summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-devices-cache_disable18
-rw-r--r--Documentation/ABI/testing/sysfs-kernel-slab479
-rw-r--r--Documentation/DocBook/Makefile3
-rw-r--r--Documentation/DocBook/kgdb.tmpl2
-rw-r--r--Documentation/DocBook/tracepoint.tmpl89
-rw-r--r--Documentation/RCU/trace.txt102
-rw-r--r--Documentation/Smack.txt20
-rw-r--r--Documentation/SubmittingPatches9
-rw-r--r--Documentation/dvb/get_dvb_firmware6
-rw-r--r--Documentation/feature-removal-schedule.txt10
-rw-r--r--Documentation/filesystems/00-INDEX4
-rw-r--r--Documentation/futex-requeue-pi.txt131
-rw-r--r--Documentation/hwmon/ibmaem2
-rw-r--r--Documentation/i2c/instantiating-devices44
-rw-r--r--Documentation/i2c/writing-clients16
-rw-r--r--Documentation/input/input.txt2
-rw-r--r--Documentation/input/rotary-encoder.txt9
-rw-r--r--Documentation/isdn/00-INDEX29
-rw-r--r--Documentation/kernel-parameters.txt25
-rw-r--r--Documentation/memory-barriers.txt129
-rw-r--r--Documentation/networking/ip-sysctl.txt11
-rw-r--r--Documentation/networking/mac80211-injection.txt28
-rw-r--r--Documentation/powerpc/dts-bindings/ecm.txt64
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt3
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/mcm.txt64
-rw-r--r--Documentation/scheduler/sched-rt-group.txt18
-rw-r--r--Documentation/scsi/scsi_fc_transport.txt14
-rw-r--r--Documentation/scsi/scsi_mid_low_api.txt5
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt11
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt12
-rw-r--r--Documentation/sound/alsa/soc/dapm.txt1
-rw-r--r--Documentation/sysctl/kernel.txt11
-rw-r--r--Documentation/sysfs-rules.txt2
-rw-r--r--Documentation/trace/events.txt135
-rw-r--r--Documentation/trace/power.txt17
-rw-r--r--Documentation/video4linux/CARDLIST.cx881
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx1
-rw-r--r--Documentation/video4linux/CARDLIST.saa713418
-rw-r--r--Documentation/video4linux/gspca.txt7
-rw-r--r--Documentation/video4linux/pxa_camera.txt49
-rw-r--r--Documentation/video4linux/v4l2-framework.txt5
-rw-r--r--Documentation/vm/slqbinfo.c1054
-rw-r--r--Documentation/x86/x86_64/mm.txt9
-rw-r--r--MAINTAINERS21
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/include/asm/percpu.h26
-rw-r--r--arch/alpha/kernel/osf_sys.c3
-rw-r--r--arch/alpha/kernel/sys_dp264.c8
-rw-r--r--arch/alpha/kernel/sys_titan.c4
-rw-r--r--arch/arm/Kconfig168
-rw-r--r--arch/arm/Makefile121
-rw-r--r--arch/arm/common/Kconfig7
-rw-r--r--arch/arm/common/gic.c4
-rw-r--r--arch/arm/common/vic.c221
-rw-r--r--arch/arm/configs/kirkwood_defconfig92
-rw-r--r--arch/arm/configs/mv78xx0_defconfig429
-rw-r--r--arch/arm/configs/mx31moboard_defconfig790
-rw-r--r--arch/arm/configs/mx3_defconfig2
-rw-r--r--arch/arm/configs/orion5x_defconfig363
-rw-r--r--arch/arm/configs/stmp378x_defconfig1141
-rw-r--r--arch/arm/configs/stmp37xx_defconfig1002
-rw-r--r--arch/arm/include/asm/elf.h16
-rw-r--r--arch/arm/include/asm/hardware/vic.h2
-rw-r--r--arch/arm/include/asm/pgtable.h2
-rw-r--r--arch/arm/kernel/module.c15
-rw-r--r--arch/arm/mach-at91/clock.c151
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pmc.h26
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c4
-rw-r--r--arch/arm/mach-ep93xx/Kconfig52
-rw-r--r--arch/arm/mach-ep93xx/Makefile8
-rw-r--r--arch/arm/mach-ep93xx/core.c19
-rw-r--r--arch/arm/mach-ep93xx/edb9302.c68
-rw-r--r--arch/arm/mach-ep93xx/edb9302a.c68
-rw-r--r--arch/arm/mach-ep93xx/edb9307.c68
-rw-r--r--arch/arm/mach-ep93xx/edb9307a.c80
-rw-r--r--arch/arm/mach-ep93xx/edb9312.c69
-rw-r--r--arch/arm/mach-ep93xx/edb9315.c68
-rw-r--r--arch/arm/mach-ep93xx/edb9315a.c68
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h1
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h42
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_npe.c2
-rw-r--r--arch/arm/mach-mmp/include/mach/irqs.h1
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa168.h27
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa910.h8
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa168.h44
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa910.h44
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apbc.h14
-rw-r--r--arch/arm/mach-mmp/pxa168.c18
-rw-r--r--arch/arm/mach-mmp/pxa910.c18
-rw-r--r--arch/arm/mach-netx/generic.c2
-rw-r--r--arch/arm/mach-pxa/Kconfig11
-rw-r--r--arch/arm/mach-pxa/Makefile1
-rw-r--r--arch/arm/mach-pxa/cm-x300.c2
-rw-r--r--arch/arm/mach-pxa/corgi.c47
-rw-r--r--arch/arm/mach-pxa/csb726.c18
-rw-r--r--arch/arm/mach-pxa/devices.c4
-rw-r--r--arch/arm/mach-pxa/em-x270.c2
-rw-r--r--arch/arm/mach-pxa/ezx.c2
-rw-r--r--arch/arm/mach-pxa/imote2.c21
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h16
-rw-r--r--arch/arm/mach-pxa/littleton.c19
-rw-r--r--arch/arm/mach-pxa/magician.c12
-rw-r--r--arch/arm/mach-pxa/mainstone.c2
-rw-r--r--arch/arm/mach-pxa/mioa701.c2
-rw-r--r--arch/arm/mach-pxa/palmt5.c14
-rw-r--r--arch/arm/mach-pxa/palmte2.c32
-rw-r--r--arch/arm/mach-pxa/palmtx.c14
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c25
-rw-r--r--arch/arm/mach-pxa/poodle.c17
-rw-r--r--arch/arm/mach-pxa/pxa27x.c2
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c4
-rw-r--r--arch/arm/mach-pxa/saar.c2
-rw-r--r--arch/arm/mach-pxa/spitz.c55
-rw-r--r--arch/arm/mach-pxa/tosa-bt.c4
-rw-r--r--arch/arm/mach-pxa/tosa.c2
-rw-r--r--arch/arm/mach-pxa/trizeps4.c2
-rw-r--r--arch/arm/mach-pxa/viper.c2
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa300.c2
-rw-r--r--arch/arm/mach-s3c2410/Kconfig8
-rw-r--r--arch/arm/mach-s3c2410/include/mach/map.h2
-rw-r--r--arch/arm/mach-s3c2412/Kconfig3
-rw-r--r--arch/arm/mach-s3c2412/pm.c3
-rw-r--r--arch/arm/mach-s3c2440/Kconfig5
-rw-r--r--arch/arm/mach-s3c6400/include/mach/map.h5
-rw-r--r--arch/arm/mach-s3c6400/include/mach/regs-clock.h16
-rw-r--r--arch/arm/mach-s3c6410/Kconfig1
-rw-r--r--arch/arm/mach-s3c6410/mach-smdk6410.c1
-rw-r--r--arch/arm/mach-stmp378x/Makefile2
-rw-r--r--arch/arm/mach-stmp378x/Makefile.boot3
-rw-r--r--arch/arm/mach-stmp378x/include/mach/entry-macro.S35
-rw-r--r--arch/arm/mach-stmp378x/include/mach/irqs.h95
-rw-r--r--arch/arm/mach-stmp378x/include/mach/pins.h151
-rw-r--r--arch/arm/mach-stmp378x/include/mach/regs-apbh.h88
-rw-r--r--arch/arm/mach-stmp378x/include/mach/regs-apbx.h79
-rw-r--r--arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h276
-rw-r--r--arch/arm/mach-stmp378x/include/mach/regs-icoll.h213
-rw-r--r--arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h143
-rw-r--r--arch/arm/mach-stmp378x/include/mach/regs-power.h32
-rw-r--r--arch/arm/mach-stmp378x/include/mach/regs-timrot.h216
-rw-r--r--arch/arm/mach-stmp378x/stmp378x.c225
-rw-r--r--arch/arm/mach-stmp378x/stmp378x.h24
-rw-r--r--arch/arm/mach-stmp378x/stmp378x_devb.c80
-rw-r--r--arch/arm/mach-stmp37xx/Makefile2
-rw-r--r--arch/arm/mach-stmp37xx/Makefile.boot3
-rw-r--r--arch/arm/mach-stmp37xx/include/mach/entry-macro.S37
-rw-r--r--arch/arm/mach-stmp37xx/include/mach/irqs.h99
-rw-r--r--arch/arm/mach-stmp37xx/include/mach/pins.h147
-rw-r--r--arch/arm/mach-stmp37xx/include/mach/regs-apbh.h102
-rw-r--r--arch/arm/mach-stmp37xx/include/mach/regs-apbx.h109
-rw-r--r--arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h85
-rw-r--r--arch/arm/mach-stmp37xx/include/mach/regs-icoll.h36
-rw-r--r--arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h159
-rw-r--r--arch/arm/mach-stmp37xx/include/mach/regs-power.h31
-rw-r--r--arch/arm/mach-stmp37xx/include/mach/regs-timrot.h52
-rw-r--r--arch/arm/mach-stmp37xx/stmp37xx.c217
-rw-r--r--arch/arm/mach-stmp37xx/stmp37xx.h24
-rw-r--r--arch/arm/mach-stmp37xx/stmp37xx_devb.c83
-rw-r--r--arch/arm/mach-u300/Kconfig105
-rw-r--r--arch/arm/mach-u300/Makefile11
-rw-r--r--arch/arm/mach-u300/clock.c1487
-rw-r--r--arch/arm/mach-u300/clock.h53
-rw-r--r--arch/arm/mach-u300/core.c649
-rw-r--r--arch/arm/mach-u300/gpio.c701
-rw-r--r--arch/arm/mach-u300/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-u300/include/mach/debug-macro.S22
-rw-r--r--arch/arm/mach-u300/include/mach/entry-macro.S40
-rw-r--r--arch/arm/mach-u300/include/mach/gpio.h290
-rw-r--r--arch/arm/mach-u300/include/mach/hardware.h5
-rw-r--r--arch/arm/mach-u300/include/mach/io.h20
-rw-r--r--arch/arm/mach-u300/include/mach/irqs.h114
-rw-r--r--arch/arm/mach-u300/include/mach/memory.h42
-rw-r--r--arch/arm/mach-u300/include/mach/platform.h19
-rw-r--r--arch/arm/mach-u300/include/mach/syscon.h644
-rw-r--r--arch/arm/mach-u300/include/mach/system.h42
-rw-r--r--arch/arm/mach-u300/include/mach/timex.h17
-rw-r--r--arch/arm/mach-u300/include/mach/u300-regs.h187
-rw-r--r--arch/arm/mach-u300/include/mach/uncompress.h46
-rw-r--r--arch/arm/mach-u300/include/mach/vmalloc.h12
-rw-r--r--arch/arm/mach-u300/mmc.c216
-rw-r--r--arch/arm/mach-u300/mmc.h18
-rw-r--r--arch/arm/mach-u300/padmux.c58
-rw-r--r--arch/arm/mach-u300/padmux.h19
-rw-r--r--arch/arm/mach-u300/timer.c422
-rw-r--r--arch/arm/mach-u300/u300.c55
-rw-r--r--arch/arm/mach-versatile/core.c2
-rw-r--r--arch/arm/mach-w90x900/include/mach/irqs.h49
-rw-r--r--arch/arm/mach-w90x900/include/mach/map.h101
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-clock.h31
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-usb.h35
-rw-r--r--arch/arm/mach-w90x900/mach-w90p910evb.c89
-rw-r--r--arch/arm/mach-w90x900/w90p910.c9
-rw-r--r--arch/arm/mm/mmu.c14
-rw-r--r--arch/arm/plat-mxc/dma-mx1-mx2.c17
-rw-r--r--arch/arm/plat-mxc/gpio.c2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx27ads.h2
-rw-r--r--arch/arm/plat-omap/mailbox.c63
-rw-r--r--arch/arm/plat-pxa/Makefile2
-rw-r--r--arch/arm/plat-pxa/include/plat/i2c.h (renamed from arch/arm/mach-pxa/include/mach/i2c.h)0
-rw-r--r--arch/arm/plat-pxa/pwm.c (renamed from arch/arm/mach-pxa/pwm.c)119
-rw-r--r--arch/arm/plat-s3c/Kconfig14
-rw-r--r--arch/arm/plat-s3c/Makefile2
-rw-r--r--arch/arm/plat-s3c/dev-usb.c50
-rw-r--r--arch/arm/plat-s3c/gpio.c11
-rw-r--r--arch/arm/plat-s3c/include/plat/cpu.h3
-rw-r--r--arch/arm/plat-s3c/include/plat/gpio-core.h30
-rw-r--r--arch/arm/plat-s3c/include/plat/pm.h15
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-serial.h5
-rw-r--r--arch/arm/plat-s3c/pm-gpio.c380
-rw-r--r--arch/arm/plat-s3c/pm.c19
-rw-r--r--arch/arm/plat-s3c24xx/devs.c30
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c8
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/map.h1
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/pm-core.h5
-rw-r--r--arch/arm/plat-s3c24xx/pm.c213
-rw-r--r--arch/arm/plat-s3c64xx/Kconfig1
-rw-r--r--arch/arm/plat-s3c64xx/Makefile6
-rw-r--r--arch/arm/plat-s3c64xx/cpu.c19
-rw-r--r--arch/arm/plat-s3c64xx/gpiolib.c10
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/irqs.h1
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/pm-core.h98
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/regs-clock.h1
-rw-r--r--arch/arm/plat-s3c64xx/irq-eint.c3
-rw-r--r--arch/arm/plat-s3c64xx/irq-pm.c111
-rw-r--r--arch/arm/plat-s3c64xx/irq.c9
-rw-r--r--arch/arm/plat-s3c64xx/pm.c175
-rw-r--r--arch/arm/plat-s3c64xx/sleep.S144
-rw-r--r--arch/arm/plat-stmp3xxx/Kconfig37
-rw-r--r--arch/arm/plat-stmp3xxx/Makefile5
-rw-r--r--arch/arm/plat-stmp3xxx/clock.c1112
-rw-r--r--arch/arm/plat-stmp3xxx/clock.h61
-rw-r--r--arch/arm/plat-stmp3xxx/core.c127
-rw-r--r--arch/arm/plat-stmp3xxx/dma.c462
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/clkdev.h18
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/cputype.h33
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/debug-macro.S42
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/dma.h155
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/gpio.h28
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/hardware.h32
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/io.h25
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/memory.h22
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/pinmux.h158
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/pins.h30
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/platform.h47
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h34
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/stmp3xxx_regs.h195
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/system.h47
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/timex.h20
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/uncompress.h53
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/vmalloc.h12
-rw-r--r--arch/arm/plat-stmp3xxx/irq.c59
-rw-r--r--arch/arm/plat-stmp3xxx/pinmux.c545
-rw-r--r--arch/arm/plat-stmp3xxx/timer.c172
-rw-r--r--arch/avr32/boards/merisc/setup.c7
-rw-r--r--arch/avr32/include/asm/hw_irq.h2
-rw-r--r--arch/cris/Makefile14
-rw-r--r--arch/cris/arch-v10/boot/compressed/README25
-rw-r--r--arch/cris/arch-v10/boot/compressed/misc.c246
-rw-r--r--arch/cris/arch-v10/kernel/entry.S14
-rw-r--r--arch/cris/arch-v32/boot/Makefile20
-rw-r--r--arch/cris/arch-v32/boot/compressed/Makefile26
-rw-r--r--arch/cris/arch-v32/boot/rescue/Makefile26
-rw-r--r--arch/cris/arch-v32/drivers/mach-a3/gpio.c4
-rw-r--r--arch/cris/arch-v32/kernel/Makefile2
-rw-r--r--arch/cris/arch-v32/kernel/entry.S8
-rw-r--r--arch/cris/arch-v32/kernel/irq.c4
-rw-r--r--arch/cris/boot/.gitignore (renamed from arch/cris/arch-v10/boot/.gitignore)0
-rw-r--r--arch/cris/boot/Makefile (renamed from arch/cris/arch-v10/boot/Makefile)8
-rw-r--r--arch/cris/boot/compressed/Makefile (renamed from arch/cris/arch-v10/boot/compressed/Makefile)19
-rw-r--r--arch/cris/boot/compressed/README (renamed from arch/cris/arch-v32/boot/compressed/README)0
-rw-r--r--arch/cris/boot/compressed/decompress_v10.lds (renamed from arch/cris/arch-v10/boot/compressed/decompress.lds)0
-rw-r--r--arch/cris/boot/compressed/decompress_v32.lds (renamed from arch/cris/arch-v32/boot/compressed/decompress.lds)0
-rw-r--r--arch/cris/boot/compressed/head_v10.S (renamed from arch/cris/arch-v10/boot/compressed/head.S)4
-rw-r--r--arch/cris/boot/compressed/head_v32.S (renamed from arch/cris/arch-v32/boot/compressed/head.S)10
-rw-r--r--arch/cris/boot/compressed/misc.c (renamed from arch/cris/arch-v32/boot/compressed/misc.c)193
-rw-r--r--arch/cris/boot/rescue/Makefile (renamed from arch/cris/arch-v10/boot/rescue/Makefile)22
-rw-r--r--arch/cris/boot/rescue/head_v10.S (renamed from arch/cris/arch-v10/boot/rescue/head.S)2
-rw-r--r--arch/cris/boot/rescue/head_v32.S (renamed from arch/cris/arch-v32/boot/rescue/head.S)0
-rw-r--r--arch/cris/boot/rescue/kimagerescue.S (renamed from arch/cris/arch-v10/boot/rescue/kimagerescue.S)0
-rw-r--r--arch/cris/boot/rescue/rescue_v10.lds (renamed from arch/cris/arch-v10/boot/rescue/rescue.lds)0
-rw-r--r--arch/cris/boot/rescue/rescue_v32.lds (renamed from arch/cris/arch-v32/boot/rescue/rescue.lds)0
-rw-r--r--arch/cris/boot/rescue/testrescue.S (renamed from arch/cris/arch-v10/boot/rescue/testrescue.S)0
-rw-r--r--arch/cris/boot/tools/build.c (renamed from arch/cris/arch-v10/boot/tools/build.c)0
-rw-r--r--arch/cris/include/asm/unistd.h12
-rw-r--r--arch/frv/include/asm/gdb-stub.h1
-rw-r--r--arch/ia64/hp/sim/hpsim_irq.c3
-rw-r--r--arch/ia64/include/asm/iommu.h1
-rw-r--r--arch/ia64/include/asm/kvm_host.h5
-rw-r--r--arch/ia64/include/asm/pgtable.h2
-rw-r--r--arch/ia64/kernel/acpi.c5
-rw-r--r--arch/ia64/kernel/iosapic.c10
-rw-r--r--arch/ia64/kernel/irq_ia64.c3
-rw-r--r--arch/ia64/kernel/msi_ia64.c16
-rw-r--r--arch/ia64/kernel/pci-dma.c2
-rw-r--r--arch/ia64/kernel/pci-swiotlb.c2
-rw-r--r--arch/ia64/kvm/Kconfig2
-rw-r--r--arch/ia64/kvm/kvm-ia64.c263
-rw-r--r--arch/ia64/kvm/kvm_fw.c28
-rw-r--r--arch/ia64/kvm/lapic.h6
-rw-r--r--arch/ia64/kvm/optvfault.S30
-rw-r--r--arch/ia64/kvm/process.c5
-rw-r--r--arch/ia64/kvm/vcpu.c20
-rw-r--r--arch/ia64/kvm/vmm.c12
-rw-r--r--arch/ia64/kvm/vmm_ivt.S18
-rw-r--r--arch/ia64/kvm/vtlb.c3
-rw-r--r--arch/ia64/sn/kernel/irq.c4
-rw-r--r--arch/ia64/sn/kernel/msi_sn.c8
-rw-r--r--arch/m68k/include/asm/checksum.h160
-rw-r--r--arch/m68k/include/asm/checksum_mm.h148
-rw-r--r--arch/m68k/include/asm/checksum_no.h132
-rw-r--r--arch/m68k/include/asm/dma.h493
-rw-r--r--arch/m68k/include/asm/dma_mm.h16
-rw-r--r--arch/m68k/include/asm/dma_no.h494
-rw-r--r--arch/m68k/include/asm/hardirq.h21
-rw-r--r--arch/m68k/include/asm/hardirq_mm.h16
-rw-r--r--arch/m68k/include/asm/hardirq_no.h27
-rw-r--r--arch/m68k/include/asm/irq.h135
-rw-r--r--arch/m68k/include/asm/irq_mm.h126
-rw-r--r--arch/m68k/include/asm/irq_no.h26
-rw-r--r--arch/m68k/include/asm/m520xsim.h28
-rw-r--r--arch/m68k/include/asm/m523xsim.h9
-rw-r--r--arch/m68k/include/asm/m527xsim.h9
-rw-r--r--arch/m68k/include/asm/m528xsim.h8
-rw-r--r--arch/m68k/include/asm/m532xsim.h55
-rw-r--r--arch/m68k/include/asm/mcfsim.h14
-rw-r--r--arch/m68k/include/asm/processor.h171
-rw-r--r--arch/m68k/include/asm/processor_mm.h130
-rw-r--r--arch/m68k/include/asm/processor_no.h143
-rw-r--r--arch/m68k/include/asm/system_no.h107
-rw-r--r--arch/m68knommu/kernel/entry.S1
-rw-r--r--arch/m68knommu/kernel/irq.c21
-rw-r--r--arch/m68knommu/lib/checksum.c9
-rw-r--r--arch/m68knommu/platform/5206/config.c18
-rw-r--r--arch/m68knommu/platform/5206e/config.c18
-rw-r--r--arch/m68knommu/platform/520x/config.c35
-rw-r--r--arch/m68knommu/platform/523x/config.c69
-rw-r--r--arch/m68knommu/platform/5249/config.c18
-rw-r--r--arch/m68knommu/platform/5272/config.c18
-rw-r--r--arch/m68knommu/platform/527x/config.c54
-rw-r--r--arch/m68knommu/platform/528x/config.c54
-rw-r--r--arch/m68knommu/platform/5307/config.c16
-rw-r--r--arch/m68knommu/platform/532x/config.c44
-rw-r--r--arch/m68knommu/platform/5407/config.c16
-rw-r--r--arch/m68knommu/platform/68328/ints.c72
-rw-r--r--arch/m68knommu/platform/68360/ints.c44
-rw-r--r--arch/m68knommu/platform/coldfire/Makefile22
-rw-r--r--arch/m68knommu/platform/coldfire/intc-2.c93
-rw-r--r--arch/m68knommu/platform/coldfire/intc-simr.c78
-rw-r--r--arch/m68knommu/platform/coldfire/intc.c55
-rw-r--r--arch/m68knommu/platform/coldfire/pit.c8
-rw-r--r--arch/m68knommu/platform/coldfire/vectors.c27
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-static.c4
-rw-r--r--arch/microblaze/kernel/sys_microblaze.c2
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/cavium-octeon/Makefile4
-rw-r--r--arch/mips/cavium-octeon/dma-octeon.c311
-rw-r--r--arch/mips/cavium-octeon/executive/Makefile1
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-errata.c70
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c144
-rw-r--r--arch/mips/cavium-octeon/msi.c288
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c10
-rw-r--r--arch/mips/cavium-octeon/pci-common.c137
-rw-r--r--arch/mips/cavium-octeon/pci-common.h39
-rw-r--r--arch/mips/cavium-octeon/pci.c568
-rw-r--r--arch/mips/cavium-octeon/pcie.c1370
-rw-r--r--arch/mips/configs/bigsur_defconfig2
-rw-r--r--arch/mips/configs/mtx1_defconfig2
-rw-r--r--arch/mips/include/asm/irq.h2
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h6
-rw-r--r--arch/mips/include/asm/mach-generic/dma-coherence.h6
-rw-r--r--arch/mips/include/asm/mach-ip27/dma-coherence.h6
-rw-r--r--arch/mips/include/asm/mach-ip32/dma-coherence.h6
-rw-r--r--arch/mips/include/asm/mach-jazz/dma-coherence.h6
-rw-r--r--arch/mips/include/asm/mach-lemote/dma-coherence.h6
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-errata.h33
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-jtag.h43
-rw-r--r--arch/mips/include/asm/octeon/cvmx-npei-defs.h2560
-rw-r--r--arch/mips/include/asm/octeon/cvmx-npi-defs.h1735
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pci-defs.h1645
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pcieep-defs.h1365
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pciercx-defs.h1397
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pescx-defs.h410
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pexp-defs.h229
-rw-r--r--arch/mips/include/asm/octeon/cvmx.h12
-rw-r--r--arch/mips/include/asm/octeon/octeon.h2
-rw-r--r--arch/mips/include/asm/r4kcache.h1
-rw-r--r--arch/mips/include/asm/txx9/dmac.h51
-rw-r--r--arch/mips/include/asm/txx9/tx4927.h2
-rw-r--r--arch/mips/include/asm/txx9/tx4938.h1
-rw-r--r--arch/mips/include/asm/txx9/tx4939.h1
-rw-r--r--arch/mips/kernel/cevt-txx9.c67
-rw-r--r--arch/mips/kernel/irq-gic.c5
-rw-r--r--arch/mips/mm/c-r4k.c12
-rw-r--r--arch/mips/mm/dma-default.c23
-rw-r--r--arch/mips/mti-malta/malta-smtc.c4
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c8
-rw-r--r--arch/mips/sibyte/sb1250/irq.c8
-rw-r--r--arch/mips/txx9/generic/setup.c55
-rw-r--r--arch/mips/txx9/generic/setup_tx4927.c12
-rw-r--r--arch/mips/txx9/generic/setup_tx4938.c21
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c21
-rw-r--r--arch/mips/txx9/rbtx4927/setup.c4
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c1
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c1
-rw-r--r--arch/mn10300/include/asm/gdb-stub.h1
-rw-r--r--arch/parisc/kernel/irq.c6
-rw-r--r--arch/powerpc/boot/dts/gef_ppc9a.dts14
-rw-r--r--arch/powerpc/boot/dts/gef_sbc310.dts14
-rw-r--r--arch/powerpc/boot/dts/gef_sbc610.dts14
-rw-r--r--arch/powerpc/boot/dts/ksi8560.dts13
-rw-r--r--arch/powerpc/boot/dts/mpc832x_mds.dts3
-rw-r--r--arch/powerpc/boot/dts/mpc832x_rdb.dts3
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitx.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitxgp.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc834x_mds.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc836x_mds.dts3
-rw-r--r--arch/powerpc/boot/dts/mpc836x_rdk.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc8377_mds.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8378_mds.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8379_mds.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8536ds.dts18
-rw-r--r--arch/powerpc/boot/dts/mpc8540ads.dts15
-rw-r--r--arch/powerpc/boot/dts/mpc8541cds.dts16
-rw-r--r--arch/powerpc/boot/dts/mpc8544ds.dts18
-rw-r--r--arch/powerpc/boot/dts/mpc8548cds.dts17
-rw-r--r--arch/powerpc/boot/dts/mpc8555cds.dts16
-rw-r--r--arch/powerpc/boot/dts/mpc8560ads.dts15
-rw-r--r--arch/powerpc/boot/dts/mpc8568mds.dts51
-rw-r--r--arch/powerpc/boot/dts/mpc8569mds.dts583
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds.dts17
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_36b.dts39
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts16
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc8610_hpcd.dts16
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn.dts16
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts609
-rw-r--r--arch/powerpc/boot/dts/sbc8349.dts1
-rw-r--r--arch/powerpc/boot/dts/sbc8548.dts16
-rw-r--r--arch/powerpc/boot/dts/sbc8560.dts15
-rw-r--r--arch/powerpc/boot/dts/sbc8641d.dts16
-rw-r--r--arch/powerpc/boot/dts/socrates.dts15
-rw-r--r--arch/powerpc/boot/dts/stx_gp3_8560.dts15
-rw-r--r--arch/powerpc/boot/dts/tqm8540.dts15
-rw-r--r--arch/powerpc/boot/dts/tqm8541.dts15
-rw-r--r--arch/powerpc/boot/dts/tqm8548-bigflash.dts16
-rw-r--r--arch/powerpc/boot/dts/tqm8548.dts16
-rw-r--r--arch/powerpc/boot/dts/tqm8555.dts15
-rw-r--r--arch/powerpc/boot/dts/tqm8560.dts15
-rw-r--r--arch/powerpc/configs/40x/acadia_defconfig2
-rw-r--r--arch/powerpc/configs/40x/ep405_defconfig2
-rw-r--r--arch/powerpc/configs/40x/kilauea_defconfig2
-rw-r--r--arch/powerpc/configs/40x/makalu_defconfig2
-rw-r--r--arch/powerpc/configs/40x/virtex_defconfig2
-rw-r--r--arch/powerpc/configs/44x/arches_defconfig2
-rw-r--r--arch/powerpc/configs/44x/bamboo_defconfig2
-rw-r--r--arch/powerpc/configs/44x/canyonlands_defconfig6
-rw-r--r--arch/powerpc/configs/44x/ebony_defconfig2
-rw-r--r--arch/powerpc/configs/44x/katmai_defconfig2
-rw-r--r--arch/powerpc/configs/44x/rainier_defconfig2
-rw-r--r--arch/powerpc/configs/44x/redwood_defconfig2
-rw-r--r--arch/powerpc/configs/44x/sam440ep_defconfig2
-rw-r--r--arch/powerpc/configs/44x/sequoia_defconfig2
-rw-r--r--arch/powerpc/configs/44x/taishan_defconfig2
-rw-r--r--arch/powerpc/configs/44x/virtex5_defconfig2
-rw-r--r--arch/powerpc/configs/ppc6xx_defconfig2
-rw-r--r--arch/powerpc/include/asm/cpm1.h2
-rw-r--r--arch/powerpc/include/asm/cpm2.h4
-rw-r--r--arch/powerpc/include/asm/mpc86xx.h33
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h6
-rw-r--r--arch/powerpc/include/asm/qe.h21
-rw-r--r--arch/powerpc/kvm/powerpc.c6
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_emb.c14
-rw-r--r--arch/powerpc/platforms/82xx/ep8248e.c9
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads.h13
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c52
-rw-r--r--arch/powerpc/platforms/86xx/gef_ppc9a.c1
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc310.c1
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc610.c1
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c1
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c1
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_smp.c8
-rw-r--r--arch/powerpc/platforms/86xx/sbc8641d.c1
-rw-r--r--arch/powerpc/platforms/8xx/mpc885ads.h4
-rw-r--r--arch/powerpc/platforms/fsl_uli1575.c23
-rw-r--r--arch/powerpc/platforms/pasemi/gpio_mdio.c32
-rw-r--r--arch/powerpc/platforms/pseries/xics.c12
-rw-r--r--arch/powerpc/sysdev/cpm2.c2
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c9
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c6
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c15
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c14
-rw-r--r--arch/powerpc/sysdev/mpic.c4
-rw-r--r--arch/powerpc/sysdev/mpic.h2
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c75
-rw-r--r--arch/s390/Kconfig18
-rw-r--r--arch/s390/include/asm/compat.h19
-rw-r--r--arch/s390/include/asm/cpu.h32
-rw-r--r--arch/s390/include/asm/cputime.h19
-rw-r--r--arch/s390/include/asm/lowcore.h1
-rw-r--r--arch/s390/include/asm/seccomp.h16
-rw-r--r--arch/s390/include/asm/spinlock.h19
-rw-r--r--arch/s390/include/asm/thread_info.h10
-rw-r--r--arch/s390/kernel/Makefile2
-rw-r--r--arch/s390/kernel/entry.S5
-rw-r--r--arch/s390/kernel/entry64.S5
-rw-r--r--arch/s390/kernel/head.S65
-rw-r--r--arch/s390/kernel/nmi.c2
-rw-r--r--arch/s390/kernel/process.c3
-rw-r--r--arch/s390/kernel/ptrace.c16
-rw-r--r--arch/s390/kernel/s390_ext.c2
-rw-r--r--arch/s390/kernel/sclp.S327
-rw-r--r--arch/s390/kernel/signal.c3
-rw-r--r--arch/s390/kernel/smp.c2
-rw-r--r--arch/s390/kernel/vdso.c16
-rw-r--r--arch/s390/kernel/vtime.c2
-rw-r--r--arch/s390/kvm/interrupt.c6
-rw-r--r--arch/s390/lib/spinlock.c40
-rw-r--r--arch/s390/mm/fault.c3
-rw-r--r--arch/s390/mm/mmap.c11
-rw-r--r--arch/sh/Kconfig105
-rw-r--r--arch/sh/Kconfig.cpu5
-rw-r--r--arch/sh/Kconfig.debug23
-rw-r--r--arch/sh/Makefile57
-rw-r--r--arch/sh/boards/Kconfig6
-rw-r--r--arch/sh/boards/mach-cayman/Makefile2
-rw-r--r--arch/sh/boards/mach-cayman/irq.c17
-rw-r--r--arch/sh/boards/mach-cayman/panic.c49
-rw-r--r--arch/sh/boards/mach-cayman/setup.c2
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c6
-rw-r--r--arch/sh/boards/mach-r2d/setup.c50
-rw-r--r--arch/sh/boards/mach-se/7751/Makefile2
-rw-r--r--arch/sh/boards/mach-se/7751/io.c16
-rw-r--r--arch/sh/boards/mach-se/7751/pci.c147
-rw-r--r--arch/sh/boards/mach-se/7780/irq.c27
-rw-r--r--arch/sh/boards/mach-sh03/rtc.c10
-rw-r--r--arch/sh/boards/mach-snapgear/io.c16
-rw-r--r--arch/sh/boards/mach-systemh/io.c16
-rw-r--r--arch/sh/boards/mach-titan/io.c20
-rw-r--r--arch/sh/boot/Makefile6
-rw-r--r--arch/sh/boot/compressed/Makefile50
-rw-r--r--arch/sh/boot/compressed/Makefile_3246
-rw-r--r--arch/sh/boot/compressed/Makefile_6443
-rw-r--r--arch/sh/boot/compressed/head_64.S5
-rw-r--r--arch/sh/boot/compressed/vmlinux_64.lds64
-rw-r--r--arch/sh/configs/ap325rxa_defconfig37
-rw-r--r--arch/sh/configs/cayman_defconfig71
-rw-r--r--arch/sh/configs/dreamcast_defconfig39
-rw-r--r--arch/sh/configs/edosk7705_defconfig29
-rw-r--r--arch/sh/configs/edosk7760_defconfig32
-rw-r--r--arch/sh/configs/espt_defconfig39
-rw-r--r--arch/sh/configs/hp6xx_defconfig35
-rw-r--r--arch/sh/configs/landisk_defconfig48
-rw-r--r--arch/sh/configs/lboxre2_defconfig44
-rw-r--r--arch/sh/configs/magicpanelr2_defconfig30
-rw-r--r--arch/sh/configs/microdev_defconfig36
-rw-r--r--arch/sh/configs/migor_defconfig36
-rw-r--r--arch/sh/configs/polaris_defconfig30
-rw-r--r--arch/sh/configs/r7780mp_defconfig38
-rw-r--r--arch/sh/configs/r7785rp_defconfig38
-rw-r--r--arch/sh/configs/rsk7201_defconfig37
-rw-r--r--arch/sh/configs/rsk7203_defconfig40
-rw-r--r--arch/sh/configs/rts7751r2d1_defconfig43
-rw-r--r--arch/sh/configs/rts7751r2dplus_defconfig130
-rw-r--r--arch/sh/configs/sdk7780_defconfig38
-rw-r--r--arch/sh/configs/se7206_defconfig35
-rw-r--r--arch/sh/configs/se7343_defconfig42
-rw-r--r--arch/sh/configs/se7619_defconfig35
-rw-r--r--arch/sh/configs/se7705_defconfig34
-rw-r--r--arch/sh/configs/se7712_defconfig30
-rw-r--r--arch/sh/configs/se7721_defconfig33
-rw-r--r--arch/sh/configs/se7722_defconfig38
-rw-r--r--arch/sh/configs/se7750_defconfig34
-rw-r--r--arch/sh/configs/se7751_defconfig34
-rw-r--r--arch/sh/configs/se7780_defconfig38
-rw-r--r--arch/sh/configs/sh03_defconfig43
-rw-r--r--arch/sh/configs/sh7710voipgw_defconfig35
-rw-r--r--arch/sh/configs/sh7724_generic_defconfig707
-rw-r--r--arch/sh/configs/sh7763rdp_defconfig35
-rw-r--r--arch/sh/configs/sh7770_generic_defconfig700
-rw-r--r--arch/sh/configs/sh7785lcr_32bit_defconfig37
-rw-r--r--arch/sh/configs/sh7785lcr_defconfig6
-rw-r--r--arch/sh/configs/shmin_defconfig31
-rw-r--r--arch/sh/configs/shx3_defconfig32
-rw-r--r--arch/sh/configs/snapgear_defconfig40
-rw-r--r--arch/sh/configs/systemh_defconfig39
-rw-r--r--arch/sh/configs/titan_defconfig40
-rw-r--r--arch/sh/configs/ul2_defconfig37
-rw-r--r--arch/sh/configs/urquell_defconfig39
-rw-r--r--arch/sh/drivers/dma/Kconfig3
-rw-r--r--arch/sh/drivers/pci/Kconfig18
-rw-r--r--arch/sh/drivers/pci/Makefile28
-rw-r--r--arch/sh/drivers/pci/fixups-cayman.c (renamed from arch/sh/drivers/pci/ops-cayman.c)12
-rw-r--r--arch/sh/drivers/pci/fixups-dreamcast.c9
-rw-r--r--arch/sh/drivers/pci/fixups-landisk.c (renamed from arch/sh/drivers/pci/ops-landisk.c)33
-rw-r--r--arch/sh/drivers/pci/fixups-lboxre2.c41
-rw-r--r--arch/sh/drivers/pci/fixups-r7780rp.c41
-rw-r--r--arch/sh/drivers/pci/fixups-rts7751r2d.c48
-rw-r--r--arch/sh/drivers/pci/fixups-sdk7780.c63
-rw-r--r--arch/sh/drivers/pci/fixups-se7751.c111
-rw-r--r--arch/sh/drivers/pci/fixups-se7780.c60
-rw-r--r--arch/sh/drivers/pci/fixups-sh7785lcr.c46
-rw-r--r--arch/sh/drivers/pci/fixups-snapgear.c38
-rw-r--r--arch/sh/drivers/pci/fixups-titan.c (renamed from arch/sh/drivers/pci/ops-titan.c)39
-rw-r--r--arch/sh/drivers/pci/ops-dreamcast.c107
-rw-r--r--arch/sh/drivers/pci/ops-lboxre2.c63
-rw-r--r--arch/sh/drivers/pci/ops-r7780rp.c68
-rw-r--r--arch/sh/drivers/pci/ops-rts7751r2d.c74
-rw-r--r--arch/sh/drivers/pci/ops-sdk7780.c73
-rw-r--r--arch/sh/drivers/pci/ops-se7780.c96
-rw-r--r--arch/sh/drivers/pci/ops-sh03.c45
-rw-r--r--arch/sh/drivers/pci/ops-sh4.c79
-rw-r--r--arch/sh/drivers/pci/ops-sh5.c25
-rw-r--r--arch/sh/drivers/pci/ops-sh7785lcr.c66
-rw-r--r--arch/sh/drivers/pci/ops-snapgear.c94
-rw-r--r--arch/sh/drivers/pci/pci-auto.c545
-rw-r--r--arch/sh/drivers/pci/pci-dreamcast.c102
-rw-r--r--arch/sh/drivers/pci/pci-sh4.h19
-rw-r--r--arch/sh/drivers/pci/pci-sh5.c55
-rw-r--r--arch/sh/drivers/pci/pci-sh5.h3
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c216
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.h12
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c227
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h16
-rw-r--r--arch/sh/drivers/pci/pci.c279
-rw-r--r--arch/sh/include/asm/cacheflush.h2
-rw-r--r--arch/sh/include/asm/clock.h4
-rw-r--r--arch/sh/include/asm/device.h2
-rw-r--r--arch/sh/include/asm/io.h22
-rw-r--r--arch/sh/include/asm/kprobes.h2
-rw-r--r--arch/sh/include/asm/pci.h98
-rw-r--r--arch/sh/include/asm/pgtable.h4
-rw-r--r--arch/sh/include/asm/processor.h2
-rw-r--r--arch/sh/include/asm/ptrace.h5
-rw-r--r--arch/sh/include/asm/rtc.h11
-rw-r--r--arch/sh/include/asm/swab.h12
-rw-r--r--arch/sh/include/asm/system_32.h2
-rw-r--r--arch/sh/include/asm/timer.h44
-rw-r--r--arch/sh/include/asm/types.h4
-rw-r--r--arch/sh/include/asm/ubc.h11
-rw-r--r--arch/sh/include/cpu-sh2a/cpu/ubc.h29
-rw-r--r--arch/sh/include/cpu-sh3/cpu/timer.h67
-rw-r--r--arch/sh/include/cpu-sh4/cpu/freq.h18
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7724.h255
-rw-r--r--arch/sh/include/cpu-sh4/cpu/timer.h60
-rw-r--r--arch/sh/include/cpu-sh5/cpu/irq.h1
-rw-r--r--arch/sh/include/mach-common/mach/sh7785lcr.h10
-rw-r--r--arch/sh/include/mach-dreamcast/mach/pci.h2
-rw-r--r--arch/sh/kernel/Makefile_326
-rw-r--r--arch/sh/kernel/Makefile_649
-rw-r--r--arch/sh/kernel/cpu/clock.c63
-rw-r--r--arch/sh/kernel/cpu/irq/imask.c2
-rw-r--r--arch/sh/kernel/cpu/irq/intc-sh5.c26
-rw-r--r--arch/sh/kernel/cpu/sh2/setup-sh7619.c84
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-mxg.c111
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7201.c115
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7203.c154
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c187
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c108
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh770x.c108
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c108
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7720.c270
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c6
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh4-202.c164
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c187
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c140
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile3
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c112
-rw-r--r--arch/sh/kernel/cpu/sh4a/pinmux-sh7724.c2230
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7343.c116
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7366.c113
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c117
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c216
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7724.c757
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7763.c204
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7770.c300
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c204
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c204
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c393
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-shx3.c209
-rw-r--r--arch/sh/kernel/cpu/sh5/Makefile3
-rw-r--r--arch/sh/kernel/cpu/sh5/clock-sh5.c2
-rw-r--r--arch/sh/kernel/cpu/sh5/entry.S65
-rw-r--r--arch/sh/kernel/cpu/sh5/setup-sh5.c195
-rw-r--r--arch/sh/kernel/io.c1
-rw-r--r--arch/sh/kernel/io_trapped.c2
-rw-r--r--arch/sh/kernel/kgdb.c4
-rw-r--r--arch/sh/kernel/localtimer.c (renamed from arch/sh/kernel/timers/timer-broadcast.c)0
-rw-r--r--arch/sh/kernel/module.c2
-rw-r--r--arch/sh/kernel/process_32.c4
-rw-r--r--arch/sh/kernel/ptrace_32.c8
-rw-r--r--arch/sh/kernel/setup.c14
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c3
-rw-r--r--arch/sh/kernel/sh_ksyms_64.c2
-rw-r--r--arch/sh/kernel/time.c125
-rw-r--r--arch/sh/kernel/time_32.c240
-rw-r--r--arch/sh/kernel/time_64.c363
-rw-r--r--arch/sh/kernel/timers/Makefile11
-rw-r--r--arch/sh/kernel/timers/timer-cmt.c188
-rw-r--r--arch/sh/kernel/timers/timer-mtu2.c202
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c297
-rw-r--r--arch/sh/kernel/timers/timer.c55
-rw-r--r--arch/sh/kernel/traps.c6
-rw-r--r--arch/sh/kernel/traps_32.c15
-rw-r--r--arch/sh/kernel/traps_64.c35
-rw-r--r--arch/sh/kernel/vmlinux.lds.S179
-rw-r--r--arch/sh/kernel/vmlinux_32.lds.S154
-rw-r--r--arch/sh/kernel/vmlinux_64.lds.S163
-rw-r--r--arch/sh/lib64/.gitignore1
-rw-r--r--arch/sh/lib64/dbg.c182
-rw-r--r--arch/sh/lib64/panic.c43
-rw-r--r--arch/sh/lib64/sdivsi3.S6
-rw-r--r--arch/sh/lib64/udelay.c2
-rw-r--r--arch/sh/mm/Kconfig8
-rw-r--r--arch/sh/mm/cache-sh5.c8
-rw-r--r--arch/sh/mm/ioremap_32.c14
-rw-r--r--arch/sh/mm/ioremap_64.c265
-rw-r--r--arch/sh/mm/mmap.c136
-rw-r--r--arch/sh/oprofile/common.c1
-rw-r--r--arch/sparc/Kconfig3
-rw-r--r--arch/sparc/include/asm/cpudata_64.h197
-rw-r--r--arch/sparc/include/asm/mdesc.h3
-rw-r--r--arch/sparc/include/asm/percpu_64.h8
-rw-r--r--arch/sparc/include/asm/prom.h2
-rw-r--r--arch/sparc/include/asm/thread_info_64.h4
-rw-r--r--arch/sparc/include/asm/trap_block.h207
-rw-r--r--arch/sparc/kernel/ds.c3
-rw-r--r--arch/sparc/kernel/head_64.S22
-rw-r--r--arch/sparc/kernel/irq_64.c12
-rw-r--r--arch/sparc/kernel/mdesc.c149
-rw-r--r--arch/sparc/kernel/prom.h1
-rw-r--r--arch/sparc/kernel/prom_64.c234
-rw-r--r--arch/sparc/kernel/prom_common.c2
-rw-r--r--arch/sparc/kernel/smp_64.c192
-rw-r--r--arch/sparc/kernel/traps_64.c170
-rw-r--r--arch/sparc/mm/init_32.c1
-rw-r--r--arch/sparc/mm/init_64.c16
-rw-r--r--arch/um/drivers/ubd_kern.c36
-rw-r--r--arch/x86/Kbuild16
-rw-r--r--arch/x86/Kconfig27
-rw-r--r--arch/x86/Kconfig.cpu1
-rw-r--r--arch/x86/Kconfig.debug12
-rw-r--r--arch/x86/Makefile19
-rw-r--r--arch/x86/boot/Makefile5
-rw-r--r--arch/x86/boot/a20.c9
-rw-r--r--arch/x86/boot/apm.c76
-rw-r--r--arch/x86/boot/bioscall.S82
-rw-r--r--arch/x86/boot/boot.h48
-rw-r--r--arch/x86/boot/compressed/Makefile54
-rw-r--r--arch/x86/boot/compressed/head_32.S181
-rw-r--r--arch/x86/boot/compressed/head_64.S147
-rw-r--r--arch/x86/boot/compressed/mkpiggy.c97
-rw-r--r--arch/x86/boot/compressed/vmlinux.lds.S (renamed from arch/x86/boot/compressed/vmlinux_64.lds)29
-rw-r--r--arch/x86/boot/compressed/vmlinux.scr10
-rw-r--r--arch/x86/boot/compressed/vmlinux_32.lds43
-rw-r--r--arch/x86/boot/edd.c71
-rw-r--r--arch/x86/boot/header.S2
-rw-r--r--arch/x86/boot/main.c39
-rw-r--r--arch/x86/boot/mca.c27
-rw-r--r--arch/x86/boot/memory.c81
-rw-r--r--arch/x86/boot/regs.c29
-rw-r--r--arch/x86/boot/setup.ld6
-rw-r--r--arch/x86/boot/tty.c52
-rw-r--r--arch/x86/boot/video-bios.c27
-rw-r--r--arch/x86/boot/video-vesa.c137
-rw-r--r--arch/x86/boot/video-vga.c95
-rw-r--r--arch/x86/boot/video.c42
-rw-r--r--arch/x86/boot/video.h14
-rw-r--r--arch/x86/configs/x86_64_defconfig1
-rw-r--r--arch/x86/crypto/Makefile2
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c267
-rw-r--r--arch/x86/crypto/fpu.c166
-rw-r--r--arch/x86/ia32/ia32entry.S1
-rw-r--r--arch/x86/include/asm/alternative.h59
-rw-r--r--arch/x86/include/asm/apic.h31
-rw-r--r--arch/x86/include/asm/apicdef.h8
-rw-r--r--arch/x86/include/asm/cpufeature.h8
-rw-r--r--arch/x86/include/asm/ds.h82
-rw-r--r--arch/x86/include/asm/hw_irq.h4
-rw-r--r--arch/x86/include/asm/i387.h31
-rw-r--r--arch/x86/include/asm/i8259.h4
-rw-r--r--arch/x86/include/asm/io_apic.h8
-rw-r--r--arch/x86/include/asm/iomap.h5
-rw-r--r--arch/x86/include/asm/iommu.h1
-rw-r--r--arch/x86/include/asm/irq_remapping.h2
-rw-r--r--arch/x86/include/asm/irq_vectors.h1
-rw-r--r--arch/x86/include/asm/k8.h13
-rw-r--r--arch/x86/include/asm/kvm.h1
-rw-r--r--arch/x86/include/asm/kvm_host.h34
-rw-r--r--arch/x86/include/asm/mpspec.h4
-rw-r--r--arch/x86/include/asm/msr-index.h1
-rw-r--r--arch/x86/include/asm/page_32_types.h4
-rw-r--r--arch/x86/include/asm/page_64_types.h8
-rw-r--r--arch/x86/include/asm/page_types.h6
-rw-r--r--arch/x86/include/asm/paravirt.h22
-rw-r--r--arch/x86/include/asm/pci.h1
-rw-r--r--arch/x86/include/asm/percpu.h10
-rw-r--r--arch/x86/include/asm/pgtable.h4
-rw-r--r--arch/x86/include/asm/pgtable_64.h6
-rw-r--r--arch/x86/include/asm/pgtable_64_types.h8
-rw-r--r--arch/x86/include/asm/pgtable_types.h1
-rw-r--r--arch/x86/include/asm/processor.h43
-rw-r--r--arch/x86/include/asm/ptrace.h16
-rw-r--r--arch/x86/include/asm/required-features.h8
-rw-r--r--arch/x86/include/asm/setup.h1
-rw-r--r--arch/x86/include/asm/sparsemem.h2
-rw-r--r--arch/x86/include/asm/svm.h1
-rw-r--r--arch/x86/include/asm/syscalls.h45
-rw-r--r--arch/x86/include/asm/thread_info.h4
-rw-r--r--arch/x86/include/asm/tlbflush.h8
-rw-r--r--arch/x86/include/asm/topology.h3
-rw-r--r--arch/x86/include/asm/traps.h5
-rw-r--r--arch/x86/include/asm/unistd_32.h1
-rw-r--r--arch/x86/include/asm/unistd_64.h2
-rw-r--r--arch/x86/kernel/Makefile3
-rw-r--r--arch/x86/kernel/acpi/boot.c8
-rw-r--r--arch/x86/kernel/acpi/cstate.c36
-rw-r--r--arch/x86/kernel/acpi/realmode/Makefile2
-rw-r--r--arch/x86/kernel/acpi/realmode/bioscall.S1
-rw-r--r--arch/x86/kernel/acpi/realmode/regs.c1
-rw-r--r--arch/x86/kernel/apic/apic.c277
-rw-r--r--arch/x86/kernel/apic/apic_flat_64.c2
-rw-r--r--arch/x86/kernel/apic/es7000_32.c10
-rw-r--r--arch/x86/kernel/apic/io_apic.c561
-rw-r--r--arch/x86/kernel/apic/nmi.c2
-rw-r--r--arch/x86/kernel/apic/probe_32.c1
-rw-r--r--arch/x86/kernel/apic/probe_64.c2
-rw-r--r--arch/x86/kernel/apic/summit_32.c7
-rw-r--r--arch/x86/kernel/apic/x2apic_cluster.c2
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c5
-rw-r--r--arch/x86/kernel/cpu/common.c17
-rw-r--r--arch/x86/kernel/cpu/cpu_debug.c14
-rw-r--r--arch/x86/kernel/cpu/cpufreq/p4-clockmod.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k7.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c134
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c60
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-ich.c81
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-lib.c1
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c153
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_intel_64.c11
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c6
-rw-r--r--arch/x86/kernel/ds.c921
-rw-r--r--arch/x86/kernel/ds_selftest.c408
-rw-r--r--arch/x86/kernel/ds_selftest.h15
-rw-r--r--arch/x86/kernel/dumpstack.h1
-rw-r--r--arch/x86/kernel/e820.c57
-rw-r--r--arch/x86/kernel/early-quirks.c2
-rw-r--r--arch/x86/kernel/entry_64.S24
-rw-r--r--arch/x86/kernel/head_32.S7
-rw-r--r--arch/x86/kernel/irq.c20
-rw-r--r--arch/x86/kernel/irqinit.c (renamed from arch/x86/kernel/irqinit_32.c)149
-rw-r--r--arch/x86/kernel/irqinit_64.c177
-rw-r--r--arch/x86/kernel/kgdb.c5
-rw-r--r--arch/x86/kernel/kvm.c6
-rw-r--r--arch/x86/kernel/machine_kexec_32.c4
-rw-r--r--arch/x86/kernel/machine_kexec_64.c4
-rw-r--r--arch/x86/kernel/paravirt.c56
-rw-r--r--arch/x86/kernel/pci-calgary_64.c54
-rw-r--r--arch/x86/kernel/pci-dma.c6
-rw-r--r--arch/x86/kernel/pci-gart_64.c45
-rw-r--r--arch/x86/kernel/pci-swiotlb.c5
-rw-r--r--arch/x86/kernel/process.c6
-rw-r--r--arch/x86/kernel/process_32.c5
-rw-r--r--arch/x86/kernel/process_64.c5
-rw-r--r--arch/x86/kernel/ptrace.c284
-rw-r--r--arch/x86/kernel/quirks.c37
-rw-r--r--arch/x86/kernel/setup.c30
-rw-r--r--arch/x86/kernel/smp.c23
-rw-r--r--arch/x86/kernel/smpboot.c14
-rw-r--r--arch/x86/kernel/syscall_table_32.S1
-rw-r--r--arch/x86/kernel/traps.c10
-rw-r--r--arch/x86/kernel/tsc.c8
-rw-r--r--arch/x86/kernel/tsc_sync.c14
-rw-r--r--arch/x86/kernel/vm86_32.c4
-rw-r--r--arch/x86/kernel/vmi_32.c20
-rw-r--r--arch/x86/kernel/vmlinux.lds.S432
-rw-r--r--arch/x86/kernel/vmlinux_32.lds.S229
-rw-r--r--arch/x86/kernel/vmlinux_64.lds.S298
-rw-r--r--arch/x86/kvm/Makefile2
-rw-r--r--arch/x86/kvm/i8254.c109
-rw-r--r--arch/x86/kvm/i8254.h12
-rw-r--r--arch/x86/kvm/irq.c7
-rw-r--r--arch/x86/kvm/kvm_timer.h18
-rw-r--r--arch/x86/kvm/lapic.c251
-rw-r--r--arch/x86/kvm/lapic.h12
-rw-r--r--arch/x86/kvm/mmu.c165
-rw-r--r--arch/x86/kvm/mmu.h5
-rw-r--r--arch/x86/kvm/paging_tmpl.h16
-rw-r--r--arch/x86/kvm/svm.c353
-rw-r--r--arch/x86/kvm/timer.c46
-rw-r--r--arch/x86/kvm/vmx.c557
-rw-r--r--arch/x86/kvm/x86.c373
-rw-r--r--arch/x86/kvm/x86.h11
-rw-r--r--arch/x86/kvm/x86_emulate.c121
-rw-r--r--arch/x86/lguest/boot.c18
-rw-r--r--arch/x86/mm/dump_pagetables.c7
-rw-r--r--arch/x86/mm/fault.c57
-rw-r--r--arch/x86/mm/highmem_32.c2
-rw-r--r--arch/x86/mm/init.c96
-rw-r--r--arch/x86/mm/init_32.c57
-rw-r--r--arch/x86/mm/init_64.c47
-rw-r--r--arch/x86/mm/iomap_32.c1
-rw-r--r--arch/x86/mm/kmmio.c104
-rw-r--r--arch/x86/mm/mmio-mod.c2
-rw-r--r--arch/x86/mm/numa_64.c15
-rw-r--r--arch/x86/mm/pageattr.c14
-rw-r--r--arch/x86/mm/srat_64.c7
-rw-r--r--arch/x86/oprofile/backtrace.c2
-rw-r--r--arch/x86/oprofile/nmi_int.c38
-rw-r--r--arch/x86/vdso/vma.c1
-rw-r--r--arch/x86/xen/enlighten.c65
-rw-r--r--arch/x86/xen/mmu.c28
-rw-r--r--arch/x86/xen/setup.c6
-rw-r--r--arch/x86/xen/xen-ops.h1
-rw-r--r--arch/xtensa/Kconfig6
-rw-r--r--arch/xtensa/include/asm/checksum.h6
-rw-r--r--block/Kconfig11
-rw-r--r--block/as-iosched.c24
-rw-r--r--block/blk-barrier.c17
-rw-r--r--block/blk-core.c668
-rw-r--r--block/blk-exec.c1
-rw-r--r--block/blk-map.c8
-rw-r--r--block/blk-merge.c46
-rw-r--r--block/blk-sysfs.c7
-rw-r--r--block/blk-tag.c2
-rw-r--r--block/blk-timeout.c22
-rw-r--r--block/blk.h49
-rw-r--r--block/bsg.c8
-rw-r--r--block/cfq-iosched.c36
-rw-r--r--block/compat_ioctl.c2
-rw-r--r--block/deadline-iosched.c2
-rw-r--r--block/elevator.c159
-rw-r--r--block/scsi_ioctl.c5
-rw-r--r--crypto/Kconfig10
-rw-r--r--crypto/algboss.c18
-rw-r--r--crypto/api.c8
-rw-r--r--crypto/cryptd.c14
-rw-r--r--crypto/eseqiv.c3
-rw-r--r--crypto/internal.h3
-rw-r--r--crypto/pcompress.c1
-rw-r--r--crypto/tcrypt.c25
-rw-r--r--crypto/testmgr.c286
-rw-r--r--crypto/testmgr.h645
-rw-r--r--drivers/acpi/acpica/Makefile27
-rw-r--r--drivers/acpi/acpica/acglobal.h3
-rw-r--r--drivers/acpi/acpica/dsobject.c5
-rw-r--r--drivers/acpi/acpica/dsopcode.c17
-rw-r--r--drivers/acpi/acpica/dswstate.c4
-rw-r--r--drivers/acpi/acpica/evxfevnt.c4
-rw-r--r--drivers/acpi/acpica/exmutex.c9
-rw-r--r--drivers/acpi/acpica/hwregs.c4
-rw-r--r--drivers/acpi/acpica/nsnames.c2
-rw-r--r--drivers/acpi/acpica/nspredef.c7
-rw-r--r--drivers/acpi/acpica/nssearch.c4
-rw-r--r--drivers/acpi/acpica/rscalc.c3
-rw-r--r--drivers/acpi/acpica/rsxface.c8
-rw-r--r--drivers/acpi/acpica/tbfadt.c16
-rw-r--r--drivers/acpi/acpica/tbinstal.c2
-rw-r--r--drivers/acpi/acpica/utcopy.c23
-rw-r--r--drivers/acpi/acpica/utdebug.c8
-rw-r--r--drivers/acpi/acpica/utmisc.c20
-rw-r--r--drivers/acpi/acpica/utmutex.c26
-rw-r--r--drivers/acpi/bus.c2
-rw-r--r--drivers/acpi/pci_irq.c5
-rw-r--r--drivers/acpi/processor_idle.c26
-rw-r--r--drivers/acpi/processor_throttling.c72
-rw-r--r--drivers/acpi/video.c38
-rw-r--r--drivers/ata/ahci.c17
-rw-r--r--drivers/ata/ata_piix.c18
-rw-r--r--drivers/ata/libata-core.c4
-rw-r--r--drivers/ata/libata-eh.c34
-rw-r--r--drivers/ata/libata-scsi.c6
-rw-r--r--drivers/ata/libata-sff.c20
-rw-r--r--drivers/ata/pata_pdc202xx_old.c6
-rw-r--r--drivers/ata/sata_mv.c69
-rw-r--r--drivers/ata/sata_sil.c2
-rw-r--r--drivers/ata/sata_sx4.c11
-rw-r--r--drivers/base/firmware_class.c129
-rw-r--r--drivers/base/iommu.c2
-rw-r--r--drivers/base/platform.c22
-rw-r--r--drivers/block/DAC960.c10
-rw-r--r--drivers/block/Kconfig2
-rw-r--r--drivers/block/amiflop.c54
-rw-r--r--drivers/block/ataflop.c66
-rw-r--r--drivers/block/cciss.c39
-rw-r--r--drivers/block/cpqarray.c16
-rw-r--r--drivers/block/floppy.c58
-rw-r--r--drivers/block/hd.c104
-rw-r--r--drivers/block/loop.c37
-rw-r--r--drivers/block/mg_disk.c535
-rw-r--r--drivers/block/nbd.c23
-rw-r--r--drivers/block/paride/pcd.c29
-rw-r--r--drivers/block/paride/pd.c22
-rw-r--r--drivers/block/paride/pf.c47
-rw-r--r--drivers/block/ps3disk.c22
-rw-r--r--drivers/block/sunvdc.c14
-rw-r--r--drivers/block/swim.c48
-rw-r--r--drivers/block/swim3.c107
-rw-r--r--drivers/block/sx8.c17
-rw-r--r--drivers/block/ub.c24
-rw-r--r--drivers/block/viodasd.c12
-rw-r--r--drivers/block/virtio_blk.c8
-rw-r--r--drivers/block/xd.c41
-rw-r--r--drivers/block/xen-blkfront.c30
-rw-r--r--drivers/block/xsysace.c44
-rw-r--r--drivers/block/z2ram.c19
-rw-r--r--drivers/cdrom/gdrom.c34
-rw-r--r--drivers/cdrom/viocd.c29
-rw-r--r--drivers/char/cyclades.c288
-rw-r--r--drivers/char/epca.c13
-rw-r--r--drivers/char/hpet.c4
-rw-r--r--drivers/char/hw_random/omap-rng.c2
-rw-r--r--drivers/char/isicom.c19
-rw-r--r--drivers/char/istallion.c8
-rw-r--r--drivers/char/keyboard.c2
-rw-r--r--drivers/char/mxser.c12
-rw-r--r--drivers/char/pcmcia/synclink_cs.c11
-rw-r--r--drivers/char/random.c19
-rw-r--r--drivers/char/rocket.c19
-rw-r--r--drivers/char/stallion.c6
-rw-r--r--drivers/char/synclink.c9
-rw-r--r--drivers/char/synclink_gt.c86
-rw-r--r--drivers/char/synclinkmp.c9
-rw-r--r--drivers/char/tpm/tpm_bios.c3
-rw-r--r--drivers/char/tty_port.c38
-rw-r--r--drivers/char/vt_ioctl.c6
-rw-r--r--drivers/clocksource/Makefile2
-rw-r--r--drivers/clocksource/sh_cmt.c116
-rw-r--r--drivers/clocksource/sh_mtu2.c357
-rw-r--r--drivers/clocksource/sh_tmu.c461
-rw-r--r--drivers/crypto/Kconfig2
-rw-r--r--drivers/crypto/ixp4xx_crypto.c33
-rw-r--r--drivers/crypto/padlock-aes.c15
-rw-r--r--drivers/crypto/talitos.c713
-rw-r--r--drivers/dma/Kconfig8
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/dmaengine.c17
-rw-r--r--drivers/dma/dmatest.c4
-rw-r--r--drivers/dma/fsldma.c13
-rw-r--r--drivers/dma/ioat_dma.c45
-rw-r--r--drivers/dma/ipu/ipu_idmac.c7
-rw-r--r--drivers/dma/txx9dmac.c1354
-rw-r--r--drivers/dma/txx9dmac.h307
-rw-r--r--drivers/firmware/dcdbas.c49
-rw-r--r--drivers/gpu/drm/Kconfig7
-rw-r--r--drivers/hid/Kconfig7
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-ids.h6
-rw-r--r--drivers/hid/hid-lgff.c2
-rw-r--r--drivers/hid/hid-wacom.c259
-rw-r--r--drivers/hid/usbhid/hid-core.c2
-rw-r--r--drivers/hid/usbhid/hid-quirks.c3
-rw-r--r--drivers/hwmon/Kconfig2
-rw-r--r--drivers/hwmon/asus_atk0110.c2
-rw-r--r--drivers/hwmon/ibmaem.c1
-rw-r--r--drivers/hwmon/w83781d.c3
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-cpm.c16
-rw-r--r--drivers/i2c/busses/i2c-mpc.c34
-rw-r--r--drivers/i2c/busses/i2c-pxa.c28
-rw-r--r--drivers/i2c/busses/i2c-voodoo3.c1
-rw-r--r--drivers/i2c/chips/Kconfig15
-rw-r--r--drivers/i2c/chips/Makefile1
-rw-r--r--drivers/i2c/i2c-core.c535
-rw-r--r--drivers/ide/alim15x3.c10
-rw-r--r--drivers/ide/ide-atapi.c177
-rw-r--r--drivers/ide/ide-cd.c140
-rw-r--r--drivers/ide/ide-cd.h4
-rw-r--r--drivers/ide/ide-disk.c9
-rw-r--r--drivers/ide/ide-dma.c22
-rw-r--r--drivers/ide/ide-floppy.c32
-rw-r--r--drivers/ide/ide-io.c57
-rw-r--r--drivers/ide/ide-ioctls.c1
-rw-r--r--drivers/ide/ide-lib.c2
-rw-r--r--drivers/ide/ide-park.c7
-rw-r--r--drivers/ide/ide-pm.c38
-rw-r--r--drivers/ide/ide-tape.c741
-rw-r--r--drivers/ide/ide-taskfile.c20
-rw-r--r--drivers/ide/pdc202xx_old.c2
-rw-r--r--drivers/ide/tc86c001.c2
-rw-r--r--drivers/ide/tx4939ide.c2
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c94
-rw-r--r--drivers/infiniband/hw/ehca/hcp_if.c6
-rw-r--r--drivers/infiniband/hw/ehca/hcp_if.h2
-rw-r--r--drivers/infiniband/hw/ehca/hcp_phyp.c11
-rw-r--r--drivers/infiniband/hw/ehca/hcp_phyp.h2
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.c19
-rw-r--r--drivers/infiniband/hw/ipath/ipath_fs.c2
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h1
-rw-r--r--drivers/infiniband/hw/mlx4/mr.c10
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c2
-rw-r--r--drivers/input/evdev.c9
-rw-r--r--drivers/input/ff-memless.c2
-rw-r--r--drivers/input/gameport/fm801-gp.c1
-rw-r--r--drivers/input/gameport/gameport.c25
-rw-r--r--drivers/input/joydev.c22
-rw-r--r--drivers/input/keyboard/Kconfig10
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/atkbd.c16
-rw-r--r--drivers/input/keyboard/ep93xx_keypad.c470
-rw-r--r--drivers/input/keyboard/gpio_keys.c3
-rw-r--r--drivers/input/misc/Kconfig19
-rw-r--r--drivers/input/misc/Makefile2
-rw-r--r--drivers/input/misc/dm355evm_keys.c329
-rw-r--r--drivers/input/misc/rotary_encoder.c61
-rw-r--r--drivers/input/misc/twl4030-pwrbutton.c145
-rw-r--r--drivers/input/mouse/alps.c18
-rw-r--r--drivers/input/mouse/lifebook.c25
-rw-r--r--drivers/input/mousedev.c9
-rw-r--r--drivers/input/serio/i8042.c17
-rw-r--r--drivers/input/serio/serio.c58
-rw-r--r--drivers/input/tablet/gtco.c1
-rw-r--r--drivers/input/tablet/wacom.h5
-rw-r--r--drivers/input/tablet/wacom_sys.c13
-rw-r--r--drivers/input/tablet/wacom_wac.c168
-rw-r--r--drivers/input/tablet/wacom_wac.h3
-rw-r--r--drivers/input/touchscreen/Kconfig15
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/atmel-wm97xx.c446
-rw-r--r--drivers/input/touchscreen/tsc2007.c5
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c2
-rw-r--r--drivers/isdn/capi/capifs.c11
-rw-r--r--drivers/macintosh/therm_adt746x.c84
-rw-r--r--drivers/macintosh/therm_pm72.c95
-rw-r--r--drivers/macintosh/therm_windtunnel.c126
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c129
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c103
-rw-r--r--drivers/macintosh/windfarm_smu_sat.c109
-rw-r--r--drivers/md/bitmap.c29
-rw-r--r--drivers/md/dm-crypt.c8
-rw-r--r--drivers/md/dm-delay.c6
-rw-r--r--drivers/md/dm-io.c14
-rw-r--r--drivers/md/dm-linear.c4
-rw-r--r--drivers/md/dm-mpath.c92
-rw-r--r--drivers/md/dm-region-hash.c2
-rw-r--r--drivers/md/dm-snap-persistent.c2
-rw-r--r--drivers/md/dm-snap.c11
-rw-r--r--drivers/md/dm-stripe.c15
-rw-r--r--drivers/md/dm-table.c123
-rw-r--r--drivers/md/dm.c194
-rw-r--r--drivers/md/md.c70
-rw-r--r--drivers/md/raid10.c12
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c80
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c7
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h3
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/dvb/frontends/Kconfig22
-rw-r--r--drivers/media/dvb/frontends/Makefile4
-rw-r--r--drivers/media/dvb/frontends/isl6423.c308
-rw-r--r--drivers/media/dvb/frontends/isl6423.h63
-rw-r--r--drivers/media/dvb/frontends/stv0900_priv.h2
-rw-r--r--drivers/media/dvb/frontends/stv090x.c4299
-rw-r--r--drivers/media/dvb/frontends/stv090x.h106
-rw-r--r--drivers/media/dvb/frontends/stv090x_priv.h269
-rw-r--r--drivers/media/dvb/frontends/stv090x_reg.h2373
-rw-r--r--drivers/media/dvb/frontends/stv6110x.c373
-rw-r--r--drivers/media/dvb/frontends/stv6110x.h71
-rw-r--r--drivers/media/dvb/frontends/stv6110x_priv.h75
-rw-r--r--drivers/media/dvb/frontends/stv6110x_reg.h82
-rw-r--r--drivers/media/dvb/frontends/tda10048.c219
-rw-r--r--drivers/media/dvb/frontends/tda10048.h14
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c36
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h119
-rw-r--r--drivers/media/dvb/siano/smsendian.c100
-rw-r--r--drivers/media/dvb/siano/smsendian.h32
-rw-r--r--drivers/media/dvb/siano/smsir.c301
-rw-r--r--drivers/media/dvb/siano/smsir.h93
-rw-r--r--drivers/media/dvb/siano/smssdio.c354
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c2
-rw-r--r--drivers/media/dvb/ttpci/budget.c85
-rw-r--r--drivers/media/radio/radio-sf16fmi.c2
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c2
-rw-r--r--drivers/media/radio/radio-si470x.c1
-rw-r--r--drivers/media/video/Makefile9
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c21
-rw-r--r--drivers/media/video/cafe_ccic.c1
-rw-r--r--drivers/media/video/cx18/cx18-audio.c44
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c234
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c82
-rw-r--r--drivers/media/video/cx18/cx18-controls.c6
-rw-r--r--drivers/media/video/cx18/cx18-driver.c95
-rw-r--r--drivers/media/video/cx18/cx18-driver.h17
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c1
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c7
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c114
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h2
-rw-r--r--drivers/media/video/cx18/cx18-queue.c85
-rw-r--r--drivers/media/video/cx18/cx18-streams.c35
-rw-r--r--drivers/media/video/cx18/cx18-streams.h20
-rw-r--r--drivers/media/video/cx18/cx18-version.h2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c8
-rw-r--r--drivers/media/video/cx231xx/cx231xx-i2c.c32
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-vbi.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c10
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c6
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c12
-rw-r--r--drivers/media/video/cx88/Makefile2
-rw-r--r--drivers/media/video/cx88/cx88-cards.c13
-rw-r--r--drivers/media/video/cx88/cx88-core.c26
-rw-r--r--drivers/media/video/cx88/cx88-dsp.c312
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c13
-rw-r--r--drivers/media/video/cx88/cx88-input.c2
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c115
-rw-r--r--drivers/media/video/cx88/cx88.h11
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c70
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c25
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c8
-rw-r--r--drivers/media/video/em28xx/em28xx.h3
-rw-r--r--drivers/media/video/gspca/finepix.c1
-rw-r--r--drivers/media/video/gspca/gspca.c50
-rw-r--r--drivers/media/video/gspca/gspca.h6
-rw-r--r--drivers/media/video/gspca/m5602/Makefile3
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h26
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c44
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c400
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h805
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.c227
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.h279
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c195
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h57
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c494
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h439
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c385
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h93
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c473
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h280
-rw-r--r--drivers/media/video/gspca/m5602/m5602_sensor.h9
-rw-r--r--drivers/media/video/gspca/mr97310a.c8
-rw-r--r--drivers/media/video/gspca/ov534.c30
-rw-r--r--drivers/media/video/gspca/sonixb.c2
-rw-r--r--drivers/media/video/gspca/sonixj.c66
-rw-r--r--drivers/media/video/gspca/spca500.c33
-rw-r--r--drivers/media/video/gspca/sq905.c1
-rw-r--r--drivers/media/video/gspca/sq905c.c1
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c76
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h10
-rw-r--r--drivers/media/video/gspca/sunplus.c33
-rw-r--r--drivers/media/video/gspca/t613.c2
-rw-r--r--drivers/media/video/gspca/vc032x.c22
-rw-r--r--drivers/media/video/gspca/zc3xx.c22
-rw-r--r--drivers/media/video/ir-kbd-i2c.c222
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c16
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c36
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c5
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c3
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c3
-rw-r--r--drivers/media/video/mt9m001.c108
-rw-r--r--drivers/media/video/mt9m111.c73
-rw-r--r--drivers/media/video/mt9t031.c135
-rw-r--r--drivers/media/video/mt9v022.c138
-rw-r--r--drivers/media/video/mx1_camera.c50
-rw-r--r--drivers/media/video/mx3_camera.c40
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c39
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c24
-rw-r--r--drivers/media/video/pxa_camera.c120
-rw-r--r--drivers/media/video/s2255drv.c47
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c436
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c31
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c117
-rw-r--r--drivers/media/video/saa7134/saa7134.h16
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c27
-rw-r--r--drivers/media/video/soc_camera.c106
-rw-r--r--drivers/media/video/tda7432.c14
-rw-r--r--drivers/media/video/tuner-core.c27
-rw-r--r--drivers/media/video/uvc/uvc_driver.c9
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c10
-rw-r--r--drivers/media/video/uvc/uvc_video.c2
-rw-r--r--drivers/media/video/v4l2-common.c4
-rw-r--r--drivers/media/video/v4l2-device.c29
-rw-r--r--drivers/media/video/v4l2-ioctl.c45
-rw-r--r--drivers/media/video/zoran/zoran_driver.c28
-rw-r--r--drivers/memstick/core/mspro_block.c17
-rw-r--r--drivers/message/fusion/mptsas.c21
-rw-r--r--drivers/message/i2o/i2o_block.c38
-rw-r--r--drivers/mfd/htc-pasic3.c4
-rw-r--r--drivers/mfd/pcf50633-core.c2
-rw-r--r--drivers/mfd/twl4030-core.c2
-rw-r--r--drivers/mfd/wm8350-core.c8
-rw-r--r--drivers/mfd/wm8350-regmap.c4
-rw-r--r--drivers/mfd/wm8400-core.c2
-rw-r--r--drivers/misc/eeprom/Kconfig14
-rw-r--r--drivers/misc/eeprom/Makefile1
-rw-r--r--drivers/misc/eeprom/max6875.c (renamed from drivers/i2c/chips/max6875.c)2
-rw-r--r--drivers/misc/isl29003.c9
-rw-r--r--drivers/mmc/card/block.c10
-rw-r--r--drivers/mmc/card/queue.c11
-rw-r--r--drivers/mmc/core/core.c107
-rw-r--r--drivers/mmc/host/atmel-mci.c12
-rw-r--r--drivers/mmc/host/mmc_spi.c12
-rw-r--r--drivers/mmc/host/mxcmmc.c45
-rw-r--r--drivers/mmc/host/omap.c3
-rw-r--r--drivers/mmc/host/omap_hsmmc.c2
-rw-r--r--drivers/mmc/host/sdhci.c53
-rw-r--r--drivers/mmc/host/sdhci.h2
-rw-r--r--drivers/mtd/devices/m25p80.c26
-rw-r--r--drivers/mtd/mtd_blkdevs.c41
-rw-r--r--drivers/mtd/mtdcore.c18
-rw-r--r--drivers/mtd/mtdsuper.c3
-rw-r--r--drivers/net/3c509.c12
-rw-r--r--drivers/net/8139too.c92
-rw-r--r--drivers/net/8390.c10
-rw-r--r--drivers/net/8390p.c19
-rw-r--r--drivers/net/Kconfig15
-rw-r--r--drivers/net/Makefile3
-rw-r--r--drivers/net/arm/ixp4xx_eth.c31
-rw-r--r--drivers/net/atl1c/atl1c_main.c24
-rw-r--r--drivers/net/atl1e/atl1e_main.c3
-rw-r--r--drivers/net/atlx/atl1.c7
-rw-r--r--drivers/net/benet/be_main.c28
-rw-r--r--drivers/net/bmac.c16
-rw-r--r--drivers/net/bnx2.c6
-rw-r--r--drivers/net/bnx2x.h15
-rw-r--r--drivers/net/bnx2x_fw_file_hdr.h37
-rw-r--r--drivers/net/bnx2x_init.h605
-rw-r--r--drivers/net/bnx2x_init_ops.h442
-rw-r--r--drivers/net/bnx2x_init_values.h16322
-rw-r--r--drivers/net/bnx2x_main.c358
-rw-r--r--drivers/net/bonding/bond_3ad.c5
-rw-r--r--drivers/net/bonding/bond_3ad.h4
-rw-r--r--drivers/net/bonding/bond_main.c72
-rw-r--r--drivers/net/chelsio/common.h2
-rw-r--r--drivers/net/chelsio/cphy.h45
-rw-r--r--drivers/net/chelsio/cxgb2.c36
-rw-r--r--drivers/net/chelsio/mv88x201x.c45
-rw-r--r--drivers/net/chelsio/my3126.c10
-rw-r--r--drivers/net/chelsio/sge.c4
-rw-r--r--drivers/net/chelsio/subr.c43
-rw-r--r--drivers/net/cpmac.c23
-rw-r--r--drivers/net/cxgb3/adapter.h2
-rw-r--r--drivers/net/cxgb3/ael1002.c146
-rw-r--r--drivers/net/cxgb3/common.h53
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c71
-rw-r--r--drivers/net/cxgb3/sge.c53
-rw-r--r--drivers/net/cxgb3/t3_hw.c78
-rw-r--r--drivers/net/cxgb3/vsc8211.c70
-rw-r--r--drivers/net/depca.c4
-rw-r--r--drivers/net/dm9000.c30
-rw-r--r--drivers/net/e1000/e1000_main.c15
-rw-r--r--drivers/net/e1000e/netdev.c19
-rw-r--r--drivers/net/ehea/ehea_main.c8
-rw-r--r--drivers/net/fec.c897
-rw-r--r--drivers/net/fec.h127
-rw-r--r--drivers/net/fec_mpc52xx.c180
-rw-r--r--drivers/net/fec_mpc52xx_phy.c26
-rw-r--r--drivers/net/forcedeth.c23
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c108
-rw-r--r--drivers/net/fs_enet/fs_enet.h5
-rw-r--r--drivers/net/fs_enet/mac-fec.c34
-rw-r--r--drivers/net/fs_enet/mii-bitbang.c29
-rw-r--r--drivers/net/fs_enet/mii-fec.c32
-rw-r--r--drivers/net/fsl_pq_mdio.c53
-rw-r--r--drivers/net/gianfar.c112
-rw-r--r--drivers/net/gianfar.h4
-rw-r--r--drivers/net/hp100.c4
-rw-r--r--drivers/net/hplance.c21
-rw-r--r--drivers/net/ibmveth.c40
-rw-r--r--drivers/net/igb/e1000_82575.h1
-rw-r--r--drivers/net/igb/e1000_defines.h3
-rw-r--r--drivers/net/igb/e1000_mbx.c8
-rw-r--r--drivers/net/igb/igb.h2
-rw-r--r--drivers/net/igb/igb_ethtool.c20
-rw-r--r--drivers/net/igb/igb_main.c113
-rw-r--r--drivers/net/igbvf/ethtool.c36
-rw-r--r--drivers/net/igbvf/igbvf.h6
-rw-r--r--drivers/net/igbvf/netdev.c17
-rw-r--r--drivers/net/irda/au1k_ir.c18
-rw-r--r--drivers/net/irda/pxaficp_ir.c16
-rw-r--r--drivers/net/irda/sa1100_ir.c18
-rw-r--r--drivers/net/iseries_veth.c17
-rw-r--r--drivers/net/ixgb/ixgb_hw.c20
-rw-r--r--drivers/net/ixgb/ixgb_hw.h14
-rw-r--r--drivers/net/ixgb/ixgb_main.c15
-rw-r--r--drivers/net/ixgb/ixgb_osdep.h2
-rw-r--r--drivers/net/ixgbe/ixgbe.h11
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c209
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c256
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c9
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c16
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c37
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c703
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c136
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.h1
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h66
-rw-r--r--drivers/net/ixp2000/ixpdev.c19
-rw-r--r--drivers/net/jazzsonic.c19
-rw-r--r--drivers/net/korina.c25
-rw-r--r--drivers/net/lasi_82596.c6
-rw-r--r--drivers/net/lib82596.c23
-rw-r--r--drivers/net/ll_temac.h374
-rw-r--r--drivers/net/ll_temac_main.c969
-rw-r--r--drivers/net/ll_temac_mdio.c120
-rw-r--r--drivers/net/loopback.c21
-rw-r--r--drivers/net/macb.c18
-rw-r--r--drivers/net/mace.c16
-rw-r--r--drivers/net/macmace.c18
-rw-r--r--drivers/net/macvlan.c22
-rw-r--r--drivers/net/mdio.c414
-rw-r--r--drivers/net/meth.c28
-rw-r--r--drivers/net/mii.c91
-rw-r--r--drivers/net/mipsnet.c15
-rw-r--r--drivers/net/mlx4/en_rx.c1
-rw-r--r--drivers/net/mv643xx_eth.c87
-rw-r--r--drivers/net/mvme147.c17
-rw-r--r--drivers/net/myri10ge/myri10ge.c38
-rw-r--r--drivers/net/ne2k-pci.c2
-rw-r--r--drivers/net/ne3210.c4
-rw-r--r--drivers/net/netx-eth.c17
-rw-r--r--drivers/net/netxen/netxen_nic.h624
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c241
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c106
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h8
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c737
-rw-r--r--drivers/net/netxen/netxen_nic_hw.h76
-rw-r--r--drivers/net/netxen/netxen_nic_init.c536
-rw-r--r--drivers/net/netxen/netxen_nic_main.c411
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c341
-rw-r--r--drivers/net/netxen/netxen_nic_phan_reg.h27
-rw-r--r--drivers/net/pasemi_mac.c58
-rw-r--r--drivers/net/pasemi_mac.h1
-rw-r--r--drivers/net/pci-skeleton.c19
-rw-r--r--drivers/net/pcmcia/3c574_cs.c2
-rw-r--r--drivers/net/pcmcia/3c589_cs.c4
-rw-r--r--drivers/net/pcnet32.c5
-rw-r--r--drivers/net/phy/mdio_bus.c29
-rw-r--r--drivers/net/phy/phy_device.c163
-rw-r--r--drivers/net/pppol2tp.c3
-rw-r--r--drivers/net/r6040.c12
-rw-r--r--drivers/net/r8169.c61
-rw-r--r--drivers/net/rionet.c14
-rw-r--r--drivers/net/s2io-regs.h5
-rw-r--r--drivers/net/s2io.c21
-rw-r--r--drivers/net/sb1250-mac.c35
-rw-r--r--drivers/net/sfc/Kconfig2
-rw-r--r--drivers/net/sfc/boards.c2
-rw-r--r--drivers/net/sfc/efx.c10
-rw-r--r--drivers/net/sfc/ethtool.c19
-rw-r--r--drivers/net/sfc/falcon.c137
-rw-r--r--drivers/net/sfc/falcon_hwdefs.h3
-rw-r--r--drivers/net/sfc/falcon_xmac.c2
-rw-r--r--drivers/net/sfc/mdio_10g.c385
-rw-r--r--drivers/net/sfc/mdio_10g.h282
-rw-r--r--drivers/net/sfc/net_driver.h34
-rw-r--r--drivers/net/sfc/rx.c26
-rw-r--r--drivers/net/sfc/selftest.c21
-rw-r--r--drivers/net/sfc/selftest.h2
-rw-r--r--drivers/net/sfc/sfe4001.c3
-rw-r--r--drivers/net/sfc/tenxpress.c226
-rw-r--r--drivers/net/sfc/xenpack.h15
-rw-r--r--drivers/net/sfc/xfp_phy.c51
-rw-r--r--drivers/net/sgiseeq.c18
-rw-r--r--drivers/net/slip.c96
-rw-r--r--drivers/net/smc-mca.c4
-rw-r--r--drivers/net/smc911x.c23
-rw-r--r--drivers/net/smsc911x.c61
-rw-r--r--drivers/net/sun3lance.c17
-rw-r--r--drivers/net/tg3.c89
-rw-r--r--drivers/net/tg3.h6
-rw-r--r--drivers/net/tulip/de4x5.c6
-rw-r--r--drivers/net/tulip/winbond-840.c3
-rw-r--r--drivers/net/tun.c26
-rw-r--r--drivers/net/ucc_geth.c99
-rw-r--r--drivers/net/ucc_geth.h7
-rw-r--r--drivers/net/usb/Kconfig8
-rw-r--r--drivers/net/usb/Makefile1
-rw-r--r--drivers/net/usb/cdc_ether.c33
-rw-r--r--drivers/net/usb/hso.c8
-rw-r--r--drivers/net/usb/int51x1.c253
-rw-r--r--drivers/net/usb/kaweth.c33
-rw-r--r--drivers/net/usb/usbnet.c37
-rw-r--r--drivers/net/virtio_net.c12
-rw-r--r--drivers/net/vxge/vxge-traffic.c4
-rw-r--r--drivers/net/wan/ixp4xx_hss.c4
-rw-r--r--drivers/net/wan/pc300_drv.c20
-rw-r--r--drivers/net/wireless/Kconfig17
-rw-r--r--drivers/net/wireless/Makefile6
-rw-r--r--drivers/net/wireless/adm8211.c14
-rw-r--r--drivers/net/wireless/airo.c10
-rw-r--r--drivers/net/wireless/at76c50x-usb.c19
-rw-r--r--drivers/net/wireless/ath/Kconfig8
-rw-r--r--drivers/net/wireless/ath/Makefile6
-rw-r--r--drivers/net/wireless/ath/ar9170/Kconfig (renamed from drivers/net/wireless/ar9170/Kconfig)1
-rw-r--r--drivers/net/wireless/ath/ar9170/Makefile (renamed from drivers/net/wireless/ar9170/Makefile)0
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h (renamed from drivers/net/wireless/ar9170/ar9170.h)32
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.c (renamed from drivers/net/wireless/ar9170/cmd.c)0
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.h (renamed from drivers/net/wireless/ar9170/cmd.h)0
-rw-r--r--drivers/net/wireless/ath/ar9170/eeprom.h (renamed from drivers/net/wireless/ar9170/eeprom.h)0
-rw-r--r--drivers/net/wireless/ath/ar9170/hw.h (renamed from drivers/net/wireless/ar9170/hw.h)17
-rw-r--r--drivers/net/wireless/ath/ar9170/led.c (renamed from drivers/net/wireless/ar9170/led.c)0
-rw-r--r--drivers/net/wireless/ath/ar9170/mac.c (renamed from drivers/net/wireless/ar9170/mac.c)33
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c (renamed from drivers/net/wireless/ar9170/main.c)657
-rw-r--r--drivers/net/wireless/ath/ar9170/phy.c (renamed from drivers/net/wireless/ar9170/phy.c)0
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c (renamed from drivers/net/wireless/ar9170/usb.c)6
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.h (renamed from drivers/net/wireless/ar9170/usb.h)2
-rw-r--r--drivers/net/wireless/ath/ath5k/Kconfig (renamed from drivers/net/wireless/ath5k/Kconfig)1
-rw-r--r--drivers/net/wireless/ath/ath5k/Makefile (renamed from drivers/net/wireless/ath5k/Makefile)0
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h (renamed from drivers/net/wireless/ath5k/ath5k.h)42
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c (renamed from drivers/net/wireless/ath5k/attach.c)1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c (renamed from drivers/net/wireless/ath5k/base.c)306
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h (renamed from drivers/net/wireless/ath5k/base.h)1
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c (renamed from drivers/net/wireless/ath5k/caps.c)0
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c (renamed from drivers/net/wireless/ath5k/debug.c)0
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h (renamed from drivers/net/wireless/ath5k/debug.h)0
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c (renamed from drivers/net/wireless/ath5k/desc.c)0
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h (renamed from drivers/net/wireless/ath5k/desc.h)0
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c (renamed from drivers/net/wireless/ath5k/dma.c)2
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c (renamed from drivers/net/wireless/ath5k/eeprom.c)73
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h (renamed from drivers/net/wireless/ath5k/eeprom.h)46
-rw-r--r--drivers/net/wireless/ath/ath5k/gpio.c (renamed from drivers/net/wireless/ath5k/gpio.c)0
-rw-r--r--drivers/net/wireless/ath/ath5k/initvals.c (renamed from drivers/net/wireless/ath5k/initvals.c)8
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c (renamed from drivers/net/wireless/ath5k/led.c)10
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c (renamed from drivers/net/wireless/ath5k/pcu.c)6
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c (renamed from drivers/net/wireless/ath5k/phy.c)542
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c (renamed from drivers/net/wireless/ath5k/qcu.c)7
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h (renamed from drivers/net/wireless/ath5k/reg.h)9
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c (renamed from drivers/net/wireless/ath5k/reset.c)77
-rw-r--r--drivers/net/wireless/ath/ath5k/rfbuffer.h (renamed from drivers/net/wireless/ath5k/rfbuffer.h)0
-rw-r--r--drivers/net/wireless/ath/ath5k/rfgain.h (renamed from drivers/net/wireless/ath5k/rfgain.h)0
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig (renamed from drivers/net/wireless/ath9k/Kconfig)1
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile (renamed from drivers/net/wireless/ath9k/Makefile)1
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c (renamed from drivers/net/wireless/ath9k/ahb.c)0
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c (renamed from drivers/net/wireless/ath9k/ani.c)8
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h (renamed from drivers/net/wireless/ath9k/ani.h)0
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h (renamed from drivers/net/wireless/ath9k/ath9k.h)110
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c (renamed from drivers/net/wireless/ath9k/beacon.c)28
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c (renamed from drivers/net/wireless/ath9k/calib.c)129
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h (renamed from drivers/net/wireless/ath9k/calib.h)33
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c (renamed from drivers/net/wireless/ath9k/debug.c)3
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h (renamed from drivers/net/wireless/ath9k/debug.h)24
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c (renamed from drivers/net/wireless/ath9k/eeprom.c)75
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h (renamed from drivers/net/wireless/ath9k/eeprom.h)4
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c (renamed from drivers/net/wireless/ath9k/hw.c)261
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h (renamed from drivers/net/wireless/ath9k/hw.h)95
-rw-r--r--drivers/net/wireless/ath/ath9k/initvals.h (renamed from drivers/net/wireless/ath9k/initvals.h)0
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c (renamed from drivers/net/wireless/ath9k/mac.c)63
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h (renamed from drivers/net/wireless/ath9k/mac.h)0
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c (renamed from drivers/net/wireless/ath9k/main.c)579
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c (renamed from drivers/net/wireless/ath9k/pci.c)0
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.c (renamed from drivers/net/wireless/ath9k/phy.c)11
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h (renamed from drivers/net/wireless/ath9k/phy.h)5
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c (renamed from drivers/net/wireless/ath9k/rc.c)96
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h (renamed from drivers/net/wireless/ath9k/rc.h)4
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c (renamed from drivers/net/wireless/ath9k/recv.c)85
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h (renamed from drivers/net/wireless/ath9k/reg.h)0
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c (renamed from drivers/net/wireless/ath9k/virtual.c)0
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c (renamed from drivers/net/wireless/ath9k/xmit.c)74
-rw-r--r--drivers/net/wireless/ath/main.c22
-rw-r--r--drivers/net/wireless/ath/regd.c (renamed from drivers/net/wireless/ath9k/regd.c)241
-rw-r--r--drivers/net/wireless/ath/regd.h (renamed from drivers/net/wireless/ath9k/regd.h)40
-rw-r--r--drivers/net/wireless/ath/regd_common.h (renamed from drivers/net/wireless/ath9k/regd_common.h)0
-rw-r--r--drivers/net/wireless/atmel_cs.c2
-rw-r--r--drivers/net/wireless/b43/Kconfig8
-rw-r--r--drivers/net/wireless/b43/b43.h8
-rw-r--r--drivers/net/wireless/b43/main.c145
-rw-r--r--drivers/net/wireless/b43legacy/Kconfig8
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h8
-rw-r--r--drivers/net/wireless/b43legacy/main.c266
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c2
-rw-r--r--drivers/net/wireless/b43legacy/xmit.h4
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c2
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c8
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c54
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c218
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c526
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c904
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c727
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h58
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c96
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c233
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c209
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c48
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c1137
-rw-r--r--drivers/net/wireless/libertas/cmd.c26
-rw-r--r--drivers/net/wireless/libertas/defs.h21
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/host.h3
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h28
-rw-r--r--drivers/net/wireless/libertas/if_cs.c34
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c17
-rw-r--r--drivers/net/wireless/libertas/if_sdio.h2
-rw-r--r--drivers/net/wireless/libertas/if_spi.c6
-rw-r--r--drivers/net/wireless/libertas/if_usb.c3
-rw-r--r--drivers/net/wireless/libertas/main.c44
-rw-r--r--drivers/net/wireless/libertas/rx.c48
-rw-r--r--drivers/net/wireless/libertas/tx.c8
-rw-r--r--drivers/net/wireless/libertas/types.h2
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c3
-rw-r--r--drivers/net/wireless/libertas_tf/main.c56
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c47
-rw-r--r--drivers/net/wireless/mwl8k.c20
-rw-r--r--drivers/net/wireless/p54/p54.h74
-rw-r--r--drivers/net/wireless/p54/p54common.c302
-rw-r--r--drivers/net/wireless/p54/p54spi.c127
-rw-r--r--drivers/net/wireless/p54/p54usb.c314
-rw-r--r--drivers/net/wireless/p54/p54usb.h16
-rw-r--r--drivers/net/wireless/ray_cs.c2
-rw-r--r--drivers/net/wireless/rndis_wlan.c652
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig17
-rw-r--r--drivers/net/wireless/rt2x00/Makefile2
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c3071
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h1945
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h50
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c87
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c125
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c69
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h65
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c88
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c48
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h53
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c4
-rw-r--r--drivers/net/wireless/rtl818x/Makefile2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c33
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h64
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c82
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.c218
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.h57
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rtl8225.c8
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig11
-rw-r--r--drivers/net/wireless/wl12xx/Makefile4
-rw-r--r--drivers/net/wireless/wl12xx/acx.c689
-rw-r--r--drivers/net/wireless/wl12xx/acx.h1245
-rw-r--r--drivers/net/wireless/wl12xx/boot.c295
-rw-r--r--drivers/net/wireless/wl12xx/boot.h40
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c353
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h265
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c508
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.h33
-rw-r--r--drivers/net/wireless/wl12xx/event.c127
-rw-r--r--drivers/net/wireless/wl12xx/event.h121
-rw-r--r--drivers/net/wireless/wl12xx/init.c200
-rw-r--r--drivers/net/wireless/wl12xx/init.h40
-rw-r--r--drivers/net/wireless/wl12xx/main.c1358
-rw-r--r--drivers/net/wireless/wl12xx/ps.c151
-rw-r--r--drivers/net/wireless/wl12xx/ps.h36
-rw-r--r--drivers/net/wireless/wl12xx/reg.h745
-rw-r--r--drivers/net/wireless/wl12xx/rx.c208
-rw-r--r--drivers/net/wireless/wl12xx/rx.h122
-rw-r--r--drivers/net/wireless/wl12xx/spi.c358
-rw-r--r--drivers/net/wireless/wl12xx/spi.h109
-rw-r--r--drivers/net/wireless/wl12xx/tx.c557
-rw-r--r--drivers/net/wireless/wl12xx/tx.h215
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.c709
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h165
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h409
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_80211.h156
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c80
-rw-r--r--drivers/of/Kconfig6
-rw-r--r--drivers/of/Makefile1
-rw-r--r--drivers/of/base.c25
-rw-r--r--drivers/of/of_mdio.c139
-rw-r--r--drivers/oprofile/cpu_buffer.c8
-rw-r--r--drivers/parisc/iosapic.c6
-rw-r--r--drivers/pci/bus.c7
-rw-r--r--drivers/pci/dmar.c44
-rw-r--r--drivers/pci/hotplug/Kconfig2
-rw-r--r--drivers/pci/hotplug/cpqphp.h167
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c1101
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c371
-rw-r--r--drivers/pci/hotplug/cpqphp_nvram.c97
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c599
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c1
-rw-r--r--drivers/pci/htirq.c4
-rw-r--r--drivers/pci/intel-iommu.c342
-rw-r--r--drivers/pci/intr_remapping.c62
-rw-r--r--drivers/pci/msi.c10
-rw-r--r--drivers/pci/msi.h14
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h3
-rw-r--r--drivers/pci/pcie/portdrv_core.c2
-rw-r--r--drivers/pci/pcie/portdrv_pci.c2
-rw-r--r--drivers/pci/probe.c9
-rw-r--r--drivers/pci/quirks.c2
-rw-r--r--drivers/pci/search.c30
-rw-r--r--drivers/pci/setup-bus.c53
-rw-r--r--drivers/pci/setup-res.c49
-rw-r--r--drivers/platform/x86/Kconfig13
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/oqo-wmi.c941
-rw-r--r--drivers/platform/x86/toshiba_acpi.c206
-rw-r--r--drivers/pnp/pnpacpi/core.c8
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c2
-rw-r--r--drivers/rapidio/rio-scan.c6
-rw-r--r--drivers/regulator/Kconfig19
-rw-r--r--drivers/regulator/Makefile2
-rw-r--r--drivers/regulator/da903x.c2
-rw-r--r--drivers/regulator/fixed.c18
-rw-r--r--drivers/regulator/max1586.c249
-rw-r--r--drivers/regulator/pcf50633-regulator.c2
-rw-r--r--drivers/regulator/userspace-consumer.c200
-rw-r--r--drivers/regulator/virtual.c1
-rw-r--r--drivers/regulator/wm8350-regulator.c1
-rw-r--r--drivers/regulator/wm8400-regulator.c8
-rw-r--r--drivers/rtc/Kconfig21
-rw-r--r--drivers/rtc/Makefile2
-rw-r--r--drivers/rtc/rtc-ep93xx.c149
-rw-r--r--drivers/rtc/rtc-msm6242.c268
-rw-r--r--drivers/rtc/rtc-rp5c01.c222
-rw-r--r--drivers/rtc/rtc-twl4030.c4
-rw-r--r--drivers/s390/block/dasd.c35
-rw-r--r--drivers/s390/block/dasd_diag.c5
-rw-r--r--drivers/s390/block/dasd_eckd.c6
-rw-r--r--drivers/s390/block/dasd_fba.c7
-rw-r--r--drivers/s390/char/tape_34xx.c2
-rw-r--r--drivers/s390/char/tape_3590.c2
-rw-r--r--drivers/s390/char/tape_block.c24
-rw-r--r--drivers/s390/cio/cio.c2
-rw-r--r--drivers/s390/cio/device_ops.c24
-rw-r--r--drivers/s390/cio/qdio_main.c44
-rw-r--r--drivers/sbus/char/jsflash.c26
-rw-r--r--drivers/scsi/eata.c24
-rw-r--r--drivers/scsi/libsas/sas_expander.c14
-rw-r--r--drivers/scsi/libsas/sas_host_smp.c52
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c22
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c23
-rw-r--r--drivers/scsi/osd/osd_initiator.c4
-rw-r--r--drivers/scsi/osd/osd_uld.c20
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c81
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h34
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h29
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c90
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c59
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c236
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c90
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c118
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c233
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c38
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
-rw-r--r--drivers/scsi/scsi_lib.c85
-rw-r--r--drivers/scsi/scsi_tgt_lib.c2
-rw-r--r--drivers/scsi/scsi_transport_fc.c616
-rw-r--r--drivers/scsi/scsi_transport_sas.c4
-rw-r--r--drivers/scsi/sd.c24
-rw-r--r--drivers/scsi/sd_dif.c2
-rw-r--r--drivers/scsi/sg.c3
-rw-r--r--drivers/scsi/sr.c15
-rw-r--r--drivers/scsi/st.c2
-rw-r--r--drivers/scsi/u14-34f.c22
-rw-r--r--drivers/serial/8250_pci.c3
-rw-r--r--drivers/serial/jsm/jsm.h2
-rw-r--r--drivers/serial/jsm/jsm_driver.c1
-rw-r--r--drivers/serial/s3c6400.c1
-rw-r--r--drivers/serial/samsung.c61
-rw-r--r--drivers/serial/samsung.h4
-rw-r--r--drivers/serial/serial_cs.c22
-rw-r--r--drivers/serial/sh-sci.c385
-rw-r--r--drivers/serial/sh-sci.h42
-rw-r--r--drivers/spi/pxa2xx_spi.c3
-rw-r--r--drivers/staging/comedi/TODO1
-rw-r--r--drivers/staging/rt2870/rt2870.h1
-rw-r--r--drivers/staging/rtl8187se/r8180.h2
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c46
-rw-r--r--drivers/staging/winbond/wbusb.c9
-rw-r--r--drivers/usb/Makefile2
-rw-r--r--drivers/usb/atm/cxacru.c10
-rw-r--r--drivers/usb/class/cdc-acm.c445
-rw-r--r--drivers/usb/class/cdc-acm.h5
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c5
-rw-r--r--drivers/usb/gadget/usbstring.c6
-rw-r--r--drivers/usb/host/isp1760-hcd.c24
-rw-r--r--drivers/usb/serial/belkin_sa.c6
-rw-r--r--drivers/usb/serial/ch341.c46
-rw-r--r--drivers/usb/serial/console.c6
-rw-r--r--drivers/usb/serial/cp210x.c6
-rw-r--r--drivers/usb/serial/cyberjack.c6
-rw-r--r--drivers/usb/serial/cypress_m8.c81
-rw-r--r--drivers/usb/serial/digi_acceleport.c75
-rw-r--r--drivers/usb/serial/empeg.c6
-rw-r--r--drivers/usb/serial/ftdi_sio.c70
-rw-r--r--drivers/usb/serial/ftdi_sio.h6
-rw-r--r--drivers/usb/serial/garmin_gps.c3
-rw-r--r--drivers/usb/serial/generic.c3
-rw-r--r--drivers/usb/serial/io_edgeport.c10
-rw-r--r--drivers/usb/serial/io_ti.c3
-rw-r--r--drivers/usb/serial/ipaq.c6
-rw-r--r--drivers/usb/serial/ipw.c18
-rw-r--r--drivers/usb/serial/ir-usb.c6
-rw-r--r--drivers/usb/serial/iuu_phoenix.c25
-rw-r--r--drivers/usb/serial/keyspan.c13
-rw-r--r--drivers/usb/serial/keyspan.h8
-rw-r--r--drivers/usb/serial/keyspan_pda.c48
-rw-r--r--drivers/usb/serial/kl5kusb105.c6
-rw-r--r--drivers/usb/serial/kobil_sct.c9
-rw-r--r--drivers/usb/serial/mct_u232.c37
-rw-r--r--drivers/usb/serial/mos7720.c3
-rw-r--r--drivers/usb/serial/mos7840.c48
-rw-r--r--drivers/usb/serial/navman.c3
-rw-r--r--drivers/usb/serial/omninet.c6
-rw-r--r--drivers/usb/serial/opticon.c3
-rw-r--r--drivers/usb/serial/option.c68
-rw-r--r--drivers/usb/serial/oti6858.c57
-rw-r--r--drivers/usb/serial/pl2303.c79
-rw-r--r--drivers/usb/serial/sierra.c97
-rw-r--r--drivers/usb/serial/spcp8x5.c85
-rw-r--r--drivers/usb/serial/symbolserial.c3
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c6
-rw-r--r--drivers/usb/serial/usb-serial.c144
-rw-r--r--drivers/usb/serial/visor.c6
-rw-r--r--drivers/usb/serial/whiteheat.c33
-rw-r--r--drivers/usb/storage/unusual_devs.h5
-rw-r--r--drivers/video/Kconfig23
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/cfbfillrect.c36
-rw-r--r--drivers/video/cyber2000fb.c9
-rw-r--r--drivers/video/fb_draw.h21
-rw-r--r--drivers/video/mx3fb.c14
-rw-r--r--drivers/video/sysfillrect.c30
-rw-r--r--drivers/video/tdfxfb.c1
-rw-r--r--drivers/video/uvesafb.c10
-rw-r--r--drivers/video/via/viafbdev.c6
-rw-r--r--drivers/watchdog/alim7101_wdt.c15
-rw-r--r--drivers/watchdog/ar7_wdt.c3
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c3
-rw-r--r--drivers/watchdog/at91sam9_wdt.c3
-rw-r--r--drivers/watchdog/bfin_wdt.c14
-rw-r--r--drivers/watchdog/cpwd.c6
-rw-r--r--drivers/watchdog/davinci_wdt.c6
-rw-r--r--drivers/watchdog/iTCO_vendor_support.c6
-rw-r--r--drivers/watchdog/iTCO_wdt.c24
-rw-r--r--drivers/watchdog/indydog.c4
-rw-r--r--drivers/watchdog/it8712f_wdt.c3
-rw-r--r--drivers/watchdog/ks8695_wdt.c4
-rw-r--r--drivers/watchdog/machzwd.c9
-rw-r--r--drivers/watchdog/mpcore_wdt.c7
-rw-r--r--drivers/watchdog/mtx-1_wdt.c6
-rw-r--r--drivers/watchdog/pnx4008_wdt.c6
-rw-r--r--drivers/watchdog/rdc321x_wdt.c4
-rw-r--r--drivers/watchdog/rm9k_wdt.c6
-rw-r--r--drivers/watchdog/s3c2410_wdt.c32
-rw-r--r--drivers/watchdog/sb_wdog.c9
-rw-r--r--drivers/watchdog/sbc60xxwdt.c5
-rw-r--r--drivers/watchdog/sbc8360.c4
-rw-r--r--drivers/watchdog/sbc_epx_c3.c12
-rw-r--r--drivers/watchdog/scx200_wdt.c7
-rw-r--r--drivers/watchdog/shwdt.c4
-rw-r--r--drivers/watchdog/softdog.c7
-rw-r--r--drivers/watchdog/w83697hf_wdt.c3
-rw-r--r--drivers/watchdog/wdrtas.c7
-rw-r--r--drivers/xen/Kconfig20
-rw-r--r--drivers/xen/Makefile4
-rw-r--r--drivers/xen/events.c20
-rw-r--r--drivers/xen/evtchn.c507
-rw-r--r--drivers/xen/manage.c9
-rw-r--r--drivers/xen/sys-hypervisor.c445
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c61
-rw-r--r--drivers/xen/xenbus/xenbus_xs.c2
-rw-r--r--drivers/xen/xenfs/super.c19
-rw-r--r--firmware/Makefile3
-rw-r--r--firmware/WHENCE40
-rw-r--r--firmware/bnx2x-e1-4.8.53.0.fw.ihex10364
-rw-r--r--firmware/bnx2x-e1h-4.8.53.0.fw.ihex12028
-rw-r--r--firmware/cis/3CCFEM556.cis.ihex13
-rw-r--r--firmware/cis/3CXEM556.cis.ihex13
-rw-r--r--fs/9p/vfs_super.c12
-rw-r--r--fs/Kconfig10
-rw-r--r--fs/adfs/super.c4
-rw-r--r--fs/affs/super.c10
-rw-r--r--fs/afs/mntpt.c2
-rw-r--r--fs/afs/super.c11
-rw-r--r--fs/autofs/dirhash.c5
-rw-r--r--fs/autofs4/autofs_i.h6
-rw-r--r--fs/autofs4/dev-ioctl.c195
-rw-r--r--fs/autofs4/expire.c15
-rw-r--r--fs/autofs4/root.c7
-rw-r--r--fs/befs/linuxvfs.c5
-rw-r--r--fs/bfs/inode.c8
-rw-r--r--fs/block_dev.c26
-rw-r--r--fs/btrfs/inode.c7
-rw-r--r--fs/btrfs/super.c27
-rw-r--r--fs/buffer.c4
-rw-r--r--fs/cachefiles/interface.c4
-rw-r--r--fs/cifs/CHANGES13
-rw-r--r--fs/cifs/README10
-rw-r--r--fs/cifs/cifs_dfs_ref.c34
-rw-r--r--fs/cifs/cifs_unicode.c198
-rw-r--r--fs/cifs/cifs_unicode.h23
-rw-r--r--fs/cifs/cifsfs.c12
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h16
-rw-r--r--fs/cifs/cifsproto.h5
-rw-r--r--fs/cifs/cifssmb.c217
-rw-r--r--fs/cifs/connect.c1190
-rw-r--r--fs/cifs/dir.c15
-rw-r--r--fs/cifs/file.c14
-rw-r--r--fs/cifs/inode.c21
-rw-r--r--fs/cifs/link.c114
-rw-r--r--fs/cifs/misc.c71
-rw-r--r--fs/cifs/netmisc.c2
-rw-r--r--fs/cifs/nterr.h9
-rw-r--r--fs/cifs/ntlmssp.h68
-rw-r--r--fs/cifs/readdir.c72
-rw-r--r--fs/cifs/sess.c340
-rw-r--r--fs/cifs/smberr.h1
-rw-r--r--fs/coda/file.c9
-rw-r--r--fs/compat.c8
-rw-r--r--fs/configfs/configfs_internal.h3
-rw-r--r--fs/configfs/dir.c193
-rw-r--r--fs/configfs/inode.c38
-rw-r--r--fs/dcache.c9
-rw-r--r--fs/devpts/inode.c5
-rw-r--r--fs/dlm/lockspace.c17
-rw-r--r--fs/ecryptfs/main.c5
-rw-r--r--fs/ecryptfs/super.c5
-rw-r--r--fs/eventpoll.c2
-rw-r--r--fs/exec.c89
-rw-r--r--fs/exofs/osd.c4
-rw-r--r--fs/exofs/super.c9
-rw-r--r--fs/ext2/super.c7
-rw-r--r--fs/ext3/acl.c13
-rw-r--r--fs/ext3/balloc.c3
-rw-r--r--fs/ext3/ialloc.c3
-rw-r--r--fs/ext3/inode.c1
-rw-r--r--fs/ext3/resize.c2
-rw-r--r--fs/ext3/super.c30
-rw-r--r--fs/ext3/xattr.c1
-rw-r--r--fs/ext4/acl.c13
-rw-r--r--fs/ext4/balloc.c28
-rw-r--r--fs/ext4/dir.c3
-rw-r--r--fs/ext4/ext4.h336
-rw-r--r--fs/ext4/ext4_i.h140
-rw-r--r--fs/ext4/ext4_sb.h161
-rw-r--r--fs/ext4/extents.c46
-rw-r--r--fs/ext4/group.h29
-rw-r--r--fs/ext4/ialloc.c70
-rw-r--r--fs/ext4/inode.c261
-rw-r--r--fs/ext4/mballoc.c145
-rw-r--r--fs/ext4/mballoc.h1
-rw-r--r--fs/ext4/namei.c22
-rw-r--r--fs/ext4/namei.h8
-rw-r--r--fs/ext4/resize.c36
-rw-r--r--fs/ext4/super.c241
-rw-r--r--fs/fat/inode.c9
-rw-r--r--fs/fcntl.c6
-rw-r--r--fs/file_table.c40
-rw-r--r--fs/freevxfs/vxfs_super.c4
-rw-r--r--fs/fs-writeback.c49
-rw-r--r--fs/fuse/Makefile1
-rw-r--r--fs/fuse/cuse.c610
-rw-r--r--fs/fuse/dev.c15
-rw-r--r--fs/fuse/dir.c33
-rw-r--r--fs/fuse/file.c346
-rw-r--r--fs/fuse/fuse_i.h47
-rw-r--r--fs/fuse/inode.c124
-rw-r--r--fs/gfs2/glock.c1
-rw-r--r--fs/gfs2/log.c8
-rw-r--r--fs/gfs2/lops.c14
-rw-r--r--fs/gfs2/meta_io.c104
-rw-r--r--fs/gfs2/ops_address.c20
-rw-r--r--fs/gfs2/ops_file.c29
-rw-r--r--fs/gfs2/ops_fstype.c8
-rw-r--r--fs/gfs2/ops_super.c15
-rw-r--r--fs/hfs/super.c14
-rw-r--r--fs/hfsplus/super.c13
-rw-r--r--fs/hpfs/super.c11
-rw-r--r--fs/hugetlbfs/inode.c11
-rw-r--r--fs/inode.c83
-rw-r--r--fs/internal.h17
-rw-r--r--fs/ioctl.c89
-rw-r--r--fs/isofs/inode.c5
-rw-r--r--fs/jffs2/fs.c15
-rw-r--r--fs/jffs2/os-linux.h1
-rw-r--r--fs/jffs2/super.c24
-rw-r--r--fs/jfs/super.c9
-rw-r--r--fs/libfs.c3
-rw-r--r--fs/lockd/svc.c15
-rw-r--r--fs/lockd/svclock.c2
-rw-r--r--fs/locks.c3
-rw-r--r--fs/minix/inode.c4
-rw-r--r--fs/mpage.c6
-rw-r--r--fs/namei.c142
-rw-r--r--fs/namespace.c350
-rw-r--r--fs/ncpfs/inode.c4
-rw-r--r--fs/nfs/Kconfig9
-rw-r--r--fs/nfs/client.c124
-rw-r--r--fs/nfs/direct.c9
-rw-r--r--fs/nfs/internal.h62
-rw-r--r--fs/nfs/namespace.c2
-rw-r--r--fs/nfs/nfs4_fs.h37
-rw-r--r--fs/nfs/nfs4proc.c1229
-rw-r--r--fs/nfs/nfs4renewd.c6
-rw-r--r--fs/nfs/nfs4state.c130
-rw-r--r--fs/nfs/nfs4xdr.c1078
-rw-r--r--fs/nfs/read.c33
-rw-r--r--fs/nfs/super.c34
-rw-r--r--fs/nfs/unlink.c20
-rw-r--r--fs/nfs/write.c31
-rw-r--r--fs/nfsd/export.c91
-rw-r--r--fs/nfsd/nfs3xdr.c1
-rw-r--r--fs/nfsd/nfs4callback.c222
-rw-r--r--fs/nfsd/nfs4recover.c4
-rw-r--r--fs/nfsd/nfs4state.c120
-rw-r--r--fs/nfsd/nfs4xdr.c264
-rw-r--r--fs/nfsd/nfsctl.c284
-rw-r--r--fs/nfsd/vfs.c54
-rw-r--r--fs/nilfs2/ioctl.c281
-rw-r--r--fs/nilfs2/mdt.c15
-rw-r--r--fs/nilfs2/nilfs.h3
-rw-r--r--fs/nilfs2/page.c3
-rw-r--r--fs/nilfs2/recovery.c6
-rw-r--r--fs/nilfs2/segment.c5
-rw-r--r--fs/nilfs2/segment.h3
-rw-r--r--fs/nilfs2/super.c8
-rw-r--r--fs/notify/inotify/inotify_user.c2
-rw-r--r--fs/ntfs/super.c6
-rw-r--r--fs/ocfs2/cluster/masklog.h35
-rw-r--r--fs/ocfs2/super.c18
-rw-r--r--fs/ocfs2/symlink.c77
-rw-r--r--fs/ocfs2/xattr.c5
-rw-r--r--fs/open.c6
-rw-r--r--fs/pipe.c14
-rw-r--r--fs/proc/base.c6
-rw-r--r--fs/proc/internal.h25
-rw-r--r--fs/proc/proc_devtree.c1
-rw-r--r--fs/proc/root.c3
-rw-r--r--fs/qnx4/inode.c9
-rw-r--r--fs/quota/quota.c25
-rw-r--r--fs/read_write.c7
-rw-r--r--fs/reiserfs/dir.c22
-rw-r--r--fs/reiserfs/namei.c17
-rw-r--r--fs/reiserfs/super.c40
-rw-r--r--fs/reiserfs/xattr.c262
-rw-r--r--fs/reiserfs/xattr_security.c12
-rw-r--r--fs/romfs/super.c3
-rw-r--r--fs/smbfs/inode.c4
-rw-r--r--fs/splice.c422
-rw-r--r--fs/squashfs/Makefile1
-rw-r--r--fs/squashfs/cache.c1
-rw-r--r--fs/squashfs/super.c14
-rw-r--r--fs/super.c230
-rw-r--r--fs/sync.c119
-rw-r--r--fs/sysfs/file.c2
-rw-r--r--fs/sysv/inode.c11
-rw-r--r--fs/ubifs/budget.c3
-rw-r--r--fs/ubifs/super.c16
-rw-r--r--fs/udf/super.c5
-rw-r--r--fs/ufs/dir.c2
-rw-r--r--fs/ufs/file.c2
-rw-r--r--fs/ufs/super.c22
-rw-r--r--fs/ufs/ufs.h2
-rw-r--r--fs/xattr.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c4
-rw-r--r--fs/xfs/xfs_dfrag.c8
-rw-r--r--include/Kbuild2
-rw-r--r--include/acpi/acpixf.h7
-rw-r--r--include/acpi/actypes.h20
-rw-r--r--include/acpi/platform/acgcc.h4
-rw-r--r--include/acpi/platform/aclinux.h63
-rw-r--r--include/asm-generic/bug.h7
-rw-r--r--include/asm-generic/pgtable.h21
-rw-r--r--include/asm-generic/vmlinux.lds.h2
-rw-r--r--include/linux/Kbuild2
-rw-r--r--include/linux/acpi.h2
-rw-r--r--include/linux/atmel-mci.h2
-rw-r--r--include/linux/bio.h8
-rw-r--r--include/linux/blkdev.h216
-rw-r--r--include/linux/blktrace_api.h32
-rw-r--r--include/linux/clocksource.h10
-rw-r--r--include/linux/compat.h2
-rw-r--r--include/linux/compiler.h5
-rw-r--r--include/linux/cpu.h5
-rw-r--r--include/linux/cyclades.h37
-rw-r--r--include/linux/dcache.h7
-rw-r--r--include/linux/device-mapper.h11
-rw-r--r--include/linux/device.h9
-rw-r--r--include/linux/dlm.h4
-rw-r--r--include/linux/dma-debug.h7
-rw-r--r--include/linux/dma_remapping.h8
-rw-r--r--include/linux/dmaengine.h6
-rw-r--r--include/linux/dmar.h3
-rw-r--r--include/linux/elevator.h4
-rw-r--r--include/linux/etherdevice.h27
-rw-r--r--include/linux/ethtool.h15
-rw-r--r--include/linux/fs.h23
-rw-r--r--include/linux/fs_enet_pd.h6
-rw-r--r--include/linux/ftrace.h17
-rw-r--r--include/linux/ftrace_event.h158
-rw-r--r--include/linux/fuse.h31
-rw-r--r--include/linux/futex.h6
-rw-r--r--include/linux/gameport.h3
-rw-r--r--include/linux/i2c.h60
-rw-r--r--include/linux/ide.h27
-rw-r--r--include/linux/ieee80211.h51
-rw-r--r--include/linux/if_tun.h1
-rw-r--r--include/linux/if_vlan.h6
-rw-r--r--include/linux/init_task.h5
-rw-r--r--include/linux/intel-iommu.h19
-rw-r--r--include/linux/interrupt.h2
-rw-r--r--include/linux/ioport.h2
-rw-r--r--include/linux/irq.h58
-rw-r--r--include/linux/kgdb.h50
-rw-r--r--include/linux/kmemtrace.h25
-rw-r--r--include/linux/kvm.h46
-rw-r--r--include/linux/kvm_host.h23
-rw-r--r--include/linux/kvm_types.h27
-rw-r--r--include/linux/loop.h3
-rw-r--r--include/linux/lsm_audit.h111
-rw-r--r--include/linux/magic.h5
-rw-r--r--include/linux/mdio.h312
-rw-r--r--include/linux/mg_disk.h206
-rw-r--r--include/linux/mii.h34
-rw-r--r--include/linux/mm.h7
-rw-r--r--include/linux/mmc/sdio_ids.h10
-rw-r--r--include/linux/mmiotrace.h2
-rw-r--r--include/linux/module.h8
-rw-r--r--include/linux/moduleparam.h40
-rw-r--r--include/linux/mount.h25
-rw-r--r--include/linux/mutex.h1
-rw-r--r--include/linux/namei.h6
-rw-r--r--include/linux/netdevice.h105
-rw-r--r--include/linux/netfilter/xt_LED.h2
-rw-r--r--include/linux/netfilter/xt_cluster.h2
-rw-r--r--include/linux/nfs4.h18
-rw-r--r--include/linux/nfs_fs_sb.h67
-rw-r--r--include/linux/nfs_xdr.h174
-rw-r--r--include/linux/nfsd/export.h6
-rw-r--r--include/linux/nfsd/nfsfh.h7
-rw-r--r--include/linux/nfsd/state.h24
-rw-r--r--include/linux/nfsd/xdr4.h17
-rw-r--r--include/linux/nl80211.h178
-rw-r--r--include/linux/nls.h19
-rw-r--r--include/linux/of.h3
-rw-r--r--include/linux/of_mdio.h22
-rw-r--r--include/linux/page-flags.h2
-rw-r--r--include/linux/pci.h12
-rw-r--r--include/linux/pci_ids.h11
-rw-r--r--include/linux/pci_regs.h4
-rw-r--r--include/linux/phy.h6
-rw-r--r--include/linux/pipe_fs_i.h1
-rw-r--r--include/linux/platform_device.h1
-rw-r--r--include/linux/poison.h16
-rw-r--r--include/linux/proc_fs.h24
-rw-r--r--include/linux/ptrace.h10
-rw-r--r--include/linux/quotaops.h20
-rw-r--r--include/linux/rcu_types.h18
-rw-r--r--include/linux/rculist.h30
-rw-r--r--include/linux/rcupdate.h11
-rw-r--r--include/linux/rcutree.h9
-rw-r--r--include/linux/regulator/max1586.h52
-rw-r--r--include/linux/regulator/userspace-consumer.h25
-rw-r--r--include/linux/reiserfs_fs_sb.h5
-rw-r--r--include/linux/reiserfs_xattr.h7
-rw-r--r--include/linux/rfkill.h8
-rw-r--r--include/linux/ring_buffer.h52
-rw-r--r--include/linux/romfs_fs.h5
-rw-r--r--include/linux/rotary_encoder.h2
-rw-r--r--include/linux/sched.h30
-rw-r--r--include/linux/serial.h116
-rw-r--r--include/linux/serial_sci.h3
-rw-r--r--include/linux/serio.h9
-rw-r--r--include/linux/sh_cmt.h13
-rw-r--r--include/linux/sh_timer.h13
-rw-r--r--include/linux/signal.h2
-rw-r--r--include/linux/skbuff.h8
-rw-r--r--include/linux/slab.h10
-rw-r--r--include/linux/slab_def.h2
-rw-r--r--include/linux/slqb_def.h298
-rw-r--r--include/linux/slub_def.h2
-rw-r--r--include/linux/smsc911x.h10
-rw-r--r--include/linux/snmp.h10
-rw-r--r--include/linux/socket.h7
-rw-r--r--include/linux/spi/wl12xx.h31
-rw-r--r--include/linux/splice.h3
-rw-r--r--include/linux/sunrpc/clnt.h1
-rw-r--r--include/linux/sunrpc/sched.h1
-rw-r--r--include/linux/sunrpc/svc_xprt.h7
-rw-r--r--include/linux/sunrpc/svcsock.h7
-rw-r--r--include/linux/swiotlb.h3
-rw-r--r--include/linux/syscalls.h1
-rw-r--r--include/linux/tcp.h4
-rw-r--r--include/linux/thread_info.h3
-rw-r--r--include/linux/time.h15
-rw-r--r--include/linux/timex.h42
-rw-r--r--include/linux/trace_seq.h90
-rw-r--r--include/linux/tracepoint.h8
-rw-r--r--include/linux/tty.h6
-rw-r--r--include/linux/usb/serial.h10
-rw-r--r--include/linux/usb/usbnet.h1
-rw-r--r--include/linux/wait.h2
-rw-r--r--include/linux/writeback.h1
-rw-r--r--include/media/ir-kbd-i2c.h10
-rw-r--r--include/media/soc_camera.h10
-rw-r--r--include/media/v4l2-device.h23
-rw-r--r--include/media/v4l2-subdev.h5
-rw-r--r--include/net/cfg80211.h950
-rw-r--r--include/net/ip.h3
-rw-r--r--include/net/ip_fib.h3
-rw-r--r--include/net/ipv6.h15
-rw-r--r--include/net/iucv/af_iucv.h9
-rw-r--r--include/net/mac80211.h218
-rw-r--r--include/net/regulatory.h101
-rw-r--r--include/net/snmp.h19
-rw-r--r--include/net/tcp.h59
-rw-r--r--include/net/wireless.h472
-rw-r--r--include/scsi/Kbuild4
-rw-r--r--include/scsi/scsi_bsg_fc.h322
-rw-r--r--include/scsi/scsi_cmnd.h2
-rw-r--r--include/scsi/scsi_host.h9
-rw-r--r--include/scsi/scsi_transport_fc.h52
-rw-r--r--include/sound/core.h10
-rw-r--r--include/sound/driver.h1
-rw-r--r--include/sound/pcm.h1
-rw-r--r--include/sound/soc-dai.h29
-rw-r--r--include/sound/soc-dapm.h19
-rw-r--r--include/sound/soc.h14
-rw-r--r--include/sound/version.h2
-rw-r--r--include/trace/block.h4
-rw-r--r--include/trace/define_trace.h75
-rw-r--r--include/trace/events/irq.h134
-rw-r--r--include/trace/events/kmem.h194
-rw-r--r--include/trace/events/lockdep.h96
-rw-r--r--include/trace/events/mm.h48
-rw-r--r--include/trace/events/sched.h (renamed from include/trace/sched_event_types.h)20
-rw-r--r--include/trace/events/skb.h40
-rw-r--r--include/trace/ftrace.h509
-rw-r--r--include/trace/irq.h9
-rw-r--r--include/trace/irq_event_types.h55
-rw-r--r--include/trace/kmemtrace.h63
-rw-r--r--include/trace/lockdep.h9
-rw-r--r--include/trace/lockdep_event_types.h44
-rw-r--r--include/trace/sched.h9
-rw-r--r--include/trace/skb.h11
-rw-r--r--include/trace/trace_event_types.h5
-rw-r--r--include/trace/trace_events.h5
-rw-r--r--include/xen/Kbuild1
-rw-r--r--include/xen/events.h3
-rw-r--r--include/xen/evtchn.h88
-rw-r--r--include/xen/interface/version.h3
-rw-r--r--include/xen/xenbus.h3
-rw-r--r--init/Kconfig30
-rw-r--r--init/initramfs.c13
-rw-r--r--init/main.c3
-rw-r--r--ipc/sem.c4
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/audit_tree.c6
-rw-r--r--kernel/auditfilter.c4
-rw-r--r--kernel/cgroup.c3
-rw-r--r--kernel/compat.c11
-rw-r--r--kernel/cpu.c11
-rw-r--r--kernel/cred.c4
-rw-r--r--kernel/exit.c7
-rw-r--r--kernel/fork.c9
-rw-r--r--kernel/futex.c1200
-rw-r--r--kernel/irq/Makefile2
-rw-r--r--kernel/irq/chip.c12
-rw-r--r--kernel/irq/handle.c49
-rw-r--r--kernel/irq/internals.h5
-rw-r--r--kernel/irq/manage.c19
-rw-r--r--kernel/irq/migration.c14
-rw-r--r--kernel/irq/numa_migrate.c38
-rw-r--r--kernel/kgdb.c6
-rw-r--r--kernel/kprobes.c31
-rw-r--r--kernel/kthread.c5
-rw-r--r--kernel/lockdep.c16
-rw-r--r--kernel/module.c33
-rw-r--r--kernel/mutex.c29
-rw-r--r--kernel/panic.c13
-rw-r--r--kernel/params.c46
-rw-r--r--kernel/ptrace.c19
-rw-r--r--kernel/rcupreempt.c8
-rw-r--r--kernel/rcutree.c25
-rw-r--r--kernel/rcutree_trace.c64
-rw-r--r--kernel/rtmutex.c248
-rw-r--r--kernel/rtmutex_common.h8
-rw-r--r--kernel/sched.c255
-rw-r--r--kernel/sched_clock.c3
-rw-r--r--kernel/sched_fair.c13
-rw-r--r--kernel/signal.c71
-rw-r--r--kernel/softirq.c9
-rw-r--r--kernel/sysctl.c12
-rw-r--r--kernel/time/clockevents.c2
-rw-r--r--kernel/time/clocksource.c3
-rw-r--r--kernel/time/tick-broadcast.c2
-rw-r--r--kernel/time/timekeeping.c7
-rw-r--r--kernel/timer.c3
-rw-r--r--kernel/trace/Kconfig90
-rw-r--r--kernel/trace/Makefile16
-rw-r--r--kernel/trace/blktrace.c209
-rw-r--r--kernel/trace/events.c14
-rw-r--r--kernel/trace/ftrace.c726
-rw-r--r--kernel/trace/kmemtrace.c10
-rw-r--r--kernel/trace/ring_buffer.c657
-rw-r--r--kernel/trace/ring_buffer_benchmark.c408
-rw-r--r--kernel/trace/trace.c370
-rw-r--r--kernel/trace/trace.h243
-rw-r--r--kernel/trace/trace_boot.c5
-rw-r--r--kernel/trace/trace_branch.c8
-rw-r--r--kernel/trace/trace_event_profile.c24
-rw-r--r--kernel/trace/trace_event_types.h12
-rw-r--r--kernel/trace/trace_events.c833
-rw-r--r--kernel/trace/trace_events_filter.c1200
-rw-r--r--kernel/trace/trace_events_stage_1.h39
-rw-r--r--kernel/trace/trace_events_stage_2.h176
-rw-r--r--kernel/trace/trace_events_stage_3.h281
-rw-r--r--kernel/trace/trace_export.c110
-rw-r--r--kernel/trace/trace_functions_graph.c25
-rw-r--r--kernel/trace/trace_hw_branches.c203
-rw-r--r--kernel/trace/trace_mm.c172
-rw-r--r--kernel/trace/trace_mmiotrace.c6
-rw-r--r--kernel/trace/trace_output.c82
-rw-r--r--kernel/trace/trace_output.h28
-rw-r--r--kernel/trace/trace_power.c8
-rw-r--r--kernel/trace/trace_printk.c6
-rw-r--r--kernel/trace/trace_sched_switch.c12
-rw-r--r--kernel/trace/trace_sched_wakeup.c8
-rw-r--r--kernel/trace/trace_selftest.c58
-rw-r--r--kernel/trace/trace_stack.c13
-rw-r--r--kernel/trace/trace_stat.c2
-rw-r--r--kernel/trace/trace_stat.h2
-rw-r--r--kernel/trace/trace_sysprof.c6
-rw-r--r--kernel/trace/trace_workqueue.c2
-rw-r--r--kernel/wait.c2
-rw-r--r--lib/Kconfig.debug21
-rw-r--r--lib/dma-debug.c72
-rw-r--r--lib/swiotlb.c119
-rw-r--r--lib/vsprintf.c56
-rw-r--r--mm/Kconfig28
-rw-r--r--mm/Makefile1
-rw-r--r--mm/madvise.c8
-rw-r--r--mm/mlock.c51
-rw-r--r--mm/nommu.c4
-rw-r--r--mm/oom_kill.c44
-rw-r--r--mm/page_alloc.c20
-rw-r--r--mm/percpu.c141
-rw-r--r--mm/slab.c2
-rw-r--r--mm/slob.c13
-rw-r--r--mm/slqb.c3746
-rw-r--r--mm/slub.c8
-rw-r--r--mm/util.c11
-rw-r--r--mm/vmalloc.c1
-rw-r--r--net/8021q/vlan_core.c4
-rw-r--r--net/8021q/vlan_dev.c23
-rw-r--r--net/Kconfig6
-rw-r--r--net/bluetooth/hci_sysfs.c7
-rw-r--r--net/core/datagram.c116
-rw-r--r--net/core/dev.c363
-rw-r--r--net/core/drop_monitor.c15
-rw-r--r--net/core/iovec.c33
-rw-r--r--net/core/net-traces.c4
-rw-r--r--net/core/net_namespace.c47
-rw-r--r--net/core/skbuff.c4
-rw-r--r--net/decnet/dn_nsp_in.c17
-rw-r--r--net/ipv4/Kconfig2
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/inet_diag.c2
-rw-r--r--net/ipv4/inet_timewait_sock.c23
-rw-r--r--net/ipv4/ip_input.c13
-rw-r--r--net/ipv4/ip_output.c12
-rw-r--r--net/ipv4/proc.c10
-rw-r--r--net/ipv4/syncookies.c5
-rw-r--r--net/ipv4/tcp_input.c2
-rw-r--r--net/ipv4/tcp_ipv4.c4
-rw-r--r--net/ipv4/tcp_output.c2
-rw-r--r--net/ipv6/ip6_input.c7
-rw-r--r--net/ipv6/ip6_output.c9
-rw-r--r--net/ipv6/ip6_tunnel.c4
-rw-r--r--net/ipv6/mcast.c19
-rw-r--r--net/ipv6/ndisc.c4
-rw-r--r--net/ipv6/netfilter/ip6t_ipv6header.c6
-rw-r--r--net/ipv6/proc.c10
-rw-r--r--net/ipv6/raw.c2
-rw-r--r--net/ipv6/syncookies.c4
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/iucv/af_iucv.c408
-rw-r--r--net/iucv/iucv.c43
-rw-r--r--net/llc/af_llc.c2
-rw-r--r--net/mac80211/Kconfig16
-rw-r--r--net/mac80211/agg-rx.c19
-rw-r--r--net/mac80211/agg-tx.c13
-rw-r--r--net/mac80211/cfg.c144
-rw-r--r--net/mac80211/debugfs.c66
-rw-r--r--net/mac80211/driver-ops.h184
-rw-r--r--net/mac80211/event.c17
-rw-r--r--net/mac80211/ht.c84
-rw-r--r--net/mac80211/ibss.c484
-rw-r--r--net/mac80211/ieee80211_i.h108
-rw-r--r--net/mac80211/iface.c113
-rw-r--r--net/mac80211/key.c29
-rw-r--r--net/mac80211/key.h3
-rw-r--r--net/mac80211/main.c299
-rw-r--r--net/mac80211/mesh.c6
-rw-r--r--net/mac80211/mlme.c544
-rw-r--r--net/mac80211/pm.c130
-rw-r--r--net/mac80211/rc80211_minstrel.c12
-rw-r--r--net/mac80211/rc80211_pid_algo.c81
-rw-r--r--net/mac80211/rx.c198
-rw-r--r--net/mac80211/scan.c428
-rw-r--r--net/mac80211/spectmgmt.c2
-rw-r--r--net/mac80211/sta_info.c97
-rw-r--r--net/mac80211/sta_info.h5
-rw-r--r--net/mac80211/tkip.c6
-rw-r--r--net/mac80211/tx.c51
-rw-r--r--net/mac80211/util.c289
-rw-r--r--net/mac80211/wext.c552
-rw-r--r--net/mac80211/wme.c2
-rw-r--r--net/mac80211/wpa.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c9
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c4
-rw-r--r--net/netfilter/nf_conntrack_netlink.c48
-rw-r--r--net/netfilter/xt_cluster.c8
-rw-r--r--net/rds/af_rds.c1
-rw-r--r--net/rds/connection.c4
-rw-r--r--net/rds/ib.c4
-rw-r--r--net/rds/ib.h2
-rw-r--r--net/rds/ib_recv.c2
-rw-r--r--net/rds/ib_ring.c2
-rw-r--r--net/rds/ib_send.c10
-rw-r--r--net/rds/info.c5
-rw-r--r--net/rds/iw.c4
-rw-r--r--net/rds/iw.h2
-rw-r--r--net/rds/iw_recv.c2
-rw-r--r--net/rds/iw_ring.c2
-rw-r--r--net/rds/iw_send.c10
-rw-r--r--net/rds/rdma.c7
-rw-r--r--net/rds/rdma_transport.c12
-rw-r--r--net/rds/rds.h2
-rw-r--r--net/rds/send.c10
-rw-r--r--net/rfkill/rfkill-input.c69
-rw-r--r--net/rfkill/rfkill.c14
-rw-r--r--net/sched/sch_fifo.c2
-rw-r--r--net/sctp/output.c17
-rw-r--r--net/sunrpc/clnt.c13
-rw-r--r--net/sunrpc/sched.c2
-rw-r--r--net/sunrpc/svc_xprt.c57
-rw-r--r--net/sunrpc/svcsock.c87
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c2
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c3
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c3
-rw-r--r--net/tipc/eth_media.c2
-rw-r--r--net/wimax/op-msg.c11
-rw-r--r--net/wimax/op-rfkill.c8
-rw-r--r--net/wimax/stack.c17
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/core.c33
-rw-r--r--net/wireless/core.h21
-rw-r--r--net/wireless/ibss.c369
-rw-r--r--net/wireless/mlme.c50
-rw-r--r--net/wireless/nl80211.c767
-rw-r--r--net/wireless/nl80211.h32
-rw-r--r--net/wireless/reg.c60
-rw-r--r--net/wireless/scan.c64
-rw-r--r--net/wireless/util.c51
-rw-r--r--net/wireless/wext-compat.c510
-rw-r--r--net/wireless/wext.c20
-rw-r--r--samples/Kconfig6
-rw-r--r--samples/Makefile2
-rw-r--r--samples/trace_events/Makefile6
-rw-r--r--samples/trace_events/trace-events-sample.c52
-rw-r--r--samples/trace_events/trace-events-sample.h129
-rw-r--r--scripts/Makefile.lib28
-rw-r--r--scripts/bin_size10
-rw-r--r--scripts/kconfig/lxdialog/checklist.c3
-rw-r--r--scripts/kconfig/mconf.c10
-rwxr-xr-xscripts/kernel-doc22
-rw-r--r--scripts/package/builddeb149
-rwxr-xr-xscripts/recordmcount.pl6
-rw-r--r--security/Makefile3
-rw-r--r--security/commoncap.c32
-rw-r--r--security/inode.c2
-rw-r--r--security/integrity/ima/ima_audit.c32
-rw-r--r--security/integrity/ima/ima_fs.c4
-rw-r--r--security/integrity/ima/ima_main.c29
-rw-r--r--security/integrity/ima/ima_policy.c8
-rw-r--r--security/lsm_audit.c386
-rw-r--r--security/selinux/avc.c2
-rw-r--r--security/selinux/hooks.c24
-rw-r--r--security/selinux/include/security.h4
-rw-r--r--security/selinux/selinuxfs.c4
-rw-r--r--security/selinux/ss/services.c30
-rw-r--r--security/smack/smack.h108
-rw-r--r--security/smack/smack_access.c143
-rw-r--r--security/smack/smack_lsm.c390
-rw-r--r--security/smack/smackfs.c74
-rw-r--r--security/tomoyo/common.c6
-rw-r--r--security/tomoyo/realpath.c16
-rw-r--r--sound/aoa/fabrics/layout.c8
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c8
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c2
-rw-r--r--sound/core/pcm_native.c8
-rw-r--r--sound/drivers/serial-u16550.c11
-rw-r--r--sound/isa/Kconfig7
-rw-r--r--sound/isa/sc6000.c134
-rw-r--r--sound/pci/Kconfig13
-rw-r--r--sound/pci/Makefile1
-rw-r--r--sound/pci/hda/Kconfig13
-rw-r--r--sound/pci/hda/Makefile4
-rw-r--r--sound/pci/hda/hda_codec.c122
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_intel.c34
-rw-r--r--sound/pci/hda/patch_ca0110.c573
-rw-r--r--sound/pci/hda/patch_realtek.c1693
-rw-r--r--sound/pci/hda/patch_sigmatel.c51
-rw-r--r--sound/pci/hda/patch_via.c111
-rw-r--r--sound/pci/lx6464es/Makefile2
-rw-r--r--sound/pci/lx6464es/lx6464es.c1152
-rw-r--r--sound/pci/lx6464es/lx6464es.h114
-rw-r--r--sound/pci/lx6464es/lx_core.c1444
-rw-r--r--sound/pci/lx6464es/lx_core.h242
-rw-r--r--sound/pci/lx6464es/lx_defs.h376
-rw-r--r--sound/pci/rme9652/hdsp.c4
-rw-r--r--sound/pci/via82xx.c2
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/atmel/Kconfig8
-rw-r--r--sound/soc/atmel/Makefile1
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c203
-rw-r--r--sound/soc/codecs/Kconfig12
-rw-r--r--sound/soc/codecs/Makefile6
-rw-r--r--sound/soc/codecs/ac97.c4
-rw-r--r--sound/soc/codecs/ad1980.c4
-rw-r--r--sound/soc/codecs/cs4270.c105
-rw-r--r--sound/soc/codecs/tlv320aic23.c2
-rw-r--r--sound/soc/codecs/twl4030.c727
-rw-r--r--sound/soc/codecs/twl4030.h29
-rw-r--r--sound/soc/codecs/wm8350.h1
-rw-r--r--sound/soc/codecs/wm8400.c4
-rw-r--r--sound/soc/codecs/wm8731.c4
-rw-r--r--sound/soc/codecs/wm8753.c4
-rw-r--r--sound/soc/codecs/wm8903.c119
-rw-r--r--sound/soc/codecs/wm8940.c955
-rw-r--r--sound/soc/codecs/wm8940.h104
-rw-r--r--sound/soc/codecs/wm8960.c969
-rw-r--r--sound/soc/codecs/wm8960.h127
-rw-r--r--sound/soc/codecs/wm8988.c1097
-rw-r--r--sound/soc/codecs/wm8988.h60
-rw-r--r--sound/soc/codecs/wm8990.c40
-rw-r--r--sound/soc/codecs/wm9705.c4
-rw-r--r--sound/soc/codecs/wm9712.c6
-rw-r--r--sound/soc/codecs/wm9713.c46
-rw-r--r--sound/soc/omap/n810.c7
-rw-r--r--sound/soc/omap/omap-mcbsp.c43
-rw-r--r--sound/soc/omap/omap-pcm.c9
-rw-r--r--sound/soc/omap/omap2evm.c2
-rw-r--r--sound/soc/omap/omap3beagle.c28
-rw-r--r--sound/soc/omap/omap3pandora.c4
-rw-r--r--sound/soc/omap/overo.c2
-rw-r--r--sound/soc/omap/sdp3430.c2
-rw-r--r--sound/soc/pxa/Kconfig20
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/em-x270.c9
-rw-r--r--sound/soc/pxa/imote2.c114
-rw-r--r--sound/soc/pxa/palm27x.c2
-rw-r--r--sound/soc/pxa/pxa-ssp.c214
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c1
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c87
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c2
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c157
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h6
-rw-r--r--sound/soc/s6000/Kconfig19
-rw-r--r--sound/soc/s6000/Makefile11
-rw-r--r--sound/soc/s6000/s6000-i2s.c629
-rw-r--r--sound/soc/s6000/s6000-i2s.h25
-rw-r--r--sound/soc/s6000/s6000-pcm.c497
-rw-r--r--sound/soc/s6000/s6000-pcm.h35
-rw-r--r--sound/soc/s6000/s6105-ipcam.c244
-rw-r--r--sound/soc/soc-core.c101
-rw-r--r--sound/soc/soc-dapm.c250
-rw-r--r--sound/usb/usbaudio.c14
-rw-r--r--virt/kvm/ioapic.c153
-rw-r--r--virt/kvm/ioapic.h27
-rw-r--r--virt/kvm/iommu.c27
-rw-r--r--virt/kvm/irq_comm.c111
-rw-r--r--virt/kvm/kvm_main.c663
2597 files changed, 180755 insertions, 68306 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-cache_disable b/Documentation/ABI/testing/sysfs-devices-cache_disable
new file mode 100644
index 000000000000..175bb4f70512
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-cache_disable
@@ -0,0 +1,18 @@
+What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
+Date: August 2008
+KernelVersion: 2.6.27
+Contact: mark.langsdorf@amd.com
+Description: These files exist in every cpu's cache index directories.
+ There are currently 2 cache_disable_# files in each
+ directory. Reading from these files on a supported
+ processor will return that cache disable index value
+ for that processor and node. Writing to one of these
+ files will cause the specificed cache index to be disabled.
+
+ Currently, only AMD Family 10h Processors support cache index
+ disable, and only for their L3 caches. See the BIOS and
+ Kernel Developer's Guide at
+ http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf
+ for formatting information and other details on the
+ cache index disable.
+Users: joachim.deguara@amd.com
diff --git a/Documentation/ABI/testing/sysfs-kernel-slab b/Documentation/ABI/testing/sysfs-kernel-slab
new file mode 100644
index 000000000000..6dcf75e594fb
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-kernel-slab
@@ -0,0 +1,479 @@
+What: /sys/kernel/slab
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The /sys/kernel/slab directory contains a snapshot of the
+ internal state of the SLUB allocator for each cache. Certain
+ files may be modified to change the behavior of the cache (and
+ any cache it aliases, if any).
+Users: kernel memory tuning tools
+
+What: /sys/kernel/slab/cache/aliases
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The aliases file is read-only and specifies how many caches
+ have merged into this cache.
+
+What: /sys/kernel/slab/cache/align
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The align file is read-only and specifies the cache's object
+ alignment in bytes.
+
+What: /sys/kernel/slab/cache/alloc_calls
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The alloc_calls file is read-only and lists the kernel code
+ locations from which allocations for this cache were performed.
+ The alloc_calls file only contains information if debugging is
+ enabled for that cache (see Documentation/vm/slub.txt).
+
+What: /sys/kernel/slab/cache/alloc_fastpath
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The alloc_fastpath file is read-only and specifies how many
+ objects have been allocated using the fast path.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/alloc_from_partial
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The alloc_from_partial file is read-only and specifies how
+ many times a cpu slab has been full and it has been refilled
+ by using a slab from the list of partially used slabs.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/alloc_refill
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The alloc_refill file is read-only and specifies how many
+ times the per-cpu freelist was empty but there were objects
+ available as the result of remote cpu frees.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/alloc_slab
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The alloc_slab file is read-only and specifies how many times
+ a new slab had to be allocated from the page allocator.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/alloc_slowpath
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The alloc_slowpath file is read-only and specifies how many
+ objects have been allocated using the slow path because of a
+ refill or allocation from a partial or new slab.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/cache_dma
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The cache_dma file is read-only and specifies whether objects
+ are from ZONE_DMA.
+ Available when CONFIG_ZONE_DMA is enabled.
+
+What: /sys/kernel/slab/cache/cpu_slabs
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The cpu_slabs file is read-only and displays how many cpu slabs
+ are active and their NUMA locality.
+
+What: /sys/kernel/slab/cache/cpuslab_flush
+Date: April 2009
+KernelVersion: 2.6.31
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file cpuslab_flush is read-only and specifies how many
+ times a cache's cpu slabs have been flushed as the result of
+ destroying or shrinking a cache, a cpu going offline, or as
+ the result of forcing an allocation from a certain node.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/ctor
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The ctor file is read-only and specifies the cache's object
+ constructor function, which is invoked for each object when a
+ new slab is allocated.
+
+What: /sys/kernel/slab/cache/deactivate_empty
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file deactivate_empty is read-only and specifies how many
+ times an empty cpu slab was deactivated.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/deactivate_full
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file deactivate_full is read-only and specifies how many
+ times a full cpu slab was deactivated.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/deactivate_remote_frees
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file deactivate_remote_frees is read-only and specifies how
+ many times a cpu slab has been deactivated and contained free
+ objects that were freed remotely.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/deactivate_to_head
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file deactivate_to_head is read-only and specifies how
+ many times a partial cpu slab was deactivated and added to the
+ head of its node's partial list.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/deactivate_to_tail
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file deactivate_to_tail is read-only and specifies how
+ many times a partial cpu slab was deactivated and added to the
+ tail of its node's partial list.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/destroy_by_rcu
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The destroy_by_rcu file is read-only and specifies whether
+ slabs (not objects) are freed by rcu.
+
+What: /sys/kernel/slab/cache/free_add_partial
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file free_add_partial is read-only and specifies how many
+ times an object has been freed in a full slab so that it had to
+ added to its node's partial list.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/free_calls
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The free_calls file is read-only and lists the locations of
+ object frees if slab debugging is enabled (see
+ Documentation/vm/slub.txt).
+
+What: /sys/kernel/slab/cache/free_fastpath
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The free_fastpath file is read-only and specifies how many
+ objects have been freed using the fast path because it was an
+ object from the cpu slab.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/free_frozen
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The free_frozen file is read-only and specifies how many
+ objects have been freed to a frozen slab (i.e. a remote cpu
+ slab).
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/free_remove_partial
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file free_remove_partial is read-only and specifies how
+ many times an object has been freed to a now-empty slab so
+ that it had to be removed from its node's partial list.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/free_slab
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The free_slab file is read-only and specifies how many times an
+ empty slab has been freed back to the page allocator.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/free_slowpath
+Date: February 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The free_slowpath file is read-only and specifies how many
+ objects have been freed using the slow path (i.e. to a full or
+ partial slab).
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/hwcache_align
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The hwcache_align file is read-only and specifies whether
+ objects are aligned on cachelines.
+
+What: /sys/kernel/slab/cache/min_partial
+Date: February 2009
+KernelVersion: 2.6.30
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ David Rientjes <rientjes@google.com>
+Description:
+ The min_partial file specifies how many empty slabs shall
+ remain on a node's partial list to avoid the overhead of
+ allocating new slabs. Such slabs may be reclaimed by utilizing
+ the shrink file.
+
+What: /sys/kernel/slab/cache/object_size
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The object_size file is read-only and specifies the cache's
+ object size.
+
+What: /sys/kernel/slab/cache/objects
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The objects file is read-only and displays how many objects are
+ active and from which nodes they are from.
+
+What: /sys/kernel/slab/cache/objects_partial
+Date: April 2008
+KernelVersion: 2.6.26
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The objects_partial file is read-only and displays how many
+ objects are on partial slabs and from which nodes they are
+ from.
+
+What: /sys/kernel/slab/cache/objs_per_slab
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file objs_per_slab is read-only and specifies how many
+ objects may be allocated from a single slab of the order
+ specified in /sys/kernel/slab/cache/order.
+
+What: /sys/kernel/slab/cache/order
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The order file specifies the page order at which new slabs are
+ allocated. It is writable and can be changed to increase the
+ number of objects per slab. If a slab cannot be allocated
+ because of fragmentation, SLUB will retry with the minimum order
+ possible depending on its characteristics.
+
+What: /sys/kernel/slab/cache/order_fallback
+Date: April 2008
+KernelVersion: 2.6.26
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file order_fallback is read-only and specifies how many
+ times an allocation of a new slab has not been possible at the
+ cache's order and instead fallen back to its minimum possible
+ order.
+ Available when CONFIG_SLUB_STATS is enabled.
+
+What: /sys/kernel/slab/cache/partial
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The partial file is read-only and displays how long many
+ partial slabs there are and how long each node's list is.
+
+What: /sys/kernel/slab/cache/poison
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The poison file specifies whether objects should be poisoned
+ when a new slab is allocated.
+
+What: /sys/kernel/slab/cache/reclaim_account
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The reclaim_account file specifies whether the cache's objects
+ are reclaimable (and grouped by their mobility).
+
+What: /sys/kernel/slab/cache/red_zone
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The red_zone file specifies whether the cache's objects are red
+ zoned.
+
+What: /sys/kernel/slab/cache/remote_node_defrag_ratio
+Date: January 2008
+KernelVersion: 2.6.25
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The file remote_node_defrag_ratio specifies the percentage of
+ times SLUB will attempt to refill the cpu slab with a partial
+ slab from a remote node as opposed to allocating a new slab on
+ the local node. This reduces the amount of wasted memory over
+ the entire system but can be expensive.
+ Available when CONFIG_NUMA is enabled.
+
+What: /sys/kernel/slab/cache/sanity_checks
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The sanity_checks file specifies whether expensive checks
+ should be performed on free and, at minimum, enables double free
+ checks. Caches that enable sanity_checks cannot be merged with
+ caches that do not.
+
+What: /sys/kernel/slab/cache/shrink
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The shrink file is written when memory should be reclaimed from
+ a cache. Empty partial slabs are freed and the partial list is
+ sorted so the slabs with the fewest available objects are used
+ first.
+
+What: /sys/kernel/slab/cache/slab_size
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The slab_size file is read-only and specifies the object size
+ with metadata (debugging information and alignment) in bytes.
+
+What: /sys/kernel/slab/cache/slabs
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The slabs file is read-only and displays how long many slabs
+ there are (both cpu and partial) and from which nodes they are
+ from.
+
+What: /sys/kernel/slab/cache/store_user
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The store_user file specifies whether the location of
+ allocation or free should be tracked for a cache.
+
+What: /sys/kernel/slab/cache/total_objects
+Date: April 2008
+KernelVersion: 2.6.26
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The total_objects file is read-only and displays how many total
+ objects a cache has and from which nodes they are from.
+
+What: /sys/kernel/slab/cache/trace
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ The trace file specifies whether object allocations and frees
+ should be traced.
+
+What: /sys/kernel/slab/cache/validate
+Date: May 2007
+KernelVersion: 2.6.22
+Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
+ Christoph Lameter <cl@linux-foundation.org>
+Description:
+ Writing to the validate file causes SLUB to traverse all of its
+ cache's objects and check the validity of metadata.
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index b1eb661e6302..9632444f6c62 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -13,7 +13,8 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
mac80211.xml debugobjects.xml sh.xml regulator.xml \
- alsa-driver-api.xml writing-an-alsa-driver.xml
+ alsa-driver-api.xml writing-an-alsa-driver.xml \
+ tracepoint.xml
###
# The build process is as follows (targets):
diff --git a/Documentation/DocBook/kgdb.tmpl b/Documentation/DocBook/kgdb.tmpl
index 372dec20c8da..5cff41a5fa7c 100644
--- a/Documentation/DocBook/kgdb.tmpl
+++ b/Documentation/DocBook/kgdb.tmpl
@@ -281,7 +281,7 @@
seriously wrong while debugging, it will most often be the case
that you want to enable gdb to be verbose about its target
communications. You do this prior to issuing the <constant>target
- remote</constant> command by typing in: <constant>set remote debug 1</constant>
+ remote</constant> command by typing in: <constant>set debug remote 1</constant>
</para>
</chapter>
<chapter id="KGDBTestSuite">
diff --git a/Documentation/DocBook/tracepoint.tmpl b/Documentation/DocBook/tracepoint.tmpl
new file mode 100644
index 000000000000..b0756d0fd579
--- /dev/null
+++ b/Documentation/DocBook/tracepoint.tmpl
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
+
+<book id="Tracepoints">
+ <bookinfo>
+ <title>The Linux Kernel Tracepoint API</title>
+
+ <authorgroup>
+ <author>
+ <firstname>Jason</firstname>
+ <surname>Baron</surname>
+ <affiliation>
+ <address>
+ <email>jbaron@redhat.com</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <legalnotice>
+ <para>
+ This documentation 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.
+ </para>
+
+ <para>
+ 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.
+ </para>
+
+ <para>
+ 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
+ </para>
+
+ <para>
+ For more details see the file COPYING in the source
+ distribution of Linux.
+ </para>
+ </legalnotice>
+ </bookinfo>
+
+ <toc></toc>
+ <chapter id="intro">
+ <title>Introduction</title>
+ <para>
+ Tracepoints are static probe points that are located in strategic points
+ throughout the kernel. 'Probes' register/unregister with tracepoints
+ via a callback mechanism. The 'probes' are strictly typed functions that
+ are passed a unique set of parameters defined by each tracepoint.
+ </para>
+
+ <para>
+ From this simple callback mechanism, 'probes' can be used to profile, debug,
+ and understand kernel behavior. There are a number of tools that provide a
+ framework for using 'probes'. These tools include Systemtap, ftrace, and
+ LTTng.
+ </para>
+
+ <para>
+ Tracepoints are defined in a number of header files via various macros. Thus,
+ the purpose of this document is to provide a clear accounting of the available
+ tracepoints. The intention is to understand not only what tracepoints are
+ available but also to understand where future tracepoints might be added.
+ </para>
+
+ <para>
+ The API presented has functions of the form:
+ <function>trace_tracepointname(function parameters)</function>. These are the
+ tracepoints callbacks that are found throughout the code. Registering and
+ unregistering probes with these callback sites is covered in the
+ <filename>Documentation/trace/*</filename> directory.
+ </para>
+ </chapter>
+
+ <chapter id="irq">
+ <title>IRQ</title>
+!Iinclude/trace/events/irq.h
+ </chapter>
+
+</book>
diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt
index 068848240a8b..02cced183b2d 100644
--- a/Documentation/RCU/trace.txt
+++ b/Documentation/RCU/trace.txt
@@ -192,23 +192,24 @@ rcu/rcuhier (which displays the struct rcu_node hierarchy).
The output of "cat rcu/rcudata" looks as follows:
rcu:
- 0 c=4011 g=4012 pq=1 pqc=4011 qp=0 rpfq=1 rp=3c2a dt=23301/73 dn=2 df=1882 of=0 ri=2126 ql=2 b=10
- 1 c=4011 g=4012 pq=1 pqc=4011 qp=0 rpfq=3 rp=39a6 dt=78073/1 dn=2 df=1402 of=0 ri=1875 ql=46 b=10
- 2 c=4010 g=4010 pq=1 pqc=4010 qp=0 rpfq=-5 rp=1d12 dt=16646/0 dn=2 df=3140 of=0 ri=2080 ql=0 b=10
- 3 c=4012 g=4013 pq=1 pqc=4012 qp=1 rpfq=3 rp=2b50 dt=21159/1 dn=2 df=2230 of=0 ri=1923 ql=72 b=10
- 4 c=4012 g=4013 pq=1 pqc=4012 qp=1 rpfq=3 rp=1644 dt=5783/1 dn=2 df=3348 of=0 ri=2805 ql=7 b=10
- 5 c=4012 g=4013 pq=0 pqc=4011 qp=1 rpfq=3 rp=1aac dt=5879/1 dn=2 df=3140 of=0 ri=2066 ql=10 b=10
- 6 c=4012 g=4013 pq=1 pqc=4012 qp=1 rpfq=3 rp=ed8 dt=5847/1 dn=2 df=3797 of=0 ri=1266 ql=10 b=10
- 7 c=4012 g=4013 pq=1 pqc=4012 qp=1 rpfq=3 rp=1fa2 dt=6199/1 dn=2 df=2795 of=0 ri=2162 ql=28 b=10
+rcu:
+ 0 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=10951/1 dn=0 df=1101 of=0 ri=36 ql=0 b=10
+ 1 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=16117/1 dn=0 df=1015 of=0 ri=0 ql=0 b=10
+ 2 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=1445/1 dn=0 df=1839 of=0 ri=0 ql=0 b=10
+ 3 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=6681/1 dn=0 df=1545 of=0 ri=0 ql=0 b=10
+ 4 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=1003/1 dn=0 df=1992 of=0 ri=0 ql=0 b=10
+ 5 c=17829 g=17830 pq=1 pqc=17829 qp=1 dt=3887/1 dn=0 df=3331 of=0 ri=4 ql=2 b=10
+ 6 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=859/1 dn=0 df=3224 of=0 ri=0 ql=0 b=10
+ 7 c=17829 g=17830 pq=0 pqc=17829 qp=1 dt=3761/1 dn=0 df=1818 of=0 ri=0 ql=2 b=10
rcu_bh:
- 0 c=-268 g=-268 pq=1 pqc=-268 qp=0 rpfq=-145 rp=21d6 dt=23301/73 dn=2 df=0 of=0 ri=0 ql=0 b=10
- 1 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-170 rp=20ce dt=78073/1 dn=2 df=26 of=0 ri=5 ql=0 b=10
- 2 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-83 rp=fbd dt=16646/0 dn=2 df=28 of=0 ri=4 ql=0 b=10
- 3 c=-268 g=-268 pq=1 pqc=-268 qp=0 rpfq=-105 rp=178c dt=21159/1 dn=2 df=28 of=0 ri=2 ql=0 b=10
- 4 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-30 rp=b54 dt=5783/1 dn=2 df=32 of=0 ri=0 ql=0 b=10
- 5 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-29 rp=df5 dt=5879/1 dn=2 df=30 of=0 ri=3 ql=0 b=10
- 6 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-28 rp=788 dt=5847/1 dn=2 df=32 of=0 ri=0 ql=0 b=10
- 7 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-53 rp=1098 dt=6199/1 dn=2 df=30 of=0 ri=3 ql=0 b=10
+ 0 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=10951/1 dn=0 df=0 of=0 ri=0 ql=0 b=10
+ 1 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=16117/1 dn=0 df=13 of=0 ri=0 ql=0 b=10
+ 2 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=1445/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
+ 3 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=6681/1 dn=0 df=9 of=0 ri=0 ql=0 b=10
+ 4 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=1003/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
+ 5 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3887/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
+ 6 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=859/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
+ 7 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3761/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
The first section lists the rcu_data structures for rcu, the second for
rcu_bh. Each section has one line per CPU, or eight for this 8-CPU system.
@@ -253,12 +254,6 @@ o "pqc" indicates which grace period the last-observed quiescent
o "qp" indicates that RCU still expects a quiescent state from
this CPU.
-o "rpfq" is the number of rcu_pending() calls on this CPU required
- to induce this CPU to invoke force_quiescent_state().
-
-o "rp" is low-order four hex digits of the count of how many times
- rcu_pending() has been invoked on this CPU.
-
o "dt" is the current value of the dyntick counter that is incremented
when entering or leaving dynticks idle state, either by the
scheduler or by irq. The number after the "/" is the interrupt
@@ -305,6 +300,9 @@ o "b" is the batch limit for this CPU. If more than this number
of RCU callbacks is ready to invoke, then the remainder will
be deferred.
+There is also an rcu/rcudata.csv file with the same information in
+comma-separated-variable spreadsheet format.
+
The output of "cat rcu/rcugp" looks as follows:
@@ -411,3 +409,63 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
For example, the first entry at the lowest level shows
"^0", indicating that it corresponds to bit zero in
the first entry at the middle level.
+
+
+The output of "cat rcu/rcu_pending" looks as follows:
+
+rcu:
+ 0 np=255892 qsp=53936 cbr=0 cng=14417 gpc=10033 gps=24320 nf=6445 nn=146741
+ 1 np=261224 qsp=54638 cbr=0 cng=25723 gpc=16310 gps=2849 nf=5912 nn=155792
+ 2 np=237496 qsp=49664 cbr=0 cng=2762 gpc=45478 gps=1762 nf=1201 nn=136629
+ 3 np=236249 qsp=48766 cbr=0 cng=286 gpc=48049 gps=1218 nf=207 nn=137723
+ 4 np=221310 qsp=46850 cbr=0 cng=26 gpc=43161 gps=4634 nf=3529 nn=123110
+ 5 np=237332 qsp=48449 cbr=0 cng=54 gpc=47920 gps=3252 nf=201 nn=137456
+ 6 np=219995 qsp=46718 cbr=0 cng=50 gpc=42098 gps=6093 nf=4202 nn=120834
+ 7 np=249893 qsp=49390 cbr=0 cng=72 gpc=38400 gps=17102 nf=41 nn=144888
+rcu_bh:
+ 0 np=146741 qsp=1419 cbr=0 cng=6 gpc=0 gps=0 nf=2 nn=145314
+ 1 np=155792 qsp=12597 cbr=0 cng=0 gpc=4 gps=8 nf=3 nn=143180
+ 2 np=136629 qsp=18680 cbr=0 cng=0 gpc=7 gps=6 nf=0 nn=117936
+ 3 np=137723 qsp=2843 cbr=0 cng=0 gpc=10 gps=7 nf=0 nn=134863
+ 4 np=123110 qsp=12433 cbr=0 cng=0 gpc=4 gps=2 nf=0 nn=110671
+ 5 np=137456 qsp=4210 cbr=0 cng=0 gpc=6 gps=5 nf=0 nn=133235
+ 6 np=120834 qsp=9902 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
+ 7 np=144888 qsp=26336 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
+
+As always, this is once again split into "rcu" and "rcu_bh" portions.
+The fields are as follows:
+
+o "np" is the number of times that __rcu_pending() has been invoked
+ for the corresponding flavor of RCU.
+
+o "qsp" is the number of times that the RCU was waiting for a
+ quiescent state from this CPU.
+
+o "cbr" is the number of times that this CPU had RCU callbacks
+ that had passed through a grace period, and were thus ready
+ to be invoked.
+
+o "cng" is the number of times that this CPU needed another
+ grace period while RCU was idle.
+
+o "gpc" is the number of times that an old grace period had
+ completed, but this CPU was not yet aware of it.
+
+o "gps" is the number of times that a new grace period had started,
+ but this CPU was not yet aware of it.
+
+o "nf" is the number of times that this CPU suspected that the
+ current grace period had run for too long, and thus needed to
+ be forced.
+
+ Please note that "forcing" consists of sending resched IPIs
+ to holdout CPUs. If that CPU really still is in an old RCU
+ read-side critical section, then we really do have to wait for it.
+ The assumption behing "forcing" is that the CPU is not still in
+ an old RCU read-side critical section, but has not yet responded
+ for some other reason.
+
+o "nn" is the number of times that this CPU needed nothing. Alert
+ readers will note that the rcu "nn" number for a given CPU very
+ closely matches the rcu_bh "np" number for that same CPU. This
+ is due to short-circuit evaluation in rcu_pending().
diff --git a/Documentation/Smack.txt b/Documentation/Smack.txt
index 629c92e99783..34614b4c708e 100644
--- a/Documentation/Smack.txt
+++ b/Documentation/Smack.txt
@@ -184,8 +184,9 @@ length. Single character labels using special characters, that being anything
other than a letter or digit, are reserved for use by the Smack development
team. Smack labels are unstructured, case sensitive, and the only operation
ever performed on them is comparison for equality. Smack labels cannot
-contain unprintable characters or the "/" (slash) character. Smack labels
-cannot begin with a '-', which is reserved for special options.
+contain unprintable characters, the "/" (slash), the "\" (backslash), the "'"
+(quote) and '"' (double-quote) characters.
+Smack labels cannot begin with a '-', which is reserved for special options.
There are some predefined labels:
@@ -523,3 +524,18 @@ Smack supports some mount options:
These mount options apply to all file system types.
+Smack auditing
+
+If you want Smack auditing of security events, you need to set CONFIG_AUDIT
+in your kernel configuration.
+By default, all denied events will be audited. You can change this behavior by
+writing a single character to the /smack/logging file :
+0 : no logging
+1 : log denied (default)
+2 : log accepted
+3 : log denied & accepted
+
+Events are logged as 'key=value' pairs, for each event you at least will get
+the subjet, the object, the rights requested, the action, the kernel function
+that triggered the event, plus other pairs depending on the type of event
+audited.
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index f309d3c6221c..6f29e29555c0 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -405,7 +405,14 @@ person it names. This tag documents that potentially interested parties
have been included in the discussion
-14) Using Tested-by: and Reviewed-by:
+14) Using Reported-by:, Tested-by: and Reviewed-by:
+
+If this patch fixes a problem reported by somebody else, consider adding a
+Reported-by: tag to credit the reporter for their contribution. Please
+note that this tag should not be added without the reporter's permission,
+especially if the problem was not reported in a public forum. That said,
+if we diligently credit our bug reporters, they will, hopefully, be
+inspired to help us again in the future.
A Tested-by: tag indicates that the patch has been successfully tested (in
some environment) by the person named. This tag informs maintainers that
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index 2f21ecd4c205..815a57840a13 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -112,7 +112,7 @@ sub tda10045 {
sub tda10046 {
my $sourcefile = "TT_PCI_2.19h_28_11_2006.zip";
- my $url = "http://technotrend-online.com/download/software/219/$sourcefile";
+ my $url = "http://www.tt-download.com/download/updates/219/$sourcefile";
my $hash = "6a7e1e2f2644b162ff0502367553c72d";
my $outfile = "dvb-fe-tda10046.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
@@ -129,8 +129,8 @@ sub tda10046 {
}
sub tda10046lifeview {
- my $sourcefile = "Drv_2.11.02.zip";
- my $url = "http://www.lifeview.com.tw/drivers/pci_card/FlyDVB-T/$sourcefile";
+ my $sourcefile = "7%5Cdrv_2.11.02.zip";
+ my $url = "http://www.lifeview.hk/dbimages/document/$sourcefile";
my $hash = "1ea24dee4eea8fe971686981f34fd2e0";
my $outfile = "dvb-fe-tda10046.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index de491a3e2313..06d0fe15fea1 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -354,16 +354,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl>
---------------------------
-What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client(),
- i2c_adapter->client_register(), i2c_adapter->client_unregister
-When: 2.6.30
-Check: i2c_attach_client i2c_detach_client
-Why: Deprecated by the new (standard) device driver binding model. Use
- i2c_driver->probe() and ->remove() instead.
-Who: Jean Delvare <khali@linux-fr.org>
-
----------------------------
-
What: fscher and fscpos drivers
When: June 2009
Why: Deprecated by the new fschmd driver.
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
index 8dd6db76171d..f15621ee5599 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -66,6 +66,10 @@ 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.
+nfs41-server.txt
+ - info on the Linux server implementation of NFSv4 minor version 1.
+nfs-rdma.txt
+ - how to install and setup the Linux NFS/RDMA client and server software.
nfsroot.txt
- short guide on setting up a diskless box with NFS root filesystem.
nilfs2.txt
diff --git a/Documentation/futex-requeue-pi.txt b/Documentation/futex-requeue-pi.txt
new file mode 100644
index 000000000000..9dc1ff4fd536
--- /dev/null
+++ b/Documentation/futex-requeue-pi.txt
@@ -0,0 +1,131 @@
+Futex Requeue PI
+----------------
+
+Requeueing of tasks from a non-PI futex to a PI futex requires
+special handling in order to ensure the underlying rt_mutex is never
+left without an owner if it has waiters; doing so would break the PI
+boosting logic [see rt-mutex-desgin.txt] For the purposes of
+brevity, this action will be referred to as "requeue_pi" throughout
+this document. Priority inheritance is abbreviated throughout as
+"PI".
+
+Motivation
+----------
+
+Without requeue_pi, the glibc implementation of
+pthread_cond_broadcast() must resort to waking all the tasks waiting
+on a pthread_condvar and letting them try to sort out which task
+gets to run first in classic thundering-herd formation. An ideal
+implementation would wake the highest-priority waiter, and leave the
+rest to the natural wakeup inherent in unlocking the mutex
+associated with the condvar.
+
+Consider the simplified glibc calls:
+
+/* caller must lock mutex */
+pthread_cond_wait(cond, mutex)
+{
+ lock(cond->__data.__lock);
+ unlock(mutex);
+ do {
+ unlock(cond->__data.__lock);
+ futex_wait(cond->__data.__futex);
+ lock(cond->__data.__lock);
+ } while(...)
+ unlock(cond->__data.__lock);
+ lock(mutex);
+}
+
+pthread_cond_broadcast(cond)
+{
+ lock(cond->__data.__lock);
+ unlock(cond->__data.__lock);
+ futex_requeue(cond->data.__futex, cond->mutex);
+}
+
+Once pthread_cond_broadcast() requeues the tasks, the cond->mutex
+has waiters. Note that pthread_cond_wait() attempts to lock the
+mutex only after it has returned to user space. This will leave the
+underlying rt_mutex with waiters, and no owner, breaking the
+previously mentioned PI-boosting algorithms.
+
+In order to support PI-aware pthread_condvar's, the kernel needs to
+be able to requeue tasks to PI futexes. This support implies that
+upon a successful futex_wait system call, the caller would return to
+user space already holding the PI futex. The glibc implementation
+would be modified as follows:
+
+
+/* caller must lock mutex */
+pthread_cond_wait_pi(cond, mutex)
+{
+ lock(cond->__data.__lock);
+ unlock(mutex);
+ do {
+ unlock(cond->__data.__lock);
+ futex_wait_requeue_pi(cond->__data.__futex);
+ lock(cond->__data.__lock);
+ } while(...)
+ unlock(cond->__data.__lock);
+ /* the kernel acquired the the mutex for us */
+}
+
+pthread_cond_broadcast_pi(cond)
+{
+ lock(cond->__data.__lock);
+ unlock(cond->__data.__lock);
+ futex_requeue_pi(cond->data.__futex, cond->mutex);
+}
+
+The actual glibc implementation will likely test for PI and make the
+necessary changes inside the existing calls rather than creating new
+calls for the PI cases. Similar changes are needed for
+pthread_cond_timedwait() and pthread_cond_signal().
+
+Implementation
+--------------
+
+In order to ensure the rt_mutex has an owner if it has waiters, it
+is necessary for both the requeue code, as well as the waiting code,
+to be able to acquire the rt_mutex before returning to user space.
+The requeue code cannot simply wake the waiter and leave it to
+acquire the rt_mutex as it would open a race window between the
+requeue call returning to user space and the waiter waking and
+starting to run. This is especially true in the uncontended case.
+
+The solution involves two new rt_mutex helper routines,
+rt_mutex_start_proxy_lock() and rt_mutex_finish_proxy_lock(), which
+allow the requeue code to acquire an uncontended rt_mutex on behalf
+of the waiter and to enqueue the waiter on a contended rt_mutex.
+Two new system calls provide the kernel<->user interface to
+requeue_pi: FUTEX_WAIT_REQUEUE_PI and FUTEX_REQUEUE_CMP_PI.
+
+FUTEX_WAIT_REQUEUE_PI is called by the waiter (pthread_cond_wait()
+and pthread_cond_timedwait()) to block on the initial futex and wait
+to be requeued to a PI-aware futex. The implementation is the
+result of a high-speed collision between futex_wait() and
+futex_lock_pi(), with some extra logic to check for the additional
+wake-up scenarios.
+
+FUTEX_REQUEUE_CMP_PI is called by the waker
+(pthread_cond_broadcast() and pthread_cond_signal()) to requeue and
+possibly wake the waiting tasks. Internally, this system call is
+still handled by futex_requeue (by passing requeue_pi=1). Before
+requeueing, futex_requeue() attempts to acquire the requeue target
+PI futex on behalf of the top waiter. If it can, this waiter is
+woken. futex_requeue() then proceeds to requeue the remaining
+nr_wake+nr_requeue tasks to the PI futex, calling
+rt_mutex_start_proxy_lock() prior to each requeue to prepare the
+task as a waiter on the underlying rt_mutex. It is possible that
+the lock can be acquired at this stage as well, if so, the next
+waiter is woken to finish the acquisition of the lock.
+
+FUTEX_REQUEUE_PI accepts nr_wake and nr_requeue as arguments, but
+their sum is all that really matters. futex_requeue() will wake or
+requeue up to nr_wake + nr_requeue tasks. It will wake only as many
+tasks as it can acquire the lock for, which in the majority of cases
+should be 0 as good programming practice dictates that the caller of
+either pthread_cond_broadcast() or pthread_cond_signal() acquire the
+mutex prior to making the call. FUTEX_REQUEUE_PI requires that
+nr_wake=1. nr_requeue should be INT_MAX for broadcast and 0 for
+signal.
diff --git a/Documentation/hwmon/ibmaem b/Documentation/hwmon/ibmaem
index e98bdfea3467..1e0d59e000b4 100644
--- a/Documentation/hwmon/ibmaem
+++ b/Documentation/hwmon/ibmaem
@@ -7,7 +7,7 @@ henceforth as AEM.
Supported systems:
* Any recent IBM System X server with AEM support.
This includes the x3350, x3550, x3650, x3655, x3755, x3850 M2,
- x3950 M2, and certain HS2x/LS2x/QS2x blades. The IPMI host interface
+ x3950 M2, and certain HC10/HS2x/LS2x/QS2x blades. The IPMI host interface
driver ("ipmi-si") needs to be loaded for this driver to do anything.
Prefix: 'ibmaem'
Datasheet: Not available
diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices
index b55ce57a84db..c740b7b41088 100644
--- a/Documentation/i2c/instantiating-devices
+++ b/Documentation/i2c/instantiating-devices
@@ -165,3 +165,47 @@ was done there. Two significant differences are:
Once again, method 3 should be avoided wherever possible. Explicit device
instantiation (methods 1 and 2) is much preferred for it is safer and
faster.
+
+
+Method 4: Instantiate from user-space
+-------------------------------------
+
+In general, the kernel should know which I2C devices are connected and
+what addresses they live at. However, in certain cases, it does not, so a
+sysfs interface was added to let the user provide the information. This
+interface is made of 2 attribute files which are created in every I2C bus
+directory: new_device and delete_device. Both files are write only and you
+must write the right parameters to them in order to properly instantiate,
+respectively delete, an I2C device.
+
+File new_device takes 2 parameters: the name of the I2C device (a string)
+and the address of the I2C device (a number, typically expressed in
+hexadecimal starting with 0x, but can also be expressed in decimal.)
+
+File delete_device takes a single parameter: the address of the I2C
+device. As no two devices can live at the same address on a given I2C
+segment, the address is sufficient to uniquely identify the device to be
+deleted.
+
+Example:
+# echo eeprom 0x50 > /sys/class/i2c-adapter/i2c-3/new_device
+
+While this interface should only be used when in-kernel device declaration
+can't be done, there is a variety of cases where it can be helpful:
+* The I2C driver usually detects devices (method 3 above) but the bus
+ segment your device lives on doesn't have the proper class bit set and
+ thus detection doesn't trigger.
+* The I2C driver usually detects devices, but your device lives at an
+ unexpected address.
+* The I2C driver usually detects devices, but your device is not detected,
+ either because the detection routine is too strict, or because your
+ device is not officially supported yet but you know it is compatible.
+* You are developing a driver on a test board, where you soldered the I2C
+ device yourself.
+
+This interface is a replacement for the force_* module parameters some I2C
+drivers implement. Being implemented in i2c-core rather than in each
+device driver individually, it is much more efficient, and also has the
+advantage that you do not have to reload the driver to change a setting.
+You can also instantiate the device before the driver is loaded or even
+available, and you don't need to know what driver the device needs.
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index c1a06f989cf7..7860aafb483d 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -126,19 +126,9 @@ different) configuration information, as do drivers handling chip variants
that can't be distinguished by protocol probing, or which need some board
specific information to operate correctly.
-Accordingly, the I2C stack now has two models for associating I2C devices
-with their drivers: the original "legacy" model, and a newer one that's
-fully compatible with the Linux 2.6 driver model. These models do not mix,
-since the "legacy" model requires drivers to create "i2c_client" device
-objects after SMBus style probing, while the Linux driver model expects
-drivers to be given such device objects in their probe() routines.
-The legacy model is deprecated now and will soon be removed, so we no
-longer document it here.
-
-
-Standard Driver Model Binding ("New Style")
--------------------------------------------
+Device/Driver Binding
+---------------------
System infrastructure, typically board-specific initialization code or
boot firmware, reports what I2C devices exist. For example, there may be
@@ -201,7 +191,7 @@ a given I2C bus. This is for example the case of hardware monitoring
devices on a PC's SMBus. In that case, you may want to let your driver
detect supported devices automatically. This is how the legacy model
was working, and is now available as an extension to the standard
-driver model (so that we can finally get rid of the legacy model.)
+driver model.
You simply have to define a detect callback which will attempt to
identify supported devices (returning 0 for supported ones and -ENODEV
diff --git a/Documentation/input/input.txt b/Documentation/input/input.txt
index 686ee9932dff..b93c08442e3c 100644
--- a/Documentation/input/input.txt
+++ b/Documentation/input/input.txt
@@ -278,7 +278,7 @@ struct input_event {
};
'time' is the timestamp, it returns the time at which the event happened.
-Type is for example EV_REL for relative moment, REL_KEY for a keypress or
+Type is for example EV_REL for relative moment, EV_KEY for a keypress or
release. More types are defined in include/linux/input.h.
'code' is event code, for example REL_X or KEY_BACKSPACE, again a complete
diff --git a/Documentation/input/rotary-encoder.txt b/Documentation/input/rotary-encoder.txt
index 435102a26d96..3a6aec40c0b0 100644
--- a/Documentation/input/rotary-encoder.txt
+++ b/Documentation/input/rotary-encoder.txt
@@ -67,7 +67,12 @@ data with it.
struct rotary_encoder_platform_data is declared in
include/linux/rotary-encoder.h and needs to be filled with the number of
steps the encoder has and can carry information about externally inverted
-signals (because of used invertig buffer or other reasons).
+signals (because of an inverting buffer or other reasons). The encoder
+can be set up to deliver input information as either an absolute or relative
+axes. For relative axes the input event returns +/-1 for each step. For
+absolute axes the position of the encoder can either roll over between zero
+and the number of steps or will clamp at the maximum and zero depending on
+the configuration.
Because GPIO to IRQ mapping is platform specific, this information must
be given in seperately to the driver. See the example below.
@@ -85,6 +90,8 @@ be given in seperately to the driver. See the example below.
static struct rotary_encoder_platform_data my_rotary_encoder_info = {
.steps = 24,
.axis = ABS_X,
+ .relative_axis = false,
+ .rollover = false,
.gpio_a = GPIO_ROTARY_A,
.gpio_b = GPIO_ROTARY_B,
.inverted_a = 0,
diff --git a/Documentation/isdn/00-INDEX b/Documentation/isdn/00-INDEX
index 5a2d69989a8c..f6010a536590 100644
--- a/Documentation/isdn/00-INDEX
+++ b/Documentation/isdn/00-INDEX
@@ -22,16 +22,11 @@ README.gigaset
- info on the drivers for Siemens Gigaset ISDN adapters.
README.icn
- info on the ICN-ISDN-card and its driver.
+>>>>>>> 93af7aca44f0e82e67bda10a0fb73d383edcc8bd:Documentation/isdn/00-INDEX
README.HiSax
- info on the HiSax driver which replaces the old teles.
-README.hfc-pci
- - info on hfc-pci based cards.
-README.pcbit
- - info on the PCBIT-D ISDN adapter and driver.
-README.syncppp
- - info on running Sync PPP over ISDN.
-syncPPP.FAQ
- - frequently asked questions about running PPP over ISDN.
+README.audio
+ - info for running audio over ISDN.
README.avmb1
- info on driver for AVM-B1 ISDN card.
README.act2000
@@ -42,10 +37,28 @@ README.concap
- info on "CONCAP" encapsulation protocol interface used for X.25.
README.diversion
- info on module for isdn diversion services.
+README.fax
+ - info for using Fax over ISDN.
+README.gigaset
+ - info on the drivers for Siemens Gigaset ISDN adapters
+README.hfc-pci
+ - info on hfc-pci based cards.
+README.hysdn
+ - info on driver for Hypercope active HYSDN cards
+README.icn
+ - info on the ICN-ISDN-card and its driver.
+README.mISDN
+ - info on the Modular ISDN subsystem (mISDN)
+README.pcbit
+ - info on the PCBIT-D ISDN adapter and driver.
README.sc
- info on driver for Spellcaster cards.
+README.syncppp
+ - info on running Sync PPP over ISDN.
README.x25
- info for running X.25 over ISDN.
+syncPPP.FAQ
+ - frequently asked questions about running PPP over ISDN.
README.hysdn
- info on driver for Hypercope active HYSDN cards
README.mISDN
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 6e33e0d2a2a7..864b7ddaf7c6 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -17,6 +17,12 @@ are specified on the kernel command line with the module name plus
usbcore.blinkenlights=1
+Hyphens (dashes) and underscores are equivalent in parameter names, so
+ log_buf_len=1M print-fatal-signals=1
+can also be entered as
+ log-buf-len=1M print_fatal_signals=1
+
+
This document may not be entirely up to date and comprehensive. The command
"modinfo -p ${modulename}" shows a current list of all parameters of a loadable
module. Loadable modules, after being loaded into the running kernel, also
@@ -345,7 +351,7 @@ and is between 256 and 4096 characters. It is defined in the file
not play well with APC CPU idle - disable it if you have
APC and your system crashes randomly.
- apic= [APIC,i386] Advanced Programmable Interrupt Controller
+ apic= [APIC,X86-32] Advanced Programmable Interrupt Controller
Change the output verbosity whilst booting
Format: { quiet (default) | verbose | debug }
Change the amount of debugging information output
@@ -702,7 +708,7 @@ and is between 256 and 4096 characters. It is defined in the file
to discrete, to make X server driver able to add WB
entry later. This parameter enables that.
- enable_timer_pin_1 [i386,x86-64]
+ enable_timer_pin_1 [X86]
Enable PIN 1 of APIC timer
Can be useful to work around chipset bugs
(in particular on some ATI chipsets).
@@ -775,7 +781,7 @@ and is between 256 and 4096 characters. It is defined in the file
hashdist= [KNL,NUMA] Large hashes allocated during boot
are distributed across NUMA nodes. Defaults on
- for IA-64, off otherwise.
+ for 64bit NUMA, off otherwise.
Format: 0 | 1 (for off | on)
hcl= [IA-64] SGI's Hardware Graph compatibility layer
@@ -965,6 +971,7 @@ and is between 256 and 4096 characters. It is defined in the file
nomerge
forcesac
soft
+ pt [x86, IA64]
io7= [HW] IO7 for Marvel based alpha systems
See comment before marvel_specify_io7 in
@@ -1565,6 +1572,9 @@ and is between 256 and 4096 characters. It is defined in the file
noinitrd [RAM] Tells the kernel not to load any configured
initial RAM disk.
+ nointremap [X86-64, Intel-IOMMU] Do not enable interrupt
+ remapping.
+
nointroute [IA-64]
nojitter [IA64] Disables jitter checking for ITC timers.
@@ -1650,6 +1660,15 @@ and is between 256 and 4096 characters. It is defined in the file
oprofile.timer= [HW]
Use timer interrupt instead of performance counters
+ oprofile.cpu_type= Force an oprofile cpu type
+ This might be useful if you have an older oprofile
+ userland or if you want common events.
+ Format: { archperfmon | core_2 }
+ archperfmon: [X86] Force use of architectural
+ perfmon on Intel CPUs instead of the
+ CPU specific event set.
+ core_2: [X86] On Intel systems: report core_2 CPU.
+
osst= [HW,SCSI] SCSI Tape Driver
Format: <buffer_size>,<write_threshold>
See also Documentation/scsi/st.txt.
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index f5b7127f54ac..7f5809eddee6 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -31,6 +31,7 @@ Contents:
- Locking functions.
- Interrupt disabling functions.
+ - Sleep and wake-up functions.
- Miscellaneous functions.
(*) Inter-CPU locking barrier effects.
@@ -1217,6 +1218,132 @@ barriers are required in such a situation, they must be provided from some
other means.
+SLEEP AND WAKE-UP FUNCTIONS
+---------------------------
+
+Sleeping and waking on an event flagged in global data can be viewed as an
+interaction between two pieces of data: the task state of the task waiting for
+the event and the global data used to indicate the event. To make sure that
+these appear to happen in the right order, the primitives to begin the process
+of going to sleep, and the primitives to initiate a wake up imply certain
+barriers.
+
+Firstly, the sleeper normally follows something like this sequence of events:
+
+ for (;;) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if (event_indicated)
+ break;
+ schedule();
+ }
+
+A general memory barrier is interpolated automatically by set_current_state()
+after it has altered the task state:
+
+ CPU 1
+ ===============================
+ set_current_state();
+ set_mb();
+ STORE current->state
+ <general barrier>
+ LOAD event_indicated
+
+set_current_state() may be wrapped by:
+
+ prepare_to_wait();
+ prepare_to_wait_exclusive();
+
+which therefore also imply a general memory barrier after setting the state.
+The whole sequence above is available in various canned forms, all of which
+interpolate the memory barrier in the right place:
+
+ wait_event();
+ wait_event_interruptible();
+ wait_event_interruptible_exclusive();
+ wait_event_interruptible_timeout();
+ wait_event_killable();
+ wait_event_timeout();
+ wait_on_bit();
+ wait_on_bit_lock();
+
+
+Secondly, code that performs a wake up normally follows something like this:
+
+ event_indicated = 1;
+ wake_up(&event_wait_queue);
+
+or:
+
+ event_indicated = 1;
+ wake_up_process(event_daemon);
+
+A write memory barrier is implied by wake_up() and co. if and only if they wake
+something up. The barrier occurs before the task state is cleared, and so sits
+between the STORE to indicate the event and the STORE to set TASK_RUNNING:
+
+ CPU 1 CPU 2
+ =============================== ===============================
+ set_current_state(); STORE event_indicated
+ set_mb(); wake_up();
+ STORE current->state <write barrier>
+ <general barrier> STORE current->state
+ LOAD event_indicated
+
+The available waker functions include:
+
+ complete();
+ wake_up();
+ wake_up_all();
+ wake_up_bit();
+ wake_up_interruptible();
+ wake_up_interruptible_all();
+ wake_up_interruptible_nr();
+ wake_up_interruptible_poll();
+ wake_up_interruptible_sync();
+ wake_up_interruptible_sync_poll();
+ wake_up_locked();
+ wake_up_locked_poll();
+ wake_up_nr();
+ wake_up_poll();
+ wake_up_process();
+
+
+[!] Note that the memory barriers implied by the sleeper and the waker do _not_
+order multiple stores before the wake-up with respect to loads of those stored
+values after the sleeper has called set_current_state(). For instance, if the
+sleeper does:
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (event_indicated)
+ break;
+ __set_current_state(TASK_RUNNING);
+ do_something(my_data);
+
+and the waker does:
+
+ my_data = value;
+ event_indicated = 1;
+ wake_up(&event_wait_queue);
+
+there's no guarantee that the change to event_indicated will be perceived by
+the sleeper as coming after the change to my_data. In such a circumstance, the
+code on both sides must interpolate its own memory barriers between the
+separate data accesses. Thus the above sleeper ought to do:
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (event_indicated) {
+ smp_rmb();
+ do_something(my_data);
+ }
+
+and the waker should do:
+
+ my_data = value;
+ smp_wmb();
+ event_indicated = 1;
+ wake_up(&event_wait_queue);
+
+
MISCELLANEOUS FUNCTIONS
-----------------------
@@ -1366,7 +1493,7 @@ WHERE ARE MEMORY BARRIERS NEEDED?
Under normal operation, memory operation reordering is generally not going to
be a problem as a single-threaded linear piece of code will still appear to
-work correctly, even if it's in an SMP kernel. There are, however, three
+work correctly, even if it's in an SMP kernel. There are, however, four
circumstances in which reordering definitely _could_ be a problem:
(*) Interprocessor interaction.
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index ec5de02f543f..7f98aa3962c6 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -168,7 +168,16 @@ tcp_dsack - BOOLEAN
Allows TCP to send "duplicate" SACKs.
tcp_ecn - BOOLEAN
- Enable Explicit Congestion Notification in TCP.
+ Enable Explicit Congestion Notification (ECN) in TCP. ECN is only
+ used when both ends of the TCP flow support it. It is useful to
+ avoid losses due to congestion (when the bottleneck router supports
+ ECN).
+ Possible values are:
+ 0 disable ECN
+ 1 ECN enabled
+ 2 Only server-side ECN enabled. If the other end does
+ not support ECN, behavior is like with ECN disabled.
+ Default: 2
tcp_fack - BOOLEAN
Enable FACK congestion avoidance and fast retransmission.
diff --git a/Documentation/networking/mac80211-injection.txt b/Documentation/networking/mac80211-injection.txt
index 84906ef3ed6e..b30e81ad5307 100644
--- a/Documentation/networking/mac80211-injection.txt
+++ b/Documentation/networking/mac80211-injection.txt
@@ -12,38 +12,22 @@ following format:
The radiotap format is discussed in
./Documentation/networking/radiotap-headers.txt.
-Despite 13 radiotap argument types are currently defined, most only make sense
+Despite many radiotap parameters being currently defined, most only make sense
to appear on received packets. The following information is parsed from the
radiotap headers and used to control injection:
- * IEEE80211_RADIOTAP_RATE
-
- rate in 500kbps units, automatic if invalid or not present
-
-
- * IEEE80211_RADIOTAP_ANTENNA
-
- antenna to use, automatic if not present
-
-
- * IEEE80211_RADIOTAP_DBM_TX_POWER
-
- transmit power in dBm, automatic if not present
-
-
* IEEE80211_RADIOTAP_FLAGS
IEEE80211_RADIOTAP_F_FCS: FCS will be removed and recalculated
IEEE80211_RADIOTAP_F_WEP: frame will be encrypted if key available
IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the
- current fragmentation threshold. Note that
- this flag is only reliable when software
- fragmentation is enabled)
+ current fragmentation threshold.
+
The injection code can also skip all other currently defined radiotap fields
facilitating replay of captured radiotap headers directly.
-Here is an example valid radiotap header defining these three parameters
+Here is an example valid radiotap header defining some parameters
0x00, 0x00, // <-- radiotap version
0x0b, 0x00, // <- radiotap header length
@@ -72,8 +56,8 @@ interface), along the following lines:
...
r = pcap_inject(ppcap, u8aSendBuffer, nLength);
-You can also find sources for a complete inject test applet here:
+You can also find a link to a complete inject application here:
-http://penumbra.warmcat.com/_twk/tiki-index.php?page=packetspammer
+http://wireless.kernel.org/en/users/Documentation/packetspammer
Andy Green <andy@warmcat.com>
diff --git a/Documentation/powerpc/dts-bindings/ecm.txt b/Documentation/powerpc/dts-bindings/ecm.txt
new file mode 100644
index 000000000000..f514f29c67d6
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/ecm.txt
@@ -0,0 +1,64 @@
+=====================================================================
+E500 LAW & Coherency Module Device Tree Binding
+Copyright (C) 2009 Freescale Semiconductor Inc.
+=====================================================================
+
+Local Access Window (LAW) Node
+
+The LAW node represents the region of CCSR space where local access
+windows are configured. For ECM based devices this is the first 4k
+of CCSR space that includes CCSRBAR, ALTCBAR, ALTCAR, BPTR, and some
+number of local access windows as specified by fsl,num-laws.
+
+PROPERTIES
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: Must include "fsl,ecm-law"
+
+ - reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property. The value specifies the
+ physical address offset and length of the CCSR space
+ registers.
+
+ - fsl,num-laws
+ Usage: required
+ Value type: <u32>
+ Definition: The value specifies the number of local access
+ windows for this device.
+
+=====================================================================
+
+E500 Coherency Module Node
+
+The E500 LAW node represents the region of CCSR space where ECM config
+and error reporting registers exist, this is the second 4k (0x1000)
+of CCSR space.
+
+PROPERTIES
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: Must include "fsl,CHIP-ecm", "fsl,ecm" where
+ CHIP is the processor (mpc8572, mpc8544, etc.)
+
+ - reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property. The value specifies the
+ physical address offset and length of the CCSR space
+ registers.
+
+ - interrupts
+ Usage: required
+ Value type: <prop-encoded-array>
+
+ - interrupt-parent
+ Usage: required
+ Value type: <phandle>
+
+=====================================================================
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
index 78790d58dc2c..6e37be1eeb2d 100644
--- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
@@ -17,6 +17,9 @@ Required properties:
- model : precise model of the QE, Can be "QE", "CPM", or "CPM2"
- reg : offset and length of the device registers.
- bus-frequency : the clock frequency for QUICC Engine.
+- fsl,qe-num-riscs: define how many RISC engines the QE has.
+- fsl,qe-num-snums: define how many serial number(SNUM) the QE can use for the
+ threads.
Recommended properties
- brg-frequency : the internal clock source frequency for baud-rate
diff --git a/Documentation/powerpc/dts-bindings/fsl/mcm.txt b/Documentation/powerpc/dts-bindings/fsl/mcm.txt
new file mode 100644
index 000000000000..4ceda9b3b413
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/fsl/mcm.txt
@@ -0,0 +1,64 @@
+=====================================================================
+MPX LAW & Coherency Module Device Tree Binding
+Copyright (C) 2009 Freescale Semiconductor Inc.
+=====================================================================
+
+Local Access Window (LAW) Node
+
+The LAW node represents the region of CCSR space where local access
+windows are configured. For MCM based devices this is the first 4k
+of CCSR space that includes CCSRBAR, ALTCBAR, ALTCAR, BPTR, and some
+number of local access windows as specified by fsl,num-laws.
+
+PROPERTIES
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: Must include "fsl,mcm-law"
+
+ - reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property. The value specifies the
+ physical address offset and length of the CCSR space
+ registers.
+
+ - fsl,num-laws
+ Usage: required
+ Value type: <u32>
+ Definition: The value specifies the number of local access
+ windows for this device.
+
+=====================================================================
+
+MPX Coherency Module Node
+
+The MPX LAW node represents the region of CCSR space where MCM config
+and error reporting registers exist, this is the second 4k (0x1000)
+of CCSR space.
+
+PROPERTIES
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: Must include "fsl,CHIP-mcm", "fsl,mcm" where
+ CHIP is the processor (mpc8641, mpc8610, etc.)
+
+ - reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property. The value specifies the
+ physical address offset and length of the CCSR space
+ registers.
+
+ - interrupts
+ Usage: required
+ Value type: <prop-encoded-array>
+
+ - interrupt-parent
+ Usage: required
+ Value type: <phandle>
+
+=====================================================================
diff --git a/Documentation/scheduler/sched-rt-group.txt b/Documentation/scheduler/sched-rt-group.txt
index 5ba4d3fc625a..eb74b014a3f8 100644
--- a/Documentation/scheduler/sched-rt-group.txt
+++ b/Documentation/scheduler/sched-rt-group.txt
@@ -4,6 +4,7 @@
CONTENTS
========
+0. WARNING
1. Overview
1.1 The problem
1.2 The solution
@@ -14,6 +15,23 @@ CONTENTS
3. Future plans
+0. WARNING
+==========
+
+ Fiddling with these settings can result in an unstable system, the knobs are
+ root only and assumes root knows what he is doing.
+
+Most notable:
+
+ * very small values in sched_rt_period_us can result in an unstable
+ system when the period is smaller than either the available hrtimer
+ resolution, or the time it takes to handle the budget refresh itself.
+
+ * very small values in sched_rt_runtime_us can result in an unstable
+ system when the runtime is so small the system has difficulty making
+ forward progress (NOTE: the migration thread and kstopmachine both
+ are real-time processes).
+
1. Overview
===========
diff --git a/Documentation/scsi/scsi_fc_transport.txt b/Documentation/scsi/scsi_fc_transport.txt
index e5b071d46619..d7f181701dc2 100644
--- a/Documentation/scsi/scsi_fc_transport.txt
+++ b/Documentation/scsi/scsi_fc_transport.txt
@@ -1,10 +1,11 @@
SCSI FC Tansport
=============================================
-Date: 4/12/2007
+Date: 11/18/2008
Kernel Revisions for features:
rports : <<TBS>>
- vports : 2.6.22 (? TBD)
+ vports : 2.6.22
+ bsg support : 2.6.30 (?TBD?)
Introduction
@@ -15,6 +16,7 @@ The FC transport can be found at:
drivers/scsi/scsi_transport_fc.c
include/scsi/scsi_transport_fc.h
include/scsi/scsi_netlink_fc.h
+ include/scsi/scsi_bsg_fc.h
This file is found at Documentation/scsi/scsi_fc_transport.txt
@@ -472,6 +474,14 @@ int
fc_vport_terminate(struct fc_vport *vport)
+FC BSG support (CT & ELS passthru, and more)
+========================================================================
+<< To Be Supplied >>
+
+
+
+
+
Credits
=======
The following people have contributed to this document:
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index a6d5354639b2..de67229251d8 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -1271,6 +1271,11 @@ of interest:
hostdata[0] - area reserved for LLD at end of struct Scsi_Host. Size
is set by the second argument (named 'xtr_bytes') to
scsi_host_alloc() or scsi_register().
+ vendor_id - a unique value that identifies the vendor supplying
+ the LLD for the Scsi_Host. Used most often in validating
+ vendor-specific message requests. Value consists of an
+ identifier type and a vendor-specific value.
+ See scsi_netlink.h for a description of valid formats.
The scsi_host structure is defined in include/scsi/scsi_host.h
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index ecb969b9e979..42470312b285 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -1093,6 +1093,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module supports multiple cards.
The driver requires the firmware loader support on kernel.
+ Module snd-lx6464es
+ -------------------
+
+ Module for Digigram LX6464ES boards
+
+ This module supports multiple cards.
+
Module snd-maestro3
-------------------
@@ -1543,13 +1550,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module snd-sc6000
-----------------
- Module for Gallant SC-6000 soundcard.
+ Module for Gallant SC-6000 soundcard and later models: SC-6600
+ and SC-7000.
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)
+ joystick - Enable gameport - 0 = disable (default), 1 = enable
This module supports multiple cards.
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 8eec05bc079e..14ed1d114d7a 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -36,6 +36,7 @@ ALC260
acer Acer TravelMate
will Will laptops (PB V7900)
replacer Replacer 672V
+ favorit100 Maxdata Favorit 100XS
basic fixed pin assignment (old default model)
test for testing/debugging purpose, almost all controls can
adjusted. Appearing only when compiled with
@@ -85,10 +86,11 @@ ALC269
eeepc-p703 ASUS Eeepc P703 P900A
eeepc-p901 ASUS Eeepc P901 S101
fujitsu FSC Amilo
+ lifebook Fujitsu Lifebook S6420
auto auto-config reading BIOS (default)
-ALC662/663
-==========
+ALC662/663/272
+==============
3stack-dig 3-stack (2-channel) with SPDIF
3stack-6ch 3-stack (6-channel)
3stack-6ch-dig 3-stack (6-channel) with SPDIF
@@ -107,6 +109,9 @@ ALC662/663
asus-mode4 ASUS
asus-mode5 ASUS
asus-mode6 ASUS
+ dell Dell with ALC272
+ dell-zm1 Dell ZM1 with ALC272
+ samsung-nc10 Samsung NC10 mini notebook
auto auto-config reading BIOS (default)
ALC882/885
@@ -118,6 +123,7 @@ ALC882/885
asus-a7j ASUS A7J
asus-a7m ASUS A7M
macpro MacPro support
+ mb5 Macbook 5,1
mbp3 Macbook Pro rev3
imac24 iMac 24'' with jack detection
w2jc ASUS W2JC
@@ -150,6 +156,7 @@ ALC883/888
fujitsu-pi2515 Fujitsu AMILO Pi2515
fujitsu-xa3530 Fujitsu AMILO XA3530
3stack-6ch-intel Intel DG33* boards
+ asus-p5q ASUS P5Q-EM boards
auto auto-config reading BIOS (default)
ALC861/660
@@ -347,6 +354,7 @@ STAC92HD71B*
hp-m4 HP mini 1000
hp-dv5 HP dv series
hp-hdx HP HDX series
+ hp-dv4-1222nr HP dv4-1222nr (with LED support)
auto BIOS setup (default)
STAC92HD73*
diff --git a/Documentation/sound/alsa/soc/dapm.txt b/Documentation/sound/alsa/soc/dapm.txt
index 9e6763264a2e..9ac842be9b4f 100644
--- a/Documentation/sound/alsa/soc/dapm.txt
+++ b/Documentation/sound/alsa/soc/dapm.txt
@@ -62,6 +62,7 @@ Audio DAPM widgets fall into a number of types:-
o Mic - Mic (and optional Jack)
o Line - Line Input/Output (and optional Jack)
o Speaker - Speaker
+ o Supply - Power or clock supply widget used by other widgets.
o Pre - Special PRE widget (exec before all others)
o Post - Special POST widget (exec after all others)
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index f11ca7979fa6..322a00bb99d9 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -32,6 +32,7 @@ show up in /proc/sys/kernel:
- kstack_depth_to_print [ X86 only ]
- l2cr [ PPC only ]
- modprobe ==> Documentation/debugging-modules.txt
+- modules_disabled
- msgmax
- msgmnb
- msgmni
@@ -184,6 +185,16 @@ kernel stack.
==============================================================
+modules_disabled:
+
+A toggle value indicating if modules are allowed to be loaded
+in an otherwise modular kernel. This toggle defaults to off
+(0), but can be set true (1). Once true, modules can be
+neither loaded nor unloaded, and the toggle cannot be set back
+to false.
+
+==============================================================
+
osrelease, ostype & version:
# cat osrelease
diff --git a/Documentation/sysfs-rules.txt b/Documentation/sysfs-rules.txt
index 6049a2a84dda..5d8bc2cd250c 100644
--- a/Documentation/sysfs-rules.txt
+++ b/Documentation/sysfs-rules.txt
@@ -113,7 +113,7 @@ versions of the sysfs interface.
"devices" directory at /sys/subsystem/<name>/devices.
If /sys/subsystem exists, /sys/bus, /sys/class and /sys/block can be
- ignored. If it does not exist, you have always to scan all three
+ ignored. If it does not exist, you always have to scan all three
places, as the kernel is free to move a subsystem from one place to
the other, as long as the devices are still reachable by the same
subsystem name.
diff --git a/Documentation/trace/events.txt b/Documentation/trace/events.txt
new file mode 100644
index 000000000000..abdee664c0f6
--- /dev/null
+++ b/Documentation/trace/events.txt
@@ -0,0 +1,135 @@
+ Event Tracing
+
+ Documentation written by Theodore Ts'o
+
+Introduction
+============
+
+Tracepoints (see Documentation/trace/tracepoints.txt) can be used
+without creating custom kernel modules to register probe functions
+using the event tracing infrastructure.
+
+Not all tracepoints can be traced using the event tracing system;
+the kernel developer must provide code snippets which define how the
+tracing information is saved into the tracing buffer, and how the
+the tracing information should be printed.
+
+Using Event Tracing
+===================
+
+The events which are available for tracing can be found in the file
+/sys/kernel/debug/tracing/available_events.
+
+To enable a particular event, such as 'sched_wakeup', simply echo it
+to /sys/debug/tracing/set_event. For example:
+
+ # echo sched_wakeup > /sys/kernel/debug/tracing/set_event
+
+[ Note: events can also be enabled/disabled via the 'enabled' toggle
+ found in the /sys/kernel/tracing/events/ hierarchy of directories. ]
+
+To disable an event, echo the event name to the set_event file prefixed
+with an exclamation point:
+
+ # echo '!sched_wakeup' >> /sys/kernel/debug/tracing/set_event
+
+To disable events, echo an empty line to the set_event file:
+
+ # echo > /sys/kernel/debug/tracing/set_event
+
+The events are organized into subsystems, such as ext4, irq, sched,
+etc., and a full event name looks like this: <subsystem>:<event>. The
+subsystem name is optional, but it is displayed in the available_events
+file. All of the events in a subsystem can be specified via the syntax
+"<subsystem>:*"; for example, to enable all irq events, you can use the
+command:
+
+ # echo 'irq:*' > /sys/kernel/debug/tracing/set_event
+
+Defining an event-enabled tracepoint
+------------------------------------
+
+A kernel developer which wishes to define an event-enabled tracepoint
+must declare the tracepoint using TRACE_EVENT instead of DECLARE_TRACE.
+This is done via two header files in include/trace. For example, to
+event-enable the jbd2 subsystem, we must create two files,
+include/trace/jbd2.h and include/trace/jbd2_event_types.h. The
+include/trace/jbd2.h file should be included by kernel source files that
+will have a tracepoint inserted, and might look like this:
+
+#ifndef _TRACE_JBD2_H
+#define _TRACE_JBD2_H
+
+#include <linux/jbd2.h>
+#include <linux/tracepoint.h>
+
+#include <trace/jbd2_event_types.h>
+
+#endif
+
+In a file that utilizes a jbd2 tracepoint, this header file would be
+included. Note that you still have to use DEFINE_TRACE(). So for
+example, if fs/jbd2/commit.c planned to use the jbd2_start_commit
+tracepoint, it would have the following near the beginning of the file:
+
+#include <trace/jbd2.h>
+
+DEFINE_TRACE(jbd2_start_commit);
+
+Then in the function that would call the tracepoint, it would call the
+tracepoint function. (For more information, please see the tracepoint
+documentation in Documentation/trace/tracepoints.txt):
+
+ trace_jbd2_start_commit(journal, commit_transaction);
+
+The code snippets which allow jbd2_start_commit to be an event-enabled
+tracepoint are placed in the file include/trace/jbd2_event_types.h:
+
+/* use <trace/jbd2.h> instead */
+#ifndef TRACE_EVENT
+# error Do not include this file directly.
+# error Unless you know what you are doing.
+#endif
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM jbd2
+
+#include <linux/jbd2.h>
+
+TRACE_EVENT(jbd2_start_commit,
+ TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
+ TP_ARGS(journal, commit_transaction),
+ TP_STRUCT__entry(
+ __array( char, devname, BDEVNAME_SIZE+24 )
+ __field( int, transaction )
+ ),
+ TP_fast_assign(
+ memcpy(__entry->devname, journal->j_devname, BDEVNAME_SIZE+24);
+ __entry->transaction = commit_transaction->t_tid;
+ ),
+ TP_printk("dev %s transaction %d",
+ __entry->devname, __entry->transaction)
+);
+
+The TP_PROTO and TP_ARGS are unchanged from DECLARE_TRACE. The new
+arguments to TRACE_EVENT are TP_STRUCT__entry, TP_fast_assign, and
+TP_printk.
+
+TP_STRUCT__entry defines the data structure which will be stored in the
+trace buffer. Normally, fields in __entry will be arrays or simple
+types. It is possible to place data structures in __entry --- however,
+pointers in the data structure can not be trusted, since they will be
+accessed sometime later by TP_printk, and if the data structure contains
+fields that will not or cannot be used by TP_printk, this will waste
+space in the trace buffer. In general, data structures should be
+avoided, unless they do only contain non-pointer types and all of the
+fields will be used by TP_printk.
+
+TP_fast_assign defines the code snippet which saves information into the
+__entry data structure, using the passed-in arguments defined in
+TP_PROTO and TP_ARGS.
+
+Finally, TP_printk will print the __entry data structure. At the time
+when the code snippet defined by TP_printk is executed, it will not have
+access to the TP_ARGS arguments; it can only use the information saved
+in the __entry data structure.
diff --git a/Documentation/trace/power.txt b/Documentation/trace/power.txt
new file mode 100644
index 000000000000..cd805e16dc27
--- /dev/null
+++ b/Documentation/trace/power.txt
@@ -0,0 +1,17 @@
+The power tracer collects detailed information about C-state and P-state
+transitions, instead of just looking at the high-level "average"
+information.
+
+There is a helper script found in scrips/tracing/power.pl in the kernel
+sources which can be used to parse this information and create a
+Scalable Vector Graphics (SVG) picture from the trace data.
+
+To use this tracer:
+
+ echo 0 > /sys/kernel/debug/tracing/tracing_enabled
+ echo power > /sys/kernel/debug/tracing/current_tracer
+ echo 1 > /sys/kernel/debug/tracing/tracing_enabled
+ sleep 1
+ echo 0 > /sys/kernel/debug/tracing/tracing_enabled
+ cat /sys/kernel/debug/tracing/trace | \
+ perl scripts/tracing/power.pl > out.sv
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 71e9db0b26f7..80527b292dd4 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -78,3 +78,4 @@
77 -> TBS 8910 DVB-S [8910:8888]
78 -> Prof 6200 DVB-S [b022:3022]
79 -> Terratec Cinergy HT PCI MKII [153b:1177]
+ 80 -> Hauppauge WinTV-IR Only [0070:9290]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index 78d0a6eed571..bf58d957e0df 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -61,3 +61,4 @@
63 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303]
64 -> Easy Cap Capture DC-60 (em2860)
65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515]
+ 66 -> Empire dual TV (em2880)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 6dacf2825259..112ff4f4fd9a 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -124,10 +124,10 @@
123 -> Beholder BeholdTV 407 [0000:4070]
124 -> Beholder BeholdTV 407 FM [0000:4071]
125 -> Beholder BeholdTV 409 [0000:4090]
-126 -> Beholder BeholdTV 505 FM/RDS [0000:5051,0000:505B,5ace:5050]
-127 -> Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM [0000:5071,0000:507B,5ace:5070,5ace:5090]
+126 -> Beholder BeholdTV 505 FM [5ace:5050]
+127 -> Beholder BeholdTV 507 FM / BeholdTV 509 FM [5ace:5070,5ace:5090]
128 -> Beholder BeholdTV Columbus TVFM [0000:5201]
-129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
+129 -> Beholder BeholdTV 607 FM [5ace:6070]
130 -> Beholder BeholdTV M6 [5ace:6190]
131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022]
132 -> Genius TVGO AM11MCE
@@ -155,3 +155,15 @@
154 -> Avermedia AVerTV GO 007 FM Plus [1461:f31d]
155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid [0070:6706,0070:6708]
156 -> Hauppauge WinTV-HVR1110r3 [0070:6707,0070:6709,0070:670a]
+157 -> Avermedia AVerTV Studio 507UA [1461:a11b]
+158 -> AVerMedia Cardbus TV/Radio (E501R) [1461:b7e9]
+159 -> Beholder BeholdTV 505 RDS [0000:505B]
+160 -> Beholder BeholdTV 507 RDS [0000:5071]
+161 -> Beholder BeholdTV 507 RDS [0000:507B]
+162 -> Beholder BeholdTV 607 FM [5ace:6071]
+163 -> Beholder BeholdTV 609 FM [5ace:6090]
+164 -> Beholder BeholdTV 609 FM [5ace:6091]
+165 -> Beholder BeholdTV 607 RDS [5ace:6072]
+166 -> Beholder BeholdTV 607 RDS [5ace:6073]
+167 -> Beholder BeholdTV 609 RDS [5ace:6092]
+168 -> Beholder BeholdTV 609 RDS [5ace:6093]
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 98529e03a46e..1bb103fe9b8d 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -178,6 +178,7 @@ spca506 06e1:a190 ADS Instant VCD
ov534 06f8:3002 Hercules Blog Webcam
ov534 06f8:3003 Hercules Dualpix HD Weblog
sonixj 06f8:3004 Hercules Classic Silver
+sonixj 06f8:3008 Hercules Deluxe Optical Glass
spca508 0733:0110 ViewQuest VQ110
spca508 0130:0130 Clone Digital Webcam 11043
spca501 0733:0401 Intel Create and Share
@@ -209,6 +210,7 @@ sunplus 08ca:2050 Medion MD 41437
sunplus 08ca:2060 Aiptek PocketDV5300
tv8532 0923:010f ICM532 cams
mars 093a:050f Mars-Semi Pc-Camera
+mr97310a 093a:010f Sakar Digital no. 77379
pac207 093a:2460 Qtec Webcam 100
pac207 093a:2461 HP Webcam
pac207 093a:2463 Philips SPC 220 NC
@@ -265,6 +267,11 @@ sonixj 0c45:60ec SN9C105+MO4000
sonixj 0c45:60fb Surfer NoName
sonixj 0c45:60fc LG-LIC300
sonixj 0c45:60fe Microdia Audio
+sonixj 0c45:6100 PC Camera (SN9C128)
+sonixj 0c45:610a PC Camera (SN9C128)
+sonixj 0c45:610b PC Camera (SN9C128)
+sonixj 0c45:610c PC Camera (SN9C128)
+sonixj 0c45:610e PC Camera (SN9C128)
sonixj 0c45:6128 Microdia/Sonix SNP325
sonixj 0c45:612a Avant Camera
sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix
diff --git a/Documentation/video4linux/pxa_camera.txt b/Documentation/video4linux/pxa_camera.txt
index b1137f9a53eb..4f6d0ca01956 100644
--- a/Documentation/video4linux/pxa_camera.txt
+++ b/Documentation/video4linux/pxa_camera.txt
@@ -26,6 +26,55 @@ Global video workflow
Once the last buffer is filled in, the QCI interface stops.
+ c) Capture global finite state machine schema
+
+ +----+ +---+ +----+
+ | DQ | | Q | | DQ |
+ | v | v | v
+ +-----------+ +------------------------+
+ | STOP | | Wait for capture start |
+ +-----------+ Q +------------------------+
++-> | QCI: stop | ------------------> | QCI: run | <------------+
+| | DMA: stop | | DMA: stop | |
+| +-----------+ +-----> +------------------------+ |
+| / | |
+| / +---+ +----+ | |
+|capture list empty / | Q | | DQ | | QCI Irq EOF |
+| / | v | v v |
+| +--------------------+ +----------------------+ |
+| | DMA hotlink missed | | Capture running | |
+| +--------------------+ +----------------------+ |
+| | QCI: run | +-----> | QCI: run | <-+ |
+| | DMA: stop | / | DMA: run | | |
+| +--------------------+ / +----------------------+ | Other |
+| ^ /DMA still | | channels |
+| | capture list / running | DMA Irq End | not |
+| | not empty / | | finished |
+| | / v | yet |
+| +----------------------+ +----------------------+ | |
+| | Videobuf released | | Channel completed | | |
+| +----------------------+ +----------------------+ | |
++-- | QCI: run | | QCI: run | --+ |
+ | DMA: run | | DMA: run | |
+ +----------------------+ +----------------------+ |
+ ^ / | |
+ | no overrun / | overrun |
+ | / v |
+ +--------------------+ / +----------------------+ |
+ | Frame completed | / | Frame overran | |
+ +--------------------+ <-----+ +----------------------+ restart frame |
+ | QCI: run | | QCI: stop | --------------+
+ | DMA: run | | DMA: stop |
+ +--------------------+ +----------------------+
+
+ Legend: - each box is a FSM state
+ - each arrow is the condition to transition to another state
+ - an arrow with a comment is a mandatory transition (no condition)
+ - arrow "Q" means : a buffer was enqueued
+ - arrow "DQ" means : a buffer was dequeued
+ - "QCI: stop" means the QCI interface is not enabled
+ - "DMA: stop" means all 3 DMA channels are stopped
+ - "DMA: run" means at least 1 DMA channel is still running
DMA usage
---------
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 854808b67fae..d54c1e4c6a9c 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -89,6 +89,11 @@ from dev (driver name followed by the bus_id, to be precise). If you set it
up before calling v4l2_device_register then it will be untouched. If dev is
NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register.
+You can use v4l2_device_set_name() to set the name based on a driver name and
+a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1,
+etc. If the name ends with a digit, then it will insert a dash: cx18-0,
+cx18-1, etc. This function returns the instance number.
+
The first 'dev' argument is normally the struct device pointer of a pci_dev,
usb_interface or platform_device. It is rare for dev to be NULL, but it happens
with ISA devices or when one device creates multiple PCI devices, thus making
diff --git a/Documentation/vm/slqbinfo.c b/Documentation/vm/slqbinfo.c
new file mode 100644
index 000000000000..449e64913e89
--- /dev/null
+++ b/Documentation/vm/slqbinfo.c
@@ -0,0 +1,1054 @@
+/*
+ * Slabinfo: Tool to get reports about slabs
+ *
+ * (C) 2007 sgi, Christoph Lameter
+ *
+ * Reworked by Lin Ming <ming.m.lin@intel.com> for SLQB
+ *
+ * Compile by:
+ *
+ * gcc -o slabinfo slabinfo.c
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <strings.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <regex.h>
+#include <errno.h>
+
+#define MAX_SLABS 500
+#define MAX_ALIASES 500
+#define MAX_NODES 1024
+
+struct slabinfo {
+ char *name;
+ int align, cache_dma, destroy_by_rcu;
+ int hwcache_align, object_size, objs_per_slab;
+ int slab_size, store_user;
+ int order, poison, reclaim_account, red_zone;
+ int batch;
+ unsigned long objects, slabs, total_objects;
+ unsigned long alloc, alloc_slab_fill, alloc_slab_new;
+ unsigned long free, free_remote;
+ unsigned long claim_remote_list, claim_remote_list_objects;
+ unsigned long flush_free_list, flush_free_list_objects, flush_free_list_remote;
+ unsigned long flush_rfree_list, flush_rfree_list_objects;
+ unsigned long flush_slab_free, flush_slab_partial;
+ int numa[MAX_NODES];
+ int numa_partial[MAX_NODES];
+} slabinfo[MAX_SLABS];
+
+int slabs = 0;
+int actual_slabs = 0;
+int highest_node = 0;
+
+char buffer[4096];
+
+int show_empty = 0;
+int show_report = 0;
+int show_slab = 0;
+int skip_zero = 1;
+int show_numa = 0;
+int show_track = 0;
+int validate = 0;
+int shrink = 0;
+int show_inverted = 0;
+int show_totals = 0;
+int sort_size = 0;
+int sort_active = 0;
+int set_debug = 0;
+int show_ops = 0;
+int show_activity = 0;
+
+/* Debug options */
+int sanity = 0;
+int redzone = 0;
+int poison = 0;
+int tracking = 0;
+int tracing = 0;
+
+int page_size;
+
+regex_t pattern;
+
+void fatal(const char *x, ...)
+{
+ va_list ap;
+
+ va_start(ap, x);
+ vfprintf(stderr, x, ap);
+ va_end(ap);
+ exit(EXIT_FAILURE);
+}
+
+void usage(void)
+{
+ printf("slabinfo 5/7/2007. (c) 2007 sgi.\n\n"
+ "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n"
+ "-A|--activity Most active slabs first\n"
+ "-d<options>|--debug=<options> Set/Clear Debug options\n"
+ "-D|--display-active Switch line format to activity\n"
+ "-e|--empty Show empty slabs\n"
+ "-h|--help Show usage information\n"
+ "-i|--inverted Inverted list\n"
+ "-l|--slabs Show slabs\n"
+ "-n|--numa Show NUMA information\n"
+ "-o|--ops Show kmem_cache_ops\n"
+ "-s|--shrink Shrink slabs\n"
+ "-r|--report Detailed report on single slabs\n"
+ "-S|--Size Sort by size\n"
+ "-t|--tracking Show alloc/free information\n"
+ "-T|--Totals Show summary information\n"
+ "-v|--validate Validate slabs\n"
+ "-z|--zero Include empty slabs\n"
+ "\nValid debug options (FZPUT may be combined)\n"
+ "a / A Switch on all debug options (=FZUP)\n"
+ "- Switch off all debug options\n"
+ "f / F Sanity Checks (SLAB_DEBUG_FREE)\n"
+ "z / Z Redzoning\n"
+ "p / P Poisoning\n"
+ "u / U Tracking\n"
+ "t / T Tracing\n"
+ );
+}
+
+unsigned long read_obj(const char *name)
+{
+ FILE *f = fopen(name, "r");
+
+ if (!f)
+ buffer[0] = 0;
+ else {
+ if (!fgets(buffer, sizeof(buffer), f))
+ buffer[0] = 0;
+ fclose(f);
+ if (buffer[strlen(buffer)] == '\n')
+ buffer[strlen(buffer)] = 0;
+ }
+ return strlen(buffer);
+}
+
+
+/*
+ * Get the contents of an attribute
+ */
+unsigned long get_obj(const char *name)
+{
+ if (!read_obj(name))
+ return 0;
+
+ return atol(buffer);
+}
+
+unsigned long get_obj_and_str(const char *name, char **x)
+{
+ unsigned long result = 0;
+ char *p;
+
+ *x = NULL;
+
+ if (!read_obj(name)) {
+ x = NULL;
+ return 0;
+ }
+ result = strtoul(buffer, &p, 10);
+ while (*p == ' ')
+ p++;
+ if (*p)
+ *x = strdup(p);
+ return result;
+}
+
+void set_obj(struct slabinfo *s, const char *name, int n)
+{
+ char x[100];
+ FILE *f;
+
+ snprintf(x, 100, "%s/%s", s->name, name);
+ f = fopen(x, "w");
+ if (!f)
+ fatal("Cannot write to %s\n", x);
+
+ fprintf(f, "%d\n", n);
+ fclose(f);
+}
+
+unsigned long read_slab_obj(struct slabinfo *s, const char *name)
+{
+ char x[100];
+ FILE *f;
+ size_t l;
+
+ snprintf(x, 100, "%s/%s", s->name, name);
+ f = fopen(x, "r");
+ if (!f) {
+ buffer[0] = 0;
+ l = 0;
+ } else {
+ l = fread(buffer, 1, sizeof(buffer), f);
+ buffer[l] = 0;
+ fclose(f);
+ }
+ return l;
+}
+
+
+/*
+ * Put a size string together
+ */
+int store_size(char *buffer, unsigned long value)
+{
+ unsigned long divisor = 1;
+ char trailer = 0;
+ int n;
+
+ if (value > 1000000000UL) {
+ divisor = 100000000UL;
+ trailer = 'G';
+ } else if (value > 1000000UL) {
+ divisor = 100000UL;
+ trailer = 'M';
+ } else if (value > 1000UL) {
+ divisor = 100;
+ trailer = 'K';
+ }
+
+ value /= divisor;
+ n = sprintf(buffer, "%ld",value);
+ if (trailer) {
+ buffer[n] = trailer;
+ n++;
+ buffer[n] = 0;
+ }
+ if (divisor != 1) {
+ memmove(buffer + n - 2, buffer + n - 3, 4);
+ buffer[n-2] = '.';
+ n++;
+ }
+ return n;
+}
+
+void decode_numa_list(int *numa, char *t)
+{
+ int node;
+ int nr;
+
+ memset(numa, 0, MAX_NODES * sizeof(int));
+
+ if (!t)
+ return;
+
+ while (*t == 'N') {
+ t++;
+ node = strtoul(t, &t, 10);
+ if (*t == '=') {
+ t++;
+ nr = strtoul(t, &t, 10);
+ numa[node] = nr;
+ if (node > highest_node)
+ highest_node = node;
+ }
+ while (*t == ' ')
+ t++;
+ }
+}
+
+void slab_validate(struct slabinfo *s)
+{
+ if (strcmp(s->name, "*") == 0)
+ return;
+
+ set_obj(s, "validate", 1);
+}
+
+void slab_shrink(struct slabinfo *s)
+{
+ if (strcmp(s->name, "*") == 0)
+ return;
+
+ set_obj(s, "shrink", 1);
+}
+
+int line = 0;
+
+void first_line(void)
+{
+ if (show_activity)
+ printf("Name Objects Alloc Free %%Fill %%New "
+ "FlushR %%FlushR FlushR_Objs O\n");
+ else
+ printf("Name Objects Objsize Space "
+ " O/S O %%Ef Batch Flg\n");
+}
+
+unsigned long slab_size(struct slabinfo *s)
+{
+ return s->slabs * (page_size << s->order);
+}
+
+unsigned long slab_activity(struct slabinfo *s)
+{
+ return s->alloc + s->free;
+}
+
+void slab_numa(struct slabinfo *s, int mode)
+{
+ int node;
+
+ if (strcmp(s->name, "*") == 0)
+ return;
+
+ if (!highest_node) {
+ printf("\n%s: No NUMA information available.\n", s->name);
+ return;
+ }
+
+ if (skip_zero && !s->slabs)
+ return;
+
+ if (!line) {
+ printf("\n%-21s:", mode ? "NUMA nodes" : "Slab");
+ for(node = 0; node <= highest_node; node++)
+ printf(" %4d", node);
+ printf("\n----------------------");
+ for(node = 0; node <= highest_node; node++)
+ printf("-----");
+ printf("\n");
+ }
+ printf("%-21s ", mode ? "All slabs" : s->name);
+ for(node = 0; node <= highest_node; node++) {
+ char b[20];
+
+ store_size(b, s->numa[node]);
+ printf(" %4s", b);
+ }
+ printf("\n");
+ if (mode) {
+ printf("%-21s ", "Partial slabs");
+ for(node = 0; node <= highest_node; node++) {
+ char b[20];
+
+ store_size(b, s->numa_partial[node]);
+ printf(" %4s", b);
+ }
+ printf("\n");
+ }
+ line++;
+}
+
+void show_tracking(struct slabinfo *s)
+{
+ printf("\n%s: Kernel object allocation\n", s->name);
+ printf("-----------------------------------------------------------------------\n");
+ if (read_slab_obj(s, "alloc_calls"))
+ printf(buffer);
+ else
+ printf("No Data\n");
+
+ printf("\n%s: Kernel object freeing\n", s->name);
+ printf("------------------------------------------------------------------------\n");
+ if (read_slab_obj(s, "free_calls"))
+ printf(buffer);
+ else
+ printf("No Data\n");
+
+}
+
+void ops(struct slabinfo *s)
+{
+ if (strcmp(s->name, "*") == 0)
+ return;
+
+ if (read_slab_obj(s, "ops")) {
+ printf("\n%s: kmem_cache operations\n", s->name);
+ printf("--------------------------------------------\n");
+ printf(buffer);
+ } else
+ printf("\n%s has no kmem_cache operations\n", s->name);
+}
+
+const char *onoff(int x)
+{
+ if (x)
+ return "On ";
+ return "Off";
+}
+
+void slab_stats(struct slabinfo *s)
+{
+ unsigned long total_alloc;
+ unsigned long total_free;
+ unsigned long total;
+
+ total_alloc = s->alloc;
+ total_free = s->free;
+
+ if (!total_alloc)
+ return;
+
+ printf("\n");
+ printf("Slab Perf Counter\n");
+ printf("------------------------------------------------------------------------\n");
+ printf("Alloc: %8lu, partial %8lu, page allocator %8lu\n",
+ total_alloc,
+ s->alloc_slab_fill, s->alloc_slab_new);
+ printf("Free: %8lu, partial %8lu, page allocator %8lu, remote %5lu\n",
+ total_free,
+ s->flush_slab_partial,
+ s->flush_slab_free,
+ s->free_remote);
+ printf("Claim: %8lu, objects %8lu\n",
+ s->claim_remote_list,
+ s->claim_remote_list_objects);
+ printf("Flush: %8lu, objects %8lu, remote: %8lu\n",
+ s->flush_free_list,
+ s->flush_free_list_objects,
+ s->flush_free_list_remote);
+ printf("FlushR:%8lu, objects %8lu\n",
+ s->flush_rfree_list,
+ s->flush_rfree_list_objects);
+}
+
+void report(struct slabinfo *s)
+{
+ if (strcmp(s->name, "*") == 0)
+ return;
+
+ printf("\nSlabcache: %-20s Order : %2d Objects: %lu\n",
+ s->name, s->order, s->objects);
+ if (s->hwcache_align)
+ printf("** Hardware cacheline aligned\n");
+ if (s->cache_dma)
+ printf("** Memory is allocated in a special DMA zone\n");
+ if (s->destroy_by_rcu)
+ printf("** Slabs are destroyed via RCU\n");
+ if (s->reclaim_account)
+ printf("** Reclaim accounting active\n");
+
+ printf("\nSizes (bytes) Slabs Debug Memory\n");
+ printf("------------------------------------------------------------------------\n");
+ printf("Object : %7d Total : %7ld Sanity Checks : %s Total: %7ld\n",
+ s->object_size, s->slabs, "N/A",
+ s->slabs * (page_size << s->order));
+ printf("SlabObj: %7d Full : %7s Redzoning : %s Used : %7ld\n",
+ s->slab_size, "N/A",
+ onoff(s->red_zone), s->objects * s->object_size);
+ printf("SlabSiz: %7d Partial: %7s Poisoning : %s Loss : %7ld\n",
+ page_size << s->order, "N/A", onoff(s->poison),
+ s->slabs * (page_size << s->order) - s->objects * s->object_size);
+ printf("Loss : %7d CpuSlab: %7s Tracking : %s Lalig: %7ld\n",
+ s->slab_size - s->object_size, "N/A", onoff(s->store_user),
+ (s->slab_size - s->object_size) * s->objects);
+ printf("Align : %7d Objects: %7d Tracing : %s Lpadd: %7ld\n",
+ s->align, s->objs_per_slab, "N/A",
+ ((page_size << s->order) - s->objs_per_slab * s->slab_size) *
+ s->slabs);
+
+ ops(s);
+ show_tracking(s);
+ slab_numa(s, 1);
+ slab_stats(s);
+}
+
+void slabcache(struct slabinfo *s)
+{
+ char size_str[20];
+ char flags[20];
+ char *p = flags;
+
+ if (strcmp(s->name, "*") == 0)
+ return;
+
+ if (actual_slabs == 1) {
+ report(s);
+ return;
+ }
+
+ if (skip_zero && !show_empty && !s->slabs)
+ return;
+
+ if (show_empty && s->slabs)
+ return;
+
+ store_size(size_str, slab_size(s));
+
+ if (!line++)
+ first_line();
+
+ if (s->cache_dma)
+ *p++ = 'd';
+ if (s->hwcache_align)
+ *p++ = 'A';
+ if (s->poison)
+ *p++ = 'P';
+ if (s->reclaim_account)
+ *p++ = 'a';
+ if (s->red_zone)
+ *p++ = 'Z';
+ if (s->store_user)
+ *p++ = 'U';
+
+ *p = 0;
+ if (show_activity) {
+ unsigned long total_alloc;
+ unsigned long total_free;
+
+ total_alloc = s->alloc;
+ total_free = s->free;
+
+ printf("%-21s %8ld %10ld %10ld %5ld %5ld %7ld %5d %7ld %8d\n",
+ s->name, s->objects,
+ total_alloc, total_free,
+ total_alloc ? (s->alloc_slab_fill * 100 / total_alloc) : 0,
+ total_alloc ? (s->alloc_slab_new * 100 / total_alloc) : 0,
+ s->flush_rfree_list,
+ s->flush_rfree_list * 100 / (total_alloc + total_free),
+ s->flush_rfree_list_objects,
+ s->order);
+ }
+ else
+ printf("%-21s %8ld %7d %8s %4d %1d %3ld %4ld %s\n",
+ s->name, s->objects, s->object_size, size_str,
+ s->objs_per_slab, s->order,
+ s->slabs ? (s->objects * s->object_size * 100) /
+ (s->slabs * (page_size << s->order)) : 100,
+ s->batch, flags);
+}
+
+/*
+ * Analyze debug options. Return false if something is amiss.
+ */
+int debug_opt_scan(char *opt)
+{
+ if (!opt || !opt[0] || strcmp(opt, "-") == 0)
+ return 1;
+
+ if (strcasecmp(opt, "a") == 0) {
+ sanity = 1;
+ poison = 1;
+ redzone = 1;
+ tracking = 1;
+ return 1;
+ }
+
+ for ( ; *opt; opt++)
+ switch (*opt) {
+ case 'F' : case 'f':
+ if (sanity)
+ return 0;
+ sanity = 1;
+ break;
+ case 'P' : case 'p':
+ if (poison)
+ return 0;
+ poison = 1;
+ break;
+
+ case 'Z' : case 'z':
+ if (redzone)
+ return 0;
+ redzone = 1;
+ break;
+
+ case 'U' : case 'u':
+ if (tracking)
+ return 0;
+ tracking = 1;
+ break;
+
+ case 'T' : case 't':
+ if (tracing)
+ return 0;
+ tracing = 1;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int slab_empty(struct slabinfo *s)
+{
+ if (s->objects > 0)
+ return 0;
+
+ /*
+ * We may still have slabs even if there are no objects. Shrinking will
+ * remove them.
+ */
+ if (s->slabs != 0)
+ set_obj(s, "shrink", 1);
+
+ return 1;
+}
+
+void slab_debug(struct slabinfo *s)
+{
+ if (strcmp(s->name, "*") == 0)
+ return;
+
+ if (redzone && !s->red_zone) {
+ if (slab_empty(s))
+ set_obj(s, "red_zone", 1);
+ else
+ fprintf(stderr, "%s not empty cannot enable redzoning\n", s->name);
+ }
+ if (!redzone && s->red_zone) {
+ if (slab_empty(s))
+ set_obj(s, "red_zone", 0);
+ else
+ fprintf(stderr, "%s not empty cannot disable redzoning\n", s->name);
+ }
+ if (poison && !s->poison) {
+ if (slab_empty(s))
+ set_obj(s, "poison", 1);
+ else
+ fprintf(stderr, "%s not empty cannot enable poisoning\n", s->name);
+ }
+ if (!poison && s->poison) {
+ if (slab_empty(s))
+ set_obj(s, "poison", 0);
+ else
+ fprintf(stderr, "%s not empty cannot disable poisoning\n", s->name);
+ }
+ if (tracking && !s->store_user) {
+ if (slab_empty(s))
+ set_obj(s, "store_user", 1);
+ else
+ fprintf(stderr, "%s not empty cannot enable tracking\n", s->name);
+ }
+ if (!tracking && s->store_user) {
+ if (slab_empty(s))
+ set_obj(s, "store_user", 0);
+ else
+ fprintf(stderr, "%s not empty cannot disable tracking\n", s->name);
+ }
+}
+
+void totals(void)
+{
+ struct slabinfo *s;
+
+ int used_slabs = 0;
+ char b1[20], b2[20], b3[20], b4[20];
+ unsigned long long max = 1ULL << 63;
+
+ /* Object size */
+ unsigned long long min_objsize = max, max_objsize = 0, avg_objsize;
+
+ /* Number of partial slabs in a slabcache */
+ unsigned long long min_partial = max, max_partial = 0,
+ avg_partial, total_partial = 0;
+
+ /* Number of slabs in a slab cache */
+ unsigned long long min_slabs = max, max_slabs = 0,
+ avg_slabs, total_slabs = 0;
+
+ /* Size of the whole slab */
+ unsigned long long min_size = max, max_size = 0,
+ avg_size, total_size = 0;
+
+ /* Bytes used for object storage in a slab */
+ unsigned long long min_used = max, max_used = 0,
+ avg_used, total_used = 0;
+
+ /* Waste: Bytes used for alignment and padding */
+ unsigned long long min_waste = max, max_waste = 0,
+ avg_waste, total_waste = 0;
+ /* Number of objects in a slab */
+ unsigned long long min_objects = max, max_objects = 0,
+ avg_objects, total_objects = 0;
+ /* Waste per object */
+ unsigned long long min_objwaste = max,
+ max_objwaste = 0, avg_objwaste,
+ total_objwaste = 0;
+
+ /* Memory per object */
+ unsigned long long min_memobj = max,
+ max_memobj = 0, avg_memobj,
+ total_objsize = 0;
+
+ for (s = slabinfo; s < slabinfo + slabs; s++) {
+ unsigned long long size;
+ unsigned long used;
+ unsigned long long wasted;
+ unsigned long long objwaste;
+
+ if (!s->slabs || !s->objects)
+ continue;
+
+ used_slabs++;
+
+ size = slab_size(s);
+ used = s->objects * s->object_size;
+ wasted = size - used;
+ objwaste = s->slab_size - s->object_size;
+
+ if (s->object_size < min_objsize)
+ min_objsize = s->object_size;
+ if (s->slabs < min_slabs)
+ min_slabs = s->slabs;
+ if (size < min_size)
+ min_size = size;
+ if (wasted < min_waste)
+ min_waste = wasted;
+ if (objwaste < min_objwaste)
+ min_objwaste = objwaste;
+ if (s->objects < min_objects)
+ min_objects = s->objects;
+ if (used < min_used)
+ min_used = used;
+ if (s->slab_size < min_memobj)
+ min_memobj = s->slab_size;
+
+ if (s->object_size > max_objsize)
+ max_objsize = s->object_size;
+ if (s->slabs > max_slabs)
+ max_slabs = s->slabs;
+ if (size > max_size)
+ max_size = size;
+ if (wasted > max_waste)
+ max_waste = wasted;
+ if (objwaste > max_objwaste)
+ max_objwaste = objwaste;
+ if (s->objects > max_objects)
+ max_objects = s->objects;
+ if (used > max_used)
+ max_used = used;
+ if (s->slab_size > max_memobj)
+ max_memobj = s->slab_size;
+
+ total_slabs += s->slabs;
+ total_size += size;
+ total_waste += wasted;
+
+ total_objects += s->objects;
+ total_used += used;
+
+ total_objwaste += s->objects * objwaste;
+ total_objsize += s->objects * s->slab_size;
+ }
+
+ if (!total_objects) {
+ printf("No objects\n");
+ return;
+ }
+ if (!used_slabs) {
+ printf("No slabs\n");
+ return;
+ }
+
+ /* Per slab averages */
+ avg_slabs = total_slabs / used_slabs;
+ avg_size = total_size / used_slabs;
+ avg_waste = total_waste / used_slabs;
+
+ avg_objects = total_objects / used_slabs;
+ avg_used = total_used / used_slabs;
+
+ /* Per object object sizes */
+ avg_objsize = total_used / total_objects;
+ avg_objwaste = total_objwaste / total_objects;
+ avg_memobj = total_objsize / total_objects;
+
+ printf("Slabcache Totals\n");
+ printf("----------------\n");
+ printf("Slabcaches : %3d Active: %3d\n",
+ slabs, used_slabs);
+
+ store_size(b1, total_size);store_size(b2, total_waste);
+ store_size(b3, total_waste * 100 / total_used);
+ printf("Memory used: %6s # Loss : %6s MRatio:%6s%%\n", b1, b2, b3);
+
+ store_size(b1, total_objects);
+ printf("# Objects : %6s\n", b1);
+
+ printf("\n");
+ printf("Per Cache Average Min Max Total\n");
+ printf("---------------------------------------------------------\n");
+
+ store_size(b1, avg_objects);store_size(b2, min_objects);
+ store_size(b3, max_objects);store_size(b4, total_objects);
+ printf("#Objects %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_slabs);store_size(b2, min_slabs);
+ store_size(b3, max_slabs);store_size(b4, total_slabs);
+ printf("#Slabs %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_size);store_size(b2, min_size);
+ store_size(b3, max_size);store_size(b4, total_size);
+ printf("Memory %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_used);store_size(b2, min_used);
+ store_size(b3, max_used);store_size(b4, total_used);
+ printf("Used %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_waste);store_size(b2, min_waste);
+ store_size(b3, max_waste);store_size(b4, total_waste);
+ printf("Loss %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ printf("\n");
+ printf("Per Object Average Min Max\n");
+ printf("---------------------------------------------\n");
+
+ store_size(b1, avg_memobj);store_size(b2, min_memobj);
+ store_size(b3, max_memobj);
+ printf("Memory %10s %10s %10s\n",
+ b1, b2, b3);
+ store_size(b1, avg_objsize);store_size(b2, min_objsize);
+ store_size(b3, max_objsize);
+ printf("User %10s %10s %10s\n",
+ b1, b2, b3);
+
+ store_size(b1, avg_objwaste);store_size(b2, min_objwaste);
+ store_size(b3, max_objwaste);
+ printf("Loss %10s %10s %10s\n",
+ b1, b2, b3);
+}
+
+void sort_slabs(void)
+{
+ struct slabinfo *s1,*s2;
+
+ for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) {
+ for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) {
+ int result;
+
+ if (sort_size)
+ result = slab_size(s1) < slab_size(s2);
+ else if (sort_active)
+ result = slab_activity(s1) < slab_activity(s2);
+ else
+ result = strcasecmp(s1->name, s2->name);
+
+ if (show_inverted)
+ result = -result;
+
+ if (result > 0) {
+ struct slabinfo t;
+
+ memcpy(&t, s1, sizeof(struct slabinfo));
+ memcpy(s1, s2, sizeof(struct slabinfo));
+ memcpy(s2, &t, sizeof(struct slabinfo));
+ }
+ }
+ }
+}
+
+int slab_mismatch(char *slab)
+{
+ return regexec(&pattern, slab, 0, NULL, 0);
+}
+
+void read_slab_dir(void)
+{
+ DIR *dir;
+ struct dirent *de;
+ struct slabinfo *slab = slabinfo;
+ char *p;
+ char *t;
+ int count;
+
+ if (chdir("/sys/kernel/slab") && chdir("/sys/slab"))
+ fatal("SYSFS support for SLUB not active\n");
+
+ dir = opendir(".");
+ while ((de = readdir(dir))) {
+ if (de->d_name[0] == '.' ||
+ (de->d_name[0] != ':' && slab_mismatch(de->d_name)))
+ continue;
+ switch (de->d_type) {
+ case DT_DIR:
+ if (chdir(de->d_name))
+ fatal("Unable to access slab %s\n", slab->name);
+ slab->name = strdup(de->d_name);
+ slab->align = get_obj("align");
+ slab->cache_dma = get_obj("cache_dma");
+ slab->destroy_by_rcu = get_obj("destroy_by_rcu");
+ slab->hwcache_align = get_obj("hwcache_align");
+ slab->object_size = get_obj("object_size");
+ slab->objects = get_obj("objects");
+ slab->total_objects = get_obj("total_objects");
+ slab->objs_per_slab = get_obj("objs_per_slab");
+ slab->order = get_obj("order");
+ slab->poison = get_obj("poison");
+ slab->reclaim_account = get_obj("reclaim_account");
+ slab->red_zone = get_obj("red_zone");
+ 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->batch = get_obj("batch");
+ slab->alloc = get_obj("alloc");
+ slab->alloc_slab_fill = get_obj("alloc_slab_fill");
+ slab->alloc_slab_new = get_obj("alloc_slab_new");
+ slab->free = get_obj("free");
+ slab->free_remote = get_obj("free_remote");
+ slab->claim_remote_list = get_obj("claim_remote_list");
+ slab->claim_remote_list_objects = get_obj("claim_remote_list_objects");
+ slab->flush_free_list = get_obj("flush_free_list");
+ slab->flush_free_list_objects = get_obj("flush_free_list_objects");
+ slab->flush_free_list_remote = get_obj("flush_free_list_remote");
+ slab->flush_rfree_list = get_obj("flush_rfree_list");
+ slab->flush_rfree_list_objects = get_obj("flush_rfree_list_objects");
+ slab->flush_slab_free = get_obj("flush_slab_free");
+ slab->flush_slab_partial = get_obj("flush_slab_partial");
+
+ chdir("..");
+ slab++;
+ break;
+ default :
+ fatal("Unknown file type %lx\n", de->d_type);
+ }
+ }
+ closedir(dir);
+ slabs = slab - slabinfo;
+ actual_slabs = slabs;
+ if (slabs > MAX_SLABS)
+ fatal("Too many slabs\n");
+}
+
+void output_slabs(void)
+{
+ struct slabinfo *slab;
+
+ for (slab = slabinfo; slab < slabinfo + slabs; slab++) {
+
+ if (show_numa)
+ slab_numa(slab, 0);
+ else if (show_track)
+ show_tracking(slab);
+ else if (validate)
+ slab_validate(slab);
+ else if (shrink)
+ slab_shrink(slab);
+ else if (set_debug)
+ slab_debug(slab);
+ else if (show_ops)
+ ops(slab);
+ else if (show_slab)
+ slabcache(slab);
+ else if (show_report)
+ report(slab);
+ }
+}
+
+struct option opts[] = {
+ { "activity", 0, NULL, 'A' },
+ { "debug", 2, NULL, 'd' },
+ { "display-activity", 0, NULL, 'D' },
+ { "empty", 0, NULL, 'e' },
+ { "help", 0, NULL, 'h' },
+ { "inverted", 0, NULL, 'i'},
+ { "numa", 0, NULL, 'n' },
+ { "ops", 0, NULL, 'o' },
+ { "report", 0, NULL, 'r' },
+ { "shrink", 0, NULL, 's' },
+ { "slabs", 0, NULL, 'l' },
+ { "track", 0, NULL, 't'},
+ { "validate", 0, NULL, 'v' },
+ { "zero", 0, NULL, 'z' },
+ { "1ref", 0, NULL, '1'},
+ { NULL, 0, NULL, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+ int c;
+ int err;
+ char *pattern_source;
+
+ page_size = getpagesize();
+
+ while ((c = getopt_long(argc, argv, "Ad::Dehil1noprstvzTS",
+ opts, NULL)) != -1)
+ switch (c) {
+ case 'A':
+ sort_active = 1;
+ break;
+ case 'd':
+ set_debug = 1;
+ if (!debug_opt_scan(optarg))
+ fatal("Invalid debug option '%s'\n", optarg);
+ break;
+ case 'D':
+ show_activity = 1;
+ break;
+ case 'e':
+ show_empty = 1;
+ break;
+ case 'h':
+ usage();
+ return 0;
+ case 'i':
+ show_inverted = 1;
+ break;
+ case 'n':
+ show_numa = 1;
+ break;
+ case 'o':
+ show_ops = 1;
+ break;
+ case 'r':
+ show_report = 1;
+ break;
+ case 's':
+ shrink = 1;
+ break;
+ case 'l':
+ show_slab = 1;
+ break;
+ case 't':
+ show_track = 1;
+ break;
+ case 'v':
+ validate = 1;
+ break;
+ case 'z':
+ skip_zero = 0;
+ break;
+ case 'T':
+ show_totals = 1;
+ break;
+ case 'S':
+ sort_size = 1;
+ break;
+
+ default:
+ fatal("%s: Invalid option '%c'\n", argv[0], optopt);
+
+ }
+
+ if (!show_slab && !show_track && !show_report
+ && !validate && !shrink && !set_debug && !show_ops)
+ show_slab = 1;
+
+ if (argc > optind)
+ pattern_source = argv[optind];
+ else
+ pattern_source = ".*";
+
+ err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB);
+ if (err)
+ fatal("%s: Invalid pattern '%s' code %d\n",
+ argv[0], pattern_source, err);
+ read_slab_dir();
+ if (show_totals)
+ totals();
+ else {
+ sort_slabs();
+ output_slabs();
+ }
+ return 0;
+}
diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 29b52b14d0b4..d6498e3cd713 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -6,10 +6,11 @@ Virtual memory map with 4 level page tables:
0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
hole caused by [48:63] sign extension
ffff800000000000 - ffff80ffffffffff (=40 bits) guard hole
-ffff880000000000 - ffffc0ffffffffff (=57 TB) 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)
+ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
+ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole
+ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
+ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
+ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
... unused hole ...
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
ffffffffa0000000 - fffffffffff00000 (=1536 MB) module mapping space
diff --git a/MAINTAINERS b/MAINTAINERS
index 2b349ba4add4..ba98ad137c18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -937,6 +937,12 @@ P: Luis R. Rodriguez
M: lrodriguez@atheros.com
P: Jouni Malinen
M: jmalinen@atheros.com
+P: Sujith Manoharan
+M: Sujith.Manoharan@atheros.com
+P: Vasanthakumar Thiagarajan
+M: vasanth@atheros.com
+P: Senthil Balasubramanian
+M: senthilkumar@atheros.com
L: linux-wireless@vger.kernel.org
L: ath9k-devel@lists.ath9k.org
S: Supported
@@ -4182,6 +4188,11 @@ F: arch/*/oprofile/
F: drivers/oprofile/
F: include/linux/oprofile.h
+OQO WMI EXTRAS DRIVER
+P: Matthew Garrett
+M: mjg59@srcf.ucam.org
+S: Maintained
+
ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
P: Mark Fasheh
M: mfasheh@suse.com
@@ -4492,8 +4503,8 @@ S: Maintained
F: drivers/ata/sata_promise.*
PS3 NETWORK SUPPORT
-P: Masakazu Mokuno
-M: mokuno@sm.sony.co.jp
+P: Geoff Levand
+M: geoffrey.levand@am.sony.com
L: netdev@vger.kernel.org
L: cbe-oss-dev@ozlabs.org
S: Supported
@@ -4557,7 +4568,8 @@ F: drivers/pcmcia/pxa2xx*
F: drivers/spi/pxa2xx*
F: drivers/usb/gadget/pxa2*
F: include/sound/pxa2xx-lib.h
-F: sound/soc/pxa/pxa2xx*
+F: sound/arm/pxa*
+F: sound/soc/pxa
PXA168 SUPPORT
P: Eric Miao
@@ -4693,7 +4705,7 @@ F: drivers/net/r6040.c
RDS - RELIABLE DATAGRAM SOCKETS
P: Andy Grover
M: andy.grover@oracle.com
-L: rds-devel@oss.oracle.com
+L: rds-devel@oss.oracle.com (moderated for non-subscribers)
S: Supported
F: net/rds/
@@ -5290,6 +5302,7 @@ L: alsa-devel@alsa-project.org (subscribers-only)
W: http://alsa-project.org/main/index.php/ASoC
S: Supported
F: sound/soc/
+F: include/sound/soc*
SPARC + UltraSPARC (sparc/sparc64)
P: David S. Miller
diff --git a/Makefile b/Makefile
index b18afad2e100..9b2b58c3b3db 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 30
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
NAME = Vindictive Armadillo
# *DOCUMENTATION*
diff --git a/arch/alpha/include/asm/percpu.h b/arch/alpha/include/asm/percpu.h
index e9e0bb5a23bf..06c5c7a4afd3 100644
--- a/arch/alpha/include/asm/percpu.h
+++ b/arch/alpha/include/asm/percpu.h
@@ -1,7 +1,9 @@
#ifndef __ALPHA_PERCPU_H
#define __ALPHA_PERCPU_H
+
#include <linux/compiler.h>
#include <linux/threads.h>
+#include <linux/percpu-defs.h>
/*
* Determine the real variable name from the name visible in the
@@ -73,6 +75,28 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
#endif /* SMP */
-#include <asm-generic/percpu.h>
+#ifdef CONFIG_SMP
+#define PER_CPU_BASE_SECTION ".data.percpu"
+#else
+#define PER_CPU_BASE_SECTION ".data"
+#endif
+
+#ifdef CONFIG_SMP
+
+#ifdef MODULE
+#define PER_CPU_SHARED_ALIGNED_SECTION ""
+#else
+#define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned"
+#endif
+#define PER_CPU_FIRST_SECTION ".first"
+
+#else
+
+#define PER_CPU_SHARED_ALIGNED_SECTION ""
+#define PER_CPU_FIRST_SECTION ""
+
+#endif
+
+#define PER_CPU_ATTRIBUTES
#endif /* __ALPHA_PERCPU_H */
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 42ee05981e71..9a3334ae282e 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -371,8 +371,6 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
int retval = -EINVAL;
char *name;
- lock_kernel();
-
name = getname(path);
retval = PTR_ERR(name);
if (IS_ERR(name))
@@ -392,7 +390,6 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
}
putname(name);
out:
- unlock_kernel();
return retval;
}
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index 9c9d1fd4155f..5bd5259324b7 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -176,22 +176,26 @@ cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
}
}
-static void
+static int
dp264_set_affinity(unsigned int irq, const struct cpumask *affinity)
{
spin_lock(&dp264_irq_lock);
cpu_set_irq_affinity(irq, *affinity);
tsunami_update_irq_hw(cached_irq_mask);
spin_unlock(&dp264_irq_lock);
+
+ return 0;
}
-static void
+static int
clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
{
spin_lock(&dp264_irq_lock);
cpu_set_irq_affinity(irq - 16, *affinity);
tsunami_update_irq_hw(cached_irq_mask);
spin_unlock(&dp264_irq_lock);
+
+ return 0;
}
static struct hw_interrupt_type dp264_irq_type = {
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 27f840a4ad3d..8dd239ebdb9e 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -157,13 +157,15 @@ titan_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
}
-static void
+static int
titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
{
spin_lock(&titan_irq_lock);
titan_cpu_set_irq_affinity(irq - 16, *affinity);
titan_update_irq_hw(titan_cached_irq_mask);
spin_unlock(&titan_irq_lock);
+
+ return 0;
}
static void
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9faccc411c2a..5b1434bbd5d7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -253,6 +253,14 @@ config ARCH_CLPS711X
help
Support for Cirrus Logic 711x/721x based boards.
+config ARCH_GEMINI
+ bool "Cortina Systems Gemini"
+ select CPU_FA526
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for the Cortina Systems Gemini family SoCs
+
config ARCH_EBSA110
bool "EBSA-110"
select CPU_SA110
@@ -276,14 +284,6 @@ config ARCH_EP93XX
help
This enables support for the Cirrus EP93xx series of CPUs.
-config ARCH_GEMINI
- bool "Cortina Systems Gemini"
- select CPU_FA526
- select GENERIC_GPIO
- select ARCH_REQUIRE_GPIOLIB
- help
- Support for the Cortina Systems Gemini family SoCs
-
config ARCH_FOOTBRIDGE
bool "FootBridge"
select CPU_SA110
@@ -292,6 +292,30 @@ config ARCH_FOOTBRIDGE
Support for systems based on the DC21285 companion chip
("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
+config ARCH_MXC
+ bool "Freescale MXC/iMX-based"
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select ARCH_MTD_XIP
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ select HAVE_CLK
+ help
+ Support for Freescale MXC/iMX-based family of processors
+
+config ARCH_STMP3XXX
+ bool "Freescale STMP3xxx"
+ select CPU_ARM926T
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_GPIO
+ select USB_ARCH_HAS_EHCI
+ help
+ Support for systems based on the Freescale 3xxx CPUs.
+
config ARCH_NETX
bool "Hilscher NetX based"
select CPU_ARM926T
@@ -404,28 +428,6 @@ config ARCH_KIRKWOOD
Support for the following Marvell Kirkwood series SoCs:
88F6180, 88F6192 and 88F6281.
-config ARCH_KS8695
- bool "Micrel/Kendin KS8695"
- select CPU_ARM922T
- select GENERIC_GPIO
- select ARCH_REQUIRE_GPIOLIB
- help
- Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
- System-on-Chip devices.
-
-config ARCH_NS9XXX
- bool "NetSilicon NS9xxx"
- select CPU_ARM926T
- select GENERIC_GPIO
- select GENERIC_TIME
- select GENERIC_CLOCKEVENTS
- select HAVE_CLK
- help
- Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
- System.
-
- <http://www.digi.com/products/microprocessors/index.jsp>
-
config ARCH_LOKI
bool "Marvell Loki (88RC8480)"
select CPU_FEROCEON
@@ -447,16 +449,6 @@ config ARCH_MV78XX0
Support for the following Marvell MV78xx0 series SoCs:
MV781x0, MV782x0.
-config ARCH_MXC
- bool "Freescale MXC/iMX-based"
- select GENERIC_TIME
- select GENERIC_CLOCKEVENTS
- select ARCH_MTD_XIP
- select GENERIC_GPIO
- select ARCH_REQUIRE_GPIOLIB
- help
- Support for Freescale MXC/iMX-based family of processors
-
config ARCH_ORION5X
bool "Marvell Orion"
depends on MMU
@@ -471,6 +463,49 @@ config ARCH_ORION5X
Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
Orion-2 (5281), Orion-1-90 (6183).
+config ARCH_MMP
+ bool "Marvell PXA168/910"
+ depends on MMU
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select TICK_ONESHOT
+ select PLAT_PXA
+ help
+ Support for Marvell's PXA168/910 processor line.
+
+config ARCH_KS8695
+ bool "Micrel/Kendin KS8695"
+ select CPU_ARM922T
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
+ System-on-Chip devices.
+
+config ARCH_NS9XXX
+ bool "NetSilicon NS9xxx"
+ select CPU_ARM926T
+ select GENERIC_GPIO
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select HAVE_CLK
+ help
+ Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
+ System.
+
+ <http://www.digi.com/products/microprocessors/index.jsp>
+
+config ARCH_W90X900
+ bool "Nuvoton W90X900 CPU"
+ select CPU_ARM926T
+ help
+ Support for Nuvoton (Winbond logic dept.) ARM9 processor,You
+ can login www.mcuos.com or www.nuvoton.com to know more.
+
config ARCH_PNX4008
bool "Philips Nexperia PNX4008 Mobile"
select CPU_ARM926T
@@ -493,19 +528,16 @@ config ARCH_PXA
help
Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
-config ARCH_MMP
- bool "Marvell PXA168/910"
- depends on MMU
- select GENERIC_GPIO
- select ARCH_REQUIRE_GPIOLIB
- select HAVE_CLK
- select COMMON_CLKDEV
+config ARCH_MSM
+ bool "Qualcomm MSM"
+ select CPU_V6
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
- select TICK_ONESHOT
- select PLAT_PXA
help
- Support for Marvell's PXA168/910 processor line.
+ Support for Qualcomm MSM7K based systems. This runs on the ARM11
+ apps processor of the MSM7K and depends on a shared memory
+ interface to the ARM9 modem processor which runs the baseband stack
+ and controls some vital subsystems (clock and power control, etc).
config ARCH_RPC
bool "RiscPC"
@@ -574,6 +606,20 @@ config ARCH_LH7A40X
core with a wide array of integrated devices for
hand-held and low-power applications.
+config ARCH_U300
+ bool "ST-Ericsson U300 Series"
+ depends on MMU
+ select CPU_ARM926T
+ select ARM_AMBA
+ select ARM_VIC
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select GENERIC_GPIO
+ help
+ Support for ST-Ericsson U300 series mobile platforms.
+
config ARCH_DAVINCI
bool "TI DaVinci"
select CPU_ARM926T
@@ -598,24 +644,6 @@ config ARCH_OMAP
help
Support for TI's OMAP platform (OMAP1 and OMAP2).
-config ARCH_MSM
- bool "Qualcomm MSM"
- select CPU_V6
- select GENERIC_TIME
- select GENERIC_CLOCKEVENTS
- help
- Support for Qualcomm MSM7K based systems. This runs on the ARM11
- apps processor of the MSM7K and depends on a shared memory
- interface to the ARM9 modem processor which runs the baseband stack
- and controls some vital subsystems (clock and power control, etc).
-
-config ARCH_W90X900
- bool "Nuvoton W90X900 CPU"
- select CPU_ARM926T
- help
- Support for Nuvoton (Winbond logic dept.) ARM9 processor,You
- can login www.mcuos.com or www.nuvoton.com to know more.
-
endchoice
source "arch/arm/mach-clps711x/Kconfig"
@@ -679,6 +707,8 @@ source "arch/arm/mach-s3c6400/Kconfig"
source "arch/arm/mach-s3c6410/Kconfig"
endif
+source "arch/arm/plat-stmp3xxx/Kconfig"
+
source "arch/arm/mach-lh7a40x/Kconfig"
source "arch/arm/mach-imx/Kconfig"
@@ -705,6 +735,8 @@ source "arch/arm/mach-ks8695/Kconfig"
source "arch/arm/mach-msm/Kconfig"
+source "arch/arm/mach-u300/Kconfig"
+
source "arch/arm/mach-w90x900/Kconfig"
# Definitions to make life easier
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index e84729bf13d4..a4f86e3d4cf0 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -99,64 +99,73 @@ CHECKFLAGS += -D__arm__
#Default value
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
textofs-y := 0x00008000
-
- machine-$(CONFIG_ARCH_RPC) := rpc
- machine-$(CONFIG_ARCH_EBSA110) := ebsa110
- machine-$(CONFIG_FOOTBRIDGE) := footbridge
- machine-$(CONFIG_ARCH_SHARK) := shark
- machine-$(CONFIG_ARCH_SA1100) := sa1100
-ifeq ($(CONFIG_ARCH_SA1100),y)
+textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
- textofs-$(CONFIG_SA1111) := 0x00208000
+ifeq ($(CONFIG_ARCH_SA1100),y)
+textofs-$(CONFIG_SA1111) := 0x00208000
endif
- machine-$(CONFIG_ARCH_PXA) := pxa
- machine-$(CONFIG_ARCH_MMP) := mmp
- plat-$(CONFIG_PLAT_PXA) := pxa
- machine-$(CONFIG_ARCH_L7200) := l7200
- machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
- machine-$(CONFIG_ARCH_GEMINI) := gemini
- textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
- machine-$(CONFIG_ARCH_CLPS711X) := clps711x
- machine-$(CONFIG_ARCH_IOP32X) := iop32x
- machine-$(CONFIG_ARCH_IOP33X) := iop33x
- machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
- plat-$(CONFIG_PLAT_IOP) := iop
- machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
- machine-$(CONFIG_ARCH_IXP2000) := ixp2000
- machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
- machine-$(CONFIG_ARCH_OMAP1) := omap1
- machine-$(CONFIG_ARCH_OMAP2) := omap2
- machine-$(CONFIG_ARCH_OMAP3) := omap2
- plat-$(CONFIG_ARCH_OMAP) := omap
- machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
- machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
- plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c
- machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410
- plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c
- machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
- machine-$(CONFIG_ARCH_VERSATILE) := versatile
- machine-$(CONFIG_ARCH_IMX) := imx
- machine-$(CONFIG_ARCH_H720X) := h720x
- machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
- machine-$(CONFIG_ARCH_REALVIEW) := realview
- machine-$(CONFIG_ARCH_AT91) := at91
- machine-$(CONFIG_ARCH_EP93XX) := ep93xx
- machine-$(CONFIG_ARCH_PNX4008) := pnx4008
- machine-$(CONFIG_ARCH_NETX) := netx
- machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
- machine-$(CONFIG_ARCH_DAVINCI) := davinci
- machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
- machine-$(CONFIG_ARCH_KS8695) := ks8695
- plat-$(CONFIG_ARCH_MXC) := mxc
- machine-$(CONFIG_ARCH_MX2) := mx2
- machine-$(CONFIG_ARCH_MX3) := mx3
- machine-$(CONFIG_ARCH_MX1) := mx1
- machine-$(CONFIG_ARCH_ORION5X) := orion5x
- plat-$(CONFIG_PLAT_ORION) := orion
- machine-$(CONFIG_ARCH_MSM) := msm
- machine-$(CONFIG_ARCH_LOKI) := loki
- machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
- machine-$(CONFIG_ARCH_W90X900) := w90x900
+
+# Machine directory name. This list is sorted alphanumerically
+# by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
+machine-$(CONFIG_ARCH_AT91) := at91
+machine-$(CONFIG_ARCH_CLPS711X) := clps711x
+machine-$(CONFIG_ARCH_DAVINCI) := davinci
+machine-$(CONFIG_ARCH_EBSA110) := ebsa110
+machine-$(CONFIG_ARCH_EP93XX) := ep93xx
+machine-$(CONFIG_ARCH_GEMINI) := gemini
+machine-$(CONFIG_ARCH_H720X) := h720x
+machine-$(CONFIG_ARCH_IMX) := imx
+machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
+machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
+machine-$(CONFIG_ARCH_IOP32X) := iop32x
+machine-$(CONFIG_ARCH_IOP33X) := iop33x
+machine-$(CONFIG_ARCH_IXP2000) := ixp2000
+machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
+machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
+machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
+machine-$(CONFIG_ARCH_KS8695) := ks8695
+machine-$(CONFIG_ARCH_L7200) := l7200
+machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
+machine-$(CONFIG_ARCH_LOKI) := loki
+machine-$(CONFIG_ARCH_MMP) := mmp
+machine-$(CONFIG_ARCH_MSM) := msm
+machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
+machine-$(CONFIG_ARCH_MX1) := mx1
+machine-$(CONFIG_ARCH_MX2) := mx2
+machine-$(CONFIG_ARCH_MX3) := mx3
+machine-$(CONFIG_ARCH_NETX) := netx
+machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
+machine-$(CONFIG_ARCH_OMAP1) := omap1
+machine-$(CONFIG_ARCH_OMAP2) := omap2
+machine-$(CONFIG_ARCH_OMAP3) := omap2
+machine-$(CONFIG_ARCH_ORION5X) := orion5x
+machine-$(CONFIG_ARCH_PNX4008) := pnx4008
+machine-$(CONFIG_ARCH_PXA) := pxa
+machine-$(CONFIG_ARCH_REALVIEW) := realview
+machine-$(CONFIG_ARCH_RPC) := rpc
+machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
+machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
+machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410
+machine-$(CONFIG_ARCH_SA1100) := sa1100
+machine-$(CONFIG_ARCH_SHARK) := shark
+machine-$(CONFIG_ARCH_STMP378X) := stmp378x
+machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
+machine-$(CONFIG_ARCH_U300) := u300
+machine-$(CONFIG_ARCH_VERSATILE) := versatile
+machine-$(CONFIG_ARCH_W90X900) := w90x900
+machine-$(CONFIG_FOOTBRIDGE) := footbridge
+
+# Platform directory name. This list is sorted alphanumerically
+# by CONFIG_* macro name.
+plat-$(CONFIG_ARCH_MXC) := mxc
+plat-$(CONFIG_ARCH_OMAP) := omap
+plat-$(CONFIG_PLAT_IOP) := iop
+plat-$(CONFIG_PLAT_ORION) := orion
+plat-$(CONFIG_PLAT_PXA) := pxa
+plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c
+plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c
+plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx
ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index a2cd9beaf37d..38518d450bc0 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -4,6 +4,13 @@ config ARM_GIC
config ARM_VIC
bool
+config ARM_VIC_NR
+ int
+ default 2
+ help
+ The maximum number of VICs available in the system, for
+ power management.
+
config ICST525
bool
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index c6884ba1d5ed..90f6b7f52d48 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -109,7 +109,7 @@ static void gic_unmask_irq(unsigned int irq)
}
#ifdef CONFIG_SMP
-static void gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
+static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
{
void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);
unsigned int shift = (irq % 4) * 8;
@@ -122,6 +122,8 @@ static void gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
val |= 1 << (cpu + shift);
writel(val, reg);
spin_unlock(&irq_controller_lock);
+
+ return 0;
}
#endif
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index b2a781d9ce05..887c6eb3a18a 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/io.h>
+#include <linux/sysdev.h>
#include <asm/mach/irq.h>
#include <asm/hardware/vic.h>
@@ -39,11 +40,219 @@ static void vic_unmask_irq(unsigned int irq)
writel(1 << irq, base + VIC_INT_ENABLE);
}
+/**
+ * vic_init2 - common initialisation code
+ * @base: Base of the VIC.
+ *
+ * Common initialisation code for registeration
+ * and resume.
+*/
+static void vic_init2(void __iomem *base)
+{
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
+ writel(VIC_VECT_CNTL_ENABLE | i, reg);
+ }
+
+ writel(32, base + VIC_PL190_DEF_VECT_ADDR);
+}
+
+#if defined(CONFIG_PM)
+/**
+ * struct vic_device - VIC PM device
+ * @sysdev: The system device which is registered.
+ * @irq: The IRQ number for the base of the VIC.
+ * @base: The register base for the VIC.
+ * @resume_sources: A bitmask of interrupts for resume.
+ * @resume_irqs: The IRQs enabled for resume.
+ * @int_select: Save for VIC_INT_SELECT.
+ * @int_enable: Save for VIC_INT_ENABLE.
+ * @soft_int: Save for VIC_INT_SOFT.
+ * @protect: Save for VIC_PROTECT.
+ */
+struct vic_device {
+ struct sys_device sysdev;
+
+ void __iomem *base;
+ int irq;
+ u32 resume_sources;
+ u32 resume_irqs;
+ u32 int_select;
+ u32 int_enable;
+ u32 soft_int;
+ u32 protect;
+};
+
+/* we cannot allocate memory when VICs are initially registered */
+static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
+
+static inline struct vic_device *to_vic(struct sys_device *sys)
+{
+ return container_of(sys, struct vic_device, sysdev);
+}
+
+static int vic_id;
+
+static int vic_class_resume(struct sys_device *dev)
+{
+ struct vic_device *vic = to_vic(dev);
+ void __iomem *base = vic->base;
+
+ printk(KERN_DEBUG "%s: resuming vic at %p\n", __func__, base);
+
+ /* re-initialise static settings */
+ vic_init2(base);
+
+ writel(vic->int_select, base + VIC_INT_SELECT);
+ writel(vic->protect, base + VIC_PROTECT);
+
+ /* set the enabled ints and then clear the non-enabled */
+ writel(vic->int_enable, base + VIC_INT_ENABLE);
+ writel(~vic->int_enable, base + VIC_INT_ENABLE_CLEAR);
+
+ /* and the same for the soft-int register */
+
+ writel(vic->soft_int, base + VIC_INT_SOFT);
+ writel(~vic->soft_int, base + VIC_INT_SOFT_CLEAR);
+
+ return 0;
+}
+
+static int vic_class_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct vic_device *vic = to_vic(dev);
+ void __iomem *base = vic->base;
+
+ printk(KERN_DEBUG "%s: suspending vic at %p\n", __func__, base);
+
+ vic->int_select = readl(base + VIC_INT_SELECT);
+ vic->int_enable = readl(base + VIC_INT_ENABLE);
+ vic->soft_int = readl(base + VIC_INT_SOFT);
+ vic->protect = readl(base + VIC_PROTECT);
+
+ /* set the interrupts (if any) that are used for
+ * resuming the system */
+
+ writel(vic->resume_irqs, base + VIC_INT_ENABLE);
+ writel(~vic->resume_irqs, base + VIC_INT_ENABLE_CLEAR);
+
+ return 0;
+}
+
+struct sysdev_class vic_class = {
+ .name = "vic",
+ .suspend = vic_class_suspend,
+ .resume = vic_class_resume,
+};
+
+/**
+ * vic_pm_register - Register a VIC for later power management control
+ * @base: The base address of the VIC.
+ * @irq: The base IRQ for the VIC.
+ * @resume_sources: bitmask of interrupts allowed for resume sources.
+ *
+ * Register the VIC with the system device tree so that it can be notified
+ * of suspend and resume requests and ensure that the correct actions are
+ * taken to re-instate the settings on resume.
+ */
+static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
+{
+ struct vic_device *v;
+
+ if (vic_id >= ARRAY_SIZE(vic_devices))
+ printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
+ else {
+ v = &vic_devices[vic_id];
+ v->base = base;
+ v->resume_sources = resume_sources;
+ v->irq = irq;
+ vic_id++;
+ }
+}
+
+/**
+ * vic_pm_init - initicall to register VIC pm
+ *
+ * This is called via late_initcall() to register
+ * the resources for the VICs due to the early
+ * nature of the VIC's registration.
+*/
+static int __init vic_pm_init(void)
+{
+ struct vic_device *dev = vic_devices;
+ int err;
+ int id;
+
+ if (vic_id == 0)
+ return 0;
+
+ err = sysdev_class_register(&vic_class);
+ if (err) {
+ printk(KERN_ERR "%s: cannot register class\n", __func__);
+ return err;
+ }
+
+ for (id = 0; id < vic_id; id++, dev++) {
+ dev->sysdev.id = id;
+ dev->sysdev.cls = &vic_class;
+
+ err = sysdev_register(&dev->sysdev);
+ if (err) {
+ printk(KERN_ERR "%s: failed to register device\n",
+ __func__);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+late_initcall(vic_pm_init);
+
+static struct vic_device *vic_from_irq(unsigned int irq)
+{
+ struct vic_device *v = vic_devices;
+ unsigned int base_irq = irq & ~31;
+ int id;
+
+ for (id = 0; id < vic_id; id++, v++) {
+ if (v->irq == base_irq)
+ return v;
+ }
+
+ return NULL;
+}
+
+static int vic_set_wake(unsigned int irq, unsigned int on)
+{
+ struct vic_device *v = vic_from_irq(irq);
+ unsigned int off = irq & 31;
+
+ if (!v)
+ return -EINVAL;
+
+ if (on)
+ v->resume_irqs |= 1 << off;
+ else
+ v->resume_irqs &= ~(1 << off);
+
+ return 0;
+}
+
+#else
+static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
+
+#define vic_set_wake NULL
+#endif /* CONFIG_PM */
+
static struct irq_chip vic_chip = {
.name = "VIC",
.ack = vic_mask_irq,
.mask = vic_mask_irq,
.unmask = vic_unmask_irq,
+ .set_wake = vic_set_wake,
};
/**
@@ -51,9 +260,10 @@ static struct irq_chip vic_chip = {
* @base: iomem base address
* @irq_start: starting interrupt number, must be muliple of 32
* @vic_sources: bitmask of interrupt sources to allow
+ * @resume_sources: bitmask of interrupt sources to allow for resume
*/
void __init vic_init(void __iomem *base, unsigned int irq_start,
- u32 vic_sources)
+ u32 vic_sources, u32 resume_sources)
{
unsigned int i;
@@ -77,12 +287,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
writel(value, base + VIC_PL190_VECT_ADDR);
}
- for (i = 0; i < 16; i++) {
- void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
- writel(VIC_VECT_CNTL_ENABLE | i, reg);
- }
-
- writel(32, base + VIC_PL190_DEF_VECT_ADDR);
+ vic_init2(base);
for (i = 0; i < 32; i++) {
if (vic_sources & (1 << i)) {
@@ -94,4 +299,6 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
+
+ vic_pm_register(base, irq_start, resume_sources);
}
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig
index c367ae44012e..dcf8153a947d 100644
--- a/arch/arm/configs/kirkwood_defconfig
+++ b/arch/arm/configs/kirkwood_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc5
-# Tue Mar 3 21:45:57 2009
+# Linux kernel version: 2.6.30-rc4
+# Mon May 4 11:58:57 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -66,20 +66,20 @@ CONFIG_NAMESPACES=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -89,6 +89,7 @@ CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -101,6 +102,7 @@ CONFIG_KPROBES=y
CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -113,7 +115,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -142,6 +143,7 @@ CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
@@ -162,6 +164,7 @@ CONFIG_ARCH_KIRKWOOD=y
# CONFIG_ARCH_ORION5X is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MMP is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
@@ -217,6 +220,7 @@ CONFIG_PCI_SYSCALL=y
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
#
@@ -237,6 +241,7 @@ CONFIG_AEABI=y
CONFIG_ARCH_FLATMEM_HAS_HOLES=y
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -249,6 +254,8 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
CONFIG_ALIGNMENT_TRAP=y
#
@@ -293,7 +300,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -324,7 +330,7 @@ CONFIG_IP_PNP_BOOTP=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
+CONFIG_INET_LRO=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
@@ -357,6 +363,7 @@ CONFIG_NET_DSA_MV88E6123_61_65=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -365,20 +372,20 @@ CONFIG_NET_DSA_MV88E6123_61_65=y
#
CONFIG_NET_PKTGEN=m
# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
CONFIG_CFG80211=y
# CONFIG_CFG80211_REG_DEBUG is not set
-# CONFIG_NL80211 is not set
CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
CONFIG_LIB80211=y
+# CONFIG_LIB80211_DEBUG is not set
CONFIG_MAC80211=y
#
@@ -513,7 +520,6 @@ CONFIG_MTD_NAND_ORION=y
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
#
# UBI - Unsorted block images
@@ -592,8 +598,10 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -614,6 +622,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -687,6 +696,7 @@ CONFIG_SATA_MV=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -724,8 +734,10 @@ CONFIG_MII=y
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -763,6 +775,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -777,6 +790,7 @@ CONFIG_MV643XX_ETH=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
@@ -789,10 +803,11 @@ CONFIG_WLAN_80211=y
CONFIG_LIBERTAS=y
# CONFIG_LIBERTAS_USB is not set
CONFIG_LIBERTAS_SDIO=y
+# CONFIG_LIBERTAS_SPI is not set
# CONFIG_LIBERTAS_DEBUG is not set
# CONFIG_LIBERTAS_THINFIRM is not set
-# CONFIG_HERMES is not set
# CONFIG_ATMEL is not set
+# CONFIG_AT76C50X_USB is not set
# CONFIG_PRISM54 is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_USB_NET_RNDIS_WLAN is not set
@@ -800,20 +815,20 @@ CONFIG_LIBERTAS_SDIO=y
# CONFIG_RTL8187 is not set
# CONFIG_ADM8211 is not set
# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_MWL8K is not set
# CONFIG_P54_COMMON is not set
# CONFIG_ATH5K is not set
# CONFIG_ATH9K is not set
+# CONFIG_AR9170_USB is not set
# CONFIG_IPW2100 is not set
# CONFIG_IPW2200 is not set
-# CONFIG_IWLCORE is not set
-# CONFIG_IWLWIFI_LEDS is not set
-# CONFIG_IWLAGN is not set
-# CONFIG_IWL3945 is not set
+# CONFIG_IWLWIFI is not set
# CONFIG_HOSTAP is not set
# CONFIG_B43 is not set
# CONFIG_B43LEGACY is not set
# CONFIG_ZD1211RW is not set
# CONFIG_RT2X00 is not set
+# CONFIG_HERMES is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -908,6 +923,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=2
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
@@ -982,7 +998,6 @@ CONFIG_I2C_MV64XXX=y
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -1082,15 +1097,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
CONFIG_HID_GYRATION=y
+CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1152,11 +1169,11 @@ CONFIG_USB_PRINTER=m
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
@@ -1198,7 +1215,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# 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
@@ -1215,6 +1231,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# OTG and related infrastructure
#
# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
@@ -1245,7 +1262,11 @@ CONFIG_LEDS_CLASS=y
#
# CONFIG_LEDS_PCA9532 is not set
CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP5521 is not set
# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
#
# LED Triggers
@@ -1255,6 +1276,10 @@ CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -1329,7 +1354,9 @@ CONFIG_DMA_ENGINE=y
# DMA Clients
#
# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_REGULATOR is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1341,6 +1368,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
# CONFIG_EXT3_FS_XATTR is not set
# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
@@ -1361,6 +1389,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
@@ -1419,6 +1452,7 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1430,7 +1464,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1502,6 +1535,9 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -1538,10 +1574,12 @@ CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1551,11 +1589,15 @@ CONFIG_TRACING=y
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1587,10 +1629,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1659,6 +1703,7 @@ CONFIG_CRYPTO_ARC4=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1667,6 +1712,7 @@ CONFIG_CRYPTO_ARC4=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
@@ -1682,7 +1728,7 @@ CONFIG_CRC32=y
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
index b0698722e0cb..398274b0771a 100644
--- a/arch/arm/configs/mv78xx0_defconfig
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -1,11 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc5
-# Fri Jun 13 02:57:32 2008
+# Linux kernel version: 2.6.30-rc4
+# Mon May 4 14:22:12 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_MMU=y
@@ -22,8 +22,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -43,10 +42,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -54,32 +62,35 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=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_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
# CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
# CONFIG_MARKERS is not set
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
@@ -87,10 +98,9 @@ CONFIG_KPROBES=y
CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -98,12 +108,10 @@ 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
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
+# CONFIG_BLK_DEV_INTEGRITY is not set
#
# IO Schedulers
@@ -117,7 +125,7 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
#
# System Type
@@ -127,11 +135,10 @@ CONFIG_CLASSIC_RCU=y
# 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_GEMINI is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
@@ -152,28 +159,23 @@ CONFIG_ARCH_MV78XX0=y
# CONFIG_ARCH_ORION5X is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MMP is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX 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_ARCH_MSM7X00A is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
#
# Marvell MV78xx0 Implementations
#
CONFIG_MACH_DB78X00_BP=y
CONFIG_MACH_RD78X00_MASA=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
CONFIG_PLAT_ORION=y
#
@@ -199,6 +201,7 @@ CONFIG_ARM_THUMB=y
# CONFIG_CPU_DCACHE_DISABLE is not set
CONFIG_OUTER_CACHE=y
CONFIG_CACHE_FEROCEON_L2=y
+# CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set
#
# Bus support
@@ -208,6 +211,8 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
#
@@ -217,25 +222,33 @@ CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_PREEMPT=y
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HIGHMEM=y
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_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
CONFIG_ALIGNMENT_TRAP=y
#
@@ -248,6 +261,11 @@ CONFIG_CMDLINE=""
# CONFIG_KEXEC is not set
#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
# Floating point emulation
#
@@ -263,6 +281,8 @@ CONFIG_VFP=y
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
# CONFIG_BINFMT_MISC is not set
@@ -271,10 +291,6 @@ CONFIG_BINFMT_ELF=y
#
# CONFIG_PM is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-
-#
-# Networking
-#
CONFIG_NET=y
#
@@ -310,7 +326,7 @@ CONFIG_IP_PNP_BOOTP=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
+CONFIG_INET_LRO=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
@@ -325,6 +341,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
@@ -334,26 +351,23 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
#
CONFIG_NET_PKTGEN=m
# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN 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 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -368,6 +382,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
@@ -376,6 +392,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
@@ -429,9 +446,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_IMPA7 is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
@@ -456,6 +471,7 @@ CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_VERIFY_WRITE=y
# CONFIG_MTD_NAND_ECC_SMC is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_CAFE is not set
@@ -466,6 +482,11 @@ CONFIG_MTD_NAND_ORION=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -486,10 +507,20 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_ATA_OVER_ETH 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
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -547,7 +578,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -566,6 +601,8 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -632,11 +669,15 @@ CONFIG_SATA_MV=y
#
# IEEE 1394 (FireWire) support
#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
# 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_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -644,7 +685,26 @@ CONFIG_NETDEVICES=y
# CONFIG_TUN is not set
# CONFIG_VETH is not set
# CONFIG_ARCNET is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
@@ -654,19 +714,25 @@ CONFIG_MII=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR 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_EEPRO100 is not set
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
@@ -676,18 +742,20 @@ CONFIG_NET_PCI=y
# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 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_ATL2 is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
-# CONFIG_E1000E_ENABLED is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -701,6 +769,9 @@ CONFIG_NETDEV_1000=y
CONFIG_MV643XX_ETH=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
@@ -709,7 +780,10 @@ CONFIG_MV643XX_ETH=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -786,11 +860,11 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
-# CONFIG_NVRAM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -799,44 +873,63 @@ CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
#
# I2C Hardware Bus support
#
+
+#
+# PC SMBus host controller drivers
+#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_MV64XXX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
# CONFIG_I2C_PCA_PLATFORM is not set
-CONFIG_I2C_MV64XXX=y
+# CONFIG_I2C_STUB is not set
#
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -848,6 +941,7 @@ CONFIG_I2C_MV64XXX=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
@@ -855,14 +949,17 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -877,10 +974,15 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 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_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
@@ -900,20 +1002,28 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
# Multifunction device drivers
#
+# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
#
# Multimedia devices
@@ -944,10 +1054,6 @@ CONFIG_SSB_POSSIBLE=y
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
@@ -958,9 +1064,36 @@ CONFIG_HID=y
# USB Input Devices
#
CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -978,6 +1111,9 @@ CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_OTG is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
#
# USB Host Controller Drivers
@@ -986,12 +1122,15 @@ CONFIG_USB_DEVICE_CLASS=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
#
# USB Device Class drivers
@@ -999,20 +1138,20 @@ CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_ACM is not set
CONFIG_USB_PRINTER=y
# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# may also be needed; see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
# CONFIG_USB_STORAGE_ISD200 is not set
-CONFIG_USB_STORAGE_DPCM=y
# CONFIG_USB_STORAGE_USBAT is not set
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
@@ -1028,7 +1167,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
#
# USB port drivers
@@ -1041,7 +1179,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
@@ -1049,7 +1187,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# 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
@@ -1059,14 +1196,29 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
#
# LED drivers
#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
#
# LED Triggers
@@ -1074,7 +1226,12 @@ CONFIG_LEDS_CLASS=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -1105,6 +1262,8 @@ CONFIG_RTC_DRV_RS5C372=y
CONFIG_RTC_DRV_M41T80=y
# CONFIG_RTC_DRV_M41T80_WDT is not set
# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
@@ -1114,18 +1273,25 @@ CONFIG_RTC_DRV_M41T80=y
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_V3020 is not set
#
# on-CPU RTC drivers
#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
#
# File systems
@@ -1134,14 +1300,25 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
# CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+CONFIG_EXT4_FS=m
+# CONFIG_EXT4DEV_COMPAT is not set
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=m
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1151,6 +1328,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
@@ -1174,15 +1356,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1202,25 +1382,27 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
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
@@ -1301,11 +1483,16 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
@@ -1320,22 +1507,55 @@ CONFIG_DEBUG_PREEMPT=y
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1347,17 +1567,27 @@ CONFIG_DEBUG_LL=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
+# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP=m
CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=m
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1393,6 +1623,10 @@ CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
@@ -1422,25 +1656,32 @@ CONFIG_CRYPTO_PCBC=m
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
#
CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=m
+# CONFIG_CRC_T10DIF is not set
CONFIG_CRC_ITU_T=m
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
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/mx31moboard_defconfig b/arch/arm/configs/mx31moboard_defconfig
deleted file mode 100644
index e90f86d6deef..000000000000
--- a/arch/arm/configs/mx31moboard_defconfig
+++ /dev/null
@@ -1,790 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc5
-# Fri Oct 24 11:41:22 2008
-#
-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_HAVE_LATENCYTOP_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_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
-CONFIG_ARCH_MTD_XIP=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=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_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-# CONFIG_RELAY is not set
-# CONFIG_NAMESPACES is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=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_PROFILING is not set
-# CONFIG_MARKERS is not set
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
-# CONFIG_HAVE_CLK is not set
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# 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
-# CONFIG_BLK_DEV_INTEGRITY 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"
-CONFIG_CLASSIC_RCU=y
-
-#
-# 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_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_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_MV78XX0 is not set
-CONFIG_ARCH_MXC=y
-# CONFIG_ARCH_ORION5X 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 is not set
-# CONFIG_ARCH_MSM7X00A is not set
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# Freescale MXC Implementations
-#
-# CONFIG_ARCH_MX2 is not set
-CONFIG_ARCH_MX3=y
-
-#
-# MX3 Options
-#
-# CONFIG_MACH_MX31ADS is not set
-# CONFIG_MACH_PCM037 is not set
-# CONFIG_MACH_MX31LITE is not set
-CONFIG_MACH_MX31MOBOARD=y
-# CONFIG_MXC_IRQ_PRIOR is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_V6=y
-# CONFIG_CPU_32v6K is not set
-CONFIG_CPU_32v6=y
-CONFIG_CPU_ABRT_EV6=y
-CONFIG_CPU_PABRT_NOIFAR=y
-CONFIG_CPU_CACHE_V6=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_TLB_V6=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_BPREDICT_DISABLE is not set
-# CONFIG_OUTER_CACHE is not set
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_ARCH_FLATMEM_HAS_HOLES=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_SPARSEMEM_VMEMMAP_ENABLE is not set
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# 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="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off"
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_VFP=y
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-# 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 is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES 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 is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# 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_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
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN 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_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-# 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=y
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
-CONFIG_MTD_REDBOOT_PARTS_READONLY=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_AR7_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
-# CONFIG_MTD_OOPS 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=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
-# 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 is not set
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_OTP is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=y
-# 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
-# CONFIG_MTD_XIP is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# 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 is not set
-# CONFIG_MISC_DEVICES is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE 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_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_AX88796 is not set
-CONFIG_SMC91X=y
-# CONFIG_DM9000 is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_B44 is not set
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP 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 is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-CONFIG_DEVKMEM=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_NVRAM is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
-# CONFIG_SPI is not set
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_GPIO_SYSFS is not set
-
-#
-# I2C GPIO expanders:
-#
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_WATCHDOG is not set
-
-#
-# Sonics Silicon Backplane
-#
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
-
-#
-# Graphics support
-#
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_SOUND is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-
-#
-# Voltage and Current regulators
-#
-# CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_UIO is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# 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_FS_WBUF_VERIFY is not set
-# 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_LZO is not set
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-CONFIG_ROOT_NFS=y
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# 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
-# CONFIG_NLS is not set
-# CONFIG_DLM is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_FRAME_WARN=1024
-# 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 is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_LATENCYTOP is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_T10DIF 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/configs/mx3_defconfig b/arch/arm/configs/mx3_defconfig
index 72a8201a5370..20ada526f6de 100644
--- a/arch/arm/configs/mx3_defconfig
+++ b/arch/arm/configs/mx3_defconfig
@@ -197,7 +197,7 @@ CONFIG_MXC_PWM=y
#
CONFIG_CPU_32=y
CONFIG_CPU_V6=y
-CONFIG_CPU_32v6K=y
+# CONFIG_CPU_32v6K is not set
CONFIG_CPU_32v6=y
CONFIG_CPU_ABRT_EV6=y
CONFIG_CPU_PABRT_NOIFAR=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 020e6a8a9e5c..5b98f7645119 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc4
-# Fri Aug 22 12:38:51 2008
+# Linux kernel version: 2.6.30-rc4
+# Mon May 4 14:07:25 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -22,8 +22,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -44,10 +42,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -55,48 +62,45 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=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_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
# CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
# CONFIG_MARKERS is not set
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
CONFIG_KRETPROBES=y
-# CONFIG_HAVE_IOREMAP_PROT is not set
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
-# CONFIG_HAVE_CLK is not set
-CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -104,11 +108,8 @@ 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
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -124,7 +125,7 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
#
# System Type
@@ -134,10 +135,10 @@ CONFIG_CLASSIC_RCU=y
# 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_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
@@ -158,14 +159,17 @@ CONFIG_CLASSIC_RCU=y
CONFIG_ARCH_ORION5X=y
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MMP is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX 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_ARCH_MSM7X00A is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
#
# Orion Implementations
@@ -175,6 +179,7 @@ CONFIG_MACH_RD88F5182=y
CONFIG_MACH_KUROBOX_PRO=y
CONFIG_MACH_DNS323=y
CONFIG_MACH_TS209=y
+CONFIG_MACH_TERASTATION_PRO2=y
CONFIG_MACH_LINKSTATION_PRO=y
CONFIG_MACH_LINKSTATION_MINI=y
CONFIG_MACH_TS409=y
@@ -187,14 +192,6 @@ CONFIG_MACH_WNR854T=y
CONFIG_MACH_RD88F5181L_GE=y
CONFIG_MACH_RD88F5181L_FXO=y
CONFIG_MACH_RD88F6183AP_GE=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
CONFIG_PLAT_ORION=y
#
@@ -228,6 +225,8 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
#
@@ -237,25 +236,32 @@ CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_PREEMPT=y
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
CONFIG_LEDS=y
CONFIG_LEDS_CPU=y
CONFIG_ALIGNMENT_TRAP=y
@@ -270,6 +276,11 @@ CONFIG_CMDLINE=""
# CONFIG_KEXEC is not set
#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
# Floating point emulation
#
@@ -285,13 +296,18 @@ CONFIG_VFP=y
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
# CONFIG_BINFMT_MISC is not set
#
# Power management options
#
-# CONFIG_PM is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_APM_EMULATION is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
@@ -328,7 +344,7 @@ CONFIG_IP_PNP_BOOTP=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
+CONFIG_INET_LRO=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
@@ -343,6 +359,15 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_TAG_DSA=y
+CONFIG_NET_DSA_TAG_EDSA=y
+# CONFIG_NET_DSA_TAG_TRAILER is not set
+CONFIG_NET_DSA_MV88E6XXX=y
+# CONFIG_NET_DSA_MV88E6060 is not set
+CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y
+CONFIG_NET_DSA_MV88E6131=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
@@ -352,27 +377,29 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
#
CONFIG_NET_PKTGEN=m
# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -397,6 +424,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
@@ -450,9 +478,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_IMPA7 is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
@@ -477,6 +503,7 @@ CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_VERIFY_WRITE=y
# CONFIG_MTD_NAND_ECC_SMC is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_CAFE is not set
@@ -487,6 +514,11 @@ CONFIG_MTD_NAND_ORION=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -507,11 +539,20 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_ATA_OVER_ETH 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
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -569,7 +610,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -589,6 +634,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -663,6 +709,7 @@ CONFIG_SATA_MV=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -670,7 +717,26 @@ CONFIG_NETDEVICES=y
# CONFIG_TUN is not set
# CONFIG_VETH is not set
# CONFIG_ARCNET is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
@@ -680,19 +746,25 @@ CONFIG_MII=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR 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_EEPRO100 is not set
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
@@ -702,10 +774,12 @@ CONFIG_NET_PCI=y
# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 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_ATL2 is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
@@ -713,6 +787,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -727,6 +802,8 @@ CONFIG_MV643XX_ETH=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
@@ -735,7 +812,10 @@ CONFIG_MV643XX_ETH=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -819,11 +899,11 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
-# CONFIG_NVRAM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -886,12 +966,9 @@ CONFIG_I2C_MV64XXX=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -911,14 +988,17 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -933,10 +1013,15 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 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_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
@@ -956,12 +1041,14 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
@@ -970,9 +1057,12 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
#
# Multimedia devices
@@ -1013,9 +1103,36 @@ CONFIG_HID=y
# USB Input Devices
#
CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1030,10 +1147,13 @@ CONFIG_USB=y
CONFIG_USB_DEVICEFS=y
CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
#
# USB Host Controller Drivers
@@ -1042,12 +1162,15 @@ CONFIG_USB_DEVICE_CLASS=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
#
# USB Device Class drivers
@@ -1055,20 +1178,20 @@ CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_ACM is not set
CONFIG_USB_PRINTER=y
# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# may also be needed; see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
# CONFIG_USB_STORAGE_ISD200 is not set
-CONFIG_USB_STORAGE_DPCM=y
# CONFIG_USB_STORAGE_USBAT is not set
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
@@ -1076,7 +1199,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_SIERRA is not set
# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
# CONFIG_USB_LIBUSUAL is not set
@@ -1097,6 +1219,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
@@ -1104,7 +1227,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# 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
@@ -1114,8 +1236,18 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
@@ -1124,7 +1256,10 @@ CONFIG_LEDS_CLASS=y
#
# CONFIG_LEDS_PCA9532 is not set
CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP5521 is not set
# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
#
# LED Triggers
@@ -1132,7 +1267,12 @@ CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -1164,6 +1304,7 @@ CONFIG_RTC_DRV_M41T80=y
# CONFIG_RTC_DRV_M41T80_WDT is not set
CONFIG_RTC_DRV_S35390A=y
# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
@@ -1173,12 +1314,15 @@ CONFIG_RTC_DRV_S35390A=y
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
CONFIG_RTC_DRV_M48T86=y
+# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_V3020 is not set
#
@@ -1196,16 +1340,12 @@ CONFIG_DMA_ENGINE=y
# DMA Clients
#
# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
# CONFIG_DMATEST is not set
-
-#
-# Voltage and Current regulators
-#
+# CONFIG_AUXDISPLAY is not set
# CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
#
# File systems
@@ -1214,14 +1354,25 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
# CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+CONFIG_EXT4_FS=m
+# CONFIG_EXT4DEV_COMPAT is not set
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=m
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1231,6 +1382,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
@@ -1254,15 +1410,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1282,6 +1436,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1290,6 +1445,7 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1381,13 +1537,16 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
@@ -1411,25 +1570,46 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_FRAME_POINTER=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_LATENCYTOP=y
CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1441,18 +1621,27 @@ CONFIG_DEBUG_LL=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_ASYNC_CORE=y
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
+# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP=m
CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=m
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1521,18 +1710,24 @@ CONFIG_CRYPTO_PCBC=m
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
#
CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=m
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
@@ -1540,7 +1735,7 @@ CONFIG_CRC32=y
# 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
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/stmp378x_defconfig b/arch/arm/configs/stmp378x_defconfig
new file mode 100644
index 000000000000..44461f197a17
--- /dev/null
+++ b/arch/arm/configs/stmp378x_defconfig
@@ -0,0 +1,1141 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc2
+# Thu Apr 23 02:44:13 2009
+#
+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_HAVE_LATENCYTOP_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_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="-default"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
+CONFIG_INITRAMFS_COMPRESSION_GZIP=y
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
+CONFIG_MARKERS=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY 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"
+# CONFIG_FREEZER is not set
+
+#
+# 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_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_GEMINI 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_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX 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_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
+CONFIG_ARCH_STMP3XXX=y
+
+#
+# Freescale STMP3xxx implementations
+#
+# CONFIG_ARCH_STMP37XX is not set
+CONFIG_ARCH_STMP378X=y
+# CONFIG_MACH_STMP37XX is not set
+CONFIG_MACH_STMP378X=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=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=y
+# 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
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HIGHMEM=y
+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_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySDBG0,115200 mem=32M"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=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=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA 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
+# CONFIG_PHONET is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+# CONFIG_NET_SCH_CBQ is not set
+# CONFIG_NET_SCH_HTB is not set
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_MULTIQ is not set
+# CONFIG_NET_SCH_RED is not set
+# CONFIG_NET_SCH_SFQ is not set
+# CONFIG_NET_SCH_TEQL is not set
+# CONFIG_NET_SCH_TBF is not set
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_NETEM is not set
+# CONFIG_NET_SCH_DRR is not set
+
+#
+# Classification
+#
+# CONFIG_NET_CLS_BASIC is not set
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# 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=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_TESTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_BLKDEVS is not set
+# CONFIG_MTD_BLOCK is not set
+# 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
+# CONFIG_MTD_OOPS 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_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=y
+# 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_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+CONFIG_MTD_UBI_GLUEBI=y
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG 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=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=6144
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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=y
+
+#
+# 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=y
+# 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_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+# CONFIG_INPUT_JOYDEV 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_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_AD7879 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO 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_TOUCHIT213 is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+# CONFIG_VIDEO_V4L1_COMPAT is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+
+#
+# RDS decoders
+#
+
+#
+# Video decoders
+#
+
+#
+# Video and audio decoders
+#
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT 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_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# 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_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT 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
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_OBJECTS_SELFTEST=y
+CONFIG_DEBUG_OBJECTS_FREE=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
+CONFIG_DEBUG_SLAB=y
+CONFIG_DEBUG_SLAB_LEAK=y
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCKDEP=y
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_LOCKDEP is not set
+CONFIG_TRACE_IRQFLAGS=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_KOBJECT=y
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+CONFIG_FUNCTION_TRACER=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+CONFIG_CONTEXT_SWITCH_TRACER=y
+# CONFIG_EVENT_TRACER is not set
+CONFIG_BOOT_TRACER=y
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_STACK_TRACER=y
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF 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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/stmp37xx_defconfig b/arch/arm/configs/stmp37xx_defconfig
new file mode 100644
index 000000000000..401279d531d5
--- /dev/null
+++ b/arch/arm/configs/stmp37xx_defconfig
@@ -0,0 +1,1002 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29.1
+# Mon Apr 20 04:41:26 2009
+#
+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_HAVE_LATENCYTOP_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_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="-default"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=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_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
+CONFIG_MARKERS=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY 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"
+# CONFIG_FREEZER is not set
+
+#
+# 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_CLPS711X 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_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X 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_S3C64XX 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_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
+CONFIG_ARCH_STMP3XXX=y
+
+#
+# Freescale STMP3xxx implementations
+#
+CONFIG_ARCH_STMP37XX=y
+# CONFIG_ARCH_STMP378X is not set
+CONFIG_MACH_STMP37XX=y
+# CONFIG_MACH_STMP378X is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=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=y
+# 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
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySDBG0,115200 mem=32M lcd_panel=lms350 rdinit=/bin/sh ignore_loglevel"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=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=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA 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
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+# CONFIG_NET_SCH_CBQ is not set
+# CONFIG_NET_SCH_HTB is not set
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_MULTIQ is not set
+# CONFIG_NET_SCH_RED is not set
+# CONFIG_NET_SCH_SFQ is not set
+# CONFIG_NET_SCH_TEQL is not set
+# CONFIG_NET_SCH_TBF is not set
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_NETEM is not set
+# CONFIG_NET_SCH_DRR is not set
+
+#
+# Classification
+#
+# CONFIG_NET_CLS_BASIC is not set
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_FIB_RULES=y
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# 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 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=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=6144
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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=y
+
+#
+# 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=y
+# 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_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+# CONFIG_INPUT_JOYDEV 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_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_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO 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_TOUCHIT213 is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_STMP_DBG is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+# CONFIG_VIDEO_V4L1_COMPAT is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+
+#
+# Video decoders
+#
+
+#
+# Video and audio decoders
+#
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT 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_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# 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_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT 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
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# 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_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+
+#
+# Tracers
+#
+CONFIG_FUNCTION_TRACER=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_BOOT_TRACER=y
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_STACK_TRACER=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF 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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index d7da19bcf928..c207504de84d 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -45,13 +45,15 @@ typedef struct user_fp elf_fpregset_t;
#define EF_ARM_HASENTRY 0x00000002 /* All */
#define EF_ARM_RELEXEC 0x00000001 /* All */
-#define R_ARM_NONE 0
-#define R_ARM_PC24 1
-#define R_ARM_ABS32 2
-#define R_ARM_CALL 28
-#define R_ARM_JUMP24 29
-#define R_ARM_V4BX 40
-#define R_ARM_PREL31 42
+#define R_ARM_NONE 0
+#define R_ARM_PC24 1
+#define R_ARM_ABS32 2
+#define R_ARM_CALL 28
+#define R_ARM_JUMP24 29
+#define R_ARM_V4BX 40
+#define R_ARM_PREL31 42
+#define R_ARM_MOVW_ABS_NC 43
+#define R_ARM_MOVT_ABS 44
/*
* These are used to set parameters in the core dumps.
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index f87328d4a180..5d72550a8097 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -41,7 +41,7 @@
#define VIC_PL192_VECT_ADDR 0xF00
#ifndef __ASSEMBLY__
-void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources);
+void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
#endif
#endif
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 110295c5461d..1cd2d6416bda 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -342,7 +342,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
return __va(ptr);
}
-#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
+#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
/*
* Conversion functions: convert a page and protection to a page entry,
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index d1731e39b496..bac03c81489d 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -169,6 +169,21 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
*(u32 *)loc = offset & 0x7fffffff;
break;
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_MOVT_ABS:
+ offset = *(u32 *)loc;
+ offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
+ offset = (offset ^ 0x8000) - 0x8000;
+
+ offset += sym->st_value;
+ if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS)
+ offset >>= 16;
+
+ *(u32 *)loc &= 0xfff0f000;
+ *(u32 *)loc |= ((offset & 0xf000) << 4) |
+ (offset & 0x0fff);
+ break;
+
default:
printk(KERN_ERR "%s: unknown relocation: %u\n",
module->name, ELF32_R_TYPE(rel->r_info));
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index e4345106ee57..bac578fe0d3d 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -43,6 +43,25 @@
#define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM)
+/*
+ * Chips have some kind of clocks : group them by functionality
+ */
+#define cpu_has_utmi() ( cpu_is_at91cap9() \
+ || cpu_is_at91sam9rl())
+
+#define cpu_has_800M_plla() (cpu_is_at91sam9g20())
+
+#define cpu_has_pllb() (!cpu_is_at91sam9rl())
+
+#define cpu_has_upll() (0)
+
+/* USB host HS & FS */
+#define cpu_has_uhp() (!cpu_is_at91sam9rl())
+
+/* USB device FS only */
+#define cpu_has_udpfs() (!cpu_is_at91sam9rl())
+
+
static LIST_HEAD(clocks);
static DEFINE_SPINLOCK(clk_lock);
@@ -140,7 +159,7 @@ static struct clk utmi_clk = {
};
static struct clk uhpck = {
.name = "uhpck",
- .parent = &pllb,
+ /*.parent = ... we choose parent at runtime */
.mode = pmc_sys_mode,
};
@@ -173,7 +192,11 @@ static struct clk __init *at91_css_to_clk(unsigned long css)
case AT91_PMC_CSS_PLLA:
return &plla;
case AT91_PMC_CSS_PLLB:
- return &pllb;
+ if (cpu_has_upll())
+ /* CSS_PLLB == CSS_UPLL */
+ return &utmi_clk;
+ else if (cpu_has_pllb())
+ return &pllb;
}
return NULL;
@@ -322,7 +345,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
u32 pckr;
pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
- pckr &= AT91_PMC_CSS_PLLB; /* clock selection */
+ pckr &= AT91_PMC_CSS; /* clock selection */
pckr |= prescale << 2;
at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
clk->rate_hz = actual;
@@ -361,7 +384,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
}
EXPORT_SYMBOL(clk_set_parent);
-/* establish PCK0..PCK3 parentage and rate */
+/* establish PCK0..PCKN parentage and rate */
static void __init init_programmable_clock(struct clk *clk)
{
struct clk *parent;
@@ -389,11 +412,13 @@ static int at91_clk_show(struct seq_file *s, void *unused)
seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR));
seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR));
seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR));
- if (!cpu_is_at91sam9rl())
+ if (cpu_has_pllb())
seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
- if (cpu_is_at91cap9() || cpu_is_at91sam9rl())
+ if (cpu_has_utmi())
seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR));
seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR));
+ if (cpu_has_upll())
+ seq_printf(s, "USB = %8x\n", at91_sys_read(AT91_PMC_USB));
seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR));
seq_printf(s, "\n");
@@ -554,16 +579,60 @@ static struct clk *const standard_pmc_clocks[] __initdata = {
&clk32k,
&main_clk,
&plla,
- &pllb,
-
- /* PLLB children (USB) */
- &udpck,
- &uhpck,
/* MCK */
&mck
};
+/* PLLB generated USB full speed clock init */
+static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
+{
+ /*
+ * USB clock init: choose 48 MHz PLLB value,
+ * disable 48MHz clock during usb peripheral suspend.
+ *
+ * REVISIT: assumes MCK doesn't derive from PLLB!
+ */
+ uhpck.parent = &pllb;
+
+ at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M;
+ pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
+ if (cpu_is_at91rm9200()) {
+ uhpck.pmc_mask = AT91RM9200_PMC_UHP;
+ udpck.pmc_mask = AT91RM9200_PMC_UDP;
+ at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
+ } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
+ uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
+ udpck.pmc_mask = AT91SAM926x_PMC_UDP;
+ } else if (cpu_is_at91cap9()) {
+ uhpck.pmc_mask = AT91CAP9_PMC_UHP;
+ }
+ at91_sys_write(AT91_CKGR_PLLBR, 0);
+
+ udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
+ uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
+}
+
+/* UPLL generated USB full speed clock init */
+static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
+{
+ /*
+ * USB clock init: choose 480 MHz from UPLL,
+ */
+ unsigned int usbr = AT91_PMC_USBS_UPLL;
+
+ /* Setup divider by 10 to reach 48 MHz */
+ usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV;
+
+ at91_sys_write(AT91_PMC_USB, usbr);
+
+ /* Now set uhpck values */
+ uhpck.parent = &utmi_clk;
+ uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
+ uhpck.rate_hz = utmi_clk.parent->rate_hz;
+ uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
+}
+
int __init at91_clock_init(unsigned long main_clock)
{
unsigned tmp, freq, mckr;
@@ -585,43 +654,37 @@ int __init at91_clock_init(unsigned long main_clock)
/* report if PLLA is more than mildly overclocked */
plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
- if ((!cpu_is_at91sam9g20() && plla.rate_hz > 209000000)
- || (cpu_is_at91sam9g20() && plla.rate_hz > 800000000))
+ if ((!cpu_has_800M_plla() && plla.rate_hz > 209000000)
+ || (cpu_has_800M_plla() && plla.rate_hz > 800000000))
pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
- /*
- * USB clock init: choose 48 MHz PLLB value,
- * disable 48MHz clock during usb peripheral suspend.
- *
- * REVISIT: assumes MCK doesn't derive from PLLB!
- */
- at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M;
- pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
- if (cpu_is_at91rm9200()) {
- uhpck.pmc_mask = AT91RM9200_PMC_UHP;
- udpck.pmc_mask = AT91RM9200_PMC_UDP;
- at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
- } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
- uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
- udpck.pmc_mask = AT91SAM926x_PMC_UDP;
- } else if (cpu_is_at91cap9()) {
- uhpck.pmc_mask = AT91CAP9_PMC_UHP;
+
+ if (cpu_has_upll() && !cpu_has_pllb()) {
+ /* setup UTMI clock as the fourth primary clock
+ * (instead of pllb) */
+ utmi_clk.type |= CLK_TYPE_PRIMARY;
+ utmi_clk.id = 3;
}
- at91_sys_write(AT91_CKGR_PLLBR, 0);
- udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
- uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
/*
* USB HS clock init
*/
- if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) {
+ if (cpu_has_utmi())
/*
* multiplier is hard-wired to 40
* (obtain the USB High Speed 480 MHz when input is 12 MHz)
*/
utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
- }
+
+ /*
+ * USB FS clock init
+ */
+ if (cpu_has_pllb())
+ at91_pllb_usbfs_clock_init(main_clock);
+ if (cpu_has_upll())
+ /* assumes that we choose UPLL for USB and not PLLA */
+ at91_upll_usbfs_clock_init(main_clock);
/*
* MCK and CPU derive from one of those primary clocks.
@@ -631,21 +694,31 @@ int __init at91_clock_init(unsigned long main_clock)
mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
freq = mck.parent->rate_hz;
freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */
- if (cpu_is_at91rm9200())
+ if (cpu_is_at91rm9200()) {
mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
- else if (cpu_is_at91sam9g20()) {
+ } else if (cpu_is_at91sam9g20()) {
mck.rate_hz = (mckr & AT91_PMC_MDIV) ?
freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */
if (mckr & AT91_PMC_PDIV)
freq /= 2; /* processor clock division */
- } else
+ } else {
mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
+ }
/* Register the PMC's standard clocks */
for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
list_add_tail(&standard_pmc_clocks[i]->node, &clocks);
- if (cpu_is_at91cap9() || cpu_is_at91sam9rl())
+ if (cpu_has_pllb())
+ list_add_tail(&pllb.node, &clocks);
+
+ if (cpu_has_uhp())
+ list_add_tail(&uhpck.node, &clocks);
+
+ if (cpu_has_udpfs())
+ list_add_tail(&udpck.node, &clocks);
+
+ if (cpu_has_utmi())
list_add_tail(&utmi_clk.node, &clocks);
/* MCK and CPU clock are "always on" */
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
index 9561e33b8a9a..64589eaaaee8 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc.h
@@ -23,7 +23,7 @@
#define AT91_PMC_PCK (1 << 0) /* Processor Clock */
#define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */
#define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
-#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [AT91CAP9 revC only] */
+#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [CAP9 revC & some SAM9 only] */
#define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */
#define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */
#define AT91CAP9_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91CAP9 only] */
@@ -39,11 +39,11 @@
#define AT91_PMC_PCDR (AT91_PMC + 0x14) /* Peripheral Clock Disable Register */
#define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */
-#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [SAM9RL, CAP9] */
+#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [some SAM9, CAP9] */
#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */
#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */
#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */
-#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI PLL Start-up Time */
+#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */
#define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */
#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */
@@ -72,6 +72,7 @@
#define AT91_PMC_CSS_MAIN (1 << 0)
#define AT91_PMC_CSS_PLLA (2 << 0)
#define AT91_PMC_CSS_PLLB (3 << 0)
+#define AT91_PMC_CSS_UPLL (3 << 0) /* [some SAM9 only] */
#define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */
#define AT91_PMC_PRES_1 (0 << 2)
#define AT91_PMC_PRES_2 (1 << 2)
@@ -88,12 +89,25 @@
#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9,CAP9 only] */
#define AT91SAM9_PMC_MDIV_2 (1 << 8)
#define AT91SAM9_PMC_MDIV_4 (2 << 8)
-#define AT91SAM9_PMC_MDIV_6 (3 << 8)
+#define AT91SAM9_PMC_MDIV_6 (3 << 8) /* [some SAM9 only] */
+#define AT91SAM9_PMC_MDIV_3 (3 << 8) /* [some SAM9 only] */
#define AT91_PMC_PDIV (1 << 12) /* Processor Clock Division [some SAM9 only] */
#define AT91_PMC_PDIV_1 (0 << 12)
#define AT91_PMC_PDIV_2 (1 << 12)
+#define AT91_PMC_PLLADIV2 (1 << 12) /* PLLA divisor by 2 [some SAM9 only] */
+#define AT91_PMC_PLLADIV2_OFF (0 << 12)
+#define AT91_PMC_PLLADIV2_ON (1 << 12)
-#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-3 Registers */
+#define AT91_PMC_USB (AT91_PMC + 0x38) /* USB Clock Register [some SAM9 only] */
+#define AT91_PMC_USBS (0x1 << 0) /* USB OHCI Input clock selection */
+#define AT91_PMC_USBS_PLLA (0 << 0)
+#define AT91_PMC_USBS_UPLL (1 << 0)
+#define AT91_PMC_OHCIUSBDIV (0xF << 8) /* Divider for USB OHCI Clock */
+
+#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */
+#define AT91_PMC_CSSMCK (0x1 << 8) /* CSS or Master Clock Selection */
+#define AT91_PMC_CSSMCK_CSS (0 << 8)
+#define AT91_PMC_CSSMCK_MCK (1 << 8)
#define AT91_PMC_IER (AT91_PMC + 0x60) /* Interrupt Enable Register */
#define AT91_PMC_IDR (AT91_PMC + 0x64) /* Interrupt Disable Register */
@@ -102,7 +116,7 @@
#define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */
#define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */
#define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */
-#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [AT91CAP9 only] */
+#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9, AT91CAP9 only] */
#define AT91_PMC_OSCSEL (1 << 7) /* Slow Clock Oscillator [AT91CAP9 revC only] */
#define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */
#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index c039674fe99e..b2e7f9c63bc5 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -211,7 +211,7 @@ static struct resource ide_resources[] = {
},
};
-static u64 ide_dma_mask = DMA_32BIT_MASK;
+static u64 ide_dma_mask = DMA_BIT_MASK(32);
static struct platform_device ide_dev = {
.name = "palm_bk3710",
@@ -220,7 +220,7 @@ static struct platform_device ide_dev = {
.num_resources = ARRAY_SIZE(ide_resources),
.dev = {
.dma_mask = &ide_dma_mask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
};
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index 56bddcef6905..9414eb641311 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -15,44 +15,62 @@ config MACH_ADSSPHERE
Say 'Y' here if you want your kernel to support the ADS
Sphere board.
+config MACH_EDB93XX
+ bool
+ default n
+
+config MACH_EDB9301
+ bool "Support Cirrus Logic EDB9301"
+ select MACH_EDB93XX
+ help
+ Say 'Y' here if you want your kernel to support the Cirrus
+ Logic EDB9301 Evaluation Board.
+
config MACH_EDB9302
bool "Support Cirrus Logic EDB9302"
+ select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9302 Evaluation Board.
config MACH_EDB9302A
bool "Support Cirrus Logic EDB9302A"
+ select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9302A Evaluation Board.
config MACH_EDB9307
bool "Support Cirrus Logic EDB9307"
+ select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9307 Evaluation Board.
config MACH_EDB9307A
bool "Support Cirrus Logic EDB9307A"
+ select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9307A Evaluation Board.
config MACH_EDB9312
bool "Support Cirrus Logic EDB9312"
+ select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9312 Evaluation Board.
config MACH_EDB9315
bool "Support Cirrus Logic EDB9315"
+ select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9315 Evaluation Board.
config MACH_EDB9315A
bool "Support Cirrus Logic EDB9315A"
+ select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9315A Evaluation Board.
@@ -64,29 +82,29 @@ config MACH_GESBC9312
GESBC-9312-sx board.
config MACH_MICRO9
- bool
- default n
+ bool
+ default n
config MACH_MICRO9H
- bool "Support Contec Hypercontrol Micro9-H"
- select MACH_MICRO9
- help
- Say 'Y' here if you want your kernel to support the
- Contec Hypercontrol Micro9-H board.
+ bool "Support Contec Hypercontrol Micro9-H"
+ select MACH_MICRO9
+ help
+ Say 'Y' here if you want your kernel to support the
+ Contec Hypercontrol Micro9-H board.
config MACH_MICRO9M
- bool "Support Contec Hypercontrol Micro9-M"
- select MACH_MICRO9
- help
- Say 'Y' here if you want your kernel to support the
- Contec Hypercontrol Micro9-M board.
+ bool "Support Contec Hypercontrol Micro9-M"
+ select MACH_MICRO9
+ help
+ Say 'Y' here if you want your kernel to support the
+ Contec Hypercontrol Micro9-M board.
config MACH_MICRO9L
- bool "Support Contec Hypercontrol Micro9-L"
- select MACH_MICRO9
- help
- Say 'Y' here if you want your kernel to support the
- Contec Hypercontrol Micro9-L board.
+ bool "Support Contec Hypercontrol Micro9-L"
+ select MACH_MICRO9
+ help
+ Say 'Y' here if you want your kernel to support the
+ Contec Hypercontrol Micro9-L board.
config MACH_TS72XX
bool "Support Technologic Systems TS-72xx SBC"
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
index 9522e205b73f..eae6199a9891 100644
--- a/arch/arm/mach-ep93xx/Makefile
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -7,13 +7,7 @@ obj-n :=
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_EDB9307A) += edb9307a.o
-obj-$(CONFIG_MACH_EDB9312) += edb9312.o
-obj-$(CONFIG_MACH_EDB9315) += edb9315.o
-obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o
+obj-$(CONFIG_MACH_EDB93XX) += edb93xx.o
obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o
obj-$(CONFIG_MACH_MICRO9) += micro9.o
obj-$(CONFIG_MACH_TS72XX) += ts72xx.o
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index ae24486f858a..8611db978efc 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -362,8 +362,8 @@ void __init ep93xx_init_irq(void)
{
int gpio_irq;
- vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK);
- vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK);
+ vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
+ vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
for (gpio_irq = gpio_to_irq(0);
gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
@@ -450,10 +450,19 @@ static struct amba_device uart3_device = {
};
+static struct resource ep93xx_rtc_resource[] = {
+ {
+ .start = EP93XX_RTC_PHYS_BASE,
+ .end = EP93XX_RTC_PHYS_BASE + 0x10c - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
static struct platform_device ep93xx_rtc_device = {
- .name = "ep93xx-rtc",
- .id = -1,
- .num_resources = 0,
+ .name = "ep93xx-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_rtc_resource),
+ .resource = ep93xx_rtc_resource,
};
diff --git a/arch/arm/mach-ep93xx/edb9302.c b/arch/arm/mach-ep93xx/edb9302.c
deleted file mode 100644
index 8bf8d7c78f1a..000000000000
--- a/arch/arm/mach-ep93xx/edb9302.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * arch/arm/mach-ep93xx/edb9302.c
- * Cirrus Logic EDB9302 support.
- *
- * Copyright (C) 2006 George Kashperko <george@chas.com.ua>
- *
- * 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 <linux/io.h>
-#include <linux/i2c.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-static struct physmap_flash_data edb9302_flash_data = {
- .width = 2,
-};
-
-static struct resource edb9302_flash_resource = {
- .start = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device edb9302_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &edb9302_flash_data,
- },
- .num_resources = 1,
- .resource = &edb9302_flash_resource,
-};
-
-static struct ep93xx_eth_data edb9302_eth_data = {
- .phy_id = 1,
-};
-
-static void __init edb9302_init_machine(void)
-{
- ep93xx_init_devices();
- platform_device_register(&edb9302_flash);
-
- ep93xx_register_eth(&edb9302_eth_data, 1);
-}
-
-MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
- /* Maintainer: George Kashperko <george@chas.com.ua> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
- .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
- .map_io = ep93xx_map_io,
- .init_irq = ep93xx_init_irq,
- .timer = &ep93xx_timer,
- .init_machine = edb9302_init_machine,
-MACHINE_END
diff --git a/arch/arm/mach-ep93xx/edb9302a.c b/arch/arm/mach-ep93xx/edb9302a.c
deleted file mode 100644
index a352c57c7b46..000000000000
--- a/arch/arm/mach-ep93xx/edb9302a.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * arch/arm/mach-ep93xx/edb9302a.c
- * Cirrus Logic EDB9302A support.
- *
- * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.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 <linux/io.h>
-#include <linux/i2c.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-static struct physmap_flash_data edb9302a_flash_data = {
- .width = 2,
-};
-
-static struct resource edb9302a_flash_resource = {
- .start = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device edb9302a_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &edb9302a_flash_data,
- },
- .num_resources = 1,
- .resource = &edb9302a_flash_resource,
-};
-
-static struct ep93xx_eth_data edb9302a_eth_data = {
- .phy_id = 1,
-};
-
-static void __init edb9302a_init_machine(void)
-{
- ep93xx_init_devices();
- platform_device_register(&edb9302a_flash);
-
- ep93xx_register_eth(&edb9302a_eth_data, 1);
-}
-
-MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
- /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
- .boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
- .map_io = ep93xx_map_io,
- .init_irq = ep93xx_init_irq,
- .timer = &ep93xx_timer,
- .init_machine = edb9302a_init_machine,
-MACHINE_END
diff --git a/arch/arm/mach-ep93xx/edb9307.c b/arch/arm/mach-ep93xx/edb9307.c
deleted file mode 100644
index 5ab22f63a4eb..000000000000
--- a/arch/arm/mach-ep93xx/edb9307.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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 <linux/io.h>
-#include <linux/i2c.h>
-#include <mach/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 = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_32M - 1,
- .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 void __init edb9307_init_machine(void)
-{
- ep93xx_init_devices();
- platform_device_register(&edb9307_flash);
-
- ep93xx_register_eth(&edb9307_eth_data, 1);
-}
-
-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 = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
- .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-ep93xx/edb9307a.c b/arch/arm/mach-ep93xx/edb9307a.c
deleted file mode 100644
index 6171167d3315..000000000000
--- a/arch/arm/mach-ep93xx/edb9307a.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * arch/arm/mach-ep93xx/edb9307a.c
- * Cirrus Logic EDB9307A support.
- *
- * Copyright (C) 2008 H Hartley Sweeten <hsweeten@visionengravers.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.
- */
-
-#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 <linux/io.h>
-#include <linux/i2c.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-static struct physmap_flash_data edb9307a_flash_data = {
- .width = 2,
-};
-
-static struct resource edb9307a_flash_resource = {
- .start = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device edb9307a_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &edb9307a_flash_data,
- },
- .num_resources = 1,
- .resource = &edb9307a_flash_resource,
-};
-
-static struct ep93xx_eth_data edb9307a_eth_data = {
- .phy_id = 1,
-};
-
-static struct i2c_board_info __initdata edb9307a_i2c_data[] = {
- {
- /* On-board battery backed RTC */
- I2C_BOARD_INFO("isl1208", 0x6f),
- },
- /*
- * The I2C signals are also routed to the Expansion Connector (J4)
- */
-};
-
-static void __init edb9307a_init_machine(void)
-{
- ep93xx_init_devices();
- platform_device_register(&edb9307a_flash);
-
- ep93xx_register_eth(&edb9307a_eth_data, 1);
-
- ep93xx_init_i2c(edb9307a_i2c_data, ARRAY_SIZE(edb9307a_i2c_data));
-}
-
-MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
- /* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
- .boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
- .map_io = ep93xx_map_io,
- .init_irq = ep93xx_init_irq,
- .timer = &ep93xx_timer,
- .init_machine = edb9307a_init_machine,
-MACHINE_END
diff --git a/arch/arm/mach-ep93xx/edb9312.c b/arch/arm/mach-ep93xx/edb9312.c
deleted file mode 100644
index d7179f66d804..000000000000
--- a/arch/arm/mach-ep93xx/edb9312.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * arch/arm/mach-ep93xx/edb9312.c
- * Cirrus Logic EDB9312 support.
- *
- * Copyright (C) 2006 Infosys Technologies Limited
- * Toufeeq Hussain <toufeeq_hussain@infosys.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.
- */
-
-#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 <linux/io.h>
-#include <linux/i2c.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-static struct physmap_flash_data edb9312_flash_data = {
- .width = 4,
-};
-
-static struct resource edb9312_flash_resource = {
- .start = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_32M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device edb9312_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &edb9312_flash_data,
- },
- .num_resources = 1,
- .resource = &edb9312_flash_resource,
-};
-
-static struct ep93xx_eth_data edb9312_eth_data = {
- .phy_id = 1,
-};
-
-static void __init edb9312_init_machine(void)
-{
- ep93xx_init_devices();
- platform_device_register(&edb9312_flash);
-
- ep93xx_register_eth(&edb9312_eth_data, 1);
-}
-
-MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
- /* Maintainer: Toufeeq Hussain <toufeeq_hussain@infosys.com> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
- .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
- .map_io = ep93xx_map_io,
- .init_irq = ep93xx_init_irq,
- .timer = &ep93xx_timer,
- .init_machine = edb9312_init_machine,
-MACHINE_END
diff --git a/arch/arm/mach-ep93xx/edb9315.c b/arch/arm/mach-ep93xx/edb9315.c
deleted file mode 100644
index 025af6eaca10..000000000000
--- a/arch/arm/mach-ep93xx/edb9315.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * arch/arm/mach-ep93xx/edb9315.c
- * Cirrus Logic EDB9315 support.
- *
- * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.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 <linux/io.h>
-#include <linux/i2c.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-static struct physmap_flash_data edb9315_flash_data = {
- .width = 4,
-};
-
-static struct resource edb9315_flash_resource = {
- .start = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_32M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device edb9315_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &edb9315_flash_data,
- },
- .num_resources = 1,
- .resource = &edb9315_flash_resource,
-};
-
-static struct ep93xx_eth_data edb9315_eth_data = {
- .phy_id = 1,
-};
-
-static void __init edb9315_init_machine(void)
-{
- ep93xx_init_devices();
- platform_device_register(&edb9315_flash);
-
- ep93xx_register_eth(&edb9315_eth_data, 1);
-}
-
-MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
- /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
- .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
- .map_io = ep93xx_map_io,
- .init_irq = ep93xx_init_irq,
- .timer = &ep93xx_timer,
- .init_machine = edb9315_init_machine,
-MACHINE_END
diff --git a/arch/arm/mach-ep93xx/edb9315a.c b/arch/arm/mach-ep93xx/edb9315a.c
deleted file mode 100644
index 4c9cc8a39f5c..000000000000
--- a/arch/arm/mach-ep93xx/edb9315a.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * arch/arm/mach-ep93xx/edb9315a.c
- * Cirrus Logic EDB9315A support.
- *
- * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.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 <linux/io.h>
-#include <linux/i2c.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-static struct physmap_flash_data edb9315a_flash_data = {
- .width = 2,
-};
-
-static struct resource edb9315a_flash_resource = {
- .start = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device edb9315a_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &edb9315a_flash_data,
- },
- .num_resources = 1,
- .resource = &edb9315a_flash_resource,
-};
-
-static struct ep93xx_eth_data edb9315a_eth_data = {
- .phy_id = 1,
-};
-
-static void __init edb9315a_init_machine(void)
-{
- ep93xx_init_devices();
- platform_device_register(&edb9315a_flash);
-
- ep93xx_register_eth(&edb9315a_eth_data, 1);
-}
-
-MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
- /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_io = EP93XX_APB_PHYS_BASE,
- .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
- .boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
- .map_io = ep93xx_map_io,
- .init_irq = ep93xx_init_irq,
- .timer = &ep93xx_timer,
- .init_machine = edb9315a_init_machine,
-MACHINE_END
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index f66be12b856e..78ac1bddc8bc 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -147,6 +147,7 @@
#define EP93XX_PWM_BASE (EP93XX_APB_VIRT_BASE + 0x00110000)
#define EP93XX_RTC_BASE (EP93XX_APB_VIRT_BASE + 0x00120000)
+#define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000)
#define EP93XX_SYSCON_BASE (EP93XX_APB_VIRT_BASE + 0x00130000)
#define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x))
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h b/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
new file mode 100644
index 000000000000..83f31cd0a274
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
+ */
+
+#ifndef __ASM_ARCH_EP93XX_KEYPAD_H
+#define __ASM_ARCH_EP93XX_KEYPAD_H
+
+#define MAX_MATRIX_KEY_ROWS (8)
+#define MAX_MATRIX_KEY_COLS (8)
+
+/* flags for the ep93xx_keypad driver */
+#define EP93XX_KEYPAD_DISABLE_3_KEY (1<<0) /* disable 3-key reset */
+#define EP93XX_KEYPAD_DIAG_MODE (1<<1) /* diagnostic mode */
+#define EP93XX_KEYPAD_BACK_DRIVE (1<<2) /* back driving mode */
+#define EP93XX_KEYPAD_TEST_MODE (1<<3) /* scan only column 0 */
+#define EP93XX_KEYPAD_KDIV (1<<4) /* 1/4 clock or 1/16 clock */
+#define EP93XX_KEYPAD_AUTOREPEAT (1<<5) /* enable key autorepeat */
+
+/**
+ * struct ep93xx_keypad_platform_data - platform specific device structure
+ * @matrix_key_rows: number of rows in the keypad matrix
+ * @matrix_key_cols: number of columns in the keypad matrix
+ * @matrix_key_map: array of keycodes defining the keypad matrix
+ * @matrix_key_map_size: ARRAY_SIZE(matrix_key_map)
+ * @debounce: debounce start count; terminal count is 0xff
+ * @prescale: row/column counter pre-scaler load value
+ * @flags: see above
+ */
+struct ep93xx_keypad_platform_data {
+ unsigned int matrix_key_rows;
+ unsigned int matrix_key_cols;
+ unsigned int *matrix_key_map;
+ int matrix_key_map_size;
+ unsigned int debounce;
+ unsigned int prescale;
+ unsigned int flags;
+};
+
+/* macro for creating the matrix_key_map table */
+#define KEY(row, col, val) (((row) << 28) | ((col) << 24) | (val))
+
+#endif /* __ASM_ARCH_EP93XX_KEYPAD_H */
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
index 252310234903..7bb8e778e4b6 100644
--- a/arch/arm/mach-ixp4xx/ixp4xx_npe.c
+++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
@@ -714,7 +714,7 @@ static int __init npe_init_module(void)
}
if (!found)
- return -ENOSYS;
+ return -ENODEV;
return 0;
}
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
index e83e45ebf7a4..16295cfd5e29 100644
--- a/arch/arm/mach-mmp/include/mach/irqs.h
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -52,6 +52,7 @@
/*
* Interrupt numbers for PXA910
*/
+#define IRQ_PXA910_NONE (-1)
#define IRQ_PXA910_AIRQ 0
#define IRQ_PXA910_SSP3 1
#define IRQ_PXA910_SSP2 2
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
index d0bdb6e3682b..d4bd393a26b0 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
@@ -248,6 +248,10 @@
#define GPIO58_LCD_PCLK_WR MFP_CFG(GPIO58, AF1)
#define GPIO85_LCD_VSYNC MFP_CFG(GPIO85, AF1)
+/* I2C */
+#define GPIO105_CI2C_SDA MFP_CFG(GPIO105, AF1)
+#define GPIO106_CI2C_SCL MFP_CFG(GPIO106, AF1)
+
/* I2S */
#define GPIO113_I2S_MCLK MFP_CFG(GPIO113,AF6)
#define GPIO114_I2S_FRM MFP_CFG(GPIO114,AF1)
@@ -255,4 +259,27 @@
#define GPIO116_I2S_RXD MFP_CFG(GPIO116,AF2)
#define GPIO117_I2S_TXD MFP_CFG(GPIO117,AF2)
+/* PWM */
+#define GPIO96_PWM3_OUT MFP_CFG(GPIO96, AF1)
+#define GPIO97_PWM2_OUT MFP_CFG(GPIO97, AF1)
+#define GPIO98_PWM1_OUT MFP_CFG(GPIO98, AF1)
+#define GPIO104_PWM4_OUT MFP_CFG(GPIO104, AF1)
+#define GPIO106_PWM2_OUT MFP_CFG(GPIO106, AF2)
+#define GPIO74_PWM4_OUT MFP_CFG(GPIO74, AF2)
+#define GPIO75_PWM3_OUT MFP_CFG(GPIO75, AF2)
+#define GPIO76_PWM2_OUT MFP_CFG(GPIO76, AF2)
+#define GPIO77_PWM1_OUT MFP_CFG(GPIO77, AF2)
+#define GPIO82_PWM4_OUT MFP_CFG(GPIO82, AF2)
+#define GPIO83_PWM3_OUT MFP_CFG(GPIO83, AF2)
+#define GPIO84_PWM2_OUT MFP_CFG(GPIO84, AF2)
+#define GPIO85_PWM1_OUT MFP_CFG(GPIO85, AF2)
+#define GPIO84_PWM1_OUT MFP_CFG(GPIO84, AF4)
+#define GPIO122_PWM3_OUT MFP_CFG(GPIO122, AF3)
+#define GPIO123_PWM1_OUT MFP_CFG(GPIO123, AF1)
+#define GPIO124_PWM2_OUT MFP_CFG(GPIO124, AF1)
+#define GPIO125_PWM3_OUT MFP_CFG(GPIO125, AF1)
+#define GPIO126_PWM4_OUT MFP_CFG(GPIO126, AF1)
+#define GPIO86_PWM1_OUT MFP_CFG(GPIO86, AF2)
+#define GPIO86_PWM2_OUT MFP_CFG(GPIO86, AF3)
+
#endif /* __ASM_MACH_MFP_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
index 48a1cbc7c56b..1f1a53ea5817 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
@@ -154,4 +154,12 @@
#define MMC1_CD_MMC1_CD MFP_CFG_DRV(MMC1_CD, AF0, MEDIUM)
#define MMC1_WP_MMC1_WP MFP_CFG_DRV(MMC1_WP, AF0, MEDIUM)
+/* PWM */
+#define GPIO27 PWM3 AF2 MFP_CFG(GPIO27, AF2)
+#define GPIO51_PWM2_OUT MFP_CFG(GPIO51, AF2)
+#define GPIO117_PWM1_OUT MFP_CFG(GPIO117, AF2)
+#define GPIO118_PWM2_OUT MFP_CFG(GPIO118, AF2)
+#define GPIO119_PWM3_OUT MFP_CFG(GPIO119, AF2)
+#define GPIO120_PWM4_OUT MFP_CFG(GPIO120, AF2)
+
#endif /* __ASM_MACH MFP_PXA910_H */
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
index ef0a8a2076e9..6bf1f0eefcd1 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -1,10 +1,18 @@
#ifndef __ASM_MACH_PXA168_H
#define __ASM_MACH_PXA168_H
+#include <linux/i2c.h>
#include <mach/devices.h>
+#include <plat/i2c.h>
extern struct pxa_device_desc pxa168_device_uart1;
extern struct pxa_device_desc pxa168_device_uart2;
+extern struct pxa_device_desc pxa168_device_twsi0;
+extern struct pxa_device_desc pxa168_device_twsi1;
+extern struct pxa_device_desc pxa168_device_pwm1;
+extern struct pxa_device_desc pxa168_device_pwm2;
+extern struct pxa_device_desc pxa168_device_pwm3;
+extern struct pxa_device_desc pxa168_device_pwm4;
static inline int pxa168_add_uart(int id)
{
@@ -20,4 +28,40 @@ static inline int pxa168_add_uart(int id)
return pxa_register_device(d, NULL, 0);
}
+
+static inline int pxa168_add_twsi(int id, struct i2c_pxa_platform_data *data,
+ struct i2c_board_info *info, unsigned size)
+{
+ struct pxa_device_desc *d = NULL;
+ int ret;
+
+ switch (id) {
+ case 0: d = &pxa168_device_twsi0; break;
+ case 1: d = &pxa168_device_twsi1; break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = i2c_register_board_info(id, info, size);
+ if (ret)
+ return ret;
+
+ return pxa_register_device(d, data, sizeof(*data));
+}
+
+static inline int pxa168_add_pwm(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &pxa168_device_pwm1; break;
+ case 2: d = &pxa168_device_pwm2; break;
+ case 3: d = &pxa168_device_pwm3; break;
+ case 4: d = &pxa168_device_pwm4; break;
+ default:
+ return -EINVAL;
+ }
+
+ return pxa_register_device(d, NULL, 0);
+}
#endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h
index b7aeaf574c36..6ae1ed7a0a9f 100644
--- a/arch/arm/mach-mmp/include/mach/pxa910.h
+++ b/arch/arm/mach-mmp/include/mach/pxa910.h
@@ -1,10 +1,18 @@
#ifndef __ASM_MACH_PXA910_H
#define __ASM_MACH_PXA910_H
+#include <linux/i2c.h>
#include <mach/devices.h>
+#include <plat/i2c.h>
extern struct pxa_device_desc pxa910_device_uart1;
extern struct pxa_device_desc pxa910_device_uart2;
+extern struct pxa_device_desc pxa910_device_twsi0;
+extern struct pxa_device_desc pxa910_device_twsi1;
+extern struct pxa_device_desc pxa910_device_pwm1;
+extern struct pxa_device_desc pxa910_device_pwm2;
+extern struct pxa_device_desc pxa910_device_pwm3;
+extern struct pxa_device_desc pxa910_device_pwm4;
static inline int pxa910_add_uart(int id)
{
@@ -20,4 +28,40 @@ static inline int pxa910_add_uart(int id)
return pxa_register_device(d, NULL, 0);
}
+
+static inline int pxa910_add_twsi(int id, struct i2c_pxa_platform_data *data,
+ struct i2c_board_info *info, unsigned size)
+{
+ struct pxa_device_desc *d = NULL;
+ int ret;
+
+ switch (id) {
+ case 0: d = &pxa910_device_twsi0; break;
+ case 1: d = &pxa910_device_twsi1; break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = i2c_register_board_info(id, info, size);
+ if (ret)
+ return ret;
+
+ return pxa_register_device(d, data, sizeof(*data));
+}
+
+static inline int pxa910_add_pwm(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &pxa910_device_pwm1; break;
+ case 2: d = &pxa910_device_pwm2; break;
+ case 3: d = &pxa910_device_pwm3; break;
+ case 4: d = &pxa910_device_pwm4; break;
+ default:
+ return -EINVAL;
+ }
+
+ return pxa_register_device(d, NULL, 0);
+}
#endif /* __ASM_MACH_PXA910_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h
index c6b8c9dc2026..98ccbee4bd0c 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apbc.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h
@@ -22,8 +22,10 @@
#define APBC_PXA168_UART1 APBC_REG(0x000)
#define APBC_PXA168_UART2 APBC_REG(0x004)
#define APBC_PXA168_GPIO APBC_REG(0x008)
-#define APBC_PXA168_PWM0 APBC_REG(0x00c)
-#define APBC_PXA168_PWM1 APBC_REG(0x010)
+#define APBC_PXA168_PWM1 APBC_REG(0x00c)
+#define APBC_PXA168_PWM2 APBC_REG(0x010)
+#define APBC_PXA168_PWM3 APBC_REG(0x014)
+#define APBC_PXA168_PWM4 APBC_REG(0x018)
#define APBC_PXA168_SSP1 APBC_REG(0x01c)
#define APBC_PXA168_SSP2 APBC_REG(0x020)
#define APBC_PXA168_RTC APBC_REG(0x028)
@@ -48,10 +50,10 @@
#define APBC_PXA910_UART0 APBC_REG(0x000)
#define APBC_PXA910_UART1 APBC_REG(0x004)
#define APBC_PXA910_GPIO APBC_REG(0x008)
-#define APBC_PXA910_PWM0 APBC_REG(0x00c)
-#define APBC_PXA910_PWM1 APBC_REG(0x010)
-#define APBC_PXA910_PWM2 APBC_REG(0x014)
-#define APBC_PXA910_PWM3 APBC_REG(0x018)
+#define APBC_PXA910_PWM1 APBC_REG(0x00c)
+#define APBC_PXA910_PWM2 APBC_REG(0x010)
+#define APBC_PXA910_PWM3 APBC_REG(0x014)
+#define APBC_PXA910_PWM4 APBC_REG(0x018)
#define APBC_PXA910_SSP1 APBC_REG(0x01c)
#define APBC_PXA910_SSP2 APBC_REG(0x020)
#define APBC_PXA910_IPC APBC_REG(0x024)
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index ae924468658c..71b1ae338753 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -65,11 +65,23 @@ void __init pxa168_init_irq(void)
/* APB peripheral clocks */
static APBC_CLK(uart1, PXA168_UART1, 1, 14745600);
static APBC_CLK(uart2, PXA168_UART2, 1, 14745600);
+static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000);
+static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000);
+static APBC_CLK(pwm1, PXA168_PWM1, 1, 13000000);
+static APBC_CLK(pwm2, PXA168_PWM2, 1, 13000000);
+static APBC_CLK(pwm3, PXA168_PWM3, 1, 13000000);
+static APBC_CLK(pwm4, PXA168_PWM4, 1, 13000000);
/* device and clock bindings */
static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
+ INIT_CLKREG(&clk_pwm1, "pxa168-pwm.0", NULL),
+ INIT_CLKREG(&clk_pwm2, "pxa168-pwm.1", NULL),
+ INIT_CLKREG(&clk_pwm3, "pxa168-pwm.2", NULL),
+ INIT_CLKREG(&clk_pwm4, "pxa168-pwm.3", NULL),
};
static int __init pxa168_init(void)
@@ -109,3 +121,9 @@ struct sys_timer pxa168_timer = {
/* on-chip devices */
PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22);
PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24);
+PXA168_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28);
+PXA168_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28);
+PXA168_DEVICE(pwm1, "pxa168-pwm", 0, NONE, 0xd401a000, 0x10);
+PXA168_DEVICE(pwm2, "pxa168-pwm", 1, NONE, 0xd401a400, 0x10);
+PXA168_DEVICE(pwm3, "pxa168-pwm", 2, NONE, 0xd401a800, 0x10);
+PXA168_DEVICE(pwm4, "pxa168-pwm", 3, NONE, 0xd401ac00, 0x10);
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index 453f8f7758bf..5882ca6b49fb 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -103,11 +103,23 @@ void __init pxa910_init_irq(void)
/* APB peripheral clocks */
static APBC_CLK(uart1, PXA910_UART0, 1, 14745600);
static APBC_CLK(uart2, PXA910_UART1, 1, 14745600);
+static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000);
+static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000);
+static APBC_CLK(pwm1, PXA910_PWM1, 1, 13000000);
+static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000);
+static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
+static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
/* device and clock bindings */
static struct clk_lookup pxa910_clkregs[] = {
INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
+ INIT_CLKREG(&clk_pwm1, "pxa910-pwm.0", NULL),
+ INIT_CLKREG(&clk_pwm2, "pxa910-pwm.1", NULL),
+ INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL),
+ INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL),
};
static int __init pxa910_init(void)
@@ -156,3 +168,9 @@ struct sys_timer pxa910_timer = {
*/
PXA910_DEVICE(uart1, "pxa2xx-uart", 0, UART2, 0xd4017000, 0x30, 21, 22);
PXA910_DEVICE(uart2, "pxa2xx-uart", 1, UART3, 0xd4018000, 0x30, 23, 24);
+PXA910_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28);
+PXA910_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28);
+PXA910_DEVICE(pwm1, "pxa910-pwm", 0, NONE, 0xd401a000, 0x10);
+PXA910_DEVICE(pwm2, "pxa910-pwm", 1, NONE, 0xd401a400, 0x10);
+PXA910_DEVICE(pwm3, "pxa910-pwm", 2, NONE, 0xd401a800, 0x10);
+PXA910_DEVICE(pwm4, "pxa910-pwm", 3, NONE, 0xd401ac00, 0x10);
diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c
index 79df60c20e70..43da8bb4926b 100644
--- a/arch/arm/mach-netx/generic.c
+++ b/arch/arm/mach-netx/generic.c
@@ -168,7 +168,7 @@ void __init netx_init_irq(void)
{
int irq;
- vic_init(__io(io_p2v(NETX_PA_VIC)), 0, ~0);
+ vic_init(__io(io_p2v(NETX_PA_VIC)), 0, ~0, 0);
for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) {
set_irq_chip(irq, &netx_hif_chip);
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 3e66d9099eab..3b34f34db204 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -280,6 +280,7 @@ config MACH_ZYLONITE
select PXA3xx
select PXA_SSP
select HAVE_PWM
+ select PXA_HAVE_BOARD_IRQS
config MACH_LITTLETON
bool "PXA3xx Form Factor Platform (aka Littleton)"
@@ -289,12 +290,12 @@ config MACH_LITTLETON
config MACH_TAVOREVB
bool "PXA930 Evaluation Board (aka TavorEVB)"
select PXA3xx
- select PXA930
+ select CPU_PXA930
config MACH_SAAR
bool "PXA930 Handheld Platform (aka SAAR)"
select PXA3xx
- select PXA930
+ select CPU_PXA930
config MACH_ARMCORE
bool "CompuLab CM-X255/CM-X270 modules"
@@ -505,12 +506,6 @@ config PXA_SSP
help
Enable support for PXA2xx SSP ports
-config PXA_PWM
- tristate
- default BACKLIGHT_PWM
- help
- Enable support for PXA2xx/PXA3xx PWM controllers
-
config TOSA_BT
tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
depends on MACH_TOSA
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 682dbf4e14b0..47d01572a04d 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -15,7 +15,6 @@ endif
# Generic drivers that other drivers may depend upon
obj-$(CONFIG_PXA_SSP) += ssp.o
-obj-$(CONFIG_PXA_PWM) += pwm.o
# SoC-specific code
obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index a9f48b1cb54a..a97f87a90d0d 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -32,7 +32,7 @@
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/ohci.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/pxa3xx_nand.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 930e364ccde9..962dda2e154a 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -42,7 +42,7 @@
#include <asm/mach/irq.h>
#include <mach/pxa25x.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/irda.h>
#include <mach/mmc.h>
#include <mach/udc.h>
@@ -445,13 +445,8 @@ static struct ads7846_platform_data corgi_ads7846_info = {
.wait_for_sync = corgi_wait_for_hsync,
};
-static void corgi_ads7846_cs(u32 command)
-{
- gpio_set_value(CORGI_GPIO_ADS7846_CS, !(command == PXA2XX_CS_ASSERT));
-}
-
static struct pxa2xx_spi_chip corgi_ads7846_chip = {
- .cs_control = corgi_ads7846_cs,
+ .gpio_cs = CORGI_GPIO_ADS7846_CS,
};
static void corgi_bl_kick_battery(void)
@@ -475,22 +470,12 @@ static struct corgi_lcd_platform_data corgi_lcdcon_info = {
.kick_battery = corgi_bl_kick_battery,
};
-static void corgi_lcdcon_cs(u32 command)
-{
- gpio_set_value(CORGI_GPIO_LCDCON_CS, !(command == PXA2XX_CS_ASSERT));
-}
-
static struct pxa2xx_spi_chip corgi_lcdcon_chip = {
- .cs_control = corgi_lcdcon_cs,
+ .gpio_cs = CORGI_GPIO_LCDCON_CS,
};
-static void corgi_max1111_cs(u32 command)
-{
- gpio_set_value(CORGI_GPIO_MAX1111_CS, !(command == PXA2XX_CS_ASSERT));
-}
-
static struct pxa2xx_spi_chip corgi_max1111_chip = {
- .cs_control = corgi_max1111_cs,
+ .gpio_cs = CORGI_GPIO_MAX1111_CS,
};
static struct spi_board_info corgi_spi_devices[] = {
@@ -520,32 +505,8 @@ static struct spi_board_info corgi_spi_devices[] = {
static void __init corgi_init_spi(void)
{
- int err;
-
- err = gpio_request(CORGI_GPIO_ADS7846_CS, "ADS7846_CS");
- if (err)
- return;
-
- err = gpio_request(CORGI_GPIO_LCDCON_CS, "LCDCON_CS");
- if (err)
- goto err_free_1;
-
- err = gpio_request(CORGI_GPIO_MAX1111_CS, "MAX1111_CS");
- if (err)
- goto err_free_2;
-
- gpio_direction_output(CORGI_GPIO_ADS7846_CS, 1);
- gpio_direction_output(CORGI_GPIO_LCDCON_CS, 1);
- gpio_direction_output(CORGI_GPIO_MAX1111_CS, 1);
-
pxa2xx_set_spi_info(1, &corgi_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices));
- return;
-
-err_free_2:
- gpio_free(CORGI_GPIO_LCDCON_CS);
-err_free_1:
- gpio_free(CORGI_GPIO_ADS7846_CS);
}
#else
static inline void corgi_init_spi(void) {}
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
index 2b289f83a61a..a7854e44d618 100644
--- a/arch/arm/mach-pxa/csb726.c
+++ b/arch/arm/mach-pxa/csb726.c
@@ -16,15 +16,17 @@
#include <linux/mtd/physmap.h>
#include <linux/mtd/partitions.h>
#include <linux/sm501.h>
+#include <linux/smsc911x.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/csb726.h>
#include <mach/mfp-pxa27x.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/mmc.h>
#include <mach/ohci.h>
#include <mach/pxa2xx-regs.h>
+#include <mach/audio.h>
#include "generic.h"
#include "devices.h"
@@ -275,13 +277,22 @@ static struct resource csb726_lan_resources[] = {
{
.start = CSB726_IRQ_LAN,
.end = CSB726_IRQ_LAN,
- .flags = IORESOURCE_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
},
};
+struct smsc911x_platform_config csb726_lan_config = {
+ .irq_type = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_32BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+
static struct platform_device csb726_lan = {
- .name = "smc911x",
+ .name = "smsc911x",
.id = -1,
+ .platform_data = &csb726_lan_config,
.num_resources = ARRAY_SIZE(csb726_lan_resources),
.resource = csb726_lan_resources,
};
@@ -303,6 +314,7 @@ static void __init csb726_init(void)
pxa27x_set_i2c_power_info(NULL);
pxa_set_mci_info(&csb726_mci);
pxa_set_ohci_info(&csb726_ohci_platform_data);
+ pxa_set_ac97_info(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index d245e59c51b1..d3c3b7b025ae 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -8,7 +8,7 @@
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/irda.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/ohci.h>
#include <mach/pxa27x_keypad.h>
#include <mach/pxa2xx_spi.h>
@@ -287,7 +287,7 @@ static struct resource pxa3xx_resources_i2c_power[] = {
};
struct platform_device pxa3xx_device_i2c_power = {
- .name = "pxa2xx-i2c",
+ .name = "pxa3xx-pwri2c",
.id = 1,
.resource = pxa3xx_resources_i2c_power,
.num_resources = ARRAY_SIZE(pxa3xx_resources_i2c_power),
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index bc0f73fbd4ca..3503f523070b 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -41,7 +41,7 @@
#include <mach/ohci.h>
#include <mach/mmc.h>
#include <mach/pxa27x_keypad.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/camera.h>
#include <mach/pxa2xx_spi.h>
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
index 92ba16e1b6fc..afc214a417bb 100644
--- a/arch/arm/mach-pxa/ezx.c
+++ b/arch/arm/mach-pxa/ezx.c
@@ -25,7 +25,7 @@
#include <mach/pxa27x.h>
#include <mach/pxafb.h>
#include <mach/ohci.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/hardware.h>
#include <mach/pxa27x_keypad.h>
diff --git a/arch/arm/mach-pxa/imote2.c b/arch/arm/mach-pxa/imote2.c
index 2121309b2474..3ef98d43d303 100644
--- a/arch/arm/mach-pxa/imote2.c
+++ b/arch/arm/mach-pxa/imote2.c
@@ -29,7 +29,7 @@
#include <asm/mach/flash.h>
#include <mach/pxa27x.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/udc.h>
#include <mach/mmc.h>
#include <mach/pxa2xx_spi.h>
@@ -456,25 +456,12 @@ static struct pxa2xx_spi_master pxa_ssp_master_2_info = {
.num_chipselect = 1,
};
-/* Patch posted by Eric Miao <eric.miao@marvell.com> will remove
- * the need for these functions.
- */
-static void spi1control(u32 command)
-{
- gpio_set_value(24, command & PXA2XX_CS_ASSERT ? 0 : 1);
-};
-
-static void spi3control(u32 command)
-{
- gpio_set_value(39, command & PXA2XX_CS_ASSERT ? 0 : 1);
-};
-
static struct pxa2xx_spi_chip staccel_chip_info = {
.tx_threshold = 8,
.rx_threshold = 8,
.dma_burst_size = 8,
.timeout = 235,
- .cs_control = spi1control,
+ .gpio_cs = 24,
};
static struct pxa2xx_spi_chip cc2420_info = {
@@ -482,7 +469,7 @@ static struct pxa2xx_spi_chip cc2420_info = {
.rx_threshold = 8,
.dma_burst_size = 8,
.timeout = 235,
- .cs_control = spi3control,
+ .gpio_cs = 39,
};
static struct spi_board_info spi_board_info[] __initdata = {
@@ -538,8 +525,6 @@ static void __init imote2_init(void)
/* SPI chip select directions - all other directions should
* be handled by drivers.*/
gpio_direction_output(37, 0);
- gpio_direction_output(24, 0);
- gpio_direction_output(39, 0);
platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices));
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index 32bb4a2eb7f1..ebf38bbb347f 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -91,13 +91,21 @@
#define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i))
/*
- * The next 16 interrupts are for board specific purposes. Since
+ * The following interrupts are for board specific purposes. Since
* the kernel can only run on one machine at a time, we can re-use
- * these. If you need more, increase IRQ_BOARD_END, but keep it
- * within sensible limits.
+ * these. There will be 16 IRQs by default. If it is not enough,
+ * IRQ_BOARD_END is allowed be customized for each board, but keep
+ * the numbers within sensible limits and in descending order, so
+ * when multiple config options are selected, the maximum will be
+ * used.
*/
#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM)
+
+#if defined(CONFIG_MACH_ZYLONITE)
+#define IRQ_BOARD_END (IRQ_BOARD_START + 32)
+#else
#define IRQ_BOARD_END (IRQ_BOARD_START + 16)
+#endif
#define IRQ_SA1111_START (IRQ_BOARD_END)
#define IRQ_GPAIN0 (IRQ_BOARD_END + 0)
@@ -188,8 +196,6 @@
#define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1)
#elif defined(CONFIG_PXA_HAVE_BOARD_IRQS)
#define NR_IRQS (IRQ_BOARD_END)
-#elif defined(CONFIG_MACH_ZYLONITE)
-#define NR_IRQS (IRQ_BOARD_START + 32)
#else
#define NR_IRQS (IRQ_BOARD_START)
#endif
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index c872b9feb4d4..94a32321ad43 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -43,7 +43,7 @@
#include <mach/pxafb.h>
#include <mach/ssp.h>
#include <mach/pxa2xx_spi.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/pxa27x_keypad.h>
#include <mach/pxa3xx_nand.h>
#include <mach/littleton.h>
@@ -179,15 +179,10 @@ static struct pxa2xx_spi_master littleton_spi_info = {
.num_chipselect = 1,
};
-static void littleton_tdo24m_cs(u32 cmd)
-{
- gpio_set_value(LITTLETON_GPIO_LCD_CS, !(cmd == PXA2XX_CS_ASSERT));
-}
-
static struct pxa2xx_spi_chip littleton_tdo24m_chip = {
.rx_threshold = 1,
.tx_threshold = 1,
- .cs_control = littleton_tdo24m_cs,
+ .gpio_cs = LITTLETON_GPIO_LCD_CS,
};
static struct spi_board_info littleton_spi_devices[] __initdata = {
@@ -202,16 +197,6 @@ static struct spi_board_info littleton_spi_devices[] __initdata = {
static void __init littleton_init_spi(void)
{
- int err;
-
- err = gpio_request(LITTLETON_GPIO_LCD_CS, "LCD_CS");
- if (err) {
- pr_warning("failed to request GPIO for LCS CS\n");
- return;
- }
-
- gpio_direction_output(LITTLETON_GPIO_LCD_CS, 1);
-
pxa2xx_set_spi_info(2, &littleton_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(littleton_spi_devices));
}
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index c899bbd94dc0..34046c8bfaf5 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -36,7 +36,7 @@
#include <mach/pxa27x.h>
#include <mach/magician.h>
#include <mach/pxafb.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
@@ -745,6 +745,14 @@ static struct platform_device strataflash = {
};
/*
+ * I2C
+ */
+
+static struct i2c_pxa_platform_data i2c_info = {
+ .fast_mode = 1,
+};
+
+/*
* Platform devices
*/
@@ -779,7 +787,7 @@ static void __init magician_init(void)
pxa_set_ficp_info(&magician_ficp_info);
}
pxa27x_set_i2c_power_info(NULL);
- pxa_set_i2c_info(NULL);
+ pxa_set_i2c_info(&i2c_info);
pxa_set_mci_info(&magician_mci_info);
pxa_set_ohci_info(&magician_ohci_info);
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index a6c8429e975f..f4dabf0273ca 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -46,7 +46,7 @@
#include <mach/mainstone.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index ff8052ce0a05..804c25c4a064 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -48,7 +48,7 @@
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/pxa27x-udc.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/camera.h>
#include <mach/audio.h>
#include <media/soc_camera.h>
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 30662363907b..1a1d8208b73d 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -26,6 +26,7 @@
#include <linux/gpio.h>
#include <linux/wm97xx_batt.h>
#include <linux/power_supply.h>
+#include <linux/usb/gpio_vbus.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -342,11 +343,18 @@ static struct pxaficp_platform_data palmt5_ficp_platform_data = {
/******************************************************************************
* UDC
******************************************************************************/
-static struct pxa2xx_udc_mach_info palmt5_udc_info __initdata = {
+static struct gpio_vbus_mach_info palmt5_udc_info = {
.gpio_vbus = GPIO_NR_PALMT5_USB_DETECT_N,
.gpio_vbus_inverted = 1,
.gpio_pullup = GPIO_NR_PALMT5_USB_PULLUP,
- .gpio_pullup_inverted = 0,
+};
+
+static struct platform_device palmt5_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmt5_udc_info,
+ },
};
/******************************************************************************
@@ -499,6 +507,7 @@ static struct platform_device *devices[] __initdata = {
&palmt5_backlight,
&power_supply,
&palmt5_asoc,
+ &palmt5_gpio_vbus,
};
/* setup udc GPIOs initial state */
@@ -518,7 +527,6 @@ static void __init palmt5_init(void)
pxa_set_mci_info(&palmt5_mci_platform_data);
palmt5_udc_init();
pxa_set_ac97_info(&palmt5_ac97_pdata);
- pxa_set_udc_info(&palmt5_udc_info);
pxa_set_ficp_info(&palmt5_ficp_platform_data);
pxa_set_keypad_info(&palmt5_keypad_platform_data);
wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index 43fcf2e86887..d823b09801df 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -25,6 +25,7 @@
#include <linux/gpio.h>
#include <linux/wm97xx_batt.h>
#include <linux/power_supply.h>
+#include <linux/usb/gpio_vbus.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -37,6 +38,7 @@
#include <mach/mfp-pxa25x.h>
#include <mach/irda.h>
#include <mach/udc.h>
+#include <mach/palmasoc.h>
#include "generic.h"
#include "devices.h"
@@ -107,6 +109,7 @@ static unsigned long palmte2_pin_config[] __initdata = {
GPIO1_RST, /* reset */
GPIO4_GPIO, /* Hotsync button */
GPIO9_GPIO, /* power detect */
+ GPIO15_GPIO, /* earphone detect */
GPIO37_GPIO, /* LCD power */
GPIO56_GPIO, /* Backlight power */
};
@@ -318,11 +321,18 @@ static struct pxaficp_platform_data palmte2_ficp_platform_data = {
/******************************************************************************
* UDC
******************************************************************************/
-static struct pxa2xx_udc_mach_info palmte2_udc_info __initdata = {
+static struct gpio_vbus_mach_info palmte2_udc_info = {
.gpio_vbus = GPIO_NR_PALMTE2_USB_DETECT_N,
.gpio_vbus_inverted = 1,
.gpio_pullup = GPIO_NR_PALMTE2_USB_PULLUP,
- .gpio_pullup_inverted = 0,
+};
+
+static struct platform_device palmte2_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte2_udc_info,
+ },
};
/******************************************************************************
@@ -395,6 +405,21 @@ static struct wm97xx_batt_info wm97xx_batt_pdata = {
};
/******************************************************************************
+ * aSoC audio
+ ******************************************************************************/
+static struct palm27x_asoc_info palmte2_asoc_pdata = {
+ .jack_gpio = GPIO_NR_PALMTE2_EARPHONE_DETECT,
+};
+
+static struct platform_device palmte2_asoc = {
+ .name = "palm27x-asoc",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte2_asoc_pdata,
+ },
+};
+
+/******************************************************************************
* Framebuffer
******************************************************************************/
static struct pxafb_mode_info palmte2_lcd_modes[] = {
@@ -429,6 +454,8 @@ static struct platform_device *devices[] __initdata = {
#endif
&palmte2_backlight,
&power_supply,
+ &palmte2_asoc,
+ &palmte2_gpio_vbus,
};
/* setup udc GPIOs initial state */
@@ -447,7 +474,6 @@ static void __init palmte2_init(void)
set_pxa_fb_info(&palmte2_lcd_screen);
pxa_set_mci_info(&palmte2_mci_platform_data);
palmte2_udc_init();
- pxa_set_udc_info(&palmte2_udc_info);
pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&palmte2_ficp_platform_data);
wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index e2d44b1a8a9b..81da4396fb07 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -27,6 +27,7 @@
#include <linux/gpio.h>
#include <linux/wm97xx_batt.h>
#include <linux/power_supply.h>
+#include <linux/usb/gpio_vbus.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -358,11 +359,18 @@ static struct pxaficp_platform_data palmtx_ficp_platform_data = {
/******************************************************************************
* UDC
******************************************************************************/
-static struct pxa2xx_udc_mach_info palmtx_udc_info __initdata = {
+static struct gpio_vbus_mach_info palmtx_udc_info = {
.gpio_vbus = GPIO_NR_PALMTX_USB_DETECT_N,
.gpio_vbus_inverted = 1,
.gpio_pullup = GPIO_NR_PALMTX_USB_PULLUP,
- .gpio_pullup_inverted = 0,
+};
+
+static struct platform_device palmtx_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtx_udc_info,
+ },
};
/******************************************************************************
@@ -516,6 +524,7 @@ static struct platform_device *devices[] __initdata = {
&palmtx_backlight,
&power_supply,
&palmtx_asoc,
+ &palmtx_gpio_vbus,
};
static struct map_desc palmtx_io_desc[] __initdata = {
@@ -551,7 +560,6 @@ static void __init palmtx_init(void)
pxa_set_mci_info(&palmtx_mci_platform_data);
palmtx_udc_init();
pxa_set_ac97_info(&palmtx_ac97_pdata);
- pxa_set_udc_info(&palmtx_udc_info);
pxa_set_ficp_info(&palmtx_ficp_platform_data);
pxa_set_keypad_info(&palmtx_keypad_platform_data);
wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 6c12b5a3132f..01791d74e08e 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -28,7 +28,7 @@
#include <media/soc_camera.h>
#include <asm/gpio.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/camera.h>
#include <asm/mach/map.h>
#include <mach/pxa27x.h>
@@ -380,12 +380,12 @@ static struct pca953x_platform_data pca9536_data = {
.gpio_base = NR_BUILTIN_GPIO,
};
-static int gpio_bus_switch;
+static int gpio_bus_switch = -EINVAL;
static int pcm990_camera_set_bus_param(struct soc_camera_link *link,
- unsigned long flags)
+ unsigned long flags)
{
- if (gpio_bus_switch <= 0) {
+ if (gpio_bus_switch < 0) {
if (flags == SOCAM_DATAWIDTH_10)
return 0;
else
@@ -404,25 +404,34 @@ static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link)
{
int ret;
- if (!gpio_bus_switch) {
+ if (gpio_bus_switch < 0) {
ret = gpio_request(NR_BUILTIN_GPIO, "camera");
if (!ret) {
gpio_bus_switch = NR_BUILTIN_GPIO;
gpio_direction_output(gpio_bus_switch, 0);
- } else
- gpio_bus_switch = -EINVAL;
+ }
}
- if (gpio_bus_switch > 0)
+ if (gpio_bus_switch >= 0)
return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10;
else
return SOCAM_DATAWIDTH_10;
}
+static void pcm990_camera_free_bus(struct soc_camera_link *link)
+{
+ if (gpio_bus_switch < 0)
+ return;
+
+ gpio_free(gpio_bus_switch);
+ gpio_bus_switch = -EINVAL;
+}
+
static struct soc_camera_link iclink = {
.bus_id = 0, /* Must match with the camera ID above */
.query_bus_param = pcm990_camera_query_bus_param,
.set_bus_param = pcm990_camera_set_bus_param,
+ .free_bus = pcm990_camera_free_bus,
};
/* Board I2C devices. */
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 036bbde4d221..ac431ed10399 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -39,7 +39,7 @@
#include <mach/pxa25x.h>
#include <mach/mmc.h>
#include <mach/udc.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/irda.h>
#include <mach/poodle.h>
#include <mach/pxafb.h>
@@ -214,13 +214,8 @@ static struct ads7846_platform_data poodle_ads7846_info = {
.gpio_pendown = POODLE_GPIO_TP_INT,
};
-static void ads7846_cs(u32 command)
-{
- gpio_set_value(POODLE_GPIO_TP_CS, !(command == PXA2XX_CS_ASSERT));
-}
-
static struct pxa2xx_spi_chip poodle_ads7846_chip = {
- .cs_control = ads7846_cs,
+ .gpio_cs = POODLE_GPIO_TP_CS,
};
static struct spi_board_info poodle_spi_devices[] = {
@@ -236,14 +231,6 @@ static struct spi_board_info poodle_spi_devices[] = {
static void __init poodle_init_spi(void)
{
- int err;
-
- err = gpio_request(POODLE_GPIO_TP_CS, "ADS7846_CS");
- if (err)
- return;
-
- gpio_direction_output(POODLE_GPIO_TP_CS, 1);
-
pxa2xx_set_spi_info(1, &poodle_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices));
}
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index a425ec71e657..c54ad8b3343c 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -27,7 +27,7 @@
#include <mach/ohci.h>
#include <mach/pm.h>
#include <mach/dma.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include "generic.h"
#include "devices.h"
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index b02d4544dc95..6f678d93bf4e 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -30,7 +30,7 @@
#include <mach/pm.h>
#include <mach/dma.h>
#include <mach/ssp.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include "generic.h"
#include "devices.h"
@@ -552,7 +552,7 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
}
static struct platform_device *devices[] __initdata = {
-/* &pxa_device_udc, The UDC driver is PXA25x only */
+ &pxa27x_device_udc,
&pxa_device_ffuart,
&pxa_device_btuart,
&pxa_device_stuart,
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
index ff8239991430..8241a63ea589 100644
--- a/arch/arm/mach-pxa/saar.c
+++ b/arch/arm/mach-pxa/saar.c
@@ -27,7 +27,7 @@
#include <asm/mach/arch.h>
#include <mach/pxa930.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/pxafb.h>
#include "devices.h"
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index c18e34acafcb..660ea4a75d8b 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -47,7 +47,7 @@
#include <mach/pxa27x.h>
#include <mach/pxa27x-udc.h>
#include <mach/reset.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/irda.h>
#include <mach/mmc.h>
#include <mach/ohci.h>
@@ -317,13 +317,8 @@ static struct ads7846_platform_data spitz_ads7846_info = {
.wait_for_sync = spitz_wait_for_hsync,
};
-static void spitz_ads7846_cs(u32 command)
-{
- gpio_set_value(SPITZ_GPIO_ADS7846_CS, !(command == PXA2XX_CS_ASSERT));
-}
-
static struct pxa2xx_spi_chip spitz_ads7846_chip = {
- .cs_control = spitz_ads7846_cs,
+ .gpio_cs = SPITZ_GPIO_ADS7846_CS,
};
static void spitz_bl_kick_battery(void)
@@ -347,22 +342,12 @@ static struct corgi_lcd_platform_data spitz_lcdcon_info = {
.kick_battery = spitz_bl_kick_battery,
};
-static void spitz_lcdcon_cs(u32 command)
-{
- gpio_set_value(SPITZ_GPIO_LCDCON_CS, !(command == PXA2XX_CS_ASSERT));
-}
-
static struct pxa2xx_spi_chip spitz_lcdcon_chip = {
- .cs_control = spitz_lcdcon_cs,
+ .gpio_cs = SPITZ_GPIO_LCDCON_CS,
};
-static void spitz_max1111_cs(u32 command)
-{
- gpio_set_value(SPITZ_GPIO_MAX1111_CS, !(command == PXA2XX_CS_ASSERT));
-}
-
static struct pxa2xx_spi_chip spitz_max1111_chip = {
- .cs_control = spitz_max1111_cs,
+ .gpio_cs = SPITZ_GPIO_MAX1111_CS,
};
static struct spi_board_info spitz_spi_devices[] = {
@@ -392,30 +377,6 @@ static struct spi_board_info spitz_spi_devices[] = {
static void __init spitz_init_spi(void)
{
- int err;
-
- err = gpio_request(SPITZ_GPIO_ADS7846_CS, "ADS7846_CS");
- if (err)
- return;
-
- err = gpio_request(SPITZ_GPIO_LCDCON_CS, "LCDCON_CS");
- if (err)
- goto err_free_1;
-
- err = gpio_request(SPITZ_GPIO_MAX1111_CS, "MAX1111_CS");
- if (err)
- goto err_free_2;
-
- err = gpio_direction_output(SPITZ_GPIO_ADS7846_CS, 1);
- if (err)
- goto err_free_3;
- err = gpio_direction_output(SPITZ_GPIO_LCDCON_CS, 1);
- if (err)
- goto err_free_3;
- err = gpio_direction_output(SPITZ_GPIO_MAX1111_CS, 1);
- if (err)
- goto err_free_3;
-
if (machine_is_akita()) {
spitz_lcdcon_info.gpio_backlight_cont = AKITA_GPIO_BACKLIGHT_CONT;
spitz_lcdcon_info.gpio_backlight_on = AKITA_GPIO_BACKLIGHT_ON;
@@ -423,14 +384,6 @@ static void __init spitz_init_spi(void)
pxa2xx_set_spi_info(2, &spitz_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
- return;
-
-err_free_3:
- gpio_free(SPITZ_GPIO_MAX1111_CS);
-err_free_2:
- gpio_free(SPITZ_GPIO_LCDCON_CS);
-err_free_1:
- gpio_free(SPITZ_GPIO_ADS7846_CS);
}
#else
static inline void spitz_init_spi(void) {}
diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c
index fb0294bd4310..bde42aa29374 100644
--- a/arch/arm/mach-pxa/tosa-bt.c
+++ b/arch/arm/mach-pxa/tosa-bt.c
@@ -38,9 +38,9 @@ static void tosa_bt_off(struct tosa_bt_data *data)
static int tosa_bt_toggle_radio(void *data, enum rfkill_state state)
{
pr_info("BT_RADIO going: %s\n",
- state == RFKILL_STATE_ON ? "on" : "off");
+ state == RFKILL_STATE_UNBLOCKED ? "on" : "off");
- if (state == RFKILL_STATE_ON) {
+ if (state == RFKILL_STATE_UNBLOCKED) {
pr_info("TOSA_BT: going ON\n");
tosa_bt_on(data);
} else {
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index afac5b6d3d78..196eebf06279 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -40,7 +40,7 @@
#include <mach/pxa25x.h>
#include <mach/reset.h>
#include <mach/irda.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/tosa_bt.h>
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index f79c9cb70ae4..825f540176d2 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -47,7 +47,7 @@
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include "generic.h"
#include "devices.h"
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 0e65344e9f53..af7c303171d7 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -45,7 +45,7 @@
#include <mach/pxa25x.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/viper.h>
#include <asm/setup.h>
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
index c256c57642c0..cefd1c0a854a 100644
--- a/arch/arm/mach-pxa/zylonite_pxa300.c
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -21,7 +21,7 @@
#include <linux/gpio.h>
#include <mach/pxa300.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
#include <mach/zylonite.h>
#include "generic.h"
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 63a30d1dd425..41bb65d5b91f 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -59,6 +59,7 @@ config ARCH_H1940
bool "IPAQ H1940"
select CPU_S3C2410
select PM_H1940 if PM
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the HP IPAQ H1940
@@ -70,6 +71,7 @@ config PM_H1940
config MACH_N30
bool "Acer N30 family"
select CPU_S3C2410
+ select S3C_DEV_USB_HOST
help
Say Y here if you want suppt for the Acer N30, Acer N35,
Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.
@@ -82,6 +84,7 @@ config ARCH_BAST
select MACH_BAST_IDE
select S3C24XX_DCLK
select ISA
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Simtec Electronics EB2410ITX
development board (also known as BAST)
@@ -89,6 +92,7 @@ config ARCH_BAST
config MACH_OTOM
bool "NexVision OTOM Board"
select CPU_S3C2410
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Nex Vision OTOM board
@@ -96,6 +100,7 @@ config MACH_AML_M5900
bool "AML M5900 Series"
select CPU_S3C2410
select PM_SIMTEC if PM
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the American Microsystems M5900 Series
<http://www.amltd.com>
@@ -111,6 +116,7 @@ config BAST_PC104_IRQ
config MACH_TCT_HAMMER
bool "TCT Hammer Board"
select CPU_S3C2410
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the TinCanTools Hammer Board
<http://www.tincantools.com>
@@ -122,12 +128,14 @@ config MACH_VR1000
select SIMTEC_NOR
select MACH_BAST_IDE
select CPU_S3C2410
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Thorcom VR1000 board.
config MACH_QT2410
bool "QT2410"
select CPU_S3C2410
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Armzone QT2410
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
index 255fdfeaf957..e99b212cb1ca 100644
--- a/arch/arm/mach-s3c2410/include/mach/map.h
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -84,7 +84,6 @@
#define S3C24XX_PA_IRQ S3C2410_PA_IRQ
#define S3C24XX_PA_MEMCTRL S3C2410_PA_MEMCTRL
-#define S3C24XX_PA_USBHOST S3C2410_PA_USBHOST
#define S3C24XX_PA_DMA S3C2410_PA_DMA
#define S3C24XX_PA_CLKPWR S3C2410_PA_CLKPWR
#define S3C24XX_PA_LCD S3C2410_PA_LCD
@@ -102,6 +101,7 @@
#define S3C_PA_IIC S3C2410_PA_IIC
#define S3C_PA_UART S3C24XX_PA_UART
+#define S3C_PA_USBHOST S3C2410_PA_USBHOST
#define S3C_PA_HSMMC0 S3C2443_PA_HSMMC
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index ca99564ae4b5..63586ffd0ae7 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -38,6 +38,7 @@ menu "S3C2412 Machines"
config MACH_JIVE
bool "Logitech Jive"
select CPU_S3C2412
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Logitech Jive.
@@ -50,6 +51,7 @@ config MACH_SMDK2413
select CPU_S3C2412
select MACH_S3C2413
select MACH_SMDK
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using an SMDK2413
@@ -72,6 +74,7 @@ config MACH_SMDK2412
config MACH_VSTMS
bool "VMSTMS"
select CPU_S3C2412
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using an VSTMS board
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c
index c9cfe40e21f6..a7417c479ffe 100644
--- a/arch/arm/mach-s3c2412/pm.c
+++ b/arch/arm/mach-s3c2412/pm.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <mach/hardware.h>
+#include <asm/cacheflush.h>
#include <asm/irq.h>
#include <mach/regs-power.h>
@@ -39,6 +40,8 @@ static void s3c2412_cpu_suspend(void)
{
unsigned long tmp;
+ flush_cache_all();
+
/* set our standby method to sleep */
tmp = __raw_readl(S3C2412_PWRCFG);
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index cde5ae9a4340..5df73cbf2b40 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -33,6 +33,7 @@ config MACH_ANUBIS
select PM_SIMTEC if PM
select HAVE_PATA_PLATFORM
select S3C24XX_GPIO_EXTRA64
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Simtec Electronics ANUBIS
development system
@@ -43,6 +44,7 @@ config MACH_OSIRIS
select S3C24XX_DCLK
select PM_SIMTEC if PM
select S3C24XX_GPIO_EXTRA128
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Simtec IM2440D20 module, also
known as the Osiris.
@@ -58,12 +60,14 @@ config ARCH_S3C2440
bool "SMDK2440"
select CPU_S3C2440
select MACH_SMDK
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the SMDK2440.
config MACH_NEXCODER_2440
bool "NexVision NEXCODER 2440 Light Board"
select CPU_S3C2440
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
@@ -76,6 +80,7 @@ config SMDK2440_CPU2440
config MACH_AT2440EVB
bool "Avantech AT2440EVB development board"
select CPU_S3C2440
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the AT2440EVB development board
diff --git a/arch/arm/mach-s3c6400/include/mach/map.h b/arch/arm/mach-s3c6400/include/mach/map.h
index baf1c0f1ea5a..46acb9259f41 100644
--- a/arch/arm/mach-s3c6400/include/mach/map.h
+++ b/arch/arm/mach-s3c6400/include/mach/map.h
@@ -40,6 +40,8 @@
#define S3C64XX_PA_FB (0x77100000)
#define S3C64XX_PA_SYSCON (0x7E00F000)
+#define S3C64XX_PA_IIS0 (0x7F002000)
+#define S3C64XX_PA_IIS1 (0x7F003000)
#define S3C64XX_PA_TIMER (0x7F006000)
#define S3C64XX_PA_IIC0 (0x7F004000)
#define S3C64XX_PA_IIC1 (0x7F00F000)
@@ -55,6 +57,8 @@
#define S3C64XX_PA_MODEM (0x74108000)
#define S3C64XX_VA_MODEM S3C_ADDR(0x00600000)
+#define S3C64XX_PA_USBHOST (0x74300000)
+
/* place VICs close together */
#define S3C_VA_VIC0 (S3C_VA_IRQ + 0x00)
#define S3C_VA_VIC1 (S3C_VA_IRQ + 0x10000)
@@ -67,5 +71,6 @@
#define S3C_PA_IIC S3C64XX_PA_IIC0
#define S3C_PA_IIC1 S3C64XX_PA_IIC1
#define S3C_PA_FB S3C64XX_PA_FB
+#define S3C_PA_USBHOST S3C64XX_PA_USBHOST
#endif /* __ASM_ARCH_6400_MAP_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/regs-clock.h b/arch/arm/mach-s3c6400/include/mach/regs-clock.h
new file mode 100644
index 000000000000..a6c7f4eb3a1b
--- /dev/null
+++ b/arch/arm/mach-s3c6400/include/mach/regs-clock.h
@@ -0,0 +1,16 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/regs-clock.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - clock register compatibility with s3c24xx
+ *
+ * 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 <plat/regs-clock.h>
+
diff --git a/arch/arm/mach-s3c6410/Kconfig b/arch/arm/mach-s3c6410/Kconfig
index 1d5010070027..0c8df9797e55 100644
--- a/arch/arm/mach-s3c6410/Kconfig
+++ b/arch/arm/mach-s3c6410/Kconfig
@@ -26,6 +26,7 @@ config MACH_SMDK6410
select S3C_DEV_HSMMC1
select S3C_DEV_I2C1
select S3C_DEV_FB
+ select S3C_DEV_USB_HOST
select S3C6410_SETUP_SDHCI
select S3C64XX_SETUP_I2C1
select S3C64XX_SETUP_FB_24BPP
diff --git a/arch/arm/mach-s3c6410/mach-smdk6410.c b/arch/arm/mach-s3c6410/mach-smdk6410.c
index 7f473e47e4f1..678b728fee12 100644
--- a/arch/arm/mach-s3c6410/mach-smdk6410.c
+++ b/arch/arm/mach-s3c6410/mach-smdk6410.c
@@ -141,6 +141,7 @@ static struct platform_device *smdk6410_devices[] __initdata = {
&s3c_device_i2c0,
&s3c_device_i2c1,
&s3c_device_fb,
+ &s3c_device_usb,
&smdk6410_lcd_powerdev,
};
diff --git a/arch/arm/mach-stmp378x/Makefile b/arch/arm/mach-stmp378x/Makefile
new file mode 100644
index 000000000000..d156f76b379f
--- /dev/null
+++ b/arch/arm/mach-stmp378x/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARCH_STMP378X) += stmp378x.o
+obj-$(CONFIG_MACH_STMP378X) += stmp378x_devb.o
diff --git a/arch/arm/mach-stmp378x/Makefile.boot b/arch/arm/mach-stmp378x/Makefile.boot
new file mode 100644
index 000000000000..1568ad404d59
--- /dev/null
+++ b/arch/arm/mach-stmp378x/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x40008000
+params_phys-y := 0x40000100
+initrd_phys-y := 0x40800000
diff --git a/arch/arm/mach-stmp378x/include/mach/entry-macro.S b/arch/arm/mach-stmp378x/include/mach/entry-macro.S
new file mode 100644
index 000000000000..731a92286da2
--- /dev/null
+++ b/arch/arm/mach-stmp378x/include/mach/entry-macro.S
@@ -0,0 +1,35 @@
+/*
+ * Low-level IRQ helper macros for Freescale STMP378X
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ mov \base, #0xf0000000 @ vm address of IRQ controller
+ ldr \irqnr, [\base, #0x70] @ HW_ICOLL_STAT
+ cmp \irqnr, #0x7f
+ moveqs \irqnr, #0 @ Zero flag set for no IRQ
+
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
diff --git a/arch/arm/mach-stmp378x/include/mach/irqs.h b/arch/arm/mach-stmp378x/include/mach/irqs.h
new file mode 100644
index 000000000000..cc59673becdd
--- /dev/null
+++ b/arch/arm/mach-stmp378x/include/mach/irqs.h
@@ -0,0 +1,95 @@
+/*
+ * Freescale STMP378X interrupts
+ *
+ * Copyright (C) 2005 Sigmatel Inc
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#define IRQ_DEBUG_UART 0
+#define IRQ_COMMS_RX 1
+#define IRQ_COMMS_TX 1
+#define IRQ_SSP2_ERROR 2
+#define IRQ_VDD5V 3
+#define IRQ_HEADPHONE_SHORT 4
+#define IRQ_DAC_DMA 5
+#define IRQ_DAC_ERROR 6
+#define IRQ_ADC_DMA 7
+#define IRQ_ADC_ERROR 8
+#define IRQ_SPDIF_DMA 9
+#define IRQ_SAIF2_DMA 9
+#define IRQ_SPDIF_ERROR 10
+#define IRQ_SAIF1_IRQ 10
+#define IRQ_SAIF2_IRQ 10
+#define IRQ_USB_CTRL 11
+#define IRQ_USB_WAKEUP 12
+#define IRQ_GPMI_DMA 13
+#define IRQ_SSP1_DMA 14
+#define IRQ_SSP_ERROR 15
+#define IRQ_GPIO0 16
+#define IRQ_GPIO1 17
+#define IRQ_GPIO2 18
+#define IRQ_SAIF1_DMA 19
+#define IRQ_SSP2_DMA 20
+#define IRQ_ECC8_IRQ 21
+#define IRQ_RTC_ALARM 22
+#define IRQ_UARTAPP_TX_DMA 23
+#define IRQ_UARTAPP_INTERNAL 24
+#define IRQ_UARTAPP_RX_DMA 25
+#define IRQ_I2C_DMA 26
+#define IRQ_I2C_ERROR 27
+#define IRQ_TIMER0 28
+#define IRQ_TIMER1 29
+#define IRQ_TIMER2 30
+#define IRQ_TIMER3 31
+#define IRQ_BATT_BRNOUT 32
+#define IRQ_VDDD_BRNOUT 33
+#define IRQ_VDDIO_BRNOUT 34
+#define IRQ_VDD18_BRNOUT 35
+#define IRQ_TOUCH_DETECT 36
+#define IRQ_LRADC_CH0 37
+#define IRQ_LRADC_CH1 38
+#define IRQ_LRADC_CH2 39
+#define IRQ_LRADC_CH3 40
+#define IRQ_LRADC_CH4 41
+#define IRQ_LRADC_CH5 42
+#define IRQ_LRADC_CH6 43
+#define IRQ_LRADC_CH7 44
+#define IRQ_LCDIF_DMA 45
+#define IRQ_LCDIF_ERROR 46
+#define IRQ_DIGCTL_DEBUG_TRAP 47
+#define IRQ_RTC_1MSEC 48
+#define IRQ_DRI_DMA 49
+#define IRQ_DRI_ATTENTION 50
+#define IRQ_GPMI_ATTENTION 51
+#define IRQ_IR 52
+#define IRQ_DCP_VMI 53
+#define IRQ_DCP 54
+#define IRQ_BCH 56
+#define IRQ_PXP 57
+#define IRQ_UARTAPP2_TX_DMA 58
+#define IRQ_UARTAPP2_INTERNAL 59
+#define IRQ_UARTAPP2_RX_DMA 60
+#define IRQ_VDAC_DETECT 61
+#define IRQ_VDD5V_DROOP 64
+#define IRQ_DCDC4P2_BO 65
+
+
+#define NR_REAL_IRQS 128
+#define NR_IRQS (NR_REAL_IRQS + 32 * 3)
+
+/* All interrupts are FIQ capable */
+#define FIQ_START IRQ_DEBUG_UART
+
+/* Hard disk IRQ is a GPMI attention IRQ */
+#define IRQ_HARDDISK IRQ_GPMI_ATTENTION
diff --git a/arch/arm/mach-stmp378x/include/mach/pins.h b/arch/arm/mach-stmp378x/include/mach/pins.h
new file mode 100644
index 000000000000..93f952d35969
--- /dev/null
+++ b/arch/arm/mach-stmp378x/include/mach/pins.h
@@ -0,0 +1,151 @@
+/*
+ * Freescale STMP378X SoC pin multiplexing
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_PINS_H
+#define __ASM_ARCH_PINS_H
+
+/*
+ * Define all STMP378x pins, a pin name corresponds to a STMP378x hardware
+ * interface this pin belongs to.
+ */
+
+/* Bank 0 */
+#define PINID_GPMI_D00 STMP3XXX_PINID(0, 0)
+#define PINID_GPMI_D01 STMP3XXX_PINID(0, 1)
+#define PINID_GPMI_D02 STMP3XXX_PINID(0, 2)
+#define PINID_GPMI_D03 STMP3XXX_PINID(0, 3)
+#define PINID_GPMI_D04 STMP3XXX_PINID(0, 4)
+#define PINID_GPMI_D05 STMP3XXX_PINID(0, 5)
+#define PINID_GPMI_D06 STMP3XXX_PINID(0, 6)
+#define PINID_GPMI_D07 STMP3XXX_PINID(0, 7)
+#define PINID_GPMI_D08 STMP3XXX_PINID(0, 8)
+#define PINID_GPMI_D09 STMP3XXX_PINID(0, 9)
+#define PINID_GPMI_D10 STMP3XXX_PINID(0, 10)
+#define PINID_GPMI_D11 STMP3XXX_PINID(0, 11)
+#define PINID_GPMI_D12 STMP3XXX_PINID(0, 12)
+#define PINID_GPMI_D13 STMP3XXX_PINID(0, 13)
+#define PINID_GPMI_D14 STMP3XXX_PINID(0, 14)
+#define PINID_GPMI_D15 STMP3XXX_PINID(0, 15)
+#define PINID_GPMI_CLE STMP3XXX_PINID(0, 16)
+#define PINID_GPMI_ALE STMP3XXX_PINID(0, 17)
+#define PINID_GMPI_CE2N STMP3XXX_PINID(0, 18)
+#define PINID_GPMI_RDY0 STMP3XXX_PINID(0, 19)
+#define PINID_GPMI_RDY1 STMP3XXX_PINID(0, 20)
+#define PINID_GPMI_RDY2 STMP3XXX_PINID(0, 21)
+#define PINID_GPMI_RDY3 STMP3XXX_PINID(0, 22)
+#define PINID_GPMI_WPN STMP3XXX_PINID(0, 23)
+#define PINID_GPMI_WRN STMP3XXX_PINID(0, 24)
+#define PINID_GPMI_RDN STMP3XXX_PINID(0, 25)
+#define PINID_AUART1_CTS STMP3XXX_PINID(0, 26)
+#define PINID_AUART1_RTS STMP3XXX_PINID(0, 27)
+#define PINID_AUART1_RX STMP3XXX_PINID(0, 28)
+#define PINID_AUART1_TX STMP3XXX_PINID(0, 29)
+#define PINID_I2C_SCL STMP3XXX_PINID(0, 30)
+#define PINID_I2C_SDA STMP3XXX_PINID(0, 31)
+
+/* Bank 1 */
+#define PINID_LCD_D00 STMP3XXX_PINID(1, 0)
+#define PINID_LCD_D01 STMP3XXX_PINID(1, 1)
+#define PINID_LCD_D02 STMP3XXX_PINID(1, 2)
+#define PINID_LCD_D03 STMP3XXX_PINID(1, 3)
+#define PINID_LCD_D04 STMP3XXX_PINID(1, 4)
+#define PINID_LCD_D05 STMP3XXX_PINID(1, 5)
+#define PINID_LCD_D06 STMP3XXX_PINID(1, 6)
+#define PINID_LCD_D07 STMP3XXX_PINID(1, 7)
+#define PINID_LCD_D08 STMP3XXX_PINID(1, 8)
+#define PINID_LCD_D09 STMP3XXX_PINID(1, 9)
+#define PINID_LCD_D10 STMP3XXX_PINID(1, 10)
+#define PINID_LCD_D11 STMP3XXX_PINID(1, 11)
+#define PINID_LCD_D12 STMP3XXX_PINID(1, 12)
+#define PINID_LCD_D13 STMP3XXX_PINID(1, 13)
+#define PINID_LCD_D14 STMP3XXX_PINID(1, 14)
+#define PINID_LCD_D15 STMP3XXX_PINID(1, 15)
+#define PINID_LCD_D16 STMP3XXX_PINID(1, 16)
+#define PINID_LCD_D17 STMP3XXX_PINID(1, 17)
+#define PINID_LCD_RESET STMP3XXX_PINID(1, 18)
+#define PINID_LCD_RS STMP3XXX_PINID(1, 19)
+#define PINID_LCD_WR STMP3XXX_PINID(1, 20)
+#define PINID_LCD_CS STMP3XXX_PINID(1, 21)
+#define PINID_LCD_DOTCK STMP3XXX_PINID(1, 22)
+#define PINID_LCD_ENABLE STMP3XXX_PINID(1, 23)
+#define PINID_LCD_HSYNC STMP3XXX_PINID(1, 24)
+#define PINID_LCD_VSYNC STMP3XXX_PINID(1, 25)
+#define PINID_PWM0 STMP3XXX_PINID(1, 26)
+#define PINID_PWM1 STMP3XXX_PINID(1, 27)
+#define PINID_PWM2 STMP3XXX_PINID(1, 28)
+#define PINID_PWM3 STMP3XXX_PINID(1, 29)
+#define PINID_PWM4 STMP3XXX_PINID(1, 30)
+
+/* Bank 2 */
+#define PINID_SSP1_CMD STMP3XXX_PINID(2, 0)
+#define PINID_SSP1_DETECT STMP3XXX_PINID(2, 1)
+#define PINID_SSP1_DATA0 STMP3XXX_PINID(2, 2)
+#define PINID_SSP1_DATA1 STMP3XXX_PINID(2, 3)
+#define PINID_SSP1_DATA2 STMP3XXX_PINID(2, 4)
+#define PINID_SSP1_DATA3 STMP3XXX_PINID(2, 5)
+#define PINID_SSP1_SCK STMP3XXX_PINID(2, 6)
+#define PINID_ROTARYA STMP3XXX_PINID(2, 7)
+#define PINID_ROTARYB STMP3XXX_PINID(2, 8)
+#define PINID_EMI_A00 STMP3XXX_PINID(2, 9)
+#define PINID_EMI_A01 STMP3XXX_PINID(2, 10)
+#define PINID_EMI_A02 STMP3XXX_PINID(2, 11)
+#define PINID_EMI_A03 STMP3XXX_PINID(2, 12)
+#define PINID_EMI_A04 STMP3XXX_PINID(2, 13)
+#define PINID_EMI_A05 STMP3XXX_PINID(2, 14)
+#define PINID_EMI_A06 STMP3XXX_PINID(2, 15)
+#define PINID_EMI_A07 STMP3XXX_PINID(2, 16)
+#define PINID_EMI_A08 STMP3XXX_PINID(2, 17)
+#define PINID_EMI_A09 STMP3XXX_PINID(2, 18)
+#define PINID_EMI_A10 STMP3XXX_PINID(2, 19)
+#define PINID_EMI_A11 STMP3XXX_PINID(2, 20)
+#define PINID_EMI_A12 STMP3XXX_PINID(2, 21)
+#define PINID_EMI_BA0 STMP3XXX_PINID(2, 22)
+#define PINID_EMI_BA1 STMP3XXX_PINID(2, 23)
+#define PINID_EMI_CASN STMP3XXX_PINID(2, 24)
+#define PINID_EMI_CE0N STMP3XXX_PINID(2, 25)
+#define PINID_EMI_CE1N STMP3XXX_PINID(2, 26)
+#define PINID_GPMI_CE1N STMP3XXX_PINID(2, 27)
+#define PINID_GPMI_CE0N STMP3XXX_PINID(2, 28)
+#define PINID_EMI_CKE STMP3XXX_PINID(2, 29)
+#define PINID_EMI_RASN STMP3XXX_PINID(2, 30)
+#define PINID_EMI_WEN STMP3XXX_PINID(2, 31)
+
+/* Bank 3 */
+#define PINID_EMI_D00 STMP3XXX_PINID(3, 0)
+#define PINID_EMI_D01 STMP3XXX_PINID(3, 1)
+#define PINID_EMI_D02 STMP3XXX_PINID(3, 2)
+#define PINID_EMI_D03 STMP3XXX_PINID(3, 3)
+#define PINID_EMI_D04 STMP3XXX_PINID(3, 4)
+#define PINID_EMI_D05 STMP3XXX_PINID(3, 5)
+#define PINID_EMI_D06 STMP3XXX_PINID(3, 6)
+#define PINID_EMI_D07 STMP3XXX_PINID(3, 7)
+#define PINID_EMI_D08 STMP3XXX_PINID(3, 8)
+#define PINID_EMI_D09 STMP3XXX_PINID(3, 9)
+#define PINID_EMI_D10 STMP3XXX_PINID(3, 10)
+#define PINID_EMI_D11 STMP3XXX_PINID(3, 11)
+#define PINID_EMI_D12 STMP3XXX_PINID(3, 12)
+#define PINID_EMI_D13 STMP3XXX_PINID(3, 13)
+#define PINID_EMI_D14 STMP3XXX_PINID(3, 14)
+#define PINID_EMI_D15 STMP3XXX_PINID(3, 15)
+#define PINID_EMI_DQM0 STMP3XXX_PINID(3, 16)
+#define PINID_EMI_DQM1 STMP3XXX_PINID(3, 17)
+#define PINID_EMI_DQS0 STMP3XXX_PINID(3, 18)
+#define PINID_EMI_DQS1 STMP3XXX_PINID(3, 19)
+#define PINID_EMI_CLK STMP3XXX_PINID(3, 20)
+#define PINID_EMI_CLKN STMP3XXX_PINID(3, 21)
+
+#endif /* __ASM_ARCH_PINS_H */
diff --git a/arch/arm/mach-stmp378x/include/mach/regs-apbh.h b/arch/arm/mach-stmp378x/include/mach/regs-apbh.h
new file mode 100644
index 000000000000..db63b041e4f0
--- /dev/null
+++ b/arch/arm/mach-stmp378x/include/mach/regs-apbh.h
@@ -0,0 +1,88 @@
+/*
+ * STMP APBH Register Definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ * Copyright 2008 Embedded Alley Solutions, 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; 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
+ */
+
+#ifndef __ARCH_ARM___APBH_H
+#define __ARCH_ARM___APBH_H 1
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_APBH_BASE (REGS_BASE + 0x4000)
+#define REGS_APBH_BASE_PHYS (0x80004000)
+#define REGS_APBH_SIZE 0x00002000
+HW_REGISTER(HW_APBH_CTRL0, REGS_APBH_BASE, 0x00000000)
+#define HW_APBH_CTRL0_ADDR (REGS_APBH_BASE + 0x00000000)
+#define BM_APBH_CTRL0_SFTRST 0x80000000
+#define BM_APBH_CTRL0_CLKGATE 0x40000000
+#define BM_APBH_CTRL0_AHB_BURST8_EN 0x20000000
+#define BM_APBH_CTRL0_APB_BURST4_EN 0x10000000
+#define BP_APBH_CTRL0_RESET_CHANNEL 16
+#define BM_APBH_CTRL0_RESET_CHANNEL 0x00FF0000
+#define BF_APBH_CTRL0_RESET_CHANNEL(v) \
+ (((v) << 16) & BM_APBH_CTRL0_RESET_CHANNEL)
+HW_REGISTER(HW_APBH_CTRL1, REGS_APBH_BASE, 0x00000010)
+#define HW_APBH_CTRL1_ADDR (REGS_APBH_BASE + 0x00000010)
+HW_REGISTER(HW_APBH_CTRL2, REGS_APBH_BASE, 0x00000020)
+HW_REGISTER_0(HW_APBH_DEVSEL, REGS_APBH_BASE, 0x00000030)
+HW_REGISTER_0_INDEXED(HW_APBH_CHn_CURCMDAR, REGS_APBH_BASE, 0x00000040, 0x70)
+#define BP_APBH_CHn_CURCMDAR_CMD_ADDR 0
+#define BM_APBH_CHn_CURCMDAR_CMD_ADDR 0xFFFFFFFF
+#define BF_APBH_CHn_CURCMDAR_CMD_ADDR(v) (v)
+HW_REGISTER_0_INDEXED(HW_APBH_CHn_NXTCMDAR, REGS_APBH_BASE, 0x00000050, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBH_CHn_CMD, REGS_APBH_BASE, 0x00000060, 0x70)
+#define BP_APBH_CHn_CMD_XFER_COUNT 16
+#define BM_APBH_CHn_CMD_XFER_COUNT 0xFFFF0000
+#define BF_APBH_CHn_CMD_XFER_COUNT(v) \
+ (((v) << 16) & BM_APBH_CHn_CMD_XFER_COUNT)
+#define BP_APBH_CHn_CMD_CMDWORDS 12
+#define BM_APBH_CHn_CMD_CMDWORDS 0x0000F000
+#define BF_APBH_CHn_CMD_CMDWORDS(v) \
+ (((v) << 12) & BM_APBH_CHn_CMD_CMDWORDS)
+#define BM_APBH_CHn_CMD_HALTONTERMINATE 0x00000100
+#define BM_APBH_CHn_CMD_WAIT4ENDCMD 0x00000080
+#define BM_APBH_CHn_CMD_SEMAPHORE 0x00000040
+#define BM_APBH_CHn_CMD_NANDWAIT4READY 0x00000020
+#define BM_APBH_CHn_CMD_NANDLOCK 0x00000010
+#define BM_APBH_CHn_CMD_IRQONCMPLT 0x00000008
+#define BM_APBH_CHn_CMD_CHAIN 0x00000004
+#define BP_APBH_CHn_CMD_COMMAND 0
+#define BM_APBH_CHn_CMD_COMMAND 0x00000003
+#define BF_APBH_CHn_CMD_COMMAND(v) \
+ (((v) << 0) & BM_APBH_CHn_CMD_COMMAND)
+#define BV_APBH_CHn_CMD_COMMAND__NO_DMA_XFER 0x0
+#define BV_APBH_CHn_CMD_COMMAND__DMA_WRITE 0x1
+#define BV_APBH_CHn_CMD_COMMAND__DMA_READ 0x2
+#define BV_APBH_CHn_CMD_COMMAND__DMA_SENSE 0x3
+HW_REGISTER_0_INDEXED(HW_APBH_CHn_BAR, REGS_APBH_BASE, 0x00000070, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBH_CHn_SEMA, REGS_APBH_BASE, 0x00000080, 0x70)
+#define BP_APBH_CHn_SEMA_PHORE 16
+#define BM_APBH_CHn_SEMA_PHORE 0x00FF0000
+#define BF_APBH_CHn_SEMA_PHORE(v) \
+ (((v) << 16) & BM_APBH_CHn_SEMA_PHORE)
+#define BP_APBH_CHn_SEMA_INCREMENT_SEMA 0
+#define BM_APBH_CHn_SEMA_INCREMENT_SEMA 0x000000FF
+#define BF_APBH_CHn_SEMA_INCREMENT_SEMA(v) \
+ (((v) << 0) & BM_APBH_CHn_SEMA_INCREMENT_SEMA)
+HW_REGISTER_0_INDEXED(HW_APBH_CHn_DEBUG1, REGS_APBH_BASE, 0x00000090, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBH_CHn_DEBUG2, REGS_APBH_BASE, 0x000000a0, 0x70)
+HW_REGISTER_0(HW_APBH_VERSION, REGS_APBH_BASE, 0x000003f0)
+#endif /* __ARCH_ARM___APBH_H */
diff --git a/arch/arm/mach-stmp378x/include/mach/regs-apbx.h b/arch/arm/mach-stmp378x/include/mach/regs-apbx.h
new file mode 100644
index 000000000000..d0e8e9fe1cce
--- /dev/null
+++ b/arch/arm/mach-stmp378x/include/mach/regs-apbx.h
@@ -0,0 +1,79 @@
+/*
+ * STMP APBX Register Definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ * Copyright 2008 Embedded Alley Solutions, 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; 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
+ */
+#ifndef __ARCH_ARM___APBX_H
+#define __ARCH_ARM___APBX_H 1
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_APBX_BASE (REGS_BASE + 0x24000)
+#define REGS_APBX_BASE_PHYS (0x80024000)
+#define REGS_APBX_SIZE 0x00002000
+HW_REGISTER(HW_APBX_CTRL0, REGS_APBX_BASE, 0x00000000)
+#define HW_APBX_CTRL0_ADDR (REGS_APBX_BASE + 0x00000000)
+#define BM_APBX_CTRL0_SFTRST 0x80000000
+#define BM_APBX_CTRL0_CLKGATE 0x40000000
+HW_REGISTER(HW_APBX_CTRL1, REGS_APBX_BASE, 0x00000010)
+HW_REGISTER(HW_APBX_CTRL2, REGS_APBX_BASE, 0x00000020)
+HW_REGISTER(HW_APBX_CHANNEL_CTRL, REGS_APBX_BASE, 0x00000030)
+#define BP_APBX_CHANNEL_CTRL_RESET_CHANNEL 16
+#define BM_APBX_CHANNEL_CTRL_RESET_CHANNEL 0xFFFF0000
+#define BF_APBX_CHANNEL_CTRL_RESET_CHANNEL(v) \
+ (((v) << BP_APBX_CHANNEL_CTRL_RESET_CHANNEL) & \
+ BM_APBX_CHANNEL_CTRL_RESET_CHANNEL)
+HW_REGISTER_0(HW_APBX_DEVSEL, REGS_APBX_BASE, 0x00000040)
+HW_REGISTER_0_INDEXED(HW_APBX_CHn_CURCMDAR, REGS_APBX_BASE, 0x00000100, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBX_CHn_NXTCMDAR, REGS_APBX_BASE, 0x00000110, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBX_CHn_CMD, REGS_APBX_BASE, 0x00000120, 0x70)
+#define BP_APBX_CHn_CMD_XFER_COUNT 16
+#define BM_APBX_CHn_CMD_XFER_COUNT 0xFFFF0000
+#define BF_APBX_CHn_CMD_XFER_COUNT(v) \
+ (((v) << 16) & BM_APBX_CHn_CMD_XFER_COUNT)
+#define BP_APBX_CHn_CMD_CMDWORDS 12
+#define BM_APBX_CHn_CMD_CMDWORDS 0x0000F000
+#define BF_APBX_CHn_CMD_CMDWORDS(v) \
+ (((v) << 12) & BM_APBX_CHn_CMD_CMDWORDS)
+#define BM_APBX_CHn_CMD_HALTONTERMINATE 0x00000100
+#define BM_APBX_CHn_CMD_WAIT4ENDCMD 0x00000080
+#define BM_APBX_CHn_CMD_SEMAPHORE 0x00000040
+#define BM_APBX_CHn_CMD_IRQONCMPLT 0x00000008
+#define BM_APBX_CHn_CMD_CHAIN 0x00000004
+#define BP_APBX_CHn_CMD_COMMAND 0
+#define BM_APBX_CHn_CMD_COMMAND 0x00000003
+#define BF_APBX_CHn_CMD_COMMAND(v) \
+ (((v) << 0) & BM_APBX_CHn_CMD_COMMAND)
+#define BV_APBX_CHn_CMD_COMMAND__NO_DMA_XFER 0x0
+#define BV_APBX_CHn_CMD_COMMAND__DMA_WRITE 0x1
+#define BV_APBX_CHn_CMD_COMMAND__DMA_READ 0x2
+HW_REGISTER_0_INDEXED(HW_APBX_CHn_BAR, REGS_APBX_BASE, 0x00000130, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBX_CHn_SEMA, REGS_APBX_BASE, 0x00000140, 0x70)
+#define BP_APBX_CHn_SEMA_PHORE 16
+#define BM_APBX_CHn_SEMA_PHORE 0x00FF0000
+#define BF_APBX_CHn_SEMA_PHORE(v) \
+ (((v) << 16) & BM_APBX_CHn_SEMA_PHORE)
+#define BP_APBX_CHn_SEMA_INCREMENT_SEMA 0
+#define BM_APBX_CHn_SEMA_INCREMENT_SEMA 0x000000FF
+#define BF_APBX_CHn_SEMA_INCREMENT_SEMA(v) \
+ (((v) << 0) & BM_APBX_CHn_SEMA_INCREMENT_SEMA)
+HW_REGISTER_0_INDEXED(HW_APBX_CHn_DEBUG1, REGS_APBX_BASE, 0x00000150, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBX_CHn_DEBUG2, REGS_APBX_BASE, 0x00000160, 0x70)
+HW_REGISTER_0(HW_APBX_VERSION, REGS_APBX_BASE, 0x00000800)
+#endif /* __ARCH_ARM___APBX_H */
diff --git a/arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h b/arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h
new file mode 100644
index 000000000000..a421d9e0cbff
--- /dev/null
+++ b/arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h
@@ -0,0 +1,276 @@
+/*
+ * STMP CLKCTRL Register Definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ * Copyright 2008 Embedded Alley Solutions, 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; 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
+ */
+
+#ifndef __ARCH_ARM___CLKCTRL_H
+#define __ARCH_ARM___CLKCTRL_H 1
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_CLKCTRL_BASE (REGS_BASE + 0x40000)
+#define REGS_CLKCTRL_BASE_PHYS (0x80040000)
+#define REGS_CLKCTRL_SIZE 0x00002000
+HW_REGISTER(HW_CLKCTRL_PLLCTRL0, REGS_CLKCTRL_BASE, 0x00000000)
+#define HW_CLKCTRL_PLLCTRL0_ADDR (REGS_CLKCTRL_BASE + 0x00000000)
+#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000
+HW_REGISTER_0(HW_CLKCTRL_PLLCTRL1, REGS_CLKCTRL_BASE, 0x00000010)
+#define HW_CLKCTRL_PLLCTRL1_ADDR (REGS_CLKCTRL_BASE + 0x00000010)
+#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
+HW_REGISTER(HW_CLKCTRL_CPU, REGS_CLKCTRL_BASE, 0x00000020)
+#define HW_CLKCTRL_CPU_ADDR (REGS_CLKCTRL_BASE + 0x00000020)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL 16
+#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
+ (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
+#define BP_CLKCTRL_CPU_DIV_CPU 0
+#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v) \
+ (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+HW_REGISTER(HW_CLKCTRL_HBUS, REGS_CLKCTRL_BASE, 0x00000030)
+#define HW_CLKCTRL_HBUS_ADDR (REGS_CLKCTRL_BASE + 0x00000030)
+#define BM_CLKCTRL_HBUS_BUSY 0x20000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
+#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE 0x00100000
+#define BP_CLKCTRL_HBUS_SLOW_DIV 16
+#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
+#define BP_CLKCTRL_HBUS_DIV 0
+#define BM_CLKCTRL_HBUS_DIV 0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+HW_REGISTER_0(HW_CLKCTRL_XBUS, REGS_CLKCTRL_BASE, 0x00000040)
+#define HW_CLKCTRL_XBUS_ADDR (REGS_CLKCTRL_BASE + 0x00000040)
+#define BM_CLKCTRL_XBUS_BUSY 0x80000000
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_XBUS_DIV 0
+#define BM_CLKCTRL_XBUS_DIV 0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+HW_REGISTER(HW_CLKCTRL_XTAL, REGS_CLKCTRL_BASE, 0x00000050)
+#define HW_CLKCTRL_XTAL_ADDR (REGS_CLKCTRL_BASE + 0x00000050)
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
+#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
+#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000
+#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
+#define BP_CLKCTRL_XTAL_DIV_UART 0
+#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v) \
+ (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+HW_REGISTER_0(HW_CLKCTRL_PIX, REGS_CLKCTRL_BASE, 0x00000060)
+#define HW_CLKCTRL_PIX_ADDR (REGS_CLKCTRL_BASE + 0x00000060)
+#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
+#define BM_CLKCTRL_PIX_BUSY 0x20000000
+#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000
+#define BP_CLKCTRL_PIX_DIV 0
+#define BM_CLKCTRL_PIX_DIV 0x00000FFF
+#define BF_CLKCTRL_PIX_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_PIX_DIV)
+HW_REGISTER_0(HW_CLKCTRL_SSP, REGS_CLKCTRL_BASE, 0x00000070)
+#define HW_CLKCTRL_SSP_ADDR (REGS_CLKCTRL_BASE + 0x00000070)
+#define BM_CLKCTRL_SSP_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP_BUSY 0x20000000
+#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP_DIV 0
+#define BM_CLKCTRL_SSP_DIV 0x000001FF
+#define BF_CLKCTRL_SSP_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP_DIV)
+HW_REGISTER_0(HW_CLKCTRL_GPMI, REGS_CLKCTRL_BASE, 0x00000080)
+#define HW_CLKCTRL_GPMI_ADDR (REGS_CLKCTRL_BASE + 0x00000080)
+#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_GPMI_BUSY 0x20000000
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_GPMI_DIV 0
+#define BM_CLKCTRL_GPMI_DIV 0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+HW_REGISTER_0(HW_CLKCTRL_SPDIF, REGS_CLKCTRL_BASE, 0x00000090)
+#define HW_CLKCTRL_SPDIF_ADDR (REGS_CLKCTRL_BASE + 0x00000090)
+#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
+HW_REGISTER_0(HW_CLKCTRL_EMI, REGS_CLKCTRL_BASE, 0x000000a0)
+#define HW_CLKCTRL_EMI_ADDR (REGS_CLKCTRL_BASE + 0x000000a0)
+#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
+#define BP_CLKCTRL_EMI_DIV_XTAL 8
+#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
+ (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_DIV_EMI 0
+#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v) \
+ (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+HW_REGISTER_0(HW_CLKCTRL_IR, REGS_CLKCTRL_BASE, 0x000000b0)
+#define HW_CLKCTRL_IR_ADDR (REGS_CLKCTRL_BASE + 0x000000b0)
+#define BM_CLKCTRL_IR_CLKGATE 0x80000000
+#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000
+#define BM_CLKCTRL_IR_IR_BUSY 0x10000000
+#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000
+#define BP_CLKCTRL_IR_IROV_DIV 16
+#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000
+#define BF_CLKCTRL_IR_IROV_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
+#define BP_CLKCTRL_IR_IR_DIV 0
+#define BM_CLKCTRL_IR_IR_DIV 0x000003FF
+#define BF_CLKCTRL_IR_IR_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
+HW_REGISTER_0(HW_CLKCTRL_SAIF, REGS_CLKCTRL_BASE, 0x000000c0)
+#define HW_CLKCTRL_SAIF_ADDR (REGS_CLKCTRL_BASE + 0x000000c0)
+#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF_BUSY 0x20000000
+#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF_DIV 0
+#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF_DIV)
+HW_REGISTER_0(HW_CLKCTRL_TV, REGS_CLKCTRL_BASE, 0x000000d0)
+#define HW_CLKCTRL_TV_ADDR (REGS_CLKCTRL_BASE + 0x000000d0)
+#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000
+#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000
+HW_REGISTER_0(HW_CLKCTRL_ETM, REGS_CLKCTRL_BASE, 0x000000e0)
+#define HW_CLKCTRL_ETM_ADDR (REGS_CLKCTRL_BASE + 0x000000e0)
+#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
+#define BM_CLKCTRL_ETM_BUSY 0x20000000
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040
+#define BP_CLKCTRL_ETM_DIV 0
+#define BM_CLKCTRL_ETM_DIV 0x0000003F
+#define BF_CLKCTRL_ETM_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_ETM_DIV)
+HW_REGISTER(HW_CLKCTRL_FRAC, REGS_CLKCTRL_BASE, 0x000000f0)
+#define HW_CLKCTRL_FRAC_ADDR (REGS_CLKCTRL_BASE + 0x000000f0)
+#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
+#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC_IOFRAC 24
+#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
+#define BF_CLKCTRL_FRAC_IOFRAC(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
+#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
+#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC_PIXFRAC 16
+#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
+#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
+#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
+#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC_EMIFRAC 8
+#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
+#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
+#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC_CPUFRAC 0
+#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
+HW_REGISTER(HW_CLKCTRL_FRAC1, REGS_CLKCTRL_BASE, 0x00000100)
+#define HW_CLKCTRL_FRAC1_ADDR (REGS_CLKCTRL_BASE + 0x00000100)
+#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000
+#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000
+HW_REGISTER(HW_CLKCTRL_CLKSEQ, REGS_CLKCTRL_BASE, 0x00000110)
+#define HW_CLKCTRL_CLKSEQ_ADDR (REGS_CLKCTRL_BASE + 0x00000110)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
+#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
+HW_REGISTER_0(HW_CLKCTRL_RESET, REGS_CLKCTRL_BASE, 0x00000120)
+#define HW_CLKCTRL_RESET_ADDR (REGS_CLKCTRL_BASE + 0x00000120)
+#define BM_CLKCTRL_RESET_CHIP 0x00000002
+#define BM_CLKCTRL_RESET_DIG 0x00000001
+HW_REGISTER_0(HW_CLKCTRL_STATUS, REGS_CLKCTRL_BASE, 0x00000130)
+#define HW_CLKCTRL_STATUS_ADDR (REGS_CLKCTRL_BASE + 0x00000130)
+#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+ (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+HW_REGISTER_0(HW_CLKCTRL_VERSION, REGS_CLKCTRL_BASE, 0x00000140)
+#define HW_CLKCTRL_VERSION_ADDR (REGS_CLKCTRL_BASE + 0x00000140)
+#define BP_CLKCTRL_VERSION_MAJOR 24
+#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR 16
+#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v) \
+ (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP 0
+#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v) \
+ (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+#endif /* __ARCH_ARM___CLKCTRL_H */
diff --git a/arch/arm/mach-stmp378x/include/mach/regs-icoll.h b/arch/arm/mach-stmp378x/include/mach/regs-icoll.h
new file mode 100644
index 000000000000..a5a530c6440d
--- /dev/null
+++ b/arch/arm/mach-stmp378x/include/mach/regs-icoll.h
@@ -0,0 +1,213 @@
+/*
+ * STMP ICOLL Register Definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ * Copyright 2008 Embedded Alley Solutions, 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; 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
+ */
+
+#ifndef __ARCH_ARM___ICOLL_H
+#define __ARCH_ARM___ICOLL_H 1
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_ICOLL_BASE (REGS_BASE + 0x0)
+#define REGS_ICOLL_BASE_PHYS (0x80000000)
+#define REGS_ICOLL_SIZE 0x00002000
+HW_REGISTER(HW_ICOLL_VECTOR, REGS_ICOLL_BASE, 0x00000000)
+#define HW_ICOLL_VECTOR_ADDR (REGS_ICOLL_BASE + 0x00000000)
+#define BP_ICOLL_VECTOR_IRQVECTOR 2
+#define BM_ICOLL_VECTOR_IRQVECTOR 0xFFFFFFFC
+#define BF_ICOLL_VECTOR_IRQVECTOR(v) \
+ (((v) << 2) & BM_ICOLL_VECTOR_IRQVECTOR)
+HW_REGISTER_0(HW_ICOLL_LEVELACK, REGS_ICOLL_BASE, 0x00000010)
+#define HW_ICOLL_LEVELACK_ADDR (REGS_ICOLL_BASE + 0x00000010)
+#define BP_ICOLL_LEVELACK_IRQLEVELACK 0
+#define BM_ICOLL_LEVELACK_IRQLEVELACK 0x0000000F
+#define BF_ICOLL_LEVELACK_IRQLEVELACK(v) \
+ (((v) << 0) & BM_ICOLL_LEVELACK_IRQLEVELACK)
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL1 0x2
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL2 0x4
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL3 0x8
+HW_REGISTER(HW_ICOLL_CTRL, REGS_ICOLL_BASE, 0x00000020)
+#define HW_ICOLL_CTRL_ADDR (REGS_ICOLL_BASE + 0x00000020)
+#define BM_ICOLL_CTRL_SFTRST 0x80000000
+#define BV_ICOLL_CTRL_SFTRST__RUN 0x0
+#define BV_ICOLL_CTRL_SFTRST__IN_RESET 0x1
+#define BM_ICOLL_CTRL_CLKGATE 0x40000000
+#define BV_ICOLL_CTRL_CLKGATE__RUN 0x0
+#define BV_ICOLL_CTRL_CLKGATE__NO_CLOCKS 0x1
+#define BP_ICOLL_CTRL_VECTOR_PITCH 21
+#define BM_ICOLL_CTRL_VECTOR_PITCH 0x00E00000
+#define BF_ICOLL_CTRL_VECTOR_PITCH(v) \
+ (((v) << 21) & BM_ICOLL_CTRL_VECTOR_PITCH)
+#define BV_ICOLL_CTRL_VECTOR_PITCH__DEFAULT_BY4 0x0
+#define BV_ICOLL_CTRL_VECTOR_PITCH__BY4 0x1
+#define BV_ICOLL_CTRL_VECTOR_PITCH__BY8 0x2
+#define BV_ICOLL_CTRL_VECTOR_PITCH__BY12 0x3
+#define BV_ICOLL_CTRL_VECTOR_PITCH__BY16 0x4
+#define BV_ICOLL_CTRL_VECTOR_PITCH__BY20 0x5
+#define BV_ICOLL_CTRL_VECTOR_PITCH__BY24 0x6
+#define BV_ICOLL_CTRL_VECTOR_PITCH__BY28 0x7
+#define BM_ICOLL_CTRL_BYPASS_FSM 0x00100000
+#define BV_ICOLL_CTRL_BYPASS_FSM__NORMAL 0x0
+#define BV_ICOLL_CTRL_BYPASS_FSM__BYPASS 0x1
+#define BM_ICOLL_CTRL_NO_NESTING 0x00080000
+#define BV_ICOLL_CTRL_NO_NESTING__NORMAL 0x0
+#define BV_ICOLL_CTRL_NO_NESTING__NO_NEST 0x1
+#define BM_ICOLL_CTRL_ARM_RSE_MODE 0x00040000
+#define BM_ICOLL_CTRL_FIQ_FINAL_ENABLE 0x00020000
+#define BV_ICOLL_CTRL_FIQ_FINAL_ENABLE__DISABLE 0x0
+#define BV_ICOLL_CTRL_FIQ_FINAL_ENABLE__ENABLE 0x1
+#define BM_ICOLL_CTRL_IRQ_FINAL_ENABLE 0x00010000
+#define BV_ICOLL_CTRL_IRQ_FINAL_ENABLE__DISABLE 0x0
+#define BV_ICOLL_CTRL_IRQ_FINAL_ENABLE__ENABLE 0x1
+HW_REGISTER(HW_ICOLL_VBASE, REGS_ICOLL_BASE, 0x00000040)
+#define HW_ICOLL_VBASE_ADDR (REGS_ICOLL_BASE + 0x00000040)
+#define BP_ICOLL_VBASE_TABLE_ADDRESS 2
+#define BM_ICOLL_VBASE_TABLE_ADDRESS 0xFFFFFFFC
+#define BF_ICOLL_VBASE_TABLE_ADDRESS(v) \
+ (((v) << 2) & BM_ICOLL_VBASE_TABLE_ADDRESS)
+HW_REGISTER_0(HW_ICOLL_STAT, REGS_ICOLL_BASE, 0x00000070)
+#define HW_ICOLL_STAT_ADDR (REGS_ICOLL_BASE + 0x00000070)
+#define BP_ICOLL_STAT_VECTOR_NUMBER 0
+#define BM_ICOLL_STAT_VECTOR_NUMBER 0x0000007F
+#define BF_ICOLL_STAT_VECTOR_NUMBER(v) \
+ (((v) << 0) & BM_ICOLL_STAT_VECTOR_NUMBER)
+/*
+ * multi-register-define name HW_ICOLL_RAWn
+ * base 0x000000A0
+ * count 4
+ * offset 0x10
+ */
+HW_REGISTER_0_INDEXED(HW_ICOLL_RAWn, REGS_ICOLL_BASE, 0x000000a0, 0x10)
+#define BP_ICOLL_RAWn_RAW_IRQS 0
+#define BM_ICOLL_RAWn_RAW_IRQS 0xFFFFFFFF
+#define BF_ICOLL_RAWn_RAW_IRQS(v) (v)
+/*
+ * multi-register-define name HW_ICOLL_INTERRUPTn
+ * base 0x00000120
+ * count 128
+ * offset 0x10
+ */
+HW_REGISTER_INDEXED(HW_ICOLL_INTERRUPTn, REGS_ICOLL_BASE, 0x00000120, 0x10)
+#define BM_ICOLL_INTERRUPTn_ENFIQ 0x00000010
+#define BV_ICOLL_INTERRUPTn_ENFIQ__DISABLE 0x0
+#define BV_ICOLL_INTERRUPTn_ENFIQ__ENABLE 0x1
+#define BM_ICOLL_INTERRUPTn_SOFTIRQ 0x00000008
+#define BV_ICOLL_INTERRUPTn_SOFTIRQ__NO_INTERRUPT 0x0
+#define BV_ICOLL_INTERRUPTn_SOFTIRQ__FORCE_INTERRUPT 0x1
+#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
+#define BV_ICOLL_INTERRUPTn_ENABLE__DISABLE 0x0
+#define BV_ICOLL_INTERRUPTn_ENABLE__ENABLE 0x1
+#define BP_ICOLL_INTERRUPTn_PRIORITY 0
+#define BM_ICOLL_INTERRUPTn_PRIORITY 0x00000003
+#define BF_ICOLL_INTERRUPTn_PRIORITY(v) \
+ (((v) << 0) & BM_ICOLL_INTERRUPTn_PRIORITY)
+#define BV_ICOLL_INTERRUPTn_PRIORITY__LEVEL0 0x0
+#define BV_ICOLL_INTERRUPTn_PRIORITY__LEVEL1 0x1
+#define BV_ICOLL_INTERRUPTn_PRIORITY__LEVEL2 0x2
+#define BV_ICOLL_INTERRUPTn_PRIORITY__LEVEL3 0x3
+HW_REGISTER(HW_ICOLL_DEBUG, REGS_ICOLL_BASE, 0x00001120)
+#define HW_ICOLL_DEBUG_ADDR (REGS_ICOLL_BASE + 0x00001120)
+#define BP_ICOLL_DEBUG_INSERVICE 28
+#define BM_ICOLL_DEBUG_INSERVICE 0xF0000000
+#define BF_ICOLL_DEBUG_INSERVICE(v) \
+ (((v) << 28) & BM_ICOLL_DEBUG_INSERVICE)
+#define BV_ICOLL_DEBUG_INSERVICE__LEVEL0 0x1
+#define BV_ICOLL_DEBUG_INSERVICE__LEVEL1 0x2
+#define BV_ICOLL_DEBUG_INSERVICE__LEVEL2 0x4
+#define BV_ICOLL_DEBUG_INSERVICE__LEVEL3 0x8
+#define BP_ICOLL_DEBUG_LEVEL_REQUESTS 24
+#define BM_ICOLL_DEBUG_LEVEL_REQUESTS 0x0F000000
+#define BF_ICOLL_DEBUG_LEVEL_REQUESTS(v) \
+ (((v) << 24) & BM_ICOLL_DEBUG_LEVEL_REQUESTS)
+#define BV_ICOLL_DEBUG_LEVEL_REQUESTS__LEVEL0 0x1
+#define BV_ICOLL_DEBUG_LEVEL_REQUESTS__LEVEL1 0x2
+#define BV_ICOLL_DEBUG_LEVEL_REQUESTS__LEVEL2 0x4
+#define BV_ICOLL_DEBUG_LEVEL_REQUESTS__LEVEL3 0x8
+#define BP_ICOLL_DEBUG_REQUESTS_BY_LEVEL 20
+#define BM_ICOLL_DEBUG_REQUESTS_BY_LEVEL 0x00F00000
+#define BF_ICOLL_DEBUG_REQUESTS_BY_LEVEL(v) \
+ (((v) << 20) & BM_ICOLL_DEBUG_REQUESTS_BY_LEVEL)
+#define BV_ICOLL_DEBUG_REQUESTS_BY_LEVEL__LEVEL0 0x1
+#define BV_ICOLL_DEBUG_REQUESTS_BY_LEVEL__LEVEL1 0x2
+#define BV_ICOLL_DEBUG_REQUESTS_BY_LEVEL__LEVEL2 0x4
+#define BV_ICOLL_DEBUG_REQUESTS_BY_LEVEL__LEVEL3 0x8
+#define BM_ICOLL_DEBUG_FIQ 0x00020000
+#define BV_ICOLL_DEBUG_FIQ__NO_FIQ_REQUESTED 0x0
+#define BV_ICOLL_DEBUG_FIQ__FIQ_REQUESTED 0x1
+#define BM_ICOLL_DEBUG_IRQ 0x00010000
+#define BV_ICOLL_DEBUG_IRQ__NO_IRQ_REQUESTED 0x0
+#define BV_ICOLL_DEBUG_IRQ__IRQ_REQUESTED 0x1
+#define BP_ICOLL_DEBUG_VECTOR_FSM 0
+#define BM_ICOLL_DEBUG_VECTOR_FSM 0x000003FF
+#define BF_ICOLL_DEBUG_VECTOR_FSM(v) \
+ (((v) << 0) & BM_ICOLL_DEBUG_VECTOR_FSM)
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_IDLE 0x000
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE1 0x001
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE2 0x002
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_PENDING 0x004
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE3 0x008
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE4 0x010
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_ISR_RUNNING1 0x020
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_ISR_RUNNING2 0x040
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_ISR_RUNNING3 0x080
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE5 0x100
+#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE6 0x200
+HW_REGISTER(HW_ICOLL_DBGREAD0, REGS_ICOLL_BASE, 0x00001130)
+#define HW_ICOLL_DBGREAD0_ADDR (REGS_ICOLL_BASE + 0x00001130)
+#define BP_ICOLL_DBGREAD0_VALUE 0
+#define BM_ICOLL_DBGREAD0_VALUE 0xFFFFFFFF
+#define BF_ICOLL_DBGREAD0_VALUE(v) (v)
+HW_REGISTER(HW_ICOLL_DBGREAD1, REGS_ICOLL_BASE, 0x00001140)
+#define HW_ICOLL_DBGREAD1_ADDR (REGS_ICOLL_BASE + 0x00001140)
+#define BP_ICOLL_DBGREAD1_VALUE 0
+#define BM_ICOLL_DBGREAD1_VALUE 0xFFFFFFFF
+#define BF_ICOLL_DBGREAD1_VALUE(v) (v)
+HW_REGISTER(HW_ICOLL_DBGFLAG, REGS_ICOLL_BASE, 0x00001150)
+#define HW_ICOLL_DBGFLAG_ADDR (REGS_ICOLL_BASE + 0x00001150)
+#define BP_ICOLL_DBGFLAG_FLAG 0
+#define BM_ICOLL_DBGFLAG_FLAG 0x0000FFFF
+#define BF_ICOLL_DBGFLAG_FLAG(v) \
+ (((v) << 0) & BM_ICOLL_DBGFLAG_FLAG)
+/*
+ * multi-register-define name HW_ICOLL_DBGREQUESTn
+ * base 0x00001160
+ * count 4
+ * offset 0x10
+ */
+HW_REGISTER_0_INDEXED(HW_ICOLL_DBGREQUESTn, REGS_ICOLL_BASE, 0x00001160,
+ 0x10)
+#define BP_ICOLL_DBGREQUESTn_BITS 0
+#define BM_ICOLL_DBGREQUESTn_BITS 0xFFFFFFFF
+#define BF_ICOLL_DBGREQUESTn_BITS(v) (v)
+HW_REGISTER_0(HW_ICOLL_VERSION, REGS_ICOLL_BASE, 0x000011e0)
+#define HW_ICOLL_VERSION_ADDR (REGS_ICOLL_BASE + 0x000011e0)
+#define BP_ICOLL_VERSION_MAJOR 24
+#define BM_ICOLL_VERSION_MAJOR 0xFF000000
+#define BF_ICOLL_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_ICOLL_VERSION_MAJOR)
+#define BP_ICOLL_VERSION_MINOR 16
+#define BM_ICOLL_VERSION_MINOR 0x00FF0000
+#define BF_ICOLL_VERSION_MINOR(v) \
+ (((v) << 16) & BM_ICOLL_VERSION_MINOR)
+#define BP_ICOLL_VERSION_STEP 0
+#define BM_ICOLL_VERSION_STEP 0x0000FFFF
+#define BF_ICOLL_VERSION_STEP(v) \
+ (((v) << 0) & BM_ICOLL_VERSION_STEP)
+#endif /* __ARCH_ARM___ICOLL_H */
diff --git a/arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h b/arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h
new file mode 100644
index 000000000000..6c42d2a47c19
--- /dev/null
+++ b/arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h
@@ -0,0 +1,143 @@
+/*
+ * STMP PINCTRL Register Definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ * Copyright 2008 Embedded Alley Solutions, 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; 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
+ */
+
+#ifndef __ARCH_ARM___PINCTRL_H
+#define __ARCH_ARM___PINCTRL_H 1
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_PINCTRL_BASE (REGS_BASE + 0x18000)
+#define REGS_PINCTRL_BASE_PHYS (0x80018000)
+#define REGS_PINCTRL_SIZE 0x00002000
+HW_REGISTER(HW_PINCTRL_CTRL, REGS_PINCTRL_BASE, 0x00000000)
+#define HW_PINCTRL_CTRL_ADDR (REGS_PINCTRL_BASE + 0x00000000)
+#define BM_PINCTRL_CTRL_SFTRST 0x80000000
+#define BM_PINCTRL_CTRL_CLKGATE 0x40000000
+#define BM_PINCTRL_CTRL_PRESENT3 0x08000000
+#define BM_PINCTRL_CTRL_PRESENT2 0x04000000
+#define BM_PINCTRL_CTRL_PRESENT1 0x02000000
+#define BM_PINCTRL_CTRL_PRESENT0 0x01000000
+#define BM_PINCTRL_CTRL_IRQOUT2 0x00000004
+#define BM_PINCTRL_CTRL_IRQOUT1 0x00000002
+#define BM_PINCTRL_CTRL_IRQOUT0 0x00000001
+HW_REGISTER(HW_PINCTRL_MUXSEL0, REGS_PINCTRL_BASE, 0x00000100)
+#define HW_PINCTRL_MUXSEL0_ADDR (REGS_PINCTRL_BASE + 0x00000100)
+HW_REGISTER(HW_PINCTRL_MUXSEL1, REGS_PINCTRL_BASE, 0x00000110)
+#define HW_PINCTRL_MUXSEL1_ADDR (REGS_PINCTRL_BASE + 0x00000110)
+HW_REGISTER(HW_PINCTRL_MUXSEL2, REGS_PINCTRL_BASE, 0x00000120)
+#define HW_PINCTRL_MUXSEL2_ADDR (REGS_PINCTRL_BASE + 0x00000120)
+HW_REGISTER(HW_PINCTRL_MUXSEL3, REGS_PINCTRL_BASE, 0x00000130)
+#define HW_PINCTRL_MUXSEL3_ADDR (REGS_PINCTRL_BASE + 0x00000130)
+HW_REGISTER(HW_PINCTRL_MUXSEL4, REGS_PINCTRL_BASE, 0x00000140)
+#define HW_PINCTRL_MUXSEL4_ADDR (REGS_PINCTRL_BASE + 0x00000140)
+HW_REGISTER(HW_PINCTRL_MUXSEL5, REGS_PINCTRL_BASE, 0x00000150)
+#define HW_PINCTRL_MUXSEL5_ADDR (REGS_PINCTRL_BASE + 0x00000150)
+HW_REGISTER(HW_PINCTRL_MUXSEL6, REGS_PINCTRL_BASE, 0x00000160)
+#define HW_PINCTRL_MUXSEL6_ADDR (REGS_PINCTRL_BASE + 0x00000160)
+HW_REGISTER(HW_PINCTRL_MUXSEL7, REGS_PINCTRL_BASE, 0x00000170)
+#define HW_PINCTRL_MUXSEL7_ADDR (REGS_PINCTRL_BASE + 0x00000170)
+HW_REGISTER(HW_PINCTRL_DRIVE0, REGS_PINCTRL_BASE, 0x00000200)
+#define HW_PINCTRL_DRIVE0_ADDR (REGS_PINCTRL_BASE + 0x00000200)
+HW_REGISTER(HW_PINCTRL_DRIVE1, REGS_PINCTRL_BASE, 0x00000210)
+#define HW_PINCTRL_DRIVE1_ADDR (REGS_PINCTRL_BASE + 0x00000210)
+HW_REGISTER(HW_PINCTRL_DRIVE2, REGS_PINCTRL_BASE, 0x00000220)
+#define HW_PINCTRL_DRIVE2_ADDR (REGS_PINCTRL_BASE + 0x00000220)
+HW_REGISTER(HW_PINCTRL_DRIVE3, REGS_PINCTRL_BASE, 0x00000230)
+#define HW_PINCTRL_DRIVE3_ADDR (REGS_PINCTRL_BASE + 0x00000230)
+HW_REGISTER(HW_PINCTRL_DRIVE4, REGS_PINCTRL_BASE, 0x00000240)
+#define HW_PINCTRL_DRIVE4_ADDR (REGS_PINCTRL_BASE + 0x00000240)
+HW_REGISTER(HW_PINCTRL_DRIVE5, REGS_PINCTRL_BASE, 0x00000250)
+#define HW_PINCTRL_DRIVE5_ADDR (REGS_PINCTRL_BASE + 0x00000250)
+HW_REGISTER(HW_PINCTRL_DRIVE6, REGS_PINCTRL_BASE, 0x00000260)
+#define HW_PINCTRL_DRIVE6_ADDR (REGS_PINCTRL_BASE + 0x00000260)
+HW_REGISTER(HW_PINCTRL_DRIVE7, REGS_PINCTRL_BASE, 0x00000270)
+#define HW_PINCTRL_DRIVE7_ADDR (REGS_PINCTRL_BASE + 0x00000270)
+HW_REGISTER(HW_PINCTRL_DRIVE8, REGS_PINCTRL_BASE, 0x00000280)
+#define HW_PINCTRL_DRIVE8_ADDR (REGS_PINCTRL_BASE + 0x00000280)
+HW_REGISTER(HW_PINCTRL_DRIVE9, REGS_PINCTRL_BASE, 0x00000290)
+#define HW_PINCTRL_DRIVE9_ADDR (REGS_PINCTRL_BASE + 0x00000290)
+HW_REGISTER(HW_PINCTRL_DRIVE10, REGS_PINCTRL_BASE, 0x000002a0)
+#define HW_PINCTRL_DRIVE10_ADDR (REGS_PINCTRL_BASE + 0x000002a0)
+HW_REGISTER(HW_PINCTRL_DRIVE11, REGS_PINCTRL_BASE, 0x000002b0)
+#define HW_PINCTRL_DRIVE11_ADDR (REGS_PINCTRL_BASE + 0x000002b0)
+HW_REGISTER(HW_PINCTRL_DRIVE12, REGS_PINCTRL_BASE, 0x000002c0)
+#define HW_PINCTRL_DRIVE12_ADDR (REGS_PINCTRL_BASE + 0x000002c0)
+HW_REGISTER(HW_PINCTRL_DRIVE13, REGS_PINCTRL_BASE, 0x000002d0)
+#define HW_PINCTRL_DRIVE13_ADDR (REGS_PINCTRL_BASE + 0x000002d0)
+HW_REGISTER(HW_PINCTRL_DRIVE14, REGS_PINCTRL_BASE, 0x000002e0)
+#define HW_PINCTRL_DRIVE14_ADDR (REGS_PINCTRL_BASE + 0x000002e0)
+HW_REGISTER(HW_PINCTRL_PULL0, REGS_PINCTRL_BASE, 0x00000400)
+#define HW_PINCTRL_PULL0_ADDR (REGS_PINCTRL_BASE + 0x00000400)
+HW_REGISTER(HW_PINCTRL_PULL1, REGS_PINCTRL_BASE, 0x00000410)
+#define HW_PINCTRL_PULL1_ADDR (REGS_PINCTRL_BASE + 0x00000410)
+HW_REGISTER(HW_PINCTRL_PULL2, REGS_PINCTRL_BASE, 0x00000420)
+#define HW_PINCTRL_PULL2_ADDR (REGS_PINCTRL_BASE + 0x00000420)
+HW_REGISTER(HW_PINCTRL_PULL3, REGS_PINCTRL_BASE, 0x00000430)
+#define HW_PINCTRL_PULL3_ADDR (REGS_PINCTRL_BASE + 0x00000430)
+HW_REGISTER(HW_PINCTRL_DOUT0, REGS_PINCTRL_BASE, 0x00000500)
+#define HW_PINCTRL_DOUT0_ADDR (REGS_PINCTRL_BASE + 0x00000500)
+HW_REGISTER(HW_PINCTRL_DOUT1, REGS_PINCTRL_BASE, 0x00000510)
+#define HW_PINCTRL_DOUT1_ADDR (REGS_PINCTRL_BASE + 0x00000510)
+HW_REGISTER(HW_PINCTRL_DOUT2, REGS_PINCTRL_BASE, 0x00000520)
+#define HW_PINCTRL_DOUT2_ADDR (REGS_PINCTRL_BASE + 0x00000520)
+HW_REGISTER(HW_PINCTRL_DIN0, REGS_PINCTRL_BASE, 0x00000600)
+#define HW_PINCTRL_DIN0_ADDR (REGS_PINCTRL_BASE + 0x00000600)
+HW_REGISTER(HW_PINCTRL_DIN1, REGS_PINCTRL_BASE, 0x00000610)
+#define HW_PINCTRL_DIN1_ADDR (REGS_PINCTRL_BASE + 0x00000610)
+HW_REGISTER(HW_PINCTRL_DIN2, REGS_PINCTRL_BASE, 0x00000620)
+#define HW_PINCTRL_DIN2_ADDR (REGS_PINCTRL_BASE + 0x00000620)
+HW_REGISTER(HW_PINCTRL_DOE0, REGS_PINCTRL_BASE, 0x00000700)
+#define HW_PINCTRL_DOE0_ADDR (REGS_PINCTRL_BASE + 0x00000700)
+HW_REGISTER(HW_PINCTRL_DOE1, REGS_PINCTRL_BASE, 0x00000710)
+#define HW_PINCTRL_DOE1_ADDR (REGS_PINCTRL_BASE + 0x00000710)
+HW_REGISTER(HW_PINCTRL_DOE2, REGS_PINCTRL_BASE, 0x00000720)
+#define HW_PINCTRL_DOE2_ADDR (REGS_PINCTRL_BASE + 0x00000720)
+HW_REGISTER(HW_PINCTRL_PIN2IRQ0, REGS_PINCTRL_BASE, 0x00000800)
+#define HW_PINCTRL_PIN2IRQ0_ADDR (REGS_PINCTRL_BASE + 0x00000800)
+HW_REGISTER(HW_PINCTRL_PIN2IRQ1, REGS_PINCTRL_BASE, 0x00000810)
+#define HW_PINCTRL_PIN2IRQ1_ADDR (REGS_PINCTRL_BASE + 0x00000810)
+HW_REGISTER(HW_PINCTRL_PIN2IRQ2, REGS_PINCTRL_BASE, 0x00000820)
+#define HW_PINCTRL_PIN2IRQ2_ADDR (REGS_PINCTRL_BASE + 0x00000820)
+HW_REGISTER(HW_PINCTRL_IRQEN0, REGS_PINCTRL_BASE, 0x00000900)
+#define HW_PINCTRL_IRQEN0_ADDR (REGS_PINCTRL_BASE + 0x00000900)
+HW_REGISTER(HW_PINCTRL_IRQEN1, REGS_PINCTRL_BASE, 0x00000910)
+#define HW_PINCTRL_IRQEN1_ADDR (REGS_PINCTRL_BASE + 0x00000910)
+HW_REGISTER(HW_PINCTRL_IRQEN2, REGS_PINCTRL_BASE, 0x00000920)
+#define HW_PINCTRL_IRQEN2_ADDR (REGS_PINCTRL_BASE + 0x00000920)
+HW_REGISTER(HW_PINCTRL_IRQLEVEL0, REGS_PINCTRL_BASE, 0x00000a00)
+#define HW_PINCTRL_IRQLEVEL0_ADDR (REGS_PINCTRL_BASE + 0x00000a00)
+HW_REGISTER(HW_PINCTRL_IRQLEVEL1, REGS_PINCTRL_BASE, 0x00000a10)
+#define HW_PINCTRL_IRQLEVEL1_ADDR (REGS_PINCTRL_BASE + 0x00000a10)
+HW_REGISTER(HW_PINCTRL_IRQLEVEL2, REGS_PINCTRL_BASE, 0x00000a20)
+#define HW_PINCTRL_IRQLEVEL2_ADDR (REGS_PINCTRL_BASE + 0x00000a20)
+HW_REGISTER(HW_PINCTRL_IRQPOL0, REGS_PINCTRL_BASE, 0x00000b00)
+#define HW_PINCTRL_IRQPOL0_ADDR (REGS_PINCTRL_BASE + 0x00000b00)
+HW_REGISTER(HW_PINCTRL_IRQPOL1, REGS_PINCTRL_BASE, 0x00000b10)
+#define HW_PINCTRL_IRQPOL1_ADDR (REGS_PINCTRL_BASE + 0x00000b10)
+HW_REGISTER(HW_PINCTRL_IRQPOL2, REGS_PINCTRL_BASE, 0x00000b20)
+#define HW_PINCTRL_IRQPOL2_ADDR (REGS_PINCTRL_BASE + 0x00000b20)
+HW_REGISTER(HW_PINCTRL_IRQSTAT0, REGS_PINCTRL_BASE, 0x00000c00)
+#define HW_PINCTRL_IRQSTAT0_ADDR (REGS_PINCTRL_BASE + 0x00000c00)
+HW_REGISTER(HW_PINCTRL_IRQSTAT1, REGS_PINCTRL_BASE, 0x00000c10)
+#define HW_PINCTRL_IRQSTAT1_ADDR (REGS_PINCTRL_BASE + 0x00000c10)
+HW_REGISTER(HW_PINCTRL_IRQSTAT2, REGS_PINCTRL_BASE, 0x00000c20)
+#define HW_PINCTRL_IRQSTAT2_ADDR (REGS_PINCTRL_BASE + 0x00000c20)
+#endif /* __ARCH_ARM___PINCTRL_H */
diff --git a/arch/arm/mach-stmp378x/include/mach/regs-power.h b/arch/arm/mach-stmp378x/include/mach/regs-power.h
new file mode 100644
index 000000000000..1c81afeed531
--- /dev/null
+++ b/arch/arm/mach-stmp378x/include/mach/regs-power.h
@@ -0,0 +1,32 @@
+/*
+ * STMP POWER Register Definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ * Copyright 2008 Embedded Alley Solutions, 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; 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
+ */
+
+#ifndef __ARCH_ARM___POWER_H
+#define __ARCH_ARM___POWER_H 1
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_POWER_BASE (void __iomem *)(REGS_BASE + 0x44000)
+#define REGS_POWER_BASE_PHYS (0x80044000)
+#define REGS_POWER_SIZE 0x00002000
+HW_REGISTER(HW_POWER_MINPWR, REGS_POWER_BASE, 0x00000020)
+HW_REGISTER(HW_POWER_CHARGE, REGS_POWER_BASE, 0x00000030)
+#endif /* __ARCH_ARM___POWER_H */
diff --git a/arch/arm/mach-stmp378x/include/mach/regs-timrot.h b/arch/arm/mach-stmp378x/include/mach/regs-timrot.h
new file mode 100644
index 000000000000..bb6355acdfd1
--- /dev/null
+++ b/arch/arm/mach-stmp378x/include/mach/regs-timrot.h
@@ -0,0 +1,216 @@
+/*
+ * STMP TIMROT Register Definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ * Copyright 2008 Embedded Alley Solutions, 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; 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
+ */
+
+#ifndef __ARCH_ARM___TIMROT_H
+#define __ARCH_ARM___TIMROT_H 1
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_TIMROT_BASE (REGS_BASE + 0x68000)
+#define REGS_TIMROT_BASE_PHYS (0x80068000)
+#define REGS_TIMROT_SIZE 0x00002000
+HW_REGISTER(HW_TIMROT_ROTCTRL, REGS_TIMROT_BASE, 0x00000000)
+#define HW_TIMROT_ROTCTRL_ADDR (REGS_TIMROT_BASE + 0x00000000)
+#define BM_TIMROT_ROTCTRL_SFTRST 0x80000000
+#define BM_TIMROT_ROTCTRL_CLKGATE 0x40000000
+#define BM_TIMROT_ROTCTRL_ROTARY_PRESENT 0x20000000
+#define BM_TIMROT_ROTCTRL_TIM3_PRESENT 0x10000000
+#define BM_TIMROT_ROTCTRL_TIM2_PRESENT 0x08000000
+#define BM_TIMROT_ROTCTRL_TIM1_PRESENT 0x04000000
+#define BM_TIMROT_ROTCTRL_TIM0_PRESENT 0x02000000
+#define BP_TIMROT_ROTCTRL_STATE 22
+#define BM_TIMROT_ROTCTRL_STATE 0x01C00000
+#define BF_TIMROT_ROTCTRL_STATE(v) \
+ (((v) << 22) & BM_TIMROT_ROTCTRL_STATE)
+#define BP_TIMROT_ROTCTRL_DIVIDER 16
+#define BM_TIMROT_ROTCTRL_DIVIDER 0x003F0000
+#define BF_TIMROT_ROTCTRL_DIVIDER(v) \
+ (((v) << 16) & BM_TIMROT_ROTCTRL_DIVIDER)
+#define BM_TIMROT_ROTCTRL_RELATIVE 0x00001000
+#define BP_TIMROT_ROTCTRL_OVERSAMPLE 10
+#define BM_TIMROT_ROTCTRL_OVERSAMPLE 0x00000C00
+#define BF_TIMROT_ROTCTRL_OVERSAMPLE(v) \
+ (((v) << 10) & BM_TIMROT_ROTCTRL_OVERSAMPLE)
+#define BV_TIMROT_ROTCTRL_OVERSAMPLE__8X 0x0
+#define BV_TIMROT_ROTCTRL_OVERSAMPLE__4X 0x1
+#define BV_TIMROT_ROTCTRL_OVERSAMPLE__2X 0x2
+#define BV_TIMROT_ROTCTRL_OVERSAMPLE__1X 0x3
+#define BM_TIMROT_ROTCTRL_POLARITY_B 0x00000200
+#define BM_TIMROT_ROTCTRL_POLARITY_A 0x00000100
+#define BP_TIMROT_ROTCTRL_SELECT_B 4
+#define BM_TIMROT_ROTCTRL_SELECT_B 0x00000070
+#define BF_TIMROT_ROTCTRL_SELECT_B(v) \
+ (((v) << 4) & BM_TIMROT_ROTCTRL_SELECT_B)
+#define BV_TIMROT_ROTCTRL_SELECT_B__NEVER_TICK 0x0
+#define BV_TIMROT_ROTCTRL_SELECT_B__PWM0 0x1
+#define BV_TIMROT_ROTCTRL_SELECT_B__PWM1 0x2
+#define BV_TIMROT_ROTCTRL_SELECT_B__PWM2 0x3
+#define BV_TIMROT_ROTCTRL_SELECT_B__PWM3 0x4
+#define BV_TIMROT_ROTCTRL_SELECT_B__PWM4 0x5
+#define BV_TIMROT_ROTCTRL_SELECT_B__ROTARYA 0x6
+#define BV_TIMROT_ROTCTRL_SELECT_B__ROTARYB 0x7
+#define BP_TIMROT_ROTCTRL_SELECT_A 0
+#define BM_TIMROT_ROTCTRL_SELECT_A 0x00000007
+#define BF_TIMROT_ROTCTRL_SELECT_A(v) \
+ (((v) << 0) & BM_TIMROT_ROTCTRL_SELECT_A)
+#define BV_TIMROT_ROTCTRL_SELECT_A__NEVER_TICK 0x0
+#define BV_TIMROT_ROTCTRL_SELECT_A__PWM0 0x1
+#define BV_TIMROT_ROTCTRL_SELECT_A__PWM1 0x2
+#define BV_TIMROT_ROTCTRL_SELECT_A__PWM2 0x3
+#define BV_TIMROT_ROTCTRL_SELECT_A__PWM3 0x4
+#define BV_TIMROT_ROTCTRL_SELECT_A__PWM4 0x5
+#define BV_TIMROT_ROTCTRL_SELECT_A__ROTARYA 0x6
+#define BV_TIMROT_ROTCTRL_SELECT_A__ROTARYB 0x7
+HW_REGISTER_0(HW_TIMROT_ROTCOUNT, REGS_TIMROT_BASE, 0x00000010)
+#define HW_TIMROT_ROTCOUNT_ADDR (REGS_TIMROT_BASE + 0x00000010)
+#define BP_TIMROT_ROTCOUNT_UPDOWN 0
+#define BM_TIMROT_ROTCOUNT_UPDOWN 0x0000FFFF
+#define BF_TIMROT_ROTCOUNT_UPDOWN(v) \
+ (((v) << 0) & BM_TIMROT_ROTCOUNT_UPDOWN)
+/*
+ * multi-register-define name HW_TIMROT_TIMCTRLn
+ * base 0x00000020
+ * count 3
+ * offset 0x20
+ */
+HW_REGISTER_INDEXED(HW_TIMROT_TIMCTRLn, REGS_TIMROT_BASE, 0x00000020, 0x20)
+#define BM_TIMROT_TIMCTRLn_IRQ 0x00008000
+#define BM_TIMROT_TIMCTRLn_IRQ_EN 0x00004000
+#define BM_TIMROT_TIMCTRLn_POLARITY 0x00000100
+#define BM_TIMROT_TIMCTRLn_UPDATE 0x00000080
+#define BM_TIMROT_TIMCTRLn_RELOAD 0x00000040
+#define BP_TIMROT_TIMCTRLn_PRESCALE 4
+#define BM_TIMROT_TIMCTRLn_PRESCALE 0x00000030
+#define BF_TIMROT_TIMCTRLn_PRESCALE(v) \
+ (((v) << 4) & BM_TIMROT_TIMCTRLn_PRESCALE)
+#define BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_1 0x0
+#define BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_2 0x1
+#define BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_4 0x2
+#define BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_8 0x3
+#define BP_TIMROT_TIMCTRLn_SELECT 0
+#define BM_TIMROT_TIMCTRLn_SELECT 0x0000000F
+#define BF_TIMROT_TIMCTRLn_SELECT(v) \
+ (((v) << 0) & BM_TIMROT_TIMCTRLn_SELECT)
+#define BV_TIMROT_TIMCTRLn_SELECT__NEVER_TICK 0x0
+#define BV_TIMROT_TIMCTRLn_SELECT__PWM0 0x1
+#define BV_TIMROT_TIMCTRLn_SELECT__PWM1 0x2
+#define BV_TIMROT_TIMCTRLn_SELECT__PWM2 0x3
+#define BV_TIMROT_TIMCTRLn_SELECT__PWM3 0x4
+#define BV_TIMROT_TIMCTRLn_SELECT__PWM4 0x5
+#define BV_TIMROT_TIMCTRLn_SELECT__ROTARYA 0x6
+#define BV_TIMROT_TIMCTRLn_SELECT__ROTARYB 0x7
+#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL 0x8
+#define BV_TIMROT_TIMCTRLn_SELECT__8KHZ_XTAL 0x9
+#define BV_TIMROT_TIMCTRLn_SELECT__4KHZ_XTAL 0xA
+#define BV_TIMROT_TIMCTRLn_SELECT__1KHZ_XTAL 0xB
+#define BV_TIMROT_TIMCTRLn_SELECT__TICK_ALWAYS 0xC
+/*
+ * multi-register-define name HW_TIMROT_TIMCOUNTn
+ * base 0x00000030
+ * count 3
+ * offset 0x20
+ */
+HW_REGISTER_0_INDEXED(HW_TIMROT_TIMCOUNTn, REGS_TIMROT_BASE, 0x00000030,
+ 0x20)
+#define BP_TIMROT_TIMCOUNTn_RUNNING_COUNT 16
+#define BM_TIMROT_TIMCOUNTn_RUNNING_COUNT 0xFFFF0000
+#define BF_TIMROT_TIMCOUNTn_RUNNING_COUNT(v) \
+ (((v) << 16) & BM_TIMROT_TIMCOUNTn_RUNNING_COUNT)
+#define BP_TIMROT_TIMCOUNTn_FIXED_COUNT 0
+#define BM_TIMROT_TIMCOUNTn_FIXED_COUNT 0x0000FFFF
+#define BF_TIMROT_TIMCOUNTn_FIXED_COUNT(v) \
+ (((v) << 0) & BM_TIMROT_TIMCOUNTn_FIXED_COUNT)
+HW_REGISTER(HW_TIMROT_TIMCTRL3, REGS_TIMROT_BASE, 0x00000080)
+#define HW_TIMROT_TIMCTRL3_ADDR (REGS_TIMROT_BASE + 0x00000080)
+#define BP_TIMROT_TIMCTRL3_TEST_SIGNAL 16
+#define BM_TIMROT_TIMCTRL3_TEST_SIGNAL 0x000F0000
+#define BF_TIMROT_TIMCTRL3_TEST_SIGNAL(v) \
+ (((v) << 16) & BM_TIMROT_TIMCTRL3_TEST_SIGNAL)
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__NEVER_TICK 0x0
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__PWM0 0x1
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__PWM1 0x2
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__PWM2 0x3
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__PWM3 0x4
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__PWM4 0x5
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__ROTARYA 0x6
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__ROTARYB 0x7
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__32KHZ_XTAL 0x8
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__8KHZ_XTAL 0x9
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__4KHZ_XTAL 0xA
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__1KHZ_XTAL 0xB
+#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__TICK_ALWAYS 0xC
+#define BM_TIMROT_TIMCTRL3_IRQ 0x00008000
+#define BM_TIMROT_TIMCTRL3_IRQ_EN 0x00004000
+#define BM_TIMROT_TIMCTRL3_DUTY_VALID 0x00000400
+#define BM_TIMROT_TIMCTRL3_DUTY_CYCLE 0x00000200
+#define BM_TIMROT_TIMCTRL3_POLARITY 0x00000100
+#define BM_TIMROT_TIMCTRL3_UPDATE 0x00000080
+#define BM_TIMROT_TIMCTRL3_RELOAD 0x00000040
+#define BP_TIMROT_TIMCTRL3_PRESCALE 4
+#define BM_TIMROT_TIMCTRL3_PRESCALE 0x00000030
+#define BF_TIMROT_TIMCTRL3_PRESCALE(v) \
+ (((v) << 4) & BM_TIMROT_TIMCTRL3_PRESCALE)
+#define BV_TIMROT_TIMCTRL3_PRESCALE__DIV_BY_1 0x0
+#define BV_TIMROT_TIMCTRL3_PRESCALE__DIV_BY_2 0x1
+#define BV_TIMROT_TIMCTRL3_PRESCALE__DIV_BY_4 0x2
+#define BV_TIMROT_TIMCTRL3_PRESCALE__DIV_BY_8 0x3
+#define BP_TIMROT_TIMCTRL3_SELECT 0
+#define BM_TIMROT_TIMCTRL3_SELECT 0x0000000F
+#define BF_TIMROT_TIMCTRL3_SELECT(v) \
+ (((v) << 0) & BM_TIMROT_TIMCTRL3_SELECT)
+#define BV_TIMROT_TIMCTRL3_SELECT__NEVER_TICK 0x0
+#define BV_TIMROT_TIMCTRL3_SELECT__PWM0 0x1
+#define BV_TIMROT_TIMCTRL3_SELECT__PWM1 0x2
+#define BV_TIMROT_TIMCTRL3_SELECT__PWM2 0x3
+#define BV_TIMROT_TIMCTRL3_SELECT__PWM3 0x4
+#define BV_TIMROT_TIMCTRL3_SELECT__PWM4 0x5
+#define BV_TIMROT_TIMCTRL3_SELECT__ROTARYA 0x6
+#define BV_TIMROT_TIMCTRL3_SELECT__ROTARYB 0x7
+#define BV_TIMROT_TIMCTRL3_SELECT__32KHZ_XTAL 0x8
+#define BV_TIMROT_TIMCTRL3_SELECT__8KHZ_XTAL 0x9
+#define BV_TIMROT_TIMCTRL3_SELECT__4KHZ_XTAL 0xA
+#define BV_TIMROT_TIMCTRL3_SELECT__1KHZ_XTAL 0xB
+#define BV_TIMROT_TIMCTRL3_SELECT__TICK_ALWAYS 0xC
+HW_REGISTER_0(HW_TIMROT_TIMCOUNT3, REGS_TIMROT_BASE, 0x00000090)
+#define HW_TIMROT_TIMCOUNT3_ADDR (REGS_TIMROT_BASE + 0x00000090)
+#define BP_TIMROT_TIMCOUNT3_LOW_RUNNING_COUNT 16
+#define BM_TIMROT_TIMCOUNT3_LOW_RUNNING_COUNT 0xFFFF0000
+#define BF_TIMROT_TIMCOUNT3_LOW_RUNNING_COUNT(v) \
+ (((v) << 16) & BM_TIMROT_TIMCOUNT3_LOW_RUNNING_COUNT)
+#define BP_TIMROT_TIMCOUNT3_HIGH_FIXED_COUNT 0
+#define BM_TIMROT_TIMCOUNT3_HIGH_FIXED_COUNT 0x0000FFFF
+#define BF_TIMROT_TIMCOUNT3_HIGH_FIXED_COUNT(v) \
+ (((v) << 0) & BM_TIMROT_TIMCOUNT3_HIGH_FIXED_COUNT)
+HW_REGISTER_0(HW_TIMROT_VERSION, REGS_TIMROT_BASE, 0x000000a0)
+#define HW_TIMROT_VERSION_ADDR (REGS_TIMROT_BASE + 0x000000a0)
+#define BP_TIMROT_VERSION_MAJOR 24
+#define BM_TIMROT_VERSION_MAJOR 0xFF000000
+#define BF_TIMROT_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_TIMROT_VERSION_MAJOR)
+#define BP_TIMROT_VERSION_MINOR 16
+#define BM_TIMROT_VERSION_MINOR 0x00FF0000
+#define BF_TIMROT_VERSION_MINOR(v) \
+ (((v) << 16) & BM_TIMROT_VERSION_MINOR)
+#define BP_TIMROT_VERSION_STEP 0
+#define BM_TIMROT_VERSION_STEP 0x0000FFFF
+#define BF_TIMROT_VERSION_STEP(v) \
+ (((v) << 0) & BM_TIMROT_VERSION_STEP)
+#endif /* __ARCH_ARM___TIMROT_H */
diff --git a/arch/arm/mach-stmp378x/stmp378x.c b/arch/arm/mach-stmp378x/stmp378x.c
new file mode 100644
index 000000000000..f156ec7306c0
--- /dev/null
+++ b/arch/arm/mach-stmp378x/stmp378x.c
@@ -0,0 +1,225 @@
+/*
+ * Freescale STMP378X platform support
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+
+#include <asm/dma.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/pins.h>
+#include <mach/pinmux.h>
+#include <mach/dma.h>
+#include <mach/hardware.h>
+#include <mach/system.h>
+#include <mach/platform.h>
+#include <mach/stmp3xxx.h>
+#include <mach/regs-icoll.h>
+#include <mach/regs-apbh.h>
+#include <mach/regs-apbx.h>
+
+#include "stmp378x.h"
+/*
+ * IRQ handling
+ */
+static void stmp378x_ack_irq(unsigned int irq)
+{
+ /* Tell ICOLL to release IRQ line */
+ HW_ICOLL_VECTOR_WR(0x0);
+
+ /* ACK current interrupt */
+ HW_ICOLL_LEVELACK_WR(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0);
+
+ /* Barrier */
+ (void) HW_ICOLL_STAT_RD();
+}
+
+static void stmp378x_mask_irq(unsigned int irq)
+{
+ /* IRQ disable */
+ HW_ICOLL_INTERRUPTn_CLR(irq, BM_ICOLL_INTERRUPTn_ENABLE);
+}
+
+static void stmp378x_unmask_irq(unsigned int irq)
+{
+ /* IRQ enable */
+ HW_ICOLL_INTERRUPTn_SET(irq, BM_ICOLL_INTERRUPTn_ENABLE);
+}
+
+static struct irq_chip stmp378x_chip = {
+ .ack = stmp378x_ack_irq,
+ .mask = stmp378x_mask_irq,
+ .unmask = stmp378x_unmask_irq,
+};
+
+void __init stmp378x_init_irq(void)
+{
+ stmp3xxx_init_irq(&stmp378x_chip);
+}
+
+/*
+ * DMA interrupt handling
+ */
+void stmp3xxx_arch_dma_enable_interrupt(int channel)
+{
+ int dmabus = channel / 16;
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ HW_APBH_CTRL1_SET(1 << (16 + (channel % 16)));
+ HW_APBH_CTRL2_SET(1 << (16 + (channel % 16)));
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ HW_APBX_CTRL1_SET(1 << (16 + (channel % 16)));
+ HW_APBX_CTRL2_SET(1 << (16 + (channel % 16)));
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt);
+
+void stmp3xxx_arch_dma_clear_interrupt(int channel)
+{
+ int dmabus = channel / 16;
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ HW_APBH_CTRL1_CLR(1 << (channel % 16));
+ HW_APBH_CTRL2_CLR(1 << (channel % 16));
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ HW_APBX_CTRL1_CLR(1 << (channel % 16));
+ HW_APBX_CTRL2_CLR(1 << (channel % 16));
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt);
+
+int stmp3xxx_arch_dma_is_interrupt(int channel)
+{
+ int dmabus = channel / 16;
+ int r = 0;
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ r = HW_APBH_CTRL1_RD() & (1 << (channel % 16));
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ r = HW_APBX_CTRL1_RD() & (1 << (channel % 16));
+ break;
+ }
+ return r;
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt);
+
+void stmp3xxx_arch_dma_reset_channel(int channel)
+{
+ int dmabus = channel / 16;
+ unsigned chbit = 1 << (channel % 16);
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ /* Reset channel and wait for it to complete */
+ HW_APBH_CTRL0_SET(chbit <<
+ BP_APBH_CTRL0_RESET_CHANNEL);
+ while (HW_APBH_CTRL0_RD() &
+ (chbit << BP_APBH_CTRL0_RESET_CHANNEL))
+ continue;
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ /* Reset channel and wait for it to complete */
+ HW_APBX_CHANNEL_CTRL_SET(
+ BF_APBX_CHANNEL_CTRL_RESET_CHANNEL(chbit));
+ while (HW_APBX_CHANNEL_CTRL_RD() &
+ BF_APBX_CHANNEL_CTRL_RESET_CHANNEL(chbit))
+ continue;
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel);
+
+void stmp3xxx_arch_dma_freeze(int channel)
+{
+ int dmabus = channel / 16;
+ unsigned chbit = 1 << (channel % 16);
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ HW_APBH_CTRL0_SET(1<<chbit);
+ break;
+ case STMP3XXX_BUS_APBX:
+ HW_APBX_CHANNEL_CTRL_SET(1<<chbit);
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_freeze);
+
+void stmp3xxx_arch_dma_unfreeze(int channel)
+{
+ int dmabus = channel / 16;
+ unsigned chbit = 1 << (channel % 16);
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ HW_APBH_CTRL0_CLR(1<<chbit);
+ break;
+ case STMP3XXX_BUS_APBX:
+ HW_APBX_CHANNEL_CTRL_CLR(1<<chbit);
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_unfreeze);
+
+/*
+ * The registers are all very closely mapped, so we might as well map them all
+ * with a single mapping
+ *
+ * Logical Physical
+ * f0000000 80000000 On-chip registers
+ * f1000000 00000000 256k on-chip SRAM
+ */
+
+static struct map_desc stmp378x_io_desc[] __initdata = {
+ {
+ .virtual = (u32)STMP3XXX_REGS_BASE,
+ .pfn = __phys_to_pfn(STMP3XXX_REGS_PHBASE),
+ .length = STMP3XXX_REGS_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (u32)STMP3XXX_OCRAM_BASE,
+ .pfn = __phys_to_pfn(STMP3XXX_OCRAM_PHBASE),
+ .length = STMP3XXX_OCRAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init stmp378x_map_io(void)
+{
+ iotable_init(stmp378x_io_desc, ARRAY_SIZE(stmp378x_io_desc));
+}
diff --git a/arch/arm/mach-stmp378x/stmp378x.h b/arch/arm/mach-stmp378x/stmp378x.h
new file mode 100644
index 000000000000..473de64cf8f7
--- /dev/null
+++ b/arch/arm/mach-stmp378x/stmp378x.h
@@ -0,0 +1,24 @@
+/*
+ * Freescale STMP37XX/STMP378X internal functions and data declarations
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __MACH_STMP378X_H
+#define __MACH_STMP378X_H
+
+void stmp378x_map_io(void);
+void stmp378x_init_irq(void);
+
+#endif /* __MACH_STMP378X_COMMON_H */
diff --git a/arch/arm/mach-stmp378x/stmp378x_devb.c b/arch/arm/mach-stmp378x/stmp378x_devb.c
new file mode 100644
index 000000000000..bc643f686b11
--- /dev/null
+++ b/arch/arm/mach-stmp378x/stmp378x_devb.c
@@ -0,0 +1,80 @@
+/*
+ * Freescale STMP378X development board support
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pins.h>
+#include <mach/pinmux.h>
+#include <mach/stmp3xxx.h>
+
+#include "stmp378x.h"
+
+static struct platform_device *devices[] = {
+ &stmp3xxx_dbguart,
+};
+
+static struct pin_desc dbguart_pins_0[] = {
+ { PINID_PWM0, PIN_FUN3, },
+ { PINID_PWM1, PIN_FUN3, },
+};
+
+static struct pin_group dbguart_pins[] = {
+ [0] = {
+ .pins = dbguart_pins_0,
+ .nr_pins = ARRAY_SIZE(dbguart_pins_0),
+ },
+};
+
+static int dbguart_pins_control(int id, int request)
+{
+ int r = 0;
+
+ if (request)
+ r = stmp3xxx_request_pin_group(&dbguart_pins[id], "debug uart");
+ else
+ stmp3xxx_release_pin_group(&dbguart_pins[id], "debug uart");
+ return r;
+}
+
+static void __init stmp378x_devb_init(void)
+{
+ stmp3xxx_pinmux_init(NR_REAL_IRQS);
+
+ /* init stmp3xxx platform */
+ stmp3xxx_init();
+
+ stmp3xxx_dbguart.dev.platform_data = dbguart_pins_control;
+
+ /* add board's devices */
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(STMP378X, "STMP378X")
+ .phys_io = 0x80000000,
+ .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
+ .boot_params = 0x40000100,
+ .map_io = stmp378x_map_io,
+ .init_irq = stmp378x_init_irq,
+ .timer = &stmp3xxx_timer,
+ .init_machine = stmp378x_devb_init,
+MACHINE_END
diff --git a/arch/arm/mach-stmp37xx/Makefile b/arch/arm/mach-stmp37xx/Makefile
new file mode 100644
index 000000000000..57deffd09fbf
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARCH_STMP37XX) += stmp37xx.o
+obj-$(CONFIG_MACH_STMP37XX) += stmp37xx_devb.o
diff --git a/arch/arm/mach-stmp37xx/Makefile.boot b/arch/arm/mach-stmp37xx/Makefile.boot
new file mode 100644
index 000000000000..1568ad404d59
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x40008000
+params_phys-y := 0x40000100
+initrd_phys-y := 0x40800000
diff --git a/arch/arm/mach-stmp37xx/include/mach/entry-macro.S b/arch/arm/mach-stmp37xx/include/mach/entry-macro.S
new file mode 100644
index 000000000000..fed2787b6c34
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/include/mach/entry-macro.S
@@ -0,0 +1,37 @@
+/*
+ * Low-level IRQ helper macros for Freescale STMP37XX
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ mov \base, #0xf0000000 @ vm address of IRQ controller
+ ldr \irqnr, [\base, #0x30] @ HW_ICOLL_STAT
+ cmp \irqnr, #0x3f
+ movne \irqstat, #0 @ Ack this IRQ
+ strne \irqstat, [\base, #0x00]@ HW_ICOLL_VECTOR
+ moveqs \irqnr, #0 @ Zero flag set for no IRQ
+
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
diff --git a/arch/arm/mach-stmp37xx/include/mach/irqs.h b/arch/arm/mach-stmp37xx/include/mach/irqs.h
new file mode 100644
index 000000000000..98f12938550d
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/include/mach/irqs.h
@@ -0,0 +1,99 @@
+/*
+ * Freescale STMP37XX interrupts
+ *
+ * Copyright (C) 2005 Sigmatel Inc
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef _ASM_ARCH_IRQS_H
+#define _ASM_ARCH_IRQS_H
+
+#define IRQ_DEBUG_UART 0
+#define IRQ_COMMS_RX 1
+#define IRQ_COMMS_TX 1
+#define IRQ_SSP2_ERROR 2
+#define IRQ_VDD5V 3
+#define IRQ_HEADPHONE_SHORT 4
+#define IRQ_DAC_DMA 5
+#define IRQ_DAC_ERROR 6
+#define IRQ_ADC_DMA 7
+#define IRQ_ADC_ERROR 8
+#define IRQ_SPDIF_DMA 9
+#define IRQ_SAIF2_DMA 9
+#define IRQ_SPDIF_ERROR 10
+#define IRQ_SAIF1_IRQ 10
+#define IRQ_SAIF2_IRQ 10
+#define IRQ_USB_CTRL 11
+#define IRQ_USB_WAKEUP 12
+#define IRQ_GPMI_DMA 13
+#define IRQ_SSP1_DMA 14
+#define IRQ_SSP_ERROR 15
+#define IRQ_GPIO0 16
+#define IRQ_GPIO1 17
+#define IRQ_GPIO2 18
+#define IRQ_SAIF1_DMA 19
+#define IRQ_SSP2_DMA 20
+#define IRQ_ECC8_IRQ 21
+#define IRQ_RTC_ALARM 22
+#define IRQ_UARTAPP_TX_DMA 23
+#define IRQ_UARTAPP_INTERNAL 24
+#define IRQ_UARTAPP_RX_DMA 25
+#define IRQ_I2C_DMA 26
+#define IRQ_I2C_ERROR 27
+#define IRQ_TIMER0 28
+#define IRQ_TIMER1 29
+#define IRQ_TIMER2 30
+#define IRQ_TIMER3 31
+#define IRQ_BATT_BRNOUT 32
+#define IRQ_VDDD_BRNOUT 33
+#define IRQ_VDDIO_BRNOUT 34
+#define IRQ_VDD18_BRNOUT 35
+#define IRQ_TOUCH_DETECT 36
+#define IRQ_LRADC_CH0 37
+#define IRQ_LRADC_CH1 38
+#define IRQ_LRADC_CH2 39
+#define IRQ_LRADC_CH3 40
+#define IRQ_LRADC_CH4 41
+#define IRQ_LRADC_CH5 42
+#define IRQ_LRADC_CH6 43
+#define IRQ_LRADC_CH7 44
+#define IRQ_LCDIF_DMA 45
+#define IRQ_LCDIF_ERROR 46
+#define IRQ_DIGCTL_DEBUG_TRAP 47
+#define IRQ_RTC_1MSEC 48
+#define IRQ_DRI_DMA 49
+#define IRQ_DRI_ATTENTION 50
+#define IRQ_GPMI_ATTENTION 51
+#define IRQ_IR 52
+#define IRQ_DCP_VMI 53
+#define IRQ_DCP 54
+#define IRQ_RESERVED_55 55
+#define IRQ_RESERVED_56 56
+#define IRQ_RESERVED_57 57
+#define IRQ_RESERVED_58 58
+#define IRQ_RESERVED_59 59
+#define SW_IRQ_60 60
+#define SW_IRQ_61 61
+#define SW_IRQ_62 62
+#define SW_IRQ_63 63
+
+#define NR_REAL_IRQS 64
+#define NR_IRQS (NR_REAL_IRQS + 32 * 3)
+
+/* TIMER and BRNOUT are FIQ capable */
+#define FIQ_START IRQ_TIMER0
+
+/* Hard disk IRQ is a GPMI attention IRQ */
+#define IRQ_HARDDISK IRQ_GPMI_ATTENTION
+
+#endif /* _ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-stmp37xx/include/mach/pins.h b/arch/arm/mach-stmp37xx/include/mach/pins.h
new file mode 100644
index 000000000000..d56de0c471d8
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/include/mach/pins.h
@@ -0,0 +1,147 @@
+/*
+ * Freescale STMP37XX SoC pin multiplexing
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_PINS_H
+#define __ASM_ARCH_PINS_H
+
+/*
+ * Define all STMP37XX pins, a pin name corresponds to a STMP37xx hardware
+ * interface this pin belongs to.
+ */
+
+/* Bank 0 */
+#define PINID_GPMI_D00 STMP3XXX_PINID(0, 0)
+#define PINID_GPMI_D01 STMP3XXX_PINID(0, 1)
+#define PINID_GPMI_D02 STMP3XXX_PINID(0, 2)
+#define PINID_GPMI_D03 STMP3XXX_PINID(0, 3)
+#define PINID_GPMI_D04 STMP3XXX_PINID(0, 4)
+#define PINID_GPMI_D05 STMP3XXX_PINID(0, 5)
+#define PINID_GPMI_D06 STMP3XXX_PINID(0, 6)
+#define PINID_GPMI_D07 STMP3XXX_PINID(0, 7)
+#define PINID_GPMI_D08 STMP3XXX_PINID(0, 8)
+#define PINID_GPMI_D09 STMP3XXX_PINID(0, 9)
+#define PINID_GPMI_D10 STMP3XXX_PINID(0, 10)
+#define PINID_GPMI_D11 STMP3XXX_PINID(0, 11)
+#define PINID_GPMI_D12 STMP3XXX_PINID(0, 12)
+#define PINID_GPMI_D13 STMP3XXX_PINID(0, 13)
+#define PINID_GPMI_D14 STMP3XXX_PINID(0, 14)
+#define PINID_GPMI_D15 STMP3XXX_PINID(0, 15)
+#define PINID_GPMI_A0 STMP3XXX_PINID(0, 16)
+#define PINID_GPMI_A1 STMP3XXX_PINID(0, 17)
+#define PINID_GPMI_A2 STMP3XXX_PINID(0, 18)
+#define PINID_GPMI_RDY0 STMP3XXX_PINID(0, 19)
+#define PINID_GPMI_RDY2 STMP3XXX_PINID(0, 20)
+#define PINID_GPMI_RDY3 STMP3XXX_PINID(0, 21)
+#define PINID_GPMI_RESETN STMP3XXX_PINID(0, 22)
+#define PINID_GPMI_IRQ STMP3XXX_PINID(0, 23)
+#define PINID_GPMI_WRN STMP3XXX_PINID(0, 24)
+#define PINID_GPMI_RDN STMP3XXX_PINID(0, 25)
+#define PINID_UART2_CTS STMP3XXX_PINID(0, 26)
+#define PINID_UART2_RTS STMP3XXX_PINID(0, 27)
+#define PINID_UART2_RX STMP3XXX_PINID(0, 28)
+#define PINID_UART2_TX STMP3XXX_PINID(0, 29)
+
+/* Bank 1 */
+#define PINID_LCD_D00 STMP3XXX_PINID(1, 0)
+#define PINID_LCD_D01 STMP3XXX_PINID(1, 1)
+#define PINID_LCD_D02 STMP3XXX_PINID(1, 2)
+#define PINID_LCD_D03 STMP3XXX_PINID(1, 3)
+#define PINID_LCD_D04 STMP3XXX_PINID(1, 4)
+#define PINID_LCD_D05 STMP3XXX_PINID(1, 5)
+#define PINID_LCD_D06 STMP3XXX_PINID(1, 6)
+#define PINID_LCD_D07 STMP3XXX_PINID(1, 7)
+#define PINID_LCD_D08 STMP3XXX_PINID(1, 8)
+#define PINID_LCD_D09 STMP3XXX_PINID(1, 9)
+#define PINID_LCD_D10 STMP3XXX_PINID(1, 10)
+#define PINID_LCD_D11 STMP3XXX_PINID(1, 11)
+#define PINID_LCD_D12 STMP3XXX_PINID(1, 12)
+#define PINID_LCD_D13 STMP3XXX_PINID(1, 13)
+#define PINID_LCD_D14 STMP3XXX_PINID(1, 14)
+#define PINID_LCD_D15 STMP3XXX_PINID(1, 15)
+#define PINID_LCD_RESET STMP3XXX_PINID(1, 16)
+#define PINID_LCD_RS STMP3XXX_PINID(1, 17)
+#define PINID_LCD_WR_RWN STMP3XXX_PINID(1, 18)
+#define PINID_LCD_RD_E STMP3XXX_PINID(1, 19)
+#define PINID_LCD_CS STMP3XXX_PINID(1, 20)
+#define PINID_LCD_BUSY STMP3XXX_PINID(1, 21)
+#define PINID_SSP1_CMD STMP3XXX_PINID(1, 22)
+#define PINID_SSP1_SCK STMP3XXX_PINID(1, 23)
+#define PINID_SSP1_DATA0 STMP3XXX_PINID(1, 24)
+#define PINID_SSP1_DATA1 STMP3XXX_PINID(1, 25)
+#define PINID_SSP1_DATA2 STMP3XXX_PINID(1, 26)
+#define PINID_SSP1_DATA3 STMP3XXX_PINID(1, 27)
+#define PINID_SSP1_DETECT STMP3XXX_PINID(1, 28)
+
+/* Bank 2 */
+#define PINID_PWM0 STMP3XXX_PINID(2, 0)
+#define PINID_PWM1 STMP3XXX_PINID(2, 1)
+#define PINID_PWM2 STMP3XXX_PINID(2, 2)
+#define PINID_PWM3 STMP3XXX_PINID(2, 3)
+#define PINID_PWM4 STMP3XXX_PINID(2, 4)
+#define PINID_I2C_SCL STMP3XXX_PINID(2, 5)
+#define PINID_I2C_SDA STMP3XXX_PINID(2, 6)
+#define PINID_ROTTARYA STMP3XXX_PINID(2, 7)
+#define PINID_ROTTARYB STMP3XXX_PINID(2, 8)
+#define PINID_EMI_CKE STMP3XXX_PINID(2, 9)
+#define PINID_EMI_RASN STMP3XXX_PINID(2, 10)
+#define PINID_EMI_CASN STMP3XXX_PINID(2, 11)
+#define PINID_EMI_CE0N STMP3XXX_PINID(2, 12)
+#define PINID_EMI_CE1N STMP3XXX_PINID(2, 13)
+#define PINID_EMI_CE2N STMP3XXX_PINID(2, 14)
+#define PINID_EMI_CE3N STMP3XXX_PINID(2, 15)
+#define PINID_EMI_A00 STMP3XXX_PINID(2, 16)
+#define PINID_EMI_A01 STMP3XXX_PINID(2, 17)
+#define PINID_EMI_A02 STMP3XXX_PINID(2, 18)
+#define PINID_EMI_A03 STMP3XXX_PINID(2, 19)
+#define PINID_EMI_A04 STMP3XXX_PINID(2, 20)
+#define PINID_EMI_A05 STMP3XXX_PINID(2, 21)
+#define PINID_EMI_A06 STMP3XXX_PINID(2, 22)
+#define PINID_EMI_A07 STMP3XXX_PINID(2, 23)
+#define PINID_EMI_A08 STMP3XXX_PINID(2, 24)
+#define PINID_EMI_A09 STMP3XXX_PINID(2, 25)
+#define PINID_EMI_A10 STMP3XXX_PINID(2, 26)
+#define PINID_EMI_A11 STMP3XXX_PINID(2, 27)
+#define PINID_EMI_A12 STMP3XXX_PINID(2, 28)
+#define PINID_EMI_A13 STMP3XXX_PINID(2, 29)
+#define PINID_EMI_A14 STMP3XXX_PINID(2, 30)
+#define PINID_EMI_WEN STMP3XXX_PINID(2, 31)
+
+/* Bank 3 */
+#define PINID_EMI_D00 STMP3XXX_PINID(3, 0)
+#define PINID_EMI_D01 STMP3XXX_PINID(3, 1)
+#define PINID_EMI_D02 STMP3XXX_PINID(3, 2)
+#define PINID_EMI_D03 STMP3XXX_PINID(3, 3)
+#define PINID_EMI_D04 STMP3XXX_PINID(3, 4)
+#define PINID_EMI_D05 STMP3XXX_PINID(3, 5)
+#define PINID_EMI_D06 STMP3XXX_PINID(3, 6)
+#define PINID_EMI_D07 STMP3XXX_PINID(3, 7)
+#define PINID_EMI_D08 STMP3XXX_PINID(3, 8)
+#define PINID_EMI_D09 STMP3XXX_PINID(3, 9)
+#define PINID_EMI_D10 STMP3XXX_PINID(3, 10)
+#define PINID_EMI_D11 STMP3XXX_PINID(3, 11)
+#define PINID_EMI_D12 STMP3XXX_PINID(3, 12)
+#define PINID_EMI_D13 STMP3XXX_PINID(3, 13)
+#define PINID_EMI_D14 STMP3XXX_PINID(3, 14)
+#define PINID_EMI_D15 STMP3XXX_PINID(3, 15)
+#define PINID_EMI_DQS0 STMP3XXX_PINID(3, 16)
+#define PINID_EMI_DQS1 STMP3XXX_PINID(3, 17)
+#define PINID_EMI_DQM0 STMP3XXX_PINID(3, 18)
+#define PINID_EMI_DQM1 STMP3XXX_PINID(3, 19)
+#define PINID_EMI_CLK STMP3XXX_PINID(3, 20)
+#define PINID_EMI_CLKN STMP3XXX_PINID(3, 21)
+
+#endif /* __ASM_ARCH_PINS_H */
diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-apbh.h b/arch/arm/mach-stmp37xx/include/mach/regs-apbh.h
new file mode 100644
index 000000000000..3044c20ad90c
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/include/mach/regs-apbh.h
@@ -0,0 +1,102 @@
+/*
+ * STMP APBH Register Definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ * Copyright 2008 Embedded Alley Solutions, 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; 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
+ */
+#ifndef _INCLUDE_ASM_ARCH_REGS_APBH_H
+#define _INCLUDE_ASM_ARCH_REGS_APBH_H
+
+#include <mach/stmp3xxx_regs.h>
+
+#ifndef REGS_APBH_BASE
+#define REGS_APBH_BASE (REGS_BASE + 0x00004000)
+#endif
+
+HW_REGISTER(HW_APBH_CTRL0, REGS_APBH_BASE, 0x00)
+#define BP_APBH_CTRL0_SFTRST 31
+#define BM_APBH_CTRL0_SFTRST 0x80000000
+#define BP_APBH_CTRL0_CLKGATE 30
+#define BM_APBH_CTRL0_CLKGATE 0x40000000
+#define BP_APBH_CTRL0_RESET_CHANNEL 16
+#define BM_APBH_CTRL0_RESET_CHANNEL 0x00FF0000
+#define BF_APBH_CTRL0_RESET_CHANNEL(v) \
+ (((v) << BP_APBH_CTRL0_RESET_CHANNEL) & BM_APBH_CTRL0_RESET_CHANNEL)
+HW_REGISTER(HW_APBH_CTRL1, REGS_APBH_BASE, 0x10)
+#define BP_APBH_CTRL1_CH1_CMDCMPLT_IRQ_EN 9
+#define BM_APBH_CTRL1_CH1_CMDCMPLT_IRQ_EN 0x00000200
+#define BP_APBH_CTRL1_CH0_CMDCMPLT_IRQ_EN 8
+#define BM_APBH_CTRL1_CH0_CMDCMPLT_IRQ_EN 0x00000100
+#define BP_APBH_CTRL1_CH7_CMDCMPLT_IRQ 7
+#define BM_APBH_CTRL1_CH7_CMDCMPLT_IRQ 0x00000080
+#define BP_APBH_CTRL1_CH1_CMDCMPLT_IRQ 1
+#define BM_APBH_CTRL1_CH1_CMDCMPLT_IRQ 0x00000002
+#define BP_APBH_CTRL1_CH0_CMDCMPLT_IRQ 0
+#define BM_APBH_CTRL1_CH0_CMDCMPLT_IRQ 0x00000001
+#define BP_APBH_CTRL1_CH1_ERR_IRQ 17
+#define BM_APBH_CTRL1_CH1_ERR_IRQ 0x00020000
+HW_REGISTER_0(HW_APBH_DEVSEL, REGS_APBH_BASE, 0x20)
+HW_REGISTER_RO_INDEXED(HW_APBH_CHn_CURCMDAR, REGS_APBH_BASE, 0x40, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBH_CHn_NXTCMDAR, REGS_APBH_BASE, 0x50, 0x70)
+#define BP_APBH_CHn_NXTCMDAR_CMD_ADDR 0
+#define BM_APBH_CHn_NXTCMDAR_CMD_ADDR 0xFFFFFFFF
+#define BF_APBH_CHn_NXTCMDAR_CMD_ADDR(v) ((u32) v)
+HW_REGISTER_RO_INDEXED(HW_APBH_CHn_CMD, REGS_APBH_BASE, 0x60, 0x70)
+#define BM_APBH_CHn_CMD_XFER_COUNT 0xFFFF0000
+#define BP_APBH_CHn_CMD_XFER_COUNT 16
+#define BF_APBH_CHn_CMD_XFER_COUNT(v) \
+ (((v) << BP_APBH_CHn_CMD_XFER_COUNT) & BM_APBH_CHn_CMD_XFER_COUNT)
+#define BM_APBH_CHn_CMD_CMDWORDS 0x0000F000
+#define BP_APBH_CHn_CMD_CMDWORDS 12
+#define BF_APBH_CHn_CMD_CMDWORDS(v) \
+ (((v) << BP_APBH_CHn_CMD_CMDWORDS) & BM_APBH_CHn_CMD_CMDWORDS)
+#define BM_APBH_CHn_CMD_WAIT4ENDCMD 0x00000080
+#define BM_APBH_CHn_CMD_SEMAPHORE 0x00000040
+#define BP_APBH_CHn_CMD_SEMAPHORE 6
+#define BF_APBH_CHn_CMD_SEMAPHORE(v) \
+ (((v) << BP_APBH_CHn_CMD_SEMAPHORE) & BM_APBH_CHn_CMD_SEMAPHORE)
+#define BM_APBH_CHn_CMD_NANDWAIT4READY 0x00000020
+#define BP_APBH_CHn_CMD_NANDLOCK 4
+#define BM_APBH_CHn_CMD_NANDLOCK 0x00000010
+#define BF_APBH_CHn_CMD_NANDLOCK(v) \
+ (((v) << BP_APBH_CHn_CMD_NANDLOCK) & BM_APBH_CHn_CMD_NANDLOCK)
+#define BM_APBH_CHn_CMD_IRQONCMPLT 0x00000008
+#define BM_APBH_CHn_CMD_CHAIN 0x00000004
+#define BM_APBH_CHn_CMD_DMA_READ 0x00000003
+#define BP_APBH_CHn_CMD_DMA_READ 0
+#define BF_APBH_CHn_CMD_DMA_READ(v) \
+ (((v) << BP_APBH_CHn_CMD_DMA_READ) & BM_APBH_CHn_CMD_DMA_READ)
+#define BF_APBH_CHn_CMD_COMMAND(v) \
+ (((v) << BP_APBH_CHn_CMD_DMA_READ) & BM_APBH_CHn_CMD_DMA_READ)
+#define BV_APBH_CHn_CMD_COMMAND__NO_DMA_XFER 0x0
+#define BV_APBH_CHn_CMD_COMMAND__DMA_WRITE 0x1
+#define BV_APBH_CHn_CMD_COMMAND__DMA_READ 0x2
+#define BV_APBH_CHn_CMD_COMMAND__DMA_SENSE 0x3
+HW_REGISTER_INDEXED(HW_APBH_CHn_BAR, REGS_APBH_BASE, 0x70, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBH_CHn_SEMA, REGS_APBH_BASE, 0x80, 0x70)
+#define BP_APBH_CHn_SEMA_INCREMENT_SEMA 0
+#define BM_APBH_CHn_SEMA_INCREMENT_SEMA 0x000000FF
+#define BF_APBH_CHn_SEMA_INCREMENT_SEMA(v) \
+ (((v) << BP_APBH_CHn_SEMA_INCREMENT_SEMA) & \
+ BM_APBH_CHn_SEMA_INCREMENT_SEMA)
+#define BP_APBH_CHn_SEMA_PHORE 16
+#define BM_APBH_CHn_SEMA_PHORE 0x00FF0000
+HW_REGISTER_RO_INDEXED(HW_APBH_CHn_DEBUG1, REGS_APBH_BASE, 0x90, 0x70)
+HW_REGISTER_RO_INDEXED(HW_APBH_CHn_DEBUG2, REGS_APBH_BASE, 0xA0, 0x70)
+HW_REGISTER_RO(HW_APBH_VERSION, REGS_APBH_BASE, 0x3F0)
+
+#endif /* _INCLUDE_ASM_ARCH_REGS_APBH_H */
diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-apbx.h b/arch/arm/mach-stmp37xx/include/mach/regs-apbx.h
new file mode 100644
index 000000000000..a14ddb97639a
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/include/mach/regs-apbx.h
@@ -0,0 +1,109 @@
+/*
+ * STMP APBX Register Definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ * Copyright 2008 Embedded Alley Solutions, 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; 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
+ */
+#ifndef _INCLUDE_ASM_ARCH_REGS_APBX_H
+#define _INCLUDE_ASM_ARCH_REGS_APBX_H
+
+#include <mach/stmp3xxx_regs.h>
+
+#ifndef REGS_APBX_BASE
+#define REGS_APBX_BASE (REGS_BASE + 0x00024000)
+#endif
+
+HW_REGISTER(HW_APBX_CTRL0, REGS_APBX_BASE, 0x00)
+#define BP_APBX_CTRL0_SFTRST 31
+#define BM_APBX_CTRL0_SFTRST 0x80000000
+#define BP_APBX_CTRL0_CLKGATE 30
+#define BM_APBX_CTRL0_CLKGATE 0x40000000
+#define BP_APBX_CTRL0_RESET_CHANNEL 16
+#define BM_APBX_CTRL0_RESET_CHANNEL 0x00FF0000
+#define BF_APBX_CTRL0_RESET_CHANNEL(v) \
+ (((v) << BP_APBX_CTRL0_RESET_CHANNEL) & BM_APBX_CTRL0_RESET_CHANNEL)
+HW_REGISTER(HW_APBX_CTRL1, REGS_APBX_BASE, 0x10)
+HW_REGISTER_0(HW_APBX_DEVSEL, REGS_APBX_BASE, 0x20)
+#define BP_APBX_DEVSEL_CH7 28
+#define BM_APBX_DEVSEL_CH7 0xF0000000
+#define BF_APBX_DEVSEL_CH7(v) \
+ (((v) << BP_APBX_DEVSEL_CH7) & BM_APBX_DEVSEL_CH7)
+#define BV_APBX_DEVSEL_CH7__USE_UART 0x0
+#define BV_APBX_DEVSEL_CH7__USE_IRDA 0x1
+#define BP_APBX_DEVSEL_CH6 24
+#define BM_APBX_DEVSEL_CH6 0x0F000000
+#define BF_APBX_DEVSEL_CH6(v) \
+ (((v) << BP_APBX_DEVSEL_CH6) & BM_APBX_DEVSEL_CH6)
+#define BV_APBX_DEVSEL_CH6__USE_UART 0x0
+#define BV_APBX_DEVSEL_CH6__USE_IRDA 0x1
+#define BP_APBX_CTRL1_CH7_AHB_ERROR_IRQ 23
+#define BM_APBX_CTRL1_CH7_AHB_ERROR_IRQ 0x00800000
+#define BP_APBX_CTRL1_CH6_AHB_ERROR_IRQ 22
+#define BM_APBX_CTRL1_CH6_AHB_ERROR_IRQ 0x00400000
+#define BP_APBX_CTRL1_CH7_CMDCMPLT_IRQ_EN 15
+#define BM_APBX_CTRL1_CH7_CMDCMPLT_IRQ_EN 0x00008000
+#define BP_APBX_CTRL1_CH6_CMDCMPLT_IRQ_EN 14
+#define BM_APBX_CTRL1_CH6_CMDCMPLT_IRQ_EN 0x00004000
+
+HW_REGISTER_RO_INDEXED(HW_APBX_CHn_CURCMDAR, REGS_APBX_BASE, 0x40, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBX_CHn_NXTCMDAR, REGS_APBX_BASE, 0x50, 0x70)
+#define BP_APBX_CHn_NXTCMDAR_CMD_ADDR 0
+#define BM_APBX_CHn_NXTCMDAR_CMD_ADDR 0xFFFFFFFF
+#define BF_APBX_CHn_NXTCMDAR_CMD_ADDR(v) ((u32) v)
+HW_REGISTER_RO_INDEXED(HW_APBX_CHn_CMD, REGS_APBX_BASE, 0x60, 0x70)
+#define BP_APBX_CHn_CMD_XFER_COUNT 16
+#define BM_APBX_CHn_CMD_XFER_COUNT 0xFFFF0000
+#define BF_APBX_CHn_CMD_XFER_COUNT(v) \
+ (((v) << BP_APBX_CHn_CMD_XFER_COUNT) & BM_APBX_CHn_CMD_XFER_COUNT)
+#define BP_APBX_CHn_CMD_CMDWORDS 12
+#define BM_APBX_CHn_CMD_CMDWORDS 0x0000F000
+#define BF_APBX_CHn_CMD_CMDWORDS(v) \
+ (((v) << BP_APBX_CHn_CMD_CMDWORDS) & BM_APBX_CHn_CMD_CMDWORDS)
+#define BP_APBX_CHn_CMD_WAIT4ENDCMD 7
+#define BM_APBX_CHn_CMD_WAIT4ENDCMD 0x00000080
+#define BP_APBX_CHn_CMD_SEMAPHORE 6
+#define BM_APBX_CHn_CMD_SEMAPHORE 0x00000040
+#define BP_APBX_CHn_CMD_IRQONCMPLT 3
+#define BM_APBX_CHn_CMD_IRQONCMPLT 0x00000008
+#define BP_APBX_CHn_CMD_CHAIN 2
+#define BM_APBX_CHn_CMD_CHAIN 0x00000004
+#define BM_APBX_CHn_CMD_DMA_READ 0x00000003
+#define BP_APBX_CHn_CMD_DMA_READ 0
+#define BF_APBX_CHn_CMD_DMA_READ(v) \
+ (((v) << BP_APBX_CHn_CMD_DMA_READ) & BM_APBX_CHn_CMD_DMA_READ)
+#define BP_APBX_CHn_CMD_COMMAND 0
+#define BM_APBX_CHn_CMD_COMMAND 0x00000003
+#define BF_APBX_CHn_CMD_COMMAND(v) \
+ (((v) << BP_APBX_CHn_CMD_COMMAND) & BM_APBX_CHn_CMD_COMMAND)
+#define BV_APBX_CHn_CMD_COMMAND__NO_DMA_XFER 0x0
+#define BV_APBX_CHn_CMD_COMMAND__DMA_WRITE 0x1
+#define BV_APBX_CHn_CMD_COMMAND__DMA_READ 0x2
+
+HW_REGISTER_RO_INDEXED(HW_APBX_CHn_BAR, REGS_APBX_BASE, 0x70, 0x70)
+HW_REGISTER_0_INDEXED(HW_APBX_CHn_SEMA, REGS_APBX_BASE, 0x80, 0x70)
+#define BP_APBX_CHn_SEMA_INCREMENT_SEMA 0
+#define BM_APBX_CHn_SEMA_INCREMENT_SEMA 0x000000FF
+#define BF_APBX_CHn_SEMA_INCREMENT_SEMA(v) \
+ (((v) << BP_APBX_CHn_SEMA_INCREMENT_SEMA) & \
+ BM_APBX_CHn_SEMA_INCREMENT_SEMA)
+#define BP_APBX_CHn_SEMA_PHORE 16
+#define BM_APBX_CHn_SEMA_PHORE 0x00FF0000
+HW_REGISTER_RO_INDEXED(HW_APBX_CHn_DEBUG1, REGS_APBX_BASE, 0x90, 0x70)
+HW_REGISTER_RO_INDEXED(HW_APBX_CHn_DEBUG2, REGS_APBX_BASE, 0xA0, 0x70)
+HW_REGISTER_RO(HW_APBX_VERSION, REGS_APBX_BASE, 0x3F0)
+
+#endif /* _INCLUDE_ASM_ARCH_REGS_APBX_H */
diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h b/arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h
new file mode 100644
index 000000000000..229ee75f90d9
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h
@@ -0,0 +1,85 @@
+#ifndef _INCLUDE_ASM_ARCH_REGS_CLKCTRL_H
+#define _INCLUDE_ASM_ARCH_REGS_CLKCTRL_H
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_CLKCTRL_BASE (REGS_BASE + 0x00040000)
+
+#define HW_CLKCTRL_PLLCTRL0_ADDR (REGS_CLKCTRL_BASE + 0x00)
+HW_REGISTER(HW_CLKCTRL_PLLCTRL0, REGS_CLKCTRL_BASE, 0x00)
+#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
+#define HW_CLKCTRL_PLLCTRL1_ADDR (REGS_CLKCTRL_BASE + 0x10)
+HW_REGISTER(HW_CLKCTRL_PLLCTRL1, REGS_CLKCTRL_BASE, 0x10)
+
+#define HW_CLKCTRL_CPU_ADDR (REGS_CLKCTRL_BASE + 0x20)
+HW_REGISTER(HW_CLKCTRL_CPU, REGS_CLKCTRL_BASE, 0x20)
+#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v) \
+ (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS_ADDR (REGS_CLKCTRL_BASE + 0x30)
+HW_REGISTER(HW_CLKCTRL_HBUS, REGS_CLKCTRL_BASE, 0x30)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0 /* for compatitibility */
+#define BM_CLKCTRL_HBUS_DIV 0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+#define HW_CLKCTRL_XBUS_ADDR (REGS_CLKCTRL_BASE + 0x40)
+HW_REGISTER(HW_CLKCTRL_XBUS, REGS_CLKCTRL_BASE, 0x40)
+#define HW_CLKCTRL_XTAL_ADDR (REGS_CLKCTRL_BASE + 0x50)
+HW_REGISTER(HW_CLKCTRL_XTAL, REGS_CLKCTRL_BASE, 0x50)
+#define HW_CLKCTRL_PIX_ADDR (REGS_CLKCTRL_BASE + 0x60)
+HW_REGISTER(HW_CLKCTRL_PIX, REGS_CLKCTRL_BASE, 0x60)
+#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
+#define BM_CLKCTRL_PIX_BUSY 0x20000000
+#define BM_CLKCTRL_PIX_DIV 0x00007FFF
+#define BP_CLKCTRL_PIX_DIV 0
+#define BF_CLKCTRL_PIX_DIV(v) \
+ (((v) << BP_CLKCTRL_PIX_DIV) & BM_CLKCTRL_PIX_DIV)
+#define HW_CLKCTRL_SSP_ADDR (REGS_CLKCTRL_BASE + 0x70)
+HW_REGISTER(HW_CLKCTRL_SSP, REGS_CLKCTRL_BASE, 0x70)
+#define HW_CLKCTRL_GPMI_ADDR (REGS_CLKCTRL_BASE + 0x80)
+HW_REGISTER(HW_CLKCTRL_GPMI, REGS_CLKCTRL_BASE, 0x80)
+#define HW_CLKCTRL_SPDIF_ADDR (REGS_CLKCTRL_BASE + 0x90)
+HW_REGISTER(HW_CLKCTRL_SPDIF, REGS_CLKCTRL_BASE, 0x90)
+#define HW_CLKCTRL_EMI_ADDR (REGS_CLKCTRL_BASE + 0xA0)
+HW_REGISTER(HW_CLKCTRL_EMI, REGS_CLKCTRL_BASE, 0xA0)
+#define HW_CLKCTRL_IR_ADDR (REGS_CLKCTRL_BASE + 0xB0)
+HW_REGISTER(HW_CLKCTRL_IR, REGS_CLKCTRL_BASE, 0xB0)
+#define HW_CLKCTRL_SAIF_ADDR (REGS_CLKCTRL_BASE + 0xC0)
+HW_REGISTER(HW_CLKCTRL_SAIF, REGS_CLKCTRL_BASE, 0xC0)
+#define HW_CLKCTRL_FRAC_ADDR (REGS_CLKCTRL_BASE + 0xD0)
+HW_REGISTER(HW_CLKCTRL_FRAC, REGS_CLKCTRL_BASE, 0xD0)
+#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
+#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
+#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
+#define BP_CLKCTRL_FRAC_IOFRAC 24
+#define BF_CLKCTRL_FRAC_IOFRAC(v) \
+ (((v) << BP_CLKCTRL_FRAC_IOFRAC) & BM_CLKCTRL_FRAC_IOFRAC)
+#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
+#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
+#define BP_CLKCTRL_FRAC_PIXFRAC 16
+#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
+ (((v) << BP_CLKCTRL_FRAC_PIXFRAC) & BM_CLKCTRL_FRAC_PIXFRAC)
+#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
+#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
+#define BP_CLKCTRL_FRAC_EMIFRAC 8
+#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
+ (((v) << BP_CLKCTRL_FRAC_EMIFRAC) & BM_CLKCTRL_FRAC_EMIFRAC)
+#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
+#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
+#define BP_CLKCTRL_FRAC_CPUFRAC 0
+#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
+ (((v) << BP_CLKCTRL_FRAC_CPUFRAC) & BM_CLKCTRL_FRAC_CPUFRAC)
+#define HW_CLKCTRL_CLKSEQ_ADDR (REGS_CLKCTRL_BASE + 0xE0)
+HW_REGISTER(HW_CLKCTRL_CLKSEQ, REGS_CLKCTRL_BASE, 0xE0)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
+#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
+HW_REGISTER_WO(HW_CLKCTRL_RESET, REGS_CLKCTRL_BASE, 0xF0)
+#define BM_CLKCTRL_RESET_CHIP 0x00000002
+#define BM_CLKCTRL_RESET_DIG 0x00000001
+#endif /* _INCLUDE_ASM_ARCH_REGS_CLKCTRL_H */
diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-icoll.h b/arch/arm/mach-stmp37xx/include/mach/regs-icoll.h
new file mode 100644
index 000000000000..8a92f923f6bd
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/include/mach/regs-icoll.h
@@ -0,0 +1,36 @@
+/*
+ * Freescale STMP378X: clock registers definitions
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _INCLUDE_ASM_ARCH_REGS_ICOLL_H
+#define _INCLUDE_ASM_ARCH_REGS_ICOLL_H
+
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_ICOLL_BASE (REGS_BASE + 0x00000000)
+
+HW_REGISTER(HW_ICOLL_VECTOR, REGS_ICOLL_BASE, 0x00)
+HW_REGISTER_WO(HW_ICOLL_LEVELACK, REGS_ICOLL_BASE, 0x10)
+HW_REGISTER(HW_ICOLL_CTRL, REGS_ICOLL_BASE, 0x20)
+#define BM_ICOLL_CTRL_CLKGATE 0x40000000
+#define BM_ICOLL_CTRL_SFTRST 0x80000000
+HW_REGISTER_RO(HW_ICOLL_STAT, REGS_ICOLL_BASE, 0x30)
+
+HW_REGISTER_INDEXED(HW_ICOLL_PRIORITYn, REGS_ICOLL_BASE, 0x60, 0x10)
+
+#endif /* _INCLUDE_ASM_ARCH_REGS_CLKCTRL_H */
diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h b/arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h
new file mode 100644
index 000000000000..b114ecd9a5eb
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h
@@ -0,0 +1,159 @@
+/*
+ * STMP pinmux register definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ *
+ * 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
+ */
+#ifndef _INCLUDE_ASM_ARCH_REGS_PINCTRL_H
+#define _INCLUDE_ASM_ARCH_REGS_PINCTRL_H
+
+#include <mach/stmp3xxx_regs.h>
+
+#ifndef REGS_PINCTRL_BASE
+#define REGS_PINCTRL_BASE (REGS_BASE + 0x00018000)
+#endif /* REGS_PINCTRL_BASE */
+
+HW_REGISTER(HW_PINCTRL_CTRL, REGS_PINCTRL_BASE, 0)
+
+#define HW_PINCTRL_MUXSEL0_ADDR (REGS_PINCTRL_BASE + 0x100)
+HW_REGISTER(HW_PINCTRL_MUXSEL0, REGS_PINCTRL_BASE, 0x100)
+#define HW_PINCTRL_MUXSEL1_ADDR (REGS_PINCTRL_BASE + 0x110)
+HW_REGISTER(HW_PINCTRL_MUXSEL1, REGS_PINCTRL_BASE, 0x110)
+#define HW_PINCTRL_MUXSEL2_ADDR (REGS_PINCTRL_BASE + 0x120)
+HW_REGISTER(HW_PINCTRL_MUXSEL2, REGS_PINCTRL_BASE, 0x120)
+#define HW_PINCTRL_MUXSEL3_ADDR (REGS_PINCTRL_BASE + 0x130)
+HW_REGISTER(HW_PINCTRL_MUXSEL3, REGS_PINCTRL_BASE, 0x130)
+#define BM_PINCTRL_MUXSEL3_BANK1_PIN28 0x03000000
+#define HW_PINCTRL_MUXSEL4_ADDR (REGS_PINCTRL_BASE + 0x140)
+HW_REGISTER(HW_PINCTRL_MUXSEL4, REGS_PINCTRL_BASE, 0x140)
+#define BM_PINCTRL_MUXSEL4_BANK2_PIN03 0x000000C0
+#define BM_PINCTRL_MUXSEL4_BANK2_PIN04 0x00000300
+#define HW_PINCTRL_MUXSEL5_ADDR (REGS_PINCTRL_BASE + 0x150)
+HW_REGISTER(HW_PINCTRL_MUXSEL5, REGS_PINCTRL_BASE, 0x150)
+#define HW_PINCTRL_MUXSEL6_ADDR (REGS_PINCTRL_BASE + 0x160)
+HW_REGISTER(HW_PINCTRL_MUXSEL6, REGS_PINCTRL_BASE, 0x160)
+#define HW_PINCTRL_MUXSEL7_ADDR (REGS_PINCTRL_BASE + 0x170)
+HW_REGISTER(HW_PINCTRL_MUXSEL7, REGS_PINCTRL_BASE, 0x170)
+
+HW_REGISTER(HW_PINCTRL_DRIVE0, REGS_PINCTRL_BASE, 0x200)
+#define HW_PINCTRL_DRIVE0_ADDR (REGS_PINCTRL_BASE + 0x200)
+HW_REGISTER(HW_PINCTRL_DRIVE1, REGS_PINCTRL_BASE, 0x210)
+#define HW_PINCTRL_DRIVE1_ADDR (REGS_PINCTRL_BASE + 0x210)
+HW_REGISTER(HW_PINCTRL_DRIVE2, REGS_PINCTRL_BASE, 0x220)
+#define HW_PINCTRL_DRIVE2_ADDR (REGS_PINCTRL_BASE + 0x220)
+HW_REGISTER(HW_PINCTRL_DRIVE3, REGS_PINCTRL_BASE, 0x230)
+#define HW_PINCTRL_DRIVE3_ADDR (REGS_PINCTRL_BASE + 0x230)
+HW_REGISTER(HW_PINCTRL_DRIVE4, REGS_PINCTRL_BASE, 0x240)
+#define HW_PINCTRL_DRIVE4_ADDR (REGS_PINCTRL_BASE + 0x240)
+HW_REGISTER(HW_PINCTRL_DRIVE5, REGS_PINCTRL_BASE, 0x250)
+#define HW_PINCTRL_DRIVE5_ADDR (REGS_PINCTRL_BASE + 0x250)
+HW_REGISTER(HW_PINCTRL_DRIVE6, REGS_PINCTRL_BASE, 0x260)
+#define HW_PINCTRL_DRIVE6_ADDR (REGS_PINCTRL_BASE + 0x260)
+HW_REGISTER(HW_PINCTRL_DRIVE7, REGS_PINCTRL_BASE, 0x270)
+#define HW_PINCTRL_DRIVE7_ADDR (REGS_PINCTRL_BASE + 0x270)
+HW_REGISTER(HW_PINCTRL_DRIVE8, REGS_PINCTRL_BASE, 0x280)
+#define HW_PINCTRL_DRIVE8_ADDR (REGS_PINCTRL_BASE + 0x280)
+HW_REGISTER(HW_PINCTRL_DRIVE9, REGS_PINCTRL_BASE, 0x290)
+#define HW_PINCTRL_DRIVE9_ADDR (REGS_PINCTRL_BASE + 0x290)
+HW_REGISTER(HW_PINCTRL_DRIVE10, REGS_PINCTRL_BASE, 0x2a0)
+#define HW_PINCTRL_DRIVE10_ADDR (REGS_PINCTRL_BASE + 0x2a0)
+HW_REGISTER(HW_PINCTRL_DRIVE11, REGS_PINCTRL_BASE, 0x2b0)
+#define HW_PINCTRL_DRIVE11_ADDR (REGS_PINCTRL_BASE + 0x2b0)
+HW_REGISTER(HW_PINCTRL_DRIVE12, REGS_PINCTRL_BASE, 0x2c0)
+#define HW_PINCTRL_DRIVE12_ADDR (REGS_PINCTRL_BASE + 0x2c0)
+HW_REGISTER(HW_PINCTRL_DRIVE13, REGS_PINCTRL_BASE, 0x2d0)
+#define HW_PINCTRL_DRIVE13_ADDR (REGS_PINCTRL_BASE + 0x2d0)
+HW_REGISTER(HW_PINCTRL_DRIVE14, REGS_PINCTRL_BASE, 0x2e0)
+#define HW_PINCTRL_DRIVE14_ADDR (REGS_PINCTRL_BASE + 0x2e0)
+
+
+HW_REGISTER(HW_PINCTRL_PULL0, REGS_PINCTRL_BASE, 0x300)
+#define HW_PINCTRL_PULL0_ADDR (REGS_PINCTRL_BASE + 0x300)
+#define BM_PINCTRL_PULL0_BANK0_PIN01 0x00000002
+#define BM_PINCTRL_PULL0_BANK0_PIN02 0x00000004
+#define BM_PINCTRL_PULL0_BANK0_PIN03 0x00000008
+#define BM_PINCTRL_PULL0_BANK0_PIN04 0x00000010
+#define BM_PINCTRL_PULL0_BANK0_PIN20 0x00100000
+HW_REGISTER(HW_PINCTRL_PULL1, REGS_PINCTRL_BASE, 0x310)
+#define HW_PINCTRL_PULL1_ADDR (REGS_PINCTRL_BASE + 0x310)
+#define BM_PINCTRL_PULL1_BANK1_PIN22 0x00400000
+#define BM_PINCTRL_PULL1_BANK1_PIN24 0x01000000
+#define BM_PINCTRL_PULL1_BANK1_PIN25 0x02000000
+#define BM_PINCTRL_PULL1_BANK1_PIN26 0x04000000
+#define BM_PINCTRL_PULL1_BANK1_PIN27 0x08000000
+HW_REGISTER(HW_PINCTRL_PULL2, REGS_PINCTRL_BASE, 0x320)
+#define HW_PINCTRL_PULL2_ADDR (REGS_PINCTRL_BASE + 0x320)
+HW_REGISTER(HW_PINCTRL_PULL3, REGS_PINCTRL_BASE, 0x330)
+#define HW_PINCTRL_PULL3_ADDR (REGS_PINCTRL_BASE + 0x330)
+
+#define HW_PINCTRL_DOUT0_ADDR (REGS_PINCTRL_BASE + 0x400)
+HW_REGISTER(HW_PINCTRL_DOUT0, REGS_PINCTRL_BASE, 0x400)
+#define HW_PINCTRL_DOUT1_ADDR (REGS_PINCTRL_BASE + 0x410)
+HW_REGISTER(HW_PINCTRL_DOUT1, REGS_PINCTRL_BASE, 0x410)
+#define HW_PINCTRL_DOUT2_ADDR (REGS_PINCTRL_BASE + 0x420)
+HW_REGISTER(HW_PINCTRL_DOUT2, REGS_PINCTRL_BASE, 0x420)
+
+#define HW_PINCTRL_DIN0_ADDR (REGS_PINCTRL_BASE + 0x500)
+HW_REGISTER_RO(HW_PINCTRL_DIN0, REGS_PINCTRL_BASE, 0x500)
+#define HW_PINCTRL_DIN1_ADDR (REGS_PINCTRL_BASE + 0x510)
+HW_REGISTER_RO(HW_PINCTRL_DIN1, REGS_PINCTRL_BASE, 0x510)
+#define HW_PINCTRL_DIN2_ADDR (REGS_PINCTRL_BASE + 0x520)
+HW_REGISTER_RO(HW_PINCTRL_DIN2, REGS_PINCTRL_BASE, 0x520)
+
+#define HW_PINCTRL_DOE0_ADDR (REGS_PINCTRL_BASE + 0x600)
+HW_REGISTER(HW_PINCTRL_DOE0, REGS_PINCTRL_BASE, 0x600)
+#define HW_PINCTRL_DOE1_ADDR (REGS_PINCTRL_BASE + 0x610)
+HW_REGISTER(HW_PINCTRL_DOE1, REGS_PINCTRL_BASE, 0x610)
+#define HW_PINCTRL_DOE2_ADDR (REGS_PINCTRL_BASE + 0x620)
+HW_REGISTER(HW_PINCTRL_DOE2, REGS_PINCTRL_BASE, 0x620)
+
+HW_REGISTER(HW_PINCTRL_PIN2IRQ0, REGS_PINCTRL_BASE, 0x700)
+#define HW_PINCTRL_PIN2IRQ0_ADDR (REGS_PINCTRL_BASE + 0x700)
+HW_REGISTER(HW_PINCTRL_PIN2IRQ1, REGS_PINCTRL_BASE, 0x710)
+#define HW_PINCTRL_PIN2IRQ1_ADDR (REGS_PINCTRL_BASE + 0x710)
+HW_REGISTER(HW_PINCTRL_PIN2IRQ2, REGS_PINCTRL_BASE, 0x720)
+#define HW_PINCTRL_PIN2IRQ2_ADDR (REGS_PINCTRL_BASE + 0x720)
+
+HW_REGISTER(HW_PINCTRL_IRQEN0, REGS_PINCTRL_BASE, 0x800)
+#define HW_PINCTRL_IRQEN0_ADDR (REGS_PINCTRL_BASE + 0x800)
+HW_REGISTER(HW_PINCTRL_IRQEN1, REGS_PINCTRL_BASE, 0x810)
+#define HW_PINCTRL_IRQEN1_ADDR (REGS_PINCTRL_BASE + 0x810)
+HW_REGISTER(HW_PINCTRL_IRQEN2, REGS_PINCTRL_BASE, 0x820)
+#define HW_PINCTRL_IRQEN2_ADDR (REGS_PINCTRL_BASE + 0x820)
+
+HW_REGISTER(HW_PINCTRL_IRQLEVEL0, REGS_PINCTRL_BASE, 0x900)
+#define HW_PINCTRL_IRQLEVEL0_ADDR (REGS_PINCTRL_BASE + 0x900)
+HW_REGISTER(HW_PINCTRL_IRQLEVEL1, REGS_PINCTRL_BASE, 0x910)
+#define HW_PINCTRL_IRQLEVEL1_ADDR (REGS_PINCTRL_BASE + 0x910)
+HW_REGISTER(HW_PINCTRL_IRQLEVEL2, REGS_PINCTRL_BASE, 0x920)
+#define HW_PINCTRL_IRQLEVEL2_ADDR (REGS_PINCTRL_BASE + 0x920)
+
+HW_REGISTER(HW_PINCTRL_IRQPOL0, REGS_PINCTRL_BASE, 0xA00)
+#define HW_PINCTRL_IRQPOL0_ADDR (REGS_PINCTRL_BASE + 0xa00)
+HW_REGISTER(HW_PINCTRL_IRQPOL1, REGS_PINCTRL_BASE, 0xA10)
+#define HW_PINCTRL_IRQPOL1_ADDR (REGS_PINCTRL_BASE + 0xa10)
+HW_REGISTER(HW_PINCTRL_IRQPOL2, REGS_PINCTRL_BASE, 0xA20)
+#define HW_PINCTRL_IRQPOL2_ADDR (REGS_PINCTRL_BASE + 0xa20)
+
+HW_REGISTER(HW_PINCTRL_IRQSTAT0, REGS_PINCTRL_BASE, 0xB00)
+#define HW_PINCTRL_IRQSTAT0_ADDR (REGS_PINCTRL_BASE + 0xb00)
+HW_REGISTER(HW_PINCTRL_IRQSTAT1, REGS_PINCTRL_BASE, 0xB10)
+#define HW_PINCTRL_IRQSTAT1_ADDR (REGS_PINCTRL_BASE + 0xb10)
+HW_REGISTER(HW_PINCTRL_IRQSTAT2, REGS_PINCTRL_BASE, 0xB20)
+#define HW_PINCTRL_IRQSTAT2_ADDR (REGS_PINCTRL_BASE + 0xb20)
+
+#endif /* _INCLUDE_ASM_ARCH_REGS_PINCTRL_H */
+
diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-power.h b/arch/arm/mach-stmp37xx/include/mach/regs-power.h
new file mode 100644
index 000000000000..d15cd6601e7f
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/include/mach/regs-power.h
@@ -0,0 +1,31 @@
+/*
+ * STMP POWER Register Definitions
+ *
+ * Copyright (c) 2008 Freescale Semiconductor
+ *
+ * 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
+ */
+
+#ifndef __ARCH_ARM___POWER_H
+#define __ARCH_ARM___POWER_H 1
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_POWER_BASE (void __iomem *)(REGS_BASE + 0x44000)
+#define REGS_POWER_BASE_PHYS (0x80044000)
+#define REGS_POWER_SIZE 0x00002000
+HW_REGISTER(HW_POWER_MINPWR, REGS_POWER_BASE, 0x00000020)
+HW_REGISTER(HW_POWER_CHARGE, REGS_POWER_BASE, 0x00000030)
+#endif /* __ARCH_ARM___POWER_H */
diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-timrot.h b/arch/arm/mach-stmp37xx/include/mach/regs-timrot.h
new file mode 100644
index 000000000000..7f000306e890
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/include/mach/regs-timrot.h
@@ -0,0 +1,52 @@
+/*
+ * include/asm-arm/arch-stmp3xxx/regstimer.h
+ *
+ * Copyright (c) 2008 SigmaTel Inc
+ * Copyright (c) 2008 Embedded Alley Solutions, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ARCH_ARM_REGS_TIMROT_H
+#define __ARCH_ARM_REGS_TIMROT_H
+
+#include <mach/stmp3xxx_regs.h>
+
+#define REGS_TIMROT_BASE (REGS_BASE + 0x00068000)
+
+HW_REGISTER(HW_TIMROT_ROTCTRL, REGS_TIMROT_BASE, 0)
+#define BM_TIMROT_ROTCTRL_SFTRST 0x80000000
+#define BM_TIMROT_ROTCTRL_CLKGATE 0x40000000
+
+HW_REGISTER_INDEXED(HW_TIMROT_TIMCTRLn, REGS_TIMROT_BASE, 0x20, 0x20)
+#define BM_TIMROT_TIMCTRLn_SELECT 0x0000000F
+#define BF_TIMROT_TIMCTRLn_SELECT(v) (((v) << 0) & BM_TIMROT_TIMCTRLn_SELECT)
+#define BM_TIMROT_TIMCTRLn_PRESCALE 0x00000030
+#define BF_TIMROT_TIMCTRLn_PRESCALE(v) \
+ (((v) << 4) & BM_TIMROT_TIMCTRLn_PRESCALE)
+#define BM_TIMROT_TIMCTRLn_RELOAD 0x00000040
+#define BF_TIMROT_TIMCTRLn_RELOAD(v) (((v) << 6) & BM_TIMROT_TIMCTRLn_RELOAD)
+#define BM_TIMROT_TIMCTRLn_UPDATE 0x00000080
+#define BF_TIMROT_TIMCTRLn_UPDATE(v) (((v) << 7) & BM_TIMROT_TIMCTRLn_UPDATE)
+#define BM_TIMROT_TIMCTRLn_POLARITY 0x00000100
+#define BF_TIMROT_TIMCTRLn_POLARITY(v) \
+ (((v) << 8) & BM_TIMROT_TIMCTRLn_POLARITY)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN 0x00004000
+#define BF_TIMROT_TIMCTRLn_IRQ_EN(v) \
+ (((v) << 14) & BM_TIMROT_TIMCTRLn_IRQ_EN)
+#define BM_TIMROT_TIMCTRLn_IRQ 0x00008000
+#define BF_TIMROT_TIMCTRLn_IRQ(v) (((v) << 15) & BM_TIMROT_TIMCTRLn_IRQ)
+HW_REGISTER_0_INDEXED(HW_TIMROT_TIMCOUNTn, REGS_TIMROT_BASE, 0x30, 0x20)
+
+#endif /* __ARCH_ARM_REGSTIMER_H */
diff --git a/arch/arm/mach-stmp37xx/stmp37xx.c b/arch/arm/mach-stmp37xx/stmp37xx.c
new file mode 100644
index 000000000000..83a41c90c252
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/stmp37xx.c
@@ -0,0 +1,217 @@
+/*
+ * Freescale STMP37XX platform support
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/stmp3xxx.h>
+#include <mach/dma.h>
+
+#include <mach/regs-icoll.h>
+#include <mach/regs-apbh.h>
+#include <mach/regs-apbx.h>
+#include "stmp37xx.h"
+
+/*
+ * IRQ handling
+ */
+static void stmp37xx_ack_irq(unsigned int irq)
+{
+ /* Disable IRQ */
+ HW_ICOLL_PRIORITYn_CLR(irq / 4, 0x04 << ((irq % 4) * 8));
+
+ /* ACK current interrupt */
+ HW_ICOLL_LEVELACK_WR(1);
+
+ /* Barrier */
+ (void) HW_ICOLL_STAT_RD();
+}
+
+static void stmp37xx_mask_irq(unsigned int irq)
+{
+ /* IRQ disable */
+ HW_ICOLL_PRIORITYn_CLR(irq / 4, 0x04 << ((irq % 4) * 8));
+}
+
+static void stmp37xx_unmask_irq(unsigned int irq)
+{
+ /* IRQ enable */
+ HW_ICOLL_PRIORITYn_SET(irq / 4, 0x04 << ((irq % 4) * 8));
+}
+
+static struct irq_chip stmp37xx_chip = {
+ .ack = stmp37xx_ack_irq,
+ .mask = stmp37xx_mask_irq,
+ .unmask = stmp37xx_unmask_irq,
+};
+
+void __init stmp37xx_init_irq(void)
+{
+ stmp3xxx_init_irq(&stmp37xx_chip);
+}
+
+/*
+ * DMA interrupt handling
+ */
+void stmp3xxx_arch_dma_enable_interrupt(int channel)
+{
+ int dmabus = channel / 16;
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ HW_APBH_CTRL1_SET(1 << (8 + (channel % 16)));
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ HW_APBX_CTRL1_SET(1 << (8 + (channel % 16)));
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt);
+
+void stmp3xxx_arch_dma_clear_interrupt(int channel)
+{
+ int dmabus = channel / 16;
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ HW_APBH_CTRL1_CLR(1 << (channel % 16));
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ HW_APBX_CTRL1_CLR(1 << (channel % 16));
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt);
+
+int stmp3xxx_arch_dma_is_interrupt(int channel)
+{
+ int r = 0;
+
+ int dmabus = channel / 16;
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ r = HW_APBH_CTRL1_RD() & (1 << (channel % 16));
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ r = HW_APBX_CTRL1_RD() & (1 << (channel % 16));
+ break;
+ }
+ return r;
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt);
+
+void stmp3xxx_arch_dma_reset_channel(int channel)
+{
+ int dmabus = channel / 16;
+ unsigned chbit = 1 << (channel % 16);
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ /* Reset channel and wait for it to complete */
+ HW_APBH_CTRL0_SET(chbit << BP_APBH_CTRL0_RESET_CHANNEL);
+ while (HW_APBH_CTRL0_RD() &
+ (chbit << BP_APBH_CTRL0_RESET_CHANNEL))
+ continue;
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ /* Reset channel and wait for it to complete */
+ HW_APBX_CTRL0_SET(chbit << BP_APBX_CTRL0_RESET_CHANNEL);
+ while (HW_APBX_CTRL0_RD() &
+ (chbit << BP_APBX_CTRL0_RESET_CHANNEL))
+ continue;
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel);
+
+void stmp3xxx_arch_dma_freeze(int channel)
+{
+ int dmabus = channel / 16;
+ unsigned chbit = 1 << (channel % 16);
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ HW_APBH_CTRL0_SET(1<<chbit);
+ break;
+ case STMP3XXX_BUS_APBX:
+ HW_APBX_CTRL0_SET(1<<chbit);
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_freeze);
+
+void stmp3xxx_arch_dma_unfreeze(int channel)
+{
+ int dmabus = channel / 16;
+ unsigned chbit = 1 << (channel % 16);
+
+ switch (dmabus) {
+ case STMP3XXX_BUS_APBH:
+ HW_APBH_CTRL0_CLR(1<<chbit);
+ break;
+ case STMP3XXX_BUS_APBX:
+ HW_APBX_CTRL0_CLR(1<<chbit);
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_arch_dma_unfreeze);
+
+/*
+ * The registers are all very closely mapped, so we might as well map them all
+ * with a single mapping
+ *
+ * Logical Physical
+ * f0000000 80000000 On-chip registers
+ * f1000000 00000000 256k on-chip SRAM
+ */
+static struct map_desc stmp37xx_io_desc[] __initdata = {
+ {
+ .virtual = (u32)STMP3XXX_REGS_BASE,
+ .pfn = __phys_to_pfn(STMP3XXX_REGS_PHBASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = (u32)STMP3XXX_OCRAM_BASE,
+ .pfn = __phys_to_pfn(STMP3XXX_OCRAM_PHBASE),
+ .length = STMP3XXX_OCRAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init stmp37xx_map_io(void)
+{
+ iotable_init(stmp37xx_io_desc, ARRAY_SIZE(stmp37xx_io_desc));
+}
diff --git a/arch/arm/mach-stmp37xx/stmp37xx.h b/arch/arm/mach-stmp37xx/stmp37xx.h
new file mode 100644
index 000000000000..0b75fb796a64
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/stmp37xx.h
@@ -0,0 +1,24 @@
+/*
+ * Freescale STMP37XX/STMP378X internal functions and data declarations
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __MACH_STMP37XX_H
+#define __MACH_STMP37XX_H
+
+void stmp37xx_map_io(void);
+void stmp37xx_init_irq(void);
+
+#endif /* __MACH_STMP37XX_H */
diff --git a/arch/arm/mach-stmp37xx/stmp37xx_devb.c b/arch/arm/mach-stmp37xx/stmp37xx_devb.c
new file mode 100644
index 000000000000..adfbdc7f8e27
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/stmp37xx_devb.c
@@ -0,0 +1,83 @@
+/*
+ * Freescale STMP37XX development board support
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/stmp3xxx.h>
+#include <mach/pins.h>
+#include <mach/pinmux.h>
+#include "stmp37xx.h"
+
+/*
+ * List of STMP37xx development board specific devices
+ */
+static struct platform_device *stmp37xx_devb_devices[] = {
+ &stmp3xxx_dbguart,
+};
+
+static struct pin_desc dbguart_pins_0[] = {
+ { PINID_PWM0, PIN_FUN3, },
+ { PINID_PWM1, PIN_FUN3, },
+};
+
+static struct pin_group dbguart_pins[] = {
+ [0] = {
+ .pins = dbguart_pins_0,
+ .nr_pins = ARRAY_SIZE(dbguart_pins_0),
+ },
+};
+
+static int dbguart_pins_control(int id, int request)
+{
+ int r = 0;
+
+ if (request)
+ r = stmp3xxx_request_pin_group(&dbguart_pins[id], "debug uart");
+ else
+ stmp3xxx_release_pin_group(&dbguart_pins[id], "debug uart");
+ return r;
+}
+
+
+static void __init stmp37xx_devb_init(void)
+{
+ stmp3xxx_pinmux_init(NR_REAL_IRQS);
+
+ /* Init STMP3xxx platform */
+ stmp3xxx_init();
+
+ stmp3xxx_dbguart.dev.platform_data = dbguart_pins_control;
+ /* Add STMP37xx development board devices */
+ platform_add_devices(stmp37xx_devb_devices,
+ ARRAY_SIZE(stmp37xx_devb_devices));
+}
+
+MACHINE_START(STMP37XX, "STMP37XX")
+ .phys_io = 0x80000000,
+ .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
+ .boot_params = 0x40000100,
+ .map_io = stmp37xx_map_io,
+ .init_irq = stmp37xx_init_irq,
+ .timer = &stmp3xxx_timer,
+ .init_machine = stmp37xx_devb_init,
+MACHINE_END
diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig
new file mode 100644
index 000000000000..337b9aabce49
--- /dev/null
+++ b/arch/arm/mach-u300/Kconfig
@@ -0,0 +1,105 @@
+if ARCH_U300
+
+menu "ST-Ericsson AB U300/U330/U335/U365 Platform"
+
+comment "ST-Ericsson Mobile Platform Products"
+
+config MACH_U300
+ bool "U300"
+
+comment "ST-Ericsson U300/U330/U335/U365 Feature Selections"
+
+choice
+ prompt "U300/U330/U335/U365 system type"
+ default MACH_U300_BS2X
+ ---help---
+ You need to select the target system, i.e. the
+ U300/U330/U335/U365 board that you want to compile your kernel
+ for.
+
+config MACH_U300_BS2X
+ bool "S26/S26/B25/B26 Test Products"
+ depends on MACH_U300
+ help
+ Select this if you're developing on the
+ S26/S25 test products. (Also works on
+ B26/B25 big boards.)
+
+config MACH_U300_BS330
+ bool "S330/B330 Test Products"
+ depends on MACH_U300
+ help
+ Select this if you're developing on the
+ S330/B330 test products.
+
+config MACH_U300_BS335
+ bool "S335/B335 Test Products"
+ depends on MACH_U300
+ help
+ Select this if you're developing on the
+ S335/B335 test products.
+
+config MACH_U300_BS365
+ bool "S365/B365 Test Products"
+ depends on MACH_U300
+ help
+ Select this if you're developing on the
+ S365/B365 test products.
+
+endchoice
+
+choice
+ prompt "Memory configuration"
+ default MACH_U300_SINGLE_RAM
+ ---help---
+ You have to config the kernel according to the physical memory
+ configuration.
+
+config MACH_U300_SINGLE_RAM
+ bool "Single RAM"
+ help
+ Select this if you want support for Single RAM phones.
+
+config MACH_U300_DUAL_RAM
+ bool "Dual RAM"
+ help
+ Select this if you want support for Dual RAM phones.
+ This is two RAM memorys on different EMIFs.
+endchoice
+
+config U300_DEBUG
+ bool "Debug support for U300"
+ depends on PM
+ help
+ Debug support for U300 in sysfs, procfs etc.
+
+config MACH_U300_SEMI_IS_SHARED
+ bool "The SEMI is used by both the access and application side"
+ depends on MACH_U300
+ help
+ This makes it possible to use the SEMI (Shared External
+ Memory Interface) from both from access and application
+ side.
+
+comment "All the settings below must match the bootloader's settings"
+
+config MACH_U300_ACCESS_MEM_SIZE
+ int "Access CPU memory allocation"
+ range 7 25
+ depends on MACH_U300_SINGLE_RAM
+ default 13
+ help
+ How much memory in MiB that the Access side CPU has allocated
+
+config MACH_U300_2MB_ALIGNMENT_FIX
+ bool "2MiB alignment fix"
+ depends on MACH_U300_SINGLE_RAM
+ default y
+ help
+ If yes and the Access side CPU has allocated an odd size in
+ MiB, this fix gives you one MiB extra that would otherwise be
+ lost due to Linux 2 MiB alignment policy.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile
new file mode 100644
index 000000000000..24950e0df4b4
--- /dev/null
+++ b/arch/arm/mach-u300/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the linux kernel, U300 machine.
+#
+
+obj-y := core.o clock.o timer.o gpio.o padmux.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_ARCH_U300) += u300.o
+obj-$(CONFIG_MMC) += mmc.o
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c
new file mode 100644
index 000000000000..d6f8232757ff
--- /dev/null
+++ b/arch/arm/mach-u300/clock.c
@@ -0,0 +1,1487 @@
+/*
+ *
+ * arch/arm/mach-u300/clock.c
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Define clocks in the app platform.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <mach/hardware.h>
+#include <mach/syscon.h>
+
+#include "clock.h"
+
+/*
+ * TODO:
+ * - move all handling of the CCR register into this file and create
+ * a spinlock for the CCR register
+ * - switch to the clkdevice lookup mechanism that maps clocks to
+ * device ID:s instead when it becomes available in kernel 2.6.29.
+ * - implement rate get/set for all clocks that need it.
+ */
+
+/*
+ * Syscon clock I/O registers lock so clock requests don't collide
+ * NOTE: this is a local lock only used to lock access to clock and
+ * reset registers in syscon.
+ */
+static DEFINE_SPINLOCK(syscon_clkreg_lock);
+static DEFINE_SPINLOCK(syscon_resetreg_lock);
+
+/*
+ * The clocking hierarchy currently looks like this.
+ * NOTE: the idea is NOT to show how the clocks are routed on the chip!
+ * The ideas is to show dependencies, so a clock higher up in the
+ * hierarchy has to be on in order for another clock to be on. Now,
+ * both CPU and DMA can actually be on top of the hierarchy, and that
+ * is not modeled currently. Instead we have the backbone AMBA bus on
+ * top. This bus cannot be programmed in any way but conceptually it
+ * needs to be active for the bridges and devices to transport data.
+ *
+ * Please be aware that a few clocks are hw controlled, which mean that
+ * the hw itself can turn on/off or change the rate of the clock when
+ * needed!
+ *
+ * AMBA bus
+ * |
+ * +- CPU
+ * +- NANDIF NAND Flash interface
+ * +- SEMI Shared Memory interface
+ * +- ISP Image Signal Processor (U335 only)
+ * +- CDS (U335 only)
+ * +- DMA Direct Memory Access Controller
+ * +- AAIF APP/ACC Inteface (Mobile Scalable Link, MSL)
+ * +- APEX
+ * +- VIDEO_ENC AVE2/3 Video Encoder
+ * +- XGAM Graphics Accelerator Controller
+ * +- AHB
+ * |
+ * +- ahb:0 AHB Bridge
+ * | |
+ * | +- ahb:1 INTCON Interrupt controller
+ * | +- ahb:3 MSPRO Memory Stick Pro controller
+ * | +- ahb:4 EMIF External Memory interface
+ * |
+ * +- fast:0 FAST bridge
+ * | |
+ * | +- fast:1 MMCSD MMC/SD card reader controller
+ * | +- fast:2 I2S0 PCM I2S channel 0 controller
+ * | +- fast:3 I2S1 PCM I2S channel 1 controller
+ * | +- fast:4 I2C0 I2C channel 0 controller
+ * | +- fast:5 I2C1 I2C channel 1 controller
+ * | +- fast:6 SPI SPI controller
+ * | +- fast:7 UART1 Secondary UART (U335 only)
+ * |
+ * +- slow:0 SLOW bridge
+ * |
+ * +- slow:1 SYSCON (not possible to control)
+ * +- slow:2 WDOG Watchdog
+ * +- slow:3 UART0 primary UART
+ * +- slow:4 TIMER_APP Application timer - used in Linux
+ * +- slow:5 KEYPAD controller
+ * +- slow:6 GPIO controller
+ * +- slow:7 RTC controller
+ * +- slow:8 BT Bus Tracer (not used currently)
+ * +- slow:9 EH Event Handler (not used currently)
+ * +- slow:a TIMER_ACC Access style timer (not used currently)
+ * +- slow:b PPM (U335 only, what is that?)
+ */
+
+/*
+ * Reset control functions. We remember if a block has been
+ * taken out of reset and don't remove the reset assertion again
+ * and vice versa. Currently we only remove resets so the
+ * enablement function is defined out.
+ */
+static void syscon_block_reset_enable(struct clk *clk)
+{
+ u16 val;
+ unsigned long iflags;
+
+ /* Not all blocks support resetting */
+ if (!clk->res_reg || !clk->res_mask)
+ return;
+ spin_lock_irqsave(&syscon_resetreg_lock, iflags);
+ val = readw(clk->res_reg);
+ val |= clk->res_mask;
+ writew(val, clk->res_reg);
+ spin_unlock_irqrestore(&syscon_resetreg_lock, iflags);
+ clk->reset = true;
+}
+
+static void syscon_block_reset_disable(struct clk *clk)
+{
+ u16 val;
+ unsigned long iflags;
+
+ /* Not all blocks support resetting */
+ if (!clk->res_reg || !clk->res_mask)
+ return;
+ spin_lock_irqsave(&syscon_resetreg_lock, iflags);
+ val = readw(clk->res_reg);
+ val &= ~clk->res_mask;
+ writew(val, clk->res_reg);
+ spin_unlock_irqrestore(&syscon_resetreg_lock, iflags);
+ clk->reset = false;
+}
+
+int __clk_get(struct clk *clk)
+{
+ u16 val;
+
+ /* The MMC and MSPRO clocks need some special set-up */
+ if (!strcmp(clk->name, "MCLK")) {
+ /* Set default MMC clock divisor to 18.9 MHz */
+ writew(0x0054U, U300_SYSCON_VBASE + U300_SYSCON_MMF0R);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMCR);
+ /* Disable the MMC feedback clock */
+ val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE;
+ /* Disable MSPRO frequency */
+ val &= ~U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_MMCR);
+ }
+ if (!strcmp(clk->name, "MSPRO")) {
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMCR);
+ /* Disable the MMC feedback clock */
+ val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE;
+ /* Enable MSPRO frequency */
+ val |= U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_MMCR);
+ }
+ return 1;
+}
+EXPORT_SYMBOL(__clk_get);
+
+void __clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(__clk_put);
+
+static void syscon_clk_disable(struct clk *clk)
+{
+ unsigned long iflags;
+
+ /* Don't touch the hardware controlled clocks */
+ if (clk->hw_ctrld)
+ return;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ writew(clk->clk_val, U300_SYSCON_VBASE + U300_SYSCON_SBCDR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+static void syscon_clk_enable(struct clk *clk)
+{
+ unsigned long iflags;
+
+ /* Don't touch the hardware controlled clocks */
+ if (clk->hw_ctrld)
+ return;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ writew(clk->clk_val, U300_SYSCON_VBASE + U300_SYSCON_SBCER);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+static u16 syscon_clk_get_rate(void)
+{
+ u16 val;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+ return val;
+}
+
+#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
+static void enable_i2s0_vcxo(void)
+{
+ u16 val;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ /* Set I2S0 to use the VCXO 26 MHz clock */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val |= U300_SYSCON_CCR_TURN_VCXO_ON;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val |= U300_SYSCON_CCR_I2S0_USE_VCXO;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ val |= U300_SYSCON_CEFR_I2S0_CLK_EN;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+static void enable_i2s1_vcxo(void)
+{
+ u16 val;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ /* Set I2S1 to use the VCXO 26 MHz clock */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val |= U300_SYSCON_CCR_TURN_VCXO_ON;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val |= U300_SYSCON_CCR_I2S1_USE_VCXO;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ val |= U300_SYSCON_CEFR_I2S1_CLK_EN;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+static void disable_i2s0_vcxo(void)
+{
+ u16 val;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ /* Disable I2S0 use of the VCXO 26 MHz clock */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= ~U300_SYSCON_CCR_I2S0_USE_VCXO;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ /* Deactivate VCXO if noone else is using VCXO */
+ if (!(val & U300_SYSCON_CCR_I2S1_USE_VCXO))
+ val &= ~U300_SYSCON_CCR_TURN_VCXO_ON;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ val &= ~U300_SYSCON_CEFR_I2S0_CLK_EN;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+static void disable_i2s1_vcxo(void)
+{
+ u16 val;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ /* Disable I2S1 use of the VCXO 26 MHz clock */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= ~U300_SYSCON_CCR_I2S1_USE_VCXO;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ /* Deactivate VCXO if noone else is using VCXO */
+ if (!(val & U300_SYSCON_CCR_I2S0_USE_VCXO))
+ val &= ~U300_SYSCON_CCR_TURN_VCXO_ON;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ val &= ~U300_SYSCON_CEFR_I2S0_CLK_EN;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+#endif /* CONFIG_MACH_U300_USE_I2S_AS_MASTER */
+
+
+static void syscon_clk_rate_set_mclk(unsigned long rate)
+{
+ u16 val;
+ u32 reg;
+ unsigned long iflags;
+
+ switch (rate) {
+ case 18900000:
+ val = 0x0054;
+ break;
+ case 20800000:
+ val = 0x0044;
+ break;
+ case 23100000:
+ val = 0x0043;
+ break;
+ case 26000000:
+ val = 0x0033;
+ break;
+ case 29700000:
+ val = 0x0032;
+ break;
+ case 34700000:
+ val = 0x0022;
+ break;
+ case 41600000:
+ val = 0x0021;
+ break;
+ case 52000000:
+ val = 0x0011;
+ break;
+ case 104000000:
+ val = 0x0000;
+ break;
+ default:
+ printk(KERN_ERR "Trying to set MCLK to unknown speed! %ld\n",
+ rate);
+ return;
+ }
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ reg = readw(U300_SYSCON_VBASE + U300_SYSCON_MMF0R) &
+ ~U300_SYSCON_MMF0R_MASK;
+ writew(reg | val, U300_SYSCON_VBASE + U300_SYSCON_MMF0R);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+void syscon_clk_rate_set_cpuclk(unsigned long rate)
+{
+ u16 val;
+ unsigned long iflags;
+
+ switch (rate) {
+ case 13000000:
+ val = U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER;
+ break;
+ case 52000000:
+ val = U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE;
+ break;
+ case 104000000:
+ val = U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH;
+ break;
+ case 208000000:
+ val = U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST;
+ break;
+ default:
+ return;
+ }
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ val |= readw(U300_SYSCON_VBASE + U300_SYSCON_CCR) &
+ ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK ;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+EXPORT_SYMBOL(syscon_clk_rate_set_cpuclk);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long iflags;
+
+ spin_lock_irqsave(&clk->lock, iflags);
+ if (clk->usecount > 0 && !(--clk->usecount)) {
+ /* some blocks lack clocking registers and cannot be disabled */
+ if (clk->disable)
+ clk->disable(clk);
+ if (likely((u32)clk->parent))
+ clk_disable(clk->parent);
+ }
+#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
+ if (unlikely(!strcmp(clk->name, "I2S0")))
+ disable_i2s0_vcxo();
+ if (unlikely(!strcmp(clk->name, "I2S1")))
+ disable_i2s1_vcxo();
+#endif
+ spin_unlock_irqrestore(&clk->lock, iflags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&clk->lock, iflags);
+ if (clk->usecount++ == 0) {
+ if (likely((u32)clk->parent))
+ ret = clk_enable(clk->parent);
+
+ if (unlikely(ret != 0))
+ clk->usecount--;
+ else {
+ /* remove reset line (we never enable reset again) */
+ syscon_block_reset_disable(clk);
+ /* clocks without enable function are always on */
+ if (clk->enable)
+ clk->enable(clk);
+#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
+ if (unlikely(!strcmp(clk->name, "I2S0")))
+ enable_i2s0_vcxo();
+ if (unlikely(!strcmp(clk->name, "I2S1")))
+ enable_i2s1_vcxo();
+#endif
+ }
+ }
+ spin_unlock_irqrestore(&clk->lock, iflags);
+ return ret;
+
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* Returns the clock rate in Hz */
+static unsigned long clk_get_rate_cpuclk(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ return 13000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ return 52000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ return 104000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ return 208000000;
+ default:
+ break;
+ }
+ return clk->rate;
+}
+
+static unsigned long clk_get_rate_ahb_clk(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ return 6500000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ return 26000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ return 52000000;
+ default:
+ break;
+ }
+ return clk->rate;
+
+}
+
+static unsigned long clk_get_rate_emif_clk(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ return 13000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ return 52000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ return 104000000;
+ default:
+ break;
+ }
+ return clk->rate;
+
+}
+
+static unsigned long clk_get_rate_xgamclk(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ return 6500000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ return 26000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ return 52000000;
+ default:
+ break;
+ }
+
+ return clk->rate;
+}
+
+static unsigned long clk_get_rate_mclk(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ /*
+ * Here, the 208 MHz PLL gets shut down and the always
+ * on 13 MHz PLL used for RTC etc kicks into use
+ * instead.
+ */
+ return 13000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ {
+ /*
+ * This clock is under program control. The register is
+ * divided in two nybbles, bit 7-4 gives cycles-1 to count
+ * high, bit 3-0 gives cycles-1 to count low. Distribute
+ * these with no more than 1 cycle difference between
+ * low and high and add low and high to get the actual
+ * divisor. The base PLL is 208 MHz. Writing 0x00 will
+ * divide by 1 and 1 so the highest frequency possible
+ * is 104 MHz.
+ *
+ * e.g. 0x54 =>
+ * f = 208 / ((5+1) + (4+1)) = 208 / 11 = 18.9 MHz
+ */
+ u16 val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMF0R) &
+ U300_SYSCON_MMF0R_MASK;
+ switch (val) {
+ case 0x0054:
+ return 18900000;
+ case 0x0044:
+ return 20800000;
+ case 0x0043:
+ return 23100000;
+ case 0x0033:
+ return 26000000;
+ case 0x0032:
+ return 29700000;
+ case 0x0022:
+ return 34700000;
+ case 0x0021:
+ return 41600000;
+ case 0x0011:
+ return 52000000;
+ case 0x0000:
+ return 104000000;
+ default:
+ break;
+ }
+ }
+ default:
+ break;
+ }
+
+ return clk->rate;
+}
+
+static unsigned long clk_get_rate_i2s_i2c_spi(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ return 13000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ return 26000000;
+ default:
+ break;
+ }
+
+ return clk->rate;
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+ else
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+static unsigned long clk_round_rate_mclk(struct clk *clk, unsigned long rate)
+{
+ if (rate >= 18900000)
+ return 18900000;
+ if (rate >= 20800000)
+ return 20800000;
+ if (rate >= 23100000)
+ return 23100000;
+ if (rate >= 26000000)
+ return 26000000;
+ if (rate >= 29700000)
+ return 29700000;
+ if (rate >= 34700000)
+ return 34700000;
+ if (rate >= 41600000)
+ return 41600000;
+ if (rate >= 52000000)
+ return 52000000;
+ return -EINVAL;
+}
+
+static unsigned long clk_round_rate_cpuclk(struct clk *clk, unsigned long rate)
+{
+ if (rate >= 13000000)
+ return 13000000;
+ if (rate >= 52000000)
+ return 52000000;
+ if (rate >= 104000000)
+ return 104000000;
+ if (rate >= 208000000)
+ return 208000000;
+ return -EINVAL;
+}
+
+/*
+ * This adjusts a requested rate to the closest exact rate
+ * a certain clock can provide. For a fixed clock it's
+ * mostly clk->rate.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ /* TODO: get apropriate switches for EMIFCLK, AHBCLK and MCLK */
+ /* Else default to fixed value */
+
+ if (clk->round_rate) {
+ return (long) clk->round_rate(clk, rate);
+ } else {
+ printk(KERN_ERR "clock: Failed to round rate of %s\n",
+ clk->name);
+ }
+ return (long) clk->rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+static int clk_set_rate_mclk(struct clk *clk, unsigned long rate)
+{
+ syscon_clk_rate_set_mclk(clk_round_rate(clk, rate));
+ return 0;
+}
+
+static int clk_set_rate_cpuclk(struct clk *clk, unsigned long rate)
+{
+ syscon_clk_rate_set_cpuclk(clk_round_rate(clk, rate));
+ return 0;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ /* TODO: set for EMIFCLK and AHBCLK */
+ /* Else assume the clock is fixed and fail */
+ if (clk->set_rate) {
+ return clk->set_rate(clk, rate);
+ } else {
+ printk(KERN_ERR "clock: Failed to set %s to %ld hz\n",
+ clk->name, rate);
+ return -1;
+ }
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/*
+ * Clock definitions. The clock parents are set to respective
+ * bridge and the clock framework makes sure that the clocks have
+ * parents activated and are brought out of reset when in use.
+ *
+ * Clocks that have hw_ctrld = true are hw controlled, and the hw
+ * can by itself turn these clocks on and off.
+ * So in other words, we don't really have to care about them.
+ */
+
+static struct clk amba_clk = {
+ .name = "AMBA",
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = false,
+};
+
+/*
+ * These blocks are connected directly to the AMBA bus
+ * with no bridge.
+ */
+
+static struct clk cpu_clk = {
+ .name = "CPU",
+ .parent = &amba_clk,
+ .rate = 208000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_CPU_RESET_EN,
+ .set_rate = clk_set_rate_cpuclk,
+ .get_rate = clk_get_rate_cpuclk,
+ .round_rate = clk_round_rate_cpuclk,
+};
+
+static struct clk nandif_clk = {
+ .name = "NANDIF",
+ .parent = &amba_clk,
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_NANDIF_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_NANDIF_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk semi_clk = {
+ .name = "SEMI",
+ .parent = &amba_clk,
+ .rate = 0, /* FIXME */
+ /* It is not possible to reset SEMI */
+ .hw_ctrld = false,
+ .reset = false,
+ .clk_val = U300_SYSCON_SBCER_SEMI_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+#ifdef CONFIG_MACH_U300_BS335
+static struct clk isp_clk = {
+ .name = "ISP",
+ .parent = &amba_clk,
+ .rate = 0, /* FIXME */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_ISP_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_ISP_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk cds_clk = {
+ .name = "CDS",
+ .parent = &amba_clk,
+ .rate = 0, /* FIXME */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_CDS_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_CDS_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+#endif
+
+static struct clk dma_clk = {
+ .name = "DMA",
+ .parent = &amba_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_DMAC_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_DMAC_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk aaif_clk = {
+ .name = "AAIF",
+ .parent = &amba_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_AAIF_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_AAIF_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk apex_clk = {
+ .name = "APEX",
+ .parent = &amba_clk,
+ .rate = 0, /* FIXME */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_APEX_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_APEX_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk video_enc_clk = {
+ .name = "VIDEO_ENC",
+ .parent = &amba_clk,
+ .rate = 208000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = false,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ /* This has XGAM in the name but refers to the video encoder */
+ .res_mask = U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk xgam_clk = {
+ .name = "XGAMCLK",
+ .parent = &amba_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_XGAM_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_XGAM_CLK_EN,
+ .get_rate = clk_get_rate_xgamclk,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+/* This clock is used to activate the video encoder */
+static struct clk ahb_clk = {
+ .name = "AHB",
+ .parent = &amba_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = false, /* This one is set to false due to HW bug */
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_AHB_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_AHB_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_ahb_clk,
+};
+
+
+/*
+ * Clocks on the AHB bridge
+ */
+
+static struct clk ahb_subsys_clk = {
+ .name = "AHB_SUBSYS",
+ .parent = &amba_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = false,
+ .clk_val = U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_ahb_clk,
+};
+
+static struct clk intcon_clk = {
+ .name = "INTCON",
+ .parent = &ahb_subsys_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_INTCON_RESET_EN,
+ /* INTCON can be reset but not clock-gated */
+};
+
+static struct clk mspro_clk = {
+ .name = "MSPRO",
+ .parent = &ahb_subsys_clk,
+ .rate = 0, /* FIXME */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_MSPRO_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_MSPRO_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk emif_clk = {
+ .name = "EMIF",
+ .parent = &ahb_subsys_clk,
+ .rate = 104000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_EMIF_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_EMIF_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_emif_clk,
+};
+
+
+/*
+ * Clocks on the FAST bridge
+ */
+static struct clk fast_clk = {
+ .name = "FAST_BRIDGE",
+ .parent = &amba_clk,
+ .rate = 13000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk mmcsd_clk = {
+ .name = "MCLK",
+ .parent = &fast_clk,
+ .rate = 18900000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_MMC_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_MMC_CLK_EN,
+ .get_rate = clk_get_rate_mclk,
+ .set_rate = clk_set_rate_mclk,
+ .round_rate = clk_round_rate_mclk,
+ .disable = syscon_clk_disable,
+ .enable = syscon_clk_enable,
+};
+
+static struct clk i2s0_clk = {
+ .name = "i2s0",
+ .parent = &fast_clk,
+ .rate = 26000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_I2S0_CORE_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_i2s_i2c_spi,
+};
+
+static struct clk i2s1_clk = {
+ .name = "i2s1",
+ .parent = &fast_clk,
+ .rate = 26000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_I2S1_CORE_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_i2s_i2c_spi,
+};
+
+static struct clk i2c0_clk = {
+ .name = "I2C0",
+ .parent = &fast_clk,
+ .rate = 26000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_I2C0_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_I2C0_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_i2s_i2c_spi,
+};
+
+static struct clk i2c1_clk = {
+ .name = "I2C1",
+ .parent = &fast_clk,
+ .rate = 26000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_I2C1_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_I2C1_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_i2s_i2c_spi,
+};
+
+static struct clk spi_clk = {
+ .name = "SPI",
+ .parent = &fast_clk,
+ .rate = 26000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_SPI_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_SPI_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_i2s_i2c_spi,
+};
+
+#ifdef CONFIG_MACH_U300_BS335
+static struct clk uart1_clk = {
+ .name = "UART1",
+ .parent = &fast_clk,
+ .rate = 13000000,
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_UART1_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_UART1_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+#endif
+
+
+/*
+ * Clocks on the SLOW bridge
+ */
+static struct clk slow_clk = {
+ .name = "SLOW_BRIDGE",
+ .parent = &amba_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+/* TODO: implement SYSCON clock? */
+
+static struct clk wdog_clk = {
+ .name = "WDOG",
+ .parent = &slow_clk,
+ .hw_ctrld = false,
+ .rate = 32768,
+ .reset = false,
+ /* This is always on, cannot be enabled/disabled or reset */
+};
+
+/* This one is hardwired to PLL13 */
+static struct clk uart_clk = {
+ .name = "UARTCLK",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_UART_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_UART_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk keypad_clk = {
+ .name = "KEYPAD",
+ .parent = &slow_clk,
+ .rate = 32768,
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_KEYPAD_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_KEYPAD_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk gpio_clk = {
+ .name = "GPIO",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_GPIO_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_GPIO_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk rtc_clk = {
+ .name = "RTC",
+ .parent = &slow_clk,
+ .rate = 32768,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_RTC_RESET_EN,
+ /* This clock is always on, cannot be enabled/disabled */
+};
+
+static struct clk bustr_clk = {
+ .name = "BUSTR",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_BTR_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_BTR_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk evhist_clk = {
+ .name = "EVHIST",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_EH_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_EH_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk timer_clk = {
+ .name = "TIMER",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_ACC_TMR_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_ACC_TMR_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+static struct clk app_timer_clk = {
+ .name = "TIMER_APP",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_APP_TMR_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_APP_TMR_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+
+#ifdef CONFIG_MACH_U300_BS335
+static struct clk ppm_clk = {
+ .name = "PPM",
+ .parent = &slow_clk,
+ .rate = 0, /* FIXME */
+ .hw_ctrld = true, /* TODO: Look up if it is hw ctrld or not */
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_PPM_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_PPM_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+};
+#endif
+
+#define DEF_LOOKUP(devid, clkref) \
+ { \
+ .dev_id = devid, \
+ .clk = clkref, \
+ }
+
+/*
+ * Here we only define clocks that are meaningful to
+ * look up through clockdevice.
+ */
+static struct clk_lookup lookups[] = {
+ /* Connected directly to the AMBA bus */
+ DEF_LOOKUP("amba", &amba_clk),
+ DEF_LOOKUP("cpu", &cpu_clk),
+ DEF_LOOKUP("nandif", &nandif_clk),
+ DEF_LOOKUP("semi", &semi_clk),
+#ifdef CONFIG_MACH_U300_BS335
+ DEF_LOOKUP("isp", &isp_clk),
+ DEF_LOOKUP("cds", &cds_clk),
+#endif
+ DEF_LOOKUP("dma", &dma_clk),
+ DEF_LOOKUP("aaif", &aaif_clk),
+ DEF_LOOKUP("apex", &apex_clk),
+ DEF_LOOKUP("video_enc", &video_enc_clk),
+ DEF_LOOKUP("xgam", &xgam_clk),
+ DEF_LOOKUP("ahb", &ahb_clk),
+ /* AHB bridge clocks */
+ DEF_LOOKUP("ahb", &ahb_subsys_clk),
+ DEF_LOOKUP("intcon", &intcon_clk),
+ DEF_LOOKUP("mspro", &mspro_clk),
+ DEF_LOOKUP("pl172", &emif_clk),
+ /* FAST bridge clocks */
+ DEF_LOOKUP("fast", &fast_clk),
+ DEF_LOOKUP("mmci", &mmcsd_clk),
+ /*
+ * The .0 and .1 identifiers on these comes from the platform device
+ * .id field and are assigned when the platform devices are registered.
+ */
+ DEF_LOOKUP("i2s.0", &i2s0_clk),
+ DEF_LOOKUP("i2s.1", &i2s1_clk),
+ DEF_LOOKUP("stddci2c.0", &i2c0_clk),
+ DEF_LOOKUP("stddci2c.1", &i2c1_clk),
+ DEF_LOOKUP("pl022", &spi_clk),
+#ifdef CONFIG_MACH_U300_BS335
+ DEF_LOOKUP("uart1", &uart1_clk),
+#endif
+ /* SLOW bridge clocks */
+ DEF_LOOKUP("slow", &slow_clk),
+ DEF_LOOKUP("wdog", &wdog_clk),
+ DEF_LOOKUP("uart0", &uart_clk),
+ DEF_LOOKUP("apptimer", &app_timer_clk),
+ DEF_LOOKUP("keypad", &keypad_clk),
+ DEF_LOOKUP("u300-gpio", &gpio_clk),
+ DEF_LOOKUP("rtc0", &rtc_clk),
+ DEF_LOOKUP("bustr", &bustr_clk),
+ DEF_LOOKUP("evhist", &evhist_clk),
+ DEF_LOOKUP("timer", &timer_clk),
+#ifdef CONFIG_MACH_U300_BS335
+ DEF_LOOKUP("ppm", &ppm_clk),
+#endif
+};
+
+static void __init clk_register(void)
+{
+ int i;
+
+ /* Register the lookups */
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
+}
+
+/*
+ * These are the clocks for cells registered as primecell drivers
+ * on the AMBA bus. These must be on during AMBA device registration
+ * since the bus probe will attempt to read magic configuration
+ * registers for these devices. If they are deactivated these probes
+ * will fail.
+ *
+ *
+ * Please note that on emif, both RAM and NAND is connected in dual
+ * RAM phones. On single RAM phones, ram is on semi and NAND on emif.
+ *
+ */
+void u300_clock_primecells(void)
+{
+ clk_enable(&intcon_clk);
+ clk_enable(&uart_clk);
+#ifdef CONFIG_MACH_U300_BS335
+ clk_enable(&uart1_clk);
+#endif
+ clk_enable(&spi_clk);
+
+ clk_enable(&mmcsd_clk);
+
+}
+EXPORT_SYMBOL(u300_clock_primecells);
+
+void u300_unclock_primecells(void)
+{
+
+ clk_disable(&intcon_clk);
+ clk_disable(&uart_clk);
+#ifdef CONFIG_MACH_U300_BS335
+ clk_disable(&uart1_clk);
+#endif
+ clk_disable(&spi_clk);
+ clk_disable(&mmcsd_clk);
+
+}
+EXPORT_SYMBOL(u300_unclock_primecells);
+
+/*
+ * The interrupt controller is enabled before the clock API is registered.
+ */
+void u300_enable_intcon_clock(void)
+{
+ clk_enable(&intcon_clk);
+}
+EXPORT_SYMBOL(u300_enable_intcon_clock);
+
+/*
+ * The timer is enabled before the clock API is registered.
+ */
+void u300_enable_timer_clock(void)
+{
+ clk_enable(&app_timer_clk);
+}
+EXPORT_SYMBOL(u300_enable_timer_clock);
+
+#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
+/*
+ * The following makes it possible to view the status (especially
+ * reference count and reset status) for the clocks in the platform
+ * by looking into the special file <debugfs>/u300_clocks
+ */
+
+/* A list of all clocks in the platform */
+static struct clk *clks[] = {
+ /* Top node clock for the AMBA bus */
+ &amba_clk,
+ /* Connected directly to the AMBA bus */
+ &cpu_clk,
+ &nandif_clk,
+ &semi_clk,
+#ifdef CONFIG_MACH_U300_BS335
+ &isp_clk,
+ &cds_clk,
+#endif
+ &dma_clk,
+ &aaif_clk,
+ &apex_clk,
+ &video_enc_clk,
+ &xgam_clk,
+ &ahb_clk,
+
+ /* AHB bridge clocks */
+ &ahb_subsys_clk,
+ &intcon_clk,
+ &mspro_clk,
+ &emif_clk,
+ /* FAST bridge clocks */
+ &fast_clk,
+ &mmcsd_clk,
+ &i2s0_clk,
+ &i2s1_clk,
+ &i2c0_clk,
+ &i2c1_clk,
+ &spi_clk,
+#ifdef CONFIG_MACH_U300_BS335
+ &uart1_clk,
+#endif
+ /* SLOW bridge clocks */
+ &slow_clk,
+ &wdog_clk,
+ &uart_clk,
+ &app_timer_clk,
+ &keypad_clk,
+ &gpio_clk,
+ &rtc_clk,
+ &bustr_clk,
+ &evhist_clk,
+ &timer_clk,
+#ifdef CONFIG_MACH_U300_BS335
+ &ppm_clk,
+#endif
+};
+
+static int u300_clocks_show(struct seq_file *s, void *data)
+{
+ struct clk *clk;
+ int i;
+
+ seq_printf(s, "CLOCK DEVICE RESET STATE\t" \
+ "ACTIVE\tUSERS\tHW CTRL FREQ\n");
+ seq_printf(s, "---------------------------------------------" \
+ "-----------------------------------------\n");
+ for (i = 0; i < ARRAY_SIZE(clks); i++) {
+ clk = clks[i];
+ if (clk != ERR_PTR(-ENOENT)) {
+ /* Format clock and device name nicely */
+ char cdp[33];
+ int chars;
+
+ chars = snprintf(&cdp[0], 17, "%s", clk->name);
+ while (chars < 16) {
+ cdp[chars] = ' ';
+ chars++;
+ }
+ chars = snprintf(&cdp[16], 17, "%s", clk->dev ?
+ dev_name(clk->dev) : "N/A");
+ while (chars < 16) {
+ cdp[chars+16] = ' ';
+ chars++;
+ }
+ cdp[32] = '\0';
+ if (clk->get_rate)
+ seq_printf(s,
+ "%s%s\t%s\t%d\t%s\t%lu Hz\n",
+ &cdp[0],
+ clk->reset ?
+ "ASSERTED" : "RELEASED",
+ clk->usecount ? "ON" : "OFF",
+ clk->usecount,
+ clk->hw_ctrld ? "YES" : "NO ",
+ clk->get_rate(clk));
+ else
+ seq_printf(s,
+ "%s%s\t%s\t%d\t%s\t" \
+ "(unknown rate)\n",
+ &cdp[0],
+ clk->reset ?
+ "ASSERTED" : "RELEASED",
+ clk->usecount ? "ON" : "OFF",
+ clk->usecount,
+ clk->hw_ctrld ? "YES" : "NO ");
+ }
+ }
+ return 0;
+}
+
+static int u300_clocks_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, u300_clocks_show, NULL);
+}
+
+static const struct file_operations u300_clocks_operations = {
+ .open = u300_clocks_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static void init_clk_read_procfs(void)
+{
+ /* Expose a simple debugfs interface to view all clocks */
+ (void) debugfs_create_file("u300_clocks", S_IFREG | S_IRUGO,
+ NULL, NULL, &u300_clocks_operations);
+}
+#else
+static inline void init_clk_read_procfs(void)
+{
+}
+#endif
+
+static int __init u300_clock_init(void)
+{
+ u16 val;
+
+ /*
+ * FIXME: shall all this powermanagement stuff really live here???
+ */
+
+ /* Set system to run at PLL208, max performance, a known state. */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ /* Wait for the PLL208 to lock if not locked in yet */
+ while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) &
+ U300_SYSCON_CSR_PLL208_LOCK_IND));
+
+ /* Power management enable */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR);
+ val |= U300_SYSCON_PMCR_PWR_MGNT_ENABLE;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR);
+
+ clk_register();
+
+ init_clk_read_procfs();
+
+ /*
+ * Some of these may be on when we boot the system so make sure they
+ * are turned OFF.
+ */
+ syscon_block_reset_enable(&timer_clk);
+ timer_clk.disable(&timer_clk);
+
+ /*
+ * These shall be turned on by default when we boot the system
+ * so make sure they are ON. (Adding CPU here is a bit too much.)
+ * These clocks will be claimed by drivers later.
+ */
+ syscon_block_reset_disable(&semi_clk);
+ syscon_block_reset_disable(&emif_clk);
+ semi_clk.enable(&semi_clk);
+ emif_clk.enable(&emif_clk);
+
+ return 0;
+}
+/* initialize clocking early to be available later in the boot */
+core_initcall(u300_clock_init);
diff --git a/arch/arm/mach-u300/clock.h b/arch/arm/mach-u300/clock.h
new file mode 100644
index 000000000000..fc6d9ccfe7e3
--- /dev/null
+++ b/arch/arm/mach-u300/clock.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-u300/include/mach/clock.h
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * Adopted to ST-Ericsson U300 platforms by
+ * Jonas Aaberg <jonas.aberg@stericsson.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 __MACH_CLOCK_H
+#define __MACH_CLOCK_H
+
+#include <linux/clk.h>
+
+struct clk {
+ struct list_head node;
+ struct module *owner;
+ struct device *dev;
+ const char *name;
+ struct clk *parent;
+
+ spinlock_t lock;
+ unsigned long rate;
+ bool reset;
+ __u16 clk_val;
+ __s8 usecount;
+ __u32 res_reg;
+ __u16 res_mask;
+
+ bool hw_ctrld;
+
+ void (*recalc) (struct clk *);
+ int (*set_rate) (struct clk *, unsigned long);
+ unsigned long (*get_rate) (struct clk *);
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ void (*init) (struct clk *);
+ void (*enable) (struct clk *);
+ void (*disable) (struct clk *);
+};
+
+void u300_clock_primecells(void);
+void u300_unclock_primecells(void);
+void u300_enable_intcon_clock(void);
+void u300_enable_timer_clock(void);
+
+#endif
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
new file mode 100644
index 000000000000..1f2ed21a0ab1
--- /dev/null
+++ b/arch/arm/mach-u300/core.c
@@ -0,0 +1,649 @@
+/*
+ *
+ * arch/arm/mach-u300/core.c
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Core platform support, IRQ handling and device definitions.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/termios.h>
+#include <linux/amba/bus.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware/vic.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/syscon.h>
+
+#include "clock.h"
+#include "mmc.h"
+
+/*
+ * Static I/O mappings that are needed for booting the U300 platforms. The
+ * only things we need are the areas where we find the timer, syscon and
+ * intcon, since the remaining device drivers will map their own memory
+ * physical to virtual as the need arise.
+ */
+static struct map_desc u300_io_desc[] __initdata = {
+ {
+ .virtual = U300_SLOW_PER_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = U300_AHB_PER_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_AHB_PER_PHYS_BASE),
+ .length = SZ_32K,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = U300_FAST_PER_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_FAST_PER_PHYS_BASE),
+ .length = SZ_32K,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = 0xffff2000, /* TCM memory */
+ .pfn = __phys_to_pfn(0xffff2000),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ },
+
+ /*
+ * This overlaps with the IRQ vectors etc at 0xffff0000, so these
+ * may have to be moved to 0x00000000 in order to use the ROM.
+ */
+ /*
+ {
+ .virtual = U300_BOOTROM_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_BOOTROM_PHYS_BASE),
+ .length = SZ_64K,
+ .type = MT_ROM,
+ },
+ */
+};
+
+void __init u300_map_io(void)
+{
+ iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
+}
+
+/*
+ * Declaration of devices found on the U300 board and
+ * their respective memory locations.
+ */
+static struct amba_device uart0_device = {
+ .dev = {
+ .init_name = "uart0", /* Slow device at 0x3000 offset */
+ .platform_data = NULL,
+ },
+ .res = {
+ .start = U300_UART0_BASE,
+ .end = U300_UART0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_U300_UART0, NO_IRQ },
+};
+
+/* The U335 have an additional UART1 on the APP CPU */
+#ifdef CONFIG_MACH_U300_BS335
+static struct amba_device uart1_device = {
+ .dev = {
+ .init_name = "uart1", /* Fast device at 0x7000 offset */
+ .platform_data = NULL,
+ },
+ .res = {
+ .start = U300_UART1_BASE,
+ .end = U300_UART1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_U300_UART1, NO_IRQ },
+};
+#endif
+
+static struct amba_device pl172_device = {
+ .dev = {
+ .init_name = "pl172", /* AHB device at 0x4000 offset */
+ .platform_data = NULL,
+ },
+ .res = {
+ .start = U300_EMIF_CFG_BASE,
+ .end = U300_EMIF_CFG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+
+/*
+ * Everything within this next ifdef deals with external devices connected to
+ * the APP SPI bus.
+ */
+static struct amba_device pl022_device = {
+ .dev = {
+ .coherent_dma_mask = ~0,
+ .init_name = "pl022", /* Fast device at 0x6000 offset */
+ },
+ .res = {
+ .start = U300_SPI_BASE,
+ .end = U300_SPI_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_U300_SPI, NO_IRQ },
+ /*
+ * This device has a DMA channel but the Linux driver does not use
+ * it currently.
+ */
+};
+
+static struct amba_device mmcsd_device = {
+ .dev = {
+ .init_name = "mmci", /* Fast device at 0x1000 offset */
+ .platform_data = NULL, /* Added later */
+ },
+ .res = {
+ .start = U300_MMCSD_BASE,
+ .end = U300_MMCSD_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 },
+ /*
+ * This device has a DMA channel but the Linux driver does not use
+ * it currently.
+ */
+};
+
+/*
+ * The order of device declaration may be important, since some devices
+ * have dependencies on other devices being initialized first.
+ */
+static struct amba_device *amba_devs[] __initdata = {
+ &uart0_device,
+#ifdef CONFIG_MACH_U300_BS335
+ &uart1_device,
+#endif
+ &pl022_device,
+ &pl172_device,
+ &mmcsd_device,
+};
+
+/* Here follows a list of all hw resources that the platform devices
+ * allocate. Note, clock dependencies are not included
+ */
+
+static struct resource gpio_resources[] = {
+ {
+ .start = U300_GPIO_BASE,
+ .end = (U300_GPIO_BASE + SZ_4K - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "gpio0",
+ .start = IRQ_U300_GPIO_PORT0,
+ .end = IRQ_U300_GPIO_PORT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio1",
+ .start = IRQ_U300_GPIO_PORT1,
+ .end = IRQ_U300_GPIO_PORT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio2",
+ .start = IRQ_U300_GPIO_PORT2,
+ .end = IRQ_U300_GPIO_PORT2,
+ .flags = IORESOURCE_IRQ,
+ },
+#ifdef U300_COH901571_3
+ {
+ .name = "gpio3",
+ .start = IRQ_U300_GPIO_PORT3,
+ .end = IRQ_U300_GPIO_PORT3,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio4",
+ .start = IRQ_U300_GPIO_PORT4,
+ .end = IRQ_U300_GPIO_PORT4,
+ .flags = IORESOURCE_IRQ,
+ },
+#ifdef CONFIG_MACH_U300_BS335
+ {
+ .name = "gpio5",
+ .start = IRQ_U300_GPIO_PORT5,
+ .end = IRQ_U300_GPIO_PORT5,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio6",
+ .start = IRQ_U300_GPIO_PORT6,
+ .end = IRQ_U300_GPIO_PORT6,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif /* CONFIG_MACH_U300_BS335 */
+#endif /* U300_COH901571_3 */
+};
+
+static struct resource keypad_resources[] = {
+ {
+ .start = U300_KEYPAD_BASE,
+ .end = U300_KEYPAD_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "coh901461-press",
+ .start = IRQ_U300_KEYPAD_KEYBF,
+ .end = IRQ_U300_KEYPAD_KEYBF,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "coh901461-release",
+ .start = IRQ_U300_KEYPAD_KEYBR,
+ .end = IRQ_U300_KEYPAD_KEYBR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource rtc_resources[] = {
+ {
+ .start = U300_RTC_BASE,
+ .end = U300_RTC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_RTC,
+ .end = IRQ_U300_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*
+ * Fsmc does have IRQs: #43 and #44 (NFIF and NFIF2)
+ * but these are not yet used by the driver.
+ */
+static struct resource fsmc_resources[] = {
+ {
+ .start = U300_NAND_IF_PHYS_BASE,
+ .end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource i2c0_resources[] = {
+ {
+ .start = U300_I2C0_BASE,
+ .end = U300_I2C0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_I2C0,
+ .end = IRQ_U300_I2C0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c1_resources[] = {
+ {
+ .start = U300_I2C1_BASE,
+ .end = U300_I2C1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_I2C1,
+ .end = IRQ_U300_I2C1,
+ .flags = IORESOURCE_IRQ,
+ },
+
+};
+
+static struct resource wdog_resources[] = {
+ {
+ .start = U300_WDOG_BASE,
+ .end = U300_WDOG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_WDOG,
+ .end = IRQ_U300_WDOG,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* TODO: These should be protected by suitable #ifdef's */
+static struct resource ave_resources[] = {
+ {
+ .name = "AVE3e I/O Area",
+ .start = U300_VIDEOENC_BASE,
+ .end = U300_VIDEOENC_BASE + SZ_512K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "AVE3e IRQ0",
+ .start = IRQ_U300_VIDEO_ENC_0,
+ .end = IRQ_U300_VIDEO_ENC_0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "AVE3e IRQ1",
+ .start = IRQ_U300_VIDEO_ENC_1,
+ .end = IRQ_U300_VIDEO_ENC_1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "AVE3e Physmem Area",
+ .start = 0, /* 0 will be remapped to reserved memory */
+ .end = SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ * The AVE3e requires two regions of 256MB that it considers
+ * "invisible". The hardware will not be able to access these
+ * adresses, so they should never point to system RAM.
+ */
+ {
+ .name = "AVE3e Reserved 0",
+ .start = 0xd0000000,
+ .end = 0xd0000000 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "AVE3e Reserved 1",
+ .start = 0xe0000000,
+ .end = 0xe0000000 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device wdog_device = {
+ .name = "wdog",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(wdog_resources),
+ .resource = wdog_resources,
+};
+
+static struct platform_device i2c0_device = {
+ .name = "stddci2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(i2c0_resources),
+ .resource = i2c0_resources,
+};
+
+static struct platform_device i2c1_device = {
+ .name = "stddci2c",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(i2c1_resources),
+ .resource = i2c1_resources,
+};
+
+static struct platform_device gpio_device = {
+ .name = "u300-gpio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(gpio_resources),
+ .resource = gpio_resources,
+};
+
+static struct platform_device keypad_device = {
+ .name = "keypad",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(keypad_resources),
+ .resource = keypad_resources,
+};
+
+static struct platform_device rtc_device = {
+ .name = "rtc0",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+
+static struct platform_device fsmc_device = {
+ .name = "nandif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(fsmc_resources),
+ .resource = fsmc_resources,
+};
+
+static struct platform_device ave_device = {
+ .name = "video_enc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ave_resources),
+ .resource = ave_resources,
+};
+
+/*
+ * Notice that AMBA devices are initialized before platform devices.
+ *
+ */
+static struct platform_device *platform_devs[] __initdata = {
+ &i2c0_device,
+ &i2c1_device,
+ &keypad_device,
+ &rtc_device,
+ &gpio_device,
+ &fsmc_device,
+ &wdog_device,
+ &ave_device
+};
+
+
+/*
+ * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
+ * together so some interrupts are connected to the first one and some
+ * to the second one.
+ */
+void __init u300_init_irq(void)
+{
+ u32 mask[2] = {0, 0};
+ int i;
+
+ for (i = 0; i < NR_IRQS; i++)
+ set_bit(i, (unsigned long *) &mask[0]);
+ u300_enable_intcon_clock();
+ vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0]);
+ vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1]);
+}
+
+
+/*
+ * U300 platforms peripheral handling
+ */
+struct db_chip {
+ u16 chipid;
+ const char *name;
+};
+
+/*
+ * This is a list of the Digital Baseband chips used in the U300 platform.
+ */
+static struct db_chip db_chips[] __initdata = {
+ {
+ .chipid = 0xb800,
+ .name = "DB3000",
+ },
+ {
+ .chipid = 0xc000,
+ .name = "DB3100",
+ },
+ {
+ .chipid = 0xc800,
+ .name = "DB3150",
+ },
+ {
+ .chipid = 0xd800,
+ .name = "DB3200",
+ },
+ {
+ .chipid = 0xe000,
+ .name = "DB3250",
+ },
+ {
+ .chipid = 0xe800,
+ .name = "DB3210",
+ },
+ {
+ .chipid = 0xf000,
+ .name = "DB3350 P1x",
+ },
+ {
+ .chipid = 0xf100,
+ .name = "DB3350 P2x",
+ },
+ {
+ .chipid = 0x0000, /* List terminator */
+ .name = NULL,
+ }
+};
+
+static void u300_init_check_chip(void)
+{
+
+ u16 val;
+ struct db_chip *chip;
+ const char *chipname;
+ const char unknown[] = "UNKNOWN";
+
+ /* Read out and print chip ID */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR);
+ /* This is in funky bigendian order... */
+ val = (val & 0xFFU) << 8 | (val >> 8);
+ chip = db_chips;
+ chipname = unknown;
+
+ for ( ; chip->chipid; chip++) {
+ if (chip->chipid == (val & 0xFF00U)) {
+ chipname = chip->name;
+ break;
+ }
+ }
+ printk(KERN_INFO "Initializing U300 system on %s baseband chip " \
+ "(chip ID 0x%04x)\n", chipname, val);
+
+#ifdef CONFIG_MACH_U300_BS26
+ if ((val & 0xFF00U) != 0xc800) {
+ printk(KERN_ERR "Platform configured for BS25/BS26 " \
+ "with DB3150 but %s detected, expect problems!",
+ chipname);
+ }
+#endif
+#ifdef CONFIG_MACH_U300_BS330
+ if ((val & 0xFF00U) != 0xd800) {
+ printk(KERN_ERR "Platform configured for BS330 " \
+ "with DB3200 but %s detected, expect problems!",
+ chipname);
+ }
+#endif
+#ifdef CONFIG_MACH_U300_BS335
+ if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) {
+ printk(KERN_ERR "Platform configured for BS365 " \
+ " with DB3350 but %s detected, expect problems!",
+ chipname);
+ }
+#endif
+#ifdef CONFIG_MACH_U300_BS365
+ if ((val & 0xFF00U) != 0xe800) {
+ printk(KERN_ERR "Platform configured for BS365 " \
+ "with DB3210 but %s detected, expect problems!",
+ chipname);
+ }
+#endif
+
+
+}
+
+/*
+ * Some devices and their resources require reserved physical memory from
+ * the end of the available RAM. This function traverses the list of devices
+ * and assigns actual adresses to these.
+ */
+static void __init u300_assign_physmem(void)
+{
+ unsigned long curr_start = __pa(high_memory);
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(platform_devs); i++) {
+ for (j = 0; j < platform_devs[i]->num_resources; j++) {
+ struct resource *const res =
+ &platform_devs[i]->resource[j];
+
+ if (IORESOURCE_MEM == res->flags &&
+ 0 == res->start) {
+ res->start = curr_start;
+ res->end += curr_start;
+ curr_start += (res->end - res->start + 1);
+
+ printk(KERN_INFO "core.c: Mapping RAM " \
+ "%#x-%#x to device %s:%s\n",
+ res->start, res->end,
+ platform_devs[i]->name, res->name);
+ }
+ }
+ }
+}
+
+void __init u300_init_devices(void)
+{
+ int i;
+ u16 val;
+
+ /* Check what platform we run and print some status information */
+ u300_init_check_chip();
+
+ /* Set system to run at PLL208, max performance, a known state. */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ /* Wait for the PLL208 to lock if not locked in yet */
+ while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) &
+ U300_SYSCON_CSR_PLL208_LOCK_IND));
+
+ /* Register the AMBA devices in the AMBA bus abstraction layer */
+ u300_clock_primecells();
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+ u300_unclock_primecells();
+
+ u300_assign_physmem();
+
+ /* Register the platform devices */
+ platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
+#ifndef CONFIG_MACH_U300_SEMI_IS_SHARED
+ /*
+ * Enable SEMI self refresh. Self-refresh of the SDRAM is entered when
+ * both subsystems are requesting this mode.
+ * If we not share the Acc SDRAM, this is never the case. Therefore
+ * enable it here from the App side.
+ */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) |
+ U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
+#endif /* CONFIG_MACH_U300_SEMI_IS_SHARED */
+}
+
+static int core_module_init(void)
+{
+ /*
+ * This needs to be initialized later: it needs the input framework
+ * to be initialized first.
+ */
+ return mmc_init(&mmcsd_device);
+}
+module_init(core_module_init);
diff --git a/arch/arm/mach-u300/gpio.c b/arch/arm/mach-u300/gpio.c
new file mode 100644
index 000000000000..2d5ae8ecb8c8
--- /dev/null
+++ b/arch/arm/mach-u300/gpio.c
@@ -0,0 +1,701 @@
+/*
+ *
+ * arch/arm/mach-u300/gpio.c
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * U300 GPIO module.
+ * This can driver either of the two basic GPIO cores
+ * available in the U300 platforms:
+ * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0)
+ * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0)
+ * Notice that you also have inline macros in <asm-arch/gpio.h>
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ *
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+/* Need access to SYSCON registers for PADmuxing */
+#include <mach/syscon.h>
+
+#include "padmux.h"
+
+/* Reference to GPIO block clock */
+static struct clk *clk;
+
+/* Memory resource */
+static struct resource *memres;
+static void __iomem *virtbase;
+
+struct u300_gpio_port {
+ const char *name;
+ int irq;
+ int number;
+};
+
+
+static struct u300_gpio_port gpio_ports[] = {
+ {
+ .name = "gpio0",
+ .number = 0,
+ },
+ {
+ .name = "gpio1",
+ .number = 1,
+ },
+ {
+ .name = "gpio2",
+ .number = 2,
+ },
+#ifdef U300_COH901571_3
+ {
+ .name = "gpio3",
+ .number = 3,
+ },
+ {
+ .name = "gpio4",
+ .number = 4,
+ },
+#ifdef CONFIG_MACH_U300_BS335
+ {
+ .name = "gpio5",
+ .number = 5,
+ },
+ {
+ .name = "gpio6",
+ .number = 6,
+ },
+#endif
+#endif
+
+};
+
+
+#ifdef U300_COH901571_3
+
+/* Default input value */
+#define DEFAULT_OUTPUT_LOW 0
+#define DEFAULT_OUTPUT_HIGH 1
+
+/* GPIO Pull-Up status */
+#define DISABLE_PULL_UP 0
+#define ENABLE_PULL_UP 1
+
+#define GPIO_NOT_USED 0
+#define GPIO_IN 1
+#define GPIO_OUT 2
+
+struct u300_gpio_configuration_data {
+ unsigned char pin_usage;
+ unsigned char default_output_value;
+ unsigned char pull_up;
+};
+
+/* Initial configuration */
+const struct u300_gpio_configuration_data
+u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
+#ifdef CONFIG_MACH_U300_BS335
+ /* Port 0, pins 0-7 */
+ {
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ },
+ /* Port 1, pins 0-7 */
+ {
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ },
+ /* Port 2, pins 0-7 */
+ {
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
+ },
+ /* Port 3, pins 0-7 */
+ {
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ },
+ /* Port 4, pins 0-7 */
+ {
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ },
+ /* Port 5, pins 0-7 */
+ {
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ },
+ /* Port 6, pind 0-7 */
+ {
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ }
+#endif
+
+#ifdef CONFIG_MACH_U300_BS365
+ /* Port 0, pins 0-7 */
+ {
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ },
+ /* Port 1, pins 0-7 */
+ {
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
+ },
+ /* Port 2, pins 0-7 */
+ {
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
+ },
+ /* Port 3, pins 0-7 */
+ {
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
+ },
+ /* Port 4, pins 0-7 */
+ {
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ /* These 4 pins doesn't exist on DB3210 */
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
+ {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
+ }
+#endif
+};
+#endif
+
+
+/* No users == we can power down GPIO */
+static int gpio_users;
+
+struct gpio_struct {
+ int (*callback)(void *);
+ void *data;
+ int users;
+};
+
+static struct gpio_struct gpio_pin[U300_GPIO_MAX];
+
+/*
+ * Let drivers register callback in order to get notified when there is
+ * an interrupt on the gpio pin
+ */
+int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data)
+{
+ if (gpio_pin[gpio].callback)
+ printk(KERN_WARNING "GPIO: %s: WARNING: callback already " \
+ "registered for gpio pin#%d\n", __func__, gpio);
+ gpio_pin[gpio].callback = func;
+ gpio_pin[gpio].data = data;
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_register_callback);
+
+int gpio_unregister_callback(unsigned gpio)
+{
+ if (!gpio_pin[gpio].callback)
+ printk(KERN_WARNING "GPIO: %s: WARNING: callback already " \
+ "unregistered for gpio pin#%d\n", __func__, gpio);
+ gpio_pin[gpio].callback = NULL;
+ gpio_pin[gpio].data = NULL;
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_unregister_callback);
+
+int gpio_request(unsigned gpio, const char *label)
+{
+ if (gpio_pin[gpio].users)
+ return -EINVAL;
+ else
+ gpio_pin[gpio].users++;
+
+ gpio_users++;
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned gpio)
+{
+ gpio_users--;
+ gpio_pin[gpio].users--;
+ if (unlikely(gpio_pin[gpio].users < 0)) {
+ printk(KERN_WARNING "GPIO: Warning: gpio#%d release mismatch\n",
+ gpio);
+ gpio_pin[gpio].users = 0;
+ }
+
+ return;
+}
+EXPORT_SYMBOL(gpio_free);
+
+/* This returns zero or nonzero */
+int gpio_get_value(unsigned gpio)
+{
+ return readl(virtbase + U300_GPIO_PXPDIR +
+ PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07));
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+/*
+ * We hope that the compiler will optimize away the unused branch
+ * in case "value" is a constant
+ */
+void gpio_set_value(unsigned gpio, int value)
+{
+ u32 val;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (value) {
+ /* set */
+ val = readl(virtbase + U300_GPIO_PXPDOR +
+ PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
+ & (1 << (gpio & 0x07));
+ writel(val | (1 << (gpio & 0x07)), virtbase +
+ U300_GPIO_PXPDOR +
+ PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
+ } else {
+ /* clear */
+ val = readl(virtbase + U300_GPIO_PXPDOR +
+ PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
+ & (1 << (gpio & 0x07));
+ writel(val & ~(1 << (gpio & 0x07)), virtbase +
+ U300_GPIO_PXPDOR +
+ PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
+ }
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int gpio_direction_input(unsigned gpio)
+{
+ unsigned long flags;
+ u32 val;
+
+ if (gpio > U300_GPIO_MAX)
+ return -EINVAL;
+
+ local_irq_save(flags);
+ val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ /* Mask out this pin*/
+ val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
+ /* This is not needed since it sets the bits to zero.*/
+ /* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */
+ writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ local_irq_restore(flags);
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ unsigned long flags;
+ u32 val;
+
+ if (gpio > U300_GPIO_MAX)
+ return -EINVAL;
+
+ local_irq_save(flags);
+ val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ /* Mask out this pin */
+ val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
+ /*
+ * FIXME: configure for push/pull, open drain or open source per pin
+ * in setup. The current driver will only support push/pull.
+ */
+ val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
+ << ((gpio & 0x07) << 1));
+ writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ gpio_set_value(gpio, value);
+ local_irq_restore(flags);
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+/*
+ * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0).
+ */
+void enable_irq_on_gpio_pin(unsigned gpio, int edge)
+{
+ u32 val;
+ unsigned long flags;
+ local_irq_save(flags);
+
+ val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ val |= (1 << (gpio & 0x07));
+ writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ if (edge)
+ val |= (1 << (gpio & 0x07));
+ else
+ val &= ~(1 << (gpio & 0x07));
+ writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(enable_irq_on_gpio_pin);
+
+void disable_irq_on_gpio_pin(unsigned gpio)
+{
+ u32 val;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ val &= ~(1 << (gpio & 0x07));
+ writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(disable_irq_on_gpio_pin);
+
+/* Enable (value == 0) or disable (value == 1) internal pullup */
+void gpio_pullup(unsigned gpio, int value)
+{
+ u32 val;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (value) {
+ val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
+ PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
+ } else {
+ val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
+ U300_GPIO_PORTX_SPACING);
+ writel(val & ~(1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
+ PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
+ }
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_pullup);
+
+static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
+{
+ struct u300_gpio_port *port = dev_id;
+ u32 val;
+ int pin;
+
+ /* Read event register */
+ val = readl(virtbase + U300_GPIO_PXIEV + port->number *
+ U300_GPIO_PORTX_SPACING);
+ /* Mask with enable register */
+ val &= readl(virtbase + U300_GPIO_PXIEV + port->number *
+ U300_GPIO_PORTX_SPACING);
+ /* Mask relevant bits */
+ val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK;
+ /* ACK IRQ (clear event) */
+ writel(val, virtbase + U300_GPIO_PXIEV + port->number *
+ U300_GPIO_PORTX_SPACING);
+ /* Print message */
+ while (val != 0) {
+ unsigned gpio;
+
+ pin = __ffs(val);
+ /* mask off this pin */
+ val &= ~(1 << pin);
+ gpio = (port->number << 3) + pin;
+
+ if (gpio_pin[gpio].callback)
+ (void)gpio_pin[gpio].callback(gpio_pin[gpio].data);
+ else
+ printk(KERN_DEBUG "GPIO: Stray GPIO IRQ on line %d\n",
+ gpio);
+ }
+ return IRQ_HANDLED;
+}
+
+static void gpio_set_initial_values(void)
+{
+#ifdef U300_COH901571_3
+ int i, j;
+ unsigned long flags;
+ u32 val;
+
+ /* Write default values to all pins */
+ for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
+ val = 0;
+ for (j = 0; j < 8; j++)
+ val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j;
+ local_irq_save(flags);
+ writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING);
+ local_irq_restore(flags);
+ }
+
+ /*
+ * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED'
+ * to output and 'GPIO_IN' to input for each port. And initalize
+ * default value on outputs.
+ */
+ for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
+ for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) {
+ local_irq_save(flags);
+ val = readl(virtbase + U300_GPIO_PXPCR +
+ i * U300_GPIO_PORTX_SPACING);
+ /* Mask out this pin */
+ val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1));
+
+ if (u300_gpio_config[i][j].pin_usage != GPIO_IN)
+ val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1));
+ writel(val, virtbase + U300_GPIO_PXPCR +
+ i * U300_GPIO_PORTX_SPACING);
+ local_irq_restore(flags);
+ }
+ }
+
+ /* Enable or disable the internal pull-ups in the GPIO ASIC block */
+ for (i = 0; i < U300_GPIO_MAX; i++) {
+ val = 0;
+ for (j = 0; j < 8; j++)
+ val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP)) << j;
+ local_irq_save(flags);
+ writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
+ local_irq_restore(flags);
+ }
+#endif
+}
+
+static int __devinit gpio_probe(struct platform_device *pdev)
+{
+ u32 val;
+ int err = 0;
+ int i;
+ int num_irqs;
+
+ memset(gpio_pin, 0, sizeof(gpio_pin));
+
+ /* Get GPIO clock */
+ clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
+ err = PTR_ERR(clk);
+ printk(KERN_ERR "GPIO: could not get GPIO clock\n");
+ goto err_no_clk;
+ }
+ err = clk_enable(clk);
+ if (err) {
+ printk(KERN_ERR "GPIO: could not enable GPIO clock\n");
+ goto err_no_clk_enable;
+ }
+
+ memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!memres)
+ goto err_no_resource;
+
+ if (request_mem_region(memres->start, memres->end - memres->start, "GPIO Controller")
+ == NULL) {
+ err = -ENODEV;
+ goto err_no_ioregion;
+ }
+
+ virtbase = ioremap(memres->start, memres->end - memres->start + 1);
+ if (!virtbase) {
+ err = -ENOMEM;
+ goto err_no_ioremap;
+ }
+
+#ifdef U300_COH901335
+ printk(KERN_INFO "GPIO: Initializing GPIO Controller COH 901 335\n");
+ /* Turn on the GPIO block */
+ writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR);
+#endif
+
+#ifdef U300_COH901571_3
+ printk(KERN_INFO "GPIO: Initializing GPIO Controller COH 901 571/3\n");
+ val = readl(virtbase + U300_GPIO_CR);
+ printk(KERN_INFO "GPIO: COH901571/3 block version: %d, " \
+ "number of cores: %d\n",
+ ((val & 0x0000FE00) >> 9),
+ ((val & 0x000001FC) >> 2));
+ writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR);
+#endif
+
+ /* Set up some padmuxing here */
+#ifdef CONFIG_MMC
+ pmx_set_mission_mode_mmc();
+#endif
+#ifdef CONFIG_SPI_PL022
+ pmx_set_mission_mode_spi();
+#endif
+
+ gpio_set_initial_values();
+
+ for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) {
+
+ gpio_ports[num_irqs].irq =
+ platform_get_irq_byname(pdev,
+ gpio_ports[num_irqs].name);
+
+ err = request_irq(gpio_ports[num_irqs].irq,
+ gpio_irq_handler, IRQF_DISABLED,
+ gpio_ports[num_irqs].name,
+ &gpio_ports[num_irqs]);
+ if (err) {
+ printk(KERN_CRIT "GPIO: Cannot allocate IRQ for %s!\n",
+ gpio_ports[num_irqs].name);
+ goto err_no_irq;
+ }
+ /* Turns off PortX_irq_force */
+ writel(0x0, virtbase + U300_GPIO_PXIFR +
+ num_irqs * U300_GPIO_PORTX_SPACING);
+ }
+ printk(KERN_INFO "GPIO: U300 gpio module loaded\n");
+
+ return 0;
+
+ err_no_irq:
+ for (i = 0; i < num_irqs; i++)
+ free_irq(gpio_ports[i].irq, &gpio_ports[i]);
+ iounmap(virtbase);
+ err_no_ioremap:
+ release_mem_region(memres->start, memres->end - memres->start);
+ err_no_ioregion:
+ err_no_resource:
+ clk_disable(clk);
+ err_no_clk_enable:
+ clk_put(clk);
+ err_no_clk:
+ printk(KERN_INFO "GPIO: module ERROR:%d\n", err);
+ return err;
+}
+
+static int __devexit gpio_remove(struct platform_device *pdev)
+{
+ int i;
+
+ /* Turn off the GPIO block */
+ writel(0x00000000U, virtbase + U300_GPIO_CR);
+ for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++)
+ free_irq(gpio_ports[i].irq, &gpio_ports[i]);
+ iounmap(virtbase);
+ release_mem_region(memres->start, memres->end - memres->start);
+ clk_disable(clk);
+ clk_put(clk);
+ return 0;
+}
+
+static struct platform_driver gpio_driver = {
+ .driver = {
+ .name = "u300-gpio",
+ },
+ .probe = gpio_probe,
+ .remove = __devexit_p(gpio_remove),
+};
+
+
+static int __init u300_gpio_init(void)
+{
+ return platform_driver_register(&gpio_driver);
+}
+
+static void __exit u300_gpio_exit(void)
+{
+ platform_driver_unregister(&gpio_driver);
+}
+
+arch_initcall(u300_gpio_init);
+module_exit(u300_gpio_exit);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
+
+#ifdef U300_COH901571_3
+MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver");
+#endif
+
+#ifdef U300_COH901335
+MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver");
+#endif
+
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-u300/include/mach/clkdev.h b/arch/arm/mach-u300/include/mach/clkdev.h
new file mode 100644
index 000000000000..92e3cc872c66
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+int __clk_get(struct clk *clk);
+void __clk_put(struct clk *clk);
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/debug-macro.S b/arch/arm/mach-u300/include/mach/debug-macro.S
new file mode 100644
index 000000000000..f3a1cbbeeab3
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/debug-macro.S
@@ -0,0 +1,22 @@
+/*
+ *
+ * arch-arm/mach-u300/include/mach/debug-macro.S
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Debugging macro include header.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <mach/hardware.h>
+
+ .macro addruart,rx
+ /* If we move the adress using MMU, use this. */
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ ldreq \rx, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address
+ ldrne \rx, = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address
+ orr \rx, \rx, #0x00003000
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-u300/include/mach/entry-macro.S b/arch/arm/mach-u300/include/mach/entry-macro.S
new file mode 100644
index 000000000000..20731ae39d38
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/entry-macro.S
@@ -0,0 +1,40 @@
+/*
+ *
+ * arch-arm/mach-u300/include/mach/entry-macro.S
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Low-level IRQ helper macros for ST-Ericsson U300
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <mach/hardware.h>
+#include <asm/hardware/vic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON0_BASE
+ ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
+ mov \irqnr, #0
+ teq \irqstat, #0
+ bne 1002f
+1001: ldr \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON1_BASE
+ ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
+ mov \irqnr, #32
+ teq \irqstat, #0
+ beq 1003f
+1002: tst \irqstat, #1
+ bne 1003f
+ add \irqnr, \irqnr, #1
+ movs \irqstat, \irqstat, lsr #1
+ bne 1002b
+1003: /* EQ will be set if no irqs pending */
+ .endm
diff --git a/arch/arm/mach-u300/include/mach/gpio.h b/arch/arm/mach-u300/include/mach/gpio.h
new file mode 100644
index 000000000000..c8174128d7eb
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/gpio.h
@@ -0,0 +1,290 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/gpio.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * GPIO block resgister definitions and inline macros for
+ * U300 GPIO COH 901 335 or COH 901 571/3
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef __MACH_U300_GPIO_H
+#define __MACH_U300_GPIO_H
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+/* Switch type depending on platform/chip variant */
+#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
+#define U300_COH901335
+#endif
+#if defined(CONFIG_MACH_U300_BS365) || defined(CONFIG_MACH_U300_BS335)
+#define U300_COH901571_3
+#endif
+
+/* Get base address for regs here */
+#include "u300-regs.h"
+/* IRQ numbers */
+#include "irqs.h"
+
+/*
+ * This is the GPIO block definitions. GPIO (General Purpose I/O) can be
+ * used for anything, and often is. The event/enable etc figures are for
+ * the lowermost pin (pin 0 on each port), shift this left to match your
+ * pin if you're gonna use these values.
+ */
+#ifdef U300_COH901335
+#define U300_GPIO_PORTX_SPACING (0x1C)
+/* Port X Pin Data Register 32bit, this is both input and output (R/W) */
+#define U300_GPIO_PXPDIR (0x00)
+#define U300_GPIO_PXPDOR (0x00)
+/* Port X Pin Config Register 32bit (R/W) */
+#define U300_GPIO_PXPCR (0x04)
+#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL)
+#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL)
+#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL)
+/* Port X Interrupt Event Register 32bit (R/W) */
+#define U300_GPIO_PXIEV (0x08)
+#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK (0x000000FFUL)
+#define U300_GPIO_PXIEV_IRQ_EVENT (0x00000001UL)
+/* Port X Interrupt Enable Register 32bit (R/W) */
+#define U300_GPIO_PXIEN (0x0C)
+#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK (0x000000FFUL)
+#define U300_GPIO_PXIEN_IRQ_ENABLE (0x00000001UL)
+/* Port X Interrupt Force Register 32bit (R/W) */
+#define U300_GPIO_PXIFR (0x10)
+#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK (0x000000FFUL)
+#define U300_GPIO_PXIFR_IRQ_FORCE (0x00000001UL)
+/* Port X Interrupt Config Register 32bit (R/W) */
+#define U300_GPIO_PXICR (0x14)
+#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL)
+/* Port X Pull-up Enable Register 32bit (R/W) */
+#define U300_GPIO_PXPER (0x18)
+#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL)
+#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL)
+/* Control Register 32bit (R/W) */
+#define U300_GPIO_CR (0x54)
+#define U300_GPIO_CR_BLOCK_CLOCK_ENABLE (0x00000001UL)
+/* three ports of 8 bits each = GPIO pins 0..23 */
+#define U300_GPIO_NUM_PORTS 3
+#define U300_GPIO_PINS_PER_PORT 8
+#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
+#endif
+
+#ifdef U300_COH901571_3
+/*
+ * Control Register 32bit (R/W)
+ * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores
+ * gives the number of GPIO pins.
+ * bit 8-2 (mask 0x000001FC) contains the core version ID.
+ */
+#define U300_GPIO_CR (0x00)
+#define U300_GPIO_CR_SYNC_SEL_ENABLE (0x00000002UL)
+#define U300_GPIO_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL)
+#define U300_GPIO_PORTX_SPACING (0x30)
+/* Port X Pin Data INPUT Register 32bit (R/W) */
+#define U300_GPIO_PXPDIR (0x04)
+/* Port X Pin Data OUTPUT Register 32bit (R/W) */
+#define U300_GPIO_PXPDOR (0x08)
+/* Port X Pin Config Register 32bit (R/W) */
+#define U300_GPIO_PXPCR (0x0C)
+#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL)
+#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL)
+#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL)
+/* Port X Pull-up Enable Register 32bit (R/W) */
+#define U300_GPIO_PXPER (0x10)
+#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL)
+#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL)
+/* Port X Interrupt Event Register 32bit (R/W) */
+#define U300_GPIO_PXIEV (0x14)
+#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK (0x000000FFUL)
+#define U300_GPIO_PXIEV_IRQ_EVENT (0x00000001UL)
+/* Port X Interrupt Enable Register 32bit (R/W) */
+#define U300_GPIO_PXIEN (0x18)
+#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK (0x000000FFUL)
+#define U300_GPIO_PXIEN_IRQ_ENABLE (0x00000001UL)
+/* Port X Interrupt Force Register 32bit (R/W) */
+#define U300_GPIO_PXIFR (0x1C)
+#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK (0x000000FFUL)
+#define U300_GPIO_PXIFR_IRQ_FORCE (0x00000001UL)
+/* Port X Interrupt Config Register 32bit (R/W) */
+#define U300_GPIO_PXICR (0x20)
+#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL)
+#ifdef CONFIG_MACH_U300_BS335
+/* seven ports of 8 bits each = GPIO pins 0..55 */
+#define U300_GPIO_NUM_PORTS 7
+#else
+/* five ports of 8 bits each = GPIO pins 0..39 */
+#define U300_GPIO_NUM_PORTS 5
+#endif
+#define U300_GPIO_PINS_PER_PORT 8
+#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
+#endif
+
+/*
+ * Individual pin assignments for the B26/S26. Notice that the
+ * actual usage of these pins depends on the PAD MUX settings, that
+ * is why the same number can potentially appear several times.
+ * In the reference design each pin is only used for one purpose.
+ * These were determined by inspecting the B26/S26 schematic:
+ * 2/1911-ROA 128 1603
+ */
+#ifdef CONFIG_MACH_U300_BS2X
+#define U300_GPIO_PIN_UART_RX 0
+#define U300_GPIO_PIN_UART_TX 1
+#define U300_GPIO_PIN_GPIO02 2 /* Unrouted */
+#define U300_GPIO_PIN_GPIO03 3 /* Unrouted */
+#define U300_GPIO_PIN_CAM_SLEEP 4
+#define U300_GPIO_PIN_CAM_REG_EN 5
+#define U300_GPIO_PIN_GPIO06 6 /* Unrouted */
+#define U300_GPIO_PIN_GPIO07 7 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO08 8 /* Service point SP2321 */
+#define U300_GPIO_PIN_GPIO09 9 /* Service point SP2322 */
+#define U300_GPIO_PIN_PHFSENSE 10 /* Headphone jack sensing */
+#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
+#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
+#define U300_GPIO_PIN_FLIPSENSE 13 /* Mechanical flip sensing */
+#define U300_GPIO_PIN_GPIO14 14 /* DSP JTAG Port RTCK */
+#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO16 16 /* Unrouted */
+#define U300_GPIO_PIN_GPIO17 17 /* Unrouted */
+#define U300_GPIO_PIN_GPIO18 18 /* Unrouted */
+#define U300_GPIO_PIN_GPIO19 19 /* Unrouted */
+#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
+#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
+#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
+#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
+#endif
+
+/*
+ * Individual pin assignments for the B330/S330 and B365/S365.
+ * Notice that the actual usage of these pins depends on the
+ * PAD MUX settings, that is why the same number can potentially
+ * appear several times. In the reference design each pin is only
+ * used for one purpose. These were determined by inspecting the
+ * S365 schematic.
+ */
+#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
+ defined(CONFIG_MACH_U300_BS335)
+#define U300_GPIO_PIN_UART_RX 0
+#define U300_GPIO_PIN_UART_TX 1
+#define U300_GPIO_PIN_UART_CTS 2
+#define U300_GPIO_PIN_UART_RTS 3
+#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
+#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */
+#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */
+#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */
+
+#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */
+#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */
+#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */
+#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
+#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
+#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */
+#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */
+#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */
+#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */
+#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */
+#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */
+#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
+#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
+#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
+#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */
+#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */
+#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */
+#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */
+#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */
+#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */
+#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */
+#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */
+#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */
+#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */
+#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */
+#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */
+#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */
+#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */
+#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */
+
+#ifdef CONFIG_MACH_U300_BS335
+
+#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */
+#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */
+#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */
+#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */
+#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */
+#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */
+#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */
+#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */
+#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */
+#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */
+#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */
+#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */
+#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */
+#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */
+#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */
+#endif
+
+#endif
+
+/* translates a pin number to a port number */
+#define PIN_TO_PORT(val) (val >> 3)
+
+/* These can be found in arch/arm/mach-u300/gpio.c */
+extern int gpio_request(unsigned gpio, const char *label);
+extern void gpio_free(unsigned gpio);
+extern int gpio_direction_input(unsigned gpio);
+extern int gpio_direction_output(unsigned gpio, int value);
+extern int gpio_register_callback(unsigned gpio,
+ int (*func)(void *arg),
+ void *);
+extern int gpio_unregister_callback(unsigned gpio);
+extern void enable_irq_on_gpio_pin(unsigned gpio, int edge);
+extern void disable_irq_on_gpio_pin(unsigned gpio);
+extern void gpio_pullup(unsigned gpio, int value);
+extern int gpio_get_value(unsigned gpio);
+extern void gpio_set_value(unsigned gpio, int value);
+
+/* wrappers to sleep-enable the previous two functions */
+static inline unsigned gpio_to_irq(unsigned gpio)
+{
+ return PIN_TO_PORT(gpio) + IRQ_U300_GPIO_PORT0;
+}
+
+static inline unsigned irq_to_gpio(unsigned irq)
+{
+ /*
+ * FIXME: This is no 1-1 mapping at all, it points to the
+ * whole block of 8 pins.
+ */
+ return (irq - IRQ_U300_GPIO_PORT0) << 3;
+}
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/hardware.h b/arch/arm/mach-u300/include/mach/hardware.h
new file mode 100644
index 000000000000..b99d4ce0ac2b
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/hardware.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-u300/include/mach/hardware.h
+ */
+#include <asm/sizes.h>
+#include <mach/u300-regs.h>
diff --git a/arch/arm/mach-u300/include/mach/io.h b/arch/arm/mach-u300/include/mach/io.h
new file mode 100644
index 000000000000..5d6b4c13b3a0
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/io.h
@@ -0,0 +1,20 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/io.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Dummy IO map for being able to use writew()/readw(),
+ * writel()/readw() and similar accessor functions.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h
new file mode 100644
index 000000000000..a6867b12773e
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/irqs.h
@@ -0,0 +1,114 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/irqs.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * IRQ channel definitions for the U300 platforms.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+#define IRQ_U300_INTCON0_START 0
+#define IRQ_U300_INTCON1_START 32
+/* These are on INTCON0 - 30 lines */
+#define IRQ_U300_IRQ0_EXT 0
+#define IRQ_U300_IRQ1_EXT 1
+#define IRQ_U300_DMA 2
+#define IRQ_U300_VIDEO_ENC_0 3
+#define IRQ_U300_VIDEO_ENC_1 4
+#define IRQ_U300_AAIF_RX 5
+#define IRQ_U300_AAIF_TX 6
+#define IRQ_U300_AAIF_VGPIO 7
+#define IRQ_U300_AAIF_WAKEUP 8
+#define IRQ_U300_PCM_I2S0_FRAME 9
+#define IRQ_U300_PCM_I2S0_FIFO 10
+#define IRQ_U300_PCM_I2S1_FRAME 11
+#define IRQ_U300_PCM_I2S1_FIFO 12
+#define IRQ_U300_XGAM_GAMCON 13
+#define IRQ_U300_XGAM_CDI 14
+#define IRQ_U300_XGAM_CDICON 15
+#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
+/* MMIACC not used on the DB3210 or DB3350 chips */
+#define IRQ_U300_XGAM_MMIACC 16
+#endif
+#define IRQ_U300_XGAM_PDI 17
+#define IRQ_U300_XGAM_PDICON 18
+#define IRQ_U300_XGAM_GAMEACC 19
+#define IRQ_U300_XGAM_MCIDCT 20
+#define IRQ_U300_APEX 21
+#define IRQ_U300_UART0 22
+#define IRQ_U300_SPI 23
+#define IRQ_U300_TIMER_APP_OS 24
+#define IRQ_U300_TIMER_APP_DD 25
+#define IRQ_U300_TIMER_APP_GP1 26
+#define IRQ_U300_TIMER_APP_GP2 27
+#define IRQ_U300_TIMER_OS 28
+#define IRQ_U300_TIMER_MS 29
+#define IRQ_U300_KEYPAD_KEYBF 30
+#define IRQ_U300_KEYPAD_KEYBR 31
+/* These are on INTCON1 - 32 lines */
+#define IRQ_U300_GPIO_PORT0 32
+#define IRQ_U300_GPIO_PORT1 33
+#define IRQ_U300_GPIO_PORT2 34
+
+#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) || \
+ defined(CONFIG_MACH_U300_BS335)
+/* These are for DB3150, DB3200 and DB3350 */
+#define IRQ_U300_WDOG 35
+#define IRQ_U300_EVHIST 36
+#define IRQ_U300_MSPRO 37
+#define IRQ_U300_MMCSD_MCIINTR0 38
+#define IRQ_U300_MMCSD_MCIINTR1 39
+#define IRQ_U300_I2C0 40
+#define IRQ_U300_I2C1 41
+#define IRQ_U300_RTC 42
+#define IRQ_U300_NFIF 43
+#define IRQ_U300_NFIF2 44
+#endif
+
+/* DB3150 and DB3200 have only 45 IRQs */
+#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
+#define U300_NR_IRQS 45
+#endif
+
+/* The DB3350-specific interrupt lines */
+#ifdef CONFIG_MACH_U300_BS335
+#define IRQ_U300_ISP_F0 45
+#define IRQ_U300_ISP_F1 46
+#define IRQ_U300_ISP_F2 47
+#define IRQ_U300_ISP_F3 48
+#define IRQ_U300_ISP_F4 49
+#define IRQ_U300_GPIO_PORT3 50
+#define IRQ_U300_SYSCON_PLL_LOCK 51
+#define IRQ_U300_UART1 52
+#define IRQ_U300_GPIO_PORT4 53
+#define IRQ_U300_GPIO_PORT5 54
+#define IRQ_U300_GPIO_PORT6 55
+#define U300_NR_IRQS 56
+#endif
+
+/* The DB3210-specific interrupt lines */
+#ifdef CONFIG_MACH_U300_BS365
+#define IRQ_U300_GPIO_PORT3 35
+#define IRQ_U300_GPIO_PORT4 36
+#define IRQ_U300_WDOG 37
+#define IRQ_U300_EVHIST 38
+#define IRQ_U300_MSPRO 39
+#define IRQ_U300_MMCSD_MCIINTR0 40
+#define IRQ_U300_MMCSD_MCIINTR1 41
+#define IRQ_U300_I2C0 42
+#define IRQ_U300_I2C1 43
+#define IRQ_U300_RTC 44
+#define IRQ_U300_NFIF 45
+#define IRQ_U300_NFIF2 46
+#define IRQ_U300_SYSCON_PLL_LOCK 47
+#define U300_NR_IRQS 48
+#endif
+
+#define NR_IRQS U300_NR_IRQS
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h
new file mode 100644
index 000000000000..bf134bcc129d
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/memory.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/memory.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Memory virtual/physical mapping constants.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ */
+
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#ifdef CONFIG_MACH_U300_DUAL_RAM
+
+#define PHYS_OFFSET UL(0x48000000)
+#define BOOT_PARAMS_OFFSET (PHYS_OFFSET + 0x100)
+
+#else
+
+#ifdef CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+#define PHYS_OFFSET (0x28000000 + \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE - \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024)
+#else
+#define PHYS_OFFSET (0x28000000 + \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE + \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024)
+#endif
+#define BOOT_PARAMS_OFFSET (0x28000000 + \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE + \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024 + 0x100)
+#endif
+
+/*
+ * We enable a real big DMA buffer if need be.
+ */
+#define CONSISTENT_DMA_SIZE SZ_4M
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/platform.h b/arch/arm/mach-u300/include/mach/platform.h
new file mode 100644
index 000000000000..77d9210a82e2
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/platform.h
@@ -0,0 +1,19 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/platform.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Basic platform init and mapping functions.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef __ASSEMBLY__
+
+void u300_map_io(void);
+void u300_init_irq(void);
+void u300_init_devices(void);
+extern struct sys_timer u300_timer;
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/syscon.h b/arch/arm/mach-u300/include/mach/syscon.h
new file mode 100644
index 000000000000..1c90d1b1ccb6
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/syscon.h
@@ -0,0 +1,644 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/syscon.h
+ *
+ *
+ * Copyright (C) 2008 ST-Ericsson AB
+ *
+ * Author: Rickard Andersson <rickard.andersson@stericsson.com>
+ */
+
+#ifndef __MACH_SYSCON_H
+#define __MACH_SYSCON_H
+
+/*
+ * All register defines for SYSCON registers that concerns individual
+ * block clocks and reset lines are registered here. This is because
+ * we don't want any other file to try to fool around with this stuff.
+ */
+
+/* APP side SYSCON registers */
+/* TODO: this is incomplete. Add all from asic_syscon_map.h eventually. */
+/* CLK Control Register 16bit (R/W) */
+#define U300_SYSCON_CCR (0x0000)
+#define U300_SYSCON_CCR_I2S1_USE_VCXO (0x0040)
+#define U300_SYSCON_CCR_I2S0_USE_VCXO (0x0020)
+#define U300_SYSCON_CCR_TURN_VCXO_ON (0x0008)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK (0x0007)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER (0x04)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW (0x03)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE (0x02)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH (0x01)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST (0x00)
+/* CLK Status Register 16bit (R/W) */
+#define U300_SYSCON_CSR (0x0004)
+#define U300_SYSCON_CSR_PLL208_LOCK_IND (0x0002)
+#define U300_SYSCON_CSR_PLL13_LOCK_IND (0x0001)
+/* Reset lines for SLOW devices 16bit (R/W) */
+#define U300_SYSCON_RSR (0x0014)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_RSR_PPM_RESET_EN (0x0200)
+#endif
+#define U300_SYSCON_RSR_ACC_TMR_RESET_EN (0x0100)
+#define U300_SYSCON_RSR_APP_TMR_RESET_EN (0x0080)
+#define U300_SYSCON_RSR_RTC_RESET_EN (0x0040)
+#define U300_SYSCON_RSR_KEYPAD_RESET_EN (0x0020)
+#define U300_SYSCON_RSR_GPIO_RESET_EN (0x0010)
+#define U300_SYSCON_RSR_EH_RESET_EN (0x0008)
+#define U300_SYSCON_RSR_BTR_RESET_EN (0x0004)
+#define U300_SYSCON_RSR_UART_RESET_EN (0x0002)
+#define U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN (0x0001)
+/* Reset lines for FAST devices 16bit (R/W) */
+#define U300_SYSCON_RFR (0x0018)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_RFR_UART1_RESET_ENABLE (0x0080)
+#endif
+#define U300_SYSCON_RFR_SPI_RESET_ENABLE (0x0040)
+#define U300_SYSCON_RFR_MMC_RESET_ENABLE (0x0020)
+#define U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE (0x0010)
+#define U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE (0x0008)
+#define U300_SYSCON_RFR_I2C1_RESET_ENABLE (0x0004)
+#define U300_SYSCON_RFR_I2C0_RESET_ENABLE (0x0002)
+#define U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE (0x0001)
+/* Reset lines for the rest of the peripherals 16bit (R/W) */
+#define U300_SYSCON_RRR (0x001c)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_RRR_CDS_RESET_EN (0x4000)
+#define U300_SYSCON_RRR_ISP_RESET_EN (0x2000)
+#endif
+#define U300_SYSCON_RRR_INTCON_RESET_EN (0x1000)
+#define U300_SYSCON_RRR_MSPRO_RESET_EN (0x0800)
+#define U300_SYSCON_RRR_XGAM_RESET_EN (0x0100)
+#define U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN (0x0080)
+#define U300_SYSCON_RRR_NANDIF_RESET_EN (0x0040)
+#define U300_SYSCON_RRR_EMIF_RESET_EN (0x0020)
+#define U300_SYSCON_RRR_DMAC_RESET_EN (0x0010)
+#define U300_SYSCON_RRR_CPU_RESET_EN (0x0008)
+#define U300_SYSCON_RRR_APEX_RESET_EN (0x0004)
+#define U300_SYSCON_RRR_AHB_RESET_EN (0x0002)
+#define U300_SYSCON_RRR_AAIF_RESET_EN (0x0001)
+/* Clock enable for SLOW peripherals 16bit (R/W) */
+#define U300_SYSCON_CESR (0x0020)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_CESR_PPM_CLK_EN (0x0200)
+#endif
+#define U300_SYSCON_CESR_ACC_TMR_CLK_EN (0x0100)
+#define U300_SYSCON_CESR_APP_TMR_CLK_EN (0x0080)
+#define U300_SYSCON_CESR_KEYPAD_CLK_EN (0x0040)
+#define U300_SYSCON_CESR_GPIO_CLK_EN (0x0010)
+#define U300_SYSCON_CESR_EH_CLK_EN (0x0008)
+#define U300_SYSCON_CESR_BTR_CLK_EN (0x0004)
+#define U300_SYSCON_CESR_UART_CLK_EN (0x0002)
+#define U300_SYSCON_CESR_SLOW_BRIDGE_CLK_EN (0x0001)
+/* Clock enable for FAST peripherals 16bit (R/W) */
+#define U300_SYSCON_CEFR (0x0024)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_CEFR_UART1_CLK_EN (0x0200)
+#endif
+#define U300_SYSCON_CEFR_I2S1_CORE_CLK_EN (0x0100)
+#define U300_SYSCON_CEFR_I2S0_CORE_CLK_EN (0x0080)
+#define U300_SYSCON_CEFR_SPI_CLK_EN (0x0040)
+#define U300_SYSCON_CEFR_MMC_CLK_EN (0x0020)
+#define U300_SYSCON_CEFR_I2S1_CLK_EN (0x0010)
+#define U300_SYSCON_CEFR_I2S0_CLK_EN (0x0008)
+#define U300_SYSCON_CEFR_I2C1_CLK_EN (0x0004)
+#define U300_SYSCON_CEFR_I2C0_CLK_EN (0x0002)
+#define U300_SYSCON_CEFR_FAST_BRIDGE_CLK_EN (0x0001)
+/* Clock enable for the rest of the peripherals 16bit (R/W) */
+#define U300_SYSCON_CERR (0x0028)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_CERR_CDS_CLK_EN (0x2000)
+#define U300_SYSCON_CERR_ISP_CLK_EN (0x1000)
+#endif
+#define U300_SYSCON_CERR_MSPRO_CLK_EN (0x0800)
+#define U300_SYSCON_CERR_AHB_SUBSYS_BRIDGE_CLK_EN (0x0400)
+#define U300_SYSCON_CERR_SEMI_CLK_EN (0x0200)
+#define U300_SYSCON_CERR_XGAM_CLK_EN (0x0100)
+#define U300_SYSCON_CERR_VIDEO_ENC_CLK_EN (0x0080)
+#define U300_SYSCON_CERR_NANDIF_CLK_EN (0x0040)
+#define U300_SYSCON_CERR_EMIF_CLK_EN (0x0020)
+#define U300_SYSCON_CERR_DMAC_CLK_EN (0x0010)
+#define U300_SYSCON_CERR_CPU_CLK_EN (0x0008)
+#define U300_SYSCON_CERR_APEX_CLK_EN (0x0004)
+#define U300_SYSCON_CERR_AHB_CLK_EN (0x0002)
+#define U300_SYSCON_CERR_AAIF_CLK_EN (0x0001)
+/* Single block clock enable 16bit (-/W) */
+#define U300_SYSCON_SBCER (0x002c)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_SBCER_PPM_CLK_EN (0x0009)
+#endif
+#define U300_SYSCON_SBCER_ACC_TMR_CLK_EN (0x0008)
+#define U300_SYSCON_SBCER_APP_TMR_CLK_EN (0x0007)
+#define U300_SYSCON_SBCER_KEYPAD_CLK_EN (0x0006)
+#define U300_SYSCON_SBCER_GPIO_CLK_EN (0x0004)
+#define U300_SYSCON_SBCER_EH_CLK_EN (0x0003)
+#define U300_SYSCON_SBCER_BTR_CLK_EN (0x0002)
+#define U300_SYSCON_SBCER_UART_CLK_EN (0x0001)
+#define U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN (0x0000)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_SBCER_UART1_CLK_EN (0x0019)
+#endif
+#define U300_SYSCON_SBCER_I2S1_CORE_CLK_EN (0x0018)
+#define U300_SYSCON_SBCER_I2S0_CORE_CLK_EN (0x0017)
+#define U300_SYSCON_SBCER_SPI_CLK_EN (0x0016)
+#define U300_SYSCON_SBCER_MMC_CLK_EN (0x0015)
+#define U300_SYSCON_SBCER_I2S1_CLK_EN (0x0014)
+#define U300_SYSCON_SBCER_I2S0_CLK_EN (0x0013)
+#define U300_SYSCON_SBCER_I2C1_CLK_EN (0x0012)
+#define U300_SYSCON_SBCER_I2C0_CLK_EN (0x0011)
+#define U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN (0x0010)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_SBCER_CDS_CLK_EN (0x002D)
+#define U300_SYSCON_SBCER_ISP_CLK_EN (0x002C)
+#endif
+#define U300_SYSCON_SBCER_MSPRO_CLK_EN (0x002B)
+#define U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN (0x002A)
+#define U300_SYSCON_SBCER_SEMI_CLK_EN (0x0029)
+#define U300_SYSCON_SBCER_XGAM_CLK_EN (0x0028)
+#define U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN (0x0027)
+#define U300_SYSCON_SBCER_NANDIF_CLK_EN (0x0026)
+#define U300_SYSCON_SBCER_EMIF_CLK_EN (0x0025)
+#define U300_SYSCON_SBCER_DMAC_CLK_EN (0x0024)
+#define U300_SYSCON_SBCER_CPU_CLK_EN (0x0023)
+#define U300_SYSCON_SBCER_APEX_CLK_EN (0x0022)
+#define U300_SYSCON_SBCER_AHB_CLK_EN (0x0021)
+#define U300_SYSCON_SBCER_AAIF_CLK_EN (0x0020)
+/* Single block clock disable 16bit (-/W) */
+#define U300_SYSCON_SBCDR (0x0030)
+/* Same values as above for SBCER */
+/* Clock force SLOW peripherals 16bit (R/W) */
+#define U300_SYSCON_CFSR (0x003c)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_CFSR_PPM_CLK_FORCE_EN (0x0200)
+#endif
+#define U300_SYSCON_CFSR_ACC_TMR_CLK_FORCE_EN (0x0100)
+#define U300_SYSCON_CFSR_APP_TMR_CLK_FORCE_EN (0x0080)
+#define U300_SYSCON_CFSR_KEYPAD_CLK_FORCE_EN (0x0020)
+#define U300_SYSCON_CFSR_GPIO_CLK_FORCE_EN (0x0010)
+#define U300_SYSCON_CFSR_EH_CLK_FORCE_EN (0x0008)
+#define U300_SYSCON_CFSR_BTR_CLK_FORCE_EN (0x0004)
+#define U300_SYSCON_CFSR_UART_CLK_FORCE_EN (0x0002)
+#define U300_SYSCON_CFSR_SLOW_BRIDGE_CLK_FORCE_EN (0x0001)
+/* Clock force FAST peripherals 16bit (R/W) */
+#define U300_SYSCON_CFFR (0x40)
+/* Values not defined. Define if you want to use them. */
+/* Clock force the rest of the peripherals 16bit (R/W) */
+#define U300_SYSCON_CFRR (0x44)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_CFRR_CDS_CLK_FORCE_EN (0x2000)
+#define U300_SYSCON_CFRR_ISP_CLK_FORCE_EN (0x1000)
+#endif
+#define U300_SYSCON_CFRR_MSPRO_CLK_FORCE_EN (0x0800)
+#define U300_SYSCON_CFRR_AHB_SUBSYS_BRIDGE_CLK_FORCE_EN (0x0400)
+#define U300_SYSCON_CFRR_SEMI_CLK_FORCE_EN (0x0200)
+#define U300_SYSCON_CFRR_XGAM_CLK_FORCE_EN (0x0100)
+#define U300_SYSCON_CFRR_VIDEO_ENC_CLK_FORCE_EN (0x0080)
+#define U300_SYSCON_CFRR_NANDIF_CLK_FORCE_EN (0x0040)
+#define U300_SYSCON_CFRR_EMIF_CLK_FORCE_EN (0x0020)
+#define U300_SYSCON_CFRR_DMAC_CLK_FORCE_EN (0x0010)
+#define U300_SYSCON_CFRR_CPU_CLK_FORCE_EN (0x0008)
+#define U300_SYSCON_CFRR_APEX_CLK_FORCE_EN (0x0004)
+#define U300_SYSCON_CFRR_AHB_CLK_FORCE_EN (0x0002)
+#define U300_SYSCON_CFRR_AAIF_CLK_FORCE_EN (0x0001)
+/* PLL208 Frequency Control 16bit (R/W) */
+#define U300_SYSCON_PFCR (0x48)
+#define U300_SYSCON_PFCR_DPLL_MULT_NUM (0x000F)
+/* Power Management Control 16bit (R/W) */
+#define U300_SYSCON_PMCR (0x50)
+#define U300_SYSCON_PMCR_DCON_ENABLE (0x0002)
+#define U300_SYSCON_PMCR_PWR_MGNT_ENABLE (0x0001)
+/*
+ * All other clocking registers moved to clock.c!
+ */
+/* Reset Out 16bit (R/W) */
+#define U300_SYSCON_RCR (0x6c)
+#define U300_SYSCON_RCR_RESOUT0_RST_N_DISABLE (0x0001)
+/* EMIF Slew Rate Control 16bit (R/W) */
+#define U300_SYSCON_SRCLR (0x70)
+#define U300_SYSCON_SRCLR_MASK (0x03FF)
+#define U300_SYSCON_SRCLR_VALUE (0x03FF)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_B (0x0200)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_A (0x0100)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_B (0x0080)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_A (0x0040)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_B (0x0020)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_A (0x0010)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_B (0x0008)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_A (0x0004)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_B (0x0002)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_A (0x0001)
+/* EMIF Clock Control Register 16bit (R/W) */
+#define U300_SYSCON_ECCR (0x0078)
+#define U300_SYSCON_ECCR_MASK (0x000F)
+#define U300_SYSCON_ECCR_EMIF_1_STATIC_CLK_EN_N_DISABLE (0x0008)
+#define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE (0x0004)
+#define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE (0x0002)
+#define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE (0x0001)
+/* PAD MUX Control register 1 (LOW) 16bit (R/W) */
+#define U300_SYSCON_PMC1LR (0x007C)
+#define U300_SYSCON_PMC1LR_MASK (0xFFFF)
+#define U300_SYSCON_PMC1LR_CDI_MASK (0xC000)
+#define U300_SYSCON_PMC1LR_CDI_CDI (0x0000)
+#define U300_SYSCON_PMC1LR_CDI_EMIF (0x4000)
+#define U300_SYSCON_PMC1LR_CDI_GPIO (0x8000)
+#define U300_SYSCON_PMC1LR_CDI_WCDMA (0xC000)
+#define U300_SYSCON_PMC1LR_PDI_MASK (0x3000)
+#define U300_SYSCON_PMC1LR_PDI_PDI (0x0000)
+#define U300_SYSCON_PMC1LR_PDI_EGG (0x1000)
+#define U300_SYSCON_PMC1LR_PDI_WCDMA (0x3000)
+#define U300_SYSCON_PMC1LR_MMCSD_MASK (0x0C00)
+#define U300_SYSCON_PMC1LR_MMCSD_MMCSD (0x0000)
+#define U300_SYSCON_PMC1LR_MMCSD_MSPRO (0x0400)
+#define U300_SYSCON_PMC1LR_MMCSD_DSP (0x0800)
+#define U300_SYSCON_PMC1LR_MMCSD_WCDMA (0x0C00)
+#define U300_SYSCON_PMC1LR_ETM_MASK (0x0300)
+#define U300_SYSCON_PMC1LR_ETM_ACC (0x0000)
+#define U300_SYSCON_PMC1LR_ETM_APP (0x0100)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK (0x00C0)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC (0x0000)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS2_NFIF (0x0040)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM (0x0080)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC_2GB (0x00C0)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK (0x0030)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC (0x0000)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS1_NFIF (0x0010)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SDRAM (0x0020)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SEMI (0x0030)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK (0x000C)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS0_STATIC (0x0000)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF (0x0004)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SDRAM (0x0008)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SEMI (0x000C)
+#define U300_SYSCON_PMC1LR_EMIF_1_MASK (0x0003)
+#define U300_SYSCON_PMC1LR_EMIF_1_STATIC (0x0000)
+#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 (0x0001)
+#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM1 (0x0002)
+#define U300_SYSCON_PMC1LR_EMIF_1 (0x0003)
+/* PAD MUX Control register 2 (HIGH) 16bit (R/W) */
+#define U300_SYSCON_PMC1HR (0x007E)
+#define U300_SYSCON_PMC1HR_MASK (0xFFFF)
+#define U300_SYSCON_PMC1HR_MISC_2_MASK (0xC000)
+#define U300_SYSCON_PMC1HR_MISC_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_MISC_2_MSPRO (0x4000)
+#define U300_SYSCON_PMC1HR_MISC_2_DSP (0x8000)
+#define U300_SYSCON_PMC1HR_MISC_2_AAIF (0xC000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_2_MASK (0x3000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_2_NFIF (0x1000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_2_DSP (0x2000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_2_AAIF (0x3000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_1_MASK (0x0C00)
+#define U300_SYSCON_PMC1HR_APP_GPIO_1_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_1_MMC (0x0400)
+#define U300_SYSCON_PMC1HR_APP_GPIO_1_DSP (0x0800)
+#define U300_SYSCON_PMC1HR_APP_GPIO_1_AAIF (0x0C00)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK (0x0300)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI (0x0100)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_AAIF (0x0300)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK (0x00C0)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI (0x0040)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_AAIF (0x00C0)
+#define U300_SYSCON_PMC1HR_APP_SPI_2_MASK (0x0030)
+#define U300_SYSCON_PMC1HR_APP_SPI_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_SPI_2_SPI (0x0010)
+#define U300_SYSCON_PMC1HR_APP_SPI_2_DSP (0x0020)
+#define U300_SYSCON_PMC1HR_APP_SPI_2_AAIF (0x0030)
+#define U300_SYSCON_PMC1HR_APP_UART0_2_MASK (0x000C)
+#define U300_SYSCON_PMC1HR_APP_UART0_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_UART0_2_UART0 (0x0004)
+#define U300_SYSCON_PMC1HR_APP_UART0_2_NFIF_CS (0x0008)
+#define U300_SYSCON_PMC1HR_APP_UART0_2_AAIF (0x000C)
+#define U300_SYSCON_PMC1HR_APP_UART0_1_MASK (0x0003)
+#define U300_SYSCON_PMC1HR_APP_UART0_1_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_UART0_1_UART0 (0x0001)
+#define U300_SYSCON_PMC1HR_APP_UART0_1_AAIF (0x0003)
+/* Step one for killing the applications system 16bit (-/W) */
+#define U300_SYSCON_KA1R (0x0080)
+#define U300_SYSCON_KA1R_MASK (0xFFFF)
+#define U300_SYSCON_KA1R_VALUE (0xFFFF)
+/* Step two for killing the application system 16bit (-/W) */
+#define U300_SYSCON_KA2R (0x0084)
+#define U300_SYSCON_KA2R_MASK (0xFFFF)
+#define U300_SYSCON_KA2R_VALUE (0xFFFF)
+/* MMC/MSPRO frequency divider register 0 16bit (R/W) */
+#define U300_SYSCON_MMF0R (0x90)
+#define U300_SYSCON_MMF0R_MASK (0x00FF)
+#define U300_SYSCON_MMF0R_FREQ_0_HIGH_MASK (0x00F0)
+#define U300_SYSCON_MMF0R_FREQ_0_LOW_MASK (0x000F)
+/* MMC/MSPRO frequency divider register 1 16bit (R/W) */
+#define U300_SYSCON_MMF1R (0x94)
+#define U300_SYSCON_MMF1R_MASK (0x00FF)
+#define U300_SYSCON_MMF1R_FREQ_1_HIGH_MASK (0x00F0)
+#define U300_SYSCON_MMF1R_FREQ_1_LOW_MASK (0x000F)
+/* AAIF control register 16 bit (R/W) */
+#define U300_SYSCON_AAIFCR (0x98)
+#define U300_SYSCON_AAIFCR_MASK (0x0003)
+#define U300_SYSCON_AAIFCR_AASW_CTRL_MASK (0x0003)
+#define U300_SYSCON_AAIFCR_AASW_CTRL_FUNCTIONAL (0x0000)
+#define U300_SYSCON_AAIFCR_AASW_CTRL_MONITORING (0x0001)
+#define U300_SYSCON_AAIFCR_AASW_CTRL_ACC_TO_EXT (0x0002)
+#define U300_SYSCON_AAIFCR_AASW_CTRL_APP_TO_EXT (0x0003)
+/* Clock control for the MMC and MSPRO blocks 16bit (R/W) */
+#define U300_SYSCON_MMCR (0x9C)
+#define U300_SYSCON_MMCR_MASK (0x0003)
+#define U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE (0x0002)
+#define U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE (0x0001)
+
+/* TODO: More SYSCON registers missing */
+#define U300_SYSCON_PMC3R (0x10c)
+#define U300_SYSCON_PMC3R_APP_MISC_11_MASK (0xc000)
+#define U300_SYSCON_PMC3R_APP_MISC_11_SPI (0x4000)
+#define U300_SYSCON_PMC3R_APP_MISC_10_MASK (0x3000)
+#define U300_SYSCON_PMC3R_APP_MISC_10_SPI (0x1000)
+/* TODO: Missing other configs, I just added the SPI stuff */
+
+/* SYS_0_CLK_CONTROL first clock control 16bit (R/W) */
+#define U300_SYSCON_S0CCR (0x120)
+#define U300_SYSCON_S0CCR_FIELD_MASK (0x43FF)
+#define U300_SYSCON_S0CCR_CLOCK_REQ (0x4000)
+#define U300_SYSCON_S0CCR_CLOCK_INV (0x0200)
+#define U300_SYSCON_S0CCR_CLOCK_FREQ_MASK (0x01E0)
+#define U300_SYSCON_S0CCR_CLOCK_SELECT_MASK (0x001E)
+#define U300_SYSCON_S0CCR_CLOCK_ENABLE (0x0001)
+#define U300_SYSCON_S0CCR_SEL_MCLK (0x8<<1)
+#define U300_SYSCON_S0CCR_SEL_ACC_FSM_CLK (0xA<<1)
+#define U300_SYSCON_S0CCR_SEL_PLL60_48_CLK (0xC<<1)
+#define U300_SYSCON_S0CCR_SEL_PLL60_60_CLK (0xD<<1)
+#define U300_SYSCON_S0CCR_SEL_ACC_PLL208_CLK (0xE<<1)
+#define U300_SYSCON_S0CCR_SEL_APP_PLL13_CLK (0x0<<1)
+#define U300_SYSCON_S0CCR_SEL_APP_FSM_CLK (0x2<<1)
+#define U300_SYSCON_S0CCR_SEL_RTC_CLK (0x4<<1)
+#define U300_SYSCON_S0CCR_SEL_APP_PLL208_CLK (0x6<<1)
+/* SYS_1_CLK_CONTROL second clock control 16 bit (R/W) */
+#define U300_SYSCON_S1CCR (0x124)
+#define U300_SYSCON_S1CCR_FIELD_MASK (0x43FF)
+#define U300_SYSCON_S1CCR_CLOCK_REQ (0x4000)
+#define U300_SYSCON_S1CCR_CLOCK_INV (0x0200)
+#define U300_SYSCON_S1CCR_CLOCK_FREQ_MASK (0x01E0)
+#define U300_SYSCON_S1CCR_CLOCK_SELECT_MASK (0x001E)
+#define U300_SYSCON_S1CCR_CLOCK_ENABLE (0x0001)
+#define U300_SYSCON_S1CCR_SEL_MCLK (0x8<<1)
+#define U300_SYSCON_S1CCR_SEL_ACC_FSM_CLK (0xA<<1)
+#define U300_SYSCON_S1CCR_SEL_PLL60_48_CLK (0xC<<1)
+#define U300_SYSCON_S1CCR_SEL_PLL60_60_CLK (0xD<<1)
+#define U300_SYSCON_S1CCR_SEL_ACC_PLL208_CLK (0xE<<1)
+#define U300_SYSCON_S1CCR_SEL_ACC_PLL13_CLK (0x0<<1)
+#define U300_SYSCON_S1CCR_SEL_APP_FSM_CLK (0x2<<1)
+#define U300_SYSCON_S1CCR_SEL_RTC_CLK (0x4<<1)
+#define U300_SYSCON_S1CCR_SEL_APP_PLL208_CLK (0x6<<1)
+/* SYS_2_CLK_CONTROL third clock contol 16 bit (R/W) */
+#define U300_SYSCON_S2CCR (0x128)
+#define U300_SYSCON_S2CCR_FIELD_MASK (0xC3FF)
+#define U300_SYSCON_S2CCR_CLK_STEAL (0x8000)
+#define U300_SYSCON_S2CCR_CLOCK_REQ (0x4000)
+#define U300_SYSCON_S2CCR_CLOCK_INV (0x0200)
+#define U300_SYSCON_S2CCR_CLOCK_FREQ_MASK (0x01E0)
+#define U300_SYSCON_S2CCR_CLOCK_SELECT_MASK (0x001E)
+#define U300_SYSCON_S2CCR_CLOCK_ENABLE (0x0001)
+#define U300_SYSCON_S2CCR_SEL_MCLK (0x8<<1)
+#define U300_SYSCON_S2CCR_SEL_ACC_FSM_CLK (0xA<<1)
+#define U300_SYSCON_S2CCR_SEL_PLL60_48_CLK (0xC<<1)
+#define U300_SYSCON_S2CCR_SEL_PLL60_60_CLK (0xD<<1)
+#define U300_SYSCON_S2CCR_SEL_ACC_PLL208_CLK (0xE<<1)
+#define U300_SYSCON_S2CCR_SEL_ACC_PLL13_CLK (0x0<<1)
+#define U300_SYSCON_S2CCR_SEL_APP_FSM_CLK (0x2<<1)
+#define U300_SYSCON_S2CCR_SEL_RTC_CLK (0x4<<1)
+#define U300_SYSCON_S2CCR_SEL_APP_PLL208_CLK (0x6<<1)
+/* SYS_MISC_CONTROL, miscellaneous 16bit (R/W) */
+#define U300_SYSCON_MCR (0x12c)
+#define U300_SYSCON_MCR_FIELD_MASK (0x00FF)
+#define U300_SYSCON_MCR_PMGEN_CR_4_MASK (0x00C0)
+#define U300_SYSCON_MCR_PMGEN_CR_4_GPIO (0x0000)
+#define U300_SYSCON_MCR_PMGEN_CR_4_SPI (0x0040)
+#define U300_SYSCON_MCR_PMGEN_CR_4_AAIF (0x00C0)
+#define U300_SYSCON_MCR_PMGEN_CR_2_MASK (0x0030)
+#define U300_SYSCON_MCR_PMGEN_CR_2_GPIO (0x0000)
+#define U300_SYSCON_MCR_PMGEN_CR_2_EMIF_1_STATIC (0x0010)
+#define U300_SYSCON_MCR_PMGEN_CR_2_DSP (0x0020)
+#define U300_SYSCON_MCR_PMGEN_CR_2_AAIF (0x0030)
+#define U300_SYSCON_MCR_PMGEN_CR_0_MASK (0x000C)
+#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M1 (0x0000)
+#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M2 (0x0004)
+#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M3 (0x0008)
+#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_0_SDRAM (0x000C)
+#define U300_SYSCON_MCR_PM1G_MODE_ENABLE (0x0002)
+#define U300_SYSCON_MCR_PMTG5_MODE_ENABLE (0x0001)
+/* Clock activity observability register 0 */
+#define U300_SYSCON_C0OAR (0x140)
+#define U300_SYSCON_C0OAR_MASK (0xFFFF)
+#define U300_SYSCON_C0OAR_VALUE (0xFFFF)
+#define U300_SYSCON_C0OAR_BT_H_CLK (0x8000)
+#define U300_SYSCON_C0OAR_ASPB_P_CLK (0x4000)
+#define U300_SYSCON_C0OAR_APP_SEMI_H_CLK (0x2000)
+#define U300_SYSCON_C0OAR_APP_SEMI_CLK (0x1000)
+#define U300_SYSCON_C0OAR_APP_MMC_MSPRO_CLK (0x0800)
+#define U300_SYSCON_C0OAR_APP_I2S1_CLK (0x0400)
+#define U300_SYSCON_C0OAR_APP_I2S0_CLK (0x0200)
+#define U300_SYSCON_C0OAR_APP_CPU_CLK (0x0100)
+#define U300_SYSCON_C0OAR_APP_52_CLK (0x0080)
+#define U300_SYSCON_C0OAR_APP_208_CLK (0x0040)
+#define U300_SYSCON_C0OAR_APP_104_CLK (0x0020)
+#define U300_SYSCON_C0OAR_APEX_CLK (0x0010)
+#define U300_SYSCON_C0OAR_AHPB_M_H_CLK (0x0008)
+#define U300_SYSCON_C0OAR_AHB_CLK (0x0004)
+#define U300_SYSCON_C0OAR_AFPB_P_CLK (0x0002)
+#define U300_SYSCON_C0OAR_AAIF_CLK (0x0001)
+/* Clock activity observability register 1 */
+#define U300_SYSCON_C1OAR (0x144)
+#define U300_SYSCON_C1OAR_MASK (0x3FFE)
+#define U300_SYSCON_C1OAR_VALUE (0x3FFE)
+#define U300_SYSCON_C1OAR_NFIF_F_CLK (0x2000)
+#define U300_SYSCON_C1OAR_MSPRO_CLK (0x1000)
+#define U300_SYSCON_C1OAR_MMC_P_CLK (0x0800)
+#define U300_SYSCON_C1OAR_MMC_CLK (0x0400)
+#define U300_SYSCON_C1OAR_KP_P_CLK (0x0200)
+#define U300_SYSCON_C1OAR_I2C1_P_CLK (0x0100)
+#define U300_SYSCON_C1OAR_I2C0_P_CLK (0x0080)
+#define U300_SYSCON_C1OAR_GPIO_CLK (0x0040)
+#define U300_SYSCON_C1OAR_EMIF_MPMC_CLK (0x0020)
+#define U300_SYSCON_C1OAR_EMIF_H_CLK (0x0010)
+#define U300_SYSCON_C1OAR_EVHIST_CLK (0x0008)
+#define U300_SYSCON_C1OAR_PPM_CLK (0x0004)
+#define U300_SYSCON_C1OAR_DMA_CLK (0x0002)
+/* Clock activity observability register 2 */
+#define U300_SYSCON_C2OAR (0x148)
+#define U300_SYSCON_C2OAR_MASK (0x0FFF)
+#define U300_SYSCON_C2OAR_VALUE (0x0FFF)
+#define U300_SYSCON_C2OAR_XGAM_CDI_CLK (0x0800)
+#define U300_SYSCON_C2OAR_XGAM_CLK (0x0400)
+#define U300_SYSCON_C2OAR_VC_H_CLK (0x0200)
+#define U300_SYSCON_C2OAR_VC_CLK (0x0100)
+#define U300_SYSCON_C2OAR_UA_P_CLK (0x0080)
+#define U300_SYSCON_C2OAR_TMR1_CLK (0x0040)
+#define U300_SYSCON_C2OAR_TMR0_CLK (0x0020)
+#define U300_SYSCON_C2OAR_SPI_P_CLK (0x0010)
+#define U300_SYSCON_C2OAR_PCM_I2S1_CORE_CLK (0x0008)
+#define U300_SYSCON_C2OAR_PCM_I2S1_CLK (0x0004)
+#define U300_SYSCON_C2OAR_PCM_I2S0_CORE_CLK (0x0002)
+#define U300_SYSCON_C2OAR_PCM_I2S0_CLK (0x0001)
+
+/* Chip ID register 16bit (R/-) */
+#define U300_SYSCON_CIDR (0x400)
+/* Video IRQ clear 16bit (R/W) */
+#define U300_SYSCON_VICR (0x404)
+#define U300_SYSCON_VICR_VIDEO1_IRQ_CLEAR_ENABLE (0x0002)
+#define U300_SYSCON_VICR_VIDEO0_IRQ_CLEAR_ENABLE (0x0001)
+/* SMCR */
+#define U300_SYSCON_SMCR (0x4d0)
+#define U300_SYSCON_SMCR_FIELD_MASK (0x000e)
+#define U300_SYSCON_SMCR_SEMI_SREFACK_IND (0x0008)
+#define U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE (0x0004)
+#define U300_SYSCON_SMCR_SEMI_EXT_BOOT_MODE_ENABLE (0x0002)
+/* CPU_SW_DBGEN Software Debug Enable 16bit (R/W) */
+#define U300_SYSCON_CSDR (0x4f0)
+#define U300_SYSCON_CSDR_SW_DEBUG_ENABLE (0x0001)
+/* PRINT_CONTROL Print Control 16bit (R/-) */
+#define U300_SYSCON_PCR (0x4f8)
+#define U300_SYSCON_PCR_SERV_IND (0x0001)
+/* BOOT_CONTROL 16bit (R/-) */
+#define U300_SYSCON_BCR (0x4fc)
+#define U300_SYSCON_BCR_ACC_CPU_SUBSYS_VINITHI_IND (0x0400)
+#define U300_SYSCON_BCR_APP_CPU_SUBSYS_VINITHI_IND (0x0200)
+#define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK (0x01FC)
+#define U300_SYSCON_BCR_APP_BOOT_SERV_MASK (0x0003)
+
+
+/* CPU clock defines */
+/**
+ * CPU high frequency in MHz
+ */
+#define SYSCON_CPU_CLOCK_HIGH 208
+/**
+ * CPU medium frequency in MHz
+ */
+#define SYSCON_CPU_CLOCK_MEDIUM 104
+/**
+ * CPU low frequency in MHz
+ */
+#define SYSCON_CPU_CLOCK_LOW 13
+
+/* EMIF clock defines */
+/**
+ * EMIF high frequency in MHz
+ */
+#define SYSCON_EMIF_CLOCK_HIGH 104
+/**
+ * EMIF medium frequency in MHz
+ */
+#define SYSCON_EMIF_CLOCK_MEDIUM 104
+/**
+ * EMIF low frequency in MHz
+ */
+#define SYSCON_EMIF_CLOCK_LOW 13
+
+/* AHB clock defines */
+/**
+ * AHB high frequency in MHz
+ */
+#define SYSCON_AHB_CLOCK_HIGH 52
+/**
+ * AHB medium frequency in MHz
+ */
+#define SYSCON_AHB_CLOCK_MEDIUM 52
+/**
+ * AHB low frequency in MHz
+ */
+#define SYSCON_AHB_CLOCK_LOW 7 /* i.e 13/2=6.5MHz */
+
+enum syscon_busmaster {
+ SYSCON_BM_DMAC,
+ SYSCON_BM_XGAM,
+ SYSCON_BM_VIDEO_ENC
+};
+
+/*
+ * Note that this array must match the order of the array "clk_reg"
+ * in syscon.c
+ */
+enum syscon_clk {
+ SYSCON_CLKCONTROL_SLOW_BRIDGE,
+ SYSCON_CLKCONTROL_UART,
+ SYSCON_CLKCONTROL_BTR,
+ SYSCON_CLKCONTROL_EH,
+ SYSCON_CLKCONTROL_GPIO,
+ SYSCON_CLKCONTROL_KEYPAD,
+ SYSCON_CLKCONTROL_APP_TIMER,
+ SYSCON_CLKCONTROL_ACC_TIMER,
+ SYSCON_CLKCONTROL_FAST_BRIDGE,
+ SYSCON_CLKCONTROL_I2C0,
+ SYSCON_CLKCONTROL_I2C1,
+ SYSCON_CLKCONTROL_I2S0,
+ SYSCON_CLKCONTROL_I2S1,
+ SYSCON_CLKCONTROL_MMC,
+ SYSCON_CLKCONTROL_SPI,
+ SYSCON_CLKCONTROL_I2S0_CORE,
+ SYSCON_CLKCONTROL_I2S1_CORE,
+ SYSCON_CLKCONTROL_AAIF,
+ SYSCON_CLKCONTROL_AHB,
+ SYSCON_CLKCONTROL_APEX,
+ SYSCON_CLKCONTROL_CPU,
+ SYSCON_CLKCONTROL_DMA,
+ SYSCON_CLKCONTROL_EMIF,
+ SYSCON_CLKCONTROL_NAND_IF,
+ SYSCON_CLKCONTROL_VIDEO_ENC,
+ SYSCON_CLKCONTROL_XGAM,
+ SYSCON_CLKCONTROL_SEMI,
+ SYSCON_CLKCONTROL_AHB_SUBSYS,
+ SYSCON_CLKCONTROL_MSPRO
+};
+
+enum syscon_sysclk_mode {
+ SYSCON_SYSCLK_DISABLED,
+ SYSCON_SYSCLK_M_CLK,
+ SYSCON_SYSCLK_ACC_FSM,
+ SYSCON_SYSCLK_PLL60_48,
+ SYSCON_SYSCLK_PLL60_60,
+ SYSCON_SYSCLK_ACC_PLL208,
+ SYSCON_SYSCLK_APP_PLL13,
+ SYSCON_SYSCLK_APP_FSM,
+ SYSCON_SYSCLK_RTC,
+ SYSCON_SYSCLK_APP_PLL208
+};
+
+enum syscon_sysclk_req {
+ SYSCON_SYSCLKREQ_DISABLED,
+ SYSCON_SYSCLKREQ_ACTIVE_LOW
+};
+
+enum syscon_clk_mode {
+ SYSCON_CLKMODE_OFF,
+ SYSCON_CLKMODE_DEFAULT,
+ SYSCON_CLKMODE_LOW,
+ SYSCON_CLKMODE_MEDIUM,
+ SYSCON_CLKMODE_HIGH,
+ SYSCON_CLKMODE_PERMANENT,
+ SYSCON_CLKMODE_ON,
+};
+
+enum syscon_call_mode {
+ SYSCON_CLKCALL_NOWAIT,
+ SYSCON_CLKCALL_WAIT,
+};
+
+int syscon_dc_on(bool keep_power_on);
+int syscon_set_busmaster_active_state(enum syscon_busmaster busmaster,
+ bool active);
+bool syscon_get_busmaster_active_state(void);
+int syscon_set_sleep_mask(enum syscon_clk,
+ bool sleep_ctrl);
+int syscon_config_sysclk(u32 sysclk,
+ enum syscon_sysclk_mode sysclkmode,
+ bool inverse,
+ u32 divisor,
+ enum syscon_sysclk_req sysclkreq);
+bool syscon_can_turn_off_semi_clock(void);
+
+/* This function is restricted to core.c */
+int syscon_request_normal_power(bool req);
+
+/* This function is restricted to be used by platform_speed.c */
+int syscon_speed_request(enum syscon_call_mode wait_mode,
+ enum syscon_clk_mode req_clk_mode);
+#endif /* __MACH_SYSCON_H */
diff --git a/arch/arm/mach-u300/include/mach/system.h b/arch/arm/mach-u300/include/mach/system.h
new file mode 100644
index 000000000000..8daf13634ce0
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/system.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/system.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * System shutdown and reset functions.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <mach/hardware.h>
+#include <asm/io.h>
+#include <asm/hardware/vic.h>
+#include <asm/irq.h>
+
+/* Forward declare this function from the watchdog */
+void coh901327_watchdog_reset(void);
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+ switch (mode) {
+ case 's':
+ case 'h':
+ printk(KERN_CRIT "RESET: shutting down/rebooting system\n");
+ /* Disable interrupts */
+ local_irq_disable();
+#ifdef CONFIG_COH901327_WATCHDOG
+ coh901327_watchdog_reset();
+#endif
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+ /* Wait for system do die/reset. */
+ while (1);
+}
diff --git a/arch/arm/mach-u300/include/mach/timex.h b/arch/arm/mach-u300/include/mach/timex.h
new file mode 100644
index 000000000000..f233b72633f6
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/timex.h
@@ -0,0 +1,17 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/timex.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Platform tick rate definition.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+/* This is for the APP OS GP1 (General Purpose 1) timer */
+#define CLOCK_TICK_RATE 1000000
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h
new file mode 100644
index 000000000000..88333dfb19fc
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/u300-regs.h
@@ -0,0 +1,187 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/u300-regs.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Basic register address definitions in physical memory and
+ * some block defintions for core devices like the timer.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef __MACH_U300_REGS_H
+#define __MACH_U300_REGS_H
+
+/*
+ * These are the large blocks of memory allocated for I/O.
+ * the defines are used for setting up the I/O memory mapping.
+ */
+
+/* NAND Flash CS0 */
+#define U300_NAND_CS0_PHYS_BASE 0x80000000
+#define U300_NAND_CS0_VIRT_BASE 0xff040000
+
+/* NFIF */
+#define U300_NAND_IF_PHYS_BASE 0x9f800000
+#define U300_NAND_IF_VIRT_BASE 0xff030000
+
+/* AHB Peripherals */
+#define U300_AHB_PER_PHYS_BASE 0xa0000000
+#define U300_AHB_PER_VIRT_BASE 0xff010000
+
+/* FAST Peripherals */
+#define U300_FAST_PER_PHYS_BASE 0xc0000000
+#define U300_FAST_PER_VIRT_BASE 0xff020000
+
+/* SLOW Peripherals */
+#define U300_SLOW_PER_PHYS_BASE 0xc0010000
+#define U300_SLOW_PER_VIRT_BASE 0xff000000
+
+/* Boot ROM */
+#define U300_BOOTROM_PHYS_BASE 0xffff0000
+#define U300_BOOTROM_VIRT_BASE 0xffff0000
+
+/* SEMI config base */
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SEMI_CONFIG_BASE 0x2FFE0000
+#else
+#define U300_SEMI_CONFIG_BASE 0x30000000
+#endif
+
+/*
+ * All the following peripherals are specified at their PHYSICAL address,
+ * so if you need to access them (in the kernel), you MUST use the macros
+ * defined in <asm/io.h> to map to the IO_ADDRESS_AHB() IO_ADDRESS_FAST()
+ * etc.
+ */
+
+/*
+ * AHB peripherals
+ */
+
+/* AHB Peripherals Bridge Controller */
+#define U300_AHB_BRIDGE_BASE (U300_AHB_PER_PHYS_BASE+0x0000)
+
+/* Vectored Interrupt Controller 0, servicing 32 interrupts */
+#define U300_INTCON0_BASE (U300_AHB_PER_PHYS_BASE+0x1000)
+#define U300_INTCON0_VBASE (U300_AHB_PER_VIRT_BASE+0x1000)
+
+/* Vectored Interrupt Controller 1, servicing 32 interrupts */
+#define U300_INTCON1_BASE (U300_AHB_PER_PHYS_BASE+0x2000)
+#define U300_INTCON1_VBASE (U300_AHB_PER_VIRT_BASE+0x2000)
+
+/* Memory Stick Pro (MSPRO) controller */
+#define U300_MSPRO_BASE (U300_AHB_PER_PHYS_BASE+0x3000)
+
+/* EMIF Configuration Area */
+#define U300_EMIF_CFG_BASE (U300_AHB_PER_PHYS_BASE+0x4000)
+
+
+/*
+ * FAST peripherals
+ */
+
+/* FAST bridge control */
+#define U300_FAST_BRIDGE_BASE (U300_FAST_PER_PHYS_BASE+0x0000)
+
+/* MMC/SD controller */
+#define U300_MMCSD_BASE (U300_FAST_PER_PHYS_BASE+0x1000)
+
+/* PCM I2S0 controller */
+#define U300_PCM_I2S0_BASE (U300_FAST_PER_PHYS_BASE+0x2000)
+
+/* PCM I2S1 controller */
+#define U300_PCM_I2S1_BASE (U300_FAST_PER_PHYS_BASE+0x3000)
+
+/* I2C0 controller */
+#define U300_I2C0_BASE (U300_FAST_PER_PHYS_BASE+0x4000)
+
+/* I2C1 controller */
+#define U300_I2C1_BASE (U300_FAST_PER_PHYS_BASE+0x5000)
+
+/* SPI controller */
+#define U300_SPI_BASE (U300_FAST_PER_PHYS_BASE+0x6000)
+
+#ifdef CONFIG_MACH_U300_BS335
+/* Fast UART1 on U335 only */
+#define U300_UART1_BASE (U300_SLOW_PER_PHYS_BASE+0x7000)
+#endif
+
+/*
+ * SLOW peripherals
+ */
+
+/* SLOW bridge control */
+#define U300_SLOW_BRIDGE_BASE (U300_SLOW_PER_PHYS_BASE)
+
+/* SYSCON */
+#define U300_SYSCON_BASE (U300_SLOW_PER_PHYS_BASE+0x1000)
+#define U300_SYSCON_VBASE (U300_SLOW_PER_VIRT_BASE+0x1000)
+
+/* Watchdog */
+#define U300_WDOG_BASE (U300_SLOW_PER_PHYS_BASE+0x2000)
+
+/* UART0 */
+#define U300_UART0_BASE (U300_SLOW_PER_PHYS_BASE+0x3000)
+
+/* APP side special timer */
+#define U300_TIMER_APP_BASE (U300_SLOW_PER_PHYS_BASE+0x4000)
+#define U300_TIMER_APP_VBASE (U300_SLOW_PER_VIRT_BASE+0x4000)
+
+/* Keypad */
+#define U300_KEYPAD_BASE (U300_SLOW_PER_PHYS_BASE+0x5000)
+
+/* GPIO */
+#define U300_GPIO_BASE (U300_SLOW_PER_PHYS_BASE+0x6000)
+
+/* RTC */
+#define U300_RTC_BASE (U300_SLOW_PER_PHYS_BASE+0x7000)
+
+/* Bus tracer */
+#define U300_BUSTR_BASE (U300_SLOW_PER_PHYS_BASE+0x8000)
+
+/* Event handler (hardware queue) */
+#define U300_EVHIST_BASE (U300_SLOW_PER_PHYS_BASE+0x9000)
+
+/* Genric Timer */
+#define U300_TIMER_BASE (U300_SLOW_PER_PHYS_BASE+0xa000)
+
+/* PPM */
+#define U300_PPM_BASE (U300_SLOW_PER_PHYS_BASE+0xb000)
+
+
+/*
+ * REST peripherals
+ */
+
+/* ISP (image signal processor) is only available in U335 */
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_ISP_BASE (0xA0008000)
+#endif
+
+/* DMA Controller base */
+#define U300_DMAC_BASE (0xC0020000)
+
+/* MSL Base */
+#define U300_MSL_BASE (0xc0022000)
+
+/* APEX Base */
+#define U300_APEX_BASE (0xc0030000)
+
+/* Video Encoder Base */
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_VIDEOENC_BASE (0xc0080000)
+#else
+#define U300_VIDEOENC_BASE (0xc0040000)
+#endif
+
+/* XGAM Base */
+#define U300_XGAM_BASE (0xd0000000)
+
+/*
+ * Virtual accessor macros for static devices
+ */
+
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/uncompress.h b/arch/arm/mach-u300/include/mach/uncompress.h
new file mode 100644
index 000000000000..29acb718acf7
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/uncompress.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-u300/include/mach/uncompress.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+#define AMBA_UART_DR (*(volatile unsigned char *)0xc0013000)
+#define AMBA_UART_LCRH (*(volatile unsigned char *)0xc001302C)
+#define AMBA_UART_CR (*(volatile unsigned char *)0xc0013030)
+#define AMBA_UART_FR (*(volatile unsigned char *)0xc0013018)
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ while (AMBA_UART_FR & (1 << 5))
+ barrier();
+
+ AMBA_UART_DR = c;
+}
+
+static inline void flush(void)
+{
+ while (AMBA_UART_FR & (1 << 3))
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-u300/include/mach/vmalloc.h b/arch/arm/mach-u300/include/mach/vmalloc.h
new file mode 100644
index 000000000000..b00c51a66fbe
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/vmalloc.h
@@ -0,0 +1,12 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/vmalloc.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Virtual memory allocations
+ * End must be above the I/O registers and on an even 2MiB boundary.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#define VMALLOC_END 0xfe800000
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c
new file mode 100644
index 000000000000..3138d3955c9e
--- /dev/null
+++ b/arch/arm/mach-u300/mmc.c
@@ -0,0 +1,216 @@
+/*
+ *
+ * arch/arm/mach-u300/mmc.c
+ *
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Johan Lundin <johan.lundin@stericsson.com>
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ */
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/mmc/host.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/mmc.h>
+#include "mmc.h"
+
+struct mmci_card_event {
+ struct input_dev *mmc_input;
+ int mmc_inserted;
+ struct work_struct workq;
+ struct mmc_platform_data mmc0_plat_data;
+};
+
+static unsigned int mmc_status(struct device *dev)
+{
+ struct mmci_card_event *mmci_card = container_of(
+ dev->platform_data,
+ struct mmci_card_event, mmc0_plat_data);
+
+ return mmci_card->mmc_inserted;
+}
+
+/*
+ * Here follows a large chunk of code which will only be enabled if you
+ * have both the AB3100 chip mounted and the MMC subsystem activated.
+ */
+
+static u32 mmc_translate_vdd(struct device *dev, unsigned int voltage)
+{
+ int v;
+
+ /*
+ * MMC Spec:
+ * bit 7: 1.70 - 1.95V
+ * bit 8 - 14: 2.0 - 2.6V
+ * bit 15 - 23: 2.7 - 3.6V
+ *
+ * ab3100 voltages:
+ * 000 - 2.85V
+ * 001 - 2.75V
+ * 010 - 1.8V
+ * 011 - 1.5V
+ */
+ switch (voltage) {
+ case 8:
+ v = 3;
+ break;
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ v = 1;
+ break;
+ case 16:
+ v = 1;
+ break;
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 24:
+ v = 0;
+ break;
+ default:
+ v = 0;
+ break;
+ }
+
+ /* PL180 voltage register bits */
+ return v << 2;
+}
+
+
+
+static int mmci_callback(void *data)
+{
+ struct mmci_card_event *mmci_card = data;
+
+ disable_irq_on_gpio_pin(U300_GPIO_PIN_MMC_CD);
+ schedule_work(&mmci_card->workq);
+
+ return 0;
+}
+
+
+static ssize_t gpio_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct mmci_card_event *mmci_card = container_of(
+ dev->platform_data,
+ struct mmci_card_event, mmc0_plat_data);
+
+
+ return sprintf(buf, "%d\n", !mmci_card->mmc_inserted);
+}
+
+static DEVICE_ATTR(mmc_inserted, S_IRUGO, gpio_show, NULL);
+
+static void _mmci_callback(struct work_struct *ws)
+{
+
+ struct mmci_card_event *mmci_card = container_of(
+ ws,
+ struct mmci_card_event, workq);
+
+ mdelay(20);
+
+ mmci_card->mmc_inserted = !!gpio_get_value(U300_GPIO_PIN_MMC_CD);
+
+ input_report_switch(mmci_card->mmc_input, KEY_INSERT,
+ !mmci_card->mmc_inserted);
+ input_sync(mmci_card->mmc_input);
+
+ pr_debug("MMC/SD card was %s\n",
+ mmci_card->mmc_inserted ? "removed" : "inserted");
+
+ enable_irq_on_gpio_pin(U300_GPIO_PIN_MMC_CD, !mmci_card->mmc_inserted);
+}
+
+int __devinit mmc_init(struct amba_device *adev)
+{
+ struct mmci_card_event *mmci_card;
+ struct device *mmcsd_device = &adev->dev;
+ int ret = 0;
+
+ mmci_card = kzalloc(sizeof(struct mmci_card_event), GFP_KERNEL);
+ if (!mmci_card)
+ return -ENOMEM;
+
+ /* Nominally 2.85V on our platform */
+ mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29;
+ mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd;
+ mmci_card->mmc0_plat_data.status = mmc_status;
+
+ mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data;
+
+ INIT_WORK(&mmci_card->workq, _mmci_callback);
+
+ ret = gpio_request(U300_GPIO_PIN_MMC_CD, "MMC card detection");
+ if (ret) {
+ printk(KERN_CRIT "Could not allocate MMC card detection " \
+ "GPIO pin\n");
+ goto out;
+ }
+
+ ret = gpio_direction_input(U300_GPIO_PIN_MMC_CD);
+ if (ret) {
+ printk(KERN_CRIT "Invalid GPIO pin requested\n");
+ goto out;
+ }
+
+ ret = sysfs_create_file(&mmcsd_device->kobj,
+ &dev_attr_mmc_inserted.attr);
+ if (ret)
+ goto out;
+
+ mmci_card->mmc_input = input_allocate_device();
+ if (!mmci_card->mmc_input) {
+ printk(KERN_CRIT "Could not allocate MMC input device\n");
+ return -ENOMEM;
+ }
+
+ mmci_card->mmc_input->name = "MMC insert notification";
+ mmci_card->mmc_input->id.bustype = BUS_HOST;
+ mmci_card->mmc_input->id.vendor = 0;
+ mmci_card->mmc_input->id.product = 0;
+ mmci_card->mmc_input->id.version = 0x0100;
+ mmci_card->mmc_input->dev.parent = mmcsd_device;
+ input_set_capability(mmci_card->mmc_input, EV_SW, KEY_INSERT);
+
+ /*
+ * Since this must always be compiled into the kernel, this input
+ * is never unregistered or free:ed.
+ */
+ ret = input_register_device(mmci_card->mmc_input);
+ if (ret) {
+ input_free_device(mmci_card->mmc_input);
+ goto out;
+ }
+
+ input_set_drvdata(mmci_card->mmc_input, mmci_card);
+
+ ret = gpio_register_callback(U300_GPIO_PIN_MMC_CD, mmci_callback,
+ mmci_card);
+
+ schedule_work(&mmci_card->workq);
+
+ printk(KERN_INFO "Registered MMC insert/remove notification\n");
+out:
+ return ret;
+}
diff --git a/arch/arm/mach-u300/mmc.h b/arch/arm/mach-u300/mmc.h
new file mode 100644
index 000000000000..92b85125abb3
--- /dev/null
+++ b/arch/arm/mach-u300/mmc.h
@@ -0,0 +1,18 @@
+/*
+ *
+ * arch/arm/mach-u300/mmc.h
+ *
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ */
+#ifndef MMC_H
+#define MMC_H
+
+#include <linux/amba/bus.h>
+
+int __devinit mmc_init(struct amba_device *adev);
+
+#endif
diff --git a/arch/arm/mach-u300/padmux.c b/arch/arm/mach-u300/padmux.c
new file mode 100644
index 000000000000..f3664564f086
--- /dev/null
+++ b/arch/arm/mach-u300/padmux.c
@@ -0,0 +1,58 @@
+/*
+ *
+ * arch/arm/mach-u300/padmux.c
+ *
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * U300 PADMUX functions
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ *
+ */
+#include <linux/io.h>
+#include <linux/err.h>
+#include <mach/u300-regs.h>
+#include <mach/syscon.h>
+
+#include "padmux.h"
+
+/* Set the PAD MUX to route the MMC reader correctly to GPIO0. */
+void pmx_set_mission_mode_mmc(void)
+{
+ u16 val;
+
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMC1LR);
+ val &= ~U300_SYSCON_PMC1LR_MMCSD_MASK;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMC1LR);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMC1HR);
+ val &= ~U300_SYSCON_PMC1HR_APP_GPIO_1_MASK;
+ val |= U300_SYSCON_PMC1HR_APP_GPIO_1_MMC;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMC1HR);
+}
+
+void pmx_set_mission_mode_spi(void)
+{
+ u16 val;
+
+ /* Set up padmuxing so the SPI port and its chipselects are active */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMC1HR);
+ /*
+ * Activate the SPI port (disable the use of these pins for generic
+ * GPIO, DSP, AAIF
+ */
+ val &= ~U300_SYSCON_PMC1HR_APP_SPI_2_MASK;
+ val |= U300_SYSCON_PMC1HR_APP_SPI_2_SPI;
+ /*
+ * Use GPIO pin SPI CS1 for CS1 actually (it can be used for other
+ * things also)
+ */
+ val &= ~U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK;
+ val |= U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI;
+ /*
+ * Use GPIO pin SPI CS2 for CS2 actually (it can be used for other
+ * things also)
+ */
+ val &= ~U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK;
+ val |= U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMC1HR);
+}
diff --git a/arch/arm/mach-u300/padmux.h b/arch/arm/mach-u300/padmux.h
new file mode 100644
index 000000000000..8c2099ac5046
--- /dev/null
+++ b/arch/arm/mach-u300/padmux.h
@@ -0,0 +1,19 @@
+/*
+ *
+ * arch/arm/mach-u300/padmux.h
+ *
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * U300 PADMUX API
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ *
+ */
+
+#ifndef __MACH_U300_PADMUX_H
+#define __MACH_U300_PADMUX_H
+
+void pmx_set_mission_mode_mmc(void);
+void pmx_set_mission_mode_spi(void);
+
+#endif
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
new file mode 100644
index 000000000000..57b5351b1816
--- /dev/null
+++ b/arch/arm/mach-u300/timer.c
@@ -0,0 +1,422 @@
+/*
+ *
+ * arch/arm/mach-u300/timer.c
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Timer COH 901 328, runs the OS timer interrupt.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/types.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+/* Generic stuff */
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+
+#include "clock.h"
+
+/*
+ * APP side special timer registers
+ * This timer contains four timers which can fire an interrupt each.
+ * OS (operating system) timer @ 32768 Hz
+ * DD (device driver) timer @ 1 kHz
+ * GP1 (general purpose 1) timer @ 1MHz
+ * GP2 (general purpose 2) timer @ 1MHz
+ */
+
+/* Reset OS Timer 32bit (-/W) */
+#define U300_TIMER_APP_ROST (0x0000)
+#define U300_TIMER_APP_ROST_TIMER_RESET (0x00000000)
+/* Enable OS Timer 32bit (-/W) */
+#define U300_TIMER_APP_EOST (0x0004)
+#define U300_TIMER_APP_EOST_TIMER_ENABLE (0x00000000)
+/* Disable OS Timer 32bit (-/W) */
+#define U300_TIMER_APP_DOST (0x0008)
+#define U300_TIMER_APP_DOST_TIMER_DISABLE (0x00000000)
+/* OS Timer Mode Register 32bit (-/W) */
+#define U300_TIMER_APP_SOSTM (0x000c)
+#define U300_TIMER_APP_SOSTM_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_SOSTM_MODE_ONE_SHOT (0x00000001)
+/* OS Timer Status Register 32bit (R/-) */
+#define U300_TIMER_APP_OSTS (0x0010)
+#define U300_TIMER_APP_OSTS_TIMER_STATE_MASK (0x0000000F)
+#define U300_TIMER_APP_OSTS_TIMER_STATE_IDLE (0x00000001)
+#define U300_TIMER_APP_OSTS_TIMER_STATE_ACTIVE (0x00000002)
+#define U300_TIMER_APP_OSTS_ENABLE_IND (0x00000010)
+#define U300_TIMER_APP_OSTS_MODE_MASK (0x00000020)
+#define U300_TIMER_APP_OSTS_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_OSTS_MODE_ONE_SHOT (0x00000020)
+#define U300_TIMER_APP_OSTS_IRQ_ENABLED_IND (0x00000040)
+#define U300_TIMER_APP_OSTS_IRQ_PENDING_IND (0x00000080)
+/* OS Timer Current Count Register 32bit (R/-) */
+#define U300_TIMER_APP_OSTCC (0x0014)
+/* OS Timer Terminal Count Register 32bit (R/W) */
+#define U300_TIMER_APP_OSTTC (0x0018)
+/* OS Timer Interrupt Enable Register 32bit (-/W) */
+#define U300_TIMER_APP_OSTIE (0x001c)
+#define U300_TIMER_APP_OSTIE_IRQ_DISABLE (0x00000000)
+#define U300_TIMER_APP_OSTIE_IRQ_ENABLE (0x00000001)
+/* OS Timer Interrupt Acknowledge Register 32bit (-/W) */
+#define U300_TIMER_APP_OSTIA (0x0020)
+#define U300_TIMER_APP_OSTIA_IRQ_ACK (0x00000080)
+
+/* Reset DD Timer 32bit (-/W) */
+#define U300_TIMER_APP_RDDT (0x0040)
+#define U300_TIMER_APP_RDDT_TIMER_RESET (0x00000000)
+/* Enable DD Timer 32bit (-/W) */
+#define U300_TIMER_APP_EDDT (0x0044)
+#define U300_TIMER_APP_EDDT_TIMER_ENABLE (0x00000000)
+/* Disable DD Timer 32bit (-/W) */
+#define U300_TIMER_APP_DDDT (0x0048)
+#define U300_TIMER_APP_DDDT_TIMER_DISABLE (0x00000000)
+/* DD Timer Mode Register 32bit (-/W) */
+#define U300_TIMER_APP_SDDTM (0x004c)
+#define U300_TIMER_APP_SDDTM_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_SDDTM_MODE_ONE_SHOT (0x00000001)
+/* DD Timer Status Register 32bit (R/-) */
+#define U300_TIMER_APP_DDTS (0x0050)
+#define U300_TIMER_APP_DDTS_TIMER_STATE_MASK (0x0000000F)
+#define U300_TIMER_APP_DDTS_TIMER_STATE_IDLE (0x00000001)
+#define U300_TIMER_APP_DDTS_TIMER_STATE_ACTIVE (0x00000002)
+#define U300_TIMER_APP_DDTS_ENABLE_IND (0x00000010)
+#define U300_TIMER_APP_DDTS_MODE_MASK (0x00000020)
+#define U300_TIMER_APP_DDTS_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_DDTS_MODE_ONE_SHOT (0x00000020)
+#define U300_TIMER_APP_DDTS_IRQ_ENABLED_IND (0x00000040)
+#define U300_TIMER_APP_DDTS_IRQ_PENDING_IND (0x00000080)
+/* DD Timer Current Count Register 32bit (R/-) */
+#define U300_TIMER_APP_DDTCC (0x0054)
+/* DD Timer Terminal Count Register 32bit (R/W) */
+#define U300_TIMER_APP_DDTTC (0x0058)
+/* DD Timer Interrupt Enable Register 32bit (-/W) */
+#define U300_TIMER_APP_DDTIE (0x005c)
+#define U300_TIMER_APP_DDTIE_IRQ_DISABLE (0x00000000)
+#define U300_TIMER_APP_DDTIE_IRQ_ENABLE (0x00000001)
+/* DD Timer Interrupt Acknowledge Register 32bit (-/W) */
+#define U300_TIMER_APP_DDTIA (0x0060)
+#define U300_TIMER_APP_DDTIA_IRQ_ACK (0x00000080)
+
+/* Reset GP1 Timer 32bit (-/W) */
+#define U300_TIMER_APP_RGPT1 (0x0080)
+#define U300_TIMER_APP_RGPT1_TIMER_RESET (0x00000000)
+/* Enable GP1 Timer 32bit (-/W) */
+#define U300_TIMER_APP_EGPT1 (0x0084)
+#define U300_TIMER_APP_EGPT1_TIMER_ENABLE (0x00000000)
+/* Disable GP1 Timer 32bit (-/W) */
+#define U300_TIMER_APP_DGPT1 (0x0088)
+#define U300_TIMER_APP_DGPT1_TIMER_DISABLE (0x00000000)
+/* GP1 Timer Mode Register 32bit (-/W) */
+#define U300_TIMER_APP_SGPT1M (0x008c)
+#define U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT (0x00000001)
+/* GP1 Timer Status Register 32bit (R/-) */
+#define U300_TIMER_APP_GPT1S (0x0090)
+#define U300_TIMER_APP_GPT1S_TIMER_STATE_MASK (0x0000000F)
+#define U300_TIMER_APP_GPT1S_TIMER_STATE_IDLE (0x00000001)
+#define U300_TIMER_APP_GPT1S_TIMER_STATE_ACTIVE (0x00000002)
+#define U300_TIMER_APP_GPT1S_ENABLE_IND (0x00000010)
+#define U300_TIMER_APP_GPT1S_MODE_MASK (0x00000020)
+#define U300_TIMER_APP_GPT1S_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_GPT1S_MODE_ONE_SHOT (0x00000020)
+#define U300_TIMER_APP_GPT1S_IRQ_ENABLED_IND (0x00000040)
+#define U300_TIMER_APP_GPT1S_IRQ_PENDING_IND (0x00000080)
+/* GP1 Timer Current Count Register 32bit (R/-) */
+#define U300_TIMER_APP_GPT1CC (0x0094)
+/* GP1 Timer Terminal Count Register 32bit (R/W) */
+#define U300_TIMER_APP_GPT1TC (0x0098)
+/* GP1 Timer Interrupt Enable Register 32bit (-/W) */
+#define U300_TIMER_APP_GPT1IE (0x009c)
+#define U300_TIMER_APP_GPT1IE_IRQ_DISABLE (0x00000000)
+#define U300_TIMER_APP_GPT1IE_IRQ_ENABLE (0x00000001)
+/* GP1 Timer Interrupt Acknowledge Register 32bit (-/W) */
+#define U300_TIMER_APP_GPT1IA (0x00a0)
+#define U300_TIMER_APP_GPT1IA_IRQ_ACK (0x00000080)
+
+/* Reset GP2 Timer 32bit (-/W) */
+#define U300_TIMER_APP_RGPT2 (0x00c0)
+#define U300_TIMER_APP_RGPT2_TIMER_RESET (0x00000000)
+/* Enable GP2 Timer 32bit (-/W) */
+#define U300_TIMER_APP_EGPT2 (0x00c4)
+#define U300_TIMER_APP_EGPT2_TIMER_ENABLE (0x00000000)
+/* Disable GP2 Timer 32bit (-/W) */
+#define U300_TIMER_APP_DGPT2 (0x00c8)
+#define U300_TIMER_APP_DGPT2_TIMER_DISABLE (0x00000000)
+/* GP2 Timer Mode Register 32bit (-/W) */
+#define U300_TIMER_APP_SGPT2M (0x00cc)
+#define U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_SGPT2M_MODE_ONE_SHOT (0x00000001)
+/* GP2 Timer Status Register 32bit (R/-) */
+#define U300_TIMER_APP_GPT2S (0x00d0)
+#define U300_TIMER_APP_GPT2S_TIMER_STATE_MASK (0x0000000F)
+#define U300_TIMER_APP_GPT2S_TIMER_STATE_IDLE (0x00000001)
+#define U300_TIMER_APP_GPT2S_TIMER_STATE_ACTIVE (0x00000002)
+#define U300_TIMER_APP_GPT2S_ENABLE_IND (0x00000010)
+#define U300_TIMER_APP_GPT2S_MODE_MASK (0x00000020)
+#define U300_TIMER_APP_GPT2S_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_GPT2S_MODE_ONE_SHOT (0x00000020)
+#define U300_TIMER_APP_GPT2S_IRQ_ENABLED_IND (0x00000040)
+#define U300_TIMER_APP_GPT2S_IRQ_PENDING_IND (0x00000080)
+/* GP2 Timer Current Count Register 32bit (R/-) */
+#define U300_TIMER_APP_GPT2CC (0x00d4)
+/* GP2 Timer Terminal Count Register 32bit (R/W) */
+#define U300_TIMER_APP_GPT2TC (0x00d8)
+/* GP2 Timer Interrupt Enable Register 32bit (-/W) */
+#define U300_TIMER_APP_GPT2IE (0x00dc)
+#define U300_TIMER_APP_GPT2IE_IRQ_DISABLE (0x00000000)
+#define U300_TIMER_APP_GPT2IE_IRQ_ENABLE (0x00000001)
+/* GP2 Timer Interrupt Acknowledge Register 32bit (-/W) */
+#define U300_TIMER_APP_GPT2IA (0x00e0)
+#define U300_TIMER_APP_GPT2IA_IRQ_ACK (0x00000080)
+
+/* Clock request control register - all four timers */
+#define U300_TIMER_APP_CRC (0x100)
+#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001)
+
+#define TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ)
+#define US_PER_TICK ((1000000 + (HZ/2)) / HZ)
+
+/*
+ * The u300_set_mode() function is always called first, if we
+ * have oneshot timer active, the oneshot scheduling function
+ * u300_set_next_event() is called immediately after.
+ */
+static void u300_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* Disable interrupts on GPT1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 while we're reprogramming it. */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ /*
+ * Set the periodic mode to a certain number of ticks per
+ * jiffy.
+ */
+ writel(TICKS_PER_JIFFY,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+ /*
+ * Set continuous mode, so the timer keeps triggering
+ * interrupts.
+ */
+ writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+ /* Enable timer interrupts */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Then enable the OS timer again */
+ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Just break; here? */
+ /*
+ * The actual event will be programmed by the next event hook,
+ * so we just set a dummy value somewhere at the end of the
+ * universe here.
+ */
+ /* Disable interrupts on GPT1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 while we're reprogramming it. */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ /*
+ * Expire far in the future, u300_set_next_event() will be
+ * called soon...
+ */
+ writel(0xFFFFFFFF, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+ /* We run one shot per tick here! */
+ writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+ /* Enable interrupts for this timer */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Enable timer */
+ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /* Disable interrupts on GP1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ /* Ignore this call */
+ break;
+ }
+}
+
+/*
+ * The app timer in one shot mode obviously has to be reprogrammed
+ * in EXACTLY this sequence to work properly. Do NOT try to e.g. replace
+ * the interrupt disable + timer disable commands with a reset command,
+ * it will fail miserably. Apparently (and I found this the hard way)
+ * the timer is very sensitive to the instruction order, though you don't
+ * get that impression from the data sheet.
+ */
+static int u300_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+
+{
+ /* Disable interrupts on GPT1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 while we're reprogramming it. */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ /* Reset the General Purpose timer 1. */
+ writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1);
+ /* IRQ in n * cycles */
+ writel(cycles, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+ /*
+ * We run one shot per tick here! (This is necessary to reconfigure,
+ * the timer will tilt if you don't!)
+ */
+ writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+ /* Enable timer interrupts */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Then enable the OS timer again */
+ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+ return 0;
+}
+
+
+/* Use general purpose timer 1 as clock event */
+static struct clock_event_device clockevent_u300_1mhz = {
+ .name = "GPT1",
+ .rating = 300, /* Reasonably fast and accurate clock event */
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ /* 22 calculated using the algorithm in arch/mips/kernel/time.c */
+ .shift = 22,
+ .set_next_event = u300_set_next_event,
+ .set_mode = u300_set_mode,
+};
+
+/* Clock event timer interrupt handler */
+static irqreturn_t u300_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_u300_1mhz;
+ /* ACK/Clear timer IRQ for the APP GPT1 Timer */
+ writel(U300_TIMER_APP_GPT1IA_IRQ_ACK,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IA);
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction u300_timer_irq = {
+ .name = "U300 Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = u300_timer_interrupt,
+};
+
+/* Use general purpose timer 2 as clock source */
+static cycle_t u300_get_cycles(void)
+{
+ return (cycles_t) readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
+}
+
+static struct clocksource clocksource_u300_1mhz = {
+ .name = "GPT2",
+ .rating = 300, /* Reasonably fast and accurate clock source */
+ .read = u300_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32), /* 32 bits */
+ /* 22 calculated using the algorithm in arch/mips/kernel/time.c */
+ .shift = 22,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+
+/*
+ * This sets up the system timers, clock source and clock event.
+ */
+static void __init u300_timer_init(void)
+{
+ u300_enable_timer_clock();
+ /*
+ * Disable the "OS" and "DD" timers - these are designed for Symbian!
+ * Example usage in cnh1601578 cpu subsystem pd_timer_app.c
+ */
+ writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_CRC);
+ writel(U300_TIMER_APP_ROST_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_ROST);
+ writel(U300_TIMER_APP_DOST_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DOST);
+ writel(U300_TIMER_APP_RDDT_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RDDT);
+ writel(U300_TIMER_APP_DDDT_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DDDT);
+
+ /* Reset the General Purpose timer 1. */
+ writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1);
+
+ /* Set up the IRQ handler */
+ setup_irq(IRQ_U300_TIMER_APP_GP1, &u300_timer_irq);
+
+ /* Reset the General Purpose timer 2 */
+ writel(U300_TIMER_APP_RGPT2_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT2);
+ /* Set this timer to run around forever */
+ writel(0xFFFFFFFFU, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2TC);
+ /* Set continuous mode so it wraps around */
+ writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT2M);
+ /* Disable timer interrupts */
+ writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2IE);
+ /* Then enable the GP2 timer to use as a free running us counter */
+ writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2);
+
+ /* This is a pure microsecond clock source */
+ clocksource_u300_1mhz.mult =
+ clocksource_khz2mult(1000, clocksource_u300_1mhz.shift);
+ if (clocksource_register(&clocksource_u300_1mhz))
+ printk(KERN_ERR "timer: failed to initialize clock "
+ "source %s\n", clocksource_u300_1mhz.name);
+
+ clockevent_u300_1mhz.mult =
+ div_sc(1000000, NSEC_PER_SEC, clockevent_u300_1mhz.shift);
+ /* 32bit counter, so 32bits delta is max */
+ clockevent_u300_1mhz.max_delta_ns =
+ clockevent_delta2ns(0xffffffff, &clockevent_u300_1mhz);
+ /* This timer is slow enough to set for 1 cycle == 1 MHz */
+ clockevent_u300_1mhz.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_u300_1mhz);
+ clockevent_u300_1mhz.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_u300_1mhz);
+ /*
+ * TODO: init and register the rest of the timers too, they can be
+ * used by hrtimers!
+ */
+}
+
+/*
+ * Very simple system timer that only register the clock event and
+ * clock source.
+ */
+struct sys_timer u300_timer = {
+ .init = u300_timer_init,
+};
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
new file mode 100644
index 000000000000..d2a0b8847a18
--- /dev/null
+++ b/arch/arm/mach-u300/u300.c
@@ -0,0 +1,55 @@
+/*
+ *
+ * arch/arm/mach-u300/u300.c
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Platform machine definition.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#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/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <mach/memory.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static void __init u300_init_machine(void)
+{
+ u300_init_devices();
+}
+
+#ifdef CONFIG_MACH_U300_BS2X
+#define MACH_U300_STRING "Ericsson AB U300 S25/S26/B25/B26 Prototype Board"
+#endif
+
+#ifdef CONFIG_MACH_U300_BS330
+#define MACH_U300_STRING "Ericsson AB U330 S330/B330 Prototype Board"
+#endif
+
+#ifdef CONFIG_MACH_U300_BS335
+#define MACH_U300_STRING "Ericsson AB U335 S335/B335 Prototype Board"
+#endif
+
+#ifdef CONFIG_MACH_U300_BS365
+#define MACH_U300_STRING "Ericsson AB U365 S365/B365 Prototype Board"
+#endif
+
+MACHINE_START(U300, MACH_U300_STRING)
+ /* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */
+ .phys_io = U300_AHB_PER_PHYS_BASE,
+ .io_pg_offst = ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = BOOT_PARAMS_OFFSET,
+ .map_io = u300_map_io,
+ .init_irq = u300_init_irq,
+ .timer = &u300_timer,
+ .init_machine = u300_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 1f929c391af7..c39c788e2731 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -116,7 +116,7 @@ void __init versatile_init_irq(void)
{
unsigned int i;
- vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0);
+ vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
diff --git a/arch/arm/mach-w90x900/include/mach/irqs.h b/arch/arm/mach-w90x900/include/mach/irqs.h
index 1c583f9cbcde..9d5cba3a509f 100644
--- a/arch/arm/mach-w90x900/include/mach/irqs.h
+++ b/arch/arm/mach-w90x900/include/mach/irqs.h
@@ -1,8 +1,7 @@
/*
* arch/arm/mach-w90x900/include/mach/irqs.h
*
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
+ * Copyright (c) 2008 Nuvoton technology corporation.
*
* Wan ZongShun <mcuos.com@gmail.com>
*
@@ -10,8 +9,7 @@
*
* 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.
+ * the Free Software Foundation;version 2 of the License.
*
*/
@@ -31,6 +29,11 @@
/* Main cpu interrupts */
#define IRQ_WDT W90X900_IRQ(1)
+#define IRQ_GROUP0 W90X900_IRQ(2)
+#define IRQ_GROUP1 W90X900_IRQ(3)
+#define IRQ_ACTL W90X900_IRQ(4)
+#define IRQ_LCD W90X900_IRQ(5)
+#define IRQ_RTC W90X900_IRQ(6)
#define IRQ_UART0 W90X900_IRQ(7)
#define IRQ_UART1 W90X900_IRQ(8)
#define IRQ_UART2 W90X900_IRQ(9)
@@ -39,7 +42,45 @@
#define IRQ_TIMER0 W90X900_IRQ(12)
#define IRQ_TIMER1 W90X900_IRQ(13)
#define IRQ_T_INT_GROUP W90X900_IRQ(14)
+#define IRQ_USBH W90X900_IRQ(15)
+#define IRQ_EMCTX W90X900_IRQ(16)
+#define IRQ_EMCRX W90X900_IRQ(17)
+#define IRQ_GDMAGROUP W90X900_IRQ(18)
+#define IRQ_DMAC W90X900_IRQ(19)
+#define IRQ_FMI W90X900_IRQ(20)
+#define IRQ_USBD W90X900_IRQ(21)
+#define IRQ_ATAPI W90X900_IRQ(22)
+#define IRQ_G2D W90X900_IRQ(23)
+#define IRQ_PCI W90X900_IRQ(24)
+#define IRQ_SCGROUP W90X900_IRQ(25)
+#define IRQ_I2CGROUP W90X900_IRQ(26)
+#define IRQ_SSP W90X900_IRQ(27)
+#define IRQ_PWM W90X900_IRQ(28)
+#define IRQ_KPI W90X900_IRQ(29)
+#define IRQ_P2SGROUP W90X900_IRQ(30)
#define IRQ_ADC W90X900_IRQ(31)
#define NR_IRQS (IRQ_ADC+1)
+/*for irq group*/
+
+#define IRQ_PS2_PORT0 0x10000000
+#define IRQ_PS2_PORT1 0x20000000
+#define IRQ_I2C_LINE0 0x04000000
+#define IRQ_I2C_LINE1 0x08000000
+#define IRQ_SC_CARD0 0x01000000
+#define IRQ_SC_CARD1 0x02000000
+#define IRQ_GDMA_CH0 0x00100000
+#define IRQ_GDMA_CH1 0x00200000
+#define IRQ_TIMER2 0x00010000
+#define IRQ_TIMER3 0x00020000
+#define IRQ_TIMER4 0x00040000
+#define IRQ_GROUP0_IRQ0 0x00000001
+#define IRQ_GROUP0_IRQ1 0x00000002
+#define IRQ_GROUP0_IRQ2 0x00000004
+#define IRQ_GROUP0_IRQ3 0x00000008
+#define IRQ_GROUP1_IRQ4 0x00000010
+#define IRQ_GROUP1_IRQ5 0x00000020
+#define IRQ_GROUP1_IRQ6 0x00000040
+#define IRQ_GROUP1_IRQ7 0x00000080
+
#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-w90x900/include/mach/map.h b/arch/arm/mach-w90x900/include/mach/map.h
index 79320ebe614b..1a2095304117 100644
--- a/arch/arm/mach-w90x900/include/mach/map.h
+++ b/arch/arm/mach-w90x900/include/mach/map.h
@@ -1,8 +1,7 @@
/*
* arch/arm/mach-w90x900/include/mach/map.h
*
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
+ * Copyright (c) 2008 Nuvoton technology corporation.
*
* Wan ZongShun <mcuos.com@gmail.com>
*
@@ -10,8 +9,7 @@
*
* 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.
+ * the Free Software Foundation;version 2 of the License.
*
*/
@@ -34,7 +32,6 @@
* interrupt controller is the first thing we put in, to make
* the assembly code for the irq detection easier
*/
-
#define W90X900_VA_IRQ W90X900_ADDR(0x00000000)
#define W90X900_PA_IRQ (0xB8002000)
#define W90X900_SZ_IRQ SZ_4K
@@ -44,33 +41,117 @@
#define W90X900_SZ_GCR SZ_4K
/* Clock and Power management */
-
#define W90X900_VA_CLKPWR (W90X900_VA_GCR+0x200)
#define W90X900_PA_CLKPWR (0xB0000200)
#define W90X900_SZ_CLKPWR SZ_4K
/* EBI management */
-
#define W90X900_VA_EBI W90X900_ADDR(0x00001000)
#define W90X900_PA_EBI (0xB0001000)
#define W90X900_SZ_EBI SZ_4K
/* UARTs */
-
#define W90X900_VA_UART W90X900_ADDR(0x08000000)
#define W90X900_PA_UART (0xB8000000)
#define W90X900_SZ_UART SZ_4K
/* Timers */
-
#define W90X900_VA_TIMER W90X900_ADDR(0x08001000)
#define W90X900_PA_TIMER (0xB8001000)
#define W90X900_SZ_TIMER SZ_4K
/* GPIO ports */
-
#define W90X900_VA_GPIO W90X900_ADDR(0x08003000)
#define W90X900_PA_GPIO (0xB8003000)
#define W90X900_SZ_GPIO SZ_4K
+/* GDMA control */
+#define W90X900_VA_GDMA W90X900_ADDR(0x00004000)
+#define W90X900_PA_GDMA (0xB0004000)
+#define W90X900_SZ_GDMA SZ_4K
+
+/* USB host controller*/
+#define W90X900_VA_USBEHCIHOST W90X900_ADDR(0x00005000)
+#define W90X900_PA_USBEHCIHOST (0xB0005000)
+#define W90X900_SZ_USBEHCIHOST SZ_4K
+
+#define W90X900_VA_USBOHCIHOST W90X900_ADDR(0x00007000)
+#define W90X900_PA_USBOHCIHOST (0xB0007000)
+#define W90X900_SZ_USBOHCIHOST SZ_4K
+
+/* I2C hardware controller */
+#define W90X900_VA_I2C W90X900_ADDR(0x08006000)
+#define W90X900_PA_I2C (0xB8006000)
+#define W90X900_SZ_I2C SZ_4K
+
+/* Keypad Interface*/
+#define W90X900_VA_KPI W90X900_ADDR(0x08008000)
+#define W90X900_PA_KPI (0xB8008000)
+#define W90X900_SZ_KPI SZ_4K
+
+/* Smart card host*/
+#define W90X900_VA_SC W90X900_ADDR(0x08005000)
+#define W90X900_PA_SC (0xB8005000)
+#define W90X900_SZ_SC SZ_4K
+
+/* LCD controller*/
+#define W90X900_VA_LCD W90X900_ADDR(0x00008000)
+#define W90X900_PA_LCD (0xB0008000)
+#define W90X900_SZ_LCD SZ_4K
+
+/* 2D controller*/
+#define W90X900_VA_GE W90X900_ADDR(0x0000B000)
+#define W90X900_PA_GE (0xB000B000)
+#define W90X900_SZ_GE SZ_4K
+
+/* ATAPI */
+#define W90X900_VA_ATAPI W90X900_ADDR(0x0000A000)
+#define W90X900_PA_ATAPI (0xB000A000)
+#define W90X900_SZ_ATAPI SZ_4K
+
+/* ADC */
+#define W90X900_VA_ADC W90X900_ADDR(0x0800A000)
+#define W90X900_PA_ADC (0xB800A000)
+#define W90X900_SZ_ADC SZ_4K
+
+/* PS2 Interface*/
+#define W90X900_VA_PS2 W90X900_ADDR(0x08009000)
+#define W90X900_PA_PS2 (0xB8009000)
+#define W90X900_SZ_PS2 SZ_4K
+
+/* RTC */
+#define W90X900_VA_RTC W90X900_ADDR(0x08004000)
+#define W90X900_PA_RTC (0xB8004000)
+#define W90X900_SZ_RTC SZ_4K
+
+/* Pulse Width Modulation(PWM) Registers */
+#define W90X900_VA_PWM W90X900_ADDR(0x08007000)
+#define W90X900_PA_PWM (0xB8007000)
+#define W90X900_SZ_PWM SZ_4K
+
+/* Audio Controller controller */
+#define W90X900_VA_ACTL W90X900_ADDR(0x00009000)
+#define W90X900_PA_ACTL (0xB0009000)
+#define W90X900_SZ_ACTL SZ_4K
+
+/* DMA controller */
+#define W90X900_VA_DMA W90X900_ADDR(0x0000c000)
+#define W90X900_PA_DMA (0xB000c000)
+#define W90X900_SZ_DMA SZ_4K
+
+/* FMI controller */
+#define W90X900_VA_FMI W90X900_ADDR(0x0000d000)
+#define W90X900_PA_FMI (0xB000d000)
+#define W90X900_SZ_FMI SZ_4K
+
+/* USB Device port */
+#define W90X900_VA_USBDEV W90X900_ADDR(0x00006000)
+#define W90X900_PA_USBDEV (0xB0006000)
+#define W90X900_SZ_USBDEV SZ_4K
+
+/* External MAC control*/
+#define W90X900_VA_EMC W90X900_ADDR(0x00003000)
+#define W90X900_PA_EMC (0xB0003000)
+#define W90X900_SZ_EMC SZ_4K
+
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-clock.h b/arch/arm/mach-w90x900/include/mach/regs-clock.h
new file mode 100644
index 000000000000..f10b6a8dc069
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-clock.h
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H
+
+/* Clock Control Registers */
+#define CLK_BA W90X900_VA_CLKPWR
+#define REG_CLKEN (CLK_BA + 0x00)
+#define REG_CLKSEL (CLK_BA + 0x04)
+#define REG_CLKDIV (CLK_BA + 0x08)
+#define REG_PLLCON0 (CLK_BA + 0x0C)
+#define REG_PLLCON1 (CLK_BA + 0x10)
+#define REG_PMCON (CLK_BA + 0x14)
+#define REG_IRQWAKECON (CLK_BA + 0x18)
+#define REG_IRQWAKEFLAG (CLK_BA + 0x1C)
+#define REG_IPSRST (CLK_BA + 0x20)
+#define REG_CLKEN1 (CLK_BA + 0x24)
+#define REG_CLKDIV1 (CLK_BA + 0x28)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-usb.h b/arch/arm/mach-w90x900/include/mach/regs-usb.h
new file mode 100644
index 000000000000..ab74b0c2480b
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-usb.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-usb.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_USB_H
+#define __ASM_ARCH_REGS_USB_H
+
+/* usb Control Registers */
+#define USBH_BA W90X900_VA_USBEHCIHOST
+#define USBD_BA W90X900_VA_USBDEV
+#define USBO_BA W90X900_VA_USBOHCIHOST
+
+/* USB Host Control Registers */
+#define REG_UPSCR0 (USBH_BA+0x064)
+#define REG_UPSCR1 (USBH_BA+0x068)
+#define REG_USBPCR0 (USBH_BA+0x0C4)
+#define REG_USBPCR1 (USBH_BA+0x0C8)
+
+/* USBH OHCI Control Registers */
+#define REG_OpModEn (USBO_BA+0x204)
+/*This bit controls the polarity of over
+*current flag from external power IC.
+*/
+#define OCALow 0x08
+
+#endif /* __ASM_ARCH_REGS_USB_H */
diff --git a/arch/arm/mach-w90x900/mach-w90p910evb.c b/arch/arm/mach-w90x900/mach-w90p910evb.c
index 726ff6798a56..26de71f73f47 100644
--- a/arch/arm/mach-w90x900/mach-w90p910evb.c
+++ b/arch/arm/mach-w90x900/mach-w90p910evb.c
@@ -3,15 +3,13 @@
*
* Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
*
- * Copyright (C) 2008 Nuvoton technology corporation
- * All rights reserved.
+ * Copyright (C) 2008 Nuvoton technology corporation.
*
* Wan ZongShun <mcuos.com@gmail.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.
+ * published by the Free Software Foundation;version 2 of the License.
*
*/
@@ -80,6 +78,86 @@ static struct platform_device w90p910_flash_device = {
.num_resources = ARRAY_SIZE(w90p910_flash_resources),
};
+/* USB EHCI Host Controller */
+
+static struct resource w90x900_usb_ehci_resource[] = {
+ [0] = {
+ .start = W90X900_PA_USBEHCIHOST,
+ .end = W90X900_PA_USBEHCIHOST + W90X900_SZ_USBEHCIHOST - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBH,
+ .end = IRQ_USBH,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 w90x900_device_usb_ehci_dmamask = 0xffffffffUL;
+
+struct platform_device w90x900_device_usb_ehci = {
+ .name = "w90x900-ehci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(w90x900_usb_ehci_resource),
+ .resource = w90x900_usb_ehci_resource,
+ .dev = {
+ .dma_mask = &w90x900_device_usb_ehci_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+EXPORT_SYMBOL(w90x900_device_usb_ehci);
+
+/* USB OHCI Host Controller */
+
+static struct resource w90x900_usb_ohci_resource[] = {
+ [0] = {
+ .start = W90X900_PA_USBOHCIHOST,
+ .end = W90X900_PA_USBOHCIHOST + W90X900_SZ_USBOHCIHOST - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBH,
+ .end = IRQ_USBH,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 w90x900_device_usb_ohci_dmamask = 0xffffffffUL;
+struct platform_device w90x900_device_usb_ohci = {
+ .name = "w90x900-ohci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(w90x900_usb_ohci_resource),
+ .resource = w90x900_usb_ohci_resource,
+ .dev = {
+ .dma_mask = &w90x900_device_usb_ohci_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+EXPORT_SYMBOL(w90x900_device_usb_ohci);
+
+/*TouchScreen controller*/
+
+static struct resource w90x900_ts_resource[] = {
+ [0] = {
+ .start = W90X900_PA_ADC,
+ .end = W90X900_PA_ADC + W90X900_SZ_ADC-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ADC,
+ .end = IRQ_ADC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device w90x900_device_ts = {
+ .name = "w90x900-ts",
+ .id = -1,
+ .resource = w90x900_ts_resource,
+ .num_resources = ARRAY_SIZE(w90x900_ts_resource),
+};
+EXPORT_SYMBOL(w90x900_device_ts);
+
static struct map_desc w90p910_iodesc[] __initdata = {
};
@@ -88,6 +166,9 @@ static struct map_desc w90p910_iodesc[] __initdata = {
static struct platform_device *w90p910evb_dev[] __initdata = {
&w90p910_serial_device,
&w90p910_flash_device,
+ &w90x900_device_usb_ehci,
+ &w90x900_device_usb_ohci,
+ &w90x900_device_ts,
};
static void __init w90p910evb_map_io(void)
diff --git a/arch/arm/mach-w90x900/w90p910.c b/arch/arm/mach-w90x900/w90p910.c
index 2bcbaa681b99..d2e4a16c9e00 100644
--- a/arch/arm/mach-w90x900/w90p910.c
+++ b/arch/arm/mach-w90x900/w90p910.c
@@ -3,8 +3,7 @@
*
* Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
*
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
+ * Copyright (c) 2008 Nuvoton technology corporation.
*
* Wan ZongShun <mcuos.com@gmail.com>
*
@@ -12,8 +11,7 @@
*
* 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.
+ * the Free Software Foundation;version 2 of the License.
*
*/
@@ -45,6 +43,9 @@ static struct map_desc w90p910_iodesc[] __initdata = {
IODESC_ENT(UART),
IODESC_ENT(TIMER),
IODESC_ENT(EBI),
+ IODESC_ENT(USBEHCIHOST),
+ IODESC_ENT(USBOHCIHOST),
+ IODESC_ENT(ADC),
/*IODESC_ENT(LCD),*/
};
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index e6344ece00ce..39fca4e416e2 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -839,6 +839,20 @@ void __init reserve_node_zero(pg_data_t *pgdat)
reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
BOOTMEM_EXCLUSIVE);
+ /*
+ * U300 - This platform family can share physical memory
+ * between two ARM cpus, one running Linux and the other
+ * running another OS.
+ */
+ if (machine_is_u300()) {
+#ifdef CONFIG_MACH_U300_SINGLE_RAM
+#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
+ CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+ res_size = 0x00100000;
+#endif
+#endif
+ }
+
#ifdef CONFIG_SA1111
/*
* Because of the SA1111 DMA bug, we want to preserve our
diff --git a/arch/arm/plat-mxc/dma-mx1-mx2.c b/arch/arm/plat-mxc/dma-mx1-mx2.c
index e364a5ed10f1..77646436c00e 100644
--- a/arch/arm/plat-mxc/dma-mx1-mx2.c
+++ b/arch/arm/plat-mxc/dma-mx1-mx2.c
@@ -693,12 +693,15 @@ int imx_dma_request(int channel, const char *name)
local_irq_restore(flags);
return -EBUSY;
}
+ memset(imxdma, 0, sizeof(imxdma));
+ imxdma->name = name;
+ local_irq_restore(flags); /* request_irq() can block */
#ifdef CONFIG_ARCH_MX2
ret = request_irq(MXC_INT_DMACH0 + channel, dma_irq_handler, 0, "DMA",
NULL);
if (ret) {
- local_irq_restore(flags);
+ imxdma->name = NULL;
printk(KERN_CRIT "Can't register IRQ %d for DMA channel %d\n",
MXC_INT_DMACH0 + channel, channel);
return ret;
@@ -708,13 +711,6 @@ int imx_dma_request(int channel, const char *name)
imxdma->watchdog.data = channel;
#endif
- imxdma->name = name;
- imxdma->irq_handler = NULL;
- imxdma->err_handler = NULL;
- imxdma->data = NULL;
- imxdma->sg = NULL;
-
- local_irq_restore(flags);
return ret;
}
EXPORT_SYMBOL(imx_dma_request);
@@ -737,10 +733,7 @@ void imx_dma_free(int channel)
local_irq_save(flags);
/* Disable interrupts */
- __raw_writel(__raw_readl(DMA_BASE + DMA_DIMR) | (1 << channel),
- DMA_BASE + DMA_DIMR);
- __raw_writel(__raw_readl(DMA_BASE + DMA_CCR(channel)) & ~CCR_CEN,
- DMA_BASE + DMA_CCR(channel));
+ imx_dma_disable(channel);
imxdma->name = NULL;
#ifdef CONFIG_ARCH_MX2
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index c6483bad8a26..89e95798cc3b 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -124,7 +124,7 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
irq_stat = __raw_readl(port->base + GPIO_ISR) &
__raw_readl(port->base + GPIO_IMR);
- BUG_ON(!irq_stat);
+
mxc_gpio_irq_handler(port, irq_stat);
}
#endif
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27ads.h b/arch/arm/plat-mxc/include/mach/board-mx27ads.h
index 1cac9d1135cd..d42f4e6116f8 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx27ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx27ads.h
@@ -47,7 +47,7 @@
/*
* Base address of PBC controller, CS4
*/
-#define PBC_BASE_ADDRESS 0xEB000000
+#define PBC_BASE_ADDRESS 0xf4300000
#define PBC_REG_ADDR(offset) (void __force __iomem *) \
(PBC_BASE_ADDRESS + (offset))
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index 0abfbaa59871..40424edae939 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -147,24 +147,40 @@ static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void *arg)
return ret;
}
+struct omap_msg_tx_data {
+ mbox_msg_t msg;
+ void *arg;
+};
+
+static void omap_msg_tx_end_io(struct request *rq, int error)
+{
+ kfree(rq->special);
+ __blk_put_request(rq->q, rq);
+}
+
int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void* arg)
{
+ struct omap_msg_tx_data *tx_data;
struct request *rq;
struct request_queue *q = mbox->txq->queue;
- int ret = 0;
+
+ tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC);
+ if (unlikely(!tx_data))
+ return -ENOMEM;
rq = blk_get_request(q, WRITE, GFP_ATOMIC);
if (unlikely(!rq)) {
- ret = -ENOMEM;
- goto fail;
+ kfree(tx_data);
+ return -ENOMEM;
}
- rq->data = (void *)msg;
- blk_insert_request(q, rq, 0, arg);
+ tx_data->msg = msg;
+ tx_data->arg = arg;
+ rq->end_io = omap_msg_tx_end_io;
+ blk_insert_request(q, rq, 0, tx_data);
schedule_work(&mbox->txq->work);
- fail:
- return ret;
+ return 0;
}
EXPORT_SYMBOL(omap_mbox_msg_send);
@@ -178,22 +194,28 @@ static void mbox_tx_work(struct work_struct *work)
struct request_queue *q = mbox->txq->queue;
while (1) {
+ struct omap_msg_tx_data *tx_data;
+
spin_lock(q->queue_lock);
- rq = elv_next_request(q);
+ rq = blk_fetch_request(q);
spin_unlock(q->queue_lock);
if (!rq)
break;
- ret = __mbox_msg_send(mbox, (mbox_msg_t) rq->data, rq->special);
+ tx_data = rq->special;
+
+ ret = __mbox_msg_send(mbox, tx_data->msg, tx_data->arg);
if (ret) {
enable_mbox_irq(mbox, IRQ_TX);
+ spin_lock(q->queue_lock);
+ blk_requeue_request(q, rq);
+ spin_unlock(q->queue_lock);
return;
}
spin_lock(q->queue_lock);
- if (__blk_end_request(rq, 0, 0))
- BUG();
+ __blk_end_request_all(rq, 0);
spin_unlock(q->queue_lock);
}
}
@@ -218,16 +240,13 @@ static void mbox_rx_work(struct work_struct *work)
while (1) {
spin_lock_irqsave(q->queue_lock, flags);
- rq = elv_next_request(q);
+ rq = blk_fetch_request(q);
spin_unlock_irqrestore(q->queue_lock, flags);
if (!rq)
break;
- msg = (mbox_msg_t) rq->data;
-
- if (blk_end_request(rq, 0, 0))
- BUG();
-
+ msg = (mbox_msg_t)rq->special;
+ blk_end_request_all(rq, 0);
mbox->rxq->callback((void *)msg);
}
}
@@ -264,7 +283,6 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
goto nomem;
msg = mbox_fifo_read(mbox);
- rq->data = (void *)msg;
if (unlikely(mbox_seq_test(mbox, msg))) {
pr_info("mbox: Illegal seq bit!(%08x)\n", msg);
@@ -272,7 +290,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
mbox->err_notify();
}
- blk_insert_request(q, rq, 0, NULL);
+ blk_insert_request(q, rq, 0, (void *)msg);
if (mbox->ops->type == OMAP_MBOX_TYPE1)
break;
}
@@ -329,16 +347,15 @@ omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf)
while (1) {
spin_lock_irqsave(q->queue_lock, flags);
- rq = elv_next_request(q);
+ rq = blk_fetch_request(q);
spin_unlock_irqrestore(q->queue_lock, flags);
if (!rq)
break;
- *p = (mbox_msg_t) rq->data;
+ *p = (mbox_msg_t)rq->special;
- if (blk_end_request(rq, 0, 0))
- BUG();
+ blk_end_request_all(rq, 0);
if (unlikely(mbox_seq_test(mbox, *p))) {
pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p);
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
index 8f2c4c7fbd48..0264bfb0ca4f 100644
--- a/arch/arm/plat-pxa/Makefile
+++ b/arch/arm/plat-pxa/Makefile
@@ -7,3 +7,5 @@ obj-y := dma.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_PXA3xx) += mfp.o
obj-$(CONFIG_ARCH_MMP) += mfp.o
+
+obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/mach-pxa/include/mach/i2c.h b/arch/arm/plat-pxa/include/plat/i2c.h
index 1a9f65e6ec0f..1a9f65e6ec0f 100644
--- a/arch/arm/mach-pxa/include/mach/i2c.h
+++ b/arch/arm/plat-pxa/include/plat/i2c.h
diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c
index fcdd374437a8..a9eabdcfa163 100644
--- a/arch/arm/mach-pxa/pwm.c
+++ b/arch/arm/plat-pxa/pwm.c
@@ -21,6 +21,19 @@
#include <asm/div64.h>
+#define HAS_SECONDARY_PWM 0x10
+#define PWM_ID_BASE(d) ((d) & 0xf)
+
+static const struct platform_device_id pwm_id_table[] = {
+ /* PWM has_secondary_pwm? */
+ { "pxa25x-pwm", 0 },
+ { "pxa27x-pwm", 0 | HAS_SECONDARY_PWM },
+ { "pxa168-pwm", 1 },
+ { "pxa910-pwm", 1 },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, pwm_id_table);
+
/* PWM registers and bits definitions */
#define PWMCR (0x00)
#define PWMDCR (0x04)
@@ -31,7 +44,8 @@
struct pwm_device {
struct list_head node;
- struct platform_device *pdev;
+ struct pwm_device *secondary;
+ struct platform_device *pdev;
const char *label;
struct clk *clk;
@@ -159,17 +173,17 @@ static inline void __add_pwm(struct pwm_device *pwm)
mutex_unlock(&pwm_lock);
}
-static struct pwm_device *pwm_probe(struct platform_device *pdev,
- unsigned int pwm_id, struct pwm_device *parent_pwm)
+static int __devinit pwm_probe(struct platform_device *pdev)
{
- struct pwm_device *pwm;
+ struct platform_device_id *id = platform_get_device_id(pdev);
+ struct pwm_device *pwm, *secondary = NULL;
struct resource *r;
int ret = 0;
pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
if (pwm == NULL) {
dev_err(&pdev->dev, "failed to allocate memory\n");
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
}
pwm->clk = clk_get(&pdev->dev, NULL);
@@ -180,16 +194,9 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev,
pwm->clk_enabled = 0;
pwm->use_count = 0;
- pwm->pwm_id = pwm_id;
+ pwm->pwm_id = PWM_ID_BASE(id->driver_data) + pdev->id;
pwm->pdev = pdev;
- if (parent_pwm != NULL) {
- /* registers for the second PWM has offset of 0x10 */
- pwm->mmio_base = parent_pwm->mmio_base + 0x10;
- __add_pwm(pwm);
- return pwm;
- }
-
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
dev_err(&pdev->dev, "no memory resource defined\n");
@@ -211,9 +218,27 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev,
goto err_free_mem;
}
+ if (id->driver_data & HAS_SECONDARY_PWM) {
+ secondary = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+ if (secondary == NULL) {
+ ret = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ *secondary = *pwm;
+ pwm->secondary = secondary;
+
+ /* registers for the second PWM has offset of 0x10 */
+ secondary->mmio_base = pwm->mmio_base + 0x10;
+ secondary->pwm_id = pdev->id + 2;
+ }
+
__add_pwm(pwm);
+ if (secondary)
+ __add_pwm(secondary);
+
platform_set_drvdata(pdev, pwm);
- return pwm;
+ return 0;
err_free_mem:
release_mem_region(r->start, r->end - r->start + 1);
@@ -221,32 +246,7 @@ err_free_clk:
clk_put(pwm->clk);
err_free:
kfree(pwm);
- return ERR_PTR(ret);
-}
-
-static int __devinit pxa25x_pwm_probe(struct platform_device *pdev)
-{
- struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL);
-
- if (IS_ERR(pwm))
- return PTR_ERR(pwm);
-
- return 0;
-}
-
-static int __devinit pxa27x_pwm_probe(struct platform_device *pdev)
-{
- struct pwm_device *pwm;
-
- pwm = pwm_probe(pdev, pdev->id, NULL);
- if (IS_ERR(pwm))
- return PTR_ERR(pwm);
-
- pwm = pwm_probe(pdev, pdev->id + 2, pwm);
- if (IS_ERR(pwm))
- return PTR_ERR(pwm);
-
- return 0;
+ return ret;
}
static int __devexit pwm_remove(struct platform_device *pdev)
@@ -259,6 +259,12 @@ static int __devexit pwm_remove(struct platform_device *pdev)
return -ENODEV;
mutex_lock(&pwm_lock);
+
+ if (pwm->secondary) {
+ list_del(&pwm->secondary->node);
+ kfree(pwm->secondary);
+ }
+
list_del(&pwm->node);
mutex_unlock(&pwm_lock);
@@ -272,46 +278,25 @@ static int __devexit pwm_remove(struct platform_device *pdev)
return 0;
}
-static struct platform_driver pxa25x_pwm_driver = {
+static struct platform_driver pwm_driver = {
.driver = {
.name = "pxa25x-pwm",
+ .owner = THIS_MODULE,
},
- .probe = pxa25x_pwm_probe,
- .remove = __devexit_p(pwm_remove),
-};
-
-static struct platform_driver pxa27x_pwm_driver = {
- .driver = {
- .name = "pxa27x-pwm",
- },
- .probe = pxa27x_pwm_probe,
+ .probe = pwm_probe,
.remove = __devexit_p(pwm_remove),
+ .id_table = pwm_id_table,
};
static int __init pwm_init(void)
{
- int ret = 0;
-
- ret = platform_driver_register(&pxa25x_pwm_driver);
- if (ret) {
- printk(KERN_ERR "failed to register pxa25x_pwm_driver\n");
- return ret;
- }
-
- ret = platform_driver_register(&pxa27x_pwm_driver);
- if (ret) {
- printk(KERN_ERR "failed to register pxa27x_pwm_driver\n");
- return ret;
- }
-
- return ret;
+ return platform_driver_register(&pwm_driver);
}
arch_initcall(pwm_init);
static void __exit pwm_exit(void)
{
- platform_driver_unregister(&pxa25x_pwm_driver);
- platform_driver_unregister(&pxa27x_pwm_driver);
+ platform_driver_unregister(&pwm_driver);
}
module_exit(pwm_exit);
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
index de9383814e5e..a4c5027421d3 100644
--- a/arch/arm/plat-s3c/Kconfig
+++ b/arch/arm/plat-s3c/Kconfig
@@ -71,6 +71,15 @@ config S3C2410_PM_DEBUG
Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
for more information.
+config S3C_PM_DEBUG_LED_SMDK
+ bool "SMDK LED suspend/resume debugging"
+ depends on PM && (MACH_SMDK6410)
+ help
+ Say Y here to enable the use of the SMDK LEDs on the baseboard
+ for debugging of the state of the suspend and resume process.
+
+ Note, this currently only works for S3C64XX based SMDK boards.
+
config S3C2410_PM_CHECK
bool "S3C2410 PM Suspend Memory CRC"
depends on PM && CRC32
@@ -172,4 +181,9 @@ config S3C_DEV_FB
help
Compile in platform device definition for framebuffer
+config S3C_DEV_USB_HOST
+ bool
+ help
+ Compile in platform device definition for USB host.
+
endif
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile
index 8d7815d25a51..bfc8f537db18 100644
--- a/arch/arm/plat-s3c/Makefile
+++ b/arch/arm/plat-s3c/Makefile
@@ -21,6 +21,7 @@ obj-y += gpio-config.o
# PM support
obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += pm-gpio.o
obj-$(CONFIG_S3C2410_PM_CHECK) += pm-check.o
# devices
@@ -30,3 +31,4 @@ obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
obj-y += dev-i2c0.o
obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
+obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
diff --git a/arch/arm/plat-s3c/dev-usb.c b/arch/arm/plat-s3c/dev-usb.c
new file mode 100644
index 000000000000..2ee85abed6d9
--- /dev/null
+++ b/arch/arm/plat-s3c/dev-usb.c
@@ -0,0 +1,50 @@
+/* linux/arch/arm/plat-s3c/dev-usb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for USB host
+ *
+ * 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/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+
+static struct resource s3c_usb_resource[] = {
+ [0] = {
+ .start = S3C_PA_USBHOST,
+ .end = S3C_PA_USBHOST + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBH,
+ .end = IRQ_USBH,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_usb_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_usb = {
+ .name = "s3c2410-ohci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usb_resource),
+ .resource = s3c_usb_resource,
+ .dev = {
+ .dma_mask = &s3c_device_usb_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_usb);
diff --git a/arch/arm/plat-s3c/gpio.c b/arch/arm/plat-s3c/gpio.c
index d71dd6d9ce5c..260fdc6ad685 100644
--- a/arch/arm/plat-s3c/gpio.c
+++ b/arch/arm/plat-s3c/gpio.c
@@ -16,7 +16,7 @@
#include <linux/io.h>
#include <linux/gpio.h>
-#include <plat/gpio-core.h>
+#include <mach/gpio-core.h>
#ifdef CONFIG_S3C_GPIO_TRACK
struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
@@ -140,6 +140,15 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
if (!gc->get)
gc->get = s3c_gpiolib_get;
+#ifdef CONFIG_PM
+ if (chip->pm != NULL) {
+ if (!chip->pm->save || !chip->pm->resume)
+ printk(KERN_ERR "gpio: %s has missing PM functions\n",
+ gc->label);
+ } else
+ printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
+#endif
+
/* gpiochip_add() prints own failure message on error. */
ret = gpiochip_add(gc);
if (ret >= 0)
diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h
index e62ae0fcfe56..be541cbba070 100644
--- a/arch/arm/plat-s3c/include/plat/cpu.h
+++ b/arch/arm/plat-s3c/include/plat/cpu.h
@@ -69,3 +69,6 @@ extern struct sysdev_class s3c2412_sysclass;
extern struct sysdev_class s3c2440_sysclass;
extern struct sysdev_class s3c2442_sysclass;
extern struct sysdev_class s3c2443_sysclass;
+extern struct sysdev_class s3c6410_sysclass;
+extern struct sysdev_class s3c64xx_sysclass;
+
diff --git a/arch/arm/plat-s3c/include/plat/gpio-core.h b/arch/arm/plat-s3c/include/plat/gpio-core.h
index 2fc60a580ac8..32af612767aa 100644
--- a/arch/arm/plat-s3c/include/plat/gpio-core.h
+++ b/arch/arm/plat-s3c/include/plat/gpio-core.h
@@ -20,6 +20,18 @@
* specific code.
*/
+struct s3c_gpio_chip;
+
+/**
+ * struct s3c_gpio_pm - power management (suspend/resume) information
+ * @save: Routine to save the state of the GPIO block
+ * @resume: Routine to resume the GPIO block.
+ */
+struct s3c_gpio_pm {
+ void (*save)(struct s3c_gpio_chip *chip);
+ void (*resume)(struct s3c_gpio_chip *chip);
+};
+
struct s3c_gpio_cfg;
/**
@@ -27,6 +39,7 @@ struct s3c_gpio_cfg;
* @chip: The chip structure to be exported via gpiolib.
* @base: The base pointer to the gpio configuration registers.
* @config: special function and pull-resistor control information.
+ * @pm_save: Save information for suspend/resume support.
*
* This wrapper provides the necessary information for the Samsung
* specific gpios being registered with gpiolib.
@@ -34,7 +47,11 @@ struct s3c_gpio_cfg;
struct s3c_gpio_chip {
struct gpio_chip chip;
struct s3c_gpio_cfg *config;
+ struct s3c_gpio_pm *pm;
void __iomem *base;
+#ifdef CONFIG_PM
+ u32 pm_save[4];
+#endif
};
static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc)
@@ -75,3 +92,16 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { }
#endif
+
+#ifdef CONFIG_PM
+extern struct s3c_gpio_pm s3c_gpio_pm_1bit;
+extern struct s3c_gpio_pm s3c_gpio_pm_2bit;
+extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
+#define __gpio_pm(x) x
+#else
+#define s3c_gpio_pm_1bit NULL
+#define s3c_gpio_pm_2bit NULL
+#define s3c_gpio_pm_4bit NULL
+#define __gpio_pm(x) NULL
+
+#endif /* CONFIG_PM */
diff --git a/arch/arm/plat-s3c/include/plat/pm.h b/arch/arm/plat-s3c/include/plat/pm.h
index 3779775133a9..7a797192fcf3 100644
--- a/arch/arm/plat-s3c/include/plat/pm.h
+++ b/arch/arm/plat-s3c/include/plat/pm.h
@@ -44,6 +44,8 @@ extern void (*pm_cpu_sleep)(void);
extern unsigned long s3c_pm_flags;
+extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */
+
/* from sleep.S */
extern int s3c_cpu_save(unsigned long *saveblk);
@@ -88,6 +90,7 @@ struct pm_uart_save {
u32 ufcon;
u32 umcon;
u32 ubrdiv;
+ u32 udivslot;
};
/* helper functions to save/restore lists of registers. */
@@ -124,6 +127,18 @@ extern void s3c_pm_dbg(const char *msg, ...);
#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt)
#endif
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+/**
+ * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs
+ * @set: set bits for the state of the LEDs
+ * @clear: clear bits for the state of the LEDs.
+ */
+extern void s3c_pm_debug_smdkled(u32 set, u32 clear);
+
+#else
+static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { }
+#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */
+
/* suspend memory checking */
#ifdef CONFIG_S3C2410_PM_CHECK
diff --git a/arch/arm/plat-s3c/include/plat/regs-serial.h b/arch/arm/plat-s3c/include/plat/regs-serial.h
index 487d7d2a7e1d..66af75a5cdd1 100644
--- a/arch/arm/plat-s3c/include/plat/regs-serial.h
+++ b/arch/arm/plat-s3c/include/plat/regs-serial.h
@@ -189,6 +189,11 @@
#define S3C2443_DIVSLOT (0x2C)
+/* S3C64XX interrupt registers. */
+#define S3C64XX_UINTP 0x30
+#define S3C64XX_UINTSP 0x34
+#define S3C64XX_UINTM 0x38
+
#ifndef __ASSEMBLY__
/* struct s3c24xx_uart_clksrc
diff --git a/arch/arm/plat-s3c/pm-gpio.c b/arch/arm/plat-s3c/pm-gpio.c
new file mode 100644
index 000000000000..cfd326a8b693
--- /dev/null
+++ b/arch/arm/plat-s3c/pm-gpio.c
@@ -0,0 +1,380 @@
+
+/* linux/arch/arm/plat-s3c/pm-gpio.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO PM 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/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/gpio-core.h>
+#include <plat/pm.h>
+
+/* PM GPIO helpers */
+
+#define OFFS_CON (0x00)
+#define OFFS_DAT (0x04)
+#define OFFS_UP (0x08)
+
+static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip)
+{
+ chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
+ chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
+}
+
+static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip)
+{
+ void __iomem *base = chip->base;
+ u32 old_gpcon = __raw_readl(base + OFFS_CON);
+ u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+ u32 gps_gpcon = chip->pm_save[0];
+ u32 gps_gpdat = chip->pm_save[1];
+ u32 gpcon;
+
+ /* GPACON only has one bit per control / data and no PULLUPs.
+ * GPACON[x] = 0 => Output, 1 => SFN */
+
+ /* first set all SFN bits to SFN */
+
+ gpcon = old_gpcon | gps_gpcon;
+ __raw_writel(gpcon, base + OFFS_CON);
+
+ /* now set all the other bits */
+
+ __raw_writel(gps_gpdat, base + OFFS_DAT);
+ __raw_writel(gps_gpcon, base + OFFS_CON);
+
+ S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_1bit = {
+ .save = s3c_gpio_pm_1bit_save,
+ .resume = s3c_gpio_pm_1bit_resume,
+};
+
+static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip)
+{
+ chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
+ chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
+ chip->pm_save[2] = __raw_readl(chip->base + OFFS_UP);
+}
+
+/* Test whether the given masked+shifted bits of an GPIO configuration
+ * are one of the SFN (special function) modes. */
+
+static inline int is_sfn(unsigned long con)
+{
+ return con >= 2;
+}
+
+/* Test if the given masked+shifted GPIO configuration is an input */
+
+static inline int is_in(unsigned long con)
+{
+ return con == 0;
+}
+
+/* Test if the given masked+shifted GPIO configuration is an output */
+
+static inline int is_out(unsigned long con)
+{
+ return con == 1;
+}
+
+/**
+ * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank
+ * @chip: The chip information to resume.
+ *
+ * Restore one of the GPIO banks that was saved during suspend. This is
+ * not as simple as once thought, due to the possibility of glitches
+ * from the order that the CON and DAT registers are set in.
+ *
+ * The three states the pin can be are {IN,OUT,SFN} which gives us 9
+ * combinations of changes to check. Three of these, if the pin stays
+ * in the same configuration can be discounted. This leaves us with
+ * the following:
+ *
+ * { IN => OUT } Change DAT first
+ * { IN => SFN } Change CON first
+ * { OUT => SFN } Change CON first, so new data will not glitch
+ * { OUT => IN } Change CON first, so new data will not glitch
+ * { SFN => IN } Change CON first
+ * { SFN => OUT } Change DAT first, so new data will not glitch [1]
+ *
+ * We do not currently deal with the UP registers as these control
+ * weak resistors, so a small delay in change should not need to bring
+ * these into the calculations.
+ *
+ * [1] this assumes that writing to a pin DAT whilst in SFN will set the
+ * state for when it is next output.
+ */
+static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip)
+{
+ void __iomem *base = chip->base;
+ u32 old_gpcon = __raw_readl(base + OFFS_CON);
+ u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+ u32 gps_gpcon = chip->pm_save[0];
+ u32 gps_gpdat = chip->pm_save[1];
+ u32 gpcon, old, new, mask;
+ u32 change_mask = 0x0;
+ int nr;
+
+ /* restore GPIO pull-up settings */
+ __raw_writel(chip->pm_save[2], base + OFFS_UP);
+
+ /* Create a change_mask of all the items that need to have
+ * their CON value changed before their DAT value, so that
+ * we minimise the work between the two settings.
+ */
+
+ for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
+ old = (old_gpcon & mask) >> nr;
+ new = (gps_gpcon & mask) >> nr;
+
+ /* If there is no change, then skip */
+
+ if (old == new)
+ continue;
+
+ /* If both are special function, then skip */
+
+ if (is_sfn(old) && is_sfn(new))
+ continue;
+
+ /* Change is IN => OUT, do not change now */
+
+ if (is_in(old) && is_out(new))
+ continue;
+
+ /* Change is SFN => OUT, do not change now */
+
+ if (is_sfn(old) && is_out(new))
+ continue;
+
+ /* We should now be at the case of IN=>SFN,
+ * OUT=>SFN, OUT=>IN, SFN=>IN. */
+
+ change_mask |= mask;
+ }
+
+
+ /* Write the new CON settings */
+
+ gpcon = old_gpcon & ~change_mask;
+ gpcon |= gps_gpcon & change_mask;
+
+ __raw_writel(gpcon, base + OFFS_CON);
+
+ /* Now change any items that require DAT,CON */
+
+ __raw_writel(gps_gpdat, base + OFFS_DAT);
+ __raw_writel(gps_gpcon, base + OFFS_CON);
+
+ S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_2bit = {
+ .save = s3c_gpio_pm_2bit_save,
+ .resume = s3c_gpio_pm_2bit_resume,
+};
+
+#ifdef CONFIG_ARCH_S3C64XX
+static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
+{
+ chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
+ chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
+ chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);
+
+ if (chip->chip.ngpio > 8)
+ chip->pm_save[0] = __raw_readl(chip->base - 4);
+}
+
+static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
+{
+ u32 old, new, mask;
+ u32 change_mask = 0x0;
+ int nr;
+
+ for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) {
+ old = (old_gpcon & mask) >> nr;
+ new = (gps_gpcon & mask) >> nr;
+
+ /* If there is no change, then skip */
+
+ if (old == new)
+ continue;
+
+ /* If both are special function, then skip */
+
+ if (is_sfn(old) && is_sfn(new))
+ continue;
+
+ /* Change is IN => OUT, do not change now */
+
+ if (is_in(old) && is_out(new))
+ continue;
+
+ /* Change is SFN => OUT, do not change now */
+
+ if (is_sfn(old) && is_out(new))
+ continue;
+
+ /* We should now be at the case of IN=>SFN,
+ * OUT=>SFN, OUT=>IN, SFN=>IN. */
+
+ change_mask |= mask;
+ }
+
+ return change_mask;
+}
+
+static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index)
+{
+ void __iomem *con = chip->base + (index * 4);
+ u32 old_gpcon = __raw_readl(con);
+ u32 gps_gpcon = chip->pm_save[index + 1];
+ u32 gpcon, mask;
+
+ mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
+
+ gpcon = old_gpcon & ~mask;
+ gpcon |= gps_gpcon & mask;
+
+ __raw_writel(gpcon, con);
+}
+
+static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
+{
+ void __iomem *base = chip->base;
+ u32 old_gpcon[2];
+ u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+ u32 gps_gpdat = chip->pm_save[2];
+
+ /* First, modify the CON settings */
+
+ old_gpcon[0] = 0;
+ old_gpcon[1] = __raw_readl(base + OFFS_CON);
+
+ s3c_gpio_pm_4bit_con(chip, 0);
+ if (chip->chip.ngpio > 8) {
+ old_gpcon[0] = __raw_readl(base - 4);
+ s3c_gpio_pm_4bit_con(chip, -1);
+ }
+
+ /* Now change the configurations that require DAT,CON */
+
+ __raw_writel(chip->pm_save[2], base + OFFS_DAT);
+ __raw_writel(chip->pm_save[1], base + OFFS_CON);
+ if (chip->chip.ngpio > 8)
+ __raw_writel(chip->pm_save[0], base - 4);
+
+ __raw_writel(chip->pm_save[2], base + OFFS_DAT);
+ __raw_writel(chip->pm_save[3], base + OFFS_UP);
+
+ if (chip->chip.ngpio > 8) {
+ S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon[0], old_gpcon[1],
+ __raw_readl(base - 4),
+ __raw_readl(base + OFFS_CON),
+ old_gpdat, gps_gpdat);
+ } else
+ S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon[1],
+ __raw_readl(base + OFFS_CON),
+ old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_4bit = {
+ .save = s3c_gpio_pm_4bit_save,
+ .resume = s3c_gpio_pm_4bit_resume,
+};
+#endif /* CONFIG_ARCH_S3C64XX */
+
+/**
+ * s3c_pm_save_gpio() - save gpio chip data for suspend
+ * @ourchip: The chip for suspend.
+ */
+static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
+{
+ struct s3c_gpio_pm *pm = ourchip->pm;
+
+ if (pm == NULL || pm->save == NULL)
+ S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
+ else
+ pm->save(ourchip);
+}
+
+/**
+ * s3c_pm_save_gpios() - Save the state of the GPIO banks.
+ *
+ * For all the GPIO banks, save the state of each one ready for going
+ * into a suspend mode.
+ */
+void s3c_pm_save_gpios(void)
+{
+ struct s3c_gpio_chip *ourchip;
+ unsigned int gpio_nr;
+
+ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
+ ourchip = s3c_gpiolib_getchip(gpio_nr);
+ if (!ourchip)
+ continue;
+
+ s3c_pm_save_gpio(ourchip);
+
+ S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
+ ourchip->chip.label,
+ ourchip->pm_save[0],
+ ourchip->pm_save[1],
+ ourchip->pm_save[2],
+ ourchip->pm_save[3]);
+
+ gpio_nr += ourchip->chip.ngpio;
+ gpio_nr += CONFIG_S3C_GPIO_SPACE;
+ }
+}
+
+/**
+ * s3c_pm_resume_gpio() - restore gpio chip data after suspend
+ * @ourchip: The suspended chip.
+ */
+static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip)
+{
+ struct s3c_gpio_pm *pm = ourchip->pm;
+
+ if (pm == NULL || pm->resume == NULL)
+ S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
+ else
+ pm->resume(ourchip);
+}
+
+void s3c_pm_restore_gpios(void)
+{
+ struct s3c_gpio_chip *ourchip;
+ unsigned int gpio_nr;
+
+ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
+ ourchip = s3c_gpiolib_getchip(gpio_nr);
+ if (!ourchip)
+ continue;
+
+ s3c_pm_resume_gpio(ourchip);
+
+ gpio_nr += ourchip->chip.ngpio;
+ gpio_nr += CONFIG_S3C_GPIO_SPACE;
+ }
+}
diff --git a/arch/arm/plat-s3c/pm.c b/arch/arm/plat-s3c/pm.c
index 061182ca66e3..8d97db2c7a0d 100644
--- a/arch/arm/plat-s3c/pm.c
+++ b/arch/arm/plat-s3c/pm.c
@@ -21,11 +21,10 @@
#include <asm/cacheflush.h>
#include <mach/hardware.h>
+#include <mach/map.h>
#include <plat/regs-serial.h>
#include <mach/regs-clock.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-mem.h>
#include <mach/regs-irq.h>
#include <asm/irq.h>
@@ -70,6 +69,8 @@ static inline void s3c_pm_debug_init(void)
/* Save the UART configurations if we are configured for debug. */
+unsigned char pm_uart_udivslot;
+
#ifdef CONFIG_S3C2410_PM_DEBUG
struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
@@ -83,6 +84,12 @@ static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
save->ufcon = __raw_readl(regs + S3C2410_UFCON);
save->umcon = __raw_readl(regs + S3C2410_UMCON);
save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
+
+ if (pm_uart_udivslot)
+ save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
+
+ S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
+ uart, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
}
static void s3c_pm_save_uarts(void)
@@ -98,11 +105,16 @@ static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save)
{
void __iomem *regs = S3C_VA_UARTx(uart);
+ s3c_pm_arch_update_uart(regs, save);
+
__raw_writel(save->ulcon, regs + S3C2410_ULCON);
__raw_writel(save->ucon, regs + S3C2410_UCON);
__raw_writel(save->ufcon, regs + S3C2410_UFCON);
__raw_writel(save->umcon, regs + S3C2410_UMCON);
__raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
+
+ if (pm_uart_udivslot)
+ __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
}
static void s3c_pm_restore_uarts(void)
@@ -313,6 +325,9 @@ static int s3c_pm_enter(suspend_state_t state)
S3C_PMDBG("%s: post sleep, preparing to return\n", __func__);
+ /* LEDs should now be 1110 */
+ s3c_pm_debug_smdkled(1 << 1, 0);
+
s3c_pm_check_restore();
/* ok, let's return from sleep */
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 16ac01d9b8ab..4eb378c89a39 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -136,36 +136,6 @@ struct platform_device *s3c24xx_uart_src[4] = {
struct platform_device *s3c24xx_uart_devs[4] = {
};
-/* USB Host Controller */
-
-static struct resource s3c_usb_resource[] = {
- [0] = {
- .start = S3C24XX_PA_USBHOST,
- .end = S3C24XX_PA_USBHOST + S3C24XX_SZ_USBHOST - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_USBH,
- .end = IRQ_USBH,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static u64 s3c_device_usb_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_usb = {
- .name = "s3c2410-ohci",
- .id = -1,
- .num_resources = ARRAY_SIZE(s3c_usb_resource),
- .resource = s3c_usb_resource,
- .dev = {
- .dma_mask = &s3c_device_usb_dmamask,
- .coherent_dma_mask = 0xffffffffUL
- }
-};
-
-EXPORT_SYMBOL(s3c_device_usb);
-
/* LCD Controller */
static struct resource s3c_lcd_resource[] = {
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
index 5c0491bf738b..4bac12dc0733 100644
--- a/arch/arm/plat-s3c24xx/gpiolib.c
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -22,6 +22,7 @@
#include <mach/gpio-core.h>
#include <mach/hardware.h>
#include <asm/irq.h>
+#include <plat/pm.h>
#include <mach/regs-gpio.h>
@@ -78,6 +79,7 @@ static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
struct s3c_gpio_chip s3c24xx_gpios[] = {
[0] = {
.base = S3C24XX_GPIO_BASE(S3C2410_GPA0),
+ .pm = __gpio_pm(&s3c_gpio_pm_1bit),
.chip = {
.base = S3C2410_GPA0,
.owner = THIS_MODULE,
@@ -89,6 +91,7 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
},
[1] = {
.base = S3C24XX_GPIO_BASE(S3C2410_GPB0),
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
.chip = {
.base = S3C2410_GPB0,
.owner = THIS_MODULE,
@@ -98,6 +101,7 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
},
[2] = {
.base = S3C24XX_GPIO_BASE(S3C2410_GPC0),
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
.chip = {
.base = S3C2410_GPC0,
.owner = THIS_MODULE,
@@ -107,6 +111,7 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
},
[3] = {
.base = S3C24XX_GPIO_BASE(S3C2410_GPD0),
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
.chip = {
.base = S3C2410_GPD0,
.owner = THIS_MODULE,
@@ -116,6 +121,7 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
},
[4] = {
.base = S3C24XX_GPIO_BASE(S3C2410_GPE0),
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
.chip = {
.base = S3C2410_GPE0,
.label = "GPIOE",
@@ -125,6 +131,7 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
},
[5] = {
.base = S3C24XX_GPIO_BASE(S3C2410_GPF0),
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
.chip = {
.base = S3C2410_GPF0,
.owner = THIS_MODULE,
@@ -135,6 +142,7 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
},
[6] = {
.base = S3C24XX_GPIO_BASE(S3C2410_GPG0),
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
.chip = {
.base = S3C2410_GPG0,
.owner = THIS_MODULE,
diff --git a/arch/arm/plat-s3c24xx/include/plat/map.h b/arch/arm/plat-s3c24xx/include/plat/map.h
index eed8f78e7593..c4d133436fc7 100644
--- a/arch/arm/plat-s3c24xx/include/plat/map.h
+++ b/arch/arm/plat-s3c24xx/include/plat/map.h
@@ -58,7 +58,6 @@
#define S3C24XX_SZ_SPI SZ_1M
#define S3C24XX_SZ_SDI SZ_1M
#define S3C24XX_SZ_NAND SZ_1M
-#define S3C24XX_SZ_USBHOST SZ_1M
/* GPIO ports */
diff --git a/arch/arm/plat-s3c24xx/include/plat/pm-core.h b/arch/arm/plat-s3c24xx/include/plat/pm-core.h
index c75882113e04..fb45dd9adca5 100644
--- a/arch/arm/plat-s3c24xx/include/plat/pm-core.h
+++ b/arch/arm/plat-s3c24xx/include/plat/pm-core.h
@@ -57,3 +57,8 @@ static inline void s3c_pm_arch_show_resume_irqs(void)
s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
s3c_irqwake_eintmask);
}
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+}
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index 062a29339a91..5135c40a1b90 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -75,43 +75,10 @@ static struct sleep_save core_save[] = {
SAVE_ITEM(S3C2410_CLKSLOW),
};
-static struct gpio_sleep {
- void __iomem *base;
- unsigned int gpcon;
- unsigned int gpdat;
- unsigned int gpup;
-} gpio_save[] = {
- [0] = {
- .base = S3C2410_GPACON,
- },
- [1] = {
- .base = S3C2410_GPBCON,
- },
- [2] = {
- .base = S3C2410_GPCCON,
- },
- [3] = {
- .base = S3C2410_GPDCON,
- },
- [4] = {
- .base = S3C2410_GPECON,
- },
- [5] = {
- .base = S3C2410_GPFCON,
- },
- [6] = {
- .base = S3C2410_GPGCON,
- },
- [7] = {
- .base = S3C2410_GPHCON,
- },
-};
-
static struct sleep_save misc_save[] = {
SAVE_ITEM(S3C2410_DCLKCON),
};
-
/* s3c_pm_check_resume_pin
*
* check to see if the pin is configured correctly for sleep mode, and
@@ -165,186 +132,6 @@ void s3c_pm_configure_extint(void)
}
}
-/* offsets for CON/DAT/UP registers */
-
-#define OFFS_CON (S3C2410_GPACON - S3C2410_GPACON)
-#define OFFS_DAT (S3C2410_GPADAT - S3C2410_GPACON)
-#define OFFS_UP (S3C2410_GPBUP - S3C2410_GPBCON)
-
-/* s3c_pm_save_gpios()
- *
- * Save the state of the GPIOs
- */
-
-void s3c_pm_save_gpios(void)
-{
- struct gpio_sleep *gps = gpio_save;
- unsigned int gpio;
-
- for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) {
- void __iomem *base = gps->base;
-
- gps->gpcon = __raw_readl(base + OFFS_CON);
- gps->gpdat = __raw_readl(base + OFFS_DAT);
-
- if (gpio > 0)
- gps->gpup = __raw_readl(base + OFFS_UP);
-
- }
-}
-
-/* Test whether the given masked+shifted bits of an GPIO configuration
- * are one of the SFN (special function) modes. */
-
-static inline int is_sfn(unsigned long con)
-{
- return (con == 2 || con == 3);
-}
-
-/* Test if the given masked+shifted GPIO configuration is an input */
-
-static inline int is_in(unsigned long con)
-{
- return con == 0;
-}
-
-/* Test if the given masked+shifted GPIO configuration is an output */
-
-static inline int is_out(unsigned long con)
-{
- return con == 1;
-}
-
-/**
- * s3c2410_pm_restore_gpio() - restore the given GPIO bank
- * @index: The number of the GPIO bank being resumed.
- * @gps: The sleep confgiuration for the bank.
- *
- * Restore one of the GPIO banks that was saved during suspend. This is
- * not as simple as once thought, due to the possibility of glitches
- * from the order that the CON and DAT registers are set in.
- *
- * The three states the pin can be are {IN,OUT,SFN} which gives us 9
- * combinations of changes to check. Three of these, if the pin stays
- * in the same configuration can be discounted. This leaves us with
- * the following:
- *
- * { IN => OUT } Change DAT first
- * { IN => SFN } Change CON first
- * { OUT => SFN } Change CON first, so new data will not glitch
- * { OUT => IN } Change CON first, so new data will not glitch
- * { SFN => IN } Change CON first
- * { SFN => OUT } Change DAT first, so new data will not glitch [1]
- *
- * We do not currently deal with the UP registers as these control
- * weak resistors, so a small delay in change should not need to bring
- * these into the calculations.
- *
- * [1] this assumes that writing to a pin DAT whilst in SFN will set the
- * state for when it is next output.
- */
-
-static void s3c2410_pm_restore_gpio(int index, struct gpio_sleep *gps)
-{
- void __iomem *base = gps->base;
- unsigned long gps_gpcon = gps->gpcon;
- unsigned long gps_gpdat = gps->gpdat;
- unsigned long old_gpcon;
- unsigned long old_gpdat;
- unsigned long old_gpup = 0x0;
- unsigned long gpcon;
- int nr;
-
- old_gpcon = __raw_readl(base + OFFS_CON);
- old_gpdat = __raw_readl(base + OFFS_DAT);
-
- if (base == S3C2410_GPACON) {
- /* GPACON only has one bit per control / data and no PULLUPs.
- * GPACON[x] = 0 => Output, 1 => SFN */
-
- /* first set all SFN bits to SFN */
-
- gpcon = old_gpcon | gps->gpcon;
- __raw_writel(gpcon, base + OFFS_CON);
-
- /* now set all the other bits */
-
- __raw_writel(gps_gpdat, base + OFFS_DAT);
- __raw_writel(gps_gpcon, base + OFFS_CON);
- } else {
- unsigned long old, new, mask;
- unsigned long change_mask = 0x0;
-
- old_gpup = __raw_readl(base + OFFS_UP);
-
- /* Create a change_mask of all the items that need to have
- * their CON value changed before their DAT value, so that
- * we minimise the work between the two settings.
- */
-
- for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
- old = (old_gpcon & mask) >> nr;
- new = (gps_gpcon & mask) >> nr;
-
- /* If there is no change, then skip */
-
- if (old == new)
- continue;
-
- /* If both are special function, then skip */
-
- if (is_sfn(old) && is_sfn(new))
- continue;
-
- /* Change is IN => OUT, do not change now */
-
- if (is_in(old) && is_out(new))
- continue;
-
- /* Change is SFN => OUT, do not change now */
-
- if (is_sfn(old) && is_out(new))
- continue;
-
- /* We should now be at the case of IN=>SFN,
- * OUT=>SFN, OUT=>IN, SFN=>IN. */
-
- change_mask |= mask;
- }
-
- /* Write the new CON settings */
-
- gpcon = old_gpcon & ~change_mask;
- gpcon |= gps_gpcon & change_mask;
-
- __raw_writel(gpcon, base + OFFS_CON);
-
- /* Now change any items that require DAT,CON */
-
- __raw_writel(gps_gpdat, base + OFFS_DAT);
- __raw_writel(gps_gpcon, base + OFFS_CON);
- __raw_writel(gps->gpup, base + OFFS_UP);
- }
-
- S3C_PMDBG("GPIO[%d] CON %08lx => %08lx, DAT %08lx => %08lx\n",
- index, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
-}
-
-
-/** s3c2410_pm_restore_gpios()
- *
- * Restore the state of the GPIOs
- */
-
-void s3c_pm_restore_gpios(void)
-{
- struct gpio_sleep *gps = gpio_save;
- int gpio;
-
- for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) {
- s3c2410_pm_restore_gpio(gpio, gps);
- }
-}
void s3c_pm_restore_core(void)
{
diff --git a/arch/arm/plat-s3c64xx/Kconfig b/arch/arm/plat-s3c64xx/Kconfig
index 54375a00a7d2..ad48fd73e04d 100644
--- a/arch/arm/plat-s3c64xx/Kconfig
+++ b/arch/arm/plat-s3c64xx/Kconfig
@@ -19,6 +19,7 @@ config PLAT_S3C64XX
select S3C_GPIO_PULL_UPDOWN
select S3C_GPIO_CFG_S3C24XX
select S3C_GPIO_CFG_S3C64XX
+ select USB_ARCH_HAS_OHCI
help
Base platform code for any Samsung S3C64XX device
diff --git a/arch/arm/plat-s3c64xx/Makefile b/arch/arm/plat-s3c64xx/Makefile
index 2e6d79bf8f33..12ac7a50ab74 100644
--- a/arch/arm/plat-s3c64xx/Makefile
+++ b/arch/arm/plat-s3c64xx/Makefile
@@ -24,6 +24,12 @@ obj-y += gpiolib.o
obj-$(CONFIG_CPU_S3C6400_INIT) += s3c6400-init.o
obj-$(CONFIG_CPU_S3C6400_CLOCK) += s3c6400-clock.o
+# PM support
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += sleep.o
+obj-$(CONFIG_PM) += irq-pm.o
+
# Device setup
obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
diff --git a/arch/arm/plat-s3c64xx/cpu.c b/arch/arm/plat-s3c64xx/cpu.c
index 91f49a3a665d..f9fdaab32ab4 100644
--- a/arch/arm/plat-s3c64xx/cpu.c
+++ b/arch/arm/plat-s3c64xx/cpu.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
+#include <linux/sysdev.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/io.h>
@@ -104,6 +105,16 @@ static struct map_desc s3c_iodesc[] __initdata = {
},
};
+
+struct sysdev_class s3c64xx_sysclass = {
+ .name = "s3c64xx-core",
+};
+
+static struct sys_device s3c64xx_sysdev = {
+ .cls = &s3c64xx_sysclass,
+};
+
+
/* read cpu identification code */
void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
@@ -117,3 +128,11 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
idcode = __raw_readl(S3C_VA_SYS + 0x118);
s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
}
+
+static __init int s3c64xx_sysdev_init(void)
+{
+ sysdev_class_register(&s3c64xx_sysclass);
+ return sysdev_register(&s3c64xx_sysdev);
+}
+
+core_initcall(s3c64xx_sysdev_init);
diff --git a/arch/arm/plat-s3c64xx/gpiolib.c b/arch/arm/plat-s3c64xx/gpiolib.c
index ee9188add8fb..ccb82e854962 100644
--- a/arch/arm/plat-s3c64xx/gpiolib.c
+++ b/arch/arm/plat-s3c64xx/gpiolib.c
@@ -385,12 +385,19 @@ static __init void s3c64xx_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
{
chip->chip.direction_input = s3c64xx_gpiolib_4bit_input;
chip->chip.direction_output = s3c64xx_gpiolib_4bit_output;
+ chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
}
static __init void s3c64xx_gpiolib_add_4bit2(struct s3c_gpio_chip *chip)
{
chip->chip.direction_input = s3c64xx_gpiolib_4bit2_input;
chip->chip.direction_output = s3c64xx_gpiolib_4bit2_output;
+ chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
+}
+
+static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
+{
+ chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
}
static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
@@ -412,7 +419,8 @@ static __init int s3c64xx_gpiolib_init(void)
s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
s3c64xx_gpiolib_add_4bit2);
- s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit), NULL);
+ s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
+ s3c64xx_gpiolib_add_2bit);
return 0;
}
diff --git a/arch/arm/plat-s3c64xx/include/plat/irqs.h b/arch/arm/plat-s3c64xx/include/plat/irqs.h
index f865bf4d709e..743a70094d04 100644
--- a/arch/arm/plat-s3c64xx/include/plat/irqs.h
+++ b/arch/arm/plat-s3c64xx/include/plat/irqs.h
@@ -157,6 +157,7 @@
#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE)
#define IRQ_EINT(x) S3C_EINT(x)
+#define IRQ_EINT_BIT(x) ((x) - S3C_EINT(0))
/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
* that they are sourced from the GPIO pins but with a different scheme for
diff --git a/arch/arm/plat-s3c64xx/include/plat/pm-core.h b/arch/arm/plat-s3c64xx/include/plat/pm-core.h
new file mode 100644
index 000000000000..d347de3ba0dc
--- /dev/null
+++ b/arch/arm/plat-s3c64xx/include/plat/pm-core.h
@@ -0,0 +1,98 @@
+/* linux/arch/arm/plat-s3c64xx/include/plat/pm-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - PM core support for arch/arm/plat-s3c/pm.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 <plat/regs-gpio.h>
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ u32 tmp = __raw_readl(S3C_PCLK_GATE);
+
+ /* As a note, since the S3C64XX UARTs generally have multiple
+ * clock sources, we simply enable PCLK at the moment and hope
+ * that the resume settings for the UART are suitable for the
+ * use with PCLK.
+ */
+
+ tmp |= S3C_CLKCON_PCLK_UART0;
+ tmp |= S3C_CLKCON_PCLK_UART1;
+ tmp |= S3C_CLKCON_PCLK_UART2;
+ tmp |= S3C_CLKCON_PCLK_UART3;
+
+ __raw_writel(tmp, S3C_PCLK_GATE);
+ udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+ /* VIC should have already been taken care of */
+
+ /* clear any pending EINT0 interrupts */
+ __raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+}
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+}
+
+/* make these defines, we currently do not have any need to change
+ * the IRQ wake controls depending on the CPU we are running on */
+
+#define s3c_irqwake_eintallow ((1 << 28) - 1)
+#define s3c_irqwake_intallow (0)
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+ u32 ucon = __raw_readl(regs + S3C2410_UCON);
+ u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
+ u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
+ u32 new_ucon;
+ u32 delta;
+
+ /* S3C64XX UART blocks only support level interrupts, so ensure that
+ * when we restore unused UART blocks we force the level interrupt
+ * settigs. */
+ save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
+
+ /* We have a constraint on changing the clock type of the UART
+ * between UCLKx and PCLK, so ensure that when we restore UCON
+ * that the CLK field is correctly modified if the bootloader
+ * has changed anything.
+ */
+ if (ucon_clk != save_clk) {
+ new_ucon = save->ucon;
+ delta = ucon_clk ^ save_clk;
+
+ /* change from UCLKx => wrong PCLK,
+ * either UCLK can be tested for by a bit-test
+ * with UCLK0 */
+ if (ucon_clk & S3C6400_UCON_UCLK0 &&
+ !(save_clk & S3C6400_UCON_UCLK0) &&
+ delta & S3C6400_UCON_PCLK2) {
+ new_ucon &= ~S3C6400_UCON_UCLK0;
+ } else if (delta == S3C6400_UCON_PCLK2) {
+ /* as an precaution, don't change from
+ * PCLK2 => PCLK or vice-versa */
+ new_ucon ^= S3C6400_UCON_PCLK2;
+ }
+
+ S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
+ ucon, new_ucon, save->ucon);
+ save->ucon = new_ucon;
+ }
+}
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-clock.h b/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
index b1082c163247..52836d41e333 100644
--- a/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
+++ b/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
@@ -32,6 +32,7 @@
#define S3C_HCLK_GATE S3C_CLKREG(0x30)
#define S3C_PCLK_GATE S3C_CLKREG(0x34)
#define S3C_SCLK_GATE S3C_CLKREG(0x38)
+#define S3C_MEM0_GATE S3C_CLKREG(0x3C)
/* CLKDIV0 */
#define S3C6400_CLKDIV0_MFC_MASK (0xf << 28)
diff --git a/arch/arm/plat-s3c64xx/irq-eint.c b/arch/arm/plat-s3c64xx/irq-eint.c
index 47e5155bb13e..f81b7b818ba0 100644
--- a/arch/arm/plat-s3c64xx/irq-eint.c
+++ b/arch/arm/plat-s3c64xx/irq-eint.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
+#include <linux/sysdev.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/io.h>
@@ -26,6 +27,7 @@
#include <mach/map.h>
#include <plat/cpu.h>
+#include <plat/pm.h>
#define eint_offset(irq) ((irq) - IRQ_EINT(0))
#define eint_irq_to_bit(irq) (1 << eint_offset(irq))
@@ -134,6 +136,7 @@ static struct irq_chip s3c_irq_eint = {
.mask_ack = s3c_irq_eint_maskack,
.ack = s3c_irq_eint_ack,
.set_type = s3c_irq_eint_set_type,
+ .set_wake = s3c_irqext_wake,
};
/* s3c_irq_demux_eint
diff --git a/arch/arm/plat-s3c64xx/irq-pm.c b/arch/arm/plat-s3c64xx/irq-pm.c
new file mode 100644
index 000000000000..ca523b5d4c17
--- /dev/null
+++ b/arch/arm/plat-s3c64xx/irq-pm.c
@@ -0,0 +1,111 @@
+/* arch/arm/plat-s3c64xx/irq-pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling Power Management
+ *
+ * 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/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/serial_core.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/regs-serial.h>
+#include <plat/regs-timer.h>
+#include <plat/regs-gpio.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+/* We handled all the IRQ types in this code, to save having to make several
+ * small files to handle each different type separately. Having the EINT_GRP
+ * code here shouldn't be as much bloat as the IRQ table space needed when
+ * they are enabled. The added benefit is we ensure that these registers are
+ * in the same state as we suspended.
+ */
+
+static struct sleep_save irq_save[] = {
+ SAVE_ITEM(S3C64XX_PRIORITY),
+ SAVE_ITEM(S3C64XX_EINT0CON0),
+ SAVE_ITEM(S3C64XX_EINT0CON1),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON0),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON1),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON2),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON3),
+ SAVE_ITEM(S3C64XX_EINT0MASK),
+ SAVE_ITEM(S3C64XX_TINT_CSTAT),
+};
+
+static struct irq_grp_save {
+ u32 fltcon;
+ u32 con;
+ u32 mask;
+} eint_grp_save[5];
+
+static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static int s3c64xx_irq_pm_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct irq_grp_save *grp = eint_grp_save;
+ int i;
+
+ S3C_PMDBG("%s: suspending IRQs\n", __func__);
+
+ s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+
+ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+ irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+ grp->con = __raw_readl(S3C64XX_EINT12CON + (i * 4));
+ grp->mask = __raw_readl(S3C64XX_EINT12MASK + (i * 4));
+ grp->fltcon = __raw_readl(S3C64XX_EINT12FLTCON + (i * 4));
+ }
+
+ return 0;
+}
+
+static int s3c64xx_irq_pm_resume(struct sys_device *dev)
+{
+ struct irq_grp_save *grp = eint_grp_save;
+ int i;
+
+ S3C_PMDBG("%s: resuming IRQs\n", __func__);
+
+ s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+
+ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+ __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+ __raw_writel(grp->con, S3C64XX_EINT12CON + (i * 4));
+ __raw_writel(grp->mask, S3C64XX_EINT12MASK + (i * 4));
+ __raw_writel(grp->fltcon, S3C64XX_EINT12FLTCON + (i * 4));
+ }
+
+ S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
+ return 0;
+}
+
+static struct sysdev_driver s3c64xx_irq_driver = {
+ .suspend = s3c64xx_irq_pm_suspend,
+ .resume = s3c64xx_irq_pm_resume,
+};
+
+static int __init s3c64xx_irq_pm_init(void)
+{
+ return sysdev_driver_register(&s3c64xx_sysclass, &s3c64xx_irq_driver);
+}
+
+arch_initcall(s3c64xx_irq_pm_init);
+
diff --git a/arch/arm/plat-s3c64xx/irq.c b/arch/arm/plat-s3c64xx/irq.c
index f22edf7c2d2d..8dc5b6da9789 100644
--- a/arch/arm/plat-s3c64xx/irq.c
+++ b/arch/arm/plat-s3c64xx/irq.c
@@ -14,12 +14,14 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
+#include <linux/serial_core.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/hardware/vic.h>
#include <mach/map.h>
+#include <plat/regs-serial.h>
#include <plat/regs-timer.h>
#include <plat/cpu.h>
@@ -135,9 +137,6 @@ static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
}
/* UART interrupt registers, not worth adding to seperate include header */
-#define S3C64XX_UINTP 0x30
-#define S3C64XX_UINTSP 0x34
-#define S3C64XX_UINTM 0x38
static void s3c_irq_uart_mask(unsigned int irq)
{
@@ -233,8 +232,8 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
/* initialise the pair of VICs */
- vic_init(S3C_VA_VIC0, S3C_VIC0_BASE, vic0_valid);
- vic_init(S3C_VA_VIC1, S3C_VIC1_BASE, vic1_valid);
+ vic_init(S3C_VA_VIC0, S3C_VIC0_BASE, vic0_valid, 0);
+ vic_init(S3C_VA_VIC1, S3C_VIC1_BASE, vic1_valid, 0);
/* add the timer sub-irqs */
diff --git a/arch/arm/plat-s3c64xx/pm.c b/arch/arm/plat-s3c64xx/pm.c
new file mode 100644
index 000000000000..07a6516a4f3c
--- /dev/null
+++ b/arch/arm/plat-s3c64xx/pm.c
@@ -0,0 +1,175 @@
+/* linux/arch/arm/plat-s3c64xx/pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU PM support.
+ *
+ * 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/init.h>
+#include <linux/suspend.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/pm.h>
+#include <plat/regs-sys.h>
+#include <plat/regs-gpio.h>
+#include <plat/regs-clock.h>
+#include <plat/regs-syscon-power.h>
+#include <plat/regs-gpio-memport.h>
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+#include <plat/gpio-bank-n.h>
+
+void s3c_pm_debug_smdkled(u32 set, u32 clear)
+{
+ unsigned long flags;
+ u32 reg;
+
+ local_irq_save(flags);
+ reg = __raw_readl(S3C64XX_GPNCON);
+ reg &= ~(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) |
+ S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15));
+ reg |= S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) |
+ S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15);
+ __raw_writel(reg, S3C64XX_GPNCON);
+
+ reg = __raw_readl(S3C64XX_GPNDAT);
+ reg &= ~(clear << 12);
+ reg |= set << 12;
+ __raw_writel(reg, S3C64XX_GPNDAT);
+
+ local_irq_restore(flags);
+}
+#endif
+
+static struct sleep_save core_save[] = {
+ SAVE_ITEM(S3C_APLL_LOCK),
+ SAVE_ITEM(S3C_MPLL_LOCK),
+ SAVE_ITEM(S3C_EPLL_LOCK),
+ SAVE_ITEM(S3C_CLK_SRC),
+ SAVE_ITEM(S3C_CLK_DIV0),
+ SAVE_ITEM(S3C_CLK_DIV1),
+ SAVE_ITEM(S3C_CLK_DIV2),
+ SAVE_ITEM(S3C_CLK_OUT),
+ SAVE_ITEM(S3C_HCLK_GATE),
+ SAVE_ITEM(S3C_PCLK_GATE),
+ SAVE_ITEM(S3C_SCLK_GATE),
+ SAVE_ITEM(S3C_MEM0_GATE),
+
+ SAVE_ITEM(S3C_EPLL_CON1),
+ SAVE_ITEM(S3C_EPLL_CON0),
+
+ SAVE_ITEM(S3C64XX_MEM0DRVCON),
+ SAVE_ITEM(S3C64XX_MEM1DRVCON),
+
+#ifndef CONFIG_CPU_FREQ
+ SAVE_ITEM(S3C_APLL_CON),
+ SAVE_ITEM(S3C_MPLL_CON),
+#endif
+};
+
+static struct sleep_save misc_save[] = {
+ SAVE_ITEM(S3C64XX_AHB_CON0),
+ SAVE_ITEM(S3C64XX_AHB_CON1),
+ SAVE_ITEM(S3C64XX_AHB_CON2),
+
+ SAVE_ITEM(S3C64XX_SPCON),
+
+ SAVE_ITEM(S3C64XX_MEM0CONSTOP),
+ SAVE_ITEM(S3C64XX_MEM1CONSTOP),
+ SAVE_ITEM(S3C64XX_MEM0CONSLP0),
+ SAVE_ITEM(S3C64XX_MEM0CONSLP1),
+ SAVE_ITEM(S3C64XX_MEM1CONSLP),
+};
+
+void s3c_pm_configure_extint(void)
+{
+ __raw_writel(s3c_irqwake_eintmask, S3C64XX_EINT_MASK);
+}
+
+void s3c_pm_restore_core(void)
+{
+ __raw_writel(0, S3C64XX_EINT_MASK);
+
+ s3c_pm_debug_smdkled(1 << 2, 0);
+
+ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+ s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
+}
+
+void s3c_pm_save_core(void)
+{
+ s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
+ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
+}
+
+/* since both s3c6400 and s3c6410 share the same sleep pm calls, we
+ * put the per-cpu code in here until any new cpu comes along and changes
+ * this.
+ */
+
+#include <plat/regs-gpio.h>
+
+static void s3c64xx_cpu_suspend(void)
+{
+ unsigned long tmp;
+
+ /* set our standby method to sleep */
+
+ tmp = __raw_readl(S3C64XX_PWR_CFG);
+ tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
+ tmp |= S3C64XX_PWRCFG_CFG_WFI_SLEEP;
+ __raw_writel(tmp, S3C64XX_PWR_CFG);
+
+ /* clear any old wakeup */
+
+ __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT),
+ S3C64XX_WAKEUP_STAT);
+
+ /* set the LED state to 0110 over sleep */
+ s3c_pm_debug_smdkled(3 << 1, 0xf);
+
+ /* issue the standby signal into the pm unit. Note, we
+ * issue a write-buffer drain just in case */
+
+ tmp = 0;
+
+ asm("b 1f\n\t"
+ ".align 5\n\t"
+ "1:\n\t"
+ "mcr p15, 0, %0, c7, c10, 5\n\t"
+ "mcr p15, 0, %0, c7, c10, 4\n\t"
+ "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
+
+ /* we should never get past here */
+
+ panic("sleep resumed to originator?");
+}
+
+static void s3c64xx_pm_prepare(void)
+{
+ /* store address of resume. */
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C64XX_INFORM0);
+
+ /* ensure previous wakeup state is cleared before sleeping */
+ __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT);
+}
+
+static int s3c64xx_pm_init(void)
+{
+ pm_cpu_prep = s3c64xx_pm_prepare;
+ pm_cpu_sleep = s3c64xx_cpu_suspend;
+ pm_uart_udivslot = 1;
+ return 0;
+}
+
+arch_initcall(s3c64xx_pm_init);
diff --git a/arch/arm/plat-s3c64xx/sleep.S b/arch/arm/plat-s3c64xx/sleep.S
new file mode 100644
index 000000000000..8e71fe90a373
--- /dev/null
+++ b/arch/arm/plat-s3c64xx/sleep.S
@@ -0,0 +1,144 @@
+/* linux/0arch/arm/plat-s3c64xx/sleep.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU sleep 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/linkage.h>
+#include <asm/assembler.h>
+#include <mach/map.h>
+
+#undef S3C64XX_VA_GPIO
+#define S3C64XX_VA_GPIO (0x0)
+
+#include <plat/regs-gpio.h>
+#include <plat/gpio-bank-n.h>
+
+#define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT))
+
+ .text
+
+ /* s3c_cpu_save
+ *
+ * Save enough processor state to allow the restart of the pm.c
+ * code after resume.
+ *
+ * entry:
+ * r0 = pointer to the save block
+ */
+
+ENTRY(s3c_cpu_save)
+ stmfd sp!, { r4 - r12, lr }
+
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
+ mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
+ mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
+ mrc p15, 0, r9, c1, c0, 0 @ Control register
+ mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
+
+ stmia r0, { r4 - r13 } @ Save CP registers and SP
+
+ @@ save our state to ram
+ bl s3c_pm_cb_flushcache
+
+ @@ call final suspend code
+ ldr r0, =pm_cpu_sleep
+ ldr pc, [r0]
+
+ @@ return to the caller, after the MMU is turned on.
+ @@ restore the last bits of the stack and return.
+resume_with_mmu:
+ ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save
+
+ .data
+
+ /* the next bit is code, but it requires easy access to the
+ * s3c_sleep_save_phys data before the MMU is switched on, so
+ * we store the code that needs this variable in the .data where
+ * the value can be written to (the .text segment is RO).
+ */
+
+ .global s3c_sleep_save_phys
+s3c_sleep_save_phys:
+ .word 0
+
+ /* Sleep magic, the word before the resume entry point so that the
+ * bootloader can check for a resumeable image. */
+
+ .word 0x2bedf00d
+
+ /* s3c_cpu_reusme
+ *
+ * This is the entry point, stored by whatever method the bootloader
+ * requires to get the kernel runnign again. This code expects to be
+ * entered with no caches live and the MMU disabled. It will then
+ * restore the MMU and other basic CP registers saved and restart
+ * the kernel C code to finish the resume code.
+ */
+
+ENTRY(s3c_cpu_resume)
+ msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ ldr r2, =LL_UART /* for debug */
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+ /* Initialise the GPIO state if we are debugging via the SMDK LEDs,
+ * as the uboot version supplied resets these to inputs during the
+ * resume checks.
+ */
+
+ ldr r3, =S3C64XX_PA_GPIO
+ ldr r0, [ r3, #S3C64XX_GPNCON ]
+ bic r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \
+ S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15))
+ orr r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \
+ S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15))
+ str r0, [ r3, #S3C64XX_GPNCON ]
+
+ ldr r0, [ r3, #S3C64XX_GPNDAT ]
+ bic r0, r0, #0xf << 12 @ GPN12..15
+ orr r0, r0, #1 << 15 @ GPN15
+ str r0, [ r3, #S3C64XX_GPNDAT ]
+#endif
+
+ /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
+ * are thoroughly cleaned just in case the bootloader didn't do it
+ * for us. */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ @@mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
+ @@mcr p15, 0, r0, c7, c7, 0 @ Invalidate I + D caches
+
+ ldr r0, s3c_sleep_save_phys
+ ldmia r0, { r4 - r13 }
+
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
+ mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
+ mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
+ mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+
+ mov r0, #0 @ restore copro access controls
+ mcr p15, 0, r11, c1, c0, 2 @ Co-processor access controls
+ mcr p15, 0, r0, c7, c5, 4
+
+ ldr r2, =resume_with_mmu
+ mcr p15, 0, r9, c1, c0, 0 /* turn mmu back on */
+ nop
+ mov pc, r2 /* jump back */
+
+ .end
diff --git a/arch/arm/plat-stmp3xxx/Kconfig b/arch/arm/plat-stmp3xxx/Kconfig
new file mode 100644
index 000000000000..2cf37c35951b
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/Kconfig
@@ -0,0 +1,37 @@
+if ARCH_STMP3XXX
+
+menu "Freescale STMP3xxx implementations"
+
+choice
+ prompt "Select STMP3xxx chip family"
+
+config ARCH_STMP37XX
+ bool "Freescale SMTP37xx"
+ select CPU_ARM926T
+ ---help---
+ STMP37xx refers to 3700 through 3769 chips
+
+config ARCH_STMP378X
+ bool "Freescale STMP378x"
+ select CPU_ARM926T
+ ---help---
+ STMP378x refers to 3780 through 3789 chips
+
+endchoice
+
+choice
+ prompt "Select STMP3xxx board type"
+
+config MACH_STMP37XX
+ depends on ARCH_STMP37XX
+ bool "Freescale STMP37xx development board"
+
+config MACH_STMP378X
+ depends on ARCH_STMP378X
+ bool "Freescale STMP378x development board"
+
+endchoice
+
+endmenu
+
+endif
diff --git a/arch/arm/plat-stmp3xxx/Makefile b/arch/arm/plat-stmp3xxx/Makefile
new file mode 100644
index 000000000000..b63480066d6b
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the linux kernel.
+#
+# Object file lists.
+obj-y += core.o timer.o irq.o dma.o clock.o pinmux.o
diff --git a/arch/arm/plat-stmp3xxx/clock.c b/arch/arm/plat-stmp3xxx/clock.c
new file mode 100644
index 000000000000..9a1d46b470cd
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/clock.c
@@ -0,0 +1,1112 @@
+/*
+ * Clock manipulation routines for Freescale STMP37XX/STMP378X
+ *
+ * Author: Vitaly Wool <vital@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+#include <asm/clkdev.h>
+#include <mach/regs-clkctrl.h>
+
+#include "clock.h"
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static struct clk osc_24M;
+static struct clk pll_clk;
+static struct clk cpu_clk;
+static struct clk hclk;
+
+static int propagate_rate(struct clk *);
+
+static inline int clk_is_busy(struct clk *clk)
+{
+ return __raw_readl(clk->busy_reg) & (1 << clk->busy_bit);
+}
+
+static inline int clk_good(struct clk *clk)
+{
+ return clk && !IS_ERR(clk) && clk->ops;
+}
+
+static int std_clk_enable(struct clk *clk)
+{
+ if (clk->enable_reg) {
+ u32 clk_reg = __raw_readl(clk->enable_reg);
+ if (clk->enable_negate)
+ clk_reg &= ~(1 << clk->enable_shift);
+ else
+ clk_reg |= (1 << clk->enable_shift);
+ __raw_writel(clk_reg, clk->enable_reg);
+ if (clk->enable_wait)
+ udelay(clk->enable_wait);
+ return 0;
+ } else
+ return -EINVAL;
+}
+
+static int std_clk_disable(struct clk *clk)
+{
+ if (clk->enable_reg) {
+ u32 clk_reg = __raw_readl(clk->enable_reg);
+ if (clk->enable_negate)
+ clk_reg |= (1 << clk->enable_shift);
+ else
+ clk_reg &= ~(1 << clk->enable_shift);
+ __raw_writel(clk_reg, clk->enable_reg);
+ return 0;
+ } else
+ return -EINVAL;
+}
+
+static int io_set_rate(struct clk *clk, u32 rate)
+{
+ u32 reg_frac, clkctrl_frac;
+ int i, ret = 0, mask = 0x1f;
+
+ clkctrl_frac = (clk->parent->rate * 18 + rate - 1) / rate;
+
+ if (clkctrl_frac < 18 || clkctrl_frac > 35) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ reg_frac = __raw_readl(clk->scale_reg);
+ reg_frac &= ~(mask << clk->scale_shift);
+ __raw_writel(reg_frac | (clkctrl_frac << clk->scale_shift),
+ clk->scale_reg);
+ if (clk->busy_reg) {
+ for (i = 10000; i; i--)
+ if (!clk_is_busy(clk))
+ break;
+ if (!i)
+ ret = -ETIMEDOUT;
+ else
+ ret = 0;
+ }
+out:
+ return ret;
+}
+
+static long io_get_rate(struct clk *clk)
+{
+ long rate = clk->parent->rate * 18;
+ int mask = 0x1f;
+
+ rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask;
+ clk->rate = rate;
+
+ return rate;
+}
+
+static long per_get_rate(struct clk *clk)
+{
+ long rate = clk->parent->rate;
+ long div;
+ const int mask = 0xff;
+
+ if (clk->enable_reg &&
+ !(__raw_readl(clk->enable_reg) & clk->enable_shift))
+ clk->rate = 0;
+ else {
+ div = (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask;
+ if (div)
+ rate /= div;
+ clk->rate = rate;
+ }
+
+ return clk->rate;
+}
+
+static int per_set_rate(struct clk *clk, u32 rate)
+{
+ int ret = -EINVAL;
+ int div = (clk->parent->rate + rate - 1) / rate;
+ u32 reg_frac;
+ const int mask = 0xff;
+ int try = 10;
+ int i = -1;
+
+ if (div == 0 || div > mask)
+ goto out;
+
+ reg_frac = __raw_readl(clk->scale_reg);
+ reg_frac &= ~(mask << clk->scale_shift);
+
+ while (try--) {
+ __raw_writel(reg_frac | (div << clk->scale_shift),
+ clk->scale_reg);
+
+ if (clk->busy_reg) {
+ for (i = 10000; i; i--)
+ if (!clk_is_busy(clk))
+ break;
+ }
+ if (i)
+ break;
+ }
+
+ if (!i)
+ ret = -ETIMEDOUT;
+ else
+ ret = 0;
+
+out:
+ if (ret != 0)
+ printk(KERN_ERR "%s: error %d\n", __func__, ret);
+ return ret;
+}
+
+static long lcdif_get_rate(struct clk *clk)
+{
+ long rate = clk->parent->rate;
+ long div;
+ const int mask = 0xff;
+
+ div = (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask;
+ if (div) {
+ rate /= div;
+ div = (HW_CLKCTRL_FRAC_RD() & BM_CLKCTRL_FRAC_PIXFRAC) >>
+ BP_CLKCTRL_FRAC_PIXFRAC;
+ rate /= div;
+ }
+ clk->rate = rate;
+
+ return rate;
+}
+
+static int lcdif_set_rate(struct clk *clk, u32 rate)
+{
+ int ret = 0;
+ /*
+ * On 3700, we can get most timings exact by modifying ref_pix
+ * and the divider, but keeping the phase timings at 1 (2
+ * phases per cycle).
+ *
+ * ref_pix can be between 480e6*18/35=246.9MHz and 480e6*18/18=480MHz,
+ * which is between 18/(18*480e6)=2.084ns and 35/(18*480e6)=4.050ns.
+ *
+ * ns_cycle >= 2*18e3/(18*480) = 25/6
+ * ns_cycle <= 2*35e3/(18*480) = 875/108
+ *
+ * Multiply the ns_cycle by 'div' to lengthen it until it fits the
+ * bounds. This is the divider we'll use after ref_pix.
+ *
+ * 6 * ns_cycle >= 25 * div
+ * 108 * ns_cycle <= 875 * div
+ */
+ u32 ns_cycle = 1000000 / rate;
+ u32 div, reg_val;
+ u32 lowest_result = (u32) -1;
+ u32 lowest_div = 0, lowest_fracdiv = 0;
+
+ for (div = 1; div < 256; ++div) {
+ u32 fracdiv;
+ u32 ps_result;
+ int lower_bound = 6 * ns_cycle >= 25 * div;
+ int upper_bound = 108 * ns_cycle <= 875 * div;
+ if (!lower_bound)
+ break;
+ if (!upper_bound)
+ continue;
+ /*
+ * Found a matching div. Calculate fractional divider needed,
+ * rounded up.
+ */
+ fracdiv = ((clk->parent->rate / 1000 * 18 / 2) *
+ ns_cycle + 1000 * div - 1) /
+ (1000 * div);
+ if (fracdiv < 18 || fracdiv > 35) {
+ ret = -EINVAL;
+ goto out;
+ }
+ /* Calculate the actual cycle time this results in */
+ ps_result = 6250 * div * fracdiv / 27;
+
+ /* Use the fastest result that doesn't break ns_cycle */
+ if (ps_result <= lowest_result) {
+ lowest_result = ps_result;
+ lowest_div = div;
+ lowest_fracdiv = fracdiv;
+ }
+ }
+
+ if (div >= 256 || lowest_result == (u32) -1) {
+ ret = -EINVAL;
+ goto out;
+ }
+ pr_debug("Programming PFD=%u,DIV=%u ref_pix=%uMHz "
+ "PIXCLK=%uMHz cycle=%u.%03uns\n",
+ lowest_fracdiv, lowest_div,
+ 480*18/lowest_fracdiv, 480*18/lowest_fracdiv/lowest_div,
+ lowest_result / 1000, lowest_result % 1000);
+
+ /* Program ref_pix phase fractional divider */
+ HW_CLKCTRL_FRAC_WR((HW_CLKCTRL_FRAC_RD() & ~BM_CLKCTRL_FRAC_PIXFRAC) |
+ BF_CLKCTRL_FRAC_PIXFRAC(lowest_fracdiv));
+ /* Ungate PFD */
+ HW_CLKCTRL_FRAC_CLR(BM_CLKCTRL_FRAC_CLKGATEPIX);
+
+ /* Program pix divider */
+ reg_val = __raw_readl(clk->scale_reg);
+ reg_val &= ~(BM_CLKCTRL_PIX_DIV | BM_CLKCTRL_PIX_CLKGATE);
+ reg_val |= BF_CLKCTRL_PIX_DIV(lowest_div);
+ __raw_writel(reg_val, clk->scale_reg);
+
+ /* Wait for divider update */
+ if (clk->busy_reg) {
+ int i;
+ for (i = 10000; i; i--)
+ if (!clk_is_busy(clk))
+ break;
+ if (!i) {
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+ }
+
+ /* Switch to ref_pix source */
+ HW_CLKCTRL_CLKSEQ_CLR(BM_CLKCTRL_CLKSEQ_BYPASS_PIX);
+
+out:
+ return ret;
+}
+
+
+static int cpu_set_rate(struct clk *clk, u32 rate)
+{
+ if (rate < 24000)
+ return -EINVAL;
+ else if (rate == 24000) {
+ /* switch to the 24M source */
+ clk_set_parent(clk, &osc_24M);
+ } else {
+ int i;
+ u32 clkctrl_cpu = 1;
+ u32 c = clkctrl_cpu;
+ u32 clkctrl_frac = 1;
+ u32 val;
+ for ( ; c < 0x40; c++) {
+ u32 f = (pll_clk.rate*18/c + rate/2) / rate;
+ int s1, s2;
+
+ if (f < 18 || f > 35)
+ continue;
+ s1 = pll_clk.rate*18/clkctrl_frac/clkctrl_cpu - rate;
+ s2 = pll_clk.rate*18/c/f - rate;
+ pr_debug("%s: s1 %d, s2 %d\n", __func__, s1, s2);
+ if (abs(s1) > abs(s2)) {
+ clkctrl_cpu = c;
+ clkctrl_frac = f;
+ }
+ if (s2 == 0)
+ break;
+ };
+ pr_debug("%s: clkctrl_cpu %d, clkctrl_frac %d\n", __func__,
+ clkctrl_cpu, clkctrl_frac);
+ if (c == 0x40) {
+ int d = pll_clk.rate*18/clkctrl_frac/clkctrl_cpu -
+ rate;
+ if (abs(d) > 100 ||
+ clkctrl_frac < 18 || clkctrl_frac > 35)
+ return -EINVAL;
+ }
+
+ /* 4.6.2 */
+ val = __raw_readl(clk->scale_reg);
+ val &= ~(0x3f << clk->scale_shift);
+ val |= clkctrl_frac;
+ clk_set_parent(clk, &osc_24M);
+ udelay(10);
+ __raw_writel(val, clk->scale_reg);
+ /* ungate */
+ __raw_writel(1<<7, clk->scale_reg + 8);
+ /* write clkctrl_cpu */
+ clk->saved_div = clkctrl_cpu;
+ HW_CLKCTRL_CPU_WR((HW_CLKCTRL_CPU_RD() & ~0x3f) | clkctrl_cpu);
+ for (i = 10000; i; i--)
+ if (!clk_is_busy(clk))
+ break;
+ if (!i) {
+ printk(KERN_ERR "couldn't set up CPU divisor\n");
+ return -ETIMEDOUT;
+ }
+ clk_set_parent(clk, &pll_clk);
+ clk->saved_div = 0;
+ udelay(10);
+ }
+ return 0;
+}
+
+static long cpu_get_rate(struct clk *clk)
+{
+ long rate = clk->parent->rate * 18;
+
+ rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & 0x3f;
+ rate /= HW_CLKCTRL_CPU_RD() & 0x3f;
+ rate = ((rate + 9) / 10) * 10;
+ clk->rate = rate;
+
+ return rate;
+}
+
+static long cpu_round_rate(struct clk *clk, u32 rate)
+{
+ unsigned long r = 0;
+
+ if (rate <= 24000)
+ r = 24000;
+ else {
+ u32 clkctrl_cpu = 1;
+ u32 clkctrl_frac;
+ do {
+ clkctrl_frac =
+ (pll_clk.rate*18 / clkctrl_cpu + rate/2) / rate;
+ if (clkctrl_frac > 35)
+ continue;
+ if (pll_clk.rate*18 / clkctrl_frac / clkctrl_cpu/10 ==
+ rate / 10)
+ break;
+ } while (pll_clk.rate / 2 >= clkctrl_cpu++ * rate);
+ if (pll_clk.rate / 2 < (clkctrl_cpu - 1) * rate)
+ clkctrl_cpu--;
+ pr_debug("%s: clkctrl_cpu %d, clkctrl_frac %d\n", __func__,
+ clkctrl_cpu, clkctrl_frac);
+ if (clkctrl_frac < 18)
+ clkctrl_frac = 18;
+ if (clkctrl_frac > 35)
+ clkctrl_frac = 35;
+
+ r = pll_clk.rate * 18;
+ r /= clkctrl_frac;
+ r /= clkctrl_cpu;
+ r = 10 * ((r + 9) / 10);
+ }
+ return r;
+}
+
+static long emi_get_rate(struct clk *clk)
+{
+ long rate = clk->parent->rate * 18;
+
+ rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & 0x3f;
+ rate /= HW_CLKCTRL_EMI_RD() & 0x3f;
+ clk->rate = rate;
+
+ return rate;
+}
+
+static int clkseq_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -EINVAL;
+ int shift = 8;
+
+ /* bypass? */
+ if (parent == &osc_24M)
+ shift = 4;
+
+ if (clk->bypass_reg) {
+ u32 hbus_mask = BM_CLKCTRL_HBUS_DIV_FRAC_EN |
+ BM_CLKCTRL_HBUS_DIV;
+
+ if (clk == &cpu_clk && shift == 4) {
+ u32 hbus_val = HW_CLKCTRL_HBUS_RD();
+ u32 cpu_val = HW_CLKCTRL_CPU_RD();
+ hbus_val &= ~hbus_mask;
+ hbus_val |= 1;
+ clk->saved_div = cpu_val & BM_CLKCTRL_CPU_DIV_CPU;
+ cpu_val &= ~BM_CLKCTRL_CPU_DIV_CPU;
+ cpu_val |= 1;
+ __raw_writel(1 << clk->bypass_shift,
+ clk->bypass_reg + shift);
+ if (machine_is_stmp378x()) {
+ HW_CLKCTRL_HBUS_WR(hbus_val);
+ HW_CLKCTRL_CPU_WR(cpu_val);
+ hclk.rate = 0;
+ }
+ } else if (clk == &cpu_clk && shift == 8) {
+ u32 hbus_val = HW_CLKCTRL_HBUS_RD();
+ u32 cpu_val = HW_CLKCTRL_CPU_RD();
+ hbus_val &= ~hbus_mask;
+ hbus_val |= 2;
+ cpu_val &= ~BM_CLKCTRL_CPU_DIV_CPU;
+ if (clk->saved_div)
+ cpu_val |= clk->saved_div;
+ else
+ cpu_val |= 2;
+ if (machine_is_stmp378x()) {
+ HW_CLKCTRL_HBUS_WR(hbus_val);
+ HW_CLKCTRL_CPU_WR(cpu_val);
+ hclk.rate = 0;
+ }
+ __raw_writel(1 << clk->bypass_shift,
+ clk->bypass_reg + shift);
+ } else
+ __raw_writel(1 << clk->bypass_shift,
+ clk->bypass_reg + shift);
+
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int hbus_set_rate(struct clk *clk, u32 rate)
+{
+ u8 div = 0;
+ int is_frac = 0;
+ u32 clkctrl_hbus;
+ struct clk *parent = clk->parent;
+
+ pr_debug("%s: rate %d, parent rate %d\n", __func__, rate,
+ parent->rate);
+
+ if (rate > parent->rate)
+ return -EINVAL;
+
+ if (((parent->rate + rate/2) / rate) * rate != parent->rate &&
+ parent->rate / rate < 32) {
+ pr_debug("%s: switching to fractional mode\n", __func__);
+ is_frac = 1;
+ }
+
+ if (is_frac)
+ div = (32 * rate + parent->rate / 2) / parent->rate;
+ else
+ div = (parent->rate + rate - 1) / rate;
+ pr_debug("%s: div calculated is %d\n", __func__, div);
+ if (!div || div > 0x1f)
+ return -EINVAL;
+
+ clk_set_parent(&cpu_clk, &osc_24M);
+ udelay(10);
+ clkctrl_hbus = __raw_readl(clk->scale_reg);
+ clkctrl_hbus &= ~0x3f;
+ clkctrl_hbus |= div;
+ clkctrl_hbus |= (is_frac << 5);
+
+ __raw_writel(clkctrl_hbus, clk->scale_reg);
+ if (clk->busy_reg) {
+ int i;
+ for (i = 10000; i; i--)
+ if (!clk_is_busy(clk))
+ break;
+ if (!i) {
+ printk(KERN_ERR "couldn't set up CPU divisor\n");
+ return -ETIMEDOUT;
+ }
+ }
+ clk_set_parent(&cpu_clk, &pll_clk);
+ __raw_writel(clkctrl_hbus, clk->scale_reg);
+ udelay(10);
+ return 0;
+}
+
+static long hbus_get_rate(struct clk *clk)
+{
+ long rate = clk->parent->rate;
+
+ if (__raw_readl(clk->scale_reg) & 0x20) {
+ rate *= __raw_readl(clk->scale_reg) & 0x1f;
+ rate /= 32;
+ } else
+ rate /= __raw_readl(clk->scale_reg) & 0x1f;
+ clk->rate = rate;
+
+ return rate;
+}
+
+static int xbus_set_rate(struct clk *clk, u32 rate)
+{
+ u16 div = 0;
+ u32 clkctrl_xbus;
+
+ pr_debug("%s: rate %d, parent rate %d\n", __func__, rate,
+ clk->parent->rate);
+
+ div = (clk->parent->rate + rate - 1) / rate;
+ pr_debug("%s: div calculated is %d\n", __func__, div);
+ if (!div || div > 0x3ff)
+ return -EINVAL;
+
+ clkctrl_xbus = __raw_readl(clk->scale_reg);
+ clkctrl_xbus &= ~0x3ff;
+ clkctrl_xbus |= div;
+ __raw_writel(clkctrl_xbus, clk->scale_reg);
+ if (clk->busy_reg) {
+ int i;
+ for (i = 10000; i; i--)
+ if (!clk_is_busy(clk))
+ break;
+ if (!i) {
+ printk(KERN_ERR "couldn't set up xbus divisor\n");
+ return -ETIMEDOUT;
+ }
+ }
+ return 0;
+}
+
+static long xbus_get_rate(struct clk *clk)
+{
+ long rate = clk->parent->rate;
+
+ rate /= __raw_readl(clk->scale_reg) & 0x3ff;
+ clk->rate = rate;
+
+ return rate;
+}
+
+
+/* Clock ops */
+
+static struct clk_ops std_ops = {
+ .enable = std_clk_enable,
+ .disable = std_clk_disable,
+ .get_rate = per_get_rate,
+ .set_rate = per_set_rate,
+ .set_parent = clkseq_set_parent,
+};
+
+static struct clk_ops min_ops = {
+ .enable = std_clk_enable,
+ .disable = std_clk_disable,
+};
+
+static struct clk_ops cpu_ops = {
+ .enable = std_clk_enable,
+ .disable = std_clk_disable,
+ .get_rate = cpu_get_rate,
+ .set_rate = cpu_set_rate,
+ .round_rate = cpu_round_rate,
+ .set_parent = clkseq_set_parent,
+};
+
+static struct clk_ops io_ops = {
+ .enable = std_clk_enable,
+ .disable = std_clk_disable,
+ .get_rate = io_get_rate,
+ .set_rate = io_set_rate,
+};
+
+static struct clk_ops hbus_ops = {
+ .get_rate = hbus_get_rate,
+ .set_rate = hbus_set_rate,
+};
+
+static struct clk_ops xbus_ops = {
+ .get_rate = xbus_get_rate,
+ .set_rate = xbus_set_rate,
+};
+
+static struct clk_ops lcdif_ops = {
+ .enable = std_clk_enable,
+ .disable = std_clk_disable,
+ .get_rate = lcdif_get_rate,
+ .set_rate = lcdif_set_rate,
+ .set_parent = clkseq_set_parent,
+};
+
+static struct clk_ops emi_ops = {
+ .get_rate = emi_get_rate,
+};
+
+/* List of on-chip clocks */
+
+static struct clk osc_24M = {
+ .flags = FIXED_RATE | ENABLED,
+ .rate = 24000,
+};
+
+static struct clk pll_clk = {
+ .parent = &osc_24M,
+ .enable_reg = HW_CLKCTRL_PLLCTRL0_ADDR,
+ .enable_shift = 16,
+ .enable_wait = 10,
+ .flags = FIXED_RATE | ENABLED,
+ .rate = 480000,
+ .ops = &min_ops,
+};
+
+static struct clk cpu_clk = {
+ .parent = &pll_clk,
+ .scale_reg = HW_CLKCTRL_FRAC_ADDR,
+ .scale_shift = 0,
+ .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR,
+ .bypass_shift = 7,
+ .busy_reg = HW_CLKCTRL_CPU_ADDR,
+ .busy_bit = 28,
+ .flags = RATE_PROPAGATES | ENABLED,
+ .ops = &cpu_ops,
+};
+
+static struct clk io_clk = {
+ .parent = &pll_clk,
+ .enable_reg = HW_CLKCTRL_FRAC_ADDR,
+ .enable_shift = 31,
+ .enable_negate = 1,
+ .scale_reg = HW_CLKCTRL_FRAC_ADDR,
+ .scale_shift = 24,
+ .flags = RATE_PROPAGATES | ENABLED,
+ .ops = &io_ops,
+};
+
+static struct clk hclk = {
+ .parent = &cpu_clk,
+ .scale_reg = HW_CLKCTRL_HBUS_ADDR,
+ .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR,
+ .bypass_shift = 7,
+ .busy_reg = HW_CLKCTRL_HBUS_ADDR,
+ .busy_bit = 29,
+ .flags = RATE_PROPAGATES | ENABLED,
+ .ops = &hbus_ops,
+};
+
+static struct clk xclk = {
+ .parent = &osc_24M,
+ .scale_reg = HW_CLKCTRL_XBUS_ADDR,
+ .busy_reg = HW_CLKCTRL_XBUS_ADDR,
+ .busy_bit = 31,
+ .flags = RATE_PROPAGATES | ENABLED,
+ .ops = &xbus_ops,
+};
+
+static struct clk uart_clk = {
+ .parent = &xclk,
+ .enable_reg = HW_CLKCTRL_XTAL_ADDR,
+ .enable_shift = 31,
+ .enable_negate = 1,
+ .flags = ENABLED,
+ .ops = &min_ops,
+};
+
+static struct clk audio_clk = {
+ .parent = &xclk,
+ .enable_reg = HW_CLKCTRL_XTAL_ADDR,
+ .enable_shift = 30,
+ .enable_negate = 1,
+ .ops = &min_ops,
+};
+
+static struct clk pwm_clk = {
+ .parent = &xclk,
+ .enable_reg = HW_CLKCTRL_XTAL_ADDR,
+ .enable_shift = 29,
+ .enable_negate = 1,
+ .ops = &min_ops,
+};
+
+static struct clk dri_clk = {
+ .parent = &xclk,
+ .enable_reg = HW_CLKCTRL_XTAL_ADDR,
+ .enable_shift = 28,
+ .enable_negate = 1,
+ .ops = &min_ops,
+};
+
+static struct clk digctl_clk = {
+ .parent = &xclk,
+ .enable_reg = HW_CLKCTRL_XTAL_ADDR,
+ .enable_shift = 27,
+ .enable_negate = 1,
+ .ops = &min_ops,
+};
+
+static struct clk timer_clk = {
+ .parent = &xclk,
+ .enable_reg = HW_CLKCTRL_XTAL_ADDR,
+ .enable_shift = 26,
+ .enable_negate = 1,
+ .flags = ENABLED,
+ .ops = &min_ops,
+};
+
+static struct clk lcdif_clk = {
+ .parent = &pll_clk,
+ .scale_reg = HW_CLKCTRL_PIX_ADDR,
+ .busy_reg = HW_CLKCTRL_PIX_ADDR,
+ .busy_bit = 29,
+ .enable_reg = HW_CLKCTRL_PIX_ADDR,
+ .enable_shift = 31,
+ .enable_negate = 1,
+ .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR,
+ .bypass_shift = 1,
+ .flags = NEEDS_SET_PARENT,
+ .ops = &lcdif_ops,
+};
+
+static struct clk ssp_clk = {
+ .parent = &io_clk,
+ .scale_reg = HW_CLKCTRL_SSP_ADDR,
+ .busy_reg = HW_CLKCTRL_SSP_ADDR,
+ .busy_bit = 29,
+ .enable_reg = HW_CLKCTRL_SSP_ADDR,
+ .enable_shift = 31,
+ .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR,
+ .bypass_shift = 5,
+ .enable_negate = 1,
+ .flags = NEEDS_SET_PARENT,
+ .ops = &std_ops,
+};
+
+static struct clk gpmi_clk = {
+ .parent = &io_clk,
+ .scale_reg = HW_CLKCTRL_GPMI_ADDR,
+ .busy_reg = HW_CLKCTRL_GPMI_ADDR,
+ .busy_bit = 29,
+ .enable_reg = HW_CLKCTRL_GPMI_ADDR,
+ .enable_shift = 31,
+ .enable_negate = 1,
+ .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR,
+ .bypass_shift = 4,
+ .flags = NEEDS_SET_PARENT,
+ .ops = &std_ops,
+};
+
+static struct clk spdif_clk = {
+ .parent = &pll_clk,
+ .enable_reg = HW_CLKCTRL_SPDIF_ADDR,
+ .enable_shift = 31,
+ .enable_negate = 1,
+ .ops = &min_ops,
+};
+
+static struct clk emi_clk = {
+ .parent = &pll_clk,
+ .enable_reg = HW_CLKCTRL_EMI_ADDR,
+ .enable_shift = 31,
+ .enable_negate = 1,
+ .scale_reg = HW_CLKCTRL_FRAC_ADDR,
+ .scale_shift = 8,
+ .busy_reg = HW_CLKCTRL_EMI_ADDR,
+ .busy_bit = 28,
+ .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR,
+ .bypass_shift = 6,
+ .flags = ENABLED,
+ .ops = &emi_ops,
+};
+
+static struct clk ir_clk = {
+ .parent = &io_clk,
+ .enable_reg = HW_CLKCTRL_IR_ADDR,
+ .enable_shift = 31,
+ .enable_negate = 1,
+ .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR,
+ .bypass_shift = 3,
+ .ops = &min_ops,
+};
+
+static struct clk saif_clk = {
+ .parent = &pll_clk,
+ .scale_reg = HW_CLKCTRL_SAIF_ADDR,
+ .busy_reg = HW_CLKCTRL_SAIF_ADDR,
+ .busy_bit = 29,
+ .enable_reg = HW_CLKCTRL_SAIF_ADDR,
+ .enable_shift = 31,
+ .enable_negate = 1,
+ .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR,
+ .bypass_shift = 0,
+ .ops = &std_ops,
+};
+
+static struct clk usb_clk = {
+ .parent = &pll_clk,
+ .enable_reg = HW_CLKCTRL_PLLCTRL0_ADDR,
+ .enable_shift = 18,
+ .enable_negate = 1,
+ .ops = &min_ops,
+};
+
+/* list of all the clocks */
+static __initdata struct clk_lookup onchip_clks[] = {
+ {
+ .con_id = "osc_24M",
+ .clk = &osc_24M,
+ }, {
+ .con_id = "pll",
+ .clk = &pll_clk,
+ }, {
+ .con_id = "cpu",
+ .clk = &cpu_clk,
+ }, {
+ .con_id = "hclk",
+ .clk = &hclk,
+ }, {
+ .con_id = "xclk",
+ .clk = &xclk,
+ }, {
+ .con_id = "io",
+ .clk = &io_clk,
+ }, {
+ .con_id = "uart",
+ .clk = &uart_clk,
+ }, {
+ .con_id = "audio",
+ .clk = &audio_clk,
+ }, {
+ .con_id = "pwm",
+ .clk = &pwm_clk,
+ }, {
+ .con_id = "dri",
+ .clk = &dri_clk,
+ }, {
+ .con_id = "digctl",
+ .clk = &digctl_clk,
+ }, {
+ .con_id = "timer",
+ .clk = &timer_clk,
+ }, {
+ .con_id = "lcdif",
+ .clk = &lcdif_clk,
+ }, {
+ .con_id = "ssp",
+ .clk = &ssp_clk,
+ }, {
+ .con_id = "gpmi",
+ .clk = &gpmi_clk,
+ }, {
+ .con_id = "spdif",
+ .clk = &spdif_clk,
+ }, {
+ .con_id = "emi",
+ .clk = &emi_clk,
+ }, {
+ .con_id = "ir",
+ .clk = &ir_clk,
+ }, {
+ .con_id = "saif",
+ .clk = &saif_clk,
+ }, {
+ .con_id = "usb",
+ .clk = &usb_clk,
+ },
+};
+
+static int __init propagate_rate(struct clk *clk)
+{
+ struct clk_lookup *cl;
+
+ for (cl = onchip_clks; cl < onchip_clks + ARRAY_SIZE(onchip_clks);
+ cl++) {
+ if (unlikely(!clk_good(cl->clk)))
+ continue;
+ if (cl->clk->parent == clk && cl->clk->ops->get_rate) {
+ cl->clk->ops->get_rate(cl->clk);
+ if (cl->clk->flags & RATE_PROPAGATES)
+ propagate_rate(cl->clk);
+ }
+ }
+
+ return 0;
+}
+
+/* Exported API */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (unlikely(!clk_good(clk)))
+ return 0;
+
+ if (clk->rate != 0)
+ return clk->rate;
+
+ if (clk->ops->get_rate != NULL)
+ return clk->ops->get_rate(clk);
+
+ return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (unlikely(!clk_good(clk)))
+ return 0;
+
+ if (clk->ops->round_rate)
+ return clk->ops->round_rate(clk, rate);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+static inline int close_enough(long rate1, long rate2)
+{
+ return rate1 && !((rate2 - rate1) * 1000 / rate1);
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (unlikely(!clk_good(clk)))
+ goto out;
+
+ if (clk->flags & FIXED_RATE || !clk->ops->set_rate)
+ goto out;
+
+ else if (!close_enough(clk->rate, rate)) {
+ ret = clk->ops->set_rate(clk, rate);
+ if (ret < 0)
+ goto out;
+ clk->rate = rate;
+ if (clk->flags & RATE_PROPAGATES)
+ propagate_rate(clk);
+ } else
+ ret = 0;
+
+out:
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long clocks_flags;
+
+ if (unlikely(!clk_good(clk)))
+ return -EINVAL;
+
+ if (clk->parent)
+ clk_enable(clk->parent);
+
+ spin_lock_irqsave(&clocks_lock, clocks_flags);
+
+ clk->usage++;
+ if (clk->ops && clk->ops->enable)
+ clk->ops->enable(clk);
+
+ spin_unlock_irqrestore(&clocks_lock, clocks_flags);
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+static void local_clk_disable(struct clk *clk)
+{
+ if (unlikely(!clk_good(clk)))
+ return;
+
+ if (clk->usage == 0 && clk->ops->disable)
+ clk->ops->disable(clk);
+
+ if (clk->parent)
+ local_clk_disable(clk->parent);
+}
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long clocks_flags;
+
+ if (unlikely(!clk_good(clk)))
+ return;
+
+ spin_lock_irqsave(&clocks_lock, clocks_flags);
+
+ if ((--clk->usage) == 0 && clk->ops->disable)
+ clk->ops->disable(clk);
+
+ spin_unlock_irqrestore(&clocks_lock, clocks_flags);
+ if (clk->parent)
+ clk_disable(clk->parent);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Some additional API */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -ENODEV;
+ unsigned long clocks_flags;
+
+ if (unlikely(!clk_good(clk)))
+ goto out;
+
+ if (!clk->ops->set_parent)
+ goto out;
+
+ spin_lock_irqsave(&clocks_lock, clocks_flags);
+
+ ret = clk->ops->set_parent(clk, parent);
+ if (!ret) {
+ /* disable if usage count is 0 */
+ local_clk_disable(parent);
+
+ parent->usage += clk->usage;
+ clk->parent->usage -= clk->usage;
+
+ /* disable if new usage count is 0 */
+ local_clk_disable(clk->parent);
+
+ clk->parent = parent;
+ }
+ spin_unlock_irqrestore(&clocks_lock, clocks_flags);
+
+out:
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (unlikely(!clk_good(clk)))
+ return NULL;
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+static int __init clk_init(void)
+{
+ struct clk_lookup *cl;
+ struct clk_ops *ops;
+
+ spin_lock_init(&clocks_lock);
+
+ for (cl = onchip_clks; cl < onchip_clks + ARRAY_SIZE(onchip_clks);
+ cl++) {
+ if (cl->clk->flags & ENABLED)
+ clk_enable(cl->clk);
+ else
+ local_clk_disable(cl->clk);
+
+ ops = cl->clk->ops;
+
+ if ((cl->clk->flags & NEEDS_INITIALIZATION) &&
+ ops && ops->set_rate)
+ ops->set_rate(cl->clk, cl->clk->rate);
+
+ if (cl->clk->flags & FIXED_RATE) {
+ if (cl->clk->flags & RATE_PROPAGATES)
+ propagate_rate(cl->clk);
+ } else {
+ if (ops && ops->get_rate)
+ ops->get_rate(cl->clk);
+ }
+
+ if (cl->clk->flags & NEEDS_SET_PARENT) {
+ if (ops && ops->set_parent)
+ ops->set_parent(cl->clk, cl->clk->parent);
+ }
+
+ clkdev_add(cl);
+ }
+ return 0;
+}
+
+arch_initcall(clk_init);
diff --git a/arch/arm/plat-stmp3xxx/clock.h b/arch/arm/plat-stmp3xxx/clock.h
new file mode 100644
index 000000000000..a6611e1a3510
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/clock.h
@@ -0,0 +1,61 @@
+/*
+ * Clock control driver for Freescale STMP37XX/STMP378X - internal header file
+ *
+ * Author: Vitaly Wool <vital@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ARCH_ARM_STMX3XXX_CLOCK_H__
+#define __ARCH_ARM_STMX3XXX_CLOCK_H__
+
+#ifndef __ASSEMBLER__
+
+struct clk_ops {
+ int (*enable) (struct clk *);
+ int (*disable) (struct clk *);
+ long (*get_rate) (struct clk *);
+ long (*round_rate) (struct clk *, u32);
+ int (*set_rate) (struct clk *, u32);
+ int (*set_parent) (struct clk *, struct clk *);
+};
+
+struct clk {
+ struct clk *parent;
+ u32 rate;
+ u32 flags;
+ u8 scale_shift;
+ u8 enable_shift;
+ u8 bypass_shift;
+ u8 busy_bit;
+ s8 usage;
+ int enable_wait;
+ int enable_negate;
+ u32 saved_div;
+ void __iomem *enable_reg;
+ void __iomem *scale_reg;
+ void __iomem *bypass_reg;
+ void __iomem *busy_reg;
+ struct clk_ops *ops;
+};
+
+#endif /* __ASSEMBLER__ */
+
+/* Flags */
+#define RATE_PROPAGATES (1<<0)
+#define NEEDS_INITIALIZATION (1<<1)
+#define PARENT_SET_RATE (1<<2)
+#define FIXED_RATE (1<<3)
+#define ENABLED (1<<4)
+#define NEEDS_SET_PARENT (1<<5)
+
+#endif
diff --git a/arch/arm/plat-stmp3xxx/core.c b/arch/arm/plat-stmp3xxx/core.c
new file mode 100644
index 000000000000..6e2fef1639b0
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/core.c
@@ -0,0 +1,127 @@
+/*
+ * Freescale STMP37XX/STMP378X core routines
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/stmp3xxx.h>
+#include <mach/dma.h>
+#include <mach/regs-clkctrl.h>
+
+static int __stmp3xxx_reset_block(void __iomem *hwreg, int just_enable)
+{
+ u32 c;
+ int timeout;
+
+ /* the process of software reset of IP block is done
+ in several steps:
+
+ - clear SFTRST and wait for block is enabled;
+ - clear clock gating (CLKGATE bit);
+ - set the SFTRST again and wait for block is in reset;
+ - clear SFTRST and wait for reset completion.
+ */
+ c = __raw_readl(hwreg);
+ c &= ~(1<<31); /* clear SFTRST */
+ __raw_writel(c, hwreg);
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* still in SFTRST state ? */
+ if ((__raw_readl(hwreg) & (1<<31)) == 0)
+ break;
+ if (timeout <= 0) {
+ printk(KERN_ERR"%s(%p): timeout when enabling\n",
+ __func__, hwreg);
+ return -ETIME;
+ }
+
+ c = __raw_readl(hwreg);
+ c &= ~(1<<30); /* clear CLKGATE */
+ __raw_writel(c, hwreg);
+
+ if (!just_enable) {
+ c = __raw_readl(hwreg);
+ c |= (1<<31); /* now again set SFTRST */
+ __raw_writel(c, hwreg);
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* poll until CLKGATE set */
+ if (__raw_readl(hwreg) & (1<<30))
+ break;
+ if (timeout <= 0) {
+ printk(KERN_ERR"%s(%p): timeout when resetting\n",
+ __func__, hwreg);
+ return -ETIME;
+ }
+
+ c = __raw_readl(hwreg);
+ c &= ~(1<<31); /* clear SFTRST */
+ __raw_writel(c, hwreg);
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* still in SFTRST state ? */
+ if ((__raw_readl(hwreg) & (1<<31)) == 0)
+ break;
+ if (timeout <= 0) {
+ printk(KERN_ERR"%s(%p): timeout when enabling "
+ "after reset\n", __func__, hwreg);
+ return -ETIME;
+ }
+
+ c = __raw_readl(hwreg);
+ c &= ~(1<<30); /* clear CLKGATE */
+ __raw_writel(c, hwreg);
+ }
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* still in SFTRST state ? */
+ if ((__raw_readl(hwreg) & (1<<30)) == 0)
+ break;
+
+ if (timeout <= 0) {
+ printk(KERN_ERR"%s(%p): timeout when unclockgating\n",
+ __func__, hwreg);
+ return -ETIME;
+ }
+
+ return 0;
+}
+
+int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable)
+{
+ int try = 10;
+ int r;
+
+ while (try--) {
+ r = __stmp3xxx_reset_block(hwreg, just_enable);
+ if (!r)
+ break;
+ pr_debug("%s: try %d failed\n", __func__, 10 - try);
+ }
+ return r;
+}
+EXPORT_SYMBOL(stmp3xxx_reset_block);
+
+struct platform_device stmp3xxx_dbguart = {
+ .name = "stmp3xxx-dbguart",
+ .id = -1,
+};
+
+void __init stmp3xxx_init(void)
+{
+ /* Turn off auto-slow and other tricks */
+ HW_CLKCTRL_HBUS_CLR(0x07f00000U);
+
+ stmp3xxx_dma_init();
+}
diff --git a/arch/arm/plat-stmp3xxx/dma.c b/arch/arm/plat-stmp3xxx/dma.c
new file mode 100644
index 000000000000..cf42de05e568
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/dma.c
@@ -0,0 +1,462 @@
+/*
+ * DMA helper routines for Freescale STMP37XX/STMP378X
+ *
+ * Author: dmitry pervushin <dpervushin@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/dmapool.h>
+#include <linux/sysdev.h>
+#include <linux/cpufreq.h>
+
+#include <asm/page.h>
+
+#include <mach/dma.h>
+#include <mach/regs-apbx.h>
+#include <mach/regs-apbh.h>
+
+static const size_t pool_item_size = sizeof(struct stmp3xxx_dma_command);
+static const size_t pool_alignment = 8;
+static struct stmp3xxx_dma_user {
+ void *pool;
+ int inuse;
+ const char *name;
+} channels[MAX_DMA_CHANNELS];
+
+static inline int dmach(int ch)
+{
+ return ch % 16;
+}
+
+static inline int dmabus(int ch)
+{
+ return ch / 16;
+}
+
+#define IS_VALID_CHANNEL(ch) ((ch) >= 0 && (ch) < MAX_DMA_CHANNELS)
+#define IS_USED(ch) (channels[ch].inuse)
+
+int stmp3xxx_dma_request(int ch, struct device *dev, const char *name)
+{
+ struct stmp3xxx_dma_user *user;
+ int err = 0;
+
+ user = channels + ch;
+ if (!IS_VALID_CHANNEL(ch)) {
+ err = -ENODEV;
+ goto out;
+ }
+ if (IS_USED(ch)) {
+ err = -EBUSY;
+ goto out;
+ }
+ /* Create a pool to allocate dma commands from */
+ user->pool = dma_pool_create(name, dev, pool_item_size,
+ pool_alignment, PAGE_SIZE);
+ if (user->pool == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
+ user->name = name;
+ user->inuse++;
+out:
+ return err;
+}
+EXPORT_SYMBOL(stmp3xxx_dma_request);
+
+int stmp3xxx_dma_release(int ch)
+{
+ struct stmp3xxx_dma_user *user = channels + ch;
+ int err = 0;
+
+ if (!IS_VALID_CHANNEL(ch)) {
+ err = -ENODEV;
+ goto out;
+ }
+ if (!IS_USED(ch)) {
+ err = -EBUSY;
+ goto out;
+ }
+ BUG_ON(user->pool == NULL);
+ dma_pool_destroy(user->pool);
+ user->inuse--;
+out:
+ return err;
+}
+EXPORT_SYMBOL(stmp3xxx_dma_release);
+
+int stmp3xxx_dma_read_semaphore(int channel)
+{
+ int sem = -1;
+
+ switch (dmabus(channel)) {
+ case STMP3XXX_BUS_APBH:
+ sem =
+ (HW_APBH_CHn_SEMA_RD(dmach(channel)) &
+ BM_APBH_CHn_SEMA_PHORE) >> BP_APBH_CHn_SEMA_PHORE;
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ sem =
+ (HW_APBX_CHn_SEMA_RD(dmach(channel)) &
+ BM_APBX_CHn_SEMA_PHORE) >> BP_APBX_CHn_SEMA_PHORE;
+ break;
+ default:
+ BUG();
+ }
+ return sem;
+}
+EXPORT_SYMBOL(stmp3xxx_dma_read_semaphore);
+
+int stmp3xxx_dma_allocate_command(int channel,
+ struct stmp3xxx_dma_descriptor *descriptor)
+{
+ struct stmp3xxx_dma_user *user = channels + channel;
+ int err = 0;
+
+ if (!IS_VALID_CHANNEL(channel)) {
+ err = -ENODEV;
+ goto out;
+ }
+ if (!IS_USED(channel)) {
+ err = -EBUSY;
+ goto out;
+ }
+ if (descriptor == NULL) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* Allocate memory for a command from the buffer */
+ descriptor->command =
+ dma_pool_alloc(user->pool, GFP_KERNEL, &descriptor->handle);
+
+ /* Check it worked */
+ if (!descriptor->command) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ memset(descriptor->command, 0, pool_item_size);
+out:
+ WARN_ON(err);
+ return err;
+}
+EXPORT_SYMBOL(stmp3xxx_dma_allocate_command);
+
+int stmp3xxx_dma_free_command(int channel,
+ struct stmp3xxx_dma_descriptor *descriptor)
+{
+ int err = 0;
+
+ if (!IS_VALID_CHANNEL(channel)) {
+ err = -ENODEV;
+ goto out;
+ }
+ if (!IS_USED(channel)) {
+ err = -EBUSY;
+ goto out;
+ }
+
+ /* Return the command memory to the pool */
+ dma_pool_free(channels[channel].pool, descriptor->command,
+ descriptor->handle);
+
+ /* Initialise descriptor so we're not tempted to use it */
+ descriptor->command = NULL;
+ descriptor->handle = 0;
+ descriptor->virtual_buf_ptr = NULL;
+ descriptor->next_descr = NULL;
+
+ WARN_ON(err);
+out:
+ return err;
+}
+EXPORT_SYMBOL(stmp3xxx_dma_free_command);
+
+void stmp3xxx_dma_go(int channel,
+ struct stmp3xxx_dma_descriptor *head, u32 semaphore)
+{
+ int ch = dmach(channel);
+
+ switch (dmabus(channel)) {
+ case STMP3XXX_BUS_APBH:
+ /* Set next command */
+ HW_APBH_CHn_NXTCMDAR_WR(ch, head->handle);
+ /* Set counting semaphore (kicks off transfer). Assumes
+ peripheral has been set up correctly */
+ HW_APBH_CHn_SEMA_WR(ch, semaphore);
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ /* Set next command */
+ HW_APBX_CHn_NXTCMDAR_WR(ch, head->handle);
+ /* Set counting semaphore (kicks off transfer). Assumes
+ peripheral has been set up correctly */
+ HW_APBX_CHn_SEMA_WR(ch, semaphore);
+ break;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_dma_go);
+
+int stmp3xxx_dma_running(int channel)
+{
+ switch (dmabus(channel)) {
+ case STMP3XXX_BUS_APBH:
+ return HW_APBH_CHn_SEMA_RD(dmach(channel)) &
+ BM_APBH_CHn_SEMA_PHORE;
+
+ case STMP3XXX_BUS_APBX:
+ return HW_APBX_CHn_SEMA_RD(dmach(channel)) &
+ BM_APBX_CHn_SEMA_PHORE;
+
+ default:
+ BUG();
+ return 0;
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_dma_running);
+
+/*
+ * Circular dma chain management
+ */
+void stmp3xxx_dma_free_chain(struct stmp37xx_circ_dma_chain *chain)
+{
+ int i;
+
+ for (i = 0; i < chain->total_count; i++)
+ stmp3xxx_dma_free_command(
+ STMP3xxx_DMA(chain->channel, chain->bus),
+ &chain->chain[i]);
+}
+EXPORT_SYMBOL(stmp3xxx_dma_free_chain);
+
+int stmp3xxx_dma_make_chain(int ch, struct stmp37xx_circ_dma_chain *chain,
+ struct stmp3xxx_dma_descriptor descriptors[],
+ unsigned items)
+{
+ int i;
+ int err = 0;
+
+ if (items == 0)
+ return err;
+
+ for (i = 0; i < items; i++) {
+ err = stmp3xxx_dma_allocate_command(ch, &descriptors[i]);
+ if (err) {
+ WARN_ON(err);
+ /*
+ * Couldn't allocate the whole chain.
+ * deallocate what has been allocated
+ */
+ if (i) {
+ do {
+ stmp3xxx_dma_free_command(ch,
+ &descriptors
+ [i]);
+ } while (i-- >= 0);
+ }
+ return err;
+ }
+
+ /* link them! */
+ if (i > 0) {
+ descriptors[i - 1].next_descr = &descriptors[i];
+ descriptors[i - 1].command->next =
+ descriptors[i].handle;
+ }
+ }
+
+ /* make list circular */
+ descriptors[items - 1].next_descr = &descriptors[0];
+ descriptors[items - 1].command->next = descriptors[0].handle;
+
+ chain->total_count = items;
+ chain->chain = descriptors;
+ chain->free_index = 0;
+ chain->active_index = 0;
+ chain->cooked_index = 0;
+ chain->free_count = items;
+ chain->active_count = 0;
+ chain->cooked_count = 0;
+ chain->bus = dmabus(ch);
+ chain->channel = dmach(ch);
+ return err;
+}
+EXPORT_SYMBOL(stmp3xxx_dma_make_chain);
+
+void stmp37xx_circ_clear_chain(struct stmp37xx_circ_dma_chain *chain)
+{
+ BUG_ON(stmp3xxx_dma_running(STMP3xxx_DMA(chain->channel, chain->bus)) >
+ 0);
+ chain->free_index = 0;
+ chain->active_index = 0;
+ chain->cooked_index = 0;
+ chain->free_count = chain->total_count;
+ chain->active_count = 0;
+ chain->cooked_count = 0;
+}
+EXPORT_SYMBOL(stmp37xx_circ_clear_chain);
+
+void stmp37xx_circ_advance_free(struct stmp37xx_circ_dma_chain *chain,
+ unsigned count)
+{
+ BUG_ON(chain->cooked_count < count);
+
+ chain->cooked_count -= count;
+ chain->cooked_index += count;
+ chain->cooked_index %= chain->total_count;
+ chain->free_count += count;
+}
+EXPORT_SYMBOL(stmp37xx_circ_advance_free);
+
+void stmp37xx_circ_advance_active(struct stmp37xx_circ_dma_chain *chain,
+ unsigned count)
+{
+ BUG_ON(chain->free_count < count);
+
+ chain->free_count -= count;
+ chain->free_index += count;
+ chain->free_index %= chain->total_count;
+ chain->active_count += count;
+
+ switch (chain->bus) {
+ case STMP3XXX_BUS_APBH:
+ /* Set counting semaphore (kicks off transfer). Assumes
+ peripheral has been set up correctly */
+ HW_APBH_CHn_SEMA_CLR(chain->channel,
+ BM_APBH_CHn_SEMA_INCREMENT_SEMA);
+ HW_APBH_CHn_SEMA_SET(chain->channel,
+ BF_APBH_CHn_SEMA_INCREMENT_SEMA(count));
+ break;
+
+ case STMP3XXX_BUS_APBX:
+ /* Set counting semaphore (kicks off transfer). Assumes
+ peripheral has been set up correctly */
+ HW_APBX_CHn_SEMA_CLR(chain->channel,
+ BM_APBX_CHn_SEMA_INCREMENT_SEMA);
+ HW_APBX_CHn_SEMA_SET(chain->channel,
+ BF_APBX_CHn_SEMA_INCREMENT_SEMA(count));
+ break;
+
+ default:
+ BUG();
+ }
+}
+EXPORT_SYMBOL(stmp37xx_circ_advance_active);
+
+unsigned stmp37xx_circ_advance_cooked(struct stmp37xx_circ_dma_chain *chain)
+{
+ unsigned cooked;
+
+ cooked = chain->active_count -
+ stmp3xxx_dma_read_semaphore(STMP3xxx_DMA(chain->channel, chain->bus));
+
+ chain->active_count -= cooked;
+ chain->active_index += cooked;
+ chain->active_index %= chain->total_count;
+
+ chain->cooked_count += cooked;
+
+ return cooked;
+}
+EXPORT_SYMBOL(stmp37xx_circ_advance_cooked);
+
+void stmp3xxx_dma_set_alt_target(int channel, int function)
+{
+#if defined(CONFIG_ARCH_STMP37XX)
+ unsigned bits = 4;
+#elif defined(CONFIG_ARCH_STMP378X)
+ unsigned bits = 2;
+#else
+#error wrong arch
+#endif
+ int shift = dmach(channel) * bits;
+ unsigned mask = (1<<bits) - 1;
+
+ BUG_ON(function < 0 || function >= (1<<bits));
+ pr_debug("%s: channel = %d, using mask %x, "
+ "shift = %d\n", __func__, channel, mask, shift);
+
+ switch (dmabus(channel)) {
+ case STMP3XXX_BUS_APBH:
+ HW_APBH_DEVSEL_CLR(mask<<shift);
+ HW_APBH_DEVSEL_SET(function<<shift);
+ break;
+ case STMP3XXX_BUS_APBX:
+ HW_APBX_DEVSEL_CLR(mask<<shift);
+ HW_APBX_DEVSEL_SET(function<<shift);
+ break;
+ default:
+ BUG();
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_dma_set_alt_target);
+
+void stmp3xxx_dma_suspend(void)
+{
+ HW_APBH_CTRL0_SET(BM_APBH_CTRL0_CLKGATE);
+ HW_APBX_CTRL0_SET(BM_APBX_CTRL0_CLKGATE);
+}
+
+void stmp3xxx_dma_resume(void)
+{
+ HW_APBH_CTRL0_CLR(BM_APBH_CTRL0_CLKGATE | BM_APBH_CTRL0_SFTRST);
+ HW_APBX_CTRL0_CLR(BM_APBX_CTRL0_CLKGATE | BM_APBX_CTRL0_SFTRST);
+}
+
+#ifdef CONFIG_CPU_FREQ
+
+struct dma_notifier_block {
+ struct notifier_block nb;
+ void *data;
+};
+
+static int dma_cpufreq_notifier(struct notifier_block *self,
+ unsigned long phase, void *p)
+{
+ switch (phase) {
+ case CPUFREQ_POSTCHANGE:
+ stmp3xxx_dma_resume();
+ break;
+
+ case CPUFREQ_PRECHANGE:
+ stmp3xxx_dma_suspend();
+ break;
+
+ default:
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct dma_notifier_block dma_cpufreq_nb = {
+ .nb = {
+ .notifier_call = dma_cpufreq_notifier,
+ },
+};
+#endif /* CONFIG_CPU_FREQ */
+
+void __init stmp3xxx_dma_init(void)
+{
+ HW_APBH_CTRL0_CLR(BM_APBH_CTRL0_CLKGATE | BM_APBH_CTRL0_SFTRST);
+ HW_APBX_CTRL0_CLR(BM_APBX_CTRL0_CLKGATE | BM_APBX_CTRL0_SFTRST);
+#ifdef CONFIG_CPU_FREQ
+ cpufreq_register_notifier(&dma_cpufreq_nb.nb,
+ CPUFREQ_TRANSITION_NOTIFIER);
+#endif /* CONFIG_CPU_FREQ */
+
+}
diff --git a/arch/arm/plat-stmp3xxx/include/mach/clkdev.h b/arch/arm/plat-stmp3xxx/include/mach/clkdev.h
new file mode 100644
index 000000000000..f9c39772d7c5
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/clkdev.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/plat-stmp3xxx/include/mach/cputype.h b/arch/arm/plat-stmp3xxx/include/mach/cputype.h
new file mode 100644
index 000000000000..b4e205b95f2c
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/cputype.h
@@ -0,0 +1,33 @@
+/*
+ * Freescale STMP37XX/STMP378X CPU type detection
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_PLAT_CPU_H
+#define __ASM_PLAT_CPU_H
+
+#ifdef CONFIG_ARCH_STMP37XX
+#define cpu_is_stmp37xx() (1)
+#else
+#define cpu_is_stmp37xx() (0)
+#endif
+
+#ifdef CONFIG_ARCH_STMP378X
+#define cpu_is_stmp378x() (1)
+#else
+#define cpu_is_stmp378x() (0)
+#endif
+
+#endif /* __ASM_PLAT_CPU_H */
diff --git a/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S b/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S
new file mode 100644
index 000000000000..fb3b969bf0a2
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S
@@ -0,0 +1,42 @@
+/*
+ * Debugging macro include header
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+ .macro addruart,rx
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ moveq \rx, #0x80000000 @ physical base address
+ addeq \rx, \rx, #0x00070000
+ movne \rx, #0xf0000000 @ virtual base
+ addne \rx, \rx, #0x00070000
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #0] @ data register at 0
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
+ tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full
+ bne 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
+ tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
+ bne 1001b
+ .endm
diff --git a/arch/arm/plat-stmp3xxx/include/mach/dma.h b/arch/arm/plat-stmp3xxx/include/mach/dma.h
new file mode 100644
index 000000000000..1e305b2bfe73
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/dma.h
@@ -0,0 +1,155 @@
+/*
+ * Freescale STMP37XX/STMP378X DMA helper interface
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_PLAT_STMP3XXX_DMA_H
+#define __ASM_PLAT_STMP3XXX_DMA_H
+
+#include <linux/platform_device.h>
+#include <linux/dmapool.h>
+
+#if !defined(MAX_PIO_WORDS)
+#define MAX_PIO_WORDS (15)
+#endif
+
+#define STMP3XXX_BUS_APBH 0
+#define STMP3XXX_BUS_APBX 1
+#define STMP3XXX_DMA_MAX_CHANNEL 16
+
+
+#define STMP3xxx_DMA(channel, bus) ((bus) * 16 + (channel))
+
+#define MAX_DMA_ADDRESS 0xffffffff
+
+#define MAX_DMA_CHANNELS 32
+
+struct stmp3xxx_dma_command {
+ u32 next;
+ u32 cmd;
+ union {
+ u32 buf_ptr;
+ u32 alternate;
+ };
+ u32 pio_words[MAX_PIO_WORDS];
+};
+
+struct stmp3xxx_dma_descriptor {
+ struct stmp3xxx_dma_command *command;
+ dma_addr_t handle;
+
+ /* The virtual address of the buffer pointer */
+ void *virtual_buf_ptr;
+ /* The next descriptor in a the DMA chain (optional) */
+ struct stmp3xxx_dma_descriptor *next_descr;
+};
+
+struct stmp37xx_circ_dma_chain {
+ unsigned total_count;
+ struct stmp3xxx_dma_descriptor *chain;
+
+ unsigned free_index;
+ unsigned free_count;
+ unsigned active_index;
+ unsigned active_count;
+ unsigned cooked_index;
+ unsigned cooked_count;
+
+ int bus;
+ unsigned channel;
+};
+
+static inline struct stmp3xxx_dma_descriptor
+ *stmp3xxx_dma_circ_get_free_head(struct stmp37xx_circ_dma_chain *chain)
+{
+ return &(chain->chain[chain->free_index]);
+}
+
+static inline struct stmp3xxx_dma_descriptor
+ *stmp3xxx_dma_circ_get_cooked_head(struct stmp37xx_circ_dma_chain *chain)
+{
+ return &(chain->chain[chain->cooked_index]);
+}
+
+int stmp3xxx_dma_request(int ch, struct device *dev, const char *name);
+int stmp3xxx_dma_release(int ch);
+int stmp3xxx_dma_allocate_command(int ch,
+ struct stmp3xxx_dma_descriptor *descriptor);
+int stmp3xxx_dma_free_command(int ch,
+ struct stmp3xxx_dma_descriptor *descriptor);
+void stmp3xxx_dma_continue(int channel, u32 semaphore);
+void stmp3xxx_dma_go(int ch, struct stmp3xxx_dma_descriptor *head,
+ u32 semaphore);
+int stmp3xxx_dma_running(int ch);
+int stmp3xxx_dma_make_chain(int ch, struct stmp37xx_circ_dma_chain *chain,
+ struct stmp3xxx_dma_descriptor descriptors[],
+ unsigned items);
+void stmp3xxx_dma_free_chain(struct stmp37xx_circ_dma_chain *chain);
+void stmp37xx_circ_clear_chain(struct stmp37xx_circ_dma_chain *chain);
+void stmp37xx_circ_advance_free(struct stmp37xx_circ_dma_chain *chain,
+ unsigned count);
+void stmp37xx_circ_advance_active(struct stmp37xx_circ_dma_chain *chain,
+ unsigned count);
+unsigned stmp37xx_circ_advance_cooked(struct stmp37xx_circ_dma_chain *chain);
+int stmp3xxx_dma_read_semaphore(int ch);
+void stmp3xxx_dma_init(void);
+void stmp3xxx_dma_set_alt_target(int ch, int target);
+void stmp3xxx_dma_suspend(void);
+void stmp3xxx_dma_resume(void);
+
+/*
+ * STMP37xx and STMP378x have different DMA control
+ * registers layout
+ */
+
+void stmp3xxx_arch_dma_freeze(int ch);
+void stmp3xxx_arch_dma_unfreeze(int ch);
+void stmp3xxx_arch_dma_reset_channel(int ch);
+void stmp3xxx_arch_dma_enable_interrupt(int ch);
+void stmp3xxx_arch_dma_clear_interrupt(int ch);
+int stmp3xxx_arch_dma_is_interrupt(int ch);
+
+static inline void stmp3xxx_dma_reset_channel(int ch)
+{
+ stmp3xxx_arch_dma_reset_channel(ch);
+}
+
+
+static inline void stmp3xxx_dma_freeze(int ch)
+{
+ stmp3xxx_arch_dma_freeze(ch);
+}
+
+static inline void stmp3xxx_dma_unfreeze(int ch)
+{
+ stmp3xxx_arch_dma_unfreeze(ch);
+}
+
+static inline void stmp3xxx_dma_enable_interrupt(int ch)
+{
+ stmp3xxx_arch_dma_enable_interrupt(ch);
+}
+
+static inline void stmp3xxx_dma_clear_interrupt(int ch)
+{
+ stmp3xxx_arch_dma_clear_interrupt(ch);
+}
+
+static inline int stmp3xxx_dma_is_interrupt(int ch)
+{
+ return stmp3xxx_arch_dma_is_interrupt(ch);
+}
+
+#endif /* __ASM_PLAT_STMP3XXX_DMA_H */
diff --git a/arch/arm/plat-stmp3xxx/include/mach/gpio.h b/arch/arm/plat-stmp3xxx/include/mach/gpio.h
new file mode 100644
index 000000000000..a8b579256170
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/gpio.h
@@ -0,0 +1,28 @@
+/*
+ * Freescale STMP37XX/STMP378X GPIO interface
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_PLAT_GPIO_H
+#define __ASM_PLAT_GPIO_H
+
+#define ARCH_NR_GPIOS (32 * 3)
+#define gpio_to_irq(gpio) __gpio_to_irq(gpio)
+#define gpio_get_value(gpio) __gpio_get_value(gpio)
+#define gpio_set_value(gpio, value) __gpio_set_value(gpio, value)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_PLAT_GPIO_H */
diff --git a/arch/arm/plat-stmp3xxx/include/mach/hardware.h b/arch/arm/plat-stmp3xxx/include/mach/hardware.h
new file mode 100644
index 000000000000..47b8978405bc
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/hardware.h
@@ -0,0 +1,32 @@
+/*
+ * This file contains the hardware definitions of the Freescale STMP3XXX
+ *
+ * Copyright (C) 2005 Sigmatel Inc
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/*
+ * Where in virtual memory the IO devices (timers, system controllers
+ * and so on)
+ */
+#define IO_BASE 0xF0000000 /* VA of IO */
+#define IO_SIZE 0x00100000 /* How much? */
+#define IO_START 0x80000000 /* PA of IO */
+
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(x) (((x) & 0x000fffff) | IO_BASE)
+
+#endif
diff --git a/arch/arm/plat-stmp3xxx/include/mach/io.h b/arch/arm/plat-stmp3xxx/include/mach/io.h
new file mode 100644
index 000000000000..d08b1b7f3d1c
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/io.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2005 Sigmatel Inc
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+#define __mem_isa(a) (a)
+
+#endif
diff --git a/arch/arm/plat-stmp3xxx/include/mach/memory.h b/arch/arm/plat-stmp3xxx/include/mach/memory.h
new file mode 100644
index 000000000000..7b875a07a1a7
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/memory.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET UL(0x40000000)
+
+#endif
diff --git a/arch/arm/plat-stmp3xxx/include/mach/pinmux.h b/arch/arm/plat-stmp3xxx/include/mach/pinmux.h
new file mode 100644
index 000000000000..526c068d7c44
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/pinmux.h
@@ -0,0 +1,158 @@
+/*
+ * Freescale STMP37XX/STMP378X Pin Multiplexing
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __PINMUX_H
+#define __PINMUX_H
+
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <asm-generic/gpio.h>
+
+/* Pin definitions */
+#include "pins.h"
+#include <mach/pins.h>
+
+/*
+ * Each pin may be routed up to four different HW interfaces
+ * including GPIO
+ */
+enum pin_fun {
+ PIN_FUN1 = 0,
+ PIN_FUN2,
+ PIN_FUN3,
+ PIN_GPIO,
+};
+
+/*
+ * Each pin may have different output drive strength in range from
+ * 4mA to 20mA. The most common case is 4, 8 and 12 mA strengths.
+ */
+enum pin_strength {
+ PIN_4MA = 0,
+ PIN_8MA,
+ PIN_12MA,
+ PIN_16MA,
+ PIN_20MA,
+};
+
+/*
+ * Each pin can be programmed for 1.8V or 3.3V
+ */
+enum pin_voltage {
+ PIN_1_8V = 0,
+ PIN_3_3V,
+};
+
+/*
+ * Structure to define a group of pins and their parameters
+ */
+struct pin_desc {
+ unsigned id;
+ enum pin_fun fun;
+ enum pin_strength strength;
+ enum pin_voltage voltage;
+ unsigned pullup:1;
+};
+
+struct pin_group {
+ struct pin_desc *pins;
+ int nr_pins;
+};
+
+/* Set pin drive strength */
+void stmp3xxx_pin_strength(unsigned id, enum pin_strength strength,
+ const char *label);
+
+/* Set pin voltage */
+void stmp3xxx_pin_voltage(unsigned id, enum pin_voltage voltage,
+ const char *label);
+
+/* Enable pull-up resistor for a pin */
+void stmp3xxx_pin_pullup(unsigned id, int enable, const char *label);
+
+/*
+ * Request a pin ownership, only one module (identified by @label)
+ * may own a pin.
+ */
+int stmp3xxx_request_pin(unsigned id, enum pin_fun fun, const char *label);
+
+/* Release pin */
+void stmp3xxx_release_pin(unsigned id, const char *label);
+
+void stmp3xxx_set_pin_type(unsigned id, enum pin_fun fun);
+
+/*
+ * Each bank is associated with a number of registers to control
+ * pin function, drive strength, voltage and pull-up reigster. The
+ * number of registers of a given type depends on the number of bits
+ * describin particular pin.
+ */
+#define HW_MUXSEL_NUM 2 /* registers per bank */
+#define HW_MUXSEL_PIN_LEN 2 /* bits per pin */
+#define HW_MUXSEL_PIN_NUM 16 /* pins per register */
+#define HW_MUXSEL_PINFUN_MASK 0x3 /* pin function mask */
+#define HW_MUXSEL_PINFUN_NUM 4 /* four options for a pin */
+
+#define HW_DRIVE_NUM 4 /* registers per bank */
+#define HW_DRIVE_PIN_LEN 4 /* bits per pin */
+#define HW_DRIVE_PIN_NUM 8 /* pins per register */
+#define HW_DRIVE_PINDRV_MASK 0x3 /* pin strength mask - 2 bits */
+#define HW_DRIVE_PINDRV_NUM 5 /* five possible strength values */
+#define HW_DRIVE_PINV_MASK 0x4 /* pin voltage mask - 1 bit */
+
+
+struct stmp3xxx_pinmux_bank {
+ struct gpio_chip chip;
+
+ /* Pins allocation map */
+ unsigned long pin_map;
+
+ /* Pin owner names */
+ const char *pin_labels[32];
+
+ /* Bank registers */
+ void __iomem *hw_muxsel[HW_MUXSEL_NUM];
+ void __iomem *hw_drive[HW_DRIVE_NUM];
+ void __iomem *hw_pull;
+
+ void __iomem *pin2irq,
+ *irqlevel,
+ *irqpolarity,
+ *irqen,
+ *irqstat;
+
+ /* HW MUXSEL register function bit values */
+ u8 functions[HW_MUXSEL_PINFUN_NUM];
+
+ /*
+ * HW DRIVE register strength bit values:
+ * 0xff - requested strength is not supported for this bank
+ */
+ u8 strengths[HW_DRIVE_PINDRV_NUM];
+
+ /* GPIO things */
+ void __iomem *hw_gpio_read,
+ *hw_gpio_set,
+ *hw_gpio_clr,
+ *hw_gpio_doe;
+ int irq, virq;
+};
+
+int __init stmp3xxx_pinmux_init(int virtual_irq_start);
+
+#endif /* __PINMUX_H */
diff --git a/arch/arm/plat-stmp3xxx/include/mach/pins.h b/arch/arm/plat-stmp3xxx/include/mach/pins.h
new file mode 100644
index 000000000000..c573318e1caa
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/pins.h
@@ -0,0 +1,30 @@
+/*
+ * Freescale STMP37XX/STMP378X Pin multiplexing interface definitions
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_PLAT_PINS_H
+#define __ASM_PLAT_PINS_H
+
+#define STMP3XXX_PINID(bank, pin) (bank * 32 + pin)
+#define STMP3XXX_PINID_TO_BANK(pinid) (pinid / 32)
+#define STMP3XXX_PINID_TO_PINNUM(pinid) (pinid % 32)
+
+/*
+ * Special invalid pin identificator to show a pin doesn't exist
+ */
+#define PINID_NO_PIN STMP3XXX_PINID(0xFF, 0xFF)
+
+#endif /* __ASM_PLAT_PINS_H */
diff --git a/arch/arm/plat-stmp3xxx/include/mach/platform.h b/arch/arm/plat-stmp3xxx/include/mach/platform.h
new file mode 100644
index 000000000000..525c41379bbe
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/platform.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_PLAT_PLATFORM_H
+#define __ASM_PLAT_PLATFORM_H
+
+#include <asm/sizes.h>
+
+/* Virtual address where registers are mapped */
+#define STMP3XXX_REGS_PHBASE 0x80000000
+#ifdef __ASSEMBLER__
+#define STMP3XXX_REGS_BASE 0xF0000000
+#else
+#define STMP3XXX_REGS_BASE (void __iomem *)0xF0000000
+#endif
+#define STMP3XXX_REGS_SIZE SZ_1M
+
+/* Virtual address where OCRAM is mapped */
+#define STMP3XXX_OCRAM_PHBASE 0x00000000
+#ifdef __ASSEMBLER__
+#define STMP3XXX_OCRAM_BASE 0xf1000000
+#else
+#define STMP3XXX_OCRAM_BASE (void __iomem *)0xf1000000
+#endif
+#define STMP3XXX_OCRAM_SIZE (32 * SZ_1K)
+
+#ifdef CONFIG_ARCH_STMP37XX
+#define IRQ_PRIORITY_REG_RD HW_ICOLL_PRIORITYn_RD
+#define IRQ_PRIORITY_REG_WR HW_ICOLL_PRIORITYn_WR
+#endif
+
+#ifdef CONFIG_ARCH_STMP378X
+#define IRQ_PRIORITY_REG_RD HW_ICOLL_INTERRUPTn_RD
+#define IRQ_PRIORITY_REG_WR HW_ICOLL_INTERRUPTn_WR
+#endif
+
+#endif /* __ASM_ARCH_PLATFORM_H */
diff --git a/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h b/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h
new file mode 100644
index 000000000000..78cf1be75519
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h
@@ -0,0 +1,34 @@
+/*
+ * Freescale STMP37XX/STMP378X core structure and function declarations
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_PLAT_STMP3XXX_H
+#define __ASM_PLAT_STMP3XXX_H
+
+#include <linux/irq.h>
+
+extern struct sys_timer stmp3xxx_timer;
+
+void stmp3xxx_init_irq(struct irq_chip *chip);
+void stmp3xxx_init(void);
+int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable);
+extern struct platform_device stmp3xxx_dbguart;
+
+struct pin_group;
+void stmp3xxx_release_pin_group(struct pin_group *pin_group, const char *label);
+int stmp3xxx_request_pin_group(struct pin_group *pin_group, const char *label);
+
+#endif /* __ASM_PLAT_STMP3XXX_H */
diff --git a/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx_regs.h b/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx_regs.h
new file mode 100644
index 000000000000..47797b2b36af
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx_regs.h
@@ -0,0 +1,195 @@
+/*
+ * Freescale STMP37XX/STMP378X SoC register access interfaces
+ *
+ * The SoC registers may be accessed via:
+ *
+ * - single 32 bit address, or
+ * - four 32 bit addresses - general purpose, set, clear and toggle bits
+ *
+ * Multiple IP blocks (e.g. SSP, UART) provide identical register sets per
+ * each module
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_PLAT_STMP3XXX_REGS_H
+#define __ASM_PLAT_STMP3XXX_REGS_H
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+#include "platform.h"
+
+#define REGS_BASE STMP3XXX_REGS_BASE
+
+#define HW_STMP3xxx_SET 0x04
+#define HW_STMP3xxx_CLR 0x08
+#define HW_STMP3xxx_TOG 0x0c
+
+#ifndef __ASSEMBLER__
+#define HW_REGISTER_FUNCS(id, base, offset, regset, rd, wr) \
+ static const u32 id##_OFFSET = offset; \
+ static inline u32 id##_RD_NB(const void __iomem *regbase) { \
+ if (!rd) \
+ printk(KERN_ERR"%s: cannot READ at %p+%x\n", \
+ #id, regbase, offset); \
+ return __raw_readl(regbase + offset); \
+ } \
+ static inline void id##_WR_NB(void __iomem *regbase, u32 v) { \
+ if (!wr) \
+ printk(KERN_ERR"%s: cannot WRITE at %p+%x\n", \
+ #id, regbase, offset); \
+ __raw_writel(v, regbase + offset); \
+ } \
+ static inline void id##_SET_NB(void __iomem *regbase, u32 v) { \
+ if (!wr) \
+ printk(KERN_ERR"%s: cannot SET at %p+%x\n", \
+ #id, regbase, offset); \
+ if (regset) \
+ __raw_writel(v, regbase + \
+ offset + HW_STMP3xxx_SET); \
+ else \
+ __raw_writel(v | __raw_readl(regbase + offset), \
+ regbase + offset); \
+ } \
+ static inline void id##_CLR_NB(void __iomem *regbase, u32 v) { \
+ if (!wr) \
+ printk(KERN_ERR"%s: cannot CLR at %p+%x\n", \
+ #id, regbase, offset); \
+ if (regset) \
+ __raw_writel(v, regbase + \
+ offset + HW_STMP3xxx_CLR); \
+ else \
+ __raw_writel( \
+ ~v & __raw_readl(regbase + offset), \
+ regbase + offset); \
+ } \
+ static inline void id##_TOG_NB(void __iomem *regbase, u32 v) { \
+ if (!wr) \
+ printk(KERN_ERR"%s: cannot TOG at %p+%x\n", \
+ #id, regbase, offset); \
+ if (regset) \
+ __raw_writel(v, regbase + \
+ offset + HW_STMP3xxx_TOG); \
+ else \
+ __raw_writel(v ^ __raw_readl(regbase + offset), \
+ regbase + offset); \
+ } \
+ static inline u32 id##_RD(void) { return id##_RD_NB(base); } \
+ static inline void id##_WR(u32 v) { id##_WR_NB(base, v); } \
+ static inline void id##_SET(u32 v) { id##_SET_NB(base, v); } \
+ static inline void id##_CLR(u32 v) { id##_CLR_NB(base, v); } \
+ static inline void id##_TOG(u32 v) { id##_TOG_NB(base, v); }
+
+#define HW_REGISTER_FUNCS_INDEXED(id, base, offset, regset, rd, wr, step)\
+ static inline u32 id##_OFFSET(int i) { \
+ return offset + i * step; \
+ } \
+ static inline u32 id##_RD_NB(const void __iomem *regbase, int i) {\
+ if (!rd) \
+ printk(KERN_ERR"%s(%d): can't READ at %p+%x\n", \
+ #id, i, regbase, offset + i * step); \
+ return __raw_readl(regbase + offset + i * step); \
+ } \
+ static inline void id##_WR_NB(void __iomem *regbase, int i, u32 v) {\
+ if (!wr) \
+ printk(KERN_ERR"%s(%d): can't WRITE at %p+%x\n",\
+ #id, i, regbase, offset + i * step); \
+ __raw_writel(v, regbase + offset + i * step); \
+ } \
+ static inline void id##_SET_NB(void __iomem *regbase, int i, u32 v) {\
+ if (!wr) \
+ printk(KERN_ERR"%s(%d): can't SET at %p+%x\n", \
+ #id, i, regbase, offset + i * step); \
+ if (regset) \
+ __raw_writel(v, regbase + offset + \
+ i * step + HW_STMP3xxx_SET); \
+ else \
+ __raw_writel(v | __raw_readl(regbase + \
+ offset + i * step), \
+ regbase + offset + i * step); \
+ } \
+ static inline void id##_CLR_NB(void __iomem *regbase, int i, u32 v) {\
+ if (!wr) \
+ printk(KERN_ERR"%s(%d): cannot CLR at %p+%x\n", \
+ #id, i, regbase, offset + i * step); \
+ if (regset) \
+ __raw_writel(v, regbase + offset + \
+ i * step + HW_STMP3xxx_CLR); \
+ else \
+ __raw_writel(~v & __raw_readl(regbase + \
+ offset + i * step), \
+ regbase + offset + i * step); \
+ } \
+ static inline void id##_TOG_NB(void __iomem *regbase, int i, u32 v) {\
+ if (!wr) \
+ printk(KERN_ERR"%s(%d): cannot TOG at %p+%x\n", \
+ #id, i, regbase, offset + i * step); \
+ if (regset) \
+ __raw_writel(v, regbase + offset + \
+ i * step + HW_STMP3xxx_TOG); \
+ else \
+ __raw_writel(v ^ __raw_readl(regbase + offset \
+ + i * step), \
+ regbase + offset + i * step); \
+ } \
+ static inline u32 id##_RD(int i) \
+ { \
+ return id##_RD_NB(base, i); \
+ } \
+ static inline void id##_WR(int i, u32 v) \
+ { \
+ id##_WR_NB(base, i, v); \
+ } \
+ static inline void id##_SET(int i, u32 v) \
+ { \
+ id##_SET_NB(base, i, v); \
+ } \
+ static inline void id##_CLR(int i, u32 v) \
+ { \
+ id##_CLR_NB(base, i, v); \
+ } \
+ static inline void id##_TOG(int i, u32 v) \
+ { \
+ id##_TOG_NB(base, i, v); \
+ }
+
+#define HW_REGISTER_WO(id, base, offset)\
+ HW_REGISTER_FUNCS(id, base, offset, 1, 0, 1)
+#define HW_REGISTER_RO(id, base, offset)\
+ HW_REGISTER_FUNCS(id, base, offset, 1, 1, 0)
+#define HW_REGISTER(id, base, offset) \
+ HW_REGISTER_FUNCS(id, base, offset, 1, 1, 1)
+#define HW_REGISTER_0(id, base, offset) \
+ HW_REGISTER_FUNCS(id, base, offset, 0, 1, 1)
+#define HW_REGISTER_INDEXED(id, base, offset, step) \
+ HW_REGISTER_FUNCS_INDEXED(id, base, offset, 1, 1, 1, step)
+#define HW_REGISTER_RO_INDEXED(id, base, offset, step) \
+ HW_REGISTER_FUNCS_INDEXED(id, base, offset, 1, 1, 0, step)
+#define HW_REGISTER_0_INDEXED(id, base, offset, step) \
+ HW_REGISTER_FUNCS_INDEXED(id, base, offset, 0, 1, 1, step)
+#else /* __ASSEMBLER__ */
+#define HW_REGISTER_FUNCS(id, base, offset, regset, rd, wr)
+#define HW_REGISTER_FUNCS_INDEXED(id, base, offset, regset, rd, wr, step)
+#define HW_REGISTER_WO(id, base, offset)
+#define HW_REGISTER_RO(id, base, offset)
+#define HW_REGISTER(id, base, offset)
+#define HW_REGISTER_0(id, base, offset)
+#define HW_REGISTER_INDEXED(id, base, offset, step)
+#define HW_REGISTER_RO_INDEXED(id, base, offset, step)
+#define HW_REGISTER_0_INDEXED(id, base, offset, step)
+#endif /* __ASSEMBLER__ */
+
+#endif /* __ASM_PLAT_STMP3XXX_REGS_H */
diff --git a/arch/arm/plat-stmp3xxx/include/mach/system.h b/arch/arm/plat-stmp3xxx/include/mach/system.h
new file mode 100644
index 000000000000..dac48d267148
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/system.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2005 Sigmatel Inc
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/proc-fns.h>
+#include <mach/regs-clkctrl.h>
+#include <mach/regs-power.h>
+
+static inline void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks
+ */
+
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /* Set BATTCHRG to default value */
+ HW_POWER_CHARGE_WR(0x00010000);
+
+ /* Set MINPWR to default value */
+ HW_POWER_MINPWR_WR(0);
+
+ /* Reset digital side of chip (but not power or RTC) */
+ HW_CLKCTRL_RESET_WR(BM_CLKCTRL_RESET_DIG);
+
+ /* Should not return */
+}
+
+#endif
diff --git a/arch/arm/plat-stmp3xxx/include/mach/timex.h b/arch/arm/plat-stmp3xxx/include/mach/timex.h
new file mode 100644
index 000000000000..3373985d7a8e
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/timex.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * System time clock is sourced from the 32k clock
+ */
+#define CLOCK_TICK_RATE (32768)
diff --git a/arch/arm/plat-stmp3xxx/include/mach/uncompress.h b/arch/arm/plat-stmp3xxx/include/mach/uncompress.h
new file mode 100644
index 000000000000..f79f5ee56cd4
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/uncompress.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_PLAT_UNCOMPRESS_H
+#define __ASM_PLAT_UNCOMPRESS_H
+
+/*
+ * Register includes are for when the MMU enabled; we need to define our
+ * own stuff here for pre-MMU use
+ */
+#define UARTDBG_BASE 0x80070000
+#define UART(c) (((volatile unsigned *)UARTDBG_BASE)[c])
+
+/*
+ * This does not append a newline
+ */
+static void putc(char c)
+{
+ /* Wait for TX fifo empty */
+ while ((UART(6) & (1<<7)) == 0)
+ continue;
+
+ /* Write byte */
+ UART(0) = c;
+
+ /* Wait for last bit to exit the UART */
+ while (UART(6) & (1<<3))
+ continue;
+}
+
+static void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
+
+#endif /* __ASM_PLAT_UNCOMPRESS_H */
diff --git a/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h b/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h
new file mode 100644
index 000000000000..541b880c1863
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#define VMALLOC_END (0xF0000000)
diff --git a/arch/arm/plat-stmp3xxx/irq.c b/arch/arm/plat-stmp3xxx/irq.c
new file mode 100644
index 000000000000..cb3659096681
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/irq.c
@@ -0,0 +1,59 @@
+/*
+ * Freescale STMP37XX/STMP378X common interrupt handling code
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/sysdev.h>
+
+#include <mach/stmp3xxx.h>
+#include <mach/regs-icoll.h>
+
+void __init stmp3xxx_init_irq(struct irq_chip *chip)
+{
+ unsigned int i;
+
+ /* Reset the interrupt controller */
+ HW_ICOLL_CTRL_CLR(BM_ICOLL_CTRL_CLKGATE);
+ udelay(10);
+ HW_ICOLL_CTRL_CLR(BM_ICOLL_CTRL_SFTRST);
+ udelay(10);
+ HW_ICOLL_CTRL_SET(BM_ICOLL_CTRL_SFTRST);
+ while (!(HW_ICOLL_CTRL_RD() & BM_ICOLL_CTRL_CLKGATE))
+ continue;
+ HW_ICOLL_CTRL_CLR(BM_ICOLL_CTRL_SFTRST | BM_ICOLL_CTRL_CLKGATE);
+
+ /* Disable all interrupts initially */
+ for (i = 0; i < NR_REAL_IRQS; i++) {
+ chip->mask(i);
+ set_irq_chip(i, chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+
+ /* Ensure vector is cleared */
+ HW_ICOLL_LEVELACK_WR(1);
+ HW_ICOLL_LEVELACK_WR(2);
+ HW_ICOLL_LEVELACK_WR(4);
+ HW_ICOLL_LEVELACK_WR(8);
+
+ HW_ICOLL_VECTOR_WR(0);
+ /* Barrier */
+ (void) HW_ICOLL_STAT_RD();
+}
+
diff --git a/arch/arm/plat-stmp3xxx/pinmux.c b/arch/arm/plat-stmp3xxx/pinmux.c
new file mode 100644
index 000000000000..9b28cc83f31c
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/pinmux.c
@@ -0,0 +1,545 @@
+/*
+ * Freescale STMP378X/STMP378X Pin Multiplexing
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sysdev.h>
+#include <linux/string.h>
+#include <linux/bitops.h>
+#include <linux/sysdev.h>
+#include <linux/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-pinctrl.h>
+#include <mach/pins.h>
+#include <mach/pinmux.h>
+
+#define NR_BANKS ARRAY_SIZE(pinmux_banks)
+static struct stmp3xxx_pinmux_bank pinmux_banks[] = {
+ [0] = {
+ .hw_muxsel = {
+ HW_PINCTRL_MUXSEL0_ADDR,
+ HW_PINCTRL_MUXSEL1_ADDR
+ },
+ .hw_drive = {
+ HW_PINCTRL_DRIVE0_ADDR,
+ HW_PINCTRL_DRIVE1_ADDR,
+ HW_PINCTRL_DRIVE2_ADDR,
+ HW_PINCTRL_DRIVE3_ADDR
+ },
+ .hw_pull = HW_PINCTRL_PULL0_ADDR,
+ .functions = { 0x0, 0x1, 0x2, 0x3 },
+ .strengths = { 0x0, 0x1, 0x2, 0x3, 0xff },
+
+ .hw_gpio_read = HW_PINCTRL_DIN0_ADDR,
+ .hw_gpio_set = HW_PINCTRL_DOUT0_ADDR + HW_STMP3xxx_SET,
+ .hw_gpio_clr = HW_PINCTRL_DOUT0_ADDR + HW_STMP3xxx_CLR,
+ .hw_gpio_doe = HW_PINCTRL_DOE0_ADDR,
+ .irq = IRQ_GPIO0,
+
+ .pin2irq = HW_PINCTRL_PIN2IRQ0_ADDR,
+ .irqstat = HW_PINCTRL_IRQSTAT0_ADDR,
+ .irqlevel = HW_PINCTRL_IRQLEVEL0_ADDR,
+ .irqpolarity = HW_PINCTRL_IRQPOL0_ADDR,
+ .irqen = HW_PINCTRL_IRQEN0_ADDR,
+ },
+ [1] = {
+ .hw_muxsel = {
+ HW_PINCTRL_MUXSEL2_ADDR,
+ HW_PINCTRL_MUXSEL3_ADDR
+ },
+ .hw_drive = {
+ HW_PINCTRL_DRIVE4_ADDR,
+ HW_PINCTRL_DRIVE5_ADDR,
+ HW_PINCTRL_DRIVE6_ADDR,
+ HW_PINCTRL_DRIVE7_ADDR
+ },
+ .hw_pull = HW_PINCTRL_PULL1_ADDR,
+ .functions = { 0x0, 0x1, 0x2, 0x3 },
+ .strengths = { 0x0, 0x1, 0x2, 0x3, 0xff },
+
+ .hw_gpio_read = HW_PINCTRL_DIN1_ADDR,
+ .hw_gpio_set = HW_PINCTRL_DOUT1_ADDR + HW_STMP3xxx_SET,
+ .hw_gpio_clr = HW_PINCTRL_DOUT1_ADDR + HW_STMP3xxx_CLR,
+ .hw_gpio_doe = HW_PINCTRL_DOE1_ADDR,
+ .irq = IRQ_GPIO1,
+
+ .pin2irq = HW_PINCTRL_PIN2IRQ1_ADDR,
+ .irqstat = HW_PINCTRL_IRQSTAT1_ADDR,
+ .irqlevel = HW_PINCTRL_IRQLEVEL1_ADDR,
+ .irqpolarity = HW_PINCTRL_IRQPOL1_ADDR,
+ .irqen = HW_PINCTRL_IRQEN1_ADDR,
+ },
+ [2] = {
+ .hw_muxsel = {
+ HW_PINCTRL_MUXSEL4_ADDR,
+ HW_PINCTRL_MUXSEL5_ADDR,
+ },
+ .hw_drive = {
+ HW_PINCTRL_DRIVE8_ADDR,
+ HW_PINCTRL_DRIVE9_ADDR,
+ HW_PINCTRL_DRIVE10_ADDR,
+ HW_PINCTRL_DRIVE11_ADDR,
+ },
+ .hw_pull = HW_PINCTRL_PULL2_ADDR,
+ .functions = { 0x0, 0x1, 0x2, 0x3 },
+ .strengths = { 0x0, 0x1, 0x2, 0x1, 0x2 },
+
+ .hw_gpio_read = HW_PINCTRL_DIN2_ADDR,
+ .hw_gpio_set = HW_PINCTRL_DOUT2_ADDR + HW_STMP3xxx_SET,
+ .hw_gpio_clr = HW_PINCTRL_DOUT2_ADDR + HW_STMP3xxx_CLR,
+ .hw_gpio_doe = HW_PINCTRL_DOE2_ADDR,
+ .irq = IRQ_GPIO2,
+
+ .pin2irq = HW_PINCTRL_PIN2IRQ2_ADDR,
+ .irqstat = HW_PINCTRL_IRQSTAT2_ADDR,
+ .irqlevel = HW_PINCTRL_IRQLEVEL2_ADDR,
+ .irqpolarity = HW_PINCTRL_IRQPOL2_ADDR,
+ .irqen = HW_PINCTRL_IRQEN2_ADDR,
+ },
+ [3] = {
+ .hw_muxsel = {
+ HW_PINCTRL_MUXSEL6_ADDR,
+ HW_PINCTRL_MUXSEL7_ADDR,
+ },
+ .hw_drive = {
+ HW_PINCTRL_DRIVE12_ADDR,
+ HW_PINCTRL_DRIVE13_ADDR,
+ HW_PINCTRL_DRIVE14_ADDR,
+ NULL,
+ },
+ .hw_pull = HW_PINCTRL_PULL3_ADDR,
+ .functions = {0x0, 0x1, 0x2, 0x3},
+ .strengths = {0x0, 0x1, 0x2, 0x3, 0xff},
+ },
+};
+
+static inline struct stmp3xxx_pinmux_bank *
+stmp3xxx_pinmux_bank(unsigned id, unsigned *bank, unsigned *pin)
+{
+ unsigned b, p;
+
+ b = STMP3XXX_PINID_TO_BANK(id);
+ p = STMP3XXX_PINID_TO_PINNUM(id);
+ BUG_ON(b >= NR_BANKS);
+ if (bank)
+ *bank = b;
+ if (pin)
+ *pin = p;
+ return &pinmux_banks[b];
+}
+
+/* Check if requested pin is owned by caller */
+static int stmp3xxx_check_pin(unsigned id, const char *label)
+{
+ unsigned pin;
+ struct stmp3xxx_pinmux_bank *pm = stmp3xxx_pinmux_bank(id, NULL, &pin);
+
+ if (!test_bit(pin, &pm->pin_map)) {
+ printk(KERN_WARNING
+ "%s: Accessing free pin %x, caller %s\n",
+ __func__, id, label);
+
+ return -EINVAL;
+ }
+
+ if (label && pm->pin_labels[pin] &&
+ strcmp(label, pm->pin_labels[pin])) {
+ printk(KERN_WARNING
+ "%s: Wrong pin owner %x, caller %s owner %s\n",
+ __func__, id, label, pm->pin_labels[pin]);
+
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void stmp3xxx_pin_strength(unsigned id, enum pin_strength strength,
+ const char *label)
+{
+ struct stmp3xxx_pinmux_bank *pbank;
+ void __iomem *hwdrive;
+ u32 shift, val;
+ u32 bank, pin;
+
+ pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
+ pr_debug("%s: label %s bank %d pin %d strength %d\n", __func__, label,
+ bank, pin, strength);
+
+ hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM];
+ shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN;
+ val = pbank->strengths[strength];
+ if (val == 0xff) {
+ printk(KERN_WARNING
+ "%s: strength is not supported for bank %d, caller %s",
+ __func__, bank, label);
+ return;
+ }
+
+ if (stmp3xxx_check_pin(id, label))
+ return;
+
+ pr_debug("%s: writing 0x%x to 0x%p register\n", __func__,
+ val << shift, hwdrive);
+ __raw_writel(HW_DRIVE_PINDRV_MASK << shift, hwdrive + HW_STMP3xxx_CLR);
+ __raw_writel(val << shift, hwdrive + HW_STMP3xxx_SET);
+}
+
+void stmp3xxx_pin_voltage(unsigned id, enum pin_voltage voltage,
+ const char *label)
+{
+ struct stmp3xxx_pinmux_bank *pbank;
+ void __iomem *hwdrive;
+ u32 shift;
+ u32 bank, pin;
+
+ pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
+ pr_debug("%s: label %s bank %d pin %d voltage %d\n", __func__, label,
+ bank, pin, voltage);
+
+ hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM];
+ shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN;
+
+ if (stmp3xxx_check_pin(id, label))
+ return;
+
+ pr_debug("%s: changing 0x%x bit in 0x%p register\n",
+ __func__, HW_DRIVE_PINV_MASK << shift, hwdrive);
+ if (voltage == PIN_1_8V)
+ __raw_writel(HW_DRIVE_PINV_MASK << shift,
+ hwdrive + HW_STMP3xxx_CLR);
+ else
+ __raw_writel(HW_DRIVE_PINV_MASK << shift,
+ hwdrive + HW_STMP3xxx_SET);
+}
+
+void stmp3xxx_pin_pullup(unsigned id, int enable, const char *label)
+{
+ struct stmp3xxx_pinmux_bank *pbank;
+ void __iomem *hwpull;
+ u32 bank, pin;
+
+ pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
+ pr_debug("%s: label %s bank %d pin %d enable %d\n", __func__, label,
+ bank, pin, enable);
+
+ hwpull = pbank->hw_pull;
+
+ if (stmp3xxx_check_pin(id, label))
+ return;
+
+ pr_debug("%s: changing 0x%x bit in 0x%p register\n",
+ __func__, 1 << pin, hwpull);
+ __raw_writel(1 << pin,
+ hwpull + (enable ? HW_STMP3xxx_SET : HW_STMP3xxx_CLR));
+}
+
+int stmp3xxx_request_pin(unsigned id, enum pin_fun fun, const char *label)
+{
+ struct stmp3xxx_pinmux_bank *pbank;
+ u32 bank, pin;
+ int ret = 0;
+
+ pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
+ pr_debug("%s: label %s bank %d pin %d fun %d\n", __func__, label,
+ bank, pin, fun);
+
+ if (test_bit(pin, &pbank->pin_map)) {
+ printk(KERN_WARNING
+ "%s: CONFLICT DETECTED pin %d:%d caller %s owner %s\n",
+ __func__, bank, pin, label, pbank->pin_labels[pin]);
+ return -EBUSY;
+ }
+
+ set_bit(pin, &pbank->pin_map);
+ pbank->pin_labels[pin] = label;
+
+ stmp3xxx_set_pin_type(id, fun);
+
+ return ret;
+}
+
+void stmp3xxx_set_pin_type(unsigned id, enum pin_fun fun)
+{
+ struct stmp3xxx_pinmux_bank *pbank;
+ void __iomem *hwmux;
+ u32 shift, val;
+ u32 bank, pin;
+
+ pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
+
+ hwmux = pbank->hw_muxsel[pin / HW_MUXSEL_PIN_NUM];
+ shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN;
+
+ val = pbank->functions[fun];
+ shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN;
+ pr_debug("%s: writing 0x%x to 0x%p register\n",
+ __func__, val << shift, hwmux);
+ __raw_writel(HW_MUXSEL_PINFUN_MASK << shift, hwmux + HW_STMP3xxx_CLR);
+ __raw_writel(val << shift, hwmux + HW_STMP3xxx_SET);
+}
+
+void stmp3xxx_release_pin(unsigned id, const char *label)
+{
+ struct stmp3xxx_pinmux_bank *pbank;
+ u32 bank, pin;
+
+ pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
+ pr_debug("%s: label %s bank %d pin %d\n", __func__, label, bank, pin);
+
+ if (stmp3xxx_check_pin(id, label))
+ return;
+
+ clear_bit(pin, &pbank->pin_map);
+ pbank->pin_labels[pin] = NULL;
+}
+
+int stmp3xxx_request_pin_group(struct pin_group *pin_group, const char *label)
+{
+ struct pin_desc *pin;
+ int p;
+ int err = 0;
+
+ /* Allocate and configure pins */
+ for (p = 0; p < pin_group->nr_pins; p++) {
+ pr_debug("%s: #%d\n", __func__, p);
+ pin = &pin_group->pins[p];
+
+ err = stmp3xxx_request_pin(pin->id, pin->fun, label);
+ if (err)
+ goto out_err;
+
+ stmp3xxx_pin_strength(pin->id, pin->strength, label);
+ stmp3xxx_pin_voltage(pin->id, pin->voltage, label);
+ stmp3xxx_pin_pullup(pin->id, pin->pullup, label);
+ }
+
+ return 0;
+
+out_err:
+ /* Release allocated pins in case of error */
+ while (--p >= 0) {
+ pr_debug("%s: releasing #%d\n", __func__, p);
+ stmp3xxx_release_pin(pin_group->pins[p].id, label);
+ }
+ return err;
+}
+EXPORT_SYMBOL(stmp3xxx_request_pin_group);
+
+void stmp3xxx_release_pin_group(struct pin_group *pin_group, const char *label)
+{
+ struct pin_desc *pin;
+ int p;
+
+ for (p = 0; p < pin_group->nr_pins; p++) {
+ pin = &pin_group->pins[p];
+ stmp3xxx_release_pin(pin->id, label);
+ }
+}
+EXPORT_SYMBOL(stmp3xxx_release_pin_group);
+
+static int stmp3xxx_irq_to_gpio(int irq,
+ struct stmp3xxx_pinmux_bank **bank, unsigned *gpio)
+{
+ struct stmp3xxx_pinmux_bank *pm;
+
+ for (pm = pinmux_banks; pm < pinmux_banks + NR_BANKS; pm++)
+ if (pm->virq <= irq && irq < pm->virq + 32) {
+ *bank = pm;
+ *gpio = irq - pm->virq;
+ return 0;
+ }
+ return -ENOENT;
+}
+
+static int stmp3xxx_set_irqtype(unsigned irq, unsigned type)
+{
+ struct stmp3xxx_pinmux_bank *pm;
+ unsigned gpio;
+ int l, p;
+
+ stmp3xxx_irq_to_gpio(irq, &pm, &gpio);
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ l = 0; p = 1; break;
+ case IRQ_TYPE_EDGE_FALLING:
+ l = 0; p = 0; break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ l = 1; p = 1; break;
+ case IRQ_TYPE_LEVEL_LOW:
+ l = 1; p = 0; break;
+ default:
+ pr_debug("%s: Incorrect GPIO interrupt type 0x%x\n",
+ __func__, type);
+ return -ENXIO;
+ }
+ __raw_writel(1 << gpio,
+ pm->irqlevel + (l ? HW_STMP3xxx_SET : HW_STMP3xxx_CLR));
+ __raw_writel(1 << gpio,
+ pm->irqpolarity + (p ? HW_STMP3xxx_SET : HW_STMP3xxx_CLR));
+ return 0;
+}
+
+static void stmp3xxx_pin_ack_irq(unsigned irq)
+{
+ u32 stat;
+ struct stmp3xxx_pinmux_bank *pm;
+ unsigned gpio;
+
+ stmp3xxx_irq_to_gpio(irq, &pm, &gpio);
+ stat = __raw_readl(pm->irqstat) & (1<<gpio);
+ __raw_writel(stat, pm->irqstat + HW_STMP3xxx_CLR);
+}
+
+static void stmp3xxx_pin_mask_irq(unsigned irq)
+{
+ struct stmp3xxx_pinmux_bank *pm;
+ unsigned gpio;
+
+ stmp3xxx_irq_to_gpio(irq, &pm, &gpio);
+ __raw_writel(1 << gpio, pm->irqen + HW_STMP3xxx_CLR);
+ __raw_writel(1 << gpio, pm->pin2irq + HW_STMP3xxx_CLR);
+}
+
+static void stmp3xxx_pin_unmask_irq(unsigned irq)
+{
+ struct stmp3xxx_pinmux_bank *pm;
+ unsigned gpio;
+
+ stmp3xxx_irq_to_gpio(irq, &pm, &gpio);
+ __raw_writel(1 << gpio, pm->irqen + HW_STMP3xxx_SET);
+ __raw_writel(1 << gpio, pm->pin2irq + HW_STMP3xxx_SET);
+}
+
+static inline
+struct stmp3xxx_pinmux_bank *to_pinmux_bank(struct gpio_chip *chip)
+{
+ return container_of(chip, struct stmp3xxx_pinmux_bank, chip);
+}
+
+static int stmp3xxx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
+ return pm->virq + offset;
+}
+
+static int stmp3xxx_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
+ unsigned v;
+
+ v = __raw_readl(pm->hw_gpio_read) & (1 << offset);
+ return v ? 1 : 0;
+}
+
+static void stmp3xxx_gpio_set(struct gpio_chip *chip, unsigned offset, int v)
+{
+ struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
+
+ __raw_writel(1 << offset, v ? pm->hw_gpio_set : pm->hw_gpio_clr);
+}
+
+static int stmp3xxx_gpio_output(struct gpio_chip *chip, unsigned offset, int v)
+{
+ struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
+
+ __raw_writel(1 << offset, pm->hw_gpio_doe + HW_STMP3xxx_SET);
+ stmp3xxx_gpio_set(chip, offset, v);
+ return 0;
+}
+
+static int stmp3xxx_gpio_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
+
+ __raw_writel(1 << offset, pm->hw_gpio_doe + HW_STMP3xxx_CLR);
+ return 0;
+}
+
+static int stmp3xxx_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return stmp3xxx_request_pin(chip->base + offset, PIN_GPIO, "gpio");
+}
+
+static void stmp3xxx_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ stmp3xxx_release_pin(chip->base + offset, "gpio");
+}
+
+static void stmp3xxx_gpio_irq(u32 irq, struct irq_desc *desc)
+{
+ struct stmp3xxx_pinmux_bank *pm = get_irq_data(irq);
+ int gpio_irq = pm->virq;
+ u32 stat = __raw_readl(pm->irqstat);
+
+ while (stat) {
+ if (stat & 1)
+ irq_desc[gpio_irq].handle_irq(gpio_irq,
+ &irq_desc[gpio_irq]);
+ gpio_irq++;
+ stat >>= 1;
+ }
+}
+
+static struct irq_chip gpio_irq_chip = {
+ .ack = stmp3xxx_pin_ack_irq,
+ .mask = stmp3xxx_pin_mask_irq,
+ .unmask = stmp3xxx_pin_unmask_irq,
+ .set_type = stmp3xxx_set_irqtype,
+};
+
+int __init stmp3xxx_pinmux_init(int virtual_irq_start)
+{
+ int b, r = 0;
+ struct stmp3xxx_pinmux_bank *pm;
+ int virq;
+
+ for (b = 0; b < 3; b++) {
+ /* only banks 0,1,2 are allowed to GPIO */
+ pm = pinmux_banks + b;
+ pm->chip.base = 32 * b;
+ pm->chip.ngpio = 32;
+ pm->chip.owner = THIS_MODULE;
+ pm->chip.can_sleep = 1;
+ pm->chip.exported = 1;
+ pm->chip.to_irq = stmp3xxx_gpio_to_irq;
+ pm->chip.direction_input = stmp3xxx_gpio_input;
+ pm->chip.direction_output = stmp3xxx_gpio_output;
+ pm->chip.get = stmp3xxx_gpio_get;
+ pm->chip.set = stmp3xxx_gpio_set;
+ pm->chip.request = stmp3xxx_gpio_request;
+ pm->chip.free = stmp3xxx_gpio_free;
+ pm->virq = virtual_irq_start + b * 32;
+
+ for (virq = pm->virq; virq < pm->virq; virq++) {
+ gpio_irq_chip.mask(virq);
+ set_irq_chip(virq, &gpio_irq_chip);
+ set_irq_handler(virq, handle_level_irq);
+ set_irq_flags(virq, IRQF_VALID);
+ }
+ r = gpiochip_add(&pm->chip);
+ if (r < 0)
+ break;
+ set_irq_chained_handler(pm->irq, stmp3xxx_gpio_irq);
+ set_irq_data(pm->irq, pm);
+ }
+ return r;
+}
+
+MODULE_AUTHOR("Vladislav Buzov");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-stmp3xxx/timer.c b/arch/arm/plat-stmp3xxx/timer.c
new file mode 100644
index 000000000000..7d872f0aee70
--- /dev/null
+++ b/arch/arm/plat-stmp3xxx/timer.c
@@ -0,0 +1,172 @@
+/*
+ * System timer for Freescale STMP37XX/STMP378X
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach/time.h>
+#include <mach/stmp3xxx.h>
+#include <mach/regs-timrot.h>
+
+static irqreturn_t
+stmp3xxx_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *c = dev_id;
+
+ if (HW_TIMROT_TIMCTRLn_RD(0) & (1<<15)) {
+ HW_TIMROT_TIMCTRLn_CLR(0, (1<<15));
+ c->event_handler(c);
+ } else if (HW_TIMROT_TIMCTRLn_RD(1) & (1<<15)) {
+ HW_TIMROT_TIMCTRLn_CLR(1, (1<<15));
+ HW_TIMROT_TIMCTRLn_CLR(1, BM_TIMROT_TIMCTRLn_IRQ_EN);
+ HW_TIMROT_TIMCOUNTn_WR(1, 0xFFFF);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static cycle_t stmp3xxx_clock_read(struct clocksource *cs)
+{
+ return ~((HW_TIMROT_TIMCOUNTn_RD(1) & 0xFFFF0000) >> 16);
+}
+
+static int
+stmp3xxx_timrot_set_next_event(unsigned long delta,
+ struct clock_event_device *dev)
+{
+ HW_TIMROT_TIMCOUNTn_WR(0, delta); /* reload */
+ return 0;
+}
+
+static void
+stmp3xxx_timrot_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *dev)
+{
+}
+
+static struct clock_event_device ckevt_timrot = {
+ .name = "timrot",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_next_event = stmp3xxx_timrot_set_next_event,
+ .set_mode = stmp3xxx_timrot_set_mode,
+};
+
+static struct clocksource cksrc_stmp3xxx = {
+ .name = "cksrc_stmp3xxx",
+ .rating = 250,
+ .read = stmp3xxx_clock_read,
+ .mask = CLOCKSOURCE_MASK(16),
+ .shift = 10,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static struct irqaction stmp3xxx_timer_irq = {
+ .name = "stmp3xxx_timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = stmp3xxx_timer_interrupt,
+ .dev_id = &ckevt_timrot,
+};
+
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static void __init stmp3xxx_init_timer(void)
+{
+ cksrc_stmp3xxx.mult = clocksource_hz2mult(CLOCK_TICK_RATE,
+ cksrc_stmp3xxx.shift);
+ ckevt_timrot.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
+ ckevt_timrot.shift);
+ ckevt_timrot.min_delta_ns = clockevent_delta2ns(2, &ckevt_timrot);
+ ckevt_timrot.max_delta_ns = clockevent_delta2ns(0xFFF, &ckevt_timrot);
+ ckevt_timrot.cpumask = cpumask_of(0);
+
+ HW_TIMROT_ROTCTRL_CLR(BM_TIMROT_ROTCTRL_SFTRST |
+ BM_TIMROT_ROTCTRL_CLKGATE);
+ HW_TIMROT_TIMCOUNTn_WR(0, 0);
+ HW_TIMROT_TIMCOUNTn_WR(1, 0);
+
+ HW_TIMROT_TIMCTRLn_WR(0,
+ (BF_TIMROT_TIMCTRLn_SELECT(8) | /* 32 kHz */
+ BF_TIMROT_TIMCTRLn_PRESCALE(0) |
+ BM_TIMROT_TIMCTRLn_RELOAD |
+ BM_TIMROT_TIMCTRLn_UPDATE |
+ BM_TIMROT_TIMCTRLn_IRQ_EN));
+ HW_TIMROT_TIMCTRLn_WR(1,
+ (BF_TIMROT_TIMCTRLn_SELECT(8) | /* 32 kHz */
+ BF_TIMROT_TIMCTRLn_PRESCALE(0) |
+ BM_TIMROT_TIMCTRLn_RELOAD |
+ BM_TIMROT_TIMCTRLn_UPDATE));
+
+ HW_TIMROT_TIMCOUNTn_WR(0, CLOCK_TICK_RATE / HZ - 1);
+ HW_TIMROT_TIMCOUNTn_WR(1, 0xFFFF); /* reload */
+
+ setup_irq(IRQ_TIMER0, &stmp3xxx_timer_irq);
+
+ clocksource_register(&cksrc_stmp3xxx);
+ clockevents_register_device(&ckevt_timrot);
+}
+
+#ifdef CONFIG_PM
+
+void stmp3xxx_suspend_timer(void)
+{
+ HW_TIMROT_TIMCTRLn_CLR(0, BM_TIMROT_TIMCTRLn_IRQ_EN);
+ HW_TIMROT_TIMCTRLn_CLR(0, (1<<15));
+ HW_TIMROT_ROTCTRL_SET(BM_TIMROT_ROTCTRL_CLKGATE);
+}
+
+void stmp3xxx_resume_timer(void)
+{
+ HW_TIMROT_ROTCTRL_CLR(BM_TIMROT_ROTCTRL_SFTRST |
+ BM_TIMROT_ROTCTRL_CLKGATE);
+
+
+ HW_TIMROT_TIMCTRLn_WR(0,
+ (BF_TIMROT_TIMCTRLn_SELECT(8) | /* 32 kHz */
+ BF_TIMROT_TIMCTRLn_PRESCALE(0) |
+ BM_TIMROT_TIMCTRLn_UPDATE |
+ BM_TIMROT_TIMCTRLn_IRQ_EN));
+ HW_TIMROT_TIMCTRLn_WR(1,
+ (BF_TIMROT_TIMCTRLn_SELECT(8) | /* 32 kHz */
+ BF_TIMROT_TIMCTRLn_PRESCALE(0) |
+ BM_TIMROT_TIMCTRLn_RELOAD |
+ BM_TIMROT_TIMCTRLn_UPDATE));
+
+ HW_TIMROT_TIMCOUNTn_WR(0, CLOCK_TICK_RATE / HZ - 1);
+ HW_TIMROT_TIMCOUNTn_WR(1, 0xFFFF); /* reload */
+}
+
+#else
+
+#define stmp3xxx_suspend_timer NULL
+#define stmp3xxx_resume_timer NULL
+
+#endif /* CONFIG_PM */
+
+struct sys_timer stmp3xxx_timer = {
+ .init = stmp3xxx_init_timer,
+ .suspend = stmp3xxx_suspend_timer,
+ .resume = stmp3xxx_resume_timer,
+};
diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c
index 20b300cf105a..623b077594fc 100644
--- a/arch/avr32/boards/merisc/setup.c
+++ b/arch/avr32/boards/merisc/setup.c
@@ -94,9 +94,10 @@ static struct spi_board_info __initdata spi0_board_info[] = {
static struct mci_platform_data __initdata mci0_data = {
.slot[0] = {
- .bus_width = 4,
- .detect_pin = GPIO_PIN_PE(19),
- .wp_pin = GPIO_PIN_PE(20),
+ .bus_width = 4,
+ .detect_pin = GPIO_PIN_PE(19),
+ .wp_pin = GPIO_PIN_PE(20),
+ .detect_is_active_high = true,
},
};
diff --git a/arch/avr32/include/asm/hw_irq.h b/arch/avr32/include/asm/hw_irq.h
index 218b0a6bfd1b..a36f9fcb8fcd 100644
--- a/arch/avr32/include/asm/hw_irq.h
+++ b/arch/avr32/include/asm/hw_irq.h
@@ -1,7 +1,7 @@
#ifndef __ASM_AVR32_HW_IRQ_H
#define __ASM_AVR32_HW_IRQ_H
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
+static inline void hw_resend_irq(struct irq_chip *h, unsigned int i)
{
/* Nothing to do */
}
diff --git a/arch/cris/Makefile b/arch/cris/Makefile
index 3662cfb7b61d..71e17d3eeddb 100644
--- a/arch/cris/Makefile
+++ b/arch/cris/Makefile
@@ -70,7 +70,7 @@ SRC_ARCH = $(srctree)/arch/cris
# cris object files path
OBJ_ARCH = $(objtree)/arch/cris
-boot := arch/cris/$(SARCH)/boot
+boot := arch/cris/boot
MACHINE := arch/cris/$(SARCH)
all: zImage
@@ -81,15 +81,15 @@ zImage Image: vmlinux
archprepare:
archclean:
- $(Q)if [ -e arch/cris/$(SARCH)/boot ]; then \
- $(MAKE) $(clean)=arch/cris/$(SARCH)/boot; \
+ $(Q)if [ -e arch/cris/boot ]; then \
+ $(MAKE) $(clean)=arch/cris/boot; \
fi
CLEAN_FILES += \
- $(MACHINE)/boot/zImage \
- $(MACHINE)/boot/compressed/decompress.bin \
- $(MACHINE)/boot/compressed/piggy.gz \
- $(MACHINE)/boot/rescue/rescue.bin
+ $(boot)/zImage \
+ $(boot)/compressed/decompress.bin \
+ $(boot)/compressed/piggy.gz \
+ $(boot)/rescue/rescue.bin
# MRPROPER_FILES +=
diff --git a/arch/cris/arch-v10/boot/compressed/README b/arch/cris/arch-v10/boot/compressed/README
deleted file mode 100644
index 48b3db9924b9..000000000000
--- a/arch/cris/arch-v10/boot/compressed/README
+++ /dev/null
@@ -1,25 +0,0 @@
-Creation of the self-extracting compressed kernel image (vmlinuz)
------------------------------------------------------------------
-$Id: README,v 1.1 2001/12/17 13:59:27 bjornw Exp $
-
-This can be slightly confusing because it's a process with many steps.
-
-The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
-by that makefile into text and data binary files, vmlinux.text and
-vmlinux.data.
-
-Those files together with a ROM filesystem can be catted together and
-burned into a flash or executed directly at the DRAM origin.
-
-They can also be catted together and compressed with gzip, which is what
-happens in this makefile. Together they make up piggy.img.
-
-The decompressor is built into the file decompress.o. It is turned into
-the binary file decompress.bin, which is catted together with piggy.img
-into the file vmlinuz. It can be executed in an arbitrary place in flash.
-
-Be careful - it assumes some things about free locations in DRAM. It
-assumes the DRAM starts at 0x40000000 and that it is at least 8 MB,
-so it puts its code at 0x40700000, and initial stack at 0x40800000.
-
--Bjorn
diff --git a/arch/cris/arch-v10/boot/compressed/misc.c b/arch/cris/arch-v10/boot/compressed/misc.c
deleted file mode 100644
index a4db1507d3b1..000000000000
--- a/arch/cris/arch-v10/boot/compressed/misc.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * misc.c
- *
- * This is a collection of several routines from gzip-1.0.3
- * adapted for Linux.
- *
- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- * puts by Nick Holloway 1993, better puts by Martin Mares 1995
- * adaptation for Linux/CRIS Axis Communications AB, 1999
- *
- */
-
-/* where the piggybacked kernel image expects itself to live.
- * it is the same address we use when we network load an uncompressed
- * image into DRAM, and it is the address the kernel is linked to live
- * at by vmlinux.lds.S
- */
-
-#define KERNEL_LOAD_ADR 0x40004000
-
-
-#include <linux/types.h>
-#include <arch/svinto.h>
-
-/*
- * gzip declarations
- */
-
-#define OF(args) args
-#define STATIC static
-
-void *memset(void *s, int c, size_t n);
-void *memcpy(void *__dest, __const void *__src, size_t __n);
-
-#define memzero(s, n) memset((s), 0, (n))
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch *inbuf; /* input buffer */
-static uch window[WSIZE]; /* Sliding window buffer */
-
-unsigned inptr = 0; /* index of next byte to be processed in inbuf
- * After decompression it will contain the
- * compressed size, and head.S will read it.
- */
-
-static unsigned outcnt = 0; /* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
-#define RESERVED 0xC0 /* bit 6,7: reserved */
-
-#define get_byte() (inbuf[inptr++])
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# define Assert(cond, msg) do { \
- if (!(cond)) \
- error(msg); \
- } while (0)
-# define Trace(x) fprintf x
-# define Tracev(x) do { \
- if (verbose) \
- fprintf x; \
- } while (0)
-# define Tracevv(x) do { \
- if (verbose > 1) \
- fprintf x; \
- } while (0)
-# define Tracec(c, x) do { \
- if (verbose && (c)) \
- fprintf x; \
- } while (0)
-# define Tracecv(c, x) do { \
- if (verbose > 1 && (c)) \
- fprintf x; \
- } while (0)
-#else
-# define Assert(cond, msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c, x)
-# define Tracecv(c, x)
-#endif
-
-static void flush_window(void);
-static void error(char *m);
-
-extern char *input_data; /* lives in head.S */
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-static void puts(const char *);
-
-/* the "heap" is put directly after the BSS ends, at end */
-
-extern int _end;
-static long free_mem_ptr = (long)&_end;
-static long free_mem_end_ptr;
-
-#include "../../../../../lib/inflate.c"
-
-/* decompressor info and error messages to serial console */
-
-static void
-puts(const char *s)
-{
-#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
- while (*s) {
-#ifdef CONFIG_ETRAX_DEBUG_PORT0
- while (!(*R_SERIAL0_STATUS & (1 << 5))) ;
- *R_SERIAL0_TR_DATA = *s++;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT1
- while (!(*R_SERIAL1_STATUS & (1 << 5))) ;
- *R_SERIAL1_TR_DATA = *s++;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT2
- while (!(*R_SERIAL2_STATUS & (1 << 5))) ;
- *R_SERIAL2_TR_DATA = *s++;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT3
- while (!(*R_SERIAL3_STATUS & (1 << 5))) ;
- *R_SERIAL3_TR_DATA = *s++;
-#endif
- }
-#endif
-}
-
-void *memset(void *s, int c, size_t n)
-{
- int i;
- char *ss = (char *)s;
-
- for (i = 0; i < n; i++)
- ss[i] = c;
-
- return s;
-}
-
-void *memcpy(void *__dest, __const void *__src, size_t __n)
-{
- int i;
- char *d = (char *)__dest, *s = (char *)__src;
-
- for (i = 0; i < __n; i++)
- d[i] = s[i];
-
- return __dest;
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-
-static void flush_window(void)
-{
- ulg c = crc; /* temporary variable */
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++) {
- ch = *out = *in;
- out++;
- in++;
- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
- }
- crc = c;
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
-}
-
-static void error(char *x)
-{
- puts("\n\n");
- puts(x);
- puts("\n\n -- System halted\n");
-
- while (1); /* Halt */
-}
-
-void setup_normal_output_buffer(void)
-{
- output_data = (char *)KERNEL_LOAD_ADR;
-}
-
-void decompress_kernel(void)
-{
- char revision;
-
- /* input_data is set in head.S */
- inbuf = input_data;
-
-#ifdef CONFIG_ETRAX_DEBUG_PORT0
- *R_SERIAL0_XOFF = 0;
- *R_SERIAL0_BAUD = 0x99;
- *R_SERIAL0_TR_CTRL = 0x40;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT1
- *R_SERIAL1_XOFF = 0;
- *R_SERIAL1_BAUD = 0x99;
- *R_SERIAL1_TR_CTRL = 0x40;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT2
- *R_GEN_CONFIG = 0x08;
- *R_SERIAL2_XOFF = 0;
- *R_SERIAL2_BAUD = 0x99;
- *R_SERIAL2_TR_CTRL = 0x40;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT3
- *R_GEN_CONFIG = 0x100;
- *R_SERIAL3_XOFF = 0;
- *R_SERIAL3_BAUD = 0x99;
- *R_SERIAL3_TR_CTRL = 0x40;
-#endif
-
- setup_normal_output_buffer();
-
- makecrc();
-
- __asm__ volatile ("move $vr,%0" : "=rm" (revision));
- if (revision < 10) {
- puts("You need an ETRAX 100LX to run linux 2.6\n");
- while (1);
- }
-
- puts("Uncompressing Linux...\n");
- gunzip();
- puts("Done. Now booting the kernel.\n");
-}
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S
index 72f5cd319b97..2c18d08cd913 100644
--- a/arch/cris/arch-v10/kernel/entry.S
+++ b/arch/cris/arch-v10/kernel/entry.S
@@ -536,10 +536,10 @@ multiple_interrupt:
movem $r13, [$sp]
push $r10 ; push orig_r10
clear.d [$sp=$sp-4] ; frametype == 0, normal frame
-
+
move.d $sp, $r10
jsr do_multiple_IRQ
-
+
jump ret_from_intr
do_sigtrap:
@@ -585,7 +585,7 @@ _ugdb_handle_breakpoint:
pop $r0 ; Restore r0.
ba do_sigtrap ; SIGTRAP the offending process.
pop $dccr ; Restore dccr in delay slot.
-
+
.global kernel_execve
kernel_execve:
move.d __NR_execve, $r9
@@ -929,6 +929,14 @@ sys_call_table:
.long sys_fallocate
.long sys_timerfd_settime /* 325 */
.long sys_timerfd_gettime
+ .long sys_signalfd4
+ .long sys_eventfd2
+ .long sys_epoll_create1
+ .long sys_dup3 /* 330 */
+ .long sys_pipe2
+ .long sys_inotify_init1
+ .long sys_preadv
+ .long sys_pwritev
/*
* NOTE!! This doesn't have to be exact - we just have
diff --git a/arch/cris/arch-v32/boot/Makefile b/arch/cris/arch-v32/boot/Makefile
deleted file mode 100644
index 99896ad60b30..000000000000
--- a/arch/cris/arch-v32/boot/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# arch/cris/arch-v32/boot/Makefile
-#
-
-OBJCOPYFLAGS = -O binary -R .note -R .comment
-
-subdir- := compressed rescue
-targets := Image
-
-$(obj)/Image: vmlinux FORCE
- $(call if_changed,objcopy)
- @echo ' Kernel: $@ is ready'
-
-$(obj)/compressed/vmlinux: $(obj)/Image FORCE
- $(Q)$(MAKE) $(build)=$(obj)/compressed $@
- $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
-
-$(obj)/zImage: $(obj)/compressed/vmlinux
- @cp $< $@
- @echo ' Kernel: $@ is ready'
diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile
deleted file mode 100644
index e176b8b69d92..000000000000
--- a/arch/cris/arch-v32/boot/compressed/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# arch/cris/arch-v32/boot/compressed/Makefile
-#
-
-asflags-y += -I$(srctree)/include/asm/mach/ -I$(srctree)/include/asm/arch
-ccflags-y += -O2 -I$(srctree)/include/asm/mach/ -I$(srctree)/include/asm/arch
-ldflags-y += -T$(srctree)/$(src)/decompress.lds
-OBJECTS = $(obj)/head.o $(obj)/misc.o
-OBJCOPYFLAGS = -O binary --remove-section=.bss
-
-quiet_cmd_image = BUILD $@
-cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
-
-targets := vmlinux piggy.gz decompress.o decompress.bin
-
-$(obj)/decompress.o: $(OBJECTS) FORCE
- $(call if_changed,ld)
-
-$(obj)/decompress.bin: $(obj)/decompress.o FORCE
- $(call if_changed,objcopy)
-
-$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
- $(call if_changed,image)
-
-$(obj)/piggy.gz: $(obj)/../Image FORCE
- $(call if_changed,gzip)
diff --git a/arch/cris/arch-v32/boot/rescue/Makefile b/arch/cris/arch-v32/boot/rescue/Makefile
deleted file mode 100644
index 566aac663a38..000000000000
--- a/arch/cris/arch-v32/boot/rescue/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Makefile for rescue (bootstrap) code
-#
-
-CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
-ccflags-y += -O2 -I $(srctree)/include/asm/arch/mach/ \
- -I $(srctree)/include/asm/arch
-asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
-LD = gcc-cris -mlinux -march=v32 -nostdlib
-ldflags-y += -T $(srctree)/$(src)/rescue.lds
-LDPOSTFLAGS = -lgcc
-OBJCOPYFLAGS = -O binary --remove-section=.bss
-obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
-OBJECT := $(obj)/head.o
-
-targets := rescue.o rescue.bin
-
-quiet_cmd_ldlibgcc = LD $@
-cmd_ldlibgcc = $(LD) $(LDFLAGS) $(filter-out FORCE,$^) $(LDPOSTFLAGS) -o $@
-
-$(obj)/rescue.o: $(OBJECTS) FORCE
- $(call if_changed,ldlibgcc)
-
-$(obj)/rescue.bin: $(obj)/rescue.o FORCE
- $(call if_changed,objcopy)
- cp -p $(obj)/rescue.bin $(objtree)
diff --git a/arch/cris/arch-v32/drivers/mach-a3/gpio.c b/arch/cris/arch-v32/drivers/mach-a3/gpio.c
index 7a87bc0ae2e8..97357cfd17bb 100644
--- a/arch/cris/arch-v32/drivers/mach-a3/gpio.c
+++ b/arch/cris/arch-v32/drivers/mach-a3/gpio.c
@@ -681,7 +681,7 @@ static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
shadow |= ~readl(dir_oe[priv->minor]) |
(arg & changeable_bits[priv->minor]);
i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- spin_lock_irqrestore(&gpio_lock, flags);
+ spin_unlock_irqrestore(&gpio_lock, flags);
break;
case IO_CLRBITS:
spin_lock_irqsave(&gpio_lock, flags);
@@ -690,7 +690,7 @@ static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
shadow |= ~readl(dir_oe[priv->minor]) &
~(arg & changeable_bits[priv->minor]);
i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- spin_lock_irqrestore(&gpio_lock, flags);
+ spin_unlock_irqrestore(&gpio_lock, flags);
break;
case IO_HIGHALARM:
/* Set alarm when bits with 1 in arg go high. */
diff --git a/arch/cris/arch-v32/kernel/Makefile b/arch/cris/arch-v32/kernel/Makefile
index 993d987b0078..40358355d0cb 100644
--- a/arch/cris/arch-v32/kernel/Makefile
+++ b/arch/cris/arch-v32/kernel/Makefile
@@ -9,8 +9,6 @@ obj-y := entry.o traps.o irq.o debugport.o \
process.o ptrace.o setup.o signal.o traps.o time.o \
cache.o cacheflush.o
-obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o
-
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_ETRAX_KGDB) += kgdb.o kgdb_asm.o
obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S
index 5e674c8f7c51..435b9671bd4b 100644
--- a/arch/cris/arch-v32/kernel/entry.S
+++ b/arch/cris/arch-v32/kernel/entry.S
@@ -852,6 +852,14 @@ sys_call_table:
.long sys_fallocate
.long sys_timerfd_settime /* 325 */
.long sys_timerfd_gettime
+ .long sys_signalfd4
+ .long sys_eventfd2
+ .long sys_epoll_create1
+ .long sys_dup3 /* 330 */
+ .long sys_pipe2
+ .long sys_inotify_init1
+ .long sys_preadv
+ .long sys_pwritev
/*
* NOTE!! This doesn't have to be exact - we just have
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
index df3925cb1c7f..d70b445f4a8f 100644
--- a/arch/cris/arch-v32/kernel/irq.c
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -325,12 +325,14 @@ static void end_crisv32_irq(unsigned int irq)
{
}
-void set_affinity_crisv32_irq(unsigned int irq, const struct cpumask *dest)
+int set_affinity_crisv32_irq(unsigned int irq, const struct cpumask *dest)
{
unsigned long flags;
spin_lock_irqsave(&irq_lock, flags);
irq_allocations[irq - FIRST_IRQ].mask = *dest;
spin_unlock_irqrestore(&irq_lock, flags);
+
+ return 0;
}
static struct irq_chip crisv32_irq_type = {
diff --git a/arch/cris/arch-v10/boot/.gitignore b/arch/cris/boot/.gitignore
index 171a0853caf8..171a0853caf8 100644
--- a/arch/cris/arch-v10/boot/.gitignore
+++ b/arch/cris/boot/.gitignore
diff --git a/arch/cris/arch-v10/boot/Makefile b/arch/cris/boot/Makefile
index 217203014433..144f3afa0119 100644
--- a/arch/cris/arch-v10/boot/Makefile
+++ b/arch/cris/boot/Makefile
@@ -1,8 +1,12 @@
#
-# arch/cris/arch-v10/boot/Makefile
+# arch/cris/boot/Makefile
#
-OBJCOPYFLAGS = -O binary --remove-section=.bss
+objcopyflags-$(CONFIG_ETRAX_ARCH_V10) += -R .note -R .comment
+objcopyflags-$(CONFIG_ETRAX_ARCH_V32) += --remove-section=.bss
+
+OBJCOPYFLAGS = -O binary $(objcopyflags-y)
+
subdir- := compressed rescue
targets := Image
diff --git a/arch/cris/arch-v10/boot/compressed/Makefile b/arch/cris/boot/compressed/Makefile
index 6fe0ffaf3be6..8fe9338c1775 100644
--- a/arch/cris/arch-v10/boot/compressed/Makefile
+++ b/arch/cris/boot/compressed/Makefile
@@ -1,11 +1,23 @@
#
-# arch/cris/arch-v10/boot/compressed/Makefile
+# arch/cris/boot/compressed/Makefile
#
asflags-y += $(LINUXINCLUDE)
ccflags-y += -O2 $(LINUXINCLUDE)
-ldflags-y += -T $(srctree)/$(src)/decompress.lds
-OBJECTS = $(obj)/head.o $(obj)/misc.o
+
+# asflags-$(CONFIG_ETRAX_ARCH_V32) += -I$(srctree)/include/asm/mach \
+# -I$(srctree)/include/asm/arch
+# ccflags-$(CONFIG_ETRAX_ARCH_V32) += -O2 -I$(srctree)/include/asm/mach
+# -I$(srctree)/include/asm/arch
+
+arch-$(CONFIG_ETRAX_ARCH_V10) = v10
+arch-$(CONFIG_ETRAX_ARCH_V32) = v32
+
+ldflags-y += -T $(srctree)/$(src)/decompress_$(arch-y).lds
+
+OBJECTS-$(CONFIG_ETRAX_ARCH_V32) = $(obj)/head_v32.o
+OBJECTS-$(CONFIG_ETRAX_ARCH_V10) = $(obj)/head_v10.o
+OBJECTS= $(OBJECTS-y) $(obj)/misc.o
OBJCOPYFLAGS = -O binary --remove-section=.bss
quiet_cmd_image = BUILD $@
@@ -24,4 +36,3 @@ $(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
$(obj)/piggy.gz: $(obj)/../Image FORCE
$(call if_changed,gzip)
-
diff --git a/arch/cris/arch-v32/boot/compressed/README b/arch/cris/boot/compressed/README
index 182c5d75784b..182c5d75784b 100644
--- a/arch/cris/arch-v32/boot/compressed/README
+++ b/arch/cris/boot/compressed/README
diff --git a/arch/cris/arch-v10/boot/compressed/decompress.lds b/arch/cris/boot/compressed/decompress_v10.lds
index e80f4594d543..e80f4594d543 100644
--- a/arch/cris/arch-v10/boot/compressed/decompress.lds
+++ b/arch/cris/boot/compressed/decompress_v10.lds
diff --git a/arch/cris/arch-v32/boot/compressed/decompress.lds b/arch/cris/boot/compressed/decompress_v32.lds
index 3c837feca3ac..3c837feca3ac 100644
--- a/arch/cris/arch-v32/boot/compressed/decompress.lds
+++ b/arch/cris/boot/compressed/decompress_v32.lds
diff --git a/arch/cris/arch-v10/boot/compressed/head.S b/arch/cris/boot/compressed/head_v10.S
index 0bb4dcc29254..9edb8ade7e1f 100644
--- a/arch/cris/arch-v10/boot/compressed/head.S
+++ b/arch/cris/boot/compressed/head_v10.S
@@ -30,7 +30,7 @@
beq dram_init_finished
nop
-#include "../../lib/dram_init.S"
+#include "../../arch-v10/lib/dram_init.S"
dram_init_finished:
@@ -123,4 +123,4 @@ _cmd_line_magic:
.dword 0
_cmd_line_addr:
.dword 0
-#include "../../lib/hw_settings.S"
+#include "../../arch-v10/lib/hw_settings.S"
diff --git a/arch/cris/arch-v32/boot/compressed/head.S b/arch/cris/boot/compressed/head_v32.S
index a4a65c5c669e..f483005f3d48 100644
--- a/arch/cris/arch-v32/boot/compressed/head.S
+++ b/arch/cris/boot/compressed/head_v32.S
@@ -17,7 +17,7 @@
.globl input_data
.text
-_start:
+start:
di
;; Start clocks for used blocks.
@@ -29,9 +29,9 @@ _start:
nop
#if defined CONFIG_ETRAXFS
-#include "../../mach-fs/dram_init.S"
+#include "../../arch-v32/mach-fs/dram_init.S"
#elif defined CONFIG_CRIS_MACH_ARTPEC3
-#include "../../mach-a3/dram_init.S"
+#include "../../arch-v32/mach-a3/dram_init.S"
#else
#error Only ETRAXFS and ARTPEC-3 supported!
#endif
@@ -137,9 +137,9 @@ _boot_source:
.dword 0
#if defined CONFIG_ETRAXFS
-#include "../../mach-fs/hw_settings.S"
+#include "../../arch-v32/mach-fs/hw_settings.S"
#elif defined CONFIG_CRIS_MACH_ARTPEC3
-#include "../../mach-a3/hw_settings.S"
+#include "../../arch-v32/mach-a3/hw_settings.S"
#else
#error Only ETRAXFS and ARTPEC-3 supported!
#endif
diff --git a/arch/cris/arch-v32/boot/compressed/misc.c b/arch/cris/boot/compressed/misc.c
index 3595e16e82bc..47bc190ba6d4 100644
--- a/arch/cris/arch-v32/boot/compressed/misc.c
+++ b/arch/cris/boot/compressed/misc.c
@@ -18,8 +18,9 @@
#define KERNEL_LOAD_ADR 0x40004000
-
#include <linux/types.h>
+
+#ifdef CONFIG_ETRAX_ARCH_V32
#include <hwregs/reg_rdwr.h>
#include <hwregs/reg_map.h>
#include <hwregs/ser_defs.h>
@@ -27,6 +28,9 @@
#ifdef CONFIG_CRIS_MACH_ARTPEC3
#include <hwregs/clkgen_defs.h>
#endif
+#else
+#include <arch/svinto.h>
+#endif
/*
* gzip declarations
@@ -35,12 +39,10 @@
#define OF(args) args
#define STATIC static
-void* memset(void* s, int c, size_t n);
-void* memcpy(void* __dest, __const void* __src,
- size_t __n);
-
-#define memzero(s, n) memset ((s), 0, (n))
+void *memset(void *s, int c, size_t n);
+void *memcpy(void *__dest, __const void *__src, size_t __n);
+#define memzero(s, n) memset((s), 0, (n))
typedef unsigned char uch;
typedef unsigned short ush;
@@ -68,27 +70,43 @@ static unsigned outcnt = 0; /* bytes in output buffer */
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
#define RESERVED 0xC0 /* bit 6,7: reserved */
-#define get_byte() inbuf[inptr++]
+#define get_byte() (inbuf[inptr++])
/* Diagnostic functions */
#ifdef DEBUG
-# define Assert(cond,msg) {if(!(cond)) error(msg);}
+# define Assert(cond, msg) do { \
+ if (!(cond)) \
+ error(msg); \
+ } while (0)
# define Trace(x) fprintf x
-# define Tracev(x) {if (verbose) fprintf x ;}
-# define Tracevv(x) {if (verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+# define Tracev(x) do { \
+ if (verbose) \
+ fprintf x; \
+ } while (0)
+# define Tracevv(x) do { \
+ if (verbose > 1) \
+ fprintf x; \
+ } while (0)
+# define Tracec(c, x) do { \
+ if (verbose && (c)) \
+ fprintf x; \
+ } while (0)
+# define Tracecv(c, x) do { \
+ if (verbose > 1 && (c)) \
+ fprintf x; \
+ } while (0)
#else
-# define Assert(cond,msg)
+# define Assert(cond, msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
+# define Tracec(c, x)
+# define Tracecv(c, x)
#endif
static void flush_window(void);
static void error(char *m);
+static void puts(const char *);
extern char *input_data; /* lives in head.S */
@@ -96,10 +114,6 @@ static long bytes_out;
static uch *output_data;
static unsigned long output_ptr;
-static void error(char *m);
-
-static void puts(const char *);
-
/* the "heap" is put directly after the BSS ends, at end */
extern int _end;
@@ -110,8 +124,8 @@ static long free_mem_end_ptr;
/* decompressor info and error messages to serial console */
-static inline void
-serout(const char *s, reg_scope_instances regi_ser)
+#ifdef CONFIG_ETRAX_ARCH_V32
+static inline void serout(const char *s, reg_scope_instances regi_ser)
{
reg_ser_rs_stat_din rs;
reg_ser_rw_dout dout = {.data = *s};
@@ -123,23 +137,47 @@ serout(const char *s, reg_scope_instances regi_ser)
REG_WR(ser, regi_ser, rw_dout, dout);
}
+#endif
-static void
-puts(const char *s)
+static void puts(const char *s)
{
#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
while (*s) {
#ifdef CONFIG_ETRAX_DEBUG_PORT0
+#ifdef CONFIG_ETRAX_ARCH_V32
serout(s, regi_ser0);
+#else
+ while (!(*R_SERIAL0_STATUS & (1 << 5)))
+ ;
+ *R_SERIAL0_TR_DATA = *s++;
+#endif
#endif
#ifdef CONFIG_ETRAX_DEBUG_PORT1
+#ifdef CONFIG_ETRAX_ARCH_V32
serout(s, regi_ser1);
+#else
+ while (!(*R_SERIAL1_STATUS & (1 << 5)))
+ ;
+ *R_SERIAL1_TR_DATA = *s++;
+#endif
#endif
#ifdef CONFIG_ETRAX_DEBUG_PORT2
+#ifdef CONFIG_ETRAX_ARCH_V32
serout(s, regi_ser2);
+#else
+ while (!(*R_SERIAL2_STATUS & (1 << 5)))
+ ;
+ *R_SERIAL2_TR_DATA = *s++;
+#endif
#endif
#ifdef CONFIG_ETRAX_DEBUG_PORT3
+#ifdef CONFIG_ETRAX_ARCH_V32
serout(s, regi_ser3);
+#else
+ while (!(*R_SERIAL3_STATUS & (1 << 5)))
+ ;
+ *R_SERIAL3_TR_DATA = *s++;
+#endif
#endif
*s++;
}
@@ -147,8 +185,7 @@ puts(const char *s)
#endif
}
-void*
-memset(void* s, int c, size_t n)
+void *memset(void *s, int c, size_t n)
{
int i;
char *ss = (char*)s;
@@ -158,14 +195,13 @@ memset(void* s, int c, size_t n)
return s;
}
-void*
-memcpy(void* __dest, __const void* __src,
- size_t __n)
+void *memcpy(void *__dest, __const void *__src, size_t __n)
{
int i;
char *d = (char *)__dest, *s = (char *)__src;
- for (i=0;i<__n;i++) d[i] = s[i];
+ for (i = 0; i < __n; i++)
+ d[i] = s[i];
return __dest;
}
@@ -175,43 +211,42 @@ memcpy(void* __dest, __const void* __src,
* (Used for the decompressed data only.)
*/
-static void
-flush_window()
+static void flush_window(void)
{
- ulg c = crc; /* temporary variable */
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++) {
- ch = *out++ = *in++;
- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
- }
- crc = c;
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
+ ulg c = crc; /* temporary variable */
+ unsigned n;
+ uch *in, *out, ch;
+
+ in = window;
+ out = &output_data[output_ptr];
+ for (n = 0; n < outcnt; n++) {
+ ch = *out = *in;
+ out++;
+ in++;
+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+ }
+ crc = c;
+ bytes_out += (ulg)outcnt;
+ output_ptr += (ulg)outcnt;
+ outcnt = 0;
}
-static void
-error(char *x)
+static void error(char *x)
{
- puts("\r\n\n");
+ puts("\n\n");
puts(x);
- puts("\r\n\n -- System halted\n");
+ puts("\n\n -- System halted\n");
while(1); /* Halt */
}
-void
-setup_normal_output_buffer(void)
+void setup_normal_output_buffer(void)
{
output_data = (char *)KERNEL_LOAD_ADR;
}
-static inline void
-serial_setup(reg_scope_instances regi_ser)
+#ifdef CONFIG_ETRAX_ARCH_V32
+static inline void serial_setup(reg_scope_instances regi_ser)
{
reg_ser_rw_xoff xoff;
reg_ser_rw_tr_ctrl tr_ctrl;
@@ -252,12 +287,16 @@ serial_setup(reg_scope_instances regi_ser)
REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
REG_WR(ser, regi_ser, rw_rec_baud_div, rec_baud);
}
+#endif
-void
-decompress_kernel(void)
+void decompress_kernel(void)
{
char revision;
+ char compile_rev;
+#ifdef CONFIG_ETRAX_ARCH_V32
+ /* Need at least a CRISv32 to run. */
+ compile_rev = 32;
#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
defined(CONFIG_ETRAX_DEBUG_PORT2) || \
defined(CONFIG_ETRAX_DEBUG_PORT3)
@@ -277,6 +316,7 @@ decompress_kernel(void)
hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
#endif
+
#ifdef CONFIG_ETRAX_DEBUG_PORT0
serial_setup(regi_ser0);
#endif
@@ -300,19 +340,52 @@ decompress_kernel(void)
/* input_data is set in head.S */
inbuf = input_data;
+#else /* CRISv10 */
+ /* Need at least a crisv10 to run. */
+ compile_rev = 10;
+
+ /* input_data is set in head.S */
+ inbuf = input_data;
+
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
+ *R_SERIAL0_XOFF = 0;
+ *R_SERIAL0_BAUD = 0x99;
+ *R_SERIAL0_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT1
+ *R_SERIAL1_XOFF = 0;
+ *R_SERIAL1_BAUD = 0x99;
+ *R_SERIAL1_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT2
+ *R_GEN_CONFIG = 0x08;
+ *R_SERIAL2_XOFF = 0;
+ *R_SERIAL2_BAUD = 0x99;
+ *R_SERIAL2_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT3
+ *R_GEN_CONFIG = 0x100;
+ *R_SERIAL3_XOFF = 0;
+ *R_SERIAL3_BAUD = 0x99;
+ *R_SERIAL3_TR_CTRL = 0x40;
+#endif
+#endif
setup_normal_output_buffer();
makecrc();
__asm__ volatile ("move $vr,%0" : "=rm" (revision));
- if (revision < 32)
- {
- puts("You need an ETRAX FS to run Linux 2.6/crisv32.\r\n");
+ if (revision < compile_rev) {
+#ifdef CONFIG_ETRAX_ARCH_V32
+ puts("You need an ETRAX FS to run Linux 2.6/crisv32\n");
+#else
+ puts("You need an ETRAX 100LX to run linux 2.6\n");
+#endif
while(1);
}
- puts("Uncompressing Linux...\r\n");
+ puts("Uncompressing Linux...\n");
gunzip();
- puts("Done. Now booting the kernel.\r\n");
+ puts("Done. Now booting the kernel\n");
}
diff --git a/arch/cris/arch-v10/boot/rescue/Makefile b/arch/cris/boot/rescue/Makefile
index 82ab59b968e5..52bd0bd1dd22 100644
--- a/arch/cris/arch-v10/boot/rescue/Makefile
+++ b/arch/cris/boot/rescue/Makefile
@@ -2,16 +2,26 @@
# Makefile for rescue (bootstrap) code
#
-ccflags-y += -O2 $(LINUXINCLUDE)
+# CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
+# ccflags-$(CONFIG_ETRAX_ARCH_V32) += -I$(srctree)/include/asm/arch/mach/ \
+# -I$(srctree)/include/asm/arch
+# asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
+# LD = gcc-cris -mlinux -march=v32 -nostdlib
+
asflags-y += $(LINUXINCLUDE)
-ldflags-y += -T $(srctree)/$(src)/rescue.lds
+ccflags-y += -O2 $(LINUXINCLUDE)
+arch-$(CONFIG_ETRAX_ARCH_V10) = v10
+arch-$(CONFIG_ETRAX_ARCH_V32) = v32
+
+ldflags-y += -T $(srctree)/$(src)/rescue_$(arch-y).lds
OBJCOPYFLAGS = -O binary --remove-section=.bss
-obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
-OBJECT := $(obj)/head.o
+obj-$(CONFIG_ETRAX_ARCH_V32) = $(obj)/head_v32.o
+obj-$(CONFIG_ETRAX_ARCH_V10) = $(obj)/head_v10.o
+OBJECTS := $(obj-y)
targets := rescue.o rescue.bin
-$(obj)/rescue.o: $(OBJECT) FORCE
+$(obj)/rescue.o: $(OBJECTS) FORCE
$(call if_changed,ld)
$(obj)/rescue.bin: $(obj)/rescue.o FORCE
@@ -26,6 +36,7 @@ $(obj)/testrescue.bin: $(obj)/testrescue.o
dd if=testrescue_tmp.bin of=$(obj)/testrescue.bin bs=1 count=784
rm tr.bin tmp2423 testrescue_tmp.bin
+
$(obj)/kimagerescue.bin: $(obj)/kimagerescue.o
$(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/kimagerescue.o ktr.bin
# Pad it to 784 bytes, that's what the rescue loader expects
@@ -33,3 +44,4 @@ $(obj)/kimagerescue.bin: $(obj)/kimagerescue.o
cat ktr.bin tmp2423 >kimagerescue_tmp.bin
dd if=kimagerescue_tmp.bin of=$(obj)/kimagerescue.bin bs=1 count=784
rm ktr.bin tmp2423 kimagerescue_tmp.bin
+
diff --git a/arch/cris/arch-v10/boot/rescue/head.S b/arch/cris/boot/rescue/head_v10.S
index fb503d1eeea4..2fafe247a25b 100644
--- a/arch/cris/arch-v10/boot/rescue/head.S
+++ b/arch/cris/boot/rescue/head_v10.S
@@ -155,7 +155,7 @@ no_newjump:
#endif
;; We need to setup the bus registers before we start using the DRAM
-#include "../../lib/dram_init.S"
+#include "../../../arch-v10/lib/dram_init.S"
;; we now should go through the checksum-table and check the listed
;; partitions for errors.
diff --git a/arch/cris/arch-v32/boot/rescue/head.S b/arch/cris/boot/rescue/head_v32.S
index 5f846b7700a3..5f846b7700a3 100644
--- a/arch/cris/arch-v32/boot/rescue/head.S
+++ b/arch/cris/boot/rescue/head_v32.S
diff --git a/arch/cris/arch-v10/boot/rescue/kimagerescue.S b/arch/cris/boot/rescue/kimagerescue.S
index 6f7b3e61260b..6f7b3e61260b 100644
--- a/arch/cris/arch-v10/boot/rescue/kimagerescue.S
+++ b/arch/cris/boot/rescue/kimagerescue.S
diff --git a/arch/cris/arch-v10/boot/rescue/rescue.lds b/arch/cris/boot/rescue/rescue_v10.lds
index 0b52a9490db6..0b52a9490db6 100644
--- a/arch/cris/arch-v10/boot/rescue/rescue.lds
+++ b/arch/cris/boot/rescue/rescue_v10.lds
diff --git a/arch/cris/arch-v32/boot/rescue/rescue.lds b/arch/cris/boot/rescue/rescue_v32.lds
index 8ac646bc1a2b..8ac646bc1a2b 100644
--- a/arch/cris/arch-v32/boot/rescue/rescue.lds
+++ b/arch/cris/boot/rescue/rescue_v32.lds
diff --git a/arch/cris/arch-v10/boot/rescue/testrescue.S b/arch/cris/boot/rescue/testrescue.S
index fc7ec674eca5..fc7ec674eca5 100644
--- a/arch/cris/arch-v10/boot/rescue/testrescue.S
+++ b/arch/cris/boot/rescue/testrescue.S
diff --git a/arch/cris/arch-v10/boot/tools/build.c b/arch/cris/boot/tools/build.c
index c8adef364160..c8adef364160 100644
--- a/arch/cris/arch-v10/boot/tools/build.c
+++ b/arch/cris/boot/tools/build.c
diff --git a/arch/cris/include/asm/unistd.h b/arch/cris/include/asm/unistd.h
index 235d076379d5..c17079388bb9 100644
--- a/arch/cris/include/asm/unistd.h
+++ b/arch/cris/include/asm/unistd.h
@@ -281,7 +281,7 @@
#define __NR_mbind 274
#define __NR_get_mempolicy 275
#define __NR_set_mempolicy 276
-#define __NR_mq_open 277
+#define __NR_mq_open 277
#define __NR_mq_unlink (__NR_mq_open+1)
#define __NR_mq_timedsend (__NR_mq_open+2)
#define __NR_mq_timedreceive (__NR_mq_open+3)
@@ -331,10 +331,18 @@
#define __NR_fallocate 324
#define __NR_timerfd_settime 325
#define __NR_timerfd_gettime 326
+#define __NR_signalfd4 327
+#define __NR_eventfd2 328
+#define __NR_epoll_create1 329
+#define __NR_dup3 330
+#define __NR_pipe2 331
+#define __NR_inotify_init1 332
+#define __NR_preadv 333
+#define __NR_pwritev 334
#ifdef __KERNEL__
-#define NR_syscalls 327
+#define NR_syscalls 335
#include <arch/unistd.h>
diff --git a/arch/frv/include/asm/gdb-stub.h b/arch/frv/include/asm/gdb-stub.h
index 24f9738670bd..2da716407ff2 100644
--- a/arch/frv/include/asm/gdb-stub.h
+++ b/arch/frv/include/asm/gdb-stub.h
@@ -90,7 +90,6 @@ extern void gdbstub_do_rx(void);
extern asmlinkage void __debug_stub_init_break(void);
extern asmlinkage void __break_hijack_kernel_event(void);
extern asmlinkage void __break_hijack_kernel_event_breaks_here(void);
-extern asmlinkage void start_kernel(void);
extern asmlinkage void gdbstub_rx_handler(void);
extern asmlinkage void gdbstub_rx_irq(void);
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c
index cc0a3182db3c..acb5047ab573 100644
--- a/arch/ia64/hp/sim/hpsim_irq.c
+++ b/arch/ia64/hp/sim/hpsim_irq.c
@@ -21,9 +21,10 @@ hpsim_irq_noop (unsigned int irq)
{
}
-static void
+static int
hpsim_set_affinity_noop(unsigned int a, const struct cpumask *b)
{
+ return 0;
}
static struct hw_interrupt_type irq_type_hp_sim = {
diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h
index 0490794fe4aa..37d41ca5645a 100644
--- a/arch/ia64/include/asm/iommu.h
+++ b/arch/ia64/include/asm/iommu.h
@@ -9,6 +9,7 @@ extern void pci_iommu_shutdown(void);
extern void no_iommu_init(void);
extern int force_iommu, no_iommu;
extern int iommu_detected;
+extern int iommu_pass_through;
extern void iommu_dma_init(void);
extern void machvec_init(const char *name);
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index 4542651e6acb..589536fa799d 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -371,6 +371,7 @@ struct kvm_vcpu_arch {
int last_run_cpu;
int vmm_tr_slot;
int vm_tr_slot;
+ int sn_rtc_tr_slot;
#define KVM_MP_STATE_RUNNABLE 0
#define KVM_MP_STATE_UNINITIALIZED 1
@@ -465,6 +466,7 @@ struct kvm_arch {
unsigned long vmm_init_rr;
int online_vcpus;
+ int is_sn2;
struct kvm_ioapic *vioapic;
struct kvm_vm_stat stat;
@@ -578,6 +580,8 @@ struct kvm_vmm_info{
kvm_vmm_entry *vmm_entry;
kvm_tramp_entry *tramp_entry;
unsigned long vmm_ivt;
+ unsigned long patch_mov_ar;
+ unsigned long patch_mov_ar_sn2;
};
int kvm_highest_pending_irq(struct kvm_vcpu *vcpu);
@@ -585,7 +589,6 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu);
int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
void kvm_sal_emul(struct kvm_vcpu *vcpu);
-static inline void kvm_inject_nmi(struct kvm_vcpu *vcpu) {}
#endif /* __ASSEMBLY__*/
#endif
diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h
index 7a9bff47564f..0a9cc73d35c7 100644
--- a/arch/ia64/include/asm/pgtable.h
+++ b/arch/ia64/include/asm/pgtable.h
@@ -146,6 +146,8 @@
#define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
#define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
#define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
+#define PAGE_KERNEL_UC __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX | \
+ _PAGE_MA_UC)
# ifndef __ASSEMBLY__
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 5510317db37b..baec6f00f7f3 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -636,7 +636,7 @@ void __init acpi_numa_arch_fixup(void)
* success: return IRQ number (>=0)
* failure: return < 0
*/
-int acpi_register_gsi(u32 gsi, int triggering, int polarity)
+int acpi_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity)
{
if (acpi_irq_model == ACPI_IRQ_MODEL_PLATFORM)
return gsi;
@@ -678,7 +678,8 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
fadt = (struct acpi_table_fadt *)fadt_header;
- acpi_register_gsi(fadt->sci_interrupt, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
+ acpi_register_gsi(NULL, fadt->sci_interrupt, ACPI_LEVEL_SENSITIVE,
+ ACPI_ACTIVE_LOW);
return 0;
}
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 166e0d839fa0..f92cef47bf86 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -329,7 +329,7 @@ unmask_irq (unsigned int irq)
}
-static void
+static int
iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
{
#ifdef CONFIG_SMP
@@ -343,15 +343,15 @@ iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
cpu = cpumask_first_and(cpu_online_mask, mask);
if (cpu >= nr_cpu_ids)
- return;
+ return -1;
if (irq_prepare_move(irq, cpu))
- return;
+ return -1;
dest = cpu_physical_id(cpu);
if (!iosapic_intr_info[irq].count)
- return; /* not an IOSAPIC interrupt */
+ return -1; /* not an IOSAPIC interrupt */
set_irq_affinity_info(irq, dest, redir);
@@ -376,7 +376,9 @@ iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
iosapic_write(iosapic, IOSAPIC_RTE_HIGH(rte_index), high32);
iosapic_write(iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
}
+
#endif
+ return 0;
}
/*
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index acc4d19ae62a..b448197728be 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -610,6 +610,9 @@ static struct irqaction ipi_irqaction = {
.name = "IPI"
};
+/*
+ * KVM uses this interrupt to force a cpu out of guest mode
+ */
static struct irqaction resched_irqaction = {
.handler = dummy_handler,
.flags = IRQF_DISABLED,
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 2b15e233f7fe..0f8ade9331ba 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -12,7 +12,7 @@
static struct irq_chip ia64_msi_chip;
#ifdef CONFIG_SMP
-static void ia64_set_msi_irq_affinity(unsigned int irq,
+static int ia64_set_msi_irq_affinity(unsigned int irq,
const cpumask_t *cpu_mask)
{
struct msi_msg msg;
@@ -20,10 +20,10 @@ static void ia64_set_msi_irq_affinity(unsigned int irq,
int cpu = first_cpu(*cpu_mask);
if (!cpu_online(cpu))
- return;
+ return -1;
if (irq_prepare_move(irq, cpu))
- return;
+ return -1;
read_msi_msg(irq, &msg);
@@ -39,6 +39,8 @@ static void ia64_set_msi_irq_affinity(unsigned int irq,
write_msi_msg(irq, &msg);
cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
+
+ return 0;
}
#endif /* CONFIG_SMP */
@@ -130,17 +132,17 @@ void arch_teardown_msi_irq(unsigned int irq)
#ifdef CONFIG_DMAR
#ifdef CONFIG_SMP
-static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
{
struct irq_cfg *cfg = irq_cfg + irq;
struct msi_msg msg;
int cpu = cpumask_first(mask);
if (!cpu_online(cpu))
- return;
+ return -1;
if (irq_prepare_move(irq, cpu))
- return;
+ return -1;
dmar_msi_read(irq, &msg);
@@ -151,6 +153,8 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
dmar_msi_write(irq, &msg);
cpumask_copy(irq_desc[irq].affinity, mask);
+
+ return 0;
}
#endif /* CONFIG_SMP */
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index eb987386f691..ecdde25d0d18 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -32,6 +32,8 @@ int force_iommu __read_mostly = 1;
int force_iommu __read_mostly;
#endif
+int iommu_pass_through;
+
/* Dummy device used for NULL arguments (normally ISA). Better would
be probably a smaller DMA mask, but this is bug-to-bug compatible
to i386. */
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
index 285aae8431c6..223abb134105 100644
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ b/arch/ia64/kernel/pci-swiotlb.c
@@ -46,7 +46,7 @@ void __init swiotlb_dma_init(void)
void __init pci_swiotlb_init(void)
{
- if (!iommu_detected) {
+ if (!iommu_detected || iommu_pass_through) {
#ifdef CONFIG_IA64_GENERIC
swiotlb = 1;
printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index 0a2d6b86075a..64d520937874 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -23,7 +23,7 @@ if VIRTUALIZATION
config KVM
tristate "Kernel-based Virtual Machine (KVM) support"
- depends on HAVE_KVM && EXPERIMENTAL
+ depends on HAVE_KVM && MODULES && EXPERIMENTAL
# for device assignment:
depends on PCI
select PREEMPT_NOTIFIERS
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index d20a5db4c4dd..80c57b0a21c4 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -41,6 +41,9 @@
#include <asm/div64.h>
#include <asm/tlb.h>
#include <asm/elf.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/clksupport.h>
+#include <asm/sn/shub_mmr.h>
#include "misc.h"
#include "vti.h"
@@ -65,6 +68,16 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ NULL }
};
+static unsigned long kvm_get_itc(struct kvm_vcpu *vcpu)
+{
+#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
+ if (vcpu->kvm->arch.is_sn2)
+ return rtc_time();
+ else
+#endif
+ return ia64_getreg(_IA64_REG_AR_ITC);
+}
+
static void kvm_flush_icache(unsigned long start, unsigned long len)
{
int l;
@@ -119,8 +132,7 @@ void kvm_arch_hardware_enable(void *garbage)
unsigned long saved_psr;
int slot;
- pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base),
- PAGE_KERNEL));
+ pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), PAGE_KERNEL));
local_irq_save(saved_psr);
slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
local_irq_restore(saved_psr);
@@ -283,6 +295,18 @@ static int handle_sal_call(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
+static int __apic_accept_irq(struct kvm_vcpu *vcpu, uint64_t vector)
+{
+ struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd);
+
+ if (!test_and_set_bit(vector, &vpd->irr[0])) {
+ vcpu->arch.irq_new_pending = 1;
+ kvm_vcpu_kick(vcpu);
+ return 1;
+ }
+ return 0;
+}
+
/*
* offset: address offset to IPI space.
* value: deliver value.
@@ -292,20 +316,20 @@ static void vcpu_deliver_ipi(struct kvm_vcpu *vcpu, uint64_t dm,
{
switch (dm) {
case SAPIC_FIXED:
- kvm_apic_set_irq(vcpu, vector, 0);
break;
case SAPIC_NMI:
- kvm_apic_set_irq(vcpu, 2, 0);
+ vector = 2;
break;
case SAPIC_EXTINT:
- kvm_apic_set_irq(vcpu, 0, 0);
+ vector = 0;
break;
case SAPIC_INIT:
case SAPIC_PMI:
default:
printk(KERN_ERR"kvm: Unimplemented Deliver reserved IPI!\n");
- break;
+ return;
}
+ __apic_accept_irq(vcpu, vector);
}
static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id,
@@ -413,6 +437,23 @@ static int handle_switch_rr6(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 1;
}
+static int kvm_sn2_setup_mappings(struct kvm_vcpu *vcpu)
+{
+ unsigned long pte, rtc_phys_addr, map_addr;
+ int slot;
+
+ map_addr = KVM_VMM_BASE + (1UL << KVM_VMM_SHIFT);
+ rtc_phys_addr = LOCAL_MMR_OFFSET | SH_RTC;
+ pte = pte_val(mk_pte_phys(rtc_phys_addr, PAGE_KERNEL_UC));
+ slot = ia64_itr_entry(0x3, map_addr, pte, PAGE_SHIFT);
+ vcpu->arch.sn_rtc_tr_slot = slot;
+ if (slot < 0) {
+ printk(KERN_ERR "Mayday mayday! RTC mapping failed!\n");
+ slot = 0;
+ }
+ return slot;
+}
+
int kvm_emulate_halt(struct kvm_vcpu *vcpu)
{
@@ -426,7 +467,7 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
if (irqchip_in_kernel(vcpu->kvm)) {
- vcpu_now_itc = ia64_getreg(_IA64_REG_AR_ITC) + vcpu->arch.itc_offset;
+ vcpu_now_itc = kvm_get_itc(vcpu) + vcpu->arch.itc_offset;
if (time_after(vcpu_now_itc, vpd->itm)) {
vcpu->arch.timer_check = 1;
@@ -447,10 +488,10 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
hrtimer_cancel(p_ht);
vcpu->arch.ht_active = 0;
- if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests))
+ if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests) ||
+ kvm_cpu_has_pending_timer(vcpu))
if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED)
- vcpu->arch.mp_state =
- KVM_MP_STATE_RUNNABLE;
+ vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE)
return -EINTR;
@@ -551,22 +592,35 @@ static int kvm_insert_vmm_mapping(struct kvm_vcpu *vcpu)
if (r < 0)
goto out;
vcpu->arch.vm_tr_slot = r;
+
+#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
+ if (kvm->arch.is_sn2) {
+ r = kvm_sn2_setup_mappings(vcpu);
+ if (r < 0)
+ goto out;
+ }
+#endif
+
r = 0;
out:
return r;
-
}
static void kvm_purge_vmm_mapping(struct kvm_vcpu *vcpu)
{
-
+ struct kvm *kvm = vcpu->kvm;
ia64_ptr_entry(0x3, vcpu->arch.vmm_tr_slot);
ia64_ptr_entry(0x3, vcpu->arch.vm_tr_slot);
-
+#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
+ if (kvm->arch.is_sn2)
+ ia64_ptr_entry(0x3, vcpu->arch.sn_rtc_tr_slot);
+#endif
}
static int kvm_vcpu_pre_transition(struct kvm_vcpu *vcpu)
{
+ unsigned long psr;
+ int r;
int cpu = smp_processor_id();
if (vcpu->arch.last_run_cpu != cpu ||
@@ -578,36 +632,27 @@ static int kvm_vcpu_pre_transition(struct kvm_vcpu *vcpu)
vcpu->arch.host_rr6 = ia64_get_rr(RR6);
vti_set_rr6(vcpu->arch.vmm_rr);
- return kvm_insert_vmm_mapping(vcpu);
+ local_irq_save(psr);
+ r = kvm_insert_vmm_mapping(vcpu);
+ local_irq_restore(psr);
+ return r;
}
+
static void kvm_vcpu_post_transition(struct kvm_vcpu *vcpu)
{
kvm_purge_vmm_mapping(vcpu);
vti_set_rr6(vcpu->arch.host_rr6);
}
-static int vti_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
union context *host_ctx, *guest_ctx;
int r;
- /*Get host and guest context with guest address space.*/
- host_ctx = kvm_get_host_context(vcpu);
- guest_ctx = kvm_get_guest_context(vcpu);
-
- r = kvm_vcpu_pre_transition(vcpu);
- if (r < 0)
- goto out;
- kvm_vmm_info->tramp_entry(host_ctx, guest_ctx);
- kvm_vcpu_post_transition(vcpu);
- r = 0;
-out:
- return r;
-}
-
-static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
-{
- int r;
+ /*
+ * down_read() may sleep and return with interrupts enabled
+ */
+ down_read(&vcpu->kvm->slots_lock);
again:
if (signal_pending(current)) {
@@ -616,26 +661,31 @@ again:
goto out;
}
- /*
- * down_read() may sleep and return with interrupts enabled
- */
- down_read(&vcpu->kvm->slots_lock);
-
preempt_disable();
local_irq_disable();
- vcpu->guest_mode = 1;
+ /*Get host and guest context with guest address space.*/
+ host_ctx = kvm_get_host_context(vcpu);
+ guest_ctx = kvm_get_guest_context(vcpu);
+
+ clear_bit(KVM_REQ_KICK, &vcpu->requests);
+
+ r = kvm_vcpu_pre_transition(vcpu);
+ if (r < 0)
+ goto vcpu_run_fail;
+
+ up_read(&vcpu->kvm->slots_lock);
kvm_guest_enter();
- r = vti_vcpu_run(vcpu, kvm_run);
- if (r < 0) {
- local_irq_enable();
- preempt_enable();
- kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
- goto out;
- }
+
+ /*
+ * Transition to the guest
+ */
+ kvm_vmm_info->tramp_entry(host_ctx, guest_ctx);
+
+ kvm_vcpu_post_transition(vcpu);
vcpu->arch.launched = 1;
- vcpu->guest_mode = 0;
+ set_bit(KVM_REQ_KICK, &vcpu->requests);
local_irq_enable();
/*
@@ -646,9 +696,10 @@ again:
*/
barrier();
kvm_guest_exit();
- up_read(&vcpu->kvm->slots_lock);
preempt_enable();
+ down_read(&vcpu->kvm->slots_lock);
+
r = kvm_handle_exit(kvm_run, vcpu);
if (r > 0) {
@@ -657,12 +708,20 @@ again:
}
out:
+ up_read(&vcpu->kvm->slots_lock);
if (r > 0) {
kvm_resched(vcpu);
+ down_read(&vcpu->kvm->slots_lock);
goto again;
}
return r;
+
+vcpu_run_fail:
+ local_irq_enable();
+ preempt_enable();
+ kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+ goto out;
}
static void kvm_set_mmio_data(struct kvm_vcpu *vcpu)
@@ -788,6 +847,9 @@ struct kvm *kvm_arch_create_vm(void)
if (IS_ERR(kvm))
return ERR_PTR(-ENOMEM);
+
+ kvm->arch.is_sn2 = ia64_platform_is("sn2");
+
kvm_init_vm(kvm);
kvm->arch.online_vcpus = 0;
@@ -884,7 +946,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
RESTORE_REGS(saved_gp);
vcpu->arch.irq_new_pending = 1;
- vcpu->arch.itc_offset = regs->saved_itc - ia64_getreg(_IA64_REG_AR_ITC);
+ vcpu->arch.itc_offset = regs->saved_itc - kvm_get_itc(vcpu);
set_bit(KVM_REQ_RESUME, &vcpu->requests);
vcpu_put(vcpu);
@@ -1043,10 +1105,6 @@ static void kvm_free_vmm_area(void)
}
}
-static void vti_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
-{
-}
-
static int vti_init_vpd(struct kvm_vcpu *vcpu)
{
int i;
@@ -1165,7 +1223,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
regs->cr_iip = PALE_RESET_ENTRY;
/*Initialize itc offset for vcpus*/
- itc_offset = 0UL - ia64_getreg(_IA64_REG_AR_ITC);
+ itc_offset = 0UL - kvm_get_itc(vcpu);
for (i = 0; i < kvm->arch.online_vcpus; i++) {
v = (struct kvm_vcpu *)((char *)vcpu +
sizeof(struct kvm_vcpu_data) * i);
@@ -1237,6 +1295,7 @@ static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id)
local_irq_save(psr);
r = kvm_insert_vmm_mapping(vcpu);
+ local_irq_restore(psr);
if (r)
goto fail;
r = kvm_vcpu_init(vcpu, vcpu->kvm, id);
@@ -1254,13 +1313,11 @@ static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id)
goto uninit;
kvm_purge_vmm_mapping(vcpu);
- local_irq_restore(psr);
return 0;
uninit:
kvm_vcpu_uninit(vcpu);
fail:
- local_irq_restore(psr);
return r;
}
@@ -1291,7 +1348,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
vcpu->kvm = kvm;
cpu = get_cpu();
- vti_vcpu_load(vcpu, cpu);
r = vti_vcpu_setup(vcpu, id);
put_cpu();
@@ -1427,7 +1483,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
}
for (i = 0; i < 4; i++)
regs->insvc[i] = vcpu->arch.insvc[i];
- regs->saved_itc = vcpu->arch.itc_offset + ia64_getreg(_IA64_REG_AR_ITC);
+ regs->saved_itc = vcpu->arch.itc_offset + kvm_get_itc(vcpu);
SAVE_REGS(xtp);
SAVE_REGS(metaphysical_rr0);
SAVE_REGS(metaphysical_rr4);
@@ -1574,6 +1630,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
void kvm_arch_flush_shadow(struct kvm *kvm)
{
+ kvm_flush_remote_tlbs(kvm);
}
long kvm_arch_dev_ioctl(struct file *filp,
@@ -1616,8 +1673,37 @@ out:
return 0;
}
+
+/*
+ * On SN2, the ITC isn't stable, so copy in fast path code to use the
+ * SN2 RTC, replacing the ITC based default verion.
+ */
+static void kvm_patch_vmm(struct kvm_vmm_info *vmm_info,
+ struct module *module)
+{
+ unsigned long new_ar, new_ar_sn2;
+ unsigned long module_base;
+
+ if (!ia64_platform_is("sn2"))
+ return;
+
+ module_base = (unsigned long)module->module_core;
+
+ new_ar = kvm_vmm_base + vmm_info->patch_mov_ar - module_base;
+ new_ar_sn2 = kvm_vmm_base + vmm_info->patch_mov_ar_sn2 - module_base;
+
+ printk(KERN_INFO "kvm: Patching ITC emulation to use SGI SN2 RTC "
+ "as source\n");
+
+ /*
+ * Copy the SN2 version of mov_ar into place. They are both
+ * the same size, so 6 bundles is sufficient (6 * 0x10).
+ */
+ memcpy((void *)new_ar, (void *)new_ar_sn2, 0x60);
+}
+
static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info,
- struct module *module)
+ struct module *module)
{
unsigned long module_base;
unsigned long vmm_size;
@@ -1639,6 +1725,7 @@ static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info,
return -EFAULT;
memcpy((void *)kvm_vmm_base, (void *)module_base, vmm_size);
+ kvm_patch_vmm(vmm_info, module);
kvm_flush_icache(kvm_vmm_base, vmm_size);
/*Recalculate kvm_vmm_info based on new VMM*/
@@ -1792,38 +1879,24 @@ void kvm_arch_hardware_unsetup(void)
{
}
-static void vcpu_kick_intr(void *info)
-{
-#ifdef DEBUG
- struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info;
- printk(KERN_DEBUG"vcpu_kick_intr %p \n", vcpu);
-#endif
-}
-
void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
{
- int ipi_pcpu = vcpu->cpu;
- int cpu = get_cpu();
+ int me;
+ int cpu = vcpu->cpu;
if (waitqueue_active(&vcpu->wq))
wake_up_interruptible(&vcpu->wq);
- if (vcpu->guest_mode && cpu != ipi_pcpu)
- smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0);
+ me = get_cpu();
+ if (cpu != me && (unsigned) cpu < nr_cpu_ids && cpu_online(cpu))
+ if (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests))
+ smp_send_reschedule(cpu);
put_cpu();
}
-int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig)
+int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq)
{
-
- struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd);
-
- if (!test_and_set_bit(vec, &vpd->irr[0])) {
- vcpu->arch.irq_new_pending = 1;
- kvm_vcpu_kick(vcpu);
- return 1;
- }
- return 0;
+ return __apic_accept_irq(vcpu, irq->vector);
}
int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest)
@@ -1836,20 +1909,18 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
return 0;
}
-struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
- unsigned long bitmap)
+int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2)
{
- struct kvm_vcpu *lvcpu = kvm->vcpus[0];
- int i;
-
- for (i = 1; i < kvm->arch.online_vcpus; i++) {
- if (!kvm->vcpus[i])
- continue;
- if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp)
- lvcpu = kvm->vcpus[i];
- }
+ return vcpu1->arch.xtp - vcpu2->arch.xtp;
+}
- return lvcpu;
+int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
+ int short_hand, int dest, int dest_mode)
+{
+ struct kvm_lapic *target = vcpu->arch.apic;
+ return (dest_mode == 0) ?
+ kvm_apic_match_physical_addr(target, dest) :
+ kvm_apic_match_logical_addr(target, dest);
}
static int find_highest_bits(int *dat)
@@ -1888,6 +1959,12 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
return 0;
}
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
+{
+ /* do real check here */
+ return 1;
+}
+
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
{
return vcpu->arch.timer_fired;
@@ -1918,6 +1995,7 @@ static int vcpu_reset(struct kvm_vcpu *vcpu)
long psr;
local_irq_save(psr);
r = kvm_insert_vmm_mapping(vcpu);
+ local_irq_restore(psr);
if (r)
goto fail;
@@ -1930,7 +2008,6 @@ static int vcpu_reset(struct kvm_vcpu *vcpu)
kvm_purge_vmm_mapping(vcpu);
r = 0;
fail:
- local_irq_restore(psr);
return r;
}
diff --git a/arch/ia64/kvm/kvm_fw.c b/arch/ia64/kvm/kvm_fw.c
index a8ae52ed5635..e4b82319881d 100644
--- a/arch/ia64/kvm/kvm_fw.c
+++ b/arch/ia64/kvm/kvm_fw.c
@@ -21,6 +21,9 @@
#include <linux/kvm_host.h>
#include <linux/smp.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/clksupport.h>
+#include <asm/sn/shub_mmr.h>
#include "vti.h"
#include "misc.h"
@@ -188,12 +191,35 @@ static struct ia64_pal_retval pal_freq_base(struct kvm_vcpu *vcpu)
return result;
}
-static struct ia64_pal_retval pal_freq_ratios(struct kvm_vcpu *vcpu)
+/*
+ * On the SGI SN2, the ITC isn't stable. Emulation backed by the SN2
+ * RTC is used instead. This function patches the ratios from SAL
+ * to match the RTC before providing them to the guest.
+ */
+static void sn2_patch_itc_freq_ratios(struct ia64_pal_retval *result)
{
+ struct pal_freq_ratio *ratio;
+ unsigned long sal_freq, sal_drift, factor;
+
+ result->status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM,
+ &sal_freq, &sal_drift);
+ ratio = (struct pal_freq_ratio *)&result->v2;
+ factor = ((sal_freq * 3) + (sn_rtc_cycles_per_second / 2)) /
+ sn_rtc_cycles_per_second;
+
+ ratio->num = 3;
+ ratio->den = factor;
+}
+static struct ia64_pal_retval pal_freq_ratios(struct kvm_vcpu *vcpu)
+{
struct ia64_pal_retval result;
PAL_CALL(result, PAL_FREQ_RATIOS, 0, 0, 0);
+
+ if (vcpu->kvm->arch.is_sn2)
+ sn2_patch_itc_freq_ratios(&result);
+
return result;
}
diff --git a/arch/ia64/kvm/lapic.h b/arch/ia64/kvm/lapic.h
index 6d6cbcb14893..ee541cebcd78 100644
--- a/arch/ia64/kvm/lapic.h
+++ b/arch/ia64/kvm/lapic.h
@@ -20,6 +20,10 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu);
int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
-int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig);
+int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
+ int short_hand, int dest, int dest_mode);
+int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2);
+int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq);
+#define kvm_apic_present(x) (true)
#endif
diff --git a/arch/ia64/kvm/optvfault.S b/arch/ia64/kvm/optvfault.S
index 32254ce9a1bd..f793be3effff 100644
--- a/arch/ia64/kvm/optvfault.S
+++ b/arch/ia64/kvm/optvfault.S
@@ -11,6 +11,7 @@
#include <asm/asmmacro.h>
#include <asm/processor.h>
+#include <asm/kvm_host.h>
#include "vti.h"
#include "asm-offsets.h"
@@ -140,6 +141,35 @@ GLOBAL_ENTRY(kvm_asm_mov_from_ar)
;;
END(kvm_asm_mov_from_ar)
+/*
+ * Special SGI SN2 optimized version of mov_from_ar using the SN2 RTC
+ * clock as it's source for emulating the ITC. This version will be
+ * copied on top of the original version if the host is determined to
+ * be an SN2.
+ */
+GLOBAL_ENTRY(kvm_asm_mov_from_ar_sn2)
+ add r18=VMM_VCPU_ITC_OFS_OFFSET, r21
+ movl r19 = (KVM_VMM_BASE+(1<<KVM_VMM_SHIFT))
+
+ add r16=VMM_VCPU_LAST_ITC_OFFSET,r21
+ extr.u r17=r25,6,7
+ mov r24=b0
+ ;;
+ ld8 r18=[r18]
+ ld8 r19=[r19]
+ addl r20=@gprel(asm_mov_to_reg),gp
+ ;;
+ add r19=r19,r18
+ shladd r17=r17,4,r20
+ ;;
+ adds r30=kvm_resume_to_guest-asm_mov_to_reg,r20
+ st8 [r16] = r19
+ mov b0=r17
+ br.sptk.few b0
+ ;;
+END(kvm_asm_mov_from_ar_sn2)
+
+
// mov r1=rr[r3]
GLOBAL_ENTRY(kvm_asm_mov_from_rr)
diff --git a/arch/ia64/kvm/process.c b/arch/ia64/kvm/process.c
index b1dc80952d91..a8f84da04b49 100644
--- a/arch/ia64/kvm/process.c
+++ b/arch/ia64/kvm/process.c
@@ -652,20 +652,25 @@ void kvm_ia64_handle_break(unsigned long ifa, struct kvm_pt_regs *regs,
unsigned long isr, unsigned long iim)
{
struct kvm_vcpu *v = current_vcpu;
+ long psr;
if (ia64_psr(regs)->cpl == 0) {
/* Allow hypercalls only when cpl = 0. */
if (iim == DOMN_PAL_REQUEST) {
+ local_irq_save(psr);
set_pal_call_data(v);
vmm_transition(v);
get_pal_call_result(v);
vcpu_increment_iip(v);
+ local_irq_restore(psr);
return;
} else if (iim == DOMN_SAL_REQUEST) {
+ local_irq_save(psr);
set_sal_call_data(v);
vmm_transition(v);
get_sal_call_result(v);
vcpu_increment_iip(v);
+ local_irq_restore(psr);
return;
}
}
diff --git a/arch/ia64/kvm/vcpu.c b/arch/ia64/kvm/vcpu.c
index a18ee17b9192..a2c6c15e4761 100644
--- a/arch/ia64/kvm/vcpu.c
+++ b/arch/ia64/kvm/vcpu.c
@@ -788,13 +788,29 @@ void vcpu_set_fpreg(struct kvm_vcpu *vcpu, unsigned long reg,
setfpreg(reg, val, regs); /* FIXME: handle NATs later*/
}
+/*
+ * The Altix RTC is mapped specially here for the vmm module
+ */
+#define SN_RTC_BASE (u64 *)(KVM_VMM_BASE+(1UL<<KVM_VMM_SHIFT))
+static long kvm_get_itc(struct kvm_vcpu *vcpu)
+{
+#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
+ struct kvm *kvm = (struct kvm *)KVM_VM_BASE;
+
+ if (kvm->arch.is_sn2)
+ return (*SN_RTC_BASE);
+ else
+#endif
+ return ia64_getreg(_IA64_REG_AR_ITC);
+}
+
/************************************************************************
* lsapic timer
***********************************************************************/
u64 vcpu_get_itc(struct kvm_vcpu *vcpu)
{
unsigned long guest_itc;
- guest_itc = VMX(vcpu, itc_offset) + ia64_getreg(_IA64_REG_AR_ITC);
+ guest_itc = VMX(vcpu, itc_offset) + kvm_get_itc(vcpu);
if (guest_itc >= VMX(vcpu, last_itc)) {
VMX(vcpu, last_itc) = guest_itc;
@@ -809,7 +825,7 @@ static void vcpu_set_itc(struct kvm_vcpu *vcpu, u64 val)
struct kvm_vcpu *v;
struct kvm *kvm;
int i;
- long itc_offset = val - ia64_getreg(_IA64_REG_AR_ITC);
+ long itc_offset = val - kvm_get_itc(vcpu);
unsigned long vitv = VCPU(vcpu, itv);
kvm = (struct kvm *)KVM_VM_BASE;
diff --git a/arch/ia64/kvm/vmm.c b/arch/ia64/kvm/vmm.c
index 9eee5c04bacc..f4b4c899bb6c 100644
--- a/arch/ia64/kvm/vmm.c
+++ b/arch/ia64/kvm/vmm.c
@@ -30,15 +30,19 @@ MODULE_AUTHOR("Intel");
MODULE_LICENSE("GPL");
extern char kvm_ia64_ivt;
+extern char kvm_asm_mov_from_ar;
+extern char kvm_asm_mov_from_ar_sn2;
extern fpswa_interface_t *vmm_fpswa_interface;
long vmm_sanity = 1;
struct kvm_vmm_info vmm_info = {
- .module = THIS_MODULE,
- .vmm_entry = vmm_entry,
- .tramp_entry = vmm_trampoline,
- .vmm_ivt = (unsigned long)&kvm_ia64_ivt,
+ .module = THIS_MODULE,
+ .vmm_entry = vmm_entry,
+ .tramp_entry = vmm_trampoline,
+ .vmm_ivt = (unsigned long)&kvm_ia64_ivt,
+ .patch_mov_ar = (unsigned long)&kvm_asm_mov_from_ar,
+ .patch_mov_ar_sn2 = (unsigned long)&kvm_asm_mov_from_ar_sn2,
};
static int __init kvm_vmm_init(void)
diff --git a/arch/ia64/kvm/vmm_ivt.S b/arch/ia64/kvm/vmm_ivt.S
index 3ef1a017a318..40920c630649 100644
--- a/arch/ia64/kvm/vmm_ivt.S
+++ b/arch/ia64/kvm/vmm_ivt.S
@@ -95,7 +95,7 @@ GLOBAL_ENTRY(kvm_vmm_panic)
;;
srlz.i // guarantee that interruption collection is on
;;
- //(p15) ssm psr.i // restore psr.i
+ (p15) ssm psr.i // restore psr.
addl r14=@gprel(ia64_leave_hypervisor),gp
;;
KVM_SAVE_REST
@@ -249,7 +249,7 @@ ENTRY(kvm_break_fault)
;;
srlz.i // guarantee that interruption collection is on
;;
- //(p15)ssm psr.i // restore psr.i
+ (p15)ssm psr.i // restore psr.i
addl r14=@gprel(ia64_leave_hypervisor),gp
;;
KVM_SAVE_REST
@@ -439,7 +439,7 @@ kvm_dispatch_vexirq:
;;
srlz.i // guarantee that interruption collection is on
;;
- //(p15) ssm psr.i // restore psr.i
+ (p15) ssm psr.i // restore psr.i
adds r3=8,r2 // set up second base pointer
;;
KVM_SAVE_REST
@@ -819,7 +819,7 @@ ENTRY(kvm_dtlb_miss_dispatch)
;;
srlz.i // guarantee that interruption collection is on
;;
- //(p15) ssm psr.i // restore psr.i
+ (p15) ssm psr.i // restore psr.i
addl r14=@gprel(ia64_leave_hypervisor_prepare),gp
;;
KVM_SAVE_REST
@@ -842,7 +842,7 @@ ENTRY(kvm_itlb_miss_dispatch)
;;
srlz.i // guarantee that interruption collection is on
;;
- //(p15) ssm psr.i // restore psr.i
+ (p15) ssm psr.i // restore psr.i
addl r14=@gprel(ia64_leave_hypervisor),gp
;;
KVM_SAVE_REST
@@ -871,7 +871,7 @@ ENTRY(kvm_dispatch_reflection)
;;
srlz.i // guarantee that interruption collection is on
;;
- //(p15) ssm psr.i // restore psr.i
+ (p15) ssm psr.i // restore psr.i
addl r14=@gprel(ia64_leave_hypervisor),gp
;;
KVM_SAVE_REST
@@ -898,7 +898,7 @@ ENTRY(kvm_dispatch_virtualization_fault)
;;
srlz.i // guarantee that interruption collection is on
;;
- //(p15) ssm psr.i // restore psr.i
+ (p15) ssm psr.i // restore psr.i
addl r14=@gprel(ia64_leave_hypervisor_prepare),gp
;;
KVM_SAVE_REST
@@ -920,7 +920,7 @@ ENTRY(kvm_dispatch_interrupt)
;;
srlz.i
;;
- //(p15) ssm psr.i
+ (p15) ssm psr.i
addl r14=@gprel(ia64_leave_hypervisor),gp
;;
KVM_SAVE_REST
@@ -1333,7 +1333,7 @@ hostret = r24
;;
(p7) srlz.i
;;
-//(p6) ssm psr.i
+(p6) ssm psr.i
;;
mov rp=rpsave
mov ar.pfs=pfssave
diff --git a/arch/ia64/kvm/vtlb.c b/arch/ia64/kvm/vtlb.c
index 2c2501f13159..4290a429bf7c 100644
--- a/arch/ia64/kvm/vtlb.c
+++ b/arch/ia64/kvm/vtlb.c
@@ -254,7 +254,8 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
"(p7) st8 [%2]=r9;;"
"ssm psr.ic;;"
"srlz.d;;"
- /* "ssm psr.i;;" Once interrupts in vmm open, need fix*/
+ "ssm psr.i;;"
+ "srlz.d;;"
: "=r"(ret) : "r"(iha), "r"(pte):"memory");
return ret;
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 66fd705e82c0..764f26abac05 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -227,7 +227,7 @@ finish_up:
return new_irq_info;
}
-static void sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
+static int sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
{
struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
nasid_t nasid;
@@ -239,6 +239,8 @@ static void sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
sn_irq_lh[irq], list)
(void)sn_retarget_vector(sn_irq_info, nasid, slice);
+
+ return 0;
}
#ifdef CONFIG_SMP
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index 81e428943d73..fbbfb9701201 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -151,7 +151,7 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
}
#ifdef CONFIG_SMP
-static void sn_set_msi_irq_affinity(unsigned int irq,
+static int sn_set_msi_irq_affinity(unsigned int irq,
const struct cpumask *cpu_mask)
{
struct msi_msg msg;
@@ -168,7 +168,7 @@ static void sn_set_msi_irq_affinity(unsigned int irq,
cpu = cpumask_first(cpu_mask);
sn_irq_info = sn_msi_info[irq].sn_irq_info;
if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
- return;
+ return -1;
/*
* Release XIO resources for the old MSI PCI address
@@ -189,7 +189,7 @@ static void sn_set_msi_irq_affinity(unsigned int irq,
new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice);
sn_msi_info[irq].sn_irq_info = new_irq_info;
if (new_irq_info == NULL)
- return;
+ return -1;
/*
* Map the xio address into bus space
@@ -206,6 +206,8 @@ static void sn_set_msi_irq_affinity(unsigned int irq,
write_msi_msg(irq, &msg);
cpumask_copy(irq_desc[irq].affinity, cpu_mask);
+
+ return 0;
}
#endif /* CONFIG_SMP */
diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h
index 1cf544767453..87cabc334249 100644
--- a/arch/m68k/include/asm/checksum.h
+++ b/arch/m68k/include/asm/checksum.h
@@ -1,5 +1,159 @@
-#ifdef __uClinux__
-#include "checksum_no.h"
+#ifndef _M68K_CHECKSUM_H
+#define _M68K_CHECKSUM_H
+
+#include <linux/in6.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+__wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern __wsum csum_partial_copy_from_user(const void __user *src,
+ void *dst,
+ int len, __wsum sum,
+ int *csum_err);
+
+extern __wsum csum_partial_copy_nocheck(const void *src,
+ void *dst, int len,
+ __wsum sum);
+
+
+#ifdef CONFIG_MMU
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ *
+ */
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+ unsigned int sum = 0;
+ unsigned long tmp;
+
+ __asm__ ("subqw #1,%2\n"
+ "1:\t"
+ "movel %1@+,%3\n\t"
+ "addxl %3,%0\n\t"
+ "dbra %2,1b\n\t"
+ "movel %0,%3\n\t"
+ "swap %3\n\t"
+ "addxw %3,%0\n\t"
+ "clrw %3\n\t"
+ "addxw %3,%0\n\t"
+ : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
+ : "0" (sum), "1" (iph), "2" (ihl)
+ : "memory");
+ return (__force __sum16)~sum;
+}
#else
-#include "checksum_mm.h"
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
#endif
+
+/*
+ * Fold a partial checksum
+ */
+
+static inline __sum16 csum_fold(__wsum sum)
+{
+ unsigned int tmp = (__force u32)sum;
+#ifdef CONFIG_COLDFIRE
+ tmp = (tmp & 0xffff) + (tmp >> 16);
+ tmp = (tmp & 0xffff) + (tmp >> 16);
+ return (__force __sum16)~tmp;
+#else
+ __asm__("swap %1\n\t"
+ "addw %1, %0\n\t"
+ "clrw %1\n\t"
+ "addxw %1, %0"
+ : "=&d" (sum), "=&d" (tmp)
+ : "0" (sum), "1" (tmp));
+ return (__force __sum16)~sum;
+#endif
+}
+
+
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ __asm__ ("addl %2,%0\n\t"
+ "addxl %3,%0\n\t"
+ "addxl %4,%0\n\t"
+ "clrl %1\n\t"
+ "addxl %1,%0"
+ : "=&d" (sum), "=d" (saddr)
+ : "g" (daddr), "1" (saddr), "d" (len + proto),
+ "0" (sum));
+ return sum;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+static inline __sum16 ip_compute_csum(const void *buff, int len)
+{
+ return csum_fold (csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ __sum16
+csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
+ __u32 len, unsigned short proto, __wsum sum)
+{
+ register unsigned long tmp;
+ __asm__("addl %2@,%0\n\t"
+ "movel %2@(4),%1\n\t"
+ "addxl %1,%0\n\t"
+ "movel %2@(8),%1\n\t"
+ "addxl %1,%0\n\t"
+ "movel %2@(12),%1\n\t"
+ "addxl %1,%0\n\t"
+ "movel %3@,%1\n\t"
+ "addxl %1,%0\n\t"
+ "movel %3@(4),%1\n\t"
+ "addxl %1,%0\n\t"
+ "movel %3@(8),%1\n\t"
+ "addxl %1,%0\n\t"
+ "movel %3@(12),%1\n\t"
+ "addxl %1,%0\n\t"
+ "addxl %4,%0\n\t"
+ "clrl %1\n\t"
+ "addxl %1,%0"
+ : "=&d" (sum), "=&d" (tmp)
+ : "a" (saddr), "a" (daddr), "d" (len + proto),
+ "0" (sum));
+
+ return csum_fold(sum);
+}
+
+#endif /* _M68K_CHECKSUM_H */
diff --git a/arch/m68k/include/asm/checksum_mm.h b/arch/m68k/include/asm/checksum_mm.h
deleted file mode 100644
index 494f9aec37ea..000000000000
--- a/arch/m68k/include/asm/checksum_mm.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef _M68K_CHECKSUM_H
-#define _M68K_CHECKSUM_H
-
-#include <linux/in6.h>
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * the same as csum_partial, but copies from src while it
- * checksums
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-extern __wsum csum_partial_copy_from_user(const void __user *src,
- void *dst,
- int len, __wsum sum,
- int *csum_err);
-
-extern __wsum csum_partial_copy_nocheck(const void *src,
- void *dst, int len,
- __wsum sum);
-
-/*
- * This is a version of ip_compute_csum() optimized for IP headers,
- * which always checksum on 4 octet boundaries.
- *
- */
-static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
-{
- unsigned int sum = 0;
- unsigned long tmp;
-
- __asm__ ("subqw #1,%2\n"
- "1:\t"
- "movel %1@+,%3\n\t"
- "addxl %3,%0\n\t"
- "dbra %2,1b\n\t"
- "movel %0,%3\n\t"
- "swap %3\n\t"
- "addxw %3,%0\n\t"
- "clrw %3\n\t"
- "addxw %3,%0\n\t"
- : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
- : "0" (sum), "1" (iph), "2" (ihl)
- : "memory");
- return (__force __sum16)~sum;
-}
-
-/*
- * Fold a partial checksum
- */
-
-static inline __sum16 csum_fold(__wsum sum)
-{
- unsigned int tmp = (__force u32)sum;
- __asm__("swap %1\n\t"
- "addw %1, %0\n\t"
- "clrw %1\n\t"
- "addxw %1, %0"
- : "=&d" (sum), "=&d" (tmp)
- : "0" (sum), "1" (tmp));
- return (__force __sum16)~sum;
-}
-
-
-static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
-{
- __asm__ ("addl %2,%0\n\t"
- "addxl %3,%0\n\t"
- "addxl %4,%0\n\t"
- "clrl %1\n\t"
- "addxl %1,%0"
- : "=&d" (sum), "=d" (saddr)
- : "g" (daddr), "1" (saddr), "d" (len + proto),
- "0" (sum));
- return sum;
-}
-
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
-{
- return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-
-static inline __sum16 ip_compute_csum(const void *buff, int len)
-{
- return csum_fold (csum_partial(buff, len, 0));
-}
-
-#define _HAVE_ARCH_IPV6_CSUM
-static __inline__ __sum16
-csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
- __u32 len, unsigned short proto, __wsum sum)
-{
- register unsigned long tmp;
- __asm__("addl %2@,%0\n\t"
- "movel %2@(4),%1\n\t"
- "addxl %1,%0\n\t"
- "movel %2@(8),%1\n\t"
- "addxl %1,%0\n\t"
- "movel %2@(12),%1\n\t"
- "addxl %1,%0\n\t"
- "movel %3@,%1\n\t"
- "addxl %1,%0\n\t"
- "movel %3@(4),%1\n\t"
- "addxl %1,%0\n\t"
- "movel %3@(8),%1\n\t"
- "addxl %1,%0\n\t"
- "movel %3@(12),%1\n\t"
- "addxl %1,%0\n\t"
- "addxl %4,%0\n\t"
- "clrl %1\n\t"
- "addxl %1,%0"
- : "=&d" (sum), "=&d" (tmp)
- : "a" (saddr), "a" (daddr), "d" (len + proto),
- "0" (sum));
-
- return csum_fold(sum);
-}
-
-#endif /* _M68K_CHECKSUM_H */
diff --git a/arch/m68k/include/asm/checksum_no.h b/arch/m68k/include/asm/checksum_no.h
deleted file mode 100644
index 81883482ffb1..000000000000
--- a/arch/m68k/include/asm/checksum_no.h
+++ /dev/null
@@ -1,132 +0,0 @@
-#ifndef _M68K_CHECKSUM_H
-#define _M68K_CHECKSUM_H
-
-#include <linux/in6.h>
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * the same as csum_partial, but copies from src while it
- * checksums
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-__wsum csum_partial_copy_nocheck(const void *src, void *dst,
- int len, __wsum sum);
-
-
-/*
- * the same as csum_partial_copy, but copies from user space.
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-extern __wsum csum_partial_copy_from_user(const void __user *src,
- void *dst, int len, __wsum sum, int *csum_err);
-
-__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
-
-/*
- * Fold a partial checksum
- */
-
-static inline __sum16 csum_fold(__wsum sum)
-{
- unsigned int tmp = (__force u32)sum;
-#ifdef CONFIG_COLDFIRE
- tmp = (tmp & 0xffff) + (tmp >> 16);
- tmp = (tmp & 0xffff) + (tmp >> 16);
- return (__force __sum16)~tmp;
-#else
- __asm__("swap %1\n\t"
- "addw %1, %0\n\t"
- "clrw %1\n\t"
- "addxw %1, %0"
- : "=&d" (sum), "=&d" (tmp)
- : "0" (sum), "1" (sum));
- return (__force __sum16)~sum;
-#endif
-}
-
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-
-static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
-{
- __asm__ ("addl %1,%0\n\t"
- "addxl %4,%0\n\t"
- "addxl %5,%0\n\t"
- "clrl %1\n\t"
- "addxl %1,%0"
- : "=&d" (sum), "=&d" (saddr)
- : "0" (daddr), "1" (saddr), "d" (len + proto),
- "d"(sum));
- return sum;
-}
-
-static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
-{
- return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-
-extern __sum16 ip_compute_csum(const void *buff, int len);
-
-#define _HAVE_ARCH_IPV6_CSUM
-static __inline__ __sum16
-csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
- __u32 len, unsigned short proto, __wsum sum)
-{
- register unsigned long tmp;
- __asm__("addl %2@,%0\n\t"
- "movel %2@(4),%1\n\t"
- "addxl %1,%0\n\t"
- "movel %2@(8),%1\n\t"
- "addxl %1,%0\n\t"
- "movel %2@(12),%1\n\t"
- "addxl %1,%0\n\t"
- "movel %3@,%1\n\t"
- "addxl %1,%0\n\t"
- "movel %3@(4),%1\n\t"
- "addxl %1,%0\n\t"
- "movel %3@(8),%1\n\t"
- "addxl %1,%0\n\t"
- "movel %3@(12),%1\n\t"
- "addxl %1,%0\n\t"
- "addxl %4,%0\n\t"
- "clrl %1\n\t"
- "addxl %1,%0"
- : "=&d" (sum), "=&d" (tmp)
- : "a" (saddr), "a" (daddr), "d" (len + proto),
- "0" (sum));
-
- return csum_fold(sum);
-}
-
-#endif /* _M68K_CHECKSUM_H */
diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h
index b82e660cf1c2..1f1fcdf5e49e 100644
--- a/arch/m68k/include/asm/dma.h
+++ b/arch/m68k/include/asm/dma.h
@@ -1,5 +1,492 @@
-#ifdef __uClinux__
-#include "dma_no.h"
+#ifndef _M68K_DMA_H
+#define _M68K_DMA_H 1
+
+#ifdef CONFIG_COLDFIRE
+/*
+ * ColdFire DMA Model:
+ * ColdFire DMA supports two forms of DMA: Single and Dual address. Single
+ * address mode emits a source address, and expects that the device will either
+ * pick up the data (DMA READ) or source data (DMA WRITE). This implies that
+ * the device will place data on the correct byte(s) of the data bus, as the
+ * memory transactions are always 32 bits. This implies that only 32 bit
+ * devices will find single mode transfers useful. Dual address DMA mode
+ * performs two cycles: source read and destination write. ColdFire will
+ * align the data so that the device will always get the correct bytes, thus
+ * is useful for 8 and 16 bit devices. This is the mode that is supported
+ * below.
+ *
+ * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000
+ * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
+ *
+ * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
+ * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
+ *
+ * APR/18/2002 : added proper support for MCF5272 DMA controller.
+ * Arthur Shipkowski (art@videon-central.com)
+ */
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+
+/*
+ * Set number of channels of DMA on ColdFire for different implementations.
+ */
+#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \
+ defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#define MAX_M68K_DMA_CHANNELS 4
+#elif defined(CONFIG_M5272)
+#define MAX_M68K_DMA_CHANNELS 1
+#elif defined(CONFIG_M532x)
+#define MAX_M68K_DMA_CHANNELS 0
#else
-#include "dma_mm.h"
+#define MAX_M68K_DMA_CHANNELS 2
#endif
+
+extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
+extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+#if !defined(CONFIG_M5272)
+#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */
+#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */
+#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */
+#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */
+
+/* I/O to memory, 8 bits, mode */
+#define DMA_MODE_READ 0
+/* memory to I/O, 8 bits, mode */
+#define DMA_MODE_WRITE 1
+/* I/O to memory, 16 bits, mode */
+#define DMA_MODE_READ_WORD 2
+/* memory to I/O, 16 bits, mode */
+#define DMA_MODE_WRITE_WORD 3
+/* I/O to memory, 32 bits, mode */
+#define DMA_MODE_READ_LONG 4
+/* memory to I/O, 32 bits, mode */
+#define DMA_MODE_WRITE_LONG 5
+/* I/O to memory, 8 bits, single-address-mode */
+#define DMA_MODE_READ_SINGLE 8
+/* memory to I/O, 8 bits, single-address-mode */
+#define DMA_MODE_WRITE_SINGLE 9
+/* I/O to memory, 16 bits, single-address-mode */
+#define DMA_MODE_READ_WORD_SINGLE 10
+/* memory to I/O, 16 bits, single-address-mode */
+#define DMA_MODE_WRITE_WORD_SINGLE 11
+/* I/O to memory, 32 bits, single-address-mode */
+#define DMA_MODE_READ_LONG_SINGLE 12
+/* memory to I/O, 32 bits, single-address-mode */
+#define DMA_MODE_WRITE_LONG_SINGLE 13
+
+#else /* CONFIG_M5272 is defined */
+
+/* Source static-address mode */
+#define DMA_MODE_SRC_SA_BIT 0x01
+/* Two bits to select between all four modes */
+#define DMA_MODE_SSIZE_MASK 0x06
+/* Offset to shift bits in */
+#define DMA_MODE_SSIZE_OFF 0x01
+/* Destination static-address mode */
+#define DMA_MODE_DES_SA_BIT 0x10
+/* Two bits to select between all four modes */
+#define DMA_MODE_DSIZE_MASK 0x60
+/* Offset to shift bits in */
+#define DMA_MODE_DSIZE_OFF 0x05
+/* Size modifiers */
+#define DMA_MODE_SIZE_LONG 0x00
+#define DMA_MODE_SIZE_BYTE 0x01
+#define DMA_MODE_SIZE_WORD 0x02
+#define DMA_MODE_SIZE_LINE 0x03
+
+/*
+ * Aliases to help speed quick ports; these may be suboptimal, however. They
+ * do not include the SINGLE mode modifiers since the MCF5272 does not have a
+ * mode where the device is in control of its addressing.
+ */
+
+/* I/O to memory, 8 bits, mode */
+#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 8 bits, mode */
+#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+/* I/O to memory, 16 bits, mode */
+#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 16 bits, mode */
+#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+/* I/O to memory, 32 bits, mode */
+#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 32 bits, mode */
+#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+
+#endif /* !defined(CONFIG_M5272) */
+
+#if !defined(CONFIG_M5272)
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+ volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+ printk("enable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+ dmawp = (unsigned short *) dma_base_addr[dmanr];
+ dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+ volatile unsigned short *dmawp;
+ volatile unsigned char *dmapb;
+
+#ifdef DMA_DEBUG
+ printk("disable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+ dmawp = (unsigned short *) dma_base_addr[dmanr];
+ dmapb = (unsigned char *) dma_base_addr[dmanr];
+
+ /* Turn off external requests, and stop any DMA in progress */
+ dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
+ dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
+}
+
+/*
+ * Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ *
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+
+ volatile unsigned char *dmabp;
+ volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+ printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
+#endif
+
+ dmabp = (unsigned char *) dma_base_addr[dmanr];
+ dmawp = (unsigned short *) dma_base_addr[dmanr];
+
+ // Clear config errors
+ dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE;
+
+ // Set command register
+ dmawp[MCFDMA_DCR] =
+ MCFDMA_DCR_INT | // Enable completion irq
+ MCFDMA_DCR_CS | // Force one xfer per request
+ MCFDMA_DCR_AA | // Enable auto alignment
+ // single-address-mode
+ ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) |
+ // sets s_rw (-> r/w) high if Memory to I/0
+ ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) |
+ // Memory to I/O or I/O to Memory
+ ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) |
+ // 32 bit, 16 bit or 8 bit transfers
+ ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD :
+ ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG :
+ MCFDMA_DCR_SSIZE_BYTE)) |
+ ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_DSIZE_WORD :
+ ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG :
+ MCFDMA_DCR_DSIZE_BYTE));
+
+#ifdef DEBUG_DMA
+ printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__,
+ dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR],
+ (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]);
+#endif
+}
+
+/* Set transfer address for specific DMA channel */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+ volatile unsigned short *dmawp;
+ volatile unsigned int *dmalp;
+
+#ifdef DMA_DEBUG
+ printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+ dmawp = (unsigned short *) dma_base_addr[dmanr];
+ dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+ // Determine which address registers are used for memory/device accesses
+ if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) {
+ // Source incrementing, must be memory
+ dmalp[MCFDMA_SAR] = a;
+ // Set dest address, must be device
+ dmalp[MCFDMA_DAR] = dma_device_address[dmanr];
+ } else {
+ // Destination incrementing, must be memory
+ dmalp[MCFDMA_DAR] = a;
+ // Set source address, must be device
+ dmalp[MCFDMA_SAR] = dma_device_address[dmanr];
+ }
+
+#ifdef DEBUG_DMA
+ printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
+ __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR],
+ (int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR],
+ (int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]);
+#endif
+}
+
+/*
+ * Specific for Coldfire - sets device address.
+ * Should be called after the mode set call, and before set DMA address.
+ */
+static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
+{
+#ifdef DMA_DEBUG
+ printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+ dma_device_address[dmanr] = a;
+}
+
+/*
+ * NOTE 2: "count" represents _bytes_.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+ volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+ printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
+#endif
+
+ dmawp = (unsigned short *) dma_base_addr[dmanr];
+ dmawp[MCFDMA_BCR] = (unsigned short)count;
+}
+
+/*
+ * Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+ volatile unsigned short *dmawp;
+ unsigned short count;
+
+#ifdef DMA_DEBUG
+ printk("get_dma_residue(dmanr=%d)\n", dmanr);
+#endif
+
+ dmawp = (unsigned short *) dma_base_addr[dmanr];
+ count = dmawp[MCFDMA_BCR];
+ return((int) count);
+}
+#else /* CONFIG_M5272 is defined */
+
+/*
+ * The MCF5272 DMA controller is very different than the controller defined above
+ * in terms of register mapping. For instance, with the exception of the 16-bit
+ * interrupt register (IRQ#85, for reference), all of the registers are 32-bit.
+ *
+ * The big difference, however, is the lack of device-requested DMA. All modes
+ * are dual address transfer, and there is no 'device' setup or direction bit.
+ * You can DMA between a device and memory, between memory and memory, or even between
+ * two devices directly, with any combination of incrementing and non-incrementing
+ * addresses you choose. This puts a crimp in distinguishing between the 'device
+ * address' set up by set_dma_device_addr.
+ *
+ * Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr,
+ * which will act exactly as above in -- it will look to see if the source is set to
+ * autoincrement, and if so it will make the source use the set_dma_addr value and the
+ * destination the set_dma_device_addr value. Otherwise the source will be set to the
+ * set_dma_device_addr value and the destination will get the set_dma_addr value.
+ *
+ * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions
+ * and make it explicit. Depending on what you're doing, one of these two should work
+ * for you, but don't mix them in the same transfer setup.
+ */
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+ volatile unsigned int *dmalp;
+
+#ifdef DMA_DEBUG
+ printk("enable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+ dmalp = (unsigned int *) dma_base_addr[dmanr];
+ dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+ volatile unsigned int *dmalp;
+
+#ifdef DMA_DEBUG
+ printk("disable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+ dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+ /* Turn off external requests, and stop any DMA in progress */
+ dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
+ dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
+}
+
+/*
+ * Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ *
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+
+ volatile unsigned int *dmalp;
+ volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+ printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
+#endif
+ dmalp = (unsigned int *) dma_base_addr[dmanr];
+ dmawp = (unsigned short *) dma_base_addr[dmanr];
+
+ // Clear config errors
+ dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
+
+ // Set command register
+ dmalp[MCFDMA_DMR] =
+ MCFDMA_DMR_RQM_DUAL | // Mandatory Request Mode setting
+ MCFDMA_DMR_DSTT_SD | // Set up addressing types; set to supervisor-data.
+ MCFDMA_DMR_SRCT_SD | // Set up addressing types; set to supervisor-data.
+ // source static-address-mode
+ ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
+ // dest static-address-mode
+ ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
+ // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272
+ (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
+ (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
+
+ dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */
+
+#ifdef DEBUG_DMA
+ printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
+ dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
+ (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
+#endif
+}
+
+/* Set transfer address for specific DMA channel */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+ volatile unsigned int *dmalp;
+
+#ifdef DMA_DEBUG
+ printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+ dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+ // Determine which address registers are used for memory/device accesses
+ if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) {
+ // Source incrementing, must be memory
+ dmalp[MCFDMA_DSAR] = a;
+ // Set dest address, must be device
+ dmalp[MCFDMA_DDAR] = dma_device_address[dmanr];
+ } else {
+ // Destination incrementing, must be memory
+ dmalp[MCFDMA_DDAR] = a;
+ // Set source address, must be device
+ dmalp[MCFDMA_DSAR] = dma_device_address[dmanr];
+ }
+
+#ifdef DEBUG_DMA
+ printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
+ __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR],
+ (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR],
+ (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);
+#endif
+}
+
+/*
+ * Specific for Coldfire - sets device address.
+ * Should be called after the mode set call, and before set DMA address.
+ */
+static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
+{
+#ifdef DMA_DEBUG
+ printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+ dma_device_address[dmanr] = a;
+}
+
+/*
+ * NOTE 2: "count" represents _bytes_.
+ *
+ * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+ volatile unsigned int *dmalp;
+
+#ifdef DMA_DEBUG
+ printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
+#endif
+
+ dmalp = (unsigned int *) dma_base_addr[dmanr];
+ dmalp[MCFDMA_DBCR] = count;
+}
+
+/*
+ * Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+ volatile unsigned int *dmalp;
+ unsigned int count;
+
+#ifdef DMA_DEBUG
+ printk("get_dma_residue(dmanr=%d)\n", dmanr);
+#endif
+
+ dmalp = (unsigned int *) dma_base_addr[dmanr];
+ count = dmalp[MCFDMA_DBCR];
+ return(count);
+}
+
+#endif /* !defined(CONFIG_M5272) */
+#endif /* CONFIG_COLDFIRE */
+
+
+/* it's useless on the m68k, but unfortunately needed by the new
+ bootmem allocator (but this should do it for this) */
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+
+#define MAX_DMA_CHANNELS 8
+
+extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr); /* release it again */
+
+#define isa_dma_bridge_buggy (0)
+
+#endif /* _M68K_DMA_H */
diff --git a/arch/m68k/include/asm/dma_mm.h b/arch/m68k/include/asm/dma_mm.h
deleted file mode 100644
index 4240fbc946f8..000000000000
--- a/arch/m68k/include/asm/dma_mm.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _M68K_DMA_H
-#define _M68K_DMA_H 1
-
-
-/* it's useless on the m68k, but unfortunately needed by the new
- bootmem allocator (but this should do it for this) */
-#define MAX_DMA_ADDRESS PAGE_OFFSET
-
-#define MAX_DMA_CHANNELS 8
-
-extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr); /* release it again */
-
-#define isa_dma_bridge_buggy (0)
-
-#endif /* _M68K_DMA_H */
diff --git a/arch/m68k/include/asm/dma_no.h b/arch/m68k/include/asm/dma_no.h
deleted file mode 100644
index 939a02056217..000000000000
--- a/arch/m68k/include/asm/dma_no.h
+++ /dev/null
@@ -1,494 +0,0 @@
-#ifndef _M68K_DMA_H
-#define _M68K_DMA_H 1
-
-//#define DMA_DEBUG 1
-
-
-#ifdef CONFIG_COLDFIRE
-/*
- * ColdFire DMA Model:
- * ColdFire DMA supports two forms of DMA: Single and Dual address. Single
- * address mode emits a source address, and expects that the device will either
- * pick up the data (DMA READ) or source data (DMA WRITE). This implies that
- * the device will place data on the correct byte(s) of the data bus, as the
- * memory transactions are always 32 bits. This implies that only 32 bit
- * devices will find single mode transfers useful. Dual address DMA mode
- * performs two cycles: source read and destination write. ColdFire will
- * align the data so that the device will always get the correct bytes, thus
- * is useful for 8 and 16 bit devices. This is the mode that is supported
- * below.
- *
- * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000
- * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
- *
- * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
- * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
- *
- * APR/18/2002 : added proper support for MCF5272 DMA controller.
- * Arthur Shipkowski (art@videon-central.com)
- */
-
-#include <asm/coldfire.h>
-#include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
-
-/*
- * Set number of channels of DMA on ColdFire for different implementations.
- */
-#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \
- defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
-#define MAX_M68K_DMA_CHANNELS 4
-#elif defined(CONFIG_M5272)
-#define MAX_M68K_DMA_CHANNELS 1
-#elif defined(CONFIG_M532x)
-#define MAX_M68K_DMA_CHANNELS 0
-#else
-#define MAX_M68K_DMA_CHANNELS 2
-#endif
-
-extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
-extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
-
-#if !defined(CONFIG_M5272)
-#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */
-#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */
-#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */
-#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */
-
-/* I/O to memory, 8 bits, mode */
-#define DMA_MODE_READ 0
-/* memory to I/O, 8 bits, mode */
-#define DMA_MODE_WRITE 1
-/* I/O to memory, 16 bits, mode */
-#define DMA_MODE_READ_WORD 2
-/* memory to I/O, 16 bits, mode */
-#define DMA_MODE_WRITE_WORD 3
-/* I/O to memory, 32 bits, mode */
-#define DMA_MODE_READ_LONG 4
-/* memory to I/O, 32 bits, mode */
-#define DMA_MODE_WRITE_LONG 5
-/* I/O to memory, 8 bits, single-address-mode */
-#define DMA_MODE_READ_SINGLE 8
-/* memory to I/O, 8 bits, single-address-mode */
-#define DMA_MODE_WRITE_SINGLE 9
-/* I/O to memory, 16 bits, single-address-mode */
-#define DMA_MODE_READ_WORD_SINGLE 10
-/* memory to I/O, 16 bits, single-address-mode */
-#define DMA_MODE_WRITE_WORD_SINGLE 11
-/* I/O to memory, 32 bits, single-address-mode */
-#define DMA_MODE_READ_LONG_SINGLE 12
-/* memory to I/O, 32 bits, single-address-mode */
-#define DMA_MODE_WRITE_LONG_SINGLE 13
-
-#else /* CONFIG_M5272 is defined */
-
-/* Source static-address mode */
-#define DMA_MODE_SRC_SA_BIT 0x01
-/* Two bits to select between all four modes */
-#define DMA_MODE_SSIZE_MASK 0x06
-/* Offset to shift bits in */
-#define DMA_MODE_SSIZE_OFF 0x01
-/* Destination static-address mode */
-#define DMA_MODE_DES_SA_BIT 0x10
-/* Two bits to select between all four modes */
-#define DMA_MODE_DSIZE_MASK 0x60
-/* Offset to shift bits in */
-#define DMA_MODE_DSIZE_OFF 0x05
-/* Size modifiers */
-#define DMA_MODE_SIZE_LONG 0x00
-#define DMA_MODE_SIZE_BYTE 0x01
-#define DMA_MODE_SIZE_WORD 0x02
-#define DMA_MODE_SIZE_LINE 0x03
-
-/*
- * Aliases to help speed quick ports; these may be suboptimal, however. They
- * do not include the SINGLE mode modifiers since the MCF5272 does not have a
- * mode where the device is in control of its addressing.
- */
-
-/* I/O to memory, 8 bits, mode */
-#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
-/* memory to I/O, 8 bits, mode */
-#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
-/* I/O to memory, 16 bits, mode */
-#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
-/* memory to I/O, 16 bits, mode */
-#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
-/* I/O to memory, 32 bits, mode */
-#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
-/* memory to I/O, 32 bits, mode */
-#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
-
-#endif /* !defined(CONFIG_M5272) */
-
-#if !defined(CONFIG_M5272)
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
- volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
- printk("enable_dma(dmanr=%d)\n", dmanr);
-#endif
-
- dmawp = (unsigned short *) dma_base_addr[dmanr];
- dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
- volatile unsigned short *dmawp;
- volatile unsigned char *dmapb;
-
-#ifdef DMA_DEBUG
- printk("disable_dma(dmanr=%d)\n", dmanr);
-#endif
-
- dmawp = (unsigned short *) dma_base_addr[dmanr];
- dmapb = (unsigned char *) dma_base_addr[dmanr];
-
- /* Turn off external requests, and stop any DMA in progress */
- dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
- dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
-}
-
-/*
- * Clear the 'DMA Pointer Flip Flop'.
- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
- * Use this once to initialize the FF to a known state.
- * After that, keep track of it. :-)
- * --- In order to do that, the DMA routines below should ---
- * --- only be used while interrupts are disabled! ---
- *
- * This is a NOP for ColdFire. Provide a stub for compatibility.
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
-
- volatile unsigned char *dmabp;
- volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
- printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
-#endif
-
- dmabp = (unsigned char *) dma_base_addr[dmanr];
- dmawp = (unsigned short *) dma_base_addr[dmanr];
-
- // Clear config errors
- dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE;
-
- // Set command register
- dmawp[MCFDMA_DCR] =
- MCFDMA_DCR_INT | // Enable completion irq
- MCFDMA_DCR_CS | // Force one xfer per request
- MCFDMA_DCR_AA | // Enable auto alignment
- // single-address-mode
- ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) |
- // sets s_rw (-> r/w) high if Memory to I/0
- ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) |
- // Memory to I/O or I/O to Memory
- ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) |
- // 32 bit, 16 bit or 8 bit transfers
- ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD :
- ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG :
- MCFDMA_DCR_SSIZE_BYTE)) |
- ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_DSIZE_WORD :
- ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG :
- MCFDMA_DCR_DSIZE_BYTE));
-
-#ifdef DEBUG_DMA
- printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__,
- dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR],
- (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]);
-#endif
-}
-
-/* Set transfer address for specific DMA channel */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
-{
- volatile unsigned short *dmawp;
- volatile unsigned int *dmalp;
-
-#ifdef DMA_DEBUG
- printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
- dmawp = (unsigned short *) dma_base_addr[dmanr];
- dmalp = (unsigned int *) dma_base_addr[dmanr];
-
- // Determine which address registers are used for memory/device accesses
- if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) {
- // Source incrementing, must be memory
- dmalp[MCFDMA_SAR] = a;
- // Set dest address, must be device
- dmalp[MCFDMA_DAR] = dma_device_address[dmanr];
- } else {
- // Destination incrementing, must be memory
- dmalp[MCFDMA_DAR] = a;
- // Set source address, must be device
- dmalp[MCFDMA_SAR] = dma_device_address[dmanr];
- }
-
-#ifdef DEBUG_DMA
- printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
- __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR],
- (int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR],
- (int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]);
-#endif
-}
-
-/*
- * Specific for Coldfire - sets device address.
- * Should be called after the mode set call, and before set DMA address.
- */
-static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
-{
-#ifdef DMA_DEBUG
- printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
- dma_device_address[dmanr] = a;
-}
-
-/*
- * NOTE 2: "count" represents _bytes_.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
- volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
- printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
-#endif
-
- dmawp = (unsigned short *) dma_base_addr[dmanr];
- dmawp[MCFDMA_BCR] = (unsigned short)count;
-}
-
-/*
- * Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
- * still in progress will return unpredictable results.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
- volatile unsigned short *dmawp;
- unsigned short count;
-
-#ifdef DMA_DEBUG
- printk("get_dma_residue(dmanr=%d)\n", dmanr);
-#endif
-
- dmawp = (unsigned short *) dma_base_addr[dmanr];
- count = dmawp[MCFDMA_BCR];
- return((int) count);
-}
-#else /* CONFIG_M5272 is defined */
-
-/*
- * The MCF5272 DMA controller is very different than the controller defined above
- * in terms of register mapping. For instance, with the exception of the 16-bit
- * interrupt register (IRQ#85, for reference), all of the registers are 32-bit.
- *
- * The big difference, however, is the lack of device-requested DMA. All modes
- * are dual address transfer, and there is no 'device' setup or direction bit.
- * You can DMA between a device and memory, between memory and memory, or even between
- * two devices directly, with any combination of incrementing and non-incrementing
- * addresses you choose. This puts a crimp in distinguishing between the 'device
- * address' set up by set_dma_device_addr.
- *
- * Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr,
- * which will act exactly as above in -- it will look to see if the source is set to
- * autoincrement, and if so it will make the source use the set_dma_addr value and the
- * destination the set_dma_device_addr value. Otherwise the source will be set to the
- * set_dma_device_addr value and the destination will get the set_dma_addr value.
- *
- * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions
- * and make it explicit. Depending on what you're doing, one of these two should work
- * for you, but don't mix them in the same transfer setup.
- */
-
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
- volatile unsigned int *dmalp;
-
-#ifdef DMA_DEBUG
- printk("enable_dma(dmanr=%d)\n", dmanr);
-#endif
-
- dmalp = (unsigned int *) dma_base_addr[dmanr];
- dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
- volatile unsigned int *dmalp;
-
-#ifdef DMA_DEBUG
- printk("disable_dma(dmanr=%d)\n", dmanr);
-#endif
-
- dmalp = (unsigned int *) dma_base_addr[dmanr];
-
- /* Turn off external requests, and stop any DMA in progress */
- dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
- dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
-}
-
-/*
- * Clear the 'DMA Pointer Flip Flop'.
- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
- * Use this once to initialize the FF to a known state.
- * After that, keep track of it. :-)
- * --- In order to do that, the DMA routines below should ---
- * --- only be used while interrupts are disabled! ---
- *
- * This is a NOP for ColdFire. Provide a stub for compatibility.
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
-
- volatile unsigned int *dmalp;
- volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
- printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
-#endif
- dmalp = (unsigned int *) dma_base_addr[dmanr];
- dmawp = (unsigned short *) dma_base_addr[dmanr];
-
- // Clear config errors
- dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
-
- // Set command register
- dmalp[MCFDMA_DMR] =
- MCFDMA_DMR_RQM_DUAL | // Mandatory Request Mode setting
- MCFDMA_DMR_DSTT_SD | // Set up addressing types; set to supervisor-data.
- MCFDMA_DMR_SRCT_SD | // Set up addressing types; set to supervisor-data.
- // source static-address-mode
- ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
- // dest static-address-mode
- ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
- // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272
- (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
- (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
-
- dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */
-
-#ifdef DEBUG_DMA
- printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
- dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
- (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
-#endif
-}
-
-/* Set transfer address for specific DMA channel */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
-{
- volatile unsigned int *dmalp;
-
-#ifdef DMA_DEBUG
- printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
- dmalp = (unsigned int *) dma_base_addr[dmanr];
-
- // Determine which address registers are used for memory/device accesses
- if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) {
- // Source incrementing, must be memory
- dmalp[MCFDMA_DSAR] = a;
- // Set dest address, must be device
- dmalp[MCFDMA_DDAR] = dma_device_address[dmanr];
- } else {
- // Destination incrementing, must be memory
- dmalp[MCFDMA_DDAR] = a;
- // Set source address, must be device
- dmalp[MCFDMA_DSAR] = dma_device_address[dmanr];
- }
-
-#ifdef DEBUG_DMA
- printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
- __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR],
- (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR],
- (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);
-#endif
-}
-
-/*
- * Specific for Coldfire - sets device address.
- * Should be called after the mode set call, and before set DMA address.
- */
-static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
-{
-#ifdef DMA_DEBUG
- printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
- dma_device_address[dmanr] = a;
-}
-
-/*
- * NOTE 2: "count" represents _bytes_.
- *
- * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
- volatile unsigned int *dmalp;
-
-#ifdef DMA_DEBUG
- printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
-#endif
-
- dmalp = (unsigned int *) dma_base_addr[dmanr];
- dmalp[MCFDMA_DBCR] = count;
-}
-
-/*
- * Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
- * still in progress will return unpredictable results.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
- volatile unsigned int *dmalp;
- unsigned int count;
-
-#ifdef DMA_DEBUG
- printk("get_dma_residue(dmanr=%d)\n", dmanr);
-#endif
-
- dmalp = (unsigned int *) dma_base_addr[dmanr];
- count = dmalp[MCFDMA_DBCR];
- return(count);
-}
-
-#endif /* !defined(CONFIG_M5272) */
-#endif /* CONFIG_COLDFIRE */
-
-#define MAX_DMA_CHANNELS 8
-
-/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any
- occurrence should be flagged as an error. */
-/* under 2.4 it is actually needed by the new bootmem allocator */
-#define MAX_DMA_ADDRESS PAGE_OFFSET
-
-/* These are in kernel/dma.c: */
-extern int request_dma(unsigned int dmanr, const char *device_id); /* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr); /* release it again */
-
-#endif /* _M68K_DMA_H */
diff --git a/arch/m68k/include/asm/hardirq.h b/arch/m68k/include/asm/hardirq.h
index 56d0d5db231c..7167ed209823 100644
--- a/arch/m68k/include/asm/hardirq.h
+++ b/arch/m68k/include/asm/hardirq.h
@@ -1,5 +1,18 @@
-#ifdef __uClinux__
-#include "hardirq_no.h"
-#else
-#include "hardirq_mm.h"
+#ifndef __M68K_HARDIRQ_H
+#define __M68K_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/cache.h>
+
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+ unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#define HARDIRQ_BITS 8
+
+void ack_bad_irq(unsigned int irq);
+
#endif
diff --git a/arch/m68k/include/asm/hardirq_mm.h b/arch/m68k/include/asm/hardirq_mm.h
deleted file mode 100644
index 394ee946015c..000000000000
--- a/arch/m68k/include/asm/hardirq_mm.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __M68K_HARDIRQ_H
-#define __M68K_HARDIRQ_H
-
-#include <linux/threads.h>
-#include <linux/cache.h>
-
-/* entry.S is sensitive to the offsets of these fields */
-typedef struct {
- unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
-#define HARDIRQ_BITS 8
-
-#endif
diff --git a/arch/m68k/include/asm/hardirq_no.h b/arch/m68k/include/asm/hardirq_no.h
deleted file mode 100644
index bfad28149a49..000000000000
--- a/arch/m68k/include/asm/hardirq_no.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef __M68K_HARDIRQ_H
-#define __M68K_HARDIRQ_H
-
-#include <linux/cache.h>
-#include <linux/threads.h>
-#include <asm/irq.h>
-
-typedef struct {
- unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
-#define HARDIRQ_BITS 8
-
-/*
- * The hardirq mask has to be large enough to have
- * space for potentially all IRQ sources in the system
- * nesting on a single CPU:
- */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
-void ack_bad_irq(unsigned int irq);
-
-#endif /* __M68K_HARDIRQ_H */
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h
index d031416595b2..cc0614a6deeb 100644
--- a/arch/m68k/include/asm/irq.h
+++ b/arch/m68k/include/asm/irq.h
@@ -1,5 +1,134 @@
-#ifdef __uClinux__
-#include "irq_no.h"
+#ifndef _M68K_IRQ_H_
+#define _M68K_IRQ_H_
+
+#include <linux/linkage.h>
+#include <linux/hardirq.h>
+#include <linux/irqreturn.h>
+#include <linux/spinlock_types.h>
+
+/*
+ * This should be the same as the max(NUM_X_SOURCES) for all the
+ * different m68k hosts compiled into the kernel.
+ * Currently the Atari has 72 and the Amiga 24, but if both are
+ * supported in the kernel it is better to make room for 72.
+ */
+#if defined(CONFIG_COLDFIRE)
+#define NR_IRQS 256
+#elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
+#define NR_IRQS 200
+#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
+#define NR_IRQS 72
+#elif defined(CONFIG_Q40)
+#define NR_IRQS 43
+#elif defined(CONFIG_AMIGA) || !defined(CONFIG_MMU)
+#define NR_IRQS 32
+#elif defined(CONFIG_APOLLO)
+#define NR_IRQS 24
+#elif defined(CONFIG_HP300)
+#define NR_IRQS 8
#else
-#include "irq_mm.h"
+#define NR_IRQS 0
#endif
+
+/*
+ * The hardirq mask has to be large enough to have
+ * space for potentially all IRQ sources in the system
+ * nesting on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+#endif
+
+#ifdef CONFIG_MMU
+
+/*
+ * Interrupt source definitions
+ * General interrupt sources are the level 1-7.
+ * Adding an interrupt service routine for one of these sources
+ * results in the addition of that routine to a chain of routines.
+ * Each one is called in succession. Each individual interrupt
+ * service routine should determine if the device associated with
+ * that routine requires service.
+ */
+
+#define IRQ_SPURIOUS 0
+
+#define IRQ_AUTO_1 1 /* level 1 interrupt */
+#define IRQ_AUTO_2 2 /* level 2 interrupt */
+#define IRQ_AUTO_3 3 /* level 3 interrupt */
+#define IRQ_AUTO_4 4 /* level 4 interrupt */
+#define IRQ_AUTO_5 5 /* level 5 interrupt */
+#define IRQ_AUTO_6 6 /* level 6 interrupt */
+#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */
+
+#define IRQ_USER 8
+
+extern unsigned int irq_canonicalize(unsigned int irq);
+
+struct pt_regs;
+
+/*
+ * various flags for request_irq() - the Amiga now uses the standard
+ * mechanism like all other architectures - IRQF_DISABLED and
+ * IRQF_SHARED are your friends.
+ */
+#ifndef MACH_AMIGA_ONLY
+#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */
+#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */
+#define IRQ_FLG_FAST (0x0004)
+#define IRQ_FLG_SLOW (0x0008)
+#define IRQ_FLG_STD (0x8000) /* internally used */
+#endif
+
+/*
+ * This structure is used to chain together the ISRs for a particular
+ * interrupt source (if it supports chaining).
+ */
+typedef struct irq_node {
+ irqreturn_t (*handler)(int, void *);
+ void *dev_id;
+ struct irq_node *next;
+ unsigned long flags;
+ const char *devname;
+} irq_node_t;
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+struct irq_handler {
+ int (*handler)(int, void *);
+ unsigned long flags;
+ void *dev_id;
+ const char *devname;
+};
+
+struct irq_controller {
+ const char *name;
+ spinlock_t lock;
+ int (*startup)(unsigned int irq);
+ void (*shutdown)(unsigned int irq);
+ void (*enable)(unsigned int irq);
+ void (*disable)(unsigned int irq);
+};
+
+extern int m68k_irq_startup(unsigned int);
+extern void m68k_irq_shutdown(unsigned int);
+
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+
+extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
+extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
+ void (*handler)(unsigned int, struct pt_regs *));
+extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
+
+asmlinkage void m68k_handle_int(unsigned int);
+asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
+
+#else
+#define irq_canonicalize(irq) (irq)
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_IRQ_H_ */
diff --git a/arch/m68k/include/asm/irq_mm.h b/arch/m68k/include/asm/irq_mm.h
deleted file mode 100644
index 0cab42cad79e..000000000000
--- a/arch/m68k/include/asm/irq_mm.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef _M68K_IRQ_H_
-#define _M68K_IRQ_H_
-
-#include <linux/linkage.h>
-#include <linux/hardirq.h>
-#include <linux/irqreturn.h>
-#include <linux/spinlock_types.h>
-
-/*
- * This should be the same as the max(NUM_X_SOURCES) for all the
- * different m68k hosts compiled into the kernel.
- * Currently the Atari has 72 and the Amiga 24, but if both are
- * supported in the kernel it is better to make room for 72.
- */
-#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
-#define NR_IRQS 200
-#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
-#define NR_IRQS 72
-#elif defined(CONFIG_Q40)
-#define NR_IRQS 43
-#elif defined(CONFIG_AMIGA)
-#define NR_IRQS 32
-#elif defined(CONFIG_APOLLO)
-#define NR_IRQS 24
-#elif defined(CONFIG_HP300)
-#define NR_IRQS 8
-#else
-#define NR_IRQS 0
-#endif
-
-/*
- * The hardirq mask has to be large enough to have
- * space for potentially all IRQ sources in the system
- * nesting on a single CPU:
- */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
-/*
- * Interrupt source definitions
- * General interrupt sources are the level 1-7.
- * Adding an interrupt service routine for one of these sources
- * results in the addition of that routine to a chain of routines.
- * Each one is called in succession. Each individual interrupt
- * service routine should determine if the device associated with
- * that routine requires service.
- */
-
-#define IRQ_SPURIOUS 0
-
-#define IRQ_AUTO_1 1 /* level 1 interrupt */
-#define IRQ_AUTO_2 2 /* level 2 interrupt */
-#define IRQ_AUTO_3 3 /* level 3 interrupt */
-#define IRQ_AUTO_4 4 /* level 4 interrupt */
-#define IRQ_AUTO_5 5 /* level 5 interrupt */
-#define IRQ_AUTO_6 6 /* level 6 interrupt */
-#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */
-
-#define IRQ_USER 8
-
-extern unsigned int irq_canonicalize(unsigned int irq);
-
-struct pt_regs;
-
-/*
- * various flags for request_irq() - the Amiga now uses the standard
- * mechanism like all other architectures - IRQF_DISABLED and
- * IRQF_SHARED are your friends.
- */
-#ifndef MACH_AMIGA_ONLY
-#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */
-#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */
-#define IRQ_FLG_FAST (0x0004)
-#define IRQ_FLG_SLOW (0x0008)
-#define IRQ_FLG_STD (0x8000) /* internally used */
-#endif
-
-/*
- * This structure is used to chain together the ISRs for a particular
- * interrupt source (if it supports chaining).
- */
-typedef struct irq_node {
- irqreturn_t (*handler)(int, void *);
- void *dev_id;
- struct irq_node *next;
- unsigned long flags;
- const char *devname;
-} irq_node_t;
-
-/*
- * This structure has only 4 elements for speed reasons
- */
-struct irq_handler {
- int (*handler)(int, void *);
- unsigned long flags;
- void *dev_id;
- const char *devname;
-};
-
-struct irq_controller {
- const char *name;
- spinlock_t lock;
- int (*startup)(unsigned int irq);
- void (*shutdown)(unsigned int irq);
- void (*enable)(unsigned int irq);
- void (*disable)(unsigned int irq);
-};
-
-extern int m68k_irq_startup(unsigned int);
-extern void m68k_irq_shutdown(unsigned int);
-
-/*
- * This function returns a new irq_node_t
- */
-extern irq_node_t *new_irq_node(void);
-
-extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
-extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
- void (*handler)(unsigned int, struct pt_regs *));
-extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
-
-asmlinkage void m68k_handle_int(unsigned int);
-asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
-
-#endif /* _M68K_IRQ_H_ */
diff --git a/arch/m68k/include/asm/irq_no.h b/arch/m68k/include/asm/irq_no.h
deleted file mode 100644
index 9373c31ac87d..000000000000
--- a/arch/m68k/include/asm/irq_no.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _M68KNOMMU_IRQ_H_
-#define _M68KNOMMU_IRQ_H_
-
-#ifdef CONFIG_COLDFIRE
-/*
- * On the ColdFire we keep track of all vectors. That way drivers
- * can register whatever vector number they wish, and we can deal
- * with it.
- */
-#define SYS_IRQS 256
-#define NR_IRQS SYS_IRQS
-
-#else
-
-/*
- * # of m68k interrupts
- */
-#define SYS_IRQS 8
-#define NR_IRQS (24 + SYS_IRQS)
-
-#endif /* CONFIG_COLDFIRE */
-
-
-#define irq_canonicalize(irq) (irq)
-
-#endif /* _M68KNOMMU_IRQ_H_ */
diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h
index 49d016e6391a..7d76b8747e35 100644
--- a/arch/m68k/include/asm/m520xsim.h
+++ b/arch/m68k/include/asm/m520xsim.h
@@ -11,9 +11,8 @@
#define m520xsim_h
/****************************************************************************/
-
/*
- * Define the 5282 SIM register set addresses.
+ * Define the 520x SIM register set addresses.
*/
#define MCFICM_INTC0 0x48000 /* Base for Interrupt Ctrl 0 */
#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */
@@ -22,8 +21,22 @@
#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */
#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */
#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */
+#define MCFINTC_SIMR 0x1c /* Set interrupt mask 0-63 */
+#define MCFINTC_CIMR 0x1d /* Clear interrupt mask 0-63 */
#define MCFINTC_ICR0 0x40 /* Base ICR register */
+/*
+ * The common interrupt controller code just wants to know the absolute
+ * address to the SIMR and CIMR registers (not offsets into IPSBAR).
+ * The 520x family only has a single INTC unit.
+ */
+#define MCFINTC0_SIMR (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_SIMR)
+#define MCFINTC0_CIMR (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_CIMR)
+#define MCFINTC0_ICR0 (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0)
+#define MCFINTC1_SIMR (0)
+#define MCFINTC1_CIMR (0)
+#define MCFINTC1_ICR0 (0)
+
#define MCFINT_VECBASE 64
#define MCFINT_UART0 26 /* Interrupt number for UART0 */
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
@@ -55,9 +68,14 @@
#define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2 (0x02)
#define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04)
-#define ICR_INTRCONF 0x05
-#define MCFPIT_IMR MCFINTC_IMRL
-#define MCFPIT_IMR_IBIT (1 << MCFINT_PIT1)
+/*
+ * Reset Controll Unit.
+ */
+#define MCF_RCR 0xFC0A0000
+#define MCF_RSR 0xFC0A0001
+
+#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
+#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
/****************************************************************************/
#endif /* m520xsim_h */
diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h
index bf397313e93f..55183b5df1b8 100644
--- a/arch/m68k/include/asm/m523xsim.h
+++ b/arch/m68k/include/asm/m523xsim.h
@@ -41,5 +41,14 @@
#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */
#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */
+/*
+ * Reset Controll Unit (relative to IPSBAR).
+ */
+#define MCF_RCR 0x110000
+#define MCF_RSR 0x110001
+
+#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
+#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
+
/****************************************************************************/
#endif /* m523xsim_h */
diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h
index 1f63ab3fb3e6..95f4f8ee8f7c 100644
--- a/arch/m68k/include/asm/m527xsim.h
+++ b/arch/m68k/include/asm/m527xsim.h
@@ -70,5 +70,14 @@
#define UART2_ENABLE_MASK 0x3f00
#endif
+/*
+ * Reset Controll Unit (relative to IPSBAR).
+ */
+#define MCF_RCR 0x110000
+#define MCF_RSR 0x110001
+
+#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
+#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
+
/****************************************************************************/
#endif /* m527xsim_h */
diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h
index 28bf783a5d6d..d79c49f8134a 100644
--- a/arch/m68k/include/asm/m528xsim.h
+++ b/arch/m68k/include/asm/m528xsim.h
@@ -56,6 +56,14 @@
#define MCF5282_INTC0_ICR17 (volatile u8 *) (MCF_IPSBAR + 0x0C51)
+/*
+ * Reset Control Unit (relative to IPSBAR).
+ */
+#define MCF_RCR 0x110000
+#define MCF_RSR 0x110001
+
+#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
+#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
/*********************************************************************
*
diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h
index ce603451b55e..d563b6bcc738 100644
--- a/arch/m68k/include/asm/m532xsim.h
+++ b/arch/m68k/include/asm/m532xsim.h
@@ -56,49 +56,18 @@
#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */
-#define MCFSIM_IMR_MASKALL 0xFFFFFFFF /* All SIM intr sources */
-
-#define MCFSIM_IMR_SIMR0 0xFC04801C
-#define MCFSIM_IMR_SIMR1 0xFC04C01C
-#define MCFSIM_IMR_CIMR0 0xFC04801D
-#define MCFSIM_IMR_CIMR1 0xFC04C01D
+#define MCFINTC0_SIMR 0xFC04801C
+#define MCFINTC0_CIMR 0xFC04801D
+#define MCFINTC0_ICR0 0xFC048040
+#define MCFINTC1_SIMR 0xFC04C01C
+#define MCFINTC1_CIMR 0xFC04C01D
+#define MCFINTC1_ICR0 0xFC04C040
#define MCFSIM_ICR_TIMER1 (0xFC048040+32)
#define MCFSIM_ICR_TIMER2 (0xFC048040+33)
/*
- * Macro to set IMR register. It is 32 bits on the 5307.
- */
-#define mcf_getimr() \
- *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
-
-#define mcf_setimr(imr) \
- *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
-
-#define mcf_getipr() \
- *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
-
-#define mcf_getiprl() \
- *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRL))
-
-#define mcf_getiprh() \
- *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRH))
-
-
-#define mcf_enable_irq0(irq) \
- *((volatile unsigned char*) (MCFSIM_IMR_CIMR0)) = (irq);
-
-#define mcf_enable_irq1(irq) \
- *((volatile unsigned char*) (MCFSIM_IMR_CIMR1)) = (irq);
-
-#define mcf_disable_irq0(irq) \
- *((volatile unsigned char*) (MCFSIM_IMR_SIMR0)) = (irq);
-
-#define mcf_disable_irq1(irq) \
- *((volatile unsigned char*) (MCFSIM_IMR_SIMR1)) = (irq);
-
-/*
* Define the Cache register flags.
*/
#define CACR_EC (1<<31)
@@ -127,6 +96,18 @@
/*********************************************************************
*
+ * Reset Controller Module
+ *
+ *********************************************************************/
+
+#define MCF_RCR 0xFC0A0000
+#define MCF_RSR 0xFC0A0001
+
+#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
+#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
+
+/*********************************************************************
+ *
* Inter-IC (I2C) Module
*
*********************************************************************/
diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h
index da3f2ceff3a4..b90425fb50fe 100644
--- a/arch/m68k/include/asm/mcfsim.h
+++ b/arch/m68k/include/asm/mcfsim.h
@@ -101,20 +101,6 @@
#endif
-/*
- * PIT interrupt settings, if not found in mXXXXsim.h file.
- */
-#ifndef ICR_INTRCONF
-#define ICR_INTRCONF 0x2b /* PIT1 level 5, priority 3 */
-#endif
-#ifndef MCFPIT_IMR
-#define MCFPIT_IMR MCFINTC_IMRH
-#endif
-#ifndef MCFPIT_IMR_IBIT
-#define MCFPIT_IMR_IBIT (1 << (MCFINT_PIT1 - 32))
-#endif
-
-
#ifndef __ASSEMBLY__
/*
* Definition for the interrupt auto-vectoring support.
diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h
index fc3f2c22f2b8..74fd674b15ad 100644
--- a/arch/m68k/include/asm/processor.h
+++ b/arch/m68k/include/asm/processor.h
@@ -1,5 +1,170 @@
-#ifdef __uClinux__
-#include "processor_no.h"
+/*
+ * include/asm-m68k/processor.h
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#ifndef __ASM_M68K_PROCESSOR_H
+#define __ASM_M68K_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/thread_info.h>
+#include <asm/segment.h>
+#include <asm/fpu.h>
+#include <asm/ptrace.h>
+
+static inline unsigned long rdusp(void)
+{
+#ifdef CONFIG_COLDFIRE
+ extern unsigned int sw_usp;
+ return sw_usp;
#else
-#include "processor_mm.h"
+ unsigned long usp;
+ __asm__ __volatile__("move %/usp,%0" : "=a" (usp));
+ return usp;
+#endif
+}
+
+static inline void wrusp(unsigned long usp)
+{
+#ifdef CONFIG_COLDFIRE
+ extern unsigned int sw_usp;
+ sw_usp = usp;
+#else
+ __asm__ __volatile__("move %0,%/usp" : : "a" (usp));
+#endif
+}
+
+/*
+ * User space process size: 3.75GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#ifndef CONFIG_SUN3
+#define TASK_SIZE (0xF0000000UL)
+#else
+#define TASK_SIZE (0x0E000000UL)
+#endif
+
+#ifdef __KERNEL__
+#define STACK_TOP TASK_SIZE
+#define STACK_TOP_MAX STACK_TOP
+#endif
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+#define TASK_UNMAPPED_BASE 0xC0000000UL
+#else
+#define TASK_UNMAPPED_BASE 0x0A000000UL
+#endif
+#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
+#else
+#define TASK_UNMAPPED_BASE 0
+#endif
+
+struct thread_struct {
+ unsigned long ksp; /* kernel stack pointer */
+ unsigned long usp; /* user stack pointer */
+ unsigned short sr; /* saved status register */
+ unsigned short fs; /* saved fs (sfc, dfc) */
+ unsigned long crp[2]; /* cpu root pointer */
+ unsigned long esp0; /* points to SR of stack frame */
+ unsigned long faddr; /* info about last fault */
+ int signo, code;
+ unsigned long fp[8*3];
+ unsigned long fpcntl[3]; /* fp control regs */
+ unsigned char fpstate[FPSTATESIZE]; /* floating point state */
+ struct thread_info info;
+};
+
+#define INIT_THREAD { \
+ .ksp = sizeof(init_stack) + (unsigned long) init_stack, \
+ .sr = PS_S, \
+ .fs = __KERNEL_DS, \
+ .info = INIT_THREAD_INFO(init_task), \
+}
+
+#ifdef CONFIG_MMU
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+static inline void start_thread(struct pt_regs * regs, unsigned long pc,
+ unsigned long usp)
+{
+ /* reads from user space */
+ set_fs(USER_DS);
+
+ regs->pc = pc;
+ regs->sr &= ~0x2000;
+ wrusp(usp);
+}
+
+#else
+
+/*
+ * Coldfire stacks need to be re-aligned on trap exit, conventional
+ * 68k can handle this case cleanly.
+ */
+#ifdef CONFIG_COLDFIRE
+#define reformat(_regs) do { (_regs)->format = 0x4; } while(0)
+#else
+#define reformat(_regs) do { } while (0)
+#endif
+
+#define start_thread(_regs, _pc, _usp) \
+do { \
+ set_fs(USER_DS); /* reads from user space */ \
+ (_regs)->pc = (_pc); \
+ ((struct switch_stack *)(_regs))[-1].a6 = 0; \
+ reformat(_regs); \
+ if (current->mm) \
+ (_regs)->d5 = current->mm->start_data; \
+ (_regs)->sr &= ~0x2000; \
+ wrusp(_usp); \
+} while(0)
+
+#endif
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk) \
+ ({ \
+ unsigned long eip = 0; \
+ if ((tsk)->thread.esp0 > PAGE_SIZE && \
+ (virt_addr_valid((tsk)->thread.esp0))) \
+ eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
+ eip; })
+#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#define cpu_relax() barrier()
+
#endif
diff --git a/arch/m68k/include/asm/processor_mm.h b/arch/m68k/include/asm/processor_mm.h
deleted file mode 100644
index 1f61ef53f0e0..000000000000
--- a/arch/m68k/include/asm/processor_mm.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * include/asm-m68k/processor.h
- *
- * Copyright (C) 1995 Hamish Macdonald
- */
-
-#ifndef __ASM_M68K_PROCESSOR_H
-#define __ASM_M68K_PROCESSOR_H
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
-#include <linux/thread_info.h>
-#include <asm/segment.h>
-#include <asm/fpu.h>
-#include <asm/ptrace.h>
-
-static inline unsigned long rdusp(void)
-{
- unsigned long usp;
-
- __asm__ __volatile__("move %/usp,%0" : "=a" (usp));
- return usp;
-}
-
-static inline void wrusp(unsigned long usp)
-{
- __asm__ __volatile__("move %0,%/usp" : : "a" (usp));
-}
-
-/*
- * User space process size: 3.75GB. This is hardcoded into a few places,
- * so don't change it unless you know what you are doing.
- */
-#ifndef CONFIG_SUN3
-#define TASK_SIZE (0xF0000000UL)
-#else
-#define TASK_SIZE (0x0E000000UL)
-#endif
-
-#ifdef __KERNEL__
-#define STACK_TOP TASK_SIZE
-#define STACK_TOP_MAX STACK_TOP
-#endif
-
-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#ifndef CONFIG_SUN3
-#define TASK_UNMAPPED_BASE 0xC0000000UL
-#else
-#define TASK_UNMAPPED_BASE 0x0A000000UL
-#endif
-#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
-
-struct thread_struct {
- unsigned long ksp; /* kernel stack pointer */
- unsigned long usp; /* user stack pointer */
- unsigned short sr; /* saved status register */
- unsigned short fs; /* saved fs (sfc, dfc) */
- unsigned long crp[2]; /* cpu root pointer */
- unsigned long esp0; /* points to SR of stack frame */
- unsigned long faddr; /* info about last fault */
- int signo, code;
- unsigned long fp[8*3];
- unsigned long fpcntl[3]; /* fp control regs */
- unsigned char fpstate[FPSTATESIZE]; /* floating point state */
- struct thread_info info;
-};
-
-#define INIT_THREAD { \
- .ksp = sizeof(init_stack) + (unsigned long) init_stack, \
- .sr = PS_S, \
- .fs = __KERNEL_DS, \
- .info = INIT_THREAD_INFO(init_task), \
-}
-
-/*
- * Do necessary setup to start up a newly executed thread.
- */
-static inline void start_thread(struct pt_regs * regs, unsigned long pc,
- unsigned long usp)
-{
- /* reads from user space */
- set_fs(USER_DS);
-
- regs->pc = pc;
- regs->sr &= ~0x2000;
- wrusp(usp);
-}
-
-/* Forward declaration, a strange C thing */
-struct task_struct;
-
-/* Free all resources held by a thread. */
-static inline void release_thread(struct task_struct *dead_task)
-{
-}
-
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk) do { } while (0)
-
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
-/*
- * Free current thread data structures etc..
- */
-static inline void exit_thread(void)
-{
-}
-
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
-unsigned long get_wchan(struct task_struct *p);
-
-#define KSTK_EIP(tsk) \
- ({ \
- unsigned long eip = 0; \
- if ((tsk)->thread.esp0 > PAGE_SIZE && \
- (virt_addr_valid((tsk)->thread.esp0))) \
- eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
- eip; })
-#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
-
-#define cpu_relax() barrier()
-
-#endif
diff --git a/arch/m68k/include/asm/processor_no.h b/arch/m68k/include/asm/processor_no.h
deleted file mode 100644
index 91cba18acdd3..000000000000
--- a/arch/m68k/include/asm/processor_no.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * include/asm-m68knommu/processor.h
- *
- * Copyright (C) 1995 Hamish Macdonald
- */
-
-#ifndef __ASM_M68K_PROCESSOR_H
-#define __ASM_M68K_PROCESSOR_H
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
-#include <linux/compiler.h>
-#include <linux/threads.h>
-#include <asm/types.h>
-#include <asm/segment.h>
-#include <asm/fpu.h>
-#include <asm/ptrace.h>
-#include <asm/current.h>
-
-static inline unsigned long rdusp(void)
-{
-#ifdef CONFIG_COLDFIRE
- extern unsigned int sw_usp;
- return(sw_usp);
-#else
- unsigned long usp;
- __asm__ __volatile__("move %/usp,%0" : "=a" (usp));
- return usp;
-#endif
-}
-
-static inline void wrusp(unsigned long usp)
-{
-#ifdef CONFIG_COLDFIRE
- extern unsigned int sw_usp;
- sw_usp = usp;
-#else
- __asm__ __volatile__("move %0,%/usp" : : "a" (usp));
-#endif
-}
-
-/*
- * User space process size: 3.75GB. This is hardcoded into a few places,
- * so don't change it unless you know what you are doing.
- */
-#define TASK_SIZE (0xF0000000UL)
-
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's. We won't be using it
- */
-#define TASK_UNMAPPED_BASE 0
-
-/*
- * if you change this structure, you must change the code and offsets
- * in m68k/machasm.S
- */
-
-struct thread_struct {
- unsigned long ksp; /* kernel stack pointer */
- unsigned long usp; /* user stack pointer */
- unsigned short sr; /* saved status register */
- unsigned short fs; /* saved fs (sfc, dfc) */
- unsigned long crp[2]; /* cpu root pointer */
- unsigned long esp0; /* points to SR of stack frame */
- unsigned long fp[8*3];
- unsigned long fpcntl[3]; /* fp control regs */
- unsigned char fpstate[FPSTATESIZE]; /* floating point state */
-};
-
-#define INIT_THREAD { \
- sizeof(init_stack) + (unsigned long) init_stack, 0, \
- PS_S, __KERNEL_DS, \
- {0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \
-}
-
-/*
- * Coldfire stacks need to be re-aligned on trap exit, conventional
- * 68k can handle this case cleanly.
- */
-#if defined(CONFIG_COLDFIRE)
-#define reformat(_regs) do { (_regs)->format = 0x4; } while(0)
-#else
-#define reformat(_regs) do { } while (0)
-#endif
-
-/*
- * Do necessary setup to start up a newly executed thread.
- *
- * pass the data segment into user programs if it exists,
- * it can't hurt anything as far as I can tell
- */
-#define start_thread(_regs, _pc, _usp) \
-do { \
- set_fs(USER_DS); /* reads from user space */ \
- (_regs)->pc = (_pc); \
- ((struct switch_stack *)(_regs))[-1].a6 = 0; \
- reformat(_regs); \
- if (current->mm) \
- (_regs)->d5 = current->mm->start_data; \
- (_regs)->sr &= ~0x2000; \
- wrusp(_usp); \
-} while(0)
-
-/* Forward declaration, a strange C thing */
-struct task_struct;
-
-/* Free all resources held by a thread. */
-static inline void release_thread(struct task_struct *dead_task)
-{
-}
-
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk) do { } while (0)
-
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
-/*
- * Free current thread data structures etc..
- */
-static inline void exit_thread(void)
-{
-}
-
-unsigned long thread_saved_pc(struct task_struct *tsk);
-unsigned long get_wchan(struct task_struct *p);
-
-#define KSTK_EIP(tsk) \
- ({ \
- unsigned long eip = 0; \
- if ((tsk)->thread.esp0 > PAGE_SIZE && \
- (virt_addr_valid((tsk)->thread.esp0))) \
- eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
- eip; })
-#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
-
-#define cpu_relax() barrier()
-
-#endif
diff --git a/arch/m68k/include/asm/system_no.h b/arch/m68k/include/asm/system_no.h
index 4496c0aa8379..3c0718d74398 100644
--- a/arch/m68k/include/asm/system_no.h
+++ b/arch/m68k/include/asm/system_no.h
@@ -203,113 +203,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
#include <asm-generic/cmpxchg.h>
#endif
-#if defined( CONFIG_M68328 ) || defined( CONFIG_M68EZ328 ) || \
- defined (CONFIG_M68360) || defined( CONFIG_M68VZ328 )
-#define HARD_RESET_NOW() ({ \
- local_irq_disable(); \
- asm(" \
- moveal #0x10c00000, %a0; \
- moveb #0, 0xFFFFF300; \
- moveal 0(%a0), %sp; \
- moveal 4(%a0), %a0; \
- jmp (%a0); \
- "); \
-})
-#endif
-
-#ifdef CONFIG_COLDFIRE
-#if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
-/*
- * Need to account for broken early mask of 5272 silicon. So don't
- * jump through the original start address. Jump strait into the
- * known start of the FLASH code.
- */
-#define HARD_RESET_NOW() ({ \
- asm(" \
- movew #0x2700, %sr; \
- jmp 0xf0000400; \
- "); \
-})
-#elif defined(CONFIG_NETtel) || \
- defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
-#define HARD_RESET_NOW() ({ \
- asm(" \
- movew #0x2700, %sr; \
- moveal #0x10000044, %a0; \
- movel #0xffffffff, (%a0); \
- moveal #0x10000001, %a0; \
- moveb #0x00, (%a0); \
- moveal #0xf0000004, %a0; \
- moveal (%a0), %a0; \
- jmp (%a0); \
- "); \
-})
-#elif defined(CONFIG_M5272)
-/*
- * Retrieve the boot address in flash using CSBR0 and CSOR0
- * find the reset vector at flash_address + 4 (e.g. 0x400)
- * remap it in the flash's current location (e.g. 0xf0000400)
- * and jump there.
- */
-#define HARD_RESET_NOW() ({ \
- asm(" \
- movew #0x2700, %%sr; \
- move.l %0+0x40,%%d0; \
- and.l %0+0x44,%%d0; \
- andi.l #0xfffff000,%%d0; \
- mov.l %%d0,%%a0; \
- or.l 4(%%a0),%%d0; \
- mov.l %%d0,%%a0; \
- jmp (%%a0);" \
- : /* No output */ \
- : "o" (*(char *)MCF_MBAR) ); \
-})
-#elif defined(CONFIG_M528x)
-/*
- * The MCF528x has a bit (SOFTRST) in memory (Reset Control Register RCR),
- * that when set, resets the MCF528x.
- */
-#define HARD_RESET_NOW() \
-({ \
- unsigned char volatile *reset; \
- asm("move.w #0x2700, %sr"); \
- reset = ((volatile unsigned char *)(MCF_IPSBAR + 0x110000)); \
- while(1) \
- *reset |= (0x01 << 7);\
-})
-#elif defined(CONFIG_M523x)
-#define HARD_RESET_NOW() ({ \
- asm(" \
- movew #0x2700, %sr; \
- movel #0x01000000, %sp; \
- moveal #0x40110000, %a0; \
- moveb #0x80, (%a0); \
- "); \
-})
-#elif defined(CONFIG_M520x)
- /*
- * The MCF5208 has a bit (SOFTRST) in memory (Reset Control Register
- * RCR), that when set, resets the MCF5208.
- */
-#define HARD_RESET_NOW() \
-({ \
- unsigned char volatile *reset; \
- asm("move.w #0x2700, %sr"); \
- reset = ((volatile unsigned char *)(MCF_IPSBAR + 0xA0000)); \
- while(1) \
- *reset |= 0x80; \
-})
-#else
-#define HARD_RESET_NOW() ({ \
- asm(" \
- movew #0x2700, %sr; \
- moveal #0x4, %a0; \
- moveal (%a0), %a0; \
- jmp (%a0); \
- "); \
-})
-#endif
-#endif
#define arch_align_stack(x) (x)
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S
index f4782d2dce8f..f56faa5c9cd9 100644
--- a/arch/m68knommu/kernel/entry.S
+++ b/arch/m68knommu/kernel/entry.S
@@ -26,7 +26,6 @@
#include <linux/sys.h>
#include <linux/linkage.h>
-#include <asm/thread_info.h>
#include <asm/errno.h>
#include <asm/setup.h>
#include <asm/segment.h>
diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c
index 56e0f4c55a67..3e56f60882b5 100644
--- a/arch/m68knommu/kernel/irq.c
+++ b/arch/m68knommu/kernel/irq.c
@@ -34,27 +34,6 @@ void ack_bad_irq(unsigned int irq)
printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq);
}
-static struct irq_chip m_irq_chip = {
- .name = "M68K-INTC",
- .enable = enable_vector,
- .disable = disable_vector,
- .ack = ack_vector,
-};
-
-void __init init_IRQ(void)
-{
- int irq;
-
- init_vectors();
-
- for (irq = 0; (irq < NR_IRQS); irq++) {
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = NULL;
- irq_desc[irq].depth = 1;
- irq_desc[irq].chip = &m_irq_chip;
- }
-}
-
int show_interrupts(struct seq_file *p, void *v)
{
struct irqaction *ap;
diff --git a/arch/m68knommu/lib/checksum.c b/arch/m68knommu/lib/checksum.c
index 269d83bfbbe1..8bf012aec81c 100644
--- a/arch/m68knommu/lib/checksum.c
+++ b/arch/m68knommu/lib/checksum.c
@@ -127,15 +127,6 @@ __wsum csum_partial(const void *buff, int len, __wsum sum)
EXPORT_SYMBOL(csum_partial);
/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-__sum16 ip_compute_csum(const void *buff, int len)
-{
- return (__force __sum16)~do_csum(buff,len);
-}
-
-/*
* copy from fs while checksumming, otherwise like csum_partial
*/
diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c
index 53a5920c2b71..f6f79874e9af 100644
--- a/arch/m68knommu/platform/5206/config.c
+++ b/arch/m68knommu/platform/5206/config.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
@@ -21,10 +20,6 @@
/***************************************************************************/
-void coldfire_reset(void);
-
-/***************************************************************************/
-
static struct mcf_platform_uart m5206_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE1,
@@ -109,10 +104,21 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
/***************************************************************************/
+void m5206_cpu_reset(void)
+{
+ local_irq_disable();
+ /* Set watchdog to soft reset, and enabled */
+ __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
+ for (;;)
+ /* wait for watchdog to timeout */;
+}
+
+/***************************************************************************/
+
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
- mach_reset = coldfire_reset;
+ mach_reset = m5206_cpu_reset;
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c
index db902540bf2c..65887799db81 100644
--- a/arch/m68knommu/platform/5206e/config.c
+++ b/arch/m68knommu/platform/5206e/config.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
@@ -21,10 +20,6 @@
/***************************************************************************/
-void coldfire_reset(void);
-
-/***************************************************************************/
-
static struct mcf_platform_uart m5206e_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE1,
@@ -109,6 +104,17 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
/***************************************************************************/
+void m5206e_cpu_reset(void)
+{
+ local_irq_disable();
+ /* Set watchdog to soft reset, and enabled */
+ __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
+ for (;;)
+ /* wait for watchdog to timeout */;
+}
+
+/***************************************************************************/
+
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
@@ -119,7 +125,7 @@ void __init config_BSP(char *commandp, int size)
commandp[size-1] = 0;
#endif /* CONFIG_NETtel */
- mach_reset = coldfire_reset;
+ mach_reset = m5206e_cpu_reset;
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c
index 855fc6a79d72..92614de42cd3 100644
--- a/arch/m68knommu/platform/520x/config.c
+++ b/arch/m68knommu/platform/520x/config.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
@@ -23,10 +22,6 @@
/***************************************************************************/
-void coldfire_reset(void);
-
-/***************************************************************************/
-
static struct mcf_platform_uart m520x_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE1,
@@ -86,20 +81,11 @@ static struct platform_device *m520x_devices[] __initdata = {
/***************************************************************************/
-#define INTC0 (MCF_MBAR + MCFICM_INTC0)
-
static void __init m520x_uart_init_line(int line, int irq)
{
- u32 imr;
u16 par;
u8 par2;
- writeb(0x03, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
-
- imr = readl(INTC0 + MCFINTC_IMRL);
- imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
- writel(imr, INTC0 + MCFINTC_IMRL);
-
switch (line) {
case 0:
par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
@@ -136,18 +122,8 @@ static void __init m520x_uarts_init(void)
static void __init m520x_fec_init(void)
{
- u32 imr;
u8 v;
- /* Unmask FEC interrupts at ColdFire interrupt controller */
- writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 36);
- writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 40);
- writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 42);
-
- imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
- imr &= ~0x0001FFF0;
- writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-
/* Set multi-function pins to ethernet mode */
v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FEC);
writeb(v | 0xf0, MCF_IPSBAR + MCF_GPIO_PAR_FEC);
@@ -158,20 +134,17 @@ static void __init m520x_fec_init(void)
/***************************************************************************/
-/*
- * Program the vector to be an auto-vectored.
- */
-
-void mcf_autovector(unsigned int vec)
+static void m520x_cpu_reset(void)
{
- /* Everything is auto-vectored on the 520x devices */
+ local_irq_disable();
+ __raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
}
/***************************************************************************/
void __init config_BSP(char *commandp, int size)
{
- mach_reset = coldfire_reset;
+ mach_reset = m520x_cpu_reset;
m520x_uarts_init();
m520x_fec_init();
}
diff --git a/arch/m68knommu/platform/523x/config.c b/arch/m68knommu/platform/523x/config.c
index 74133f27b30c..00f08d2e43b0 100644
--- a/arch/m68knommu/platform/523x/config.c
+++ b/arch/m68knommu/platform/523x/config.c
@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
@@ -24,10 +23,6 @@
/***************************************************************************/
-void coldfire_reset(void);
-
-/***************************************************************************/
-
static struct mcf_platform_uart m523x_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE1,
@@ -87,73 +82,17 @@ static struct platform_device *m523x_devices[] __initdata = {
/***************************************************************************/
-#define INTC0 (MCF_MBAR + MCFICM_INTC0)
-
-static void __init m523x_uart_init_line(int line, int irq)
-{
- u32 imr;
-
- if ((line < 0) || (line > 2))
- return;
-
- writeb(0x30+line, (INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line));
-
- imr = readl(INTC0 + MCFINTC_IMRL);
- imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
- writel(imr, INTC0 + MCFINTC_IMRL);
-}
-
-static void __init m523x_uarts_init(void)
-{
- const int nrlines = ARRAY_SIZE(m523x_uart_platform);
- int line;
-
- for (line = 0; (line < nrlines); line++)
- m523x_uart_init_line(line, m523x_uart_platform[line].irq);
-}
-
-/***************************************************************************/
-
-static void __init m523x_fec_init(void)
-{
- u32 imr;
-
- /* Unmask FEC interrupts at ColdFire interrupt controller */
- writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
- writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
- writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
-
- imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
- imr &= ~0xf;
- writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
- imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
- imr &= ~0xff800001;
- writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
-}
-
-/***************************************************************************/
-
-void mcf_disableall(void)
-{
- *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
- *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
-}
-
-/***************************************************************************/
-
-void mcf_autovector(unsigned int vec)
+static void m523x_cpu_reset(void)
{
- /* Everything is auto-vectored on the 523x */
+ local_irq_disable();
+ __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
}
/***************************************************************************/
void __init config_BSP(char *commandp, int size)
{
- mcf_disableall();
- mach_reset = coldfire_reset;
- m523x_uarts_init();
- m523x_fec_init();
+ mach_reset = m523x_cpu_reset;
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c
index 9eab19d01eb1..93d998825925 100644
--- a/arch/m68knommu/platform/5249/config.c
+++ b/arch/m68knommu/platform/5249/config.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
@@ -20,10 +19,6 @@
/***************************************************************************/
-void coldfire_reset(void);
-
-/***************************************************************************/
-
static struct mcf_platform_uart m5249_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE1,
@@ -106,10 +101,21 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
/***************************************************************************/
+void m5249_cpu_reset(void)
+{
+ local_irq_disable();
+ /* Set watchdog to soft reset, and enabled */
+ __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
+ for (;;)
+ /* wait for watchdog to timeout */;
+}
+
+/***************************************************************************/
+
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
- mach_reset = coldfire_reset;
+ mach_reset = m5249_cpu_reset;
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c
index e049245f4092..5f95fcde05fd 100644
--- a/arch/m68knommu/platform/5272/config.c
+++ b/arch/m68knommu/platform/5272/config.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
@@ -21,8 +20,6 @@
/***************************************************************************/
-void coldfire_reset(void);
-
extern unsigned int mcf_timervector;
extern unsigned int mcf_profilevector;
extern unsigned int mcf_timerlevel;
@@ -170,6 +167,19 @@ void mcf_settimericr(int timer, int level)
/***************************************************************************/
+static void m5272_cpu_reset(void)
+{
+ local_irq_disable();
+ /* Set watchdog to reset, and enabled */
+ __raw_writew(0, MCF_MBAR + MCFSIM_WIRR);
+ __raw_writew(1, MCF_MBAR + MCFSIM_WRRR);
+ __raw_writew(0, MCF_MBAR + MCFSIM_WCR);
+ for (;;)
+ /* wait for watchdog to timeout */;
+}
+
+/***************************************************************************/
+
void __init config_BSP(char *commandp, int size)
{
#if defined (CONFIG_MOD5272)
@@ -194,7 +204,7 @@ void __init config_BSP(char *commandp, int size)
mcf_timervector = 69;
mcf_profilevector = 70;
- mach_reset = coldfire_reset;
+ mach_reset = m5272_cpu_reset;
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/527x/config.c b/arch/m68knommu/platform/527x/config.c
index 428b15922ef5..fa51be172830 100644
--- a/arch/m68knommu/platform/527x/config.c
+++ b/arch/m68knommu/platform/527x/config.c
@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
@@ -24,10 +23,6 @@
/***************************************************************************/
-void coldfire_reset(void);
-
-/***************************************************************************/
-
static struct mcf_platform_uart m527x_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE1,
@@ -121,23 +116,13 @@ static struct platform_device *m527x_devices[] __initdata = {
/***************************************************************************/
-#define INTC0 (MCF_MBAR + MCFICM_INTC0)
-
static void __init m527x_uart_init_line(int line, int irq)
{
u16 sepmask;
- u32 imr;
if ((line < 0) || (line > 2))
return;
- /* level 6, line based priority */
- writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
-
- imr = readl(INTC0 + MCFINTC_IMRL);
- imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
- writel(imr, INTC0 + MCFINTC_IMRL);
-
/*
* External Pin Mask Setting & Enable External Pin for Interface
*/
@@ -162,32 +147,11 @@ static void __init m527x_uarts_init(void)
/***************************************************************************/
-static void __init m527x_fec_irq_init(int nr)
-{
- unsigned long base;
- u32 imr;
-
- base = MCF_IPSBAR + (nr ? MCFICM_INTC1 : MCFICM_INTC0);
-
- writeb(0x28, base + MCFINTC_ICR0 + 23);
- writeb(0x27, base + MCFINTC_ICR0 + 27);
- writeb(0x26, base + MCFINTC_ICR0 + 29);
-
- imr = readl(base + MCFINTC_IMRH);
- imr &= ~0xf;
- writel(imr, base + MCFINTC_IMRH);
- imr = readl(base + MCFINTC_IMRL);
- imr &= ~0xff800001;
- writel(imr, base + MCFINTC_IMRL);
-}
-
static void __init m527x_fec_init(void)
{
u16 par;
u8 v;
- m527x_fec_irq_init(0);
-
/* Set multi-function pins to ethernet mode for fec0 */
#if defined(CONFIG_M5271)
v = readb(MCF_IPSBAR + 0x100047);
@@ -200,8 +164,6 @@ static void __init m527x_fec_init(void)
#endif
#ifdef CONFIG_FEC2
- m527x_fec_irq_init(1);
-
/* Set multi-function pins to ethernet mode for fec1 */
par = readw(MCF_IPSBAR + 0x100082);
writew(par | 0xa0, MCF_IPSBAR + 0x100082);
@@ -212,25 +174,17 @@ static void __init m527x_fec_init(void)
/***************************************************************************/
-void mcf_disableall(void)
-{
- *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
- *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
-}
-
-/***************************************************************************/
-
-void mcf_autovector(unsigned int vec)
+static void m527x_cpu_reset(void)
{
- /* Everything is auto-vectored on the 5272 */
+ local_irq_disable();
+ __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
}
/***************************************************************************/
void __init config_BSP(char *commandp, int size)
{
- mcf_disableall();
- mach_reset = coldfire_reset;
+ mach_reset = m527x_cpu_reset;
m527x_uarts_init();
m527x_fec_init();
}
diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c
index bee526f4d1af..6e608d1836f1 100644
--- a/arch/m68knommu/platform/528x/config.c
+++ b/arch/m68knommu/platform/528x/config.c
@@ -3,8 +3,8 @@
/*
* linux/arch/m68knommu/platform/528x/config.c
*
- * Sub-architcture dependant initialization code for the Motorola
- * 5280 and 5282 CPUs.
+ * Sub-architcture dependant initialization code for the Freescale
+ * 5280, 5281 and 5282 CPUs.
*
* Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
* Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
@@ -15,24 +15,13 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/flash.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
-#ifdef CONFIG_MTD_PARTITIONS
-#include <linux/mtd/partitions.h>
-#endif
-
-/***************************************************************************/
-
-void coldfire_reset(void);
-
/***************************************************************************/
static struct mcf_platform_uart m528x_uart_platform[] = {
@@ -95,23 +84,13 @@ static struct platform_device *m528x_devices[] __initdata = {
/***************************************************************************/
-#define INTC0 (MCF_MBAR + MCFICM_INTC0)
-
static void __init m528x_uart_init_line(int line, int irq)
{
u8 port;
- u32 imr;
if ((line < 0) || (line > 2))
return;
- /* level 6, line based priority */
- writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
-
- imr = readl(INTC0 + MCFINTC_IMRL);
- imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
- writel(imr, INTC0 + MCFINTC_IMRL);
-
/* make sure PUAPAR is set for UART0 and UART1 */
if (line < 2) {
port = readb(MCF_MBAR + MCF5282_GPIO_PUAPAR);
@@ -133,21 +112,8 @@ static void __init m528x_uarts_init(void)
static void __init m528x_fec_init(void)
{
- u32 imr;
u16 v16;
- /* Unmask FEC interrupts at ColdFire interrupt controller */
- writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
- writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
- writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
-
- imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
- imr &= ~0xf;
- writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
- imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
- imr &= ~0xff800001;
- writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
-
/* Set multi-function pins to ethernet mode for fec0 */
v16 = readw(MCF_IPSBAR + 0x100056);
writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
@@ -156,17 +122,10 @@ static void __init m528x_fec_init(void)
/***************************************************************************/
-void mcf_disableall(void)
-{
- *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
- *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
-}
-
-/***************************************************************************/
-
-void mcf_autovector(unsigned int vec)
+static void m528x_cpu_reset(void)
{
- /* Everything is auto-vectored on the 5272 */
+ local_irq_disable();
+ __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
}
/***************************************************************************/
@@ -200,8 +159,6 @@ void wildfiremod_halt(void)
void __init config_BSP(char *commandp, int size)
{
- mcf_disableall();
-
#ifdef CONFIG_WILDFIRE
mach_halt = wildfire_halt;
#endif
@@ -214,6 +171,7 @@ void __init config_BSP(char *commandp, int size)
static int __init init_BSP(void)
{
+ mach_reset = m528x_cpu_reset;
m528x_uarts_init();
m528x_fec_init();
platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c
index 44803bf70a6e..39da9e9ff674 100644
--- a/arch/m68knommu/platform/5307/config.c
+++ b/arch/m68knommu/platform/5307/config.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
@@ -22,8 +21,6 @@
/***************************************************************************/
-void coldfire_reset(void);
-
extern unsigned int mcf_timervector;
extern unsigned int mcf_profilevector;
extern unsigned int mcf_timerlevel;
@@ -119,6 +116,17 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
/***************************************************************************/
+void m5307_cpu_reset(void)
+{
+ local_irq_disable();
+ /* Set watchdog to soft reset, and enabled */
+ __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
+ for (;;)
+ /* wait for watchdog to timeout */;
+}
+
+/***************************************************************************/
+
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
@@ -134,7 +142,7 @@ void __init config_BSP(char *commandp, int size)
mcf_timerlevel = 6;
#endif
- mach_reset = coldfire_reset;
+ mach_reset = m5307_cpu_reset;
#ifdef CONFIG_BDM_DISABLE
/*
diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c
index 591f2f801134..47e4573c328e 100644
--- a/arch/m68knommu/platform/532x/config.c
+++ b/arch/m68knommu/platform/532x/config.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
@@ -31,8 +30,6 @@
/***************************************************************************/
-void coldfire_reset(void);
-
extern unsigned int mcf_timervector;
extern unsigned int mcf_profilevector;
extern unsigned int mcf_timerlevel;
@@ -100,18 +97,11 @@ static struct platform_device *m532x_devices[] __initdata = {
static void __init m532x_uart_init_line(int line, int irq)
{
if (line == 0) {
- MCF_INTC0_ICR26 = 0x3;
- MCF_INTC0_CIMR = 26;
/* GPIO initialization */
MCF_GPIO_PAR_UART |= 0x000F;
} else if (line == 1) {
- MCF_INTC0_ICR27 = 0x3;
- MCF_INTC0_CIMR = 27;
/* GPIO initialization */
MCF_GPIO_PAR_UART |= 0x0FF0;
- } else if (line == 2) {
- MCF_INTC0_ICR28 = 0x3;
- MCF_INTC0_CIMR = 28;
}
}
@@ -127,14 +117,6 @@ static void __init m532x_uarts_init(void)
static void __init m532x_fec_init(void)
{
- /* Unmask FEC interrupts at ColdFire interrupt controller */
- MCF_INTC0_ICR36 = 0x2;
- MCF_INTC0_ICR40 = 0x2;
- MCF_INTC0_ICR42 = 0x2;
-
- MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 |
- MCF_INTC_IMRH_INT_MASK40 | MCF_INTC_IMRH_INT_MASK42);
-
/* Set multi-function pins to ethernet mode for fec0 */
MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
@@ -146,28 +128,20 @@ static void __init m532x_fec_init(void)
void mcf_settimericr(unsigned int timer, unsigned int level)
{
- volatile unsigned char *icrp;
- unsigned int icr;
- unsigned char irq;
-
- if (timer <= 2) {
- switch (timer) {
- case 2: irq = 33; icr = MCFSIM_ICR_TIMER2; break;
- default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
- }
-
- icrp = (volatile unsigned char *) (icr);
- *icrp = level;
- mcf_enable_irq0(irq);
- }
}
/***************************************************************************/
-void __init config_BSP(char *commandp, int size)
+static void m532x_cpu_reset(void)
{
- mcf_setimr(MCFSIM_IMR_MASKALL);
+ local_irq_disable();
+ __raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
+}
+
+/***************************************************************************/
+void __init config_BSP(char *commandp, int size)
+{
#if !defined(CONFIG_BOOTPARAM)
/* Copy command line from FLASH to local buffer... */
memcpy(commandp, (char *) 0x4000, 4);
@@ -181,7 +155,7 @@ void __init config_BSP(char *commandp, int size)
mcf_timervector = 64+32;
mcf_profilevector = 64+33;
- mach_reset = coldfire_reset;
+ mach_reset = m532x_cpu_reset;
#ifdef CONFIG_BDM_DISABLE
/*
diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c
index 0ee8c1a200c8..b41d942bf8d0 100644
--- a/arch/m68knommu/platform/5407/config.c
+++ b/arch/m68knommu/platform/5407/config.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
@@ -21,8 +20,6 @@
/***************************************************************************/
-void coldfire_reset(void);
-
extern unsigned int mcf_timervector;
extern unsigned int mcf_profilevector;
extern unsigned int mcf_timerlevel;
@@ -110,6 +107,17 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
/***************************************************************************/
+void m5407_cpu_reset(void)
+{
+ local_irq_disable();
+ /* set watchdog to soft reset, and enabled */
+ __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
+ for (;;)
+ /* wait for watchdog to timeout */;
+}
+
+/***************************************************************************/
+
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
@@ -121,7 +129,7 @@ void __init config_BSP(char *commandp, int size)
mcf_timerlevel = 6;
#endif
- mach_reset = coldfire_reset;
+ mach_reset = m5407_cpu_reset;
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c
index 72e56d554f4f..dab623389a01 100644
--- a/arch/m68knommu/platform/68328/ints.c
+++ b/arch/m68knommu/platform/68328/ints.c
@@ -73,34 +73,6 @@ extern e_vector *_ramvec;
/* The number of spurious interrupts */
volatile unsigned int num_spurious;
-/*
- * This function should be called during kernel startup to initialize
- * the machine vector table.
- */
-void __init init_vectors(void)
-{
- int i;
-
- /* set up the vectors */
- for (i = 72; i < 256; ++i)
- _ramvec[i] = (e_vector) bad_interrupt;
-
- _ramvec[32] = system_call;
-
- _ramvec[65] = (e_vector) inthandler1;
- _ramvec[66] = (e_vector) inthandler2;
- _ramvec[67] = (e_vector) inthandler3;
- _ramvec[68] = (e_vector) inthandler4;
- _ramvec[69] = (e_vector) inthandler5;
- _ramvec[70] = (e_vector) inthandler6;
- _ramvec[71] = (e_vector) inthandler7;
-
- IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
-
- /* turn off all interrupts */
- IMR = ~0;
-}
-
/* The 68k family did not have a good way to determine the source
* of interrupts until later in the family. The EC000 core does
* not provide the vector number on the stack, we vector everything
@@ -163,18 +135,54 @@ void process_int(int vec, struct pt_regs *fp)
}
}
-void enable_vector(unsigned int irq)
+static void intc_irq_unmask(unsigned int irq)
{
IMR &= ~(1<<irq);
}
-void disable_vector(unsigned int irq)
+static void intc_irq_mask(unsigned int irq)
{
IMR |= (1<<irq);
}
-void ack_vector(unsigned int irq)
+static struct irq_chip intc_irq_chip = {
+ .name = "M68K-INTC",
+ .mask = intc_irq_mask,
+ .unmask = intc_irq_unmask,
+};
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the machine vector table.
+ */
+void __init init_IRQ(void)
{
- /* Nothing needed */
+ int i;
+
+ /* set up the vectors */
+ for (i = 72; i < 256; ++i)
+ _ramvec[i] = (e_vector) bad_interrupt;
+
+ _ramvec[32] = system_call;
+
+ _ramvec[65] = (e_vector) inthandler1;
+ _ramvec[66] = (e_vector) inthandler2;
+ _ramvec[67] = (e_vector) inthandler3;
+ _ramvec[68] = (e_vector) inthandler4;
+ _ramvec[69] = (e_vector) inthandler5;
+ _ramvec[70] = (e_vector) inthandler6;
+ _ramvec[71] = (e_vector) inthandler7;
+
+ IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+ /* turn off all interrupts */
+ IMR = ~0;
+
+ for (i = 0; (i < NR_IRQS); i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = NULL;
+ irq_desc[i].depth = 1;
+ irq_desc[i].chip = &intc_irq_chip;
+ }
}
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c
index c36781157e09..1143f77caca4 100644
--- a/arch/m68knommu/platform/68360/ints.c
+++ b/arch/m68knommu/platform/68360/ints.c
@@ -37,11 +37,33 @@ extern void *_ramvec[];
/* The number of spurious interrupts */
volatile unsigned int num_spurious;
+static void intc_irq_unmask(unsigned int irq)
+{
+ pquicc->intr_cimr |= (1 << irq);
+}
+
+static void intc_irq_mask(unsigned int irq)
+{
+ pquicc->intr_cimr &= ~(1 << irq);
+}
+
+static void intc_irq_ack(unsigned int irq)
+{
+ pquicc->intr_cisr = (1 << irq);
+}
+
+static struct irq_chip intc_irq_chip = {
+ .name = "M68K-INTC",
+ .mask = intc_irq_mask,
+ .unmask = intc_irq_unmask,
+ .ack = intc_irq_ack,
+};
+
/*
* This function should be called during kernel startup to initialize
* the vector table.
*/
-void init_vectors(void)
+void init_IRQ(void)
{
int i;
int vba = (CPM_VECTOR_BASE<<4);
@@ -109,20 +131,12 @@ void init_vectors(void)
/* turn off all CPM interrupts */
pquicc->intr_cimr = 0x00000000;
-}
-
-void enable_vector(unsigned int irq)
-{
- pquicc->intr_cimr |= (1 << irq);
-}
-void disable_vector(unsigned int irq)
-{
- pquicc->intr_cimr &= ~(1 << irq);
-}
-
-void ack_vector(unsigned int irq)
-{
- pquicc->intr_cisr = (1 << irq);
+ for (i = 0; (i < NR_IRQS); i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = NULL;
+ irq_desc[i].depth = 1;
+ irq_desc[i].chip = &intc_irq_chip;
+ }
}
diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile
index 1bcb9372353f..85be019f378b 100644
--- a/arch/m68knommu/platform/coldfire/Makefile
+++ b/arch/m68knommu/platform/coldfire/Makefile
@@ -15,16 +15,16 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-$(CONFIG_COLDFIRE) += clk.o dma.o entry.o vectors.o
-obj-$(CONFIG_M5206) += timers.o
-obj-$(CONFIG_M5206e) += timers.o
-obj-$(CONFIG_M520x) += pit.o
-obj-$(CONFIG_M523x) += pit.o dma_timer.o
-obj-$(CONFIG_M5249) += timers.o
-obj-$(CONFIG_M527x) += pit.o
-obj-$(CONFIG_M5272) += timers.o
-obj-$(CONFIG_M528x) += pit.o
-obj-$(CONFIG_M5307) += timers.o
-obj-$(CONFIG_M532x) += timers.o
-obj-$(CONFIG_M5407) += timers.o
+obj-$(CONFIG_M5206) += timers.o intc.o
+obj-$(CONFIG_M5206e) += timers.o intc.o
+obj-$(CONFIG_M520x) += pit.o intc-simr.o
+obj-$(CONFIG_M523x) += pit.o dma_timer.o intc-2.o
+obj-$(CONFIG_M5249) += timers.o intc.o
+obj-$(CONFIG_M527x) += pit.o intc-2.o
+obj-$(CONFIG_M5272) += timers.o intc.o
+obj-$(CONFIG_M528x) += pit.o intc-2.o
+obj-$(CONFIG_M5307) += timers.o intc.o
+obj-$(CONFIG_M532x) += timers.o intc-simr.o
+obj-$(CONFIG_M5407) += timers.o intc.o
extra-y := head.o
diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c
new file mode 100644
index 000000000000..5598c8b8661f
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/intc-2.c
@@ -0,0 +1,93 @@
+/*
+ * intc-1.c
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * 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/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/traps.h>
+
+/*
+ * Each vector needs a unique priority and level asscoiated with it.
+ * We don't really care so much what they are, we don't rely on the
+ * tranditional priority interrupt scheme of the m68k/ColdFire.
+ */
+static u8 intc_intpri = 0x36;
+
+static void intc_irq_mask(unsigned int irq)
+{
+ if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
+ unsigned long imraddr;
+ u32 val, imrbit;
+
+ irq -= MCFINT_VECBASE;
+ imraddr = MCF_IPSBAR;
+ imraddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
+ imraddr += (irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL;
+ imrbit = 0x1 << (irq & 0x1f);
+
+ val = __raw_readl(imraddr);
+ __raw_writel(val | imrbit, imraddr);
+ }
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+ if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
+ unsigned long intaddr, imraddr, icraddr;
+ u32 val, imrbit;
+
+ irq -= MCFINT_VECBASE;
+ intaddr = MCF_IPSBAR;
+ intaddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
+ imraddr = intaddr + ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
+ icraddr = intaddr + MCFINTC_ICR0 + (irq & 0x3f);
+ imrbit = 0x1 << (irq & 0x1f);
+
+ /* Don't set the "maskall" bit! */
+ if ((irq & 0x20) == 0)
+ imrbit |= 0x1;
+
+ if (__raw_readb(icraddr) == 0)
+ __raw_writeb(intc_intpri--, icraddr);
+
+ val = __raw_readl(imraddr);
+ __raw_writel(val & ~imrbit, imraddr);
+ }
+}
+
+static struct irq_chip intc_irq_chip = {
+ .name = "CF-INTC",
+ .mask = intc_irq_mask,
+ .unmask = intc_irq_unmask,
+};
+
+void __init init_IRQ(void)
+{
+ int irq;
+
+ init_vectors();
+
+ /* Mask all interrupt sources */
+ __raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+ __raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC1 + MCFINTC_IMRL);
+
+ for (irq = 0; (irq < NR_IRQS); irq++) {
+ irq_desc[irq].status = IRQ_DISABLED;
+ irq_desc[irq].action = NULL;
+ irq_desc[irq].depth = 1;
+ irq_desc[irq].chip = &intc_irq_chip;
+ }
+}
+
diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c
new file mode 100644
index 000000000000..1b01e79c2f63
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/intc-simr.c
@@ -0,0 +1,78 @@
+/*
+ * intc-simr.c
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * 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/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/traps.h>
+
+static void intc_irq_mask(unsigned int irq)
+{
+ if (irq >= MCFINT_VECBASE) {
+ if (irq < MCFINT_VECBASE + 64)
+ __raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_SIMR);
+ else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_SIMR)
+ __raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_SIMR);
+ }
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+ if (irq >= MCFINT_VECBASE) {
+ if (irq < MCFINT_VECBASE + 64)
+ __raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_CIMR);
+ else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_CIMR)
+ __raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_CIMR);
+ }
+}
+
+static int intc_irq_set_type(unsigned int irq, unsigned int type)
+{
+ if (irq >= MCFINT_VECBASE) {
+ if (irq < MCFINT_VECBASE + 64)
+ __raw_writeb(5, MCFINTC0_ICR0 + irq - MCFINT_VECBASE);
+ else if ((irq < MCFINT_VECBASE) && MCFINTC1_ICR0)
+ __raw_writeb(5, MCFINTC1_ICR0 + irq - MCFINT_VECBASE - 64);
+ }
+ return 0;
+}
+
+static struct irq_chip intc_irq_chip = {
+ .name = "CF-INTC",
+ .mask = intc_irq_mask,
+ .unmask = intc_irq_unmask,
+ .set_type = intc_irq_set_type,
+};
+
+void __init init_IRQ(void)
+{
+ int irq;
+
+ init_vectors();
+
+ /* Mask all interrupt sources */
+ __raw_writeb(0xff, MCFINTC0_SIMR);
+ if (MCFINTC1_SIMR)
+ __raw_writeb(0xff, MCFINTC1_SIMR);
+
+ for (irq = 0; (irq < NR_IRQS); irq++) {
+ irq_desc[irq].status = IRQ_DISABLED;
+ irq_desc[irq].action = NULL;
+ irq_desc[irq].depth = 1;
+ irq_desc[irq].chip = &intc_irq_chip;
+ intc_irq_set_type(irq, 0);
+ }
+}
+
diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c
new file mode 100644
index 000000000000..c81ab6e5cf26
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/intc.c
@@ -0,0 +1,55 @@
+/*
+ * intc.c
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * 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/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/traps.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+static void intc_irq_mask(unsigned int irq)
+{
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+}
+
+static int intc_irq_set_type(unsigned int irq, unsigned int type)
+{
+ return 0;
+}
+
+static struct irq_chip intc_irq_chip = {
+ .name = "CF-INTC",
+ .mask = intc_irq_mask,
+ .unmask = intc_irq_unmask,
+ .set_type = intc_irq_set_type,
+};
+
+void __init init_IRQ(void)
+{
+ int irq;
+
+ init_vectors();
+
+ for (irq = 0; (irq < NR_IRQS); irq++) {
+ irq_desc[irq].status = IRQ_DISABLED;
+ irq_desc[irq].action = NULL;
+ irq_desc[irq].depth = 1;
+ irq_desc[irq].chip = &intc_irq_chip;
+ intc_irq_set_type(irq, 0);
+ }
+}
+
diff --git a/arch/m68knommu/platform/coldfire/pit.c b/arch/m68knommu/platform/coldfire/pit.c
index 61b96211f8ff..d8720ee34510 100644
--- a/arch/m68knommu/platform/coldfire/pit.c
+++ b/arch/m68knommu/platform/coldfire/pit.c
@@ -32,7 +32,6 @@
*/
#define FREQ ((MCF_CLK / 2) / 64)
#define TA(a) (MCF_IPSBAR + MCFPIT_BASE1 + (a))
-#define INTC0 (MCF_IPSBAR + MCFICM_INTC0)
#define PIT_CYCLES_PER_JIFFY (FREQ / HZ)
static u32 pit_cnt;
@@ -154,8 +153,6 @@ static struct clocksource pit_clk = {
void hw_timer_init(void)
{
- u32 imr;
-
cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id());
cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32);
cf_pit_clockevent.max_delta_ns =
@@ -166,11 +163,6 @@ void hw_timer_init(void)
setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &pit_irq);
- __raw_writeb(ICR_INTRCONF, INTC0 + MCFINTC_ICR0 + MCFINT_PIT1);
- imr = __raw_readl(INTC0 + MCFPIT_IMR);
- imr &= ~MCFPIT_IMR_IBIT;
- __raw_writel(imr, INTC0 + MCFPIT_IMR);
-
pit_clk.mult = clocksource_hz2mult(FREQ, pit_clk.shift);
clocksource_register(&pit_clk);
}
diff --git a/arch/m68knommu/platform/coldfire/vectors.c b/arch/m68knommu/platform/coldfire/vectors.c
index 6cf894620234..a21d3f870b7a 100644
--- a/arch/m68knommu/platform/coldfire/vectors.c
+++ b/arch/m68knommu/platform/coldfire/vectors.c
@@ -1,7 +1,7 @@
/***************************************************************************/
/*
- * linux/arch/m68knommu/platform/5307/vectors.c
+ * linux/arch/m68knommu/platform/coldfire/vectors.c
*
* Copyright (C) 1999-2007, Greg Ungerer <gerg@snapgear.com>
*/
@@ -15,7 +15,6 @@
#include <asm/machdep.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
#include <asm/mcfwdebug.h>
/***************************************************************************/
@@ -79,27 +78,3 @@ void __init init_vectors(void)
}
/***************************************************************************/
-
-void enable_vector(unsigned int irq)
-{
- /* Currently no action on ColdFire */
-}
-
-void disable_vector(unsigned int irq)
-{
- /* Currently no action on ColdFire */
-}
-
-void ack_vector(unsigned int irq)
-{
- /* Currently no action on ColdFire */
-}
-
-/***************************************************************************/
-
-void coldfire_reset(void)
-{
- HARD_RESET_NOW();
-}
-
-/***************************************************************************/
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
index cfe44effdb77..450ca6bb828d 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-static.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c
@@ -14,8 +14,8 @@
#include <asm/cpuinfo.h>
#include <asm/pvr.h>
-const static char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY;
-const static char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
+static const char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY;
+static const char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
#define err_printk(x) \
early_printk("ERROR: Microblaze " x "- different for kernel and DTS\n");
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index ba0568c2cc1c..31905ff590b7 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -131,7 +131,7 @@ sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth)
ret = sys_shmctl(first, second, (struct shmid_ds *) ptr);
break;
}
- return -EINVAL;
+ return ret;
}
asmlinkage int sys_vfork(struct pt_regs *regs)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 998e5db8cc0f..db97aa101f5f 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -617,6 +617,8 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
select SYS_HAS_EARLY_PRINTK
select SYS_HAS_CPU_CAVIUM_OCTEON
select SWAP_IO_SPACE
+ select HW_HAS_PCI
+ select ARCH_SUPPORTS_MSI
help
This option supports all of the Octeon reference boards from Cavium
Networks. It builds a kernel that dynamically determines the Octeon
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index d6903c3f3d51..7c0528b0e34c 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -14,5 +14,9 @@ obj-y += dma-octeon.o flash_setup.o
obj-y += octeon-memcpy.o
obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_PCI) += pci-common.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_PCI) += pcie.o
+obj-$(CONFIG_PCI_MSI) += msi.o
EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index 01b1ef94b361..627c162a6159 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -13,20 +13,327 @@
*/
#include <linux/types.h>
#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/scatterlist.h>
+
+#include <linux/cache.h>
+#include <linux/io.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include <asm/octeon/cvmx-pci-defs.h>
#include <dma-coherence.h>
+#ifdef CONFIG_PCI
+#include "pci-common.h"
+#endif
+
+#define BAR2_PCI_ADDRESS 0x8000000000ul
+
+struct bar1_index_state {
+ int16_t ref_count; /* Number of PCI mappings using this index */
+ uint16_t address_bits; /* Upper bits of physical address. This is
+ shifted 22 bits */
+};
+
+#ifdef CONFIG_PCI
+static DEFINE_SPINLOCK(bar1_lock);
+static struct bar1_index_state bar1_state[32];
+#endif
+
dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size)
{
+#ifndef CONFIG_PCI
/* Without PCI/PCIe this function can be called for Octeon internal
devices such as USB. These devices all support 64bit addressing */
mb();
return virt_to_phys(ptr);
+#else
+ unsigned long flags;
+ uint64_t dma_mask;
+ int64_t start_index;
+ dma_addr_t result = -1;
+ uint64_t physical = virt_to_phys(ptr);
+ int64_t index;
+
+ mb();
+ /*
+ * Use the DMA masks to determine the allowed memory
+ * region. For us it doesn't limit the actual memory, just the
+ * address visible over PCI. Devices with limits need to use
+ * lower indexed Bar1 entries.
+ */
+ if (dev) {
+ dma_mask = dev->coherent_dma_mask;
+ if (dev->dma_mask)
+ dma_mask = *dev->dma_mask;
+ } else {
+ dma_mask = 0xfffffffful;
+ }
+
+ /*
+ * Platform devices, such as the internal USB, skip all
+ * translation and use Octeon physical addresses directly.
+ */
+ if (!dev || dev->bus == &platform_bus_type)
+ return physical;
+
+ switch (octeon_dma_bar_type) {
+ case OCTEON_DMA_BAR_TYPE_PCIE:
+ if (unlikely(physical < (16ul << 10)))
+ panic("dma_map_single: Not allowed to map first 16KB."
+ " It interferes with BAR0 special area\n");
+ else if ((physical + size >= (256ul << 20)) &&
+ (physical < (512ul << 20)))
+ panic("dma_map_single: Not allowed to map bootbus\n");
+ else if ((physical + size >= 0x400000000ull) &&
+ physical < 0x410000000ull)
+ panic("dma_map_single: "
+ "Attempt to map illegal memory address 0x%llx\n",
+ physical);
+ else if (physical >= 0x420000000ull)
+ panic("dma_map_single: "
+ "Attempt to map illegal memory address 0x%llx\n",
+ physical);
+ else if ((physical + size >=
+ (4ull<<30) - (OCTEON_PCI_BAR1_HOLE_SIZE<<20))
+ && physical < (4ull<<30))
+ pr_warning("dma_map_single: Warning: "
+ "Mapping memory address that might "
+ "conflict with devices 0x%llx-0x%llx\n",
+ physical, physical+size-1);
+ /* The 2nd 256MB is mapped at 256<<20 instead of 0x410000000 */
+ if ((physical >= 0x410000000ull) && physical < 0x420000000ull)
+ result = physical - 0x400000000ull;
+ else
+ result = physical;
+ if (((result+size-1) & dma_mask) != result+size-1)
+ panic("dma_map_single: Attempt to map address "
+ "0x%llx-0x%llx, which can't be accessed "
+ "according to the dma mask 0x%llx\n",
+ physical, physical+size-1, dma_mask);
+ goto done;
+
+ case OCTEON_DMA_BAR_TYPE_BIG:
+#ifdef CONFIG_64BIT
+ /* If the device supports 64bit addressing, then use BAR2 */
+ if (dma_mask > BAR2_PCI_ADDRESS) {
+ result = physical + BAR2_PCI_ADDRESS;
+ goto done;
+ }
+#endif
+ if (unlikely(physical < (4ul << 10))) {
+ panic("dma_map_single: Not allowed to map first 4KB. "
+ "It interferes with BAR0 special area\n");
+ } else if (physical < (256ul << 20)) {
+ if (unlikely(physical + size > (256ul << 20)))
+ panic("dma_map_single: Requested memory spans "
+ "Bar0 0:256MB and bootbus\n");
+ result = physical;
+ goto done;
+ } else if (unlikely(physical < (512ul << 20))) {
+ panic("dma_map_single: Not allowed to map bootbus\n");
+ } else if (physical < (2ul << 30)) {
+ if (unlikely(physical + size > (2ul << 30)))
+ panic("dma_map_single: Requested memory spans "
+ "Bar0 512MB:2GB and BAR1\n");
+ result = physical;
+ goto done;
+ } else if (physical < (2ul << 30) + (128 << 20)) {
+ /* Fall through */
+ } else if (physical <
+ (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)) {
+ if (unlikely
+ (physical + size >
+ (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)))
+ panic("dma_map_single: Requested memory "
+ "extends past Bar1 (4GB-%luMB)\n",
+ OCTEON_PCI_BAR1_HOLE_SIZE);
+ result = physical;
+ goto done;
+ } else if ((physical >= 0x410000000ull) &&
+ (physical < 0x420000000ull)) {
+ if (unlikely(physical + size > 0x420000000ull))
+ panic("dma_map_single: Requested memory spans "
+ "non existant memory\n");
+ /* BAR0 fixed mapping 256MB:512MB ->
+ * 16GB+256MB:16GB+512MB */
+ result = physical - 0x400000000ull;
+ goto done;
+ } else {
+ /* Continued below switch statement */
+ }
+ break;
+
+ case OCTEON_DMA_BAR_TYPE_SMALL:
+#ifdef CONFIG_64BIT
+ /* If the device supports 64bit addressing, then use BAR2 */
+ if (dma_mask > BAR2_PCI_ADDRESS) {
+ result = physical + BAR2_PCI_ADDRESS;
+ goto done;
+ }
+#endif
+ /* Continued below switch statement */
+ break;
+
+ default:
+ panic("dma_map_single: Invalid octeon_dma_bar_type\n");
+ }
+
+ /* Don't allow mapping to span multiple Bar entries. The hardware guys
+ won't guarantee that DMA across boards work */
+ if (unlikely((physical >> 22) != ((physical + size - 1) >> 22)))
+ panic("dma_map_single: "
+ "Requested memory spans more than one Bar1 entry\n");
+
+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
+ start_index = 31;
+ else if (unlikely(dma_mask < (1ul << 27)))
+ start_index = (dma_mask >> 22);
+ else
+ start_index = 31;
+
+ /* Only one processor can access the Bar register at once */
+ spin_lock_irqsave(&bar1_lock, flags);
+
+ /* Look through Bar1 for existing mapping that will work */
+ for (index = start_index; index >= 0; index--) {
+ if ((bar1_state[index].address_bits == physical >> 22) &&
+ (bar1_state[index].ref_count)) {
+ /* An existing mapping will work, use it */
+ bar1_state[index].ref_count++;
+ if (unlikely(bar1_state[index].ref_count < 0))
+ panic("dma_map_single: "
+ "Bar1[%d] reference count overflowed\n",
+ (int) index);
+ result = (index << 22) | (physical & ((1 << 22) - 1));
+ /* Large BAR1 is offset at 2GB */
+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
+ result += 2ul << 30;
+ goto done_unlock;
+ }
+ }
+
+ /* No existing mappings, look for a free entry */
+ for (index = start_index; index >= 0; index--) {
+ if (unlikely(bar1_state[index].ref_count == 0)) {
+ union cvmx_pci_bar1_indexx bar1_index;
+ /* We have a free entry, use it */
+ bar1_state[index].ref_count = 1;
+ bar1_state[index].address_bits = physical >> 22;
+ bar1_index.u32 = 0;
+ /* Address bits[35:22] sent to L2C */
+ bar1_index.s.addr_idx = physical >> 22;
+ /* Don't put PCI accesses in L2. */
+ bar1_index.s.ca = 1;
+ /* Endian Swap Mode */
+ bar1_index.s.end_swp = 1;
+ /* Set '1' when the selected address range is valid. */
+ bar1_index.s.addr_v = 1;
+ octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
+ bar1_index.u32);
+ /* An existing mapping will work, use it */
+ result = (index << 22) | (physical & ((1 << 22) - 1));
+ /* Large BAR1 is offset at 2GB */
+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
+ result += 2ul << 30;
+ goto done_unlock;
+ }
+ }
+
+ pr_err("dma_map_single: "
+ "Can't find empty BAR1 index for physical mapping 0x%llx\n",
+ (unsigned long long) physical);
+
+done_unlock:
+ spin_unlock_irqrestore(&bar1_lock, flags);
+done:
+ pr_debug("dma_map_single 0x%llx->0x%llx\n", physical, result);
+ return result;
+#endif
}
void octeon_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
- /* Without PCI/PCIe this function can be called for Octeon internal
- * devices such as USB. These devices all support 64bit addressing */
+#ifndef CONFIG_PCI
+ /*
+ * Without PCI/PCIe this function can be called for Octeon internal
+ * devices such as USB. These devices all support 64bit addressing.
+ */
+ return;
+#else
+ unsigned long flags;
+ uint64_t index;
+
+ /*
+ * Platform devices, such as the internal USB, skip all
+ * translation and use Octeon physical addresses directly.
+ */
+ if (dev->bus == &platform_bus_type)
+ return;
+
+ switch (octeon_dma_bar_type) {
+ case OCTEON_DMA_BAR_TYPE_PCIE:
+ /* Nothing to do, all mappings are static */
+ goto done;
+
+ case OCTEON_DMA_BAR_TYPE_BIG:
+#ifdef CONFIG_64BIT
+ /* Nothing to do for addresses using BAR2 */
+ if (dma_addr >= BAR2_PCI_ADDRESS)
+ goto done;
+#endif
+ if (unlikely(dma_addr < (4ul << 10)))
+ panic("dma_unmap_single: Unexpect DMA address 0x%llx\n",
+ dma_addr);
+ else if (dma_addr < (2ul << 30))
+ /* Nothing to do for addresses using BAR0 */
+ goto done;
+ else if (dma_addr < (2ul << 30) + (128ul << 20))
+ /* Need to unmap, fall through */
+ index = (dma_addr - (2ul << 30)) >> 22;
+ else if (dma_addr <
+ (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20))
+ goto done; /* Nothing to do for the rest of BAR1 */
+ else
+ panic("dma_unmap_single: Unexpect DMA address 0x%llx\n",
+ dma_addr);
+ /* Continued below switch statement */
+ break;
+
+ case OCTEON_DMA_BAR_TYPE_SMALL:
+#ifdef CONFIG_64BIT
+ /* Nothing to do for addresses using BAR2 */
+ if (dma_addr >= BAR2_PCI_ADDRESS)
+ goto done;
+#endif
+ index = dma_addr >> 22;
+ /* Continued below switch statement */
+ break;
+
+ default:
+ panic("dma_unmap_single: Invalid octeon_dma_bar_type\n");
+ }
+
+ if (unlikely(index > 31))
+ panic("dma_unmap_single: "
+ "Attempt to unmap an invalid address (0x%llx)\n",
+ dma_addr);
+
+ spin_lock_irqsave(&bar1_lock, flags);
+ bar1_state[index].ref_count--;
+ if (bar1_state[index].ref_count == 0)
+ octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0);
+ else if (unlikely(bar1_state[index].ref_count < 0))
+ panic("dma_unmap_single: Bar1[%u] reference count < 0\n",
+ (int) index);
+ spin_unlock_irqrestore(&bar1_lock, flags);
+done:
+ pr_debug("dma_unmap_single 0x%llx\n", dma_addr);
return;
+#endif
}
diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile
index 80d6cb26766b..2fd66db6939e 100644
--- a/arch/mips/cavium-octeon/executive/Makefile
+++ b/arch/mips/cavium-octeon/executive/Makefile
@@ -11,3 +11,4 @@
obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o
+obj-$(CONFIG_PCI) += cvmx-helper-errata.o cvmx-helper-jtag.o
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c b/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c
new file mode 100644
index 000000000000..8fb82057cd80
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c
@@ -0,0 +1,70 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * Fixes and workaround for Octeon chip errata. This file
+ * contains functions called by cvmx-helper to workaround known
+ * chip errata. For the most part, code doesn't need to call
+ * these functions directly.
+ *
+ */
+#include <asm/octeon/octeon.h>
+
+#include <asm/octeon/cvmx-helper-jtag.h>
+
+/**
+ * Due to errata G-720, the 2nd order CDR circuit on CN52XX pass
+ * 1 doesn't work properly. The following code disables 2nd order
+ * CDR for the specified QLM.
+ *
+ * @qlm: QLM to disable 2nd order CDR for.
+ */
+void __cvmx_helper_errata_qlm_disable_2nd_order_cdr(int qlm)
+{
+ int lane;
+ cvmx_helper_qlm_jtag_init();
+ /* We need to load all four lanes of the QLM, a total of 1072 bits */
+ for (lane = 0; lane < 4; lane++) {
+ /*
+ * Each lane has 268 bits. We need to set
+ * cfg_cdr_incx<67:64> = 3 and cfg_cdr_secord<77> =
+ * 1. All other bits are zero. Bits go in LSB first,
+ * so start off with the zeros for bits <63:0>.
+ */
+ cvmx_helper_qlm_jtag_shift_zeros(qlm, 63 - 0 + 1);
+ /* cfg_cdr_incx<67:64>=3 */
+ cvmx_helper_qlm_jtag_shift(qlm, 67 - 64 + 1, 3);
+ /* Zeros for bits <76:68> */
+ cvmx_helper_qlm_jtag_shift_zeros(qlm, 76 - 68 + 1);
+ /* cfg_cdr_secord<77>=1 */
+ cvmx_helper_qlm_jtag_shift(qlm, 77 - 77 + 1, 1);
+ /* Zeros for bits <267:78> */
+ cvmx_helper_qlm_jtag_shift_zeros(qlm, 267 - 78 + 1);
+ }
+ cvmx_helper_qlm_jtag_update(qlm);
+}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c b/arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c
new file mode 100644
index 000000000000..c1c54890bae0
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c
@@ -0,0 +1,144 @@
+
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * Helper utilities for qlm_jtag.
+ *
+ */
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-helper-jtag.h>
+
+
+/**
+ * Initialize the internal QLM JTAG logic to allow programming
+ * of the JTAG chain by the cvmx_helper_qlm_jtag_*() functions.
+ * These functions should only be used at the direction of Cavium
+ * Networks. Programming incorrect values into the JTAG chain
+ * can cause chip damage.
+ */
+void cvmx_helper_qlm_jtag_init(void)
+{
+ union cvmx_ciu_qlm_jtgc jtgc;
+ uint32_t clock_div = 0;
+ uint32_t divisor = cvmx_sysinfo_get()->cpu_clock_hz / (25 * 1000000);
+ divisor = (divisor - 1) >> 2;
+ /* Convert the divisor into a power of 2 shift */
+ while (divisor) {
+ clock_div++;
+ divisor = divisor >> 1;
+ }
+
+ /*
+ * Clock divider for QLM JTAG operations. eclk is divided by
+ * 2^(CLK_DIV + 2)
+ */
+ jtgc.u64 = 0;
+ jtgc.s.clk_div = clock_div;
+ jtgc.s.mux_sel = 0;
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+ jtgc.s.bypass = 0x3;
+ else
+ jtgc.s.bypass = 0xf;
+ cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64);
+ cvmx_read_csr(CVMX_CIU_QLM_JTGC);
+}
+
+/**
+ * Write up to 32bits into the QLM jtag chain. Bits are shifted
+ * into the MSB and out the LSB, so you should shift in the low
+ * order bits followed by the high order bits. The JTAG chain is
+ * 4 * 268 bits long, or 1072.
+ *
+ * @qlm: QLM to shift value into
+ * @bits: Number of bits to shift in (1-32).
+ * @data: Data to shift in. Bit 0 enters the chain first, followed by
+ * bit 1, etc.
+ *
+ * Returns The low order bits of the JTAG chain that shifted out of the
+ * circle.
+ */
+uint32_t cvmx_helper_qlm_jtag_shift(int qlm, int bits, uint32_t data)
+{
+ union cvmx_ciu_qlm_jtgd jtgd;
+ jtgd.u64 = 0;
+ jtgd.s.shift = 1;
+ jtgd.s.shft_cnt = bits - 1;
+ jtgd.s.shft_reg = data;
+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
+ jtgd.s.select = 1 << qlm;
+ cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64);
+ do {
+ jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD);
+ } while (jtgd.s.shift);
+ return jtgd.s.shft_reg >> (32 - bits);
+}
+
+/**
+ * Shift long sequences of zeros into the QLM JTAG chain. It is
+ * common to need to shift more than 32 bits of zeros into the
+ * chain. This function is a convience wrapper around
+ * cvmx_helper_qlm_jtag_shift() to shift more than 32 bits of
+ * zeros at a time.
+ *
+ * @qlm: QLM to shift zeros into
+ * @bits:
+ */
+void cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits)
+{
+ while (bits > 0) {
+ int n = bits;
+ if (n > 32)
+ n = 32;
+ cvmx_helper_qlm_jtag_shift(qlm, n, 0);
+ bits -= n;
+ }
+}
+
+/**
+ * Program the QLM JTAG chain into all lanes of the QLM. You must
+ * have already shifted in 268*4, or 1072 bits into the JTAG
+ * chain. Updating invalid values can possibly cause chip damage.
+ *
+ * @qlm: QLM to program
+ */
+void cvmx_helper_qlm_jtag_update(int qlm)
+{
+ union cvmx_ciu_qlm_jtgd jtgd;
+
+ /* Update the new data */
+ jtgd.u64 = 0;
+ jtgd.s.update = 1;
+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
+ jtgd.s.select = 1 << qlm;
+ cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64);
+ do {
+ jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD);
+ } while (jtgd.s.update);
+}
diff --git a/arch/mips/cavium-octeon/msi.c b/arch/mips/cavium-octeon/msi.c
new file mode 100644
index 000000000000..964b03b75a8f
--- /dev/null
+++ b/arch/mips/cavium-octeon/msi.c
@@ -0,0 +1,288 @@
+/*
+ * 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) 2005-2007 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/msi.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include <asm/octeon/cvmx-pci-defs.h>
+#include <asm/octeon/cvmx-npei-defs.h>
+#include <asm/octeon/cvmx-pexp-defs.h>
+
+#include "pci-common.h"
+
+/*
+ * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is
+ * in use.
+ */
+static uint64_t msi_free_irq_bitmask;
+
+/*
+ * Each bit in msi_multiple_irq_bitmask tells that the device using
+ * this bit in msi_free_irq_bitmask is also using the next bit. This
+ * is used so we can disable all of the MSI interrupts when a device
+ * uses multiple.
+ */
+static uint64_t msi_multiple_irq_bitmask;
+
+/*
+ * This lock controls updates to msi_free_irq_bitmask and
+ * msi_multiple_irq_bitmask.
+ */
+static DEFINE_SPINLOCK(msi_free_irq_bitmask_lock);
+
+
+/**
+ * Called when a driver request MSI interrupts instead of the
+ * legacy INT A-D. This routine will allocate multiple interrupts
+ * for MSI devices that support them. A device can override this by
+ * programming the MSI control bits [6:4] before calling
+ * pci_enable_msi().
+ *
+ * @param dev Device requesting MSI interrupts
+ * @param desc MSI descriptor
+ *
+ * Returns 0 on success.
+ */
+int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+{
+ struct msi_msg msg;
+ uint16_t control;
+ int configured_private_bits;
+ int request_private_bits;
+ int irq;
+ int irq_step;
+ uint64_t search_mask;
+
+ /*
+ * Read the MSI config to figure out how many IRQs this device
+ * wants. Most devices only want 1, which will give
+ * configured_private_bits and request_private_bits equal 0.
+ */
+ pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
+ &control);
+
+ /*
+ * If the number of private bits has been configured then use
+ * that value instead of the requested number. This gives the
+ * driver the chance to override the number of interrupts
+ * before calling pci_enable_msi().
+ */
+ configured_private_bits = (control & PCI_MSI_FLAGS_QSIZE) >> 4;
+ if (configured_private_bits == 0) {
+ /* Nothing is configured, so use the hardware requested size */
+ request_private_bits = (control & PCI_MSI_FLAGS_QMASK) >> 1;
+ } else {
+ /*
+ * Use the number of configured bits, assuming the
+ * driver wanted to override the hardware request
+ * value.
+ */
+ request_private_bits = configured_private_bits;
+ }
+
+ /*
+ * The PCI 2.3 spec mandates that there are at most 32
+ * interrupts. If this device asks for more, only give it one.
+ */
+ if (request_private_bits > 5)
+ request_private_bits = 0;
+
+try_only_one:
+ /*
+ * The IRQs have to be aligned on a power of two based on the
+ * number being requested.
+ */
+ irq_step = 1 << request_private_bits;
+
+ /* Mask with one bit for each IRQ */
+ search_mask = (1 << irq_step) - 1;
+
+ /*
+ * We're going to search msi_free_irq_bitmask_lock for zero
+ * bits. This represents an MSI interrupt number that isn't in
+ * use.
+ */
+ spin_lock(&msi_free_irq_bitmask_lock);
+ for (irq = 0; irq < 64; irq += irq_step) {
+ if ((msi_free_irq_bitmask & (search_mask << irq)) == 0) {
+ msi_free_irq_bitmask |= search_mask << irq;
+ msi_multiple_irq_bitmask |= (search_mask >> 1) << irq;
+ break;
+ }
+ }
+ spin_unlock(&msi_free_irq_bitmask_lock);
+
+ /* Make sure the search for available interrupts didn't fail */
+ if (irq >= 64) {
+ if (request_private_bits) {
+ pr_err("arch_setup_msi_irq: Unable to find %d free "
+ "interrupts, trying just one",
+ 1 << request_private_bits);
+ request_private_bits = 0;
+ goto try_only_one;
+ } else
+ panic("arch_setup_msi_irq: Unable to find a free MSI "
+ "interrupt");
+ }
+
+ /* MSI interrupts start at logical IRQ OCTEON_IRQ_MSI_BIT0 */
+ irq += OCTEON_IRQ_MSI_BIT0;
+
+ switch (octeon_dma_bar_type) {
+ case OCTEON_DMA_BAR_TYPE_SMALL:
+ /* When not using big bar, Bar 0 is based at 128MB */
+ msg.address_lo =
+ ((128ul << 20) + CVMX_PCI_MSI_RCV) & 0xffffffff;
+ msg.address_hi = ((128ul << 20) + CVMX_PCI_MSI_RCV) >> 32;
+ case OCTEON_DMA_BAR_TYPE_BIG:
+ /* When using big bar, Bar 0 is based at 0 */
+ msg.address_lo = (0 + CVMX_PCI_MSI_RCV) & 0xffffffff;
+ msg.address_hi = (0 + CVMX_PCI_MSI_RCV) >> 32;
+ break;
+ case OCTEON_DMA_BAR_TYPE_PCIE:
+ /* When using PCIe, Bar 0 is based at 0 */
+ /* FIXME CVMX_NPEI_MSI_RCV* other than 0? */
+ msg.address_lo = (0 + CVMX_NPEI_PCIE_MSI_RCV) & 0xffffffff;
+ msg.address_hi = (0 + CVMX_NPEI_PCIE_MSI_RCV) >> 32;
+ break;
+ default:
+ panic("arch_setup_msi_irq: Invalid octeon_dma_bar_type\n");
+ }
+ msg.data = irq - OCTEON_IRQ_MSI_BIT0;
+
+ /* Update the number of IRQs the device has available to it */
+ control &= ~PCI_MSI_FLAGS_QSIZE;
+ control |= request_private_bits << 4;
+ pci_write_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
+ control);
+
+ set_irq_msi(irq, desc);
+ write_msi_msg(irq, &msg);
+ return 0;
+}
+
+
+/**
+ * Called when a device no longer needs its MSI interrupts. All
+ * MSI interrupts for the device are freed.
+ *
+ * @irq: The devices first irq number. There may be multple in sequence.
+ */
+void arch_teardown_msi_irq(unsigned int irq)
+{
+ int number_irqs;
+ uint64_t bitmask;
+
+ if ((irq < OCTEON_IRQ_MSI_BIT0) || (irq > OCTEON_IRQ_MSI_BIT63))
+ panic("arch_teardown_msi_irq: Attempted to teardown illegal "
+ "MSI interrupt (%d)", irq);
+ irq -= OCTEON_IRQ_MSI_BIT0;
+
+ /*
+ * Count the number of IRQs we need to free by looking at the
+ * msi_multiple_irq_bitmask. Each bit set means that the next
+ * IRQ is also owned by this device.
+ */
+ number_irqs = 0;
+ while ((irq+number_irqs < 64) &&
+ (msi_multiple_irq_bitmask & (1ull << (irq + number_irqs))))
+ number_irqs++;
+ number_irqs++;
+ /* Mask with one bit for each IRQ */
+ bitmask = (1 << number_irqs) - 1;
+ /* Shift the mask to the correct bit location */
+ bitmask <<= irq;
+ if ((msi_free_irq_bitmask & bitmask) != bitmask)
+ panic("arch_teardown_msi_irq: Attempted to teardown MSI "
+ "interrupt (%d) not in use", irq);
+
+ /* Checks are done, update the in use bitmask */
+ spin_lock(&msi_free_irq_bitmask_lock);
+ msi_free_irq_bitmask &= ~bitmask;
+ msi_multiple_irq_bitmask &= ~bitmask;
+ spin_unlock(&msi_free_irq_bitmask_lock);
+}
+
+
+/**
+ * Called by the interrupt handling code when an MSI interrupt
+ * occurs.
+ *
+ * @param cpl
+ * @param dev_id
+ *
+ * @return
+ */
+static irqreturn_t octeon_msi_interrupt(int cpl, void *dev_id)
+{
+ uint64_t msi_bits;
+ int irq;
+
+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE)
+ msi_bits = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_RCV0);
+ else
+ msi_bits = cvmx_read_csr(CVMX_NPI_NPI_MSI_RCV);
+ irq = fls64(msi_bits);
+ if (irq) {
+ irq += OCTEON_IRQ_MSI_BIT0 - 1;
+ if (irq_desc[irq].action) {
+ do_IRQ(irq);
+ return IRQ_HANDLED;
+ } else {
+ pr_err("Spurious MSI interrupt %d\n", irq);
+ if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
+ /* These chips have PCIe */
+ cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0,
+ 1ull << (irq -
+ OCTEON_IRQ_MSI_BIT0));
+ } else {
+ /* These chips have PCI */
+ cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
+ 1ull << (irq -
+ OCTEON_IRQ_MSI_BIT0));
+ }
+ }
+ }
+ return IRQ_NONE;
+}
+
+
+/**
+ * Initializes the MSI interrupt handling code
+ *
+ * @return
+ */
+int octeon_msi_initialize(void)
+{
+ int r;
+ if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
+ r = request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt,
+ IRQF_SHARED,
+ "MSI[0:63]", octeon_msi_interrupt);
+ } else if (octeon_is_pci_host()) {
+ r = request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt,
+ IRQF_SHARED,
+ "MSI[0:15]", octeon_msi_interrupt);
+ r += request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt,
+ IRQF_SHARED,
+ "MSI[16:31]", octeon_msi_interrupt);
+ r += request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt,
+ IRQF_SHARED,
+ "MSI[32:47]", octeon_msi_interrupt);
+ r += request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt,
+ IRQF_SHARED,
+ "MSI[48:63]", octeon_msi_interrupt);
+ }
+ return 0;
+}
+
+subsys_initcall(octeon_msi_initialize);
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 1c19af8daa62..8dfa009e0070 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -10,6 +10,8 @@
#include <linux/hardirq.h>
#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-pexp-defs.h>
+#include <asm/octeon/cvmx-npi-defs.h>
DEFINE_RWLOCK(octeon_irq_ciu0_rwlock);
DEFINE_RWLOCK(octeon_irq_ciu1_rwlock);
@@ -177,7 +179,7 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
}
#ifdef CONFIG_SMP
-static void octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
+static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
{
int cpu;
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
@@ -199,6 +201,8 @@ static void octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask
*/
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
write_unlock(&octeon_irq_ciu0_rwlock);
+
+ return 0;
}
#endif
@@ -292,7 +296,7 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
}
#ifdef CONFIG_SMP
-static void octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest)
+static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest)
{
int cpu;
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
@@ -315,6 +319,8 @@ static void octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask
*/
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
write_unlock(&octeon_irq_ciu1_rwlock);
+
+ return 0;
}
#endif
diff --git a/arch/mips/cavium-octeon/pci-common.c b/arch/mips/cavium-octeon/pci-common.c
new file mode 100644
index 000000000000..cd029f88da7f
--- /dev/null
+++ b/arch/mips/cavium-octeon/pci-common.c
@@ -0,0 +1,137 @@
+/*
+ * 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) 2005-2007 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include "pci-common.h"
+
+typeof(pcibios_map_irq) *octeon_pcibios_map_irq;
+enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID;
+
+/**
+ * Map a PCI device to the appropriate interrupt line
+ *
+ * @param dev The Linux PCI device structure for the device to map
+ * @param slot The slot number for this device on __BUS 0__. Linux
+ * enumerates through all the bridges and figures out the
+ * slot on Bus 0 where this device eventually hooks to.
+ * @param pin The PCI interrupt pin read from the device, then swizzled
+ * as it goes through each bridge.
+ * @return Interrupt number for the device
+ */
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (octeon_pcibios_map_irq)
+ return octeon_pcibios_map_irq(dev, slot, pin);
+ else
+ panic("octeon_pcibios_map_irq doesn't point to a "
+ "pcibios_map_irq() function");
+}
+
+
+/**
+ * Called to perform platform specific PCI setup
+ *
+ * @param dev
+ * @return
+ */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ uint16_t config;
+ uint32_t dconfig;
+ int pos;
+ /*
+ * Force the Cache line setting to 64 bytes. The standard
+ * Linux bus scan doesn't seem to set it. Octeon really has
+ * 128 byte lines, but Intel bridges get really upset if you
+ * try and set values above 64 bytes. Value is specified in
+ * 32bit words.
+ */
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4);
+ /* Set latency timers for all devices */
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 48);
+
+ /* Enable reporting System errors and parity errors on all devices */
+ /* Enable parity checking and error reporting */
+ pci_read_config_word(dev, PCI_COMMAND, &config);
+ config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+ pci_write_config_word(dev, PCI_COMMAND, config);
+
+ if (dev->subordinate) {
+ /* Set latency timers on sub bridges */
+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 48);
+ /* More bridge error detection */
+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
+ config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config);
+ }
+
+ /* Enable the PCIe normal error reporting */
+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+ if (pos) {
+ /* Update Device Control */
+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
+ /* Correctable Error Reporting */
+ config |= PCI_EXP_DEVCTL_CERE;
+ /* Non-Fatal Error Reporting */
+ config |= PCI_EXP_DEVCTL_NFERE;
+ /* Fatal Error Reporting */
+ config |= PCI_EXP_DEVCTL_FERE;
+ /* Unsupported Request */
+ config |= PCI_EXP_DEVCTL_URRE;
+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
+ }
+
+ /* Find the Advanced Error Reporting capability */
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+ if (pos) {
+ /* Clear Uncorrectable Error Status */
+ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
+ &dconfig);
+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
+ dconfig);
+ /* Enable reporting of all uncorrectable errors */
+ /* Uncorrectable Error Mask - turned on bits disable errors */
+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0);
+ /*
+ * Leave severity at HW default. This only controls if
+ * errors are reported as uncorrectable or
+ * correctable, not if the error is reported.
+ */
+ /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */
+ /* Clear Correctable Error Status */
+ pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig);
+ pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig);
+ /* Enable reporting of all correctable errors */
+ /* Correctable Error Mask - turned on bits disable errors */
+ pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0);
+ /* Advanced Error Capabilities */
+ pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig);
+ /* ECRC Generation Enable */
+ if (config & PCI_ERR_CAP_ECRC_GENC)
+ config |= PCI_ERR_CAP_ECRC_GENE;
+ /* ECRC Check Enable */
+ if (config & PCI_ERR_CAP_ECRC_CHKC)
+ config |= PCI_ERR_CAP_ECRC_CHKE;
+ pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig);
+ /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */
+ /* Report all errors to the root complex */
+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND,
+ PCI_ERR_ROOT_CMD_COR_EN |
+ PCI_ERR_ROOT_CMD_NONFATAL_EN |
+ PCI_ERR_ROOT_CMD_FATAL_EN);
+ /* Clear the Root status register */
+ pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig);
+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
+ }
+
+ return 0;
+}
diff --git a/arch/mips/cavium-octeon/pci-common.h b/arch/mips/cavium-octeon/pci-common.h
new file mode 100644
index 000000000000..74ae79991e45
--- /dev/null
+++ b/arch/mips/cavium-octeon/pci-common.h
@@ -0,0 +1,39 @@
+/*
+ * 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) 2005-2007 Cavium Networks
+ */
+#ifndef __OCTEON_PCI_COMMON_H__
+#define __OCTEON_PCI_COMMON_H__
+
+#include <linux/pci.h>
+
+/* Some PCI cards require delays when accessing config space. */
+#define PCI_CONFIG_SPACE_DELAY 10000
+
+/* pcibios_map_irq() is defined inside pci-common.c. All it does is call the
+ Octeon specific version pointed to by this variable. This function needs to
+ change for PCI or PCIe based hosts */
+extern typeof(pcibios_map_irq) *octeon_pcibios_map_irq;
+
+/* The following defines are only used when octeon_dma_bar_type =
+ OCTEON_DMA_BAR_TYPE_BIG */
+#define OCTEON_PCI_BAR1_HOLE_BITS 5
+#define OCTEON_PCI_BAR1_HOLE_SIZE (1ul<<(OCTEON_PCI_BAR1_HOLE_BITS+3))
+
+enum octeon_dma_bar_type {
+ OCTEON_DMA_BAR_TYPE_INVALID,
+ OCTEON_DMA_BAR_TYPE_SMALL,
+ OCTEON_DMA_BAR_TYPE_BIG,
+ OCTEON_DMA_BAR_TYPE_PCIE
+};
+
+/**
+ * This is a variable to tell the DMA mapping system in dma-octeon.c
+ * how to map PCI DMA addresses.
+ */
+extern enum octeon_dma_bar_type octeon_dma_bar_type;
+
+#endif
diff --git a/arch/mips/cavium-octeon/pci.c b/arch/mips/cavium-octeon/pci.c
new file mode 100644
index 000000000000..67c0ff5e92f1
--- /dev/null
+++ b/arch/mips/cavium-octeon/pci.c
@@ -0,0 +1,568 @@
+/*
+ * 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) 2005-2007 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include <asm/octeon/cvmx-pci-defs.h>
+
+#include "pci-common.h"
+
+#define USE_OCTEON_INTERNAL_ARBITER
+
+/*
+ * Octeon's PCI controller uses did=3, subdid=2 for PCI IO
+ * addresses. Use PCI endian swapping 1 so no address swapping is
+ * necessary. The Linux io routines will endian swap the data.
+ */
+#define OCTEON_PCI_IOSPACE_BASE 0x80011a0400000000ull
+#define OCTEON_PCI_IOSPACE_SIZE (1ull<<32)
+
+/* Octeon't PCI controller uses did=3, subdid=3 for PCI memory. */
+#define OCTEON_PCI_MEMSPACE_OFFSET (0x00011b0000000000ull)
+
+/**
+ * This is the bit decoding used for the Octeon PCI controller addresses
+ */
+union octeon_pci_address {
+ uint64_t u64;
+ struct {
+ uint64_t upper:2;
+ uint64_t reserved:13;
+ uint64_t io:1;
+ uint64_t did:5;
+ uint64_t subdid:3;
+ uint64_t reserved2:4;
+ uint64_t endian_swap:2;
+ uint64_t reserved3:10;
+ uint64_t bus:8;
+ uint64_t dev:5;
+ uint64_t func:3;
+ uint64_t reg:8;
+ } s;
+};
+
+/**
+ * Return the mapping of PCI device number to IRQ line. Each
+ * character in the return string represents the interrupt
+ * line for the device at that position. Device 1 maps to the
+ * first character, etc. The characters A-D are used for PCI
+ * interrupts.
+ *
+ * Returns PCI interrupt mapping
+ */
+const char *octeon_get_pci_interrupts(void)
+{
+ /*
+ * Returning an empty string causes the interrupts to be
+ * routed based on the PCI specification. From the PCI spec:
+ *
+ * INTA# of Device Number 0 is connected to IRQW on the system
+ * board. (Device Number has no significance regarding being
+ * located on the system board or in a connector.) INTA# of
+ * Device Number 1 is connected to IRQX on the system
+ * board. INTA# of Device Number 2 is connected to IRQY on the
+ * system board. INTA# of Device Number 3 is connected to IRQZ
+ * on the system board. The table below describes how each
+ * agent's INTx# lines are connected to the system board
+ * interrupt lines. The following equation can be used to
+ * determine to which INTx# signal on the system board a given
+ * device's INTx# line(s) is connected.
+ *
+ * MB = (D + I) MOD 4 MB = System board Interrupt (IRQW = 0,
+ * IRQX = 1, IRQY = 2, and IRQZ = 3) D = Device Number I =
+ * Interrupt Number (INTA# = 0, INTB# = 1, INTC# = 2, and
+ * INTD# = 3)
+ */
+ switch (octeon_bootinfo->board_type) {
+ case CVMX_BOARD_TYPE_NAO38:
+ /* This is really the NAC38 */
+ return "AAAAADABAAAAAAAAAAAAAAAAAAAAAAAA";
+ case CVMX_BOARD_TYPE_THUNDER:
+ return "";
+ case CVMX_BOARD_TYPE_EBH3000:
+ return "";
+ case CVMX_BOARD_TYPE_EBH3100:
+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
+ return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ case CVMX_BOARD_TYPE_BBGW_REF:
+ return "AABCD";
+ default:
+ return "";
+ }
+}
+
+/**
+ * Map a PCI device to the appropriate interrupt line
+ *
+ * @dev: The Linux PCI device structure for the device to map
+ * @slot: The slot number for this device on __BUS 0__. Linux
+ * enumerates through all the bridges and figures out the
+ * slot on Bus 0 where this device eventually hooks to.
+ * @pin: The PCI interrupt pin read from the device, then swizzled
+ * as it goes through each bridge.
+ * Returns Interrupt number for the device
+ */
+int __init octeon_pci_pcibios_map_irq(const struct pci_dev *dev,
+ u8 slot, u8 pin)
+{
+ int irq_num;
+ const char *interrupts;
+ int dev_num;
+
+ /* Get the board specific interrupt mapping */
+ interrupts = octeon_get_pci_interrupts();
+
+ dev_num = dev->devfn >> 3;
+ if (dev_num < strlen(interrupts))
+ irq_num = ((interrupts[dev_num] - 'A' + pin - 1) & 3) +
+ OCTEON_IRQ_PCI_INT0;
+ else
+ irq_num = ((slot + pin - 3) & 3) + OCTEON_IRQ_PCI_INT0;
+ return irq_num;
+}
+
+
+/**
+ * Read a value from configuration space
+ *
+ */
+static int octeon_read_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 *val)
+{
+ union octeon_pci_address pci_addr;
+
+ pci_addr.u64 = 0;
+ pci_addr.s.upper = 2;
+ pci_addr.s.io = 1;
+ pci_addr.s.did = 3;
+ pci_addr.s.subdid = 1;
+ pci_addr.s.endian_swap = 1;
+ pci_addr.s.bus = bus->number;
+ pci_addr.s.dev = devfn >> 3;
+ pci_addr.s.func = devfn & 0x7;
+ pci_addr.s.reg = reg;
+
+#if PCI_CONFIG_SPACE_DELAY
+ udelay(PCI_CONFIG_SPACE_DELAY);
+#endif
+ switch (size) {
+ case 4:
+ *val = le32_to_cpu(cvmx_read64_uint32(pci_addr.u64));
+ return PCIBIOS_SUCCESSFUL;
+ case 2:
+ *val = le16_to_cpu(cvmx_read64_uint16(pci_addr.u64));
+ return PCIBIOS_SUCCESSFUL;
+ case 1:
+ *val = cvmx_read64_uint8(pci_addr.u64);
+ return PCIBIOS_SUCCESSFUL;
+ }
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
+
+
+/**
+ * Write a value to PCI configuration space
+ *
+ * @bus:
+ * @devfn:
+ * @reg:
+ * @size:
+ * @val:
+ * Returns
+ */
+static int octeon_write_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 val)
+{
+ union octeon_pci_address pci_addr;
+
+ pci_addr.u64 = 0;
+ pci_addr.s.upper = 2;
+ pci_addr.s.io = 1;
+ pci_addr.s.did = 3;
+ pci_addr.s.subdid = 1;
+ pci_addr.s.endian_swap = 1;
+ pci_addr.s.bus = bus->number;
+ pci_addr.s.dev = devfn >> 3;
+ pci_addr.s.func = devfn & 0x7;
+ pci_addr.s.reg = reg;
+
+#if PCI_CONFIG_SPACE_DELAY
+ udelay(PCI_CONFIG_SPACE_DELAY);
+#endif
+ switch (size) {
+ case 4:
+ cvmx_write64_uint32(pci_addr.u64, cpu_to_le32(val));
+ return PCIBIOS_SUCCESSFUL;
+ case 2:
+ cvmx_write64_uint16(pci_addr.u64, cpu_to_le16(val));
+ return PCIBIOS_SUCCESSFUL;
+ case 1:
+ cvmx_write64_uint8(pci_addr.u64, val);
+ return PCIBIOS_SUCCESSFUL;
+ }
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
+
+
+static struct pci_ops octeon_pci_ops = {
+ octeon_read_config,
+ octeon_write_config,
+};
+
+static struct resource octeon_pci_mem_resource = {
+ .start = 0,
+ .end = 0,
+ .name = "Octeon PCI MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+/*
+ * PCI ports must be above 16KB so the ISA bus filtering in the PCI-X to PCI
+ * bridge
+ */
+static struct resource octeon_pci_io_resource = {
+ .start = 0x4000,
+ .end = OCTEON_PCI_IOSPACE_SIZE - 1,
+ .name = "Octeon PCI IO",
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller octeon_pci_controller = {
+ .pci_ops = &octeon_pci_ops,
+ .mem_resource = &octeon_pci_mem_resource,
+ .mem_offset = OCTEON_PCI_MEMSPACE_OFFSET,
+ .io_resource = &octeon_pci_io_resource,
+ .io_offset = 0,
+ .io_map_base = OCTEON_PCI_IOSPACE_BASE,
+};
+
+
+/**
+ * Low level initialize the Octeon PCI controller
+ *
+ * Returns
+ */
+static void octeon_pci_initialize(void)
+{
+ union cvmx_pci_cfg01 cfg01;
+ union cvmx_npi_ctl_status ctl_status;
+ union cvmx_pci_ctl_status_2 ctl_status_2;
+ union cvmx_pci_cfg19 cfg19;
+ union cvmx_pci_cfg16 cfg16;
+ union cvmx_pci_cfg22 cfg22;
+ union cvmx_pci_cfg56 cfg56;
+
+ /* Reset the PCI Bus */
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x1);
+ cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+
+ udelay(2000); /* Hold PCI reset for 2 ms */
+
+ ctl_status.u64 = 0; /* cvmx_read_csr(CVMX_NPI_CTL_STATUS); */
+ ctl_status.s.max_word = 1;
+ ctl_status.s.timer = 1;
+ cvmx_write_csr(CVMX_NPI_CTL_STATUS, ctl_status.u64);
+
+ /* Deassert PCI reset and advertize PCX Host Mode Device Capability
+ (64b) */
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x4);
+ cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+
+ udelay(2000); /* Wait 2 ms after deasserting PCI reset */
+
+ ctl_status_2.u32 = 0;
+ ctl_status_2.s.tsr_hwm = 1; /* Initializes to 0. Must be set
+ before any PCI reads. */
+ ctl_status_2.s.bar2pres = 1; /* Enable BAR2 */
+ ctl_status_2.s.bar2_enb = 1;
+ ctl_status_2.s.bar2_cax = 1; /* Don't use L2 */
+ ctl_status_2.s.bar2_esx = 1;
+ ctl_status_2.s.pmo_amod = 1; /* Round robin priority */
+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) {
+ /* BAR1 hole */
+ ctl_status_2.s.bb1_hole = OCTEON_PCI_BAR1_HOLE_BITS;
+ ctl_status_2.s.bb1_siz = 1; /* BAR1 is 2GB */
+ ctl_status_2.s.bb_ca = 1; /* Don't use L2 with big bars */
+ ctl_status_2.s.bb_es = 1; /* Big bar in byte swap mode */
+ ctl_status_2.s.bb1 = 1; /* BAR1 is big */
+ ctl_status_2.s.bb0 = 1; /* BAR0 is big */
+ }
+
+ octeon_npi_write32(CVMX_NPI_PCI_CTL_STATUS_2, ctl_status_2.u32);
+ udelay(2000); /* Wait 2 ms before doing PCI reads */
+
+ ctl_status_2.u32 = octeon_npi_read32(CVMX_NPI_PCI_CTL_STATUS_2);
+ pr_notice("PCI Status: %s %s-bit\n",
+ ctl_status_2.s.ap_pcix ? "PCI-X" : "PCI",
+ ctl_status_2.s.ap_64ad ? "64" : "32");
+
+ if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+ union cvmx_pci_cnt_reg cnt_reg_start;
+ union cvmx_pci_cnt_reg cnt_reg_end;
+ unsigned long cycles, pci_clock;
+
+ cnt_reg_start.u64 = cvmx_read_csr(CVMX_NPI_PCI_CNT_REG);
+ cycles = read_c0_cvmcount();
+ udelay(1000);
+ cnt_reg_end.u64 = cvmx_read_csr(CVMX_NPI_PCI_CNT_REG);
+ cycles = read_c0_cvmcount() - cycles;
+ pci_clock = (cnt_reg_end.s.pcicnt - cnt_reg_start.s.pcicnt) /
+ (cycles / (mips_hpt_frequency / 1000000));
+ pr_notice("PCI Clock: %lu MHz\n", pci_clock);
+ }
+
+ /*
+ * TDOMC must be set to one in PCI mode. TDOMC should be set to 4
+ * in PCI-X mode to allow four oustanding splits. Otherwise,
+ * should not change from its reset value. Don't write PCI_CFG19
+ * in PCI mode (0x82000001 reset value), write it to 0x82000004
+ * after PCI-X mode is known. MRBCI,MDWE,MDRE -> must be zero.
+ * MRBCM -> must be one.
+ */
+ if (ctl_status_2.s.ap_pcix) {
+ cfg19.u32 = 0;
+ /*
+ * Target Delayed/Split request outstanding maximum
+ * count. [1..31] and 0=32. NOTE: If the user
+ * programs these bits beyond the Designed Maximum
+ * outstanding count, then the designed maximum table
+ * depth will be used instead. No additional
+ * Deferred/Split transactions will be accepted if
+ * this outstanding maximum count is
+ * reached. Furthermore, no additional deferred/split
+ * transactions will be accepted if the I/O delay/ I/O
+ * Split Request outstanding maximum is reached.
+ */
+ cfg19.s.tdomc = 4;
+ /*
+ * Master Deferred Read Request Outstanding Max Count
+ * (PCI only). CR4C[26:24] Max SAC cycles MAX DAC
+ * cycles 000 8 4 001 1 0 010 2 1 011 3 1 100 4 2 101
+ * 5 2 110 6 3 111 7 3 For example, if these bits are
+ * programmed to 100, the core can support 2 DAC
+ * cycles, 4 SAC cycles or a combination of 1 DAC and
+ * 2 SAC cycles. NOTE: For the PCI-X maximum
+ * outstanding split transactions, refer to
+ * CRE0[22:20].
+ */
+ cfg19.s.mdrrmc = 2;
+ /*
+ * Master Request (Memory Read) Byte Count/Byte Enable
+ * select. 0 = Byte Enables valid. In PCI mode, a
+ * burst transaction cannot be performed using Memory
+ * Read command=4?h6. 1 = DWORD Byte Count valid
+ * (default). In PCI Mode, the memory read byte
+ * enables are automatically generated by the
+ * core. Note: N3 Master Request transaction sizes are
+ * always determined through the
+ * am_attr[<35:32>|<7:0>] field.
+ */
+ cfg19.s.mrbcm = 1;
+ octeon_npi_write32(CVMX_NPI_PCI_CFG19, cfg19.u32);
+ }
+
+
+ cfg01.u32 = 0;
+ cfg01.s.msae = 1; /* Memory Space Access Enable */
+ cfg01.s.me = 1; /* Master Enable */
+ cfg01.s.pee = 1; /* PERR# Enable */
+ cfg01.s.see = 1; /* System Error Enable */
+ cfg01.s.fbbe = 1; /* Fast Back to Back Transaction Enable */
+
+ octeon_npi_write32(CVMX_NPI_PCI_CFG01, cfg01.u32);
+
+#ifdef USE_OCTEON_INTERNAL_ARBITER
+ /*
+ * When OCTEON is a PCI host, most systems will use OCTEON's
+ * internal arbiter, so must enable it before any PCI/PCI-X
+ * traffic can occur.
+ */
+ {
+ union cvmx_npi_pci_int_arb_cfg pci_int_arb_cfg;
+
+ pci_int_arb_cfg.u64 = 0;
+ pci_int_arb_cfg.s.en = 1; /* Internal arbiter enable */
+ cvmx_write_csr(CVMX_NPI_PCI_INT_ARB_CFG, pci_int_arb_cfg.u64);
+ }
+#endif /* USE_OCTEON_INTERNAL_ARBITER */
+
+ /*
+ * Preferrably written to 1 to set MLTD. [RDSATI,TRTAE,
+ * TWTAE,TMAE,DPPMR -> must be zero. TILT -> must not be set to
+ * 1..7.
+ */
+ cfg16.u32 = 0;
+ cfg16.s.mltd = 1; /* Master Latency Timer Disable */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG16, cfg16.u32);
+
+ /*
+ * Should be written to 0x4ff00. MTTV -> must be zero.
+ * FLUSH -> must be 1. MRV -> should be 0xFF.
+ */
+ cfg22.u32 = 0;
+ /* Master Retry Value [1..255] and 0=infinite */
+ cfg22.s.mrv = 0xff;
+ /*
+ * AM_DO_FLUSH_I control NOTE: This bit MUST BE ONE for proper
+ * N3K operation.
+ */
+ cfg22.s.flush = 1;
+ octeon_npi_write32(CVMX_NPI_PCI_CFG22, cfg22.u32);
+
+ /*
+ * MOST Indicates the maximum number of outstanding splits (in -1
+ * notation) when OCTEON is in PCI-X mode. PCI-X performance is
+ * affected by the MOST selection. Should generally be written
+ * with one of 0x3be807, 0x2be807, 0x1be807, or 0x0be807,
+ * depending on the desired MOST of 3, 2, 1, or 0, respectively.
+ */
+ cfg56.u32 = 0;
+ cfg56.s.pxcid = 7; /* RO - PCI-X Capability ID */
+ cfg56.s.ncp = 0xe8; /* RO - Next Capability Pointer */
+ cfg56.s.dpere = 1; /* Data Parity Error Recovery Enable */
+ cfg56.s.roe = 1; /* Relaxed Ordering Enable */
+ cfg56.s.mmbc = 1; /* Maximum Memory Byte Count
+ [0=512B,1=1024B,2=2048B,3=4096B] */
+ cfg56.s.most = 3; /* Maximum outstanding Split transactions [0=1
+ .. 7=32] */
+
+ octeon_npi_write32(CVMX_NPI_PCI_CFG56, cfg56.u32);
+
+ /*
+ * Affects PCI performance when OCTEON services reads to its
+ * BAR1/BAR2. Refer to Section 10.6.1. The recommended values are
+ * 0x22, 0x33, and 0x33 for PCI_READ_CMD_6, PCI_READ_CMD_C, and
+ * PCI_READ_CMD_E, respectively. Unfortunately due to errata DDR-700,
+ * these values need to be changed so they won't possibly prefetch off
+ * of the end of memory if PCI is DMAing a buffer at the end of
+ * memory. Note that these values differ from their reset values.
+ */
+ octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_6, 0x21);
+ octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_C, 0x31);
+ octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_E, 0x31);
+}
+
+
+/**
+ * Initialize the Octeon PCI controller
+ *
+ * Returns
+ */
+static int __init octeon_pci_setup(void)
+{
+ union cvmx_npi_mem_access_subidx mem_access;
+ int index;
+
+ /* Only these chips have PCI */
+ if (octeon_has_feature(OCTEON_FEATURE_PCIE))
+ return 0;
+
+ /* Point pcibios_map_irq() to the PCI version of it */
+ octeon_pcibios_map_irq = octeon_pci_pcibios_map_irq;
+
+ /* Only use the big bars on chips that support it */
+ if (OCTEON_IS_MODEL(OCTEON_CN31XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2) ||
+ OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_SMALL;
+ else
+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_BIG;
+
+ /* PCI I/O and PCI MEM values */
+ set_io_port_base(OCTEON_PCI_IOSPACE_BASE);
+ ioport_resource.start = 0;
+ ioport_resource.end = OCTEON_PCI_IOSPACE_SIZE - 1;
+ if (!octeon_is_pci_host()) {
+ pr_notice("Not in host mode, PCI Controller not initialized\n");
+ return 0;
+ }
+
+ pr_notice("%s Octeon big bar support\n",
+ (octeon_dma_bar_type ==
+ OCTEON_DMA_BAR_TYPE_BIG) ? "Enabling" : "Disabling");
+
+ octeon_pci_initialize();
+
+ mem_access.u64 = 0;
+ mem_access.s.esr = 1; /* Endian-Swap on read. */
+ mem_access.s.esw = 1; /* Endian-Swap on write. */
+ mem_access.s.nsr = 0; /* No-Snoop on read. */
+ mem_access.s.nsw = 0; /* No-Snoop on write. */
+ mem_access.s.ror = 0; /* Relax Read on read. */
+ mem_access.s.row = 0; /* Relax Order on write. */
+ mem_access.s.ba = 0; /* PCI Address bits [63:36]. */
+ cvmx_write_csr(CVMX_NPI_MEM_ACCESS_SUBID3, mem_access.u64);
+
+ /*
+ * Remap the Octeon BAR 2 above all 32 bit devices
+ * (0x8000000000ul). This is done here so it is remapped
+ * before the readl()'s below. We don't want BAR2 overlapping
+ * with BAR0/BAR1 during these reads.
+ */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG08, 0);
+ octeon_npi_write32(CVMX_NPI_PCI_CFG09, 0x80);
+
+ /* Disable the BAR1 movable mappings */
+ for (index = 0; index < 32; index++)
+ octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0);
+
+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) {
+ /* Remap the Octeon BAR 0 to 0-2GB */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG04, 0);
+ octeon_npi_write32(CVMX_NPI_PCI_CFG05, 0);
+
+ /*
+ * Remap the Octeon BAR 1 to map 2GB-4GB (minus the
+ * BAR 1 hole).
+ */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG06, 2ul << 30);
+ octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0);
+
+ /* Devices go after BAR1 */
+ octeon_pci_mem_resource.start =
+ OCTEON_PCI_MEMSPACE_OFFSET + (4ul << 30) -
+ (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
+ octeon_pci_mem_resource.end =
+ octeon_pci_mem_resource.start + (1ul << 30);
+ } else {
+ /* Remap the Octeon BAR 0 to map 128MB-(128MB+4KB) */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG04, 128ul << 20);
+ octeon_npi_write32(CVMX_NPI_PCI_CFG05, 0);
+
+ /* Remap the Octeon BAR 1 to map 0-128MB */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG06, 0);
+ octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0);
+
+ /* Devices go after BAR0 */
+ octeon_pci_mem_resource.start =
+ OCTEON_PCI_MEMSPACE_OFFSET + (128ul << 20) +
+ (4ul << 10);
+ octeon_pci_mem_resource.end =
+ octeon_pci_mem_resource.start + (1ul << 30);
+ }
+
+ register_pci_controller(&octeon_pci_controller);
+
+ /*
+ * Clear any errors that might be pending from before the bus
+ * was setup properly.
+ */
+ cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1);
+ return 0;
+}
+
+arch_initcall(octeon_pci_setup);
diff --git a/arch/mips/cavium-octeon/pcie.c b/arch/mips/cavium-octeon/pcie.c
new file mode 100644
index 000000000000..49d14081b3b5
--- /dev/null
+++ b/arch/mips/cavium-octeon/pcie.c
@@ -0,0 +1,1370 @@
+/*
+ * 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, 2008 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npei-defs.h>
+#include <asm/octeon/cvmx-pciercx-defs.h>
+#include <asm/octeon/cvmx-pescx-defs.h>
+#include <asm/octeon/cvmx-pexp-defs.h>
+#include <asm/octeon/cvmx-helper-errata.h>
+
+#include "pci-common.h"
+
+union cvmx_pcie_address {
+ uint64_t u64;
+ struct {
+ uint64_t upper:2; /* Normally 2 for XKPHYS */
+ uint64_t reserved_49_61:13; /* Must be zero */
+ uint64_t io:1; /* 1 for IO space access */
+ uint64_t did:5; /* PCIe DID = 3 */
+ uint64_t subdid:3; /* PCIe SubDID = 1 */
+ uint64_t reserved_36_39:4; /* Must be zero */
+ uint64_t es:2; /* Endian swap = 1 */
+ uint64_t port:2; /* PCIe port 0,1 */
+ uint64_t reserved_29_31:3; /* Must be zero */
+ /*
+ * Selects the type of the configuration request (0 = type 0,
+ * 1 = type 1).
+ */
+ uint64_t ty:1;
+ /* Target bus number sent in the ID in the request. */
+ uint64_t bus:8;
+ /*
+ * Target device number sent in the ID in the
+ * request. Note that Dev must be zero for type 0
+ * configuration requests.
+ */
+ uint64_t dev:5;
+ /* Target function number sent in the ID in the request. */
+ uint64_t func:3;
+ /*
+ * Selects a register in the configuration space of
+ * the target.
+ */
+ uint64_t reg:12;
+ } config;
+ struct {
+ uint64_t upper:2; /* Normally 2 for XKPHYS */
+ uint64_t reserved_49_61:13; /* Must be zero */
+ uint64_t io:1; /* 1 for IO space access */
+ uint64_t did:5; /* PCIe DID = 3 */
+ uint64_t subdid:3; /* PCIe SubDID = 2 */
+ uint64_t reserved_36_39:4; /* Must be zero */
+ uint64_t es:2; /* Endian swap = 1 */
+ uint64_t port:2; /* PCIe port 0,1 */
+ uint64_t address:32; /* PCIe IO address */
+ } io;
+ struct {
+ uint64_t upper:2; /* Normally 2 for XKPHYS */
+ uint64_t reserved_49_61:13; /* Must be zero */
+ uint64_t io:1; /* 1 for IO space access */
+ uint64_t did:5; /* PCIe DID = 3 */
+ uint64_t subdid:3; /* PCIe SubDID = 3-6 */
+ uint64_t reserved_36_39:4; /* Must be zero */
+ uint64_t address:36; /* PCIe Mem address */
+ } mem;
+};
+
+/**
+ * Return the Core virtual base address for PCIe IO access. IOs are
+ * read/written as an offset from this address.
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns 64bit Octeon IO base address for read/write
+ */
+static inline uint64_t cvmx_pcie_get_io_base_address(int pcie_port)
+{
+ union cvmx_pcie_address pcie_addr;
+ pcie_addr.u64 = 0;
+ pcie_addr.io.upper = 0;
+ pcie_addr.io.io = 1;
+ pcie_addr.io.did = 3;
+ pcie_addr.io.subdid = 2;
+ pcie_addr.io.es = 1;
+ pcie_addr.io.port = pcie_port;
+ return pcie_addr.u64;
+}
+
+/**
+ * Size of the IO address region returned at address
+ * cvmx_pcie_get_io_base_address()
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns Size of the IO window
+ */
+static inline uint64_t cvmx_pcie_get_io_size(int pcie_port)
+{
+ return 1ull << 32;
+}
+
+/**
+ * Return the Core virtual base address for PCIe MEM access. Memory is
+ * read/written as an offset from this address.
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns 64bit Octeon IO base address for read/write
+ */
+static inline uint64_t cvmx_pcie_get_mem_base_address(int pcie_port)
+{
+ union cvmx_pcie_address pcie_addr;
+ pcie_addr.u64 = 0;
+ pcie_addr.mem.upper = 0;
+ pcie_addr.mem.io = 1;
+ pcie_addr.mem.did = 3;
+ pcie_addr.mem.subdid = 3 + pcie_port;
+ return pcie_addr.u64;
+}
+
+/**
+ * Size of the Mem address region returned at address
+ * cvmx_pcie_get_mem_base_address()
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns Size of the Mem window
+ */
+static inline uint64_t cvmx_pcie_get_mem_size(int pcie_port)
+{
+ return 1ull << 36;
+}
+
+/**
+ * Read a PCIe config space register indirectly. This is used for
+ * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
+ *
+ * @pcie_port: PCIe port to read from
+ * @cfg_offset: Address to read
+ *
+ * Returns Value read
+ */
+static uint32_t cvmx_pcie_cfgx_read(int pcie_port, uint32_t cfg_offset)
+{
+ union cvmx_pescx_cfg_rd pescx_cfg_rd;
+ pescx_cfg_rd.u64 = 0;
+ pescx_cfg_rd.s.addr = cfg_offset;
+ cvmx_write_csr(CVMX_PESCX_CFG_RD(pcie_port), pescx_cfg_rd.u64);
+ pescx_cfg_rd.u64 = cvmx_read_csr(CVMX_PESCX_CFG_RD(pcie_port));
+ return pescx_cfg_rd.s.data;
+}
+
+/**
+ * Write a PCIe config space register indirectly. This is used for
+ * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
+ *
+ * @pcie_port: PCIe port to write to
+ * @cfg_offset: Address to write
+ * @val: Value to write
+ */
+static void cvmx_pcie_cfgx_write(int pcie_port, uint32_t cfg_offset,
+ uint32_t val)
+{
+ union cvmx_pescx_cfg_wr pescx_cfg_wr;
+ pescx_cfg_wr.u64 = 0;
+ pescx_cfg_wr.s.addr = cfg_offset;
+ pescx_cfg_wr.s.data = val;
+ cvmx_write_csr(CVMX_PESCX_CFG_WR(pcie_port), pescx_cfg_wr.u64);
+}
+
+/**
+ * Build a PCIe config space request address for a device
+ *
+ * @pcie_port: PCIe port to access
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ *
+ * Returns 64bit Octeon IO address
+ */
+static inline uint64_t __cvmx_pcie_build_config_addr(int pcie_port, int bus,
+ int dev, int fn, int reg)
+{
+ union cvmx_pcie_address pcie_addr;
+ union cvmx_pciercx_cfg006 pciercx_cfg006;
+
+ pciercx_cfg006.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port));
+ if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0))
+ return 0;
+
+ pcie_addr.u64 = 0;
+ pcie_addr.config.upper = 2;
+ pcie_addr.config.io = 1;
+ pcie_addr.config.did = 3;
+ pcie_addr.config.subdid = 1;
+ pcie_addr.config.es = 1;
+ pcie_addr.config.port = pcie_port;
+ pcie_addr.config.ty = (bus > pciercx_cfg006.s.pbnum);
+ pcie_addr.config.bus = bus;
+ pcie_addr.config.dev = dev;
+ pcie_addr.config.func = fn;
+ pcie_addr.config.reg = reg;
+ return pcie_addr.u64;
+}
+
+/**
+ * Read 8bits from a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ *
+ * Returns Result of the read
+ */
+static uint8_t cvmx_pcie_config_read8(int pcie_port, int bus, int dev,
+ int fn, int reg)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ return cvmx_read64_uint8(address);
+ else
+ return 0xff;
+}
+
+/**
+ * Read 16bits from a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ *
+ * Returns Result of the read
+ */
+static uint16_t cvmx_pcie_config_read16(int pcie_port, int bus, int dev,
+ int fn, int reg)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ return le16_to_cpu(cvmx_read64_uint16(address));
+ else
+ return 0xffff;
+}
+
+/**
+ * Read 32bits from a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ *
+ * Returns Result of the read
+ */
+static uint32_t cvmx_pcie_config_read32(int pcie_port, int bus, int dev,
+ int fn, int reg)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ return le32_to_cpu(cvmx_read64_uint32(address));
+ else
+ return 0xffffffff;
+}
+
+/**
+ * Write 8bits to a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ * @val: Value to write
+ */
+static void cvmx_pcie_config_write8(int pcie_port, int bus, int dev, int fn,
+ int reg, uint8_t val)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ cvmx_write64_uint8(address, val);
+}
+
+/**
+ * Write 16bits to a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ * @val: Value to write
+ */
+static void cvmx_pcie_config_write16(int pcie_port, int bus, int dev, int fn,
+ int reg, uint16_t val)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ cvmx_write64_uint16(address, cpu_to_le16(val));
+}
+
+/**
+ * Write 32bits to a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ * @val: Value to write
+ */
+static void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn,
+ int reg, uint32_t val)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ cvmx_write64_uint32(address, cpu_to_le32(val));
+}
+
+/**
+ * Initialize the RC config space CSRs
+ *
+ * @pcie_port: PCIe port to initialize
+ */
+static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
+{
+ union cvmx_pciercx_cfg030 pciercx_cfg030;
+ union cvmx_npei_ctl_status2 npei_ctl_status2;
+ union cvmx_pciercx_cfg070 pciercx_cfg070;
+ union cvmx_pciercx_cfg001 pciercx_cfg001;
+ union cvmx_pciercx_cfg032 pciercx_cfg032;
+ union cvmx_pciercx_cfg006 pciercx_cfg006;
+ union cvmx_pciercx_cfg008 pciercx_cfg008;
+ union cvmx_pciercx_cfg009 pciercx_cfg009;
+ union cvmx_pciercx_cfg010 pciercx_cfg010;
+ union cvmx_pciercx_cfg011 pciercx_cfg011;
+ union cvmx_pciercx_cfg035 pciercx_cfg035;
+ union cvmx_pciercx_cfg075 pciercx_cfg075;
+ union cvmx_pciercx_cfg034 pciercx_cfg034;
+
+ /* Max Payload Size (PCIE*_CFG030[MPS]) */
+ /* Max Read Request Size (PCIE*_CFG030[MRRS]) */
+ /* Relaxed-order, no-snoop enables (PCIE*_CFG030[RO_EN,NS_EN] */
+ /* Error Message Enables (PCIE*_CFG030[CE_EN,NFE_EN,FE_EN,UR_EN]) */
+ pciercx_cfg030.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG030(pcie_port));
+ /*
+ * Max payload size = 128 bytes for best Octeon DMA
+ * performance.
+ */
+ pciercx_cfg030.s.mps = 0;
+ /*
+ * Max read request size = 128 bytes for best Octeon DMA
+ * performance.
+ */
+ pciercx_cfg030.s.mrrs = 0;
+ /* Enable relaxed ordering. */
+ pciercx_cfg030.s.ro_en = 1;
+ /* Enable no snoop. */
+ pciercx_cfg030.s.ns_en = 1;
+ /* Correctable error reporting enable. */
+ pciercx_cfg030.s.ce_en = 1;
+ /* Non-fatal error reporting enable. */
+ pciercx_cfg030.s.nfe_en = 1;
+ /* Fatal error reporting enable. */
+ pciercx_cfg030.s.fe_en = 1;
+ /* Unsupported request reporting enable. */
+ pciercx_cfg030.s.ur_en = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG030(pcie_port),
+ pciercx_cfg030.u32);
+
+ /*
+ * Max Payload Size (NPEI_CTL_STATUS2[MPS]) must match
+ * PCIE*_CFG030[MPS]
+ *
+ * Max Read Request Size (NPEI_CTL_STATUS2[MRRS]) must not
+ * exceed PCIE*_CFG030[MRRS].
+ */
+ npei_ctl_status2.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS2);
+ /* Max payload size = 128 bytes for best Octeon DMA performance */
+ npei_ctl_status2.s.mps = 0;
+ /* Max read request size = 128 bytes for best Octeon DMA performance */
+ npei_ctl_status2.s.mrrs = 0;
+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS2, npei_ctl_status2.u64);
+
+ /* ECRC Generation (PCIE*_CFG070[GE,CE]) */
+ pciercx_cfg070.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG070(pcie_port));
+ pciercx_cfg070.s.ge = 1; /* ECRC generation enable. */
+ pciercx_cfg070.s.ce = 1; /* ECRC check enable. */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG070(pcie_port),
+ pciercx_cfg070.u32);
+
+ /*
+ * Access Enables (PCIE*_CFG001[MSAE,ME]) ME and MSAE should
+ * always be set.
+ *
+ * Interrupt Disable (PCIE*_CFG001[I_DIS]) System Error
+ * Message Enable (PCIE*_CFG001[SEE])
+ */
+ pciercx_cfg001.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG001(pcie_port));
+ pciercx_cfg001.s.msae = 1; /* Memory space enable. */
+ pciercx_cfg001.s.me = 1; /* Bus master enable. */
+ pciercx_cfg001.s.i_dis = 1; /* INTx assertion disable. */
+ pciercx_cfg001.s.see = 1; /* SERR# enable */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG001(pcie_port),
+ pciercx_cfg001.u32);
+
+ /* Advanced Error Recovery Message Enables */
+ /* (PCIE*_CFG066,PCIE*_CFG067,PCIE*_CFG069) */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG066(pcie_port), 0);
+ /* Use CVMX_PCIERCX_CFG067 hardware default */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG069(pcie_port), 0);
+
+ /* Active State Power Management (PCIE*_CFG032[ASLPC]) */
+ pciercx_cfg032.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ pciercx_cfg032.s.aslpc = 0; /* Active state Link PM control. */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG032(pcie_port),
+ pciercx_cfg032.u32);
+
+ /* Entrance Latencies (PCIE*_CFG451[L0EL,L1EL]) */
+
+ /*
+ * Link Width Mode (PCIERCn_CFG452[LME]) - Set during
+ * cvmx_pcie_rc_initialize_link()
+ *
+ * Primary Bus Number (PCIERCn_CFG006[PBNUM])
+ *
+ * We set the primary bus number to 1 so IDT bridges are
+ * happy. They don't like zero.
+ */
+ pciercx_cfg006.u32 = 0;
+ pciercx_cfg006.s.pbnum = 1;
+ pciercx_cfg006.s.sbnum = 1;
+ pciercx_cfg006.s.subbnum = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG006(pcie_port),
+ pciercx_cfg006.u32);
+
+ /*
+ * Memory-mapped I/O BAR (PCIERCn_CFG008)
+ * Most applications should disable the memory-mapped I/O BAR by
+ * setting PCIERCn_CFG008[ML_ADDR] < PCIERCn_CFG008[MB_ADDR]
+ */
+ pciercx_cfg008.u32 = 0;
+ pciercx_cfg008.s.mb_addr = 0x100;
+ pciercx_cfg008.s.ml_addr = 0;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG008(pcie_port),
+ pciercx_cfg008.u32);
+
+ /*
+ * Prefetchable BAR (PCIERCn_CFG009,PCIERCn_CFG010,PCIERCn_CFG011)
+ * Most applications should disable the prefetchable BAR by setting
+ * PCIERCn_CFG011[UMEM_LIMIT],PCIERCn_CFG009[LMEM_LIMIT] <
+ * PCIERCn_CFG010[UMEM_BASE],PCIERCn_CFG009[LMEM_BASE]
+ */
+ pciercx_cfg009.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG009(pcie_port));
+ pciercx_cfg010.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG010(pcie_port));
+ pciercx_cfg011.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG011(pcie_port));
+ pciercx_cfg009.s.lmem_base = 0x100;
+ pciercx_cfg009.s.lmem_limit = 0;
+ pciercx_cfg010.s.umem_base = 0x100;
+ pciercx_cfg011.s.umem_limit = 0;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG009(pcie_port),
+ pciercx_cfg009.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG010(pcie_port),
+ pciercx_cfg010.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG011(pcie_port),
+ pciercx_cfg011.u32);
+
+ /*
+ * System Error Interrupt Enables (PCIERCn_CFG035[SECEE,SEFEE,SENFEE])
+ * PME Interrupt Enables (PCIERCn_CFG035[PMEIE])
+ */
+ pciercx_cfg035.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG035(pcie_port));
+ /* System error on correctable error enable. */
+ pciercx_cfg035.s.secee = 1;
+ /* System error on fatal error enable. */
+ pciercx_cfg035.s.sefee = 1;
+ /* System error on non-fatal error enable. */
+ pciercx_cfg035.s.senfee = 1;
+ /* PME interrupt enable. */
+ pciercx_cfg035.s.pmeie = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG035(pcie_port),
+ pciercx_cfg035.u32);
+
+ /*
+ * Advanced Error Recovery Interrupt Enables
+ * (PCIERCn_CFG075[CERE,NFERE,FERE])
+ */
+ pciercx_cfg075.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG075(pcie_port));
+ /* Correctable error reporting enable. */
+ pciercx_cfg075.s.cere = 1;
+ /* Non-fatal error reporting enable. */
+ pciercx_cfg075.s.nfere = 1;
+ /* Fatal error reporting enable. */
+ pciercx_cfg075.s.fere = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG075(pcie_port),
+ pciercx_cfg075.u32);
+
+ /* HP Interrupt Enables (PCIERCn_CFG034[HPINT_EN],
+ * PCIERCn_CFG034[DLLS_EN,CCINT_EN])
+ */
+ pciercx_cfg034.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG034(pcie_port));
+ /* Hot-plug interrupt enable. */
+ pciercx_cfg034.s.hpint_en = 1;
+ /* Data Link Layer state changed enable */
+ pciercx_cfg034.s.dlls_en = 1;
+ /* Command completed interrupt enable. */
+ pciercx_cfg034.s.ccint_en = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG034(pcie_port),
+ pciercx_cfg034.u32);
+}
+
+/**
+ * Initialize a host mode PCIe link. This function takes a PCIe
+ * port from reset to a link up state. Software can then begin
+ * configuring the rest of the link.
+ *
+ * @pcie_port: PCIe port to initialize
+ *
+ * Returns Zero on success
+ */
+static int __cvmx_pcie_rc_initialize_link(int pcie_port)
+{
+ uint64_t start_cycle;
+ union cvmx_pescx_ctl_status pescx_ctl_status;
+ union cvmx_pciercx_cfg452 pciercx_cfg452;
+ union cvmx_pciercx_cfg032 pciercx_cfg032;
+ union cvmx_pciercx_cfg448 pciercx_cfg448;
+
+ /* Set the lane width */
+ pciercx_cfg452.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG452(pcie_port));
+ pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port));
+ if (pescx_ctl_status.s.qlm_cfg == 0) {
+ /* We're in 8 lane (56XX) or 4 lane (54XX) mode */
+ pciercx_cfg452.s.lme = 0xf;
+ } else {
+ /* We're in 4 lane (56XX) or 2 lane (52XX) mode */
+ pciercx_cfg452.s.lme = 0x7;
+ }
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG452(pcie_port),
+ pciercx_cfg452.u32);
+
+ /*
+ * CN52XX pass 1.x has an errata where length mismatches on UR
+ * responses can cause bus errors on 64bit memory
+ * reads. Turning off length error checking fixes this.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+ union cvmx_pciercx_cfg455 pciercx_cfg455;
+ pciercx_cfg455.u32 =
+ cvmx_pcie_cfgx_read(pcie_port,
+ CVMX_PCIERCX_CFG455(pcie_port));
+ pciercx_cfg455.s.m_cpl_len_err = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG455(pcie_port),
+ pciercx_cfg455.u32);
+ }
+
+ /* Lane swap needs to be manually enabled for CN52XX */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX) && (pcie_port == 1)) {
+ pescx_ctl_status.s.lane_swp = 1;
+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port),
+ pescx_ctl_status.u64);
+ }
+
+ /* Bring up the link */
+ pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port));
+ pescx_ctl_status.s.lnk_enb = 1;
+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port), pescx_ctl_status.u64);
+
+ /*
+ * CN52XX pass 1.0: Due to a bug in 2nd order CDR, it needs to
+ * be disabled.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
+ __cvmx_helper_errata_qlm_disable_2nd_order_cdr(0);
+
+ /* Wait for the link to come up */
+ cvmx_dprintf("PCIe: Waiting for port %d link\n", pcie_port);
+ start_cycle = cvmx_get_cycle();
+ do {
+ if (cvmx_get_cycle() - start_cycle >
+ 2 * cvmx_sysinfo_get()->cpu_clock_hz) {
+ cvmx_dprintf("PCIe: Port %d link timeout\n",
+ pcie_port);
+ return -1;
+ }
+ cvmx_wait(10000);
+ pciercx_cfg032.u32 =
+ cvmx_pcie_cfgx_read(pcie_port,
+ CVMX_PCIERCX_CFG032(pcie_port));
+ } while (pciercx_cfg032.s.dlla == 0);
+
+ /* Display the link status */
+ cvmx_dprintf("PCIe: Port %d link active, %d lanes\n", pcie_port,
+ pciercx_cfg032.s.nlw);
+
+ /*
+ * Update the Replay Time Limit. Empirically, some PCIe
+ * devices take a little longer to respond than expected under
+ * load. As a workaround for this we configure the Replay Time
+ * Limit to the value expected for a 512 byte MPS instead of
+ * our actual 256 byte MPS. The numbers below are directly
+ * from the PCIe spec table 3-4.
+ */
+ pciercx_cfg448.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG448(pcie_port));
+ switch (pciercx_cfg032.s.nlw) {
+ case 1: /* 1 lane */
+ pciercx_cfg448.s.rtl = 1677;
+ break;
+ case 2: /* 2 lanes */
+ pciercx_cfg448.s.rtl = 867;
+ break;
+ case 4: /* 4 lanes */
+ pciercx_cfg448.s.rtl = 462;
+ break;
+ case 8: /* 8 lanes */
+ pciercx_cfg448.s.rtl = 258;
+ break;
+ }
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG448(pcie_port),
+ pciercx_cfg448.u32);
+
+ return 0;
+}
+
+/**
+ * Initialize a PCIe port for use in host(RC) mode. It doesn't
+ * enumerate the bus.
+ *
+ * @pcie_port: PCIe port to initialize
+ *
+ * Returns Zero on success
+ */
+static int cvmx_pcie_rc_initialize(int pcie_port)
+{
+ int i;
+ union cvmx_ciu_soft_prst ciu_soft_prst;
+ union cvmx_pescx_bist_status pescx_bist_status;
+ union cvmx_pescx_bist_status2 pescx_bist_status2;
+ union cvmx_npei_ctl_status npei_ctl_status;
+ union cvmx_npei_mem_access_ctl npei_mem_access_ctl;
+ union cvmx_npei_mem_access_subidx mem_access_subid;
+ union cvmx_npei_dbg_data npei_dbg_data;
+ union cvmx_pescx_ctl_status2 pescx_ctl_status2;
+
+ /*
+ * Make sure we aren't trying to setup a target mode interface
+ * in host mode.
+ */
+ npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
+ if ((pcie_port == 0) && !npei_ctl_status.s.host_mode) {
+ cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() called "
+ "on port0, but port0 is not in host mode\n");
+ return -1;
+ }
+
+ /*
+ * Make sure a CN52XX isn't trying to bring up port 1 when it
+ * is disabled.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+ npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
+ if ((pcie_port == 1) && npei_dbg_data.cn52xx.qlm0_link_width) {
+ cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() "
+ "called on port1, but port1 is "
+ "disabled\n");
+ return -1;
+ }
+ }
+
+ /*
+ * PCIe switch arbitration mode. '0' == fixed priority NPEI,
+ * PCIe0, then PCIe1. '1' == round robin.
+ */
+ npei_ctl_status.s.arb = 1;
+ /* Allow up to 0x20 config retries */
+ npei_ctl_status.s.cfg_rtry = 0x20;
+ /*
+ * CN52XX pass1.x has an errata where P0_NTAGS and P1_NTAGS
+ * don't reset.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+ npei_ctl_status.s.p0_ntags = 0x20;
+ npei_ctl_status.s.p1_ntags = 0x20;
+ }
+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS, npei_ctl_status.u64);
+
+ /* Bring the PCIe out of reset */
+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBH5200) {
+ /*
+ * The EBH5200 board swapped the PCIe reset lines on
+ * the board. As a workaround for this bug, we bring
+ * both PCIe ports out of reset at the same time
+ * instead of on separate calls. So for port 0, we
+ * bring both out of reset and do nothing on port 1.
+ */
+ if (pcie_port == 0) {
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+ /*
+ * After a chip reset the PCIe will also be in
+ * reset. If it isn't, most likely someone is
+ * trying to init it again without a proper
+ * PCIe reset.
+ */
+ if (ciu_soft_prst.s.soft_prst == 0) {
+ /* Reset the ports */
+ ciu_soft_prst.s.soft_prst = 1;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST,
+ ciu_soft_prst.u64);
+ ciu_soft_prst.u64 =
+ cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ ciu_soft_prst.s.soft_prst = 1;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1,
+ ciu_soft_prst.u64);
+ /* Wait until pcie resets the ports. */
+ udelay(2000);
+ }
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ ciu_soft_prst.s.soft_prst = 0;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+ ciu_soft_prst.s.soft_prst = 0;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
+ }
+ } else {
+ /*
+ * The normal case: The PCIe ports are completely
+ * separate and can be brought out of reset
+ * independently.
+ */
+ if (pcie_port)
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ else
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+ /*
+ * After a chip reset the PCIe will also be in
+ * reset. If it isn't, most likely someone is trying
+ * to init it again without a proper PCIe reset.
+ */
+ if (ciu_soft_prst.s.soft_prst == 0) {
+ /* Reset the port */
+ ciu_soft_prst.s.soft_prst = 1;
+ if (pcie_port)
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1,
+ ciu_soft_prst.u64);
+ else
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST,
+ ciu_soft_prst.u64);
+ /* Wait until pcie resets the ports. */
+ udelay(2000);
+ }
+ if (pcie_port) {
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ ciu_soft_prst.s.soft_prst = 0;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
+ } else {
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+ ciu_soft_prst.s.soft_prst = 0;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
+ }
+ }
+
+ /*
+ * Wait for PCIe reset to complete. Due to errata PCIE-700, we
+ * don't poll PESCX_CTL_STATUS2[PCIERST], but simply wait a
+ * fixed number of cycles.
+ */
+ cvmx_wait(400000);
+
+ /* PESCX_BIST_STATUS2[PCLK_RUN] was missing on pass 1 of CN56XX and
+ CN52XX, so we only probe it on newer chips */
+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
+ && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+ /* Clear PCLK_RUN so we can check if the clock is running */
+ pescx_ctl_status2.u64 =
+ cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
+ pescx_ctl_status2.s.pclk_run = 1;
+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS2(pcie_port),
+ pescx_ctl_status2.u64);
+ /*
+ * Now that we cleared PCLK_RUN, wait for it to be set
+ * again telling us the clock is running.
+ */
+ if (CVMX_WAIT_FOR_FIELD64(CVMX_PESCX_CTL_STATUS2(pcie_port),
+ union cvmx_pescx_ctl_status2,
+ pclk_run, ==, 1, 10000)) {
+ cvmx_dprintf("PCIe: Port %d isn't clocked, skipping.\n",
+ pcie_port);
+ return -1;
+ }
+ }
+
+ /*
+ * Check and make sure PCIe came out of reset. If it doesn't
+ * the board probably hasn't wired the clocks up and the
+ * interface should be skipped.
+ */
+ pescx_ctl_status2.u64 =
+ cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
+ if (pescx_ctl_status2.s.pcierst) {
+ cvmx_dprintf("PCIe: Port %d stuck in reset, skipping.\n",
+ pcie_port);
+ return -1;
+ }
+
+ /*
+ * Check BIST2 status. If any bits are set skip this interface. This
+ * is an attempt to catch PCIE-813 on pass 1 parts.
+ */
+ pescx_bist_status2.u64 =
+ cvmx_read_csr(CVMX_PESCX_BIST_STATUS2(pcie_port));
+ if (pescx_bist_status2.u64) {
+ cvmx_dprintf("PCIe: Port %d BIST2 failed. Most likely this "
+ "port isn't hooked up, skipping.\n",
+ pcie_port);
+ return -1;
+ }
+
+ /* Check BIST status */
+ pescx_bist_status.u64 =
+ cvmx_read_csr(CVMX_PESCX_BIST_STATUS(pcie_port));
+ if (pescx_bist_status.u64)
+ cvmx_dprintf("PCIe: BIST FAILED for port %d (0x%016llx)\n",
+ pcie_port, CAST64(pescx_bist_status.u64));
+
+ /* Initialize the config space CSRs */
+ __cvmx_pcie_rc_initialize_config_space(pcie_port);
+
+ /* Bring the link up */
+ if (__cvmx_pcie_rc_initialize_link(pcie_port)) {
+ cvmx_dprintf
+ ("PCIe: ERROR: cvmx_pcie_rc_initialize_link() failed\n");
+ return -1;
+ }
+
+ /* Store merge control (NPEI_MEM_ACCESS_CTL[TIMER,MAX_WORD]) */
+ npei_mem_access_ctl.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL);
+ /* Allow 16 words to combine */
+ npei_mem_access_ctl.s.max_word = 0;
+ /* Wait up to 127 cycles for more data */
+ npei_mem_access_ctl.s.timer = 127;
+ cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL, npei_mem_access_ctl.u64);
+
+ /* Setup Mem access SubDIDs */
+ mem_access_subid.u64 = 0;
+ /* Port the request is sent to. */
+ mem_access_subid.s.port = pcie_port;
+ /* Due to an errata on pass 1 chips, no merging is allowed. */
+ mem_access_subid.s.nmerge = 1;
+ /* Endian-swap for Reads. */
+ mem_access_subid.s.esr = 1;
+ /* Endian-swap for Writes. */
+ mem_access_subid.s.esw = 1;
+ /* No Snoop for Reads. */
+ mem_access_subid.s.nsr = 1;
+ /* No Snoop for Writes. */
+ mem_access_subid.s.nsw = 1;
+ /* Disable Relaxed Ordering for Reads. */
+ mem_access_subid.s.ror = 0;
+ /* Disable Relaxed Ordering for Writes. */
+ mem_access_subid.s.row = 0;
+ /* PCIe Adddress Bits <63:34>. */
+ mem_access_subid.s.ba = 0;
+
+ /*
+ * Setup mem access 12-15 for port 0, 16-19 for port 1,
+ * supplying 36 bits of address space.
+ */
+ for (i = 12 + pcie_port * 4; i < 16 + pcie_port * 4; i++) {
+ cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(i),
+ mem_access_subid.u64);
+ /* Set each SUBID to extend the addressable range */
+ mem_access_subid.s.ba += 1;
+ }
+
+ /*
+ * Disable the peer to peer forwarding register. This must be
+ * setup by the OS after it enumerates the bus and assigns
+ * addresses to the PCIe busses.
+ */
+ for (i = 0; i < 4; i++) {
+ cvmx_write_csr(CVMX_PESCX_P2P_BARX_START(i, pcie_port), -1);
+ cvmx_write_csr(CVMX_PESCX_P2P_BARX_END(i, pcie_port), -1);
+ }
+
+ /* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
+ cvmx_write_csr(CVMX_PESCX_P2N_BAR0_START(pcie_port), 0);
+
+ /*
+ * Disable Octeon's BAR1. It isn't needed in RC mode since
+ * BAR2 maps all of memory. BAR2 also maps 256MB-512MB into
+ * the 2nd 256MB of memory.
+ */
+ cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), -1);
+
+ /*
+ * Set Octeon's BAR2 to decode 0-2^39. Bar0 and Bar1 take
+ * precedence where they overlap. It also overlaps with the
+ * device addresses, so make sure the peer to peer forwarding
+ * is set right.
+ */
+ cvmx_write_csr(CVMX_PESCX_P2N_BAR2_START(pcie_port), 0);
+
+ /*
+ * Setup BAR2 attributes
+ *
+ * Relaxed Ordering (NPEI_CTL_PORTn[PTLP_RO,CTLP_RO, WAIT_COM])
+ * - PTLP_RO,CTLP_RO should normally be set (except for debug).
+ * - WAIT_COM=0 will likely work for all applications.
+ *
+ * Load completion relaxed ordering (NPEI_CTL_PORTn[WAITL_COM]).
+ */
+ if (pcie_port) {
+ union cvmx_npei_ctl_port1 npei_ctl_port;
+ npei_ctl_port.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_PORT1);
+ npei_ctl_port.s.bar2_enb = 1;
+ npei_ctl_port.s.bar2_esx = 1;
+ npei_ctl_port.s.bar2_cax = 0;
+ npei_ctl_port.s.ptlp_ro = 1;
+ npei_ctl_port.s.ctlp_ro = 1;
+ npei_ctl_port.s.wait_com = 0;
+ npei_ctl_port.s.waitl_com = 0;
+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT1, npei_ctl_port.u64);
+ } else {
+ union cvmx_npei_ctl_port0 npei_ctl_port;
+ npei_ctl_port.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_PORT0);
+ npei_ctl_port.s.bar2_enb = 1;
+ npei_ctl_port.s.bar2_esx = 1;
+ npei_ctl_port.s.bar2_cax = 0;
+ npei_ctl_port.s.ptlp_ro = 1;
+ npei_ctl_port.s.ctlp_ro = 1;
+ npei_ctl_port.s.wait_com = 0;
+ npei_ctl_port.s.waitl_com = 0;
+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT0, npei_ctl_port.u64);
+ }
+ return 0;
+}
+
+
+/* Above was cvmx-pcie.c, below original pcie.c */
+
+
+/**
+ * Map a PCI device to the appropriate interrupt line
+ *
+ * @param dev The Linux PCI device structure for the device to map
+ * @param slot The slot number for this device on __BUS 0__. Linux
+ * enumerates through all the bridges and figures out the
+ * slot on Bus 0 where this device eventually hooks to.
+ * @param pin The PCI interrupt pin read from the device, then swizzled
+ * as it goes through each bridge.
+ * @return Interrupt number for the device
+ */
+int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev,
+ u8 slot, u8 pin)
+{
+ /*
+ * The EBH5600 board with the PCI to PCIe bridge mistakenly
+ * wires the first slot for both device id 2 and interrupt
+ * A. According to the PCI spec, device id 2 should be C. The
+ * following kludge attempts to fix this.
+ */
+ if (strstr(octeon_board_type_string(), "EBH5600") &&
+ dev->bus && dev->bus->parent) {
+ /*
+ * Iterate all the way up the device chain and find
+ * the root bus.
+ */
+ while (dev->bus && dev->bus->parent)
+ dev = to_pci_dev(dev->bus->bridge);
+ /* If the root bus is number 0 and the PEX 8114 is the
+ * root, assume we are behind the miswired bus. We
+ * need to correct the swizzle level by two. Yuck.
+ */
+ if ((dev->bus->number == 0) &&
+ (dev->vendor == 0x10b5) && (dev->device == 0x8114)) {
+ /*
+ * The pin field is one based, not zero. We
+ * need to swizzle it by minus two.
+ */
+ pin = ((pin - 3) & 3) + 1;
+ }
+ }
+ /*
+ * The -1 is because pin starts with one, not zero. It might
+ * be that this equation needs to include the slot number, but
+ * I don't have hardware to check that against.
+ */
+ return pin - 1 + OCTEON_IRQ_PCI_INT0;
+}
+
+/**
+ * Read a value from configuration space
+ *
+ * @param bus
+ * @param devfn
+ * @param reg
+ * @param size
+ * @param val
+ * @return
+ */
+static inline int octeon_pcie_read_config(int pcie_port, struct pci_bus *bus,
+ unsigned int devfn, int reg, int size,
+ u32 *val)
+{
+ union octeon_cvmemctl cvmmemctl;
+ union octeon_cvmemctl cvmmemctl_save;
+ int bus_number = bus->number;
+
+ /*
+ * We need to force the bus number to be zero on the root
+ * bus. Linux numbers the 2nd root bus to start after all
+ * buses on root 0.
+ */
+ if (bus->parent == NULL)
+ bus_number = 0;
+
+ /*
+ * PCIe only has a single device connected to Octeon. It is
+ * always device ID 0. Don't bother doing reads for other
+ * device IDs on the first segment.
+ */
+ if ((bus_number == 0) && (devfn >> 3 != 0))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+
+ /*
+ * The following is a workaround for the CN57XX, CN56XX,
+ * CN55XX, and CN54XX errata with PCIe config reads from non
+ * existent devices. These chips will hang the PCIe link if a
+ * config read is performed that causes a UR response.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_1)) {
+ /*
+ * For our EBH5600 board, port 0 has a bridge with two
+ * PCI-X slots. We need a new special checks to make
+ * sure we only probe valid stuff. The PCIe->PCI-X
+ * bridge only respondes to device ID 0, function
+ * 0-1
+ */
+ if ((bus_number == 0) && (devfn >= 2))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ /*
+ * The PCI-X slots are device ID 2,3. Choose one of
+ * the below "if" blocks based on what is plugged into
+ * the board.
+ */
+#if 1
+ /* Use this option if you aren't using either slot */
+ if (bus_number == 1)
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+#elif 0
+ /*
+ * Use this option if you are using the first slot but
+ * not the second.
+ */
+ if ((bus_number == 1) && (devfn >> 3 != 2))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+#elif 0
+ /*
+ * Use this option if you are using the second slot
+ * but not the first.
+ */
+ if ((bus_number == 1) && (devfn >> 3 != 3))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+#elif 0
+ /* Use this opion if you are using both slots */
+ if ((bus_number == 1) &&
+ !((devfn == (2 << 3)) || (devfn == (3 << 3))))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+#endif
+
+ /*
+ * Shorten the DID timeout so bus errors for PCIe
+ * config reads from non existent devices happen
+ * faster. This allows us to continue booting even if
+ * the above "if" checks are wrong. Once one of these
+ * errors happens, the PCIe port is dead.
+ */
+ cvmmemctl_save.u64 = __read_64bit_c0_register($11, 7);
+ cvmmemctl.u64 = cvmmemctl_save.u64;
+ cvmmemctl.s.didtto = 2;
+ __write_64bit_c0_register($11, 7, cvmmemctl.u64);
+ }
+
+ switch (size) {
+ case 4:
+ *val = cvmx_pcie_config_read32(pcie_port, bus_number,
+ devfn >> 3, devfn & 0x7, reg);
+ break;
+ case 2:
+ *val = cvmx_pcie_config_read16(pcie_port, bus_number,
+ devfn >> 3, devfn & 0x7, reg);
+ break;
+ case 1:
+ *val = cvmx_pcie_config_read8(pcie_port, bus_number, devfn >> 3,
+ devfn & 0x7, reg);
+ break;
+ default:
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ }
+
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_1))
+ __write_64bit_c0_register($11, 7, cvmmemctl_save.u64);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int octeon_pcie0_read_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 *val)
+{
+ return octeon_pcie_read_config(0, bus, devfn, reg, size, val);
+}
+
+static int octeon_pcie1_read_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 *val)
+{
+ return octeon_pcie_read_config(1, bus, devfn, reg, size, val);
+}
+
+
+
+/**
+ * Write a value to PCI configuration space
+ *
+ * @param bus
+ * @param devfn
+ * @param reg
+ * @param size
+ * @param val
+ * @return
+ */
+static inline int octeon_pcie_write_config(int pcie_port, struct pci_bus *bus,
+ unsigned int devfn, int reg,
+ int size, u32 val)
+{
+ int bus_number = bus->number;
+ /*
+ * We need to force the bus number to be zero on the root
+ * bus. Linux numbers the 2nd root bus to start after all
+ * busses on root 0.
+ */
+ if (bus->parent == NULL)
+ bus_number = 0;
+
+ switch (size) {
+ case 4:
+ cvmx_pcie_config_write32(pcie_port, bus_number, devfn >> 3,
+ devfn & 0x7, reg, val);
+ return PCIBIOS_SUCCESSFUL;
+ case 2:
+ cvmx_pcie_config_write16(pcie_port, bus_number, devfn >> 3,
+ devfn & 0x7, reg, val);
+ return PCIBIOS_SUCCESSFUL;
+ case 1:
+ cvmx_pcie_config_write8(pcie_port, bus_number, devfn >> 3,
+ devfn & 0x7, reg, val);
+ return PCIBIOS_SUCCESSFUL;
+ }
+#if PCI_CONFIG_SPACE_DELAY
+ udelay(PCI_CONFIG_SPACE_DELAY);
+#endif
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
+
+static int octeon_pcie0_write_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 val)
+{
+ return octeon_pcie_write_config(0, bus, devfn, reg, size, val);
+}
+
+static int octeon_pcie1_write_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 val)
+{
+ return octeon_pcie_write_config(1, bus, devfn, reg, size, val);
+}
+
+static struct pci_ops octeon_pcie0_ops = {
+ octeon_pcie0_read_config,
+ octeon_pcie0_write_config,
+};
+
+static struct resource octeon_pcie0_mem_resource = {
+ .name = "Octeon PCIe0 MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource octeon_pcie0_io_resource = {
+ .name = "Octeon PCIe0 IO",
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller octeon_pcie0_controller = {
+ .pci_ops = &octeon_pcie0_ops,
+ .mem_resource = &octeon_pcie0_mem_resource,
+ .io_resource = &octeon_pcie0_io_resource,
+};
+
+static struct pci_ops octeon_pcie1_ops = {
+ octeon_pcie1_read_config,
+ octeon_pcie1_write_config,
+};
+
+static struct resource octeon_pcie1_mem_resource = {
+ .name = "Octeon PCIe1 MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource octeon_pcie1_io_resource = {
+ .name = "Octeon PCIe1 IO",
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller octeon_pcie1_controller = {
+ .pci_ops = &octeon_pcie1_ops,
+ .mem_resource = &octeon_pcie1_mem_resource,
+ .io_resource = &octeon_pcie1_io_resource,
+};
+
+
+/**
+ * Initialize the Octeon PCIe controllers
+ *
+ * @return
+ */
+static int __init octeon_pcie_setup(void)
+{
+ union cvmx_npei_ctl_status npei_ctl_status;
+ int result;
+
+ /* These chips don't have PCIe */
+ if (!octeon_has_feature(OCTEON_FEATURE_PCIE))
+ return 0;
+
+ /* Point pcibios_map_irq() to the PCIe version of it */
+ octeon_pcibios_map_irq = octeon_pcie_pcibios_map_irq;
+
+ /* Use the PCIe based DMA mappings */
+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE;
+
+ /*
+ * PCIe I/O range. It is based on port 0 but includes up until
+ * port 1's end.
+ */
+ set_io_port_base(CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(0)));
+ ioport_resource.start = 0;
+ ioport_resource.end =
+ cvmx_pcie_get_io_base_address(1) -
+ cvmx_pcie_get_io_base_address(0) + cvmx_pcie_get_io_size(1) - 1;
+
+ npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
+ if (npei_ctl_status.s.host_mode) {
+ pr_notice("PCIe: Initializing port 0\n");
+ result = cvmx_pcie_rc_initialize(0);
+ if (result == 0) {
+ /* Memory offsets are physical addresses */
+ octeon_pcie0_controller.mem_offset =
+ cvmx_pcie_get_mem_base_address(0);
+ /* IO offsets are Mips virtual addresses */
+ octeon_pcie0_controller.io_map_base =
+ CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address
+ (0));
+ octeon_pcie0_controller.io_offset = 0;
+ /*
+ * To keep things similar to PCI, we start
+ * device addresses at the same place as PCI
+ * uisng big bar support. This normally
+ * translates to 4GB-256MB, which is the same
+ * as most x86 PCs.
+ */
+ octeon_pcie0_controller.mem_resource->start =
+ cvmx_pcie_get_mem_base_address(0) +
+ (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
+ octeon_pcie0_controller.mem_resource->end =
+ cvmx_pcie_get_mem_base_address(0) +
+ cvmx_pcie_get_mem_size(0) - 1;
+ /*
+ * Ports must be above 16KB for the ISA bus
+ * filtering in the PCI-X to PCI bridge.
+ */
+ octeon_pcie0_controller.io_resource->start = 4 << 10;
+ octeon_pcie0_controller.io_resource->end =
+ cvmx_pcie_get_io_size(0) - 1;
+ register_pci_controller(&octeon_pcie0_controller);
+ }
+ } else {
+ pr_notice("PCIe: Port 0 in endpoint mode, skipping.\n");
+ }
+
+ /* Skip the 2nd port on CN52XX if port 0 is in 4 lane mode */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+ union cvmx_npei_dbg_data npei_dbg_data;
+ npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
+ if (npei_dbg_data.cn52xx.qlm0_link_width)
+ return 0;
+ }
+
+ pr_notice("PCIe: Initializing port 1\n");
+ result = cvmx_pcie_rc_initialize(1);
+ if (result == 0) {
+ /* Memory offsets are physical addresses */
+ octeon_pcie1_controller.mem_offset =
+ cvmx_pcie_get_mem_base_address(1);
+ /* IO offsets are Mips virtual addresses */
+ octeon_pcie1_controller.io_map_base =
+ CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(1));
+ octeon_pcie1_controller.io_offset =
+ cvmx_pcie_get_io_base_address(1) -
+ cvmx_pcie_get_io_base_address(0);
+ /*
+ * To keep things similar to PCI, we start device
+ * addresses at the same place as PCI uisng big bar
+ * support. This normally translates to 4GB-256MB,
+ * which is the same as most x86 PCs.
+ */
+ octeon_pcie1_controller.mem_resource->start =
+ cvmx_pcie_get_mem_base_address(1) + (4ul << 30) -
+ (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
+ octeon_pcie1_controller.mem_resource->end =
+ cvmx_pcie_get_mem_base_address(1) +
+ cvmx_pcie_get_mem_size(1) - 1;
+ /*
+ * Ports must be above 16KB for the ISA bus filtering
+ * in the PCI-X to PCI bridge.
+ */
+ octeon_pcie1_controller.io_resource->start =
+ cvmx_pcie_get_io_base_address(1) -
+ cvmx_pcie_get_io_base_address(0);
+ octeon_pcie1_controller.io_resource->end =
+ octeon_pcie1_controller.io_resource->start +
+ cvmx_pcie_get_io_size(1) - 1;
+ register_pci_controller(&octeon_pcie1_controller);
+ }
+ return 0;
+}
+
+arch_initcall(octeon_pcie_setup);
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index 783da855a2e3..d6d35b2e5fe8 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -963,7 +963,7 @@ CONFIG_EEPROM_LEGACY=y
CONFIG_SENSORS_PCF8574=y
# CONFIG_PCF8575 is not set
CONFIG_SENSORS_PCF8591=y
-CONFIG_SENSORS_MAX6875=y
+CONFIG_EEPROM_MAX6875=y
# CONFIG_SENSORS_TSL2550 is not set
CONFIG_I2C_DEBUG_CORE=y
CONFIG_I2C_DEBUG_ALGO=y
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index 8426d3b9501c..fadb351d249b 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -1849,7 +1849,7 @@ CONFIG_EEPROM_LEGACY=m
CONFIG_SENSORS_PCF8574=m
CONFIG_SENSORS_PCA9539=m
CONFIG_SENSORS_PCF8591=m
-CONFIG_SENSORS_MAX6875=m
+CONFIG_EEPROM_MAX6875=m
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index 3214ade02d10..4f1eed107b08 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -49,7 +49,7 @@ static inline void smtc_im_ack_irq(unsigned int irq)
#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
#include <linux/cpumask.h>
-extern void plat_set_irq_affinity(unsigned int irq,
+extern int plat_set_irq_affinity(unsigned int irq,
const struct cpumask *affinity);
extern void smtc_forward_irq(unsigned int irq);
diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
index f30fce92aabb..17d579471ec4 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
@@ -30,12 +30,14 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
return octeon_map_dma_mem(dev, page_address(page), PAGE_SIZE);
}
-static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
{
return dma_addr;
}
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
{
octeon_unmap_dma_mem(dev, dma_addr);
}
diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h
index 36c611b6c597..8da98073e952 100644
--- a/arch/mips/include/asm/mach-generic/dma-coherence.h
+++ b/arch/mips/include/asm/mach-generic/dma-coherence.h
@@ -23,12 +23,14 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
return page_to_phys(page);
}
-static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
{
return dma_addr;
}
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
{
}
diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h b/arch/mips/include/asm/mach-ip27/dma-coherence.h
index 4c21bfca10c3..d3d04018a858 100644
--- a/arch/mips/include/asm/mach-ip27/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ip27/dma-coherence.h
@@ -33,12 +33,14 @@ static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
return pa;
}
-static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
{
return dma_addr & ~(0xffUL << 56);
}
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
{
}
diff --git a/arch/mips/include/asm/mach-ip32/dma-coherence.h b/arch/mips/include/asm/mach-ip32/dma-coherence.h
index 7ae40f4b1c80..37855955b313 100644
--- a/arch/mips/include/asm/mach-ip32/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ip32/dma-coherence.h
@@ -50,7 +50,8 @@ static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
}
/* This is almost certainly wrong but it's what dma-ip32.c used to use */
-static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
{
unsigned long addr = dma_addr & RAM_OFFSET_MASK;
@@ -60,7 +61,8 @@ static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return addr;
}
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
{
}
diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h b/arch/mips/include/asm/mach-jazz/dma-coherence.h
index 1c7cd27efa7b..f93aee59454a 100644
--- a/arch/mips/include/asm/mach-jazz/dma-coherence.h
+++ b/arch/mips/include/asm/mach-jazz/dma-coherence.h
@@ -22,12 +22,14 @@ static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
return vdma_alloc(page_to_phys(page), PAGE_SIZE);
}
-static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
{
return vdma_log2phys(dma_addr);
}
-static void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
{
vdma_free(dma_addr);
}
diff --git a/arch/mips/include/asm/mach-lemote/dma-coherence.h b/arch/mips/include/asm/mach-lemote/dma-coherence.h
index 38fad7dfe7da..c8de5e750777 100644
--- a/arch/mips/include/asm/mach-lemote/dma-coherence.h
+++ b/arch/mips/include/asm/mach-lemote/dma-coherence.h
@@ -25,12 +25,14 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
return page_to_phys(page) | 0x80000000;
}
-static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
{
return dma_addr & 0x7fffffff;
}
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
{
}
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-errata.h b/arch/mips/include/asm/octeon/cvmx-helper-errata.h
new file mode 100644
index 000000000000..5fc99189ff58
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-helper-errata.h
@@ -0,0 +1,33 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_HELPER_ERRATA_H__
+#define __CVMX_HELPER_ERRATA_H__
+
+extern void __cvmx_helper_errata_qlm_disable_2nd_order_cdr(int qlm);
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-jtag.h b/arch/mips/include/asm/octeon/cvmx-helper-jtag.h
new file mode 100644
index 000000000000..29f016ddb895
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-helper-jtag.h
@@ -0,0 +1,43 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Helper utilities for qlm_jtag.
+ *
+ */
+
+#ifndef __CVMX_HELPER_JTAG_H__
+#define __CVMX_HELPER_JTAG_H__
+
+extern void cvmx_helper_qlm_jtag_init(void);
+extern uint32_t cvmx_helper_qlm_jtag_shift(int qlm, int bits, uint32_t data);
+extern void cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits);
+extern void cvmx_helper_qlm_jtag_update(int qlm);
+
+#endif /* __CVMX_HELPER_JTAG_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-npei-defs.h b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
new file mode 100644
index 000000000000..4b347bb8ce80
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
@@ -0,0 +1,2560 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_NPEI_DEFS_H__
+#define __CVMX_NPEI_DEFS_H__
+
+#define CVMX_NPEI_BAR1_INDEXX(offset) \
+ (0x0000000000000000ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_BIST_STATUS \
+ (0x0000000000000580ull)
+#define CVMX_NPEI_BIST_STATUS2 \
+ (0x0000000000000680ull)
+#define CVMX_NPEI_CTL_PORT0 \
+ (0x0000000000000250ull)
+#define CVMX_NPEI_CTL_PORT1 \
+ (0x0000000000000260ull)
+#define CVMX_NPEI_CTL_STATUS \
+ (0x0000000000000570ull)
+#define CVMX_NPEI_CTL_STATUS2 \
+ (0x0000000000003C00ull)
+#define CVMX_NPEI_DATA_OUT_CNT \
+ (0x00000000000005F0ull)
+#define CVMX_NPEI_DBG_DATA \
+ (0x0000000000000510ull)
+#define CVMX_NPEI_DBG_SELECT \
+ (0x0000000000000500ull)
+#define CVMX_NPEI_DMA0_INT_LEVEL \
+ (0x00000000000005C0ull)
+#define CVMX_NPEI_DMA1_INT_LEVEL \
+ (0x00000000000005D0ull)
+#define CVMX_NPEI_DMAX_COUNTS(offset) \
+ (0x0000000000000450ull + (((offset) & 7) * 16))
+#define CVMX_NPEI_DMAX_DBELL(offset) \
+ (0x00000000000003B0ull + (((offset) & 7) * 16))
+#define CVMX_NPEI_DMAX_IBUFF_SADDR(offset) \
+ (0x0000000000000400ull + (((offset) & 7) * 16))
+#define CVMX_NPEI_DMAX_NADDR(offset) \
+ (0x00000000000004A0ull + (((offset) & 7) * 16))
+#define CVMX_NPEI_DMA_CNTS \
+ (0x00000000000005E0ull)
+#define CVMX_NPEI_DMA_CONTROL \
+ (0x00000000000003A0ull)
+#define CVMX_NPEI_INT_A_ENB \
+ (0x0000000000000560ull)
+#define CVMX_NPEI_INT_A_ENB2 \
+ (0x0000000000003CE0ull)
+#define CVMX_NPEI_INT_A_SUM \
+ (0x0000000000000550ull)
+#define CVMX_NPEI_INT_ENB \
+ (0x0000000000000540ull)
+#define CVMX_NPEI_INT_ENB2 \
+ (0x0000000000003CD0ull)
+#define CVMX_NPEI_INT_INFO \
+ (0x0000000000000590ull)
+#define CVMX_NPEI_INT_SUM \
+ (0x0000000000000530ull)
+#define CVMX_NPEI_INT_SUM2 \
+ (0x0000000000003CC0ull)
+#define CVMX_NPEI_LAST_WIN_RDATA0 \
+ (0x0000000000000600ull)
+#define CVMX_NPEI_LAST_WIN_RDATA1 \
+ (0x0000000000000610ull)
+#define CVMX_NPEI_MEM_ACCESS_CTL \
+ (0x00000000000004F0ull)
+#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) \
+ (0x0000000000000340ull + (((offset) & 31) * 16) - 16 * 12)
+#define CVMX_NPEI_MSI_ENB0 \
+ (0x0000000000003C50ull)
+#define CVMX_NPEI_MSI_ENB1 \
+ (0x0000000000003C60ull)
+#define CVMX_NPEI_MSI_ENB2 \
+ (0x0000000000003C70ull)
+#define CVMX_NPEI_MSI_ENB3 \
+ (0x0000000000003C80ull)
+#define CVMX_NPEI_MSI_RCV0 \
+ (0x0000000000003C10ull)
+#define CVMX_NPEI_MSI_RCV1 \
+ (0x0000000000003C20ull)
+#define CVMX_NPEI_MSI_RCV2 \
+ (0x0000000000003C30ull)
+#define CVMX_NPEI_MSI_RCV3 \
+ (0x0000000000003C40ull)
+#define CVMX_NPEI_MSI_RD_MAP \
+ (0x0000000000003CA0ull)
+#define CVMX_NPEI_MSI_W1C_ENB0 \
+ (0x0000000000003CF0ull)
+#define CVMX_NPEI_MSI_W1C_ENB1 \
+ (0x0000000000003D00ull)
+#define CVMX_NPEI_MSI_W1C_ENB2 \
+ (0x0000000000003D10ull)
+#define CVMX_NPEI_MSI_W1C_ENB3 \
+ (0x0000000000003D20ull)
+#define CVMX_NPEI_MSI_W1S_ENB0 \
+ (0x0000000000003D30ull)
+#define CVMX_NPEI_MSI_W1S_ENB1 \
+ (0x0000000000003D40ull)
+#define CVMX_NPEI_MSI_W1S_ENB2 \
+ (0x0000000000003D50ull)
+#define CVMX_NPEI_MSI_W1S_ENB3 \
+ (0x0000000000003D60ull)
+#define CVMX_NPEI_MSI_WR_MAP \
+ (0x0000000000003C90ull)
+#define CVMX_NPEI_PCIE_CREDIT_CNT \
+ (0x0000000000003D70ull)
+#define CVMX_NPEI_PCIE_MSI_RCV \
+ (0x0000000000003CB0ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B1 \
+ (0x0000000000000650ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B2 \
+ (0x0000000000000660ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B3 \
+ (0x0000000000000670ull)
+#define CVMX_NPEI_PKTX_CNTS(offset) \
+ (0x0000000000002400ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_INSTR_BADDR(offset) \
+ (0x0000000000002800ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \
+ (0x0000000000002C00ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \
+ (0x0000000000003000ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_INSTR_HEADER(offset) \
+ (0x0000000000003400ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_IN_BP(offset) \
+ (0x0000000000003800ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_SLIST_BADDR(offset) \
+ (0x0000000000001400ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \
+ (0x0000000000001800ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \
+ (0x0000000000001C00ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKT_CNT_INT \
+ (0x0000000000001110ull)
+#define CVMX_NPEI_PKT_CNT_INT_ENB \
+ (0x0000000000001130ull)
+#define CVMX_NPEI_PKT_DATA_OUT_ES \
+ (0x00000000000010B0ull)
+#define CVMX_NPEI_PKT_DATA_OUT_NS \
+ (0x00000000000010A0ull)
+#define CVMX_NPEI_PKT_DATA_OUT_ROR \
+ (0x0000000000001090ull)
+#define CVMX_NPEI_PKT_DPADDR \
+ (0x0000000000001080ull)
+#define CVMX_NPEI_PKT_INPUT_CONTROL \
+ (0x0000000000001150ull)
+#define CVMX_NPEI_PKT_INSTR_ENB \
+ (0x0000000000001000ull)
+#define CVMX_NPEI_PKT_INSTR_RD_SIZE \
+ (0x0000000000001190ull)
+#define CVMX_NPEI_PKT_INSTR_SIZE \
+ (0x0000000000001020ull)
+#define CVMX_NPEI_PKT_INT_LEVELS \
+ (0x0000000000001100ull)
+#define CVMX_NPEI_PKT_IN_BP \
+ (0x00000000000006B0ull)
+#define CVMX_NPEI_PKT_IN_DONEX_CNTS(offset) \
+ (0x0000000000002000ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKT_IN_INSTR_COUNTS \
+ (0x00000000000006A0ull)
+#define CVMX_NPEI_PKT_IN_PCIE_PORT \
+ (0x00000000000011A0ull)
+#define CVMX_NPEI_PKT_IPTR \
+ (0x0000000000001070ull)
+#define CVMX_NPEI_PKT_OUTPUT_WMARK \
+ (0x0000000000001160ull)
+#define CVMX_NPEI_PKT_OUT_BMODE \
+ (0x00000000000010D0ull)
+#define CVMX_NPEI_PKT_OUT_ENB \
+ (0x0000000000001010ull)
+#define CVMX_NPEI_PKT_PCIE_PORT \
+ (0x00000000000010E0ull)
+#define CVMX_NPEI_PKT_PORT_IN_RST \
+ (0x0000000000000690ull)
+#define CVMX_NPEI_PKT_SLIST_ES \
+ (0x0000000000001050ull)
+#define CVMX_NPEI_PKT_SLIST_ID_SIZE \
+ (0x0000000000001180ull)
+#define CVMX_NPEI_PKT_SLIST_NS \
+ (0x0000000000001040ull)
+#define CVMX_NPEI_PKT_SLIST_ROR \
+ (0x0000000000001030ull)
+#define CVMX_NPEI_PKT_TIME_INT \
+ (0x0000000000001120ull)
+#define CVMX_NPEI_PKT_TIME_INT_ENB \
+ (0x0000000000001140ull)
+#define CVMX_NPEI_RSL_INT_BLOCKS \
+ (0x0000000000000520ull)
+#define CVMX_NPEI_SCRATCH_1 \
+ (0x0000000000000270ull)
+#define CVMX_NPEI_STATE1 \
+ (0x0000000000000620ull)
+#define CVMX_NPEI_STATE2 \
+ (0x0000000000000630ull)
+#define CVMX_NPEI_STATE3 \
+ (0x0000000000000640ull)
+#define CVMX_NPEI_WINDOW_CTL \
+ (0x0000000000000380ull)
+#define CVMX_NPEI_WIN_RD_ADDR \
+ (0x0000000000000210ull)
+#define CVMX_NPEI_WIN_RD_DATA \
+ (0x0000000000000240ull)
+#define CVMX_NPEI_WIN_WR_ADDR \
+ (0x0000000000000200ull)
+#define CVMX_NPEI_WIN_WR_DATA \
+ (0x0000000000000220ull)
+#define CVMX_NPEI_WIN_WR_MASK \
+ (0x0000000000000230ull)
+
+union cvmx_npei_bar1_indexx {
+ uint32_t u32;
+ struct cvmx_npei_bar1_indexx_s {
+ uint32_t reserved_18_31:14;
+ uint32_t addr_idx:14;
+ uint32_t ca:1;
+ uint32_t end_swp:2;
+ uint32_t addr_v:1;
+ } s;
+ struct cvmx_npei_bar1_indexx_s cn52xx;
+ struct cvmx_npei_bar1_indexx_s cn52xxp1;
+ struct cvmx_npei_bar1_indexx_s cn56xx;
+ struct cvmx_npei_bar1_indexx_s cn56xxp1;
+};
+
+union cvmx_npei_bist_status {
+ uint64_t u64;
+ struct cvmx_npei_bist_status_s {
+ uint64_t pkt_rdf:1;
+ uint64_t pkt_pmem:1;
+ uint64_t pkt_p1:1;
+ uint64_t reserved_60_60:1;
+ uint64_t pcr_gim:1;
+ uint64_t pkt_pif:1;
+ uint64_t pcsr_int:1;
+ uint64_t pcsr_im:1;
+ uint64_t pcsr_cnt:1;
+ uint64_t pcsr_id:1;
+ uint64_t pcsr_sl:1;
+ uint64_t reserved_50_52:3;
+ uint64_t pkt_ind:1;
+ uint64_t pkt_slm:1;
+ uint64_t reserved_36_47:12;
+ uint64_t d0_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t reserved_31_31:1;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t p2n1_po:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t csm0:1;
+ uint64_t csm1:1;
+ uint64_t dif0:1;
+ uint64_t dif1:1;
+ uint64_t dif2:1;
+ uint64_t dif3:1;
+ uint64_t reserved_2_2:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } s;
+ struct cvmx_npei_bist_status_cn52xx {
+ uint64_t pkt_rdf:1;
+ uint64_t pkt_pmem:1;
+ uint64_t pkt_p1:1;
+ uint64_t reserved_60_60:1;
+ uint64_t pcr_gim:1;
+ uint64_t pkt_pif:1;
+ uint64_t pcsr_int:1;
+ uint64_t pcsr_im:1;
+ uint64_t pcsr_cnt:1;
+ uint64_t pcsr_id:1;
+ uint64_t pcsr_sl:1;
+ uint64_t pkt_imem:1;
+ uint64_t pkt_pfm:1;
+ uint64_t pkt_pof:1;
+ uint64_t reserved_48_49:2;
+ uint64_t pkt_pop0:1;
+ uint64_t pkt_pop1:1;
+ uint64_t d0_mem:1;
+ uint64_t d1_mem:1;
+ uint64_t d2_mem:1;
+ uint64_t d3_mem:1;
+ uint64_t d4_mem:1;
+ uint64_t ds_mem:1;
+ uint64_t reserved_36_39:4;
+ uint64_t d0_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t d4_pst:1;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t p2n1_po:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t csm0:1;
+ uint64_t csm1:1;
+ uint64_t dif0:1;
+ uint64_t dif1:1;
+ uint64_t dif2:1;
+ uint64_t dif3:1;
+ uint64_t dif4:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } cn52xx;
+ struct cvmx_npei_bist_status_cn52xxp1 {
+ uint64_t reserved_46_63:18;
+ uint64_t d0_mem0:1;
+ uint64_t d1_mem1:1;
+ uint64_t d2_mem2:1;
+ uint64_t d3_mem3:1;
+ uint64_t dr0_mem:1;
+ uint64_t d0_mem:1;
+ uint64_t d1_mem:1;
+ uint64_t d2_mem:1;
+ uint64_t d3_mem:1;
+ uint64_t dr1_mem:1;
+ uint64_t d0_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t dr2_mem:1;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t p2n1_po:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t csm0:1;
+ uint64_t csm1:1;
+ uint64_t dif0:1;
+ uint64_t dif1:1;
+ uint64_t dif2:1;
+ uint64_t dif3:1;
+ uint64_t dr3_mem:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } cn52xxp1;
+ struct cvmx_npei_bist_status_cn56xx {
+ uint64_t pkt_rdf:1;
+ uint64_t reserved_60_62:3;
+ uint64_t pcr_gim:1;
+ uint64_t pkt_pif:1;
+ uint64_t pcsr_int:1;
+ uint64_t pcsr_im:1;
+ uint64_t pcsr_cnt:1;
+ uint64_t pcsr_id:1;
+ uint64_t pcsr_sl:1;
+ uint64_t pkt_imem:1;
+ uint64_t pkt_pfm:1;
+ uint64_t pkt_pof:1;
+ uint64_t reserved_48_49:2;
+ uint64_t pkt_pop0:1;
+ uint64_t pkt_pop1:1;
+ uint64_t d0_mem:1;
+ uint64_t d1_mem:1;
+ uint64_t d2_mem:1;
+ uint64_t d3_mem:1;
+ uint64_t d4_mem:1;
+ uint64_t ds_mem:1;
+ uint64_t reserved_36_39:4;
+ uint64_t d0_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t d4_pst:1;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t p2n1_po:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t csm0:1;
+ uint64_t csm1:1;
+ uint64_t dif0:1;
+ uint64_t dif1:1;
+ uint64_t dif2:1;
+ uint64_t dif3:1;
+ uint64_t dif4:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } cn56xx;
+ struct cvmx_npei_bist_status_cn56xxp1 {
+ uint64_t reserved_58_63:6;
+ uint64_t pcsr_int:1;
+ uint64_t pcsr_im:1;
+ uint64_t pcsr_cnt:1;
+ uint64_t pcsr_id:1;
+ uint64_t pcsr_sl:1;
+ uint64_t pkt_pout:1;
+ uint64_t pkt_imem:1;
+ uint64_t pkt_cntm:1;
+ uint64_t pkt_ind:1;
+ uint64_t pkt_slm:1;
+ uint64_t pkt_odf:1;
+ uint64_t pkt_oif:1;
+ uint64_t pkt_out:1;
+ uint64_t pkt_i0:1;
+ uint64_t pkt_i1:1;
+ uint64_t pkt_s0:1;
+ uint64_t pkt_s1:1;
+ uint64_t d0_mem:1;
+ uint64_t d1_mem:1;
+ uint64_t d2_mem:1;
+ uint64_t d3_mem:1;
+ uint64_t d4_mem:1;
+ uint64_t d0_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t d4_pst:1;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t p2n1_po:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t csm0:1;
+ uint64_t csm1:1;
+ uint64_t dif0:1;
+ uint64_t dif1:1;
+ uint64_t dif2:1;
+ uint64_t dif3:1;
+ uint64_t dif4:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } cn56xxp1;
+};
+
+union cvmx_npei_bist_status2 {
+ uint64_t u64;
+ struct cvmx_npei_bist_status2_s {
+ uint64_t reserved_5_63:59;
+ uint64_t psc_p0:1;
+ uint64_t psc_p1:1;
+ uint64_t pkt_gd:1;
+ uint64_t pkt_gl:1;
+ uint64_t pkt_blk:1;
+ } s;
+ struct cvmx_npei_bist_status2_s cn52xx;
+ struct cvmx_npei_bist_status2_s cn56xx;
+};
+
+union cvmx_npei_ctl_port0 {
+ uint64_t u64;
+ struct cvmx_npei_ctl_port0_s {
+ uint64_t reserved_21_63:43;
+ uint64_t waitl_com:1;
+ uint64_t intd:1;
+ uint64_t intc:1;
+ uint64_t intb:1;
+ uint64_t inta:1;
+ uint64_t intd_map:2;
+ uint64_t intc_map:2;
+ uint64_t intb_map:2;
+ uint64_t inta_map:2;
+ uint64_t ctlp_ro:1;
+ uint64_t reserved_6_6:1;
+ uint64_t ptlp_ro:1;
+ uint64_t bar2_enb:1;
+ uint64_t bar2_esx:2;
+ uint64_t bar2_cax:1;
+ uint64_t wait_com:1;
+ } s;
+ struct cvmx_npei_ctl_port0_s cn52xx;
+ struct cvmx_npei_ctl_port0_s cn52xxp1;
+ struct cvmx_npei_ctl_port0_s cn56xx;
+ struct cvmx_npei_ctl_port0_s cn56xxp1;
+};
+
+union cvmx_npei_ctl_port1 {
+ uint64_t u64;
+ struct cvmx_npei_ctl_port1_s {
+ uint64_t reserved_21_63:43;
+ uint64_t waitl_com:1;
+ uint64_t intd:1;
+ uint64_t intc:1;
+ uint64_t intb:1;
+ uint64_t inta:1;
+ uint64_t intd_map:2;
+ uint64_t intc_map:2;
+ uint64_t intb_map:2;
+ uint64_t inta_map:2;
+ uint64_t ctlp_ro:1;
+ uint64_t reserved_6_6:1;
+ uint64_t ptlp_ro:1;
+ uint64_t bar2_enb:1;
+ uint64_t bar2_esx:2;
+ uint64_t bar2_cax:1;
+ uint64_t wait_com:1;
+ } s;
+ struct cvmx_npei_ctl_port1_s cn52xx;
+ struct cvmx_npei_ctl_port1_s cn52xxp1;
+ struct cvmx_npei_ctl_port1_s cn56xx;
+ struct cvmx_npei_ctl_port1_s cn56xxp1;
+};
+
+union cvmx_npei_ctl_status {
+ uint64_t u64;
+ struct cvmx_npei_ctl_status_s {
+ uint64_t reserved_44_63:20;
+ uint64_t p1_ntags:6;
+ uint64_t p0_ntags:6;
+ uint64_t cfg_rtry:16;
+ uint64_t ring_en:1;
+ uint64_t lnk_rst:1;
+ uint64_t arb:1;
+ uint64_t pkt_bp:4;
+ uint64_t host_mode:1;
+ uint64_t chip_rev:8;
+ } s;
+ struct cvmx_npei_ctl_status_s cn52xx;
+ struct cvmx_npei_ctl_status_cn52xxp1 {
+ uint64_t reserved_44_63:20;
+ uint64_t p1_ntags:6;
+ uint64_t p0_ntags:6;
+ uint64_t cfg_rtry:16;
+ uint64_t reserved_15_15:1;
+ uint64_t lnk_rst:1;
+ uint64_t arb:1;
+ uint64_t reserved_9_12:4;
+ uint64_t host_mode:1;
+ uint64_t chip_rev:8;
+ } cn52xxp1;
+ struct cvmx_npei_ctl_status_s cn56xx;
+ struct cvmx_npei_ctl_status_cn56xxp1 {
+ uint64_t reserved_16_63:48;
+ uint64_t ring_en:1;
+ uint64_t lnk_rst:1;
+ uint64_t arb:1;
+ uint64_t pkt_bp:4;
+ uint64_t host_mode:1;
+ uint64_t chip_rev:8;
+ } cn56xxp1;
+};
+
+union cvmx_npei_ctl_status2 {
+ uint64_t u64;
+ struct cvmx_npei_ctl_status2_s {
+ uint64_t reserved_16_63:48;
+ uint64_t mps:1;
+ uint64_t mrrs:3;
+ uint64_t c1_w_flt:1;
+ uint64_t c0_w_flt:1;
+ uint64_t c1_b1_s:3;
+ uint64_t c0_b1_s:3;
+ uint64_t c1_wi_d:1;
+ uint64_t c1_b0_d:1;
+ uint64_t c0_wi_d:1;
+ uint64_t c0_b0_d:1;
+ } s;
+ struct cvmx_npei_ctl_status2_s cn52xx;
+ struct cvmx_npei_ctl_status2_s cn52xxp1;
+ struct cvmx_npei_ctl_status2_s cn56xx;
+ struct cvmx_npei_ctl_status2_s cn56xxp1;
+};
+
+union cvmx_npei_data_out_cnt {
+ uint64_t u64;
+ struct cvmx_npei_data_out_cnt_s {
+ uint64_t reserved_44_63:20;
+ uint64_t p1_ucnt:16;
+ uint64_t p1_fcnt:6;
+ uint64_t p0_ucnt:16;
+ uint64_t p0_fcnt:6;
+ } s;
+ struct cvmx_npei_data_out_cnt_s cn52xx;
+ struct cvmx_npei_data_out_cnt_s cn52xxp1;
+ struct cvmx_npei_data_out_cnt_s cn56xx;
+ struct cvmx_npei_data_out_cnt_s cn56xxp1;
+};
+
+union cvmx_npei_dbg_data {
+ uint64_t u64;
+ struct cvmx_npei_dbg_data_s {
+ uint64_t reserved_28_63:36;
+ uint64_t qlm0_rev_lanes:1;
+ uint64_t reserved_25_26:2;
+ uint64_t qlm1_spd:2;
+ uint64_t c_mul:5;
+ uint64_t dsel_ext:1;
+ uint64_t data:17;
+ } s;
+ struct cvmx_npei_dbg_data_cn52xx {
+ uint64_t reserved_29_63:35;
+ uint64_t qlm0_link_width:1;
+ uint64_t qlm0_rev_lanes:1;
+ uint64_t qlm1_mode:2;
+ uint64_t qlm1_spd:2;
+ uint64_t c_mul:5;
+ uint64_t dsel_ext:1;
+ uint64_t data:17;
+ } cn52xx;
+ struct cvmx_npei_dbg_data_cn52xx cn52xxp1;
+ struct cvmx_npei_dbg_data_cn56xx {
+ uint64_t reserved_29_63:35;
+ uint64_t qlm2_rev_lanes:1;
+ uint64_t qlm0_rev_lanes:1;
+ uint64_t qlm3_spd:2;
+ uint64_t qlm1_spd:2;
+ uint64_t c_mul:5;
+ uint64_t dsel_ext:1;
+ uint64_t data:17;
+ } cn56xx;
+ struct cvmx_npei_dbg_data_cn56xx cn56xxp1;
+};
+
+union cvmx_npei_dbg_select {
+ uint64_t u64;
+ struct cvmx_npei_dbg_select_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dbg_sel:16;
+ } s;
+ struct cvmx_npei_dbg_select_s cn52xx;
+ struct cvmx_npei_dbg_select_s cn52xxp1;
+ struct cvmx_npei_dbg_select_s cn56xx;
+ struct cvmx_npei_dbg_select_s cn56xxp1;
+};
+
+union cvmx_npei_dmax_counts {
+ uint64_t u64;
+ struct cvmx_npei_dmax_counts_s {
+ uint64_t reserved_39_63:25;
+ uint64_t fcnt:7;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_npei_dmax_counts_s cn52xx;
+ struct cvmx_npei_dmax_counts_s cn52xxp1;
+ struct cvmx_npei_dmax_counts_s cn56xx;
+ struct cvmx_npei_dmax_counts_s cn56xxp1;
+};
+
+union cvmx_npei_dmax_dbell {
+ uint32_t u32;
+ struct cvmx_npei_dmax_dbell_s {
+ uint32_t reserved_16_31:16;
+ uint32_t dbell:16;
+ } s;
+ struct cvmx_npei_dmax_dbell_s cn52xx;
+ struct cvmx_npei_dmax_dbell_s cn52xxp1;
+ struct cvmx_npei_dmax_dbell_s cn56xx;
+ struct cvmx_npei_dmax_dbell_s cn56xxp1;
+};
+
+union cvmx_npei_dmax_ibuff_saddr {
+ uint64_t u64;
+ struct cvmx_npei_dmax_ibuff_saddr_s {
+ uint64_t reserved_37_63:27;
+ uint64_t idle:1;
+ uint64_t saddr:29;
+ uint64_t reserved_0_6:7;
+ } s;
+ struct cvmx_npei_dmax_ibuff_saddr_cn52xx {
+ uint64_t reserved_36_63:28;
+ uint64_t saddr:29;
+ uint64_t reserved_0_6:7;
+ } cn52xx;
+ struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn52xxp1;
+ struct cvmx_npei_dmax_ibuff_saddr_s cn56xx;
+ struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn56xxp1;
+};
+
+union cvmx_npei_dmax_naddr {
+ uint64_t u64;
+ struct cvmx_npei_dmax_naddr_s {
+ uint64_t reserved_36_63:28;
+ uint64_t addr:36;
+ } s;
+ struct cvmx_npei_dmax_naddr_s cn52xx;
+ struct cvmx_npei_dmax_naddr_s cn52xxp1;
+ struct cvmx_npei_dmax_naddr_s cn56xx;
+ struct cvmx_npei_dmax_naddr_s cn56xxp1;
+};
+
+union cvmx_npei_dma0_int_level {
+ uint64_t u64;
+ struct cvmx_npei_dma0_int_level_s {
+ uint64_t time:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_dma0_int_level_s cn52xx;
+ struct cvmx_npei_dma0_int_level_s cn52xxp1;
+ struct cvmx_npei_dma0_int_level_s cn56xx;
+ struct cvmx_npei_dma0_int_level_s cn56xxp1;
+};
+
+union cvmx_npei_dma1_int_level {
+ uint64_t u64;
+ struct cvmx_npei_dma1_int_level_s {
+ uint64_t time:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_dma1_int_level_s cn52xx;
+ struct cvmx_npei_dma1_int_level_s cn52xxp1;
+ struct cvmx_npei_dma1_int_level_s cn56xx;
+ struct cvmx_npei_dma1_int_level_s cn56xxp1;
+};
+
+union cvmx_npei_dma_cnts {
+ uint64_t u64;
+ struct cvmx_npei_dma_cnts_s {
+ uint64_t dma1:32;
+ uint64_t dma0:32;
+ } s;
+ struct cvmx_npei_dma_cnts_s cn52xx;
+ struct cvmx_npei_dma_cnts_s cn52xxp1;
+ struct cvmx_npei_dma_cnts_s cn56xx;
+ struct cvmx_npei_dma_cnts_s cn56xxp1;
+};
+
+union cvmx_npei_dma_control {
+ uint64_t u64;
+ struct cvmx_npei_dma_control_s {
+ uint64_t reserved_39_63:25;
+ uint64_t dma4_enb:1;
+ uint64_t dma3_enb:1;
+ uint64_t dma2_enb:1;
+ uint64_t dma1_enb:1;
+ uint64_t dma0_enb:1;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t csize:14;
+ } s;
+ struct cvmx_npei_dma_control_s cn52xx;
+ struct cvmx_npei_dma_control_cn52xxp1 {
+ uint64_t reserved_38_63:26;
+ uint64_t dma3_enb:1;
+ uint64_t dma2_enb:1;
+ uint64_t dma1_enb:1;
+ uint64_t dma0_enb:1;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t csize:14;
+ } cn52xxp1;
+ struct cvmx_npei_dma_control_s cn56xx;
+ struct cvmx_npei_dma_control_s cn56xxp1;
+};
+
+union cvmx_npei_int_a_enb {
+ uint64_t u64;
+ struct cvmx_npei_int_a_enb_s {
+ uint64_t reserved_10_63:54;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t p1_rdlk:1;
+ uint64_t p0_rdlk:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } s;
+ struct cvmx_npei_int_a_enb_cn52xx {
+ uint64_t reserved_8_63:56;
+ uint64_t p1_rdlk:1;
+ uint64_t p0_rdlk:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } cn52xx;
+ struct cvmx_npei_int_a_enb_cn52xxp1 {
+ uint64_t reserved_2_63:62;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_a_enb_s cn56xx;
+};
+
+union cvmx_npei_int_a_enb2 {
+ uint64_t u64;
+ struct cvmx_npei_int_a_enb2_s {
+ uint64_t reserved_10_63:54;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t p1_rdlk:1;
+ uint64_t p0_rdlk:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } s;
+ struct cvmx_npei_int_a_enb2_cn52xx {
+ uint64_t reserved_8_63:56;
+ uint64_t p1_rdlk:1;
+ uint64_t p0_rdlk:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t reserved_0_1:2;
+ } cn52xx;
+ struct cvmx_npei_int_a_enb2_cn52xxp1 {
+ uint64_t reserved_2_63:62;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_a_enb2_s cn56xx;
+};
+
+union cvmx_npei_int_a_sum {
+ uint64_t u64;
+ struct cvmx_npei_int_a_sum_s {
+ uint64_t reserved_10_63:54;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t p1_rdlk:1;
+ uint64_t p0_rdlk:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } s;
+ struct cvmx_npei_int_a_sum_cn52xx {
+ uint64_t reserved_8_63:56;
+ uint64_t p1_rdlk:1;
+ uint64_t p0_rdlk:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } cn52xx;
+ struct cvmx_npei_int_a_sum_cn52xxp1 {
+ uint64_t reserved_2_63:62;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_a_sum_s cn56xx;
+};
+
+union cvmx_npei_int_enb {
+ uint64_t u64;
+ struct cvmx_npei_int_enb_s {
+ uint64_t mio_inta:1;
+ uint64_t reserved_62_62:1;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npei_int_enb_s cn52xx;
+ struct cvmx_npei_int_enb_cn52xxp1 {
+ uint64_t mio_inta:1;
+ uint64_t reserved_62_62:1;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_enb_s cn56xx;
+ struct cvmx_npei_int_enb_cn56xxp1 {
+ uint64_t mio_inta:1;
+ uint64_t reserved_61_62:2;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t reserved_29_29:1;
+ uint64_t c1_se:1;
+ uint64_t reserved_27_27:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t reserved_22_22:1;
+ uint64_t c0_se:1;
+ uint64_t reserved_20_20:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn56xxp1;
+};
+
+union cvmx_npei_int_enb2 {
+ uint64_t u64;
+ struct cvmx_npei_int_enb2_s {
+ uint64_t reserved_62_63:2;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npei_int_enb2_s cn52xx;
+ struct cvmx_npei_int_enb2_cn52xxp1 {
+ uint64_t reserved_62_63:2;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_enb2_s cn56xx;
+ struct cvmx_npei_int_enb2_cn56xxp1 {
+ uint64_t reserved_61_63:3;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t reserved_29_29:1;
+ uint64_t c1_se:1;
+ uint64_t reserved_27_27:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t reserved_22_22:1;
+ uint64_t c0_se:1;
+ uint64_t reserved_20_20:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn56xxp1;
+};
+
+union cvmx_npei_int_info {
+ uint64_t u64;
+ struct cvmx_npei_int_info_s {
+ uint64_t reserved_12_63:52;
+ uint64_t pidbof:6;
+ uint64_t psldbof:6;
+ } s;
+ struct cvmx_npei_int_info_s cn52xx;
+ struct cvmx_npei_int_info_s cn56xx;
+ struct cvmx_npei_int_info_s cn56xxp1;
+};
+
+union cvmx_npei_int_sum {
+ uint64_t u64;
+ struct cvmx_npei_int_sum_s {
+ uint64_t mio_inta:1;
+ uint64_t reserved_62_62:1;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npei_int_sum_s cn52xx;
+ struct cvmx_npei_int_sum_cn52xxp1 {
+ uint64_t mio_inta:1;
+ uint64_t reserved_62_62:1;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t reserved_15_18:4;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_sum_s cn56xx;
+ struct cvmx_npei_int_sum_cn56xxp1 {
+ uint64_t mio_inta:1;
+ uint64_t reserved_61_62:2;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t reserved_29_29:1;
+ uint64_t c1_se:1;
+ uint64_t reserved_27_27:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t reserved_22_22:1;
+ uint64_t c0_se:1;
+ uint64_t reserved_20_20:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn56xxp1;
+};
+
+union cvmx_npei_int_sum2 {
+ uint64_t u64;
+ struct cvmx_npei_int_sum2_s {
+ uint64_t mio_inta:1;
+ uint64_t reserved_62_62:1;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t reserved_15_18:4;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npei_int_sum2_s cn52xx;
+ struct cvmx_npei_int_sum2_s cn52xxp1;
+ struct cvmx_npei_int_sum2_s cn56xx;
+};
+
+union cvmx_npei_last_win_rdata0 {
+ uint64_t u64;
+ struct cvmx_npei_last_win_rdata0_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_npei_last_win_rdata0_s cn52xx;
+ struct cvmx_npei_last_win_rdata0_s cn52xxp1;
+ struct cvmx_npei_last_win_rdata0_s cn56xx;
+ struct cvmx_npei_last_win_rdata0_s cn56xxp1;
+};
+
+union cvmx_npei_last_win_rdata1 {
+ uint64_t u64;
+ struct cvmx_npei_last_win_rdata1_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_npei_last_win_rdata1_s cn52xx;
+ struct cvmx_npei_last_win_rdata1_s cn52xxp1;
+ struct cvmx_npei_last_win_rdata1_s cn56xx;
+ struct cvmx_npei_last_win_rdata1_s cn56xxp1;
+};
+
+union cvmx_npei_mem_access_ctl {
+ uint64_t u64;
+ struct cvmx_npei_mem_access_ctl_s {
+ uint64_t reserved_14_63:50;
+ uint64_t max_word:4;
+ uint64_t timer:10;
+ } s;
+ struct cvmx_npei_mem_access_ctl_s cn52xx;
+ struct cvmx_npei_mem_access_ctl_s cn52xxp1;
+ struct cvmx_npei_mem_access_ctl_s cn56xx;
+ struct cvmx_npei_mem_access_ctl_s cn56xxp1;
+};
+
+union cvmx_npei_mem_access_subidx {
+ uint64_t u64;
+ struct cvmx_npei_mem_access_subidx_s {
+ uint64_t reserved_42_63:22;
+ uint64_t zero:1;
+ uint64_t port:2;
+ uint64_t nmerge:1;
+ uint64_t esr:2;
+ uint64_t esw:2;
+ uint64_t nsr:1;
+ uint64_t nsw:1;
+ uint64_t ror:1;
+ uint64_t row:1;
+ uint64_t ba:30;
+ } s;
+ struct cvmx_npei_mem_access_subidx_s cn52xx;
+ struct cvmx_npei_mem_access_subidx_s cn52xxp1;
+ struct cvmx_npei_mem_access_subidx_s cn56xx;
+ struct cvmx_npei_mem_access_subidx_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb0 {
+ uint64_t u64;
+ struct cvmx_npei_msi_enb0_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_npei_msi_enb0_s cn52xx;
+ struct cvmx_npei_msi_enb0_s cn52xxp1;
+ struct cvmx_npei_msi_enb0_s cn56xx;
+ struct cvmx_npei_msi_enb0_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb1 {
+ uint64_t u64;
+ struct cvmx_npei_msi_enb1_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_npei_msi_enb1_s cn52xx;
+ struct cvmx_npei_msi_enb1_s cn52xxp1;
+ struct cvmx_npei_msi_enb1_s cn56xx;
+ struct cvmx_npei_msi_enb1_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb2 {
+ uint64_t u64;
+ struct cvmx_npei_msi_enb2_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_npei_msi_enb2_s cn52xx;
+ struct cvmx_npei_msi_enb2_s cn52xxp1;
+ struct cvmx_npei_msi_enb2_s cn56xx;
+ struct cvmx_npei_msi_enb2_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb3 {
+ uint64_t u64;
+ struct cvmx_npei_msi_enb3_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_npei_msi_enb3_s cn52xx;
+ struct cvmx_npei_msi_enb3_s cn52xxp1;
+ struct cvmx_npei_msi_enb3_s cn56xx;
+ struct cvmx_npei_msi_enb3_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv0 {
+ uint64_t u64;
+ struct cvmx_npei_msi_rcv0_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_npei_msi_rcv0_s cn52xx;
+ struct cvmx_npei_msi_rcv0_s cn52xxp1;
+ struct cvmx_npei_msi_rcv0_s cn56xx;
+ struct cvmx_npei_msi_rcv0_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv1 {
+ uint64_t u64;
+ struct cvmx_npei_msi_rcv1_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_npei_msi_rcv1_s cn52xx;
+ struct cvmx_npei_msi_rcv1_s cn52xxp1;
+ struct cvmx_npei_msi_rcv1_s cn56xx;
+ struct cvmx_npei_msi_rcv1_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv2 {
+ uint64_t u64;
+ struct cvmx_npei_msi_rcv2_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_npei_msi_rcv2_s cn52xx;
+ struct cvmx_npei_msi_rcv2_s cn52xxp1;
+ struct cvmx_npei_msi_rcv2_s cn56xx;
+ struct cvmx_npei_msi_rcv2_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv3 {
+ uint64_t u64;
+ struct cvmx_npei_msi_rcv3_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_npei_msi_rcv3_s cn52xx;
+ struct cvmx_npei_msi_rcv3_s cn52xxp1;
+ struct cvmx_npei_msi_rcv3_s cn56xx;
+ struct cvmx_npei_msi_rcv3_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rd_map {
+ uint64_t u64;
+ struct cvmx_npei_msi_rd_map_s {
+ uint64_t reserved_16_63:48;
+ uint64_t rd_int:8;
+ uint64_t msi_int:8;
+ } s;
+ struct cvmx_npei_msi_rd_map_s cn52xx;
+ struct cvmx_npei_msi_rd_map_s cn52xxp1;
+ struct cvmx_npei_msi_rd_map_s cn56xx;
+ struct cvmx_npei_msi_rd_map_s cn56xxp1;
+};
+
+union cvmx_npei_msi_w1c_enb0 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1c_enb0_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_npei_msi_w1c_enb0_s cn52xx;
+ struct cvmx_npei_msi_w1c_enb0_s cn56xx;
+};
+
+union cvmx_npei_msi_w1c_enb1 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1c_enb1_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_npei_msi_w1c_enb1_s cn52xx;
+ struct cvmx_npei_msi_w1c_enb1_s cn56xx;
+};
+
+union cvmx_npei_msi_w1c_enb2 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1c_enb2_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_npei_msi_w1c_enb2_s cn52xx;
+ struct cvmx_npei_msi_w1c_enb2_s cn56xx;
+};
+
+union cvmx_npei_msi_w1c_enb3 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1c_enb3_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_npei_msi_w1c_enb3_s cn52xx;
+ struct cvmx_npei_msi_w1c_enb3_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb0 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1s_enb0_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_npei_msi_w1s_enb0_s cn52xx;
+ struct cvmx_npei_msi_w1s_enb0_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb1 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1s_enb1_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_npei_msi_w1s_enb1_s cn52xx;
+ struct cvmx_npei_msi_w1s_enb1_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb2 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1s_enb2_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_npei_msi_w1s_enb2_s cn52xx;
+ struct cvmx_npei_msi_w1s_enb2_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb3 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1s_enb3_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_npei_msi_w1s_enb3_s cn52xx;
+ struct cvmx_npei_msi_w1s_enb3_s cn56xx;
+};
+
+union cvmx_npei_msi_wr_map {
+ uint64_t u64;
+ struct cvmx_npei_msi_wr_map_s {
+ uint64_t reserved_16_63:48;
+ uint64_t ciu_int:8;
+ uint64_t msi_int:8;
+ } s;
+ struct cvmx_npei_msi_wr_map_s cn52xx;
+ struct cvmx_npei_msi_wr_map_s cn52xxp1;
+ struct cvmx_npei_msi_wr_map_s cn56xx;
+ struct cvmx_npei_msi_wr_map_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_credit_cnt {
+ uint64_t u64;
+ struct cvmx_npei_pcie_credit_cnt_s {
+ uint64_t reserved_48_63:16;
+ uint64_t p1_ccnt:8;
+ uint64_t p1_ncnt:8;
+ uint64_t p1_pcnt:8;
+ uint64_t p0_ccnt:8;
+ uint64_t p0_ncnt:8;
+ uint64_t p0_pcnt:8;
+ } s;
+ struct cvmx_npei_pcie_credit_cnt_s cn52xx;
+ struct cvmx_npei_pcie_credit_cnt_s cn56xx;
+};
+
+union cvmx_npei_pcie_msi_rcv {
+ uint64_t u64;
+ struct cvmx_npei_pcie_msi_rcv_s {
+ uint64_t reserved_8_63:56;
+ uint64_t intr:8;
+ } s;
+ struct cvmx_npei_pcie_msi_rcv_s cn52xx;
+ struct cvmx_npei_pcie_msi_rcv_s cn52xxp1;
+ struct cvmx_npei_pcie_msi_rcv_s cn56xx;
+ struct cvmx_npei_pcie_msi_rcv_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_msi_rcv_b1 {
+ uint64_t u64;
+ struct cvmx_npei_pcie_msi_rcv_b1_s {
+ uint64_t reserved_16_63:48;
+ uint64_t intr:8;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_npei_pcie_msi_rcv_b1_s cn52xx;
+ struct cvmx_npei_pcie_msi_rcv_b1_s cn52xxp1;
+ struct cvmx_npei_pcie_msi_rcv_b1_s cn56xx;
+ struct cvmx_npei_pcie_msi_rcv_b1_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_msi_rcv_b2 {
+ uint64_t u64;
+ struct cvmx_npei_pcie_msi_rcv_b2_s {
+ uint64_t reserved_24_63:40;
+ uint64_t intr:8;
+ uint64_t reserved_0_15:16;
+ } s;
+ struct cvmx_npei_pcie_msi_rcv_b2_s cn52xx;
+ struct cvmx_npei_pcie_msi_rcv_b2_s cn52xxp1;
+ struct cvmx_npei_pcie_msi_rcv_b2_s cn56xx;
+ struct cvmx_npei_pcie_msi_rcv_b2_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_msi_rcv_b3 {
+ uint64_t u64;
+ struct cvmx_npei_pcie_msi_rcv_b3_s {
+ uint64_t reserved_32_63:32;
+ uint64_t intr:8;
+ uint64_t reserved_0_23:24;
+ } s;
+ struct cvmx_npei_pcie_msi_rcv_b3_s cn52xx;
+ struct cvmx_npei_pcie_msi_rcv_b3_s cn52xxp1;
+ struct cvmx_npei_pcie_msi_rcv_b3_s cn56xx;
+ struct cvmx_npei_pcie_msi_rcv_b3_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_cnts {
+ uint64_t u64;
+ struct cvmx_npei_pktx_cnts_s {
+ uint64_t reserved_54_63:10;
+ uint64_t timer:22;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_pktx_cnts_s cn52xx;
+ struct cvmx_npei_pktx_cnts_s cn56xx;
+ struct cvmx_npei_pktx_cnts_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_in_bp {
+ uint64_t u64;
+ struct cvmx_npei_pktx_in_bp_s {
+ uint64_t wmark:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_pktx_in_bp_s cn52xx;
+ struct cvmx_npei_pktx_in_bp_s cn56xx;
+ struct cvmx_npei_pktx_in_bp_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_instr_baddr {
+ uint64_t u64;
+ struct cvmx_npei_pktx_instr_baddr_s {
+ uint64_t addr:61;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_npei_pktx_instr_baddr_s cn52xx;
+ struct cvmx_npei_pktx_instr_baddr_s cn56xx;
+ struct cvmx_npei_pktx_instr_baddr_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_instr_baoff_dbell {
+ uint64_t u64;
+ struct cvmx_npei_pktx_instr_baoff_dbell_s {
+ uint64_t aoff:32;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_npei_pktx_instr_baoff_dbell_s cn52xx;
+ struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xx;
+ struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_instr_fifo_rsize {
+ uint64_t u64;
+ struct cvmx_npei_pktx_instr_fifo_rsize_s {
+ uint64_t max:9;
+ uint64_t rrp:9;
+ uint64_t wrp:9;
+ uint64_t fcnt:5;
+ uint64_t rsize:32;
+ } s;
+ struct cvmx_npei_pktx_instr_fifo_rsize_s cn52xx;
+ struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xx;
+ struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_instr_header {
+ uint64_t u64;
+ struct cvmx_npei_pktx_instr_header_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t rsv_f:5;
+ uint64_t rparmode:2;
+ uint64_t rsv_e:1;
+ uint64_t rskp_len:7;
+ uint64_t rsv_d:6;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_c:5;
+ uint64_t par_mode:2;
+ uint64_t rsv_b:1;
+ uint64_t skp_len:7;
+ uint64_t rsv_a:6;
+ } s;
+ struct cvmx_npei_pktx_instr_header_s cn52xx;
+ struct cvmx_npei_pktx_instr_header_s cn56xx;
+ struct cvmx_npei_pktx_instr_header_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_slist_baddr {
+ uint64_t u64;
+ struct cvmx_npei_pktx_slist_baddr_s {
+ uint64_t addr:60;
+ uint64_t reserved_0_3:4;
+ } s;
+ struct cvmx_npei_pktx_slist_baddr_s cn52xx;
+ struct cvmx_npei_pktx_slist_baddr_s cn56xx;
+ struct cvmx_npei_pktx_slist_baddr_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_slist_baoff_dbell {
+ uint64_t u64;
+ struct cvmx_npei_pktx_slist_baoff_dbell_s {
+ uint64_t aoff:32;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_npei_pktx_slist_baoff_dbell_s cn52xx;
+ struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xx;
+ struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_slist_fifo_rsize {
+ uint64_t u64;
+ struct cvmx_npei_pktx_slist_fifo_rsize_s {
+ uint64_t reserved_32_63:32;
+ uint64_t rsize:32;
+ } s;
+ struct cvmx_npei_pktx_slist_fifo_rsize_s cn52xx;
+ struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xx;
+ struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_cnt_int {
+ uint64_t u64;
+ struct cvmx_npei_pkt_cnt_int_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_npei_pkt_cnt_int_s cn52xx;
+ struct cvmx_npei_pkt_cnt_int_s cn56xx;
+ struct cvmx_npei_pkt_cnt_int_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_cnt_int_enb {
+ uint64_t u64;
+ struct cvmx_npei_pkt_cnt_int_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_npei_pkt_cnt_int_enb_s cn52xx;
+ struct cvmx_npei_pkt_cnt_int_enb_s cn56xx;
+ struct cvmx_npei_pkt_cnt_int_enb_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_data_out_es {
+ uint64_t u64;
+ struct cvmx_npei_pkt_data_out_es_s {
+ uint64_t es:64;
+ } s;
+ struct cvmx_npei_pkt_data_out_es_s cn52xx;
+ struct cvmx_npei_pkt_data_out_es_s cn56xx;
+ struct cvmx_npei_pkt_data_out_es_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_data_out_ns {
+ uint64_t u64;
+ struct cvmx_npei_pkt_data_out_ns_s {
+ uint64_t reserved_32_63:32;
+ uint64_t nsr:32;
+ } s;
+ struct cvmx_npei_pkt_data_out_ns_s cn52xx;
+ struct cvmx_npei_pkt_data_out_ns_s cn56xx;
+ struct cvmx_npei_pkt_data_out_ns_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_data_out_ror {
+ uint64_t u64;
+ struct cvmx_npei_pkt_data_out_ror_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ror:32;
+ } s;
+ struct cvmx_npei_pkt_data_out_ror_s cn52xx;
+ struct cvmx_npei_pkt_data_out_ror_s cn56xx;
+ struct cvmx_npei_pkt_data_out_ror_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_dpaddr {
+ uint64_t u64;
+ struct cvmx_npei_pkt_dpaddr_s {
+ uint64_t reserved_32_63:32;
+ uint64_t dptr:32;
+ } s;
+ struct cvmx_npei_pkt_dpaddr_s cn52xx;
+ struct cvmx_npei_pkt_dpaddr_s cn56xx;
+ struct cvmx_npei_pkt_dpaddr_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_in_bp {
+ uint64_t u64;
+ struct cvmx_npei_pkt_in_bp_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bp:32;
+ } s;
+ struct cvmx_npei_pkt_in_bp_s cn56xx;
+};
+
+union cvmx_npei_pkt_in_donex_cnts {
+ uint64_t u64;
+ struct cvmx_npei_pkt_in_donex_cnts_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_pkt_in_donex_cnts_s cn52xx;
+ struct cvmx_npei_pkt_in_donex_cnts_s cn56xx;
+ struct cvmx_npei_pkt_in_donex_cnts_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_in_instr_counts {
+ uint64_t u64;
+ struct cvmx_npei_pkt_in_instr_counts_s {
+ uint64_t wr_cnt:32;
+ uint64_t rd_cnt:32;
+ } s;
+ struct cvmx_npei_pkt_in_instr_counts_s cn52xx;
+ struct cvmx_npei_pkt_in_instr_counts_s cn56xx;
+};
+
+union cvmx_npei_pkt_in_pcie_port {
+ uint64_t u64;
+ struct cvmx_npei_pkt_in_pcie_port_s {
+ uint64_t pp:64;
+ } s;
+ struct cvmx_npei_pkt_in_pcie_port_s cn52xx;
+ struct cvmx_npei_pkt_in_pcie_port_s cn56xx;
+};
+
+union cvmx_npei_pkt_input_control {
+ uint64_t u64;
+ struct cvmx_npei_pkt_input_control_s {
+ uint64_t reserved_23_63:41;
+ uint64_t pkt_rr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t d_nsr:1;
+ uint64_t d_esr:2;
+ uint64_t d_ror:1;
+ uint64_t use_csr:1;
+ uint64_t nsr:1;
+ uint64_t esr:2;
+ uint64_t ror:1;
+ } s;
+ struct cvmx_npei_pkt_input_control_s cn52xx;
+ struct cvmx_npei_pkt_input_control_s cn56xx;
+ struct cvmx_npei_pkt_input_control_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_instr_enb {
+ uint64_t u64;
+ struct cvmx_npei_pkt_instr_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t enb:32;
+ } s;
+ struct cvmx_npei_pkt_instr_enb_s cn52xx;
+ struct cvmx_npei_pkt_instr_enb_s cn56xx;
+ struct cvmx_npei_pkt_instr_enb_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_instr_rd_size {
+ uint64_t u64;
+ struct cvmx_npei_pkt_instr_rd_size_s {
+ uint64_t rdsize:64;
+ } s;
+ struct cvmx_npei_pkt_instr_rd_size_s cn52xx;
+ struct cvmx_npei_pkt_instr_rd_size_s cn56xx;
+};
+
+union cvmx_npei_pkt_instr_size {
+ uint64_t u64;
+ struct cvmx_npei_pkt_instr_size_s {
+ uint64_t reserved_32_63:32;
+ uint64_t is_64b:32;
+ } s;
+ struct cvmx_npei_pkt_instr_size_s cn52xx;
+ struct cvmx_npei_pkt_instr_size_s cn56xx;
+ struct cvmx_npei_pkt_instr_size_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_int_levels {
+ uint64_t u64;
+ struct cvmx_npei_pkt_int_levels_s {
+ uint64_t reserved_54_63:10;
+ uint64_t time:22;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_pkt_int_levels_s cn52xx;
+ struct cvmx_npei_pkt_int_levels_s cn56xx;
+ struct cvmx_npei_pkt_int_levels_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_iptr {
+ uint64_t u64;
+ struct cvmx_npei_pkt_iptr_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iptr:32;
+ } s;
+ struct cvmx_npei_pkt_iptr_s cn52xx;
+ struct cvmx_npei_pkt_iptr_s cn56xx;
+ struct cvmx_npei_pkt_iptr_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_out_bmode {
+ uint64_t u64;
+ struct cvmx_npei_pkt_out_bmode_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bmode:32;
+ } s;
+ struct cvmx_npei_pkt_out_bmode_s cn52xx;
+ struct cvmx_npei_pkt_out_bmode_s cn56xx;
+ struct cvmx_npei_pkt_out_bmode_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_out_enb {
+ uint64_t u64;
+ struct cvmx_npei_pkt_out_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t enb:32;
+ } s;
+ struct cvmx_npei_pkt_out_enb_s cn52xx;
+ struct cvmx_npei_pkt_out_enb_s cn56xx;
+ struct cvmx_npei_pkt_out_enb_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_output_wmark {
+ uint64_t u64;
+ struct cvmx_npei_pkt_output_wmark_s {
+ uint64_t reserved_32_63:32;
+ uint64_t wmark:32;
+ } s;
+ struct cvmx_npei_pkt_output_wmark_s cn52xx;
+ struct cvmx_npei_pkt_output_wmark_s cn56xx;
+};
+
+union cvmx_npei_pkt_pcie_port {
+ uint64_t u64;
+ struct cvmx_npei_pkt_pcie_port_s {
+ uint64_t pp:64;
+ } s;
+ struct cvmx_npei_pkt_pcie_port_s cn52xx;
+ struct cvmx_npei_pkt_pcie_port_s cn56xx;
+ struct cvmx_npei_pkt_pcie_port_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_port_in_rst {
+ uint64_t u64;
+ struct cvmx_npei_pkt_port_in_rst_s {
+ uint64_t in_rst:32;
+ uint64_t out_rst:32;
+ } s;
+ struct cvmx_npei_pkt_port_in_rst_s cn52xx;
+ struct cvmx_npei_pkt_port_in_rst_s cn56xx;
+};
+
+union cvmx_npei_pkt_slist_es {
+ uint64_t u64;
+ struct cvmx_npei_pkt_slist_es_s {
+ uint64_t es:64;
+ } s;
+ struct cvmx_npei_pkt_slist_es_s cn52xx;
+ struct cvmx_npei_pkt_slist_es_s cn56xx;
+ struct cvmx_npei_pkt_slist_es_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_slist_id_size {
+ uint64_t u64;
+ struct cvmx_npei_pkt_slist_id_size_s {
+ uint64_t reserved_23_63:41;
+ uint64_t isize:7;
+ uint64_t bsize:16;
+ } s;
+ struct cvmx_npei_pkt_slist_id_size_s cn52xx;
+ struct cvmx_npei_pkt_slist_id_size_s cn56xx;
+ struct cvmx_npei_pkt_slist_id_size_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_slist_ns {
+ uint64_t u64;
+ struct cvmx_npei_pkt_slist_ns_s {
+ uint64_t reserved_32_63:32;
+ uint64_t nsr:32;
+ } s;
+ struct cvmx_npei_pkt_slist_ns_s cn52xx;
+ struct cvmx_npei_pkt_slist_ns_s cn56xx;
+ struct cvmx_npei_pkt_slist_ns_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_slist_ror {
+ uint64_t u64;
+ struct cvmx_npei_pkt_slist_ror_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ror:32;
+ } s;
+ struct cvmx_npei_pkt_slist_ror_s cn52xx;
+ struct cvmx_npei_pkt_slist_ror_s cn56xx;
+ struct cvmx_npei_pkt_slist_ror_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_time_int {
+ uint64_t u64;
+ struct cvmx_npei_pkt_time_int_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_npei_pkt_time_int_s cn52xx;
+ struct cvmx_npei_pkt_time_int_s cn56xx;
+ struct cvmx_npei_pkt_time_int_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_time_int_enb {
+ uint64_t u64;
+ struct cvmx_npei_pkt_time_int_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_npei_pkt_time_int_enb_s cn52xx;
+ struct cvmx_npei_pkt_time_int_enb_s cn56xx;
+ struct cvmx_npei_pkt_time_int_enb_s cn56xxp1;
+};
+
+union cvmx_npei_rsl_int_blocks {
+ uint64_t u64;
+ struct cvmx_npei_rsl_int_blocks_s {
+ uint64_t reserved_31_63:33;
+ uint64_t iob:1;
+ uint64_t lmc1:1;
+ uint64_t agl:1;
+ uint64_t reserved_24_27:4;
+ uint64_t asxpcs1:1;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t reserved_18_19:2;
+ uint64_t lmc0:1;
+ uint64_t l2c:1;
+ uint64_t usb1:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_8_8:1;
+ uint64_t zip:1;
+ uint64_t reserved_6_6:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npei:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } s;
+ struct cvmx_npei_rsl_int_blocks_s cn52xx;
+ struct cvmx_npei_rsl_int_blocks_s cn52xxp1;
+ struct cvmx_npei_rsl_int_blocks_cn56xx {
+ uint64_t reserved_31_63:33;
+ uint64_t iob:1;
+ uint64_t lmc1:1;
+ uint64_t agl:1;
+ uint64_t reserved_24_27:4;
+ uint64_t asxpcs1:1;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t reserved_18_19:2;
+ uint64_t lmc0:1;
+ uint64_t l2c:1;
+ uint64_t reserved_15_15:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_8_8:1;
+ uint64_t zip:1;
+ uint64_t reserved_6_6:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npei:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } cn56xx;
+ struct cvmx_npei_rsl_int_blocks_cn56xx cn56xxp1;
+};
+
+union cvmx_npei_scratch_1 {
+ uint64_t u64;
+ struct cvmx_npei_scratch_1_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_npei_scratch_1_s cn52xx;
+ struct cvmx_npei_scratch_1_s cn52xxp1;
+ struct cvmx_npei_scratch_1_s cn56xx;
+ struct cvmx_npei_scratch_1_s cn56xxp1;
+};
+
+union cvmx_npei_state1 {
+ uint64_t u64;
+ struct cvmx_npei_state1_s {
+ uint64_t cpl1:12;
+ uint64_t cpl0:12;
+ uint64_t arb:1;
+ uint64_t csr:39;
+ } s;
+ struct cvmx_npei_state1_s cn52xx;
+ struct cvmx_npei_state1_s cn52xxp1;
+ struct cvmx_npei_state1_s cn56xx;
+ struct cvmx_npei_state1_s cn56xxp1;
+};
+
+union cvmx_npei_state2 {
+ uint64_t u64;
+ struct cvmx_npei_state2_s {
+ uint64_t reserved_48_63:16;
+ uint64_t npei:1;
+ uint64_t rac:1;
+ uint64_t csm1:15;
+ uint64_t csm0:15;
+ uint64_t nnp0:8;
+ uint64_t nnd:8;
+ } s;
+ struct cvmx_npei_state2_s cn52xx;
+ struct cvmx_npei_state2_s cn52xxp1;
+ struct cvmx_npei_state2_s cn56xx;
+ struct cvmx_npei_state2_s cn56xxp1;
+};
+
+union cvmx_npei_state3 {
+ uint64_t u64;
+ struct cvmx_npei_state3_s {
+ uint64_t reserved_56_63:8;
+ uint64_t psm1:15;
+ uint64_t psm0:15;
+ uint64_t nsm1:13;
+ uint64_t nsm0:13;
+ } s;
+ struct cvmx_npei_state3_s cn52xx;
+ struct cvmx_npei_state3_s cn52xxp1;
+ struct cvmx_npei_state3_s cn56xx;
+ struct cvmx_npei_state3_s cn56xxp1;
+};
+
+union cvmx_npei_win_rd_addr {
+ uint64_t u64;
+ struct cvmx_npei_win_rd_addr_s {
+ uint64_t reserved_51_63:13;
+ uint64_t ld_cmd:2;
+ uint64_t iobit:1;
+ uint64_t rd_addr:48;
+ } s;
+ struct cvmx_npei_win_rd_addr_s cn52xx;
+ struct cvmx_npei_win_rd_addr_s cn52xxp1;
+ struct cvmx_npei_win_rd_addr_s cn56xx;
+ struct cvmx_npei_win_rd_addr_s cn56xxp1;
+};
+
+union cvmx_npei_win_rd_data {
+ uint64_t u64;
+ struct cvmx_npei_win_rd_data_s {
+ uint64_t rd_data:64;
+ } s;
+ struct cvmx_npei_win_rd_data_s cn52xx;
+ struct cvmx_npei_win_rd_data_s cn52xxp1;
+ struct cvmx_npei_win_rd_data_s cn56xx;
+ struct cvmx_npei_win_rd_data_s cn56xxp1;
+};
+
+union cvmx_npei_win_wr_addr {
+ uint64_t u64;
+ struct cvmx_npei_win_wr_addr_s {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t wr_addr:46;
+ uint64_t reserved_0_1:2;
+ } s;
+ struct cvmx_npei_win_wr_addr_s cn52xx;
+ struct cvmx_npei_win_wr_addr_s cn52xxp1;
+ struct cvmx_npei_win_wr_addr_s cn56xx;
+ struct cvmx_npei_win_wr_addr_s cn56xxp1;
+};
+
+union cvmx_npei_win_wr_data {
+ uint64_t u64;
+ struct cvmx_npei_win_wr_data_s {
+ uint64_t wr_data:64;
+ } s;
+ struct cvmx_npei_win_wr_data_s cn52xx;
+ struct cvmx_npei_win_wr_data_s cn52xxp1;
+ struct cvmx_npei_win_wr_data_s cn56xx;
+ struct cvmx_npei_win_wr_data_s cn56xxp1;
+};
+
+union cvmx_npei_win_wr_mask {
+ uint64_t u64;
+ struct cvmx_npei_win_wr_mask_s {
+ uint64_t reserved_8_63:56;
+ uint64_t wr_mask:8;
+ } s;
+ struct cvmx_npei_win_wr_mask_s cn52xx;
+ struct cvmx_npei_win_wr_mask_s cn52xxp1;
+ struct cvmx_npei_win_wr_mask_s cn56xx;
+ struct cvmx_npei_win_wr_mask_s cn56xxp1;
+};
+
+union cvmx_npei_window_ctl {
+ uint64_t u64;
+ struct cvmx_npei_window_ctl_s {
+ uint64_t reserved_32_63:32;
+ uint64_t time:32;
+ } s;
+ struct cvmx_npei_window_ctl_s cn52xx;
+ struct cvmx_npei_window_ctl_s cn52xxp1;
+ struct cvmx_npei_window_ctl_s cn56xx;
+ struct cvmx_npei_window_ctl_s cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-npi-defs.h b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
new file mode 100644
index 000000000000..4e03cd8561e3
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
@@ -0,0 +1,1735 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_NPI_DEFS_H__
+#define __CVMX_NPI_DEFS_H__
+
+#define CVMX_NPI_BASE_ADDR_INPUT0 \
+ CVMX_ADD_IO_SEG(0x00011F0000000070ull)
+#define CVMX_NPI_BASE_ADDR_INPUT1 \
+ CVMX_ADD_IO_SEG(0x00011F0000000080ull)
+#define CVMX_NPI_BASE_ADDR_INPUT2 \
+ CVMX_ADD_IO_SEG(0x00011F0000000090ull)
+#define CVMX_NPI_BASE_ADDR_INPUT3 \
+ CVMX_ADD_IO_SEG(0x00011F00000000A0ull)
+#define CVMX_NPI_BASE_ADDR_INPUTX(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000000070ull + (((offset) & 3) * 16))
+#define CVMX_NPI_BASE_ADDR_OUTPUT0 \
+ CVMX_ADD_IO_SEG(0x00011F00000000B8ull)
+#define CVMX_NPI_BASE_ADDR_OUTPUT1 \
+ CVMX_ADD_IO_SEG(0x00011F00000000C0ull)
+#define CVMX_NPI_BASE_ADDR_OUTPUT2 \
+ CVMX_ADD_IO_SEG(0x00011F00000000C8ull)
+#define CVMX_NPI_BASE_ADDR_OUTPUT3 \
+ CVMX_ADD_IO_SEG(0x00011F00000000D0ull)
+#define CVMX_NPI_BASE_ADDR_OUTPUTX(offset) \
+ CVMX_ADD_IO_SEG(0x00011F00000000B8ull + (((offset) & 3) * 8))
+#define CVMX_NPI_BIST_STATUS \
+ CVMX_ADD_IO_SEG(0x00011F00000003F8ull)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT0 \
+ CVMX_ADD_IO_SEG(0x00011F00000000E0ull)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT1 \
+ CVMX_ADD_IO_SEG(0x00011F00000000E8ull)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT2 \
+ CVMX_ADD_IO_SEG(0x00011F00000000F0ull)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT3 \
+ CVMX_ADD_IO_SEG(0x00011F00000000F8ull)
+#define CVMX_NPI_BUFF_SIZE_OUTPUTX(offset) \
+ CVMX_ADD_IO_SEG(0x00011F00000000E0ull + (((offset) & 3) * 8))
+#define CVMX_NPI_COMP_CTL \
+ CVMX_ADD_IO_SEG(0x00011F0000000218ull)
+#define CVMX_NPI_CTL_STATUS \
+ CVMX_ADD_IO_SEG(0x00011F0000000010ull)
+#define CVMX_NPI_DBG_SELECT \
+ CVMX_ADD_IO_SEG(0x00011F0000000008ull)
+#define CVMX_NPI_DMA_CONTROL \
+ CVMX_ADD_IO_SEG(0x00011F0000000128ull)
+#define CVMX_NPI_DMA_HIGHP_COUNTS \
+ CVMX_ADD_IO_SEG(0x00011F0000000148ull)
+#define CVMX_NPI_DMA_HIGHP_NADDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000158ull)
+#define CVMX_NPI_DMA_LOWP_COUNTS \
+ CVMX_ADD_IO_SEG(0x00011F0000000140ull)
+#define CVMX_NPI_DMA_LOWP_NADDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000150ull)
+#define CVMX_NPI_HIGHP_DBELL \
+ CVMX_ADD_IO_SEG(0x00011F0000000120ull)
+#define CVMX_NPI_HIGHP_IBUFF_SADDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000110ull)
+#define CVMX_NPI_INPUT_CONTROL \
+ CVMX_ADD_IO_SEG(0x00011F0000000138ull)
+#define CVMX_NPI_INT_ENB \
+ CVMX_ADD_IO_SEG(0x00011F0000000020ull)
+#define CVMX_NPI_INT_SUM \
+ CVMX_ADD_IO_SEG(0x00011F0000000018ull)
+#define CVMX_NPI_LOWP_DBELL \
+ CVMX_ADD_IO_SEG(0x00011F0000000118ull)
+#define CVMX_NPI_LOWP_IBUFF_SADDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000108ull)
+#define CVMX_NPI_MEM_ACCESS_SUBID3 \
+ CVMX_ADD_IO_SEG(0x00011F0000000028ull)
+#define CVMX_NPI_MEM_ACCESS_SUBID4 \
+ CVMX_ADD_IO_SEG(0x00011F0000000030ull)
+#define CVMX_NPI_MEM_ACCESS_SUBID5 \
+ CVMX_ADD_IO_SEG(0x00011F0000000038ull)
+#define CVMX_NPI_MEM_ACCESS_SUBID6 \
+ CVMX_ADD_IO_SEG(0x00011F0000000040ull)
+#define CVMX_NPI_MEM_ACCESS_SUBIDX(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000000028ull + (((offset) & 7) * 8) - 8 * 3)
+#define CVMX_NPI_MSI_RCV \
+ (0x0000000000000190ull)
+#define CVMX_NPI_NPI_MSI_RCV \
+ CVMX_ADD_IO_SEG(0x00011F0000001190ull)
+#define CVMX_NPI_NUM_DESC_OUTPUT0 \
+ CVMX_ADD_IO_SEG(0x00011F0000000050ull)
+#define CVMX_NPI_NUM_DESC_OUTPUT1 \
+ CVMX_ADD_IO_SEG(0x00011F0000000058ull)
+#define CVMX_NPI_NUM_DESC_OUTPUT2 \
+ CVMX_ADD_IO_SEG(0x00011F0000000060ull)
+#define CVMX_NPI_NUM_DESC_OUTPUT3 \
+ CVMX_ADD_IO_SEG(0x00011F0000000068ull)
+#define CVMX_NPI_NUM_DESC_OUTPUTX(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000000050ull + (((offset) & 3) * 8))
+#define CVMX_NPI_OUTPUT_CONTROL \
+ CVMX_ADD_IO_SEG(0x00011F0000000100ull)
+#define CVMX_NPI_P0_DBPAIR_ADDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000180ull)
+#define CVMX_NPI_P0_INSTR_ADDR \
+ CVMX_ADD_IO_SEG(0x00011F00000001C0ull)
+#define CVMX_NPI_P0_INSTR_CNTS \
+ CVMX_ADD_IO_SEG(0x00011F00000001A0ull)
+#define CVMX_NPI_P0_PAIR_CNTS \
+ CVMX_ADD_IO_SEG(0x00011F0000000160ull)
+#define CVMX_NPI_P1_DBPAIR_ADDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000188ull)
+#define CVMX_NPI_P1_INSTR_ADDR \
+ CVMX_ADD_IO_SEG(0x00011F00000001C8ull)
+#define CVMX_NPI_P1_INSTR_CNTS \
+ CVMX_ADD_IO_SEG(0x00011F00000001A8ull)
+#define CVMX_NPI_P1_PAIR_CNTS \
+ CVMX_ADD_IO_SEG(0x00011F0000000168ull)
+#define CVMX_NPI_P2_DBPAIR_ADDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000190ull)
+#define CVMX_NPI_P2_INSTR_ADDR \
+ CVMX_ADD_IO_SEG(0x00011F00000001D0ull)
+#define CVMX_NPI_P2_INSTR_CNTS \
+ CVMX_ADD_IO_SEG(0x00011F00000001B0ull)
+#define CVMX_NPI_P2_PAIR_CNTS \
+ CVMX_ADD_IO_SEG(0x00011F0000000170ull)
+#define CVMX_NPI_P3_DBPAIR_ADDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000198ull)
+#define CVMX_NPI_P3_INSTR_ADDR \
+ CVMX_ADD_IO_SEG(0x00011F00000001D8ull)
+#define CVMX_NPI_P3_INSTR_CNTS \
+ CVMX_ADD_IO_SEG(0x00011F00000001B8ull)
+#define CVMX_NPI_P3_PAIR_CNTS \
+ CVMX_ADD_IO_SEG(0x00011F0000000178ull)
+#define CVMX_NPI_PCI_BAR1_INDEXX(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000001100ull + (((offset) & 31) * 4))
+#define CVMX_NPI_PCI_BIST_REG \
+ CVMX_ADD_IO_SEG(0x00011F00000011C0ull)
+#define CVMX_NPI_PCI_BURST_SIZE \
+ CVMX_ADD_IO_SEG(0x00011F00000000D8ull)
+#define CVMX_NPI_PCI_CFG00 \
+ CVMX_ADD_IO_SEG(0x00011F0000001800ull)
+#define CVMX_NPI_PCI_CFG01 \
+ CVMX_ADD_IO_SEG(0x00011F0000001804ull)
+#define CVMX_NPI_PCI_CFG02 \
+ CVMX_ADD_IO_SEG(0x00011F0000001808ull)
+#define CVMX_NPI_PCI_CFG03 \
+ CVMX_ADD_IO_SEG(0x00011F000000180Cull)
+#define CVMX_NPI_PCI_CFG04 \
+ CVMX_ADD_IO_SEG(0x00011F0000001810ull)
+#define CVMX_NPI_PCI_CFG05 \
+ CVMX_ADD_IO_SEG(0x00011F0000001814ull)
+#define CVMX_NPI_PCI_CFG06 \
+ CVMX_ADD_IO_SEG(0x00011F0000001818ull)
+#define CVMX_NPI_PCI_CFG07 \
+ CVMX_ADD_IO_SEG(0x00011F000000181Cull)
+#define CVMX_NPI_PCI_CFG08 \
+ CVMX_ADD_IO_SEG(0x00011F0000001820ull)
+#define CVMX_NPI_PCI_CFG09 \
+ CVMX_ADD_IO_SEG(0x00011F0000001824ull)
+#define CVMX_NPI_PCI_CFG10 \
+ CVMX_ADD_IO_SEG(0x00011F0000001828ull)
+#define CVMX_NPI_PCI_CFG11 \
+ CVMX_ADD_IO_SEG(0x00011F000000182Cull)
+#define CVMX_NPI_PCI_CFG12 \
+ CVMX_ADD_IO_SEG(0x00011F0000001830ull)
+#define CVMX_NPI_PCI_CFG13 \
+ CVMX_ADD_IO_SEG(0x00011F0000001834ull)
+#define CVMX_NPI_PCI_CFG15 \
+ CVMX_ADD_IO_SEG(0x00011F000000183Cull)
+#define CVMX_NPI_PCI_CFG16 \
+ CVMX_ADD_IO_SEG(0x00011F0000001840ull)
+#define CVMX_NPI_PCI_CFG17 \
+ CVMX_ADD_IO_SEG(0x00011F0000001844ull)
+#define CVMX_NPI_PCI_CFG18 \
+ CVMX_ADD_IO_SEG(0x00011F0000001848ull)
+#define CVMX_NPI_PCI_CFG19 \
+ CVMX_ADD_IO_SEG(0x00011F000000184Cull)
+#define CVMX_NPI_PCI_CFG20 \
+ CVMX_ADD_IO_SEG(0x00011F0000001850ull)
+#define CVMX_NPI_PCI_CFG21 \
+ CVMX_ADD_IO_SEG(0x00011F0000001854ull)
+#define CVMX_NPI_PCI_CFG22 \
+ CVMX_ADD_IO_SEG(0x00011F0000001858ull)
+#define CVMX_NPI_PCI_CFG56 \
+ CVMX_ADD_IO_SEG(0x00011F00000018E0ull)
+#define CVMX_NPI_PCI_CFG57 \
+ CVMX_ADD_IO_SEG(0x00011F00000018E4ull)
+#define CVMX_NPI_PCI_CFG58 \
+ CVMX_ADD_IO_SEG(0x00011F00000018E8ull)
+#define CVMX_NPI_PCI_CFG59 \
+ CVMX_ADD_IO_SEG(0x00011F00000018ECull)
+#define CVMX_NPI_PCI_CFG60 \
+ CVMX_ADD_IO_SEG(0x00011F00000018F0ull)
+#define CVMX_NPI_PCI_CFG61 \
+ CVMX_ADD_IO_SEG(0x00011F00000018F4ull)
+#define CVMX_NPI_PCI_CFG62 \
+ CVMX_ADD_IO_SEG(0x00011F00000018F8ull)
+#define CVMX_NPI_PCI_CFG63 \
+ CVMX_ADD_IO_SEG(0x00011F00000018FCull)
+#define CVMX_NPI_PCI_CNT_REG \
+ CVMX_ADD_IO_SEG(0x00011F00000011B8ull)
+#define CVMX_NPI_PCI_CTL_STATUS_2 \
+ CVMX_ADD_IO_SEG(0x00011F000000118Cull)
+#define CVMX_NPI_PCI_INT_ARB_CFG \
+ CVMX_ADD_IO_SEG(0x00011F0000000130ull)
+#define CVMX_NPI_PCI_INT_ENB2 \
+ CVMX_ADD_IO_SEG(0x00011F00000011A0ull)
+#define CVMX_NPI_PCI_INT_SUM2 \
+ CVMX_ADD_IO_SEG(0x00011F0000001198ull)
+#define CVMX_NPI_PCI_READ_CMD \
+ CVMX_ADD_IO_SEG(0x00011F0000000048ull)
+#define CVMX_NPI_PCI_READ_CMD_6 \
+ CVMX_ADD_IO_SEG(0x00011F0000001180ull)
+#define CVMX_NPI_PCI_READ_CMD_C \
+ CVMX_ADD_IO_SEG(0x00011F0000001184ull)
+#define CVMX_NPI_PCI_READ_CMD_E \
+ CVMX_ADD_IO_SEG(0x00011F0000001188ull)
+#define CVMX_NPI_PCI_SCM_REG \
+ CVMX_ADD_IO_SEG(0x00011F00000011A8ull)
+#define CVMX_NPI_PCI_TSR_REG \
+ CVMX_ADD_IO_SEG(0x00011F00000011B0ull)
+#define CVMX_NPI_PORT32_INSTR_HDR \
+ CVMX_ADD_IO_SEG(0x00011F00000001F8ull)
+#define CVMX_NPI_PORT33_INSTR_HDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000200ull)
+#define CVMX_NPI_PORT34_INSTR_HDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000208ull)
+#define CVMX_NPI_PORT35_INSTR_HDR \
+ CVMX_ADD_IO_SEG(0x00011F0000000210ull)
+#define CVMX_NPI_PORT_BP_CONTROL \
+ CVMX_ADD_IO_SEG(0x00011F00000001F0ull)
+#define CVMX_NPI_PX_DBPAIR_ADDR(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000000180ull + (((offset) & 3) * 8))
+#define CVMX_NPI_PX_INSTR_ADDR(offset) \
+ CVMX_ADD_IO_SEG(0x00011F00000001C0ull + (((offset) & 3) * 8))
+#define CVMX_NPI_PX_INSTR_CNTS(offset) \
+ CVMX_ADD_IO_SEG(0x00011F00000001A0ull + (((offset) & 3) * 8))
+#define CVMX_NPI_PX_PAIR_CNTS(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000000160ull + (((offset) & 3) * 8))
+#define CVMX_NPI_RSL_INT_BLOCKS \
+ CVMX_ADD_IO_SEG(0x00011F0000000000ull)
+#define CVMX_NPI_SIZE_INPUT0 \
+ CVMX_ADD_IO_SEG(0x00011F0000000078ull)
+#define CVMX_NPI_SIZE_INPUT1 \
+ CVMX_ADD_IO_SEG(0x00011F0000000088ull)
+#define CVMX_NPI_SIZE_INPUT2 \
+ CVMX_ADD_IO_SEG(0x00011F0000000098ull)
+#define CVMX_NPI_SIZE_INPUT3 \
+ CVMX_ADD_IO_SEG(0x00011F00000000A8ull)
+#define CVMX_NPI_SIZE_INPUTX(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000000078ull + (((offset) & 3) * 16))
+#define CVMX_NPI_WIN_READ_TO \
+ CVMX_ADD_IO_SEG(0x00011F00000001E0ull)
+
+union cvmx_npi_base_addr_inputx {
+ uint64_t u64;
+ struct cvmx_npi_base_addr_inputx_s {
+ uint64_t baddr:61;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_npi_base_addr_inputx_s cn30xx;
+ struct cvmx_npi_base_addr_inputx_s cn31xx;
+ struct cvmx_npi_base_addr_inputx_s cn38xx;
+ struct cvmx_npi_base_addr_inputx_s cn38xxp2;
+ struct cvmx_npi_base_addr_inputx_s cn50xx;
+ struct cvmx_npi_base_addr_inputx_s cn58xx;
+ struct cvmx_npi_base_addr_inputx_s cn58xxp1;
+};
+
+union cvmx_npi_base_addr_outputx {
+ uint64_t u64;
+ struct cvmx_npi_base_addr_outputx_s {
+ uint64_t baddr:61;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_npi_base_addr_outputx_s cn30xx;
+ struct cvmx_npi_base_addr_outputx_s cn31xx;
+ struct cvmx_npi_base_addr_outputx_s cn38xx;
+ struct cvmx_npi_base_addr_outputx_s cn38xxp2;
+ struct cvmx_npi_base_addr_outputx_s cn50xx;
+ struct cvmx_npi_base_addr_outputx_s cn58xx;
+ struct cvmx_npi_base_addr_outputx_s cn58xxp1;
+};
+
+union cvmx_npi_bist_status {
+ uint64_t u64;
+ struct cvmx_npi_bist_status_s {
+ uint64_t reserved_20_63:44;
+ uint64_t csr_bs:1;
+ uint64_t dif_bs:1;
+ uint64_t rdp_bs:1;
+ uint64_t pcnc_bs:1;
+ uint64_t pcn_bs:1;
+ uint64_t rdn_bs:1;
+ uint64_t pcac_bs:1;
+ uint64_t pcad_bs:1;
+ uint64_t rdnl_bs:1;
+ uint64_t pgf_bs:1;
+ uint64_t pig_bs:1;
+ uint64_t pof0_bs:1;
+ uint64_t pof1_bs:1;
+ uint64_t pof2_bs:1;
+ uint64_t pof3_bs:1;
+ uint64_t pos_bs:1;
+ uint64_t nus_bs:1;
+ uint64_t dob_bs:1;
+ uint64_t pdf_bs:1;
+ uint64_t dpi_bs:1;
+ } s;
+ struct cvmx_npi_bist_status_cn30xx {
+ uint64_t reserved_20_63:44;
+ uint64_t csr_bs:1;
+ uint64_t dif_bs:1;
+ uint64_t rdp_bs:1;
+ uint64_t pcnc_bs:1;
+ uint64_t pcn_bs:1;
+ uint64_t rdn_bs:1;
+ uint64_t pcac_bs:1;
+ uint64_t pcad_bs:1;
+ uint64_t rdnl_bs:1;
+ uint64_t pgf_bs:1;
+ uint64_t pig_bs:1;
+ uint64_t pof0_bs:1;
+ uint64_t reserved_5_7:3;
+ uint64_t pos_bs:1;
+ uint64_t nus_bs:1;
+ uint64_t dob_bs:1;
+ uint64_t pdf_bs:1;
+ uint64_t dpi_bs:1;
+ } cn30xx;
+ struct cvmx_npi_bist_status_s cn31xx;
+ struct cvmx_npi_bist_status_s cn38xx;
+ struct cvmx_npi_bist_status_s cn38xxp2;
+ struct cvmx_npi_bist_status_cn50xx {
+ uint64_t reserved_20_63:44;
+ uint64_t csr_bs:1;
+ uint64_t dif_bs:1;
+ uint64_t rdp_bs:1;
+ uint64_t pcnc_bs:1;
+ uint64_t pcn_bs:1;
+ uint64_t rdn_bs:1;
+ uint64_t pcac_bs:1;
+ uint64_t pcad_bs:1;
+ uint64_t rdnl_bs:1;
+ uint64_t pgf_bs:1;
+ uint64_t pig_bs:1;
+ uint64_t pof0_bs:1;
+ uint64_t pof1_bs:1;
+ uint64_t reserved_5_6:2;
+ uint64_t pos_bs:1;
+ uint64_t nus_bs:1;
+ uint64_t dob_bs:1;
+ uint64_t pdf_bs:1;
+ uint64_t dpi_bs:1;
+ } cn50xx;
+ struct cvmx_npi_bist_status_s cn58xx;
+ struct cvmx_npi_bist_status_s cn58xxp1;
+};
+
+union cvmx_npi_buff_size_outputx {
+ uint64_t u64;
+ struct cvmx_npi_buff_size_outputx_s {
+ uint64_t reserved_23_63:41;
+ uint64_t isize:7;
+ uint64_t bsize:16;
+ } s;
+ struct cvmx_npi_buff_size_outputx_s cn30xx;
+ struct cvmx_npi_buff_size_outputx_s cn31xx;
+ struct cvmx_npi_buff_size_outputx_s cn38xx;
+ struct cvmx_npi_buff_size_outputx_s cn38xxp2;
+ struct cvmx_npi_buff_size_outputx_s cn50xx;
+ struct cvmx_npi_buff_size_outputx_s cn58xx;
+ struct cvmx_npi_buff_size_outputx_s cn58xxp1;
+};
+
+union cvmx_npi_comp_ctl {
+ uint64_t u64;
+ struct cvmx_npi_comp_ctl_s {
+ uint64_t reserved_10_63:54;
+ uint64_t pctl:5;
+ uint64_t nctl:5;
+ } s;
+ struct cvmx_npi_comp_ctl_s cn50xx;
+ struct cvmx_npi_comp_ctl_s cn58xx;
+ struct cvmx_npi_comp_ctl_s cn58xxp1;
+};
+
+union cvmx_npi_ctl_status {
+ uint64_t u64;
+ struct cvmx_npi_ctl_status_s {
+ uint64_t reserved_63_63:1;
+ uint64_t chip_rev:8;
+ uint64_t dis_pniw:1;
+ uint64_t out3_enb:1;
+ uint64_t out2_enb:1;
+ uint64_t out1_enb:1;
+ uint64_t out0_enb:1;
+ uint64_t ins3_enb:1;
+ uint64_t ins2_enb:1;
+ uint64_t ins1_enb:1;
+ uint64_t ins0_enb:1;
+ uint64_t ins3_64b:1;
+ uint64_t ins2_64b:1;
+ uint64_t ins1_64b:1;
+ uint64_t ins0_64b:1;
+ uint64_t pci_wdis:1;
+ uint64_t wait_com:1;
+ uint64_t reserved_37_39:3;
+ uint64_t max_word:5;
+ uint64_t reserved_10_31:22;
+ uint64_t timer:10;
+ } s;
+ struct cvmx_npi_ctl_status_cn30xx {
+ uint64_t reserved_63_63:1;
+ uint64_t chip_rev:8;
+ uint64_t dis_pniw:1;
+ uint64_t reserved_51_53:3;
+ uint64_t out0_enb:1;
+ uint64_t reserved_47_49:3;
+ uint64_t ins0_enb:1;
+ uint64_t reserved_43_45:3;
+ uint64_t ins0_64b:1;
+ uint64_t pci_wdis:1;
+ uint64_t wait_com:1;
+ uint64_t reserved_37_39:3;
+ uint64_t max_word:5;
+ uint64_t reserved_10_31:22;
+ uint64_t timer:10;
+ } cn30xx;
+ struct cvmx_npi_ctl_status_cn31xx {
+ uint64_t reserved_63_63:1;
+ uint64_t chip_rev:8;
+ uint64_t dis_pniw:1;
+ uint64_t reserved_52_53:2;
+ uint64_t out1_enb:1;
+ uint64_t out0_enb:1;
+ uint64_t reserved_48_49:2;
+ uint64_t ins1_enb:1;
+ uint64_t ins0_enb:1;
+ uint64_t reserved_44_45:2;
+ uint64_t ins1_64b:1;
+ uint64_t ins0_64b:1;
+ uint64_t pci_wdis:1;
+ uint64_t wait_com:1;
+ uint64_t reserved_37_39:3;
+ uint64_t max_word:5;
+ uint64_t reserved_10_31:22;
+ uint64_t timer:10;
+ } cn31xx;
+ struct cvmx_npi_ctl_status_s cn38xx;
+ struct cvmx_npi_ctl_status_s cn38xxp2;
+ struct cvmx_npi_ctl_status_cn31xx cn50xx;
+ struct cvmx_npi_ctl_status_s cn58xx;
+ struct cvmx_npi_ctl_status_s cn58xxp1;
+};
+
+union cvmx_npi_dbg_select {
+ uint64_t u64;
+ struct cvmx_npi_dbg_select_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dbg_sel:16;
+ } s;
+ struct cvmx_npi_dbg_select_s cn30xx;
+ struct cvmx_npi_dbg_select_s cn31xx;
+ struct cvmx_npi_dbg_select_s cn38xx;
+ struct cvmx_npi_dbg_select_s cn38xxp2;
+ struct cvmx_npi_dbg_select_s cn50xx;
+ struct cvmx_npi_dbg_select_s cn58xx;
+ struct cvmx_npi_dbg_select_s cn58xxp1;
+};
+
+union cvmx_npi_dma_control {
+ uint64_t u64;
+ struct cvmx_npi_dma_control_s {
+ uint64_t reserved_36_63:28;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t hp_enb:1;
+ uint64_t lp_enb:1;
+ uint64_t csize:14;
+ } s;
+ struct cvmx_npi_dma_control_s cn30xx;
+ struct cvmx_npi_dma_control_s cn31xx;
+ struct cvmx_npi_dma_control_s cn38xx;
+ struct cvmx_npi_dma_control_s cn38xxp2;
+ struct cvmx_npi_dma_control_s cn50xx;
+ struct cvmx_npi_dma_control_s cn58xx;
+ struct cvmx_npi_dma_control_s cn58xxp1;
+};
+
+union cvmx_npi_dma_highp_counts {
+ uint64_t u64;
+ struct cvmx_npi_dma_highp_counts_s {
+ uint64_t reserved_39_63:25;
+ uint64_t fcnt:7;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_npi_dma_highp_counts_s cn30xx;
+ struct cvmx_npi_dma_highp_counts_s cn31xx;
+ struct cvmx_npi_dma_highp_counts_s cn38xx;
+ struct cvmx_npi_dma_highp_counts_s cn38xxp2;
+ struct cvmx_npi_dma_highp_counts_s cn50xx;
+ struct cvmx_npi_dma_highp_counts_s cn58xx;
+ struct cvmx_npi_dma_highp_counts_s cn58xxp1;
+};
+
+union cvmx_npi_dma_highp_naddr {
+ uint64_t u64;
+ struct cvmx_npi_dma_highp_naddr_s {
+ uint64_t reserved_40_63:24;
+ uint64_t state:4;
+ uint64_t addr:36;
+ } s;
+ struct cvmx_npi_dma_highp_naddr_s cn30xx;
+ struct cvmx_npi_dma_highp_naddr_s cn31xx;
+ struct cvmx_npi_dma_highp_naddr_s cn38xx;
+ struct cvmx_npi_dma_highp_naddr_s cn38xxp2;
+ struct cvmx_npi_dma_highp_naddr_s cn50xx;
+ struct cvmx_npi_dma_highp_naddr_s cn58xx;
+ struct cvmx_npi_dma_highp_naddr_s cn58xxp1;
+};
+
+union cvmx_npi_dma_lowp_counts {
+ uint64_t u64;
+ struct cvmx_npi_dma_lowp_counts_s {
+ uint64_t reserved_39_63:25;
+ uint64_t fcnt:7;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_npi_dma_lowp_counts_s cn30xx;
+ struct cvmx_npi_dma_lowp_counts_s cn31xx;
+ struct cvmx_npi_dma_lowp_counts_s cn38xx;
+ struct cvmx_npi_dma_lowp_counts_s cn38xxp2;
+ struct cvmx_npi_dma_lowp_counts_s cn50xx;
+ struct cvmx_npi_dma_lowp_counts_s cn58xx;
+ struct cvmx_npi_dma_lowp_counts_s cn58xxp1;
+};
+
+union cvmx_npi_dma_lowp_naddr {
+ uint64_t u64;
+ struct cvmx_npi_dma_lowp_naddr_s {
+ uint64_t reserved_40_63:24;
+ uint64_t state:4;
+ uint64_t addr:36;
+ } s;
+ struct cvmx_npi_dma_lowp_naddr_s cn30xx;
+ struct cvmx_npi_dma_lowp_naddr_s cn31xx;
+ struct cvmx_npi_dma_lowp_naddr_s cn38xx;
+ struct cvmx_npi_dma_lowp_naddr_s cn38xxp2;
+ struct cvmx_npi_dma_lowp_naddr_s cn50xx;
+ struct cvmx_npi_dma_lowp_naddr_s cn58xx;
+ struct cvmx_npi_dma_lowp_naddr_s cn58xxp1;
+};
+
+union cvmx_npi_highp_dbell {
+ uint64_t u64;
+ struct cvmx_npi_highp_dbell_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dbell:16;
+ } s;
+ struct cvmx_npi_highp_dbell_s cn30xx;
+ struct cvmx_npi_highp_dbell_s cn31xx;
+ struct cvmx_npi_highp_dbell_s cn38xx;
+ struct cvmx_npi_highp_dbell_s cn38xxp2;
+ struct cvmx_npi_highp_dbell_s cn50xx;
+ struct cvmx_npi_highp_dbell_s cn58xx;
+ struct cvmx_npi_highp_dbell_s cn58xxp1;
+};
+
+union cvmx_npi_highp_ibuff_saddr {
+ uint64_t u64;
+ struct cvmx_npi_highp_ibuff_saddr_s {
+ uint64_t reserved_36_63:28;
+ uint64_t saddr:36;
+ } s;
+ struct cvmx_npi_highp_ibuff_saddr_s cn30xx;
+ struct cvmx_npi_highp_ibuff_saddr_s cn31xx;
+ struct cvmx_npi_highp_ibuff_saddr_s cn38xx;
+ struct cvmx_npi_highp_ibuff_saddr_s cn38xxp2;
+ struct cvmx_npi_highp_ibuff_saddr_s cn50xx;
+ struct cvmx_npi_highp_ibuff_saddr_s cn58xx;
+ struct cvmx_npi_highp_ibuff_saddr_s cn58xxp1;
+};
+
+union cvmx_npi_input_control {
+ uint64_t u64;
+ struct cvmx_npi_input_control_s {
+ uint64_t reserved_23_63:41;
+ uint64_t pkt_rr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t d_nsr:1;
+ uint64_t d_esr:2;
+ uint64_t d_ror:1;
+ uint64_t use_csr:1;
+ uint64_t nsr:1;
+ uint64_t esr:2;
+ uint64_t ror:1;
+ } s;
+ struct cvmx_npi_input_control_cn30xx {
+ uint64_t reserved_22_63:42;
+ uint64_t pbp_dhi:13;
+ uint64_t d_nsr:1;
+ uint64_t d_esr:2;
+ uint64_t d_ror:1;
+ uint64_t use_csr:1;
+ uint64_t nsr:1;
+ uint64_t esr:2;
+ uint64_t ror:1;
+ } cn30xx;
+ struct cvmx_npi_input_control_cn30xx cn31xx;
+ struct cvmx_npi_input_control_s cn38xx;
+ struct cvmx_npi_input_control_cn30xx cn38xxp2;
+ struct cvmx_npi_input_control_s cn50xx;
+ struct cvmx_npi_input_control_s cn58xx;
+ struct cvmx_npi_input_control_s cn58xxp1;
+};
+
+union cvmx_npi_int_enb {
+ uint64_t u64;
+ struct cvmx_npi_int_enb_s {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t i3_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t p3_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t p3_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t g3_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t p3_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t p3_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t i3_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t i3_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t po3_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npi_int_enb_cn30xx {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t reserved_36_38:3;
+ uint64_t i0_pperr:1;
+ uint64_t reserved_32_34:3;
+ uint64_t p0_ptout:1;
+ uint64_t reserved_28_30:3;
+ uint64_t p0_pperr:1;
+ uint64_t reserved_24_26:3;
+ uint64_t g0_rtout:1;
+ uint64_t reserved_20_22:3;
+ uint64_t p0_perr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t p0_rtout:1;
+ uint64_t reserved_12_14:3;
+ uint64_t i0_overf:1;
+ uint64_t reserved_8_10:3;
+ uint64_t i0_rtout:1;
+ uint64_t reserved_4_6:3;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn30xx;
+ struct cvmx_npi_int_enb_cn31xx {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t reserved_37_38:2;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t reserved_33_34:2;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t reserved_29_30:2;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t reserved_25_26:2;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t reserved_21_22:2;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t reserved_17_18:2;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t reserved_13_14:2;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t reserved_9_10:2;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t reserved_5_6:2;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn31xx;
+ struct cvmx_npi_int_enb_s cn38xx;
+ struct cvmx_npi_int_enb_cn38xxp2 {
+ uint64_t reserved_42_63:22;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t i3_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t p3_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t p3_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t g3_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t p3_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t p3_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t i3_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t i3_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t po3_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn38xxp2;
+ struct cvmx_npi_int_enb_cn31xx cn50xx;
+ struct cvmx_npi_int_enb_s cn58xx;
+ struct cvmx_npi_int_enb_s cn58xxp1;
+};
+
+union cvmx_npi_int_sum {
+ uint64_t u64;
+ struct cvmx_npi_int_sum_s {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t i3_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t p3_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t p3_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t g3_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t p3_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t p3_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t i3_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t i3_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t po3_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npi_int_sum_cn30xx {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t reserved_36_38:3;
+ uint64_t i0_pperr:1;
+ uint64_t reserved_32_34:3;
+ uint64_t p0_ptout:1;
+ uint64_t reserved_28_30:3;
+ uint64_t p0_pperr:1;
+ uint64_t reserved_24_26:3;
+ uint64_t g0_rtout:1;
+ uint64_t reserved_20_22:3;
+ uint64_t p0_perr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t p0_rtout:1;
+ uint64_t reserved_12_14:3;
+ uint64_t i0_overf:1;
+ uint64_t reserved_8_10:3;
+ uint64_t i0_rtout:1;
+ uint64_t reserved_4_6:3;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn30xx;
+ struct cvmx_npi_int_sum_cn31xx {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t reserved_37_38:2;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t reserved_33_34:2;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t reserved_29_30:2;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t reserved_25_26:2;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t reserved_21_22:2;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t reserved_17_18:2;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t reserved_13_14:2;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t reserved_9_10:2;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t reserved_5_6:2;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn31xx;
+ struct cvmx_npi_int_sum_s cn38xx;
+ struct cvmx_npi_int_sum_cn38xxp2 {
+ uint64_t reserved_42_63:22;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t i3_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t p3_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t p3_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t g3_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t p3_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t p3_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t i3_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t i3_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t po3_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn38xxp2;
+ struct cvmx_npi_int_sum_cn31xx cn50xx;
+ struct cvmx_npi_int_sum_s cn58xx;
+ struct cvmx_npi_int_sum_s cn58xxp1;
+};
+
+union cvmx_npi_lowp_dbell {
+ uint64_t u64;
+ struct cvmx_npi_lowp_dbell_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dbell:16;
+ } s;
+ struct cvmx_npi_lowp_dbell_s cn30xx;
+ struct cvmx_npi_lowp_dbell_s cn31xx;
+ struct cvmx_npi_lowp_dbell_s cn38xx;
+ struct cvmx_npi_lowp_dbell_s cn38xxp2;
+ struct cvmx_npi_lowp_dbell_s cn50xx;
+ struct cvmx_npi_lowp_dbell_s cn58xx;
+ struct cvmx_npi_lowp_dbell_s cn58xxp1;
+};
+
+union cvmx_npi_lowp_ibuff_saddr {
+ uint64_t u64;
+ struct cvmx_npi_lowp_ibuff_saddr_s {
+ uint64_t reserved_36_63:28;
+ uint64_t saddr:36;
+ } s;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn30xx;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn31xx;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn38xx;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn38xxp2;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn50xx;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn58xx;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn58xxp1;
+};
+
+union cvmx_npi_mem_access_subidx {
+ uint64_t u64;
+ struct cvmx_npi_mem_access_subidx_s {
+ uint64_t reserved_38_63:26;
+ uint64_t shortl:1;
+ uint64_t nmerge:1;
+ uint64_t esr:2;
+ uint64_t esw:2;
+ uint64_t nsr:1;
+ uint64_t nsw:1;
+ uint64_t ror:1;
+ uint64_t row:1;
+ uint64_t ba:28;
+ } s;
+ struct cvmx_npi_mem_access_subidx_s cn30xx;
+ struct cvmx_npi_mem_access_subidx_cn31xx {
+ uint64_t reserved_36_63:28;
+ uint64_t esr:2;
+ uint64_t esw:2;
+ uint64_t nsr:1;
+ uint64_t nsw:1;
+ uint64_t ror:1;
+ uint64_t row:1;
+ uint64_t ba:28;
+ } cn31xx;
+ struct cvmx_npi_mem_access_subidx_s cn38xx;
+ struct cvmx_npi_mem_access_subidx_cn31xx cn38xxp2;
+ struct cvmx_npi_mem_access_subidx_s cn50xx;
+ struct cvmx_npi_mem_access_subidx_s cn58xx;
+ struct cvmx_npi_mem_access_subidx_s cn58xxp1;
+};
+
+union cvmx_npi_msi_rcv {
+ uint64_t u64;
+ struct cvmx_npi_msi_rcv_s {
+ uint64_t int_vec:64;
+ } s;
+ struct cvmx_npi_msi_rcv_s cn30xx;
+ struct cvmx_npi_msi_rcv_s cn31xx;
+ struct cvmx_npi_msi_rcv_s cn38xx;
+ struct cvmx_npi_msi_rcv_s cn38xxp2;
+ struct cvmx_npi_msi_rcv_s cn50xx;
+ struct cvmx_npi_msi_rcv_s cn58xx;
+ struct cvmx_npi_msi_rcv_s cn58xxp1;
+};
+
+union cvmx_npi_num_desc_outputx {
+ uint64_t u64;
+ struct cvmx_npi_num_desc_outputx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t size:32;
+ } s;
+ struct cvmx_npi_num_desc_outputx_s cn30xx;
+ struct cvmx_npi_num_desc_outputx_s cn31xx;
+ struct cvmx_npi_num_desc_outputx_s cn38xx;
+ struct cvmx_npi_num_desc_outputx_s cn38xxp2;
+ struct cvmx_npi_num_desc_outputx_s cn50xx;
+ struct cvmx_npi_num_desc_outputx_s cn58xx;
+ struct cvmx_npi_num_desc_outputx_s cn58xxp1;
+};
+
+union cvmx_npi_output_control {
+ uint64_t u64;
+ struct cvmx_npi_output_control_s {
+ uint64_t reserved_49_63:15;
+ uint64_t pkt_rr:1;
+ uint64_t p3_bmode:1;
+ uint64_t p2_bmode:1;
+ uint64_t p1_bmode:1;
+ uint64_t p0_bmode:1;
+ uint64_t o3_es:2;
+ uint64_t o3_ns:1;
+ uint64_t o3_ro:1;
+ uint64_t o2_es:2;
+ uint64_t o2_ns:1;
+ uint64_t o2_ro:1;
+ uint64_t o1_es:2;
+ uint64_t o1_ns:1;
+ uint64_t o1_ro:1;
+ uint64_t o0_es:2;
+ uint64_t o0_ns:1;
+ uint64_t o0_ro:1;
+ uint64_t o3_csrm:1;
+ uint64_t o2_csrm:1;
+ uint64_t o1_csrm:1;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_20_23:4;
+ uint64_t iptr_o3:1;
+ uint64_t iptr_o2:1;
+ uint64_t iptr_o1:1;
+ uint64_t iptr_o0:1;
+ uint64_t esr_sl3:2;
+ uint64_t nsr_sl3:1;
+ uint64_t ror_sl3:1;
+ uint64_t esr_sl2:2;
+ uint64_t nsr_sl2:1;
+ uint64_t ror_sl2:1;
+ uint64_t esr_sl1:2;
+ uint64_t nsr_sl1:1;
+ uint64_t ror_sl1:1;
+ uint64_t esr_sl0:2;
+ uint64_t nsr_sl0:1;
+ uint64_t ror_sl0:1;
+ } s;
+ struct cvmx_npi_output_control_cn30xx {
+ uint64_t reserved_45_63:19;
+ uint64_t p0_bmode:1;
+ uint64_t reserved_32_43:12;
+ uint64_t o0_es:2;
+ uint64_t o0_ns:1;
+ uint64_t o0_ro:1;
+ uint64_t reserved_25_27:3;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_17_23:7;
+ uint64_t iptr_o0:1;
+ uint64_t reserved_4_15:12;
+ uint64_t esr_sl0:2;
+ uint64_t nsr_sl0:1;
+ uint64_t ror_sl0:1;
+ } cn30xx;
+ struct cvmx_npi_output_control_cn31xx {
+ uint64_t reserved_46_63:18;
+ uint64_t p1_bmode:1;
+ uint64_t p0_bmode:1;
+ uint64_t reserved_36_43:8;
+ uint64_t o1_es:2;
+ uint64_t o1_ns:1;
+ uint64_t o1_ro:1;
+ uint64_t o0_es:2;
+ uint64_t o0_ns:1;
+ uint64_t o0_ro:1;
+ uint64_t reserved_26_27:2;
+ uint64_t o1_csrm:1;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_18_23:6;
+ uint64_t iptr_o1:1;
+ uint64_t iptr_o0:1;
+ uint64_t reserved_8_15:8;
+ uint64_t esr_sl1:2;
+ uint64_t nsr_sl1:1;
+ uint64_t ror_sl1:1;
+ uint64_t esr_sl0:2;
+ uint64_t nsr_sl0:1;
+ uint64_t ror_sl0:1;
+ } cn31xx;
+ struct cvmx_npi_output_control_s cn38xx;
+ struct cvmx_npi_output_control_cn38xxp2 {
+ uint64_t reserved_48_63:16;
+ uint64_t p3_bmode:1;
+ uint64_t p2_bmode:1;
+ uint64_t p1_bmode:1;
+ uint64_t p0_bmode:1;
+ uint64_t o3_es:2;
+ uint64_t o3_ns:1;
+ uint64_t o3_ro:1;
+ uint64_t o2_es:2;
+ uint64_t o2_ns:1;
+ uint64_t o2_ro:1;
+ uint64_t o1_es:2;
+ uint64_t o1_ns:1;
+ uint64_t o1_ro:1;
+ uint64_t o0_es:2;
+ uint64_t o0_ns:1;
+ uint64_t o0_ro:1;
+ uint64_t o3_csrm:1;
+ uint64_t o2_csrm:1;
+ uint64_t o1_csrm:1;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_20_23:4;
+ uint64_t iptr_o3:1;
+ uint64_t iptr_o2:1;
+ uint64_t iptr_o1:1;
+ uint64_t iptr_o0:1;
+ uint64_t esr_sl3:2;
+ uint64_t nsr_sl3:1;
+ uint64_t ror_sl3:1;
+ uint64_t esr_sl2:2;
+ uint64_t nsr_sl2:1;
+ uint64_t ror_sl2:1;
+ uint64_t esr_sl1:2;
+ uint64_t nsr_sl1:1;
+ uint64_t ror_sl1:1;
+ uint64_t esr_sl0:2;
+ uint64_t nsr_sl0:1;
+ uint64_t ror_sl0:1;
+ } cn38xxp2;
+ struct cvmx_npi_output_control_cn50xx {
+ uint64_t reserved_49_63:15;
+ uint64_t pkt_rr:1;
+ uint64_t reserved_46_47:2;
+ uint64_t p1_bmode:1;
+ uint64_t p0_bmode:1;
+ uint64_t reserved_36_43:8;
+ uint64_t o1_es:2;
+ uint64_t o1_ns:1;
+ uint64_t o1_ro:1;
+ uint64_t o0_es:2;
+ uint64_t o0_ns:1;
+ uint64_t o0_ro:1;
+ uint64_t reserved_26_27:2;
+ uint64_t o1_csrm:1;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_18_23:6;
+ uint64_t iptr_o1:1;
+ uint64_t iptr_o0:1;
+ uint64_t reserved_8_15:8;
+ uint64_t esr_sl1:2;
+ uint64_t nsr_sl1:1;
+ uint64_t ror_sl1:1;
+ uint64_t esr_sl0:2;
+ uint64_t nsr_sl0:1;
+ uint64_t ror_sl0:1;
+ } cn50xx;
+ struct cvmx_npi_output_control_s cn58xx;
+ struct cvmx_npi_output_control_s cn58xxp1;
+};
+
+union cvmx_npi_px_dbpair_addr {
+ uint64_t u64;
+ struct cvmx_npi_px_dbpair_addr_s {
+ uint64_t reserved_63_63:1;
+ uint64_t state:2;
+ uint64_t naddr:61;
+ } s;
+ struct cvmx_npi_px_dbpair_addr_s cn30xx;
+ struct cvmx_npi_px_dbpair_addr_s cn31xx;
+ struct cvmx_npi_px_dbpair_addr_s cn38xx;
+ struct cvmx_npi_px_dbpair_addr_s cn38xxp2;
+ struct cvmx_npi_px_dbpair_addr_s cn50xx;
+ struct cvmx_npi_px_dbpair_addr_s cn58xx;
+ struct cvmx_npi_px_dbpair_addr_s cn58xxp1;
+};
+
+union cvmx_npi_px_instr_addr {
+ uint64_t u64;
+ struct cvmx_npi_px_instr_addr_s {
+ uint64_t state:3;
+ uint64_t naddr:61;
+ } s;
+ struct cvmx_npi_px_instr_addr_s cn30xx;
+ struct cvmx_npi_px_instr_addr_s cn31xx;
+ struct cvmx_npi_px_instr_addr_s cn38xx;
+ struct cvmx_npi_px_instr_addr_s cn38xxp2;
+ struct cvmx_npi_px_instr_addr_s cn50xx;
+ struct cvmx_npi_px_instr_addr_s cn58xx;
+ struct cvmx_npi_px_instr_addr_s cn58xxp1;
+};
+
+union cvmx_npi_px_instr_cnts {
+ uint64_t u64;
+ struct cvmx_npi_px_instr_cnts_s {
+ uint64_t reserved_38_63:26;
+ uint64_t fcnt:6;
+ uint64_t avail:32;
+ } s;
+ struct cvmx_npi_px_instr_cnts_s cn30xx;
+ struct cvmx_npi_px_instr_cnts_s cn31xx;
+ struct cvmx_npi_px_instr_cnts_s cn38xx;
+ struct cvmx_npi_px_instr_cnts_s cn38xxp2;
+ struct cvmx_npi_px_instr_cnts_s cn50xx;
+ struct cvmx_npi_px_instr_cnts_s cn58xx;
+ struct cvmx_npi_px_instr_cnts_s cn58xxp1;
+};
+
+union cvmx_npi_px_pair_cnts {
+ uint64_t u64;
+ struct cvmx_npi_px_pair_cnts_s {
+ uint64_t reserved_37_63:27;
+ uint64_t fcnt:5;
+ uint64_t avail:32;
+ } s;
+ struct cvmx_npi_px_pair_cnts_s cn30xx;
+ struct cvmx_npi_px_pair_cnts_s cn31xx;
+ struct cvmx_npi_px_pair_cnts_s cn38xx;
+ struct cvmx_npi_px_pair_cnts_s cn38xxp2;
+ struct cvmx_npi_px_pair_cnts_s cn50xx;
+ struct cvmx_npi_px_pair_cnts_s cn58xx;
+ struct cvmx_npi_px_pair_cnts_s cn58xxp1;
+};
+
+union cvmx_npi_pci_burst_size {
+ uint64_t u64;
+ struct cvmx_npi_pci_burst_size_s {
+ uint64_t reserved_14_63:50;
+ uint64_t wr_brst:7;
+ uint64_t rd_brst:7;
+ } s;
+ struct cvmx_npi_pci_burst_size_s cn30xx;
+ struct cvmx_npi_pci_burst_size_s cn31xx;
+ struct cvmx_npi_pci_burst_size_s cn38xx;
+ struct cvmx_npi_pci_burst_size_s cn38xxp2;
+ struct cvmx_npi_pci_burst_size_s cn50xx;
+ struct cvmx_npi_pci_burst_size_s cn58xx;
+ struct cvmx_npi_pci_burst_size_s cn58xxp1;
+};
+
+union cvmx_npi_pci_int_arb_cfg {
+ uint64_t u64;
+ struct cvmx_npi_pci_int_arb_cfg_s {
+ uint64_t reserved_13_63:51;
+ uint64_t hostmode:1;
+ uint64_t pci_ovr:4;
+ uint64_t reserved_5_7:3;
+ uint64_t en:1;
+ uint64_t park_mod:1;
+ uint64_t park_dev:3;
+ } s;
+ struct cvmx_npi_pci_int_arb_cfg_cn30xx {
+ uint64_t reserved_5_63:59;
+ uint64_t en:1;
+ uint64_t park_mod:1;
+ uint64_t park_dev:3;
+ } cn30xx;
+ struct cvmx_npi_pci_int_arb_cfg_cn30xx cn31xx;
+ struct cvmx_npi_pci_int_arb_cfg_cn30xx cn38xx;
+ struct cvmx_npi_pci_int_arb_cfg_cn30xx cn38xxp2;
+ struct cvmx_npi_pci_int_arb_cfg_s cn50xx;
+ struct cvmx_npi_pci_int_arb_cfg_s cn58xx;
+ struct cvmx_npi_pci_int_arb_cfg_s cn58xxp1;
+};
+
+union cvmx_npi_pci_read_cmd {
+ uint64_t u64;
+ struct cvmx_npi_pci_read_cmd_s {
+ uint64_t reserved_11_63:53;
+ uint64_t cmd_size:11;
+ } s;
+ struct cvmx_npi_pci_read_cmd_s cn30xx;
+ struct cvmx_npi_pci_read_cmd_s cn31xx;
+ struct cvmx_npi_pci_read_cmd_s cn38xx;
+ struct cvmx_npi_pci_read_cmd_s cn38xxp2;
+ struct cvmx_npi_pci_read_cmd_s cn50xx;
+ struct cvmx_npi_pci_read_cmd_s cn58xx;
+ struct cvmx_npi_pci_read_cmd_s cn58xxp1;
+};
+
+union cvmx_npi_port32_instr_hdr {
+ uint64_t u64;
+ struct cvmx_npi_port32_instr_hdr_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t rsv_f:5;
+ uint64_t rparmode:2;
+ uint64_t rsv_e:1;
+ uint64_t rskp_len:7;
+ uint64_t rsv_d:6;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_c:5;
+ uint64_t par_mode:2;
+ uint64_t rsv_b:1;
+ uint64_t skp_len:7;
+ uint64_t rsv_a:6;
+ } s;
+ struct cvmx_npi_port32_instr_hdr_s cn30xx;
+ struct cvmx_npi_port32_instr_hdr_s cn31xx;
+ struct cvmx_npi_port32_instr_hdr_s cn38xx;
+ struct cvmx_npi_port32_instr_hdr_s cn38xxp2;
+ struct cvmx_npi_port32_instr_hdr_s cn50xx;
+ struct cvmx_npi_port32_instr_hdr_s cn58xx;
+ struct cvmx_npi_port32_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port33_instr_hdr {
+ uint64_t u64;
+ struct cvmx_npi_port33_instr_hdr_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t rsv_f:5;
+ uint64_t rparmode:2;
+ uint64_t rsv_e:1;
+ uint64_t rskp_len:7;
+ uint64_t rsv_d:6;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_c:5;
+ uint64_t par_mode:2;
+ uint64_t rsv_b:1;
+ uint64_t skp_len:7;
+ uint64_t rsv_a:6;
+ } s;
+ struct cvmx_npi_port33_instr_hdr_s cn31xx;
+ struct cvmx_npi_port33_instr_hdr_s cn38xx;
+ struct cvmx_npi_port33_instr_hdr_s cn38xxp2;
+ struct cvmx_npi_port33_instr_hdr_s cn50xx;
+ struct cvmx_npi_port33_instr_hdr_s cn58xx;
+ struct cvmx_npi_port33_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port34_instr_hdr {
+ uint64_t u64;
+ struct cvmx_npi_port34_instr_hdr_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t rsv_f:5;
+ uint64_t rparmode:2;
+ uint64_t rsv_e:1;
+ uint64_t rskp_len:7;
+ uint64_t rsv_d:6;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_c:5;
+ uint64_t par_mode:2;
+ uint64_t rsv_b:1;
+ uint64_t skp_len:7;
+ uint64_t rsv_a:6;
+ } s;
+ struct cvmx_npi_port34_instr_hdr_s cn38xx;
+ struct cvmx_npi_port34_instr_hdr_s cn38xxp2;
+ struct cvmx_npi_port34_instr_hdr_s cn58xx;
+ struct cvmx_npi_port34_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port35_instr_hdr {
+ uint64_t u64;
+ struct cvmx_npi_port35_instr_hdr_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t rsv_f:5;
+ uint64_t rparmode:2;
+ uint64_t rsv_e:1;
+ uint64_t rskp_len:7;
+ uint64_t rsv_d:6;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_c:5;
+ uint64_t par_mode:2;
+ uint64_t rsv_b:1;
+ uint64_t skp_len:7;
+ uint64_t rsv_a:6;
+ } s;
+ struct cvmx_npi_port35_instr_hdr_s cn38xx;
+ struct cvmx_npi_port35_instr_hdr_s cn38xxp2;
+ struct cvmx_npi_port35_instr_hdr_s cn58xx;
+ struct cvmx_npi_port35_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port_bp_control {
+ uint64_t u64;
+ struct cvmx_npi_port_bp_control_s {
+ uint64_t reserved_8_63:56;
+ uint64_t bp_on:4;
+ uint64_t enb:4;
+ } s;
+ struct cvmx_npi_port_bp_control_s cn30xx;
+ struct cvmx_npi_port_bp_control_s cn31xx;
+ struct cvmx_npi_port_bp_control_s cn38xx;
+ struct cvmx_npi_port_bp_control_s cn38xxp2;
+ struct cvmx_npi_port_bp_control_s cn50xx;
+ struct cvmx_npi_port_bp_control_s cn58xx;
+ struct cvmx_npi_port_bp_control_s cn58xxp1;
+};
+
+union cvmx_npi_rsl_int_blocks {
+ uint64_t u64;
+ struct cvmx_npi_rsl_int_blocks_s {
+ uint64_t reserved_32_63:32;
+ uint64_t rint_31:1;
+ uint64_t iob:1;
+ uint64_t reserved_28_29:2;
+ uint64_t rint_27:1;
+ uint64_t rint_26:1;
+ uint64_t rint_25:1;
+ uint64_t rint_24:1;
+ uint64_t asx1:1;
+ uint64_t asx0:1;
+ uint64_t rint_21:1;
+ uint64_t pip:1;
+ uint64_t spx1:1;
+ uint64_t spx0:1;
+ uint64_t lmc:1;
+ uint64_t l2c:1;
+ uint64_t rint_15:1;
+ uint64_t reserved_13_14:2;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t rint_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npi:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } s;
+ struct cvmx_npi_rsl_int_blocks_cn30xx {
+ uint64_t reserved_32_63:32;
+ uint64_t rint_31:1;
+ uint64_t iob:1;
+ uint64_t rint_29:1;
+ uint64_t rint_28:1;
+ uint64_t rint_27:1;
+ uint64_t rint_26:1;
+ uint64_t rint_25:1;
+ uint64_t rint_24:1;
+ uint64_t asx1:1;
+ uint64_t asx0:1;
+ uint64_t rint_21:1;
+ uint64_t pip:1;
+ uint64_t spx1:1;
+ uint64_t spx0:1;
+ uint64_t lmc:1;
+ uint64_t l2c:1;
+ uint64_t rint_15:1;
+ uint64_t rint_14:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t rint_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npi:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } cn30xx;
+ struct cvmx_npi_rsl_int_blocks_cn30xx cn31xx;
+ struct cvmx_npi_rsl_int_blocks_cn38xx {
+ uint64_t reserved_32_63:32;
+ uint64_t rint_31:1;
+ uint64_t iob:1;
+ uint64_t rint_29:1;
+ uint64_t rint_28:1;
+ uint64_t rint_27:1;
+ uint64_t rint_26:1;
+ uint64_t rint_25:1;
+ uint64_t rint_24:1;
+ uint64_t asx1:1;
+ uint64_t asx0:1;
+ uint64_t rint_21:1;
+ uint64_t pip:1;
+ uint64_t spx1:1;
+ uint64_t spx0:1;
+ uint64_t lmc:1;
+ uint64_t l2c:1;
+ uint64_t rint_15:1;
+ uint64_t rint_14:1;
+ uint64_t rint_13:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t rint_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npi:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } cn38xx;
+ struct cvmx_npi_rsl_int_blocks_cn38xx cn38xxp2;
+ struct cvmx_npi_rsl_int_blocks_cn50xx {
+ uint64_t reserved_31_63:33;
+ uint64_t iob:1;
+ uint64_t lmc1:1;
+ uint64_t agl:1;
+ uint64_t reserved_24_27:4;
+ uint64_t asx1:1;
+ uint64_t asx0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t spx1:1;
+ uint64_t spx0:1;
+ uint64_t lmc:1;
+ uint64_t l2c:1;
+ uint64_t reserved_15_15:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_8_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npi:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } cn50xx;
+ struct cvmx_npi_rsl_int_blocks_cn38xx cn58xx;
+ struct cvmx_npi_rsl_int_blocks_cn38xx cn58xxp1;
+};
+
+union cvmx_npi_size_inputx {
+ uint64_t u64;
+ struct cvmx_npi_size_inputx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t size:32;
+ } s;
+ struct cvmx_npi_size_inputx_s cn30xx;
+ struct cvmx_npi_size_inputx_s cn31xx;
+ struct cvmx_npi_size_inputx_s cn38xx;
+ struct cvmx_npi_size_inputx_s cn38xxp2;
+ struct cvmx_npi_size_inputx_s cn50xx;
+ struct cvmx_npi_size_inputx_s cn58xx;
+ struct cvmx_npi_size_inputx_s cn58xxp1;
+};
+
+union cvmx_npi_win_read_to {
+ uint64_t u64;
+ struct cvmx_npi_win_read_to_s {
+ uint64_t reserved_32_63:32;
+ uint64_t time:32;
+ } s;
+ struct cvmx_npi_win_read_to_s cn30xx;
+ struct cvmx_npi_win_read_to_s cn31xx;
+ struct cvmx_npi_win_read_to_s cn38xx;
+ struct cvmx_npi_win_read_to_s cn38xxp2;
+ struct cvmx_npi_win_read_to_s cn50xx;
+ struct cvmx_npi_win_read_to_s cn58xx;
+ struct cvmx_npi_win_read_to_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pci-defs.h b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
new file mode 100644
index 000000000000..90f8d6535753
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
@@ -0,0 +1,1645 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCI_DEFS_H__
+#define __CVMX_PCI_DEFS_H__
+
+#define CVMX_PCI_BAR1_INDEXX(offset) \
+ (0x0000000000000100ull + (((offset) & 31) * 4))
+#define CVMX_PCI_BIST_REG \
+ (0x00000000000001C0ull)
+#define CVMX_PCI_CFG00 \
+ (0x0000000000000000ull)
+#define CVMX_PCI_CFG01 \
+ (0x0000000000000004ull)
+#define CVMX_PCI_CFG02 \
+ (0x0000000000000008ull)
+#define CVMX_PCI_CFG03 \
+ (0x000000000000000Cull)
+#define CVMX_PCI_CFG04 \
+ (0x0000000000000010ull)
+#define CVMX_PCI_CFG05 \
+ (0x0000000000000014ull)
+#define CVMX_PCI_CFG06 \
+ (0x0000000000000018ull)
+#define CVMX_PCI_CFG07 \
+ (0x000000000000001Cull)
+#define CVMX_PCI_CFG08 \
+ (0x0000000000000020ull)
+#define CVMX_PCI_CFG09 \
+ (0x0000000000000024ull)
+#define CVMX_PCI_CFG10 \
+ (0x0000000000000028ull)
+#define CVMX_PCI_CFG11 \
+ (0x000000000000002Cull)
+#define CVMX_PCI_CFG12 \
+ (0x0000000000000030ull)
+#define CVMX_PCI_CFG13 \
+ (0x0000000000000034ull)
+#define CVMX_PCI_CFG15 \
+ (0x000000000000003Cull)
+#define CVMX_PCI_CFG16 \
+ (0x0000000000000040ull)
+#define CVMX_PCI_CFG17 \
+ (0x0000000000000044ull)
+#define CVMX_PCI_CFG18 \
+ (0x0000000000000048ull)
+#define CVMX_PCI_CFG19 \
+ (0x000000000000004Cull)
+#define CVMX_PCI_CFG20 \
+ (0x0000000000000050ull)
+#define CVMX_PCI_CFG21 \
+ (0x0000000000000054ull)
+#define CVMX_PCI_CFG22 \
+ (0x0000000000000058ull)
+#define CVMX_PCI_CFG56 \
+ (0x00000000000000E0ull)
+#define CVMX_PCI_CFG57 \
+ (0x00000000000000E4ull)
+#define CVMX_PCI_CFG58 \
+ (0x00000000000000E8ull)
+#define CVMX_PCI_CFG59 \
+ (0x00000000000000ECull)
+#define CVMX_PCI_CFG60 \
+ (0x00000000000000F0ull)
+#define CVMX_PCI_CFG61 \
+ (0x00000000000000F4ull)
+#define CVMX_PCI_CFG62 \
+ (0x00000000000000F8ull)
+#define CVMX_PCI_CFG63 \
+ (0x00000000000000FCull)
+#define CVMX_PCI_CNT_REG \
+ (0x00000000000001B8ull)
+#define CVMX_PCI_CTL_STATUS_2 \
+ (0x000000000000018Cull)
+#define CVMX_PCI_DBELL_0 \
+ (0x0000000000000080ull)
+#define CVMX_PCI_DBELL_1 \
+ (0x0000000000000088ull)
+#define CVMX_PCI_DBELL_2 \
+ (0x0000000000000090ull)
+#define CVMX_PCI_DBELL_3 \
+ (0x0000000000000098ull)
+#define CVMX_PCI_DBELL_X(offset) \
+ (0x0000000000000080ull + (((offset) & 3) * 8))
+#define CVMX_PCI_DMA_CNT0 \
+ (0x00000000000000A0ull)
+#define CVMX_PCI_DMA_CNT1 \
+ (0x00000000000000A8ull)
+#define CVMX_PCI_DMA_CNTX(offset) \
+ (0x00000000000000A0ull + (((offset) & 1) * 8))
+#define CVMX_PCI_DMA_INT_LEV0 \
+ (0x00000000000000A4ull)
+#define CVMX_PCI_DMA_INT_LEV1 \
+ (0x00000000000000ACull)
+#define CVMX_PCI_DMA_INT_LEVX(offset) \
+ (0x00000000000000A4ull + (((offset) & 1) * 8))
+#define CVMX_PCI_DMA_TIME0 \
+ (0x00000000000000B0ull)
+#define CVMX_PCI_DMA_TIME1 \
+ (0x00000000000000B4ull)
+#define CVMX_PCI_DMA_TIMEX(offset) \
+ (0x00000000000000B0ull + (((offset) & 1) * 4))
+#define CVMX_PCI_INSTR_COUNT0 \
+ (0x0000000000000084ull)
+#define CVMX_PCI_INSTR_COUNT1 \
+ (0x000000000000008Cull)
+#define CVMX_PCI_INSTR_COUNT2 \
+ (0x0000000000000094ull)
+#define CVMX_PCI_INSTR_COUNT3 \
+ (0x000000000000009Cull)
+#define CVMX_PCI_INSTR_COUNTX(offset) \
+ (0x0000000000000084ull + (((offset) & 3) * 8))
+#define CVMX_PCI_INT_ENB \
+ (0x0000000000000038ull)
+#define CVMX_PCI_INT_ENB2 \
+ (0x00000000000001A0ull)
+#define CVMX_PCI_INT_SUM \
+ (0x0000000000000030ull)
+#define CVMX_PCI_INT_SUM2 \
+ (0x0000000000000198ull)
+#define CVMX_PCI_MSI_RCV \
+ (0x00000000000000F0ull)
+#define CVMX_PCI_PKTS_SENT0 \
+ (0x0000000000000040ull)
+#define CVMX_PCI_PKTS_SENT1 \
+ (0x0000000000000050ull)
+#define CVMX_PCI_PKTS_SENT2 \
+ (0x0000000000000060ull)
+#define CVMX_PCI_PKTS_SENT3 \
+ (0x0000000000000070ull)
+#define CVMX_PCI_PKTS_SENTX(offset) \
+ (0x0000000000000040ull + (((offset) & 3) * 16))
+#define CVMX_PCI_PKTS_SENT_INT_LEV0 \
+ (0x0000000000000048ull)
+#define CVMX_PCI_PKTS_SENT_INT_LEV1 \
+ (0x0000000000000058ull)
+#define CVMX_PCI_PKTS_SENT_INT_LEV2 \
+ (0x0000000000000068ull)
+#define CVMX_PCI_PKTS_SENT_INT_LEV3 \
+ (0x0000000000000078ull)
+#define CVMX_PCI_PKTS_SENT_INT_LEVX(offset) \
+ (0x0000000000000048ull + (((offset) & 3) * 16))
+#define CVMX_PCI_PKTS_SENT_TIME0 \
+ (0x000000000000004Cull)
+#define CVMX_PCI_PKTS_SENT_TIME1 \
+ (0x000000000000005Cull)
+#define CVMX_PCI_PKTS_SENT_TIME2 \
+ (0x000000000000006Cull)
+#define CVMX_PCI_PKTS_SENT_TIME3 \
+ (0x000000000000007Cull)
+#define CVMX_PCI_PKTS_SENT_TIMEX(offset) \
+ (0x000000000000004Cull + (((offset) & 3) * 16))
+#define CVMX_PCI_PKT_CREDITS0 \
+ (0x0000000000000044ull)
+#define CVMX_PCI_PKT_CREDITS1 \
+ (0x0000000000000054ull)
+#define CVMX_PCI_PKT_CREDITS2 \
+ (0x0000000000000064ull)
+#define CVMX_PCI_PKT_CREDITS3 \
+ (0x0000000000000074ull)
+#define CVMX_PCI_PKT_CREDITSX(offset) \
+ (0x0000000000000044ull + (((offset) & 3) * 16))
+#define CVMX_PCI_READ_CMD_6 \
+ (0x0000000000000180ull)
+#define CVMX_PCI_READ_CMD_C \
+ (0x0000000000000184ull)
+#define CVMX_PCI_READ_CMD_E \
+ (0x0000000000000188ull)
+#define CVMX_PCI_READ_TIMEOUT \
+ CVMX_ADD_IO_SEG(0x00011F00000000B0ull)
+#define CVMX_PCI_SCM_REG \
+ (0x00000000000001A8ull)
+#define CVMX_PCI_TSR_REG \
+ (0x00000000000001B0ull)
+#define CVMX_PCI_WIN_RD_ADDR \
+ (0x0000000000000008ull)
+#define CVMX_PCI_WIN_RD_DATA \
+ (0x0000000000000020ull)
+#define CVMX_PCI_WIN_WR_ADDR \
+ (0x0000000000000000ull)
+#define CVMX_PCI_WIN_WR_DATA \
+ (0x0000000000000010ull)
+#define CVMX_PCI_WIN_WR_MASK \
+ (0x0000000000000018ull)
+
+union cvmx_pci_bar1_indexx {
+ uint32_t u32;
+ struct cvmx_pci_bar1_indexx_s {
+ uint32_t reserved_18_31:14;
+ uint32_t addr_idx:14;
+ uint32_t ca:1;
+ uint32_t end_swp:2;
+ uint32_t addr_v:1;
+ } s;
+ struct cvmx_pci_bar1_indexx_s cn30xx;
+ struct cvmx_pci_bar1_indexx_s cn31xx;
+ struct cvmx_pci_bar1_indexx_s cn38xx;
+ struct cvmx_pci_bar1_indexx_s cn38xxp2;
+ struct cvmx_pci_bar1_indexx_s cn50xx;
+ struct cvmx_pci_bar1_indexx_s cn58xx;
+ struct cvmx_pci_bar1_indexx_s cn58xxp1;
+};
+
+union cvmx_pci_bist_reg {
+ uint64_t u64;
+ struct cvmx_pci_bist_reg_s {
+ uint64_t reserved_10_63:54;
+ uint64_t rsp_bs:1;
+ uint64_t dma0_bs:1;
+ uint64_t cmd0_bs:1;
+ uint64_t cmd_bs:1;
+ uint64_t csr2p_bs:1;
+ uint64_t csrr_bs:1;
+ uint64_t rsp2p_bs:1;
+ uint64_t csr2n_bs:1;
+ uint64_t dat2n_bs:1;
+ uint64_t dbg2n_bs:1;
+ } s;
+ struct cvmx_pci_bist_reg_s cn50xx;
+};
+
+union cvmx_pci_cfg00 {
+ uint32_t u32;
+ struct cvmx_pci_cfg00_s {
+ uint32_t devid:16;
+ uint32_t vendid:16;
+ } s;
+ struct cvmx_pci_cfg00_s cn30xx;
+ struct cvmx_pci_cfg00_s cn31xx;
+ struct cvmx_pci_cfg00_s cn38xx;
+ struct cvmx_pci_cfg00_s cn38xxp2;
+ struct cvmx_pci_cfg00_s cn50xx;
+ struct cvmx_pci_cfg00_s cn58xx;
+ struct cvmx_pci_cfg00_s cn58xxp1;
+};
+
+union cvmx_pci_cfg01 {
+ uint32_t u32;
+ struct cvmx_pci_cfg01_s {
+ uint32_t dpe:1;
+ uint32_t sse:1;
+ uint32_t rma:1;
+ uint32_t rta:1;
+ uint32_t sta:1;
+ uint32_t devt:2;
+ uint32_t mdpe:1;
+ uint32_t fbb:1;
+ uint32_t reserved_22_22:1;
+ uint32_t m66:1;
+ uint32_t cle:1;
+ uint32_t i_stat:1;
+ uint32_t reserved_11_18:8;
+ uint32_t i_dis:1;
+ uint32_t fbbe:1;
+ uint32_t see:1;
+ uint32_t ads:1;
+ uint32_t pee:1;
+ uint32_t vps:1;
+ uint32_t mwice:1;
+ uint32_t scse:1;
+ uint32_t me:1;
+ uint32_t msae:1;
+ uint32_t isae:1;
+ } s;
+ struct cvmx_pci_cfg01_s cn30xx;
+ struct cvmx_pci_cfg01_s cn31xx;
+ struct cvmx_pci_cfg01_s cn38xx;
+ struct cvmx_pci_cfg01_s cn38xxp2;
+ struct cvmx_pci_cfg01_s cn50xx;
+ struct cvmx_pci_cfg01_s cn58xx;
+ struct cvmx_pci_cfg01_s cn58xxp1;
+};
+
+union cvmx_pci_cfg02 {
+ uint32_t u32;
+ struct cvmx_pci_cfg02_s {
+ uint32_t cc:24;
+ uint32_t rid:8;
+ } s;
+ struct cvmx_pci_cfg02_s cn30xx;
+ struct cvmx_pci_cfg02_s cn31xx;
+ struct cvmx_pci_cfg02_s cn38xx;
+ struct cvmx_pci_cfg02_s cn38xxp2;
+ struct cvmx_pci_cfg02_s cn50xx;
+ struct cvmx_pci_cfg02_s cn58xx;
+ struct cvmx_pci_cfg02_s cn58xxp1;
+};
+
+union cvmx_pci_cfg03 {
+ uint32_t u32;
+ struct cvmx_pci_cfg03_s {
+ uint32_t bcap:1;
+ uint32_t brb:1;
+ uint32_t reserved_28_29:2;
+ uint32_t bcod:4;
+ uint32_t ht:8;
+ uint32_t lt:8;
+ uint32_t cls:8;
+ } s;
+ struct cvmx_pci_cfg03_s cn30xx;
+ struct cvmx_pci_cfg03_s cn31xx;
+ struct cvmx_pci_cfg03_s cn38xx;
+ struct cvmx_pci_cfg03_s cn38xxp2;
+ struct cvmx_pci_cfg03_s cn50xx;
+ struct cvmx_pci_cfg03_s cn58xx;
+ struct cvmx_pci_cfg03_s cn58xxp1;
+};
+
+union cvmx_pci_cfg04 {
+ uint32_t u32;
+ struct cvmx_pci_cfg04_s {
+ uint32_t lbase:20;
+ uint32_t lbasez:8;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pci_cfg04_s cn30xx;
+ struct cvmx_pci_cfg04_s cn31xx;
+ struct cvmx_pci_cfg04_s cn38xx;
+ struct cvmx_pci_cfg04_s cn38xxp2;
+ struct cvmx_pci_cfg04_s cn50xx;
+ struct cvmx_pci_cfg04_s cn58xx;
+ struct cvmx_pci_cfg04_s cn58xxp1;
+};
+
+union cvmx_pci_cfg05 {
+ uint32_t u32;
+ struct cvmx_pci_cfg05_s {
+ uint32_t hbase:32;
+ } s;
+ struct cvmx_pci_cfg05_s cn30xx;
+ struct cvmx_pci_cfg05_s cn31xx;
+ struct cvmx_pci_cfg05_s cn38xx;
+ struct cvmx_pci_cfg05_s cn38xxp2;
+ struct cvmx_pci_cfg05_s cn50xx;
+ struct cvmx_pci_cfg05_s cn58xx;
+ struct cvmx_pci_cfg05_s cn58xxp1;
+};
+
+union cvmx_pci_cfg06 {
+ uint32_t u32;
+ struct cvmx_pci_cfg06_s {
+ uint32_t lbase:5;
+ uint32_t lbasez:23;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pci_cfg06_s cn30xx;
+ struct cvmx_pci_cfg06_s cn31xx;
+ struct cvmx_pci_cfg06_s cn38xx;
+ struct cvmx_pci_cfg06_s cn38xxp2;
+ struct cvmx_pci_cfg06_s cn50xx;
+ struct cvmx_pci_cfg06_s cn58xx;
+ struct cvmx_pci_cfg06_s cn58xxp1;
+};
+
+union cvmx_pci_cfg07 {
+ uint32_t u32;
+ struct cvmx_pci_cfg07_s {
+ uint32_t hbase:32;
+ } s;
+ struct cvmx_pci_cfg07_s cn30xx;
+ struct cvmx_pci_cfg07_s cn31xx;
+ struct cvmx_pci_cfg07_s cn38xx;
+ struct cvmx_pci_cfg07_s cn38xxp2;
+ struct cvmx_pci_cfg07_s cn50xx;
+ struct cvmx_pci_cfg07_s cn58xx;
+ struct cvmx_pci_cfg07_s cn58xxp1;
+};
+
+union cvmx_pci_cfg08 {
+ uint32_t u32;
+ struct cvmx_pci_cfg08_s {
+ uint32_t lbasez:28;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pci_cfg08_s cn30xx;
+ struct cvmx_pci_cfg08_s cn31xx;
+ struct cvmx_pci_cfg08_s cn38xx;
+ struct cvmx_pci_cfg08_s cn38xxp2;
+ struct cvmx_pci_cfg08_s cn50xx;
+ struct cvmx_pci_cfg08_s cn58xx;
+ struct cvmx_pci_cfg08_s cn58xxp1;
+};
+
+union cvmx_pci_cfg09 {
+ uint32_t u32;
+ struct cvmx_pci_cfg09_s {
+ uint32_t hbase:25;
+ uint32_t hbasez:7;
+ } s;
+ struct cvmx_pci_cfg09_s cn30xx;
+ struct cvmx_pci_cfg09_s cn31xx;
+ struct cvmx_pci_cfg09_s cn38xx;
+ struct cvmx_pci_cfg09_s cn38xxp2;
+ struct cvmx_pci_cfg09_s cn50xx;
+ struct cvmx_pci_cfg09_s cn58xx;
+ struct cvmx_pci_cfg09_s cn58xxp1;
+};
+
+union cvmx_pci_cfg10 {
+ uint32_t u32;
+ struct cvmx_pci_cfg10_s {
+ uint32_t cisp:32;
+ } s;
+ struct cvmx_pci_cfg10_s cn30xx;
+ struct cvmx_pci_cfg10_s cn31xx;
+ struct cvmx_pci_cfg10_s cn38xx;
+ struct cvmx_pci_cfg10_s cn38xxp2;
+ struct cvmx_pci_cfg10_s cn50xx;
+ struct cvmx_pci_cfg10_s cn58xx;
+ struct cvmx_pci_cfg10_s cn58xxp1;
+};
+
+union cvmx_pci_cfg11 {
+ uint32_t u32;
+ struct cvmx_pci_cfg11_s {
+ uint32_t ssid:16;
+ uint32_t ssvid:16;
+ } s;
+ struct cvmx_pci_cfg11_s cn30xx;
+ struct cvmx_pci_cfg11_s cn31xx;
+ struct cvmx_pci_cfg11_s cn38xx;
+ struct cvmx_pci_cfg11_s cn38xxp2;
+ struct cvmx_pci_cfg11_s cn50xx;
+ struct cvmx_pci_cfg11_s cn58xx;
+ struct cvmx_pci_cfg11_s cn58xxp1;
+};
+
+union cvmx_pci_cfg12 {
+ uint32_t u32;
+ struct cvmx_pci_cfg12_s {
+ uint32_t erbar:16;
+ uint32_t erbarz:5;
+ uint32_t reserved_1_10:10;
+ uint32_t erbar_en:1;
+ } s;
+ struct cvmx_pci_cfg12_s cn30xx;
+ struct cvmx_pci_cfg12_s cn31xx;
+ struct cvmx_pci_cfg12_s cn38xx;
+ struct cvmx_pci_cfg12_s cn38xxp2;
+ struct cvmx_pci_cfg12_s cn50xx;
+ struct cvmx_pci_cfg12_s cn58xx;
+ struct cvmx_pci_cfg12_s cn58xxp1;
+};
+
+union cvmx_pci_cfg13 {
+ uint32_t u32;
+ struct cvmx_pci_cfg13_s {
+ uint32_t reserved_8_31:24;
+ uint32_t cp:8;
+ } s;
+ struct cvmx_pci_cfg13_s cn30xx;
+ struct cvmx_pci_cfg13_s cn31xx;
+ struct cvmx_pci_cfg13_s cn38xx;
+ struct cvmx_pci_cfg13_s cn38xxp2;
+ struct cvmx_pci_cfg13_s cn50xx;
+ struct cvmx_pci_cfg13_s cn58xx;
+ struct cvmx_pci_cfg13_s cn58xxp1;
+};
+
+union cvmx_pci_cfg15 {
+ uint32_t u32;
+ struct cvmx_pci_cfg15_s {
+ uint32_t ml:8;
+ uint32_t mg:8;
+ uint32_t inta:8;
+ uint32_t il:8;
+ } s;
+ struct cvmx_pci_cfg15_s cn30xx;
+ struct cvmx_pci_cfg15_s cn31xx;
+ struct cvmx_pci_cfg15_s cn38xx;
+ struct cvmx_pci_cfg15_s cn38xxp2;
+ struct cvmx_pci_cfg15_s cn50xx;
+ struct cvmx_pci_cfg15_s cn58xx;
+ struct cvmx_pci_cfg15_s cn58xxp1;
+};
+
+union cvmx_pci_cfg16 {
+ uint32_t u32;
+ struct cvmx_pci_cfg16_s {
+ uint32_t trdnpr:1;
+ uint32_t trdard:1;
+ uint32_t rdsati:1;
+ uint32_t trdrs:1;
+ uint32_t trtae:1;
+ uint32_t twsei:1;
+ uint32_t twsen:1;
+ uint32_t twtae:1;
+ uint32_t tmae:1;
+ uint32_t tslte:3;
+ uint32_t tilt:4;
+ uint32_t pbe:12;
+ uint32_t dppmr:1;
+ uint32_t reserved_2_2:1;
+ uint32_t tswc:1;
+ uint32_t mltd:1;
+ } s;
+ struct cvmx_pci_cfg16_s cn30xx;
+ struct cvmx_pci_cfg16_s cn31xx;
+ struct cvmx_pci_cfg16_s cn38xx;
+ struct cvmx_pci_cfg16_s cn38xxp2;
+ struct cvmx_pci_cfg16_s cn50xx;
+ struct cvmx_pci_cfg16_s cn58xx;
+ struct cvmx_pci_cfg16_s cn58xxp1;
+};
+
+union cvmx_pci_cfg17 {
+ uint32_t u32;
+ struct cvmx_pci_cfg17_s {
+ uint32_t tscme:32;
+ } s;
+ struct cvmx_pci_cfg17_s cn30xx;
+ struct cvmx_pci_cfg17_s cn31xx;
+ struct cvmx_pci_cfg17_s cn38xx;
+ struct cvmx_pci_cfg17_s cn38xxp2;
+ struct cvmx_pci_cfg17_s cn50xx;
+ struct cvmx_pci_cfg17_s cn58xx;
+ struct cvmx_pci_cfg17_s cn58xxp1;
+};
+
+union cvmx_pci_cfg18 {
+ uint32_t u32;
+ struct cvmx_pci_cfg18_s {
+ uint32_t tdsrps:32;
+ } s;
+ struct cvmx_pci_cfg18_s cn30xx;
+ struct cvmx_pci_cfg18_s cn31xx;
+ struct cvmx_pci_cfg18_s cn38xx;
+ struct cvmx_pci_cfg18_s cn38xxp2;
+ struct cvmx_pci_cfg18_s cn50xx;
+ struct cvmx_pci_cfg18_s cn58xx;
+ struct cvmx_pci_cfg18_s cn58xxp1;
+};
+
+union cvmx_pci_cfg19 {
+ uint32_t u32;
+ struct cvmx_pci_cfg19_s {
+ uint32_t mrbcm:1;
+ uint32_t mrbci:1;
+ uint32_t mdwe:1;
+ uint32_t mdre:1;
+ uint32_t mdrimc:1;
+ uint32_t mdrrmc:3;
+ uint32_t tmes:8;
+ uint32_t teci:1;
+ uint32_t tmei:1;
+ uint32_t tmse:1;
+ uint32_t tmdpes:1;
+ uint32_t tmapes:1;
+ uint32_t reserved_9_10:2;
+ uint32_t tibcd:1;
+ uint32_t tibde:1;
+ uint32_t reserved_6_6:1;
+ uint32_t tidomc:1;
+ uint32_t tdomc:5;
+ } s;
+ struct cvmx_pci_cfg19_s cn30xx;
+ struct cvmx_pci_cfg19_s cn31xx;
+ struct cvmx_pci_cfg19_s cn38xx;
+ struct cvmx_pci_cfg19_s cn38xxp2;
+ struct cvmx_pci_cfg19_s cn50xx;
+ struct cvmx_pci_cfg19_s cn58xx;
+ struct cvmx_pci_cfg19_s cn58xxp1;
+};
+
+union cvmx_pci_cfg20 {
+ uint32_t u32;
+ struct cvmx_pci_cfg20_s {
+ uint32_t mdsp:32;
+ } s;
+ struct cvmx_pci_cfg20_s cn30xx;
+ struct cvmx_pci_cfg20_s cn31xx;
+ struct cvmx_pci_cfg20_s cn38xx;
+ struct cvmx_pci_cfg20_s cn38xxp2;
+ struct cvmx_pci_cfg20_s cn50xx;
+ struct cvmx_pci_cfg20_s cn58xx;
+ struct cvmx_pci_cfg20_s cn58xxp1;
+};
+
+union cvmx_pci_cfg21 {
+ uint32_t u32;
+ struct cvmx_pci_cfg21_s {
+ uint32_t scmre:32;
+ } s;
+ struct cvmx_pci_cfg21_s cn30xx;
+ struct cvmx_pci_cfg21_s cn31xx;
+ struct cvmx_pci_cfg21_s cn38xx;
+ struct cvmx_pci_cfg21_s cn38xxp2;
+ struct cvmx_pci_cfg21_s cn50xx;
+ struct cvmx_pci_cfg21_s cn58xx;
+ struct cvmx_pci_cfg21_s cn58xxp1;
+};
+
+union cvmx_pci_cfg22 {
+ uint32_t u32;
+ struct cvmx_pci_cfg22_s {
+ uint32_t mac:7;
+ uint32_t reserved_19_24:6;
+ uint32_t flush:1;
+ uint32_t mra:1;
+ uint32_t mtta:1;
+ uint32_t mrv:8;
+ uint32_t mttv:8;
+ } s;
+ struct cvmx_pci_cfg22_s cn30xx;
+ struct cvmx_pci_cfg22_s cn31xx;
+ struct cvmx_pci_cfg22_s cn38xx;
+ struct cvmx_pci_cfg22_s cn38xxp2;
+ struct cvmx_pci_cfg22_s cn50xx;
+ struct cvmx_pci_cfg22_s cn58xx;
+ struct cvmx_pci_cfg22_s cn58xxp1;
+};
+
+union cvmx_pci_cfg56 {
+ uint32_t u32;
+ struct cvmx_pci_cfg56_s {
+ uint32_t reserved_23_31:9;
+ uint32_t most:3;
+ uint32_t mmbc:2;
+ uint32_t roe:1;
+ uint32_t dpere:1;
+ uint32_t ncp:8;
+ uint32_t pxcid:8;
+ } s;
+ struct cvmx_pci_cfg56_s cn30xx;
+ struct cvmx_pci_cfg56_s cn31xx;
+ struct cvmx_pci_cfg56_s cn38xx;
+ struct cvmx_pci_cfg56_s cn38xxp2;
+ struct cvmx_pci_cfg56_s cn50xx;
+ struct cvmx_pci_cfg56_s cn58xx;
+ struct cvmx_pci_cfg56_s cn58xxp1;
+};
+
+union cvmx_pci_cfg57 {
+ uint32_t u32;
+ struct cvmx_pci_cfg57_s {
+ uint32_t reserved_30_31:2;
+ uint32_t scemr:1;
+ uint32_t mcrsd:3;
+ uint32_t mostd:3;
+ uint32_t mmrbcd:2;
+ uint32_t dc:1;
+ uint32_t usc:1;
+ uint32_t scd:1;
+ uint32_t m133:1;
+ uint32_t w64:1;
+ uint32_t bn:8;
+ uint32_t dn:5;
+ uint32_t fn:3;
+ } s;
+ struct cvmx_pci_cfg57_s cn30xx;
+ struct cvmx_pci_cfg57_s cn31xx;
+ struct cvmx_pci_cfg57_s cn38xx;
+ struct cvmx_pci_cfg57_s cn38xxp2;
+ struct cvmx_pci_cfg57_s cn50xx;
+ struct cvmx_pci_cfg57_s cn58xx;
+ struct cvmx_pci_cfg57_s cn58xxp1;
+};
+
+union cvmx_pci_cfg58 {
+ uint32_t u32;
+ struct cvmx_pci_cfg58_s {
+ uint32_t pmes:5;
+ uint32_t d2s:1;
+ uint32_t d1s:1;
+ uint32_t auxc:3;
+ uint32_t dsi:1;
+ uint32_t reserved_20_20:1;
+ uint32_t pmec:1;
+ uint32_t pcimiv:3;
+ uint32_t ncp:8;
+ uint32_t pmcid:8;
+ } s;
+ struct cvmx_pci_cfg58_s cn30xx;
+ struct cvmx_pci_cfg58_s cn31xx;
+ struct cvmx_pci_cfg58_s cn38xx;
+ struct cvmx_pci_cfg58_s cn38xxp2;
+ struct cvmx_pci_cfg58_s cn50xx;
+ struct cvmx_pci_cfg58_s cn58xx;
+ struct cvmx_pci_cfg58_s cn58xxp1;
+};
+
+union cvmx_pci_cfg59 {
+ uint32_t u32;
+ struct cvmx_pci_cfg59_s {
+ uint32_t pmdia:8;
+ uint32_t bpccen:1;
+ uint32_t bd3h:1;
+ uint32_t reserved_16_21:6;
+ uint32_t pmess:1;
+ uint32_t pmedsia:2;
+ uint32_t pmds:4;
+ uint32_t pmeens:1;
+ uint32_t reserved_2_7:6;
+ uint32_t ps:2;
+ } s;
+ struct cvmx_pci_cfg59_s cn30xx;
+ struct cvmx_pci_cfg59_s cn31xx;
+ struct cvmx_pci_cfg59_s cn38xx;
+ struct cvmx_pci_cfg59_s cn38xxp2;
+ struct cvmx_pci_cfg59_s cn50xx;
+ struct cvmx_pci_cfg59_s cn58xx;
+ struct cvmx_pci_cfg59_s cn58xxp1;
+};
+
+union cvmx_pci_cfg60 {
+ uint32_t u32;
+ struct cvmx_pci_cfg60_s {
+ uint32_t reserved_24_31:8;
+ uint32_t m64:1;
+ uint32_t mme:3;
+ uint32_t mmc:3;
+ uint32_t msien:1;
+ uint32_t ncp:8;
+ uint32_t msicid:8;
+ } s;
+ struct cvmx_pci_cfg60_s cn30xx;
+ struct cvmx_pci_cfg60_s cn31xx;
+ struct cvmx_pci_cfg60_s cn38xx;
+ struct cvmx_pci_cfg60_s cn38xxp2;
+ struct cvmx_pci_cfg60_s cn50xx;
+ struct cvmx_pci_cfg60_s cn58xx;
+ struct cvmx_pci_cfg60_s cn58xxp1;
+};
+
+union cvmx_pci_cfg61 {
+ uint32_t u32;
+ struct cvmx_pci_cfg61_s {
+ uint32_t msi31t2:30;
+ uint32_t reserved_0_1:2;
+ } s;
+ struct cvmx_pci_cfg61_s cn30xx;
+ struct cvmx_pci_cfg61_s cn31xx;
+ struct cvmx_pci_cfg61_s cn38xx;
+ struct cvmx_pci_cfg61_s cn38xxp2;
+ struct cvmx_pci_cfg61_s cn50xx;
+ struct cvmx_pci_cfg61_s cn58xx;
+ struct cvmx_pci_cfg61_s cn58xxp1;
+};
+
+union cvmx_pci_cfg62 {
+ uint32_t u32;
+ struct cvmx_pci_cfg62_s {
+ uint32_t msi:32;
+ } s;
+ struct cvmx_pci_cfg62_s cn30xx;
+ struct cvmx_pci_cfg62_s cn31xx;
+ struct cvmx_pci_cfg62_s cn38xx;
+ struct cvmx_pci_cfg62_s cn38xxp2;
+ struct cvmx_pci_cfg62_s cn50xx;
+ struct cvmx_pci_cfg62_s cn58xx;
+ struct cvmx_pci_cfg62_s cn58xxp1;
+};
+
+union cvmx_pci_cfg63 {
+ uint32_t u32;
+ struct cvmx_pci_cfg63_s {
+ uint32_t reserved_16_31:16;
+ uint32_t msimd:16;
+ } s;
+ struct cvmx_pci_cfg63_s cn30xx;
+ struct cvmx_pci_cfg63_s cn31xx;
+ struct cvmx_pci_cfg63_s cn38xx;
+ struct cvmx_pci_cfg63_s cn38xxp2;
+ struct cvmx_pci_cfg63_s cn50xx;
+ struct cvmx_pci_cfg63_s cn58xx;
+ struct cvmx_pci_cfg63_s cn58xxp1;
+};
+
+union cvmx_pci_cnt_reg {
+ uint64_t u64;
+ struct cvmx_pci_cnt_reg_s {
+ uint64_t reserved_38_63:26;
+ uint64_t hm_pcix:1;
+ uint64_t hm_speed:2;
+ uint64_t ap_pcix:1;
+ uint64_t ap_speed:2;
+ uint64_t pcicnt:32;
+ } s;
+ struct cvmx_pci_cnt_reg_s cn50xx;
+ struct cvmx_pci_cnt_reg_s cn58xx;
+ struct cvmx_pci_cnt_reg_s cn58xxp1;
+};
+
+union cvmx_pci_ctl_status_2 {
+ uint32_t u32;
+ struct cvmx_pci_ctl_status_2_s {
+ uint32_t reserved_29_31:3;
+ uint32_t bb1_hole:3;
+ uint32_t bb1_siz:1;
+ uint32_t bb_ca:1;
+ uint32_t bb_es:2;
+ uint32_t bb1:1;
+ uint32_t bb0:1;
+ uint32_t erst_n:1;
+ uint32_t bar2pres:1;
+ uint32_t scmtyp:1;
+ uint32_t scm:1;
+ uint32_t en_wfilt:1;
+ uint32_t reserved_14_14:1;
+ uint32_t ap_pcix:1;
+ uint32_t ap_64ad:1;
+ uint32_t b12_bist:1;
+ uint32_t pmo_amod:1;
+ uint32_t pmo_fpc:3;
+ uint32_t tsr_hwm:3;
+ uint32_t bar2_enb:1;
+ uint32_t bar2_esx:2;
+ uint32_t bar2_cax:1;
+ } s;
+ struct cvmx_pci_ctl_status_2_s cn30xx;
+ struct cvmx_pci_ctl_status_2_cn31xx {
+ uint32_t reserved_20_31:12;
+ uint32_t erst_n:1;
+ uint32_t bar2pres:1;
+ uint32_t scmtyp:1;
+ uint32_t scm:1;
+ uint32_t en_wfilt:1;
+ uint32_t reserved_14_14:1;
+ uint32_t ap_pcix:1;
+ uint32_t ap_64ad:1;
+ uint32_t b12_bist:1;
+ uint32_t pmo_amod:1;
+ uint32_t pmo_fpc:3;
+ uint32_t tsr_hwm:3;
+ uint32_t bar2_enb:1;
+ uint32_t bar2_esx:2;
+ uint32_t bar2_cax:1;
+ } cn31xx;
+ struct cvmx_pci_ctl_status_2_s cn38xx;
+ struct cvmx_pci_ctl_status_2_cn31xx cn38xxp2;
+ struct cvmx_pci_ctl_status_2_s cn50xx;
+ struct cvmx_pci_ctl_status_2_s cn58xx;
+ struct cvmx_pci_ctl_status_2_s cn58xxp1;
+};
+
+union cvmx_pci_dbellx {
+ uint32_t u32;
+ struct cvmx_pci_dbellx_s {
+ uint32_t reserved_16_31:16;
+ uint32_t inc_val:16;
+ } s;
+ struct cvmx_pci_dbellx_s cn30xx;
+ struct cvmx_pci_dbellx_s cn31xx;
+ struct cvmx_pci_dbellx_s cn38xx;
+ struct cvmx_pci_dbellx_s cn38xxp2;
+ struct cvmx_pci_dbellx_s cn50xx;
+ struct cvmx_pci_dbellx_s cn58xx;
+ struct cvmx_pci_dbellx_s cn58xxp1;
+};
+
+union cvmx_pci_dma_cntx {
+ uint32_t u32;
+ struct cvmx_pci_dma_cntx_s {
+ uint32_t dma_cnt:32;
+ } s;
+ struct cvmx_pci_dma_cntx_s cn30xx;
+ struct cvmx_pci_dma_cntx_s cn31xx;
+ struct cvmx_pci_dma_cntx_s cn38xx;
+ struct cvmx_pci_dma_cntx_s cn38xxp2;
+ struct cvmx_pci_dma_cntx_s cn50xx;
+ struct cvmx_pci_dma_cntx_s cn58xx;
+ struct cvmx_pci_dma_cntx_s cn58xxp1;
+};
+
+union cvmx_pci_dma_int_levx {
+ uint32_t u32;
+ struct cvmx_pci_dma_int_levx_s {
+ uint32_t pkt_cnt:32;
+ } s;
+ struct cvmx_pci_dma_int_levx_s cn30xx;
+ struct cvmx_pci_dma_int_levx_s cn31xx;
+ struct cvmx_pci_dma_int_levx_s cn38xx;
+ struct cvmx_pci_dma_int_levx_s cn38xxp2;
+ struct cvmx_pci_dma_int_levx_s cn50xx;
+ struct cvmx_pci_dma_int_levx_s cn58xx;
+ struct cvmx_pci_dma_int_levx_s cn58xxp1;
+};
+
+union cvmx_pci_dma_timex {
+ uint32_t u32;
+ struct cvmx_pci_dma_timex_s {
+ uint32_t dma_time:32;
+ } s;
+ struct cvmx_pci_dma_timex_s cn30xx;
+ struct cvmx_pci_dma_timex_s cn31xx;
+ struct cvmx_pci_dma_timex_s cn38xx;
+ struct cvmx_pci_dma_timex_s cn38xxp2;
+ struct cvmx_pci_dma_timex_s cn50xx;
+ struct cvmx_pci_dma_timex_s cn58xx;
+ struct cvmx_pci_dma_timex_s cn58xxp1;
+};
+
+union cvmx_pci_instr_countx {
+ uint32_t u32;
+ struct cvmx_pci_instr_countx_s {
+ uint32_t icnt:32;
+ } s;
+ struct cvmx_pci_instr_countx_s cn30xx;
+ struct cvmx_pci_instr_countx_s cn31xx;
+ struct cvmx_pci_instr_countx_s cn38xx;
+ struct cvmx_pci_instr_countx_s cn38xxp2;
+ struct cvmx_pci_instr_countx_s cn50xx;
+ struct cvmx_pci_instr_countx_s cn58xx;
+ struct cvmx_pci_instr_countx_s cn58xxp1;
+};
+
+union cvmx_pci_int_enb {
+ uint64_t u64;
+ struct cvmx_pci_int_enb_s {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t idtime1:1;
+ uint64_t idtime0:1;
+ uint64_t idcnt1:1;
+ uint64_t idcnt0:1;
+ uint64_t iptime3:1;
+ uint64_t iptime2:1;
+ uint64_t iptime1:1;
+ uint64_t iptime0:1;
+ uint64_t ipcnt3:1;
+ uint64_t ipcnt2:1;
+ uint64_t ipcnt1:1;
+ uint64_t ipcnt0:1;
+ uint64_t irsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t idperr:1;
+ uint64_t iaperr:1;
+ uint64_t iserr:1;
+ uint64_t itsr_abt:1;
+ uint64_t imsc_msg:1;
+ uint64_t imsi_mabt:1;
+ uint64_t imsi_tabt:1;
+ uint64_t imsi_per:1;
+ uint64_t imr_tto:1;
+ uint64_t imr_abt:1;
+ uint64_t itr_abt:1;
+ uint64_t imr_wtto:1;
+ uint64_t imr_wabt:1;
+ uint64_t itr_wabt:1;
+ } s;
+ struct cvmx_pci_int_enb_cn30xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t idtime1:1;
+ uint64_t idtime0:1;
+ uint64_t idcnt1:1;
+ uint64_t idcnt0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t iptime0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t ipcnt0:1;
+ uint64_t irsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t idperr:1;
+ uint64_t iaperr:1;
+ uint64_t iserr:1;
+ uint64_t itsr_abt:1;
+ uint64_t imsc_msg:1;
+ uint64_t imsi_mabt:1;
+ uint64_t imsi_tabt:1;
+ uint64_t imsi_per:1;
+ uint64_t imr_tto:1;
+ uint64_t imr_abt:1;
+ uint64_t itr_abt:1;
+ uint64_t imr_wtto:1;
+ uint64_t imr_wabt:1;
+ uint64_t itr_wabt:1;
+ } cn30xx;
+ struct cvmx_pci_int_enb_cn31xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t idtime1:1;
+ uint64_t idtime0:1;
+ uint64_t idcnt1:1;
+ uint64_t idcnt0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t iptime1:1;
+ uint64_t iptime0:1;
+ uint64_t reserved_19_20:2;
+ uint64_t ipcnt1:1;
+ uint64_t ipcnt0:1;
+ uint64_t irsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t idperr:1;
+ uint64_t iaperr:1;
+ uint64_t iserr:1;
+ uint64_t itsr_abt:1;
+ uint64_t imsc_msg:1;
+ uint64_t imsi_mabt:1;
+ uint64_t imsi_tabt:1;
+ uint64_t imsi_per:1;
+ uint64_t imr_tto:1;
+ uint64_t imr_abt:1;
+ uint64_t itr_abt:1;
+ uint64_t imr_wtto:1;
+ uint64_t imr_wabt:1;
+ uint64_t itr_wabt:1;
+ } cn31xx;
+ struct cvmx_pci_int_enb_s cn38xx;
+ struct cvmx_pci_int_enb_s cn38xxp2;
+ struct cvmx_pci_int_enb_cn31xx cn50xx;
+ struct cvmx_pci_int_enb_s cn58xx;
+ struct cvmx_pci_int_enb_s cn58xxp1;
+};
+
+union cvmx_pci_int_enb2 {
+ uint64_t u64;
+ struct cvmx_pci_int_enb2_s {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t rdtime1:1;
+ uint64_t rdtime0:1;
+ uint64_t rdcnt1:1;
+ uint64_t rdcnt0:1;
+ uint64_t rptime3:1;
+ uint64_t rptime2:1;
+ uint64_t rptime1:1;
+ uint64_t rptime0:1;
+ uint64_t rpcnt3:1;
+ uint64_t rpcnt2:1;
+ uint64_t rpcnt1:1;
+ uint64_t rpcnt0:1;
+ uint64_t rrsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t rdperr:1;
+ uint64_t raperr:1;
+ uint64_t rserr:1;
+ uint64_t rtsr_abt:1;
+ uint64_t rmsc_msg:1;
+ uint64_t rmsi_mabt:1;
+ uint64_t rmsi_tabt:1;
+ uint64_t rmsi_per:1;
+ uint64_t rmr_tto:1;
+ uint64_t rmr_abt:1;
+ uint64_t rtr_abt:1;
+ uint64_t rmr_wtto:1;
+ uint64_t rmr_wabt:1;
+ uint64_t rtr_wabt:1;
+ } s;
+ struct cvmx_pci_int_enb2_cn30xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t rdtime1:1;
+ uint64_t rdtime0:1;
+ uint64_t rdcnt1:1;
+ uint64_t rdcnt0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t rptime0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t rpcnt0:1;
+ uint64_t rrsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t rdperr:1;
+ uint64_t raperr:1;
+ uint64_t rserr:1;
+ uint64_t rtsr_abt:1;
+ uint64_t rmsc_msg:1;
+ uint64_t rmsi_mabt:1;
+ uint64_t rmsi_tabt:1;
+ uint64_t rmsi_per:1;
+ uint64_t rmr_tto:1;
+ uint64_t rmr_abt:1;
+ uint64_t rtr_abt:1;
+ uint64_t rmr_wtto:1;
+ uint64_t rmr_wabt:1;
+ uint64_t rtr_wabt:1;
+ } cn30xx;
+ struct cvmx_pci_int_enb2_cn31xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t rdtime1:1;
+ uint64_t rdtime0:1;
+ uint64_t rdcnt1:1;
+ uint64_t rdcnt0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t rptime1:1;
+ uint64_t rptime0:1;
+ uint64_t reserved_19_20:2;
+ uint64_t rpcnt1:1;
+ uint64_t rpcnt0:1;
+ uint64_t rrsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t rdperr:1;
+ uint64_t raperr:1;
+ uint64_t rserr:1;
+ uint64_t rtsr_abt:1;
+ uint64_t rmsc_msg:1;
+ uint64_t rmsi_mabt:1;
+ uint64_t rmsi_tabt:1;
+ uint64_t rmsi_per:1;
+ uint64_t rmr_tto:1;
+ uint64_t rmr_abt:1;
+ uint64_t rtr_abt:1;
+ uint64_t rmr_wtto:1;
+ uint64_t rmr_wabt:1;
+ uint64_t rtr_wabt:1;
+ } cn31xx;
+ struct cvmx_pci_int_enb2_s cn38xx;
+ struct cvmx_pci_int_enb2_s cn38xxp2;
+ struct cvmx_pci_int_enb2_cn31xx cn50xx;
+ struct cvmx_pci_int_enb2_s cn58xx;
+ struct cvmx_pci_int_enb2_s cn58xxp1;
+};
+
+union cvmx_pci_int_sum {
+ uint64_t u64;
+ struct cvmx_pci_int_sum_s {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t ptime3:1;
+ uint64_t ptime2:1;
+ uint64_t ptime1:1;
+ uint64_t ptime0:1;
+ uint64_t pcnt3:1;
+ uint64_t pcnt2:1;
+ uint64_t pcnt1:1;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } s;
+ struct cvmx_pci_int_sum_cn30xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t ptime0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } cn30xx;
+ struct cvmx_pci_int_sum_cn31xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t ptime1:1;
+ uint64_t ptime0:1;
+ uint64_t reserved_19_20:2;
+ uint64_t pcnt1:1;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } cn31xx;
+ struct cvmx_pci_int_sum_s cn38xx;
+ struct cvmx_pci_int_sum_s cn38xxp2;
+ struct cvmx_pci_int_sum_cn31xx cn50xx;
+ struct cvmx_pci_int_sum_s cn58xx;
+ struct cvmx_pci_int_sum_s cn58xxp1;
+};
+
+union cvmx_pci_int_sum2 {
+ uint64_t u64;
+ struct cvmx_pci_int_sum2_s {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t ptime3:1;
+ uint64_t ptime2:1;
+ uint64_t ptime1:1;
+ uint64_t ptime0:1;
+ uint64_t pcnt3:1;
+ uint64_t pcnt2:1;
+ uint64_t pcnt1:1;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } s;
+ struct cvmx_pci_int_sum2_cn30xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t ptime0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } cn30xx;
+ struct cvmx_pci_int_sum2_cn31xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t ptime1:1;
+ uint64_t ptime0:1;
+ uint64_t reserved_19_20:2;
+ uint64_t pcnt1:1;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } cn31xx;
+ struct cvmx_pci_int_sum2_s cn38xx;
+ struct cvmx_pci_int_sum2_s cn38xxp2;
+ struct cvmx_pci_int_sum2_cn31xx cn50xx;
+ struct cvmx_pci_int_sum2_s cn58xx;
+ struct cvmx_pci_int_sum2_s cn58xxp1;
+};
+
+union cvmx_pci_msi_rcv {
+ uint32_t u32;
+ struct cvmx_pci_msi_rcv_s {
+ uint32_t reserved_6_31:26;
+ uint32_t intr:6;
+ } s;
+ struct cvmx_pci_msi_rcv_s cn30xx;
+ struct cvmx_pci_msi_rcv_s cn31xx;
+ struct cvmx_pci_msi_rcv_s cn38xx;
+ struct cvmx_pci_msi_rcv_s cn38xxp2;
+ struct cvmx_pci_msi_rcv_s cn50xx;
+ struct cvmx_pci_msi_rcv_s cn58xx;
+ struct cvmx_pci_msi_rcv_s cn58xxp1;
+};
+
+union cvmx_pci_pkt_creditsx {
+ uint32_t u32;
+ struct cvmx_pci_pkt_creditsx_s {
+ uint32_t pkt_cnt:16;
+ uint32_t ptr_cnt:16;
+ } s;
+ struct cvmx_pci_pkt_creditsx_s cn30xx;
+ struct cvmx_pci_pkt_creditsx_s cn31xx;
+ struct cvmx_pci_pkt_creditsx_s cn38xx;
+ struct cvmx_pci_pkt_creditsx_s cn38xxp2;
+ struct cvmx_pci_pkt_creditsx_s cn50xx;
+ struct cvmx_pci_pkt_creditsx_s cn58xx;
+ struct cvmx_pci_pkt_creditsx_s cn58xxp1;
+};
+
+union cvmx_pci_pkts_sentx {
+ uint32_t u32;
+ struct cvmx_pci_pkts_sentx_s {
+ uint32_t pkt_cnt:32;
+ } s;
+ struct cvmx_pci_pkts_sentx_s cn30xx;
+ struct cvmx_pci_pkts_sentx_s cn31xx;
+ struct cvmx_pci_pkts_sentx_s cn38xx;
+ struct cvmx_pci_pkts_sentx_s cn38xxp2;
+ struct cvmx_pci_pkts_sentx_s cn50xx;
+ struct cvmx_pci_pkts_sentx_s cn58xx;
+ struct cvmx_pci_pkts_sentx_s cn58xxp1;
+};
+
+union cvmx_pci_pkts_sent_int_levx {
+ uint32_t u32;
+ struct cvmx_pci_pkts_sent_int_levx_s {
+ uint32_t pkt_cnt:32;
+ } s;
+ struct cvmx_pci_pkts_sent_int_levx_s cn30xx;
+ struct cvmx_pci_pkts_sent_int_levx_s cn31xx;
+ struct cvmx_pci_pkts_sent_int_levx_s cn38xx;
+ struct cvmx_pci_pkts_sent_int_levx_s cn38xxp2;
+ struct cvmx_pci_pkts_sent_int_levx_s cn50xx;
+ struct cvmx_pci_pkts_sent_int_levx_s cn58xx;
+ struct cvmx_pci_pkts_sent_int_levx_s cn58xxp1;
+};
+
+union cvmx_pci_pkts_sent_timex {
+ uint32_t u32;
+ struct cvmx_pci_pkts_sent_timex_s {
+ uint32_t pkt_time:32;
+ } s;
+ struct cvmx_pci_pkts_sent_timex_s cn30xx;
+ struct cvmx_pci_pkts_sent_timex_s cn31xx;
+ struct cvmx_pci_pkts_sent_timex_s cn38xx;
+ struct cvmx_pci_pkts_sent_timex_s cn38xxp2;
+ struct cvmx_pci_pkts_sent_timex_s cn50xx;
+ struct cvmx_pci_pkts_sent_timex_s cn58xx;
+ struct cvmx_pci_pkts_sent_timex_s cn58xxp1;
+};
+
+union cvmx_pci_read_cmd_6 {
+ uint32_t u32;
+ struct cvmx_pci_read_cmd_6_s {
+ uint32_t reserved_9_31:23;
+ uint32_t min_data:6;
+ uint32_t prefetch:3;
+ } s;
+ struct cvmx_pci_read_cmd_6_s cn30xx;
+ struct cvmx_pci_read_cmd_6_s cn31xx;
+ struct cvmx_pci_read_cmd_6_s cn38xx;
+ struct cvmx_pci_read_cmd_6_s cn38xxp2;
+ struct cvmx_pci_read_cmd_6_s cn50xx;
+ struct cvmx_pci_read_cmd_6_s cn58xx;
+ struct cvmx_pci_read_cmd_6_s cn58xxp1;
+};
+
+union cvmx_pci_read_cmd_c {
+ uint32_t u32;
+ struct cvmx_pci_read_cmd_c_s {
+ uint32_t reserved_9_31:23;
+ uint32_t min_data:6;
+ uint32_t prefetch:3;
+ } s;
+ struct cvmx_pci_read_cmd_c_s cn30xx;
+ struct cvmx_pci_read_cmd_c_s cn31xx;
+ struct cvmx_pci_read_cmd_c_s cn38xx;
+ struct cvmx_pci_read_cmd_c_s cn38xxp2;
+ struct cvmx_pci_read_cmd_c_s cn50xx;
+ struct cvmx_pci_read_cmd_c_s cn58xx;
+ struct cvmx_pci_read_cmd_c_s cn58xxp1;
+};
+
+union cvmx_pci_read_cmd_e {
+ uint32_t u32;
+ struct cvmx_pci_read_cmd_e_s {
+ uint32_t reserved_9_31:23;
+ uint32_t min_data:6;
+ uint32_t prefetch:3;
+ } s;
+ struct cvmx_pci_read_cmd_e_s cn30xx;
+ struct cvmx_pci_read_cmd_e_s cn31xx;
+ struct cvmx_pci_read_cmd_e_s cn38xx;
+ struct cvmx_pci_read_cmd_e_s cn38xxp2;
+ struct cvmx_pci_read_cmd_e_s cn50xx;
+ struct cvmx_pci_read_cmd_e_s cn58xx;
+ struct cvmx_pci_read_cmd_e_s cn58xxp1;
+};
+
+union cvmx_pci_read_timeout {
+ uint64_t u64;
+ struct cvmx_pci_read_timeout_s {
+ uint64_t reserved_32_63:32;
+ uint64_t enb:1;
+ uint64_t cnt:31;
+ } s;
+ struct cvmx_pci_read_timeout_s cn30xx;
+ struct cvmx_pci_read_timeout_s cn31xx;
+ struct cvmx_pci_read_timeout_s cn38xx;
+ struct cvmx_pci_read_timeout_s cn38xxp2;
+ struct cvmx_pci_read_timeout_s cn50xx;
+ struct cvmx_pci_read_timeout_s cn58xx;
+ struct cvmx_pci_read_timeout_s cn58xxp1;
+};
+
+union cvmx_pci_scm_reg {
+ uint64_t u64;
+ struct cvmx_pci_scm_reg_s {
+ uint64_t reserved_32_63:32;
+ uint64_t scm:32;
+ } s;
+ struct cvmx_pci_scm_reg_s cn30xx;
+ struct cvmx_pci_scm_reg_s cn31xx;
+ struct cvmx_pci_scm_reg_s cn38xx;
+ struct cvmx_pci_scm_reg_s cn38xxp2;
+ struct cvmx_pci_scm_reg_s cn50xx;
+ struct cvmx_pci_scm_reg_s cn58xx;
+ struct cvmx_pci_scm_reg_s cn58xxp1;
+};
+
+union cvmx_pci_tsr_reg {
+ uint64_t u64;
+ struct cvmx_pci_tsr_reg_s {
+ uint64_t reserved_36_63:28;
+ uint64_t tsr:36;
+ } s;
+ struct cvmx_pci_tsr_reg_s cn30xx;
+ struct cvmx_pci_tsr_reg_s cn31xx;
+ struct cvmx_pci_tsr_reg_s cn38xx;
+ struct cvmx_pci_tsr_reg_s cn38xxp2;
+ struct cvmx_pci_tsr_reg_s cn50xx;
+ struct cvmx_pci_tsr_reg_s cn58xx;
+ struct cvmx_pci_tsr_reg_s cn58xxp1;
+};
+
+union cvmx_pci_win_rd_addr {
+ uint64_t u64;
+ struct cvmx_pci_win_rd_addr_s {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t reserved_0_47:48;
+ } s;
+ struct cvmx_pci_win_rd_addr_cn30xx {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t rd_addr:46;
+ uint64_t reserved_0_1:2;
+ } cn30xx;
+ struct cvmx_pci_win_rd_addr_cn30xx cn31xx;
+ struct cvmx_pci_win_rd_addr_cn38xx {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t rd_addr:45;
+ uint64_t reserved_0_2:3;
+ } cn38xx;
+ struct cvmx_pci_win_rd_addr_cn38xx cn38xxp2;
+ struct cvmx_pci_win_rd_addr_cn30xx cn50xx;
+ struct cvmx_pci_win_rd_addr_cn38xx cn58xx;
+ struct cvmx_pci_win_rd_addr_cn38xx cn58xxp1;
+};
+
+union cvmx_pci_win_rd_data {
+ uint64_t u64;
+ struct cvmx_pci_win_rd_data_s {
+ uint64_t rd_data:64;
+ } s;
+ struct cvmx_pci_win_rd_data_s cn30xx;
+ struct cvmx_pci_win_rd_data_s cn31xx;
+ struct cvmx_pci_win_rd_data_s cn38xx;
+ struct cvmx_pci_win_rd_data_s cn38xxp2;
+ struct cvmx_pci_win_rd_data_s cn50xx;
+ struct cvmx_pci_win_rd_data_s cn58xx;
+ struct cvmx_pci_win_rd_data_s cn58xxp1;
+};
+
+union cvmx_pci_win_wr_addr {
+ uint64_t u64;
+ struct cvmx_pci_win_wr_addr_s {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t wr_addr:45;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_pci_win_wr_addr_s cn30xx;
+ struct cvmx_pci_win_wr_addr_s cn31xx;
+ struct cvmx_pci_win_wr_addr_s cn38xx;
+ struct cvmx_pci_win_wr_addr_s cn38xxp2;
+ struct cvmx_pci_win_wr_addr_s cn50xx;
+ struct cvmx_pci_win_wr_addr_s cn58xx;
+ struct cvmx_pci_win_wr_addr_s cn58xxp1;
+};
+
+union cvmx_pci_win_wr_data {
+ uint64_t u64;
+ struct cvmx_pci_win_wr_data_s {
+ uint64_t wr_data:64;
+ } s;
+ struct cvmx_pci_win_wr_data_s cn30xx;
+ struct cvmx_pci_win_wr_data_s cn31xx;
+ struct cvmx_pci_win_wr_data_s cn38xx;
+ struct cvmx_pci_win_wr_data_s cn38xxp2;
+ struct cvmx_pci_win_wr_data_s cn50xx;
+ struct cvmx_pci_win_wr_data_s cn58xx;
+ struct cvmx_pci_win_wr_data_s cn58xxp1;
+};
+
+union cvmx_pci_win_wr_mask {
+ uint64_t u64;
+ struct cvmx_pci_win_wr_mask_s {
+ uint64_t reserved_8_63:56;
+ uint64_t wr_mask:8;
+ } s;
+ struct cvmx_pci_win_wr_mask_s cn30xx;
+ struct cvmx_pci_win_wr_mask_s cn31xx;
+ struct cvmx_pci_win_wr_mask_s cn38xx;
+ struct cvmx_pci_win_wr_mask_s cn38xxp2;
+ struct cvmx_pci_win_wr_mask_s cn50xx;
+ struct cvmx_pci_win_wr_mask_s cn58xx;
+ struct cvmx_pci_win_wr_mask_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h b/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h
new file mode 100644
index 000000000000..d553f8e88df6
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h
@@ -0,0 +1,1365 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCIEEP_DEFS_H__
+#define __CVMX_PCIEEP_DEFS_H__
+
+#define CVMX_PCIEEP_CFG000 \
+ (0x0000000000000000ull)
+#define CVMX_PCIEEP_CFG001 \
+ (0x0000000000000004ull)
+#define CVMX_PCIEEP_CFG002 \
+ (0x0000000000000008ull)
+#define CVMX_PCIEEP_CFG003 \
+ (0x000000000000000Cull)
+#define CVMX_PCIEEP_CFG004 \
+ (0x0000000000000010ull)
+#define CVMX_PCIEEP_CFG004_MASK \
+ (0x0000000080000010ull)
+#define CVMX_PCIEEP_CFG005 \
+ (0x0000000000000014ull)
+#define CVMX_PCIEEP_CFG005_MASK \
+ (0x0000000080000014ull)
+#define CVMX_PCIEEP_CFG006 \
+ (0x0000000000000018ull)
+#define CVMX_PCIEEP_CFG006_MASK \
+ (0x0000000080000018ull)
+#define CVMX_PCIEEP_CFG007 \
+ (0x000000000000001Cull)
+#define CVMX_PCIEEP_CFG007_MASK \
+ (0x000000008000001Cull)
+#define CVMX_PCIEEP_CFG008 \
+ (0x0000000000000020ull)
+#define CVMX_PCIEEP_CFG008_MASK \
+ (0x0000000080000020ull)
+#define CVMX_PCIEEP_CFG009 \
+ (0x0000000000000024ull)
+#define CVMX_PCIEEP_CFG009_MASK \
+ (0x0000000080000024ull)
+#define CVMX_PCIEEP_CFG010 \
+ (0x0000000000000028ull)
+#define CVMX_PCIEEP_CFG011 \
+ (0x000000000000002Cull)
+#define CVMX_PCIEEP_CFG012 \
+ (0x0000000000000030ull)
+#define CVMX_PCIEEP_CFG012_MASK \
+ (0x0000000080000030ull)
+#define CVMX_PCIEEP_CFG013 \
+ (0x0000000000000034ull)
+#define CVMX_PCIEEP_CFG015 \
+ (0x000000000000003Cull)
+#define CVMX_PCIEEP_CFG016 \
+ (0x0000000000000040ull)
+#define CVMX_PCIEEP_CFG017 \
+ (0x0000000000000044ull)
+#define CVMX_PCIEEP_CFG020 \
+ (0x0000000000000050ull)
+#define CVMX_PCIEEP_CFG021 \
+ (0x0000000000000054ull)
+#define CVMX_PCIEEP_CFG022 \
+ (0x0000000000000058ull)
+#define CVMX_PCIEEP_CFG023 \
+ (0x000000000000005Cull)
+#define CVMX_PCIEEP_CFG028 \
+ (0x0000000000000070ull)
+#define CVMX_PCIEEP_CFG029 \
+ (0x0000000000000074ull)
+#define CVMX_PCIEEP_CFG030 \
+ (0x0000000000000078ull)
+#define CVMX_PCIEEP_CFG031 \
+ (0x000000000000007Cull)
+#define CVMX_PCIEEP_CFG032 \
+ (0x0000000000000080ull)
+#define CVMX_PCIEEP_CFG033 \
+ (0x0000000000000084ull)
+#define CVMX_PCIEEP_CFG034 \
+ (0x0000000000000088ull)
+#define CVMX_PCIEEP_CFG037 \
+ (0x0000000000000094ull)
+#define CVMX_PCIEEP_CFG038 \
+ (0x0000000000000098ull)
+#define CVMX_PCIEEP_CFG039 \
+ (0x000000000000009Cull)
+#define CVMX_PCIEEP_CFG040 \
+ (0x00000000000000A0ull)
+#define CVMX_PCIEEP_CFG041 \
+ (0x00000000000000A4ull)
+#define CVMX_PCIEEP_CFG042 \
+ (0x00000000000000A8ull)
+#define CVMX_PCIEEP_CFG064 \
+ (0x0000000000000100ull)
+#define CVMX_PCIEEP_CFG065 \
+ (0x0000000000000104ull)
+#define CVMX_PCIEEP_CFG066 \
+ (0x0000000000000108ull)
+#define CVMX_PCIEEP_CFG067 \
+ (0x000000000000010Cull)
+#define CVMX_PCIEEP_CFG068 \
+ (0x0000000000000110ull)
+#define CVMX_PCIEEP_CFG069 \
+ (0x0000000000000114ull)
+#define CVMX_PCIEEP_CFG070 \
+ (0x0000000000000118ull)
+#define CVMX_PCIEEP_CFG071 \
+ (0x000000000000011Cull)
+#define CVMX_PCIEEP_CFG072 \
+ (0x0000000000000120ull)
+#define CVMX_PCIEEP_CFG073 \
+ (0x0000000000000124ull)
+#define CVMX_PCIEEP_CFG074 \
+ (0x0000000000000128ull)
+#define CVMX_PCIEEP_CFG448 \
+ (0x0000000000000700ull)
+#define CVMX_PCIEEP_CFG449 \
+ (0x0000000000000704ull)
+#define CVMX_PCIEEP_CFG450 \
+ (0x0000000000000708ull)
+#define CVMX_PCIEEP_CFG451 \
+ (0x000000000000070Cull)
+#define CVMX_PCIEEP_CFG452 \
+ (0x0000000000000710ull)
+#define CVMX_PCIEEP_CFG453 \
+ (0x0000000000000714ull)
+#define CVMX_PCIEEP_CFG454 \
+ (0x0000000000000718ull)
+#define CVMX_PCIEEP_CFG455 \
+ (0x000000000000071Cull)
+#define CVMX_PCIEEP_CFG456 \
+ (0x0000000000000720ull)
+#define CVMX_PCIEEP_CFG458 \
+ (0x0000000000000728ull)
+#define CVMX_PCIEEP_CFG459 \
+ (0x000000000000072Cull)
+#define CVMX_PCIEEP_CFG460 \
+ (0x0000000000000730ull)
+#define CVMX_PCIEEP_CFG461 \
+ (0x0000000000000734ull)
+#define CVMX_PCIEEP_CFG462 \
+ (0x0000000000000738ull)
+#define CVMX_PCIEEP_CFG463 \
+ (0x000000000000073Cull)
+#define CVMX_PCIEEP_CFG464 \
+ (0x0000000000000740ull)
+#define CVMX_PCIEEP_CFG465 \
+ (0x0000000000000744ull)
+#define CVMX_PCIEEP_CFG466 \
+ (0x0000000000000748ull)
+#define CVMX_PCIEEP_CFG467 \
+ (0x000000000000074Cull)
+#define CVMX_PCIEEP_CFG468 \
+ (0x0000000000000750ull)
+#define CVMX_PCIEEP_CFG490 \
+ (0x00000000000007A8ull)
+#define CVMX_PCIEEP_CFG491 \
+ (0x00000000000007ACull)
+#define CVMX_PCIEEP_CFG492 \
+ (0x00000000000007B0ull)
+#define CVMX_PCIEEP_CFG516 \
+ (0x0000000000000810ull)
+#define CVMX_PCIEEP_CFG517 \
+ (0x0000000000000814ull)
+
+union cvmx_pcieep_cfg000 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg000_s {
+ uint32_t devid:16;
+ uint32_t vendid:16;
+ } s;
+ struct cvmx_pcieep_cfg000_s cn52xx;
+ struct cvmx_pcieep_cfg000_s cn52xxp1;
+ struct cvmx_pcieep_cfg000_s cn56xx;
+ struct cvmx_pcieep_cfg000_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg001 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg001_s {
+ uint32_t dpe:1;
+ uint32_t sse:1;
+ uint32_t rma:1;
+ uint32_t rta:1;
+ uint32_t sta:1;
+ uint32_t devt:2;
+ uint32_t mdpe:1;
+ uint32_t fbb:1;
+ uint32_t reserved_22_22:1;
+ uint32_t m66:1;
+ uint32_t cl:1;
+ uint32_t i_stat:1;
+ uint32_t reserved_11_18:8;
+ uint32_t i_dis:1;
+ uint32_t fbbe:1;
+ uint32_t see:1;
+ uint32_t ids_wcc:1;
+ uint32_t per:1;
+ uint32_t vps:1;
+ uint32_t mwice:1;
+ uint32_t scse:1;
+ uint32_t me:1;
+ uint32_t msae:1;
+ uint32_t isae:1;
+ } s;
+ struct cvmx_pcieep_cfg001_s cn52xx;
+ struct cvmx_pcieep_cfg001_s cn52xxp1;
+ struct cvmx_pcieep_cfg001_s cn56xx;
+ struct cvmx_pcieep_cfg001_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg002 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg002_s {
+ uint32_t bcc:8;
+ uint32_t sc:8;
+ uint32_t pi:8;
+ uint32_t rid:8;
+ } s;
+ struct cvmx_pcieep_cfg002_s cn52xx;
+ struct cvmx_pcieep_cfg002_s cn52xxp1;
+ struct cvmx_pcieep_cfg002_s cn56xx;
+ struct cvmx_pcieep_cfg002_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg003 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg003_s {
+ uint32_t bist:8;
+ uint32_t mfd:1;
+ uint32_t chf:7;
+ uint32_t lt:8;
+ uint32_t cls:8;
+ } s;
+ struct cvmx_pcieep_cfg003_s cn52xx;
+ struct cvmx_pcieep_cfg003_s cn52xxp1;
+ struct cvmx_pcieep_cfg003_s cn56xx;
+ struct cvmx_pcieep_cfg003_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg004 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg004_s {
+ uint32_t lbab:18;
+ uint32_t reserved_4_13:10;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pcieep_cfg004_s cn52xx;
+ struct cvmx_pcieep_cfg004_s cn52xxp1;
+ struct cvmx_pcieep_cfg004_s cn56xx;
+ struct cvmx_pcieep_cfg004_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg004_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg004_mask_s {
+ uint32_t lmask:31;
+ uint32_t enb:1;
+ } s;
+ struct cvmx_pcieep_cfg004_mask_s cn52xx;
+ struct cvmx_pcieep_cfg004_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg004_mask_s cn56xx;
+ struct cvmx_pcieep_cfg004_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg005 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg005_s {
+ uint32_t ubab:32;
+ } s;
+ struct cvmx_pcieep_cfg005_s cn52xx;
+ struct cvmx_pcieep_cfg005_s cn52xxp1;
+ struct cvmx_pcieep_cfg005_s cn56xx;
+ struct cvmx_pcieep_cfg005_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg005_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg005_mask_s {
+ uint32_t umask:32;
+ } s;
+ struct cvmx_pcieep_cfg005_mask_s cn52xx;
+ struct cvmx_pcieep_cfg005_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg005_mask_s cn56xx;
+ struct cvmx_pcieep_cfg005_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg006 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg006_s {
+ uint32_t lbab:6;
+ uint32_t reserved_4_25:22;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pcieep_cfg006_s cn52xx;
+ struct cvmx_pcieep_cfg006_s cn52xxp1;
+ struct cvmx_pcieep_cfg006_s cn56xx;
+ struct cvmx_pcieep_cfg006_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg006_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg006_mask_s {
+ uint32_t lmask:31;
+ uint32_t enb:1;
+ } s;
+ struct cvmx_pcieep_cfg006_mask_s cn52xx;
+ struct cvmx_pcieep_cfg006_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg006_mask_s cn56xx;
+ struct cvmx_pcieep_cfg006_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg007 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg007_s {
+ uint32_t ubab:32;
+ } s;
+ struct cvmx_pcieep_cfg007_s cn52xx;
+ struct cvmx_pcieep_cfg007_s cn52xxp1;
+ struct cvmx_pcieep_cfg007_s cn56xx;
+ struct cvmx_pcieep_cfg007_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg007_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg007_mask_s {
+ uint32_t umask:32;
+ } s;
+ struct cvmx_pcieep_cfg007_mask_s cn52xx;
+ struct cvmx_pcieep_cfg007_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg007_mask_s cn56xx;
+ struct cvmx_pcieep_cfg007_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg008 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg008_s {
+ uint32_t reserved_4_31:28;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pcieep_cfg008_s cn52xx;
+ struct cvmx_pcieep_cfg008_s cn52xxp1;
+ struct cvmx_pcieep_cfg008_s cn56xx;
+ struct cvmx_pcieep_cfg008_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg008_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg008_mask_s {
+ uint32_t lmask:31;
+ uint32_t enb:1;
+ } s;
+ struct cvmx_pcieep_cfg008_mask_s cn52xx;
+ struct cvmx_pcieep_cfg008_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg008_mask_s cn56xx;
+ struct cvmx_pcieep_cfg008_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg009 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg009_s {
+ uint32_t ubab:25;
+ uint32_t reserved_0_6:7;
+ } s;
+ struct cvmx_pcieep_cfg009_s cn52xx;
+ struct cvmx_pcieep_cfg009_s cn52xxp1;
+ struct cvmx_pcieep_cfg009_s cn56xx;
+ struct cvmx_pcieep_cfg009_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg009_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg009_mask_s {
+ uint32_t umask:32;
+ } s;
+ struct cvmx_pcieep_cfg009_mask_s cn52xx;
+ struct cvmx_pcieep_cfg009_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg009_mask_s cn56xx;
+ struct cvmx_pcieep_cfg009_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg010 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg010_s {
+ uint32_t cisp:32;
+ } s;
+ struct cvmx_pcieep_cfg010_s cn52xx;
+ struct cvmx_pcieep_cfg010_s cn52xxp1;
+ struct cvmx_pcieep_cfg010_s cn56xx;
+ struct cvmx_pcieep_cfg010_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg011 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg011_s {
+ uint32_t ssid:16;
+ uint32_t ssvid:16;
+ } s;
+ struct cvmx_pcieep_cfg011_s cn52xx;
+ struct cvmx_pcieep_cfg011_s cn52xxp1;
+ struct cvmx_pcieep_cfg011_s cn56xx;
+ struct cvmx_pcieep_cfg011_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg012 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg012_s {
+ uint32_t eraddr:16;
+ uint32_t reserved_1_15:15;
+ uint32_t er_en:1;
+ } s;
+ struct cvmx_pcieep_cfg012_s cn52xx;
+ struct cvmx_pcieep_cfg012_s cn52xxp1;
+ struct cvmx_pcieep_cfg012_s cn56xx;
+ struct cvmx_pcieep_cfg012_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg012_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg012_mask_s {
+ uint32_t mask:31;
+ uint32_t enb:1;
+ } s;
+ struct cvmx_pcieep_cfg012_mask_s cn52xx;
+ struct cvmx_pcieep_cfg012_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg012_mask_s cn56xx;
+ struct cvmx_pcieep_cfg012_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg013 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg013_s {
+ uint32_t reserved_8_31:24;
+ uint32_t cp:8;
+ } s;
+ struct cvmx_pcieep_cfg013_s cn52xx;
+ struct cvmx_pcieep_cfg013_s cn52xxp1;
+ struct cvmx_pcieep_cfg013_s cn56xx;
+ struct cvmx_pcieep_cfg013_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg015 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg015_s {
+ uint32_t ml:8;
+ uint32_t mg:8;
+ uint32_t inta:8;
+ uint32_t il:8;
+ } s;
+ struct cvmx_pcieep_cfg015_s cn52xx;
+ struct cvmx_pcieep_cfg015_s cn52xxp1;
+ struct cvmx_pcieep_cfg015_s cn56xx;
+ struct cvmx_pcieep_cfg015_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg016 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg016_s {
+ uint32_t pmes:5;
+ uint32_t d2s:1;
+ uint32_t d1s:1;
+ uint32_t auxc:3;
+ uint32_t dsi:1;
+ uint32_t reserved_20_20:1;
+ uint32_t pme_clock:1;
+ uint32_t pmsv:3;
+ uint32_t ncp:8;
+ uint32_t pmcid:8;
+ } s;
+ struct cvmx_pcieep_cfg016_s cn52xx;
+ struct cvmx_pcieep_cfg016_s cn52xxp1;
+ struct cvmx_pcieep_cfg016_s cn56xx;
+ struct cvmx_pcieep_cfg016_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg017 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg017_s {
+ uint32_t pmdia:8;
+ uint32_t bpccee:1;
+ uint32_t bd3h:1;
+ uint32_t reserved_16_21:6;
+ uint32_t pmess:1;
+ uint32_t pmedsia:2;
+ uint32_t pmds:4;
+ uint32_t pmeens:1;
+ uint32_t reserved_4_7:4;
+ uint32_t nsr:1;
+ uint32_t reserved_2_2:1;
+ uint32_t ps:2;
+ } s;
+ struct cvmx_pcieep_cfg017_s cn52xx;
+ struct cvmx_pcieep_cfg017_s cn52xxp1;
+ struct cvmx_pcieep_cfg017_s cn56xx;
+ struct cvmx_pcieep_cfg017_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg020 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg020_s {
+ uint32_t reserved_24_31:8;
+ uint32_t m64:1;
+ uint32_t mme:3;
+ uint32_t mmc:3;
+ uint32_t msien:1;
+ uint32_t ncp:8;
+ uint32_t msicid:8;
+ } s;
+ struct cvmx_pcieep_cfg020_s cn52xx;
+ struct cvmx_pcieep_cfg020_s cn52xxp1;
+ struct cvmx_pcieep_cfg020_s cn56xx;
+ struct cvmx_pcieep_cfg020_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg021 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg021_s {
+ uint32_t lmsi:30;
+ uint32_t reserved_0_1:2;
+ } s;
+ struct cvmx_pcieep_cfg021_s cn52xx;
+ struct cvmx_pcieep_cfg021_s cn52xxp1;
+ struct cvmx_pcieep_cfg021_s cn56xx;
+ struct cvmx_pcieep_cfg021_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg022 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg022_s {
+ uint32_t umsi:32;
+ } s;
+ struct cvmx_pcieep_cfg022_s cn52xx;
+ struct cvmx_pcieep_cfg022_s cn52xxp1;
+ struct cvmx_pcieep_cfg022_s cn56xx;
+ struct cvmx_pcieep_cfg022_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg023 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg023_s {
+ uint32_t reserved_16_31:16;
+ uint32_t msimd:16;
+ } s;
+ struct cvmx_pcieep_cfg023_s cn52xx;
+ struct cvmx_pcieep_cfg023_s cn52xxp1;
+ struct cvmx_pcieep_cfg023_s cn56xx;
+ struct cvmx_pcieep_cfg023_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg028 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg028_s {
+ uint32_t reserved_30_31:2;
+ uint32_t imn:5;
+ uint32_t si:1;
+ uint32_t dpt:4;
+ uint32_t pciecv:4;
+ uint32_t ncp:8;
+ uint32_t pcieid:8;
+ } s;
+ struct cvmx_pcieep_cfg028_s cn52xx;
+ struct cvmx_pcieep_cfg028_s cn52xxp1;
+ struct cvmx_pcieep_cfg028_s cn56xx;
+ struct cvmx_pcieep_cfg028_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg029 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg029_s {
+ uint32_t reserved_28_31:4;
+ uint32_t cspls:2;
+ uint32_t csplv:8;
+ uint32_t reserved_16_17:2;
+ uint32_t rber:1;
+ uint32_t reserved_12_14:3;
+ uint32_t el1al:3;
+ uint32_t el0al:3;
+ uint32_t etfs:1;
+ uint32_t pfs:2;
+ uint32_t mpss:3;
+ } s;
+ struct cvmx_pcieep_cfg029_s cn52xx;
+ struct cvmx_pcieep_cfg029_s cn52xxp1;
+ struct cvmx_pcieep_cfg029_s cn56xx;
+ struct cvmx_pcieep_cfg029_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg030 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg030_s {
+ uint32_t reserved_22_31:10;
+ uint32_t tp:1;
+ uint32_t ap_d:1;
+ uint32_t ur_d:1;
+ uint32_t fe_d:1;
+ uint32_t nfe_d:1;
+ uint32_t ce_d:1;
+ uint32_t reserved_15_15:1;
+ uint32_t mrrs:3;
+ uint32_t ns_en:1;
+ uint32_t ap_en:1;
+ uint32_t pf_en:1;
+ uint32_t etf_en:1;
+ uint32_t mps:3;
+ uint32_t ro_en:1;
+ uint32_t ur_en:1;
+ uint32_t fe_en:1;
+ uint32_t nfe_en:1;
+ uint32_t ce_en:1;
+ } s;
+ struct cvmx_pcieep_cfg030_s cn52xx;
+ struct cvmx_pcieep_cfg030_s cn52xxp1;
+ struct cvmx_pcieep_cfg030_s cn56xx;
+ struct cvmx_pcieep_cfg030_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg031 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg031_s {
+ uint32_t pnum:8;
+ uint32_t reserved_22_23:2;
+ uint32_t lbnc:1;
+ uint32_t dllarc:1;
+ uint32_t sderc:1;
+ uint32_t cpm:1;
+ uint32_t l1el:3;
+ uint32_t l0el:3;
+ uint32_t aslpms:2;
+ uint32_t mlw:6;
+ uint32_t mls:4;
+ } s;
+ struct cvmx_pcieep_cfg031_s cn52xx;
+ struct cvmx_pcieep_cfg031_s cn52xxp1;
+ struct cvmx_pcieep_cfg031_s cn56xx;
+ struct cvmx_pcieep_cfg031_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg032 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg032_s {
+ uint32_t reserved_30_31:2;
+ uint32_t dlla:1;
+ uint32_t scc:1;
+ uint32_t lt:1;
+ uint32_t reserved_26_26:1;
+ uint32_t nlw:6;
+ uint32_t ls:4;
+ uint32_t reserved_10_15:6;
+ uint32_t hawd:1;
+ uint32_t ecpm:1;
+ uint32_t es:1;
+ uint32_t ccc:1;
+ uint32_t rl:1;
+ uint32_t ld:1;
+ uint32_t rcb:1;
+ uint32_t reserved_2_2:1;
+ uint32_t aslpc:2;
+ } s;
+ struct cvmx_pcieep_cfg032_s cn52xx;
+ struct cvmx_pcieep_cfg032_s cn52xxp1;
+ struct cvmx_pcieep_cfg032_s cn56xx;
+ struct cvmx_pcieep_cfg032_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg033 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg033_s {
+ uint32_t ps_num:13;
+ uint32_t nccs:1;
+ uint32_t emip:1;
+ uint32_t sp_ls:2;
+ uint32_t sp_lv:8;
+ uint32_t hp_c:1;
+ uint32_t hp_s:1;
+ uint32_t pip:1;
+ uint32_t aip:1;
+ uint32_t mrlsp:1;
+ uint32_t pcp:1;
+ uint32_t abp:1;
+ } s;
+ struct cvmx_pcieep_cfg033_s cn52xx;
+ struct cvmx_pcieep_cfg033_s cn52xxp1;
+ struct cvmx_pcieep_cfg033_s cn56xx;
+ struct cvmx_pcieep_cfg033_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg034 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg034_s {
+ uint32_t reserved_25_31:7;
+ uint32_t dlls_c:1;
+ uint32_t emis:1;
+ uint32_t pds:1;
+ uint32_t mrlss:1;
+ uint32_t ccint_d:1;
+ uint32_t pd_c:1;
+ uint32_t mrls_c:1;
+ uint32_t pf_d:1;
+ uint32_t abp_d:1;
+ uint32_t reserved_13_15:3;
+ uint32_t dlls_en:1;
+ uint32_t emic:1;
+ uint32_t pcc:1;
+ uint32_t pic:2;
+ uint32_t aic:2;
+ uint32_t hpint_en:1;
+ uint32_t ccint_en:1;
+ uint32_t pd_en:1;
+ uint32_t mrls_en:1;
+ uint32_t pf_en:1;
+ uint32_t abp_en:1;
+ } s;
+ struct cvmx_pcieep_cfg034_s cn52xx;
+ struct cvmx_pcieep_cfg034_s cn52xxp1;
+ struct cvmx_pcieep_cfg034_s cn56xx;
+ struct cvmx_pcieep_cfg034_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg037 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg037_s {
+ uint32_t reserved_5_31:27;
+ uint32_t ctds:1;
+ uint32_t ctrs:4;
+ } s;
+ struct cvmx_pcieep_cfg037_s cn52xx;
+ struct cvmx_pcieep_cfg037_s cn52xxp1;
+ struct cvmx_pcieep_cfg037_s cn56xx;
+ struct cvmx_pcieep_cfg037_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg038 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg038_s {
+ uint32_t reserved_5_31:27;
+ uint32_t ctd:1;
+ uint32_t ctv:4;
+ } s;
+ struct cvmx_pcieep_cfg038_s cn52xx;
+ struct cvmx_pcieep_cfg038_s cn52xxp1;
+ struct cvmx_pcieep_cfg038_s cn56xx;
+ struct cvmx_pcieep_cfg038_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg039 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg039_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pcieep_cfg039_s cn52xx;
+ struct cvmx_pcieep_cfg039_s cn52xxp1;
+ struct cvmx_pcieep_cfg039_s cn56xx;
+ struct cvmx_pcieep_cfg039_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg040 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg040_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pcieep_cfg040_s cn52xx;
+ struct cvmx_pcieep_cfg040_s cn52xxp1;
+ struct cvmx_pcieep_cfg040_s cn56xx;
+ struct cvmx_pcieep_cfg040_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg041 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg041_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pcieep_cfg041_s cn52xx;
+ struct cvmx_pcieep_cfg041_s cn52xxp1;
+ struct cvmx_pcieep_cfg041_s cn56xx;
+ struct cvmx_pcieep_cfg041_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg042 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg042_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pcieep_cfg042_s cn52xx;
+ struct cvmx_pcieep_cfg042_s cn52xxp1;
+ struct cvmx_pcieep_cfg042_s cn56xx;
+ struct cvmx_pcieep_cfg042_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg064 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg064_s {
+ uint32_t nco:12;
+ uint32_t cv:4;
+ uint32_t pcieec:16;
+ } s;
+ struct cvmx_pcieep_cfg064_s cn52xx;
+ struct cvmx_pcieep_cfg064_s cn52xxp1;
+ struct cvmx_pcieep_cfg064_s cn56xx;
+ struct cvmx_pcieep_cfg064_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg065 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg065_s {
+ uint32_t reserved_21_31:11;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pcieep_cfg065_s cn52xx;
+ struct cvmx_pcieep_cfg065_s cn52xxp1;
+ struct cvmx_pcieep_cfg065_s cn56xx;
+ struct cvmx_pcieep_cfg065_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg066 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg066_s {
+ uint32_t reserved_21_31:11;
+ uint32_t urem:1;
+ uint32_t ecrcem:1;
+ uint32_t mtlpm:1;
+ uint32_t rom:1;
+ uint32_t ucm:1;
+ uint32_t cam:1;
+ uint32_t ctm:1;
+ uint32_t fcpem:1;
+ uint32_t ptlpm:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdem:1;
+ uint32_t dlpem:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pcieep_cfg066_s cn52xx;
+ struct cvmx_pcieep_cfg066_s cn52xxp1;
+ struct cvmx_pcieep_cfg066_s cn56xx;
+ struct cvmx_pcieep_cfg066_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg067 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg067_s {
+ uint32_t reserved_21_31:11;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pcieep_cfg067_s cn52xx;
+ struct cvmx_pcieep_cfg067_s cn52xxp1;
+ struct cvmx_pcieep_cfg067_s cn56xx;
+ struct cvmx_pcieep_cfg067_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg068 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg068_s {
+ uint32_t reserved_14_31:18;
+ uint32_t anfes:1;
+ uint32_t rtts:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rnrs:1;
+ uint32_t bdllps:1;
+ uint32_t btlps:1;
+ uint32_t reserved_1_5:5;
+ uint32_t res:1;
+ } s;
+ struct cvmx_pcieep_cfg068_s cn52xx;
+ struct cvmx_pcieep_cfg068_s cn52xxp1;
+ struct cvmx_pcieep_cfg068_s cn56xx;
+ struct cvmx_pcieep_cfg068_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg069 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg069_s {
+ uint32_t reserved_14_31:18;
+ uint32_t anfem:1;
+ uint32_t rttm:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rnrm:1;
+ uint32_t bdllpm:1;
+ uint32_t btlpm:1;
+ uint32_t reserved_1_5:5;
+ uint32_t rem:1;
+ } s;
+ struct cvmx_pcieep_cfg069_s cn52xx;
+ struct cvmx_pcieep_cfg069_s cn52xxp1;
+ struct cvmx_pcieep_cfg069_s cn56xx;
+ struct cvmx_pcieep_cfg069_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg070 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg070_s {
+ uint32_t reserved_9_31:23;
+ uint32_t ce:1;
+ uint32_t cc:1;
+ uint32_t ge:1;
+ uint32_t gc:1;
+ uint32_t fep:5;
+ } s;
+ struct cvmx_pcieep_cfg070_s cn52xx;
+ struct cvmx_pcieep_cfg070_s cn52xxp1;
+ struct cvmx_pcieep_cfg070_s cn56xx;
+ struct cvmx_pcieep_cfg070_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg071 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg071_s {
+ uint32_t dword1:32;
+ } s;
+ struct cvmx_pcieep_cfg071_s cn52xx;
+ struct cvmx_pcieep_cfg071_s cn52xxp1;
+ struct cvmx_pcieep_cfg071_s cn56xx;
+ struct cvmx_pcieep_cfg071_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg072 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg072_s {
+ uint32_t dword2:32;
+ } s;
+ struct cvmx_pcieep_cfg072_s cn52xx;
+ struct cvmx_pcieep_cfg072_s cn52xxp1;
+ struct cvmx_pcieep_cfg072_s cn56xx;
+ struct cvmx_pcieep_cfg072_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg073 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg073_s {
+ uint32_t dword3:32;
+ } s;
+ struct cvmx_pcieep_cfg073_s cn52xx;
+ struct cvmx_pcieep_cfg073_s cn52xxp1;
+ struct cvmx_pcieep_cfg073_s cn56xx;
+ struct cvmx_pcieep_cfg073_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg074 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg074_s {
+ uint32_t dword4:32;
+ } s;
+ struct cvmx_pcieep_cfg074_s cn52xx;
+ struct cvmx_pcieep_cfg074_s cn52xxp1;
+ struct cvmx_pcieep_cfg074_s cn56xx;
+ struct cvmx_pcieep_cfg074_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg448 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg448_s {
+ uint32_t rtl:16;
+ uint32_t rtltl:16;
+ } s;
+ struct cvmx_pcieep_cfg448_s cn52xx;
+ struct cvmx_pcieep_cfg448_s cn52xxp1;
+ struct cvmx_pcieep_cfg448_s cn56xx;
+ struct cvmx_pcieep_cfg448_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg449 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg449_s {
+ uint32_t omr:32;
+ } s;
+ struct cvmx_pcieep_cfg449_s cn52xx;
+ struct cvmx_pcieep_cfg449_s cn52xxp1;
+ struct cvmx_pcieep_cfg449_s cn56xx;
+ struct cvmx_pcieep_cfg449_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg450 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg450_s {
+ uint32_t lpec:8;
+ uint32_t reserved_22_23:2;
+ uint32_t link_state:6;
+ uint32_t force_link:1;
+ uint32_t reserved_8_14:7;
+ uint32_t link_num:8;
+ } s;
+ struct cvmx_pcieep_cfg450_s cn52xx;
+ struct cvmx_pcieep_cfg450_s cn52xxp1;
+ struct cvmx_pcieep_cfg450_s cn56xx;
+ struct cvmx_pcieep_cfg450_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg451 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg451_s {
+ uint32_t reserved_30_31:2;
+ uint32_t l1el:3;
+ uint32_t l0el:3;
+ uint32_t n_fts_cc:8;
+ uint32_t n_fts:8;
+ uint32_t ack_freq:8;
+ } s;
+ struct cvmx_pcieep_cfg451_s cn52xx;
+ struct cvmx_pcieep_cfg451_s cn52xxp1;
+ struct cvmx_pcieep_cfg451_s cn56xx;
+ struct cvmx_pcieep_cfg451_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg452 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg452_s {
+ uint32_t reserved_26_31:6;
+ uint32_t eccrc:1;
+ uint32_t reserved_22_24:3;
+ uint32_t lme:6;
+ uint32_t reserved_8_15:8;
+ uint32_t flm:1;
+ uint32_t reserved_6_6:1;
+ uint32_t dllle:1;
+ uint32_t reserved_4_4:1;
+ uint32_t ra:1;
+ uint32_t le:1;
+ uint32_t sd:1;
+ uint32_t omr:1;
+ } s;
+ struct cvmx_pcieep_cfg452_s cn52xx;
+ struct cvmx_pcieep_cfg452_s cn52xxp1;
+ struct cvmx_pcieep_cfg452_s cn56xx;
+ struct cvmx_pcieep_cfg452_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg453 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg453_s {
+ uint32_t dlld:1;
+ uint32_t reserved_26_30:5;
+ uint32_t ack_nak:1;
+ uint32_t fcd:1;
+ uint32_t ilst:24;
+ } s;
+ struct cvmx_pcieep_cfg453_s cn52xx;
+ struct cvmx_pcieep_cfg453_s cn52xxp1;
+ struct cvmx_pcieep_cfg453_s cn56xx;
+ struct cvmx_pcieep_cfg453_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg454 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg454_s {
+ uint32_t reserved_29_31:3;
+ uint32_t tmfcwt:5;
+ uint32_t tmanlt:5;
+ uint32_t tmrt:5;
+ uint32_t reserved_11_13:3;
+ uint32_t nskps:3;
+ uint32_t reserved_4_7:4;
+ uint32_t ntss:4;
+ } s;
+ struct cvmx_pcieep_cfg454_s cn52xx;
+ struct cvmx_pcieep_cfg454_s cn52xxp1;
+ struct cvmx_pcieep_cfg454_s cn56xx;
+ struct cvmx_pcieep_cfg454_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg455 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg455_s {
+ uint32_t m_cfg0_filt:1;
+ uint32_t m_io_filt:1;
+ uint32_t msg_ctrl:1;
+ uint32_t m_cpl_ecrc_filt:1;
+ uint32_t m_ecrc_filt:1;
+ uint32_t m_cpl_len_err:1;
+ uint32_t m_cpl_attr_err:1;
+ uint32_t m_cpl_tc_err:1;
+ uint32_t m_cpl_fun_err:1;
+ uint32_t m_cpl_rid_err:1;
+ uint32_t m_cpl_tag_err:1;
+ uint32_t m_lk_filt:1;
+ uint32_t m_cfg1_filt:1;
+ uint32_t m_bar_match:1;
+ uint32_t m_pois_filt:1;
+ uint32_t m_fun:1;
+ uint32_t dfcwt:1;
+ uint32_t reserved_11_14:4;
+ uint32_t skpiv:11;
+ } s;
+ struct cvmx_pcieep_cfg455_s cn52xx;
+ struct cvmx_pcieep_cfg455_s cn52xxp1;
+ struct cvmx_pcieep_cfg455_s cn56xx;
+ struct cvmx_pcieep_cfg455_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg456 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg456_s {
+ uint32_t reserved_2_31:30;
+ uint32_t m_vend1_drp:1;
+ uint32_t m_vend0_drp:1;
+ } s;
+ struct cvmx_pcieep_cfg456_s cn52xx;
+ struct cvmx_pcieep_cfg456_s cn52xxp1;
+ struct cvmx_pcieep_cfg456_s cn56xx;
+ struct cvmx_pcieep_cfg456_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg458 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg458_s {
+ uint32_t dbg_info_l32:32;
+ } s;
+ struct cvmx_pcieep_cfg458_s cn52xx;
+ struct cvmx_pcieep_cfg458_s cn52xxp1;
+ struct cvmx_pcieep_cfg458_s cn56xx;
+ struct cvmx_pcieep_cfg458_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg459 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg459_s {
+ uint32_t dbg_info_u32:32;
+ } s;
+ struct cvmx_pcieep_cfg459_s cn52xx;
+ struct cvmx_pcieep_cfg459_s cn52xxp1;
+ struct cvmx_pcieep_cfg459_s cn56xx;
+ struct cvmx_pcieep_cfg459_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg460 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg460_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tphfcc:8;
+ uint32_t tpdfcc:12;
+ } s;
+ struct cvmx_pcieep_cfg460_s cn52xx;
+ struct cvmx_pcieep_cfg460_s cn52xxp1;
+ struct cvmx_pcieep_cfg460_s cn56xx;
+ struct cvmx_pcieep_cfg460_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg461 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg461_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tchfcc:8;
+ uint32_t tcdfcc:12;
+ } s;
+ struct cvmx_pcieep_cfg461_s cn52xx;
+ struct cvmx_pcieep_cfg461_s cn52xxp1;
+ struct cvmx_pcieep_cfg461_s cn56xx;
+ struct cvmx_pcieep_cfg461_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg462 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg462_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tchfcc:8;
+ uint32_t tcdfcc:12;
+ } s;
+ struct cvmx_pcieep_cfg462_s cn52xx;
+ struct cvmx_pcieep_cfg462_s cn52xxp1;
+ struct cvmx_pcieep_cfg462_s cn56xx;
+ struct cvmx_pcieep_cfg462_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg463 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg463_s {
+ uint32_t reserved_3_31:29;
+ uint32_t rqne:1;
+ uint32_t trbne:1;
+ uint32_t rtlpfccnr:1;
+ } s;
+ struct cvmx_pcieep_cfg463_s cn52xx;
+ struct cvmx_pcieep_cfg463_s cn52xxp1;
+ struct cvmx_pcieep_cfg463_s cn56xx;
+ struct cvmx_pcieep_cfg463_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg464 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg464_s {
+ uint32_t wrr_vc3:8;
+ uint32_t wrr_vc2:8;
+ uint32_t wrr_vc1:8;
+ uint32_t wrr_vc0:8;
+ } s;
+ struct cvmx_pcieep_cfg464_s cn52xx;
+ struct cvmx_pcieep_cfg464_s cn52xxp1;
+ struct cvmx_pcieep_cfg464_s cn56xx;
+ struct cvmx_pcieep_cfg464_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg465 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg465_s {
+ uint32_t wrr_vc7:8;
+ uint32_t wrr_vc6:8;
+ uint32_t wrr_vc5:8;
+ uint32_t wrr_vc4:8;
+ } s;
+ struct cvmx_pcieep_cfg465_s cn52xx;
+ struct cvmx_pcieep_cfg465_s cn52xxp1;
+ struct cvmx_pcieep_cfg465_s cn56xx;
+ struct cvmx_pcieep_cfg465_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg466 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg466_s {
+ uint32_t rx_queue_order:1;
+ uint32_t type_ordering:1;
+ uint32_t reserved_24_29:6;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pcieep_cfg466_s cn52xx;
+ struct cvmx_pcieep_cfg466_s cn52xxp1;
+ struct cvmx_pcieep_cfg466_s cn56xx;
+ struct cvmx_pcieep_cfg466_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg467 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg467_s {
+ uint32_t reserved_24_31:8;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pcieep_cfg467_s cn52xx;
+ struct cvmx_pcieep_cfg467_s cn52xxp1;
+ struct cvmx_pcieep_cfg467_s cn56xx;
+ struct cvmx_pcieep_cfg467_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg468 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg468_s {
+ uint32_t reserved_24_31:8;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pcieep_cfg468_s cn52xx;
+ struct cvmx_pcieep_cfg468_s cn52xxp1;
+ struct cvmx_pcieep_cfg468_s cn56xx;
+ struct cvmx_pcieep_cfg468_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg490 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg490_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pcieep_cfg490_s cn52xx;
+ struct cvmx_pcieep_cfg490_s cn52xxp1;
+ struct cvmx_pcieep_cfg490_s cn56xx;
+ struct cvmx_pcieep_cfg490_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg491 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg491_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pcieep_cfg491_s cn52xx;
+ struct cvmx_pcieep_cfg491_s cn52xxp1;
+ struct cvmx_pcieep_cfg491_s cn56xx;
+ struct cvmx_pcieep_cfg491_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg492 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg492_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pcieep_cfg492_s cn52xx;
+ struct cvmx_pcieep_cfg492_s cn52xxp1;
+ struct cvmx_pcieep_cfg492_s cn56xx;
+ struct cvmx_pcieep_cfg492_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg516 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg516_s {
+ uint32_t phy_stat:32;
+ } s;
+ struct cvmx_pcieep_cfg516_s cn52xx;
+ struct cvmx_pcieep_cfg516_s cn52xxp1;
+ struct cvmx_pcieep_cfg516_s cn56xx;
+ struct cvmx_pcieep_cfg516_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg517 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg517_s {
+ uint32_t phy_ctrl:32;
+ } s;
+ struct cvmx_pcieep_cfg517_s cn52xx;
+ struct cvmx_pcieep_cfg517_s cn52xxp1;
+ struct cvmx_pcieep_cfg517_s cn56xx;
+ struct cvmx_pcieep_cfg517_s cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
new file mode 100644
index 000000000000..75574c918942
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
@@ -0,0 +1,1397 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCIERCX_DEFS_H__
+#define __CVMX_PCIERCX_DEFS_H__
+
+#define CVMX_PCIERCX_CFG000(offset) \
+ (0x0000000000000000ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG001(offset) \
+ (0x0000000000000004ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG002(offset) \
+ (0x0000000000000008ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG003(offset) \
+ (0x000000000000000Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG004(offset) \
+ (0x0000000000000010ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG005(offset) \
+ (0x0000000000000014ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG006(offset) \
+ (0x0000000000000018ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG007(offset) \
+ (0x000000000000001Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG008(offset) \
+ (0x0000000000000020ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG009(offset) \
+ (0x0000000000000024ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG010(offset) \
+ (0x0000000000000028ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG011(offset) \
+ (0x000000000000002Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG012(offset) \
+ (0x0000000000000030ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG013(offset) \
+ (0x0000000000000034ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG014(offset) \
+ (0x0000000000000038ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG015(offset) \
+ (0x000000000000003Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG016(offset) \
+ (0x0000000000000040ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG017(offset) \
+ (0x0000000000000044ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG020(offset) \
+ (0x0000000000000050ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG021(offset) \
+ (0x0000000000000054ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG022(offset) \
+ (0x0000000000000058ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG023(offset) \
+ (0x000000000000005Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG028(offset) \
+ (0x0000000000000070ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG029(offset) \
+ (0x0000000000000074ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG030(offset) \
+ (0x0000000000000078ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG031(offset) \
+ (0x000000000000007Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG032(offset) \
+ (0x0000000000000080ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG033(offset) \
+ (0x0000000000000084ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG034(offset) \
+ (0x0000000000000088ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG035(offset) \
+ (0x000000000000008Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG036(offset) \
+ (0x0000000000000090ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG037(offset) \
+ (0x0000000000000094ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG038(offset) \
+ (0x0000000000000098ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG039(offset) \
+ (0x000000000000009Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG040(offset) \
+ (0x00000000000000A0ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG041(offset) \
+ (0x00000000000000A4ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG042(offset) \
+ (0x00000000000000A8ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG064(offset) \
+ (0x0000000000000100ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG065(offset) \
+ (0x0000000000000104ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG066(offset) \
+ (0x0000000000000108ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG067(offset) \
+ (0x000000000000010Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG068(offset) \
+ (0x0000000000000110ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG069(offset) \
+ (0x0000000000000114ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG070(offset) \
+ (0x0000000000000118ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG071(offset) \
+ (0x000000000000011Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG072(offset) \
+ (0x0000000000000120ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG073(offset) \
+ (0x0000000000000124ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG074(offset) \
+ (0x0000000000000128ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG075(offset) \
+ (0x000000000000012Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG076(offset) \
+ (0x0000000000000130ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG077(offset) \
+ (0x0000000000000134ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG448(offset) \
+ (0x0000000000000700ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG449(offset) \
+ (0x0000000000000704ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG450(offset) \
+ (0x0000000000000708ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG451(offset) \
+ (0x000000000000070Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG452(offset) \
+ (0x0000000000000710ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG453(offset) \
+ (0x0000000000000714ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG454(offset) \
+ (0x0000000000000718ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG455(offset) \
+ (0x000000000000071Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG456(offset) \
+ (0x0000000000000720ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG458(offset) \
+ (0x0000000000000728ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG459(offset) \
+ (0x000000000000072Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG460(offset) \
+ (0x0000000000000730ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG461(offset) \
+ (0x0000000000000734ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG462(offset) \
+ (0x0000000000000738ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG463(offset) \
+ (0x000000000000073Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG464(offset) \
+ (0x0000000000000740ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG465(offset) \
+ (0x0000000000000744ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG466(offset) \
+ (0x0000000000000748ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG467(offset) \
+ (0x000000000000074Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG468(offset) \
+ (0x0000000000000750ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG490(offset) \
+ (0x00000000000007A8ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG491(offset) \
+ (0x00000000000007ACull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG492(offset) \
+ (0x00000000000007B0ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG516(offset) \
+ (0x0000000000000810ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG517(offset) \
+ (0x0000000000000814ull + (((offset) & 1) * 0))
+
+union cvmx_pciercx_cfg000 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg000_s {
+ uint32_t devid:16;
+ uint32_t vendid:16;
+ } s;
+ struct cvmx_pciercx_cfg000_s cn52xx;
+ struct cvmx_pciercx_cfg000_s cn52xxp1;
+ struct cvmx_pciercx_cfg000_s cn56xx;
+ struct cvmx_pciercx_cfg000_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg001 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg001_s {
+ uint32_t dpe:1;
+ uint32_t sse:1;
+ uint32_t rma:1;
+ uint32_t rta:1;
+ uint32_t sta:1;
+ uint32_t devt:2;
+ uint32_t mdpe:1;
+ uint32_t fbb:1;
+ uint32_t reserved_22_22:1;
+ uint32_t m66:1;
+ uint32_t cl:1;
+ uint32_t i_stat:1;
+ uint32_t reserved_11_18:8;
+ uint32_t i_dis:1;
+ uint32_t fbbe:1;
+ uint32_t see:1;
+ uint32_t ids_wcc:1;
+ uint32_t per:1;
+ uint32_t vps:1;
+ uint32_t mwice:1;
+ uint32_t scse:1;
+ uint32_t me:1;
+ uint32_t msae:1;
+ uint32_t isae:1;
+ } s;
+ struct cvmx_pciercx_cfg001_s cn52xx;
+ struct cvmx_pciercx_cfg001_s cn52xxp1;
+ struct cvmx_pciercx_cfg001_s cn56xx;
+ struct cvmx_pciercx_cfg001_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg002 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg002_s {
+ uint32_t bcc:8;
+ uint32_t sc:8;
+ uint32_t pi:8;
+ uint32_t rid:8;
+ } s;
+ struct cvmx_pciercx_cfg002_s cn52xx;
+ struct cvmx_pciercx_cfg002_s cn52xxp1;
+ struct cvmx_pciercx_cfg002_s cn56xx;
+ struct cvmx_pciercx_cfg002_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg003 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg003_s {
+ uint32_t bist:8;
+ uint32_t mfd:1;
+ uint32_t chf:7;
+ uint32_t lt:8;
+ uint32_t cls:8;
+ } s;
+ struct cvmx_pciercx_cfg003_s cn52xx;
+ struct cvmx_pciercx_cfg003_s cn52xxp1;
+ struct cvmx_pciercx_cfg003_s cn56xx;
+ struct cvmx_pciercx_cfg003_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg004 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg004_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg004_s cn52xx;
+ struct cvmx_pciercx_cfg004_s cn52xxp1;
+ struct cvmx_pciercx_cfg004_s cn56xx;
+ struct cvmx_pciercx_cfg004_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg005 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg005_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg005_s cn52xx;
+ struct cvmx_pciercx_cfg005_s cn52xxp1;
+ struct cvmx_pciercx_cfg005_s cn56xx;
+ struct cvmx_pciercx_cfg005_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg006 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg006_s {
+ uint32_t slt:8;
+ uint32_t subbnum:8;
+ uint32_t sbnum:8;
+ uint32_t pbnum:8;
+ } s;
+ struct cvmx_pciercx_cfg006_s cn52xx;
+ struct cvmx_pciercx_cfg006_s cn52xxp1;
+ struct cvmx_pciercx_cfg006_s cn56xx;
+ struct cvmx_pciercx_cfg006_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg007 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg007_s {
+ uint32_t dpe:1;
+ uint32_t sse:1;
+ uint32_t rma:1;
+ uint32_t rta:1;
+ uint32_t sta:1;
+ uint32_t devt:2;
+ uint32_t mdpe:1;
+ uint32_t fbb:1;
+ uint32_t reserved_22_22:1;
+ uint32_t m66:1;
+ uint32_t reserved_16_20:5;
+ uint32_t lio_limi:4;
+ uint32_t reserved_9_11:3;
+ uint32_t io32b:1;
+ uint32_t lio_base:4;
+ uint32_t reserved_1_3:3;
+ uint32_t io32a:1;
+ } s;
+ struct cvmx_pciercx_cfg007_s cn52xx;
+ struct cvmx_pciercx_cfg007_s cn52xxp1;
+ struct cvmx_pciercx_cfg007_s cn56xx;
+ struct cvmx_pciercx_cfg007_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg008 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg008_s {
+ uint32_t ml_addr:12;
+ uint32_t reserved_16_19:4;
+ uint32_t mb_addr:12;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pciercx_cfg008_s cn52xx;
+ struct cvmx_pciercx_cfg008_s cn52xxp1;
+ struct cvmx_pciercx_cfg008_s cn56xx;
+ struct cvmx_pciercx_cfg008_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg009 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg009_s {
+ uint32_t lmem_limit:12;
+ uint32_t reserved_17_19:3;
+ uint32_t mem64b:1;
+ uint32_t lmem_base:12;
+ uint32_t reserved_1_3:3;
+ uint32_t mem64a:1;
+ } s;
+ struct cvmx_pciercx_cfg009_s cn52xx;
+ struct cvmx_pciercx_cfg009_s cn52xxp1;
+ struct cvmx_pciercx_cfg009_s cn56xx;
+ struct cvmx_pciercx_cfg009_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg010 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg010_s {
+ uint32_t umem_base:32;
+ } s;
+ struct cvmx_pciercx_cfg010_s cn52xx;
+ struct cvmx_pciercx_cfg010_s cn52xxp1;
+ struct cvmx_pciercx_cfg010_s cn56xx;
+ struct cvmx_pciercx_cfg010_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg011 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg011_s {
+ uint32_t umem_limit:32;
+ } s;
+ struct cvmx_pciercx_cfg011_s cn52xx;
+ struct cvmx_pciercx_cfg011_s cn52xxp1;
+ struct cvmx_pciercx_cfg011_s cn56xx;
+ struct cvmx_pciercx_cfg011_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg012 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg012_s {
+ uint32_t uio_limit:16;
+ uint32_t uio_base:16;
+ } s;
+ struct cvmx_pciercx_cfg012_s cn52xx;
+ struct cvmx_pciercx_cfg012_s cn52xxp1;
+ struct cvmx_pciercx_cfg012_s cn56xx;
+ struct cvmx_pciercx_cfg012_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg013 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg013_s {
+ uint32_t reserved_8_31:24;
+ uint32_t cp:8;
+ } s;
+ struct cvmx_pciercx_cfg013_s cn52xx;
+ struct cvmx_pciercx_cfg013_s cn52xxp1;
+ struct cvmx_pciercx_cfg013_s cn56xx;
+ struct cvmx_pciercx_cfg013_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg014 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg014_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg014_s cn52xx;
+ struct cvmx_pciercx_cfg014_s cn52xxp1;
+ struct cvmx_pciercx_cfg014_s cn56xx;
+ struct cvmx_pciercx_cfg014_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg015 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg015_s {
+ uint32_t reserved_28_31:4;
+ uint32_t dtsees:1;
+ uint32_t dts:1;
+ uint32_t sdt:1;
+ uint32_t pdt:1;
+ uint32_t fbbe:1;
+ uint32_t sbrst:1;
+ uint32_t mam:1;
+ uint32_t vga16d:1;
+ uint32_t vgae:1;
+ uint32_t isae:1;
+ uint32_t see:1;
+ uint32_t pere:1;
+ uint32_t inta:8;
+ uint32_t il:8;
+ } s;
+ struct cvmx_pciercx_cfg015_s cn52xx;
+ struct cvmx_pciercx_cfg015_s cn52xxp1;
+ struct cvmx_pciercx_cfg015_s cn56xx;
+ struct cvmx_pciercx_cfg015_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg016 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg016_s {
+ uint32_t pmes:5;
+ uint32_t d2s:1;
+ uint32_t d1s:1;
+ uint32_t auxc:3;
+ uint32_t dsi:1;
+ uint32_t reserved_20_20:1;
+ uint32_t pme_clock:1;
+ uint32_t pmsv:3;
+ uint32_t ncp:8;
+ uint32_t pmcid:8;
+ } s;
+ struct cvmx_pciercx_cfg016_s cn52xx;
+ struct cvmx_pciercx_cfg016_s cn52xxp1;
+ struct cvmx_pciercx_cfg016_s cn56xx;
+ struct cvmx_pciercx_cfg016_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg017 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg017_s {
+ uint32_t pmdia:8;
+ uint32_t bpccee:1;
+ uint32_t bd3h:1;
+ uint32_t reserved_16_21:6;
+ uint32_t pmess:1;
+ uint32_t pmedsia:2;
+ uint32_t pmds:4;
+ uint32_t pmeens:1;
+ uint32_t reserved_4_7:4;
+ uint32_t nsr:1;
+ uint32_t reserved_2_2:1;
+ uint32_t ps:2;
+ } s;
+ struct cvmx_pciercx_cfg017_s cn52xx;
+ struct cvmx_pciercx_cfg017_s cn52xxp1;
+ struct cvmx_pciercx_cfg017_s cn56xx;
+ struct cvmx_pciercx_cfg017_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg020 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg020_s {
+ uint32_t reserved_24_31:8;
+ uint32_t m64:1;
+ uint32_t mme:3;
+ uint32_t mmc:3;
+ uint32_t msien:1;
+ uint32_t ncp:8;
+ uint32_t msicid:8;
+ } s;
+ struct cvmx_pciercx_cfg020_s cn52xx;
+ struct cvmx_pciercx_cfg020_s cn52xxp1;
+ struct cvmx_pciercx_cfg020_s cn56xx;
+ struct cvmx_pciercx_cfg020_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg021 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg021_s {
+ uint32_t lmsi:30;
+ uint32_t reserved_0_1:2;
+ } s;
+ struct cvmx_pciercx_cfg021_s cn52xx;
+ struct cvmx_pciercx_cfg021_s cn52xxp1;
+ struct cvmx_pciercx_cfg021_s cn56xx;
+ struct cvmx_pciercx_cfg021_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg022 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg022_s {
+ uint32_t umsi:32;
+ } s;
+ struct cvmx_pciercx_cfg022_s cn52xx;
+ struct cvmx_pciercx_cfg022_s cn52xxp1;
+ struct cvmx_pciercx_cfg022_s cn56xx;
+ struct cvmx_pciercx_cfg022_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg023 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg023_s {
+ uint32_t reserved_16_31:16;
+ uint32_t msimd:16;
+ } s;
+ struct cvmx_pciercx_cfg023_s cn52xx;
+ struct cvmx_pciercx_cfg023_s cn52xxp1;
+ struct cvmx_pciercx_cfg023_s cn56xx;
+ struct cvmx_pciercx_cfg023_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg028 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg028_s {
+ uint32_t reserved_30_31:2;
+ uint32_t imn:5;
+ uint32_t si:1;
+ uint32_t dpt:4;
+ uint32_t pciecv:4;
+ uint32_t ncp:8;
+ uint32_t pcieid:8;
+ } s;
+ struct cvmx_pciercx_cfg028_s cn52xx;
+ struct cvmx_pciercx_cfg028_s cn52xxp1;
+ struct cvmx_pciercx_cfg028_s cn56xx;
+ struct cvmx_pciercx_cfg028_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg029 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg029_s {
+ uint32_t reserved_28_31:4;
+ uint32_t cspls:2;
+ uint32_t csplv:8;
+ uint32_t reserved_16_17:2;
+ uint32_t rber:1;
+ uint32_t reserved_12_14:3;
+ uint32_t el1al:3;
+ uint32_t el0al:3;
+ uint32_t etfs:1;
+ uint32_t pfs:2;
+ uint32_t mpss:3;
+ } s;
+ struct cvmx_pciercx_cfg029_s cn52xx;
+ struct cvmx_pciercx_cfg029_s cn52xxp1;
+ struct cvmx_pciercx_cfg029_s cn56xx;
+ struct cvmx_pciercx_cfg029_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg030 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg030_s {
+ uint32_t reserved_22_31:10;
+ uint32_t tp:1;
+ uint32_t ap_d:1;
+ uint32_t ur_d:1;
+ uint32_t fe_d:1;
+ uint32_t nfe_d:1;
+ uint32_t ce_d:1;
+ uint32_t reserved_15_15:1;
+ uint32_t mrrs:3;
+ uint32_t ns_en:1;
+ uint32_t ap_en:1;
+ uint32_t pf_en:1;
+ uint32_t etf_en:1;
+ uint32_t mps:3;
+ uint32_t ro_en:1;
+ uint32_t ur_en:1;
+ uint32_t fe_en:1;
+ uint32_t nfe_en:1;
+ uint32_t ce_en:1;
+ } s;
+ struct cvmx_pciercx_cfg030_s cn52xx;
+ struct cvmx_pciercx_cfg030_s cn52xxp1;
+ struct cvmx_pciercx_cfg030_s cn56xx;
+ struct cvmx_pciercx_cfg030_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg031 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg031_s {
+ uint32_t pnum:8;
+ uint32_t reserved_22_23:2;
+ uint32_t lbnc:1;
+ uint32_t dllarc:1;
+ uint32_t sderc:1;
+ uint32_t cpm:1;
+ uint32_t l1el:3;
+ uint32_t l0el:3;
+ uint32_t aslpms:2;
+ uint32_t mlw:6;
+ uint32_t mls:4;
+ } s;
+ struct cvmx_pciercx_cfg031_s cn52xx;
+ struct cvmx_pciercx_cfg031_s cn52xxp1;
+ struct cvmx_pciercx_cfg031_s cn56xx;
+ struct cvmx_pciercx_cfg031_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg032 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg032_s {
+ uint32_t lab:1;
+ uint32_t lbm:1;
+ uint32_t dlla:1;
+ uint32_t scc:1;
+ uint32_t lt:1;
+ uint32_t reserved_26_26:1;
+ uint32_t nlw:6;
+ uint32_t ls:4;
+ uint32_t reserved_12_15:4;
+ uint32_t lab_int_enb:1;
+ uint32_t lbm_int_enb:1;
+ uint32_t hawd:1;
+ uint32_t ecpm:1;
+ uint32_t es:1;
+ uint32_t ccc:1;
+ uint32_t rl:1;
+ uint32_t ld:1;
+ uint32_t rcb:1;
+ uint32_t reserved_2_2:1;
+ uint32_t aslpc:2;
+ } s;
+ struct cvmx_pciercx_cfg032_s cn52xx;
+ struct cvmx_pciercx_cfg032_s cn52xxp1;
+ struct cvmx_pciercx_cfg032_s cn56xx;
+ struct cvmx_pciercx_cfg032_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg033 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg033_s {
+ uint32_t ps_num:13;
+ uint32_t nccs:1;
+ uint32_t emip:1;
+ uint32_t sp_ls:2;
+ uint32_t sp_lv:8;
+ uint32_t hp_c:1;
+ uint32_t hp_s:1;
+ uint32_t pip:1;
+ uint32_t aip:1;
+ uint32_t mrlsp:1;
+ uint32_t pcp:1;
+ uint32_t abp:1;
+ } s;
+ struct cvmx_pciercx_cfg033_s cn52xx;
+ struct cvmx_pciercx_cfg033_s cn52xxp1;
+ struct cvmx_pciercx_cfg033_s cn56xx;
+ struct cvmx_pciercx_cfg033_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg034 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg034_s {
+ uint32_t reserved_25_31:7;
+ uint32_t dlls_c:1;
+ uint32_t emis:1;
+ uint32_t pds:1;
+ uint32_t mrlss:1;
+ uint32_t ccint_d:1;
+ uint32_t pd_c:1;
+ uint32_t mrls_c:1;
+ uint32_t pf_d:1;
+ uint32_t abp_d:1;
+ uint32_t reserved_13_15:3;
+ uint32_t dlls_en:1;
+ uint32_t emic:1;
+ uint32_t pcc:1;
+ uint32_t pic:2;
+ uint32_t aic:2;
+ uint32_t hpint_en:1;
+ uint32_t ccint_en:1;
+ uint32_t pd_en:1;
+ uint32_t mrls_en:1;
+ uint32_t pf_en:1;
+ uint32_t abp_en:1;
+ } s;
+ struct cvmx_pciercx_cfg034_s cn52xx;
+ struct cvmx_pciercx_cfg034_s cn52xxp1;
+ struct cvmx_pciercx_cfg034_s cn56xx;
+ struct cvmx_pciercx_cfg034_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg035 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg035_s {
+ uint32_t reserved_17_31:15;
+ uint32_t crssv:1;
+ uint32_t reserved_5_15:11;
+ uint32_t crssve:1;
+ uint32_t pmeie:1;
+ uint32_t sefee:1;
+ uint32_t senfee:1;
+ uint32_t secee:1;
+ } s;
+ struct cvmx_pciercx_cfg035_s cn52xx;
+ struct cvmx_pciercx_cfg035_s cn52xxp1;
+ struct cvmx_pciercx_cfg035_s cn56xx;
+ struct cvmx_pciercx_cfg035_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg036 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg036_s {
+ uint32_t reserved_18_31:14;
+ uint32_t pme_pend:1;
+ uint32_t pme_stat:1;
+ uint32_t pme_rid:16;
+ } s;
+ struct cvmx_pciercx_cfg036_s cn52xx;
+ struct cvmx_pciercx_cfg036_s cn52xxp1;
+ struct cvmx_pciercx_cfg036_s cn56xx;
+ struct cvmx_pciercx_cfg036_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg037 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg037_s {
+ uint32_t reserved_5_31:27;
+ uint32_t ctds:1;
+ uint32_t ctrs:4;
+ } s;
+ struct cvmx_pciercx_cfg037_s cn52xx;
+ struct cvmx_pciercx_cfg037_s cn52xxp1;
+ struct cvmx_pciercx_cfg037_s cn56xx;
+ struct cvmx_pciercx_cfg037_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg038 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg038_s {
+ uint32_t reserved_5_31:27;
+ uint32_t ctd:1;
+ uint32_t ctv:4;
+ } s;
+ struct cvmx_pciercx_cfg038_s cn52xx;
+ struct cvmx_pciercx_cfg038_s cn52xxp1;
+ struct cvmx_pciercx_cfg038_s cn56xx;
+ struct cvmx_pciercx_cfg038_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg039 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg039_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg039_s cn52xx;
+ struct cvmx_pciercx_cfg039_s cn52xxp1;
+ struct cvmx_pciercx_cfg039_s cn56xx;
+ struct cvmx_pciercx_cfg039_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg040 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg040_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg040_s cn52xx;
+ struct cvmx_pciercx_cfg040_s cn52xxp1;
+ struct cvmx_pciercx_cfg040_s cn56xx;
+ struct cvmx_pciercx_cfg040_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg041 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg041_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg041_s cn52xx;
+ struct cvmx_pciercx_cfg041_s cn52xxp1;
+ struct cvmx_pciercx_cfg041_s cn56xx;
+ struct cvmx_pciercx_cfg041_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg042 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg042_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg042_s cn52xx;
+ struct cvmx_pciercx_cfg042_s cn52xxp1;
+ struct cvmx_pciercx_cfg042_s cn56xx;
+ struct cvmx_pciercx_cfg042_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg064 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg064_s {
+ uint32_t nco:12;
+ uint32_t cv:4;
+ uint32_t pcieec:16;
+ } s;
+ struct cvmx_pciercx_cfg064_s cn52xx;
+ struct cvmx_pciercx_cfg064_s cn52xxp1;
+ struct cvmx_pciercx_cfg064_s cn56xx;
+ struct cvmx_pciercx_cfg064_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg065 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg065_s {
+ uint32_t reserved_21_31:11;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pciercx_cfg065_s cn52xx;
+ struct cvmx_pciercx_cfg065_s cn52xxp1;
+ struct cvmx_pciercx_cfg065_s cn56xx;
+ struct cvmx_pciercx_cfg065_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg066 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg066_s {
+ uint32_t reserved_21_31:11;
+ uint32_t urem:1;
+ uint32_t ecrcem:1;
+ uint32_t mtlpm:1;
+ uint32_t rom:1;
+ uint32_t ucm:1;
+ uint32_t cam:1;
+ uint32_t ctm:1;
+ uint32_t fcpem:1;
+ uint32_t ptlpm:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdem:1;
+ uint32_t dlpem:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pciercx_cfg066_s cn52xx;
+ struct cvmx_pciercx_cfg066_s cn52xxp1;
+ struct cvmx_pciercx_cfg066_s cn56xx;
+ struct cvmx_pciercx_cfg066_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg067 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg067_s {
+ uint32_t reserved_21_31:11;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pciercx_cfg067_s cn52xx;
+ struct cvmx_pciercx_cfg067_s cn52xxp1;
+ struct cvmx_pciercx_cfg067_s cn56xx;
+ struct cvmx_pciercx_cfg067_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg068 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg068_s {
+ uint32_t reserved_14_31:18;
+ uint32_t anfes:1;
+ uint32_t rtts:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rnrs:1;
+ uint32_t bdllps:1;
+ uint32_t btlps:1;
+ uint32_t reserved_1_5:5;
+ uint32_t res:1;
+ } s;
+ struct cvmx_pciercx_cfg068_s cn52xx;
+ struct cvmx_pciercx_cfg068_s cn52xxp1;
+ struct cvmx_pciercx_cfg068_s cn56xx;
+ struct cvmx_pciercx_cfg068_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg069 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg069_s {
+ uint32_t reserved_14_31:18;
+ uint32_t anfem:1;
+ uint32_t rttm:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rnrm:1;
+ uint32_t bdllpm:1;
+ uint32_t btlpm:1;
+ uint32_t reserved_1_5:5;
+ uint32_t rem:1;
+ } s;
+ struct cvmx_pciercx_cfg069_s cn52xx;
+ struct cvmx_pciercx_cfg069_s cn52xxp1;
+ struct cvmx_pciercx_cfg069_s cn56xx;
+ struct cvmx_pciercx_cfg069_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg070 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg070_s {
+ uint32_t reserved_9_31:23;
+ uint32_t ce:1;
+ uint32_t cc:1;
+ uint32_t ge:1;
+ uint32_t gc:1;
+ uint32_t fep:5;
+ } s;
+ struct cvmx_pciercx_cfg070_s cn52xx;
+ struct cvmx_pciercx_cfg070_s cn52xxp1;
+ struct cvmx_pciercx_cfg070_s cn56xx;
+ struct cvmx_pciercx_cfg070_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg071 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg071_s {
+ uint32_t dword1:32;
+ } s;
+ struct cvmx_pciercx_cfg071_s cn52xx;
+ struct cvmx_pciercx_cfg071_s cn52xxp1;
+ struct cvmx_pciercx_cfg071_s cn56xx;
+ struct cvmx_pciercx_cfg071_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg072 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg072_s {
+ uint32_t dword2:32;
+ } s;
+ struct cvmx_pciercx_cfg072_s cn52xx;
+ struct cvmx_pciercx_cfg072_s cn52xxp1;
+ struct cvmx_pciercx_cfg072_s cn56xx;
+ struct cvmx_pciercx_cfg072_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg073 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg073_s {
+ uint32_t dword3:32;
+ } s;
+ struct cvmx_pciercx_cfg073_s cn52xx;
+ struct cvmx_pciercx_cfg073_s cn52xxp1;
+ struct cvmx_pciercx_cfg073_s cn56xx;
+ struct cvmx_pciercx_cfg073_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg074 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg074_s {
+ uint32_t dword4:32;
+ } s;
+ struct cvmx_pciercx_cfg074_s cn52xx;
+ struct cvmx_pciercx_cfg074_s cn52xxp1;
+ struct cvmx_pciercx_cfg074_s cn56xx;
+ struct cvmx_pciercx_cfg074_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg075 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg075_s {
+ uint32_t reserved_3_31:29;
+ uint32_t fere:1;
+ uint32_t nfere:1;
+ uint32_t cere:1;
+ } s;
+ struct cvmx_pciercx_cfg075_s cn52xx;
+ struct cvmx_pciercx_cfg075_s cn52xxp1;
+ struct cvmx_pciercx_cfg075_s cn56xx;
+ struct cvmx_pciercx_cfg075_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg076 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg076_s {
+ uint32_t aeimn:5;
+ uint32_t reserved_7_26:20;
+ uint32_t femr:1;
+ uint32_t nfemr:1;
+ uint32_t fuf:1;
+ uint32_t multi_efnfr:1;
+ uint32_t efnfr:1;
+ uint32_t multi_ecr:1;
+ uint32_t ecr:1;
+ } s;
+ struct cvmx_pciercx_cfg076_s cn52xx;
+ struct cvmx_pciercx_cfg076_s cn52xxp1;
+ struct cvmx_pciercx_cfg076_s cn56xx;
+ struct cvmx_pciercx_cfg076_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg077 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg077_s {
+ uint32_t efnfsi:16;
+ uint32_t ecsi:16;
+ } s;
+ struct cvmx_pciercx_cfg077_s cn52xx;
+ struct cvmx_pciercx_cfg077_s cn52xxp1;
+ struct cvmx_pciercx_cfg077_s cn56xx;
+ struct cvmx_pciercx_cfg077_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg448 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg448_s {
+ uint32_t rtl:16;
+ uint32_t rtltl:16;
+ } s;
+ struct cvmx_pciercx_cfg448_s cn52xx;
+ struct cvmx_pciercx_cfg448_s cn52xxp1;
+ struct cvmx_pciercx_cfg448_s cn56xx;
+ struct cvmx_pciercx_cfg448_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg449 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg449_s {
+ uint32_t omr:32;
+ } s;
+ struct cvmx_pciercx_cfg449_s cn52xx;
+ struct cvmx_pciercx_cfg449_s cn52xxp1;
+ struct cvmx_pciercx_cfg449_s cn56xx;
+ struct cvmx_pciercx_cfg449_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg450 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg450_s {
+ uint32_t lpec:8;
+ uint32_t reserved_22_23:2;
+ uint32_t link_state:6;
+ uint32_t force_link:1;
+ uint32_t reserved_8_14:7;
+ uint32_t link_num:8;
+ } s;
+ struct cvmx_pciercx_cfg450_s cn52xx;
+ struct cvmx_pciercx_cfg450_s cn52xxp1;
+ struct cvmx_pciercx_cfg450_s cn56xx;
+ struct cvmx_pciercx_cfg450_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg451 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg451_s {
+ uint32_t reserved_30_31:2;
+ uint32_t l1el:3;
+ uint32_t l0el:3;
+ uint32_t n_fts_cc:8;
+ uint32_t n_fts:8;
+ uint32_t ack_freq:8;
+ } s;
+ struct cvmx_pciercx_cfg451_s cn52xx;
+ struct cvmx_pciercx_cfg451_s cn52xxp1;
+ struct cvmx_pciercx_cfg451_s cn56xx;
+ struct cvmx_pciercx_cfg451_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg452 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg452_s {
+ uint32_t reserved_26_31:6;
+ uint32_t eccrc:1;
+ uint32_t reserved_22_24:3;
+ uint32_t lme:6;
+ uint32_t reserved_8_15:8;
+ uint32_t flm:1;
+ uint32_t reserved_6_6:1;
+ uint32_t dllle:1;
+ uint32_t reserved_4_4:1;
+ uint32_t ra:1;
+ uint32_t le:1;
+ uint32_t sd:1;
+ uint32_t omr:1;
+ } s;
+ struct cvmx_pciercx_cfg452_s cn52xx;
+ struct cvmx_pciercx_cfg452_s cn52xxp1;
+ struct cvmx_pciercx_cfg452_s cn56xx;
+ struct cvmx_pciercx_cfg452_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg453 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg453_s {
+ uint32_t dlld:1;
+ uint32_t reserved_26_30:5;
+ uint32_t ack_nak:1;
+ uint32_t fcd:1;
+ uint32_t ilst:24;
+ } s;
+ struct cvmx_pciercx_cfg453_s cn52xx;
+ struct cvmx_pciercx_cfg453_s cn52xxp1;
+ struct cvmx_pciercx_cfg453_s cn56xx;
+ struct cvmx_pciercx_cfg453_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg454 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg454_s {
+ uint32_t reserved_29_31:3;
+ uint32_t tmfcwt:5;
+ uint32_t tmanlt:5;
+ uint32_t tmrt:5;
+ uint32_t reserved_11_13:3;
+ uint32_t nskps:3;
+ uint32_t reserved_4_7:4;
+ uint32_t ntss:4;
+ } s;
+ struct cvmx_pciercx_cfg454_s cn52xx;
+ struct cvmx_pciercx_cfg454_s cn52xxp1;
+ struct cvmx_pciercx_cfg454_s cn56xx;
+ struct cvmx_pciercx_cfg454_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg455 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg455_s {
+ uint32_t m_cfg0_filt:1;
+ uint32_t m_io_filt:1;
+ uint32_t msg_ctrl:1;
+ uint32_t m_cpl_ecrc_filt:1;
+ uint32_t m_ecrc_filt:1;
+ uint32_t m_cpl_len_err:1;
+ uint32_t m_cpl_attr_err:1;
+ uint32_t m_cpl_tc_err:1;
+ uint32_t m_cpl_fun_err:1;
+ uint32_t m_cpl_rid_err:1;
+ uint32_t m_cpl_tag_err:1;
+ uint32_t m_lk_filt:1;
+ uint32_t m_cfg1_filt:1;
+ uint32_t m_bar_match:1;
+ uint32_t m_pois_filt:1;
+ uint32_t m_fun:1;
+ uint32_t dfcwt:1;
+ uint32_t reserved_11_14:4;
+ uint32_t skpiv:11;
+ } s;
+ struct cvmx_pciercx_cfg455_s cn52xx;
+ struct cvmx_pciercx_cfg455_s cn52xxp1;
+ struct cvmx_pciercx_cfg455_s cn56xx;
+ struct cvmx_pciercx_cfg455_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg456 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg456_s {
+ uint32_t reserved_2_31:30;
+ uint32_t m_vend1_drp:1;
+ uint32_t m_vend0_drp:1;
+ } s;
+ struct cvmx_pciercx_cfg456_s cn52xx;
+ struct cvmx_pciercx_cfg456_s cn52xxp1;
+ struct cvmx_pciercx_cfg456_s cn56xx;
+ struct cvmx_pciercx_cfg456_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg458 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg458_s {
+ uint32_t dbg_info_l32:32;
+ } s;
+ struct cvmx_pciercx_cfg458_s cn52xx;
+ struct cvmx_pciercx_cfg458_s cn52xxp1;
+ struct cvmx_pciercx_cfg458_s cn56xx;
+ struct cvmx_pciercx_cfg458_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg459 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg459_s {
+ uint32_t dbg_info_u32:32;
+ } s;
+ struct cvmx_pciercx_cfg459_s cn52xx;
+ struct cvmx_pciercx_cfg459_s cn52xxp1;
+ struct cvmx_pciercx_cfg459_s cn56xx;
+ struct cvmx_pciercx_cfg459_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg460 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg460_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tphfcc:8;
+ uint32_t tpdfcc:12;
+ } s;
+ struct cvmx_pciercx_cfg460_s cn52xx;
+ struct cvmx_pciercx_cfg460_s cn52xxp1;
+ struct cvmx_pciercx_cfg460_s cn56xx;
+ struct cvmx_pciercx_cfg460_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg461 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg461_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tchfcc:8;
+ uint32_t tcdfcc:12;
+ } s;
+ struct cvmx_pciercx_cfg461_s cn52xx;
+ struct cvmx_pciercx_cfg461_s cn52xxp1;
+ struct cvmx_pciercx_cfg461_s cn56xx;
+ struct cvmx_pciercx_cfg461_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg462 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg462_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tchfcc:8;
+ uint32_t tcdfcc:12;
+ } s;
+ struct cvmx_pciercx_cfg462_s cn52xx;
+ struct cvmx_pciercx_cfg462_s cn52xxp1;
+ struct cvmx_pciercx_cfg462_s cn56xx;
+ struct cvmx_pciercx_cfg462_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg463 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg463_s {
+ uint32_t reserved_3_31:29;
+ uint32_t rqne:1;
+ uint32_t trbne:1;
+ uint32_t rtlpfccnr:1;
+ } s;
+ struct cvmx_pciercx_cfg463_s cn52xx;
+ struct cvmx_pciercx_cfg463_s cn52xxp1;
+ struct cvmx_pciercx_cfg463_s cn56xx;
+ struct cvmx_pciercx_cfg463_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg464 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg464_s {
+ uint32_t wrr_vc3:8;
+ uint32_t wrr_vc2:8;
+ uint32_t wrr_vc1:8;
+ uint32_t wrr_vc0:8;
+ } s;
+ struct cvmx_pciercx_cfg464_s cn52xx;
+ struct cvmx_pciercx_cfg464_s cn52xxp1;
+ struct cvmx_pciercx_cfg464_s cn56xx;
+ struct cvmx_pciercx_cfg464_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg465 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg465_s {
+ uint32_t wrr_vc7:8;
+ uint32_t wrr_vc6:8;
+ uint32_t wrr_vc5:8;
+ uint32_t wrr_vc4:8;
+ } s;
+ struct cvmx_pciercx_cfg465_s cn52xx;
+ struct cvmx_pciercx_cfg465_s cn52xxp1;
+ struct cvmx_pciercx_cfg465_s cn56xx;
+ struct cvmx_pciercx_cfg465_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg466 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg466_s {
+ uint32_t rx_queue_order:1;
+ uint32_t type_ordering:1;
+ uint32_t reserved_24_29:6;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pciercx_cfg466_s cn52xx;
+ struct cvmx_pciercx_cfg466_s cn52xxp1;
+ struct cvmx_pciercx_cfg466_s cn56xx;
+ struct cvmx_pciercx_cfg466_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg467 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg467_s {
+ uint32_t reserved_24_31:8;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pciercx_cfg467_s cn52xx;
+ struct cvmx_pciercx_cfg467_s cn52xxp1;
+ struct cvmx_pciercx_cfg467_s cn56xx;
+ struct cvmx_pciercx_cfg467_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg468 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg468_s {
+ uint32_t reserved_24_31:8;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pciercx_cfg468_s cn52xx;
+ struct cvmx_pciercx_cfg468_s cn52xxp1;
+ struct cvmx_pciercx_cfg468_s cn56xx;
+ struct cvmx_pciercx_cfg468_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg490 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg490_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pciercx_cfg490_s cn52xx;
+ struct cvmx_pciercx_cfg490_s cn52xxp1;
+ struct cvmx_pciercx_cfg490_s cn56xx;
+ struct cvmx_pciercx_cfg490_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg491 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg491_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pciercx_cfg491_s cn52xx;
+ struct cvmx_pciercx_cfg491_s cn52xxp1;
+ struct cvmx_pciercx_cfg491_s cn56xx;
+ struct cvmx_pciercx_cfg491_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg492 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg492_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pciercx_cfg492_s cn52xx;
+ struct cvmx_pciercx_cfg492_s cn52xxp1;
+ struct cvmx_pciercx_cfg492_s cn56xx;
+ struct cvmx_pciercx_cfg492_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg516 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg516_s {
+ uint32_t phy_stat:32;
+ } s;
+ struct cvmx_pciercx_cfg516_s cn52xx;
+ struct cvmx_pciercx_cfg516_s cn52xxp1;
+ struct cvmx_pciercx_cfg516_s cn56xx;
+ struct cvmx_pciercx_cfg516_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg517 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg517_s {
+ uint32_t phy_ctrl:32;
+ } s;
+ struct cvmx_pciercx_cfg517_s cn52xx;
+ struct cvmx_pciercx_cfg517_s cn52xxp1;
+ struct cvmx_pciercx_cfg517_s cn56xx;
+ struct cvmx_pciercx_cfg517_s cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pescx-defs.h b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
new file mode 100644
index 000000000000..f40cfaf84454
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
@@ -0,0 +1,410 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PESCX_DEFS_H__
+#define __CVMX_PESCX_DEFS_H__
+
+#define CVMX_PESCX_BIST_STATUS(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000018ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_BIST_STATUS2(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000418ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_CFG_RD(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000030ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_CFG_WR(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000028ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_CPL_LUT_VALID(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000098ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_CTL_STATUS(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000000ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_CTL_STATUS2(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000400ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_DBG_INFO(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000008ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_DBG_INFO_EN(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C80000A0ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_DIAG_STATUS(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000020ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_P2N_BAR0_START(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000080ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_P2N_BAR1_START(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000088ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_P2N_BAR2_START(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000090ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_P2P_BARX_END(offset, block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000048ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_P2P_BARX_START(offset, block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000040ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_TLP_CREDITS(block_id) \
+ CVMX_ADD_IO_SEG(0x00011800C8000038ull + (((block_id) & 1) * 0x8000000ull))
+
+union cvmx_pescx_bist_status {
+ uint64_t u64;
+ struct cvmx_pescx_bist_status_s {
+ uint64_t reserved_13_63:51;
+ uint64_t rqdata5:1;
+ uint64_t ctlp_or:1;
+ uint64_t ntlp_or:1;
+ uint64_t ptlp_or:1;
+ uint64_t retry:1;
+ uint64_t rqdata0:1;
+ uint64_t rqdata1:1;
+ uint64_t rqdata2:1;
+ uint64_t rqdata3:1;
+ uint64_t rqdata4:1;
+ uint64_t rqhdr1:1;
+ uint64_t rqhdr0:1;
+ uint64_t sot:1;
+ } s;
+ struct cvmx_pescx_bist_status_s cn52xx;
+ struct cvmx_pescx_bist_status_cn52xxp1 {
+ uint64_t reserved_12_63:52;
+ uint64_t ctlp_or:1;
+ uint64_t ntlp_or:1;
+ uint64_t ptlp_or:1;
+ uint64_t retry:1;
+ uint64_t rqdata0:1;
+ uint64_t rqdata1:1;
+ uint64_t rqdata2:1;
+ uint64_t rqdata3:1;
+ uint64_t rqdata4:1;
+ uint64_t rqhdr1:1;
+ uint64_t rqhdr0:1;
+ uint64_t sot:1;
+ } cn52xxp1;
+ struct cvmx_pescx_bist_status_s cn56xx;
+ struct cvmx_pescx_bist_status_cn52xxp1 cn56xxp1;
+};
+
+union cvmx_pescx_bist_status2 {
+ uint64_t u64;
+ struct cvmx_pescx_bist_status2_s {
+ uint64_t reserved_14_63:50;
+ uint64_t cto_p2e:1;
+ uint64_t e2p_cpl:1;
+ uint64_t e2p_n:1;
+ uint64_t e2p_p:1;
+ uint64_t e2p_rsl:1;
+ uint64_t dbg_p2e:1;
+ uint64_t peai_p2e:1;
+ uint64_t rsl_p2e:1;
+ uint64_t pef_tpf1:1;
+ uint64_t pef_tpf0:1;
+ uint64_t pef_tnf:1;
+ uint64_t pef_tcf1:1;
+ uint64_t pef_tc0:1;
+ uint64_t ppf:1;
+ } s;
+ struct cvmx_pescx_bist_status2_s cn52xx;
+ struct cvmx_pescx_bist_status2_s cn52xxp1;
+ struct cvmx_pescx_bist_status2_s cn56xx;
+ struct cvmx_pescx_bist_status2_s cn56xxp1;
+};
+
+union cvmx_pescx_cfg_rd {
+ uint64_t u64;
+ struct cvmx_pescx_cfg_rd_s {
+ uint64_t data:32;
+ uint64_t addr:32;
+ } s;
+ struct cvmx_pescx_cfg_rd_s cn52xx;
+ struct cvmx_pescx_cfg_rd_s cn52xxp1;
+ struct cvmx_pescx_cfg_rd_s cn56xx;
+ struct cvmx_pescx_cfg_rd_s cn56xxp1;
+};
+
+union cvmx_pescx_cfg_wr {
+ uint64_t u64;
+ struct cvmx_pescx_cfg_wr_s {
+ uint64_t data:32;
+ uint64_t addr:32;
+ } s;
+ struct cvmx_pescx_cfg_wr_s cn52xx;
+ struct cvmx_pescx_cfg_wr_s cn52xxp1;
+ struct cvmx_pescx_cfg_wr_s cn56xx;
+ struct cvmx_pescx_cfg_wr_s cn56xxp1;
+};
+
+union cvmx_pescx_cpl_lut_valid {
+ uint64_t u64;
+ struct cvmx_pescx_cpl_lut_valid_s {
+ uint64_t reserved_32_63:32;
+ uint64_t tag:32;
+ } s;
+ struct cvmx_pescx_cpl_lut_valid_s cn52xx;
+ struct cvmx_pescx_cpl_lut_valid_s cn52xxp1;
+ struct cvmx_pescx_cpl_lut_valid_s cn56xx;
+ struct cvmx_pescx_cpl_lut_valid_s cn56xxp1;
+};
+
+union cvmx_pescx_ctl_status {
+ uint64_t u64;
+ struct cvmx_pescx_ctl_status_s {
+ uint64_t reserved_28_63:36;
+ uint64_t dnum:5;
+ uint64_t pbus:8;
+ uint64_t qlm_cfg:2;
+ uint64_t lane_swp:1;
+ uint64_t pm_xtoff:1;
+ uint64_t pm_xpme:1;
+ uint64_t ob_p_cmd:1;
+ uint64_t reserved_7_8:2;
+ uint64_t nf_ecrc:1;
+ uint64_t dly_one:1;
+ uint64_t lnk_enb:1;
+ uint64_t ro_ctlp:1;
+ uint64_t reserved_2_2:1;
+ uint64_t inv_ecrc:1;
+ uint64_t inv_lcrc:1;
+ } s;
+ struct cvmx_pescx_ctl_status_s cn52xx;
+ struct cvmx_pescx_ctl_status_s cn52xxp1;
+ struct cvmx_pescx_ctl_status_cn56xx {
+ uint64_t reserved_28_63:36;
+ uint64_t dnum:5;
+ uint64_t pbus:8;
+ uint64_t qlm_cfg:2;
+ uint64_t reserved_12_12:1;
+ uint64_t pm_xtoff:1;
+ uint64_t pm_xpme:1;
+ uint64_t ob_p_cmd:1;
+ uint64_t reserved_7_8:2;
+ uint64_t nf_ecrc:1;
+ uint64_t dly_one:1;
+ uint64_t lnk_enb:1;
+ uint64_t ro_ctlp:1;
+ uint64_t reserved_2_2:1;
+ uint64_t inv_ecrc:1;
+ uint64_t inv_lcrc:1;
+ } cn56xx;
+ struct cvmx_pescx_ctl_status_cn56xx cn56xxp1;
+};
+
+union cvmx_pescx_ctl_status2 {
+ uint64_t u64;
+ struct cvmx_pescx_ctl_status2_s {
+ uint64_t reserved_2_63:62;
+ uint64_t pclk_run:1;
+ uint64_t pcierst:1;
+ } s;
+ struct cvmx_pescx_ctl_status2_s cn52xx;
+ struct cvmx_pescx_ctl_status2_cn52xxp1 {
+ uint64_t reserved_1_63:63;
+ uint64_t pcierst:1;
+ } cn52xxp1;
+ struct cvmx_pescx_ctl_status2_s cn56xx;
+ struct cvmx_pescx_ctl_status2_cn52xxp1 cn56xxp1;
+};
+
+union cvmx_pescx_dbg_info {
+ uint64_t u64;
+ struct cvmx_pescx_dbg_info_s {
+ uint64_t reserved_31_63:33;
+ uint64_t ecrc_e:1;
+ uint64_t rawwpp:1;
+ uint64_t racpp:1;
+ uint64_t ramtlp:1;
+ uint64_t rarwdns:1;
+ uint64_t caar:1;
+ uint64_t racca:1;
+ uint64_t racur:1;
+ uint64_t rauc:1;
+ uint64_t rqo:1;
+ uint64_t fcuv:1;
+ uint64_t rpe:1;
+ uint64_t fcpvwt:1;
+ uint64_t dpeoosd:1;
+ uint64_t rtwdle:1;
+ uint64_t rdwdle:1;
+ uint64_t mre:1;
+ uint64_t rte:1;
+ uint64_t acto:1;
+ uint64_t rvdm:1;
+ uint64_t rumep:1;
+ uint64_t rptamrc:1;
+ uint64_t rpmerc:1;
+ uint64_t rfemrc:1;
+ uint64_t rnfemrc:1;
+ uint64_t rcemrc:1;
+ uint64_t rpoison:1;
+ uint64_t recrce:1;
+ uint64_t rtlplle:1;
+ uint64_t rtlpmal:1;
+ uint64_t spoison:1;
+ } s;
+ struct cvmx_pescx_dbg_info_s cn52xx;
+ struct cvmx_pescx_dbg_info_s cn52xxp1;
+ struct cvmx_pescx_dbg_info_s cn56xx;
+ struct cvmx_pescx_dbg_info_s cn56xxp1;
+};
+
+union cvmx_pescx_dbg_info_en {
+ uint64_t u64;
+ struct cvmx_pescx_dbg_info_en_s {
+ uint64_t reserved_31_63:33;
+ uint64_t ecrc_e:1;
+ uint64_t rawwpp:1;
+ uint64_t racpp:1;
+ uint64_t ramtlp:1;
+ uint64_t rarwdns:1;
+ uint64_t caar:1;
+ uint64_t racca:1;
+ uint64_t racur:1;
+ uint64_t rauc:1;
+ uint64_t rqo:1;
+ uint64_t fcuv:1;
+ uint64_t rpe:1;
+ uint64_t fcpvwt:1;
+ uint64_t dpeoosd:1;
+ uint64_t rtwdle:1;
+ uint64_t rdwdle:1;
+ uint64_t mre:1;
+ uint64_t rte:1;
+ uint64_t acto:1;
+ uint64_t rvdm:1;
+ uint64_t rumep:1;
+ uint64_t rptamrc:1;
+ uint64_t rpmerc:1;
+ uint64_t rfemrc:1;
+ uint64_t rnfemrc:1;
+ uint64_t rcemrc:1;
+ uint64_t rpoison:1;
+ uint64_t recrce:1;
+ uint64_t rtlplle:1;
+ uint64_t rtlpmal:1;
+ uint64_t spoison:1;
+ } s;
+ struct cvmx_pescx_dbg_info_en_s cn52xx;
+ struct cvmx_pescx_dbg_info_en_s cn52xxp1;
+ struct cvmx_pescx_dbg_info_en_s cn56xx;
+ struct cvmx_pescx_dbg_info_en_s cn56xxp1;
+};
+
+union cvmx_pescx_diag_status {
+ uint64_t u64;
+ struct cvmx_pescx_diag_status_s {
+ uint64_t reserved_4_63:60;
+ uint64_t pm_dst:1;
+ uint64_t pm_stat:1;
+ uint64_t pm_en:1;
+ uint64_t aux_en:1;
+ } s;
+ struct cvmx_pescx_diag_status_s cn52xx;
+ struct cvmx_pescx_diag_status_s cn52xxp1;
+ struct cvmx_pescx_diag_status_s cn56xx;
+ struct cvmx_pescx_diag_status_s cn56xxp1;
+};
+
+union cvmx_pescx_p2n_bar0_start {
+ uint64_t u64;
+ struct cvmx_pescx_p2n_bar0_start_s {
+ uint64_t addr:50;
+ uint64_t reserved_0_13:14;
+ } s;
+ struct cvmx_pescx_p2n_bar0_start_s cn52xx;
+ struct cvmx_pescx_p2n_bar0_start_s cn52xxp1;
+ struct cvmx_pescx_p2n_bar0_start_s cn56xx;
+ struct cvmx_pescx_p2n_bar0_start_s cn56xxp1;
+};
+
+union cvmx_pescx_p2n_bar1_start {
+ uint64_t u64;
+ struct cvmx_pescx_p2n_bar1_start_s {
+ uint64_t addr:38;
+ uint64_t reserved_0_25:26;
+ } s;
+ struct cvmx_pescx_p2n_bar1_start_s cn52xx;
+ struct cvmx_pescx_p2n_bar1_start_s cn52xxp1;
+ struct cvmx_pescx_p2n_bar1_start_s cn56xx;
+ struct cvmx_pescx_p2n_bar1_start_s cn56xxp1;
+};
+
+union cvmx_pescx_p2n_bar2_start {
+ uint64_t u64;
+ struct cvmx_pescx_p2n_bar2_start_s {
+ uint64_t addr:25;
+ uint64_t reserved_0_38:39;
+ } s;
+ struct cvmx_pescx_p2n_bar2_start_s cn52xx;
+ struct cvmx_pescx_p2n_bar2_start_s cn52xxp1;
+ struct cvmx_pescx_p2n_bar2_start_s cn56xx;
+ struct cvmx_pescx_p2n_bar2_start_s cn56xxp1;
+};
+
+union cvmx_pescx_p2p_barx_end {
+ uint64_t u64;
+ struct cvmx_pescx_p2p_barx_end_s {
+ uint64_t addr:52;
+ uint64_t reserved_0_11:12;
+ } s;
+ struct cvmx_pescx_p2p_barx_end_s cn52xx;
+ struct cvmx_pescx_p2p_barx_end_s cn52xxp1;
+ struct cvmx_pescx_p2p_barx_end_s cn56xx;
+ struct cvmx_pescx_p2p_barx_end_s cn56xxp1;
+};
+
+union cvmx_pescx_p2p_barx_start {
+ uint64_t u64;
+ struct cvmx_pescx_p2p_barx_start_s {
+ uint64_t addr:52;
+ uint64_t reserved_0_11:12;
+ } s;
+ struct cvmx_pescx_p2p_barx_start_s cn52xx;
+ struct cvmx_pescx_p2p_barx_start_s cn52xxp1;
+ struct cvmx_pescx_p2p_barx_start_s cn56xx;
+ struct cvmx_pescx_p2p_barx_start_s cn56xxp1;
+};
+
+union cvmx_pescx_tlp_credits {
+ uint64_t u64;
+ struct cvmx_pescx_tlp_credits_s {
+ uint64_t reserved_0_63:64;
+ } s;
+ struct cvmx_pescx_tlp_credits_cn52xx {
+ uint64_t reserved_56_63:8;
+ uint64_t peai_ppf:8;
+ uint64_t pesc_cpl:8;
+ uint64_t pesc_np:8;
+ uint64_t pesc_p:8;
+ uint64_t npei_cpl:8;
+ uint64_t npei_np:8;
+ uint64_t npei_p:8;
+ } cn52xx;
+ struct cvmx_pescx_tlp_credits_cn52xxp1 {
+ uint64_t reserved_38_63:26;
+ uint64_t peai_ppf:8;
+ uint64_t pesc_cpl:5;
+ uint64_t pesc_np:5;
+ uint64_t pesc_p:5;
+ uint64_t npei_cpl:5;
+ uint64_t npei_np:5;
+ uint64_t npei_p:5;
+ } cn52xxp1;
+ struct cvmx_pescx_tlp_credits_cn52xx cn56xx;
+ struct cvmx_pescx_tlp_credits_cn52xxp1 cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
new file mode 100644
index 000000000000..5ea5dc571b54
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
@@ -0,0 +1,229 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * cvmx-pexp-defs.h
+ *
+ * Configuration and status register (CSR) definitions for
+ * OCTEON PEXP.
+ *
+ */
+#ifndef __CVMX_PEXP_DEFS_H__
+#define __CVMX_PEXP_DEFS_H__
+
+#define CVMX_PEXP_NPEI_BAR1_INDEXX(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000008000ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_BIST_STATUS \
+ CVMX_ADD_IO_SEG(0x00011F0000008580ull)
+#define CVMX_PEXP_NPEI_BIST_STATUS2 \
+ CVMX_ADD_IO_SEG(0x00011F0000008680ull)
+#define CVMX_PEXP_NPEI_CTL_PORT0 \
+ CVMX_ADD_IO_SEG(0x00011F0000008250ull)
+#define CVMX_PEXP_NPEI_CTL_PORT1 \
+ CVMX_ADD_IO_SEG(0x00011F0000008260ull)
+#define CVMX_PEXP_NPEI_CTL_STATUS \
+ CVMX_ADD_IO_SEG(0x00011F0000008570ull)
+#define CVMX_PEXP_NPEI_CTL_STATUS2 \
+ CVMX_ADD_IO_SEG(0x00011F000000BC00ull)
+#define CVMX_PEXP_NPEI_DATA_OUT_CNT \
+ CVMX_ADD_IO_SEG(0x00011F00000085F0ull)
+#define CVMX_PEXP_NPEI_DBG_DATA \
+ CVMX_ADD_IO_SEG(0x00011F0000008510ull)
+#define CVMX_PEXP_NPEI_DBG_SELECT \
+ CVMX_ADD_IO_SEG(0x00011F0000008500ull)
+#define CVMX_PEXP_NPEI_DMA0_INT_LEVEL \
+ CVMX_ADD_IO_SEG(0x00011F00000085C0ull)
+#define CVMX_PEXP_NPEI_DMA1_INT_LEVEL \
+ CVMX_ADD_IO_SEG(0x00011F00000085D0ull)
+#define CVMX_PEXP_NPEI_DMAX_COUNTS(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000008450ull + (((offset) & 7) * 16))
+#define CVMX_PEXP_NPEI_DMAX_DBELL(offset) \
+ CVMX_ADD_IO_SEG(0x00011F00000083B0ull + (((offset) & 7) * 16))
+#define CVMX_PEXP_NPEI_DMAX_IBUFF_SADDR(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000008400ull + (((offset) & 7) * 16))
+#define CVMX_PEXP_NPEI_DMAX_NADDR(offset) \
+ CVMX_ADD_IO_SEG(0x00011F00000084A0ull + (((offset) & 7) * 16))
+#define CVMX_PEXP_NPEI_DMA_CNTS \
+ CVMX_ADD_IO_SEG(0x00011F00000085E0ull)
+#define CVMX_PEXP_NPEI_DMA_CONTROL \
+ CVMX_ADD_IO_SEG(0x00011F00000083A0ull)
+#define CVMX_PEXP_NPEI_INT_A_ENB \
+ CVMX_ADD_IO_SEG(0x00011F0000008560ull)
+#define CVMX_PEXP_NPEI_INT_A_ENB2 \
+ CVMX_ADD_IO_SEG(0x00011F000000BCE0ull)
+#define CVMX_PEXP_NPEI_INT_A_SUM \
+ CVMX_ADD_IO_SEG(0x00011F0000008550ull)
+#define CVMX_PEXP_NPEI_INT_ENB \
+ CVMX_ADD_IO_SEG(0x00011F0000008540ull)
+#define CVMX_PEXP_NPEI_INT_ENB2 \
+ CVMX_ADD_IO_SEG(0x00011F000000BCD0ull)
+#define CVMX_PEXP_NPEI_INT_INFO \
+ CVMX_ADD_IO_SEG(0x00011F0000008590ull)
+#define CVMX_PEXP_NPEI_INT_SUM \
+ CVMX_ADD_IO_SEG(0x00011F0000008530ull)
+#define CVMX_PEXP_NPEI_INT_SUM2 \
+ CVMX_ADD_IO_SEG(0x00011F000000BCC0ull)
+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA0 \
+ CVMX_ADD_IO_SEG(0x00011F0000008600ull)
+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA1 \
+ CVMX_ADD_IO_SEG(0x00011F0000008610ull)
+#define CVMX_PEXP_NPEI_MEM_ACCESS_CTL \
+ CVMX_ADD_IO_SEG(0x00011F00000084F0ull)
+#define CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000008280ull + (((offset) & 31) * 16) - 16 * 12)
+#define CVMX_PEXP_NPEI_MSI_ENB0 \
+ CVMX_ADD_IO_SEG(0x00011F000000BC50ull)
+#define CVMX_PEXP_NPEI_MSI_ENB1 \
+ CVMX_ADD_IO_SEG(0x00011F000000BC60ull)
+#define CVMX_PEXP_NPEI_MSI_ENB2 \
+ CVMX_ADD_IO_SEG(0x00011F000000BC70ull)
+#define CVMX_PEXP_NPEI_MSI_ENB3 \
+ CVMX_ADD_IO_SEG(0x00011F000000BC80ull)
+#define CVMX_PEXP_NPEI_MSI_RCV0 \
+ CVMX_ADD_IO_SEG(0x00011F000000BC10ull)
+#define CVMX_PEXP_NPEI_MSI_RCV1 \
+ CVMX_ADD_IO_SEG(0x00011F000000BC20ull)
+#define CVMX_PEXP_NPEI_MSI_RCV2 \
+ CVMX_ADD_IO_SEG(0x00011F000000BC30ull)
+#define CVMX_PEXP_NPEI_MSI_RCV3 \
+ CVMX_ADD_IO_SEG(0x00011F000000BC40ull)
+#define CVMX_PEXP_NPEI_MSI_RD_MAP \
+ CVMX_ADD_IO_SEG(0x00011F000000BCA0ull)
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB0 \
+ CVMX_ADD_IO_SEG(0x00011F000000BCF0ull)
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB1 \
+ CVMX_ADD_IO_SEG(0x00011F000000BD00ull)
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB2 \
+ CVMX_ADD_IO_SEG(0x00011F000000BD10ull)
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB3 \
+ CVMX_ADD_IO_SEG(0x00011F000000BD20ull)
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB0 \
+ CVMX_ADD_IO_SEG(0x00011F000000BD30ull)
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB1 \
+ CVMX_ADD_IO_SEG(0x00011F000000BD40ull)
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB2 \
+ CVMX_ADD_IO_SEG(0x00011F000000BD50ull)
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB3 \
+ CVMX_ADD_IO_SEG(0x00011F000000BD60ull)
+#define CVMX_PEXP_NPEI_MSI_WR_MAP \
+ CVMX_ADD_IO_SEG(0x00011F000000BC90ull)
+#define CVMX_PEXP_NPEI_PCIE_CREDIT_CNT \
+ CVMX_ADD_IO_SEG(0x00011F000000BD70ull)
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV \
+ CVMX_ADD_IO_SEG(0x00011F000000BCB0ull)
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B1 \
+ CVMX_ADD_IO_SEG(0x00011F0000008650ull)
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B2 \
+ CVMX_ADD_IO_SEG(0x00011F0000008660ull)
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B3 \
+ CVMX_ADD_IO_SEG(0x00011F0000008670ull)
+#define CVMX_PEXP_NPEI_PKTX_CNTS(offset) \
+ CVMX_ADD_IO_SEG(0x00011F000000A400ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_INSTR_BADDR(offset) \
+ CVMX_ADD_IO_SEG(0x00011F000000A800ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \
+ CVMX_ADD_IO_SEG(0x00011F000000AC00ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \
+ CVMX_ADD_IO_SEG(0x00011F000000B000ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_INSTR_HEADER(offset) \
+ CVMX_ADD_IO_SEG(0x00011F000000B400ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_IN_BP(offset) \
+ CVMX_ADD_IO_SEG(0x00011F000000B800ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_SLIST_BADDR(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000009400ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000009800ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \
+ CVMX_ADD_IO_SEG(0x00011F0000009C00ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKT_CNT_INT \
+ CVMX_ADD_IO_SEG(0x00011F0000009110ull)
+#define CVMX_PEXP_NPEI_PKT_CNT_INT_ENB \
+ CVMX_ADD_IO_SEG(0x00011F0000009130ull)
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ES \
+ CVMX_ADD_IO_SEG(0x00011F00000090B0ull)
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_NS \
+ CVMX_ADD_IO_SEG(0x00011F00000090A0ull)
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ROR \
+ CVMX_ADD_IO_SEG(0x00011F0000009090ull)
+#define CVMX_PEXP_NPEI_PKT_DPADDR \
+ CVMX_ADD_IO_SEG(0x00011F0000009080ull)
+#define CVMX_PEXP_NPEI_PKT_INPUT_CONTROL \
+ CVMX_ADD_IO_SEG(0x00011F0000009150ull)
+#define CVMX_PEXP_NPEI_PKT_INSTR_ENB \
+ CVMX_ADD_IO_SEG(0x00011F0000009000ull)
+#define CVMX_PEXP_NPEI_PKT_INSTR_RD_SIZE \
+ CVMX_ADD_IO_SEG(0x00011F0000009190ull)
+#define CVMX_PEXP_NPEI_PKT_INSTR_SIZE \
+ CVMX_ADD_IO_SEG(0x00011F0000009020ull)
+#define CVMX_PEXP_NPEI_PKT_INT_LEVELS \
+ CVMX_ADD_IO_SEG(0x00011F0000009100ull)
+#define CVMX_PEXP_NPEI_PKT_IN_BP \
+ CVMX_ADD_IO_SEG(0x00011F00000086B0ull)
+#define CVMX_PEXP_NPEI_PKT_IN_DONEX_CNTS(offset) \
+ CVMX_ADD_IO_SEG(0x00011F000000A000ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKT_IN_INSTR_COUNTS \
+ CVMX_ADD_IO_SEG(0x00011F00000086A0ull)
+#define CVMX_PEXP_NPEI_PKT_IN_PCIE_PORT \
+ CVMX_ADD_IO_SEG(0x00011F00000091A0ull)
+#define CVMX_PEXP_NPEI_PKT_IPTR \
+ CVMX_ADD_IO_SEG(0x00011F0000009070ull)
+#define CVMX_PEXP_NPEI_PKT_OUTPUT_WMARK \
+ CVMX_ADD_IO_SEG(0x00011F0000009160ull)
+#define CVMX_PEXP_NPEI_PKT_OUT_BMODE \
+ CVMX_ADD_IO_SEG(0x00011F00000090D0ull)
+#define CVMX_PEXP_NPEI_PKT_OUT_ENB \
+ CVMX_ADD_IO_SEG(0x00011F0000009010ull)
+#define CVMX_PEXP_NPEI_PKT_PCIE_PORT \
+ CVMX_ADD_IO_SEG(0x00011F00000090E0ull)
+#define CVMX_PEXP_NPEI_PKT_PORT_IN_RST \
+ CVMX_ADD_IO_SEG(0x00011F0000008690ull)
+#define CVMX_PEXP_NPEI_PKT_SLIST_ES \
+ CVMX_ADD_IO_SEG(0x00011F0000009050ull)
+#define CVMX_PEXP_NPEI_PKT_SLIST_ID_SIZE \
+ CVMX_ADD_IO_SEG(0x00011F0000009180ull)
+#define CVMX_PEXP_NPEI_PKT_SLIST_NS \
+ CVMX_ADD_IO_SEG(0x00011F0000009040ull)
+#define CVMX_PEXP_NPEI_PKT_SLIST_ROR \
+ CVMX_ADD_IO_SEG(0x00011F0000009030ull)
+#define CVMX_PEXP_NPEI_PKT_TIME_INT \
+ CVMX_ADD_IO_SEG(0x00011F0000009120ull)
+#define CVMX_PEXP_NPEI_PKT_TIME_INT_ENB \
+ CVMX_ADD_IO_SEG(0x00011F0000009140ull)
+#define CVMX_PEXP_NPEI_RSL_INT_BLOCKS \
+ CVMX_ADD_IO_SEG(0x00011F0000008520ull)
+#define CVMX_PEXP_NPEI_SCRATCH_1 \
+ CVMX_ADD_IO_SEG(0x00011F0000008270ull)
+#define CVMX_PEXP_NPEI_STATE1 \
+ CVMX_ADD_IO_SEG(0x00011F0000008620ull)
+#define CVMX_PEXP_NPEI_STATE2 \
+ CVMX_ADD_IO_SEG(0x00011F0000008630ull)
+#define CVMX_PEXP_NPEI_STATE3 \
+ CVMX_ADD_IO_SEG(0x00011F0000008640ull)
+#define CVMX_PEXP_NPEI_WINDOW_CTL \
+ CVMX_ADD_IO_SEG(0x00011F0000008380ull)
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
index 03fddfa3e928..e31e3fe14f8a 100644
--- a/arch/mips/include/asm/octeon/cvmx.h
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -376,6 +376,18 @@ static inline uint64_t cvmx_get_cycle(void)
}
/**
+ * Wait for the specified number of cycle
+ *
+ */
+static inline void cvmx_wait(uint64_t cycles)
+{
+ uint64_t done = cvmx_get_cycle() + cycles;
+
+ while (cvmx_get_cycle() < done)
+ ; /* Spin */
+}
+
+/**
* Reads a chip global cycle counter. This counts CPU cycles since
* chip reset. The counter is 64 bit.
* This register does not exist on CN38XX pass 1 silicion
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index edc676084cda..cac9b1a206fc 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -245,4 +245,6 @@ static inline uint32_t octeon_npi_read32(uint64_t address)
return cvmx_read64_uint32(address ^ 4);
}
+extern struct cvmx_bootinfo *octeon_bootinfo;
+
#endif /* __ASM_OCTEON_OCTEON_H */
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
index 4c140db36786..387bf59f1e37 100644
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -399,6 +399,7 @@ __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16)
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32)
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32)
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32)
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64)
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64)
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
diff --git a/arch/mips/include/asm/txx9/dmac.h b/arch/mips/include/asm/txx9/dmac.h
new file mode 100644
index 000000000000..5e9151fccbb4
--- /dev/null
+++ b/arch/mips/include/asm/txx9/dmac.h
@@ -0,0 +1,51 @@
+/*
+ * TXx9 SoC DMA Controller
+ *
+ * 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_TXX9_DMAC_H
+#define __ASM_TXX9_DMAC_H
+
+#include <linux/dmaengine.h>
+
+#define TXX9_DMA_MAX_NR_CHANNELS 4
+
+/**
+ * struct txx9dmac_platform_data - Controller configuration parameters
+ * @memcpy_chan: Channel used for DMA_MEMCPY
+ * @have_64bit_regs: DMAC have 64 bit registers
+ */
+struct txx9dmac_platform_data {
+ int memcpy_chan;
+ bool have_64bit_regs;
+};
+
+/**
+ * struct txx9dmac_chan_platform_data - Channel configuration parameters
+ * @dmac_dev: A platform device for DMAC
+ */
+struct txx9dmac_chan_platform_data {
+ struct platform_device *dmac_dev;
+};
+
+/**
+ * struct txx9dmac_slave - Controller-specific information about a slave
+ * @tx_reg: physical address of data register used for
+ * memory-to-peripheral transfers
+ * @rx_reg: physical address of data register used for
+ * peripheral-to-memory transfers
+ * @reg_width: peripheral register width
+ */
+struct txx9dmac_slave {
+ u64 tx_reg;
+ u64 rx_reg;
+ unsigned int reg_width;
+};
+
+void txx9_dmac_init(int id, unsigned long baseaddr, int irq,
+ const struct txx9dmac_platform_data *pdata);
+
+#endif /* __ASM_TXX9_DMAC_H */
diff --git a/arch/mips/include/asm/txx9/tx4927.h b/arch/mips/include/asm/txx9/tx4927.h
index 7d813f1cb98d..d92ae07000d3 100644
--- a/arch/mips/include/asm/txx9/tx4927.h
+++ b/arch/mips/include/asm/txx9/tx4927.h
@@ -41,6 +41,7 @@
#define TX4927_SDRAMC_REG (TX4927_REG_BASE + 0x8000)
#define TX4927_EBUSC_REG (TX4927_REG_BASE + 0x9000)
+#define TX4927_DMA_REG (TX4927_REG_BASE + 0xb000)
#define TX4927_PCIC_REG (TX4927_REG_BASE + 0xd000)
#define TX4927_CCFG_REG (TX4927_REG_BASE + 0xe000)
#define TX4927_IRC_REG (TX4927_REG_BASE + 0xf600)
@@ -265,5 +266,6 @@ int tx4927_pciclk66_setup(void);
void tx4927_setup_pcierr_irq(void);
void tx4927_irq_init(void);
void tx4927_mtd_init(int ch);
+void tx4927_dmac_init(int memcpy_chan);
#endif /* __ASM_TXX9_TX4927_H */
diff --git a/arch/mips/include/asm/txx9/tx4938.h b/arch/mips/include/asm/txx9/tx4938.h
index cd8bc2021755..0758a0c411b1 100644
--- a/arch/mips/include/asm/txx9/tx4938.h
+++ b/arch/mips/include/asm/txx9/tx4938.h
@@ -305,5 +305,6 @@ struct tx4938ide_platform_info {
};
void tx4938_ata_init(unsigned int irq, unsigned int shift, int tune);
+void tx4938_dmac_init(int memcpy_chan0, int memcpy_chan1);
#endif
diff --git a/arch/mips/include/asm/txx9/tx4939.h b/arch/mips/include/asm/txx9/tx4939.h
index f02c50b3abfb..1be9798a26b5 100644
--- a/arch/mips/include/asm/txx9/tx4939.h
+++ b/arch/mips/include/asm/txx9/tx4939.h
@@ -544,5 +544,6 @@ void tx4939_ata_init(void);
void tx4939_rtc_init(void);
void tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
unsigned char ch_mask, unsigned char wide_mask);
+void tx4939_dmac_init(int memcpy_chan0, int memcpy_chan1);
#endif /* __ASM_TXX9_TX4939_H */
diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c
index 2e911e3da8d3..0037f21baf0d 100644
--- a/arch/mips/kernel/cevt-txx9.c
+++ b/arch/mips/kernel/cevt-txx9.c
@@ -20,22 +20,29 @@
#define TIMER_CCD 0 /* 1/2 */
#define TIMER_CLK(imclk) ((imclk) / (2 << TIMER_CCD))
-static struct txx9_tmr_reg __iomem *txx9_cs_tmrptr;
+struct txx9_clocksource {
+ struct clocksource cs;
+ struct txx9_tmr_reg __iomem *tmrptr;
+};
static cycle_t txx9_cs_read(struct clocksource *cs)
{
- return __raw_readl(&txx9_cs_tmrptr->trr);
+ struct txx9_clocksource *txx9_cs =
+ container_of(cs, struct txx9_clocksource, cs);
+ return __raw_readl(&txx9_cs->tmrptr->trr);
}
/* Use 1 bit smaller width to use full bits in that width */
#define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1)
-static struct clocksource txx9_clocksource = {
- .name = "TXx9",
- .rating = 200,
- .read = txx9_cs_read,
- .mask = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+static struct txx9_clocksource txx9_clocksource = {
+ .cs = {
+ .name = "TXx9",
+ .rating = 200,
+ .read = txx9_cs_read,
+ .mask = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ },
};
void __init txx9_clocksource_init(unsigned long baseaddr,
@@ -43,8 +50,8 @@ void __init txx9_clocksource_init(unsigned long baseaddr,
{
struct txx9_tmr_reg __iomem *tmrptr;
- clocksource_set_clock(&txx9_clocksource, TIMER_CLK(imbusclk));
- clocksource_register(&txx9_clocksource);
+ clocksource_set_clock(&txx9_clocksource.cs, TIMER_CLK(imbusclk));
+ clocksource_register(&txx9_clocksource.cs);
tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
__raw_writel(TCR_BASE, &tmrptr->tcr);
@@ -53,10 +60,13 @@ void __init txx9_clocksource_init(unsigned long baseaddr,
__raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr);
__raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra);
__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
- txx9_cs_tmrptr = tmrptr;
+ txx9_clocksource.tmrptr = tmrptr;
}
-static struct txx9_tmr_reg __iomem *txx9_tmrptr;
+struct txx9_clock_event_device {
+ struct clock_event_device cd;
+ struct txx9_tmr_reg __iomem *tmrptr;
+};
static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr)
{
@@ -69,7 +79,9 @@ static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr)
static void txx9tmr_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
- struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
+ struct txx9_clock_event_device *txx9_cd =
+ container_of(evt, struct txx9_clock_event_device, cd);
+ struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
txx9tmr_stop_and_clear(tmrptr);
switch (mode) {
@@ -99,7 +111,9 @@ static void txx9tmr_set_mode(enum clock_event_mode mode,
static int txx9tmr_set_next_event(unsigned long delta,
struct clock_event_device *evt)
{
- struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
+ struct txx9_clock_event_device *txx9_cd =
+ container_of(evt, struct txx9_clock_event_device, cd);
+ struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
txx9tmr_stop_and_clear(tmrptr);
/* start timer */
@@ -108,18 +122,22 @@ static int txx9tmr_set_next_event(unsigned long delta,
return 0;
}
-static struct clock_event_device txx9tmr_clock_event_device = {
- .name = "TXx9",
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .rating = 200,
- .set_mode = txx9tmr_set_mode,
- .set_next_event = txx9tmr_set_next_event,
+static struct txx9_clock_event_device txx9_clock_event_device = {
+ .cd = {
+ .name = "TXx9",
+ .features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .set_mode = txx9tmr_set_mode,
+ .set_next_event = txx9tmr_set_next_event,
+ },
};
static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
{
- struct clock_event_device *cd = &txx9tmr_clock_event_device;
- struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
+ struct txx9_clock_event_device *txx9_cd = dev_id;
+ struct clock_event_device *cd = &txx9_cd->cd;
+ struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
__raw_writel(0, &tmrptr->tisr); /* ack interrupt */
cd->event_handler(cd);
@@ -130,19 +148,20 @@ static struct irqaction txx9tmr_irq = {
.handler = txx9tmr_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU,
.name = "txx9tmr",
+ .dev_id = &txx9_clock_event_device,
};
void __init txx9_clockevent_init(unsigned long baseaddr, int irq,
unsigned int imbusclk)
{
- struct clock_event_device *cd = &txx9tmr_clock_event_device;
+ struct clock_event_device *cd = &txx9_clock_event_device.cd;
struct txx9_tmr_reg __iomem *tmrptr;
tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
txx9tmr_stop_and_clear(tmrptr);
__raw_writel(TIMER_CCD, &tmrptr->ccdr);
__raw_writel(0, &tmrptr->itmr);
- txx9_tmrptr = tmrptr;
+ txx9_clock_event_device.tmrptr = tmrptr;
clockevent_set_clock(cd, TIMER_CLK(imbusclk));
cd->max_delta_ns =
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
index 87deb8f6c458..3f43c2e3aa5a 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -155,7 +155,7 @@ static void gic_unmask_irq(unsigned int irq)
static DEFINE_SPINLOCK(gic_lock);
-static void gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
{
cpumask_t tmp = CPU_MASK_NONE;
unsigned long flags;
@@ -166,7 +166,7 @@ static void gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
cpumask_and(&tmp, cpumask, cpu_online_mask);
if (cpus_empty(tmp))
- return;
+ return -1;
/* Assumption : cpumask refers to a single CPU */
spin_lock_irqsave(&gic_lock, flags);
@@ -190,6 +190,7 @@ static void gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
cpumask_copy(irq_desc[irq].affinity, cpumask);
spin_unlock_irqrestore(&gic_lock, flags);
+ return 0;
}
#endif
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 58d9075e86fe..e9ffb5a1a0a1 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -100,6 +100,12 @@ static inline void r4k_blast_dcache_page_dc32(unsigned long addr)
blast_dcache32_page(addr);
}
+static inline void r4k_blast_dcache_page_dc64(unsigned long addr)
+{
+ R4600_HIT_CACHEOP_WAR_IMPL;
+ blast_dcache64_page(addr);
+}
+
static void __cpuinit r4k_blast_dcache_page_setup(void)
{
unsigned long dc_lsize = cpu_dcache_line_size();
@@ -110,6 +116,8 @@ static void __cpuinit r4k_blast_dcache_page_setup(void)
r4k_blast_dcache_page = blast_dcache16_page;
else if (dc_lsize == 32)
r4k_blast_dcache_page = r4k_blast_dcache_page_dc32;
+ else if (dc_lsize == 64)
+ r4k_blast_dcache_page = r4k_blast_dcache_page_dc64;
}
static void (* r4k_blast_dcache_page_indexed)(unsigned long addr);
@@ -124,6 +132,8 @@ static void __cpuinit r4k_blast_dcache_page_indexed_setup(void)
r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed;
else if (dc_lsize == 32)
r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed;
+ else if (dc_lsize == 64)
+ r4k_blast_dcache_page_indexed = blast_dcache64_page_indexed;
}
static void (* r4k_blast_dcache)(void);
@@ -138,6 +148,8 @@ static void __cpuinit r4k_blast_dcache_setup(void)
r4k_blast_dcache = blast_dcache16;
else if (dc_lsize == 32)
r4k_blast_dcache = blast_dcache32;
+ else if (dc_lsize == 64)
+ r4k_blast_dcache = blast_dcache64;
}
/* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index bed56f1ac837..d835130ad609 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -20,9 +20,10 @@
#include <dma-coherence.h>
-static inline unsigned long dma_addr_to_virt(dma_addr_t dma_addr)
+static inline unsigned long dma_addr_to_virt(struct device *dev,
+ dma_addr_t dma_addr)
{
- unsigned long addr = plat_dma_addr_to_phys(dma_addr);
+ unsigned long addr = plat_dma_addr_to_phys(dev, dma_addr);
return (unsigned long)phys_to_virt(addr);
}
@@ -111,7 +112,7 @@ EXPORT_SYMBOL(dma_alloc_coherent);
void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle)
{
- plat_unmap_dma_mem(dev, dma_handle);
+ plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
free_pages((unsigned long) vaddr, get_order(size));
}
@@ -122,7 +123,7 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
{
unsigned long addr = (unsigned long) vaddr;
- plat_unmap_dma_mem(dev, dma_handle);
+ plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
if (!plat_device_is_coherent(dev))
addr = CAC_ADDR(addr);
@@ -170,10 +171,10 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
{
if (cpu_is_noncoherent_r10000(dev))
- __dma_sync(dma_addr_to_virt(dma_addr), size,
+ __dma_sync(dma_addr_to_virt(dev, dma_addr), size,
direction);
- plat_unmap_dma_mem(dev, dma_addr);
+ plat_unmap_dma_mem(dev, dma_addr, size, direction);
}
EXPORT_SYMBOL(dma_unmap_single);
@@ -249,7 +250,7 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
if (addr)
__dma_sync(addr, sg->length, direction);
}
- plat_unmap_dma_mem(dev, sg->dma_address);
+ plat_unmap_dma_mem(dev, sg->dma_address, sg->length, direction);
}
}
@@ -263,7 +264,7 @@ void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
if (cpu_is_noncoherent_r10000(dev)) {
unsigned long addr;
- addr = dma_addr_to_virt(dma_handle);
+ addr = dma_addr_to_virt(dev, dma_handle);
__dma_sync(addr, size, direction);
}
}
@@ -279,7 +280,7 @@ void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
if (!plat_device_is_coherent(dev)) {
unsigned long addr;
- addr = dma_addr_to_virt(dma_handle);
+ addr = dma_addr_to_virt(dev, dma_handle);
__dma_sync(addr, size, direction);
}
}
@@ -294,7 +295,7 @@ void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
if (cpu_is_noncoherent_r10000(dev)) {
unsigned long addr;
- addr = dma_addr_to_virt(dma_handle);
+ addr = dma_addr_to_virt(dev, dma_handle);
__dma_sync(addr + offset, size, direction);
}
}
@@ -310,7 +311,7 @@ void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
if (!plat_device_is_coherent(dev)) {
unsigned long addr;
- addr = dma_addr_to_virt(dma_handle);
+ addr = dma_addr_to_virt(dev, dma_handle);
__dma_sync(addr + offset, size, direction);
}
}
diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c
index 5ba31888fefb..499ffe5475df 100644
--- a/arch/mips/mti-malta/malta-smtc.c
+++ b/arch/mips/mti-malta/malta-smtc.c
@@ -114,7 +114,7 @@ struct plat_smp_ops msmtc_smp_ops = {
*/
-void plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
+int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
{
cpumask_t tmask;
int cpu = 0;
@@ -156,5 +156,7 @@ void plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
/* Do any generic SMTC IRQ affinity setup */
smtc_set_irq_affinity(irq, tmask);
+
+ return 0;
}
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 352352b3cb2f..4f256a131bf6 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -50,7 +50,7 @@ static void enable_bcm1480_irq(unsigned int irq);
static void disable_bcm1480_irq(unsigned int irq);
static void ack_bcm1480_irq(unsigned int irq);
#ifdef CONFIG_SMP
-static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask);
+static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask);
#endif
#ifdef CONFIG_PCI
@@ -109,7 +109,7 @@ void bcm1480_unmask_irq(int cpu, int irq)
}
#ifdef CONFIG_SMP
-static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
{
int i = 0, old_cpu, cpu, int_on, k;
u64 cur_ints;
@@ -119,7 +119,7 @@ static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
if (cpumask_weight(mask) != 1) {
printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
- return;
+ return -1;
}
i = cpumask_first(mask);
@@ -155,6 +155,8 @@ static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
}
spin_unlock(&bcm1480_imr_lock);
spin_unlock_irqrestore(&desc->lock, flags);
+
+ return 0;
}
#endif
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index c08ff582da6f..e389507f1f96 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -50,7 +50,7 @@ static void enable_sb1250_irq(unsigned int irq);
static void disable_sb1250_irq(unsigned int irq);
static void ack_sb1250_irq(unsigned int irq);
#ifdef CONFIG_SMP
-static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask);
+static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask);
#endif
#ifdef CONFIG_SIBYTE_HAS_LDT
@@ -103,7 +103,7 @@ void sb1250_unmask_irq(int cpu, int irq)
}
#ifdef CONFIG_SMP
-static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
{
int i = 0, old_cpu, cpu, int_on;
u64 cur_ints;
@@ -114,7 +114,7 @@ static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
if (cpumask_weight(mask) > 1) {
printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
- return;
+ return -1;
}
/* Convert logical CPU to physical CPU */
@@ -146,6 +146,8 @@ static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
}
spin_unlock(&sb1250_imr_lock);
spin_unlock_irqrestore(&desc->lock, flags);
+
+ return 0;
}
#endif
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index 8a266c6a3f58..369d8637217d 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -33,6 +33,7 @@
#include <asm/txx9/pci.h>
#include <asm/txx9tmr.h>
#include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
#ifdef CONFIG_CPU_TX49XX
#include <asm/txx9/tx4938.h>
#endif
@@ -821,3 +822,57 @@ void __init txx9_iocled_init(unsigned long baseaddr,
{
}
#endif /* CONFIG_LEDS_GPIO */
+
+void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq,
+ const struct txx9dmac_platform_data *pdata)
+{
+#if defined(CONFIG_TXX9_DMAC) || defined(CONFIG_TXX9_DMAC_MODULE)
+ struct resource res[] = {
+ {
+ .start = baseaddr,
+ .end = baseaddr + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+#ifndef CONFIG_MACH_TX49XX
+ }, {
+ .start = irq,
+ .flags = IORESOURCE_IRQ,
+#endif
+ }
+ };
+#ifdef CONFIG_MACH_TX49XX
+ struct resource chan_res[] = {
+ {
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+#endif
+ struct platform_device *pdev = platform_device_alloc("txx9dmac", id);
+ struct txx9dmac_chan_platform_data cpdata;
+ int i;
+
+ if (!pdev ||
+ platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
+ platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
+ platform_device_add(pdev)) {
+ platform_device_put(pdev);
+ return;
+ }
+ memset(&cpdata, 0, sizeof(cpdata));
+ cpdata.dmac_dev = pdev;
+ for (i = 0; i < TXX9_DMA_MAX_NR_CHANNELS; i++) {
+#ifdef CONFIG_MACH_TX49XX
+ chan_res[0].start = irq + i;
+#endif
+ pdev = platform_device_alloc("txx9dmac-chan",
+ id * TXX9_DMA_MAX_NR_CHANNELS + i);
+ if (!pdev ||
+#ifdef CONFIG_MACH_TX49XX
+ platform_device_add_resources(pdev, chan_res,
+ ARRAY_SIZE(chan_res)) ||
+#endif
+ platform_device_add_data(pdev, &cpdata, sizeof(cpdata)) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
+ }
+#endif
+}
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c
index 914e93c62639..778078adea3b 100644
--- a/arch/mips/txx9/generic/setup_tx4927.c
+++ b/arch/mips/txx9/generic/setup_tx4927.c
@@ -22,6 +22,7 @@
#include <asm/txx9tmr.h>
#include <asm/txx9pio.h>
#include <asm/txx9/generic.h>
+#include <asm/txx9/dmac.h>
#include <asm/txx9/tx4927.h>
static void __init tx4927_wdr_init(void)
@@ -253,6 +254,17 @@ void __init tx4927_mtd_init(int ch)
txx9_physmap_flash_init(ch, start, size, &pdata);
}
+void __init tx4927_dmac_init(int memcpy_chan)
+{
+ struct txx9dmac_platform_data plat_data = {
+ .memcpy_chan = memcpy_chan,
+ .have_64bit_regs = true,
+ };
+
+ txx9_dmac_init(0, TX4927_DMA_REG & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4927_IR_DMA(0), &plat_data);
+}
+
static void __init tx4927_stop_unused_modules(void)
{
__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c
index f0844f891f0b..5d2cbbfd5d4a 100644
--- a/arch/mips/txx9/generic/setup_tx4938.c
+++ b/arch/mips/txx9/generic/setup_tx4938.c
@@ -24,6 +24,7 @@
#include <asm/txx9pio.h>
#include <asm/txx9/generic.h>
#include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
#include <asm/txx9/tx4938.h>
static void __init tx4938_wdr_init(void)
@@ -239,11 +240,6 @@ void __init tx4938_setup(void)
for (i = 0; i < TX4938_NR_TMR; i++)
txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
- /* DMA */
- for (i = 0; i < 2; i++)
- ____raw_writeq(TX4938_DMA_MCR_MSTEN,
- (void __iomem *)(TX4938_DMA_REG(i) + 0x50));
-
/* PIO */
txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO);
__raw_writel(0, &tx4938_pioptr->maskcpu);
@@ -403,6 +399,21 @@ void __init tx4938_ndfmc_init(unsigned int hold, unsigned int spw)
txx9_ndfmc_init(baseaddr, &plat_data);
}
+void __init tx4938_dmac_init(int memcpy_chan0, int memcpy_chan1)
+{
+ struct txx9dmac_platform_data plat_data = {
+ .have_64bit_regs = true,
+ };
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
+ txx9_dmac_init(i, TX4938_DMA_REG(i) & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4938_IR_DMA(i, 0),
+ &plat_data);
+ }
+}
+
static void __init tx4938_stop_unused_modules(void)
{
__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index 7a25b573e9b0..6ed53a75010a 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -28,6 +28,7 @@
#include <asm/txx9tmr.h>
#include <asm/txx9/generic.h>
#include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
#include <asm/txx9/tx4939.h>
static void __init tx4939_wdr_init(void)
@@ -259,11 +260,6 @@ void __init tx4939_setup(void)
for (i = 0; i < TX4939_NR_TMR; i++)
txx9_tmr_init(TX4939_TMR_REG(i) & 0xfffffffffULL);
- /* DMA */
- for (i = 0; i < 2; i++)
- ____raw_writeq(TX4938_DMA_MCR_MSTEN,
- (void __iomem *)(TX4939_DMA_REG(i) + 0x50));
-
/* set PCIC1 reset (required to prevent hangup on BIST) */
txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
@@ -474,6 +470,21 @@ void __init tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
}
+void __init tx4939_dmac_init(int memcpy_chan0, int memcpy_chan1)
+{
+ struct txx9dmac_platform_data plat_data = {
+ .have_64bit_regs = true,
+ };
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
+ txx9_dmac_init(i, TX4939_DMA_REG(i) & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4939_IR_DMA(i, 0),
+ &plat_data);
+ }
+}
+
static void __init tx4939_stop_unused_modules(void)
{
__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c
index 01129a9d50fa..332cdbc7fcef 100644
--- a/arch/mips/txx9/rbtx4927/setup.c
+++ b/arch/mips/txx9/rbtx4927/setup.c
@@ -337,6 +337,10 @@ static void __init rbtx4927_device_init(void)
rbtx4927_ne_init();
tx4927_wdt_init();
rbtx4927_mtd_init();
+ if (TX4927_REV_PCODE() == 0x4927)
+ tx4927_dmac_init(2);
+ else
+ tx4938_dmac_init(0, 2);
txx9_iocled_init(RBTX4927_LED_ADDR - IO_BASE, -1, 3, 1, "green", NULL);
rbtx4927_gpioled_init();
}
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
index 65d13df8878a..37c5e3d20287 100644
--- a/arch/mips/txx9/rbtx4938/setup.c
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -355,6 +355,7 @@ static void __init rbtx4938_device_init(void)
/* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
tx4938_ndfmc_init(10, 35);
tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1);
+ tx4938_dmac_init(0, 2);
txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
}
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index 011e1e332f47..d5ef662e992b 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -498,6 +498,7 @@ static void __init rbtx4939_device_init(void)
tx4939_wdt_init();
tx4939_ata_init();
tx4939_rtc_init();
+ tx4939_dmac_init(0, 2);
}
static void __init rbtx4939_setup(void)
diff --git a/arch/mn10300/include/asm/gdb-stub.h b/arch/mn10300/include/asm/gdb-stub.h
index e5a6368559af..556cce992548 100644
--- a/arch/mn10300/include/asm/gdb-stub.h
+++ b/arch/mn10300/include/asm/gdb-stub.h
@@ -109,7 +109,6 @@ extern asmlinkage int gdbstub_intercept(struct pt_regs *, enum exception_code);
extern asmlinkage void gdbstub_exception(struct pt_regs *, enum exception_code);
extern asmlinkage void __gdbstub_bug_trap(void);
extern asmlinkage void __gdbstub_pause(void);
-extern asmlinkage void start_kernel(void);
#ifndef CONFIG_MN10300_CACHE_DISABLED
extern asmlinkage void gdbstub_purge_cache(void);
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 4ea4229d765c..8007f1e65729 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -130,15 +130,17 @@ int cpu_check_affinity(unsigned int irq, const struct cpumask *dest)
return cpu_dest;
}
-static void cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
+static int cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
{
int cpu_dest;
cpu_dest = cpu_check_affinity(irq, dest);
if (cpu_dest < 0)
- return;
+ return -1;
cpumask_copy(&irq_desc[irq].affinity, dest);
+
+ return 0;
}
#endif
diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts
index 53a7a6255909..910944edd886 100644
--- a/arch/powerpc/boot/dts/gef_ppc9a.dts
+++ b/arch/powerpc/boot/dts/gef_ppc9a.dts
@@ -164,9 +164,21 @@
device_type = "soc";
compatible = "fsl,mpc8641-soc", "simple-bus";
ranges = <0x0 0xfef00000 0x00100000>;
- reg = <0xfef00000 0x100000>; // CCSRBAR 1M
bus-frequency = <33333333>;
+ mcm-law@0 {
+ compatible = "fsl,mcm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ mcm@1000 {
+ compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
i2c1: i2c@3000 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts
index 1569117e5ddc..0f4c9ec2c3a6 100644
--- a/arch/powerpc/boot/dts/gef_sbc310.dts
+++ b/arch/powerpc/boot/dts/gef_sbc310.dts
@@ -163,9 +163,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xfef00000 0x00100000>;
- reg = <0xfef00000 0x100000>; // CCSRBAR 1M
bus-frequency = <33333333>;
+ mcm-law@0 {
+ compatible = "fsl,mcm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ mcm@1000 {
+ compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
i2c1: i2c@3000 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
index 6582dbd36da7..217f8aa66725 100644
--- a/arch/powerpc/boot/dts/gef_sbc610.dts
+++ b/arch/powerpc/boot/dts/gef_sbc610.dts
@@ -128,9 +128,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xfef00000 0x00100000>;
- reg = <0xfef00000 0x100000>; // CCSRBAR 1M
bus-frequency = <33333333>;
+ mcm-law@0 {
+ compatible = "fsl,mcm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ mcm@1000 {
+ compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
i2c1: i2c@3000 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/powerpc/boot/dts/ksi8560.dts b/arch/powerpc/boot/dts/ksi8560.dts
index c9cfd374bffb..bdb7fc0fa332 100644
--- a/arch/powerpc/boot/dts/ksi8560.dts
+++ b/arch/powerpc/boot/dts/ksi8560.dts
@@ -56,6 +56,19 @@
ranges = <0x00000000 0xfdf00000 0x00100000>;
bus-frequency = <0>; /* Fixed by bootwrapper */
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index 57c595bf1071..436c9c671dd9 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -249,6 +249,8 @@
reg = <0xe0100000 0x480>;
brg-frequency = <0>;
bus-frequency = <198000000>;
+ fsl,qe-num-riscs = <1>;
+ fsl,qe-num-snums = <28>;
muram@10000 {
#address-cells = <1>;
@@ -369,7 +371,6 @@
};
pci0: pci@e0008500 {
- cell-index = <1>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x11 AD17 */
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index 4319bd70a580..9a0952f74b81 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -221,6 +221,8 @@
reg = <0xe0100000 0x480>;
brg-frequency = <0>;
bus-frequency = <198000000>;
+ fsl,qe-num-riscs = <1>;
+ fsl,qe-num-snums = <28>;
muram@10000 {
#address-cells = <1>;
@@ -327,7 +329,6 @@
};
pci0: pci@e0008500 {
- cell-index = <1>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x10 AD16 (USB) */
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index 1ae38f0ddef8..e3eeaeda9187 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -278,7 +278,6 @@
};
pci0: pci@e0008500 {
- cell-index = <1>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x10 - SATA */
@@ -301,7 +300,6 @@
};
pci1: pci@e0008600 {
- cell-index = <2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x0E - MiniPCI Slot */
diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
index 662abe1fb804..eb732115f016 100644
--- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
@@ -227,7 +227,6 @@
};
pci0: pci@e0008600 {
- cell-index = <2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x0F - PCI Slot */
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index d9f0a2325fa4..a2553a6f9009 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -286,7 +286,6 @@
};
pci0: pci@e0008500 {
- cell-index = <1>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
@@ -348,7 +347,6 @@
};
pci1: pci@e0008600 {
- cell-index = <2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 6e34f170fa62..39ff4c829caf 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -289,6 +289,8 @@
reg = <0xe0100000 0x480>;
brg-frequency = <0>;
bus-frequency = <396000000>;
+ fsl,qe-num-riscs = <2>;
+ fsl,qe-num-snums = <28>;
muram@10000 {
#address-cells = <1>;
@@ -410,7 +412,6 @@
};
pci0: pci@e0008500 {
- cell-index = <1>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/mpc836x_rdk.dts b/arch/powerpc/boot/dts/mpc836x_rdk.dts
index 37b789510d68..6315d6fcc58a 100644
--- a/arch/powerpc/boot/dts/mpc836x_rdk.dts
+++ b/arch/powerpc/boot/dts/mpc836x_rdk.dts
@@ -198,6 +198,8 @@
clock-frequency = <0>;
bus-frequency = <0>;
brg-frequency = <0>;
+ fsl,qe-num-riscs = <2>;
+ fsl,qe-num-snums = <28>;
muram@10000 {
#address-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts
index 963708017e6c..67bb372c9451 100644
--- a/arch/powerpc/boot/dts/mpc8377_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8377_mds.dts
@@ -383,7 +383,6 @@
};
pci0: pci@e0008500 {
- cell-index = <0>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/mpc8378_mds.dts b/arch/powerpc/boot/dts/mpc8378_mds.dts
index 651ff2f9db2d..a955a577db81 100644
--- a/arch/powerpc/boot/dts/mpc8378_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8378_mds.dts
@@ -367,7 +367,6 @@
};
pci0: pci@e0008500 {
- cell-index = <0>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/mpc8379_mds.dts b/arch/powerpc/boot/dts/mpc8379_mds.dts
index d6f208b8297a..d266ddbfc28d 100644
--- a/arch/powerpc/boot/dts/mpc8379_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8379_mds.dts
@@ -397,7 +397,6 @@
};
pci0: pci@e0008500 {
- cell-index = <0>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts
index b31c5041350b..e781ad2f1f8a 100644
--- a/arch/powerpc/boot/dts/mpc8536ds.dts
+++ b/arch/powerpc/boot/dts/mpc8536ds.dts
@@ -51,9 +51,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xffe00000 0x100000>;
- reg = <0xffe00000 0x1000>;
bus-frequency = <0>; // Filled out by uboot.
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <12>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8536-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8536-memory-controller";
reg = <0x2000 0x1000>;
@@ -321,7 +333,6 @@
};
pci0: pci@ffe08000 {
- cell-index = <0>;
compatible = "fsl,mpc8540-pci";
device_type = "pci";
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
@@ -346,7 +357,6 @@
};
pci1: pcie@ffe09000 {
- cell-index = <1>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -383,7 +393,6 @@
};
pci2: pcie@ffe0a000 {
- cell-index = <2>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -420,7 +429,6 @@
};
pci3: pcie@ffe0b000 {
- cell-index = <3>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
index ddd67be10b03..9dc292962a9a 100644
--- a/arch/powerpc/boot/dts/mpc8540ads.dts
+++ b/arch/powerpc/boot/dts/mpc8540ads.dts
@@ -55,9 +55,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x100000>; // CCSRBAR 1M
bus-frequency = <0>;
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8540-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,8540-memory-controller";
reg = <0x2000 0x1000>;
@@ -258,7 +270,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
index e45097f44fbd..9a3ad311aedf 100644
--- a/arch/powerpc/boot/dts/mpc8541cds.dts
+++ b/arch/powerpc/boot/dts/mpc8541cds.dts
@@ -55,9 +55,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x1000>; // CCSRBAR 1M
bus-frequency = <0>;
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8541-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,8541-memory-controller";
reg = <0x2000 0x1000>;
@@ -272,7 +284,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
interrupt-map = <
@@ -344,7 +355,6 @@
};
pci1: pci@e0009000 {
- cell-index = <1>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts
index 7c6932be0197..98e94b465662 100644
--- a/arch/powerpc/boot/dts/mpc8544ds.dts
+++ b/arch/powerpc/boot/dts/mpc8544ds.dts
@@ -57,9 +57,21 @@
compatible = "simple-bus";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x1000>; // CCSRBAR 1M
bus-frequency = <0>; // Filled out by uboot.
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8544-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,8544-memory-controller";
reg = <0x2000 0x1000>;
@@ -274,7 +286,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
compatible = "fsl,mpc8540-pci";
device_type = "pci";
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
@@ -306,7 +317,6 @@
};
pci1: pcie@e0009000 {
- cell-index = <1>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -343,7 +353,6 @@
};
pci2: pcie@e000a000 {
- cell-index = <2>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -380,7 +389,6 @@
};
pci3: pcie@e000b000 {
- cell-index = <3>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
index 804e90353293..475be1433fe1 100644
--- a/arch/powerpc/boot/dts/mpc8548cds.dts
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -60,9 +60,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x1000>; // CCSRBAR
bus-frequency = <0>;
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,8548-memory-controller";
reg = <0x2000 0x1000>;
@@ -328,7 +340,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x4 (PCIX Slot 2) */
@@ -478,7 +489,6 @@
};
pci1: pci@e0009000 {
- cell-index = <1>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
@@ -503,7 +513,6 @@
};
pci2: pcie@e000a000 {
- cell-index = <2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
index 9484f0729b10..065b2f093de2 100644
--- a/arch/powerpc/boot/dts/mpc8555cds.dts
+++ b/arch/powerpc/boot/dts/mpc8555cds.dts
@@ -55,9 +55,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x1000>; // CCSRBAR 1M
bus-frequency = <0>;
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8555-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,8555-memory-controller";
reg = <0x2000 0x1000>;
@@ -272,7 +284,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
interrupt-map = <
@@ -344,7 +355,6 @@
};
pci1: pci@e0009000 {
- cell-index = <1>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
index cc2acf87d02f..a5bb1ec70a5a 100644
--- a/arch/powerpc/boot/dts/mpc8560ads.dts
+++ b/arch/powerpc/boot/dts/mpc8560ads.dts
@@ -55,9 +55,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x200>;
bus-frequency = <330000000>;
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,8540-memory-controller";
reg = <0x2000 0x1000>;
@@ -291,7 +303,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 9d52e3b25047..00c2bbda7013 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -26,6 +26,7 @@
serial1 = &serial1;
pci0 = &pci0;
pci1 = &pci1;
+ rapidio0 = &rio0;
};
cpus {
@@ -62,9 +63,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x1000>;
bus-frequency = <0>;
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8568-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,8568-memory-controller";
reg = <0x2000 0x1000>;
@@ -275,6 +288,22 @@
device_type = "open-pic";
};
+ msi@41600 {
+ compatible = "fsl,mpc8568-msi", "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
par_io@e0100 {
reg = <0xe0100 0x100>;
device_type = "par_io";
@@ -349,6 +378,8 @@
reg = <0xe0080000 0x480>;
brg-frequency = <0>;
bus-frequency = <396000000>;
+ fsl,qe-num-riscs = <2>;
+ fsl,qe-num-snums = <28>;
muram@10000 {
#address-cells = <1>;
@@ -459,7 +490,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x12 AD18 */
@@ -490,7 +520,6 @@
/* PCI Express */
pci1: pcie@e000a000 {
- cell-index = <2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
@@ -526,4 +555,20 @@
0x0 0x800000>;
};
};
+
+ rio0: rapidio@e00c00000 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "fsl,mpc8568-rapidio", "fsl,rapidio-delta";
+ reg = <0xe00c0000 0x20000>;
+ ranges = <0x0 0x0 0xc0000000 0x0 0x20000000>;
+ interrupts = <48 2 /* error */
+ 49 2 /* bell_outb */
+ 50 2 /* bell_inb */
+ 53 2 /* msg1_tx */
+ 54 2 /* msg1_rx */
+ 55 2 /* msg2_tx */
+ 56 2 /* msg2_rx */>;
+ interrupt-parent = <&mpic>;
+ };
};
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts
new file mode 100644
index 000000000000..39c2927503cf
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8569mds.dts
@@ -0,0 +1,583 @@
+/*
+ * MPC8569E MDS Device Tree Source
+ *
+ * Copyright (C) 2009 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.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "MPC8569EMDS";
+ compatible = "fsl,MPC8569EMDS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ pci1 = &pci1;
+ rapidio0 = &rio0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8569@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ localbus@e0005000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8569-elbc", "fsl,elbc", "simple-bus";
+ reg = <0xe0005000 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ ranges = <0x0 0x0 0xfe000000 0x02000000
+ 0x1 0x0 0xf8000000 0x00008000
+ 0x2 0x0 0xf0000000 0x04000000
+ 0x3 0x0 0xfc000000 0x00008000
+ 0x4 0x0 0xf8008000 0x00008000
+ 0x5 0x0 0xf8010000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x02000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ bcsr@1,0 {
+ compatible = "fsl,mpc8569mds-bcsr";
+ reg = <1 0 0x8000>;
+ };
+
+ nand@3,0 {
+ compatible = "fsl,mpc8569-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <3 0 0x8000>;
+ };
+
+ pib@4,0 {
+ compatible = "fsl,mpc8569mds-pib";
+ reg = <4 0 0x8000>;
+ };
+
+ pib@5,0 {
+ compatible = "fsl,mpc8569mds-pib";
+ reg = <5 0 0x8000>;
+ };
+ };
+
+ soc@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "fsl,mpc8569-immr", "simple-bus";
+ ranges = <0x0 0xe0000000 0x100000>;
+ bus-frequency = <0>;
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8569-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,mpc8569-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ };
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,mpc8569-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x80000>; // L2, 512K
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8569-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8569-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8569-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8569-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8569-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ sdhci@2e000 {
+ compatible = "fsl,mpc8569-esdhc", "fsl,esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <72 0x8>;
+ interrupt-parent = <&mpic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
+ status = "disabled";
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+ "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <45 2 58 2>;
+ interrupt-parent = <&mpic>;
+ fsl,num-channels = <4>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0xbfe>;
+ fsl,descriptor-types-mask = <0x3ab0ebf>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi@41600 {
+ compatible = "fsl,mpc8568-msi", "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ global-utilities@e0000 {
+ compatible = "fsl,mpc8569-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+
+ par_io@e0100 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0100 0x100>;
+ ranges = <0x0 0xe0100 0x100>;
+ device_type = "par_io";
+ num-ports = <7>;
+
+ qe_pio_e: gpio-controller@80 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8569-qe-pario-bank",
+ "fsl,mpc8323-qe-pario-bank";
+ reg = <0x80 0x18>;
+ gpio-controller;
+ };
+
+ pio1: ucc_pin@01 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
+ 0x2 0x0b 0x2 0x0 0x1 0x0 /* CLK12*/
+ 0x0 0x0 0x1 0x0 0x3 0x0 /* ENET1_TXD0_SER1_TXD0 */
+ 0x0 0x1 0x1 0x0 0x3 0x0 /* ENET1_TXD1_SER1_TXD1 */
+ 0x0 0x2 0x1 0x0 0x1 0x0 /* ENET1_TXD2_SER1_TXD2 */
+ 0x0 0x3 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
+ 0x0 0x6 0x2 0x0 0x3 0x0 /* ENET1_RXD0_SER1_RXD0 */
+ 0x0 0x7 0x2 0x0 0x1 0x0 /* ENET1_RXD1_SER1_RXD1 */
+ 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
+ 0x0 0x9 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
+ 0x0 0x4 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
+ 0x0 0xc 0x2 0x0 0x3 0x0 /* ENET1_RX_DV_SER1_CTS_B */
+ 0x2 0x8 0x2 0x0 0x1 0x0 /* ENET1_GRXCLK */
+ 0x2 0x14 0x1 0x0 0x2 0x0>; /* ENET1_GTXCLK */
+ };
+
+ pio2: ucc_pin@02 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
+ 0x2 0x10 0x2 0x0 0x3 0x0 /* CLK17 */
+ 0x0 0xe 0x1 0x0 0x2 0x0 /* ENET2_TXD0_SER2_TXD0 */
+ 0x0 0xf 0x1 0x0 0x2 0x0 /* ENET2_TXD1_SER2_TXD1 */
+ 0x0 0x10 0x1 0x0 0x1 0x0 /* ENET2_TXD2_SER2_TXD2 */
+ 0x0 0x11 0x1 0x0 0x1 0x0 /* ENET2_TXD3_SER2_TXD3 */
+ 0x0 0x14 0x2 0x0 0x2 0x0 /* ENET2_RXD0_SER2_RXD0 */
+ 0x0 0x15 0x2 0x0 0x1 0x0 /* ENET2_RXD1_SER2_RXD1 */
+ 0x0 0x16 0x2 0x0 0x1 0x0 /* ENET2_RXD2_SER2_RXD2 */
+ 0x0 0x17 0x2 0x0 0x1 0x0 /* ENET2_RXD3_SER2_RXD3 */
+ 0x0 0x12 0x1 0x0 0x2 0x0 /* ENET2_TX_EN_SER2_RTS_B */
+ 0x0 0x1a 0x2 0x0 0x3 0x0 /* ENET2_RX_DV_SER2_CTS_B */
+ 0x2 0x3 0x2 0x0 0x1 0x0 /* ENET2_GRXCLK */
+ 0x2 0x2 0x1 0x0 0x2 0x0>; /* ENET2_GTXCLK */
+ };
+
+ pio3: ucc_pin@03 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
+ 0x2 0x0b 0x2 0x0 0x1 0x0 /* CLK12*/
+ 0x0 0x1d 0x1 0x0 0x2 0x0 /* ENET3_TXD0_SER3_TXD0 */
+ 0x0 0x1e 0x1 0x0 0x3 0x0 /* ENET3_TXD1_SER3_TXD1 */
+ 0x0 0x1f 0x1 0x0 0x2 0x0 /* ENET3_TXD2_SER3_TXD2 */
+ 0x1 0x0 0x1 0x0 0x3 0x0 /* ENET3_TXD3_SER3_TXD3 */
+ 0x1 0x3 0x2 0x0 0x3 0x0 /* ENET3_RXD0_SER3_RXD0 */
+ 0x1 0x4 0x2 0x0 0x1 0x0 /* ENET3_RXD1_SER3_RXD1 */
+ 0x1 0x5 0x2 0x0 0x2 0x0 /* ENET3_RXD2_SER3_RXD2 */
+ 0x1 0x6 0x2 0x0 0x3 0x0 /* ENET3_RXD3_SER3_RXD3 */
+ 0x1 0x1 0x1 0x0 0x1 0x0 /* ENET3_TX_EN_SER3_RTS_B */
+ 0x1 0x9 0x2 0x0 0x3 0x0 /* ENET3_RX_DV_SER3_CTS_B */
+ 0x2 0x9 0x2 0x0 0x2 0x0 /* ENET3_GRXCLK */
+ 0x2 0x19 0x1 0x0 0x2 0x0>; /* ENET3_GTXCLK */
+ };
+
+ pio4: ucc_pin@04 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
+ 0x2 0x10 0x2 0x0 0x3 0x0 /* CLK17 */
+ 0x1 0xc 0x1 0x0 0x2 0x0 /* ENET4_TXD0_SER4_TXD0 */
+ 0x1 0xd 0x1 0x0 0x2 0x0 /* ENET4_TXD1_SER4_TXD1 */
+ 0x1 0xe 0x1 0x0 0x1 0x0 /* ENET4_TXD2_SER4_TXD2 */
+ 0x1 0xf 0x1 0x0 0x2 0x0 /* ENET4_TXD3_SER4_TXD3 */
+ 0x1 0x12 0x2 0x0 0x2 0x0 /* ENET4_RXD0_SER4_RXD0 */
+ 0x1 0x13 0x2 0x0 0x1 0x0 /* ENET4_RXD1_SER4_RXD1 */
+ 0x1 0x14 0x2 0x0 0x1 0x0 /* ENET4_RXD2_SER4_RXD2 */
+ 0x1 0x15 0x2 0x0 0x2 0x0 /* ENET4_RXD3_SER4_RXD3 */
+ 0x1 0x10 0x1 0x0 0x2 0x0 /* ENET4_TX_EN_SER4_RTS_B */
+ 0x1 0x18 0x2 0x0 0x3 0x0 /* ENET4_RX_DV_SER4_CTS_B */
+ 0x2 0x11 0x2 0x0 0x2 0x0 /* ENET4_GRXCLK */
+ 0x2 0x18 0x1 0x0 0x2 0x0>; /* ENET4_GTXCLK */
+ };
+ };
+ };
+
+ qe@e0080000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "qe";
+ compatible = "fsl,qe";
+ ranges = <0x0 0xe0080000 0x40000>;
+ reg = <0xe0080000 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+ fsl,qe-num-riscs = <4>;
+ fsl,qe-num-snums = <46>;
+
+ qeic: interrupt-controller@80 {
+ interrupt-controller;
+ compatible = "fsl,qe-ic";
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x80 0x80>;
+ interrupts = <46 2 46 2>; //high:30 low:30
+ interrupt-parent = <&mpic>;
+ };
+
+ spi@4c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc8569-qe-spi", "fsl,spi";
+ reg = <0x4c0 0x40>;
+ cell-index = <0>;
+ interrupts = <2>;
+ interrupt-parent = <&qeic>;
+ gpios = <&qe_pio_e 30 0>;
+ mode = "cpu-qe";
+
+ serial-flash@0 {
+ compatible = "stm,m25p40";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+ };
+ };
+
+ spi@500 {
+ cell-index = <1>;
+ compatible = "fsl,spi";
+ reg = <0x500 0x40>;
+ interrupts = <1>;
+ interrupt-parent = <&qeic>;
+ mode = "cpu";
+ };
+
+ enet0: ucc@2000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ cell-index = <1>;
+ reg = <0x2000 0x200>;
+ interrupts = <32>;
+ interrupt-parent = <&qeic>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk12";
+ pio-handle = <&pio1>;
+ phy-handle = <&qe_phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@2120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2120 0x18>;
+ compatible = "fsl,ucc-mdio";
+
+ qe_phy0: ethernet-phy@07 {
+ interrupt-parent = <&mpic>;
+ interrupts = <1 1>;
+ reg = <0x7>;
+ device_type = "ethernet-phy";
+ };
+ qe_phy1: ethernet-phy@01 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+ qe_phy2: ethernet-phy@02 {
+ interrupt-parent = <&mpic>;
+ interrupts = <3 1>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+ qe_phy3: ethernet-phy@03 {
+ interrupt-parent = <&mpic>;
+ interrupts = <4 1>;
+ reg = <0x3>;
+ device_type = "ethernet-phy";
+ };
+ };
+
+ enet2: ucc@2200 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ cell-index = <3>;
+ reg = <0x2200 0x200>;
+ interrupts = <34>;
+ interrupt-parent = <&qeic>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk12";
+ pio-handle = <&pio3>;
+ phy-handle = <&qe_phy2>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ enet1: ucc@3000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ cell-index = <2>;
+ reg = <0x3000 0x200>;
+ interrupts = <33>;
+ interrupt-parent = <&qeic>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk17";
+ pio-handle = <&pio2>;
+ phy-handle = <&qe_phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ enet3: ucc@3200 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ cell-index = <4>;
+ reg = <0x3200 0x200>;
+ interrupts = <35>;
+ interrupt-parent = <&qeic>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk17";
+ pio-handle = <&pio4>;
+ phy-handle = <&qe_phy3>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ muram@10000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,qe-muram", "fsl,cpm-muram";
+ ranges = <0x0 0x10000 0x20000>;
+
+ data-only@0 {
+ compatible = "fsl,qe-muram-data",
+ "fsl,cpm-muram-data";
+ reg = <0x0 0x20000>;
+ };
+ };
+
+ };
+
+ /* PCI Express */
+ pci1: pcie@e000a000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xe000a000 0x1000>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x0 (PEX) */
+ 00000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 00000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 00000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 00000 0x0 0x0 0x4 &mpic 0x3 0x1>;
+
+ interrupt-parent = <&mpic>;
+ interrupts = <26 2>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0xe2800000 0x0 0x00800000>;
+ clock-frequency = <33333333>;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x10000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x800000>;
+ };
+ };
+
+ rio0: rapidio@e00c00000 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "fsl,mpc8569-rapidio", "fsl,rapidio-delta";
+ reg = <0xe00c0000 0x20000>;
+ ranges = <0x0 0x0 0xc0000000 0x0 0x20000000>;
+ interrupts = <48 2 /* error */
+ 49 2 /* bell_outb */
+ 50 2 /* bell_inb */
+ 53 2 /* msg1_tx */
+ 54 2 /* msg1_rx */
+ 55 2 /* msg2_tx */
+ 56 2 /* msg2_rx */>;
+ interrupt-parent = <&mpic>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts
index 6e79a4169088..cafc1285c140 100644
--- a/arch/powerpc/boot/dts/mpc8572ds.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds.dts
@@ -182,9 +182,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0 0xffe00000 0x100000>;
- reg = <0 0xffe00000 0 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed
bus-frequency = <0>; // Filled out by uboot.
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <12>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8572-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8572-memory-controller";
reg = <0x2000 0x1000>;
@@ -514,7 +526,6 @@
};
pci0: pcie@ffe08000 {
- cell-index = <0>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -724,7 +735,6 @@
};
pci1: pcie@ffe09000 {
- cell-index = <1>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -761,7 +771,6 @@
};
pci2: pcie@ffe0a000 {
- cell-index = <2>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8572ds_36b.dts b/arch/powerpc/boot/dts/mpc8572ds_36b.dts
index dbd81a764742..f6365db3b97d 100644
--- a/arch/powerpc/boot/dts/mpc8572ds_36b.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds_36b.dts
@@ -182,9 +182,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xf 0xffe00000 0x100000>;
- reg = <0xf 0xffe00000 0 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed
bus-frequency = <0>; // Filled out by uboot.
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <12>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8572-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8572-memory-controller";
reg = <0x2000 0x1000>;
@@ -514,7 +526,6 @@
};
pci0: pcie@fffe08000 {
- cell-index = <0>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -522,7 +533,7 @@
#address-cells = <3>;
reg = <0xf 0xffe08000 0 0x1000>;
bus-range = <0 255>;
- ranges = <0x2000000 0x0 0xc0000000 0xc 0x00000000 0x0 0x20000000
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x00010000>;
clock-frequency = <33333333>;
interrupt-parent = <&mpic>;
@@ -649,8 +660,8 @@
#size-cells = <2>;
#address-cells = <3>;
device_type = "pci";
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
0x0 0x20000000
0x1000000 0x0 0x0
@@ -660,8 +671,8 @@
reg = <0x0 0x0 0x0 0x0 0x0>;
#size-cells = <2>;
#address-cells = <3>;
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
0x0 0x20000000
0x1000000 0x0 0x0
@@ -724,7 +735,6 @@
};
pci1: pcie@fffe09000 {
- cell-index = <1>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -732,7 +742,7 @@
#address-cells = <3>;
reg = <0xf 0xffe09000 0 0x1000>;
bus-range = <0 255>;
- ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x00010000>;
clock-frequency = <33333333>;
interrupt-parent = <&mpic>;
@@ -750,8 +760,8 @@
#size-cells = <2>;
#address-cells = <3>;
device_type = "pci";
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
0x0 0x20000000
0x1000000 0x0 0x0
@@ -761,7 +771,6 @@
};
pci2: pcie@fffe0a000 {
- cell-index = <2>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -769,7 +778,7 @@
#address-cells = <3>;
reg = <0xf 0xffe0a000 0 0x1000>;
bus-range = <0 255>;
- ranges = <0x2000000 0x0 0xc0000000 0xc 0x40000000 0x0 0x20000000
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x40000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x00010000>;
clock-frequency = <33333333>;
interrupt-parent = <&mpic>;
@@ -787,8 +796,8 @@
#size-cells = <2>;
#address-cells = <3>;
device_type = "pci";
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
0x0 0x20000000
0x1000000 0x0 0x0
diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
index 2bc0c7189653..5bd1011fde96 100644
--- a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
@@ -59,9 +59,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xffe00000 0x100000>;
- reg = <0xffe00000 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed
bus-frequency = <0>; // Filled out by uboot.
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <12>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8572-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8572-memory-controller";
reg = <0x2000 0x1000>;
@@ -238,7 +250,6 @@
};
pci0: pcie@ffe08000 {
- cell-index = <0>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -448,7 +459,6 @@
};
pci1: pcie@ffe09000 {
- cell-index = <1>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
index 159cb3a875f0..0efc3456e297 100644
--- a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
@@ -58,7 +58,6 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xffe00000 0x100000>;
- reg = <0xffe00000 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed
bus-frequency = <0>; // Filled out by uboot.
L2: l2-cache-controller@20000 {
@@ -196,7 +195,6 @@
};
pci2: pcie@ffe0a000 {
- cell-index = <2>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
index 1bd3ebe11437..cfc2c60d1f5f 100644
--- a/arch/powerpc/boot/dts/mpc8610_hpcd.dts
+++ b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
@@ -112,9 +112,21 @@
device_type = "soc";
compatible = "fsl,mpc8610-immr", "simple-bus";
ranges = <0x0 0xe0000000 0x00100000>;
- reg = <0xe0000000 0x1000>;
bus-frequency = <0>;
+ mcm-law@0 {
+ compatible = "fsl,mcm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ mcm@1000 {
+ compatible = "fsl,mpc8610-mcm", "fsl,mcm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
i2c@3000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -316,7 +328,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
compatible = "fsl,mpc8610-pci";
device_type = "pci";
#interrupt-cells = <1>;
@@ -346,7 +357,6 @@
};
pci1: pcie@e000a000 {
- cell-index = <1>;
compatible = "fsl,mpc8641-pcie";
device_type = "pci";
#interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index d72beb192460..848320e4d3c4 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -114,9 +114,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x00000000 0xffe00000 0x00100000>;
- reg = <0xffe00000 0x00001000>; // CCSRBAR
bus-frequency = <0>;
+ mcm-law@0 {
+ compatible = "fsl,mcm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ mcm@1000 {
+ compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
i2c@3000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -357,7 +369,6 @@
};
pci0: pcie@ffe08000 {
- cell-index = <0>;
compatible = "fsl,mpc8641-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -566,7 +577,6 @@
};
pci1: pcie@ffe09000 {
- cell-index = <1>;
compatible = "fsl,mpc8641-pcie";
device_type = "pci";
#interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts b/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts
new file mode 100644
index 000000000000..8be8e701e1d3
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts
@@ -0,0 +1,609 @@
+/*
+ * MPC8641 HPCN Device Tree Source
+ *
+ * Copyright 2008-2009 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.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "MPC8641HPCN";
+ compatible = "fsl,mpc8641hpcn";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8641@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <32768>; // L1, 32K
+ i-cache-size = <32768>; // L1, 32K
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ bus-frequency = <0>; // From uboot
+ clock-frequency = <0>; // From uboot
+ };
+ PowerPC,8641@1 {
+ device_type = "cpu";
+ reg = <1>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <32768>; // L1, 32K
+ i-cache-size = <32768>; // L1, 32K
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ bus-frequency = <0>; // From uboot
+ clock-frequency = <0>; // From uboot
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x00000000 0x0 0x40000000>; // 1G at 0x0
+ };
+
+ localbus@fffe05000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8641-localbus", "simple-bus";
+ reg = <0x0f 0xffe05000 0x0 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ ranges = <0 0 0xf 0xef800000 0x00800000
+ 2 0 0xf 0xffdf8000 0x00008000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x00800000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "kernel";
+ reg = <0x00000000 0x00300000>;
+ };
+ partition@300000 {
+ label = "firmware b";
+ reg = <0x00300000 0x00100000>;
+ read-only;
+ };
+ partition@400000 {
+ label = "fs";
+ reg = <0x00400000 0x00300000>;
+ };
+ partition@700000 {
+ label = "firmware a";
+ reg = <0x00700000 0x00100000>;
+ read-only;
+ };
+ };
+ };
+
+ soc8641@fffe00000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+ ranges = <0x00000000 0x0f 0xffe00000 0x00100000>;
+ bus-frequency = <0>;
+
+ mcm-law@0 {
+ compatible = "fsl,mcm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ mcm@1000 {
+ compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <35 2 36 2 40 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <2>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <31 2 32 2 33 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet3: ethernet@27000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <3>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x27000 0x1000>;
+ ranges = <0x0 0x27000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <37 2 38 2 39 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy3>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <28 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ global-utilities@e0000 {
+ compatible = "fsl,mpc8641-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+ };
+
+ pci0: pcie@fffe08000 {
+ cell-index = <0>;
+ compatible = "fsl,mpc8641-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0x0f 0xffe08000 0x0 0x1000>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x02000000 0x0 0xe0000000 0x0c 0x00000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0x0f 0xffc00000 0x0 0x00010000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <24 2>;
+ interrupt-map-mask = <0xff00 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x11 func 0 - PCI slot 1 */
+ 0x8800 0 0 1 &mpic 2 1
+ 0x8800 0 0 2 &mpic 3 1
+ 0x8800 0 0 3 &mpic 4 1
+ 0x8800 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 1 - PCI slot 1 */
+ 0x8900 0 0 1 &mpic 2 1
+ 0x8900 0 0 2 &mpic 3 1
+ 0x8900 0 0 3 &mpic 4 1
+ 0x8900 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 2 - PCI slot 1 */
+ 0x8a00 0 0 1 &mpic 2 1
+ 0x8a00 0 0 2 &mpic 3 1
+ 0x8a00 0 0 3 &mpic 4 1
+ 0x8a00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 3 - PCI slot 1 */
+ 0x8b00 0 0 1 &mpic 2 1
+ 0x8b00 0 0 2 &mpic 3 1
+ 0x8b00 0 0 3 &mpic 4 1
+ 0x8b00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 4 - PCI slot 1 */
+ 0x8c00 0 0 1 &mpic 2 1
+ 0x8c00 0 0 2 &mpic 3 1
+ 0x8c00 0 0 3 &mpic 4 1
+ 0x8c00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 5 - PCI slot 1 */
+ 0x8d00 0 0 1 &mpic 2 1
+ 0x8d00 0 0 2 &mpic 3 1
+ 0x8d00 0 0 3 &mpic 4 1
+ 0x8d00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 6 - PCI slot 1 */
+ 0x8e00 0 0 1 &mpic 2 1
+ 0x8e00 0 0 2 &mpic 3 1
+ 0x8e00 0 0 3 &mpic 4 1
+ 0x8e00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 7 - PCI slot 1 */
+ 0x8f00 0 0 1 &mpic 2 1
+ 0x8f00 0 0 2 &mpic 3 1
+ 0x8f00 0 0 3 &mpic 4 1
+ 0x8f00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x12 func 0 - PCI slot 2 */
+ 0x9000 0 0 1 &mpic 3 1
+ 0x9000 0 0 2 &mpic 4 1
+ 0x9000 0 0 3 &mpic 1 1
+ 0x9000 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 1 - PCI slot 2 */
+ 0x9100 0 0 1 &mpic 3 1
+ 0x9100 0 0 2 &mpic 4 1
+ 0x9100 0 0 3 &mpic 1 1
+ 0x9100 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 2 - PCI slot 2 */
+ 0x9200 0 0 1 &mpic 3 1
+ 0x9200 0 0 2 &mpic 4 1
+ 0x9200 0 0 3 &mpic 1 1
+ 0x9200 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 3 - PCI slot 2 */
+ 0x9300 0 0 1 &mpic 3 1
+ 0x9300 0 0 2 &mpic 4 1
+ 0x9300 0 0 3 &mpic 1 1
+ 0x9300 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 4 - PCI slot 2 */
+ 0x9400 0 0 1 &mpic 3 1
+ 0x9400 0 0 2 &mpic 4 1
+ 0x9400 0 0 3 &mpic 1 1
+ 0x9400 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 5 - PCI slot 2 */
+ 0x9500 0 0 1 &mpic 3 1
+ 0x9500 0 0 2 &mpic 4 1
+ 0x9500 0 0 3 &mpic 1 1
+ 0x9500 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 6 - PCI slot 2 */
+ 0x9600 0 0 1 &mpic 3 1
+ 0x9600 0 0 2 &mpic 4 1
+ 0x9600 0 0 3 &mpic 1 1
+ 0x9600 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 7 - PCI slot 2 */
+ 0x9700 0 0 1 &mpic 3 1
+ 0x9700 0 0 2 &mpic 4 1
+ 0x9700 0 0 3 &mpic 1 1
+ 0x9700 0 0 4 &mpic 2 1
+
+ // IDSEL 0x1c USB
+ 0xe000 0 0 1 &i8259 12 2
+ 0xe100 0 0 2 &i8259 9 2
+ 0xe200 0 0 3 &i8259 10 2
+ 0xe300 0 0 4 &i8259 11 2
+
+ // IDSEL 0x1d Audio
+ 0xe800 0 0 1 &i8259 6 2
+
+ // IDSEL 0x1e Legacy
+ 0xf000 0 0 1 &i8259 7 2
+ 0xf100 0 0 1 &i8259 7 2
+
+ // IDSEL 0x1f IDE/SATA
+ 0xf800 0 0 1 &i8259 14 2
+ 0xf900 0 0 1 &i8259 5 2
+ >;
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x02000000 0x0 0xe0000000
+ 0x02000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00010000>;
+ uli1575@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ ranges = <0x02000000 0x0 0xe0000000
+ 0x02000000 0x0 0xe0000000
+ 0x0 0x20000000
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00010000>;
+ isa@1e {
+ device_type = "isa";
+ #interrupt-cells = <2>;
+ #size-cells = <1>;
+ #address-cells = <2>;
+ reg = <0xf000 0 0 0 0>;
+ ranges = <1 0 0x01000000 0 0
+ 0x00001000>;
+ interrupt-parent = <&i8259>;
+
+ i8259: interrupt-controller@20 {
+ reg = <1 0x20 2
+ 1 0xa0 2
+ 1 0x4d0 2>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "chrp,iic";
+ interrupts = <9 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ i8042@60 {
+ #size-cells = <0>;
+ #address-cells = <1>;
+ reg = <1 0x60 1 1 0x64 1>;
+ interrupts = <1 3 12 3>;
+ interrupt-parent =
+ <&i8259>;
+
+ keyboard@0 {
+ reg = <0>;
+ compatible = "pnpPNP,303";
+ };
+
+ mouse@1 {
+ reg = <1>;
+ compatible = "pnpPNP,f03";
+ };
+ };
+
+ rtc@70 {
+ compatible =
+ "pnpPNP,b00";
+ reg = <1 0x70 2>;
+ };
+
+ gpio@400 {
+ reg = <1 0x400 0x80>;
+ };
+ };
+ };
+ };
+
+ };
+
+ pci1: pcie@fffe09000 {
+ cell-index = <1>;
+ compatible = "fsl,mpc8641-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0x0f 0xffe09000 0x0 0x1000>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x02000000 0x0 0xe0000000 0x0c 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0x0f 0xffc10000 0x0 0x00010000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <25 2>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0x0000 0 0 1 &mpic 4 1
+ 0x0000 0 0 2 &mpic 5 1
+ 0x0000 0 0 3 &mpic 6 1
+ 0x0000 0 0 4 &mpic 7 1
+ >;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x02000000 0x0 0xe0000000
+ 0x02000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00010000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/sbc8349.dts b/arch/powerpc/boot/dts/sbc8349.dts
index a36dbbc48694..5fb6f6684b0e 100644
--- a/arch/powerpc/boot/dts/sbc8349.dts
+++ b/arch/powerpc/boot/dts/sbc8349.dts
@@ -278,7 +278,6 @@
};
pci0: pci@e0008500 {
- cell-index = <1>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/sbc8548.dts b/arch/powerpc/boot/dts/sbc8548.dts
index b1f1416ac998..9eefe00ed253 100644
--- a/arch/powerpc/boot/dts/sbc8548.dts
+++ b/arch/powerpc/boot/dts/sbc8548.dts
@@ -151,10 +151,22 @@
#size-cells = <1>;
device_type = "soc";
ranges = <0x00000000 0xe0000000 0x00100000>;
- reg = <0xe0000000 0x00001000>; // CCSRBAR
bus-frequency = <0>;
compatible = "simple-bus";
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8548-memory-controller";
reg = <0x2000 0x1000>;
@@ -350,7 +362,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x01 (PCI-X slot) @66MHz */
@@ -380,7 +391,6 @@
};
pci2: pcie@e000a000 {
- cell-index = <2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/sbc8560.dts b/arch/powerpc/boot/dts/sbc8560.dts
index c4564b81e473..239d57a55cf4 100644
--- a/arch/powerpc/boot/dts/sbc8560.dts
+++ b/arch/powerpc/boot/dts/sbc8560.dts
@@ -57,9 +57,21 @@
#size-cells = <1>;
device_type = "soc";
ranges = <0x0 0xff700000 0x00100000>;
- reg = <0xff700000 0x00100000>;
clock-frequency = <0>;
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8560-memory-controller";
reg = <0x2000 0x1000>;
@@ -296,7 +308,6 @@
};
pci0: pci@ff708000 {
- cell-index = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
diff --git a/arch/powerpc/boot/dts/sbc8641d.dts b/arch/powerpc/boot/dts/sbc8641d.dts
index e3e914e78caa..ee5538feb455 100644
--- a/arch/powerpc/boot/dts/sbc8641d.dts
+++ b/arch/powerpc/boot/dts/sbc8641d.dts
@@ -126,9 +126,21 @@
device_type = "soc";
compatible = "simple-bus";
ranges = <0x00000000 0xf8000000 0x00100000>;
- reg = <0xf8000000 0x00001000>; // CCSRBAR
bus-frequency = <0>;
+ mcm-law@0 {
+ compatible = "fsl,mcm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ mcm@1000 {
+ compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
i2c@3000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -371,7 +383,6 @@
};
pci0: pcie@f8008000 {
- cell-index = <0>;
compatible = "fsl,mpc8641-pcie";
device_type = "pci";
#interrupt-cells = <1>;
@@ -410,7 +421,6 @@
};
pci1: pcie@f8009000 {
- cell-index = <1>;
compatible = "fsl,mpc8641-pcie";
device_type = "pci";
#interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/socrates.dts b/arch/powerpc/boot/dts/socrates.dts
index 7a6ae75a1e57..feb4ef6bd144 100644
--- a/arch/powerpc/boot/dts/socrates.dts
+++ b/arch/powerpc/boot/dts/socrates.dts
@@ -55,10 +55,22 @@
device_type = "soc";
ranges = <0x00000000 0xe0000000 0x00100000>;
- reg = <0xe0000000 0x00001000>; // CCSRBAR 1M
bus-frequency = <0>; // Filled in by U-Boot
compatible = "fsl,mpc8544-immr", "simple-bus";
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8544-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8544-memory-controller";
reg = <0x2000 0x1000>;
@@ -314,7 +326,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
diff --git a/arch/powerpc/boot/dts/stx_gp3_8560.dts b/arch/powerpc/boot/dts/stx_gp3_8560.dts
index ea6b15152de3..b670d03fbcd9 100644
--- a/arch/powerpc/boot/dts/stx_gp3_8560.dts
+++ b/arch/powerpc/boot/dts/stx_gp3_8560.dts
@@ -52,10 +52,22 @@
#size-cells = <1>;
device_type = "soc";
ranges = <0 0xfdf00000 0x100000>;
- reg = <0xfdf00000 0x1000>;
bus-frequency = <0>;
compatible = "fsl,mpc8560-immr", "simple-bus";
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
@@ -251,7 +263,6 @@
};
pci0: pci@fdf08000 {
- cell-index = <0>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
diff --git a/arch/powerpc/boot/dts/tqm8540.dts b/arch/powerpc/boot/dts/tqm8540.dts
index b6f1fc6eb960..71347537b83e 100644
--- a/arch/powerpc/boot/dts/tqm8540.dts
+++ b/arch/powerpc/boot/dts/tqm8540.dts
@@ -54,10 +54,22 @@
#size-cells = <1>;
device_type = "soc";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x200>;
bus-frequency = <0>;
compatible = "fsl,mpc8540-immr", "simple-bus";
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8540-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
@@ -266,7 +278,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
diff --git a/arch/powerpc/boot/dts/tqm8541.dts b/arch/powerpc/boot/dts/tqm8541.dts
index fa6a3d54a8a5..b30f63753d41 100644
--- a/arch/powerpc/boot/dts/tqm8541.dts
+++ b/arch/powerpc/boot/dts/tqm8541.dts
@@ -53,10 +53,22 @@
#size-cells = <1>;
device_type = "soc";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x200>;
bus-frequency = <0>;
compatible = "fsl,mpc8541-immr", "simple-bus";
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8541-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
@@ -288,7 +300,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
diff --git a/arch/powerpc/boot/dts/tqm8548-bigflash.dts b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
index 00f7ed7a2455..61f25e15fd66 100644
--- a/arch/powerpc/boot/dts/tqm8548-bigflash.dts
+++ b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
@@ -55,10 +55,22 @@
#size-cells = <1>;
device_type = "soc";
ranges = <0x0 0xa0000000 0x100000>;
- reg = <0xa0000000 0x1000>; // CCSRBAR
bus-frequency = <0>;
compatible = "fsl,mpc8548-immr", "simple-bus";
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8548-memory-controller";
reg = <0x2000 0x1000>;
@@ -419,7 +431,6 @@
};
pci0: pci@a0008000 {
- cell-index = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
@@ -441,7 +452,6 @@
};
pci1: pcie@a000a000 {
- cell-index = <2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x0 (PEX) */
diff --git a/arch/powerpc/boot/dts/tqm8548.dts b/arch/powerpc/boot/dts/tqm8548.dts
index 673e4a778ac8..025759c7c955 100644
--- a/arch/powerpc/boot/dts/tqm8548.dts
+++ b/arch/powerpc/boot/dts/tqm8548.dts
@@ -55,10 +55,22 @@
#size-cells = <1>;
device_type = "soc";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x1000>; // CCSRBAR
bus-frequency = <0>;
compatible = "fsl,mpc8548-immr", "simple-bus";
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8548-memory-controller";
reg = <0x2000 0x1000>;
@@ -419,7 +431,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
@@ -441,7 +452,6 @@
};
pci1: pcie@e000a000 {
- cell-index = <2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x0 (PEX) */
diff --git a/arch/powerpc/boot/dts/tqm8555.dts b/arch/powerpc/boot/dts/tqm8555.dts
index 6a99f1eef7ad..95e287381836 100644
--- a/arch/powerpc/boot/dts/tqm8555.dts
+++ b/arch/powerpc/boot/dts/tqm8555.dts
@@ -53,10 +53,22 @@
#size-cells = <1>;
device_type = "soc";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x200>;
bus-frequency = <0>;
compatible = "fsl,mpc8555-immr", "simple-bus";
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8555-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
@@ -288,7 +300,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
diff --git a/arch/powerpc/boot/dts/tqm8560.dts b/arch/powerpc/boot/dts/tqm8560.dts
index b6c2d71defd3..ff70580a8f4c 100644
--- a/arch/powerpc/boot/dts/tqm8560.dts
+++ b/arch/powerpc/boot/dts/tqm8560.dts
@@ -55,10 +55,22 @@
#size-cells = <1>;
device_type = "soc";
ranges = <0x0 0xe0000000 0x100000>;
- reg = <0xe0000000 0x200>;
bus-frequency = <0>;
compatible = "fsl,mpc8560-immr", "simple-bus";
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
memory-controller@2000 {
compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
@@ -359,7 +371,6 @@
};
pci0: pci@e0008000 {
- cell-index = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig
index a32ec8d323a0..173a5bb77ca1 100644
--- a/arch/powerpc/configs/40x/acadia_defconfig
+++ b/arch/powerpc/configs/40x/acadia_defconfig
@@ -252,7 +252,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/40x/ep405_defconfig b/arch/powerpc/configs/40x/ep405_defconfig
index 4e9d85f39da0..e9b8495cde0c 100644
--- a/arch/powerpc/configs/40x/ep405_defconfig
+++ b/arch/powerpc/configs/40x/ep405_defconfig
@@ -254,7 +254,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig
index 9917a09bad3a..cc3e7b785ac4 100644
--- a/arch/powerpc/configs/40x/kilauea_defconfig
+++ b/arch/powerpc/configs/40x/kilauea_defconfig
@@ -252,7 +252,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/40x/makalu_defconfig b/arch/powerpc/configs/40x/makalu_defconfig
index 58bf2ac2e0dd..50c7cc174568 100644
--- a/arch/powerpc/configs/40x/makalu_defconfig
+++ b/arch/powerpc/configs/40x/makalu_defconfig
@@ -252,7 +252,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/40x/virtex_defconfig b/arch/powerpc/configs/40x/virtex_defconfig
index f5698f962e58..416e79ac0711 100644
--- a/arch/powerpc/configs/40x/virtex_defconfig
+++ b/arch/powerpc/configs/40x/virtex_defconfig
@@ -258,7 +258,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/44x/arches_defconfig b/arch/powerpc/configs/44x/arches_defconfig
index 1d72b0ac3f25..f7fd32c09424 100644
--- a/arch/powerpc/configs/44x/arches_defconfig
+++ b/arch/powerpc/configs/44x/arches_defconfig
@@ -258,7 +258,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/44x/bamboo_defconfig b/arch/powerpc/configs/44x/bamboo_defconfig
index 959bdc43a491..e57f1e4c1795 100644
--- a/arch/powerpc/configs/44x/bamboo_defconfig
+++ b/arch/powerpc/configs/44x/bamboo_defconfig
@@ -262,7 +262,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/44x/canyonlands_defconfig b/arch/powerpc/configs/44x/canyonlands_defconfig
index f9a08ee49b96..5e85412eb9fa 100644
--- a/arch/powerpc/configs/44x/canyonlands_defconfig
+++ b/arch/powerpc/configs/44x/canyonlands_defconfig
@@ -262,7 +262,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
@@ -716,7 +716,7 @@ CONFIG_SSB_POSSIBLE=y
#
# Multimedia drivers
#
-CONFIG_DAB=y
+# CONFIG_DAB is not set
# CONFIG_USB_DABUSB is not set
#
@@ -725,7 +725,7 @@ CONFIG_DAB=y
# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
diff --git a/arch/powerpc/configs/44x/ebony_defconfig b/arch/powerpc/configs/44x/ebony_defconfig
index be64aa644d15..b652f7dcab5a 100644
--- a/arch/powerpc/configs/44x/ebony_defconfig
+++ b/arch/powerpc/configs/44x/ebony_defconfig
@@ -261,7 +261,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/44x/katmai_defconfig b/arch/powerpc/configs/44x/katmai_defconfig
index f67250b24ec5..c23a4ef13e45 100644
--- a/arch/powerpc/configs/44x/katmai_defconfig
+++ b/arch/powerpc/configs/44x/katmai_defconfig
@@ -256,7 +256,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/44x/rainier_defconfig b/arch/powerpc/configs/44x/rainier_defconfig
index 9348c12bd7a6..b25fad1343dc 100644
--- a/arch/powerpc/configs/44x/rainier_defconfig
+++ b/arch/powerpc/configs/44x/rainier_defconfig
@@ -260,7 +260,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/44x/redwood_defconfig b/arch/powerpc/configs/44x/redwood_defconfig
index e665433762ba..ed31d4f17b5a 100644
--- a/arch/powerpc/configs/44x/redwood_defconfig
+++ b/arch/powerpc/configs/44x/redwood_defconfig
@@ -265,7 +265,7 @@ CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/44x/sam440ep_defconfig b/arch/powerpc/configs/44x/sam440ep_defconfig
index 70d5c3fa3283..e14e89a5e06b 100644
--- a/arch/powerpc/configs/44x/sam440ep_defconfig
+++ b/arch/powerpc/configs/44x/sam440ep_defconfig
@@ -262,7 +262,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
diff --git a/arch/powerpc/configs/44x/sequoia_defconfig b/arch/powerpc/configs/44x/sequoia_defconfig
index a921fe3c3711..cb98da046d3d 100644
--- a/arch/powerpc/configs/44x/sequoia_defconfig
+++ b/arch/powerpc/configs/44x/sequoia_defconfig
@@ -262,7 +262,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/44x/taishan_defconfig b/arch/powerpc/configs/44x/taishan_defconfig
index 826700872d26..ef32cc4f82eb 100644
--- a/arch/powerpc/configs/44x/taishan_defconfig
+++ b/arch/powerpc/configs/44x/taishan_defconfig
@@ -260,7 +260,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/44x/virtex5_defconfig b/arch/powerpc/configs/44x/virtex5_defconfig
index 1bf0a63614b1..2518b8568c70 100644
--- a/arch/powerpc/configs/44x/virtex5_defconfig
+++ b/arch/powerpc/configs/44x/virtex5_defconfig
@@ -263,7 +263,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index 7d044dfd9236..12dc7c409616 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -1808,7 +1808,7 @@ CONFIG_PCF8575=m
CONFIG_SENSORS_PCA9539=m
CONFIG_SENSORS_PCF8591=m
# CONFIG_TPS65010 is not set
-CONFIG_SENSORS_MAX6875=m
+CONFIG_EEPROM_MAX6875=m
CONFIG_SENSORS_TSL2550=m
CONFIG_MCU_MPC8349EMITX=m
# CONFIG_I2C_DEBUG_CORE is not set
diff --git a/arch/powerpc/include/asm/cpm1.h b/arch/powerpc/include/asm/cpm1.h
index 2ff798744c1d..7685ffde8821 100644
--- a/arch/powerpc/include/asm/cpm1.h
+++ b/arch/powerpc/include/asm/cpm1.h
@@ -598,8 +598,6 @@ typedef struct risc_timer_pram {
#define CICR_IEN ((uint)0x00000080) /* Int. enable */
#define CICR_SPS ((uint)0x00000001) /* SCC Spread */
-#define IMAP_ADDR (get_immrbase())
-
#define CPM_PIN_INPUT 0
#define CPM_PIN_OUTPUT 1
#define CPM_PIN_PRIMARY 0
diff --git a/arch/powerpc/include/asm/cpm2.h b/arch/powerpc/include/asm/cpm2.h
index 0f5e8ff59a85..990ff191da8b 100644
--- a/arch/powerpc/include/asm/cpm2.h
+++ b/arch/powerpc/include/asm/cpm2.h
@@ -14,10 +14,6 @@
#include <asm/cpm.h>
#include <sysdev/fsl_soc.h>
-#ifdef CONFIG_PPC_85xx
-#define CPM_MAP_ADDR (get_immrbase() + 0x80000)
-#endif
-
/* CPM Command register.
*/
#define CPM_CR_RST ((uint)0x80000000)
diff --git a/arch/powerpc/include/asm/mpc86xx.h b/arch/powerpc/include/asm/mpc86xx.h
deleted file mode 100644
index 15f650f987e7..000000000000
--- a/arch/powerpc/include/asm/mpc86xx.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * MPC86xx definitions
- *
- * Author: Jeff Brown
- *
- * Copyright 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 as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifdef __KERNEL__
-#ifndef __ASM_POWERPC_MPC86xx_H__
-#define __ASM_POWERPC_MPC86xx_H__
-
-#include <asm/mmu.h>
-
-#ifdef CONFIG_PPC_86xx
-
-#define CPU0_BOOT_RELEASE 0x01000000
-#define CPU1_BOOT_RELEASE 0x02000000
-#define CPU_ALL_RELEASED (CPU0_BOOT_RELEASE | CPU1_BOOT_RELEASE)
-#define MCM_PORT_CONFIG_OFFSET 0x1010
-
-/* Offset from CCSRBAR */
-#define MPC86xx_MCM_OFFSET (0x00000)
-#define MPC86xx_MCM_SIZE (0x02000)
-
-#endif /* CONFIG_PPC_86xx */
-#endif /* __ASM_POWERPC_MPC86xx_H__ */
-#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 84007afabdb5..9861258f6a4c 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -140,10 +140,12 @@ struct pci_controller {
struct resource io_resource;
struct resource mem_resources[3];
int global_number; /* PCI domain number */
+
+ resource_size_t dma_window_base_cur;
+ resource_size_t dma_window_size;
+
#ifdef CONFIG_PPC64
unsigned long buid;
- unsigned long dma_window_base_cur;
- unsigned long dma_window_size;
void *private_data;
#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h
index 2701753d9937..e0faf332c9c9 100644
--- a/arch/powerpc/include/asm/qe.h
+++ b/arch/powerpc/include/asm/qe.h
@@ -22,7 +22,7 @@
#include <asm/cpm.h>
#include <asm/immap_qe.h>
-#define QE_NUM_OF_SNUM 28
+#define QE_NUM_OF_SNUM 256 /* There are 256 serial number in QE */
#define QE_NUM_OF_BRGS 16
#define QE_NUM_OF_PORTS 1024
@@ -152,6 +152,9 @@ unsigned int qe_get_brg_clk(void);
int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
int qe_get_snum(void);
void qe_put_snum(u8 snum);
+unsigned int qe_get_num_of_risc(void);
+unsigned int qe_get_num_of_snums(void);
+
/* we actually use cpm_muram implementation, define this for convenience */
#define qe_muram_init cpm_muram_init
#define qe_muram_alloc cpm_muram_alloc
@@ -231,12 +234,16 @@ struct qe_bd {
#define QE_ALIGNMENT_OF_PRAM 64
/* RISC allocation */
-enum qe_risc_allocation {
- QE_RISC_ALLOCATION_RISC1 = 1, /* RISC 1 */
- QE_RISC_ALLOCATION_RISC2 = 2, /* RISC 2 */
- QE_RISC_ALLOCATION_RISC1_AND_RISC2 = 3 /* Dynamically choose
- RISC 1 or RISC 2 */
-};
+#define QE_RISC_ALLOCATION_RISC1 0x1 /* RISC 1 */
+#define QE_RISC_ALLOCATION_RISC2 0x2 /* RISC 2 */
+#define QE_RISC_ALLOCATION_RISC3 0x4 /* RISC 3 */
+#define QE_RISC_ALLOCATION_RISC4 0x8 /* RISC 4 */
+#define QE_RISC_ALLOCATION_RISC1_AND_RISC2 (QE_RISC_ALLOCATION_RISC1 | \
+ QE_RISC_ALLOCATION_RISC2)
+#define QE_RISC_ALLOCATION_FOUR_RISCS (QE_RISC_ALLOCATION_RISC1 | \
+ QE_RISC_ALLOCATION_RISC2 | \
+ QE_RISC_ALLOCATION_RISC3 | \
+ QE_RISC_ALLOCATION_RISC4)
/* QE extended filtering Table Lookup Key Size */
enum qe_fltr_tbl_lookup_key_size {
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 9057335fdc61..2cf915e51e7e 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -41,6 +41,12 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
return !!(v->arch.pending_exceptions);
}
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
+{
+ /* do real check here */
+ return 1;
+}
+
int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
{
return !(v->arch.msr & MSR_WE);
diff --git a/arch/powerpc/oprofile/op_model_fsl_emb.c b/arch/powerpc/oprofile/op_model_fsl_emb.c
index 91596f6ba1f4..62312abffa28 100644
--- a/arch/powerpc/oprofile/op_model_fsl_emb.c
+++ b/arch/powerpc/oprofile/op_model_fsl_emb.c
@@ -228,20 +228,6 @@ static void pmc_stop_ctrs(void)
mtpmr(PMRN_PMGC0, pmgc0);
}
-static void dump_pmcs(void)
-{
- printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
- printk("pmc\t\tpmlca\t\tpmlcb\n");
- printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
- mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
- printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
- mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
- printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
- mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
- printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
- mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
-}
-
static int fsl_emb_cpu_setup(struct op_counter_config *ctr)
{
int i;
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c
index 0eb6d7f62241..51fcae41f08a 100644
--- a/arch/powerpc/platforms/82xx/ep8248e.c
+++ b/arch/powerpc/platforms/82xx/ep8248e.c
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/fsl_devices.h>
#include <linux/mdio-bitbang.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <asm/io.h>
@@ -115,7 +116,7 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
struct mii_bus *bus;
struct resource res;
struct device_node *node;
- int ret, i;
+ int ret;
node = of_get_parent(ofdev->node);
of_node_put(node);
@@ -130,17 +131,13 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
if (!bus)
return -ENOMEM;
- bus->phy_mask = 0;
bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
- for (i = 0; i < PHY_MAX_ADDR; i++)
- bus->irq[i] = -1;
-
bus->name = "ep8248e-mdio-bitbang";
bus->parent = &ofdev->dev;
snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
- return mdiobus_register(bus);
+ return of_mdiobus_register(bus, ofdev->node);
}
static int ep8248e_mdio_remove(struct of_device *ofdev)
diff --git a/arch/powerpc/platforms/82xx/pq2ads.h b/arch/powerpc/platforms/82xx/pq2ads.h
index 984db42cc8e7..6cf0f97486e2 100644
--- a/arch/powerpc/platforms/82xx/pq2ads.h
+++ b/arch/powerpc/platforms/82xx/pq2ads.h
@@ -24,10 +24,6 @@
#include <linux/seq_file.h>
-/* Backword-compatibility stuff for the drivers */
-#define CPM_MAP_ADDR ((uint)0xf0000000)
-#define CPM_IRQ_OFFSET 0
-
/* The ADS8260 has 16, 32-bit wide control/status registers, accessed
* only on word boundaries.
* Not all are used (yet), or are interesting to us (yet).
@@ -44,14 +40,5 @@
#define BCSR3_FETHIEN2 ((uint)0x10000000) /* 0 == enable*/
#define BCSR3_FETH2_RST ((uint)0x80000000) /* 0 == reset */
-/* cpm serial driver works with constants below */
-
-#define SIU_INT_SMC1 ((uint)0x04+CPM_IRQ_OFFSET)
-#define SIU_INT_SMC2 ((uint)0x05+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC1 ((uint)0x28+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC2 ((uint)0x29+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC3 ((uint)0x2a+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC4 ((uint)0x2b+CPM_IRQ_OFFSET)
-
#endif /* __MACH_ADS8260_DEFS */
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 7f066adc068c..43d385cedcd7 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -34,6 +34,7 @@ config MPC85xx_MDS
bool "Freescale MPC85xx MDS"
select DEFAULT_UIMAGE
select PHYLIB
+ select HAS_RAPIDIO
help
This option enables support for the MPC85xx MDS board
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 7dd029034aec..b2c0a4319973 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -206,23 +206,24 @@ static void __init mpc85xx_mds_setup_arch(void)
}
if (bcsr_regs) {
+ if (machine_is(mpc8568_mds)) {
#define BCSR_UCC1_GETH_EN (0x1 << 7)
#define BCSR_UCC2_GETH_EN (0x1 << 7)
#define BCSR_UCC1_MODE_MSK (0x3 << 4)
#define BCSR_UCC2_MODE_MSK (0x3 << 0)
- /* Turn off UCC1 & UCC2 */
- clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
- clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+ /* Turn off UCC1 & UCC2 */
+ clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
+ clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
- /* Mode is RGMII, all bits clear */
- clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
- BCSR_UCC2_MODE_MSK);
-
- /* Turn UCC1 & UCC2 on */
- setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
- setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+ /* Mode is RGMII, all bits clear */
+ clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
+ BCSR_UCC2_MODE_MSK);
+ /* Turn UCC1 & UCC2 on */
+ setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
+ setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+ }
iounmap(bcsr_regs);
}
#endif /* CONFIG_QUICC_ENGINE */
@@ -257,7 +258,8 @@ static int __init board_fixups(void)
return 0;
}
-machine_arch_initcall(mpc85xx_mds, board_fixups);
+machine_arch_initcall(mpc8568_mds, board_fixups);
+machine_arch_initcall(mpc8569_mds, board_fixups);
static struct of_device_id mpc85xx_ids[] = {
{ .type = "soc", },
@@ -276,7 +278,8 @@ static int __init mpc85xx_publish_devices(void)
return 0;
}
-machine_device_initcall(mpc85xx_mds, mpc85xx_publish_devices);
+machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
+machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
static void __init mpc85xx_mds_pic_init(void)
{
@@ -321,8 +324,8 @@ static int __init mpc85xx_mds_probe(void)
return of_flat_dt_is_compatible(root, "MPC85xxMDS");
}
-define_machine(mpc85xx_mds) {
- .name = "MPC85xx MDS",
+define_machine(mpc8568_mds) {
+ .name = "MPC8568 MDS",
.probe = mpc85xx_mds_probe,
.setup_arch = mpc85xx_mds_setup_arch,
.init_IRQ = mpc85xx_mds_pic_init,
@@ -334,3 +337,24 @@ define_machine(mpc85xx_mds) {
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
#endif
};
+
+static int __init mpc8569_mds_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "fsl,MPC8569EMDS");
+}
+
+define_machine(mpc8569_mds) {
+ .name = "MPC8569 MDS",
+ .probe = mpc8569_mds_probe,
+ .setup_arch = mpc85xx_mds_setup_arch,
+ .init_IRQ = mpc85xx_mds_pic_init,
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+};
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
index d79104669cdc..2efa052975e6 100644
--- a/arch/powerpc/platforms/86xx/gef_ppc9a.c
+++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
@@ -28,7 +28,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c
index af14f852d747..90754e752bd8 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc310.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc310.c
@@ -28,7 +28,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
index ea2360639652..72b31a6010a0 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc610.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
@@ -28,7 +28,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 3f49a6f893a3..51eec0cd5519 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -28,7 +28,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index c4ec49b5f7f8..7e9e83c04a8a 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -24,7 +24,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/arch/powerpc/platforms/86xx/mpc86xx_smp.c
index 014e26cda08d..d84bbb508ee7 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_smp.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_smp.c
@@ -20,7 +20,6 @@
#include <asm/pgtable.h>
#include <asm/pci-bridge.h>
#include <asm/mpic.h>
-#include <asm/mpc86xx.h>
#include <asm/cacheflush.h>
#include <sysdev/fsl_soc.h>
@@ -30,6 +29,11 @@
extern void __secondary_start_mpc86xx(void);
extern unsigned long __secondary_hold_acknowledge;
+#define MCM_PORT_CONFIG_OFFSET 0x10
+
+/* Offset from CCSRBAR */
+#define MPC86xx_MCM_OFFSET (0x1000)
+#define MPC86xx_MCM_SIZE (0x1000)
static void __init
smp_86xx_release_core(int nr)
@@ -48,6 +52,8 @@ smp_86xx_release_core(int nr)
pcr = in_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2));
pcr |= 1 << (nr + 24);
out_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2), pcr);
+
+ iounmap(mcm_vaddr);
}
diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c
index 2886a36fc085..51c8f331b671 100644
--- a/arch/powerpc/platforms/86xx/sbc8641d.c
+++ b/arch/powerpc/platforms/86xx/sbc8641d.c
@@ -25,7 +25,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/8xx/mpc885ads.h b/arch/powerpc/platforms/8xx/mpc885ads.h
index a5076668bad6..19412f76fa3b 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads.h
+++ b/arch/powerpc/platforms/8xx/mpc885ads.h
@@ -17,10 +17,6 @@
#include <sysdev/fsl_soc.h>
-#define MPC8xx_CPM_OFFSET (0x9c0)
-#define CPM_MAP_ADDR (get_immrbase() + MPC8xx_CPM_OFFSET)
-#define CPM_IRQ_OFFSET 16 // for compability with cpm_uart driver
-
/* Bits of interest in the BCSRs.
*/
#define BCSR1_ETHEN ((uint)0x20000000)
diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c
index 65a35f38e062..df83dc972531 100644
--- a/arch/powerpc/platforms/fsl_uli1575.c
+++ b/arch/powerpc/platforms/fsl_uli1575.c
@@ -51,13 +51,19 @@ u8 uli_pirq_to_irq[8] = {
ULI_8259_NONE, /* PIRQH */
};
+static inline bool is_quirk_valid(void)
+{
+ return (machine_is(mpc86xx_hpcn) ||
+ machine_is(mpc8544_ds) ||
+ machine_is(mpc8572_ds));
+}
+
/* Bridge */
static void __devinit early_uli5249(struct pci_dev *dev)
{
unsigned char temp;
- if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
- !machine_is(mpc8572_ds))
+ if (!is_quirk_valid())
return;
pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO |
@@ -80,8 +86,7 @@ static void __devinit quirk_uli1575(struct pci_dev *dev)
{
int i;
- if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
- !machine_is(mpc8572_ds))
+ if (!is_quirk_valid())
return;
/*
@@ -149,8 +154,7 @@ static void __devinit quirk_final_uli1575(struct pci_dev *dev)
* IRQ 14: Edge
* IRQ 15: Edge
*/
- if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
- !machine_is(mpc8572_ds))
+ if (!is_quirk_valid())
return;
outb(0xfa, 0x4d0);
@@ -176,8 +180,7 @@ static void __devinit quirk_uli5288(struct pci_dev *dev)
unsigned char c;
unsigned int d;
- if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
- !machine_is(mpc8572_ds))
+ if (!is_quirk_valid())
return;
/* read/write lock */
@@ -201,8 +204,7 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
{
unsigned short temp;
- if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
- !machine_is(mpc8572_ds))
+ if (!is_quirk_valid())
return;
pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE |
@@ -270,7 +272,6 @@ static void __devinit hpcd_quirk_uli1575(struct pci_dev *dev)
static void __devinit hpcd_quirk_uli5288(struct pci_dev *dev)
{
unsigned char c;
- unsigned short temp;
if (!machine_is(mpc86xx_hpcd))
return;
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index 75cc165d5bee..3bf546797cbb 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -29,7 +29,7 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/phy.h>
-#include <linux/platform_device.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#define DELAY 1
@@ -39,6 +39,7 @@ static void __iomem *gpio_regs;
struct gpio_priv {
int mdc_pin;
int mdio_pin;
+ int mdio_irqs[PHY_MAX_ADDR];
};
#define MDC_PIN(bus) (((struct gpio_priv *)bus->priv)->mdc_pin)
@@ -218,12 +219,11 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
struct device *dev = &ofdev->dev;
- struct device_node *phy_dn, *np = ofdev->node;
+ struct device_node *np = ofdev->node;
struct mii_bus *new_bus;
struct gpio_priv *priv;
const unsigned int *prop;
int err;
- int i;
err = -ENOMEM;
priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL);
@@ -244,27 +244,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop);
new_bus->priv = priv;
- new_bus->phy_mask = 0;
-
- new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
-
- if (!new_bus->irq)
- goto out_free_bus;
-
- for (i = 0; i < PHY_MAX_ADDR; i++)
- new_bus->irq[i] = NO_IRQ;
-
- for (phy_dn = of_get_next_child(np, NULL);
- phy_dn != NULL;
- phy_dn = of_get_next_child(np, phy_dn)) {
- const unsigned int *ip, *regp;
-
- ip = of_get_property(phy_dn, "interrupts", NULL);
- regp = of_get_property(phy_dn, "reg", NULL);
- if (!ip || !regp || *regp >= PHY_MAX_ADDR)
- continue;
- new_bus->irq[*regp] = irq_create_mapping(NULL, *ip);
- }
+ new_bus->irq = priv->mdio_irqs;
prop = of_get_property(np, "mdc-pin", NULL);
priv->mdc_pin = *prop;
@@ -275,7 +255,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
new_bus->parent = dev;
dev_set_drvdata(dev, new_bus);
- err = mdiobus_register(new_bus);
+ err = of_mdiobus_register(new_bus, np);
if (err != 0) {
printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n",
@@ -286,8 +266,6 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
return 0;
out_free_irq:
- kfree(new_bus->irq);
-out_free_bus:
kfree(new_bus);
out_free_priv:
kfree(priv);
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 80b513449f4c..be3581a8c294 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -333,7 +333,7 @@ static void xics_eoi_lpar(unsigned int virq)
lpar_xirr_info_set((0xff << 24) | irq);
}
-static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
+static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
{
unsigned int irq;
int status;
@@ -342,14 +342,14 @@ static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
irq = (unsigned int)irq_map[virq].hwirq;
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
- return;
+ return -1;
status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
if (status) {
printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
__func__, irq, status);
- return;
+ return -1;
}
/*
@@ -363,7 +363,7 @@ static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
printk(KERN_WARNING
"%s: No online cpus in the mask %s for irq %d\n",
__func__, cpulist, virq);
- return;
+ return -1;
}
status = rtas_call(ibm_set_xive, 3, 1, NULL,
@@ -372,8 +372,10 @@ static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
if (status) {
printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
__func__, irq, status);
- return;
+ return -1;
}
+
+ return 0;
}
static struct irq_chip xics_pic_direct = {
diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c
index fd969f0e3121..eb5927212fab 100644
--- a/arch/powerpc/sysdev/cpm2.c
+++ b/arch/powerpc/sysdev/cpm2.c
@@ -61,7 +61,7 @@ EXPORT_SYMBOL(cpm2_immr);
void __init cpm2_reset(void)
{
#ifdef CONFIG_PPC_85xx
- cpm2_immr = ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
+ cpm2_immr = ioremap(get_immrbase() + 0x80000, CPM_MAP_SIZE);
#else
cpm2_immr = ioremap(get_immrbase(), CPM_MAP_SIZE);
#endif
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index f25ce818d40a..da38a1ff97bb 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -113,8 +113,13 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
struct msi_msg *msg)
{
struct fsl_msi *msi_data = fsl_msi;
+ struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+ u32 base = 0;
- msg->address_lo = msi_data->msi_addr_lo;
+ pci_bus_read_config_dword(hose->bus,
+ PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
+
+ msg->address_lo = msi_data->msi_addr_lo + base;
msg->address_hi = msi_data->msi_addr_hi;
msg->data = hwirq;
@@ -271,7 +276,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
msi->irqhost->host_data = msi;
msi->msi_addr_hi = 0x0;
- msi->msi_addr_lo = res.start + features->msiir_offset;
+ msi->msi_addr_lo = features->msiir_offset + (res.start & 0xfffff);
rc = fsl_msi_init_allocator(msi);
if (rc) {
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 78021d8afc53..94d8b3feb1ea 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -152,6 +152,10 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
out_be32(&pci->piw[2].piwbar,0x00000000);
out_be32(&pci->piw[2].piwar, PIWAR_2G);
+ /* Save the base address and size covered by inbound window mappings */
+ hose->dma_window_base_cur = 0x00000000;
+ hose->dma_window_size = 0x80000000;
+
iounmap(pci);
}
@@ -281,6 +285,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8569E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8569, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_header);
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index abdb124e1e2f..39db9d1155d2 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1026,8 +1026,7 @@ int fsl_rio_setup(struct of_device *dev)
return -EFAULT;
}
dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name);
- dev_info(&dev->dev, "Regs start 0x%08x size 0x%08x\n", regs.start,
- regs.end - regs.start + 1);
+ dev_info(&dev->dev, "Regs: %pR\n", &regs);
dt_range = of_get_property(dev->node, "ranges", &rlen);
if (!dt_range) {
@@ -1077,8 +1076,9 @@ int fsl_rio_setup(struct of_device *dev)
INIT_LIST_HEAD(&port->dbells);
port->iores.start = law_start;
- port->iores.end = law_start + law_size;
+ port->iores.end = law_start + law_size - 1;
port->iores.flags = IORESOURCE_MEM;
+ port->iores.name = "rio_io_win";
priv->bellirq = irq_of_parse_and_map(dev->node, 2);
priv->txirq = irq_of_parse_and_map(dev->node, 3);
@@ -1156,14 +1156,15 @@ int fsl_rio_setup(struct of_device *dev)
out_be32((priv->regs_win + RIO_ISR_AACR), RIO_ISR_AACR_AA);
/* Configure maintenance transaction window */
- out_be32(&priv->maint_atmu_regs->rowbar, 0x000c0000);
- out_be32(&priv->maint_atmu_regs->rowar, 0x80077015);
+ out_be32(&priv->maint_atmu_regs->rowbar, law_start >> 12);
+ out_be32(&priv->maint_atmu_regs->rowar, 0x80077015); /* 4M */
priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE);
/* Configure outbound doorbell window */
- out_be32(&priv->dbell_atmu_regs->rowbar, 0x000c0400);
- out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
+ out_be32(&priv->dbell_atmu_regs->rowbar,
+ (law_start + RIO_MAINT_WIN_SIZE) >> 12);
+ out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b); /* 4k */
fsl_rio_doorbell_init(port);
return 0;
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index afe8dbc964aa..bd1b74dad739 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -425,16 +425,10 @@ static int __init setup_rstcr(void)
struct device_node *np;
np = of_find_node_by_name(NULL, "global-utilities");
if ((np && of_get_property(np, "fsl,has-rstcr", NULL))) {
- const u32 *prop = of_get_property(np, "reg", NULL);
- if (prop) {
- /* map reset control register
- * 0xE00B0 is offset of reset control register
- */
- rstcr = ioremap(get_immrbase() + *prop + 0xB0, 0xff);
- if (!rstcr)
- printk (KERN_EMERG "Error: reset control "
- "register not mapped!\n");
- }
+ rstcr = of_iomap(np, 0) + 0xb0;
+ if (!rstcr)
+ printk (KERN_EMERG "Error: reset control register "
+ "not mapped!\n");
} else
printk (KERN_INFO "rstcr compatible register does not exist!\n");
if (np)
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 21b956701596..f4cbd15cf22f 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -807,7 +807,7 @@ static void mpic_end_ipi(unsigned int irq)
#endif /* CONFIG_SMP */
-void mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
{
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq);
@@ -824,6 +824,8 @@ void mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
mpic_physmask(cpus_addr(tmp)[0]));
}
+
+ return 0;
}
static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
index 3cef2af10f42..eff433c322a0 100644
--- a/arch/powerpc/sysdev/mpic.h
+++ b/arch/powerpc/sysdev/mpic.h
@@ -36,6 +36,6 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
extern void mpic_set_vector(unsigned int virq, unsigned int vector);
-extern void mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
+extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
#endif /* _POWERPC_SYSDEV_MPIC_H */
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 01bce3784b0a..b28b0e512d67 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -61,6 +61,7 @@ struct qe_immap __iomem *qe_immr;
EXPORT_SYMBOL(qe_immr);
static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */
+static unsigned int qe_num_of_snum;
static phys_addr_t qebase = -1;
@@ -264,10 +265,14 @@ static void qe_snums_init(void)
0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
- 0xD8, 0xD9, 0xE8, 0xE9,
+ 0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
+ 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
+ 0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
};
- for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+ qe_num_of_snum = qe_get_num_of_snums();
+
+ for (i = 0; i < qe_num_of_snum; i++) {
snums[i].num = snum_init[i];
snums[i].state = QE_SNUM_STATE_FREE;
}
@@ -280,7 +285,7 @@ int qe_get_snum(void)
int i;
spin_lock_irqsave(&qe_lock, flags);
- for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+ for (i = 0; i < qe_num_of_snum; i++) {
if (snums[i].state == QE_SNUM_STATE_FREE) {
snums[i].state = QE_SNUM_STATE_USED;
snum = snums[i].num;
@@ -297,7 +302,7 @@ void qe_put_snum(u8 snum)
{
int i;
- for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+ for (i = 0; i < qe_num_of_snum; i++) {
if (snums[i].num == snum) {
snums[i].state = QE_SNUM_STATE_FREE;
break;
@@ -575,3 +580,65 @@ struct qe_firmware_info *qe_get_firmware_info(void)
}
EXPORT_SYMBOL(qe_get_firmware_info);
+unsigned int qe_get_num_of_risc(void)
+{
+ struct device_node *qe;
+ int size;
+ unsigned int num_of_risc = 0;
+ const u32 *prop;
+
+ qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+ if (!qe) {
+ /* Older devices trees did not have an "fsl,qe"
+ * compatible property, so we need to look for
+ * the QE node by name.
+ */
+ qe = of_find_node_by_type(NULL, "qe");
+ if (!qe)
+ return num_of_risc;
+ }
+
+ prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
+ if (prop && size == sizeof(*prop))
+ num_of_risc = *prop;
+
+ of_node_put(qe);
+
+ return num_of_risc;
+}
+EXPORT_SYMBOL(qe_get_num_of_risc);
+
+unsigned int qe_get_num_of_snums(void)
+{
+ struct device_node *qe;
+ int size;
+ unsigned int num_of_snums;
+ const u32 *prop;
+
+ num_of_snums = 28; /* The default number of snum for threads is 28 */
+ qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+ if (!qe) {
+ /* Older devices trees did not have an "fsl,qe"
+ * compatible property, so we need to look for
+ * the QE node by name.
+ */
+ qe = of_find_node_by_type(NULL, "qe");
+ if (!qe)
+ return num_of_snums;
+ }
+
+ prop = of_get_property(qe, "fsl,qe-num-snums", &size);
+ if (prop && size == sizeof(*prop)) {
+ num_of_snums = *prop;
+ if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
+ /* No QE ever has fewer than 28 SNUMs */
+ pr_err("QE: number of snum is invalid\n");
+ return -EINVAL;
+ }
+ }
+
+ of_node_put(qe);
+
+ return num_of_snums;
+}
+EXPORT_SYMBOL(qe_get_num_of_snums);
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 2eca5fe0e75b..1094787e97e5 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -567,6 +567,24 @@ bool "s390 guest support for KVM (EXPERIMENTAL)"
the KVM hypervisor. This will add detection for KVM as well as a
virtio transport. If KVM is detected, the virtio console will be
the default console.
+
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS
+ default y
+ help
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via /proc/<pid>/seccomp, it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
+ If unsure, say Y.
+
endmenu
source "net/Kconfig"
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index de065b32381a..01a08020bc0e 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -5,6 +5,7 @@
*/
#include <linux/types.h>
#include <linux/sched.h>
+#include <linux/thread_info.h>
#define PSW32_MASK_PER 0x40000000UL
#define PSW32_MASK_DAT 0x04000000UL
@@ -163,12 +164,28 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
return (u32)(unsigned long)uptr;
}
+#ifdef CONFIG_COMPAT
+
+static inline int is_compat_task(void)
+{
+ return test_thread_flag(TIF_31BIT);
+}
+
+#else
+
+static inline int is_compat_task(void)
+{
+ return 0;
+}
+
+#endif
+
static inline void __user *compat_alloc_user_space(long len)
{
unsigned long stack;
stack = KSTK_ESP(current);
- if (test_thread_flag(TIF_31BIT))
+ if (is_compat_task())
stack &= 0x7fffffffUL;
return (void __user *) (stack - len);
}
diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h
deleted file mode 100644
index d60a2eefb17b..000000000000
--- a/arch/s390/include/asm/cpu.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * include/asm-s390/cpu.h
- *
- * Copyright IBM Corp. 2007
- * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
- */
-
-#ifndef _ASM_S390_CPU_H_
-#define _ASM_S390_CPU_H_
-
-#include <linux/types.h>
-#include <linux/percpu.h>
-#include <linux/spinlock.h>
-
-struct s390_idle_data {
- spinlock_t lock;
- unsigned long long idle_count;
- unsigned long long idle_enter;
- unsigned long long idle_time;
-};
-
-DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
-
-void vtime_start_cpu(void);
-
-static inline void s390_idle_check(void)
-{
- if ((&__get_cpu_var(s390_idle))->idle_enter != 0ULL)
- vtime_start_cpu();
-}
-
-#endif /* _ASM_S390_CPU_H_ */
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index 941384fbd39c..ec917d42ee6d 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -9,6 +9,9 @@
#ifndef _S390_CPUTIME_H
#define _S390_CPUTIME_H
+#include <linux/types.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
#include <asm/div64.h>
/* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */
@@ -174,8 +177,24 @@ cputime64_to_clock_t(cputime64_t cputime)
return __div(cputime, 4096000000ULL / USER_HZ);
}
+struct s390_idle_data {
+ spinlock_t lock;
+ unsigned long long idle_count;
+ unsigned long long idle_enter;
+ unsigned long long idle_time;
+};
+
+DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
+
+void vtime_start_cpu(void);
cputime64_t s390_get_idle_time(int cpu);
#define arch_idle_time(cpu) s390_get_idle_time(cpu)
+static inline void s390_idle_check(void)
+{
+ if ((&__get_cpu_var(s390_idle))->idle_enter != 0ULL)
+ vtime_start_cpu();
+}
+
#endif /* _S390_CPUTIME_H */
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 3aeca492b147..713fe9fb1fcc 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -30,6 +30,7 @@
#define __LC_SUBCHANNEL_NR 0x00ba
#define __LC_IO_INT_PARM 0x00bc
#define __LC_IO_INT_WORD 0x00c0
+#define __LC_STFL_FAC_LIST 0x00c8
#define __LC_MCCK_CODE 0x00e8
#define __LC_DUMP_REIPL 0x0e00
diff --git a/arch/s390/include/asm/seccomp.h b/arch/s390/include/asm/seccomp.h
new file mode 100644
index 000000000000..781a9cf9b002
--- /dev/null
+++ b/arch/s390/include/asm/seccomp.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_S390_SECCOMP_H
+#define _ASM_S390_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_sigreturn
+
+#define __NR_seccomp_read_32 __NR_read
+#define __NR_seccomp_write_32 __NR_write
+#define __NR_seccomp_exit_32 __NR_exit
+#define __NR_seccomp_sigreturn_32 __NR_sigreturn
+
+#endif /* _ASM_S390_SECCOMP_H */
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h
index f3861b09ebb0..c9af0d19c7ab 100644
--- a/arch/s390/include/asm/spinlock.h
+++ b/arch/s390/include/asm/spinlock.h
@@ -122,8 +122,10 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lp)
#define __raw_write_can_lock(x) ((x)->lock == 0)
extern void _raw_read_lock_wait(raw_rwlock_t *lp);
+extern void _raw_read_lock_wait_flags(raw_rwlock_t *lp, unsigned long flags);
extern int _raw_read_trylock_retry(raw_rwlock_t *lp);
extern void _raw_write_lock_wait(raw_rwlock_t *lp);
+extern void _raw_write_lock_wait_flags(raw_rwlock_t *lp, unsigned long flags);
extern int _raw_write_trylock_retry(raw_rwlock_t *lp);
static inline void __raw_read_lock(raw_rwlock_t *rw)
@@ -134,6 +136,14 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
_raw_read_lock_wait(rw);
}
+static inline void __raw_read_lock_flags(raw_rwlock_t *rw, unsigned long flags)
+{
+ unsigned int old;
+ old = rw->lock & 0x7fffffffU;
+ if (_raw_compare_and_swap(&rw->lock, old, old + 1) != old)
+ _raw_read_lock_wait_flags(rw, flags);
+}
+
static inline void __raw_read_unlock(raw_rwlock_t *rw)
{
unsigned int old, cmp;
@@ -151,6 +161,12 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
_raw_write_lock_wait(rw);
}
+static inline void __raw_write_lock_flags(raw_rwlock_t *rw, unsigned long flags)
+{
+ if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0))
+ _raw_write_lock_wait_flags(rw, flags);
+}
+
static inline void __raw_write_unlock(raw_rwlock_t *rw)
{
_raw_compare_and_swap(&rw->lock, 0x80000000, 0);
@@ -172,9 +188,6 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
return _raw_write_trylock_retry(rw);
}
-#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
-#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
-
#define _raw_read_relax(lock) cpu_relax()
#define _raw_write_relax(lock) cpu_relax()
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index 461f2abd2e6f..2f86653dda69 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -83,14 +83,15 @@ static inline struct thread_info *current_thread_info(void)
/*
* thread information flags bit numbers
*/
-#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTART_SVC 4 /* restart svc with new svc number */
-#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
#define TIF_SINGLE_STEP 6 /* deliver sigtrap on return to user */
#define TIF_MCCK_PENDING 7 /* machine check handling is pending */
+#define TIF_SYSCALL_TRACE 8 /* syscall trace active */
+#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */
+#define TIF_SECCOMP 10 /* secure computing */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
@@ -99,15 +100,16 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */
#define TIF_FREEZE 21 /* thread is freezing for suspend */
-#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC)
-#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP)
#define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING)
+#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
+#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_31BIT (1<<TIF_31BIT)
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 228e3105ded7..0657de7944fe 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -22,7 +22,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o \
processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \
- vdso.o vtime.o sysinfo.o nmi.o
+ vdso.o vtime.o sysinfo.o nmi.o sclp.o
obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index f3e275934213..db25cdc21e12 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -53,6 +53,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING)
+_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | _TIF_SECCOMP>>8)
STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
STACK_SIZE = 1 << STACK_SHIFT
@@ -265,7 +266,7 @@ sysc_do_restart:
sth %r7,SP_SVCNR(%r15)
sll %r7,2 # svc number *4
l %r8,BASED(.Lsysc_table)
- tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+ tm __TI_flags+2(%r9),_TIF_SYSCALL
l %r8,0(%r7,%r8) # get system call addr.
bnz BASED(sysc_tracesys)
basr %r14,%r8 # call sys_xxxx
@@ -405,7 +406,7 @@ sysc_tracego:
basr %r14,%r8 # call sys_xxx
st %r2,SP_R2(%r15) # store return value
sysc_tracenogo:
- tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+ tm __TI_flags+2(%r9),_TIF_SYSCALL
bz BASED(sysc_return)
l %r1,BASED(.Ltrace_exit)
la %r2,SP_PTREGS(%r15) # load pt_regs
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 84a105838e03..3cec9b504f5f 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -56,6 +56,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING)
+_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | _TIF_SECCOMP>>8)
#define BASED(name) name-system_call(%r13)
@@ -260,7 +261,7 @@ sysc_do_restart:
larl %r10,sys_call_table_emu # use 31 bit emulation system calls
sysc_noemu:
#endif
- tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+ tm __TI_flags+6(%r9),_TIF_SYSCALL
lgf %r8,0(%r7,%r10) # load address of system call routine
jnz sysc_tracesys
basr %r14,%r8 # call sys_xxxx
@@ -391,7 +392,7 @@ sysc_tracego:
basr %r14,%r8 # call sys_xxx
stg %r2,SP_R2(%r15) # store return value
sysc_tracenogo:
- tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+ tm __TI_flags+6(%r9),_TIF_SYSCALL
jz sysc_return
la %r2,SP_PTREGS(%r15) # load pt_regs
larl %r14,sysc_return # return point is sysc_return
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 2c54e970d0d6..ec6882348520 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -1,7 +1,5 @@
/*
- * arch/s390/kernel/head.S
- *
- * Copyright (C) IBM Corp. 1999,2006
+ * Copyright IBM Corp. 1999,2009
*
* Author(s): Hartmut Penner <hp@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -479,27 +477,58 @@ startup:basr %r13,0 # get base
mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
mvc __LC_EXIT_TIMER(8),5f-.LPG0(%r13)
#ifndef CONFIG_MARCH_G5
- # check processor version against MARCH_{G5,Z900,Z990,Z9_109,Z10}
- stidp __LC_CPUID # store cpuid
- lhi %r0,(3f-2f) / 2
- la %r1,2f-.LPG0(%r13)
-0: clc __LC_CPUID+4(2),0(%r1)
- jne 3f
- lpsw 1f-.LPG0(13) # machine type not good enough, crash
+ # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
+ xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
+ stfl __LC_STFL_FAC_LIST # store facility list
+ tm __LC_STFL_FAC_LIST,0x01 # stfle available ?
+ jz 0f
+ la %r0,0
+ .insn s,0xb2b00000,__LC_STFL_FAC_LIST # store facility list extended
+0: l %r0,__LC_STFL_FAC_LIST
+ n %r0,2f+8-.LPG0(%r13)
+ cl %r0,2f+8-.LPG0(%r13)
+ jne 1f
+ l %r0,__LC_STFL_FAC_LIST+4
+ n %r0,2f+12-.LPG0(%r13)
+ cl %r0,2f+12-.LPG0(%r13)
+ je 3f
+1: l %r15,.Lstack-.LPG0(%r13)
+ ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
+ ahi %r15,-96
+ la %r2,.Lals_string-.LPG0(%r13)
+ l %r3,.Lsclp_print-.LPG0(%r13)
+ basr %r14,%r3
+ lpsw 2f-.LPG0(%r13) # machine type not good enough, crash
+.Lals_string:
+ .asciz "The Linux kernel requires more recent processor hardware"
+.Lsclp_print:
+ .long _sclp_print_early
+.Lstack:
+ .long init_thread_union
.align 16
-1: .long 0x000a0000,0x00000000
-2:
+2: .long 0x000a0000,0x8badcccc
+#if defined(CONFIG_64BIT)
#if defined(CONFIG_MARCH_Z10)
- .short 0x9672, 0x2064, 0x2066, 0x2084, 0x2086, 0x2094, 0x2096
+ .long 0xc100efe3, 0xf0680000
#elif defined(CONFIG_MARCH_Z9_109)
- .short 0x9672, 0x2064, 0x2066, 0x2084, 0x2086
+ .long 0xc100efc3, 0x00000000
#elif defined(CONFIG_MARCH_Z990)
- .short 0x9672, 0x2064, 0x2066
+ .long 0xc0002000, 0x00000000
#elif defined(CONFIG_MARCH_Z900)
- .short 0x9672
+ .long 0xc0000000, 0x00000000
+#endif
+#else
+#if defined(CONFIG_MARCH_Z10)
+ .long 0x8100c880, 0x00000000
+#elif defined(CONFIG_MARCH_Z9_109)
+ .long 0x8100c880, 0x00000000
+#elif defined(CONFIG_MARCH_Z990)
+ .long 0x80002000, 0x00000000
+#elif defined(CONFIG_MARCH_Z900)
+ .long 0x80000000, 0x00000000
+#endif
#endif
-3: la %r1,2(%r1)
- brct %r0,0b
+3:
#endif
l %r13,4f-.LPG0(%r13)
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c
index 28cf196ba775..015e27da40eb 100644
--- a/arch/s390/kernel/nmi.c
+++ b/arch/s390/kernel/nmi.c
@@ -16,7 +16,7 @@
#include <asm/lowcore.h>
#include <asm/smp.h>
#include <asm/etr.h>
-#include <asm/cpu.h>
+#include <asm/cputime.h>
#include <asm/nmi.h>
#include <asm/crw.h>
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index a3acd8e60aff..355f7a30c3f1 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -32,6 +32,7 @@
#include <linux/elfcore.h>
#include <linux/kernel_stat.h>
#include <linux/syscalls.h>
+#include <asm/compat.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -204,7 +205,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
save_fp_regs(&p->thread.fp_regs);
/* Set a new TLS ? */
if (clone_flags & CLONE_SETTLS) {
- if (test_thread_flag(TIF_31BIT)) {
+ if (is_compat_task()) {
p->thread.acrs[0] = (unsigned int) regs->gprs[6];
} else {
p->thread.acrs[0] = (unsigned int)(regs->gprs[6] >> 32);
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 75c496f4f16d..b6fc1ae2ffcb 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -36,7 +36,8 @@
#include <linux/elf.h>
#include <linux/regset.h>
#include <linux/tracehook.h>
-
+#include <linux/seccomp.h>
+#include <asm/compat.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -69,7 +70,7 @@ FixPerRegisters(struct task_struct *task)
if (per_info->single_step) {
per_info->control_regs.bits.starting_addr = 0;
#ifdef CONFIG_COMPAT
- if (test_thread_flag(TIF_31BIT))
+ if (is_compat_task())
per_info->control_regs.bits.ending_addr = 0x7fffffffUL;
else
#endif
@@ -482,8 +483,7 @@ static int peek_user_compat(struct task_struct *child,
{
__u32 tmp;
- if (!test_thread_flag(TIF_31BIT) ||
- (addr & 3) || addr > sizeof(struct user) - 3)
+ if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user) - 3)
return -EIO;
tmp = __peek_user_compat(child, addr);
@@ -584,8 +584,7 @@ static int __poke_user_compat(struct task_struct *child,
static int poke_user_compat(struct task_struct *child,
addr_t addr, addr_t data)
{
- if (!test_thread_flag(TIF_31BIT) ||
- (addr & 3) || addr > sizeof(struct user32) - 3)
+ if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user32) - 3)
return -EIO;
return __poke_user_compat(child, addr, data);
@@ -642,6 +641,9 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{
long ret;
+ /* Do the secure computing check first. */
+ secure_computing(regs->gprs[2]);
+
/*
* The sysc_tracesys code in entry.S stored the system
* call number to gprs[2].
@@ -660,7 +662,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
}
if (unlikely(current->audit_context))
- audit_syscall_entry(test_thread_flag(TIF_31BIT) ?
+ audit_syscall_entry(is_compat_task() ?
AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
regs->gprs[2], regs->orig_gpr2,
regs->gprs[3], regs->gprs[4],
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index a0d2d55d7fb3..6b0686d78fc7 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -13,7 +13,7 @@
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
-#include <asm/cpu.h>
+#include <asm/cputime.h>
#include <asm/lowcore.h>
#include <asm/s390_ext.h>
#include <asm/irq_regs.h>
diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S
new file mode 100644
index 000000000000..20639dfe0c42
--- /dev/null
+++ b/arch/s390/kernel/sclp.S
@@ -0,0 +1,327 @@
+/*
+ * Mini SCLP driver.
+ *
+ * Copyright IBM Corp. 2004,2009
+ *
+ * Author(s): Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com>,
+ * Heiko Carstens <heiko.carstens@de.ibm.com>,
+ *
+ */
+
+LC_EXT_NEW_PSW = 0x58 # addr of ext int handler
+LC_EXT_INT_PARAM = 0x80 # addr of ext int parameter
+LC_EXT_INT_CODE = 0x86 # addr of ext int code
+
+#
+# Subroutine which waits synchronously until either an external interruption
+# or a timeout occurs.
+#
+# Parameters:
+# R2 = 0 for no timeout, non-zero for timeout in (approximated) seconds
+#
+# Returns:
+# R2 = 0 on interrupt, 2 on timeout
+# R3 = external interruption parameter if R2=0
+#
+
+.section ".init.text","ax"
+
+_sclp_wait_int:
+ stm %r6,%r15,24(%r15) # save registers
+ basr %r13,0 # get base register
+.LbaseS1:
+ ahi %r15,-96 # create stack frame
+ la %r8,LC_EXT_NEW_PSW # register int handler
+ mvc .LoldpswS1-.LbaseS1(8,%r13),0(%r8)
+ mvc 0(8,%r8),.LextpswS1-.LbaseS1(%r13)
+ lhi %r6,0x0200 # cr mask for ext int (cr0.54)
+ ltr %r2,%r2
+ jz .LsetctS1
+ ahi %r6,0x0800 # cr mask for clock int (cr0.52)
+ stck .LtimeS1-.LbaseS1(%r13) # initiate timeout
+ al %r2,.LtimeS1-.LbaseS1(%r13)
+ st %r2,.LtimeS1-.LbaseS1(%r13)
+ sckc .LtimeS1-.LbaseS1(%r13)
+
+.LsetctS1:
+ stctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # enable required interrupts
+ l %r0,.LctlS1-.LbaseS1(%r13)
+ lhi %r1,~(0x200 | 0x800) # clear old values
+ nr %r1,%r0
+ or %r1,%r6 # set new value
+ st %r1,.LctlS1-.LbaseS1(%r13)
+ lctl %c0,%c0,.LctlS1-.LbaseS1(%r13)
+ st %r0,.LctlS1-.LbaseS1(%r13)
+ lhi %r2,2 # return code for timeout
+.LloopS1:
+ lpsw .LwaitpswS1-.LbaseS1(%r13) # wait until interrupt
+.LwaitS1:
+ lh %r7,LC_EXT_INT_CODE
+ chi %r7,0x1004 # timeout?
+ je .LtimeoutS1
+ chi %r7,0x2401 # service int?
+ jne .LloopS1
+ sr %r2,%r2
+ l %r3,LC_EXT_INT_PARAM
+.LtimeoutS1:
+ lctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # restore interrupt setting
+ # restore old handler
+ mvc 0(8,%r8),.LoldpswS1-.LbaseS1(%r13)
+ lm %r6,%r15,120(%r15) # restore registers
+ br %r14 # return to caller
+
+ .align 8
+.LoldpswS1:
+ .long 0, 0 # old ext int PSW
+.LextpswS1:
+ .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int
+.LwaitpswS1:
+ .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int
+.LtimeS1:
+ .quad 0 # current time
+.LctlS1:
+ .long 0 # CT0 contents
+
+#
+# Subroutine to synchronously issue a service call.
+#
+# Parameters:
+# R2 = command word
+# R3 = sccb address
+#
+# Returns:
+# R2 = 0 on success, 1 on failure
+# R3 = sccb response code if R2 = 0
+#
+
+_sclp_servc:
+ stm %r6,%r15,24(%r15) # save registers
+ ahi %r15,-96 # create stack frame
+ lr %r6,%r2 # save command word
+ lr %r7,%r3 # save sccb address
+.LretryS2:
+ lhi %r2,1 # error return code
+ .insn rre,0xb2200000,%r6,%r7 # servc
+ brc 1,.LendS2 # exit if not operational
+ brc 8,.LnotbusyS2 # go on if not busy
+ sr %r2,%r2 # wait until no longer busy
+ bras %r14,_sclp_wait_int
+ j .LretryS2 # retry
+.LnotbusyS2:
+ sr %r2,%r2 # wait until result
+ bras %r14,_sclp_wait_int
+ sr %r2,%r2
+ lh %r3,6(%r7)
+.LendS2:
+ lm %r6,%r15,120(%r15) # restore registers
+ br %r14
+
+#
+# Subroutine to set up the SCLP interface.
+#
+# Parameters:
+# R2 = 0 to activate, non-zero to deactivate
+#
+# Returns:
+# R2 = 0 on success, non-zero on failure
+#
+
+_sclp_setup:
+ stm %r6,%r15,24(%r15) # save registers
+ ahi %r15,-96 # create stack frame
+ basr %r13,0 # get base register
+.LbaseS3:
+ l %r6,.LsccbS0-.LbaseS3(%r13) # prepare init mask sccb
+ mvc 0(.LinitendS3-.LinitsccbS3,%r6),.LinitsccbS3-.LbaseS3(%r13)
+ ltr %r2,%r2 # initialization?
+ jz .LdoinitS3 # go ahead
+ # clear masks
+ xc .LinitmaskS3-.LinitsccbS3(8,%r6),.LinitmaskS3-.LinitsccbS3(%r6)
+.LdoinitS3:
+ l %r2,.LwritemaskS3-.LbaseS3(%r13)# get command word
+ lr %r3,%r6 # get sccb address
+ bras %r14,_sclp_servc # issue service call
+ ltr %r2,%r2 # servc successful?
+ jnz .LerrorS3
+ chi %r3,0x20 # write mask successful?
+ jne .LerrorS3
+ # check masks
+ la %r2,.LinitmaskS3-.LinitsccbS3(%r6)
+ l %r1,0(%r2) # receive mask ok?
+ n %r1,12(%r2)
+ cl %r1,0(%r2)
+ jne .LerrorS3
+ l %r1,4(%r2) # send mask ok?
+ n %r1,8(%r2)
+ cl %r1,4(%r2)
+ sr %r2,%r2
+ je .LendS3
+.LerrorS3:
+ lhi %r2,1 # error return code
+.LendS3:
+ lm %r6,%r15,120(%r15) # restore registers
+ br %r14
+.LwritemaskS3:
+ .long 0x00780005 # SCLP command for write mask
+.LinitsccbS3:
+ .word .LinitendS3-.LinitsccbS3
+ .byte 0,0,0,0
+ .word 0
+ .word 0
+ .word 4
+.LinitmaskS3:
+ .long 0x80000000
+ .long 0x40000000
+ .long 0
+ .long 0
+.LinitendS3:
+
+#
+# Subroutine which prints a given text to the SCLP console.
+#
+# Parameters:
+# R2 = address of nil-terminated ASCII text
+#
+# Returns:
+# R2 = 0 on success, 1 on failure
+#
+
+_sclp_print:
+ stm %r6,%r15,24(%r15) # save registers
+ ahi %r15,-96 # create stack frame
+ basr %r13,0 # get base register
+.LbaseS4:
+ l %r8,.LsccbS0-.LbaseS4(%r13) # prepare write data sccb
+ mvc 0(.LmtoS4-.LwritesccbS4,%r8),.LwritesccbS4-.LbaseS4(%r13)
+ la %r7,.LmtoS4-.LwritesccbS4(%r8) # current mto addr
+ sr %r0,%r0
+ l %r10,.Lascebc-.LbaseS4(%r13) # address of translation table
+.LinitmtoS4:
+ # initialize mto
+ mvc 0(.LmtoendS4-.LmtoS4,%r7),.LmtoS4-.LbaseS4(%r13)
+ lhi %r6,.LmtoendS4-.LmtoS4 # current mto length
+.LloopS4:
+ ic %r0,0(%r2) # get character
+ ahi %r2,1
+ ltr %r0,%r0 # end of string?
+ jz .LfinalizemtoS4
+ chi %r0,0x15 # end of line (NL)?
+ jz .LfinalizemtoS4
+ stc %r0,0(%r6,%r7) # copy to mto
+ la %r11,0(%r6,%r7)
+ tr 0(1,%r11),0(%r10) # translate to EBCDIC
+ ahi %r6,1
+ j .LloopS4
+.LfinalizemtoS4:
+ sth %r6,0(%r7) # update mto length
+ lh %r9,.LmdbS4-.LwritesccbS4(%r8) # update mdb length
+ ar %r9,%r6
+ sth %r9,.LmdbS4-.LwritesccbS4(%r8)
+ lh %r9,.LevbufS4-.LwritesccbS4(%r8)# update evbuf length
+ ar %r9,%r6
+ sth %r9,.LevbufS4-.LwritesccbS4(%r8)
+ lh %r9,0(%r8) # update sccb length
+ ar %r9,%r6
+ sth %r9,0(%r8)
+ ar %r7,%r6 # update current mto adress
+ ltr %r0,%r0 # more characters?
+ jnz .LinitmtoS4
+ l %r2,.LwritedataS4-.LbaseS4(%r13)# write data
+ lr %r3,%r8
+ bras %r14,_sclp_servc
+ ltr %r2,%r2 # servc successful?
+ jnz .LendS4
+ chi %r3,0x20 # write data successful?
+ je .LendS4
+ lhi %r2,1 # error return code
+.LendS4:
+ lm %r6,%r15,120(%r15) # restore registers
+ br %r14
+
+#
+# Function which prints a given text to the SCLP console.
+#
+# Parameters:
+# R2 = address of nil-terminated ASCII text
+#
+# Returns:
+# R2 = 0 on success, 1 on failure
+#
+
+ .globl _sclp_print_early
+_sclp_print_early:
+ stm %r6,%r15,24(%r15) # save registers
+ ahi %r15,-96 # create stack frame
+ lr %r10,%r2 # save string pointer
+ lhi %r2,0
+ bras %r14,_sclp_setup # enable console
+ ltr %r2,%r2
+ jnz .LendS5
+ lr %r2,%r10
+ bras %r14,_sclp_print # print string
+ ltr %r2,%r2
+ jnz .LendS5
+ lhi %r2,1
+ bras %r14,_sclp_setup # disable console
+.LendS5:
+ lm %r6,%r15,120(%r15) # restore registers
+ br %r14
+
+.LwritedataS4:
+ .long 0x00760005 # SCLP command for write data
+.LwritesccbS4:
+ # sccb
+ .word .LmtoS4-.LwritesccbS4
+ .byte 0
+ .byte 0,0,0
+ .word 0
+
+ # evbuf
+.LevbufS4:
+ .word .LmtoS4-.LevbufS4
+ .byte 0x02
+ .byte 0
+ .word 0
+
+.LmdbS4:
+ # mdb
+ .word .LmtoS4-.LmdbS4
+ .word 1
+ .long 0xd4c4c240
+ .long 1
+
+ # go
+.LgoS4:
+ .word .LmtoS4-.LgoS4
+ .word 1
+ .long 0
+ .byte 0,0,0,0,0,0,0,0
+ .byte 0,0,0
+ .byte 0
+ .byte 0,0,0,0,0,0,0
+ .byte 0
+ .word 0
+ .byte 0,0,0,0,0,0,0,0,0,0
+ .byte 0,0,0,0,0,0,0,0
+ .byte 0,0,0,0,0,0,0,0
+
+.LmtoS4:
+ .word .LmtoendS4-.LmtoS4
+ .word 4
+ .word 0x1000
+ .byte 0
+ .byte 0,0,0
+.LmtoendS4:
+
+ # Global constants
+.LsccbS0:
+ .long _sclp_work_area
+.Lascebc:
+ .long _ascebc
+.previous
+
+.section ".init.data","a"
+ .balign 4096
+_sclp_work_area:
+ .fill 4096
+.previous
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 3cf74c3ccb69..062bd64e65fa 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -26,6 +26,7 @@
#include <linux/binfmts.h>
#include <linux/tracehook.h>
#include <linux/syscalls.h>
+#include <linux/compat.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
#include <asm/lowcore.h>
@@ -482,7 +483,7 @@ void do_signal(struct pt_regs *regs)
/* Whee! Actually deliver the signal. */
int ret;
#ifdef CONFIG_COMPAT
- if (test_thread_flag(TIF_31BIT)) {
+ if (is_compat_task()) {
ret = handle_signal32(signr, &ka, &info, oldset, regs);
}
else
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index a985a3ba4401..0af302ceac2d 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -47,7 +47,7 @@
#include <asm/timer.h>
#include <asm/lowcore.h>
#include <asm/sclp.h>
-#include <asm/cpu.h>
+#include <asm/cputime.h>
#include <asm/vdso.h>
#include "entry.h"
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 89b2e7f1b7a9..75b2d83085ce 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -22,7 +22,7 @@
#include <linux/elf.h>
#include <linux/security.h>
#include <linux/bootmem.h>
-
+#include <linux/compat.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/processor.h>
@@ -53,8 +53,16 @@ unsigned int __read_mostly vdso_enabled = 1;
static int __init vdso_setup(char *s)
{
- vdso_enabled = simple_strtoul(s, NULL, 0);
- return 1;
+ int rc;
+
+ rc = 0;
+ if (strncmp(s, "on", 3) == 0)
+ vdso_enabled = 1;
+ else if (strncmp(s, "off", 4) == 0)
+ vdso_enabled = 0;
+ else
+ rc = strict_strtoul(s, 0, &vdso_enabled);
+ return !rc;
}
__setup("vdso=", vdso_setup);
@@ -203,7 +211,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
vdso_pagelist = vdso64_pagelist;
vdso_pages = vdso64_pages;
#ifdef CONFIG_COMPAT
- if (test_thread_flag(TIF_31BIT)) {
+ if (is_compat_task()) {
vdso_pagelist = vdso32_pagelist;
vdso_pages = vdso32_pages;
}
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index c87f59bd8246..c8eb7255332b 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -23,7 +23,7 @@
#include <asm/s390_ext.h>
#include <asm/timer.h>
#include <asm/irq_regs.h>
-#include <asm/cpu.h>
+#include <asm/cputime.h>
static ext_int_info_t ext_int_info_timer;
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 0189356fe209..4ed4c3a11485 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -318,6 +318,12 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
return rc;
}
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
+{
+ /* do real check here */
+ return 1;
+}
+
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
{
return 0;
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index e41f4008afc5..f7e0d30250b7 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -124,6 +124,27 @@ void _raw_read_lock_wait(raw_rwlock_t *rw)
}
EXPORT_SYMBOL(_raw_read_lock_wait);
+void _raw_read_lock_wait_flags(raw_rwlock_t *rw, unsigned long flags)
+{
+ unsigned int old;
+ int count = spin_retry;
+
+ local_irq_restore(flags);
+ while (1) {
+ if (count-- <= 0) {
+ _raw_yield();
+ count = spin_retry;
+ }
+ if (!__raw_read_can_lock(rw))
+ continue;
+ old = rw->lock & 0x7fffffffU;
+ local_irq_disable();
+ if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
+ return;
+ }
+}
+EXPORT_SYMBOL(_raw_read_lock_wait_flags);
+
int _raw_read_trylock_retry(raw_rwlock_t *rw)
{
unsigned int old;
@@ -157,6 +178,25 @@ void _raw_write_lock_wait(raw_rwlock_t *rw)
}
EXPORT_SYMBOL(_raw_write_lock_wait);
+void _raw_write_lock_wait_flags(raw_rwlock_t *rw, unsigned long flags)
+{
+ int count = spin_retry;
+
+ local_irq_restore(flags);
+ while (1) {
+ if (count-- <= 0) {
+ _raw_yield();
+ count = spin_retry;
+ }
+ if (!__raw_write_can_lock(rw))
+ continue;
+ local_irq_disable();
+ if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
+ return;
+ }
+}
+EXPORT_SYMBOL(_raw_write_lock_wait_flags);
+
int _raw_write_trylock_retry(raw_rwlock_t *rw)
{
int count = spin_retry;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 833e8366c351..220a152c836c 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -19,6 +19,7 @@
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
+#include <linux/compat.h>
#include <linux/smp.h>
#include <linux/kdebug.h>
#include <linux/smp_lock.h>
@@ -239,7 +240,7 @@ static int signal_return(struct mm_struct *mm, struct pt_regs *regs,
up_read(&mm->mmap_sem);
clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
#ifdef CONFIG_COMPAT
- compat = test_tsk_thread_flag(current, TIF_31BIT);
+ compat = is_compat_task();
if (compat && instruction == 0x0a77)
sys32_sigreturn();
else if (compat && instruction == 0x0aad)
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index e008d236cc15..f4558ccf02b9 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -28,6 +28,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/pgalloc.h>
+#include <asm/compat.h>
/*
* Top of mmap area (just below the process stack).
@@ -55,7 +56,7 @@ static inline int mmap_is_legacy(void)
/*
* Force standard allocation for 64 bit programs.
*/
- if (!test_thread_flag(TIF_31BIT))
+ if (!is_compat_task())
return 1;
#endif
return sysctl_legacy_va_layout ||
@@ -91,7 +92,7 @@ EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
int s390_mmap_check(unsigned long addr, unsigned long len)
{
- if (!test_thread_flag(TIF_31BIT) &&
+ if (!is_compat_task() &&
len >= TASK_SIZE && TASK_SIZE < (1UL << 53))
return crst_table_upgrade(current->mm, 1UL << 53);
return 0;
@@ -108,8 +109,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr,
area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
if (!(area & ~PAGE_MASK))
return area;
- if (area == -ENOMEM &&
- !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) {
+ if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
/* Upgrade the page table to 4 levels and retry. */
rc = crst_table_upgrade(mm, 1UL << 53);
if (rc)
@@ -131,8 +131,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr,
area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags);
if (!(area & ~PAGE_MASK))
return area;
- if (area == -ENOMEM &&
- !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) {
+ if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
/* Upgrade the page table to 4 levels and retry. */
rc = crst_table_upgrade(mm, 1UL << 53);
if (rc)
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index e7390dd0283d..fb75c2d1928d 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -15,6 +15,7 @@ config SUPERH
select HAVE_IOREMAP_PROT if MMU
select HAVE_ARCH_TRACEHOOK
select HAVE_DMA_API_DEBUG
+ select RTC_LIB
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
@@ -74,14 +75,18 @@ config GENERIC_IOMAP
bool
config GENERIC_TIME
- def_bool n
+ def_bool y
config GENERIC_CLOCKEVENTS
- def_bool n
+ def_bool y
config GENERIC_CLOCKEVENTS_BROADCAST
bool
+config GENERIC_CMOS_UPDATE
+ def_bool y
+ depends on SH_SH03 || SH_DREAMCAST
+
config GENERIC_LOCKBREAK
def_bool y
depends on SMP && PREEMPT
@@ -112,6 +117,12 @@ config SYS_SUPPORTS_PCI
config SYS_SUPPORTS_CMT
bool
+config SYS_SUPPORTS_MTU2
+ bool
+
+config SYS_SUPPORTS_TMU
+ bool
+
config STACKTRACE_SUPPORT
def_bool y
@@ -157,6 +168,7 @@ config CPU_SH3
bool
select CPU_HAS_INTEVT
select CPU_HAS_SR_RB
+ select SYS_SUPPORTS_TMU
config CPU_SH4
bool
@@ -164,6 +176,7 @@ config CPU_SH4
select CPU_HAS_SR_RB
select CPU_HAS_PTEA if !CPU_SH4A || CPU_SHX2
select CPU_HAS_FPU if !CPU_SH4AL_DSP
+ select SYS_SUPPORTS_TMU
config CPU_SH4A
bool
@@ -177,6 +190,7 @@ config CPU_SH4AL_DSP
config CPU_SH5
bool
select CPU_HAS_FPU
+ select SYS_SUPPORTS_TMU
config CPU_SHX2
bool
@@ -210,27 +224,32 @@ config CPU_SUBTYPE_SH7201
bool "Support SH7201 processor"
select CPU_SH2A
select CPU_HAS_FPU
+ select SYS_SUPPORTS_MTU2
config CPU_SUBTYPE_SH7203
bool "Support SH7203 processor"
select CPU_SH2A
select CPU_HAS_FPU
select SYS_SUPPORTS_CMT
+ select SYS_SUPPORTS_MTU2
config CPU_SUBTYPE_SH7206
bool "Support SH7206 processor"
select CPU_SH2A
select SYS_SUPPORTS_CMT
+ select SYS_SUPPORTS_MTU2
config CPU_SUBTYPE_SH7263
bool "Support SH7263 processor"
select CPU_SH2A
select CPU_HAS_FPU
select SYS_SUPPORTS_CMT
+ select SYS_SUPPORTS_MTU2
config CPU_SUBTYPE_MXG
bool "Support MX-G processor"
select CPU_SH2A
+ select SYS_SUPPORTS_MTU2
help
Select MX-G if running on an R8A03022BG part.
@@ -283,6 +302,7 @@ config CPU_SUBTYPE_SH7720
bool "Support SH7720 processor"
select CPU_SH3
select CPU_HAS_DSP
+ select SYS_SUPPORTS_CMT
help
Select SH7720 if you have a SH3-DSP SH7720 CPU.
@@ -290,6 +310,7 @@ config CPU_SUBTYPE_SH7721
bool "Support SH7721 processor"
select CPU_SH3
select CPU_HAS_DSP
+ select SYS_SUPPORTS_CMT
help
Select SH7721 if you have a SH3-DSP SH7721 CPU.
@@ -347,6 +368,16 @@ config CPU_SUBTYPE_SH7723
help
Select SH7723 if you have an SH-MobileR2 CPU.
+config CPU_SUBTYPE_SH7724
+ bool "Support SH7724 processor"
+ select CPU_SH4A
+ select CPU_SHX2
+ select ARCH_SHMOBILE
+ select ARCH_SPARSEMEM_ENABLE
+ select SYS_SUPPORTS_CMT
+ help
+ Select SH7724 if you have an SH-MobileR2R CPU.
+
config CPU_SUBTYPE_SH7763
bool "Support SH7763 processor"
select CPU_SH4A
@@ -442,48 +473,26 @@ source "arch/sh/boards/Kconfig"
menu "Timer and clock configuration"
-config SH_TMU
- bool "TMU timer support"
- depends on CPU_SH3 || CPU_SH4
+config SH_TIMER_TMU
+ bool "TMU timer driver"
+ depends on SYS_SUPPORTS_TMU
default y
- select GENERIC_TIME
- select GENERIC_CLOCKEVENTS
help
- This enables the use of the TMU as the system timer.
+ This enables the build of the TMU timer driver.
-config SH_CMT
- bool "CMT timer support"
- depends on SYS_SUPPORTS_CMT && CPU_SH2
+config SH_TIMER_CMT
+ bool "CMT timer driver"
+ depends on SYS_SUPPORTS_CMT
default y
help
- This enables the use of the CMT as the system timer.
-
-#
-# Support for the new-style CMT driver. This will replace SH_CMT
-# once its other dependencies are merged.
-#
-config SH_TIMER_CMT
- bool "CMT clockevents driver"
- depends on SYS_SUPPORTS_CMT && !SH_CMT
- select GENERIC_CLOCKEVENTS
+ This enables build of the CMT timer driver.
-config SH_MTU2
- bool "MTU2 timer support"
- depends on CPU_SH2A
+config SH_TIMER_MTU2
+ bool "MTU2 timer driver"
+ depends on SYS_SUPPORTS_MTU2
default y
help
- This enables the use of the MTU2 as the system timer.
-
-config SH_TIMER_IRQ
- int
- default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 || \
- CPU_SUBTYPE_SH7763
- default "86" if CPU_SUBTYPE_SH7619
- default "140" if CPU_SUBTYPE_SH7206
- default "142" if CPU_SUBTYPE_SH7203 && SH_CMT
- default "153" if CPU_SUBTYPE_SH7203 && SH_MTU2
- default "238" if CPU_SUBTYPE_MXG
- default "16"
+ This enables build of the MTU2 timer driver.
config SH_PCLK_FREQ
int "Peripheral clock frequency (in Hz)"
@@ -495,6 +504,7 @@ config SH_PCLK_FREQ
CPU_SUBTYPE_SH7203 || CPU_SUBTYPE_SH7206 || \
CPU_SUBTYPE_SH7263 || CPU_SUBTYPE_MXG || \
CPU_SUBTYPE_SH7786
+ default "41666666" if CPU_SUBTYPE_SH7724
default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R
default "66000000" if CPU_SUBTYPE_SH4_202
default "50000000"
@@ -668,22 +678,37 @@ endmenu
menu "Boot options"
config ZERO_PAGE_OFFSET
- hex "Zero page offset"
- default "0x00004000" if SH_SH03
- default "0x00010000" if PAGE_SIZE_64KB
+ hex
+ default "0x00010000" if PAGE_SIZE_64KB || SH_RTS7751R2D || \
+ SH_7751_SOLUTION_ENGINE
+ default "0x00004000" if PAGE_SIZE_16KB || SH_SH03
default "0x00002000" if PAGE_SIZE_8KB
default "0x00001000"
help
This sets the default offset of zero page.
config BOOT_LINK_OFFSET
- hex "Link address offset for booting"
+ hex
+ default "0x00210000" if SH_SHMIN
+ default "0x00400000" if SH_CAYMAN
+ default "0x00810000" if SH_7780_SOLUTION_ENGINE
+ default "0x009e0000" if SH_TITAN
+ default "0x01800000" if SH_SDK7780
+ default "0x02000000" if SH_EDOSK7760
default "0x00800000"
help
This option allows you to set the link address offset of the zImage.
This can be useful if you are on a board which has a small amount of
memory.
+config ENTRY_OFFSET
+ hex
+ default "0x00001000" if PAGE_SIZE_4KB
+ default "0x00002000" if PAGE_SIZE_8KB
+ default "0x00004000" if PAGE_SIZE_16KB
+ default "0x00010000" if PAGE_SIZE_64KB
+ default "0x00000000"
+
config UBC_WAKEUP
bool "Wakeup UBC on startup"
depends on CPU_SH4 && !CPU_SH4A
diff --git a/arch/sh/Kconfig.cpu b/arch/sh/Kconfig.cpu
index c7d704381a6d..9eb1712372d8 100644
--- a/arch/sh/Kconfig.cpu
+++ b/arch/sh/Kconfig.cpu
@@ -76,11 +76,6 @@ config SPECULATIVE_EXECUTION
If unsure, say N.
-config SH64_USER_MISALIGNED_FIXUP
- def_bool y
- prompt "Fixup misaligned loads/stores occurring in user mode"
- depends on SUPERH64
-
config SH64_ID2815_WORKAROUND
bool "Include workaround for SH5-101 cut2 silicon defect ID2815"
depends on CPU_SUBTYPE_SH5_101
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 0d62681f72a0..8179cc9be9a4 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -38,10 +38,10 @@ config EARLY_SCIF_CONSOLE_PORT
default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \
CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \
CPU_SUBTYPE_SH7343
- default "0xffe80000" if CPU_SH4
default "0xffea0000" if CPU_SUBTYPE_SH7785
default "0xfffe8000" if CPU_SUBTYPE_SH7203
default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263
+ default "0xffe80000" if CPU_SH4
default "0x00000000"
config EARLY_PRINTK
@@ -92,7 +92,7 @@ config 4KSTACKS
config IRQSTACKS
bool "Use separate kernel stacks when processing interrupts"
- depends on DEBUG_KERNEL && SUPERH32
+ depends on DEBUG_KERNEL && SUPERH32 && BROKEN
help
If you say Y here the kernel will use separate kernel stacks
for handling hard and soft interrupts. This can help avoid
@@ -122,27 +122,8 @@ config SH_NO_BSS_INIT
For all other cases, say N. If this option seems perplexing, or
you aren't sure, say N.
-config MORE_COMPILE_OPTIONS
- bool "Add any additional compile options"
- help
- If you want to add additional CFLAGS to the kernel build, enable this
- option and then enter what you would like to add in the next question.
- Note however that -g is already appended with the selection of KGDB.
-
-config COMPILE_OPTIONS
- string "Additional compile arguments"
- depends on MORE_COMPILE_OPTIONS
-
config SH64_SR_WATCH
bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
depends on SUPERH64
-config POOR_MANS_STRACE
- bool "Debug: enable rudimentary strace facility"
- depends on SUPERH64
- help
- This option allows system calls to be traced to the console. It also
- aids in detecting kernel stack underflow. It is useful for debugging
- early-userland problems (e.g. init incurring fatal exceptions.)
-
endmenu
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index bece1f7535f2..a47fbd260ba4 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -70,9 +70,6 @@ cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
cflags-y += $(call cc-option,-mno-fdpic)
cflags-y += $(isaflags-y) -ffreestanding
-cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \
- $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
-
OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment \
-R .stab -R .stabstr -S
@@ -94,25 +91,35 @@ KBUILD_IMAGE := $(defaultimage-y)
#
ifdef CONFIG_SUPERH32
UTS_MACHINE := sh
+BITS := 32
LDFLAGS_vmlinux += -e _stext
else
UTS_MACHINE := sh64
+BITS := 64
LDFLAGS_vmlinux += --defsym phys_stext=_stext-$(CONFIG_PAGE_OFFSET) \
--defsym phys_stext_shmedia=phys_stext+1 \
-e phys_stext_shmedia
endif
+ifneq ($(SUBARCH),$(ARCH))
+ ifeq ($(CROSS_COMPILE),)
+ CROSS_COMPILE := $(call cc-cross-prefix, $(UTS_MACHINE)-linux- $(UTS_MACHINE)-linux-gnu- $(UTS_MACHINE)-unknown-linux-gnu-)
+ endif
+endif
+
ifdef CONFIG_CPU_LITTLE_ENDIAN
-LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64'
+ld-bfd := elf32-$(UTS_MACHINE)-linux
+LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64' --oformat $(ld-bfd)
LDFLAGS += -EL
else
-LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64+4'
+ld-bfd := elf32-$(UTS_MACHINE)big-linux
+LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64+4' --oformat $(ld-bfd)
LDFLAGS += -EB
endif
-head-y := arch/sh/kernel/init_task.o
-head-$(CONFIG_SUPERH32) += arch/sh/kernel/head_32.o
-head-$(CONFIG_SUPERH64) += arch/sh/kernel/head_64.o
+export ld-bfd BITS
+
+head-y := arch/sh/kernel/init_task.o arch/sh/kernel/head_$(BITS).o
core-y += arch/sh/kernel/ arch/sh/mm/ arch/sh/boards/
core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/
@@ -193,7 +200,7 @@ zImage uImage uImage.srec vmlinux.srec: vmlinux
compressed: zImage
-archprepare: maketools arch/sh/lib64/syscalltab.h
+archprepare: maketools
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
@@ -205,34 +212,4 @@ define archhelp
@echo ' uImage.srec - Create an S-record for U-Boot'
endef
-define filechk_gen-syscalltab
- (set -e; \
- echo "/*"; \
- echo " * DO NOT MODIFY."; \
- echo " *"; \
- echo " * This file was generated by arch/sh/Makefile"; \
- echo " * Any changes will be reverted at build time."; \
- echo " */"; \
- echo ""; \
- echo "#ifndef __SYSCALLTAB_H"; \
- echo "#define __SYSCALLTAB_H"; \
- echo ""; \
- echo "#include <linux/kernel.h>"; \
- echo ""; \
- echo "struct syscall_info {"; \
- echo " const char *name;"; \
- echo "} syscall_info_table[] = {"; \
- sed -e '/^.*\.long /!d;s// { "/;s/\(\([^/]*\)\/\)\{1\}.*/\2/; \
- s/[ \t]*$$//g;s/$$/" },/;s/\("\)sys_/\1/g'; \
- echo "};"; \
- echo ""; \
- echo "#define NUM_SYSCALL_INFO_ENTRIES ARRAY_SIZE(syscall_info_table)";\
- echo ""; \
- echo "#endif /* __SYSCALLTAB_H */" )
-endef
-
-arch/sh/lib64/syscalltab.h: arch/sh/kernel/syscalls_64.S
- $(call filechk,gen-syscalltab)
-
-CLEAN_FILES += arch/sh/lib64/syscalltab.h \
- include/asm-sh/machtypes.h
+CLEAN_FILES += include/asm-sh/machtypes.h
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index dcc1af8a2cfe..99e2d47f79f5 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -121,7 +121,7 @@ config SH_RTS7751R2D
bool "RTS7751R2D"
depends on CPU_SUBTYPE_SH7751R
select SYS_SUPPORTS_PCI
- select IO_TRAPPED
+ select IO_TRAPPED if MMU
help
Select RTS7751R2D if configuring for a Renesas Technology
Sales SH-Graphics board.
@@ -145,13 +145,13 @@ config SH_HIGHLANDER
bool "Highlander"
depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
select SYS_SUPPORTS_PCI
- select IO_TRAPPED
+ select IO_TRAPPED if MMU
config SH_SH7785LCR
bool "SH7785LCR"
depends on CPU_SUBTYPE_SH7785
select SYS_SUPPORTS_PCI
- select IO_TRAPPED
+ select IO_TRAPPED if MMU
config SH_SH7785LCR_29BIT_PHYSMAPS
bool "SH7785LCR 29bit physmaps"
diff --git a/arch/sh/boards/mach-cayman/Makefile b/arch/sh/boards/mach-cayman/Makefile
index cafe1ac3b29c..00fa3eaecb1b 100644
--- a/arch/sh/boards/mach-cayman/Makefile
+++ b/arch/sh/boards/mach-cayman/Makefile
@@ -1,4 +1,4 @@
#
# Makefile for the Hitachi Cayman specific parts of the kernel
#
-obj-y := setup.o irq.o
+obj-y := setup.o irq.o panic.o
diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c
index da62ad516994..33f770856319 100644
--- a/arch/sh/boards/mach-cayman/irq.c
+++ b/arch/sh/boards/mach-cayman/irq.c
@@ -142,26 +142,11 @@ int cayman_irq_demux(int evt)
return irq;
}
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
-int cayman_irq_describe(char* p, int irq)
-{
- if (irq < NR_INTC_IRQS) {
- return intc_irq_describe(p, irq);
- } else if (irq < NR_INTC_IRQS + 8) {
- return sprintf(p, "(SMSC %d)", irq - NR_INTC_IRQS);
- } else if ((irq >= NR_INTC_IRQS + 24) && (irq < NR_INTC_IRQS + 32)) {
- return sprintf(p, "(PCI2 %d)", irq - (NR_INTC_IRQS + 24));
- }
-
- return 0;
-}
-#endif
-
void init_cayman_irq(void)
{
int i;
- epld_virt = onchip_remap(EPLD_BASE, 1024, "EPLD");
+ epld_virt = (unsigned long)ioremap_nocache(EPLD_BASE, 1024);
if (!epld_virt) {
printk(KERN_ERR "Cayman IRQ: Unable to remap EPLD\n");
return;
diff --git a/arch/sh/boards/mach-cayman/panic.c b/arch/sh/boards/mach-cayman/panic.c
new file mode 100644
index 000000000000..d1e67306d07c
--- /dev/null
+++ b/arch/sh/boards/mach-cayman/panic.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2003 Richard Curnow, SuperH UK Limited
+ *
+ * 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/kernel.h>
+#include <linux/io.h>
+#include <cpu/registers.h>
+
+/* THIS IS A PHYSICAL ADDRESS */
+#define HDSP2534_ADDR (0x04002100)
+
+static void poor_mans_delay(void)
+{
+ int i;
+
+ for (i = 0; i < 2500000; i++)
+ cpu_relax();
+}
+
+static void show_value(unsigned long x)
+{
+ int i;
+ unsigned nibble;
+ for (i = 0; i < 8; i++) {
+ nibble = ((x >> (i * 4)) & 0xf);
+
+ __raw_writeb(nibble + ((nibble > 9) ? 55 : 48),
+ HDSP2534_ADDR + 0xe0 + ((7 - i) << 2));
+ }
+}
+
+void
+panic_handler(unsigned long panicPC, unsigned long panicSSR,
+ unsigned long panicEXPEVT)
+{
+ while (1) {
+ /* This piece of code displays the PC on the LED display */
+ show_value(panicPC);
+ poor_mans_delay();
+ show_value(panicSSR);
+ poor_mans_delay();
+ show_value(panicEXPEVT);
+ poor_mans_delay();
+ }
+}
diff --git a/arch/sh/boards/mach-cayman/setup.c b/arch/sh/boards/mach-cayman/setup.c
index e7f9cc5f2ff1..7e8216ac31bd 100644
--- a/arch/sh/boards/mach-cayman/setup.c
+++ b/arch/sh/boards/mach-cayman/setup.c
@@ -102,7 +102,7 @@ static int __init smsc_superio_setup(void)
{
unsigned char devid, devrev;
- smsc_superio_virt = onchip_remap(SMSC_SUPERIO_BASE, 1024, "SMSC SuperIO");
+ smsc_superio_virt = (unsigned long)ioremap_nocache(SMSC_SUPERIO_BASE, 1024);
if (!smsc_superio_virt) {
panic("Unable to remap SMSC SuperIO\n");
}
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
index d1bee4884cd6..ebe99227d4e6 100644
--- a/arch/sh/boards/mach-dreamcast/setup.c
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -30,7 +30,6 @@
extern struct irq_chip systemasic_int;
extern void aica_time_init(void);
-extern int gapspci_init(void);
extern int systemasic_irq_demux(int);
static void __init dreamcast_setup(char **cmdline_p)
@@ -51,11 +50,6 @@ static void __init dreamcast_setup(char **cmdline_p)
handle_level_irq);
board_time_init = aica_time_init;
-
-#ifdef CONFIG_PCI
- if (gapspci_init() < 0)
- printk(KERN_WARNING "GAPSPCI was not detected.\n");
-#endif
}
static struct sh_machine_vector mv_dreamcast __initmv = {
diff --git a/arch/sh/boards/mach-r2d/setup.c b/arch/sh/boards/mach-r2d/setup.c
index c585be00956e..a625ecb93e47 100644
--- a/arch/sh/boards/mach-r2d/setup.c
+++ b/arch/sh/boards/mach-r2d/setup.c
@@ -10,6 +10,9 @@
*/
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
#include <linux/ata_platform.h>
#include <linux/sm501.h>
#include <linux/sm501-regs.h>
@@ -181,6 +184,50 @@ static struct platform_device sm501_device = {
.resource = sm501_resources,
};
+static struct mtd_partition r2d_partitions[] = {
+ {
+ .name = "U-Boot",
+ .offset = 0x00000000,
+ .size = 0x00040000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "Environment",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 0x00040000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 0x001c0000,
+ }, {
+ .name = "Flash_FS",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct physmap_flash_data flash_data = {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(r2d_partitions),
+ .parts = r2d_partitions,
+};
+
+static struct resource flash_resource = {
+ .start = 0x00000000,
+ .end = 0x02000000,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = &flash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &flash_data,
+ },
+};
+
static struct platform_device *rts7751r2d_devices[] __initdata = {
&sm501_device,
&heartbeat_device,
@@ -203,6 +250,9 @@ static int __init rts7751r2d_devices_setup(void)
if (register_trapped_io(&cf_trapped_io) == 0)
platform_device_register(&cf_ide_device);
+ if (mach_is_r2d_plus())
+ platform_device_register(&flash_device);
+
spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
return platform_add_devices(rts7751r2d_devices,
diff --git a/arch/sh/boards/mach-se/7751/Makefile b/arch/sh/boards/mach-se/7751/Makefile
index dbc29f3a9de5..e6f4341bfe6e 100644
--- a/arch/sh/boards/mach-se/7751/Makefile
+++ b/arch/sh/boards/mach-se/7751/Makefile
@@ -3,5 +3,3 @@
#
obj-y := setup.o io.o irq.o
-
-obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/sh/boards/mach-se/7751/io.c b/arch/sh/boards/mach-se/7751/io.c
index 6287ae570319..6e75bd4459e5 100644
--- a/arch/sh/boards/mach-se/7751/io.c
+++ b/arch/sh/boards/mach-se/7751/io.c
@@ -34,8 +34,6 @@ unsigned char sh7751se_inb(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned char *)port;
- else if (is_pci_ioaddr(port))
- return *(volatile unsigned char *)pci_ioaddr(port);
else
return (*port2adr(port)) & 0xff;
}
@@ -46,8 +44,6 @@ unsigned char sh7751se_inb_p(unsigned long port)
if (PXSEG(port))
v = *(volatile unsigned char *)port;
- else if (is_pci_ioaddr(port))
- v = *(volatile unsigned char *)pci_ioaddr(port);
else
v = (*port2adr(port)) & 0xff;
ctrl_delay();
@@ -58,8 +54,6 @@ unsigned short sh7751se_inw(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned short *)port;
- else if (is_pci_ioaddr(port))
- return *(volatile unsigned short *)pci_ioaddr(port);
else if (port >= 0x2000)
return *port2adr(port);
else
@@ -71,8 +65,6 @@ unsigned int sh7751se_inl(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned long *)port;
- else if (is_pci_ioaddr(port))
- return *(volatile unsigned int *)pci_ioaddr(port);
else if (port >= 0x2000)
return *port2adr(port);
else
@@ -85,8 +77,6 @@ void sh7751se_outb(unsigned char value, unsigned long port)
if (PXSEG(port))
*(volatile unsigned char *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned char*)pci_ioaddr(port)) = value;
else
*(port2adr(port)) = value;
}
@@ -95,8 +85,6 @@ void sh7751se_outb_p(unsigned char value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned char *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned char*)pci_ioaddr(port)) = value;
else
*(port2adr(port)) = value;
ctrl_delay();
@@ -106,8 +94,6 @@ void sh7751se_outw(unsigned short value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned short *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned short *)pci_ioaddr(port)) = value;
else if (port >= 0x2000)
*port2adr(port) = value;
else
@@ -118,8 +104,6 @@ void sh7751se_outl(unsigned int value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned long *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned long*)pci_ioaddr(port)) = value;
else
maybebadio(port);
}
diff --git a/arch/sh/boards/mach-se/7751/pci.c b/arch/sh/boards/mach-se/7751/pci.c
deleted file mode 100644
index 203b2923fe7f..000000000000
--- a/arch/sh/boards/mach-se/7751/pci.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * linux/arch/sh/boards/se/7751/pci.c
- *
- * Author: Ian DaSilva (idasilva@mvista.com)
- *
- * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * PCI initialization for the Hitachi SH7751 Solution Engine board (MS7751SE01)
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
-#include <asm/io.h>
-#include "../../../drivers/pci/pci-sh7751.h"
-
-#define PCIMCR_MRSET_OFF 0xBFFFFFFF
-#define PCIMCR_RFSH_OFF 0xFFFFFFFB
-
-/*
- * Only long word accesses of the PCIC's internal local registers and the
- * configuration registers from the CPU is supported.
- */
-#define PCIC_WRITE(x,v) writel((v), PCI_REG(x))
-#define PCIC_READ(x) readl(PCI_REG(x))
-
-/*
- * Description: This function sets up and initializes the pcic, sets
- * up the BARS, maps the DRAM into the address space etc, etc.
- */
-int __init pcibios_init_platform(void)
-{
- unsigned long bcr1, wcr1, wcr2, wcr3, mcr;
- unsigned short bcr2;
-
- /*
- * Initialize the slave bus controller on the pcic. The values used
- * here should not be hardcoded, but they should be taken from the bsc
- * on the processor, to make this function as generic as possible.
- * (i.e. Another sbc may usr different SDRAM timing settings -- in order
- * for the pcic to work, its settings need to be exactly the same.)
- */
- bcr1 = (*(volatile unsigned long*)(SH7751_BCR1));
- bcr2 = (*(volatile unsigned short*)(SH7751_BCR2));
- wcr1 = (*(volatile unsigned long*)(SH7751_WCR1));
- wcr2 = (*(volatile unsigned long*)(SH7751_WCR2));
- wcr3 = (*(volatile unsigned long*)(SH7751_WCR3));
- mcr = (*(volatile unsigned long*)(SH7751_MCR));
-
- bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */
- (*(volatile unsigned long*)(SH7751_BCR1)) = bcr1;
-
- bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
- PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */
- PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */
- PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */
- PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */
- PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */
- mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
- PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */
-
-
- /* Enable all interrupts, so we know what to fix */
- PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff);
- PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f);
-
- /* Set up standard PCI config registers */
- PCIC_WRITE(SH7751_PCICONF1, 0xF39000C7); /* Bus Master, Mem & I/O access */
- PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */
- PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */
- PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */
- PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */
- PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */
- PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */
- PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */
- PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */
- PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */
-
- /* Now turn it on... */
- PCIC_WRITE(SH7751_PCICR, 0xa5000001);
-
- /*
- * Set PCIMBR and PCIIOBR here, assuming a single window
- * (16M MEM, 256K IO) is enough. If a larger space is
- * needed, the readx/writex and inx/outx functions will
- * have to do more (e.g. setting registers for each call).
- */
-
- /*
- * Set the MBR so PCI address is one-to-one with window,
- * meaning all calls go straight through... use BUG_ON to
- * catch erroneous assumption.
- */
- BUG_ON(PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE);
-
- PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM);
-
- /* Set IOBR for window containing area specified in pci.h */
- PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK));
-
- /* All done, may as well say so... */
- printk("SH7751 PCI: Finished initialization of the PCI controller\n");
-
- return 1;
-}
-
-int __init pcibios_map_platform_irq(u8 slot, u8 pin)
-{
- switch (slot) {
- case 0: return 13;
- case 1: return 13; /* AMD Ethernet controller */
- case 2: return -1;
- case 3: return -1;
- case 4: return -1;
- default:
- printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
- return -1;
- }
-}
-
-static struct resource sh7751_io_resource = {
- .name = "SH7751 IO",
- .start = SH7751_PCI_IO_BASE,
- .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource sh7751_mem_resource = {
- .name = "SH7751 mem",
- .start = SH7751_PCI_MEMORY_BASE,
- .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
-};
-
-extern struct pci_ops sh7751_pci_ops;
-
-struct pci_channel board_pci_channels[] = {
- { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
- { NULL, NULL, NULL, 0, 0 },
-};
-
diff --git a/arch/sh/boards/mach-se/7780/irq.c b/arch/sh/boards/mach-se/7780/irq.c
index 66ad292c9fc3..b8d43b638fcf 100644
--- a/arch/sh/boards/mach-se/7780/irq.c
+++ b/arch/sh/boards/mach-se/7780/irq.c
@@ -12,10 +12,13 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
-#include <asm/irq.h>
-#include <asm/io.h>
+#include <linux/irq.h>
+#include <linux/io.h>
#include <mach-se/mach/se7780.h>
+#define INTC_BASE 0xffd00000
+#define INTC_ICR1 (INTC_BASE+0x1c)
+
/*
* Initialize IRQ setting
*/
@@ -43,4 +46,24 @@ void __init init_se7780_IRQ(void)
ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3);
plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-7 */
+
+ /* ICR1: detect low level(for 2ndcut) */
+ ctrl_outl(0xAAAA0000, INTC_ICR1);
+
+ /*
+ * FPGA PCISEL register initialize
+ *
+ * CPU || SLOT1 | SLOT2 | S-ATA | USB
+ * -------------------------------------
+ * INTA || INTA | INTD | -- | INTB
+ * -------------------------------------
+ * INTB || INTB | INTA | -- | INTC
+ * -------------------------------------
+ * INTC || INTC | INTB | INTA | --
+ * -------------------------------------
+ * INTD || INTD | INTC | -- | INTA
+ * -------------------------------------
+ */
+ ctrl_outw(0x0013, FPGA_PCI_INTSEL1);
+ ctrl_outw(0xE402, FPGA_PCI_INTSEL2);
}
diff --git a/arch/sh/boards/mach-sh03/rtc.c b/arch/sh/boards/mach-sh03/rtc.c
index 0a9266bb51c5..a8b9f844ab5b 100644
--- a/arch/sh/boards/mach-sh03/rtc.c
+++ b/arch/sh/boards/mach-sh03/rtc.c
@@ -35,13 +35,13 @@
#define RTC_BUSY 1
#define RTC_STOP 2
-extern spinlock_t rtc_lock;
+static DEFINE_SPINLOCK(sh03_rtc_lock);
unsigned long get_cmos_time(void)
{
unsigned int year, mon, day, hour, min, sec;
- spin_lock(&rtc_lock);
+ spin_lock(&sh03_rtc_lock);
again:
do {
sec = (ctrl_inb(RTC_SEC1) & 0xf) + (ctrl_inb(RTC_SEC10) & 0x7) * 10;
@@ -73,7 +73,7 @@ unsigned long get_cmos_time(void)
goto again;
}
- spin_unlock(&rtc_lock);
+ spin_unlock(&sh03_rtc_lock);
return mktime(year, mon, day, hour, min, sec);
}
@@ -91,7 +91,7 @@ static int set_rtc_mmss(unsigned long nowtime)
int i;
/* gets recalled with irq locally disabled */
- spin_lock(&rtc_lock);
+ spin_lock(&sh03_rtc_lock);
for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
if (!(ctrl_inb(RTC_CTL) & RTC_BUSY))
break;
@@ -113,7 +113,7 @@ static int set_rtc_mmss(unsigned long nowtime)
cmos_minutes, real_minutes);
retval = -1;
}
- spin_unlock(&rtc_lock);
+ spin_unlock(&sh03_rtc_lock);
return retval;
}
diff --git a/arch/sh/boards/mach-snapgear/io.c b/arch/sh/boards/mach-snapgear/io.c
index 0f4824264557..476650e42dbc 100644
--- a/arch/sh/boards/mach-snapgear/io.c
+++ b/arch/sh/boards/mach-snapgear/io.c
@@ -36,8 +36,6 @@ unsigned char snapgear_inb(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned char *)port;
- else if (is_pci_ioaddr(port))
- return *(volatile unsigned char *)pci_ioaddr(port);
else
return (*port2adr(port)) & 0xff;
}
@@ -48,8 +46,6 @@ unsigned char snapgear_inb_p(unsigned long port)
if (PXSEG(port))
v = *(volatile unsigned char *)port;
- else if (is_pci_ioaddr(port))
- v = *(volatile unsigned char *)pci_ioaddr(port);
else
v = (*port2adr(port))&0xff;
ctrl_delay();
@@ -60,8 +56,6 @@ unsigned short snapgear_inw(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned short *)port;
- else if (is_pci_ioaddr(port))
- return *(volatile unsigned short *)pci_ioaddr(port);
else if (port >= 0x2000)
return *port2adr(port);
else
@@ -73,8 +67,6 @@ unsigned int snapgear_inl(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned long *)port;
- else if (is_pci_ioaddr(port))
- return *(volatile unsigned int *)pci_ioaddr(port);
else if (port >= 0x2000)
return *port2adr(port);
else
@@ -87,8 +79,6 @@ void snapgear_outb(unsigned char value, unsigned long port)
if (PXSEG(port))
*(volatile unsigned char *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned char*)pci_ioaddr(port)) = value;
else
*(port2adr(port)) = value;
}
@@ -97,8 +87,6 @@ void snapgear_outb_p(unsigned char value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned char *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned char*)pci_ioaddr(port)) = value;
else
*(port2adr(port)) = value;
ctrl_delay();
@@ -108,8 +96,6 @@ void snapgear_outw(unsigned short value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned short *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned short *)pci_ioaddr(port)) = value;
else if (port >= 0x2000)
*port2adr(port) = value;
else
@@ -120,8 +106,6 @@ void snapgear_outl(unsigned int value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned long *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned long*)pci_ioaddr(port)) = value;
else
maybebadio(port);
}
diff --git a/arch/sh/boards/mach-systemh/io.c b/arch/sh/boards/mach-systemh/io.c
index dec3db0ee933..15577ff1f715 100644
--- a/arch/sh/boards/mach-systemh/io.c
+++ b/arch/sh/boards/mach-systemh/io.c
@@ -35,8 +35,6 @@ unsigned char sh7751systemh_inb(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned char *)port;
- else if (is_pci_ioaddr(port))
- return *(volatile unsigned char *)pci_ioaddr(port);
else if (port <= 0x3F1)
return *(volatile unsigned char *)ETHER_IOMAP(port);
else
@@ -49,8 +47,6 @@ unsigned char sh7751systemh_inb_p(unsigned long port)
if (PXSEG(port))
v = *(volatile unsigned char *)port;
- else if (is_pci_ioaddr(port))
- v = *(volatile unsigned char *)pci_ioaddr(port);
else if (port <= 0x3F1)
v = *(volatile unsigned char *)ETHER_IOMAP(port);
else
@@ -63,8 +59,6 @@ unsigned short sh7751systemh_inw(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned short *)port;
- else if (is_pci_ioaddr(port))
- return *(volatile unsigned short *)pci_ioaddr(port);
else if (port >= 0x2000)
return *port2adr(port);
else if (port <= 0x3F1)
@@ -78,8 +72,6 @@ unsigned int sh7751systemh_inl(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned long *)port;
- else if (is_pci_ioaddr(port))
- return *(volatile unsigned int *)pci_ioaddr(port);
else if (port >= 0x2000)
return *port2adr(port);
else if (port <= 0x3F1)
@@ -94,8 +86,6 @@ void sh7751systemh_outb(unsigned char value, unsigned long port)
if (PXSEG(port))
*(volatile unsigned char *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned char*)pci_ioaddr(port)) = value;
else if (port <= 0x3F1)
*(volatile unsigned char *)ETHER_IOMAP(port) = value;
else
@@ -106,8 +96,6 @@ void sh7751systemh_outb_p(unsigned char value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned char *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned char*)pci_ioaddr(port)) = value;
else if (port <= 0x3F1)
*(volatile unsigned char *)ETHER_IOMAP(port) = value;
else
@@ -119,8 +107,6 @@ void sh7751systemh_outw(unsigned short value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned short *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned short *)pci_ioaddr(port)) = value;
else if (port >= 0x2000)
*port2adr(port) = value;
else if (port <= 0x3F1)
@@ -133,8 +119,6 @@ void sh7751systemh_outl(unsigned int value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned long *)port = value;
- else if (is_pci_ioaddr(port))
- *((unsigned long*)pci_ioaddr(port)) = value;
else
maybebadio(port);
}
diff --git a/arch/sh/boards/mach-titan/io.c b/arch/sh/boards/mach-titan/io.c
index 4badad4c6f30..0130e9826aca 100644
--- a/arch/sh/boards/mach-titan/io.c
+++ b/arch/sh/boards/mach-titan/io.c
@@ -17,8 +17,6 @@ u8 titan_inb(unsigned long port)
{
if (PXSEG(port))
return ctrl_inb(port);
- else if (is_pci_ioaddr(port))
- return ctrl_inb(pci_ioaddr(port));
return ctrl_inw(port2adr(port)) & 0xff;
}
@@ -28,8 +26,6 @@ u8 titan_inb_p(unsigned long port)
if (PXSEG(port))
v = ctrl_inb(port);
- else if (is_pci_ioaddr(port))
- v = ctrl_inb(pci_ioaddr(port));
else
v = ctrl_inw(port2adr(port)) & 0xff;
ctrl_delay();
@@ -40,8 +36,6 @@ u16 titan_inw(unsigned long port)
{
if (PXSEG(port))
return ctrl_inw(port);
- else if (is_pci_ioaddr(port))
- return ctrl_inw(pci_ioaddr(port));
else if (port >= 0x2000)
return ctrl_inw(port2adr(port));
else
@@ -53,8 +47,6 @@ u32 titan_inl(unsigned long port)
{
if (PXSEG(port))
return ctrl_inl(port);
- else if (is_pci_ioaddr(port))
- return ctrl_inl(pci_ioaddr(port));
else if (port >= 0x2000)
return ctrl_inw(port2adr(port));
else
@@ -66,8 +58,6 @@ void titan_outb(u8 value, unsigned long port)
{
if (PXSEG(port))
ctrl_outb(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outb(value, pci_ioaddr(port));
else
ctrl_outw(value, port2adr(port));
}
@@ -76,8 +66,6 @@ void titan_outb_p(u8 value, unsigned long port)
{
if (PXSEG(port))
ctrl_outb(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outb(value, pci_ioaddr(port));
else
ctrl_outw(value, port2adr(port));
ctrl_delay();
@@ -87,8 +75,6 @@ void titan_outw(u16 value, unsigned long port)
{
if (PXSEG(port))
ctrl_outw(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outw(value, pci_ioaddr(port));
else if (port >= 0x2000)
ctrl_outw(value, port2adr(port));
else
@@ -99,8 +85,6 @@ void titan_outl(u32 value, unsigned long port)
{
if (PXSEG(port))
ctrl_outl(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outl(value, pci_ioaddr(port));
else
maybebadio(port);
}
@@ -117,10 +101,8 @@ void titan_outsl(unsigned long port, const void *src, unsigned long count)
void __iomem *titan_ioport_map(unsigned long port, unsigned int size)
{
- if (PXSEG(port) || is_pci_memaddr(port))
+ if (PXSEG(port))
return (void __iomem *)port;
- else if (is_pci_ioaddr(port))
- return (void __iomem *)pci_ioaddr(port);
return (void __iomem *)port2adr(port);
}
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index 95483d161258..78efb04c28f3 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -20,9 +20,6 @@ CONFIG_BOOT_LINK_OFFSET ?= 0x00800000
CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000
CONFIG_ENTRY_OFFSET ?= 0x00001000
-export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
- CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET
-
targets := zImage vmlinux.srec uImage uImage.srec
subdir- := compressed
@@ -43,6 +40,9 @@ KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_MEMORY_START)]')
endif
+export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
+ CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET KERNEL_MEMORY
+
KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_PAGE_OFFSET) + \
$(KERNEL_MEMORY) + \
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index efb01dc3c8c3..9531bf1b7c2f 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -1,5 +1,47 @@
-ifeq ($(CONFIG_SUPERH32),y)
-include ${srctree}/arch/sh/boot/compressed/Makefile_32
-else
-include ${srctree}/arch/sh/boot/compressed/Makefile_64
+#
+# linux/arch/sh/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+targets := vmlinux vmlinux.bin vmlinux.bin.gz \
+ head_$(BITS).o misc_$(BITS).o piggy.o
+
+OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc_$(BITS).o $(obj)/cache.o
+
+ifdef CONFIG_SH_STANDARD_BIOS
+OBJECTS += $(obj)/../../kernel/sh_bios.o
endif
+
+#
+# IMAGE_OFFSET is the load offset of the compression loader
+#
+IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_PAGE_OFFSET) + \
+ $(KERNEL_MEMORY) + \
+ $(CONFIG_BOOT_LINK_OFFSET)]')
+
+LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
+
+ifeq ($(CONFIG_FUNCTION_TRACER),y)
+ORIG_CFLAGS := $(KBUILD_CFLAGS)
+KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
+endif
+
+LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(IMAGE_OFFSET) -e startup \
+ -T $(obj)/../../kernel/vmlinux.lds
+
+$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
+ $(call if_changed,ld)
+ @:
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+
+OBJCOPYFLAGS += -R .empty_zero_page
+
+$(obj)/piggy.o: $(obj)/piggy.S $(obj)/vmlinux.bin.gz FORCE
+ $(call if_changed,as_o_S)
diff --git a/arch/sh/boot/compressed/Makefile_32 b/arch/sh/boot/compressed/Makefile_32
deleted file mode 100644
index b96a055b053e..000000000000
--- a/arch/sh/boot/compressed/Makefile_32
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# linux/arch/sh/boot/compressed/Makefile
-#
-# create a compressed vmlinux image from the original vmlinux
-#
-
-targets := vmlinux vmlinux.bin vmlinux.bin.gz \
- head_32.o misc_32.o piggy.o
-
-OBJECTS = $(obj)/head_32.o $(obj)/misc_32.o
-
-ifdef CONFIG_SH_STANDARD_BIOS
-OBJECTS += $(obj)/../../kernel/sh_bios.o
-endif
-
-#
-# IMAGE_OFFSET is the load offset of the compression loader
-#
-IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
- $$[$(CONFIG_PAGE_OFFSET) + \
- $(CONFIG_MEMORY_START) + \
- $(CONFIG_BOOT_LINK_OFFSET)]')
-
-LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
-
-ifeq ($(CONFIG_FUNCTION_TRACER),y)
-ORIG_CFLAGS := $(KBUILD_CFLAGS)
-KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
-endif
-
-LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds
-
-$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
- $(call if_changed,ld)
- @:
-
-$(obj)/vmlinux.bin: vmlinux FORCE
- $(call if_changed,objcopy)
-
-$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
- $(call if_changed,gzip)
-
-OBJCOPYFLAGS += -R .empty_zero_page
-
-$(obj)/piggy.o: $(obj)/piggy.S $(obj)/vmlinux.bin.gz FORCE
- $(call if_changed,as_o_S)
diff --git a/arch/sh/boot/compressed/Makefile_64 b/arch/sh/boot/compressed/Makefile_64
deleted file mode 100644
index 658d4f915556..000000000000
--- a/arch/sh/boot/compressed/Makefile_64
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# arch/sh/boot/compressed/Makefile_64
-#
-# create a compressed vmlinux image from the original vmlinux
-#
-# Copyright (C) 2002 Stuart Menefy
-# Copyright (C) 2004 Paul Mundt
-#
-# 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.
-#
-
-targets := vmlinux vmlinux.bin vmlinux.bin.gz \
- head_64.o misc_64.o cache.o piggy.o
-
-OBJECTS := $(obj)/vmlinux_64.lds $(obj)/head_64.o $(obj)/misc_64.o \
- $(obj)/cache.o
-
-#
-# ZIMAGE_OFFSET is the load offset of the compression loader
-# (4M for the kernel plus 64K for this loader)
-#
-ZIMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
- $$[$(CONFIG_PAGE_OFFSET)+0x400000+0x10000]')
-
-LDFLAGS_vmlinux := -Ttext $(ZIMAGE_OFFSET) -e startup \
- -T $(obj)/../../kernel/vmlinux.lds
-
-$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
- $(call if_changed,ld)
- @:
-
-$(obj)/vmlinux.bin: vmlinux FORCE
- $(call if_changed,objcopy)
-
-$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
- $(call if_changed,gzip)
-
-OBJCOPYFLAGS += -R .empty_zero_page
-
-$(obj)/piggy.o: $(obj)/piggy.S $(obj)/vmlinux.bin.gz FORCE
- $(call if_changed,as_o_S)
diff --git a/arch/sh/boot/compressed/head_64.S b/arch/sh/boot/compressed/head_64.S
index 622eac3cf556..9993113c6713 100644
--- a/arch/sh/boot/compressed/head_64.S
+++ b/arch/sh/boot/compressed/head_64.S
@@ -14,6 +14,7 @@
* Copyright (C) 2002 Stuart Menefy (stuart.menefy@st.com)
*/
#include <asm/cache.h>
+#include <asm/tlb.h>
#include <cpu/mmu_context.h>
#include <cpu/registers.h>
@@ -33,11 +34,7 @@
#define ICCR0_INIT_VAL ICCR0_ON | ICCR0_ICI /* ICE + ICI */
#define ICCR1_INIT_VAL ICCR1_NOLOCK /* No locking */
-#if 1
#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WB /* OCE + OCI + WB */
-#else
-#define OCCR0_INIT_VAL OCCR0_OFF
-#endif
#define OCCR1_INIT_VAL OCCR1_NOLOCK /* No locking */
.text
diff --git a/arch/sh/boot/compressed/vmlinux_64.lds b/arch/sh/boot/compressed/vmlinux_64.lds
deleted file mode 100644
index 59c2ef4aeda5..000000000000
--- a/arch/sh/boot/compressed/vmlinux_64.lds
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * ld script to make compressed SuperH/shmedia Linux kernel+decompression
- * bootstrap
- * Modified by Stuart Menefy from arch/sh/vmlinux.lds.S written by Niibe Yutaka
- */
-
-
-#ifdef CONFIG_LITTLE_ENDIAN
-/* OUTPUT_FORMAT("elf32-sh64l-linux", "elf32-sh64l-linux", "elf32-sh64l-linux") */
-#define NOP 0x6ff0fff0
-#else
-/* OUTPUT_FORMAT("elf32-sh64", "elf32-sh64", "elf32-sh64") */
-#define NOP 0xf0fff06f
-#endif
-
-OUTPUT_FORMAT("elf32-sh64-linux")
-OUTPUT_ARCH(sh)
-ENTRY(_start)
-
-#define ALIGNED_GAP(section, align) (((ADDR(section)+SIZEOF(section)+(align)-1) & ~((align)-1))-ADDR(section))
-#define FOLLOWING(section, align) AT (LOADADDR(section) + ALIGNED_GAP(section,align))
-
-SECTIONS
-{
- _text = .; /* Text and read-only data */
-
- .text : {
- *(.text)
- *(.text64)
- *(.text..SHmedia32)
- *(.fixup)
- *(.gnu.warning)
- } = NOP
- . = ALIGN(4);
- .rodata : { *(.rodata) }
-
- /* There is no 'real' reason for eight byte alignment, four would work
- * as well, but gdb downloads much (*4) faster with this.
- */
- . = ALIGN(8);
- .image : { *(.image) }
- . = ALIGN(4);
- _etext = .; /* End of text section */
-
- .data : /* Data */
- FOLLOWING(.image, 4)
- {
- _data = .;
- *(.data)
- }
- _data_image = LOADADDR(.data);/* Address of data section in ROM */
-
- _edata = .; /* End of data section */
-
- .stack : { stack = .; _stack = .; }
-
- . = ALIGN(4);
- __bss_start = .; /* BSS */
- .bss : {
- *(.bss)
- }
- . = ALIGN(4);
- _end = . ;
-}
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig
index c8d982a8a2e6..022f70e0ea03 100644
--- a/arch/sh/configs/ap325rxa_defconfig
+++ b/arch/sh/configs/ap325rxa_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 17:46:53 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:42:06 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -74,6 +75,7 @@ CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
# CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -92,12 +94,15 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -110,7 +115,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -159,6 +163,7 @@ CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
CONFIG_CPU_SUBTYPE_SH7723=y
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -168,8 +173,6 @@ CONFIG_CPU_SUBTYPE_SH7723=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -573,6 +576,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
@@ -695,6 +699,7 @@ CONFIG_DEVKMEM=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=6
CONFIG_SERIAL_SH_SCI_CONSOLE=y
@@ -1030,6 +1035,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
@@ -1052,6 +1058,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1100,6 +1111,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1191,10 +1203,24 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1303,6 +1329,7 @@ CONFIG_CRYPTO_CBC=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig
index fa5fc1e1e980..40301f86a45c 100644
--- a/arch/sh/configs/cayman_defconfig
+++ b/arch/sh/configs/cayman_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 17:49:14 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:42:53 2009
#
CONFIG_SUPERH=y
# CONFIG_SUPERH32 is not set
@@ -40,6 +40,7 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
@@ -70,6 +71,7 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -89,10 +91,13 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -105,7 +110,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -127,39 +131,6 @@ CONFIG_DEFAULT_IOSCHED="cfq"
# System type
#
CONFIG_CPU_SH5=y
-# CONFIG_CPU_SUBTYPE_SH7619 is not set
-# CONFIG_CPU_SUBTYPE_SH7201 is not set
-# CONFIG_CPU_SUBTYPE_SH7203 is not set
-# CONFIG_CPU_SUBTYPE_SH7206 is not set
-# CONFIG_CPU_SUBTYPE_SH7263 is not set
-# CONFIG_CPU_SUBTYPE_MXG is not set
-# CONFIG_CPU_SUBTYPE_SH7705 is not set
-# CONFIG_CPU_SUBTYPE_SH7706 is not set
-# CONFIG_CPU_SUBTYPE_SH7707 is not set
-# CONFIG_CPU_SUBTYPE_SH7708 is not set
-# CONFIG_CPU_SUBTYPE_SH7709 is not set
-# CONFIG_CPU_SUBTYPE_SH7710 is not set
-# CONFIG_CPU_SUBTYPE_SH7712 is not set
-# CONFIG_CPU_SUBTYPE_SH7720 is not set
-# CONFIG_CPU_SUBTYPE_SH7721 is not set
-# CONFIG_CPU_SUBTYPE_SH7750 is not set
-# CONFIG_CPU_SUBTYPE_SH7091 is not set
-# CONFIG_CPU_SUBTYPE_SH7750R is not set
-# CONFIG_CPU_SUBTYPE_SH7750S is not set
-# CONFIG_CPU_SUBTYPE_SH7751 is not set
-# CONFIG_CPU_SUBTYPE_SH7751R is not set
-# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-# CONFIG_CPU_SUBTYPE_SH7723 is not set
-# CONFIG_CPU_SUBTYPE_SH7763 is not set
-# CONFIG_CPU_SUBTYPE_SH7770 is not set
-# CONFIG_CPU_SUBTYPE_SH7780 is not set
-# CONFIG_CPU_SUBTYPE_SH7785 is not set
-# CONFIG_CPU_SUBTYPE_SH7786 is not set
-# CONFIG_CPU_SUBTYPE_SHX3 is not set
-# CONFIG_CPU_SUBTYPE_SH7343 is not set
-# CONFIG_CPU_SUBTYPE_SH7722 is not set
-# CONFIG_CPU_SUBTYPE_SH7366 is not set
CONFIG_CPU_SUBTYPE_SH5_101=y
# CONFIG_CPU_SUBTYPE_SH5_103 is not set
@@ -279,8 +250,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -492,6 +461,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -568,6 +538,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -591,6 +562,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
@@ -779,6 +751,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -1042,7 +1015,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1082,6 +1054,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1105,6 +1078,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1146,8 +1124,13 @@ CONFIG_MINIX_FS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1208,6 +1191,9 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
@@ -1241,15 +1227,21 @@ CONFIG_FRAME_POINTER=y
# CONFIG_LATENCYTOP is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
# CONFIG_PAGE_POISONING is not set
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_DEBUG_BOOTMEM is not set
@@ -1354,6 +1346,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig
index 5c1123640142..1f3cc98330bf 100644
--- a/arch/sh/configs/dreamcast_defconfig
+++ b/arch/sh/configs/dreamcast_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 17:51:48 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:44:27 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -71,6 +72,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -90,6 +92,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
# CONFIG_OPROFILE is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
@@ -98,6 +101,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -110,7 +115,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -156,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7091=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -165,8 +170,6 @@ CONFIG_CPU_SUBTYPE_SH7091=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -271,7 +274,7 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
CONFIG_SH_DMA_IRQ_MULTI=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=6
+CONFIG_NR_ONCHIP_DMA_CHANNELS=4
CONFIG_NR_DMA_CHANNELS_BOOL=y
CONFIG_NR_DMA_CHANNELS=9
# CONFIG_PVR2_DMA is not set
@@ -320,7 +323,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 panic=3"
CONFIG_MAPLE=y
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -602,6 +604,7 @@ CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_APPLETOUCH is not set
# CONFIG_MOUSE_BCM5974 is not set
# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_MAPLE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
@@ -812,7 +815,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -867,6 +869,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -910,6 +917,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
@@ -947,10 +955,24 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1051,6 +1073,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig
index f4c34b039312..d7092457ddc7 100644
--- a/arch/sh/configs/edosk7705_defconfig
+++ b/arch/sh/configs/edosk7705_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 17:54:02 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:45:04 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
@@ -56,6 +57,7 @@ CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HOTPLUG is not set
# CONFIG_PRINTK is not set
# CONFIG_BUG is not set
@@ -74,12 +76,15 @@ CONFIG_SHMEM=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_BASE_SMALL=1
# CONFIG_MODULES is not set
@@ -114,6 +119,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -123,8 +129,6 @@ CONFIG_CPU_SUBTYPE_SH7705=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -382,6 +386,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+
+#
# Pseudo filesystems
#
# CONFIG_PROC_FS is not set
@@ -409,10 +417,22 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -426,6 +446,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig
index 7825c2699f18..a822b1d8c116 100644
--- a/arch/sh/configs/edosk7760_defconfig
+++ b/arch/sh/configs/edosk7760_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 17:54:57 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:45:25 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -40,6 +41,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
@@ -67,7 +69,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -77,6 +78,7 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -96,6 +98,7 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -103,6 +106,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -115,7 +120,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -161,6 +165,7 @@ CONFIG_CPU_SH4=y
CONFIG_CPU_SUBTYPE_SH7760=y
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -170,8 +175,6 @@ CONFIG_CPU_SUBTYPE_SH7760=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -815,6 +818,7 @@ CONFIG_EXT2_FS_XATTR=y
# CONFIG_EXT2_FS_SECURITY is not set
CONFIG_EXT2_FS_XIP=y
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -839,6 +843,11 @@ CONFIG_INOTIFY_USER=y
CONFIG_GENERIC_ACL=y
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -883,6 +892,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -964,6 +974,9 @@ CONFIG_DEBUG_SHIRQ=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
CONFIG_TIMER_STATS=y
@@ -1001,6 +1014,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1010,9 +1024,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1126,6 +1145,7 @@ CONFIG_CRYPTO_DES=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig
index ebb4c37abaa6..c5b50077913d 100644
--- a/arch/sh/configs/espt_defconfig
+++ b/arch/sh/configs/espt_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 17:58:18 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:46:26 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -78,6 +79,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -106,6 +108,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -117,7 +121,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -164,6 +167,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
CONFIG_CPU_SUBTYPE_SH7763=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -173,8 +177,6 @@ CONFIG_CPU_SUBTYPE_SH7763=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -548,6 +550,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
@@ -919,6 +922,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -943,6 +947,11 @@ CONFIG_AUTOFS4_FS=y
CONFIG_GENERIC_ACL=y
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -985,8 +994,13 @@ CONFIG_CRAMFS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1075,11 +1089,25 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1179,6 +1207,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig
index 82b113af08d3..8e13027eecc3 100644
--- a/arch/sh/configs/hp6xx_defconfig
+++ b/arch/sh/configs/hp6xx_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:01:05 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:47:15 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -67,6 +68,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -85,12 +87,15 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -98,7 +103,6 @@ CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -144,6 +148,7 @@ CONFIG_CPU_SUBTYPE_SH7709=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -153,8 +158,6 @@ CONFIG_CPU_SUBTYPE_SH7709=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -385,6 +388,7 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
@@ -431,6 +435,7 @@ CONFIG_KEYBOARD_HP6XX=y
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_AD7879 is not set
# CONFIG_TOUCHSCREEN_FUJITSU is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
@@ -674,6 +679,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -719,6 +729,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
#
# Partition Types
@@ -786,10 +797,23 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -898,6 +922,7 @@ CONFIG_CRYPTO_MD5=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index b6fa4a7599d0..7f549aef0dfd 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:02:54 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:47:48 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -69,6 +70,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -88,6 +90,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -95,6 +98,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -107,7 +112,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -153,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -162,8 +167,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -292,8 +295,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -602,6 +603,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -706,6 +708,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -729,6 +732,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
@@ -922,6 +926,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
# CONFIG_SOC_CAMERA is not set
CONFIG_V4L_USB_DRIVERS=y
# CONFIG_USB_VIDEO_CLASS is not set
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
# CONFIG_USB_GSPCA is not set
# CONFIG_VIDEO_HDPVR is not set
CONFIG_VIDEO_USBVIDEO=m
@@ -994,15 +999,17 @@ CONFIG_USB_HID=m
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=m
CONFIG_HID_APPLE=m
CONFIG_HID_BELKIN=m
CONFIG_HID_CHERRY=m
CONFIG_HID_CHICONY=m
CONFIG_HID_CYPRESS=m
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=m
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=m
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=m
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1197,6 +1204,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1222,6 +1230,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
@@ -1270,10 +1283,15 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
@@ -1364,10 +1382,23 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -1469,6 +1500,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig
index 92c515c4199f..a7db539f2800 100644
--- a/arch/sh/configs/lboxre2_defconfig
+++ b/arch/sh/configs/lboxre2_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:06:51 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:48:54 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -69,6 +70,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -88,6 +90,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -95,6 +98,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -107,7 +112,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -153,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -162,8 +167,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -293,8 +296,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1"
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -542,6 +543,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -702,6 +704,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -725,6 +728,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
@@ -931,7 +935,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1007,6 +1010,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1029,6 +1033,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1073,8 +1082,13 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
@@ -1151,10 +1165,23 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -1256,6 +1283,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig
index 26586c2d64ca..58bec61506fa 100644
--- a/arch/sh/configs/magicpanelr2_defconfig
+++ b/arch/sh/configs/magicpanelr2_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:07:39 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:49:32 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -39,6 +40,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
# CONFIG_TASKSTATS is not set
@@ -66,7 +68,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -76,6 +77,7 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -94,6 +96,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -101,6 +104,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -113,7 +118,6 @@ CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -159,6 +163,7 @@ CONFIG_CPU_SUBTYPE_SH7720=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -168,8 +173,6 @@ CONFIG_CPU_SUBTYPE_SH7720=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -813,6 +816,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
# CONFIG_EXT3_FS_XATTR is not set
# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
@@ -831,6 +835,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -884,6 +893,7 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -965,6 +975,7 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -1000,6 +1011,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1008,9 +1020,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1035,6 +1052,7 @@ CONFIG_DUMP_CODE=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig
index 75178355d69a..2886fc84bc1c 100644
--- a/arch/sh/configs/microdev_defconfig
+++ b/arch/sh/configs/microdev_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:11:13 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:50:51 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -65,7 +66,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -74,6 +74,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -92,12 +93,15 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -105,7 +109,6 @@ CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -151,6 +154,7 @@ CONFIG_CPU_SH4=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
CONFIG_CPU_SUBTYPE_SH4_202=y
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -160,8 +164,6 @@ CONFIG_CPU_SUBTYPE_SH4_202=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -647,6 +649,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -669,6 +672,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -715,6 +723,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -802,10 +811,24 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -914,6 +937,7 @@ CONFIG_CRYPTO_DES=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig
index a8720f9c6047..8ecceb4bf27e 100644
--- a/arch/sh/configs/migor_defconfig
+++ b/arch/sh/configs/migor_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:14:03 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:51:34 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -67,7 +68,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -76,6 +76,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -104,6 +105,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -115,7 +118,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -165,6 +167,7 @@ CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -174,8 +177,6 @@ CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
CONFIG_CPU_SUBTYPE_SH7722=y
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -577,6 +578,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
@@ -873,7 +875,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -1012,6 +1013,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1056,6 +1062,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1105,11 +1112,25 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1218,6 +1239,7 @@ CONFIG_CRYPTO_WORKQUEUE=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig
index df2d177d5346..2b9507286182 100644
--- a/arch/sh/configs/polaris_defconfig
+++ b/arch/sh/configs/polaris_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:16:48 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:52:19 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -40,6 +41,7 @@ CONFIG_LOCALVERSION=""
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
# CONFIG_TASKSTATS is not set
@@ -76,6 +78,7 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -94,6 +97,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -101,6 +105,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -113,7 +119,6 @@ CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -159,6 +164,7 @@ CONFIG_CPU_SUBTYPE_SH7709=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -168,8 +174,6 @@ CONFIG_CPU_SUBTYPE_SH7709=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -778,6 +782,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -831,6 +840,7 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -874,6 +884,9 @@ CONFIG_DEBUG_SHIRQ=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -914,6 +927,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -923,9 +937,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -950,6 +969,7 @@ CONFIG_DUMP_CODE=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig
index 7def4df46ddb..943da63a3852 100644
--- a/arch/sh/configs/r7780mp_defconfig
+++ b/arch/sh/configs/r7780mp_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:20:17 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:53:28 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -78,6 +79,7 @@ CONFIG_UID16=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -107,6 +109,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_BASE_SMALL=0
@@ -118,7 +122,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -165,6 +168,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
@@ -174,8 +178,6 @@ CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -258,7 +260,7 @@ CONFIG_SH_R7780MP=y
#
CONFIG_SH_TMU=y
CONFIG_SH_TIMER_IRQ=28
-CONFIG_SH_PCLK_FREQ=32000000
+CONFIG_SH_PCLK_FREQ=33333333
# CONFIG_NO_HZ is not set
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -313,8 +315,6 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -536,6 +536,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -696,6 +697,7 @@ CONFIG_E1000=m
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -719,6 +721,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
@@ -920,6 +923,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -1027,7 +1031,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1120,6 +1123,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1143,6 +1147,11 @@ CONFIG_INOTIFY_USER=y
CONFIG_FUSE_FS=m
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1191,6 +1200,7 @@ CONFIG_MINIX_FS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1279,6 +1289,9 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -1316,6 +1329,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1325,11 +1339,16 @@ CONFIG_TRACING=y
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1449,6 +1468,7 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig
index cb134ffc2118..82658f672398 100644
--- a/arch/sh/configs/r7785rp_defconfig
+++ b/arch/sh/configs/r7785rp_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:24:35 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:55:10 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -43,6 +44,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
@@ -78,6 +80,7 @@ CONFIG_UID16=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -108,6 +111,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -120,7 +125,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -168,6 +172,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -177,8 +182,6 @@ CONFIG_CPU_SUBTYPE_SH7785=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -266,7 +269,7 @@ CONFIG_SH_R7785RP=y
#
CONFIG_SH_TMU=y
CONFIG_SH_TIMER_IRQ=28
-CONFIG_SH_PCLK_FREQ=50000000
+CONFIG_SH_PCLK_FREQ=33333333
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -337,8 +340,6 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_LEGACY is not set
@@ -561,6 +562,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -698,6 +700,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -721,6 +724,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
@@ -948,6 +952,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -970,6 +975,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
@@ -1109,7 +1115,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1202,6 +1207,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1225,6 +1231,11 @@ CONFIG_INOTIFY_USER=y
CONFIG_FUSE_FS=m
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1273,6 +1284,7 @@ CONFIG_MINIX_FS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1359,6 +1371,7 @@ CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -1401,6 +1414,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1410,11 +1424,16 @@ CONFIG_TRACING=y
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1534,6 +1553,7 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig
index a037c744b798..fa4395768d19 100644
--- a/arch/sh/configs/rsk7201_defconfig
+++ b/arch/sh/configs/rsk7201_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:29:08 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:56:29 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -65,7 +66,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -74,6 +74,7 @@ CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -100,6 +101,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
@@ -110,7 +113,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -157,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7201=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -166,8 +169,6 @@ CONFIG_CPU_SUBTYPE_SH7201=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -603,6 +604,11 @@ CONFIG_EXT2_FS=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -651,8 +657,13 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
#
# Partition Types
@@ -686,11 +697,24 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -705,6 +729,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig
index 9ae28e88426c..e3a65f819f0a 100644
--- a/arch/sh/configs/rsk7203_defconfig
+++ b/arch/sh/configs/rsk7203_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:30:34 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:57:06 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -39,6 +40,7 @@ CONFIG_LOCALVERSION=""
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
@@ -70,7 +72,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -80,6 +81,7 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -106,6 +108,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
@@ -116,7 +120,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -163,6 +166,7 @@ CONFIG_CPU_SUBTYPE_SH7203=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -172,8 +176,6 @@ CONFIG_CPU_SUBTYPE_SH7203=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -750,15 +752,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -874,6 +878,7 @@ CONFIG_LEDS_CLASS=y
# LED drivers
#
CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
#
# LED Triggers
@@ -882,6 +887,7 @@ CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+# CONFIG_LEDS_TRIGGER_GPIO is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
#
@@ -951,6 +957,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -989,8 +1000,13 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1033,6 +1049,9 @@ CONFIG_DEBUG_SHIRQ=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -1076,6 +1095,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1083,11 +1103,16 @@ CONFIG_TRACING=y
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1111,6 +1136,7 @@ CONFIG_DUMP_CODE=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig
index c0f741af6da8..a4a59f6205ab 100644
--- a/arch/sh/configs/rts7751r2d1_defconfig
+++ b/arch/sh/configs/rts7751r2d1_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:33:25 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:58:13 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -70,6 +71,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -99,6 +101,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -110,7 +114,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -156,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -165,8 +169,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -302,8 +304,6 @@ CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=se
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -513,6 +513,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -672,6 +673,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -695,6 +697,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
@@ -793,6 +796,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=1
CONFIG_SERIAL_SH_SCI_CONSOLE=y
@@ -1079,15 +1083,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1291,6 +1297,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1337,6 +1348,7 @@ CONFIG_MINIX_FS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
@@ -1417,11 +1429,25 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1524,6 +1550,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig
index 8feef629e49c..a860435b8847 100644
--- a/arch/sh/configs/rts7751r2dplus_defconfig
+++ b/arch/sh/configs/rts7751r2dplus_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:34:12 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:59:01 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -70,6 +71,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -99,6 +101,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -110,7 +114,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -156,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -165,8 +169,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -302,8 +304,6 @@ CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=se
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -424,7 +424,92 @@ CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_BLKDEVS is not set
+# CONFIG_MTD_BLOCK is not set
+# 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
+# CONFIG_MTD_OOPS 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 is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# 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=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR 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_CISS_DA is not set
@@ -513,6 +598,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -672,6 +758,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -695,6 +782,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
@@ -793,6 +881,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=1
CONFIG_SERIAL_SH_SCI_CONSOLE=y
@@ -1079,15 +1168,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1291,6 +1382,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1337,6 +1433,7 @@ CONFIG_MINIX_FS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
@@ -1417,11 +1514,25 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1524,6 +1635,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig
index 739e2299ae80..a629b79a1844 100644
--- a/arch/sh/configs/sdk7780_defconfig
+++ b/arch/sh/configs/sdk7780_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:34:43 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 12:59:32 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -41,6 +42,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
@@ -73,6 +75,7 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -93,6 +96,7 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -100,6 +104,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -112,7 +118,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -159,6 +164,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
@@ -168,8 +174,6 @@ CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -310,8 +314,6 @@ CONFIG_CMDLINE="mem=128M console=tty0 console=ttySC0,115200 ip=bootp root=/dev/n
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_LEGACY is not set
@@ -646,6 +648,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -1091,15 +1094,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1257,6 +1262,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1281,6 +1287,11 @@ CONFIG_AUTOFS4_FS=y
CONFIG_GENERIC_ACL=y
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
@@ -1331,6 +1342,7 @@ CONFIG_MINIX_FS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1418,6 +1430,9 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
CONFIG_TIMER_STATS=y
@@ -1455,6 +1470,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1464,9 +1480,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1580,6 +1601,7 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig
index d30e0a7ad9f1..5caf85a3312d 100644
--- a/arch/sh/configs/se7206_defconfig
+++ b/arch/sh/configs/se7206_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:39:37 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:01:02 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -40,6 +41,7 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
@@ -63,6 +65,7 @@ CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_NS=y
# CONFIG_CGROUP_FREEZER is not set
CONFIG_CGROUP_DEVICE=y
+# CONFIG_CPUSETS is not set
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
CONFIG_CGROUP_MEM_RES_CTLR=y
@@ -80,7 +83,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -90,6 +92,7 @@ CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -116,6 +119,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
@@ -127,7 +132,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -174,6 +178,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -183,8 +188,6 @@ CONFIG_CPU_SUBTYPE_SH7206=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -746,6 +749,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -785,8 +793,13 @@ CONFIG_CRAMFS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -831,6 +844,9 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -869,6 +885,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -876,11 +893,16 @@ CONFIG_TRACING=y
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -991,6 +1013,7 @@ CONFIG_CRYPTO_LZO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index fbb72d029e68..004d531716dc 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:42:00 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:01:44 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -40,6 +41,7 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
@@ -73,6 +75,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -91,6 +94,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -98,6 +102,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_BASE_SMALL=0
@@ -109,7 +115,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -158,6 +163,7 @@ CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -167,8 +173,6 @@ CONFIG_ARCH_SHMOBILE=y
CONFIG_CPU_SUBTYPE_SH7343=y
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -769,6 +773,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
# CONFIG_SOC_CAMERA is not set
CONFIG_V4L_USB_DRIVERS=y
# CONFIG_USB_VIDEO_CLASS is not set
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
CONFIG_USB_GSPCA=m
# CONFIG_USB_M5602 is not set
# CONFIG_USB_STV06XX is not set
@@ -800,6 +805,7 @@ CONFIG_USB_GSPCA=m
# CONFIG_VIDEO_PVRUSB2 is not set
# CONFIG_VIDEO_HDPVR is not set
# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_CX231XX is not set
# CONFIG_VIDEO_USBVISION is not set
# CONFIG_USB_VICAM is not set
# CONFIG_USB_IBMCAM is not set
@@ -813,6 +819,7 @@ CONFIG_USB_GSPCA=m
# CONFIG_USB_STV680 is not set
# CONFIG_USB_ZC0301 is not set
# CONFIG_USB_PWC is not set
+CONFIG_USB_PWC_INPUT_EVDEV=y
# CONFIG_USB_ZR364XX is not set
# CONFIG_USB_STKWEBCAM is not set
# CONFIG_USB_S2255 is not set
@@ -914,15 +921,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1050,6 +1059,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1071,6 +1081,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1125,6 +1140,7 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1174,10 +1190,23 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1279,6 +1308,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig
index 125304e80f57..edbece52afc1 100644
--- a/arch/sh/configs/se7619_defconfig
+++ b/arch/sh/configs/se7619_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:44:53 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:02:32 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -61,6 +62,7 @@ CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -78,11 +80,14 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_BASE_SMALL=1
@@ -134,6 +139,7 @@ CONFIG_CPU_SUBTYPE_SH7619=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -143,8 +149,6 @@ CONFIG_CPU_SUBTYPE_SH7619=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -513,7 +517,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -564,6 +567,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -601,8 +609,13 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
#
# Partition Types
@@ -630,10 +643,21 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -647,6 +671,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
index 0308abf52384..bae161c66835 100644
--- a/arch/sh/configs/se7705_defconfig
+++ b/arch/sh/configs/se7705_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:45:56 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:02:52 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -62,7 +63,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -70,6 +70,7 @@ CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -88,12 +89,15 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -150,6 +154,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -159,8 +164,6 @@ CONFIG_CPU_SUBTYPE_SH7705=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -698,7 +701,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -752,6 +754,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -804,6 +811,7 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -847,10 +855,23 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -949,6 +970,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
index a8c24b703489..330043f3c316 100644
--- a/arch/sh/configs/se7712_defconfig
+++ b/arch/sh/configs/se7712_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:48:18 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:03:27 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
@@ -38,6 +39,7 @@ CONFIG_LOCALVERSION=""
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
@@ -69,6 +71,7 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
# CONFIG_BUG is not set
@@ -87,6 +90,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -94,6 +98,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -105,7 +111,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -151,6 +156,7 @@ CONFIG_CPU_SUBTYPE_SH7712=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -160,8 +166,6 @@ CONFIG_CPU_SUBTYPE_SH7712=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -585,6 +589,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
@@ -812,6 +817,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -833,6 +839,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -887,6 +898,7 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -927,6 +939,7 @@ CONFIG_FRAME_WARN=1024
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -961,6 +974,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -969,9 +983,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1090,6 +1109,7 @@ CONFIG_CRYPTO_DEFLATE=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig
index 4b79c2567dc8..56478918440d 100644
--- a/arch/sh/configs/se7721_defconfig
+++ b/arch/sh/configs/se7721_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:51:44 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:04:19 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
@@ -38,6 +39,7 @@ CONFIG_LOCALVERSION=""
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
@@ -73,6 +75,7 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
# CONFIG_BUG is not set
@@ -91,6 +94,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -98,6 +102,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -109,7 +115,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7721=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -164,8 +170,6 @@ CONFIG_CPU_SUBTYPE_SH7721=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -776,15 +780,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -943,6 +949,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -964,6 +971,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1021,6 +1033,7 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
#
@@ -1085,6 +1098,7 @@ CONFIG_FRAME_WARN=1024
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -1119,6 +1133,7 @@ CONFIG_FRAME_POINTER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1127,9 +1142,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1248,6 +1268,7 @@ CONFIG_CRYPTO_DEFLATE=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig
index 82bdaac45fb5..726fdbdb2807 100644
--- a/arch/sh/configs/se7722_defconfig
+++ b/arch/sh/configs/se7722_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:55:10 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:05:29 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -69,7 +70,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -78,6 +78,7 @@ CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -97,6 +98,7 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
# CONFIG_OPROFILE is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
@@ -105,6 +107,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -117,7 +121,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -167,6 +170,7 @@ CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -176,8 +180,6 @@ CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
CONFIG_CPU_SUBTYPE_SH7722=y
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -486,6 +488,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
@@ -692,7 +695,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -766,6 +768,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -789,6 +792,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -832,6 +840,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
@@ -872,11 +881,25 @@ CONFIG_DEBUG_FS=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -977,6 +1000,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
index ceef6d9138ee..ed1a1230f636 100644
--- a/arch/sh/configs/se7750_defconfig
+++ b/arch/sh/configs/se7750_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:57:31 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:06:02 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -70,6 +71,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -88,6 +90,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -95,6 +98,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -106,7 +111,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -152,6 +156,7 @@ CONFIG_CPU_SUBTYPE_SH7750=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -161,8 +166,6 @@ CONFIG_CPU_SUBTYPE_SH7750=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -553,6 +556,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
@@ -775,6 +779,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -829,6 +838,7 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -886,10 +896,23 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -989,6 +1012,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig
index 67fc26b3a7d0..55f3b788e0cb 100644
--- a/arch/sh/configs/se7751_defconfig
+++ b/arch/sh/configs/se7751_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 18:59:59 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:06:44 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -65,7 +66,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -74,6 +74,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -92,6 +93,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -99,6 +101,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -110,7 +114,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -156,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7751=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -165,8 +169,6 @@ CONFIG_CPU_SUBTYPE_SH7751=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -742,6 +744,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -796,6 +803,7 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
@@ -833,10 +841,23 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -936,6 +957,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig
index ebce23cc2ad8..c4f0af32efa9 100644
--- a/arch/sh/configs/se7780_defconfig
+++ b/arch/sh/configs/se7780_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:02:05 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:07:14 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -67,6 +68,7 @@ CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
# CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -86,12 +88,15 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -103,7 +108,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
#
@@ -149,6 +153,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
@@ -158,8 +163,6 @@ CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -285,8 +288,6 @@ CONFIG_CMDLINE="console=ttySC0.115200 root=/dev/sda1"
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -558,6 +559,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -957,15 +959,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1122,6 +1126,10 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1245,11 +1253,24 @@ CONFIG_DEBUG_FS=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1345,6 +1366,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig
index 6fcdb090cf32..f9c6e51dc0b0 100644
--- a/arch/sh/configs/sh03_defconfig
+++ b/arch/sh/configs/sh03_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:04:59 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:07:56 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -41,6 +42,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
@@ -67,7 +69,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -76,6 +77,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -105,6 +107,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -117,7 +121,6 @@ CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -163,6 +166,7 @@ CONFIG_CPU_SUBTYPE_SH7751=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -172,8 +176,6 @@ CONFIG_CPU_SUBTYPE_SH7751=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -300,8 +302,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -562,6 +562,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -656,6 +657,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -679,6 +681,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
@@ -887,7 +890,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -929,6 +931,7 @@ CONFIG_EXT2_FS_XATTR=y
# CONFIG_EXT2_FS_SECURITY is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
@@ -952,6 +955,11 @@ CONFIG_AUTOFS4_FS=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
@@ -1001,6 +1009,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1112,11 +1121,26 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -1228,6 +1252,7 @@ CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
index 1ab37c01da6e..48b58098cf84 100644
--- a/arch/sh/configs/sh7710voipgw_defconfig
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:09:01 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:09:16 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -39,6 +40,7 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
@@ -72,6 +74,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -90,6 +93,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -97,6 +101,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_BASE_SMALL=0
@@ -108,7 +114,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -154,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7710=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -163,8 +169,6 @@ CONFIG_CPU_SUBTYPE_SH7710=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -728,7 +732,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -780,6 +783,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -834,6 +842,7 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
@@ -871,11 +880,24 @@ CONFIG_DEBUG_FS=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -975,6 +997,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/sh7724_generic_defconfig b/arch/sh/configs/sh7724_generic_defconfig
new file mode 100644
index 000000000000..ec8f18c7684c
--- /dev/null
+++ b/arch/sh/configs/sh7724_generic_defconfig
@@ -0,0 +1,707 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:09:47 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+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 is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+# CONFIG_UID16 is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY 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"
+CONFIG_FREEZER=y
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7724=y
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+
+#
+# Memory hotplug is currently incompatible with Software Suspend
+#
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_SH_PCLK_FREQ=41666666
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_SH_CPU_FREQ=y
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_KEXEC_JUMP=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 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
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# 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
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+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_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SH=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+# CONFIG_PROC_FS is not set
+# CONFIG_SYSFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_MORE_COMPILE_OPTIONS is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig
index c79bb84ec305..f77bc7998d2f 100644
--- a/arch/sh/configs/sh7763rdp_defconfig
+++ b/arch/sh/configs/sh7763rdp_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:10:57 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:10:12 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -78,6 +79,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -106,6 +108,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -117,7 +121,6 @@ CONFIG_MODULES=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -164,6 +167,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
CONFIG_CPU_SUBTYPE_SH7763=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -173,8 +177,6 @@ CONFIG_CPU_SUBTYPE_SH7763=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -555,6 +557,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
@@ -941,6 +944,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -965,6 +969,11 @@ CONFIG_AUTOFS4_FS=y
CONFIG_GENERIC_ACL=y
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1012,6 +1021,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1100,11 +1110,25 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1204,6 +1228,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/sh7770_generic_defconfig b/arch/sh/configs/sh7770_generic_defconfig
new file mode 100644
index 000000000000..d6489b46ca5b
--- /dev/null
+++ b/arch/sh/configs/sh7770_generic_defconfig
@@ -0,0 +1,700 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc4
+# Tue May 12 14:48:21 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_TMU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+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 is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+# CONFIG_UID16 is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY 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"
+CONFIG_FREEZER=y
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+CONFIG_CPU_SUBTYPE_SH7770=y
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+
+#
+# Memory hotplug is currently incompatible with Software Suspend
+#
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_SH_PCLK_FREQ=41666666
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_SH_CPU_FREQ=y
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_KEXEC_JUMP=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 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
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# 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
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+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_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SH=y
+# CONFIG_RTC_DRV_GENERIC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+# CONFIG_PROC_FS is not set
+# CONFIG_SYSFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig
index a6cf4505741c..1c55b800d124 100644
--- a/arch/sh/configs/sh7785lcr_32bit_defconfig
+++ b/arch/sh/configs/sh7785lcr_32bit_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:12:18 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:10:53 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -79,6 +80,7 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -98,6 +100,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
# CONFIG_OPROFILE is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
@@ -106,6 +109,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -118,7 +123,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -166,6 +170,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -175,8 +180,6 @@ CONFIG_CPU_SUBTYPE_SH7785=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -310,8 +313,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -672,6 +673,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -1009,15 +1011,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1218,6 +1222,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1240,6 +1245,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1289,6 +1299,7 @@ CONFIG_MINIX_FS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1377,6 +1388,9 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -1413,6 +1427,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1422,9 +1437,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1542,6 +1562,7 @@ CONFIG_CRYPTO_DES=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig
index e4fac2efc055..4385fe97a780 100644
--- a/arch/sh/configs/sh7785lcr_defconfig
+++ b/arch/sh/configs/sh7785lcr_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Wed Apr 22 19:17:56 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:11:48 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -307,8 +307,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig
index d695e9061874..4e120256ec63 100644
--- a/arch/sh/configs/shmin_defconfig
+++ b/arch/sh/configs/shmin_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:19:03 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:12:41 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
@@ -63,6 +64,7 @@ CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
# CONFIG_BUG is not set
@@ -81,12 +83,15 @@ CONFIG_COMPAT_BRK=y
# CONFIG_SLUB is not set
CONFIG_SLOB=y
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_BASE_SMALL=1
# CONFIG_MODULES is not set
@@ -137,6 +142,7 @@ CONFIG_CPU_SUBTYPE_SH7706=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -146,8 +152,6 @@ CONFIG_CPU_SUBTYPE_SH7706=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -675,6 +679,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -718,6 +727,7 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -762,10 +772,22 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -864,6 +886,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig
index e3651f574399..c088144925fa 100644
--- a/arch/sh/configs/shx3_defconfig
+++ b/arch/sh/configs/shx3_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:20:54 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:13:12 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -42,6 +43,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
@@ -96,6 +98,7 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -126,6 +129,8 @@ CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
@@ -138,7 +143,6 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -186,6 +190,7 @@ CONFIG_CPU_SHX3=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -195,8 +200,6 @@ CONFIG_CPU_SUBTYPE_SHX3=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -553,6 +556,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
@@ -646,6 +650,7 @@ CONFIG_DEVKMEM=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_CONSOLE=y
@@ -985,6 +990,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1008,6 +1014,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1051,6 +1062,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
@@ -1085,6 +1097,9 @@ CONFIG_DEBUG_SHIRQ=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -1124,6 +1139,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1133,11 +1149,16 @@ CONFIG_TRACING=y
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1245,6 +1266,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
#
# Library routines
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
index 6960f60bf52e..54a7a3c41f34 100644
--- a/arch/sh/configs/snapgear_defconfig
+++ b/arch/sh/configs/snapgear_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:21:39 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:14:00 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -64,7 +65,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -73,6 +73,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -92,12 +93,15 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -105,7 +109,6 @@ CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -151,6 +154,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -160,8 +164,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -295,8 +297,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -763,6 +763,11 @@ CONFIG_FILE_LOCKING=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -805,8 +810,13 @@ CONFIG_CRAMFS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
@@ -844,10 +854,23 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -862,6 +885,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig
index 7ea639bc5936..dbe7e546f0bb 100644
--- a/arch/sh/configs/systemh_defconfig
+++ b/arch/sh/configs/systemh_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:23:31 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:14:33 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -61,7 +62,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -70,6 +70,7 @@ CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -88,6 +89,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -95,6 +97,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -107,7 +111,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -153,6 +156,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -162,8 +166,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -506,6 +508,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -547,8 +554,13 @@ CONFIG_CRAMFS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
#
# Partition Types
@@ -577,10 +589,24 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -595,6 +621,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index bbeb4c6ebb95..8ca94ef74278 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:24:55 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:14:55 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -40,6 +41,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
@@ -66,7 +68,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -76,6 +77,7 @@ CONFIG_UID16=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -95,6 +97,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_IOREMAP_PROT=y
@@ -102,6 +105,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -114,7 +119,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -160,6 +164,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -169,8 +174,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -305,8 +308,6 @@ CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw"
#
CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
@@ -789,6 +790,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -906,6 +908,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -929,6 +932,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
@@ -1182,7 +1186,6 @@ CONFIG_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1393,6 +1396,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
# CONFIG_EXT3_FS_XATTR is not set
# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
@@ -1419,6 +1423,11 @@ CONFIG_INOTIFY_USER=y
CONFIG_FUSE_FS=m
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
@@ -1467,8 +1476,13 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1576,6 +1590,7 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -1610,6 +1625,7 @@ CONFIG_SCHED_DEBUG=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1618,9 +1634,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1741,6 +1762,7 @@ CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig
index 34f5192a3241..bfb4d9806892 100644
--- a/arch/sh/configs/ul2_defconfig
+++ b/arch/sh/configs/ul2_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:30:27 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 13:17:05 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -69,7 +70,6 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -78,6 +78,7 @@ CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -97,6 +98,7 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
# CONFIG_OPROFILE is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
@@ -105,6 +107,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -117,7 +121,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -167,6 +170,7 @@ CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -176,8 +180,6 @@ CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
CONFIG_CPU_SUBTYPE_SH7366=y
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -584,6 +586,7 @@ CONFIG_SCSI_WAIT_SCAN=m
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
@@ -936,6 +939,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -958,6 +962,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1005,6 +1014,7 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
@@ -1095,10 +1105,24 @@ CONFIG_FRAME_WARN=1024
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1208,6 +1232,7 @@ CONFIG_CRYPTO_ARC4=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig
index d174b1a4d802..512664fed66c 100644
--- a/arch/sh/configs/urquell_defconfig
+++ b/arch/sh/configs/urquell_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Thu Apr 2 19:33:39 2009
+# Linux kernel version: 2.6.30-rc3
+# Mon Apr 27 14:02:55 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_BUG=y
@@ -76,6 +77,7 @@ CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -94,6 +96,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
# CONFIG_OPROFILE is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
@@ -102,6 +105,8 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -114,7 +119,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -162,6 +166,7 @@ CONFIG_CPU_SHX3=y
# CONFIG_CPU_SUBTYPE_SH7760 is not set
# CONFIG_CPU_SUBTYPE_SH4_202 is not set
# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
# CONFIG_CPU_SUBTYPE_SH7763 is not set
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -171,8 +176,6 @@ CONFIG_CPU_SUBTYPE_SH7786=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
#
# Memory management options
@@ -900,15 +903,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1046,6 +1051,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1068,6 +1074,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1117,6 +1128,7 @@ CONFIG_MINIX_FS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1209,10 +1221,24 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1322,6 +1348,7 @@ CONFIG_CRYPTO_DES=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index 666713ac5fcf..63e9dd30b41c 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -16,7 +16,8 @@ config SH_DMA_IRQ_MULTI
CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7750R || \
CPU_SUBTYPE_SH7751R || CPU_SUBTYPE_SH7091 || \
CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7764 || \
- CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
+ CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 || \
+ CPU_SUBTYPE_SH7760
config NR_ONCHIP_DMA_CHANNELS
int
diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig
index 7e816ededed7..e8db585a6638 100644
--- a/arch/sh/drivers/pci/Kconfig
+++ b/arch/sh/drivers/pci/Kconfig
@@ -17,21 +17,3 @@ config SH_PCIDMA_NONCOHERENT
code will not have to flush the CPU's caches. If you have a PCI host
bridge integrated with your SH CPU, refer carefully to the chip specs
to see if you can say 'N' here. Otherwise, leave it as 'Y'.
-
-# This is also board-specific
-config PCI_AUTO
- bool
- depends on PCI
- default y
-
-config PCI_AUTO_UPDATE_RESOURCES
- bool
- depends on PCI_AUTO
- default y if !SH_DREAMCAST
- help
- Selecting this option will cause the PCI auto code to leave your
- BAR values alone. Otherwise they will be updated automatically. If
- for some reason, you have a board that simply refuses to work
- with its resources updated beyond what they are when the device
- is powered up, set this to N. Everyone else will want this as Y.
-
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index 847e90894d1b..d2ffc477549a 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -1,9 +1,7 @@
#
# Makefile for the PCI specific kernel interface routines under Linux.
#
-
obj-y += pci.o
-obj-$(CONFIG_PCI_AUTO) += pci-auto.o
obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o
@@ -12,15 +10,17 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o
obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o
-obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o
-obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
-obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
-obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
-obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o
-obj-$(CONFIG_SH_SDK7780) += ops-sdk7780.o fixups-sdk7780.o
-obj-$(CONFIG_SH_TITAN) += ops-titan.o
-obj-$(CONFIG_SH_LANDISK) += ops-landisk.o
-obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o
-obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o
-obj-$(CONFIG_SH_CAYMAN) += ops-cayman.o
-obj-$(CONFIG_SH_SH7785LCR) += ops-sh7785lcr.o fixups-sh7785lcr.o
+obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
+ pci-dreamcast.o
+obj-$(CONFIG_SH_SECUREEDGE5410) += fixups-snapgear.o
+obj-$(CONFIG_SH_7751_SOLUTION_ENGINE) += fixups-se7751.o
+obj-$(CONFIG_SH_RTS7751R2D) += fixups-rts7751r2d.o
+obj-$(CONFIG_SH_SH03) += fixups-sh03.o
+obj-$(CONFIG_SH_HIGHLANDER) += fixups-r7780rp.o
+obj-$(CONFIG_SH_SH7785LCR) += fixups-r7780rp.o
+obj-$(CONFIG_SH_SDK7780) += fixups-sdk7780.o
+obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o
+obj-$(CONFIG_SH_TITAN) += fixups-titan.o
+obj-$(CONFIG_SH_LANDISK) += fixups-landisk.o
+obj-$(CONFIG_SH_LBOX_RE2) += fixups-rts7751r2d.o
+obj-$(CONFIG_SH_CAYMAN) += fixups-cayman.o
diff --git a/arch/sh/drivers/pci/ops-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c
index 38ef76207af6..b68b61d22c6c 100644
--- a/arch/sh/drivers/pci/ops-cayman.c
+++ b/arch/sh/drivers/pci/fixups-cayman.c
@@ -75,15 +75,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
return result;
}
-
-struct pci_channel board_pci_channels[] = {
- { &sh5_pci_ops, NULL, NULL, 0, 0xff },
- { NULL, NULL, NULL, 0, 0 },
-};
-EXPORT_SYMBOL(board_pci_channels);
-
-int __init pcibios_init_platform(void)
-{
- return sh5pci_init(__pa(memory_start),
- __pa(memory_end) - __pa(memory_start));
-}
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
index 2bf85cf091e1..ed7f489936f1 100644
--- a/arch/sh/drivers/pci/fixups-dreamcast.c
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -30,7 +30,7 @@
static void __init gapspci_fixup_resources(struct pci_dev *dev)
{
- struct pci_channel *p = board_pci_channels;
+ struct pci_channel *p = dev->sysdata;
printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev));
@@ -41,6 +41,13 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev)
*/
dev->resource[1].start = p->io_resource->start + 0x100;
dev->resource[1].end = dev->resource[1].start + 0x200 - 1;
+
+ /*
+ * This is not a normal BAR, prevent any attempts to move
+ * the BAR, as this will result in a bus lock.
+ */
+ dev->resource[1].flags |= IORESOURCE_PCI_FIXED;
+
/*
* Redirect dma memory allocations to special memory window.
*/
diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/fixups-landisk.c
index bff09ecf3419..bb1a6bb5149e 100644
--- a/arch/sh/drivers/pci/ops-landisk.c
+++ b/arch/sh/drivers/pci/fixups-landisk.c
@@ -15,39 +15,6 @@
#include <linux/pci.h>
#include "pci-sh4.h"
-static struct resource sh7751_io_resource = {
- .name = "SH7751 IO",
- .start = SH7751_PCI_IO_BASE,
- .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource sh7751_mem_resource = {
- .name = "SH7751 mem",
- .start = SH7751_PCI_MEMORY_BASE,
- .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
-};
-
-struct pci_channel board_pci_channels[] = {
- {&sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0x3ff},
- {NULL, NULL, NULL, 0, 0},
-};
-
-static struct sh4_pci_address_map sh7751_pci_map = {
- .window0 = {
- .base = SH7751_CS3_BASE_ADDR,
- .size = (64 << 20), /* 64MB */
- },
-
- .flags = SH4_PCIC_NO_RESET,
-};
-
-int __init pcibios_init_platform(void)
-{
- return sh7751_pcic_init(&sh7751_pci_map);
-}
-
int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
{
/*
diff --git a/arch/sh/drivers/pci/fixups-lboxre2.c b/arch/sh/drivers/pci/fixups-lboxre2.c
deleted file mode 100644
index 1c1d41255ec0..000000000000
--- a/arch/sh/drivers/pci/fixups-lboxre2.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * arch/sh/drivers/pci/fixups-lboxre2.c
- *
- * L-BOX RE2 PCI fixups
- *
- * Copyright (C) 2007 Nobuhiro Iwamatsu
- *
- * 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 "pci-sh4.h"
-
-#define PCIMCR_MRSET_OFF 0xBFFFFFFF
-#define PCIMCR_RFSH_OFF 0xFFFFFFFB
-
-int pci_fixup_pcic(void)
-{
- unsigned long bcr1, mcr;
-
- bcr1 = ctrl_inl(SH7751_BCR1);
- bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
- pci_write_reg(bcr1, SH4_PCIBCR1);
-
- /* Enable all interrupts, so we known what to fix */
- pci_write_reg(0x0000c3ff, SH4_PCIINTM);
- pci_write_reg(0x0000380f, SH4_PCIAINTM);
- pci_write_reg(0xfb900047, SH7751_PCICONF1);
- pci_write_reg(0xab000001, SH7751_PCICONF4);
-
- mcr = ctrl_inl(SH7751_MCR);
- mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
- pci_write_reg(mcr, SH4_PCIMCR);
-
- pci_write_reg(0x0c000000, SH7751_PCICONF5);
- pci_write_reg(0xd0000000, SH7751_PCICONF6);
- pci_write_reg(0x0c000000, SH4_PCILAR0);
- pci_write_reg(0x00000000, SH4_PCILAR1);
-
- return 0;
-}
diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c
index 3e321df65d22..15ca65cb667e 100644
--- a/arch/sh/drivers/pci/fixups-r7780rp.c
+++ b/arch/sh/drivers/pci/fixups-r7780rp.c
@@ -11,35 +11,26 @@
* for more details.
*/
#include <linux/pci.h>
+#include <linux/io.h>
#include "pci-sh4.h"
-#include <asm/io.h>
-int pci_fixup_pcic(void)
-{
- pci_write_reg(0x000043ff, SH4_PCIINTM);
- pci_write_reg(0x0000380f, SH4_PCIAINTM);
-
- pci_write_reg(0xfbb00047, SH7780_PCICMD);
- pci_write_reg(0x00000000, SH7780_PCIIBAR);
-
- pci_write_reg(0x00011912, SH7780_PCISVID);
- pci_write_reg(0x08000000, SH7780_PCICSCR0);
- pci_write_reg(0x0000001b, SH7780_PCICSAR0);
- pci_write_reg(0xfd000000, SH7780_PCICSCR1);
- pci_write_reg(0x0000000f, SH7780_PCICSAR1);
-
- pci_write_reg(0xfd000000, SH7780_PCIMBR0);
- pci_write_reg(0x00fc0000, SH7780_PCIMBMR0);
+static char irq_tab[] __initdata = {
+ 65, 66, 67, 68,
+};
-#ifdef CONFIG_32BIT
- pci_write_reg(0xc0000000, SH7780_PCIMBR2);
- pci_write_reg(0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2);
-#endif
+int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
+{
+ return irq_tab[slot];
+}
- /* Set IOBR for windows containing area specified in pci.h */
- pci_write_reg((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)),
- SH7780_PCIIOBR);
- pci_write_reg(((SH7780_PCI_IO_SIZE-1) & (7<<18)), SH7780_PCIIOBMR);
+int pci_fixup_pcic(struct pci_channel *chan)
+{
+ pci_write_reg(chan, 0x000043ff, SH4_PCIINTM);
+ pci_write_reg(chan, 0x00000000, SH7780_PCIIBAR);
+ pci_write_reg(chan, 0x08000000, SH7780_PCICSCR0);
+ pci_write_reg(chan, 0x0000001b, SH7780_PCICSAR0);
+ pci_write_reg(chan, 0xfd000000, SH7780_PCICSCR1);
+ pci_write_reg(chan, 0x0000000f, SH7780_PCICSAR1);
return 0;
}
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c
index 904bce8768d3..052b354236dc 100644
--- a/arch/sh/drivers/pci/fixups-rts7751r2d.c
+++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c
@@ -1,43 +1,67 @@
/*
* arch/sh/drivers/pci/fixups-rts7751r2d.c
*
- * RTS7751R2D PCI fixups
+ * RTS7751R2D / LBOXRE2 PCI fixups
*
* Copyright (C) 2003 Lineo uSolutions, Inc.
* Copyright (C) 2004 Paul Mundt
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
*
* 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/pci.h>
+#include <mach/lboxre2.h>
+#include <mach/r2d.h>
#include "pci-sh4.h"
+#include <asm/machtypes.h>
#define PCIMCR_MRSET_OFF 0xBFFFFFFF
#define PCIMCR_RFSH_OFF 0xFFFFFFFB
-int pci_fixup_pcic(void)
+static u8 rts7751r2d_irq_tab[] __initdata = {
+ IRQ_PCI_INTA,
+ IRQ_PCI_INTB,
+ IRQ_PCI_INTC,
+ IRQ_PCI_INTD,
+};
+
+static char lboxre2_irq_tab[] __initdata = {
+ IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD,
+};
+
+int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
+{
+ if (mach_is_lboxre2())
+ return lboxre2_irq_tab[slot];
+ else
+ return rts7751r2d_irq_tab[slot];
+}
+
+int pci_fixup_pcic(struct pci_channel *chan)
{
unsigned long bcr1, mcr;
bcr1 = ctrl_inl(SH7751_BCR1);
bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
- pci_write_reg(bcr1, SH4_PCIBCR1);
+ pci_write_reg(chan, bcr1, SH4_PCIBCR1);
/* Enable all interrupts, so we known what to fix */
- pci_write_reg(0x0000c3ff, SH4_PCIINTM);
- pci_write_reg(0x0000380f, SH4_PCIAINTM);
+ pci_write_reg(chan, 0x0000c3ff, SH4_PCIINTM);
+ pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM);
- pci_write_reg(0xfb900047, SH7751_PCICONF1);
- pci_write_reg(0xab000001, SH7751_PCICONF4);
+ pci_write_reg(chan, 0xfb900047, SH7751_PCICONF1);
+ pci_write_reg(chan, 0xab000001, SH7751_PCICONF4);
mcr = ctrl_inl(SH7751_MCR);
mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
- pci_write_reg(mcr, SH4_PCIMCR);
+ pci_write_reg(chan, mcr, SH4_PCIMCR);
- pci_write_reg(0x0c000000, SH7751_PCICONF5);
- pci_write_reg(0xd0000000, SH7751_PCICONF6);
- pci_write_reg(0x0c000000, SH4_PCILAR0);
- pci_write_reg(0x00000000, SH4_PCILAR1);
+ pci_write_reg(chan, 0x0c000000, SH7751_PCICONF5);
+ pci_write_reg(chan, 0xd0000000, SH7751_PCICONF6);
+ pci_write_reg(chan, 0x0c000000, SH4_PCILAR0);
+ pci_write_reg(chan, 0x00000000, SH4_PCILAR1);
return 0;
}
diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c
index 2f8863099dd1..250b0edd7365 100644
--- a/arch/sh/drivers/pci/fixups-sdk7780.c
+++ b/arch/sh/drivers/pci/fixups-sdk7780.c
@@ -5,55 +5,48 @@
*
* Copyright (C) 2003 Lineo uSolutions, Inc.
* Copyright (C) 2004 - 2006 Paul Mundt
+ * Copyright (C) 2006 Nobuhiro Iwamatsu
*
* 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/pci.h>
+#include <linux/io.h>
#include "pci-sh4.h"
-#include <asm/io.h>
-int pci_fixup_pcic(void)
+/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */
+static char sdk7780_irq_tab[4][16] __initdata = {
+ /* INTA */
+ { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ /* INTB */
+ { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ /* INTC */
+ { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ /* INTD */
+ { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+};
+
+int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
+{
+ return sdk7780_irq_tab[pin-1][slot];
+}
+int pci_fixup_pcic(struct pci_channel *chan)
{
- ctrl_outl(0x00000001, SH7780_PCI_VCR2);
-
/* Enable all interrupts, so we know what to fix */
- pci_write_reg(0x0000C3FF, SH7780_PCIIMR);
- pci_write_reg(0x0000380F, SH7780_PCIAINTM);
+ pci_write_reg(chan, 0x0000C3FF, SH7780_PCIIMR);
/* Set up standard PCI config registers */
- pci_write_reg(0xFB00, SH7780_PCISTATUS);
- pci_write_reg(0x0047, SH7780_PCICMD);
- pci_write_reg(0x00, SH7780_PCIPIF);
- pci_write_reg(0x00, SH7780_PCISUB);
- pci_write_reg(0x06, SH7780_PCIBCC);
- pci_write_reg(0x1912, SH7780_PCISVID);
- pci_write_reg(0x0001, SH7780_PCISID);
-
- pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */
- pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */
- pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */
-
- pci_write_reg(0x00000000, SH7780_PCIMBAR1);
- pci_write_reg(0x00000000, SH7780_PCILAR1);
- pci_write_reg(0x00000000, SH7780_PCILSR1);
-
- pci_write_reg(0xAB000801, SH7780_PCIIBAR);
-
- /*
- * Set the MBR so PCI address is one-to-one with window,
- * meaning all calls go straight through... use ifdef to
- * catch erroneous assumption.
- */
- pci_write_reg(0xFD000000 , SH7780_PCIMBR0);
- pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */
+ pci_write_reg(chan, 0x08000000, SH7780_PCIMBAR0); /* PCI */
+ pci_write_reg(chan, 0x08000000, SH4_PCILAR0); /* SHwy */
+ pci_write_reg(chan, 0x07F00001, SH4_PCILSR0); /* size 128M w/ MBAR */
- /* Set IOBR for window containing area specified in pci.h */
- pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR);
- pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR);
+ pci_write_reg(chan, 0x00000000, SH7780_PCIMBAR1);
+ pci_write_reg(chan, 0x00000000, SH4_PCILAR1);
+ pci_write_reg(chan, 0x00000000, SH4_PCILSR1);
- pci_write_reg(0xA5000C01, SH7780_PCICR);
+ pci_write_reg(chan, 0xAB000801, SH7780_PCIIBAR);
+ pci_write_reg(chan, 0xA5000C01, SH4_PCICR);
return 0;
}
diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c
new file mode 100644
index 000000000000..475fa9f0fe2c
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-se7751.c
@@ -0,0 +1,111 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include "pci-sh4.h"
+
+int __init pcibios_map_platform_irq(u8 slot, u8 pin)
+{
+ switch (slot) {
+ case 0: return 13;
+ case 1: return 13; /* AMD Ethernet controller */
+ case 2: return -1;
+ case 3: return -1;
+ case 4: return -1;
+ default:
+ printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
+ return -1;
+ }
+}
+
+#define PCIMCR_MRSET_OFF 0xBFFFFFFF
+#define PCIMCR_RFSH_OFF 0xFFFFFFFB
+
+/*
+ * Only long word accesses of the PCIC's internal local registers and the
+ * configuration registers from the CPU is supported.
+ */
+#define PCIC_WRITE(x,v) writel((v), PCI_REG(x))
+#define PCIC_READ(x) readl(PCI_REG(x))
+
+/*
+ * Description: This function sets up and initializes the pcic, sets
+ * up the BARS, maps the DRAM into the address space etc, etc.
+ */
+int pci_fixup_pcic(struct pci_channel *chan)
+{
+ unsigned long bcr1, wcr1, wcr2, wcr3, mcr;
+ unsigned short bcr2;
+
+ /*
+ * Initialize the slave bus controller on the pcic. The values used
+ * here should not be hardcoded, but they should be taken from the bsc
+ * on the processor, to make this function as generic as possible.
+ * (i.e. Another sbc may usr different SDRAM timing settings -- in order
+ * for the pcic to work, its settings need to be exactly the same.)
+ */
+ bcr1 = (*(volatile unsigned long*)(SH7751_BCR1));
+ bcr2 = (*(volatile unsigned short*)(SH7751_BCR2));
+ wcr1 = (*(volatile unsigned long*)(SH7751_WCR1));
+ wcr2 = (*(volatile unsigned long*)(SH7751_WCR2));
+ wcr3 = (*(volatile unsigned long*)(SH7751_WCR3));
+ mcr = (*(volatile unsigned long*)(SH7751_MCR));
+
+ bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */
+ (*(volatile unsigned long*)(SH7751_BCR1)) = bcr1;
+
+ bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
+ PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */
+ PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */
+ PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */
+ PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */
+ PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */
+ mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
+ PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */
+
+
+ /* Enable all interrupts, so we know what to fix */
+ PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff);
+ PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f);
+
+ /* Set up standard PCI config registers */
+ PCIC_WRITE(SH7751_PCICONF1, 0xF39000C7); /* Bus Master, Mem & I/O access */
+ PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */
+ PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */
+ PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */
+ PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */
+ PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */
+ PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */
+ PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */
+ PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */
+ PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */
+
+ /* Now turn it on... */
+ PCIC_WRITE(SH7751_PCICR, 0xa5000001);
+
+ /*
+ * Set PCIMBR and PCIIOBR here, assuming a single window
+ * (16M MEM, 256K IO) is enough. If a larger space is
+ * needed, the readx/writex and inx/outx functions will
+ * have to do more (e.g. setting registers for each call).
+ */
+
+ /*
+ * Set the MBR so PCI address is one-to-one with window,
+ * meaning all calls go straight through... use BUG_ON to
+ * catch erroneous assumption.
+ */
+ BUG_ON(chan->mem_resource->start != SH7751_PCI_MEMORY_BASE);
+
+ PCIC_WRITE(SH7751_PCIMBR, chan->mem_resource->start);
+
+ /* Set IOBR for window containing area specified in pci.h */
+ PCIC_WRITE(SH7751_PCIIOBR, (chan->io_resource->start & SH7751_PCIIOBR_MASK));
+
+ /* All done, may as well say so... */
+ printk("SH7751 PCI: Finished initialization of the PCI controller\n");
+
+ return 1;
+}
diff --git a/arch/sh/drivers/pci/fixups-se7780.c b/arch/sh/drivers/pci/fixups-se7780.c
deleted file mode 100644
index 880cea1c0d89..000000000000
--- a/arch/sh/drivers/pci/fixups-se7780.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * arch/sh/drivers/pci/fixups-se7780.c
- *
- * HITACHI UL Solution Engine 7780 PCI fixups
- *
- * Copyright (C) 2003 Lineo uSolutions, Inc.
- * Copyright (C) 2004 - 2006 Paul Mundt
- * Copyright (C) 2006 Nobuhiro Iwamatsu
- *
- * 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/pci.h>
-#include "pci-sh4.h"
-#include <asm/io.h>
-
-int pci_fixup_pcic(void)
-{
- ctrl_outl(0x00000001, SH7780_PCI_VCR2);
-
- /* Enable all interrupts, so we know what to fix */
- pci_write_reg(0x0000C3FF, SH7780_PCIIMR);
- pci_write_reg(0x0000380F, SH7780_PCIAINTM);
-
- /* Set up standard PCI config registers */
- ctrl_outw(0xFB00, PCI_REG(SH7780_PCISTATUS));
- ctrl_outw(0x0047, PCI_REG(SH7780_PCICMD));
- ctrl_outb( 0x00, PCI_REG(SH7780_PCIPIF));
- ctrl_outb( 0x00, PCI_REG(SH7780_PCISUB));
- ctrl_outb( 0x06, PCI_REG(SH7780_PCIBCC));
- ctrl_outw(0x1912, PCI_REG(SH7780_PCISVID));
- ctrl_outw(0x0001, PCI_REG(SH7780_PCISID));
-
- pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */
- pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */
- pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */
-
- pci_write_reg(0x00000000, SH7780_PCIMBAR1);
- pci_write_reg(0x00000000, SH7780_PCILAR1);
- pci_write_reg(0x00000000, SH7780_PCILSR1);
-
- pci_write_reg(0xAB000801, SH7780_PCIIBAR);
-
- /*
- * Set the MBR so PCI address is one-to-one with window,
- * meaning all calls go straight through... use ifdef to
- * catch erroneous assumption.
- */
- pci_write_reg(0xFD000000 , SH7780_PCIMBR0);
- pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */
-
- /* Set IOBR for window containing area specified in pci.h */
- pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR);
- pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR);
-
- pci_write_reg(0xA5000C01, SH7780_PCICR);
-
- return 0;
-}
diff --git a/arch/sh/drivers/pci/fixups-sh7785lcr.c b/arch/sh/drivers/pci/fixups-sh7785lcr.c
deleted file mode 100644
index 4949e601387a..000000000000
--- a/arch/sh/drivers/pci/fixups-sh7785lcr.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * arch/sh/drivers/pci/fixups-sh7785lcr.c
- *
- * R0P7785LC0011RL PCI fixups
- * Copyright (C) 2008 Yoshihiro Shimoda
- *
- * Based on arch/sh/drivers/pci/fixups-r7780rp.c
- * Copyright (C) 2003 Lineo uSolutions, Inc.
- * Copyright (C) 2004 - 2006 Paul Mundt
- *
- * 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/pci.h>
-#include "pci-sh4.h"
-
-int pci_fixup_pcic(void)
-{
- pci_write_reg(0x000043ff, SH4_PCIINTM);
- pci_write_reg(0x0000380f, SH4_PCIAINTM);
-
- pci_write_reg(0xfbb00047, SH7780_PCICMD);
- pci_write_reg(0x00000000, SH7780_PCIIBAR);
-
- pci_write_reg(0x00011912, SH7780_PCISVID);
- pci_write_reg(0x08000000, SH7780_PCICSCR0);
- pci_write_reg(0x0000001b, SH7780_PCICSAR0);
- pci_write_reg(0xfd000000, SH7780_PCICSCR1);
- pci_write_reg(0x0000000f, SH7780_PCICSAR1);
-
- pci_write_reg(0xfd000000, SH7780_PCIMBR0);
- pci_write_reg(0x00fc0000, SH7780_PCIMBMR0);
-
-#ifdef CONFIG_32BIT
- pci_write_reg(0xc0000000, SH7780_PCIMBR2);
- pci_write_reg(0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2);
-#endif
-
- /* Set IOBR for windows containing area specified in pci.h */
- pci_write_reg((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)),
- SH7780_PCIIOBR);
- pci_write_reg(((SH7780_PCI_IO_SIZE - 1) & (7 << 18)), SH7780_PCIIOBMR);
-
- return 0;
-}
diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c
new file mode 100644
index 000000000000..5a39ecc1adb8
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-snapgear.c
@@ -0,0 +1,38 @@
+/*
+ * arch/sh/drivers/pci/ops-snapgear.c
+ *
+ * Author: David McCullough <davidm@snapgear.com>
+ *
+ * Ported to new API by Paul Mundt <lethal@linux-sh.org>
+ *
+ * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * PCI initialization for the SnapGear boards
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include "pci-sh4.h"
+
+int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
+{
+ int irq = -1;
+
+ switch (slot) {
+ case 8: /* the PCI bridge */ break;
+ case 11: irq = 8; break; /* USB */
+ case 12: irq = 11; break; /* PCMCIA */
+ case 13: irq = 5; break; /* eth0 */
+ case 14: irq = 8; break; /* eth1 */
+ case 15: irq = 11; break; /* safenet (unused) */
+ }
+
+ printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n",
+ slot, pin - 1 + 'A', irq);
+
+ return irq;
+}
diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/fixups-titan.c
index a8f7801a34af..3a79fa8254a6 100644
--- a/arch/sh/drivers/pci/ops-titan.c
+++ b/arch/sh/drivers/pci/fixups-titan.c
@@ -36,42 +36,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
return irq;
}
-
-static struct resource sh7751_io_resource = {
- .name = "SH7751_IO",
- .start = SH7751_PCI_IO_BASE,
- .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource sh7751_mem_resource = {
- .name = "SH7751_mem",
- .start = SH7751_PCI_MEMORY_BASE,
- .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
-};
-
-struct pci_channel board_pci_channels[] = {
- { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
- { NULL, NULL, NULL, 0, 0 },
-};
-EXPORT_SYMBOL(board_pci_channels);
-
-static struct sh4_pci_address_map sh7751_pci_map = {
- .window0 = {
- .base = SH7751_CS2_BASE_ADDR,
- .size = SH7751_MEM_REGION_SIZE*2, /* cs2 and cs3 */
- },
-
- .window1 = {
- .base = SH7751_CS2_BASE_ADDR,
- .size = SH7751_MEM_REGION_SIZE*2,
- },
-
- .flags = SH4_PCIC_NO_RESET,
-};
-
-int __init pcibios_init_platform(void)
-{
- return sh7751_pcic_init(&sh7751_pci_map);
-}
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c
index f5d2a2aa6f3f..e83d0d3aabe2 100644
--- a/arch/sh/drivers/pci/ops-dreamcast.c
+++ b/arch/sh/drivers/pci/ops-dreamcast.c
@@ -1,15 +1,9 @@
/*
- * arch/sh/drivers/pci/ops-dreamcast.c
- *
* PCI operations for the Sega Dreamcast
*
* Copyright (C) 2001, 2002 M. R. Brown
* Copyright (C) 2002, 2003 Paul Mundt
*
- * This file originally bore the message (with enclosed-$):
- * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
- * Dreamcast PCI: Supports SEGA Broadband Adaptor only.
- *
* 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.
@@ -23,34 +17,10 @@
#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/module.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <linux/io.h>
+#include <linux/irq.h>
#include <mach/pci.h>
-static struct resource gapspci_io_resource = {
- .name = "GAPSPCI IO",
- .start = GAPSPCI_BBA_CONFIG,
- .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1,
- .flags = IORESOURCE_IO,
-};
-
-static struct resource gapspci_mem_resource = {
- .name = "GAPSPCI mem",
- .start = GAPSPCI_DMA_BASE,
- .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct pci_ops gapspci_pci_ops;
-
-struct pci_channel board_pci_channels[] = {
- { &gapspci_pci_ops, &gapspci_io_resource,
- &gapspci_mem_resource, 0, 1 },
- { 0, }
-};
-EXPORT_SYMBOL(board_pci_channels);
-
/*
* The !gapspci_config_access case really shouldn't happen, ever, unless
* someone implicitly messes around with the last devfn value.. otherwise we
@@ -85,10 +55,10 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
- case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break;
- case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break;
- case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break;
- }
+ case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break;
+ case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break;
+ case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break;
+ }
return PCIBIOS_SUCCESSFUL;
}
@@ -99,72 +69,15 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
- case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
- case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
- case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
+ case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
+ case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
+ case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
}
return PCIBIOS_SUCCESSFUL;
}
-static struct pci_ops gapspci_pci_ops = {
+struct pci_ops gapspci_pci_ops = {
.read = gapspci_read,
.write = gapspci_write,
};
-
-/*
- * gapspci init
- */
-
-int __init gapspci_init(void)
-{
- char idbuf[16];
- int i;
-
- /*
- * FIXME: All of this wants documenting to some degree,
- * even some basic register definitions would be nice.
- *
- * I haven't seen anything this ugly since.. maple.
- */
-
- for (i=0; i<16; i++)
- idbuf[i] = inb(GAPSPCI_REGS+i);
-
- if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
- return -ENODEV;
-
- outl(0x5a14a501, GAPSPCI_REGS+0x18);
-
- for (i=0; i<1000000; i++)
- ;
-
- if (inl(GAPSPCI_REGS+0x18) != 1)
- return -EINVAL;
-
- outl(0x01000000, GAPSPCI_REGS+0x20);
- outl(0x01000000, GAPSPCI_REGS+0x24);
-
- outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
- outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
-
- outl(1, GAPSPCI_REGS+0x14);
- outl(1, GAPSPCI_REGS+0x34);
-
- /* Setting Broadband Adapter */
- outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
- outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
- outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
- outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
- outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
- outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
- outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
-
- return 0;
-}
-
-/* Haven't done anything here as yet */
-char * __devinit pcibios_setup(char *str)
-{
- return str;
-}
diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c
deleted file mode 100644
index 86c0b6fb7375..000000000000
--- a/arch/sh/drivers/pci/ops-lboxre2.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * linux/arch/sh/drivers/pci/ops-lboxre2.c
- *
- * Copyright (C) 2007 Nobuhiro Iwamatsu
- *
- * PCI initialization for the NTT COMWARE L-BOX RE2
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/io.h>
-#include <mach/lboxre2.h>
-#include "pci-sh4.h"
-
-static char lboxre2_irq_tab[] __initdata = {
- IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD,
-};
-
-int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
-{
- return lboxre2_irq_tab[slot];
-}
-
-static struct resource sh7751_io_resource = {
- .name = "SH7751_IO",
- .start = SH7751_PCI_IO_BASE ,
- .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource sh7751_mem_resource = {
- .name = "SH7751_mem",
- .start = SH7751_PCI_MEMORY_BASE,
- .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
-};
-
-extern struct pci_ops sh7751_pci_ops;
-
-struct pci_channel board_pci_channels[] = {
- { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
- { NULL, NULL, NULL, 0, 0 },
-};
-
-EXPORT_SYMBOL(board_pci_channels);
-
-static struct sh4_pci_address_map sh7751_pci_map = {
- .window0 = {
- .base = SH7751_CS3_BASE_ADDR,
- .size = 0x04000000,
- },
- .window1 = {
- .base = 0x00000000, /* Unused */
- .size = 0x00000000, /* Unused */
- },
- .flags = SH4_PCIC_NO_RESET,
-};
-
-int __init pcibios_init_platform(void)
-{
- return sh7751_pcic_init(&sh7751_pci_map);
-}
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
deleted file mode 100644
index 8555238e63eb..000000000000
--- a/arch/sh/drivers/pci/ops-r7780rp.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Author: Ian DaSilva (idasilva@mvista.com)
- *
- * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * PCI initialization for the Renesas SH7780 Highlander R7780RP-1 board
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <mach/highlander.h>
-#include <asm/io.h>
-#include "pci-sh4.h"
-
-static char irq_tab[] __initdata = {
- 65, 66, 67, 68,
-};
-
-int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
-{
- return irq_tab[slot];
-}
-
-static struct resource sh7780_io_resource = {
- .name = "SH7780_IO",
- .start = SH7780_PCI_IO_BASE,
- .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource sh7780_mem_resource = {
- .name = "SH7780_mem",
- .start = SH7780_PCI_MEMORY_BASE,
- .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
-};
-
-extern struct pci_ops sh7780_pci_ops;
-
-struct pci_channel board_pci_channels[] = {
- { &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff },
- { NULL, NULL, NULL, 0, 0 },
-};
-EXPORT_SYMBOL(board_pci_channels);
-
-static struct sh4_pci_address_map sh7780_pci_map = {
- .window0 = {
- .base = SH7780_CS2_BASE_ADDR,
- .size = 0x04000000,
- },
-
- .window1 = {
- .base = SH7780_CS3_BASE_ADDR,
- .size = 0x04000000,
- },
-
- .flags = SH4_PCIC_NO_RESET,
-};
-
-int __init pcibios_init_platform(void)
-{
- return sh7780_pcic_init(&sh7780_pci_map);
-}
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c
deleted file mode 100644
index d6ca74b25d5f..000000000000
--- a/arch/sh/drivers/pci/ops-rts7751r2d.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * linux/arch/sh/drivers/pci/ops-rts7751r2d.c
- *
- * Author: Ian DaSilva (idasilva@mvista.com)
- *
- * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * PCI initialization for the Renesas SH7751R RTS7751R2D board
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/io.h>
-#include <mach/r2d.h>
-#include "pci-sh4.h"
-
-static u8 rts7751r2d_irq_tab[] __initdata = {
- IRQ_PCI_INTA,
- IRQ_PCI_INTB,
- IRQ_PCI_INTC,
- IRQ_PCI_INTD,
-};
-
-int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
-{
- return rts7751r2d_irq_tab[slot];
-}
-
-static struct resource sh7751_io_resource = {
- .name = "SH7751_IO",
- .start = 0x4000,
- .end = SH7751_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource sh7751_mem_resource = {
- .name = "SH7751_mem",
- .start = SH7751_PCI_MEMORY_BASE,
- .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
-};
-
-extern struct pci_ops sh7751_pci_ops;
-
-struct pci_channel board_pci_channels[] = {
- { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
- { NULL, NULL, NULL, 0, 0 },
-};
-EXPORT_SYMBOL(board_pci_channels);
-
-static struct sh4_pci_address_map sh7751_pci_map = {
- .window0 = {
- .base = SH7751_CS3_BASE_ADDR,
- .size = 0x04000000,
- },
-
- .window1 = {
- .base = 0x00000000, /* Unused */
- .size = 0x00000000, /* Unused */
- },
-
- .flags = SH4_PCIC_NO_RESET,
-};
-
-int __init pcibios_init_platform(void)
-{
- __set_io_port_base(SH7751_PCI_IO_BASE);
- return sh7751_pcic_init(&sh7751_pci_map);
-}
-
diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c
deleted file mode 100644
index 4dcc64184b23..000000000000
--- a/arch/sh/drivers/pci/ops-sdk7780.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * linux/arch/sh/drivers/pci/ops-sdk7780.c
- *
- * Copyright (C) 2006 Nobuhiro Iwamatsu
- *
- * PCI initialization for the SDK7780SE03
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <mach/sdk7780.h>
-#include <asm/io.h>
-#include "pci-sh4.h"
-
-/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */
-static char sdk7780_irq_tab[4][16] __initdata = {
- /* INTA */
- { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- /* INTB */
- { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- /* INTC */
- { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- /* INTD */
- { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
-};
-
-int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
-{
- return sdk7780_irq_tab[pin-1][slot];
-}
-
-static struct resource sdk7780_io_resource = {
- .name = "SH7780_IO",
- .start = SH7780_PCI_IO_BASE,
- .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource sdk7780_mem_resource = {
- .name = "SH7780_mem",
- .start = SH7780_PCI_MEMORY_BASE,
- .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
-};
-
-struct pci_channel board_pci_channels[] = {
- { &sh4_pci_ops, &sdk7780_io_resource, &sdk7780_mem_resource, 0, 0xff },
- { NULL, NULL, NULL, 0, 0 },
-};
-EXPORT_SYMBOL(board_pci_channels);
-
-static struct sh4_pci_address_map sdk7780_pci_map = {
- .window0 = {
- .base = SH7780_CS2_BASE_ADDR,
- .size = 0x04000000,
- },
- .window1 = {
- .base = SH7780_CS3_BASE_ADDR,
- .size = 0x04000000,
- },
- .flags = SH4_PCIC_NO_RESET,
-};
-
-int __init pcibios_init_platform(void)
-{
- printk(KERN_INFO "SH7780 PCI: Finished initializing PCI controller\n");
- return sh7780_pcic_init(&sdk7780_pci_map);
-}
diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c
deleted file mode 100644
index 3145c62484d6..000000000000
--- a/arch/sh/drivers/pci/ops-se7780.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * linux/arch/sh/drivers/pci/ops-se7780.c
- *
- * Copyright (C) 2006 Nobuhiro Iwamatsu
- *
- * PCI initialization for the Hitachi UL Solution Engine 7780SE03
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <mach-se/mach/se7780.h>
-#include <asm/io.h>
-#include "pci-sh4.h"
-
-/*
- * IDSEL = AD16 PCI slot
- * IDSEL = AD17 PCI slot
- * IDSEL = AD18 Serial ATA Controller (Silicon Image SiL3512A)
- * IDSEL = AD19 USB Host Controller (NEC uPD7210100A)
- */
-
-/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */
-static char se7780_irq_tab[4][16] __initdata = {
- /* INTA */
- { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- /* INTB */
- { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- /* INTC */
- { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- /* INTD */
- { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
-};
-
-int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
-{
- return se7780_irq_tab[pin-1][slot];
-}
-
-static struct resource se7780_io_resource = {
- .name = "SH7780_IO",
- .start = SH7780_PCI_IO_BASE,
- .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource se7780_mem_resource = {
- .name = "SH7780_mem",
- .start = SH7780_PCI_MEMORY_BASE,
- .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
-};
-
-extern struct pci_ops se7780_pci_ops;
-
-struct pci_channel board_pci_channels[] = {
- { &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff },
- { NULL, NULL, NULL, 0, 0 },
-};
-EXPORT_SYMBOL(board_pci_channels);
-
-static struct sh4_pci_address_map se7780_pci_map = {
- .window0 = {
- .base = SH7780_CS2_BASE_ADDR,
- .size = 0x04000000,
- },
- .flags = SH4_PCIC_NO_RESET,
-};
-
-int __init pcibios_init_platform(void)
-{
- printk("SH7780 PCI: Finished initialization of the PCI controller\n");
-
- /*
- * FPGA PCISEL register initialize
- *
- * CPU || SLOT1 | SLOT2 | S-ATA | USB
- * -------------------------------------
- * INTA || INTA | INTD | -- | INTB
- * -------------------------------------
- * INTB || INTB | INTA | -- | INTC
- * -------------------------------------
- * INTC || INTC | INTB | INTA | --
- * -------------------------------------
- * INTD || INTD | INTC | -- | INTA
- * -------------------------------------
- */
- ctrl_outw(0x0013, FPGA_PCI_INTSEL1);
- ctrl_outw(0xE402, FPGA_PCI_INTSEL2);
-
- return sh7780_pcic_init(&se7780_pci_map);
-}
diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c
deleted file mode 100644
index e1703ff5a4d2..000000000000
--- a/arch/sh/drivers/pci/ops-sh03.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * linux/arch/sh/drivers/pci/ops-sh03.c
- *
- * PCI initialization for the Interface CTP/PCI-SH03 board
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-#include "pci-sh7751.h"
-
-/*
- * Description: This function sets up and initializes the pcic, sets
- * up the BARS, maps the DRAM into the address space etc, etc.
- */
-int __init pcibios_init_platform(void)
-{
- __set_io_port_base(SH7751_PCI_IO_BASE);
- return 1;
-}
-
-static struct resource sh7751_io_resource = {
- .name = "SH03 IO",
- .start = SH7751_PCI_IO_BASE,
- .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource sh7751_mem_resource = {
- .name = "SH03 mem",
- .start = SH7751_PCI_MEMORY_BASE,
- .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
-};
-
-extern struct pci_ops sh4_pci_ops;
-
-struct pci_channel board_pci_channels[] = {
- { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
- { NULL, NULL, NULL, 0, 0 },
-};
-
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c
index 710a3b0306e5..78bebebdc99c 100644
--- a/arch/sh/drivers/pci/ops-sh4.c
+++ b/arch/sh/drivers/pci/ops-sh4.c
@@ -1,22 +1,22 @@
/*
* Generic SH-4 / SH-4A PCIC operations (SH7751, SH7780).
*
- * Copyright (C) 2002 - 2006 Paul Mundt
+ * Copyright (C) 2002 - 2009 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License v2. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/pci.h>
+#include <linux/io.h>
#include <asm/addrspace.h>
-#include <asm/io.h>
#include "pci-sh4.h"
/*
* Direct access to PCI hardware...
*/
#define CONFIG_CMD(bus, devfn, where) \
- P1SEGADDR((bus->number << 16) | (devfn << 8) | (where & ~3))
+ (P1SEG | (bus->number << 16) | (devfn << 8) | (where & ~3))
static DEFINE_SPINLOCK(sh4_pci_lock);
@@ -26,6 +26,7 @@ static DEFINE_SPINLOCK(sh4_pci_lock);
static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
+ struct pci_channel *chan = bus->sysdata;
unsigned long flags;
u32 data;
@@ -34,8 +35,8 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
* so we must do byte alignment by hand
*/
spin_lock_irqsave(&sh4_pci_lock, flags);
- pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
- data = pci_read_reg(SH4_PCIPDR);
+ pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
+ data = pci_read_reg(chan, SH4_PCIPDR);
spin_unlock_irqrestore(&sh4_pci_lock, flags);
switch (size) {
@@ -63,13 +64,14 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
+ struct pci_channel *chan = bus->sysdata;
unsigned long flags;
int shift;
u32 data;
spin_lock_irqsave(&sh4_pci_lock, flags);
- pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
- data = pci_read_reg(SH4_PCIPDR);
+ pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
+ data = pci_read_reg(chan, SH4_PCIPDR);
spin_unlock_irqrestore(&sh4_pci_lock, flags);
switch (size) {
@@ -90,7 +92,7 @@ static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_FUNC_NOT_SUPPORTED;
}
- pci_write_reg(data, SH4_PCIPDR);
+ pci_write_reg(chan, data, SH4_PCIPDR);
return PCIBIOS_SUCCESSFUL;
}
@@ -104,66 +106,31 @@ struct pci_ops sh4_pci_ops = {
* Not really related to pci_ops, but it's common and not worth shoving
* somewhere else for now..
*/
-static unsigned int pci_probe = PCI_PROBE_CONF1;
-
-int __init sh4_pci_check_direct(void)
+int __init sh4_pci_check_direct(struct pci_channel *chan)
{
/*
* Check if configuration works.
*/
- if (pci_probe & PCI_PROBE_CONF1) {
- unsigned int tmp = pci_read_reg(SH4_PCIPAR);
-
- pci_write_reg(P1SEG, SH4_PCIPAR);
+ unsigned int tmp = pci_read_reg(chan, SH4_PCIPAR);
- if (pci_read_reg(SH4_PCIPAR) == P1SEG) {
- pci_write_reg(tmp, SH4_PCIPAR);
- printk(KERN_INFO "PCI: Using configuration type 1\n");
- request_region(PCI_REG(SH4_PCIPAR), 8, "PCI conf1");
+ pci_write_reg(chan, P1SEG, SH4_PCIPAR);
- return 0;
- }
-
- pci_write_reg(tmp, SH4_PCIPAR);
+ if (pci_read_reg(chan, SH4_PCIPAR) == P1SEG) {
+ pci_write_reg(chan, tmp, SH4_PCIPAR);
+ printk(KERN_INFO "PCI: Using configuration type 1\n");
+ request_region(chan->reg_base + SH4_PCIPAR, 8,
+ "PCI conf1");
+ return 0;
}
- pr_debug("PCI: pci_check_direct failed\n");
- return -EINVAL;
-}
+ pci_write_reg(chan, tmp, SH4_PCIPAR);
-/* Handle generic fixups */
-static void __init pci_fixup_ide_bases(struct pci_dev *d)
-{
- int i;
+ printk(KERN_ERR "PCI: %s failed\n", __func__);
- /*
- * PCI IDE controllers use non-standard I/O port decoding, respect it.
- */
- if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
- return;
- pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d));
- for(i = 0; i < 4; i++) {
- struct resource *r = &d->resource[i];
-
- if ((r->start & ~0x80) == 0x374) {
- r->start |= 2;
- r->end = r->start;
- }
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
-
-char * __devinit pcibios_setup(char *str)
-{
- if (!strcmp(str, "off")) {
- pci_probe = 0;
- return NULL;
- }
-
- return str;
+ return -EINVAL;
}
-int __attribute__((weak)) pci_fixup_pcic(void)
+int __attribute__((weak)) pci_fixup_pcic(struct pci_channel *chan)
{
/* Nothing to do. */
return 0;
diff --git a/arch/sh/drivers/pci/ops-sh5.c b/arch/sh/drivers/pci/ops-sh5.c
index 729e38a6fe07..4ce95a001b80 100644
--- a/arch/sh/drivers/pci/ops-sh5.c
+++ b/arch/sh/drivers/pci/ops-sh5.c
@@ -22,31 +22,6 @@
#include <asm/io.h>
#include "pci-sh5.h"
-static void __init pci_fixup_ide_bases(struct pci_dev *d)
-{
- int i;
-
- /*
- * PCI IDE controllers use non-standard I/O port decoding, respect it.
- */
- if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
- return;
- printk("PCI: IDE base address fixup for %s\n", pci_name(d));
- for(i=0; i<4; i++) {
- struct resource *r = &d->resource[i];
- if ((r->start & ~0x80) == 0x374) {
- r->start |= 2;
- r->end = r->start;
- }
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
-
-char * __devinit pcibios_setup(char *str)
-{
- return str;
-}
-
static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *val)
{
diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c
deleted file mode 100644
index fb0869f0bef8..000000000000
--- a/arch/sh/drivers/pci/ops-sh7785lcr.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Author: Ian DaSilva (idasilva@mvista.com)
- *
- * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * PCI initialization for the Renesas R0P7785LC0011RL board
- * Based on arch/sh/drivers/pci/ops-r7780rp.c
- *
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include "pci-sh4.h"
-
-static char irq_tab[] __initdata = {
- 65, 66, 67, 68,
-};
-
-int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
-{
- return irq_tab[slot];
-}
-
-static struct resource sh7785_io_resource = {
- .name = "SH7785_IO",
- .start = SH7780_PCI_IO_BASE,
- .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource sh7785_mem_resource = {
- .name = "SH7785_mem",
- .start = SH7780_PCI_MEMORY_BASE,
- .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
-};
-
-struct pci_channel board_pci_channels[] = {
- { &sh4_pci_ops, &sh7785_io_resource, &sh7785_mem_resource, 0, 0xff },
- { NULL, NULL, NULL, 0, 0 },
-};
-EXPORT_SYMBOL(board_pci_channels);
-
-static struct sh4_pci_address_map sh7785_pci_map = {
- .window0 = {
-#if defined(CONFIG_32BIT)
- .base = SH7780_32BIT_DDR_BASE_ADDR,
- .size = 0x40000000,
-#else
- .base = SH7780_CS0_BASE_ADDR,
- .size = 0x20000000,
-#endif
- },
-
- .flags = SH4_PCIC_NO_RESET,
-};
-
-int __init pcibios_init_platform(void)
-{
- return sh7780_pcic_init(&sh7785_pci_map);
-}
diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c
deleted file mode 100644
index 53dd893d4e54..000000000000
--- a/arch/sh/drivers/pci/ops-snapgear.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * arch/sh/drivers/pci/ops-snapgear.c
- *
- * Author: David McCullough <davidm@snapgear.com>
- *
- * Ported to new API by Paul Mundt <lethal@linux-sh.org>
- *
- * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * PCI initialization for the SnapGear boards
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include "pci-sh4.h"
-
-#define SNAPGEAR_PCI_IO 0x4000
-#define SNAPGEAR_PCI_MEM 0xfd000000
-
-/* PCI: default LOCAL memory window sizes (seen from PCI bus) */
-#define SNAPGEAR_LSR0_SIZE (64*(1<<20)) //64MB
-#define SNAPGEAR_LSR1_SIZE (64*(1<<20)) //64MB
-
-static struct resource sh7751_io_resource = {
- .name = "SH7751 IO",
- .start = SNAPGEAR_PCI_IO,
- .end = SNAPGEAR_PCI_IO + (64*1024) - 1, /* 64KiB I/O */
- .flags = IORESOURCE_IO,
-};
-
-static struct resource sh7751_mem_resource = {
- .name = "SH7751 mem",
- .start = SNAPGEAR_PCI_MEM,
- .end = SNAPGEAR_PCI_MEM + (64*1024*1024) - 1, /* 64MiB mem */
- .flags = IORESOURCE_MEM,
-};
-
-struct pci_channel board_pci_channels[] = {
- { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
- { 0, }
-};
-
-static struct sh4_pci_address_map sh7751_pci_map = {
- .window0 = {
- .base = SH7751_CS2_BASE_ADDR,
- .size = SNAPGEAR_LSR0_SIZE,
- },
-
- .window1 = {
- .base = SH7751_CS2_BASE_ADDR,
- .size = SNAPGEAR_LSR1_SIZE,
- },
-
- .flags = SH4_PCIC_NO_RESET,
-};
-
-/*
- * Initialize the SnapGear PCI interface
- * Setup hardware to be Central Funtion
- * Copy the BSR regs to the PCI interface
- * Setup PCI windows into local RAM
- */
-int __init pcibios_init_platform(void)
-{
- return sh7751_pcic_init(&sh7751_pci_map);
-}
-
-int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
-{
- int irq = -1;
-
- switch (slot) {
- case 8: /* the PCI bridge */ break;
- case 11: irq = 8; break; /* USB */
- case 12: irq = 11; break; /* PCMCIA */
- case 13: irq = 5; break; /* eth0 */
- case 14: irq = 8; break; /* eth1 */
- case 15: irq = 11; break; /* safenet (unused) */
- }
-
- printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n",
- slot, pin - 1 + 'A', irq);
-
- return irq;
-}
-
-void __init pcibios_fixup(void)
-{
- /* Nothing to fixup .. */
-}
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c
deleted file mode 100644
index cf48b12ee58c..000000000000
--- a/arch/sh/drivers/pci/pci-auto.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * PCI autoconfiguration library
- *
- * Author: Matt Porter <mporter@mvista.com>
- *
- * Copyright 2000, 2001 MontaVista Software Inc.
- * Copyright 2001 Bradley D. LaRonde <brad@ltc.com>
- * Copyright 2003 Paul Mundt <lethal@linux-sh.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.
- */
-
-/*
- * Modified for MIPS by Jun Sun, jsun@mvista.com
- *
- * . Simplify the interface between pci_auto and the rest: a single function.
- * . Assign resources from low address to upper address.
- * . change most int to u32.
- *
- * Further modified to include it as mips generic code, ppopov@mvista.com.
- *
- * 2001-10-26 Bradley D. LaRonde <brad@ltc.com>
- * - Add a top_bus argument to the "early config" functions so that
- * they can set a fake parent bus pointer to convince the underlying
- * pci ops to use type 1 configuration for sub busses.
- * - Set bridge base and limit registers correctly.
- * - Align io and memory base properly before and after bridge setup.
- * - Don't fall through to pci_setup_bars for bridge.
- * - Reformat the debug output to look more like lspci's output.
- *
- * Cloned for SuperH by M. R. Brown, mrbrown@0xd6.org
- *
- * 2003-08-05 Paul Mundt <lethal@linux-sh.org>
- * - Don't update the BAR values on systems that already have valid addresses
- * and don't want these updated for whatever reason, by way of a new config
- * option check. However, we still read in the old BAR values so that they
- * can still be reported through the debug output.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-
-#define DEBUG
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/*
- * These functions are used early on before PCI scanning is done
- * and all of the pci_dev and pci_bus structures have been created.
- */
-static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
- int top_bus, int busnr, int devfn)
-{
- static struct pci_dev dev;
- static struct pci_bus bus;
-
- dev.bus = &bus;
- dev.sysdata = hose;
- dev.devfn = devfn;
- bus.number = busnr;
- bus.ops = hose->pci_ops;
-
- if(busnr != top_bus)
- /* Fake a parent bus structure. */
- bus.parent = &bus;
- else
- bus.parent = NULL;
-
- return &dev;
-}
-
-#define EARLY_PCI_OP(rw, size, type) \
-static int early_##rw##_config_##size(struct pci_channel *hose, \
- int top_bus, int bus, int devfn, int offset, type value) \
-{ \
- return pci_##rw##_config_##size( \
- fake_pci_dev(hose, top_bus, bus, devfn), \
- offset, value); \
-}
-
-EARLY_PCI_OP(read, byte, u8 *)
-EARLY_PCI_OP(read, word, u16 *)
-EARLY_PCI_OP(read, dword, u32 *)
-EARLY_PCI_OP(write, byte, u8)
-EARLY_PCI_OP(write, word, u16)
-EARLY_PCI_OP(write, dword, u32)
-
-static struct resource *io_resource_inuse;
-static struct resource *mem_resource_inuse;
-
-static u32 pciauto_lower_iospc;
-static u32 pciauto_upper_iospc;
-
-static u32 pciauto_lower_memspc;
-static u32 pciauto_upper_memspc;
-
-static void __init
-pciauto_setup_bars(struct pci_channel *hose,
- int top_bus,
- int current_bus,
- int pci_devfn,
- int bar_limit)
-{
- u32 bar_response, bar_size, bar_value;
- u32 bar, addr_mask, bar_nr = 0;
- u32 * upper_limit;
- u32 * lower_limit;
- int found_mem64 = 0;
-
- for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) {
- u32 bar_addr;
-
- /* Read the old BAR value */
- early_read_config_dword(hose, top_bus,
- current_bus,
- pci_devfn,
- bar,
- &bar_addr);
-
- /* Tickle the BAR and get the response */
- early_write_config_dword(hose, top_bus,
- current_bus,
- pci_devfn,
- bar,
- 0xffffffff);
-
- early_read_config_dword(hose, top_bus,
- current_bus,
- pci_devfn,
- bar,
- &bar_response);
-
- /*
- * Write the old BAR value back out, only update the BAR
- * if we implicitly want resources to be updated, which
- * is done by the generic code further down. -- PFM.
- */
- early_write_config_dword(hose, top_bus,
- current_bus,
- pci_devfn,
- bar,
- bar_addr);
-
- /* If BAR is not implemented go to the next BAR */
- if (!bar_response)
- continue;
-
- /*
- * Workaround for a BAR that doesn't use its upper word,
- * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457).
- * bdl <brad@ltc.com>
- */
- if (!(bar_response & 0xffff0000))
- bar_response |= 0xffff0000;
-
-retry:
- /* Check the BAR type and set our address mask */
- if (bar_response & PCI_BASE_ADDRESS_SPACE) {
- addr_mask = PCI_BASE_ADDRESS_IO_MASK;
- upper_limit = &pciauto_upper_iospc;
- lower_limit = &pciauto_lower_iospc;
- DBG(" I/O");
- } else {
- if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
- PCI_BASE_ADDRESS_MEM_TYPE_64)
- found_mem64 = 1;
-
- addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
- upper_limit = &pciauto_upper_memspc;
- lower_limit = &pciauto_lower_memspc;
- DBG(" Mem");
- }
-
-
- /* Calculate requested size */
- bar_size = ~(bar_response & addr_mask) + 1;
-
- /* Allocate a base address */
- bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size;
-
- if ((bar_value + bar_size) > *upper_limit) {
- if (bar_response & PCI_BASE_ADDRESS_SPACE) {
- if (io_resource_inuse->child) {
- io_resource_inuse =
- io_resource_inuse->child;
- pciauto_lower_iospc =
- io_resource_inuse->start;
- pciauto_upper_iospc =
- io_resource_inuse->end + 1;
- goto retry;
- }
-
- } else {
- if (mem_resource_inuse->child) {
- mem_resource_inuse =
- mem_resource_inuse->child;
- pciauto_lower_memspc =
- mem_resource_inuse->start;
- pciauto_upper_memspc =
- mem_resource_inuse->end + 1;
- goto retry;
- }
- }
- DBG(" unavailable -- skipping, value %x size %x\n",
- bar_value, bar_size);
- continue;
- }
-
- if (bar_value < *lower_limit || (bar_value + bar_size) >= *upper_limit) {
- DBG(" unavailable -- skipping, value %x size %x\n",
- bar_value, bar_size);
- continue;
- }
-
-#ifdef CONFIG_PCI_AUTO_UPDATE_RESOURCES
- /* Write it out and update our limit */
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- bar, bar_value);
-#endif
-
- *lower_limit = bar_value + bar_size;
-
- /*
- * If we are a 64-bit decoder then increment to the
- * upper 32 bits of the bar and force it to locate
- * in the lower 4GB of memory.
- */
- if (found_mem64) {
- bar += 4;
- early_write_config_dword(hose, top_bus,
- current_bus,
- pci_devfn,
- bar,
- 0x00000000);
- }
-
- DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size);
-
- bar_nr++;
- }
-
-}
-
-static void __init
-pciauto_prescan_setup_bridge(struct pci_channel *hose,
- int top_bus,
- int current_bus,
- int pci_devfn,
- int sub_bus)
-{
- /* Configure bus number registers */
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_PRIMARY_BUS, current_bus);
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_SECONDARY_BUS, sub_bus + 1);
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_SUBORDINATE_BUS, 0xff);
-
- /* Align memory and I/O to 1MB and 4KB boundaries. */
- pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
- & ~(0x100000 - 1);
- pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
- & ~(0x1000 - 1);
-
- /* Set base (lower limit) of address range behind bridge. */
- early_write_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_MEMORY_BASE, pciauto_lower_memspc >> 16);
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8);
- early_write_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16);
-
- /* We don't support prefetchable memory for now, so disable */
- early_write_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_PREF_MEMORY_BASE, 0);
- early_write_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_PREF_MEMORY_LIMIT, 0);
-}
-
-static void __init
-pciauto_postscan_setup_bridge(struct pci_channel *hose,
- int top_bus,
- int current_bus,
- int pci_devfn,
- int sub_bus)
-{
- u32 temp;
-
- /*
- * [jsun] we always bump up baselines a little, so that if there
- * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
- * spaces.
- */
- pciauto_lower_memspc += 1;
- pciauto_lower_iospc += 1;
-
- /* Configure bus number registers */
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_SUBORDINATE_BUS, sub_bus);
-
- /* Set upper limit of address range behind bridge. */
- early_write_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16);
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8);
- early_write_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16);
-
- /* Align memory and I/O to 1MB and 4KB boundaries. */
- pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
- & ~(0x100000 - 1);
- pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
- & ~(0x1000 - 1);
-
- /* Enable memory and I/O accesses, enable bus master */
- early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_COMMAND, &temp);
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY
- | PCI_COMMAND_MASTER);
-}
-
-static void __init
-pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose,
- int top_bus,
- int current_bus,
- int pci_devfn,
- int sub_bus)
-{
- /* Configure bus number registers */
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_PRIMARY_BUS, current_bus);
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_SECONDARY_BUS, sub_bus + 1);
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_SUBORDINATE_BUS, 0xff);
-
- /* Align memory and I/O to 4KB and 4 byte boundaries. */
- pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
- & ~(0x1000 - 1);
- pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
- & ~(0x4 - 1);
-
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc);
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_CB_IO_BASE_0, pciauto_lower_iospc);
-}
-
-static void __init
-pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
- int top_bus,
- int current_bus,
- int pci_devfn,
- int sub_bus)
-{
- u32 temp;
-
- /*
- * [jsun] we always bump up baselines a little, so that if there
- * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
- * spaces.
- */
- pciauto_lower_memspc += 1;
- pciauto_lower_iospc += 1;
-
- /*
- * Configure subordinate bus number. The PCI subsystem
- * bus scan will renumber buses (reserving three additional
- * for this PCI<->CardBus bridge for the case where a CardBus
- * adapter contains a P2P or CB2CB bridge.
- */
-
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_SUBORDINATE_BUS, sub_bus);
-
- /*
- * Reserve an additional 4MB for mem space and 16KB for
- * I/O space. This should cover any additional space
- * requirement of unusual CardBus devices with
- * additional bridges that can consume more address space.
- *
- * Although pcmcia-cs currently will reprogram bridge
- * windows, the goal is to add an option to leave them
- * alone and use the bridge window ranges as the regions
- * that are searched for free resources upon hot-insertion
- * of a device. This will allow a PCI<->CardBus bridge
- * configured by this routine to happily live behind a
- * P2P bridge in a system.
- */
- /* Align memory and I/O to 4KB and 4 byte boundaries. */
- pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
- & ~(0x1000 - 1);
- pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
- & ~(0x4 - 1);
- /* Set up memory and I/O filter limits, assume 32-bit I/O space */
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1);
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1);
-
- /* Enable memory and I/O accesses, enable bus master */
- early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_COMMAND, &temp);
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
- PCI_COMMAND_MASTER);
-}
-
-#define PCIAUTO_IDE_MODE_MASK 0x05
-
-static int __init
-pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
-{
- int sub_bus;
- u32 pci_devfn, pci_class, cmdstat, found_multi=0;
- unsigned short vid, did;
- unsigned char header_type;
- int devfn_start = 0;
- int devfn_stop = 0xff;
-
- sub_bus = current_bus;
-
- if (hose->first_devfn)
- devfn_start = hose->first_devfn;
- if (hose->last_devfn)
- devfn_stop = hose->last_devfn;
-
- for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
-
- if (PCI_FUNC(pci_devfn) && !found_multi)
- continue;
-
- early_read_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_VENDOR_ID, &vid);
-
- if (vid == 0xffff) continue;
-
- early_read_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_HEADER_TYPE, &header_type);
-
- if (!PCI_FUNC(pci_devfn))
- found_multi = header_type & 0x80;
-
- early_read_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_DEVICE_ID, &did);
-
- early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_CLASS_REVISION, &pci_class);
-
- DBG("%.2x:%.2x.%x Class %.4x: %.4x:%.4x",
- current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn),
- pci_class >> 16, vid, did);
- if (pci_class & 0xff)
- DBG(" (rev %.2x)", pci_class & 0xff);
- DBG("\n");
-
- if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
- DBG(" Bridge: primary=%.2x, secondary=%.2x\n",
- current_bus, sub_bus + 1);
- pciauto_prescan_setup_bridge(hose, top_bus, current_bus,
- pci_devfn, sub_bus);
- DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
- sub_bus + 1,
- pciauto_lower_iospc, pciauto_lower_memspc);
- sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
- DBG("Back to bus %.2x\n", current_bus);
- pciauto_postscan_setup_bridge(hose, top_bus, current_bus,
- pci_devfn, sub_bus);
- continue;
- } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) {
- DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n",
- current_bus, sub_bus + 1);
- DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
- /* Place CardBus Socket/ExCA registers */
- pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0);
-
- pciauto_prescan_setup_cardbus_bridge(hose, top_bus,
- current_bus, pci_devfn, sub_bus);
-
- DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
- sub_bus + 1,
- pciauto_lower_iospc, pciauto_lower_memspc);
- sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
- DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus);
- pciauto_postscan_setup_cardbus_bridge(hose, top_bus,
- current_bus, pci_devfn, sub_bus);
- continue;
- } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
-
- unsigned char prg_iface;
-
- early_read_config_byte(hose, top_bus, current_bus,
- pci_devfn, PCI_CLASS_PROG, &prg_iface);
- if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
- DBG("Skipping legacy mode IDE controller\n");
- continue;
- }
- }
-
- /*
- * Found a peripheral, enable some standard
- * settings
- */
- early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_COMMAND, &cmdstat);
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_COMMAND, cmdstat | PCI_COMMAND_IO |
- PCI_COMMAND_MEMORY |
- PCI_COMMAND_MASTER);
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_LATENCY_TIMER, 0x80);
-
- /* Allocate PCI I/O and/or memory space */
- pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5);
- }
- return sub_bus;
-}
-
-int __init
-pciauto_assign_resources(int busno, struct pci_channel *hose)
-{
- /* setup resource limits */
- io_resource_inuse = hose->io_resource;
- mem_resource_inuse = hose->mem_resource;
-
- pciauto_lower_iospc = io_resource_inuse->start;
- pciauto_upper_iospc = io_resource_inuse->end + 1;
- pciauto_lower_memspc = mem_resource_inuse->start;
- pciauto_upper_memspc = mem_resource_inuse->end + 1;
- DBG("Autoconfig PCI channel 0x%p\n", hose);
- DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n",
- busno, pciauto_lower_iospc, pciauto_upper_iospc,
- pciauto_lower_memspc, pciauto_upper_memspc);
-
- return pciauto_bus_scan(hose, busno, busno);
-}
diff --git a/arch/sh/drivers/pci/pci-dreamcast.c b/arch/sh/drivers/pci/pci-dreamcast.c
new file mode 100644
index 000000000000..210f9d4af141
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-dreamcast.c
@@ -0,0 +1,102 @@
+/*
+ * PCI support for the Sega Dreamcast
+ *
+ * Copyright (C) 2001, 2002 M. R. Brown
+ * Copyright (C) 2002, 2003 Paul Mundt
+ *
+ * This file originally bore the message (with enclosed-$):
+ * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
+ * Dreamcast PCI: Supports SEGA Broadband Adaptor only.
+ *
+ * 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/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <mach/pci.h>
+
+static struct resource gapspci_io_resource = {
+ .name = "GAPSPCI IO",
+ .start = GAPSPCI_BBA_CONFIG,
+ .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource gapspci_mem_resource = {
+ .name = "GAPSPCI mem",
+ .start = GAPSPCI_DMA_BASE,
+ .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct pci_channel dreamcast_pci_controller = {
+ .pci_ops = &gapspci_pci_ops,
+ .io_resource = &gapspci_io_resource,
+ .io_offset = 0x00000000,
+ .mem_resource = &gapspci_mem_resource,
+ .mem_offset = 0x00000000,
+};
+
+/*
+ * gapspci init
+ */
+
+static int __init gapspci_init(void)
+{
+ char idbuf[16];
+ int i;
+
+ /*
+ * FIXME: All of this wants documenting to some degree,
+ * even some basic register definitions would be nice.
+ *
+ * I haven't seen anything this ugly since.. maple.
+ */
+
+ for (i=0; i<16; i++)
+ idbuf[i] = inb(GAPSPCI_REGS+i);
+
+ if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
+ return -ENODEV;
+
+ outl(0x5a14a501, GAPSPCI_REGS+0x18);
+
+ for (i=0; i<1000000; i++)
+ cpu_relax();
+
+ if (inl(GAPSPCI_REGS+0x18) != 1)
+ return -EINVAL;
+
+ outl(0x01000000, GAPSPCI_REGS+0x20);
+ outl(0x01000000, GAPSPCI_REGS+0x24);
+
+ outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
+ outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
+
+ outl(1, GAPSPCI_REGS+0x14);
+ outl(1, GAPSPCI_REGS+0x34);
+
+ /* Setting Broadband Adapter */
+ outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
+ outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
+ outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
+ outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
+ outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
+ outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
+ outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
+
+ register_pci_controller(&dreamcast_pci_controller);
+
+ return 0;
+}
+arch_initcall(gapspci_init);
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h
index a83dcf70c13b..3d5296cde622 100644
--- a/arch/sh/drivers/pci/pci-sh4.h
+++ b/arch/sh/drivers/pci/pci-sh4.h
@@ -149,13 +149,10 @@
#define SH4_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */
#define SH4_PCIPDR 0x220 /* Port IO Data Register */
-/* Flags */
-#define SH4_PCIC_NO_RESET 0x0001
-
/* arch/sh/kernel/drivers/pci/ops-sh4.c */
extern struct pci_ops sh4_pci_ops;
-int sh4_pci_check_direct(void);
-int pci_fixup_pcic(void);
+int sh4_pci_check_direct(struct pci_channel *chan);
+int pci_fixup_pcic(struct pci_channel *chan);
struct sh4_pci_address_space {
unsigned long base;
@@ -165,16 +162,18 @@ struct sh4_pci_address_space {
struct sh4_pci_address_map {
struct sh4_pci_address_space window0;
struct sh4_pci_address_space window1;
- unsigned long flags;
};
-static inline void pci_write_reg(unsigned long val, unsigned long reg)
+static inline void pci_write_reg(struct pci_channel *chan,
+ unsigned long val, unsigned long reg)
{
- ctrl_outl(val, PCI_REG(reg));
+ ctrl_outl(val, chan->reg_base + reg);
}
-static inline unsigned long pci_read_reg(unsigned long reg)
+static inline unsigned long pci_read_reg(struct pci_channel *chan,
+ unsigned long reg)
{
- return ctrl_inl(PCI_REG(reg));
+ return ctrl_inl(chan->reg_base + reg);
}
+
#endif /* __PCI_SH4_H */
diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c
index 7a97438762c8..873ed2b44055 100644
--- a/arch/sh/drivers/pci/pci-sh5.c
+++ b/arch/sh/drivers/pci/pci-sh5.c
@@ -89,8 +89,21 @@ static irqreturn_t pcish5_serr_irq(int irq, void *dev_id)
return IRQ_NONE;
}
-int __init sh5pci_init(unsigned long memStart, unsigned long memSize)
+static struct resource sh5_io_resource = { /* place holder */ };
+static struct resource sh5_mem_resource = { /* place holder */ };
+
+static struct pci_channel sh5pci_controller = {
+ .pci_ops = &sh5_pci_ops,
+ .mem_resource = &sh5_mem_resource,
+ .mem_offset = 0x00000000,
+ .io_resource = &sh5_io_resource,
+ .io_offset = 0x00000000,
+};
+
+static int __init sh5pci_init(void)
{
+ unsigned long memStart = __pa(memory_start);
+ unsigned long memSize = __pa(memory_end) - memStart;
u32 lsr0;
u32 uval;
@@ -106,12 +119,12 @@ int __init sh5pci_init(unsigned long memStart, unsigned long memSize)
return -EINVAL;
}
- pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
+ pcicr_virt = (unsigned long)ioremap_nocache(SH5PCI_ICR_BASE, 1024);
if (!pcicr_virt) {
panic("Unable to remap PCICR\n");
}
- PCI_IO_AREA = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
+ PCI_IO_AREA = (unsigned long)ioremap_nocache(SH5PCI_IO_BASE, 0x10000);
if (!PCI_IO_AREA) {
panic("Unable to remap PCIIO\n");
}
@@ -197,32 +210,14 @@ int __init sh5pci_init(unsigned long memStart, unsigned long memSize)
SH5PCI_WRITE(AINTM, ~0);
SH5PCI_WRITE(PINTM, ~0);
- return 0;
-}
+ sh5_io_resource.start = PCI_IO_AREA;
+ sh5_io_resource.end = PCI_IO_AREA + 0x10000;
-void __devinit pcibios_fixup_bus(struct pci_bus *bus)
-{
- struct pci_dev *dev = bus->self;
- int i;
-
- if (dev) {
- for (i= 0; i < 3; i++) {
- bus->resource[i] =
- &dev->resource[PCI_BRIDGE_RESOURCES+i];
- bus->resource[i]->name = bus->name;
- }
- bus->resource[0]->flags |= IORESOURCE_IO;
- bus->resource[1]->flags |= IORESOURCE_MEM;
-
- /* For now, propagate host limits to the bus;
- * we'll adjust them later. */
- bus->resource[0]->end = 64*1024 - 1 ;
- bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
- bus->resource[0]->start = PCIBIOS_MIN_IO;
- bus->resource[1]->start = PCIBIOS_MIN_MEM;
-
- /* Turn off downstream PF memory address range by default */
- bus->resource[2]->start = 1024*1024;
- bus->resource[2]->end = bus->resource[2]->start - 1;
- }
+ sh5_mem_resource.start = memStart;
+ sh5_mem_resource.end = memStart + memSize;
+
+ register_pci_controller(&sh5pci_controller);
+
+ return 0;
}
+arch_initcall(sh5pci_init);
diff --git a/arch/sh/drivers/pci/pci-sh5.h b/arch/sh/drivers/pci/pci-sh5.h
index 7cff3fc04d30..f277628221f3 100644
--- a/arch/sh/drivers/pci/pci-sh5.h
+++ b/arch/sh/drivers/pci/pci-sh5.h
@@ -107,7 +107,4 @@ extern unsigned long pcicr_virt;
extern struct pci_ops sh5_pci_ops;
-/* arch/sh/drivers/pci/pci-sh5.c */
-int sh5pci_init(unsigned long memStart, unsigned long memSize);
-
#endif /* __PCI_SH5_H */
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index 3065eb184f01..c4fa0bb13976 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -1,88 +1,99 @@
/*
- * Low-Level PCI Support for the SH7751
+ * Low-Level PCI Support for the SH7751
*
- * Dustin McIntire (dustin@sensoria.com)
- * Derived from arch/i386/kernel/pci-*.c which bore the message:
- * (c) 1999--2000 Martin Mares <mj@ucw.cz>
+ * Copyright (C) 2003 - 2009 Paul Mundt
+ * Copyright (C) 2001 Dustin McIntire
*
- * Ported to the new API by Paul Mundt <lethal@linux-sh.org>
- * With cleanup by Paul van Gool <pvangool@mimotech.com>
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
+ * With cleanup by Paul van Gool <pvangool@mimotech.com>, 2003.
*
+ * 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.
*/
-#undef DEBUG
-
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/types.h>
#include <linux/errno.h>
-#include <linux/delay.h>
+#include <linux/io.h>
#include "pci-sh4.h"
#include <asm/addrspace.h>
-#include <asm/io.h>
-/*
- * Initialization. Try all known PCI access methods. Note that we support
- * using both PCI BIOS and direct access: in such cases, we use I/O ports
- * to access config space.
- *
- * Note that the platform specific initialization (BSC registers, and memory
- * space mapping) will be called via the platform defined function
- * pcibios_init_platform().
- */
-static int __init sh7751_pci_init(void)
+static int __init __area_sdram_check(struct pci_channel *chan,
+ unsigned int area)
{
- unsigned int id;
- int ret;
-
- pr_debug("PCI: Starting intialization.\n");
+ unsigned long word;
- /* check for SH7751/SH7751R hardware */
- id = pci_read_reg(SH7751_PCICONF0);
- if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
- id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) {
- pr_debug("PCI: This is not an SH7751(R) (%x)\n", id);
- return -ENODEV;
- }
-
- if ((ret = sh4_pci_check_direct()) != 0)
- return ret;
-
- return pcibios_init_platform();
-}
-subsys_initcall(sh7751_pci_init);
-
-static int __init __area_sdram_check(unsigned int area)
-{
- u32 word;
-
- word = ctrl_inl(SH7751_BCR1);
+ word = __raw_readl(SH7751_BCR1);
/* check BCR for SDRAM in area */
if (((word >> area) & 1) == 0) {
- printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n",
+ printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%lx\n",
area, word);
return 0;
}
- pci_write_reg(word, SH4_PCIBCR1);
+ pci_write_reg(chan, word, SH4_PCIBCR1);
- word = (u16)ctrl_inw(SH7751_BCR2);
+ word = __raw_readw(SH7751_BCR2);
/* check BCR2 for 32bit SDRAM interface*/
if (((word >> (area << 1)) & 0x3) != 0x3) {
- printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n",
+ printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%lx\n",
area, word);
return 0;
}
- pci_write_reg(word, SH4_PCIBCR2);
+ pci_write_reg(chan, word, SH4_PCIBCR2);
return 1;
}
-int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
+static struct resource sh7751_io_resource = {
+ .name = "SH7751_IO",
+ .start = SH7751_PCI_IO_BASE,
+ .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO
+};
+
+static struct resource sh7751_mem_resource = {
+ .name = "SH7785_mem",
+ .start = SH7751_PCI_MEMORY_BASE,
+ .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM
+};
+
+static struct pci_channel sh7751_pci_controller = {
+ .pci_ops = &sh4_pci_ops,
+ .mem_resource = &sh7751_mem_resource,
+ .mem_offset = 0x00000000,
+ .io_resource = &sh7751_io_resource,
+ .io_offset = 0x00000000,
+};
+
+static struct sh4_pci_address_map sh7751_pci_map = {
+ .window0 = {
+ .base = SH7751_CS3_BASE_ADDR,
+ .size = 0x04000000,
+ },
+};
+
+static int __init sh7751_pci_init(void)
{
- u32 reg;
- u32 word;
+ struct pci_channel *chan = &sh7751_pci_controller;
+ unsigned int id;
+ u32 word, reg;
+ int ret;
+
+ printk(KERN_NOTICE "PCI: Starting intialization.\n");
+
+ chan->reg_base = 0xfe200000;
+
+ /* check for SH7751/SH7751R hardware */
+ id = pci_read_reg(chan, SH7751_PCICONF0);
+ if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
+ id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) {
+ pr_debug("PCI: This is not an SH7751(R) (%x)\n", id);
+ return -ENODEV;
+ }
+
+ if ((ret = sh4_pci_check_direct(chan)) != 0)
+ return ret;
/* Set the BCR's to enable PCI access */
reg = ctrl_inl(SH7751_BCR1);
@@ -90,25 +101,10 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
ctrl_outl(reg, SH7751_BCR1);
/* Turn the clocks back on (not done in reset)*/
- pci_write_reg(0, SH4_PCICLKR);
+ pci_write_reg(chan, 0, SH4_PCICLKR);
/* Clear Powerdown IRQ's (not done in reset) */
word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0;
- pci_write_reg(word, SH4_PCIPINT);
-
- /*
- * This code is unused for some boards as it is done in the
- * bootloader and doing it here means the MAC addresses loaded
- * by the bootloader get lost.
- */
- if (!(map->flags & SH4_PCIC_NO_RESET)) {
- /* toggle PCI reset pin */
- word = SH4_PCICR_PREFIX | SH4_PCICR_PRST;
- pci_write_reg(word, SH4_PCICR);
- /* Wait for a long time... not 1 sec. but long enough */
- mdelay(100);
- word = SH4_PCICR_PREFIX;
- pci_write_reg(word, SH4_PCICR);
- }
+ pci_write_reg(chan, word, SH4_PCIPINT);
/* set the command/status bits to:
* Wait Cycle Control + Parity Enable + Bus Master +
@@ -116,89 +112,77 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
*/
word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER |
SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES;
- pci_write_reg(word, SH7751_PCICONF1);
+ pci_write_reg(chan, word, SH7751_PCICONF1);
/* define this host as the host bridge */
word = PCI_BASE_CLASS_BRIDGE << 24;
- pci_write_reg(word, SH7751_PCICONF2);
+ pci_write_reg(chan, word, SH7751_PCICONF2);
/* Set IO and Mem windows to local address
* Make PCI and local address the same for easy 1 to 1 mapping
- * Window0 = map->window0.size @ non-cached area base = SDRAM
- * Window1 = map->window1.size @ cached area base = SDRAM
*/
- word = map->window0.size - 1;
- pci_write_reg(word, SH4_PCILSR0);
- word = map->window1.size - 1;
- pci_write_reg(word, SH4_PCILSR1);
+ word = sh7751_pci_map.window0.size - 1;
+ pci_write_reg(chan, word, SH4_PCILSR0);
/* Set the values on window 0 PCI config registers */
- word = P2SEGADDR(map->window0.base);
- pci_write_reg(word, SH4_PCILAR0);
- pci_write_reg(word, SH7751_PCICONF5);
- /* Set the values on window 1 PCI config registers */
- word = PHYSADDR(map->window1.base);
- pci_write_reg(word, SH4_PCILAR1);
- pci_write_reg(word, SH7751_PCICONF6);
+ word = P2SEGADDR(sh7751_pci_map.window0.base);
+ pci_write_reg(chan, word, SH4_PCILAR0);
+ pci_write_reg(chan, word, SH7751_PCICONF5);
/* Set the local 16MB PCI memory space window to
* the lowest PCI mapped address
*/
- word = PCIBIOS_MIN_MEM & SH4_PCIMBR_MASK;
+ word = chan->mem_resource->start & SH4_PCIMBR_MASK;
pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word);
- pci_write_reg(word , SH4_PCIMBR);
-
- /* Map IO space into PCI IO window
- * The IO window is 64K-PCIBIOS_MIN_IO in size
- * IO addresses will be translated to the
- * PCI IO window base address
- */
- pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n",
- PCIBIOS_MIN_IO, (64 << 10),
- SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO);
+ pci_write_reg(chan, word , SH4_PCIMBR);
/* Make sure the MSB's of IO window are set to access PCI space
* correctly */
- word = PCIBIOS_MIN_IO & SH4_PCIIOBR_MASK;
+ word = chan->io_resource->start & SH4_PCIIOBR_MASK;
pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word);
- pci_write_reg(word, SH4_PCIIOBR);
+ pci_write_reg(chan, word, SH4_PCIIOBR);
/* Set PCI WCRx, BCRx's, copy from BSC locations */
/* check BCR for SDRAM in specified area */
- switch (map->window0.base) {
- case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(0); break;
- case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(1); break;
- case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(2); break;
- case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(3); break;
- case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(4); break;
- case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break;
- case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break;
+ switch (sh7751_pci_map.window0.base) {
+ case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(chan, 0); break;
+ case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(chan, 1); break;
+ case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(chan, 2); break;
+ case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(chan, 3); break;
+ case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(chan, 4); break;
+ case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(chan, 5); break;
+ case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(chan, 6); break;
}
if (!word)
- return 0;
+ return -1;
/* configure the wait control registers */
word = ctrl_inl(SH7751_WCR1);
- pci_write_reg(word, SH4_PCIWCR1);
+ pci_write_reg(chan, word, SH4_PCIWCR1);
word = ctrl_inl(SH7751_WCR2);
- pci_write_reg(word, SH4_PCIWCR2);
+ pci_write_reg(chan, word, SH4_PCIWCR2);
word = ctrl_inl(SH7751_WCR3);
- pci_write_reg(word, SH4_PCIWCR3);
+ pci_write_reg(chan, word, SH4_PCIWCR3);
word = ctrl_inl(SH7751_MCR);
- pci_write_reg(word, SH4_PCIMCR);
+ pci_write_reg(chan, word, SH4_PCIMCR);
/* NOTE: I'm ignoring the PCI error IRQs for now..
* TODO: add support for the internal error interrupts and
* DMA interrupts...
*/
- pci_fixup_pcic();
+ pci_fixup_pcic(chan);
/* SH7751 init done, set central function init complete */
/* use round robin mode to stop a device starving/overruning */
word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM;
- pci_write_reg(word, SH4_PCICR);
+ pci_write_reg(chan, word, SH4_PCICR);
- return 1;
+ __set_io_port_base(SH7751_PCI_IO_BASE);
+
+ register_pci_controller(chan);
+
+ return 0;
}
+arch_initcall(sh7751_pci_init);
diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h
index 68e3cb5e6bec..4983a4d20355 100644
--- a/arch/sh/drivers/pci/pci-sh7751.h
+++ b/arch/sh/drivers/pci/pci-sh7751.h
@@ -26,7 +26,6 @@
#define SH7751_PCI_IO_SIZE 0x40000 /* Size of IO window */
#define SH7751_PCIREG_BASE 0xFE200000 /* PCI regs base address */
-#define PCI_REG(n) (SH7751_PCIREG_BASE+ n)
#define SH7751_PCICONF0 0x0 /* PCI Config Reg 0 */
#define SH7751_PCICONF0_DEVID 0xFFFF0000 /* Device ID */
@@ -58,7 +57,7 @@
#define SH7751_PCICONF2_SCC 0x00FF0000 /* Sub-Class Code */
#define SH7751_PCICONF2_RLPI 0x0000FF00 /* Programming Interface */
#define SH7751_PCICONF2_REV 0x000000FF /* Revision ID */
-#define SH7751_PCICONF3 0xC /* PCI Config Reg 3 */
+#define SH7751_PCICONF3 0xC /* PCI Config Reg 3 */
#define SH7751_PCICONF3_BIST7 0x80000000 /* Bist Supported */
#define SH7751_PCICONF3_BIST6 0x40000000 /* Bist Executing */
#define SH7751_PCICONF3_BIST3_0 0x0F000000 /* Bist Passed */
@@ -73,12 +72,12 @@
#define SH7751_PCICONF5_BASE 0xFFFFFFF0 /* Mem Space Base Addr */
#define SH7751_PCICONF5_LAP 0x00000008 /* Prefetch Enabled */
#define SH7751_PCICONF5_LAT 0x00000006 /* Local Memory type */
- #define SH7751_PCICONF5_ASI 0x00000001 /* Address Space Type */
+ #define SH7751_PCICONF5_ASI 0x00000001 /* Address Space Type */
#define SH7751_PCICONF6 0x18 /* PCI Config Reg 6 */
#define SH7751_PCICONF6_BASE 0xFFFFFFF0 /* Mem Space Base Addr */
#define SH7751_PCICONF6_LAP 0x00000008 /* Prefetch Enabled */
#define SH7751_PCICONF6_LAT 0x00000006 /* Local Memory type */
- #define SH7751_PCICONF6_ASI 0x00000001 /* Address Space Type */
+ #define SH7751_PCICONF6_ASI 0x00000001 /* Address Space Type */
/* PCICONF7 - PCICONF10 are undefined */
#define SH7751_PCICONF11 0x2C /* PCI Config Reg 11 */
#define SH7751_PCICONF11_SSID 0xFFFF0000 /* Subsystem ID */
@@ -127,9 +126,4 @@
#define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE)
#define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE)
-struct sh4_pci_address_map;
-
-/* arch/sh/drivers/pci/pci-sh7751.c */
-int sh7751_pcic_init(struct sh4_pci_address_map *map);
-
#endif /* _PCI_SH7751_H_ */
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index bae6a2cf047d..ae13ff925c61 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -1,19 +1,12 @@
/*
- * Low-Level PCI Support for the SH7780
+ * Low-Level PCI Support for the SH7780
*
- * Dustin McIntire (dustin@sensoria.com)
- * Derived from arch/i386/kernel/pci-*.c which bore the message:
- * (c) 1999--2000 Martin Mares <mj@ucw.cz>
- *
- * Ported to the new API by Paul Mundt <lethal@linux-sh.org>
- * With cleanup by Paul van Gool <pvangool@mimotech.com>
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
+ * Copyright (C) 2005 - 2009 Paul Mundt
*
+ * 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.
*/
-#undef DEBUG
-
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -22,135 +15,137 @@
#include <linux/delay.h>
#include "pci-sh4.h"
-#define INTC_BASE 0xffd00000
-#define INTC_ICR0 (INTC_BASE+0x0)
-#define INTC_ICR1 (INTC_BASE+0x1c)
-#define INTC_INTPRI (INTC_BASE+0x10)
-#define INTC_INTREQ (INTC_BASE+0x24)
-#define INTC_INTMSK0 (INTC_BASE+0x44)
-#define INTC_INTMSK1 (INTC_BASE+0x48)
-#define INTC_INTMSK2 (INTC_BASE+0x40080)
-#define INTC_INTMSKCLR0 (INTC_BASE+0x64)
-#define INTC_INTMSKCLR1 (INTC_BASE+0x68)
-#define INTC_INTMSKCLR2 (INTC_BASE+0x40084)
-#define INTC_INT2MSKR (INTC_BASE+0x40038)
-#define INTC_INT2MSKCR (INTC_BASE+0x4003c)
+extern u8 pci_cache_line_size;
+
+static struct resource sh7785_io_resource = {
+ .name = "SH7785_IO",
+ .start = SH7780_PCI_IO_BASE,
+ .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO
+};
+
+static struct resource sh7785_mem_resource = {
+ .name = "SH7785_mem",
+ .start = SH7780_PCI_MEMORY_BASE,
+ .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM
+};
+
+static struct pci_channel sh7780_pci_controller = {
+ .pci_ops = &sh4_pci_ops,
+ .mem_resource = &sh7785_mem_resource,
+ .mem_offset = 0x00000000,
+ .io_resource = &sh7785_io_resource,
+ .io_offset = 0x00000000,
+};
+
+static struct sh4_pci_address_map sh7780_pci_map = {
+ .window0 = {
+#if defined(CONFIG_32BIT)
+ .base = SH7780_32BIT_DDR_BASE_ADDR,
+ .size = 0x40000000,
+#else
+ .base = SH7780_CS0_BASE_ADDR,
+ .size = 0x20000000,
+#endif
+ },
+};
-/*
- * Initialization. Try all known PCI access methods. Note that we support
- * using both PCI BIOS and direct access: in such cases, we use I/O ports
- * to access config space.
- *
- * Note that the platform specific initialization (BSC registers, and memory
- * space mapping) will be called via the platform defined function
- * pcibios_init_platform().
- */
static int __init sh7780_pci_init(void)
{
+ struct pci_channel *chan = &sh7780_pci_controller;
unsigned int id;
- int ret, match = 0;
-
- pr_debug("PCI: Starting intialization.\n");
-
- ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */
-
- /* check for SH7780/SH7780R hardware */
- id = pci_read_reg(SH7780_PCIVID);
- if ((id & 0xffff) == SH7780_VENDOR_ID) {
- switch ((id >> 16) & 0xffff) {
- case SH7763_DEVICE_ID:
- case SH7780_DEVICE_ID:
- case SH7781_DEVICE_ID:
- case SH7785_DEVICE_ID:
- match = 1;
- break;
- }
- }
+ const char *type = NULL;
+ int ret;
+ u32 word;
- if (unlikely(!match)) {
- printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id);
+ printk(KERN_NOTICE "PCI: Starting intialization.\n");
+
+ chan->reg_base = 0xfe040000;
+
+ /* Enable CPU access to the PCIC registers. */
+ __raw_writel(PCIECR_ENBL, PCIECR);
+
+ id = __raw_readw(chan->reg_base + SH7780_PCIVID);
+ if (id != SH7780_VENDOR_ID) {
+ printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id);
return -ENODEV;
}
- /* Setup the INTC */
- if (mach_is_7780se()) {
- /* ICR0: IRL=use separately */
- ctrl_outl(0x00C00020, INTC_ICR0);
- /* ICR1: detect low level(for 2ndcut) */
- ctrl_outl(0xAAAA0000, INTC_ICR1);
- /* INTPRI: priority=3(all) */
- ctrl_outl(0x33333333, INTC_INTPRI);
+ id = __raw_readw(chan->reg_base + SH7780_PCIDID);
+ type = (id == SH7763_DEVICE_ID) ? "SH7763" :
+ (id == SH7780_DEVICE_ID) ? "SH7780" :
+ (id == SH7781_DEVICE_ID) ? "SH7781" :
+ (id == SH7785_DEVICE_ID) ? "SH7785" :
+ NULL;
+ if (unlikely(!type)) {
+ printk(KERN_ERR "PCI: Found an unsupported Renesas host "
+ "controller, device id 0x%04x.\n", id);
+ return -EINVAL;
}
- if ((ret = sh4_pci_check_direct()) != 0)
- return ret;
+ printk(KERN_NOTICE "PCI: Found a Renesas %s host "
+ "controller, revision %d.\n", type,
+ __raw_readb(chan->reg_base + SH7780_PCIRID));
- return pcibios_init_platform();
-}
-core_initcall(sh7780_pci_init);
-
-int __init sh7780_pcic_init(struct sh4_pci_address_map *map)
-{
- u32 word;
+ if ((ret = sh4_pci_check_direct(chan)) != 0)
+ return ret;
/*
- * This code is unused for some boards as it is done in the
- * bootloader and doing it here means the MAC addresses loaded
- * by the bootloader get lost.
- */
- if (!(map->flags & SH4_PCIC_NO_RESET)) {
- /* toggle PCI reset pin */
- word = SH4_PCICR_PREFIX | SH4_PCICR_PRST;
- pci_write_reg(word, SH4_PCICR);
- /* Wait for a long time... not 1 sec. but long enough */
- mdelay(100);
- word = SH4_PCICR_PREFIX;
- pci_write_reg(word, SH4_PCICR);
- }
-
- /* set the command/status bits to:
- * Wait Cycle Control + Parity Enable + Bus Master +
- * Mem space enable
+ * Set the class and sub-class codes.
*/
- pci_write_reg(0x00000046, SH7780_PCICMD);
+ __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8,
+ chan->reg_base + SH7780_PCIBCC);
+ __raw_writeb(PCI_CLASS_BRIDGE_HOST & 0xff,
+ chan->reg_base + SH7780_PCISUB);
- /* define this host as the host bridge */
- word = PCI_BASE_CLASS_BRIDGE << 24;
- pci_write_reg(word, SH7780_PCIRID);
+ pci_cache_line_size = pci_read_reg(chan, SH7780_PCICLS) / 4;
- /* Set IO and Mem windows to local address
+ /*
+ * Set IO and Mem windows to local address
* Make PCI and local address the same for easy 1 to 1 mapping
*/
- pci_write_reg(map->window0.size - 0xfffff, SH4_PCILSR0);
- pci_write_reg(map->window1.size - 0xfffff, SH4_PCILSR1);
+ pci_write_reg(chan, sh7780_pci_map.window0.size - 0xfffff, SH4_PCILSR0);
/* Set the values on window 0 PCI config registers */
- pci_write_reg(map->window0.base, SH4_PCILAR0);
- pci_write_reg(map->window0.base, SH7780_PCIMBAR0);
- /* Set the values on window 1 PCI config registers */
- pci_write_reg(map->window1.base, SH4_PCILAR1);
- pci_write_reg(map->window1.base, SH7780_PCIMBAR1);
-
- /* Map IO space into PCI IO window
- * The IO window is 64K-PCIBIOS_MIN_IO in size
- * IO addresses will be translated to the
- * PCI IO window base address
- */
- pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n",
- PCIBIOS_MIN_IO, (64 << 10),
- SH7780_PCI_IO_BASE + PCIBIOS_MIN_IO);
+ pci_write_reg(chan, sh7780_pci_map.window0.base, SH4_PCILAR0);
+ pci_write_reg(chan, sh7780_pci_map.window0.base, SH7780_PCIMBAR0);
- /* NOTE: I'm ignoring the PCI error IRQs for now..
- * TODO: add support for the internal error interrupts and
- * DMA interrupts...
- */
+ pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM);
+
+ /* Set up standard PCI config registers */
+ __raw_writew(0xFB00, chan->reg_base + SH7780_PCISTATUS);
+ __raw_writew(0x0047, chan->reg_base + SH7780_PCICMD);
+ __raw_writew(0x1912, chan->reg_base + SH7780_PCISVID);
+ __raw_writew(0x0001, chan->reg_base + SH7780_PCISID);
+
+ __raw_writeb(0x00, chan->reg_base + SH7780_PCIPIF);
/* Apply any last-minute PCIC fixups */
- pci_fixup_pcic();
+ pci_fixup_pcic(chan);
+
+ pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0);
+ pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0);
+
+#ifdef CONFIG_32BIT
+ pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2);
+ pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2);
+#endif
+
+ /* Set IOBR for windows containing area specified in pci.h */
+ pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1),
+ SH7780_PCIIOBR);
+ pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)),
+ SH7780_PCIIOBMR);
/* SH7780 init done, set central function init complete */
/* use round robin mode to stop a device starving/overruning */
word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO;
- pci_write_reg(word, SH4_PCICR);
+ pci_write_reg(chan, word, SH4_PCICR);
+
+ __set_io_port_base(SH7780_PCI_IO_BASE);
+
+ register_pci_controller(chan);
- return 1;
+ return 0;
}
+arch_initcall(sh7780_pci_init);
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index 93adc7119b79..4a52478c97cf 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -20,9 +20,8 @@
#define SH7785_DEVICE_ID 0x0007
/* SH7780 Control Registers */
-#define SH7780_PCI_VCR0 0xFE000000
-#define SH7780_PCI_VCR1 0xFE000004
-#define SH7780_PCI_VCR2 0xFE000008
+#define PCIECR 0xFE000008
+#define PCIECR_ENBL 0x01
/* SH7780 Specific Values */
#define SH7780_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */
@@ -35,7 +34,6 @@
#define SH7780_PCI_IO_SIZE 0x00400000 /* Size of IO window */
#define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */
-#define PCI_REG(n) (SH7780_PCIREG_BASE+n)
/* SH7780 PCI Config Registers */
#define SH7780_PCIVID 0x000 /* Vendor ID */
@@ -67,11 +65,6 @@
#define SH7780_PCIPMCSR_BSE 0x046
#define SH7780_PCICDD 0x047
-#define SH7780_PCICR 0x100 /* PCI Control Register */
-#define SH7780_PCILSR 0x104 /* PCI Local Space Register0 */
-#define SH7780_PCILSR1 0x108 /* PCI Local Space Register1 */
-#define SH7780_PCILAR0 0x10C /* PCI Local Address Register1 */
-#define SH7780_PCILAR1 0x110 /* PCI Local Address Register1 */
#define SH7780_PCIIR 0x114 /* PCI Interrupt Register */
#define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */
#define SH7780_PCIAIR 0x11C /* Error Address Register */
@@ -106,9 +99,4 @@
#define SH7780_32BIT_DDR_BASE_ADDR 0x40000000
-struct sh4_pci_address_map;
-
-/* arch/sh/drivers/pci/pci-sh7780.c */
-int sh7780_pcic_init(struct sh4_pci_address_map *map);
-
#endif /* _PCI_SH7780_H_ */
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 0d6ac7a1db49..54d77cbb8b39 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -1,67 +1,156 @@
/*
- * arch/sh/drivers/pci/pci.c
+ * New-style PCI core.
*
- * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org>
- * Copyright (c) 2004 - 2006 Paul Mundt <lethal@linux-sh.org>
+ * Copyright (c) 2004 - 2009 Paul Mundt
+ * Copyright (c) 2002 M. R. Brown
*
- * These functions are collected here to reduce duplication of common
- * code amongst the many platform-specific PCI support code files.
- *
- * These routines require the following board-specific routines:
- * void pcibios_fixup_irqs();
- *
- * See include/asm-sh/pci.h for more information.
+ * Modelled after arch/mips/pci/pci.c:
+ * Copyright (C) 2003, 04 Ralf Baechle (ralf@linux-mips.org)
*
* 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/kernel.h>
+#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/types.h>
#include <linux/dma-debug.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
-static int __init pcibios_init(void)
+unsigned long PCIBIOS_MIN_IO = 0x0000;
+unsigned long PCIBIOS_MIN_MEM = 0;
+
+/*
+ * The PCI controller list.
+ */
+static struct pci_channel *hose_head, **hose_tail = &hose_head;
+
+static int pci_initialized;
+
+static void __devinit pcibios_scanbus(struct pci_channel *hose)
{
- struct pci_channel *p;
+ static int next_busno;
struct pci_bus *bus;
- int busno;
-#ifdef CONFIG_PCI_AUTO
- /* assign resources */
- busno = 0;
- for (p = board_pci_channels; p->pci_ops != NULL; p++)
- busno = pciauto_assign_resources(busno, p) + 1;
-#endif
+ bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
+ if (bus) {
+ next_busno = bus->subordinate + 1;
+ /* Don't allow 8-bit bus number overflow inside the hose -
+ reserve some space for bridges. */
+ if (next_busno > 224)
+ next_busno = 0;
+
+ pci_bus_size_bridges(bus);
+ pci_bus_assign_resources(bus);
+ pci_enable_bridges(bus);
+ }
+}
+
+static DEFINE_MUTEX(pci_scan_mutex);
- /* scan the buses */
- busno = 0;
- for (p = board_pci_channels; p->pci_ops != NULL; p++) {
- bus = pci_scan_bus(busno, p->pci_ops, p);
- busno = bus->subordinate + 1;
+void __devinit register_pci_controller(struct pci_channel *hose)
+{
+ if (request_resource(&iomem_resource, hose->mem_resource) < 0)
+ goto out;
+ if (request_resource(&ioport_resource, hose->io_resource) < 0) {
+ release_resource(hose->mem_resource);
+ goto out;
}
+ *hose_tail = hose;
+ hose_tail = &hose->next;
+
+ /*
+ * Do not panic here but later - this might hapen before console init.
+ */
+ if (!hose->io_map_base) {
+ printk(KERN_WARNING
+ "registering PCI controller with io_map_base unset\n");
+ }
+
+ /*
+ * Scan the bus if it is register after the PCI subsystem
+ * initialization.
+ */
+ if (pci_initialized) {
+ mutex_lock(&pci_scan_mutex);
+ pcibios_scanbus(hose);
+ mutex_unlock(&pci_scan_mutex);
+ }
+
+ return;
+
+out:
+ printk(KERN_WARNING
+ "Skipping PCI bus scan due to resource conflict\n");
+}
+
+static int __init pcibios_init(void)
+{
+ struct pci_channel *hose;
+
+ /* Scan all of the recorded PCI controllers. */
+ for (hose = hose_head; hose; hose = hose->next)
+ pcibios_scanbus(hose);
+
pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
dma_debug_add_bus(&pci_bus_type);
+ pci_initialized = 1;
+
return 0;
}
subsys_initcall(pcibios_init);
+static void pcibios_fixup_device_resources(struct pci_dev *dev,
+ struct pci_bus *bus)
+{
+ /* Update device resources. */
+ struct pci_channel *hose = bus->sysdata;
+ unsigned long offset = 0;
+ int i;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ if (!dev->resource[i].start)
+ continue;
+ if (dev->resource[i].flags & IORESOURCE_PCI_FIXED)
+ continue;
+ if (dev->resource[i].flags & IORESOURCE_IO)
+ offset = hose->io_offset;
+ else if (dev->resource[i].flags & IORESOURCE_MEM)
+ offset = hose->mem_offset;
+
+ dev->resource[i].start += offset;
+ dev->resource[i].end += offset;
+ }
+}
+
/*
* Called after each bus is probed, but before its children
* are examined.
*/
-void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus)
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
{
- pci_read_bridge_bases(bus);
-}
+ struct pci_dev *dev = bus->self;
+ struct list_head *ln;
+ struct pci_channel *chan = bus->sysdata;
-void pcibios_align_resource(void *data, struct resource *res,
- resource_size_t size, resource_size_t align)
- __attribute__ ((weak));
+ if (!dev) {
+ bus->resource[0] = chan->io_resource;
+ bus->resource[1] = chan->mem_resource;
+ }
+
+ for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
+ dev = pci_dev_b(ln);
+
+ if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+ pcibios_fixup_device_resources(dev, bus);
+ }
+}
/*
* We need to avoid collisions with `mirrored' VGA ports
@@ -72,14 +161,58 @@ void pcibios_align_resource(void *data, struct resource *res,
void pcibios_align_resource(void *data, struct resource *res,
resource_size_t size, resource_size_t align)
{
+ struct pci_dev *dev = data;
+ struct pci_channel *chan = dev->sysdata;
+ resource_size_t start = res->start;
+
if (res->flags & IORESOURCE_IO) {
- resource_size_t start = res->start;
+ if (start < PCIBIOS_MIN_IO + chan->io_resource->start)
+ start = PCIBIOS_MIN_IO + chan->io_resource->start;
+ /*
+ * Put everything into 0x00-0xff region modulo 0x400.
+ */
if (start & 0x300) {
start = (start + 0x3ff) & ~0x3ff;
res->start = start;
}
+ } else if (res->flags & IORESOURCE_MEM) {
+ if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start)
+ start = PCIBIOS_MIN_MEM + chan->mem_resource->start;
}
+
+ res->start = start;
+}
+
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+ struct resource *res)
+{
+ struct pci_channel *hose = dev->sysdata;
+ unsigned long offset = 0;
+
+ if (res->flags & IORESOURCE_IO)
+ offset = hose->io_offset;
+ else if (res->flags & IORESOURCE_MEM)
+ offset = hose->mem_offset;
+
+ region->start = res->start - offset;
+ region->end = res->end - offset;
+}
+
+void __devinit
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region)
+{
+ struct pci_channel *hose = dev->sysdata;
+ unsigned long offset = 0;
+
+ if (res->flags & IORESOURCE_IO)
+ offset = hose->io_offset;
+ else if (res->flags & IORESOURCE_MEM)
+ offset = hose->mem_offset;
+
+ res->start = region->start + offset;
+ res->end = region->end + offset;
}
int pcibios_enable_device(struct pci_dev *dev, int mask)
@@ -90,13 +223,21 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
- for(idx=0; idx<6; idx++) {
- if (!(mask & (1 << idx)))
+ for (idx=0; idx < PCI_NUM_RESOURCES; idx++) {
+ /* Only set up the requested stuff */
+ if (!(mask & (1<<idx)))
continue;
+
r = &dev->resource[idx];
+ if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
+ continue;
+ if ((idx == PCI_ROM_RESOURCE) &&
+ (!(r->flags & IORESOURCE_ROM_ENABLE)))
+ continue;
if (!r->start && r->end) {
- printk(KERN_ERR "PCI: Device %s not available because "
- "of resource collisions\n", pci_name(dev));
+ printk(KERN_ERR "PCI: Device %s not available "
+ "because of resource collisions\n",
+ pci_name(dev));
return -EINVAL;
}
if (r->flags & IORESOURCE_IO)
@@ -104,10 +245,8 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
if (r->flags & IORESOURCE_MEM)
cmd |= PCI_COMMAND_MEMORY;
}
- if (dev->resource[PCI_ROM_RESOURCE].start)
- cmd |= PCI_COMMAND_MEMORY;
if (cmd != old_cmd) {
- printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n",
+ printk("PCI: Enabling device %s (%04x -> %04x)\n",
pci_name(dev), old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
@@ -140,6 +279,43 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
+char * __devinit pcibios_setup(char *str)
+{
+ return str;
+}
+
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine)
+{
+ /*
+ * I/O space can be accessed via normal processor loads and stores on
+ * this platform but for now we elect not to do this and portable
+ * drivers should not do this anyway.
+ */
+ if (mmap_state == pci_mmap_io)
+ return -EINVAL;
+
+ /*
+ * Ignore write-combine; for now only return uncached mappings.
+ */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+static void __iomem *ioport_map_pci(struct pci_dev *dev,
+ unsigned long port, unsigned int nr)
+{
+ struct pci_channel *chan = dev->sysdata;
+
+ if (!chan->io_map_base)
+ chan->io_map_base = generic_io_base;
+
+ return (void __iomem *)(chan->io_map_base + port);
+}
+
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
{
resource_size_t start = pci_resource_start(dev, bar);
@@ -151,20 +327,24 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
if (maxlen && len > maxlen)
len = maxlen;
+ if (flags & IORESOURCE_IO)
+ return ioport_map_pci(dev, start, len);
+
/*
* Presently the IORESOURCE_MEM case is a bit special, most
* SH7751 style PCI controllers have PCI memory at a fixed
- * location in the address space where no remapping is desired
- * (typically at 0xfd000000, but is_pci_memaddr() will know
- * best). With the IORESOURCE_MEM case more care has to be taken
+ * location in the address space where no remapping is desired.
+ * With the IORESOURCE_MEM case more care has to be taken
* to inhibit page table mapping for legacy cores, but this is
* punted off to __ioremap().
* -- PFM.
*/
- if (flags & IORESOURCE_IO)
- return ioport_map(start, len);
- if (flags & IORESOURCE_MEM)
- return ioremap(start, len);
+ if (flags & IORESOURCE_MEM) {
+ if (flags & IORESOURCE_CACHEABLE)
+ return ioremap(start, len);
+
+ return ioremap_nocache(start, len);
+ }
return NULL;
}
@@ -175,3 +355,10 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
iounmap(addr);
}
EXPORT_SYMBOL(pci_iounmap);
+
+#ifdef CONFIG_HOTPLUG
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+EXPORT_SYMBOL(PCIBIOS_MIN_IO);
+EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
+#endif
diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h
index 09acbc32d6c7..4c5462daa74c 100644
--- a/arch/sh/include/asm/cacheflush.h
+++ b/arch/sh/include/asm/cacheflush.h
@@ -75,7 +75,5 @@ extern void copy_from_user_page(struct vm_area_struct *vma,
#define flush_cache_vmap(start, end) flush_cache_all()
#define flush_cache_vunmap(start, end) flush_cache_all()
-#define HAVE_ARCH_UNMAPPED_AREA
-
#endif /* __KERNEL__ */
#endif /* __ASM_SH_CACHEFLUSH_H */
diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h
index 2f6c9627bc1f..b1f29199e4bd 100644
--- a/arch/sh/include/asm/clock.h
+++ b/arch/sh/include/asm/clock.h
@@ -1,7 +1,6 @@
#ifndef __ASM_SH_CLOCK_H
#define __ASM_SH_CLOCK_H
-#include <linux/kref.h>
#include <linux/list.h>
#include <linux/seq_file.h>
#include <linux/clk.h>
@@ -28,7 +27,7 @@ struct clk {
struct clk *parent;
struct clk_ops *ops;
- struct kref kref;
+ int usecount;
unsigned long rate;
unsigned long flags;
@@ -37,6 +36,7 @@ struct clk {
#define CLK_ALWAYS_ENABLED (1 << 0)
#define CLK_RATE_PROPAGATES (1 << 1)
+#define CLK_NEEDS_INIT (1 << 2)
/* Should be defined by processor-specific code */
void arch_init_clk_ops(struct clk_ops **, int type);
diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h
index efd511d0803a..8688a88303ee 100644
--- a/arch/sh/include/asm/device.h
+++ b/arch/sh/include/asm/device.h
@@ -10,3 +10,5 @@ struct platform_device;
int platform_resource_setup_memory(struct platform_device *pdev,
char *name, unsigned long memsize);
+void plat_early_device_setup(void);
+
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 0454f8d68059..25348141674b 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -123,10 +123,15 @@ static inline void __raw_reads##bwlq(volatile void __iomem *mem, \
__BUILD_MEMORY_STRING(b, u8)
__BUILD_MEMORY_STRING(w, u16)
-__BUILD_MEMORY_STRING(q, u64)
+#ifdef CONFIG_SUPERH32
void __raw_writesl(void __iomem *addr, const void *data, int longlen);
void __raw_readsl(const void __iomem *addr, void *data, int longlen);
+#else
+__BUILD_MEMORY_STRING(l, u32)
+#endif
+
+__BUILD_MEMORY_STRING(q, u64)
#define writesb __raw_writesb
#define writesw __raw_writesw
@@ -224,17 +229,6 @@ void __iomem *__ioremap(unsigned long offset, unsigned long size,
unsigned long flags);
void __iounmap(void __iomem *addr);
-/* arch/sh/mm/ioremap_64.c */
-unsigned long onchip_remap(unsigned long addr, unsigned long size,
- const char *name);
-extern void onchip_unmap(unsigned long vaddr);
-#else
-#define __ioremap(offset, size, flags) ((void __iomem *)(offset))
-#define __iounmap(addr) do { } while (0)
-#define onchip_remap(addr, size, name) (addr)
-#define onchip_unmap(addr) do { } while (0)
-#endif /* CONFIG_MMU */
-
static inline void __iomem *
__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
{
@@ -268,6 +262,10 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
return __ioremap(offset, size, flags);
}
+#else
+#define __ioremap_mode(offset, size, flags) ((void __iomem *)(offset))
+#define __iounmap(addr) do { } while (0)
+#endif /* CONFIG_MMU */
#define ioremap(offset, size) \
__ioremap_mode((offset), (size), 0)
diff --git a/arch/sh/include/asm/kprobes.h b/arch/sh/include/asm/kprobes.h
index 613644a758e8..036c3311233c 100644
--- a/arch/sh/include/asm/kprobes.h
+++ b/arch/sh/include/asm/kprobes.h
@@ -6,7 +6,7 @@
#include <linux/types.h>
#include <linux/ptrace.h>
-typedef u16 kprobe_opcode_t;
+typedef insn_size_t kprobe_opcode_t;
#define BREAKPOINT_INSTRUCTION 0xc33a
#define MAX_INSN_SIZE 16
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index df1d383e18a5..5b2e0fcdfc22 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -17,54 +17,29 @@
* external) PCI controllers.
*/
struct pci_channel {
- struct pci_ops *pci_ops;
- struct resource *io_resource;
- struct resource *mem_resource;
- int first_devfn;
- int last_devfn;
-};
+ struct pci_channel *next;
-/*
- * Each board initializes this array and terminates it with a NULL entry.
- */
-extern struct pci_channel board_pci_channels[];
+ struct pci_ops *pci_ops;
+ struct resource *io_resource;
+ struct resource *mem_resource;
-#define PCIBIOS_MIN_IO board_pci_channels->io_resource->start
-#define PCIBIOS_MIN_MEM board_pci_channels->mem_resource->start
+ unsigned long io_offset;
+ unsigned long mem_offset;
-/*
- * I/O routine helpers
- */
-#if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785)
-#define PCI_IO_AREA 0xFE400000
-#define PCI_IO_SIZE 0x00400000
-#elif defined(CONFIG_CPU_SH5)
-extern unsigned long PCI_IO_AREA;
-#define PCI_IO_SIZE 0x00010000
-#else
-#define PCI_IO_AREA 0xFE240000
-#define PCI_IO_SIZE 0x00040000
-#endif
+ unsigned long reg_base;
-#define PCI_MEM_SIZE 0x01000000
+ unsigned long io_map_base;
+};
-#define SH4_PCIIOBR_MASK 0xFFFC0000
-#define pci_ioaddr(addr) (PCI_IO_AREA + (addr & ~SH4_PCIIOBR_MASK))
+extern void register_pci_controller(struct pci_channel *hose);
-#if defined(CONFIG_PCI)
-#define is_pci_ioaddr(port) \
- (((port) >= PCIBIOS_MIN_IO) && \
- ((port) < (PCIBIOS_MIN_IO + PCI_IO_SIZE)))
-#define is_pci_memaddr(port) \
- (((port) >= PCIBIOS_MIN_MEM) && \
- ((port) < (PCIBIOS_MIN_MEM + PCI_MEM_SIZE)))
-#else
-#define is_pci_ioaddr(port) (0)
-#define is_pci_memaddr(port) (0)
-#endif
+extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM;
struct pci_dev;
+#define HAVE_PCI_MMAP
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine);
extern void pcibios_set_master(struct pci_dev *dev);
static inline void pcibios_penalize_isa_irq(int irq, int active)
@@ -123,22 +98,51 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
}
#endif
+#ifdef CONFIG_SUPERH32
+/*
+ * If we're on an SH7751 or SH7780 PCI controller, PCI memory is mapped
+ * at the end of the address space in a special non-translatable area.
+ */
+#define PCI_MEM_FIXED_START 0xfd000000
+#define PCI_MEM_FIXED_END (PCI_MEM_FIXED_START + 0x01000000)
+
+#define is_pci_memory_fixed_range(s, e) \
+ ((s) >= PCI_MEM_FIXED_START && (e) < PCI_MEM_FIXED_END)
+#else
+#define is_pci_memory_fixed_range(s, e) (0)
+#endif
+
/* Board-specific fixup routines. */
-void pcibios_fixup(void);
-int pcibios_init_platform(void);
int pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
-#ifdef CONFIG_PCI_AUTO
-int pciauto_assign_resources(int busno, struct pci_channel *hose);
-#endif
+extern void pcibios_resource_to_bus(struct pci_dev *dev,
+ struct pci_bus_region *region, struct resource *res);
-#endif /* __KERNEL__ */
+extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region);
+
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+ struct resource *root = NULL;
-/* generic pci stuff */
-#include <asm-generic/pci.h>
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
+
+/* Chances are this interrupt is wired PC-style ... */
+static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
+{
+ return channel ? 15 : 14;
+}
/* generic DMA-mapping stuff */
#include <asm-generic/pci-dma-compat.h>
+#endif /* __KERNEL__ */
#endif /* __ASM_SH_PCI_H */
diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h
index b517ae08b9c0..2a011b18090b 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -154,6 +154,10 @@ extern void kmap_coherent_init(void);
#define kmap_coherent_init() do { } while (0)
#endif
+/* arch/sh/mm/mmap.c */
+#define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+
#include <asm-generic/pgtable.h>
#endif /* __ASM_SH_PGTABLE_H */
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 1fd58b421438..005c962c8b1c 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -32,7 +32,7 @@ enum cpu_type {
/* SH-4A types */
CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SH7786,
- CPU_SH7723, CPU_SHX3,
+ CPU_SH7723, CPU_SH7724, CPU_SHX3,
/* SH4AL-DSP types */
CPU_SH7343, CPU_SH7722, CPU_SH7366,
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index 68e20ff9aa9b..1dc12cb44a2d 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -102,6 +102,11 @@ struct pt_dspregs {
#define PTRACE_GETDSPREGS 55 /* DSP registers */
#define PTRACE_SETDSPREGS 56
+#define PT_TEXT_END_ADDR 240
+#define PT_TEXT_ADDR 244 /* &(struct user)->start_code */
+#define PT_DATA_ADDR 248 /* &(struct user)->start_data */
+#define PT_TEXT_LEN 252
+
#ifdef __KERNEL__
#include <asm/addrspace.h>
diff --git a/arch/sh/include/asm/rtc.h b/arch/sh/include/asm/rtc.h
index f7b010d48af7..52b0c2dba979 100644
--- a/arch/sh/include/asm/rtc.h
+++ b/arch/sh/include/asm/rtc.h
@@ -6,6 +6,17 @@ extern void (*board_time_init)(void);
extern void (*rtc_sh_get_time)(struct timespec *);
extern int (*rtc_sh_set_time)(const time_t);
+/* some dummy definitions */
+#define RTC_BATT_BAD 0x100 /* battery bad */
+#define RTC_SQWE 0x08 /* enable square-wave output */
+#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */
+#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */
+#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */
+
+struct rtc_time;
+unsigned int get_rtc_time(struct rtc_time *);
+int set_rtc_time(struct rtc_time *);
+
#define RTC_CAP_4_DIGIT_YEAR (1 << 0)
struct sh_rtc_platform_info {
diff --git a/arch/sh/include/asm/swab.h b/arch/sh/include/asm/swab.h
index e69315935107..0e08fe54ad71 100644
--- a/arch/sh/include/asm/swab.h
+++ b/arch/sh/include/asm/swab.h
@@ -14,15 +14,15 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
{
__asm__(
#ifdef __SH5__
- "byterev %0, %0\n\t"
+ "byterev %1, %0\n\t"
"shari %0, 32, %0"
#else
- "swap.b %0, %0\n\t"
+ "swap.b %1, %0\n\t"
"swap.w %0, %0\n\t"
"swap.b %0, %0"
#endif
: "=r" (x)
- : "0" (x));
+ : "r" (x));
return x;
}
@@ -32,13 +32,13 @@ static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
{
__asm__(
#ifdef __SH5__
- "byterev %0, %0\n\t"
+ "byterev %1, %0\n\t"
"shari %0, 32, %0"
#else
- "swap.b %0, %0"
+ "swap.b %1, %0"
#endif
: "=r" (x)
- : "0" (x));
+ : "r" (x));
return x;
}
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index 240b31e1142c..6c68a51f1cc5 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -198,7 +198,7 @@ do { \
})
#endif
-int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs,
+int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
struct mem_access *ma);
asmlinkage void do_address_error(struct pt_regs *regs,
diff --git a/arch/sh/include/asm/timer.h b/arch/sh/include/asm/timer.h
deleted file mode 100644
index 4c3b66e30af2..000000000000
--- a/arch/sh/include/asm/timer.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef __ASM_SH_TIMER_H
-#define __ASM_SH_TIMER_H
-
-#include <linux/sysdev.h>
-#include <linux/clocksource.h>
-#include <cpu/timer.h>
-
-struct sys_timer_ops {
- int (*init)(void);
- int (*start)(void);
- int (*stop)(void);
-#ifndef CONFIG_GENERIC_TIME
- unsigned long (*get_offset)(void);
-#endif
-};
-
-struct sys_timer {
- const char *name;
-
- struct sys_device dev;
- struct sys_timer_ops *ops;
-};
-
-#define TICK_SIZE (tick_nsec / 1000)
-
-extern struct sys_timer tmu_timer, cmt_timer, mtu2_timer;
-extern struct sys_timer *sys_timer;
-
-#ifndef CONFIG_GENERIC_TIME
-static inline unsigned long get_timer_offset(void)
-{
- return sys_timer->ops->get_offset();
-}
-#endif
-
-/* arch/sh/kernel/timers/timer.c */
-struct sys_timer *get_sys_timer(void);
-
-/* arch/sh/kernel/time.c */
-void handle_timer_tick(void);
-
-extern struct clocksource clocksource_sh;
-
-#endif /* __ASM_SH_TIMER_H */
diff --git a/arch/sh/include/asm/types.h b/arch/sh/include/asm/types.h
index beea4e6f8dfd..b13caca62a76 100644
--- a/arch/sh/include/asm/types.h
+++ b/arch/sh/include/asm/types.h
@@ -23,9 +23,9 @@ typedef unsigned short umode_t;
typedef u32 dma_addr_t;
#ifdef CONFIG_SUPERH32
-typedef u16 opcode_t;
+typedef u16 insn_size_t;
#else
-typedef u32 opcode_t;
+typedef u32 insn_size_t;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/sh/include/asm/ubc.h b/arch/sh/include/asm/ubc.h
index a7b9028bbfbb..4ca4b7717371 100644
--- a/arch/sh/include/asm/ubc.h
+++ b/arch/sh/include/asm/ubc.h
@@ -42,12 +42,23 @@
#define BRCR_CMFA (1 << 15)
#define BRCR_CMFB (1 << 14)
+
+#if defined CONFIG_CPU_SH2A
+#define BRCR_CMFCA (1 << 15)
+#define BRCR_CMFCB (1 << 14)
+#define BRCR_CMFDA (1 << 13)
+#define BRCR_CMFDB (1 << 12)
+#define BRCR_PCBB (1 << 6) /* 1: after execution */
+#define BRCR_PCBA (1 << 5) /* 1: after execution */
+#define BRCR_PCTE 0
+#else
#define BRCR_PCTE (1 << 11)
#define BRCR_PCBA (1 << 10) /* 1: after execution */
#define BRCR_DBEB (1 << 7)
#define BRCR_PCBB (1 << 6)
#define BRCR_SEQ (1 << 3)
#define BRCR_UBDE (1 << 0)
+#endif
#ifndef __ASSEMBLY__
/* arch/sh/kernel/cpu/ubc.S */
diff --git a/arch/sh/include/cpu-sh2a/cpu/ubc.h b/arch/sh/include/cpu-sh2a/cpu/ubc.h
index 8ce2fc1cf625..1192e1c761a7 100644
--- a/arch/sh/include/cpu-sh2a/cpu/ubc.h
+++ b/arch/sh/include/cpu-sh2a/cpu/ubc.h
@@ -1 +1,28 @@
-#include <cpu-sh2/cpu/ubc.h>
+/*
+ * SH-2A UBC definitions
+ *
+ * Copyright (C) 2008 Kieran Bingham
+ *
+ * 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.
+ */
+
+#ifndef __ASM_CPU_SH2A_UBC_H
+#define __ASM_CPU_SH2A_UBC_H
+
+#define UBC_BARA 0xfffc0400
+#define UBC_BAMRA 0xfffc0404
+#define UBC_BBRA 0xfffc04a0 /* 16 bit access */
+#define UBC_BDRA 0xfffc0408
+#define UBC_BDMRA 0xfffc040c
+
+#define UBC_BARB 0xfffc0410
+#define UBC_BAMRB 0xfffc0414
+#define UBC_BBRB 0xfffc04b0 /* 16 bit access */
+#define UBC_BDRB 0xfffc0418
+#define UBC_BDMRB 0xfffc041c
+
+#define UBC_BRCR 0xfffc04c0
+
+#endif /* __ASM_CPU_SH2A_UBC_H */
diff --git a/arch/sh/include/cpu-sh3/cpu/timer.h b/arch/sh/include/cpu-sh3/cpu/timer.h
deleted file mode 100644
index 793acf12aa08..000000000000
--- a/arch/sh/include/cpu-sh3/cpu/timer.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * include/asm-sh/cpu-sh3/timer.h
- *
- * Copyright (C) 2004 Lineo Solutions, Inc.
- *
- * 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.
- */
-#ifndef __ASM_CPU_SH3_TIMER_H
-#define __ASM_CPU_SH3_TIMER_H
-
-/*
- * ---------------------------------------------------------------------------
- * TMU Common definitions for SH3 processors
- * SH7706
- * SH7709S
- * SH7727
- * SH7729R
- * SH7710
- * SH7720
- * SH7710
- * ---------------------------------------------------------------------------
- */
-
-#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && !defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define TMU_TOCR 0xfffffe90 /* Byte access */
-#endif
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7710) || \
- defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define TMU_012_TSTR 0xa412fe92 /* Byte access */
-
-#define TMU0_TCOR 0xa412fe94 /* Long access */
-#define TMU0_TCNT 0xa412fe98 /* Long access */
-#define TMU0_TCR 0xa412fe9c /* Word access */
-
-#define TMU1_TCOR 0xa412fea0 /* Long access */
-#define TMU1_TCNT 0xa412fea4 /* Long access */
-#define TMU1_TCR 0xa412fea8 /* Word access */
-
-#define TMU2_TCOR 0xa412feac /* Long access */
-#define TMU2_TCNT 0xa412feb0 /* Long access */
-#define TMU2_TCR 0xa412feb4 /* Word access */
-
-#else
-#define TMU_012_TSTR 0xfffffe92 /* Byte access */
-
-#define TMU0_TCOR 0xfffffe94 /* Long access */
-#define TMU0_TCNT 0xfffffe98 /* Long access */
-#define TMU0_TCR 0xfffffe9c /* Word access */
-
-#define TMU1_TCOR 0xfffffea0 /* Long access */
-#define TMU1_TCNT 0xfffffea4 /* Long access */
-#define TMU1_TCR 0xfffffea8 /* Word access */
-
-#define TMU2_TCOR 0xfffffeac /* Long access */
-#define TMU2_TCNT 0xfffffeb0 /* Long access */
-#define TMU2_TCR 0xfffffeb4 /* Word access */
-#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && !defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define TMU2_TCPR2 0xfffffeb8 /* Long access */
-#endif
-#endif
-
-#endif /* __ASM_CPU_SH3_TIMER_H */
-
diff --git a/arch/sh/include/cpu-sh4/cpu/freq.h b/arch/sh/include/cpu-sh4/cpu/freq.h
index 749d1c434337..ccf1d999db6d 100644
--- a/arch/sh/include/cpu-sh4/cpu/freq.h
+++ b/arch/sh/include/cpu-sh4/cpu/freq.h
@@ -25,6 +25,24 @@
#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780)
#define FRQCR 0xffc80000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define FRQCRA 0xa4150000
+#define FRQCRB 0xa4150004
+#define VCLKCR 0xa4150048
+
+#define FCLKACR 0xa4150008
+#define FCLKBCR 0xa415000c
+#define FRQCR FRQCRA
+#define SCLKACR FCLKACR
+#define SCLKBCR FCLKBCR
+#define FCLKACR 0xa4150008
+#define FCLKBCR 0xa415000c
+#define IrDACLKCR 0xa4150018
+
+#define MSTPCR0 0xa4150030
+#define MSTPCR1 0xa4150034
+#define MSTPCR2 0xa4150038
+
#elif defined(CONFIG_CPU_SUBTYPE_SH7785)
#define FRQCR0 0xffc80000
#define FRQCR1 0xffc80004
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h
new file mode 100644
index 000000000000..34605c9e354d
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h
@@ -0,0 +1,255 @@
+#ifndef __ASM_SH7724_H__
+#define __ASM_SH7724_H__
+
+enum {
+ /* PTA */
+ GPIO_PTA7, GPIO_PTA6, GPIO_PTA5, GPIO_PTA4,
+ GPIO_PTA3, GPIO_PTA2, GPIO_PTA1, GPIO_PTA0,
+
+ /* PTB */
+ GPIO_PTB7, GPIO_PTB6, GPIO_PTB5, GPIO_PTB4,
+ GPIO_PTB3, GPIO_PTB2, GPIO_PTB1, GPIO_PTB0,
+
+ /* PTC */
+ GPIO_PTC7, GPIO_PTC6, GPIO_PTC5, GPIO_PTC4,
+ GPIO_PTC3, GPIO_PTC2, GPIO_PTC1, GPIO_PTC0,
+
+ /* PTD */
+ GPIO_PTD7, GPIO_PTD6, GPIO_PTD5, GPIO_PTD4,
+ GPIO_PTD3, GPIO_PTD2, GPIO_PTD1, GPIO_PTD0,
+
+ /* PTE */
+ GPIO_PTE7, GPIO_PTE6, GPIO_PTE5, GPIO_PTE4,
+ GPIO_PTE3, GPIO_PTE2, GPIO_PTE1, GPIO_PTE0,
+
+ /* PTF */
+ GPIO_PTF7, GPIO_PTF6, GPIO_PTF5, GPIO_PTF4,
+ GPIO_PTF3, GPIO_PTF2, GPIO_PTF1, GPIO_PTF0,
+
+ /* PTG */
+ GPIO_PTG5, GPIO_PTG4,
+ GPIO_PTG3, GPIO_PTG2, GPIO_PTG1, GPIO_PTG0,
+
+ /* PTH */
+ GPIO_PTH7, GPIO_PTH6, GPIO_PTH5, GPIO_PTH4,
+ GPIO_PTH3, GPIO_PTH2, GPIO_PTH1, GPIO_PTH0,
+
+ /* PTJ */
+ GPIO_PTJ7, GPIO_PTJ6, GPIO_PTJ5,
+ GPIO_PTJ3, GPIO_PTJ2, GPIO_PTJ1, GPIO_PTJ0,
+
+ /* PTK */
+ GPIO_PTK7, GPIO_PTK6, GPIO_PTK5, GPIO_PTK4,
+ GPIO_PTK3, GPIO_PTK2, GPIO_PTK1, GPIO_PTK0,
+
+ /* PTL */
+ GPIO_PTL7, GPIO_PTL6, GPIO_PTL5, GPIO_PTL4,
+ GPIO_PTL3, GPIO_PTL2, GPIO_PTL1, GPIO_PTL0,
+
+ /* PTM */
+ GPIO_PTM7, GPIO_PTM6, GPIO_PTM5, GPIO_PTM4,
+ GPIO_PTM3, GPIO_PTM2, GPIO_PTM1, GPIO_PTM0,
+
+ /* PTN */
+ GPIO_PTN7, GPIO_PTN6, GPIO_PTN5, GPIO_PTN4,
+ GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
+
+ /* PTQ */
+ GPIO_PTQ7, GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
+ GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
+
+ /* PTR */
+ GPIO_PTR7, GPIO_PTR6, GPIO_PTR5, GPIO_PTR4,
+ GPIO_PTR3, GPIO_PTR2, GPIO_PTR1, GPIO_PTR0,
+
+ /* PTS */
+ GPIO_PTS6, GPIO_PTS5, GPIO_PTS4,
+ GPIO_PTS3, GPIO_PTS2, GPIO_PTS1, GPIO_PTS0,
+
+ /* PTT */
+ GPIO_PTT7, GPIO_PTT6, GPIO_PTT5, GPIO_PTT4,
+ GPIO_PTT3, GPIO_PTT2, GPIO_PTT1, GPIO_PTT0,
+
+ /* PTU */
+ GPIO_PTU7, GPIO_PTU6, GPIO_PTU5, GPIO_PTU4,
+ GPIO_PTU3, GPIO_PTU2, GPIO_PTU1, GPIO_PTU0,
+
+ /* PTV */
+ GPIO_PTV7, GPIO_PTV6, GPIO_PTV5, GPIO_PTV4,
+ GPIO_PTV3, GPIO_PTV2, GPIO_PTV1, GPIO_PTV0,
+
+ /* PTW */
+ GPIO_PTW7, GPIO_PTW6, GPIO_PTW5, GPIO_PTW4,
+ GPIO_PTW3, GPIO_PTW2, GPIO_PTW1, GPIO_PTW0,
+
+ /* PTX */
+ GPIO_PTX7, GPIO_PTX6, GPIO_PTX5, GPIO_PTX4,
+ GPIO_PTX3, GPIO_PTX2, GPIO_PTX1, GPIO_PTX0,
+
+ /* PTY */
+ GPIO_PTY7, GPIO_PTY6, GPIO_PTY5, GPIO_PTY4,
+ GPIO_PTY3, GPIO_PTY2, GPIO_PTY1, GPIO_PTY0,
+
+ /* PTZ */
+ GPIO_PTZ7, GPIO_PTZ6, GPIO_PTZ5, GPIO_PTZ4,
+ GPIO_PTZ3, GPIO_PTZ2, GPIO_PTZ1, GPIO_PTZ0,
+
+ /* BSC (PTA/PTB/PTJ/PTQ/PTR/PTT) */
+ GPIO_FN_D31, GPIO_FN_D30, GPIO_FN_D29, GPIO_FN_D28,
+ GPIO_FN_D27, GPIO_FN_D26, GPIO_FN_D25, GPIO_FN_D24,
+ GPIO_FN_D23, GPIO_FN_D22, GPIO_FN_D21, GPIO_FN_D20,
+ GPIO_FN_D19, GPIO_FN_D18, GPIO_FN_D17, GPIO_FN_D16,
+ GPIO_FN_D15, GPIO_FN_D14, GPIO_FN_D13, GPIO_FN_D12,
+ GPIO_FN_D11, GPIO_FN_D10, GPIO_FN_D9, GPIO_FN_D8,
+ GPIO_FN_D7, GPIO_FN_D6, GPIO_FN_D5, GPIO_FN_D4,
+ GPIO_FN_D3, GPIO_FN_D2, GPIO_FN_D1, GPIO_FN_D0,
+ GPIO_FN_A25, GPIO_FN_A24, GPIO_FN_A23, GPIO_FN_A22,
+ GPIO_FN_CS6B_CE1B, GPIO_FN_CS6A_CE2B,
+ GPIO_FN_CS5B_CE1A, GPIO_FN_CS5A_CE2A,
+ GPIO_FN_WE3_ICIOWR, GPIO_FN_WE2_ICIORD,
+ GPIO_FN_IOIS16, GPIO_FN_WAIT,
+ GPIO_FN_BS,
+
+ /* KEYSC (PTA/PTB)*/
+ GPIO_FN_KEYOUT5_IN5, GPIO_FN_KEYOUT4_IN6, GPIO_FN_KEYIN4,
+ GPIO_FN_KEYIN3, GPIO_FN_KEYIN2, GPIO_FN_KEYIN1, GPIO_FN_KEYIN0,
+ GPIO_FN_KEYOUT3, GPIO_FN_KEYOUT2, GPIO_FN_KEYOUT1, GPIO_FN_KEYOUT0,
+
+ /* ATAPI (PTA/PTB/PTK/PTR/PTS/PTW) */
+ GPIO_FN_IDED15, GPIO_FN_IDED14, GPIO_FN_IDED13, GPIO_FN_IDED12,
+ GPIO_FN_IDED11, GPIO_FN_IDED10, GPIO_FN_IDED9, GPIO_FN_IDED8,
+ GPIO_FN_IDED7, GPIO_FN_IDED6, GPIO_FN_IDED5, GPIO_FN_IDED4,
+ GPIO_FN_IDED3, GPIO_FN_IDED2, GPIO_FN_IDED1, GPIO_FN_IDED0,
+ GPIO_FN_IDEA2, GPIO_FN_IDEA1, GPIO_FN_IDEA0, GPIO_FN_IDEIOWR,
+ GPIO_FN_IODREQ, GPIO_FN_IDECS0, GPIO_FN_IDECS1, GPIO_FN_IDEIORD,
+ GPIO_FN_DIRECTION, GPIO_FN_EXBUF_ENB, GPIO_FN_IDERST, GPIO_FN_IODACK,
+ GPIO_FN_IDEINT, GPIO_FN_IDEIORDY,
+
+ /* TPU (PTB/PTR/PTS) */
+ GPIO_FN_TPUTO3, GPIO_FN_TPUTO2, GPIO_FN_TPUTO1, GPIO_FN_TPUTO0,
+ GPIO_FN_TPUTI3, GPIO_FN_TPUTI2,
+
+ /* LCDC (PTC/PTD/PTE/PTF/PTM/PTR) */
+ GPIO_FN_LCDD23, GPIO_FN_LCDD22, GPIO_FN_LCDD21, GPIO_FN_LCDD20,
+ GPIO_FN_LCDD19, GPIO_FN_LCDD18, GPIO_FN_LCDD17, GPIO_FN_LCDD16,
+ GPIO_FN_LCDD15, GPIO_FN_LCDD14, GPIO_FN_LCDD13, GPIO_FN_LCDD12,
+ GPIO_FN_LCDD11, GPIO_FN_LCDD10, GPIO_FN_LCDD9, GPIO_FN_LCDD8,
+ GPIO_FN_LCDD7, GPIO_FN_LCDD6, GPIO_FN_LCDD5, GPIO_FN_LCDD4,
+ GPIO_FN_LCDD3, GPIO_FN_LCDD2, GPIO_FN_LCDD1, GPIO_FN_LCDD0,
+ GPIO_FN_LCDVSYN, GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_LCDHSYN,
+ GPIO_FN_LCDCS, GPIO_FN_LCDDON, GPIO_FN_LCDDCK, GPIO_FN_LCDWR,
+ GPIO_FN_LCDVEPWC, GPIO_FN_LCDVCPWC, GPIO_FN_LCDRD, GPIO_FN_LCDLCLK,
+
+ /* SCIF0 (PTF/PTM) */
+ GPIO_FN_SCIF0_TXD, GPIO_FN_SCIF0_RXD, GPIO_FN_SCIF0_SCK,
+
+ /* SCIF1 (PTL) */
+ GPIO_FN_SCIF1_SCK, GPIO_FN_SCIF1_RXD, GPIO_FN_SCIF1_TXD,
+
+ /* SCIF2 (PTE/PTF/PTN) with LCDC, VOU */
+ GPIO_FN_SCIF2_L_TXD, GPIO_FN_SCIF2_L_SCK, GPIO_FN_SCIF2_L_RXD,
+ GPIO_FN_SCIF2_V_TXD, GPIO_FN_SCIF2_V_SCK, GPIO_FN_SCIF2_V_RXD,
+
+ /* SCIF3 (PTL/PTN/PTZ) with VOU, IRQ */
+ GPIO_FN_SCIF3_V_SCK, GPIO_FN_SCIF3_V_RXD, GPIO_FN_SCIF3_V_TXD,
+ GPIO_FN_SCIF3_V_CTS, GPIO_FN_SCIF3_V_RTS,
+ GPIO_FN_SCIF3_I_SCK, GPIO_FN_SCIF3_I_RXD, GPIO_FN_SCIF3_I_TXD,
+ GPIO_FN_SCIF3_I_CTS, GPIO_FN_SCIF3_I_RTS,
+
+ /* SCIF4 (PTE) */
+ GPIO_FN_SCIF4_SCK, GPIO_FN_SCIF4_RXD, GPIO_FN_SCIF4_TXD,
+
+ /* SCIF5 (PTS) */
+ GPIO_FN_SCIF5_SCK, GPIO_FN_SCIF5_RXD, GPIO_FN_SCIF5_TXD,
+
+ /* FSI (PTE/PTU/PTV) */
+ GPIO_FN_FSIMCKB, GPIO_FN_FSIMCKA, GPIO_FN_FSIOASD,
+ GPIO_FN_FSIIABCK, GPIO_FN_FSIIALRCK, GPIO_FN_FSIOABCK,
+ GPIO_FN_FSIOALRCK, GPIO_FN_CLKAUDIOAO, GPIO_FN_FSIIBSD,
+ GPIO_FN_FSIOBSD, GPIO_FN_FSIIBBCK, GPIO_FN_FSIIBLRCK,
+ GPIO_FN_FSIOBBCK, GPIO_FN_FSIOBLRCK, GPIO_FN_CLKAUDIOBO,
+ GPIO_FN_FSIIASD,
+
+ /* AUD (PTG) */
+ GPIO_FN_AUDCK, GPIO_FN_AUDSYNC, GPIO_FN_AUDATA3,
+ GPIO_FN_AUDATA2, GPIO_FN_AUDATA1, GPIO_FN_AUDATA0,
+
+ /* VIO (PTS) (common?) */
+ GPIO_FN_VIO_CKO,
+
+ /* VIO0 (PTH/PTK) */
+ GPIO_FN_VIO0_D15, GPIO_FN_VIO0_D14, GPIO_FN_VIO0_D13, GPIO_FN_VIO0_D12,
+ GPIO_FN_VIO0_D11, GPIO_FN_VIO0_D10, GPIO_FN_VIO0_D9, GPIO_FN_VIO0_D8,
+ GPIO_FN_VIO0_D7, GPIO_FN_VIO0_D6, GPIO_FN_VIO0_D5, GPIO_FN_VIO0_D4,
+ GPIO_FN_VIO0_D3, GPIO_FN_VIO0_D2, GPIO_FN_VIO0_D1, GPIO_FN_VIO0_D0,
+ GPIO_FN_VIO0_VD, GPIO_FN_VIO0_CLK,
+ GPIO_FN_VIO0_FLD, GPIO_FN_VIO0_HD,
+
+ /* VIO1 (PTK/PTS) */
+ GPIO_FN_VIO1_D7, GPIO_FN_VIO1_D6, GPIO_FN_VIO1_D5, GPIO_FN_VIO1_D4,
+ GPIO_FN_VIO1_D3, GPIO_FN_VIO1_D2, GPIO_FN_VIO1_D1, GPIO_FN_VIO1_D0,
+ GPIO_FN_VIO1_FLD, GPIO_FN_VIO1_HD, GPIO_FN_VIO1_VD, GPIO_FN_VIO1_CLK,
+
+ /* Eth (PTL/PTN/PTX) */
+ GPIO_FN_RMII_RXD0, GPIO_FN_RMII_RXD1,
+ GPIO_FN_RMII_TXD0, GPIO_FN_RMII_TXD1,
+ GPIO_FN_RMII_REF_CLK, GPIO_FN_RMII_TX_EN,
+ GPIO_FN_RMII_RX_ER, GPIO_FN_RMII_CRS_DV,
+ GPIO_FN_LNKSTA, GPIO_FN_MDIO,
+ GPIO_FN_MDC,
+
+ /* System (PTJ) */
+ GPIO_FN_PDSTATUS, GPIO_FN_STATUS2, GPIO_FN_STATUS0,
+
+ /* VOU (PTL/PTM/PTN*/
+ GPIO_FN_DV_D15, GPIO_FN_DV_D14, GPIO_FN_DV_D13, GPIO_FN_DV_D12,
+ GPIO_FN_DV_D11, GPIO_FN_DV_D10, GPIO_FN_DV_D9, GPIO_FN_DV_D8,
+ GPIO_FN_DV_D7, GPIO_FN_DV_D6, GPIO_FN_DV_D5, GPIO_FN_DV_D4,
+ GPIO_FN_DV_D3, GPIO_FN_DV_D2, GPIO_FN_DV_D1, GPIO_FN_DV_D0,
+ GPIO_FN_DV_CLKI, GPIO_FN_DV_CLK, GPIO_FN_DV_VSYNC, GPIO_FN_DV_HSYNC,
+
+ /* MSIOF0 (PTL/PTM) */
+ GPIO_FN_MSIOF0_RXD, GPIO_FN_MSIOF0_TXD,
+ GPIO_FN_MSIOF0_MCK, GPIO_FN_MSIOF0_TSCK,
+ GPIO_FN_MSIOF0_SS1, GPIO_FN_MSIOF0_SS2,
+ GPIO_FN_MSIOF0_TSYNC, GPIO_FN_MSIOF0_RSCK,
+ GPIO_FN_MSIOF0_RSYNC,
+
+ /* MSIOF1 (PTV) */
+ GPIO_FN_MSIOF1_RXD, GPIO_FN_MSIOF1_TXD,
+ GPIO_FN_MSIOF1_MCK, GPIO_FN_MSIOF1_TSCK,
+ GPIO_FN_MSIOF1_SS1, GPIO_FN_MSIOF1_SS2,
+ GPIO_FN_MSIOF1_TSYNC, GPIO_FN_MSIOF1_RSCK,
+ GPIO_FN_MSIOF1_RSYNC,
+
+ /* DMAC (PTU/PTX) */
+ GPIO_FN_DMAC_DACK0, GPIO_FN_DMAC_DREQ0,
+ GPIO_FN_DMAC_DACK1, GPIO_FN_DMAC_DREQ1,
+
+ /* SDHI0 (PTY) */
+ GPIO_FN_SDHI0CD, GPIO_FN_SDHI0WP, GPIO_FN_SDHI0CMD, GPIO_FN_SDHI0CLK,
+ GPIO_FN_SDHI0D3, GPIO_FN_SDHI0D2, GPIO_FN_SDHI0D1, GPIO_FN_SDHI0D0,
+
+ /* SDHI1 (PTW) */
+ GPIO_FN_SDHI1CD, GPIO_FN_SDHI1WP, GPIO_FN_SDHI1CMD, GPIO_FN_SDHI1CLK,
+ GPIO_FN_SDHI1D3, GPIO_FN_SDHI1D2, GPIO_FN_SDHI1D1, GPIO_FN_SDHI1D0,
+
+ /* MMC (PTW/PTX)*/
+ GPIO_FN_MMC_D7, GPIO_FN_MMC_D6, GPIO_FN_MMC_D5, GPIO_FN_MMC_D4,
+ GPIO_FN_MMC_D3, GPIO_FN_MMC_D2, GPIO_FN_MMC_D1, GPIO_FN_MMC_D0,
+ GPIO_FN_MMC_CLK, GPIO_FN_MMC_CMD,
+
+ /* IrDA (PTX) */
+ GPIO_FN_IRDA_OUT, GPIO_FN_IRDA_IN,
+
+ /* TSIF (PTX) */
+ GPIO_FN_TSIF_TS0_SDAT, GPIO_FN_TSIF_TS0_SCK,
+ GPIO_FN_TSIF_TS0_SDEN, GPIO_FN_TSIF_TS0_SPSYNC,
+
+ /* IRQ (PTZ) */
+ GPIO_FN_INTC_IRQ7, GPIO_FN_INTC_IRQ6, GPIO_FN_INTC_IRQ5,
+ GPIO_FN_INTC_IRQ4, GPIO_FN_INTC_IRQ3, GPIO_FN_INTC_IRQ2,
+ GPIO_FN_INTC_IRQ1, GPIO_FN_INTC_IRQ0,
+};
+
+#endif /* __ASM_SH7724_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/timer.h b/arch/sh/include/cpu-sh4/cpu/timer.h
deleted file mode 100644
index d1e796b96888..000000000000
--- a/arch/sh/include/cpu-sh4/cpu/timer.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * include/asm-sh/cpu-sh4/timer.h
- *
- * Copyright (C) 2004 Lineo Solutions, Inc.
- *
- * 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.
- */
-#ifndef __ASM_CPU_SH4_TIMER_H
-#define __ASM_CPU_SH4_TIMER_H
-
-/*
- * ---------------------------------------------------------------------------
- * TMU Common definitions for SH4 processors
- * SH7750S/SH7750R
- * SH7751/SH7751R
- * SH7760
- * SH-X3
- * ---------------------------------------------------------------------------
- */
-#ifdef CONFIG_CPU_SUBTYPE_SHX3
-#define TMU_012_BASE 0xffc10000
-#define TMU_345_BASE 0xffc20000
-#else
-#define TMU_012_BASE 0xffd80000
-#define TMU_345_BASE 0xfe100000
-#endif
-
-#define TMU_TOCR TMU_012_BASE /* Not supported on all CPUs */
-
-#define TMU_012_TSTR (TMU_012_BASE + 0x04)
-#define TMU_345_TSTR (TMU_345_BASE + 0x04)
-
-#define TMU0_TCOR (TMU_012_BASE + 0x08)
-#define TMU0_TCNT (TMU_012_BASE + 0x0c)
-#define TMU0_TCR (TMU_012_BASE + 0x10)
-
-#define TMU1_TCOR (TMU_012_BASE + 0x14)
-#define TMU1_TCNT (TMU_012_BASE + 0x18)
-#define TMU1_TCR (TMU_012_BASE + 0x1c)
-
-#define TMU2_TCOR (TMU_012_BASE + 0x20)
-#define TMU2_TCNT (TMU_012_BASE + 0x24)
-#define TMU2_TCR (TMU_012_BASE + 0x28)
-#define TMU2_TCPR (TMU_012_BASE + 0x2c)
-
-#define TMU3_TCOR (TMU_345_BASE + 0x08)
-#define TMU3_TCNT (TMU_345_BASE + 0x0c)
-#define TMU3_TCR (TMU_345_BASE + 0x10)
-
-#define TMU4_TCOR (TMU_345_BASE + 0x14)
-#define TMU4_TCNT (TMU_345_BASE + 0x18)
-#define TMU4_TCR (TMU_345_BASE + 0x1c)
-
-#define TMU5_TCOR (TMU_345_BASE + 0x20)
-#define TMU5_TCNT (TMU_345_BASE + 0x24)
-#define TMU5_TCR (TMU_345_BASE + 0x28)
-
-#endif /* __ASM_CPU_SH4_TIMER_H */
diff --git a/arch/sh/include/cpu-sh5/cpu/irq.h b/arch/sh/include/cpu-sh5/cpu/irq.h
index f0f0756e6e84..0ccf257a72d1 100644
--- a/arch/sh/include/cpu-sh5/cpu/irq.h
+++ b/arch/sh/include/cpu-sh5/cpu/irq.h
@@ -111,7 +111,6 @@
#define TOP_PRIORITY 15
extern int intc_evt_to_irq[(0xE20/0x20)+1];
-int intc_irq_describe(char* p, int irq);
extern int platform_int_priority[NR_INTC_IRQS];
#endif /* __ASM_SH_CPU_SH5_IRQ_H */
diff --git a/arch/sh/include/mach-common/mach/sh7785lcr.h b/arch/sh/include/mach-common/mach/sh7785lcr.h
index 1ce27d5c7491..90011d435f30 100644
--- a/arch/sh/include/mach-common/mach/sh7785lcr.h
+++ b/arch/sh/include/mach-common/mach/sh7785lcr.h
@@ -9,11 +9,11 @@
* -----------------------------+---------------+---------------
* 0x00000000 - 0x03ffffff(CS0) | NOR Flash | NOR Flash
* 0x04000000 - 0x05ffffff(CS1) | PLD | PLD
- * 0x06000000 - 0x07ffffff(CS1) | reserved | I2C
+ * 0x06000000 - 0x07ffffff(CS1) | I2C | I2C
* 0x08000000 - 0x0bffffff(CS2) | USB | DDR SDRAM
* 0x0c000000 - 0x0fffffff(CS3) | SD | DDR SDRAM
* 0x10000000 - 0x13ffffff(CS4) | SM107 | SM107
- * 0x14000000 - 0x17ffffff(CS5) | I2C | USB
+ * 0x14000000 - 0x17ffffff(CS5) | reserved | USB
* 0x18000000 - 0x1bffffff(CS6) | reserved | SD
* 0x40000000 - 0x5fffffff | DDR SDRAM | (cannot use)
*
@@ -32,6 +32,9 @@
#define PLD_VERSR (PLD_BASE_ADDR + 0x0c)
#define PLD_MMSR (PLD_BASE_ADDR + 0x0e)
+#define PCA9564_ADDR 0x06000000 /* I2C */
+#define PCA9564_SIZE 0x00000100
+
#define SM107_MEM_ADDR 0x10000000
#define SM107_MEM_SIZE 0x00e00000
#define SM107_REG_ADDR 0x13e00000
@@ -40,16 +43,13 @@
#if defined(CONFIG_SH_SH7785LCR_29BIT_PHYSMAPS)
#define R8A66597_ADDR 0x14000000 /* USB */
#define CG200_ADDR 0x18000000 /* SD */
-#define PCA9564_ADDR 0x06000000 /* I2C */
#else
#define R8A66597_ADDR 0x08000000
#define CG200_ADDR 0x0c000000
-#define PCA9564_ADDR 0x14000000
#endif
#define R8A66597_SIZE 0x00000100
#define CG200_SIZE 0x00010000
-#define PCA9564_SIZE 0x00000100
#endif /* __ASM_SH_RENESAS_SH7785LCR_H */
diff --git a/arch/sh/include/mach-dreamcast/mach/pci.h b/arch/sh/include/mach-dreamcast/mach/pci.h
index 75fc9009e092..0314d975e626 100644
--- a/arch/sh/include/mach-dreamcast/mach/pci.h
+++ b/arch/sh/include/mach-dreamcast/mach/pci.h
@@ -21,5 +21,7 @@
#define GAPSPCI_IRQ HW_EVENT_EXTERNAL
+extern struct pci_ops gapspci_pci_ops;
+
#endif /* __ASM_SH_DREAMCAST_PCI_H */
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
index 82a3a150c00d..9411e3e31e68 100644
--- a/arch/sh/kernel/Makefile_32
+++ b/arch/sh/kernel/Makefile_32
@@ -11,10 +11,10 @@ endif
obj-y := debugtraps.o idle.o io.o io_generic.o irq.o \
machvec.o process_32.o ptrace_32.o setup.o signal_32.o \
- sys_sh.o sys_sh32.o syscalls_32.o time_32.o topology.o \
+ sys_sh.o sys_sh32.o syscalls_32.o time.o topology.o \
traps.o traps_32.o
-obj-y += cpu/ timers/
+obj-y += cpu/
obj-$(CONFIG_VSYSCALL) += vsyscall/
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
@@ -32,4 +32,6 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_DUMP_CODE) += disassemble.o
obj-$(CONFIG_HIBERNATION) += swsusp.o
+obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
+
EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
index fe425d7f6871..67b9f6c6326b 100644
--- a/arch/sh/kernel/Makefile_64
+++ b/arch/sh/kernel/Makefile_64
@@ -2,19 +2,18 @@ extra-y := head_64.o init_task.o vmlinux.lds
obj-y := debugtraps.o idle.o io.o io_generic.o irq.o machvec.o process_64.o \
ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \
- syscalls_64.o time_64.o topology.o traps.o traps_64.o
+ syscalls_64.o time.o topology.o traps.o traps_64.o
-obj-y += cpu/ timers/
-obj-$(CONFIG_VSYSCALL) += vsyscall/
+obj-y += cpu/
obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_MODULES) += sh_ksyms_64.o module.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
+obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
+
EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 1dc896483b59..f54769f455b1 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -19,7 +19,6 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/list.h>
-#include <linux/kref.h>
#include <linux/kobject.h>
#include <linux/sysdev.h>
#include <linux/seq_file.h>
@@ -27,7 +26,6 @@
#include <linux/platform_device.h>
#include <linux/proc_fs.h>
#include <asm/clock.h>
-#include <asm/timer.h>
static LIST_HEAD(clock_list);
static DEFINE_SPINLOCK(clock_lock);
@@ -90,7 +88,7 @@ static void propagate_rate(struct clk *clk)
}
}
-static int __clk_enable(struct clk *clk)
+static void __clk_init(struct clk *clk)
{
/*
* See if this is the first time we're enabling the clock, some
@@ -99,17 +97,34 @@ static int __clk_enable(struct clk *clk)
* changes and the clock needs to hunt for the proper set of
* divisors to use before it can effectively recalc.
*/
- if (unlikely(atomic_read(&clk->kref.refcount) == 1))
+
+ if (clk->flags & CLK_NEEDS_INIT) {
if (clk->ops && clk->ops->init)
clk->ops->init(clk);
- kref_get(&clk->kref);
+ clk->flags &= ~CLK_NEEDS_INIT;
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ if (!clk)
+ return -EINVAL;
+ clk->usecount++;
+
+ /* nothing to do if always enabled */
if (clk->flags & CLK_ALWAYS_ENABLED)
return 0;
- if (likely(clk->ops && clk->ops->enable))
- clk->ops->enable(clk);
+ if (clk->usecount == 1) {
+ __clk_init(clk);
+
+ __clk_enable(clk->parent);
+
+ if (clk->ops && clk->ops->enable)
+ clk->ops->enable(clk);
+ }
return 0;
}
@@ -119,11 +134,6 @@ int clk_enable(struct clk *clk)
unsigned long flags;
int ret;
- if (!clk)
- return -EINVAL;
-
- clk_enable(clk->parent);
-
spin_lock_irqsave(&clock_lock, flags);
ret = __clk_enable(clk);
spin_unlock_irqrestore(&clock_lock, flags);
@@ -132,21 +142,23 @@ int clk_enable(struct clk *clk)
}
EXPORT_SYMBOL_GPL(clk_enable);
-static void clk_kref_release(struct kref *kref)
-{
- /* Nothing to do */
-}
-
static void __clk_disable(struct clk *clk)
{
- int count = kref_put(&clk->kref, clk_kref_release);
+ if (!clk)
+ return;
+
+ clk->usecount--;
+
+ WARN_ON(clk->usecount < 0);
if (clk->flags & CLK_ALWAYS_ENABLED)
return;
- if (!count) { /* count reaches zero, disable the clock */
+ if (clk->usecount == 0) {
if (likely(clk->ops && clk->ops->disable))
clk->ops->disable(clk);
+
+ __clk_disable(clk->parent);
}
}
@@ -154,14 +166,9 @@ void clk_disable(struct clk *clk)
{
unsigned long flags;
- if (!clk)
- return;
-
spin_lock_irqsave(&clock_lock, flags);
__clk_disable(clk);
spin_unlock_irqrestore(&clock_lock, flags);
-
- clk_disable(clk->parent);
}
EXPORT_SYMBOL_GPL(clk_disable);
@@ -170,14 +177,14 @@ int clk_register(struct clk *clk)
mutex_lock(&clock_list_sem);
list_add(&clk->node, &clock_list);
- kref_init(&clk->kref);
+ clk->usecount = 0;
+ clk->flags |= CLK_NEEDS_INIT;
mutex_unlock(&clock_list_sem);
if (clk->flags & CLK_ALWAYS_ENABLED) {
+ __clk_init(clk);
pr_debug( "Clock '%s' is ALWAYS_ENABLED\n", clk->name);
- if (clk->ops && clk->ops->init)
- clk->ops->init(clk);
if (clk->ops && clk->ops->enable)
clk->ops->enable(clk);
pr_debug( "Enabled.");
@@ -353,7 +360,7 @@ static int show_clocks(char *buf, char **start, off_t off,
p += sprintf(p, "%-12s\t: %ld.%02ldMHz\t%s\n", clk->name,
rate / 1000000, (rate % 1000000) / 10000,
((clk->flags & CLK_ALWAYS_ENABLED) ||
- (atomic_read(&clk->kref.refcount) != 1)) ?
+ clk->usecount > 0) ?
"enabled" : "disabled");
}
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c
index 301b505c4278..f43753b54e1d 100644
--- a/arch/sh/kernel/cpu/irq/imask.c
+++ b/arch/sh/kernel/cpu/irq/imask.c
@@ -39,7 +39,7 @@ static unsigned int startup_imask_irq(unsigned int irq)
return 0; /* never anything pending */
}
-static struct hw_interrupt_type imask_irq_type = {
+static struct irq_chip imask_irq_type = {
.typename = "SR.IMASK",
.startup = startup_imask_irq,
.shutdown = shutdown_imask_irq,
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index 726f0335da76..a619eaf6e6b4 100644
--- a/arch/sh/kernel/cpu/irq/intc-sh5.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -84,7 +84,7 @@ static void disable_intc_irq(unsigned int irq);
static void mask_and_ack_intc(unsigned int);
static void end_intc_irq(unsigned int irq);
-static struct hw_interrupt_type intc_irq_type = {
+static struct irq_chip intc_irq_type = {
.typename = "INTC",
.startup = startup_intc_irq,
.shutdown = shutdown_intc_irq,
@@ -160,35 +160,13 @@ void make_intc_irq(unsigned int irq)
disable_intc_irq(irq);
}
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
-static int IRQ_to_vectorN[NR_INTC_IRQS] = {
- 0x12, 0x15, 0x18, 0x1B, 0x40, 0x41, 0x42, 0x43, /* 0- 7 */
- -1, -1, -1, -1, 0x50, 0x51, 0x52, 0x53, /* 8-15 */
- 0x54, 0x55, 0x32, 0x33, 0x34, 0x35, 0x36, -1, /* 16-23 */
- -1, -1, -1, -1, -1, -1, -1, -1, /* 24-31 */
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x38, /* 32-39 */
- 0x39, 0x3A, 0x3B, -1, -1, -1, -1, -1, /* 40-47 */
- -1, -1, -1, -1, -1, -1, -1, -1, /* 48-55 */
- -1, -1, -1, -1, -1, -1, -1, 0x2B, /* 56-63 */
-
-};
-
-int intc_irq_describe(char* p, int irq)
-{
- if (irq < NR_INTC_IRQS)
- return sprintf(p, "(0x%3x)", IRQ_to_vectorN[irq]*0x20);
- else
- return 0;
-}
-#endif
-
void __init plat_irq_setup(void)
{
unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
unsigned long reg;
int i;
- intc_virt = onchip_remap(INTC_BASE, 1024, "INTC");
+ intc_virt = (unsigned long)ioremap_nocache(INTC_BASE, 1024);
if (!intc_virt) {
panic("Unable to remap INTC\n");
}
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index 0e32d8e448ca..94ac27fc2237 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -12,6 +12,8 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <linux/io.h>
enum {
UNUSED = 0,
@@ -109,9 +111,75 @@ static struct platform_device eth_device = {
.resource = eth_resources,
};
+static struct sh_timer_config cmt0_platform_data = {
+ .name = "CMT0",
+ .channel_offset = 0x02,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 125,
+ .clocksource_rating = 0, /* disabled due to code generation issues */
+};
+
+static struct resource cmt0_resources[] = {
+ [0] = {
+ .name = "CMT0",
+ .start = 0xf84a0072,
+ .end = 0xf84a0077,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 86,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt0_device = {
+ .name = "sh_cmt",
+ .id = 0,
+ .dev = {
+ .platform_data = &cmt0_platform_data,
+ },
+ .resource = cmt0_resources,
+ .num_resources = ARRAY_SIZE(cmt0_resources),
+};
+
+static struct sh_timer_config cmt1_platform_data = {
+ .name = "CMT1",
+ .channel_offset = 0x08,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clockevent_rating = 125,
+ .clocksource_rating = 0, /* disabled due to code generation issues */
+};
+
+static struct resource cmt1_resources[] = {
+ [0] = {
+ .name = "CMT1",
+ .start = 0xf84a0078,
+ .end = 0xf84a007d,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 87,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt1_device = {
+ .name = "sh_cmt",
+ .id = 1,
+ .dev = {
+ .platform_data = &cmt1_platform_data,
+ },
+ .resource = cmt1_resources,
+ .num_resources = ARRAY_SIZE(cmt1_resources),
+};
+
static struct platform_device *sh7619_devices[] __initdata = {
&sci_device,
&eth_device,
+ &cmt0_device,
+ &cmt1_device,
};
static int __init sh7619_devices_setup(void)
@@ -125,3 +193,19 @@ void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
+
+static struct platform_device *sh7619_early_devices[] __initdata = {
+ &cmt0_device,
+ &cmt1_device,
+};
+
+#define STBCR3 0xf80a0000
+
+void __init plat_early_device_setup(void)
+{
+ /* enable CMT clock */
+ __raw_writeb(__raw_readb(STBCR3) & ~0x10, STBCR3);
+
+ early_platform_add_devices(sh7619_early_devices,
+ ARRAY_SIZE(sh7619_early_devices));
+}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
index 844293723cfc..a452d9649069 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
enum {
UNUSED = 0,
@@ -24,7 +25,7 @@ enum {
SCIF0, SCIF1,
- MTU2_GROUP1, MTU2_GROUP2, MTU2_GROUP3, MTU2_GROUP4, MTU2_GROUP5
+ MTU2_GROUP1, MTU2_GROUP2, MTU2_GROUP3, MTU2_GROUP4, MTU2_GROUP5,
MTU2_TGI3B, MTU2_TGI3C,
/* interrupt groups */
@@ -113,6 +114,99 @@ static struct intc_mask_reg mask_registers[] __initdata = {
static DECLARE_INTC_DESC(intc_desc, "mxg", vectors, groups,
mask_registers, prio_registers, NULL);
+static struct sh_timer_config mtu2_0_platform_data = {
+ .name = "MTU2_0",
+ .channel_offset = -0x80,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_0_resources[] = {
+ [0] = {
+ .name = "MTU2_0",
+ .start = 0xff801300,
+ .end = 0xff801326,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 228,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_0_device = {
+ .name = "sh_mtu2",
+ .id = 0,
+ .dev = {
+ .platform_data = &mtu2_0_platform_data,
+ },
+ .resource = mtu2_0_resources,
+ .num_resources = ARRAY_SIZE(mtu2_0_resources),
+};
+
+static struct sh_timer_config mtu2_1_platform_data = {
+ .name = "MTU2_1",
+ .channel_offset = -0x100,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_1_resources[] = {
+ [0] = {
+ .name = "MTU2_1",
+ .start = 0xff801380,
+ .end = 0xff801390,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 234,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_1_device = {
+ .name = "sh_mtu2",
+ .id = 1,
+ .dev = {
+ .platform_data = &mtu2_1_platform_data,
+ },
+ .resource = mtu2_1_resources,
+ .num_resources = ARRAY_SIZE(mtu2_1_resources),
+};
+
+static struct sh_timer_config mtu2_2_platform_data = {
+ .name = "MTU2_2",
+ .channel_offset = 0x80,
+ .timer_bit = 2,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_2_resources[] = {
+ [0] = {
+ .name = "MTU2_2",
+ .start = 0xff801000,
+ .end = 0xff80100a,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 240,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_2_device = {
+ .name = "sh_mtu2",
+ .id = 2,
+ .dev = {
+ .platform_data = &mtu2_2_platform_data,
+ },
+ .resource = mtu2_2_resources,
+ .num_resources = ARRAY_SIZE(mtu2_2_resources),
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xff804000,
@@ -134,6 +228,9 @@ static struct platform_device sci_device = {
static struct platform_device *mxg_devices[] __initdata = {
&sci_device,
+ &mtu2_0_device,
+ &mtu2_1_device,
+ &mtu2_2_device,
};
static int __init mxg_devices_setup(void)
@@ -147,3 +244,15 @@ void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
+
+static struct platform_device *mxg_early_devices[] __initdata = {
+ &mtu2_0_device,
+ &mtu2_1_device,
+ &mtu2_2_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(mxg_early_devices,
+ ARRAY_SIZE(mxg_early_devices));
+}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
index 00f42f9e3f5c..772358b7685e 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
@@ -12,6 +12,8 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <linux/io.h>
enum {
UNUSED = 0,
@@ -249,9 +251,105 @@ static struct platform_device rtc_device = {
.resource = rtc_resources,
};
+static struct sh_timer_config mtu2_0_platform_data = {
+ .name = "MTU2_0",
+ .channel_offset = -0x80,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_0_resources[] = {
+ [0] = {
+ .name = "MTU2_0",
+ .start = 0xfffe4300,
+ .end = 0xfffe4326,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 108,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_0_device = {
+ .name = "sh_mtu2",
+ .id = 0,
+ .dev = {
+ .platform_data = &mtu2_0_platform_data,
+ },
+ .resource = mtu2_0_resources,
+ .num_resources = ARRAY_SIZE(mtu2_0_resources),
+};
+
+static struct sh_timer_config mtu2_1_platform_data = {
+ .name = "MTU2_1",
+ .channel_offset = -0x100,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_1_resources[] = {
+ [0] = {
+ .name = "MTU2_1",
+ .start = 0xfffe4380,
+ .end = 0xfffe4390,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 116,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_1_device = {
+ .name = "sh_mtu2",
+ .id = 1,
+ .dev = {
+ .platform_data = &mtu2_1_platform_data,
+ },
+ .resource = mtu2_1_resources,
+ .num_resources = ARRAY_SIZE(mtu2_1_resources),
+};
+
+static struct sh_timer_config mtu2_2_platform_data = {
+ .name = "MTU2_2",
+ .channel_offset = 0x80,
+ .timer_bit = 2,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_2_resources[] = {
+ [0] = {
+ .name = "MTU2_2",
+ .start = 0xfffe4000,
+ .end = 0xfffe400a,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 124,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_2_device = {
+ .name = "sh_mtu2",
+ .id = 2,
+ .dev = {
+ .platform_data = &mtu2_2_platform_data,
+ },
+ .resource = mtu2_2_resources,
+ .num_resources = ARRAY_SIZE(mtu2_2_resources),
+};
+
static struct platform_device *sh7201_devices[] __initdata = {
&sci_device,
&rtc_device,
+ &mtu2_0_device,
+ &mtu2_1_device,
+ &mtu2_2_device,
};
static int __init sh7201_devices_setup(void)
@@ -265,3 +363,20 @@ void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
+
+static struct platform_device *sh7201_early_devices[] __initdata = {
+ &mtu2_0_device,
+ &mtu2_1_device,
+ &mtu2_2_device,
+};
+
+#define STBCR3 0xfffe0408
+
+void __init plat_early_device_setup(void)
+{
+ /* enable MTU2 clock */
+ __raw_writeb(__raw_readb(STBCR3) & ~0x20, STBCR3);
+
+ early_platform_add_devices(sh7201_early_devices,
+ ARRAY_SIZE(sh7201_early_devices));
+}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index 820dfb2e8656..d7493418ba60 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -11,6 +11,8 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <linux/io.h>
enum {
UNUSED = 0,
@@ -205,6 +207,132 @@ static struct platform_device sci_device = {
},
};
+static struct sh_timer_config cmt0_platform_data = {
+ .name = "CMT0",
+ .channel_offset = 0x02,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 125,
+ .clocksource_rating = 0, /* disabled due to code generation issues */
+};
+
+static struct resource cmt0_resources[] = {
+ [0] = {
+ .name = "CMT0",
+ .start = 0xfffec002,
+ .end = 0xfffec007,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 142,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt0_device = {
+ .name = "sh_cmt",
+ .id = 0,
+ .dev = {
+ .platform_data = &cmt0_platform_data,
+ },
+ .resource = cmt0_resources,
+ .num_resources = ARRAY_SIZE(cmt0_resources),
+};
+
+static struct sh_timer_config cmt1_platform_data = {
+ .name = "CMT1",
+ .channel_offset = 0x08,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clockevent_rating = 125,
+ .clocksource_rating = 0, /* disabled due to code generation issues */
+};
+
+static struct resource cmt1_resources[] = {
+ [0] = {
+ .name = "CMT1",
+ .start = 0xfffec008,
+ .end = 0xfffec00d,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 143,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt1_device = {
+ .name = "sh_cmt",
+ .id = 1,
+ .dev = {
+ .platform_data = &cmt1_platform_data,
+ },
+ .resource = cmt1_resources,
+ .num_resources = ARRAY_SIZE(cmt1_resources),
+};
+
+static struct sh_timer_config mtu2_0_platform_data = {
+ .name = "MTU2_0",
+ .channel_offset = -0x80,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_0_resources[] = {
+ [0] = {
+ .name = "MTU2_0",
+ .start = 0xfffe4300,
+ .end = 0xfffe4326,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 146,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_0_device = {
+ .name = "sh_mtu2",
+ .id = 0,
+ .dev = {
+ .platform_data = &mtu2_0_platform_data,
+ },
+ .resource = mtu2_0_resources,
+ .num_resources = ARRAY_SIZE(mtu2_0_resources),
+};
+
+static struct sh_timer_config mtu2_1_platform_data = {
+ .name = "MTU2_1",
+ .channel_offset = -0x100,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_1_resources[] = {
+ [0] = {
+ .name = "MTU2_1",
+ .start = 0xfffe4380,
+ .end = 0xfffe4390,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 153,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_1_device = {
+ .name = "sh_mtu2",
+ .id = 1,
+ .dev = {
+ .platform_data = &mtu2_1_platform_data,
+ },
+ .resource = mtu2_1_resources,
+ .num_resources = ARRAY_SIZE(mtu2_1_resources),
+};
+
static struct resource rtc_resources[] = {
[0] = {
.start = 0xffff2000,
@@ -227,6 +355,10 @@ static struct platform_device rtc_device = {
static struct platform_device *sh7203_devices[] __initdata = {
&sci_device,
+ &cmt0_device,
+ &cmt1_device,
+ &mtu2_0_device,
+ &mtu2_1_device,
&rtc_device,
};
@@ -241,3 +373,25 @@ void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
+
+static struct platform_device *sh7203_early_devices[] __initdata = {
+ &cmt0_device,
+ &cmt1_device,
+ &mtu2_0_device,
+ &mtu2_1_device,
+};
+
+#define STBCR3 0xfffe0408
+#define STBCR4 0xfffe040c
+
+void __init plat_early_device_setup(void)
+{
+ /* enable CMT clock */
+ __raw_writeb(__raw_readb(STBCR4) & ~0x04, STBCR4);
+
+ /* enable MTU2 clock */
+ __raw_writeb(__raw_readb(STBCR3) & ~0x20, STBCR3);
+
+ early_platform_add_devices(sh7203_early_devices,
+ ARRAY_SIZE(sh7203_early_devices));
+}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index c46a8355726d..2fc6bff5c5fb 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -12,6 +12,8 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <linux/io.h>
enum {
UNUSED = 0,
@@ -165,8 +167,170 @@ static struct platform_device sci_device = {
},
};
+static struct sh_timer_config cmt0_platform_data = {
+ .name = "CMT0",
+ .channel_offset = 0x02,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 125,
+ .clocksource_rating = 0, /* disabled due to code generation issues */
+};
+
+static struct resource cmt0_resources[] = {
+ [0] = {
+ .name = "CMT0",
+ .start = 0xfffec002,
+ .end = 0xfffec007,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 140,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt0_device = {
+ .name = "sh_cmt",
+ .id = 0,
+ .dev = {
+ .platform_data = &cmt0_platform_data,
+ },
+ .resource = cmt0_resources,
+ .num_resources = ARRAY_SIZE(cmt0_resources),
+};
+
+static struct sh_timer_config cmt1_platform_data = {
+ .name = "CMT1",
+ .channel_offset = 0x08,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clockevent_rating = 125,
+ .clocksource_rating = 0, /* disabled due to code generation issues */
+};
+
+static struct resource cmt1_resources[] = {
+ [0] = {
+ .name = "CMT1",
+ .start = 0xfffec008,
+ .end = 0xfffec00d,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 144,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt1_device = {
+ .name = "sh_cmt",
+ .id = 1,
+ .dev = {
+ .platform_data = &cmt1_platform_data,
+ },
+ .resource = cmt1_resources,
+ .num_resources = ARRAY_SIZE(cmt1_resources),
+};
+
+static struct sh_timer_config mtu2_0_platform_data = {
+ .name = "MTU2_0",
+ .channel_offset = -0x80,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_0_resources[] = {
+ [0] = {
+ .name = "MTU2_0",
+ .start = 0xfffe4300,
+ .end = 0xfffe4326,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 156,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_0_device = {
+ .name = "sh_mtu2",
+ .id = 0,
+ .dev = {
+ .platform_data = &mtu2_0_platform_data,
+ },
+ .resource = mtu2_0_resources,
+ .num_resources = ARRAY_SIZE(mtu2_0_resources),
+};
+
+static struct sh_timer_config mtu2_1_platform_data = {
+ .name = "MTU2_1",
+ .channel_offset = -0x100,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_1_resources[] = {
+ [0] = {
+ .name = "MTU2_1",
+ .start = 0xfffe4380,
+ .end = 0xfffe4390,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 164,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_1_device = {
+ .name = "sh_mtu2",
+ .id = 1,
+ .dev = {
+ .platform_data = &mtu2_1_platform_data,
+ },
+ .resource = mtu2_1_resources,
+ .num_resources = ARRAY_SIZE(mtu2_1_resources),
+};
+
+static struct sh_timer_config mtu2_2_platform_data = {
+ .name = "MTU2_2",
+ .channel_offset = 0x80,
+ .timer_bit = 2,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource mtu2_2_resources[] = {
+ [0] = {
+ .name = "MTU2_2",
+ .start = 0xfffe4000,
+ .end = 0xfffe400a,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 180,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mtu2_2_device = {
+ .name = "sh_mtu2",
+ .id = 2,
+ .dev = {
+ .platform_data = &mtu2_2_platform_data,
+ },
+ .resource = mtu2_2_resources,
+ .num_resources = ARRAY_SIZE(mtu2_2_resources),
+};
+
static struct platform_device *sh7206_devices[] __initdata = {
&sci_device,
+ &cmt0_device,
+ &cmt1_device,
+ &mtu2_0_device,
+ &mtu2_1_device,
+ &mtu2_2_device,
};
static int __init sh7206_devices_setup(void)
@@ -180,3 +344,26 @@ void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
+
+static struct platform_device *sh7206_early_devices[] __initdata = {
+ &cmt0_device,
+ &cmt1_device,
+ &mtu2_0_device,
+ &mtu2_1_device,
+ &mtu2_2_device,
+};
+
+#define STBCR3 0xfffe0408
+#define STBCR4 0xfffe040c
+
+void __init plat_early_device_setup(void)
+{
+ /* enable CMT clock */
+ __raw_writeb(__raw_readb(STBCR4) & ~0x04, STBCR4);
+
+ /* enable MTU2 clock */
+ __raw_writeb(__raw_readb(STBCR3) & ~0x20, STBCR3);
+
+ early_platform_add_devices(sh7206_early_devices,
+ ARRAY_SIZE(sh7206_early_devices));
+}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index 63b67badd67e..39513664d5d7 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -13,6 +13,7 @@
#include <linux/irq.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
#include <asm/rtc.h>
enum {
@@ -116,7 +117,102 @@ static struct platform_device rtc_device = {
},
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x02,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xfffffe94,
+ .end = 0xfffffe9f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0xe,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xfffffea0,
+ .end = 0xfffffeab,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1a,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xfffffeac,
+ .end = 0xfffffebb,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
static struct platform_device *sh7705_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
&sci_device,
&rtc_device,
};
@@ -128,6 +224,18 @@ static int __init sh7705_devices_setup(void)
}
__initcall(sh7705_devices_setup);
+static struct platform_device *sh7705_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7705_early_devices,
+ ARRAY_SIZE(sh7705_early_devices));
+}
+
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index a74f960b5e79..9412d915b84e 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -18,6 +18,7 @@
#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
enum {
UNUSED = 0,
@@ -144,7 +145,102 @@ static struct platform_device sci_device = {
},
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x02,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xfffffe94,
+ .end = 0xfffffe9f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0xe,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xfffffea0,
+ .end = 0xfffffeab,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1a,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xfffffeac,
+ .end = 0xfffffebb,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
static struct platform_device *sh770x_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
&sci_device,
&rtc_device,
};
@@ -156,6 +252,18 @@ static int __init sh770x_devices_setup(void)
}
__initcall(sh770x_devices_setup);
+static struct platform_device *sh770x_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh770x_early_devices,
+ ARRAY_SIZE(sh770x_early_devices));
+}
+
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 335098b66e2f..07ff38d055a7 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -13,6 +13,7 @@
#include <linux/irq.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
#include <asm/rtc.h>
enum {
@@ -120,7 +121,102 @@ static struct platform_device sci_device = {
},
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x02,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xa412fe94,
+ .end = 0xa412fe9f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0xe,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xa412fea0,
+ .end = 0xa412feab,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1a,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xa412feac,
+ .end = 0xa412feb5,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
static struct platform_device *sh7710_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
&sci_device,
&rtc_device,
};
@@ -132,6 +228,18 @@ static int __init sh7710_devices_setup(void)
}
__initcall(sh7710_devices_setup);
+static struct platform_device *sh7710_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7710_early_devices,
+ ARRAY_SIZE(sh7710_early_devices));
+}
+
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 003874a2fd2a..d8b46f5dff60 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -18,6 +18,7 @@
#include <linux/serial.h>
#include <linux/io.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
#include <asm/rtc.h>
static struct resource rtc_resources[] = {
@@ -123,7 +124,259 @@ static struct platform_device usbf_device = {
.resource = usbf_resources,
};
+static struct sh_timer_config cmt0_platform_data = {
+ .name = "CMT0",
+ .channel_offset = 0x10,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 125,
+ .clocksource_rating = 125,
+};
+
+static struct resource cmt0_resources[] = {
+ [0] = {
+ .name = "CMT0",
+ .start = 0x044a0010,
+ .end = 0x044a001b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 104,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt0_device = {
+ .name = "sh_cmt",
+ .id = 0,
+ .dev = {
+ .platform_data = &cmt0_platform_data,
+ },
+ .resource = cmt0_resources,
+ .num_resources = ARRAY_SIZE(cmt0_resources),
+};
+
+static struct sh_timer_config cmt1_platform_data = {
+ .name = "CMT1",
+ .channel_offset = 0x20,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource cmt1_resources[] = {
+ [0] = {
+ .name = "CMT1",
+ .start = 0x044a0020,
+ .end = 0x044a002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 104,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt1_device = {
+ .name = "sh_cmt",
+ .id = 1,
+ .dev = {
+ .platform_data = &cmt1_platform_data,
+ },
+ .resource = cmt1_resources,
+ .num_resources = ARRAY_SIZE(cmt1_resources),
+};
+
+static struct sh_timer_config cmt2_platform_data = {
+ .name = "CMT2",
+ .channel_offset = 0x30,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource cmt2_resources[] = {
+ [0] = {
+ .name = "CMT2",
+ .start = 0x044a0030,
+ .end = 0x044a003b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 104,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt2_device = {
+ .name = "sh_cmt",
+ .id = 2,
+ .dev = {
+ .platform_data = &cmt2_platform_data,
+ },
+ .resource = cmt2_resources,
+ .num_resources = ARRAY_SIZE(cmt2_resources),
+};
+
+static struct sh_timer_config cmt3_platform_data = {
+ .name = "CMT3",
+ .channel_offset = 0x40,
+ .timer_bit = 3,
+ .clk = "module_clk",
+};
+
+static struct resource cmt3_resources[] = {
+ [0] = {
+ .name = "CMT3",
+ .start = 0x044a0040,
+ .end = 0x044a004b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 104,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt3_device = {
+ .name = "sh_cmt",
+ .id = 3,
+ .dev = {
+ .platform_data = &cmt3_platform_data,
+ },
+ .resource = cmt3_resources,
+ .num_resources = ARRAY_SIZE(cmt3_resources),
+};
+
+static struct sh_timer_config cmt4_platform_data = {
+ .name = "CMT4",
+ .channel_offset = 0x50,
+ .timer_bit = 4,
+ .clk = "module_clk",
+};
+
+static struct resource cmt4_resources[] = {
+ [0] = {
+ .name = "CMT4",
+ .start = 0x044a0050,
+ .end = 0x044a005b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 104,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt4_device = {
+ .name = "sh_cmt",
+ .id = 4,
+ .dev = {
+ .platform_data = &cmt4_platform_data,
+ },
+ .resource = cmt4_resources,
+ .num_resources = ARRAY_SIZE(cmt4_resources),
+};
+
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x02,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xa412fe94,
+ .end = 0xa412fe9f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0xe,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xa412fea0,
+ .end = 0xa412feab,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1a,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xa412feac,
+ .end = 0xa412feb5,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
static struct platform_device *sh7720_devices[] __initdata = {
+ &cmt0_device,
+ &cmt1_device,
+ &cmt2_device,
+ &cmt3_device,
+ &cmt4_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
&rtc_device,
&sci_device,
&usb_ohci_device,
@@ -137,6 +390,23 @@ static int __init sh7720_devices_setup(void)
}
__initcall(sh7720_devices_setup);
+static struct platform_device *sh7720_early_devices[] __initdata = {
+ &cmt0_device,
+ &cmt1_device,
+ &cmt2_device,
+ &cmt3_device,
+ &cmt4_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7720_early_devices,
+ ARRAY_SIZE(sh7720_early_devices));
+}
+
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 91e3677ae09d..973ff831c8a8 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -156,6 +156,12 @@ int __init detect_cpu_and_cache_system(void)
break;
}
break;
+ case 0x300b:
+ boot_cpu_data.type = CPU_SH7724;
+ boot_cpu_data.icache.ways = 4;
+ boot_cpu_data.dcache.ways = 4;
+ boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_FPU;
+ break;
case 0x4000: /* 1st cut */
case 0x4001: /* 2nd cut */
boot_cpu_data.type = CPU_SHX3;
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
index 7371abf64f80..be79fa136255 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
@@ -2,6 +2,7 @@
* SH4-202 Setup
*
* Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2009 Magnus Damm
*
* 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
@@ -11,6 +12,8 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <linux/io.h>
static struct plat_sci_port sci_platform_data[] = {
{
@@ -31,8 +34,103 @@ static struct platform_device sci_device = {
},
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
static struct platform_device *sh4202_devices[] __initdata = {
&sci_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
};
static int __init sh4202_devices_setup(void)
@@ -42,7 +140,71 @@ static int __init sh4202_devices_setup(void)
}
__initcall(sh4202_devices_setup);
+static struct platform_device *sh4202_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh4202_early_devices,
+ ARRAY_SIZE(sh4202_early_devices));
+}
+
+enum {
+ UNUSED = 0,
+
+ /* interrupt sources */
+ IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
+ HUDI, TMU0, TMU1, TMU2, RTC, SCIF, WDT,
+};
+
+static struct intc_vect vectors[] __initdata = {
+ INTC_VECT(HUDI, 0x600),
+ INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
+ INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460),
+ INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+ INTC_VECT(RTC, 0x4c0),
+ INTC_VECT(SCIF, 0x700), INTC_VECT(SCIF, 0x720),
+ INTC_VECT(SCIF, 0x740), INTC_VECT(SCIF, 0x760),
+ INTC_VECT(WDT, 0x560),
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+ { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
+ { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, 0, 0, 0 } },
+ { 0xffd0000c, 0, 16, 4, /* IPRC */ { 0, 0, SCIF, HUDI } },
+ { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
+};
+
+static DECLARE_INTC_DESC(intc_desc, "sh4-202", vectors, NULL,
+ NULL, prio_registers, NULL);
+
+static struct intc_vect vectors_irlm[] __initdata = {
+ INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
+ INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
+};
+
+static DECLARE_INTC_DESC(intc_desc_irlm, "sh4-202_irlm", vectors_irlm, NULL,
+ NULL, prio_registers, NULL);
+
void __init plat_irq_setup(void)
{
- /* do nothing - all IRL interrupts are handled by the board code */
+ register_intc_controller(&intc_desc);
+}
+
+#define INTC_ICR 0xffd00000UL
+#define INTC_ICR_IRLM (1<<7)
+
+void __init plat_irq_setup_pins(int mode)
+{
+ switch (mode) {
+ case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
+ ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
+ register_intc_controller(&intc_desc_irlm);
+ break;
+ default:
+ BUG();
+ }
}
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index a1c80d909cd6..09da0c187d4c 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/io.h>
+#include <linux/sh_timer.h>
#include <linux/serial_sci.h>
static struct resource rtc_resources[] = {
@@ -60,9 +61,177 @@ static struct platform_device sci_device = {
},
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+/* SH7750R, SH7751 and SH7751R all have two extra timer channels */
+#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751R)
+
+static struct sh_timer_config tmu3_platform_data = {
+ .name = "TMU3",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+};
+
+static struct resource tmu3_resources[] = {
+ [0] = {
+ .name = "TMU3",
+ .start = 0xfe100008,
+ .end = 0xfe100013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 72,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu3_device = {
+ .name = "sh_tmu",
+ .id = 3,
+ .dev = {
+ .platform_data = &tmu3_platform_data,
+ },
+ .resource = tmu3_resources,
+ .num_resources = ARRAY_SIZE(tmu3_resources),
+};
+
+static struct sh_timer_config tmu4_platform_data = {
+ .name = "TMU4",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource tmu4_resources[] = {
+ [0] = {
+ .name = "TMU4",
+ .start = 0xfe100014,
+ .end = 0xfe10001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 76,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu4_device = {
+ .name = "sh_tmu",
+ .id = 4,
+ .dev = {
+ .platform_data = &tmu4_platform_data,
+ },
+ .resource = tmu4_resources,
+ .num_resources = ARRAY_SIZE(tmu4_resources),
+};
+
+#endif
+
static struct platform_device *sh7750_devices[] __initdata = {
&rtc_device,
&sci_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751R)
+ &tmu3_device,
+ &tmu4_device,
+#endif
};
static int __init sh7750_devices_setup(void)
@@ -72,6 +241,24 @@ static int __init sh7750_devices_setup(void)
}
__initcall(sh7750_devices_setup);
+static struct platform_device *sh7750_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751R)
+ &tmu3_device,
+ &tmu4_device,
+#endif
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7750_early_devices,
+ ARRAY_SIZE(sh7750_early_devices));
+}
+
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index d9bdc931ac09..cd097335758f 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -10,6 +10,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
+#include <linux/sh_timer.h>
#include <linux/serial_sci.h>
#include <linux/io.h>
@@ -18,10 +19,7 @@ enum {
/* interrupt sources */
IRL0, IRL1, IRL2, IRL3,
- HUDI, GPIOI,
- DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
- DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
- DMAC_DMAE,
+ HUDI, GPIOI, DMAC,
IRQ4, IRQ5, IRQ6, IRQ7,
HCAN20, HCAN21,
SSI0, SSI1,
@@ -36,21 +34,20 @@ enum {
HSPI,
MMCIF0, MMCIF1, MMCIF2, MMCIF3,
MFI, ADC, CMT,
- TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
- WDT,
- REF_RCMI, REF_ROVI,
+ TMU0, TMU1, TMU2,
+ WDT, REF,
/* interrupt groups */
- DMAC, DMABRG, SCIF0, SCIF1, SCIF2, SIM, MMCIF, TMU2, REF,
+ DMABRG, SCIF0, SCIF1, SCIF2, SIM, MMCIF,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
- INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
- INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
- INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
- INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0),
- INTC_VECT(DMAC_DMAE, 0x6c0),
+ INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
+ INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
+ INTC_VECT(DMAC, 0x780), INTC_VECT(DMAC, 0x7a0),
+ INTC_VECT(DMAC, 0x7c0), INTC_VECT(DMAC, 0x7e0),
+ INTC_VECT(DMAC, 0x6c0),
INTC_VECT(IRQ4, 0x800), INTC_VECT(IRQ5, 0x820),
INTC_VECT(IRQ6, 0x840), INTC_VECT(IRQ6, 0x860),
INTC_VECT(HCAN20, 0x900), INTC_VECT(HCAN21, 0x920),
@@ -74,23 +71,18 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(MFI, 0xe80), /* 0xf80 according to data sheet */
INTC_VECT(ADC, 0xf80), INTC_VECT(CMT, 0xfa0),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
- INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
+ INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460),
INTC_VECT(WDT, 0x560),
- INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
+ INTC_VECT(REF, 0x580), INTC_VECT(REF, 0x5a0),
};
static struct intc_group groups[] __initdata = {
- INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
- DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
- DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
INTC_GROUP(DMABRG, DMABRG0, DMABRG1, DMABRG2),
INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI),
INTC_GROUP(MMCIF, MMCIF0, MMCIF1, MMCIF2, MMCIF3),
- INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
- INTC_GROUP(REF, REF_RCMI, REF_ROVI),
};
static struct intc_mask_reg mask_registers[] __initdata = {
@@ -168,8 +160,104 @@ static struct platform_device sci_device = {
},
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+
static struct platform_device *sh7760_devices[] __initdata = {
&sci_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
};
static int __init sh7760_devices_setup(void)
@@ -179,6 +267,18 @@ static int __init sh7760_devices_setup(void)
}
__initcall(sh7760_devices_setup);
+static struct platform_device *sh7760_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7760_early_devices,
+ ARRAY_SIZE(sh7760_early_devices));
+}
+
#define INTC_ICR 0xffd00000UL
#define INTC_ICR_IRLM (1 << 7)
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index 1a92361feeb9..afd6fba47849 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7786) += setup-sh7786.o
obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7724) += setup-sh7724.o
obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o
obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o
@@ -26,12 +27,14 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7786) := clock-sh7786.o
clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7722.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o
# Pinmux setup
pinmux-$(CONFIG_CPU_SUBTYPE_SH7722) := pinmux-sh7722.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7723) := pinmux-sh7723.o
+pinmux-$(CONFIG_CPU_SUBTYPE_SH7724) := pinmux-sh7724.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index 0e174af21874..1ccdfc561fef 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -130,6 +130,12 @@ static void adjust_clocks(int originate, int *l, unsigned long v[],
* is quite simple..
*/
+#if defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define STCPLL(frqcr) ((((frqcr >> 24) & 0x3f) + 1) * 2)
+#else
+#define STCPLL(frqcr) (((frqcr >> 24) & 0x1f) + 1)
+#endif
+
/*
* Instead of having two separate multipliers/divisors set, like this:
*
@@ -139,13 +145,17 @@ static void adjust_clocks(int originate, int *l, unsigned long v[],
* I created the divisors2 array, which is used to calculate rate like
* rate = parent * 2 / divisors2[ divisor ];
*/
+#if defined(CONFIG_CPU_SUBTYPE_SH7724)
+static int divisors2[] = { 4, 1, 8, 12, 16, 24, 32, 1, 48, 64, 72, 96, 1, 144 };
+#else
static int divisors2[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40 };
+#endif
static void master_clk_recalc(struct clk *clk)
{
unsigned frqcr = ctrl_inl(FRQCR);
- clk->rate = CONFIG_SH_PCLK_FREQ * (((frqcr >> 24) & 0x1f) + 1);
+ clk->rate = CONFIG_SH_PCLK_FREQ * STCPLL(frqcr);
}
static void master_clk_init(struct clk *clk)
@@ -161,13 +171,30 @@ static void module_clk_recalc(struct clk *clk)
{
unsigned long frqcr = ctrl_inl(FRQCR);
- clk->rate = clk->parent->rate / (((frqcr >> 24) & 0x1f) + 1);
+ clk->rate = clk->parent->rate / STCPLL(frqcr);
}
+#if defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define MASTERDIVS { 12, 16, 24, 30, 32, 36, 48 }
+#define STCMASK 0x3f
+#define DIVCALC(div) (div/2-1)
+#define FRQCRKICK 0x80000000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#define MASTERDIVS { 6, 8, 12, 16 }
+#define STCMASK 0x1f
+#define DIVCALC(div) (div-1)
+#define FRQCRKICK 0x00000000
+#else
+#define MASTERDIVS { 2, 3, 4, 6, 8, 16 }
+#define STCMASK 0x1f
+#define DIVCALC(div) (div-1)
+#define FRQCRKICK 0x00000000
+#endif
+
static int master_clk_setrate(struct clk *clk, unsigned long rate, int id)
{
int div = rate / clk->rate;
- int master_divs[] = { 2, 3, 4, 6, 8, 16 };
+ int master_divs[] = MASTERDIVS;
int index;
unsigned long frqcr;
@@ -180,8 +207,9 @@ static int master_clk_setrate(struct clk *clk, unsigned long rate, int id)
div = master_divs[index - 1];
frqcr = ctrl_inl(FRQCR);
- frqcr &= ~(0xF << 24);
- frqcr |= ( (div-1) << 24);
+ frqcr &= ~(STCMASK << 24);
+ frqcr |= (DIVCALC(div) << 24);
+ frqcr |= FRQCRKICK;
ctrl_outl(frqcr, FRQCR);
return 0;
@@ -377,6 +405,7 @@ static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate,
/* clear FRQCR bits */
frqcr &= ~(ctx.mask << ctx.shift);
frqcr |= div << ctx.shift;
+ frqcr |= FRQCRKICK;
/* ...and perform actual change */
ctrl_outl(frqcr, FRQCR);
@@ -542,8 +571,8 @@ static struct clk sh7722_r_clock = {
.flags = CLK_RATE_PROPAGATES,
};
-#ifndef CONFIG_CPU_SUBTYPE_SH7343
-
+#if !defined(CONFIG_CPU_SUBTYPE_SH7343) &&\
+ !defined(CONFIG_CPU_SUBTYPE_SH7724)
/*
* these three clocks - SIU A, SIU B, IrDA - share the same clk_ops
* methods of clk_ops determine which register they should access by
@@ -560,15 +589,16 @@ static struct clk sh7722_siu_b_clock = {
.arch_flags = SCLKBCR,
.ops = &sh7722_siu_clk_ops,
};
+#endif /* CONFIG_CPU_SUBTYPE_SH7343, SH7724 */
-#if defined(CONFIG_CPU_SUBTYPE_SH7722)
+#if defined(CONFIG_CPU_SUBTYPE_SH7722) ||\
+ defined(CONFIG_CPU_SUBTYPE_SH7724)
static struct clk sh7722_irda_clock = {
.name = "irda_clk",
.arch_flags = IrDACLKCR,
.ops = &sh7722_siu_clk_ops,
};
#endif
-#endif /* CONFIG_CPU_SUBTYPE_SH7343 */
static struct clk sh7722_video_clock = {
.name = "video_clk",
@@ -715,6 +745,61 @@ static struct clk sh7722_mstpcr_clocks[] = {
MSTPCR("vpu0", "bus_clk", 2, 1),
MSTPCR("lcdc0", "bus_clk", 2, 0),
#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7724)
+ /* See Datasheet : Overview -> Block Diagram */
+ MSTPCR("tlb0", "cpu_clk", 0, 31),
+ MSTPCR("ic0", "cpu_clk", 0, 30),
+ MSTPCR("oc0", "cpu_clk", 0, 29),
+ MSTPCR("rs0", "bus_clk", 0, 28),
+ MSTPCR("ilmem0", "cpu_clk", 0, 27),
+ MSTPCR("l2c0", "sh_clk", 0, 26),
+ MSTPCR("fpu0", "cpu_clk", 0, 24),
+ MSTPCR("intc0", "peripheral_clk", 0, 22),
+ MSTPCR("dmac0", "bus_clk", 0, 21),
+ MSTPCR("sh0", "sh_clk", 0, 20),
+ MSTPCR("hudi0", "peripheral_clk", 0, 19),
+ MSTPCR("ubc0", "cpu_clk", 0, 17),
+ MSTPCR("tmu0", "peripheral_clk", 0, 15),
+ MSTPCR("cmt0", "r_clk", 0, 14),
+ MSTPCR("rwdt0", "r_clk", 0, 13),
+ MSTPCR("dmac1", "bus_clk", 0, 12),
+ MSTPCR("tmu1", "peripheral_clk", 0, 10),
+ MSTPCR("scif0", "peripheral_clk", 0, 9),
+ MSTPCR("scif1", "peripheral_clk", 0, 8),
+ MSTPCR("scif2", "peripheral_clk", 0, 7),
+ MSTPCR("scif3", "bus_clk", 0, 6),
+ MSTPCR("scif4", "bus_clk", 0, 5),
+ MSTPCR("scif5", "bus_clk", 0, 4),
+ MSTPCR("msiof0", "bus_clk", 0, 2),
+ MSTPCR("msiof1", "bus_clk", 0, 1),
+ MSTPCR("keysc0", "r_clk", 1, 12),
+ MSTPCR("rtc0", "r_clk", 1, 11),
+ MSTPCR("i2c0", "peripheral_clk", 1, 9),
+ MSTPCR("i2c1", "peripheral_clk", 1, 8),
+ MSTPCR("mmc0", "bus_clk", 2, 29),
+ MSTPCR("eth0", "bus_clk", 2, 28),
+ MSTPCR("atapi0", "bus_clk", 2, 26),
+ MSTPCR("tpu0", "bus_clk", 2, 25),
+ MSTPCR("irda0", "peripheral_clk", 2, 24),
+ MSTPCR("tsif0", "bus_clk", 2, 22),
+ MSTPCR("usb1", "bus_clk", 2, 21),
+ MSTPCR("usb0", "bus_clk", 2, 20),
+ MSTPCR("2dg0", "bus_clk", 2, 19),
+ MSTPCR("sdhi0", "bus_clk", 2, 18),
+ MSTPCR("sdhi1", "bus_clk", 2, 17),
+ MSTPCR("veu1", "bus_clk", 2, 15),
+ MSTPCR("ceu1", "bus_clk", 2, 13),
+ MSTPCR("beu1", "bus_clk", 2, 12),
+ MSTPCR("2ddmac0", "sh_clk", 2, 10),
+ MSTPCR("spu0", "bus_clk", 2, 9),
+ MSTPCR("jpu0", "bus_clk", 2, 6),
+ MSTPCR("vou0", "bus_clk", 2, 5),
+ MSTPCR("beu0", "bus_clk", 2, 4),
+ MSTPCR("ceu0", "bus_clk", 2, 3),
+ MSTPCR("veu0", "bus_clk", 2, 2),
+ MSTPCR("vpu0", "bus_clk", 2, 1),
+ MSTPCR("lcdc0", "bus_clk", 2, 0),
+#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7343)
MSTPCR("uram0", "umem_clk", 0, 28),
MSTPCR("xymem0", "bus_clk", 0, 26),
@@ -786,12 +871,15 @@ static struct clk *sh7722_clocks[] = {
&sh7722_sh_clock,
&sh7722_peripheral_clock,
&sh7722_sdram_clock,
-#ifndef CONFIG_CPU_SUBTYPE_SH7343
+#if !defined(CONFIG_CPU_SUBTYPE_SH7343) &&\
+ !defined(CONFIG_CPU_SUBTYPE_SH7724)
&sh7722_siu_a_clock,
&sh7722_siu_b_clock,
-#if defined(CONFIG_CPU_SUBTYPE_SH7722)
- &sh7722_irda_clock,
#endif
+/* 7724 should support FSI clock */
+#if defined(CONFIG_CPU_SUBTYPE_SH7722) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7724)
+ &sh7722_irda_clock,
#endif
&sh7722_video_clock,
};
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7724.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7724.c
new file mode 100644
index 000000000000..1af0f9586379
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7724.c
@@ -0,0 +1,2230 @@
+/*
+ * SH7724 Pinmux
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on SH7723 Pinmux
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <cpu/sh7724.h>
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+ PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA,
+ PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+ PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA,
+ PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA,
+ PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA,
+ PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+ PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA,
+ PTE7_DATA, PTE6_DATA, PTE5_DATA, PTE4_DATA,
+ PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA,
+ PTF7_DATA, PTF6_DATA, PTF5_DATA, PTF4_DATA,
+ PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA,
+ PTG5_DATA, PTG4_DATA,
+ PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA,
+ PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+ PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA,
+ PTJ7_DATA, PTJ6_DATA, PTJ5_DATA,
+ PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA,
+ PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA,
+ PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA,
+ PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA,
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA,
+ PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+ PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA,
+ PTQ7_DATA, PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
+ PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA,
+ PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
+ PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA,
+ PTS6_DATA, PTS5_DATA, PTS4_DATA,
+ PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA,
+ PTT7_DATA, PTT6_DATA, PTT5_DATA, PTT4_DATA,
+ PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA,
+ PTU7_DATA, PTU6_DATA, PTU5_DATA, PTU4_DATA,
+ PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA,
+ PTV7_DATA, PTV6_DATA, PTV5_DATA, PTV4_DATA,
+ PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA,
+ PTW7_DATA, PTW6_DATA, PTW5_DATA, PTW4_DATA,
+ PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA,
+ PTX7_DATA, PTX6_DATA, PTX5_DATA, PTX4_DATA,
+ PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA,
+ PTY7_DATA, PTY6_DATA, PTY5_DATA, PTY4_DATA,
+ PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA,
+ PTZ7_DATA, PTZ6_DATA, PTZ5_DATA, PTZ4_DATA,
+ PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA,
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PTA7_IN, PTA6_IN, PTA5_IN, PTA4_IN,
+ PTA3_IN, PTA2_IN, PTA1_IN, PTA0_IN,
+ PTB7_IN, PTB6_IN, PTB5_IN, PTB4_IN,
+ PTB3_IN, PTB2_IN, PTB1_IN, PTB0_IN,
+ PTC7_IN, PTC6_IN, PTC5_IN, PTC4_IN,
+ PTC3_IN, PTC2_IN, PTC1_IN, PTC0_IN,
+ PTD7_IN, PTD6_IN, PTD5_IN, PTD4_IN,
+ PTD3_IN, PTD2_IN, PTD1_IN, PTD0_IN,
+ PTE7_IN, PTE6_IN, PTE5_IN, PTE4_IN,
+ PTE3_IN, PTE2_IN, PTE1_IN, PTE0_IN,
+ PTF7_IN, PTF6_IN, PTF5_IN, PTF4_IN,
+ PTF3_IN, PTF2_IN, PTF1_IN, PTF0_IN,
+ PTH7_IN, PTH6_IN, PTH5_IN, PTH4_IN,
+ PTH3_IN, PTH2_IN, PTH1_IN, PTH0_IN,
+ PTJ3_IN, PTJ2_IN, PTJ1_IN, PTJ0_IN,
+ PTK7_IN, PTK6_IN, PTK5_IN, PTK4_IN,
+ PTK3_IN, PTK2_IN, PTK1_IN, PTK0_IN,
+ PTL7_IN, PTL6_IN, PTL5_IN, PTL4_IN,
+ PTL3_IN, PTL2_IN, PTL1_IN, PTL0_IN,
+ PTM7_IN, PTM6_IN, PTM5_IN, PTM4_IN,
+ PTM3_IN, PTM2_IN, PTM1_IN, PTM0_IN,
+ PTN7_IN, PTN6_IN, PTN5_IN, PTN4_IN,
+ PTN3_IN, PTN2_IN, PTN1_IN, PTN0_IN,
+ PTQ7_IN, PTQ6_IN, PTQ5_IN, PTQ4_IN,
+ PTQ3_IN, PTQ2_IN, PTQ1_IN, PTQ0_IN,
+ PTR7_IN, PTR6_IN, PTR5_IN, PTR4_IN,
+ PTR3_IN, PTR2_IN, PTR1_IN, PTR0_IN,
+ PTS6_IN, PTS5_IN, PTS4_IN,
+ PTS3_IN, PTS2_IN, PTS1_IN, PTS0_IN,
+ PTT7_IN, PTT6_IN, PTT5_IN, PTT4_IN,
+ PTT3_IN, PTT2_IN, PTT1_IN, PTT0_IN,
+ PTU7_IN, PTU6_IN, PTU5_IN, PTU4_IN,
+ PTU3_IN, PTU2_IN, PTU1_IN, PTU0_IN,
+ PTV7_IN, PTV6_IN, PTV5_IN, PTV4_IN,
+ PTV3_IN, PTV2_IN, PTV1_IN, PTV0_IN,
+ PTW7_IN, PTW6_IN, PTW5_IN, PTW4_IN,
+ PTW3_IN, PTW2_IN, PTW1_IN, PTW0_IN,
+ PTX7_IN, PTX6_IN, PTX5_IN, PTX4_IN,
+ PTX3_IN, PTX2_IN, PTX1_IN, PTX0_IN,
+ PTY7_IN, PTY6_IN, PTY5_IN, PTY4_IN,
+ PTY3_IN, PTY2_IN, PTY1_IN, PTY0_IN,
+ PTZ7_IN, PTZ6_IN, PTZ5_IN, PTZ4_IN,
+ PTZ3_IN, PTZ2_IN, PTZ1_IN, PTZ0_IN,
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PTA7_IN_PU, PTA6_IN_PU, PTA5_IN_PU, PTA4_IN_PU,
+ PTA3_IN_PU, PTA2_IN_PU, PTA1_IN_PU, PTA0_IN_PU,
+ PTB7_IN_PU, PTB6_IN_PU, PTB5_IN_PU, PTB4_IN_PU,
+ PTB3_IN_PU, PTB2_IN_PU, PTB1_IN_PU, PTB0_IN_PU,
+ PTC7_IN_PU, PTC6_IN_PU, PTC5_IN_PU, PTC4_IN_PU,
+ PTC3_IN_PU, PTC2_IN_PU, PTC1_IN_PU, PTC0_IN_PU,
+ PTD7_IN_PU, PTD6_IN_PU, PTD5_IN_PU, PTD4_IN_PU,
+ PTD3_IN_PU, PTD2_IN_PU, PTD1_IN_PU, PTD0_IN_PU,
+ PTE7_IN_PU, PTE6_IN_PU, PTE5_IN_PU, PTE4_IN_PU,
+ PTE3_IN_PU, PTE2_IN_PU, PTE1_IN_PU, PTE0_IN_PU,
+ PTF7_IN_PU, PTF6_IN_PU, PTF5_IN_PU, PTF4_IN_PU,
+ PTF3_IN_PU, PTF2_IN_PU, PTF1_IN_PU, PTF0_IN_PU,
+ PTH7_IN_PU, PTH6_IN_PU, PTH5_IN_PU, PTH4_IN_PU,
+ PTH3_IN_PU, PTH2_IN_PU, PTH1_IN_PU, PTH0_IN_PU,
+ PTJ3_IN_PU, PTJ2_IN_PU, PTJ1_IN_PU, PTJ0_IN_PU,
+ PTK7_IN_PU, PTK6_IN_PU, PTK5_IN_PU, PTK4_IN_PU,
+ PTK3_IN_PU, PTK2_IN_PU, PTK1_IN_PU, PTK0_IN_PU,
+ PTL7_IN_PU, PTL6_IN_PU, PTL5_IN_PU, PTL4_IN_PU,
+ PTL3_IN_PU, PTL2_IN_PU, PTL1_IN_PU, PTL0_IN_PU,
+ PTM7_IN_PU, PTM6_IN_PU, PTM5_IN_PU, PTM4_IN_PU,
+ PTM3_IN_PU, PTM2_IN_PU, PTM1_IN_PU, PTM0_IN_PU,
+ PTN7_IN_PU, PTN6_IN_PU, PTN5_IN_PU, PTN4_IN_PU,
+ PTN3_IN_PU, PTN2_IN_PU, PTN1_IN_PU, PTN0_IN_PU,
+ PTQ7_IN_PU, PTQ6_IN_PU, PTQ5_IN_PU, PTQ4_IN_PU,
+ PTQ3_IN_PU, PTQ2_IN_PU, PTQ1_IN_PU, PTQ0_IN_PU,
+ PTR7_IN_PU, PTR6_IN_PU, PTR5_IN_PU, PTR4_IN_PU,
+ PTR3_IN_PU, PTR2_IN_PU, PTR1_IN_PU, PTR0_IN_PU,
+ PTS6_IN_PU, PTS5_IN_PU, PTS4_IN_PU,
+ PTS3_IN_PU, PTS2_IN_PU, PTS1_IN_PU, PTS0_IN_PU,
+ PTT7_IN_PU, PTT6_IN_PU, PTT5_IN_PU, PTT4_IN_PU,
+ PTT3_IN_PU, PTT2_IN_PU, PTT1_IN_PU, PTT0_IN_PU,
+ PTU7_IN_PU, PTU6_IN_PU, PTU5_IN_PU, PTU4_IN_PU,
+ PTU3_IN_PU, PTU2_IN_PU, PTU1_IN_PU, PTU0_IN_PU,
+ PTV7_IN_PU, PTV6_IN_PU, PTV5_IN_PU, PTV4_IN_PU,
+ PTV3_IN_PU, PTV2_IN_PU, PTV1_IN_PU, PTV0_IN_PU,
+ PTW7_IN_PU, PTW6_IN_PU, PTW5_IN_PU, PTW4_IN_PU,
+ PTW3_IN_PU, PTW2_IN_PU, PTW1_IN_PU, PTW0_IN_PU,
+ PTX7_IN_PU, PTX6_IN_PU, PTX5_IN_PU, PTX4_IN_PU,
+ PTX3_IN_PU, PTX2_IN_PU, PTX1_IN_PU, PTX0_IN_PU,
+ PTY7_IN_PU, PTY6_IN_PU, PTY5_IN_PU, PTY4_IN_PU,
+ PTY3_IN_PU, PTY2_IN_PU, PTY1_IN_PU, PTY0_IN_PU,
+ PTZ7_IN_PU, PTZ6_IN_PU, PTZ5_IN_PU, PTZ4_IN_PU,
+ PTZ3_IN_PU, PTZ2_IN_PU, PTZ1_IN_PU, PTZ0_IN_PU,
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PTA7_OUT, PTA6_OUT, PTA5_OUT, PTA4_OUT,
+ PTA3_OUT, PTA2_OUT, PTA1_OUT, PTA0_OUT,
+ PTB7_OUT, PTB6_OUT, PTB5_OUT, PTB4_OUT,
+ PTB3_OUT, PTB2_OUT, PTB1_OUT, PTB0_OUT,
+ PTC7_OUT, PTC6_OUT, PTC5_OUT, PTC4_OUT,
+ PTC3_OUT, PTC2_OUT, PTC1_OUT, PTC0_OUT,
+ PTD7_OUT, PTD6_OUT, PTD5_OUT, PTD4_OUT,
+ PTD3_OUT, PTD2_OUT, PTD1_OUT, PTD0_OUT,
+ PTE7_OUT, PTE6_OUT, PTE5_OUT, PTE4_OUT,
+ PTE3_OUT, PTE2_OUT, PTE1_OUT, PTE0_OUT,
+ PTF7_OUT, PTF6_OUT, PTF5_OUT, PTF4_OUT,
+ PTF3_OUT, PTF2_OUT, PTF1_OUT, PTF0_OUT,
+ PTG5_OUT, PTG4_OUT,
+ PTG3_OUT, PTG2_OUT, PTG1_OUT, PTG0_OUT,
+ PTH7_OUT, PTH6_OUT, PTH5_OUT, PTH4_OUT,
+ PTH3_OUT, PTH2_OUT, PTH1_OUT, PTH0_OUT,
+ PTJ7_OUT, PTJ6_OUT, PTJ5_OUT,
+ PTJ3_OUT, PTJ2_OUT, PTJ1_OUT, PTJ0_OUT,
+ PTK7_OUT, PTK6_OUT, PTK5_OUT, PTK4_OUT,
+ PTK3_OUT, PTK2_OUT, PTK1_OUT, PTK0_OUT,
+ PTL7_OUT, PTL6_OUT, PTL5_OUT, PTL4_OUT,
+ PTL3_OUT, PTL2_OUT, PTL1_OUT, PTL0_OUT,
+ PTM7_OUT, PTM6_OUT, PTM5_OUT, PTM4_OUT,
+ PTM3_OUT, PTM2_OUT, PTM1_OUT, PTM0_OUT,
+ PTN7_OUT, PTN6_OUT, PTN5_OUT, PTN4_OUT,
+ PTN3_OUT, PTN2_OUT, PTN1_OUT, PTN0_OUT,
+ PTQ7_OUT, PTQ6_OUT, PTQ5_OUT, PTQ4_OUT,
+ PTQ3_OUT, PTQ2_OUT, PTQ1_OUT, PTQ0_OUT,
+ PTR7_OUT, PTR6_OUT, PTR5_OUT, PTR4_OUT,
+ PTR1_OUT, PTR0_OUT,
+ PTS6_OUT, PTS5_OUT, PTS4_OUT,
+ PTS3_OUT, PTS2_OUT, PTS1_OUT, PTS0_OUT,
+ PTT7_OUT, PTT6_OUT, PTT5_OUT, PTT4_OUT,
+ PTT3_OUT, PTT2_OUT, PTT1_OUT, PTT0_OUT,
+ PTU7_OUT, PTU6_OUT, PTU5_OUT, PTU4_OUT,
+ PTU3_OUT, PTU2_OUT, PTU1_OUT, PTU0_OUT,
+ PTV7_OUT, PTV6_OUT, PTV5_OUT, PTV4_OUT,
+ PTV3_OUT, PTV2_OUT, PTV1_OUT, PTV0_OUT,
+ PTW7_OUT, PTW6_OUT, PTW5_OUT, PTW4_OUT,
+ PTW3_OUT, PTW2_OUT, PTW1_OUT, PTW0_OUT,
+ PTX7_OUT, PTX6_OUT, PTX5_OUT, PTX4_OUT,
+ PTX3_OUT, PTX2_OUT, PTX1_OUT, PTX0_OUT,
+ PTY7_OUT, PTY6_OUT, PTY5_OUT, PTY4_OUT,
+ PTY3_OUT, PTY2_OUT, PTY1_OUT, PTY0_OUT,
+ PTZ7_OUT, PTZ6_OUT, PTZ5_OUT, PTZ4_OUT,
+ PTZ3_OUT, PTZ2_OUT, PTZ1_OUT, PTZ0_OUT,
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PTA7_FN, PTA6_FN, PTA5_FN, PTA4_FN,
+ PTA3_FN, PTA2_FN, PTA1_FN, PTA0_FN,
+ PTB7_FN, PTB6_FN, PTB5_FN, PTB4_FN,
+ PTB3_FN, PTB2_FN, PTB1_FN, PTB0_FN,
+ PTC7_FN, PTC6_FN, PTC5_FN, PTC4_FN,
+ PTC3_FN, PTC2_FN, PTC1_FN, PTC0_FN,
+ PTD7_FN, PTD6_FN, PTD5_FN, PTD4_FN,
+ PTD3_FN, PTD2_FN, PTD1_FN, PTD0_FN,
+ PTE7_FN, PTE6_FN, PTE5_FN, PTE4_FN,
+ PTE3_FN, PTE2_FN, PTE1_FN, PTE0_FN,
+ PTF7_FN, PTF6_FN, PTF5_FN, PTF4_FN,
+ PTF3_FN, PTF2_FN, PTF1_FN, PTF0_FN,
+ PTG5_FN, PTG4_FN,
+ PTG3_FN, PTG2_FN, PTG1_FN, PTG0_FN,
+ PTH7_FN, PTH6_FN, PTH5_FN, PTH4_FN,
+ PTH3_FN, PTH2_FN, PTH1_FN, PTH0_FN,
+ PTJ7_FN, PTJ6_FN, PTJ5_FN,
+ PTJ3_FN, PTJ2_FN, PTJ1_FN, PTJ0_FN,
+ PTK7_FN, PTK6_FN, PTK5_FN, PTK4_FN,
+ PTK3_FN, PTK2_FN, PTK1_FN, PTK0_FN,
+ PTL7_FN, PTL6_FN, PTL5_FN, PTL4_FN,
+ PTL3_FN, PTL2_FN, PTL1_FN, PTL0_FN,
+ PTM7_FN, PTM6_FN, PTM5_FN, PTM4_FN,
+ PTM3_FN, PTM2_FN, PTM1_FN, PTM0_FN,
+ PTN7_FN, PTN6_FN, PTN5_FN, PTN4_FN,
+ PTN3_FN, PTN2_FN, PTN1_FN, PTN0_FN,
+ PTQ7_FN, PTQ6_FN, PTQ5_FN, PTQ4_FN,
+ PTQ3_FN, PTQ2_FN, PTQ1_FN, PTQ0_FN,
+ PTR7_FN, PTR6_FN, PTR5_FN, PTR4_FN,
+ PTR3_FN, PTR2_FN, PTR1_FN, PTR0_FN,
+ PTS6_FN, PTS5_FN, PTS4_FN,
+ PTS3_FN, PTS2_FN, PTS1_FN, PTS0_FN,
+ PTT7_FN, PTT6_FN, PTT5_FN, PTT4_FN,
+ PTT3_FN, PTT2_FN, PTT1_FN, PTT0_FN,
+ PTU7_FN, PTU6_FN, PTU5_FN, PTU4_FN,
+ PTU3_FN, PTU2_FN, PTU1_FN, PTU0_FN,
+ PTV7_FN, PTV6_FN, PTV5_FN, PTV4_FN,
+ PTV3_FN, PTV2_FN, PTV1_FN, PTV0_FN,
+ PTW7_FN, PTW6_FN, PTW5_FN, PTW4_FN,
+ PTW3_FN, PTW2_FN, PTW1_FN, PTW0_FN,
+ PTX7_FN, PTX6_FN, PTX5_FN, PTX4_FN,
+ PTX3_FN, PTX2_FN, PTX1_FN, PTX0_FN,
+ PTY7_FN, PTY6_FN, PTY5_FN, PTY4_FN,
+ PTY3_FN, PTY2_FN, PTY1_FN, PTY0_FN,
+ PTZ7_FN, PTZ6_FN, PTZ5_FN, PTZ4_FN,
+ PTZ3_FN, PTZ2_FN, PTZ1_FN, PTZ0_FN,
+
+
+ PSA15_0, PSA15_1,
+ PSA14_0, PSA14_1,
+ PSA13_0, PSA13_1,
+ PSA12_0, PSA12_1,
+ PSA10_0, PSA10_1,
+ PSA9_0, PSA9_1,
+ PSA8_0, PSA8_1,
+ PSA7_0, PSA7_1,
+ PSA6_0, PSA6_1,
+ PSA5_0, PSA5_1,
+ PSA3_0, PSA3_1,
+ PSA2_0, PSA2_1,
+ PSA1_0, PSA1_1,
+ PSA0_0, PSA0_1,
+
+ PSB14_0, PSB14_1,
+ PSB13_0, PSB13_1,
+ PSB12_0, PSB12_1,
+ PSB11_0, PSB11_1,
+ PSB10_0, PSB10_1,
+ PSB9_0, PSB9_1,
+ PSB8_0, PSB8_1,
+ PSB7_0, PSB7_1,
+ PSB6_0, PSB6_1,
+ PSB5_0, PSB5_1,
+ PSB4_0, PSB4_1,
+ PSB3_0, PSB3_1,
+ PSB2_0, PSB2_1,
+ PSB1_0, PSB1_1,
+ PSB0_0, PSB0_1,
+
+ PSC15_0, PSC15_1,
+ PSC14_0, PSC14_1,
+ PSC13_0, PSC13_1,
+ PSC12_0, PSC12_1,
+ PSC11_0, PSC11_1,
+ PSC10_0, PSC10_1,
+ PSC9_0, PSC9_1,
+ PSC8_0, PSC8_1,
+ PSC7_0, PSC7_1,
+ PSC6_0, PSC6_1,
+ PSC5_0, PSC5_1,
+ PSC4_0, PSC4_1,
+ PSC2_0, PSC2_1,
+ PSC1_0, PSC1_1,
+ PSC0_0, PSC0_1,
+
+ PSD15_0, PSD15_1,
+ PSD14_0, PSD14_1,
+ PSD13_0, PSD13_1,
+ PSD12_0, PSD12_1,
+ PSD11_0, PSD11_1,
+ PSD10_0, PSD10_1,
+ PSD9_0, PSD9_1,
+ PSD8_0, PSD8_1,
+ PSD7_0, PSD7_1,
+ PSD6_0, PSD6_1,
+ PSD5_0, PSD5_1,
+ PSD4_0, PSD4_1,
+ PSD3_0, PSD3_1,
+ PSD2_0, PSD2_1,
+ PSD1_0, PSD1_1,
+ PSD0_0, PSD0_1,
+
+ PSE15_0, PSE15_1,
+ PSE14_0, PSE14_1,
+ PSE13_0, PSE13_1,
+ PSE12_0, PSE12_1,
+ PSE11_0, PSE11_1,
+ PSE10_0, PSE10_1,
+ PSE9_0, PSE9_1,
+ PSE8_0, PSE8_1,
+ PSE7_0, PSE7_1,
+ PSE6_0, PSE6_1,
+ PSE5_0, PSE5_1,
+ PSE4_0, PSE4_1,
+ PSE3_0, PSE3_1,
+ PSE2_0, PSE2_1,
+ PSE1_0, PSE1_1,
+ PSE0_0, PSE0_1,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ /*PTA*/
+ D23_MARK, KEYOUT2_MARK, IDED15_MARK,
+ D22_MARK, KEYOUT1_MARK, IDED14_MARK,
+ D21_MARK, KEYOUT0_MARK, IDED13_MARK,
+ D20_MARK, KEYIN4_MARK, IDED12_MARK,
+ D19_MARK, KEYIN3_MARK, IDED11_MARK,
+ D18_MARK, KEYIN2_MARK, IDED10_MARK,
+ D17_MARK, KEYIN1_MARK, IDED9_MARK,
+ D16_MARK, KEYIN0_MARK, IDED8_MARK,
+
+ /*PTB*/
+ D31_MARK, TPUTO1_MARK, IDEA1_MARK,
+ D30_MARK, TPUTO0_MARK, IDEA0_MARK,
+ D29_MARK, IODREQ_MARK,
+ D28_MARK, IDECS0_MARK,
+ D27_MARK, IDECS1_MARK,
+ D26_MARK, KEYOUT5_IN5_MARK, IDEIORD_MARK,
+ D25_MARK, KEYOUT4_IN6_MARK, IDEIOWR_MARK,
+ D24_MARK, KEYOUT3_MARK, IDEINT_MARK,
+
+ /*PTC*/
+ LCDD7_MARK,
+ LCDD6_MARK,
+ LCDD5_MARK,
+ LCDD4_MARK,
+ LCDD3_MARK,
+ LCDD2_MARK,
+ LCDD1_MARK,
+ LCDD0_MARK,
+
+ /*PTD*/
+ LCDD15_MARK,
+ LCDD14_MARK,
+ LCDD13_MARK,
+ LCDD12_MARK,
+ LCDD11_MARK,
+ LCDD10_MARK,
+ LCDD9_MARK,
+ LCDD8_MARK,
+
+ /*PTE*/
+ FSIMCKB_MARK,
+ FSIMCKA_MARK,
+ LCDD21_MARK, SCIF2_L_TXD_MARK,
+ LCDD20_MARK, SCIF4_SCK_MARK,
+ LCDD19_MARK, SCIF4_RXD_MARK,
+ LCDD18_MARK, SCIF4_TXD_MARK,
+ LCDD17_MARK,
+ LCDD16_MARK,
+
+ /*PTF*/
+ LCDVSYN_MARK,
+ LCDDISP_MARK, LCDRS_MARK,
+ LCDHSYN_MARK, LCDCS_MARK,
+ LCDDON_MARK,
+ LCDDCK_MARK, LCDWR_MARK,
+ LCDVEPWC_MARK, SCIF0_TXD_MARK,
+ LCDD23_MARK, SCIF2_L_SCK_MARK,
+ LCDD22_MARK, SCIF2_L_RXD_MARK,
+
+ /*PTG*/
+ AUDCK_MARK,
+ AUDSYNC_MARK,
+ AUDATA3_MARK,
+ AUDATA2_MARK,
+ AUDATA1_MARK,
+ AUDATA0_MARK,
+
+ /*PTH*/
+ VIO0_VD_MARK,
+ VIO0_CLK_MARK,
+ VIO0_D7_MARK,
+ VIO0_D6_MARK,
+ VIO0_D5_MARK,
+ VIO0_D4_MARK,
+ VIO0_D3_MARK,
+ VIO0_D2_MARK,
+
+ /*PTJ*/
+ PDSTATUS_MARK,
+ STATUS2_MARK,
+ STATUS0_MARK,
+ A25_MARK, BS_MARK,
+ A24_MARK,
+ A23_MARK,
+ A22_MARK,
+
+ /*PTK*/
+ VIO1_D5_MARK, VIO0_D13_MARK, IDED5_MARK,
+ VIO1_D4_MARK, VIO0_D12_MARK, IDED4_MARK,
+ VIO1_D3_MARK, VIO0_D11_MARK, IDED3_MARK,
+ VIO1_D2_MARK, VIO0_D10_MARK, IDED2_MARK,
+ VIO1_D1_MARK, VIO0_D9_MARK, IDED1_MARK,
+ VIO1_D0_MARK, VIO0_D8_MARK, IDED0_MARK,
+ VIO0_FLD_MARK,
+ VIO0_HD_MARK,
+
+ /*PTL*/
+ DV_D5_MARK, SCIF3_V_SCK_MARK, RMII_RXD0_MARK,
+ DV_D4_MARK, SCIF3_V_RXD_MARK, RMII_RXD1_MARK,
+ DV_D3_MARK, SCIF3_V_TXD_MARK, RMII_REF_CLK_MARK,
+ DV_D2_MARK, SCIF1_SCK_MARK, RMII_TX_EN_MARK,
+ DV_D1_MARK, SCIF1_RXD_MARK, RMII_TXD0_MARK,
+ DV_D0_MARK, SCIF1_TXD_MARK, RMII_TXD1_MARK,
+ DV_D15_MARK,
+ DV_D14_MARK, MSIOF0_MCK_MARK,
+
+ /*PTM*/
+ DV_D13_MARK, MSIOF0_TSCK_MARK,
+ DV_D12_MARK, MSIOF0_RXD_MARK,
+ DV_D11_MARK, MSIOF0_TXD_MARK,
+ DV_D10_MARK, MSIOF0_TSYNC_MARK,
+ DV_D9_MARK, MSIOF0_SS1_MARK, MSIOF0_RSCK_MARK,
+ DV_D8_MARK, MSIOF0_SS2_MARK, MSIOF0_RSYNC_MARK,
+ LCDVCPWC_MARK, SCIF0_RXD_MARK,
+ LCDRD_MARK, SCIF0_SCK_MARK,
+
+ /*PTN*/
+ VIO0_D1_MARK,
+ VIO0_D0_MARK,
+ DV_CLKI_MARK,
+ DV_CLK_MARK, SCIF2_V_SCK_MARK,
+ DV_VSYNC_MARK, SCIF2_V_RXD_MARK,
+ DV_HSYNC_MARK, SCIF2_V_TXD_MARK,
+ DV_D7_MARK, SCIF3_V_CTS_MARK, RMII_RX_ER_MARK,
+ DV_D6_MARK, SCIF3_V_RTS_MARK, RMII_CRS_DV_MARK,
+
+ /*PTQ*/
+ D7_MARK,
+ D6_MARK,
+ D5_MARK,
+ D4_MARK,
+ D3_MARK,
+ D2_MARK,
+ D1_MARK,
+ D0_MARK,
+
+ /*PTR*/
+ CS6B_CE1B_MARK,
+ CS6A_CE2B_MARK,
+ CS5B_CE1A_MARK,
+ CS5A_CE2A_MARK,
+ IOIS16_MARK, LCDLCLK_MARK,
+ WAIT_MARK,
+ WE3_ICIOWR_MARK, TPUTO3_MARK, TPUTI3_MARK,
+ WE2_ICIORD_MARK, TPUTO2_MARK, IDEA2_MARK,
+
+ /*PTS*/
+ VIO_CKO_MARK,
+ VIO1_FLD_MARK, TPUTI2_MARK, IDEIORDY_MARK,
+ VIO1_HD_MARK, SCIF5_SCK_MARK,
+ VIO1_VD_MARK, SCIF5_RXD_MARK,
+ VIO1_CLK_MARK, SCIF5_TXD_MARK,
+ VIO1_D7_MARK, VIO0_D15_MARK, IDED7_MARK,
+ VIO1_D6_MARK, VIO0_D14_MARK, IDED6_MARK,
+
+ /*PTT*/
+ D15_MARK,
+ D14_MARK,
+ D13_MARK,
+ D12_MARK,
+ D11_MARK,
+ D10_MARK,
+ D9_MARK,
+ D8_MARK,
+
+ /*PTU*/
+ DMAC_DACK0_MARK,
+ DMAC_DREQ0_MARK,
+ FSIOASD_MARK,
+ FSIIABCK_MARK,
+ FSIIALRCK_MARK,
+ FSIOABCK_MARK,
+ FSIOALRCK_MARK,
+ CLKAUDIOAO_MARK,
+
+ /*PTV*/
+ FSIIBSD_MARK, MSIOF1_SS2_MARK, MSIOF1_RSYNC_MARK,
+ FSIOBSD_MARK, MSIOF1_SS1_MARK, MSIOF1_RSCK_MARK,
+ FSIIBBCK_MARK, MSIOF1_RXD_MARK,
+ FSIIBLRCK_MARK, MSIOF1_TSYNC_MARK,
+ FSIOBBCK_MARK, MSIOF1_TSCK_MARK,
+ FSIOBLRCK_MARK, MSIOF1_TXD_MARK,
+ CLKAUDIOBO_MARK, MSIOF1_MCK_MARK,
+ FSIIASD_MARK,
+
+ /*PTW*/
+ MMC_D7_MARK, SDHI1CD_MARK, IODACK_MARK,
+ MMC_D6_MARK, SDHI1WP_MARK, IDERST_MARK,
+ MMC_D5_MARK, SDHI1D3_MARK, EXBUF_ENB_MARK,
+ MMC_D4_MARK, SDHI1D2_MARK, DIRECTION_MARK,
+ MMC_D3_MARK, SDHI1D1_MARK,
+ MMC_D2_MARK, SDHI1D0_MARK,
+ MMC_D1_MARK, SDHI1CMD_MARK,
+ MMC_D0_MARK, SDHI1CLK_MARK,
+
+ /*PTX*/
+ DMAC_DACK1_MARK, IRDA_OUT_MARK,
+ DMAC_DREQ1_MARK, IRDA_IN_MARK,
+ TSIF_TS0_SDAT_MARK, LNKSTA_MARK,
+ TSIF_TS0_SCK_MARK, MDIO_MARK,
+ TSIF_TS0_SDEN_MARK, MDC_MARK,
+ TSIF_TS0_SPSYNC_MARK,
+ MMC_CLK_MARK,
+ MMC_CMD_MARK,
+
+ /*PTY*/
+ SDHI0CD_MARK,
+ SDHI0WP_MARK,
+ SDHI0D3_MARK,
+ SDHI0D2_MARK,
+ SDHI0D1_MARK,
+ SDHI0D0_MARK,
+ SDHI0CMD_MARK,
+ SDHI0CLK_MARK,
+
+ /*PTZ*/
+ INTC_IRQ7_MARK, SCIF3_I_CTS_MARK,
+ INTC_IRQ6_MARK, SCIF3_I_RTS_MARK,
+ INTC_IRQ5_MARK, SCIF3_I_SCK_MARK,
+ INTC_IRQ4_MARK, SCIF3_I_RXD_MARK,
+ INTC_IRQ3_MARK, SCIF3_I_TXD_MARK,
+ INTC_IRQ2_MARK,
+ INTC_IRQ1_MARK,
+ INTC_IRQ0_MARK,
+ PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+ /* PTA GPIO */
+ PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_OUT, PTA7_IN_PU),
+ PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_OUT, PTA6_IN_PU),
+ PINMUX_DATA(PTA5_DATA, PTA5_IN, PTA5_OUT, PTA5_IN_PU),
+ PINMUX_DATA(PTA4_DATA, PTA4_IN, PTA4_OUT, PTA4_IN_PU),
+ PINMUX_DATA(PTA3_DATA, PTA3_IN, PTA3_OUT, PTA3_IN_PU),
+ PINMUX_DATA(PTA2_DATA, PTA2_IN, PTA2_OUT, PTA2_IN_PU),
+ PINMUX_DATA(PTA1_DATA, PTA1_IN, PTA1_OUT, PTA1_IN_PU),
+ PINMUX_DATA(PTA0_DATA, PTA0_IN, PTA0_OUT, PTA0_IN_PU),
+
+ /* PTB GPIO */
+ PINMUX_DATA(PTB7_DATA, PTB7_IN, PTB7_OUT, PTB7_IN_PU),
+ PINMUX_DATA(PTB6_DATA, PTB6_IN, PTB6_OUT, PTB6_IN_PU),
+ PINMUX_DATA(PTB5_DATA, PTB5_IN, PTB5_OUT, PTB5_IN_PU),
+ PINMUX_DATA(PTB4_DATA, PTB4_IN, PTB4_OUT, PTB4_IN_PU),
+ PINMUX_DATA(PTB3_DATA, PTB3_IN, PTB3_OUT, PTB3_IN_PU),
+ PINMUX_DATA(PTB2_DATA, PTB2_IN, PTB2_OUT, PTB2_IN_PU),
+ PINMUX_DATA(PTB1_DATA, PTB1_IN, PTB1_OUT, PTB1_IN_PU),
+ PINMUX_DATA(PTB0_DATA, PTB0_IN, PTB0_OUT, PTB0_IN_PU),
+
+ /* PTC GPIO */
+ PINMUX_DATA(PTC7_DATA, PTC7_IN, PTC7_OUT, PTC7_IN_PU),
+ PINMUX_DATA(PTC6_DATA, PTC6_IN, PTC6_OUT, PTC6_IN_PU),
+ PINMUX_DATA(PTC5_DATA, PTC5_IN, PTC5_OUT, PTC5_IN_PU),
+ PINMUX_DATA(PTC4_DATA, PTC4_IN, PTC4_OUT, PTC4_IN_PU),
+ PINMUX_DATA(PTC3_DATA, PTC3_IN, PTC3_OUT, PTC3_IN_PU),
+ PINMUX_DATA(PTC2_DATA, PTC2_IN, PTC2_OUT, PTC2_IN_PU),
+ PINMUX_DATA(PTC1_DATA, PTC1_IN, PTC1_OUT, PTC1_IN_PU),
+ PINMUX_DATA(PTC0_DATA, PTC0_IN, PTC0_OUT, PTC0_IN_PU),
+
+ /* PTD GPIO */
+ PINMUX_DATA(PTD7_DATA, PTD7_IN, PTD7_OUT, PTD7_IN_PU),
+ PINMUX_DATA(PTD6_DATA, PTD6_IN, PTD6_OUT, PTD6_IN_PU),
+ PINMUX_DATA(PTD5_DATA, PTD5_IN, PTD5_OUT, PTD5_IN_PU),
+ PINMUX_DATA(PTD4_DATA, PTD4_IN, PTD4_OUT, PTD4_IN_PU),
+ PINMUX_DATA(PTD3_DATA, PTD3_IN, PTD3_OUT, PTD3_IN_PU),
+ PINMUX_DATA(PTD2_DATA, PTD2_IN, PTD2_OUT, PTD2_IN_PU),
+ PINMUX_DATA(PTD1_DATA, PTD1_IN, PTD1_OUT, PTD1_IN_PU),
+ PINMUX_DATA(PTD0_DATA, PTD0_IN, PTD0_OUT, PTD0_IN_PU),
+
+ /* PTE GPIO */
+ PINMUX_DATA(PTE7_DATA, PTE7_IN, PTE7_OUT, PTE7_IN_PU),
+ PINMUX_DATA(PTE6_DATA, PTE6_IN, PTE6_OUT, PTE6_IN_PU),
+ PINMUX_DATA(PTE5_DATA, PTE5_IN, PTE5_OUT, PTE5_IN_PU),
+ PINMUX_DATA(PTE4_DATA, PTE4_IN, PTE4_OUT, PTE4_IN_PU),
+ PINMUX_DATA(PTE3_DATA, PTE3_IN, PTE3_OUT, PTE3_IN_PU),
+ PINMUX_DATA(PTE2_DATA, PTE2_IN, PTE2_OUT, PTE2_IN_PU),
+ PINMUX_DATA(PTE1_DATA, PTE1_IN, PTE1_OUT, PTE1_IN_PU),
+ PINMUX_DATA(PTE0_DATA, PTE0_IN, PTE0_OUT, PTE0_IN_PU),
+
+ /* PTF GPIO */
+ PINMUX_DATA(PTF7_DATA, PTF7_IN, PTF7_OUT, PTF7_IN_PU),
+ PINMUX_DATA(PTF6_DATA, PTF6_IN, PTF6_OUT, PTF6_IN_PU),
+ PINMUX_DATA(PTF5_DATA, PTF5_IN, PTF5_OUT, PTF5_IN_PU),
+ PINMUX_DATA(PTF4_DATA, PTF4_IN, PTF4_OUT, PTF4_IN_PU),
+ PINMUX_DATA(PTF3_DATA, PTF3_IN, PTF3_OUT, PTF3_IN_PU),
+ PINMUX_DATA(PTF2_DATA, PTF2_IN, PTF2_OUT, PTF2_IN_PU),
+ PINMUX_DATA(PTF1_DATA, PTF1_IN, PTF1_OUT, PTF1_IN_PU),
+ PINMUX_DATA(PTF0_DATA, PTF0_IN, PTF0_OUT, PTF0_IN_PU),
+
+ /* PTG GPIO */
+ PINMUX_DATA(PTG5_DATA, PTG5_OUT),
+ PINMUX_DATA(PTG4_DATA, PTG4_OUT),
+ PINMUX_DATA(PTG3_DATA, PTG3_OUT),
+ PINMUX_DATA(PTG2_DATA, PTG2_OUT),
+ PINMUX_DATA(PTG1_DATA, PTG1_OUT),
+ PINMUX_DATA(PTG0_DATA, PTG0_OUT),
+
+ /* PTH GPIO */
+ PINMUX_DATA(PTH7_DATA, PTH7_IN, PTH7_OUT, PTH7_IN_PU),
+ PINMUX_DATA(PTH6_DATA, PTH6_IN, PTH6_OUT, PTH6_IN_PU),
+ PINMUX_DATA(PTH5_DATA, PTH5_IN, PTH5_OUT, PTH5_IN_PU),
+ PINMUX_DATA(PTH4_DATA, PTH4_IN, PTH4_OUT, PTH4_IN_PU),
+ PINMUX_DATA(PTH3_DATA, PTH3_IN, PTH3_OUT, PTH3_IN_PU),
+ PINMUX_DATA(PTH2_DATA, PTH2_IN, PTH2_OUT, PTH2_IN_PU),
+ PINMUX_DATA(PTH1_DATA, PTH1_IN, PTH1_OUT, PTH1_IN_PU),
+ PINMUX_DATA(PTH0_DATA, PTH0_IN, PTH0_OUT, PTH0_IN_PU),
+
+ /* PTJ GPIO */
+ PINMUX_DATA(PTJ7_DATA, PTJ7_OUT),
+ PINMUX_DATA(PTJ6_DATA, PTJ6_OUT),
+ PINMUX_DATA(PTJ5_DATA, PTJ5_OUT),
+ PINMUX_DATA(PTJ3_DATA, PTJ3_IN, PTJ3_OUT, PTJ3_IN_PU),
+ PINMUX_DATA(PTJ2_DATA, PTJ2_IN, PTJ2_OUT, PTJ2_IN_PU),
+ PINMUX_DATA(PTJ1_DATA, PTJ1_IN, PTJ1_OUT, PTJ1_IN_PU),
+ PINMUX_DATA(PTJ0_DATA, PTJ0_IN, PTJ0_OUT, PTJ0_IN_PU),
+
+ /* PTK GPIO */
+ PINMUX_DATA(PTK7_DATA, PTK7_IN, PTK7_OUT, PTK7_IN_PU),
+ PINMUX_DATA(PTK6_DATA, PTK6_IN, PTK6_OUT, PTK6_IN_PU),
+ PINMUX_DATA(PTK5_DATA, PTK5_IN, PTK5_OUT, PTK5_IN_PU),
+ PINMUX_DATA(PTK4_DATA, PTK4_IN, PTK4_OUT, PTK4_IN_PU),
+ PINMUX_DATA(PTK3_DATA, PTK3_IN, PTK3_OUT, PTK3_IN_PU),
+ PINMUX_DATA(PTK2_DATA, PTK2_IN, PTK2_OUT, PTK2_IN_PU),
+ PINMUX_DATA(PTK1_DATA, PTK1_IN, PTK1_OUT, PTK1_IN_PU),
+ PINMUX_DATA(PTK0_DATA, PTK0_IN, PTK0_OUT, PTK0_IN_PU),
+
+ /* PTL GPIO */
+ PINMUX_DATA(PTL7_DATA, PTL7_IN, PTL7_OUT, PTL7_IN_PU),
+ PINMUX_DATA(PTL6_DATA, PTL6_IN, PTL6_OUT, PTL6_IN_PU),
+ PINMUX_DATA(PTL5_DATA, PTL5_IN, PTL5_OUT, PTL5_IN_PU),
+ PINMUX_DATA(PTL4_DATA, PTL4_IN, PTL4_OUT, PTL4_IN_PU),
+ PINMUX_DATA(PTL3_DATA, PTL3_IN, PTL3_OUT, PTL3_IN_PU),
+ PINMUX_DATA(PTL2_DATA, PTL2_IN, PTL2_OUT, PTL2_IN_PU),
+ PINMUX_DATA(PTL1_DATA, PTL1_IN, PTL1_OUT, PTL1_IN_PU),
+ PINMUX_DATA(PTL0_DATA, PTL0_IN, PTL0_OUT, PTL0_IN_PU),
+
+ /* PTM GPIO */
+ PINMUX_DATA(PTM7_DATA, PTM7_IN, PTM7_OUT, PTM7_IN_PU),
+ PINMUX_DATA(PTM6_DATA, PTM6_IN, PTM6_OUT, PTM6_IN_PU),
+ PINMUX_DATA(PTM5_DATA, PTM5_IN, PTM5_OUT, PTM5_IN_PU),
+ PINMUX_DATA(PTM4_DATA, PTM4_IN, PTM4_OUT, PTM4_IN_PU),
+ PINMUX_DATA(PTM3_DATA, PTM3_IN, PTM3_OUT, PTM3_IN_PU),
+ PINMUX_DATA(PTM2_DATA, PTM2_IN, PTM2_OUT, PTM2_IN_PU),
+ PINMUX_DATA(PTM1_DATA, PTM1_IN, PTM1_OUT, PTM1_IN_PU),
+ PINMUX_DATA(PTM0_DATA, PTM0_IN, PTM0_OUT, PTM0_IN_PU),
+
+ /* PTN GPIO */
+ PINMUX_DATA(PTN7_DATA, PTN7_IN, PTN7_OUT, PTN7_IN_PU),
+ PINMUX_DATA(PTN6_DATA, PTN6_IN, PTN6_OUT, PTN6_IN_PU),
+ PINMUX_DATA(PTN5_DATA, PTN5_IN, PTN5_OUT, PTN5_IN_PU),
+ PINMUX_DATA(PTN4_DATA, PTN4_IN, PTN4_OUT, PTN4_IN_PU),
+ PINMUX_DATA(PTN3_DATA, PTN3_IN, PTN3_OUT, PTN3_IN_PU),
+ PINMUX_DATA(PTN2_DATA, PTN2_IN, PTN2_OUT, PTN2_IN_PU),
+ PINMUX_DATA(PTN1_DATA, PTN1_IN, PTN1_OUT, PTN1_IN_PU),
+ PINMUX_DATA(PTN0_DATA, PTN0_IN, PTN0_OUT, PTN0_IN_PU),
+
+ /* PTQ GPIO */
+ PINMUX_DATA(PTQ7_DATA, PTQ7_IN, PTQ7_OUT, PTQ7_IN_PU),
+ PINMUX_DATA(PTQ6_DATA, PTQ6_IN, PTQ6_OUT, PTQ6_IN_PU),
+ PINMUX_DATA(PTQ5_DATA, PTQ5_IN, PTQ5_OUT, PTQ5_IN_PU),
+ PINMUX_DATA(PTQ4_DATA, PTQ4_IN, PTQ4_OUT, PTQ4_IN_PU),
+ PINMUX_DATA(PTQ3_DATA, PTQ3_IN, PTQ3_OUT, PTQ3_IN_PU),
+ PINMUX_DATA(PTQ2_DATA, PTQ2_IN, PTQ2_OUT, PTQ2_IN_PU),
+ PINMUX_DATA(PTQ1_DATA, PTQ1_IN, PTQ1_OUT, PTQ1_IN_PU),
+ PINMUX_DATA(PTQ0_DATA, PTQ0_IN, PTQ0_OUT, PTQ0_IN_PU),
+
+ /* PTR GPIO */
+ PINMUX_DATA(PTR7_DATA, PTR7_IN, PTR7_OUT, PTR7_IN_PU),
+ PINMUX_DATA(PTR6_DATA, PTR6_IN, PTR6_OUT, PTR6_IN_PU),
+ PINMUX_DATA(PTR5_DATA, PTR5_IN, PTR5_OUT, PTR5_IN_PU),
+ PINMUX_DATA(PTR4_DATA, PTR4_IN, PTR4_OUT, PTR4_IN_PU),
+ PINMUX_DATA(PTR3_DATA, PTR3_IN, PTR3_IN_PU),
+ PINMUX_DATA(PTR2_DATA, PTR2_IN, PTR2_IN_PU),
+ PINMUX_DATA(PTR1_DATA, PTR1_IN, PTR1_OUT, PTR1_IN_PU),
+ PINMUX_DATA(PTR0_DATA, PTR0_IN, PTR0_OUT, PTR0_IN_PU),
+
+ /* PTS GPIO */
+ PINMUX_DATA(PTS6_DATA, PTS6_IN, PTS6_OUT, PTS6_IN_PU),
+ PINMUX_DATA(PTS5_DATA, PTS5_IN, PTS5_OUT, PTS5_IN_PU),
+ PINMUX_DATA(PTS4_DATA, PTS4_IN, PTS4_OUT, PTS4_IN_PU),
+ PINMUX_DATA(PTS3_DATA, PTS3_IN, PTS3_OUT, PTS3_IN_PU),
+ PINMUX_DATA(PTS2_DATA, PTS2_IN, PTS2_OUT, PTS2_IN_PU),
+ PINMUX_DATA(PTS1_DATA, PTS1_IN, PTS1_OUT, PTS1_IN_PU),
+ PINMUX_DATA(PTS0_DATA, PTS0_IN, PTS0_OUT, PTS0_IN_PU),
+
+ /* PTT GPIO */
+ PINMUX_DATA(PTT7_DATA, PTT7_IN, PTT7_OUT, PTT7_IN_PU),
+ PINMUX_DATA(PTT6_DATA, PTT6_IN, PTT6_OUT, PTT6_IN_PU),
+ PINMUX_DATA(PTT5_DATA, PTT5_IN, PTT5_OUT, PTT5_IN_PU),
+ PINMUX_DATA(PTT4_DATA, PTT4_IN, PTT4_OUT, PTT4_IN_PU),
+ PINMUX_DATA(PTT3_DATA, PTT3_IN, PTT3_OUT, PTT3_IN_PU),
+ PINMUX_DATA(PTT2_DATA, PTT2_IN, PTT2_OUT, PTT2_IN_PU),
+ PINMUX_DATA(PTT1_DATA, PTT1_IN, PTT1_OUT, PTT1_IN_PU),
+ PINMUX_DATA(PTT0_DATA, PTT0_IN, PTT0_OUT, PTT0_IN_PU),
+
+ /* PTU GPIO */
+ PINMUX_DATA(PTU7_DATA, PTU7_IN, PTU7_OUT, PTU7_IN_PU),
+ PINMUX_DATA(PTU6_DATA, PTU6_IN, PTU6_OUT, PTU6_IN_PU),
+ PINMUX_DATA(PTU5_DATA, PTU5_IN, PTU5_OUT, PTU5_IN_PU),
+ PINMUX_DATA(PTU4_DATA, PTU4_IN, PTU4_OUT, PTU4_IN_PU),
+ PINMUX_DATA(PTU3_DATA, PTU3_IN, PTU3_OUT, PTU3_IN_PU),
+ PINMUX_DATA(PTU2_DATA, PTU2_IN, PTU2_OUT, PTU2_IN_PU),
+ PINMUX_DATA(PTU1_DATA, PTU1_IN, PTU1_OUT, PTU1_IN_PU),
+ PINMUX_DATA(PTU0_DATA, PTU0_IN, PTU0_OUT, PTU0_IN_PU),
+
+ /* PTV GPIO */
+ PINMUX_DATA(PTV7_DATA, PTV7_IN, PTV7_OUT, PTV7_IN_PU),
+ PINMUX_DATA(PTV6_DATA, PTV6_IN, PTV6_OUT, PTV6_IN_PU),
+ PINMUX_DATA(PTV5_DATA, PTV5_IN, PTV5_OUT, PTV5_IN_PU),
+ PINMUX_DATA(PTV4_DATA, PTV4_IN, PTV4_OUT, PTV4_IN_PU),
+ PINMUX_DATA(PTV3_DATA, PTV3_IN, PTV3_OUT, PTV3_IN_PU),
+ PINMUX_DATA(PTV2_DATA, PTV2_IN, PTV2_OUT, PTV2_IN_PU),
+ PINMUX_DATA(PTV1_DATA, PTV1_IN, PTV1_OUT, PTV1_IN_PU),
+ PINMUX_DATA(PTV0_DATA, PTV0_IN, PTV0_OUT, PTV0_IN_PU),
+
+ /* PTW GPIO */
+ PINMUX_DATA(PTW7_DATA, PTW7_IN, PTW7_OUT, PTW7_IN_PU),
+ PINMUX_DATA(PTW6_DATA, PTW6_IN, PTW6_OUT, PTW6_IN_PU),
+ PINMUX_DATA(PTW5_DATA, PTW5_IN, PTW5_OUT, PTW5_IN_PU),
+ PINMUX_DATA(PTW4_DATA, PTW4_IN, PTW4_OUT, PTW4_IN_PU),
+ PINMUX_DATA(PTW3_DATA, PTW3_IN, PTW3_OUT, PTW3_IN_PU),
+ PINMUX_DATA(PTW2_DATA, PTW2_IN, PTW2_OUT, PTW2_IN_PU),
+ PINMUX_DATA(PTW1_DATA, PTW1_IN, PTW1_OUT, PTW1_IN_PU),
+ PINMUX_DATA(PTW0_DATA, PTW0_IN, PTW0_OUT, PTW0_IN_PU),
+
+ /* PTX GPIO */
+ PINMUX_DATA(PTX7_DATA, PTX7_IN, PTX7_OUT, PTX7_IN_PU),
+ PINMUX_DATA(PTX6_DATA, PTX6_IN, PTX6_OUT, PTX6_IN_PU),
+ PINMUX_DATA(PTX5_DATA, PTX5_IN, PTX5_OUT, PTX5_IN_PU),
+ PINMUX_DATA(PTX4_DATA, PTX4_IN, PTX4_OUT, PTX4_IN_PU),
+ PINMUX_DATA(PTX3_DATA, PTX3_IN, PTX3_OUT, PTX3_IN_PU),
+ PINMUX_DATA(PTX2_DATA, PTX2_IN, PTX2_OUT, PTX2_IN_PU),
+ PINMUX_DATA(PTX1_DATA, PTX1_IN, PTX1_OUT, PTX1_IN_PU),
+ PINMUX_DATA(PTX0_DATA, PTX0_IN, PTX0_OUT, PTX0_IN_PU),
+
+ /* PTY GPIO */
+ PINMUX_DATA(PTY7_DATA, PTY7_IN, PTY7_OUT, PTY7_IN_PU),
+ PINMUX_DATA(PTY6_DATA, PTY6_IN, PTY6_OUT, PTY6_IN_PU),
+ PINMUX_DATA(PTY5_DATA, PTY5_IN, PTY5_OUT, PTY5_IN_PU),
+ PINMUX_DATA(PTY4_DATA, PTY4_IN, PTY4_OUT, PTY4_IN_PU),
+ PINMUX_DATA(PTY3_DATA, PTY3_IN, PTY3_OUT, PTY3_IN_PU),
+ PINMUX_DATA(PTY2_DATA, PTY2_IN, PTY2_OUT, PTY2_IN_PU),
+ PINMUX_DATA(PTY1_DATA, PTY1_IN, PTY1_OUT, PTY1_IN_PU),
+ PINMUX_DATA(PTY0_DATA, PTY0_IN, PTY0_OUT, PTY0_IN_PU),
+
+ /* PTZ GPIO */
+ PINMUX_DATA(PTZ7_DATA, PTZ7_IN, PTZ7_OUT, PTZ7_IN_PU),
+ PINMUX_DATA(PTZ6_DATA, PTZ6_IN, PTZ6_OUT, PTZ6_IN_PU),
+ PINMUX_DATA(PTZ5_DATA, PTZ5_IN, PTZ5_OUT, PTZ5_IN_PU),
+ PINMUX_DATA(PTZ4_DATA, PTZ4_IN, PTZ4_OUT, PTZ4_IN_PU),
+ PINMUX_DATA(PTZ3_DATA, PTZ3_IN, PTZ3_OUT, PTZ3_IN_PU),
+ PINMUX_DATA(PTZ2_DATA, PTZ2_IN, PTZ2_OUT, PTZ2_IN_PU),
+ PINMUX_DATA(PTZ1_DATA, PTZ1_IN, PTZ1_OUT, PTZ1_IN_PU),
+ PINMUX_DATA(PTZ0_DATA, PTZ0_IN, PTZ0_OUT, PTZ0_IN_PU),
+
+ /* PTA FN */
+ PINMUX_DATA(D23_MARK, PSA15_0, PSA14_0, PTA7_FN),
+ PINMUX_DATA(D22_MARK, PSA15_0, PSA14_0, PTA6_FN),
+ PINMUX_DATA(D21_MARK, PSA15_0, PSA14_0, PTA5_FN),
+ PINMUX_DATA(D20_MARK, PSA15_0, PSA14_0, PTA4_FN),
+ PINMUX_DATA(D19_MARK, PSA15_0, PSA14_0, PTA3_FN),
+ PINMUX_DATA(D18_MARK, PSA15_0, PSA14_0, PTA2_FN),
+ PINMUX_DATA(D17_MARK, PSA15_0, PSA14_0, PTA1_FN),
+ PINMUX_DATA(D16_MARK, PSA15_0, PSA14_0, PTA0_FN),
+
+ PINMUX_DATA(KEYOUT2_MARK, PSA15_0, PSA14_1, PTA7_FN),
+ PINMUX_DATA(KEYOUT1_MARK, PSA15_0, PSA14_1, PTA6_FN),
+ PINMUX_DATA(KEYOUT0_MARK, PSA15_0, PSA14_1, PTA5_FN),
+ PINMUX_DATA(KEYIN4_MARK, PSA15_0, PSA14_1, PTA4_FN),
+ PINMUX_DATA(KEYIN3_MARK, PSA15_0, PSA14_1, PTA3_FN),
+ PINMUX_DATA(KEYIN2_MARK, PSA15_0, PSA14_1, PTA2_FN),
+ PINMUX_DATA(KEYIN1_MARK, PSA15_0, PSA14_1, PTA1_FN),
+ PINMUX_DATA(KEYIN0_MARK, PSA15_0, PSA14_1, PTA0_FN),
+
+ PINMUX_DATA(IDED15_MARK, PSA15_1, PSA14_0, PTA7_FN),
+ PINMUX_DATA(IDED14_MARK, PSA15_1, PSA14_0, PTA6_FN),
+ PINMUX_DATA(IDED13_MARK, PSA15_1, PSA14_0, PTA5_FN),
+ PINMUX_DATA(IDED12_MARK, PSA15_1, PSA14_0, PTA4_FN),
+ PINMUX_DATA(IDED11_MARK, PSA15_1, PSA14_0, PTA3_FN),
+ PINMUX_DATA(IDED10_MARK, PSA15_1, PSA14_0, PTA2_FN),
+ PINMUX_DATA(IDED9_MARK, PSA15_1, PSA14_0, PTA1_FN),
+ PINMUX_DATA(IDED8_MARK, PSA15_1, PSA14_0, PTA0_FN),
+
+ /* PTB FN */
+ PINMUX_DATA(D31_MARK, PSE15_0, PSE14_0, PTB7_FN),
+ PINMUX_DATA(D30_MARK, PSE15_0, PSE14_0, PTB6_FN),
+ PINMUX_DATA(D29_MARK, PSE11_0, PTB5_FN),
+ PINMUX_DATA(D28_MARK, PSE11_0, PTB4_FN),
+ PINMUX_DATA(D27_MARK, PSE11_0, PTB3_FN),
+ PINMUX_DATA(D26_MARK, PSA15_0, PSA14_0, PTB2_FN),
+ PINMUX_DATA(D25_MARK, PSA15_0, PSA14_0, PTB1_FN),
+ PINMUX_DATA(D24_MARK, PSA15_0, PSA14_0, PTB0_FN),
+
+ PINMUX_DATA(IDEA1_MARK, PSE15_1, PSE14_0, PTB7_FN),
+ PINMUX_DATA(IDEA0_MARK, PSE15_1, PSE14_0, PTB6_FN),
+ PINMUX_DATA(IODREQ_MARK, PSE11_1, PTB5_FN),
+ PINMUX_DATA(IDECS0_MARK, PSE11_1, PTB4_FN),
+ PINMUX_DATA(IDECS1_MARK, PSE11_1, PTB3_FN),
+ PINMUX_DATA(IDEIORD_MARK, PSA15_1, PSA14_0, PTB2_FN),
+ PINMUX_DATA(IDEIOWR_MARK, PSA15_1, PSA14_0, PTB1_FN),
+ PINMUX_DATA(IDEINT_MARK, PSA15_1, PSA14_0, PTB0_FN),
+
+ PINMUX_DATA(TPUTO1_MARK, PSE15_0, PSE14_1, PTB7_FN),
+ PINMUX_DATA(TPUTO0_MARK, PSE15_0, PSE14_1, PTB6_FN),
+
+ PINMUX_DATA(KEYOUT5_IN5_MARK, PSA15_0, PSA14_1, PTB2_FN),
+ PINMUX_DATA(KEYOUT4_IN6_MARK, PSA15_0, PSA14_1, PTB1_FN),
+ PINMUX_DATA(KEYOUT3_MARK, PSA15_0, PSA14_1, PTB0_FN),
+
+ /* PTC FN */
+ PINMUX_DATA(LCDD7_MARK, PSD5_0, PTC7_FN),
+ PINMUX_DATA(LCDD6_MARK, PSD5_0, PTC6_FN),
+ PINMUX_DATA(LCDD5_MARK, PSD5_0, PTC5_FN),
+ PINMUX_DATA(LCDD4_MARK, PSD5_0, PTC4_FN),
+ PINMUX_DATA(LCDD3_MARK, PSD5_0, PTC3_FN),
+ PINMUX_DATA(LCDD2_MARK, PSD5_0, PTC2_FN),
+ PINMUX_DATA(LCDD1_MARK, PSD5_0, PTC1_FN),
+ PINMUX_DATA(LCDD0_MARK, PSD5_0, PTC0_FN),
+
+ /* PTD FN */
+ PINMUX_DATA(LCDD15_MARK, PSD5_0, PTD7_FN),
+ PINMUX_DATA(LCDD14_MARK, PSD5_0, PTD6_FN),
+ PINMUX_DATA(LCDD13_MARK, PSD5_0, PTD5_FN),
+ PINMUX_DATA(LCDD12_MARK, PSD5_0, PTD4_FN),
+ PINMUX_DATA(LCDD11_MARK, PSD5_0, PTD3_FN),
+ PINMUX_DATA(LCDD10_MARK, PSD5_0, PTD2_FN),
+ PINMUX_DATA(LCDD9_MARK, PSD5_0, PTD1_FN),
+ PINMUX_DATA(LCDD8_MARK, PSD5_0, PTD0_FN),
+
+ /* PTE FN */
+ PINMUX_DATA(FSIMCKB_MARK, PTE7_FN),
+ PINMUX_DATA(FSIMCKA_MARK, PTE6_FN),
+
+ PINMUX_DATA(LCDD21_MARK, PSC5_0, PSC4_0, PTE5_FN),
+ PINMUX_DATA(LCDD20_MARK, PSD3_0, PSD2_0, PTE4_FN),
+ PINMUX_DATA(LCDD19_MARK, PSA3_0, PSA2_0, PTE3_FN),
+ PINMUX_DATA(LCDD18_MARK, PSA3_0, PSA2_0, PTE2_FN),
+ PINMUX_DATA(LCDD17_MARK, PSD5_0, PTE1_FN),
+ PINMUX_DATA(LCDD16_MARK, PSD5_0, PTE0_FN),
+
+ PINMUX_DATA(SCIF2_L_TXD_MARK, PSC5_0, PSC4_1, PTE5_FN),
+ PINMUX_DATA(SCIF4_SCK_MARK, PSD3_0, PSD2_1, PTE4_FN),
+ PINMUX_DATA(SCIF4_RXD_MARK, PSA3_0, PSA2_1, PTE3_FN),
+ PINMUX_DATA(SCIF4_TXD_MARK, PSA3_0, PSA2_1, PTE2_FN),
+
+ /* PTF FN */
+ PINMUX_DATA(LCDVSYN_MARK, PSD8_0, PTF7_FN),
+ PINMUX_DATA(LCDDISP_MARK, PSD10_0, PSD9_0, PTF6_FN),
+ PINMUX_DATA(LCDHSYN_MARK, PSD10_0, PSD9_0, PTF5_FN),
+ PINMUX_DATA(LCDDON_MARK, PSD8_0, PTF4_FN),
+ PINMUX_DATA(LCDDCK_MARK, PSD10_0, PSD9_0, PTF3_FN),
+ PINMUX_DATA(LCDVEPWC_MARK, PSA6_0, PTF2_FN),
+ PINMUX_DATA(LCDD23_MARK, PSC7_0, PSC6_0, PTF1_FN),
+ PINMUX_DATA(LCDD22_MARK, PSC5_0, PSC4_0, PTF0_FN),
+
+ PINMUX_DATA(LCDRS_MARK, PSD10_0, PSD9_1, PTF6_FN),
+ PINMUX_DATA(LCDCS_MARK, PSD10_0, PSD9_1, PTF5_FN),
+ PINMUX_DATA(LCDWR_MARK, PSD10_0, PSD9_1, PTF3_FN),
+
+ PINMUX_DATA(SCIF0_TXD_MARK, PSA6_1, PTF2_FN),
+ PINMUX_DATA(SCIF2_L_SCK_MARK, PSC7_0, PSC6_1, PTF1_FN),
+ PINMUX_DATA(SCIF2_L_RXD_MARK, PSC5_0, PSC4_1, PTF0_FN),
+
+ /* PTG FN */
+ PINMUX_DATA(AUDCK_MARK, PTG5_FN),
+ PINMUX_DATA(AUDSYNC_MARK, PTG4_FN),
+ PINMUX_DATA(AUDATA3_MARK, PTG3_FN),
+ PINMUX_DATA(AUDATA2_MARK, PTG2_FN),
+ PINMUX_DATA(AUDATA1_MARK, PTG1_FN),
+ PINMUX_DATA(AUDATA0_MARK, PTG0_FN),
+
+ /* PTH FN */
+ PINMUX_DATA(VIO0_VD_MARK, PTH7_FN),
+ PINMUX_DATA(VIO0_CLK_MARK, PTH6_FN),
+ PINMUX_DATA(VIO0_D7_MARK, PTH5_FN),
+ PINMUX_DATA(VIO0_D6_MARK, PTH4_FN),
+ PINMUX_DATA(VIO0_D5_MARK, PTH3_FN),
+ PINMUX_DATA(VIO0_D4_MARK, PTH2_FN),
+ PINMUX_DATA(VIO0_D3_MARK, PTH1_FN),
+ PINMUX_DATA(VIO0_D2_MARK, PTH0_FN),
+
+ /* PTJ FN */
+ PINMUX_DATA(PDSTATUS_MARK, PTJ7_FN),
+ PINMUX_DATA(STATUS2_MARK, PTJ6_FN),
+ PINMUX_DATA(STATUS0_MARK, PTJ5_FN),
+ PINMUX_DATA(A25_MARK, PSA8_0, PTJ3_FN),
+ PINMUX_DATA(BS_MARK, PSA8_1, PTJ3_FN),
+ PINMUX_DATA(A24_MARK, PTJ2_FN),
+ PINMUX_DATA(A23_MARK, PTJ1_FN),
+ PINMUX_DATA(A22_MARK, PTJ0_FN),
+
+ /* PTK FN */
+ PINMUX_DATA(VIO1_D5_MARK, PSB7_0, PSB6_0, PTK7_FN),
+ PINMUX_DATA(VIO1_D4_MARK, PSB7_0, PSB6_0, PTK6_FN),
+ PINMUX_DATA(VIO1_D3_MARK, PSB7_0, PSB6_0, PTK5_FN),
+ PINMUX_DATA(VIO1_D2_MARK, PSB7_0, PSB6_0, PTK4_FN),
+ PINMUX_DATA(VIO1_D1_MARK, PSB7_0, PSB6_0, PTK3_FN),
+ PINMUX_DATA(VIO1_D0_MARK, PSB7_0, PSB6_0, PTK2_FN),
+
+ PINMUX_DATA(VIO0_D13_MARK, PSB7_0, PSB6_1, PTK7_FN),
+ PINMUX_DATA(VIO0_D12_MARK, PSB7_0, PSB6_1, PTK6_FN),
+ PINMUX_DATA(VIO0_D11_MARK, PSB7_0, PSB6_1, PTK5_FN),
+ PINMUX_DATA(VIO0_D10_MARK, PSB7_0, PSB6_1, PTK4_FN),
+ PINMUX_DATA(VIO0_D9_MARK, PSB7_0, PSB6_1, PTK3_FN),
+ PINMUX_DATA(VIO0_D8_MARK, PSB7_0, PSB6_1, PTK2_FN),
+
+ PINMUX_DATA(IDED5_MARK, PSB7_1, PSB6_0, PTK7_FN),
+ PINMUX_DATA(IDED4_MARK, PSB7_1, PSB6_0, PTK6_FN),
+ PINMUX_DATA(IDED3_MARK, PSB7_1, PSB6_0, PTK5_FN),
+ PINMUX_DATA(IDED2_MARK, PSB7_1, PSB6_0, PTK4_FN),
+ PINMUX_DATA(IDED1_MARK, PSB7_1, PSB6_0, PTK3_FN),
+ PINMUX_DATA(IDED0_MARK, PSB7_1, PSB6_0, PTK2_FN),
+
+ PINMUX_DATA(VIO0_FLD_MARK, PTK1_FN),
+ PINMUX_DATA(VIO0_HD_MARK, PTK0_FN),
+
+ /* PTL FN */
+ PINMUX_DATA(DV_D5_MARK, PSB9_0, PSB8_0, PTL7_FN),
+ PINMUX_DATA(DV_D4_MARK, PSB9_0, PSB8_0, PTL6_FN),
+ PINMUX_DATA(DV_D3_MARK, PSE7_0, PSE6_0, PTL5_FN),
+ PINMUX_DATA(DV_D2_MARK, PSC9_0, PSC8_0, PTL4_FN),
+ PINMUX_DATA(DV_D1_MARK, PSC9_0, PSC8_0, PTL3_FN),
+ PINMUX_DATA(DV_D0_MARK, PSC9_0, PSC8_0, PTL2_FN),
+ PINMUX_DATA(DV_D15_MARK, PSD4_0, PTL1_FN),
+ PINMUX_DATA(DV_D14_MARK, PSE5_0, PSE4_0, PTL0_FN),
+
+ PINMUX_DATA(SCIF3_V_SCK_MARK, PSB9_0, PSB8_1, PTL7_FN),
+ PINMUX_DATA(SCIF3_V_RXD_MARK, PSB9_0, PSB8_1, PTL6_FN),
+ PINMUX_DATA(SCIF3_V_TXD_MARK, PSE7_0, PSE6_1, PTL5_FN),
+ PINMUX_DATA(SCIF1_SCK_MARK, PSC9_0, PSC8_1, PTL4_FN),
+ PINMUX_DATA(SCIF1_RXD_MARK, PSC9_0, PSC8_1, PTL3_FN),
+ PINMUX_DATA(SCIF1_TXD_MARK, PSC9_0, PSC8_1, PTL2_FN),
+
+ PINMUX_DATA(RMII_RXD0_MARK, PSB9_1, PSB8_0, PTL7_FN),
+ PINMUX_DATA(RMII_RXD1_MARK, PSB9_1, PSB8_0, PTL6_FN),
+ PINMUX_DATA(RMII_REF_CLK_MARK, PSE7_1, PSE6_0, PTL5_FN),
+ PINMUX_DATA(RMII_TX_EN_MARK, PSC9_1, PSC8_0, PTL4_FN),
+ PINMUX_DATA(RMII_TXD0_MARK, PSC9_1, PSC8_0, PTL3_FN),
+ PINMUX_DATA(RMII_TXD1_MARK, PSC9_1, PSC8_0, PTL2_FN),
+
+ PINMUX_DATA(MSIOF0_MCK_MARK, PSE5_0, PSE4_1, PTL0_FN),
+
+ /* PTM FN */
+ PINMUX_DATA(DV_D13_MARK, PSC13_0, PSC12_0, PTM7_FN),
+ PINMUX_DATA(DV_D12_MARK, PSC13_0, PSC12_0, PTM6_FN),
+ PINMUX_DATA(DV_D11_MARK, PSC13_0, PSC12_0, PTM5_FN),
+ PINMUX_DATA(DV_D10_MARK, PSC13_0, PSC12_0, PTM4_FN),
+ PINMUX_DATA(DV_D9_MARK, PSC11_0, PSC10_0, PTM3_FN),
+ PINMUX_DATA(DV_D8_MARK, PSC11_0, PSC10_0, PTM2_FN),
+
+ PINMUX_DATA(MSIOF0_TSCK_MARK, PSC13_0, PSC12_1, PTM7_FN),
+ PINMUX_DATA(MSIOF0_RXD_MARK, PSC13_0, PSC12_1, PTM6_FN),
+ PINMUX_DATA(MSIOF0_TXD_MARK, PSC13_0, PSC12_1, PTM5_FN),
+ PINMUX_DATA(MSIOF0_TSYNC_MARK, PSC13_0, PSC12_1, PTM4_FN),
+ PINMUX_DATA(MSIOF0_SS1_MARK, PSC11_0, PSC10_1, PTM3_FN),
+ PINMUX_DATA(MSIOF0_RSCK_MARK, PSC11_1, PSC10_0, PTM3_FN),
+ PINMUX_DATA(MSIOF0_SS2_MARK, PSC11_0, PSC10_1, PTM2_FN),
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PSC11_1, PSC10_0, PTM2_FN),
+
+ PINMUX_DATA(LCDVCPWC_MARK, PSA6_0, PTM1_FN),
+ PINMUX_DATA(LCDRD_MARK, PSA7_0, PTM0_FN),
+
+ PINMUX_DATA(SCIF0_RXD_MARK, PSA6_1, PTM1_FN),
+ PINMUX_DATA(SCIF0_SCK_MARK, PSA7_1, PTM0_FN),
+
+ /* PTN FN */
+ PINMUX_DATA(VIO0_D1_MARK, PTN7_FN),
+ PINMUX_DATA(VIO0_D0_MARK, PTN6_FN),
+
+ PINMUX_DATA(DV_CLKI_MARK, PSD11_0, PTN5_FN),
+ PINMUX_DATA(DV_CLK_MARK, PSD13_0, PSD12_0, PTN4_FN),
+ PINMUX_DATA(DV_VSYNC_MARK, PSD15_0, PSD14_0, PTN3_FN),
+ PINMUX_DATA(DV_HSYNC_MARK, PSB5_0, PSB4_0, PTN2_FN),
+ PINMUX_DATA(DV_D7_MARK, PSB3_0, PSB2_0, PTN1_FN),
+ PINMUX_DATA(DV_D6_MARK, PSB1_0, PSB0_0, PTN0_FN),
+
+ PINMUX_DATA(SCIF2_V_SCK_MARK, PSD13_0, PSD12_1, PTN4_FN),
+ PINMUX_DATA(SCIF2_V_RXD_MARK, PSD15_0, PSD14_1, PTN3_FN),
+ PINMUX_DATA(SCIF2_V_TXD_MARK, PSB5_0, PSB4_1, PTN2_FN),
+ PINMUX_DATA(SCIF3_V_CTS_MARK, PSB3_0, PSB2_1, PTN1_FN),
+ PINMUX_DATA(SCIF3_V_RTS_MARK, PSB1_0, PSB0_1, PTN0_FN),
+
+ PINMUX_DATA(RMII_RX_ER_MARK, PSB3_1, PSB2_0, PTN1_FN),
+ PINMUX_DATA(RMII_CRS_DV_MARK, PSB1_1, PSB0_0, PTN0_FN),
+
+ /* PTQ FN */
+ PINMUX_DATA(D7_MARK, PTQ7_FN),
+ PINMUX_DATA(D6_MARK, PTQ6_FN),
+ PINMUX_DATA(D5_MARK, PTQ5_FN),
+ PINMUX_DATA(D4_MARK, PTQ4_FN),
+ PINMUX_DATA(D3_MARK, PTQ3_FN),
+ PINMUX_DATA(D2_MARK, PTQ2_FN),
+ PINMUX_DATA(D1_MARK, PTQ1_FN),
+ PINMUX_DATA(D0_MARK, PTQ0_FN),
+
+ /* PTR FN */
+ PINMUX_DATA(CS6B_CE1B_MARK, PTR7_FN),
+ PINMUX_DATA(CS6A_CE2B_MARK, PTR6_FN),
+ PINMUX_DATA(CS5B_CE1A_MARK, PTR5_FN),
+ PINMUX_DATA(CS5A_CE2A_MARK, PTR4_FN),
+ PINMUX_DATA(IOIS16_MARK, PSA5_0, PTR3_FN),
+ PINMUX_DATA(WAIT_MARK, PTR2_FN),
+ PINMUX_DATA(WE3_ICIOWR_MARK, PSA1_0, PSA0_0, PTR1_FN),
+ PINMUX_DATA(WE2_ICIORD_MARK, PSD1_0, PSD0_0, PTR0_FN),
+
+ PINMUX_DATA(LCDLCLK_MARK, PSA5_1, PTR3_FN),
+
+ PINMUX_DATA(IDEA2_MARK, PSD1_1, PSD0_0, PTR0_FN),
+
+ PINMUX_DATA(TPUTO3_MARK, PSA1_0, PSA0_1, PTR1_FN),
+ PINMUX_DATA(TPUTI3_MARK, PSA1_1, PSA0_0, PTR1_FN),
+ PINMUX_DATA(TPUTO2_MARK, PSD1_0, PSD0_1, PTR0_FN),
+
+ /* PTS FN */
+ PINMUX_DATA(VIO_CKO_MARK, PTS6_FN),
+
+ PINMUX_DATA(TPUTI2_MARK, PSE9_0, PSE8_1, PTS5_FN),
+
+ PINMUX_DATA(IDEIORDY_MARK, PSE9_1, PSE8_0, PTS5_FN),
+
+ PINMUX_DATA(VIO1_FLD_MARK, PSE9_0, PSE8_0, PTS5_FN),
+ PINMUX_DATA(VIO1_HD_MARK, PSA10_0, PTS4_FN),
+ PINMUX_DATA(VIO1_VD_MARK, PSA9_0, PTS3_FN),
+ PINMUX_DATA(VIO1_CLK_MARK, PSA9_0, PTS2_FN),
+ PINMUX_DATA(VIO1_D7_MARK, PSB7_0, PSB6_0, PTS1_FN),
+ PINMUX_DATA(VIO1_D6_MARK, PSB7_0, PSB6_0, PTS0_FN),
+
+ PINMUX_DATA(SCIF5_SCK_MARK, PSA10_1, PTS4_FN),
+ PINMUX_DATA(SCIF5_RXD_MARK, PSA9_1, PTS3_FN),
+ PINMUX_DATA(SCIF5_TXD_MARK, PSA9_1, PTS2_FN),
+
+ PINMUX_DATA(VIO0_D15_MARK, PSB7_0, PSB6_1, PTS1_FN),
+ PINMUX_DATA(VIO0_D14_MARK, PSB7_0, PSB6_1, PTS0_FN),
+
+ PINMUX_DATA(IDED7_MARK, PSB7_1, PSB6_0, PTS1_FN),
+ PINMUX_DATA(IDED6_MARK, PSB7_1, PSB6_0, PTS0_FN),
+
+ /* PTT FN */
+ PINMUX_DATA(D15_MARK, PTT7_FN),
+ PINMUX_DATA(D14_MARK, PTT6_FN),
+ PINMUX_DATA(D13_MARK, PTT5_FN),
+ PINMUX_DATA(D12_MARK, PTT4_FN),
+ PINMUX_DATA(D11_MARK, PTT3_FN),
+ PINMUX_DATA(D10_MARK, PTT2_FN),
+ PINMUX_DATA(D9_MARK, PTT1_FN),
+ PINMUX_DATA(D8_MARK, PTT0_FN),
+
+ /* PTU FN */
+ PINMUX_DATA(DMAC_DACK0_MARK, PTU7_FN),
+ PINMUX_DATA(DMAC_DREQ0_MARK, PTU6_FN),
+
+ PINMUX_DATA(FSIOASD_MARK, PSE1_0, PTU5_FN),
+ PINMUX_DATA(FSIIABCK_MARK, PSE1_0, PTU4_FN),
+ PINMUX_DATA(FSIIALRCK_MARK, PSE1_0, PTU3_FN),
+ PINMUX_DATA(FSIOABCK_MARK, PSE1_0, PTU2_FN),
+ PINMUX_DATA(FSIOALRCK_MARK, PSE1_0, PTU1_FN),
+ PINMUX_DATA(CLKAUDIOAO_MARK, PSE0_0, PTU0_FN),
+
+ /* PTV FN */
+ PINMUX_DATA(FSIIBSD_MARK, PSD7_0, PSD6_0, PTV7_FN),
+ PINMUX_DATA(FSIOBSD_MARK, PSD7_0, PSD6_0, PTV6_FN),
+ PINMUX_DATA(FSIIBBCK_MARK, PSC15_0, PSC14_0, PTV5_FN),
+ PINMUX_DATA(FSIIBLRCK_MARK, PSC15_0, PSC14_0, PTV4_FN),
+ PINMUX_DATA(FSIOBBCK_MARK, PSC15_0, PSC14_0, PTV3_FN),
+ PINMUX_DATA(FSIOBLRCK_MARK, PSC15_0, PSC14_0, PTV2_FN),
+ PINMUX_DATA(CLKAUDIOBO_MARK, PSE3_0, PSE2_0, PTV1_FN),
+ PINMUX_DATA(FSIIASD_MARK, PSE10_0, PTV0_FN),
+
+ PINMUX_DATA(MSIOF1_SS2_MARK, PSD7_0, PSD6_1, PTV7_FN),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PSD7_1, PSD6_0, PTV7_FN),
+ PINMUX_DATA(MSIOF1_SS1_MARK, PSD7_0, PSD6_1, PTV6_FN),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PSD7_1, PSD6_0, PTV6_FN),
+ PINMUX_DATA(MSIOF1_RXD_MARK, PSC15_0, PSC14_1, PTV5_FN),
+ PINMUX_DATA(MSIOF1_TSYNC_MARK, PSC15_0, PSC14_1, PTV4_FN),
+ PINMUX_DATA(MSIOF1_TSCK_MARK, PSC15_0, PSC14_1, PTV3_FN),
+ PINMUX_DATA(MSIOF1_TXD_MARK, PSC15_0, PSC14_1, PTV2_FN),
+ PINMUX_DATA(MSIOF1_MCK_MARK, PSE3_0, PSE2_1, PTV1_FN),
+
+ /* PTW FN */
+ PINMUX_DATA(MMC_D7_MARK, PSE13_0, PSE12_0, PTW7_FN),
+ PINMUX_DATA(MMC_D6_MARK, PSE13_0, PSE12_0, PTW6_FN),
+ PINMUX_DATA(MMC_D5_MARK, PSE13_0, PSE12_0, PTW5_FN),
+ PINMUX_DATA(MMC_D4_MARK, PSE13_0, PSE12_0, PTW4_FN),
+ PINMUX_DATA(MMC_D3_MARK, PSA13_0, PTW3_FN),
+ PINMUX_DATA(MMC_D2_MARK, PSA13_0, PTW2_FN),
+ PINMUX_DATA(MMC_D1_MARK, PSA13_0, PTW1_FN),
+ PINMUX_DATA(MMC_D0_MARK, PSA13_0, PTW0_FN),
+
+ PINMUX_DATA(SDHI1CD_MARK, PSE13_0, PSE12_1, PTW7_FN),
+ PINMUX_DATA(SDHI1WP_MARK, PSE13_0, PSE12_1, PTW6_FN),
+ PINMUX_DATA(SDHI1D3_MARK, PSE13_0, PSE12_1, PTW5_FN),
+ PINMUX_DATA(SDHI1D2_MARK, PSE13_0, PSE12_1, PTW4_FN),
+ PINMUX_DATA(SDHI1D1_MARK, PSA13_1, PTW3_FN),
+ PINMUX_DATA(SDHI1D0_MARK, PSA13_1, PTW2_FN),
+ PINMUX_DATA(SDHI1CMD_MARK, PSA13_1, PTW1_FN),
+ PINMUX_DATA(SDHI1CLK_MARK, PSA13_1, PTW0_FN),
+
+ PINMUX_DATA(IODACK_MARK, PSE13_1, PSE12_0, PTW7_FN),
+ PINMUX_DATA(IDERST_MARK, PSE13_1, PSE12_0, PTW6_FN),
+ PINMUX_DATA(EXBUF_ENB_MARK, PSE13_1, PSE12_0, PTW5_FN),
+ PINMUX_DATA(DIRECTION_MARK, PSE13_1, PSE12_0, PTW4_FN),
+
+ /* PTX FN */
+ PINMUX_DATA(DMAC_DACK1_MARK, PSA12_0, PTX7_FN),
+ PINMUX_DATA(DMAC_DREQ1_MARK, PSA12_0, PTX6_FN),
+
+ PINMUX_DATA(IRDA_OUT_MARK, PSA12_1, PTX7_FN),
+ PINMUX_DATA(IRDA_IN_MARK, PSA12_1, PTX6_FN),
+
+ PINMUX_DATA(TSIF_TS0_SDAT_MARK, PSC0_0, PTX5_FN),
+ PINMUX_DATA(TSIF_TS0_SCK_MARK, PSC1_0, PTX4_FN),
+ PINMUX_DATA(TSIF_TS0_SDEN_MARK, PSC2_0, PTX3_FN),
+ PINMUX_DATA(TSIF_TS0_SPSYNC_MARK, PTX2_FN),
+
+ PINMUX_DATA(LNKSTA_MARK, PSC0_1, PTX5_FN),
+ PINMUX_DATA(MDIO_MARK, PSC1_1, PTX4_FN),
+ PINMUX_DATA(MDC_MARK, PSC2_1, PTX3_FN),
+
+ PINMUX_DATA(MMC_CLK_MARK, PTX1_FN),
+ PINMUX_DATA(MMC_CMD_MARK, PTX0_FN),
+
+ /* PTY FN */
+ PINMUX_DATA(SDHI0CD_MARK, PTY7_FN),
+ PINMUX_DATA(SDHI0WP_MARK, PTY6_FN),
+ PINMUX_DATA(SDHI0D3_MARK, PTY5_FN),
+ PINMUX_DATA(SDHI0D2_MARK, PTY4_FN),
+ PINMUX_DATA(SDHI0D1_MARK, PTY3_FN),
+ PINMUX_DATA(SDHI0D0_MARK, PTY2_FN),
+ PINMUX_DATA(SDHI0CMD_MARK, PTY1_FN),
+ PINMUX_DATA(SDHI0CLK_MARK, PTY0_FN),
+
+ /* PTZ FN */
+ PINMUX_DATA(INTC_IRQ7_MARK, PSB10_0, PTZ7_FN),
+ PINMUX_DATA(INTC_IRQ6_MARK, PSB11_0, PTZ6_FN),
+ PINMUX_DATA(INTC_IRQ5_MARK, PSB12_0, PTZ5_FN),
+ PINMUX_DATA(INTC_IRQ4_MARK, PSB13_0, PTZ4_FN),
+ PINMUX_DATA(INTC_IRQ3_MARK, PSB14_0, PTZ3_FN),
+ PINMUX_DATA(INTC_IRQ2_MARK, PTZ2_FN),
+ PINMUX_DATA(INTC_IRQ1_MARK, PTZ1_FN),
+ PINMUX_DATA(INTC_IRQ0_MARK, PTZ0_FN),
+
+ PINMUX_DATA(SCIF3_I_CTS_MARK, PSB10_1, PTZ7_FN),
+ PINMUX_DATA(SCIF3_I_RTS_MARK, PSB11_1, PTZ6_FN),
+ PINMUX_DATA(SCIF3_I_SCK_MARK, PSB12_1, PTZ5_FN),
+ PINMUX_DATA(SCIF3_I_RXD_MARK, PSB13_1, PTZ4_FN),
+ PINMUX_DATA(SCIF3_I_TXD_MARK, PSB14_1, PTZ3_FN),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ /* PTA */
+ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA),
+ PINMUX_GPIO(GPIO_PTA6, PTA6_DATA),
+ PINMUX_GPIO(GPIO_PTA5, PTA5_DATA),
+ PINMUX_GPIO(GPIO_PTA4, PTA4_DATA),
+ PINMUX_GPIO(GPIO_PTA3, PTA3_DATA),
+ PINMUX_GPIO(GPIO_PTA2, PTA2_DATA),
+ PINMUX_GPIO(GPIO_PTA1, PTA1_DATA),
+ PINMUX_GPIO(GPIO_PTA0, PTA0_DATA),
+
+ /* PTB */
+ PINMUX_GPIO(GPIO_PTB7, PTB7_DATA),
+ PINMUX_GPIO(GPIO_PTB6, PTB6_DATA),
+ PINMUX_GPIO(GPIO_PTB5, PTB5_DATA),
+ PINMUX_GPIO(GPIO_PTB4, PTB4_DATA),
+ PINMUX_GPIO(GPIO_PTB3, PTB3_DATA),
+ PINMUX_GPIO(GPIO_PTB2, PTB2_DATA),
+ PINMUX_GPIO(GPIO_PTB1, PTB1_DATA),
+ PINMUX_GPIO(GPIO_PTB0, PTB0_DATA),
+
+ /* PTC */
+ PINMUX_GPIO(GPIO_PTC7, PTC7_DATA),
+ PINMUX_GPIO(GPIO_PTC6, PTC6_DATA),
+ PINMUX_GPIO(GPIO_PTC5, PTC5_DATA),
+ PINMUX_GPIO(GPIO_PTC4, PTC4_DATA),
+ PINMUX_GPIO(GPIO_PTC3, PTC3_DATA),
+ PINMUX_GPIO(GPIO_PTC2, PTC2_DATA),
+ PINMUX_GPIO(GPIO_PTC1, PTC1_DATA),
+ PINMUX_GPIO(GPIO_PTC0, PTC0_DATA),
+
+ /* PTD */
+ PINMUX_GPIO(GPIO_PTD7, PTD7_DATA),
+ PINMUX_GPIO(GPIO_PTD6, PTD6_DATA),
+ PINMUX_GPIO(GPIO_PTD5, PTD5_DATA),
+ PINMUX_GPIO(GPIO_PTD4, PTD4_DATA),
+ PINMUX_GPIO(GPIO_PTD3, PTD3_DATA),
+ PINMUX_GPIO(GPIO_PTD2, PTD2_DATA),
+ PINMUX_GPIO(GPIO_PTD1, PTD1_DATA),
+ PINMUX_GPIO(GPIO_PTD0, PTD0_DATA),
+
+ /* PTE */
+ PINMUX_GPIO(GPIO_PTE7, PTE7_DATA),
+ PINMUX_GPIO(GPIO_PTE6, PTE6_DATA),
+ PINMUX_GPIO(GPIO_PTE5, PTE5_DATA),
+ PINMUX_GPIO(GPIO_PTE4, PTE4_DATA),
+ PINMUX_GPIO(GPIO_PTE3, PTE3_DATA),
+ PINMUX_GPIO(GPIO_PTE2, PTE2_DATA),
+ PINMUX_GPIO(GPIO_PTE1, PTE1_DATA),
+ PINMUX_GPIO(GPIO_PTE0, PTE0_DATA),
+
+ /* PTF */
+ PINMUX_GPIO(GPIO_PTF7, PTF7_DATA),
+ PINMUX_GPIO(GPIO_PTF6, PTF6_DATA),
+ PINMUX_GPIO(GPIO_PTF5, PTF5_DATA),
+ PINMUX_GPIO(GPIO_PTF4, PTF4_DATA),
+ PINMUX_GPIO(GPIO_PTF3, PTF3_DATA),
+ PINMUX_GPIO(GPIO_PTF2, PTF2_DATA),
+ PINMUX_GPIO(GPIO_PTF1, PTF1_DATA),
+ PINMUX_GPIO(GPIO_PTF0, PTF0_DATA),
+
+ /* PTG */
+ PINMUX_GPIO(GPIO_PTG5, PTG5_DATA),
+ PINMUX_GPIO(GPIO_PTG4, PTG4_DATA),
+ PINMUX_GPIO(GPIO_PTG3, PTG3_DATA),
+ PINMUX_GPIO(GPIO_PTG2, PTG2_DATA),
+ PINMUX_GPIO(GPIO_PTG1, PTG1_DATA),
+ PINMUX_GPIO(GPIO_PTG0, PTG0_DATA),
+
+ /* PTH */
+ PINMUX_GPIO(GPIO_PTH7, PTH7_DATA),
+ PINMUX_GPIO(GPIO_PTH6, PTH6_DATA),
+ PINMUX_GPIO(GPIO_PTH5, PTH5_DATA),
+ PINMUX_GPIO(GPIO_PTH4, PTH4_DATA),
+ PINMUX_GPIO(GPIO_PTH3, PTH3_DATA),
+ PINMUX_GPIO(GPIO_PTH2, PTH2_DATA),
+ PINMUX_GPIO(GPIO_PTH1, PTH1_DATA),
+ PINMUX_GPIO(GPIO_PTH0, PTH0_DATA),
+
+ /* PTJ */
+ PINMUX_GPIO(GPIO_PTJ7, PTJ7_DATA),
+ PINMUX_GPIO(GPIO_PTJ6, PTJ6_DATA),
+ PINMUX_GPIO(GPIO_PTJ5, PTJ5_DATA),
+ PINMUX_GPIO(GPIO_PTJ3, PTJ3_DATA),
+ PINMUX_GPIO(GPIO_PTJ2, PTJ2_DATA),
+ PINMUX_GPIO(GPIO_PTJ1, PTJ1_DATA),
+ PINMUX_GPIO(GPIO_PTJ0, PTJ0_DATA),
+
+ /* PTK */
+ PINMUX_GPIO(GPIO_PTK7, PTK7_DATA),
+ PINMUX_GPIO(GPIO_PTK6, PTK6_DATA),
+ PINMUX_GPIO(GPIO_PTK5, PTK5_DATA),
+ PINMUX_GPIO(GPIO_PTK4, PTK4_DATA),
+ PINMUX_GPIO(GPIO_PTK3, PTK3_DATA),
+ PINMUX_GPIO(GPIO_PTK2, PTK2_DATA),
+ PINMUX_GPIO(GPIO_PTK1, PTK1_DATA),
+ PINMUX_GPIO(GPIO_PTK0, PTK0_DATA),
+
+ /* PTL */
+ PINMUX_GPIO(GPIO_PTL7, PTL7_DATA),
+ PINMUX_GPIO(GPIO_PTL6, PTL6_DATA),
+ PINMUX_GPIO(GPIO_PTL5, PTL5_DATA),
+ PINMUX_GPIO(GPIO_PTL4, PTL4_DATA),
+ PINMUX_GPIO(GPIO_PTL3, PTL3_DATA),
+ PINMUX_GPIO(GPIO_PTL2, PTL2_DATA),
+ PINMUX_GPIO(GPIO_PTL1, PTL1_DATA),
+ PINMUX_GPIO(GPIO_PTL0, PTL0_DATA),
+
+ /* PTM */
+ PINMUX_GPIO(GPIO_PTM7, PTM7_DATA),
+ PINMUX_GPIO(GPIO_PTM6, PTM6_DATA),
+ PINMUX_GPIO(GPIO_PTM5, PTM5_DATA),
+ PINMUX_GPIO(GPIO_PTM4, PTM4_DATA),
+ PINMUX_GPIO(GPIO_PTM3, PTM3_DATA),
+ PINMUX_GPIO(GPIO_PTM2, PTM2_DATA),
+ PINMUX_GPIO(GPIO_PTM1, PTM1_DATA),
+ PINMUX_GPIO(GPIO_PTM0, PTM0_DATA),
+
+ /* PTN */
+ PINMUX_GPIO(GPIO_PTN7, PTN7_DATA),
+ PINMUX_GPIO(GPIO_PTN6, PTN6_DATA),
+ PINMUX_GPIO(GPIO_PTN5, PTN5_DATA),
+ PINMUX_GPIO(GPIO_PTN4, PTN4_DATA),
+ PINMUX_GPIO(GPIO_PTN3, PTN3_DATA),
+ PINMUX_GPIO(GPIO_PTN2, PTN2_DATA),
+ PINMUX_GPIO(GPIO_PTN1, PTN1_DATA),
+ PINMUX_GPIO(GPIO_PTN0, PTN0_DATA),
+
+ /* PTQ */
+ PINMUX_GPIO(GPIO_PTQ7, PTQ7_DATA),
+ PINMUX_GPIO(GPIO_PTQ6, PTQ6_DATA),
+ PINMUX_GPIO(GPIO_PTQ5, PTQ5_DATA),
+ PINMUX_GPIO(GPIO_PTQ4, PTQ4_DATA),
+ PINMUX_GPIO(GPIO_PTQ3, PTQ3_DATA),
+ PINMUX_GPIO(GPIO_PTQ2, PTQ2_DATA),
+ PINMUX_GPIO(GPIO_PTQ1, PTQ1_DATA),
+ PINMUX_GPIO(GPIO_PTQ0, PTQ0_DATA),
+
+ /* PTR */
+ PINMUX_GPIO(GPIO_PTR7, PTR7_DATA),
+ PINMUX_GPIO(GPIO_PTR6, PTR6_DATA),
+ PINMUX_GPIO(GPIO_PTR5, PTR5_DATA),
+ PINMUX_GPIO(GPIO_PTR4, PTR4_DATA),
+ PINMUX_GPIO(GPIO_PTR3, PTR3_DATA),
+ PINMUX_GPIO(GPIO_PTR2, PTR2_DATA),
+ PINMUX_GPIO(GPIO_PTR1, PTR1_DATA),
+ PINMUX_GPIO(GPIO_PTR0, PTR0_DATA),
+
+ /* PTS */
+ PINMUX_GPIO(GPIO_PTS6, PTS6_DATA),
+ PINMUX_GPIO(GPIO_PTS5, PTS5_DATA),
+ PINMUX_GPIO(GPIO_PTS4, PTS4_DATA),
+ PINMUX_GPIO(GPIO_PTS3, PTS3_DATA),
+ PINMUX_GPIO(GPIO_PTS2, PTS2_DATA),
+ PINMUX_GPIO(GPIO_PTS1, PTS1_DATA),
+ PINMUX_GPIO(GPIO_PTS0, PTS0_DATA),
+
+ /* PTT */
+ PINMUX_GPIO(GPIO_PTT7, PTT7_DATA),
+ PINMUX_GPIO(GPIO_PTT6, PTT6_DATA),
+ PINMUX_GPIO(GPIO_PTT5, PTT5_DATA),
+ PINMUX_GPIO(GPIO_PTT4, PTT4_DATA),
+ PINMUX_GPIO(GPIO_PTT3, PTT3_DATA),
+ PINMUX_GPIO(GPIO_PTT2, PTT2_DATA),
+ PINMUX_GPIO(GPIO_PTT1, PTT1_DATA),
+ PINMUX_GPIO(GPIO_PTT0, PTT0_DATA),
+
+ /* PTU */
+ PINMUX_GPIO(GPIO_PTU7, PTU7_DATA),
+ PINMUX_GPIO(GPIO_PTU6, PTU6_DATA),
+ PINMUX_GPIO(GPIO_PTU5, PTU5_DATA),
+ PINMUX_GPIO(GPIO_PTU4, PTU4_DATA),
+ PINMUX_GPIO(GPIO_PTU3, PTU3_DATA),
+ PINMUX_GPIO(GPIO_PTU2, PTU2_DATA),
+ PINMUX_GPIO(GPIO_PTU1, PTU1_DATA),
+ PINMUX_GPIO(GPIO_PTU0, PTU0_DATA),
+
+ /* PTV */
+ PINMUX_GPIO(GPIO_PTV7, PTV7_DATA),
+ PINMUX_GPIO(GPIO_PTV6, PTV6_DATA),
+ PINMUX_GPIO(GPIO_PTV5, PTV5_DATA),
+ PINMUX_GPIO(GPIO_PTV4, PTV4_DATA),
+ PINMUX_GPIO(GPIO_PTV3, PTV3_DATA),
+ PINMUX_GPIO(GPIO_PTV2, PTV2_DATA),
+ PINMUX_GPIO(GPIO_PTV1, PTV1_DATA),
+ PINMUX_GPIO(GPIO_PTV0, PTV0_DATA),
+
+ /* PTW */
+ PINMUX_GPIO(GPIO_PTW7, PTW7_DATA),
+ PINMUX_GPIO(GPIO_PTW6, PTW6_DATA),
+ PINMUX_GPIO(GPIO_PTW5, PTW5_DATA),
+ PINMUX_GPIO(GPIO_PTW4, PTW4_DATA),
+ PINMUX_GPIO(GPIO_PTW3, PTW3_DATA),
+ PINMUX_GPIO(GPIO_PTW2, PTW2_DATA),
+ PINMUX_GPIO(GPIO_PTW1, PTW1_DATA),
+ PINMUX_GPIO(GPIO_PTW0, PTW0_DATA),
+
+ /* PTX */
+ PINMUX_GPIO(GPIO_PTX7, PTX7_DATA),
+ PINMUX_GPIO(GPIO_PTX6, PTX6_DATA),
+ PINMUX_GPIO(GPIO_PTX5, PTX5_DATA),
+ PINMUX_GPIO(GPIO_PTX4, PTX4_DATA),
+ PINMUX_GPIO(GPIO_PTX3, PTX3_DATA),
+ PINMUX_GPIO(GPIO_PTX2, PTX2_DATA),
+ PINMUX_GPIO(GPIO_PTX1, PTX1_DATA),
+ PINMUX_GPIO(GPIO_PTX0, PTX0_DATA),
+
+ /* PTY */
+ PINMUX_GPIO(GPIO_PTY7, PTY7_DATA),
+ PINMUX_GPIO(GPIO_PTY6, PTY6_DATA),
+ PINMUX_GPIO(GPIO_PTY5, PTY5_DATA),
+ PINMUX_GPIO(GPIO_PTY4, PTY4_DATA),
+ PINMUX_GPIO(GPIO_PTY3, PTY3_DATA),
+ PINMUX_GPIO(GPIO_PTY2, PTY2_DATA),
+ PINMUX_GPIO(GPIO_PTY1, PTY1_DATA),
+ PINMUX_GPIO(GPIO_PTY0, PTY0_DATA),
+
+ /* PTZ */
+ PINMUX_GPIO(GPIO_PTZ7, PTZ7_DATA),
+ PINMUX_GPIO(GPIO_PTZ6, PTZ6_DATA),
+ PINMUX_GPIO(GPIO_PTZ5, PTZ5_DATA),
+ PINMUX_GPIO(GPIO_PTZ4, PTZ4_DATA),
+ PINMUX_GPIO(GPIO_PTZ3, PTZ3_DATA),
+ PINMUX_GPIO(GPIO_PTZ2, PTZ2_DATA),
+ PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA),
+ PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA),
+
+ /* BSC */
+ PINMUX_GPIO(GPIO_FN_D31, D31_MARK),
+ PINMUX_GPIO(GPIO_FN_D30, D30_MARK),
+ PINMUX_GPIO(GPIO_FN_D29, D29_MARK),
+ PINMUX_GPIO(GPIO_FN_D28, D28_MARK),
+ PINMUX_GPIO(GPIO_FN_D27, D27_MARK),
+ PINMUX_GPIO(GPIO_FN_D26, D26_MARK),
+ PINMUX_GPIO(GPIO_FN_D25, D25_MARK),
+ PINMUX_GPIO(GPIO_FN_D24, D24_MARK),
+ PINMUX_GPIO(GPIO_FN_D23, D23_MARK),
+ PINMUX_GPIO(GPIO_FN_D22, D22_MARK),
+ PINMUX_GPIO(GPIO_FN_D21, D21_MARK),
+ PINMUX_GPIO(GPIO_FN_D20, D20_MARK),
+ PINMUX_GPIO(GPIO_FN_D19, D19_MARK),
+ PINMUX_GPIO(GPIO_FN_D18, D18_MARK),
+ PINMUX_GPIO(GPIO_FN_D17, D17_MARK),
+ PINMUX_GPIO(GPIO_FN_D16, D16_MARK),
+ PINMUX_GPIO(GPIO_FN_D15, D15_MARK),
+ PINMUX_GPIO(GPIO_FN_D14, D14_MARK),
+ PINMUX_GPIO(GPIO_FN_D13, D13_MARK),
+ PINMUX_GPIO(GPIO_FN_D12, D12_MARK),
+ PINMUX_GPIO(GPIO_FN_D11, D11_MARK),
+ PINMUX_GPIO(GPIO_FN_D10, D10_MARK),
+ PINMUX_GPIO(GPIO_FN_D9, D9_MARK),
+ PINMUX_GPIO(GPIO_FN_D8, D8_MARK),
+ PINMUX_GPIO(GPIO_FN_D7, D7_MARK),
+ PINMUX_GPIO(GPIO_FN_D6, D6_MARK),
+ PINMUX_GPIO(GPIO_FN_D5, D5_MARK),
+ PINMUX_GPIO(GPIO_FN_D4, D4_MARK),
+ PINMUX_GPIO(GPIO_FN_D3, D3_MARK),
+ PINMUX_GPIO(GPIO_FN_D2, D2_MARK),
+ PINMUX_GPIO(GPIO_FN_D1, D1_MARK),
+ PINMUX_GPIO(GPIO_FN_D0, D0_MARK),
+ PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
+ PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
+ PINMUX_GPIO(GPIO_FN_A23, A23_MARK),
+ PINMUX_GPIO(GPIO_FN_A22, A22_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6B_CE1B, CS6B_CE1B_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6A_CE2B, CS6A_CE2B_MARK),
+ PINMUX_GPIO(GPIO_FN_CS5B_CE1A, CS5B_CE1A_MARK),
+ PINMUX_GPIO(GPIO_FN_CS5A_CE2A, CS5A_CE2A_MARK),
+ PINMUX_GPIO(GPIO_FN_WE3_ICIOWR, WE3_ICIOWR_MARK),
+ PINMUX_GPIO(GPIO_FN_WE2_ICIORD, WE2_ICIORD_MARK),
+ PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK),
+ PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK),
+ PINMUX_GPIO(GPIO_FN_BS, BS_MARK),
+
+ /* KEYSC */
+ PINMUX_GPIO(GPIO_FN_KEYOUT5_IN5, KEYOUT5_IN5_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT4_IN6, KEYOUT4_IN6_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN4, KEYIN4_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN3, KEYIN3_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN2, KEYIN2_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN1, KEYIN1_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN0, KEYIN0_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT3, KEYOUT3_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT2, KEYOUT2_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT1, KEYOUT1_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT0, KEYOUT0_MARK),
+
+ /* ATAPI */
+ PINMUX_GPIO(GPIO_FN_IDED15, IDED15_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED14, IDED14_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED13, IDED13_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED12, IDED12_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED11, IDED11_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED10, IDED10_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED9, IDED9_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED8, IDED8_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED7, IDED7_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED6, IDED6_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED5, IDED5_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED4, IDED4_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED3, IDED3_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED2, IDED2_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED1, IDED1_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED0, IDED0_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEA2, IDEA2_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEA1, IDEA1_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEA0, IDEA0_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEIOWR, IDEIOWR_MARK),
+ PINMUX_GPIO(GPIO_FN_IODREQ, IODREQ_MARK),
+ PINMUX_GPIO(GPIO_FN_IDECS0, IDECS0_MARK),
+ PINMUX_GPIO(GPIO_FN_IDECS1, IDECS1_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEIORD, IDEIORD_MARK),
+ PINMUX_GPIO(GPIO_FN_DIRECTION, DIRECTION_MARK),
+ PINMUX_GPIO(GPIO_FN_EXBUF_ENB, EXBUF_ENB_MARK),
+ PINMUX_GPIO(GPIO_FN_IDERST, IDERST_MARK),
+ PINMUX_GPIO(GPIO_FN_IODACK, IODACK_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEINT, IDEINT_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEIORDY, IDEIORDY_MARK),
+
+ /* TPU */
+ PINMUX_GPIO(GPIO_FN_TPUTO3, TPUTO3_MARK),
+ PINMUX_GPIO(GPIO_FN_TPUTO2, TPUTO2_MARK),
+ PINMUX_GPIO(GPIO_FN_TPUTO1, TPUTO1_MARK),
+ PINMUX_GPIO(GPIO_FN_TPUTO0, TPUTO0_MARK),
+ PINMUX_GPIO(GPIO_FN_TPUTI3, TPUTI3_MARK),
+ PINMUX_GPIO(GPIO_FN_TPUTI2, TPUTI2_MARK),
+
+ /* LCDC */
+ PINMUX_GPIO(GPIO_FN_LCDD23, LCDD23_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD22, LCDD22_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD21, LCDD21_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD20, LCDD20_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD19, LCDD19_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD18, LCDD18_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD17, LCDD17_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD16, LCDD16_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD15, LCDD15_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD14, LCDD14_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD13, LCDD13_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD12, LCDD12_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD11, LCDD11_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD10, LCDD10_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD9, LCDD9_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD8, LCDD8_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD7, LCDD7_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD6, LCDD6_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD5, LCDD5_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD4, LCDD4_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD3, LCDD3_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD2, LCDD2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD1, LCDD1_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD0, LCDD0_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVSYN, LCDVSYN_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDDISP, LCDDISP_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDRS, LCDRS_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDHSYN, LCDHSYN_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDCS, LCDCS_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDDON, LCDDON_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDDCK, LCDDCK_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDWR, LCDWR_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVEPWC, LCDVEPWC_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVCPWC, LCDVCPWC_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDRD, LCDRD_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDLCLK, LCDLCLK_MARK),
+
+ /* SCIF0 */
+ PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK),
+
+ /* SCIF1 */
+ PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK),
+
+ /* SCIF2 */
+ PINMUX_GPIO(GPIO_FN_SCIF2_L_TXD, SCIF2_L_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_L_SCK, SCIF2_L_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_L_RXD, SCIF2_L_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_V_TXD, SCIF2_V_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_V_SCK, SCIF2_V_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_V_RXD, SCIF2_V_RXD_MARK),
+
+ /* SCIF3 */
+ PINMUX_GPIO(GPIO_FN_SCIF3_V_SCK, SCIF3_V_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_V_RXD, SCIF3_V_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_V_TXD, SCIF3_V_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_V_CTS, SCIF3_V_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_V_RTS, SCIF3_V_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_I_SCK, SCIF3_I_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_I_RXD, SCIF3_I_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_I_TXD, SCIF3_I_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_I_CTS, SCIF3_I_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_I_RTS, SCIF3_I_RTS_MARK),
+
+ /* SCIF4 */
+ PINMUX_GPIO(GPIO_FN_SCIF4_SCK, SCIF4_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF4_RXD, SCIF4_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF4_TXD, SCIF4_TXD_MARK),
+
+ /* SCIF5 */
+ PINMUX_GPIO(GPIO_FN_SCIF5_SCK, SCIF5_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF5_RXD, SCIF5_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF5_TXD, SCIF5_TXD_MARK),
+
+ /* FSI */
+ PINMUX_GPIO(GPIO_FN_FSIMCKB, FSIMCKB_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIMCKA, FSIMCKA_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIOASD, FSIOASD_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIIABCK, FSIIABCK_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIIALRCK, FSIIALRCK_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIOABCK, FSIOABCK_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIOALRCK, FSIOALRCK_MARK),
+ PINMUX_GPIO(GPIO_FN_CLKAUDIOAO, CLKAUDIOAO_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIIBSD, FSIIBSD_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIOBSD, FSIOBSD_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIIBBCK, FSIIBBCK_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIIBLRCK, FSIIBLRCK_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIOBBCK, FSIOBBCK_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIOBLRCK, FSIOBLRCK_MARK),
+ PINMUX_GPIO(GPIO_FN_CLKAUDIOBO, CLKAUDIOBO_MARK),
+ PINMUX_GPIO(GPIO_FN_FSIIASD, FSIIASD_MARK),
+
+ /* AUD */
+ PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK),
+
+ /* VIO */
+ PINMUX_GPIO(GPIO_FN_VIO_CKO, VIO_CKO_MARK),
+
+ /* VIO0 */
+ PINMUX_GPIO(GPIO_FN_VIO0_D15, VIO0_D15_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D14, VIO0_D14_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D13, VIO0_D13_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D12, VIO0_D12_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D11, VIO0_D11_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D10, VIO0_D10_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D9, VIO0_D9_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D8, VIO0_D8_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D7, VIO0_D7_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D6, VIO0_D6_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D5, VIO0_D5_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D4, VIO0_D4_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D3, VIO0_D3_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D2, VIO0_D2_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D1, VIO0_D1_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_D0, VIO0_D0_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_VD, VIO0_VD_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_CLK, VIO0_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_FLD, VIO0_FLD_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO0_HD, VIO0_HD_MARK),
+
+ /* VIO1 */
+ PINMUX_GPIO(GPIO_FN_VIO1_D7, VIO1_D7_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_D6, VIO1_D6_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_D5, VIO1_D5_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_D4, VIO1_D4_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_D3, VIO1_D3_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_D2, VIO1_D2_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_D1, VIO1_D1_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_D0, VIO1_D0_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_FLD, VIO1_FLD_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_HD, VIO1_HD_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_VD, VIO1_VD_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO1_CLK, VIO1_CLK_MARK),
+
+ /* Eth */
+ PINMUX_GPIO(GPIO_FN_RMII_RXD0, RMII_RXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII_RXD1, RMII_RXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII_TXD0, RMII_TXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII_TXD1, RMII_TXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII_REF_CLK, RMII_REF_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII_TX_EN, RMII_TX_EN_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII_RX_ER, RMII_RX_ER_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII_CRS_DV, RMII_CRS_DV_MARK),
+ PINMUX_GPIO(GPIO_FN_LNKSTA, LNKSTA_MARK),
+ PINMUX_GPIO(GPIO_FN_MDIO, MDIO_MARK),
+ PINMUX_GPIO(GPIO_FN_MDC, MDC_MARK),
+
+ /* System */
+ PINMUX_GPIO(GPIO_FN_PDSTATUS, PDSTATUS_MARK),
+ PINMUX_GPIO(GPIO_FN_STATUS2, STATUS2_MARK),
+ PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
+
+ /* VOU */
+ PINMUX_GPIO(GPIO_FN_DV_D15, DV_D15_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D14, DV_D14_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D13, DV_D13_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D12, DV_D12_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D11, DV_D11_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D10, DV_D10_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D9, DV_D9_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D8, DV_D8_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D7, DV_D7_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D6, DV_D6_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D5, DV_D5_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D4, DV_D4_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D3, DV_D3_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D2, DV_D2_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D1, DV_D1_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D0, DV_D0_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_CLKI, DV_CLKI_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_CLK, DV_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_VSYNC, DV_VSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_HSYNC, DV_HSYNC_MARK),
+
+ /* MSIOF0 */
+ PINMUX_GPIO(GPIO_FN_MSIOF0_RXD, MSIOF0_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_TXD, MSIOF0_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_MCK, MSIOF0_MCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_TSCK, MSIOF0_TSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_SS1, MSIOF0_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_SS2, MSIOF0_SS2_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_TSYNC, MSIOF0_TSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_RSCK, MSIOF0_RSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_RSYNC, MSIOF0_RSYNC_MARK),
+
+ /* MSIOF1 */
+ PINMUX_GPIO(GPIO_FN_MSIOF1_RXD, MSIOF1_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_TXD, MSIOF1_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_MCK, MSIOF1_MCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_TSCK, MSIOF1_TSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_SS1, MSIOF1_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_SS2, MSIOF1_SS2_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_TSYNC, MSIOF1_TSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_RSCK, MSIOF1_RSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_RSYNC, MSIOF1_RSYNC_MARK),
+
+ /* DMAC */
+ PINMUX_GPIO(GPIO_FN_DMAC_DACK0, DMAC_DACK0_MARK),
+ PINMUX_GPIO(GPIO_FN_DMAC_DREQ0, DMAC_DREQ0_MARK),
+ PINMUX_GPIO(GPIO_FN_DMAC_DACK1, DMAC_DACK1_MARK),
+ PINMUX_GPIO(GPIO_FN_DMAC_DREQ1, DMAC_DREQ1_MARK),
+
+ /* SDHI0 */
+ PINMUX_GPIO(GPIO_FN_SDHI0CD, SDHI0CD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0WP, SDHI0WP_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0CMD, SDHI0CMD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0CLK, SDHI0CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D3, SDHI0D3_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D2, SDHI0D2_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D1, SDHI0D1_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D0, SDHI0D0_MARK),
+
+ /* SDHI1 */
+ PINMUX_GPIO(GPIO_FN_SDHI1CD, SDHI1CD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1WP, SDHI1WP_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1CMD, SDHI1CMD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1CLK, SDHI1CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1D3, SDHI1D3_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1D2, SDHI1D2_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1D1, SDHI1D1_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1D0, SDHI1D0_MARK),
+
+ /* MMC */
+ PINMUX_GPIO(GPIO_FN_MMC_D7, MMC_D7_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_D6, MMC_D6_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_D5, MMC_D5_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_D4, MMC_D4_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_D3, MMC_D3_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_D2, MMC_D2_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_D1, MMC_D1_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_D0, MMC_D0_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_CLK, MMC_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_CMD, MMC_CMD_MARK),
+
+ /* IrDA */
+ PINMUX_GPIO(GPIO_FN_IRDA_OUT, IRDA_OUT_MARK),
+ PINMUX_GPIO(GPIO_FN_IRDA_IN, IRDA_IN_MARK),
+
+ /* TSIF */
+ PINMUX_GPIO(GPIO_FN_TSIF_TS0_SDAT, TSIF_TS0_SDAT_MARK),
+ PINMUX_GPIO(GPIO_FN_TSIF_TS0_SCK, TSIF_TS0_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_TSIF_TS0_SDEN, TSIF_TS0_SDEN_MARK),
+ PINMUX_GPIO(GPIO_FN_TSIF_TS0_SPSYNC, TSIF_TS0_SPSYNC_MARK),
+
+ /* IRQ */
+ PINMUX_GPIO(GPIO_FN_INTC_IRQ7, INTC_IRQ7_MARK),
+ PINMUX_GPIO(GPIO_FN_INTC_IRQ6, INTC_IRQ6_MARK),
+ PINMUX_GPIO(GPIO_FN_INTC_IRQ5, INTC_IRQ5_MARK),
+ PINMUX_GPIO(GPIO_FN_INTC_IRQ4, INTC_IRQ4_MARK),
+ PINMUX_GPIO(GPIO_FN_INTC_IRQ3, INTC_IRQ3_MARK),
+ PINMUX_GPIO(GPIO_FN_INTC_IRQ2, INTC_IRQ2_MARK),
+ PINMUX_GPIO(GPIO_FN_INTC_IRQ1, INTC_IRQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_INTC_IRQ0, INTC_IRQ0_MARK),
+ };
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ { PINMUX_CFG_REG("PACR", 0xa4050100, 16, 2) {
+ PTA7_FN, PTA7_OUT, PTA7_IN_PU, PTA7_IN,
+ PTA6_FN, PTA6_OUT, PTA6_IN_PU, PTA6_IN,
+ PTA5_FN, PTA5_OUT, PTA5_IN_PU, PTA5_IN,
+ PTA4_FN, PTA4_OUT, PTA4_IN_PU, PTA4_IN,
+ PTA3_FN, PTA3_OUT, PTA3_IN_PU, PTA3_IN,
+ PTA2_FN, PTA2_OUT, PTA2_IN_PU, PTA2_IN,
+ PTA1_FN, PTA1_OUT, PTA1_IN_PU, PTA1_IN,
+ PTA0_FN, PTA0_OUT, PTA0_IN_PU, PTA0_IN }
+ },
+ { PINMUX_CFG_REG("PBCR", 0xa4050102, 16, 2) {
+ PTB7_FN, PTB7_OUT, PTB7_IN_PU, PTB7_IN,
+ PTB6_FN, PTB6_OUT, PTB6_IN_PU, PTB6_IN,
+ PTB5_FN, PTB5_OUT, PTB5_IN_PU, PTB5_IN,
+ PTB4_FN, PTB4_OUT, PTB4_IN_PU, PTB4_IN,
+ PTB3_FN, PTB3_OUT, PTB3_IN_PU, PTB3_IN,
+ PTB2_FN, PTB2_OUT, PTB2_IN_PU, PTB2_IN,
+ PTB1_FN, PTB1_OUT, PTB1_IN_PU, PTB1_IN,
+ PTB0_FN, PTB0_OUT, PTB0_IN_PU, PTB0_IN }
+ },
+ { PINMUX_CFG_REG("PCCR", 0xa4050104, 16, 2) {
+ PTC7_FN, PTC7_OUT, PTC7_IN_PU, PTC7_IN,
+ PTC6_FN, PTC6_OUT, PTC6_IN_PU, PTC6_IN,
+ PTC5_FN, PTC5_OUT, PTC5_IN_PU, PTC5_IN,
+ PTC4_FN, PTC4_OUT, PTC4_IN_PU, PTC4_IN,
+ PTC3_FN, PTC3_OUT, PTC3_IN_PU, PTC3_IN,
+ PTC2_FN, PTC2_OUT, PTC2_IN_PU, PTC2_IN,
+ PTC1_FN, PTC1_OUT, PTC1_IN_PU, PTC1_IN,
+ PTC0_FN, PTC0_OUT, PTC0_IN_PU, PTC0_IN }
+ },
+ { PINMUX_CFG_REG("PDCR", 0xa4050106, 16, 2) {
+ PTD7_FN, PTD7_OUT, PTD7_IN_PU, PTD7_IN,
+ PTD6_FN, PTD6_OUT, PTD6_IN_PU, PTD6_IN,
+ PTD5_FN, PTD5_OUT, PTD5_IN_PU, PTD5_IN,
+ PTD4_FN, PTD4_OUT, PTD4_IN_PU, PTD4_IN,
+ PTD3_FN, PTD3_OUT, PTD3_IN_PU, PTD3_IN,
+ PTD2_FN, PTD2_OUT, PTD2_IN_PU, PTD2_IN,
+ PTD1_FN, PTD1_OUT, PTD1_IN_PU, PTD1_IN,
+ PTD0_FN, PTD0_OUT, PTD0_IN_PU, PTD0_IN }
+ },
+ { PINMUX_CFG_REG("PECR", 0xa4050108, 16, 2) {
+ PTE7_FN, PTE7_OUT, PTE7_IN_PU, PTE7_IN,
+ PTE6_FN, PTE6_OUT, PTE6_IN_PU, PTE6_IN,
+ PTE5_FN, PTE5_OUT, PTE5_IN_PU, PTE5_IN,
+ PTE4_FN, PTE4_OUT, PTE4_IN_PU, PTE4_IN,
+ PTE3_FN, PTE3_OUT, PTE3_IN_PU, PTE3_IN,
+ PTE2_FN, PTE2_OUT, PTE2_IN_PU, PTE2_IN,
+ PTE1_FN, PTE1_OUT, PTE1_IN_PU, PTE1_IN,
+ PTE0_FN, PTE0_OUT, PTE0_IN_PU, PTE0_IN }
+ },
+ { PINMUX_CFG_REG("PFCR", 0xa405010a, 16, 2) {
+ PTF7_FN, PTF7_OUT, PTF7_IN_PU, PTF7_IN,
+ PTF6_FN, PTF6_OUT, PTF6_IN_PU, PTF6_IN,
+ PTF5_FN, PTF5_OUT, PTF5_IN_PU, PTF5_IN,
+ PTF4_FN, PTF4_OUT, PTF4_IN_PU, PTF4_IN,
+ PTF3_FN, PTF3_OUT, PTF3_IN_PU, PTF3_IN,
+ PTF2_FN, PTF2_OUT, PTF2_IN_PU, PTF2_IN,
+ PTF1_FN, PTF1_OUT, PTF1_IN_PU, PTF1_IN,
+ PTF0_FN, PTF0_OUT, PTF0_IN_PU, PTF0_IN }
+ },
+ { PINMUX_CFG_REG("PGCR", 0xa405010c, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTG5_FN, PTG5_OUT, 0, 0,
+ PTG4_FN, PTG4_OUT, 0, 0,
+ PTG3_FN, PTG3_OUT, 0, 0,
+ PTG2_FN, PTG2_OUT, 0, 0,
+ PTG1_FN, PTG1_OUT, 0, 0,
+ PTG0_FN, PTG0_OUT, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PHCR", 0xa405010e, 16, 2) {
+ PTH7_FN, PTH7_OUT, PTH7_IN_PU, PTH7_IN,
+ PTH6_FN, PTH6_OUT, PTH6_IN_PU, PTH6_IN,
+ PTH5_FN, PTH5_OUT, PTH5_IN_PU, PTH5_IN,
+ PTH4_FN, PTH4_OUT, PTH4_IN_PU, PTH4_IN,
+ PTH3_FN, PTH3_OUT, PTH3_IN_PU, PTH3_IN,
+ PTH2_FN, PTH2_OUT, PTH2_IN_PU, PTH2_IN,
+ PTH1_FN, PTH1_OUT, PTH1_IN_PU, PTH1_IN,
+ PTH0_FN, PTH0_OUT, PTH0_IN_PU, PTH0_IN }
+ },
+ { PINMUX_CFG_REG("PJCR", 0xa4050110, 16, 2) {
+ PTJ7_FN, PTJ7_OUT, 0, 0,
+ PTJ6_FN, PTJ6_OUT, 0, 0,
+ PTJ5_FN, PTJ5_OUT, 0, 0,
+ 0, 0, 0, 0,
+ PTJ3_FN, PTJ3_OUT, PTJ3_IN_PU, PTJ3_IN,
+ PTJ2_FN, PTJ2_OUT, PTJ2_IN_PU, PTJ2_IN,
+ PTJ1_FN, PTJ1_OUT, PTJ1_IN_PU, PTJ1_IN,
+ PTJ0_FN, PTJ0_OUT, PTJ0_IN_PU, PTJ0_IN }
+ },
+ { PINMUX_CFG_REG("PKCR", 0xa4050112, 16, 2) {
+ PTK7_FN, PTK7_OUT, PTK7_IN_PU, PTK7_IN,
+ PTK6_FN, PTK6_OUT, PTK6_IN_PU, PTK6_IN,
+ PTK5_FN, PTK5_OUT, PTK5_IN_PU, PTK5_IN,
+ PTK4_FN, PTK4_OUT, PTK4_IN_PU, PTK4_IN,
+ PTK3_FN, PTK3_OUT, PTK3_IN_PU, PTK3_IN,
+ PTK2_FN, PTK2_OUT, PTK2_IN_PU, PTK2_IN,
+ PTK1_FN, PTK1_OUT, PTK1_IN_PU, PTK1_IN,
+ PTK0_FN, PTK0_OUT, PTK0_IN_PU, PTK0_IN }
+ },
+ { PINMUX_CFG_REG("PLCR", 0xa4050114, 16, 2) {
+ PTL7_FN, PTL7_OUT, PTL7_IN_PU, PTL7_IN,
+ PTL6_FN, PTL6_OUT, PTL6_IN_PU, PTL6_IN,
+ PTL5_FN, PTL5_OUT, PTL5_IN_PU, PTL5_IN,
+ PTL4_FN, PTL4_OUT, PTL4_IN_PU, PTL4_IN,
+ PTL3_FN, PTL3_OUT, PTL3_IN_PU, PTL3_IN,
+ PTL2_FN, PTL2_OUT, PTL2_IN_PU, PTL2_IN,
+ PTL1_FN, PTL1_OUT, PTL1_IN_PU, PTL1_IN,
+ PTL0_FN, PTL0_OUT, PTL0_IN_PU, PTL0_IN }
+ },
+ { PINMUX_CFG_REG("PMCR", 0xa4050116, 16, 2) {
+ PTM7_FN, PTM7_OUT, PTM7_IN_PU, PTM7_IN,
+ PTM6_FN, PTM6_OUT, PTM6_IN_PU, PTM6_IN,
+ PTM5_FN, PTM5_OUT, PTM5_IN_PU, PTM5_IN,
+ PTM4_FN, PTM4_OUT, PTM4_IN_PU, PTM4_IN,
+ PTM3_FN, PTM3_OUT, PTM3_IN_PU, PTM3_IN,
+ PTM2_FN, PTM2_OUT, PTM2_IN_PU, PTM2_IN,
+ PTM1_FN, PTM1_OUT, PTM1_IN_PU, PTM1_IN,
+ PTM0_FN, PTM0_OUT, PTM0_IN_PU, PTM0_IN }
+ },
+ { PINMUX_CFG_REG("PNCR", 0xa4050118, 16, 2) {
+ PTN7_FN, PTN7_OUT, PTN7_IN_PU, PTN7_IN,
+ PTN6_FN, PTN6_OUT, PTN6_IN_PU, PTN6_IN,
+ PTN5_FN, PTN5_OUT, PTN5_IN_PU, PTN5_IN,
+ PTN4_FN, PTN4_OUT, PTN4_IN_PU, PTN4_IN,
+ PTN3_FN, PTN3_OUT, PTN3_IN_PU, PTN3_IN,
+ PTN2_FN, PTN2_OUT, PTN2_IN_PU, PTN2_IN,
+ PTN1_FN, PTN1_OUT, PTN1_IN_PU, PTN1_IN,
+ PTN0_FN, PTN0_OUT, PTN0_IN_PU, PTN0_IN }
+ },
+ { PINMUX_CFG_REG("PQCR", 0xa405011a, 16, 2) {
+ PTQ7_FN, PTQ7_OUT, PTQ7_IN_PU, PTQ7_IN,
+ PTQ6_FN, PTQ6_OUT, PTQ6_IN_PU, PTQ6_IN,
+ PTQ5_FN, PTQ5_OUT, PTQ5_IN_PU, PTQ5_IN,
+ PTQ4_FN, PTQ4_OUT, PTQ4_IN_PU, PTQ4_IN,
+ PTQ3_FN, PTQ3_OUT, PTQ3_IN_PU, PTQ3_IN,
+ PTQ2_FN, PTQ2_OUT, PTQ2_IN_PU, PTQ2_IN,
+ PTQ1_FN, PTQ1_OUT, PTQ1_IN_PU, PTQ1_IN,
+ PTQ0_FN, PTQ0_OUT, PTQ0_IN_PU, PTQ0_IN }
+ },
+ { PINMUX_CFG_REG("PRCR", 0xa405011c, 16, 2) {
+ PTR7_FN, PTR7_OUT, PTR7_IN_PU, PTR7_IN,
+ PTR6_FN, PTR6_OUT, PTR6_IN_PU, PTR6_IN,
+ PTR5_FN, PTR5_OUT, PTR5_IN_PU, PTR5_IN,
+ PTR4_FN, PTR4_OUT, PTR4_IN_PU, PTR4_IN,
+ PTR3_FN, 0, PTR3_IN_PU, PTR3_IN,
+ PTR2_FN, 0, PTR2_IN_PU, PTR2_IN,
+ PTR1_FN, PTR1_OUT, PTR1_IN_PU, PTR1_IN,
+ PTR0_FN, PTR0_OUT, PTR0_IN_PU, PTR0_IN }
+ },
+ { PINMUX_CFG_REG("PSCR", 0xa405011e, 16, 2) {
+ 0, 0, 0, 0,
+ PTS6_FN, PTS6_OUT, PTS6_IN_PU, PTS6_IN,
+ PTS5_FN, PTS5_OUT, PTS5_IN_PU, PTS5_IN,
+ PTS4_FN, PTS4_OUT, PTS4_IN_PU, PTS4_IN,
+ PTS3_FN, PTS3_OUT, PTS3_IN_PU, PTS3_IN,
+ PTS2_FN, PTS2_OUT, PTS2_IN_PU, PTS2_IN,
+ PTS1_FN, PTS1_OUT, PTS1_IN_PU, PTS1_IN,
+ PTS0_FN, PTS0_OUT, PTS0_IN_PU, PTS0_IN }
+ },
+ { PINMUX_CFG_REG("PTCR", 0xa4050140, 16, 2) {
+ PTT7_FN, PTT7_OUT, PTT7_IN_PU, PTT7_IN,
+ PTT6_FN, PTT6_OUT, PTT6_IN_PU, PTT6_IN,
+ PTT5_FN, PTT5_OUT, PTT5_IN_PU, PTT5_IN,
+ PTT4_FN, PTT4_OUT, PTT4_IN_PU, PTT4_IN,
+ PTT3_FN, PTT3_OUT, PTT3_IN_PU, PTT3_IN,
+ PTT2_FN, PTT2_OUT, PTT2_IN_PU, PTT2_IN,
+ PTT1_FN, PTT1_OUT, PTT1_IN_PU, PTT1_IN,
+ PTT0_FN, PTT0_OUT, PTT0_IN_PU, PTT0_IN }
+ },
+ { PINMUX_CFG_REG("PUCR", 0xa4050142, 16, 2) {
+ PTU7_FN, PTU7_OUT, PTU7_IN_PU, PTU7_IN,
+ PTU6_FN, PTU6_OUT, PTU6_IN_PU, PTU6_IN,
+ PTU5_FN, PTU5_OUT, PTU5_IN_PU, PTU5_IN,
+ PTU4_FN, PTU4_OUT, PTU4_IN_PU, PTU4_IN,
+ PTU3_FN, PTU3_OUT, PTU3_IN_PU, PTU3_IN,
+ PTU2_FN, PTU2_OUT, PTU2_IN_PU, PTU2_IN,
+ PTU1_FN, PTU1_OUT, PTU1_IN_PU, PTU1_IN,
+ PTU0_FN, PTU0_OUT, PTU0_IN_PU, PTU0_IN }
+ },
+ { PINMUX_CFG_REG("PVCR", 0xa4050144, 16, 2) {
+ PTV7_FN, PTV7_OUT, PTV7_IN_PU, PTV7_IN,
+ PTV6_FN, PTV6_OUT, PTV6_IN_PU, PTV6_IN,
+ PTV5_FN, PTV5_OUT, PTV5_IN_PU, PTV5_IN,
+ PTV4_FN, PTV4_OUT, PTV4_IN_PU, PTV4_IN,
+ PTV3_FN, PTV3_OUT, PTV3_IN_PU, PTV3_IN,
+ PTV2_FN, PTV2_OUT, PTV2_IN_PU, PTV2_IN,
+ PTV1_FN, PTV1_OUT, PTV1_IN_PU, PTV1_IN,
+ PTV0_FN, PTV0_OUT, PTV0_IN_PU, PTV0_IN }
+ },
+ { PINMUX_CFG_REG("PWCR", 0xa4050146, 16, 2) {
+ PTW7_FN, PTW7_OUT, PTW7_IN_PU, PTW7_IN,
+ PTW6_FN, PTW6_OUT, PTW6_IN_PU, PTW6_IN,
+ PTW5_FN, PTW5_OUT, PTW5_IN_PU, PTW5_IN,
+ PTW4_FN, PTW4_OUT, PTW4_IN_PU, PTW4_IN,
+ PTW3_FN, PTW3_OUT, PTW3_IN_PU, PTW3_IN,
+ PTW2_FN, PTW2_OUT, PTW2_IN_PU, PTW2_IN,
+ PTW1_FN, PTW1_OUT, PTW1_IN_PU, PTW1_IN,
+ PTW0_FN, PTW0_OUT, PTW0_IN_PU, PTW0_IN }
+ },
+ { PINMUX_CFG_REG("PXCR", 0xa4050148, 16, 2) {
+ PTX7_FN, PTX7_OUT, PTX7_IN_PU, PTX7_IN,
+ PTX6_FN, PTX6_OUT, PTX6_IN_PU, PTX6_IN,
+ PTX5_FN, PTX5_OUT, PTX5_IN_PU, PTX5_IN,
+ PTX4_FN, PTX4_OUT, PTX4_IN_PU, PTX4_IN,
+ PTX3_FN, PTX3_OUT, PTX3_IN_PU, PTX3_IN,
+ PTX2_FN, PTX2_OUT, PTX2_IN_PU, PTX2_IN,
+ PTX1_FN, PTX1_OUT, PTX1_IN_PU, PTX1_IN,
+ PTX0_FN, PTX0_OUT, PTX0_IN_PU, PTX0_IN }
+ },
+ { PINMUX_CFG_REG("PYCR", 0xa405014a, 16, 2) {
+ PTY7_FN, PTY7_OUT, PTY7_IN_PU, PTY7_IN,
+ PTY6_FN, PTY6_OUT, PTY6_IN_PU, PTY6_IN,
+ PTY5_FN, PTY5_OUT, PTY5_IN_PU, PTY5_IN,
+ PTY4_FN, PTY4_OUT, PTY4_IN_PU, PTY4_IN,
+ PTY3_FN, PTY3_OUT, PTY3_IN_PU, PTY3_IN,
+ PTY2_FN, PTY2_OUT, PTY2_IN_PU, PTY2_IN,
+ PTY1_FN, PTY1_OUT, PTY1_IN_PU, PTY1_IN,
+ PTY0_FN, PTY0_OUT, PTY0_IN_PU, PTY0_IN }
+ },
+ { PINMUX_CFG_REG("PZCR", 0xa405014c, 16, 2) {
+ PTZ7_FN, PTZ7_OUT, PTZ7_IN_PU, PTZ7_IN,
+ PTZ6_FN, PTZ6_OUT, PTZ6_IN_PU, PTZ6_IN,
+ PTZ5_FN, PTZ5_OUT, PTZ5_IN_PU, PTZ5_IN,
+ PTZ4_FN, PTZ4_OUT, PTZ4_IN_PU, PTZ4_IN,
+ PTZ3_FN, PTZ3_OUT, PTZ3_IN_PU, PTZ3_IN,
+ PTZ2_FN, PTZ2_OUT, PTZ2_IN_PU, PTZ2_IN,
+ PTZ1_FN, PTZ1_OUT, PTZ1_IN_PU, PTZ1_IN,
+ PTZ0_FN, PTZ0_OUT, PTZ0_IN_PU, PTZ0_IN }
+ },
+ { PINMUX_CFG_REG("PSELA", 0xa405014e, 16, 1) {
+ PSA15_0, PSA15_1,
+ PSA14_0, PSA14_1,
+ PSA13_0, PSA13_1,
+ PSA12_0, PSA12_1,
+ 0, 0,
+ PSA10_0, PSA10_1,
+ PSA9_0, PSA9_1,
+ PSA8_0, PSA8_1,
+ PSA7_0, PSA7_1,
+ PSA6_0, PSA6_1,
+ PSA5_0, PSA5_1,
+ 0, 0,
+ PSA3_0, PSA3_1,
+ PSA2_0, PSA2_1,
+ PSA1_0, PSA1_1,
+ PSA0_0, PSA0_1}
+ },
+ { PINMUX_CFG_REG("PSELB", 0xa4050150, 16, 1) {
+ 0, 0,
+ PSB14_0, PSB14_1,
+ PSB13_0, PSB13_1,
+ PSB12_0, PSB12_1,
+ PSB11_0, PSB11_1,
+ PSB10_0, PSB10_1,
+ PSB9_0, PSB9_1,
+ PSB8_0, PSB8_1,
+ PSB7_0, PSB7_1,
+ PSB6_0, PSB6_1,
+ PSB5_0, PSB5_1,
+ PSB4_0, PSB4_1,
+ PSB3_0, PSB3_1,
+ PSB2_0, PSB2_1,
+ PSB1_0, PSB1_1,
+ PSB0_0, PSB0_1}
+ },
+ { PINMUX_CFG_REG("PSELC", 0xa4050152, 16, 1) {
+ PSC15_0, PSC15_1,
+ PSC14_0, PSC14_1,
+ PSC13_0, PSC13_1,
+ PSC12_0, PSC12_1,
+ PSC11_0, PSC11_1,
+ PSC10_0, PSC10_1,
+ PSC9_0, PSC9_1,
+ PSC8_0, PSC8_1,
+ PSC7_0, PSC7_1,
+ PSC6_0, PSC6_1,
+ PSC5_0, PSC5_1,
+ PSC4_0, PSC4_1,
+ 0, 0,
+ PSC2_0, PSC2_1,
+ PSC1_0, PSC1_1,
+ PSC0_0, PSC0_1}
+ },
+ { PINMUX_CFG_REG("PSELD", 0xa4050154, 16, 1) {
+ PSD15_0, PSD15_1,
+ PSD14_0, PSD14_1,
+ PSD13_0, PSD13_1,
+ PSD12_0, PSD12_1,
+ PSD11_0, PSD11_1,
+ PSD10_0, PSD10_1,
+ PSD9_0, PSD9_1,
+ PSD8_0, PSD8_1,
+ PSD7_0, PSD7_1,
+ PSD6_0, PSD6_1,
+ PSD5_0, PSD5_1,
+ PSD4_0, PSD4_1,
+ PSD3_0, PSD3_1,
+ PSD2_0, PSD2_1,
+ PSD1_0, PSD1_1,
+ PSD0_0, PSD0_1}
+ },
+ { PINMUX_CFG_REG("PSELE", 0xa4050156, 16, 1) {
+ PSE15_0, PSE15_1,
+ PSE14_0, PSE14_1,
+ PSE13_0, PSE13_1,
+ PSE12_0, PSE12_1,
+ PSE11_0, PSE11_1,
+ PSE10_0, PSE10_1,
+ PSE9_0, PSE9_1,
+ PSE8_0, PSE8_1,
+ PSE7_0, PSE7_1,
+ PSE6_0, PSE6_1,
+ PSE5_0, PSE5_1,
+ PSE4_0, PSE4_1,
+ PSE3_0, PSE3_1,
+ PSE2_0, PSE2_1,
+ PSE1_0, PSE1_1,
+ PSE0_0, PSE0_1}
+ },
+ {}
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PADR", 0xa4050120, 8) {
+ PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+ PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA }
+ },
+ { PINMUX_DATA_REG("PBDR", 0xa4050122, 8) {
+ PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+ PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA }
+ },
+ { PINMUX_DATA_REG("PCDR", 0xa4050124, 8) {
+ PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA,
+ PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA }
+ },
+ { PINMUX_DATA_REG("PDDR", 0xa4050126, 8) {
+ PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+ PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA }
+ },
+ { PINMUX_DATA_REG("PEDR", 0xa4050128, 8) {
+ PTE7_DATA, PTE6_DATA, PTE5_DATA, PTE4_DATA,
+ PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA }
+ },
+ { PINMUX_DATA_REG("PFDR", 0xa405012a, 8) {
+ PTF7_DATA, PTF6_DATA, PTF5_DATA, PTF4_DATA,
+ PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA }
+ },
+ { PINMUX_DATA_REG("PGDR", 0xa405012c, 8) {
+ 0, 0, PTG5_DATA, PTG4_DATA,
+ PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA }
+ },
+ { PINMUX_DATA_REG("PHDR", 0xa405012e, 8) {
+ PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+ PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA }
+ },
+ { PINMUX_DATA_REG("PJDR", 0xa4050130, 8) {
+ PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, 0,
+ PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA }
+ },
+ { PINMUX_DATA_REG("PKDR", 0xa4050132, 8) {
+ PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA,
+ PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA }
+ },
+ { PINMUX_DATA_REG("PLDR", 0xa4050134, 8) {
+ PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA }
+ },
+ { PINMUX_DATA_REG("PMDR", 0xa4050136, 8) {
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA }
+ },
+ { PINMUX_DATA_REG("PNDR", 0xa4050138, 8) {
+ PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+ PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA }
+ },
+ { PINMUX_DATA_REG("PQDR", 0xa405013a, 8) {
+ PTQ7_DATA, PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
+ PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA }
+ },
+ { PINMUX_DATA_REG("PRDR", 0xa405013c, 8) {
+ PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
+ PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA }
+ },
+ { PINMUX_DATA_REG("PSDR", 0xa405013e, 8) {
+ 0, PTS6_DATA, PTS5_DATA, PTS4_DATA,
+ PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA }
+ },
+ { PINMUX_DATA_REG("PTDR", 0xa4050160, 8) {
+ PTT7_DATA, PTT6_DATA, PTT5_DATA, PTT4_DATA,
+ PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA }
+ },
+ { PINMUX_DATA_REG("PUDR", 0xa4050162, 8) {
+ PTU7_DATA, PTU6_DATA, PTU5_DATA, PTU4_DATA,
+ PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA }
+ },
+ { PINMUX_DATA_REG("PVDR", 0xa4050164, 8) {
+ PTV7_DATA, PTV6_DATA, PTV5_DATA, PTV4_DATA,
+ PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA }
+ },
+ { PINMUX_DATA_REG("PWDR", 0xa4050166, 8) {
+ PTW7_DATA, PTW6_DATA, PTW5_DATA, PTW4_DATA,
+ PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA }
+ },
+ { PINMUX_DATA_REG("PXDR", 0xa4050168, 8) {
+ PTX7_DATA, PTX6_DATA, PTX5_DATA, PTX4_DATA,
+ PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA }
+ },
+ { PINMUX_DATA_REG("PYDR", 0xa405016a, 8) {
+ PTY7_DATA, PTY6_DATA, PTY5_DATA, PTY4_DATA,
+ PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA }
+ },
+ { PINMUX_DATA_REG("PZDR", 0xa405016c, 8) {
+ PTZ7_DATA, PTZ6_DATA, PTZ5_DATA, PTZ4_DATA,
+ PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh7724_pinmux_info = {
+ .name = "sh7724_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PTA7,
+ .last_gpio = GPIO_FN_INTC_IRQ0,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+static int __init plat_pinmux_setup(void)
+{
+ return register_pinmux(&sh7724_pinmux_info);
+}
+arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index c1549382c87c..51204dc7ca21 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -12,7 +12,7 @@
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/uio_driver.h>
-#include <linux/sh_cmt.h>
+#include <linux/sh_timer.h>
#include <asm/clock.h>
static struct resource iic0_resources[] = {
@@ -141,7 +141,7 @@ static struct platform_device jpu_device = {
.num_resources = ARRAY_SIZE(jpu_resources),
};
-static struct sh_cmt_config cmt_platform_data = {
+static struct sh_timer_config cmt_platform_data = {
.name = "CMT",
.channel_offset = 0x60,
.timer_bit = 5,
@@ -173,27 +173,123 @@ static struct platform_device cmt_device = {
.num_resources = ARRAY_SIZE(cmt_resources),
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "tmu0",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "tmu0",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "tmu0",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xffe00000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 80, 80, 80, 80 },
+ .clk = "scif0",
}, {
.mapbase = 0xffe10000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 81, 81, 81, 81 },
+ .clk = "scif1",
}, {
.mapbase = 0xffe20000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 82, 82, 82, 82 },
+ .clk = "scif2",
}, {
.mapbase = 0xffe30000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 83, 83, 83, 83 },
+ .clk = "scif3",
}, {
.flags = 0,
}
@@ -209,6 +305,9 @@ static struct platform_device sci_device = {
static struct platform_device *sh7343_devices[] __initdata = {
&cmt_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
&iic0_device,
&iic1_device,
&sci_device,
@@ -234,6 +333,19 @@ static int __init sh7343_devices_setup(void)
}
__initcall(sh7343_devices_setup);
+static struct platform_device *sh7343_early_devices[] __initdata = {
+ &cmt_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7343_early_devices,
+ ARRAY_SIZE(sh7343_early_devices));
+}
+
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 93ecf8ed5c6c..04de0fa85120 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -14,7 +14,7 @@
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/uio_driver.h>
-#include <linux/sh_cmt.h>
+#include <linux/sh_timer.h>
#include <asm/clock.h>
static struct resource iic_resources[] = {
@@ -148,7 +148,7 @@ static struct platform_device veu1_device = {
.num_resources = ARRAY_SIZE(veu1_resources),
};
-static struct sh_cmt_config cmt_platform_data = {
+static struct sh_timer_config cmt_platform_data = {
.name = "CMT",
.channel_offset = 0x60,
.timer_bit = 5,
@@ -180,12 +180,105 @@ static struct platform_device cmt_device = {
.num_resources = ARRAY_SIZE(cmt_resources),
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "tmu0",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "tmu0",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "tmu0",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xffe00000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 80, 80, 80, 80 },
+ .clk = "scif0",
}, {
.flags = 0,
}
@@ -201,6 +294,9 @@ static struct platform_device sci_device = {
static struct platform_device *sh7366_devices[] __initdata = {
&cmt_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
&iic_device,
&sci_device,
&usb_host_device,
@@ -226,6 +322,19 @@ static int __init sh7366_devices_setup(void)
}
__initcall(sh7366_devices_setup);
+static struct platform_device *sh7366_early_devices[] __initdata = {
+ &cmt_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7366_early_devices,
+ ARRAY_SIZE(sh7366_early_devices));
+}
+
enum {
UNUSED=0,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 406747f07dc0..5d6247fecd63 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -13,7 +13,7 @@
#include <linux/serial_sci.h>
#include <linux/mm.h>
#include <linux/uio_driver.h>
-#include <linux/sh_cmt.h>
+#include <linux/sh_timer.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
@@ -177,13 +177,13 @@ static struct platform_device jpu_device = {
.num_resources = ARRAY_SIZE(jpu_resources),
};
-static struct sh_cmt_config cmt_platform_data = {
+static struct sh_timer_config cmt_platform_data = {
.name = "CMT",
.channel_offset = 0x60,
.timer_bit = 5,
.clk = "cmt0",
.clockevent_rating = 125,
- .clocksource_rating = 200,
+ .clocksource_rating = 125,
};
static struct resource cmt_resources[] = {
@@ -209,24 +209,119 @@ static struct platform_device cmt_device = {
.num_resources = ARRAY_SIZE(cmt_resources),
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "tmu0",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "tmu0",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "tmu0",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xffe00000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 80, 80, 80, 80 },
+ .clk = "scif0",
},
{
.mapbase = 0xffe10000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 81, 81, 81, 81 },
+ .clk = "scif1",
},
{
.mapbase = 0xffe20000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 82, 82, 82, 82 },
+ .clk = "scif2",
},
{
.flags = 0,
@@ -243,6 +338,9 @@ static struct platform_device sci_device = {
static struct platform_device *sh7722_devices[] __initdata = {
&cmt_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
&rtc_device,
&usbf_device,
&iic_device,
@@ -269,6 +367,19 @@ static int __init sh7722_devices_setup(void)
}
__initcall(sh7722_devices_setup);
+static struct platform_device *sh7722_early_devices[] __initdata = {
+ &cmt_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7722_early_devices,
+ ARRAY_SIZE(sh7722_early_devices));
+}
+
enum {
UNUSED=0,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index a800466b938c..1429fc5e4286 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -13,7 +13,7 @@
#include <linux/mm.h>
#include <linux/serial_sci.h>
#include <linux/uio_driver.h>
-#include <linux/sh_cmt.h>
+#include <linux/sh_timer.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
@@ -101,13 +101,13 @@ static struct platform_device veu1_device = {
.num_resources = ARRAY_SIZE(veu1_resources),
};
-static struct sh_cmt_config cmt_platform_data = {
+static struct sh_timer_config cmt_platform_data = {
.name = "CMT",
.channel_offset = 0x60,
.timer_bit = 5,
.clk = "cmt0",
.clockevent_rating = 125,
- .clocksource_rating = 200,
+ .clocksource_rating = 125,
};
static struct resource cmt_resources[] = {
@@ -133,37 +133,225 @@ static struct platform_device cmt_device = {
.num_resources = ARRAY_SIZE(cmt_resources),
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "tmu0",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "tmu0",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "tmu0",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+static struct sh_timer_config tmu3_platform_data = {
+ .name = "TMU3",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "tmu1",
+};
+
+static struct resource tmu3_resources[] = {
+ [0] = {
+ .name = "TMU3",
+ .start = 0xffd90008,
+ .end = 0xffd90013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 57,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu3_device = {
+ .name = "sh_tmu",
+ .id = 3,
+ .dev = {
+ .platform_data = &tmu3_platform_data,
+ },
+ .resource = tmu3_resources,
+ .num_resources = ARRAY_SIZE(tmu3_resources),
+};
+
+static struct sh_timer_config tmu4_platform_data = {
+ .name = "TMU4",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "tmu1",
+};
+
+static struct resource tmu4_resources[] = {
+ [0] = {
+ .name = "TMU4",
+ .start = 0xffd90014,
+ .end = 0xffd9001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 58,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu4_device = {
+ .name = "sh_tmu",
+ .id = 4,
+ .dev = {
+ .platform_data = &tmu4_platform_data,
+ },
+ .resource = tmu4_resources,
+ .num_resources = ARRAY_SIZE(tmu4_resources),
+};
+
+static struct sh_timer_config tmu5_platform_data = {
+ .name = "TMU5",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "tmu1",
+};
+
+static struct resource tmu5_resources[] = {
+ [0] = {
+ .name = "TMU5",
+ .start = 0xffd90020,
+ .end = 0xffd9002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 57,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu5_device = {
+ .name = "sh_tmu",
+ .id = 5,
+ .dev = {
+ .platform_data = &tmu5_platform_data,
+ },
+ .resource = tmu5_resources,
+ .num_resources = ARRAY_SIZE(tmu5_resources),
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xffe00000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 80, 80, 80, 80 },
+ .clk = "scif0",
},{
.mapbase = 0xffe10000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 81, 81, 81, 81 },
+ .clk = "scif1",
},{
.mapbase = 0xffe20000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.irqs = { 82, 82, 82, 82 },
+ .clk = "scif2",
},{
.mapbase = 0xa4e30000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { 56, 56, 56, 56 },
+ .clk = "scif3",
},{
.mapbase = 0xa4e40000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { 88, 88, 88, 88 },
+ .clk = "scif4",
},{
.mapbase = 0xa4e50000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { 109, 109, 109, 109 },
+ .clk = "scif5",
}, {
.flags = 0,
}
@@ -255,6 +443,12 @@ static struct platform_device iic_device = {
static struct platform_device *sh7723_devices[] __initdata = {
&cmt_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
&sci_device,
&rtc_device,
&iic_device,
@@ -280,6 +474,22 @@ static int __init sh7723_devices_setup(void)
}
__initcall(sh7723_devices_setup);
+static struct platform_device *sh7723_early_devices[] __initdata = {
+ &cmt_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7723_early_devices,
+ ARRAY_SIZE(sh7723_early_devices));
+}
+
enum {
UNUSED=0,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
new file mode 100644
index 000000000000..852f8104f03a
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -0,0 +1,757 @@
+/*
+ * SH7724 Setup
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on SH7723 Setup
+ * Copyright (C) 2008 Paul Mundt
+ *
+ * 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/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/mm.h>
+#include <linux/serial_sci.h>
+#include <linux/uio_driver.h>
+#include <linux/sh_timer.h>
+#include <linux/io.h>
+#include <asm/clock.h>
+#include <asm/mmzone.h>
+
+/* Serial */
+static struct plat_sci_port sci_platform_data[] = {
+ {
+ .mapbase = 0xffe00000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 80, 80, 80, 80 },
+ .clk = "scif0",
+ }, {
+ .mapbase = 0xffe10000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 81, 81, 81, 81 },
+ .clk = "scif1",
+ }, {
+ .mapbase = 0xffe20000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 82, 82, 82, 82 },
+ .clk = "scif2",
+ }, {
+ .mapbase = 0xa4e30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIFA,
+ .irqs = { 56, 56, 56, 56 },
+ .clk = "scif3",
+ }, {
+ .mapbase = 0xa4e40000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIFA,
+ .irqs = { 88, 88, 88, 88 },
+ .clk = "scif4",
+ }, {
+ .mapbase = 0xa4e50000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIFA,
+ .irqs = { 109, 109, 109, 109 },
+ .clk = "scif5",
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct platform_device sci_device = {
+ .name = "sh-sci",
+ .id = -1,
+ .dev = {
+ .platform_data = sci_platform_data,
+ },
+};
+
+/* RTC */
+static struct resource rtc_resources[] = {
+ [0] = {
+ .start = 0xa465fec0,
+ .end = 0xa465fec0 + 0x58 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ /* Period IRQ */
+ .start = 69,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* Carry IRQ */
+ .start = 70,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ /* Alarm IRQ */
+ .start = 68,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device rtc_device = {
+ .name = "sh-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+
+/* I2C0 */
+static struct resource iic0_resources[] = {
+ [0] = {
+ .name = "IIC0",
+ .start = 0x04470000,
+ .end = 0x04470018 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 96,
+ .end = 99,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device iic0_device = {
+ .name = "i2c-sh_mobile",
+ .id = 0, /* "i2c0" clock */
+ .num_resources = ARRAY_SIZE(iic0_resources),
+ .resource = iic0_resources,
+};
+
+/* I2C1 */
+static struct resource iic1_resources[] = {
+ [0] = {
+ .name = "IIC1",
+ .start = 0x04750000,
+ .end = 0x04750018 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 92,
+ .end = 95,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device iic1_device = {
+ .name = "i2c-sh_mobile",
+ .id = 1, /* "i2c1" clock */
+ .num_resources = ARRAY_SIZE(iic1_resources),
+ .resource = iic1_resources,
+};
+
+/* VPU */
+static struct uio_info vpu_platform_data = {
+ .name = "VPU5F",
+ .version = "0",
+ .irq = 60,
+};
+
+static struct resource vpu_resources[] = {
+ [0] = {
+ .name = "VPU",
+ .start = 0xfe900000,
+ .end = 0xfe902807,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* place holder for contiguous memory */
+ },
+};
+
+static struct platform_device vpu_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 0,
+ .dev = {
+ .platform_data = &vpu_platform_data,
+ },
+ .resource = vpu_resources,
+ .num_resources = ARRAY_SIZE(vpu_resources),
+};
+
+/* VEU0 */
+static struct uio_info veu0_platform_data = {
+ .name = "VEU3F0",
+ .version = "0",
+ .irq = 83,
+};
+
+static struct resource veu0_resources[] = {
+ [0] = {
+ .name = "VEU3F0",
+ .start = 0xfe920000,
+ .end = 0xfe9200cb - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* place holder for contiguous memory */
+ },
+};
+
+static struct platform_device veu0_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 1,
+ .dev = {
+ .platform_data = &veu0_platform_data,
+ },
+ .resource = veu0_resources,
+ .num_resources = ARRAY_SIZE(veu0_resources),
+};
+
+/* VEU1 */
+static struct uio_info veu1_platform_data = {
+ .name = "VEU3F1",
+ .version = "0",
+ .irq = 54,
+};
+
+static struct resource veu1_resources[] = {
+ [0] = {
+ .name = "VEU3F1",
+ .start = 0xfe924000,
+ .end = 0xfe9240cb - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* place holder for contiguous memory */
+ },
+};
+
+static struct platform_device veu1_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 2,
+ .dev = {
+ .platform_data = &veu1_platform_data,
+ },
+ .resource = veu1_resources,
+ .num_resources = ARRAY_SIZE(veu1_resources),
+};
+
+static struct sh_timer_config cmt_platform_data = {
+ .name = "CMT",
+ .channel_offset = 0x60,
+ .timer_bit = 5,
+ .clk = "cmt0",
+ .clockevent_rating = 125,
+ .clocksource_rating = 200,
+};
+
+static struct resource cmt_resources[] = {
+ [0] = {
+ .name = "CMT",
+ .start = 0x044a0060,
+ .end = 0x044a006b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 104,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt_device = {
+ .name = "sh_cmt",
+ .id = 0,
+ .dev = {
+ .platform_data = &cmt_platform_data,
+ },
+ .resource = cmt_resources,
+ .num_resources = ARRAY_SIZE(cmt_resources),
+};
+
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "tmu0",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "tmu0",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "tmu0",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+
+static struct sh_timer_config tmu3_platform_data = {
+ .name = "TMU3",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "tmu1",
+};
+
+static struct resource tmu3_resources[] = {
+ [0] = {
+ .name = "TMU3",
+ .start = 0xffd90008,
+ .end = 0xffd90013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 57,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu3_device = {
+ .name = "sh_tmu",
+ .id = 3,
+ .dev = {
+ .platform_data = &tmu3_platform_data,
+ },
+ .resource = tmu3_resources,
+ .num_resources = ARRAY_SIZE(tmu3_resources),
+};
+
+static struct sh_timer_config tmu4_platform_data = {
+ .name = "TMU4",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "tmu1",
+};
+
+static struct resource tmu4_resources[] = {
+ [0] = {
+ .name = "TMU4",
+ .start = 0xffd90014,
+ .end = 0xffd9001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 58,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu4_device = {
+ .name = "sh_tmu",
+ .id = 4,
+ .dev = {
+ .platform_data = &tmu4_platform_data,
+ },
+ .resource = tmu4_resources,
+ .num_resources = ARRAY_SIZE(tmu4_resources),
+};
+
+static struct sh_timer_config tmu5_platform_data = {
+ .name = "TMU5",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "tmu1",
+};
+
+static struct resource tmu5_resources[] = {
+ [0] = {
+ .name = "TMU5",
+ .start = 0xffd90020,
+ .end = 0xffd9002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 57,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu5_device = {
+ .name = "sh_tmu",
+ .id = 5,
+ .dev = {
+ .platform_data = &tmu5_platform_data,
+ },
+ .resource = tmu5_resources,
+ .num_resources = ARRAY_SIZE(tmu5_resources),
+};
+
+static struct platform_device *sh7724_devices[] __initdata = {
+ &cmt_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
+ &sci_device,
+ &rtc_device,
+ &iic0_device,
+ &iic1_device,
+ &vpu_device,
+ &veu0_device,
+ &veu1_device,
+};
+
+static int __init sh7724_devices_setup(void)
+{
+ clk_always_enable("vpu0"); /* VPU */
+ clk_always_enable("veu1"); /* VEU3F1 */
+ clk_always_enable("veu0"); /* VEU3F0 */
+
+ platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20);
+ platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
+ platform_resource_setup_memory(&veu1_device, "veu1", 2 << 20);
+
+ return platform_add_devices(sh7724_devices,
+ ARRAY_SIZE(sh7724_devices));
+}
+device_initcall(sh7724_devices_setup);
+
+static struct platform_device *sh7724_early_devices[] __initdata = {
+ &cmt_device,
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7724_early_devices,
+ ARRAY_SIZE(sh7724_early_devices));
+}
+
+enum {
+ UNUSED = 0,
+
+ /* interrupt sources */
+ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
+ HUDI,
+ DMAC1A_DEI0, DMAC1A_DEI1, DMAC1A_DEI2, DMAC1A_DEI3,
+ _2DG_TRI, _2DG_INI, _2DG_CEI, _2DG_BRK,
+ DMAC0A_DEI0, DMAC0A_DEI1, DMAC0A_DEI2, DMAC0A_DEI3,
+ VIO_CEU20I, VIO_BEU20I, VIO_VEU3F1, VIO_VOUI,
+ SCIFA_SCIFA0,
+ VPU_VPUI,
+ TPU_TPUI,
+ CEU21I,
+ BEU21I,
+ USB_USI0,
+ ATAPI,
+ RTC_ATI, RTC_PRI, RTC_CUI,
+ DMAC1B_DEI4, DMAC1B_DEI5, DMAC1B_DADERR,
+ DMAC0B_DEI4, DMAC0B_DEI5, DMAC0B_DADERR,
+ KEYSC_KEYI,
+ SCIF_SCIF0, SCIF_SCIF1, SCIF_SCIF2,
+ VEU3F0I,
+ MSIOF_MSIOFI0, MSIOF_MSIOFI1,
+ SPU_SPUI0, SPU_SPUI1,
+ SCIFA_SCIFA1,
+/* ICB_ICBI, */
+ ETHI,
+ I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI,
+ I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI,
+ SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2,
+ CMT_CMTI,
+ TSIF_TSIFI,
+/* ICB_LMBI, */
+ FSI_FSI,
+ SCIFA_SCIFA2,
+ TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2,
+ IRDA_IRDAI,
+ SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2,
+ JPU_JPUI,
+ MMC_MMCI0, MMC_MMCI1, MMC_MMCI2,
+ LCDC_LCDCI,
+ TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2,
+
+ /* interrupt groups */
+ DMAC1A, _2DG, DMAC0A, VIO, RTC,
+ DMAC1B, DMAC0B, I2C0, I2C1, SDHI0, SDHI1, SPU, MMC,
+};
+
+static struct intc_vect vectors[] __initdata = {
+ INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
+ INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
+ INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+ INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0),
+
+ INTC_VECT(DMAC1A_DEI0, 0x700),
+ INTC_VECT(DMAC1A_DEI1, 0x720),
+ INTC_VECT(DMAC1A_DEI2, 0x740),
+ INTC_VECT(DMAC1A_DEI3, 0x760),
+
+ INTC_VECT(_2DG_TRI, 0x780),
+ INTC_VECT(_2DG_INI, 0x7A0),
+ INTC_VECT(_2DG_CEI, 0x7C0),
+ INTC_VECT(_2DG_BRK, 0x7E0),
+
+ INTC_VECT(DMAC0A_DEI0, 0x800),
+ INTC_VECT(DMAC0A_DEI1, 0x820),
+ INTC_VECT(DMAC0A_DEI2, 0x840),
+ INTC_VECT(DMAC0A_DEI3, 0x860),
+
+ INTC_VECT(VIO_CEU20I, 0x880),
+ INTC_VECT(VIO_BEU20I, 0x8A0),
+ INTC_VECT(VIO_VEU3F1, 0x8C0),
+ INTC_VECT(VIO_VOUI, 0x8E0),
+
+ INTC_VECT(SCIFA_SCIFA0, 0x900),
+ INTC_VECT(VPU_VPUI, 0x980),
+ INTC_VECT(TPU_TPUI, 0x9A0),
+ INTC_VECT(CEU21I, 0x9E0),
+ INTC_VECT(BEU21I, 0xA00),
+ INTC_VECT(USB_USI0, 0xA20),
+ INTC_VECT(ATAPI, 0xA60),
+
+ INTC_VECT(RTC_ATI, 0xA80),
+ INTC_VECT(RTC_PRI, 0xAA0),
+ INTC_VECT(RTC_CUI, 0xAC0),
+
+ INTC_VECT(DMAC1B_DEI4, 0xB00),
+ INTC_VECT(DMAC1B_DEI5, 0xB20),
+ INTC_VECT(DMAC1B_DADERR, 0xB40),
+
+ INTC_VECT(DMAC0B_DEI4, 0xB80),
+ INTC_VECT(DMAC0B_DEI5, 0xBA0),
+ INTC_VECT(DMAC0B_DADERR, 0xBC0),
+
+ INTC_VECT(KEYSC_KEYI, 0xBE0),
+ INTC_VECT(SCIF_SCIF0, 0xC00),
+ INTC_VECT(SCIF_SCIF1, 0xC20),
+ INTC_VECT(SCIF_SCIF2, 0xC40),
+ INTC_VECT(VEU3F0I, 0xC60),
+ INTC_VECT(MSIOF_MSIOFI0, 0xC80),
+ INTC_VECT(MSIOF_MSIOFI1, 0xCA0),
+ INTC_VECT(SPU_SPUI0, 0xCC0),
+ INTC_VECT(SPU_SPUI1, 0xCE0),
+ INTC_VECT(SCIFA_SCIFA1, 0xD00),
+
+/* INTC_VECT(ICB_ICBI, 0xD20), */
+ INTC_VECT(ETHI, 0xD60),
+
+ INTC_VECT(I2C1_ALI, 0xD80),
+ INTC_VECT(I2C1_TACKI, 0xDA0),
+ INTC_VECT(I2C1_WAITI, 0xDC0),
+ INTC_VECT(I2C1_DTEI, 0xDE0),
+
+ INTC_VECT(I2C0_ALI, 0xE00),
+ INTC_VECT(I2C0_TACKI, 0xE20),
+ INTC_VECT(I2C0_WAITI, 0xE40),
+ INTC_VECT(I2C0_DTEI, 0xE60),
+
+ INTC_VECT(SDHI0_SDHII0, 0xE80),
+ INTC_VECT(SDHI0_SDHII1, 0xEA0),
+ INTC_VECT(SDHI0_SDHII2, 0xEC0),
+
+ INTC_VECT(CMT_CMTI, 0xF00),
+ INTC_VECT(TSIF_TSIFI, 0xF20),
+/* INTC_VECT(ICB_LMBI, 0xF60), */
+ INTC_VECT(FSI_FSI, 0xF80),
+ INTC_VECT(SCIFA_SCIFA2, 0xFA0),
+
+ INTC_VECT(TMU0_TUNI0, 0x400),
+ INTC_VECT(TMU0_TUNI1, 0x420),
+ INTC_VECT(TMU0_TUNI2, 0x440),
+
+ INTC_VECT(IRDA_IRDAI, 0x480),
+
+ INTC_VECT(SDHI1_SDHII0, 0x4E0),
+ INTC_VECT(SDHI1_SDHII1, 0x500),
+ INTC_VECT(SDHI1_SDHII2, 0x520),
+
+ INTC_VECT(JPU_JPUI, 0x560),
+
+ INTC_VECT(MMC_MMCI0, 0x580),
+ INTC_VECT(MMC_MMCI1, 0x5A0),
+ INTC_VECT(MMC_MMCI2, 0x5C0),
+
+ INTC_VECT(LCDC_LCDCI, 0xF40),
+
+ INTC_VECT(TMU1_TUNI0, 0x920),
+ INTC_VECT(TMU1_TUNI1, 0x940),
+ INTC_VECT(TMU1_TUNI2, 0x960),
+};
+
+static struct intc_group groups[] __initdata = {
+ INTC_GROUP(DMAC1A, DMAC1A_DEI0, DMAC1A_DEI1, DMAC1A_DEI2, DMAC1A_DEI3),
+ INTC_GROUP(_2DG, _2DG_TRI, _2DG_INI, _2DG_CEI, _2DG_BRK),
+ INTC_GROUP(DMAC0A, DMAC0A_DEI0, DMAC0A_DEI1, DMAC0A_DEI2, DMAC0A_DEI3),
+ INTC_GROUP(VIO, VIO_CEU20I, VIO_BEU20I, VIO_VEU3F1, VIO_VOUI),
+ INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
+ INTC_GROUP(DMAC1B, DMAC1B_DEI4, DMAC1B_DEI5, DMAC1B_DADERR),
+ INTC_GROUP(DMAC0B, DMAC0B_DEI4, DMAC0B_DEI5, DMAC0B_DADERR),
+ INTC_GROUP(I2C0, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI),
+ INTC_GROUP(I2C1, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI),
+ INTC_GROUP(SDHI0, SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2),
+ INTC_GROUP(SDHI1, SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2),
+ INTC_GROUP(SPU, SPU_SPUI0, SPU_SPUI1),
+ INTC_GROUP(MMC, MMC_MMCI0, MMC_MMCI1, MMC_MMCI2),
+};
+
+/* FIXMEEEEEEEEEEEEEEEEEEE !!!!! */
+/* very bad manual !! */
+static struct intc_mask_reg mask_registers[] __initdata = {
+ { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
+ { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
+ /*SDHII3?*/0, SDHI1_SDHII2, SDHI1_SDHII1, SDHI1_SDHII0 } },
+ { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
+ { VIO_VOUI, VIO_VEU3F1, VIO_BEU20I, VIO_CEU20I,
+ DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } },
+ { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */
+ { 0, 0, 0, VPU_VPUI, ATAPI, ETHI, 0, /*SCIFA3*/SCIFA_SCIFA0 } },
+ { 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */
+ { DMAC1A_DEI3, DMAC1A_DEI2, DMAC1A_DEI1, DMAC1A_DEI0,
+ SPU_SPUI1, SPU_SPUI0, BEU21I, IRDA_IRDAI } },
+ { 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */
+ { 0, TMU0_TUNI2, TMU0_TUNI1, TMU0_TUNI0,
+ JPU_JPUI, 0, 0, LCDC_LCDCI } },
+ { 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */
+ { KEYSC_KEYI, DMAC0B_DADERR, DMAC0B_DEI5, DMAC0B_DEI4,
+ VEU3F0I, SCIF_SCIF2, SCIF_SCIF1, SCIF_SCIF0 } },
+ { 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */
+ { 0, 0, /*ICB_ICBI*/0, /*SCIFA4*/SCIFA_SCIFA1,
+ CEU21I, 0, MSIOF_MSIOFI1, MSIOF_MSIOFI0 } },
+ { 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */
+ { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI,
+ I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI } },
+ { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
+ { /*SDHII3*/0, SDHI0_SDHII2, SDHI0_SDHII1, SDHI0_SDHII0,
+ 0, 0, /*SCIFA5*/SCIFA_SCIFA2, FSI_FSI } },
+ { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
+ { 0, 0, 0, CMT_CMTI, 0, /*USB1*/0, USB_USI0, 0 } },
+ { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
+ { 0, DMAC1B_DADERR, DMAC1B_DEI5, DMAC1B_DEI4,
+ 0, RTC_ATI, RTC_PRI, RTC_CUI } },
+ { 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */
+ { _2DG_BRK, _2DG_CEI, _2DG_INI, _2DG_TRI,
+ 0, TPU_TPUI, /*ICB_LMBI*/0, TSIF_TSIFI } },
+ { 0xa40800b0, 0xa40800f0, 8, /* IMR12 / IMCR12 */
+ { 0, 0, 0, 0, 0, 0, 0, 0/*2DDMAC*/ } },
+ { 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */
+ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+ { 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0_TUNI0, TMU0_TUNI1,
+ TMU0_TUNI2, IRDA_IRDAI } },
+ { 0xa4080004, 0, 16, 4, /* IPRB */ { JPU_JPUI, LCDC_LCDCI,
+ DMAC1A, BEU21I } },
+ { 0xa4080008, 0, 16, 4, /* IPRC */ { TMU1_TUNI0, TMU1_TUNI1,
+ TMU1_TUNI2, SPU } },
+ { 0xa408000c, 0, 16, 4, /* IPRD */ { 0, MMC, 0, ATAPI } },
+ { 0xa4080010, 0, 16, 4, /* IPRE */
+ { DMAC0A, /*BEU?VEU?*/VIO, /*SCIFA3*/SCIFA_SCIFA0, /*VPU5F*/
+ VPU_VPUI } },
+ { 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC_KEYI, DMAC0B,
+ USB_USI0, CMT_CMTI } },
+ { 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF_SCIF0, SCIF_SCIF1,
+ SCIF_SCIF2, VEU3F0I } },
+ { 0xa408001c, 0, 16, 4, /* IPRH */ { MSIOF_MSIOFI0, MSIOF_MSIOFI1,
+ I2C1, I2C0 } },
+ { 0xa4080020, 0, 16, 4, /* IPRI */ { /*SCIFA4*/SCIFA_SCIFA1, /*ICB*/0,
+ TSIF_TSIFI, _2DG/*ICB?*/ } },
+ { 0xa4080024, 0, 16, 4, /* IPRJ */ { CEU21I, ETHI, FSI_FSI, SDHI1 } },
+ { 0xa4080028, 0, 16, 4, /* IPRK */ { RTC, DMAC1B, /*ICB?*/0, SDHI0 } },
+ { 0xa408002c, 0, 16, 4, /* IPRL */ { /*SCIFA5*/SCIFA_SCIFA2, 0,
+ TPU_TPUI, /*2DDMAC*/0 } },
+ { 0xa4140010, 0, 32, 4, /* INTPRI00 */
+ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static struct intc_sense_reg sense_registers[] __initdata = {
+ { 0xa414001c, 16, 2, /* ICR1 */
+ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static struct intc_mask_reg ack_registers[] __initdata = {
+ { 0xa4140024, 0, 8, /* INTREQ00 */
+ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static DECLARE_INTC_DESC_ACK(intc_desc, "sh7724", vectors, groups,
+ mask_registers, prio_registers, sense_registers,
+ ack_registers);
+
+void __init plat_irq_setup(void)
+{
+ register_intc_controller(&intc_desc);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index bdf0f61ae1ed..c91f34c9aa83 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
+#include <linux/sh_timer.h>
#include <linux/io.h>
#include <linux/serial_sci.h>
@@ -113,7 +114,195 @@ static struct platform_device usbf_device = {
.resource = usbf_resources,
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 28,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 29,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 30,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+static struct sh_timer_config tmu3_platform_data = {
+ .name = "TMU3",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+};
+
+static struct resource tmu3_resources[] = {
+ [0] = {
+ .name = "TMU3",
+ .start = 0xffd88008,
+ .end = 0xffd88013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 96,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu3_device = {
+ .name = "sh_tmu",
+ .id = 3,
+ .dev = {
+ .platform_data = &tmu3_platform_data,
+ },
+ .resource = tmu3_resources,
+ .num_resources = ARRAY_SIZE(tmu3_resources),
+};
+
+static struct sh_timer_config tmu4_platform_data = {
+ .name = "TMU4",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource tmu4_resources[] = {
+ [0] = {
+ .name = "TMU4",
+ .start = 0xffd88014,
+ .end = 0xffd8801f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 97,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu4_device = {
+ .name = "sh_tmu",
+ .id = 4,
+ .dev = {
+ .platform_data = &tmu4_platform_data,
+ },
+ .resource = tmu4_resources,
+ .num_resources = ARRAY_SIZE(tmu4_resources),
+};
+
+static struct sh_timer_config tmu5_platform_data = {
+ .name = "TMU5",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu5_resources[] = {
+ [0] = {
+ .name = "TMU5",
+ .start = 0xffd88020,
+ .end = 0xffd8802b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 98,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu5_device = {
+ .name = "sh_tmu",
+ .id = 5,
+ .dev = {
+ .platform_data = &tmu5_platform_data,
+ },
+ .resource = tmu5_resources,
+ .num_resources = ARRAY_SIZE(tmu5_resources),
+};
+
static struct platform_device *sh7763_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
&rtc_device,
&sci_device,
&usb_ohci_device,
@@ -127,6 +316,21 @@ static int __init sh7763_devices_setup(void)
}
__initcall(sh7763_devices_setup);
+static struct platform_device *sh7763_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7763_early_devices,
+ ARRAY_SIZE(sh7763_early_devices));
+}
+
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
index b73578ee295d..b61d6143aaaa 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
static struct plat_sci_port sci_platform_data[] = {
{
@@ -76,7 +77,288 @@ static struct platform_device sci_device = {
},
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+static struct sh_timer_config tmu3_platform_data = {
+ .name = "TMU3",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+};
+
+static struct resource tmu3_resources[] = {
+ [0] = {
+ .name = "TMU3",
+ .start = 0xffd81008,
+ .end = 0xffd81013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 19,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu3_device = {
+ .name = "sh_tmu",
+ .id = 3,
+ .dev = {
+ .platform_data = &tmu3_platform_data,
+ },
+ .resource = tmu3_resources,
+ .num_resources = ARRAY_SIZE(tmu3_resources),
+};
+
+static struct sh_timer_config tmu4_platform_data = {
+ .name = "TMU4",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource tmu4_resources[] = {
+ [0] = {
+ .name = "TMU4",
+ .start = 0xffd81014,
+ .end = 0xffd8101f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 20,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu4_device = {
+ .name = "sh_tmu",
+ .id = 4,
+ .dev = {
+ .platform_data = &tmu4_platform_data,
+ },
+ .resource = tmu4_resources,
+ .num_resources = ARRAY_SIZE(tmu4_resources),
+};
+
+static struct sh_timer_config tmu5_platform_data = {
+ .name = "TMU5",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu5_resources[] = {
+ [0] = {
+ .name = "TMU5",
+ .start = 0xffd81020,
+ .end = 0xffd8102f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 21,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu5_device = {
+ .name = "sh_tmu",
+ .id = 5,
+ .dev = {
+ .platform_data = &tmu5_platform_data,
+ },
+ .resource = tmu5_resources,
+ .num_resources = ARRAY_SIZE(tmu5_resources),
+};
+
+static struct sh_timer_config tmu6_platform_data = {
+ .name = "TMU6",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+};
+
+static struct resource tmu6_resources[] = {
+ [0] = {
+ .name = "TMU6",
+ .start = 0xffd82008,
+ .end = 0xffd82013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 22,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu6_device = {
+ .name = "sh_tmu",
+ .id = 6,
+ .dev = {
+ .platform_data = &tmu6_platform_data,
+ },
+ .resource = tmu6_resources,
+ .num_resources = ARRAY_SIZE(tmu6_resources),
+};
+
+static struct sh_timer_config tmu7_platform_data = {
+ .name = "TMU7",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource tmu7_resources[] = {
+ [0] = {
+ .name = "TMU7",
+ .start = 0xffd82014,
+ .end = 0xffd8201f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 23,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu7_device = {
+ .name = "sh_tmu",
+ .id = 7,
+ .dev = {
+ .platform_data = &tmu7_platform_data,
+ },
+ .resource = tmu7_resources,
+ .num_resources = ARRAY_SIZE(tmu7_resources),
+};
+
+static struct sh_timer_config tmu8_platform_data = {
+ .name = "TMU8",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu8_resources[] = {
+ [0] = {
+ .name = "TMU8",
+ .start = 0xffd82020,
+ .end = 0xffd8202b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 24,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu8_device = {
+ .name = "sh_tmu",
+ .id = 8,
+ .dev = {
+ .platform_data = &tmu8_platform_data,
+ },
+ .resource = tmu8_resources,
+ .num_resources = ARRAY_SIZE(tmu8_resources),
+};
+
static struct platform_device *sh7770_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
+ &tmu6_device,
+ &tmu7_device,
+ &tmu8_device,
&sci_device,
};
@@ -87,6 +369,24 @@ static int __init sh7770_devices_setup(void)
}
__initcall(sh7770_devices_setup);
+static struct platform_device *sh7770_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
+ &tmu6_device,
+ &tmu7_device,
+ &tmu8_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7770_early_devices,
+ ARRAY_SIZE(sh7770_early_devices));
+}
+
void __init plat_irq_setup(void)
{
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index 6f7227cd65bf..f1df02095062 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -12,6 +12,189 @@
#include <linux/serial.h>
#include <linux/io.h>
#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 28,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 29,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 30,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+static struct sh_timer_config tmu3_platform_data = {
+ .name = "TMU3",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+};
+
+static struct resource tmu3_resources[] = {
+ [0] = {
+ .name = "TMU3",
+ .start = 0xffdc0008,
+ .end = 0xffdc0013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 96,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu3_device = {
+ .name = "sh_tmu",
+ .id = 3,
+ .dev = {
+ .platform_data = &tmu3_platform_data,
+ },
+ .resource = tmu3_resources,
+ .num_resources = ARRAY_SIZE(tmu3_resources),
+};
+
+static struct sh_timer_config tmu4_platform_data = {
+ .name = "TMU4",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource tmu4_resources[] = {
+ [0] = {
+ .name = "TMU4",
+ .start = 0xffdc0014,
+ .end = 0xffdc001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 97,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu4_device = {
+ .name = "sh_tmu",
+ .id = 4,
+ .dev = {
+ .platform_data = &tmu4_platform_data,
+ },
+ .resource = tmu4_resources,
+ .num_resources = ARRAY_SIZE(tmu4_resources),
+};
+
+static struct sh_timer_config tmu5_platform_data = {
+ .name = "TMU5",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu5_resources[] = {
+ [0] = {
+ .name = "TMU5",
+ .start = 0xffdc0020,
+ .end = 0xffdc002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 98,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu5_device = {
+ .name = "sh_tmu",
+ .id = 5,
+ .dev = {
+ .platform_data = &tmu5_platform_data,
+ },
+ .resource = tmu5_resources,
+ .num_resources = ARRAY_SIZE(tmu5_resources),
+};
static struct resource rtc_resources[] = {
[0] = {
@@ -58,6 +241,12 @@ static struct platform_device sci_device = {
};
static struct platform_device *sh7780_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
&rtc_device,
&sci_device,
};
@@ -69,6 +258,21 @@ static int __init sh7780_devices_setup(void)
}
__initcall(sh7780_devices_setup);
+static struct platform_device *sh7780_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7780_early_devices,
+ ARRAY_SIZE(sh7780_early_devices));
+}
+
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index d80802a49dbd..dc5d3e507a21 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -13,8 +13,191 @@
#include <linux/serial_sci.h>
#include <linux/io.h>
#include <linux/mm.h>
+#include <linux/sh_timer.h>
#include <asm/mmzone.h>
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 28,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 29,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 30,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+static struct sh_timer_config tmu3_platform_data = {
+ .name = "TMU3",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+};
+
+static struct resource tmu3_resources[] = {
+ [0] = {
+ .name = "TMU3",
+ .start = 0xffdc0008,
+ .end = 0xffdc0013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 96,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu3_device = {
+ .name = "sh_tmu",
+ .id = 3,
+ .dev = {
+ .platform_data = &tmu3_platform_data,
+ },
+ .resource = tmu3_resources,
+ .num_resources = ARRAY_SIZE(tmu3_resources),
+};
+
+static struct sh_timer_config tmu4_platform_data = {
+ .name = "TMU4",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource tmu4_resources[] = {
+ [0] = {
+ .name = "TMU4",
+ .start = 0xffdc0014,
+ .end = 0xffdc001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 97,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu4_device = {
+ .name = "sh_tmu",
+ .id = 4,
+ .dev = {
+ .platform_data = &tmu4_platform_data,
+ },
+ .resource = tmu4_resources,
+ .num_resources = ARRAY_SIZE(tmu4_resources),
+};
+
+static struct sh_timer_config tmu5_platform_data = {
+ .name = "TMU5",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu5_resources[] = {
+ [0] = {
+ .name = "TMU5",
+ .start = 0xffdc0020,
+ .end = 0xffdc002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 98,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu5_device = {
+ .name = "sh_tmu",
+ .id = 5,
+ .dev = {
+ .platform_data = &tmu5_platform_data,
+ },
+ .resource = tmu5_resources,
+ .num_resources = ARRAY_SIZE(tmu5_resources),
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xffea0000,
@@ -60,6 +243,12 @@ static struct platform_device sci_device = {
};
static struct platform_device *sh7785_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
&sci_device,
};
@@ -70,6 +259,21 @@ static int __init sh7785_devices_setup(void)
}
__initcall(sh7785_devices_setup);
+static struct platform_device *sh7785_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7785_early_devices,
+ ARRAY_SIZE(sh7785_early_devices));
+}
+
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 90e8cfff55fd..2c464bf5a899 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2009 Renesas Solutions Corp.
* Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ * Paul Mundt <paul.mundt@renesas.com>
*
* Based on SH7785 Setup
*
@@ -19,6 +20,7 @@
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
+#include <linux/sh_timer.h>
#include <asm/mmzone.h>
static struct plat_sci_port sci_platform_data[] = {
@@ -69,6 +71,368 @@ static struct platform_device sci_device = {
},
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffd80020,
+ .end = 0xffd8002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+static struct sh_timer_config tmu3_platform_data = {
+ .name = "TMU3",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+};
+
+static struct resource tmu3_resources[] = {
+ [0] = {
+ .name = "TMU3",
+ .start = 0xffda0008,
+ .end = 0xffda0013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 20,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu3_device = {
+ .name = "sh_tmu",
+ .id = 3,
+ .dev = {
+ .platform_data = &tmu3_platform_data,
+ },
+ .resource = tmu3_resources,
+ .num_resources = ARRAY_SIZE(tmu3_resources),
+};
+
+static struct sh_timer_config tmu4_platform_data = {
+ .name = "TMU4",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource tmu4_resources[] = {
+ [0] = {
+ .name = "TMU4",
+ .start = 0xffda0014,
+ .end = 0xffda001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 21,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu4_device = {
+ .name = "sh_tmu",
+ .id = 4,
+ .dev = {
+ .platform_data = &tmu4_platform_data,
+ },
+ .resource = tmu4_resources,
+ .num_resources = ARRAY_SIZE(tmu4_resources),
+};
+
+static struct sh_timer_config tmu5_platform_data = {
+ .name = "TMU5",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu5_resources[] = {
+ [0] = {
+ .name = "TMU5",
+ .start = 0xffda0020,
+ .end = 0xffda002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 22,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu5_device = {
+ .name = "sh_tmu",
+ .id = 5,
+ .dev = {
+ .platform_data = &tmu5_platform_data,
+ },
+ .resource = tmu5_resources,
+ .num_resources = ARRAY_SIZE(tmu5_resources),
+};
+
+static struct sh_timer_config tmu6_platform_data = {
+ .name = "TMU6",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+};
+
+static struct resource tmu6_resources[] = {
+ [0] = {
+ .name = "TMU6",
+ .start = 0xffdc0008,
+ .end = 0xffdc0013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 45,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu6_device = {
+ .name = "sh_tmu",
+ .id = 6,
+ .dev = {
+ .platform_data = &tmu6_platform_data,
+ },
+ .resource = tmu6_resources,
+ .num_resources = ARRAY_SIZE(tmu6_resources),
+};
+
+static struct sh_timer_config tmu7_platform_data = {
+ .name = "TMU7",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource tmu7_resources[] = {
+ [0] = {
+ .name = "TMU7",
+ .start = 0xffdc0014,
+ .end = 0xffdc001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 45,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu7_device = {
+ .name = "sh_tmu",
+ .id = 7,
+ .dev = {
+ .platform_data = &tmu7_platform_data,
+ },
+ .resource = tmu7_resources,
+ .num_resources = ARRAY_SIZE(tmu7_resources),
+};
+
+static struct sh_timer_config tmu8_platform_data = {
+ .name = "TMU8",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu8_resources[] = {
+ [0] = {
+ .name = "TMU8",
+ .start = 0xffdc0020,
+ .end = 0xffdc002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 45,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu8_device = {
+ .name = "sh_tmu",
+ .id = 8,
+ .dev = {
+ .platform_data = &tmu8_platform_data,
+ },
+ .resource = tmu8_resources,
+ .num_resources = ARRAY_SIZE(tmu8_resources),
+};
+
+static struct sh_timer_config tmu9_platform_data = {
+ .name = "TMU9",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+};
+
+static struct resource tmu9_resources[] = {
+ [0] = {
+ .name = "TMU9",
+ .start = 0xffde0008,
+ .end = 0xffde0013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 46,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu9_device = {
+ .name = "sh_tmu",
+ .id = 9,
+ .dev = {
+ .platform_data = &tmu9_platform_data,
+ },
+ .resource = tmu9_resources,
+ .num_resources = ARRAY_SIZE(tmu9_resources),
+};
+
+static struct sh_timer_config tmu10_platform_data = {
+ .name = "TMU10",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource tmu10_resources[] = {
+ [0] = {
+ .name = "TMU10",
+ .start = 0xffde0014,
+ .end = 0xffde001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 46,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu10_device = {
+ .name = "sh_tmu",
+ .id = 10,
+ .dev = {
+ .platform_data = &tmu10_platform_data,
+ },
+ .resource = tmu10_resources,
+ .num_resources = ARRAY_SIZE(tmu10_resources),
+};
+
+static struct sh_timer_config tmu11_platform_data = {
+ .name = "TMU11",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu11_resources[] = {
+ [0] = {
+ .name = "TMU11",
+ .start = 0xffde0020,
+ .end = 0xffde002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 46,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu11_device = {
+ .name = "sh_tmu",
+ .id = 11,
+ .dev = {
+ .platform_data = &tmu11_platform_data,
+ },
+ .resource = tmu11_resources,
+ .num_resources = ARRAY_SIZE(tmu11_resources),
+};
+
static struct resource usb_ohci_resources[] = {
[0] = {
.start = 0xffe70400,
@@ -94,6 +458,21 @@ static struct platform_device usb_ohci_device = {
.resource = usb_ohci_resources,
};
+static struct platform_device *sh7786_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
+ &tmu6_device,
+ &tmu7_device,
+ &tmu8_device,
+ &tmu9_device,
+ &tmu10_device,
+ &tmu11_device,
+};
+
static struct platform_device *sh7786_devices[] __initdata = {
&sci_device,
&usb_ohci_device,
@@ -156,12 +535,26 @@ static void __init sh7786_usb_setup(void)
static int __init sh7786_devices_setup(void)
{
+ int ret;
+
sh7786_usb_setup();
+
+ ret = platform_add_devices(sh7786_early_devices,
+ ARRAY_SIZE(sh7786_early_devices));
+ if (unlikely(ret != 0))
+ return ret;
+
return platform_add_devices(sh7786_devices,
ARRAY_SIZE(sh7786_devices));
}
device_initcall(sh7786_devices_setup);
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh7786_early_devices,
+ ARRAY_SIZE(sh7786_early_devices));
+}
+
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index bd35f32534b9..9d5185b42f13 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -1,7 +1,7 @@
/*
- * SH-X3 Setup
+ * SH-X3 Prototype Setup
*
- * Copyright (C) 2007 Paul Mundt
+ * Copyright (C) 2007 - 2009 Paul Mundt
*
* 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
@@ -12,6 +12,7 @@
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/io.h>
+#include <linux/sh_timer.h>
#include <asm/mmzone.h>
static struct plat_sci_port sci_platform_data[] = {
@@ -48,17 +49,221 @@ static struct platform_device sci_device = {
},
};
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = 0xffc10008,
+ .end = 0xffc10013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = 0xffc10014,
+ .end = 0xffc1001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 17,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = 0xffc10020,
+ .end = 0xffc1002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 18,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+static struct sh_timer_config tmu3_platform_data = {
+ .name = "TMU3",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+};
+
+static struct resource tmu3_resources[] = {
+ [0] = {
+ .name = "TMU3",
+ .start = 0xffc20008,
+ .end = 0xffc20013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 19,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu3_device = {
+ .name = "sh_tmu",
+ .id = 3,
+ .dev = {
+ .platform_data = &tmu3_platform_data,
+ },
+ .resource = tmu3_resources,
+ .num_resources = ARRAY_SIZE(tmu3_resources),
+};
+
+static struct sh_timer_config tmu4_platform_data = {
+ .name = "TMU4",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+};
+
+static struct resource tmu4_resources[] = {
+ [0] = {
+ .name = "TMU4",
+ .start = 0xffc20014,
+ .end = 0xffc2001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 20,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu4_device = {
+ .name = "sh_tmu",
+ .id = 4,
+ .dev = {
+ .platform_data = &tmu4_platform_data,
+ },
+ .resource = tmu4_resources,
+ .num_resources = ARRAY_SIZE(tmu4_resources),
+};
+
+static struct sh_timer_config tmu5_platform_data = {
+ .name = "TMU5",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu5_resources[] = {
+ [0] = {
+ .name = "TMU5",
+ .start = 0xffc20020,
+ .end = 0xffc2002b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 21,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu5_device = {
+ .name = "sh_tmu",
+ .id = 5,
+ .dev = {
+ .platform_data = &tmu5_platform_data,
+ },
+ .resource = tmu5_resources,
+ .num_resources = ARRAY_SIZE(tmu5_resources),
+};
+
+static struct platform_device *shx3_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+ &tmu3_device,
+ &tmu4_device,
+ &tmu5_device,
+};
+
static struct platform_device *shx3_devices[] __initdata = {
&sci_device,
};
static int __init shx3_devices_setup(void)
{
+ int ret;
+
+ ret = platform_add_devices(shx3_early_devices,
+ ARRAY_SIZE(shx3_early_devices));
+ if (unlikely(ret != 0))
+ return ret;
+
return platform_add_devices(shx3_devices,
ARRAY_SIZE(shx3_devices));
}
__initcall(shx3_devices_setup);
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(shx3_early_devices,
+ ARRAY_SIZE(shx3_early_devices));
+}
+
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh5/Makefile b/arch/sh/kernel/cpu/sh5/Makefile
index ce4602ea23a8..a184a31e686e 100644
--- a/arch/sh/kernel/cpu/sh5/Makefile
+++ b/arch/sh/kernel/cpu/sh5/Makefile
@@ -6,6 +6,9 @@ obj-y := entry.o probe.o switchto.o
obj-$(CONFIG_SH_FPU) += fpu.o
obj-$(CONFIG_KALLSYMS) += unwind.o
+# CPU subtype setup
+obj-$(CONFIG_CPU_SH5) += setup-sh5.o
+
# Primary on-chip clocks (common)
clock-$(CONFIG_CPU_SH5) := clock-sh5.o
diff --git a/arch/sh/kernel/cpu/sh5/clock-sh5.c b/arch/sh/kernel/cpu/sh5/clock-sh5.c
index 52c49248833a..5486324880e1 100644
--- a/arch/sh/kernel/cpu/sh5/clock-sh5.c
+++ b/arch/sh/kernel/cpu/sh5/clock-sh5.c
@@ -71,7 +71,7 @@ static struct clk_ops *sh5_clk_ops[] = {
void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
{
- cprc_base = onchip_remap(CPRC_BASE, 1024, "CPRC");
+ cprc_base = (unsigned long)ioremap_nocache(CPRC_BASE, 1024);
BUG_ON(!cprc_base);
if (idx < ARRAY_SIZE(sh5_clk_ops))
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index 7e49cb812f8b..b0aacf675258 100644
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -812,27 +812,6 @@ no_underflow:
! exceptions
add SP, ZERO, r14
-#ifdef CONFIG_POOR_MANS_STRACE
- /* We've pushed all the registers now, so only r2-r4 hold anything
- * useful. Move them into callee save registers */
- or r2, ZERO, r28
- or r3, ZERO, r29
- or r4, ZERO, r30
-
- /* Preserve r2 as the event code */
- movi evt_debug, r3
- ori r3, 1, r3
- ptabs r3, tr0
-
- or SP, ZERO, r6
- getcon TRA, r5
- blink tr0, LINK
-
- or r28, ZERO, r2
- or r29, ZERO, r3
- or r30, ZERO, r4
-#endif
-
/* For syscall and debug race condition, get TRA now */
getcon TRA, r5
@@ -887,11 +866,6 @@ no_underflow:
*/
.global ret_from_irq
ret_from_irq:
-#ifdef CONFIG_POOR_MANS_STRACE
- pta evt_debug_ret_from_irq, tr0
- ori SP, 0, r2
- blink tr0, LINK
-#endif
ld.q SP, FRAME_S(FSSR), r6
shlri r6, 30, r6
andi r6, 1, r6
@@ -905,12 +879,6 @@ ret_from_irq:
ret_from_exception:
preempt_stop()
-#ifdef CONFIG_POOR_MANS_STRACE
- pta evt_debug_ret_from_exc, tr0
- ori SP, 0, r2
- blink tr0, LINK
-#endif
-
ld.q SP, FRAME_S(FSSR), r6
shlri r6, 30, r6
andi r6, 1, r6
@@ -1236,18 +1204,6 @@ syscall_bad:
.global syscall_ret
syscall_ret:
st.q SP, FRAME_R(9), r2 /* Expecting SP back to BASIC frame */
-
-#ifdef CONFIG_POOR_MANS_STRACE
- /* nothing useful in registers at this point */
-
- movi evt_debug2, r5
- ori r5, 1, r5
- ptabs r5, tr0
- ld.q SP, FRAME_R(9), r2
- or SP, ZERO, r3
- blink tr0, LINK
-#endif
-
ld.q SP, FRAME_S(FSPC), r2
addi r2, 4, r2 /* Move PC, being pre-execution event */
st.q SP, FRAME_S(FSPC), r2
@@ -1268,25 +1224,12 @@ ret_from_fork:
ptabs r5, tr0
blink tr0, LINK
-#ifdef CONFIG_POOR_MANS_STRACE
- /* nothing useful in registers at this point */
-
- movi evt_debug2, r5
- ori r5, 1, r5
- ptabs r5, tr0
- ld.q SP, FRAME_R(9), r2
- or SP, ZERO, r3
- blink tr0, LINK
-#endif
-
ld.q SP, FRAME_S(FSPC), r2
addi r2, 4, r2 /* Move PC, being pre-execution event */
st.q SP, FRAME_S(FSPC), r2
pta ret_from_syscall, tr0
blink tr0, ZERO
-
-
syscall_allowed:
/* Use LINK to deflect the exit point, default is syscall_ret */
pta syscall_ret, tr0
@@ -1410,8 +1353,8 @@ peek_real_address_q:
r2(out) : result quadword
This is provided as a cheapskate way of manipulating device
- registers for debugging (to avoid the need to onchip_remap the debug
- module, and to avoid the need to onchip_remap the watchpoint
+ registers for debugging (to avoid the need to ioremap the debug
+ module, and to avoid the need to ioremap the watchpoint
controller in a way that identity maps sufficient bits to avoid the
SH5-101 cut2 silicon defect).
@@ -1459,8 +1402,8 @@ poke_real_address_q:
r3 : quadword value to write.
This is provided as a cheapskate way of manipulating device
- registers for debugging (to avoid the need to onchip_remap the debug
- module, and to avoid the need to onchip_remap the watchpoint
+ registers for debugging (to avoid the need to ioremap the debug
+ module, and to avoid the need to ioremap the watchpoint
controller in a way that identity maps sufficient bits to avoid the
SH5-101 cut2 silicon defect).
diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c
new file mode 100644
index 000000000000..678d69bdebba
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c
@@ -0,0 +1,195 @@
+/*
+ * SH5-101/SH5-103 CPU Setup
+ *
+ * Copyright (C) 2009 Paul Mundt
+ *
+ * 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/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_sci.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/sh_timer.h>
+#include <asm/addrspace.h>
+
+static struct plat_sci_port sci_platform_data[] = {
+ {
+ .mapbase = PHYS_PERIPHERAL_BLOCK + 0x01030000,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .type = PORT_SCIF,
+ .irqs = { 39, 40, 42, 0 },
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct platform_device sci_device = {
+ .name = "sh-sci",
+ .id = -1,
+ .dev = {
+ .platform_data = sci_platform_data,
+ },
+};
+
+static struct resource rtc_resources[] = {
+ [0] = {
+ .start = PHYS_PERIPHERAL_BLOCK + 0x01040000,
+ .end = PHYS_PERIPHERAL_BLOCK + 0x01040000 + 0x58 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ /* Period IRQ */
+ .start = IRQ_PRI,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* Carry IRQ */
+ .start = IRQ_CUI,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ /* Alarm IRQ */
+ .start = IRQ_ATI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device rtc_device = {
+ .name = "sh-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+
+#define TMU_BLOCK_OFF 0x01020000
+#define TMU_BASE PHYS_PERIPHERAL_BLOCK + TMU_BLOCK_OFF
+#define TMU0_BASE (TMU_BASE + 0x8 + (0xc * 0x0))
+#define TMU1_BASE (TMU_BASE + 0x8 + (0xc * 0x1))
+#define TMU2_BASE (TMU_BASE + 0x8 + (0xc * 0x2))
+
+static struct sh_timer_config tmu0_platform_data = {
+ .name = "TMU0",
+ .channel_offset = 0x04,
+ .timer_bit = 0,
+ .clk = "module_clk",
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+ [0] = {
+ .name = "TMU0",
+ .start = TMU0_BASE,
+ .end = TMU0_BASE + 0xc - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TUNI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu0_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu0_platform_data,
+ },
+ .resource = tmu0_resources,
+ .num_resources = ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+ .name = "TMU1",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clk = "module_clk",
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+ [0] = {
+ .name = "TMU1",
+ .start = TMU1_BASE,
+ .end = TMU1_BASE + 0xc - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TUNI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu1_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu1_platform_data,
+ },
+ .resource = tmu1_resources,
+ .num_resources = ARRAY_SIZE(tmu1_resources),
+};
+
+static struct sh_timer_config tmu2_platform_data = {
+ .name = "TMU2",
+ .channel_offset = 0x1c,
+ .timer_bit = 2,
+ .clk = "module_clk",
+};
+
+static struct resource tmu2_resources[] = {
+ [0] = {
+ .name = "TMU2",
+ .start = TMU2_BASE,
+ .end = TMU2_BASE + 0xc - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TUNI2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu2_device = {
+ .name = "sh_tmu",
+ .id = 2,
+ .dev = {
+ .platform_data = &tmu2_platform_data,
+ },
+ .resource = tmu2_resources,
+ .num_resources = ARRAY_SIZE(tmu2_resources),
+};
+
+static struct platform_device *sh5_early_devices[] __initdata = {
+ &tmu0_device,
+ &tmu1_device,
+ &tmu2_device,
+};
+
+static struct platform_device *sh5_devices[] __initdata = {
+ &sci_device,
+ &rtc_device,
+};
+
+static int __init sh5_devices_setup(void)
+{
+ int ret;
+
+ ret = platform_add_devices(sh5_early_devices,
+ ARRAY_SIZE(sh5_early_devices));
+ if (unlikely(ret != 0))
+ return ret;
+
+ return platform_add_devices(sh5_devices,
+ ARRAY_SIZE(sh5_devices));
+}
+__initcall(sh5_devices_setup);
+
+void __init plat_early_device_setup(void)
+{
+ early_platform_add_devices(sh5_early_devices,
+ ARRAY_SIZE(sh5_early_devices));
+}
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
index 29cf4588fc05..4f85fffaa557 100644
--- a/arch/sh/kernel/io.c
+++ b/arch/sh/kernel/io.c
@@ -12,6 +12,7 @@
* for more details.
*/
#include <linux/module.h>
+#include <linux/pci.h>
#include <asm/machvec.h>
#include <asm/io.h>
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index c22853b059ef..77dfecb64373 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -267,7 +267,7 @@ static struct mem_access trapped_io_access = {
int handle_trapped_io(struct pt_regs *regs, unsigned long address)
{
mm_segment_t oldfs;
- opcode_t instruction;
+ insn_size_t instruction;
int tmp;
if (!lookup_tiop(address))
diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c
index 7c747e7d71b8..305aad742aec 100644
--- a/arch/sh/kernel/kgdb.c
+++ b/arch/sh/kernel/kgdb.c
@@ -47,7 +47,7 @@ char in_nmi = 0; /* Set during NMI to prevent re-entry */
/* Calculate the new address for after a step */
static short *get_step_address(struct pt_regs *linux_regs)
{
- opcode_t op = __raw_readw(linux_regs->pc);
+ insn_size_t op = __raw_readw(linux_regs->pc);
long addr;
/* BT */
@@ -134,7 +134,7 @@ static short *get_step_address(struct pt_regs *linux_regs)
*/
static unsigned long stepped_address;
-static opcode_t stepped_opcode;
+static insn_size_t stepped_opcode;
static void do_single_step(struct pt_regs *linux_regs)
{
diff --git a/arch/sh/kernel/timers/timer-broadcast.c b/arch/sh/kernel/localtimer.c
index 96e8eaea1e62..96e8eaea1e62 100644
--- a/arch/sh/kernel/timers/timer-broadcast.c
+++ b/arch/sh/kernel/localtimer.c
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index c43081039dd5..c19b0f7d2cc1 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -90,7 +90,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
* SHmedia, the LSB of the symbol needs to be asserted
* for the CPU to be in SHmedia mode when it starts executing
* the branch target. */
- relocation |= (sym->st_other & 4);
+ relocation |= !!(sym->st_other & 4);
#endif
switch (ELF32_R_TYPE(rel[i].r_info)) {
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 6d94725d22f2..9289ede29c7b 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -251,7 +251,8 @@ static void ubc_set_tracing(int asid, unsigned long pc)
if (current_cpu_data.type == CPU_SH7729 ||
current_cpu_data.type == CPU_SH7710 ||
- current_cpu_data.type == CPU_SH7712) {
+ current_cpu_data.type == CPU_SH7712 ||
+ current_cpu_data.type == CPU_SH7203){
ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
} else {
@@ -407,6 +408,7 @@ asmlinkage void break_point_trap(void)
#else
ctrl_outw(0, UBC_BBRA);
ctrl_outw(0, UBC_BBRB);
+ ctrl_outl(0, UBC_BRCR);
#endif
current->thread.ubc_pc = 0;
ubc_usercnt -= 1;
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index f7b22dd83b0c..3392e835a374 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -334,6 +334,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
[(addr - (long)&dummy->fpu) >> 2];
} else if (addr == (long) &dummy->u_fpvalid)
tmp = !!tsk_used_math(child);
+ else if (addr == PT_TEXT_ADDR)
+ tmp = child->mm->start_code;
+ else if (addr == PT_DATA_ADDR)
+ tmp = child->mm->start_data;
+ else if (addr == PT_TEXT_END_ADDR)
+ tmp = child->mm->end_code;
+ else if (addr == PT_TEXT_LEN)
+ tmp = child->mm->end_code - child->mm->start_code;
else
tmp = 0;
ret = put_user(tmp, datap);
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 04a6004fccc4..00086b234278 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -29,6 +29,7 @@
#include <linux/mmzone.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/page.h>
@@ -155,7 +156,7 @@ static void __init reserve_crashkernel(void)
&crash_size, &crash_base);
if (ret == 0 && crash_size) {
if (crash_base <= 0) {
- vp = alloc_bootmem_nopanic(crash_size);
+ vp = alloc_bootmem_nopanic(crash_size);
if (!vp) {
printk(KERN_INFO "crashkernel allocation "
"failed\n");
@@ -184,7 +185,6 @@ static inline void __init reserve_crashkernel(void)
{}
#endif
-#ifndef CONFIG_GENERIC_CALIBRATE_DELAY
void __cpuinit calibrate_delay(void)
{
struct clk *clk = clk_get(NULL, "cpu_clk");
@@ -200,7 +200,6 @@ void __cpuinit calibrate_delay(void)
(loops_per_jiffy/(5000/HZ)) % 100,
loops_per_jiffy);
}
-#endif
void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
unsigned long end_pfn)
@@ -328,6 +327,10 @@ static int __init parse_elfcorehdr(char *arg)
early_param("elfcorehdr", parse_elfcorehdr);
#endif
+void __init __attribute__ ((weak)) plat_early_device_setup(void)
+{
+}
+
void __init setup_arch(char **cmdline_p)
{
enable_mmu();
@@ -381,6 +384,8 @@ void __init setup_arch(char **cmdline_p)
parse_early_param();
+ plat_early_device_setup();
+
sh_mv_setup();
/*
@@ -435,7 +440,8 @@ static const char *cpu_name[] = {
[CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3",
[CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103",
[CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723",
- [CPU_SH7366] = "SH7366", [CPU_SH_NONE] = "Unknown"
+ [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724",
+ [CPU_SH_NONE] = "Unknown"
};
const char *get_cpu_subtype(struct sh_cpuinfo *c)
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 528de2955c81..2d868c60aa6e 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -19,13 +19,12 @@
#include <asm/ftrace.h>
extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
-extern struct hw_interrupt_type no_irq_type;
/* platform dependent support */
EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(irq_desc);
-EXPORT_SYMBOL(no_irq_type);
+EXPORT_SYMBOL(no_irq_chip);
EXPORT_SYMBOL(strlen);
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index 0d74d6b8774e..8f54ef0cfbca 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -76,5 +76,7 @@ EXPORT_SYMBOL(strcpy);
#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
DECLARE_EXPORT(__sdivsi3);
+DECLARE_EXPORT(__sdivsi3_1);
+DECLARE_EXPORT(__sdivsi3_2);
DECLARE_EXPORT(__udivsi3);
DECLARE_EXPORT(__div_table);
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
new file mode 100644
index 000000000000..2edde32c764b
--- /dev/null
+++ b/arch/sh/kernel/time.c
@@ -0,0 +1,125 @@
+/*
+ * arch/sh/kernel/time.c
+ *
+ * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
+ * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ * Copyright (C) 2002 - 2009 Paul Mundt
+ * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org>
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/profile.h>
+#include <linux/timex.h>
+#include <linux/sched.h>
+#include <linux/clockchips.h>
+#include <linux/platform_device.h>
+#include <linux/smp.h>
+#include <linux/rtc.h>
+#include <asm/clock.h>
+#include <asm/rtc.h>
+
+/* Dummy RTC ops */
+static void null_rtc_get_time(struct timespec *tv)
+{
+ tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0);
+ tv->tv_nsec = 0;
+}
+
+static int null_rtc_set_time(const time_t secs)
+{
+ return 0;
+}
+
+void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
+int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
+
+#ifdef CONFIG_GENERIC_CMOS_UPDATE
+unsigned long read_persistent_clock(void)
+{
+ struct timespec tv;
+ rtc_sh_get_time(&tv);
+ return tv.tv_sec;
+}
+
+int update_persistent_clock(struct timespec now)
+{
+ return rtc_sh_set_time(now.tv_sec);
+}
+#endif
+
+unsigned int get_rtc_time(struct rtc_time *tm)
+{
+ if (rtc_sh_get_time != null_rtc_get_time) {
+ struct timespec tv;
+
+ rtc_sh_get_time(&tv);
+ rtc_time_to_tm(tv.tv_sec, tm);
+ }
+
+ return RTC_24H;
+}
+EXPORT_SYMBOL(get_rtc_time);
+
+int set_rtc_time(struct rtc_time *tm)
+{
+ unsigned long secs;
+
+ rtc_tm_to_time(tm, &secs);
+ return rtc_sh_set_time(secs);
+}
+EXPORT_SYMBOL(set_rtc_time);
+
+static int __init rtc_generic_init(void)
+{
+ struct platform_device *pdev;
+
+ if (rtc_sh_get_time == null_rtc_get_time)
+ return -ENODEV;
+
+ pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+module_init(rtc_generic_init);
+
+void (*board_time_init)(void);
+
+unsigned long long sched_clock(void)
+{
+ return (jiffies_64 - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ);
+}
+
+static void __init sh_late_time_init(void)
+{
+ /*
+ * Make sure all compiled-in early timers register themselves.
+ * Run probe() for one "earlytimer" device.
+ */
+ early_platform_driver_register_all("earlytimer");
+ early_platform_driver_probe("earlytimer", 1, 0);
+}
+
+void __init time_init(void)
+{
+ if (board_time_init)
+ board_time_init();
+
+ clk_init();
+
+ rtc_sh_get_time(&xtime);
+ set_normalized_timespec(&wall_to_monotonic,
+ -xtime.tv_sec, -xtime.tv_nsec);
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+ local_timer_setup(smp_processor_id());
+#endif
+
+ late_time_init = sh_late_time_init;
+}
diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c
deleted file mode 100644
index 1700d2465f6c..000000000000
--- a/arch/sh/kernel/time_32.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * arch/sh/kernel/time_32.c
- *
- * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- * Copyright (C) 2002 - 2008 Paul Mundt
- * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org>
- *
- * Some code taken from i386 version.
- * Copyright (C) 1991, 1992, 1995 Linus Torvalds
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/profile.h>
-#include <linux/timex.h>
-#include <linux/sched.h>
-#include <linux/clockchips.h>
-#include <linux/mc146818rtc.h> /* for rtc_lock */
-#include <linux/smp.h>
-#include <asm/clock.h>
-#include <asm/rtc.h>
-#include <asm/timer.h>
-#include <asm/kgdb.h>
-
-struct sys_timer *sys_timer;
-
-/* Move this somewhere more sensible.. */
-DEFINE_SPINLOCK(rtc_lock);
-EXPORT_SYMBOL(rtc_lock);
-
-/* Dummy RTC ops */
-static void null_rtc_get_time(struct timespec *tv)
-{
- tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0);
- tv->tv_nsec = 0;
-}
-
-static int null_rtc_set_time(const time_t secs)
-{
- return 0;
-}
-
-void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
-int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
-
-#ifndef CONFIG_GENERIC_TIME
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
-
- do {
- /*
- * Turn off IRQs when grabbing xtime_lock, so that
- * the sys_timer get_offset code doesn't have to handle it.
- */
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- usec = get_timer_offset();
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec / NSEC_PER_USEC;
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- nsec -= get_timer_offset() * NSEC_PER_USEC;
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
-
- return 0;
-}
-EXPORT_SYMBOL(do_settimeofday);
-#endif /* !CONFIG_GENERIC_TIME */
-
-/* last time the RTC clock got updated */
-static long last_rtc_update;
-
-/*
- * handle_timer_tick() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
- */
-void handle_timer_tick(void)
-{
- if (current->pid)
- profile_tick(CPU_PROFILING);
-
- /*
- * Here we are in the timer irq handler. We just have irqs locally
- * disabled but we don't know if the timer_bh is running on the other
- * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
- * the irq version of write_lock because as just said we have irq
- * locally disabled. -arca
- */
- write_seqlock(&xtime_lock);
- do_timer(1);
-
- /*
- * If we have an externally synchronized Linux clock, then update
- * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
- * called as close as possible to 500 ms before the new second starts.
- */
- if (ntp_synced() &&
- xtime.tv_sec > last_rtc_update + 660 &&
- (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
- (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
- if (rtc_sh_set_time(xtime.tv_sec) == 0)
- last_rtc_update = xtime.tv_sec;
- else
- /* do it again in 60s */
- last_rtc_update = xtime.tv_sec - 600;
- }
- write_sequnlock(&xtime_lock);
-
-#ifndef CONFIG_SMP
- update_process_times(user_mode(get_irq_regs()));
-#endif
-}
-
-#ifdef CONFIG_PM
-int timer_suspend(struct sys_device *dev, pm_message_t state)
-{
- struct sys_timer *sys_timer = container_of(dev, struct sys_timer, dev);
-
- sys_timer->ops->stop();
-
- return 0;
-}
-
-int timer_resume(struct sys_device *dev)
-{
- struct sys_timer *sys_timer = container_of(dev, struct sys_timer, dev);
-
- sys_timer->ops->start();
-
- return 0;
-}
-#else
-#define timer_suspend NULL
-#define timer_resume NULL
-#endif
-
-static struct sysdev_class timer_sysclass = {
- .name = "timer",
- .suspend = timer_suspend,
- .resume = timer_resume,
-};
-
-static int __init timer_init_sysfs(void)
-{
- int ret;
-
- if (!sys_timer)
- return 0;
-
- ret = sysdev_class_register(&timer_sysclass);
- if (ret != 0)
- return ret;
-
- sys_timer->dev.cls = &timer_sysclass;
- return sysdev_register(&sys_timer->dev);
-}
-device_initcall(timer_init_sysfs);
-
-void (*board_time_init)(void);
-
-struct clocksource clocksource_sh = {
- .name = "SuperH",
-};
-
-#ifdef CONFIG_GENERIC_TIME
-unsigned long long sched_clock(void)
-{
- unsigned long long cycles;
-
- /* jiffies based sched_clock if no clocksource is installed */
- if (!clocksource_sh.rating)
- return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
-
- cycles = clocksource_sh.read(&clocksource_sh);
- return cyc2ns(&clocksource_sh, cycles);
-}
-#endif
-
-void __init time_init(void)
-{
- if (board_time_init)
- board_time_init();
-
- clk_init();
-
- rtc_sh_get_time(&xtime);
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
-
-#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
- local_timer_setup(smp_processor_id());
-#endif
-
- /*
- * Find the timer to use as the system timer, it will be
- * initialized for us.
- */
- sys_timer = get_sys_timer();
- if (unlikely(!sys_timer))
- panic("System timer missing.\n");
-
- printk(KERN_INFO "Using %s for system timer\n", sys_timer->name);
-}
diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c
deleted file mode 100644
index 988c77c37231..000000000000
--- a/arch/sh/kernel/time_64.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * arch/sh/kernel/time_64.c
- *
- * Copyright (C) 2000, 2001 Paolo Alberelli
- * Copyright (C) 2003 - 2007 Paul Mundt
- * Copyright (C) 2003 Richard Curnow
- *
- * Original TMU/RTC code taken from sh version.
- * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
- * Some code taken from i386 version.
- * Copyright (C) 1991, 1992, 1995 Linus Torvalds
- *
- * 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/errno.h>
-#include <linux/rwsem.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/profile.h>
-#include <linux/smp.h>
-#include <linux/module.h>
-#include <linux/bcd.h>
-#include <linux/timex.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <cpu/registers.h> /* required by inline __asm__ stmt. */
-#include <cpu/irq.h>
-#include <asm/addrspace.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-#include <asm/delay.h>
-#include <asm/clock.h>
-
-#define TMU_TOCR_INIT 0x00
-#define TMU0_TCR_INIT 0x0020
-#define TMU_TSTR_INIT 1
-#define TMU_TSTR_OFF 0
-
-/* Real Time Clock */
-#define RTC_BLOCK_OFF 0x01040000
-#define RTC_BASE PHYS_PERIPHERAL_BLOCK + RTC_BLOCK_OFF
-#define RTC_RCR1_CIE 0x10 /* Carry Interrupt Enable */
-#define RTC_RCR1 (rtc_base + 0x38)
-
-/* Time Management Unit */
-#define TMU_BLOCK_OFF 0x01020000
-#define TMU_BASE PHYS_PERIPHERAL_BLOCK + TMU_BLOCK_OFF
-#define TMU0_BASE tmu_base + 0x8 + (0xc * 0x0)
-#define TMU1_BASE tmu_base + 0x8 + (0xc * 0x1)
-#define TMU2_BASE tmu_base + 0x8 + (0xc * 0x2)
-
-#define TMU_TOCR tmu_base+0x0 /* Byte access */
-#define TMU_TSTR tmu_base+0x4 /* Byte access */
-
-#define TMU0_TCOR TMU0_BASE+0x0 /* Long access */
-#define TMU0_TCNT TMU0_BASE+0x4 /* Long access */
-#define TMU0_TCR TMU0_BASE+0x8 /* Word access */
-
-#define TICK_SIZE (tick_nsec / 1000)
-
-static unsigned long tmu_base, rtc_base;
-unsigned long cprc_base;
-
-/* Variables to allow interpolation of time of day to resolution better than a
- * jiffy. */
-
-/* This is effectively protected by xtime_lock */
-static unsigned long ctc_last_interrupt;
-static unsigned long long usecs_per_jiffy = 1000000/HZ; /* Approximation */
-
-#define CTC_JIFFY_SCALE_SHIFT 40
-
-/* 2**CTC_JIFFY_SCALE_SHIFT / ctc_ticks_per_jiffy */
-static unsigned long long scaled_recip_ctc_ticks_per_jiffy;
-
-/* Estimate number of microseconds that have elapsed since the last timer tick,
- by scaling the delta that has occurred in the CTC register.
-
- WARNING WARNING WARNING : This algorithm relies on the CTC decrementing at
- the CPU clock rate. If the CPU sleeps, the CTC stops counting. Bear this
- in mind if enabling SLEEP_WORKS in process.c. In that case, this algorithm
- probably needs to use TMU.TCNT0 instead. This will work even if the CPU is
- sleeping, though will be coarser.
-
- FIXME : What if usecs_per_tick is moving around too much, e.g. if an adjtime
- is running or if the freq or tick arguments of adjtimex are modified after
- we have calibrated the scaling factor? This will result in either a jump at
- the end of a tick period, or a wrap backwards at the start of the next one,
- if the application is reading the time of day often enough. I think we
- ought to do better than this. For this reason, usecs_per_jiffy is left
- separated out in the calculation below. This allows some future hook into
- the adjtime-related stuff in kernel/timer.c to remove this hazard.
-
-*/
-
-static unsigned long usecs_since_tick(void)
-{
- unsigned long long current_ctc;
- long ctc_ticks_since_interrupt;
- unsigned long long ull_ctc_ticks_since_interrupt;
- unsigned long result;
-
- unsigned long long mul1_out;
- unsigned long long mul1_out_high;
- unsigned long long mul2_out_low, mul2_out_high;
-
- /* Read CTC register */
- asm ("getcon cr62, %0" : "=r" (current_ctc));
- /* Note, the CTC counts down on each CPU clock, not up.
- Note(2), use long type to get correct wraparound arithmetic when
- the counter crosses zero. */
- ctc_ticks_since_interrupt = (long) ctc_last_interrupt - (long) current_ctc;
- ull_ctc_ticks_since_interrupt = (unsigned long long) ctc_ticks_since_interrupt;
-
- /* Inline assembly to do 32x32x32->64 multiplier */
- asm volatile ("mulu.l %1, %2, %0" :
- "=r" (mul1_out) :
- "r" (ull_ctc_ticks_since_interrupt), "r" (usecs_per_jiffy));
-
- mul1_out_high = mul1_out >> 32;
-
- asm volatile ("mulu.l %1, %2, %0" :
- "=r" (mul2_out_low) :
- "r" (mul1_out), "r" (scaled_recip_ctc_ticks_per_jiffy));
-
-#if 1
- asm volatile ("mulu.l %1, %2, %0" :
- "=r" (mul2_out_high) :
- "r" (mul1_out_high), "r" (scaled_recip_ctc_ticks_per_jiffy));
-#endif
-
- result = (unsigned long) (((mul2_out_high << 32) + mul2_out_low) >> CTC_JIFFY_SCALE_SHIFT);
-
- return result;
-}
-
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- usec = usecs_since_tick();
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec / 1000;
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- nsec -= 1000 * usecs_since_tick();
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
-
- return 0;
-}
-EXPORT_SYMBOL(do_settimeofday);
-
-/* Dummy RTC ops */
-static void null_rtc_get_time(struct timespec *tv)
-{
- tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0);
- tv->tv_nsec = 0;
-}
-
-static int null_rtc_set_time(const time_t secs)
-{
- return 0;
-}
-
-void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
-int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
-
-/* last time the RTC clock got updated */
-static long last_rtc_update;
-
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
- */
-static inline void do_timer_interrupt(void)
-{
- unsigned long long current_ctc;
-
- if (current->pid)
- profile_tick(CPU_PROFILING);
-
- /*
- * Here we are in the timer irq handler. We just have irqs locally
- * disabled but we don't know if the timer_bh is running on the other
- * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
- * the irq version of write_lock because as just said we have irq
- * locally disabled. -arca
- */
- write_seqlock(&xtime_lock);
- asm ("getcon cr62, %0" : "=r" (current_ctc));
- ctc_last_interrupt = (unsigned long) current_ctc;
-
- do_timer(1);
-
- /*
- * If we have an externally synchronized Linux clock, then update
- * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
- * called as close as possible to 500 ms before the new second starts.
- */
- if (ntp_synced() &&
- xtime.tv_sec > last_rtc_update + 660 &&
- (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
- (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
- if (rtc_sh_set_time(xtime.tv_sec) == 0)
- last_rtc_update = xtime.tv_sec;
- else
- /* do it again in 60 s */
- last_rtc_update = xtime.tv_sec - 600;
- }
- write_sequnlock(&xtime_lock);
-
-#ifndef CONFIG_SMP
- update_process_times(user_mode(get_irq_regs()));
-#endif
-}
-
-/*
- * This is the same as the above, except we _also_ save the current
- * Time Stamp Counter value at the time of the timer interrupt, so that
- * we later on can estimate the time of day more exactly.
- */
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
- unsigned long timer_status;
-
- /* Clear UNF bit */
- timer_status = ctrl_inw(TMU0_TCR);
- timer_status &= ~0x100;
- ctrl_outw(timer_status, TMU0_TCR);
-
- do_timer_interrupt();
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction irq0 = {
- .handler = timer_interrupt,
- .flags = IRQF_DISABLED,
- .name = "timer",
-};
-
-void __init time_init(void)
-{
- unsigned long interval;
- struct clk *clk;
-
- tmu_base = onchip_remap(TMU_BASE, 1024, "TMU");
- if (!tmu_base) {
- panic("Unable to remap TMU\n");
- }
-
- rtc_base = onchip_remap(RTC_BASE, 1024, "RTC");
- if (!rtc_base) {
- panic("Unable to remap RTC\n");
- }
-
- clk = clk_get(NULL, "cpu_clk");
- scaled_recip_ctc_ticks_per_jiffy = ((1ULL << CTC_JIFFY_SCALE_SHIFT) /
- (unsigned long long)(clk_get_rate(clk) / HZ));
-
- rtc_sh_get_time(&xtime);
-
- setup_irq(TIMER_IRQ, &irq0);
-
- clk = clk_get(NULL, "module_clk");
- interval = (clk_get_rate(clk)/(HZ*4));
-
- printk("Interval = %ld\n", interval);
-
- /* Start TMU0 */
- ctrl_outb(TMU_TSTR_OFF, TMU_TSTR);
- ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
- ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
- ctrl_outl(interval, TMU0_TCOR);
- ctrl_outl(interval, TMU0_TCNT);
- ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
-}
-
-static struct resource rtc_resources[] = {
- [0] = {
- /* RTC base, filled in by rtc_init */
- .flags = IORESOURCE_IO,
- },
- [1] = {
- /* Period IRQ */
- .start = IRQ_PRI,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- /* Carry IRQ */
- .start = IRQ_CUI,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- /* Alarm IRQ */
- .start = IRQ_ATI,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device rtc_device = {
- .name = "sh-rtc",
- .id = -1,
- .num_resources = ARRAY_SIZE(rtc_resources),
- .resource = rtc_resources,
-};
-
-static int __init rtc_init(void)
-{
- rtc_resources[0].start = rtc_base;
- rtc_resources[0].end = rtc_resources[0].start + 0x58 - 1;
-
- return platform_device_register(&rtc_device);
-}
-device_initcall(rtc_init);
diff --git a/arch/sh/kernel/timers/Makefile b/arch/sh/kernel/timers/Makefile
deleted file mode 100644
index 0b7f8577193f..000000000000
--- a/arch/sh/kernel/timers/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the various Linux/SuperH timers
-#
-
-obj-y := timer.o
-
-obj-$(CONFIG_SH_TMU) += timer-tmu.o
-obj-$(CONFIG_SH_MTU2) += timer-mtu2.o
-obj-$(CONFIG_SH_CMT) += timer-cmt.o
-
-obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += timer-broadcast.o
diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c
deleted file mode 100644
index 9aa348658ae3..000000000000
--- a/arch/sh/kernel/timers/timer-cmt.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * arch/sh/kernel/timers/timer-cmt.c - CMT Timer Support
- *
- * Copyright (C) 2005 Yoshinori Sato
- *
- * 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/init.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/seqlock.h>
-#include <asm/timer.h>
-#include <asm/rtc.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/clock.h>
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7619)
-#define CMT_CMSTR 0xf84a0070
-#define CMT_CMCSR_0 0xf84a0072
-#define CMT_CMCNT_0 0xf84a0074
-#define CMT_CMCOR_0 0xf84a0076
-#define CMT_CMCSR_1 0xf84a0078
-#define CMT_CMCNT_1 0xf84a007a
-#define CMT_CMCOR_1 0xf84a007c
-
-#define STBCR3 0xf80a0000
-#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR3) & ~0x10, STBCR3); } while(0)
-#define CMT_CMCSR_INIT 0x0040
-#define CMT_CMCSR_CALIB 0x0000
-#elif defined(CONFIG_CPU_SUBTYPE_SH7203) || \
- defined(CONFIG_CPU_SUBTYPE_SH7206) || \
- defined(CONFIG_CPU_SUBTYPE_SH7263)
-#define CMT_CMSTR 0xfffec000
-#define CMT_CMCSR_0 0xfffec002
-#define CMT_CMCNT_0 0xfffec004
-#define CMT_CMCOR_0 0xfffec006
-
-#define STBCR4 0xfffe040c
-#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR4) & ~0x04, STBCR4); } while(0)
-#define CMT_CMCSR_INIT 0x0040
-#define CMT_CMCSR_CALIB 0x0000
-#else
-#error "Unknown CPU SUBTYPE"
-#endif
-
-static unsigned long cmt_timer_get_offset(void)
-{
- int count;
- static unsigned short count_p = 0xffff; /* for the first call after boot */
- static unsigned long jiffies_p = 0;
-
- /*
- * cache volatile jiffies temporarily; we have IRQs turned off.
- */
- unsigned long jiffies_t;
-
- /* timer count may underflow right here */
- count = ctrl_inw(CMT_CMCOR_0);
- count -= ctrl_inw(CMT_CMCNT_0);
-
- jiffies_t = jiffies;
-
- /*
- * avoiding timer inconsistencies (they are rare, but they happen)...
- * there is one kind of problem that must be avoided here:
- * 1. the timer counter underflows
- */
-
- if (jiffies_t == jiffies_p) {
- if (count > count_p) {
- /* the nutcase */
- if (ctrl_inw(CMT_CMCSR_0) & 0x80) { /* Check CMF bit */
- count -= LATCH;
- } else {
- printk("%s (): hardware timer problem?\n",
- __func__);
- }
- }
- } else
- jiffies_p = jiffies_t;
-
- count_p = count;
-
- count = ((LATCH-1) - count) * TICK_SIZE;
- count = (count + LATCH/2) / LATCH;
-
- return count;
-}
-
-static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id)
-{
- unsigned long timer_status;
-
- /* Clear CMF bit */
- timer_status = ctrl_inw(CMT_CMCSR_0);
- timer_status &= ~0x80;
- ctrl_outw(timer_status, CMT_CMCSR_0);
-
- handle_timer_tick();
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction cmt_irq = {
- .name = "timer",
- .handler = cmt_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-};
-
-static void cmt_clk_init(struct clk *clk)
-{
- u8 divisor = CMT_CMCSR_INIT & 0x3;
- ctrl_inw(CMT_CMCSR_0);
- ctrl_outw(CMT_CMCSR_INIT, CMT_CMCSR_0);
- clk->parent = clk_get(NULL, "module_clk");
- clk->rate = clk->parent->rate / (8 << (divisor << 1));
-}
-
-static void cmt_clk_recalc(struct clk *clk)
-{
- u8 divisor = ctrl_inw(CMT_CMCSR_0) & 0x3;
- clk->rate = clk->parent->rate / (8 << (divisor << 1));
-}
-
-static struct clk_ops cmt_clk_ops = {
- .init = cmt_clk_init,
- .recalc = cmt_clk_recalc,
-};
-
-static struct clk cmt0_clk = {
- .name = "cmt0_clk",
- .ops = &cmt_clk_ops,
-};
-
-static int cmt_timer_start(void)
-{
- ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR);
- return 0;
-}
-
-static int cmt_timer_stop(void)
-{
- ctrl_outw(ctrl_inw(CMT_CMSTR) & ~0x01, CMT_CMSTR);
- return 0;
-}
-
-static int cmt_timer_init(void)
-{
- unsigned long interval;
-
- cmt_clock_enable();
-
- setup_irq(CONFIG_SH_TIMER_IRQ, &cmt_irq);
-
- cmt0_clk.parent = clk_get(NULL, "module_clk");
-
- cmt_timer_stop();
-
- interval = cmt0_clk.parent->rate / 8 / HZ;
- printk(KERN_INFO "Interval = %ld\n", interval);
-
- ctrl_outw(interval, CMT_CMCOR_0);
-
- clk_register(&cmt0_clk);
- clk_enable(&cmt0_clk);
-
- cmt_timer_start();
-
- return 0;
-}
-
-static struct sys_timer_ops cmt_timer_ops = {
- .init = cmt_timer_init,
- .start = cmt_timer_start,
- .stop = cmt_timer_stop,
-#ifndef CONFIG_GENERIC_TIME
- .get_offset = cmt_timer_get_offset,
-#endif
-};
-
-struct sys_timer cmt_timer = {
- .name = "cmt",
- .ops = &cmt_timer_ops,
-};
diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c
deleted file mode 100644
index 9b0ef0126479..000000000000
--- a/arch/sh/kernel/timers/timer-mtu2.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * arch/sh/kernel/timers/timer-mtu2.c - MTU2 Timer Support
- *
- * Copyright (C) 2005 Paul Mundt
- *
- * Based off of arch/sh/kernel/timers/timer-tmu.c
- *
- * 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/init.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/seqlock.h>
-#include <asm/timer.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/clock.h>
-
-/*
- * We use channel 1 for our lowly system timer. Channel 2 would be the other
- * likely candidate, but we leave it alone as it has higher divisors that
- * would be of more use to other more interesting applications.
- *
- * TODO: Presently we only implement a 16-bit single-channel system timer.
- * However, we can implement channel cascade if we go the overflow route and
- * get away with using 2 MTU2 channels as a 32-bit timer.
- */
-#define MTU2_TSTR 0xfffe4280
-#define MTU2_TCR_1 0xfffe4380
-#define MTU2_TMDR_1 0xfffe4381
-#define MTU2_TIOR_1 0xfffe4382
-#define MTU2_TIER_1 0xfffe4384
-#define MTU2_TSR_1 0xfffe4385
-#define MTU2_TCNT_1 0xfffe4386 /* 16-bit counter */
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7201) || \
- defined(CONFIG_CPU_SUBTYPE_SH7203)
-#define MTU2_TGRA_1 0xfffe4388
-#else
-#define MTU2_TGRA_1 0xfffe438a
-#endif
-
-#define STBCR3 0xfffe0408
-
-#define MTU2_TSTR_CST1 (1 << 1) /* Counter Start 1 */
-
-#define MTU2_TSR_TGFA (1 << 0) /* GRA compare match */
-
-#define MTU2_TIER_TGIEA (1 << 0) /* GRA compare match interrupt enable */
-
-#define MTU2_TCR_INIT 0x22
-
-#define MTU2_TCR_CALIB 0x00
-
-static unsigned long mtu2_timer_get_offset(void)
-{
- int count;
- static int count_p = 0x7fff; /* for the first call after boot */
- static unsigned long jiffies_p = 0;
-
- /*
- * cache volatile jiffies temporarily; we have IRQs turned off.
- */
- unsigned long jiffies_t;
-
- /* timer count may underflow right here */
- count = ctrl_inw(MTU2_TCNT_1); /* read the latched count */
-
- jiffies_t = jiffies;
-
- /*
- * avoiding timer inconsistencies (they are rare, but they happen)...
- * there is one kind of problem that must be avoided here:
- * 1. the timer counter underflows
- */
-
- if (jiffies_t == jiffies_p) {
- if (count > count_p) {
- if (ctrl_inb(MTU2_TSR_1) & MTU2_TSR_TGFA) {
- count -= LATCH;
- } else {
- printk("%s (): hardware timer problem?\n",
- __func__);
- }
- }
- } else
- jiffies_p = jiffies_t;
-
- count_p = count;
-
- count = ((LATCH-1) - count) * TICK_SIZE;
- count = (count + LATCH/2) / LATCH;
-
- return count;
-}
-
-static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id)
-{
- unsigned long timer_status;
-
- /* Clear TGFA bit */
- timer_status = ctrl_inb(MTU2_TSR_1);
- timer_status &= ~MTU2_TSR_TGFA;
- ctrl_outb(timer_status, MTU2_TSR_1);
-
- /* Do timer tick */
- handle_timer_tick();
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction mtu2_irq = {
- .name = "timer",
- .handler = mtu2_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-};
-
-static unsigned int divisors[] = { 1, 4, 16, 64, 1, 1, 256 };
-
-static void mtu2_clk_init(struct clk *clk)
-{
- u8 idx = MTU2_TCR_INIT & 0x7;
-
- clk->rate = clk->parent->rate / divisors[idx];
- /* Start TCNT counting */
- ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR);
-
-}
-
-static void mtu2_clk_recalc(struct clk *clk)
-{
- u8 idx = ctrl_inb(MTU2_TCR_1) & 0x7;
- clk->rate = clk->parent->rate / divisors[idx];
-}
-
-static struct clk_ops mtu2_clk_ops = {
- .init = mtu2_clk_init,
- .recalc = mtu2_clk_recalc,
-};
-
-static struct clk mtu2_clk1 = {
- .name = "mtu2_clk1",
- .ops = &mtu2_clk_ops,
-};
-
-static int mtu2_timer_start(void)
-{
- ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR);
- return 0;
-}
-
-static int mtu2_timer_stop(void)
-{
- ctrl_outb(ctrl_inb(MTU2_TSTR) & ~MTU2_TSTR_CST1, MTU2_TSTR);
- return 0;
-}
-
-static int mtu2_timer_init(void)
-{
- unsigned long interval;
-
- setup_irq(CONFIG_SH_TIMER_IRQ, &mtu2_irq);
-
- mtu2_clk1.parent = clk_get(NULL, "module_clk");
-
- ctrl_outb(ctrl_inb(STBCR3) & (~0x20), STBCR3);
-
- /* Normal operation */
- ctrl_outb(0, MTU2_TMDR_1);
- ctrl_outb(MTU2_TCR_INIT, MTU2_TCR_1);
- ctrl_outb(0x01, MTU2_TIOR_1);
-
- /* Enable underflow interrupt */
- ctrl_outb(ctrl_inb(MTU2_TIER_1) | MTU2_TIER_TGIEA, MTU2_TIER_1);
-
- interval = CONFIG_SH_PCLK_FREQ / 16 / HZ;
- printk(KERN_INFO "Interval = %ld\n", interval);
-
- ctrl_outw(interval, MTU2_TGRA_1);
- ctrl_outw(0, MTU2_TCNT_1);
-
- clk_register(&mtu2_clk1);
- clk_enable(&mtu2_clk1);
-
- return 0;
-}
-
-struct sys_timer_ops mtu2_timer_ops = {
- .init = mtu2_timer_init,
- .start = mtu2_timer_start,
- .stop = mtu2_timer_stop,
-#ifndef CONFIG_GENERIC_TIME
- .get_offset = mtu2_timer_get_offset,
-#endif
-};
-
-struct sys_timer mtu2_timer = {
- .name = "mtu2",
- .ops = &mtu2_timer_ops,
-};
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
deleted file mode 100644
index fe8d8930ccb6..000000000000
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * arch/sh/kernel/timers/timer-tmu.c - TMU Timer Support
- *
- * Copyright (C) 2005 - 2007 Paul Mundt
- *
- * TMU handling code hacked out of arch/sh/kernel/time.c
- *
- * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- * Copyright (C) 2002, 2003, 2004 Paul Mundt
- * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org>
- *
- * 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/init.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/seqlock.h>
-#include <linux/clockchips.h>
-#include <asm/timer.h>
-#include <asm/rtc.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/clock.h>
-
-#define TMU_TOCR_INIT 0x00
-#define TMU_TCR_INIT 0x0020
-
-#define TMU0 (0)
-#define TMU1 (1)
-
-static inline void _tmu_start(int tmu_num)
-{
- ctrl_outb(ctrl_inb(TMU_012_TSTR) | (0x1<<tmu_num), TMU_012_TSTR);
-}
-
-static inline void _tmu_set_irq(int tmu_num, int enabled)
-{
- register unsigned long tmu_tcr = TMU0_TCR + (0xc*tmu_num);
- ctrl_outw( (enabled ? ctrl_inw(tmu_tcr) | (1<<5) : ctrl_inw(tmu_tcr) & ~(1<<5)), tmu_tcr);
-}
-
-static inline void _tmu_stop(int tmu_num)
-{
- ctrl_outb(ctrl_inb(TMU_012_TSTR) & ~(0x1<<tmu_num), TMU_012_TSTR);
-}
-
-static inline void _tmu_clear_status(int tmu_num)
-{
- register unsigned long tmu_tcr = TMU0_TCR + (0xc*tmu_num);
- /* Clear UNF bit */
- ctrl_outw(ctrl_inw(tmu_tcr) & ~0x100, tmu_tcr);
-}
-
-static inline unsigned long _tmu_read(int tmu_num)
-{
- return ctrl_inl(TMU0_TCNT+0xC*tmu_num);
-}
-
-static int tmu_timer_start(void)
-{
- _tmu_start(TMU0);
- _tmu_start(TMU1);
- _tmu_set_irq(TMU0,1);
- return 0;
-}
-
-static int tmu_timer_stop(void)
-{
- _tmu_stop(TMU0);
- _tmu_stop(TMU1);
- _tmu_clear_status(TMU0);
- return 0;
-}
-
-/*
- * also when the module_clk is scaled the TMU1
- * will show the same frequency
- */
-static int tmus_are_scaled;
-
-static cycle_t tmu_timer_read(struct clocksource *cs)
-{
- return ((cycle_t)(~_tmu_read(TMU1)))<<tmus_are_scaled;
-}
-
-
-static unsigned long tmu_latest_interval[3];
-static void tmu_timer_set_interval(int tmu_num, unsigned long interval, unsigned int reload)
-{
- unsigned long tmu_tcnt = TMU0_TCNT + tmu_num*0xC;
- unsigned long tmu_tcor = TMU0_TCOR + tmu_num*0xC;
-
- _tmu_stop(tmu_num);
-
- ctrl_outl(interval, tmu_tcnt);
- tmu_latest_interval[tmu_num] = interval;
-
- /*
- * TCNT reloads from TCOR on underflow, clear it if we don't
- * intend to auto-reload
- */
- ctrl_outl( reload ? interval : 0 , tmu_tcor);
-
- _tmu_start(tmu_num);
-}
-
-static int tmu_set_next_event(unsigned long cycles,
- struct clock_event_device *evt)
-{
- tmu_timer_set_interval(TMU0,cycles, evt->mode == CLOCK_EVT_MODE_PERIODIC);
- _tmu_set_irq(TMU0,1);
- return 0;
-}
-
-static void tmu_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- ctrl_outl(tmu_latest_interval[TMU0], TMU0_TCOR);
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- ctrl_outl(0, TMU0_TCOR);
- break;
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- case CLOCK_EVT_MODE_RESUME:
- break;
- }
-}
-
-static struct clock_event_device tmu0_clockevent = {
- .name = "tmu0",
- .shift = 32,
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .set_mode = tmu_set_mode,
- .set_next_event = tmu_set_next_event,
-};
-
-static irqreturn_t tmu_timer_interrupt(int irq, void *dummy)
-{
- struct clock_event_device *evt = &tmu0_clockevent;
- _tmu_clear_status(TMU0);
- _tmu_set_irq(TMU0,tmu0_clockevent.mode != CLOCK_EVT_MODE_ONESHOT);
-
- switch (tmu0_clockevent.mode) {
- case CLOCK_EVT_MODE_ONESHOT:
- case CLOCK_EVT_MODE_PERIODIC:
- evt->event_handler(evt);
- break;
- default:
- break;
- }
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction tmu0_irq = {
- .name = "periodic/oneshot timer",
- .handler = tmu_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-};
-
-static void __init tmu_clk_init(struct clk *clk)
-{
- u8 divisor = TMU_TCR_INIT & 0x7;
- int tmu_num = clk->name[3]-'0';
- ctrl_outw(TMU_TCR_INIT, TMU0_TCR+(tmu_num*0xC));
- clk->rate = clk_get_rate(clk->parent) / (4 << (divisor << 1));
-}
-
-static void tmu_clk_recalc(struct clk *clk)
-{
- int tmu_num = clk->name[3]-'0';
- unsigned long prev_rate = clk_get_rate(clk);
- unsigned long flags;
- u8 divisor = ctrl_inw(TMU0_TCR+tmu_num*0xC) & 0x7;
- clk->rate = clk_get_rate(clk->parent) / (4 << (divisor << 1));
-
- if(prev_rate==clk_get_rate(clk))
- return;
-
- if(tmu_num)
- return; /* No more work on TMU1 */
-
- local_irq_save(flags);
- tmus_are_scaled = (prev_rate > clk->rate);
-
- _tmu_stop(TMU0);
-
- tmu0_clockevent.mult = div_sc(clk->rate, NSEC_PER_SEC,
- tmu0_clockevent.shift);
- tmu0_clockevent.max_delta_ns =
- clockevent_delta2ns(-1, &tmu0_clockevent);
- tmu0_clockevent.min_delta_ns =
- clockevent_delta2ns(1, &tmu0_clockevent);
-
- if (tmus_are_scaled)
- tmu_latest_interval[TMU0] >>= 1;
- else
- tmu_latest_interval[TMU0] <<= 1;
-
- tmu_timer_set_interval(TMU0,
- tmu_latest_interval[TMU0],
- tmu0_clockevent.mode == CLOCK_EVT_MODE_PERIODIC);
-
- _tmu_start(TMU0);
-
- local_irq_restore(flags);
-}
-
-static struct clk_ops tmu_clk_ops = {
- .init = tmu_clk_init,
- .recalc = tmu_clk_recalc,
-};
-
-static struct clk tmu0_clk = {
- .name = "tmu0_clk",
- .ops = &tmu_clk_ops,
-};
-
-static struct clk tmu1_clk = {
- .name = "tmu1_clk",
- .ops = &tmu_clk_ops,
-};
-
-static int tmu_timer_init(void)
-{
- unsigned long interval;
- unsigned long frequency;
-
- setup_irq(CONFIG_SH_TIMER_IRQ, &tmu0_irq);
-
- tmu0_clk.parent = clk_get(NULL, "module_clk");
- tmu1_clk.parent = clk_get(NULL, "module_clk");
-
- tmu_timer_stop();
-
-#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \
- !defined(CONFIG_CPU_SUBTYPE_SH7721) && \
- !defined(CONFIG_CPU_SUBTYPE_SH7760) && \
- !defined(CONFIG_CPU_SUBTYPE_SH7785) && \
- !defined(CONFIG_CPU_SUBTYPE_SH7786) && \
- !defined(CONFIG_CPU_SUBTYPE_SHX3)
- ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
-#endif
-
- clk_register(&tmu0_clk);
- clk_register(&tmu1_clk);
- clk_enable(&tmu0_clk);
- clk_enable(&tmu1_clk);
-
- frequency = clk_get_rate(&tmu0_clk);
- interval = (frequency + HZ / 2) / HZ;
-
- tmu_timer_set_interval(TMU0,interval, 1);
- tmu_timer_set_interval(TMU1,~0,1);
-
- _tmu_start(TMU1);
-
- clocksource_sh.rating = 200;
- clocksource_sh.mask = CLOCKSOURCE_MASK(32);
- clocksource_sh.read = tmu_timer_read;
- clocksource_sh.shift = 10;
- clocksource_sh.mult = clocksource_hz2mult(clk_get_rate(&tmu1_clk),
- clocksource_sh.shift);
- clocksource_sh.flags = CLOCK_SOURCE_IS_CONTINUOUS;
- clocksource_register(&clocksource_sh);
-
- tmu0_clockevent.mult = div_sc(frequency, NSEC_PER_SEC,
- tmu0_clockevent.shift);
- tmu0_clockevent.max_delta_ns =
- clockevent_delta2ns(-1, &tmu0_clockevent);
- tmu0_clockevent.min_delta_ns =
- clockevent_delta2ns(1, &tmu0_clockevent);
-
- tmu0_clockevent.cpumask = cpumask_of(0);
- tmu0_clockevent.rating = 100;
-
- clockevents_register_device(&tmu0_clockevent);
-
- return 0;
-}
-
-static struct sys_timer_ops tmu_timer_ops = {
- .init = tmu_timer_init,
- .start = tmu_timer_start,
- .stop = tmu_timer_stop,
-};
-
-struct sys_timer tmu_timer = {
- .name = "tmu",
- .ops = &tmu_timer_ops,
-};
diff --git a/arch/sh/kernel/timers/timer.c b/arch/sh/kernel/timers/timer.c
deleted file mode 100644
index 4e7e747d1b69..000000000000
--- a/arch/sh/kernel/timers/timer.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * arch/sh/kernel/timers/timer.c - Common timer code
- *
- * Copyright (C) 2005 Paul Mundt
- *
- * 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/kernel.h>
-#include <linux/init.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <asm/timer.h>
-
-static struct sys_timer *sys_timers[] = {
-#ifdef CONFIG_SH_TMU
- &tmu_timer,
-#endif
-#ifdef CONFIG_SH_MTU2
- &mtu2_timer,
-#endif
-#ifdef CONFIG_SH_CMT
- &cmt_timer,
-#endif
- NULL,
-};
-
-static char timer_override[10];
-static int __init timer_setup(char *str)
-{
- if (str)
- strlcpy(timer_override, str, sizeof(timer_override));
- return 1;
-}
-__setup("timer=", timer_setup);
-
-struct sys_timer *get_sys_timer(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(sys_timers); i++) {
- struct sys_timer *t = sys_timers[i];
-
- if (unlikely(!t))
- break;
- if (unlikely(timer_override[0]))
- if ((strcmp(timer_override, t->name) != 0))
- continue;
- if (likely(t->ops->init() == 0))
- return t;
- }
-
- return NULL;
-}
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 438f1ebcc453..46348ed07cc3 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -22,11 +22,11 @@ static void handle_BUG(struct pt_regs *regs)
int is_valid_bugaddr(unsigned long addr)
{
- unsigned short opcode;
+ insn_size_t opcode;
if (addr < PAGE_OFFSET)
return 0;
- if (probe_kernel_address((u16 *)addr, opcode))
+ if (probe_kernel_address((insn_size_t *)addr, opcode))
return 0;
return opcode == TRAPA_BUG_OPCODE;
@@ -66,7 +66,7 @@ BUILD_TRAP_HANDLER(bug)
#ifdef CONFIG_BUG
if (__kernel_text_address(instruction_pointer(regs))) {
- opcode_t insn = *(opcode_t *)instruction_pointer(regs);
+ insn_size_t insn = *(insn_size_t *)instruction_pointer(regs);
if (insn == TRAPA_BUG_OPCODE)
handle_BUG(regs);
}
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 30ca9c51e52d..2b772776fcda 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -34,6 +34,7 @@
# define TRAP_ILLEGAL_SLOT_INST 6
# define TRAP_ADDRESS_ERROR 9
# ifdef CONFIG_CPU_SH2A
+# define TRAP_UBC 12
# define TRAP_FPU_ERROR 13
# define TRAP_DIVZERO_ERROR 17
# define TRAP_DIVOVF_ERROR 18
@@ -176,7 +177,7 @@ static struct mem_access user_mem_access = {
* (if that instruction is in a branch delay slot)
* - return 0 if emulation okay, -EFAULT on existential error
*/
-static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs,
+static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs,
struct mem_access *ma)
{
int ret, index, count;
@@ -321,10 +322,10 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs,
* - fetches the instruction from PC+2
*/
static inline int handle_delayslot(struct pt_regs *regs,
- opcode_t old_instruction,
+ insn_size_t old_instruction,
struct mem_access *ma)
{
- opcode_t instruction;
+ insn_size_t instruction;
void __user *addr = (void __user *)(regs->pc +
instruction_size(old_instruction));
@@ -364,7 +365,7 @@ static inline int handle_delayslot(struct pt_regs *regs,
static int handle_unaligned_notify_count = 10;
-int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs,
+int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
struct mem_access *ma)
{
u_int rm;
@@ -522,7 +523,7 @@ asmlinkage void do_address_error(struct pt_regs *regs,
unsigned long error_code = 0;
mm_segment_t oldfs;
siginfo_t info;
- opcode_t instruction;
+ insn_size_t instruction;
int tmp;
/* Intentional ifdef */
@@ -849,6 +850,10 @@ void __init trap_init(void)
#endif
#endif
+#ifdef TRAP_UBC
+ set_exception_table_vec(TRAP_UBC, break_point_trap);
+#endif
+
/* Setup VBR for boot cpu */
per_cpu_trap_init();
}
diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c
index a85831cbf18b..267e5ebbb475 100644
--- a/arch/sh/kernel/traps_64.c
+++ b/arch/sh/kernel/traps_64.c
@@ -370,7 +370,6 @@ static int generate_and_check_address(struct pt_regs *regs,
return -1;
}
-#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
/* Check accessible. For misaligned access in the kernel, assume the
address is always accessible (and if not, just fault when the
load/store gets done.) */
@@ -380,18 +379,13 @@ static int generate_and_check_address(struct pt_regs *regs,
}
/* Do access_ok check later - it depends on whether it's a load or a store. */
}
-#endif
*address = addr;
return 0;
}
-/* Default value as for sh */
-#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
static int user_mode_unaligned_fixup_count = 10;
static int user_mode_unaligned_fixup_enable = 1;
-#endif
-
static int kernel_mode_unaligned_fixup_count = 32;
static void misaligned_kernel_word_load(__u64 address, int do_sign_extend, __u64 *result)
@@ -440,7 +434,6 @@ static int misaligned_load(struct pt_regs *regs,
}
destreg = (opcode >> 4) & 0x3f;
-#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
if (user_mode(regs)) {
__u64 buffer;
@@ -470,9 +463,7 @@ static int misaligned_load(struct pt_regs *regs,
width_shift, (unsigned long) regs->pc);
break;
}
- } else
-#endif
- {
+ } else {
/* kernel mode - we can take short cuts since if we fault, it's a genuine bug */
__u64 lo, hi;
@@ -519,7 +510,6 @@ static int misaligned_store(struct pt_regs *regs,
}
srcreg = (opcode >> 4) & 0x3f;
-#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
if (user_mode(regs)) {
__u64 buffer;
@@ -546,9 +536,7 @@ static int misaligned_store(struct pt_regs *regs,
if (__copy_user((void *)(int)address, &buffer, (1 << width_shift)) > 0) {
return -1; /* fault */
}
- } else
-#endif
- {
+ } else {
/* kernel mode - we can take short cuts since if we fault, it's a genuine bug */
__u64 val = regs->regs[srcreg];
@@ -576,7 +564,6 @@ static int misaligned_store(struct pt_regs *regs,
}
-#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
/* Never need to fix up misaligned FPU accesses within the kernel since that's a real
error. */
static int misaligned_fpu_load(struct pt_regs *regs,
@@ -727,7 +714,6 @@ static int misaligned_fpu_store(struct pt_regs *regs,
return -1;
}
}
-#endif
static int misaligned_fixup(struct pt_regs *regs)
{
@@ -735,12 +721,8 @@ static int misaligned_fixup(struct pt_regs *regs)
int error;
int major, minor;
-#if !defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
- /* Never fixup user mode misaligned accesses without this option enabled. */
- return -1;
-#else
- if (!user_mode_unaligned_fixup_enable) return -1;
-#endif
+ if (!user_mode_unaligned_fixup_enable)
+ return -1;
error = read_opcode(regs->pc, &opcode, user_mode(regs));
if (error < 0) {
@@ -749,15 +731,12 @@ static int misaligned_fixup(struct pt_regs *regs)
major = (opcode >> 26) & 0x3f;
minor = (opcode >> 16) & 0xf;
-#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
if (user_mode(regs) && (user_mode_unaligned_fixup_count > 0)) {
--user_mode_unaligned_fixup_count;
/* Only do 'count' worth of these reports, to remove a potential DoS against syslog */
printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n",
current->comm, task_pid_nr(current), (__u32)regs->pc, opcode);
- } else
-#endif
- if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) {
+ } else if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) {
--kernel_mode_unaligned_fixup_count;
if (in_interrupt()) {
printk("Fixing up unaligned kernelspace access in interrupt pc=0x%08x ins=0x%08lx\n",
@@ -830,7 +809,6 @@ static int misaligned_fixup(struct pt_regs *regs)
}
break;
-#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
case (0x94>>2): /* FLD.S */
error = misaligned_fpu_load(regs, opcode, 1, 2, 0);
break;
@@ -881,7 +859,6 @@ static int misaligned_fixup(struct pt_regs *regs)
break;
}
break;
-#endif
default:
/* Fault */
@@ -907,7 +884,6 @@ static ctl_table unaligned_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec
},
-#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
{
.ctl_name = CTL_UNNUMBERED,
.procname = "user_reports",
@@ -923,7 +899,6 @@ static ctl_table unaligned_table[] = {
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec},
-#endif
{}
};
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index d7d4991f32af..f53c76acaede 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -1,5 +1,178 @@
-#ifdef CONFIG_SUPERH32
-# include "vmlinux_32.lds.S"
+/*
+ * ld script to make SuperH Linux kernel
+ * Written by Niibe Yutaka and Paul Mundt
+ */
+#ifdef CONFIG_SUPERH64
+#define LOAD_OFFSET CONFIG_PAGE_OFFSET
+OUTPUT_ARCH(sh:sh5)
#else
-# include "vmlinux_64.lds.S"
+#define LOAD_OFFSET 0
+OUTPUT_ARCH(sh)
#endif
+
+#include <asm/thread_info.h>
+#include <asm/cache.h>
+#include <asm-generic/vmlinux.lds.h>
+
+ENTRY(_start)
+SECTIONS
+{
+#ifdef CONFIG_PMB_FIXED
+ . = CONFIG_PAGE_OFFSET + (CONFIG_MEMORY_START & 0x1fffffff) +
+ CONFIG_ZERO_PAGE_OFFSET;
+#elif defined(CONFIG_32BIT)
+ . = CONFIG_PAGE_OFFSET + CONFIG_ZERO_PAGE_OFFSET;
+#else
+ . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
+#endif
+
+ _text = .; /* Text and read-only data */
+
+ .empty_zero_page : AT(ADDR(.empty_zero_page) - LOAD_OFFSET) {
+ *(.empty_zero_page)
+ } = 0
+
+ .text : AT(ADDR(.text) - LOAD_OFFSET) {
+ HEAD_TEXT
+ TEXT_TEXT
+
+#ifdef CONFIG_SUPERH64
+ *(.text64)
+ *(.text..SHmedia32)
+#endif
+
+ SCHED_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
+ IRQENTRY_TEXT
+ *(.fixup)
+ *(.gnu.warning)
+ _etext = .; /* End of text section */
+ } = 0x0009
+
+ . = ALIGN(16); /* Exception table */
+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+ }
+
+ NOTES
+ RO_DATA(PAGE_SIZE)
+
+ /*
+ * Code which must be executed uncached and the associated data
+ */
+ . = ALIGN(PAGE_SIZE);
+ .uncached : AT(ADDR(.uncached) - LOAD_OFFSET) {
+ __uncached_start = .;
+ *(.uncached.text)
+ *(.uncached.data)
+ __uncached_end = .;
+ }
+
+ . = ALIGN(THREAD_SIZE);
+ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
+ *(.data.init_task)
+
+ . = ALIGN(L1_CACHE_BYTES);
+ *(.data.cacheline_aligned)
+
+ . = ALIGN(L1_CACHE_BYTES);
+ *(.data.read_mostly)
+
+ . = ALIGN(PAGE_SIZE);
+ *(.data.page_aligned)
+
+ __nosave_begin = .;
+ *(.data.nosave)
+ . = ALIGN(PAGE_SIZE);
+ __nosave_end = .;
+
+ DATA_DATA
+ CONSTRUCTORS
+ }
+
+ _edata = .; /* End of data section */
+
+ . = ALIGN(PAGE_SIZE); /* Init code and data */
+ .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
+ __init_begin = .;
+ _sinittext = .;
+ INIT_TEXT
+ _einittext = .;
+ }
+
+ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { INIT_DATA }
+
+ . = ALIGN(16);
+ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ }
+
+ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
+ __initcall_start = .;
+ INITCALLS
+ __initcall_end = .;
+ }
+
+ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ }
+
+ SECURITY_INIT
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ . = ALIGN(PAGE_SIZE);
+ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ }
+#endif
+
+ . = ALIGN(4);
+ .machvec.init : AT(ADDR(.machvec.init) - LOAD_OFFSET) {
+ __machvec_start = .;
+ *(.machvec.init)
+ __machvec_end = .;
+ }
+
+ PERCPU(PAGE_SIZE)
+
+ /*
+ * .exit.text is discarded at runtime, not link time, to deal with
+ * references from __bug_table
+ */
+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { EXIT_TEXT }
+ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { EXIT_DATA }
+
+ . = ALIGN(PAGE_SIZE);
+ .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
+ __init_end = .;
+ __bss_start = .; /* BSS */
+ *(.bss.page_aligned)
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .; /* uClinux MTD sucks */
+ _end = . ;
+ }
+
+ /*
+ * When something in the kernel is NOT compiled as a module, the
+ * module cleanup code and data are put into these segments. Both
+ * can then be thrown away, as cleanup code is never called unless
+ * it's a module.
+ */
+ /DISCARD/ : {
+ *(.exitcall.exit)
+ }
+
+ STABS_DEBUG
+ DWARF_DEBUG
+}
diff --git a/arch/sh/kernel/vmlinux_32.lds.S b/arch/sh/kernel/vmlinux_32.lds.S
deleted file mode 100644
index dd9b2ee1312d..000000000000
--- a/arch/sh/kernel/vmlinux_32.lds.S
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * ld script to make SuperH Linux kernel
- * Written by Niibe Yutaka
- */
-#include <asm/thread_info.h>
-#include <asm/cache.h>
-#include <asm-generic/vmlinux.lds.h>
-
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
-#else
-OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux")
-#endif
-OUTPUT_ARCH(sh)
-ENTRY(_start)
-SECTIONS
-{
-#ifdef CONFIG_PMB_FIXED
- . = CONFIG_PAGE_OFFSET + (CONFIG_MEMORY_START & 0x1fffffff) +
- CONFIG_ZERO_PAGE_OFFSET;
-#elif defined(CONFIG_32BIT)
- . = CONFIG_PAGE_OFFSET + CONFIG_ZERO_PAGE_OFFSET;
-#else
- . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
-#endif
-
- _text = .; /* Text and read-only data */
-
- .empty_zero_page : {
- *(.empty_zero_page)
- } = 0
-
- .text : {
- HEAD_TEXT
- TEXT_TEXT
- SCHED_TEXT
- LOCK_TEXT
- KPROBES_TEXT
- *(.fixup)
- *(.gnu.warning)
- } = 0x0009
-
- . = ALIGN(16); /* Exception table */
- __start___ex_table = .;
- __ex_table : { *(__ex_table) }
- __stop___ex_table = .;
-
- _etext = .; /* End of text section */
-
- NOTES
- RO_DATA(PAGE_SIZE)
-
- /*
- * Code which must be executed uncached and the associated data
- */
- . = ALIGN(PAGE_SIZE);
- __uncached_start = .;
- .uncached.text : { *(.uncached.text) }
- .uncached.data : { *(.uncached.data) }
- __uncached_end = .;
-
- . = ALIGN(THREAD_SIZE);
- .data : { /* Data */
- *(.data.init_task)
-
- . = ALIGN(L1_CACHE_BYTES);
- *(.data.cacheline_aligned)
-
- . = ALIGN(L1_CACHE_BYTES);
- *(.data.read_mostly)
-
- . = ALIGN(PAGE_SIZE);
- *(.data.page_aligned)
-
- __nosave_begin = .;
- *(.data.nosave)
- . = ALIGN(PAGE_SIZE);
- __nosave_end = .;
-
- DATA_DATA
- CONSTRUCTORS
- }
-
- _edata = .; /* End of data section */
-
- . = ALIGN(PAGE_SIZE); /* Init code and data */
- __init_begin = .;
- _sinittext = .;
- .init.text : { INIT_TEXT }
- _einittext = .;
- .init.data : { INIT_DATA }
-
- . = ALIGN(16);
- __setup_start = .;
- .init.setup : { *(.init.setup) }
- __setup_end = .;
-
- __initcall_start = .;
- .initcall.init : {
- INITCALLS
- }
- __initcall_end = .;
- __con_initcall_start = .;
- .con_initcall.init : { *(.con_initcall.init) }
- __con_initcall_end = .;
-
- SECURITY_INIT
-
-#ifdef CONFIG_BLK_DEV_INITRD
- . = ALIGN(PAGE_SIZE);
- __initramfs_start = .;
- .init.ramfs : { *(.init.ramfs) }
- __initramfs_end = .;
-#endif
-
- . = ALIGN(4);
- __machvec_start = .;
- .machvec.init : { *(.machvec.init) }
- __machvec_end = .;
-
- PERCPU(PAGE_SIZE)
-
- /*
- * .exit.text is discarded at runtime, not link time, to deal with
- * references from __bug_table
- */
- .exit.text : { EXIT_TEXT }
- .exit.data : { EXIT_DATA }
-
- . = ALIGN(PAGE_SIZE);
- .bss : {
- __init_end = .;
- __bss_start = .; /* BSS */
- *(.bss.page_aligned)
- *(.bss)
- *(COMMON)
- . = ALIGN(4);
- _ebss = .; /* uClinux MTD sucks */
- _end = . ;
- }
-
- /*
- * When something in the kernel is NOT compiled as a module, the
- * module cleanup code and data are put into these segments. Both
- * can then be thrown away, as cleanup code is never called unless
- * it's a module.
- */
- /DISCARD/ : {
- *(.exitcall.exit)
- }
-
- STABS_DEBUG
- DWARF_DEBUG
-}
diff --git a/arch/sh/kernel/vmlinux_64.lds.S b/arch/sh/kernel/vmlinux_64.lds.S
deleted file mode 100644
index 69664460c688..000000000000
--- a/arch/sh/kernel/vmlinux_64.lds.S
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * ld script to make SH64 Linux kernel
- *
- * Copyright (C) 2000, 2001 Paolo Alberelli
- *
- * benedict.gaster@superh.com: 2nd May 2002
- * Add definition of empty_zero_page to be the first page of kernel image.
- *
- * benedict.gaster@superh.com: 3rd May 2002
- * Added support for ramdisk, removing statically linked romfs at the
- * same time.
- *
- * lethal@linux-sh.org: 9th May 2003
- * Kill off GLOBAL_NAME() usage and other CDC-isms.
- *
- * lethal@linux-sh.org: 19th May 2003
- * Remove support for ancient toolchains.
- *
- * 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 <asm/page.h>
-#include <asm/cache.h>
-#include <asm/thread_info.h>
-
-#define LOAD_OFFSET CONFIG_PAGE_OFFSET
-#include <asm-generic/vmlinux.lds.h>
-
-OUTPUT_ARCH(sh:sh5)
-
-#define C_PHYS(x) AT (ADDR(x) - LOAD_OFFSET)
-
-ENTRY(__start)
-SECTIONS
-{
- . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + PAGE_SIZE;
- _text = .; /* Text and read-only data */
-
- .empty_zero_page : C_PHYS(.empty_zero_page) {
- *(.empty_zero_page)
- } = 0
-
- .text : C_PHYS(.text) {
- HEAD_TEXT
- TEXT_TEXT
- *(.text64)
- *(.text..SHmedia32)
- SCHED_TEXT
- LOCK_TEXT
- KPROBES_TEXT
- *(.fixup)
- *(.gnu.warning)
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
- } = 0x6ff0fff0
-#else
- } = 0xf0fff06f
-#endif
-
- /* We likely want __ex_table to be Cache Line aligned */
- . = ALIGN(L1_CACHE_BYTES); /* Exception table */
- __start___ex_table = .;
- __ex_table : C_PHYS(__ex_table) { *(__ex_table) }
- __stop___ex_table = .;
-
- _etext = .; /* End of text section */
-
- NOTES
- RO_DATA(PAGE_SIZE)
-
- . = ALIGN(THREAD_SIZE);
- .data : C_PHYS(.data) { /* Data */
- *(.data.init_task)
-
- . = ALIGN(L1_CACHE_BYTES);
- *(.data.cacheline_aligned)
-
- . = ALIGN(L1_CACHE_BYTES);
- *(.data.read_mostly)
-
- . = ALIGN(PAGE_SIZE);
- *(.data.page_aligned)
-
- __nosave_begin = .;
- *(.data.nosave)
- . = ALIGN(PAGE_SIZE);
- __nosave_end = .;
-
- DATA_DATA
- CONSTRUCTORS
- }
-
- _edata = .; /* End of data section */
-
- . = ALIGN(PAGE_SIZE); /* Init code and data */
- __init_begin = .;
- _sinittext = .;
- .init.text : C_PHYS(.init.text) { INIT_TEXT }
- _einittext = .;
- .init.data : C_PHYS(.init.data) { INIT_DATA }
- . = ALIGN(L1_CACHE_BYTES); /* Better if Cache Line aligned */
- __setup_start = .;
- .init.setup : C_PHYS(.init.setup) { *(.init.setup) }
- __setup_end = .;
- __initcall_start = .;
- .initcall.init : C_PHYS(.initcall.init) {
- INITCALLS
- }
- __initcall_end = .;
- __con_initcall_start = .;
- .con_initcall.init : C_PHYS(.con_initcall.init) {
- *(.con_initcall.init)
- }
- __con_initcall_end = .;
-
- SECURITY_INIT
-
-#ifdef CONFIG_BLK_DEV_INITRD
- . = ALIGN(PAGE_SIZE);
- __initramfs_start = .;
- .init.ramfs : C_PHYS(.init.ramfs) { *(.init.ramfs) }
- __initramfs_end = .;
-#endif
-
- . = ALIGN(8);
- __machvec_start = .;
- .machvec.init : C_PHYS(.machvec.init) { *(.machvec.init) }
- __machvec_end = .;
-
- PERCPU(PAGE_SIZE)
-
- /*
- * .exit.text is discarded at runtime, not link time, to deal with
- * references from __bug_table
- */
- .exit.text : C_PHYS(.exit.text) { EXIT_TEXT }
- .exit.data : C_PHYS(.exit.data) { EXIT_DATA }
-
- . = ALIGN(PAGE_SIZE);
- .bss : C_PHYS(.bss) {
- __init_end = .;
- __bss_start = .; /* BSS */
- *(.bss.page_aligned)
- *(.bss)
- *(COMMON)
- . = ALIGN(4);
- _ebss = .; /* uClinux MTD sucks */
- _end = . ;
- }
-
- /*
- * When something in the kernel is NOT compiled as a module, the
- * module cleanup code and data are put into these segments. Both
- * can then be thrown away, as cleanup code is never called unless
- * it's a module.
- */
- /DISCARD/ : {
- *(.exitcall.exit)
- }
-
- STABS_DEBUG
- DWARF_DEBUG
-}
diff --git a/arch/sh/lib64/.gitignore b/arch/sh/lib64/.gitignore
deleted file mode 100644
index 3508c2cb23c4..000000000000
--- a/arch/sh/lib64/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-syscalltab.h
diff --git a/arch/sh/lib64/dbg.c b/arch/sh/lib64/dbg.c
index 2fb8eaf6de60..6152a6a6d9c6 100644
--- a/arch/sh/lib64/dbg.c
+++ b/arch/sh/lib64/dbg.c
@@ -135,140 +135,6 @@ void print_itlb(void)
(" =============================================================\n");
}
-/* ======================================================================= */
-
-#ifdef CONFIG_POOR_MANS_STRACE
-
-#include "syscalltab.h"
-
-struct ring_node {
- int evt;
- int ret_addr;
- int event;
- int tra;
- int pid;
- unsigned long sp;
- unsigned long pc;
-};
-
-static struct ring_node event_ring[16];
-static int event_ptr = 0;
-
-struct stored_syscall_data {
- int pid;
- int syscall_number;
-};
-
-#define N_STORED_SYSCALLS 16
-
-static struct stored_syscall_data stored_syscalls[N_STORED_SYSCALLS];
-static int syscall_next=0;
-static int syscall_next_print=0;
-
-void evt_debug(int evt, int ret_addr, int event, int tra, struct pt_regs *regs)
-{
- int syscallno = tra & 0xff;
- unsigned long sp;
- unsigned long stack_bottom;
- int pid;
- struct ring_node *rr;
-
- pid = current->pid;
- stack_bottom = (unsigned long) task_stack_page(current);
- asm volatile("ori r15, 0, %0" : "=r" (sp));
- rr = event_ring + event_ptr;
- rr->evt = evt;
- rr->ret_addr = ret_addr;
- rr->event = event;
- rr->tra = tra;
- rr->pid = pid;
- rr->sp = sp;
- rr->pc = regs->pc;
-
- if (sp < stack_bottom + 3092) {
- int i, j;
- printk("evt_debug : stack underflow report\n");
- for (j=0, i = event_ptr; j<16; j++) {
- rr = event_ring + i;
- printk("evt=%08x event=%08x tra=%08x pid=%5d sp=%08lx pc=%08lx\n",
- rr->evt, rr->event, rr->tra, rr->pid, rr->sp, rr->pc);
- i--;
- i &= 15;
- }
- panic("STACK UNDERFLOW\n");
- }
-
- event_ptr = (event_ptr + 1) & 15;
-
- if ((event == 2) && (evt == 0x160)) {
- if (syscallno < NUM_SYSCALL_INFO_ENTRIES) {
- /* Store the syscall information to print later. We
- * can't print this now - currently we're running with
- * SR.BL=1, so we can't take a tlbmiss (which could occur
- * in the console drivers under printk).
- *
- * Just overwrite old entries on ring overflow - this
- * is only for last-hope debugging. */
- stored_syscalls[syscall_next].pid = current->pid;
- stored_syscalls[syscall_next].syscall_number = syscallno;
- syscall_next++;
- syscall_next &= (N_STORED_SYSCALLS - 1);
- }
- }
-}
-
-static void drain_syscalls(void) {
- while (syscall_next_print != syscall_next) {
- printk("Task %d: %s()\n",
- stored_syscalls[syscall_next_print].pid,
- syscall_info_table[stored_syscalls[syscall_next_print].syscall_number].name);
- syscall_next_print++;
- syscall_next_print &= (N_STORED_SYSCALLS - 1);
- }
-}
-
-void evt_debug2(unsigned int ret)
-{
- drain_syscalls();
- printk("Task %d: syscall returns %08x\n", current->pid, ret);
-}
-
-void evt_debug_ret_from_irq(struct pt_regs *regs)
-{
- int pid;
- struct ring_node *rr;
-
- pid = current->pid;
- rr = event_ring + event_ptr;
- rr->evt = 0xffff;
- rr->ret_addr = 0;
- rr->event = 0;
- rr->tra = 0;
- rr->pid = pid;
- rr->pc = regs->pc;
- event_ptr = (event_ptr + 1) & 15;
-}
-
-void evt_debug_ret_from_exc(struct pt_regs *regs)
-{
- int pid;
- struct ring_node *rr;
-
- pid = current->pid;
- rr = event_ring + event_ptr;
- rr->evt = 0xfffe;
- rr->ret_addr = 0;
- rr->event = 0;
- rr->tra = 0;
- rr->pid = pid;
- rr->pc = regs->pc;
- event_ptr = (event_ptr + 1) & 15;
-}
-
-#endif /* CONFIG_POOR_MANS_STRACE */
-
-/* ======================================================================= */
-
void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs)
{
@@ -380,51 +246,3 @@ void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs)
print_dtlb();
print_itlb();
}
-
-/* ======================================================================= */
-
-/*
-** Depending on <base> scan the MMU, Data or Instruction side
-** looking for a valid mapping matching Eaddr & asid.
-** Return -1 if not found or the TLB id entry otherwise.
-** Note: it works only for 4k pages!
-*/
-static unsigned long
-lookup_mmu_side(unsigned long base, unsigned long Eaddr, unsigned long asid)
-{
- regType_t pteH;
- unsigned long epn;
- int count;
-
- epn = Eaddr & 0xfffff000;
-
- for (count = 0; count < MAX_TLBs; count++, base += TLB_STEP) {
- pteH = getConfigReg(base);
- if (GET_VALID(pteH))
- if ((unsigned long) GET_EPN(pteH) == epn)
- if ((unsigned long) GET_ASID(pteH) == asid)
- break;
- }
- return ((unsigned long) ((count < MAX_TLBs) ? base : -1));
-}
-
-unsigned long lookup_dtlb(unsigned long Eaddr)
-{
- unsigned long asid = get_asid();
- return (lookup_mmu_side((u64) DTLB_BASE, Eaddr, asid));
-}
-
-unsigned long lookup_itlb(unsigned long Eaddr)
-{
- unsigned long asid = get_asid();
- return (lookup_mmu_side((u64) ITLB_BASE, Eaddr, asid));
-}
-
-void print_page(struct page *page)
-{
- printk(" page[%p] -> index 0x%lx, count 0x%x, flags 0x%lx\n",
- page, page->index, page_count(page), page->flags);
- printk(" address_space = %p, pages =%ld\n", page->mapping,
- page->mapping->nrpages);
-
-}
diff --git a/arch/sh/lib64/panic.c b/arch/sh/lib64/panic.c
index da32ba7b5fcc..38c954e04f6a 100644
--- a/arch/sh/lib64/panic.c
+++ b/arch/sh/lib64/panic.c
@@ -6,53 +6,10 @@
* for more details.
*/
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <cpu/registers.h>
-
-/* THIS IS A PHYSICAL ADDRESS */
-#define HDSP2534_ADDR (0x04002100)
-
-#ifdef CONFIG_SH_CAYMAN
-
-static void poor_mans_delay(void)
-{
- int i;
- for (i = 0; i < 2500000; i++) {
- } /* poor man's delay */
-}
-
-static void show_value(unsigned long x)
-{
- int i;
- unsigned nibble;
- for (i = 0; i < 8; i++) {
- nibble = ((x >> (i * 4)) & 0xf);
-
- ctrl_outb(nibble + ((nibble > 9) ? 55 : 48),
- HDSP2534_ADDR + 0xe0 + ((7 - i) << 2));
- }
-}
-
-#endif
-
void
panic_handler(unsigned long panicPC, unsigned long panicSSR,
unsigned long panicEXPEVT)
{
-#ifdef CONFIG_SH_CAYMAN
- while (1) {
- /* This piece of code displays the PC on the LED display */
- show_value(panicPC);
- poor_mans_delay();
- show_value(panicSSR);
- poor_mans_delay();
- show_value(panicEXPEVT);
- poor_mans_delay();
- }
-#endif
-
/* Never return from the panic handler */
for (;;) ;
-
}
diff --git a/arch/sh/lib64/sdivsi3.S b/arch/sh/lib64/sdivsi3.S
index 6a800c6a4904..1963bbd42288 100644
--- a/arch/sh/lib64/sdivsi3.S
+++ b/arch/sh/lib64/sdivsi3.S
@@ -1,4 +1,6 @@
.global __sdivsi3
+ .global __sdivsi3_1
+ .global __sdivsi3_2
.section .text..SHmedia32,"ax"
.align 2
@@ -6,13 +8,15 @@
/* clobbered: r1,r18,r19,r20,r21,r25,tr0 */
/* result in r0 */
__sdivsi3:
+__sdivsi3_1:
ptb __div_table,tr0
+ gettr tr0,r20
+__sdivsi3_2:
nsb r5, r1
shlld r5, r1, r25 /* normalize; [-2 ..1, 1..2) in s2.62 */
shari r25, 58, r21 /* extract 5(6) bit index (s2.4 with hole -1..1) */
/* bubble */
- gettr tr0,r20
ldx.ub r20, r21, r19 /* u0.8 */
shari r25, 32, r25 /* normalize to s2.30 */
shlli r21, 1, r21
diff --git a/arch/sh/lib64/udelay.c b/arch/sh/lib64/udelay.c
index d76bd801194f..f215b063da70 100644
--- a/arch/sh/lib64/udelay.c
+++ b/arch/sh/lib64/udelay.c
@@ -33,7 +33,7 @@ void __delay(unsigned long loops)
:"0"(loops));
}
-inline void __const_udelay(unsigned long xloops)
+void __const_udelay(unsigned long xloops)
{
__delay(xloops * (HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy));
}
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index d4079cab2d58..b900d2cd18f7 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -201,14 +201,6 @@ config PAGE_SIZE_64KB
endchoice
-config ENTRY_OFFSET
- hex
- default "0x00001000" if PAGE_SIZE_4KB
- default "0x00002000" if PAGE_SIZE_8KB
- default "0x00004000" if PAGE_SIZE_16KB
- default "0x00010000" if PAGE_SIZE_64KB
- default "0x00000000"
-
choice
prompt "HugeTLB page size"
depends on HUGETLB_PAGE && (CPU_SH4 || CPU_SH5) && MMU
diff --git a/arch/sh/mm/cache-sh5.c b/arch/sh/mm/cache-sh5.c
index 9e277ec7d536..86762092508c 100644
--- a/arch/sh/mm/cache-sh5.c
+++ b/arch/sh/mm/cache-sh5.c
@@ -60,7 +60,7 @@ static inline void sh64_teardown_dtlb_cache_slot(void)
static inline void sh64_icache_inv_all(void)
{
unsigned long long addr, flag, data;
- unsigned int flags;
+ unsigned long flags;
addr = ICCR0;
flag = ICCR0_ICI;
@@ -172,7 +172,7 @@ static void sh64_icache_inv_user_page_range(struct mm_struct *mm,
unsigned long eaddr;
unsigned long after_last_page_start;
unsigned long mm_asid, current_asid;
- unsigned long long flags = 0ULL;
+ unsigned long flags = 0;
mm_asid = cpu_asid(smp_processor_id(), mm);
current_asid = get_asid();
@@ -236,7 +236,7 @@ static void sh64_icache_inv_user_small_range(struct mm_struct *mm,
unsigned long long eaddr = start;
unsigned long long eaddr_end = start + len;
unsigned long current_asid, mm_asid;
- unsigned long long flags;
+ unsigned long flags;
unsigned long long epage_start;
/*
@@ -342,7 +342,7 @@ static void inline sh64_dcache_purge_sets(int sets_to_purge_base, int n_sets)
* alloco is a NOP if the cache is write-through.
*/
if (test_bit(SH_CACHE_MODE_WT, &(cpu_data->dcache.flags)))
- ctrl_inb(eaddr);
+ __raw_readb((unsigned long)eaddr);
}
}
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c
index 60cc486d2c2c..da2f4186f2cd 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap_32.c
@@ -46,17 +46,15 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
return NULL;
/*
- * If we're on an SH7751 or SH7780 PCI controller, PCI memory is
- * mapped at the end of the address space (typically 0xfd000000)
- * in a non-translatable area, so mapping through page tables for
- * this area is not only pointless, but also fundamentally
- * broken. Just return the physical address instead.
+ * If we're in the fixed PCI memory range, mapping through page
+ * tables is not only pointless, but also fundamentally broken.
+ * Just return the physical address instead.
*
* For boards that map a small PCI memory aperture somewhere in
* P1/P2 space, ioremap() will already do the right thing,
* and we'll never get this far.
*/
- if (is_pci_memaddr(phys_addr) && is_pci_memaddr(last_addr))
+ if (is_pci_memory_fixed_range(phys_addr, size))
return (void __iomem *)phys_addr;
#if !defined(CONFIG_PMB_FIXED)
@@ -121,7 +119,9 @@ void __iounmap(void __iomem *addr)
unsigned long seg = PXSEG(vaddr);
struct vm_struct *p;
- if (seg < P3SEG || vaddr >= P3_ADDR_MAX || is_pci_memaddr(vaddr))
+ if (seg < P3SEG || vaddr >= P3_ADDR_MAX)
+ return;
+ if (is_pci_memory_fixed_range(vaddr, 0))
return;
#ifdef CONFIG_PMB
diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c
index 31e1bb5effbe..2331229f8126 100644
--- a/arch/sh/mm/ioremap_64.c
+++ b/arch/sh/mm/ioremap_64.c
@@ -27,88 +27,17 @@
#include <asm/tlbflush.h>
#include <asm/mmu.h>
-static void shmedia_mapioaddr(unsigned long, unsigned long);
-static unsigned long shmedia_ioremap(struct resource *, u32, int);
-
-/*
- * Generic mapping function (not visible outside):
- */
-
-/*
- * Remap an arbitrary physical address space into the kernel virtual
- * address space. Needed when the kernel wants to access high addresses
- * directly.
- *
- * NOTE! We need to allow non-page-aligned mappings too: we will obviously
- * have to convert them into an offset in a page-aligned mapping, but the
- * caller shouldn't need to know that small detail.
- */
-void *__ioremap(unsigned long phys_addr, unsigned long size,
- unsigned long flags)
-{
- void * addr;
- struct vm_struct * area;
- unsigned long offset, last_addr;
- pgprot_t pgprot;
-
- /* Don't allow wraparound or zero size */
- last_addr = phys_addr + size - 1;
- if (!size || last_addr < phys_addr)
- return NULL;
-
- pgprot = __pgprot(_PAGE_PRESENT | _PAGE_READ |
- _PAGE_WRITE | _PAGE_DIRTY |
- _PAGE_ACCESSED | _PAGE_SHARED | flags);
-
- /*
- * Mappings have to be page-aligned
- */
- offset = phys_addr & ~PAGE_MASK;
- phys_addr &= PAGE_MASK;
- size = PAGE_ALIGN(last_addr + 1) - phys_addr;
-
- /*
- * Ok, go for it..
- */
- area = get_vm_area(size, VM_IOREMAP);
- if (!area)
- return NULL;
- pr_debug("Get vm_area returns %p addr %p\n", area, area->addr);
- area->phys_addr = phys_addr;
- addr = area->addr;
- if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
- phys_addr, pgprot)) {
- vunmap(addr);
- return NULL;
- }
- return (void *) (offset + (char *)addr);
-}
-EXPORT_SYMBOL(__ioremap);
-
-void __iounmap(void *addr)
-{
- struct vm_struct *area;
-
- vfree((void *) (PAGE_MASK & (unsigned long) addr));
- area = remove_vm_area((void *) (PAGE_MASK & (unsigned long) addr));
- if (!area) {
- printk(KERN_ERR "iounmap: bad address %p\n", addr);
- return;
- }
-
- kfree(area);
-}
-EXPORT_SYMBOL(__iounmap);
-
static struct resource shmedia_iomap = {
.name = "shmedia_iomap",
.start = IOBASE_VADDR + PAGE_SIZE,
.end = IOBASE_END - 1,
};
-static void shmedia_mapioaddr(unsigned long pa, unsigned long va);
+static void shmedia_mapioaddr(unsigned long pa, unsigned long va,
+ unsigned long flags);
static void shmedia_unmapioaddr(unsigned long vaddr);
-static unsigned long shmedia_ioremap(struct resource *res, u32 pa, int sz);
+static void __iomem *shmedia_ioremap(struct resource *res, u32 pa,
+ int sz, unsigned long flags);
/*
* We have the same problem as the SPARC, so lets have the same comment:
@@ -130,18 +59,18 @@ static struct xresource xresv[XNRES];
static struct xresource *xres_alloc(void)
{
- struct xresource *xrp;
- int n;
-
- xrp = xresv;
- for (n = 0; n < XNRES; n++) {
- if (xrp->xflag == 0) {
- xrp->xflag = 1;
- return xrp;
- }
- xrp++;
- }
- return NULL;
+ struct xresource *xrp;
+ int n;
+
+ xrp = xresv;
+ for (n = 0; n < XNRES; n++) {
+ if (xrp->xflag == 0) {
+ xrp->xflag = 1;
+ return xrp;
+ }
+ xrp++;
+ }
+ return NULL;
}
static void xres_free(struct xresource *xrp)
@@ -161,76 +90,71 @@ static struct resource *shmedia_find_resource(struct resource *root,
return NULL;
}
-static unsigned long shmedia_alloc_io(unsigned long phys, unsigned long size,
- const char *name)
+static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size,
+ const char *name, unsigned long flags)
{
- static int printed_full = 0;
- struct xresource *xres;
- struct resource *res;
- char *tack;
- int tlen;
-
- if (name == NULL) name = "???";
-
- if ((xres = xres_alloc()) != 0) {
- tack = xres->xname;
- res = &xres->xres;
- } else {
- if (!printed_full) {
- printk("%s: done with statics, switching to kmalloc\n",
- __func__);
- printed_full = 1;
- }
- tlen = strlen(name);
- tack = kmalloc(sizeof (struct resource) + tlen + 1, GFP_KERNEL);
- if (!tack)
- return -ENOMEM;
- memset(tack, 0, sizeof(struct resource));
- res = (struct resource *) tack;
- tack += sizeof (struct resource);
- }
-
- strncpy(tack, name, XNMLN);
- tack[XNMLN] = 0;
- res->name = tack;
-
- return shmedia_ioremap(res, phys, size);
+ static int printed_full;
+ struct xresource *xres;
+ struct resource *res;
+ char *tack;
+ int tlen;
+
+ if (name == NULL)
+ name = "???";
+
+ xres = xres_alloc();
+ if (xres != 0) {
+ tack = xres->xname;
+ res = &xres->xres;
+ } else {
+ if (!printed_full) {
+ printk(KERN_NOTICE "%s: done with statics, "
+ "switching to kmalloc\n", __func__);
+ printed_full = 1;
+ }
+ tlen = strlen(name);
+ tack = kmalloc(sizeof(struct resource) + tlen + 1, GFP_KERNEL);
+ if (!tack)
+ return NULL;
+ memset(tack, 0, sizeof(struct resource));
+ res = (struct resource *) tack;
+ tack += sizeof(struct resource);
+ }
+
+ strncpy(tack, name, XNMLN);
+ tack[XNMLN] = 0;
+ res->name = tack;
+
+ return shmedia_ioremap(res, phys, size, flags);
}
-static unsigned long shmedia_ioremap(struct resource *res, u32 pa, int sz)
+static void __iomem *shmedia_ioremap(struct resource *res, u32 pa, int sz,
+ unsigned long flags)
{
- unsigned long offset = ((unsigned long) pa) & (~PAGE_MASK);
+ unsigned long offset = ((unsigned long) pa) & (~PAGE_MASK);
unsigned long round_sz = (offset + sz + PAGE_SIZE-1) & PAGE_MASK;
- unsigned long va;
- unsigned int psz;
+ unsigned long va;
+ unsigned int psz;
- if (allocate_resource(&shmedia_iomap, res, round_sz,
+ if (allocate_resource(&shmedia_iomap, res, round_sz,
shmedia_iomap.start, shmedia_iomap.end,
PAGE_SIZE, NULL, NULL) != 0) {
- panic("alloc_io_res(%s): cannot occupy\n",
- (res->name != NULL)? res->name: "???");
- }
+ panic("alloc_io_res(%s): cannot occupy\n",
+ (res->name != NULL) ? res->name : "???");
+ }
- va = res->start;
- pa &= PAGE_MASK;
+ va = res->start;
+ pa &= PAGE_MASK;
psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;
- /* log at boot time ... */
- printk("mapioaddr: %6s [%2d page%s] va 0x%08lx pa 0x%08x\n",
- ((res->name != NULL) ? res->name : "???"),
- psz, psz == 1 ? " " : "s", va, pa);
-
- for (psz = res->end - res->start + 1; psz != 0; psz -= PAGE_SIZE) {
- shmedia_mapioaddr(pa, va);
- va += PAGE_SIZE;
- pa += PAGE_SIZE;
- }
-
- res->start += offset;
- res->end = res->start + sz - 1; /* not strictly necessary.. */
+ for (psz = res->end - res->start + 1; psz != 0; psz -= PAGE_SIZE) {
+ shmedia_mapioaddr(pa, va, flags);
+ va += PAGE_SIZE;
+ pa += PAGE_SIZE;
+ }
- return res->start;
+ return (void __iomem *)(unsigned long)(res->start + offset);
}
static void shmedia_free_io(struct resource *res)
@@ -249,14 +173,12 @@ static void shmedia_free_io(struct resource *res)
static __init_refok void *sh64_get_page(void)
{
- extern int after_bootmem;
void *page;
- if (after_bootmem) {
- page = (void *)get_zeroed_page(GFP_ATOMIC);
- } else {
+ if (after_bootmem)
+ page = (void *)get_zeroed_page(GFP_KERNEL);
+ else
page = alloc_bootmem_pages(PAGE_SIZE);
- }
if (!page || ((unsigned long)page & ~PAGE_MASK))
panic("sh64_get_page: Out of memory already?\n");
@@ -264,17 +186,20 @@ static __init_refok void *sh64_get_page(void)
return page;
}
-static void shmedia_mapioaddr(unsigned long pa, unsigned long va)
+static void shmedia_mapioaddr(unsigned long pa, unsigned long va,
+ unsigned long flags)
{
pgd_t *pgdp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep, pte;
pgprot_t prot;
- unsigned long flags = 1; /* 1 = CB0-1 device */
pr_debug("shmedia_mapiopage pa %08lx va %08lx\n", pa, va);
+ if (!flags)
+ flags = 1; /* 1 = CB0-1 device */
+
pgdp = pgd_offset_k(va);
if (pgd_none(*pgdp) || !pgd_present(*pgdp)) {
pudp = (pud_t *)sh64_get_page();
@@ -288,7 +213,7 @@ static void shmedia_mapioaddr(unsigned long pa, unsigned long va)
}
pmdp = pmd_offset(pudp, va);
- if (pmd_none(*pmdp) || !pmd_present(*pmdp) ) {
+ if (pmd_none(*pmdp) || !pmd_present(*pmdp)) {
ptep = (pte_t *)sh64_get_page();
set_pmd(pmdp, __pmd((unsigned long)ptep + _PAGE_TABLE));
}
@@ -336,17 +261,19 @@ static void shmedia_unmapioaddr(unsigned long vaddr)
pte_clear(&init_mm, vaddr, ptep);
}
-unsigned long onchip_remap(unsigned long phys, unsigned long size, const char *name)
+void __iomem *__ioremap(unsigned long offset, unsigned long size,
+ unsigned long flags)
{
- if (size < PAGE_SIZE)
- size = PAGE_SIZE;
+ char name[14];
- return shmedia_alloc_io(phys, size, name);
+ sprintf(name, "phys_%08x", (u32)offset);
+ return shmedia_alloc_io(offset, size, name, flags);
}
-EXPORT_SYMBOL(onchip_remap);
+EXPORT_SYMBOL(__ioremap);
-void onchip_unmap(unsigned long vaddr)
+void __iounmap(void __iomem *virtual)
{
+ unsigned long vaddr = (unsigned long)virtual & PAGE_MASK;
struct resource *res;
unsigned int psz;
@@ -357,10 +284,7 @@ void onchip_unmap(unsigned long vaddr)
return;
}
- psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;
-
- printk(KERN_DEBUG "unmapioaddr: %6s [%2d page%s] freed\n",
- res->name, psz, psz == 1 ? " " : "s");
+ psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;
shmedia_free_io(res);
@@ -371,9 +295,8 @@ void onchip_unmap(unsigned long vaddr)
kfree(res);
}
}
-EXPORT_SYMBOL(onchip_unmap);
+EXPORT_SYMBOL(__iounmap);
-#ifdef CONFIG_PROC_FS
static int
ioremap_proc_info(char *buf, char **start, off_t fpos, int length, int *eof,
void *data)
@@ -385,7 +308,10 @@ ioremap_proc_info(char *buf, char **start, off_t fpos, int length, int *eof,
for (r = ((struct resource *)data)->child; r != NULL; r = r->sibling) {
if (p + 32 >= e) /* Better than nothing */
break;
- if ((nm = r->name) == 0) nm = "???";
+ nm = r->name;
+ if (nm == NULL)
+ nm = "???";
+
p += sprintf(p, "%08lx-%08lx: %s\n",
(unsigned long)r->start,
(unsigned long)r->end, nm);
@@ -393,14 +319,11 @@ ioremap_proc_info(char *buf, char **start, off_t fpos, int length, int *eof,
return p-buf;
}
-#endif /* CONFIG_PROC_FS */
static int __init register_proc_onchip(void)
{
-#ifdef CONFIG_PROC_FS
- create_proc_read_entry("io_map",0,0, ioremap_proc_info, &shmedia_iomap);
-#endif
+ create_proc_read_entry("io_map", 0, 0, ioremap_proc_info,
+ &shmedia_iomap);
return 0;
}
-
-__initcall(register_proc_onchip);
+late_initcall(register_proc_onchip);
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index 931f4d003fa0..1b5fdfb4e0c2 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -1,7 +1,7 @@
/*
* arch/sh/mm/mmap.c
*
- * Copyright (C) 2008 Paul Mundt
+ * Copyright (C) 2008 - 2009 Paul Mundt
*
* 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
@@ -21,9 +21,26 @@ EXPORT_SYMBOL(shm_align_mask);
/*
* To avoid cache aliases, we map the shared page with same color.
*/
-#define COLOUR_ALIGN(addr, pgoff) \
- ((((addr) + shm_align_mask) & ~shm_align_mask) + \
- (((pgoff) << PAGE_SHIFT) & shm_align_mask))
+static inline unsigned long COLOUR_ALIGN(unsigned long addr,
+ unsigned long pgoff)
+{
+ unsigned long base = (addr + shm_align_mask) & ~shm_align_mask;
+ unsigned long off = (pgoff << PAGE_SHIFT) & shm_align_mask;
+
+ return base + off;
+}
+
+static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr,
+ unsigned long pgoff)
+{
+ unsigned long base = addr & ~shm_align_mask;
+ unsigned long off = (pgoff << PAGE_SHIFT) & shm_align_mask;
+
+ if (base + off <= addr)
+ return base + off;
+
+ return base - off;
+}
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags)
@@ -103,6 +120,117 @@ full_search:
addr = COLOUR_ALIGN(addr, pgoff);
}
}
+
+unsigned long
+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ const unsigned long len, const unsigned long pgoff,
+ const unsigned long flags)
+{
+ struct vm_area_struct *vma;
+ struct mm_struct *mm = current->mm;
+ unsigned long addr = addr0;
+ int do_colour_align;
+
+ if (flags & MAP_FIXED) {
+ /* We do not accept a shared mapping if it would violate
+ * cache aliasing constraints.
+ */
+ if ((flags & MAP_SHARED) &&
+ ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
+ return -EINVAL;
+ return addr;
+ }
+
+ if (unlikely(len > TASK_SIZE))
+ return -ENOMEM;
+
+ do_colour_align = 0;
+ if (filp || (flags & MAP_SHARED))
+ do_colour_align = 1;
+
+ /* requesting a specific address */
+ if (addr) {
+ if (do_colour_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+ else
+ addr = PAGE_ALIGN(addr);
+
+ vma = find_vma(mm, addr);
+ if (TASK_SIZE - len >= addr &&
+ (!vma || addr + len <= vma->vm_start))
+ return addr;
+ }
+
+ /* check if free_area_cache is useful for us */
+ if (len <= mm->cached_hole_size) {
+ mm->cached_hole_size = 0;
+ mm->free_area_cache = mm->mmap_base;
+ }
+
+ /* either no address requested or can't fit in requested address hole */
+ addr = mm->free_area_cache;
+ if (do_colour_align) {
+ unsigned long base = COLOUR_ALIGN_DOWN(addr-len, pgoff);
+
+ addr = base + len;
+ }
+
+ /* make sure it can fit in the remaining address space */
+ if (likely(addr > len)) {
+ vma = find_vma(mm, addr-len);
+ if (!vma || addr <= vma->vm_start) {
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr-len);
+ }
+ }
+
+ if (unlikely(mm->mmap_base < len))
+ goto bottomup;
+
+ addr = mm->mmap_base-len;
+ if (do_colour_align)
+ addr = COLOUR_ALIGN_DOWN(addr, pgoff);
+
+ do {
+ /*
+ * Lookup failure means no vma is above this address,
+ * else if new region fits below vma->vm_start,
+ * return with success:
+ */
+ vma = find_vma(mm, addr);
+ if (likely(!vma || addr+len <= vma->vm_start)) {
+ /* remember the address as a hint for next time */
+ return (mm->free_area_cache = addr);
+ }
+
+ /* remember the largest hole we saw so far */
+ if (addr + mm->cached_hole_size < vma->vm_start)
+ mm->cached_hole_size = vma->vm_start - addr;
+
+ /* try just below the current vma->vm_start */
+ addr = vma->vm_start-len;
+ if (do_colour_align)
+ addr = COLOUR_ALIGN_DOWN(addr, pgoff);
+ } while (likely(len < vma->vm_start));
+
+bottomup:
+ /*
+ * A failed mmap() very likely causes application failure,
+ * so fall back to the bottom-up function here. This scenario
+ * can happen with large stack limits and large mmap()
+ * allocations.
+ */
+ mm->cached_hole_size = ~0UL;
+ mm->free_area_cache = TASK_UNMAPPED_BASE;
+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
+ /*
+ * Restore the topdown base:
+ */
+ mm->free_area_cache = mm->mmap_base;
+ mm->cached_hole_size = ~0UL;
+
+ return addr;
+}
#endif /* CONFIG_MMU */
/*
diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c
index 1b9d4304b3bf..44f4e31c6d63 100644
--- a/arch/sh/oprofile/common.c
+++ b/arch/sh/oprofile/common.c
@@ -109,6 +109,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
case CPU_SH7785:
case CPU_SH7786:
case CPU_SH7723:
+ case CPU_SH7724:
case CPU_SHX3:
lmodel = &op_model_sh4a_ops;
break;
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index cc12cd48bbc5..2185cf946d68 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -93,6 +93,9 @@ config AUDIT_ARCH
config HAVE_SETUP_PER_CPU_AREA
def_bool y if SPARC64
+config HAVE_DYNAMIC_PER_CPU_AREA
+ def_bool y if SPARC64
+
config GENERIC_HARDIRQS_NO__DO_IRQ
bool
def_bool y if SPARC64
diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h
index a11b89ee9ef8..926397d345ff 100644
--- a/arch/sparc/include/asm/cpudata_64.h
+++ b/arch/sparc/include/asm/cpudata_64.h
@@ -6,9 +6,6 @@
#ifndef _SPARC64_CPUDATA_H
#define _SPARC64_CPUDATA_H
-#include <asm/hypervisor.h>
-#include <asm/asi.h>
-
#ifndef __ASSEMBLY__
#include <linux/percpu.h>
@@ -38,202 +35,10 @@ DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
#define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu))
#define local_cpu_data() __get_cpu_var(__cpu_data)
-/* Trap handling code needs to get at a few critical values upon
- * trap entry and to process TSB misses. These cannot be in the
- * per_cpu() area as we really need to lock them into the TLB and
- * thus make them part of the main kernel image. As a result we
- * try to make this as small as possible.
- *
- * This is padded out and aligned to 64-bytes to avoid false sharing
- * on SMP.
- */
-
-/* If you modify the size of this structure, please update
- * TRAP_BLOCK_SZ_SHIFT below.
- */
-struct thread_info;
-struct trap_per_cpu {
-/* D-cache line 1: Basic thread information, cpu and device mondo queues */
- struct thread_info *thread;
- unsigned long pgd_paddr;
- unsigned long cpu_mondo_pa;
- unsigned long dev_mondo_pa;
-
-/* D-cache line 2: Error Mondo Queue and kernel buffer pointers */
- unsigned long resum_mondo_pa;
- unsigned long resum_kernel_buf_pa;
- unsigned long nonresum_mondo_pa;
- unsigned long nonresum_kernel_buf_pa;
-
-/* Dcache lines 3, 4, 5, and 6: Hypervisor Fault Status */
- struct hv_fault_status fault_info;
-
-/* Dcache line 7: Physical addresses of CPU send mondo block and CPU list. */
- unsigned long cpu_mondo_block_pa;
- unsigned long cpu_list_pa;
- unsigned long tsb_huge;
- unsigned long tsb_huge_temp;
-
-/* Dcache line 8: IRQ work list, and keep trap_block a power-of-2 in size. */
- unsigned long irq_worklist_pa;
- unsigned int cpu_mondo_qmask;
- unsigned int dev_mondo_qmask;
- unsigned int resum_qmask;
- unsigned int nonresum_qmask;
- void *hdesc;
-} __attribute__((aligned(64)));
-extern struct trap_per_cpu trap_block[NR_CPUS];
-extern void init_cur_cpu_trap(struct thread_info *);
-extern void setup_tba(void);
-extern int ncpus_probed;
extern const struct seq_operations cpuinfo_op;
-extern unsigned long real_hard_smp_processor_id(void);
-
-struct cpuid_patch_entry {
- unsigned int addr;
- unsigned int cheetah_safari[4];
- unsigned int cheetah_jbus[4];
- unsigned int starfire[4];
- unsigned int sun4v[4];
-};
-extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
-
-struct sun4v_1insn_patch_entry {
- unsigned int addr;
- unsigned int insn;
-};
-extern struct sun4v_1insn_patch_entry __sun4v_1insn_patch,
- __sun4v_1insn_patch_end;
-
-struct sun4v_2insn_patch_entry {
- unsigned int addr;
- unsigned int insns[2];
-};
-extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
- __sun4v_2insn_patch_end;
-
#endif /* !(__ASSEMBLY__) */
-#define TRAP_PER_CPU_THREAD 0x00
-#define TRAP_PER_CPU_PGD_PADDR 0x08
-#define TRAP_PER_CPU_CPU_MONDO_PA 0x10
-#define TRAP_PER_CPU_DEV_MONDO_PA 0x18
-#define TRAP_PER_CPU_RESUM_MONDO_PA 0x20
-#define TRAP_PER_CPU_RESUM_KBUF_PA 0x28
-#define TRAP_PER_CPU_NONRESUM_MONDO_PA 0x30
-#define TRAP_PER_CPU_NONRESUM_KBUF_PA 0x38
-#define TRAP_PER_CPU_FAULT_INFO 0x40
-#define TRAP_PER_CPU_CPU_MONDO_BLOCK_PA 0xc0
-#define TRAP_PER_CPU_CPU_LIST_PA 0xc8
-#define TRAP_PER_CPU_TSB_HUGE 0xd0
-#define TRAP_PER_CPU_TSB_HUGE_TEMP 0xd8
-#define TRAP_PER_CPU_IRQ_WORKLIST_PA 0xe0
-#define TRAP_PER_CPU_CPU_MONDO_QMASK 0xe8
-#define TRAP_PER_CPU_DEV_MONDO_QMASK 0xec
-#define TRAP_PER_CPU_RESUM_QMASK 0xf0
-#define TRAP_PER_CPU_NONRESUM_QMASK 0xf4
-
-#define TRAP_BLOCK_SZ_SHIFT 8
-
-#include <asm/scratchpad.h>
-
-#define __GET_CPUID(REG) \
- /* Spitfire implementation (default). */ \
-661: ldxa [%g0] ASI_UPA_CONFIG, REG; \
- srlx REG, 17, REG; \
- and REG, 0x1f, REG; \
- nop; \
- .section .cpuid_patch, "ax"; \
- /* Instruction location. */ \
- .word 661b; \
- /* Cheetah Safari implementation. */ \
- ldxa [%g0] ASI_SAFARI_CONFIG, REG; \
- srlx REG, 17, REG; \
- and REG, 0x3ff, REG; \
- nop; \
- /* Cheetah JBUS implementation. */ \
- ldxa [%g0] ASI_JBUS_CONFIG, REG; \
- srlx REG, 17, REG; \
- and REG, 0x1f, REG; \
- nop; \
- /* Starfire implementation. */ \
- sethi %hi(0x1fff40000d0 >> 9), REG; \
- sllx REG, 9, REG; \
- or REG, 0xd0, REG; \
- lduwa [REG] ASI_PHYS_BYPASS_EC_E, REG;\
- /* sun4v implementation. */ \
- mov SCRATCHPAD_CPUID, REG; \
- ldxa [REG] ASI_SCRATCHPAD, REG; \
- nop; \
- nop; \
- .previous;
-
-#ifdef CONFIG_SMP
-
-#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
- __GET_CPUID(TMP) \
- sethi %hi(trap_block), DEST; \
- sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \
- or DEST, %lo(trap_block), DEST; \
- add DEST, TMP, DEST; \
-
-/* Clobbers TMP, current address space PGD phys address into DEST. */
-#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \
- TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
- ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
-
-/* Clobbers TMP, loads local processor's IRQ work area into DEST. */
-#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP) \
- TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
- add DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
-
-/* Clobbers TMP, loads DEST with current thread info pointer. */
-#define TRAP_LOAD_THREAD_REG(DEST, TMP) \
- TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
- ldx [DEST + TRAP_PER_CPU_THREAD], DEST;
-
-/* Given the current thread info pointer in THR, load the per-cpu
- * area base of the current processor into DEST. REG1, REG2, and REG3 are
- * clobbered.
- *
- * You absolutely cannot use DEST as a temporary in this code. The
- * reason is that traps can happen during execution, and return from
- * trap will load the fully resolved DEST per-cpu base. This can corrupt
- * the calculations done by the macro mid-stream.
- */
-#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) \
- lduh [THR + TI_CPU], REG1; \
- sethi %hi(__per_cpu_shift), REG3; \
- sethi %hi(__per_cpu_base), REG2; \
- ldx [REG3 + %lo(__per_cpu_shift)], REG3; \
- ldx [REG2 + %lo(__per_cpu_base)], REG2; \
- sllx REG1, REG3, REG3; \
- add REG3, REG2, DEST;
-
-#else
-
-#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
- sethi %hi(trap_block), DEST; \
- or DEST, %lo(trap_block), DEST; \
-
-/* Uniprocessor versions, we know the cpuid is zero. */
-#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \
- TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
- ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
-
-/* Clobbers TMP, loads local processor's IRQ work area into DEST. */
-#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP) \
- TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
- add DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
-
-#define TRAP_LOAD_THREAD_REG(DEST, TMP) \
- TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
- ldx [DEST + TRAP_PER_CPU_THREAD], DEST;
-
-/* No per-cpu areas on uniprocessor, so no need to load DEST. */
-#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3)
-
-#endif /* !(CONFIG_SMP) */
+#include <asm/trap_block.h>
#endif /* _SPARC64_CPUDATA_H */
diff --git a/arch/sparc/include/asm/mdesc.h b/arch/sparc/include/asm/mdesc.h
index 1acc7272e537..9faa046713fb 100644
--- a/arch/sparc/include/asm/mdesc.h
+++ b/arch/sparc/include/asm/mdesc.h
@@ -71,7 +71,8 @@ struct mdesc_notifier_client {
extern void mdesc_register_notifier(struct mdesc_notifier_client *client);
-extern void mdesc_fill_in_cpu_data(cpumask_t mask);
+extern void mdesc_fill_in_cpu_data(cpumask_t *mask);
+extern void mdesc_populate_present_mask(cpumask_t *mask);
extern void sun4v_mdesc_init(void);
diff --git a/arch/sparc/include/asm/percpu_64.h b/arch/sparc/include/asm/percpu_64.h
index bee64593023e..007aafb4ae97 100644
--- a/arch/sparc/include/asm/percpu_64.h
+++ b/arch/sparc/include/asm/percpu_64.h
@@ -7,20 +7,16 @@ register unsigned long __local_per_cpu_offset asm("g5");
#ifdef CONFIG_SMP
-extern void real_setup_per_cpu_areas(void);
+#include <asm/trap_block.h>
-extern unsigned long __per_cpu_base;
-extern unsigned long __per_cpu_shift;
#define __per_cpu_offset(__cpu) \
- (__per_cpu_base + ((unsigned long)(__cpu) << __per_cpu_shift))
+ (trap_block[(__cpu)].__per_cpu_base)
#define per_cpu_offset(x) (__per_cpu_offset(x))
#define __my_cpu_offset __local_per_cpu_offset
#else /* ! SMP */
-#define real_setup_per_cpu_areas() do { } while (0)
-
#endif /* SMP */
#include <asm-generic/percpu.h>
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index 900d44714f8d..be8d7aaeb60d 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -86,6 +86,8 @@ extern int of_node_to_nid(struct device_node *dp);
#endif
extern void prom_build_devicetree(void);
+extern void of_populate_present_mask(void);
+extern void of_fill_in_cpu_data(void);
/* Dummy ref counting routines - to be implemented later */
static inline struct device_node *of_node_get(struct device_node *node)
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 639ac805448a..65865726b283 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -102,8 +102,8 @@ struct thread_info {
#define TI_KERN_CNTD1 0x00000488
#define TI_PCR 0x00000490
#define TI_RESTART_BLOCK 0x00000498
-#define TI_KUNA_REGS 0x000004c0
-#define TI_KUNA_INSN 0x000004c8
+#define TI_KUNA_REGS 0x000004c8
+#define TI_KUNA_INSN 0x000004d0
#define TI_FPREGS 0x00000500
/* We embed this in the uppermost byte of thread_info->flags */
diff --git a/arch/sparc/include/asm/trap_block.h b/arch/sparc/include/asm/trap_block.h
new file mode 100644
index 000000000000..7e26b2db6211
--- /dev/null
+++ b/arch/sparc/include/asm/trap_block.h
@@ -0,0 +1,207 @@
+#ifndef _SPARC_TRAP_BLOCK_H
+#define _SPARC_TRAP_BLOCK_H
+
+#include <asm/hypervisor.h>
+#include <asm/asi.h>
+
+#ifndef __ASSEMBLY__
+
+/* Trap handling code needs to get at a few critical values upon
+ * trap entry and to process TSB misses. These cannot be in the
+ * per_cpu() area as we really need to lock them into the TLB and
+ * thus make them part of the main kernel image. As a result we
+ * try to make this as small as possible.
+ *
+ * This is padded out and aligned to 64-bytes to avoid false sharing
+ * on SMP.
+ */
+
+/* If you modify the size of this structure, please update
+ * TRAP_BLOCK_SZ_SHIFT below.
+ */
+struct thread_info;
+struct trap_per_cpu {
+/* D-cache line 1: Basic thread information, cpu and device mondo queues */
+ struct thread_info *thread;
+ unsigned long pgd_paddr;
+ unsigned long cpu_mondo_pa;
+ unsigned long dev_mondo_pa;
+
+/* D-cache line 2: Error Mondo Queue and kernel buffer pointers */
+ unsigned long resum_mondo_pa;
+ unsigned long resum_kernel_buf_pa;
+ unsigned long nonresum_mondo_pa;
+ unsigned long nonresum_kernel_buf_pa;
+
+/* Dcache lines 3, 4, 5, and 6: Hypervisor Fault Status */
+ struct hv_fault_status fault_info;
+
+/* Dcache line 7: Physical addresses of CPU send mondo block and CPU list. */
+ unsigned long cpu_mondo_block_pa;
+ unsigned long cpu_list_pa;
+ unsigned long tsb_huge;
+ unsigned long tsb_huge_temp;
+
+/* Dcache line 8: IRQ work list, and keep trap_block a power-of-2 in size. */
+ unsigned long irq_worklist_pa;
+ unsigned int cpu_mondo_qmask;
+ unsigned int dev_mondo_qmask;
+ unsigned int resum_qmask;
+ unsigned int nonresum_qmask;
+ unsigned long __per_cpu_base;
+} __attribute__((aligned(64)));
+extern struct trap_per_cpu trap_block[NR_CPUS];
+extern void init_cur_cpu_trap(struct thread_info *);
+extern void setup_tba(void);
+extern int ncpus_probed;
+
+extern unsigned long real_hard_smp_processor_id(void);
+
+struct cpuid_patch_entry {
+ unsigned int addr;
+ unsigned int cheetah_safari[4];
+ unsigned int cheetah_jbus[4];
+ unsigned int starfire[4];
+ unsigned int sun4v[4];
+};
+extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
+
+struct sun4v_1insn_patch_entry {
+ unsigned int addr;
+ unsigned int insn;
+};
+extern struct sun4v_1insn_patch_entry __sun4v_1insn_patch,
+ __sun4v_1insn_patch_end;
+
+struct sun4v_2insn_patch_entry {
+ unsigned int addr;
+ unsigned int insns[2];
+};
+extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
+ __sun4v_2insn_patch_end;
+
+
+#endif /* !(__ASSEMBLY__) */
+
+#define TRAP_PER_CPU_THREAD 0x00
+#define TRAP_PER_CPU_PGD_PADDR 0x08
+#define TRAP_PER_CPU_CPU_MONDO_PA 0x10
+#define TRAP_PER_CPU_DEV_MONDO_PA 0x18
+#define TRAP_PER_CPU_RESUM_MONDO_PA 0x20
+#define TRAP_PER_CPU_RESUM_KBUF_PA 0x28
+#define TRAP_PER_CPU_NONRESUM_MONDO_PA 0x30
+#define TRAP_PER_CPU_NONRESUM_KBUF_PA 0x38
+#define TRAP_PER_CPU_FAULT_INFO 0x40
+#define TRAP_PER_CPU_CPU_MONDO_BLOCK_PA 0xc0
+#define TRAP_PER_CPU_CPU_LIST_PA 0xc8
+#define TRAP_PER_CPU_TSB_HUGE 0xd0
+#define TRAP_PER_CPU_TSB_HUGE_TEMP 0xd8
+#define TRAP_PER_CPU_IRQ_WORKLIST_PA 0xe0
+#define TRAP_PER_CPU_CPU_MONDO_QMASK 0xe8
+#define TRAP_PER_CPU_DEV_MONDO_QMASK 0xec
+#define TRAP_PER_CPU_RESUM_QMASK 0xf0
+#define TRAP_PER_CPU_NONRESUM_QMASK 0xf4
+#define TRAP_PER_CPU_PER_CPU_BASE 0xf8
+
+#define TRAP_BLOCK_SZ_SHIFT 8
+
+#include <asm/scratchpad.h>
+
+#define __GET_CPUID(REG) \
+ /* Spitfire implementation (default). */ \
+661: ldxa [%g0] ASI_UPA_CONFIG, REG; \
+ srlx REG, 17, REG; \
+ and REG, 0x1f, REG; \
+ nop; \
+ .section .cpuid_patch, "ax"; \
+ /* Instruction location. */ \
+ .word 661b; \
+ /* Cheetah Safari implementation. */ \
+ ldxa [%g0] ASI_SAFARI_CONFIG, REG; \
+ srlx REG, 17, REG; \
+ and REG, 0x3ff, REG; \
+ nop; \
+ /* Cheetah JBUS implementation. */ \
+ ldxa [%g0] ASI_JBUS_CONFIG, REG; \
+ srlx REG, 17, REG; \
+ and REG, 0x1f, REG; \
+ nop; \
+ /* Starfire implementation. */ \
+ sethi %hi(0x1fff40000d0 >> 9), REG; \
+ sllx REG, 9, REG; \
+ or REG, 0xd0, REG; \
+ lduwa [REG] ASI_PHYS_BYPASS_EC_E, REG;\
+ /* sun4v implementation. */ \
+ mov SCRATCHPAD_CPUID, REG; \
+ ldxa [REG] ASI_SCRATCHPAD, REG; \
+ nop; \
+ nop; \
+ .previous;
+
+#ifdef CONFIG_SMP
+
+#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
+ __GET_CPUID(TMP) \
+ sethi %hi(trap_block), DEST; \
+ sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \
+ or DEST, %lo(trap_block), DEST; \
+ add DEST, TMP, DEST; \
+
+/* Clobbers TMP, current address space PGD phys address into DEST. */
+#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \
+ TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
+ ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
+
+/* Clobbers TMP, loads local processor's IRQ work area into DEST. */
+#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP) \
+ TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
+ add DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
+
+/* Clobbers TMP, loads DEST with current thread info pointer. */
+#define TRAP_LOAD_THREAD_REG(DEST, TMP) \
+ TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
+ ldx [DEST + TRAP_PER_CPU_THREAD], DEST;
+
+/* Given the current thread info pointer in THR, load the per-cpu
+ * area base of the current processor into DEST. REG1, REG2, and REG3 are
+ * clobbered.
+ *
+ * You absolutely cannot use DEST as a temporary in this code. The
+ * reason is that traps can happen during execution, and return from
+ * trap will load the fully resolved DEST per-cpu base. This can corrupt
+ * the calculations done by the macro mid-stream.
+ */
+#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) \
+ lduh [THR + TI_CPU], REG1; \
+ sethi %hi(trap_block), REG2; \
+ sllx REG1, TRAP_BLOCK_SZ_SHIFT, REG1; \
+ or REG2, %lo(trap_block), REG2; \
+ add REG2, REG1, REG2; \
+ ldx [REG2 + TRAP_PER_CPU_PER_CPU_BASE], DEST;
+
+#else
+
+#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
+ sethi %hi(trap_block), DEST; \
+ or DEST, %lo(trap_block), DEST; \
+
+/* Uniprocessor versions, we know the cpuid is zero. */
+#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \
+ TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
+ ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
+
+/* Clobbers TMP, loads local processor's IRQ work area into DEST. */
+#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP) \
+ TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
+ add DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
+
+#define TRAP_LOAD_THREAD_REG(DEST, TMP) \
+ TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
+ ldx [DEST + TRAP_PER_CPU_THREAD], DEST;
+
+/* No per-cpu areas on uniprocessor, so no need to load DEST. */
+#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3)
+
+#endif /* !(CONFIG_SMP) */
+
+#endif /* _SPARC_TRAP_BLOCK_H */
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index 90350f838f05..4a700f4b79ce 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -544,7 +544,8 @@ static int __cpuinit dr_cpu_configure(struct ds_info *dp,
resp_len, ncpus, mask,
DR_CPU_STAT_CONFIGURED);
- mdesc_fill_in_cpu_data(*mask);
+ mdesc_populate_present_mask(mask);
+ mdesc_fill_in_cpu_data(mask);
for_each_cpu_mask(cpu, *mask) {
int err;
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index 91bf4c7f79b9..f8f21050448b 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -641,28 +641,6 @@ tlb_fixup_done:
/* Not reached... */
1:
- /* If we boot on a non-zero cpu, all of the per-cpu
- * variable references we make before setting up the
- * per-cpu areas will use a bogus offset. Put a
- * compensating factor into __per_cpu_base to handle
- * this cleanly.
- *
- * What the per-cpu code calculates is:
- *
- * __per_cpu_base + (cpu << __per_cpu_shift)
- *
- * These two variables are zero initially, so to
- * make it all cancel out to zero we need to put
- * "0 - (cpu << 0)" into __per_cpu_base so that the
- * above formula evaluates to zero.
- *
- * We cannot even perform a printk() until this stuff
- * is setup as that calls cpu_clock() which uses
- * per-cpu variables.
- */
- sub %g0, %o0, %o1
- sethi %hi(__per_cpu_base), %o2
- stx %o1, [%o2 + %lo(__per_cpu_base)]
#else
mov 0, %o0
#endif
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 5deabe921a47..e5e78f9cfc95 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -318,10 +318,12 @@ static void sun4u_irq_enable(unsigned int virt_irq)
}
}
-static void sun4u_set_affinity(unsigned int virt_irq,
+static int sun4u_set_affinity(unsigned int virt_irq,
const struct cpumask *mask)
{
sun4u_irq_enable(virt_irq);
+
+ return 0;
}
/* Don't do anything. The desc->status check for IRQ_DISABLED in
@@ -377,7 +379,7 @@ static void sun4v_irq_enable(unsigned int virt_irq)
ino, err);
}
-static void sun4v_set_affinity(unsigned int virt_irq,
+static int sun4v_set_affinity(unsigned int virt_irq,
const struct cpumask *mask)
{
unsigned int ino = virt_irq_table[virt_irq].dev_ino;
@@ -388,6 +390,8 @@ static void sun4v_set_affinity(unsigned int virt_irq,
if (err != HV_EOK)
printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
"err(%d)\n", ino, cpuid, err);
+
+ return 0;
}
static void sun4v_irq_disable(unsigned int virt_irq)
@@ -445,7 +449,7 @@ static void sun4v_virq_enable(unsigned int virt_irq)
dev_handle, dev_ino, err);
}
-static void sun4v_virt_set_affinity(unsigned int virt_irq,
+static int sun4v_virt_set_affinity(unsigned int virt_irq,
const struct cpumask *mask)
{
unsigned long cpuid, dev_handle, dev_ino;
@@ -461,6 +465,8 @@ static void sun4v_virt_set_affinity(unsigned int virt_irq,
printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
"err(%d)\n",
dev_handle, dev_ino, cpuid, err);
+
+ return 0;
}
static void sun4v_virq_disable(unsigned int virt_irq)
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index f0e6ed23a468..938da19dc065 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -574,7 +574,7 @@ static void __init report_platform_properties(void)
mdesc_release(hp);
}
-static void __devinit fill_in_one_cache(cpuinfo_sparc *c,
+static void __cpuinit fill_in_one_cache(cpuinfo_sparc *c,
struct mdesc_handle *hp,
u64 mp)
{
@@ -619,8 +619,7 @@ static void __devinit fill_in_one_cache(cpuinfo_sparc *c,
}
}
-static void __devinit mark_core_ids(struct mdesc_handle *hp, u64 mp,
- int core_id)
+static void __cpuinit mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id)
{
u64 a;
@@ -653,7 +652,7 @@ static void __devinit mark_core_ids(struct mdesc_handle *hp, u64 mp,
}
}
-static void __devinit set_core_ids(struct mdesc_handle *hp)
+static void __cpuinit set_core_ids(struct mdesc_handle *hp)
{
int idx;
u64 mp;
@@ -678,8 +677,7 @@ static void __devinit set_core_ids(struct mdesc_handle *hp)
}
}
-static void __devinit mark_proc_ids(struct mdesc_handle *hp, u64 mp,
- int proc_id)
+static void __cpuinit mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
{
u64 a;
@@ -698,8 +696,7 @@ static void __devinit mark_proc_ids(struct mdesc_handle *hp, u64 mp,
}
}
-static void __devinit __set_proc_ids(struct mdesc_handle *hp,
- const char *exec_unit_name)
+static void __cpuinit __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
{
int idx;
u64 mp;
@@ -720,13 +717,13 @@ static void __devinit __set_proc_ids(struct mdesc_handle *hp,
}
}
-static void __devinit set_proc_ids(struct mdesc_handle *hp)
+static void __cpuinit set_proc_ids(struct mdesc_handle *hp)
{
__set_proc_ids(hp, "exec_unit");
__set_proc_ids(hp, "exec-unit");
}
-static void __devinit get_one_mondo_bits(const u64 *p, unsigned int *mask,
+static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask,
unsigned char def)
{
u64 val;
@@ -745,7 +742,7 @@ use_default:
*mask = ((1U << def) * 64U) - 1U;
}
-static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp,
+static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp,
struct trap_per_cpu *tb)
{
const u64 *val;
@@ -763,23 +760,15 @@ static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp,
get_one_mondo_bits(val, &tb->nonresum_qmask, 2);
}
-void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask)
+static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask)
{
struct mdesc_handle *hp = mdesc_grab();
+ void *ret = NULL;
u64 mp;
- ncpus_probed = 0;
mdesc_for_each_node_by_name(hp, mp, "cpu") {
const u64 *id = mdesc_get_property(hp, mp, "id", NULL);
- const u64 *cfreq = mdesc_get_property(hp, mp, "clock-frequency", NULL);
- struct trap_per_cpu *tb;
- cpuinfo_sparc *c;
- int cpuid;
- u64 a;
-
- ncpus_probed++;
-
- cpuid = *id;
+ int cpuid = *id;
#ifdef CONFIG_SMP
if (cpuid >= NR_CPUS) {
@@ -788,62 +777,104 @@ void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask)
cpuid, NR_CPUS);
continue;
}
- if (!cpu_isset(cpuid, mask))
+ if (!cpu_isset(cpuid, *mask))
continue;
-#else
- /* On uniprocessor we only want the values for the
- * real physical cpu the kernel booted onto, however
- * cpu_data() only has one entry at index 0.
- */
- if (cpuid != real_hard_smp_processor_id())
- continue;
- cpuid = 0;
#endif
- c = &cpu_data(cpuid);
- c->clock_tick = *cfreq;
+ ret = func(hp, mp, cpuid, arg);
+ if (ret)
+ goto out;
+ }
+out:
+ mdesc_release(hp);
+ return ret;
+}
- tb = &trap_block[cpuid];
- get_mondo_data(hp, mp, tb);
+static void * __cpuinit record_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg)
+{
+ ncpus_probed++;
+#ifdef CONFIG_SMP
+ set_cpu_present(cpuid, true);
+#endif
+ return NULL;
+}
- mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
- u64 j, t = mdesc_arc_target(hp, a);
- const char *t_name;
+void __cpuinit mdesc_populate_present_mask(cpumask_t *mask)
+{
+ if (tlb_type != hypervisor)
+ return;
- t_name = mdesc_node_name(hp, t);
- if (!strcmp(t_name, "cache")) {
- fill_in_one_cache(c, hp, t);
- continue;
- }
+ ncpus_probed = 0;
+ mdesc_iterate_over_cpus(record_one_cpu, NULL, mask);
+}
- mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_FWD) {
- u64 n = mdesc_arc_target(hp, j);
- const char *n_name;
+static void * __cpuinit fill_in_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg)
+{
+ const u64 *cfreq = mdesc_get_property(hp, mp, "clock-frequency", NULL);
+ struct trap_per_cpu *tb;
+ cpuinfo_sparc *c;
+ u64 a;
- n_name = mdesc_node_name(hp, n);
- if (!strcmp(n_name, "cache"))
- fill_in_one_cache(c, hp, n);
- }
+#ifndef CONFIG_SMP
+ /* On uniprocessor we only want the values for the
+ * real physical cpu the kernel booted onto, however
+ * cpu_data() only has one entry at index 0.
+ */
+ if (cpuid != real_hard_smp_processor_id())
+ return NULL;
+ cpuid = 0;
+#endif
+
+ c = &cpu_data(cpuid);
+ c->clock_tick = *cfreq;
+
+ tb = &trap_block[cpuid];
+ get_mondo_data(hp, mp, tb);
+
+ mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
+ u64 j, t = mdesc_arc_target(hp, a);
+ const char *t_name;
+
+ t_name = mdesc_node_name(hp, t);
+ if (!strcmp(t_name, "cache")) {
+ fill_in_one_cache(c, hp, t);
+ continue;
}
-#ifdef CONFIG_SMP
- cpu_set(cpuid, cpu_present_map);
-#endif
+ mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_FWD) {
+ u64 n = mdesc_arc_target(hp, j);
+ const char *n_name;
- c->core_id = 0;
- c->proc_id = -1;
+ n_name = mdesc_node_name(hp, n);
+ if (!strcmp(n_name, "cache"))
+ fill_in_one_cache(c, hp, n);
+ }
}
+ c->core_id = 0;
+ c->proc_id = -1;
+
+ return NULL;
+}
+
+void __cpuinit mdesc_fill_in_cpu_data(cpumask_t *mask)
+{
+ struct mdesc_handle *hp;
+
+ mdesc_iterate_over_cpus(fill_in_one_cpu, NULL, mask);
+
#ifdef CONFIG_SMP
sparc64_multi_core = 1;
#endif
+ hp = mdesc_grab();
+
set_core_ids(hp);
set_proc_ids(hp);
- smp_fill_in_sib_core_maps();
-
mdesc_release(hp);
+
+ smp_fill_in_sib_core_maps();
}
static ssize_t mdesc_read(struct file *file, char __user *buf,
@@ -887,7 +918,6 @@ void __init sun4v_mdesc_init(void)
{
struct mdesc_handle *hp;
unsigned long len, real_len, status;
- cpumask_t mask;
(void) sun4v_mach_desc(0UL, 0UL, &len);
@@ -911,7 +941,4 @@ void __init sun4v_mdesc_init(void)
cur_mdesc = hp;
report_platform_properties();
-
- cpus_setall(mask);
- mdesc_fill_in_cpu_data(mask);
}
diff --git a/arch/sparc/kernel/prom.h b/arch/sparc/kernel/prom.h
index bb0f0fda6cab..453397fe5e14 100644
--- a/arch/sparc/kernel/prom.h
+++ b/arch/sparc/kernel/prom.h
@@ -22,7 +22,6 @@ static inline int is_root_node(const struct device_node *dp)
extern char *build_path_component(struct device_node *dp);
extern void of_console_init(void);
-extern void of_fill_in_cpu_data(void);
extern unsigned int prom_early_allocated;
diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c
index ca55c7012f77..f65d62385cb4 100644
--- a/arch/sparc/kernel/prom_64.c
+++ b/arch/sparc/kernel/prom_64.c
@@ -374,75 +374,26 @@ static const char *get_mid_prop(void)
return (tlb_type == spitfire ? "upa-portid" : "portid");
}
-struct device_node *of_find_node_by_cpuid(int cpuid)
-{
- struct device_node *dp;
- const char *mid_prop = get_mid_prop();
-
- for_each_node_by_type(dp, "cpu") {
- int id = of_getintprop_default(dp, mid_prop, -1);
- const char *this_mid_prop = mid_prop;
-
- if (id < 0) {
- this_mid_prop = "cpuid";
- id = of_getintprop_default(dp, this_mid_prop, -1);
- }
-
- if (id < 0) {
- prom_printf("OF: Serious problem, cpu lacks "
- "%s property", this_mid_prop);
- prom_halt();
- }
- if (cpuid == id)
- return dp;
- }
- return NULL;
-}
-
-void __init of_fill_in_cpu_data(void)
+static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, void *), void *arg)
{
struct device_node *dp;
const char *mid_prop;
- if (tlb_type == hypervisor)
- return;
-
mid_prop = get_mid_prop();
- ncpus_probed = 0;
for_each_node_by_type(dp, "cpu") {
int cpuid = of_getintprop_default(dp, mid_prop, -1);
const char *this_mid_prop = mid_prop;
- struct device_node *portid_parent;
- int portid = -1;
+ void *ret;
- portid_parent = NULL;
if (cpuid < 0) {
this_mid_prop = "cpuid";
cpuid = of_getintprop_default(dp, this_mid_prop, -1);
- if (cpuid >= 0) {
- int limit = 2;
-
- portid_parent = dp;
- while (limit--) {
- portid_parent = portid_parent->parent;
- if (!portid_parent)
- break;
- portid = of_getintprop_default(portid_parent,
- "portid", -1);
- if (portid >= 0)
- break;
- }
- }
}
-
if (cpuid < 0) {
prom_printf("OF: Serious problem, cpu lacks "
"%s property", this_mid_prop);
prom_halt();
}
-
- ncpus_probed++;
-
#ifdef CONFIG_SMP
if (cpuid >= NR_CPUS) {
printk(KERN_WARNING "Ignoring CPU %d which is "
@@ -450,79 +401,144 @@ void __init of_fill_in_cpu_data(void)
cpuid, NR_CPUS);
continue;
}
-#else
- /* On uniprocessor we only want the values for the
- * real physical cpu the kernel booted onto, however
- * cpu_data() only has one entry at index 0.
- */
- if (cpuid != real_hard_smp_processor_id())
- continue;
- cpuid = 0;
#endif
+ ret = func(dp, cpuid, arg);
+ if (ret)
+ return ret;
+ }
+ return NULL;
+}
- cpu_data(cpuid).clock_tick =
- of_getintprop_default(dp, "clock-frequency", 0);
-
- if (portid_parent) {
- cpu_data(cpuid).dcache_size =
- of_getintprop_default(dp, "l1-dcache-size",
- 16 * 1024);
- cpu_data(cpuid).dcache_line_size =
- of_getintprop_default(dp, "l1-dcache-line-size",
- 32);
- cpu_data(cpuid).icache_size =
- of_getintprop_default(dp, "l1-icache-size",
- 8 * 1024);
- cpu_data(cpuid).icache_line_size =
- of_getintprop_default(dp, "l1-icache-line-size",
- 32);
- cpu_data(cpuid).ecache_size =
- of_getintprop_default(dp, "l2-cache-size", 0);
- cpu_data(cpuid).ecache_line_size =
- of_getintprop_default(dp, "l2-cache-line-size", 0);
- if (!cpu_data(cpuid).ecache_size ||
- !cpu_data(cpuid).ecache_line_size) {
- cpu_data(cpuid).ecache_size =
- of_getintprop_default(portid_parent,
- "l2-cache-size",
- (4 * 1024 * 1024));
- cpu_data(cpuid).ecache_line_size =
- of_getintprop_default(portid_parent,
- "l2-cache-line-size", 64);
- }
-
- cpu_data(cpuid).core_id = portid + 1;
- cpu_data(cpuid).proc_id = portid;
+static void *check_cpu_node(struct device_node *dp, int cpuid, void *arg)
+{
+ int id = (int) (long) arg;
+
+ if (id == cpuid)
+ return dp;
+ return NULL;
+}
+
+struct device_node *of_find_node_by_cpuid(int cpuid)
+{
+ return of_iterate_over_cpus(check_cpu_node, (void *) (long) cpuid);
+}
+
+static void *record_one_cpu(struct device_node *dp, int cpuid, void *arg)
+{
+ ncpus_probed++;
#ifdef CONFIG_SMP
- sparc64_multi_core = 1;
+ set_cpu_present(cpuid, true);
+ set_cpu_possible(cpuid, true);
#endif
- } else {
- cpu_data(cpuid).dcache_size =
- of_getintprop_default(dp, "dcache-size", 16 * 1024);
- cpu_data(cpuid).dcache_line_size =
- of_getintprop_default(dp, "dcache-line-size", 32);
+ return NULL;
+}
+
+void __init of_populate_present_mask(void)
+{
+ if (tlb_type == hypervisor)
+ return;
+
+ ncpus_probed = 0;
+ of_iterate_over_cpus(record_one_cpu, NULL);
+}
- cpu_data(cpuid).icache_size =
- of_getintprop_default(dp, "icache-size", 16 * 1024);
- cpu_data(cpuid).icache_line_size =
- of_getintprop_default(dp, "icache-line-size", 32);
+static void *fill_in_one_cpu(struct device_node *dp, int cpuid, void *arg)
+{
+ struct device_node *portid_parent = NULL;
+ int portid = -1;
+
+ if (of_find_property(dp, "cpuid", NULL)) {
+ int limit = 2;
+
+ portid_parent = dp;
+ while (limit--) {
+ portid_parent = portid_parent->parent;
+ if (!portid_parent)
+ break;
+ portid = of_getintprop_default(portid_parent,
+ "portid", -1);
+ if (portid >= 0)
+ break;
+ }
+ }
+#ifndef CONFIG_SMP
+ /* On uniprocessor we only want the values for the
+ * real physical cpu the kernel booted onto, however
+ * cpu_data() only has one entry at index 0.
+ */
+ if (cpuid != real_hard_smp_processor_id())
+ return NULL;
+ cpuid = 0;
+#endif
+
+ cpu_data(cpuid).clock_tick =
+ of_getintprop_default(dp, "clock-frequency", 0);
+
+ if (portid_parent) {
+ cpu_data(cpuid).dcache_size =
+ of_getintprop_default(dp, "l1-dcache-size",
+ 16 * 1024);
+ cpu_data(cpuid).dcache_line_size =
+ of_getintprop_default(dp, "l1-dcache-line-size",
+ 32);
+ cpu_data(cpuid).icache_size =
+ of_getintprop_default(dp, "l1-icache-size",
+ 8 * 1024);
+ cpu_data(cpuid).icache_line_size =
+ of_getintprop_default(dp, "l1-icache-line-size",
+ 32);
+ cpu_data(cpuid).ecache_size =
+ of_getintprop_default(dp, "l2-cache-size", 0);
+ cpu_data(cpuid).ecache_line_size =
+ of_getintprop_default(dp, "l2-cache-line-size", 0);
+ if (!cpu_data(cpuid).ecache_size ||
+ !cpu_data(cpuid).ecache_line_size) {
cpu_data(cpuid).ecache_size =
- of_getintprop_default(dp, "ecache-size",
+ of_getintprop_default(portid_parent,
+ "l2-cache-size",
(4 * 1024 * 1024));
cpu_data(cpuid).ecache_line_size =
- of_getintprop_default(dp, "ecache-line-size", 64);
-
- cpu_data(cpuid).core_id = 0;
- cpu_data(cpuid).proc_id = -1;
+ of_getintprop_default(portid_parent,
+ "l2-cache-line-size", 64);
}
+ cpu_data(cpuid).core_id = portid + 1;
+ cpu_data(cpuid).proc_id = portid;
#ifdef CONFIG_SMP
- set_cpu_present(cpuid, true);
- set_cpu_possible(cpuid, true);
+ sparc64_multi_core = 1;
#endif
+ } else {
+ cpu_data(cpuid).dcache_size =
+ of_getintprop_default(dp, "dcache-size", 16 * 1024);
+ cpu_data(cpuid).dcache_line_size =
+ of_getintprop_default(dp, "dcache-line-size", 32);
+
+ cpu_data(cpuid).icache_size =
+ of_getintprop_default(dp, "icache-size", 16 * 1024);
+ cpu_data(cpuid).icache_line_size =
+ of_getintprop_default(dp, "icache-line-size", 32);
+
+ cpu_data(cpuid).ecache_size =
+ of_getintprop_default(dp, "ecache-size",
+ (4 * 1024 * 1024));
+ cpu_data(cpuid).ecache_line_size =
+ of_getintprop_default(dp, "ecache-line-size", 64);
+
+ cpu_data(cpuid).core_id = 0;
+ cpu_data(cpuid).proc_id = -1;
}
+ return NULL;
+}
+
+void __init of_fill_in_cpu_data(void)
+{
+ if (tlb_type == hypervisor)
+ return;
+
+ of_iterate_over_cpus(fill_in_one_cpu, NULL);
+
smp_fill_in_sib_core_maps();
}
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index ff7b591c8946..0fb5789d43c8 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -313,6 +313,4 @@ void __init prom_build_devicetree(void)
printk("PROM: Built device tree with %u bytes of memory.\n",
prom_early_allocated);
-
- of_fill_in_cpu_data();
}
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index f7642e5a94db..1de47d2169c8 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -20,7 +20,8 @@
#include <linux/cache.h>
#include <linux/jiffies.h>
#include <linux/profile.h>
-#include <linux/lmb.h>
+#include <linux/bootmem.h>
+#include <linux/vmalloc.h>
#include <linux/cpu.h>
#include <asm/head.h>
@@ -278,7 +279,7 @@ static unsigned long kimage_addr_to_ra(void *p)
return kern_base + (val - KERNBASE);
}
-static void __cpuinit ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg)
+static void __cpuinit ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg, void **descrp)
{
extern unsigned long sparc64_ttable_tl0;
extern unsigned long kern_locked_tte_data;
@@ -298,12 +299,12 @@ static void __cpuinit ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread
"hvtramp_descr.\n");
return;
}
+ *descrp = hdesc;
hdesc->cpu = cpu;
hdesc->num_mappings = num_kernel_image_mappings;
tb = &trap_block[cpu];
- tb->hdesc = hdesc;
hdesc->fault_info_va = (unsigned long) &tb->fault_info;
hdesc->fault_info_pa = kimage_addr_to_ra(&tb->fault_info);
@@ -341,12 +342,12 @@ static struct thread_info *cpu_new_thread = NULL;
static int __cpuinit smp_boot_one_cpu(unsigned int cpu)
{
- struct trap_per_cpu *tb = &trap_block[cpu];
unsigned long entry =
(unsigned long)(&sparc64_cpu_startup);
unsigned long cookie =
(unsigned long)(&cpu_new_thread);
struct task_struct *p;
+ void *descr = NULL;
int timeout, ret;
p = fork_idle(cpu);
@@ -359,7 +360,8 @@ static int __cpuinit smp_boot_one_cpu(unsigned int cpu)
#if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU)
if (ldom_domaining_enabled)
ldom_startcpu_cpuid(cpu,
- (unsigned long) cpu_new_thread);
+ (unsigned long) cpu_new_thread,
+ &descr);
else
#endif
prom_startcpu_cpuid(cpu, entry, cookie);
@@ -383,10 +385,7 @@ static int __cpuinit smp_boot_one_cpu(unsigned int cpu)
}
cpu_new_thread = NULL;
- if (tb->hdesc) {
- kfree(tb->hdesc);
- tb->hdesc = NULL;
- }
+ kfree(descr);
return ret;
}
@@ -1373,36 +1372,171 @@ void smp_send_stop(void)
{
}
-unsigned long __per_cpu_base __read_mostly;
-unsigned long __per_cpu_shift __read_mostly;
+/**
+ * pcpu_alloc_bootmem - NUMA friendly alloc_bootmem wrapper for percpu
+ * @cpu: cpu to allocate for
+ * @size: size allocation in bytes
+ * @align: alignment
+ *
+ * Allocate @size bytes aligned at @align for cpu @cpu. This wrapper
+ * does the right thing for NUMA regardless of the current
+ * configuration.
+ *
+ * RETURNS:
+ * Pointer to the allocated area on success, NULL on failure.
+ */
+static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size,
+ unsigned long align)
+{
+ const unsigned long goal = __pa(MAX_DMA_ADDRESS);
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+ int node = cpu_to_node(cpu);
+ void *ptr;
+
+ if (!node_online(node) || !NODE_DATA(node)) {
+ ptr = __alloc_bootmem(size, align, goal);
+ pr_info("cpu %d has no node %d or node-local memory\n",
+ cpu, node);
+ pr_debug("per cpu data for cpu%d %lu bytes at %016lx\n",
+ cpu, size, __pa(ptr));
+ } else {
+ ptr = __alloc_bootmem_node(NODE_DATA(node),
+ size, align, goal);
+ pr_debug("per cpu data for cpu%d %lu bytes on node%d at "
+ "%016lx\n", cpu, size, node, __pa(ptr));
+ }
+ return ptr;
+#else
+ return __alloc_bootmem(size, align, goal);
+#endif
+}
+
+static size_t pcpur_size __initdata;
+static void **pcpur_ptrs __initdata;
-EXPORT_SYMBOL(__per_cpu_base);
-EXPORT_SYMBOL(__per_cpu_shift);
+static struct page * __init pcpur_get_page(unsigned int cpu, int pageno)
+{
+ size_t off = (size_t)pageno << PAGE_SHIFT;
+
+ if (off >= pcpur_size)
+ return NULL;
+
+ return virt_to_page(pcpur_ptrs[cpu] + off);
+}
+
+#define PCPU_CHUNK_SIZE (4UL * 1024UL * 1024UL)
-void __init real_setup_per_cpu_areas(void)
+static void __init pcpu_map_range(unsigned long start, unsigned long end,
+ struct page *page)
{
- unsigned long paddr, goal, size, i;
- char *ptr;
+ unsigned long pfn = page_to_pfn(page);
+ unsigned long pte_base;
+
+ BUG_ON((pfn<<PAGE_SHIFT)&(PCPU_CHUNK_SIZE - 1UL));
- /* Copy section for each CPU (we discard the original) */
- goal = PERCPU_ENOUGH_ROOM;
+ 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);
+
+ while (start < end) {
+ pgd_t *pgd = pgd_offset_k(start);
+ unsigned long this_end;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ pud = pud_offset(pgd, start);
+ if (pud_none(*pud)) {
+ pmd_t *new;
+
+ new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+ pud_populate(&init_mm, pud, new);
+ }
+
+ pmd = pmd_offset(pud, start);
+ if (!pmd_present(*pmd)) {
+ pte_t *new;
+
+ new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+ pmd_populate_kernel(&init_mm, pmd, new);
+ }
- __per_cpu_shift = PAGE_SHIFT;
- for (size = PAGE_SIZE; size < goal; size <<= 1UL)
- __per_cpu_shift++;
+ pte = pte_offset_kernel(pmd, start);
+ this_end = (start + PMD_SIZE) & PMD_MASK;
+ if (this_end > end)
+ this_end = end;
- paddr = lmb_alloc(size * NR_CPUS, PAGE_SIZE);
- if (!paddr) {
- prom_printf("Cannot allocate per-cpu memory.\n");
- prom_halt();
+ while (start < this_end) {
+ unsigned long paddr = pfn << PAGE_SHIFT;
+
+ pte_val(*pte) = (paddr | pte_base);
+
+ start += PAGE_SIZE;
+ pte++;
+ pfn++;
+ }
}
+}
+
+void __init setup_per_cpu_areas(void)
+{
+ size_t dyn_size, static_size = __per_cpu_end - __per_cpu_start;
+ static struct vm_struct vm;
+ unsigned long delta, cpu;
+ size_t pcpu_unit_size;
+ size_t ptrs_size;
- ptr = __va(paddr);
- __per_cpu_base = ptr - __per_cpu_start;
+ pcpur_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE +
+ PERCPU_DYNAMIC_RESERVE);
+ dyn_size = pcpur_size - static_size - PERCPU_MODULE_RESERVE;
- for (i = 0; i < NR_CPUS; i++, ptr += size)
- memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+
+ ptrs_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpur_ptrs[0]));
+ pcpur_ptrs = alloc_bootmem(ptrs_size);
+
+ for_each_possible_cpu(cpu) {
+ pcpur_ptrs[cpu] = pcpu_alloc_bootmem(cpu, PCPU_CHUNK_SIZE,
+ PCPU_CHUNK_SIZE);
+
+ free_bootmem(__pa(pcpur_ptrs[cpu] + pcpur_size),
+ PCPU_CHUNK_SIZE - pcpur_size);
+
+ memcpy(pcpur_ptrs[cpu], __per_cpu_load, static_size);
+ }
+
+ /* allocate address and map */
+ vm.flags = VM_ALLOC;
+ vm.size = num_possible_cpus() * PCPU_CHUNK_SIZE;
+ vm_area_register_early(&vm, PCPU_CHUNK_SIZE);
+
+ for_each_possible_cpu(cpu) {
+ unsigned long start = (unsigned long) vm.addr;
+ unsigned long end;
+
+ start += cpu * PCPU_CHUNK_SIZE;
+ end = start + PCPU_CHUNK_SIZE;
+ pcpu_map_range(start, end, virt_to_page(pcpur_ptrs[cpu]));
+ }
+
+ pcpu_unit_size = pcpu_setup_first_chunk(pcpur_get_page, static_size,
+ PERCPU_MODULE_RESERVE, dyn_size,
+ PCPU_CHUNK_SIZE, vm.addr, NULL);
+
+ free_bootmem(__pa(pcpur_ptrs), ptrs_size);
+
+ delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
+ for_each_possible_cpu(cpu) {
+ __per_cpu_offset(cpu) = delta + cpu * pcpu_unit_size;
+ }
/* Setup %g5 for the boot cpu. */
__local_per_cpu_offset = __per_cpu_offset(smp_processor_id());
+
+ of_fill_in_cpu_data();
+ if (tlb_type == hypervisor)
+ mdesc_fill_in_cpu_data(CPU_MASK_ALL_PTR);
}
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index d809c4ebb48f..10f7bb9fc140 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2509,6 +2509,7 @@ void do_getpsr(struct pt_regs *regs)
}
struct trap_per_cpu trap_block[NR_CPUS];
+EXPORT_SYMBOL(trap_block);
/* This can get invoked before sched_init() so play it super safe
* and use hard_smp_processor_id().
@@ -2530,84 +2531,97 @@ extern void tsb_config_offsets_are_bolixed_dave(void);
void __init trap_init(void)
{
/* Compile time sanity check. */
- if (TI_TASK != offsetof(struct thread_info, task) ||
- TI_FLAGS != offsetof(struct thread_info, flags) ||
- TI_CPU != offsetof(struct thread_info, cpu) ||
- TI_FPSAVED != offsetof(struct thread_info, fpsaved) ||
- TI_KSP != offsetof(struct thread_info, ksp) ||
- TI_FAULT_ADDR != offsetof(struct thread_info, fault_address) ||
- TI_KREGS != offsetof(struct thread_info, kregs) ||
- TI_UTRAPS != offsetof(struct thread_info, utraps) ||
- TI_EXEC_DOMAIN != offsetof(struct thread_info, exec_domain) ||
- TI_REG_WINDOW != offsetof(struct thread_info, reg_window) ||
- TI_RWIN_SPTRS != offsetof(struct thread_info, rwbuf_stkptrs) ||
- TI_GSR != offsetof(struct thread_info, gsr) ||
- TI_XFSR != offsetof(struct thread_info, xfsr) ||
- TI_USER_CNTD0 != offsetof(struct thread_info, user_cntd0) ||
- TI_USER_CNTD1 != offsetof(struct thread_info, user_cntd1) ||
- TI_KERN_CNTD0 != offsetof(struct thread_info, kernel_cntd0) ||
- TI_KERN_CNTD1 != offsetof(struct thread_info, kernel_cntd1) ||
- TI_PCR != offsetof(struct thread_info, pcr_reg) ||
- TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) ||
- TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
- TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) ||
- TI_RESTART_BLOCK != offsetof(struct thread_info, restart_block) ||
- TI_KUNA_REGS != offsetof(struct thread_info, kern_una_regs) ||
- TI_KUNA_INSN != offsetof(struct thread_info, kern_una_insn) ||
- TI_FPREGS != offsetof(struct thread_info, fpregs) ||
- (TI_FPREGS & (64 - 1)))
- thread_info_offsets_are_bolixed_dave();
-
- if (TRAP_PER_CPU_THREAD != offsetof(struct trap_per_cpu, thread) ||
- (TRAP_PER_CPU_PGD_PADDR !=
- offsetof(struct trap_per_cpu, pgd_paddr)) ||
- (TRAP_PER_CPU_CPU_MONDO_PA !=
- offsetof(struct trap_per_cpu, cpu_mondo_pa)) ||
- (TRAP_PER_CPU_DEV_MONDO_PA !=
- offsetof(struct trap_per_cpu, dev_mondo_pa)) ||
- (TRAP_PER_CPU_RESUM_MONDO_PA !=
- offsetof(struct trap_per_cpu, resum_mondo_pa)) ||
- (TRAP_PER_CPU_RESUM_KBUF_PA !=
- offsetof(struct trap_per_cpu, resum_kernel_buf_pa)) ||
- (TRAP_PER_CPU_NONRESUM_MONDO_PA !=
- offsetof(struct trap_per_cpu, nonresum_mondo_pa)) ||
- (TRAP_PER_CPU_NONRESUM_KBUF_PA !=
- offsetof(struct trap_per_cpu, nonresum_kernel_buf_pa)) ||
- (TRAP_PER_CPU_FAULT_INFO !=
- offsetof(struct trap_per_cpu, fault_info)) ||
- (TRAP_PER_CPU_CPU_MONDO_BLOCK_PA !=
- offsetof(struct trap_per_cpu, cpu_mondo_block_pa)) ||
- (TRAP_PER_CPU_CPU_LIST_PA !=
- offsetof(struct trap_per_cpu, cpu_list_pa)) ||
- (TRAP_PER_CPU_TSB_HUGE !=
- offsetof(struct trap_per_cpu, tsb_huge)) ||
- (TRAP_PER_CPU_TSB_HUGE_TEMP !=
- offsetof(struct trap_per_cpu, tsb_huge_temp)) ||
- (TRAP_PER_CPU_IRQ_WORKLIST_PA !=
- offsetof(struct trap_per_cpu, irq_worklist_pa)) ||
- (TRAP_PER_CPU_CPU_MONDO_QMASK !=
- offsetof(struct trap_per_cpu, cpu_mondo_qmask)) ||
- (TRAP_PER_CPU_DEV_MONDO_QMASK !=
- offsetof(struct trap_per_cpu, dev_mondo_qmask)) ||
- (TRAP_PER_CPU_RESUM_QMASK !=
- offsetof(struct trap_per_cpu, resum_qmask)) ||
- (TRAP_PER_CPU_NONRESUM_QMASK !=
- offsetof(struct trap_per_cpu, nonresum_qmask)))
- trap_per_cpu_offsets_are_bolixed_dave();
-
- if ((TSB_CONFIG_TSB !=
- offsetof(struct tsb_config, tsb)) ||
- (TSB_CONFIG_RSS_LIMIT !=
- offsetof(struct tsb_config, tsb_rss_limit)) ||
- (TSB_CONFIG_NENTRIES !=
- offsetof(struct tsb_config, tsb_nentries)) ||
- (TSB_CONFIG_REG_VAL !=
- offsetof(struct tsb_config, tsb_reg_val)) ||
- (TSB_CONFIG_MAP_VADDR !=
- offsetof(struct tsb_config, tsb_map_vaddr)) ||
- (TSB_CONFIG_MAP_PTE !=
- offsetof(struct tsb_config, tsb_map_pte)))
- tsb_config_offsets_are_bolixed_dave();
+ BUILD_BUG_ON(TI_TASK != offsetof(struct thread_info, task) ||
+ TI_FLAGS != offsetof(struct thread_info, flags) ||
+ TI_CPU != offsetof(struct thread_info, cpu) ||
+ TI_FPSAVED != offsetof(struct thread_info, fpsaved) ||
+ TI_KSP != offsetof(struct thread_info, ksp) ||
+ TI_FAULT_ADDR != offsetof(struct thread_info,
+ fault_address) ||
+ TI_KREGS != offsetof(struct thread_info, kregs) ||
+ TI_UTRAPS != offsetof(struct thread_info, utraps) ||
+ TI_EXEC_DOMAIN != offsetof(struct thread_info,
+ exec_domain) ||
+ TI_REG_WINDOW != offsetof(struct thread_info,
+ reg_window) ||
+ TI_RWIN_SPTRS != offsetof(struct thread_info,
+ rwbuf_stkptrs) ||
+ TI_GSR != offsetof(struct thread_info, gsr) ||
+ TI_XFSR != offsetof(struct thread_info, xfsr) ||
+ TI_USER_CNTD0 != offsetof(struct thread_info,
+ user_cntd0) ||
+ TI_USER_CNTD1 != offsetof(struct thread_info,
+ user_cntd1) ||
+ TI_KERN_CNTD0 != offsetof(struct thread_info,
+ kernel_cntd0) ||
+ TI_KERN_CNTD1 != offsetof(struct thread_info,
+ kernel_cntd1) ||
+ TI_PCR != offsetof(struct thread_info, pcr_reg) ||
+ TI_PRE_COUNT != offsetof(struct thread_info,
+ preempt_count) ||
+ TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
+ TI_SYS_NOERROR != offsetof(struct thread_info,
+ syscall_noerror) ||
+ TI_RESTART_BLOCK != offsetof(struct thread_info,
+ restart_block) ||
+ TI_KUNA_REGS != offsetof(struct thread_info,
+ kern_una_regs) ||
+ TI_KUNA_INSN != offsetof(struct thread_info,
+ kern_una_insn) ||
+ TI_FPREGS != offsetof(struct thread_info, fpregs) ||
+ (TI_FPREGS & (64 - 1)));
+
+ BUILD_BUG_ON(TRAP_PER_CPU_THREAD != offsetof(struct trap_per_cpu,
+ thread) ||
+ (TRAP_PER_CPU_PGD_PADDR !=
+ offsetof(struct trap_per_cpu, pgd_paddr)) ||
+ (TRAP_PER_CPU_CPU_MONDO_PA !=
+ offsetof(struct trap_per_cpu, cpu_mondo_pa)) ||
+ (TRAP_PER_CPU_DEV_MONDO_PA !=
+ offsetof(struct trap_per_cpu, dev_mondo_pa)) ||
+ (TRAP_PER_CPU_RESUM_MONDO_PA !=
+ offsetof(struct trap_per_cpu, resum_mondo_pa)) ||
+ (TRAP_PER_CPU_RESUM_KBUF_PA !=
+ offsetof(struct trap_per_cpu, resum_kernel_buf_pa)) ||
+ (TRAP_PER_CPU_NONRESUM_MONDO_PA !=
+ offsetof(struct trap_per_cpu, nonresum_mondo_pa)) ||
+ (TRAP_PER_CPU_NONRESUM_KBUF_PA !=
+ offsetof(struct trap_per_cpu, nonresum_kernel_buf_pa)) ||
+ (TRAP_PER_CPU_FAULT_INFO !=
+ offsetof(struct trap_per_cpu, fault_info)) ||
+ (TRAP_PER_CPU_CPU_MONDO_BLOCK_PA !=
+ offsetof(struct trap_per_cpu, cpu_mondo_block_pa)) ||
+ (TRAP_PER_CPU_CPU_LIST_PA !=
+ offsetof(struct trap_per_cpu, cpu_list_pa)) ||
+ (TRAP_PER_CPU_TSB_HUGE !=
+ offsetof(struct trap_per_cpu, tsb_huge)) ||
+ (TRAP_PER_CPU_TSB_HUGE_TEMP !=
+ offsetof(struct trap_per_cpu, tsb_huge_temp)) ||
+ (TRAP_PER_CPU_IRQ_WORKLIST_PA !=
+ offsetof(struct trap_per_cpu, irq_worklist_pa)) ||
+ (TRAP_PER_CPU_CPU_MONDO_QMASK !=
+ offsetof(struct trap_per_cpu, cpu_mondo_qmask)) ||
+ (TRAP_PER_CPU_DEV_MONDO_QMASK !=
+ offsetof(struct trap_per_cpu, dev_mondo_qmask)) ||
+ (TRAP_PER_CPU_RESUM_QMASK !=
+ offsetof(struct trap_per_cpu, resum_qmask)) ||
+ (TRAP_PER_CPU_NONRESUM_QMASK !=
+ offsetof(struct trap_per_cpu, nonresum_qmask)) ||
+ (TRAP_PER_CPU_PER_CPU_BASE !=
+ offsetof(struct trap_per_cpu, __per_cpu_base)));
+
+ BUILD_BUG_ON((TSB_CONFIG_TSB !=
+ offsetof(struct tsb_config, tsb)) ||
+ (TSB_CONFIG_RSS_LIMIT !=
+ offsetof(struct tsb_config, tsb_rss_limit)) ||
+ (TSB_CONFIG_NENTRIES !=
+ offsetof(struct tsb_config, tsb_nentries)) ||
+ (TSB_CONFIG_REG_VAL !=
+ offsetof(struct tsb_config, tsb_reg_val)) ||
+ (TSB_CONFIG_MAP_VADDR !=
+ offsetof(struct tsb_config, tsb_map_vaddr)) ||
+ (TSB_CONFIG_MAP_PTE !=
+ offsetof(struct tsb_config, tsb_map_pte)));
/* Attach to the address space of init_task. On SMP we
* do this in smp.c:smp_callin for other cpus.
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index cbb282dab5a7..26bb3919ff1f 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -358,6 +358,7 @@ void __init paging_init(void)
protection_map[15] = PAGE_SHARED;
btfixup();
prom_build_devicetree();
+ of_fill_in_cpu_data();
device_scan();
}
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index f26a352c08a0..b5a5932def77 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1679,11 +1679,6 @@ pgd_t swapper_pg_dir[2048];
static void sun4u_pgprot_init(void);
static void sun4v_pgprot_init(void);
-/* Dummy function */
-void __init setup_per_cpu_areas(void)
-{
-}
-
void __init paging_init(void)
{
unsigned long end_pfn, shift, phys_base;
@@ -1799,16 +1794,13 @@ void __init paging_init(void)
if (tlb_type == hypervisor)
sun4v_ktsb_register();
- /* We must setup the per-cpu areas before we pull in the
- * PROM and the MDESC. The code there fills in cpu and
- * other information into per-cpu data structures.
- */
- real_setup_per_cpu_areas();
-
prom_build_devicetree();
+ of_populate_present_mask();
- if (tlb_type == hypervisor)
+ if (tlb_type == hypervisor) {
sun4v_mdesc_init();
+ mdesc_populate_present_mask(CPU_MASK_ALL_PTR);
+ }
/* Once the OF device tree and MDESC have been setup, we know
* the list of possible cpus. Therefore we can allocate the
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index f934225fd8ef..aa9e926e13d7 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -451,23 +451,6 @@ static void do_ubd_request(struct request_queue * q);
/* Only changed by ubd_init, which is an initcall. */
static int thread_fd = -1;
-
-static void ubd_end_request(struct request *req, int bytes, int error)
-{
- blk_end_request(req, error, bytes);
-}
-
-/* Callable only from interrupt context - otherwise you need to do
- * spin_lock_irq()/spin_lock_irqsave() */
-static inline void ubd_finish(struct request *req, int bytes)
-{
- if(bytes < 0){
- ubd_end_request(req, 0, -EIO);
- return;
- }
- ubd_end_request(req, bytes, 0);
-}
-
static LIST_HEAD(restart);
/* XXX - move this inside ubd_intr. */
@@ -475,7 +458,6 @@ static LIST_HEAD(restart);
static void ubd_handler(void)
{
struct io_thread_req *req;
- struct request *rq;
struct ubd *ubd;
struct list_head *list, *next_ele;
unsigned long flags;
@@ -492,10 +474,7 @@ static void ubd_handler(void)
return;
}
- rq = req->req;
- rq->nr_sectors -= req->length >> 9;
- if(rq->nr_sectors == 0)
- ubd_finish(rq, rq->hard_nr_sectors << 9);
+ blk_end_request(req->req, 0, req->length);
kfree(req);
}
reactivate_fd(thread_fd, UBD_IRQ);
@@ -1243,27 +1222,26 @@ static void do_ubd_request(struct request_queue *q)
{
struct io_thread_req *io_req;
struct request *req;
- int n, last_sectors;
+ sector_t sector;
+ int n;
while(1){
struct ubd *dev = q->queuedata;
if(dev->end_sg == 0){
- struct request *req = elv_next_request(q);
+ struct request *req = blk_fetch_request(q);
if(req == NULL)
return;
dev->request = req;
- blkdev_dequeue_request(req);
dev->start_sg = 0;
dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
}
req = dev->request;
- last_sectors = 0;
+ sector = blk_rq_pos(req);
while(dev->start_sg < dev->end_sg){
struct scatterlist *sg = &dev->sg[dev->start_sg];
- req->sector += last_sectors;
io_req = kmalloc(sizeof(struct io_thread_req),
GFP_ATOMIC);
if(io_req == NULL){
@@ -1272,10 +1250,10 @@ static void do_ubd_request(struct request_queue *q)
return;
}
prepare_request(req, io_req,
- (unsigned long long) req->sector << 9,
+ (unsigned long long)sector << 9,
sg->offset, sg->length, sg_page(sg));
- last_sectors = sg->length >> 9;
+ sector += sg->length >> 9;
n = os_write_file(thread_fd, &io_req,
sizeof(struct io_thread_req *));
if(n != sizeof(struct io_thread_req *)){
diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
new file mode 100644
index 000000000000..ad8ec356fb36
--- /dev/null
+++ b/arch/x86/Kbuild
@@ -0,0 +1,16 @@
+
+obj-$(CONFIG_KVM) += kvm/
+
+# Xen paravirtualization support
+obj-$(CONFIG_XEN) += xen/
+
+# lguest paravirtualization support
+obj-$(CONFIG_LGUEST_GUEST) += lguest/
+
+obj-y += kernel/
+obj-y += mm/
+
+obj-y += crypto/
+obj-y += vdso/
+obj-$(CONFIG_IA32_EMULATION) += ia32/
+
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index df9e885eee14..41adbced6c54 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -47,6 +47,11 @@ config X86
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
+config OUTPUT_FORMAT
+ string
+ default "elf32-i386" if X86_32
+ default "elf64-x86-64" if X86_64
+
config ARCH_DEFCONFIG
string
default "arch/x86/configs/i386_defconfig" if X86_32
@@ -274,15 +279,9 @@ config SPARSE_IRQ
If you don't know what to do here, say N.
-config NUMA_MIGRATE_IRQ_DESC
- bool "Move irq desc when changing irq smp_affinity"
+config NUMA_IRQ_DESC
+ def_bool y
depends on SPARSE_IRQ && NUMA
- depends on BROKEN
- default n
- ---help---
- This enables moving irq_desc to cpu/node that irq will use handled.
-
- If you don't know what to do here, say N.
config X86_MPPARSE
bool "Enable MPS table" if ACPI
@@ -355,7 +354,7 @@ config X86_UV
depends on X86_64
depends on X86_EXTENDED_PLATFORM
depends on NUMA
- select X86_X2APIC
+ depends on X86_X2APIC
---help---
This option is needed in order to support SGI Ultraviolet systems.
If you don't have one of these, you should say N here.
@@ -1194,6 +1193,11 @@ config ARCH_MEMORY_PROBE
def_bool X86_64
depends on MEMORY_HOTPLUG
+config ILLEGAL_POINTER_VALUE
+ hex
+ default 0 if X86_32
+ default 0xdead000000000000 if X86_64
+
source "mm/Kconfig"
config HIGHPTE
@@ -1511,6 +1515,11 @@ config RELOCATABLE
it has been loaded at and the compile time physical address
(CONFIG_PHYSICAL_START) is ignored.
+# Relocation on x86-32 needs some additional build support
+config X86_NEED_RELOCS
+ def_bool y
+ depends on X86_32 && RELOCATABLE
+
config PHYSICAL_ALIGN
hex
prompt "Alignment value to which kernel should be aligned" if X86_32
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 8130334329c0..924e156a85ab 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -506,7 +506,6 @@ config X86_PTRACE_BTS
bool "Branch Trace Store"
default y
depends on X86_DEBUGCTLMSR
- depends on BROKEN
---help---
This adds a ptrace interface to the hardware's branch trace store.
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index d8359e73317f..ca1aa3eca9bc 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -161,12 +161,20 @@ config IOMMU_DEBUG
config IOMMU_LEAK
bool "IOMMU leak tracing"
- depends on DEBUG_KERNEL
- depends on IOMMU_DEBUG
+ depends on IOMMU_DEBUG && DMA_API_DEBUG
---help---
Add a simple leak tracer to the IOMMU code. This is useful when you
are debugging a buggy device driver that leaks IOMMU mappings.
+config X86_DS_SELFTEST
+ bool "DS selftest"
+ default y
+ depends on DEBUG_KERNEL
+ depends on X86_DS
+ ---help---
+ Perform Debug Store selftests at boot time.
+ If in doubt, say "N".
+
config HAVE_MMIOTRACE_SUPPORT
def_bool y
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 8c86b72afdc2..edbd0ca62067 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -7,8 +7,6 @@ else
KBUILD_DEFCONFIG := $(ARCH)_defconfig
endif
-core-$(CONFIG_KVM) += arch/x86/kvm/
-
# BITS is used as extension for files which are available in a 32 bit
# and a 64 bit version to simplify shared Makefiles.
# e.g.: obj-y += foo_$(BITS).o
@@ -118,21 +116,8 @@ head-y += arch/x86/kernel/init_task.o
libs-y += arch/x86/lib/
-# Sub architecture files that needs linking first
-core-y += $(fcore-y)
-
-# Xen paravirtualization support
-core-$(CONFIG_XEN) += arch/x86/xen/
-
-# lguest paravirtualization support
-core-$(CONFIG_LGUEST_GUEST) += arch/x86/lguest/
-
-core-y += arch/x86/kernel/
-core-y += arch/x86/mm/
-
-core-y += arch/x86/crypto/
-core-y += arch/x86/vdso/
-core-$(CONFIG_IA32_EMULATION) += arch/x86/ia32/
+# See arch/x86/Kbuild for content of core part of the kernel
+core-y += arch/x86/
# drivers-y are linked after core-y
drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 6633b6e7505a..658bc525cac7 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -26,9 +26,10 @@ targets := vmlinux.bin setup.bin setup.elf bzImage
targets += fdimage fdimage144 fdimage288 image.iso mtools.conf
subdir- := compressed
-setup-y += a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o
+setup-y += a20.o bioscall.o cmdline.o copy.o cpu.o cpucheck.o edd.o
setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
-setup-y += printf.o string.o tty.o video.o video-mode.o version.o
+setup-y += printf.o regs.o string.o tty.o video.o video-mode.o
+setup-y += version.o
setup-$(CONFIG_X86_APM_BOOT) += apm.o
# The link order of the video-*.o modules can matter. In particular,
diff --git a/arch/x86/boot/a20.c b/arch/x86/boot/a20.c
index 7c19ce8c2442..64a31a6d751a 100644
--- a/arch/x86/boot/a20.c
+++ b/arch/x86/boot/a20.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007-2008 rPath, Inc. - All Rights Reserved
- * Copyright 2009 Intel Corporation
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -90,8 +90,11 @@ static int a20_test_long(void)
static void enable_a20_bios(void)
{
- asm volatile("pushfl; int $0x15; popfl"
- : : "a" ((u16)0x2401));
+ struct biosregs ireg;
+
+ initregs(&ireg);
+ ireg.ax = 0x2401;
+ intcall(0x15, &ireg, NULL);
}
static void enable_a20_kbc(void)
diff --git a/arch/x86/boot/apm.c b/arch/x86/boot/apm.c
index 7aa6033001f9..ee274834ea8b 100644
--- a/arch/x86/boot/apm.c
+++ b/arch/x86/boot/apm.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* Original APM BIOS checking by Stephen Rothwell, May 1994
* (sfr@canb.auug.org.au)
@@ -19,75 +20,56 @@
int query_apm_bios(void)
{
- u16 ax, bx, cx, dx, di;
- u32 ebx, esi;
- u8 err;
+ struct biosregs ireg, oreg;
/* APM BIOS installation check */
- ax = 0x5300;
- bx = cx = 0;
- asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
- : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
- : : "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x53;
+ intcall(0x15, &ireg, &oreg);
- if (err)
+ if (oreg.flags & X86_EFLAGS_CF)
return -1; /* No APM BIOS */
- if (bx != 0x504d) /* "PM" signature */
+ if (oreg.bx != 0x504d) /* "PM" signature */
return -1;
- if (!(cx & 0x02)) /* 32 bits supported? */
+ if (!(oreg.cx & 0x02)) /* 32 bits supported? */
return -1;
/* Disconnect first, just in case */
- ax = 0x5304;
- bx = 0;
- asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
- : "+a" (ax), "+b" (bx)
- : : "ecx", "edx", "esi", "edi");
-
- /* Paranoia */
- ebx = esi = 0;
- cx = dx = di = 0;
+ ireg.al = 0x04;
+ intcall(0x15, &ireg, NULL);
/* 32-bit connect */
- asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
- : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
- "+S" (esi), "+D" (di), "=m" (err)
- : "a" (0x5303));
-
- boot_params.apm_bios_info.cseg = ax;
- boot_params.apm_bios_info.offset = ebx;
- boot_params.apm_bios_info.cseg_16 = cx;
- boot_params.apm_bios_info.dseg = dx;
- boot_params.apm_bios_info.cseg_len = (u16)esi;
- boot_params.apm_bios_info.cseg_16_len = esi >> 16;
- boot_params.apm_bios_info.dseg_len = di;
-
- if (err)
+ ireg.al = 0x03;
+ intcall(0x15, &ireg, &oreg);
+
+ boot_params.apm_bios_info.cseg = oreg.ax;
+ boot_params.apm_bios_info.offset = oreg.ebx;
+ boot_params.apm_bios_info.cseg_16 = oreg.cx;
+ boot_params.apm_bios_info.dseg = oreg.dx;
+ boot_params.apm_bios_info.cseg_len = oreg.si;
+ boot_params.apm_bios_info.cseg_16_len = oreg.hsi;
+ boot_params.apm_bios_info.dseg_len = oreg.di;
+
+ if (oreg.flags & X86_EFLAGS_CF)
return -1;
/* Redo the installation check as the 32-bit connect;
some BIOSes return different flags this way... */
- ax = 0x5300;
- bx = cx = 0;
- asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
- : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
- : : "esi", "edi");
+ ireg.al = 0x00;
+ intcall(0x15, &ireg, &oreg);
- if (err || bx != 0x504d) {
+ if ((oreg.eflags & X86_EFLAGS_CF) || oreg.bx != 0x504d) {
/* Failure with 32-bit connect, try to disconect and ignore */
- ax = 0x5304;
- bx = 0;
- asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
- : "+a" (ax), "+b" (bx)
- : : "ecx", "edx", "esi", "edi");
+ ireg.al = 0x04;
+ intcall(0x15, &ireg, NULL);
return -1;
}
- boot_params.apm_bios_info.version = ax;
- boot_params.apm_bios_info.flags = cx;
+ boot_params.apm_bios_info.version = oreg.ax;
+ boot_params.apm_bios_info.flags = oreg.cx;
return 0;
}
diff --git a/arch/x86/boot/bioscall.S b/arch/x86/boot/bioscall.S
new file mode 100644
index 000000000000..507793739ea5
--- /dev/null
+++ b/arch/x86/boot/bioscall.S
@@ -0,0 +1,82 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
+ *
+ * This file is part of the Linux kernel, and is made available under
+ * the terms of the GNU General Public License version 2 or (at your
+ * option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * "Glove box" for BIOS calls. Avoids the constant problems with BIOSes
+ * touching registers they shouldn't be.
+ */
+
+ .code16
+ .text
+ .globl intcall
+ .type intcall, @function
+intcall:
+ /* Self-modify the INT instruction. Ugly, but works. */
+ cmpb %al, 3f
+ je 1f
+ movb %al, 3f
+ jmp 1f /* Synchronize pipeline */
+1:
+ /* Save state */
+ pushfl
+ pushw %fs
+ pushw %gs
+ pushal
+
+ /* Copy input state to stack frame */
+ subw $44, %sp
+ movw %dx, %si
+ movw %sp, %di
+ movw $11, %cx
+ rep; movsd
+
+ /* Pop full state from the stack */
+ popal
+ popw %gs
+ popw %fs
+ popw %es
+ popw %ds
+ popfl
+
+ /* Actual INT */
+ .byte 0xcd /* INT opcode */
+3: .byte 0
+
+ /* Push full state to the stack */
+ pushfl
+ pushw %ds
+ pushw %es
+ pushw %fs
+ pushw %gs
+ pushal
+
+ /* Re-establish C environment invariants */
+ cld
+ movzwl %sp, %esp
+ movw %cs, %ax
+ movw %ax, %ds
+ movw %ax, %es
+
+ /* Copy output state from stack frame */
+ movw 68(%esp), %di /* Original %cx == 3rd argument */
+ andw %di, %di
+ jz 4f
+ movw %sp, %si
+ movw $11, %cx
+ rep; movsd
+4: addw $44, %sp
+
+ /* Restore state and return */
+ popal
+ popw %gs
+ popw %fs
+ popfl
+ retl
+ .size intcall, .-intcall
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h
index 7b2692e897e5..98239d2658f2 100644
--- a/arch/x86/boot/boot.h
+++ b/arch/x86/boot/boot.h
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -26,6 +27,7 @@
#include <asm/setup.h>
#include "bitops.h"
#include <asm/cpufeature.h>
+#include <asm/processor-flags.h>
/* Useful macros */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
@@ -241,6 +243,49 @@ int enable_a20(void);
/* apm.c */
int query_apm_bios(void);
+/* bioscall.c */
+struct biosregs {
+ union {
+ struct {
+ u32 edi;
+ u32 esi;
+ u32 ebp;
+ u32 _esp;
+ u32 ebx;
+ u32 edx;
+ u32 ecx;
+ u32 eax;
+ u32 _fsgs;
+ u32 _dses;
+ u32 eflags;
+ };
+ struct {
+ u16 di, hdi;
+ u16 si, hsi;
+ u16 bp, hbp;
+ u16 _sp, _hsp;
+ u16 bx, hbx;
+ u16 dx, hdx;
+ u16 cx, hcx;
+ u16 ax, hax;
+ u16 gs, fs;
+ u16 es, ds;
+ u16 flags, hflags;
+ };
+ struct {
+ u8 dil, dih, edi2, edi3;
+ u8 sil, sih, esi2, esi3;
+ u8 bpl, bph, ebp2, ebp3;
+ u8 _spl, _sph, _esp2, _esp3;
+ u8 bl, bh, ebx2, ebx3;
+ u8 dl, dh, edx2, edx3;
+ u8 cl, ch, ecx2, ecx3;
+ u8 al, ah, eax2, eax3;
+ };
+ };
+};
+void intcall(u8 int_no, const struct biosregs *ireg, struct biosregs *oreg);
+
/* cmdline.c */
int cmdline_find_option(const char *option, char *buffer, int bufsize);
int cmdline_find_option_bool(const char *option);
@@ -279,6 +324,9 @@ int sprintf(char *buf, const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args);
int printf(const char *fmt, ...);
+/* regs.c */
+void initregs(struct biosregs *regs);
+
/* string.c */
int strcmp(const char *str1, const char *str2);
size_t strnlen(const char *s, size_t maxlen);
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 65551c9f8571..49c8a4c37d7c 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -19,7 +19,9 @@ KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
LDFLAGS := -m elf_$(UTS_MACHINE)
LDFLAGS_vmlinux := -T
-$(obj)/vmlinux: $(src)/vmlinux_$(BITS).lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/piggy.o FORCE
+hostprogs-y := mkpiggy
+
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/piggy.o FORCE
$(call if_changed,ld)
@:
@@ -29,7 +31,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE
targets += vmlinux.bin.all vmlinux.relocs relocs
-hostprogs-$(CONFIG_X86_32) += relocs
+hostprogs-$(CONFIG_X86_NEED_RELOCS) += relocs
quiet_cmd_relocs = RELOCS $@
cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $<
@@ -37,46 +39,22 @@ $(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE
$(call if_changed,relocs)
vmlinux.bin.all-y := $(obj)/vmlinux.bin
-vmlinux.bin.all-$(CONFIG_RELOCATABLE) += $(obj)/vmlinux.relocs
-quiet_cmd_relocbin = BUILD $@
- cmd_relocbin = cat $(filter-out FORCE,$^) > $@
-$(obj)/vmlinux.bin.all: $(vmlinux.bin.all-y) FORCE
- $(call if_changed,relocbin)
-
-ifeq ($(CONFIG_X86_32),y)
+vmlinux.bin.all-$(CONFIG_X86_NEED_RELOCS) += $(obj)/vmlinux.relocs
-ifdef CONFIG_RELOCATABLE
-$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE
- $(call if_changed,gzip)
-$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin.all FORCE
- $(call if_changed,bzip2)
-$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin.all FORCE
- $(call if_changed,lzma)
-else
-$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
$(call if_changed,gzip)
-$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
$(call if_changed,bzip2)
-$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lzma)
-endif
-LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
-else
+suffix-$(CONFIG_KERNEL_GZIP) := gz
+suffix-$(CONFIG_KERNEL_BZIP2) := bz2
+suffix-$(CONFIG_KERNEL_LZMA) := lzma
-$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
- $(call if_changed,gzip)
-$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
- $(call if_changed,bzip2)
-$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
- $(call if_changed,lzma)
-
-LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
-endif
+quiet_cmd_mkpiggy = MKPIGGY $@
+ cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false )
-suffix_$(CONFIG_KERNEL_GZIP) = gz
-suffix_$(CONFIG_KERNEL_BZIP2) = bz2
-suffix_$(CONFIG_KERNEL_LZMA) = lzma
-
-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE
- $(call if_changed,ld)
+targets += piggy.S
+$(obj)/piggy.S: $(obj)/vmlinux.bin.$(suffix-y) $(obj)/mkpiggy FORCE
+ $(call if_changed,mkpiggy)
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index 3a8a866fb2e2..470474bafc4d 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -12,16 +12,16 @@
* the page directory. [According to comments etc elsewhere on a compressed
* kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
*
- * Page 0 is deliberately kept safe, since System Management Mode code in
+ * Page 0 is deliberately kept safe, since System Management Mode code in
* laptops may need to access the BIOS data stored there. This is also
- * useful for future device drivers that either access the BIOS via VM86
+ * useful for future device drivers that either access the BIOS via VM86
* mode.
*/
/*
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
*/
-.text
+ .text
#include <linux/linkage.h>
#include <asm/segment.h>
@@ -29,75 +29,78 @@
#include <asm/boot.h>
#include <asm/asm-offsets.h>
-.section ".text.head","ax",@progbits
+ .section ".text.head","ax",@progbits
ENTRY(startup_32)
cld
- /* test KEEP_SEGMENTS flag to see if the bootloader is asking
- * us to not reload segments */
- testb $(1<<6), BP_loadflags(%esi)
- jnz 1f
+ /*
+ * Test KEEP_SEGMENTS flag to see if the bootloader is asking
+ * us to not reload segments
+ */
+ testb $(1<<6), BP_loadflags(%esi)
+ jnz 1f
cli
- movl $(__BOOT_DS),%eax
- movl %eax,%ds
- movl %eax,%es
- movl %eax,%fs
- movl %eax,%gs
- movl %eax,%ss
+ movl $__BOOT_DS, %eax
+ movl %eax, %ds
+ movl %eax, %es
+ movl %eax, %fs
+ movl %eax, %gs
+ movl %eax, %ss
1:
-/* Calculate the delta between where we were compiled to run
+/*
+ * Calculate the delta between where we were compiled to run
* at and where we were actually loaded at. This can only be done
* with a short local call on x86. Nothing else will tell us what
* address we are running at. The reserved chunk of the real-mode
* data at 0x1e4 (defined as a scratch field) are used as the stack
* for this calculation. Only 4 bytes are needed.
*/
- leal (0x1e4+4)(%esi), %esp
- call 1f
-1: popl %ebp
- subl $1b, %ebp
+ leal (BP_scratch+4)(%esi), %esp
+ call 1f
+1: popl %ebp
+ subl $1b, %ebp
-/* %ebp contains the address we are loaded at by the boot loader and %ebx
+/*
+ * %ebp contains the address we are loaded at by the boot loader and %ebx
* contains the address where we should move the kernel image temporarily
* for safe in-place decompression.
*/
#ifdef CONFIG_RELOCATABLE
- movl %ebp, %ebx
+ movl %ebp, %ebx
addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
#else
- movl $LOAD_PHYSICAL_ADDR, %ebx
+ movl $LOAD_PHYSICAL_ADDR, %ebx
#endif
- /* Replace the compressed data size with the uncompressed size */
- subl input_len(%ebp), %ebx
- movl output_len(%ebp), %eax
- addl %eax, %ebx
- /* Add 8 bytes for every 32K input block */
- shrl $12, %eax
- addl %eax, %ebx
- /* Add 32K + 18 bytes of extra slack */
- addl $(32768 + 18), %ebx
- /* Align on a 4K boundary */
- addl $4095, %ebx
- andl $~4095, %ebx
-
-/* Copy the compressed kernel to the end of our buffer
+ /* Target address to relocate to for decompression */
+ addl $z_extract_offset, %ebx
+
+ /* Set up the stack */
+ leal boot_stack_end(%ebx), %esp
+
+ /* Zero EFLAGS */
+ pushl $0
+ popfl
+
+/*
+ * Copy the compressed kernel to the end of our buffer
* where decompression in place becomes safe.
*/
- pushl %esi
- leal _end(%ebp), %esi
- leal _end(%ebx), %edi
- movl $(_end - startup_32), %ecx
+ pushl %esi
+ leal (_bss-4)(%ebp), %esi
+ leal (_bss-4)(%ebx), %edi
+ movl $(_bss - startup_32), %ecx
+ shrl $2, %ecx
std
- rep
- movsb
+ rep movsl
cld
- popl %esi
+ popl %esi
-/* Compute the kernel start address.
+/*
+ * Compute the kernel start address.
*/
#ifdef CONFIG_RELOCATABLE
addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
@@ -109,81 +112,75 @@ ENTRY(startup_32)
/*
* Jump to the relocated address.
*/
- leal relocated(%ebx), %eax
- jmp *%eax
+ leal relocated(%ebx), %eax
+ jmp *%eax
ENDPROC(startup_32)
-.section ".text"
+ .text
relocated:
/*
- * Clear BSS
+ * Clear BSS (stack is currently empty)
*/
- xorl %eax,%eax
- leal _edata(%ebx),%edi
- leal _end(%ebx), %ecx
- subl %edi,%ecx
- cld
- rep
- stosb
-
-/*
- * Setup the stack for the decompressor
- */
- leal boot_stack_end(%ebx), %esp
+ xorl %eax, %eax
+ leal _bss(%ebx), %edi
+ leal _ebss(%ebx), %ecx
+ subl %edi, %ecx
+ shrl $2, %ecx
+ rep stosl
/*
* Do the decompression, and jump to the new kernel..
*/
- movl output_len(%ebx), %eax
- pushl %eax
- # push arguments for decompress_kernel:
- pushl %ebp # output address
- movl input_len(%ebx), %eax
- pushl %eax # input_len
- leal input_data(%ebx), %eax
- pushl %eax # input_data
- leal boot_heap(%ebx), %eax
- pushl %eax # heap area
- pushl %esi # real mode pointer
- call decompress_kernel
- addl $20, %esp
- popl %ecx
+ leal z_extract_offset_negative(%ebx), %ebp
+ /* push arguments for decompress_kernel: */
+ pushl %ebp /* output address */
+ pushl $z_input_len /* input_len */
+ leal input_data(%ebx), %eax
+ pushl %eax /* input_data */
+ leal boot_heap(%ebx), %eax
+ pushl %eax /* heap area */
+ pushl %esi /* real mode pointer */
+ call decompress_kernel
+ addl $20, %esp
#if CONFIG_RELOCATABLE
-/* Find the address of the relocations.
+/*
+ * Find the address of the relocations.
*/
- movl %ebp, %edi
- addl %ecx, %edi
+ leal z_output_len(%ebp), %edi
-/* Calculate the delta between where vmlinux was compiled to run
+/*
+ * Calculate the delta between where vmlinux was compiled to run
* and where it was actually loaded.
*/
- movl %ebp, %ebx
- subl $LOAD_PHYSICAL_ADDR, %ebx
- jz 2f /* Nothing to be done if loaded at compiled addr. */
+ movl %ebp, %ebx
+ subl $LOAD_PHYSICAL_ADDR, %ebx
+ jz 2f /* Nothing to be done if loaded at compiled addr. */
/*
* Process relocations.
*/
-1: subl $4, %edi
- movl 0(%edi), %ecx
- testl %ecx, %ecx
- jz 2f
- addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
- jmp 1b
+1: subl $4, %edi
+ movl (%edi), %ecx
+ testl %ecx, %ecx
+ jz 2f
+ addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
+ jmp 1b
2:
#endif
/*
* Jump to the decompressed kernel.
*/
- xorl %ebx,%ebx
- jmp *%ebp
+ xorl %ebx, %ebx
+ jmp *%ebp
-.bss
-/* Stack and heap for uncompression */
-.balign 4
+/*
+ * Stack and heap for uncompression
+ */
+ .bss
+ .balign 4
boot_heap:
.fill BOOT_HEAP_SIZE, 1, 0
boot_stack:
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index ed4a82948002..2b9f2510507b 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -21,8 +21,8 @@
/*
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
*/
-.code32
-.text
+ .code32
+ .text
#include <linux/linkage.h>
#include <asm/segment.h>
@@ -33,12 +33,14 @@
#include <asm/processor-flags.h>
#include <asm/asm-offsets.h>
-.section ".text.head"
+ .section ".text.head"
.code32
ENTRY(startup_32)
cld
- /* test KEEP_SEGMENTS flag to see if the bootloader is asking
- * us to not reload segments */
+ /*
+ * Test KEEP_SEGMENTS flag to see if the bootloader is asking
+ * us to not reload segments
+ */
testb $(1<<6), BP_loadflags(%esi)
jnz 1f
@@ -49,14 +51,15 @@ ENTRY(startup_32)
movl %eax, %ss
1:
-/* Calculate the delta between where we were compiled to run
+/*
+ * Calculate the delta between where we were compiled to run
* at and where we were actually loaded at. This can only be done
* with a short local call on x86. Nothing else will tell us what
* address we are running at. The reserved chunk of the real-mode
* data at 0x1e4 (defined as a scratch field) are used as the stack
* for this calculation. Only 4 bytes are needed.
*/
- leal (0x1e4+4)(%esi), %esp
+ leal (BP_scratch+4)(%esi), %esp
call 1f
1: popl %ebp
subl $1b, %ebp
@@ -70,10 +73,11 @@ ENTRY(startup_32)
testl %eax, %eax
jnz no_longmode
-/* Compute the delta between where we were compiled to run at
+/*
+ * Compute the delta between where we were compiled to run at
* and where the code will actually run at.
- */
-/* %ebp contains the address we are loaded at by the boot loader and %ebx
+ *
+ * %ebp contains the address we are loaded at by the boot loader and %ebx
* contains the address where we should move the kernel image temporarily
* for safe in-place decompression.
*/
@@ -86,16 +90,8 @@ ENTRY(startup_32)
movl $CONFIG_PHYSICAL_START, %ebx
#endif
- /* Replace the compressed data size with the uncompressed size */
- subl input_len(%ebp), %ebx
- movl output_len(%ebp), %eax
- addl %eax, %ebx
- /* Add 8 bytes for every 32K input block */
- shrl $12, %eax
- addl %eax, %ebx
- /* Add 32K + 18 bytes of extra slack and align on a 4K boundary */
- addl $(32768 + 18 + 4095), %ebx
- andl $~4095, %ebx
+ /* Target address to relocate to for decompression */
+ addl $z_extract_offset, %ebx
/*
* Prepare for entering 64 bit mode
@@ -114,7 +110,7 @@ ENTRY(startup_32)
/*
* Build early 4G boot pagetable
*/
- /* Initialize Page tables to 0*/
+ /* Initialize Page tables to 0 */
leal pgtable(%ebx), %edi
xorl %eax, %eax
movl $((4096*6)/4), %ecx
@@ -155,7 +151,8 @@ ENTRY(startup_32)
btsl $_EFER_LME, %eax
wrmsr
- /* Setup for the jump to 64bit mode
+ /*
+ * Setup for the jump to 64bit mode
*
* When the jump is performend we will be in long mode but
* in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1
@@ -184,7 +181,8 @@ no_longmode:
#include "../../kernel/verify_cpu_64.S"
- /* Be careful here startup_64 needs to be at a predictable
+ /*
+ * Be careful here startup_64 needs to be at a predictable
* address so I can export it in an ELF header. Bootloaders
* should look at the ELF header to find this address, as
* it may change in the future.
@@ -192,7 +190,8 @@ no_longmode:
.code64
.org 0x200
ENTRY(startup_64)
- /* We come here either from startup_32 or directly from a
+ /*
+ * We come here either from startup_32 or directly from a
* 64bit bootloader. If we come here from a bootloader we depend on
* an identity mapped page table being provied that maps our
* entire text+data+bss and hopefully all of memory.
@@ -209,13 +208,17 @@ ENTRY(startup_64)
movl $0x20, %eax
ltr %ax
- /* Compute the decompressed kernel start address. It is where
+ /*
+ * Compute the decompressed kernel start address. It is where
* we were loaded at aligned to a 2M boundary. %rbp contains the
* decompressed kernel start address.
*
* If it is a relocatable kernel then decompress and run the kernel
* from load address aligned to 2MB addr, otherwise decompress and
* run the kernel from CONFIG_PHYSICAL_START
+ *
+ * We cannot rely on the calculation done in 32-bit mode, since we
+ * may have been invoked via the 64-bit entry point.
*/
/* Start with the delta to where the kernel will run at. */
@@ -229,30 +232,29 @@ ENTRY(startup_64)
movq %rbp, %rbx
#endif
- /* Replace the compressed data size with the uncompressed size */
- movl input_len(%rip), %eax
- subq %rax, %rbx
- movl output_len(%rip), %eax
- addq %rax, %rbx
- /* Add 8 bytes for every 32K input block */
- shrq $12, %rax
- addq %rax, %rbx
- /* Add 32K + 18 bytes of extra slack and align on a 4K boundary */
- addq $(32768 + 18 + 4095), %rbx
- andq $~4095, %rbx
-
-/* Copy the compressed kernel to the end of our buffer
+ /* Target address to relocate to for decompression */
+ leaq z_extract_offset(%rbp), %rbx
+
+ /* Set up the stack */
+ leaq boot_stack_end(%rbx), %rsp
+
+ /* Zero EFLAGS */
+ pushq $0
+ popfq
+
+/*
+ * Copy the compressed kernel to the end of our buffer
* where decompression in place becomes safe.
*/
- leaq _end_before_pgt(%rip), %r8
- leaq _end_before_pgt(%rbx), %r9
- movq $_end_before_pgt /* - $startup_32 */, %rcx
-1: subq $8, %r8
- subq $8, %r9
- movq 0(%r8), %rax
- movq %rax, 0(%r9)
- subq $8, %rcx
- jnz 1b
+ pushq %rsi
+ leaq (_bss-8)(%rip), %rsi
+ leaq (_bss-8)(%rbx), %rdi
+ movq $_bss /* - $startup_32 */, %rcx
+ shrq $3, %rcx
+ std
+ rep movsq
+ cld
+ popq %rsi
/*
* Jump to the relocated address.
@@ -260,37 +262,28 @@ ENTRY(startup_64)
leaq relocated(%rbx), %rax
jmp *%rax
-.section ".text"
+ .text
relocated:
/*
- * Clear BSS
+ * Clear BSS (stack is currently empty)
*/
- xorq %rax, %rax
- leaq _edata(%rbx), %rdi
- leaq _end_before_pgt(%rbx), %rcx
+ xorl %eax, %eax
+ leaq _bss(%rip), %rdi
+ leaq _ebss(%rip), %rcx
subq %rdi, %rcx
- cld
- rep
- stosb
-
- /* Setup the stack */
- leaq boot_stack_end(%rip), %rsp
-
- /* zero EFLAGS after setting rsp */
- pushq $0
- popfq
+ shrq $3, %rcx
+ rep stosq
/*
* Do the decompression, and jump to the new kernel..
*/
- pushq %rsi # Save the real mode argument
- movq %rsi, %rdi # real mode address
- leaq boot_heap(%rip), %rsi # malloc area for uncompression
- leaq input_data(%rip), %rdx # input_data
- movl input_len(%rip), %eax
- movq %rax, %rcx # input_len
- movq %rbp, %r8 # output
+ pushq %rsi /* Save the real mode argument */
+ movq %rsi, %rdi /* real mode address */
+ leaq boot_heap(%rip), %rsi /* malloc area for uncompression */
+ leaq input_data(%rip), %rdx /* input_data */
+ movl $z_input_len, %ecx /* input_len */
+ movq %rbp, %r8 /* output target address */
call decompress_kernel
popq %rsi
@@ -311,11 +304,21 @@ gdt:
.quad 0x0000000000000000 /* TS continued */
gdt_end:
-.bss
-/* Stack and heap for uncompression */
-.balign 4
+/*
+ * Stack and heap for uncompression
+ */
+ .bss
+ .balign 4
boot_heap:
.fill BOOT_HEAP_SIZE, 1, 0
boot_stack:
.fill BOOT_STACK_SIZE, 1, 0
boot_stack_end:
+
+/*
+ * Space for page tables (not in .bss so not zeroed)
+ */
+ .section ".pgtable","a",@nobits
+ .balign 4096
+pgtable:
+ .fill 6*4096, 1, 0
diff --git a/arch/x86/boot/compressed/mkpiggy.c b/arch/x86/boot/compressed/mkpiggy.c
new file mode 100644
index 000000000000..bcbd36c41432
--- /dev/null
+++ b/arch/x86/boot/compressed/mkpiggy.c
@@ -0,0 +1,97 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright (C) 2009 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 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 Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * H. Peter Anvin <hpa@linux.intel.com>
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Compute the desired load offset from a compressed program; outputs
+ * a small assembly wrapper with the appropriate symbols defined.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+static uint32_t getle32(const void *p)
+{
+ const uint8_t *cp = p;
+
+ return (uint32_t)cp[0] + ((uint32_t)cp[1] << 8) +
+ ((uint32_t)cp[2] << 16) + ((uint32_t)cp[3] << 24);
+}
+
+int main(int argc, char *argv[])
+{
+ uint32_t olen;
+ long ilen;
+ unsigned long offs;
+ FILE *f;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s compressed_file\n", argv[0]);
+ return 1;
+ }
+
+ /* Get the information for the compressed kernel image first */
+
+ f = fopen(argv[1], "r");
+ if (!f) {
+ perror(argv[1]);
+ return 1;
+ }
+
+
+ if (fseek(f, -4L, SEEK_END)) {
+ perror(argv[1]);
+ }
+ fread(&olen, sizeof olen, 1, f);
+ ilen = ftell(f);
+ olen = getle32(&olen);
+ fclose(f);
+
+ /*
+ * Now we have the input (compressed) and output (uncompressed)
+ * sizes, compute the necessary decompression offset...
+ */
+
+ offs = (olen > ilen) ? olen - ilen : 0;
+ offs += olen >> 12; /* Add 8 bytes for each 32K block */
+ offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */
+ offs = (offs+4095) & ~4095; /* Round to a 4K boundary */
+
+ printf(".section \".rodata.compressed\",\"a\",@progbits\n");
+ printf(".globl z_input_len\n");
+ printf("z_input_len = %lu\n", ilen);
+ printf(".globl z_output_len\n");
+ printf("z_output_len = %lu\n", (unsigned long)olen);
+ printf(".globl z_extract_offset\n");
+ printf("z_extract_offset = 0x%lx\n", offs);
+ /* z_extract_offset_negative allows simplification of head_32.S */
+ printf(".globl z_extract_offset_negative\n");
+ printf("z_extract_offset_negative = -0x%lx\n", offs);
+
+ printf(".globl input_data, input_data_end\n");
+ printf("input_data:\n");
+ printf(".incbin \"%s\"\n", argv[1]);
+ printf("input_data_end:\n");
+
+ return 0;
+}
diff --git a/arch/x86/boot/compressed/vmlinux_64.lds b/arch/x86/boot/compressed/vmlinux.lds.S
index bef1ac891bce..cc353e1b3ffd 100644
--- a/arch/x86/boot/compressed/vmlinux_64.lds
+++ b/arch/x86/boot/compressed/vmlinux.lds.S
@@ -1,6 +1,17 @@
-OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT)
+
+#undef i386
+
+#include <asm/page_types.h>
+
+#ifdef CONFIG_X86_64
OUTPUT_ARCH(i386:x86-64)
ENTRY(startup_64)
+#else
+OUTPUT_ARCH(i386)
+ENTRY(startup_32)
+#endif
+
SECTIONS
{
/* Be careful parts of head_64.S assume startup_32 is at
@@ -33,16 +44,22 @@ SECTIONS
*(.data.*)
_edata = . ;
}
+ . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
.bss : {
_bss = . ;
*(.bss)
*(.bss.*)
*(COMMON)
- . = ALIGN(8);
- _end_before_pgt = . ;
- . = ALIGN(4096);
- pgtable = . ;
- . = . + 4096 * 6;
+ . = ALIGN(8); /* For convenience during zeroing */
_ebss = .;
}
+#ifdef CONFIG_X86_64
+ . = ALIGN(PAGE_SIZE);
+ .pgtable : {
+ _pgtable = . ;
+ *(.pgtable)
+ _epgtable = . ;
+ }
+#endif
+ _end = .;
}
diff --git a/arch/x86/boot/compressed/vmlinux.scr b/arch/x86/boot/compressed/vmlinux.scr
deleted file mode 100644
index f02382ae5c48..000000000000
--- a/arch/x86/boot/compressed/vmlinux.scr
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTIONS
-{
- .rodata.compressed : {
- input_len = .;
- LONG(input_data_end - input_data) input_data = .;
- *(.data)
- output_len = . - 4;
- input_data_end = .;
- }
-}
diff --git a/arch/x86/boot/compressed/vmlinux_32.lds b/arch/x86/boot/compressed/vmlinux_32.lds
deleted file mode 100644
index bb3c48379c40..000000000000
--- a/arch/x86/boot/compressed/vmlinux_32.lds
+++ /dev/null
@@ -1,43 +0,0 @@
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-ENTRY(startup_32)
-SECTIONS
-{
- /* Be careful parts of head_32.S assume startup_32 is at
- * address 0.
- */
- . = 0;
- .text.head : {
- _head = . ;
- *(.text.head)
- _ehead = . ;
- }
- .rodata.compressed : {
- *(.rodata.compressed)
- }
- .text : {
- _text = .; /* Text */
- *(.text)
- *(.text.*)
- _etext = . ;
- }
- .rodata : {
- _rodata = . ;
- *(.rodata) /* read-only data */
- *(.rodata.*)
- _erodata = . ;
- }
- .data : {
- _data = . ;
- *(.data)
- *(.data.*)
- _edata = . ;
- }
- .bss : {
- _bss = . ;
- *(.bss)
- *(.bss.*)
- *(COMMON)
- _end = . ;
- }
-}
diff --git a/arch/x86/boot/edd.c b/arch/x86/boot/edd.c
index 1aae8f3e5ca1..c501a5b466f8 100644
--- a/arch/x86/boot/edd.c
+++ b/arch/x86/boot/edd.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -22,17 +23,17 @@
*/
static int read_mbr(u8 devno, void *buf)
{
- u16 ax, bx, cx, dx;
+ struct biosregs ireg, oreg;
- ax = 0x0201; /* Legacy Read, one sector */
- cx = 0x0001; /* Sector 0-0-1 */
- dx = devno;
- bx = (size_t)buf;
- asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
- : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
- : : "esi", "edi", "memory");
+ initregs(&ireg);
+ ireg.ax = 0x0201; /* Legacy Read, one sector */
+ ireg.cx = 0x0001; /* Sector 0-0-1 */
+ ireg.dl = devno;
+ ireg.bx = (size_t)buf;
- return -(u8)ax; /* 0 or -1 */
+ intcall(0x13, &ireg, &oreg);
+
+ return -(oreg.eflags & X86_EFLAGS_CF); /* 0 or -1 */
}
static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig)
@@ -72,56 +73,46 @@ static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig)
static int get_edd_info(u8 devno, struct edd_info *ei)
{
- u16 ax, bx, cx, dx, di;
+ struct biosregs ireg, oreg;
memset(ei, 0, sizeof *ei);
/* Check Extensions Present */
- ax = 0x4100;
- bx = EDDMAGIC1;
- dx = devno;
- asm("pushfl; stc; int $0x13; setc %%al; popfl"
- : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
- : : "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x41;
+ ireg.bx = EDDMAGIC1;
+ ireg.dl = devno;
+ intcall(0x13, &ireg, &oreg);
- if ((u8)ax)
+ if (oreg.eflags & X86_EFLAGS_CF)
return -1; /* No extended information */
- if (bx != EDDMAGIC2)
+ if (oreg.bx != EDDMAGIC2)
return -1;
ei->device = devno;
- ei->version = ax >> 8; /* EDD version number */
- ei->interface_support = cx; /* EDD functionality subsets */
+ ei->version = oreg.ah; /* EDD version number */
+ ei->interface_support = oreg.cx; /* EDD functionality subsets */
/* Extended Get Device Parameters */
ei->params.length = sizeof(ei->params);
- ax = 0x4800;
- dx = devno;
- asm("pushfl; int $0x13; popfl"
- : "+a" (ax), "+d" (dx), "=m" (ei->params)
- : "S" (&ei->params)
- : "ebx", "ecx", "edi");
+ ireg.ah = 0x48;
+ ireg.si = (size_t)&ei->params;
+ intcall(0x13, &ireg, &oreg);
/* Get legacy CHS parameters */
/* Ralf Brown recommends setting ES:DI to 0:0 */
- ax = 0x0800;
- dx = devno;
- di = 0;
- asm("pushw %%es; "
- "movw %%di,%%es; "
- "pushfl; stc; int $0x13; setc %%al; popfl; "
- "popw %%es"
- : "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
- : : "esi");
-
- if ((u8)ax == 0) {
- ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
- ei->legacy_max_head = dx >> 8;
- ei->legacy_sectors_per_track = cx & 0x3f;
+ ireg.ah = 0x08;
+ ireg.es = 0;
+ intcall(0x13, &ireg, &oreg);
+
+ if (!(oreg.eflags & X86_EFLAGS_CF)) {
+ ei->legacy_max_cylinder = oreg.ch + ((oreg.cl & 0xc0) << 2);
+ ei->legacy_max_head = oreg.dh;
+ ei->legacy_sectors_per_track = oreg.cl & 0x3f;
}
return 0;
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 5d84d1c74e4c..486d97fa7f4d 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -221,7 +221,7 @@ setup_data: .quad 0 # 64-bit physical pointer to
# End of setup header #####################################################
- .section ".inittext", "ax"
+ .section ".entrytext", "ax"
start_of_setup:
#ifdef SAFE_RESET_DISK_CONTROLLER
# Reset the disk controller.
diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c
index 58f0415d3ae0..140172b895bd 100644
--- a/arch/x86/boot/main.c
+++ b/arch/x86/boot/main.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -61,11 +62,10 @@ static void copy_boot_params(void)
*/
static void keyboard_set_repeat(void)
{
- u16 ax = 0x0305;
- u16 bx = 0;
- asm volatile("int $0x16"
- : "+a" (ax), "+b" (bx)
- : : "ecx", "edx", "esi", "edi");
+ struct biosregs ireg;
+ initregs(&ireg);
+ ireg.ax = 0x0305;
+ intcall(0x16, &ireg, NULL);
}
/*
@@ -73,18 +73,22 @@ static void keyboard_set_repeat(void)
*/
static void query_ist(void)
{
+ struct biosregs ireg, oreg;
+
/* Some older BIOSes apparently crash on this call, so filter
it from machines too old to have SpeedStep at all. */
if (cpu.level < 6)
return;
- asm("int $0x15"
- : "=a" (boot_params.ist_info.signature),
- "=b" (boot_params.ist_info.command),
- "=c" (boot_params.ist_info.event),
- "=d" (boot_params.ist_info.perf_level)
- : "a" (0x0000e980), /* IST Support */
- "d" (0x47534943)); /* Request value */
+ initregs(&ireg);
+ ireg.ax = 0xe980; /* IST Support */
+ ireg.edx = 0x47534943; /* Request value */
+ intcall(0x15, &ireg, &oreg);
+
+ boot_params.ist_info.signature = oreg.eax;
+ boot_params.ist_info.command = oreg.ebx;
+ boot_params.ist_info.event = oreg.ecx;
+ boot_params.ist_info.perf_level = oreg.edx;
}
/*
@@ -93,13 +97,12 @@ static void query_ist(void)
static void set_bios_mode(void)
{
#ifdef CONFIG_X86_64
- u32 eax, ebx;
+ struct biosregs ireg;
- eax = 0xec00;
- ebx = 2;
- asm volatile("int $0x15"
- : "+a" (eax), "+b" (ebx)
- : : "ecx", "edx", "esi", "edi");
+ initregs(&ireg);
+ ireg.ax = 0xec00;
+ ireg.bx = 2;
+ intcall(0x15, &ireg, NULL);
#endif
}
diff --git a/arch/x86/boot/mca.c b/arch/x86/boot/mca.c
index 911eaae5d696..a95a531148ef 100644
--- a/arch/x86/boot/mca.c
+++ b/arch/x86/boot/mca.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -16,26 +17,22 @@
int query_mca(void)
{
- u8 err;
- u16 es, bx, len;
-
- asm("pushw %%es ; "
- "int $0x15 ; "
- "setc %0 ; "
- "movw %%es, %1 ; "
- "popw %%es"
- : "=acd" (err), "=acdSD" (es), "=b" (bx)
- : "a" (0xc000));
-
- if (err)
+ struct biosregs ireg, oreg;
+ u16 len;
+
+ initregs(&ireg);
+ ireg.ah = 0xc0;
+ intcall(0x15, &ireg, &oreg);
+
+ if (oreg.eflags & X86_EFLAGS_CF)
return -1; /* No MCA present */
- set_fs(es);
- len = rdfs16(bx);
+ set_fs(oreg.es);
+ len = rdfs16(oreg.bx);
if (len > sizeof(boot_params.sys_desc_table))
len = sizeof(boot_params.sys_desc_table);
- copy_from_fs(&boot_params.sys_desc_table, bx, len);
+ copy_from_fs(&boot_params.sys_desc_table, oreg.bx, len);
return 0;
}
diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
index 5054c2ddd1a0..d989de810cac 100644
--- a/arch/x86/boot/memory.c
+++ b/arch/x86/boot/memory.c
@@ -25,12 +25,16 @@ struct e820_ext_entry {
static int detect_memory_e820(void)
{
int count = 0;
- u32 next = 0;
- u32 size, id, edi;
- u8 err;
+ struct biosregs ireg, oreg;
struct e820entry *desc = boot_params.e820_map;
static struct e820_ext_entry buf; /* static so it is zeroed */
+ initregs(&ireg);
+ ireg.ax = 0xe820;
+ ireg.cx = sizeof buf;
+ ireg.edx = SMAP;
+ ireg.di = (size_t)&buf;
+
/*
* Set this here so that if the BIOS doesn't change this field
* but still doesn't change %ecx, we're still okay...
@@ -38,22 +42,13 @@ static int detect_memory_e820(void)
buf.ext_flags = 1;
do {
- size = sizeof buf;
-
- /* Important: %edx and %esi are clobbered by some BIOSes,
- so they must be either used for the error output
- or explicitly marked clobbered. Given that, assume there
- is something out there clobbering %ebp and %edi, too. */
- asm("pushl %%ebp; int $0x15; popl %%ebp; setc %0"
- : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
- "=D" (edi), "+m" (buf)
- : "D" (&buf), "d" (SMAP), "a" (0xe820)
- : "esi");
+ intcall(0x15, &ireg, &oreg);
+ ireg.ebx = oreg.ebx; /* for next iteration... */
/* BIOSes which terminate the chain with CF = 1 as opposed
to %ebx = 0 don't always report the SMAP signature on
the final, failing, probe. */
- if (err)
+ if (oreg.eflags & X86_EFLAGS_CF)
break;
/* Some BIOSes stop returning SMAP in the middle of
@@ -61,7 +56,7 @@ static int detect_memory_e820(void)
screwed up the map at that point, we might have a
partial map, the full map, or complete garbage, so
just return failure. */
- if (id != SMAP) {
+ if (oreg.eax != SMAP) {
count = 0;
break;
}
@@ -69,58 +64,62 @@ static int detect_memory_e820(void)
/* ACPI 3.0 added the extended flags support. If bit 0
in the extended flags is zero, we're supposed to simply
ignore the entry -- a backwards incompatible change! */
- if (size > 20 && !(buf.ext_flags & 1))
+ if (oreg.cx > 20 && !(buf.ext_flags & 1))
continue;
*desc++ = buf.std;
count++;
- } while (next && count < ARRAY_SIZE(boot_params.e820_map));
+ } while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_map));
return boot_params.e820_entries = count;
}
static int detect_memory_e801(void)
{
- u16 ax, bx, cx, dx;
- u8 err;
+ struct biosregs ireg, oreg;
- bx = cx = dx = 0;
- ax = 0xe801;
- asm("stc; int $0x15; setc %0"
- : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
+ initregs(&ireg);
+ ireg.ax = 0xe801;
+ intcall(0x15, &ireg, &oreg);
- if (err)
+ if (oreg.eflags & X86_EFLAGS_CF)
return -1;
/* Do we really need to do this? */
- if (cx || dx) {
- ax = cx;
- bx = dx;
+ if (oreg.cx || oreg.dx) {
+ oreg.ax = oreg.cx;
+ oreg.bx = oreg.dx;
}
- if (ax > 15*1024)
+ if (oreg.ax > 15*1024) {
return -1; /* Bogus! */
-
- /* This ignores memory above 16MB if we have a memory hole
- there. If someone actually finds a machine with a memory
- hole at 16MB and no support for 0E820h they should probably
- generate a fake e820 map. */
- boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
+ } else if (oreg.ax == 15*1024) {
+ boot_params.alt_mem_k = (oreg.dx << 6) + oreg.ax;
+ } else {
+ /*
+ * This ignores memory above 16MB if we have a memory
+ * hole there. If someone actually finds a machine
+ * with a memory hole at 16MB and no support for
+ * 0E820h they should probably generate a fake e820
+ * map.
+ */
+ boot_params.alt_mem_k = oreg.ax;
+ }
return 0;
}
static int detect_memory_88(void)
{
- u16 ax;
- u8 err;
+ struct biosregs ireg, oreg;
- ax = 0x8800;
- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
+ initregs(&ireg);
+ ireg.ah = 0x88;
+ intcall(0x15, &ireg, &oreg);
- boot_params.screen_info.ext_mem_k = ax;
+ boot_params.screen_info.ext_mem_k = oreg.ax;
- return -err;
+ return -(oreg.eflags & X86_EFLAGS_CF); /* 0 or -1 */
}
int detect_memory(void)
diff --git a/arch/x86/boot/regs.c b/arch/x86/boot/regs.c
new file mode 100644
index 000000000000..958019b1cfa5
--- /dev/null
+++ b/arch/x86/boot/regs.c
@@ -0,0 +1,29 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
+ *
+ * This file is part of the Linux kernel, and is made available under
+ * the terms of the GNU General Public License version 2 or (at your
+ * option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Simple helper function for initializing a register set.
+ *
+ * Note that this sets EFLAGS_CF in the input register set; this
+ * makes it easier to catch functions which do nothing but don't
+ * explicitly set CF.
+ */
+
+#include "boot.h"
+
+void initregs(struct biosregs *reg)
+{
+ memset(reg, 0, sizeof *reg);
+ reg->eflags |= X86_EFLAGS_CF;
+ reg->ds = ds();
+ reg->es = ds();
+ reg->fs = fs();
+ reg->gs = gs();
+}
diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld
index bb8dc2de7969..0f6ec455a2b1 100644
--- a/arch/x86/boot/setup.ld
+++ b/arch/x86/boot/setup.ld
@@ -15,8 +15,11 @@ SECTIONS
. = 497;
.header : { *(.header) }
+ .entrytext : { *(.entrytext) }
.inittext : { *(.inittext) }
.initdata : { *(.initdata) }
+ __end_init = .;
+
.text : { *(.text) }
.text32 : { *(.text32) }
@@ -52,4 +55,7 @@ SECTIONS
. = ASSERT(_end <= 0x8000, "Setup too big!");
. = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
+ /* Necessary for the very-old-loader check to work... */
+ . = ASSERT(__end_init <= 5*512, "init sections too big!");
+
}
diff --git a/arch/x86/boot/tty.c b/arch/x86/boot/tty.c
index 7e8e8b25f5f6..01ec69c901c7 100644
--- a/arch/x86/boot/tty.c
+++ b/arch/x86/boot/tty.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -22,24 +23,23 @@
void __attribute__((section(".inittext"))) putchar(int ch)
{
- unsigned char c = ch;
+ struct biosregs ireg;
- if (c == '\n')
+ if (ch == '\n')
putchar('\r'); /* \n -> \r\n */
- /* int $0x10 is known to have bugs involving touching registers
- it shouldn't. Be extra conservative... */
- asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal"
- : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
+ initregs(&ireg);
+ ireg.bx = 0x0007;
+ ireg.cx = 0x0001;
+ ireg.ah = 0x0e;
+ ireg.al = ch;
+ intcall(0x10, &ireg, NULL);
}
void __attribute__((section(".inittext"))) puts(const char *str)
{
- int n = 0;
- while (*str) {
+ while (*str)
putchar(*str++);
- n++;
- }
}
/*
@@ -49,14 +49,13 @@ void __attribute__((section(".inittext"))) puts(const char *str)
static u8 gettime(void)
{
- u16 ax = 0x0200;
- u16 cx, dx;
+ struct biosregs ireg, oreg;
- asm volatile("int $0x1a"
- : "+a" (ax), "=c" (cx), "=d" (dx)
- : : "ebx", "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x02;
+ intcall(0x1a, &ireg, &oreg);
- return dx >> 8;
+ return oreg.dh;
}
/*
@@ -64,19 +63,24 @@ static u8 gettime(void)
*/
int getchar(void)
{
- u16 ax = 0;
- asm volatile("int $0x16" : "+a" (ax));
+ struct biosregs ireg, oreg;
+
+ initregs(&ireg);
+ /* ireg.ah = 0x00; */
+ intcall(0x16, &ireg, &oreg);
- return ax & 0xff;
+ return oreg.al;
}
static int kbd_pending(void)
{
- u8 pending;
- asm volatile("int $0x16; setnz %0"
- : "=qm" (pending)
- : "a" (0x0100));
- return pending;
+ struct biosregs ireg, oreg;
+
+ initregs(&ireg);
+ ireg.ah = 0x01;
+ intcall(0x16, &ireg, &oreg);
+
+ return !(oreg.eflags & X86_EFLAGS_ZF);
}
void kbd_flush(void)
diff --git a/arch/x86/boot/video-bios.c b/arch/x86/boot/video-bios.c
index 3fa979c9c363..d660be492363 100644
--- a/arch/x86/boot/video-bios.c
+++ b/arch/x86/boot/video-bios.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -29,21 +30,21 @@ static int bios_set_mode(struct mode_info *mi)
static int set_bios_mode(u8 mode)
{
- u16 ax;
+ struct biosregs ireg, oreg;
u8 new_mode;
- ax = mode; /* AH=0x00 Set Video Mode */
- asm volatile(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
+ initregs(&ireg);
+ ireg.al = mode; /* AH=0x00 Set Video Mode */
+ intcall(0x10, &ireg, NULL);
- ax = 0x0f00; /* Get Current Video Mode */
- asm volatile(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
+
+ ireg.ah = 0x0f; /* Get Current Video Mode */
+ intcall(0x10, &ireg, &oreg);
do_restore = 1; /* Assume video contents were lost */
- new_mode = ax & 0x7f; /* Not all BIOSes are clean with the top bit */
+
+ /* Not all BIOSes are clean with the top bit */
+ new_mode = ireg.al & 0x7f;
if (new_mode == mode)
return 0; /* Mode change OK */
@@ -53,10 +54,8 @@ static int set_bios_mode(u8 mode)
/* Mode setting failed, but we didn't end up where we
started. That's bad. Try to revert to the original
video mode. */
- ax = boot_params.screen_info.orig_video_mode;
- asm volatile(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
+ ireg.ax = boot_params.screen_info.orig_video_mode;
+ intcall(0x10, &ireg, NULL);
}
#endif
return -1;
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
index 4a58c8ce3f69..c700147d6ffb 100644
--- a/arch/x86/boot/video-vesa.c
+++ b/arch/x86/boot/video-vesa.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -31,7 +32,7 @@ static inline void vesa_store_mode_params_graphics(void) {}
static int vesa_probe(void)
{
#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
- u16 ax, cx, di;
+ struct biosregs ireg, oreg;
u16 mode;
addr_t mode_ptr;
struct mode_info *mi;
@@ -39,13 +40,12 @@ static int vesa_probe(void)
video_vesa.modes = GET_HEAP(struct mode_info, 0);
- ax = 0x4f00;
- di = (size_t)&vginfo;
- asm(INT10
- : "+a" (ax), "+D" (di), "=m" (vginfo)
- : : "ebx", "ecx", "edx", "esi");
+ initregs(&ireg);
+ ireg.ax = 0x4f00;
+ ireg.di = (size_t)&vginfo;
+ intcall(0x10, &ireg, &oreg);
- if (ax != 0x004f ||
+ if (ireg.ax != 0x004f ||
vginfo.signature != VESA_MAGIC ||
vginfo.version < 0x0102)
return 0; /* Not present */
@@ -65,14 +65,12 @@ static int vesa_probe(void)
memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
- ax = 0x4f01;
- cx = mode;
- di = (size_t)&vminfo;
- asm(INT10
- : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
- : : "ebx", "edx", "esi");
+ ireg.ax = 0x4f01;
+ ireg.cx = mode;
+ ireg.di = (size_t)&vminfo;
+ intcall(0x10, &ireg, &oreg);
- if (ax != 0x004f)
+ if (ireg.ax != 0x004f)
continue;
if ((vminfo.mode_attr & 0x15) == 0x05) {
@@ -111,20 +109,19 @@ static int vesa_probe(void)
static int vesa_set_mode(struct mode_info *mode)
{
- u16 ax, bx, cx, di;
+ struct biosregs ireg, oreg;
int is_graphic;
u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
- ax = 0x4f01;
- cx = vesa_mode;
- di = (size_t)&vminfo;
- asm(INT10
- : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
- : : "ebx", "edx", "esi");
+ initregs(&ireg);
+ ireg.ax = 0x4f01;
+ ireg.cx = vesa_mode;
+ ireg.di = (size_t)&vminfo;
+ intcall(0x10, &ireg, &oreg);
- if (ax != 0x004f)
+ if (oreg.ax != 0x004f)
return -1;
if ((vminfo.mode_attr & 0x15) == 0x05) {
@@ -141,14 +138,12 @@ static int vesa_set_mode(struct mode_info *mode)
}
- ax = 0x4f02;
- bx = vesa_mode;
- di = 0;
- asm volatile(INT10
- : "+a" (ax), "+b" (bx), "+D" (di)
- : : "ecx", "edx", "esi");
+ initregs(&ireg);
+ ireg.ax = 0x4f02;
+ ireg.bx = vesa_mode;
+ intcall(0x10, &ireg, &oreg);
- if (ax != 0x004f)
+ if (oreg.ax != 0x004f)
return -1;
graphic_mode = is_graphic;
@@ -171,50 +166,45 @@ static int vesa_set_mode(struct mode_info *mode)
/* Switch DAC to 8-bit mode */
static void vesa_dac_set_8bits(void)
{
+ struct biosregs ireg, oreg;
u8 dac_size = 6;
/* If possible, switch the DAC to 8-bit mode */
if (vginfo.capabilities & 1) {
- u16 ax, bx;
-
- ax = 0x4f08;
- bx = 0x0800;
- asm volatile(INT10
- : "+a" (ax), "+b" (bx)
- : : "ecx", "edx", "esi", "edi");
-
- if (ax == 0x004f)
- dac_size = bx >> 8;
+ initregs(&ireg);
+ ireg.ax = 0x4f08;
+ ireg.bh = 0x08;
+ intcall(0x10, &ireg, &oreg);
+ if (oreg.ax == 0x004f)
+ dac_size = oreg.bh;
}
/* Set the color sizes to the DAC size, and offsets to 0 */
- boot_params.screen_info.red_size = dac_size;
+ boot_params.screen_info.red_size = dac_size;
boot_params.screen_info.green_size = dac_size;
- boot_params.screen_info.blue_size = dac_size;
- boot_params.screen_info.rsvd_size = dac_size;
+ boot_params.screen_info.blue_size = dac_size;
+ boot_params.screen_info.rsvd_size = dac_size;
- boot_params.screen_info.red_pos = 0;
- boot_params.screen_info.green_pos = 0;
- boot_params.screen_info.blue_pos = 0;
- boot_params.screen_info.rsvd_pos = 0;
+ boot_params.screen_info.red_pos = 0;
+ boot_params.screen_info.green_pos = 0;
+ boot_params.screen_info.blue_pos = 0;
+ boot_params.screen_info.rsvd_pos = 0;
}
/* Save the VESA protected mode info */
static void vesa_store_pm_info(void)
{
- u16 ax, bx, di, es;
+ struct biosregs ireg, oreg;
- ax = 0x4f0a;
- bx = di = 0;
- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
- : : "ecx", "esi");
+ initregs(&ireg);
+ ireg.ax = 0x4f0a;
+ intcall(0x10, &ireg, &oreg);
- if (ax != 0x004f)
+ if (oreg.ax != 0x004f)
return;
- boot_params.screen_info.vesapm_seg = es;
- boot_params.screen_info.vesapm_off = di;
+ boot_params.screen_info.vesapm_seg = oreg.es;
+ boot_params.screen_info.vesapm_off = oreg.di;
}
/*
@@ -252,7 +242,7 @@ static void vesa_store_mode_params_graphics(void)
void vesa_store_edid(void)
{
#ifdef CONFIG_FIRMWARE_EDID
- u16 ax, bx, cx, dx, di;
+ struct biosregs ireg, oreg;
/* Apparently used as a nonsense token... */
memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
@@ -260,33 +250,26 @@ void vesa_store_edid(void)
if (vginfo.version < 0x0200)
return; /* EDID requires VBE 2.0+ */
- ax = 0x4f15; /* VBE DDC */
- bx = 0x0000; /* Report DDC capabilities */
- cx = 0; /* Controller 0 */
- di = 0; /* ES:DI must be 0 by spec */
-
- /* Note: The VBE DDC spec is different from the main VESA spec;
- we genuinely have to assume all registers are destroyed here. */
-
- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
- : "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
- : : "esi", "edx");
+ initregs(&ireg);
+ ireg.ax = 0x4f15; /* VBE DDC */
+ /* ireg.bx = 0x0000; */ /* Report DDC capabilities */
+ /* ireg.cx = 0; */ /* Controller 0 */
+ ireg.es = 0; /* ES:DI must be 0 by spec */
+ intcall(0x10, &ireg, &oreg);
- if (ax != 0x004f)
+ if (oreg.ax != 0x004f)
return; /* No EDID */
/* BH = time in seconds to transfer EDD information */
/* BL = DDC level supported */
- ax = 0x4f15; /* VBE DDC */
- bx = 0x0001; /* Read EDID */
- cx = 0; /* Controller 0 */
- dx = 0; /* EDID block number */
- di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
- asm(INT10
- : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info),
- "+c" (cx), "+D" (di)
- : : "esi");
+ ireg.ax = 0x4f15; /* VBE DDC */
+ ireg.bx = 0x0001; /* Read EDID */
+ /* ireg.cx = 0; */ /* Controller 0 */
+ /* ireg.dx = 0; */ /* EDID block number */
+ ireg.es = ds();
+ ireg.di =(size_t)&boot_params.edid_info; /* (ES:)Pointer to block */
+ intcall(0x10, &ireg, &oreg);
#endif /* CONFIG_FIRMWARE_EDID */
}
diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c
index 9e0587a37768..8f8d827e254d 100644
--- a/arch/x86/boot/video-vga.c
+++ b/arch/x86/boot/video-vga.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -39,30 +40,30 @@ static __videocard video_vga;
/* Set basic 80x25 mode */
static u8 vga_set_basic_mode(void)
{
+ struct biosregs ireg, oreg;
u16 ax;
u8 rows;
u8 mode;
+ initregs(&ireg);
+
#ifdef CONFIG_VIDEO_400_HACK
if (adapter >= ADAPTER_VGA) {
- asm volatile(INT10
- : : "a" (0x1202), "b" (0x0030)
- : "ecx", "edx", "esi", "edi");
+ ireg.ax = 0x1202;
+ ireg.bx = 0x0030;
+ intcall(0x10, &ireg, NULL);
}
#endif
ax = 0x0f00;
- asm volatile(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
-
- mode = (u8)ax;
+ intcall(0x10, &ireg, &oreg);
+ mode = oreg.al;
set_fs(0);
rows = rdfs8(0x484); /* rows minus one */
#ifndef CONFIG_VIDEO_400_HACK
- if ((ax == 0x5003 || ax == 0x5007) &&
+ if ((oreg.ax == 0x5003 || oreg.ax == 0x5007) &&
(rows == 0 || rows == 24))
return mode;
#endif
@@ -71,10 +72,8 @@ static u8 vga_set_basic_mode(void)
mode = 3;
/* Set the mode */
- ax = mode;
- asm volatile(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
+ ireg.ax = mode; /* AH=0: set mode */
+ intcall(0x10, &ireg, NULL);
do_restore = 1;
return mode;
}
@@ -82,43 +81,69 @@ static u8 vga_set_basic_mode(void)
static void vga_set_8font(void)
{
/* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
+ struct biosregs ireg;
+
+ initregs(&ireg);
/* Set 8x8 font */
- asm volatile(INT10 : : "a" (0x1112), "b" (0));
+ ireg.ax = 0x1112;
+ /* ireg.bl = 0; */
+ intcall(0x10, &ireg, NULL);
/* Use alternate print screen */
- asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
+ ireg.ax = 0x1200;
+ ireg.bl = 0x20;
+ intcall(0x10, &ireg, NULL);
/* Turn off cursor emulation */
- asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+ ireg.ax = 0x1201;
+ ireg.bl = 0x34;
+ intcall(0x10, &ireg, NULL);
/* Cursor is scan lines 6-7 */
- asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
+ ireg.ax = 0x0100;
+ ireg.cx = 0x0607;
+ intcall(0x10, &ireg, NULL);
}
static void vga_set_14font(void)
{
/* Set 9x14 font - 80x28 on VGA */
+ struct biosregs ireg;
+
+ initregs(&ireg);
/* Set 9x14 font */
- asm volatile(INT10 : : "a" (0x1111), "b" (0));
+ ireg.ax = 0x1111;
+ /* ireg.bl = 0; */
+ intcall(0x10, &ireg, NULL);
/* Turn off cursor emulation */
- asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+ ireg.ax = 0x1201;
+ ireg.bl = 0x34;
+ intcall(0x10, &ireg, NULL);
/* Cursor is scan lines 11-12 */
- asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
+ ireg.ax = 0x0100;
+ ireg.cx = 0x0b0c;
+ intcall(0x10, &ireg, NULL);
}
static void vga_set_80x43(void)
{
/* Set 80x43 mode on VGA (not EGA) */
+ struct biosregs ireg;
+
+ initregs(&ireg);
/* Set 350 scans */
- asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
+ ireg.ax = 0x1201;
+ ireg.bl = 0x30;
+ intcall(0x10, &ireg, NULL);
/* Reset video mode */
- asm volatile(INT10 : : "a" (0x0003));
+ ireg.ax = 0x0003;
+ intcall(0x10, &ireg, NULL);
vga_set_8font();
}
@@ -225,8 +250,6 @@ static int vga_set_mode(struct mode_info *mode)
*/
static int vga_probe(void)
{
- u16 ega_bx;
-
static const char *card_name[] = {
"CGA/MDA/HGC", "EGA", "VGA"
};
@@ -240,26 +263,26 @@ static int vga_probe(void)
sizeof(ega_modes)/sizeof(struct mode_info),
sizeof(vga_modes)/sizeof(struct mode_info),
};
- u8 vga_flag;
- asm(INT10
- : "=b" (ega_bx)
- : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
- : "ecx", "edx", "esi", "edi");
+ struct biosregs ireg, oreg;
+
+ initregs(&ireg);
+
+ ireg.ax = 0x1200;
+ ireg.bl = 0x10; /* Check EGA/VGA */
+ intcall(0x10, &ireg, &oreg);
#ifndef _WAKEUP
- boot_params.screen_info.orig_video_ega_bx = ega_bx;
+ boot_params.screen_info.orig_video_ega_bx = oreg.bx;
#endif
/* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
- if ((u8)ega_bx != 0x10) {
+ if (oreg.bl != 0x10) {
/* EGA/VGA */
- asm(INT10
- : "=a" (vga_flag)
- : "a" (0x1a00)
- : "ebx", "ecx", "edx", "esi", "edi");
+ ireg.ax = 0x1a00;
+ intcall(0x10, &ireg, &oreg);
- if (vga_flag == 0x1a) {
+ if (oreg.al == 0x1a) {
adapter = ADAPTER_VGA;
#ifndef _WAKEUP
boot_params.screen_info.orig_video_isVGA = 1;
diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c
index 3bef2c1febe9..bad728b76fc2 100644
--- a/arch/x86/boot/video.c
+++ b/arch/x86/boot/video.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -18,33 +19,29 @@
static void store_cursor_position(void)
{
- u16 curpos;
- u16 ax, bx;
+ struct biosregs ireg, oreg;
- ax = 0x0300;
- bx = 0;
- asm(INT10
- : "=d" (curpos), "+a" (ax), "+b" (bx)
- : : "ecx", "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x03;
+ intcall(0x10, &ireg, &oreg);
- boot_params.screen_info.orig_x = curpos;
- boot_params.screen_info.orig_y = curpos >> 8;
+ boot_params.screen_info.orig_x = oreg.dl;
+ boot_params.screen_info.orig_y = oreg.dh;
}
static void store_video_mode(void)
{
- u16 ax, page;
+ struct biosregs ireg, oreg;
/* N.B.: the saving of the video page here is a bit silly,
since we pretty much assume page 0 everywhere. */
- ax = 0x0f00;
- asm(INT10
- : "+a" (ax), "=b" (page)
- : : "ecx", "edx", "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x0f;
+ intcall(0x10, &ireg, &oreg);
/* Not all BIOSes are clean with respect to the top bit */
- boot_params.screen_info.orig_video_mode = ax & 0x7f;
- boot_params.screen_info.orig_video_page = page >> 8;
+ boot_params.screen_info.orig_video_mode = oreg.al & 0x7f;
+ boot_params.screen_info.orig_video_page = oreg.bh;
}
/*
@@ -257,7 +254,7 @@ static void restore_screen(void)
int y;
addr_t dst = 0;
u16 *src = saved.data;
- u16 ax, bx, dx;
+ struct biosregs ireg;
if (graphic_mode)
return; /* Can't restore onto a graphic mode */
@@ -296,12 +293,11 @@ static void restore_screen(void)
}
/* Restore cursor position */
- ax = 0x0200; /* Set cursor position */
- bx = 0; /* Page number (<< 8) */
- dx = (saved.cury << 8)+saved.curx;
- asm volatile(INT10
- : "+a" (ax), "+b" (bx), "+d" (dx)
- : : "ecx", "esi", "edi");
+ initregs(&ireg);
+ ireg.ah = 0x02; /* Set cursor position */
+ ireg.dh = saved.cury;
+ ireg.dl = saved.curx;
+ intcall(0x10, &ireg, NULL);
}
#else
#define save_screen() ((void)0)
diff --git a/arch/x86/boot/video.h b/arch/x86/boot/video.h
index ee63f5d14461..5bb174a997fc 100644
--- a/arch/x86/boot/video.h
+++ b/arch/x86/boot/video.h
@@ -112,20 +112,6 @@ extern int force_x, force_y; /* Don't query the BIOS for cols/rows */
extern int do_restore; /* Restore screen contents */
extern int graphic_mode; /* Graphics mode with linear frame buffer */
-/*
- * int $0x10 is notorious for touching registers it shouldn't.
- * gcc doesn't like %ebp being clobbered, so define it as a push/pop
- * sequence here.
- *
- * A number of systems, including the original PC can clobber %bp in
- * certain circumstances, like when scrolling. There exists at least
- * one Trident video card which could clobber DS under a set of
- * circumstances that we are unlikely to encounter (scrolling when
- * using an extended graphics mode of more than 800x600 pixels), but
- * it's cheap insurance to deal with that here.
- */
-#define INT10 "pushl %%ebp; pushw %%ds; int $0x10; popw %%ds; popl %%ebp"
-
/* Accessing VGA indexed registers */
static inline u8 in_idx(u16 port, u8 index)
{
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
index 9fe5d212ab4c..27b8ce0f5908 100644
--- a/arch/x86/configs/x86_64_defconfig
+++ b/arch/x86/configs/x86_64_defconfig
@@ -195,7 +195,6 @@ CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_SMP=y
CONFIG_SPARSE_IRQ=y
-# CONFIG_NUMA_MIGRATE_IRQ_DESC is not set
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
# CONFIG_X86_ELAN is not set
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index ebe7deedd5b4..cfb0010fa940 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -2,6 +2,8 @@
# Arch-specific CryptoAPI modules.
#
+obj-$(CONFIG_CRYPTO_FPU) += fpu.o
+
obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 02af0af65497..4e663398f77f 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -21,6 +21,22 @@
#include <asm/i387.h>
#include <asm/aes.h>
+#if defined(CONFIG_CRYPTO_CTR) || defined(CONFIG_CRYPTO_CTR_MODULE)
+#define HAS_CTR
+#endif
+
+#if defined(CONFIG_CRYPTO_LRW) || defined(CONFIG_CRYPTO_LRW_MODULE)
+#define HAS_LRW
+#endif
+
+#if defined(CONFIG_CRYPTO_PCBC) || defined(CONFIG_CRYPTO_PCBC_MODULE)
+#define HAS_PCBC
+#endif
+
+#if defined(CONFIG_CRYPTO_XTS) || defined(CONFIG_CRYPTO_XTS_MODULE)
+#define HAS_XTS
+#endif
+
struct async_aes_ctx {
struct cryptd_ablkcipher *cryptd_tfm;
};
@@ -137,6 +153,41 @@ static struct crypto_alg aesni_alg = {
}
};
+static void __aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
+
+ aesni_enc(ctx, dst, src);
+}
+
+static void __aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
+
+ aesni_dec(ctx, dst, src);
+}
+
+static struct crypto_alg __aesni_alg = {
+ .cra_name = "__aes-aesni",
+ .cra_driver_name = "__driver-aes-aesni",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx)+AESNI_ALIGN-1,
+ .cra_alignmask = 0,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(__aesni_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = AES_MIN_KEY_SIZE,
+ .cia_max_keysize = AES_MAX_KEY_SIZE,
+ .cia_setkey = aes_set_key,
+ .cia_encrypt = __aes_encrypt,
+ .cia_decrypt = __aes_decrypt
+ }
+ }
+};
+
static int ecb_encrypt(struct blkcipher_desc *desc,
struct scatterlist *dst, struct scatterlist *src,
unsigned int nbytes)
@@ -277,8 +328,16 @@ static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key,
unsigned int key_len)
{
struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+ struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base;
+ int err;
- return crypto_ablkcipher_setkey(&ctx->cryptd_tfm->base, key, key_len);
+ crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+ crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm)
+ & CRYPTO_TFM_REQ_MASK);
+ err = crypto_ablkcipher_setkey(child, key, key_len);
+ crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child)
+ & CRYPTO_TFM_RES_MASK);
+ return err;
}
static int ablk_encrypt(struct ablkcipher_request *req)
@@ -411,6 +470,163 @@ static struct crypto_alg ablk_cbc_alg = {
},
};
+#ifdef HAS_CTR
+static int ablk_ctr_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("fpu(ctr(__driver-aes-aesni))",
+ 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_ctr_alg = {
+ .cra_name = "ctr(aes)",
+ .cra_driver_name = "ctr-aes-aesni",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct async_aes_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_ctr_alg.cra_list),
+ .cra_init = ablk_ctr_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ .geniv = "chainiv",
+ },
+ },
+};
+#endif
+
+#ifdef HAS_LRW
+static int ablk_lrw_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("fpu(lrw(__driver-aes-aesni))",
+ 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_lrw_alg = {
+ .cra_name = "lrw(aes)",
+ .cra_driver_name = "lrw-aes-aesni",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_aes_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_lrw_alg.cra_list),
+ .cra_init = ablk_lrw_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE + AES_BLOCK_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE + AES_BLOCK_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+};
+#endif
+
+#ifdef HAS_PCBC
+static int ablk_pcbc_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("fpu(pcbc(__driver-aes-aesni))",
+ 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_pcbc_alg = {
+ .cra_name = "pcbc(aes)",
+ .cra_driver_name = "pcbc-aes-aesni",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_aes_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_pcbc_alg.cra_list),
+ .cra_init = ablk_pcbc_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+};
+#endif
+
+#ifdef HAS_XTS
+static int ablk_xts_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("fpu(xts(__driver-aes-aesni))",
+ 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_xts_alg = {
+ .cra_name = "xts(aes)",
+ .cra_driver_name = "xts-aes-aesni",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_aes_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_xts_alg.cra_list),
+ .cra_init = ablk_xts_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = 2 * AES_MIN_KEY_SIZE,
+ .max_keysize = 2 * AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+};
+#endif
+
static int __init aesni_init(void)
{
int err;
@@ -421,6 +637,8 @@ static int __init aesni_init(void)
}
if ((err = crypto_register_alg(&aesni_alg)))
goto aes_err;
+ if ((err = crypto_register_alg(&__aesni_alg)))
+ goto __aes_err;
if ((err = crypto_register_alg(&blk_ecb_alg)))
goto blk_ecb_err;
if ((err = crypto_register_alg(&blk_cbc_alg)))
@@ -429,9 +647,41 @@ static int __init aesni_init(void)
goto ablk_ecb_err;
if ((err = crypto_register_alg(&ablk_cbc_alg)))
goto ablk_cbc_err;
+#ifdef HAS_CTR
+ if ((err = crypto_register_alg(&ablk_ctr_alg)))
+ goto ablk_ctr_err;
+#endif
+#ifdef HAS_LRW
+ if ((err = crypto_register_alg(&ablk_lrw_alg)))
+ goto ablk_lrw_err;
+#endif
+#ifdef HAS_PCBC
+ if ((err = crypto_register_alg(&ablk_pcbc_alg)))
+ goto ablk_pcbc_err;
+#endif
+#ifdef HAS_XTS
+ if ((err = crypto_register_alg(&ablk_xts_alg)))
+ goto ablk_xts_err;
+#endif
return err;
+#ifdef HAS_XTS
+ablk_xts_err:
+#endif
+#ifdef HAS_PCBC
+ crypto_unregister_alg(&ablk_pcbc_alg);
+ablk_pcbc_err:
+#endif
+#ifdef HAS_LRW
+ crypto_unregister_alg(&ablk_lrw_alg);
+ablk_lrw_err:
+#endif
+#ifdef HAS_CTR
+ crypto_unregister_alg(&ablk_ctr_alg);
+ablk_ctr_err:
+#endif
+ crypto_unregister_alg(&ablk_cbc_alg);
ablk_cbc_err:
crypto_unregister_alg(&ablk_ecb_alg);
ablk_ecb_err:
@@ -439,6 +689,8 @@ ablk_ecb_err:
blk_cbc_err:
crypto_unregister_alg(&blk_ecb_alg);
blk_ecb_err:
+ crypto_unregister_alg(&__aesni_alg);
+__aes_err:
crypto_unregister_alg(&aesni_alg);
aes_err:
return err;
@@ -446,10 +698,23 @@ aes_err:
static void __exit aesni_exit(void)
{
+#ifdef HAS_XTS
+ crypto_unregister_alg(&ablk_xts_alg);
+#endif
+#ifdef HAS_PCBC
+ crypto_unregister_alg(&ablk_pcbc_alg);
+#endif
+#ifdef HAS_LRW
+ crypto_unregister_alg(&ablk_lrw_alg);
+#endif
+#ifdef HAS_CTR
+ crypto_unregister_alg(&ablk_ctr_alg);
+#endif
crypto_unregister_alg(&ablk_cbc_alg);
crypto_unregister_alg(&ablk_ecb_alg);
crypto_unregister_alg(&blk_cbc_alg);
crypto_unregister_alg(&blk_ecb_alg);
+ crypto_unregister_alg(&__aesni_alg);
crypto_unregister_alg(&aesni_alg);
}
diff --git a/arch/x86/crypto/fpu.c b/arch/x86/crypto/fpu.c
new file mode 100644
index 000000000000..5f9781a3815f
--- /dev/null
+++ b/arch/x86/crypto/fpu.c
@@ -0,0 +1,166 @@
+/*
+ * FPU: Wrapper for blkcipher touching fpu
+ *
+ * Copyright (c) Intel Corp.
+ * Author: Huang Ying <ying.huang@intel.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.
+ *
+ */
+
+#include <crypto/algapi.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/i387.h>
+
+struct crypto_fpu_ctx {
+ struct crypto_blkcipher *child;
+};
+
+static int crypto_fpu_setkey(struct crypto_tfm *parent, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_fpu_ctx *ctx = crypto_tfm_ctx(parent);
+ struct crypto_blkcipher *child = ctx->child;
+ int err;
+
+ crypto_blkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+ crypto_blkcipher_set_flags(child, crypto_tfm_get_flags(parent) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_blkcipher_setkey(child, key, keylen);
+ crypto_tfm_set_flags(parent, crypto_blkcipher_get_flags(child) &
+ CRYPTO_TFM_RES_MASK);
+ return err;
+}
+
+static int crypto_fpu_encrypt(struct blkcipher_desc *desc_in,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ int err;
+ struct crypto_fpu_ctx *ctx = crypto_blkcipher_ctx(desc_in->tfm);
+ struct crypto_blkcipher *child = ctx->child;
+ struct blkcipher_desc desc = {
+ .tfm = child,
+ .info = desc_in->info,
+ .flags = desc_in->flags,
+ };
+
+ kernel_fpu_begin();
+ err = crypto_blkcipher_crt(desc.tfm)->encrypt(&desc, dst, src, nbytes);
+ kernel_fpu_end();
+ return err;
+}
+
+static int crypto_fpu_decrypt(struct blkcipher_desc *desc_in,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ int err;
+ struct crypto_fpu_ctx *ctx = crypto_blkcipher_ctx(desc_in->tfm);
+ struct crypto_blkcipher *child = ctx->child;
+ struct blkcipher_desc desc = {
+ .tfm = child,
+ .info = desc_in->info,
+ .flags = desc_in->flags,
+ };
+
+ kernel_fpu_begin();
+ err = crypto_blkcipher_crt(desc.tfm)->decrypt(&desc, dst, src, nbytes);
+ kernel_fpu_end();
+ return err;
+}
+
+static int crypto_fpu_init_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
+ struct crypto_spawn *spawn = crypto_instance_ctx(inst);
+ struct crypto_fpu_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct crypto_blkcipher *cipher;
+
+ cipher = crypto_spawn_blkcipher(spawn);
+ if (IS_ERR(cipher))
+ return PTR_ERR(cipher);
+
+ ctx->child = cipher;
+ return 0;
+}
+
+static void crypto_fpu_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_fpu_ctx *ctx = crypto_tfm_ctx(tfm);
+ crypto_free_blkcipher(ctx->child);
+}
+
+static struct crypto_instance *crypto_fpu_alloc(struct rtattr **tb)
+{
+ struct crypto_instance *inst;
+ struct crypto_alg *alg;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
+ if (err)
+ return ERR_PTR(err);
+
+ alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_BLKCIPHER,
+ CRYPTO_ALG_TYPE_MASK);
+ if (IS_ERR(alg))
+ return ERR_CAST(alg);
+
+ inst = crypto_alloc_instance("fpu", alg);
+ if (IS_ERR(inst))
+ goto out_put_alg;
+
+ inst->alg.cra_flags = alg->cra_flags;
+ inst->alg.cra_priority = alg->cra_priority;
+ inst->alg.cra_blocksize = alg->cra_blocksize;
+ inst->alg.cra_alignmask = alg->cra_alignmask;
+ inst->alg.cra_type = alg->cra_type;
+ inst->alg.cra_blkcipher.ivsize = alg->cra_blkcipher.ivsize;
+ inst->alg.cra_blkcipher.min_keysize = alg->cra_blkcipher.min_keysize;
+ inst->alg.cra_blkcipher.max_keysize = alg->cra_blkcipher.max_keysize;
+ inst->alg.cra_ctxsize = sizeof(struct crypto_fpu_ctx);
+ inst->alg.cra_init = crypto_fpu_init_tfm;
+ inst->alg.cra_exit = crypto_fpu_exit_tfm;
+ inst->alg.cra_blkcipher.setkey = crypto_fpu_setkey;
+ inst->alg.cra_blkcipher.encrypt = crypto_fpu_encrypt;
+ inst->alg.cra_blkcipher.decrypt = crypto_fpu_decrypt;
+
+out_put_alg:
+ crypto_mod_put(alg);
+ return inst;
+}
+
+static void crypto_fpu_free(struct crypto_instance *inst)
+{
+ crypto_drop_spawn(crypto_instance_ctx(inst));
+ kfree(inst);
+}
+
+static struct crypto_template crypto_fpu_tmpl = {
+ .name = "fpu",
+ .alloc = crypto_fpu_alloc,
+ .free = crypto_fpu_free,
+ .module = THIS_MODULE,
+};
+
+static int __init crypto_fpu_module_init(void)
+{
+ return crypto_register_template(&crypto_fpu_tmpl);
+}
+
+static void __exit crypto_fpu_module_exit(void)
+{
+ crypto_unregister_template(&crypto_fpu_tmpl);
+}
+
+module_init(crypto_fpu_module_init);
+module_exit(crypto_fpu_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("FPU block cipher wrapper");
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index a505202086e8..dcef387ddc36 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -830,4 +830,5 @@ ia32_sys_call_table:
.quad sys_inotify_init1
.quad compat_sys_preadv
.quad compat_sys_pwritev
+ .quad compat_sys_rt_tgsigqueueinfo /* 335 */
ia32_syscall_end:
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index f6aa18eadf71..1a37bcdc8606 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -3,6 +3,7 @@
#include <linux/types.h>
#include <linux/stddef.h>
+#include <linux/stringify.h>
#include <asm/asm.h>
/*
@@ -74,6 +75,22 @@ static inline void alternatives_smp_switch(int smp) {}
const unsigned char *const *find_nop_table(void);
+/* alternative assembly primitive: */
+#define ALTERNATIVE(oldinstr, newinstr, feature) \
+ \
+ "661:\n\t" oldinstr "\n662:\n" \
+ ".section .altinstructions,\"a\"\n" \
+ _ASM_ALIGN "\n" \
+ _ASM_PTR "661b\n" /* label */ \
+ _ASM_PTR "663f\n" /* new instruction */ \
+ " .byte " __stringify(feature) "\n" /* feature bit */ \
+ " .byte 662b-661b\n" /* sourcelen */ \
+ " .byte 664f-663f\n" /* replacementlen */ \
+ ".previous\n" \
+ ".section .altinstr_replacement, \"ax\"\n" \
+ "663:\n\t" newinstr "\n664:\n" /* replacement */ \
+ ".previous"
+
/*
* Alternative instructions for different CPU types or capabilities.
*
@@ -87,18 +104,7 @@ const unsigned char *const *find_nop_table(void);
* without volatile and memory clobber.
*/
#define alternative(oldinstr, newinstr, feature) \
- asm volatile ("661:\n\t" oldinstr "\n662:\n" \
- ".section .altinstructions,\"a\"\n" \
- _ASM_ALIGN "\n" \
- _ASM_PTR "661b\n" /* label */ \
- _ASM_PTR "663f\n" /* new instruction */ \
- " .byte %c0\n" /* feature bit */ \
- " .byte 662b-661b\n" /* sourcelen */ \
- " .byte 664f-663f\n" /* replacementlen */ \
- ".previous\n" \
- ".section .altinstr_replacement,\"ax\"\n" \
- "663:\n\t" newinstr "\n664:\n" /* replacement */ \
- ".previous" :: "i" (feature) : "memory")
+ asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) : : : "memory")
/*
* Alternative inline assembly with input.
@@ -109,35 +115,16 @@ const unsigned char *const *find_nop_table(void);
* Best is to use constraints that are fixed size (like (%1) ... "r")
* If you use variable sized constraints like "m" or "g" in the
* replacement make sure to pad to the worst case length.
+ * Leaving an unused argument 0 to keep API compatibility.
*/
#define alternative_input(oldinstr, newinstr, feature, input...) \
- asm volatile ("661:\n\t" oldinstr "\n662:\n" \
- ".section .altinstructions,\"a\"\n" \
- _ASM_ALIGN "\n" \
- _ASM_PTR "661b\n" /* label */ \
- _ASM_PTR "663f\n" /* new instruction */ \
- " .byte %c0\n" /* feature bit */ \
- " .byte 662b-661b\n" /* sourcelen */ \
- " .byte 664f-663f\n" /* replacementlen */ \
- ".previous\n" \
- ".section .altinstr_replacement,\"ax\"\n" \
- "663:\n\t" newinstr "\n664:\n" /* replacement */ \
- ".previous" :: "i" (feature), ##input)
+ asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) \
+ : : "i" (0), ## input)
/* Like alternative_input, but with a single output argument */
#define alternative_io(oldinstr, newinstr, feature, output, input...) \
- asm volatile ("661:\n\t" oldinstr "\n662:\n" \
- ".section .altinstructions,\"a\"\n" \
- _ASM_ALIGN "\n" \
- _ASM_PTR "661b\n" /* label */ \
- _ASM_PTR "663f\n" /* new instruction */ \
- " .byte %c[feat]\n" /* feature bit */ \
- " .byte 662b-661b\n" /* sourcelen */ \
- " .byte 664f-663f\n" /* replacementlen */ \
- ".previous\n" \
- ".section .altinstr_replacement,\"ax\"\n" \
- "663:\n\t" newinstr "\n664:\n" /* replacement */ \
- ".previous" : output : [feat] "i" (feature), ##input)
+ asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) \
+ : output : "i" (0), ## input)
/*
* use this macro(s) if you need more than one output parameter
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 42f2f8377422..229d0be184a2 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -107,8 +107,7 @@ extern u32 native_safe_apic_wait_icr_idle(void);
extern void native_apic_icr_write(u32 low, u32 id);
extern u64 native_apic_icr_read(void);
-#define EIM_8BIT_APIC_ID 0
-#define EIM_32BIT_APIC_ID 1
+extern int x2apic_mode;
#ifdef CONFIG_X86_X2APIC
/*
@@ -166,10 +165,9 @@ static inline u64 native_x2apic_icr_read(void)
return val;
}
-extern int x2apic, x2apic_phys;
+extern int x2apic_phys;
extern void check_x2apic(void);
extern void enable_x2apic(void);
-extern void enable_IR_x2apic(void);
extern void x2apic_icr_write(u32 low, u32 id);
static inline int x2apic_enabled(void)
{
@@ -183,6 +181,8 @@ static inline int x2apic_enabled(void)
return 1;
return 0;
}
+
+#define x2apic_supported() (cpu_has_x2apic)
#else
static inline void check_x2apic(void)
{
@@ -190,28 +190,20 @@ static inline void check_x2apic(void)
static inline void enable_x2apic(void)
{
}
-static inline void enable_IR_x2apic(void)
-{
-}
static inline int x2apic_enabled(void)
{
return 0;
}
-#define x2apic 0
-
+#define x2apic_preenabled 0
+#define x2apic_supported() 0
#endif
-extern int get_physical_broadcast(void);
+extern void enable_IR_x2apic(void);
-#ifdef CONFIG_X86_X2APIC
-static inline void ack_x2APIC_irq(void)
-{
- /* Docs say use 0 for future compatibility */
- native_apic_msr_write(APIC_EOI, 0);
-}
-#endif
+extern int get_physical_broadcast(void);
+extern void apic_disable(void);
extern int lapic_get_maxlvt(void);
extern void clear_local_APIC(void);
extern void connect_bsp_APIC(void);
@@ -252,7 +244,7 @@ static inline void lapic_shutdown(void) { }
#define local_apic_timer_c2_ok 1
static inline void init_apic_mappings(void) { }
static inline void disable_local_APIC(void) { }
-
+static inline void apic_disable(void) { }
#endif /* !CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_64
@@ -478,6 +470,9 @@ static inline unsigned int read_apic_id(void)
extern void default_setup_apic_routing(void);
#ifdef CONFIG_X86_32
+
+extern struct apic apic_default;
+
/*
* Set up the logical destination ID.
*
diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
index bc9514fb3b13..7ddb36ab933b 100644
--- a/arch/x86/include/asm/apicdef.h
+++ b/arch/x86/include/asm/apicdef.h
@@ -22,6 +22,7 @@
# define APIC_INTEGRATED(x) (1)
#endif
#define APIC_XAPIC(x) ((x) >= 0x14)
+#define APIC_EXT_SPACE(x) ((x) & 0x80000000)
#define APIC_TASKPRI 0x80
#define APIC_TPRI_MASK 0xFFu
#define APIC_ARBPRI 0x90
@@ -116,7 +117,9 @@
#define APIC_TDR_DIV_32 0x8
#define APIC_TDR_DIV_64 0x9
#define APIC_TDR_DIV_128 0xA
-#define APIC_EILVT0 0x500
+#define APIC_EFEAT 0x400
+#define APIC_ECTRL 0x410
+#define APIC_EILVTn(n) (0x500 + 0x10 * n)
#define APIC_EILVT_NR_AMD_K8 1 /* # of extended interrupts */
#define APIC_EILVT_NR_AMD_10H 4
#define APIC_EILVT_LVTOFF(x) (((x) >> 4) & 0xF)
@@ -125,9 +128,6 @@
#define APIC_EILVT_MSG_NMI 0x4
#define APIC_EILVT_MSG_EXT 0x7
#define APIC_EILVT_MASKED (1 << 16)
-#define APIC_EILVT1 0x510
-#define APIC_EILVT2 0x520
-#define APIC_EILVT3 0x530
#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
#define APIC_BASE_MSR 0x800
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index bb83b1c397aa..c0bbbf3cd67c 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -22,7 +22,7 @@
#define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */
#define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers */
#define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */
-#define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */
+#define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Exception */
#define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */
#define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */
#define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */
@@ -115,6 +115,8 @@
#define X86_FEATURE_XMM4_1 (4*32+19) /* "sse4_1" SSE-4.1 */
#define X86_FEATURE_XMM4_2 (4*32+20) /* "sse4_2" SSE-4.2 */
#define X86_FEATURE_X2APIC (4*32+21) /* x2APIC */
+#define X86_FEATURE_MOVBE (4*32+22) /* MOVBE instruction */
+#define X86_FEATURE_POPCNT (4*32+23) /* POPCNT instruction */
#define X86_FEATURE_AES (4*32+25) /* AES instructions */
#define X86_FEATURE_XSAVE (4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
#define X86_FEATURE_OSXSAVE (4*32+27) /* "" XSAVE enabled in the OS */
@@ -192,11 +194,11 @@ extern const char * const x86_power_flags[32];
#define clear_cpu_cap(c, bit) clear_bit(bit, (unsigned long *)((c)->x86_capability))
#define setup_clear_cpu_cap(bit) do { \
clear_cpu_cap(&boot_cpu_data, bit); \
- set_bit(bit, (unsigned long *)cleared_cpu_caps); \
+ set_bit(bit, (unsigned long *)cpu_caps_cleared); \
} while (0)
#define setup_force_cpu_cap(bit) do { \
set_cpu_cap(&boot_cpu_data, bit); \
- clear_bit(bit, (unsigned long *)cleared_cpu_caps); \
+ set_bit(bit, (unsigned long *)cpu_caps_set); \
} while (0)
#define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU)
diff --git a/arch/x86/include/asm/ds.h b/arch/x86/include/asm/ds.h
index a8f672ba100c..70dac199b093 100644
--- a/arch/x86/include/asm/ds.h
+++ b/arch/x86/include/asm/ds.h
@@ -15,8 +15,8 @@
* - buffer allocation (memory accounting)
*
*
- * Copyright (C) 2007-2008 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
+ * Copyright (C) 2007-2009 Intel Corporation.
+ * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
*/
#ifndef _ASM_X86_DS_H
@@ -83,8 +83,10 @@ enum ds_feature {
* The interrupt threshold is independent from the overflow callback
* to allow users to use their own overflow interrupt handling mechanism.
*
- * task: the task to request recording for;
- * NULL for per-cpu recording on the current cpu
+ * The function might sleep.
+ *
+ * task: the task to request recording for
+ * cpu: the cpu to request recording for
* base: the base pointer for the (non-pageable) buffer;
* size: the size of the provided buffer in bytes
* ovfl: pointer to a function to be called on buffer overflow;
@@ -93,19 +95,28 @@ enum ds_feature {
* -1 if no interrupt threshold is requested.
* flags: a bit-mask of the above flags
*/
-extern struct bts_tracer *ds_request_bts(struct task_struct *task,
- void *base, size_t size,
- bts_ovfl_callback_t ovfl,
- size_t th, unsigned int flags);
-extern struct pebs_tracer *ds_request_pebs(struct task_struct *task,
- void *base, size_t size,
- pebs_ovfl_callback_t ovfl,
- size_t th, unsigned int flags);
+extern struct bts_tracer *ds_request_bts_task(struct task_struct *task,
+ void *base, size_t size,
+ bts_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags);
+extern struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size,
+ bts_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags);
+extern struct pebs_tracer *ds_request_pebs_task(struct task_struct *task,
+ void *base, size_t size,
+ pebs_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags);
+extern struct pebs_tracer *ds_request_pebs_cpu(int cpu,
+ void *base, size_t size,
+ pebs_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags);
/*
* Release BTS or PEBS resources
* Suspend and resume BTS or PEBS tracing
*
+ * Must be called with irq's enabled.
+ *
* tracer: the tracer handle returned from ds_request_~()
*/
extern void ds_release_bts(struct bts_tracer *tracer);
@@ -115,6 +126,28 @@ extern void ds_release_pebs(struct pebs_tracer *tracer);
extern void ds_suspend_pebs(struct pebs_tracer *tracer);
extern void ds_resume_pebs(struct pebs_tracer *tracer);
+/*
+ * Release BTS or PEBS resources
+ * Suspend and resume BTS or PEBS tracing
+ *
+ * Cpu tracers must call this on the traced cpu.
+ * Task tracers must call ds_release_~_noirq() for themselves.
+ *
+ * May be called with irq's disabled.
+ *
+ * Returns 0 if successful;
+ * -EPERM if the cpu tracer does not trace the current cpu.
+ * -EPERM if the task tracer does not trace itself.
+ *
+ * tracer: the tracer handle returned from ds_request_~()
+ */
+extern int ds_release_bts_noirq(struct bts_tracer *tracer);
+extern int ds_suspend_bts_noirq(struct bts_tracer *tracer);
+extern int ds_resume_bts_noirq(struct bts_tracer *tracer);
+extern int ds_release_pebs_noirq(struct pebs_tracer *tracer);
+extern int ds_suspend_pebs_noirq(struct pebs_tracer *tracer);
+extern int ds_resume_pebs_noirq(struct pebs_tracer *tracer);
+
/*
* The raw DS buffer state as it is used for BTS and PEBS recording.
@@ -170,9 +203,9 @@ struct bts_struct {
} lbr;
/* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */
struct {
- __u64 jiffies;
+ __u64 clock;
pid_t pid;
- } timestamp;
+ } event;
} variant;
};
@@ -201,8 +234,12 @@ struct bts_trace {
struct pebs_trace {
struct ds_trace ds;
- /* the PEBS reset value */
- unsigned long long reset_value;
+ /* the number of valid counters in the below array */
+ unsigned int counters;
+
+#define MAX_PEBS_COUNTERS 4
+ /* the counter reset value */
+ unsigned long long counter_reset[MAX_PEBS_COUNTERS];
};
@@ -237,9 +274,11 @@ extern int ds_reset_pebs(struct pebs_tracer *tracer);
* Returns 0 on success; -Eerrno on error
*
* tracer: the tracer handle returned from ds_request_pebs()
+ * counter: the index of the counter
* value: the new counter reset value
*/
-extern int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value);
+extern int ds_set_pebs_reset(struct pebs_tracer *tracer,
+ unsigned int counter, u64 value);
/*
* Initialization
@@ -252,21 +291,12 @@ extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
*/
extern void ds_switch_to(struct task_struct *prev, struct task_struct *next);
-/*
- * Task clone/init and cleanup work
- */
-extern void ds_copy_thread(struct task_struct *tsk, struct task_struct *father);
-extern void ds_exit_thread(struct task_struct *tsk);
-
#else /* CONFIG_X86_DS */
struct cpuinfo_x86;
static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
static inline void ds_switch_to(struct task_struct *prev,
struct task_struct *next) {}
-static inline void ds_copy_thread(struct task_struct *tsk,
- struct task_struct *father) {}
-static inline void ds_exit_thread(struct task_struct *tsk) {}
#endif /* CONFIG_X86_DS */
#endif /* _ASM_X86_DS_H */
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index b762ea49bd70..be9ae4111c94 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -78,7 +78,11 @@ extern void eisa_set_level_irq(unsigned int irq);
/* SMP */
extern void smp_apic_timer_interrupt(struct pt_regs *);
extern void smp_spurious_interrupt(struct pt_regs *);
+extern void smp_generic_interrupt(struct pt_regs *);
extern void smp_error_interrupt(struct pt_regs *);
+#ifdef CONFIG_X86_IO_APIC
+extern asmlinkage void smp_irq_move_cleanup_interrupt(void);
+#endif
#ifdef CONFIG_SMP
extern void smp_reschedule_interrupt(struct pt_regs *);
extern void smp_call_function_interrupt(struct pt_regs *);
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index 71c9e5183982..63d185087d91 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -67,7 +67,7 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
".previous\n"
_ASM_EXTABLE(1b, 3b)
: [err] "=r" (err)
-#if 0 /* See comment in __save_init_fpu() below. */
+#if 0 /* See comment in fxsave() below. */
: [fx] "r" (fx), "m" (*fx), "0" (0));
#else
: [fx] "cdaSDb" (fx), "m" (*fx), "0" (0));
@@ -75,14 +75,6 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
return err;
}
-static inline int restore_fpu_checking(struct task_struct *tsk)
-{
- if (task_thread_info(tsk)->status & TS_XSAVE)
- return xrstor_checking(&tsk->thread.xstate->xsave);
- else
- return fxrstor_checking(&tsk->thread.xstate->fxsave);
-}
-
/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
is pending. Clear the x87 state here by setting it to fixed
values. The kernel data segment can be sometimes 0 and sometimes
@@ -120,7 +112,7 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
".previous\n"
_ASM_EXTABLE(1b, 3b)
: [err] "=r" (err), "=m" (*fx)
-#if 0 /* See comment in __fxsave_clear() below. */
+#if 0 /* See comment in fxsave() below. */
: [fx] "r" (fx), "0" (0));
#else
: [fx] "cdaSDb" (fx), "0" (0));
@@ -185,12 +177,9 @@ static inline void tolerant_fwait(void)
asm volatile("fnclex ; fwait");
}
-static inline void restore_fpu(struct task_struct *tsk)
+/* perform fxrstor iff the processor has extended states, otherwise frstor */
+static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
{
- if (task_thread_info(tsk)->status & TS_XSAVE) {
- xrstor_checking(&tsk->thread.xstate->xsave);
- return;
- }
/*
* The "nop" is needed to make the instructions the same
* length.
@@ -199,7 +188,9 @@ static inline void restore_fpu(struct task_struct *tsk)
"nop ; frstor %1",
"fxrstor %1",
X86_FEATURE_FXSR,
- "m" (tsk->thread.xstate->fxsave));
+ "m" (*fx));
+
+ return 0;
}
/* We need a safe address that is cheap to find and that is already
@@ -262,6 +253,14 @@ end:
#endif /* CONFIG_X86_64 */
+static inline int restore_fpu_checking(struct task_struct *tsk)
+{
+ if (task_thread_info(tsk)->status & TS_XSAVE)
+ return xrstor_checking(&tsk->thread.xstate->xsave);
+ else
+ return fxrstor_checking(&tsk->thread.xstate->fxsave);
+}
+
/*
* Signal frame handlers...
*/
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
index 1a99e6c092af..58d7091eeb1f 100644
--- a/arch/x86/include/asm/i8259.h
+++ b/arch/x86/include/asm/i8259.h
@@ -60,8 +60,4 @@ extern struct irq_chip i8259A_chip;
extern void mask_8259A(void);
extern void unmask_8259A(void);
-#ifdef CONFIG_X86_32
-extern void init_ISA_irqs(void);
-#endif
-
#endif /* _ASM_X86_I8259_H */
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 9d826e436010..27bd2fdd00ae 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -154,22 +154,18 @@ extern int timer_through_8259;
extern int io_apic_get_unique_id(int ioapic, int apic_id);
extern int io_apic_get_version(int ioapic);
extern int io_apic_get_redir_entries(int ioapic);
-extern int io_apic_set_pci_routing(int ioapic, int pin, int irq,
- int edge_level, int active_high_low);
+extern int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin,
+ int irq, int edge_level, int active_high_low);
#endif /* CONFIG_ACPI */
extern int (*ioapic_renumber_irq)(int ioapic, int irq);
extern void ioapic_init_mappings(void);
-#ifdef CONFIG_X86_64
extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
-extern void reinit_intr_remapped_IO_APIC(int intr_remapping,
- struct IO_APIC_route_entry **ioapic_entries);
-#endif
extern void probe_nr_irqs_gsi(void);
diff --git a/arch/x86/include/asm/iomap.h b/arch/x86/include/asm/iomap.h
index 86af26091d6c..0e9fe1d9d971 100644
--- a/arch/x86/include/asm/iomap.h
+++ b/arch/x86/include/asm/iomap.h
@@ -1,3 +1,6 @@
+#ifndef _ASM_X86_IOMAP_H
+#define _ASM_X86_IOMAP_H
+
/*
* Copyright © 2008 Ingo Molnar
*
@@ -31,3 +34,5 @@ iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
void
iounmap_atomic(void *kvaddr, enum km_type type);
+
+#endif /* _ASM_X86_IOMAP_H */
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index af326a2975b5..fd6d21bbee6c 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -6,6 +6,7 @@ extern void no_iommu_init(void);
extern struct dma_map_ops nommu_dma_ops;
extern int force_iommu, no_iommu;
extern int iommu_detected;
+extern int iommu_pass_through;
/* 10 seconds */
#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
index 0396760fccb8..f275e2244505 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -1,6 +1,6 @@
#ifndef _ASM_X86_IRQ_REMAPPING_H
#define _ASM_X86_IRQ_REMAPPING_H
-#define IRTE_DEST(dest) ((x2apic) ? dest : dest << 8)
+#define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8)
#endif /* _ASM_X86_IRQ_REMAPPING_H */
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 3cbd79bbb47c..910b5a3d6751 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -34,6 +34,7 @@
#ifdef CONFIG_X86_32
# define SYSCALL_VECTOR 0x80
+# define IA32_SYSCALL_VECTOR 0x80
#else
# define IA32_SYSCALL_VECTOR 0x80
#endif
diff --git a/arch/x86/include/asm/k8.h b/arch/x86/include/asm/k8.h
index 54c8cc53b24d..c2d1f3b58e5f 100644
--- a/arch/x86/include/asm/k8.h
+++ b/arch/x86/include/asm/k8.h
@@ -12,4 +12,17 @@ extern int cache_k8_northbridges(void);
extern void k8_flush_garts(void);
extern int k8_scan_nodes(unsigned long start, unsigned long end);
+#ifdef CONFIG_K8_NB
+static inline struct pci_dev *node_to_k8_nb_misc(int node)
+{
+ return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL;
+}
+#else
+static inline struct pci_dev *node_to_k8_nb_misc(int node)
+{
+ return NULL;
+}
+#endif
+
+
#endif /* _ASM_X86_K8_H */
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index dc3f6cf11704..125be8b19568 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -16,6 +16,7 @@
#define __KVM_HAVE_MSI
#define __KVM_HAVE_USER_NMI
#define __KVM_HAVE_GUEST_DEBUG
+#define __KVM_HAVE_MSIX
/* Architectural interrupt line count. */
#define KVM_NR_INTERRUPTS 256
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index f0faf58044ff..5322ee67caaa 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -185,6 +185,7 @@ union kvm_mmu_page_role {
unsigned access:3;
unsigned invalid:1;
unsigned cr4_pge:1;
+ unsigned nxe:1;
};
};
@@ -212,7 +213,6 @@ struct kvm_mmu_page {
int multimapped; /* More than one parent_pte? */
int root_count; /* Currently serving as active root */
bool unsync;
- bool global;
unsigned int unsync_children;
union {
u64 *parent_pte; /* !multimapped */
@@ -261,11 +261,11 @@ struct kvm_mmu {
union kvm_mmu_page_role base_role;
u64 *pae_root;
+ u64 rsvd_bits_mask[2][4];
};
struct kvm_vcpu_arch {
u64 host_tsc;
- int interrupt_window_open;
unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */
DECLARE_BITMAP(irq_pending, KVM_NR_INTERRUPTS);
/*
@@ -286,6 +286,7 @@ struct kvm_vcpu_arch {
u64 shadow_efer;
u64 apic_base;
struct kvm_lapic *apic; /* kernel irqchip context */
+ int32_t apic_arb_prio;
int mp_state;
int sipi_vector;
u64 ia32_misc_enable_msr;
@@ -358,7 +359,6 @@ struct kvm_vcpu_arch {
bool nmi_pending;
bool nmi_injected;
- bool nmi_window_open;
struct mtrr_state_type mtrr_state;
u32 pat;
@@ -392,15 +392,15 @@ struct kvm_arch{
*/
struct list_head active_mmu_pages;
struct list_head assigned_dev_head;
- struct list_head oos_global_pages;
struct iommu_domain *iommu_domain;
+#define KVM_IOMMU_CACHE_COHERENCY 0x1
+ int iommu_flags;
struct kvm_pic *vpic;
struct kvm_ioapic *vioapic;
struct kvm_pit *vpit;
struct hlist_head irq_ack_notifier_list;
int vapics_in_nmi_mode;
- int round_robin_prev_vcpu;
unsigned int tss_addr;
struct page *apic_access_page;
@@ -423,7 +423,6 @@ struct kvm_vm_stat {
u32 mmu_recycled;
u32 mmu_cache_miss;
u32 mmu_unsync;
- u32 mmu_unsync_global;
u32 remote_tlb_flush;
u32 lpages;
};
@@ -443,7 +442,6 @@ struct kvm_vcpu_stat {
u32 halt_exits;
u32 halt_wakeup;
u32 request_irq_exits;
- u32 request_nmi_exits;
u32 irq_exits;
u32 host_state_reload;
u32 efer_reload;
@@ -513,18 +511,19 @@ struct kvm_x86_ops {
void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
void (*patch_hypercall)(struct kvm_vcpu *vcpu,
unsigned char *hypercall_addr);
- int (*get_irq)(struct kvm_vcpu *vcpu);
void (*set_irq)(struct kvm_vcpu *vcpu, int vec);
+ void (*set_nmi)(struct kvm_vcpu *vcpu);
void (*queue_exception)(struct kvm_vcpu *vcpu, unsigned nr,
bool has_error_code, u32 error_code);
- bool (*exception_injected)(struct kvm_vcpu *vcpu);
- void (*inject_pending_irq)(struct kvm_vcpu *vcpu);
- void (*inject_pending_vectors)(struct kvm_vcpu *vcpu,
- struct kvm_run *run);
-
+ int (*interrupt_allowed)(struct kvm_vcpu *vcpu);
+ int (*nmi_allowed)(struct kvm_vcpu *vcpu);
+ void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
+ void (*enable_irq_window)(struct kvm_vcpu *vcpu);
+ void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
+ void (*drop_interrupt_shadow)(struct kvm_vcpu *vcpu);
int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
int (*get_tdp_level)(void);
- int (*get_mt_mask_shift)(void);
+ u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
};
extern struct kvm_x86_ops *kvm_x86_ops;
@@ -538,7 +537,7 @@ int kvm_mmu_setup(struct kvm_vcpu *vcpu);
void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte);
void kvm_mmu_set_base_ptes(u64 base_pte);
void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
- u64 dirty_mask, u64 nx_mask, u64 x_mask, u64 mt_mask);
+ u64 dirty_mask, u64 nx_mask, u64 x_mask);
int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
@@ -552,6 +551,7 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
const void *val, int bytes);
int kvm_pv_mmu_op(struct kvm_vcpu *vcpu, unsigned long bytes,
gpa_t addr, unsigned long *ret);
+u8 kvm_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn);
extern bool tdp_enabled;
@@ -563,6 +563,7 @@ enum emulation_result {
#define EMULTYPE_NO_DECODE (1 << 0)
#define EMULTYPE_TRAP_UD (1 << 1)
+#define EMULTYPE_SKIP (1 << 2)
int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run,
unsigned long cr2, u16 error_code, int emulation_type);
void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context);
@@ -638,7 +639,6 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
int kvm_mmu_load(struct kvm_vcpu *vcpu);
void kvm_mmu_unload(struct kvm_vcpu *vcpu);
void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu);
-void kvm_mmu_sync_global(struct kvm_vcpu *vcpu);
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
@@ -769,6 +769,7 @@ enum {
#define HF_GIF_MASK (1 << 0)
#define HF_HIF_MASK (1 << 1)
#define HF_VINTR_MASK (1 << 2)
+#define HF_NMI_MASK (1 << 3)
/*
* Hardware virtualization extension instructions may fault if a
@@ -791,5 +792,6 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
#define KVM_ARCH_WANT_MMU_NOTIFIER
int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
int kvm_age_hva(struct kvm *kvm, unsigned long hva);
+int cpuid_maxphyaddr(struct kvm_vcpu *vcpu);
#endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 642fc7fc8cdc..3ea1f531f532 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -72,7 +72,9 @@ extern void mp_register_ioapic(int id, u32 address, u32 gsi_base);
extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
u32 gsi);
extern void mp_config_acpi_legacy_irqs(void);
-extern int mp_register_gsi(u32 gsi, int edge_level, int active_high_low);
+struct device;
+extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
+ int active_high_low);
extern int acpi_probe_gsi(void);
#ifdef CONFIG_X86_IO_APIC
extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index ec41fc16c167..4d58d04fca83 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -121,7 +121,6 @@
#define MSR_K8_TOP_MEM1 0xc001001a
#define MSR_K8_TOP_MEM2 0xc001001d
#define MSR_K8_SYSCFG 0xc0010010
-#define MSR_K8_HWCR 0xc0010015
#define MSR_K8_INT_PENDING_MSG 0xc0010055
/* C1E active bits in int pending message */
#define K8_INTP_C1E_ACTIVE_MASK 0x18000000
diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h
index 0f915ae649a7..6f1b7331313f 100644
--- a/arch/x86/include/asm/page_32_types.h
+++ b/arch/x86/include/asm/page_32_types.h
@@ -54,10 +54,6 @@ extern unsigned int __VMALLOC_RESERVE;
extern int sysctl_legacy_va_layout;
extern void find_low_pfn_range(void);
-extern unsigned long init_memory_mapping(unsigned long start,
- unsigned long end);
-extern void initmem_init(unsigned long, unsigned long);
-extern void free_initmem(void);
extern void setup_bootmem_allocator(void);
#endif /* !__ASSEMBLY__ */
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h
index d38c91b70248..6fadb020bd2b 100644
--- a/arch/x86/include/asm/page_64_types.h
+++ b/arch/x86/include/asm/page_64_types.h
@@ -47,7 +47,7 @@
#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
#define __START_KERNEL_map _AC(0xffffffff80000000, UL)
-/* See Documentation/x86_64/mm.txt for a description of the memory map. */
+/* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */
#define __PHYSICAL_MASK_SHIFT 46
#define __VIRTUAL_MASK_SHIFT 48
@@ -71,12 +71,6 @@ extern unsigned long __phys_addr(unsigned long);
#define vmemmap ((struct page *)VMEMMAP_START)
-extern unsigned long init_memory_mapping(unsigned long start,
- unsigned long end);
-
-extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn);
-extern void free_initmem(void);
-
extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h
index 826ad37006ab..6473f5ccff85 100644
--- a/arch/x86/include/asm/page_types.h
+++ b/arch/x86/include/asm/page_types.h
@@ -46,6 +46,12 @@ extern int devmem_is_allowed(unsigned long pagenr);
extern unsigned long max_low_pfn_mapped;
extern unsigned long max_pfn_mapped;
+extern unsigned long init_memory_mapping(unsigned long start,
+ unsigned long end);
+
+extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn);
+extern void free_initmem(void);
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_X86_PAGE_DEFS_H */
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 378e3691c08c..1fe583783792 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -56,6 +56,7 @@ struct desc_ptr;
struct tss_struct;
struct mm_struct;
struct desc_struct;
+struct task_struct;
/*
* Wrapper type for pointers to code which uses the non-standard
@@ -203,7 +204,8 @@ struct pv_cpu_ops {
void (*swapgs)(void);
- struct pv_lazy_ops lazy_mode;
+ void (*start_context_switch)(struct task_struct *prev);
+ void (*end_context_switch)(struct task_struct *next);
};
struct pv_irq_ops {
@@ -1399,25 +1401,23 @@ enum paravirt_lazy_mode {
};
enum paravirt_lazy_mode paravirt_get_lazy_mode(void);
-void paravirt_enter_lazy_cpu(void);
-void paravirt_leave_lazy_cpu(void);
+void paravirt_start_context_switch(struct task_struct *prev);
+void paravirt_end_context_switch(struct task_struct *next);
+
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)
+#define __HAVE_ARCH_START_CONTEXT_SWITCH
+static inline void arch_start_context_switch(struct task_struct *prev)
{
- PVOP_VCALL0(pv_cpu_ops.lazy_mode.enter);
+ PVOP_VCALL1(pv_cpu_ops.start_context_switch, prev);
}
-static inline void arch_leave_lazy_cpu_mode(void)
+static inline void arch_end_context_switch(struct task_struct *next)
{
- PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave);
+ PVOP_VCALL1(pv_cpu_ops.end_context_switch, next);
}
-void arch_flush_lazy_cpu_mode(void);
-
#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
static inline void arch_enter_lazy_mmu_mode(void)
{
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index b51a1e8b0baf..927958d13c19 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -130,6 +130,7 @@ extern void pci_iommu_alloc(void);
/* generic pci stuff */
#include <asm-generic/pci.h>
+#define PCIBIOS_MAX_MEM_32 0xffffffff
#ifdef CONFIG_NUMA
/* Returns the node based on pci bus */
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index aee103b26d01..02ecb30982a3 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -82,22 +82,22 @@ do { \
case 1: \
asm(op "b %1,"__percpu_arg(0) \
: "+m" (var) \
- : "ri" ((T__)val)); \
+ : "qi" ((T__)(val))); \
break; \
case 2: \
asm(op "w %1,"__percpu_arg(0) \
: "+m" (var) \
- : "ri" ((T__)val)); \
+ : "ri" ((T__)(val))); \
break; \
case 4: \
asm(op "l %1,"__percpu_arg(0) \
: "+m" (var) \
- : "ri" ((T__)val)); \
+ : "ri" ((T__)(val))); \
break; \
case 8: \
asm(op "q %1,"__percpu_arg(0) \
: "+m" (var) \
- : "re" ((T__)val)); \
+ : "re" ((T__)(val))); \
break; \
default: __bad_percpu_size(); \
} \
@@ -109,7 +109,7 @@ do { \
switch (sizeof(var)) { \
case 1: \
asm(op "b "__percpu_arg(1)",%0" \
- : "=r" (ret__) \
+ : "=q" (ret__) \
: "m" (var)); \
break; \
case 2: \
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 29d96d168bc0..18ef7ebf2631 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -81,6 +81,8 @@ static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
#define pte_val(x) native_pte_val(x)
#define __pte(x) native_make_pte(x)
+#define arch_end_context_switch(prev) do {} while(0)
+
#endif /* CONFIG_PARAVIRT */
/*
@@ -503,6 +505,8 @@ static inline int pgd_none(pgd_t pgd)
#ifndef __ASSEMBLY__
+extern int direct_gbpages;
+
/* local pte updates need not use xchg for locking */
static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep)
{
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 6b87bc6d5018..abde308fdb0f 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -25,10 +25,6 @@ extern pgd_t init_level4_pgt[];
extern void paging_init(void);
-#endif /* !__ASSEMBLY__ */
-
-#ifndef __ASSEMBLY__
-
#define pte_ERROR(e) \
printk("%s:%d: bad pte %p(%016lx).\n", \
__FILE__, __LINE__, &(e), pte_val(e))
@@ -135,8 +131,6 @@ static inline int pgd_large(pgd_t pgd) { return 0; }
#define update_mmu_cache(vma, address, pte) do { } while (0)
-extern int direct_gbpages;
-
/* Encode and de-code a swap entry */
#if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE
#define SWP_TYPE_BITS (_PAGE_BIT_FILE - _PAGE_BIT_PRESENT - 1)
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index fbf42b8e0383..766ea16fbbbd 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -51,11 +51,11 @@ typedef struct { pteval_t pte; } pte_t;
#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE - 1))
-
+/* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */
#define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL)
-#define VMALLOC_START _AC(0xffffc20000000000, UL)
-#define VMALLOC_END _AC(0xffffe1ffffffffff, UL)
-#define VMEMMAP_START _AC(0xffffe20000000000, UL)
+#define VMALLOC_START _AC(0xffffc90000000000, UL)
+#define VMALLOC_END _AC(0xffffe8ffffffffff, UL)
+#define VMEMMAP_START _AC(0xffffea0000000000, UL)
#define MODULES_VADDR _AC(0xffffffffa0000000, UL)
#define MODULES_END _AC(0xffffffffff000000, UL)
#define MODULES_LEN (MODULES_END - MODULES_VADDR)
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index b8238dc8786d..4d258ad76a0f 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -273,7 +273,6 @@ typedef struct page *pgtable_t;
extern pteval_t __supported_pte_mask;
extern int nx_enabled;
-extern void set_nx(void);
#define pgprot_writecombine pgprot_writecombine
extern pgprot_t pgprot_writecombine(pgprot_t prot);
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c2cceae709c8..b08c21ca59a8 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -135,7 +135,8 @@ extern struct cpuinfo_x86 boot_cpu_data;
extern struct cpuinfo_x86 new_cpu_data;
extern struct tss_struct doublefault_tss;
-extern __u32 cleared_cpu_caps[NCAPINTS];
+extern __u32 cpu_caps_cleared[NCAPINTS];
+extern __u32 cpu_caps_set[NCAPINTS];
#ifdef CONFIG_SMP
DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
@@ -427,8 +428,12 @@ struct thread_struct {
unsigned short fsindex;
unsigned short gsindex;
#endif
+#ifdef CONFIG_X86_32
unsigned long ip;
+#endif
+#ifdef CONFIG_X86_64
unsigned long fs;
+#endif
unsigned long gs;
/* Hardware debugging registers: */
unsigned long debugreg0;
@@ -460,14 +465,8 @@ struct thread_struct {
unsigned io_bitmap_max;
/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */
unsigned long debugctlmsr;
-#ifdef CONFIG_X86_DS
-/* Debug Store context; see include/asm-x86/ds.h; goes into MSR_IA32_DS_AREA */
+ /* Debug Store context; see asm/ds.h */
struct ds_context *ds_ctx;
-#endif /* CONFIG_X86_DS */
-#ifdef CONFIG_X86_PTRACE_BTS
-/* the signal to send on a bts buffer overflow */
- unsigned int bts_ovfl_signal;
-#endif /* CONFIG_X86_PTRACE_BTS */
};
static inline unsigned long native_get_debugreg(int regno)
@@ -795,6 +794,21 @@ static inline unsigned long get_debugctlmsr(void)
return debugctlmsr;
}
+static inline unsigned long get_debugctlmsr_on_cpu(int cpu)
+{
+ u64 debugctlmsr = 0;
+ u32 val1, val2;
+
+#ifndef CONFIG_X86_DEBUGCTLMSR
+ if (boot_cpu_data.x86 < 6)
+ return 0;
+#endif
+ rdmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR, &val1, &val2);
+ debugctlmsr = val1 | ((u64)val2 << 32);
+
+ return debugctlmsr;
+}
+
static inline void update_debugctlmsr(unsigned long debugctlmsr)
{
#ifndef CONFIG_X86_DEBUGCTLMSR
@@ -804,6 +818,18 @@ static inline void update_debugctlmsr(unsigned long debugctlmsr)
wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
}
+static inline void update_debugctlmsr_on_cpu(int cpu,
+ unsigned long debugctlmsr)
+{
+#ifndef CONFIG_X86_DEBUGCTLMSR
+ if (boot_cpu_data.x86 < 6)
+ return;
+#endif
+ wrmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR,
+ (u32)((u64)debugctlmsr),
+ (u32)((u64)debugctlmsr >> 32));
+}
+
/*
* from system description table in BIOS. Mostly for MCA use, but
* others may find it useful:
@@ -874,7 +900,6 @@ static inline void spin_lock_prefetch(const void *x)
.vm86_info = NULL, \
.sysenter_cs = __KERNEL_CS, \
.io_bitmap_ptr = NULL, \
- .fs = __KERNEL_PERCPU, \
}
/*
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index e304b66abeea..0f0d908349aa 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -187,14 +187,15 @@ static inline int v8086_mode(struct pt_regs *regs)
/*
* X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
- * when it traps. So regs will be the current sp.
+ * when it traps. The previous stack will be directly underneath the saved
+ * registers, and 'sp/ss' won't even have been saved. Thus the '&regs->sp'.
*
* This is valid only for kernel mode traps.
*/
-static inline unsigned long kernel_trap_sp(struct pt_regs *regs)
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
{
#ifdef CONFIG_X86_32
- return (unsigned long)regs;
+ return (unsigned long)(&regs->sp);
#else
return regs->sp;
#endif
@@ -235,12 +236,11 @@ extern int do_get_thread_area(struct task_struct *p, int idx,
extern int do_set_thread_area(struct task_struct *p, int idx,
struct user_desc __user *info, int can_allocate);
-extern void x86_ptrace_untrace(struct task_struct *);
-extern void x86_ptrace_fork(struct task_struct *child,
- unsigned long clone_flags);
+#ifdef CONFIG_X86_PTRACE_BTS
+extern void ptrace_bts_untrace(struct task_struct *tsk);
-#define arch_ptrace_untrace(tsk) x86_ptrace_untrace(tsk)
-#define arch_ptrace_fork(child, flags) x86_ptrace_fork(child, flags)
+#define arch_ptrace_untrace(tsk) ptrace_bts_untrace(tsk)
+#endif /* CONFIG_X86_PTRACE_BTS */
#endif /* __KERNEL__ */
diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h
index a4737dddfd58..64cf2d24fad1 100644
--- a/arch/x86/include/asm/required-features.h
+++ b/arch/x86/include/asm/required-features.h
@@ -48,9 +48,15 @@
#endif
#ifdef CONFIG_X86_64
+#ifdef CONFIG_PARAVIRT
+/* Paravirtualized systems may not have PSE or PGE available */
#define NEED_PSE 0
-#define NEED_MSR (1<<(X86_FEATURE_MSR & 31))
#define NEED_PGE 0
+#else
+#define NEED_PSE (1<<(X86_FEATURE_PSE) & 31)
+#define NEED_PGE (1<<(X86_FEATURE_PGE) & 31)
+#endif
+#define NEED_MSR (1<<(X86_FEATURE_MSR & 31))
#define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31))
#define NEED_XMM (1<<(X86_FEATURE_XMM & 31))
#define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31))
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index bdc2ada05ae0..4093d1ed6db2 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -33,7 +33,6 @@ struct x86_quirks {
int (*setup_ioapic_ids)(void);
};
-extern void x86_quirk_pre_intr_init(void);
extern void x86_quirk_intr_init(void);
extern void x86_quirk_trap_init(void);
diff --git a/arch/x86/include/asm/sparsemem.h b/arch/x86/include/asm/sparsemem.h
index e3cc3c063ec5..4517d6b93188 100644
--- a/arch/x86/include/asm/sparsemem.h
+++ b/arch/x86/include/asm/sparsemem.h
@@ -27,7 +27,7 @@
#else /* CONFIG_X86_32 */
# define SECTION_SIZE_BITS 27 /* matt - 128 is convenient right now */
# define MAX_PHYSADDR_BITS 44
-# define MAX_PHYSMEM_BITS 44 /* Can be max 45 bits */
+# define MAX_PHYSMEM_BITS 46
#endif
#endif /* CONFIG_SPARSEMEM */
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 82ada75f3ebf..85574b7c1bc1 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -225,6 +225,7 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_EVTINJ_VALID_ERR (1 << 11)
#define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK
+#define SVM_EXITINTINFO_TYPE_MASK SVM_EVTINJ_TYPE_MASK
#define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR
#define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 7043408f6904..372b76edd63f 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -1,7 +1,7 @@
/*
* syscalls.h - Linux syscall interfaces (arch-specific)
*
- * Copyright (c) 2008 Jaswinder Singh
+ * Copyright (c) 2008 Jaswinder Singh Rajput
*
* This file is released under the GPLv2.
* See the file COPYING for more details.
@@ -12,50 +12,55 @@
#include <linux/compiler.h>
#include <linux/linkage.h>
-#include <linux/types.h>
#include <linux/signal.h>
+#include <linux/types.h>
/* Common in X86_32 and X86_64 */
/* kernel/ioport.c */
asmlinkage long sys_ioperm(unsigned long, unsigned long, int);
+/* kernel/process.c */
+int sys_fork(struct pt_regs *);
+int sys_vfork(struct pt_regs *);
+
/* kernel/ldt.c */
asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
+/* kernel/signal.c */
+long sys_rt_sigreturn(struct pt_regs *);
+
/* kernel/tls.c */
asmlinkage int sys_set_thread_area(struct user_desc __user *);
asmlinkage int sys_get_thread_area(struct user_desc __user *);
/* X86_32 only */
#ifdef CONFIG_X86_32
+/* kernel/ioport.c */
+long sys_iopl(struct pt_regs *);
+
/* kernel/process_32.c */
-int sys_fork(struct pt_regs *);
int sys_clone(struct pt_regs *);
-int sys_vfork(struct pt_regs *);
int sys_execve(struct pt_regs *);
-/* kernel/signal_32.c */
+/* kernel/signal.c */
asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
struct old_sigaction __user *);
int sys_sigaltstack(struct pt_regs *);
unsigned long sys_sigreturn(struct pt_regs *);
-long sys_rt_sigreturn(struct pt_regs *);
-
-/* kernel/ioport.c */
-long sys_iopl(struct pt_regs *);
/* kernel/sys_i386_32.c */
+struct mmap_arg_struct;
+struct sel_arg_struct;
+struct oldold_utsname;
+struct old_utsname;
+
asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long, unsigned long);
-struct mmap_arg_struct;
asmlinkage int old_mmap(struct mmap_arg_struct __user *);
-struct sel_arg_struct;
asmlinkage int old_select(struct sel_arg_struct __user *);
asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
-struct old_utsname;
asmlinkage int sys_uname(struct old_utsname __user *);
-struct oldold_utsname;
asmlinkage int sys_olduname(struct oldold_utsname __user *);
/* kernel/vm86_32.c */
@@ -65,29 +70,27 @@ int sys_vm86(struct pt_regs *);
#else /* CONFIG_X86_32 */
/* X86_64 only */
+/* kernel/ioport.c */
+asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
+
/* kernel/process_64.c */
-asmlinkage long sys_fork(struct pt_regs *);
asmlinkage long sys_clone(unsigned long, unsigned long,
void __user *, void __user *,
struct pt_regs *);
-asmlinkage long sys_vfork(struct pt_regs *);
asmlinkage long sys_execve(char __user *, char __user * __user *,
char __user * __user *,
struct pt_regs *);
long sys_arch_prctl(int, unsigned long);
-/* kernel/ioport.c */
-asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
-
-/* kernel/signal_64.c */
+/* kernel/signal.c */
asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *,
struct pt_regs *);
-long sys_rt_sigreturn(struct pt_regs *);
/* kernel/sys_x86_64.c */
+struct new_utsname;
+
asmlinkage long sys_mmap(unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long, unsigned long);
-struct new_utsname;
asmlinkage long sys_uname(struct new_utsname __user *);
#endif /* CONFIG_X86_32 */
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 8820a73ae090..602c769fc98c 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -94,7 +94,8 @@ struct thread_info {
#define TIF_FORCED_TF 24 /* true if TF in eflags artificially */
#define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */
#define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */
-#define TIF_SYSCALL_FTRACE 27 /* for ftrace syscall instrumentation */
+#define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */
+#define TIF_SYSCALL_FTRACE 28 /* for ftrace syscall instrumentation */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
@@ -116,6 +117,7 @@ struct thread_info {
#define _TIF_FORCED_TF (1 << TIF_FORCED_TF)
#define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR)
#define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR)
+#define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES)
#define _TIF_SYSCALL_FTRACE (1 << TIF_SYSCALL_FTRACE)
/* work to do in syscall_trace_enter() */
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 16a5c84b0329..a5ecc9c33e92 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -17,7 +17,7 @@
static inline void __native_flush_tlb(void)
{
- write_cr3(read_cr3());
+ native_write_cr3(native_read_cr3());
}
static inline void __native_flush_tlb_global(void)
@@ -32,11 +32,11 @@ static inline void __native_flush_tlb_global(void)
*/
raw_local_irq_save(flags);
- cr4 = read_cr4();
+ cr4 = native_read_cr4();
/* clear PGE */
- write_cr4(cr4 & ~X86_CR4_PGE);
+ native_write_cr4(cr4 & ~X86_CR4_PGE);
/* write old PGE again and flush TLBs */
- write_cr4(cr4);
+ native_write_cr4(cr4);
raw_local_irq_restore(flags);
}
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index f44b49abca49..066ef590d7e0 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -203,7 +203,8 @@ struct pci_bus;
void x86_pci_root_bus_res_quirks(struct pci_bus *b);
#ifdef CONFIG_SMP
-#define mc_capable() (cpumask_weight(cpu_core_mask(0)) != nr_cpu_ids)
+#define mc_capable() ((boot_cpu_data.x86_max_cores > 1) && \
+ (cpumask_weight(cpu_core_mask(0)) != nr_cpu_ids))
#define smt_capable() (smp_num_siblings > 1)
#endif
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index 0d5342515b86..bfd74c032fca 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -2,6 +2,7 @@
#define _ASM_X86_TRAPS_H
#include <asm/debugreg.h>
+#include <asm/siginfo.h> /* TRAP_TRACE, ... */
#ifdef CONFIG_X86_32
#define dotraplinkage
@@ -13,6 +14,9 @@ asmlinkage void divide_error(void);
asmlinkage void debug(void);
asmlinkage void nmi(void);
asmlinkage void int3(void);
+asmlinkage void xen_debug(void);
+asmlinkage void xen_int3(void);
+asmlinkage void xen_stack_segment(void);
asmlinkage void overflow(void);
asmlinkage void bounds(void);
asmlinkage void invalid_op(void);
@@ -74,7 +78,6 @@ static inline int get_si_code(unsigned long condition)
}
extern int panic_on_unrecovered_nmi;
-extern int kstack_depth_to_print;
void math_error(void __user *);
void math_emulate(struct math_emu_info *);
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
index 6e72d74cf8dc..708dae61262d 100644
--- a/arch/x86/include/asm/unistd_32.h
+++ b/arch/x86/include/asm/unistd_32.h
@@ -340,6 +340,7 @@
#define __NR_inotify_init1 332
#define __NR_preadv 333
#define __NR_pwritev 334
+#define __NR_rt_tgsigqueueinfo 335
#ifdef __KERNEL__
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
index f81829462325..4e2b05404400 100644
--- a/arch/x86/include/asm/unistd_64.h
+++ b/arch/x86/include/asm/unistd_64.h
@@ -657,6 +657,8 @@ __SYSCALL(__NR_inotify_init1, sys_inotify_init1)
__SYSCALL(__NR_preadv, sys_preadv)
#define __NR_pwritev 296
__SYSCALL(__NR_pwritev, sys_pwritev)
+#define __NR_rt_tgsigqueueinfo 297
+__SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
#ifndef __NO_STUBS
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 145cce75cda7..68a4ff609767 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -28,7 +28,7 @@ CFLAGS_paravirt.o := $(nostackp)
obj-y := process_$(BITS).o signal.o entry_$(BITS).o
obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
obj-y += time_$(BITS).o ioport.o ldt.o dumpstack.o
-obj-y += setup.o i8259.o irqinit_$(BITS).o
+obj-y += setup.o i8259.o irqinit.o
obj-$(CONFIG_X86_VISWS) += visws_quirks.o
obj-$(CONFIG_X86_32) += probe_roms_32.o
obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
@@ -44,6 +44,7 @@ obj-y += process.o
obj-y += i387.o xsave.o
obj-y += ptrace.o
obj-$(CONFIG_X86_DS) += ds.o
+obj-$(CONFIG_X86_DS_SELFTEST) += ds_selftest.o
obj-$(CONFIG_X86_32) += tls.o
obj-$(CONFIG_IA32_EMULATION) += tls.o
obj-y += step.o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 723989d7f802..6ee96b5530f1 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -522,7 +522,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
* success: return IRQ number (>=0)
* failure: return < 0
*/
-int acpi_register_gsi(u32 gsi, int triggering, int polarity)
+int acpi_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity)
{
unsigned int irq;
unsigned int plat_gsi = gsi;
@@ -539,7 +539,7 @@ int acpi_register_gsi(u32 gsi, int triggering, int polarity)
#ifdef CONFIG_X86_IO_APIC
if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
- plat_gsi = mp_register_gsi(gsi, triggering, polarity);
+ plat_gsi = mp_register_gsi(dev, gsi, triggering, polarity);
}
#endif
acpi_gsi_to_irq(plat_gsi, &irq);
@@ -1158,7 +1158,7 @@ void __init mp_config_acpi_legacy_irqs(void)
}
}
-int mp_register_gsi(u32 gsi, int triggering, int polarity)
+int mp_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity)
{
int ioapic;
int ioapic_pin;
@@ -1253,7 +1253,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
}
}
#endif
- io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
+ io_apic_set_pci_routing(dev, ioapic, ioapic_pin, gsi,
triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
return gsi;
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index bbbe4bbb6f34..b866b876446e 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -53,6 +53,12 @@ struct cstate_entry {
};
static struct cstate_entry *cpu_cstate_entry; /* per CPU ptr */
+/* Used for the cross-CPU calls */
+struct acpi_processor_cx_cross_cpu {
+ struct acpi_processor_cx *cx;
+ long retval;
+};
+
static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
#define MWAIT_SUBSTATE_MASK (0xf)
@@ -67,10 +73,10 @@ static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
#define NATIVE_CSTATE_BEYOND_HALT (2)
-static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
+static void acpi_processor_ffh_cstate_probe_cpu(void *_cxcc)
{
- struct acpi_processor_cx *cx = _cx;
- long retval;
+ struct acpi_processor_cx_cross_cpu *cxcc = _cxcc;
+ struct acpi_processor_cx *cx = cxcc->cx;
unsigned int eax, ebx, ecx, edx;
unsigned int edx_part;
unsigned int cstate_type; /* C-state type and not ACPI C-state type */
@@ -84,16 +90,16 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE);
num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;
- retval = 0;
+ cxcc->retval = 0;
if (num_cstate_subtype < (cx->address & MWAIT_SUBSTATE_MASK)) {
- retval = -1;
+ cxcc->retval = -1;
goto out;
}
/* mwait ecx extensions INTERRUPT_BREAK should be supported for C2/C3 */
if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
!(ecx & CPUID5_ECX_INTERRUPT_BREAK)) {
- retval = -1;
+ cxcc->retval = -1;
goto out;
}
@@ -107,7 +113,7 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x",
cx->address);
out:
- return retval;
+ return;
}
int acpi_processor_ffh_cstate_probe(unsigned int cpu,
@@ -115,6 +121,7 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
{
struct cstate_entry *percpu_entry;
struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct acpi_processor_cx_cross_cpu cxcc = { .cx = cx, };
long retval;
if (!cpu_cstate_entry || c->cpuid_level < CPUID_MWAIT_LEAF)
@@ -127,13 +134,18 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
percpu_entry->states[cx->index].eax = 0;
percpu_entry->states[cx->index].ecx = 0;
- /* Make sure we are running on right CPU */
+ /* Run acpi_processor_ffh_cstate_probe_cpu() on the target CPU */
- retval = work_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx);
+ retval = smp_call_function_single(cpu,
+ acpi_processor_ffh_cstate_probe_cpu, &cxcc, 1);
if (retval == 0) {
- /* Use the hint in CST */
- percpu_entry->states[cx->index].eax = cx->address;
- percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK;
+ retval = cxcc.retval;
+ if (retval == 0) {
+ /* Use the hint in CST */
+ percpu_entry->states[cx->index].eax = cx->address;
+ percpu_entry->states[cx->index].ecx =
+ MWAIT_ECX_INTERRUPT_BREAK;
+ }
}
return retval;
}
diff --git a/arch/x86/kernel/acpi/realmode/Makefile b/arch/x86/kernel/acpi/realmode/Makefile
index 1c31cc0e9def..167bc16ce0e5 100644
--- a/arch/x86/kernel/acpi/realmode/Makefile
+++ b/arch/x86/kernel/acpi/realmode/Makefile
@@ -9,7 +9,7 @@
always := wakeup.bin
targets := wakeup.elf wakeup.lds
-wakeup-y += wakeup.o wakemain.o video-mode.o copy.o
+wakeup-y += wakeup.o wakemain.o video-mode.o copy.o bioscall.o regs.o
# The link order of the video-*.o modules can matter. In particular,
# video-vga.o *must* be listed first, followed by video-vesa.o.
diff --git a/arch/x86/kernel/acpi/realmode/bioscall.S b/arch/x86/kernel/acpi/realmode/bioscall.S
new file mode 100644
index 000000000000..f51eb0bb56ce
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/bioscall.S
@@ -0,0 +1 @@
+#include "../../../boot/bioscall.S"
diff --git a/arch/x86/kernel/acpi/realmode/regs.c b/arch/x86/kernel/acpi/realmode/regs.c
new file mode 100644
index 000000000000..6206033ba202
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/regs.c
@@ -0,0 +1 @@
+#include "../../../boot/regs.c"
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index f2870920f246..07cffc1214cb 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -98,6 +98,29 @@ early_param("lapic", parse_lapic);
/* Local APIC was disabled by the BIOS and enabled by the kernel */
static int enabled_via_apicbase;
+/*
+ * Handle interrupt mode configuration register (IMCR).
+ * This register controls whether the interrupt signals
+ * that reach the BSP come from the master PIC or from the
+ * local APIC. Before entering Symmetric I/O Mode, either
+ * the BIOS or the operating system must switch out of
+ * PIC Mode by changing the IMCR.
+ */
+static inline void imcr_pic_to_apic(void)
+{
+ /* select IMCR register */
+ outb(0x70, 0x22);
+ /* NMI and 8259 INTR go through APIC */
+ outb(0x01, 0x23);
+}
+
+static inline void imcr_apic_to_pic(void)
+{
+ /* select IMCR register */
+ outb(0x70, 0x22);
+ /* NMI and 8259 INTR go directly to BSP */
+ outb(0x00, 0x23);
+}
#endif
#ifdef CONFIG_X86_64
@@ -111,13 +134,19 @@ static __init int setup_apicpmtimer(char *s)
__setup("apicpmtimer", setup_apicpmtimer);
#endif
+int x2apic_mode;
#ifdef CONFIG_X86_X2APIC
-int x2apic;
/* x2apic enabled before OS handover */
static int x2apic_preenabled;
static int disable_x2apic;
static __init int setup_nox2apic(char *str)
{
+ if (x2apic_enabled()) {
+ pr_warning("Bios already enabled x2apic, "
+ "can't enforce nox2apic");
+ return 0;
+ }
+
disable_x2apic = 1;
setup_clear_cpu_cap(X86_FEATURE_X2APIC);
return 0;
@@ -209,6 +238,24 @@ static int modern_apic(void)
return lapic_get_version() >= 0x14;
}
+/*
+ * bare function to substitute write operation
+ * and it's _that_ fast :)
+ */
+void native_apic_write_dummy(u32 reg, u32 v)
+{
+ WARN_ON_ONCE((cpu_has_apic || !disable_apic));
+}
+
+/*
+ * right after this call apic->write doesn't do anything
+ * note that there is no restore operation it works one way
+ */
+void apic_disable(void)
+{
+ apic->write = native_apic_write_dummy;
+}
+
void native_apic_wait_icr_idle(void)
{
while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
@@ -348,7 +395,7 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask)
{
- unsigned long reg = (lvt_off << 4) + APIC_EILVT0;
+ unsigned long reg = (lvt_off << 4) + APIC_EILVTn(0);
unsigned int v = (mask << 16) | (msg_type << 8) | vector;
apic_write(reg, v);
@@ -815,7 +862,7 @@ void clear_local_APIC(void)
u32 v;
/* APIC hasn't been mapped yet */
- if (!x2apic && !apic_phys)
+ if (!x2apic_mode && !apic_phys)
return;
maxlvt = lapic_get_maxlvt();
@@ -1287,7 +1334,7 @@ void check_x2apic(void)
{
if (x2apic_enabled()) {
pr_info("x2apic enabled by BIOS, switching to x2apic ops\n");
- x2apic_preenabled = x2apic = 1;
+ x2apic_preenabled = x2apic_mode = 1;
}
}
@@ -1295,7 +1342,7 @@ void enable_x2apic(void)
{
int msr, msr2;
- if (!x2apic)
+ if (!x2apic_mode)
return;
rdmsr(MSR_IA32_APICBASE, msr, msr2);
@@ -1304,6 +1351,7 @@ void enable_x2apic(void)
wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
}
}
+#endif /* CONFIG_X86_X2APIC */
void __init enable_IR_x2apic(void)
{
@@ -1312,32 +1360,21 @@ void __init enable_IR_x2apic(void)
unsigned long flags;
struct IO_APIC_route_entry **ioapic_entries = NULL;
- if (!cpu_has_x2apic)
- return;
-
- if (!x2apic_preenabled && disable_x2apic) {
- pr_info("Skipped enabling x2apic and Interrupt-remapping "
- "because of nox2apic\n");
- return;
+ ret = dmar_table_init();
+ if (ret) {
+ pr_debug("dmar_table_init() failed with %d:\n", ret);
+ goto ir_failed;
}
- if (x2apic_preenabled && disable_x2apic)
- panic("Bios already enabled x2apic, can't enforce nox2apic");
-
- if (!x2apic_preenabled && skip_ioapic_setup) {
- pr_info("Skipped enabling x2apic and Interrupt-remapping "
- "because of skipping io-apic setup\n");
- return;
+ if (!intr_remapping_supported()) {
+ pr_debug("intr-remapping not supported\n");
+ goto ir_failed;
}
- ret = dmar_table_init();
- if (ret) {
- pr_info("dmar_table_init() failed with %d:\n", ret);
- if (x2apic_preenabled)
- panic("x2apic enabled by bios. But IR enabling failed");
- else
- pr_info("Not enabling x2apic,Intr-remapping\n");
+ if (!x2apic_preenabled && skip_ioapic_setup) {
+ pr_info("Skipped enabling intr-remap because of skipping "
+ "io-apic setup\n");
return;
}
@@ -1357,19 +1394,16 @@ void __init enable_IR_x2apic(void)
mask_IO_APIC_setup(ioapic_entries);
mask_8259A();
- ret = enable_intr_remapping(EIM_32BIT_APIC_ID);
-
- if (ret && x2apic_preenabled) {
- local_irq_restore(flags);
- panic("x2apic enabled by bios. But IR enabling failed");
- }
-
+ ret = enable_intr_remapping(x2apic_supported());
if (ret)
goto end_restore;
- if (!x2apic) {
- x2apic = 1;
+ pr_info("Enabled Interrupt-remapping\n");
+
+ if (x2apic_supported() && !x2apic_mode) {
+ x2apic_mode = 1;
enable_x2apic();
+ pr_info("Enabled x2apic\n");
}
end_restore:
@@ -1378,37 +1412,34 @@ end_restore:
* IR enabling failed
*/
restore_IO_APIC_setup(ioapic_entries);
- else
- reinit_intr_remapped_IO_APIC(x2apic_preenabled, ioapic_entries);
unmask_8259A();
local_irq_restore(flags);
end:
- if (!ret) {
- if (!x2apic_preenabled)
- pr_info("Enabled x2apic and interrupt-remapping\n");
- else
- pr_info("Enabled Interrupt-remapping\n");
- } else
- pr_err("Failed to enable Interrupt-remapping and x2apic\n");
if (ioapic_entries)
free_ioapic_entries(ioapic_entries);
+
+ if (!ret)
+ return;
+
+ir_failed:
+ if (x2apic_preenabled)
+ panic("x2apic enabled by bios. But IR enabling failed");
+ else if (cpu_has_x2apic)
+ pr_info("Not enabling x2apic,Intr-remapping\n");
#else
if (!cpu_has_x2apic)
return;
if (x2apic_preenabled)
panic("x2apic enabled prior OS handover,"
- " enable CONFIG_INTR_REMAP");
-
- pr_info("Enable CONFIG_INTR_REMAP for enabling intr-remapping "
- " and x2apic\n");
+ " enable CONFIG_X86_X2APIC, CONFIG_INTR_REMAP");
#endif
return;
}
-#endif /* CONFIG_X86_X2APIC */
+
#ifdef CONFIG_X86_64
/*
@@ -1425,7 +1456,6 @@ static int __init detect_init_APIC(void)
}
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
- boot_cpu_physical_apicid = 0;
return 0;
}
#else
@@ -1539,7 +1569,9 @@ void __init early_init_lapic_mapping(void)
*/
void __init init_apic_mappings(void)
{
- if (x2apic) {
+ unsigned int new_apicid;
+
+ if (x2apic_mode) {
boot_cpu_physical_apicid = read_apic_id();
return;
}
@@ -1555,16 +1587,33 @@ void __init init_apic_mappings(void)
} else
apic_phys = mp_lapic_addr;
- set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
+ /*
+ * acpi lapic path already maps that address in
+ * acpi_register_lapic_address()
+ */
+ if (!acpi_lapic)
+ set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
+
apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
- APIC_BASE, apic_phys);
+ APIC_BASE, apic_phys);
+
+ /* lets check if we may NOP'ify apic operations */
+ if (!cpu_has_apic) {
+ pr_info("APIC: disable apic facility\n");
+ apic_disable();
+ return;
+ }
/*
* Fetch the APIC ID of the BSP in case we have a
* default configuration (or the MP table is broken).
*/
- if (boot_cpu_physical_apicid == -1U)
- boot_cpu_physical_apicid = read_apic_id();
+ new_apicid = read_apic_id();
+ if (boot_cpu_physical_apicid != new_apicid) {
+ boot_cpu_physical_apicid = new_apicid;
+ apic_version[new_apicid] =
+ GET_APIC_VERSION(apic_read(APIC_LVR));
+ }
}
/*
@@ -1733,8 +1782,7 @@ void __init connect_bsp_APIC(void)
*/
apic_printk(APIC_VERBOSE, "leaving PIC mode, "
"enabling APIC mode.\n");
- outb(0x70, 0x22);
- outb(0x01, 0x23);
+ imcr_pic_to_apic();
}
#endif
if (apic->enable_apic_mode)
@@ -1762,8 +1810,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
*/
apic_printk(APIC_VERBOSE, "disabling APIC mode, "
"entering PIC mode.\n");
- outb(0x70, 0x22);
- outb(0x00, 0x23);
+ imcr_apic_to_pic();
return;
}
#endif
@@ -1969,10 +2016,10 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
local_irq_save(flags);
disable_local_APIC();
-#ifdef CONFIG_INTR_REMAP
+
if (intr_remapping_enabled)
disable_intr_remapping();
-#endif
+
local_irq_restore(flags);
return 0;
}
@@ -1982,8 +2029,6 @@ static int lapic_resume(struct sys_device *dev)
unsigned int l, h;
unsigned long flags;
int maxlvt;
-
-#ifdef CONFIG_INTR_REMAP
int ret;
struct IO_APIC_route_entry **ioapic_entries = NULL;
@@ -1991,7 +2036,7 @@ static int lapic_resume(struct sys_device *dev)
return 0;
local_irq_save(flags);
- if (x2apic) {
+ if (intr_remapping_enabled) {
ioapic_entries = alloc_ioapic_entries();
if (!ioapic_entries) {
WARN(1, "Alloc ioapic_entries in lapic resume failed.");
@@ -2007,17 +2052,10 @@ static int lapic_resume(struct sys_device *dev)
mask_IO_APIC_setup(ioapic_entries);
mask_8259A();
- enable_x2apic();
}
-#else
- if (!apic_pm_state.active)
- return 0;
- local_irq_save(flags);
- if (x2apic)
+ if (x2apic_mode)
enable_x2apic();
-#endif
-
else {
/*
* Make sure the APICBASE points to the right address
@@ -2055,20 +2093,15 @@ static int lapic_resume(struct sys_device *dev)
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);
-#ifdef CONFIG_INTR_REMAP
- if (intr_remapping_enabled)
- reenable_intr_remapping(EIM_32BIT_APIC_ID);
-
- if (x2apic) {
+ if (intr_remapping_enabled) {
+ reenable_intr_remapping(x2apic_mode);
unmask_8259A();
restore_IO_APIC_setup(ioapic_entries);
free_ioapic_entries(ioapic_entries);
}
-#endif
local_irq_restore(flags);
-
return 0;
}
@@ -2117,31 +2150,14 @@ static void apic_pm_activate(void) { }
#endif /* CONFIG_PM */
#ifdef CONFIG_X86_64
-/*
- * apic_is_clustered_box() -- Check if we can expect good TSC
- *
- * Thus far, the major user of this is IBM's Summit2 series:
- *
- * Clustered boxes may have unsynced TSC problems if they are
- * multi-chassis. Use available data to take a good guess.
- * If in doubt, go HPET.
- */
-__cpuinit int apic_is_clustered_box(void)
+
+static int __cpuinit apic_cluster_num(void)
{
int i, clusters, zeros;
unsigned id;
u16 *bios_cpu_apicid;
DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
- /*
- * there is not this kind of box with AMD CPU yet.
- * Some AMD box with quadcore cpu and 8 sockets apicid
- * will be [4, 0x23] or [8, 0x27] could be thought to
- * vsmp box still need checking...
- */
- if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box())
- return 0;
-
bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
@@ -2177,18 +2193,67 @@ __cpuinit int apic_is_clustered_box(void)
++zeros;
}
- /* ScaleMP vSMPowered boxes have one cluster per board and TSCs are
- * not guaranteed to be synced between boards
- */
- if (is_vsmp_box() && clusters > 1)
+ return clusters;
+}
+
+static int __cpuinitdata multi_checked;
+static int __cpuinitdata multi;
+
+static int __cpuinit set_multi(const struct dmi_system_id *d)
+{
+ if (multi)
+ return 0;
+ pr_info("APIC: %s detected, Multi Chassis\n", d->ident);
+ multi = 1;
+ return 0;
+}
+
+static const __cpuinitconst struct dmi_system_id multi_dmi_table[] = {
+ {
+ .callback = set_multi,
+ .ident = "IBM System Summit2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Summit2"),
+ },
+ },
+ {}
+};
+
+static void __cpuinit dmi_check_multi(void)
+{
+ if (multi_checked)
+ return;
+
+ dmi_check_system(multi_dmi_table);
+ multi_checked = 1;
+}
+
+/*
+ * apic_is_clustered_box() -- Check if we can expect good TSC
+ *
+ * Thus far, the major user of this is IBM's Summit2 series:
+ * Clustered boxes may have unsynced TSC problems if they are
+ * multi-chassis.
+ * Use DMI to check them
+ */
+__cpuinit int apic_is_clustered_box(void)
+{
+ dmi_check_multi();
+ if (multi)
return 1;
+ if (!is_vsmp_box())
+ return 0;
+
/*
- * If clusters > 2, then should be multi-chassis.
- * May have to revisit this when multi-core + hyperthreaded CPUs come
- * out, but AFAIK this will work even for them.
+ * ScaleMP vSMPowered boxes have one cluster per board and TSCs are
+ * not guaranteed to be synced between boards
*/
- return (clusters > 2);
+ if (apic_cluster_num() > 1)
+ return 1;
+
+ return 0;
}
#endif
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c
index 306e5e88fb6f..744e6d8af27b 100644
--- a/arch/x86/kernel/apic/apic_flat_64.c
+++ b/arch/x86/kernel/apic/apic_flat_64.c
@@ -235,7 +235,7 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
* regardless of how many processors are present (x86_64 ES7000
* is an example).
*/
- if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
+ if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
printk(KERN_DEBUG "system APIC only can use physical flat");
return 1;
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index 1c11b819f245..69328ac8de9c 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -145,7 +145,7 @@ es7000_rename_gsi(int ioapic, int gsi)
return gsi;
}
-static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
+static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
{
unsigned long vect = 0, psaival = 0;
@@ -254,7 +254,7 @@ static int parse_unisys_oem(char *oemptr)
}
#ifdef CONFIG_ACPI
-static int find_unisys_acpi_oem_table(unsigned long *oem_addr)
+static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
{
struct acpi_table_header *header = NULL;
struct es7000_oem_table *table;
@@ -285,7 +285,7 @@ static int find_unisys_acpi_oem_table(unsigned long *oem_addr)
return 0;
}
-static void unmap_unisys_acpi_oem_table(unsigned long oem_addr)
+static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
{
if (!oem_addr)
return;
@@ -306,7 +306,7 @@ static int es7000_check_dsdt(void)
static int es7000_acpi_ret;
/* Hook from generic ACPI tables.c */
-static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
unsigned long oem_addr = 0;
int check_dsdt;
@@ -717,7 +717,7 @@ struct apic apic_es7000_cluster = {
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
};
-struct apic apic_es7000 = {
+struct apic __refdata apic_es7000 = {
.name = "es7000",
.probe = probe_es7000,
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 30da617d18e4..0a3f3abfdca4 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -59,6 +59,7 @@
#include <asm/setup.h>
#include <asm/irq_remapping.h>
#include <asm/hpet.h>
+#include <asm/hw_irq.h>
#include <asm/uv/uv_hub.h>
#include <asm/uv/uv_irq.h>
@@ -129,12 +130,9 @@ struct irq_pin_list {
struct irq_pin_list *next;
};
-static struct irq_pin_list *get_one_free_irq_2_pin(int cpu)
+static struct irq_pin_list *get_one_free_irq_2_pin(int node)
{
struct irq_pin_list *pin;
- int node;
-
- node = cpu_to_node(cpu);
pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node);
@@ -148,9 +146,6 @@ struct irq_cfg {
unsigned move_cleanup_count;
u8 vector;
u8 move_in_progress : 1;
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
- u8 move_desc_pending : 1;
-#endif
};
/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
@@ -212,12 +207,9 @@ static struct irq_cfg *irq_cfg(unsigned int irq)
return cfg;
}
-static struct irq_cfg *get_one_free_irq_cfg(int cpu)
+static struct irq_cfg *get_one_free_irq_cfg(int node)
{
struct irq_cfg *cfg;
- int node;
-
- node = cpu_to_node(cpu);
cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node);
if (cfg) {
@@ -238,13 +230,13 @@ static struct irq_cfg *get_one_free_irq_cfg(int cpu)
return cfg;
}
-int arch_init_chip_data(struct irq_desc *desc, int cpu)
+int arch_init_chip_data(struct irq_desc *desc, int node)
{
struct irq_cfg *cfg;
cfg = desc->chip_data;
if (!cfg) {
- desc->chip_data = get_one_free_irq_cfg(cpu);
+ desc->chip_data = get_one_free_irq_cfg(node);
if (!desc->chip_data) {
printk(KERN_ERR "can not alloc irq_cfg\n");
BUG_ON(1);
@@ -254,10 +246,9 @@ int arch_init_chip_data(struct irq_desc *desc, int cpu)
return 0;
}
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
-
+/* for move_irq_desc */
static void
-init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu)
+init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int node)
{
struct irq_pin_list *old_entry, *head, *tail, *entry;
@@ -266,7 +257,7 @@ init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu)
if (!old_entry)
return;
- entry = get_one_free_irq_2_pin(cpu);
+ entry = get_one_free_irq_2_pin(node);
if (!entry)
return;
@@ -276,7 +267,7 @@ init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu)
tail = entry;
old_entry = old_entry->next;
while (old_entry) {
- entry = get_one_free_irq_2_pin(cpu);
+ entry = get_one_free_irq_2_pin(node);
if (!entry) {
entry = head;
while (entry) {
@@ -316,12 +307,12 @@ static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg)
}
void arch_init_copy_chip_data(struct irq_desc *old_desc,
- struct irq_desc *desc, int cpu)
+ struct irq_desc *desc, int node)
{
struct irq_cfg *cfg;
struct irq_cfg *old_cfg;
- cfg = get_one_free_irq_cfg(cpu);
+ cfg = get_one_free_irq_cfg(node);
if (!cfg)
return;
@@ -332,7 +323,7 @@ void arch_init_copy_chip_data(struct irq_desc *old_desc,
memcpy(cfg, old_cfg, sizeof(struct irq_cfg));
- init_copy_irq_2_pin(old_cfg, cfg, cpu);
+ init_copy_irq_2_pin(old_cfg, cfg, node);
}
static void free_irq_cfg(struct irq_cfg *old_cfg)
@@ -356,19 +347,7 @@ void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
old_desc->chip_data = NULL;
}
}
-
-static void
-set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
-{
- struct irq_cfg *cfg = desc->chip_data;
-
- if (!cfg->move_in_progress) {
- /* it means that domain is not changed */
- if (!cpumask_intersects(desc->affinity, mask))
- cfg->move_desc_pending = 1;
- }
-}
-#endif
+/* end for move_irq_desc */
#else
static struct irq_cfg *irq_cfg(unsigned int irq)
@@ -378,13 +357,6 @@ static struct irq_cfg *irq_cfg(unsigned int irq)
#endif
-#ifndef CONFIG_NUMA_MIGRATE_IRQ_DESC
-static inline void
-set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
-{
-}
-#endif
-
struct io_apic {
unsigned int index;
unsigned int unused[3];
@@ -518,132 +490,18 @@ static void ioapic_mask_entry(int apic, int pin)
spin_unlock_irqrestore(&ioapic_lock, flags);
}
-#ifdef CONFIG_SMP
-static void send_cleanup_vector(struct irq_cfg *cfg)
-{
- cpumask_var_t cleanup_mask;
-
- if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) {
- unsigned int i;
- cfg->move_cleanup_count = 0;
- for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
- cfg->move_cleanup_count++;
- for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
- apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR);
- } else {
- cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask);
- cfg->move_cleanup_count = cpumask_weight(cleanup_mask);
- apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
- free_cpumask_var(cleanup_mask);
- }
- cfg->move_in_progress = 0;
-}
-
-static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
-{
- int apic, pin;
- struct irq_pin_list *entry;
- u8 vector = cfg->vector;
-
- entry = cfg->irq_2_pin;
- for (;;) {
- unsigned int reg;
-
- if (!entry)
- break;
-
- apic = entry->apic;
- pin = entry->pin;
- /*
- * With interrupt-remapping, destination information comes
- * from interrupt-remapping table entry.
- */
- if (!irq_remapped(irq))
- io_apic_write(apic, 0x11 + pin*2, dest);
- reg = io_apic_read(apic, 0x10 + pin*2);
- reg &= ~IO_APIC_REDIR_VECTOR_MASK;
- reg |= vector;
- io_apic_modify(apic, 0x10 + pin*2, reg);
- if (!entry->next)
- break;
- entry = entry->next;
- }
-}
-
-static int
-assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask);
-
-/*
- * Either sets desc->affinity to a valid value, and returns
- * ->cpu_mask_to_apicid of that, or returns BAD_APICID and
- * leaves desc->affinity untouched.
- */
-static unsigned int
-set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
-{
- struct irq_cfg *cfg;
- unsigned int irq;
-
- if (!cpumask_intersects(mask, cpu_online_mask))
- return BAD_APICID;
-
- irq = desc->irq;
- cfg = desc->chip_data;
- if (assign_irq_vector(irq, cfg, mask))
- return BAD_APICID;
-
- /* check that before desc->addinity get updated */
- set_extra_move_desc(desc, mask);
-
- cpumask_copy(desc->affinity, mask);
-
- return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
-}
-
-static void
-set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
-{
- struct irq_cfg *cfg;
- unsigned long flags;
- unsigned int dest;
- unsigned int irq;
-
- irq = desc->irq;
- cfg = desc->chip_data;
-
- spin_lock_irqsave(&ioapic_lock, flags);
- dest = set_desc_affinity(desc, mask);
- if (dest != BAD_APICID) {
- /* Only the high 8 bits are valid. */
- dest = SET_APIC_LOGICAL_ID(dest);
- __target_IO_APIC_irq(irq, dest, cfg);
- }
- spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-static void
-set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
-{
- struct irq_desc *desc;
-
- desc = irq_to_desc(irq);
-
- set_ioapic_affinity_irq_desc(desc, mask);
-}
-#endif /* CONFIG_SMP */
-
/*
* The common case is 1:1 IRQ<->pin mappings. Sometimes there are
* shared ISA-space IRQs, so we have to support them. We are super
* fast in the common case, and fast for shared ISA-space IRQs.
*/
-static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin)
+static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin)
{
struct irq_pin_list *entry;
entry = cfg->irq_2_pin;
if (!entry) {
- entry = get_one_free_irq_2_pin(cpu);
+ entry = get_one_free_irq_2_pin(node);
if (!entry) {
printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n",
apic, pin);
@@ -663,7 +521,7 @@ static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin)
entry = entry->next;
}
- entry->next = get_one_free_irq_2_pin(cpu);
+ entry->next = get_one_free_irq_2_pin(node);
entry = entry->next;
entry->apic = apic;
entry->pin = pin;
@@ -672,7 +530,7 @@ static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin)
/*
* Reroute an IRQ to a different pin.
*/
-static void __init replace_pin_at_irq_cpu(struct irq_cfg *cfg, int cpu,
+static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node,
int oldapic, int oldpin,
int newapic, int newpin)
{
@@ -692,7 +550,7 @@ static void __init replace_pin_at_irq_cpu(struct irq_cfg *cfg, int cpu,
/* why? call replace before add? */
if (!replaced)
- add_pin_to_irq_cpu(cfg, cpu, newapic, newpin);
+ add_pin_to_irq_node(cfg, node, newapic, newpin);
}
static inline void io_apic_modify_irq(struct irq_cfg *cfg,
@@ -850,7 +708,6 @@ static int __init ioapic_pirq_setup(char *str)
__setup("pirq=", ioapic_pirq_setup);
#endif /* CONFIG_X86_32 */
-#ifdef CONFIG_INTR_REMAP
struct IO_APIC_route_entry **alloc_ioapic_entries(void)
{
int apic;
@@ -948,20 +805,6 @@ int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
return 0;
}
-void reinit_intr_remapped_IO_APIC(int intr_remapping,
- struct IO_APIC_route_entry **ioapic_entries)
-
-{
- /*
- * for now plain restore of previous settings.
- * TBD: In the case of OS enabling interrupt-remapping,
- * IO-APIC RTE's need to be setup to point to interrupt-remapping
- * table entries. for now, do a plain restore, and wait for
- * the setup_IO_APIC_irqs() to do proper initialization.
- */
- restore_IO_APIC_setup(ioapic_entries);
-}
-
void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
{
int apic;
@@ -971,7 +814,6 @@ void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
kfree(ioapic_entries);
}
-#endif
/*
* Find the IRQ entry number of a certain pin.
@@ -1634,7 +1476,7 @@ static void __init setup_IO_APIC_irqs(void)
int notcon = 0;
struct irq_desc *desc;
struct irq_cfg *cfg;
- int cpu = boot_cpu_id;
+ int node = cpu_to_node(boot_cpu_id);
apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
@@ -1669,13 +1511,13 @@ static void __init setup_IO_APIC_irqs(void)
apic->multi_timer_check(apic_id, irq))
continue;
- desc = irq_to_desc_alloc_cpu(irq, cpu);
+ desc = irq_to_desc_alloc_node(irq, node);
if (!desc) {
printk(KERN_INFO "can not get irq_desc for %d\n", irq);
continue;
}
cfg = desc->chip_data;
- add_pin_to_irq_cpu(cfg, cpu, apic_id, pin);
+ add_pin_to_irq_node(cfg, node, apic_id, pin);
setup_IO_APIC_irq(apic_id, pin, irq, desc,
irq_trigger(idx), irq_polarity(idx));
@@ -1869,7 +1711,7 @@ __apicdebuginit(void) print_APIC_bitfield(int base)
__apicdebuginit(void) print_local_APIC(void *dummy)
{
- unsigned int v, ver, maxlvt;
+ unsigned int i, v, ver, maxlvt;
u64 icr;
if (apic_verbosity == APIC_QUIET)
@@ -1957,6 +1799,18 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v);
v = apic_read(APIC_TDCR);
printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
+
+ if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
+ v = apic_read(APIC_EFEAT);
+ maxlvt = (v >> 16) & 0xff;
+ printk(KERN_DEBUG "... APIC EFEAT: %08x\n", v);
+ v = apic_read(APIC_ECTRL);
+ printk(KERN_DEBUG "... APIC ECTRL: %08x\n", v);
+ for (i = 0; i < maxlvt; i++) {
+ v = apic_read(APIC_EILVTn(i));
+ printk(KERN_DEBUG "... APIC EILVT%d: %08x\n", i, v);
+ }
+ }
printk("\n");
}
@@ -2360,6 +2214,118 @@ static int ioapic_retrigger_irq(unsigned int irq)
*/
#ifdef CONFIG_SMP
+static void send_cleanup_vector(struct irq_cfg *cfg)
+{
+ cpumask_var_t cleanup_mask;
+
+ if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) {
+ unsigned int i;
+ cfg->move_cleanup_count = 0;
+ for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
+ cfg->move_cleanup_count++;
+ for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
+ apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR);
+ } else {
+ cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask);
+ cfg->move_cleanup_count = cpumask_weight(cleanup_mask);
+ apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
+ free_cpumask_var(cleanup_mask);
+ }
+ cfg->move_in_progress = 0;
+}
+
+static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
+{
+ int apic, pin;
+ struct irq_pin_list *entry;
+ u8 vector = cfg->vector;
+
+ entry = cfg->irq_2_pin;
+ for (;;) {
+ unsigned int reg;
+
+ if (!entry)
+ break;
+
+ apic = entry->apic;
+ pin = entry->pin;
+ /*
+ * With interrupt-remapping, destination information comes
+ * from interrupt-remapping table entry.
+ */
+ if (!irq_remapped(irq))
+ io_apic_write(apic, 0x11 + pin*2, dest);
+ reg = io_apic_read(apic, 0x10 + pin*2);
+ reg &= ~IO_APIC_REDIR_VECTOR_MASK;
+ reg |= vector;
+ io_apic_modify(apic, 0x10 + pin*2, reg);
+ if (!entry->next)
+ break;
+ entry = entry->next;
+ }
+}
+
+static int
+assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask);
+
+/*
+ * Either sets desc->affinity to a valid value, and returns
+ * ->cpu_mask_to_apicid of that, or returns BAD_APICID and
+ * leaves desc->affinity untouched.
+ */
+static unsigned int
+set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
+{
+ struct irq_cfg *cfg;
+ unsigned int irq;
+
+ if (!cpumask_intersects(mask, cpu_online_mask))
+ return BAD_APICID;
+
+ irq = desc->irq;
+ cfg = desc->chip_data;
+ if (assign_irq_vector(irq, cfg, mask))
+ return BAD_APICID;
+
+ cpumask_copy(desc->affinity, mask);
+
+ return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+}
+
+static int
+set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
+{
+ struct irq_cfg *cfg;
+ unsigned long flags;
+ unsigned int dest;
+ unsigned int irq;
+ int ret = -1;
+
+ irq = desc->irq;
+ cfg = desc->chip_data;
+
+ spin_lock_irqsave(&ioapic_lock, flags);
+ dest = set_desc_affinity(desc, mask);
+ if (dest != BAD_APICID) {
+ /* Only the high 8 bits are valid. */
+ dest = SET_APIC_LOGICAL_ID(dest);
+ __target_IO_APIC_irq(irq, dest, cfg);
+ ret = 0;
+ }
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+
+ return ret;
+}
+
+static int
+set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
+{
+ struct irq_desc *desc;
+
+ desc = irq_to_desc(irq);
+
+ return set_ioapic_affinity_irq_desc(desc, mask);
+}
#ifdef CONFIG_INTR_REMAP
@@ -2374,26 +2340,25 @@ static int ioapic_retrigger_irq(unsigned int irq)
* Real vector that is used for interrupting cpu will be coming from
* the interrupt-remapping table entry.
*/
-static void
+static int
migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
{
struct irq_cfg *cfg;
struct irte irte;
unsigned int dest;
unsigned int irq;
+ int ret = -1;
if (!cpumask_intersects(mask, cpu_online_mask))
- return;
+ return ret;
irq = desc->irq;
if (get_irte(irq, &irte))
- return;
+ return ret;
cfg = desc->chip_data;
if (assign_irq_vector(irq, cfg, mask))
- return;
-
- set_extra_move_desc(desc, mask);
+ return ret;
dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
@@ -2409,27 +2374,30 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
send_cleanup_vector(cfg);
cpumask_copy(desc->affinity, mask);
+
+ return 0;
}
/*
* Migrates the IRQ destination in the process context.
*/
-static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
+static int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
const struct cpumask *mask)
{
- migrate_ioapic_irq_desc(desc, mask);
+ return migrate_ioapic_irq_desc(desc, mask);
}
-static void set_ir_ioapic_affinity_irq(unsigned int irq,
+static int set_ir_ioapic_affinity_irq(unsigned int irq,
const struct cpumask *mask)
{
struct irq_desc *desc = irq_to_desc(irq);
- set_ir_ioapic_affinity_irq_desc(desc, mask);
+ return set_ir_ioapic_affinity_irq_desc(desc, mask);
}
#else
-static inline void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
+static inline int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
const struct cpumask *mask)
{
+ return 0;
}
#endif
@@ -2491,86 +2459,19 @@ static void irq_complete_move(struct irq_desc **descp)
struct irq_cfg *cfg = desc->chip_data;
unsigned vector, me;
- if (likely(!cfg->move_in_progress)) {
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
- if (likely(!cfg->move_desc_pending))
- return;
-
- /* domain has not changed, but affinity did */
- me = smp_processor_id();
- if (cpumask_test_cpu(me, desc->affinity)) {
- *descp = desc = move_irq_desc(desc, me);
- /* get the new one */
- cfg = desc->chip_data;
- cfg->move_desc_pending = 0;
- }
-#endif
+ if (likely(!cfg->move_in_progress))
return;
- }
vector = ~get_irq_regs()->orig_ax;
me = smp_processor_id();
- if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) {
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
- *descp = desc = move_irq_desc(desc, me);
- /* get the new one */
- cfg = desc->chip_data;
-#endif
+ if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
send_cleanup_vector(cfg);
- }
}
#else
static inline void irq_complete_move(struct irq_desc **descp) {}
#endif
-static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
-{
- int apic, pin;
- struct irq_pin_list *entry;
-
- entry = cfg->irq_2_pin;
- for (;;) {
-
- if (!entry)
- break;
-
- apic = entry->apic;
- pin = entry->pin;
- io_apic_eoi(apic, pin);
- entry = entry->next;
- }
-}
-
-static void
-eoi_ioapic_irq(struct irq_desc *desc)
-{
- struct irq_cfg *cfg;
- unsigned long flags;
- unsigned int irq;
-
- irq = desc->irq;
- cfg = desc->chip_data;
-
- spin_lock_irqsave(&ioapic_lock, flags);
- __eoi_ioapic_irq(irq, cfg);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-#ifdef CONFIG_X86_X2APIC
-static void ack_x2apic_level(unsigned int irq)
-{
- struct irq_desc *desc = irq_to_desc(irq);
- ack_x2APIC_irq();
- eoi_ioapic_irq(desc);
-}
-
-static void ack_x2apic_edge(unsigned int irq)
-{
- ack_x2APIC_irq();
-}
-#endif
-
static void ack_apic_edge(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
@@ -2634,9 +2535,6 @@ static void ack_apic_level(unsigned int irq)
*/
ack_APIC_irq();
- if (irq_remapped(irq))
- eoi_ioapic_irq(desc);
-
/* Now we can move and renable the irq */
if (unlikely(do_unmask_irq)) {
/* Only migrate the irq if the ack has been received.
@@ -2683,22 +2581,50 @@ static void ack_apic_level(unsigned int irq)
}
#ifdef CONFIG_INTR_REMAP
+static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
+{
+ int apic, pin;
+ struct irq_pin_list *entry;
+
+ entry = cfg->irq_2_pin;
+ for (;;) {
+
+ if (!entry)
+ break;
+
+ apic = entry->apic;
+ pin = entry->pin;
+ io_apic_eoi(apic, pin);
+ entry = entry->next;
+ }
+}
+
+static void
+eoi_ioapic_irq(struct irq_desc *desc)
+{
+ struct irq_cfg *cfg;
+ unsigned long flags;
+ unsigned int irq;
+
+ irq = desc->irq;
+ cfg = desc->chip_data;
+
+ spin_lock_irqsave(&ioapic_lock, flags);
+ __eoi_ioapic_irq(irq, cfg);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
static void ir_ack_apic_edge(unsigned int irq)
{
-#ifdef CONFIG_X86_X2APIC
- if (x2apic_enabled())
- return ack_x2apic_edge(irq);
-#endif
- return ack_apic_edge(irq);
+ ack_APIC_irq();
}
static void ir_ack_apic_level(unsigned int irq)
{
-#ifdef CONFIG_X86_X2APIC
- if (x2apic_enabled())
- return ack_x2apic_level(irq);
-#endif
- return ack_apic_level(irq);
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ ack_APIC_irq();
+ eoi_ioapic_irq(desc);
}
#endif /* CONFIG_INTR_REMAP */
@@ -2903,7 +2829,7 @@ static inline void __init check_timer(void)
{
struct irq_desc *desc = irq_to_desc(0);
struct irq_cfg *cfg = desc->chip_data;
- int cpu = boot_cpu_id;
+ int node = cpu_to_node(boot_cpu_id);
int apic1, pin1, apic2, pin2;
unsigned long flags;
int no_pin1 = 0;
@@ -2969,7 +2895,7 @@ static inline void __init check_timer(void)
* Ok, does IRQ0 through the IOAPIC work?
*/
if (no_pin1) {
- add_pin_to_irq_cpu(cfg, cpu, apic1, pin1);
+ add_pin_to_irq_node(cfg, node, apic1, pin1);
setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
} else {
/* for edge trigger, setup_IO_APIC_irq already
@@ -3006,7 +2932,7 @@ static inline void __init check_timer(void)
/*
* legacy devices should be connected to IO APIC #0
*/
- replace_pin_at_irq_cpu(cfg, cpu, apic1, pin1, apic2, pin2);
+ replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2);
setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
enable_8259A_irq(0);
if (timer_irq_works()) {
@@ -3218,14 +3144,13 @@ static int nr_irqs_gsi = NR_IRQS_LEGACY;
/*
* Dynamic irq allocate and deallocation
*/
-unsigned int create_irq_nr(unsigned int irq_want)
+unsigned int create_irq_nr(unsigned int irq_want, int node)
{
/* Allocate an unused irq */
unsigned int irq;
unsigned int new;
unsigned long flags;
struct irq_cfg *cfg_new = NULL;
- int cpu = boot_cpu_id;
struct irq_desc *desc_new = NULL;
irq = 0;
@@ -3234,7 +3159,7 @@ unsigned int create_irq_nr(unsigned int irq_want)
spin_lock_irqsave(&vector_lock, flags);
for (new = irq_want; new < nr_irqs; new++) {
- desc_new = irq_to_desc_alloc_cpu(new, cpu);
+ desc_new = irq_to_desc_alloc_node(new, node);
if (!desc_new) {
printk(KERN_INFO "can not get irq_desc for %d\n", new);
continue;
@@ -3243,6 +3168,9 @@ unsigned int create_irq_nr(unsigned int irq_want)
if (cfg_new->vector != 0)
continue;
+
+ desc_new = move_irq_desc(desc_new, node);
+
if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
irq = new;
break;
@@ -3260,11 +3188,12 @@ unsigned int create_irq_nr(unsigned int irq_want)
int create_irq(void)
{
+ int node = cpu_to_node(boot_cpu_id);
unsigned int irq_want;
int irq;
irq_want = nr_irqs_gsi;
- irq = create_irq_nr(irq_want);
+ irq = create_irq_nr(irq_want, node);
if (irq == 0)
irq = -1;
@@ -3366,7 +3295,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
}
#ifdef CONFIG_SMP
-static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irq_cfg *cfg;
@@ -3375,7 +3304,7 @@ static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
dest = set_desc_affinity(desc, mask);
if (dest == BAD_APICID)
- return;
+ return -1;
cfg = desc->chip_data;
@@ -3387,13 +3316,15 @@ static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
write_msi_msg_desc(desc, &msg);
+
+ return 0;
}
#ifdef CONFIG_INTR_REMAP
/*
* Migrate the MSI irq to another cpumask. This migration is
* done in the process context using interrupt-remapping hardware.
*/
-static void
+static int
ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
{
struct irq_desc *desc = irq_to_desc(irq);
@@ -3402,11 +3333,11 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
struct irte irte;
if (get_irte(irq, &irte))
- return;
+ return -1;
dest = set_desc_affinity(desc, mask);
if (dest == BAD_APICID)
- return;
+ return -1;
irte.vector = cfg->vector;
irte.dest_id = IRTE_DEST(dest);
@@ -3423,6 +3354,8 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
*/
if (cfg->move_in_progress)
send_cleanup_vector(cfg);
+
+ return 0;
}
#endif
@@ -3518,15 +3451,17 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
unsigned int irq_want;
struct intel_iommu *iommu = NULL;
int index = 0;
+ int node;
/* x86 doesn't support multiple MSI yet */
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;
+ node = dev_to_node(&dev->dev);
irq_want = nr_irqs_gsi;
sub_handle = 0;
list_for_each_entry(msidesc, &dev->msi_list, list) {
- irq = create_irq_nr(irq_want);
+ irq = create_irq_nr(irq_want, node);
if (irq == 0)
return -1;
irq_want = irq + 1;
@@ -3576,7 +3511,7 @@ void arch_teardown_msi_irq(unsigned int irq)
#if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP)
#ifdef CONFIG_SMP
-static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irq_cfg *cfg;
@@ -3585,7 +3520,7 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
dest = set_desc_affinity(desc, mask);
if (dest == BAD_APICID)
- return;
+ return -1;
cfg = desc->chip_data;
@@ -3597,6 +3532,8 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
dmar_msi_write(irq, &msg);
+
+ return 0;
}
#endif /* CONFIG_SMP */
@@ -3630,7 +3567,7 @@ int arch_setup_dmar_msi(unsigned int irq)
#ifdef CONFIG_HPET_TIMER
#ifdef CONFIG_SMP
-static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irq_cfg *cfg;
@@ -3639,7 +3576,7 @@ static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
dest = set_desc_affinity(desc, mask);
if (dest == BAD_APICID)
- return;
+ return -1;
cfg = desc->chip_data;
@@ -3651,6 +3588,8 @@ static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
hpet_msi_write(irq, &msg);
+
+ return 0;
}
#endif /* CONFIG_SMP */
@@ -3707,7 +3646,7 @@ static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
write_ht_irq_msg(irq, &msg);
}
-static void set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irq_cfg *cfg;
@@ -3715,11 +3654,13 @@ static void set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
dest = set_desc_affinity(desc, mask);
if (dest == BAD_APICID)
- return;
+ return -1;
cfg = desc->chip_data;
target_ht_irq(irq, dest, cfg->vector);
+
+ return 0;
}
#endif
@@ -3794,6 +3735,8 @@ int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
unsigned long flags;
int err;
+ BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
cfg = irq_cfg(irq);
err = assign_irq_vector(irq, cfg, eligible_cpu);
@@ -3807,15 +3750,13 @@ int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
mmr_value = 0;
entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
- BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
- entry->vector = cfg->vector;
- entry->delivery_mode = apic->irq_delivery_mode;
- entry->dest_mode = apic->irq_dest_mode;
- entry->polarity = 0;
- entry->trigger = 0;
- entry->mask = 0;
- entry->dest = apic->cpu_mask_to_apicid(eligible_cpu);
+ entry->vector = cfg->vector;
+ entry->delivery_mode = apic->irq_delivery_mode;
+ entry->dest_mode = apic->irq_dest_mode;
+ entry->polarity = 0;
+ entry->trigger = 0;
+ entry->mask = 0;
+ entry->dest = apic->cpu_mask_to_apicid(eligible_cpu);
mmr_pnode = uv_blade_to_pnode(mmr_blade);
uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
@@ -3833,10 +3774,10 @@ void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset)
struct uv_IO_APIC_route_entry *entry;
int mmr_pnode;
+ BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
mmr_value = 0;
entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
- BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
entry->mask = 1;
mmr_pnode = uv_blade_to_pnode(mmr_blade);
@@ -3994,11 +3935,12 @@ int __init io_apic_get_version(int ioapic)
}
#endif
-int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity)
+int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
+ int triggering, int polarity)
{
struct irq_desc *desc;
struct irq_cfg *cfg;
- int cpu = boot_cpu_id;
+ int node;
if (!IO_APIC_IRQ(irq)) {
apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
@@ -4006,7 +3948,12 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
return -EINVAL;
}
- desc = irq_to_desc_alloc_cpu(irq, cpu);
+ if (dev)
+ node = dev_to_node(dev);
+ else
+ node = cpu_to_node(boot_cpu_id);
+
+ desc = irq_to_desc_alloc_node(irq, node);
if (!desc) {
printk(KERN_INFO "can not get irq_desc %d\n", irq);
return 0;
@@ -4017,7 +3964,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
*/
if (irq >= NR_IRQS_LEGACY) {
cfg = desc->chip_data;
- add_pin_to_irq_cpu(cfg, cpu, ioapic, pin);
+ add_pin_to_irq_node(cfg, node, ioapic, pin);
}
setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity);
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c
index ce4fbfa315a1..a691302dc3ff 100644
--- a/arch/x86/kernel/apic/nmi.c
+++ b/arch/x86/kernel/apic/nmi.c
@@ -104,7 +104,7 @@ static __init void nmi_cpu_busy(void *data)
}
#endif
-static void report_broken_nmi(int cpu, int *prev_nmi_count)
+static void report_broken_nmi(int cpu, unsigned int *prev_nmi_count)
{
printk(KERN_CONT "\n");
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 01eda2ac65e4..440a8bccd91a 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -160,7 +160,6 @@ extern struct apic apic_summit;
extern struct apic apic_bigsmp;
extern struct apic apic_es7000;
extern struct apic apic_es7000_cluster;
-extern struct apic apic_default;
struct apic *apic = &apic_default;
EXPORT_SYMBOL_GPL(apic);
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index 1783652bb0e5..bc3e880f9b82 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -50,7 +50,7 @@ static struct apic *apic_probe[] __initdata = {
void __init default_setup_apic_routing(void)
{
#ifdef CONFIG_X86_X2APIC
- if (x2apic && (apic != &apic_x2apic_phys &&
+ if (x2apic_mode && (apic != &apic_x2apic_phys &&
#ifdef CONFIG_X86_UV
apic != &apic_x2apic_uv_x &&
#endif
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
index 9cfe1f415d81..344eee4ac0a4 100644
--- a/arch/x86/kernel/apic/summit_32.c
+++ b/arch/x86/kernel/apic/summit_32.c
@@ -173,13 +173,6 @@ static inline int is_WPEG(struct rio_detail *rio){
rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
}
-
-/* In clustered mode, the high nibble of APIC ID is a cluster number.
- * The low nibble is a 4-bit bitmap. */
-#define XAPIC_DEST_CPUS_SHIFT 4
-#define XAPIC_DEST_CPUS_MASK ((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
-#define XAPIC_DEST_CLUSTER_MASK (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
-
#define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
static const struct cpumask *summit_target_cpus(void)
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c
index 4a903e2f0d17..8e4cbb255c38 100644
--- a/arch/x86/kernel/apic/x2apic_cluster.c
+++ b/arch/x86/kernel/apic/x2apic_cluster.c
@@ -10,7 +10,7 @@
#include <asm/apic.h>
#include <asm/ipi.h>
-DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
+static DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 2bda69352976..780a733a5e7a 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -105,7 +105,7 @@ static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask)
cpumask_set_cpu(cpu, retmask);
}
-static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip)
+static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_rip)
{
#ifdef CONFIG_SMP
unsigned long val;
@@ -583,15 +583,18 @@ void __init uv_system_init(void)
bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades();
uv_blade_info = kmalloc(bytes, GFP_KERNEL);
+ BUG_ON(!uv_blade_info);
get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size);
bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes();
uv_node_to_blade = kmalloc(bytes, GFP_KERNEL);
+ BUG_ON(!uv_node_to_blade);
memset(uv_node_to_blade, 255, bytes);
bytes = sizeof(uv_cpu_to_blade[0]) * num_possible_cpus();
uv_cpu_to_blade = kmalloc(bytes, GFP_KERNEL);
+ BUG_ON(!uv_cpu_to_blade);
memset(uv_cpu_to_blade, 255, bytes);
blade = 0;
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index c1caefc82e62..82bec86832b9 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -292,7 +292,8 @@ static const char *__cpuinit table_lookup_model(struct cpuinfo_x86 *c)
return NULL; /* Not found */
}
-__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
+__u32 cpu_caps_cleared[NCAPINTS] __cpuinitdata;
+__u32 cpu_caps_set[NCAPINTS] __cpuinitdata;
void load_percpu_segment(int cpu)
{
@@ -806,6 +807,16 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
#endif
init_hypervisor(c);
+
+ /*
+ * Clear/Set all flags overriden by options, need do it
+ * before following smp all cpus cap AND.
+ */
+ for (i = 0; i < NCAPINTS; i++) {
+ c->x86_capability[i] &= ~cpu_caps_cleared[i];
+ c->x86_capability[i] |= cpu_caps_set[i];
+ }
+
/*
* On SMP, boot_cpu_data holds the common feature set between
* all CPUs; so make sure that we indicate which features are
@@ -818,10 +829,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
}
- /* Clear all flags overriden by options */
- for (i = 0; i < NCAPINTS; i++)
- c->x86_capability[i] &= ~cleared_cpu_caps[i];
-
#ifdef CONFIG_X86_MCE
/* Init Machine Check Exception if available. */
mcheck_init(c);
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index 46e29ab96c6a..2fc4f6bb9ca5 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -588,8 +588,20 @@ static void print_apic(void *arg)
seq_printf(seq, " TMICT\t\t: %08x\n", apic_read(APIC_TMICT));
seq_printf(seq, " TMCCT\t\t: %08x\n", apic_read(APIC_TMCCT));
seq_printf(seq, " TDCR\t\t: %08x\n", apic_read(APIC_TDCR));
-#endif /* CONFIG_X86_LOCAL_APIC */
+ if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
+ unsigned int i, v, maxeilvt;
+
+ v = apic_read(APIC_EFEAT);
+ maxeilvt = (v >> 16) & 0xff;
+ seq_printf(seq, " EFEAT\t\t: %08x\n", v);
+ seq_printf(seq, " ECTRL\t\t: %08x\n", apic_read(APIC_ECTRL));
+ for (i = 0; i < maxeilvt; i++) {
+ v = apic_read(APIC_EILVTn(i));
+ seq_printf(seq, " EILVT%d\t\t: %08x\n", i, v);
+ }
+ }
+#endif /* CONFIG_X86_LOCAL_APIC */
seq_printf(seq, "\n MSR\t:\n");
}
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 6ac55bd341ae..869615193720 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -168,6 +168,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
case 0x0E: /* Core */
case 0x0F: /* Core Duo */
case 0x16: /* Celeron Core */
+ case 0x1C: /* Atom */
p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE);
case 0x0D: /* Pentium M (Dothan) */
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
index 3c28ccd49742..a8363e5be4ef 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
@@ -168,10 +168,12 @@ static int check_powernow(void)
return 1;
}
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
static void invalidate_entry(unsigned int entry)
{
powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
}
+#endif
static int get_ranges(unsigned char *pst)
{
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 4709ead2db52..e9c6f7736b1c 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -510,19 +510,10 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,
return 0;
}
-static int check_supported_cpu(unsigned int cpu)
+static long check_supported_cpu(void *unused)
{
- cpumask_t oldmask;
u32 eax, ebx, ecx, edx;
- unsigned int rc = 0;
-
- oldmask = current->cpus_allowed;
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
-
- if (smp_processor_id() != cpu) {
- printk(KERN_ERR PFX "limiting to cpu %u failed\n", cpu);
- goto out;
- }
+ unsigned int rc = -ENODEV;
if (current_cpu_data.x86_vendor != X86_VENDOR_AMD)
goto out;
@@ -562,10 +553,9 @@ static int check_supported_cpu(unsigned int cpu)
goto out;
}
- rc = 1;
+ rc = 0;
out:
- set_cpus_allowed_ptr(current, &oldmask);
return rc;
}
@@ -1121,11 +1111,16 @@ static int transition_frequency_pstate(struct powernow_k8_data *data,
return res;
}
-/* Driver entry point to switch to the target frequency */
-static int powernowk8_target(struct cpufreq_policy *pol,
- unsigned targfreq, unsigned relation)
+struct target_data {
+ struct cpufreq_policy *pol;
+ unsigned targfreq;
+ unsigned relation;
+};
+
+static long powernowk8_target_on_cpu(void *_tdata)
{
- cpumask_t oldmask;
+ struct target_data *tdata = _tdata;
+ struct cpufreq_policy *pol = tdata->pol;
struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
u32 checkfid;
u32 checkvid;
@@ -1138,22 +1133,13 @@ static int powernowk8_target(struct cpufreq_policy *pol,
checkfid = data->currfid;
checkvid = data->currvid;
- /* only run on specific CPU from here on */
- oldmask = current->cpus_allowed;
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(pol->cpu));
-
- if (smp_processor_id() != pol->cpu) {
- printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
- goto err_out;
- }
-
if (pending_bit_stuck()) {
printk(KERN_ERR PFX "failing targ, change pending bit set\n");
goto err_out;
}
dprintk("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
- pol->cpu, targfreq, pol->min, pol->max, relation);
+ pol->cpu, tdata->targfreq, pol->min, pol->max, tdata->relation);
if (query_current_values_with_pending_wait(data))
goto err_out;
@@ -1173,7 +1159,8 @@ static int powernowk8_target(struct cpufreq_policy *pol,
}
if (cpufreq_frequency_table_target(pol, data->powernow_table,
- targfreq, relation, &newstate))
+ tdata->targfreq, tdata->relation,
+ &newstate))
goto err_out;
mutex_lock(&fidvid_mutex);
@@ -1200,10 +1187,19 @@ static int powernowk8_target(struct cpufreq_policy *pol,
ret = 0;
err_out:
- set_cpus_allowed_ptr(current, &oldmask);
return ret;
}
+/* Driver entry point to switch to the target frequency */
+static int powernowk8_target(struct cpufreq_policy *pol,
+ unsigned targfreq, unsigned relation)
+{
+ struct target_data tdata = { .pol = pol,
+ .targfreq = targfreq,
+ .relation = relation };
+ return work_on_cpu(pol->cpu, powernowk8_target_on_cpu, &tdata);
+}
+
/* Driver entry point to verify the policy and range of frequencies */
static int powernowk8_verify(struct cpufreq_policy *pol)
{
@@ -1215,19 +1211,42 @@ static int powernowk8_verify(struct cpufreq_policy *pol)
return cpufreq_frequency_table_verify(pol, data->powernow_table);
}
+static long __cpuinit powernowk8_cpu_init_on_cpu(void *_data)
+{
+ struct powernow_k8_data *data = _data;
+
+ if (smp_processor_id() != data->cpu) {
+ printk(KERN_ERR PFX "limiting to cpu %u failed\n", data->cpu);
+ return -EIO;
+ }
+
+ if (pending_bit_stuck()) {
+ printk(KERN_ERR PFX "failing init, change pending bit set\n");
+ return -ENODEV;
+ }
+
+ if (query_current_values_with_pending_wait(data))
+ return -ENODEV;
+
+ if (cpu_family == CPU_OPTERON)
+ fidvid_msr_init();
+
+ return 0;
+}
+
/* per CPU init entry point to the driver */
static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
{
struct powernow_k8_data *data;
- cpumask_t oldmask;
int rc;
static int print_once;
if (!cpu_online(pol->cpu))
return -ENODEV;
- if (!check_supported_cpu(pol->cpu))
- return -ENODEV;
+ rc = work_on_cpu(pol->cpu, check_supported_cpu, NULL);
+ if (rc != 0)
+ return rc;
data = kzalloc(sizeof(struct powernow_k8_data), GFP_KERNEL);
if (!data) {
@@ -1278,27 +1297,9 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
pol->cpuinfo.transition_latency = get_transition_latency(data);
/* only run on specific CPU from here on */
- oldmask = current->cpus_allowed;
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(pol->cpu));
-
- if (smp_processor_id() != pol->cpu) {
- printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
- goto err_out_unmask;
- }
-
- if (pending_bit_stuck()) {
- printk(KERN_ERR PFX "failing init, change pending bit set\n");
- goto err_out_unmask;
- }
-
- if (query_current_values_with_pending_wait(data))
- goto err_out_unmask;
-
- if (cpu_family == CPU_OPTERON)
- fidvid_msr_init();
-
- /* run on any CPU again */
- set_cpus_allowed_ptr(current, &oldmask);
+ rc = work_on_cpu(data->cpu, powernowk8_cpu_init_on_cpu, data);
+ if (rc != 0)
+ goto err_out_exit_acpi;
if (cpu_family == CPU_HW_PSTATE)
cpumask_copy(pol->cpus, cpumask_of(pol->cpu));
@@ -1335,8 +1336,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
return 0;
-err_out_unmask:
- set_cpus_allowed_ptr(current, &oldmask);
+err_out_exit_acpi:
powernow_k8_cpu_exit_acpi(data);
err_out:
@@ -1361,12 +1361,20 @@ static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol)
return 0;
}
+static void query_values_on_cpu(void *_err)
+{
+ int *err = _err;
+ struct powernow_k8_data *data = __get_cpu_var(powernow_data);
+
+ *err = query_current_values_with_pending_wait(data);
+}
+
static unsigned int powernowk8_get(unsigned int cpu)
{
struct powernow_k8_data *data;
- cpumask_t oldmask = current->cpus_allowed;
unsigned int khz = 0;
unsigned int first;
+ int err;
first = cpumask_first(cpu_core_mask(cpu));
data = per_cpu(powernow_data, first);
@@ -1374,15 +1382,8 @@ static unsigned int powernowk8_get(unsigned int cpu)
if (!data)
return -EINVAL;
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
- if (smp_processor_id() != cpu) {
- printk(KERN_ERR PFX
- "limiting to CPU %d failed in powernowk8_get\n", cpu);
- set_cpus_allowed_ptr(current, &oldmask);
- return 0;
- }
-
- if (query_current_values_with_pending_wait(data))
+ smp_call_function_single(first, query_values_on_cpu, &err, true);
+ if (err)
goto out;
if (cpu_family == CPU_HW_PSTATE)
@@ -1393,7 +1394,6 @@ static unsigned int powernowk8_get(unsigned int cpu)
out:
- set_cpus_allowed_ptr(current, &oldmask);
return khz;
}
@@ -1419,7 +1419,7 @@ static int __cpuinit powernowk8_init(void)
unsigned int i, supported_cpus = 0;
for_each_online_cpu(i) {
- if (check_supported_cpu(i))
+ if (work_on_cpu(i, check_supported_cpu, NULL) == 0)
supported_cpus++;
}
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
index c9f1fdc02830..c9727f62a820 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -323,14 +323,8 @@ static unsigned int get_cur_freq(unsigned int cpu)
{
unsigned l, h;
unsigned clock_freq;
- cpumask_t saved_mask;
- saved_mask = current->cpus_allowed;
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
- if (smp_processor_id() != cpu)
- return 0;
-
- rdmsr(MSR_IA32_PERF_STATUS, l, h);
+ rdmsr_on_cpu(cpu, MSR_IA32_PERF_STATUS, &l, &h);
clock_freq = extract_clock(l, cpu, 0);
if (unlikely(clock_freq == 0)) {
@@ -340,11 +334,9 @@ static unsigned int get_cur_freq(unsigned int cpu)
* P-state transition (like TM2). Get the last freq set
* in PERF_CTL.
*/
- rdmsr(MSR_IA32_PERF_CTL, l, h);
+ rdmsr_on_cpu(cpu, MSR_IA32_PERF_CTL, &l, &h);
clock_freq = extract_clock(l, cpu, 1);
}
-
- set_cpus_allowed_ptr(current, &saved_mask);
return clock_freq;
}
@@ -467,15 +459,10 @@ static int centrino_target (struct cpufreq_policy *policy,
struct cpufreq_freqs freqs;
int retval = 0;
unsigned int j, k, first_cpu, tmp;
- cpumask_var_t saved_mask, covered_cpus;
+ cpumask_var_t covered_cpus;
- if (unlikely(!alloc_cpumask_var(&saved_mask, GFP_KERNEL)))
- return -ENOMEM;
- if (unlikely(!alloc_cpumask_var(&covered_cpus, GFP_KERNEL))) {
- free_cpumask_var(saved_mask);
+ if (unlikely(!alloc_cpumask_var(&covered_cpus, GFP_KERNEL)))
return -ENOMEM;
- }
- cpumask_copy(saved_mask, &current->cpus_allowed);
if (unlikely(per_cpu(centrino_model, cpu) == NULL)) {
retval = -ENODEV;
@@ -493,7 +480,7 @@ static int centrino_target (struct cpufreq_policy *policy,
first_cpu = 1;
for_each_cpu(j, policy->cpus) {
- const struct cpumask *mask;
+ int good_cpu;
/* cpufreq holds the hotplug lock, so we are safe here */
if (!cpu_online(j))
@@ -504,32 +491,30 @@ static int centrino_target (struct cpufreq_policy *policy,
* Make sure we are running on CPU that wants to change freq
*/
if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
- mask = policy->cpus;
+ good_cpu = cpumask_any_and(policy->cpus,
+ cpu_online_mask);
else
- mask = cpumask_of(j);
+ good_cpu = j;
- set_cpus_allowed_ptr(current, mask);
- preempt_disable();
- if (unlikely(!cpu_isset(smp_processor_id(), *mask))) {
+ if (good_cpu >= nr_cpu_ids) {
dprintk("couldn't limit to CPUs in this domain\n");
retval = -EAGAIN;
if (first_cpu) {
/* We haven't started the transition yet. */
- goto migrate_end;
+ goto out;
}
- preempt_enable();
break;
}
msr = per_cpu(centrino_model, cpu)->op_points[newstate].index;
if (first_cpu) {
- rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
+ rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h);
if (msr == (oldmsr & 0xffff)) {
dprintk("no change needed - msr was and needs "
"to be %x\n", oldmsr);
retval = 0;
- goto migrate_end;
+ goto out;
}
freqs.old = extract_clock(oldmsr, cpu, 0);
@@ -553,14 +538,11 @@ static int centrino_target (struct cpufreq_policy *policy,
oldmsr |= msr;
}
- wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);
- if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
- preempt_enable();
+ wrmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, oldmsr, h);
+ if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
break;
- }
- cpu_set(j, *covered_cpus);
- preempt_enable();
+ cpumask_set_cpu(j, covered_cpus);
}
for_each_cpu(k, policy->cpus) {
@@ -578,10 +560,8 @@ static int centrino_target (struct cpufreq_policy *policy,
* Best effort undo..
*/
- for_each_cpu_mask_nr(j, *covered_cpus) {
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(j));
- wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);
- }
+ for_each_cpu(j, covered_cpus)
+ wrmsr_on_cpu(j, MSR_IA32_PERF_CTL, oldmsr, h);
tmp = freqs.new;
freqs.new = freqs.old;
@@ -593,15 +573,9 @@ static int centrino_target (struct cpufreq_policy *policy,
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
}
- set_cpus_allowed_ptr(current, saved_mask);
retval = 0;
- goto out;
-migrate_end:
- preempt_enable();
- set_cpus_allowed_ptr(current, saved_mask);
out:
- free_cpumask_var(saved_mask);
free_cpumask_var(covered_cpus);
return retval;
}
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index 016c1a4fa3fc..ed9c539ba646 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -89,7 +89,8 @@ static int speedstep_find_register(void)
* speedstep_set_state - set the SpeedStep state
* @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
*
- * Tries to change the SpeedStep state.
+ * Tries to change the SpeedStep state. Can be called from
+ * smp_call_function_single.
*/
static void speedstep_set_state(unsigned int state)
{
@@ -143,6 +144,11 @@ static void speedstep_set_state(unsigned int state)
return;
}
+/* Wrapper for smp_call_function_single. */
+static void _speedstep_set_state(void *_state)
+{
+ speedstep_set_state(*(unsigned int *)_state);
+}
/**
* speedstep_activate - activate SpeedStep control in the chipset
@@ -226,22 +232,28 @@ static unsigned int speedstep_detect_chipset(void)
return 0;
}
-static unsigned int _speedstep_get(const struct cpumask *cpus)
-{
+struct get_freq_data {
unsigned int speed;
- cpumask_t cpus_allowed;
-
- cpus_allowed = current->cpus_allowed;
- set_cpus_allowed_ptr(current, cpus);
- speed = speedstep_get_frequency(speedstep_processor);
- set_cpus_allowed_ptr(current, &cpus_allowed);
- dprintk("detected %u kHz as current frequency\n", speed);
- return speed;
+ unsigned int processor;
+};
+
+static void get_freq_data(void *_data)
+{
+ struct get_freq_data *data = _data;
+
+ data->speed = speedstep_get_frequency(data->processor);
}
static unsigned int speedstep_get(unsigned int cpu)
{
- return _speedstep_get(cpumask_of(cpu));
+ struct get_freq_data data = { .processor = cpu };
+
+ /* You're supposed to ensure CPU is online. */
+ if (smp_call_function_single(cpu, get_freq_data, &data, 1) != 0)
+ BUG();
+
+ dprintk("detected %u kHz as current frequency\n", data.speed);
+ return data.speed;
}
/**
@@ -257,16 +269,16 @@ static int speedstep_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
- unsigned int newstate = 0;
+ unsigned int newstate = 0, policy_cpu;
struct cpufreq_freqs freqs;
- cpumask_t cpus_allowed;
int i;
if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
target_freq, relation, &newstate))
return -EINVAL;
- freqs.old = _speedstep_get(policy->cpus);
+ policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask);
+ freqs.old = speedstep_get(policy_cpu);
freqs.new = speedstep_freqs[newstate].frequency;
freqs.cpu = policy->cpu;
@@ -276,20 +288,13 @@ static int speedstep_target(struct cpufreq_policy *policy,
if (freqs.old == freqs.new)
return 0;
- cpus_allowed = current->cpus_allowed;
-
for_each_cpu(i, policy->cpus) {
freqs.cpu = i;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
}
- /* switch to physical CPU where state is to be changed */
- set_cpus_allowed_ptr(current, policy->cpus);
-
- speedstep_set_state(newstate);
-
- /* allow to be run on all CPUs */
- set_cpus_allowed_ptr(current, &cpus_allowed);
+ smp_call_function_single(policy_cpu, _speedstep_set_state, &newstate,
+ true);
for_each_cpu(i, policy->cpus) {
freqs.cpu = i;
@@ -312,33 +317,35 @@ static int speedstep_verify(struct cpufreq_policy *policy)
return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
}
+static long get_freqs_on_cpu(void *_policy)
+{
+ struct cpufreq_policy *policy = _policy;
+
+ return speedstep_get_freqs(speedstep_processor,
+ &speedstep_freqs[SPEEDSTEP_LOW].frequency,
+ &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+ &policy->cpuinfo.transition_latency,
+ &speedstep_set_state);
+}
static int speedstep_cpu_init(struct cpufreq_policy *policy)
{
- int result = 0;
- unsigned int speed;
- cpumask_t cpus_allowed;
+ int result;
+ unsigned int policy_cpu, speed;
/* only run on CPU to be set, or on its sibling */
#ifdef CONFIG_SMP
cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
#endif
-
- cpus_allowed = current->cpus_allowed;
- set_cpus_allowed_ptr(current, policy->cpus);
+ policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask);
/* detect low and high frequency and transition latency */
- result = speedstep_get_freqs(speedstep_processor,
- &speedstep_freqs[SPEEDSTEP_LOW].frequency,
- &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
- &policy->cpuinfo.transition_latency,
- &speedstep_set_state);
- set_cpus_allowed_ptr(current, &cpus_allowed);
+ result = work_on_cpu(policy_cpu, get_freqs_on_cpu, policy);
if (result)
return result;
/* get current speed setting */
- speed = _speedstep_get(policy->cpus);
+ speed = speedstep_get(policy_cpu);
if (!speed)
return -EIO;
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
index 2e3c6862657b..f4c290b8482f 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
@@ -226,6 +226,7 @@ static unsigned int pentium4_get_frequency(void)
}
+/* Warning: may get called from smp_call_function_single. */
unsigned int speedstep_get_frequency(unsigned int processor)
{
switch (processor) {
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 483eda96e102..789efe217e1a 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -17,6 +17,7 @@
#include <asm/processor.h>
#include <asm/smp.h>
+#include <asm/k8.h>
#define LVL_1_INST 1
#define LVL_1_DATA 2
@@ -159,14 +160,6 @@ struct _cpuid4_info_regs {
unsigned long can_disable;
};
-#if defined(CONFIG_PCI) && defined(CONFIG_SYSFS)
-static struct pci_device_id k8_nb_id[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) },
- {}
-};
-#endif
-
unsigned short num_cache_leaves;
/* AMD doesn't have CPUID4. Emulate it here to report the same
@@ -207,10 +200,17 @@ union l3_cache {
};
static const unsigned short __cpuinitconst assocs[] = {
- [1] = 1, [2] = 2, [4] = 4, [6] = 8,
- [8] = 16, [0xa] = 32, [0xb] = 48,
+ [1] = 1,
+ [2] = 2,
+ [4] = 4,
+ [6] = 8,
+ [8] = 16,
+ [0xa] = 32,
+ [0xb] = 48,
[0xc] = 64,
- [0xf] = 0xffff // ??
+ [0xd] = 96,
+ [0xe] = 128,
+ [0xf] = 0xffff /* fully associative - no way to show this currently */
};
static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
@@ -271,7 +271,8 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
eax->split.type = types[leaf];
eax->split.level = levels[leaf];
if (leaf == 3)
- eax->split.num_threads_sharing = current_cpu_data.x86_max_cores - 1;
+ eax->split.num_threads_sharing =
+ current_cpu_data.x86_max_cores - 1;
else
eax->split.num_threads_sharing = 0;
eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
@@ -291,6 +292,14 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
{
if (index < 3)
return;
+
+ if (boot_cpu_data.x86 == 0x11)
+ return;
+
+ /* see erratum #382 */
+ if ((boot_cpu_data.x86 == 0x10) && (boot_cpu_data.x86_model < 0x8))
+ return;
+
this_leaf->can_disable = 1;
}
@@ -696,97 +705,75 @@ static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf)
#define to_object(k) container_of(k, struct _index_kobject, kobj)
#define to_attr(a) container_of(a, struct _cache_attr, attr)
-#ifdef CONFIG_PCI
-static struct pci_dev *get_k8_northbridge(int node)
-{
- struct pci_dev *dev = NULL;
- int i;
-
- for (i = 0; i <= node; i++) {
- do {
- dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
- if (!dev)
- break;
- } while (!pci_match_id(&k8_nb_id[0], dev));
- if (!dev)
- break;
- }
- return dev;
-}
-#else
-static struct pci_dev *get_k8_northbridge(int node)
-{
- return NULL;
-}
-#endif
-
-static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf)
+static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
+ unsigned int index)
{
- const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
- int node = cpu_to_node(cpumask_first(mask));
- struct pci_dev *dev = NULL;
- ssize_t ret = 0;
- int i;
+ int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
+ int node = cpu_to_node(cpu);
+ struct pci_dev *dev = node_to_k8_nb_misc(node);
+ unsigned int reg = 0;
if (!this_leaf->can_disable)
- return sprintf(buf, "Feature not enabled\n");
-
- dev = get_k8_northbridge(node);
- if (!dev) {
- printk(KERN_ERR "Attempting AMD northbridge operation on a system with no northbridge\n");
return -EINVAL;
- }
- for (i = 0; i < 2; i++) {
- unsigned int reg;
+ if (!dev)
+ return -EINVAL;
- pci_read_config_dword(dev, 0x1BC + i * 4, &reg);
+ pci_read_config_dword(dev, 0x1BC + index * 4, &reg);
+ return sprintf(buf, "%x\n", reg);
+}
- ret += sprintf(buf, "%sEntry: %d\n", buf, i);
- ret += sprintf(buf, "%sReads: %s\tNew Entries: %s\n",
- buf,
- reg & 0x80000000 ? "Disabled" : "Allowed",
- reg & 0x40000000 ? "Disabled" : "Allowed");
- ret += sprintf(buf, "%sSubCache: %x\tIndex: %x\n",
- buf, (reg & 0x30000) >> 16, reg & 0xfff);
- }
- return ret;
+#define SHOW_CACHE_DISABLE(index) \
+static ssize_t \
+show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
+{ \
+ return show_cache_disable(this_leaf, buf, index); \
}
+SHOW_CACHE_DISABLE(0)
+SHOW_CACHE_DISABLE(1)
-static ssize_t
-store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf,
- size_t count)
+static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
+ const char *buf, size_t count, unsigned int index)
{
- const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
- int node = cpu_to_node(cpumask_first(mask));
- struct pci_dev *dev = NULL;
- unsigned int ret, index, val;
+ int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
+ int node = cpu_to_node(cpu);
+ struct pci_dev *dev = node_to_k8_nb_misc(node);
+ unsigned long val = 0;
+ unsigned int scrubber = 0;
if (!this_leaf->can_disable)
- return 0;
-
- if (strlen(buf) > 15)
return -EINVAL;
- ret = sscanf(buf, "%x %x", &index, &val);
- if (ret != 2)
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (!dev)
return -EINVAL;
- if (index > 1)
+
+ if (strict_strtoul(buf, 10, &val) < 0)
return -EINVAL;
val |= 0xc0000000;
- dev = get_k8_northbridge(node);
- if (!dev) {
- printk(KERN_ERR "Attempting AMD northbridge operation on a system with no northbridge\n");
- return -EINVAL;
- }
+
+ pci_read_config_dword(dev, 0x58, &scrubber);
+ scrubber &= ~0x1f000000;
+ pci_write_config_dword(dev, 0x58, scrubber);
pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
wbinvd();
pci_write_config_dword(dev, 0x1BC + index * 4, val);
+ return count;
+}
- return 1;
+#define STORE_CACHE_DISABLE(index) \
+static ssize_t \
+store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
+ const char *buf, size_t count) \
+{ \
+ return store_cache_disable(this_leaf, buf, count, index); \
}
+STORE_CACHE_DISABLE(0)
+STORE_CACHE_DISABLE(1)
struct _cache_attr {
struct attribute attr;
@@ -808,7 +795,10 @@ define_one_ro(size);
define_one_ro(shared_cpu_map);
define_one_ro(shared_cpu_list);
-static struct _cache_attr cache_disable = __ATTR(cache_disable, 0644, show_cache_disable, store_cache_disable);
+static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
+ show_cache_disable_0, store_cache_disable_0);
+static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
+ show_cache_disable_1, store_cache_disable_1);
static struct attribute * default_attrs[] = {
&type.attr,
@@ -820,7 +810,8 @@ static struct attribute * default_attrs[] = {
&size.attr,
&shared_cpu_map.attr,
&shared_cpu_list.attr,
- &cache_disable.attr,
+ &cache_disable_0.attr,
+ &cache_disable_1.attr,
NULL
};
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
index d6b72df89d69..65a0fceedcd7 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
@@ -15,7 +15,6 @@
#include <asm/hw_irq.h>
#include <asm/idle.h>
#include <asm/therm_throt.h>
-#include <asm/apic.h>
asmlinkage void smp_thermal_interrupt(void)
{
@@ -151,10 +150,11 @@ static void print_update(char *type, int *hdr, int num)
static void cmci_discover(int banks, int boot)
{
unsigned long *owned = (void *)&__get_cpu_var(mce_banks_owned);
+ unsigned long flags;
int hdr = 0;
int i;
- spin_lock(&cmci_discover_lock);
+ spin_lock_irqsave(&cmci_discover_lock, flags);
for (i = 0; i < banks; i++) {
u64 val;
@@ -184,7 +184,7 @@ static void cmci_discover(int banks, int boot)
WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks)));
}
}
- spin_unlock(&cmci_discover_lock);
+ spin_unlock_irqrestore(&cmci_discover_lock, flags);
if (hdr)
printk(KERN_CONT "\n");
}
@@ -211,13 +211,14 @@ void cmci_recheck(void)
*/
void cmci_clear(void)
{
+ unsigned long flags;
int i;
int banks;
u64 val;
if (!cmci_supported(&banks))
return;
- spin_lock(&cmci_discover_lock);
+ spin_lock_irqsave(&cmci_discover_lock, flags);
for (i = 0; i < banks; i++) {
if (!test_bit(i, __get_cpu_var(mce_banks_owned)))
continue;
@@ -227,7 +228,7 @@ void cmci_clear(void)
wrmsrl(MSR_IA32_MC0_CTL2 + i, val);
__clear_bit(i, __get_cpu_var(mce_banks_owned));
}
- spin_unlock(&cmci_discover_lock);
+ spin_unlock_irqrestore(&cmci_discover_lock, flags);
}
/*
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 0b776c09aff3..d21d4fb161f7 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -275,7 +275,11 @@ static void __init print_mtrr_state(void)
}
printk(KERN_DEBUG "MTRR variable ranges %sabled:\n",
mtrr_state.enabled & 2 ? "en" : "dis");
- high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4;
+ if (size_or_mask & 0xffffffffUL)
+ high_width = ffs(size_or_mask & 0xffffffffUL) - 1;
+ else
+ high_width = ffs(size_or_mask>>32) + 32 - 1;
+ high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4;
for (i = 0; i < num_var_ranges; ++i) {
if (mtrr_state.var_ranges[i].mask_lo & (1 << 11))
printk(KERN_DEBUG " %u base %0*X%05X000 mask %0*X%05X000 %s\n",
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
index 87b67e3a765a..48bfe1386038 100644
--- a/arch/x86/kernel/ds.c
+++ b/arch/x86/kernel/ds.c
@@ -19,45 +19,61 @@
* Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
*/
-
-#include <asm/ds.h>
-
-#include <linux/errno.h>
+#include <linux/kernel.h>
#include <linux/string.h>
-#include <linux/slab.h>
+#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/mm.h>
-#include <linux/kernel.h>
+#include <linux/trace_clock.h>
+
+#include <asm/ds.h>
+#include "ds_selftest.h"
/*
- * The configuration for a particular DS hardware implementation.
+ * The configuration for a particular DS hardware implementation:
*/
struct ds_configuration {
- /* the name of the configuration */
- const char *name;
- /* the size of one pointer-typed field in the DS structure and
- in the BTS and PEBS buffers in bytes;
- this covers the first 8 DS fields related to buffer management. */
- unsigned char sizeof_field;
- /* the size of a BTS/PEBS record in bytes */
- unsigned char sizeof_rec[2];
- /* a series of bit-masks to control various features indexed
- * by enum ds_feature */
- unsigned long ctl[dsf_ctl_max];
+ /* The name of the configuration: */
+ const char *name;
+
+ /* The size of pointer-typed fields in DS, BTS, and PEBS: */
+ unsigned char sizeof_ptr_field;
+
+ /* The size of a BTS/PEBS record in bytes: */
+ unsigned char sizeof_rec[2];
+
+ /* The number of pebs counter reset values in the DS structure. */
+ unsigned char nr_counter_reset;
+
+ /* Control bit-masks indexed by enum ds_feature: */
+ unsigned long ctl[dsf_ctl_max];
};
-static DEFINE_PER_CPU(struct ds_configuration, ds_cfg_array);
+static struct ds_configuration ds_cfg __read_mostly;
+
+
+/* Maximal size of a DS configuration: */
+#define MAX_SIZEOF_DS 0x80
-#define ds_cfg per_cpu(ds_cfg_array, smp_processor_id())
+/* Maximal size of a BTS record: */
+#define MAX_SIZEOF_BTS (3 * 8)
-#define MAX_SIZEOF_DS (12 * 8) /* maximal size of a DS configuration */
-#define MAX_SIZEOF_BTS (3 * 8) /* maximal size of a BTS record */
-#define DS_ALIGNMENT (1 << 3) /* BTS and PEBS buffer alignment */
+/* BTS and PEBS buffer alignment: */
+#define DS_ALIGNMENT (1 << 3)
-#define BTS_CONTROL \
- (ds_cfg.ctl[dsf_bts] | ds_cfg.ctl[dsf_bts_kernel] | ds_cfg.ctl[dsf_bts_user] |\
- ds_cfg.ctl[dsf_bts_overflow])
+/* Number of buffer pointers in DS: */
+#define NUM_DS_PTR_FIELDS 8
+/* Size of a pebs reset value in DS: */
+#define PEBS_RESET_FIELD_SIZE 8
+
+/* Mask of control bits in the DS MSR register: */
+#define BTS_CONTROL \
+ ( ds_cfg.ctl[dsf_bts] | \
+ ds_cfg.ctl[dsf_bts_kernel] | \
+ ds_cfg.ctl[dsf_bts_user] | \
+ ds_cfg.ctl[dsf_bts_overflow] )
/*
* A BTS or PEBS tracer.
@@ -66,29 +82,36 @@ static DEFINE_PER_CPU(struct ds_configuration, ds_cfg_array);
* to identify tracers.
*/
struct ds_tracer {
- /* the DS context (partially) owned by this tracer */
- struct ds_context *context;
- /* the buffer provided on ds_request() and its size in bytes */
- void *buffer;
- size_t size;
+ /* The DS context (partially) owned by this tracer. */
+ struct ds_context *context;
+ /* The buffer provided on ds_request() and its size in bytes. */
+ void *buffer;
+ size_t size;
};
struct bts_tracer {
- /* the common DS part */
- struct ds_tracer ds;
- /* the trace including the DS configuration */
- struct bts_trace trace;
- /* buffer overflow notification function */
- bts_ovfl_callback_t ovfl;
+ /* The common DS part: */
+ struct ds_tracer ds;
+
+ /* The trace including the DS configuration: */
+ struct bts_trace trace;
+
+ /* Buffer overflow notification function: */
+ bts_ovfl_callback_t ovfl;
+
+ /* Active flags affecting trace collection. */
+ unsigned int flags;
};
struct pebs_tracer {
- /* the common DS part */
- struct ds_tracer ds;
- /* the trace including the DS configuration */
- struct pebs_trace trace;
- /* buffer overflow notification function */
- pebs_ovfl_callback_t ovfl;
+ /* The common DS part: */
+ struct ds_tracer ds;
+
+ /* The trace including the DS configuration: */
+ struct pebs_trace trace;
+
+ /* Buffer overflow notification function: */
+ pebs_ovfl_callback_t ovfl;
};
/*
@@ -97,6 +120,7 @@ struct pebs_tracer {
*
* The DS configuration consists of the following fields; different
* architetures vary in the size of those fields.
+ *
* - double-word aligned base linear address of the BTS buffer
* - write pointer into the BTS buffer
* - end linear address of the BTS buffer (one byte beyond the end of
@@ -135,21 +159,22 @@ enum ds_field {
};
enum ds_qualifier {
- ds_bts = 0,
+ ds_bts = 0,
ds_pebs
};
-static inline unsigned long ds_get(const unsigned char *base,
- enum ds_qualifier qual, enum ds_field field)
+static inline unsigned long
+ds_get(const unsigned char *base, enum ds_qualifier qual, enum ds_field field)
{
- base += (ds_cfg.sizeof_field * (field + (4 * qual)));
+ base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
return *(unsigned long *)base;
}
-static inline void ds_set(unsigned char *base, enum ds_qualifier qual,
- enum ds_field field, unsigned long value)
+static inline void
+ds_set(unsigned char *base, enum ds_qualifier qual, enum ds_field field,
+ unsigned long value)
{
- base += (ds_cfg.sizeof_field * (field + (4 * qual)));
+ base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
(*(unsigned long *)base) = value;
}
@@ -159,7 +184,6 @@ static inline void ds_set(unsigned char *base, enum ds_qualifier qual,
*/
static DEFINE_SPINLOCK(ds_lock);
-
/*
* We either support (system-wide) per-cpu or per-thread allocation.
* We distinguish the two based on the task_struct pointer, where a
@@ -178,12 +202,28 @@ static DEFINE_SPINLOCK(ds_lock);
*/
static atomic_t tracers = ATOMIC_INIT(0);
-static inline void get_tracer(struct task_struct *task)
+static inline int get_tracer(struct task_struct *task)
{
- if (task)
+ int error;
+
+ spin_lock_irq(&ds_lock);
+
+ if (task) {
+ error = -EPERM;
+ if (atomic_read(&tracers) < 0)
+ goto out;
atomic_inc(&tracers);
- else
+ } else {
+ error = -EPERM;
+ if (atomic_read(&tracers) > 0)
+ goto out;
atomic_dec(&tracers);
+ }
+
+ error = 0;
+out:
+ spin_unlock_irq(&ds_lock);
+ return error;
}
static inline void put_tracer(struct task_struct *task)
@@ -194,14 +234,6 @@ static inline void put_tracer(struct task_struct *task)
atomic_inc(&tracers);
}
-static inline int check_tracer(struct task_struct *task)
-{
- return task ?
- (atomic_read(&tracers) >= 0) :
- (atomic_read(&tracers) <= 0);
-}
-
-
/*
* The DS context is either attached to a thread or to a cpu:
* - in the former case, the thread_struct contains a pointer to the
@@ -213,61 +245,58 @@ static inline int check_tracer(struct task_struct *task)
* deallocated when the last user puts the context.
*/
struct ds_context {
- /* pointer to the DS configuration; goes into MSR_IA32_DS_AREA */
- unsigned char ds[MAX_SIZEOF_DS];
- /* the owner of the BTS and PEBS configuration, respectively */
- struct bts_tracer *bts_master;
- struct pebs_tracer *pebs_master;
- /* use count */
- unsigned long count;
- /* a pointer to the context location inside the thread_struct
- * or the per_cpu context array */
- struct ds_context **this;
- /* a pointer to the task owning this context, or NULL, if the
- * context is owned by a cpu */
- struct task_struct *task;
-};
+ /* The DS configuration; goes into MSR_IA32_DS_AREA: */
+ unsigned char ds[MAX_SIZEOF_DS];
+
+ /* The owner of the BTS and PEBS configuration, respectively: */
+ struct bts_tracer *bts_master;
+ struct pebs_tracer *pebs_master;
-static DEFINE_PER_CPU(struct ds_context *, system_context_array);
+ /* Use count: */
+ unsigned long count;
-#define system_context per_cpu(system_context_array, smp_processor_id())
+ /* Pointer to the context pointer field: */
+ struct ds_context **this;
+
+ /* The traced task; NULL for cpu tracing: */
+ struct task_struct *task;
+
+ /* The traced cpu; only valid if task is NULL: */
+ int cpu;
+};
+static DEFINE_PER_CPU(struct ds_context *, cpu_context);
-static inline struct ds_context *ds_get_context(struct task_struct *task)
+
+static struct ds_context *ds_get_context(struct task_struct *task, int cpu)
{
struct ds_context **p_context =
- (task ? &task->thread.ds_ctx : &system_context);
+ (task ? &task->thread.ds_ctx : &per_cpu(cpu_context, cpu));
struct ds_context *context = NULL;
struct ds_context *new_context = NULL;
- unsigned long irq;
/* Chances are small that we already have a context. */
new_context = kzalloc(sizeof(*new_context), GFP_KERNEL);
if (!new_context)
return NULL;
- spin_lock_irqsave(&ds_lock, irq);
+ spin_lock_irq(&ds_lock);
context = *p_context;
- if (!context) {
+ if (likely(!context)) {
context = new_context;
context->this = p_context;
context->task = task;
+ context->cpu = cpu;
context->count = 0;
- if (task)
- set_tsk_thread_flag(task, TIF_DS_AREA_MSR);
-
- if (!task || (task == current))
- wrmsrl(MSR_IA32_DS_AREA, (unsigned long)context->ds);
-
*p_context = context;
}
context->count++;
- spin_unlock_irqrestore(&ds_lock, irq);
+ spin_unlock_irq(&ds_lock);
if (context != new_context)
kfree(new_context);
@@ -275,8 +304,9 @@ static inline struct ds_context *ds_get_context(struct task_struct *task)
return context;
}
-static inline void ds_put_context(struct ds_context *context)
+static void ds_put_context(struct ds_context *context)
{
+ struct task_struct *task;
unsigned long irq;
if (!context)
@@ -291,17 +321,55 @@ static inline void ds_put_context(struct ds_context *context)
*(context->this) = NULL;
- if (context->task)
- clear_tsk_thread_flag(context->task, TIF_DS_AREA_MSR);
+ task = context->task;
+
+ if (task)
+ clear_tsk_thread_flag(task, TIF_DS_AREA_MSR);
- if (!context->task || (context->task == current))
- wrmsrl(MSR_IA32_DS_AREA, 0);
+ /*
+ * We leave the (now dangling) pointer to the DS configuration in
+ * the DS_AREA msr. This is as good or as bad as replacing it with
+ * NULL - the hardware would crash if we enabled tracing.
+ *
+ * This saves us some problems with having to write an msr on a
+ * different cpu while preventing others from doing the same for the
+ * next context for that same cpu.
+ */
spin_unlock_irqrestore(&ds_lock, irq);
+ /* The context might still be in use for context switching. */
+ if (task && (task != current))
+ wait_task_context_switch(task);
+
kfree(context);
}
+static void ds_install_ds_area(struct ds_context *context)
+{
+ unsigned long ds;
+
+ ds = (unsigned long)context->ds;
+
+ /*
+ * There is a race between the bts master and the pebs master.
+ *
+ * The thread/cpu access is synchronized via get/put_cpu() for
+ * task tracing and via wrmsr_on_cpu for cpu tracing.
+ *
+ * If bts and pebs are collected for the same task or same cpu,
+ * the same confiuration is written twice.
+ */
+ if (context->task) {
+ get_cpu();
+ if (context->task == current)
+ wrmsrl(MSR_IA32_DS_AREA, ds);
+ set_tsk_thread_flag(context->task, TIF_DS_AREA_MSR);
+ put_cpu();
+ } else
+ wrmsr_on_cpu(context->cpu, MSR_IA32_DS_AREA,
+ (u32)((u64)ds), (u32)((u64)ds >> 32));
+}
/*
* Call the tracer's callback on a buffer overflow.
@@ -332,9 +400,9 @@ static void ds_overflow(struct ds_context *context, enum ds_qualifier qual)
* The remainder of any partially written record is zeroed out.
*
* context: the DS context
- * qual: the buffer type
- * record: the data to write
- * size: the size of the data
+ * qual: the buffer type
+ * record: the data to write
+ * size: the size of the data
*/
static int ds_write(struct ds_context *context, enum ds_qualifier qual,
const void *record, size_t size)
@@ -349,14 +417,14 @@ static int ds_write(struct ds_context *context, enum ds_qualifier qual,
unsigned long write_size, adj_write_size;
/*
- * write as much as possible without producing an
+ * Write as much as possible without producing an
* overflow interrupt.
*
- * interrupt_threshold must either be
+ * Interrupt_threshold must either be
* - bigger than absolute_maximum or
* - point to a record between buffer_base and absolute_maximum
*
- * index points to a valid record.
+ * Index points to a valid record.
*/
base = ds_get(context->ds, qual, ds_buffer_base);
index = ds_get(context->ds, qual, ds_index);
@@ -365,8 +433,10 @@ static int ds_write(struct ds_context *context, enum ds_qualifier qual,
write_end = min(end, int_th);
- /* if we are already beyond the interrupt threshold,
- * we fill the entire buffer */
+ /*
+ * If we are already beyond the interrupt threshold,
+ * we fill the entire buffer.
+ */
if (write_end <= index)
write_end = end;
@@ -383,7 +453,7 @@ static int ds_write(struct ds_context *context, enum ds_qualifier qual,
adj_write_size = write_size / ds_cfg.sizeof_rec[qual];
adj_write_size *= ds_cfg.sizeof_rec[qual];
- /* zero out trailing bytes */
+ /* Zero out trailing bytes. */
memset((char *)index + write_size, 0,
adj_write_size - write_size);
index += adj_write_size;
@@ -410,7 +480,7 @@ static int ds_write(struct ds_context *context, enum ds_qualifier qual,
* Later architectures use 64bit pointers throughout, whereas earlier
* architectures use 32bit pointers in 32bit mode.
*
- * We compute the base address for the first 8 fields based on:
+ * We compute the base address for the fields based on:
* - the field size stored in the DS configuration
* - the relative field position
*
@@ -431,23 +501,23 @@ enum bts_field {
bts_to,
bts_flags,
- bts_qual = bts_from,
- bts_jiffies = bts_to,
- bts_pid = bts_flags,
+ bts_qual = bts_from,
+ bts_clock = bts_to,
+ bts_pid = bts_flags,
- bts_qual_mask = (bts_qual_max - 1),
- bts_escape = ((unsigned long)-1 & ~bts_qual_mask)
+ bts_qual_mask = (bts_qual_max - 1),
+ bts_escape = ((unsigned long)-1 & ~bts_qual_mask)
};
static inline unsigned long bts_get(const char *base, enum bts_field field)
{
- base += (ds_cfg.sizeof_field * field);
+ base += (ds_cfg.sizeof_ptr_field * field);
return *(unsigned long *)base;
}
static inline void bts_set(char *base, enum bts_field field, unsigned long val)
{
- base += (ds_cfg.sizeof_field * field);;
+ base += (ds_cfg.sizeof_ptr_field * field);;
(*(unsigned long *)base) = val;
}
@@ -463,8 +533,8 @@ static inline void bts_set(char *base, enum bts_field field, unsigned long val)
*
* return: bytes read/written on success; -Eerrno, otherwise
*/
-static int bts_read(struct bts_tracer *tracer, const void *at,
- struct bts_struct *out)
+static int
+bts_read(struct bts_tracer *tracer, const void *at, struct bts_struct *out)
{
if (!tracer)
return -EINVAL;
@@ -478,8 +548,8 @@ static int bts_read(struct bts_tracer *tracer, const void *at,
memset(out, 0, sizeof(*out));
if ((bts_get(at, bts_qual) & ~bts_qual_mask) == bts_escape) {
out->qualifier = (bts_get(at, bts_qual) & bts_qual_mask);
- out->variant.timestamp.jiffies = bts_get(at, bts_jiffies);
- out->variant.timestamp.pid = bts_get(at, bts_pid);
+ out->variant.event.clock = bts_get(at, bts_clock);
+ out->variant.event.pid = bts_get(at, bts_pid);
} else {
out->qualifier = bts_branch;
out->variant.lbr.from = bts_get(at, bts_from);
@@ -516,8 +586,8 @@ static int bts_write(struct bts_tracer *tracer, const struct bts_struct *in)
case bts_task_arrives:
case bts_task_departs:
bts_set(raw, bts_qual, (bts_escape | in->qualifier));
- bts_set(raw, bts_jiffies, in->variant.timestamp.jiffies);
- bts_set(raw, bts_pid, in->variant.timestamp.pid);
+ bts_set(raw, bts_clock, in->variant.event.clock);
+ bts_set(raw, bts_pid, in->variant.event.pid);
break;
default:
return -EINVAL;
@@ -555,7 +625,8 @@ static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual,
unsigned int flags) {
unsigned long buffer, adj;
- /* adjust the buffer address and size to meet alignment
+ /*
+ * Adjust the buffer address and size to meet alignment
* constraints:
* - buffer is double-word aligned
* - size is multiple of record size
@@ -577,9 +648,11 @@ static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual,
trace->begin = (void *)buffer;
trace->top = trace->begin;
trace->end = (void *)(buffer + size);
- /* The value for 'no threshold' is -1, which will set the
+ /*
+ * The value for 'no threshold' is -1, which will set the
* threshold outside of the buffer, just like we want it.
*/
+ ith *= ds_cfg.sizeof_rec[qual];
trace->ith = (void *)(buffer + size - ith);
trace->flags = flags;
@@ -588,18 +661,27 @@ static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual,
static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace,
enum ds_qualifier qual, struct task_struct *task,
- void *base, size_t size, size_t th, unsigned int flags)
+ int cpu, void *base, size_t size, size_t th)
{
struct ds_context *context;
int error;
+ size_t req_size;
+
+ error = -EOPNOTSUPP;
+ if (!ds_cfg.sizeof_rec[qual])
+ goto out;
error = -EINVAL;
if (!base)
goto out;
- /* we require some space to do alignment adjustments below */
+ req_size = ds_cfg.sizeof_rec[qual];
+ /* We might need space for alignment adjustments. */
+ if (!IS_ALIGNED((unsigned long)base, DS_ALIGNMENT))
+ req_size += DS_ALIGNMENT;
+
error = -EINVAL;
- if (size < (DS_ALIGNMENT + ds_cfg.sizeof_rec[qual]))
+ if (size < req_size)
goto out;
if (th != (size_t)-1) {
@@ -614,182 +696,318 @@ static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace,
tracer->size = size;
error = -ENOMEM;
- context = ds_get_context(task);
+ context = ds_get_context(task, cpu);
if (!context)
goto out;
tracer->context = context;
- ds_init_ds_trace(trace, qual, base, size, th, flags);
+ /*
+ * Defer any tracer-specific initialization work for the context until
+ * context ownership has been clarified.
+ */
error = 0;
out:
return error;
}
-struct bts_tracer *ds_request_bts(struct task_struct *task,
- void *base, size_t size,
- bts_ovfl_callback_t ovfl, size_t th,
- unsigned int flags)
+static struct bts_tracer *ds_request_bts(struct task_struct *task, int cpu,
+ void *base, size_t size,
+ bts_ovfl_callback_t ovfl, size_t th,
+ unsigned int flags)
{
struct bts_tracer *tracer;
- unsigned long irq;
int error;
+ /* Buffer overflow notification is not yet implemented. */
error = -EOPNOTSUPP;
- if (!ds_cfg.ctl[dsf_bts])
+ if (ovfl)
goto out;
- /* buffer overflow notification is not yet implemented */
- error = -EOPNOTSUPP;
- if (ovfl)
+ error = get_tracer(task);
+ if (error < 0)
goto out;
error = -ENOMEM;
tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
if (!tracer)
- goto out;
+ goto out_put_tracer;
tracer->ovfl = ovfl;
+ /* Do some more error checking and acquire a tracing context. */
error = ds_request(&tracer->ds, &tracer->trace.ds,
- ds_bts, task, base, size, th, flags);
+ ds_bts, task, cpu, base, size, th);
if (error < 0)
goto out_tracer;
-
- spin_lock_irqsave(&ds_lock, irq);
-
- error = -EPERM;
- if (!check_tracer(task))
- goto out_unlock;
- get_tracer(task);
+ /* Claim the bts part of the tracing context we acquired above. */
+ spin_lock_irq(&ds_lock);
error = -EPERM;
if (tracer->ds.context->bts_master)
- goto out_put_tracer;
+ goto out_unlock;
tracer->ds.context->bts_master = tracer;
- spin_unlock_irqrestore(&ds_lock, irq);
+ spin_unlock_irq(&ds_lock);
+ /*
+ * Now that we own the bts part of the context, let's complete the
+ * initialization for that part.
+ */
+ ds_init_ds_trace(&tracer->trace.ds, ds_bts, base, size, th, flags);
+ ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
+ ds_install_ds_area(tracer->ds.context);
tracer->trace.read = bts_read;
tracer->trace.write = bts_write;
- ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
+ /* Start tracing. */
ds_resume_bts(tracer);
return tracer;
- out_put_tracer:
- put_tracer(task);
out_unlock:
- spin_unlock_irqrestore(&ds_lock, irq);
+ spin_unlock_irq(&ds_lock);
ds_put_context(tracer->ds.context);
out_tracer:
kfree(tracer);
+ out_put_tracer:
+ put_tracer(task);
out:
return ERR_PTR(error);
}
-struct pebs_tracer *ds_request_pebs(struct task_struct *task,
- void *base, size_t size,
- pebs_ovfl_callback_t ovfl, size_t th,
- unsigned int flags)
+struct bts_tracer *ds_request_bts_task(struct task_struct *task,
+ void *base, size_t size,
+ bts_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags)
+{
+ return ds_request_bts(task, 0, base, size, ovfl, th, flags);
+}
+
+struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size,
+ bts_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags)
+{
+ return ds_request_bts(NULL, cpu, base, size, ovfl, th, flags);
+}
+
+static struct pebs_tracer *ds_request_pebs(struct task_struct *task, int cpu,
+ void *base, size_t size,
+ pebs_ovfl_callback_t ovfl, size_t th,
+ unsigned int flags)
{
struct pebs_tracer *tracer;
- unsigned long irq;
int error;
- /* buffer overflow notification is not yet implemented */
+ /* Buffer overflow notification is not yet implemented. */
error = -EOPNOTSUPP;
if (ovfl)
goto out;
+ error = get_tracer(task);
+ if (error < 0)
+ goto out;
+
error = -ENOMEM;
tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
if (!tracer)
- goto out;
+ goto out_put_tracer;
tracer->ovfl = ovfl;
+ /* Do some more error checking and acquire a tracing context. */
error = ds_request(&tracer->ds, &tracer->trace.ds,
- ds_pebs, task, base, size, th, flags);
+ ds_pebs, task, cpu, base, size, th);
if (error < 0)
goto out_tracer;
- spin_lock_irqsave(&ds_lock, irq);
-
- error = -EPERM;
- if (!check_tracer(task))
- goto out_unlock;
- get_tracer(task);
+ /* Claim the pebs part of the tracing context we acquired above. */
+ spin_lock_irq(&ds_lock);
error = -EPERM;
if (tracer->ds.context->pebs_master)
- goto out_put_tracer;
+ goto out_unlock;
tracer->ds.context->pebs_master = tracer;
- spin_unlock_irqrestore(&ds_lock, irq);
+ spin_unlock_irq(&ds_lock);
+ /*
+ * Now that we own the pebs part of the context, let's complete the
+ * initialization for that part.
+ */
+ ds_init_ds_trace(&tracer->trace.ds, ds_pebs, base, size, th, flags);
ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
+ ds_install_ds_area(tracer->ds.context);
+
+ /* Start tracing. */
ds_resume_pebs(tracer);
return tracer;
- out_put_tracer:
- put_tracer(task);
out_unlock:
- spin_unlock_irqrestore(&ds_lock, irq);
+ spin_unlock_irq(&ds_lock);
ds_put_context(tracer->ds.context);
out_tracer:
kfree(tracer);
+ out_put_tracer:
+ put_tracer(task);
out:
return ERR_PTR(error);
}
-void ds_release_bts(struct bts_tracer *tracer)
+struct pebs_tracer *ds_request_pebs_task(struct task_struct *task,
+ void *base, size_t size,
+ pebs_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags)
{
- if (!tracer)
- return;
+ return ds_request_pebs(task, 0, base, size, ovfl, th, flags);
+}
- ds_suspend_bts(tracer);
+struct pebs_tracer *ds_request_pebs_cpu(int cpu, void *base, size_t size,
+ pebs_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags)
+{
+ return ds_request_pebs(NULL, cpu, base, size, ovfl, th, flags);
+}
+
+static void ds_free_bts(struct bts_tracer *tracer)
+{
+ struct task_struct *task;
+
+ task = tracer->ds.context->task;
WARN_ON_ONCE(tracer->ds.context->bts_master != tracer);
tracer->ds.context->bts_master = NULL;
- put_tracer(tracer->ds.context->task);
+ /* Make sure tracing stopped and the tracer is not in use. */
+ if (task && (task != current))
+ wait_task_context_switch(task);
+
ds_put_context(tracer->ds.context);
+ put_tracer(task);
kfree(tracer);
}
+void ds_release_bts(struct bts_tracer *tracer)
+{
+ might_sleep();
+
+ if (!tracer)
+ return;
+
+ ds_suspend_bts(tracer);
+ ds_free_bts(tracer);
+}
+
+int ds_release_bts_noirq(struct bts_tracer *tracer)
+{
+ struct task_struct *task;
+ unsigned long irq;
+ int error;
+
+ if (!tracer)
+ return 0;
+
+ task = tracer->ds.context->task;
+
+ local_irq_save(irq);
+
+ error = -EPERM;
+ if (!task &&
+ (tracer->ds.context->cpu != smp_processor_id()))
+ goto out;
+
+ error = -EPERM;
+ if (task && (task != current))
+ goto out;
+
+ ds_suspend_bts_noirq(tracer);
+ ds_free_bts(tracer);
+
+ error = 0;
+ out:
+ local_irq_restore(irq);
+ return error;
+}
+
+static void update_task_debugctlmsr(struct task_struct *task,
+ unsigned long debugctlmsr)
+{
+ task->thread.debugctlmsr = debugctlmsr;
+
+ get_cpu();
+ if (task == current)
+ update_debugctlmsr(debugctlmsr);
+ put_cpu();
+}
+
void ds_suspend_bts(struct bts_tracer *tracer)
{
struct task_struct *task;
+ unsigned long debugctlmsr;
+ int cpu;
if (!tracer)
return;
+ tracer->flags = 0;
+
task = tracer->ds.context->task;
+ cpu = tracer->ds.context->cpu;
- if (!task || (task == current))
- update_debugctlmsr(get_debugctlmsr() & ~BTS_CONTROL);
+ WARN_ON(!task && irqs_disabled());
- if (task) {
- task->thread.debugctlmsr &= ~BTS_CONTROL;
+ debugctlmsr = (task ?
+ task->thread.debugctlmsr :
+ get_debugctlmsr_on_cpu(cpu));
+ debugctlmsr &= ~BTS_CONTROL;
- if (!task->thread.debugctlmsr)
- clear_tsk_thread_flag(task, TIF_DEBUGCTLMSR);
- }
+ if (task)
+ update_task_debugctlmsr(task, debugctlmsr);
+ else
+ update_debugctlmsr_on_cpu(cpu, debugctlmsr);
}
-void ds_resume_bts(struct bts_tracer *tracer)
+int ds_suspend_bts_noirq(struct bts_tracer *tracer)
{
struct task_struct *task;
- unsigned long control;
+ unsigned long debugctlmsr, irq;
+ int cpu, error = 0;
if (!tracer)
- return;
+ return 0;
+
+ tracer->flags = 0;
task = tracer->ds.context->task;
+ cpu = tracer->ds.context->cpu;
+
+ local_irq_save(irq);
+
+ error = -EPERM;
+ if (!task && (cpu != smp_processor_id()))
+ goto out;
+
+ debugctlmsr = (task ?
+ task->thread.debugctlmsr :
+ get_debugctlmsr());
+ debugctlmsr &= ~BTS_CONTROL;
+
+ if (task)
+ update_task_debugctlmsr(task, debugctlmsr);
+ else
+ update_debugctlmsr(debugctlmsr);
+
+ error = 0;
+ out:
+ local_irq_restore(irq);
+ return error;
+}
+
+static unsigned long ds_bts_control(struct bts_tracer *tracer)
+{
+ unsigned long control;
control = ds_cfg.ctl[dsf_bts];
if (!(tracer->trace.ds.flags & BTS_KERNEL))
@@ -797,41 +1015,149 @@ void ds_resume_bts(struct bts_tracer *tracer)
if (!(tracer->trace.ds.flags & BTS_USER))
control |= ds_cfg.ctl[dsf_bts_user];
- if (task) {
- task->thread.debugctlmsr |= control;
- set_tsk_thread_flag(task, TIF_DEBUGCTLMSR);
- }
-
- if (!task || (task == current))
- update_debugctlmsr(get_debugctlmsr() | control);
+ return control;
}
-void ds_release_pebs(struct pebs_tracer *tracer)
+void ds_resume_bts(struct bts_tracer *tracer)
{
+ struct task_struct *task;
+ unsigned long debugctlmsr;
+ int cpu;
+
if (!tracer)
return;
- ds_suspend_pebs(tracer);
+ tracer->flags = tracer->trace.ds.flags;
+
+ task = tracer->ds.context->task;
+ cpu = tracer->ds.context->cpu;
+
+ WARN_ON(!task && irqs_disabled());
+
+ debugctlmsr = (task ?
+ task->thread.debugctlmsr :
+ get_debugctlmsr_on_cpu(cpu));
+ debugctlmsr |= ds_bts_control(tracer);
+
+ if (task)
+ update_task_debugctlmsr(task, debugctlmsr);
+ else
+ update_debugctlmsr_on_cpu(cpu, debugctlmsr);
+}
+
+int ds_resume_bts_noirq(struct bts_tracer *tracer)
+{
+ struct task_struct *task;
+ unsigned long debugctlmsr, irq;
+ int cpu, error = 0;
+
+ if (!tracer)
+ return 0;
+
+ tracer->flags = tracer->trace.ds.flags;
+
+ task = tracer->ds.context->task;
+ cpu = tracer->ds.context->cpu;
+
+ local_irq_save(irq);
+
+ error = -EPERM;
+ if (!task && (cpu != smp_processor_id()))
+ goto out;
+
+ debugctlmsr = (task ?
+ task->thread.debugctlmsr :
+ get_debugctlmsr());
+ debugctlmsr |= ds_bts_control(tracer);
+
+ if (task)
+ update_task_debugctlmsr(task, debugctlmsr);
+ else
+ update_debugctlmsr(debugctlmsr);
+
+ error = 0;
+ out:
+ local_irq_restore(irq);
+ return error;
+}
+
+static void ds_free_pebs(struct pebs_tracer *tracer)
+{
+ struct task_struct *task;
+
+ task = tracer->ds.context->task;
WARN_ON_ONCE(tracer->ds.context->pebs_master != tracer);
tracer->ds.context->pebs_master = NULL;
- put_tracer(tracer->ds.context->task);
ds_put_context(tracer->ds.context);
+ put_tracer(task);
kfree(tracer);
}
+void ds_release_pebs(struct pebs_tracer *tracer)
+{
+ might_sleep();
+
+ if (!tracer)
+ return;
+
+ ds_suspend_pebs(tracer);
+ ds_free_pebs(tracer);
+}
+
+int ds_release_pebs_noirq(struct pebs_tracer *tracer)
+{
+ struct task_struct *task;
+ unsigned long irq;
+ int error;
+
+ if (!tracer)
+ return 0;
+
+ task = tracer->ds.context->task;
+
+ local_irq_save(irq);
+
+ error = -EPERM;
+ if (!task &&
+ (tracer->ds.context->cpu != smp_processor_id()))
+ goto out;
+
+ error = -EPERM;
+ if (task && (task != current))
+ goto out;
+
+ ds_suspend_pebs_noirq(tracer);
+ ds_free_pebs(tracer);
+
+ error = 0;
+ out:
+ local_irq_restore(irq);
+ return error;
+}
+
void ds_suspend_pebs(struct pebs_tracer *tracer)
{
}
+int ds_suspend_pebs_noirq(struct pebs_tracer *tracer)
+{
+ return 0;
+}
+
void ds_resume_pebs(struct pebs_tracer *tracer)
{
}
+int ds_resume_pebs_noirq(struct pebs_tracer *tracer)
+{
+ return 0;
+}
+
const struct bts_trace *ds_read_bts(struct bts_tracer *tracer)
{
if (!tracer)
@@ -847,8 +1173,12 @@ const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer)
return NULL;
ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
- tracer->trace.reset_value =
- *(u64 *)(tracer->ds.context->ds + (ds_cfg.sizeof_field * 8));
+
+ tracer->trace.counters = ds_cfg.nr_counter_reset;
+ memcpy(tracer->trace.counter_reset,
+ tracer->ds.context->ds +
+ (NUM_DS_PTR_FIELDS * ds_cfg.sizeof_ptr_field),
+ ds_cfg.nr_counter_reset * PEBS_RESET_FIELD_SIZE);
return &tracer->trace;
}
@@ -873,18 +1203,24 @@ int ds_reset_pebs(struct pebs_tracer *tracer)
tracer->trace.ds.top = tracer->trace.ds.begin;
- ds_set(tracer->ds.context->ds, ds_bts, ds_index,
+ ds_set(tracer->ds.context->ds, ds_pebs, ds_index,
(unsigned long)tracer->trace.ds.top);
return 0;
}
-int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value)
+int ds_set_pebs_reset(struct pebs_tracer *tracer,
+ unsigned int counter, u64 value)
{
if (!tracer)
return -EINVAL;
- *(u64 *)(tracer->ds.context->ds + (ds_cfg.sizeof_field * 8)) = value;
+ if (ds_cfg.nr_counter_reset < counter)
+ return -EINVAL;
+
+ *(u64 *)(tracer->ds.context->ds +
+ (NUM_DS_PTR_FIELDS * ds_cfg.sizeof_ptr_field) +
+ (counter * PEBS_RESET_FIELD_SIZE)) = value;
return 0;
}
@@ -894,73 +1230,117 @@ static const struct ds_configuration ds_cfg_netburst = {
.ctl[dsf_bts] = (1 << 2) | (1 << 3),
.ctl[dsf_bts_kernel] = (1 << 5),
.ctl[dsf_bts_user] = (1 << 6),
-
- .sizeof_field = sizeof(long),
- .sizeof_rec[ds_bts] = sizeof(long) * 3,
-#ifdef __i386__
- .sizeof_rec[ds_pebs] = sizeof(long) * 10,
-#else
- .sizeof_rec[ds_pebs] = sizeof(long) * 18,
-#endif
+ .nr_counter_reset = 1,
};
static const struct ds_configuration ds_cfg_pentium_m = {
.name = "Pentium M",
.ctl[dsf_bts] = (1 << 6) | (1 << 7),
-
- .sizeof_field = sizeof(long),
- .sizeof_rec[ds_bts] = sizeof(long) * 3,
-#ifdef __i386__
- .sizeof_rec[ds_pebs] = sizeof(long) * 10,
-#else
- .sizeof_rec[ds_pebs] = sizeof(long) * 18,
-#endif
+ .nr_counter_reset = 1,
};
static const struct ds_configuration ds_cfg_core2_atom = {
.name = "Core 2/Atom",
.ctl[dsf_bts] = (1 << 6) | (1 << 7),
.ctl[dsf_bts_kernel] = (1 << 9),
.ctl[dsf_bts_user] = (1 << 10),
-
- .sizeof_field = 8,
- .sizeof_rec[ds_bts] = 8 * 3,
- .sizeof_rec[ds_pebs] = 8 * 18,
+ .nr_counter_reset = 1,
+};
+static const struct ds_configuration ds_cfg_core_i7 = {
+ .name = "Core i7",
+ .ctl[dsf_bts] = (1 << 6) | (1 << 7),
+ .ctl[dsf_bts_kernel] = (1 << 9),
+ .ctl[dsf_bts_user] = (1 << 10),
+ .nr_counter_reset = 4,
};
static void
-ds_configure(const struct ds_configuration *cfg)
+ds_configure(const struct ds_configuration *cfg,
+ struct cpuinfo_x86 *cpu)
{
+ unsigned long nr_pebs_fields = 0;
+
+ printk(KERN_INFO "[ds] using %s configuration\n", cfg->name);
+
+#ifdef __i386__
+ nr_pebs_fields = 10;
+#else
+ nr_pebs_fields = 18;
+#endif
+
+ /*
+ * Starting with version 2, architectural performance
+ * monitoring supports a format specifier.
+ */
+ if ((cpuid_eax(0xa) & 0xff) > 1) {
+ unsigned long perf_capabilities, format;
+
+ rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_capabilities);
+
+ format = (perf_capabilities >> 8) & 0xf;
+
+ switch (format) {
+ case 0:
+ nr_pebs_fields = 18;
+ break;
+ case 1:
+ nr_pebs_fields = 22;
+ break;
+ default:
+ printk(KERN_INFO
+ "[ds] unknown PEBS format: %lu\n", format);
+ nr_pebs_fields = 0;
+ break;
+ }
+ }
+
memset(&ds_cfg, 0, sizeof(ds_cfg));
ds_cfg = *cfg;
- printk(KERN_INFO "[ds] using %s configuration\n", ds_cfg.name);
+ ds_cfg.sizeof_ptr_field =
+ (cpu_has(cpu, X86_FEATURE_DTES64) ? 8 : 4);
+
+ ds_cfg.sizeof_rec[ds_bts] = ds_cfg.sizeof_ptr_field * 3;
+ ds_cfg.sizeof_rec[ds_pebs] = ds_cfg.sizeof_ptr_field * nr_pebs_fields;
- if (!cpu_has_bts) {
- ds_cfg.ctl[dsf_bts] = 0;
+ if (!cpu_has(cpu, X86_FEATURE_BTS)) {
+ ds_cfg.sizeof_rec[ds_bts] = 0;
printk(KERN_INFO "[ds] bts not available\n");
}
- if (!cpu_has_pebs)
+ if (!cpu_has(cpu, X86_FEATURE_PEBS)) {
+ ds_cfg.sizeof_rec[ds_pebs] = 0;
printk(KERN_INFO "[ds] pebs not available\n");
+ }
+
+ printk(KERN_INFO "[ds] sizes: address: %u bit, ",
+ 8 * ds_cfg.sizeof_ptr_field);
+ printk("bts/pebs record: %u/%u bytes\n",
+ ds_cfg.sizeof_rec[ds_bts], ds_cfg.sizeof_rec[ds_pebs]);
- WARN_ON_ONCE(MAX_SIZEOF_DS < (12 * ds_cfg.sizeof_field));
+ WARN_ON_ONCE(MAX_PEBS_COUNTERS < ds_cfg.nr_counter_reset);
}
void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
{
+ /* Only configure the first cpu. Others are identical. */
+ if (ds_cfg.name)
+ return;
+
switch (c->x86) {
case 0x6:
switch (c->x86_model) {
case 0x9:
case 0xd: /* Pentium M */
- ds_configure(&ds_cfg_pentium_m);
+ ds_configure(&ds_cfg_pentium_m, c);
break;
case 0xf:
case 0x17: /* Core2 */
case 0x1c: /* Atom */
- ds_configure(&ds_cfg_core2_atom);
+ ds_configure(&ds_cfg_core2_atom, c);
+ break;
+ case 0x1a: /* Core i7 */
+ ds_configure(&ds_cfg_core_i7, c);
break;
- case 0x1a: /* i7 */
default:
- /* sorry, don't know about them */
+ /* Sorry, don't know about them. */
break;
}
break;
@@ -969,64 +1349,89 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
case 0x0:
case 0x1:
case 0x2: /* Netburst */
- ds_configure(&ds_cfg_netburst);
+ ds_configure(&ds_cfg_netburst, c);
break;
default:
- /* sorry, don't know about them */
+ /* Sorry, don't know about them. */
break;
}
break;
default:
- /* sorry, don't know about them */
+ /* Sorry, don't know about them. */
break;
}
}
+static inline void ds_take_timestamp(struct ds_context *context,
+ enum bts_qualifier qualifier,
+ struct task_struct *task)
+{
+ struct bts_tracer *tracer = context->bts_master;
+ struct bts_struct ts;
+
+ /* Prevent compilers from reading the tracer pointer twice. */
+ barrier();
+
+ if (!tracer || !(tracer->flags & BTS_TIMESTAMPS))
+ return;
+
+ memset(&ts, 0, sizeof(ts));
+ ts.qualifier = qualifier;
+ ts.variant.event.clock = trace_clock_global();
+ ts.variant.event.pid = task->pid;
+
+ bts_write(tracer, &ts);
+}
+
/*
* Change the DS configuration from tracing prev to tracing next.
*/
void ds_switch_to(struct task_struct *prev, struct task_struct *next)
{
- struct ds_context *prev_ctx = prev->thread.ds_ctx;
- struct ds_context *next_ctx = next->thread.ds_ctx;
+ struct ds_context *prev_ctx = prev->thread.ds_ctx;
+ struct ds_context *next_ctx = next->thread.ds_ctx;
+ unsigned long debugctlmsr = next->thread.debugctlmsr;
+
+ /* Make sure all data is read before we start. */
+ barrier();
if (prev_ctx) {
update_debugctlmsr(0);
- if (prev_ctx->bts_master &&
- (prev_ctx->bts_master->trace.ds.flags & BTS_TIMESTAMPS)) {
- struct bts_struct ts = {
- .qualifier = bts_task_departs,
- .variant.timestamp.jiffies = jiffies_64,
- .variant.timestamp.pid = prev->pid
- };
- bts_write(prev_ctx->bts_master, &ts);
- }
+ ds_take_timestamp(prev_ctx, bts_task_departs, prev);
}
if (next_ctx) {
- if (next_ctx->bts_master &&
- (next_ctx->bts_master->trace.ds.flags & BTS_TIMESTAMPS)) {
- struct bts_struct ts = {
- .qualifier = bts_task_arrives,
- .variant.timestamp.jiffies = jiffies_64,
- .variant.timestamp.pid = next->pid
- };
- bts_write(next_ctx->bts_master, &ts);
- }
+ ds_take_timestamp(next_ctx, bts_task_arrives, next);
wrmsrl(MSR_IA32_DS_AREA, (unsigned long)next_ctx->ds);
}
- update_debugctlmsr(next->thread.debugctlmsr);
+ update_debugctlmsr(debugctlmsr);
}
-void ds_copy_thread(struct task_struct *tsk, struct task_struct *father)
+static __init int ds_selftest(void)
{
- clear_tsk_thread_flag(tsk, TIF_DS_AREA_MSR);
- tsk->thread.ds_ctx = NULL;
-}
+ if (ds_cfg.sizeof_rec[ds_bts]) {
+ int error;
-void ds_exit_thread(struct task_struct *tsk)
-{
+ error = ds_selftest_bts();
+ if (error) {
+ WARN(1, "[ds] selftest failed. disabling bts.\n");
+ ds_cfg.sizeof_rec[ds_bts] = 0;
+ }
+ }
+
+ if (ds_cfg.sizeof_rec[ds_pebs]) {
+ int error;
+
+ error = ds_selftest_pebs();
+ if (error) {
+ WARN(1, "[ds] selftest failed. disabling pebs.\n");
+ ds_cfg.sizeof_rec[ds_pebs] = 0;
+ }
+ }
+
+ return 0;
}
+device_initcall(ds_selftest);
diff --git a/arch/x86/kernel/ds_selftest.c b/arch/x86/kernel/ds_selftest.c
new file mode 100644
index 000000000000..6bc7c199ab99
--- /dev/null
+++ b/arch/x86/kernel/ds_selftest.c
@@ -0,0 +1,408 @@
+/*
+ * Debug Store support - selftest
+ *
+ *
+ * Copyright (C) 2009 Intel Corporation.
+ * Markus Metzger <markus.t.metzger@intel.com>, 2009
+ */
+
+#include "ds_selftest.h"
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/smp.h>
+#include <linux/cpu.h>
+
+#include <asm/ds.h>
+
+
+#define BUFFER_SIZE 521 /* Intentionally chose an odd size. */
+#define SMALL_BUFFER_SIZE 24 /* A single bts entry. */
+
+struct ds_selftest_bts_conf {
+ struct bts_tracer *tracer;
+ int error;
+ int (*suspend)(struct bts_tracer *);
+ int (*resume)(struct bts_tracer *);
+};
+
+static int ds_selftest_bts_consistency(const struct bts_trace *trace)
+{
+ int error = 0;
+
+ if (!trace) {
+ printk(KERN_CONT "failed to access trace...");
+ /* Bail out. Other tests are pointless. */
+ return -1;
+ }
+
+ if (!trace->read) {
+ printk(KERN_CONT "bts read not available...");
+ error = -1;
+ }
+
+ /* Do some sanity checks on the trace configuration. */
+ if (!trace->ds.n) {
+ printk(KERN_CONT "empty bts buffer...");
+ error = -1;
+ }
+ if (!trace->ds.size) {
+ printk(KERN_CONT "bad bts trace setup...");
+ error = -1;
+ }
+ if (trace->ds.end !=
+ (char *)trace->ds.begin + (trace->ds.n * trace->ds.size)) {
+ printk(KERN_CONT "bad bts buffer setup...");
+ error = -1;
+ }
+ /*
+ * We allow top in [begin; end], since its not clear when the
+ * overflow adjustment happens: after the increment or before the
+ * write.
+ */
+ if ((trace->ds.top < trace->ds.begin) ||
+ (trace->ds.end < trace->ds.top)) {
+ printk(KERN_CONT "bts top out of bounds...");
+ error = -1;
+ }
+
+ return error;
+}
+
+static int ds_selftest_bts_read(struct bts_tracer *tracer,
+ const struct bts_trace *trace,
+ const void *from, const void *to)
+{
+ const unsigned char *at;
+
+ /*
+ * Check a few things which do not belong to this test.
+ * They should be covered by other tests.
+ */
+ if (!trace)
+ return -1;
+
+ if (!trace->read)
+ return -1;
+
+ if (to < from)
+ return -1;
+
+ if (from < trace->ds.begin)
+ return -1;
+
+ if (trace->ds.end < to)
+ return -1;
+
+ if (!trace->ds.size)
+ return -1;
+
+ /* Now to the test itself. */
+ for (at = from; (void *)at < to; at += trace->ds.size) {
+ struct bts_struct bts;
+ unsigned long index;
+ int error;
+
+ if (((void *)at - trace->ds.begin) % trace->ds.size) {
+ printk(KERN_CONT
+ "read from non-integer index...");
+ return -1;
+ }
+ index = ((void *)at - trace->ds.begin) / trace->ds.size;
+
+ memset(&bts, 0, sizeof(bts));
+ error = trace->read(tracer, at, &bts);
+ if (error < 0) {
+ printk(KERN_CONT
+ "error reading bts trace at [%lu] (0x%p)...",
+ index, at);
+ return error;
+ }
+
+ switch (bts.qualifier) {
+ case BTS_BRANCH:
+ break;
+ default:
+ printk(KERN_CONT
+ "unexpected bts entry %llu at [%lu] (0x%p)...",
+ bts.qualifier, index, at);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void ds_selftest_bts_cpu(void *arg)
+{
+ struct ds_selftest_bts_conf *conf = arg;
+ const struct bts_trace *trace;
+ void *top;
+
+ if (IS_ERR(conf->tracer)) {
+ conf->error = PTR_ERR(conf->tracer);
+ conf->tracer = NULL;
+
+ printk(KERN_CONT
+ "initialization failed (err: %d)...", conf->error);
+ return;
+ }
+
+ /* We should meanwhile have enough trace. */
+ conf->error = conf->suspend(conf->tracer);
+ if (conf->error < 0)
+ return;
+
+ /* Let's see if we can access the trace. */
+ trace = ds_read_bts(conf->tracer);
+
+ conf->error = ds_selftest_bts_consistency(trace);
+ if (conf->error < 0)
+ return;
+
+ /* If everything went well, we should have a few trace entries. */
+ if (trace->ds.top == trace->ds.begin) {
+ /*
+ * It is possible but highly unlikely that we got a
+ * buffer overflow and end up at exactly the same
+ * position we started from.
+ * Let's issue a warning, but continue.
+ */
+ printk(KERN_CONT "no trace/overflow...");
+ }
+
+ /* Let's try to read the trace we collected. */
+ conf->error =
+ ds_selftest_bts_read(conf->tracer, trace,
+ trace->ds.begin, trace->ds.top);
+ if (conf->error < 0)
+ return;
+
+ /*
+ * Let's read the trace again.
+ * Since we suspended tracing, we should get the same result.
+ */
+ top = trace->ds.top;
+
+ trace = ds_read_bts(conf->tracer);
+ conf->error = ds_selftest_bts_consistency(trace);
+ if (conf->error < 0)
+ return;
+
+ if (top != trace->ds.top) {
+ printk(KERN_CONT "suspend not working...");
+ conf->error = -1;
+ return;
+ }
+
+ /* Let's collect some more trace - see if resume is working. */
+ conf->error = conf->resume(conf->tracer);
+ if (conf->error < 0)
+ return;
+
+ conf->error = conf->suspend(conf->tracer);
+ if (conf->error < 0)
+ return;
+
+ trace = ds_read_bts(conf->tracer);
+
+ conf->error = ds_selftest_bts_consistency(trace);
+ if (conf->error < 0)
+ return;
+
+ if (trace->ds.top == top) {
+ /*
+ * It is possible but highly unlikely that we got a
+ * buffer overflow and end up at exactly the same
+ * position we started from.
+ * Let's issue a warning and check the full trace.
+ */
+ printk(KERN_CONT
+ "no resume progress/overflow...");
+
+ conf->error =
+ ds_selftest_bts_read(conf->tracer, trace,
+ trace->ds.begin, trace->ds.end);
+ } else if (trace->ds.top < top) {
+ /*
+ * We had a buffer overflow - the entire buffer should
+ * contain trace records.
+ */
+ conf->error =
+ ds_selftest_bts_read(conf->tracer, trace,
+ trace->ds.begin, trace->ds.end);
+ } else {
+ /*
+ * It is quite likely that the buffer did not overflow.
+ * Let's just check the delta trace.
+ */
+ conf->error =
+ ds_selftest_bts_read(conf->tracer, trace, top,
+ trace->ds.top);
+ }
+ if (conf->error < 0)
+ return;
+
+ conf->error = 0;
+}
+
+static int ds_suspend_bts_wrap(struct bts_tracer *tracer)
+{
+ ds_suspend_bts(tracer);
+ return 0;
+}
+
+static int ds_resume_bts_wrap(struct bts_tracer *tracer)
+{
+ ds_resume_bts(tracer);
+ return 0;
+}
+
+static void ds_release_bts_noirq_wrap(void *tracer)
+{
+ (void)ds_release_bts_noirq(tracer);
+}
+
+static int ds_selftest_bts_bad_release_noirq(int cpu,
+ struct bts_tracer *tracer)
+{
+ int error = -EPERM;
+
+ /* Try to release the tracer on the wrong cpu. */
+ get_cpu();
+ if (cpu != smp_processor_id()) {
+ error = ds_release_bts_noirq(tracer);
+ if (error != -EPERM)
+ printk(KERN_CONT "release on wrong cpu...");
+ }
+ put_cpu();
+
+ return error ? 0 : -1;
+}
+
+static int ds_selftest_bts_bad_request_cpu(int cpu, void *buffer)
+{
+ struct bts_tracer *tracer;
+ int error;
+
+ /* Try to request cpu tracing while task tracing is active. */
+ tracer = ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, NULL,
+ (size_t)-1, BTS_KERNEL);
+ error = PTR_ERR(tracer);
+ if (!IS_ERR(tracer)) {
+ ds_release_bts(tracer);
+ error = 0;
+ }
+
+ if (error != -EPERM)
+ printk(KERN_CONT "cpu/task tracing overlap...");
+
+ return error ? 0 : -1;
+}
+
+static int ds_selftest_bts_bad_request_task(void *buffer)
+{
+ struct bts_tracer *tracer;
+ int error;
+
+ /* Try to request cpu tracing while task tracing is active. */
+ tracer = ds_request_bts_task(current, buffer, BUFFER_SIZE, NULL,
+ (size_t)-1, BTS_KERNEL);
+ error = PTR_ERR(tracer);
+ if (!IS_ERR(tracer)) {
+ error = 0;
+ ds_release_bts(tracer);
+ }
+
+ if (error != -EPERM)
+ printk(KERN_CONT "task/cpu tracing overlap...");
+
+ return error ? 0 : -1;
+}
+
+int ds_selftest_bts(void)
+{
+ struct ds_selftest_bts_conf conf;
+ unsigned char buffer[BUFFER_SIZE], *small_buffer;
+ unsigned long irq;
+ int cpu;
+
+ printk(KERN_INFO "[ds] bts selftest...");
+ conf.error = 0;
+
+ small_buffer = (unsigned char *)ALIGN((unsigned long)buffer, 8) + 8;
+
+ get_online_cpus();
+ for_each_online_cpu(cpu) {
+ conf.suspend = ds_suspend_bts_wrap;
+ conf.resume = ds_resume_bts_wrap;
+ conf.tracer =
+ ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE,
+ NULL, (size_t)-1, BTS_KERNEL);
+ ds_selftest_bts_cpu(&conf);
+ if (conf.error >= 0)
+ conf.error = ds_selftest_bts_bad_request_task(buffer);
+ ds_release_bts(conf.tracer);
+ if (conf.error < 0)
+ goto out;
+
+ conf.suspend = ds_suspend_bts_noirq;
+ conf.resume = ds_resume_bts_noirq;
+ conf.tracer =
+ ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE,
+ NULL, (size_t)-1, BTS_KERNEL);
+ smp_call_function_single(cpu, ds_selftest_bts_cpu, &conf, 1);
+ if (conf.error >= 0) {
+ conf.error =
+ ds_selftest_bts_bad_release_noirq(cpu,
+ conf.tracer);
+ /* We must not release the tracer twice. */
+ if (conf.error < 0)
+ conf.tracer = NULL;
+ }
+ if (conf.error >= 0)
+ conf.error = ds_selftest_bts_bad_request_task(buffer);
+ smp_call_function_single(cpu, ds_release_bts_noirq_wrap,
+ conf.tracer, 1);
+ if (conf.error < 0)
+ goto out;
+ }
+
+ conf.suspend = ds_suspend_bts_wrap;
+ conf.resume = ds_resume_bts_wrap;
+ conf.tracer =
+ ds_request_bts_task(current, buffer, BUFFER_SIZE,
+ NULL, (size_t)-1, BTS_KERNEL);
+ ds_selftest_bts_cpu(&conf);
+ if (conf.error >= 0)
+ conf.error = ds_selftest_bts_bad_request_cpu(0, buffer);
+ ds_release_bts(conf.tracer);
+ if (conf.error < 0)
+ goto out;
+
+ conf.suspend = ds_suspend_bts_noirq;
+ conf.resume = ds_resume_bts_noirq;
+ conf.tracer =
+ ds_request_bts_task(current, small_buffer, SMALL_BUFFER_SIZE,
+ NULL, (size_t)-1, BTS_KERNEL);
+ local_irq_save(irq);
+ ds_selftest_bts_cpu(&conf);
+ if (conf.error >= 0)
+ conf.error = ds_selftest_bts_bad_request_cpu(0, buffer);
+ ds_release_bts_noirq(conf.tracer);
+ local_irq_restore(irq);
+ if (conf.error < 0)
+ goto out;
+
+ conf.error = 0;
+ out:
+ put_online_cpus();
+ printk(KERN_CONT "%s.\n", (conf.error ? "failed" : "passed"));
+
+ return conf.error;
+}
+
+int ds_selftest_pebs(void)
+{
+ return 0;
+}
diff --git a/arch/x86/kernel/ds_selftest.h b/arch/x86/kernel/ds_selftest.h
new file mode 100644
index 000000000000..2ba8745c6663
--- /dev/null
+++ b/arch/x86/kernel/ds_selftest.h
@@ -0,0 +1,15 @@
+/*
+ * Debug Store support - selftest
+ *
+ *
+ * Copyright (C) 2009 Intel Corporation.
+ * Markus Metzger <markus.t.metzger@intel.com>, 2009
+ */
+
+#ifdef CONFIG_X86_DS_SELFTEST
+extern int ds_selftest_bts(void);
+extern int ds_selftest_pebs(void);
+#else
+static inline int ds_selftest_bts(void) { return 0; }
+static inline int ds_selftest_pebs(void) { return 0; }
+#endif
diff --git a/arch/x86/kernel/dumpstack.h b/arch/x86/kernel/dumpstack.h
index da87590b8698..81086c227ab7 100644
--- a/arch/x86/kernel/dumpstack.h
+++ b/arch/x86/kernel/dumpstack.h
@@ -29,7 +29,6 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
unsigned long *sp, unsigned long bp, char *log_lvl);
extern unsigned int code_bytes;
-extern int kstack_depth_to_print;
/* The form of the top of the frame on the stack */
struct stack_frame {
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index ef2c3563357d..7271fa33d791 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -617,7 +617,7 @@ __init int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
*/
__init void e820_setup_gap(void)
{
- unsigned long gapstart, gapsize, round;
+ unsigned long gapstart, gapsize;
int found;
gapstart = 0x10000000;
@@ -635,14 +635,9 @@ __init void e820_setup_gap(void)
#endif
/*
- * See how much we want to round up: start off with
- * rounding to the next 1MB area.
+ * e820_reserve_resources_late protect stolen RAM already
*/
- round = 0x100000;
- while ((gapsize >> 4) > round)
- round += round;
- /* Fun with two's complement */
- pci_mem_start = (gapstart + round) & -round;
+ pci_mem_start = gapstart;
printk(KERN_INFO
"Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
@@ -1074,12 +1069,13 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
u64 addr;
u64 start;
- start = startt;
- while (size < sizet && (start + 1))
+ for (start = startt; ; start += size) {
start = find_e820_area_size(start, &size, align);
-
- if (size < sizet)
- return 0;
+ if (!(start + 1))
+ return 0;
+ if (size >= sizet)
+ break;
+ }
#ifdef CONFIG_X86_32
if (start >= MAXMEM)
@@ -1370,6 +1366,23 @@ void __init e820_reserve_resources(void)
}
}
+/* How much should we pad RAM ending depending on where it is? */
+static unsigned long ram_alignment(resource_size_t pos)
+{
+ unsigned long mb = pos >> 20;
+
+ /* To 64kB in the first megabyte */
+ if (!mb)
+ return 64*1024;
+
+ /* To 1MB in the first 16MB */
+ if (mb < 16)
+ return 1024*1024;
+
+ /* To 32MB for anything above that */
+ return 32*1024*1024;
+}
+
void __init e820_reserve_resources_late(void)
{
int i;
@@ -1381,6 +1394,24 @@ void __init e820_reserve_resources_late(void)
insert_resource_expand_to_fit(&iomem_resource, res);
res++;
}
+
+ /*
+ * Try to bump up RAM regions to reasonable boundaries to
+ * avoid stolen RAM:
+ */
+ for (i = 0; i < e820.nr_map; i++) {
+ struct e820entry *entry = &e820_saved.map[i];
+ resource_size_t start, end;
+
+ if (entry->type != E820_RAM)
+ continue;
+ start = entry->addr + entry->size;
+ end = round_up(start, ram_alignment(start));
+ if (start == end)
+ continue;
+ reserve_region_with_split(&iomem_resource, start,
+ end - 1, "RAM buffer");
+ }
}
char *__init default_machine_specific_memory_setup(void)
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 76b8cd953dee..ebdb85cf2686 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -97,6 +97,7 @@ static void __init nvidia_bugs(int num, int slot, int func)
}
#if defined(CONFIG_ACPI) && defined(CONFIG_X86_IO_APIC)
+#if defined(CONFIG_ACPI) && defined(CONFIG_X86_IO_APIC)
static u32 __init ati_ixp4x0_rev(int num, int slot, int func)
{
u32 d;
@@ -114,6 +115,7 @@ static u32 __init ati_ixp4x0_rev(int num, int slot, int func)
d &= 0xff;
return d;
}
+#endif
static void __init ati_bugs(int num, int slot, int func)
{
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 38946c6e8433..1c17d7c751a4 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -147,27 +147,14 @@ END(ftrace_graph_caller)
GLOBAL(return_to_handler)
subq $80, %rsp
+ /* Save the return values */
movq %rax, (%rsp)
- movq %rcx, 8(%rsp)
- movq %rdx, 16(%rsp)
- movq %rsi, 24(%rsp)
- movq %rdi, 32(%rsp)
- movq %r8, 40(%rsp)
- movq %r9, 48(%rsp)
- movq %r10, 56(%rsp)
- movq %r11, 64(%rsp)
+ movq %rdx, 8(%rsp)
call ftrace_return_to_handler
movq %rax, 72(%rsp)
- movq 64(%rsp), %r11
- movq 56(%rsp), %r10
- movq 48(%rsp), %r9
- movq 40(%rsp), %r8
- movq 32(%rsp), %rdi
- movq 24(%rsp), %rsi
- movq 16(%rsp), %rdx
- movq 8(%rsp), %rcx
+ movq 8(%rsp), %rdx
movq (%rsp), %rax
addq $72, %rsp
retq
@@ -1379,6 +1366,11 @@ END(xen_failsafe_callback)
paranoidzeroentry_ist debug do_debug DEBUG_STACK
paranoidzeroentry_ist int3 do_int3 DEBUG_STACK
paranoiderrorentry stack_segment do_stack_segment
+#ifdef CONFIG_XEN
+zeroentry xen_debug do_debug
+zeroentry xen_int3 do_int3
+errorentry xen_stack_segment do_stack_segment
+#endif
errorentry general_protection do_general_protection
errorentry page_fault do_page_fault
#ifdef CONFIG_X86_MCE
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 30683883e0cd..dc5ed4bdd88d 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -608,13 +608,6 @@ ignore_int:
ENTRY(initial_code)
.long i386_start_kernel
-.section .text
-/*
- * Real beginning of normal "text" segment
- */
-ENTRY(stext)
-ENTRY(_stext)
-
/*
* BSS section
*/
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index c3fe010d74c8..9a391bbb8ba8 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -12,6 +12,7 @@
#include <asm/io_apic.h>
#include <asm/irq.h>
#include <asm/idle.h>
+#include <asm/hw_irq.h>
atomic_t irq_err_count;
@@ -24,9 +25,9 @@ void (*generic_interrupt_extension)(void) = NULL;
*/
void ack_bad_irq(unsigned int irq)
{
- printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
+ if (printk_ratelimit())
+ pr_err("unexpected IRQ trap at vector %02x\n", irq);
-#ifdef CONFIG_X86_LOCAL_APIC
/*
* Currently unexpected vectors happen only on SMP and APIC.
* We _must_ ack these because every local APIC has only N
@@ -36,9 +37,7 @@ void ack_bad_irq(unsigned int irq)
* completely.
* But only ack when the APIC is enabled -AK
*/
- if (cpu_has_apic)
- ack_APIC_irq();
-#endif
+ ack_APIC_irq();
}
#define irq_stats(x) (&per_cpu(irq_stat, x))
@@ -178,7 +177,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
sum += irq_stats(cpu)->irq_thermal_count;
# ifdef CONFIG_X86_64
sum += irq_stats(cpu)->irq_threshold_count;
-#endif
+# endif
#endif
return sum;
}
@@ -213,14 +212,11 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
irq = __get_cpu_var(vector_irq)[vector];
if (!handle_irq(irq, regs)) {
-#ifdef CONFIG_X86_64
- if (!disable_apic)
- ack_APIC_irq();
-#endif
+ ack_APIC_irq();
if (printk_ratelimit())
- printk(KERN_EMERG "%s: %d.%d No irq handler for vector (irq %d)\n",
- __func__, smp_processor_id(), vector, irq);
+ pr_emerg("%s: %d.%d No irq handler for vector (irq %d)\n",
+ __func__, smp_processor_id(), vector, irq);
}
irq_exit();
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit.c
index 368b0a8836f9..2e08b10ad51a 100644
--- a/arch/x86/kernel/irqinit_32.c
+++ b/arch/x86/kernel/irqinit.c
@@ -1,20 +1,25 @@
+#include <linux/linkage.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
+#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
+#include <linux/kprobes.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
#include <linux/bitops.h>
+#include <linux/acpi.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <asm/atomic.h>
#include <asm/system.h>
#include <asm/timer.h>
+#include <asm/hw_irq.h>
#include <asm/pgtable.h>
#include <asm/desc.h>
#include <asm/apic.h>
@@ -22,7 +27,23 @@
#include <asm/i8259.h>
#include <asm/traps.h>
+/*
+ * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
+ * (these are usually mapped to vectors 0x30-0x3f)
+ */
+
+/*
+ * The IO-APIC gives us many more interrupt sources. Most of these
+ * are unused but an SMP system is supposed to have enough memory ...
+ * sometimes (mostly wrt. hw bugs) we get corrupted vectors all
+ * across the spectrum, so we really want to be prepared to get all
+ * of these. Plus, more powerful systems might have more than 64
+ * IO-APIC registers.
+ *
+ * (these are usually mapped into the 0x30-0xff vector range)
+ */
+#ifdef CONFIG_X86_32
/*
* Note that on a 486, we don't want to do a SIGFPE on an irq13
* as the irq is unreliable, and exception 16 works correctly
@@ -52,30 +73,7 @@ static struct irqaction fpu_irq = {
.handler = math_error_irq,
.name = "fpu",
};
-
-void __init init_ISA_irqs(void)
-{
- int i;
-
-#ifdef CONFIG_X86_LOCAL_APIC
- init_bsp_APIC();
#endif
- init_8259A(0);
-
- /*
- * 16 old-style INTA-cycle interrupts:
- */
- for (i = 0; i < NR_IRQS_LEGACY; i++) {
- struct irq_desc *desc = irq_to_desc(i);
-
- desc->status = IRQ_DISABLED;
- desc->action = NULL;
- desc->depth = 1;
-
- set_irq_chip_and_handler_name(i, &i8259A_chip,
- handle_level_irq, "XT");
- }
-}
/*
* IRQ2 is cascade interrupt to second interrupt controller
@@ -118,29 +116,37 @@ int vector_used_by_percpu_irq(unsigned int vector)
return 0;
}
-/* Overridden in paravirt.c */
-void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
-
-void __init native_init_IRQ(void)
+static void __init init_ISA_irqs(void)
{
int i;
- /* Execute any quirks before the call gates are initialised: */
- x86_quirk_pre_intr_init();
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
+ init_bsp_APIC();
+#endif
+ init_8259A(0);
/*
- * Cover the whole vector space, no vector can escape
- * us. (some of these will be overridden and become
- * 'special' SMP interrupts)
+ * 16 old-style INTA-cycle interrupts:
*/
- for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
- /* SYSCALL_VECTOR was reserved in trap_init. */
- if (i != SYSCALL_VECTOR)
- set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]);
+ for (i = 0; i < NR_IRQS_LEGACY; i++) {
+ struct irq_desc *desc = irq_to_desc(i);
+
+ desc->status = IRQ_DISABLED;
+ desc->action = NULL;
+ desc->depth = 1;
+
+ set_irq_chip_and_handler_name(i, &i8259A_chip,
+ handle_level_irq, "XT");
}
+}
+/* Overridden in paravirt.c */
+void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
-#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP)
+static void __init smp_intr_init(void)
+{
+#ifdef CONFIG_SMP
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
/*
* The reschedule interrupt is a CPU-to-CPU reschedule-helper
* IPI, driven by wakeup.
@@ -160,16 +166,27 @@ void __init native_init_IRQ(void)
/* IPI for generic function call */
alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
- /* IPI for single call function */
+ /* IPI for generic single function call */
alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,
- call_function_single_interrupt);
+ call_function_single_interrupt);
/* Low priority IPI to cleanup after moving an irq */
set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
#endif
+#endif /* CONFIG_SMP */
+}
+
+static void __init apic_intr_init(void)
+{
+ smp_intr_init();
+
+#ifdef CONFIG_X86_64
+ alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
+ alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
+#endif
-#ifdef CONFIG_X86_LOCAL_APIC
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
/* self generated IPI for local APIC timer */
alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
@@ -179,16 +196,67 @@ void __init native_init_IRQ(void)
/* IPI vectors for APIC spurious and error interrupts */
alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
+
+ /* Performance monitoring interrupts: */
+# ifdef CONFIG_PERF_COUNTERS
+ alloc_intr_gate(LOCAL_PERF_VECTOR, perf_counter_interrupt);
+ alloc_intr_gate(LOCAL_PENDING_VECTOR, perf_pending_interrupt);
+# endif
+
#endif
+#ifdef CONFIG_X86_32
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_MCE_P4THERMAL)
/* thermal monitor LVT interrupt */
alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
#endif
+#endif
+}
+
+/**
+ * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
+ *
+ * Description:
+ * Perform any necessary interrupt initialisation prior to setting up
+ * the "ordinary" interrupt call gates. For legacy reasons, the ISA
+ * interrupts should be initialised here if the machine emulates a PC
+ * in any way.
+ **/
+static void __init x86_quirk_pre_intr_init(void)
+{
+#ifdef CONFIG_X86_32
+ if (x86_quirks->arch_pre_intr_init) {
+ if (x86_quirks->arch_pre_intr_init())
+ return;
+ }
+#endif
+ init_ISA_irqs();
+}
+
+void __init native_init_IRQ(void)
+{
+ int i;
+
+ /* Execute any quirks before the call gates are initialised: */
+ x86_quirk_pre_intr_init();
+
+ apic_intr_init();
+
+ /*
+ * Cover the whole vector space, no vector can escape
+ * us. (some of these will be overridden and become
+ * 'special' SMP interrupts)
+ */
+ for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
+ /* IA32_SYSCALL_VECTOR could be used in trap_init already. */
+ if (!test_bit(i, used_vectors))
+ set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]);
+ }
if (!acpi_ioapic)
setup_irq(2, &irq2);
+#ifdef CONFIG_X86_32
/*
* Call quirks after call gates are initialised (usually add in
* the architecture specific gates):
@@ -203,4 +271,5 @@ void __init native_init_IRQ(void)
setup_irq(FPU_IRQ, &fpu_irq);
irq_ctx_init(smp_processor_id());
+#endif
}
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c
deleted file mode 100644
index 8cd10537fd46..000000000000
--- a/arch/x86/kernel/irqinit_64.c
+++ /dev/null
@@ -1,177 +0,0 @@
-#include <linux/linkage.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/sysdev.h>
-#include <linux/bitops.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include <asm/atomic.h>
-#include <asm/system.h>
-#include <asm/hw_irq.h>
-#include <asm/pgtable.h>
-#include <asm/desc.h>
-#include <asm/apic.h>
-#include <asm/i8259.h>
-
-/*
- * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
- * (these are usually mapped to vectors 0x30-0x3f)
- */
-
-/*
- * The IO-APIC gives us many more interrupt sources. Most of these
- * are unused but an SMP system is supposed to have enough memory ...
- * sometimes (mostly wrt. hw bugs) we get corrupted vectors all
- * across the spectrum, so we really want to be prepared to get all
- * of these. Plus, more powerful systems might have more than 64
- * IO-APIC registers.
- *
- * (these are usually mapped into the 0x30-0xff vector range)
- */
-
-/*
- * IRQ2 is cascade interrupt to second interrupt controller
- */
-
-static struct irqaction irq2 = {
- .handler = no_action,
- .name = "cascade",
-};
-DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
- [0 ... IRQ0_VECTOR - 1] = -1,
- [IRQ0_VECTOR] = 0,
- [IRQ1_VECTOR] = 1,
- [IRQ2_VECTOR] = 2,
- [IRQ3_VECTOR] = 3,
- [IRQ4_VECTOR] = 4,
- [IRQ5_VECTOR] = 5,
- [IRQ6_VECTOR] = 6,
- [IRQ7_VECTOR] = 7,
- [IRQ8_VECTOR] = 8,
- [IRQ9_VECTOR] = 9,
- [IRQ10_VECTOR] = 10,
- [IRQ11_VECTOR] = 11,
- [IRQ12_VECTOR] = 12,
- [IRQ13_VECTOR] = 13,
- [IRQ14_VECTOR] = 14,
- [IRQ15_VECTOR] = 15,
- [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
-};
-
-int vector_used_by_percpu_irq(unsigned int vector)
-{
- int cpu;
-
- for_each_online_cpu(cpu) {
- if (per_cpu(vector_irq, cpu)[vector] != -1)
- return 1;
- }
-
- return 0;
-}
-
-static void __init init_ISA_irqs(void)
-{
- int i;
-
- init_bsp_APIC();
- init_8259A(0);
-
- for (i = 0; i < NR_IRQS_LEGACY; i++) {
- struct irq_desc *desc = irq_to_desc(i);
-
- desc->status = IRQ_DISABLED;
- desc->action = NULL;
- desc->depth = 1;
-
- /*
- * 16 old-style INTA-cycle interrupts:
- */
- set_irq_chip_and_handler_name(i, &i8259A_chip,
- handle_level_irq, "XT");
- }
-}
-
-void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
-
-static void __init smp_intr_init(void)
-{
-#ifdef CONFIG_SMP
- /*
- * The reschedule interrupt is a CPU-to-CPU reschedule-helper
- * IPI, driven by wakeup.
- */
- alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
-
- /* IPIs for invalidation */
- alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0);
- alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1);
- alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2);
- alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3);
- alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4);
- alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5);
- alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6);
- alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7);
-
- /* IPI for generic function call */
- alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
-
- /* IPI for generic single function call */
- alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,
- call_function_single_interrupt);
-
- /* Low priority IPI to cleanup after moving an irq */
- set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
- set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
-#endif
-}
-
-static void __init apic_intr_init(void)
-{
- smp_intr_init();
-
- alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
- alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
-
- /* self generated IPI for local APIC timer */
- alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
-
- /* generic IPI for platform specific use */
- alloc_intr_gate(GENERIC_INTERRUPT_VECTOR, generic_interrupt);
-
- /* IPI vectors for APIC spurious and error interrupts */
- alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
- alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
-}
-
-void __init native_init_IRQ(void)
-{
- int i;
-
- init_ISA_irqs();
- /*
- * Cover the whole vector space, no vector can escape
- * us. (some of these will be overridden and become
- * 'special' SMP interrupts)
- */
- for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
- int vector = FIRST_EXTERNAL_VECTOR + i;
- if (vector != IA32_SYSCALL_VECTOR)
- set_intr_gate(vector, interrupt[i]);
- }
-
- apic_intr_init();
-
- if (!acpi_ioapic)
- setup_irq(2, &irq2);
-}
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index eedfaebe1063..8d82a77a3f3b 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -88,6 +88,7 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
gdb_regs[GDB_SS] = __KERNEL_DS;
gdb_regs[GDB_FS] = 0xFFFF;
gdb_regs[GDB_GS] = 0xFFFF;
+ gdb_regs[GDB_SP] = (int)&regs->sp;
#else
gdb_regs[GDB_R8] = regs->r8;
gdb_regs[GDB_R9] = regs->r9;
@@ -100,8 +101,8 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
gdb_regs32[GDB_PS] = regs->flags;
gdb_regs32[GDB_CS] = regs->cs;
gdb_regs32[GDB_SS] = regs->ss;
-#endif
gdb_regs[GDB_SP] = regs->sp;
+#endif
}
/**
@@ -141,7 +142,7 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
gdb_regs32[GDB_PS] = *(unsigned long *)(p->thread.sp + 8);
gdb_regs32[GDB_CS] = __KERNEL_CS;
gdb_regs32[GDB_SS] = __KERNEL_DS;
- gdb_regs[GDB_PC] = p->thread.ip;
+ gdb_regs[GDB_PC] = 0;
gdb_regs[GDB_R8] = 0;
gdb_regs[GDB_R9] = 0;
gdb_regs[GDB_R10] = 0;
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 33019ddb56b4..a78ecad0c900 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -27,6 +27,7 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/hardirq.h>
+#include <asm/timer.h>
#define MMU_QUEUE_SIZE 1024
@@ -195,7 +196,7 @@ static void kvm_leave_lazy_mmu(void)
struct kvm_para_state *state = kvm_para_state();
mmu_queue_flush(state);
- paravirt_leave_lazy(paravirt_get_lazy_mode());
+ paravirt_leave_lazy_mmu();
state->mode = paravirt_get_lazy_mode();
}
@@ -230,6 +231,9 @@ static void paravirt_ops_setup(void)
pv_mmu_ops.lazy_mode.enter = kvm_enter_lazy_mmu;
pv_mmu_ops.lazy_mode.leave = kvm_leave_lazy_mmu;
}
+#ifdef CONFIG_X86_IO_APIC
+ no_timer_check = 1;
+#endif
}
void __init kvm_guest_init(void)
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index e7368c1da01d..c1c429d00130 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -194,7 +194,7 @@ void machine_kexec(struct kimage *image)
unsigned int preserve_context);
#ifdef CONFIG_KEXEC_JUMP
- if (kexec_image->preserve_context)
+ if (image->preserve_context)
save_processor_state();
#endif
@@ -253,7 +253,7 @@ void machine_kexec(struct kimage *image)
image->preserve_context);
#ifdef CONFIG_KEXEC_JUMP
- if (kexec_image->preserve_context)
+ if (image->preserve_context)
restore_processor_state();
#endif
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 89cea4d44679..84c3bf209e98 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -274,7 +274,7 @@ void machine_kexec(struct kimage *image)
int save_ftrace_enabled;
#ifdef CONFIG_KEXEC_JUMP
- if (kexec_image->preserve_context)
+ if (image->preserve_context)
save_processor_state();
#endif
@@ -333,7 +333,7 @@ void machine_kexec(struct kimage *image)
image->preserve_context);
#ifdef CONFIG_KEXEC_JUMP
- if (kexec_image->preserve_context)
+ if (image->preserve_context)
restore_processor_state();
#endif
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 8e45f4464880..aa3442340705 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -246,18 +246,16 @@ static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LA
static inline void enter_lazy(enum paravirt_lazy_mode mode)
{
- BUG_ON(__get_cpu_var(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
- BUG_ON(preemptible());
+ BUG_ON(percpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
- __get_cpu_var(paravirt_lazy_mode) = mode;
+ percpu_write(paravirt_lazy_mode, mode);
}
-void paravirt_leave_lazy(enum paravirt_lazy_mode mode)
+static void leave_lazy(enum paravirt_lazy_mode mode)
{
- BUG_ON(__get_cpu_var(paravirt_lazy_mode) != mode);
- BUG_ON(preemptible());
+ BUG_ON(percpu_read(paravirt_lazy_mode) != mode);
- __get_cpu_var(paravirt_lazy_mode) = PARAVIRT_LAZY_NONE;
+ percpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE);
}
void paravirt_enter_lazy_mmu(void)
@@ -267,22 +265,36 @@ void paravirt_enter_lazy_mmu(void)
void paravirt_leave_lazy_mmu(void)
{
- paravirt_leave_lazy(PARAVIRT_LAZY_MMU);
+ leave_lazy(PARAVIRT_LAZY_MMU);
}
-void paravirt_enter_lazy_cpu(void)
+void paravirt_start_context_switch(struct task_struct *prev)
{
+ BUG_ON(preemptible());
+
+ if (percpu_read(paravirt_lazy_mode) == PARAVIRT_LAZY_MMU) {
+ arch_leave_lazy_mmu_mode();
+ set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES);
+ }
enter_lazy(PARAVIRT_LAZY_CPU);
}
-void paravirt_leave_lazy_cpu(void)
+void paravirt_end_context_switch(struct task_struct *next)
{
- paravirt_leave_lazy(PARAVIRT_LAZY_CPU);
+ BUG_ON(preemptible());
+
+ leave_lazy(PARAVIRT_LAZY_CPU);
+
+ if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES))
+ arch_enter_lazy_mmu_mode();
}
enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
{
- return __get_cpu_var(paravirt_lazy_mode);
+ if (in_interrupt())
+ return PARAVIRT_LAZY_NONE;
+
+ return percpu_read(paravirt_lazy_mode);
}
void arch_flush_lazy_mmu_mode(void)
@@ -290,7 +302,6 @@ void arch_flush_lazy_mmu_mode(void)
preempt_disable();
if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
- WARN_ON(preempt_count() == 1);
arch_leave_lazy_mmu_mode();
arch_enter_lazy_mmu_mode();
}
@@ -298,19 +309,6 @@ void arch_flush_lazy_mmu_mode(void)
preempt_enable();
}
-void arch_flush_lazy_cpu_mode(void)
-{
- preempt_disable();
-
- if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) {
- WARN_ON(preempt_count() == 1);
- arch_leave_lazy_cpu_mode();
- arch_enter_lazy_cpu_mode();
- }
-
- preempt_enable();
-}
-
struct pv_info pv_info = {
.name = "bare hardware",
.paravirt_enabled = 0,
@@ -402,10 +400,8 @@ struct pv_cpu_ops pv_cpu_ops = {
.set_iopl_mask = native_set_iopl_mask,
.io_delay = native_io_delay,
- .lazy_mode = {
- .enter = paravirt_nop,
- .leave = paravirt_nop,
- },
+ .start_context_switch = paravirt_nop,
+ .end_context_switch = paravirt_nop,
};
struct pv_apic_ops pv_apic_ops = {
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 755c21e906f3..971a3bec47a8 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -186,37 +186,6 @@ static struct cal_chipset_ops calioc2_chip_ops = {
static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, };
-/* enable this to stress test the chip's TCE cache */
-#ifdef CONFIG_IOMMU_DEBUG
-static int debugging = 1;
-
-static inline unsigned long verify_bit_range(unsigned long* bitmap,
- int expected, unsigned long start, unsigned long end)
-{
- unsigned long idx = start;
-
- BUG_ON(start >= end);
-
- while (idx < end) {
- if (!!test_bit(idx, bitmap) != expected)
- return idx;
- ++idx;
- }
-
- /* all bits have the expected value */
- return ~0UL;
-}
-#else /* debugging is disabled */
-static int debugging;
-
-static inline unsigned long verify_bit_range(unsigned long* bitmap,
- int expected, unsigned long start, unsigned long end)
-{
- return ~0UL;
-}
-
-#endif /* CONFIG_IOMMU_DEBUG */
-
static inline int translation_enabled(struct iommu_table *tbl)
{
/* only PHBs with translation enabled have an IOMMU table */
@@ -228,7 +197,6 @@ static void iommu_range_reserve(struct iommu_table *tbl,
{
unsigned long index;
unsigned long end;
- unsigned long badbit;
unsigned long flags;
index = start_addr >> PAGE_SHIFT;
@@ -243,14 +211,6 @@ static void iommu_range_reserve(struct iommu_table *tbl,
spin_lock_irqsave(&tbl->it_lock, flags);
- badbit = verify_bit_range(tbl->it_map, 0, index, end);
- if (badbit != ~0UL) {
- if (printk_ratelimit())
- printk(KERN_ERR "Calgary: entry already allocated at "
- "0x%lx tbl %p dma 0x%lx npages %u\n",
- badbit, tbl, start_addr, npages);
- }
-
iommu_area_reserve(tbl->it_map, index, npages);
spin_unlock_irqrestore(&tbl->it_lock, flags);
@@ -326,7 +286,6 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
unsigned int npages)
{
unsigned long entry;
- unsigned long badbit;
unsigned long badend;
unsigned long flags;
@@ -346,14 +305,6 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
spin_lock_irqsave(&tbl->it_lock, flags);
- badbit = verify_bit_range(tbl->it_map, 1, entry, entry + npages);
- if (badbit != ~0UL) {
- if (printk_ratelimit())
- printk(KERN_ERR "Calgary: bit is off at 0x%lx "
- "tbl %p dma 0x%Lx entry 0x%lx npages %u\n",
- badbit, tbl, dma_addr, entry, npages);
- }
-
iommu_area_free(tbl->it_map, entry, npages);
spin_unlock_irqrestore(&tbl->it_lock, flags);
@@ -1488,9 +1439,8 @@ void __init detect_calgary(void)
iommu_detected = 1;
calgary_detected = 1;
printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected.\n");
- printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, "
- "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size,
- debugging ? "enabled" : "disabled");
+ printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d\n",
+ specified_table_size);
/* swiotlb for devices that aren't behind the Calgary. */
if (max_pfn > MAX_DMA32_PFN)
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 745579bc8256..049005e82178 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -32,6 +32,8 @@ int no_iommu __read_mostly;
/* Set this to 1 if there is a HW IOMMU in the system */
int iommu_detected __read_mostly = 0;
+int iommu_pass_through;
+
dma_addr_t bad_dma_address __read_mostly = 0;
EXPORT_SYMBOL(bad_dma_address);
@@ -209,6 +211,10 @@ static __init int iommu_setup(char *p)
#ifdef CONFIG_SWIOTLB
if (!strncmp(p, "soft", 4))
swiotlb = 1;
+ if (!strncmp(p, "pt", 2)) {
+ iommu_pass_through = 1;
+ return 1;
+ }
#endif
gart_parse_options(p);
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index b284b58c035c..1e8920d98f7c 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -144,48 +144,21 @@ static void flush_gart(void)
}
#ifdef CONFIG_IOMMU_LEAK
-
-#define SET_LEAK(x) \
- do { \
- if (iommu_leak_tab) \
- iommu_leak_tab[x] = __builtin_return_address(0);\
- } while (0)
-
-#define CLEAR_LEAK(x) \
- do { \
- if (iommu_leak_tab) \
- iommu_leak_tab[x] = NULL; \
- } while (0)
-
/* Debugging aid for drivers that don't free their IOMMU tables */
-static void **iommu_leak_tab;
static int leak_trace;
static int iommu_leak_pages = 20;
static void dump_leak(void)
{
- int i;
static int dump;
- if (dump || !iommu_leak_tab)
+ if (dump)
return;
dump = 1;
- show_stack(NULL, NULL);
- /* Very crude. dump some from the end of the table too */
- printk(KERN_DEBUG "Dumping %d pages from end of IOMMU:\n",
- iommu_leak_pages);
- for (i = 0; i < iommu_leak_pages; i += 2) {
- printk(KERN_DEBUG "%lu: ", iommu_pages-i);
- printk_address((unsigned long) iommu_leak_tab[iommu_pages-i],
- 0);
- printk(KERN_CONT "%c", (i+1)%2 == 0 ? '\n' : ' ');
- }
- printk(KERN_DEBUG "\n");
+ show_stack(NULL, NULL);
+ debug_dma_dump_mappings(NULL);
}
-#else
-# define SET_LEAK(x)
-# define CLEAR_LEAK(x)
#endif
static void iommu_full(struct device *dev, size_t size, int dir)
@@ -248,7 +221,6 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
for (i = 0; i < npages; i++) {
iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
- SET_LEAK(iommu_page + i);
phys_mem += PAGE_SIZE;
}
return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK);
@@ -294,7 +266,6 @@ static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr,
npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
for (i = 0; i < npages; i++) {
iommu_gatt_base[iommu_page + i] = gart_unmapped_entry;
- CLEAR_LEAK(iommu_page + i);
}
free_iommu(iommu_page, npages);
}
@@ -377,7 +348,6 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start,
pages = iommu_num_pages(s->offset, s->length, PAGE_SIZE);
while (pages--) {
iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr);
- SET_LEAK(iommu_page);
addr += PAGE_SIZE;
iommu_page++;
}
@@ -801,11 +771,12 @@ void __init gart_iommu_init(void)
#ifdef CONFIG_IOMMU_LEAK
if (leak_trace) {
- iommu_leak_tab = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
- get_order(iommu_pages*sizeof(void *)));
- if (!iommu_leak_tab)
+ int ret;
+
+ ret = dma_debug_resize_entries(iommu_pages);
+ if (ret)
printk(KERN_DEBUG
- "PCI-DMA: Cannot allocate leak trace area\n");
+ "PCI-DMA: Cannot trace all the entries\n");
}
#endif
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index 221a3853e268..6af96ee44200 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -28,7 +28,7 @@ dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr)
return paddr;
}
-phys_addr_t swiotlb_bus_to_phys(dma_addr_t baddr)
+phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr)
{
return baddr;
}
@@ -71,7 +71,8 @@ void __init pci_swiotlb_init(void)
{
/* don't initialize swiotlb if iommu=off (no_iommu=1) */
#ifdef CONFIG_X86_64
- if (!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN)
+ if ((!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN) ||
+ iommu_pass_through)
swiotlb = 1;
#endif
if (swiotlb_force)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index ca989158e847..08f23b50af53 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -11,9 +11,11 @@
#include <trace/power.h>
#include <asm/system.h>
#include <asm/apic.h>
+#include <asm/syscalls.h>
#include <asm/idle.h>
#include <asm/uaccess.h>
#include <asm/i387.h>
+#include <asm/ds.h>
unsigned long idle_halt;
EXPORT_SYMBOL(idle_halt);
@@ -45,6 +47,8 @@ void free_thread_xstate(struct task_struct *tsk)
kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
tsk->thread.xstate = NULL;
}
+
+ WARN(tsk->thread.ds_ctx, "leaking DS context\n");
}
void free_thread_info(struct thread_info *ti)
@@ -83,8 +87,6 @@ void exit_thread(void)
put_cpu();
kfree(bp);
}
-
- ds_exit_thread(current);
}
void flush_thread(void)
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 76f8f84043a2..54638585993b 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -290,7 +290,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
p->thread.io_bitmap_max = 0;
}
- ds_copy_thread(p, current);
+ clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
+ p->thread.ds_ctx = NULL;
clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
p->thread.debugctlmsr = 0;
@@ -407,7 +408,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
* done before math_state_restore, so the TS bit is up
* to date.
*/
- arch_leave_lazy_cpu_mode();
+ arch_end_context_switch(next_p);
/* If the task has used fpu the last 5 timeslices, just do a full
* restore of the math state immediately to avoid the trap; the
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index b751a41392b1..2b659f21a83c 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -335,7 +335,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
goto out;
}
- ds_copy_thread(p, me);
+ clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
+ p->thread.ds_ctx = NULL;
clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
p->thread.debugctlmsr = 0;
@@ -428,7 +429,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
* done before math_state_restore, so the TS bit is up
* to date.
*/
- arch_leave_lazy_cpu_mode();
+ arch_end_context_switch(next_p);
/*
* Switch FS and GS.
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 23b7c8f017e2..09ecbde91c13 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -21,6 +21,7 @@
#include <linux/audit.h>
#include <linux/seccomp.h>
#include <linux/signal.h>
+#include <linux/workqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -578,17 +579,130 @@ static int ioperm_get(struct task_struct *target,
}
#ifdef CONFIG_X86_PTRACE_BTS
+/*
+ * A branch trace store context.
+ *
+ * Contexts may only be installed by ptrace_bts_config() and only for
+ * ptraced tasks.
+ *
+ * Contexts are destroyed when the tracee is detached from the tracer.
+ * The actual destruction work requires interrupts enabled, so the
+ * work is deferred and will be scheduled during __ptrace_unlink().
+ *
+ * Contexts hold an additional task_struct reference on the traced
+ * task, as well as a reference on the tracer's mm.
+ *
+ * Ptrace already holds a task_struct for the duration of ptrace operations,
+ * but since destruction is deferred, it may be executed after both
+ * tracer and tracee exited.
+ */
+struct bts_context {
+ /* The branch trace handle. */
+ struct bts_tracer *tracer;
+
+ /* The buffer used to store the branch trace and its size. */
+ void *buffer;
+ unsigned int size;
+
+ /* The mm that paid for the above buffer. */
+ struct mm_struct *mm;
+
+ /* The task this context belongs to. */
+ struct task_struct *task;
+
+ /* The signal to send on a bts buffer overflow. */
+ unsigned int bts_ovfl_signal;
+
+ /* The work struct to destroy a context. */
+ struct work_struct work;
+};
+
+static int alloc_bts_buffer(struct bts_context *context, unsigned int size)
+{
+ void *buffer = NULL;
+ int err = -ENOMEM;
+
+ err = account_locked_memory(current->mm, current->signal->rlim, size);
+ if (err < 0)
+ return err;
+
+ buffer = kzalloc(size, GFP_KERNEL);
+ if (!buffer)
+ goto out_refund;
+
+ context->buffer = buffer;
+ context->size = size;
+ context->mm = get_task_mm(current);
+
+ return 0;
+
+ out_refund:
+ refund_locked_memory(current->mm, size);
+ return err;
+}
+
+static inline void free_bts_buffer(struct bts_context *context)
+{
+ if (!context->buffer)
+ return;
+
+ kfree(context->buffer);
+ context->buffer = NULL;
+
+ refund_locked_memory(context->mm, context->size);
+ context->size = 0;
+
+ mmput(context->mm);
+ context->mm = NULL;
+}
+
+static void free_bts_context_work(struct work_struct *w)
+{
+ struct bts_context *context;
+
+ context = container_of(w, struct bts_context, work);
+
+ ds_release_bts(context->tracer);
+ put_task_struct(context->task);
+ free_bts_buffer(context);
+ kfree(context);
+}
+
+static inline void free_bts_context(struct bts_context *context)
+{
+ INIT_WORK(&context->work, free_bts_context_work);
+ schedule_work(&context->work);
+}
+
+static inline struct bts_context *alloc_bts_context(struct task_struct *task)
+{
+ struct bts_context *context = kzalloc(sizeof(*context), GFP_KERNEL);
+ if (context) {
+ context->task = task;
+ task->bts = context;
+
+ get_task_struct(task);
+ }
+
+ return context;
+}
+
static int ptrace_bts_read_record(struct task_struct *child, size_t index,
struct bts_struct __user *out)
{
+ struct bts_context *context;
const struct bts_trace *trace;
struct bts_struct bts;
const unsigned char *at;
int error;
- trace = ds_read_bts(child->bts);
+ context = child->bts;
+ if (!context)
+ return -ESRCH;
+
+ trace = ds_read_bts(context->tracer);
if (!trace)
- return -EPERM;
+ return -ESRCH;
at = trace->ds.top - ((index + 1) * trace->ds.size);
if ((void *)at < trace->ds.begin)
@@ -597,7 +711,7 @@ static int ptrace_bts_read_record(struct task_struct *child, size_t index,
if (!trace->read)
return -EOPNOTSUPP;
- error = trace->read(child->bts, at, &bts);
+ error = trace->read(context->tracer, at, &bts);
if (error < 0)
return error;
@@ -611,13 +725,18 @@ static int ptrace_bts_drain(struct task_struct *child,
long size,
struct bts_struct __user *out)
{
+ struct bts_context *context;
const struct bts_trace *trace;
const unsigned char *at;
int error, drained = 0;
- trace = ds_read_bts(child->bts);
+ context = child->bts;
+ if (!context)
+ return -ESRCH;
+
+ trace = ds_read_bts(context->tracer);
if (!trace)
- return -EPERM;
+ return -ESRCH;
if (!trace->read)
return -EOPNOTSUPP;
@@ -628,9 +747,8 @@ static int ptrace_bts_drain(struct task_struct *child,
for (at = trace->ds.begin; (void *)at < trace->ds.top;
out++, drained++, at += trace->ds.size) {
struct bts_struct bts;
- int error;
- error = trace->read(child->bts, at, &bts);
+ error = trace->read(context->tracer, at, &bts);
if (error < 0)
return error;
@@ -640,35 +758,18 @@ static int ptrace_bts_drain(struct task_struct *child,
memset(trace->ds.begin, 0, trace->ds.n * trace->ds.size);
- error = ds_reset_bts(child->bts);
+ error = ds_reset_bts(context->tracer);
if (error < 0)
return error;
return drained;
}
-static int ptrace_bts_allocate_buffer(struct task_struct *child, size_t size)
-{
- child->bts_buffer = alloc_locked_buffer(size);
- if (!child->bts_buffer)
- return -ENOMEM;
-
- child->bts_size = size;
-
- return 0;
-}
-
-static void ptrace_bts_free_buffer(struct task_struct *child)
-{
- free_locked_buffer(child->bts_buffer, child->bts_size);
- child->bts_buffer = NULL;
- child->bts_size = 0;
-}
-
static int ptrace_bts_config(struct task_struct *child,
long cfg_size,
const struct ptrace_bts_config __user *ucfg)
{
+ struct bts_context *context;
struct ptrace_bts_config cfg;
unsigned int flags = 0;
@@ -678,28 +779,33 @@ static int ptrace_bts_config(struct task_struct *child,
if (copy_from_user(&cfg, ucfg, sizeof(cfg)))
return -EFAULT;
- if (child->bts) {
- ds_release_bts(child->bts);
- child->bts = NULL;
- }
+ context = child->bts;
+ if (!context)
+ context = alloc_bts_context(child);
+ if (!context)
+ return -ENOMEM;
if (cfg.flags & PTRACE_BTS_O_SIGNAL) {
if (!cfg.signal)
return -EINVAL;
- child->thread.bts_ovfl_signal = cfg.signal;
return -EOPNOTSUPP;
+ context->bts_ovfl_signal = cfg.signal;
}
- if ((cfg.flags & PTRACE_BTS_O_ALLOC) &&
- (cfg.size != child->bts_size)) {
- int error;
+ ds_release_bts(context->tracer);
+ context->tracer = NULL;
- ptrace_bts_free_buffer(child);
+ if ((cfg.flags & PTRACE_BTS_O_ALLOC) && (cfg.size != context->size)) {
+ int err;
- error = ptrace_bts_allocate_buffer(child, cfg.size);
- if (error < 0)
- return error;
+ free_bts_buffer(context);
+ if (!cfg.size)
+ return 0;
+
+ err = alloc_bts_buffer(context, cfg.size);
+ if (err < 0)
+ return err;
}
if (cfg.flags & PTRACE_BTS_O_TRACE)
@@ -708,15 +814,14 @@ static int ptrace_bts_config(struct task_struct *child,
if (cfg.flags & PTRACE_BTS_O_SCHED)
flags |= BTS_TIMESTAMPS;
- child->bts = ds_request_bts(child, child->bts_buffer, child->bts_size,
- /* ovfl = */ NULL, /* th = */ (size_t)-1,
- flags);
- if (IS_ERR(child->bts)) {
- int error = PTR_ERR(child->bts);
-
- ptrace_bts_free_buffer(child);
- child->bts = NULL;
+ context->tracer =
+ ds_request_bts_task(child, context->buffer, context->size,
+ NULL, (size_t)-1, flags);
+ if (unlikely(IS_ERR(context->tracer))) {
+ int error = PTR_ERR(context->tracer);
+ free_bts_buffer(context);
+ context->tracer = NULL;
return error;
}
@@ -727,20 +832,25 @@ static int ptrace_bts_status(struct task_struct *child,
long cfg_size,
struct ptrace_bts_config __user *ucfg)
{
+ struct bts_context *context;
const struct bts_trace *trace;
struct ptrace_bts_config cfg;
+ context = child->bts;
+ if (!context)
+ return -ESRCH;
+
if (cfg_size < sizeof(cfg))
return -EIO;
- trace = ds_read_bts(child->bts);
+ trace = ds_read_bts(context->tracer);
if (!trace)
- return -EPERM;
+ return -ESRCH;
memset(&cfg, 0, sizeof(cfg));
- cfg.size = trace->ds.end - trace->ds.begin;
- cfg.signal = child->thread.bts_ovfl_signal;
- cfg.bts_size = sizeof(struct bts_struct);
+ cfg.size = trace->ds.end - trace->ds.begin;
+ cfg.signal = context->bts_ovfl_signal;
+ cfg.bts_size = sizeof(struct bts_struct);
if (cfg.signal)
cfg.flags |= PTRACE_BTS_O_SIGNAL;
@@ -759,80 +869,51 @@ static int ptrace_bts_status(struct task_struct *child,
static int ptrace_bts_clear(struct task_struct *child)
{
+ struct bts_context *context;
const struct bts_trace *trace;
- trace = ds_read_bts(child->bts);
+ context = child->bts;
+ if (!context)
+ return -ESRCH;
+
+ trace = ds_read_bts(context->tracer);
if (!trace)
- return -EPERM;
+ return -ESRCH;
memset(trace->ds.begin, 0, trace->ds.n * trace->ds.size);
- return ds_reset_bts(child->bts);
+ return ds_reset_bts(context->tracer);
}
static int ptrace_bts_size(struct task_struct *child)
{
+ struct bts_context *context;
const struct bts_trace *trace;
- trace = ds_read_bts(child->bts);
+ context = child->bts;
+ if (!context)
+ return -ESRCH;
+
+ trace = ds_read_bts(context->tracer);
if (!trace)
- return -EPERM;
+ return -ESRCH;
return (trace->ds.top - trace->ds.begin) / trace->ds.size;
}
-static void ptrace_bts_fork(struct task_struct *tsk)
-{
- tsk->bts = NULL;
- tsk->bts_buffer = NULL;
- tsk->bts_size = 0;
- tsk->thread.bts_ovfl_signal = 0;
-}
-
-static void ptrace_bts_untrace(struct task_struct *child)
+/*
+ * Called from __ptrace_unlink() after the child has been moved back
+ * to its original parent.
+ */
+void ptrace_bts_untrace(struct task_struct *child)
{
if (unlikely(child->bts)) {
- ds_release_bts(child->bts);
+ free_bts_context(child->bts);
child->bts = NULL;
-
- /* We cannot update total_vm and locked_vm since
- child's mm is already gone. But we can reclaim the
- memory. */
- kfree(child->bts_buffer);
- child->bts_buffer = NULL;
- child->bts_size = 0;
}
}
-
-static void ptrace_bts_detach(struct task_struct *child)
-{
- /*
- * Ptrace_detach() races with ptrace_untrace() in case
- * the child dies and is reaped by another thread.
- *
- * We only do the memory accounting at this point and
- * leave the buffer deallocation and the bts tracer
- * release to ptrace_bts_untrace() which will be called
- * later on with tasklist_lock held.
- */
- release_locked_buffer(child->bts_buffer, child->bts_size);
-}
-#else
-static inline void ptrace_bts_fork(struct task_struct *tsk) {}
-static inline void ptrace_bts_detach(struct task_struct *child) {}
-static inline void ptrace_bts_untrace(struct task_struct *child) {}
#endif /* CONFIG_X86_PTRACE_BTS */
-void x86_ptrace_fork(struct task_struct *child, unsigned long clone_flags)
-{
- ptrace_bts_fork(child);
-}
-
-void x86_ptrace_untrace(struct task_struct *child)
-{
- ptrace_bts_untrace(child);
-}
-
/*
* Called by kernel/ptrace.c when detaching..
*
@@ -844,7 +925,6 @@ void ptrace_disable(struct task_struct *child)
#ifdef TIF_SYSCALL_EMU
clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
#endif
- ptrace_bts_detach(child);
}
#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index 7563b31b4f03..af71d06624bf 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -491,5 +491,42 @@ void force_hpet_resume(void)
break;
}
}
+#endif
+
+#if defined(CONFIG_PCI) && defined(CONFIG_NUMA)
+/* Set correct numa_node information for AMD NB functions */
+static void __init quirk_amd_nb_node(struct pci_dev *dev)
+{
+ struct pci_dev *nb_ht;
+ unsigned int devfn;
+ u32 val;
+
+ devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 0);
+ nb_ht = pci_get_slot(dev->bus, devfn);
+ if (!nb_ht)
+ return;
+
+ pci_read_config_dword(nb_ht, 0x60, &val);
+ set_dev_node(&dev->dev, val & 7);
+ pci_dev_put(dev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB,
+ quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP,
+ quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MEMCTL,
+ quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC,
+ quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_HT,
+ quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MAP,
+ quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_DRAM,
+ quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC,
+ quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_LINK,
+ quirk_amd_nb_node);
#endif
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index b4158439bf63..d059bba3891c 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -112,6 +112,14 @@
#define ARCH_SETUP
#endif
+/*
+ * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
+ * The direct mapping extends to max_pfn_mapped, so that we can directly access
+ * apertures, ACPI and other tables without having to play with fixmaps.
+ */
+unsigned long max_low_pfn_mapped;
+unsigned long max_pfn_mapped;
+
RESERVE_BRK(dmi_alloc, 65536);
unsigned int boot_cpu_id __read_mostly;
@@ -854,12 +862,16 @@ void __init setup_arch(char **cmdline_p)
max_low_pfn = max_pfn;
high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
+ max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
#endif
#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
setup_bios_corruption_check();
#endif
+ printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
+ max_pfn_mapped<<PAGE_SHIFT);
+
reserve_brk();
/* max_pfn_mapped is updated here */
@@ -997,24 +1009,6 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_X86_32
/**
- * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
- *
- * Description:
- * Perform any necessary interrupt initialisation prior to setting up
- * the "ordinary" interrupt call gates. For legacy reasons, the ISA
- * interrupts should be initialised here if the machine emulates a PC
- * in any way.
- **/
-void __init x86_quirk_pre_intr_init(void)
-{
- if (x86_quirks->arch_pre_intr_init) {
- if (x86_quirks->arch_pre_intr_init())
- return;
- }
- init_ISA_irqs();
-}
-
-/**
* x86_quirk_intr_init - post gate setup interrupt initialisation
*
* Description:
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 13f33ea8ccaa..28f5fb495a66 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -172,6 +172,9 @@ void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
inc_irq_stat(irq_resched_count);
+ /*
+ * KVM uses this interrupt to force a cpu out of guest mode
+ */
}
void smp_call_function_interrupt(struct pt_regs *regs)
@@ -193,19 +196,19 @@ void smp_call_function_single_interrupt(struct pt_regs *regs)
}
struct smp_ops smp_ops = {
- .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu,
- .smp_prepare_cpus = native_smp_prepare_cpus,
- .smp_cpus_done = native_smp_cpus_done,
+ .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu,
+ .smp_prepare_cpus = native_smp_prepare_cpus,
+ .smp_cpus_done = native_smp_cpus_done,
- .smp_send_stop = native_smp_send_stop,
- .smp_send_reschedule = native_smp_send_reschedule,
+ .smp_send_stop = native_smp_send_stop,
+ .smp_send_reschedule = native_smp_send_reschedule,
- .cpu_up = native_cpu_up,
- .cpu_die = native_cpu_die,
- .cpu_disable = native_cpu_disable,
- .play_dead = native_play_dead,
+ .cpu_up = native_cpu_up,
+ .cpu_die = native_cpu_die,
+ .cpu_disable = native_cpu_disable,
+ .play_dead = native_play_dead,
- .send_call_func_ipi = native_send_call_func_ipi,
+ .send_call_func_ipi = native_send_call_func_ipi,
.send_call_func_single_ipi = native_send_call_func_single_ipi,
};
EXPORT_SYMBOL_GPL(smp_ops);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 58d24ef917d8..d2e8de958156 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -504,7 +504,7 @@ void __inquire_remote_apic(int apicid)
* INIT, INIT, STARTUP sequence will reset the chip hard for us, and this
* won't ... remember to clear down the APIC, etc later.
*/
-int __devinit
+int __cpuinit
wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip)
{
unsigned long send_status, accept_status = 0;
@@ -538,7 +538,7 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip)
return (send_status | accept_status);
}
-int __devinit
+static int __cpuinit
wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
{
unsigned long send_status, accept_status = 0;
@@ -822,10 +822,12 @@ do_rest:
/* mark "stuck" area as not stuck */
*((volatile unsigned long *)trampoline_base) = 0;
- /*
- * Cleanup possible dangling ends...
- */
- smpboot_restore_warm_reset_vector();
+ if (get_uv_system_type() != UV_NON_UNIQUE_APIC) {
+ /*
+ * Cleanup possible dangling ends...
+ */
+ smpboot_restore_warm_reset_vector();
+ }
return boot_error;
}
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index ff5c8736b491..734f92c02dde 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -334,3 +334,4 @@ ENTRY(sys_call_table)
.long sys_inotify_init1
.long sys_preadv
.long sys_pwritev
+ .long sys_rt_tgsigqueueinfo /* 335 */
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index a1d288327ff0..ede024531f8f 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -839,9 +839,6 @@ asmlinkage void math_state_restore(void)
}
clts(); /* Allow maths ops (or we recurse) */
-#ifdef CONFIG_X86_32
- restore_fpu(tsk);
-#else
/*
* Paranoid restore. send a SIGSEGV if we fail to restore the state.
*/
@@ -850,7 +847,7 @@ asmlinkage void math_state_restore(void)
force_sig(SIGSEGV, tsk);
return;
}
-#endif
+
thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */
tsk->fpu_counter++;
}
@@ -969,11 +966,8 @@ void __init trap_init(void)
for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
set_bit(i, used_vectors);
-#ifdef CONFIG_X86_64
set_bit(IA32_SYSCALL_VECTOR, used_vectors);
-#else
- set_bit(SYSCALL_VECTOR, used_vectors);
-#endif
+
/*
* Should be a barrier for any external CPU state:
*/
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index d57de05dc430..84d27356c3d0 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -384,13 +384,13 @@ unsigned long native_calibrate_tsc(void)
{
u64 tsc1, tsc2, delta, ref1, ref2;
unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
- unsigned long flags, latch, ms, fast_calibrate, tsc_khz;
+ unsigned long flags, latch, ms, fast_calibrate, hv_tsc_khz;
int hpet = is_hpet_enabled(), i, loopmin;
- tsc_khz = get_hypervisor_tsc_freq();
- if (tsc_khz) {
+ hv_tsc_khz = get_hypervisor_tsc_freq();
+ if (hv_tsc_khz) {
printk(KERN_INFO "TSC: Frequency read from the hypervisor\n");
- return tsc_khz;
+ return hv_tsc_khz;
}
local_irq_save(flags);
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index bf36328f6ef9..027b5b498993 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -34,6 +34,7 @@ static __cpuinitdata atomic_t stop_count;
* of a critical section, to be able to prove TSC time-warps:
*/
static __cpuinitdata raw_spinlock_t sync_lock = __RAW_SPIN_LOCK_UNLOCKED;
+
static __cpuinitdata cycles_t last_tsc;
static __cpuinitdata cycles_t max_warp;
static __cpuinitdata int nr_warps;
@@ -113,13 +114,12 @@ void __cpuinit check_tsc_sync_source(int cpu)
return;
if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
- printk(KERN_INFO
- "Skipping synchronization checks as TSC is reliable.\n");
+ pr_info("Skipping synchronization checks as TSC is reliable.\n");
return;
}
- printk(KERN_INFO "checking TSC synchronization [CPU#%d -> CPU#%d]:",
- smp_processor_id(), cpu);
+ pr_info("checking TSC synchronization [CPU#%d -> CPU#%d]:",
+ smp_processor_id(), cpu);
/*
* Reset it - in case this is a second bootup:
@@ -143,8 +143,8 @@ void __cpuinit check_tsc_sync_source(int cpu)
if (nr_warps) {
printk("\n");
- printk(KERN_WARNING "Measured %Ld cycles TSC warp between CPUs,"
- " turning off TSC clock.\n", max_warp);
+ pr_warning("Measured %Ld cycles TSC warp between CPUs, "
+ "turning off TSC clock.\n", max_warp);
mark_tsc_unstable("check_tsc_sync_source failed");
} else {
printk(" passed.\n");
@@ -195,5 +195,3 @@ void __cpuinit check_tsc_sync_target(void)
while (atomic_read(&stop_count) != cpus)
cpu_relax();
}
-#undef NR_LOOPS
-
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index d7ac84e7fc1c..b8035a0f4048 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -318,9 +318,9 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
}
/*
- * Save old state, set default return value (%ax) to 0
+ * Save old state, set default return value (%ax) to 0 (VM86_SIGNAL)
*/
- info->regs32->ax = 0;
+ info->regs32->ax = VM86_SIGNAL;
tsk->thread.saved_sp0 = tsk->thread.sp0;
tsk->thread.saved_fs = info->regs32->fs;
tsk->thread.saved_gs = get_user_gs(info->regs32);
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
index 95deb9f2211e..b263423fbe2a 100644
--- a/arch/x86/kernel/vmi_32.c
+++ b/arch/x86/kernel/vmi_32.c
@@ -462,22 +462,28 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip,
}
#endif
-static void vmi_enter_lazy_cpu(void)
+static void vmi_start_context_switch(struct task_struct *prev)
{
- paravirt_enter_lazy_cpu();
+ paravirt_start_context_switch(prev);
vmi_ops.set_lazy_mode(2);
}
+static void vmi_end_context_switch(struct task_struct *next)
+{
+ vmi_ops.set_lazy_mode(0);
+ paravirt_end_context_switch(next);
+}
+
static void vmi_enter_lazy_mmu(void)
{
paravirt_enter_lazy_mmu();
vmi_ops.set_lazy_mode(1);
}
-static void vmi_leave_lazy(void)
+static void vmi_leave_lazy_mmu(void)
{
- paravirt_leave_lazy(paravirt_get_lazy_mode());
vmi_ops.set_lazy_mode(0);
+ paravirt_leave_lazy_mmu();
}
static inline int __init check_vmi_rom(struct vrom_header *rom)
@@ -711,14 +717,14 @@ static inline int __init activate_vmi(void)
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,
+ para_wrap(pv_cpu_ops.start_context_switch, vmi_start_context_switch,
set_lazy_mode, SetLazyMode);
- para_wrap(pv_cpu_ops.lazy_mode.leave, vmi_leave_lazy,
+ para_wrap(pv_cpu_ops.end_context_switch, vmi_end_context_switch,
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,
+ para_wrap(pv_mmu_ops.lazy_mode.leave, vmi_leave_lazy_mmu,
set_lazy_mode, SetLazyMode);
/* user and kernel flush are just handled with different flags to FlushTLB */
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 849ee611f013..367e87882041 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -1,5 +1,433 @@
+/*
+ * ld script for the x86 kernel
+ *
+ * Historic 32-bit version written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ * Modernisation, unification and other changes and fixes:
+ * Copyright (C) 2007-2009 Sam Ravnborg <sam@ravnborg.org>
+ *
+ *
+ * Don't define absolute symbols until and unless you know that symbol
+ * value is should remain constant even if kernel image is relocated
+ * at run time. Absolute symbols are not relocated. If symbol value should
+ * change if kernel is relocated, make the symbol section relative and
+ * put it inside the section definition.
+ */
+
#ifdef CONFIG_X86_32
-# include "vmlinux_32.lds.S"
+#define LOAD_OFFSET __PAGE_OFFSET
#else
-# include "vmlinux_64.lds.S"
+#define LOAD_OFFSET __START_KERNEL_map
#endif
+
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <asm/page_types.h>
+#include <asm/cache.h>
+#include <asm/boot.h>
+
+#undef i386 /* in case the preprocessor is a 32bit one */
+
+OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT)
+
+#ifdef CONFIG_X86_32
+OUTPUT_ARCH(i386)
+ENTRY(phys_startup_32)
+jiffies = jiffies_64;
+#else
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(phys_startup_64)
+jiffies_64 = jiffies;
+#endif
+
+PHDRS {
+ text PT_LOAD FLAGS(5); /* R_E */
+ data PT_LOAD FLAGS(7); /* RWE */
+#ifdef CONFIG_X86_64
+ user PT_LOAD FLAGS(7); /* RWE */
+ data.init PT_LOAD FLAGS(7); /* RWE */
+#ifdef CONFIG_SMP
+ percpu PT_LOAD FLAGS(7); /* RWE */
+#endif
+ data.init2 PT_LOAD FLAGS(7); /* RWE */
+#endif
+ note PT_NOTE FLAGS(0); /* ___ */
+}
+
+SECTIONS
+{
+#ifdef CONFIG_X86_32
+ . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
+ phys_startup_32 = startup_32 - LOAD_OFFSET;
+#else
+ . = __START_KERNEL;
+ phys_startup_64 = startup_64 - LOAD_OFFSET;
+#endif
+
+ /* Text and read-only data */
+
+ /* bootstrapping code */
+ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
+ _text = .;
+ *(.text.head)
+ } :text = 0x9090
+
+ /* The rest of the text */
+ .text : AT(ADDR(.text) - LOAD_OFFSET) {
+#ifdef CONFIG_X86_32
+ /* not really needed, already page aligned */
+ . = ALIGN(PAGE_SIZE);
+ *(.text.page_aligned)
+#endif
+ . = ALIGN(8);
+ _stext = .;
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
+ IRQENTRY_TEXT
+ *(.fixup)
+ *(.gnu.warning)
+ /* End of text section */
+ _etext = .;
+ } :text = 0x9090
+
+ NOTES :text :note
+
+ /* Exception table */
+ . = ALIGN(16);
+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+ } :text = 0x9090
+
+ RODATA
+
+ /* Data */
+ . = ALIGN(PAGE_SIZE);
+ .data : AT(ADDR(.data) - LOAD_OFFSET) {
+ /* Start of data section */
+ _sdata = .;
+ DATA_DATA
+ CONSTRUCTORS
+
+#ifdef CONFIG_X86_64
+ /* End of data section */
+ _edata = .;
+#endif
+ } :data
+
+#ifdef CONFIG_X86_32
+ /* 32 bit has nosave before _edata */
+ . = ALIGN(PAGE_SIZE);
+ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
+ __nosave_begin = .;
+ *(.data.nosave)
+ . = ALIGN(PAGE_SIZE);
+ __nosave_end = .;
+ }
+#endif
+
+ . = ALIGN(PAGE_SIZE);
+ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+ *(.data.page_aligned)
+ *(.data.idt)
+ }
+
+#ifdef CONFIG_X86_32
+ . = ALIGN(32);
+#else
+ . = ALIGN(PAGE_SIZE);
+ . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+#endif
+ .data.cacheline_aligned :
+ AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+ *(.data.cacheline_aligned)
+ }
+
+ /* rarely changed data like cpu maps */
+#ifdef CONFIG_X86_32
+ . = ALIGN(32);
+#else
+ . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
+#endif
+ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
+ *(.data.read_mostly)
+
+#ifdef CONFIG_X86_32
+ /* End of data section */
+ _edata = .;
+#endif
+ }
+
+#ifdef CONFIG_X86_64
+
+#define VSYSCALL_ADDR (-10*1024*1024)
+#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + \
+ SIZEOF(.data.read_mostly) + 4095) & ~(4095))
+#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + \
+ SIZEOF(.data.read_mostly) + 4095) & ~(4095))
+
+#define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
+#define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
+
+#define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR)
+#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
+
+ . = VSYSCALL_ADDR;
+ .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) {
+ *(.vsyscall_0)
+ } :user
+
+ __vsyscall_0 = VSYSCALL_VIRT_ADDR;
+
+ . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+ .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) {
+ *(.vsyscall_fn)
+ }
+
+ . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+ .vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data)) {
+ *(.vsyscall_gtod_data)
+ }
+
+ vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data);
+ .vsyscall_clock : AT(VLOAD(.vsyscall_clock)) {
+ *(.vsyscall_clock)
+ }
+ vsyscall_clock = VVIRT(.vsyscall_clock);
+
+
+ .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) {
+ *(.vsyscall_1)
+ }
+ .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) {
+ *(.vsyscall_2)
+ }
+
+ .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) {
+ *(.vgetcpu_mode)
+ }
+ vgetcpu_mode = VVIRT(.vgetcpu_mode);
+
+ . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+ .jiffies : AT(VLOAD(.jiffies)) {
+ *(.jiffies)
+ }
+ jiffies = VVIRT(.jiffies);
+
+ .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) {
+ *(.vsyscall_3)
+ }
+
+ . = VSYSCALL_VIRT_ADDR + PAGE_SIZE;
+
+#undef VSYSCALL_ADDR
+#undef VSYSCALL_PHYS_ADDR
+#undef VSYSCALL_VIRT_ADDR
+#undef VLOAD_OFFSET
+#undef VLOAD
+#undef VVIRT_OFFSET
+#undef VVIRT
+
+#endif /* CONFIG_X86_64 */
+
+ /* init_task */
+ . = ALIGN(THREAD_SIZE);
+ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+ *(.data.init_task)
+ }
+#ifdef CONFIG_X86_64
+ :data.init
+#endif
+
+ /*
+ * smp_locks might be freed after init
+ * start/end must be page aligned
+ */
+ . = ALIGN(PAGE_SIZE);
+ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
+ __smp_locks = .;
+ *(.smp_locks)
+ __smp_locks_end = .;
+ . = ALIGN(PAGE_SIZE);
+ }
+
+ /* Init code and data - will be freed after init */
+ . = ALIGN(PAGE_SIZE);
+ .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
+ __init_begin = .; /* paired with __init_end */
+ _sinittext = .;
+ INIT_TEXT
+ _einittext = .;
+ }
+
+ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
+ INIT_DATA
+ }
+
+ . = ALIGN(16);
+ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ }
+ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
+ __initcall_start = .;
+ INITCALLS
+ __initcall_end = .;
+ }
+
+ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ }
+
+ .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
+ __x86_cpu_dev_start = .;
+ *(.x86_cpu_dev.init)
+ __x86_cpu_dev_end = .;
+ }
+
+ SECURITY_INIT
+
+ . = ALIGN(8);
+ .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
+ __parainstructions = .;
+ *(.parainstructions)
+ __parainstructions_end = .;
+ }
+
+ . = ALIGN(8);
+ .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+ __alt_instructions = .;
+ *(.altinstructions)
+ __alt_instructions_end = .;
+ }
+
+ .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
+ *(.altinstr_replacement)
+ }
+
+ /*
+ * .exit.text is discard at runtime, not link time, to deal with
+ * references from .altinstructions and .eh_frame
+ */
+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
+ EXIT_TEXT
+ }
+
+ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
+ EXIT_DATA
+ }
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ . = ALIGN(PAGE_SIZE);
+ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ }
+#endif
+
+#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
+ /*
+ * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
+ * output PHDR, so the next output section - __data_nosave - should
+ * start another section data.init2. Also, pda should be at the head of
+ * percpu area. Preallocate it and define the percpu offset symbol
+ * so that it can be accessed as a percpu variable.
+ */
+ . = ALIGN(PAGE_SIZE);
+ PERCPU_VADDR(0, :percpu)
+#else
+ PERCPU(PAGE_SIZE)
+#endif
+
+ . = ALIGN(PAGE_SIZE);
+
+ /* freed after init ends here */
+ .init.end : AT(ADDR(.init.end) - LOAD_OFFSET) {
+ __init_end = .;
+ }
+
+#ifdef CONFIG_X86_64
+ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
+ . = ALIGN(PAGE_SIZE);
+ __nosave_begin = .;
+ *(.data.nosave)
+ . = ALIGN(PAGE_SIZE);
+ __nosave_end = .;
+ } :data.init2
+ /* use another section data.init2, see PERCPU_VADDR() above */
+#endif
+
+ /* BSS */
+ . = ALIGN(PAGE_SIZE);
+ .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
+ __bss_start = .;
+ *(.bss.page_aligned)
+ *(.bss)
+ . = ALIGN(4);
+ __bss_stop = .;
+ }
+
+ . = ALIGN(PAGE_SIZE);
+ .brk : AT(ADDR(.brk) - LOAD_OFFSET) {
+ __brk_base = .;
+ . += 64 * 1024; /* 64k alignment slop space */
+ *(.brk_reservation) /* areas brk users have reserved */
+ __brk_limit = .;
+ }
+
+ .end : AT(ADDR(.end) - LOAD_OFFSET) {
+ _end = .;
+ }
+
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.exitcall.exit)
+ *(.eh_frame)
+ *(.discard)
+ }
+
+ STABS_DEBUG
+ DWARF_DEBUG
+}
+
+
+#ifdef CONFIG_X86_32
+ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
+ "kernel image bigger than KERNEL_IMAGE_SIZE")
+#else
+/*
+ * Per-cpu symbols which need to be offset from __per_cpu_load
+ * for the boot processor.
+ */
+#define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load
+INIT_PER_CPU(gdt_page);
+INIT_PER_CPU(irq_stack_union);
+
+/*
+ * Build-time check on the image size:
+ */
+ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),
+ "kernel image bigger than KERNEL_IMAGE_SIZE")
+
+#ifdef CONFIG_SMP
+ASSERT((per_cpu__irq_stack_union == 0),
+ "irq_stack_union is not at start of per-cpu area");
+#endif
+
+#endif /* CONFIG_X86_32 */
+
+#ifdef CONFIG_KEXEC
+#include <asm/kexec.h>
+
+ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE,
+ "kexec control code size is too big")
+#endif
+
diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
deleted file mode 100644
index 62ad500d55f3..000000000000
--- a/arch/x86/kernel/vmlinux_32.lds.S
+++ /dev/null
@@ -1,229 +0,0 @@
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- *
- * Don't define absolute symbols until and unless you know that symbol
- * value is should remain constant even if kernel image is relocated
- * at run time. Absolute symbols are not relocated. If symbol value should
- * change if kernel is relocated, make the symbol section relative and
- * put it inside the section definition.
- */
-
-#define LOAD_OFFSET __PAGE_OFFSET
-
-#include <asm-generic/vmlinux.lds.h>
-#include <asm/thread_info.h>
-#include <asm/page_types.h>
-#include <asm/cache.h>
-#include <asm/boot.h>
-
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-ENTRY(phys_startup_32)
-jiffies = jiffies_64;
-
-PHDRS {
- text PT_LOAD FLAGS(5); /* R_E */
- data PT_LOAD FLAGS(7); /* RWE */
- note PT_NOTE FLAGS(0); /* ___ */
-}
-SECTIONS
-{
- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
- phys_startup_32 = startup_32 - LOAD_OFFSET;
-
- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
- _text = .; /* Text and read-only data */
- *(.text.head)
- } :text = 0x9090
-
- /* read-only */
- .text : AT(ADDR(.text) - LOAD_OFFSET) {
- . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
- *(.text.page_aligned)
- TEXT_TEXT
- SCHED_TEXT
- LOCK_TEXT
- KPROBES_TEXT
- IRQENTRY_TEXT
- *(.fixup)
- *(.gnu.warning)
- _etext = .; /* End of text section */
- } :text = 0x9090
-
- NOTES :text :note
-
- . = ALIGN(16); /* Exception table */
- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
- __start___ex_table = .;
- *(__ex_table)
- __stop___ex_table = .;
- } :text = 0x9090
-
- RODATA
-
- /* writeable */
- . = ALIGN(PAGE_SIZE);
- .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
- DATA_DATA
- CONSTRUCTORS
- } :data
-
- . = ALIGN(PAGE_SIZE);
- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
- __nosave_begin = .;
- *(.data.nosave)
- . = ALIGN(PAGE_SIZE);
- __nosave_end = .;
- }
-
- . = ALIGN(PAGE_SIZE);
- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
- *(.data.page_aligned)
- *(.data.idt)
- }
-
- . = ALIGN(32);
- .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
- *(.data.cacheline_aligned)
- }
-
- /* rarely changed data like cpu maps */
- . = ALIGN(32);
- .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
- *(.data.read_mostly)
- _edata = .; /* End of data section */
- }
-
- . = ALIGN(THREAD_SIZE); /* init_task */
- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
- *(.data.init_task)
- }
-
- /* might get freed after init */
- . = ALIGN(PAGE_SIZE);
- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
- __smp_locks = .;
- *(.smp_locks)
- __smp_locks_end = .;
- }
- /* will be freed after init
- * Following ALIGN() is required to make sure no other data falls on the
- * same page where __smp_alt_end is pointing as that page might be freed
- * after boot. Always make sure that ALIGN() directive is present after
- * the section which contains __smp_alt_end.
- */
- . = ALIGN(PAGE_SIZE);
-
- /* will be freed after init */
- . = ALIGN(PAGE_SIZE); /* Init code and data */
- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
- __init_begin = .;
- _sinittext = .;
- INIT_TEXT
- _einittext = .;
- }
- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
- INIT_DATA
- }
- . = ALIGN(16);
- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
- __setup_start = .;
- *(.init.setup)
- __setup_end = .;
- }
- .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
- __initcall_start = .;
- INITCALLS
- __initcall_end = .;
- }
- .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
- __con_initcall_start = .;
- *(.con_initcall.init)
- __con_initcall_end = .;
- }
- .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
- __x86_cpu_dev_start = .;
- *(.x86_cpu_dev.init)
- __x86_cpu_dev_end = .;
- }
- SECURITY_INIT
- . = ALIGN(4);
- .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
- __alt_instructions = .;
- *(.altinstructions)
- __alt_instructions_end = .;
- }
- .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
- *(.altinstr_replacement)
- }
- . = ALIGN(4);
- .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
- __parainstructions = .;
- *(.parainstructions)
- __parainstructions_end = .;
- }
- /* .exit.text is discard at runtime, not link time, to deal with references
- from .altinstructions and .eh_frame */
- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
- EXIT_TEXT
- }
- .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
- EXIT_DATA
- }
-#if defined(CONFIG_BLK_DEV_INITRD)
- . = ALIGN(PAGE_SIZE);
- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
- __initramfs_start = .;
- *(.init.ramfs)
- __initramfs_end = .;
- }
-#endif
- PERCPU(PAGE_SIZE)
- . = ALIGN(PAGE_SIZE);
- /* freed after init ends here */
-
- .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
- __init_end = .;
- __bss_start = .; /* BSS */
- *(.bss.page_aligned)
- *(.bss)
- . = ALIGN(4);
- __bss_stop = .;
- }
-
- .brk : AT(ADDR(.brk) - LOAD_OFFSET) {
- . = ALIGN(PAGE_SIZE);
- __brk_base = . ;
- . += 64 * 1024 ; /* 64k alignment slop space */
- *(.brk_reservation) /* areas brk users have reserved */
- __brk_limit = . ;
- }
-
- .end : AT(ADDR(.end) - LOAD_OFFSET) {
- _end = . ;
- }
-
- /* Sections to be discarded */
- /DISCARD/ : {
- *(.exitcall.exit)
- *(.discard)
- }
-
- STABS_DEBUG
-
- DWARF_DEBUG
-}
-
-/*
- * Build-time check on the image size:
- */
-ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
- "kernel image bigger than KERNEL_IMAGE_SIZE")
-
-#ifdef CONFIG_KEXEC
-/* Link time checks */
-#include <asm/kexec.h>
-
-ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE,
- "kexec control code size is too big")
-#endif
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
deleted file mode 100644
index c8742507b030..000000000000
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ /dev/null
@@ -1,298 +0,0 @@
-/* ld script to make x86-64 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-
-#define LOAD_OFFSET __START_KERNEL_map
-
-#include <asm-generic/vmlinux.lds.h>
-#include <asm/asm-offsets.h>
-#include <asm/page_types.h>
-
-#undef i386 /* in case the preprocessor is a 32bit one */
-
-OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
-OUTPUT_ARCH(i386:x86-64)
-ENTRY(phys_startup_64)
-jiffies_64 = jiffies;
-PHDRS {
- text PT_LOAD FLAGS(5); /* R_E */
- data PT_LOAD FLAGS(7); /* RWE */
- user PT_LOAD FLAGS(7); /* RWE */
- data.init PT_LOAD FLAGS(7); /* RWE */
-#ifdef CONFIG_SMP
- percpu PT_LOAD FLAGS(7); /* RWE */
-#endif
- data.init2 PT_LOAD FLAGS(7); /* RWE */
- note PT_NOTE FLAGS(0); /* ___ */
-}
-SECTIONS
-{
- . = __START_KERNEL;
- phys_startup_64 = startup_64 - LOAD_OFFSET;
- .text : AT(ADDR(.text) - LOAD_OFFSET) {
- _text = .; /* Text and read-only data */
- /* First the code that has to be first for bootstrapping */
- *(.text.head)
- _stext = .;
- /* Then the rest */
- TEXT_TEXT
- SCHED_TEXT
- LOCK_TEXT
- KPROBES_TEXT
- IRQENTRY_TEXT
- *(.fixup)
- *(.gnu.warning)
- _etext = .; /* End of text section */
- } :text = 0x9090
-
- NOTES :text :note
-
- . = ALIGN(16); /* Exception table */
- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
- __start___ex_table = .;
- *(__ex_table)
- __stop___ex_table = .;
- } :text = 0x9090
-
- RODATA
-
- . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
- /* Data */
- .data : AT(ADDR(.data) - LOAD_OFFSET) {
- DATA_DATA
- CONSTRUCTORS
- _edata = .; /* End of data section */
- } :data
-
-
- .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
- . = ALIGN(PAGE_SIZE);
- . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
- *(.data.cacheline_aligned)
- }
- . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
- .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
- *(.data.read_mostly)
- }
-
-#define VSYSCALL_ADDR (-10*1024*1024)
-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
-
-#define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
-#define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
-
-#define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR)
-#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
-
- . = VSYSCALL_ADDR;
- .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } :user
- __vsyscall_0 = VSYSCALL_VIRT_ADDR;
-
- . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
- .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) { *(.vsyscall_fn) }
- . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
- .vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data))
- { *(.vsyscall_gtod_data) }
- vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data);
- .vsyscall_clock : AT(VLOAD(.vsyscall_clock))
- { *(.vsyscall_clock) }
- vsyscall_clock = VVIRT(.vsyscall_clock);
-
-
- .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1))
- { *(.vsyscall_1) }
- .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2))
- { *(.vsyscall_2) }
-
- .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) }
- vgetcpu_mode = VVIRT(.vgetcpu_mode);
-
- . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
- .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) }
- jiffies = VVIRT(.jiffies);
-
- .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3))
- { *(.vsyscall_3) }
-
- . = VSYSCALL_VIRT_ADDR + PAGE_SIZE;
-
-#undef VSYSCALL_ADDR
-#undef VSYSCALL_PHYS_ADDR
-#undef VSYSCALL_VIRT_ADDR
-#undef VLOAD_OFFSET
-#undef VLOAD
-#undef VVIRT_OFFSET
-#undef VVIRT
-
- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
- . = ALIGN(THREAD_SIZE); /* init_task */
- *(.data.init_task)
- }:data.init
-
- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
- . = ALIGN(PAGE_SIZE);
- *(.data.page_aligned)
- }
-
- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
- /* might get freed after init */
- . = ALIGN(PAGE_SIZE);
- __smp_alt_begin = .;
- __smp_locks = .;
- *(.smp_locks)
- __smp_locks_end = .;
- . = ALIGN(PAGE_SIZE);
- __smp_alt_end = .;
- }
-
- . = ALIGN(PAGE_SIZE); /* Init code and data */
- __init_begin = .; /* paired with __init_end */
- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
- _sinittext = .;
- INIT_TEXT
- _einittext = .;
- }
- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
- __initdata_begin = .;
- INIT_DATA
- __initdata_end = .;
- }
-
- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
- . = ALIGN(16);
- __setup_start = .;
- *(.init.setup)
- __setup_end = .;
- }
- .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
- __initcall_start = .;
- INITCALLS
- __initcall_end = .;
- }
- .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
- __con_initcall_start = .;
- *(.con_initcall.init)
- __con_initcall_end = .;
- }
- .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
- __x86_cpu_dev_start = .;
- *(.x86_cpu_dev.init)
- __x86_cpu_dev_end = .;
- }
- SECURITY_INIT
-
- . = ALIGN(8);
- .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
- __parainstructions = .;
- *(.parainstructions)
- __parainstructions_end = .;
- }
-
- .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
- . = ALIGN(8);
- __alt_instructions = .;
- *(.altinstructions)
- __alt_instructions_end = .;
- }
- .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
- *(.altinstr_replacement)
- }
- /* .exit.text is discard at runtime, not link time, to deal with references
- from .altinstructions and .eh_frame */
- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
- EXIT_TEXT
- }
- .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
- EXIT_DATA
- }
-
-#ifdef CONFIG_BLK_DEV_INITRD
- . = ALIGN(PAGE_SIZE);
- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
- __initramfs_start = .;
- *(.init.ramfs)
- __initramfs_end = .;
- }
-#endif
-
-#ifdef CONFIG_SMP
- /*
- * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
- * output PHDR, so the next output section - __data_nosave - should
- * start another section data.init2. Also, pda should be at the head of
- * percpu area. Preallocate it and define the percpu offset symbol
- * so that it can be accessed as a percpu variable.
- */
- . = ALIGN(PAGE_SIZE);
- PERCPU_VADDR(0, :percpu)
-#else
- PERCPU(PAGE_SIZE)
-#endif
-
- . = ALIGN(PAGE_SIZE);
- __init_end = .;
-
- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
- . = ALIGN(PAGE_SIZE);
- __nosave_begin = .;
- *(.data.nosave)
- . = ALIGN(PAGE_SIZE);
- __nosave_end = .;
- } :data.init2 /* use another section data.init2, see PERCPU_VADDR() above */
-
- .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
- . = ALIGN(PAGE_SIZE);
- __bss_start = .; /* BSS */
- *(.bss.page_aligned)
- *(.bss)
- __bss_stop = .;
- }
-
- .brk : AT(ADDR(.brk) - LOAD_OFFSET) {
- . = ALIGN(PAGE_SIZE);
- __brk_base = . ;
- . += 64 * 1024 ; /* 64k alignment slop space */
- *(.brk_reservation) /* areas brk users have reserved */
- __brk_limit = . ;
- }
-
- _end = . ;
-
- /* Sections to be discarded */
- /DISCARD/ : {
- *(.exitcall.exit)
- *(.eh_frame)
- *(.discard)
- }
-
- STABS_DEBUG
-
- DWARF_DEBUG
-}
-
- /*
- * Per-cpu symbols which need to be offset from __per_cpu_load
- * for the boot processor.
- */
-#define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load
-INIT_PER_CPU(gdt_page);
-INIT_PER_CPU(irq_stack_union);
-
-/*
- * Build-time check on the image size:
- */
-ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),
- "kernel image bigger than KERNEL_IMAGE_SIZE")
-
-#ifdef CONFIG_SMP
-ASSERT((per_cpu__irq_stack_union == 0),
- "irq_stack_union is not at start of per-cpu area");
-#endif
-
-#ifdef CONFIG_KEXEC
-#include <asm/kexec.h>
-
-ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE,
- "kexec control code size is too big")
-#endif
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index d3ec292f00f2..b43c4efafe80 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -14,7 +14,7 @@ endif
EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm
kvm-objs := $(common-objs) x86.o mmu.o x86_emulate.o i8259.o irq.o lapic.o \
- i8254.o
+ i8254.o timer.o
obj-$(CONFIG_KVM) += kvm.o
kvm-intel-objs = vmx.o
obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index c13bb92d3157..4d6f0d293ee2 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -98,6 +98,37 @@ static int pit_get_gate(struct kvm *kvm, int channel)
return kvm->arch.vpit->pit_state.channels[channel].gate;
}
+static s64 __kpit_elapsed(struct kvm *kvm)
+{
+ s64 elapsed;
+ ktime_t remaining;
+ struct kvm_kpit_state *ps = &kvm->arch.vpit->pit_state;
+
+ /*
+ * The Counter does not stop when it reaches zero. In
+ * Modes 0, 1, 4, and 5 the Counter ``wraps around'' to
+ * the highest count, either FFFF hex for binary counting
+ * or 9999 for BCD counting, and continues counting.
+ * Modes 2 and 3 are periodic; the Counter reloads
+ * itself with the initial count and continues counting
+ * from there.
+ */
+ remaining = hrtimer_expires_remaining(&ps->pit_timer.timer);
+ elapsed = ps->pit_timer.period - ktime_to_ns(remaining);
+ elapsed = mod_64(elapsed, ps->pit_timer.period);
+
+ return elapsed;
+}
+
+static s64 kpit_elapsed(struct kvm *kvm, struct kvm_kpit_channel_state *c,
+ int channel)
+{
+ if (channel == 0)
+ return __kpit_elapsed(kvm);
+
+ return ktime_to_ns(ktime_sub(ktime_get(), c->count_load_time));
+}
+
static int pit_get_count(struct kvm *kvm, int channel)
{
struct kvm_kpit_channel_state *c =
@@ -107,7 +138,7 @@ static int pit_get_count(struct kvm *kvm, int channel)
WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
- t = ktime_to_ns(ktime_sub(ktime_get(), c->count_load_time));
+ t = kpit_elapsed(kvm, c, channel);
d = muldiv64(t, KVM_PIT_FREQ, NSEC_PER_SEC);
switch (c->mode) {
@@ -137,7 +168,7 @@ static int pit_get_out(struct kvm *kvm, int channel)
WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
- t = ktime_to_ns(ktime_sub(ktime_get(), c->count_load_time));
+ t = kpit_elapsed(kvm, c, channel);
d = muldiv64(t, KVM_PIT_FREQ, NSEC_PER_SEC);
switch (c->mode) {
@@ -193,28 +224,6 @@ static void pit_latch_status(struct kvm *kvm, int channel)
}
}
-static int __pit_timer_fn(struct kvm_kpit_state *ps)
-{
- struct kvm_vcpu *vcpu0 = ps->pit->kvm->vcpus[0];
- struct kvm_kpit_timer *pt = &ps->pit_timer;
-
- if (!atomic_inc_and_test(&pt->pending))
- set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests);
-
- if (!pt->reinject)
- atomic_set(&pt->pending, 1);
-
- if (vcpu0 && waitqueue_active(&vcpu0->wq))
- wake_up_interruptible(&vcpu0->wq);
-
- hrtimer_add_expires_ns(&pt->timer, pt->period);
- pt->scheduled = hrtimer_get_expires_ns(&pt->timer);
- if (pt->period)
- ps->channels[0].count_load_time = ktime_get();
-
- return (pt->period == 0 ? 0 : 1);
-}
-
int pit_has_pending_timer(struct kvm_vcpu *vcpu)
{
struct kvm_pit *pit = vcpu->kvm->arch.vpit;
@@ -235,21 +244,6 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
spin_unlock(&ps->inject_lock);
}
-static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
-{
- struct kvm_kpit_state *ps;
- int restart_timer = 0;
-
- ps = container_of(data, struct kvm_kpit_state, pit_timer.timer);
-
- restart_timer = __pit_timer_fn(ps);
-
- if (restart_timer)
- return HRTIMER_RESTART;
- else
- return HRTIMER_NORESTART;
-}
-
void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
{
struct kvm_pit *pit = vcpu->kvm->arch.vpit;
@@ -263,15 +257,26 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
}
-static void destroy_pit_timer(struct kvm_kpit_timer *pt)
+static void destroy_pit_timer(struct kvm_timer *pt)
{
pr_debug("pit: execute del timer!\n");
hrtimer_cancel(&pt->timer);
}
+static bool kpit_is_periodic(struct kvm_timer *ktimer)
+{
+ struct kvm_kpit_state *ps = container_of(ktimer, struct kvm_kpit_state,
+ pit_timer);
+ return ps->is_periodic;
+}
+
+static struct kvm_timer_ops kpit_ops = {
+ .is_periodic = kpit_is_periodic,
+};
+
static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
{
- struct kvm_kpit_timer *pt = &ps->pit_timer;
+ struct kvm_timer *pt = &ps->pit_timer;
s64 interval;
interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ);
@@ -280,8 +285,14 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
/* TODO The new value only affected after the retriggered */
hrtimer_cancel(&pt->timer);
- pt->period = (is_period == 0) ? 0 : interval;
- pt->timer.function = pit_timer_fn;
+ pt->period = interval;
+ ps->is_periodic = is_period;
+
+ pt->timer.function = kvm_timer_fn;
+ pt->t_ops = &kpit_ops;
+ pt->kvm = ps->pit->kvm;
+ pt->vcpu_id = 0;
+
atomic_set(&pt->pending, 0);
ps->irq_ack = 1;
@@ -298,23 +309,23 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
pr_debug("pit: load_count val is %d, channel is %d\n", val, channel);
/*
- * Though spec said the state of 8254 is undefined after power-up,
- * seems some tricky OS like Windows XP depends on IRQ0 interrupt
- * when booting up.
- * So here setting initialize rate for it, and not a specific number
+ * The largest possible initial count is 0; this is equivalent
+ * to 216 for binary counting and 104 for BCD counting.
*/
if (val == 0)
val = 0x10000;
- ps->channels[channel].count_load_time = ktime_get();
ps->channels[channel].count = val;
- if (channel != 0)
+ if (channel != 0) {
+ ps->channels[channel].count_load_time = ktime_get();
return;
+ }
/* Two types of timer
* mode 1 is one shot, mode 2 is period, otherwise del timer */
switch (ps->channels[0].mode) {
+ case 0:
case 1:
/* FIXME: enhance mode 4 precision */
case 4:
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index 6acbe4b505d5..bbd863ff60b7 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -3,15 +3,6 @@
#include "iodev.h"
-struct kvm_kpit_timer {
- struct hrtimer timer;
- int irq;
- s64 period; /* unit: ns */
- s64 scheduled;
- atomic_t pending;
- bool reinject;
-};
-
struct kvm_kpit_channel_state {
u32 count; /* can be 65536 */
u16 latched_count;
@@ -30,7 +21,8 @@ struct kvm_kpit_channel_state {
struct kvm_kpit_state {
struct kvm_kpit_channel_state channels[3];
- struct kvm_kpit_timer pit_timer;
+ struct kvm_timer pit_timer;
+ bool is_periodic;
u32 speaker_data_on;
struct mutex lock;
struct kvm_pit *pit;
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
index cf17ed52f6fb..11c2757b808f 100644
--- a/arch/x86/kvm/irq.c
+++ b/arch/x86/kvm/irq.c
@@ -24,6 +24,7 @@
#include "irq.h"
#include "i8254.h"
+#include "x86.h"
/*
* check if there are pending timer events
@@ -48,6 +49,9 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
{
struct kvm_pic *s;
+ if (!irqchip_in_kernel(v->kvm))
+ return v->arch.irq_summary;
+
if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */
if (kvm_apic_accept_pic_intr(v)) {
s = pic_irqchip(v->kvm); /* PIC */
@@ -67,6 +71,9 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
struct kvm_pic *s;
int vector;
+ if (!irqchip_in_kernel(v->kvm))
+ return kvm_pop_irq(v);
+
vector = kvm_get_apic_interrupt(v); /* APIC */
if (vector == -1) {
if (kvm_apic_accept_pic_intr(v)) {
diff --git a/arch/x86/kvm/kvm_timer.h b/arch/x86/kvm/kvm_timer.h
new file mode 100644
index 000000000000..26bd6ba74e1c
--- /dev/null
+++ b/arch/x86/kvm/kvm_timer.h
@@ -0,0 +1,18 @@
+
+struct kvm_timer {
+ struct hrtimer timer;
+ s64 period; /* unit: ns */
+ atomic_t pending; /* accumulated triggered timers */
+ bool reinject;
+ struct kvm_timer_ops *t_ops;
+ struct kvm *kvm;
+ int vcpu_id;
+};
+
+struct kvm_timer_ops {
+ bool (*is_periodic)(struct kvm_timer *);
+};
+
+
+enum hrtimer_restart kvm_timer_fn(struct hrtimer *data);
+
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index f0b67f2cdd69..ae99d83f81a3 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -196,20 +196,15 @@ int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr);
-int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig)
+static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
+ int vector, int level, int trig_mode);
+
+int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!apic_test_and_set_irr(vec, apic)) {
- /* a new pending irq is set in IRR */
- if (trig)
- apic_set_vector(vec, apic->regs + APIC_TMR);
- else
- apic_clear_vector(vec, apic->regs + APIC_TMR);
- kvm_vcpu_kick(apic->vcpu);
- return 1;
- }
- return 0;
+ return __apic_accept_irq(apic, irq->delivery_mode, irq->vector,
+ irq->level, irq->trig_mode);
}
static inline int apic_find_highest_isr(struct kvm_lapic *apic)
@@ -250,7 +245,7 @@ static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr)
int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest)
{
- return kvm_apic_id(apic) == dest;
+ return dest == 0xff || kvm_apic_id(apic) == dest;
}
int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
@@ -279,37 +274,34 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
return result;
}
-static int apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
+int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
int short_hand, int dest, int dest_mode)
{
int result = 0;
struct kvm_lapic *target = vcpu->arch.apic;
apic_debug("target %p, source %p, dest 0x%x, "
- "dest_mode 0x%x, short_hand 0x%x",
+ "dest_mode 0x%x, short_hand 0x%x\n",
target, source, dest, dest_mode, short_hand);
ASSERT(!target);
switch (short_hand) {
case APIC_DEST_NOSHORT:
- if (dest_mode == 0) {
+ if (dest_mode == 0)
/* Physical mode. */
- if ((dest == 0xFF) || (dest == kvm_apic_id(target)))
- result = 1;
- } else
+ result = kvm_apic_match_physical_addr(target, dest);
+ else
/* Logical mode. */
result = kvm_apic_match_logical_addr(target, dest);
break;
case APIC_DEST_SELF:
- if (target == source)
- result = 1;
+ result = (target == source);
break;
case APIC_DEST_ALLINC:
result = 1;
break;
case APIC_DEST_ALLBUT:
- if (target != source)
- result = 1;
+ result = (target != source);
break;
default:
printk(KERN_WARNING "Bad dest shorthand value %x\n",
@@ -327,20 +319,22 @@ static int apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
int vector, int level, int trig_mode)
{
- int orig_irr, result = 0;
+ int result = 0;
struct kvm_vcpu *vcpu = apic->vcpu;
switch (delivery_mode) {
- case APIC_DM_FIXED:
case APIC_DM_LOWEST:
+ vcpu->arch.apic_arb_prio++;
+ case APIC_DM_FIXED:
/* FIXME add logic for vcpu on reset */
if (unlikely(!apic_enabled(apic)))
break;
- orig_irr = apic_test_and_set_irr(vector, apic);
- if (orig_irr && trig_mode) {
- apic_debug("level trig mode repeatedly for vector %d",
- vector);
+ result = !apic_test_and_set_irr(vector, apic);
+ if (!result) {
+ if (trig_mode)
+ apic_debug("level trig mode repeatedly for "
+ "vector %d", vector);
break;
}
@@ -349,10 +343,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
apic_set_vector(vector, apic->regs + APIC_TMR);
} else
apic_clear_vector(vector, apic->regs + APIC_TMR);
-
kvm_vcpu_kick(vcpu);
-
- result = (orig_irr == 0);
break;
case APIC_DM_REMRD:
@@ -364,12 +355,14 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
break;
case APIC_DM_NMI:
+ result = 1;
kvm_inject_nmi(vcpu);
kvm_vcpu_kick(vcpu);
break;
case APIC_DM_INIT:
if (level) {
+ result = 1;
if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE)
printk(KERN_DEBUG
"INIT on a runnable vcpu %d\n",
@@ -386,6 +379,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
apic_debug("SIPI to vcpu %d vector 0x%02x\n",
vcpu->vcpu_id, vector);
if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) {
+ result = 1;
vcpu->arch.sipi_vector = vector;
vcpu->arch.mp_state = KVM_MP_STATE_SIPI_RECEIVED;
kvm_vcpu_kick(vcpu);
@@ -408,43 +402,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
return result;
}
-static struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector,
- unsigned long bitmap)
-{
- int last;
- int next;
- struct kvm_lapic *apic = NULL;
-
- last = kvm->arch.round_robin_prev_vcpu;
- next = last;
-
- do {
- if (++next == KVM_MAX_VCPUS)
- next = 0;
- if (kvm->vcpus[next] == NULL || !test_bit(next, &bitmap))
- continue;
- apic = kvm->vcpus[next]->arch.apic;
- if (apic && apic_enabled(apic))
- break;
- apic = NULL;
- } while (next != last);
- kvm->arch.round_robin_prev_vcpu = next;
-
- if (!apic)
- printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n");
-
- return apic;
-}
-
-struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
- unsigned long bitmap)
+int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2)
{
- struct kvm_lapic *apic;
-
- apic = kvm_apic_round_robin(kvm, vector, bitmap);
- if (apic)
- return apic->vcpu;
- return NULL;
+ return vcpu1->arch.apic_arb_prio - vcpu2->arch.apic_arb_prio;
}
static void apic_set_eoi(struct kvm_lapic *apic)
@@ -472,47 +432,24 @@ static void apic_send_ipi(struct kvm_lapic *apic)
{
u32 icr_low = apic_get_reg(apic, APIC_ICR);
u32 icr_high = apic_get_reg(apic, APIC_ICR2);
+ struct kvm_lapic_irq irq;
- unsigned int dest = GET_APIC_DEST_FIELD(icr_high);
- unsigned int short_hand = icr_low & APIC_SHORT_MASK;
- unsigned int trig_mode = icr_low & APIC_INT_LEVELTRIG;
- unsigned int level = icr_low & APIC_INT_ASSERT;
- unsigned int dest_mode = icr_low & APIC_DEST_MASK;
- unsigned int delivery_mode = icr_low & APIC_MODE_MASK;
- unsigned int vector = icr_low & APIC_VECTOR_MASK;
-
- struct kvm_vcpu *target;
- struct kvm_vcpu *vcpu;
- unsigned long lpr_map = 0;
- int i;
+ irq.vector = icr_low & APIC_VECTOR_MASK;
+ irq.delivery_mode = icr_low & APIC_MODE_MASK;
+ irq.dest_mode = icr_low & APIC_DEST_MASK;
+ irq.level = icr_low & APIC_INT_ASSERT;
+ irq.trig_mode = icr_low & APIC_INT_LEVELTRIG;
+ irq.shorthand = icr_low & APIC_SHORT_MASK;
+ irq.dest_id = GET_APIC_DEST_FIELD(icr_high);
apic_debug("icr_high 0x%x, icr_low 0x%x, "
"short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
"dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n",
- icr_high, icr_low, short_hand, dest,
- trig_mode, level, dest_mode, delivery_mode, vector);
-
- for (i = 0; i < KVM_MAX_VCPUS; i++) {
- vcpu = apic->vcpu->kvm->vcpus[i];
- if (!vcpu)
- continue;
-
- if (vcpu->arch.apic &&
- apic_match_dest(vcpu, apic, short_hand, dest, dest_mode)) {
- if (delivery_mode == APIC_DM_LOWEST)
- set_bit(vcpu->vcpu_id, &lpr_map);
- else
- __apic_accept_irq(vcpu->arch.apic, delivery_mode,
- vector, level, trig_mode);
- }
- }
+ icr_high, icr_low, irq.shorthand, irq.dest_id,
+ irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode,
+ irq.vector);
- if (delivery_mode == APIC_DM_LOWEST) {
- target = kvm_get_lowest_prio_vcpu(vcpu->kvm, vector, lpr_map);
- if (target != NULL)
- __apic_accept_irq(target->arch.apic, delivery_mode,
- vector, level, trig_mode);
- }
+ kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq);
}
static u32 apic_get_tmcct(struct kvm_lapic *apic)
@@ -527,12 +464,13 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
if (apic_get_reg(apic, APIC_TMICT) == 0)
return 0;
- remaining = hrtimer_expires_remaining(&apic->timer.dev);
+ remaining = hrtimer_expires_remaining(&apic->lapic_timer.timer);
if (ktime_to_ns(remaining) < 0)
remaining = ktime_set(0, 0);
- ns = mod_64(ktime_to_ns(remaining), apic->timer.period);
- tmcct = div64_u64(ns, (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
+ ns = mod_64(ktime_to_ns(remaining), apic->lapic_timer.period);
+ tmcct = div64_u64(ns,
+ (APIC_BUS_CYCLE_NS * apic->divide_count));
return tmcct;
}
@@ -619,25 +557,25 @@ static void update_divide_count(struct kvm_lapic *apic)
tdcr = apic_get_reg(apic, APIC_TDCR);
tmp1 = tdcr & 0xf;
tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1;
- apic->timer.divide_count = 0x1 << (tmp2 & 0x7);
+ apic->divide_count = 0x1 << (tmp2 & 0x7);
apic_debug("timer divide count is 0x%x\n",
- apic->timer.divide_count);
+ apic->divide_count);
}
static void start_apic_timer(struct kvm_lapic *apic)
{
- ktime_t now = apic->timer.dev.base->get_time();
+ ktime_t now = apic->lapic_timer.timer.base->get_time();
- apic->timer.period = apic_get_reg(apic, APIC_TMICT) *
- APIC_BUS_CYCLE_NS * apic->timer.divide_count;
- atomic_set(&apic->timer.pending, 0);
+ apic->lapic_timer.period = apic_get_reg(apic, APIC_TMICT) *
+ APIC_BUS_CYCLE_NS * apic->divide_count;
+ atomic_set(&apic->lapic_timer.pending, 0);
- if (!apic->timer.period)
+ if (!apic->lapic_timer.period)
return;
- hrtimer_start(&apic->timer.dev,
- ktime_add_ns(now, apic->timer.period),
+ hrtimer_start(&apic->lapic_timer.timer,
+ ktime_add_ns(now, apic->lapic_timer.period),
HRTIMER_MODE_ABS);
apic_debug("%s: bus cycle is %" PRId64 "ns, now 0x%016"
@@ -646,9 +584,9 @@ static void start_apic_timer(struct kvm_lapic *apic)
"expire @ 0x%016" PRIx64 ".\n", __func__,
APIC_BUS_CYCLE_NS, ktime_to_ns(now),
apic_get_reg(apic, APIC_TMICT),
- apic->timer.period,
+ apic->lapic_timer.period,
ktime_to_ns(ktime_add_ns(now,
- apic->timer.period)));
+ apic->lapic_timer.period)));
}
static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
@@ -730,7 +668,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
apic_set_reg(apic, APIC_LVTT + 0x10 * i,
lvt_val | APIC_LVT_MASKED);
}
- atomic_set(&apic->timer.pending, 0);
+ atomic_set(&apic->lapic_timer.pending, 0);
}
break;
@@ -762,7 +700,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
break;
case APIC_TMICT:
- hrtimer_cancel(&apic->timer.dev);
+ hrtimer_cancel(&apic->lapic_timer.timer);
apic_set_reg(apic, APIC_TMICT, val);
start_apic_timer(apic);
return;
@@ -802,7 +740,7 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu)
if (!vcpu->arch.apic)
return;
- hrtimer_cancel(&vcpu->arch.apic->timer.dev);
+ hrtimer_cancel(&vcpu->arch.apic->lapic_timer.timer);
if (vcpu->arch.apic->regs_page)
__free_page(vcpu->arch.apic->regs_page);
@@ -880,7 +818,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
ASSERT(apic != NULL);
/* Stop the timer in case it's a reset to an active apic */
- hrtimer_cancel(&apic->timer.dev);
+ hrtimer_cancel(&apic->lapic_timer.timer);
apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24);
apic_set_reg(apic, APIC_LVR, APIC_VERSION);
@@ -905,11 +843,13 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
}
update_divide_count(apic);
- atomic_set(&apic->timer.pending, 0);
+ atomic_set(&apic->lapic_timer.pending, 0);
if (vcpu->vcpu_id == 0)
vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP;
apic_update_ppr(apic);
+ vcpu->arch.apic_arb_prio = 0;
+
apic_debug(KERN_INFO "%s: vcpu=%p, id=%d, base_msr="
"0x%016" PRIx64 ", base_address=0x%0lx.\n", __func__,
vcpu, kvm_apic_id(apic),
@@ -917,16 +857,14 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_lapic_reset);
-int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
+bool kvm_apic_present(struct kvm_vcpu *vcpu)
{
- struct kvm_lapic *apic = vcpu->arch.apic;
- int ret = 0;
-
- if (!apic)
- return 0;
- ret = apic_enabled(apic);
+ return vcpu->arch.apic && apic_hw_enabled(vcpu->arch.apic);
+}
- return ret;
+int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
+{
+ return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic);
}
EXPORT_SYMBOL_GPL(kvm_lapic_enabled);
@@ -936,22 +874,11 @@ EXPORT_SYMBOL_GPL(kvm_lapic_enabled);
*----------------------------------------------------------------------
*/
-/* TODO: make sure __apic_timer_fn runs in current pCPU */
-static int __apic_timer_fn(struct kvm_lapic *apic)
+static bool lapic_is_periodic(struct kvm_timer *ktimer)
{
- int result = 0;
- wait_queue_head_t *q = &apic->vcpu->wq;
-
- if(!atomic_inc_and_test(&apic->timer.pending))
- set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests);
- if (waitqueue_active(q))
- wake_up_interruptible(q);
-
- if (apic_lvtt_period(apic)) {
- result = 1;
- hrtimer_add_expires_ns(&apic->timer.dev, apic->timer.period);
- }
- return result;
+ struct kvm_lapic *apic = container_of(ktimer, struct kvm_lapic,
+ lapic_timer);
+ return apic_lvtt_period(apic);
}
int apic_has_pending_timer(struct kvm_vcpu *vcpu)
@@ -959,7 +886,7 @@ int apic_has_pending_timer(struct kvm_vcpu *vcpu)
struct kvm_lapic *lapic = vcpu->arch.apic;
if (lapic && apic_enabled(lapic) && apic_lvt_enabled(lapic, APIC_LVTT))
- return atomic_read(&lapic->timer.pending);
+ return atomic_read(&lapic->lapic_timer.pending);
return 0;
}
@@ -986,20 +913,9 @@ void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu)
kvm_apic_local_deliver(apic, APIC_LVT0);
}
-static enum hrtimer_restart apic_timer_fn(struct hrtimer *data)
-{
- struct kvm_lapic *apic;
- int restart_timer = 0;
-
- apic = container_of(data, struct kvm_lapic, timer.dev);
-
- restart_timer = __apic_timer_fn(apic);
-
- if (restart_timer)
- return HRTIMER_RESTART;
- else
- return HRTIMER_NORESTART;
-}
+static struct kvm_timer_ops lapic_timer_ops = {
+ .is_periodic = lapic_is_periodic,
+};
int kvm_create_lapic(struct kvm_vcpu *vcpu)
{
@@ -1024,8 +940,13 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
memset(apic->regs, 0, PAGE_SIZE);
apic->vcpu = vcpu;
- hrtimer_init(&apic->timer.dev, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
- apic->timer.dev.function = apic_timer_fn;
+ hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_ABS);
+ apic->lapic_timer.timer.function = kvm_timer_fn;
+ apic->lapic_timer.t_ops = &lapic_timer_ops;
+ apic->lapic_timer.kvm = vcpu->kvm;
+ apic->lapic_timer.vcpu_id = vcpu->vcpu_id;
+
apic->base_address = APIC_DEFAULT_PHYS_BASE;
vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE;
@@ -1078,9 +999,9 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (apic && atomic_read(&apic->timer.pending) > 0) {
+ if (apic && atomic_read(&apic->lapic_timer.pending) > 0) {
if (kvm_apic_local_deliver(apic, APIC_LVTT))
- atomic_dec(&apic->timer.pending);
+ atomic_dec(&apic->lapic_timer.pending);
}
}
@@ -1106,7 +1027,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
MSR_IA32_APICBASE_BASE;
apic_set_reg(apic, APIC_LVR, APIC_VERSION);
apic_update_ppr(apic);
- hrtimer_cancel(&apic->timer.dev);
+ hrtimer_cancel(&apic->lapic_timer.timer);
update_divide_count(apic);
start_apic_timer(apic);
}
@@ -1119,7 +1040,7 @@ void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
if (!apic)
return;
- timer = &apic->timer.dev;
+ timer = &apic->lapic_timer.timer;
if (hrtimer_cancel(timer))
hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
}
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 45ab6ee71209..a587f8349c46 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -2,18 +2,15 @@
#define __KVM_X86_LAPIC_H
#include "iodev.h"
+#include "kvm_timer.h"
#include <linux/kvm_host.h>
struct kvm_lapic {
unsigned long base_address;
struct kvm_io_device dev;
- struct {
- atomic_t pending;
- s64 period; /* unit: ns */
- u32 divide_count;
- struct hrtimer dev;
- } timer;
+ struct kvm_timer lapic_timer;
+ u32 divide_count;
struct kvm_vcpu *vcpu;
struct page *regs_page;
void *regs;
@@ -34,12 +31,13 @@ u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
-int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig);
+int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq);
u64 kvm_get_apic_base(struct kvm_vcpu *vcpu);
void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data);
void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu);
int kvm_lapic_enabled(struct kvm_vcpu *vcpu);
+bool kvm_apic_present(struct kvm_vcpu *vcpu);
int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu);
void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index b6caf1329b1b..8fcdae9660f4 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -126,6 +126,7 @@ module_param(oos_shadow, bool, 0644);
#define PFERR_PRESENT_MASK (1U << 0)
#define PFERR_WRITE_MASK (1U << 1)
#define PFERR_USER_MASK (1U << 2)
+#define PFERR_RSVD_MASK (1U << 3)
#define PFERR_FETCH_MASK (1U << 4)
#define PT_DIRECTORY_LEVEL 2
@@ -177,7 +178,11 @@ static u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */
static u64 __read_mostly shadow_user_mask;
static u64 __read_mostly shadow_accessed_mask;
static u64 __read_mostly shadow_dirty_mask;
-static u64 __read_mostly shadow_mt_mask;
+
+static inline u64 rsvd_bits(int s, int e)
+{
+ return ((1ULL << (e - s + 1)) - 1) << s;
+}
void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte)
{
@@ -193,14 +198,13 @@ void kvm_mmu_set_base_ptes(u64 base_pte)
EXPORT_SYMBOL_GPL(kvm_mmu_set_base_ptes);
void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
- u64 dirty_mask, u64 nx_mask, u64 x_mask, u64 mt_mask)
+ u64 dirty_mask, u64 nx_mask, u64 x_mask)
{
shadow_user_mask = user_mask;
shadow_accessed_mask = accessed_mask;
shadow_dirty_mask = dirty_mask;
shadow_nx_mask = nx_mask;
shadow_x_mask = x_mask;
- shadow_mt_mask = mt_mask;
}
EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes);
@@ -219,11 +223,6 @@ static int is_nx(struct kvm_vcpu *vcpu)
return vcpu->arch.shadow_efer & EFER_NX;
}
-static int is_present_pte(unsigned long pte)
-{
- return pte & PT_PRESENT_MASK;
-}
-
static int is_shadow_present_pte(u64 pte)
{
return pte != shadow_trap_nonpresent_pte
@@ -1074,18 +1073,10 @@ static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn)
return NULL;
}
-static void kvm_unlink_unsync_global(struct kvm *kvm, struct kvm_mmu_page *sp)
-{
- list_del(&sp->oos_link);
- --kvm->stat.mmu_unsync_global;
-}
-
static void kvm_unlink_unsync_page(struct kvm *kvm, struct kvm_mmu_page *sp)
{
WARN_ON(!sp->unsync);
sp->unsync = 0;
- if (sp->global)
- kvm_unlink_unsync_global(kvm, sp);
--kvm->stat.mmu_unsync;
}
@@ -1248,7 +1239,6 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
pgprintk("%s: adding gfn %lx role %x\n", __func__, gfn, role.word);
sp->gfn = gfn;
sp->role = role;
- sp->global = 0;
hlist_add_head(&sp->hash_link, bucket);
if (!direct) {
if (rmap_write_protect(vcpu->kvm, gfn))
@@ -1616,7 +1606,7 @@ static int get_mtrr_type(struct mtrr_state_type *mtrr_state,
return mtrr_state->def_type;
}
-static u8 get_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
+u8 kvm_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
{
u8 mtrr;
@@ -1626,6 +1616,7 @@ static u8 get_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
mtrr = MTRR_TYPE_WRBACK;
return mtrr;
}
+EXPORT_SYMBOL_GPL(kvm_get_guest_memory_type);
static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
{
@@ -1646,11 +1637,7 @@ static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
++vcpu->kvm->stat.mmu_unsync;
sp->unsync = 1;
- if (sp->global) {
- list_add(&sp->oos_link, &vcpu->kvm->arch.oos_global_pages);
- ++vcpu->kvm->stat.mmu_unsync_global;
- } else
- kvm_mmu_mark_parents_unsync(vcpu, sp);
+ kvm_mmu_mark_parents_unsync(vcpu, sp);
mmu_convert_notrap(sp);
return 0;
@@ -1677,21 +1664,11 @@ static int mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn,
static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
unsigned pte_access, int user_fault,
int write_fault, int dirty, int largepage,
- int global, gfn_t gfn, pfn_t pfn, bool speculative,
+ gfn_t gfn, pfn_t pfn, bool speculative,
bool can_unsync)
{
u64 spte;
int ret = 0;
- u64 mt_mask = shadow_mt_mask;
- struct kvm_mmu_page *sp = page_header(__pa(shadow_pte));
-
- if (!global && sp->global) {
- sp->global = 0;
- if (sp->unsync) {
- kvm_unlink_unsync_global(vcpu->kvm, sp);
- kvm_mmu_mark_parents_unsync(vcpu, sp);
- }
- }
/*
* We don't set the accessed bit, since we sometimes want to see
@@ -1711,16 +1688,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
spte |= shadow_user_mask;
if (largepage)
spte |= PT_PAGE_SIZE_MASK;
- if (mt_mask) {
- if (!kvm_is_mmio_pfn(pfn)) {
- mt_mask = get_memory_type(vcpu, gfn) <<
- kvm_x86_ops->get_mt_mask_shift();
- mt_mask |= VMX_EPT_IGMT_BIT;
- } else
- mt_mask = MTRR_TYPE_UNCACHABLE <<
- kvm_x86_ops->get_mt_mask_shift();
- spte |= mt_mask;
- }
+ if (tdp_enabled)
+ spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn,
+ kvm_is_mmio_pfn(pfn));
spte |= (u64)pfn << PAGE_SHIFT;
@@ -1765,8 +1735,8 @@ set_pte:
static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
unsigned pt_access, unsigned pte_access,
int user_fault, int write_fault, int dirty,
- int *ptwrite, int largepage, int global,
- gfn_t gfn, pfn_t pfn, bool speculative)
+ int *ptwrite, int largepage, gfn_t gfn,
+ pfn_t pfn, bool speculative)
{
int was_rmapped = 0;
int was_writeble = is_writeble_pte(*shadow_pte);
@@ -1795,7 +1765,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
was_rmapped = 1;
}
if (set_spte(vcpu, shadow_pte, pte_access, user_fault, write_fault,
- dirty, largepage, global, gfn, pfn, speculative, true)) {
+ dirty, largepage, gfn, pfn, speculative, true)) {
if (write_fault)
*ptwrite = 1;
kvm_x86_ops->tlb_flush(vcpu);
@@ -1843,7 +1813,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
|| (largepage && iterator.level == PT_DIRECTORY_LEVEL)) {
mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
0, write, 1, &pt_write,
- largepage, 0, gfn, pfn, false);
+ largepage, gfn, pfn, false);
++vcpu->stat.pf_fixed;
break;
}
@@ -2014,15 +1984,6 @@ static void mmu_sync_roots(struct kvm_vcpu *vcpu)
}
}
-static void mmu_sync_global(struct kvm_vcpu *vcpu)
-{
- struct kvm *kvm = vcpu->kvm;
- struct kvm_mmu_page *sp, *n;
-
- list_for_each_entry_safe(sp, n, &kvm->arch.oos_global_pages, oos_link)
- kvm_sync_page(vcpu, sp);
-}
-
void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu)
{
spin_lock(&vcpu->kvm->mmu_lock);
@@ -2030,13 +1991,6 @@ void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu)
spin_unlock(&vcpu->kvm->mmu_lock);
}
-void kvm_mmu_sync_global(struct kvm_vcpu *vcpu)
-{
- spin_lock(&vcpu->kvm->mmu_lock);
- mmu_sync_global(vcpu);
- spin_unlock(&vcpu->kvm->mmu_lock);
-}
-
static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr)
{
return vaddr;
@@ -2151,6 +2105,14 @@ static void paging_free(struct kvm_vcpu *vcpu)
nonpaging_free(vcpu);
}
+static bool is_rsvd_bits_set(struct kvm_vcpu *vcpu, u64 gpte, int level)
+{
+ int bit7;
+
+ bit7 = (gpte >> 7) & 1;
+ return (gpte & vcpu->arch.mmu.rsvd_bits_mask[bit7][level-1]) != 0;
+}
+
#define PTTYPE 64
#include "paging_tmpl.h"
#undef PTTYPE
@@ -2159,6 +2121,59 @@ static void paging_free(struct kvm_vcpu *vcpu)
#include "paging_tmpl.h"
#undef PTTYPE
+static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level)
+{
+ struct kvm_mmu *context = &vcpu->arch.mmu;
+ int maxphyaddr = cpuid_maxphyaddr(vcpu);
+ u64 exb_bit_rsvd = 0;
+
+ if (!is_nx(vcpu))
+ exb_bit_rsvd = rsvd_bits(63, 63);
+ switch (level) {
+ case PT32_ROOT_LEVEL:
+ /* no rsvd bits for 2 level 4K page table entries */
+ context->rsvd_bits_mask[0][1] = 0;
+ context->rsvd_bits_mask[0][0] = 0;
+ if (is_cpuid_PSE36())
+ /* 36bits PSE 4MB page */
+ context->rsvd_bits_mask[1][1] = rsvd_bits(17, 21);
+ else
+ /* 32 bits PSE 4MB page */
+ context->rsvd_bits_mask[1][1] = rsvd_bits(13, 21);
+ context->rsvd_bits_mask[1][0] = ~0ull;
+ break;
+ case PT32E_ROOT_LEVEL:
+ context->rsvd_bits_mask[0][2] =
+ rsvd_bits(maxphyaddr, 63) |
+ rsvd_bits(7, 8) | rsvd_bits(1, 2); /* PDPTE */
+ context->rsvd_bits_mask[0][1] = exb_bit_rsvd |
+ rsvd_bits(maxphyaddr, 62); /* PDE */
+ context->rsvd_bits_mask[0][0] = exb_bit_rsvd |
+ rsvd_bits(maxphyaddr, 62); /* PTE */
+ context->rsvd_bits_mask[1][1] = exb_bit_rsvd |
+ rsvd_bits(maxphyaddr, 62) |
+ rsvd_bits(13, 20); /* large page */
+ context->rsvd_bits_mask[1][0] = ~0ull;
+ break;
+ case PT64_ROOT_LEVEL:
+ context->rsvd_bits_mask[0][3] = exb_bit_rsvd |
+ rsvd_bits(maxphyaddr, 51) | rsvd_bits(7, 8);
+ context->rsvd_bits_mask[0][2] = exb_bit_rsvd |
+ rsvd_bits(maxphyaddr, 51) | rsvd_bits(7, 8);
+ context->rsvd_bits_mask[0][1] = exb_bit_rsvd |
+ rsvd_bits(maxphyaddr, 51);
+ context->rsvd_bits_mask[0][0] = exb_bit_rsvd |
+ rsvd_bits(maxphyaddr, 51);
+ context->rsvd_bits_mask[1][3] = context->rsvd_bits_mask[0][3];
+ context->rsvd_bits_mask[1][2] = context->rsvd_bits_mask[0][2];
+ context->rsvd_bits_mask[1][1] = exb_bit_rsvd |
+ rsvd_bits(maxphyaddr, 51) |
+ rsvd_bits(13, 20); /* large page */
+ context->rsvd_bits_mask[1][0] = ~0ull;
+ break;
+ }
+}
+
static int paging64_init_context_common(struct kvm_vcpu *vcpu, int level)
{
struct kvm_mmu *context = &vcpu->arch.mmu;
@@ -2179,6 +2194,7 @@ static int paging64_init_context_common(struct kvm_vcpu *vcpu, int level)
static int paging64_init_context(struct kvm_vcpu *vcpu)
{
+ reset_rsvds_bits_mask(vcpu, PT64_ROOT_LEVEL);
return paging64_init_context_common(vcpu, PT64_ROOT_LEVEL);
}
@@ -2186,6 +2202,7 @@ static int paging32_init_context(struct kvm_vcpu *vcpu)
{
struct kvm_mmu *context = &vcpu->arch.mmu;
+ reset_rsvds_bits_mask(vcpu, PT32_ROOT_LEVEL);
context->new_cr3 = paging_new_cr3;
context->page_fault = paging32_page_fault;
context->gva_to_gpa = paging32_gva_to_gpa;
@@ -2201,6 +2218,7 @@ static int paging32_init_context(struct kvm_vcpu *vcpu)
static int paging32E_init_context(struct kvm_vcpu *vcpu)
{
+ reset_rsvds_bits_mask(vcpu, PT32E_ROOT_LEVEL);
return paging64_init_context_common(vcpu, PT32E_ROOT_LEVEL);
}
@@ -2221,12 +2239,15 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
context->gva_to_gpa = nonpaging_gva_to_gpa;
context->root_level = 0;
} else if (is_long_mode(vcpu)) {
+ reset_rsvds_bits_mask(vcpu, PT64_ROOT_LEVEL);
context->gva_to_gpa = paging64_gva_to_gpa;
context->root_level = PT64_ROOT_LEVEL;
} else if (is_pae(vcpu)) {
+ reset_rsvds_bits_mask(vcpu, PT32E_ROOT_LEVEL);
context->gva_to_gpa = paging64_gva_to_gpa;
context->root_level = PT32E_ROOT_LEVEL;
} else {
+ reset_rsvds_bits_mask(vcpu, PT32_ROOT_LEVEL);
context->gva_to_gpa = paging32_gva_to_gpa;
context->root_level = PT32_ROOT_LEVEL;
}
@@ -2638,14 +2659,6 @@ EXPORT_SYMBOL_GPL(kvm_disable_tdp);
static void free_mmu_pages(struct kvm_vcpu *vcpu)
{
- struct kvm_mmu_page *sp;
-
- while (!list_empty(&vcpu->kvm->arch.active_mmu_pages)) {
- sp = container_of(vcpu->kvm->arch.active_mmu_pages.next,
- struct kvm_mmu_page, link);
- kvm_mmu_zap_page(vcpu->kvm, sp);
- cond_resched();
- }
free_page((unsigned long)vcpu->arch.mmu.pae_root);
}
@@ -3008,11 +3021,13 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
" in nonleaf level: levels %d gva %lx"
" level %d pte %llx\n", audit_msg,
vcpu->arch.mmu.root_level, va, level, ent);
-
- audit_mappings_page(vcpu, ent, va, level - 1);
+ else
+ audit_mappings_page(vcpu, ent, va, level - 1);
} else {
gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va);
- hpa_t hpa = (hpa_t)gpa_to_pfn(vcpu, gpa) << PAGE_SHIFT;
+ gfn_t gfn = gpa >> PAGE_SHIFT;
+ pfn_t pfn = gfn_to_pfn(vcpu->kvm, gfn);
+ hpa_t hpa = (hpa_t)pfn << PAGE_SHIFT;
if (is_shadow_present_pte(ent)
&& (ent & PT64_BASE_ADDR_MASK) != hpa)
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index eaab2145f62b..3494a2fb136e 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -75,4 +75,9 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
return vcpu->arch.cr0 & X86_CR0_PG;
}
+static inline int is_present_pte(unsigned long pte)
+{
+ return pte & PT_PRESENT_MASK;
+}
+
#endif
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 6bd70206c561..258e4591e1ca 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -123,6 +123,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
gfn_t table_gfn;
unsigned index, pt_access, pte_access;
gpa_t pte_gpa;
+ int rsvd_fault = 0;
pgprintk("%s: addr %lx\n", __func__, addr);
walk:
@@ -157,6 +158,10 @@ walk:
if (!is_present_pte(pte))
goto not_present;
+ rsvd_fault = is_rsvd_bits_set(vcpu, pte, walker->level);
+ if (rsvd_fault)
+ goto access_error;
+
if (write_fault && !is_writeble_pte(pte))
if (user_fault || is_write_protection(vcpu))
goto access_error;
@@ -209,7 +214,6 @@ walk:
if (ret)
goto walk;
pte |= PT_DIRTY_MASK;
- kvm_mmu_pte_write(vcpu, pte_gpa, (u8 *)&pte, sizeof(pte), 0);
walker->ptes[walker->level - 1] = pte;
}
@@ -233,6 +237,8 @@ err:
walker->error_code |= PFERR_USER_MASK;
if (fetch_fault)
walker->error_code |= PFERR_FETCH_MASK;
+ if (rsvd_fault)
+ walker->error_code |= PFERR_RSVD_MASK;
return 0;
}
@@ -262,8 +268,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
kvm_get_pfn(pfn);
mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0,
gpte & PT_DIRTY_MASK, NULL, largepage,
- gpte & PT_GLOBAL_MASK, gpte_to_gfn(gpte),
- pfn, true);
+ gpte_to_gfn(gpte), pfn, true);
}
/*
@@ -297,7 +302,6 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
user_fault, write_fault,
gw->ptes[gw->level-1] & PT_DIRTY_MASK,
ptwrite, largepage,
- gw->ptes[gw->level-1] & PT_GLOBAL_MASK,
gw->gfn, pfn, false);
break;
}
@@ -380,7 +384,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
return r;
/*
- * Look up the shadow pte for the faulting address.
+ * Look up the guest pte for the faulting address.
*/
r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault,
fetch_fault);
@@ -586,7 +590,7 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
nr_present++;
pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
set_spte(vcpu, &sp->spt[i], pte_access, 0, 0,
- is_dirty_pte(gpte), 0, gpte & PT_GLOBAL_MASK, gfn,
+ is_dirty_pte(gpte), 0, gfn,
spte_to_pfn(sp->spt[i]), true, false);
}
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 1821c2078199..f994c6df78be 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -19,6 +19,7 @@
#include "irq.h"
#include "mmu.h"
#include "kvm_cache_regs.h"
+#include "x86.h"
#include <linux/module.h>
#include <linux/kernel.h>
@@ -69,7 +70,6 @@ module_param(npt, int, S_IRUGO);
static int nested = 0;
module_param(nested, int, S_IRUGO);
-static void kvm_reput_irq(struct vcpu_svm *svm);
static void svm_flush_tlb(struct kvm_vcpu *vcpu);
static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override);
@@ -132,24 +132,6 @@ static inline u32 svm_has(u32 feat)
return svm_features & feat;
}
-static inline u8 pop_irq(struct kvm_vcpu *vcpu)
-{
- int word_index = __ffs(vcpu->arch.irq_summary);
- int bit_index = __ffs(vcpu->arch.irq_pending[word_index]);
- int irq = word_index * BITS_PER_LONG + bit_index;
-
- clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
- if (!vcpu->arch.irq_pending[word_index])
- clear_bit(word_index, &vcpu->arch.irq_summary);
- return irq;
-}
-
-static inline void push_irq(struct kvm_vcpu *vcpu, u8 irq)
-{
- set_bit(irq, vcpu->arch.irq_pending);
- set_bit(irq / BITS_PER_LONG, &vcpu->arch.irq_summary);
-}
-
static inline void clgi(void)
{
asm volatile (__ex(SVM_CLGI));
@@ -214,13 +196,6 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
svm->vmcb->control.event_inj_err = error_code;
}
-static bool svm_exception_injected(struct kvm_vcpu *vcpu)
-{
- struct vcpu_svm *svm = to_svm(vcpu);
-
- return !(svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID);
-}
-
static int is_external_interrupt(u32 info)
{
info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID;
@@ -241,8 +216,6 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
kvm_rip_write(vcpu, svm->next_rip);
svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
-
- vcpu->arch.interrupt_window_open = (svm->vcpu.arch.hflags & HF_GIF_MASK);
}
static int has_svm(void)
@@ -411,7 +384,6 @@ static __init int svm_hardware_setup(void)
iopm_va = page_address(iopm_pages);
memset(iopm_va, 0xff, PAGE_SIZE * (1 << IOPM_ALLOC_ORDER));
- clear_bit(0x80, iopm_va); /* allow direct access to PC debug port */
iopm_base = page_to_pfn(iopm_pages) << PAGE_SHIFT;
if (boot_cpu_has(X86_FEATURE_NX))
@@ -796,6 +768,11 @@ static void svm_get_segment(struct kvm_vcpu *vcpu,
var->db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1;
var->g = (s->attrib >> SVM_SELECTOR_G_SHIFT) & 1;
+ /* AMD's VMCB does not have an explicit unusable field, so emulate it
+ * for cross vendor migration purposes by "not present"
+ */
+ var->unusable = !var->present || (var->type == 0);
+
switch (seg) {
case VCPU_SREG_CS:
/*
@@ -826,9 +803,16 @@ static void svm_get_segment(struct kvm_vcpu *vcpu,
if (!var->unusable)
var->type |= 0x1;
break;
+ case VCPU_SREG_SS:
+ /* On AMD CPUs sometimes the DB bit in the segment
+ * descriptor is left as 1, although the whole segment has
+ * been made unusable. Clear it here to pass an Intel VMX
+ * entry check when cross vendor migrating.
+ */
+ if (var->unusable)
+ var->db = 0;
+ break;
}
-
- var->unusable = !var->present;
}
static int svm_get_cpl(struct kvm_vcpu *vcpu)
@@ -991,16 +975,6 @@ static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
return 0;
}
-static int svm_get_irq(struct kvm_vcpu *vcpu)
-{
- struct vcpu_svm *svm = to_svm(vcpu);
- u32 exit_int_info = svm->vmcb->control.exit_int_info;
-
- if (is_external_interrupt(exit_int_info))
- return exit_int_info & SVM_EVTINJ_VEC_MASK;
- return -1;
-}
-
static void load_host_msrs(struct kvm_vcpu *vcpu)
{
#ifdef CONFIG_X86_64
@@ -1105,17 +1079,8 @@ static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value,
static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
{
- u32 exit_int_info = svm->vmcb->control.exit_int_info;
- struct kvm *kvm = svm->vcpu.kvm;
u64 fault_address;
u32 error_code;
- bool event_injection = false;
-
- if (!irqchip_in_kernel(kvm) &&
- is_external_interrupt(exit_int_info)) {
- event_injection = true;
- push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK);
- }
fault_address = svm->vmcb->control.exit_info_2;
error_code = svm->vmcb->control.exit_info_1;
@@ -1135,9 +1100,11 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
*/
if (npt_enabled)
svm_flush_tlb(&svm->vcpu);
-
- if (!npt_enabled && event_injection)
- kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
+ else {
+ if (svm->vcpu.arch.interrupt.pending ||
+ svm->vcpu.arch.exception.pending)
+ kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
+ }
return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
}
@@ -1840,17 +1807,54 @@ static int task_switch_interception(struct vcpu_svm *svm,
struct kvm_run *kvm_run)
{
u16 tss_selector;
+ int reason;
+ int int_type = svm->vmcb->control.exit_int_info &
+ SVM_EXITINTINFO_TYPE_MASK;
+ int int_vec = svm->vmcb->control.exit_int_info & SVM_EVTINJ_VEC_MASK;
+ uint32_t type =
+ svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_TYPE_MASK;
+ uint32_t idt_v =
+ svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID;
tss_selector = (u16)svm->vmcb->control.exit_info_1;
+
if (svm->vmcb->control.exit_info_2 &
(1ULL << SVM_EXITINFOSHIFT_TS_REASON_IRET))
- return kvm_task_switch(&svm->vcpu, tss_selector,
- TASK_SWITCH_IRET);
- if (svm->vmcb->control.exit_info_2 &
- (1ULL << SVM_EXITINFOSHIFT_TS_REASON_JMP))
- return kvm_task_switch(&svm->vcpu, tss_selector,
- TASK_SWITCH_JMP);
- return kvm_task_switch(&svm->vcpu, tss_selector, TASK_SWITCH_CALL);
+ reason = TASK_SWITCH_IRET;
+ else if (svm->vmcb->control.exit_info_2 &
+ (1ULL << SVM_EXITINFOSHIFT_TS_REASON_JMP))
+ reason = TASK_SWITCH_JMP;
+ else if (idt_v)
+ reason = TASK_SWITCH_GATE;
+ else
+ reason = TASK_SWITCH_CALL;
+
+ if (reason == TASK_SWITCH_GATE) {
+ switch (type) {
+ case SVM_EXITINTINFO_TYPE_NMI:
+ svm->vcpu.arch.nmi_injected = false;
+ break;
+ case SVM_EXITINTINFO_TYPE_EXEPT:
+ kvm_clear_exception_queue(&svm->vcpu);
+ break;
+ case SVM_EXITINTINFO_TYPE_INTR:
+ kvm_clear_interrupt_queue(&svm->vcpu);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (reason != TASK_SWITCH_GATE ||
+ int_type == SVM_EXITINTINFO_TYPE_SOFT ||
+ (int_type == SVM_EXITINTINFO_TYPE_EXEPT &&
+ (int_vec == OF_VECTOR || int_vec == BP_VECTOR))) {
+ if (emulate_instruction(&svm->vcpu, kvm_run, 0, 0,
+ EMULTYPE_SKIP) != EMULATE_DONE)
+ return 0;
+ }
+
+ return kvm_task_switch(&svm->vcpu, tss_selector, reason);
}
static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
@@ -1860,6 +1864,14 @@ static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
return 1;
}
+static int iret_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+ ++svm->vcpu.stat.nmi_window_exits;
+ svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
+ svm->vcpu.arch.hflags &= ~HF_NMI_MASK;
+ return 1;
+}
+
static int invlpg_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
{
if (emulate_instruction(&svm->vcpu, kvm_run, 0, 0, 0) != EMULATE_DONE)
@@ -1877,8 +1889,14 @@ static int emulate_on_interception(struct vcpu_svm *svm,
static int cr8_write_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
{
+ u8 cr8_prev = kvm_get_cr8(&svm->vcpu);
+ /* instruction emulation calls kvm_set_cr8() */
emulate_instruction(&svm->vcpu, NULL, 0, 0, 0);
- if (irqchip_in_kernel(svm->vcpu.kvm))
+ if (irqchip_in_kernel(svm->vcpu.kvm)) {
+ svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK;
+ return 1;
+ }
+ if (cr8_prev <= kvm_get_cr8(&svm->vcpu))
return 1;
kvm_run->exit_reason = KVM_EXIT_SET_TPR;
return 0;
@@ -2088,8 +2106,9 @@ static int interrupt_window_interception(struct vcpu_svm *svm,
* If the user space waits to inject interrupts, exit as soon as
* possible
*/
- if (kvm_run->request_interrupt_window &&
- !svm->vcpu.arch.irq_summary) {
+ if (!irqchip_in_kernel(svm->vcpu.kvm) &&
+ kvm_run->request_interrupt_window &&
+ !kvm_cpu_has_interrupt(&svm->vcpu)) {
++svm->vcpu.stat.irq_window_exits;
kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
return 0;
@@ -2132,6 +2151,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
[SVM_EXIT_VINTR] = interrupt_window_interception,
/* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */
[SVM_EXIT_CPUID] = cpuid_interception,
+ [SVM_EXIT_IRET] = iret_interception,
[SVM_EXIT_INVD] = emulate_on_interception,
[SVM_EXIT_HLT] = halt_interception,
[SVM_EXIT_INVLPG] = invlpg_interception,
@@ -2192,7 +2212,6 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
}
}
- kvm_reput_irq(svm);
if (svm->vmcb->control.exit_code == SVM_EXIT_ERR) {
kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
@@ -2203,7 +2222,7 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
if (is_external_interrupt(svm->vmcb->control.exit_int_info) &&
exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR &&
- exit_code != SVM_EXIT_NPF)
+ exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH)
printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x "
"exit_code 0x%x\n",
__func__, svm->vmcb->control.exit_int_info,
@@ -2240,6 +2259,21 @@ static void pre_svm_run(struct vcpu_svm *svm)
new_asid(svm, svm_data);
}
+static void svm_drop_interrupt_shadow(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+ svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
+}
+
+static void svm_inject_nmi(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI;
+ vcpu->arch.hflags |= HF_NMI_MASK;
+ svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
+ ++vcpu->stat.nmi_injections;
+}
static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
{
@@ -2255,134 +2289,63 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT);
}
+static void svm_queue_irq(struct kvm_vcpu *vcpu, unsigned nr)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ svm->vmcb->control.event_inj = nr |
+ SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR;
+}
+
static void svm_set_irq(struct kvm_vcpu *vcpu, int irq)
{
struct vcpu_svm *svm = to_svm(vcpu);
nested_svm_intr(svm);
- svm_inject_irq(svm, irq);
+ svm_queue_irq(vcpu, irq);
}
-static void update_cr8_intercept(struct kvm_vcpu *vcpu)
+static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
{
struct vcpu_svm *svm = to_svm(vcpu);
- struct vmcb *vmcb = svm->vmcb;
- int max_irr, tpr;
-
- if (!irqchip_in_kernel(vcpu->kvm) || vcpu->arch.apic->vapic_addr)
- return;
-
- vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK;
- max_irr = kvm_lapic_find_highest_irr(vcpu);
- if (max_irr == -1)
+ if (irr == -1)
return;
- tpr = kvm_lapic_get_cr8(vcpu) << 4;
-
- if (tpr >= (max_irr & 0xf0))
- vmcb->control.intercept_cr_write |= INTERCEPT_CR8_MASK;
+ if (tpr >= irr)
+ svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR8_MASK;
}
-static void svm_intr_assist(struct kvm_vcpu *vcpu)
+static int svm_nmi_allowed(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
struct vmcb *vmcb = svm->vmcb;
- int intr_vector = -1;
-
- if ((vmcb->control.exit_int_info & SVM_EVTINJ_VALID) &&
- ((vmcb->control.exit_int_info & SVM_EVTINJ_TYPE_MASK) == 0)) {
- intr_vector = vmcb->control.exit_int_info &
- SVM_EVTINJ_VEC_MASK;
- vmcb->control.exit_int_info = 0;
- svm_inject_irq(svm, intr_vector);
- goto out;
- }
-
- if (vmcb->control.int_ctl & V_IRQ_MASK)
- goto out;
-
- if (!kvm_cpu_has_interrupt(vcpu))
- goto out;
-
- if (nested_svm_intr(svm))
- goto out;
-
- if (!(svm->vcpu.arch.hflags & HF_GIF_MASK))
- goto out;
-
- if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
- (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
- (vmcb->control.event_inj & SVM_EVTINJ_VALID)) {
- /* unable to deliver irq, set pending irq */
- svm_set_vintr(svm);
- svm_inject_irq(svm, 0x0);
- goto out;
- }
- /* Okay, we can deliver the interrupt: grab it and update PIC state. */
- intr_vector = kvm_cpu_get_interrupt(vcpu);
- svm_inject_irq(svm, intr_vector);
-out:
- update_cr8_intercept(vcpu);
+ return !(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) &&
+ !(svm->vcpu.arch.hflags & HF_NMI_MASK);
}
-static void kvm_reput_irq(struct vcpu_svm *svm)
+static int svm_interrupt_allowed(struct kvm_vcpu *vcpu)
{
- struct vmcb_control_area *control = &svm->vmcb->control;
-
- if ((control->int_ctl & V_IRQ_MASK)
- && !irqchip_in_kernel(svm->vcpu.kvm)) {
- control->int_ctl &= ~V_IRQ_MASK;
- push_irq(&svm->vcpu, control->int_vector);
- }
-
- svm->vcpu.arch.interrupt_window_open =
- !(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
- (svm->vcpu.arch.hflags & HF_GIF_MASK);
+ struct vcpu_svm *svm = to_svm(vcpu);
+ struct vmcb *vmcb = svm->vmcb;
+ return (vmcb->save.rflags & X86_EFLAGS_IF) &&
+ !(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) &&
+ (svm->vcpu.arch.hflags & HF_GIF_MASK);
}
-static void svm_do_inject_vector(struct vcpu_svm *svm)
+static void enable_irq_window(struct kvm_vcpu *vcpu)
{
- struct kvm_vcpu *vcpu = &svm->vcpu;
- int word_index = __ffs(vcpu->arch.irq_summary);
- int bit_index = __ffs(vcpu->arch.irq_pending[word_index]);
- int irq = word_index * BITS_PER_LONG + bit_index;
-
- clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
- if (!vcpu->arch.irq_pending[word_index])
- clear_bit(word_index, &vcpu->arch.irq_summary);
- svm_inject_irq(svm, irq);
+ svm_set_vintr(to_svm(vcpu));
+ svm_inject_irq(to_svm(vcpu), 0x0);
}
-static void do_interrupt_requests(struct kvm_vcpu *vcpu,
- struct kvm_run *kvm_run)
+static void enable_nmi_window(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- struct vmcb_control_area *control = &svm->vmcb->control;
-
- if (nested_svm_intr(svm))
- return;
-
- svm->vcpu.arch.interrupt_window_open =
- (!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
- (svm->vmcb->save.rflags & X86_EFLAGS_IF) &&
- (svm->vcpu.arch.hflags & HF_GIF_MASK));
- if (svm->vcpu.arch.interrupt_window_open && svm->vcpu.arch.irq_summary)
- /*
- * If interrupts enabled, and not blocked by sti or mov ss. Good.
- */
- svm_do_inject_vector(svm);
-
- /*
- * Interrupts blocked. Wait for unblock.
- */
- if (!svm->vcpu.arch.interrupt_window_open &&
- (svm->vcpu.arch.irq_summary || kvm_run->request_interrupt_window))
- svm_set_vintr(svm);
- else
- svm_clear_vintr(svm);
+ if (svm->vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK)
+ enable_irq_window(vcpu);
}
static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
@@ -2405,7 +2368,7 @@ static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu)
if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR8_MASK)) {
int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK;
- kvm_lapic_set_tpr(vcpu, cr8);
+ kvm_set_cr8(vcpu, cr8);
}
}
@@ -2414,14 +2377,51 @@ static inline void sync_lapic_to_cr8(struct kvm_vcpu *vcpu)
struct vcpu_svm *svm = to_svm(vcpu);
u64 cr8;
- if (!irqchip_in_kernel(vcpu->kvm))
- return;
-
cr8 = kvm_get_cr8(vcpu);
svm->vmcb->control.int_ctl &= ~V_TPR_MASK;
svm->vmcb->control.int_ctl |= cr8 & V_TPR_MASK;
}
+static void svm_complete_interrupts(struct vcpu_svm *svm)
+{
+ u8 vector;
+ int type;
+ u32 exitintinfo = svm->vmcb->control.exit_int_info;
+
+ svm->vcpu.arch.nmi_injected = false;
+ kvm_clear_exception_queue(&svm->vcpu);
+ kvm_clear_interrupt_queue(&svm->vcpu);
+
+ if (!(exitintinfo & SVM_EXITINTINFO_VALID))
+ return;
+
+ vector = exitintinfo & SVM_EXITINTINFO_VEC_MASK;
+ type = exitintinfo & SVM_EXITINTINFO_TYPE_MASK;
+
+ switch (type) {
+ case SVM_EXITINTINFO_TYPE_NMI:
+ svm->vcpu.arch.nmi_injected = true;
+ break;
+ case SVM_EXITINTINFO_TYPE_EXEPT:
+ /* In case of software exception do not reinject an exception
+ vector, but re-execute and instruction instead */
+ if (vector == BP_VECTOR || vector == OF_VECTOR)
+ break;
+ if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) {
+ u32 err = svm->vmcb->control.exit_int_info_err;
+ kvm_queue_exception_e(&svm->vcpu, vector, err);
+
+ } else
+ kvm_queue_exception(&svm->vcpu, vector);
+ break;
+ case SVM_EXITINTINFO_TYPE_INTR:
+ kvm_queue_interrupt(&svm->vcpu, vector);
+ break;
+ default:
+ break;
+ }
+}
+
#ifdef CONFIG_X86_64
#define R "r"
#else
@@ -2550,6 +2550,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
sync_cr8_to_lapic(vcpu);
svm->next_rip = 0;
+
+ svm_complete_interrupts(svm);
}
#undef R
@@ -2615,7 +2617,7 @@ static int get_npt_level(void)
#endif
}
-static int svm_get_mt_mask_shift(void)
+static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
{
return 0;
}
@@ -2666,16 +2668,19 @@ static struct kvm_x86_ops svm_x86_ops = {
.handle_exit = handle_exit,
.skip_emulated_instruction = skip_emulated_instruction,
.patch_hypercall = svm_patch_hypercall,
- .get_irq = svm_get_irq,
.set_irq = svm_set_irq,
+ .set_nmi = svm_inject_nmi,
.queue_exception = svm_queue_exception,
- .exception_injected = svm_exception_injected,
- .inject_pending_irq = svm_intr_assist,
- .inject_pending_vectors = do_interrupt_requests,
+ .interrupt_allowed = svm_interrupt_allowed,
+ .nmi_allowed = svm_nmi_allowed,
+ .enable_nmi_window = enable_nmi_window,
+ .enable_irq_window = enable_irq_window,
+ .update_cr8_intercept = update_cr8_intercept,
+ .drop_interrupt_shadow = svm_drop_interrupt_shadow,
.set_tss_addr = svm_set_tss_addr,
.get_tdp_level = get_npt_level,
- .get_mt_mask_shift = svm_get_mt_mask_shift,
+ .get_mt_mask = svm_get_mt_mask,
};
static int __init svm_init(void)
diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c
new file mode 100644
index 000000000000..86dbac072d0c
--- /dev/null
+++ b/arch/x86/kvm/timer.c
@@ -0,0 +1,46 @@
+#include <linux/kvm_host.h>
+#include <linux/kvm.h>
+#include <linux/hrtimer.h>
+#include <asm/atomic.h>
+#include "kvm_timer.h"
+
+static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer)
+{
+ int restart_timer = 0;
+ wait_queue_head_t *q = &vcpu->wq;
+
+ /* FIXME: this code should not know anything about vcpus */
+ if (!atomic_inc_and_test(&ktimer->pending))
+ set_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
+
+ if (!ktimer->reinject)
+ atomic_set(&ktimer->pending, 1);
+
+ if (waitqueue_active(q))
+ wake_up_interruptible(q);
+
+ if (ktimer->t_ops->is_periodic(ktimer)) {
+ hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);
+ restart_timer = 1;
+ }
+
+ return restart_timer;
+}
+
+enum hrtimer_restart kvm_timer_fn(struct hrtimer *data)
+{
+ int restart_timer;
+ struct kvm_vcpu *vcpu;
+ struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
+
+ vcpu = ktimer->kvm->vcpus[ktimer->vcpu_id];
+ if (!vcpu)
+ return HRTIMER_NORESTART;
+
+ restart_timer = __kvm_timer_fn(vcpu, ktimer);
+ if (restart_timer)
+ return HRTIMER_RESTART;
+ else
+ return HRTIMER_NORESTART;
+}
+
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index bb481330716f..e8a5649f9c15 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -38,20 +38,20 @@
MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");
-static int bypass_guest_pf = 1;
-module_param(bypass_guest_pf, bool, 0);
+static int __read_mostly bypass_guest_pf = 1;
+module_param(bypass_guest_pf, bool, S_IRUGO);
-static int enable_vpid = 1;
-module_param(enable_vpid, bool, 0);
+static int __read_mostly enable_vpid = 1;
+module_param_named(vpid, enable_vpid, bool, 0444);
-static int flexpriority_enabled = 1;
-module_param(flexpriority_enabled, bool, 0);
+static int __read_mostly flexpriority_enabled = 1;
+module_param_named(flexpriority, flexpriority_enabled, bool, S_IRUGO);
-static int enable_ept = 1;
-module_param(enable_ept, bool, 0);
+static int __read_mostly enable_ept = 1;
+module_param_named(ept, enable_ept, bool, S_IRUGO);
-static int emulate_invalid_guest_state = 0;
-module_param(emulate_invalid_guest_state, bool, 0);
+static int __read_mostly emulate_invalid_guest_state = 0;
+module_param(emulate_invalid_guest_state, bool, S_IRUGO);
struct vmcs {
u32 revision_id;
@@ -111,9 +111,10 @@ static DEFINE_PER_CPU(struct vmcs *, vmxarea);
static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
static DEFINE_PER_CPU(struct list_head, vcpus_on_cpu);
-static struct page *vmx_io_bitmap_a;
-static struct page *vmx_io_bitmap_b;
-static struct page *vmx_msr_bitmap;
+static unsigned long *vmx_io_bitmap_a;
+static unsigned long *vmx_io_bitmap_b;
+static unsigned long *vmx_msr_bitmap_legacy;
+static unsigned long *vmx_msr_bitmap_longmode;
static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS);
static DEFINE_SPINLOCK(vmx_vpid_lock);
@@ -215,68 +216,69 @@ static inline int is_external_interrupt(u32 intr_info)
static inline int cpu_has_vmx_msr_bitmap(void)
{
- return (vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS);
+ return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS;
}
static inline int cpu_has_vmx_tpr_shadow(void)
{
- return (vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW);
+ return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW;
}
static inline int vm_need_tpr_shadow(struct kvm *kvm)
{
- return ((cpu_has_vmx_tpr_shadow()) && (irqchip_in_kernel(kvm)));
+ return (cpu_has_vmx_tpr_shadow()) && (irqchip_in_kernel(kvm));
}
static inline int cpu_has_secondary_exec_ctrls(void)
{
- return (vmcs_config.cpu_based_exec_ctrl &
- CPU_BASED_ACTIVATE_SECONDARY_CONTROLS);
+ return vmcs_config.cpu_based_exec_ctrl &
+ CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
}
static inline bool cpu_has_vmx_virtualize_apic_accesses(void)
{
- return flexpriority_enabled
- && (vmcs_config.cpu_based_2nd_exec_ctrl &
- SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES);
+ return vmcs_config.cpu_based_2nd_exec_ctrl &
+ SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+}
+
+static inline bool cpu_has_vmx_flexpriority(void)
+{
+ return cpu_has_vmx_tpr_shadow() &&
+ cpu_has_vmx_virtualize_apic_accesses();
}
static inline int cpu_has_vmx_invept_individual_addr(void)
{
- return (!!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT));
+ return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT);
}
static inline int cpu_has_vmx_invept_context(void)
{
- return (!!(vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT));
+ return !!(vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT);
}
static inline int cpu_has_vmx_invept_global(void)
{
- return (!!(vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT));
+ return !!(vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT);
}
static inline int cpu_has_vmx_ept(void)
{
- return (vmcs_config.cpu_based_2nd_exec_ctrl &
- SECONDARY_EXEC_ENABLE_EPT);
-}
-
-static inline int vm_need_ept(void)
-{
- return (cpu_has_vmx_ept() && enable_ept);
+ return vmcs_config.cpu_based_2nd_exec_ctrl &
+ SECONDARY_EXEC_ENABLE_EPT;
}
static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm)
{
- return ((cpu_has_vmx_virtualize_apic_accesses()) &&
- (irqchip_in_kernel(kvm)));
+ return flexpriority_enabled &&
+ (cpu_has_vmx_virtualize_apic_accesses()) &&
+ (irqchip_in_kernel(kvm));
}
static inline int cpu_has_vmx_vpid(void)
{
- return (vmcs_config.cpu_based_2nd_exec_ctrl &
- SECONDARY_EXEC_ENABLE_VPID);
+ return vmcs_config.cpu_based_2nd_exec_ctrl &
+ SECONDARY_EXEC_ENABLE_VPID;
}
static inline int cpu_has_virtual_nmis(void)
@@ -284,6 +286,11 @@ static inline int cpu_has_virtual_nmis(void)
return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS;
}
+static inline bool report_flexpriority(void)
+{
+ return flexpriority_enabled;
+}
+
static int __find_msr_index(struct vcpu_vmx *vmx, u32 msr)
{
int i;
@@ -381,7 +388,7 @@ static inline void ept_sync_global(void)
static inline void ept_sync_context(u64 eptp)
{
- if (vm_need_ept()) {
+ if (enable_ept) {
if (cpu_has_vmx_invept_context())
__invept(VMX_EPT_EXTENT_CONTEXT, eptp, 0);
else
@@ -391,7 +398,7 @@ static inline void ept_sync_context(u64 eptp)
static inline void ept_sync_individual_addr(u64 eptp, gpa_t gpa)
{
- if (vm_need_ept()) {
+ if (enable_ept) {
if (cpu_has_vmx_invept_individual_addr())
__invept(VMX_EPT_EXTENT_INDIVIDUAL_ADDR,
eptp, gpa);
@@ -490,7 +497,7 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
}
if (vcpu->arch.rmode.active)
eb = ~0;
- if (vm_need_ept())
+ if (enable_ept)
eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */
vmcs_write32(EXCEPTION_BITMAP, eb);
}
@@ -746,7 +753,6 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
if (interruptibility & 3)
vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
interruptibility & ~3);
- vcpu->arch.interrupt_window_open = 1;
}
static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
@@ -782,11 +788,6 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
}
-static bool vmx_exception_injected(struct kvm_vcpu *vcpu)
-{
- return false;
-}
-
/*
* Swap MSR entry in host/guest MSR entry array.
*/
@@ -812,6 +813,7 @@ static void move_msr_up(struct vcpu_vmx *vmx, int from, int to)
static void setup_msrs(struct vcpu_vmx *vmx)
{
int save_nmsrs;
+ unsigned long *msr_bitmap;
vmx_load_host_state(vmx);
save_nmsrs = 0;
@@ -847,6 +849,15 @@ static void setup_msrs(struct vcpu_vmx *vmx)
__find_msr_index(vmx, MSR_KERNEL_GS_BASE);
#endif
vmx->msr_offset_efer = __find_msr_index(vmx, MSR_EFER);
+
+ if (cpu_has_vmx_msr_bitmap()) {
+ if (is_long_mode(&vmx->vcpu))
+ msr_bitmap = vmx_msr_bitmap_longmode;
+ else
+ msr_bitmap = vmx_msr_bitmap_legacy;
+
+ vmcs_write64(MSR_BITMAP, __pa(msr_bitmap));
+ }
}
/*
@@ -1034,13 +1045,6 @@ static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
return 0;
}
-static int vmx_get_irq(struct kvm_vcpu *vcpu)
-{
- if (!vcpu->arch.interrupt.pending)
- return -1;
- return vcpu->arch.interrupt.nr;
-}
-
static __init int cpu_has_kvm_support(void)
{
return cpu_has_vmx();
@@ -1294,6 +1298,18 @@ static __init int hardware_setup(void)
if (boot_cpu_has(X86_FEATURE_NX))
kvm_enable_efer_bits(EFER_NX);
+ if (!cpu_has_vmx_vpid())
+ enable_vpid = 0;
+
+ if (!cpu_has_vmx_ept())
+ enable_ept = 0;
+
+ if (!cpu_has_vmx_flexpriority())
+ flexpriority_enabled = 0;
+
+ if (!cpu_has_vmx_tpr_shadow())
+ kvm_x86_ops->update_cr8_intercept = NULL;
+
return alloc_kvm_area();
}
@@ -1485,7 +1501,7 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
{
vpid_sync_vcpu_all(to_vmx(vcpu));
- if (vm_need_ept())
+ if (enable_ept)
ept_sync_context(construct_eptp(vcpu->arch.mmu.root_hpa));
}
@@ -1570,7 +1586,7 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
}
#endif
- if (vm_need_ept())
+ if (enable_ept)
ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu);
vmcs_writel(CR0_READ_SHADOW, cr0);
@@ -1599,7 +1615,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
u64 eptp;
guest_cr3 = cr3;
- if (vm_need_ept()) {
+ if (enable_ept) {
eptp = construct_eptp(cr3);
vmcs_write64(EPT_POINTER, eptp);
ept_sync_context(eptp);
@@ -1620,7 +1636,7 @@ static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON);
vcpu->arch.cr4 = cr4;
- if (vm_need_ept())
+ if (enable_ept)
ept_update_paging_mode_cr4(&hw_cr4, vcpu);
vmcs_writel(CR4_READ_SHADOW, cr4);
@@ -1982,7 +1998,7 @@ static int init_rmode_identity_map(struct kvm *kvm)
pfn_t identity_map_pfn;
u32 tmp;
- if (!vm_need_ept())
+ if (!enable_ept)
return 1;
if (unlikely(!kvm->arch.ept_identity_pagetable)) {
printk(KERN_ERR "EPT: identity-mapping pagetable "
@@ -2071,7 +2087,7 @@ static void allocate_vpid(struct vcpu_vmx *vmx)
int vpid;
vmx->vpid = 0;
- if (!enable_vpid || !cpu_has_vmx_vpid())
+ if (!enable_vpid)
return;
spin_lock(&vmx_vpid_lock);
vpid = find_first_zero_bit(vmx_vpid_bitmap, VMX_NR_VPIDS);
@@ -2082,9 +2098,9 @@ static void allocate_vpid(struct vcpu_vmx *vmx)
spin_unlock(&vmx_vpid_lock);
}
-static void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr)
+static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, u32 msr)
{
- void *va;
+ int f = sizeof(unsigned long);
if (!cpu_has_vmx_msr_bitmap())
return;
@@ -2094,16 +2110,21 @@ static void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr)
* have the write-low and read-high bitmap offsets the wrong way round.
* We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
*/
- va = kmap(msr_bitmap);
if (msr <= 0x1fff) {
- __clear_bit(msr, va + 0x000); /* read-low */
- __clear_bit(msr, va + 0x800); /* write-low */
+ __clear_bit(msr, msr_bitmap + 0x000 / f); /* read-low */
+ __clear_bit(msr, msr_bitmap + 0x800 / f); /* write-low */
} else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) {
msr &= 0x1fff;
- __clear_bit(msr, va + 0x400); /* read-high */
- __clear_bit(msr, va + 0xc00); /* write-high */
+ __clear_bit(msr, msr_bitmap + 0x400 / f); /* read-high */
+ __clear_bit(msr, msr_bitmap + 0xc00 / f); /* write-high */
}
- kunmap(msr_bitmap);
+}
+
+static void vmx_disable_intercept_for_msr(u32 msr, bool longmode_only)
+{
+ if (!longmode_only)
+ __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy, msr);
+ __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode, msr);
}
/*
@@ -2121,11 +2142,11 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
u32 exec_control;
/* I/O */
- vmcs_write64(IO_BITMAP_A, page_to_phys(vmx_io_bitmap_a));
- vmcs_write64(IO_BITMAP_B, page_to_phys(vmx_io_bitmap_b));
+ vmcs_write64(IO_BITMAP_A, __pa(vmx_io_bitmap_a));
+ vmcs_write64(IO_BITMAP_B, __pa(vmx_io_bitmap_b));
if (cpu_has_vmx_msr_bitmap())
- vmcs_write64(MSR_BITMAP, page_to_phys(vmx_msr_bitmap));
+ vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap_legacy));
vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */
@@ -2141,7 +2162,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
CPU_BASED_CR8_LOAD_EXITING;
#endif
}
- if (!vm_need_ept())
+ if (!enable_ept)
exec_control |= CPU_BASED_CR3_STORE_EXITING |
CPU_BASED_CR3_LOAD_EXITING |
CPU_BASED_INVLPG_EXITING;
@@ -2154,7 +2175,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
if (vmx->vpid == 0)
exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
- if (!vm_need_ept())
+ if (!enable_ept)
exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
}
@@ -2379,6 +2400,12 @@ out:
return ret;
}
+void vmx_drop_interrupt_shadow(struct kvm_vcpu *vcpu)
+{
+ vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+ GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS);
+}
+
static void enable_irq_window(struct kvm_vcpu *vcpu)
{
u32 cpu_based_vm_exec_control;
@@ -2456,76 +2483,21 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR);
}
-static void vmx_update_window_states(struct kvm_vcpu *vcpu)
+static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
{
- u32 guest_intr = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
-
- vcpu->arch.nmi_window_open =
- !(guest_intr & (GUEST_INTR_STATE_STI |
- GUEST_INTR_STATE_MOV_SS |
- GUEST_INTR_STATE_NMI));
if (!cpu_has_virtual_nmis() && to_vmx(vcpu)->soft_vnmi_blocked)
- vcpu->arch.nmi_window_open = 0;
-
- vcpu->arch.interrupt_window_open =
- ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&
- !(guest_intr & (GUEST_INTR_STATE_STI |
- GUEST_INTR_STATE_MOV_SS)));
-}
-
-static void kvm_do_inject_irq(struct kvm_vcpu *vcpu)
-{
- int word_index = __ffs(vcpu->arch.irq_summary);
- int bit_index = __ffs(vcpu->arch.irq_pending[word_index]);
- int irq = word_index * BITS_PER_LONG + bit_index;
+ return 0;
- clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
- if (!vcpu->arch.irq_pending[word_index])
- clear_bit(word_index, &vcpu->arch.irq_summary);
- kvm_queue_interrupt(vcpu, irq);
+ return !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
+ (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS |
+ GUEST_INTR_STATE_NMI));
}
-static void do_interrupt_requests(struct kvm_vcpu *vcpu,
- struct kvm_run *kvm_run)
+static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
{
- vmx_update_window_states(vcpu);
-
- if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
- vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
- GUEST_INTR_STATE_STI |
- GUEST_INTR_STATE_MOV_SS);
-
- if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
- if (vcpu->arch.interrupt.pending) {
- enable_nmi_window(vcpu);
- } else if (vcpu->arch.nmi_window_open) {
- vcpu->arch.nmi_pending = false;
- vcpu->arch.nmi_injected = true;
- } else {
- enable_nmi_window(vcpu);
- return;
- }
- }
- if (vcpu->arch.nmi_injected) {
- vmx_inject_nmi(vcpu);
- if (vcpu->arch.nmi_pending)
- enable_nmi_window(vcpu);
- else if (vcpu->arch.irq_summary
- || kvm_run->request_interrupt_window)
- enable_irq_window(vcpu);
- return;
- }
-
- if (vcpu->arch.interrupt_window_open) {
- if (vcpu->arch.irq_summary && !vcpu->arch.interrupt.pending)
- kvm_do_inject_irq(vcpu);
-
- if (vcpu->arch.interrupt.pending)
- vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr);
- }
- if (!vcpu->arch.interrupt_window_open &&
- (vcpu->arch.irq_summary || kvm_run->request_interrupt_window))
- enable_irq_window(vcpu);
+ return (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&
+ !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
+ (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS));
}
static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
@@ -2601,12 +2573,6 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
printk(KERN_ERR "%s: unexpected, vectoring info 0x%x "
"intr info 0x%x\n", __func__, vect_info, intr_info);
- if (!irqchip_in_kernel(vcpu->kvm) && is_external_interrupt(vect_info)) {
- int irq = vect_info & VECTORING_INFO_VECTOR_MASK;
- set_bit(irq, vcpu->arch.irq_pending);
- set_bit(irq / BITS_PER_LONG, &vcpu->arch.irq_summary);
- }
-
if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR)
return 1; /* already handled by vmx_vcpu_run() */
@@ -2628,7 +2594,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
if (is_page_fault(intr_info)) {
/* EPT won't cause page fault directly */
- if (vm_need_ept())
+ if (enable_ept)
BUG();
cr2 = vmcs_readl(EXIT_QUALIFICATION);
KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2,
@@ -2753,13 +2719,18 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_set_cr4(vcpu, kvm_register_read(vcpu, reg));
skip_emulated_instruction(vcpu);
return 1;
- case 8:
- kvm_set_cr8(vcpu, kvm_register_read(vcpu, reg));
- skip_emulated_instruction(vcpu);
- if (irqchip_in_kernel(vcpu->kvm))
- return 1;
- kvm_run->exit_reason = KVM_EXIT_SET_TPR;
- return 0;
+ case 8: {
+ u8 cr8_prev = kvm_get_cr8(vcpu);
+ u8 cr8 = kvm_register_read(vcpu, reg);
+ kvm_set_cr8(vcpu, cr8);
+ skip_emulated_instruction(vcpu);
+ if (irqchip_in_kernel(vcpu->kvm))
+ return 1;
+ if (cr8_prev <= cr8)
+ return 1;
+ kvm_run->exit_reason = KVM_EXIT_SET_TPR;
+ return 0;
+ }
};
break;
case 2: /* clts */
@@ -2957,8 +2928,9 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu,
* If the user space waits to inject interrupts, exit as soon as
* possible
*/
- if (kvm_run->request_interrupt_window &&
- !vcpu->arch.irq_summary) {
+ if (!irqchip_in_kernel(vcpu->kvm) &&
+ kvm_run->request_interrupt_window &&
+ !kvm_cpu_has_interrupt(vcpu)) {
kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
return 0;
}
@@ -2980,7 +2952,7 @@ static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
- u64 exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
+ unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
kvm_mmu_invlpg(vcpu, exit_qualification);
skip_emulated_instruction(vcpu);
@@ -2996,11 +2968,11 @@ static int handle_wbinvd(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
- u64 exit_qualification;
+ unsigned long exit_qualification;
enum emulation_result er;
unsigned long offset;
- exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
+ exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
offset = exit_qualification & 0xffful;
er = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
@@ -3019,22 +2991,40 @@ static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
struct vcpu_vmx *vmx = to_vmx(vcpu);
unsigned long exit_qualification;
u16 tss_selector;
- int reason;
+ int reason, type, idt_v;
+
+ idt_v = (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK);
+ type = (vmx->idt_vectoring_info & VECTORING_INFO_TYPE_MASK);
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
reason = (u32)exit_qualification >> 30;
- if (reason == TASK_SWITCH_GATE && vmx->vcpu.arch.nmi_injected &&
- (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK) &&
- (vmx->idt_vectoring_info & VECTORING_INFO_TYPE_MASK)
- == INTR_TYPE_NMI_INTR) {
- vcpu->arch.nmi_injected = false;
- if (cpu_has_virtual_nmis())
- vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
- GUEST_INTR_STATE_NMI);
+ if (reason == TASK_SWITCH_GATE && idt_v) {
+ switch (type) {
+ case INTR_TYPE_NMI_INTR:
+ vcpu->arch.nmi_injected = false;
+ if (cpu_has_virtual_nmis())
+ vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
+ GUEST_INTR_STATE_NMI);
+ break;
+ case INTR_TYPE_EXT_INTR:
+ kvm_clear_interrupt_queue(vcpu);
+ break;
+ case INTR_TYPE_HARD_EXCEPTION:
+ case INTR_TYPE_SOFT_EXCEPTION:
+ kvm_clear_exception_queue(vcpu);
+ break;
+ default:
+ break;
+ }
}
tss_selector = exit_qualification;
+ if (!idt_v || (type != INTR_TYPE_HARD_EXCEPTION &&
+ type != INTR_TYPE_EXT_INTR &&
+ type != INTR_TYPE_NMI_INTR))
+ skip_emulated_instruction(vcpu);
+
if (!kvm_task_switch(vcpu, tss_selector, reason))
return 0;
@@ -3051,11 +3041,11 @@ static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
- u64 exit_qualification;
+ unsigned long exit_qualification;
gpa_t gpa;
int gla_validity;
- exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
+ exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
if (exit_qualification & (1 << 6)) {
printk(KERN_ERR "EPT: GPA exceeds GAW!\n");
@@ -3067,7 +3057,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
printk(KERN_ERR "EPT: Handling EPT violation failed!\n");
printk(KERN_ERR "EPT: GPA: 0x%lx, GVA: 0x%lx\n",
(long unsigned int)vmcs_read64(GUEST_PHYSICAL_ADDRESS),
- (long unsigned int)vmcs_read64(GUEST_LINEAR_ADDRESS));
+ vmcs_readl(GUEST_LINEAR_ADDRESS));
printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n",
(long unsigned int)exit_qualification);
kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
@@ -3159,7 +3149,7 @@ static const int kvm_vmx_max_exit_handlers =
* The guest has exited. See if we can fix it or if we need userspace
* assistance.
*/
-static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
+static int vmx_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
{
u32 exit_reason = vmcs_read32(VM_EXIT_REASON);
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -3178,7 +3168,7 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
/* Access CR3 don't cause VMExit in paging mode, so we need
* to sync with guest real CR3. */
- if (vm_need_ept() && is_paging(vcpu)) {
+ if (enable_ept && is_paging(vcpu)) {
vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
ept_load_pdptrs(vcpu);
}
@@ -3199,9 +3189,8 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
__func__, vectoring_info, exit_reason);
if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked)) {
- if (vcpu->arch.interrupt_window_open) {
+ if (vmx_interrupt_allowed(vcpu)) {
vmx->soft_vnmi_blocked = 0;
- vcpu->arch.nmi_window_open = 1;
} else if (vmx->vnmi_blocked_time > 1000000000LL &&
vcpu->arch.nmi_pending) {
/*
@@ -3214,7 +3203,6 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
"state on VCPU %d after 1 s timeout\n",
__func__, vcpu->vcpu_id);
vmx->soft_vnmi_blocked = 0;
- vmx->vcpu.arch.nmi_window_open = 1;
}
}
@@ -3228,122 +3216,82 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
return 0;
}
-static void update_tpr_threshold(struct kvm_vcpu *vcpu)
+static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
{
- int max_irr, tpr;
-
- if (!vm_need_tpr_shadow(vcpu->kvm))
- return;
-
- if (!kvm_lapic_enabled(vcpu) ||
- ((max_irr = kvm_lapic_find_highest_irr(vcpu)) == -1)) {
+ if (irr == -1 || tpr < irr) {
vmcs_write32(TPR_THRESHOLD, 0);
return;
}
- tpr = (kvm_lapic_get_cr8(vcpu) & 0x0f) << 4;
- vmcs_write32(TPR_THRESHOLD, (max_irr > tpr) ? tpr >> 4 : max_irr >> 4);
+ vmcs_write32(TPR_THRESHOLD, irr);
}
static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
{
u32 exit_intr_info;
- u32 idt_vectoring_info;
+ u32 idt_vectoring_info = vmx->idt_vectoring_info;
bool unblock_nmi;
u8 vector;
int type;
bool idtv_info_valid;
- u32 error;
+ idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
if (cpu_has_virtual_nmis()) {
unblock_nmi = (exit_intr_info & INTR_INFO_UNBLOCK_NMI) != 0;
vector = exit_intr_info & INTR_INFO_VECTOR_MASK;
/*
- * SDM 3: 25.7.1.2
+ * SDM 3: 27.7.1.2 (September 2008)
* Re-set bit "block by NMI" before VM entry if vmexit caused by
* a guest IRET fault.
+ * SDM 3: 23.2.2 (September 2008)
+ * Bit 12 is undefined in any of the following cases:
+ * If the VM exit sets the valid bit in the IDT-vectoring
+ * information field.
+ * If the VM exit is due to a double fault.
*/
- if (unblock_nmi && vector != DF_VECTOR)
+ if ((exit_intr_info & INTR_INFO_VALID_MASK) && unblock_nmi &&
+ vector != DF_VECTOR && !idtv_info_valid)
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
GUEST_INTR_STATE_NMI);
} else if (unlikely(vmx->soft_vnmi_blocked))
vmx->vnmi_blocked_time +=
ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
- idt_vectoring_info = vmx->idt_vectoring_info;
- idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
+ vmx->vcpu.arch.nmi_injected = false;
+ kvm_clear_exception_queue(&vmx->vcpu);
+ kvm_clear_interrupt_queue(&vmx->vcpu);
+
+ if (!idtv_info_valid)
+ return;
+
vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK;
type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK;
- if (vmx->vcpu.arch.nmi_injected) {
+
+ switch (type) {
+ case INTR_TYPE_NMI_INTR:
+ vmx->vcpu.arch.nmi_injected = true;
/*
- * SDM 3: 25.7.1.2
- * Clear bit "block by NMI" before VM entry if a NMI delivery
- * faulted.
+ * SDM 3: 27.7.1.2 (September 2008)
+ * Clear bit "block by NMI" before VM entry if a NMI
+ * delivery faulted.
*/
- if (idtv_info_valid && type == INTR_TYPE_NMI_INTR)
- vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
- GUEST_INTR_STATE_NMI);
- else
- vmx->vcpu.arch.nmi_injected = false;
- }
- kvm_clear_exception_queue(&vmx->vcpu);
- if (idtv_info_valid && (type == INTR_TYPE_HARD_EXCEPTION ||
- type == INTR_TYPE_SOFT_EXCEPTION)) {
+ vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+ GUEST_INTR_STATE_NMI);
+ break;
+ case INTR_TYPE_HARD_EXCEPTION:
+ case INTR_TYPE_SOFT_EXCEPTION:
if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) {
- error = vmcs_read32(IDT_VECTORING_ERROR_CODE);
- kvm_queue_exception_e(&vmx->vcpu, vector, error);
+ u32 err = vmcs_read32(IDT_VECTORING_ERROR_CODE);
+ kvm_queue_exception_e(&vmx->vcpu, vector, err);
} else
kvm_queue_exception(&vmx->vcpu, vector);
- vmx->idt_vectoring_info = 0;
- }
- kvm_clear_interrupt_queue(&vmx->vcpu);
- if (idtv_info_valid && type == INTR_TYPE_EXT_INTR) {
+ break;
+ case INTR_TYPE_EXT_INTR:
kvm_queue_interrupt(&vmx->vcpu, vector);
- vmx->idt_vectoring_info = 0;
- }
-}
-
-static void vmx_intr_assist(struct kvm_vcpu *vcpu)
-{
- update_tpr_threshold(vcpu);
-
- vmx_update_window_states(vcpu);
-
- if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
- vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
- GUEST_INTR_STATE_STI |
- GUEST_INTR_STATE_MOV_SS);
-
- if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
- if (vcpu->arch.interrupt.pending) {
- enable_nmi_window(vcpu);
- } else if (vcpu->arch.nmi_window_open) {
- vcpu->arch.nmi_pending = false;
- vcpu->arch.nmi_injected = true;
- } else {
- enable_nmi_window(vcpu);
- return;
- }
- }
- if (vcpu->arch.nmi_injected) {
- vmx_inject_nmi(vcpu);
- if (vcpu->arch.nmi_pending)
- enable_nmi_window(vcpu);
- else if (kvm_cpu_has_interrupt(vcpu))
- enable_irq_window(vcpu);
- return;
- }
- if (!vcpu->arch.interrupt.pending && kvm_cpu_has_interrupt(vcpu)) {
- if (vcpu->arch.interrupt_window_open)
- kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu));
- else
- enable_irq_window(vcpu);
- }
- if (vcpu->arch.interrupt.pending) {
- vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr);
- if (kvm_cpu_has_interrupt(vcpu))
- enable_irq_window(vcpu);
+ break;
+ default:
+ break;
}
}
@@ -3505,8 +3453,6 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
if (vmx->rmode.irq.pending)
fixup_rmode_irq(vmx);
- vmx_update_window_states(vcpu);
-
asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
vmx->launched = 1;
@@ -3593,7 +3539,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
if (alloc_apic_access_page(kvm) != 0)
goto free_vmcs;
- if (vm_need_ept())
+ if (enable_ept)
if (alloc_identity_pagetable(kvm) != 0)
goto free_vmcs;
@@ -3631,9 +3577,32 @@ static int get_ept_level(void)
return VMX_EPT_DEFAULT_GAW + 1;
}
-static int vmx_get_mt_mask_shift(void)
+static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
{
- return VMX_EPT_MT_EPTE_SHIFT;
+ u64 ret;
+
+ /* For VT-d and EPT combination
+ * 1. MMIO: always map as UC
+ * 2. EPT with VT-d:
+ * a. VT-d without snooping control feature: can't guarantee the
+ * result, try to trust guest.
+ * b. VT-d with snooping control feature: snooping control feature of
+ * VT-d engine can guarantee the cache correctness. Just set it
+ * to WB to keep consistent with host. So the same as item 3.
+ * 3. EPT without VT-d: always map as WB and set IGMT=1 to keep
+ * consistent with host MTRR
+ */
+ if (is_mmio)
+ ret = MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT;
+ else if (vcpu->kvm->arch.iommu_domain &&
+ !(vcpu->kvm->arch.iommu_flags & KVM_IOMMU_CACHE_COHERENCY))
+ ret = kvm_get_guest_memory_type(vcpu, gfn) <<
+ VMX_EPT_MT_EPTE_SHIFT;
+ else
+ ret = (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT)
+ | VMX_EPT_IGMT_BIT;
+
+ return ret;
}
static struct kvm_x86_ops vmx_x86_ops = {
@@ -3644,7 +3613,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
.check_processor_compatibility = vmx_check_processor_compat,
.hardware_enable = hardware_enable,
.hardware_disable = hardware_disable,
- .cpu_has_accelerated_tpr = cpu_has_vmx_virtualize_apic_accesses,
+ .cpu_has_accelerated_tpr = report_flexpriority,
.vcpu_create = vmx_create_vcpu,
.vcpu_free = vmx_free_vcpu,
@@ -3678,78 +3647,81 @@ static struct kvm_x86_ops vmx_x86_ops = {
.tlb_flush = vmx_flush_tlb,
.run = vmx_vcpu_run,
- .handle_exit = kvm_handle_exit,
+ .handle_exit = vmx_handle_exit,
.skip_emulated_instruction = skip_emulated_instruction,
.patch_hypercall = vmx_patch_hypercall,
- .get_irq = vmx_get_irq,
.set_irq = vmx_inject_irq,
+ .set_nmi = vmx_inject_nmi,
.queue_exception = vmx_queue_exception,
- .exception_injected = vmx_exception_injected,
- .inject_pending_irq = vmx_intr_assist,
- .inject_pending_vectors = do_interrupt_requests,
+ .interrupt_allowed = vmx_interrupt_allowed,
+ .nmi_allowed = vmx_nmi_allowed,
+ .enable_nmi_window = enable_nmi_window,
+ .enable_irq_window = enable_irq_window,
+ .update_cr8_intercept = update_cr8_intercept,
+ .drop_interrupt_shadow = vmx_drop_interrupt_shadow,
.set_tss_addr = vmx_set_tss_addr,
.get_tdp_level = get_ept_level,
- .get_mt_mask_shift = vmx_get_mt_mask_shift,
+ .get_mt_mask = vmx_get_mt_mask,
};
static int __init vmx_init(void)
{
- void *va;
int r;
- vmx_io_bitmap_a = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
+ vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL);
if (!vmx_io_bitmap_a)
return -ENOMEM;
- vmx_io_bitmap_b = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
+ vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL);
if (!vmx_io_bitmap_b) {
r = -ENOMEM;
goto out;
}
- vmx_msr_bitmap = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
- if (!vmx_msr_bitmap) {
+ vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL);
+ if (!vmx_msr_bitmap_legacy) {
r = -ENOMEM;
goto out1;
}
+ vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL);
+ if (!vmx_msr_bitmap_longmode) {
+ r = -ENOMEM;
+ goto out2;
+ }
+
/*
* Allow direct access to the PC debug port (it is often used for I/O
* delays, but the vmexits simply slow things down).
*/
- va = kmap(vmx_io_bitmap_a);
- memset(va, 0xff, PAGE_SIZE);
- clear_bit(0x80, va);
- kunmap(vmx_io_bitmap_a);
+ memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE);
+ clear_bit(0x80, vmx_io_bitmap_a);
- va = kmap(vmx_io_bitmap_b);
- memset(va, 0xff, PAGE_SIZE);
- kunmap(vmx_io_bitmap_b);
+ memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE);
- va = kmap(vmx_msr_bitmap);
- memset(va, 0xff, PAGE_SIZE);
- kunmap(vmx_msr_bitmap);
+ memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
+ memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */
r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx), THIS_MODULE);
if (r)
- goto out2;
+ goto out3;
- vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_FS_BASE);
- vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_GS_BASE);
- vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_CS);
- vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_ESP);
- vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_EIP);
+ vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
+ vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
+ vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
+ vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
+ vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
+ vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
- if (vm_need_ept()) {
+ if (enable_ept) {
bypass_guest_pf = 0;
kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
VMX_EPT_WRITABLE_MASK);
kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull,
- VMX_EPT_EXECUTABLE_MASK,
- VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT);
+ VMX_EPT_EXECUTABLE_MASK);
kvm_enable_tdp();
} else
kvm_disable_tdp();
@@ -3761,20 +3733,23 @@ static int __init vmx_init(void)
return 0;
+out3:
+ free_page((unsigned long)vmx_msr_bitmap_longmode);
out2:
- __free_page(vmx_msr_bitmap);
+ free_page((unsigned long)vmx_msr_bitmap_legacy);
out1:
- __free_page(vmx_io_bitmap_b);
+ free_page((unsigned long)vmx_io_bitmap_b);
out:
- __free_page(vmx_io_bitmap_a);
+ free_page((unsigned long)vmx_io_bitmap_a);
return r;
}
static void __exit vmx_exit(void)
{
- __free_page(vmx_msr_bitmap);
- __free_page(vmx_io_bitmap_b);
- __free_page(vmx_io_bitmap_a);
+ free_page((unsigned long)vmx_msr_bitmap_legacy);
+ free_page((unsigned long)vmx_msr_bitmap_longmode);
+ free_page((unsigned long)vmx_io_bitmap_b);
+ free_page((unsigned long)vmx_io_bitmap_a);
kvm_exit();
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7c1ce5ac6131..fd0a5719f117 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -91,7 +91,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "halt_wakeup", VCPU_STAT(halt_wakeup) },
{ "hypercalls", VCPU_STAT(hypercalls) },
{ "request_irq", VCPU_STAT(request_irq_exits) },
- { "request_nmi", VCPU_STAT(request_nmi_exits) },
{ "irq_exits", VCPU_STAT(irq_exits) },
{ "host_state_reload", VCPU_STAT(host_state_reload) },
{ "efer_reload", VCPU_STAT(efer_reload) },
@@ -108,7 +107,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "mmu_recycled", VM_STAT(mmu_recycled) },
{ "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
{ "mmu_unsync", VM_STAT(mmu_unsync) },
- { "mmu_unsync_global", VM_STAT(mmu_unsync_global) },
{ "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
{ "largepages", VM_STAT(lpages) },
{ NULL }
@@ -234,7 +232,8 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
goto out;
}
for (i = 0; i < ARRAY_SIZE(pdpte); ++i) {
- if ((pdpte[i] & 1) && (pdpte[i] & 0xfffffff0000001e6ull)) {
+ if (is_present_pte(pdpte[i]) &&
+ (pdpte[i] & vcpu->arch.mmu.rsvd_bits_mask[0][2])) {
ret = 0;
goto out;
}
@@ -321,7 +320,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
kvm_x86_ops->set_cr0(vcpu, cr0);
vcpu->arch.cr0 = cr0;
- kvm_mmu_sync_global(vcpu);
kvm_mmu_reset_context(vcpu);
return;
}
@@ -366,7 +364,6 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
kvm_x86_ops->set_cr4(vcpu, cr4);
vcpu->arch.cr4 = cr4;
vcpu->arch.mmu.base_role.cr4_pge = (cr4 & X86_CR4_PGE) && !tdp_enabled;
- kvm_mmu_sync_global(vcpu);
kvm_mmu_reset_context(vcpu);
}
EXPORT_SYMBOL_GPL(kvm_set_cr4);
@@ -519,6 +516,9 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
efer |= vcpu->arch.shadow_efer & EFER_LMA;
vcpu->arch.shadow_efer = efer;
+
+ vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled;
+ kvm_mmu_reset_context(vcpu);
}
void kvm_enable_efer_bits(u64 mask)
@@ -626,14 +626,17 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
unsigned long flags;
struct kvm_vcpu_arch *vcpu = &v->arch;
void *shared_kaddr;
+ unsigned long this_tsc_khz;
if ((!vcpu->time_page))
return;
- if (unlikely(vcpu->hv_clock_tsc_khz != __get_cpu_var(cpu_tsc_khz))) {
- kvm_set_time_scale(__get_cpu_var(cpu_tsc_khz), &vcpu->hv_clock);
- vcpu->hv_clock_tsc_khz = __get_cpu_var(cpu_tsc_khz);
+ this_tsc_khz = get_cpu_var(cpu_tsc_khz);
+ if (unlikely(vcpu->hv_clock_tsc_khz != this_tsc_khz)) {
+ kvm_set_time_scale(this_tsc_khz, &vcpu->hv_clock);
+ vcpu->hv_clock_tsc_khz = this_tsc_khz;
}
+ put_cpu_var(cpu_tsc_khz);
/* Keep irq disabled to prevent changes to the clock */
local_irq_save(flags);
@@ -889,6 +892,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_IA32_LASTINTFROMIP:
case MSR_IA32_LASTINTTOIP:
case MSR_VM_HSAVE_PA:
+ case MSR_P6_EVNTSEL0:
+ case MSR_P6_EVNTSEL1:
data = 0;
break;
case MSR_MTRRcap:
@@ -1020,6 +1025,7 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_SYNC_MMU:
case KVM_CAP_REINJECT_CONTROL:
case KVM_CAP_IRQ_INJECT_STATUS:
+ case KVM_CAP_ASSIGN_DEV_IRQ:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -1121,9 +1127,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
static int is_efer_nx(void)
{
- u64 efer;
+ unsigned long long efer = 0;
- rdmsrl(MSR_EFER, efer);
+ rdmsrl_safe(MSR_EFER, &efer);
return efer & EFER_NX;
}
@@ -1237,41 +1243,53 @@ static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function,
entry->flags = 0;
}
+#define F(x) bit(X86_FEATURE_##x)
+
static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
u32 index, int *nent, int maxnent)
{
- const u32 kvm_supported_word0_x86_features = bit(X86_FEATURE_FPU) |
- bit(X86_FEATURE_VME) | bit(X86_FEATURE_DE) |
- bit(X86_FEATURE_PSE) | bit(X86_FEATURE_TSC) |
- bit(X86_FEATURE_MSR) | bit(X86_FEATURE_PAE) |
- bit(X86_FEATURE_CX8) | bit(X86_FEATURE_APIC) |
- bit(X86_FEATURE_SEP) | bit(X86_FEATURE_PGE) |
- bit(X86_FEATURE_CMOV) | bit(X86_FEATURE_PSE36) |
- bit(X86_FEATURE_CLFLSH) | bit(X86_FEATURE_MMX) |
- bit(X86_FEATURE_FXSR) | bit(X86_FEATURE_XMM) |
- bit(X86_FEATURE_XMM2) | bit(X86_FEATURE_SELFSNOOP);
- const u32 kvm_supported_word1_x86_features = bit(X86_FEATURE_FPU) |
- bit(X86_FEATURE_VME) | bit(X86_FEATURE_DE) |
- bit(X86_FEATURE_PSE) | bit(X86_FEATURE_TSC) |
- bit(X86_FEATURE_MSR) | bit(X86_FEATURE_PAE) |
- bit(X86_FEATURE_CX8) | bit(X86_FEATURE_APIC) |
- bit(X86_FEATURE_PGE) |
- bit(X86_FEATURE_CMOV) | bit(X86_FEATURE_PSE36) |
- bit(X86_FEATURE_MMX) | bit(X86_FEATURE_FXSR) |
- bit(X86_FEATURE_SYSCALL) |
- (bit(X86_FEATURE_NX) && is_efer_nx()) |
+ unsigned f_nx = is_efer_nx() ? F(NX) : 0;
#ifdef CONFIG_X86_64
- bit(X86_FEATURE_LM) |
+ unsigned f_lm = F(LM);
+#else
+ unsigned f_lm = 0;
#endif
- bit(X86_FEATURE_FXSR_OPT) |
- bit(X86_FEATURE_MMXEXT) |
- bit(X86_FEATURE_3DNOWEXT) |
- bit(X86_FEATURE_3DNOW);
- const u32 kvm_supported_word3_x86_features =
- bit(X86_FEATURE_XMM3) | bit(X86_FEATURE_CX16);
+
+ /* cpuid 1.edx */
+ const u32 kvm_supported_word0_x86_features =
+ F(FPU) | F(VME) | F(DE) | F(PSE) |
+ F(TSC) | F(MSR) | F(PAE) | F(MCE) |
+ F(CX8) | F(APIC) | 0 /* Reserved */ | F(SEP) |
+ F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
+ F(PAT) | F(PSE36) | 0 /* PSN */ | F(CLFLSH) |
+ 0 /* Reserved, DS, ACPI */ | F(MMX) |
+ F(FXSR) | F(XMM) | F(XMM2) | F(SELFSNOOP) |
+ 0 /* HTT, TM, Reserved, PBE */;
+ /* cpuid 0x80000001.edx */
+ const u32 kvm_supported_word1_x86_features =
+ F(FPU) | F(VME) | F(DE) | F(PSE) |
+ F(TSC) | F(MSR) | F(PAE) | F(MCE) |
+ F(CX8) | F(APIC) | 0 /* Reserved */ | F(SYSCALL) |
+ F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
+ F(PAT) | F(PSE36) | 0 /* Reserved */ |
+ f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) |
+ F(FXSR) | F(FXSR_OPT) | 0 /* GBPAGES */ | 0 /* RDTSCP */ |
+ 0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW);
+ /* cpuid 1.ecx */
+ const u32 kvm_supported_word4_x86_features =
+ F(XMM3) | 0 /* Reserved, DTES64, MONITOR */ |
+ 0 /* DS-CPL, VMX, SMX, EST */ |
+ 0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ |
+ 0 /* Reserved */ | F(CX16) | 0 /* xTPR Update, PDCM */ |
+ 0 /* Reserved, DCA */ | F(XMM4_1) |
+ F(XMM4_2) | 0 /* x2APIC */ | F(MOVBE) | F(POPCNT) |
+ 0 /* Reserved, XSAVE, OSXSAVE */;
+ /* cpuid 0x80000001.ecx */
const u32 kvm_supported_word6_x86_features =
- bit(X86_FEATURE_LAHF_LM) | bit(X86_FEATURE_CMP_LEGACY) |
- bit(X86_FEATURE_SVM);
+ F(LAHF_LM) | F(CMP_LEGACY) | F(SVM) | 0 /* ExtApicSpace */ |
+ F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) |
+ F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(SSE5) |
+ 0 /* SKINIT */ | 0 /* WDT */;
/* all calls to cpuid_count() should be made on the same cpu */
get_cpu();
@@ -1284,7 +1302,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
break;
case 1:
entry->edx &= kvm_supported_word0_x86_features;
- entry->ecx &= kvm_supported_word3_x86_features;
+ entry->ecx &= kvm_supported_word4_x86_features;
break;
/* function 2 entries are STATEFUL. That is, repeated cpuid commands
* may return different values. This forces us to get_cpu() before
@@ -1346,6 +1364,8 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
put_cpu();
}
+#undef F
+
static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *entries)
{
@@ -1580,8 +1600,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = -EINVAL;
}
out:
- if (lapic)
- kfree(lapic);
+ kfree(lapic);
return r;
}
@@ -2404,6 +2423,11 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
}
}
+ if (emulation_type & EMULTYPE_SKIP) {
+ kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.decode.eip);
+ return EMULATE_DONE;
+ }
+
r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
if (vcpu->arch.pio.string)
@@ -2757,7 +2781,7 @@ int kvm_arch_init(void *opaque)
kvm_mmu_set_nonpresent_ptes(0ull, 0ull);
kvm_mmu_set_base_ptes(PT_PRESENT_MASK);
kvm_mmu_set_mask_ptes(PT_USER_MASK, PT_ACCESSED_MASK,
- PT_DIRTY_MASK, PT64_NX_MASK, 0, 0);
+ PT_DIRTY_MASK, PT64_NX_MASK, 0);
for_each_possible_cpu(cpu)
per_cpu(cpu_tsc_khz, cpu) = tsc_khz;
@@ -3008,6 +3032,16 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
return best;
}
+int cpuid_maxphyaddr(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpuid_entry2 *best;
+
+ best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
+ if (best)
+ return best->eax & 0xff;
+ return 36;
+}
+
void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
{
u32 function, index;
@@ -3044,10 +3078,9 @@ EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu,
struct kvm_run *kvm_run)
{
- return (!vcpu->arch.irq_summary &&
+ return (!irqchip_in_kernel(vcpu->kvm) && !kvm_cpu_has_interrupt(vcpu) &&
kvm_run->request_interrupt_window &&
- vcpu->arch.interrupt_window_open &&
- (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF));
+ kvm_arch_interrupt_allowed(vcpu));
}
static void post_kvm_run_save(struct kvm_vcpu *vcpu,
@@ -3060,8 +3093,8 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu,
kvm_run->ready_for_interrupt_injection = 1;
else
kvm_run->ready_for_interrupt_injection =
- (vcpu->arch.interrupt_window_open &&
- vcpu->arch.irq_summary == 0);
+ (kvm_arch_interrupt_allowed(vcpu) &&
+ !kvm_cpu_has_interrupt(vcpu));
}
static void vapic_enter(struct kvm_vcpu *vcpu)
@@ -3090,6 +3123,68 @@ static void vapic_exit(struct kvm_vcpu *vcpu)
up_read(&vcpu->kvm->slots_lock);
}
+static void update_cr8_intercept(struct kvm_vcpu *vcpu)
+{
+ int max_irr, tpr;
+
+ if (!kvm_x86_ops->update_cr8_intercept)
+ return;
+
+ max_irr = kvm_lapic_find_highest_irr(vcpu);
+
+ if (max_irr != -1)
+ max_irr >>= 4;
+
+ tpr = kvm_lapic_get_cr8(vcpu);
+
+ kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr);
+}
+
+static void inject_irq(struct kvm_vcpu *vcpu)
+{
+ /* try to reinject previous events if any */
+ if (vcpu->arch.nmi_injected) {
+ kvm_x86_ops->set_nmi(vcpu);
+ return;
+ }
+
+ if (vcpu->arch.interrupt.pending) {
+ kvm_x86_ops->set_irq(vcpu, vcpu->arch.interrupt.nr);
+ return;
+ }
+
+ /* try to inject new event if pending */
+ if (vcpu->arch.nmi_pending) {
+ if (kvm_x86_ops->nmi_allowed(vcpu)) {
+ vcpu->arch.nmi_pending = false;
+ vcpu->arch.nmi_injected = true;
+ kvm_x86_ops->set_nmi(vcpu);
+ }
+ } else if (kvm_cpu_has_interrupt(vcpu)) {
+ if (kvm_x86_ops->interrupt_allowed(vcpu)) {
+ kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu));
+ kvm_x86_ops->set_irq(vcpu, vcpu->arch.interrupt.nr);
+ }
+ }
+}
+
+static void inject_pending_irq(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+ bool req_int_win = !irqchip_in_kernel(vcpu->kvm) &&
+ kvm_run->request_interrupt_window;
+
+ if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+ kvm_x86_ops->drop_interrupt_shadow(vcpu);
+
+ inject_irq(vcpu);
+
+ /* enable NMI/IRQ window open exits if needed */
+ if (vcpu->arch.nmi_pending)
+ kvm_x86_ops->enable_nmi_window(vcpu);
+ else if (kvm_cpu_has_interrupt(vcpu) || req_int_win)
+ kvm_x86_ops->enable_irq_window(vcpu);
+}
+
static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
int r;
@@ -3124,9 +3219,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
}
- clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
- kvm_inject_pending_timer_irqs(vcpu);
-
preempt_disable();
kvm_x86_ops->prepare_guest_switch(vcpu);
@@ -3134,6 +3226,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
local_irq_disable();
+ clear_bit(KVM_REQ_KICK, &vcpu->requests);
+ smp_mb__after_clear_bit();
+
if (vcpu->requests || need_resched() || signal_pending(current)) {
local_irq_enable();
preempt_enable();
@@ -3141,21 +3236,17 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
goto out;
}
- vcpu->guest_mode = 1;
- /*
- * Make sure that guest_mode assignment won't happen after
- * testing the pending IRQ vector bitmap.
- */
- smp_wmb();
-
if (vcpu->arch.exception.pending)
__queue_exception(vcpu);
- else if (irqchip_in_kernel(vcpu->kvm))
- kvm_x86_ops->inject_pending_irq(vcpu);
else
- kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run);
+ inject_pending_irq(vcpu, kvm_run);
- kvm_lapic_sync_to_vapic(vcpu);
+ if (kvm_lapic_enabled(vcpu)) {
+ if (!vcpu->arch.apic->vapic_addr)
+ update_cr8_intercept(vcpu);
+ else
+ kvm_lapic_sync_to_vapic(vcpu);
+ }
up_read(&vcpu->kvm->slots_lock);
@@ -3189,7 +3280,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
set_debugreg(vcpu->arch.host_dr6, 6);
set_debugreg(vcpu->arch.host_dr7, 7);
- vcpu->guest_mode = 0;
+ set_bit(KVM_REQ_KICK, &vcpu->requests);
local_irq_enable();
++vcpu->stat.exits;
@@ -3216,8 +3307,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
profile_hit(KVM_PROFILING, (void *)rip);
}
- if (vcpu->arch.exception.pending && kvm_x86_ops->exception_injected(vcpu))
- vcpu->arch.exception.pending = false;
kvm_lapic_sync_from_vapic(vcpu);
@@ -3226,6 +3315,7 @@ out:
return r;
}
+
static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
int r;
@@ -3252,29 +3342,42 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_vcpu_block(vcpu);
down_read(&vcpu->kvm->slots_lock);
if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests))
- if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED)
+ {
+ switch(vcpu->arch.mp_state) {
+ case KVM_MP_STATE_HALTED:
vcpu->arch.mp_state =
- KVM_MP_STATE_RUNNABLE;
- if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE)
- r = -EINTR;
+ KVM_MP_STATE_RUNNABLE;
+ case KVM_MP_STATE_RUNNABLE:
+ break;
+ case KVM_MP_STATE_SIPI_RECEIVED:
+ default:
+ r = -EINTR;
+ break;
+ }
+ }
}
- if (r > 0) {
- if (dm_request_for_irq_injection(vcpu, kvm_run)) {
- r = -EINTR;
- kvm_run->exit_reason = KVM_EXIT_INTR;
- ++vcpu->stat.request_irq_exits;
- }
- if (signal_pending(current)) {
- r = -EINTR;
- kvm_run->exit_reason = KVM_EXIT_INTR;
- ++vcpu->stat.signal_exits;
- }
- if (need_resched()) {
- up_read(&vcpu->kvm->slots_lock);
- kvm_resched(vcpu);
- down_read(&vcpu->kvm->slots_lock);
- }
+ if (r <= 0)
+ break;
+
+ clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
+ if (kvm_cpu_has_pending_timer(vcpu))
+ kvm_inject_pending_timer_irqs(vcpu);
+
+ if (dm_request_for_irq_injection(vcpu, kvm_run)) {
+ r = -EINTR;
+ kvm_run->exit_reason = KVM_EXIT_INTR;
+ ++vcpu->stat.request_irq_exits;
+ }
+ if (signal_pending(current)) {
+ r = -EINTR;
+ kvm_run->exit_reason = KVM_EXIT_INTR;
+ ++vcpu->stat.signal_exits;
+ }
+ if (need_resched()) {
+ up_read(&vcpu->kvm->slots_lock);
+ kvm_resched(vcpu);
+ down_read(&vcpu->kvm->slots_lock);
}
}
@@ -3438,7 +3541,6 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
struct kvm_sregs *sregs)
{
struct descriptor_table dt;
- int pending_vec;
vcpu_load(vcpu);
@@ -3468,17 +3570,17 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
sregs->efer = vcpu->arch.shadow_efer;
sregs->apic_base = kvm_get_apic_base(vcpu);
- if (irqchip_in_kernel(vcpu->kvm)) {
+ if (irqchip_in_kernel(vcpu->kvm))
memset(sregs->interrupt_bitmap, 0,
sizeof sregs->interrupt_bitmap);
- pending_vec = kvm_x86_ops->get_irq(vcpu);
- if (pending_vec >= 0)
- set_bit(pending_vec,
- (unsigned long *)sregs->interrupt_bitmap);
- } else
+ else
memcpy(sregs->interrupt_bitmap, vcpu->arch.irq_pending,
sizeof sregs->interrupt_bitmap);
+ if (vcpu->arch.interrupt.pending)
+ set_bit(vcpu->arch.interrupt.nr,
+ (unsigned long *)sregs->interrupt_bitmap);
+
vcpu_put(vcpu);
return 0;
@@ -3684,7 +3786,6 @@ static void save_state_to_tss32(struct kvm_vcpu *vcpu,
tss->fs = get_segment_selector(vcpu, VCPU_SREG_FS);
tss->gs = get_segment_selector(vcpu, VCPU_SREG_GS);
tss->ldt_selector = get_segment_selector(vcpu, VCPU_SREG_LDTR);
- tss->prev_task_link = get_segment_selector(vcpu, VCPU_SREG_TR);
}
static int load_state_from_tss32(struct kvm_vcpu *vcpu,
@@ -3781,8 +3882,8 @@ static int load_state_from_tss16(struct kvm_vcpu *vcpu,
}
static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
- u32 old_tss_base,
- struct desc_struct *nseg_desc)
+ u16 old_tss_sel, u32 old_tss_base,
+ struct desc_struct *nseg_desc)
{
struct tss_segment_16 tss_segment_16;
int ret = 0;
@@ -3801,6 +3902,16 @@ static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
&tss_segment_16, sizeof tss_segment_16))
goto out;
+ if (old_tss_sel != 0xffff) {
+ tss_segment_16.prev_task_link = old_tss_sel;
+
+ if (kvm_write_guest(vcpu->kvm,
+ get_tss_base_addr(vcpu, nseg_desc),
+ &tss_segment_16.prev_task_link,
+ sizeof tss_segment_16.prev_task_link))
+ goto out;
+ }
+
if (load_state_from_tss16(vcpu, &tss_segment_16))
goto out;
@@ -3810,7 +3921,7 @@ out:
}
static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
- u32 old_tss_base,
+ u16 old_tss_sel, u32 old_tss_base,
struct desc_struct *nseg_desc)
{
struct tss_segment_32 tss_segment_32;
@@ -3830,6 +3941,16 @@ static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
&tss_segment_32, sizeof tss_segment_32))
goto out;
+ if (old_tss_sel != 0xffff) {
+ tss_segment_32.prev_task_link = old_tss_sel;
+
+ if (kvm_write_guest(vcpu->kvm,
+ get_tss_base_addr(vcpu, nseg_desc),
+ &tss_segment_32.prev_task_link,
+ sizeof tss_segment_32.prev_task_link))
+ goto out;
+ }
+
if (load_state_from_tss32(vcpu, &tss_segment_32))
goto out;
@@ -3883,14 +4004,22 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
kvm_x86_ops->set_rflags(vcpu, eflags & ~X86_EFLAGS_NT);
}
- kvm_x86_ops->skip_emulated_instruction(vcpu);
+ /* set back link to prev task only if NT bit is set in eflags
+ note that old_tss_sel is not used afetr this point */
+ if (reason != TASK_SWITCH_CALL && reason != TASK_SWITCH_GATE)
+ old_tss_sel = 0xffff;
+
+ /* set back link to prev task only if NT bit is set in eflags
+ note that old_tss_sel is not used afetr this point */
+ if (reason != TASK_SWITCH_CALL && reason != TASK_SWITCH_GATE)
+ old_tss_sel = 0xffff;
if (nseg_desc.type & 8)
- ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_base,
- &nseg_desc);
+ ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_sel,
+ old_tss_base, &nseg_desc);
else
- ret = kvm_task_switch_16(vcpu, tss_selector, old_tss_base,
- &nseg_desc);
+ ret = kvm_task_switch_16(vcpu, tss_selector, old_tss_sel,
+ old_tss_base, &nseg_desc);
if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) {
u32 eflags = kvm_x86_ops->get_rflags(vcpu);
@@ -3930,7 +4059,13 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
vcpu->arch.cr2 = sregs->cr2;
mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3;
- vcpu->arch.cr3 = sregs->cr3;
+
+ down_read(&vcpu->kvm->slots_lock);
+ if (gfn_to_memslot(vcpu->kvm, sregs->cr3 >> PAGE_SHIFT))
+ vcpu->arch.cr3 = sregs->cr3;
+ else
+ set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
+ up_read(&vcpu->kvm->slots_lock);
kvm_set_cr8(vcpu, sregs->cr8);
@@ -3966,9 +4101,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
max_bits);
/* Only pending external irq is handled here */
if (pending_vec < max_bits) {
- kvm_x86_ops->set_irq(vcpu, pending_vec);
- pr_debug("Set back pending irq %d\n",
- pending_vec);
+ kvm_queue_interrupt(vcpu, pending_vec);
+ pr_debug("Set back pending irq %d\n", pending_vec);
}
kvm_pic_clear_isr_ack(vcpu->kvm);
}
@@ -4304,7 +4438,6 @@ struct kvm *kvm_arch_create_vm(void)
return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
- INIT_LIST_HEAD(&kvm->arch.oos_global_pages);
INIT_LIST_HEAD(&kvm->arch.assigned_dev_head);
/* Reserve bit 0 of irq_sources_bitmap for userspace irq source */
@@ -4430,28 +4563,24 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
|| vcpu->arch.nmi_pending;
}
-static void vcpu_kick_intr(void *info)
-{
-#ifdef DEBUG
- struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info;
- printk(KERN_DEBUG "vcpu_kick_intr %p \n", vcpu);
-#endif
-}
-
void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
{
- int ipi_pcpu = vcpu->cpu;
- int cpu = get_cpu();
+ int me;
+ int cpu = vcpu->cpu;
if (waitqueue_active(&vcpu->wq)) {
wake_up_interruptible(&vcpu->wq);
++vcpu->stat.halt_wakeup;
}
- /*
- * We may be called synchronously with irqs disabled in guest mode,
- * So need not to call smp_call_function_single() in that case.
- */
- if (vcpu->guest_mode && vcpu->cpu != cpu)
- smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0);
+
+ me = get_cpu();
+ if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu))
+ if (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests))
+ smp_send_reschedule(cpu);
put_cpu();
}
+
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
+{
+ return kvm_x86_ops->interrupt_allowed(vcpu);
+}
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 6a4be78a7384..39350b252725 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -19,4 +19,15 @@ static inline void kvm_clear_interrupt_queue(struct kvm_vcpu *vcpu)
vcpu->arch.interrupt.pending = false;
}
+static inline u8 kvm_pop_irq(struct kvm_vcpu *vcpu)
+{
+ int word_index = __ffs(vcpu->arch.irq_summary);
+ int bit_index = __ffs(vcpu->arch.irq_pending[word_index]);
+ int irq = word_index * BITS_PER_LONG + bit_index;
+
+ clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
+ if (!vcpu->arch.irq_pending[word_index])
+ clear_bit(word_index, &vcpu->arch.irq_summary);
+ return irq;
+}
#endif
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index ca91749d2083..d2664fcba7fa 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -59,13 +59,14 @@
#define SrcImm (5<<4) /* Immediate operand. */
#define SrcImmByte (6<<4) /* 8-bit sign-extended immediate operand. */
#define SrcOne (7<<4) /* Implied '1' */
-#define SrcMask (7<<4)
+#define SrcImmUByte (8<<4) /* 8-bit unsigned immediate operand. */
+#define SrcMask (0xf<<4)
/* Generic ModRM decode. */
-#define ModRM (1<<7)
+#define ModRM (1<<8)
/* Destination is only written; never read. */
-#define Mov (1<<8)
-#define BitOp (1<<9)
-#define MemAbs (1<<10) /* Memory operand is absolute displacement */
+#define Mov (1<<9)
+#define BitOp (1<<10)
+#define MemAbs (1<<11) /* Memory operand is absolute displacement */
#define String (1<<12) /* String instruction (rep capable) */
#define Stack (1<<13) /* Stack instruction (push/pop) */
#define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */
@@ -76,6 +77,7 @@
#define Src2CL (1<<29)
#define Src2ImmByte (2<<29)
#define Src2One (3<<29)
+#define Src2Imm16 (4<<29)
#define Src2Mask (7<<29)
enum {
@@ -135,11 +137,11 @@ static u32 opcode_table[256] = {
SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */
SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */
/* 0x70 - 0x77 */
- ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
- ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+ SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
+ SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
/* 0x78 - 0x7F */
- ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
- ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+ SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
+ SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
/* 0x80 - 0x87 */
Group | Group1_80, Group | Group1_81,
Group | Group1_82, Group | Group1_83,
@@ -153,7 +155,8 @@ static u32 opcode_table[256] = {
/* 0x90 - 0x97 */
DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
/* 0x98 - 0x9F */
- 0, 0, 0, 0, ImplicitOps | Stack, ImplicitOps | Stack, 0, 0,
+ 0, 0, SrcImm | Src2Imm16, 0,
+ ImplicitOps | Stack, ImplicitOps | Stack, 0, 0,
/* 0xA0 - 0xA7 */
ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs,
ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs,
@@ -178,7 +181,8 @@ static u32 opcode_table[256] = {
0, ImplicitOps | Stack, 0, 0,
ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov,
/* 0xC8 - 0xCF */
- 0, 0, 0, ImplicitOps | Stack, 0, 0, 0, 0,
+ 0, 0, 0, ImplicitOps | Stack,
+ ImplicitOps, SrcImmByte, ImplicitOps, ImplicitOps,
/* 0xD0 - 0xD7 */
ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
@@ -187,11 +191,11 @@ static u32 opcode_table[256] = {
0, 0, 0, 0, 0, 0, 0, 0,
/* 0xE0 - 0xE7 */
0, 0, 0, 0,
- SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
- SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
+ ByteOp | SrcImmUByte, SrcImmUByte,
+ ByteOp | SrcImmUByte, SrcImmUByte,
/* 0xE8 - 0xEF */
- ImplicitOps | Stack, SrcImm | ImplicitOps,
- ImplicitOps, SrcImmByte | ImplicitOps,
+ SrcImm | Stack, SrcImm | ImplicitOps,
+ SrcImm | Src2Imm16, SrcImmByte | ImplicitOps,
SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
/* 0xF0 - 0xF7 */
@@ -230,10 +234,8 @@ static u32 twobyte_table[256] = {
/* 0x70 - 0x7F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x80 - 0x8F */
- ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
- ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
- ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
- ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+ SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm,
+ SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm,
/* 0x90 - 0x9F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0xA0 - 0xA7 */
@@ -1044,10 +1046,14 @@ done_prefixes:
}
break;
case SrcImmByte:
+ case SrcImmUByte:
c->src.type = OP_IMM;
c->src.ptr = (unsigned long *)c->eip;
c->src.bytes = 1;
- c->src.val = insn_fetch(s8, 1, c->eip);
+ if ((c->d & SrcMask) == SrcImmByte)
+ c->src.val = insn_fetch(s8, 1, c->eip);
+ else
+ c->src.val = insn_fetch(u8, 1, c->eip);
break;
case SrcOne:
c->src.bytes = 1;
@@ -1072,6 +1078,12 @@ done_prefixes:
c->src2.bytes = 1;
c->src2.val = insn_fetch(u8, 1, c->eip);
break;
+ case Src2Imm16:
+ c->src2.type = OP_IMM;
+ c->src2.ptr = (unsigned long *)c->eip;
+ c->src2.bytes = 2;
+ c->src2.val = insn_fetch(u16, 2, c->eip);
+ break;
case Src2One:
c->src2.bytes = 1;
c->src2.val = 1;
@@ -1531,13 +1543,10 @@ special_insn:
return -1;
}
return 0;
- case 0x70 ... 0x7f: /* jcc (short) */ {
- int rel = insn_fetch(s8, 1, c->eip);
-
+ case 0x70 ... 0x7f: /* jcc (short) */
if (test_cc(c->b, ctxt->eflags))
- jmp_rel(c, rel);
+ jmp_rel(c, c->src.val);
break;
- }
case 0x80 ... 0x83: /* Grp1 */
switch (c->modrm_reg) {
case 0:
@@ -1769,59 +1778,32 @@ special_insn:
break;
case 0xe4: /* inb */
case 0xe5: /* in */
- port = insn_fetch(u8, 1, c->eip);
+ port = c->src.val;
io_dir_in = 1;
goto do_io;
case 0xe6: /* outb */
case 0xe7: /* out */
- port = insn_fetch(u8, 1, c->eip);
+ port = c->src.val;
io_dir_in = 0;
goto do_io;
case 0xe8: /* call (near) */ {
- long int rel;
- switch (c->op_bytes) {
- case 2:
- rel = insn_fetch(s16, 2, c->eip);
- break;
- case 4:
- rel = insn_fetch(s32, 4, c->eip);
- break;
- default:
- DPRINTF("Call: Invalid op_bytes\n");
- goto cannot_emulate;
- }
+ long int rel = c->src.val;
c->src.val = (unsigned long) c->eip;
jmp_rel(c, rel);
- c->op_bytes = c->ad_bytes;
emulate_push(ctxt);
break;
}
case 0xe9: /* jmp rel */
goto jmp;
- case 0xea: /* jmp far */ {
- uint32_t eip;
- uint16_t sel;
-
- switch (c->op_bytes) {
- case 2:
- eip = insn_fetch(u16, 2, c->eip);
- break;
- case 4:
- eip = insn_fetch(u32, 4, c->eip);
- break;
- default:
- DPRINTF("jmp far: Invalid op_bytes\n");
- goto cannot_emulate;
- }
- sel = insn_fetch(u16, 2, c->eip);
- if (kvm_load_segment_descriptor(ctxt->vcpu, sel, 9, VCPU_SREG_CS) < 0) {
+ case 0xea: /* jmp far */
+ if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, 9,
+ VCPU_SREG_CS) < 0) {
DPRINTF("jmp far: Failed to load CS descriptor\n");
goto cannot_emulate;
}
- c->eip = eip;
+ c->eip = c->src.val;
break;
- }
case 0xeb:
jmp: /* jmp rel short */
jmp_rel(c, c->src.val);
@@ -2039,28 +2021,11 @@ twobyte_insn:
if (!test_cc(c->b, ctxt->eflags))
c->dst.type = OP_NONE; /* no writeback */
break;
- case 0x80 ... 0x8f: /* jnz rel, etc*/ {
- long int rel;
-
- switch (c->op_bytes) {
- case 2:
- rel = insn_fetch(s16, 2, c->eip);
- break;
- case 4:
- rel = insn_fetch(s32, 4, c->eip);
- break;
- case 8:
- rel = insn_fetch(s64, 8, c->eip);
- break;
- default:
- DPRINTF("jnz: Invalid op_bytes\n");
- goto cannot_emulate;
- }
+ case 0x80 ... 0x8f: /* jnz rel, etc*/
if (test_cc(c->b, ctxt->eflags))
- jmp_rel(c, rel);
+ jmp_rel(c, c->src.val);
c->dst.type = OP_NONE;
break;
- }
case 0xa3:
bt: /* bt */
c->dst.type = OP_NONE;
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index ca7ec44bafc3..da1d5a276bc5 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -166,10 +166,16 @@ static void lazy_hcall3(unsigned long call,
/* When lazy mode is turned off reset the per-cpu lazy mode variable and then
* issue the do-nothing hypercall to flush any stored calls. */
-static void lguest_leave_lazy_mode(void)
+static void lguest_leave_lazy_mmu_mode(void)
{
- paravirt_leave_lazy(paravirt_get_lazy_mode());
kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+ paravirt_leave_lazy_mmu();
+}
+
+static void lguest_end_context_switch(struct task_struct *next)
+{
+ kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+ paravirt_end_context_switch(next);
}
/*G:033
@@ -636,7 +642,7 @@ static void __init lguest_init_IRQ(void)
void lguest_setup_irq(unsigned int irq)
{
- irq_to_desc_alloc_cpu(irq, 0);
+ irq_to_desc_alloc_node(irq, 0);
set_irq_chip_and_handler_name(irq, &lguest_irq_controller,
handle_level_irq, "level");
}
@@ -1053,8 +1059,8 @@ __init void lguest_init(void)
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;
+ pv_cpu_ops.start_context_switch = paravirt_start_context_switch;
+ pv_cpu_ops.end_context_switch = lguest_end_context_switch;
/* pagetable management */
pv_mmu_ops.write_cr3 = lguest_write_cr3;
@@ -1067,7 +1073,7 @@ __init void lguest_init(void)
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;
+ pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode;
pv_mmu_ops.pte_update = lguest_pte_update;
pv_mmu_ops.pte_update_defer = lguest_pte_update;
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index e7277cbcfb40..a725b7f760ae 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -161,13 +161,14 @@ static void note_page(struct seq_file *m, struct pg_state *st,
st->current_address >= st->marker[1].start_address) {
const char *unit = units;
unsigned long delta;
+ int width = sizeof(unsigned long) * 2;
/*
* Now print the actual finished series
*/
- seq_printf(m, "0x%p-0x%p ",
- (void *)st->start_address,
- (void *)st->current_address);
+ seq_printf(m, "0x%0*lx-0x%0*lx ",
+ width, st->start_address,
+ width, st->current_address);
delta = (st->current_address - st->start_address) >> 10;
while (!(delta & 1023) && unit[1]) {
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index a03b7279efa0..5ec7ae366615 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -3,40 +3,16 @@
* Copyright (C) 2001, 2002 Andi Kleen, SuSE Labs.
* Copyright (C) 2008-2009, Red Hat Inc., Ingo Molnar
*/
-#include <linux/interrupt.h>
-#include <linux/mmiotrace.h>
-#include <linux/bootmem.h>
-#include <linux/compiler.h>
-#include <linux/highmem.h>
-#include <linux/kprobes.h>
-#include <linux/uaccess.h>
-#include <linux/vmalloc.h>
-#include <linux/vt_kern.h>
-#include <linux/signal.h>
-#include <linux/kernel.h>
-#include <linux/ptrace.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <linux/kdebug.h>
-#include <linux/errno.h>
-#include <linux/magic.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mman.h>
-#include <linux/tty.h>
-#include <linux/smp.h>
-#include <linux/mm.h>
-
-#include <asm-generic/sections.h>
-
-#include <asm/tlbflush.h>
-#include <asm/pgalloc.h>
-#include <asm/segment.h>
-#include <asm/system.h>
-#include <asm/proto.h>
-#include <asm/traps.h>
-#include <asm/desc.h>
+#include <linux/magic.h> /* STACK_END_MAGIC */
+#include <linux/sched.h> /* test_thread_flag(), ... */
+#include <linux/kdebug.h> /* oops_begin/end, ... */
+#include <linux/module.h> /* search_exception_table */
+#include <linux/bootmem.h> /* max_low_pfn */
+#include <linux/kprobes.h> /* __kprobes, ... */
+#include <linux/mmiotrace.h> /* kmmio_handler, ... */
+
+#include <asm/traps.h> /* dotraplinkage, ... */
+#include <asm/pgalloc.h> /* pgd_*(), ... */
/*
* Page fault error code bits:
@@ -225,12 +201,10 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
if (!pmd_present(*pmd_k))
return NULL;
- if (!pmd_present(*pmd)) {
+ if (!pmd_present(*pmd))
set_pmd(pmd, *pmd_k);
- arch_flush_lazy_mmu_mode();
- } else {
+ else
BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
- }
return pmd_k;
}
@@ -538,8 +512,6 @@ bad:
static int is_errata93(struct pt_regs *regs, unsigned long address)
{
#ifdef CONFIG_X86_64
- static int once;
-
if (address != regs->ip)
return 0;
@@ -549,10 +521,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)
address |= 0xffffffffUL << 32;
if ((address >= (u64)_stext && address <= (u64)_etext) ||
(address >= MODULES_VADDR && address <= MODULES_END)) {
- if (!once) {
- printk(errata93_warning);
- once = 1;
- }
+ printk_once(errata93_warning);
regs->ip = address;
return 1;
}
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 8126e8d1a2a4..58f621e81919 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -44,7 +44,6 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
BUG_ON(!pte_none(*(kmap_pte-idx)));
set_pte(kmap_pte-idx, mk_pte(page, prot));
- arch_flush_lazy_mmu_mode();
return (void *)vaddr;
}
@@ -74,7 +73,6 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
#endif
}
- arch_flush_lazy_mmu_mode();
pagefault_enable();
}
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index fd3da1dda1c9..34c1bfb64f1c 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -1,3 +1,4 @@
+#include <linux/initrd.h>
#include <linux/ioport.h>
#include <linux/swap.h>
@@ -7,8 +8,12 @@
#include <asm/page.h>
#include <asm/page_types.h>
#include <asm/sections.h>
+#include <asm/setup.h>
#include <asm/system.h>
#include <asm/tlbflush.h>
+#include <asm/tlb.h>
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
unsigned long __initdata e820_table_start;
unsigned long __meminitdata e820_table_end;
@@ -22,6 +27,69 @@ int direct_gbpages
#endif
;
+int nx_enabled;
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+static int disable_nx __cpuinitdata;
+
+/*
+ * noexec = on|off
+ *
+ * Control non-executable mappings for processes.
+ *
+ * on Enable
+ * off Disable
+ */
+static int __init noexec_setup(char *str)
+{
+ if (!str)
+ return -EINVAL;
+ if (!strncmp(str, "on", 2)) {
+ __supported_pte_mask |= _PAGE_NX;
+ disable_nx = 0;
+ } else if (!strncmp(str, "off", 3)) {
+ disable_nx = 1;
+ __supported_pte_mask &= ~_PAGE_NX;
+ }
+ return 0;
+}
+early_param("noexec", noexec_setup);
+#endif
+
+#ifdef CONFIG_X86_PAE
+static void __init set_nx(void)
+{
+ unsigned int v[4], l, h;
+
+ if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
+ cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
+
+ if ((v[3] & (1 << 20)) && !disable_nx) {
+ rdmsr(MSR_EFER, l, h);
+ l |= EFER_NX;
+ wrmsr(MSR_EFER, l, h);
+ nx_enabled = 1;
+ __supported_pte_mask |= _PAGE_NX;
+ }
+ }
+}
+#else
+static inline void set_nx(void)
+{
+}
+#endif
+
+#ifdef CONFIG_X86_64
+void __cpuinit check_efer(void)
+{
+ unsigned long efer;
+
+ rdmsrl(MSR_EFER, efer);
+ if (!(efer & EFER_NX) || disable_nx)
+ __supported_pte_mask &= ~_PAGE_NX;
+}
+#endif
+
static void __init find_early_table_space(unsigned long end, int use_pse,
int use_gbpages)
{
@@ -65,12 +133,11 @@ static void __init find_early_table_space(unsigned long end, int use_pse,
*/
#ifdef CONFIG_X86_32
start = 0x7000;
- e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT,
- tables, PAGE_SIZE);
-#else /* CONFIG_X86_64 */
+#else
start = 0x8000;
- e820_table_start = find_e820_area(start, end, tables, PAGE_SIZE);
#endif
+ e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT,
+ tables, PAGE_SIZE);
if (e820_table_start == -1UL)
panic("Cannot find space for the kernel page tables");
@@ -158,12 +225,9 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
use_gbpages = direct_gbpages;
#endif
-#ifdef CONFIG_X86_32
-#ifdef CONFIG_X86_PAE
set_nx();
if (nx_enabled)
printk(KERN_INFO "NX (Execute Disable) protection: active\n");
-#endif
/* Enable PSE if available */
if (cpu_has_pse)
@@ -174,7 +238,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
set_in_cr4(X86_CR4_PGE);
__supported_pte_mask |= _PAGE_GLOBAL;
}
-#endif
if (use_gbpages)
page_size_mask |= 1 << PG_LEVEL_1G;
@@ -304,8 +367,23 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
#endif
#ifdef CONFIG_X86_64
- if (!after_bootmem)
+ if (!after_bootmem && !start) {
+ pud_t *pud;
+ pmd_t *pmd;
+
mmu_cr4_features = read_cr4();
+
+ /*
+ * _brk_end cannot change anymore, but it and _end may be
+ * located on different 2M pages. cleanup_highmap(), however,
+ * can only consider _end when it runs, so destroy any
+ * mappings beyond _brk_end here.
+ */
+ pud = pud_offset(pgd_offset_k(_brk_end), _brk_end);
+ pmd = pmd_offset(pud, _brk_end - 1);
+ while (++pmd <= pmd_offset(pud, (unsigned long)_end - 1))
+ pmd_clear(pmd);
+ }
#endif
__flush_tlb_all();
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 749559ed80f5..fef1d90d4f15 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -49,12 +49,9 @@
#include <asm/paravirt.h>
#include <asm/setup.h>
#include <asm/cacheflush.h>
+#include <asm/page_types.h>
#include <asm/init.h>
-unsigned long max_low_pfn_mapped;
-unsigned long max_pfn_mapped;
-
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
unsigned long highstart_pfn, highend_pfn;
static noinline int do_test_wp_bit(void);
@@ -587,61 +584,9 @@ void zap_low_mappings(void)
flush_tlb_all();
}
-int nx_enabled;
-
pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
EXPORT_SYMBOL_GPL(__supported_pte_mask);
-#ifdef CONFIG_X86_PAE
-
-static int disable_nx __initdata;
-
-/*
- * noexec = on|off
- *
- * Control non executable mappings.
- *
- * on Enable
- * off Disable
- */
-static int __init noexec_setup(char *str)
-{
- if (!str || !strcmp(str, "on")) {
- if (cpu_has_nx) {
- __supported_pte_mask |= _PAGE_NX;
- disable_nx = 0;
- }
- } else {
- if (!strcmp(str, "off")) {
- disable_nx = 1;
- __supported_pte_mask &= ~_PAGE_NX;
- } else {
- return -EINVAL;
- }
- }
-
- return 0;
-}
-early_param("noexec", noexec_setup);
-
-void __init set_nx(void)
-{
- unsigned int v[4], l, h;
-
- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
-
- if ((v[3] & (1 << 20)) && !disable_nx) {
- rdmsr(MSR_EFER, l, h);
- l |= EFER_NX;
- wrmsr(MSR_EFER, l, h);
- nx_enabled = 1;
- __supported_pte_mask |= _PAGE_NX;
- }
- }
-}
-#endif
-
/* user-defined highmem size */
static unsigned int highmem_pages = -1;
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 1753e8020df6..52bb9519bb86 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -50,18 +50,8 @@
#include <asm/cacheflush.h>
#include <asm/init.h>
-/*
- * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
- * The direct mapping extends to max_pfn_mapped, so that we can directly access
- * apertures, ACPI and other tables without having to play with fixmaps.
- */
-unsigned long max_low_pfn_mapped;
-unsigned long max_pfn_mapped;
-
static unsigned long dma_reserve __initdata;
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
static int __init parse_direct_gbpages_off(char *arg)
{
direct_gbpages = 0;
@@ -85,39 +75,6 @@ early_param("gbpages", parse_direct_gbpages_on);
pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP;
EXPORT_SYMBOL_GPL(__supported_pte_mask);
-static int disable_nx __cpuinitdata;
-
-/*
- * noexec=on|off
- * Control non-executable mappings for 64-bit processes.
- *
- * on Enable (default)
- * off Disable
- */
-static int __init nonx_setup(char *str)
-{
- if (!str)
- return -EINVAL;
- if (!strncmp(str, "on", 2)) {
- __supported_pte_mask |= _PAGE_NX;
- disable_nx = 0;
- } else if (!strncmp(str, "off", 3)) {
- disable_nx = 1;
- __supported_pte_mask &= ~_PAGE_NX;
- }
- return 0;
-}
-early_param("noexec", nonx_setup);
-
-void __cpuinit check_efer(void)
-{
- unsigned long efer;
-
- rdmsrl(MSR_EFER, efer);
- if (!(efer & EFER_NX) || disable_nx)
- __supported_pte_mask &= ~_PAGE_NX;
-}
-
int force_personality32;
/*
@@ -628,6 +585,7 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn)
early_res_to_bootmem(0, end_pfn<<PAGE_SHIFT);
reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT);
}
+#endif
void __init paging_init(void)
{
@@ -638,11 +596,10 @@ void __init paging_init(void)
max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
max_zone_pfns[ZONE_NORMAL] = max_pfn;
- memory_present(0, 0, max_pfn);
+ sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
free_area_init_nodes(max_zone_pfns);
}
-#endif
/*
* Memory hotplug specific functions
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
index 8056545e2d39..fe6f84ca121e 100644
--- a/arch/x86/mm/iomap_32.c
+++ b/arch/x86/mm/iomap_32.c
@@ -82,7 +82,6 @@ iounmap_atomic(void *kvaddr, enum km_type type)
if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
kpte_clear_flush(kmap_pte-idx, vaddr);
- arch_flush_lazy_mmu_mode();
pagefault_enable();
}
EXPORT_SYMBOL_GPL(iounmap_atomic);
diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 50dc802a1c46..16ccbd77917f 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -32,7 +32,7 @@ struct kmmio_fault_page {
struct list_head list;
struct kmmio_fault_page *release_next;
unsigned long page; /* location of the fault page */
- bool old_presence; /* page presence prior to arming */
+ pteval_t old_presence; /* page presence prior to arming */
bool armed;
/*
@@ -97,60 +97,62 @@ static struct kmmio_probe *get_kmmio_probe(unsigned long addr)
static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page)
{
struct list_head *head;
- struct kmmio_fault_page *p;
+ struct kmmio_fault_page *f;
page &= PAGE_MASK;
head = kmmio_page_list(page);
- list_for_each_entry_rcu(p, head, list) {
- if (p->page == page)
- return p;
+ list_for_each_entry_rcu(f, head, list) {
+ if (f->page == page)
+ return f;
}
return NULL;
}
-static void set_pmd_presence(pmd_t *pmd, bool present, bool *old)
+static void clear_pmd_presence(pmd_t *pmd, bool clear, pmdval_t *old)
{
pmdval_t v = pmd_val(*pmd);
- *old = !!(v & _PAGE_PRESENT);
- v &= ~_PAGE_PRESENT;
- if (present)
- v |= _PAGE_PRESENT;
+ if (clear) {
+ *old = v & _PAGE_PRESENT;
+ v &= ~_PAGE_PRESENT;
+ } else /* presume this has been called with clear==true previously */
+ v |= *old;
set_pmd(pmd, __pmd(v));
}
-static void set_pte_presence(pte_t *pte, bool present, bool *old)
+static void clear_pte_presence(pte_t *pte, bool clear, pteval_t *old)
{
pteval_t v = pte_val(*pte);
- *old = !!(v & _PAGE_PRESENT);
- v &= ~_PAGE_PRESENT;
- if (present)
- v |= _PAGE_PRESENT;
+ if (clear) {
+ *old = v & _PAGE_PRESENT;
+ v &= ~_PAGE_PRESENT;
+ } else /* presume this has been called with clear==true previously */
+ v |= *old;
set_pte_atomic(pte, __pte(v));
}
-static int set_page_presence(unsigned long addr, bool present, bool *old)
+static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
{
unsigned int level;
- pte_t *pte = lookup_address(addr, &level);
+ pte_t *pte = lookup_address(f->page, &level);
if (!pte) {
- pr_err("kmmio: no pte for page 0x%08lx\n", addr);
+ pr_err("kmmio: no pte for page 0x%08lx\n", f->page);
return -1;
}
switch (level) {
case PG_LEVEL_2M:
- set_pmd_presence((pmd_t *)pte, present, old);
+ clear_pmd_presence((pmd_t *)pte, clear, &f->old_presence);
break;
case PG_LEVEL_4K:
- set_pte_presence(pte, present, old);
+ clear_pte_presence(pte, clear, &f->old_presence);
break;
default:
pr_err("kmmio: unexpected page level 0x%x.\n", level);
return -1;
}
- __flush_tlb_one(addr);
+ __flush_tlb_one(f->page);
return 0;
}
@@ -171,9 +173,9 @@ static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
WARN_ONCE(f->armed, KERN_ERR "kmmio page already armed.\n");
if (f->armed) {
pr_warning("kmmio double-arm: page 0x%08lx, ref %d, old %d\n",
- f->page, f->count, f->old_presence);
+ f->page, f->count, !!f->old_presence);
}
- ret = set_page_presence(f->page, false, &f->old_presence);
+ ret = clear_page_presence(f, true);
WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", f->page);
f->armed = true;
return ret;
@@ -182,8 +184,7 @@ static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
/** Restore the given page to saved presence state. */
static void disarm_kmmio_fault_page(struct kmmio_fault_page *f)
{
- bool tmp;
- int ret = set_page_presence(f->page, f->old_presence, &tmp);
+ int ret = clear_page_presence(f, false);
WARN_ONCE(ret < 0,
KERN_ERR "kmmio disarming 0x%08lx failed.\n", f->page);
f->armed = false;
@@ -310,7 +311,12 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx);
if (!ctx->active) {
- pr_debug("kmmio: spurious debug trap on CPU %d.\n",
+ /*
+ * debug traps without an active context are due to either
+ * something external causing them (f.e. using a debugger while
+ * mmio tracing enabled), or erroneous behaviour
+ */
+ pr_warning("kmmio: unexpected debug trap on CPU %d.\n",
smp_processor_id());
goto out;
}
@@ -439,12 +445,12 @@ static void rcu_free_kmmio_fault_pages(struct rcu_head *head)
head,
struct kmmio_delayed_release,
rcu);
- struct kmmio_fault_page *p = dr->release_list;
- while (p) {
- struct kmmio_fault_page *next = p->release_next;
- BUG_ON(p->count);
- kfree(p);
- p = next;
+ struct kmmio_fault_page *f = dr->release_list;
+ while (f) {
+ struct kmmio_fault_page *next = f->release_next;
+ BUG_ON(f->count);
+ kfree(f);
+ f = next;
}
kfree(dr);
}
@@ -453,19 +459,19 @@ static void remove_kmmio_fault_pages(struct rcu_head *head)
{
struct kmmio_delayed_release *dr =
container_of(head, struct kmmio_delayed_release, rcu);
- struct kmmio_fault_page *p = dr->release_list;
+ struct kmmio_fault_page *f = dr->release_list;
struct kmmio_fault_page **prevp = &dr->release_list;
unsigned long flags;
spin_lock_irqsave(&kmmio_lock, flags);
- while (p) {
- if (!p->count) {
- list_del_rcu(&p->list);
- prevp = &p->release_next;
+ while (f) {
+ if (!f->count) {
+ list_del_rcu(&f->list);
+ prevp = &f->release_next;
} else {
- *prevp = p->release_next;
+ *prevp = f->release_next;
}
- p = p->release_next;
+ f = f->release_next;
}
spin_unlock_irqrestore(&kmmio_lock, flags);
@@ -528,8 +534,8 @@ void unregister_kmmio_probe(struct kmmio_probe *p)
}
EXPORT_SYMBOL(unregister_kmmio_probe);
-static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val,
- void *args)
+static int
+kmmio_die_notifier(struct notifier_block *nb, unsigned long val, void *args)
{
struct die_args *arg = args;
@@ -544,11 +550,23 @@ static struct notifier_block nb_die = {
.notifier_call = kmmio_die_notifier
};
-static int __init init_kmmio(void)
+int kmmio_init(void)
{
int i;
+
for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++)
INIT_LIST_HEAD(&kmmio_page_table[i]);
+
return register_die_notifier(&nb_die);
}
-fs_initcall(init_kmmio); /* should be before device_initcall() */
+
+void kmmio_cleanup(void)
+{
+ int i;
+
+ unregister_die_notifier(&nb_die);
+ for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++) {
+ WARN_ONCE(!list_empty(&kmmio_page_table[i]),
+ KERN_ERR "kmmio_page_table not empty at cleanup, any further tracing will leak memory.\n");
+ }
+}
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index c9342ed8b402..132772a8ec57 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -451,6 +451,7 @@ void enable_mmiotrace(void)
if (nommiotrace)
pr_info(NAME "MMIO tracing disabled.\n");
+ kmmio_init();
enter_uniprocessor();
spin_lock_irq(&trace_lock);
atomic_inc(&mmiotrace_enabled);
@@ -473,6 +474,7 @@ void disable_mmiotrace(void)
clear_trace_list(); /* guarantees: no more kmmio callbacks */
leave_uniprocessor();
+ kmmio_cleanup();
pr_info(NAME "disabled.\n");
out:
mutex_unlock(&mmiotrace_mutex);
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 2d05a12029dc..fb61d81a656f 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -578,21 +578,6 @@ unsigned long __init numa_free_all_bootmem(void)
return pages;
}
-void __init paging_init(void)
-{
- unsigned long max_zone_pfns[MAX_NR_ZONES];
-
- memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
- max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
- max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
- max_zone_pfns[ZONE_NORMAL] = max_pfn;
-
- sparse_memory_present_with_active_regions(MAX_NUMNODES);
- sparse_init();
-
- free_area_init_nodes(max_zone_pfns);
-}
-
static __init int numa_setup(char *opt)
{
if (!opt)
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 797f9f107cb6..b81b41a0481f 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -844,13 +844,6 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
vm_unmap_aliases();
- /*
- * If we're called with lazy mmu updates enabled, the
- * in-memory pte state may be stale. Flush pending updates to
- * bring them up to date.
- */
- arch_flush_lazy_mmu_mode();
-
cpa.vaddr = addr;
cpa.pages = pages;
cpa.numpages = numpages;
@@ -895,13 +888,6 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
} else
cpa_flush_all(cache);
- /*
- * If we've been called with lazy mmu updates enabled, then
- * make sure that everything gets flushed out before we
- * return.
- */
- arch_flush_lazy_mmu_mode();
-
out:
return ret;
}
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index 33c5fa57e43d..87b45bff250d 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -345,9 +345,9 @@ static int __init nodes_cover_memory(const struct bootnode *nodes)
pxmram = 0;
}
- e820ram = max_pfn - absent_pages_in_range(0, max_pfn);
- /* We seem to lose 3 pages somewhere. Allow a bit of slack. */
- if ((long)(e820ram - pxmram) >= 1*1024*1024) {
+ e820ram = max_pfn - (e820_hole_size(0, max_pfn<<PAGE_SHIFT)>>PAGE_SHIFT);
+ /* We seem to lose 3 pages somewhere. Allow 1M of slack. */
+ if ((long)(e820ram - pxmram) >= (1<<(20 - PAGE_SHIFT))) {
printk(KERN_ERR
"SRAT: PXMs only cover %luMB of your %luMB e820 RAM. Not used.\n",
(pxmram << PAGE_SHIFT) >> 20,
@@ -361,6 +361,7 @@ static void __init unparse_node(int node)
{
int i;
node_clear(node, nodes_parsed);
+ node_clear(node, cpu_nodes_parsed);
for (i = 0; i < MAX_LOCAL_APIC; i++) {
if (apicid_to_node[i] == node)
apicid_to_node[i] = NUMA_NO_NODE;
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
index 04df67f8a7ba..044897be021f 100644
--- a/arch/x86/oprofile/backtrace.c
+++ b/arch/x86/oprofile/backtrace.c
@@ -76,9 +76,9 @@ void
x86_backtrace(struct pt_regs * const regs, unsigned int depth)
{
struct frame_head *head = (struct frame_head *)frame_pointer(regs);
- unsigned long stack = kernel_trap_sp(regs);
if (!user_mode_vm(regs)) {
+ unsigned long stack = kernel_stack_pointer(regs);
if (depth)
dump_trace(NULL, regs, (unsigned long *)stack, 0,
&backtrace_ops, &depth);
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 202864ad49a7..d7348a27e1e8 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -356,14 +356,11 @@ static void exit_sysfs(void)
#define exit_sysfs() do { } while (0)
#endif /* CONFIG_PM */
-static int p4force;
-module_param(p4force, int, 0);
-
static int __init p4_init(char **cpu_type)
{
__u8 cpu_model = boot_cpu_data.x86_model;
- if (!p4force && (cpu_model > 6 || cpu_model == 5))
+ if (cpu_model > 6 || cpu_model == 5)
return 0;
#ifndef CONFIG_SMP
@@ -389,10 +386,36 @@ static int __init p4_init(char **cpu_type)
return 0;
}
+static enum {
+ NONE = 0,
+ ARCH_PERFMON,
+ CORE_2,
+} forced_cpu;
+
+static int force_cpu_type(const char *str, struct kernel_param *kp)
+{
+ if (!strcmp(str, "archperfmon")) {
+ forced_cpu = ARCH_PERFMON;
+ printk(KERN_INFO "oprofile: forcing architectural perfmon\n");
+ } else if (!strcmp(str, "core_2")) {
+ forced_cpu = CORE_2;
+ printk(KERN_INFO "oprofile: forcing core_2\n");
+ }
+
+ return 0;
+}
+module_param_call(cpu_type, force_cpu_type, NULL, NULL, 0);
+
static int __init ppro_init(char **cpu_type)
{
__u8 cpu_model = boot_cpu_data.x86_model;
+ if (forced_cpu == ARCH_PERFMON && cpu_has_arch_perfmon)
+ return 0;
+
+ if (forced_cpu == CORE_2)
+ cpu_model = 15;
+
switch (cpu_model) {
case 0 ... 2:
*cpu_type = "i386/ppro";
@@ -414,6 +437,13 @@ static int __init ppro_init(char **cpu_type)
case 15: case 23:
*cpu_type = "i386/core_2";
break;
+ case 26:
+ arch_perfmon_setup_counters();
+ *cpu_type = "i386/core_i7";
+ break;
+ case 28:
+ *cpu_type = "i386/atom";
+ break;
default:
/* Unknown */
return 0;
diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
index 7133cdf9098b..cac083386e03 100644
--- a/arch/x86/vdso/vma.c
+++ b/arch/x86/vdso/vma.c
@@ -8,6 +8,7 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/random.h>
+#include <linux/elf.h>
#include <asm/vsyscall.h>
#include <asm/vgtod.h>
#include <asm/proto.h>
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index f09e8c36ee80..0a1700a2be9c 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/start_kernel.h>
#include <linux/sched.h>
+#include <linux/kprobes.h>
#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/mm.h>
@@ -44,6 +45,7 @@
#include <asm/processor.h>
#include <asm/proto.h>
#include <asm/msr-index.h>
+#include <asm/traps.h>
#include <asm/setup.h>
#include <asm/desc.h>
#include <asm/pgtable.h>
@@ -240,10 +242,10 @@ static unsigned long xen_get_debugreg(int reg)
return HYPERVISOR_get_debugreg(reg);
}
-void xen_leave_lazy(void)
+static void xen_end_context_switch(struct task_struct *next)
{
- paravirt_leave_lazy(paravirt_get_lazy_mode());
xen_mc_flush();
+ paravirt_end_context_switch(next);
}
static unsigned long xen_store_tr(void)
@@ -428,11 +430,44 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
static int cvt_gate_to_trap(int vector, const gate_desc *val,
struct trap_info *info)
{
+ unsigned long addr;
+
if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT)
return 0;
info->vector = vector;
- info->address = gate_offset(*val);
+
+ addr = gate_offset(*val);
+#ifdef CONFIG_X86_64
+ /*
+ * Look for known traps using IST, and substitute them
+ * appropriately. The debugger ones are the only ones we care
+ * about. Xen will handle faults like double_fault and
+ * machine_check, so we should never see them. Warn if
+ * there's an unexpected IST-using fault handler.
+ */
+ if (addr == (unsigned long)debug)
+ addr = (unsigned long)xen_debug;
+ else if (addr == (unsigned long)int3)
+ addr = (unsigned long)xen_int3;
+ else if (addr == (unsigned long)stack_segment)
+ addr = (unsigned long)xen_stack_segment;
+ else if (addr == (unsigned long)double_fault ||
+ addr == (unsigned long)nmi) {
+ /* Don't need to handle these */
+ return 0;
+#ifdef CONFIG_X86_MCE
+ } else if (addr == (unsigned long)machine_check) {
+ return 0;
+#endif
+ } else {
+ /* Some other trap using IST? */
+ if (WARN_ON(val->ist != 0))
+ return 0;
+ }
+#endif /* CONFIG_X86_64 */
+ info->address = addr;
+
info->cs = gate_segment(*val);
info->flags = val->dpl;
/* interrupt gates clear IF */
@@ -623,10 +658,26 @@ static void xen_clts(void)
xen_mc_issue(PARAVIRT_LAZY_CPU);
}
+static DEFINE_PER_CPU(unsigned long, xen_cr0_value);
+
+static unsigned long xen_read_cr0(void)
+{
+ unsigned long cr0 = percpu_read(xen_cr0_value);
+
+ if (unlikely(cr0 == 0)) {
+ cr0 = native_read_cr0();
+ percpu_write(xen_cr0_value, cr0);
+ }
+
+ return cr0;
+}
+
static void xen_write_cr0(unsigned long cr0)
{
struct multicall_space mcs;
+ percpu_write(xen_cr0_value, cr0);
+
/* Only pay attention to cr0.TS; everything else is
ignored. */
mcs = xen_mc_entry(0);
@@ -812,7 +863,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
.clts = xen_clts,
- .read_cr0 = native_read_cr0,
+ .read_cr0 = xen_read_cr0,
.write_cr0 = xen_write_cr0,
.read_cr4 = native_read_cr4,
@@ -860,10 +911,8 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
/* Xen takes care of %gs when switching to usermode for us */
.swapgs = paravirt_nop,
- .lazy_mode = {
- .enter = paravirt_enter_lazy_cpu,
- .leave = xen_leave_lazy,
- },
+ .start_context_switch = paravirt_start_context_switch,
+ .end_context_switch = xen_end_context_switch,
};
static const struct pv_apic_ops xen_apic_ops __initdata = {
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 9842b1212407..760e3a512059 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -451,10 +451,6 @@ void set_pte_mfn(unsigned long vaddr, unsigned long mfn, pgprot_t flags)
void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
- /* updates to init_mm may be done without lock */
- if (mm == &init_mm)
- preempt_disable();
-
ADD_STATS(set_pte_at, 1);
// ADD_STATS(set_pte_at_pinned, xen_page_pinned(ptep));
ADD_STATS(set_pte_at_current, mm == current->mm);
@@ -475,9 +471,7 @@ void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
}
xen_set_pte(ptep, pteval);
-out:
- if (mm == &init_mm)
- preempt_enable();
+out: return;
}
pte_t xen_ptep_modify_prot_start(struct mm_struct *mm,
@@ -1151,10 +1145,8 @@ static void drop_other_mm_ref(void *info)
/* If this cpu still has a stale cr3 reference, then make sure
it has been flushed. */
- if (percpu_read(xen_current_cr3) == __pa(mm->pgd)) {
+ if (percpu_read(xen_current_cr3) == __pa(mm->pgd))
load_cr3(swapper_pg_dir);
- arch_flush_lazy_cpu_mode();
- }
}
static void xen_drop_mm_ref(struct mm_struct *mm)
@@ -1167,7 +1159,6 @@ static void xen_drop_mm_ref(struct mm_struct *mm)
load_cr3(swapper_pg_dir);
else
leave_mm(smp_processor_id());
- arch_flush_lazy_cpu_mode();
}
/* Get the "official" set of cpus referring to our pagetable. */
@@ -1794,6 +1785,11 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(swapper_pg_dir)));
+ reserve_early(__pa(xen_start_info->pt_base),
+ __pa(xen_start_info->pt_base +
+ xen_start_info->nr_pt_frames * PAGE_SIZE),
+ "XEN PAGETABLES");
+
return swapper_pg_dir;
}
#endif /* CONFIG_X86_64 */
@@ -1870,6 +1866,14 @@ __init void xen_post_allocator_init(void)
xen_mark_init_mm_pinned();
}
+static void xen_leave_lazy_mmu(void)
+{
+ preempt_disable();
+ xen_mc_flush();
+ paravirt_leave_lazy_mmu();
+ preempt_enable();
+}
+
const struct pv_mmu_ops xen_mmu_ops __initdata = {
.pagetable_setup_start = xen_pagetable_setup_start,
.pagetable_setup_done = xen_pagetable_setup_done,
@@ -1943,7 +1947,7 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = {
.lazy_mode = {
.enter = paravirt_enter_lazy_mmu,
- .leave = xen_leave_lazy,
+ .leave = xen_leave_lazy_mmu,
},
.set_fixmap = xen_set_fixmap,
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 15c6c68db6a2..ad0047f47cd4 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -61,9 +61,9 @@ char * __init xen_memory_setup(void)
* - xen_start_info
* See comment above "struct start_info" in <xen/interface/xen.h>
*/
- e820_add_region(__pa(xen_start_info->mfn_list),
- xen_start_info->pt_base - xen_start_info->mfn_list,
- E820_RESERVED);
+ reserve_early(__pa(xen_start_info->mfn_list),
+ __pa(xen_start_info->pt_base),
+ "XEN START INFO");
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 20139464943c..5c50a1017a37 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -30,7 +30,6 @@ pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
void xen_ident_map_ISA(void);
void xen_reserve_top(void);
-void xen_leave_lazy(void);
void xen_post_allocator_init(void);
char * __init xen_memory_setup(void);
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index fa6dc4dd3b19..30d21a9e2ef5 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -137,6 +137,8 @@ config PCI
source "drivers/pci/Kconfig"
+endmenu
+
menu "Platform options"
choice
@@ -153,8 +155,6 @@ config XTENSA_PLATFORM_ISS
config XTENSA_PLATFORM_XT2000
bool "XT2000"
- select XTENSA_CALIBRATE_CCOUNT
- select PCI
help
XT2000 is the name of Tensilica's feature-rich emulation platform.
This hardware is capable of running a full Linux distribution.
@@ -192,8 +192,6 @@ config CMDLINE
source "mm/Kconfig"
-endmenu
-
config HOTPLUG
bool "Support for hot-pluggable devices"
help
diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h
index f84d3f00774a..e4d831a30772 100644
--- a/arch/xtensa/include/asm/checksum.h
+++ b/arch/xtensa/include/asm/checksum.h
@@ -113,7 +113,8 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
are modified, we must also specify them as outputs, or gcc
will assume they contain their original values. */
: "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr)
- : "1" (iph), "2" (ihl));
+ : "1" (iph), "2" (ihl)
+ : "memory");
return csum_fold(sum);
}
@@ -227,7 +228,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
"1:\t"
: "=r" (sum), "=&r" (__dummy)
: "r" (saddr), "r" (daddr),
- "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
+ "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)
+ : "memory");
return csum_fold(sum);
}
diff --git a/block/Kconfig b/block/Kconfig
index e7d12782bcfb..2c39527aa7db 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -26,6 +26,7 @@ if BLOCK
config LBD
bool "Support for large block devices and files"
depends on !64BIT
+ default y
help
Enable block devices or files of size 2TB and larger.
@@ -38,11 +39,13 @@ config LBD
The ext4 filesystem requires that this feature be enabled in
order to support filesystems that have the huge_file feature
- enabled. Otherwise, it will refuse to mount any filesystems
- that use the huge_file feature, which is enabled by default
- by mke2fs.ext4. The GFS2 filesystem also requires this feature.
+ enabled. Otherwise, it will refuse to mount in the read-write
+ mode any filesystems that use the huge_file feature, which is
+ enabled by default by mke2fs.ext4.
- If unsure, say N.
+ The GFS2 filesystem also requires this feature.
+
+ If unsure, say Y.
config BLK_DEV_BSG
bool "Block layer SG support v4 (EXPERIMENTAL)"
diff --git a/block/as-iosched.c b/block/as-iosched.c
index c48fa670d221..7a12cf6ee1d3 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -306,8 +306,8 @@ as_choose_req(struct as_data *ad, struct request *rq1, struct request *rq2)
data_dir = rq_is_sync(rq1);
last = ad->last_sector[data_dir];
- s1 = rq1->sector;
- s2 = rq2->sector;
+ s1 = blk_rq_pos(rq1);
+ s2 = blk_rq_pos(rq2);
BUG_ON(data_dir != rq_is_sync(rq2));
@@ -566,13 +566,15 @@ static void as_update_iohist(struct as_data *ad, struct as_io_context *aic,
as_update_thinktime(ad, aic, thinktime);
/* Calculate read -> read seek distance */
- if (aic->last_request_pos < rq->sector)
- seek_dist = rq->sector - aic->last_request_pos;
+ if (aic->last_request_pos < blk_rq_pos(rq))
+ seek_dist = blk_rq_pos(rq) -
+ aic->last_request_pos;
else
- seek_dist = aic->last_request_pos - rq->sector;
+ seek_dist = aic->last_request_pos -
+ blk_rq_pos(rq);
as_update_seekdist(ad, aic, seek_dist);
}
- aic->last_request_pos = rq->sector + rq->nr_sectors;
+ aic->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
set_bit(AS_TASK_IOSTARTED, &aic->state);
spin_unlock(&aic->lock);
}
@@ -587,7 +589,7 @@ static int as_close_req(struct as_data *ad, struct as_io_context *aic,
{
unsigned long delay; /* jiffies */
sector_t last = ad->last_sector[ad->batch_data_dir];
- sector_t next = rq->sector;
+ sector_t next = blk_rq_pos(rq);
sector_t delta; /* acceptable close offset (in sectors) */
sector_t s;
@@ -981,7 +983,7 @@ static void as_move_to_dispatch(struct as_data *ad, struct request *rq)
* This has to be set in order to be correctly updated by
* as_find_next_rq
*/
- ad->last_sector[data_dir] = rq->sector + rq->nr_sectors;
+ ad->last_sector[data_dir] = blk_rq_pos(rq) + blk_rq_sectors(rq);
if (data_dir == BLK_RW_SYNC) {
struct io_context *ioc = RQ_IOC(rq);
@@ -1312,12 +1314,8 @@ static void as_merged_requests(struct request_queue *q, struct request *req,
static void as_work_handler(struct work_struct *work)
{
struct as_data *ad = container_of(work, struct as_data, antic_work);
- struct request_queue *q = ad->q;
- unsigned long flags;
- spin_lock_irqsave(q->queue_lock, flags);
- blk_start_queueing(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
+ blk_run_queue(ad->q);
}
static int as_may_queue(struct request_queue *q, int rw)
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 20b4111fa050..0ab81a0a7502 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -106,10 +106,7 @@ bool blk_ordered_complete_seq(struct request_queue *q, unsigned seq, int error)
*/
q->ordseq = 0;
rq = q->orig_bar_rq;
-
- if (__blk_end_request(rq, q->orderr, blk_rq_bytes(rq)))
- BUG();
-
+ __blk_end_request_all(rq, q->orderr);
return true;
}
@@ -166,7 +163,7 @@ static inline bool start_ordered(struct request_queue *q, struct request **rqp)
* For an empty barrier, there's no actual BAR request, which
* in turn makes POSTFLUSH unnecessary. Mask them off.
*/
- if (!rq->hard_nr_sectors) {
+ if (!blk_rq_sectors(rq)) {
q->ordered &= ~(QUEUE_ORDERED_DO_BAR |
QUEUE_ORDERED_DO_POSTFLUSH);
/*
@@ -183,7 +180,7 @@ static inline bool start_ordered(struct request_queue *q, struct request **rqp)
}
/* stash away the original request */
- elv_dequeue_request(q, rq);
+ blk_dequeue_request(rq);
q->orig_bar_rq = rq;
rq = NULL;
@@ -251,10 +248,8 @@ bool blk_do_ordered(struct request_queue *q, struct request **rqp)
* Queue ordering not supported. Terminate
* with prejudice.
*/
- elv_dequeue_request(q, rq);
- if (__blk_end_request(rq, -EOPNOTSUPP,
- blk_rq_bytes(rq)))
- BUG();
+ blk_dequeue_request(rq);
+ __blk_end_request_all(rq, -EOPNOTSUPP);
*rqp = NULL;
return false;
}
@@ -329,7 +324,7 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
/*
* 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.
+ * from blk_rq_pos(rq).
*/
if (error_sector)
*error_sector = bio->bi_sector;
diff --git a/block/blk-core.c b/block/blk-core.c
index 2998fe3a2377..be592dfd4584 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -68,11 +68,11 @@ static void drive_stat_acct(struct request *rq, int new_io)
int rw = rq_data_dir(rq);
int cpu;
- if (!blk_fs_request(rq) || !blk_do_io_stat(rq))
+ if (!blk_do_io_stat(rq))
return;
cpu = part_stat_lock();
- part = disk_map_sector_rcu(rq->rq_disk, rq->sector);
+ part = disk_map_sector_rcu(rq->rq_disk, blk_rq_pos(rq));
if (!new_io)
part_stat_inc(cpu, part, merges[rw]);
@@ -127,13 +127,14 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
INIT_LIST_HEAD(&rq->timeout_list);
rq->cpu = -1;
rq->q = q;
- rq->sector = rq->hard_sector = (sector_t) -1;
+ rq->__sector = (sector_t) -1;
INIT_HLIST_NODE(&rq->hash);
RB_CLEAR_NODE(&rq->rb_node);
rq->cmd = rq->__cmd;
rq->cmd_len = BLK_MAX_CDB;
rq->tag = -1;
rq->ref_count = 1;
+ rq->start_time = jiffies;
}
EXPORT_SYMBOL(blk_rq_init);
@@ -184,14 +185,11 @@ void blk_dump_rq_flags(struct request *rq, char *msg)
rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type,
rq->cmd_flags);
- printk(KERN_INFO " sector %llu, nr/cnr %lu/%u\n",
- (unsigned long long)rq->sector,
- rq->nr_sectors,
- rq->current_nr_sectors);
- printk(KERN_INFO " bio %p, biotail %p, buffer %p, data %p, len %u\n",
- rq->bio, rq->biotail,
- rq->buffer, rq->data,
- rq->data_len);
+ printk(KERN_INFO " sector %llu, nr/cnr %u/%u\n",
+ (unsigned long long)blk_rq_pos(rq),
+ blk_rq_sectors(rq), blk_rq_cur_sectors(rq));
+ printk(KERN_INFO " bio %p, biotail %p, buffer %p, len %u\n",
+ rq->bio, rq->biotail, rq->buffer, blk_rq_bytes(rq));
if (blk_pc_request(rq)) {
printk(KERN_INFO " cdb: ");
@@ -333,24 +331,6 @@ void blk_unplug(struct request_queue *q)
}
EXPORT_SYMBOL(blk_unplug);
-static void blk_invoke_request_fn(struct request_queue *q)
-{
- if (unlikely(blk_queue_stopped(q)))
- return;
-
- /*
- * one level of recursion is ok and is much faster than kicking
- * the unplug handling
- */
- if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) {
- q->request_fn(q);
- queue_flag_clear(QUEUE_FLAG_REENTER, q);
- } else {
- queue_flag_set(QUEUE_FLAG_PLUGGED, q);
- kblockd_schedule_work(q, &q->unplug_work);
- }
-}
-
/**
* blk_start_queue - restart a previously stopped queue
* @q: The &struct request_queue in question
@@ -365,7 +345,7 @@ void blk_start_queue(struct request_queue *q)
WARN_ON(!irqs_disabled());
queue_flag_clear(QUEUE_FLAG_STOPPED, q);
- blk_invoke_request_fn(q);
+ __blk_run_queue(q);
}
EXPORT_SYMBOL(blk_start_queue);
@@ -425,12 +405,23 @@ void __blk_run_queue(struct request_queue *q)
{
blk_remove_plug(q);
+ if (unlikely(blk_queue_stopped(q)))
+ return;
+
+ if (elv_queue_empty(q))
+ return;
+
/*
* Only recurse once to avoid overrunning the stack, let the unplug
* handling reinvoke the handler shortly if we already got there.
*/
- if (!elv_queue_empty(q))
- blk_invoke_request_fn(q);
+ if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) {
+ q->request_fn(q);
+ queue_flag_clear(QUEUE_FLAG_REENTER, q);
+ } else {
+ queue_flag_set(QUEUE_FLAG_PLUGGED, q);
+ kblockd_schedule_work(q, &q->unplug_work);
+ }
}
EXPORT_SYMBOL(__blk_run_queue);
@@ -440,9 +431,7 @@ EXPORT_SYMBOL(__blk_run_queue);
*
* Description:
* Invoke request handling on this queue, if it has pending work to do.
- * May be used to restart queueing when a request has completed. Also
- * See @blk_start_queueing.
- *
+ * May be used to restart queueing when a request has completed.
*/
void blk_run_queue(struct request_queue *q)
{
@@ -902,28 +891,6 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask)
EXPORT_SYMBOL(blk_get_request);
/**
- * blk_start_queueing - initiate dispatch of requests to device
- * @q: request queue to kick into gear
- *
- * This is basically a helper to remove the need to know whether a queue
- * is plugged or not if someone just wants to initiate dispatch of requests
- * for this queue. Should be used to start queueing on a device outside
- * of ->request_fn() context. Also see @blk_run_queue.
- *
- * The queue lock must be held with interrupts disabled.
- */
-void blk_start_queueing(struct request_queue *q)
-{
- if (!blk_queue_plugged(q)) {
- if (unlikely(blk_queue_stopped(q)))
- return;
- q->request_fn(q);
- } else
- __generic_unplug_device(q);
-}
-EXPORT_SYMBOL(blk_start_queueing);
-
-/**
* blk_requeue_request - put a request back on queue
* @q: request queue where request should be inserted
* @rq: request to be inserted
@@ -935,6 +902,8 @@ EXPORT_SYMBOL(blk_start_queueing);
*/
void blk_requeue_request(struct request_queue *q, struct request *rq)
{
+ BUG_ON(blk_queued_rq(rq));
+
blk_delete_timer(rq);
blk_clear_rq_complete(rq);
trace_block_rq_requeue(q, rq);
@@ -977,7 +946,6 @@ void blk_insert_request(struct request_queue *q, struct request *rq,
* barrier
*/
rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->cmd_flags |= REQ_SOFTBARRIER;
rq->special = data;
@@ -991,7 +959,7 @@ void blk_insert_request(struct request_queue *q, struct request *rq,
drive_stat_acct(rq, 1);
__elv_add_request(q, rq, where, 0);
- blk_start_queueing(q);
+ __blk_run_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags);
}
EXPORT_SYMBOL(blk_insert_request);
@@ -1113,16 +1081,13 @@ void init_request_from_bio(struct request *req, struct bio *bio)
if (bio_failfast_driver(bio))
req->cmd_flags |= REQ_FAILFAST_DRIVER;
- /*
- * REQ_BARRIER implies no merging, but lets make it explicit
- */
if (unlikely(bio_discard(bio))) {
req->cmd_flags |= REQ_DISCARD;
if (bio_barrier(bio))
req->cmd_flags |= REQ_SOFTBARRIER;
req->q->prepare_discard_fn(req->q, req);
} else if (unlikely(bio_barrier(bio)))
- req->cmd_flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
+ req->cmd_flags |= REQ_HARDBARRIER;
if (bio_sync(bio))
req->cmd_flags |= REQ_RW_SYNC;
@@ -1132,9 +1097,8 @@ void init_request_from_bio(struct request *req, struct bio *bio)
req->cmd_flags |= REQ_NOIDLE;
req->errors = 0;
- req->hard_sector = req->sector = bio->bi_sector;
+ req->__sector = bio->bi_sector;
req->ioprio = bio_prio(bio);
- req->start_time = jiffies;
blk_rq_bio_prep(req->q, req, bio);
}
@@ -1150,14 +1114,13 @@ static inline bool queue_should_plug(struct request_queue *q)
static int __make_request(struct request_queue *q, struct bio *bio)
{
struct request *req;
- int el_ret, nr_sectors;
+ int el_ret;
+ unsigned int bytes = bio->bi_size;
const unsigned short prio = bio_prio(bio);
const int sync = bio_sync(bio);
const int unplug = bio_unplug(bio);
int rw_flags;
- nr_sectors = bio_sectors(bio);
-
/*
* low level driver can indicate that it wants pages above a
* certain limit bounced to low memory (ie for highmem, or even
@@ -1182,7 +1145,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
req->biotail->bi_next = bio;
req->biotail = bio;
- req->nr_sectors = req->hard_nr_sectors += nr_sectors;
+ req->__data_len += bytes;
req->ioprio = ioprio_best(req->ioprio, prio);
if (!blk_rq_cpu_valid(req))
req->cpu = bio->bi_comp_cpu;
@@ -1208,10 +1171,8 @@ static int __make_request(struct request_queue *q, struct bio *bio)
* not touch req->buffer either...
*/
req->buffer = bio_data(bio);
- req->current_nr_sectors = bio_cur_sectors(bio);
- req->hard_cur_sectors = req->current_nr_sectors;
- req->sector = req->hard_sector = bio->bi_sector;
- req->nr_sectors = req->hard_nr_sectors += nr_sectors;
+ req->__sector = bio->bi_sector;
+ req->__data_len += bytes;
req->ioprio = ioprio_best(req->ioprio, prio);
if (!blk_rq_cpu_valid(req))
req->cpu = bio->bi_comp_cpu;
@@ -1277,7 +1238,7 @@ static inline void blk_partition_remap(struct bio *bio)
bio->bi_bdev = bdev->bd_contains;
trace_block_remap(bdev_get_queue(bio->bi_bdev), bio,
- bdev->bd_dev, bio->bi_sector,
+ bdev->bd_dev,
bio->bi_sector - p->start_sect);
}
}
@@ -1446,8 +1407,7 @@ static inline void __generic_make_request(struct bio *bio)
goto end_io;
if (old_sector != -1)
- trace_block_remap(q, bio, old_dev, bio->bi_sector,
- old_sector);
+ trace_block_remap(q, bio, old_dev, old_sector);
trace_block_bio_queue(q, bio);
@@ -1593,8 +1553,8 @@ EXPORT_SYMBOL(submit_bio);
*/
int blk_rq_check_limits(struct request_queue *q, struct request *rq)
{
- if (rq->nr_sectors > q->max_sectors ||
- rq->data_len > q->max_hw_sectors << 9) {
+ if (blk_rq_sectors(rq) > q->max_sectors ||
+ blk_rq_bytes(rq) > q->max_hw_sectors << 9) {
printk(KERN_ERR "%s: over max size limit.\n", __func__);
return -EIO;
}
@@ -1651,40 +1611,15 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq)
}
EXPORT_SYMBOL_GPL(blk_insert_cloned_request);
-/**
- * blkdev_dequeue_request - dequeue request and start timeout timer
- * @req: request to dequeue
- *
- * Dequeue @req and start timeout timer on it. This hands off the
- * request to the driver.
- *
- * Block internal functions which don't want to start timer should
- * call elv_dequeue_request().
- */
-void blkdev_dequeue_request(struct request *req)
-{
- elv_dequeue_request(req->q, req);
-
- /*
- * We are now handing the request to the hardware, add the
- * timeout handler.
- */
- blk_add_timer(req);
-}
-EXPORT_SYMBOL(blkdev_dequeue_request);
-
static void blk_account_io_completion(struct request *req, unsigned int bytes)
{
- if (!blk_do_io_stat(req))
- return;
-
- if (blk_fs_request(req)) {
+ if (blk_do_io_stat(req)) {
const int rw = rq_data_dir(req);
struct hd_struct *part;
int cpu;
cpu = part_stat_lock();
- part = disk_map_sector_rcu(req->rq_disk, req->sector);
+ part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
part_stat_add(cpu, part, sectors[rw], bytes >> 9);
part_stat_unlock();
}
@@ -1692,22 +1627,19 @@ static void blk_account_io_completion(struct request *req, unsigned int bytes)
static void blk_account_io_done(struct request *req)
{
- if (!blk_do_io_stat(req))
- return;
-
/*
* Account IO completion. bar_rq isn't accounted as a normal
* IO on queueing nor completion. Accounting the containing
* request is enough.
*/
- if (blk_fs_request(req) && req != &req->q->bar_rq) {
+ if (blk_do_io_stat(req) && req != &req->q->bar_rq) {
unsigned long duration = jiffies - req->start_time;
const int rw = rq_data_dir(req);
struct hd_struct *part;
int cpu;
cpu = part_stat_lock();
- part = disk_map_sector_rcu(req->rq_disk, req->sector);
+ part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
part_stat_inc(cpu, part, ios[rw]);
part_stat_add(cpu, part, ticks[rw], duration);
@@ -1719,38 +1651,217 @@ static void blk_account_io_done(struct request *req)
}
/**
- * __end_that_request_first - end I/O on a request
- * @req: the request being processed
+ * blk_peek_request - peek at the top of a request queue
+ * @q: request queue to peek at
+ *
+ * Description:
+ * Return the request at the top of @q. The returned request
+ * should be started using blk_start_request() before LLD starts
+ * processing it.
+ *
+ * Return:
+ * Pointer to the request at the top of @q if available. Null
+ * otherwise.
+ *
+ * Context:
+ * queue_lock must be held.
+ */
+struct request *blk_peek_request(struct request_queue *q)
+{
+ struct request *rq;
+ int ret;
+
+ while ((rq = __elv_next_request(q)) != NULL) {
+ if (!(rq->cmd_flags & REQ_STARTED)) {
+ /*
+ * This is the first time the device driver
+ * sees this request (possibly after
+ * requeueing). Notify IO scheduler.
+ */
+ if (blk_sorted_rq(rq))
+ elv_activate_rq(q, rq);
+
+ /*
+ * just mark as started even if we don't start
+ * it, a request that has been delayed should
+ * not be passed by new incoming requests
+ */
+ rq->cmd_flags |= REQ_STARTED;
+ trace_block_rq_issue(q, rq);
+ }
+
+ if (!q->boundary_rq || q->boundary_rq == rq) {
+ q->end_sector = rq_end_sector(rq);
+ q->boundary_rq = NULL;
+ }
+
+ if (rq->cmd_flags & REQ_DONTPREP)
+ break;
+
+ if (q->dma_drain_size && blk_rq_bytes(rq)) {
+ /*
+ * make sure space for the drain appears we
+ * know we can do this because max_hw_segments
+ * has been adjusted to be one fewer than the
+ * device can handle
+ */
+ rq->nr_phys_segments++;
+ }
+
+ if (!q->prep_rq_fn)
+ break;
+
+ ret = q->prep_rq_fn(q, rq);
+ if (ret == BLKPREP_OK) {
+ break;
+ } else if (ret == BLKPREP_DEFER) {
+ /*
+ * the request may have been (partially) prepped.
+ * we need to keep this request in the front to
+ * avoid resource deadlock. REQ_STARTED will
+ * prevent other fs requests from passing this one.
+ */
+ if (q->dma_drain_size && blk_rq_bytes(rq) &&
+ !(rq->cmd_flags & REQ_DONTPREP)) {
+ /*
+ * remove the space for the drain we added
+ * so that we don't add it again
+ */
+ --rq->nr_phys_segments;
+ }
+
+ rq = NULL;
+ break;
+ } else if (ret == BLKPREP_KILL) {
+ rq->cmd_flags |= REQ_QUIET;
+ __blk_end_request_all(rq, -EIO);
+ } else {
+ printk(KERN_ERR "%s: bad return=%d\n", __func__, ret);
+ break;
+ }
+ }
+
+ return rq;
+}
+EXPORT_SYMBOL(blk_peek_request);
+
+void blk_dequeue_request(struct request *rq)
+{
+ struct request_queue *q = rq->q;
+
+ BUG_ON(list_empty(&rq->queuelist));
+ BUG_ON(ELV_ON_HASH(rq));
+
+ list_del_init(&rq->queuelist);
+
+ /*
+ * the time frame between a request being removed from the lists
+ * and to it is freed is accounted as io that is in progress at
+ * the driver side.
+ */
+ if (blk_account_rq(rq))
+ q->in_flight++;
+}
+
+/**
+ * blk_start_request - start request processing on the driver
+ * @req: request to dequeue
+ *
+ * Description:
+ * Dequeue @req and start timeout timer on it. This hands off the
+ * request to the driver.
+ *
+ * Block internal functions which don't want to start timer should
+ * call blk_dequeue_request().
+ *
+ * Context:
+ * queue_lock must be held.
+ */
+void blk_start_request(struct request *req)
+{
+ blk_dequeue_request(req);
+
+ /*
+ * We are now handing the request to the hardware, add the
+ * timeout handler.
+ */
+ blk_add_timer(req);
+}
+EXPORT_SYMBOL(blk_start_request);
+
+/**
+ * blk_fetch_request - fetch a request from a request queue
+ * @q: request queue to fetch a request from
+ *
+ * Description:
+ * Return the request at the top of @q. The request is started on
+ * return and LLD can start processing it immediately.
+ *
+ * Return:
+ * Pointer to the request at the top of @q if available. Null
+ * otherwise.
+ *
+ * Context:
+ * queue_lock must be held.
+ */
+struct request *blk_fetch_request(struct request_queue *q)
+{
+ struct request *rq;
+
+ rq = blk_peek_request(q);
+ if (rq)
+ blk_start_request(rq);
+ return rq;
+}
+EXPORT_SYMBOL(blk_fetch_request);
+
+/**
+ * blk_update_request - Special helper function for request stacking drivers
+ * @rq: the request being processed
* @error: %0 for success, < %0 for error
- * @nr_bytes: number of bytes to complete
+ * @nr_bytes: number of bytes to complete @rq
*
* Description:
- * Ends I/O on a number of bytes attached to @req, and sets it up
- * for the next range of segments (if any) in the cluster.
+ * Ends I/O on a number of bytes attached to @rq, but doesn't complete
+ * the request structure even if @rq doesn't have leftover.
+ * If @rq has leftover, sets it up for the next range of segments.
+ *
+ * This special helper function is only for request stacking drivers
+ * (e.g. request-based dm) so that they can handle partial completion.
+ * Actual device drivers should use blk_end_request instead.
+ *
+ * Passing the result of blk_rq_bytes() as @nr_bytes guarantees
+ * %false return from this function.
*
* Return:
- * %0 - we are done with this request, call end_that_request_last()
- * %1 - still buffers pending for this request
+ * %false - this request doesn't have any more data
+ * %true - this request has more data
**/
-static int __end_that_request_first(struct request *req, int error,
- int nr_bytes)
+bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
{
int total_bytes, bio_nbytes, next_idx = 0;
struct bio *bio;
+ if (!req->bio)
+ return false;
+
trace_block_rq_complete(req->q, req);
/*
- * for a REQ_TYPE_BLOCK_PC request, we want to carry any eventual
- * sense key with us all the way through
+ * For fs requests, rq is just carrier of independent bio's
+ * and each partial completion should be handled separately.
+ * Reset per-request error on each partial completion.
+ *
+ * TODO: tj: This is too subtle. It would be better to let
+ * low level drivers do what they see fit.
*/
- if (!blk_pc_request(req))
+ if (blk_fs_request(req))
req->errors = 0;
if (error && (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET))) {
printk(KERN_ERR "end_request: I/O error, dev %s, sector %llu\n",
req->rq_disk ? req->rq_disk->disk_name : "?",
- (unsigned long long)req->sector);
+ (unsigned long long)blk_rq_pos(req));
}
blk_account_io_completion(req, nr_bytes);
@@ -1810,8 +1921,15 @@ static int __end_that_request_first(struct request *req, int error,
/*
* completely done
*/
- if (!req->bio)
- return 0;
+ if (!req->bio) {
+ /*
+ * Reset counters so that the request stacking driver
+ * can find how many bytes remain in the request
+ * later.
+ */
+ req->__data_len = 0;
+ return false;
+ }
/*
* if the request wasn't completed, update state
@@ -1823,22 +1941,56 @@ static int __end_that_request_first(struct request *req, int error,
bio_iovec(bio)->bv_len -= nr_bytes;
}
- blk_recalc_rq_sectors(req, total_bytes >> 9);
+ req->__data_len -= total_bytes;
+ req->buffer = bio_data(req->bio);
+
+ /* update sector only for requests with clear definition of sector */
+ if (blk_fs_request(req) || blk_discard_rq(req))
+ req->__sector += total_bytes >> 9;
+
+ /*
+ * If total number of sectors is less than the first segment
+ * size, something has gone terribly wrong.
+ */
+ if (blk_rq_bytes(req) < blk_rq_cur_bytes(req)) {
+ printk(KERN_ERR "blk: request botched\n");
+ req->__data_len = blk_rq_cur_bytes(req);
+ }
+
+ /* recalculate the number of segments */
blk_recalc_rq_segments(req);
- return 1;
+
+ return true;
+}
+EXPORT_SYMBOL_GPL(blk_update_request);
+
+static bool blk_update_bidi_request(struct request *rq, int error,
+ unsigned int nr_bytes,
+ unsigned int bidi_bytes)
+{
+ if (blk_update_request(rq, error, nr_bytes))
+ return true;
+
+ /* Bidi request must be completed as a whole */
+ if (unlikely(blk_bidi_rq(rq)) &&
+ blk_update_request(rq->next_rq, error, bidi_bytes))
+ return true;
+
+ add_disk_randomness(rq->rq_disk);
+
+ return false;
}
/*
* queue lock must be held
*/
-static void end_that_request_last(struct request *req, int error)
+static void blk_finish_request(struct request *req, int error)
{
+ BUG_ON(blk_queued_rq(req));
+
if (blk_rq_tagged(req))
blk_queue_end_tag(req->q, req);
- if (blk_queued_rq(req))
- elv_dequeue_request(req->q, req);
-
if (unlikely(laptop_mode) && blk_fs_request(req))
laptop_io_completion();
@@ -1857,248 +2009,65 @@ static void end_that_request_last(struct request *req, int error)
}
/**
- * blk_rq_bytes - Returns bytes left to complete in the entire request
- * @rq: the request being processed
- **/
-unsigned int blk_rq_bytes(struct request *rq)
-{
- if (blk_fs_request(rq))
- return rq->hard_nr_sectors << 9;
-
- return rq->data_len;
-}
-EXPORT_SYMBOL_GPL(blk_rq_bytes);
-
-/**
- * blk_rq_cur_bytes - Returns bytes left to complete in the current segment
- * @rq: the request being processed
- **/
-unsigned int blk_rq_cur_bytes(struct request *rq)
-{
- if (blk_fs_request(rq))
- return rq->current_nr_sectors << 9;
-
- if (rq->bio)
- return rq->bio->bi_size;
-
- return rq->data_len;
-}
-EXPORT_SYMBOL_GPL(blk_rq_cur_bytes);
-
-/**
- * end_request - end I/O on the current segment of the request
- * @req: 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 I/O completions.
- * Modern drivers typically end I/O 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. Use blk_end_request() or __blk_end_request() to end a request.
- **/
-void end_request(struct request *req, int uptodate)
-{
- int error = 0;
-
- if (uptodate <= 0)
- error = uptodate ? uptodate : -EIO;
-
- __blk_end_request(req, error, req->hard_cur_sectors << 9);
-}
-EXPORT_SYMBOL(end_request);
-
-static int end_that_request_data(struct request *rq, int error,
- unsigned int nr_bytes, unsigned int bidi_bytes)
-{
- if (rq->bio) {
- if (__end_that_request_first(rq, error, nr_bytes))
- return 1;
-
- /* Bidi request must be completed as a whole */
- if (blk_bidi_rq(rq) &&
- __end_that_request_first(rq->next_rq, error, bidi_bytes))
- return 1;
- }
-
- return 0;
-}
-
-/**
- * blk_end_io - Generic end_io function to complete a request.
- * @rq: the request being processed
- * @error: %0 for success, < %0 for error
- * @nr_bytes: number of bytes to complete @rq
- * @bidi_bytes: number of bytes to complete @rq->next_rq
- * @drv_callback: function called between completion of bios in the request
- * and completion of the request.
- * If the callback returns non %0, this helper returns without
- * completion of the request.
+ * blk_end_bidi_request - Complete a bidi request
+ * @rq: the request to complete
+ * @error: %0 for success, < %0 for error
+ * @nr_bytes: number of bytes to complete @rq
+ * @bidi_bytes: number of bytes to complete @rq->next_rq
*
* Description:
* Ends I/O on a number of bytes attached to @rq and @rq->next_rq.
- * If @rq has leftover, sets it up for the next range of segments.
+ * Drivers that supports bidi can safely call this member for any
+ * type of request, bidi or uni. In the later case @bidi_bytes is
+ * just ignored.
*
* Return:
- * %0 - we are done with this request
- * %1 - this request is not freed yet, it still has pending buffers.
+ * %false - we are done with this request
+ * %true - still buffers pending for this request
**/
-static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes,
- unsigned int bidi_bytes,
- int (drv_callback)(struct request *))
+bool blk_end_bidi_request(struct request *rq, int error,
+ unsigned int nr_bytes, unsigned int bidi_bytes)
{
struct request_queue *q = rq->q;
- unsigned long flags = 0UL;
-
- if (end_that_request_data(rq, error, nr_bytes, bidi_bytes))
- return 1;
-
- /* Special feature for tricky drivers */
- if (drv_callback && drv_callback(rq))
- return 1;
+ unsigned long flags;
- add_disk_randomness(rq->rq_disk);
+ if (blk_update_bidi_request(rq, error, nr_bytes, bidi_bytes))
+ return true;
spin_lock_irqsave(q->queue_lock, flags);
- end_that_request_last(rq, error);
+ blk_finish_request(rq, error);
spin_unlock_irqrestore(q->queue_lock, flags);
- return 0;
+ return false;
}
+EXPORT_SYMBOL_GPL(blk_end_bidi_request);
/**
- * blk_end_request - Helper function for drivers to complete the request.
- * @rq: the request being processed
- * @error: %0 for success, < %0 for error
- * @nr_bytes: number of bytes to complete
- *
- * Description:
- * Ends I/O on a number of bytes attached to @rq.
- * If @rq has leftover, sets it up for the next range of segments.
- *
- * Return:
- * %0 - we are done with this request
- * %1 - still buffers pending for this request
- **/
-int blk_end_request(struct request *rq, int error, unsigned int nr_bytes)
-{
- return blk_end_io(rq, error, nr_bytes, 0, NULL);
-}
-EXPORT_SYMBOL_GPL(blk_end_request);
-
-/**
- * __blk_end_request - Helper function for drivers to complete the request.
- * @rq: the request being processed
- * @error: %0 for success, < %0 for error
- * @nr_bytes: number of bytes to complete
- *
- * Description:
- * Must be called with queue lock held unlike blk_end_request().
- *
- * Return:
- * %0 - we are done with this request
- * %1 - still buffers pending for this request
- **/
-int __blk_end_request(struct request *rq, int error, unsigned int nr_bytes)
-{
- if (rq->bio && __end_that_request_first(rq, error, nr_bytes))
- return 1;
-
- add_disk_randomness(rq->rq_disk);
-
- end_that_request_last(rq, error);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(__blk_end_request);
-
-/**
- * blk_end_bidi_request - Helper function for drivers to complete bidi request.
- * @rq: the bidi request being processed
+ * __blk_end_bidi_request - Complete a bidi request with queue lock held
+ * @rq: the request to complete
* @error: %0 for success, < %0 for error
* @nr_bytes: number of bytes to complete @rq
* @bidi_bytes: number of bytes to complete @rq->next_rq
*
* Description:
- * Ends I/O on a number of bytes attached to @rq and @rq->next_rq.
+ * Identical to blk_end_bidi_request() except that queue lock is
+ * assumed to be locked on entry and remains so on return.
*
* Return:
- * %0 - we are done with this request
- * %1 - still buffers pending for this request
+ * %false - we are done with this request
+ * %true - still buffers pending for this request
**/
-int blk_end_bidi_request(struct request *rq, int error, unsigned int nr_bytes,
- unsigned int bidi_bytes)
+bool __blk_end_bidi_request(struct request *rq, int error,
+ unsigned int nr_bytes, unsigned int bidi_bytes)
{
- return blk_end_io(rq, error, nr_bytes, bidi_bytes, NULL);
-}
-EXPORT_SYMBOL_GPL(blk_end_bidi_request);
+ if (blk_update_bidi_request(rq, error, nr_bytes, bidi_bytes))
+ return true;
-/**
- * blk_update_request - Special helper function for request stacking drivers
- * @rq: the request being processed
- * @error: %0 for success, < %0 for error
- * @nr_bytes: number of bytes to complete @rq
- *
- * Description:
- * Ends I/O on a number of bytes attached to @rq, but doesn't complete
- * the request structure even if @rq doesn't have leftover.
- * If @rq has leftover, sets it up for the next range of segments.
- *
- * This special helper function is only for request stacking drivers
- * (e.g. request-based dm) so that they can handle partial completion.
- * Actual device drivers should use blk_end_request instead.
- */
-void blk_update_request(struct request *rq, int error, unsigned int nr_bytes)
-{
- if (!end_that_request_data(rq, error, nr_bytes, 0)) {
- /*
- * These members are not updated in end_that_request_data()
- * when all bios are completed.
- * Update them so that the request stacking driver can find
- * how many bytes remain in the request later.
- */
- rq->nr_sectors = rq->hard_nr_sectors = 0;
- rq->current_nr_sectors = rq->hard_cur_sectors = 0;
- }
-}
-EXPORT_SYMBOL_GPL(blk_update_request);
+ blk_finish_request(rq, error);
-/**
- * blk_end_request_callback - Special helper function for tricky drivers
- * @rq: the request being processed
- * @error: %0 for success, < %0 for error
- * @nr_bytes: number of bytes to complete
- * @drv_callback: function called between completion of bios in the request
- * and completion of the request.
- * If the callback returns non %0, this helper returns without
- * completion of the request.
- *
- * Description:
- * Ends I/O on a number of bytes attached to @rq.
- * If @rq has leftover, sets it up for the next range of segments.
- *
- * This special helper function is used only for existing tricky drivers.
- * (e.g. cdrom_newpc_intr() of ide-cd)
- * This interface will be removed when such drivers are rewritten.
- * Don't use this interface in other places anymore.
- *
- * Return:
- * %0 - we are done with this request
- * %1 - this request is not freed yet.
- * this request still has pending buffers or
- * the driver doesn't want to finish this request yet.
- **/
-int blk_end_request_callback(struct request *rq, int error,
- unsigned int nr_bytes,
- int (drv_callback)(struct request *))
-{
- return blk_end_io(rq, error, nr_bytes, 0, drv_callback);
+ return false;
}
-EXPORT_SYMBOL_GPL(blk_end_request_callback);
+EXPORT_SYMBOL_GPL(__blk_end_bidi_request);
void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
struct bio *bio)
@@ -2111,11 +2080,7 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
rq->nr_phys_segments = bio_phys_segments(q, bio);
rq->buffer = bio_data(bio);
}
- rq->current_nr_sectors = bio_cur_sectors(bio);
- rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);
- rq->data_len = bio->bi_size;
-
+ rq->__data_len = bio->bi_size;
rq->bio = rq->biotail = bio;
if (bio->bi_bdev)
@@ -2158,6 +2123,9 @@ EXPORT_SYMBOL(kblockd_schedule_work);
int __init blk_dev_init(void)
{
+ BUILD_BUG_ON(__REQ_NR_BITS > 8 *
+ sizeof(((struct request *)0)->cmd_flags));
+
kblockd_workqueue = create_workqueue("kblockd");
if (!kblockd_workqueue)
panic("Failed to create kblockd\n");
diff --git a/block/blk-exec.c b/block/blk-exec.c
index 6af716d1e54e..49557e91f0da 100644
--- a/block/blk-exec.c
+++ b/block/blk-exec.c
@@ -51,7 +51,6 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
rq->rq_disk = bd_disk;
- rq->cmd_flags |= REQ_NOMERGE;
rq->end_io = done;
WARN_ON(irqs_disabled());
spin_lock_irq(q->queue_lock);
diff --git a/block/blk-map.c b/block/blk-map.c
index f103729b462f..56082bea4504 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -20,7 +20,7 @@ int blk_rq_append_bio(struct request_queue *q, struct request *rq,
rq->biotail->bi_next = bio;
rq->biotail = bio;
- rq->data_len += bio->bi_size;
+ rq->__data_len += bio->bi_size;
}
return 0;
}
@@ -156,7 +156,7 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
if (!bio_flagged(bio, BIO_USER_MAPPED))
rq->cmd_flags |= REQ_COPY_USER;
- rq->buffer = rq->data = NULL;
+ rq->buffer = NULL;
return 0;
unmap_rq:
blk_rq_unmap_user(bio);
@@ -235,7 +235,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
blk_queue_bounce(q, &bio);
bio_get(bio);
blk_rq_bio_prep(q, rq, bio);
- rq->buffer = rq->data = NULL;
+ rq->buffer = NULL;
return 0;
}
EXPORT_SYMBOL(blk_rq_map_user_iov);
@@ -313,7 +313,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
blk_rq_bio_prep(q, rq, bio);
blk_queue_bounce(q, &rq->bio);
- rq->buffer = rq->data = NULL;
+ rq->buffer = NULL;
return 0;
}
EXPORT_SYMBOL(blk_rq_map_kern);
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 23d2a6fe34a3..4974dd5767e5 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -9,35 +9,6 @@
#include "blk.h"
-void blk_recalc_rq_sectors(struct request *rq, int nsect)
-{
- if (blk_fs_request(rq) || blk_discard_rq(rq)) {
- rq->hard_sector += nsect;
- rq->hard_nr_sectors -= nsect;
-
- /*
- * Move the I/O submission pointers ahead if required.
- */
- if ((rq->nr_sectors >= rq->hard_nr_sectors) &&
- (rq->sector <= rq->hard_sector)) {
- rq->sector = rq->hard_sector;
- rq->nr_sectors = rq->hard_nr_sectors;
- rq->hard_cur_sectors = bio_cur_sectors(rq->bio);
- rq->current_nr_sectors = rq->hard_cur_sectors;
- rq->buffer = bio_data(rq->bio);
- }
-
- /*
- * if total number of sectors is less than the first segment
- * size, something has gone terribly wrong
- */
- if (rq->nr_sectors < rq->current_nr_sectors) {
- printk(KERN_ERR "blk: request botched\n");
- rq->nr_sectors = rq->current_nr_sectors;
- }
- }
-}
-
static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
struct bio *bio)
{
@@ -199,8 +170,9 @@ new_segment:
if (unlikely(rq->cmd_flags & REQ_COPY_USER) &&
- (rq->data_len & q->dma_pad_mask)) {
- unsigned int pad_len = (q->dma_pad_mask & ~rq->data_len) + 1;
+ (blk_rq_bytes(rq) & q->dma_pad_mask)) {
+ unsigned int pad_len =
+ (q->dma_pad_mask & ~blk_rq_bytes(rq)) + 1;
sg->length += pad_len;
rq->extra_len += pad_len;
@@ -259,7 +231,7 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req,
else
max_sectors = q->max_sectors;
- if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
+ if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
req->cmd_flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
@@ -284,7 +256,7 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req,
max_sectors = q->max_sectors;
- if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
+ if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
req->cmd_flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
@@ -315,7 +287,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
/*
* Will it become too large?
*/
- if ((req->nr_sectors + next->nr_sectors) > q->max_sectors)
+ if ((blk_rq_sectors(req) + blk_rq_sectors(next)) > q->max_sectors)
return 0;
total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
@@ -345,7 +317,7 @@ static void blk_account_io_merge(struct request *req)
int cpu;
cpu = part_stat_lock();
- part = disk_map_sector_rcu(req->rq_disk, req->sector);
+ part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
part_round_stats(cpu, part);
part_dec_in_flight(part);
@@ -366,7 +338,7 @@ static int attempt_merge(struct request_queue *q, struct request *req,
/*
* not contiguous
*/
- if (req->sector + req->nr_sectors != next->sector)
+ if (blk_rq_pos(req) + blk_rq_sectors(req) != blk_rq_pos(next))
return 0;
if (rq_data_dir(req) != rq_data_dir(next)
@@ -398,7 +370,7 @@ static int attempt_merge(struct request_queue *q, struct request *req,
req->biotail->bi_next = next->bio;
req->biotail = next->biotail;
- req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors;
+ req->__data_len += blk_rq_bytes(next);
elv_merge_requests(q, req, next);
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 3ff9bba3379a..26f9ec28f56c 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -383,16 +383,21 @@ struct kobj_type blk_queue_ktype = {
int blk_register_queue(struct gendisk *disk)
{
int ret;
+ struct device *dev = disk_to_dev(disk);
struct request_queue *q = disk->queue;
if (WARN_ON(!q))
return -ENXIO;
+ ret = blk_trace_init_sysfs(dev);
+ if (ret)
+ return ret;
+
if (!q->request_fn)
return 0;
- ret = kobject_add(&q->kobj, kobject_get(&disk_to_dev(disk)->kobj),
+ ret = kobject_add(&q->kobj, kobject_get(&dev->kobj),
"%s", "queue");
if (ret < 0)
return ret;
diff --git a/block/blk-tag.c b/block/blk-tag.c
index 3c518e3303ae..c260f7c30dda 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -374,7 +374,7 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
rq->cmd_flags |= REQ_QUEUED;
rq->tag = tag;
bqt->tag_index[tag] = rq;
- blkdev_dequeue_request(rq);
+ blk_start_request(rq);
list_add(&rq->queuelist, &q->tag_busy_list);
return 0;
}
diff --git a/block/blk-timeout.c b/block/blk-timeout.c
index 1ec0d503cacd..1ba7e0aca878 100644
--- a/block/blk-timeout.c
+++ b/block/blk-timeout.c
@@ -122,10 +122,8 @@ void blk_rq_timed_out_timer(unsigned long data)
if (blk_mark_rq_complete(rq))
continue;
blk_rq_timed_out(rq);
- } else {
- if (!next || time_after(next, rq->deadline))
- next = rq->deadline;
- }
+ } else if (!next || time_after(next, rq->deadline))
+ next = rq->deadline;
}
/*
@@ -176,16 +174,14 @@ void blk_add_timer(struct request *req)
BUG_ON(!list_empty(&req->timeout_list));
BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags));
- if (req->timeout)
- req->deadline = jiffies + req->timeout;
- else {
- req->deadline = jiffies + q->rq_timeout;
- /*
- * Some LLDs, like scsi, peek at the timeout to prevent
- * a command from being retried forever.
- */
+ /*
+ * Some LLDs, like scsi, peek at the timeout to prevent a
+ * command from being retried forever.
+ */
+ if (!req->timeout)
req->timeout = q->rq_timeout;
- }
+
+ req->deadline = jiffies + req->timeout;
list_add_tail(&req->timeout_list, &q->timeout_list);
/*
diff --git a/block/blk.h b/block/blk.h
index 79c85f7c9ff5..9e0042ca9495 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -13,6 +13,7 @@ extern struct kobj_type blk_queue_ktype;
void init_request_from_bio(struct request *req, struct bio *bio);
void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
struct bio *bio);
+void blk_dequeue_request(struct request *rq);
void __blk_queue_free_tags(struct request_queue *q);
void blk_unplug_work(struct work_struct *work);
@@ -43,6 +44,43 @@ static inline void blk_clear_rq_complete(struct request *rq)
clear_bit(REQ_ATOM_COMPLETE, &rq->atomic_flags);
}
+/*
+ * Internal elevator interface
+ */
+#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash))
+
+static inline struct request *__elv_next_request(struct request_queue *q)
+{
+ struct request *rq;
+
+ while (1) {
+ while (!list_empty(&q->queue_head)) {
+ rq = list_entry_rq(q->queue_head.next);
+ if (blk_do_ordered(q, &rq))
+ return rq;
+ }
+
+ if (!q->elevator->ops->elevator_dispatch_fn(q, 0))
+ return NULL;
+ }
+}
+
+static inline void elv_activate_rq(struct request_queue *q, struct request *rq)
+{
+ struct elevator_queue *e = q->elevator;
+
+ if (e->ops->elevator_activate_req_fn)
+ e->ops->elevator_activate_req_fn(q, rq);
+}
+
+static inline void elv_deactivate_rq(struct request_queue *q, struct request *rq)
+{
+ struct elevator_queue *e = q->elevator;
+
+ if (e->ops->elevator_deactivate_req_fn)
+ e->ops->elevator_deactivate_req_fn(q, rq);
+}
+
#ifdef CONFIG_FAIL_IO_TIMEOUT
int blk_should_fake_timeout(struct request_queue *);
ssize_t part_timeout_show(struct device *, struct device_attribute *, char *);
@@ -64,7 +102,6 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req,
int attempt_back_merge(struct request_queue *q, struct request *rq);
int attempt_front_merge(struct request_queue *q, struct request *rq);
void blk_recalc_rq_segments(struct request *rq);
-void blk_recalc_rq_sectors(struct request *rq, int nsect);
void blk_queue_congestion_threshold(struct request_queue *q);
@@ -112,9 +149,17 @@ static inline int blk_cpu_to_group(int cpu)
#endif
}
+/*
+ * Contribute to IO statistics IFF:
+ *
+ * a) it's attached to a gendisk, and
+ * b) the queue had IO stats enabled when this request was started, and
+ * c) it's a file system request
+ */
static inline int blk_do_io_stat(struct request *rq)
{
- return rq->rq_disk && blk_rq_io_stat(rq);
+ return rq->rq_disk && blk_rq_io_stat(rq) && blk_fs_request(rq) &&
+ blk_discard_rq(rq);
}
#endif
diff --git a/block/bsg.c b/block/bsg.c
index 206060e795da..2d746e34f4c2 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -445,14 +445,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
}
if (rq->next_rq) {
- hdr->dout_resid = rq->data_len;
- hdr->din_resid = rq->next_rq->data_len;
+ hdr->dout_resid = rq->resid_len;
+ hdr->din_resid = rq->next_rq->resid_len;
blk_rq_unmap_user(bidi_bio);
blk_put_request(rq->next_rq);
} else if (rq_data_dir(rq) == READ)
- hdr->din_resid = rq->data_len;
+ hdr->din_resid = rq->resid_len;
else
- hdr->dout_resid = rq->data_len;
+ hdr->dout_resid = rq->resid_len;
/*
* If the request generated a negative error number, return it
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index a55a9bd75bd1..99ac4304d711 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -349,8 +349,8 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2)
else if (rq_is_meta(rq2) && !rq_is_meta(rq1))
return rq2;
- s1 = rq1->sector;
- s2 = rq2->sector;
+ s1 = blk_rq_pos(rq1);
+ s2 = blk_rq_pos(rq2);
last = cfqd->last_position;
@@ -579,9 +579,9 @@ cfq_prio_tree_lookup(struct cfq_data *cfqd, struct rb_root *root,
* Sort strictly based on sector. Smallest to the left,
* largest to the right.
*/
- if (sector > cfqq->next_rq->sector)
+ if (sector > blk_rq_pos(cfqq->next_rq))
n = &(*p)->rb_right;
- else if (sector < cfqq->next_rq->sector)
+ else if (sector < blk_rq_pos(cfqq->next_rq))
n = &(*p)->rb_left;
else
break;
@@ -611,8 +611,8 @@ static void cfq_prio_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq)
return;
cfqq->p_root = &cfqd->prio_trees[cfqq->org_ioprio];
- __cfqq = cfq_prio_tree_lookup(cfqd, cfqq->p_root, cfqq->next_rq->sector,
- &parent, &p);
+ __cfqq = cfq_prio_tree_lookup(cfqd, cfqq->p_root,
+ blk_rq_pos(cfqq->next_rq), &parent, &p);
if (!__cfqq) {
rb_link_node(&cfqq->p_node, parent, p);
rb_insert_color(&cfqq->p_node, cfqq->p_root);
@@ -760,7 +760,7 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq)
cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d",
cfqd->rq_in_driver);
- cfqd->last_position = rq->hard_sector + rq->hard_nr_sectors;
+ cfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
}
static void cfq_deactivate_request(struct request_queue *q, struct request *rq)
@@ -949,10 +949,10 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd,
static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd,
struct request *rq)
{
- if (rq->sector >= cfqd->last_position)
- return rq->sector - cfqd->last_position;
+ if (blk_rq_pos(rq) >= cfqd->last_position)
+ return blk_rq_pos(rq) - cfqd->last_position;
else
- return cfqd->last_position - rq->sector;
+ return cfqd->last_position - blk_rq_pos(rq);
}
#define CIC_SEEK_THR 8 * 1024
@@ -996,7 +996,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
if (cfq_rq_close(cfqd, __cfqq->next_rq))
return __cfqq;
- if (__cfqq->next_rq->sector < sector)
+ if (blk_rq_pos(__cfqq->next_rq) < sector)
node = rb_next(&__cfqq->p_node);
else
node = rb_prev(&__cfqq->p_node);
@@ -1918,10 +1918,10 @@ cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic,
if (!cic->last_request_pos)
sdist = 0;
- else if (cic->last_request_pos < rq->sector)
- sdist = rq->sector - cic->last_request_pos;
+ else if (cic->last_request_pos < blk_rq_pos(rq))
+ sdist = blk_rq_pos(rq) - cic->last_request_pos;
else
- sdist = cic->last_request_pos - rq->sector;
+ sdist = cic->last_request_pos - blk_rq_pos(rq);
/*
* Don't allow the seek distance to get too large from the
@@ -2071,7 +2071,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
cfq_update_io_seektime(cfqd, cic, rq);
cfq_update_idle_window(cfqd, cfqq, cic);
- cic->last_request_pos = rq->sector + rq->nr_sectors;
+ cic->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
if (cfqq == cfqd->active_queue) {
/*
@@ -2088,7 +2088,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
if (blk_rq_bytes(rq) > PAGE_CACHE_SIZE ||
cfqd->busy_queues > 1) {
del_timer(&cfqd->idle_slice_timer);
- blk_start_queueing(cfqd->queue);
+ __blk_run_queue(cfqd->queue);
}
cfq_mark_cfqq_must_dispatch(cfqq);
}
@@ -2100,7 +2100,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
* this new queue is RT and the current one is BE
*/
cfq_preempt_queue(cfqd, cfqq);
- blk_start_queueing(cfqd->queue);
+ __blk_run_queue(cfqd->queue);
}
}
@@ -2345,7 +2345,7 @@ static void cfq_kick_queue(struct work_struct *work)
struct request_queue *q = cfqd->queue;
spin_lock_irq(q->queue_lock);
- blk_start_queueing(q);
+ __blk_run_queue(cfqd->queue);
spin_unlock_irq(q->queue_lock);
}
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index f87615dea46b..f8c218cd08e1 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -568,7 +568,7 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg)
memcpy(&buts.name, &cbuts.name, 32);
mutex_lock(&bdev->bd_mutex);
- ret = do_blk_trace_setup(q, b, bdev->bd_dev, &buts);
+ ret = do_blk_trace_setup(q, b, bdev->bd_dev, bdev, &buts);
mutex_unlock(&bdev->bd_mutex);
if (ret)
return ret;
diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c
index c4d991d4adef..b547cbca7b23 100644
--- a/block/deadline-iosched.c
+++ b/block/deadline-iosched.c
@@ -138,7 +138,7 @@ deadline_merge(struct request_queue *q, struct request **req, struct bio *bio)
__rq = elv_rb_find(&dd->sort_list[bio_data_dir(bio)], sector);
if (__rq) {
- BUG_ON(sector != __rq->sector);
+ BUG_ON(sector != blk_rq_pos(__rq));
if (elv_rq_merge_ok(__rq, bio)) {
ret = ELEVATOR_FRONT_MERGE;
diff --git a/block/elevator.c b/block/elevator.c
index 7073a9072577..918920056e42 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -52,8 +52,7 @@ static const int elv_hash_shift = 6;
#define ELV_HASH_FN(sec) \
(hash_long(ELV_HASH_BLOCK((sec)), elv_hash_shift))
#define ELV_HASH_ENTRIES (1 << elv_hash_shift)
-#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
-#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash))
+#define rq_hash_key(rq) (blk_rq_pos(rq) + blk_rq_sectors(rq))
DEFINE_TRACE(block_rq_insert);
DEFINE_TRACE(block_rq_issue);
@@ -120,9 +119,9 @@ static inline int elv_try_merge(struct request *__rq, struct bio *bio)
* we can merge and sequence is ok, check if it's possible
*/
if (elv_rq_merge_ok(__rq, bio)) {
- if (__rq->sector + __rq->nr_sectors == bio->bi_sector)
+ if (blk_rq_pos(__rq) + blk_rq_sectors(__rq) == bio->bi_sector)
ret = ELEVATOR_BACK_MERGE;
- else if (__rq->sector - bio_sectors(bio) == bio->bi_sector)
+ else if (blk_rq_pos(__rq) - bio_sectors(bio) == bio->bi_sector)
ret = ELEVATOR_FRONT_MERGE;
}
@@ -310,22 +309,6 @@ void elevator_exit(struct elevator_queue *e)
}
EXPORT_SYMBOL(elevator_exit);
-static void elv_activate_rq(struct request_queue *q, struct request *rq)
-{
- struct elevator_queue *e = q->elevator;
-
- if (e->ops->elevator_activate_req_fn)
- e->ops->elevator_activate_req_fn(q, rq);
-}
-
-static void elv_deactivate_rq(struct request_queue *q, struct request *rq)
-{
- struct elevator_queue *e = q->elevator;
-
- if (e->ops->elevator_deactivate_req_fn)
- e->ops->elevator_deactivate_req_fn(q, rq);
-}
-
static inline void __elv_rqhash_del(struct request *rq)
{
hlist_del_init(&rq->hash);
@@ -387,9 +370,9 @@ struct request *elv_rb_add(struct rb_root *root, struct request *rq)
parent = *p;
__rq = rb_entry(parent, struct request, rb_node);
- if (rq->sector < __rq->sector)
+ if (blk_rq_pos(rq) < blk_rq_pos(__rq))
p = &(*p)->rb_left;
- else if (rq->sector > __rq->sector)
+ else if (blk_rq_pos(rq) > blk_rq_pos(__rq))
p = &(*p)->rb_right;
else
return __rq;
@@ -417,9 +400,9 @@ struct request *elv_rb_find(struct rb_root *root, sector_t sector)
while (n) {
rq = rb_entry(n, struct request, rb_node);
- if (sector < rq->sector)
+ if (sector < blk_rq_pos(rq))
n = n->rb_left;
- else if (sector > rq->sector)
+ else if (sector > blk_rq_pos(rq))
n = n->rb_right;
else
return rq;
@@ -458,14 +441,14 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq)
break;
if (pos->cmd_flags & stop_flags)
break;
- if (rq->sector >= boundary) {
- if (pos->sector < boundary)
+ if (blk_rq_pos(rq) >= boundary) {
+ if (blk_rq_pos(pos) < boundary)
continue;
} else {
- if (pos->sector >= boundary)
+ if (blk_rq_pos(pos) >= boundary)
break;
}
- if (rq->sector >= pos->sector)
+ if (blk_rq_pos(rq) >= blk_rq_pos(pos))
break;
}
@@ -599,7 +582,7 @@ void elv_quiesce_start(struct request_queue *q)
*/
elv_drain_elevator(q);
while (q->rq.elvpriv) {
- blk_start_queueing(q);
+ __blk_run_queue(q);
spin_unlock_irq(q->queue_lock);
msleep(10);
spin_lock_irq(q->queue_lock);
@@ -643,8 +626,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
* with anything. There's no point in delaying queue
* processing.
*/
- blk_remove_plug(q);
- blk_start_queueing(q);
+ __blk_run_queue(q);
break;
case ELEVATOR_INSERT_SORT:
@@ -759,117 +741,6 @@ void elv_add_request(struct request_queue *q, struct request *rq, int where,
}
EXPORT_SYMBOL(elv_add_request);
-static inline struct request *__elv_next_request(struct request_queue *q)
-{
- struct request *rq;
-
- while (1) {
- while (!list_empty(&q->queue_head)) {
- rq = list_entry_rq(q->queue_head.next);
- if (blk_do_ordered(q, &rq))
- return rq;
- }
-
- if (!q->elevator->ops->elevator_dispatch_fn(q, 0))
- return NULL;
- }
-}
-
-struct request *elv_next_request(struct request_queue *q)
-{
- struct request *rq;
- int ret;
-
- while ((rq = __elv_next_request(q)) != NULL) {
- if (!(rq->cmd_flags & REQ_STARTED)) {
- /*
- * This is the first time the device driver
- * sees this request (possibly after
- * requeueing). Notify IO scheduler.
- */
- if (blk_sorted_rq(rq))
- elv_activate_rq(q, rq);
-
- /*
- * just mark as started even if we don't start
- * it, a request that has been delayed should
- * not be passed by new incoming requests
- */
- rq->cmd_flags |= REQ_STARTED;
- trace_block_rq_issue(q, rq);
- }
-
- if (!q->boundary_rq || q->boundary_rq == rq) {
- q->end_sector = rq_end_sector(rq);
- q->boundary_rq = NULL;
- }
-
- if (rq->cmd_flags & REQ_DONTPREP)
- break;
-
- if (q->dma_drain_size && rq->data_len) {
- /*
- * make sure space for the drain appears we
- * know we can do this because max_hw_segments
- * has been adjusted to be one fewer than the
- * device can handle
- */
- rq->nr_phys_segments++;
- }
-
- if (!q->prep_rq_fn)
- break;
-
- ret = q->prep_rq_fn(q, rq);
- if (ret == BLKPREP_OK) {
- break;
- } else if (ret == BLKPREP_DEFER) {
- /*
- * the request may have been (partially) prepped.
- * we need to keep this request in the front to
- * avoid resource deadlock. REQ_STARTED will
- * prevent other fs requests from passing this one.
- */
- if (q->dma_drain_size && rq->data_len &&
- !(rq->cmd_flags & REQ_DONTPREP)) {
- /*
- * remove the space for the drain we added
- * so that we don't add it again
- */
- --rq->nr_phys_segments;
- }
-
- rq = NULL;
- break;
- } else if (ret == BLKPREP_KILL) {
- rq->cmd_flags |= REQ_QUIET;
- __blk_end_request(rq, -EIO, blk_rq_bytes(rq));
- } else {
- printk(KERN_ERR "%s: bad return=%d\n", __func__, ret);
- break;
- }
- }
-
- return rq;
-}
-EXPORT_SYMBOL(elv_next_request);
-
-void elv_dequeue_request(struct request_queue *q, struct request *rq)
-{
- BUG_ON(list_empty(&rq->queuelist));
- BUG_ON(ELV_ON_HASH(rq));
-
- list_del_init(&rq->queuelist);
-
- /*
- * the time frame between a request being removed from the lists
- * and to it is freed is accounted as io that is in progress at
- * the driver side.
- */
- if (blk_account_rq(rq))
- q->in_flight++;
-}
-
int elv_queue_empty(struct request_queue *q)
{
struct elevator_queue *e = q->elevator;
@@ -939,7 +810,7 @@ void elv_abort_queue(struct request_queue *q)
rq = list_entry_rq(q->queue_head.next);
rq->cmd_flags |= REQ_QUIET;
trace_block_rq_abort(q, rq);
- __blk_end_request(rq, -EIO, blk_rq_bytes(rq));
+ __blk_end_request_all(rq, -EIO);
}
}
EXPORT_SYMBOL(elv_abort_queue);
@@ -971,7 +842,7 @@ void elv_completed_request(struct request_queue *q, struct request *rq)
blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN &&
(!next || blk_ordered_req_seq(next) > QUEUE_ORDSEQ_DRAIN)) {
blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0);
- blk_start_queueing(q);
+ __blk_run_queue(q);
}
}
}
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 82a0ca2f6729..a9670dd4b5de 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -230,7 +230,7 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
hdr->info = 0;
if (hdr->masked_status || hdr->host_status || hdr->driver_status)
hdr->info |= SG_INFO_CHECK;
- hdr->resid = rq->data_len;
+ hdr->resid = rq->resid_len;
hdr->sb_len_wr = 0;
if (rq->sense_len && hdr->sbp) {
@@ -500,9 +500,6 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
rq = blk_get_request(q, WRITE, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_BLOCK_PC;
- rq->data = NULL;
- rq->data_len = 0;
- rq->extra_len = 0;
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
rq->cmd[0] = cmd;
rq->cmd[4] = data;
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 74d0e622a515..4dfdd03e708f 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -241,6 +241,11 @@ config CRYPTO_XTS
key size 256, 384 or 512 bits. This implementation currently
can't handle a sectorsize which is not a multiple of 16 bytes.
+config CRYPTO_FPU
+ tristate
+ select CRYPTO_BLKCIPHER
+ select CRYPTO_MANAGER
+
comment "Hash modes"
config CRYPTO_HMAC
@@ -486,6 +491,7 @@ config CRYPTO_AES_NI_INTEL
select CRYPTO_AES_X86_64
select CRYPTO_CRYPTD
select CRYPTO_ALGAPI
+ select CRYPTO_FPU
help
Use Intel AES-NI instructions for AES algorithm.
@@ -505,6 +511,10 @@ config CRYPTO_AES_NI_INTEL
See <http://csrc.nist.gov/encryption/aes/> for more information.
+ In addition to AES cipher algorithm support, the
+ acceleration for some popular block cipher mode is supported
+ too, including ECB, CBC, CTR, LRW, PCBC, XTS.
+
config CRYPTO_ANUBIS
tristate "Anubis cipher algorithm"
select CRYPTO_ALGAPI
diff --git a/crypto/algboss.c b/crypto/algboss.c
index 6906f92aeac0..9908dd830c26 100644
--- a/crypto/algboss.c
+++ b/crypto/algboss.c
@@ -280,29 +280,13 @@ static struct notifier_block cryptomgr_notifier = {
static int __init cryptomgr_init(void)
{
- int err;
-
- err = testmgr_init();
- if (err)
- return err;
-
- err = crypto_register_notifier(&cryptomgr_notifier);
- if (err)
- goto free_testmgr;
-
- return 0;
-
-free_testmgr:
- testmgr_exit();
- return err;
+ return crypto_register_notifier(&cryptomgr_notifier);
}
static void __exit cryptomgr_exit(void)
{
int err = crypto_unregister_notifier(&cryptomgr_notifier);
BUG_ON(err);
-
- testmgr_exit();
}
subsys_initcall(cryptomgr_init);
diff --git a/crypto/api.c b/crypto/api.c
index 314dab96840e..f500fb840be9 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -221,7 +221,8 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask)
request_module(name);
- if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask) &&
+ if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask &
+ CRYPTO_ALG_NEED_FALLBACK) &&
snprintf(tmp, sizeof(tmp), "%s-all", name) < sizeof(tmp))
request_module(tmp);
@@ -579,20 +580,17 @@ EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
{
struct crypto_alg *alg;
- int size;
if (unlikely(!mem))
return;
alg = tfm->__crt_alg;
- size = ksize(mem);
if (!tfm->exit && alg->cra_exit)
alg->cra_exit(tfm);
crypto_exit_ops(tfm);
crypto_mod_put(alg);
- memset(mem, 0, size);
- kfree(mem);
+ kzfree(mem);
}
EXPORT_SYMBOL_GPL(crypto_destroy_tfm);
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index d14b22658d7a..ae5fa99d5d36 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -586,20 +586,24 @@ struct cryptd_ablkcipher *cryptd_alloc_ablkcipher(const char *alg_name,
u32 type, u32 mask)
{
char cryptd_alg_name[CRYPTO_MAX_ALG_NAME];
- struct crypto_ablkcipher *tfm;
+ struct crypto_tfm *tfm;
if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME,
"cryptd(%s)", alg_name) >= CRYPTO_MAX_ALG_NAME)
return ERR_PTR(-EINVAL);
- tfm = crypto_alloc_ablkcipher(cryptd_alg_name, type, mask);
+ type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
+ type |= CRYPTO_ALG_TYPE_BLKCIPHER;
+ mask &= ~CRYPTO_ALG_TYPE_MASK;
+ mask |= (CRYPTO_ALG_GENIV | CRYPTO_ALG_TYPE_BLKCIPHER_MASK);
+ tfm = crypto_alloc_base(cryptd_alg_name, type, mask);
if (IS_ERR(tfm))
return ERR_CAST(tfm);
- if (crypto_ablkcipher_tfm(tfm)->__crt_alg->cra_module != THIS_MODULE) {
- crypto_free_ablkcipher(tfm);
+ if (tfm->__crt_alg->cra_module != THIS_MODULE) {
+ crypto_free_tfm(tfm);
return ERR_PTR(-EINVAL);
}
- return __cryptd_ablkcipher_cast(tfm);
+ return __cryptd_ablkcipher_cast(__crypto_ablkcipher_cast(tfm));
}
EXPORT_SYMBOL_GPL(cryptd_alloc_ablkcipher);
diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c
index 2a342c8e52b3..3ca3b669d5d5 100644
--- a/crypto/eseqiv.c
+++ b/crypto/eseqiv.c
@@ -153,7 +153,8 @@ static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req)
if (err)
goto out;
- eseqiv_complete2(req);
+ if (giv != req->giv)
+ eseqiv_complete2(req);
out:
return err;
diff --git a/crypto/internal.h b/crypto/internal.h
index fc76e1f37fc3..113579a82dff 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -121,9 +121,6 @@ int crypto_register_notifier(struct notifier_block *nb);
int crypto_unregister_notifier(struct notifier_block *nb);
int crypto_probing_notify(unsigned long val, void *v);
-int __init testmgr_init(void);
-void testmgr_exit(void);
-
static inline void crypto_alg_put(struct crypto_alg *alg)
{
if (atomic_dec_and_test(&alg->cra_refcnt) && alg->cra_destroy)
diff --git a/crypto/pcompress.c b/crypto/pcompress.c
index ca9a4af91efe..bcadc03726b7 100644
--- a/crypto/pcompress.c
+++ b/crypto/pcompress.c
@@ -26,6 +26,7 @@
#include <linux/string.h>
#include <crypto/compress.h>
+#include <crypto/internal/compress.h>
#include "internal.h"
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index c3c9124209a1..9e4974eb7825 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -396,16 +396,16 @@ static void test_hash_speed(const char *algo, unsigned int sec,
struct scatterlist sg[TVMEMSIZE];
struct crypto_hash *tfm;
struct hash_desc desc;
- char output[1024];
+ static char output[1024];
int i;
int ret;
- printk("\ntesting speed of %s\n", algo);
+ printk(KERN_INFO "\ntesting speed of %s\n", algo);
tfm = crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
- printk("failed to load transform for %s: %ld\n", algo,
+ printk(KERN_ERR "failed to load transform for %s: %ld\n", algo,
PTR_ERR(tfm));
return;
}
@@ -414,7 +414,7 @@ static void test_hash_speed(const char *algo, unsigned int sec,
desc.flags = 0;
if (crypto_hash_digestsize(tfm) > sizeof(output)) {
- printk("digestsize(%u) > outputbuffer(%zu)\n",
+ printk(KERN_ERR "digestsize(%u) > outputbuffer(%zu)\n",
crypto_hash_digestsize(tfm), sizeof(output));
goto out;
}
@@ -427,12 +427,14 @@ static void test_hash_speed(const char *algo, unsigned int sec,
for (i = 0; speed[i].blen != 0; i++) {
if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) {
- printk("template (%u) too big for tvmem (%lu)\n",
+ printk(KERN_ERR
+ "template (%u) too big for tvmem (%lu)\n",
speed[i].blen, TVMEMSIZE * PAGE_SIZE);
goto out;
}
- printk("test%3u (%5u byte blocks,%5u bytes per update,%4u updates): ",
+ printk(KERN_INFO "test%3u "
+ "(%5u byte blocks,%5u bytes per update,%4u updates): ",
i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
if (sec)
@@ -443,7 +445,7 @@ static void test_hash_speed(const char *algo, unsigned int sec,
speed[i].plen, output);
if (ret) {
- printk("hashing failed ret=%d\n", ret);
+ printk(KERN_ERR "hashing failed ret=%d\n", ret);
break;
}
}
@@ -524,6 +526,7 @@ static void do_test(int m)
tcrypt_test("cbc(aes)");
tcrypt_test("lrw(aes)");
tcrypt_test("xts(aes)");
+ tcrypt_test("ctr(aes)");
tcrypt_test("rfc3686(ctr(aes))");
break;
@@ -665,6 +668,10 @@ static void do_test(int m)
tcrypt_test("zlib");
break;
+ case 45:
+ tcrypt_test("rfc4309(ccm(aes))");
+ break;
+
case 100:
tcrypt_test("hmac(md5)");
break;
@@ -701,6 +708,10 @@ static void do_test(int m)
tcrypt_test("hmac(rmd160)");
break;
+ case 150:
+ tcrypt_test("ansi_cprng");
+ break;
+
case 200:
test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
speed_template_16_24_32);
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index b50c3c6b17a2..f4cc1780aee2 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -19,6 +19,7 @@
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <crypto/rng.h>
#include "internal.h"
#include "testmgr.h"
@@ -84,6 +85,11 @@ struct hash_test_suite {
unsigned int count;
};
+struct cprng_test_suite {
+ struct cprng_testvec *vecs;
+ unsigned int count;
+};
+
struct alg_test_desc {
const char *alg;
int (*test)(const struct alg_test_desc *desc, const char *driver,
@@ -95,14 +101,12 @@ struct alg_test_desc {
struct comp_test_suite comp;
struct pcomp_test_suite pcomp;
struct hash_test_suite hash;
+ struct cprng_test_suite cprng;
} suite;
};
static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
-static char *xbuf[XBUFSIZE];
-static char *axbuf[XBUFSIZE];
-
static void hexdump(unsigned char *buf, unsigned int len)
{
print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
@@ -121,6 +125,33 @@ static void tcrypt_complete(struct crypto_async_request *req, int err)
complete(&res->completion);
}
+static int testmgr_alloc_buf(char *buf[XBUFSIZE])
+{
+ int i;
+
+ for (i = 0; i < XBUFSIZE; i++) {
+ buf[i] = (void *)__get_free_page(GFP_KERNEL);
+ if (!buf[i])
+ goto err_free_buf;
+ }
+
+ return 0;
+
+err_free_buf:
+ while (i-- > 0)
+ free_page((unsigned long)buf[i]);
+
+ return -ENOMEM;
+}
+
+static void testmgr_free_buf(char *buf[XBUFSIZE])
+{
+ int i;
+
+ for (i = 0; i < XBUFSIZE; i++)
+ free_page((unsigned long)buf[i]);
+}
+
static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
unsigned int tcount)
{
@@ -130,8 +161,12 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
char result[64];
struct ahash_request *req;
struct tcrypt_result tresult;
- int ret;
void *hash_buff;
+ char *xbuf[XBUFSIZE];
+ int ret = -ENOMEM;
+
+ if (testmgr_alloc_buf(xbuf))
+ goto out_nobuf;
init_completion(&tresult.completion);
@@ -139,7 +174,6 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
if (!req) {
printk(KERN_ERR "alg: hash: Failed to allocate request for "
"%s\n", algo);
- ret = -ENOMEM;
goto out_noreq;
}
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
@@ -265,6 +299,8 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
out:
ahash_request_free(req);
out_noreq:
+ testmgr_free_buf(xbuf);
+out_nobuf:
return ret;
}
@@ -273,7 +309,7 @@ static int test_aead(struct crypto_aead *tfm, int enc,
{
const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
unsigned int i, j, k, n, temp;
- int ret = 0;
+ int ret = -ENOMEM;
char *q;
char *key;
struct aead_request *req;
@@ -285,6 +321,13 @@ static int test_aead(struct crypto_aead *tfm, int enc,
void *input;
void *assoc;
char iv[MAX_IVLEN];
+ char *xbuf[XBUFSIZE];
+ char *axbuf[XBUFSIZE];
+
+ if (testmgr_alloc_buf(xbuf))
+ goto out_noxbuf;
+ if (testmgr_alloc_buf(axbuf))
+ goto out_noaxbuf;
if (enc == ENCRYPT)
e = "encryption";
@@ -297,7 +340,6 @@ static int test_aead(struct crypto_aead *tfm, int enc,
if (!req) {
printk(KERN_ERR "alg: aead: Failed to allocate request for "
"%s\n", algo);
- ret = -ENOMEM;
goto out;
}
@@ -363,6 +405,16 @@ static int test_aead(struct crypto_aead *tfm, int enc,
switch (ret) {
case 0:
+ if (template[i].novrfy) {
+ /* verification was supposed to fail */
+ printk(KERN_ERR "alg: aead: %s failed "
+ "on test %d for %s: ret was 0, "
+ "expected -EBADMSG\n",
+ e, j, algo);
+ /* so really, we got a bad message */
+ ret = -EBADMSG;
+ goto out;
+ }
break;
case -EINPROGRESS:
case -EBUSY:
@@ -372,6 +424,10 @@ static int test_aead(struct crypto_aead *tfm, int enc,
INIT_COMPLETION(result.completion);
break;
}
+ case -EBADMSG:
+ if (template[i].novrfy)
+ /* verification failure was expected */
+ continue;
/* fall through */
default:
printk(KERN_ERR "alg: aead: %s failed on test "
@@ -481,6 +537,16 @@ static int test_aead(struct crypto_aead *tfm, int enc,
switch (ret) {
case 0:
+ if (template[i].novrfy) {
+ /* verification was supposed to fail */
+ printk(KERN_ERR "alg: aead: %s failed "
+ "on chunk test %d for %s: ret "
+ "was 0, expected -EBADMSG\n",
+ e, j, algo);
+ /* so really, we got a bad message */
+ ret = -EBADMSG;
+ goto out;
+ }
break;
case -EINPROGRESS:
case -EBUSY:
@@ -490,6 +556,10 @@ static int test_aead(struct crypto_aead *tfm, int enc,
INIT_COMPLETION(result.completion);
break;
}
+ case -EBADMSG:
+ if (template[i].novrfy)
+ /* verification failure was expected */
+ continue;
/* fall through */
default:
printk(KERN_ERR "alg: aead: %s failed on "
@@ -546,6 +616,10 @@ static int test_aead(struct crypto_aead *tfm, int enc,
out:
aead_request_free(req);
+ testmgr_free_buf(axbuf);
+out_noaxbuf:
+ testmgr_free_buf(xbuf);
+out_noxbuf:
return ret;
}
@@ -554,10 +628,14 @@ static int test_cipher(struct crypto_cipher *tfm, int enc,
{
const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
unsigned int i, j, k;
- int ret;
char *q;
const char *e;
void *data;
+ char *xbuf[XBUFSIZE];
+ int ret = -ENOMEM;
+
+ if (testmgr_alloc_buf(xbuf))
+ goto out_nobuf;
if (enc == ENCRYPT)
e = "encryption";
@@ -611,6 +689,8 @@ static int test_cipher(struct crypto_cipher *tfm, int enc,
ret = 0;
out:
+ testmgr_free_buf(xbuf);
+out_nobuf:
return ret;
}
@@ -620,7 +700,6 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
const char *algo =
crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
unsigned int i, j, k, n, temp;
- int ret;
char *q;
struct ablkcipher_request *req;
struct scatterlist sg[8];
@@ -628,6 +707,11 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
struct tcrypt_result result;
void *data;
char iv[MAX_IVLEN];
+ char *xbuf[XBUFSIZE];
+ int ret = -ENOMEM;
+
+ if (testmgr_alloc_buf(xbuf))
+ goto out_nobuf;
if (enc == ENCRYPT)
e = "encryption";
@@ -640,7 +724,6 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
if (!req) {
printk(KERN_ERR "alg: skcipher: Failed to allocate request "
"for %s\n", algo);
- ret = -ENOMEM;
goto out;
}
@@ -825,6 +908,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
out:
ablkcipher_request_free(req);
+ testmgr_free_buf(xbuf);
+out_nobuf:
return ret;
}
@@ -837,7 +922,8 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
int ret;
for (i = 0; i < ctcount; i++) {
- int ilen, dlen = COMP_BUF_SIZE;
+ int ilen;
+ unsigned int dlen = COMP_BUF_SIZE;
memset(result, 0, sizeof (result));
@@ -869,7 +955,8 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
}
for (i = 0; i < dtcount; i++) {
- int ilen, dlen = COMP_BUF_SIZE;
+ int ilen;
+ unsigned int dlen = COMP_BUF_SIZE;
memset(result, 0, sizeof (result));
@@ -1059,6 +1146,68 @@ static int test_pcomp(struct crypto_pcomp *tfm,
return 0;
}
+
+static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template,
+ unsigned int tcount)
+{
+ const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
+ int err, i, j, seedsize;
+ u8 *seed;
+ char result[32];
+
+ seedsize = crypto_rng_seedsize(tfm);
+
+ seed = kmalloc(seedsize, GFP_KERNEL);
+ if (!seed) {
+ printk(KERN_ERR "alg: cprng: Failed to allocate seed space "
+ "for %s\n", algo);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < tcount; i++) {
+ memset(result, 0, 32);
+
+ memcpy(seed, template[i].v, template[i].vlen);
+ memcpy(seed + template[i].vlen, template[i].key,
+ template[i].klen);
+ memcpy(seed + template[i].vlen + template[i].klen,
+ template[i].dt, template[i].dtlen);
+
+ err = crypto_rng_reset(tfm, seed, seedsize);
+ if (err) {
+ printk(KERN_ERR "alg: cprng: Failed to reset rng "
+ "for %s\n", algo);
+ goto out;
+ }
+
+ for (j = 0; j < template[i].loops; j++) {
+ err = crypto_rng_get_bytes(tfm, result,
+ template[i].rlen);
+ if (err != template[i].rlen) {
+ printk(KERN_ERR "alg: cprng: Failed to obtain "
+ "the correct amount of random data for "
+ "%s (requested %d, got %d)\n", algo,
+ template[i].rlen, err);
+ goto out;
+ }
+ }
+
+ err = memcmp(result, template[i].result,
+ template[i].rlen);
+ if (err) {
+ printk(KERN_ERR "alg: cprng: Test %d failed for %s\n",
+ i, algo);
+ hexdump(result, template[i].rlen);
+ err = -EINVAL;
+ goto out;
+ }
+ }
+
+out:
+ kfree(seed);
+ return err;
+}
+
static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
u32 type, u32 mask)
{
@@ -1258,9 +1407,38 @@ out:
return err;
}
+static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
+ u32 type, u32 mask)
+{
+ struct crypto_rng *rng;
+ int err;
+
+ rng = crypto_alloc_rng(driver, type, mask);
+ if (IS_ERR(rng)) {
+ printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
+ "%ld\n", driver, PTR_ERR(rng));
+ return PTR_ERR(rng);
+ }
+
+ err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count);
+
+ crypto_free_rng(rng);
+
+ return err;
+}
+
/* Please keep this list sorted by algorithm name. */
static const struct alg_test_desc alg_test_descs[] = {
{
+ .alg = "ansi_cprng",
+ .test = alg_test_cprng,
+ .suite = {
+ .cprng = {
+ .vecs = ansi_cprng_aes_tv_template,
+ .count = ANSI_CPRNG_AES_TEST_VECTORS
+ }
+ }
+ }, {
.alg = "cbc(aes)",
.test = alg_test_skcipher,
.suite = {
@@ -1390,6 +1568,21 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "ctr(aes)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = aes_ctr_enc_tv_template,
+ .count = AES_CTR_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_ctr_dec_tv_template,
+ .count = AES_CTR_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
.alg = "cts(cbc(aes))",
.test = alg_test_skcipher,
.suite = {
@@ -1839,12 +2032,27 @@ static const struct alg_test_desc alg_test_descs[] = {
.suite = {
.cipher = {
.enc = {
- .vecs = aes_ctr_enc_tv_template,
- .count = AES_CTR_ENC_TEST_VECTORS
+ .vecs = aes_ctr_rfc3686_enc_tv_template,
+ .count = AES_CTR_3686_ENC_TEST_VECTORS
},
.dec = {
- .vecs = aes_ctr_dec_tv_template,
- .count = AES_CTR_DEC_TEST_VECTORS
+ .vecs = aes_ctr_rfc3686_dec_tv_template,
+ .count = AES_CTR_3686_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "rfc4309(ccm(aes))",
+ .test = alg_test_aead,
+ .suite = {
+ .aead = {
+ .enc = {
+ .vecs = aes_ccm_rfc4309_enc_tv_template,
+ .count = AES_CCM_4309_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_ccm_rfc4309_dec_tv_template,
+ .count = AES_CCM_4309_DEC_TEST_VECTORS
}
}
}
@@ -2077,7 +2285,8 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
if (i < 0)
goto notest;
- return alg_test_cipher(alg_test_descs + i, driver, type, mask);
+ rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
+ goto test_done;
}
i = alg_find_test(alg);
@@ -2086,9 +2295,14 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
rc = alg_test_descs[i].test(alg_test_descs + i, driver,
type, mask);
+test_done:
if (fips_enabled && rc)
panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
+ if (fips_enabled && !rc)
+ printk(KERN_INFO "alg: self-tests for %s (%s) passed\n",
+ driver, alg);
+
return rc;
notest:
@@ -2096,41 +2310,3 @@ notest:
return 0;
}
EXPORT_SYMBOL_GPL(alg_test);
-
-int __init testmgr_init(void)
-{
- int i;
-
- for (i = 0; i < XBUFSIZE; i++) {
- xbuf[i] = (void *)__get_free_page(GFP_KERNEL);
- if (!xbuf[i])
- goto err_free_xbuf;
- }
-
- for (i = 0; i < XBUFSIZE; i++) {
- axbuf[i] = (void *)__get_free_page(GFP_KERNEL);
- if (!axbuf[i])
- goto err_free_axbuf;
- }
-
- return 0;
-
-err_free_axbuf:
- for (i = 0; i < XBUFSIZE && axbuf[i]; i++)
- free_page((unsigned long)axbuf[i]);
-err_free_xbuf:
- for (i = 0; i < XBUFSIZE && xbuf[i]; i++)
- free_page((unsigned long)xbuf[i]);
-
- return -ENOMEM;
-}
-
-void testmgr_exit(void)
-{
- int i;
-
- for (i = 0; i < XBUFSIZE; i++)
- free_page((unsigned long)axbuf[i]);
- for (i = 0; i < XBUFSIZE; i++)
- free_page((unsigned long)xbuf[i]);
-}
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 526f00a9c72f..69316228fc19 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -62,6 +62,7 @@ struct aead_testvec {
int np;
int anp;
unsigned char fail;
+ unsigned char novrfy; /* ccm dec verification failure expected */
unsigned char wk; /* weak key flag */
unsigned char klen;
unsigned short ilen;
@@ -69,6 +70,18 @@ struct aead_testvec {
unsigned short rlen;
};
+struct cprng_testvec {
+ char *key;
+ char *dt;
+ char *v;
+ char *result;
+ unsigned char klen;
+ unsigned short dtlen;
+ unsigned short vlen;
+ unsigned short rlen;
+ unsigned short loops;
+};
+
static char zeroed_string[48];
/*
@@ -2841,12 +2854,16 @@ static struct cipher_testvec cast6_dec_tv_template[] = {
#define AES_LRW_DEC_TEST_VECTORS 8
#define AES_XTS_ENC_TEST_VECTORS 4
#define AES_XTS_DEC_TEST_VECTORS 4
-#define AES_CTR_ENC_TEST_VECTORS 7
-#define AES_CTR_DEC_TEST_VECTORS 6
+#define AES_CTR_ENC_TEST_VECTORS 3
+#define AES_CTR_DEC_TEST_VECTORS 3
+#define AES_CTR_3686_ENC_TEST_VECTORS 7
+#define AES_CTR_3686_DEC_TEST_VECTORS 6
#define AES_GCM_ENC_TEST_VECTORS 9
#define AES_GCM_DEC_TEST_VECTORS 8
#define AES_CCM_ENC_TEST_VECTORS 7
#define AES_CCM_DEC_TEST_VECTORS 7
+#define AES_CCM_4309_ENC_TEST_VECTORS 7
+#define AES_CCM_4309_DEC_TEST_VECTORS 10
static struct cipher_testvec aes_enc_tv_template[] = {
{ /* From FIPS-197 */
@@ -3983,6 +4000,164 @@ static struct cipher_testvec aes_xts_dec_tv_template[] = {
static struct cipher_testvec aes_ctr_enc_tv_template[] = {
+ { /* From NIST Special Publication 800-38A, Appendix F.5 */
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+ "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .klen = 16,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .ilen = 64,
+ .result = "\x87\x4d\x61\x91\xb6\x20\xe3\x26"
+ "\x1b\xef\x68\x64\x99\x0d\xb6\xce"
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff"
+ "\x86\x17\x18\x7b\xb9\xff\xfd\xff"
+ "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e"
+ "\x5b\x4f\x09\x02\x0d\xb0\x3e\xab"
+ "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1"
+ "\x79\x21\x70\xa0\xf3\x00\x9c\xee",
+ .rlen = 64,
+ }, {
+ .key = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+ "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ .klen = 24,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .ilen = 64,
+ .result = "\x1a\xbc\x93\x24\x17\x52\x1c\xa2"
+ "\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b"
+ "\x09\x03\x39\xec\x0a\xa6\xfa\xef"
+ "\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94"
+ "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70"
+ "\xd1\xbd\x1d\x66\x56\x20\xab\xf7"
+ "\x4f\x78\xa7\xf6\xd2\x98\x09\x58"
+ "\x5a\x97\xda\xec\x58\xc6\xb0\x50",
+ .rlen = 64,
+ }, {
+ .key = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+ "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+ "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ .klen = 32,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .ilen = 64,
+ .result = "\x60\x1e\xc3\x13\x77\x57\x89\xa5"
+ "\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28"
+ "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a"
+ "\xca\x84\xe9\x90\xca\xca\xf5\xc5"
+ "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c"
+ "\xe8\x70\x17\xba\x2d\x84\x98\x8d"
+ "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6"
+ "\x13\xc2\xdd\x08\x45\x79\x41\xa6",
+ .rlen = 64,
+ }
+};
+
+static struct cipher_testvec aes_ctr_dec_tv_template[] = {
+ { /* From NIST Special Publication 800-38A, Appendix F.5 */
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+ "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .klen = 16,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x87\x4d\x61\x91\xb6\x20\xe3\x26"
+ "\x1b\xef\x68\x64\x99\x0d\xb6\xce"
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff"
+ "\x86\x17\x18\x7b\xb9\xff\xfd\xff"
+ "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e"
+ "\x5b\x4f\x09\x02\x0d\xb0\x3e\xab"
+ "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1"
+ "\x79\x21\x70\xa0\xf3\x00\x9c\xee",
+ .ilen = 64,
+ .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .rlen = 64,
+ }, {
+ .key = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+ "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ .klen = 24,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x1a\xbc\x93\x24\x17\x52\x1c\xa2"
+ "\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b"
+ "\x09\x03\x39\xec\x0a\xa6\xfa\xef"
+ "\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94"
+ "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70"
+ "\xd1\xbd\x1d\x66\x56\x20\xab\xf7"
+ "\x4f\x78\xa7\xf6\xd2\x98\x09\x58"
+ "\x5a\x97\xda\xec\x58\xc6\xb0\x50",
+ .ilen = 64,
+ .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .rlen = 64,
+ }, {
+ .key = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+ "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+ "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ .klen = 32,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x60\x1e\xc3\x13\x77\x57\x89\xa5"
+ "\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28"
+ "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a"
+ "\xca\x84\xe9\x90\xca\xca\xf5\xc5"
+ "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c"
+ "\xe8\x70\x17\xba\x2d\x84\x98\x8d"
+ "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6"
+ "\x13\xc2\xdd\x08\x45\x79\x41\xa6",
+ .ilen = 64,
+ .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .rlen = 64,
+ }
+};
+
+static struct cipher_testvec aes_ctr_rfc3686_enc_tv_template[] = {
{ /* From RFC 3686 */
.key = "\xae\x68\x52\xf8\x12\x10\x67\xcc"
"\x4b\xf7\xa5\x76\x55\x77\xf3\x9e"
@@ -5114,7 +5289,7 @@ static struct cipher_testvec aes_ctr_enc_tv_template[] = {
},
};
-static struct cipher_testvec aes_ctr_dec_tv_template[] = {
+static struct cipher_testvec aes_ctr_rfc3686_dec_tv_template[] = {
{ /* From RFC 3686 */
.key = "\xae\x68\x52\xf8\x12\x10\x67\xcc"
"\x4b\xf7\xa5\x76\x55\x77\xf3\x9e"
@@ -5825,6 +6000,470 @@ static struct aead_testvec aes_ccm_dec_tv_template[] = {
},
};
+/*
+ * rfc4309 refers to section 8 of rfc3610 for test vectors, but they all
+ * use a 13-byte nonce, we only support an 11-byte nonce. Similarly, all of
+ * Special Publication 800-38C's test vectors also use nonce lengths our
+ * implementation doesn't support. The following are taken from fips cavs
+ * fax files on hand at Red Hat.
+ *
+ * nb: actual key lengths are (klen - 3), the last 3 bytes are actually
+ * part of the nonce which combine w/the iv, but need to be input this way.
+ */
+static struct aead_testvec aes_ccm_rfc4309_enc_tv_template[] = {
+ {
+ .key = "\x83\xac\x54\x66\xc2\xeb\xe5\x05"
+ "\x2e\x01\xd1\xfc\x5d\x82\x66\x2e"
+ "\x96\xac\x59",
+ .klen = 19,
+ .iv = "\x30\x07\xa1\xe2\xa2\xc7\x55\x24",
+ .alen = 0,
+ .input = "\x19\xc8\x81\xf6\xe9\x86\xff\x93"
+ "\x0b\x78\x67\xe5\xbb\xb7\xfc\x6e"
+ "\x83\x77\xb3\xa6\x0c\x8c\x9f\x9c"
+ "\x35\x2e\xad\xe0\x62\xf9\x91\xa1",
+ .ilen = 32,
+ .result = "\xab\x6f\xe1\x69\x1d\x19\x99\xa8"
+ "\x92\xa0\xc4\x6f\x7e\xe2\x8b\xb1"
+ "\x70\xbb\x8c\xa6\x4c\x6e\x97\x8a"
+ "\x57\x2b\xbe\x5d\x98\xa6\xb1\x32"
+ "\xda\x24\xea\xd9\xa1\x39\x98\xfd"
+ "\xa4\xbe\xd9\xf2\x1a\x6d\x22\xa8",
+ .rlen = 48,
+ }, {
+ .key = "\x1e\x2c\x7e\x01\x41\x9a\xef\xc0"
+ "\x0d\x58\x96\x6e\x5c\xa2\x4b\xd3"
+ "\x4f\xa3\x19",
+ .klen = 19,
+ .iv = "\xd3\x01\x5a\xd8\x30\x60\x15\x56",
+ .assoc = "\xda\xe6\x28\x9c\x45\x2d\xfd\x63"
+ "\x5e\xda\x4c\xb6\xe6\xfc\xf9\xb7"
+ "\x0c\x56\xcb\xe4\xe0\x05\x7a\xe1"
+ "\x0a\x63\x09\x78\xbc\x2c\x55\xde",
+ .alen = 32,
+ .input = "\x87\xa3\x36\xfd\x96\xb3\x93\x78"
+ "\xa9\x28\x63\xba\x12\xa3\x14\x85"
+ "\x57\x1e\x06\xc9\x7b\x21\xef\x76"
+ "\x7f\x38\x7e\x8e\x29\xa4\x3e\x7e",
+ .ilen = 32,
+ .result = "\x8a\x1e\x11\xf0\x02\x6b\xe2\x19"
+ "\xfc\x70\xc4\x6d\x8e\xb7\x99\xab"
+ "\xc5\x4b\xa2\xac\xd3\xf3\x48\xff"
+ "\x3b\xb5\xce\x53\xef\xde\xbb\x02"
+ "\xa9\x86\x15\x6c\x13\xfe\xda\x0a"
+ "\x22\xb8\x29\x3d\xd8\x39\x9a\x23",
+ .rlen = 48,
+ }, {
+ .key = "\xf4\x6b\xc2\x75\x62\xfe\xb4\xe1"
+ "\xa3\xf0\xff\xdd\x4e\x4b\x12\x75"
+ "\x53\x14\x73\x66\x8d\x88\xf6\x80"
+ "\xa0\x20\x35",
+ .klen = 27,
+ .iv = "\x26\xf2\x21\x8d\x50\x20\xda\xe2",
+ .assoc = "\x5b\x9e\x13\x67\x02\x5e\xef\xc1"
+ "\x6c\xf9\xd7\x1e\x52\x8f\x7a\x47"
+ "\xe9\xd4\xcf\x20\x14\x6e\xf0\x2d"
+ "\xd8\x9e\x2b\x56\x10\x23\x56\xe7",
+ .alen = 32,
+ .ilen = 0,
+ .result = "\x36\xea\x7a\x70\x08\xdc\x6a\xbc"
+ "\xad\x0c\x7a\x63\xf6\x61\xfd\x9b",
+ .rlen = 16,
+ }, {
+ .key = "\x56\xdf\x5c\x8f\x26\x3f\x0e\x42"
+ "\xef\x7a\xd3\xce\xfc\x84\x60\x62"
+ "\xca\xb4\x40\xaf\x5f\xc9\xc9\x01"
+ "\xd6\x3c\x8c",
+ .klen = 27,
+ .iv = "\x86\x84\xb6\xcd\xef\x09\x2e\x94",
+ .assoc = "\x02\x65\x78\x3c\xe9\x21\x30\x91"
+ "\xb1\xb9\xda\x76\x9a\x78\x6d\x95"
+ "\xf2\x88\x32\xa3\xf2\x50\xcb\x4c"
+ "\xe3\x00\x73\x69\x84\x69\x87\x79",
+ .alen = 32,
+ .input = "\x9f\xd2\x02\x4b\x52\x49\x31\x3c"
+ "\x43\x69\x3a\x2d\x8e\x70\xad\x7e"
+ "\xe0\xe5\x46\x09\x80\x89\x13\xb2"
+ "\x8c\x8b\xd9\x3f\x86\xfb\xb5\x6b",
+ .ilen = 32,
+ .result = "\x39\xdf\x7c\x3c\x5a\x29\xb9\x62"
+ "\x5d\x51\xc2\x16\xd8\xbd\x06\x9f"
+ "\x9b\x6a\x09\x70\xc1\x51\x83\xc2"
+ "\x66\x88\x1d\x4f\x9a\xda\xe0\x1e"
+ "\xc7\x79\x11\x58\xe5\x6b\x20\x40"
+ "\x7a\xea\x46\x42\x8b\xe4\x6f\xe1",
+ .rlen = 48,
+ }, {
+ .key = "\xe0\x8d\x99\x71\x60\xd7\x97\x1a"
+ "\xbd\x01\x99\xd5\x8a\xdf\x71\x3a"
+ "\xd3\xdf\x24\x4b\x5e\x3d\x4b\x4e"
+ "\x30\x7a\xb9\xd8\x53\x0a\x5e\x2b"
+ "\x1e\x29\x91",
+ .klen = 35,
+ .iv = "\xad\x8e\xc1\x53\x0a\xcf\x2d\xbe",
+ .assoc = "\x19\xb6\x1f\x57\xc4\xf3\xf0\x8b"
+ "\x78\x2b\x94\x02\x29\x0f\x42\x27"
+ "\x6b\x75\xcb\x98\x34\x08\x7e\x79"
+ "\xe4\x3e\x49\x0d\x84\x8b\x22\x87",
+ .alen = 32,
+ .input = "\xe1\xd9\xd8\x13\xeb\x3a\x75\x3f"
+ "\x9d\xbd\x5f\x66\xbe\xdc\xbb\x66"
+ "\xbf\x17\x99\x62\x4a\x39\x27\x1f"
+ "\x1d\xdc\x24\xae\x19\x2f\x98\x4c",
+ .ilen = 32,
+ .result = "\x19\xb8\x61\x33\x45\x2b\x43\x96"
+ "\x6f\x51\xd0\x20\x30\x7d\x9b\xc6"
+ "\x26\x3d\xf8\xc9\x65\x16\xa8\x9f"
+ "\xf0\x62\x17\x34\xf2\x1e\x8d\x75"
+ "\x4e\x13\xcc\xc0\xc3\x2a\x54\x2d",
+ .rlen = 40,
+ }, {
+ .key = "\x7c\xc8\x18\x3b\x8d\x99\xe0\x7c"
+ "\x45\x41\xb8\xbd\x5c\xa7\xc2\x32"
+ "\x8a\xb8\x02\x59\xa4\xfe\xa9\x2c"
+ "\x09\x75\x9a\x9b\x3c\x9b\x27\x39"
+ "\xf9\xd9\x4e",
+ .klen = 35,
+ .iv = "\x63\xb5\x3d\x9d\x43\xf6\x1e\x50",
+ .assoc = "\x57\xf5\x6b\x8b\x57\x5c\x3d\x3b"
+ "\x13\x02\x01\x0c\x83\x4c\x96\x35"
+ "\x8e\xd6\x39\xcf\x7d\x14\x9b\x94"
+ "\xb0\x39\x36\xe6\x8f\x57\xe0\x13",
+ .alen = 32,
+ .input = "\x3b\x6c\x29\x36\xb6\xef\x07\xa6"
+ "\x83\x72\x07\x4f\xcf\xfa\x66\x89"
+ "\x5f\xca\xb1\xba\xd5\x8f\x2c\x27"
+ "\x30\xdb\x75\x09\x93\xd4\x65\xe4",
+ .ilen = 32,
+ .result = "\xb0\x88\x5a\x33\xaa\xe5\xc7\x1d"
+ "\x85\x23\xc7\xc6\x2f\xf4\x1e\x3d"
+ "\xcc\x63\x44\x25\x07\x78\x4f\x9e"
+ "\x96\xb8\x88\xeb\xbc\x48\x1f\x06"
+ "\x39\xaf\x39\xac\xd8\x4a\x80\x39"
+ "\x7b\x72\x8a\xf7",
+ .rlen = 44,
+ }, {
+ .key = "\xab\xd0\xe9\x33\x07\x26\xe5\x83"
+ "\x8c\x76\x95\xd4\xb6\xdc\xf3\x46"
+ "\xf9\x8f\xad\xe3\x02\x13\x83\x77"
+ "\x3f\xb0\xf1\xa1\xa1\x22\x0f\x2b"
+ "\x24\xa7\x8b",
+ .klen = 35,
+ .iv = "\x07\xcb\xcc\x0e\xe6\x33\xbf\xf5",
+ .assoc = "\xd4\xdb\x30\x1d\x03\xfe\xfd\x5f"
+ "\x87\xd4\x8c\xb6\xb6\xf1\x7a\x5d"
+ "\xab\x90\x65\x8d\x8e\xca\x4d\x4f"
+ "\x16\x0c\x40\x90\x4b\xc7\x36\x73",
+ .alen = 32,
+ .input = "\xf5\xc6\x7d\x48\xc1\xb7\xe6\x92"
+ "\x97\x5a\xca\xc4\xa9\x6d\xf9\x3d"
+ "\x6c\xde\xbc\xf1\x90\xea\x6a\xb2"
+ "\x35\x86\x36\xaf\x5c\xfe\x4b\x3a",
+ .ilen = 32,
+ .result = "\x83\x6f\x40\x87\x72\xcf\xc1\x13"
+ "\xef\xbb\x80\x21\x04\x6c\x58\x09"
+ "\x07\x1b\xfc\xdf\xc0\x3f\x5b\xc7"
+ "\xe0\x79\xa8\x6e\x71\x7c\x3f\xcf"
+ "\x5c\xda\xb2\x33\xe5\x13\xe2\x0d"
+ "\x74\xd1\xef\xb5\x0f\x3a\xb5\xf8",
+ .rlen = 48,
+ },
+};
+
+static struct aead_testvec aes_ccm_rfc4309_dec_tv_template[] = {
+ {
+ .key = "\xab\x2f\x8a\x74\xb7\x1c\xd2\xb1"
+ "\xff\x80\x2e\x48\x7d\x82\xf8\xb9"
+ "\xc6\xfb\x7d",
+ .klen = 19,
+ .iv = "\x80\x0d\x13\xab\xd8\xa6\xb2\xd8",
+ .alen = 0,
+ .input = "\xd5\xe8\x93\x9f\xc7\x89\x2e\x2b",
+ .ilen = 8,
+ .result = "\x00",
+ .rlen = 0,
+ .novrfy = 1,
+ }, {
+ .key = "\xab\x2f\x8a\x74\xb7\x1c\xd2\xb1"
+ "\xff\x80\x2e\x48\x7d\x82\xf8\xb9"
+ "\xaf\x94\x87",
+ .klen = 19,
+ .iv = "\x78\x35\x82\x81\x7f\x88\x94\x68",
+ .alen = 0,
+ .input = "\x41\x3c\xb8\x87\x73\xcb\xf3\xf3",
+ .ilen = 8,
+ .result = "\x00",
+ .rlen = 0,
+ }, {
+ .key = "\x61\x0e\x8c\xae\xe3\x23\xb6\x38"
+ "\x76\x1c\xf6\x3a\x67\xa3\x9c\xd8"
+ "\xc6\xfb\x7d",
+ .klen = 19,
+ .iv = "\x80\x0d\x13\xab\xd8\xa6\xb2\xd8",
+ .assoc = "\xf3\x94\x87\x78\x35\x82\x81\x7f"
+ "\x88\x94\x68\xb1\x78\x6b\x2b\xd6"
+ "\x04\x1f\x4e\xed\x78\xd5\x33\x66"
+ "\xd8\x94\x99\x91\x81\x54\x62\x57",
+ .alen = 32,
+ .input = "\xf0\x7c\x29\x02\xae\x1c\x2f\x55"
+ "\xd0\xd1\x3d\x1a\xa3\x6d\xe4\x0a"
+ "\x86\xb0\x87\x6b\x62\x33\x8c\x34"
+ "\xce\xab\x57\xcc\x79\x0b\xe0\x6f"
+ "\x5c\x3e\x48\x1f\x6c\x46\xf7\x51"
+ "\x8b\x84\x83\x2a\xc1\x05\xb8\xc5",
+ .ilen = 48,
+ .result = "\x50\x82\x3e\x07\xe2\x1e\xb6\xfb"
+ "\x33\xe4\x73\xce\xd2\xfb\x95\x79"
+ "\xe8\xb4\xb5\x77\x11\x10\x62\x6f"
+ "\x6a\x82\xd1\x13\xec\xf5\xd0\x48",
+ .rlen = 32,
+ .novrfy = 1,
+ }, {
+ .key = "\x61\x0e\x8c\xae\xe3\x23\xb6\x38"
+ "\x76\x1c\xf6\x3a\x67\xa3\x9c\xd8"
+ "\x05\xe0\xc9",
+ .klen = 19,
+ .iv = "\x0f\xed\x34\xea\x97\xd4\x3b\xdf",
+ .assoc = "\x49\x5c\x50\x1f\x1d\x94\xcc\x81"
+ "\xba\xb7\xb6\x03\xaf\xa5\xc1\xa1"
+ "\xd8\x5c\x42\x68\xe0\x6c\xda\x89"
+ "\x05\xac\x56\xac\x1b\x2a\xd3\x86",
+ .alen = 32,
+ .input = "\x39\xbe\x7d\x15\x62\x77\xf3\x3c"
+ "\xad\x83\x52\x6d\x71\x03\x25\x1c"
+ "\xed\x81\x3a\x9a\x16\x7d\x19\x80"
+ "\x72\x04\x72\xd0\xf6\xff\x05\x0f"
+ "\xb7\x14\x30\x00\x32\x9e\xa0\xa6"
+ "\x9e\x5a\x18\xa1\xb8\xfe\xdb\xd3",
+ .ilen = 48,
+ .result = "\x75\x05\xbe\xc2\xd9\x1e\xde\x60"
+ "\x47\x3d\x8c\x7d\xbd\xb5\xd9\xb7"
+ "\xf2\xae\x61\x05\x8f\x82\x24\x3f"
+ "\x9c\x67\x91\xe1\x38\x4f\xe4\x0c",
+ .rlen = 32,
+ }, {
+ .key = "\x39\xbb\xa7\xbe\x59\x97\x9e\x73"
+ "\xa2\xbc\x6b\x98\xd7\x75\x7f\xe3"
+ "\xa4\x48\x93\x39\x26\x71\x4a\xc6"
+ "\xee\x49\x83",
+ .klen = 27,
+ .iv = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e",
+ .assoc = "\x44\xa6\x2c\x05\xe9\xe1\x43\xb1"
+ "\x58\x7c\xf2\x5c\x6d\x39\x0a\x64"
+ "\xa4\xf0\x13\x05\xd1\x77\x99\x67"
+ "\x11\xc4\xc6\xdb\x00\x56\x36\x61",
+ .alen = 32,
+ .input = "\x71\x99\xfa\xf4\x44\x12\x68\x9b",
+ .ilen = 8,
+ .result = "\x00",
+ .rlen = 0,
+ }, {
+ .key = "\x58\x5d\xa0\x96\x65\x1a\x04\xd7"
+ "\x96\xe5\xc5\x68\xaa\x95\x35\xe0"
+ "\x29\xa0\xba\x9e\x48\x78\xd1\xba"
+ "\xee\x49\x83",
+ .klen = 27,
+ .iv = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e",
+ .assoc = "\x44\xa6\x2c\x05\xe9\xe1\x43\xb1"
+ "\x58\x7c\xf2\x5c\x6d\x39\x0a\x64"
+ "\xa4\xf0\x13\x05\xd1\x77\x99\x67"
+ "\x11\xc4\xc6\xdb\x00\x56\x36\x61",
+ .alen = 32,
+ .input = "\xfb\xe5\x5d\x34\xbe\xe5\xe8\xe7"
+ "\x5a\xef\x2f\xbf\x1f\x7f\xd4\xb2"
+ "\x66\xca\x61\x1e\x96\x7a\x61\xb3"
+ "\x1c\x16\x45\x52\xba\x04\x9c\x9f"
+ "\xb1\xd2\x40\xbc\x52\x7c\x6f\xb1",
+ .ilen = 40,
+ .result = "\x85\x34\x66\x42\xc8\x92\x0f\x36"
+ "\x58\xe0\x6b\x91\x3c\x98\x5c\xbb"
+ "\x0a\x85\xcc\x02\xad\x7a\x96\xe9"
+ "\x65\x43\xa4\xc3\x0f\xdc\x55\x81",
+ .rlen = 32,
+ }, {
+ .key = "\x58\x5d\xa0\x96\x65\x1a\x04\xd7"
+ "\x96\xe5\xc5\x68\xaa\x95\x35\xe0"
+ "\x29\xa0\xba\x9e\x48\x78\xd1\xba"
+ "\xd1\xfc\x57",
+ .klen = 27,
+ .iv = "\x9c\xfe\xb8\x9c\xad\x71\xaa\x1f",
+ .assoc = "\x86\x67\xa5\xa9\x14\x5f\x0d\xc6"
+ "\xff\x14\xc7\x44\xbf\x6c\x3a\xc3"
+ "\xff\xb6\x81\xbd\xe2\xd5\x06\xc7"
+ "\x3c\xa1\x52\x13\x03\x8a\x23\x3a",
+ .alen = 32,
+ .input = "\x3f\x66\xb0\x9d\xe5\x4b\x38\x00"
+ "\xc6\x0e\x6e\xe5\xd6\x98\xa6\x37"
+ "\x8c\x26\x33\xc6\xb2\xa2\x17\xfa"
+ "\x64\x19\xc0\x30\xd7\xfc\x14\x6b"
+ "\xe3\x33\xc2\x04\xb0\x37\xbe\x3f"
+ "\xa9\xb4\x2d\x68\x03\xa3\x44\xef",
+ .ilen = 48,
+ .result = "\x02\x87\x4d\x28\x80\x6e\xb2\xed"
+ "\x99\x2a\xa8\xca\x04\x25\x45\x90"
+ "\x1d\xdd\x5a\xd9\xe4\xdb\x9c\x9c"
+ "\x49\xe9\x01\xfe\xa7\x80\x6d\x6b",
+ .rlen = 32,
+ .novrfy = 1,
+ }, {
+ .key = "\xa4\x4b\x54\x29\x0a\xb8\x6d\x01"
+ "\x5b\x80\x2a\xcf\x25\xc4\xb7\x5c"
+ "\x20\x2c\xad\x30\xc2\x2b\x41\xfb"
+ "\x0e\x85\xbc\x33\xad\x0f\x2b\xff"
+ "\xee\x49\x83",
+ .klen = 35,
+ .iv = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e",
+ .alen = 0,
+ .input = "\x1f\xb8\x8f\xa3\xdd\x54\x00\xf2",
+ .ilen = 8,
+ .result = "\x00",
+ .rlen = 0,
+ }, {
+ .key = "\x39\xbb\xa7\xbe\x59\x97\x9e\x73"
+ "\xa2\xbc\x6b\x98\xd7\x75\x7f\xe3"
+ "\xa4\x48\x93\x39\x26\x71\x4a\xc6"
+ "\xae\x8f\x11\x4c\xc2\x9c\x4a\xbb"
+ "\x85\x34\x66",
+ .klen = 35,
+ .iv = "\x42\xc8\x92\x0f\x36\x58\xe0\x6b",
+ .alen = 0,
+ .input = "\x48\x01\x5e\x02\x24\x04\x66\x47"
+ "\xa1\xea\x6f\xaf\xe8\xfc\xfb\xdd"
+ "\xa5\xa9\x87\x8d\x84\xee\x2e\x77"
+ "\xbb\x86\xb9\xf5\x5c\x6c\xff\xf6"
+ "\x72\xc3\x8e\xf7\x70\xb1\xb2\x07"
+ "\xbc\xa8\xa3\xbd\x83\x7c\x1d\x2a",
+ .ilen = 48,
+ .result = "\xdc\x56\xf2\x71\xb0\xb1\xa0\x6c"
+ "\xf0\x97\x3a\xfb\x6d\xe7\x32\x99"
+ "\x3e\xaf\x70\x5e\xb2\x4d\xea\x39"
+ "\x89\xd4\x75\x7a\x63\xb1\xda\x93",
+ .rlen = 32,
+ .novrfy = 1,
+ }, {
+ .key = "\x58\x5d\xa0\x96\x65\x1a\x04\xd7"
+ "\x96\xe5\xc5\x68\xaa\x95\x35\xe0"
+ "\x29\xa0\xba\x9e\x48\x78\xd1\xba"
+ "\x0d\x1a\x53\x3b\xb5\xe3\xf8\x8b"
+ "\xcf\x76\x3f",
+ .klen = 35,
+ .iv = "\xd9\x95\x75\x8f\x44\x89\x40\x7b",
+ .assoc = "\x8f\x86\x6c\x4d\x1d\xc5\x39\x88"
+ "\xc8\xf3\x5c\x52\x10\x63\x6f\x2b"
+ "\x8a\x2a\xc5\x6f\x30\x23\x58\x7b"
+ "\xfb\x36\x03\x11\xb4\xd9\xf2\xfe",
+ .alen = 32,
+ .input = "\x48\x58\xd6\xf3\xad\x63\x58\xbf"
+ "\xae\xc7\x5e\xae\x83\x8f\x7b\xe4"
+ "\x78\x5c\x4c\x67\x71\x89\x94\xbf"
+ "\x47\xf1\x63\x7e\x1c\x59\xbd\xc5"
+ "\x7f\x44\x0a\x0c\x01\x18\x07\x92"
+ "\xe1\xd3\x51\xce\x32\x6d\x0c\x5b",
+ .ilen = 48,
+ .result = "\xc2\x54\xc8\xde\x78\x87\x77\x40"
+ "\x49\x71\xe4\xb7\xe7\xcb\x76\x61"
+ "\x0a\x41\xb9\xe9\xc0\x76\x54\xab"
+ "\x04\x49\x3b\x19\x93\x57\x25\x5d",
+ .rlen = 32,
+ },
+};
+
+/*
+ * ANSI X9.31 Continuous Pseudo-Random Number Generator (AES mode)
+ * test vectors, taken from Appendix B.2.9 and B.2.10:
+ * http://csrc.nist.gov/groups/STM/cavp/documents/rng/RNGVS.pdf
+ * Only AES-128 is supported at this time.
+ */
+#define ANSI_CPRNG_AES_TEST_VECTORS 6
+
+static struct cprng_testvec ansi_cprng_aes_tv_template[] = {
+ {
+ .key = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+ "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+ .klen = 16,
+ .dt = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+ "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xf9",
+ .dtlen = 16,
+ .v = "\x80\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .vlen = 16,
+ .result = "\x59\x53\x1e\xd1\x3b\xb0\xc0\x55"
+ "\x84\x79\x66\x85\xc1\x2f\x76\x41",
+ .rlen = 16,
+ .loops = 1,
+ }, {
+ .key = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+ "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+ .klen = 16,
+ .dt = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+ "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfa",
+ .dtlen = 16,
+ .v = "\xc0\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .vlen = 16,
+ .result = "\x7c\x22\x2c\xf4\xca\x8f\xa2\x4c"
+ "\x1c\x9c\xb6\x41\xa9\xf3\x22\x0d",
+ .rlen = 16,
+ .loops = 1,
+ }, {
+ .key = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+ "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+ .klen = 16,
+ .dt = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+ "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfb",
+ .dtlen = 16,
+ .v = "\xe0\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .vlen = 16,
+ .result = "\x8a\xaa\x00\x39\x66\x67\x5b\xe5"
+ "\x29\x14\x28\x81\xa9\x4d\x4e\xc7",
+ .rlen = 16,
+ .loops = 1,
+ }, {
+ .key = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+ "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+ .klen = 16,
+ .dt = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+ "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfc",
+ .dtlen = 16,
+ .v = "\xf0\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .vlen = 16,
+ .result = "\x88\xdd\xa4\x56\x30\x24\x23\xe5"
+ "\xf6\x9d\xa5\x7e\x7b\x95\xc7\x3a",
+ .rlen = 16,
+ .loops = 1,
+ }, {
+ .key = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+ "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+ .klen = 16,
+ .dt = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+ "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfd",
+ .dtlen = 16,
+ .v = "\xf8\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .vlen = 16,
+ .result = "\x05\x25\x92\x46\x61\x79\xd2\xcb"
+ "\x78\xc4\x0b\x14\x0a\x5a\x9a\xc8",
+ .rlen = 16,
+ .loops = 1,
+ }, { /* Monte Carlo Test */
+ .key = "\x9f\x5b\x51\x20\x0b\xf3\x34\xb5"
+ "\xd8\x2b\xe8\xc3\x72\x55\xc8\x48",
+ .klen = 16,
+ .dt = "\x63\x76\xbb\xe5\x29\x02\xba\x3b"
+ "\x67\xc9\x25\xfa\x70\x1f\x11\xac",
+ .dtlen = 16,
+ .v = "\x57\x2c\x8e\x76\x87\x26\x47\x97"
+ "\x7e\x74\xfb\xdd\xc4\x95\x01\xd1",
+ .vlen = 16,
+ .result = "\x48\xe9\xbd\x0d\x06\xee\x18\xfb"
+ "\xe4\x57\x90\xd5\xc3\xfc\x9b\x73",
+ .rlen = 16,
+ .loops = 10000,
+ },
+};
+
/* Cast5 test vectors from RFC 2144 */
#define CAST5_ENC_TEST_VECTORS 3
#define CAST5_DEC_TEST_VECTORS 3
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index 17e50824a6f1..72ac28da14e3 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -5,40 +5,43 @@
ccflags-y := -Os
ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
-obj-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \
+# use acpi.o to put all files here into acpi.o modparam namespace
+obj-y += acpi.o
+
+acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \
dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \
dsinit.o
-obj-y += evevent.o evregion.o evsci.o evxfevnt.o \
+acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \
evmisc.o evrgnini.o evxface.o evxfregn.o \
evgpe.o evgpeblk.o
-obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
+acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\
excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \
exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o
-obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o
+acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o
-obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
+acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
-obj-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \
+acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \
nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \
nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \
nsparse.o nspredef.o
-obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
+acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
-obj-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \
+acpi-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \
psopcode.o psscope.o psutils.o psxface.o
-obj-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \
+acpi-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \
rscalc.o rsirq.o rsmemory.o rsutils.o
-obj-$(ACPI_FUTURE_USAGE) += rsdump.o
+acpi-$(ACPI_FUTURE_USAGE) += rsdump.o
-obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
+acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
-obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
+acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
utstate.o utmutex.o utobject.o utresrc.o utlock.o
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 16e5210ae936..3d87362d17ed 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -362,9 +362,6 @@ extern u8 acpi_gbl_method_executing;
extern u8 acpi_gbl_abort_method;
extern u8 acpi_gbl_db_terminate_threads;
-ACPI_EXTERN int optind;
-ACPI_EXTERN char *optarg;
-
ACPI_EXTERN u8 acpi_gbl_db_opt_tables;
ACPI_EXTERN u8 acpi_gbl_db_opt_stats;
ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods;
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
index dab3f48f0b42..02e6caad4a76 100644
--- a/drivers/acpi/acpica/dsobject.c
+++ b/drivers/acpi/acpica/dsobject.c
@@ -734,7 +734,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
/* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
- obj_desc->reference.value = opcode - AML_LOCAL_OP;
+ obj_desc->reference.value =
+ ((u32)opcode) - AML_LOCAL_OP;
obj_desc->reference.class = ACPI_REFCLASS_LOCAL;
#ifndef ACPI_NO_METHOD_EXECUTION
@@ -754,7 +755,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
/* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
- obj_desc->reference.value = opcode - AML_ARG_OP;
+ obj_desc->reference.value = ((u32)opcode) - AML_ARG_OP;
obj_desc->reference.class = ACPI_REFCLASS_ARG;
#ifndef ACPI_NO_METHOD_EXECUTION
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index b4c87b5053e6..584d766e6f12 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -1386,14 +1386,19 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
case AML_BREAK_POINT_OP:
- /* Call up to the OS service layer to handle this */
-
- status =
- acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
- "Executed AML Breakpoint opcode");
+ /*
+ * Set the single-step flag. This will cause the debugger (if present)
+ * to break to the console within the AML debugger at the start of the
+ * next AML instruction.
+ */
+ ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE);
+ ACPI_DEBUGGER_EXEC(acpi_os_printf
+ ("**break** Executed AML BreakPoint opcode\n"));
- /* If and when it returns, all done. */
+ /* Call to the OSL in case OS wants a piece of the action */
+ status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
+ "Executed AML Breakpoint opcode");
break;
case AML_BREAK_OP:
diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c
index 40f92bf7dce5..e46c821cf572 100644
--- a/drivers/acpi/acpica/dswstate.c
+++ b/drivers/acpi/acpica/dswstate.c
@@ -102,7 +102,7 @@ acpi_ds_result_pop(union acpi_operand_object **object,
/* Return object of the top element and clean that top element result stack */
walk_state->result_count--;
- index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
+ index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
*object = state->results.obj_desc[index];
if (!*object) {
@@ -186,7 +186,7 @@ acpi_ds_result_push(union acpi_operand_object * object,
/* Assign the address of object to the top free element of result stack */
- index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
+ index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
state->results.obj_desc[index] = object;
walk_state->result_count++;
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index d0a080747ec3..4721f58fe42c 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -51,7 +51,7 @@
ACPI_MODULE_NAME("evxfevnt")
/* Local prototypes */
-acpi_status
+static acpi_status
acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block, void *context);
@@ -785,7 +785,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
* block device. NULL if the GPE is one of the FADT-defined GPEs.
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block, void *context)
{
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c
index d301c1f363ef..d7cb030a21f8 100644
--- a/drivers/acpi/acpica/exmutex.c
+++ b/drivers/acpi/acpica/exmutex.c
@@ -373,11 +373,12 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
walk_state->thread->thread_id)
&& (obj_desc != acpi_gbl_global_lock_mutex)) {
ACPI_ERROR((AE_INFO,
- "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
- (unsigned long)walk_state->thread->thread_id,
+ "Thread %p cannot release Mutex [%4.4s] acquired by thread %p",
+ ACPI_CAST_PTR(void, walk_state->thread->thread_id),
acpi_ut_get_node_name(obj_desc->mutex.node),
- (unsigned long)obj_desc->mutex.owner_thread->
- thread_id));
+ ACPI_CAST_PTR(void,
+ obj_desc->mutex.owner_thread->
+ thread_id)));
return_ACPI_STATUS(AE_AML_NOT_OWNER);
}
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index 7b2fb602b5cb..23d5505cb1f7 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -81,9 +81,9 @@ acpi_status acpi_hw_clear_acpi_status(void)
ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
- ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
ACPI_BITMASK_ALL_FIXED_STATUS,
- acpi_gbl_xpm1a_status.address));
+ ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address)));
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c
index ae3dc10a7e81..af8e6bcee07e 100644
--- a/drivers/acpi/acpica/nsnames.c
+++ b/drivers/acpi/acpica/nsnames.c
@@ -149,7 +149,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
name_buffer = ACPI_ALLOCATE_ZEROED(size);
if (!name_buffer) {
- ACPI_ERROR((AE_INFO, "Allocation failure"));
+ ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size));
return_PTR(NULL);
}
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index d9e8cbc6e679..7f8e066b12a3 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -144,7 +144,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
pathname = acpi_ns_get_external_pathname(node);
if (!pathname) {
- pathname = ACPI_CAST_PTR(char, predefined->info.name);
+ return AE_OK; /* Could not get pathname, ignore */
}
/*
@@ -230,10 +230,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
}
exit:
- if (pathname != predefined->info.name) {
- ACPI_FREE(pathname);
- }
-
+ ACPI_FREE(pathname);
return (status);
}
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c
index f9b4f51bf8f2..7e865639a928 100644
--- a/drivers/acpi/acpica/nssearch.c
+++ b/drivers/acpi/acpica/nssearch.c
@@ -45,6 +45,10 @@
#include "accommon.h"
#include "acnamesp.h"
+#ifdef ACPI_ASL_COMPILER
+#include "amlcode.h"
+#endif
+
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nssearch")
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
index 88b5a2c4814d..d3f77a5df79d 100644
--- a/drivers/acpi/acpica/rscalc.c
+++ b/drivers/acpi/acpica/rscalc.c
@@ -593,9 +593,6 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
} else {
temp_size_needed +=
acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
- if (!temp_size_needed) {
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
}
} else {
/*
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c
index 69a2aa5b5d83..395212bcd19b 100644
--- a/drivers/acpi/acpica/rsxface.c
+++ b/drivers/acpi/acpica/rsxface.c
@@ -338,13 +338,17 @@ acpi_resource_to_address64(struct acpi_resource *resource,
switch (resource->type) {
case ACPI_RESOURCE_TYPE_ADDRESS16:
- address16 = (struct acpi_resource_address16 *)&resource->data;
+ address16 =
+ ACPI_CAST_PTR(struct acpi_resource_address16,
+ &resource->data);
ACPI_COPY_ADDRESS(out, address16);
break;
case ACPI_RESOURCE_TYPE_ADDRESS32:
- address32 = (struct acpi_resource_address32 *)&resource->data;
+ address32 =
+ ACPI_CAST_PTR(struct acpi_resource_address32,
+ &resource->data);
ACPI_COPY_ADDRESS(out, address32);
break;
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 71e655d14cb0..82b02dcb942e 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -284,9 +284,9 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
if (length > sizeof(struct acpi_table_fadt)) {
ACPI_WARNING((AE_INFO,
"FADT (revision %u) is longer than ACPI 2.0 version, "
- "truncating length 0x%X to 0x%zX",
- table->revision, (unsigned)length,
- sizeof(struct acpi_table_fadt)));
+ "truncating length 0x%X to 0x%X",
+ table->revision, length,
+ (u32)sizeof(struct acpi_table_fadt)));
}
/* Clear the entire local FADT */
@@ -441,7 +441,7 @@ static void acpi_tb_convert_fadt(void)
&acpi_gbl_FADT,
fadt_info_table
[i].length),
- address32);
+ (u64) address32);
}
}
}
@@ -469,7 +469,6 @@ static void acpi_tb_convert_fadt(void)
static void acpi_tb_validate_fadt(void)
{
char *name;
- u32 *address32;
struct acpi_generic_address *address64;
u8 length;
u32 i;
@@ -505,15 +504,12 @@ static void acpi_tb_validate_fadt(void)
for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
/*
- * Generate pointers to the 32-bit and 64-bit addresses, get the
- * register length (width), and the register name
+ * Generate pointer to the 64-bit address, get the register
+ * length (width) and the register name
*/
address64 = ACPI_ADD_PTR(struct acpi_generic_address,
&acpi_gbl_FADT,
fadt_info_table[i].address64);
- address32 =
- ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
- fadt_info_table[i].address32);
length =
*ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
fadt_info_table[i].length);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index f865d5a096de..63e82329a9e8 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -472,7 +472,7 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
* lock may block, and also since the execution of a namespace walk
* must be allowed to use the interpreter.
*/
- acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
+ (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
acpi_ns_delete_namespace_by_owner(owner_id);
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
index 919624f123d5..0f0c64bf8ac9 100644
--- a/drivers/acpi/acpica/utcopy.c
+++ b/drivers/acpi/acpica/utcopy.c
@@ -676,6 +676,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
{
u16 reference_count;
union acpi_operand_object *next_object;
+ acpi_status status;
/* Save fields from destination that we don't want to overwrite */
@@ -768,6 +769,28 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
}
break;
+ /*
+ * For Mutex and Event objects, we cannot simply copy the underlying
+ * OS object. We must create a new one.
+ */
+ case ACPI_TYPE_MUTEX:
+
+ status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+ break;
+
+ case ACPI_TYPE_EVENT:
+
+ status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
+ &dest_desc->event.
+ os_semaphore);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+ break;
+
default:
/* Nothing to do for other simple objects */
break;
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c
index 38821f53042c..527d729f6815 100644
--- a/drivers/acpi/acpica/utdebug.c
+++ b/drivers/acpi/acpica/utdebug.c
@@ -179,9 +179,9 @@ acpi_debug_print(u32 requested_debug_level,
if (thread_id != acpi_gbl_prev_thread_id) {
if (ACPI_LV_THREADS & acpi_dbg_level) {
acpi_os_printf
- ("\n**** Context Switch from TID %lX to TID %lX ****\n\n",
- (unsigned long)acpi_gbl_prev_thread_id,
- (unsigned long)thread_id);
+ ("\n**** Context Switch from TID %p to TID %p ****\n\n",
+ ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id),
+ ACPI_CAST_PTR(void, thread_id));
}
acpi_gbl_prev_thread_id = thread_id;
@@ -194,7 +194,7 @@ acpi_debug_print(u32 requested_debug_level,
acpi_os_printf("%8s-%04ld ", module_name, line_number);
if (ACPI_LV_THREADS & acpi_dbg_level) {
- acpi_os_printf("[%04lX] ", (unsigned long)thread_id);
+ acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id));
}
acpi_os_printf("[%02ld] %-22.22s: ",
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
index 1c9e250caefb..fbe782348b0b 100644
--- a/drivers/acpi/acpica/utmisc.c
+++ b/drivers/acpi/acpica/utmisc.c
@@ -1033,11 +1033,12 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...)
{
va_list args;
- acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
+ acpi_os_printf("ACPI Error: ");
va_start(args, format);
acpi_os_vprintf(format, args);
- acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
+ acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name,
+ line_number);
va_end(args);
}
@@ -1047,12 +1048,12 @@ acpi_exception(const char *module_name,
{
va_list args;
- acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name,
- line_number, acpi_format_exception(status));
+ acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status));
va_start(args, format);
acpi_os_vprintf(format, args);
- acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
+ acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name,
+ line_number);
va_end(args);
}
@@ -1061,11 +1062,12 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...)
{
va_list args;
- acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number);
+ acpi_os_printf("ACPI Warning: ");
va_start(args, format);
acpi_os_vprintf(format, args);
- acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
+ acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name,
+ line_number);
va_end(args);
}
@@ -1074,10 +1076,6 @@ acpi_info(const char *module_name, u32 line_number, const char *format, ...)
{
va_list args;
- /*
- * Removed module_name, line_number, and acpica version, not needed
- * for info output
- */
acpi_os_printf("ACPI: ");
va_start(args, format);
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 26c93a748e64..80bb65154117 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -230,17 +230,18 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
if (i == mutex_id) {
ACPI_ERROR((AE_INFO,
- "Mutex [%s] already acquired by this thread [%X]",
+ "Mutex [%s] already acquired by this thread [%p]",
acpi_ut_get_mutex_name
(mutex_id),
- this_thread_id));
+ ACPI_CAST_PTR(void,
+ this_thread_id)));
return (AE_ALREADY_ACQUIRED);
}
ACPI_ERROR((AE_INFO,
- "Invalid acquire order: Thread %X owns [%s], wants [%s]",
- this_thread_id,
+ "Invalid acquire order: Thread %p owns [%s], wants [%s]",
+ ACPI_CAST_PTR(void, this_thread_id),
acpi_ut_get_mutex_name(i),
acpi_ut_get_mutex_name(mutex_id)));
@@ -251,24 +252,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
#endif
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
- "Thread %lX attempting to acquire Mutex [%s]\n",
- (unsigned long)this_thread_id,
+ "Thread %p attempting to acquire Mutex [%s]\n",
+ ACPI_CAST_PTR(void, this_thread_id),
acpi_ut_get_mutex_name(mutex_id)));
status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
ACPI_WAIT_FOREVER);
if (ACPI_SUCCESS(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
- "Thread %lX acquired Mutex [%s]\n",
- (unsigned long)this_thread_id,
+ "Thread %p acquired Mutex [%s]\n",
+ ACPI_CAST_PTR(void, this_thread_id),
acpi_ut_get_mutex_name(mutex_id)));
acpi_gbl_mutex_info[mutex_id].use_count++;
acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
} else {
ACPI_EXCEPTION((AE_INFO, status,
- "Thread %lX could not acquire Mutex [%X]",
- (unsigned long)this_thread_id, mutex_id));
+ "Thread %p could not acquire Mutex [%X]",
+ ACPI_CAST_PTR(void, this_thread_id), mutex_id));
}
return (status);
@@ -293,9 +294,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
ACPI_FUNCTION_NAME(ut_release_mutex);
this_thread_id = acpi_os_get_thread_id();
- ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
- "Thread %lX releasing Mutex [%s]\n",
- (unsigned long)this_thread_id,
+ ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n",
+ ACPI_CAST_PTR(void, this_thread_id),
acpi_ut_get_mutex_name(mutex_id)));
if (mutex_id > ACPI_MAX_MUTEX) {
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index e8f7b64e92da..ae862f1798dc 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -312,7 +312,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
end:
if (result)
printk(KERN_WARNING PREFIX
- "Transitioning device [%s] to D%d\n",
+ "Device [%s] failed to transition to D%d\n",
device->pnp.bus_id, state);
else {
device->power.state = state;
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 51b9f8280f88..2faa9e2ac893 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -401,7 +401,8 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
/* Interrupt Line values above 0xF are forbidden */
if (dev->irq > 0 && (dev->irq <= 0xF)) {
printk(" - using IRQ %d\n", dev->irq);
- acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE,
+ acpi_register_gsi(&dev->dev, dev->irq,
+ ACPI_LEVEL_SENSITIVE,
ACPI_ACTIVE_LOW);
return 0;
} else {
@@ -410,7 +411,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
}
}
- rc = acpi_register_gsi(gsi, triggering, polarity);
+ rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
if (rc < 0) {
dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n",
pin_name(pin));
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index f7ca8c55956b..afa5c0341e5d 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -202,15 +202,41 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr,
* Suspend / resume control
*/
static int acpi_idle_suspend;
+static u32 saved_bm_rld;
+
+static void acpi_idle_bm_rld_save(void)
+{
+ acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);
+ printk(KERN_NOTICE PREFIX "saved: BM_RLD %u\n", saved_bm_rld);
+}
+static void acpi_idle_bm_rld_restore(void)
+{
+ u32 resumed_bm_rld;
+
+ acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld);
+ printk(KERN_NOTICE PREFIX "resumed: BM_RLD %u\n", resumed_bm_rld);
+ if (resumed_bm_rld != saved_bm_rld) {
+ printk(KERN_WARNING PREFIX "restored BM_RLD %u\n", saved_bm_rld);
+ acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld);
+ }
+}
int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
{
+ if (acpi_idle_suspend == 1)
+ return 0;
+
+ acpi_idle_bm_rld_save();
acpi_idle_suspend = 1;
return 0;
}
int acpi_processor_resume(struct acpi_device * device)
{
+ if (acpi_idle_suspend == 0)
+ return 0;
+
+ acpi_idle_bm_rld_restore();
acpi_idle_suspend = 0;
return 0;
}
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index d0d1f4d50434..9b37dda58895 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -827,32 +827,22 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
return 0;
}
-static int acpi_processor_get_throttling(struct acpi_processor *pr)
+static long get_throttling(void *_pr)
{
- cpumask_var_t saved_mask;
- int ret;
+ struct acpi_processor *pr = _pr;
+
+ return pr->throttling.acpi_processor_get_throttling(pr);
+}
+static int acpi_processor_get_throttling(struct acpi_processor *pr)
+{
if (!pr)
return -EINVAL;
if (!pr->flags.throttling)
return -ENODEV;
- if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL))
- return -ENOMEM;
-
- /*
- * Migrate task to the cpu pointed by pr.
- */
- cpumask_copy(saved_mask, &current->cpus_allowed);
- /* FIXME: use work_on_cpu() */
- set_cpus_allowed_ptr(current, cpumask_of(pr->id));
- ret = pr->throttling.acpi_processor_get_throttling(pr);
- /* restore the previous state */
- set_cpus_allowed_ptr(current, saved_mask);
- free_cpumask_var(saved_mask);
-
- return ret;
+ return work_on_cpu(pr->id, get_throttling, pr);
}
static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
@@ -993,9 +983,22 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
return 0;
}
+struct set_throttling_info {
+ struct acpi_processor *pr;
+ struct acpi_processor_throttling *p_throttling;
+ int target_state;
+};
+
+static long set_throttling(void *_sti)
+{
+ struct set_throttling_info *s = _sti;
+
+ return s->p_throttling->acpi_processor_set_throttling(s->pr,
+ s->target_state);
+}
+
int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
{
- cpumask_var_t saved_mask;
int ret = 0;
unsigned int i;
struct acpi_processor *match_pr;
@@ -1012,15 +1015,9 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
if ((state < 0) || (state > (pr->throttling.state_count - 1)))
return -EINVAL;
- if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL))
- return -ENOMEM;
-
- if (!alloc_cpumask_var(&online_throttling_cpus, GFP_KERNEL)) {
- free_cpumask_var(saved_mask);
+ if (!alloc_cpumask_var(&online_throttling_cpus, GFP_KERNEL))
return -ENOMEM;
- }
- cpumask_copy(saved_mask, &current->cpus_allowed);
t_state.target_state = state;
p_throttling = &(pr->throttling);
cpumask_and(online_throttling_cpus, cpu_online_mask,
@@ -1042,10 +1039,9 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
* it can be called only for the cpu pointed by pr.
*/
if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
- /* FIXME: use work_on_cpu() */
- set_cpus_allowed_ptr(current, cpumask_of(pr->id));
- ret = p_throttling->acpi_processor_set_throttling(pr,
- t_state.target_state);
+ struct set_throttling_info sti
+ = { pr, p_throttling, t_state.target_state };
+ ret = work_on_cpu(pr->id, set_throttling, &sti);
} else {
/*
* When the T-state coordination is SW_ALL or HW_ALL,
@@ -1053,6 +1049,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
* cpus.
*/
for_each_cpu(i, online_throttling_cpus) {
+ struct set_throttling_info sti;
+
match_pr = per_cpu(processors, i);
/*
* If the pointer is invalid, we will report the
@@ -1074,11 +1072,10 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
continue;
}
t_state.cpu = i;
- /* FIXME: use work_on_cpu() */
- set_cpus_allowed_ptr(current, cpumask_of(i));
- ret = match_pr->throttling.
- acpi_processor_set_throttling(
- match_pr, t_state.target_state);
+ sti.pr = match_pr;
+ sti.p_throttling = &match_pr->throttling;
+ sti.target_state = t_state.target_state;
+ ret = work_on_cpu(i, set_throttling, &sti);
}
}
/*
@@ -1092,11 +1089,6 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE,
&t_state);
}
- /* restore the previous state */
- /* FIXME: use work_on_cpu() */
- set_cpus_allowed_ptr(current, saved_mask);
- free_cpumask_var(online_throttling_cpus);
- free_cpumask_var(saved_mask);
return ret;
}
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index d7ff61c0d571..810cca90ca7f 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -538,6 +538,41 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
return -EINVAL;
}
+/*
+ * For some buggy _BQC methods, we need to add a constant value to
+ * the _BQC return value to get the actual current brightness level
+ */
+
+static int bqc_offset_aml_bug_workaround;
+static int __init video_set_bqc_offset(const struct dmi_system_id *d)
+{
+ bqc_offset_aml_bug_workaround = 9;
+ return 0;
+}
+
+static struct dmi_system_id video_dmi_table[] __initdata = {
+ /*
+ * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121
+ */
+ {
+ .callback = video_set_bqc_offset,
+ .ident = "Acer Aspire 5720",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
+ },
+ },
+ {
+ .callback = video_set_bqc_offset,
+ .ident = "Acer Aspire 5710Z",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"),
+ },
+ },
+ {}
+};
+
static int
acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
unsigned long long *level)
@@ -557,6 +592,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
*level = device->brightness->levels[*level + 2];
}
+ *level += bqc_offset_aml_bug_workaround;
device->brightness->curr = *level;
return 0;
} else {
@@ -2290,6 +2326,8 @@ EXPORT_SYMBOL(acpi_video_register);
static int __init acpi_video_init(void)
{
+ dmi_check_system(video_dmi_table);
+
if (intel_opregion_present())
return 0;
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 08186ecbaf8d..3489085b448b 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -312,7 +312,6 @@ static void ahci_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
static int ahci_port_resume(struct ata_port *ap);
static void ahci_dev_config(struct ata_device *dev);
-static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl);
static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
u32 opts);
#ifdef CONFIG_PM
@@ -403,14 +402,14 @@ static struct ata_port_operations ahci_sb600_ops = {
#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
static const struct ata_port_info ahci_port_info[] = {
- /* board_ahci */
+ [board_ahci] =
{
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- /* board_ahci_vt8251 */
+ [board_ahci_vt8251] =
{
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
@@ -418,7 +417,7 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_vt8251_ops,
},
- /* board_ahci_ign_iferr */
+ [board_ahci_ign_iferr] =
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR),
.flags = AHCI_FLAG_COMMON,
@@ -426,7 +425,7 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- /* board_ahci_sb600 */
+ [board_ahci_sb600] =
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
@@ -436,7 +435,7 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_sb600_ops,
},
- /* board_ahci_mv */
+ [board_ahci_mv] =
{
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI |
AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
@@ -446,7 +445,7 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- /* board_ahci_sb700, for SB700 and SB800 */
+ [board_ahci_sb700] = /* for SB700 and SB800 */
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL),
.flags = AHCI_FLAG_COMMON,
@@ -454,7 +453,7 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_sb600_ops,
},
- /* board_ahci_mcp65 */
+ [board_ahci_mcp65] =
{
AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ),
.flags = AHCI_FLAG_COMMON,
@@ -462,7 +461,7 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- /* board_ahci_nopmp */
+ [board_ahci_nopmp] =
{
AHCI_HFLAGS (AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 942d14ac8792..d51a17c0f59b 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -72,6 +72,7 @@
* ICH2 spec c #20 - IDE PRD must not cross a 64K boundary
* and must be dword aligned
* ICH2 spec c #24 - UDMA mode 4,5 t85/86 should be 6ns not 3.3
+ * ICH7 errata #16 - MWDMA1 timings are incorrect
*
* Should have been BIOS fixed:
* 450NX: errata #19 - DMA hangs on old 450NX
@@ -94,7 +95,7 @@
#include <linux/dmi.h>
#define DRV_NAME "ata_piix"
-#define DRV_VERSION "2.12"
+#define DRV_VERSION "2.13"
enum {
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
@@ -136,6 +137,7 @@ enum piix_controller_ids {
ich_pata_33, /* ICH up to UDMA 33 only */
ich_pata_66, /* ICH up to 66 Mhz */
ich_pata_100, /* ICH up to UDMA 100 */
+ ich_pata_100_nomwdma1, /* ICH up to UDMA 100 but with no MWDMA1*/
ich5_sata,
ich6_sata,
ich6m_sata,
@@ -216,8 +218,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* ICH6 (and 6) (i915) UDMA 100 */
{ 0x8086, 0x266F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
/* ICH7/7-R (i945, i975) UDMA 100*/
- { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
- { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
+ { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100_nomwdma1 },
+ { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100_nomwdma1 },
/* ICH8 Mobile PATA Controller */
{ 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
@@ -487,6 +489,15 @@ static struct ata_port_info piix_port_info[] = {
.port_ops = &ich_pata_ops,
},
+ [ich_pata_100_nomwdma1] =
+ {
+ .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2_ONLY,
+ .udma_mask = ATA_UDMA5,
+ .port_ops = &ich_pata_ops,
+ },
+
[ich5_sata] =
{
.flags = PIIX_SATA_FLAGS,
@@ -594,6 +605,7 @@ static const struct ich_laptop ich_laptop[] = {
{ 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */
{ 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
{ 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
+ { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */
/* end marker */
{ 0, }
};
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 17c5d48a75d2..c9242301cfa1 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4091,7 +4091,9 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
/* fail early if !ATA && !ATAPI to avoid issuing [P]IDENTIFY to PMP */
if (ata_class_enabled(new_class) &&
- new_class != ATA_DEV_ATA && new_class != ATA_DEV_ATAPI) {
+ new_class != ATA_DEV_ATA &&
+ new_class != ATA_DEV_ATAPI &&
+ new_class != ATA_DEV_SEMB) {
ata_dev_printk(dev, KERN_INFO, "class mismatch %u != %u\n",
dev->class, new_class);
rc = -ENODEV;
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index e5550f573a6b..fa22f94ca415 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2783,6 +2783,12 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
} else if (dev->class == ATA_DEV_UNKNOWN &&
ehc->tries[dev->devno] &&
ata_class_enabled(ehc->classes[dev->devno])) {
+ /* Temporarily set dev->class, it will be
+ * permanently set once all configurations are
+ * complete. This is necessary because new
+ * device configuration is done in two
+ * separate loops.
+ */
dev->class = ehc->classes[dev->devno];
if (dev->class == ATA_DEV_PMP)
@@ -2790,6 +2796,11 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
else
rc = ata_dev_read_id(dev, &dev->class,
readid_flags, dev->id);
+
+ /* read_id might have changed class, store and reset */
+ ehc->classes[dev->devno] = dev->class;
+ dev->class = ATA_DEV_UNKNOWN;
+
switch (rc) {
case 0:
/* clear error info accumulated during probe */
@@ -2799,13 +2810,11 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
case -ENOENT:
/* IDENTIFY was issued to non-existent
* device. No need to reset. Just
- * thaw and kill the device.
+ * thaw and ignore the device.
*/
ata_eh_thaw_port(ap);
- dev->class = ATA_DEV_UNKNOWN;
break;
default:
- dev->class = ATA_DEV_UNKNOWN;
goto err;
}
}
@@ -2826,11 +2835,15 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
dev->class == ATA_DEV_PMP)
continue;
+ dev->class = ehc->classes[dev->devno];
+
ehc->i.flags |= ATA_EHI_PRINTINFO;
rc = ata_dev_configure(dev);
ehc->i.flags &= ~ATA_EHI_PRINTINFO;
- if (rc)
+ if (rc) {
+ dev->class = ATA_DEV_UNKNOWN;
goto err;
+ }
spin_lock_irqsave(ap->lock, flags);
ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
@@ -3494,6 +3507,8 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
*/
static void ata_eh_handle_port_resume(struct ata_port *ap)
{
+ struct ata_link *link;
+ struct ata_device *dev;
unsigned long flags;
int rc = 0;
@@ -3508,6 +3523,17 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED));
+ /*
+ * Error timestamps are in jiffies which doesn't run while
+ * suspended and PHY events during resume isn't too uncommon.
+ * When the two are combined, it can lead to unnecessary speed
+ * downs if the machine is suspended and resumed repeatedly.
+ * Clear error history.
+ */
+ ata_for_each_link(link, ap, HOST_FIRST)
+ ata_for_each_dev(dev, link, ALL)
+ ata_ering_clear(&dev->ering);
+
ata_acpi_set_state(ap, PMSG_ON);
if (ap->ops->port_resume)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 2733b0c90b75..1c154d230719 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -313,7 +313,7 @@ ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr,
return ap->ops->em_show(ap, buf);
return -EINVAL;
}
-DEVICE_ATTR(em_message, S_IRUGO | S_IWUGO,
+DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR,
ata_scsi_em_message_show, ata_scsi_em_message_store);
EXPORT_SYMBOL_GPL(dev_attr_em_message);
@@ -366,7 +366,7 @@ ata_scsi_activity_store(struct device *dev, struct device_attribute *attr,
}
return -EINVAL;
}
-DEVICE_ATTR(sw_activity, S_IWUGO | S_IRUGO, ata_scsi_activity_show,
+DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show,
ata_scsi_activity_store);
EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
@@ -1084,7 +1084,7 @@ static int atapi_drain_needed(struct request *rq)
if (likely(!blk_pc_request(rq)))
return 0;
- if (!rq->data_len || (rq->cmd_flags & REQ_RW))
+ if (!blk_rq_bytes(rq) || (rq->cmd_flags & REQ_RW))
return 0;
return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC;
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index bb18415d3d63..bbbb1fab1755 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -727,17 +727,23 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf,
else
iowrite16_rep(data_addr, buf, words);
- /* Transfer trailing 1 byte, if any. */
+ /* Transfer trailing byte, if any. */
if (unlikely(buflen & 0x01)) {
- __le16 align_buf[1] = { 0 };
- unsigned char *trailing_buf = buf + buflen - 1;
+ unsigned char pad[2];
+ /* Point buf to the tail of buffer */
+ buf += buflen - 1;
+
+ /*
+ * Use io*16_rep() accessors here as well to avoid pointlessly
+ * swapping bytes to and fro on the big endian machines...
+ */
if (rw == READ) {
- align_buf[0] = cpu_to_le16(ioread16(data_addr));
- memcpy(trailing_buf, align_buf, 1);
+ ioread16_rep(data_addr, pad, 1);
+ *buf = pad[0];
} else {
- memcpy(align_buf, trailing_buf, 1);
- iowrite16(le16_to_cpu(align_buf[0]), data_addr);
+ pad[0] = *buf;
+ iowrite16_rep(data_addr, pad, 1);
}
words++;
}
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index 5fedb3d4032b..2f3c9bed63d9 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -2,7 +2,7 @@
* pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <alan@lxorguk.ukuu.org.uk>
- * (C) 2007 Bartlomiej Zolnierkiewicz
+ * (C) 2007,2009 Bartlomiej Zolnierkiewicz
*
* Based in part on linux/drivers/ide/pci/pdc202xx_old.c
*
@@ -158,7 +158,7 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
u32 len;
/* Check we keep host level locking here */
- if (adev->dma_mode >= XFER_UDMA_2)
+ if (adev->dma_mode > XFER_UDMA_2)
iowrite8(ioread8(clock) | sel66, clock);
else
iowrite8(ioread8(clock) & ~sel66, clock);
@@ -212,7 +212,7 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
iowrite8(ioread8(clock) & ~sel66, clock);
}
/* Flip back to 33Mhz for PIO */
- if (adev->dma_mode >= XFER_UDMA_2)
+ if (adev->dma_mode > XFER_UDMA_2)
iowrite8(ioread8(clock) & ~sel66, clock);
ata_bmdma_stop(qc);
pdc202xx_set_piomode(ap, adev);
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 870dcfd82357..23714aefb825 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -293,6 +293,10 @@ enum {
FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */
FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
+ PHY_MODE9_GEN2 = 0x398,
+ PHY_MODE9_GEN1 = 0x39c,
+ PHYCFG_OFS = 0x3a0, /* only in 65n devices */
+
MV5_PHY_MODE = 0x74,
MV5_LTMODE = 0x30,
MV5_PHY_CTL = 0x0C,
@@ -609,6 +613,8 @@ static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
void __iomem *mmio);
static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+ void __iomem *mmio, unsigned int port);
static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
@@ -807,6 +813,14 @@ static const struct mv_hw_ops mv_soc_ops = {
.reset_bus = mv_soc_reset_bus,
};
+static const struct mv_hw_ops mv_soc_65n_ops = {
+ .phy_errata = mv_soc_65n_phy_errata,
+ .enable_leds = mv_soc_enable_leds,
+ .reset_hc = mv_soc_reset_hc,
+ .reset_flash = mv_soc_reset_flash,
+ .reset_bus = mv_soc_reset_bus,
+};
+
/*
* Functions
*/
@@ -3397,6 +3411,53 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
return;
}
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+ void __iomem *mmio, unsigned int port)
+{
+ void __iomem *port_mmio = mv_port_base(mmio, port);
+ u32 reg;
+
+ reg = readl(port_mmio + PHY_MODE3);
+ reg &= ~(0x3 << 27); /* SELMUPF (bits 28:27) to 1 */
+ reg |= (0x1 << 27);
+ reg &= ~(0x3 << 29); /* SELMUPI (bits 30:29) to 1 */
+ reg |= (0x1 << 29);
+ writel(reg, port_mmio + PHY_MODE3);
+
+ reg = readl(port_mmio + PHY_MODE4);
+ reg &= ~0x1; /* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */
+ reg |= (0x1 << 16);
+ writel(reg, port_mmio + PHY_MODE4);
+
+ reg = readl(port_mmio + PHY_MODE9_GEN2);
+ reg &= ~0xf; /* TXAMP[3:0] (bits 3:0) to 8 */
+ reg |= 0x8;
+ reg &= ~(0x1 << 14); /* TXAMP[4] (bit 14) to 0 */
+ writel(reg, port_mmio + PHY_MODE9_GEN2);
+
+ reg = readl(port_mmio + PHY_MODE9_GEN1);
+ reg &= ~0xf; /* TXAMP[3:0] (bits 3:0) to 8 */
+ reg |= 0x8;
+ reg &= ~(0x1 << 14); /* TXAMP[4] (bit 14) to 0 */
+ writel(reg, port_mmio + PHY_MODE9_GEN1);
+}
+
+/**
+ * soc_is_65 - check if the soc is 65 nano device
+ *
+ * Detect the type of the SoC, this is done by reading the PHYCFG_OFS
+ * register, this register should contain non-zero value and it exists only
+ * in the 65 nano devices, when reading it from older devices we get 0.
+ */
+static bool soc_is_65n(struct mv_host_priv *hpriv)
+{
+ void __iomem *port0_mmio = mv_port_base(hpriv->base, 0);
+
+ if (readl(port0_mmio + PHYCFG_OFS))
+ return true;
+ return false;
+}
+
static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
{
u32 ifcfg = readl(port_mmio + SATA_IFCFG);
@@ -3737,7 +3798,10 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
}
break;
case chip_soc:
- hpriv->ops = &mv_soc_ops;
+ if (soc_is_65n(hpriv))
+ hpriv->ops = &mv_soc_65n_ops;
+ else
+ hpriv->ops = &mv_soc_ops;
hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
MV_HP_ERRATA_60X1C0;
break;
@@ -3800,7 +3864,8 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
n_hc = mv_get_hc_count(host->ports[0]->flags);
for (port = 0; port < host->n_ports; port++)
- hpriv->ops->read_preamp(hpriv, port, mmio);
+ if (hpriv->ops->read_preamp)
+ hpriv->ops->read_preamp(hpriv, port, mmio);
rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
if (rc)
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index e67ce8e5caa5..030ec079b184 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -183,7 +183,7 @@ static struct scsi_host_template sil_sht = {
};
static struct ata_port_operations sil_ops = {
- .inherits = &ata_bmdma_port_ops,
+ .inherits = &ata_bmdma32_port_ops,
.dev_config = sil_dev_config,
.set_mode = sil_set_mode,
.bmdma_setup = sil_bmdma_setup,
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index dce3dccced3f..ac723f5181ee 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -193,6 +193,7 @@ enum {
PDC_TIMER_MASK_INT,
};
+#define ECC_ERASE_BUF_SZ (128 * 1024)
struct pdc_port_priv {
u8 dimm_buf[(ATA_PRD_SZ * ATA_MAX_PRD) + 512];
@@ -1208,7 +1209,6 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host)
{
int speed, size, length;
u32 addr, spd0, pci_status;
- u32 tmp = 0;
u32 time_period = 0;
u32 tcount = 0;
u32 ticks = 0;
@@ -1323,14 +1323,17 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host)
pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
PDC_DIMM_SPD_TYPE, &spd0);
if (spd0 == 0x02) {
+ void *buf;
VPRINTK("Start ECC initialization\n");
addr = 0;
length = size * 1024 * 1024;
+ buf = kzalloc(ECC_ERASE_BUF_SZ, GFP_KERNEL);
while (addr < length) {
- pdc20621_put_to_dimm(host, (void *) &tmp, addr,
- sizeof(u32));
- addr += sizeof(u32);
+ pdc20621_put_to_dimm(host, buf, addr,
+ ECC_ERASE_BUF_SZ);
+ addr += ECC_ERASE_BUF_SZ;
}
+ kfree(buf);
VPRINTK("Finish ECC initialization\n");
}
return 0;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index d3a59c688fe4..f19afa8b4583 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -17,7 +17,7 @@
#include <linux/bitops.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
-
+#include <linux/highmem.h>
#include <linux/firmware.h>
#include "base.h"
@@ -45,7 +45,10 @@ struct firmware_priv {
struct bin_attribute attr_data;
struct firmware *fw;
unsigned long status;
- int alloc_size;
+ struct page **pages;
+ int nr_pages;
+ int page_array_size;
+ const char *vdata;
struct timer_list timeout;
};
@@ -122,6 +125,10 @@ static ssize_t firmware_loading_show(struct device *dev,
return sprintf(buf, "%d\n", loading);
}
+/* Some architectures don't have PAGE_KERNEL_RO */
+#ifndef PAGE_KERNEL_RO
+#define PAGE_KERNEL_RO PAGE_KERNEL
+#endif
/**
* firmware_loading_store - set value in the 'loading' control file
* @dev: device pointer
@@ -141,6 +148,7 @@ static ssize_t firmware_loading_store(struct device *dev,
{
struct firmware_priv *fw_priv = dev_get_drvdata(dev);
int loading = simple_strtol(buf, NULL, 10);
+ int i;
switch (loading) {
case 1:
@@ -151,13 +159,30 @@ static ssize_t firmware_loading_store(struct device *dev,
}
vfree(fw_priv->fw->data);
fw_priv->fw->data = NULL;
+ for (i = 0; i < fw_priv->nr_pages; i++)
+ __free_page(fw_priv->pages[i]);
+ kfree(fw_priv->pages);
+ fw_priv->pages = NULL;
+ fw_priv->page_array_size = 0;
+ fw_priv->nr_pages = 0;
fw_priv->fw->size = 0;
- fw_priv->alloc_size = 0;
set_bit(FW_STATUS_LOADING, &fw_priv->status);
mutex_unlock(&fw_lock);
break;
case 0:
if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
+ vfree(fw_priv->fw->data);
+ fw_priv->fw->data = vmap(fw_priv->pages,
+ fw_priv->nr_pages,
+ 0, PAGE_KERNEL_RO);
+ if (!fw_priv->fw->data) {
+ dev_err(dev, "%s: vmap() failed\n", __func__);
+ goto err;
+ }
+ /* Pages will be freed by vfree() */
+ fw_priv->pages = NULL;
+ fw_priv->page_array_size = 0;
+ fw_priv->nr_pages = 0;
complete(&fw_priv->completion);
clear_bit(FW_STATUS_LOADING, &fw_priv->status);
break;
@@ -167,6 +192,7 @@ static ssize_t firmware_loading_store(struct device *dev,
dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading);
/* fallthrough */
case -1:
+ err:
fw_load_abort(fw_priv);
break;
}
@@ -191,8 +217,28 @@ firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr,
ret_count = -ENODEV;
goto out;
}
- ret_count = memory_read_from_buffer(buffer, count, &offset,
- fw->data, fw->size);
+ if (offset > fw->size)
+ return 0;
+ if (count > fw->size - offset)
+ count = fw->size - offset;
+
+ ret_count = count;
+
+ while (count) {
+ void *page_data;
+ int page_nr = offset >> PAGE_SHIFT;
+ int page_ofs = offset & (PAGE_SIZE-1);
+ int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count);
+
+ page_data = kmap(fw_priv->pages[page_nr]);
+
+ memcpy(buffer, page_data + page_ofs, page_cnt);
+
+ kunmap(page_data);
+ buffer += page_cnt;
+ offset += page_cnt;
+ count -= page_cnt;
+ }
out:
mutex_unlock(&fw_lock);
return ret_count;
@@ -201,27 +247,39 @@ out:
static int
fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
{
- u8 *new_data;
- int new_size = fw_priv->alloc_size;
+ int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT;
+
+ /* If the array of pages is too small, grow it... */
+ if (fw_priv->page_array_size < pages_needed) {
+ int new_array_size = max(pages_needed,
+ fw_priv->page_array_size * 2);
+ struct page **new_pages;
+
+ new_pages = kmalloc(new_array_size * sizeof(void *),
+ GFP_KERNEL);
+ if (!new_pages) {
+ fw_load_abort(fw_priv);
+ return -ENOMEM;
+ }
+ memcpy(new_pages, fw_priv->pages,
+ fw_priv->page_array_size * sizeof(void *));
+ memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) *
+ (new_array_size - fw_priv->page_array_size));
+ kfree(fw_priv->pages);
+ fw_priv->pages = new_pages;
+ fw_priv->page_array_size = new_array_size;
+ }
- if (min_size <= fw_priv->alloc_size)
- return 0;
+ while (fw_priv->nr_pages < pages_needed) {
+ fw_priv->pages[fw_priv->nr_pages] =
+ alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
- new_size = ALIGN(min_size, PAGE_SIZE);
- new_data = vmalloc(new_size);
- if (!new_data) {
- printk(KERN_ERR "%s: unable to alloc buffer\n", __func__);
- /* Make sure that we don't keep incomplete data */
- fw_load_abort(fw_priv);
- return -ENOMEM;
- }
- fw_priv->alloc_size = new_size;
- if (fw_priv->fw->data) {
- memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
- vfree(fw_priv->fw->data);
+ if (!fw_priv->pages[fw_priv->nr_pages]) {
+ fw_load_abort(fw_priv);
+ return -ENOMEM;
+ }
+ fw_priv->nr_pages++;
}
- fw_priv->fw->data = new_data;
- BUG_ON(min_size > fw_priv->alloc_size);
return 0;
}
@@ -258,10 +316,25 @@ firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr,
if (retval)
goto out;
- memcpy((u8 *)fw->data + offset, buffer, count);
-
- fw->size = max_t(size_t, offset + count, fw->size);
retval = count;
+
+ while (count) {
+ void *page_data;
+ int page_nr = offset >> PAGE_SHIFT;
+ int page_ofs = offset & (PAGE_SIZE - 1);
+ int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count);
+
+ page_data = kmap(fw_priv->pages[page_nr]);
+
+ memcpy(page_data + page_ofs, buffer, page_cnt);
+
+ kunmap(page_data);
+ buffer += page_cnt;
+ offset += page_cnt;
+ count -= page_cnt;
+ }
+
+ fw->size = max_t(size_t, offset, fw->size);
out:
mutex_unlock(&fw_lock);
return retval;
@@ -277,7 +350,11 @@ static struct bin_attribute firmware_attr_data_tmpl = {
static void fw_dev_release(struct device *dev)
{
struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+ int i;
+ for (i = 0; i < fw_priv->nr_pages; i++)
+ __free_page(fw_priv->pages[i]);
+ kfree(fw_priv->pages);
kfree(fw_priv);
kfree(dev);
diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c
index 9f0e672f4be8..8ad4ffea6920 100644
--- a/drivers/base/iommu.c
+++ b/drivers/base/iommu.c
@@ -18,6 +18,8 @@
#include <linux/bug.h>
#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/iommu.h>
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index b5b6c973a2e0..8b4708e06244 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -217,7 +217,6 @@ int platform_device_add_data(struct platform_device *pdev, const void *data,
if (d) {
memcpy(d, data, size);
pdev->dev.platform_data = d;
- pdev->platform_data = d;
}
return d ? 0 : -ENOMEM;
}
@@ -247,21 +246,6 @@ int platform_device_add(struct platform_device *pdev)
else
dev_set_name(&pdev->dev, pdev->name);
- /* We will remove platform_data field from struct device
- * if all platform devices pass its platform specific data
- * from platform_device. The conversion is going to be a
- * long time, so we allow the two cases coexist to make
- * this kind of fix more easily*/
- if (pdev->platform_data && pdev->dev.platform_data) {
- printk(KERN_ERR
- "%s: use which platform_data?\n",
- dev_name(&pdev->dev));
- } else if (pdev->platform_data) {
- pdev->dev.platform_data = pdev->platform_data;
- } else if (pdev->dev.platform_data) {
- pdev->platform_data = pdev->dev.platform_data;
- }
-
for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];
@@ -1028,7 +1012,7 @@ static __initdata LIST_HEAD(early_platform_device_list);
/**
* early_platform_driver_register
- * @edrv: early_platform driver structure
+ * @epdrv: early_platform driver structure
* @buf: string passed from early_param()
*/
int __init early_platform_driver_register(struct early_platform_driver *epdrv,
@@ -1112,7 +1096,7 @@ void __init early_platform_driver_register_all(char *class_str)
/**
* early_platform_match
- * @edrv: early platform driver structure
+ * @epdrv: early platform driver structure
* @id: id to match against
*/
static __init struct platform_device *
@@ -1130,7 +1114,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id)
/**
* early_platform_left
- * @edrv: early platform driver structure
+ * @epdrv: early platform driver structure
* @id: return true if id or above exists
*/
static __init int early_platform_left(struct early_platform_driver *epdrv,
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index f22ed6cc69f2..668dc234b8e2 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -3321,7 +3321,7 @@ static int DAC960_process_queue(DAC960_Controller_T *Controller, struct request_
DAC960_Command_T *Command;
while(1) {
- Request = elv_next_request(req_q);
+ Request = blk_peek_request(req_q);
if (!Request)
return 1;
@@ -3338,10 +3338,10 @@ static int DAC960_process_queue(DAC960_Controller_T *Controller, struct request_
}
Command->Completion = Request->end_io_data;
Command->LogicalDriveNumber = (long)Request->rq_disk->private_data;
- Command->BlockNumber = Request->sector;
- Command->BlockCount = Request->nr_sectors;
+ Command->BlockNumber = blk_rq_pos(Request);
+ Command->BlockCount = blk_rq_sectors(Request);
Command->Request = Request;
- blkdev_dequeue_request(Request);
+ blk_start_request(Request);
Command->SegmentCount = blk_rq_map_sg(req_q,
Command->Request, Command->cmd_sglist);
/* pci_map_sg MAY change the value of SegCount */
@@ -3431,7 +3431,7 @@ static void DAC960_queue_partial_rw(DAC960_Command_T *Command)
* successfully as possible.
*/
Command->SegmentCount = 1;
- Command->BlockNumber = Request->sector;
+ Command->BlockNumber = blk_rq_pos(Request);
Command->BlockCount = 1;
DAC960_QueueReadWriteCommand(Command);
return;
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index ddea8e485cc9..f42fa50d3550 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -412,7 +412,7 @@ config ATA_OVER_ETH
config MG_DISK
tristate "mGine mflash, gflash support"
- depends on ARM && ATA && GPIOLIB
+ depends on ARM && GPIOLIB
help
mGine mFlash(gFlash) block device driver
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 8df436ff7068..9c6e5b0fe894 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -112,8 +112,6 @@ module_param(fd_def_df0, ulong, 0);
MODULE_LICENSE("GPL");
static struct request_queue *floppy_queue;
-#define QUEUE (floppy_queue)
-#define CURRENT elv_next_request(floppy_queue)
/*
* Macros
@@ -1335,64 +1333,60 @@ static int get_track(int drive, int track)
static void redo_fd_request(void)
{
+ struct request *rq;
unsigned int cnt, block, track, sector;
int drive;
struct amiga_floppy_struct *floppy;
char *data;
unsigned long flags;
+ int err;
- repeat:
- if (!CURRENT) {
+next_req:
+ rq = blk_fetch_request(floppy_queue);
+ if (!rq) {
/* Nothing left to do */
return;
}
- floppy = CURRENT->rq_disk->private_data;
+ floppy = rq->rq_disk->private_data;
drive = floppy - unit;
+next_segment:
/* Here someone could investigate to be more efficient */
- for (cnt = 0; cnt < CURRENT->current_nr_sectors; cnt++) {
+ for (cnt = 0, err = 0; cnt < blk_rq_cur_sectors(rq); cnt++) {
#ifdef DEBUG
printk("fd: sector %ld + %d requested for %s\n",
- CURRENT->sector,cnt,
- (rq_data_dir(CURRENT) == READ) ? "read" : "write");
+ blk_rq_pos(rq), cnt,
+ (rq_data_dir(rq) == READ) ? "read" : "write");
#endif
- block = CURRENT->sector + cnt;
+ block = blk_rq_pos(rq) + cnt;
if ((int)block > floppy->blocks) {
- end_request(CURRENT, 0);
- goto repeat;
+ err = -EIO;
+ break;
}
track = block / (floppy->dtype->sects * floppy->type->sect_mult);
sector = block % (floppy->dtype->sects * floppy->type->sect_mult);
- data = CURRENT->buffer + 512 * cnt;
+ data = rq->buffer + 512 * cnt;
#ifdef DEBUG
printk("access to track %d, sector %d, with buffer at "
"0x%08lx\n", track, sector, data);
#endif
- if ((rq_data_dir(CURRENT) != READ) && (rq_data_dir(CURRENT) != WRITE)) {
- printk(KERN_WARNING "do_fd_request: unknown command\n");
- end_request(CURRENT, 0);
- goto repeat;
- }
if (get_track(drive, track) == -1) {
- end_request(CURRENT, 0);
- goto repeat;
+ err = -EIO;
+ break;
}
- switch (rq_data_dir(CURRENT)) {
- case READ:
+ if (rq_data_dir(rq) == READ) {
memcpy(data, floppy->trackbuf + sector * 512, 512);
- break;
-
- case WRITE:
+ } else {
memcpy(floppy->trackbuf + sector * 512, data, 512);
/* keep the drive spinning while writes are scheduled */
if (!fd_motor_on(drive)) {
- end_request(CURRENT, 0);
- goto repeat;
+ err = -EIO;
+ break;
}
/*
* setup a callback to write the track buffer
@@ -1404,14 +1398,12 @@ static void redo_fd_request(void)
/* reset the timer */
mod_timer (flush_track_timer + drive, jiffies + 1);
local_irq_restore(flags);
- break;
}
}
- CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
- CURRENT->sector += CURRENT->current_nr_sectors;
- end_request(CURRENT, 1);
- goto repeat;
+ if (__blk_end_request_cur(rq, err))
+ goto next_segment;
+ goto next_req;
}
static void do_fd_request(struct request_queue * q)
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 4234c11c1e4c..f5e7180d7f47 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -79,9 +79,7 @@
#undef DEBUG
static struct request_queue *floppy_queue;
-
-#define QUEUE (floppy_queue)
-#define CURRENT elv_next_request(floppy_queue)
+static struct request *fd_request;
/* Disk types: DD, HD, ED */
static struct atari_disk_type {
@@ -376,6 +374,12 @@ static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0);
static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0);
static DEFINE_TIMER(fd_timer, check_change, 0, 0);
+static void fd_end_request_cur(int err)
+{
+ if (!__blk_end_request_cur(fd_request, err))
+ fd_request = NULL;
+}
+
static inline void start_motor_off_timer(void)
{
mod_timer(&motor_off_timer, jiffies + FD_MOTOR_OFF_DELAY);
@@ -606,15 +610,15 @@ static void fd_error( void )
return;
}
- if (!CURRENT)
+ if (!fd_request)
return;
- CURRENT->errors++;
- if (CURRENT->errors >= MAX_ERRORS) {
+ fd_request->errors++;
+ if (fd_request->errors >= MAX_ERRORS) {
printk(KERN_ERR "fd%d: too many errors.\n", SelectedDrive );
- end_request(CURRENT, 0);
+ fd_end_request_cur(-EIO);
}
- else if (CURRENT->errors == RECALIBRATE_ERRORS) {
+ else if (fd_request->errors == RECALIBRATE_ERRORS) {
printk(KERN_WARNING "fd%d: recalibrating\n", SelectedDrive );
if (SelectedDrive != -1)
SUD.track = -1;
@@ -725,16 +729,14 @@ static void do_fd_action( int drive )
if (IS_BUFFERED( drive, ReqSide, ReqTrack )) {
if (ReqCmd == READ) {
copy_buffer( SECTOR_BUFFER(ReqSector), ReqData );
- if (++ReqCnt < CURRENT->current_nr_sectors) {
+ if (++ReqCnt < blk_rq_cur_sectors(fd_request)) {
/* read next sector */
setup_req_params( drive );
goto repeat;
}
else {
/* all sectors finished */
- CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
- CURRENT->sector += CURRENT->current_nr_sectors;
- end_request(CURRENT, 1);
+ fd_end_request_cur(0);
redo_fd_request();
return;
}
@@ -1132,16 +1134,14 @@ static void fd_rwsec_done1(int status)
}
}
- if (++ReqCnt < CURRENT->current_nr_sectors) {
+ if (++ReqCnt < blk_rq_cur_sectors(fd_request)) {
/* read next sector */
setup_req_params( SelectedDrive );
do_fd_action( SelectedDrive );
}
else {
/* all sectors finished */
- CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
- CURRENT->sector += CURRENT->current_nr_sectors;
- end_request(CURRENT, 1);
+ fd_end_request_cur(0);
redo_fd_request();
}
return;
@@ -1382,7 +1382,7 @@ static void setup_req_params( int drive )
ReqData = ReqBuffer + 512 * ReqCnt;
if (UseTrackbuffer)
- read_track = (ReqCmd == READ && CURRENT->errors == 0);
+ read_track = (ReqCmd == READ && fd_request->errors == 0);
else
read_track = 0;
@@ -1396,25 +1396,27 @@ static void redo_fd_request(void)
int drive, type;
struct atari_floppy_struct *floppy;
- DPRINT(("redo_fd_request: CURRENT=%p dev=%s CURRENT->sector=%ld\n",
- CURRENT, CURRENT ? CURRENT->rq_disk->disk_name : "",
- CURRENT ? CURRENT->sector : 0 ));
+ DPRINT(("redo_fd_request: fd_request=%p dev=%s fd_request->sector=%ld\n",
+ fd_request, fd_request ? fd_request->rq_disk->disk_name : "",
+ fd_request ? blk_rq_pos(fd_request) : 0 ));
IsFormatting = 0;
repeat:
+ if (!fd_request) {
+ fd_request = blk_fetch_request(floppy_queue);
+ if (!fd_request)
+ goto the_end;
+ }
- if (!CURRENT)
- goto the_end;
-
- floppy = CURRENT->rq_disk->private_data;
+ floppy = fd_request->rq_disk->private_data;
drive = floppy - unit;
type = floppy->type;
if (!UD.connected) {
/* drive not connected */
printk(KERN_ERR "Unknown Device: fd%d\n", drive );
- end_request(CURRENT, 0);
+ fd_end_request_cur(-EIO);
goto repeat;
}
@@ -1430,12 +1432,12 @@ repeat:
/* user supplied disk type */
if (--type >= NUM_DISK_MINORS) {
printk(KERN_WARNING "fd%d: invalid disk format", drive );
- end_request(CURRENT, 0);
+ fd_end_request_cur(-EIO);
goto repeat;
}
if (minor2disktype[type].drive_types > DriveType) {
printk(KERN_WARNING "fd%d: unsupported disk format", drive );
- end_request(CURRENT, 0);
+ fd_end_request_cur(-EIO);
goto repeat;
}
type = minor2disktype[type].index;
@@ -1444,8 +1446,8 @@ repeat:
UD.autoprobe = 0;
}
- if (CURRENT->sector + 1 > UDT->blocks) {
- end_request(CURRENT, 0);
+ if (blk_rq_pos(fd_request) + 1 > UDT->blocks) {
+ fd_end_request_cur(-EIO);
goto repeat;
}
@@ -1453,9 +1455,9 @@ repeat:
del_timer( &motor_off_timer );
ReqCnt = 0;
- ReqCmd = rq_data_dir(CURRENT);
- ReqBlock = CURRENT->sector;
- ReqBuffer = CURRENT->buffer;
+ ReqCmd = rq_data_dir(fd_request);
+ ReqBlock = blk_rq_pos(fd_request);
+ ReqBuffer = fd_request->buffer;
setup_req_params( drive );
do_fd_action( drive );
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 4d4d5e0d3fa6..e714e7cce6f2 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1299,7 +1299,6 @@ static void cciss_softirq_done(struct request *rq)
{
CommandList_struct *cmd = rq->completion_data;
ctlr_info_t *h = hba[cmd->ctlr];
- unsigned int nr_bytes;
unsigned long flags;
u64bit temp64;
int i, ddir;
@@ -1321,15 +1320,11 @@ static void cciss_softirq_done(struct request *rq)
printk("Done with %p\n", rq);
#endif /* CCISS_DEBUG */
- /*
- * Store the full size and set the residual count for pc requests
- */
- nr_bytes = blk_rq_bytes(rq);
+ /* set the residual count for pc requests */
if (blk_pc_request(rq))
- rq->data_len = cmd->err_info->ResidualCnt;
+ rq->resid_len = cmd->err_info->ResidualCnt;
- if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, nr_bytes))
- BUG();
+ blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO);
spin_lock_irqsave(&h->lock, flags);
cmd_free(h, cmd, 1);
@@ -2691,7 +2686,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
printk(KERN_WARNING "cciss: cmd %p has"
" completed with data underrun "
"reported\n", cmd);
- cmd->rq->data_len = cmd->err_info->ResidualCnt;
+ cmd->rq->resid_len = cmd->err_info->ResidualCnt;
}
break;
case CMD_DATA_OVERRUN:
@@ -2806,7 +2801,7 @@ static void do_cciss_request(struct request_queue *q)
goto startio;
queue:
- creq = elv_next_request(q);
+ creq = blk_peek_request(q);
if (!creq)
goto startio;
@@ -2815,7 +2810,7 @@ static void do_cciss_request(struct request_queue *q)
if ((c = cmd_alloc(h, 1)) == NULL)
goto full;
- blkdev_dequeue_request(creq);
+ blk_start_request(creq);
spin_unlock_irq(q->queue_lock);
@@ -2840,10 +2835,10 @@ static void do_cciss_request(struct request_queue *q)
c->Request.Timeout = 0; // Don't time out
c->Request.CDB[0] =
(rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
- start_blk = creq->sector;
+ start_blk = blk_rq_pos(creq);
#ifdef CCISS_DEBUG
- printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", (int)creq->sector,
- (int)creq->nr_sectors);
+ printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n",
+ (int)blk_rq_pos(creq), (int)blk_rq_sectors(creq));
#endif /* CCISS_DEBUG */
sg_init_table(tmp_sg, MAXSGENTRIES);
@@ -2869,8 +2864,8 @@ static void do_cciss_request(struct request_queue *q)
h->maxSG = seg;
#ifdef CCISS_DEBUG
- printk(KERN_DEBUG "cciss: Submitting %lu sectors in %d segments\n",
- creq->nr_sectors, seg);
+ printk(KERN_DEBUG "cciss: Submitting %u sectors in %d segments\n",
+ blk_rq_sectors(creq), seg);
#endif /* CCISS_DEBUG */
c->Header.SGList = c->Header.SGTotal = seg;
@@ -2882,8 +2877,8 @@ static void do_cciss_request(struct request_queue *q)
c->Request.CDB[4] = (start_blk >> 8) & 0xff;
c->Request.CDB[5] = start_blk & 0xff;
c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB
- c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
- c->Request.CDB[8] = creq->nr_sectors & 0xff;
+ c->Request.CDB[7] = (blk_rq_sectors(creq) >> 8) & 0xff;
+ c->Request.CDB[8] = blk_rq_sectors(creq) & 0xff;
c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
} else {
u32 upper32 = upper_32_bits(start_blk);
@@ -2898,10 +2893,10 @@ static void do_cciss_request(struct request_queue *q)
c->Request.CDB[7]= (start_blk >> 16) & 0xff;
c->Request.CDB[8]= (start_blk >> 8) & 0xff;
c->Request.CDB[9]= start_blk & 0xff;
- c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff;
- c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff;
- c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff;
- c->Request.CDB[13]= creq->nr_sectors & 0xff;
+ c->Request.CDB[10]= (blk_rq_sectors(creq) >> 24) & 0xff;
+ c->Request.CDB[11]= (blk_rq_sectors(creq) >> 16) & 0xff;
+ c->Request.CDB[12]= (blk_rq_sectors(creq) >> 8) & 0xff;
+ c->Request.CDB[13]= blk_rq_sectors(creq) & 0xff;
c->Request.CDB[14] = c->Request.CDB[15] = 0;
}
} else if (blk_pc_request(creq)) {
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index ca268ca11159..a02dcfc00f13 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -903,7 +903,7 @@ static void do_ida_request(struct request_queue *q)
goto startio;
queue_next:
- creq = elv_next_request(q);
+ creq = blk_peek_request(q);
if (!creq)
goto startio;
@@ -912,17 +912,18 @@ queue_next:
if ((c = cmd_alloc(h,1)) == NULL)
goto startio;
- blkdev_dequeue_request(creq);
+ blk_start_request(creq);
c->ctlr = h->ctlr;
c->hdr.unit = (drv_info_t *)(creq->rq_disk->private_data) - h->drv;
c->hdr.size = sizeof(rblk_t) >> 2;
c->size += sizeof(rblk_t);
- c->req.hdr.blk = creq->sector;
+ c->req.hdr.blk = blk_rq_pos(creq);
c->rq = creq;
DBGPX(
- printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
+ printk("sector=%d, nr_sectors=%u\n",
+ blk_rq_pos(creq), blk_rq_sectors(creq));
);
sg_init_table(tmp_sg, SG_MAX);
seg = blk_rq_map_sg(q, creq, tmp_sg);
@@ -940,9 +941,9 @@ DBGPX(
tmp_sg[i].offset,
tmp_sg[i].length, dir);
}
-DBGPX( printk("Submitting %d sectors in %d segments\n", creq->nr_sectors, seg); );
+DBGPX( printk("Submitting %u sectors in %d segments\n", blk_rq_sectors(creq), seg); );
c->req.hdr.sg_cnt = seg;
- c->req.hdr.blk_cnt = creq->nr_sectors;
+ c->req.hdr.blk_cnt = blk_rq_sectors(creq);
c->req.hdr.cmd = (rq_data_dir(creq) == READ) ? IDA_READ : IDA_WRITE;
c->type = CMD_RWREQ;
@@ -1024,8 +1025,7 @@ static inline void complete_command(cmdlist_t *cmd, int timeout)
cmd->req.sg[i].size, ddir);
DBGPX(printk("Done with %p\n", rq););
- if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
- BUG();
+ __blk_end_request_all(rq, error);
}
/*
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 1300df6f1642..90877fee0ee0 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -931,7 +931,7 @@ static inline void unlock_fdc(void)
del_timer(&fd_timeout);
cont = NULL;
clear_bit(0, &fdc_busy);
- if (elv_next_request(floppy_queue))
+ if (current_req || blk_peek_request(floppy_queue))
do_fd_request(floppy_queue);
spin_unlock_irqrestore(&floppy_lock, flags);
wake_up(&fdc_wait);
@@ -2303,7 +2303,7 @@ static void floppy_end_request(struct request *req, int error)
/* current_count_sectors can be zero if transfer failed */
if (error)
- nr_sectors = req->current_nr_sectors;
+ nr_sectors = blk_rq_cur_sectors(req);
if (__blk_end_request(req, error, nr_sectors << 9))
return;
@@ -2332,7 +2332,7 @@ static void request_done(int uptodate)
if (uptodate) {
/* maintain values for invalidation on geometry
* change */
- block = current_count_sectors + req->sector;
+ block = current_count_sectors + blk_rq_pos(req);
INFBOUND(DRS->maxblock, block);
if (block > _floppy->sect)
DRS->maxtrack = 1;
@@ -2346,10 +2346,10 @@ static void request_done(int uptodate)
/* record write error information */
DRWE->write_errors++;
if (DRWE->write_errors == 1) {
- DRWE->first_error_sector = req->sector;
+ DRWE->first_error_sector = blk_rq_pos(req);
DRWE->first_error_generation = DRS->generation;
}
- DRWE->last_error_sector = req->sector;
+ DRWE->last_error_sector = blk_rq_pos(req);
DRWE->last_error_generation = DRS->generation;
}
spin_lock_irqsave(q->queue_lock, flags);
@@ -2503,24 +2503,23 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
max_sector = transfer_size(ssize,
min(max_sector, max_sector_2),
- current_req->nr_sectors);
+ blk_rq_sectors(current_req));
if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
- buffer_max > fsector_t + current_req->nr_sectors)
+ buffer_max > fsector_t + blk_rq_sectors(current_req))
current_count_sectors = min_t(int, buffer_max - fsector_t,
- current_req->nr_sectors);
+ blk_rq_sectors(current_req));
remaining = current_count_sectors << 9;
#ifdef FLOPPY_SANITY_CHECK
- if ((remaining >> 9) > current_req->nr_sectors &&
- CT(COMMAND) == FD_WRITE) {
+ if (remaining > blk_rq_bytes(current_req) && CT(COMMAND) == FD_WRITE) {
DPRINT("in copy buffer\n");
printk("current_count_sectors=%ld\n", current_count_sectors);
printk("remaining=%d\n", remaining >> 9);
- printk("current_req->nr_sectors=%ld\n",
- current_req->nr_sectors);
+ printk("current_req->nr_sectors=%u\n",
+ blk_rq_sectors(current_req));
printk("current_req->current_nr_sectors=%u\n",
- current_req->current_nr_sectors);
+ blk_rq_cur_sectors(current_req));
printk("max_sector=%d\n", max_sector);
printk("ssize=%d\n", ssize);
}
@@ -2530,7 +2529,7 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
dma_buffer = floppy_track_buffer + ((fsector_t - buffer_min) << 9);
- size = current_req->current_nr_sectors << 9;
+ size = blk_rq_cur_bytes(current_req);
rq_for_each_segment(bv, current_req, iter) {
if (!remaining)
@@ -2648,10 +2647,10 @@ static int make_raw_rw_request(void)
max_sector = _floppy->sect * _floppy->head;
- TRACK = (int)current_req->sector / max_sector;
- fsector_t = (int)current_req->sector % max_sector;
+ TRACK = (int)blk_rq_pos(current_req) / max_sector;
+ fsector_t = (int)blk_rq_pos(current_req) % max_sector;
if (_floppy->track && TRACK >= _floppy->track) {
- if (current_req->current_nr_sectors & 1) {
+ if (blk_rq_cur_sectors(current_req) & 1) {
current_count_sectors = 1;
return 1;
} else
@@ -2669,7 +2668,7 @@ static int make_raw_rw_request(void)
if (fsector_t >= max_sector) {
current_count_sectors =
min_t(int, _floppy->sect - fsector_t,
- current_req->nr_sectors);
+ blk_rq_sectors(current_req));
return 1;
}
SIZECODE = 2;
@@ -2720,7 +2719,7 @@ static int make_raw_rw_request(void)
in_sector_offset = (fsector_t % _floppy->sect) % ssize;
aligned_sector_t = fsector_t - in_sector_offset;
- max_size = current_req->nr_sectors;
+ max_size = blk_rq_sectors(current_req);
if ((raw_cmd->track == buffer_track) &&
(current_drive == buffer_drive) &&
(fsector_t >= buffer_min) && (fsector_t < buffer_max)) {
@@ -2729,10 +2728,10 @@ static int make_raw_rw_request(void)
copy_buffer(1, max_sector, buffer_max);
return 1;
}
- } else if (in_sector_offset || current_req->nr_sectors < ssize) {
+ } else if (in_sector_offset || blk_rq_sectors(current_req) < ssize) {
if (CT(COMMAND) == FD_WRITE) {
- if (fsector_t + current_req->nr_sectors > ssize &&
- fsector_t + current_req->nr_sectors < ssize + ssize)
+ if (fsector_t + blk_rq_sectors(current_req) > ssize &&
+ fsector_t + blk_rq_sectors(current_req) < ssize + ssize)
max_size = ssize + ssize;
else
max_size = ssize;
@@ -2776,7 +2775,7 @@ static int make_raw_rw_request(void)
(indirect * 2 > direct * 3 &&
*errors < DP->max_errors.read_track && ((!probing
|| (DP->read_track & (1 << DRS->probed_format)))))) {
- max_size = current_req->nr_sectors;
+ max_size = blk_rq_sectors(current_req);
} else {
raw_cmd->kernel_data = current_req->buffer;
raw_cmd->length = current_count_sectors << 9;
@@ -2801,7 +2800,7 @@ static int make_raw_rw_request(void)
fsector_t > buffer_max ||
fsector_t < buffer_min ||
((CT(COMMAND) == FD_READ ||
- (!in_sector_offset && current_req->nr_sectors >= ssize)) &&
+ (!in_sector_offset && blk_rq_sectors(current_req) >= ssize)) &&
max_sector > 2 * max_buffer_sectors + buffer_min &&
max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)
/* not enough space */
@@ -2879,8 +2878,8 @@ static int make_raw_rw_request(void)
printk("write\n");
return 0;
}
- } else if (raw_cmd->length > current_req->nr_sectors << 9 ||
- current_count_sectors > current_req->nr_sectors) {
+ } else if (raw_cmd->length > blk_rq_bytes(current_req) ||
+ current_count_sectors > blk_rq_sectors(current_req)) {
DPRINT("buffer overrun in direct transfer\n");
return 0;
} else if (raw_cmd->length < current_count_sectors << 9) {
@@ -2913,7 +2912,7 @@ static void redo_fd_request(void)
struct request *req;
spin_lock_irq(floppy_queue->queue_lock);
- req = elv_next_request(floppy_queue);
+ req = blk_fetch_request(floppy_queue);
spin_unlock_irq(floppy_queue->queue_lock);
if (!req) {
do_floppy = NULL;
@@ -2990,8 +2989,9 @@ static void do_fd_request(struct request_queue * q)
if (usage_count == 0) {
printk("warning: usage count=0, current_req=%p exiting\n",
current_req);
- printk("sect=%ld type=%x flags=%x\n", (long)current_req->sector,
- current_req->cmd_type, current_req->cmd_flags);
+ printk("sect=%ld type=%x flags=%x\n",
+ (long)blk_rq_pos(current_req), current_req->cmd_type,
+ current_req->cmd_flags);
return;
}
if (test_bit(0, &fdc_busy)) {
diff --git a/drivers/block/hd.c b/drivers/block/hd.c
index baaa9e486e50..961de56d00a9 100644
--- a/drivers/block/hd.c
+++ b/drivers/block/hd.c
@@ -98,10 +98,9 @@
static DEFINE_SPINLOCK(hd_lock);
static struct request_queue *hd_queue;
+static struct request *hd_req;
#define MAJOR_NR HD_MAJOR
-#define QUEUE (hd_queue)
-#define CURRENT elv_next_request(hd_queue)
#define TIMEOUT_VALUE (6*HZ)
#define HD_DELAY 0
@@ -195,11 +194,24 @@ static void __init hd_setup(char *str, int *ints)
NR_HD = hdind+1;
}
+static bool hd_end_request(int err, unsigned int bytes)
+{
+ if (__blk_end_request(hd_req, err, bytes))
+ return true;
+ hd_req = NULL;
+ return false;
+}
+
+static bool hd_end_request_cur(int err)
+{
+ return hd_end_request(err, blk_rq_cur_bytes(hd_req));
+}
+
static void dump_status(const char *msg, unsigned int stat)
{
char *name = "hd?";
- if (CURRENT)
- name = CURRENT->rq_disk->disk_name;
+ if (hd_req)
+ name = hd_req->rq_disk->disk_name;
#ifdef VERBOSE_ERRORS
printk("%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
@@ -227,8 +239,8 @@ static void dump_status(const char *msg, unsigned int stat)
if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) {
printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL),
inb(HD_CURRENT) & 0xf, inb(HD_SECTOR));
- if (CURRENT)
- printk(", sector=%ld", CURRENT->sector);
+ if (hd_req)
+ printk(", sector=%ld", blk_rq_pos(hd_req));
}
printk("\n");
}
@@ -406,11 +418,12 @@ static void unexpected_hd_interrupt(void)
*/
static void bad_rw_intr(void)
{
- struct request *req = CURRENT;
+ struct request *req = hd_req;
+
if (req != NULL) {
struct hd_i_struct *disk = req->rq_disk->private_data;
if (++req->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) {
- end_request(req, 0);
+ hd_end_request_cur(-EIO);
disk->special_op = disk->recalibrate = 1;
} else if (req->errors % RESET_FREQ == 0)
reset = 1;
@@ -452,37 +465,30 @@ static void read_intr(void)
bad_rw_intr();
hd_request();
return;
+
ok_to_read:
- req = CURRENT;
+ req = hd_req;
insw(HD_DATA, req->buffer, 256);
- req->sector++;
- req->buffer += 512;
- req->errors = 0;
- i = --req->nr_sectors;
- --req->current_nr_sectors;
#ifdef DEBUG
- printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n",
- req->rq_disk->disk_name, req->sector, req->nr_sectors,
- req->buffer+512);
+ printk("%s: read: sector %ld, remaining = %u, buffer=%p\n",
+ req->rq_disk->disk_name, blk_rq_pos(req) + 1,
+ blk_rq_sectors(req) - 1, req->buffer+512);
#endif
- if (req->current_nr_sectors <= 0)
- end_request(req, 1);
- if (i > 0) {
+ if (hd_end_request(0, 512)) {
SET_HANDLER(&read_intr);
return;
}
+
(void) inb_p(HD_STATUS);
#if (HD_DELAY > 0)
last_req = read_timer();
#endif
- if (elv_next_request(QUEUE))
- hd_request();
- return;
+ hd_request();
}
static void write_intr(void)
{
- struct request *req = CURRENT;
+ struct request *req = hd_req;
int i;
int retries = 100000;
@@ -492,30 +498,25 @@ static void write_intr(void)
continue;
if (!OK_STATUS(i))
break;
- if ((req->nr_sectors <= 1) || (i & DRQ_STAT))
+ if ((blk_rq_sectors(req) <= 1) || (i & DRQ_STAT))
goto ok_to_write;
} while (--retries > 0);
dump_status("write_intr", i);
bad_rw_intr();
hd_request();
return;
+
ok_to_write:
- req->sector++;
- i = --req->nr_sectors;
- --req->current_nr_sectors;
- req->buffer += 512;
- if (!i || (req->bio && req->current_nr_sectors <= 0))
- end_request(req, 1);
- if (i > 0) {
+ if (hd_end_request(0, 512)) {
SET_HANDLER(&write_intr);
outsw(HD_DATA, req->buffer, 256);
- } else {
+ return;
+ }
+
#if (HD_DELAY > 0)
- last_req = read_timer();
+ last_req = read_timer();
#endif
- hd_request();
- }
- return;
+ hd_request();
}
static void recal_intr(void)
@@ -537,18 +538,18 @@ static void hd_times_out(unsigned long dummy)
do_hd = NULL;
- if (!CURRENT)
+ if (!hd_req)
return;
spin_lock_irq(hd_queue->queue_lock);
reset = 1;
- name = CURRENT->rq_disk->disk_name;
+ name = hd_req->rq_disk->disk_name;
printk("%s: timeout\n", name);
- if (++CURRENT->errors >= MAX_ERRORS) {
+ if (++hd_req->errors >= MAX_ERRORS) {
#ifdef DEBUG
printk("%s: too many errors\n", name);
#endif
- end_request(CURRENT, 0);
+ hd_end_request_cur(-EIO);
}
hd_request();
spin_unlock_irq(hd_queue->queue_lock);
@@ -563,7 +564,7 @@ static int do_special_op(struct hd_i_struct *disk, struct request *req)
}
if (disk->head > 16) {
printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name);
- end_request(req, 0);
+ hd_end_request_cur(-EIO);
}
disk->special_op = 0;
return 1;
@@ -590,24 +591,27 @@ static void hd_request(void)
repeat:
del_timer(&device_timer);
- req = CURRENT;
- if (!req) {
- do_hd = NULL;
- return;
+ if (!hd_req) {
+ hd_req = blk_fetch_request(hd_queue);
+ if (!hd_req) {
+ do_hd = NULL;
+ return;
+ }
}
+ req = hd_req;
if (reset) {
reset_hd();
return;
}
disk = req->rq_disk->private_data;
- block = req->sector;
- nsect = req->nr_sectors;
+ block = blk_rq_pos(req);
+ nsect = blk_rq_sectors(req);
if (block >= get_capacity(req->rq_disk) ||
((block+nsect) > get_capacity(req->rq_disk))) {
printk("%s: bad access: block=%d, count=%d\n",
req->rq_disk->disk_name, block, nsect);
- end_request(req, 0);
+ hd_end_request_cur(-EIO);
goto repeat;
}
@@ -647,7 +651,7 @@ repeat:
break;
default:
printk("unknown hd-command\n");
- end_request(req, 0);
+ hd_end_request_cur(-EIO);
break;
}
}
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index ddae80825899..801f4ab83302 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -511,11 +511,7 @@ out:
*/
static void loop_add_bio(struct loop_device *lo, struct bio *bio)
{
- if (lo->lo_biotail) {
- lo->lo_biotail->bi_next = bio;
- lo->lo_biotail = bio;
- } else
- lo->lo_bio = lo->lo_biotail = bio;
+ bio_list_add(&lo->lo_bio_list, bio);
}
/*
@@ -523,16 +519,7 @@ static void loop_add_bio(struct loop_device *lo, struct bio *bio)
*/
static struct bio *loop_get_bio(struct loop_device *lo)
{
- struct bio *bio;
-
- if ((bio = lo->lo_bio)) {
- if (bio == lo->lo_biotail)
- lo->lo_biotail = NULL;
- lo->lo_bio = bio->bi_next;
- bio->bi_next = NULL;
- }
-
- return bio;
+ return bio_list_pop(&lo->lo_bio_list);
}
static int loop_make_request(struct request_queue *q, struct bio *old_bio)
@@ -609,12 +596,13 @@ static int loop_thread(void *data)
set_user_nice(current, -20);
- while (!kthread_should_stop() || lo->lo_bio) {
+ while (!kthread_should_stop() || !bio_list_empty(&lo->lo_bio_list)) {
wait_event_interruptible(lo->lo_event,
- lo->lo_bio || kthread_should_stop());
+ !bio_list_empty(&lo->lo_bio_list) ||
+ kthread_should_stop());
- if (!lo->lo_bio)
+ if (bio_list_empty(&lo->lo_bio_list))
continue;
spin_lock_irq(&lo->lo_lock);
bio = loop_get_bio(lo);
@@ -721,10 +709,6 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
goto out_putf;
- /* new backing store needs to support loop (eg splice_read) */
- if (!inode->i_fop->splice_read)
- goto out_putf;
-
/* size of the new backing store needs to be the same */
if (get_loop_size(lo, file) != get_loop_size(lo, old_file))
goto out_putf;
@@ -800,12 +784,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
error = -EINVAL;
if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) {
const struct address_space_operations *aops = mapping->a_ops;
- /*
- * If we can't read - sorry. If we only can't write - well,
- * it's going to be read-only.
- */
- if (!file->f_op->splice_read)
- goto out_putf;
+
if (aops->write_begin)
lo_flags |= LO_FLAGS_USE_AOPS;
if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write)
@@ -841,7 +820,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
lo->old_gfp_mask = mapping_gfp_mask(mapping);
mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
- lo->lo_bio = lo->lo_biotail = NULL;
+ bio_list_init(&lo->lo_bio_list);
/*
* set queue make_request_fn, and add limits based on lower level
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
index f3898353d0a8..c0cd0a03f698 100644
--- a/drivers/block/mg_disk.c
+++ b/drivers/block/mg_disk.c
@@ -17,71 +17,220 @@
#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
-#include <linux/libata.h>
+#include <linux/ata.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
-#include <linux/mg_disk.h>
#define MG_RES_SEC (CONFIG_MG_DISK_RES << 1)
+/* name for block device */
+#define MG_DISK_NAME "mgd"
+/* name for platform device */
+#define MG_DEV_NAME "mg_disk"
+
+#define MG_DISK_MAJ 0
+#define MG_DISK_MAX_PART 16
+#define MG_SECTOR_SIZE 512
+#define MG_MAX_SECTS 256
+
+/* Register offsets */
+#define MG_BUFF_OFFSET 0x8000
+#define MG_STORAGE_BUFFER_SIZE 0x200
+#define MG_REG_OFFSET 0xC000
+#define MG_REG_FEATURE (MG_REG_OFFSET + 2) /* write case */
+#define MG_REG_ERROR (MG_REG_OFFSET + 2) /* read case */
+#define MG_REG_SECT_CNT (MG_REG_OFFSET + 4)
+#define MG_REG_SECT_NUM (MG_REG_OFFSET + 6)
+#define MG_REG_CYL_LOW (MG_REG_OFFSET + 8)
+#define MG_REG_CYL_HIGH (MG_REG_OFFSET + 0xA)
+#define MG_REG_DRV_HEAD (MG_REG_OFFSET + 0xC)
+#define MG_REG_COMMAND (MG_REG_OFFSET + 0xE) /* write case */
+#define MG_REG_STATUS (MG_REG_OFFSET + 0xE) /* read case */
+#define MG_REG_DRV_CTRL (MG_REG_OFFSET + 0x10)
+#define MG_REG_BURST_CTRL (MG_REG_OFFSET + 0x12)
+
+/* handy status */
+#define MG_STAT_READY (ATA_DRDY | ATA_DSC)
+#define MG_READY_OK(s) (((s) & (MG_STAT_READY | (ATA_BUSY | ATA_DF | \
+ ATA_ERR))) == MG_STAT_READY)
+
+/* error code for others */
+#define MG_ERR_NONE 0
+#define MG_ERR_TIMEOUT 0x100
+#define MG_ERR_INIT_STAT 0x101
+#define MG_ERR_TRANSLATION 0x102
+#define MG_ERR_CTRL_RST 0x103
+#define MG_ERR_INV_STAT 0x104
+#define MG_ERR_RSTOUT 0x105
+
+#define MG_MAX_ERRORS 6 /* Max read/write errors */
+
+/* command */
+#define MG_CMD_RD 0x20
+#define MG_CMD_WR 0x30
+#define MG_CMD_SLEEP 0x99
+#define MG_CMD_WAKEUP 0xC3
+#define MG_CMD_ID 0xEC
+#define MG_CMD_WR_CONF 0x3C
+#define MG_CMD_RD_CONF 0x40
+
+/* operation mode */
+#define MG_OP_CASCADE (1 << 0)
+#define MG_OP_CASCADE_SYNC_RD (1 << 1)
+#define MG_OP_CASCADE_SYNC_WR (1 << 2)
+#define MG_OP_INTERLEAVE (1 << 3)
+
+/* synchronous */
+#define MG_BURST_LAT_4 (3 << 4)
+#define MG_BURST_LAT_5 (4 << 4)
+#define MG_BURST_LAT_6 (5 << 4)
+#define MG_BURST_LAT_7 (6 << 4)
+#define MG_BURST_LAT_8 (7 << 4)
+#define MG_BURST_LEN_4 (1 << 1)
+#define MG_BURST_LEN_8 (2 << 1)
+#define MG_BURST_LEN_16 (3 << 1)
+#define MG_BURST_LEN_32 (4 << 1)
+#define MG_BURST_LEN_CONT (0 << 1)
+
+/* timeout value (unit: ms) */
+#define MG_TMAX_CONF_TO_CMD 1
+#define MG_TMAX_WAIT_RD_DRQ 10
+#define MG_TMAX_WAIT_WR_DRQ 500
+#define MG_TMAX_RST_TO_BUSY 10
+#define MG_TMAX_HDRST_TO_RDY 500
+#define MG_TMAX_SWRST_TO_RDY 500
+#define MG_TMAX_RSTOUT 3000
+
+/* device attribution */
+/* use mflash as boot device */
+#define MG_BOOT_DEV (1 << 0)
+/* use mflash as storage device */
+#define MG_STORAGE_DEV (1 << 1)
+/* same as MG_STORAGE_DEV, but bootloader already done reset sequence */
+#define MG_STORAGE_DEV_SKIP_RST (1 << 2)
+
+#define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST)
+
+/* names of GPIO resource */
+#define MG_RST_PIN "mg_rst"
+/* except MG_BOOT_DEV, reset-out pin should be assigned */
+#define MG_RSTOUT_PIN "mg_rstout"
+
+/* private driver data */
+struct mg_drv_data {
+ /* disk resource */
+ u32 use_polling;
+
+ /* device attribution */
+ u32 dev_attr;
+
+ /* internally used */
+ struct mg_host *host;
+};
+
+/* main structure for mflash driver */
+struct mg_host {
+ struct device *dev;
+
+ struct request_queue *breq;
+ struct request *req;
+ spinlock_t lock;
+ struct gendisk *gd;
+
+ struct timer_list timer;
+ void (*mg_do_intr) (struct mg_host *);
+
+ u16 id[ATA_ID_WORDS];
+
+ u16 cyls;
+ u16 heads;
+ u16 sectors;
+ u32 n_sectors;
+ u32 nres_sectors;
+
+ void __iomem *dev_base;
+ unsigned int irq;
+ unsigned int rst;
+ unsigned int rstout;
+
+ u32 major;
+ u32 error;
+};
+
+/*
+ * Debugging macro and defines
+ */
+#undef DO_MG_DEBUG
+#ifdef DO_MG_DEBUG
+# define MG_DBG(fmt, args...) \
+ printk(KERN_DEBUG "%s:%d "fmt, __func__, __LINE__, ##args)
+#else /* CONFIG_MG_DEBUG */
+# define MG_DBG(fmt, args...) do { } while (0)
+#endif /* CONFIG_MG_DEBUG */
+
static void mg_request(struct request_queue *);
+static bool mg_end_request(struct mg_host *host, int err, unsigned int nr_bytes)
+{
+ if (__blk_end_request(host->req, err, nr_bytes))
+ return true;
+
+ host->req = NULL;
+ return false;
+}
+
+static bool mg_end_request_cur(struct mg_host *host, int err)
+{
+ return mg_end_request(host, err, blk_rq_cur_bytes(host->req));
+}
+
static void mg_dump_status(const char *msg, unsigned int stat,
struct mg_host *host)
{
char *name = MG_DISK_NAME;
- struct request *req;
- if (host->breq) {
- req = elv_next_request(host->breq);
- if (req)
- name = req->rq_disk->disk_name;
- }
+ if (host->req)
+ name = host->req->rq_disk->disk_name;
printk(KERN_ERR "%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
- if (stat & MG_REG_STATUS_BIT_BUSY)
+ if (stat & ATA_BUSY)
printk("Busy ");
- if (stat & MG_REG_STATUS_BIT_READY)
+ if (stat & ATA_DRDY)
printk("DriveReady ");
- if (stat & MG_REG_STATUS_BIT_WRITE_FAULT)
+ if (stat & ATA_DF)
printk("WriteFault ");
- if (stat & MG_REG_STATUS_BIT_SEEK_DONE)
+ if (stat & ATA_DSC)
printk("SeekComplete ");
- if (stat & MG_REG_STATUS_BIT_DATA_REQ)
+ if (stat & ATA_DRQ)
printk("DataRequest ");
- if (stat & MG_REG_STATUS_BIT_CORRECTED_ERROR)
+ if (stat & ATA_CORR)
printk("CorrectedError ");
- if (stat & MG_REG_STATUS_BIT_ERROR)
+ if (stat & ATA_ERR)
printk("Error ");
printk("}\n");
- if ((stat & MG_REG_STATUS_BIT_ERROR) == 0) {
+ if ((stat & ATA_ERR) == 0) {
host->error = 0;
} else {
host->error = inb((unsigned long)host->dev_base + MG_REG_ERROR);
printk(KERN_ERR "%s: %s: error=0x%02x { ", name, msg,
host->error & 0xff);
- if (host->error & MG_REG_ERR_BBK)
+ if (host->error & ATA_BBK)
printk("BadSector ");
- if (host->error & MG_REG_ERR_UNC)
+ if (host->error & ATA_UNC)
printk("UncorrectableError ");
- if (host->error & MG_REG_ERR_IDNF)
+ if (host->error & ATA_IDNF)
printk("SectorIdNotFound ");
- if (host->error & MG_REG_ERR_ABRT)
+ if (host->error & ATA_ABORTED)
printk("DriveStatusError ");
- if (host->error & MG_REG_ERR_AMNF)
+ if (host->error & ATA_AMNF)
printk("AddrMarkNotFound ");
printk("}");
- if (host->error &
- (MG_REG_ERR_BBK | MG_REG_ERR_UNC |
- MG_REG_ERR_IDNF | MG_REG_ERR_AMNF)) {
- if (host->breq) {
- req = elv_next_request(host->breq);
- if (req)
- printk(", sector=%u", (u32)req->sector);
- }
-
+ if (host->error & (ATA_BBK | ATA_UNC | ATA_IDNF | ATA_AMNF)) {
+ if (host->req)
+ printk(", sector=%u",
+ (unsigned int)blk_rq_pos(host->req));
}
printk("\n");
}
@@ -100,12 +249,12 @@ static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec)
do {
cur_jiffies = jiffies;
- if (status & MG_REG_STATUS_BIT_BUSY) {
- if (expect == MG_REG_STATUS_BIT_BUSY)
+ if (status & ATA_BUSY) {
+ if (expect == ATA_BUSY)
break;
} else {
/* Check the error condition! */
- if (status & MG_REG_STATUS_BIT_ERROR) {
+ if (status & ATA_ERR) {
mg_dump_status("mg_wait", status, host);
break;
}
@@ -114,8 +263,8 @@ static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec)
if (MG_READY_OK(status))
break;
- if (expect == MG_REG_STATUS_BIT_DATA_REQ)
- if (status & MG_REG_STATUS_BIT_DATA_REQ)
+ if (expect == ATA_DRQ)
+ if (status & ATA_DRQ)
break;
}
if (!msec) {
@@ -173,6 +322,42 @@ static irqreturn_t mg_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+/* local copy of ata_id_string() */
+static void mg_id_string(const u16 *id, unsigned char *s,
+ unsigned int ofs, unsigned int len)
+{
+ unsigned int c;
+
+ BUG_ON(len & 1);
+
+ while (len > 0) {
+ c = id[ofs] >> 8;
+ *s = c;
+ s++;
+
+ c = id[ofs] & 0xff;
+ *s = c;
+ s++;
+
+ ofs++;
+ len -= 2;
+ }
+}
+
+/* local copy of ata_id_c_string() */
+static void mg_id_c_string(const u16 *id, unsigned char *s,
+ unsigned int ofs, unsigned int len)
+{
+ unsigned char *p;
+
+ mg_id_string(id, s, ofs, len - 1);
+
+ p = s + strnlen(s, len - 1);
+ while (p > s && p[-1] == ' ')
+ p--;
+ *p = '\0';
+}
+
static int mg_get_disk_id(struct mg_host *host)
{
u32 i;
@@ -184,12 +369,10 @@ static int mg_get_disk_id(struct mg_host *host)
char serial[ATA_ID_SERNO_LEN + 1];
if (!prv_data->use_polling)
- outb(MG_REG_CTRL_INTR_DISABLE,
- (unsigned long)host->dev_base +
- MG_REG_DRV_CTRL);
+ outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
outb(MG_CMD_ID, (unsigned long)host->dev_base + MG_REG_COMMAND);
- err = mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, MG_TMAX_WAIT_RD_DRQ);
+ err = mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_RD_DRQ);
if (err)
return err;
@@ -219,9 +402,9 @@ static int mg_get_disk_id(struct mg_host *host)
host->n_sectors -= host->nres_sectors;
}
- ata_id_c_string(id, fwrev, ATA_ID_FW_REV, sizeof(fwrev));
- ata_id_c_string(id, model, ATA_ID_PROD, sizeof(model));
- ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
+ mg_id_c_string(id, fwrev, ATA_ID_FW_REV, sizeof(fwrev));
+ mg_id_c_string(id, model, ATA_ID_PROD, sizeof(model));
+ mg_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
printk(KERN_INFO "mg_disk: model: %s\n", model);
printk(KERN_INFO "mg_disk: firm: %.8s\n", fwrev);
printk(KERN_INFO "mg_disk: serial: %s\n", serial);
@@ -229,8 +412,7 @@ static int mg_get_disk_id(struct mg_host *host)
host->n_sectors, host->nres_sectors);
if (!prv_data->use_polling)
- outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base +
- MG_REG_DRV_CTRL);
+ outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
return err;
}
@@ -244,7 +426,7 @@ static int mg_disk_init(struct mg_host *host)
/* hdd rst low */
gpio_set_value(host->rst, 0);
- err = mg_wait(host, MG_REG_STATUS_BIT_BUSY, MG_TMAX_RST_TO_BUSY);
+ err = mg_wait(host, ATA_BUSY, MG_TMAX_RST_TO_BUSY);
if (err)
return err;
@@ -255,17 +437,14 @@ static int mg_disk_init(struct mg_host *host)
return err;
/* soft reset on */
- outb(MG_REG_CTRL_RESET |
- (prv_data->use_polling ? MG_REG_CTRL_INTR_DISABLE :
- MG_REG_CTRL_INTR_ENABLE),
+ outb(ATA_SRST | (prv_data->use_polling ? ATA_NIEN : 0),
(unsigned long)host->dev_base + MG_REG_DRV_CTRL);
- err = mg_wait(host, MG_REG_STATUS_BIT_BUSY, MG_TMAX_RST_TO_BUSY);
+ err = mg_wait(host, ATA_BUSY, MG_TMAX_RST_TO_BUSY);
if (err)
return err;
/* soft reset off */
- outb(prv_data->use_polling ? MG_REG_CTRL_INTR_DISABLE :
- MG_REG_CTRL_INTR_ENABLE,
+ outb(prv_data->use_polling ? ATA_NIEN : 0,
(unsigned long)host->dev_base + MG_REG_DRV_CTRL);
err = mg_wait(host, MG_STAT_READY, MG_TMAX_SWRST_TO_RDY);
if (err)
@@ -281,11 +460,10 @@ static int mg_disk_init(struct mg_host *host)
static void mg_bad_rw_intr(struct mg_host *host)
{
- struct request *req = elv_next_request(host->breq);
- if (req != NULL)
- if (++req->errors >= MG_MAX_ERRORS ||
- host->error == MG_ERR_TIMEOUT)
- end_request(req, 0);
+ if (host->req)
+ if (++host->req->errors >= MG_MAX_ERRORS ||
+ host->error == MG_ERR_TIMEOUT)
+ mg_end_request_cur(host, -EIO);
}
static unsigned int mg_out(struct mg_host *host,
@@ -311,7 +489,7 @@ static unsigned int mg_out(struct mg_host *host,
MG_REG_CYL_LOW);
outb((u8)(sect_num >> 16), (unsigned long)host->dev_base +
MG_REG_CYL_HIGH);
- outb((u8)((sect_num >> 24) | MG_REG_HEAD_LBA_MODE),
+ outb((u8)((sect_num >> 24) | ATA_LBA | ATA_DEVICE_OBS),
(unsigned long)host->dev_base + MG_REG_DRV_HEAD);
outb(cmd, (unsigned long)host->dev_base + MG_REG_COMMAND);
return MG_ERR_NONE;
@@ -319,105 +497,77 @@ static unsigned int mg_out(struct mg_host *host,
static void mg_read(struct request *req)
{
- u32 remains, j;
+ u32 j;
struct mg_host *host = req->rq_disk->private_data;
- remains = req->nr_sectors;
-
- if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, NULL) !=
- MG_ERR_NONE)
+ if (mg_out(host, blk_rq_pos(req), blk_rq_sectors(req),
+ MG_CMD_RD, NULL) != MG_ERR_NONE)
mg_bad_rw_intr(host);
MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
- remains, req->sector, req->buffer);
+ blk_rq_sectors(req), blk_rq_pos(req), req->buffer);
+
+ do {
+ u16 *buff = (u16 *)req->buffer;
- while (remains) {
- if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
- MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) {
+ if (mg_wait(host, ATA_DRQ,
+ MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) {
mg_bad_rw_intr(host);
return;
}
- for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
- *(u16 *)req->buffer =
- inw((unsigned long)host->dev_base +
- MG_BUFF_OFFSET + (j << 1));
- req->buffer += 2;
- }
-
- req->sector++;
- req->errors = 0;
- remains = --req->nr_sectors;
- --req->current_nr_sectors;
-
- if (req->current_nr_sectors <= 0) {
- MG_DBG("remain : %d sects\n", remains);
- end_request(req, 1);
- if (remains > 0)
- req = elv_next_request(host->breq);
- }
+ for (j = 0; j < MG_SECTOR_SIZE >> 1; j++)
+ *buff++ = inw((unsigned long)host->dev_base +
+ MG_BUFF_OFFSET + (j << 1));
outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base +
MG_REG_COMMAND);
- }
+ } while (mg_end_request(host, 0, MG_SECTOR_SIZE));
}
static void mg_write(struct request *req)
{
- u32 remains, j;
+ u32 j;
struct mg_host *host = req->rq_disk->private_data;
- remains = req->nr_sectors;
-
- if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, NULL) !=
- MG_ERR_NONE) {
+ if (mg_out(host, blk_rq_pos(req), blk_rq_sectors(req),
+ MG_CMD_WR, NULL) != MG_ERR_NONE) {
mg_bad_rw_intr(host);
return;
}
-
MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
- remains, req->sector, req->buffer);
- while (remains) {
- if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
- MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
+ blk_rq_sectors(req), blk_rq_pos(req), req->buffer);
+
+ do {
+ u16 *buff = (u16 *)req->buffer;
+
+ if (mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
mg_bad_rw_intr(host);
return;
}
- for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
- outw(*(u16 *)req->buffer,
- (unsigned long)host->dev_base +
- MG_BUFF_OFFSET + (j << 1));
- req->buffer += 2;
- }
- req->sector++;
- remains = --req->nr_sectors;
- --req->current_nr_sectors;
-
- if (req->current_nr_sectors <= 0) {
- MG_DBG("remain : %d sects\n", remains);
- end_request(req, 1);
- if (remains > 0)
- req = elv_next_request(host->breq);
- }
+ for (j = 0; j < MG_SECTOR_SIZE >> 1; j++)
+ outw(*buff++, (unsigned long)host->dev_base +
+ MG_BUFF_OFFSET + (j << 1));
outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
MG_REG_COMMAND);
- }
+ } while (mg_end_request(host, 0, MG_SECTOR_SIZE));
}
static void mg_read_intr(struct mg_host *host)
{
+ struct request *req = host->req;
u32 i;
- struct request *req;
+ u16 *buff;
/* check status */
do {
i = inb((unsigned long)host->dev_base + MG_REG_STATUS);
- if (i & MG_REG_STATUS_BIT_BUSY)
+ if (i & ATA_BUSY)
break;
if (!MG_READY_OK(i))
break;
- if (i & MG_REG_STATUS_BIT_DATA_REQ)
+ if (i & ATA_DRQ)
goto ok_to_read;
} while (0);
mg_dump_status("mg_read_intr", i, host);
@@ -427,60 +577,42 @@ static void mg_read_intr(struct mg_host *host)
ok_to_read:
/* get current segment of request */
- req = elv_next_request(host->breq);
+ buff = (u16 *)req->buffer;
/* read 1 sector */
- for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) {
- *(u16 *)req->buffer =
- inw((unsigned long)host->dev_base + MG_BUFF_OFFSET +
- (i << 1));
- req->buffer += 2;
- }
+ for (i = 0; i < MG_SECTOR_SIZE >> 1; i++)
+ *buff++ = inw((unsigned long)host->dev_base + MG_BUFF_OFFSET +
+ (i << 1));
- /* manipulate request */
MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
- req->sector, req->nr_sectors - 1, req->buffer);
-
- req->sector++;
- req->errors = 0;
- i = --req->nr_sectors;
- --req->current_nr_sectors;
-
- /* let know if current segment done */
- if (req->current_nr_sectors <= 0)
- end_request(req, 1);
-
- /* set handler if read remains */
- if (i > 0) {
- host->mg_do_intr = mg_read_intr;
- mod_timer(&host->timer, jiffies + 3 * HZ);
- }
+ blk_rq_pos(req), blk_rq_sectors(req) - 1, req->buffer);
/* send read confirm */
outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
- /* goto next request */
- if (!i)
+ if (mg_end_request(host, 0, MG_SECTOR_SIZE)) {
+ /* set handler if read remains */
+ host->mg_do_intr = mg_read_intr;
+ mod_timer(&host->timer, jiffies + 3 * HZ);
+ } else /* goto next request */
mg_request(host->breq);
}
static void mg_write_intr(struct mg_host *host)
{
+ struct request *req = host->req;
u32 i, j;
u16 *buff;
- struct request *req;
-
- /* get current segment of request */
- req = elv_next_request(host->breq);
+ bool rem;
/* check status */
do {
i = inb((unsigned long)host->dev_base + MG_REG_STATUS);
- if (i & MG_REG_STATUS_BIT_BUSY)
+ if (i & ATA_BUSY)
break;
if (!MG_READY_OK(i))
break;
- if ((req->nr_sectors <= 1) || (i & MG_REG_STATUS_BIT_DATA_REQ))
+ if ((blk_rq_sectors(req) <= 1) || (i & ATA_DRQ))
goto ok_to_write;
} while (0);
mg_dump_status("mg_write_intr", i, host);
@@ -489,18 +621,8 @@ static void mg_write_intr(struct mg_host *host)
return;
ok_to_write:
- /* manipulate request */
- req->sector++;
- i = --req->nr_sectors;
- --req->current_nr_sectors;
- req->buffer += MG_SECTOR_SIZE;
-
- /* let know if current segment or all done */
- if (!i || (req->bio && req->current_nr_sectors <= 0))
- end_request(req, 1);
-
- /* write 1 sector and set handler if remains */
- if (i > 0) {
+ if ((rem = mg_end_request(host, 0, MG_SECTOR_SIZE))) {
+ /* write 1 sector and set handler if remains */
buff = (u16 *)req->buffer;
for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) {
outw(*buff, (unsigned long)host->dev_base +
@@ -508,7 +630,7 @@ ok_to_write:
buff++;
}
MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
- req->sector, req->nr_sectors, req->buffer);
+ blk_rq_pos(req), blk_rq_sectors(req), req->buffer);
host->mg_do_intr = mg_write_intr;
mod_timer(&host->timer, jiffies + 3 * HZ);
}
@@ -516,7 +638,7 @@ ok_to_write:
/* send write confirm */
outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
- if (!i)
+ if (!rem)
mg_request(host->breq);
}
@@ -524,49 +646,45 @@ void mg_times_out(unsigned long data)
{
struct mg_host *host = (struct mg_host *)data;
char *name;
- struct request *req;
spin_lock_irq(&host->lock);
- req = elv_next_request(host->breq);
- if (!req)
+ if (!host->req)
goto out_unlock;
host->mg_do_intr = NULL;
- name = req->rq_disk->disk_name;
+ name = host->req->rq_disk->disk_name;
printk(KERN_DEBUG "%s: timeout\n", name);
host->error = MG_ERR_TIMEOUT;
mg_bad_rw_intr(host);
- mg_request(host->breq);
out_unlock:
+ mg_request(host->breq);
spin_unlock_irq(&host->lock);
}
static void mg_request_poll(struct request_queue *q)
{
- struct request *req;
- struct mg_host *host;
+ struct mg_host *host = q->queuedata;
- while ((req = elv_next_request(q)) != NULL) {
- host = req->rq_disk->private_data;
- if (blk_fs_request(req)) {
- switch (rq_data_dir(req)) {
- case READ:
- mg_read(req);
- break;
- case WRITE:
- mg_write(req);
- break;
- default:
- printk(KERN_WARNING "%s:%d unknown command\n",
- __func__, __LINE__);
- end_request(req, 0);
+ while (1) {
+ if (!host->req) {
+ host->req = blk_fetch_request(q);
+ if (!host->req)
break;
- }
}
+
+ if (unlikely(!blk_fs_request(host->req))) {
+ mg_end_request_cur(host, -EIO);
+ continue;
+ }
+
+ if (rq_data_dir(host->req) == READ)
+ mg_read(host->req);
+ else
+ mg_write(host->req);
}
}
@@ -588,18 +706,15 @@ static unsigned int mg_issue_req(struct request *req,
break;
case WRITE:
/* TODO : handler */
- outb(MG_REG_CTRL_INTR_DISABLE,
- (unsigned long)host->dev_base +
- MG_REG_DRV_CTRL);
+ outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
if (mg_out(host, sect_num, sect_cnt, MG_CMD_WR, &mg_write_intr)
!= MG_ERR_NONE) {
mg_bad_rw_intr(host);
return host->error;
}
del_timer(&host->timer);
- mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, MG_TMAX_WAIT_WR_DRQ);
- outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base +
- MG_REG_DRV_CTRL);
+ mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ);
+ outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
if (host->error) {
mg_bad_rw_intr(host);
return host->error;
@@ -614,11 +729,6 @@ static unsigned int mg_issue_req(struct request *req,
outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
MG_REG_COMMAND);
break;
- default:
- printk(KERN_WARNING "%s:%d unknown command\n",
- __func__, __LINE__);
- end_request(req, 0);
- break;
}
return MG_ERR_NONE;
}
@@ -626,16 +736,17 @@ static unsigned int mg_issue_req(struct request *req,
/* This function also called from IRQ context */
static void mg_request(struct request_queue *q)
{
+ struct mg_host *host = q->queuedata;
struct request *req;
- struct mg_host *host;
u32 sect_num, sect_cnt;
while (1) {
- req = elv_next_request(q);
- if (!req)
- return;
-
- host = req->rq_disk->private_data;
+ if (!host->req) {
+ host->req = blk_fetch_request(q);
+ if (!host->req)
+ break;
+ }
+ req = host->req;
/* check unwanted request call */
if (host->mg_do_intr)
@@ -643,9 +754,9 @@ static void mg_request(struct request_queue *q)
del_timer(&host->timer);
- sect_num = req->sector;
+ sect_num = blk_rq_pos(req);
/* deal whole segments */
- sect_cnt = req->nr_sectors;
+ sect_cnt = blk_rq_sectors(req);
/* sanity check */
if (sect_num >= get_capacity(req->rq_disk) ||
@@ -655,12 +766,14 @@ static void mg_request(struct request_queue *q)
"%s: bad access: sector=%d, count=%d\n",
req->rq_disk->disk_name,
sect_num, sect_cnt);
- end_request(req, 0);
+ mg_end_request_cur(host, -EIO);
continue;
}
- if (!blk_fs_request(req))
- return;
+ if (unlikely(!blk_fs_request(req))) {
+ mg_end_request_cur(host, -EIO);
+ continue;
+ }
if (!mg_issue_req(req, host, sect_num, sect_cnt))
return;
@@ -690,9 +803,7 @@ static int mg_suspend(struct platform_device *plat_dev, pm_message_t state)
return -EIO;
if (!prv_data->use_polling)
- outb(MG_REG_CTRL_INTR_DISABLE,
- (unsigned long)host->dev_base +
- MG_REG_DRV_CTRL);
+ outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
outb(MG_CMD_SLEEP, (unsigned long)host->dev_base + MG_REG_COMMAND);
/* wait until mflash deep sleep */
@@ -700,9 +811,7 @@ static int mg_suspend(struct platform_device *plat_dev, pm_message_t state)
if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) {
if (!prv_data->use_polling)
- outb(MG_REG_CTRL_INTR_ENABLE,
- (unsigned long)host->dev_base +
- MG_REG_DRV_CTRL);
+ outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
return -EIO;
}
@@ -725,8 +834,7 @@ static int mg_resume(struct platform_device *plat_dev)
return -EIO;
if (!prv_data->use_polling)
- outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base +
- MG_REG_DRV_CTRL);
+ outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
return 0;
}
@@ -877,6 +985,7 @@ static int mg_probe(struct platform_device *plat_dev)
__func__, __LINE__);
goto probe_err_5;
}
+ host->breq->queuedata = host;
/* mflash is random device, thanx for the noop */
elevator_exit(host->breq->elevator);
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 4d6de4f15ccb..5d23ffad7c77 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -110,7 +110,7 @@ static void nbd_end_request(struct request *req)
req, error ? "failed" : "done");
spin_lock_irqsave(q->queue_lock, flags);
- __blk_end_request(req, error, req->nr_sectors << 9);
+ __blk_end_request_all(req, error);
spin_unlock_irqrestore(q->queue_lock, flags);
}
@@ -231,19 +231,19 @@ 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;
+ unsigned long size = blk_rq_bytes(req);
request.magic = htonl(NBD_REQUEST_MAGIC);
request.type = htonl(nbd_cmd(req));
- request.from = cpu_to_be64((u64) req->sector << 9);
+ request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
request.len = htonl(size);
memcpy(request.handle, &req, sizeof(req));
- dprintk(DBG_TX, "%s: request %p: sending control (%s@%llu,%luB)\n",
+ dprintk(DBG_TX, "%s: request %p: sending control (%s@%llu,%uB)\n",
lo->disk->disk_name, req,
nbdcmd_to_ascii(nbd_cmd(req)),
- (unsigned long long)req->sector << 9,
- req->nr_sectors << 9);
+ (unsigned long long)blk_rq_pos(req) << 9,
+ blk_rq_bytes(req));
result = sock_xmit(lo, 1, &request, sizeof(request),
(nbd_cmd(req) == NBD_CMD_WRITE) ? MSG_MORE : 0);
if (result <= 0) {
@@ -533,11 +533,9 @@ static void do_nbd_request(struct request_queue *q)
{
struct request *req;
- while ((req = elv_next_request(q)) != NULL) {
+ while ((req = blk_fetch_request(q)) != NULL) {
struct nbd_device *lo;
- blkdev_dequeue_request(req);
-
spin_unlock_irq(q->queue_lock);
dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%x)\n",
@@ -580,13 +578,6 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo,
blk_rq_init(NULL, &sreq);
sreq.cmd_type = REQ_TYPE_SPECIAL;
nbd_cmd(&sreq) = NBD_CMD_DISC;
- /*
- * Set these to sane values in case server implementation
- * fails to check the request type first and also to keep
- * debugging output cleaner.
- */
- sreq.sector = 0;
- sreq.nr_sectors = 0;
if (!lo->sock)
return -EINVAL;
nbd_send_req(lo, &sreq);
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index e91d4b4b014f..911dfd98d813 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -719,32 +719,37 @@ static void do_pcd_request(struct request_queue * q)
if (pcd_busy)
return;
while (1) {
- pcd_req = elv_next_request(q);
- if (!pcd_req)
- return;
+ if (!pcd_req) {
+ pcd_req = blk_fetch_request(q);
+ if (!pcd_req)
+ return;
+ }
if (rq_data_dir(pcd_req) == READ) {
struct pcd_unit *cd = pcd_req->rq_disk->private_data;
if (cd != pcd_current)
pcd_bufblk = -1;
pcd_current = cd;
- pcd_sector = pcd_req->sector;
- pcd_count = pcd_req->current_nr_sectors;
+ pcd_sector = blk_rq_pos(pcd_req);
+ pcd_count = blk_rq_cur_sectors(pcd_req);
pcd_buf = pcd_req->buffer;
pcd_busy = 1;
ps_set_intr(do_pcd_read, NULL, 0, nice);
return;
- } else
- end_request(pcd_req, 0);
+ } else {
+ __blk_end_request_all(pcd_req, -EIO);
+ pcd_req = NULL;
+ }
}
}
-static inline void next_request(int success)
+static inline void next_request(int err)
{
unsigned long saved_flags;
spin_lock_irqsave(&pcd_lock, saved_flags);
- end_request(pcd_req, success);
+ if (!__blk_end_request_cur(pcd_req, err))
+ pcd_req = NULL;
pcd_busy = 0;
do_pcd_request(pcd_queue);
spin_unlock_irqrestore(&pcd_lock, saved_flags);
@@ -781,7 +786,7 @@ static void pcd_start(void)
if (pcd_command(pcd_current, rd_cmd, 2048, "read block")) {
pcd_bufblk = -1;
- next_request(0);
+ next_request(-EIO);
return;
}
@@ -796,7 +801,7 @@ static void do_pcd_read(void)
pcd_retries = 0;
pcd_transfer();
if (!pcd_count) {
- next_request(1);
+ next_request(0);
return;
}
@@ -815,7 +820,7 @@ static void do_pcd_read_drq(void)
return;
}
pcd_bufblk = -1;
- next_request(0);
+ next_request(-EIO);
return;
}
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 9299455b0af6..bf5955b3d873 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -410,10 +410,12 @@ static void run_fsm(void)
pd_claimed = 0;
phase = NULL;
spin_lock_irqsave(&pd_lock, saved_flags);
- end_request(pd_req, res);
- pd_req = elv_next_request(pd_queue);
- if (!pd_req)
- stop = 1;
+ if (!__blk_end_request_cur(pd_req,
+ res == Ok ? 0 : -EIO)) {
+ pd_req = blk_fetch_request(pd_queue);
+ if (!pd_req)
+ stop = 1;
+ }
spin_unlock_irqrestore(&pd_lock, saved_flags);
if (stop)
return;
@@ -443,11 +445,11 @@ static enum action do_pd_io_start(void)
pd_cmd = rq_data_dir(pd_req);
if (pd_cmd == READ || pd_cmd == WRITE) {
- pd_block = pd_req->sector;
- pd_count = pd_req->current_nr_sectors;
+ pd_block = blk_rq_pos(pd_req);
+ pd_count = blk_rq_cur_sectors(pd_req);
if (pd_block + pd_count > get_capacity(pd_req->rq_disk))
return Fail;
- pd_run = pd_req->nr_sectors;
+ pd_run = blk_rq_sectors(pd_req);
pd_buf = pd_req->buffer;
pd_retries = 0;
if (pd_cmd == READ)
@@ -477,8 +479,8 @@ static int pd_next_buf(void)
if (pd_count)
return 0;
spin_lock_irqsave(&pd_lock, saved_flags);
- end_request(pd_req, 1);
- pd_count = pd_req->current_nr_sectors;
+ __blk_end_request_cur(pd_req, 0);
+ pd_count = blk_rq_cur_sectors(pd_req);
pd_buf = pd_req->buffer;
spin_unlock_irqrestore(&pd_lock, saved_flags);
return 0;
@@ -702,7 +704,7 @@ static void do_pd_request(struct request_queue * q)
{
if (pd_req)
return;
- pd_req = elv_next_request(q);
+ pd_req = blk_fetch_request(q);
if (!pd_req)
return;
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index bef3b997ba3e..68a90834e993 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -750,12 +750,10 @@ static int pf_ready(void)
static struct request_queue *pf_queue;
-static void pf_end_request(int uptodate)
+static void pf_end_request(int err)
{
- if (pf_req) {
- end_request(pf_req, uptodate);
+ if (pf_req && !__blk_end_request_cur(pf_req, err))
pf_req = NULL;
- }
}
static void do_pf_request(struct request_queue * q)
@@ -763,17 +761,19 @@ static void do_pf_request(struct request_queue * q)
if (pf_busy)
return;
repeat:
- pf_req = elv_next_request(q);
- if (!pf_req)
- return;
+ if (!pf_req) {
+ pf_req = blk_fetch_request(q);
+ if (!pf_req)
+ return;
+ }
pf_current = pf_req->rq_disk->private_data;
- pf_block = pf_req->sector;
- pf_run = pf_req->nr_sectors;
- pf_count = pf_req->current_nr_sectors;
+ pf_block = blk_rq_pos(pf_req);
+ pf_run = blk_rq_sectors(pf_req);
+ pf_count = blk_rq_cur_sectors(pf_req);
if (pf_block + pf_count > get_capacity(pf_req->rq_disk)) {
- pf_end_request(0);
+ pf_end_request(-EIO);
goto repeat;
}
@@ -788,7 +788,7 @@ repeat:
pi_do_claimed(pf_current->pi, do_pf_write);
else {
pf_busy = 0;
- pf_end_request(0);
+ pf_end_request(-EIO);
goto repeat;
}
}
@@ -805,23 +805,22 @@ static int pf_next_buf(void)
return 1;
if (!pf_count) {
spin_lock_irqsave(&pf_spin_lock, saved_flags);
- pf_end_request(1);
- pf_req = elv_next_request(pf_queue);
+ pf_end_request(0);
spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
if (!pf_req)
return 1;
- pf_count = pf_req->current_nr_sectors;
+ pf_count = blk_rq_cur_sectors(pf_req);
pf_buf = pf_req->buffer;
}
return 0;
}
-static inline void next_request(int success)
+static inline void next_request(int err)
{
unsigned long saved_flags;
spin_lock_irqsave(&pf_spin_lock, saved_flags);
- pf_end_request(success);
+ pf_end_request(err);
pf_busy = 0;
do_pf_request(pf_queue);
spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
@@ -844,7 +843,7 @@ static void do_pf_read_start(void)
pi_do_claimed(pf_current->pi, do_pf_read_start);
return;
}
- next_request(0);
+ next_request(-EIO);
return;
}
pf_mask = STAT_DRQ;
@@ -863,7 +862,7 @@ static void do_pf_read_drq(void)
pi_do_claimed(pf_current->pi, do_pf_read_start);
return;
}
- next_request(0);
+ next_request(-EIO);
return;
}
pi_read_block(pf_current->pi, pf_buf, 512);
@@ -871,7 +870,7 @@ static void do_pf_read_drq(void)
break;
}
pi_disconnect(pf_current->pi);
- next_request(1);
+ next_request(0);
}
static void do_pf_write(void)
@@ -890,7 +889,7 @@ static void do_pf_write_start(void)
pi_do_claimed(pf_current->pi, do_pf_write_start);
return;
}
- next_request(0);
+ next_request(-EIO);
return;
}
@@ -903,7 +902,7 @@ static void do_pf_write_start(void)
pi_do_claimed(pf_current->pi, do_pf_write_start);
return;
}
- next_request(0);
+ next_request(-EIO);
return;
}
pi_write_block(pf_current->pi, pf_buf, 512);
@@ -923,11 +922,11 @@ static void do_pf_write_done(void)
pi_do_claimed(pf_current->pi, do_pf_write_start);
return;
}
- next_request(0);
+ next_request(-EIO);
return;
}
pi_disconnect(pf_current->pi);
- next_request(1);
+ next_request(0);
}
static int __init pf_init(void)
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index bccc42bb9212..338cee4cc0ba 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -134,13 +134,12 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
rq_for_each_segment(bv, req, iter)
n++;
dev_dbg(&dev->sbd.core,
- "%s:%u: %s req has %u bvecs for %lu sectors %lu hard sectors\n",
- __func__, __LINE__, op, n, req->nr_sectors,
- req->hard_nr_sectors);
+ "%s:%u: %s req has %u bvecs for %u sectors\n",
+ __func__, __LINE__, op, n, blk_rq_sectors(req));
#endif
- start_sector = req->sector * priv->blocking_factor;
- sectors = req->nr_sectors * priv->blocking_factor;
+ start_sector = blk_rq_pos(req) * priv->blocking_factor;
+ sectors = blk_rq_sectors(req) * priv->blocking_factor;
dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n",
__func__, __LINE__, op, sectors, start_sector);
@@ -158,7 +157,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
if (res) {
dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
__LINE__, op, res);
- end_request(req, 0);
+ __blk_end_request_all(req, -EIO);
return 0;
}
@@ -180,7 +179,7 @@ static int ps3disk_submit_flush_request(struct ps3_storage_device *dev,
if (res) {
dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n",
__func__, __LINE__, res);
- end_request(req, 0);
+ __blk_end_request_all(req, -EIO);
return 0;
}
@@ -195,7 +194,7 @@ static void ps3disk_do_request(struct ps3_storage_device *dev,
dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
- while ((req = elv_next_request(q))) {
+ while ((req = blk_fetch_request(q))) {
if (blk_fs_request(req)) {
if (ps3disk_submit_request_sg(dev, req))
break;
@@ -205,7 +204,7 @@ static void ps3disk_do_request(struct ps3_storage_device *dev,
break;
} else {
blk_dump_rq_flags(req, DEVICE_NAME " bad request");
- end_request(req, 0);
+ __blk_end_request_all(req, -EIO);
continue;
}
}
@@ -231,7 +230,6 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
struct request *req;
int res, read, error;
u64 tag, status;
- unsigned long num_sectors;
const char *op;
res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
@@ -261,11 +259,9 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
req->cmd[0] == REQ_LB_OP_FLUSH) {
read = 0;
- num_sectors = req->hard_cur_sectors;
op = "flush";
} else {
read = !rq_data_dir(req);
- num_sectors = req->nr_sectors;
op = read ? "read" : "write";
}
if (status) {
@@ -281,7 +277,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
}
spin_lock(&priv->lock);
- __blk_end_request(req, error, num_sectors << 9);
+ __blk_end_request_all(req, error);
priv->req = NULL;
ps3disk_do_request(dev, priv->queue);
spin_unlock(&priv->lock);
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 5861e33efe63..cbfd9c0aef03 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -212,11 +212,6 @@ static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc)
vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD);
}
-static void vdc_end_request(struct request *req, int error, int num_sectors)
-{
- __blk_end_request(req, error, num_sectors << 9);
-}
-
static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
unsigned int index)
{
@@ -239,7 +234,7 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
rqe->req = NULL;
- vdc_end_request(req, (desc->status ? -EIO : 0), desc->size >> 9);
+ __blk_end_request(req, (desc->status ? -EIO : 0), desc->size);
if (blk_queue_stopped(port->disk->queue))
blk_start_queue(port->disk->queue);
@@ -421,7 +416,7 @@ static int __send_request(struct request *req)
desc->slice = 0;
}
desc->status = ~0;
- desc->offset = (req->sector << 9) / port->vdisk_block_size;
+ desc->offset = (blk_rq_pos(req) << 9) / port->vdisk_block_size;
desc->size = len;
desc->ncookies = err;
@@ -446,14 +441,13 @@ out:
static void do_vdc_request(struct request_queue *q)
{
while (1) {
- struct request *req = elv_next_request(q);
+ struct request *req = blk_fetch_request(q);
if (!req)
break;
- blkdev_dequeue_request(req);
if (__send_request(req) < 0)
- vdc_end_request(req, -EIO, req->hard_nr_sectors);
+ __blk_end_request_all(req, -EIO);
}
}
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index d22cc3856937..cf7877fb8a7d 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -514,7 +514,7 @@ static int floppy_read_sectors(struct floppy_state *fs,
ret = swim_read_sector(fs, side, track, sector,
buffer);
if (try-- == 0)
- return -1;
+ return -EIO;
} while (ret != 512);
buffer += ret;
@@ -528,45 +528,31 @@ static void redo_fd_request(struct request_queue *q)
struct request *req;
struct floppy_state *fs;
- while ((req = elv_next_request(q))) {
+ req = blk_fetch_request(q);
+ while (req) {
+ int err = -EIO;
fs = req->rq_disk->private_data;
- if (req->sector < 0 || req->sector >= fs->total_secs) {
- end_request(req, 0);
- continue;
- }
- if (req->current_nr_sectors == 0) {
- end_request(req, 1);
- continue;
- }
- if (!fs->disk_in) {
- end_request(req, 0);
- continue;
- }
- if (rq_data_dir(req) == WRITE) {
- if (fs->write_protected) {
- end_request(req, 0);
- continue;
- }
- }
+ if (blk_rq_pos(req) >= fs->total_secs)
+ goto done;
+ if (!fs->disk_in)
+ goto done;
+ if (rq_data_dir(req) == WRITE && fs->write_protected)
+ goto done;
+
switch (rq_data_dir(req)) {
case WRITE:
/* NOT IMPLEMENTED */
- end_request(req, 0);
break;
case READ:
- if (floppy_read_sectors(fs, req->sector,
- req->current_nr_sectors,
- req->buffer)) {
- end_request(req, 0);
- continue;
- }
- req->nr_sectors -= req->current_nr_sectors;
- req->sector += req->current_nr_sectors;
- req->buffer += req->current_nr_sectors * 512;
- end_request(req, 1);
+ err = floppy_read_sectors(fs, blk_rq_pos(req),
+ blk_rq_cur_sectors(req),
+ req->buffer);
break;
}
+ done:
+ if (!__blk_end_request_cur(req, err))
+ req = blk_fetch_request(q);
}
}
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index 612965307ba0..80df93e3cdd0 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -251,6 +251,20 @@ static int floppy_release(struct gendisk *disk, fmode_t mode);
static int floppy_check_change(struct gendisk *disk);
static int floppy_revalidate(struct gendisk *disk);
+static bool swim3_end_request(int err, unsigned int nr_bytes)
+{
+ if (__blk_end_request(fd_req, err, nr_bytes))
+ return true;
+
+ fd_req = NULL;
+ return false;
+}
+
+static bool swim3_end_request_cur(int err)
+{
+ return swim3_end_request(err, blk_rq_cur_bytes(fd_req));
+}
+
static void swim3_select(struct floppy_state *fs, int sel)
{
struct swim3 __iomem *sw = fs->swim3;
@@ -310,25 +324,27 @@ static void start_request(struct floppy_state *fs)
wake_up(&fs->wait);
return;
}
- while (fs->state == idle && (req = elv_next_request(swim3_queue))) {
+ while (fs->state == idle) {
+ if (!fd_req) {
+ fd_req = blk_fetch_request(swim3_queue);
+ if (!fd_req)
+ break;
+ }
+ req = fd_req;
#if 0
- printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n",
+ printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%u buf=%p\n",
req->rq_disk->disk_name, req->cmd,
- (long)req->sector, req->nr_sectors, req->buffer);
- printk(" errors=%d current_nr_sectors=%ld\n",
- req->errors, req->current_nr_sectors);
+ (long)blk_rq_pos(req), blk_rq_sectors(req), req->buffer);
+ printk(" errors=%d current_nr_sectors=%u\n",
+ req->errors, blk_rq_cur_sectors(req));
#endif
- if (req->sector < 0 || req->sector >= fs->total_secs) {
- end_request(req, 0);
- continue;
- }
- if (req->current_nr_sectors == 0) {
- end_request(req, 1);
+ if (blk_rq_pos(req) >= fs->total_secs) {
+ swim3_end_request_cur(-EIO);
continue;
}
if (fs->ejected) {
- end_request(req, 0);
+ swim3_end_request_cur(-EIO);
continue;
}
@@ -336,18 +352,19 @@ static void start_request(struct floppy_state *fs)
if (fs->write_prot < 0)
fs->write_prot = swim3_readbit(fs, WRITE_PROT);
if (fs->write_prot) {
- end_request(req, 0);
+ swim3_end_request_cur(-EIO);
continue;
}
}
- /* Do not remove the cast. req->sector is now a sector_t and
- * can be 64 bits, but it will never go past 32 bits for this
- * driver anyway, so we can safely cast it down and not have
- * to do a 64/32 division
+ /* Do not remove the cast. blk_rq_pos(req) is now a
+ * sector_t and can be 64 bits, but it will never go
+ * past 32 bits for this driver anyway, so we can
+ * safely cast it down and not have to do a 64/32
+ * division
*/
- fs->req_cyl = ((long)req->sector) / fs->secpercyl;
- x = ((long)req->sector) % fs->secpercyl;
+ fs->req_cyl = ((long)blk_rq_pos(req)) / fs->secpercyl;
+ x = ((long)blk_rq_pos(req)) % fs->secpercyl;
fs->head = x / fs->secpertrack;
fs->req_sector = x % fs->secpertrack + 1;
fd_req = req;
@@ -424,7 +441,7 @@ static inline void setup_transfer(struct floppy_state *fs)
struct dbdma_cmd *cp = fs->dma_cmd;
struct dbdma_regs __iomem *dr = fs->dma;
- if (fd_req->current_nr_sectors <= 0) {
+ if (blk_rq_cur_sectors(fd_req) <= 0) {
printk(KERN_ERR "swim3: transfer 0 sectors?\n");
return;
}
@@ -432,8 +449,8 @@ static inline void setup_transfer(struct floppy_state *fs)
n = 1;
else {
n = fs->secpertrack - fs->req_sector + 1;
- if (n > fd_req->current_nr_sectors)
- n = fd_req->current_nr_sectors;
+ if (n > blk_rq_cur_sectors(fd_req))
+ n = blk_rq_cur_sectors(fd_req);
}
fs->scount = n;
swim3_select(fs, fs->head? READ_DATA_1: READ_DATA_0);
@@ -508,7 +525,7 @@ static void act(struct floppy_state *fs)
case do_transfer:
if (fs->cur_cyl != fs->req_cyl) {
if (fs->retries > 5) {
- end_request(fd_req, 0);
+ swim3_end_request_cur(-EIO);
fs->state = idle;
return;
}
@@ -540,7 +557,7 @@ static void scan_timeout(unsigned long data)
out_8(&sw->intr_enable, 0);
fs->cur_cyl = -1;
if (fs->retries > 5) {
- end_request(fd_req, 0);
+ swim3_end_request_cur(-EIO);
fs->state = idle;
start_request(fs);
} else {
@@ -559,7 +576,7 @@ static void seek_timeout(unsigned long data)
out_8(&sw->select, RELAX);
out_8(&sw->intr_enable, 0);
printk(KERN_ERR "swim3: seek timeout\n");
- end_request(fd_req, 0);
+ swim3_end_request_cur(-EIO);
fs->state = idle;
start_request(fs);
}
@@ -583,7 +600,7 @@ static void settle_timeout(unsigned long data)
return;
}
printk(KERN_ERR "swim3: seek settle timeout\n");
- end_request(fd_req, 0);
+ swim3_end_request_cur(-EIO);
fs->state = idle;
start_request(fs);
}
@@ -593,8 +610,6 @@ static void xfer_timeout(unsigned long data)
struct floppy_state *fs = (struct floppy_state *) data;
struct swim3 __iomem *sw = fs->swim3;
struct dbdma_regs __iomem *dr = fs->dma;
- struct dbdma_cmd *cp = fs->dma_cmd;
- unsigned long s;
int n;
fs->timeout_pending = 0;
@@ -605,17 +620,10 @@ static void xfer_timeout(unsigned long data)
out_8(&sw->intr_enable, 0);
out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
out_8(&sw->select, RELAX);
- if (rq_data_dir(fd_req) == WRITE)
- ++cp;
- if (ld_le16(&cp->xfer_status) != 0)
- s = fs->scount - ((ld_le16(&cp->res_count) + 511) >> 9);
- else
- s = 0;
- fd_req->sector += s;
- fd_req->current_nr_sectors -= s;
printk(KERN_ERR "swim3: timeout %sing sector %ld\n",
- (rq_data_dir(fd_req)==WRITE? "writ": "read"), (long)fd_req->sector);
- end_request(fd_req, 0);
+ (rq_data_dir(fd_req)==WRITE? "writ": "read"),
+ (long)blk_rq_pos(fd_req));
+ swim3_end_request_cur(-EIO);
fs->state = idle;
start_request(fs);
}
@@ -646,7 +654,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
printk(KERN_ERR "swim3: seen sector but cyl=ff?\n");
fs->cur_cyl = -1;
if (fs->retries > 5) {
- end_request(fd_req, 0);
+ swim3_end_request_cur(-EIO);
fs->state = idle;
start_request(fs);
} else {
@@ -719,9 +727,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
if (intr & ERROR_INTR) {
n = fs->scount - 1 - resid / 512;
if (n > 0) {
- fd_req->sector += n;
- fd_req->current_nr_sectors -= n;
- fd_req->buffer += n * 512;
+ blk_update_request(fd_req, 0, n << 9);
fs->req_sector += n;
}
if (fs->retries < 5) {
@@ -730,8 +736,8 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
} else {
printk("swim3: error %sing block %ld (err=%x)\n",
rq_data_dir(fd_req) == WRITE? "writ": "read",
- (long)fd_req->sector, err);
- end_request(fd_req, 0);
+ (long)blk_rq_pos(fd_req), err);
+ swim3_end_request_cur(-EIO);
fs->state = idle;
}
} else {
@@ -740,18 +746,12 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid);
printk(KERN_ERR " state=%d, dir=%x, intr=%x, err=%x\n",
fs->state, rq_data_dir(fd_req), intr, err);
- end_request(fd_req, 0);
+ swim3_end_request_cur(-EIO);
fs->state = idle;
start_request(fs);
break;
}
- fd_req->sector += fs->scount;
- fd_req->current_nr_sectors -= fs->scount;
- fd_req->buffer += fs->scount * 512;
- if (fd_req->current_nr_sectors <= 0) {
- end_request(fd_req, 1);
- fs->state = idle;
- } else {
+ if (swim3_end_request(0, fs->scount << 9)) {
fs->req_sector += fs->scount;
if (fs->req_sector > fs->secpertrack) {
fs->req_sector -= fs->secpertrack;
@@ -761,7 +761,8 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
}
}
act(fs);
- }
+ } else
+ fs->state = idle;
}
if (fs->state == idle)
start_request(fs);
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index ff0448e4bf03..da403b6a7f43 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -749,8 +749,7 @@ static inline void carm_end_request_queued(struct carm_host *host,
struct request *req = crq->rq;
int rc;
- rc = __blk_end_request(req, error, blk_rq_bytes(req));
- assert(rc == 0);
+ __blk_end_request_all(req, error);
rc = carm_put_request(host, crq);
assert(rc == 0);
@@ -811,12 +810,10 @@ static void carm_oob_rq_fn(struct request_queue *q)
while (1) {
DPRINTK("get req\n");
- rq = elv_next_request(q);
+ rq = blk_fetch_request(q);
if (!rq)
break;
- blkdev_dequeue_request(rq);
-
crq = rq->special;
assert(crq != NULL);
assert(crq->rq == rq);
@@ -847,7 +844,7 @@ static void carm_rq_fn(struct request_queue *q)
queue_one_request:
VPRINTK("get req\n");
- rq = elv_next_request(q);
+ rq = blk_peek_request(q);
if (!rq)
return;
@@ -858,7 +855,7 @@ queue_one_request:
}
crq->rq = rq;
- blkdev_dequeue_request(rq);
+ blk_start_request(rq);
if (rq_data_dir(rq) == WRITE) {
writing = 1;
@@ -904,10 +901,10 @@ queue_one_request:
msg->sg_count = n_elem;
msg->sg_type = SGT_32BIT;
msg->handle = cpu_to_le32(TAG_ENCODE(crq->tag));
- msg->lba = cpu_to_le32(rq->sector & 0xffffffff);
- tmp = (rq->sector >> 16) >> 16;
+ msg->lba = cpu_to_le32(blk_rq_pos(rq) & 0xffffffff);
+ tmp = (blk_rq_pos(rq) >> 16) >> 16;
msg->lba_high = cpu_to_le16( (u16) tmp );
- msg->lba_count = cpu_to_le16(rq->nr_sectors);
+ msg->lba_count = cpu_to_le16(blk_rq_sectors(rq));
msg_size = sizeof(struct carm_msg_rw) - sizeof(msg->sg);
for (i = 0; i < n_elem; i++) {
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 689cd27ac890..178f459a50ed 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -627,7 +627,7 @@ static void ub_request_fn(struct request_queue *q)
struct ub_lun *lun = q->queuedata;
struct request *rq;
- while ((rq = elv_next_request(q)) != NULL) {
+ while ((rq = blk_peek_request(q)) != NULL) {
if (ub_request_fn_1(lun, rq) != 0) {
blk_stop_queue(q);
break;
@@ -643,13 +643,13 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
int n_elem;
if (atomic_read(&sc->poison)) {
- blkdev_dequeue_request(rq);
+ blk_start_request(rq);
ub_end_rq(rq, DID_NO_CONNECT << 16, blk_rq_bytes(rq));
return 0;
}
if (lun->changed && !blk_pc_request(rq)) {
- blkdev_dequeue_request(rq);
+ blk_start_request(rq);
ub_end_rq(rq, SAM_STAT_CHECK_CONDITION, blk_rq_bytes(rq));
return 0;
}
@@ -660,7 +660,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
return -1;
memset(cmd, 0, sizeof(struct ub_scsi_cmd));
- blkdev_dequeue_request(rq);
+ blk_start_request(rq);
urq = &lun->urq;
memset(urq, 0, sizeof(struct ub_request));
@@ -726,8 +726,8 @@ static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
* The call to blk_queue_hardsect_size() guarantees that request
* is aligned, but it is given in terms of 512 byte units, always.
*/
- block = rq->sector >> lun->capacity.bshift;
- nblks = rq->nr_sectors >> lun->capacity.bshift;
+ block = blk_rq_pos(rq) >> lun->capacity.bshift;
+ nblks = blk_rq_sectors(rq) >> lun->capacity.bshift;
cmd->cdb[0] = (cmd->dir == UB_DIR_READ)? READ_10: WRITE_10;
/* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */
@@ -739,7 +739,7 @@ static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
cmd->cdb[8] = nblks;
cmd->cdb_len = 10;
- cmd->len = rq->nr_sectors * 512;
+ cmd->len = blk_rq_bytes(rq);
}
static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
@@ -747,7 +747,7 @@ static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
{
struct request *rq = urq->rq;
- if (rq->data_len == 0) {
+ if (blk_rq_bytes(rq) == 0) {
cmd->dir = UB_DIR_NONE;
} else {
if (rq_data_dir(rq) == WRITE)
@@ -762,7 +762,7 @@ static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
cmd->cdb_len = rq->cmd_len;
- cmd->len = rq->data_len;
+ cmd->len = blk_rq_bytes(rq);
/*
* To reapply this to every URB is not as incorrect as it looks.
@@ -783,10 +783,8 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
if (cmd->error == 0) {
if (blk_pc_request(rq)) {
- if (cmd->act_len >= rq->data_len)
- rq->data_len = 0;
- else
- rq->data_len -= cmd->act_len;
+ if (cmd->act_len < blk_rq_bytes(rq))
+ rq->resid_len = blk_rq_bytes(rq) - cmd->act_len;
scsi_status = 0;
} else {
if (cmd->act_len != cmd->len) {
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index ecccf65dce2f..390d69bb7c48 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -252,7 +252,7 @@ static int send_request(struct request *req)
struct viodasd_device *d;
unsigned long flags;
- start = (u64)req->sector << 9;
+ start = (u64)blk_rq_pos(req) << 9;
if (rq_data_dir(req) == READ) {
direction = DMA_FROM_DEVICE;
@@ -361,19 +361,17 @@ static void do_viodasd_request(struct request_queue *q)
* back later.
*/
while (num_req_outstanding < VIOMAXREQ) {
- req = elv_next_request(q);
+ req = blk_fetch_request(q);
if (req == NULL)
return;
- /* dequeue the current request from the queue */
- blkdev_dequeue_request(req);
/* check that request contains a valid command */
if (!blk_fs_request(req)) {
- viodasd_end_request(req, -EIO, req->hard_nr_sectors);
+ viodasd_end_request(req, -EIO, blk_rq_sectors(req));
continue;
}
/* Try sending the request */
if (send_request(req) != 0)
- viodasd_end_request(req, -EIO, req->hard_nr_sectors);
+ viodasd_end_request(req, -EIO, blk_rq_sectors(req));
}
}
@@ -590,7 +588,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent)
err = vio_lookup_rc(viodasd_err_table, bevent->sub_result);
printk(VIOD_KERN_WARNING "read/write error %d:0x%04x (%s)\n",
event->xRc, bevent->sub_result, err->msg);
- num_sect = req->hard_nr_sectors;
+ num_sect = blk_rq_sectors(req);
}
qlock = req->q->queue_lock;
spin_lock_irqsave(qlock, irq_flags);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 5d34764c8a87..29a9daf48621 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -62,7 +62,7 @@ static void blk_done(struct virtqueue *vq)
break;
}
- __blk_end_request(vbr->req, error, blk_rq_bytes(vbr->req));
+ __blk_end_request_all(vbr->req, error);
list_del(&vbr->list);
mempool_free(vbr, vblk->pool);
}
@@ -85,7 +85,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
vbr->req = req;
if (blk_fs_request(vbr->req)) {
vbr->out_hdr.type = 0;
- vbr->out_hdr.sector = vbr->req->sector;
+ vbr->out_hdr.sector = blk_rq_pos(vbr->req);
vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
} else if (blk_pc_request(vbr->req)) {
vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD;
@@ -128,7 +128,7 @@ static void do_virtblk_request(struct request_queue *q)
struct request *req;
unsigned int issued = 0;
- while ((req = elv_next_request(q)) != NULL) {
+ while ((req = blk_peek_request(q)) != NULL) {
vblk = req->rq_disk->private_data;
BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems);
@@ -138,7 +138,7 @@ static void do_virtblk_request(struct request_queue *q)
blk_stop_queue(q);
break;
}
- blkdev_dequeue_request(req);
+ blk_start_request(req);
issued++;
}
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 64b496fce98b..ce2429219925 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -305,30 +305,25 @@ static void do_xd_request (struct request_queue * q)
if (xdc_busy)
return;
- while ((req = elv_next_request(q)) != NULL) {
- unsigned block = req->sector;
- unsigned count = req->nr_sectors;
- int rw = rq_data_dir(req);
+ req = blk_fetch_request(q);
+ while (req) {
+ unsigned block = blk_rq_pos(req);
+ unsigned count = blk_rq_cur_sectors(req);
XD_INFO *disk = req->rq_disk->private_data;
- int res = 0;
+ int res = -EIO;
int retry;
- if (!blk_fs_request(req)) {
- end_request(req, 0);
- continue;
- }
- if (block + count > get_capacity(req->rq_disk)) {
- end_request(req, 0);
- continue;
- }
- if (rw != READ && rw != WRITE) {
- printk("do_xd_request: unknown request\n");
- end_request(req, 0);
- continue;
- }
+ if (!blk_fs_request(req))
+ goto done;
+ if (block + count > get_capacity(req->rq_disk))
+ goto done;
for (retry = 0; (retry < XD_RETRIES) && !res; retry++)
- res = xd_readwrite(rw, disk, req->buffer, block, count);
- end_request(req, res); /* wrap up, 0 = fail, 1 = success */
+ res = xd_readwrite(rq_data_dir(req), disk, req->buffer,
+ block, count);
+ done:
+ /* wrap up, 0 = success, -errno = fail */
+ if (!__blk_end_request_cur(req, res))
+ req = blk_fetch_request(q);
}
}
@@ -418,7 +413,7 @@ static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_
printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
xd_recalibrate(drive);
spin_lock_irq(&xd_lock);
- return (0);
+ return -EIO;
case 2:
if (sense[0] & 0x30) {
printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
@@ -439,7 +434,7 @@ static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_
else
printk(" - no valid disk address\n");
spin_lock_irq(&xd_lock);
- return (0);
+ return -EIO;
}
if (xd_dma_buffer)
for (i=0; i < (temp * 0x200); i++)
@@ -448,7 +443,7 @@ static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_
count -= temp, buffer += temp * 0x200, block += temp;
}
spin_lock_irq(&xd_lock);
- return (1);
+ return 0;
}
/* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 8f905089b72b..6d4ac76c2806 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -231,7 +231,7 @@ static int blkif_queue_request(struct request *req)
info->shadow[id].request = (unsigned long)req;
ring_req->id = id;
- ring_req->sector_number = (blkif_sector_t)req->sector;
+ ring_req->sector_number = (blkif_sector_t)blk_rq_pos(req);
ring_req->handle = info->handle;
ring_req->operation = rq_data_dir(req) ?
@@ -299,25 +299,25 @@ static void do_blkif_request(struct request_queue *rq)
queued = 0;
- while ((req = elv_next_request(rq)) != NULL) {
+ while ((req = blk_peek_request(rq)) != NULL) {
info = req->rq_disk->private_data;
- if (!blk_fs_request(req)) {
- end_request(req, 0);
- continue;
- }
if (RING_FULL(&info->ring))
goto wait;
- pr_debug("do_blk_req %p: cmd %p, sec %lx, "
- "(%u/%li) buffer:%p [%s]\n",
- req, req->cmd, (unsigned long)req->sector,
- req->current_nr_sectors,
- req->nr_sectors, req->buffer,
- rq_data_dir(req) ? "write" : "read");
+ blk_start_request(req);
+ if (!blk_fs_request(req)) {
+ __blk_end_request_all(req, -EIO);
+ continue;
+ }
+
+ pr_debug("do_blk_req %p: cmd %p, sec %lx, "
+ "(%u/%u) buffer:%p [%s]\n",
+ req, req->cmd, (unsigned long)blk_rq_pos(req),
+ blk_rq_cur_sectors(req), blk_rq_sectors(req),
+ req->buffer, rq_data_dir(req) ? "write" : "read");
- blkdev_dequeue_request(req);
if (blkif_queue_request(req)) {
blk_requeue_request(rq, req);
wait:
@@ -551,7 +551,6 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
for (i = info->ring.rsp_cons; i != rp; i++) {
unsigned long id;
- int ret;
bret = RING_GET_RESPONSE(&info->ring, i);
id = bret->id;
@@ -578,8 +577,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
dev_dbg(&info->xbdev->dev, "Bad return from blkdev data "
"request: %x\n", bret->status);
- ret = __blk_end_request(req, error, blk_rq_bytes(req));
- BUG_ON(ret);
+ __blk_end_request_all(req, error);
break;
default:
BUG();
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 4aecf5dc6a93..3a4397edab71 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -463,10 +463,11 @@ struct request *ace_get_next_request(struct request_queue * q)
{
struct request *req;
- while ((req = elv_next_request(q)) != NULL) {
+ while ((req = blk_peek_request(q)) != NULL) {
if (blk_fs_request(req))
break;
- end_request(req, 0);
+ blk_start_request(req);
+ __blk_end_request_all(req, -EIO);
}
return req;
}
@@ -492,9 +493,13 @@ static void ace_fsm_dostate(struct ace_device *ace)
set_capacity(ace->gd, 0);
dev_info(ace->dev, "No CF in slot\n");
- /* Drop all pending requests */
- while ((req = elv_next_request(ace->queue)) != NULL)
- end_request(req, 0);
+ /* Drop all in-flight and pending requests */
+ if (ace->req) {
+ __blk_end_request_all(ace->req, -EIO);
+ ace->req = NULL;
+ }
+ while ((req = blk_fetch_request(ace->queue)) != NULL)
+ __blk_end_request_all(req, -EIO);
/* Drop back to IDLE state and notify waiters */
ace->fsm_state = ACE_FSM_STATE_IDLE;
@@ -642,19 +647,21 @@ static void ace_fsm_dostate(struct ace_device *ace)
ace->fsm_state = ACE_FSM_STATE_IDLE;
break;
}
+ blk_start_request(req);
/* Okay, it's a data request, set it up for transfer */
dev_dbg(ace->dev,
- "request: sec=%llx hcnt=%lx, ccnt=%x, dir=%i\n",
- (unsigned long long) req->sector, req->hard_nr_sectors,
- req->current_nr_sectors, rq_data_dir(req));
+ "request: sec=%llx hcnt=%x, ccnt=%x, dir=%i\n",
+ (unsigned long long)blk_rq_pos(req),
+ blk_rq_sectors(req), blk_rq_cur_sectors(req),
+ rq_data_dir(req));
ace->req = req;
ace->data_ptr = req->buffer;
- ace->data_count = req->current_nr_sectors * ACE_BUF_PER_SECTOR;
- ace_out32(ace, ACE_MPULBA, req->sector & 0x0FFFFFFF);
+ ace->data_count = blk_rq_cur_sectors(req) * ACE_BUF_PER_SECTOR;
+ ace_out32(ace, ACE_MPULBA, blk_rq_pos(req) & 0x0FFFFFFF);
- count = req->hard_nr_sectors;
+ count = blk_rq_sectors(req);
if (rq_data_dir(req)) {
/* Kick off write request */
dev_dbg(ace->dev, "write data\n");
@@ -688,7 +695,7 @@ static void ace_fsm_dostate(struct ace_device *ace)
dev_dbg(ace->dev,
"CFBSY set; t=%i iter=%i c=%i dc=%i irq=%i\n",
ace->fsm_task, ace->fsm_iter_num,
- ace->req->current_nr_sectors * 16,
+ blk_rq_cur_sectors(ace->req) * 16,
ace->data_count, ace->in_irq);
ace_fsm_yield(ace); /* need to poll CFBSY bit */
break;
@@ -697,7 +704,7 @@ static void ace_fsm_dostate(struct ace_device *ace)
dev_dbg(ace->dev,
"DATABUF not set; t=%i iter=%i c=%i dc=%i irq=%i\n",
ace->fsm_task, ace->fsm_iter_num,
- ace->req->current_nr_sectors * 16,
+ blk_rq_cur_sectors(ace->req) * 16,
ace->data_count, ace->in_irq);
ace_fsm_yieldirq(ace);
break;
@@ -717,14 +724,13 @@ static void ace_fsm_dostate(struct ace_device *ace)
}
/* bio finished; is there another one? */
- if (__blk_end_request(ace->req, 0,
- blk_rq_cur_bytes(ace->req))) {
- /* dev_dbg(ace->dev, "next block; h=%li c=%i\n",
- * ace->req->hard_nr_sectors,
- * ace->req->current_nr_sectors);
+ if (__blk_end_request_cur(ace->req, 0)) {
+ /* dev_dbg(ace->dev, "next block; h=%u c=%u\n",
+ * blk_rq_sectors(ace->req),
+ * blk_rq_cur_sectors(ace->req));
*/
ace->data_ptr = ace->req->buffer;
- ace->data_count = ace->req->current_nr_sectors * 16;
+ ace->data_count = blk_rq_cur_sectors(ace->req) * 16;
ace_fsm_yieldirq(ace);
break;
}
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index 80754cdd3119..4575171e5beb 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -70,15 +70,18 @@ static struct gendisk *z2ram_gendisk;
static void do_z2_request(struct request_queue *q)
{
struct request *req;
- while ((req = elv_next_request(q)) != NULL) {
- unsigned long start = req->sector << 9;
- unsigned long len = req->current_nr_sectors << 9;
+
+ req = blk_fetch_request(q);
+ while (req) {
+ unsigned long start = blk_rq_pos(req) << 9;
+ unsigned long len = blk_rq_cur_bytes(req);
+ int err = 0;
if (start + len > z2ram_size) {
printk( KERN_ERR DEVICE_NAME ": bad access: block=%lu, count=%u\n",
- req->sector, req->current_nr_sectors);
- end_request(req, 0);
- continue;
+ blk_rq_pos(req), blk_rq_cur_sectors(req));
+ err = -EIO;
+ goto done;
}
while (len) {
unsigned long addr = start & Z2RAM_CHUNKMASK;
@@ -93,7 +96,9 @@ static void do_z2_request(struct request_queue *q)
start += size;
len -= size;
}
- end_request(req, 1);
+ done:
+ if (!__blk_end_request_cur(req, err))
+ req = blk_fetch_request(q);
}
}
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 2eecb779437b..1e366ad8f680 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -584,8 +584,8 @@ static void gdrom_readdisk_dma(struct work_struct *work)
list_for_each_safe(elem, next, &gdrom_deferred) {
req = list_entry(elem, struct request, queuelist);
spin_unlock(&gdrom_lock);
- block = req->sector/GD_TO_BLK + GD_SESSION_OFFSET;
- block_cnt = req->nr_sectors/GD_TO_BLK;
+ block = blk_rq_pos(req)/GD_TO_BLK + GD_SESSION_OFFSET;
+ block_cnt = blk_rq_sectors(req)/GD_TO_BLK;
ctrl_outl(PHYSADDR(req->buffer), GDROM_DMA_STARTADDR_REG);
ctrl_outl(block_cnt * GDROM_HARD_SECTOR, GDROM_DMA_LENGTH_REG);
ctrl_outl(1, GDROM_DMA_DIRECTION_REG);
@@ -632,39 +632,35 @@ static void gdrom_readdisk_dma(struct work_struct *work)
* before handling ending the request */
spin_lock(&gdrom_lock);
list_del_init(&req->queuelist);
- __blk_end_request(req, err, blk_rq_bytes(req));
+ __blk_end_request_all(req, err);
}
spin_unlock(&gdrom_lock);
kfree(read_command);
}
-static void gdrom_request_handler_dma(struct request *req)
-{
- /* dequeue, add to list of deferred work
- * and then schedule workqueue */
- blkdev_dequeue_request(req);
- list_add_tail(&req->queuelist, &gdrom_deferred);
- schedule_work(&work);
-}
-
static void gdrom_request(struct request_queue *rq)
{
struct request *req;
- while ((req = elv_next_request(rq)) != NULL) {
+ while ((req = blk_fetch_request(rq)) != NULL) {
if (!blk_fs_request(req)) {
printk(KERN_DEBUG "GDROM: Non-fs request ignored\n");
- end_request(req, 0);
+ __blk_end_request_all(req, -EIO);
+ continue;
}
if (rq_data_dir(req) != READ) {
printk(KERN_NOTICE "GDROM: Read only device -");
printk(" write request ignored\n");
- end_request(req, 0);
+ __blk_end_request_all(req, -EIO);
+ continue;
}
- if (req->nr_sectors)
- gdrom_request_handler_dma(req);
- else
- end_request(req, 0);
+
+ /*
+ * Add to list of deferred work and then schedule
+ * workqueue.
+ */
+ list_add_tail(&req->queuelist, &gdrom_deferred);
+ schedule_work(&work);
}
}
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 13929356135c..ca741c21e4aa 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -282,7 +282,7 @@ static int send_request(struct request *req)
viopath_targetinst(viopath_hostLp),
(u64)req, VIOVERSION << 16,
((u64)DEVICE_NR(diskinfo) << 48) | dmaaddr,
- (u64)req->sector * 512, len, 0);
+ (u64)blk_rq_pos(req) * 512, len, 0);
if (hvrc != HvLpEvent_Rc_Good) {
printk(VIOCD_KERN_WARNING "hv error on op %d\n", (int)hvrc);
return -1;
@@ -291,36 +291,19 @@ static int send_request(struct request *req)
return 0;
}
-static void viocd_end_request(struct request *req, int error)
-{
- int nsectors = req->hard_nr_sectors;
-
- /*
- * Make sure it's fully ended, and ensure that we process
- * at least one sector.
- */
- if (blk_pc_request(req))
- nsectors = (req->data_len + 511) >> 9;
- if (!nsectors)
- nsectors = 1;
-
- if (__blk_end_request(req, error, nsectors << 9))
- BUG();
-}
-
static int rwreq;
static void do_viocd_request(struct request_queue *q)
{
struct request *req;
- while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) {
+ while ((rwreq == 0) && ((req = blk_fetch_request(q)) != NULL)) {
if (!blk_fs_request(req))
- viocd_end_request(req, -EIO);
+ __blk_end_request_all(req, -EIO);
else if (send_request(req) < 0) {
printk(VIOCD_KERN_WARNING
"unable to send message to OS/400!");
- viocd_end_request(req, -EIO);
+ __blk_end_request_all(req, -EIO);
} else
rwreq++;
}
@@ -531,9 +514,9 @@ return_complete:
"with rc %d:0x%04X: %s\n",
req, event->xRc,
bevent->sub_result, err->msg);
- viocd_end_request(req, -EIO);
+ __blk_end_request_all(req, -EIO);
} else
- viocd_end_request(req, 0);
+ __blk_end_request_all(req, 0);
/* restart handling of incoming requests */
spin_unlock_irqrestore(&viocd_reqlock, flags);
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 1fdb9f657d8f..456019051742 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -604,7 +604,6 @@
#define NR_PORTS 256
-#define ZE_V1_NPORTS 64
#define ZO_V1 0
#define ZO_V2 1
#define ZE_V1 2
@@ -663,18 +662,6 @@
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 == (unsigned int)-1)
-
-#define Z_FPGA_CHECK(card) \
- ((readl(&((struct RUNTIME_9060 __iomem *) \
- ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
-
-#define ISZLOADED(card) (((ZO_V1 == readl(&((struct RUNTIME_9060 __iomem *) \
- ((card).ctl_addr))->mail_box_0)) || \
- Z_FPGA_CHECK(card)) && \
- (ZFIRM_ID == readl(&((struct FIRM_ID __iomem *) \
- ((card).base_addr+ID_ADDRESS))->signature)))
-
#ifndef SERIAL_XMIT_SIZE
#define SERIAL_XMIT_SIZE (min(PAGE_SIZE, 4096))
#endif
@@ -687,8 +674,6 @@ static void cy_send_xchar(struct tty_struct *tty, char ch);
#define DRIVER_VERSION 0x02010203
#define RAM_SIZE 0x80000
-#define Z_FPGA_LOADED(X) ((readl(&(X)->init_ctrl) & (1<<17)) != 0)
-
enum zblock_type {
ZBLOCK_PRG = 0,
ZBLOCK_FPGA = 1
@@ -883,6 +868,29 @@ static void cyz_rx_restart(unsigned long);
static struct timer_list cyz_rx_full_timer[NR_PORTS];
#endif /* CONFIG_CYZ_INTR */
+static inline bool cy_is_Z(struct cyclades_card *card)
+{
+ return card->num_chips == (unsigned int)-1;
+}
+
+static inline bool __cyz_fpga_loaded(struct RUNTIME_9060 __iomem *ctl_addr)
+{
+ return readl(&ctl_addr->init_ctrl) & (1 << 17);
+}
+
+static inline bool cyz_fpga_loaded(struct cyclades_card *card)
+{
+ return __cyz_fpga_loaded(card->ctl_addr.p9060);
+}
+
+static inline bool cyz_is_loaded(struct cyclades_card *card)
+{
+ struct FIRM_ID __iomem *fw_id = card->base_addr + ID_ADDRESS;
+
+ return (card->hw_ver == ZO_V1 || cyz_fpga_loaded(card)) &&
+ readl(&fw_id->signature) == ZFIRM_ID;
+}
+
static inline int serial_paranoia_check(struct cyclades_port *info,
char *name, const char *routine)
{
@@ -1395,19 +1403,15 @@ cyz_fetch_msg(struct cyclades_card *cinfo,
unsigned long loc_doorbell;
firm_id = cinfo->base_addr + ID_ADDRESS;
- if (!ISZLOADED(*cinfo))
- return -1;
zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
- loc_doorbell = readl(&((struct RUNTIME_9060 __iomem *)
- (cinfo->ctl_addr))->loc_doorbell);
+ loc_doorbell = readl(&cinfo->ctl_addr.p9060->loc_doorbell);
if (loc_doorbell) {
*cmd = (char)(0xff & loc_doorbell);
*channel = readl(&board_ctrl->fwcmd_channel);
*param = (__u32) readl(&board_ctrl->fwcmd_param);
- cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
- loc_doorbell, 0xffffffff);
+ cy_writel(&cinfo->ctl_addr.p9060->loc_doorbell, 0xffffffff);
return 1;
}
return 0;
@@ -1424,15 +1428,14 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
unsigned int index;
firm_id = cinfo->base_addr + ID_ADDRESS;
- if (!ISZLOADED(*cinfo))
+ if (!cyz_is_loaded(cinfo))
return -1;
zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
index = 0;
- pci_doorbell =
- &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell;
+ pci_doorbell = &cinfo->ctl_addr.p9060->pci_doorbell;
while ((readl(pci_doorbell) & 0xff) != 0) {
if (index++ == 1000)
return (int)(readl(pci_doorbell) & 0xff);
@@ -1624,10 +1627,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
static struct BOARD_CTRL __iomem *board_ctrl;
static struct CH_CTRL __iomem *ch_ctrl;
static struct BUF_CTRL __iomem *buf_ctrl;
- __u32 channel;
+ __u32 channel, param, fw_ver;
__u8 cmd;
- __u32 param;
- __u32 hw_ver, fw_ver;
int special_count;
int delta_count;
@@ -1635,8 +1636,6 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
fw_ver = readl(&board_ctrl->fw_version);
- hw_ver = readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
- mail_box_0);
while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
special_count = 0;
@@ -1737,15 +1736,7 @@ static irqreturn_t cyz_interrupt(int irq, void *dev_id)
{
struct cyclades_card *cinfo = dev_id;
- if (unlikely(cinfo == NULL)) {
-#ifdef CY_DEBUG_INTERRUPTS
- printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n",
- irq);
-#endif
- return IRQ_NONE; /* spurious interrupt */
- }
-
- if (unlikely(!ISZLOADED(*cinfo))) {
+ if (unlikely(!cyz_is_loaded(cinfo))) {
#ifdef CY_DEBUG_INTERRUPTS
printk(KERN_DEBUG "cyz_interrupt: board not yet loaded "
"(IRQ%d).\n", irq);
@@ -1785,7 +1776,6 @@ static void cyz_poll(unsigned long arg)
struct tty_struct *tty;
struct FIRM_ID __iomem *firm_id;
struct ZFW_CTRL __iomem *zfw_ctrl;
- struct BOARD_CTRL __iomem *board_ctrl;
struct BUF_CTRL __iomem *buf_ctrl;
unsigned long expires = jiffies + HZ;
unsigned int port, card;
@@ -1793,19 +1783,17 @@ static void cyz_poll(unsigned long arg)
for (card = 0; card < NR_CARDS; card++) {
cinfo = &cy_card[card];
- if (!IS_CYC_Z(*cinfo))
+ if (!cy_is_Z(cinfo))
continue;
- if (!ISZLOADED(*cinfo))
+ if (!cyz_is_loaded(cinfo))
continue;
firm_id = cinfo->base_addr + ID_ADDRESS;
zfw_ctrl = cinfo->base_addr +
(readl(&firm_id->zfwctrl_addr) & 0xfffff);
- board_ctrl = &(zfw_ctrl->board_ctrl);
/* Skip first polling cycle to avoid racing conditions with the FW */
if (!cinfo->intr_enabled) {
- cinfo->nports = (int)readl(&board_ctrl->n_channel);
cinfo->intr_enabled = 1;
continue;
}
@@ -1874,7 +1862,7 @@ static int startup(struct cyclades_port *info)
set_line_char(info);
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -1931,7 +1919,7 @@ static int startup(struct cyclades_port *info)
base_addr = card->base_addr;
firm_id = base_addr + ID_ADDRESS;
- if (!ISZLOADED(*card))
+ if (!cyz_is_loaded(card))
return -ENODEV;
zfw_ctrl = card->base_addr +
@@ -2026,7 +2014,7 @@ static void start_xmit(struct cyclades_port *info)
card = info->card;
channel = info->line - card->first_line;
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -2070,7 +2058,7 @@ static void shutdown(struct cyclades_port *info)
card = info->card;
channel = info->line - card->first_line;
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -2126,7 +2114,7 @@ static void shutdown(struct cyclades_port *info)
#endif
firm_id = base_addr + ID_ADDRESS;
- if (!ISZLOADED(*card))
+ if (!cyz_is_loaded(card))
return;
zfw_ctrl = card->base_addr +
@@ -2233,7 +2221,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
#endif
info->port.blocked_open++;
- if (!IS_CYC_Z(*cinfo)) {
+ if (!cy_is_Z(cinfo)) {
chip = channel >> 2;
channel &= 0x03;
index = cinfo->bus_index;
@@ -2296,7 +2284,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
base_addr = cinfo->base_addr;
firm_id = base_addr + ID_ADDRESS;
- if (!ISZLOADED(*cinfo)) {
+ if (!cyz_is_loaded(cinfo)) {
__set_current_state(TASK_RUNNING);
remove_wait_queue(&info->port.open_wait, &wait);
return -EINVAL;
@@ -2397,16 +2385,14 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
treat it as absent from the system. This
will make the user pay attention.
*/
- if (IS_CYC_Z(*info->card)) {
+ if (cy_is_Z(info->card)) {
struct cyclades_card *cinfo = info->card;
struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS;
- if (!ISZLOADED(*cinfo)) {
- if (((ZE_V1 == readl(&((struct RUNTIME_9060 __iomem *)
- (cinfo->ctl_addr))->mail_box_0)) &&
- Z_FPGA_CHECK(*cinfo)) &&
- (ZFIRM_HLT == readl(
- &firm_id->signature))) {
+ if (!cyz_is_loaded(cinfo)) {
+ if (cinfo->hw_ver == ZE_V1 && cyz_fpga_loaded(cinfo) &&
+ readl(&firm_id->signature) ==
+ ZFIRM_HLT) {
printk(KERN_ERR "cyc:Cyclades-Z Error: you "
"need an external power supply for "
"this number of ports.\nFirmware "
@@ -2423,18 +2409,13 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
interrupts should be enabled as soon as the first open
happens to one of its ports. */
if (!cinfo->intr_enabled) {
- struct ZFW_CTRL __iomem *zfw_ctrl;
- struct BOARD_CTRL __iomem *board_ctrl;
-
- zfw_ctrl = cinfo->base_addr +
- (readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
-
- board_ctrl = &zfw_ctrl->board_ctrl;
+ u16 intr;
/* Enable interrupts on the PLX chip */
- cy_writew(cinfo->ctl_addr + 0x68,
- readw(cinfo->ctl_addr + 0x68) | 0x0900);
+ intr = readw(&cinfo->ctl_addr.p9060->
+ intr_ctrl_stat) | 0x0900;
+ cy_writew(&cinfo->ctl_addr.p9060->
+ intr_ctrl_stat, intr);
/* Enable interrupts on the FW */
retval = cyz_issue_cmd(cinfo, 0,
C_CM_IRQ_ENBL, 0L);
@@ -2442,8 +2423,6 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
printk(KERN_ERR "cyc:IRQ enable retval "
"was %x\n", retval);
}
- cinfo->nports =
- (int)readl(&board_ctrl->n_channel);
cinfo->intr_enabled = 1;
}
}
@@ -2556,7 +2535,7 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
#endif
card = info->card;
channel = (info->line) - (card->first_line);
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -2601,7 +2580,7 @@ static void cy_flush_buffer(struct tty_struct *tty)
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
spin_unlock_irqrestore(&card->card_lock, flags);
- if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board
+ if (cy_is_Z(card)) { /* If it is a Z card, flush the on-board
buffers as well */
spin_lock_irqsave(&card->card_lock, flags);
retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L);
@@ -2682,7 +2661,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
spin_lock_irqsave(&card->card_lock, flags);
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
int channel = info->line - card->first_line;
int index = card->bus_index;
void __iomem *base_addr = card->base_addr +
@@ -2902,7 +2881,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty)
channel = (info->line) - (card->first_line);
#ifdef Z_EXT_CHARS_IN_BUFFER
- if (!IS_CYC_Z(cy_card[card])) {
+ if (!cy_is_Z(card)) {
#endif /* Z_EXT_CHARS_IN_BUFFER */
#ifdef CY_DEBUG_IO
printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
@@ -2984,7 +2963,6 @@ static void set_line_char(struct cyclades_port *info)
void __iomem *base_addr;
int chip, channel, index;
unsigned cflag, iflag;
- unsigned short chip_number;
int baud, baud_rate = 0;
int i;
@@ -3013,9 +2991,8 @@ static void set_line_char(struct cyclades_port *info)
card = info->card;
channel = info->line - card->first_line;
- chip_number = channel / 4;
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
index = card->bus_index;
@@ -3233,21 +3210,17 @@ static void set_line_char(struct cyclades_port *info)
} else {
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;
__u32 sw_flow;
int retval;
firm_id = card->base_addr + ID_ADDRESS;
- if (!ISZLOADED(*card))
+ if (!cyz_is_loaded(card))
return;
zfw_ctrl = card->base_addr +
(readl(&firm_id->zfwctrl_addr) & 0xfffff);
- board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
- buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
/* baud rate */
baud = tty_get_baud_rate(info->port.tty);
@@ -3457,7 +3430,7 @@ static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value)
card = info->card;
channel = (info->line) - (card->first_line);
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -3497,7 +3470,7 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
card = info->card;
channel = info->line - card->first_line;
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -3523,7 +3496,7 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
} else {
base_addr = card->base_addr;
firm_id = card->base_addr + ID_ADDRESS;
- if (ISZLOADED(*card)) {
+ if (cyz_is_loaded(card)) {
zfw_ctrl = card->base_addr +
(readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
@@ -3566,7 +3539,7 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
card = info->card;
channel = (info->line) - (card->first_line);
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -3641,7 +3614,7 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
base_addr = card->base_addr;
firm_id = card->base_addr + ID_ADDRESS;
- if (ISZLOADED(*card)) {
+ if (cyz_is_loaded(card)) {
zfw_ctrl = card->base_addr +
(readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
@@ -3713,7 +3686,7 @@ static int cy_break(struct tty_struct *tty, int break_state)
card = info->card;
spin_lock_irqsave(&card->card_lock, flags);
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
/* Let the transmit ISR take care of this (since it
requires stuffing characters into the output stream).
*/
@@ -3782,7 +3755,7 @@ static int set_threshold(struct cyclades_port *info, unsigned long value)
card = info->card;
channel = info->line - card->first_line;
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -3810,7 +3783,7 @@ static int get_threshold(struct cyclades_port *info,
card = info->card;
channel = info->line - card->first_line;
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -3844,7 +3817,7 @@ static int set_timeout(struct cyclades_port *info, unsigned long value)
card = info->card;
channel = info->line - card->first_line;
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -3867,7 +3840,7 @@ static int get_timeout(struct cyclades_port *info,
card = info->card;
channel = info->line - card->first_line;
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -4121,7 +4094,7 @@ static void cy_send_xchar(struct tty_struct *tty, char ch)
card = info->card;
channel = info->line - card->first_line;
- if (IS_CYC_Z(*card)) {
+ if (cy_is_Z(card)) {
if (ch == STOP_CHAR(tty))
cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L);
else if (ch == START_CHAR(tty))
@@ -4154,7 +4127,7 @@ static void cy_throttle(struct tty_struct *tty)
card = info->card;
if (I_IXOFF(tty)) {
- if (!IS_CYC_Z(*card))
+ if (!cy_is_Z(card))
cy_send_xchar(tty, STOP_CHAR(tty));
else
info->throttle = 1;
@@ -4162,7 +4135,7 @@ static void cy_throttle(struct tty_struct *tty)
if (tty->termios->c_cflag & CRTSCTS) {
channel = info->line - card->first_line;
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -4219,7 +4192,7 @@ static void cy_unthrottle(struct tty_struct *tty)
if (tty->termios->c_cflag & CRTSCTS) {
card = info->card;
channel = info->line - card->first_line;
- if (!IS_CYC_Z(*card)) {
+ if (!cy_is_Z(card)) {
chip = channel >> 2;
channel &= 0x03;
index = card->bus_index;
@@ -4263,7 +4236,7 @@ static void cy_stop(struct tty_struct *tty)
cinfo = info->card;
channel = info->line - cinfo->first_line;
- if (!IS_CYC_Z(*cinfo)) {
+ if (!cy_is_Z(cinfo)) {
index = cinfo->bus_index;
chip = channel >> 2;
channel &= 0x03;
@@ -4296,7 +4269,7 @@ static void cy_start(struct tty_struct *tty)
cinfo = info->card;
channel = info->line - cinfo->first_line;
index = cinfo->bus_index;
- if (!IS_CYC_Z(*cinfo)) {
+ if (!cy_is_Z(cinfo)) {
chip = channel >> 2;
channel &= 0x03;
base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
@@ -4347,33 +4320,20 @@ static void cy_hangup(struct tty_struct *tty)
static int __devinit cy_init_card(struct cyclades_card *cinfo)
{
struct cyclades_port *info;
- u32 uninitialized_var(mailbox);
- unsigned int nports, port;
+ unsigned int port;
unsigned short chip_number;
- int uninitialized_var(index);
spin_lock_init(&cinfo->card_lock);
+ cinfo->intr_enabled = 0;
- if (IS_CYC_Z(*cinfo)) { /* Cyclades-Z */
- mailbox = readl(&((struct RUNTIME_9060 __iomem *)
- cinfo->ctl_addr)->mail_box_0);
- nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
- cinfo->intr_enabled = 0;
- cinfo->nports = 0; /* Will be correctly set later, after
- Z FW is loaded */
- } else {
- index = cinfo->bus_index;
- nports = cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
- }
-
- cinfo->ports = kzalloc(sizeof(*cinfo->ports) * nports, GFP_KERNEL);
+ cinfo->ports = kcalloc(cinfo->nports, sizeof(*cinfo->ports),
+ GFP_KERNEL);
if (cinfo->ports == NULL) {
printk(KERN_ERR "Cyclades: cannot allocate ports\n");
- cinfo->nports = 0;
return -ENOMEM;
}
- for (port = cinfo->first_line; port < cinfo->first_line + nports;
+ for (port = cinfo->first_line; port < cinfo->first_line + cinfo->nports;
port++) {
info = &cinfo->ports[port - cinfo->first_line];
tty_port_init(&info->port);
@@ -4387,9 +4347,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
init_completion(&info->shutdown_wait);
init_waitqueue_head(&info->delta_msr_wait);
- if (IS_CYC_Z(*cinfo)) {
+ if (cy_is_Z(cinfo)) {
info->type = PORT_STARTECH;
- if (mailbox == ZO_V1)
+ if (cinfo->hw_ver == ZO_V1)
info->xmit_fifo_size = CYZ_FIFO_SIZE;
else
info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
@@ -4398,6 +4358,7 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
cyz_rx_restart, (unsigned long)info);
#endif
} else {
+ int index = cinfo->bus_index;
info->type = PORT_CIRRUS;
info->xmit_fifo_size = CyMAX_CHAR_FIFO;
info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
@@ -4430,7 +4391,7 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
}
#ifndef CONFIG_CYZ_INTR
- if (IS_CYC_Z(*cinfo) && !timer_pending(&cyz_timerlist)) {
+ if (cy_is_Z(cinfo) && !timer_pending(&cyz_timerlist)) {
mod_timer(&cyz_timerlist, jiffies + 1);
#ifdef CY_PCI_DEBUG
printk(KERN_DEBUG "Cyclades-Z polling initialized\n");
@@ -4621,11 +4582,12 @@ static int __init cy_detect_isa(void)
/* set cy_card */
cy_card[j].base_addr = cy_isa_address;
- cy_card[j].ctl_addr = NULL;
+ cy_card[j].ctl_addr.p9050 = NULL;
cy_card[j].irq = (int)cy_isa_irq;
cy_card[j].bus_index = 0;
cy_card[j].first_line = cy_next_channel;
- cy_card[j].num_chips = cy_isa_nchan / 4;
+ cy_card[j].num_chips = cy_isa_nchan / CyPORTS_PER_CHIP;
+ cy_card[j].nports = cy_isa_nchan;
if (cy_init_card(&cy_card[j])) {
cy_card[j].base_addr = NULL;
free_irq(cy_isa_irq, &cy_card[j]);
@@ -4781,7 +4743,7 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
struct CUSTOM_REG __iomem *cust = base_addr;
struct ZFW_CTRL __iomem *pt_zfwctrl;
void __iomem *tmp;
- u32 mailbox, status;
+ u32 mailbox, status, nchan;
unsigned int i;
int retval;
@@ -4793,7 +4755,7 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
/* Check whether the firmware is already loaded and running. If
positive, skip this board */
- if (Z_FPGA_LOADED(ctl_addr) && readl(&fid->signature) == ZFIRM_ID) {
+ if (__cyz_fpga_loaded(ctl_addr) && readl(&fid->signature) == ZFIRM_ID) {
u32 cntval = readl(base_addr + 0x190);
udelay(100);
@@ -4812,7 +4774,7 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
mailbox = readl(&ctl_addr->mail_box_0);
- if (mailbox == 0 || Z_FPGA_LOADED(ctl_addr)) {
+ if (mailbox == 0 || __cyz_fpga_loaded(ctl_addr)) {
/* stops CPU and set window to beginning of RAM */
cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
cy_writel(&cust->cpu_stop, 0);
@@ -4828,7 +4790,7 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
base_addr);
if (retval)
goto err_rel;
- if (!Z_FPGA_LOADED(ctl_addr)) {
+ if (!__cyz_fpga_loaded(ctl_addr)) {
dev_err(&pdev->dev, "fw upload successful, but fw is "
"not loaded\n");
goto err_rel;
@@ -4887,7 +4849,7 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
"system before loading the new FW to the "
"Cyclades-Z.\n");
- if (Z_FPGA_LOADED(ctl_addr))
+ if (__cyz_fpga_loaded(ctl_addr))
plx_init(pdev, irq, ctl_addr);
retval = -EIO;
@@ -4902,16 +4864,16 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
base_addr + ID_ADDRESS, readl(&fid->zfwctrl_addr),
base_addr + readl(&fid->zfwctrl_addr));
+ nchan = readl(&pt_zfwctrl->board_ctrl.n_channel);
dev_info(&pdev->dev, "Cyclades-Z FW loaded: version = %x, ports = %u\n",
- readl(&pt_zfwctrl->board_ctrl.fw_version),
- readl(&pt_zfwctrl->board_ctrl.n_channel));
+ readl(&pt_zfwctrl->board_ctrl.fw_version), nchan);
- if (readl(&pt_zfwctrl->board_ctrl.n_channel) == 0) {
+ if (nchan == 0) {
dev_warn(&pdev->dev, "no Cyclades-Z ports were found. Please "
"check the connection between the Z host card and the "
"serial expanders.\n");
- if (Z_FPGA_LOADED(ctl_addr))
+ if (__cyz_fpga_loaded(ctl_addr))
plx_init(pdev, irq, ctl_addr);
dev_info(&pdev->dev, "Null number of ports detected. Board "
@@ -4932,9 +4894,7 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) |
0x00030800UL);
- plx_init(pdev, irq, ctl_addr);
-
- return 0;
+ return nchan;
err_rel:
release_firmware(fw);
err:
@@ -4946,7 +4906,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
{
void __iomem *addr0 = NULL, *addr2 = NULL;
char *card_name = NULL;
- u32 mailbox;
+ u32 uninitialized_var(mailbox);
unsigned int device_id, nchan = 0, card_no, i;
unsigned char plx_ver;
int retval, irq;
@@ -5023,11 +4983,12 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
}
/* Disable interrupts on the PLX before resetting it */
- cy_writew(addr0 + 0x68, readw(addr0 + 0x68) & ~0x0900);
+ cy_writew(&ctl_addr->intr_ctrl_stat,
+ readw(&ctl_addr->intr_ctrl_stat) & ~0x0900);
plx_init(pdev, irq, addr0);
- mailbox = (u32)readl(&ctl_addr->mail_box_0);
+ mailbox = readl(&ctl_addr->mail_box_0);
addr2 = ioremap_nocache(pci_resource_start(pdev, 2),
mailbox == ZE_V1 ? CyPCI_Ze_win : CyPCI_Zwin);
@@ -5038,12 +4999,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
if (mailbox == ZE_V1) {
card_name = "Cyclades-Ze";
-
- readl(&ctl_addr->mail_box_0);
- nchan = ZE_V1_NPORTS;
} else {
card_name = "Cyclades-8Zo";
-
#ifdef CY_PCI_DEBUG
if (mailbox == ZO_V1) {
cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
@@ -5065,15 +5022,12 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
*/
if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
cy_writel(addr2 + ID_ADDRESS, 0L);
-
- retval = cyz_load_fw(pdev, addr2, addr0, irq);
- if (retval)
- goto err_unmap;
- /* This must be a Cyclades-8Zo/PCI. The extendable
- version will have a different device_id and will
- be allocated its maximum number of ports. */
- nchan = 8;
}
+
+ retval = cyz_load_fw(pdev, addr2, addr0, irq);
+ if (retval <= 0)
+ goto err_unmap;
+ nchan = retval;
}
if ((cy_next_channel + nchan) > NR_PORTS) {
@@ -5103,8 +5057,10 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
dev_err(&pdev->dev, "could not allocate IRQ\n");
goto err_unmap;
}
- cy_card[card_no].num_chips = nchan / 4;
+ cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP;
} else {
+ cy_card[card_no].hw_ver = mailbox;
+ cy_card[card_no].num_chips = (unsigned int)-1;
#ifdef CONFIG_CYZ_INTR
/* allocate IRQ only if board has an IRQ */
if (irq != 0 && irq != 255) {
@@ -5117,15 +5073,15 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
}
}
#endif /* CONFIG_CYZ_INTR */
- cy_card[card_no].num_chips = (unsigned int)-1;
}
/* set cy_card */
cy_card[card_no].base_addr = addr2;
- cy_card[card_no].ctl_addr = addr0;
+ cy_card[card_no].ctl_addr.p9050 = addr0;
cy_card[card_no].irq = irq;
cy_card[card_no].bus_index = 1;
cy_card[card_no].first_line = cy_next_channel;
+ cy_card[card_no].nports = nchan;
retval = cy_init_card(&cy_card[card_no]);
if (retval)
goto err_null;
@@ -5138,17 +5094,20 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
plx_ver = readb(addr2 + CyPLX_VER) & 0x0f;
switch (plx_ver) {
case PLX_9050:
-
cy_writeb(addr0 + 0x4c, 0x43);
break;
case PLX_9060:
case PLX_9080:
default: /* Old boards, use PLX_9060 */
- plx_init(pdev, irq, addr0);
- cy_writew(addr0 + 0x68, readw(addr0 + 0x68) | 0x0900);
+ {
+ struct RUNTIME_9060 __iomem *ctl_addr = addr0;
+ plx_init(pdev, irq, ctl_addr);
+ cy_writew(&ctl_addr->intr_ctrl_stat,
+ readw(&ctl_addr->intr_ctrl_stat) | 0x0900);
break;
}
+ }
}
dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from "
@@ -5179,22 +5138,23 @@ static void __devexit cy_pci_remove(struct pci_dev *pdev)
unsigned int i;
/* non-Z with old PLX */
- if (!IS_CYC_Z(*cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) ==
+ if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) ==
PLX_9050)
- cy_writeb(cinfo->ctl_addr + 0x4c, 0);
+ cy_writeb(cinfo->ctl_addr.p9050 + 0x4c, 0);
else
#ifndef CONFIG_CYZ_INTR
- if (!IS_CYC_Z(*cinfo))
+ if (!cy_is_Z(cinfo))
#endif
- cy_writew(cinfo->ctl_addr + 0x68,
- readw(cinfo->ctl_addr + 0x68) & ~0x0900);
+ cy_writew(&cinfo->ctl_addr.p9060->intr_ctrl_stat,
+ readw(&cinfo->ctl_addr.p9060->intr_ctrl_stat) &
+ ~0x0900);
iounmap(cinfo->base_addr);
- if (cinfo->ctl_addr)
- iounmap(cinfo->ctl_addr);
+ if (cinfo->ctl_addr.p9050)
+ iounmap(cinfo->ctl_addr.p9050);
if (cinfo->irq
#ifndef CONFIG_CYZ_INTR
- && !IS_CYC_Z(*cinfo)
+ && !cy_is_Z(cinfo)
#endif /* CONFIG_CYZ_INTR */
)
free_irq(cinfo->irq, cinfo);
@@ -5386,11 +5346,11 @@ static void __exit cy_cleanup_module(void)
/* clear interrupt */
cy_writeb(card->base_addr + Cy_ClrIntr, 0);
iounmap(card->base_addr);
- if (card->ctl_addr)
- iounmap(card->ctl_addr);
+ if (card->ctl_addr.p9050)
+ iounmap(card->ctl_addr.p9050);
if (card->irq
#ifndef CONFIG_CYZ_INTR
- && !IS_CYC_Z(*card)
+ && !cy_is_Z(card)
#endif /* CONFIG_CYZ_INTR */
)
free_irq(card->irq, card);
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index af7c13ca9493..710ee9333057 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -745,7 +745,7 @@ static int epca_carrier_raised(struct tty_port *port)
return 0;
}
-static void epca_raise_dtr_rts(struct tty_port *port)
+static void epca_dtr_rts(struct tty_port *port, int onoff)
{
}
@@ -925,7 +925,7 @@ static const struct tty_operations pc_ops = {
static const struct tty_port_operations epca_port_ops = {
.carrier_raised = epca_carrier_raised,
- .raise_dtr_rts = epca_raise_dtr_rts,
+ .dtr_rts = epca_dtr_rts,
};
static int info_open(struct tty_struct *tty, struct file *filp)
@@ -1518,7 +1518,7 @@ static void doevent(int crd)
if (event & MODEMCHG_IND) {
/* A modem signal change has been indicated */
ch->imodem = mstat;
- if (test_bit(ASYNC_CHECK_CD, &ch->port.flags)) {
+ if (test_bit(ASYNCB_CHECK_CD, &ch->port.flags)) {
/* We are now receiving dcd */
if (mstat & ch->dcd)
wake_up_interruptible(&ch->port.open_wait);
@@ -1765,9 +1765,9 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
* that the driver will wait on carrier detect.
*/
if (ts->c_cflag & CLOCAL)
- clear_bit(ASYNC_CHECK_CD, &ch->port.flags);
+ clear_bit(ASYNCB_CHECK_CD, &ch->port.flags);
else
- set_bit(ASYNC_CHECK_CD, &ch->port.flags);
+ set_bit(ASYNCB_CHECK_CD, &ch->port.flags);
mval = ch->m_dtr | ch->m_rts;
} /* End CBAUD not detected */
iflag = termios2digi_i(ch, ts->c_iflag);
@@ -2244,7 +2244,8 @@ static void do_softint(struct work_struct *work)
if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
tty_hangup(tty);
wake_up_interruptible(&ch->port.open_wait);
- clear_bit(ASYNC_NORMAL_ACTIVE, &ch->port.flags);
+ clear_bit(ASYNCB_NORMAL_ACTIVE,
+ &ch->port.flags);
}
}
tty_kref_put(tty);
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 340ba4f9dc54..4a9f3492b921 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -224,7 +224,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
break;
}
- gsi = acpi_register_gsi(irq, ACPI_LEVEL_SENSITIVE,
+ gsi = acpi_register_gsi(NULL, irq, ACPI_LEVEL_SENSITIVE,
ACPI_ACTIVE_LOW);
if (gsi > 0)
break;
@@ -939,7 +939,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
irqp = &res->data.extended_irq;
for (i = 0; i < irqp->interrupt_count; i++) {
- irq = acpi_register_gsi(irqp->interrupts[i],
+ irq = acpi_register_gsi(NULL, irqp->interrupts[i],
irqp->triggering, irqp->polarity);
if (irq < 0)
return AE_ERROR;
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index 538313f9e7ac..00dd3de1be51 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -89,7 +89,7 @@ static struct hwrng omap_rng_ops = {
.data_read = omap_rng_data_read,
};
-static int __init omap_rng_probe(struct platform_device *pdev)
+static int __devinit omap_rng_probe(struct platform_device *pdev)
{
struct resource *res, *mem;
int ret;
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index a59eac584d16..4d745a89504f 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -329,7 +329,7 @@ static inline void drop_rts(struct isi_port *port)
/* card->lock MUST NOT be held */
-static void isicom_raise_dtr_rts(struct tty_port *port)
+static void isicom_dtr_rts(struct tty_port *port, int on)
{
struct isi_port *ip = container_of(port, struct isi_port, port);
struct isi_board *card = ip->card;
@@ -339,10 +339,17 @@ static void isicom_raise_dtr_rts(struct tty_port *port)
if (!lock_card(card))
return;
- outw(0x8000 | (channel << card->shift_count) | 0x02, base);
- outw(0x0f04, base);
- InterruptTheCard(base);
- ip->status |= (ISI_DTR | ISI_RTS);
+ if (on) {
+ outw(0x8000 | (channel << card->shift_count) | 0x02, base);
+ outw(0x0f04, base);
+ InterruptTheCard(base);
+ ip->status |= (ISI_DTR | ISI_RTS);
+ } else {
+ outw(0x8000 | (channel << card->shift_count) | 0x02, base);
+ outw(0x0C04, base);
+ InterruptTheCard(base);
+ ip->status &= ~(ISI_DTR | ISI_RTS);
+ }
unlock_card(card);
}
@@ -1339,7 +1346,7 @@ static const struct tty_operations isicom_ops = {
static const struct tty_port_operations isicom_port_ops = {
.carrier_raised = isicom_carrier_raised,
- .raise_dtr_rts = isicom_raise_dtr_rts,
+ .dtr_rts = isicom_dtr_rts,
};
static int __devinit reset_card(struct pci_dev *pdev,
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index fff19f7e29d2..e18800c400b1 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -1140,14 +1140,14 @@ static int stli_carrier_raised(struct tty_port *port)
return (portp->sigs & TIOCM_CD) ? 1 : 0;
}
-static void stli_raise_dtr_rts(struct tty_port *port)
+static void stli_dtr_rts(struct tty_port *port, int on)
{
struct stliport *portp = container_of(port, struct stliport, port);
struct stlibrd *brdp = stli_brds[portp->brdnr];
- stli_mkasysigs(&portp->asig, 1, 1);
+ stli_mkasysigs(&portp->asig, on, on);
if (stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
sizeof(asysigs_t), 0) < 0)
- printk(KERN_WARNING "istallion: dtr raise failed.\n");
+ printk(KERN_WARNING "istallion: dtr set failed.\n");
}
@@ -4417,7 +4417,7 @@ static const struct tty_operations stli_ops = {
static const struct tty_port_operations stli_port_ops = {
.carrier_raised = stli_carrier_raised,
- .raise_dtr_rts = stli_raise_dtr_rts,
+ .dtr_rts = stli_dtr_rts,
};
/*****************************************************************************/
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index de26a978fbdd..737be953cc58 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1123,8 +1123,6 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
#define HW_RAW(dev) 0
-#warning "Cannot generate rawmode keyboard for your architecture yet."
-
static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
{
if (keycode > 127)
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index a420e8d437dd..6dfef561ee50 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -547,14 +547,18 @@ static int mxser_carrier_raised(struct tty_port *port)
return (inb(mp->ioaddr + UART_MSR) & UART_MSR_DCD)?1:0;
}
-static void mxser_raise_dtr_rts(struct tty_port *port)
+static void mxser_dtr_rts(struct tty_port *port, int on)
{
struct mxser_port *mp = container_of(port, struct mxser_port, port);
unsigned long flags;
spin_lock_irqsave(&mp->slock, flags);
- outb(inb(mp->ioaddr + UART_MCR) |
- UART_MCR_DTR | UART_MCR_RTS, mp->ioaddr + UART_MCR);
+ if (on)
+ outb(inb(mp->ioaddr + UART_MCR) |
+ UART_MCR_DTR | UART_MCR_RTS, mp->ioaddr + UART_MCR);
+ else
+ outb(inb(mp->ioaddr + UART_MCR)&~(UART_MCR_DTR | UART_MCR_RTS),
+ mp->ioaddr + UART_MCR);
spin_unlock_irqrestore(&mp->slock, flags);
}
@@ -2356,7 +2360,7 @@ static const struct tty_operations mxser_ops = {
struct tty_port_operations mxser_port_ops = {
.carrier_raised = mxser_carrier_raised,
- .raise_dtr_rts = mxser_raise_dtr_rts,
+ .dtr_rts = mxser_dtr_rts,
};
/*
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 19d79fc54461..77b364889224 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -383,7 +383,7 @@ static void async_mode(MGSLPC_INFO *info);
static void tx_timeout(unsigned long context);
static int carrier_raised(struct tty_port *port);
-static void raise_dtr_rts(struct tty_port *port);
+static void dtr_rts(struct tty_port *port, int onoff);
#if SYNCLINK_GENERIC_HDLC
#define dev_to_port(D) (dev_to_hdlc(D)->priv)
@@ -513,7 +513,7 @@ static void ldisc_receive_buf(struct tty_struct *tty,
static const struct tty_port_operations mgslpc_port_ops = {
.carrier_raised = carrier_raised,
- .raise_dtr_rts = raise_dtr_rts
+ .dtr_rts = dtr_rts
};
static int mgslpc_probe(struct pcmcia_device *link)
@@ -2528,13 +2528,16 @@ static int carrier_raised(struct tty_port *port)
return 0;
}
-static void raise_dtr_rts(struct tty_port *port)
+static void dtr_rts(struct tty_port *port, int onoff)
{
MGSLPC_INFO *info = container_of(port, MGSLPC_INFO, port);
unsigned long flags;
spin_lock_irqsave(&info->lock,flags);
- info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;
+ if (onoff)
+ info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;
+ else
+ info->serial_signals &= ~SerialSignal_RTS + SerialSignal_DTR;
set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
}
diff --git a/drivers/char/random.c b/drivers/char/random.c
index f824ef8a9273..b2ced39d76b2 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1665,15 +1665,20 @@ EXPORT_SYMBOL(secure_dccp_sequence_number);
* value is not cryptographically secure but for several uses the cost of
* depleting entropy is too high
*/
+DEFINE_PER_CPU(__u32 [4], get_random_int_hash);
unsigned int get_random_int(void)
{
- /*
- * Use IP's RNG. It suits our purpose perfectly: it re-keys itself
- * every second, from the entropy pool (and thus creates a limited
- * drain on it), and uses halfMD4Transform within the second. We
- * also mix it with jiffies and the PID:
- */
- return secure_ip_id((__force __be32)(current->pid + jiffies));
+ struct keydata *keyptr;
+ __u32 *hash = get_cpu_var(get_random_int_hash);
+ int ret;
+
+ keyptr = get_keyptr();
+ hash[0] += current->pid + jiffies + get_cycles() + (int)(long)&ret;
+
+ ret = half_md4_transform(hash, keyptr->secret);
+ put_cpu_var(get_random_int_hash);
+
+ return ret;
}
/*
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index f59fc5cea067..63d5b628477a 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -872,11 +872,16 @@ static int carrier_raised(struct tty_port *port)
return (sGetChanStatusLo(&info->channel) & CD_ACT) ? 1 : 0;
}
-static void raise_dtr_rts(struct tty_port *port)
+static void dtr_rts(struct tty_port *port, int on)
{
struct r_port *info = container_of(port, struct r_port, port);
- sSetDTR(&info->channel);
- sSetRTS(&info->channel);
+ if (on) {
+ sSetDTR(&info->channel);
+ sSetRTS(&info->channel);
+ } else {
+ sClrDTR(&info->channel);
+ sClrRTS(&info->channel);
+ }
}
/*
@@ -934,7 +939,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
/*
* Info->count is now 1; so it's safe to sleep now.
*/
- if (!test_bit(ASYNC_INITIALIZED, &port->flags)) {
+ if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
cp = &info->channel;
sSetRxTrigger(cp, TRIG_1);
if (sGetChanStatus(cp) & CD_ACT)
@@ -958,7 +963,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
sEnRxFIFO(cp);
sEnTransmit(cp);
- set_bit(ASYNC_INITIALIZED, &info->port.flags);
+ set_bit(ASYNCB_INITIALIZED, &info->port.flags);
/*
* Set up the tty->alt_speed kludge
@@ -1641,7 +1646,7 @@ static int rp_write(struct tty_struct *tty,
/* Write remaining data into the port's xmit_buf */
while (1) {
/* Hung up ? */
- if (!test_bit(ASYNC_NORMAL_ACTIVE, &info->port.flags))
+ if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags))
goto end;
c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
c = min(c, XMIT_BUF_SIZE - info->xmit_head);
@@ -2250,7 +2255,7 @@ static const struct tty_operations rocket_ops = {
static const struct tty_port_operations rocket_port_ops = {
.carrier_raised = carrier_raised,
- .raise_dtr_rts = raise_dtr_rts,
+ .dtr_rts = dtr_rts,
};
/*
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 2ad813a801dc..53e504f41b20 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -772,11 +772,11 @@ static int stl_carrier_raised(struct tty_port *port)
return (portp->sigs & TIOCM_CD) ? 1 : 0;
}
-static void stl_raise_dtr_rts(struct tty_port *port)
+static void stl_dtr_rts(struct tty_port *port, int on)
{
struct stlport *portp = container_of(port, struct stlport, port);
/* Takes brd_lock internally */
- stl_setsignals(portp, 1, 1);
+ stl_setsignals(portp, on, on);
}
/*****************************************************************************/
@@ -2547,7 +2547,7 @@ static const struct tty_operations stl_ops = {
static const struct tty_port_operations stl_port_ops = {
.carrier_raised = stl_carrier_raised,
- .raise_dtr_rts = stl_raise_dtr_rts,
+ .dtr_rts = stl_dtr_rts,
};
/*****************************************************************************/
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index afd0b26ca056..afded3a2379c 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -3247,13 +3247,16 @@ static int carrier_raised(struct tty_port *port)
return (info->serial_signals & SerialSignal_DCD) ? 1 : 0;
}
-static void raise_dtr_rts(struct tty_port *port)
+static void dtr_rts(struct tty_port *port, int on)
{
struct mgsl_struct *info = container_of(port, struct mgsl_struct, port);
unsigned long flags;
spin_lock_irqsave(&info->irq_spinlock,flags);
- info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;
+ if (on)
+ info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;
+ else
+ info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
usc_set_serial_signals(info);
spin_unlock_irqrestore(&info->irq_spinlock,flags);
}
@@ -4258,7 +4261,7 @@ static void mgsl_add_device( struct mgsl_struct *info )
static const struct tty_port_operations mgsl_port_ops = {
.carrier_raised = carrier_raised,
- .raise_dtr_rts = raise_dtr_rts,
+ .dtr_rts = dtr_rts,
};
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 5e256494686a..1386625fc4ca 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -214,6 +214,7 @@ struct slgt_desc
#define set_desc_next(a,b) (a).next = cpu_to_le32((unsigned int)(b))
#define set_desc_count(a,b)(a).count = cpu_to_le16((unsigned short)(b))
#define set_desc_eof(a,b) (a).status = cpu_to_le16((b) ? (le16_to_cpu((a).status) | BIT0) : (le16_to_cpu((a).status) & ~BIT0))
+#define set_desc_status(a, b) (a).status = cpu_to_le16((unsigned short)(b))
#define desc_count(a) (le16_to_cpu((a).count))
#define desc_status(a) (le16_to_cpu((a).status))
#define desc_complete(a) (le16_to_cpu((a).status) & BIT15)
@@ -297,6 +298,7 @@ struct slgt_info {
u32 max_frame_size; /* as set by device config */
unsigned int rbuf_fill_level;
+ unsigned int rx_pio;
unsigned int if_mode;
unsigned int base_clock;
@@ -331,6 +333,8 @@ struct slgt_info {
struct slgt_desc *rbufs;
unsigned int rbuf_current;
unsigned int rbuf_index;
+ unsigned int rbuf_fill_index;
+ unsigned short rbuf_fill_count;
unsigned int tbuf_count;
struct slgt_desc *tbufs;
@@ -2110,6 +2114,40 @@ static void ri_change(struct slgt_info *info, unsigned short status)
info->pending_bh |= BH_STATUS;
}
+static void isr_rxdata(struct slgt_info *info)
+{
+ unsigned int count = info->rbuf_fill_count;
+ unsigned int i = info->rbuf_fill_index;
+ unsigned short reg;
+
+ while (rd_reg16(info, SSR) & IRQ_RXDATA) {
+ reg = rd_reg16(info, RDR);
+ DBGISR(("isr_rxdata %s RDR=%04X\n", info->device_name, reg));
+ if (desc_complete(info->rbufs[i])) {
+ /* all buffers full */
+ rx_stop(info);
+ info->rx_restart = 1;
+ continue;
+ }
+ info->rbufs[i].buf[count++] = (unsigned char)reg;
+ /* async mode saves status byte to buffer for each data byte */
+ if (info->params.mode == MGSL_MODE_ASYNC)
+ info->rbufs[i].buf[count++] = (unsigned char)(reg >> 8);
+ if (count == info->rbuf_fill_level || (reg & BIT10)) {
+ /* buffer full or end of frame */
+ set_desc_count(info->rbufs[i], count);
+ set_desc_status(info->rbufs[i], BIT15 | (reg >> 8));
+ info->rbuf_fill_count = count = 0;
+ if (++i == info->rbuf_count)
+ i = 0;
+ info->pending_bh |= BH_RECEIVE;
+ }
+ }
+
+ info->rbuf_fill_index = i;
+ info->rbuf_fill_count = count;
+}
+
static void isr_serial(struct slgt_info *info)
{
unsigned short status = rd_reg16(info, SSR);
@@ -2125,6 +2163,8 @@ static void isr_serial(struct slgt_info *info)
if (info->tx_count)
isr_txeom(info, status);
}
+ if (info->rx_pio && (status & IRQ_RXDATA))
+ isr_rxdata(info);
if ((status & IRQ_RXBREAK) && (status & RXBREAK)) {
info->icount.brk++;
/* process break detection if tty control allows */
@@ -2141,7 +2181,8 @@ static void isr_serial(struct slgt_info *info)
} else {
if (status & (IRQ_TXIDLE + IRQ_TXUNDER))
isr_txeom(info, status);
-
+ if (info->rx_pio && (status & IRQ_RXDATA))
+ isr_rxdata(info);
if (status & IRQ_RXIDLE) {
if (status & RXIDLE)
info->icount.rxidle++;
@@ -2642,6 +2683,10 @@ static int rx_enable(struct slgt_info *info, int enable)
return -EINVAL;
}
info->rbuf_fill_level = rbuf_fill_level;
+ if (rbuf_fill_level < 128)
+ info->rx_pio = 1; /* PIO mode */
+ else
+ info->rx_pio = 0; /* DMA mode */
rx_stop(info); /* restart receiver to use new fill level */
}
@@ -3099,13 +3144,16 @@ static int carrier_raised(struct tty_port *port)
return (info->signals & SerialSignal_DCD) ? 1 : 0;
}
-static void raise_dtr_rts(struct tty_port *port)
+static void dtr_rts(struct tty_port *port, int on)
{
unsigned long flags;
struct slgt_info *info = container_of(port, struct slgt_info, port);
spin_lock_irqsave(&info->lock,flags);
- info->signals |= SerialSignal_RTS + SerialSignal_DTR;
+ if (on)
+ info->signals |= SerialSignal_RTS + SerialSignal_DTR;
+ else
+ info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
}
@@ -3419,7 +3467,7 @@ static void add_device(struct slgt_info *info)
static const struct tty_port_operations slgt_port_ops = {
.carrier_raised = carrier_raised,
- .raise_dtr_rts = raise_dtr_rts,
+ .dtr_rts = dtr_rts,
};
/*
@@ -3841,15 +3889,27 @@ static void rx_start(struct slgt_info *info)
rdma_reset(info);
reset_rbufs(info);
- /* set 1st descriptor address */
- wr_reg32(info, RDDAR, info->rbufs[0].pdesc);
-
- if (info->params.mode != MGSL_MODE_ASYNC) {
- /* enable rx DMA and DMA interrupt */
- wr_reg32(info, RDCSR, (BIT2 + BIT0));
+ if (info->rx_pio) {
+ /* rx request when rx FIFO not empty */
+ wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) & ~BIT14));
+ slgt_irq_on(info, IRQ_RXDATA);
+ if (info->params.mode == MGSL_MODE_ASYNC) {
+ /* enable saving of rx status */
+ wr_reg32(info, RDCSR, BIT6);
+ }
} else {
- /* enable saving of rx status, rx DMA and DMA interrupt */
- wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0));
+ /* rx request when rx FIFO half full */
+ wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT14));
+ /* set 1st descriptor address */
+ wr_reg32(info, RDDAR, info->rbufs[0].pdesc);
+
+ if (info->params.mode != MGSL_MODE_ASYNC) {
+ /* enable rx DMA and DMA interrupt */
+ wr_reg32(info, RDCSR, (BIT2 + BIT0));
+ } else {
+ /* enable saving of rx status, rx DMA and DMA interrupt */
+ wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0));
+ }
}
slgt_irq_on(info, IRQ_RXOVER);
@@ -4467,6 +4527,8 @@ static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last
static void reset_rbufs(struct slgt_info *info)
{
free_rbufs(info, 0, info->rbuf_count - 1);
+ info->rbuf_fill_index = 0;
+ info->rbuf_fill_count = 0;
}
/*
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 26de60efe4b2..6f727e3c53ad 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -3277,13 +3277,16 @@ static int carrier_raised(struct tty_port *port)
return (info->serial_signals & SerialSignal_DCD) ? 1 : 0;
}
-static void raise_dtr_rts(struct tty_port *port)
+static void dtr_rts(struct tty_port *port, int on)
{
SLMP_INFO *info = container_of(port, SLMP_INFO, port);
unsigned long flags;
spin_lock_irqsave(&info->lock,flags);
- info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;
+ if (on)
+ info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;
+ else
+ info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
}
@@ -3746,7 +3749,7 @@ static void add_device(SLMP_INFO *info)
static const struct tty_port_operations port_ops = {
.carrier_raised = carrier_raised,
- .raise_dtr_rts = raise_dtr_rts,
+ .dtr_rts = dtr_rts,
};
/* Allocate and initialize a device instance structure
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index ed306eb1057f..0c2f55a38b95 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_bios.c
@@ -212,7 +212,8 @@ static int get_event_name(char *dest, struct tcpa_event *event,
unsigned char * event_entry)
{
const char *name = "";
- char data[40] = "";
+ /* 41 so there is room for 40 data and 1 nul */
+ char data[41] = "";
int i, n_len = 0, d_len = 0;
struct tcpa_pc_event *pc_event;
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 9b8004c72686..4d08b6d27c28 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -137,7 +137,7 @@ int tty_port_carrier_raised(struct tty_port *port)
EXPORT_SYMBOL(tty_port_carrier_raised);
/**
- * tty_port_raise_dtr_rts - Riase DTR/RTS
+ * tty_port_raise_dtr_rts - Raise DTR/RTS
* @port: tty port
*
* Wrapper for the DTR/RTS raise logic. For the moment this is used
@@ -147,12 +147,28 @@ EXPORT_SYMBOL(tty_port_carrier_raised);
void tty_port_raise_dtr_rts(struct tty_port *port)
{
- if (port->ops->raise_dtr_rts)
- port->ops->raise_dtr_rts(port);
+ if (port->ops->dtr_rts)
+ port->ops->dtr_rts(port, 1);
}
EXPORT_SYMBOL(tty_port_raise_dtr_rts);
/**
+ * tty_port_lower_dtr_rts - Lower DTR/RTS
+ * @port: tty port
+ *
+ * Wrapper for the DTR/RTS raise logic. For the moment this is used
+ * to hide some internal details. This will eventually become entirely
+ * internal to the tty port.
+ */
+
+void tty_port_lower_dtr_rts(struct tty_port *port)
+{
+ if (port->ops->dtr_rts)
+ port->ops->dtr_rts(port, 0);
+}
+EXPORT_SYMBOL(tty_port_lower_dtr_rts);
+
+/**
* tty_port_block_til_ready - Waiting logic for tty open
* @port: the tty port being opened
* @tty: the tty device being bound
@@ -167,7 +183,7 @@ EXPORT_SYMBOL(tty_port_raise_dtr_rts);
* - port flags and counts
*
* The passed tty_port must implement the carrier_raised method if it can
- * do carrier detect and the raise_dtr_rts method if it supports software
+ * do carrier detect and the dtr_rts method if it supports software
* management of these lines. Note that the dtr/rts raise is done each
* iteration as a hangup may have previously dropped them while we wait.
*/
@@ -292,6 +308,17 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
if (port->flags & ASYNC_INITIALIZED &&
port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
tty_wait_until_sent(tty, port->closing_wait);
+ if (port->drain_delay) {
+ unsigned int bps = tty_get_baud_rate(tty);
+ long timeout;
+
+ if (bps > 1200)
+ timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps,
+ HZ / 10);
+ else
+ timeout = 2 * HZ;
+ schedule_timeout_interruptible(timeout);
+ }
return 1;
}
EXPORT_SYMBOL(tty_port_close_start);
@@ -302,6 +329,9 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
tty_ldisc_flush(tty);
+ if (tty->termios->c_cflag & HUPCL)
+ tty_port_lower_dtr_rts(port);
+
spin_lock_irqsave(&port->lock, flags);
tty->closing = 0;
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index a2dee0eb6dad..e6ce632a393e 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -400,6 +400,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KIOCSOUND:
if (!perm)
goto eperm;
+ /* FIXME: This is an old broken API but we need to keep it
+ supported and somehow separate the historic advertised
+ tick rate from any real one */
if (arg)
arg = CLOCK_TICK_RATE / arg;
kd_mksound(arg, 0);
@@ -417,6 +420,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/
ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
count = ticks ? (arg & 0xffff) : 0;
+ /* FIXME: This is an old broken API but we need to keep it
+ supported and somehow separate the historic advertised
+ tick rate from any real one */
if (count)
count = CLOCK_TICK_RATE / count;
kd_mksound(count, ticks);
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 1efb2879a94f..eef216f7f61d 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -3,3 +3,5 @@ obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o
obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o
+obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o
+obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 1c92c39a53aa..cf56a2af5fe1 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -18,7 +18,6 @@
*/
#include <linux/init.h>
-#include <linux/bootmem.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
@@ -29,7 +28,7 @@
#include <linux/err.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
-#include <linux/sh_cmt.h>
+#include <linux/sh_timer.h>
struct sh_cmt_priv {
void __iomem *mapbase;
@@ -47,6 +46,7 @@ struct sh_cmt_priv {
unsigned long rate;
spinlock_t lock;
struct clock_event_device ced;
+ struct clocksource cs;
unsigned long total_cycles;
};
@@ -59,7 +59,7 @@ static DEFINE_SPINLOCK(sh_cmt_lock);
static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
{
- struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
void __iomem *base = p->mapbase;
unsigned long offs;
@@ -83,7 +83,7 @@ static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
unsigned long value)
{
- struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
void __iomem *base = p->mapbase;
unsigned long offs;
@@ -110,23 +110,28 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
int *has_wrapped)
{
unsigned long v1, v2, v3;
+ int o1, o2;
+
+ o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
/* Make sure the timer value is stable. Stolen from acpi_pm.c */
do {
+ o2 = o1;
v1 = sh_cmt_read(p, CMCNT);
v2 = sh_cmt_read(p, CMCNT);
v3 = sh_cmt_read(p, CMCNT);
- } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
- || (v3 > v1 && v3 < v2)));
+ o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+ } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
+ || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
- *has_wrapped = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+ *has_wrapped = o1;
return v2;
}
static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
{
- struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
unsigned long flags, value;
/* start stop register shared by multiple timer channels */
@@ -144,7 +149,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
{
- struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
int ret;
/* enable clock */
@@ -153,16 +158,18 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
pr_err("sh_cmt: cannot enable clock \"%s\"\n", cfg->clk);
return ret;
}
- *rate = clk_get_rate(p->clk) / 8;
/* make sure channel is disabled */
sh_cmt_start_stop_ch(p, 0);
/* configure channel, periodic mode and maximum timeout */
- if (p->width == 16)
- sh_cmt_write(p, CMCSR, 0);
- else
+ if (p->width == 16) {
+ *rate = clk_get_rate(p->clk) / 512;
+ sh_cmt_write(p, CMCSR, 0x43);
+ } else {
+ *rate = clk_get_rate(p->clk) / 8;
sh_cmt_write(p, CMCSR, 0x01a4);
+ }
sh_cmt_write(p, CMCOR, 0xffffffff);
sh_cmt_write(p, CMCNT, 0);
@@ -376,6 +383,68 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
spin_unlock_irqrestore(&p->lock, flags);
}
+static struct sh_cmt_priv *cs_to_sh_cmt(struct clocksource *cs)
+{
+ return container_of(cs, struct sh_cmt_priv, cs);
+}
+
+static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
+{
+ struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+ unsigned long flags, raw;
+ unsigned long value;
+ int has_wrapped;
+
+ spin_lock_irqsave(&p->lock, flags);
+ value = p->total_cycles;
+ raw = sh_cmt_get_counter(p, &has_wrapped);
+
+ if (unlikely(has_wrapped))
+ raw += p->match_value;
+ spin_unlock_irqrestore(&p->lock, flags);
+
+ return value + raw;
+}
+
+static int sh_cmt_clocksource_enable(struct clocksource *cs)
+{
+ struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+ int ret;
+
+ p->total_cycles = 0;
+
+ ret = sh_cmt_start(p, FLAG_CLOCKSOURCE);
+ if (ret)
+ return ret;
+
+ /* TODO: calculate good shift from rate and counter bit width */
+ cs->shift = 0;
+ cs->mult = clocksource_hz2mult(p->rate, cs->shift);
+ return 0;
+}
+
+static void sh_cmt_clocksource_disable(struct clocksource *cs)
+{
+ sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
+}
+
+static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
+ char *name, unsigned long rating)
+{
+ struct clocksource *cs = &p->cs;
+
+ cs->name = name;
+ cs->rating = rating;
+ cs->read = sh_cmt_clocksource_read;
+ cs->enable = sh_cmt_clocksource_enable;
+ cs->disable = sh_cmt_clocksource_disable;
+ cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
+ cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
+ pr_info("sh_cmt: %s used as clock source\n", cs->name);
+ clocksource_register(cs);
+ return 0;
+}
+
static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced)
{
return container_of(ced, struct sh_cmt_priv, ced);
@@ -468,9 +537,9 @@ static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
clockevents_register_device(ced);
}
-int sh_cmt_register(struct sh_cmt_priv *p, char *name,
- unsigned long clockevent_rating,
- unsigned long clocksource_rating)
+static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
+ unsigned long clockevent_rating,
+ unsigned long clocksource_rating)
{
if (p->width == (sizeof(p->max_match_value) * 8))
p->max_match_value = ~0;
@@ -483,12 +552,15 @@ int sh_cmt_register(struct sh_cmt_priv *p, char *name,
if (clockevent_rating)
sh_cmt_register_clockevent(p, name, clockevent_rating);
+ if (clocksource_rating)
+ sh_cmt_register_clocksource(p, name, clocksource_rating);
+
return 0;
}
static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
{
- struct sh_cmt_config *cfg = pdev->dev.platform_data;
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
struct resource *res;
int irq, ret;
ret = -ENXIO;
@@ -545,7 +617,7 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
if (resource_size(res) == 6) {
p->width = 16;
p->overflow_bit = 0x80;
- p->clear_bits = ~0xc0;
+ p->clear_bits = ~0x80;
} else {
p->width = 32;
p->overflow_bit = 0x8000;
@@ -566,8 +638,14 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
static int __devinit sh_cmt_probe(struct platform_device *pdev)
{
struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
int ret;
+ if (p) {
+ pr_info("sh_cmt: %s kept as earlytimer\n", cfg->name);
+ return 0;
+ }
+
p = kmalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
@@ -577,7 +655,6 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev)
ret = sh_cmt_setup(p, pdev);
if (ret) {
kfree(p);
-
platform_set_drvdata(pdev, NULL);
}
return ret;
@@ -606,6 +683,7 @@ static void __exit sh_cmt_exit(void)
platform_driver_unregister(&sh_cmt_device_driver);
}
+early_platform_init("earlytimer", &sh_cmt_device_driver);
module_init(sh_cmt_init);
module_exit(sh_cmt_exit);
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
new file mode 100644
index 000000000000..d1ae75454d10
--- /dev/null
+++ b/drivers/clocksource/sh_mtu2.c
@@ -0,0 +1,357 @@
+/*
+ * SuperH Timer Support - MTU2
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * 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
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clockchips.h>
+#include <linux/sh_timer.h>
+
+struct sh_mtu2_priv {
+ void __iomem *mapbase;
+ struct clk *clk;
+ struct irqaction irqaction;
+ struct platform_device *pdev;
+ unsigned long rate;
+ unsigned long periodic;
+ struct clock_event_device ced;
+};
+
+static DEFINE_SPINLOCK(sh_mtu2_lock);
+
+#define TSTR -1 /* shared register */
+#define TCR 0 /* channel register */
+#define TMDR 1 /* channel register */
+#define TIOR 2 /* channel register */
+#define TIER 3 /* channel register */
+#define TSR 4 /* channel register */
+#define TCNT 5 /* channel register */
+#define TGR 6 /* channel register */
+
+static unsigned long mtu2_reg_offs[] = {
+ [TCR] = 0,
+ [TMDR] = 1,
+ [TIOR] = 2,
+ [TIER] = 4,
+ [TSR] = 5,
+ [TCNT] = 6,
+ [TGR] = 8,
+};
+
+static inline unsigned long sh_mtu2_read(struct sh_mtu2_priv *p, int reg_nr)
+{
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+ void __iomem *base = p->mapbase;
+ unsigned long offs;
+
+ if (reg_nr == TSTR)
+ return ioread8(base + cfg->channel_offset);
+
+ offs = mtu2_reg_offs[reg_nr];
+
+ if ((reg_nr == TCNT) || (reg_nr == TGR))
+ return ioread16(base + offs);
+ else
+ return ioread8(base + offs);
+}
+
+static inline void sh_mtu2_write(struct sh_mtu2_priv *p, int reg_nr,
+ unsigned long value)
+{
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+ void __iomem *base = p->mapbase;
+ unsigned long offs;
+
+ if (reg_nr == TSTR) {
+ iowrite8(value, base + cfg->channel_offset);
+ return;
+ }
+
+ offs = mtu2_reg_offs[reg_nr];
+
+ if ((reg_nr == TCNT) || (reg_nr == TGR))
+ iowrite16(value, base + offs);
+ else
+ iowrite8(value, base + offs);
+}
+
+static void sh_mtu2_start_stop_ch(struct sh_mtu2_priv *p, int start)
+{
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+ unsigned long flags, value;
+
+ /* start stop register shared by multiple timer channels */
+ spin_lock_irqsave(&sh_mtu2_lock, flags);
+ value = sh_mtu2_read(p, TSTR);
+
+ if (start)
+ value |= 1 << cfg->timer_bit;
+ else
+ value &= ~(1 << cfg->timer_bit);
+
+ sh_mtu2_write(p, TSTR, value);
+ spin_unlock_irqrestore(&sh_mtu2_lock, flags);
+}
+
+static int sh_mtu2_enable(struct sh_mtu2_priv *p)
+{
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+ int ret;
+
+ /* enable clock */
+ ret = clk_enable(p->clk);
+ if (ret) {
+ pr_err("sh_mtu2: cannot enable clock \"%s\"\n", cfg->clk);
+ return ret;
+ }
+
+ /* make sure channel is disabled */
+ sh_mtu2_start_stop_ch(p, 0);
+
+ p->rate = clk_get_rate(p->clk) / 64;
+ p->periodic = (p->rate + HZ/2) / HZ;
+
+ /* "Periodic Counter Operation" */
+ sh_mtu2_write(p, TCR, 0x23); /* TGRA clear, divide clock by 64 */
+ sh_mtu2_write(p, TIOR, 0);
+ sh_mtu2_write(p, TGR, p->periodic);
+ sh_mtu2_write(p, TCNT, 0);
+ sh_mtu2_write(p, TMDR, 0);
+ sh_mtu2_write(p, TIER, 0x01);
+
+ /* enable channel */
+ sh_mtu2_start_stop_ch(p, 1);
+
+ return 0;
+}
+
+static void sh_mtu2_disable(struct sh_mtu2_priv *p)
+{
+ /* disable channel */
+ sh_mtu2_start_stop_ch(p, 0);
+
+ /* stop clock */
+ clk_disable(p->clk);
+}
+
+static irqreturn_t sh_mtu2_interrupt(int irq, void *dev_id)
+{
+ struct sh_mtu2_priv *p = dev_id;
+
+ /* acknowledge interrupt */
+ sh_mtu2_read(p, TSR);
+ sh_mtu2_write(p, TSR, 0xfe);
+
+ /* notify clockevent layer */
+ p->ced.event_handler(&p->ced);
+ return IRQ_HANDLED;
+}
+
+static struct sh_mtu2_priv *ced_to_sh_mtu2(struct clock_event_device *ced)
+{
+ return container_of(ced, struct sh_mtu2_priv, ced);
+}
+
+static void sh_mtu2_clock_event_mode(enum clock_event_mode mode,
+ struct clock_event_device *ced)
+{
+ struct sh_mtu2_priv *p = ced_to_sh_mtu2(ced);
+ int disabled = 0;
+
+ /* deal with old setting first */
+ switch (ced->mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ sh_mtu2_disable(p);
+ disabled = 1;
+ break;
+ default:
+ break;
+ }
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ pr_info("sh_mtu2: %s used for periodic clock events\n",
+ ced->name);
+ sh_mtu2_enable(p);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ if (!disabled)
+ sh_mtu2_disable(p);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ break;
+ }
+}
+
+static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p,
+ char *name, unsigned long rating)
+{
+ struct clock_event_device *ced = &p->ced;
+ int ret;
+
+ memset(ced, 0, sizeof(*ced));
+
+ ced->name = name;
+ ced->features = CLOCK_EVT_FEAT_PERIODIC;
+ ced->rating = rating;
+ ced->cpumask = cpumask_of(0);
+ ced->set_mode = sh_mtu2_clock_event_mode;
+
+ ret = setup_irq(p->irqaction.irq, &p->irqaction);
+ if (ret) {
+ pr_err("sh_mtu2: failed to request irq %d\n",
+ p->irqaction.irq);
+ return;
+ }
+
+ pr_info("sh_mtu2: %s used for clock events\n", ced->name);
+ clockevents_register_device(ced);
+}
+
+static int sh_mtu2_register(struct sh_mtu2_priv *p, char *name,
+ unsigned long clockevent_rating)
+{
+ if (clockevent_rating)
+ sh_mtu2_register_clockevent(p, name, clockevent_rating);
+
+ return 0;
+}
+
+static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev)
+{
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
+ struct resource *res;
+ int irq, ret;
+ ret = -ENXIO;
+
+ memset(p, 0, sizeof(*p));
+ p->pdev = pdev;
+
+ if (!cfg) {
+ dev_err(&p->pdev->dev, "missing platform data\n");
+ goto err0;
+ }
+
+ platform_set_drvdata(pdev, p);
+
+ res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+ goto err0;
+ }
+
+ irq = platform_get_irq(p->pdev, 0);
+ if (irq < 0) {
+ dev_err(&p->pdev->dev, "failed to get irq\n");
+ goto err0;
+ }
+
+ /* map memory, let mapbase point to our channel */
+ p->mapbase = ioremap_nocache(res->start, resource_size(res));
+ if (p->mapbase == NULL) {
+ pr_err("sh_mtu2: failed to remap I/O memory\n");
+ goto err0;
+ }
+
+ /* setup data for setup_irq() (too early for request_irq()) */
+ p->irqaction.name = cfg->name;
+ p->irqaction.handler = sh_mtu2_interrupt;
+ p->irqaction.dev_id = p;
+ p->irqaction.irq = irq;
+ p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
+ p->irqaction.mask = CPU_MASK_NONE;
+
+ /* get hold of clock */
+ p->clk = clk_get(&p->pdev->dev, cfg->clk);
+ if (IS_ERR(p->clk)) {
+ pr_err("sh_mtu2: cannot get clock \"%s\"\n", cfg->clk);
+ ret = PTR_ERR(p->clk);
+ goto err1;
+ }
+
+ return sh_mtu2_register(p, cfg->name, cfg->clockevent_rating);
+ err1:
+ iounmap(p->mapbase);
+ err0:
+ return ret;
+}
+
+static int __devinit sh_mtu2_probe(struct platform_device *pdev)
+{
+ struct sh_mtu2_priv *p = platform_get_drvdata(pdev);
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
+ int ret;
+
+ if (p) {
+ pr_info("sh_mtu2: %s kept as earlytimer\n", cfg->name);
+ return 0;
+ }
+
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ dev_err(&pdev->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ ret = sh_mtu2_setup(p, pdev);
+ if (ret) {
+ kfree(p);
+ platform_set_drvdata(pdev, NULL);
+ }
+ return ret;
+}
+
+static int __devexit sh_mtu2_remove(struct platform_device *pdev)
+{
+ return -EBUSY; /* cannot unregister clockevent */
+}
+
+static struct platform_driver sh_mtu2_device_driver = {
+ .probe = sh_mtu2_probe,
+ .remove = __devexit_p(sh_mtu2_remove),
+ .driver = {
+ .name = "sh_mtu2",
+ }
+};
+
+static int __init sh_mtu2_init(void)
+{
+ return platform_driver_register(&sh_mtu2_device_driver);
+}
+
+static void __exit sh_mtu2_exit(void)
+{
+ platform_driver_unregister(&sh_mtu2_device_driver);
+}
+
+early_platform_init("earlytimer", &sh_mtu2_device_driver);
+module_init(sh_mtu2_init);
+module_exit(sh_mtu2_exit);
+
+MODULE_AUTHOR("Magnus Damm");
+MODULE_DESCRIPTION("SuperH MTU2 Timer Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
new file mode 100644
index 000000000000..d6ea4398bf62
--- /dev/null
+++ b/drivers/clocksource/sh_tmu.c
@@ -0,0 +1,461 @@
+/*
+ * SuperH Timer Support - TMU
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * 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
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/sh_timer.h>
+
+struct sh_tmu_priv {
+ void __iomem *mapbase;
+ struct clk *clk;
+ struct irqaction irqaction;
+ struct platform_device *pdev;
+ unsigned long rate;
+ unsigned long periodic;
+ struct clock_event_device ced;
+ struct clocksource cs;
+};
+
+static DEFINE_SPINLOCK(sh_tmu_lock);
+
+#define TSTR -1 /* shared register */
+#define TCOR 0 /* channel register */
+#define TCNT 1 /* channel register */
+#define TCR 2 /* channel register */
+
+static inline unsigned long sh_tmu_read(struct sh_tmu_priv *p, int reg_nr)
+{
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+ void __iomem *base = p->mapbase;
+ unsigned long offs;
+
+ if (reg_nr == TSTR)
+ return ioread8(base - cfg->channel_offset);
+
+ offs = reg_nr << 2;
+
+ if (reg_nr == TCR)
+ return ioread16(base + offs);
+ else
+ return ioread32(base + offs);
+}
+
+static inline void sh_tmu_write(struct sh_tmu_priv *p, int reg_nr,
+ unsigned long value)
+{
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+ void __iomem *base = p->mapbase;
+ unsigned long offs;
+
+ if (reg_nr == TSTR) {
+ iowrite8(value, base - cfg->channel_offset);
+ return;
+ }
+
+ offs = reg_nr << 2;
+
+ if (reg_nr == TCR)
+ iowrite16(value, base + offs);
+ else
+ iowrite32(value, base + offs);
+}
+
+static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start)
+{
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+ unsigned long flags, value;
+
+ /* start stop register shared by multiple timer channels */
+ spin_lock_irqsave(&sh_tmu_lock, flags);
+ value = sh_tmu_read(p, TSTR);
+
+ if (start)
+ value |= 1 << cfg->timer_bit;
+ else
+ value &= ~(1 << cfg->timer_bit);
+
+ sh_tmu_write(p, TSTR, value);
+ spin_unlock_irqrestore(&sh_tmu_lock, flags);
+}
+
+static int sh_tmu_enable(struct sh_tmu_priv *p)
+{
+ struct sh_timer_config *cfg = p->pdev->dev.platform_data;
+ int ret;
+
+ /* enable clock */
+ ret = clk_enable(p->clk);
+ if (ret) {
+ pr_err("sh_tmu: cannot enable clock \"%s\"\n", cfg->clk);
+ return ret;
+ }
+
+ /* make sure channel is disabled */
+ sh_tmu_start_stop_ch(p, 0);
+
+ /* maximum timeout */
+ sh_tmu_write(p, TCOR, 0xffffffff);
+ sh_tmu_write(p, TCNT, 0xffffffff);
+
+ /* configure channel to parent clock / 4, irq off */
+ p->rate = clk_get_rate(p->clk) / 4;
+ sh_tmu_write(p, TCR, 0x0000);
+
+ /* enable channel */
+ sh_tmu_start_stop_ch(p, 1);
+
+ return 0;
+}
+
+static void sh_tmu_disable(struct sh_tmu_priv *p)
+{
+ /* disable channel */
+ sh_tmu_start_stop_ch(p, 0);
+
+ /* stop clock */
+ clk_disable(p->clk);
+}
+
+static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta,
+ int periodic)
+{
+ /* stop timer */
+ sh_tmu_start_stop_ch(p, 0);
+
+ /* acknowledge interrupt */
+ sh_tmu_read(p, TCR);
+
+ /* enable interrupt */
+ sh_tmu_write(p, TCR, 0x0020);
+
+ /* reload delta value in case of periodic timer */
+ if (periodic)
+ sh_tmu_write(p, TCOR, delta);
+ else
+ sh_tmu_write(p, TCOR, 0);
+
+ sh_tmu_write(p, TCNT, delta);
+
+ /* start timer */
+ sh_tmu_start_stop_ch(p, 1);
+}
+
+static irqreturn_t sh_tmu_interrupt(int irq, void *dev_id)
+{
+ struct sh_tmu_priv *p = dev_id;
+
+ /* disable or acknowledge interrupt */
+ if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT)
+ sh_tmu_write(p, TCR, 0x0000);
+ else
+ sh_tmu_write(p, TCR, 0x0020);
+
+ /* notify clockevent layer */
+ p->ced.event_handler(&p->ced);
+ return IRQ_HANDLED;
+}
+
+static struct sh_tmu_priv *cs_to_sh_tmu(struct clocksource *cs)
+{
+ return container_of(cs, struct sh_tmu_priv, cs);
+}
+
+static cycle_t sh_tmu_clocksource_read(struct clocksource *cs)
+{
+ struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
+
+ return sh_tmu_read(p, TCNT) ^ 0xffffffff;
+}
+
+static int sh_tmu_clocksource_enable(struct clocksource *cs)
+{
+ struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
+ int ret;
+
+ ret = sh_tmu_enable(p);
+ if (ret)
+ return ret;
+
+ /* TODO: calculate good shift from rate and counter bit width */
+ cs->shift = 10;
+ cs->mult = clocksource_hz2mult(p->rate, cs->shift);
+ return 0;
+}
+
+static void sh_tmu_clocksource_disable(struct clocksource *cs)
+{
+ sh_tmu_disable(cs_to_sh_tmu(cs));
+}
+
+static int sh_tmu_register_clocksource(struct sh_tmu_priv *p,
+ char *name, unsigned long rating)
+{
+ struct clocksource *cs = &p->cs;
+
+ cs->name = name;
+ cs->rating = rating;
+ cs->read = sh_tmu_clocksource_read;
+ cs->enable = sh_tmu_clocksource_enable;
+ cs->disable = sh_tmu_clocksource_disable;
+ cs->mask = CLOCKSOURCE_MASK(32);
+ cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
+ pr_info("sh_tmu: %s used as clock source\n", cs->name);
+ clocksource_register(cs);
+ return 0;
+}
+
+static struct sh_tmu_priv *ced_to_sh_tmu(struct clock_event_device *ced)
+{
+ return container_of(ced, struct sh_tmu_priv, ced);
+}
+
+static void sh_tmu_clock_event_start(struct sh_tmu_priv *p, int periodic)
+{
+ struct clock_event_device *ced = &p->ced;
+
+ sh_tmu_enable(p);
+
+ /* TODO: calculate good shift from rate and counter bit width */
+
+ ced->shift = 32;
+ ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
+ ced->max_delta_ns = clockevent_delta2ns(0xffffffff, ced);
+ ced->min_delta_ns = 5000;
+
+ if (periodic) {
+ p->periodic = (p->rate + HZ/2) / HZ;
+ sh_tmu_set_next(p, p->periodic, 1);
+ }
+}
+
+static void sh_tmu_clock_event_mode(enum clock_event_mode mode,
+ struct clock_event_device *ced)
+{
+ struct sh_tmu_priv *p = ced_to_sh_tmu(ced);
+ int disabled = 0;
+
+ /* deal with old setting first */
+ switch (ced->mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ case CLOCK_EVT_MODE_ONESHOT:
+ sh_tmu_disable(p);
+ disabled = 1;
+ break;
+ default:
+ break;
+ }
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ pr_info("sh_tmu: %s used for periodic clock events\n",
+ ced->name);
+ sh_tmu_clock_event_start(p, 1);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ pr_info("sh_tmu: %s used for oneshot clock events\n",
+ ced->name);
+ sh_tmu_clock_event_start(p, 0);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ if (!disabled)
+ sh_tmu_disable(p);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ break;
+ }
+}
+
+static int sh_tmu_clock_event_next(unsigned long delta,
+ struct clock_event_device *ced)
+{
+ struct sh_tmu_priv *p = ced_to_sh_tmu(ced);
+
+ BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
+
+ /* program new delta value */
+ sh_tmu_set_next(p, delta, 0);
+ return 0;
+}
+
+static void sh_tmu_register_clockevent(struct sh_tmu_priv *p,
+ char *name, unsigned long rating)
+{
+ struct clock_event_device *ced = &p->ced;
+ int ret;
+
+ memset(ced, 0, sizeof(*ced));
+
+ ced->name = name;
+ ced->features = CLOCK_EVT_FEAT_PERIODIC;
+ ced->features |= CLOCK_EVT_FEAT_ONESHOT;
+ ced->rating = rating;
+ ced->cpumask = cpumask_of(0);
+ ced->set_next_event = sh_tmu_clock_event_next;
+ ced->set_mode = sh_tmu_clock_event_mode;
+
+ ret = setup_irq(p->irqaction.irq, &p->irqaction);
+ if (ret) {
+ pr_err("sh_tmu: failed to request irq %d\n",
+ p->irqaction.irq);
+ return;
+ }
+
+ pr_info("sh_tmu: %s used for clock events\n", ced->name);
+ clockevents_register_device(ced);
+}
+
+static int sh_tmu_register(struct sh_tmu_priv *p, char *name,
+ unsigned long clockevent_rating,
+ unsigned long clocksource_rating)
+{
+ if (clockevent_rating)
+ sh_tmu_register_clockevent(p, name, clockevent_rating);
+ else if (clocksource_rating)
+ sh_tmu_register_clocksource(p, name, clocksource_rating);
+
+ return 0;
+}
+
+static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev)
+{
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
+ struct resource *res;
+ int irq, ret;
+ ret = -ENXIO;
+
+ memset(p, 0, sizeof(*p));
+ p->pdev = pdev;
+
+ if (!cfg) {
+ dev_err(&p->pdev->dev, "missing platform data\n");
+ goto err0;
+ }
+
+ platform_set_drvdata(pdev, p);
+
+ res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+ goto err0;
+ }
+
+ irq = platform_get_irq(p->pdev, 0);
+ if (irq < 0) {
+ dev_err(&p->pdev->dev, "failed to get irq\n");
+ goto err0;
+ }
+
+ /* map memory, let mapbase point to our channel */
+ p->mapbase = ioremap_nocache(res->start, resource_size(res));
+ if (p->mapbase == NULL) {
+ pr_err("sh_tmu: failed to remap I/O memory\n");
+ goto err0;
+ }
+
+ /* setup data for setup_irq() (too early for request_irq()) */
+ p->irqaction.name = cfg->name;
+ p->irqaction.handler = sh_tmu_interrupt;
+ p->irqaction.dev_id = p;
+ p->irqaction.irq = irq;
+ p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
+ p->irqaction.mask = CPU_MASK_NONE;
+
+ /* get hold of clock */
+ p->clk = clk_get(&p->pdev->dev, cfg->clk);
+ if (IS_ERR(p->clk)) {
+ pr_err("sh_tmu: cannot get clock \"%s\"\n", cfg->clk);
+ ret = PTR_ERR(p->clk);
+ goto err1;
+ }
+
+ return sh_tmu_register(p, cfg->name,
+ cfg->clockevent_rating,
+ cfg->clocksource_rating);
+ err1:
+ iounmap(p->mapbase);
+ err0:
+ return ret;
+}
+
+static int __devinit sh_tmu_probe(struct platform_device *pdev)
+{
+ struct sh_tmu_priv *p = platform_get_drvdata(pdev);
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
+ int ret;
+
+ if (p) {
+ pr_info("sh_tmu: %s kept as earlytimer\n", cfg->name);
+ return 0;
+ }
+
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ dev_err(&pdev->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ ret = sh_tmu_setup(p, pdev);
+ if (ret) {
+ kfree(p);
+ platform_set_drvdata(pdev, NULL);
+ }
+ return ret;
+}
+
+static int __devexit sh_tmu_remove(struct platform_device *pdev)
+{
+ return -EBUSY; /* cannot unregister clockevent and clocksource */
+}
+
+static struct platform_driver sh_tmu_device_driver = {
+ .probe = sh_tmu_probe,
+ .remove = __devexit_p(sh_tmu_remove),
+ .driver = {
+ .name = "sh_tmu",
+ }
+};
+
+static int __init sh_tmu_init(void)
+{
+ return platform_driver_register(&sh_tmu_device_driver);
+}
+
+static void __exit sh_tmu_exit(void)
+{
+ platform_driver_unregister(&sh_tmu_device_driver);
+}
+
+early_platform_init("earlytimer", &sh_tmu_device_driver);
+module_init(sh_tmu_init);
+module_exit(sh_tmu_exit);
+
+MODULE_AUTHOR("Magnus Damm");
+MODULE_DESCRIPTION("SuperH TMU Timer Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 01afd758072f..e748e55bd86b 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -12,7 +12,7 @@ if CRYPTO_HW
config CRYPTO_DEV_PADLOCK
tristate "Support for VIA PadLock ACE"
- depends on X86_32 && !UML
+ depends on X86 && !UML
select CRYPTO_ALGAPI
help
Some VIA processors come with an integrated crypto engine
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index f9f05d7a707d..6c6656d3b1e2 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -415,6 +415,7 @@ static void crypto_done_action(unsigned long arg)
static int init_ixp_crypto(void)
{
int ret = -ENODEV;
+ u32 msg[2] = { 0, 0 };
if (! ( ~(*IXP4XX_EXP_CFG2) & (IXP4XX_FEATURE_HASH |
IXP4XX_FEATURE_AES | IXP4XX_FEATURE_DES))) {
@@ -426,9 +427,35 @@ static int init_ixp_crypto(void)
return ret;
if (!npe_running(npe_c)) {
- npe_load_firmware(npe_c, npe_name(npe_c), dev);
+ ret = npe_load_firmware(npe_c, npe_name(npe_c), dev);
+ if (ret) {
+ return ret;
+ }
+ if (npe_recv_message(npe_c, msg, "STATUS_MSG"))
+ goto npe_error;
+ } else {
+ if (npe_send_message(npe_c, msg, "STATUS_MSG"))
+ goto npe_error;
+
+ if (npe_recv_message(npe_c, msg, "STATUS_MSG"))
+ goto npe_error;
}
+ switch ((msg[1]>>16) & 0xff) {
+ case 3:
+ printk(KERN_WARNING "Firmware of %s lacks AES support\n",
+ npe_name(npe_c));
+ support_aes = 0;
+ break;
+ case 4:
+ case 5:
+ support_aes = 1;
+ break;
+ default:
+ printk(KERN_ERR "Firmware of %s lacks crypto support\n",
+ npe_name(npe_c));
+ return -ENODEV;
+ }
/* buffer_pool will also be used to sometimes store the hmac,
* so assure it is large enough
*/
@@ -459,6 +486,10 @@ static int init_ixp_crypto(void)
qmgr_enable_irq(RECV_QID);
return 0;
+
+npe_error:
+ printk(KERN_ERR "%s not responding\n", npe_name(npe_c));
+ ret = -EIO;
err:
if (ctx_pool)
dma_pool_destroy(ctx_pool);
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index 3f0fdd18255d..87f92c39b5f0 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -154,7 +154,11 @@ static inline void padlock_reset_key(struct cword *cword)
int cpu = raw_smp_processor_id();
if (cword != per_cpu(last_cword, cpu))
+#ifndef CONFIG_X86_64
asm volatile ("pushfl; popfl");
+#else
+ asm volatile ("pushfq; popfq");
+#endif
}
static inline void padlock_store_cword(struct cword *cword)
@@ -208,10 +212,19 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
asm volatile ("test $1, %%cl;"
"je 1f;"
+#ifndef CONFIG_X86_64
"lea -1(%%ecx), %%eax;"
"mov $1, %%ecx;"
+#else
+ "lea -1(%%rcx), %%rax;"
+ "mov $1, %%rcx;"
+#endif
".byte 0xf3,0x0f,0xa7,0xc8;" /* rep xcryptecb */
+#ifndef CONFIG_X86_64
"mov %%eax, %%ecx;"
+#else
+ "mov %%rax, %%rcx;"
+#endif
"1:"
".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */
: "+S"(input), "+D"(output)
@@ -489,4 +502,4 @@ MODULE_DESCRIPTION("VIA PadLock AES algorithm support");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Michal Ludvig");
-MODULE_ALIAS("aes-all");
+MODULE_ALIAS("aes");
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index a3918c16b3db..c70775fd3ce2 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -44,6 +44,8 @@
#include <crypto/sha.h>
#include <crypto/aead.h>
#include <crypto/authenc.h>
+#include <crypto/skcipher.h>
+#include <crypto/scatterwalk.h>
#include "talitos.h"
@@ -339,7 +341,8 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
status = error;
dma_unmap_single(dev, request->dma_desc,
- sizeof(struct talitos_desc), DMA_BIDIRECTIONAL);
+ sizeof(struct talitos_desc),
+ DMA_BIDIRECTIONAL);
/* copy entries so we can call callback outside lock */
saved_req.desc = request->desc;
@@ -413,7 +416,8 @@ static struct talitos_desc *current_desc(struct device *dev, int ch)
/*
* user diagnostics; report root cause of error based on execution unit status
*/
-static void report_eu_error(struct device *dev, int ch, struct talitos_desc *desc)
+static void report_eu_error(struct device *dev, int ch,
+ struct talitos_desc *desc)
{
struct talitos_private *priv = dev_get_drvdata(dev);
int i;
@@ -684,8 +688,8 @@ struct talitos_ctx {
unsigned int authsize;
};
-static int aead_authenc_setauthsize(struct crypto_aead *authenc,
- unsigned int authsize)
+static int aead_setauthsize(struct crypto_aead *authenc,
+ unsigned int authsize)
{
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
@@ -694,8 +698,8 @@ static int aead_authenc_setauthsize(struct crypto_aead *authenc,
return 0;
}
-static int aead_authenc_setkey(struct crypto_aead *authenc,
- const u8 *key, unsigned int keylen)
+static int aead_setkey(struct crypto_aead *authenc,
+ const u8 *key, unsigned int keylen)
{
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
struct rtattr *rta = (void *)key;
@@ -740,7 +744,7 @@ badkey:
}
/*
- * ipsec_esp_edesc - s/w-extended ipsec_esp descriptor
+ * talitos_edesc - s/w-extended descriptor
* @src_nents: number of segments in input scatterlist
* @dst_nents: number of segments in output scatterlist
* @dma_len: length of dma mapped link_tbl space
@@ -752,17 +756,67 @@ badkey:
* is greater than 1, an integrity check value is concatenated to the end
* of link_tbl data
*/
-struct ipsec_esp_edesc {
+struct talitos_edesc {
int src_nents;
int dst_nents;
+ int src_is_chained;
+ int dst_is_chained;
int dma_len;
dma_addr_t dma_link_tbl;
struct talitos_desc desc;
struct talitos_ptr link_tbl[0];
};
+static int talitos_map_sg(struct device *dev, struct scatterlist *sg,
+ unsigned int nents, enum dma_data_direction dir,
+ int chained)
+{
+ if (unlikely(chained))
+ while (sg) {
+ dma_map_sg(dev, sg, 1, dir);
+ sg = scatterwalk_sg_next(sg);
+ }
+ else
+ dma_map_sg(dev, sg, nents, dir);
+ return nents;
+}
+
+static void talitos_unmap_sg_chain(struct device *dev, struct scatterlist *sg,
+ enum dma_data_direction dir)
+{
+ while (sg) {
+ dma_unmap_sg(dev, sg, 1, dir);
+ sg = scatterwalk_sg_next(sg);
+ }
+}
+
+static void talitos_sg_unmap(struct device *dev,
+ struct talitos_edesc *edesc,
+ struct scatterlist *src,
+ struct scatterlist *dst)
+{
+ unsigned int src_nents = edesc->src_nents ? : 1;
+ unsigned int dst_nents = edesc->dst_nents ? : 1;
+
+ if (src != dst) {
+ if (edesc->src_is_chained)
+ talitos_unmap_sg_chain(dev, src, DMA_TO_DEVICE);
+ else
+ dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
+
+ if (edesc->dst_is_chained)
+ talitos_unmap_sg_chain(dev, dst, DMA_FROM_DEVICE);
+ else
+ dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
+ } else
+ if (edesc->src_is_chained)
+ talitos_unmap_sg_chain(dev, src, DMA_BIDIRECTIONAL);
+ else
+ dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
+}
+
static void ipsec_esp_unmap(struct device *dev,
- struct ipsec_esp_edesc *edesc,
+ struct talitos_edesc *edesc,
struct aead_request *areq)
{
unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6], DMA_FROM_DEVICE);
@@ -772,15 +826,7 @@ static void ipsec_esp_unmap(struct device *dev,
dma_unmap_sg(dev, areq->assoc, 1, DMA_TO_DEVICE);
- if (areq->src != areq->dst) {
- dma_unmap_sg(dev, areq->src, edesc->src_nents ? : 1,
- DMA_TO_DEVICE);
- dma_unmap_sg(dev, areq->dst, edesc->dst_nents ? : 1,
- DMA_FROM_DEVICE);
- } else {
- dma_unmap_sg(dev, areq->src, edesc->src_nents ? : 1,
- DMA_BIDIRECTIONAL);
- }
+ talitos_sg_unmap(dev, edesc, areq->src, areq->dst);
if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
@@ -795,13 +841,14 @@ static void ipsec_esp_encrypt_done(struct device *dev,
int err)
{
struct aead_request *areq = context;
- struct ipsec_esp_edesc *edesc =
- container_of(desc, struct ipsec_esp_edesc, desc);
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
+ struct talitos_edesc *edesc;
struct scatterlist *sg;
void *icvdata;
+ edesc = container_of(desc, struct talitos_edesc, desc);
+
ipsec_esp_unmap(dev, edesc, areq);
/* copy the generated ICV to dst */
@@ -819,17 +866,18 @@ static void ipsec_esp_encrypt_done(struct device *dev,
}
static void ipsec_esp_decrypt_swauth_done(struct device *dev,
- struct talitos_desc *desc, void *context,
- int err)
+ struct talitos_desc *desc,
+ void *context, int err)
{
struct aead_request *req = context;
- struct ipsec_esp_edesc *edesc =
- container_of(desc, struct ipsec_esp_edesc, desc);
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
+ struct talitos_edesc *edesc;
struct scatterlist *sg;
void *icvdata;
+ edesc = container_of(desc, struct talitos_edesc, desc);
+
ipsec_esp_unmap(dev, edesc, req);
if (!err) {
@@ -851,20 +899,20 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev,
}
static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
- struct talitos_desc *desc, void *context,
- int err)
+ struct talitos_desc *desc,
+ void *context, int err)
{
struct aead_request *req = context;
- struct ipsec_esp_edesc *edesc =
- container_of(desc, struct ipsec_esp_edesc, desc);
+ struct talitos_edesc *edesc;
+
+ edesc = container_of(desc, struct talitos_edesc, desc);
ipsec_esp_unmap(dev, edesc, req);
/* check ICV auth status */
- if (!err)
- if ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
- DESC_HDR_LO_ICCR1_PASS)
- err = -EBADMSG;
+ if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
+ DESC_HDR_LO_ICCR1_PASS))
+ err = -EBADMSG;
kfree(edesc);
@@ -886,7 +934,7 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
link_tbl_ptr->j_extent = 0;
link_tbl_ptr++;
cryptlen -= sg_dma_len(sg);
- sg = sg_next(sg);
+ sg = scatterwalk_sg_next(sg);
}
/* adjust (decrease) last one (or two) entry's len to cryptlen */
@@ -910,7 +958,7 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
/*
* fill in and submit ipsec_esp descriptor
*/
-static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
+static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
u8 *giv, u64 seq,
void (*callback) (struct device *dev,
struct talitos_desc *desc,
@@ -952,32 +1000,31 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
desc->ptr[4].len = cpu_to_be16(cryptlen);
desc->ptr[4].j_extent = authsize;
- if (areq->src == areq->dst)
- sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ? : 1,
- DMA_BIDIRECTIONAL);
- else
- sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ? : 1,
- DMA_TO_DEVICE);
+ sg_count = talitos_map_sg(dev, areq->src, edesc->src_nents ? : 1,
+ (areq->src == areq->dst) ? DMA_BIDIRECTIONAL
+ : DMA_TO_DEVICE,
+ edesc->src_is_chained);
if (sg_count == 1) {
desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src));
} else {
sg_link_tbl_len = cryptlen;
- if ((edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV) &&
- (edesc->desc.hdr & DESC_HDR_MODE0_ENCRYPT) == 0) {
+ if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV)
sg_link_tbl_len = cryptlen + authsize;
- }
+
sg_count = sg_to_link_tbl(areq->src, sg_count, sg_link_tbl_len,
&edesc->link_tbl[0]);
if (sg_count > 1) {
desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl);
- dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
- edesc->dma_len, DMA_BIDIRECTIONAL);
+ dma_sync_single_for_device(dev, edesc->dma_link_tbl,
+ edesc->dma_len,
+ DMA_BIDIRECTIONAL);
} else {
/* Only one segment now, so no link tbl needed */
- desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src));
+ desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->
+ src));
}
}
@@ -985,10 +1032,11 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
desc->ptr[5].len = cpu_to_be16(cryptlen);
desc->ptr[5].j_extent = authsize;
- if (areq->src != areq->dst) {
- sg_count = dma_map_sg(dev, areq->dst, edesc->dst_nents ? : 1,
- DMA_FROM_DEVICE);
- }
+ if (areq->src != areq->dst)
+ sg_count = talitos_map_sg(dev, areq->dst,
+ edesc->dst_nents ? : 1,
+ DMA_FROM_DEVICE,
+ edesc->dst_is_chained);
if (sg_count == 1) {
desc->ptr[5].ptr = cpu_to_be32(sg_dma_address(areq->dst));
@@ -1033,49 +1081,55 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
return ret;
}
-
/*
* derive number of elements in scatterlist
*/
-static int sg_count(struct scatterlist *sg_list, int nbytes)
+static int sg_count(struct scatterlist *sg_list, int nbytes, int *chained)
{
struct scatterlist *sg = sg_list;
int sg_nents = 0;
- while (nbytes) {
+ *chained = 0;
+ while (nbytes > 0) {
sg_nents++;
nbytes -= sg->length;
- sg = sg_next(sg);
+ if (!sg_is_last(sg) && (sg + 1)->length == 0)
+ *chained = 1;
+ sg = scatterwalk_sg_next(sg);
}
return sg_nents;
}
/*
- * allocate and map the ipsec_esp extended descriptor
+ * allocate and map the extended descriptor
*/
-static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq,
- int icv_stashing)
+static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
+ struct scatterlist *src,
+ struct scatterlist *dst,
+ unsigned int cryptlen,
+ unsigned int authsize,
+ int icv_stashing,
+ u32 cryptoflags)
{
- struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
- struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
- struct ipsec_esp_edesc *edesc;
+ struct talitos_edesc *edesc;
int src_nents, dst_nents, alloc_len, dma_len;
- gfp_t flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
+ int src_chained, dst_chained = 0;
+ gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
GFP_ATOMIC;
- if (areq->cryptlen + ctx->authsize > TALITOS_MAX_DATA_LEN) {
- dev_err(ctx->dev, "cryptlen exceeds h/w max limit\n");
+ if (cryptlen + authsize > TALITOS_MAX_DATA_LEN) {
+ dev_err(dev, "length exceeds h/w max limit\n");
return ERR_PTR(-EINVAL);
}
- src_nents = sg_count(areq->src, areq->cryptlen + ctx->authsize);
+ src_nents = sg_count(src, cryptlen + authsize, &src_chained);
src_nents = (src_nents == 1) ? 0 : src_nents;
- if (areq->dst == areq->src) {
+ if (dst == src) {
dst_nents = src_nents;
} else {
- dst_nents = sg_count(areq->dst, areq->cryptlen + ctx->authsize);
+ dst_nents = sg_count(dst, cryptlen + authsize, &dst_chained);
dst_nents = (dst_nents == 1) ? 0 : dst_nents;
}
@@ -1084,39 +1138,52 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq,
* allowing for two separate entries for ICV and generated ICV (+ 2),
* and the ICV data itself
*/
- alloc_len = sizeof(struct ipsec_esp_edesc);
+ alloc_len = sizeof(struct talitos_edesc);
if (src_nents || dst_nents) {
dma_len = (src_nents + dst_nents + 2) *
- sizeof(struct talitos_ptr) + ctx->authsize;
+ sizeof(struct talitos_ptr) + authsize;
alloc_len += dma_len;
} else {
dma_len = 0;
- alloc_len += icv_stashing ? ctx->authsize : 0;
+ alloc_len += icv_stashing ? authsize : 0;
}
edesc = kmalloc(alloc_len, GFP_DMA | flags);
if (!edesc) {
- dev_err(ctx->dev, "could not allocate edescriptor\n");
+ dev_err(dev, "could not allocate edescriptor\n");
return ERR_PTR(-ENOMEM);
}
edesc->src_nents = src_nents;
edesc->dst_nents = dst_nents;
+ edesc->src_is_chained = src_chained;
+ edesc->dst_is_chained = dst_chained;
edesc->dma_len = dma_len;
- edesc->dma_link_tbl = dma_map_single(ctx->dev, &edesc->link_tbl[0],
+ edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
edesc->dma_len, DMA_BIDIRECTIONAL);
return edesc;
}
-static int aead_authenc_encrypt(struct aead_request *req)
+static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq,
+ int icv_stashing)
+{
+ struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
+
+ return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
+ areq->cryptlen, ctx->authsize, icv_stashing,
+ areq->base.flags);
+}
+
+static int aead_encrypt(struct aead_request *req)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
- struct ipsec_esp_edesc *edesc;
+ struct talitos_edesc *edesc;
/* allocate extended descriptor */
- edesc = ipsec_esp_edesc_alloc(req, 0);
+ edesc = aead_edesc_alloc(req, 0);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
@@ -1126,70 +1193,67 @@ static int aead_authenc_encrypt(struct aead_request *req)
return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_encrypt_done);
}
-
-
-static int aead_authenc_decrypt(struct aead_request *req)
+static int aead_decrypt(struct aead_request *req)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
unsigned int authsize = ctx->authsize;
struct talitos_private *priv = dev_get_drvdata(ctx->dev);
- struct ipsec_esp_edesc *edesc;
+ struct talitos_edesc *edesc;
struct scatterlist *sg;
void *icvdata;
req->cryptlen -= authsize;
/* allocate extended descriptor */
- edesc = ipsec_esp_edesc_alloc(req, 1);
+ edesc = aead_edesc_alloc(req, 1);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
- (((!edesc->src_nents && !edesc->dst_nents) ||
- priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT))) {
+ ((!edesc->src_nents && !edesc->dst_nents) ||
+ priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
/* decrypt and check the ICV */
- edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND |
+ edesc->desc.hdr = ctx->desc_hdr_template |
+ DESC_HDR_DIR_INBOUND |
DESC_HDR_MODE1_MDEU_CICV;
/* reset integrity check result bits */
edesc->desc.hdr_lo = 0;
- return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_hwauth_done);
+ return ipsec_esp(edesc, req, NULL, 0,
+ ipsec_esp_decrypt_hwauth_done);
- } else {
-
- /* Have to check the ICV with software */
+ }
- edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
+ /* Have to check the ICV with software */
+ edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
- /* stash incoming ICV for later cmp with ICV generated by the h/w */
- if (edesc->dma_len)
- icvdata = &edesc->link_tbl[edesc->src_nents +
- edesc->dst_nents + 2];
- else
- icvdata = &edesc->link_tbl[0];
+ /* stash incoming ICV for later cmp with ICV generated by the h/w */
+ if (edesc->dma_len)
+ icvdata = &edesc->link_tbl[edesc->src_nents +
+ edesc->dst_nents + 2];
+ else
+ icvdata = &edesc->link_tbl[0];
- sg = sg_last(req->src, edesc->src_nents ? : 1);
+ sg = sg_last(req->src, edesc->src_nents ? : 1);
- memcpy(icvdata, (char *)sg_virt(sg) + sg->length - ctx->authsize,
- ctx->authsize);
+ memcpy(icvdata, (char *)sg_virt(sg) + sg->length - ctx->authsize,
+ ctx->authsize);
- return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_swauth_done);
- }
+ return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_swauth_done);
}
-static int aead_authenc_givencrypt(
- struct aead_givcrypt_request *req)
+static int aead_givencrypt(struct aead_givcrypt_request *req)
{
struct aead_request *areq = &req->areq;
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
- struct ipsec_esp_edesc *edesc;
+ struct talitos_edesc *edesc;
/* allocate extended descriptor */
- edesc = ipsec_esp_edesc_alloc(areq, 0);
+ edesc = aead_edesc_alloc(areq, 0);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
@@ -1204,31 +1268,228 @@ static int aead_authenc_givencrypt(
ipsec_esp_encrypt_done);
}
+static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
+ const u8 *key, unsigned int keylen)
+{
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ struct ablkcipher_alg *alg = crypto_ablkcipher_alg(cipher);
+
+ if (keylen > TALITOS_MAX_KEY_SIZE)
+ goto badkey;
+
+ if (keylen < alg->min_keysize || keylen > alg->max_keysize)
+ goto badkey;
+
+ memcpy(&ctx->key, key, keylen);
+ ctx->keylen = keylen;
+
+ return 0;
+
+badkey:
+ crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+}
+
+static void common_nonsnoop_unmap(struct device *dev,
+ struct talitos_edesc *edesc,
+ struct ablkcipher_request *areq)
+{
+ unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
+ unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
+ unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
+
+ talitos_sg_unmap(dev, edesc, areq->src, areq->dst);
+
+ if (edesc->dma_len)
+ dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
+ DMA_BIDIRECTIONAL);
+}
+
+static void ablkcipher_done(struct device *dev,
+ struct talitos_desc *desc, void *context,
+ int err)
+{
+ struct ablkcipher_request *areq = context;
+ struct talitos_edesc *edesc;
+
+ edesc = container_of(desc, struct talitos_edesc, desc);
+
+ common_nonsnoop_unmap(dev, edesc, areq);
+
+ kfree(edesc);
+
+ areq->base.complete(&areq->base, err);
+}
+
+static int common_nonsnoop(struct talitos_edesc *edesc,
+ struct ablkcipher_request *areq,
+ u8 *giv,
+ void (*callback) (struct device *dev,
+ struct talitos_desc *desc,
+ void *context, int error))
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ struct device *dev = ctx->dev;
+ struct talitos_desc *desc = &edesc->desc;
+ unsigned int cryptlen = areq->nbytes;
+ unsigned int ivsize;
+ int sg_count, ret;
+
+ /* first DWORD empty */
+ desc->ptr[0].len = 0;
+ desc->ptr[0].ptr = 0;
+ desc->ptr[0].j_extent = 0;
+
+ /* cipher iv */
+ ivsize = crypto_ablkcipher_ivsize(cipher);
+ map_single_talitos_ptr(dev, &desc->ptr[1], ivsize, giv ?: areq->info, 0,
+ DMA_TO_DEVICE);
+
+ /* cipher key */
+ map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
+ (char *)&ctx->key, 0, DMA_TO_DEVICE);
+
+ /*
+ * cipher in
+ */
+ desc->ptr[3].len = cpu_to_be16(cryptlen);
+ desc->ptr[3].j_extent = 0;
+
+ sg_count = talitos_map_sg(dev, areq->src, edesc->src_nents ? : 1,
+ (areq->src == areq->dst) ? DMA_BIDIRECTIONAL
+ : DMA_TO_DEVICE,
+ edesc->src_is_chained);
+
+ if (sg_count == 1) {
+ desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
+ } else {
+ sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen,
+ &edesc->link_tbl[0]);
+ if (sg_count > 1) {
+ desc->ptr[3].j_extent |= DESC_PTR_LNKTBL_JUMP;
+ desc->ptr[3].ptr = cpu_to_be32(edesc->dma_link_tbl);
+ dma_sync_single_for_device(dev, edesc->dma_link_tbl,
+ edesc->dma_len,
+ DMA_BIDIRECTIONAL);
+ } else {
+ /* Only one segment now, so no link tbl needed */
+ desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->
+ src));
+ }
+ }
+
+ /* cipher out */
+ desc->ptr[4].len = cpu_to_be16(cryptlen);
+ desc->ptr[4].j_extent = 0;
+
+ if (areq->src != areq->dst)
+ sg_count = talitos_map_sg(dev, areq->dst,
+ edesc->dst_nents ? : 1,
+ DMA_FROM_DEVICE,
+ edesc->dst_is_chained);
+
+ if (sg_count == 1) {
+ desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->dst));
+ } else {
+ struct talitos_ptr *link_tbl_ptr =
+ &edesc->link_tbl[edesc->src_nents + 1];
+
+ desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
+ desc->ptr[4].ptr = cpu_to_be32((struct talitos_ptr *)
+ edesc->dma_link_tbl +
+ edesc->src_nents + 1);
+ sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen,
+ link_tbl_ptr);
+ dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
+ edesc->dma_len, DMA_BIDIRECTIONAL);
+ }
+
+ /* iv out */
+ map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv, 0,
+ DMA_FROM_DEVICE);
+
+ /* last DWORD empty */
+ desc->ptr[6].len = 0;
+ desc->ptr[6].ptr = 0;
+ desc->ptr[6].j_extent = 0;
+
+ ret = talitos_submit(dev, desc, callback, areq);
+ if (ret != -EINPROGRESS) {
+ common_nonsnoop_unmap(dev, edesc, areq);
+ kfree(edesc);
+ }
+ return ret;
+}
+
+static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
+ areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, areq->nbytes,
+ 0, 0, areq->base.flags);
+}
+
+static int ablkcipher_encrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ struct talitos_edesc *edesc;
+
+ /* allocate extended descriptor */
+ edesc = ablkcipher_edesc_alloc(areq);
+ if (IS_ERR(edesc))
+ return PTR_ERR(edesc);
+
+ /* set encrypt */
+ edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
+
+ return common_nonsnoop(edesc, areq, NULL, ablkcipher_done);
+}
+
+static int ablkcipher_decrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ struct talitos_edesc *edesc;
+
+ /* allocate extended descriptor */
+ edesc = ablkcipher_edesc_alloc(areq);
+ if (IS_ERR(edesc))
+ return PTR_ERR(edesc);
+
+ edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
+
+ return common_nonsnoop(edesc, areq, NULL, ablkcipher_done);
+}
+
struct talitos_alg_template {
- char name[CRYPTO_MAX_ALG_NAME];
- char driver_name[CRYPTO_MAX_ALG_NAME];
- unsigned int blocksize;
- struct aead_alg aead;
- struct device *dev;
+ struct crypto_alg alg;
__be32 desc_hdr_template;
};
static struct talitos_alg_template driver_algs[] = {
- /* single-pass ipsec_esp descriptor */
+ /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
{
- .name = "authenc(hmac(sha1),cbc(aes))",
- .driver_name = "authenc-hmac-sha1-cbc-aes-talitos",
- .blocksize = AES_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = AES_BLOCK_SIZE,
- .maxauthsize = SHA1_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(sha1),cbc(aes))",
+ .cra_driver_name = "authenc-hmac-sha1-cbc-aes-talitos",
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = SHA1_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_AESU |
DESC_HDR_MODE0_AESU_CBC |
@@ -1238,19 +1499,23 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_SHA1_HMAC,
},
{
- .name = "authenc(hmac(sha1),cbc(des3_ede))",
- .driver_name = "authenc-hmac-sha1-cbc-3des-talitos",
- .blocksize = DES3_EDE_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = DES3_EDE_BLOCK_SIZE,
- .maxauthsize = SHA1_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(sha1),cbc(des3_ede))",
+ .cra_driver_name = "authenc-hmac-sha1-cbc-3des-talitos",
+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ .maxauthsize = SHA1_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_DEU |
DESC_HDR_MODE0_DEU_CBC |
@@ -1261,19 +1526,23 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_SHA1_HMAC,
},
{
- .name = "authenc(hmac(sha256),cbc(aes))",
- .driver_name = "authenc-hmac-sha256-cbc-aes-talitos",
- .blocksize = AES_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = AES_BLOCK_SIZE,
- .maxauthsize = SHA256_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(sha256),cbc(aes))",
+ .cra_driver_name = "authenc-hmac-sha256-cbc-aes-talitos",
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = SHA256_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_AESU |
DESC_HDR_MODE0_AESU_CBC |
@@ -1283,19 +1552,23 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_SHA256_HMAC,
},
{
- .name = "authenc(hmac(sha256),cbc(des3_ede))",
- .driver_name = "authenc-hmac-sha256-cbc-3des-talitos",
- .blocksize = DES3_EDE_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = DES3_EDE_BLOCK_SIZE,
- .maxauthsize = SHA256_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(sha256),cbc(des3_ede))",
+ .cra_driver_name = "authenc-hmac-sha256-cbc-3des-talitos",
+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ .maxauthsize = SHA256_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_DEU |
DESC_HDR_MODE0_DEU_CBC |
@@ -1306,19 +1579,23 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_SHA256_HMAC,
},
{
- .name = "authenc(hmac(md5),cbc(aes))",
- .driver_name = "authenc-hmac-md5-cbc-aes-talitos",
- .blocksize = AES_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = AES_BLOCK_SIZE,
- .maxauthsize = MD5_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(md5),cbc(aes))",
+ .cra_driver_name = "authenc-hmac-md5-cbc-aes-talitos",
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = MD5_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_AESU |
DESC_HDR_MODE0_AESU_CBC |
@@ -1328,19 +1605,23 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_MD5_HMAC,
},
{
- .name = "authenc(hmac(md5),cbc(des3_ede))",
- .driver_name = "authenc-hmac-md5-cbc-3des-talitos",
- .blocksize = DES3_EDE_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = DES3_EDE_BLOCK_SIZE,
- .maxauthsize = MD5_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
+ .cra_driver_name = "authenc-hmac-md5-cbc-3des-talitos",
+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ .maxauthsize = MD5_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_DEU |
DESC_HDR_MODE0_DEU_CBC |
@@ -1349,6 +1630,52 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_INIT |
DESC_HDR_MODE1_MDEU_PAD |
DESC_HDR_MODE1_MDEU_MD5_HMAC,
+ },
+ /* ABLKCIPHER algorithms. */
+ {
+ .alg = {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-talitos",
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+ CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_ablkcipher = {
+ .setkey = ablkcipher_setkey,
+ .encrypt = ablkcipher_encrypt,
+ .decrypt = ablkcipher_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_AESU |
+ DESC_HDR_MODE0_AESU_CBC,
+ },
+ {
+ .alg = {
+ .cra_name = "cbc(des3_ede)",
+ .cra_driver_name = "cbc-3des-talitos",
+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+ CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_ablkcipher = {
+ .setkey = ablkcipher_setkey,
+ .encrypt = ablkcipher_encrypt,
+ .decrypt = ablkcipher_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = DES3_EDE_KEY_SIZE,
+ .max_keysize = DES3_EDE_KEY_SIZE,
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_DEU |
+ DESC_HDR_MODE0_DEU_CBC |
+ DESC_HDR_MODE0_DEU_3DES,
}
};
@@ -1362,12 +1689,14 @@ struct talitos_crypto_alg {
static int talitos_cra_init(struct crypto_tfm *tfm)
{
struct crypto_alg *alg = tfm->__crt_alg;
- struct talitos_crypto_alg *talitos_alg =
- container_of(alg, struct talitos_crypto_alg, crypto_alg);
+ struct talitos_crypto_alg *talitos_alg;
struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
+ talitos_alg = container_of(alg, struct talitos_crypto_alg, crypto_alg);
+
/* update context with ptr to dev */
ctx->dev = talitos_alg->dev;
+
/* copy descriptor header template value */
ctx->desc_hdr_template = talitos_alg->desc_hdr_template;
@@ -1453,19 +1782,13 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
return ERR_PTR(-ENOMEM);
alg = &t_alg->crypto_alg;
+ *alg = template->alg;
- snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name);
- snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
- template->driver_name);
alg->cra_module = THIS_MODULE;
alg->cra_init = talitos_cra_init;
alg->cra_priority = TALITOS_CRA_PRIORITY;
- alg->cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC;
- alg->cra_blocksize = template->blocksize;
alg->cra_alignmask = 0;
- alg->cra_type = &crypto_aead_type;
alg->cra_ctxsize = sizeof(struct talitos_ctx);
- alg->cra_u.aead = template->aead;
t_alg->desc_hdr_template = template->desc_hdr_template;
t_alg->dev = dev;
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 3b3c01b6f1ee..070357aaedbc 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -81,6 +81,14 @@ config MX3_IPU_IRQS
To avoid bloating the irq_desc[] array we allocate a sufficient
number of IRQ slots and map them dynamically to specific sources.
+config TXX9_DMAC
+ tristate "Toshiba TXx9 SoC DMA support"
+ depends on MACH_TX49XX || MACH_TX39XX
+ select DMA_ENGINE
+ help
+ Support the TXx9 SoC internal DMA controller. This can be
+ integrated in chips such as the Toshiba TX4927/38/39.
+
config DMA_ENGINE
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 2e5dc96700d2..a0b6564800c4 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_FSL_DMA) += fsldma.o
obj-$(CONFIG_MV_XOR) += mv_xor.o
obj-$(CONFIG_DW_DMAC) += dw_dmac.o
obj-$(CONFIG_MX3_IPU) += ipu/
+obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 92438e9dacc3..5a87384ea4ff 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -804,11 +804,14 @@ dma_async_memcpy_buf_to_buf(struct dma_chan *chan, void *dest,
dma_addr_t dma_dest, dma_src;
dma_cookie_t cookie;
int cpu;
+ unsigned long flags;
dma_src = dma_map_single(dev->dev, src, len, DMA_TO_DEVICE);
dma_dest = dma_map_single(dev->dev, dest, len, DMA_FROM_DEVICE);
- tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len,
- DMA_CTRL_ACK);
+ flags = DMA_CTRL_ACK |
+ DMA_COMPL_SRC_UNMAP_SINGLE |
+ DMA_COMPL_DEST_UNMAP_SINGLE;
+ tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags);
if (!tx) {
dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
@@ -850,11 +853,12 @@ dma_async_memcpy_buf_to_pg(struct dma_chan *chan, struct page *page,
dma_addr_t dma_dest, dma_src;
dma_cookie_t cookie;
int cpu;
+ unsigned long flags;
dma_src = dma_map_single(dev->dev, kdata, len, DMA_TO_DEVICE);
dma_dest = dma_map_page(dev->dev, page, offset, len, DMA_FROM_DEVICE);
- tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len,
- DMA_CTRL_ACK);
+ flags = DMA_CTRL_ACK | DMA_COMPL_SRC_UNMAP_SINGLE;
+ tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags);
if (!tx) {
dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
@@ -898,12 +902,13 @@ dma_async_memcpy_pg_to_pg(struct dma_chan *chan, struct page *dest_pg,
dma_addr_t dma_dest, dma_src;
dma_cookie_t cookie;
int cpu;
+ unsigned long flags;
dma_src = dma_map_page(dev->dev, src_pg, src_off, len, DMA_TO_DEVICE);
dma_dest = dma_map_page(dev->dev, dest_pg, dest_off, len,
DMA_FROM_DEVICE);
- tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len,
- DMA_CTRL_ACK);
+ flags = DMA_CTRL_ACK;
+ tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags);
if (!tx) {
dma_unmap_page(dev->dev, dma_src, len, DMA_TO_DEVICE);
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index a27c0fb1bc11..fb7da5141e96 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -531,9 +531,7 @@ static int __init dmatest_init(void)
chan = dma_request_channel(mask, filter, NULL);
if (chan) {
err = dmatest_add_channel(chan);
- if (err == 0)
- continue;
- else {
+ if (err) {
dma_release_channel(chan);
break; /* add_channel failed, punt */
}
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index da8a8ed9e411..66a7687cca73 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -622,8 +622,8 @@ static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan)
if (ld_node != &fsl_chan->ld_queue) {
/* Get the ld start address from ld_queue */
next_dest_addr = to_fsl_desc(ld_node)->async_tx.phys;
- dev_dbg(fsl_chan->dev, "xfer LDs staring from %p\n",
- (void *)next_dest_addr);
+ dev_dbg(fsl_chan->dev, "xfer LDs staring from 0x%llx\n",
+ (unsigned long long)next_dest_addr);
set_cdar(fsl_chan, next_dest_addr);
dma_start(fsl_chan);
} else {
@@ -734,8 +734,9 @@ static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data)
*/
if (stat & FSL_DMA_SR_EOSI) {
dev_dbg(fsl_chan->dev, "event: End-of-segments INT\n");
- dev_dbg(fsl_chan->dev, "event: clndar %p, nlndar %p\n",
- (void *)get_cdar(fsl_chan), (void *)get_ndar(fsl_chan));
+ dev_dbg(fsl_chan->dev, "event: clndar 0x%llx, nlndar 0x%llx\n",
+ (unsigned long long)get_cdar(fsl_chan),
+ (unsigned long long)get_ndar(fsl_chan));
stat &= ~FSL_DMA_SR_EOSI;
update_cookie = 1;
}
@@ -925,8 +926,8 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
}
dev_info(&dev->dev, "Probe the Freescale DMA driver for %s "
- "controller at %p...\n",
- match->compatible, (void *)fdev->reg.start);
+ "controller at 0x%llx...\n",
+ match->compatible, (unsigned long long)fdev->reg.start);
fdev->reg_base = ioremap(fdev->reg.start, fdev->reg.end
- fdev->reg.start + 1);
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index e4fc33c1c32f..1955ee8d6d20 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -1063,22 +1063,31 @@ static void ioat_dma_cleanup_tasklet(unsigned long data)
static void
ioat_dma_unmap(struct ioat_dma_chan *ioat_chan, struct ioat_desc_sw *desc)
{
- /*
- * yes we are unmapping both _page and _single
- * alloc'd regions with unmap_page. Is this
- * *really* that bad?
- */
- if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP))
- pci_unmap_page(ioat_chan->device->pdev,
- pci_unmap_addr(desc, dst),
- pci_unmap_len(desc, len),
- PCI_DMA_FROMDEVICE);
-
- if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP))
- pci_unmap_page(ioat_chan->device->pdev,
- pci_unmap_addr(desc, src),
- pci_unmap_len(desc, len),
- PCI_DMA_TODEVICE);
+ if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+ if (desc->async_tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
+ pci_unmap_single(ioat_chan->device->pdev,
+ pci_unmap_addr(desc, dst),
+ pci_unmap_len(desc, len),
+ PCI_DMA_FROMDEVICE);
+ else
+ pci_unmap_page(ioat_chan->device->pdev,
+ pci_unmap_addr(desc, dst),
+ pci_unmap_len(desc, len),
+ PCI_DMA_FROMDEVICE);
+ }
+
+ if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+ if (desc->async_tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
+ pci_unmap_single(ioat_chan->device->pdev,
+ pci_unmap_addr(desc, src),
+ pci_unmap_len(desc, len),
+ PCI_DMA_TODEVICE);
+ else
+ pci_unmap_page(ioat_chan->device->pdev,
+ pci_unmap_addr(desc, src),
+ pci_unmap_len(desc, len),
+ PCI_DMA_TODEVICE);
+ }
}
/**
@@ -1363,6 +1372,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
int err = 0;
struct completion cmp;
unsigned long tmo;
+ unsigned long flags;
src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
if (!src)
@@ -1392,8 +1402,9 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
DMA_TO_DEVICE);
dma_dest = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE,
DMA_FROM_DEVICE);
+ flags = DMA_COMPL_SRC_UNMAP_SINGLE | DMA_COMPL_DEST_UNMAP_SINGLE;
tx = device->common.device_prep_dma_memcpy(dma_chan, dma_dest, dma_src,
- IOAT_TEST_SIZE, 0);
+ IOAT_TEST_SIZE, flags);
if (!tx) {
dev_err(&device->pdev->dev,
"Self-test prep failed, disabling\n");
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index e202a6ce5573..9a5bc1a7389e 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1272,7 +1272,8 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
/* Other interrupts do not interfere with this channel */
spin_lock(&ichan->lock);
if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
- ((curbuf >> chan_id) & 1) == ichan->active_buffer)) {
+ ((curbuf >> chan_id) & 1) == ichan->active_buffer &&
+ !list_is_last(ichan->queue.next, &ichan->queue))) {
int i = 100;
/* This doesn't help. See comment in ipu_disable_channel() */
@@ -1547,7 +1548,7 @@ static irqreturn_t ic_sof_irq(int irq, void *dev_id)
struct idmac_channel *ichan = dev_id;
printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n",
irq, ichan->dma_chan.chan_id);
- disable_irq(irq);
+ disable_irq_nosync(irq);
return IRQ_HANDLED;
}
@@ -1556,7 +1557,7 @@ static irqreturn_t ic_eof_irq(int irq, void *dev_id)
struct idmac_channel *ichan = dev_id;
printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n",
irq, ichan->dma_chan.chan_id);
- disable_irq(irq);
+ disable_irq_nosync(irq);
return IRQ_HANDLED;
}
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
new file mode 100644
index 000000000000..9aa9ea9822c8
--- /dev/null
+++ b/drivers/dma/txx9dmac.c
@@ -0,0 +1,1354 @@
+/*
+ * Driver for the TXx9 SoC DMA Controller
+ *
+ * Copyright (C) 2009 Atsushi Nemoto
+ *
+ * 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/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/scatterlist.h>
+#include "txx9dmac.h"
+
+static struct txx9dmac_chan *to_txx9dmac_chan(struct dma_chan *chan)
+{
+ return container_of(chan, struct txx9dmac_chan, chan);
+}
+
+static struct txx9dmac_cregs __iomem *__dma_regs(const struct txx9dmac_chan *dc)
+{
+ return dc->ch_regs;
+}
+
+static struct txx9dmac_cregs32 __iomem *__dma_regs32(
+ const struct txx9dmac_chan *dc)
+{
+ return dc->ch_regs;
+}
+
+#define channel64_readq(dc, name) \
+ __raw_readq(&(__dma_regs(dc)->name))
+#define channel64_writeq(dc, name, val) \
+ __raw_writeq((val), &(__dma_regs(dc)->name))
+#define channel64_readl(dc, name) \
+ __raw_readl(&(__dma_regs(dc)->name))
+#define channel64_writel(dc, name, val) \
+ __raw_writel((val), &(__dma_regs(dc)->name))
+
+#define channel32_readl(dc, name) \
+ __raw_readl(&(__dma_regs32(dc)->name))
+#define channel32_writel(dc, name, val) \
+ __raw_writel((val), &(__dma_regs32(dc)->name))
+
+#define channel_readq(dc, name) channel64_readq(dc, name)
+#define channel_writeq(dc, name, val) channel64_writeq(dc, name, val)
+#define channel_readl(dc, name) \
+ (is_dmac64(dc) ? \
+ channel64_readl(dc, name) : channel32_readl(dc, name))
+#define channel_writel(dc, name, val) \
+ (is_dmac64(dc) ? \
+ channel64_writel(dc, name, val) : channel32_writel(dc, name, val))
+
+static dma_addr_t channel64_read_CHAR(const struct txx9dmac_chan *dc)
+{
+ if (sizeof(__dma_regs(dc)->CHAR) == sizeof(u64))
+ return channel64_readq(dc, CHAR);
+ else
+ return channel64_readl(dc, CHAR);
+}
+
+static void channel64_write_CHAR(const struct txx9dmac_chan *dc, dma_addr_t val)
+{
+ if (sizeof(__dma_regs(dc)->CHAR) == sizeof(u64))
+ channel64_writeq(dc, CHAR, val);
+ else
+ channel64_writel(dc, CHAR, val);
+}
+
+static void channel64_clear_CHAR(const struct txx9dmac_chan *dc)
+{
+#if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR)
+ channel64_writel(dc, CHAR, 0);
+ channel64_writel(dc, __pad_CHAR, 0);
+#else
+ channel64_writeq(dc, CHAR, 0);
+#endif
+}
+
+static dma_addr_t channel_read_CHAR(const struct txx9dmac_chan *dc)
+{
+ if (is_dmac64(dc))
+ return channel64_read_CHAR(dc);
+ else
+ return channel32_readl(dc, CHAR);
+}
+
+static void channel_write_CHAR(const struct txx9dmac_chan *dc, dma_addr_t val)
+{
+ if (is_dmac64(dc))
+ channel64_write_CHAR(dc, val);
+ else
+ channel32_writel(dc, CHAR, val);
+}
+
+static struct txx9dmac_regs __iomem *__txx9dmac_regs(
+ const struct txx9dmac_dev *ddev)
+{
+ return ddev->regs;
+}
+
+static struct txx9dmac_regs32 __iomem *__txx9dmac_regs32(
+ const struct txx9dmac_dev *ddev)
+{
+ return ddev->regs;
+}
+
+#define dma64_readl(ddev, name) \
+ __raw_readl(&(__txx9dmac_regs(ddev)->name))
+#define dma64_writel(ddev, name, val) \
+ __raw_writel((val), &(__txx9dmac_regs(ddev)->name))
+
+#define dma32_readl(ddev, name) \
+ __raw_readl(&(__txx9dmac_regs32(ddev)->name))
+#define dma32_writel(ddev, name, val) \
+ __raw_writel((val), &(__txx9dmac_regs32(ddev)->name))
+
+#define dma_readl(ddev, name) \
+ (__is_dmac64(ddev) ? \
+ dma64_readl(ddev, name) : dma32_readl(ddev, name))
+#define dma_writel(ddev, name, val) \
+ (__is_dmac64(ddev) ? \
+ dma64_writel(ddev, name, val) : dma32_writel(ddev, name, val))
+
+static struct device *chan2dev(struct dma_chan *chan)
+{
+ return &chan->dev->device;
+}
+static struct device *chan2parent(struct dma_chan *chan)
+{
+ return chan->dev->device.parent;
+}
+
+static struct txx9dmac_desc *
+txd_to_txx9dmac_desc(struct dma_async_tx_descriptor *txd)
+{
+ return container_of(txd, struct txx9dmac_desc, txd);
+}
+
+static dma_addr_t desc_read_CHAR(const struct txx9dmac_chan *dc,
+ const struct txx9dmac_desc *desc)
+{
+ return is_dmac64(dc) ? desc->hwdesc.CHAR : desc->hwdesc32.CHAR;
+}
+
+static void desc_write_CHAR(const struct txx9dmac_chan *dc,
+ struct txx9dmac_desc *desc, dma_addr_t val)
+{
+ if (is_dmac64(dc))
+ desc->hwdesc.CHAR = val;
+ else
+ desc->hwdesc32.CHAR = val;
+}
+
+#define TXX9_DMA_MAX_COUNT 0x04000000
+
+#define TXX9_DMA_INITIAL_DESC_COUNT 64
+
+static struct txx9dmac_desc *txx9dmac_first_active(struct txx9dmac_chan *dc)
+{
+ return list_entry(dc->active_list.next,
+ struct txx9dmac_desc, desc_node);
+}
+
+static struct txx9dmac_desc *txx9dmac_last_active(struct txx9dmac_chan *dc)
+{
+ return list_entry(dc->active_list.prev,
+ struct txx9dmac_desc, desc_node);
+}
+
+static struct txx9dmac_desc *txx9dmac_first_queued(struct txx9dmac_chan *dc)
+{
+ return list_entry(dc->queue.next, struct txx9dmac_desc, desc_node);
+}
+
+static struct txx9dmac_desc *txx9dmac_last_child(struct txx9dmac_desc *desc)
+{
+ if (!list_empty(&desc->txd.tx_list))
+ desc = list_entry(desc->txd.tx_list.prev,
+ struct txx9dmac_desc, desc_node);
+ return desc;
+}
+
+static dma_cookie_t txx9dmac_tx_submit(struct dma_async_tx_descriptor *tx);
+
+static struct txx9dmac_desc *txx9dmac_desc_alloc(struct txx9dmac_chan *dc,
+ gfp_t flags)
+{
+ struct txx9dmac_dev *ddev = dc->ddev;
+ struct txx9dmac_desc *desc;
+
+ desc = kzalloc(sizeof(*desc), flags);
+ if (!desc)
+ return NULL;
+ dma_async_tx_descriptor_init(&desc->txd, &dc->chan);
+ desc->txd.tx_submit = txx9dmac_tx_submit;
+ /* txd.flags will be overwritten in prep funcs */
+ desc->txd.flags = DMA_CTRL_ACK;
+ desc->txd.phys = dma_map_single(chan2parent(&dc->chan), &desc->hwdesc,
+ ddev->descsize, DMA_TO_DEVICE);
+ return desc;
+}
+
+static struct txx9dmac_desc *txx9dmac_desc_get(struct txx9dmac_chan *dc)
+{
+ struct txx9dmac_desc *desc, *_desc;
+ struct txx9dmac_desc *ret = NULL;
+ unsigned int i = 0;
+
+ spin_lock_bh(&dc->lock);
+ list_for_each_entry_safe(desc, _desc, &dc->free_list, desc_node) {
+ if (async_tx_test_ack(&desc->txd)) {
+ list_del(&desc->desc_node);
+ ret = desc;
+ break;
+ }
+ dev_dbg(chan2dev(&dc->chan), "desc %p not ACKed\n", desc);
+ i++;
+ }
+ spin_unlock_bh(&dc->lock);
+
+ dev_vdbg(chan2dev(&dc->chan), "scanned %u descriptors on freelist\n",
+ i);
+ if (!ret) {
+ ret = txx9dmac_desc_alloc(dc, GFP_ATOMIC);
+ if (ret) {
+ spin_lock_bh(&dc->lock);
+ dc->descs_allocated++;
+ spin_unlock_bh(&dc->lock);
+ } else
+ dev_err(chan2dev(&dc->chan),
+ "not enough descriptors available\n");
+ }
+ return ret;
+}
+
+static void txx9dmac_sync_desc_for_cpu(struct txx9dmac_chan *dc,
+ struct txx9dmac_desc *desc)
+{
+ struct txx9dmac_dev *ddev = dc->ddev;
+ struct txx9dmac_desc *child;
+
+ list_for_each_entry(child, &desc->txd.tx_list, desc_node)
+ dma_sync_single_for_cpu(chan2parent(&dc->chan),
+ child->txd.phys, ddev->descsize,
+ DMA_TO_DEVICE);
+ dma_sync_single_for_cpu(chan2parent(&dc->chan),
+ desc->txd.phys, ddev->descsize,
+ DMA_TO_DEVICE);
+}
+
+/*
+ * Move a descriptor, including any children, to the free list.
+ * `desc' must not be on any lists.
+ */
+static void txx9dmac_desc_put(struct txx9dmac_chan *dc,
+ struct txx9dmac_desc *desc)
+{
+ if (desc) {
+ struct txx9dmac_desc *child;
+
+ txx9dmac_sync_desc_for_cpu(dc, desc);
+
+ spin_lock_bh(&dc->lock);
+ list_for_each_entry(child, &desc->txd.tx_list, desc_node)
+ dev_vdbg(chan2dev(&dc->chan),
+ "moving child desc %p to freelist\n",
+ child);
+ list_splice_init(&desc->txd.tx_list, &dc->free_list);
+ dev_vdbg(chan2dev(&dc->chan), "moving desc %p to freelist\n",
+ desc);
+ list_add(&desc->desc_node, &dc->free_list);
+ spin_unlock_bh(&dc->lock);
+ }
+}
+
+/* Called with dc->lock held and bh disabled */
+static dma_cookie_t
+txx9dmac_assign_cookie(struct txx9dmac_chan *dc, struct txx9dmac_desc *desc)
+{
+ dma_cookie_t cookie = dc->chan.cookie;
+
+ if (++cookie < 0)
+ cookie = 1;
+
+ dc->chan.cookie = cookie;
+ desc->txd.cookie = cookie;
+
+ return cookie;
+}
+
+/*----------------------------------------------------------------------*/
+
+static void txx9dmac_dump_regs(struct txx9dmac_chan *dc)
+{
+ if (is_dmac64(dc))
+ dev_err(chan2dev(&dc->chan),
+ " CHAR: %#llx SAR: %#llx DAR: %#llx CNTR: %#x"
+ " SAIR: %#x DAIR: %#x CCR: %#x CSR: %#x\n",
+ (u64)channel64_read_CHAR(dc),
+ channel64_readq(dc, SAR),
+ channel64_readq(dc, DAR),
+ channel64_readl(dc, CNTR),
+ channel64_readl(dc, SAIR),
+ channel64_readl(dc, DAIR),
+ channel64_readl(dc, CCR),
+ channel64_readl(dc, CSR));
+ else
+ dev_err(chan2dev(&dc->chan),
+ " CHAR: %#x SAR: %#x DAR: %#x CNTR: %#x"
+ " SAIR: %#x DAIR: %#x CCR: %#x CSR: %#x\n",
+ channel32_readl(dc, CHAR),
+ channel32_readl(dc, SAR),
+ channel32_readl(dc, DAR),
+ channel32_readl(dc, CNTR),
+ channel32_readl(dc, SAIR),
+ channel32_readl(dc, DAIR),
+ channel32_readl(dc, CCR),
+ channel32_readl(dc, CSR));
+}
+
+static void txx9dmac_reset_chan(struct txx9dmac_chan *dc)
+{
+ channel_writel(dc, CCR, TXX9_DMA_CCR_CHRST);
+ if (is_dmac64(dc)) {
+ channel64_clear_CHAR(dc);
+ channel_writeq(dc, SAR, 0);
+ channel_writeq(dc, DAR, 0);
+ } else {
+ channel_writel(dc, CHAR, 0);
+ channel_writel(dc, SAR, 0);
+ channel_writel(dc, DAR, 0);
+ }
+ channel_writel(dc, CNTR, 0);
+ channel_writel(dc, SAIR, 0);
+ channel_writel(dc, DAIR, 0);
+ channel_writel(dc, CCR, 0);
+ mmiowb();
+}
+
+/* Called with dc->lock held and bh disabled */
+static void txx9dmac_dostart(struct txx9dmac_chan *dc,
+ struct txx9dmac_desc *first)
+{
+ struct txx9dmac_slave *ds = dc->chan.private;
+ u32 sai, dai;
+
+ dev_vdbg(chan2dev(&dc->chan), "dostart %u %p\n",
+ first->txd.cookie, first);
+ /* ASSERT: channel is idle */
+ if (channel_readl(dc, CSR) & TXX9_DMA_CSR_XFACT) {
+ dev_err(chan2dev(&dc->chan),
+ "BUG: Attempted to start non-idle channel\n");
+ txx9dmac_dump_regs(dc);
+ /* The tasklet will hopefully advance the queue... */
+ return;
+ }
+
+ if (is_dmac64(dc)) {
+ channel64_writel(dc, CNTR, 0);
+ channel64_writel(dc, CSR, 0xffffffff);
+ if (ds) {
+ if (ds->tx_reg) {
+ sai = ds->reg_width;
+ dai = 0;
+ } else {
+ sai = 0;
+ dai = ds->reg_width;
+ }
+ } else {
+ sai = 8;
+ dai = 8;
+ }
+ channel64_writel(dc, SAIR, sai);
+ channel64_writel(dc, DAIR, dai);
+ /* All 64-bit DMAC supports SMPCHN */
+ channel64_writel(dc, CCR, dc->ccr);
+ /* Writing a non zero value to CHAR will assert XFACT */
+ channel64_write_CHAR(dc, first->txd.phys);
+ } else {
+ channel32_writel(dc, CNTR, 0);
+ channel32_writel(dc, CSR, 0xffffffff);
+ if (ds) {
+ if (ds->tx_reg) {
+ sai = ds->reg_width;
+ dai = 0;
+ } else {
+ sai = 0;
+ dai = ds->reg_width;
+ }
+ } else {
+ sai = 4;
+ dai = 4;
+ }
+ channel32_writel(dc, SAIR, sai);
+ channel32_writel(dc, DAIR, dai);
+ if (txx9_dma_have_SMPCHN()) {
+ channel32_writel(dc, CCR, dc->ccr);
+ /* Writing a non zero value to CHAR will assert XFACT */
+ channel32_writel(dc, CHAR, first->txd.phys);
+ } else {
+ channel32_writel(dc, CHAR, first->txd.phys);
+ channel32_writel(dc, CCR, dc->ccr);
+ }
+ }
+}
+
+/*----------------------------------------------------------------------*/
+
+static void
+txx9dmac_descriptor_complete(struct txx9dmac_chan *dc,
+ struct txx9dmac_desc *desc)
+{
+ dma_async_tx_callback callback;
+ void *param;
+ struct dma_async_tx_descriptor *txd = &desc->txd;
+ struct txx9dmac_slave *ds = dc->chan.private;
+
+ dev_vdbg(chan2dev(&dc->chan), "descriptor %u %p complete\n",
+ txd->cookie, desc);
+
+ dc->completed = txd->cookie;
+ callback = txd->callback;
+ param = txd->callback_param;
+
+ txx9dmac_sync_desc_for_cpu(dc, desc);
+ list_splice_init(&txd->tx_list, &dc->free_list);
+ list_move(&desc->desc_node, &dc->free_list);
+
+ /*
+ * We use dma_unmap_page() regardless of how the buffers were
+ * mapped before they were submitted...
+ */
+ if (!ds) {
+ dma_addr_t dmaaddr;
+ if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+ dmaaddr = is_dmac64(dc) ?
+ desc->hwdesc.DAR : desc->hwdesc32.DAR;
+ dma_unmap_page(chan2parent(&dc->chan), dmaaddr,
+ desc->len, DMA_FROM_DEVICE);
+ }
+ if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+ dmaaddr = is_dmac64(dc) ?
+ desc->hwdesc.SAR : desc->hwdesc32.SAR;
+ dma_unmap_page(chan2parent(&dc->chan), dmaaddr,
+ desc->len, DMA_TO_DEVICE);
+ }
+ }
+
+ /*
+ * The API requires that no submissions are done from a
+ * callback, so we don't need to drop the lock here
+ */
+ if (callback)
+ callback(param);
+ dma_run_dependencies(txd);
+}
+
+static void txx9dmac_dequeue(struct txx9dmac_chan *dc, struct list_head *list)
+{
+ struct txx9dmac_dev *ddev = dc->ddev;
+ struct txx9dmac_desc *desc;
+ struct txx9dmac_desc *prev = NULL;
+
+ BUG_ON(!list_empty(list));
+ do {
+ desc = txx9dmac_first_queued(dc);
+ if (prev) {
+ desc_write_CHAR(dc, prev, desc->txd.phys);
+ dma_sync_single_for_device(chan2parent(&dc->chan),
+ prev->txd.phys, ddev->descsize,
+ DMA_TO_DEVICE);
+ }
+ prev = txx9dmac_last_child(desc);
+ list_move_tail(&desc->desc_node, list);
+ /* Make chain-completion interrupt happen */
+ if ((desc->txd.flags & DMA_PREP_INTERRUPT) &&
+ !txx9dmac_chan_INTENT(dc))
+ break;
+ } while (!list_empty(&dc->queue));
+}
+
+static void txx9dmac_complete_all(struct txx9dmac_chan *dc)
+{
+ struct txx9dmac_desc *desc, *_desc;
+ LIST_HEAD(list);
+
+ /*
+ * Submit queued descriptors ASAP, i.e. before we go through
+ * the completed ones.
+ */
+ list_splice_init(&dc->active_list, &list);
+ if (!list_empty(&dc->queue)) {
+ txx9dmac_dequeue(dc, &dc->active_list);
+ txx9dmac_dostart(dc, txx9dmac_first_active(dc));
+ }
+
+ list_for_each_entry_safe(desc, _desc, &list, desc_node)
+ txx9dmac_descriptor_complete(dc, desc);
+}
+
+static void txx9dmac_dump_desc(struct txx9dmac_chan *dc,
+ struct txx9dmac_hwdesc *desc)
+{
+ if (is_dmac64(dc)) {
+#ifdef TXX9_DMA_USE_SIMPLE_CHAIN
+ dev_crit(chan2dev(&dc->chan),
+ " desc: ch%#llx s%#llx d%#llx c%#x\n",
+ (u64)desc->CHAR, desc->SAR, desc->DAR, desc->CNTR);
+#else
+ dev_crit(chan2dev(&dc->chan),
+ " desc: ch%#llx s%#llx d%#llx c%#x"
+ " si%#x di%#x cc%#x cs%#x\n",
+ (u64)desc->CHAR, desc->SAR, desc->DAR, desc->CNTR,
+ desc->SAIR, desc->DAIR, desc->CCR, desc->CSR);
+#endif
+ } else {
+ struct txx9dmac_hwdesc32 *d = (struct txx9dmac_hwdesc32 *)desc;
+#ifdef TXX9_DMA_USE_SIMPLE_CHAIN
+ dev_crit(chan2dev(&dc->chan),
+ " desc: ch%#x s%#x d%#x c%#x\n",
+ d->CHAR, d->SAR, d->DAR, d->CNTR);
+#else
+ dev_crit(chan2dev(&dc->chan),
+ " desc: ch%#x s%#x d%#x c%#x"
+ " si%#x di%#x cc%#x cs%#x\n",
+ d->CHAR, d->SAR, d->DAR, d->CNTR,
+ d->SAIR, d->DAIR, d->CCR, d->CSR);
+#endif
+ }
+}
+
+static void txx9dmac_handle_error(struct txx9dmac_chan *dc, u32 csr)
+{
+ struct txx9dmac_desc *bad_desc;
+ struct txx9dmac_desc *child;
+ u32 errors;
+
+ /*
+ * The descriptor currently at the head of the active list is
+ * borked. Since we don't have any way to report errors, we'll
+ * just have to scream loudly and try to carry on.
+ */
+ dev_crit(chan2dev(&dc->chan), "Abnormal Chain Completion\n");
+ txx9dmac_dump_regs(dc);
+
+ bad_desc = txx9dmac_first_active(dc);
+ list_del_init(&bad_desc->desc_node);
+
+ /* Clear all error flags and try to restart the controller */
+ errors = csr & (TXX9_DMA_CSR_ABCHC |
+ TXX9_DMA_CSR_CFERR | TXX9_DMA_CSR_CHERR |
+ TXX9_DMA_CSR_DESERR | TXX9_DMA_CSR_SORERR);
+ channel_writel(dc, CSR, errors);
+
+ if (list_empty(&dc->active_list) && !list_empty(&dc->queue))
+ txx9dmac_dequeue(dc, &dc->active_list);
+ if (!list_empty(&dc->active_list))
+ txx9dmac_dostart(dc, txx9dmac_first_active(dc));
+
+ dev_crit(chan2dev(&dc->chan),
+ "Bad descriptor submitted for DMA! (cookie: %d)\n",
+ bad_desc->txd.cookie);
+ txx9dmac_dump_desc(dc, &bad_desc->hwdesc);
+ list_for_each_entry(child, &bad_desc->txd.tx_list, desc_node)
+ txx9dmac_dump_desc(dc, &child->hwdesc);
+ /* Pretend the descriptor completed successfully */
+ txx9dmac_descriptor_complete(dc, bad_desc);
+}
+
+static void txx9dmac_scan_descriptors(struct txx9dmac_chan *dc)
+{
+ dma_addr_t chain;
+ struct txx9dmac_desc *desc, *_desc;
+ struct txx9dmac_desc *child;
+ u32 csr;
+
+ if (is_dmac64(dc)) {
+ chain = channel64_read_CHAR(dc);
+ csr = channel64_readl(dc, CSR);
+ channel64_writel(dc, CSR, csr);
+ } else {
+ chain = channel32_readl(dc, CHAR);
+ csr = channel32_readl(dc, CSR);
+ channel32_writel(dc, CSR, csr);
+ }
+ /* For dynamic chain, we should look at XFACT instead of NCHNC */
+ if (!(csr & (TXX9_DMA_CSR_XFACT | TXX9_DMA_CSR_ABCHC))) {
+ /* Everything we've submitted is done */
+ txx9dmac_complete_all(dc);
+ return;
+ }
+ if (!(csr & TXX9_DMA_CSR_CHNEN))
+ chain = 0; /* last descriptor of this chain */
+
+ dev_vdbg(chan2dev(&dc->chan), "scan_descriptors: char=%#llx\n",
+ (u64)chain);
+
+ list_for_each_entry_safe(desc, _desc, &dc->active_list, desc_node) {
+ if (desc_read_CHAR(dc, desc) == chain) {
+ /* This one is currently in progress */
+ if (csr & TXX9_DMA_CSR_ABCHC)
+ goto scan_done;
+ return;
+ }
+
+ list_for_each_entry(child, &desc->txd.tx_list, desc_node)
+ if (desc_read_CHAR(dc, child) == chain) {
+ /* Currently in progress */
+ if (csr & TXX9_DMA_CSR_ABCHC)
+ goto scan_done;
+ return;
+ }
+
+ /*
+ * No descriptors so far seem to be in progress, i.e.
+ * this one must be done.
+ */
+ txx9dmac_descriptor_complete(dc, desc);
+ }
+scan_done:
+ if (csr & TXX9_DMA_CSR_ABCHC) {
+ txx9dmac_handle_error(dc, csr);
+ return;
+ }
+
+ dev_err(chan2dev(&dc->chan),
+ "BUG: All descriptors done, but channel not idle!\n");
+
+ /* Try to continue after resetting the channel... */
+ txx9dmac_reset_chan(dc);
+
+ if (!list_empty(&dc->queue)) {
+ txx9dmac_dequeue(dc, &dc->active_list);
+ txx9dmac_dostart(dc, txx9dmac_first_active(dc));
+ }
+}
+
+static void txx9dmac_chan_tasklet(unsigned long data)
+{
+ int irq;
+ u32 csr;
+ struct txx9dmac_chan *dc;
+
+ dc = (struct txx9dmac_chan *)data;
+ csr = channel_readl(dc, CSR);
+ dev_vdbg(chan2dev(&dc->chan), "tasklet: status=%x\n", csr);
+
+ spin_lock(&dc->lock);
+ if (csr & (TXX9_DMA_CSR_ABCHC | TXX9_DMA_CSR_NCHNC |
+ TXX9_DMA_CSR_NTRNFC))
+ txx9dmac_scan_descriptors(dc);
+ spin_unlock(&dc->lock);
+ irq = dc->irq;
+
+ enable_irq(irq);
+}
+
+static irqreturn_t txx9dmac_chan_interrupt(int irq, void *dev_id)
+{
+ struct txx9dmac_chan *dc = dev_id;
+
+ dev_vdbg(chan2dev(&dc->chan), "interrupt: status=%#x\n",
+ channel_readl(dc, CSR));
+
+ tasklet_schedule(&dc->tasklet);
+ /*
+ * Just disable the interrupts. We'll turn them back on in the
+ * softirq handler.
+ */
+ disable_irq_nosync(irq);
+
+ return IRQ_HANDLED;
+}
+
+static void txx9dmac_tasklet(unsigned long data)
+{
+ int irq;
+ u32 csr;
+ struct txx9dmac_chan *dc;
+
+ struct txx9dmac_dev *ddev = (struct txx9dmac_dev *)data;
+ u32 mcr;
+ int i;
+
+ mcr = dma_readl(ddev, MCR);
+ dev_vdbg(ddev->chan[0]->dma.dev, "tasklet: mcr=%x\n", mcr);
+ for (i = 0; i < TXX9_DMA_MAX_NR_CHANNELS; i++) {
+ if ((mcr >> (24 + i)) & 0x11) {
+ dc = ddev->chan[i];
+ csr = channel_readl(dc, CSR);
+ dev_vdbg(chan2dev(&dc->chan), "tasklet: status=%x\n",
+ csr);
+ spin_lock(&dc->lock);
+ if (csr & (TXX9_DMA_CSR_ABCHC | TXX9_DMA_CSR_NCHNC |
+ TXX9_DMA_CSR_NTRNFC))
+ txx9dmac_scan_descriptors(dc);
+ spin_unlock(&dc->lock);
+ }
+ }
+ irq = ddev->irq;
+
+ enable_irq(irq);
+}
+
+static irqreturn_t txx9dmac_interrupt(int irq, void *dev_id)
+{
+ struct txx9dmac_dev *ddev = dev_id;
+
+ dev_vdbg(ddev->chan[0]->dma.dev, "interrupt: status=%#x\n",
+ dma_readl(ddev, MCR));
+
+ tasklet_schedule(&ddev->tasklet);
+ /*
+ * Just disable the interrupts. We'll turn them back on in the
+ * softirq handler.
+ */
+ disable_irq_nosync(irq);
+
+ return IRQ_HANDLED;
+}
+
+/*----------------------------------------------------------------------*/
+
+static dma_cookie_t txx9dmac_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct txx9dmac_desc *desc = txd_to_txx9dmac_desc(tx);
+ struct txx9dmac_chan *dc = to_txx9dmac_chan(tx->chan);
+ dma_cookie_t cookie;
+
+ spin_lock_bh(&dc->lock);
+ cookie = txx9dmac_assign_cookie(dc, desc);
+
+ dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u %p\n",
+ desc->txd.cookie, desc);
+
+ list_add_tail(&desc->desc_node, &dc->queue);
+ spin_unlock_bh(&dc->lock);
+
+ return cookie;
+}
+
+static struct dma_async_tx_descriptor *
+txx9dmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+ size_t len, unsigned long flags)
+{
+ struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+ struct txx9dmac_dev *ddev = dc->ddev;
+ struct txx9dmac_desc *desc;
+ struct txx9dmac_desc *first;
+ struct txx9dmac_desc *prev;
+ size_t xfer_count;
+ size_t offset;
+
+ dev_vdbg(chan2dev(chan), "prep_dma_memcpy d%#llx s%#llx l%#zx f%#lx\n",
+ (u64)dest, (u64)src, len, flags);
+
+ if (unlikely(!len)) {
+ dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
+ return NULL;
+ }
+
+ prev = first = NULL;
+
+ for (offset = 0; offset < len; offset += xfer_count) {
+ xfer_count = min_t(size_t, len - offset, TXX9_DMA_MAX_COUNT);
+ /*
+ * Workaround for ERT-TX49H2-033, ERT-TX49H3-020,
+ * ERT-TX49H4-016 (slightly conservative)
+ */
+ if (__is_dmac64(ddev)) {
+ if (xfer_count > 0x100 &&
+ (xfer_count & 0xff) >= 0xfa &&
+ (xfer_count & 0xff) <= 0xff)
+ xfer_count -= 0x20;
+ } else {
+ if (xfer_count > 0x80 &&
+ (xfer_count & 0x7f) >= 0x7e &&
+ (xfer_count & 0x7f) <= 0x7f)
+ xfer_count -= 0x20;
+ }
+
+ desc = txx9dmac_desc_get(dc);
+ if (!desc) {
+ txx9dmac_desc_put(dc, first);
+ return NULL;
+ }
+
+ if (__is_dmac64(ddev)) {
+ desc->hwdesc.SAR = src + offset;
+ desc->hwdesc.DAR = dest + offset;
+ desc->hwdesc.CNTR = xfer_count;
+ txx9dmac_desc_set_nosimple(ddev, desc, 8, 8,
+ dc->ccr | TXX9_DMA_CCR_XFACT);
+ } else {
+ desc->hwdesc32.SAR = src + offset;
+ desc->hwdesc32.DAR = dest + offset;
+ desc->hwdesc32.CNTR = xfer_count;
+ txx9dmac_desc_set_nosimple(ddev, desc, 4, 4,
+ dc->ccr | TXX9_DMA_CCR_XFACT);
+ }
+
+ /*
+ * The descriptors on tx_list are not reachable from
+ * the dc->queue list or dc->active_list after a
+ * submit. If we put all descriptors on active_list,
+ * calling of callback on the completion will be more
+ * complex.
+ */
+ if (!first) {
+ first = desc;
+ } else {
+ desc_write_CHAR(dc, prev, desc->txd.phys);
+ dma_sync_single_for_device(chan2parent(&dc->chan),
+ prev->txd.phys, ddev->descsize,
+ DMA_TO_DEVICE);
+ list_add_tail(&desc->desc_node,
+ &first->txd.tx_list);
+ }
+ prev = desc;
+ }
+
+ /* Trigger interrupt after last block */
+ if (flags & DMA_PREP_INTERRUPT)
+ txx9dmac_desc_set_INTENT(ddev, prev);
+
+ desc_write_CHAR(dc, prev, 0);
+ dma_sync_single_for_device(chan2parent(&dc->chan),
+ prev->txd.phys, ddev->descsize,
+ DMA_TO_DEVICE);
+
+ first->txd.flags = flags;
+ first->len = len;
+
+ return &first->txd;
+}
+
+static struct dma_async_tx_descriptor *
+txx9dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_data_direction direction,
+ unsigned long flags)
+{
+ struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+ struct txx9dmac_dev *ddev = dc->ddev;
+ struct txx9dmac_slave *ds = chan->private;
+ struct txx9dmac_desc *prev;
+ struct txx9dmac_desc *first;
+ unsigned int i;
+ struct scatterlist *sg;
+
+ dev_vdbg(chan2dev(chan), "prep_dma_slave\n");
+
+ BUG_ON(!ds || !ds->reg_width);
+ if (ds->tx_reg)
+ BUG_ON(direction != DMA_TO_DEVICE);
+ else
+ BUG_ON(direction != DMA_FROM_DEVICE);
+ if (unlikely(!sg_len))
+ return NULL;
+
+ prev = first = NULL;
+
+ for_each_sg(sgl, sg, sg_len, i) {
+ struct txx9dmac_desc *desc;
+ dma_addr_t mem;
+ u32 sai, dai;
+
+ desc = txx9dmac_desc_get(dc);
+ if (!desc) {
+ txx9dmac_desc_put(dc, first);
+ return NULL;
+ }
+
+ mem = sg_dma_address(sg);
+
+ if (__is_dmac64(ddev)) {
+ if (direction == DMA_TO_DEVICE) {
+ desc->hwdesc.SAR = mem;
+ desc->hwdesc.DAR = ds->tx_reg;
+ } else {
+ desc->hwdesc.SAR = ds->rx_reg;
+ desc->hwdesc.DAR = mem;
+ }
+ desc->hwdesc.CNTR = sg_dma_len(sg);
+ } else {
+ if (direction == DMA_TO_DEVICE) {
+ desc->hwdesc32.SAR = mem;
+ desc->hwdesc32.DAR = ds->tx_reg;
+ } else {
+ desc->hwdesc32.SAR = ds->rx_reg;
+ desc->hwdesc32.DAR = mem;
+ }
+ desc->hwdesc32.CNTR = sg_dma_len(sg);
+ }
+ if (direction == DMA_TO_DEVICE) {
+ sai = ds->reg_width;
+ dai = 0;
+ } else {
+ sai = 0;
+ dai = ds->reg_width;
+ }
+ txx9dmac_desc_set_nosimple(ddev, desc, sai, dai,
+ dc->ccr | TXX9_DMA_CCR_XFACT);
+
+ if (!first) {
+ first = desc;
+ } else {
+ desc_write_CHAR(dc, prev, desc->txd.phys);
+ dma_sync_single_for_device(chan2parent(&dc->chan),
+ prev->txd.phys,
+ ddev->descsize,
+ DMA_TO_DEVICE);
+ list_add_tail(&desc->desc_node,
+ &first->txd.tx_list);
+ }
+ prev = desc;
+ }
+
+ /* Trigger interrupt after last block */
+ if (flags & DMA_PREP_INTERRUPT)
+ txx9dmac_desc_set_INTENT(ddev, prev);
+
+ desc_write_CHAR(dc, prev, 0);
+ dma_sync_single_for_device(chan2parent(&dc->chan),
+ prev->txd.phys, ddev->descsize,
+ DMA_TO_DEVICE);
+
+ first->txd.flags = flags;
+ first->len = 0;
+
+ return &first->txd;
+}
+
+static void txx9dmac_terminate_all(struct dma_chan *chan)
+{
+ struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+ struct txx9dmac_desc *desc, *_desc;
+ LIST_HEAD(list);
+
+ dev_vdbg(chan2dev(chan), "terminate_all\n");
+ spin_lock_bh(&dc->lock);
+
+ txx9dmac_reset_chan(dc);
+
+ /* active_list entries will end up before queued entries */
+ list_splice_init(&dc->queue, &list);
+ list_splice_init(&dc->active_list, &list);
+
+ spin_unlock_bh(&dc->lock);
+
+ /* Flush all pending and queued descriptors */
+ list_for_each_entry_safe(desc, _desc, &list, desc_node)
+ txx9dmac_descriptor_complete(dc, desc);
+}
+
+static enum dma_status
+txx9dmac_is_tx_complete(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ dma_cookie_t *done, dma_cookie_t *used)
+{
+ struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+ dma_cookie_t last_used;
+ dma_cookie_t last_complete;
+ int ret;
+
+ last_complete = dc->completed;
+ last_used = chan->cookie;
+
+ ret = dma_async_is_complete(cookie, last_complete, last_used);
+ if (ret != DMA_SUCCESS) {
+ spin_lock_bh(&dc->lock);
+ txx9dmac_scan_descriptors(dc);
+ spin_unlock_bh(&dc->lock);
+
+ last_complete = dc->completed;
+ last_used = chan->cookie;
+
+ ret = dma_async_is_complete(cookie, last_complete, last_used);
+ }
+
+ if (done)
+ *done = last_complete;
+ if (used)
+ *used = last_used;
+
+ return ret;
+}
+
+static void txx9dmac_chain_dynamic(struct txx9dmac_chan *dc,
+ struct txx9dmac_desc *prev)
+{
+ struct txx9dmac_dev *ddev = dc->ddev;
+ struct txx9dmac_desc *desc;
+ LIST_HEAD(list);
+
+ prev = txx9dmac_last_child(prev);
+ txx9dmac_dequeue(dc, &list);
+ desc = list_entry(list.next, struct txx9dmac_desc, desc_node);
+ desc_write_CHAR(dc, prev, desc->txd.phys);
+ dma_sync_single_for_device(chan2parent(&dc->chan),
+ prev->txd.phys, ddev->descsize,
+ DMA_TO_DEVICE);
+ mmiowb();
+ if (!(channel_readl(dc, CSR) & TXX9_DMA_CSR_CHNEN) &&
+ channel_read_CHAR(dc) == prev->txd.phys)
+ /* Restart chain DMA */
+ channel_write_CHAR(dc, desc->txd.phys);
+ list_splice_tail(&list, &dc->active_list);
+}
+
+static void txx9dmac_issue_pending(struct dma_chan *chan)
+{
+ struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+
+ spin_lock_bh(&dc->lock);
+
+ if (!list_empty(&dc->active_list))
+ txx9dmac_scan_descriptors(dc);
+ if (!list_empty(&dc->queue)) {
+ if (list_empty(&dc->active_list)) {
+ txx9dmac_dequeue(dc, &dc->active_list);
+ txx9dmac_dostart(dc, txx9dmac_first_active(dc));
+ } else if (txx9_dma_have_SMPCHN()) {
+ struct txx9dmac_desc *prev = txx9dmac_last_active(dc);
+
+ if (!(prev->txd.flags & DMA_PREP_INTERRUPT) ||
+ txx9dmac_chan_INTENT(dc))
+ txx9dmac_chain_dynamic(dc, prev);
+ }
+ }
+
+ spin_unlock_bh(&dc->lock);
+}
+
+static int txx9dmac_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+ struct txx9dmac_slave *ds = chan->private;
+ struct txx9dmac_desc *desc;
+ int i;
+
+ dev_vdbg(chan2dev(chan), "alloc_chan_resources\n");
+
+ /* ASSERT: channel is idle */
+ if (channel_readl(dc, CSR) & TXX9_DMA_CSR_XFACT) {
+ dev_dbg(chan2dev(chan), "DMA channel not idle?\n");
+ return -EIO;
+ }
+
+ dc->completed = chan->cookie = 1;
+
+ dc->ccr = TXX9_DMA_CCR_IMMCHN | TXX9_DMA_CCR_INTENE | CCR_LE;
+ txx9dmac_chan_set_SMPCHN(dc);
+ if (!txx9_dma_have_SMPCHN() || (dc->ccr & TXX9_DMA_CCR_SMPCHN))
+ dc->ccr |= TXX9_DMA_CCR_INTENC;
+ if (chan->device->device_prep_dma_memcpy) {
+ if (ds)
+ return -EINVAL;
+ dc->ccr |= TXX9_DMA_CCR_XFSZ_X8;
+ } else {
+ if (!ds ||
+ (ds->tx_reg && ds->rx_reg) || (!ds->tx_reg && !ds->rx_reg))
+ return -EINVAL;
+ dc->ccr |= TXX9_DMA_CCR_EXTRQ |
+ TXX9_DMA_CCR_XFSZ(__ffs(ds->reg_width));
+ txx9dmac_chan_set_INTENT(dc);
+ }
+
+ spin_lock_bh(&dc->lock);
+ i = dc->descs_allocated;
+ while (dc->descs_allocated < TXX9_DMA_INITIAL_DESC_COUNT) {
+ spin_unlock_bh(&dc->lock);
+
+ desc = txx9dmac_desc_alloc(dc, GFP_KERNEL);
+ if (!desc) {
+ dev_info(chan2dev(chan),
+ "only allocated %d descriptors\n", i);
+ spin_lock_bh(&dc->lock);
+ break;
+ }
+ txx9dmac_desc_put(dc, desc);
+
+ spin_lock_bh(&dc->lock);
+ i = ++dc->descs_allocated;
+ }
+ spin_unlock_bh(&dc->lock);
+
+ dev_dbg(chan2dev(chan),
+ "alloc_chan_resources allocated %d descriptors\n", i);
+
+ return i;
+}
+
+static void txx9dmac_free_chan_resources(struct dma_chan *chan)
+{
+ struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+ struct txx9dmac_dev *ddev = dc->ddev;
+ struct txx9dmac_desc *desc, *_desc;
+ LIST_HEAD(list);
+
+ dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n",
+ dc->descs_allocated);
+
+ /* ASSERT: channel is idle */
+ BUG_ON(!list_empty(&dc->active_list));
+ BUG_ON(!list_empty(&dc->queue));
+ BUG_ON(channel_readl(dc, CSR) & TXX9_DMA_CSR_XFACT);
+
+ spin_lock_bh(&dc->lock);
+ list_splice_init(&dc->free_list, &list);
+ dc->descs_allocated = 0;
+ spin_unlock_bh(&dc->lock);
+
+ list_for_each_entry_safe(desc, _desc, &list, desc_node) {
+ dev_vdbg(chan2dev(chan), " freeing descriptor %p\n", desc);
+ dma_unmap_single(chan2parent(chan), desc->txd.phys,
+ ddev->descsize, DMA_TO_DEVICE);
+ kfree(desc);
+ }
+
+ dev_vdbg(chan2dev(chan), "free_chan_resources done\n");
+}
+
+/*----------------------------------------------------------------------*/
+
+static void txx9dmac_off(struct txx9dmac_dev *ddev)
+{
+ dma_writel(ddev, MCR, 0);
+ mmiowb();
+}
+
+static int __init txx9dmac_chan_probe(struct platform_device *pdev)
+{
+ struct txx9dmac_chan_platform_data *cpdata = pdev->dev.platform_data;
+ struct platform_device *dmac_dev = cpdata->dmac_dev;
+ struct txx9dmac_platform_data *pdata = dmac_dev->dev.platform_data;
+ struct txx9dmac_chan *dc;
+ int err;
+ int ch = pdev->id % TXX9_DMA_MAX_NR_CHANNELS;
+ int irq;
+
+ dc = devm_kzalloc(&pdev->dev, sizeof(*dc), GFP_KERNEL);
+ if (!dc)
+ return -ENOMEM;
+
+ dc->dma.dev = &pdev->dev;
+ dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources;
+ dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources;
+ dc->dma.device_terminate_all = txx9dmac_terminate_all;
+ dc->dma.device_is_tx_complete = txx9dmac_is_tx_complete;
+ dc->dma.device_issue_pending = txx9dmac_issue_pending;
+ if (pdata && pdata->memcpy_chan == ch) {
+ dc->dma.device_prep_dma_memcpy = txx9dmac_prep_dma_memcpy;
+ dma_cap_set(DMA_MEMCPY, dc->dma.cap_mask);
+ } else {
+ dc->dma.device_prep_slave_sg = txx9dmac_prep_slave_sg;
+ dma_cap_set(DMA_SLAVE, dc->dma.cap_mask);
+ dma_cap_set(DMA_PRIVATE, dc->dma.cap_mask);
+ }
+
+ INIT_LIST_HEAD(&dc->dma.channels);
+ dc->ddev = platform_get_drvdata(dmac_dev);
+ if (dc->ddev->irq < 0) {
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+ tasklet_init(&dc->tasklet, txx9dmac_chan_tasklet,
+ (unsigned long)dc);
+ dc->irq = irq;
+ err = devm_request_irq(&pdev->dev, dc->irq,
+ txx9dmac_chan_interrupt, 0, dev_name(&pdev->dev), dc);
+ if (err)
+ return err;
+ } else
+ dc->irq = -1;
+ dc->ddev->chan[ch] = dc;
+ dc->chan.device = &dc->dma;
+ list_add_tail(&dc->chan.device_node, &dc->chan.device->channels);
+ dc->chan.cookie = dc->completed = 1;
+
+ if (is_dmac64(dc))
+ dc->ch_regs = &__txx9dmac_regs(dc->ddev)->CHAN[ch];
+ else
+ dc->ch_regs = &__txx9dmac_regs32(dc->ddev)->CHAN[ch];
+ spin_lock_init(&dc->lock);
+
+ INIT_LIST_HEAD(&dc->active_list);
+ INIT_LIST_HEAD(&dc->queue);
+ INIT_LIST_HEAD(&dc->free_list);
+
+ txx9dmac_reset_chan(dc);
+
+ platform_set_drvdata(pdev, dc);
+
+ err = dma_async_device_register(&dc->dma);
+ if (err)
+ return err;
+ dev_dbg(&pdev->dev, "TXx9 DMA Channel (dma%d%s%s)\n",
+ dc->dma.dev_id,
+ dma_has_cap(DMA_MEMCPY, dc->dma.cap_mask) ? " memcpy" : "",
+ dma_has_cap(DMA_SLAVE, dc->dma.cap_mask) ? " slave" : "");
+
+ return 0;
+}
+
+static int __exit txx9dmac_chan_remove(struct platform_device *pdev)
+{
+ struct txx9dmac_chan *dc = platform_get_drvdata(pdev);
+
+ dma_async_device_unregister(&dc->dma);
+ if (dc->irq >= 0)
+ tasklet_kill(&dc->tasklet);
+ dc->ddev->chan[pdev->id % TXX9_DMA_MAX_NR_CHANNELS] = NULL;
+ return 0;
+}
+
+static int __init txx9dmac_probe(struct platform_device *pdev)
+{
+ struct txx9dmac_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *io;
+ struct txx9dmac_dev *ddev;
+ u32 mcr;
+ int err;
+
+ io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!io)
+ return -EINVAL;
+
+ ddev = devm_kzalloc(&pdev->dev, sizeof(*ddev), GFP_KERNEL);
+ if (!ddev)
+ return -ENOMEM;
+
+ if (!devm_request_mem_region(&pdev->dev, io->start, resource_size(io),
+ dev_name(&pdev->dev)))
+ return -EBUSY;
+
+ ddev->regs = devm_ioremap(&pdev->dev, io->start, resource_size(io));
+ if (!ddev->regs)
+ return -ENOMEM;
+ ddev->have_64bit_regs = pdata->have_64bit_regs;
+ if (__is_dmac64(ddev))
+ ddev->descsize = sizeof(struct txx9dmac_hwdesc);
+ else
+ ddev->descsize = sizeof(struct txx9dmac_hwdesc32);
+
+ /* force dma off, just in case */
+ txx9dmac_off(ddev);
+
+ ddev->irq = platform_get_irq(pdev, 0);
+ if (ddev->irq >= 0) {
+ tasklet_init(&ddev->tasklet, txx9dmac_tasklet,
+ (unsigned long)ddev);
+ err = devm_request_irq(&pdev->dev, ddev->irq,
+ txx9dmac_interrupt, 0, dev_name(&pdev->dev), ddev);
+ if (err)
+ return err;
+ }
+
+ mcr = TXX9_DMA_MCR_MSTEN | MCR_LE;
+ if (pdata && pdata->memcpy_chan >= 0)
+ mcr |= TXX9_DMA_MCR_FIFUM(pdata->memcpy_chan);
+ dma_writel(ddev, MCR, mcr);
+
+ platform_set_drvdata(pdev, ddev);
+ return 0;
+}
+
+static int __exit txx9dmac_remove(struct platform_device *pdev)
+{
+ struct txx9dmac_dev *ddev = platform_get_drvdata(pdev);
+
+ txx9dmac_off(ddev);
+ if (ddev->irq >= 0)
+ tasklet_kill(&ddev->tasklet);
+ return 0;
+}
+
+static void txx9dmac_shutdown(struct platform_device *pdev)
+{
+ struct txx9dmac_dev *ddev = platform_get_drvdata(pdev);
+
+ txx9dmac_off(ddev);
+}
+
+static int txx9dmac_suspend_late(struct platform_device *pdev,
+ pm_message_t mesg)
+{
+ struct txx9dmac_dev *ddev = platform_get_drvdata(pdev);
+
+ txx9dmac_off(ddev);
+ return 0;
+}
+
+static int txx9dmac_resume_early(struct platform_device *pdev)
+{
+ struct txx9dmac_dev *ddev = platform_get_drvdata(pdev);
+ struct txx9dmac_platform_data *pdata = pdev->dev.platform_data;
+ u32 mcr;
+
+ mcr = TXX9_DMA_MCR_MSTEN | MCR_LE;
+ if (pdata && pdata->memcpy_chan >= 0)
+ mcr |= TXX9_DMA_MCR_FIFUM(pdata->memcpy_chan);
+ dma_writel(ddev, MCR, mcr);
+ return 0;
+
+}
+
+static struct platform_driver txx9dmac_chan_driver = {
+ .remove = __exit_p(txx9dmac_chan_remove),
+ .driver = {
+ .name = "txx9dmac-chan",
+ },
+};
+
+static struct platform_driver txx9dmac_driver = {
+ .remove = __exit_p(txx9dmac_remove),
+ .shutdown = txx9dmac_shutdown,
+ .suspend_late = txx9dmac_suspend_late,
+ .resume_early = txx9dmac_resume_early,
+ .driver = {
+ .name = "txx9dmac",
+ },
+};
+
+static int __init txx9dmac_init(void)
+{
+ int rc;
+
+ rc = platform_driver_probe(&txx9dmac_driver, txx9dmac_probe);
+ if (!rc) {
+ rc = platform_driver_probe(&txx9dmac_chan_driver,
+ txx9dmac_chan_probe);
+ if (rc)
+ platform_driver_unregister(&txx9dmac_driver);
+ }
+ return rc;
+}
+module_init(txx9dmac_init);
+
+static void __exit txx9dmac_exit(void)
+{
+ platform_driver_unregister(&txx9dmac_chan_driver);
+ platform_driver_unregister(&txx9dmac_driver);
+}
+module_exit(txx9dmac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TXx9 DMA Controller driver");
+MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
diff --git a/drivers/dma/txx9dmac.h b/drivers/dma/txx9dmac.h
new file mode 100644
index 000000000000..c907ff01d276
--- /dev/null
+++ b/drivers/dma/txx9dmac.h
@@ -0,0 +1,307 @@
+/*
+ * Driver for the TXx9 SoC DMA Controller
+ *
+ * Copyright (C) 2009 Atsushi Nemoto
+ *
+ * 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 TXX9DMAC_H
+#define TXX9DMAC_H
+
+#include <linux/dmaengine.h>
+#include <asm/txx9/dmac.h>
+
+/*
+ * Design Notes:
+ *
+ * This DMAC have four channels and one FIFO buffer. Each channel can
+ * be configured for memory-memory or device-memory transfer, but only
+ * one channel can do alignment-free memory-memory transfer at a time
+ * while the channel should occupy the FIFO buffer for effective
+ * transfers.
+ *
+ * Instead of dynamically assign the FIFO buffer to channels, I chose
+ * make one dedicated channel for memory-memory transfer. The
+ * dedicated channel is public. Other channels are private and used
+ * for slave transfer. Some devices in the SoC are wired to certain
+ * DMA channel.
+ */
+
+#ifdef CONFIG_MACH_TX49XX
+static inline bool txx9_dma_have_SMPCHN(void)
+{
+ return true;
+}
+#define TXX9_DMA_USE_SIMPLE_CHAIN
+#else
+static inline bool txx9_dma_have_SMPCHN(void)
+{
+ return false;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN
+#ifdef CONFIG_MACH_TX49XX
+#define CCR_LE TXX9_DMA_CCR_LE
+#define MCR_LE 0
+#else
+#define CCR_LE 0
+#define MCR_LE TXX9_DMA_MCR_LE
+#endif
+#else
+#define CCR_LE 0
+#define MCR_LE 0
+#endif
+
+/*
+ * Redefine this macro to handle differences between 32- and 64-bit
+ * addressing, big vs. little endian, etc.
+ */
+#ifdef __BIG_ENDIAN
+#define TXX9_DMA_REG32(name) u32 __pad_##name; u32 name
+#else
+#define TXX9_DMA_REG32(name) u32 name; u32 __pad_##name
+#endif
+
+/* Hardware register definitions. */
+struct txx9dmac_cregs {
+#if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR)
+ TXX9_DMA_REG32(CHAR); /* Chain Address Register */
+#else
+ u64 CHAR; /* Chain Address Register */
+#endif
+ u64 SAR; /* Source Address Register */
+ u64 DAR; /* Destination Address Register */
+ TXX9_DMA_REG32(CNTR); /* Count Register */
+ TXX9_DMA_REG32(SAIR); /* Source Address Increment Register */
+ TXX9_DMA_REG32(DAIR); /* Destination Address Increment Register */
+ TXX9_DMA_REG32(CCR); /* Channel Control Register */
+ TXX9_DMA_REG32(CSR); /* Channel Status Register */
+};
+struct txx9dmac_cregs32 {
+ u32 CHAR;
+ u32 SAR;
+ u32 DAR;
+ u32 CNTR;
+ u32 SAIR;
+ u32 DAIR;
+ u32 CCR;
+ u32 CSR;
+};
+
+struct txx9dmac_regs {
+ /* per-channel registers */
+ struct txx9dmac_cregs CHAN[TXX9_DMA_MAX_NR_CHANNELS];
+ u64 __pad[9];
+ u64 MFDR; /* Memory Fill Data Register */
+ TXX9_DMA_REG32(MCR); /* Master Control Register */
+};
+struct txx9dmac_regs32 {
+ struct txx9dmac_cregs32 CHAN[TXX9_DMA_MAX_NR_CHANNELS];
+ u32 __pad[9];
+ u32 MFDR;
+ u32 MCR;
+};
+
+/* bits for MCR */
+#define TXX9_DMA_MCR_EIS(ch) (0x10000000<<(ch))
+#define TXX9_DMA_MCR_DIS(ch) (0x01000000<<(ch))
+#define TXX9_DMA_MCR_RSFIF 0x00000080
+#define TXX9_DMA_MCR_FIFUM(ch) (0x00000008<<(ch))
+#define TXX9_DMA_MCR_LE 0x00000004
+#define TXX9_DMA_MCR_RPRT 0x00000002
+#define TXX9_DMA_MCR_MSTEN 0x00000001
+
+/* bits for CCRn */
+#define TXX9_DMA_CCR_IMMCHN 0x20000000
+#define TXX9_DMA_CCR_USEXFSZ 0x10000000
+#define TXX9_DMA_CCR_LE 0x08000000
+#define TXX9_DMA_CCR_DBINH 0x04000000
+#define TXX9_DMA_CCR_SBINH 0x02000000
+#define TXX9_DMA_CCR_CHRST 0x01000000
+#define TXX9_DMA_CCR_RVBYTE 0x00800000
+#define TXX9_DMA_CCR_ACKPOL 0x00400000
+#define TXX9_DMA_CCR_REQPL 0x00200000
+#define TXX9_DMA_CCR_EGREQ 0x00100000
+#define TXX9_DMA_CCR_CHDN 0x00080000
+#define TXX9_DMA_CCR_DNCTL 0x00060000
+#define TXX9_DMA_CCR_EXTRQ 0x00010000
+#define TXX9_DMA_CCR_INTRQD 0x0000e000
+#define TXX9_DMA_CCR_INTENE 0x00001000
+#define TXX9_DMA_CCR_INTENC 0x00000800
+#define TXX9_DMA_CCR_INTENT 0x00000400
+#define TXX9_DMA_CCR_CHNEN 0x00000200
+#define TXX9_DMA_CCR_XFACT 0x00000100
+#define TXX9_DMA_CCR_SMPCHN 0x00000020
+#define TXX9_DMA_CCR_XFSZ(order) (((order) << 2) & 0x0000001c)
+#define TXX9_DMA_CCR_XFSZ_1 TXX9_DMA_CCR_XFSZ(0)
+#define TXX9_DMA_CCR_XFSZ_2 TXX9_DMA_CCR_XFSZ(1)
+#define TXX9_DMA_CCR_XFSZ_4 TXX9_DMA_CCR_XFSZ(2)
+#define TXX9_DMA_CCR_XFSZ_8 TXX9_DMA_CCR_XFSZ(3)
+#define TXX9_DMA_CCR_XFSZ_X4 TXX9_DMA_CCR_XFSZ(4)
+#define TXX9_DMA_CCR_XFSZ_X8 TXX9_DMA_CCR_XFSZ(5)
+#define TXX9_DMA_CCR_XFSZ_X16 TXX9_DMA_CCR_XFSZ(6)
+#define TXX9_DMA_CCR_XFSZ_X32 TXX9_DMA_CCR_XFSZ(7)
+#define TXX9_DMA_CCR_MEMIO 0x00000002
+#define TXX9_DMA_CCR_SNGAD 0x00000001
+
+/* bits for CSRn */
+#define TXX9_DMA_CSR_CHNEN 0x00000400
+#define TXX9_DMA_CSR_STLXFER 0x00000200
+#define TXX9_DMA_CSR_XFACT 0x00000100
+#define TXX9_DMA_CSR_ABCHC 0x00000080
+#define TXX9_DMA_CSR_NCHNC 0x00000040
+#define TXX9_DMA_CSR_NTRNFC 0x00000020
+#define TXX9_DMA_CSR_EXTDN 0x00000010
+#define TXX9_DMA_CSR_CFERR 0x00000008
+#define TXX9_DMA_CSR_CHERR 0x00000004
+#define TXX9_DMA_CSR_DESERR 0x00000002
+#define TXX9_DMA_CSR_SORERR 0x00000001
+
+struct txx9dmac_chan {
+ struct dma_chan chan;
+ struct dma_device dma;
+ struct txx9dmac_dev *ddev;
+ void __iomem *ch_regs;
+ struct tasklet_struct tasklet;
+ int irq;
+ u32 ccr;
+
+ spinlock_t lock;
+
+ /* these other elements are all protected by lock */
+ dma_cookie_t completed;
+ struct list_head active_list;
+ struct list_head queue;
+ struct list_head free_list;
+
+ unsigned int descs_allocated;
+};
+
+struct txx9dmac_dev {
+ void __iomem *regs;
+ struct tasklet_struct tasklet;
+ int irq;
+ struct txx9dmac_chan *chan[TXX9_DMA_MAX_NR_CHANNELS];
+ bool have_64bit_regs;
+ unsigned int descsize;
+};
+
+static inline bool __is_dmac64(const struct txx9dmac_dev *ddev)
+{
+ return ddev->have_64bit_regs;
+}
+
+static inline bool is_dmac64(const struct txx9dmac_chan *dc)
+{
+ return __is_dmac64(dc->ddev);
+}
+
+#ifdef TXX9_DMA_USE_SIMPLE_CHAIN
+/* Hardware descriptor definition. (for simple-chain) */
+struct txx9dmac_hwdesc {
+#if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR)
+ TXX9_DMA_REG32(CHAR);
+#else
+ u64 CHAR;
+#endif
+ u64 SAR;
+ u64 DAR;
+ TXX9_DMA_REG32(CNTR);
+};
+struct txx9dmac_hwdesc32 {
+ u32 CHAR;
+ u32 SAR;
+ u32 DAR;
+ u32 CNTR;
+};
+#else
+#define txx9dmac_hwdesc txx9dmac_cregs
+#define txx9dmac_hwdesc32 txx9dmac_cregs32
+#endif
+
+struct txx9dmac_desc {
+ /* FIRST values the hardware uses */
+ union {
+ struct txx9dmac_hwdesc hwdesc;
+ struct txx9dmac_hwdesc32 hwdesc32;
+ };
+
+ /* THEN values for driver housekeeping */
+ struct list_head desc_node ____cacheline_aligned;
+ struct dma_async_tx_descriptor txd;
+ size_t len;
+};
+
+#ifdef TXX9_DMA_USE_SIMPLE_CHAIN
+
+static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
+{
+ return (dc->ccr & TXX9_DMA_CCR_INTENT) != 0;
+}
+
+static inline void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
+{
+ dc->ccr |= TXX9_DMA_CCR_INTENT;
+}
+
+static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
+ struct txx9dmac_desc *desc)
+{
+}
+
+static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
+{
+ dc->ccr |= TXX9_DMA_CCR_SMPCHN;
+}
+
+static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
+ struct txx9dmac_desc *desc,
+ u32 sair, u32 dair, u32 ccr)
+{
+}
+
+#else /* TXX9_DMA_USE_SIMPLE_CHAIN */
+
+static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
+{
+ return true;
+}
+
+static void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
+{
+}
+
+static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
+ struct txx9dmac_desc *desc)
+{
+ if (__is_dmac64(ddev))
+ desc->hwdesc.CCR |= TXX9_DMA_CCR_INTENT;
+ else
+ desc->hwdesc32.CCR |= TXX9_DMA_CCR_INTENT;
+}
+
+static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
+{
+}
+
+static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
+ struct txx9dmac_desc *desc,
+ u32 sai, u32 dai, u32 ccr)
+{
+ if (__is_dmac64(ddev)) {
+ desc->hwdesc.SAIR = sai;
+ desc->hwdesc.DAIR = dai;
+ desc->hwdesc.CCR = ccr;
+ } else {
+ desc->hwdesc32.SAIR = sai;
+ desc->hwdesc32.DAIR = dai;
+ desc->hwdesc32.CCR = ccr;
+ }
+}
+
+#endif /* TXX9_DMA_USE_SIMPLE_CHAIN */
+
+#endif /* TXX9DMAC_H */
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 18d65fb42ee7..e8727817c8b5 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -237,6 +237,23 @@ static ssize_t host_control_on_shutdown_store(struct device *dev,
return count;
}
+static long generate_smi(void *_smi_cmd)
+{
+ struct smi_cmd *smi_cmd = _smi_cmd;
+
+ /* generate SMI */
+ asm volatile (
+ "outb %b0,%w1"
+ : /* no output args */
+ : "a" (smi_cmd->command_code),
+ "d" (smi_cmd->command_address),
+ "b" (smi_cmd->ebx),
+ "c" (smi_cmd->ecx)
+ : "memory"
+ );
+ return 0;
+}
+
/**
* dcdbas_smi_request: generate SMI request
*
@@ -244,9 +261,6 @@ static ssize_t host_control_on_shutdown_store(struct device *dev,
*/
int dcdbas_smi_request(struct smi_cmd *smi_cmd)
{
- cpumask_var_t old_mask;
- int ret = 0;
-
if (smi_cmd->magic != SMI_CMD_MAGIC) {
dev_info(&dcdbas_pdev->dev, "%s: invalid magic value\n",
__func__);
@@ -254,35 +268,8 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd)
}
/* SMI requires CPU 0 */
- if (!alloc_cpumask_var(&old_mask, GFP_KERNEL))
- return -ENOMEM;
-
- cpumask_copy(old_mask, &current->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(0));
- if (smp_processor_id() != 0) {
- dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n",
- __func__);
- ret = -EBUSY;
- goto out;
- }
-
- /* generate SMI */
- asm volatile (
- "outb %b0,%w1"
- : /* no output args */
- : "a" (smi_cmd->command_code),
- "d" (smi_cmd->command_address),
- "b" (smi_cmd->ebx),
- "c" (smi_cmd->ecx)
- : "memory"
- );
-
-out:
- set_cpus_allowed_ptr(current, old_mask);
- free_cpumask_var(old_mask);
- return ret;
+ return work_on_cpu(0, generate_smi, smi_cmd);
}
-
/**
* smi_request_store:
*
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 3a22eb9be378..4cd35d8fd799 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -71,6 +71,7 @@ config DRM_I915
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB
+ select FRAMEBUFFER_CONSOLE if !EMBEDDED
tristate "i915 driver"
help
Choose this option if you have a system that has Intel 830M, 845G,
@@ -83,6 +84,12 @@ config DRM_I915
config DRM_I915_KMS
bool "Enable modesetting on intel by default"
depends on DRM_I915
+ # i915 KMS depends on ACPI_VIDEO when ACPI is enabled
+ # but for select to work, need to select ACPI_VIDEO's dependencies, ick
+ select VIDEO_OUTPUT_CONTROL if ACPI
+ select BACKLIGHT_CLASS_DEVICE if ACPI
+ select INPUT if ACPI
+ select ACPI_VIDEO if ACPI
help
Choose this option if you want kernel modesetting enabled by default,
and you have a new enough userspace to support this. Running old
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 7e67dcb3d4f6..21edf407bbda 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -271,6 +271,13 @@ config THRUSTMASTER_FF
Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel.
+config HID_WACOM
+ tristate "Wacom Bluetooth devices support" if EMBEDDED
+ depends on BT_HIDP
+ default !EMBEDDED
+ ---help---
+ Support for Wacom Graphire Bluetooth tablet.
+
config ZEROPLUS_FF
tristate "Zeroplus based game controller support"
depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 1f7cb0fd4505..39cebcfa898c 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_GREENASIA_FF) += hid-gaff.o
obj-$(CONFIG_THRUSTMASTER_FF) += hid-tmff.o
obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
obj-$(CONFIG_ZEROPLUS_FF) += hid-zpff.o
+obj-$(CONFIG_HID_WACOM) += hid-wacom.o
obj-$(CONFIG_USB_HID) += usbhid/
obj-$(CONFIG_USB_MOUSE) += usbhid/
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8551693d645f..9f38ab874c93 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1312,6 +1312,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index aa1b995dd033..b519692732db 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -113,6 +113,11 @@
#define USB_VENDOR_ID_BERKSHIRE 0x0c98
#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
+#define USB_VENDOR_ID_CH 0x068e
+#define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2
+#define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4
+#define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff
+
#define USB_VENDOR_ID_CHERRY 0x046a
#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
@@ -409,6 +414,7 @@
#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006
#define USB_VENDOR_ID_WACOM 0x056a
+#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
#define USB_VENDOR_ID_WISEGROUP 0x0925
#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101
diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c
index 51aff08e10ce..9735be6ee4ff 100644
--- a/drivers/hid/hid-lgff.c
+++ b/drivers/hid/hid-lgff.c
@@ -61,7 +61,7 @@ static const struct dev_type devices[] = {
{ 0x046d, 0xc219, ff_rumble },
{ 0x046d, 0xc283, ff_joystick },
{ 0x046d, 0xc286, ff_joystick },
- { 0x046d, 0xc294, ff_joystick },
+ { 0x046d, 0xc294, ff_wheel },
{ 0x046d, 0xc295, ff_joystick },
{ 0x046d, 0xca03, ff_wheel },
};
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
new file mode 100644
index 000000000000..1f9237f511e3
--- /dev/null
+++ b/drivers/hid/hid-wacom.c
@@ -0,0 +1,259 @@
+/*
+ * Bluetooth Wacom Tablet support
+ *
+ * Copyright (c) 1999 Andreas Gal
+ * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
+ * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
+ * Copyright (c) 2006-2007 Jiri Kosina
+ * Copyright (c) 2007 Paul Walmsley
+ * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2006 Andrew Zabolotny <zap@homelink.ru>
+ * Copyright (c) 2009 Bastien Nocera <hadess@hadess.net>
+ */
+
+/*
+ * 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/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+struct wacom_data {
+ __u16 tool;
+ unsigned char butstate;
+};
+
+static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
+ u8 *raw_data, int size)
+{
+ struct wacom_data *wdata = hid_get_drvdata(hdev);
+ struct hid_input *hidinput;
+ struct input_dev *input;
+ unsigned char *data = (unsigned char *) raw_data;
+ int tool, x, y, rw;
+
+ if (!(hdev->claimed & HID_CLAIMED_INPUT))
+ return 0;
+
+ tool = 0;
+ hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
+ input = hidinput->input;
+
+ /* Check if this is a tablet report */
+ if (data[0] != 0x03)
+ return 0;
+
+ /* Get X & Y positions */
+ x = le16_to_cpu(*(__le16 *) &data[2]);
+ y = le16_to_cpu(*(__le16 *) &data[4]);
+
+ /* Get current tool identifier */
+ if (data[1] & 0x90) { /* If pen is in the in/active area */
+ switch ((data[1] >> 5) & 3) {
+ case 0: /* Pen */
+ tool = BTN_TOOL_PEN;
+ break;
+
+ case 1: /* Rubber */
+ tool = BTN_TOOL_RUBBER;
+ break;
+
+ case 2: /* Mouse with wheel */
+ case 3: /* Mouse without wheel */
+ tool = BTN_TOOL_MOUSE;
+ break;
+ }
+
+ /* Reset tool if out of active tablet area */
+ if (!(data[1] & 0x10))
+ tool = 0;
+ }
+
+ /* If tool changed, notify input subsystem */
+ if (wdata->tool != tool) {
+ if (wdata->tool) {
+ /* Completely reset old tool state */
+ if (wdata->tool == BTN_TOOL_MOUSE) {
+ input_report_key(input, BTN_LEFT, 0);
+ input_report_key(input, BTN_RIGHT, 0);
+ input_report_key(input, BTN_MIDDLE, 0);
+ input_report_abs(input, ABS_DISTANCE,
+ input->absmax[ABS_DISTANCE]);
+ } else {
+ input_report_key(input, BTN_TOUCH, 0);
+ input_report_key(input, BTN_STYLUS, 0);
+ input_report_key(input, BTN_STYLUS2, 0);
+ input_report_abs(input, ABS_PRESSURE, 0);
+ }
+ input_report_key(input, wdata->tool, 0);
+ input_sync(input);
+ }
+ wdata->tool = tool;
+ if (tool)
+ input_report_key(input, tool, 1);
+ }
+
+ if (tool) {
+ input_report_abs(input, ABS_X, x);
+ input_report_abs(input, ABS_Y, y);
+
+ switch ((data[1] >> 5) & 3) {
+ case 2: /* Mouse with wheel */
+ input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
+ rw = (data[6] & 0x01) ? -1 :
+ (data[6] & 0x02) ? 1 : 0;
+ input_report_rel(input, REL_WHEEL, rw);
+ /* fall through */
+
+ case 3: /* Mouse without wheel */
+ input_report_key(input, BTN_LEFT, data[1] & 0x01);
+ input_report_key(input, BTN_RIGHT, data[1] & 0x02);
+ /* Compute distance between mouse and tablet */
+ rw = 44 - (data[6] >> 2);
+ if (rw < 0)
+ rw = 0;
+ else if (rw > 31)
+ rw = 31;
+ input_report_abs(input, ABS_DISTANCE, rw);
+ break;
+
+ default:
+ input_report_abs(input, ABS_PRESSURE,
+ data[6] | (((__u16) (data[1] & 0x08)) << 5));
+ input_report_key(input, BTN_TOUCH, data[1] & 0x01);
+ input_report_key(input, BTN_STYLUS, data[1] & 0x02);
+ input_report_key(input, BTN_STYLUS2, (tool == BTN_TOOL_PEN) && data[1] & 0x04);
+ break;
+ }
+
+ input_sync(input);
+ }
+
+ /* Report the state of the two buttons at the top of the tablet
+ * as two extra fingerpad keys (buttons 4 & 5). */
+ rw = data[7] & 0x03;
+ if (rw != wdata->butstate) {
+ wdata->butstate = rw;
+ input_report_key(input, BTN_0, rw & 0x02);
+ input_report_key(input, BTN_1, rw & 0x01);
+ input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
+ input_sync(input);
+ }
+
+ return 1;
+}
+
+static int wacom_probe(struct hid_device *hdev,
+ const struct hid_device_id *id)
+{
+ struct hid_input *hidinput;
+ struct input_dev *input;
+ struct wacom_data *wdata;
+ int ret;
+
+ wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
+ if (wdata == NULL) {
+ dev_err(&hdev->dev, "can't alloc wacom descriptor\n");
+ return -ENOMEM;
+ }
+
+ hid_set_drvdata(hdev, wdata);
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ dev_err(&hdev->dev, "parse failed\n");
+ goto err_free;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (ret) {
+ dev_err(&hdev->dev, "hw start failed\n");
+ goto err_free;
+ }
+
+ hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
+ input = hidinput->input;
+
+ /* Basics */
+ input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
+ input->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) |
+ BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE);
+ input->relbit[0] |= BIT(REL_WHEEL);
+ set_bit(BTN_TOOL_PEN, input->keybit);
+ set_bit(BTN_TOUCH, input->keybit);
+ set_bit(BTN_STYLUS, input->keybit);
+ set_bit(BTN_STYLUS2, input->keybit);
+ set_bit(BTN_LEFT, input->keybit);
+ set_bit(BTN_RIGHT, input->keybit);
+ set_bit(BTN_MIDDLE, input->keybit);
+
+ /* Pad */
+ input->evbit[0] |= BIT(EV_MSC);
+ input->mscbit[0] |= BIT(MSC_SERIAL);
+
+ /* Distance, rubber and mouse */
+ input->absbit[0] |= BIT(ABS_DISTANCE);
+ set_bit(BTN_TOOL_RUBBER, input->keybit);
+ set_bit(BTN_TOOL_MOUSE, input->keybit);
+
+ input->absmax[ABS_PRESSURE] = 511;
+ input->absmax[ABS_DISTANCE] = 32;
+
+ input->absmax[ABS_X] = 16704;
+ input->absmax[ABS_Y] = 12064;
+ input->absfuzz[ABS_X] = 4;
+ input->absfuzz[ABS_Y] = 4;
+
+ return 0;
+err_free:
+ kfree(wdata);
+ return ret;
+}
+
+static void wacom_remove(struct hid_device *hdev)
+{
+ hid_hw_stop(hdev);
+ kfree(hid_get_drvdata(hdev));
+}
+
+static const struct hid_device_id wacom_devices[] = {
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
+
+ { }
+};
+MODULE_DEVICE_TABLE(hid, wacom_devices);
+
+static struct hid_driver wacom_driver = {
+ .name = "wacom",
+ .id_table = wacom_devices,
+ .probe = wacom_probe,
+ .remove = wacom_remove,
+ .raw_event = wacom_raw_event,
+};
+
+static int wacom_init(void)
+{
+ int ret;
+
+ ret = hid_register_driver(&wacom_driver);
+ if (ret)
+ printk(KERN_ERR "can't register wacom driver\n");
+ printk(KERN_ERR "wacom driver registered\n");
+ return ret;
+}
+
+static void wacom_exit(void)
+{
+ hid_unregister_driver(&wacom_driver);
+}
+
+module_init(wacom_init);
+module_exit(wacom_exit);
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 900ce18dd549..ac8049b5f1e9 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -898,7 +898,7 @@ static int usbhid_parse(struct hid_device *hid)
goto err;
}
- hid->quirks = quirks;
+ hid->quirks |= quirks;
return 0;
err:
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 4391717d2519..d8f7423f363e 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -50,6 +50,9 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index d73f5f473e38..86a5cff0c027 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -418,7 +418,7 @@ config SENSORS_IBMAEM
power sensors and capping hardware in various IBM System X
servers that support Active Energy Manager. This includes
the x3350, x3550, x3650, x3655, x3755, x3850 M2, x3950 M2,
- and certain HS2x/LS2x/QS2x blades.
+ and certain HC10/HS2x/LS2x/QS2x blades.
This driver can also be built as a module. If so, the module
will be called ibmaem.
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index 0897edef2574..bff0103610c1 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -348,6 +348,7 @@ static int validate_hwmon_pack(struct atk_data *data, union acpi_object *obj)
return 0;
}
+#ifdef DEBUG
static char const *atk_sensor_type(union acpi_object *flags)
{
u64 type = flags->integer.value & ATK_TYPE_MASK;
@@ -370,6 +371,7 @@ static char const *atk_sensor_type(union acpi_object *flags)
return what;
}
+#endif
static void atk_print_sensor(struct atk_data *data, union acpi_object *obj)
{
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index fe74609a7feb..405d3fb5d76f 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -1127,3 +1127,4 @@ MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650-*");
MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3655-*");
MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3755-*");
MODULE_ALIAS("dmi:bvnIBM:*:pnIBM3850M2/x3950M2-*");
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMBladeHC10-*");
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index dbfb30c588d8..0bdab959b736 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -1462,7 +1462,8 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
data->pwm[i] =
w83781d_read_value(data,
W83781D_REG_PWM[i]);
- if ((data->type != w83782d || !client->driver)
+ /* Only W83782D on SMBus has PWM3 and PWM4 */
+ if ((data->type != w83782d || !client)
&& i == 1)
break;
}
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index a48c8aee0218..f1c6ca7e2852 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -467,7 +467,7 @@ config I2C_PXA_SLAVE
config I2C_S3C2410
tristate "S3C2410 I2C Driver"
- depends on ARCH_S3C2410
+ depends on ARCH_S3C2410 || ARCH_S3C64XX
help
Say Y here to include support for I2C controller in the
Samsung S3C2410 based System-on-Chip devices.
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
index 3fcf78e906db..b5db8b883615 100644
--- a/drivers/i2c/busses/i2c-cpm.c
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -531,16 +531,16 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm)
rbdf = cpm->rbase;
for (i = 0; i < CPM_MAXBD; i++) {
- cpm->rxbuf[i] = dma_alloc_coherent(
- NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL);
+ cpm->rxbuf[i] = dma_alloc_coherent(&cpm->ofdev->dev,
+ CPM_MAX_READ + 1,
+ &cpm->rxdma[i], GFP_KERNEL);
if (!cpm->rxbuf[i]) {
ret = -ENOMEM;
goto out_muram;
}
out_be32(&rbdf[i].cbd_bufaddr, ((cpm->rxdma[i] + 1) & ~1));
- cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(
- NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
+ cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
if (!cpm->txbuf[i]) {
ret = -ENOMEM;
goto out_muram;
@@ -585,10 +585,10 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm)
out_muram:
for (i = 0; i < CPM_MAXBD; i++) {
if (cpm->rxbuf[i])
- dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
cpm->rxbuf[i], cpm->rxdma[i]);
if (cpm->txbuf[i])
- dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
cpm->txbuf[i], cpm->txdma[i]);
}
cpm_muram_free(cpm->dp_addr);
@@ -619,9 +619,9 @@ static void cpm_i2c_shutdown(struct cpm_i2c *cpm)
/* Free all memory */
for (i = 0; i < CPM_MAXBD; i++) {
- dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
cpm->rxbuf[i], cpm->rxdma[i]);
- dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
cpm->txbuf[i], cpm->txdma[i]);
}
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 4af5c09f0e8f..dd778d7ae047 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -164,7 +164,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
return 0;
}
-#ifdef CONFIG_PPC_52xx
+#ifdef CONFIG_PPC_MPC52xx
static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
{20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
{28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
@@ -188,7 +188,7 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
{
- const struct mpc52xx_i2c_divider *div = NULL;
+ const struct mpc_i2c_divider *div = NULL;
unsigned int pvr = mfspr(SPRN_PVR);
u32 divider;
int i;
@@ -203,7 +203,7 @@ int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
* We want to choose an FDR/DFSR that generates an I2C bus speed that
* is equal to or lower than the requested speed.
*/
- for (i = 0; i < ARRAY_SIZE(mpc52xx_i2c_dividers); i++) {
+ for (i = 0; i < ARRAY_SIZE(mpc_i2c_dividers_52xx); i++) {
div = &mpc_i2c_dividers_52xx[i];
/* Old MPC5200 rev A CPUs do not support the high bits */
if (div->fdr & 0xc0 && pvr == 0x80822011)
@@ -219,20 +219,23 @@ static void mpc_i2c_setclock_52xx(struct device_node *node,
struct mpc_i2c *i2c,
u32 clock, u32 prescaler)
{
- int fdr = mpc52xx_i2c_get_fdr(node, clock, prescaler);
+ int ret, fdr;
+
+ ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
+ fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
- if (fdr < 0)
- fdr = 0x3f; /* backward compatibility */
writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
- dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
+
+ if (ret >= 0)
+ dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
}
-#else /* !CONFIG_PPC_52xx */
+#else /* !CONFIG_PPC_MPC52xx */
static void mpc_i2c_setclock_52xx(struct device_node *node,
struct mpc_i2c *i2c,
u32 clock, u32 prescaler)
{
}
-#endif /* CONFIG_PPC_52xx*/
+#endif /* CONFIG_PPC_MPC52xx*/
#ifdef CONFIG_FSL_SOC
static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
@@ -321,14 +324,17 @@ static void mpc_i2c_setclock_8xxx(struct device_node *node,
struct mpc_i2c *i2c,
u32 clock, u32 prescaler)
{
- int fdr = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
+ int ret, fdr;
+
+ ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
+ fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
- if (fdr < 0)
- fdr = 0x1031; /* backward compatibility */
writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
writeb((fdr >> 8) & 0xff, i2c->base + MPC_I2C_DFSRR);
- dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n",
- clock, fdr >> 8, fdr & 0xff);
+
+ if (ret >= 0)
+ dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n",
+ clock, fdr >> 8, fdr & 0xff);
}
#else /* !CONFIG_FSL_SOC */
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index c1405c8f6ba5..035a6c7e59df 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -34,10 +34,24 @@
#include <linux/err.h>
#include <linux/clk.h>
-#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/io.h>
-#include <mach/i2c.h>
+#include <plat/i2c.h>
+
+/*
+ * I2C register offsets will be shifted 0 or 1 bit left, depending on
+ * different SoCs
+ */
+#define REG_SHIFT_0 (0 << 0)
+#define REG_SHIFT_1 (1 << 0)
+#define REG_SHIFT(d) ((d) & 0x1)
+
+static const struct platform_device_id i2c_pxa_id_table[] = {
+ { "pxa2xx-i2c", REG_SHIFT_1 },
+ { "pxa3xx-pwri2c", REG_SHIFT_0 },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
/*
* I2C registers and bit definitions
@@ -265,10 +279,10 @@ static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
show_state(i2c);
}
- if (timeout <= 0)
+ if (timeout < 0)
show_state(i2c);
- return timeout <= 0 ? I2C_RETRY : 0;
+ return timeout < 0 ? I2C_RETRY : 0;
}
static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
@@ -612,7 +626,7 @@ static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
show_state(i2c);
}
- if (timeout <= 0) {
+ if (timeout < 0) {
show_state(i2c);
dev_err(&i2c->adap.dev,
"i2c_pxa: timeout waiting for bus free\n");
@@ -985,6 +999,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
struct pxa_i2c *i2c;
struct resource *res;
struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
+ struct platform_device_id *id = platform_get_device_id(dev);
int ret;
int irq;
@@ -1028,7 +1043,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
ret = -EIO;
goto eremap;
}
- i2c->reg_shift = (cpu_is_pxa3xx() && (dev->id == 1)) ? 0 : 1;
+ i2c->reg_shift = REG_SHIFT(id->driver_data);
i2c->iobase = res->start;
i2c->iosize = res_len(res);
@@ -1150,6 +1165,7 @@ static struct platform_driver i2c_pxa_driver = {
.name = "pxa2xx-i2c",
.owner = THIS_MODULE,
},
+ .id_table = i2c_pxa_id_table,
};
static int __init i2c_adap_pxa_init(void)
diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
index 1a474acc0ddd..7663d57833a0 100644
--- a/drivers/i2c/busses/i2c-voodoo3.c
+++ b/drivers/i2c/busses/i2c-voodoo3.c
@@ -163,7 +163,6 @@ static struct i2c_algo_bit_data voo_i2c_bit_data = {
static struct i2c_adapter voodoo3_i2c_adapter = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
.name = "I2C Voodoo3/Banshee adapter",
.algo_data = &voo_i2c_bit_data,
};
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index 8f8c81eb0aee..02d746c9c474 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -64,21 +64,6 @@ config SENSORS_PCA9539
This driver is deprecated and will be dropped soon. Use
drivers/gpio/pca953x.c instead.
-config SENSORS_MAX6875
- tristate "Maxim MAX6875 Power supply supervisor"
- depends on EXPERIMENTAL
- help
- If you say yes here you get support for the Maxim MAX6875
- EEPROM-programmable, quad power-supply sequencer/supervisor.
-
- This provides an interface to program the EEPROM and reset the chip.
-
- This driver also supports the Maxim MAX6874 hex power-supply
- sequencer/supervisor if found at a compatible address.
-
- This driver can also be built as a module. If so, the module
- will be called max6875.
-
config SENSORS_TSL2550
tristate "Taos TSL2550 ambient light sensor"
depends on EXPERIMENTAL
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 55a376037183..f4680d16ee34 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -11,7 +11,6 @@
#
obj-$(CONFIG_DS1682) += ds1682.o
-obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
obj-$(CONFIG_PCF8575) += pcf8575.o
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 85e2e919d1cd..864e9e10c36e 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -29,7 +29,6 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/idr.h>
-#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/completion.h>
#include <linux/hardirq.h>
@@ -39,11 +38,12 @@
#include "i2c-core.h"
+/* core_lock protects i2c_adapter_idr and userspace_devices, amongst others */
static DEFINE_MUTEX(core_lock);
static DEFINE_IDR(i2c_adapter_idr);
+static LIST_HEAD(userspace_devices);
-#define is_newstyle_driver(d) ((d)->probe || (d)->remove || (d)->detect)
-
+static int i2c_check_addr(struct i2c_adapter *adapter, int addr);
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
/* ------------------------------------------------------------------------- */
@@ -64,12 +64,6 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(drv);
- /* make legacy i2c drivers bypass driver model probing entirely;
- * such drivers scan each i2c adapter/bus themselves.
- */
- if (!is_newstyle_driver(driver))
- return 0;
-
/* match on an id table if there is one */
if (driver->id_table)
return i2c_match_id(driver->id_table, client) != NULL;
@@ -84,10 +78,6 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct i2c_client *client = to_i2c_client(dev);
- /* by definition, legacy drivers can't hotplug */
- if (dev->driver)
- return 0;
-
if (add_uevent_var(env, "MODALIAS=%s%s",
I2C_MODULE_PREFIX, client->name))
return -ENOMEM;
@@ -176,12 +166,6 @@ static int i2c_device_resume(struct device *dev)
return driver->resume(to_i2c_client(dev));
}
-static void i2c_client_release(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- complete(&client->released);
-}
-
static void i2c_client_dev_release(struct device *dev)
{
kfree(to_i2c_client(dev));
@@ -241,15 +225,17 @@ EXPORT_SYMBOL(i2c_verify_client);
/**
- * i2c_new_device - instantiate an i2c device for use with a new style driver
+ * i2c_new_device - instantiate an i2c device
* @adap: the adapter managing the device
* @info: describes one I2C device; bus_num is ignored
* Context: can sleep
*
- * Create a device to work with a new style i2c driver, where binding is
- * handled through driver model probe()/remove() methods. This call is not
- * appropriate for use by mainboad initialization logic, which usually runs
- * during an arch_initcall() long before any i2c_adapter could exist.
+ * Create an i2c device. Binding is handled through driver model
+ * probe()/remove() methods. A driver may be bound to this device when we
+ * return from this function, or any later moment (e.g. maybe hotplugging will
+ * load the driver module). This call is not appropriate for use by mainboard
+ * initialization logic, which usually runs during an arch_initcall() long
+ * before any i2c_adapter could exist.
*
* This returns the new i2c client, which may be saved for later use with
* i2c_unregister_device(); or NULL to indicate an error.
@@ -277,17 +263,31 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
strlcpy(client->name, info->type, sizeof(client->name));
- /* a new style driver may be bound to this device when we
- * return from this function, or any later moment (e.g. maybe
- * hotplugging will load the driver module). and the device
- * refcount model is the standard driver model one.
- */
- status = i2c_attach_client(client);
- if (status < 0) {
- kfree(client);
- client = NULL;
- }
+ /* Check for address business */
+ status = i2c_check_addr(adap, client->addr);
+ if (status)
+ goto out_err;
+
+ client->dev.parent = &client->adapter->dev;
+ client->dev.bus = &i2c_bus_type;
+ client->dev.release = i2c_client_dev_release;
+
+ dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
+ client->addr);
+ status = device_register(&client->dev);
+ if (status)
+ goto out_err;
+
+ dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",
+ client->name, dev_name(&client->dev));
+
return client;
+
+out_err:
+ dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "
+ "(%d)\n", client->name, client->addr, status);
+ kfree(client);
+ return NULL;
}
EXPORT_SYMBOL_GPL(i2c_new_device);
@@ -299,28 +299,6 @@ EXPORT_SYMBOL_GPL(i2c_new_device);
*/
void i2c_unregister_device(struct i2c_client *client)
{
- struct i2c_adapter *adapter = client->adapter;
- struct i2c_driver *driver = client->driver;
-
- if (driver && !is_newstyle_driver(driver)) {
- dev_err(&client->dev, "can't unregister devices "
- "with legacy drivers\n");
- WARN_ON(1);
- return;
- }
-
- if (adapter->client_unregister) {
- if (adapter->client_unregister(client)) {
- dev_warn(&client->dev,
- "client_unregister [%s] failed\n",
- client->name);
- }
- }
-
- mutex_lock(&adapter->clist_lock);
- list_del(&client->list);
- mutex_unlock(&adapter->clist_lock);
-
device_unregister(&client->dev);
}
EXPORT_SYMBOL_GPL(i2c_unregister_device);
@@ -394,8 +372,128 @@ show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf)
return sprintf(buf, "%s\n", adap->name);
}
+/*
+ * Let users instantiate I2C devices through sysfs. This can be used when
+ * platform initialization code doesn't contain the proper data for
+ * whatever reason. Also useful for drivers that do device detection and
+ * detection fails, either because the device uses an unexpected address,
+ * or this is a compatible device with different ID register values.
+ *
+ * Parameter checking may look overzealous, but we really don't want
+ * the user to provide incorrect parameters.
+ */
+static ssize_t
+i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_adapter *adap = to_i2c_adapter(dev);
+ struct i2c_board_info info;
+ struct i2c_client *client;
+ char *blank, end;
+ int res;
+
+ dev_warn(dev, "The new_device interface is still experimental "
+ "and may change in a near future\n");
+ memset(&info, 0, sizeof(struct i2c_board_info));
+
+ blank = strchr(buf, ' ');
+ if (!blank) {
+ dev_err(dev, "%s: Missing parameters\n", "new_device");
+ return -EINVAL;
+ }
+ if (blank - buf > I2C_NAME_SIZE - 1) {
+ dev_err(dev, "%s: Invalid device name\n", "new_device");
+ return -EINVAL;
+ }
+ memcpy(info.type, buf, blank - buf);
+
+ /* Parse remaining parameters, reject extra parameters */
+ res = sscanf(++blank, "%hi%c", &info.addr, &end);
+ if (res < 1) {
+ dev_err(dev, "%s: Can't parse I2C address\n", "new_device");
+ return -EINVAL;
+ }
+ if (res > 1 && end != '\n') {
+ dev_err(dev, "%s: Extra parameters\n", "new_device");
+ return -EINVAL;
+ }
+
+ if (info.addr < 0x03 || info.addr > 0x77) {
+ dev_err(dev, "%s: Invalid I2C address 0x%hx\n", "new_device",
+ info.addr);
+ return -EINVAL;
+ }
+
+ client = i2c_new_device(adap, &info);
+ if (!client)
+ return -EEXIST;
+
+ /* Keep track of the added device */
+ mutex_lock(&core_lock);
+ list_add_tail(&client->detected, &userspace_devices);
+ mutex_unlock(&core_lock);
+ dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
+ info.type, info.addr);
+
+ return count;
+}
+
+/*
+ * And of course let the users delete the devices they instantiated, if
+ * they got it wrong. This interface can only be used to delete devices
+ * instantiated by i2c_sysfs_new_device above. This guarantees that we
+ * don't delete devices to which some kernel code still has references.
+ *
+ * Parameter checking may look overzealous, but we really don't want
+ * the user to delete the wrong device.
+ */
+static ssize_t
+i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_adapter *adap = to_i2c_adapter(dev);
+ struct i2c_client *client, *next;
+ unsigned short addr;
+ char end;
+ int res;
+
+ /* Parse parameters, reject extra parameters */
+ res = sscanf(buf, "%hi%c", &addr, &end);
+ if (res < 1) {
+ dev_err(dev, "%s: Can't parse I2C address\n", "delete_device");
+ return -EINVAL;
+ }
+ if (res > 1 && end != '\n') {
+ dev_err(dev, "%s: Extra parameters\n", "delete_device");
+ return -EINVAL;
+ }
+
+ /* Make sure the device was added through sysfs */
+ res = -ENOENT;
+ mutex_lock(&core_lock);
+ list_for_each_entry_safe(client, next, &userspace_devices, detected) {
+ if (client->addr == addr && client->adapter == adap) {
+ dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
+ "delete_device", client->name, client->addr);
+
+ list_del(&client->detected);
+ i2c_unregister_device(client);
+ res = count;
+ break;
+ }
+ }
+ mutex_unlock(&core_lock);
+
+ if (res < 0)
+ dev_err(dev, "%s: Can't find device in list\n",
+ "delete_device");
+ return res;
+}
+
static struct device_attribute i2c_adapter_attrs[] = {
__ATTR(name, S_IRUGO, show_adapter_name, NULL),
+ __ATTR(new_device, S_IWUSR, NULL, i2c_sysfs_new_device),
+ __ATTR(delete_device, S_IWUSR, NULL, i2c_sysfs_delete_device),
{ },
};
@@ -446,21 +544,9 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
return -EAGAIN;
mutex_init(&adap->bus_lock);
- mutex_init(&adap->clist_lock);
- INIT_LIST_HEAD(&adap->clients);
mutex_lock(&core_lock);
- /* Add the adapter to the driver core.
- * If the parent pointer is not set up,
- * we add this adapter to the host bus.
- */
- if (adap->dev.parent == NULL) {
- adap->dev.parent = &platform_bus;
- pr_debug("I2C adapter driver [%s] forgot to specify "
- "physical device\n", adap->name);
- }
-
/* Set default timeout to 1 second if not already set */
if (adap->timeout == 0)
adap->timeout = HZ;
@@ -474,7 +560,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
- /* create pre-declared device nodes for new-style drivers */
+ /* create pre-declared device nodes */
if (adap->nr < __i2c_first_dynamic_bus_num)
i2c_scan_static_board_info(adap);
@@ -617,7 +703,6 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data)
*/
int i2c_del_adapter(struct i2c_adapter *adap)
{
- struct i2c_client *client, *_n;
int res = 0;
mutex_lock(&core_lock);
@@ -636,28 +721,6 @@ int i2c_del_adapter(struct i2c_adapter *adap)
if (res)
goto out_unlock;
- /* detach any active clients. This must be done first, because
- * it can fail; in which case we give up. */
- list_for_each_entry_safe_reverse(client, _n, &adap->clients, list) {
- struct i2c_driver *driver;
-
- driver = client->driver;
-
- /* new style, follow standard driver model */
- if (!driver || is_newstyle_driver(driver)) {
- i2c_unregister_device(client);
- continue;
- }
-
- /* legacy drivers create and remove clients themselves */
- if ((res = driver->detach_client(client))) {
- dev_err(&adap->dev, "detach_client failed for client "
- "[%s] at address 0x%02x\n", client->name,
- client->addr);
- goto out_unlock;
- }
- }
-
/* clean up the sysfs representation */
init_completion(&adap->dev_released);
device_unregister(&adap->dev);
@@ -699,11 +762,7 @@ static int __attach_adapter(struct device *dev, void *data)
/*
* An i2c_driver is used with one or more i2c_client (device) nodes to access
- * i2c slave chips, on a bus instance associated with some i2c_adapter. There
- * are two models for binding the driver to its device: "new style" drivers
- * follow the standard Linux driver model and just respond to probe() calls
- * issued if the driver core sees they match(); "legacy" drivers create device
- * nodes themselves.
+ * i2c slave chips, on a bus instance associated with some i2c_adapter.
*/
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
@@ -714,21 +773,11 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
if (unlikely(WARN_ON(!i2c_bus_type.p)))
return -EAGAIN;
- /* new style driver methods can't mix with legacy ones */
- if (is_newstyle_driver(driver)) {
- if (driver->detach_adapter || driver->detach_client) {
- printk(KERN_WARNING
- "i2c-core: driver [%s] is confused\n",
- driver->driver.name);
- return -EINVAL;
- }
- }
-
/* add the driver to the list of i2c drivers in the driver core */
driver->driver.owner = owner;
driver->driver.bus = &i2c_bus_type;
- /* for new style drivers, when registration returns the driver core
+ /* When registration returns, the driver core
* will have called probe() for all matching-but-unbound devices.
*/
res = driver_register(&driver->driver);
@@ -764,32 +813,11 @@ static int __detach_adapter(struct device *dev, void *data)
i2c_unregister_device(client);
}
- if (is_newstyle_driver(driver))
- return 0;
-
- /* Have a look at each adapter, if clients of this driver are still
- * attached. If so, detach them to be able to kill the driver
- * afterwards.
- */
if (driver->detach_adapter) {
if (driver->detach_adapter(adapter))
dev_err(&adapter->dev,
"detach_adapter failed for driver [%s]\n",
driver->driver.name);
- } else {
- struct i2c_client *client, *_n;
-
- list_for_each_entry_safe(client, _n, &adapter->clients, list) {
- if (client->driver != driver)
- continue;
- dev_dbg(&adapter->dev,
- "detaching client [%s] at 0x%02x\n",
- client->name, client->addr);
- if (driver->detach_client(client))
- dev_err(&adapter->dev, "detach_client "
- "failed for client [%s] at 0x%02x\n",
- client->name, client->addr);
- }
}
return 0;
@@ -831,86 +859,6 @@ static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr);
}
-int i2c_attach_client(struct i2c_client *client)
-{
- struct i2c_adapter *adapter = client->adapter;
- int res;
-
- /* Check for address business */
- res = i2c_check_addr(adapter, client->addr);
- if (res)
- return res;
-
- client->dev.parent = &client->adapter->dev;
- client->dev.bus = &i2c_bus_type;
-
- if (client->driver)
- client->dev.driver = &client->driver->driver;
-
- if (client->driver && !is_newstyle_driver(client->driver)) {
- client->dev.release = i2c_client_release;
- dev_set_uevent_suppress(&client->dev, 1);
- } else
- client->dev.release = i2c_client_dev_release;
-
- dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adapter),
- client->addr);
- res = device_register(&client->dev);
- if (res)
- goto out_err;
-
- mutex_lock(&adapter->clist_lock);
- list_add_tail(&client->list, &adapter->clients);
- mutex_unlock(&adapter->clist_lock);
-
- dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",
- client->name, dev_name(&client->dev));
-
- if (adapter->client_register) {
- if (adapter->client_register(client)) {
- dev_dbg(&adapter->dev, "client_register "
- "failed for client [%s] at 0x%02x\n",
- client->name, client->addr);
- }
- }
-
- return 0;
-
-out_err:
- dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x "
- "(%d)\n", client->name, client->addr, res);
- return res;
-}
-EXPORT_SYMBOL(i2c_attach_client);
-
-int i2c_detach_client(struct i2c_client *client)
-{
- struct i2c_adapter *adapter = client->adapter;
- int res = 0;
-
- if (adapter->client_unregister) {
- res = adapter->client_unregister(client);
- if (res) {
- dev_err(&client->dev,
- "client_unregister [%s] failed, "
- "client not detached\n", client->name);
- goto out;
- }
- }
-
- mutex_lock(&adapter->clist_lock);
- list_del(&client->list);
- mutex_unlock(&adapter->clist_lock);
-
- init_completion(&client->released);
- device_unregister(&client->dev);
- wait_for_completion(&client->released);
-
- out:
- return res;
-}
-EXPORT_SYMBOL(i2c_detach_client);
-
/**
* i2c_use_client - increments the reference count of the i2c client structure
* @client: the client being referenced
@@ -1022,7 +970,8 @@ module_exit(i2c_exit);
*/
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
- int ret;
+ unsigned long orig_jiffies;
+ int ret, try;
/* REVISIT the fault reporting model here is weak:
*
@@ -1060,7 +1009,15 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
mutex_lock_nested(&adap->bus_lock, adap->level);
}
- ret = adap->algo->master_xfer(adap,msgs,num);
+ /* Retry automatically on arbitration loss */
+ orig_jiffies = jiffies;
+ for (ret = 0, try = 0; try <= adap->retries; try++) {
+ ret = adap->algo->master_xfer(adap, msgs, num);
+ if (ret != -EAGAIN)
+ break;
+ if (time_after(jiffies, orig_jiffies + adap->timeout))
+ break;
+ }
mutex_unlock(&adap->bus_lock);
return ret;
@@ -1131,144 +1088,7 @@ EXPORT_SYMBOL(i2c_master_recv);
* Will not work for 10-bit addresses!
* ----------------------------------------------------
*/
-static int i2c_probe_address(struct i2c_adapter *adapter, int addr, int kind,
- int (*found_proc) (struct i2c_adapter *, int, int))
-{
- int err;
-
- /* Make sure the address is valid */
- if (addr < 0x03 || addr > 0x77) {
- dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",
- addr);
- return -EINVAL;
- }
- /* Skip if already in use */
- if (i2c_check_addr(adapter, addr))
- return 0;
-
- /* Make sure there is something at this address, unless forced */
- if (kind < 0) {
- if (i2c_smbus_xfer(adapter, addr, 0, 0, 0,
- I2C_SMBUS_QUICK, NULL) < 0)
- return 0;
-
- /* prevent 24RF08 corruption */
- if ((addr & ~0x0f) == 0x50)
- i2c_smbus_xfer(adapter, addr, 0, 0, 0,
- I2C_SMBUS_QUICK, NULL);
- }
-
- /* Finally call the custom detection function */
- err = found_proc(adapter, addr, kind);
- /* -ENODEV can be returned if there is a chip at the given address
- but it isn't supported by this chip driver. We catch it here as
- this isn't an error. */
- if (err == -ENODEV)
- err = 0;
-
- if (err)
- dev_warn(&adapter->dev, "Client creation failed at 0x%x (%d)\n",
- addr, err);
- return err;
-}
-
-int i2c_probe(struct i2c_adapter *adapter,
- const struct i2c_client_address_data *address_data,
- int (*found_proc) (struct i2c_adapter *, int, int))
-{
- int i, err;
- int adap_id = i2c_adapter_id(adapter);
-
- /* Force entries are done first, and are not affected by ignore
- entries */
- if (address_data->forces) {
- const unsigned short * const *forces = address_data->forces;
- int kind;
-
- for (kind = 0; forces[kind]; kind++) {
- for (i = 0; forces[kind][i] != I2C_CLIENT_END;
- i += 2) {
- if (forces[kind][i] == adap_id
- || forces[kind][i] == ANY_I2C_BUS) {
- dev_dbg(&adapter->dev, "found force "
- "parameter for adapter %d, "
- "addr 0x%02x, kind %d\n",
- adap_id, forces[kind][i + 1],
- kind);
- err = i2c_probe_address(adapter,
- forces[kind][i + 1],
- kind, found_proc);
- if (err)
- return err;
- }
- }
- }
- }
-
- /* Stop here if we can't use SMBUS_QUICK */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {
- if (address_data->probe[0] == I2C_CLIENT_END
- && address_data->normal_i2c[0] == I2C_CLIENT_END)
- return 0;
-
- dev_dbg(&adapter->dev, "SMBus Quick command not supported, "
- "can't probe for chips\n");
- return -EOPNOTSUPP;
- }
-
- /* Probe entries are done second, and are not affected by ignore
- entries either */
- for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) {
- if (address_data->probe[i] == adap_id
- || address_data->probe[i] == ANY_I2C_BUS) {
- dev_dbg(&adapter->dev, "found probe parameter for "
- "adapter %d, addr 0x%02x\n", adap_id,
- address_data->probe[i + 1]);
- err = i2c_probe_address(adapter,
- address_data->probe[i + 1],
- -1, found_proc);
- if (err)
- return err;
- }
- }
-
- /* Normal entries are done last, unless shadowed by an ignore entry */
- for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) {
- int j, ignore;
-
- ignore = 0;
- for (j = 0; address_data->ignore[j] != I2C_CLIENT_END;
- j += 2) {
- if ((address_data->ignore[j] == adap_id ||
- address_data->ignore[j] == ANY_I2C_BUS)
- && address_data->ignore[j + 1]
- == address_data->normal_i2c[i]) {
- dev_dbg(&adapter->dev, "found ignore "
- "parameter for adapter %d, "
- "addr 0x%02x\n", adap_id,
- address_data->ignore[j + 1]);
- ignore = 1;
- break;
- }
- }
- if (ignore)
- continue;
-
- dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
- "addr 0x%02x\n", adap_id,
- address_data->normal_i2c[i]);
- err = i2c_probe_address(adapter, address_data->normal_i2c[i],
- -1, found_proc);
- if (err)
- return err;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(i2c_probe);
-
-/* Separate detection function for new-style drivers */
static int i2c_detect_address(struct i2c_client *temp_client, int kind,
struct i2c_driver *driver)
{
@@ -1509,7 +1329,7 @@ struct i2c_adapter* i2c_get_adapter(int id)
struct i2c_adapter *adapter;
mutex_lock(&core_lock);
- adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
+ adapter = idr_find(&i2c_adapter_idr, id);
if (adapter && !try_module_get(adapter->owner))
adapter = NULL;
@@ -1995,14 +1815,27 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
char read_write, u8 command, int protocol,
union i2c_smbus_data *data)
{
+ unsigned long orig_jiffies;
+ int try;
s32 res;
flags &= I2C_M_TEN | I2C_CLIENT_PEC;
if (adapter->algo->smbus_xfer) {
mutex_lock(&adapter->bus_lock);
- res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write,
- command, protocol, data);
+
+ /* Retry automatically on arbitration loss */
+ orig_jiffies = jiffies;
+ for (res = 0, try = 0; try <= adapter->retries; try++) {
+ res = adapter->algo->smbus_xfer(adapter, addr, flags,
+ read_write, command,
+ protocol, data);
+ if (res != -EAGAIN)
+ break;
+ if (time_after(jiffies,
+ orig_jiffies + adapter->timeout))
+ break;
+ }
mutex_unlock(&adapter->bus_lock);
} else
res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index 537da1cde16d..e59b6dee9ae2 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -402,27 +402,23 @@ static u8 ali_cable_detect(ide_hwif_t *hwif)
return cbl;
}
-#if !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC)
+#ifndef CONFIG_SPARC64
/**
* init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff
* @hwif: interface to configure
*
* Obtain the IRQ tables for an ALi based IDE solution on the PC
* class platforms. This part of the code isn't applicable to the
- * Sparc and PowerPC systems.
+ * Sparc systems.
*/
static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 ideic, inmir;
s8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6,
1, 11, 0, 12, 0, 14, 0, 15 };
int irq = -1;
- if (dev->device == PCI_DEVICE_ID_AL_M5229)
- hwif->irq = hwif->channel ? 15 : 14;
-
if (isa_dev) {
/*
* read IDE interface control
@@ -455,7 +451,7 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
}
#else
#define init_hwif_ali15x3 NULL
-#endif /* !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC) */
+#endif /* CONFIG_SPARC64 */
/**
* init_dma_ali15x3 - set up DMA on ALi15x3
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index d01cffe497c4..ffa1bb877949 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -80,34 +80,6 @@ void ide_init_pc(struct ide_atapi_pc *pc)
EXPORT_SYMBOL_GPL(ide_init_pc);
/*
- * Generate a new packet command request in front of the request queue, before
- * the current request, so that it will be processed immediately, on the next
- * pass through the driver.
- */
-static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
- struct ide_atapi_pc *pc, struct request *rq)
-{
- blk_rq_init(NULL, rq);
- rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->cmd_flags |= REQ_PREEMPT;
- rq->buffer = (char *)pc;
- rq->rq_disk = disk;
-
- if (pc->req_xfer) {
- rq->data = pc->buf;
- rq->data_len = pc->req_xfer;
- }
-
- memcpy(rq->cmd, pc->c, 12);
- if (drive->media == ide_tape)
- rq->cmd[13] = REQ_IDETAPE_PC1;
-
- drive->hwif->rq = NULL;
-
- elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
-}
-
-/*
* Add a special packet command request to the tail of the request queue,
* and wait for it to be serviced.
*/
@@ -119,19 +91,21 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->buffer = (char *)pc;
+ rq->special = (char *)pc;
if (pc->req_xfer) {
- rq->data = pc->buf;
- rq->data_len = pc->req_xfer;
+ error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer,
+ GFP_NOIO);
+ if (error)
+ goto put_req;
}
memcpy(rq->cmd, pc->c, 12);
if (drive->media == ide_tape)
rq->cmd[13] = REQ_IDETAPE_PC1;
error = blk_execute_rq(drive->queue, disk, rq, 0);
+put_req:
blk_put_request(rq);
-
return error;
}
EXPORT_SYMBOL_GPL(ide_queue_pc_tail);
@@ -191,20 +165,113 @@ void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc)
}
EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd);
+void ide_prep_sense(ide_drive_t *drive, struct request *rq)
+{
+ struct request_sense *sense = &drive->sense_data;
+ struct request *sense_rq = &drive->sense_rq;
+ unsigned int cmd_len, sense_len;
+ int err;
+
+ debug_log("%s: enter\n", __func__);
+
+ switch (drive->media) {
+ case ide_floppy:
+ cmd_len = 255;
+ sense_len = 18;
+ break;
+ case ide_tape:
+ cmd_len = 20;
+ sense_len = 20;
+ break;
+ default:
+ cmd_len = 18;
+ sense_len = 18;
+ }
+
+ BUG_ON(sense_len > sizeof(*sense));
+
+ if (blk_sense_request(rq) || drive->sense_rq_armed)
+ return;
+
+ memset(sense, 0, sizeof(*sense));
+
+ blk_rq_init(rq->q, sense_rq);
+
+ err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len,
+ GFP_NOIO);
+ if (unlikely(err)) {
+ if (printk_ratelimit())
+ printk(KERN_WARNING "%s: failed to map sense buffer\n",
+ drive->name);
+ return;
+ }
+
+ sense_rq->rq_disk = rq->rq_disk;
+ sense_rq->cmd[0] = GPCMD_REQUEST_SENSE;
+ sense_rq->cmd[4] = cmd_len;
+ sense_rq->cmd_type = REQ_TYPE_SENSE;
+ sense_rq->cmd_flags |= REQ_PREEMPT;
+
+ if (drive->media == ide_tape)
+ sense_rq->cmd[13] = REQ_IDETAPE_PC1;
+
+ drive->sense_rq_armed = true;
+}
+EXPORT_SYMBOL_GPL(ide_prep_sense);
+
+int ide_queue_sense_rq(ide_drive_t *drive, void *special)
+{
+ /* deferred failure from ide_prep_sense() */
+ if (!drive->sense_rq_armed) {
+ printk(KERN_WARNING "%s: failed queue sense request\n",
+ drive->name);
+ return -ENOMEM;
+ }
+
+ drive->sense_rq.special = special;
+ drive->sense_rq_armed = false;
+
+ drive->hwif->rq = NULL;
+
+ elv_add_request(drive->queue, &drive->sense_rq,
+ ELEVATOR_INSERT_FRONT, 0);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ide_queue_sense_rq);
+
/*
* Called when an error was detected during the last packet command.
- * We queue a request sense packet command in the head of the request list.
+ * We queue a request sense packet command at the head of the request
+ * queue.
*/
-void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk)
+void ide_retry_pc(ide_drive_t *drive)
{
- struct request *rq = &drive->request_sense_rq;
+ struct request *failed_rq = drive->hwif->rq;
+ struct request *sense_rq = &drive->sense_rq;
struct ide_atapi_pc *pc = &drive->request_sense_pc;
(void)ide_read_error(drive);
- ide_create_request_sense_cmd(drive, pc);
+
+ /* init pc from sense_rq */
+ ide_init_pc(pc);
+ memcpy(pc->c, sense_rq->cmd, 12);
+ pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */
+ pc->req_xfer = blk_rq_bytes(sense_rq);
+
if (drive->media == ide_tape)
set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
- ide_queue_pc_head(drive, disk, pc, rq);
+
+ /*
+ * Push back the failed request and put request sense on top
+ * of it. The failed command will be retried after sense data
+ * is acquired.
+ */
+ blk_requeue_request(failed_rq->q, failed_rq);
+ drive->hwif->rq = NULL;
+ if (ide_queue_sense_rq(drive, pc)) {
+ blk_start_request(failed_rq);
+ ide_complete_rq(drive, -EIO, blk_rq_bytes(failed_rq));
+ }
}
EXPORT_SYMBOL_GPL(ide_retry_pc);
@@ -246,7 +313,7 @@ int ide_cd_get_xferlen(struct request *rq)
return 32768;
else if (blk_sense_request(rq) || blk_pc_request(rq) ||
rq->cmd_type == REQ_TYPE_ATA_PC)
- return rq->data_len;
+ return blk_rq_bytes(rq);
else
return 0;
}
@@ -276,7 +343,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- xfer_func_t *xferfunc;
unsigned int timeout, done;
u16 bcount;
u8 stat, ireason, dsc = 0;
@@ -303,18 +369,14 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
drive->name, rq_data_dir(pc->rq)
? "write" : "read");
pc->flags |= PC_FLAG_DMA_ERROR;
- } else {
+ } else
pc->xferred = pc->req_xfer;
- if (drive->pc_update_buffers)
- drive->pc_update_buffers(drive, pc);
- }
debug_log("%s: DMA finished\n", drive->name);
}
/* No more interrupts */
if ((stat & ATA_DRQ) == 0) {
int uptodate, error;
- unsigned int done;
debug_log("Packet command completed, %d bytes transferred\n",
pc->xferred);
@@ -343,7 +405,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
debug_log("[cmd %x]: check condition\n", rq->cmd[0]);
/* Retry operation */
- ide_retry_pc(drive, rq->rq_disk);
+ ide_retry_pc(drive);
/* queued, but not started */
return ide_stopped;
@@ -361,7 +423,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if (blk_special_request(rq)) {
rq->errors = 0;
- done = blk_rq_bytes(rq);
error = 0;
} else {
@@ -370,15 +431,10 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
rq->errors = -EIO;
}
- if (drive->media == ide_tape)
- done = ide_rq_bytes(rq); /* FIXME */
- else
- done = blk_rq_bytes(rq);
-
error = uptodate ? 0 : -EIO;
}
- ide_complete_rq(drive, error, done);
+ ide_complete_rq(drive, error, blk_rq_bytes(rq));
return ide_stopped;
}
@@ -407,21 +463,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}
- xferfunc = write ? tp_ops->output_data : tp_ops->input_data;
-
- if (drive->media == ide_floppy && pc->buf == NULL) {
- done = min_t(unsigned int, bcount, cmd->nleft);
- ide_pio_bytes(drive, cmd, write, done);
- } else if (drive->media == ide_tape && pc->bh) {
- done = drive->pc_io_buffers(drive, pc, bcount, write);
- } else {
- done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred);
- xferfunc(drive, NULL, pc->cur_pos, done);
- }
+ done = min_t(unsigned int, bcount, cmd->nleft);
+ ide_pio_bytes(drive, cmd, write, done);
- /* Update the current position */
+ /* Update transferred byte count */
pc->xferred += done;
- pc->cur_pos += done;
bcount -= done;
@@ -599,7 +645,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
/* We haven't transferred any data yet */
pc->xferred = 0;
- pc->cur_pos = pc->buf;
valid_tf = IDE_VALID_DEVICE;
bcount = ((drive->media == ide_tape) ?
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 925eb9e245d1..1f889115c923 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -206,54 +206,25 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
ide_cd_log_error(drive->name, failed_command, sense);
}
-static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
- struct request *failed_command)
-{
- struct cdrom_info *info = drive->driver_data;
- struct request *rq = &drive->request_sense_rq;
-
- ide_debug_log(IDE_DBG_SENSE, "enter");
-
- if (sense == NULL)
- sense = &info->sense_data;
-
- /* stuff the sense request in front of our current request */
- blk_rq_init(NULL, rq);
- rq->cmd_type = REQ_TYPE_ATA_PC;
- rq->rq_disk = info->disk;
-
- rq->data = sense;
- rq->cmd[0] = GPCMD_REQUEST_SENSE;
- rq->cmd[4] = 18;
- rq->data_len = 18;
-
- rq->cmd_type = REQ_TYPE_SENSE;
- rq->cmd_flags |= REQ_PREEMPT;
-
- /* NOTE! Save the failed command in "rq->buffer" */
- rq->buffer = (void *) failed_command;
-
- if (failed_command)
- ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x",
- failed_command->cmd[0]);
-
- drive->hwif->rq = NULL;
-
- elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
-}
-
static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
{
/*
- * For REQ_TYPE_SENSE, "rq->buffer" points to the original
- * failed request
+ * For REQ_TYPE_SENSE, "rq->special" points to the original
+ * failed request. Also, the sense data should be read
+ * directly from rq which might be different from the original
+ * sense buffer if it got copied during mapping.
*/
- struct request *failed = (struct request *)rq->buffer;
- struct cdrom_info *info = drive->driver_data;
- void *sense = &info->sense_data;
+ struct request *failed = (struct request *)rq->special;
+ void *sense = bio_data(rq->bio);
if (failed) {
if (failed->sense) {
+ /*
+ * Sense is always read into drive->sense_data.
+ * Copy back if the failed request has its
+ * sense pointer set.
+ */
+ memcpy(failed->sense, sense, 18);
sense = failed->sense;
failed->sense_len = rq->sense_len;
}
@@ -428,22 +399,13 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
/* if we got a CHECK_CONDITION status, queue a request sense command */
if (stat & ATA_ERR)
- cdrom_queue_request_sense(drive, NULL, NULL);
+ return ide_queue_sense_rq(drive, NULL) ? 2 : 1;
return 1;
end_request:
if (stat & ATA_ERR) {
- struct request_queue *q = drive->queue;
- unsigned long flags;
-
- spin_lock_irqsave(q->queue_lock, flags);
- blkdev_dequeue_request(rq);
- spin_unlock_irqrestore(q->queue_lock, flags);
-
hwif->rq = NULL;
-
- cdrom_queue_request_sense(drive, rq->sense, rq);
- return 1;
+ return ide_queue_sense_rq(drive, rq) ? 2 : 1;
} else
return 2;
}
@@ -503,14 +465,8 @@ static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
* and some drives don't send them. Sigh.
*/
if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
- cmd->nleft > 0 && cmd->nleft <= 5) {
- unsigned int ofs = cmd->nbytes - cmd->nleft;
-
- while (cmd->nleft > 0) {
- *((u8 *)rq->data + ofs++) = 0;
- cmd->nleft--;
- }
- }
+ cmd->nleft > 0 && cmd->nleft <= 5)
+ cmd->nleft = 0;
}
int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
@@ -543,14 +499,18 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
rq->cmd_flags |= cmd_flags;
rq->timeout = timeout;
if (buffer) {
- rq->data = buffer;
- rq->data_len = *bufflen;
+ error = blk_rq_map_kern(drive->queue, rq, buffer,
+ *bufflen, GFP_NOIO);
+ if (error) {
+ blk_put_request(rq);
+ return error;
+ }
}
error = blk_execute_rq(drive->queue, info->disk, rq, 0);
if (buffer)
- *bufflen = rq->data_len;
+ *bufflen = rq->resid_len;
flags = rq->cmd_flags;
blk_put_request(rq);
@@ -608,7 +568,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
struct request *rq = hwif->rq;
ide_expiry_t *expiry = NULL;
int dma_error = 0, dma, thislen, uptodate = 0;
- int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0, nsectors;
+ int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0;
int sense = blk_sense_request(rq);
unsigned int timeout;
u16 len;
@@ -738,13 +698,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
out_end:
if (blk_pc_request(rq) && rc == 0) {
- unsigned int dlen = rq->data_len;
-
- rq->data_len = 0;
-
- if (blk_end_request(rq, 0, dlen))
- BUG();
-
+ blk_end_request_all(rq, 0);
hwif->rq = NULL;
} else {
if (sense && uptodate)
@@ -762,21 +716,14 @@ out_end:
ide_cd_error_cmd(drive, cmd);
/* make sure it's fully ended */
- if (blk_pc_request(rq))
- nsectors = (rq->data_len + 511) >> 9;
- else
- nsectors = rq->hard_nr_sectors;
-
- if (nsectors == 0)
- nsectors = 1;
-
if (blk_fs_request(rq) == 0) {
- rq->data_len -= (cmd->nbytes - cmd->nleft);
+ rq->resid_len = blk_rq_bytes(rq) -
+ (cmd->nbytes - cmd->nleft);
if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
- rq->data_len += cmd->last_xfer_len;
+ rq->resid_len += cmd->last_xfer_len;
}
- ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+ ide_complete_rq(drive, uptodate ? 0 : -EIO, blk_rq_bytes(rq));
if (sense && rc == 2)
ide_error(drive, "request sense failure", stat);
@@ -809,8 +756,8 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
}
/* fs requests *must* be hardware frame aligned */
- if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
- (rq->sector & (sectors_per_frame - 1)))
+ if ((blk_rq_sectors(rq) & (sectors_per_frame - 1)) ||
+ (blk_rq_pos(rq) & (sectors_per_frame - 1)))
return ide_stopped;
/* use DMA, if possible */
@@ -838,15 +785,10 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
drive->dma = 0;
/* sg request */
- if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) {
+ if (rq->bio) {
struct request_queue *q = drive->queue;
+ char *buf = bio_data(rq->bio);
unsigned int alignment;
- char *buf;
-
- if (rq->bio)
- buf = bio_data(rq->bio);
- else
- buf = rq->data;
drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
@@ -858,7 +800,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
*/
alignment = queue_dma_alignment(q) | q->dma_pad_mask;
if ((unsigned long)buf & alignment
- || rq->data_len & q->dma_pad_mask
+ || blk_rq_bytes(rq) & q->dma_pad_mask
|| object_is_on_stack(buf))
drive->dma = 0;
}
@@ -896,6 +838,9 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
goto out_end;
}
+ /* prepare sense request for this command */
+ ide_prep_sense(drive, rq);
+
memset(&cmd, 0, sizeof(cmd));
if (rq_data_dir(rq))
@@ -903,15 +848,14 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
cmd.rq = rq;
- if (blk_fs_request(rq) || rq->data_len) {
- ide_init_sg_cmd(&cmd, blk_fs_request(rq) ? (rq->nr_sectors << 9)
- : rq->data_len);
+ if (blk_fs_request(rq) || blk_rq_bytes(rq)) {
+ ide_init_sg_cmd(&cmd, blk_rq_bytes(rq));
ide_map_sg(drive, &cmd);
}
return ide_issue_pc(drive, &cmd);
out_end:
- nsectors = rq->hard_nr_sectors;
+ nsectors = blk_rq_sectors(rq);
if (nsectors == 0)
nsectors = 1;
@@ -1395,8 +1339,8 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
{
int hard_sect = queue_hardsect_size(q);
- long block = (long)rq->hard_sector / (hard_sect >> 9);
- unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
+ long block = (long)blk_rq_pos(rq) / (hard_sect >> 9);
+ unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9);
memset(rq->cmd, 0, BLK_MAX_CDB);
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 1d97101099ce..93a3cf1b0f3f 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -87,10 +87,6 @@ struct cdrom_info {
struct atapi_toc *toc;
- /* The result of the last successful request sense command
- on this device. */
- struct request_sense sense_data;
-
u8 max_speed; /* Max speed of the drive. */
u8 current_speed; /* Current speed of the drive. */
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index a9fbe2c31210..ad18e14043c5 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -82,7 +82,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
sector_t block)
{
ide_hwif_t *hwif = drive->hwif;
- u16 nsectors = (u16)rq->nr_sectors;
+ u16 nsectors = (u16)blk_rq_sectors(rq);
u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
struct ide_cmd cmd;
@@ -90,7 +90,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
ide_startstop_t rc;
if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
- if (block + rq->nr_sectors > 1ULL << 28)
+ if (block + blk_rq_sectors(rq) > 1ULL << 28)
dma = 0;
else
lba48 = 0;
@@ -195,9 +195,9 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
ledtrig_ide_activity();
- pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
+ pr_debug("%s: %sing: block=%llu, sectors=%u, buffer=0x%08lx\n",
drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
- (unsigned long long)block, rq->nr_sectors,
+ (unsigned long long)block, blk_rq_sectors(rq),
(unsigned long)rq->buffer);
if (hwif->rw_disk)
@@ -411,7 +411,6 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
cmd->protocol = ATA_PROT_NODATA;
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
- rq->cmd_flags |= REQ_SOFTBARRIER;
rq->special = cmd;
}
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index a0b8cab1d9a6..001f68f0bb28 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -103,7 +103,7 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive)
ide_finish_cmd(drive, cmd, stat);
else
ide_complete_rq(drive, 0,
- cmd->rq->nr_sectors << 9);
+ blk_rq_sectors(cmd->rq) << 9);
return ide_stopped;
}
printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n",
@@ -510,23 +510,11 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
/*
* un-busy drive etc and make sure request is sane
*/
-
rq = hwif->rq;
- if (!rq)
- goto out;
-
- hwif->rq = NULL;
-
- rq->errors = 0;
-
- if (!rq->bio)
- goto out;
-
- rq->sector = rq->bio->bi_sector;
- rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
- rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->buffer = bio_data(rq->bio);
-out:
+ if (rq) {
+ hwif->rq = NULL;
+ rq->errors = 0;
+ }
return ret;
}
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 2b4868d95f8b..650981758f15 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -134,13 +134,17 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive,
drive->pc = pc;
if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) {
+ unsigned int done = blk_rq_bytes(drive->hwif->rq);
+
if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
ide_floppy_report_error(floppy, pc);
+
/* Giving up */
pc->error = IDE_DRV_ERROR_GENERAL;
drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
+ ide_complete_rq(drive, -EIO, done);
return ide_stopped;
}
@@ -190,7 +194,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
{
struct ide_disk_obj *floppy = drive->driver_data;
int block = sector / floppy->bs_factor;
- int blocks = rq->nr_sectors / floppy->bs_factor;
+ int blocks = blk_rq_sectors(rq) / floppy->bs_factor;
int cmd = rq_data_dir(rq);
ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks);
@@ -216,16 +220,14 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
ide_init_pc(pc);
memcpy(pc->c, rq->cmd, sizeof(pc->c));
pc->rq = rq;
- if (rq->data_len && rq_data_dir(rq) == WRITE)
- pc->flags |= PC_FLAG_WRITING;
- pc->buf = rq->data;
- if (rq->bio)
+ if (blk_rq_bytes(rq)) {
pc->flags |= PC_FLAG_DMA_OK;
- /*
- * possibly problematic, doesn't look like ide-floppy correctly
- * handled scattered requests if dma fails...
- */
- pc->req_xfer = pc->buf_size = rq->data_len;
+ if (rq_data_dir(rq) == WRITE)
+ pc->flags |= PC_FLAG_WRITING;
+ }
+ /* pio will be performed by ide_pio_bytes() which handles sg fine */
+ pc->buf = NULL;
+ pc->req_xfer = pc->buf_size = blk_rq_bytes(rq);
}
static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
@@ -257,16 +259,16 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
goto out_end;
}
if (blk_fs_request(rq)) {
- if (((long)rq->sector % floppy->bs_factor) ||
- (rq->nr_sectors % floppy->bs_factor)) {
+ if (((long)blk_rq_pos(rq) % floppy->bs_factor) ||
+ (blk_rq_sectors(rq) % floppy->bs_factor)) {
printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
drive->name);
goto out_end;
}
pc = &floppy->queued_pc;
idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
- } else if (blk_special_request(rq)) {
- pc = (struct ide_atapi_pc *) rq->buffer;
+ } else if (blk_special_request(rq) || blk_sense_request(rq)) {
+ pc = (struct ide_atapi_pc *)rq->special;
} else if (blk_pc_request(rq)) {
pc = &floppy->queued_pc;
idefloppy_blockpc_cmd(floppy, pc, rq);
@@ -275,6 +277,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
goto out_end;
}
+ ide_prep_sense(drive, rq);
+
memset(&cmd, 0, sizeof(cmd));
if (rq_data_dir(rq))
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 35dc38d3b2c5..e4e3a0e3201e 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -116,9 +116,9 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
unsigned int ide_rq_bytes(struct request *rq)
{
if (blk_pc_request(rq))
- return rq->data_len;
+ return blk_rq_bytes(rq);
else
- return rq->hard_cur_sectors << 9;
+ return blk_rq_cur_sectors(rq) << 9;
}
EXPORT_SYMBOL_GPL(ide_rq_bytes);
@@ -133,7 +133,7 @@ int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes)
* and complete the whole request right now
*/
if (blk_noretry_request(rq) && error <= 0)
- nr_bytes = rq->hard_nr_sectors << 9;
+ nr_bytes = blk_rq_sectors(rq) << 9;
rc = ide_end_rq(drive, rq, error, nr_bytes);
if (rc == 0)
@@ -248,14 +248,7 @@ void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
struct scatterlist *sg = hwif->sg_table;
struct request *rq = cmd->rq;
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
- cmd->sg_nents = 1;
- } else if (!rq->bio) {
- sg_init_one(sg, rq->data, rq->data_len);
- cmd->sg_nents = 1;
- } else
- cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
+ cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
}
EXPORT_SYMBOL_GPL(ide_map_sg);
@@ -286,7 +279,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
if (cmd) {
if (cmd->protocol == ATA_PROT_PIO) {
- ide_init_sg_cmd(cmd, rq->nr_sectors << 9);
+ ide_init_sg_cmd(cmd, blk_rq_sectors(rq) << 9);
ide_map_sg(drive, cmd);
}
@@ -371,7 +364,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
return execute_drive_cmd(drive, rq);
else if (blk_pm_request(rq)) {
- struct request_pm_state *pm = rq->data;
+ struct request_pm_state *pm = rq->special;
#ifdef DEBUG_PM
printk("%s: start_power_step(step: %d)\n",
drive->name, pm->pm_step);
@@ -394,7 +387,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
drv = *(struct ide_driver **)rq->rq_disk->private_data;
- return drv->do_request(drive, rq, rq->sector);
+ return drv->do_request(drive, rq, blk_rq_pos(rq));
}
return do_special(drive);
kill_rq:
@@ -484,6 +477,9 @@ void do_ide_request(struct request_queue *q)
spin_unlock_irq(q->queue_lock);
+ /* HLD do_request() callback might sleep, make sure it's okay */
+ might_sleep();
+
if (ide_lock_host(host, hwif))
goto plug_device_2;
@@ -491,10 +487,10 @@ void do_ide_request(struct request_queue *q)
if (!ide_lock_port(hwif)) {
ide_hwif_t *prev_port;
+
+ WARN_ON_ONCE(hwif->rq);
repeat:
prev_port = hwif->host->cur_port;
- hwif->rq = NULL;
-
if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
time_after(drive->sleep, jiffies)) {
ide_unlock_port(hwif);
@@ -523,7 +519,9 @@ repeat:
* we know that the queue isn't empty, but this can happen
* if the q->prep_rq_fn() decides to kill a request
*/
- rq = elv_next_request(drive->queue);
+ if (!rq)
+ rq = blk_fetch_request(drive->queue);
+
spin_unlock_irq(q->queue_lock);
spin_lock_irq(&hwif->lock);
@@ -535,7 +533,7 @@ repeat:
/*
* Sanity: don't accept a request that isn't a PM request
* if we are currently power managed. This is very important as
- * blk_stop_queue() doesn't prevent the elv_next_request()
+ * blk_stop_queue() doesn't prevent the blk_fetch_request()
* above to return us whatever is in the queue. Since we call
* ide_do_request() ourselves, we end up taking requests while
* the queue is blocked...
@@ -559,8 +557,11 @@ repeat:
startstop = start_request(drive, rq);
spin_lock_irq(&hwif->lock);
- if (startstop == ide_stopped)
+ if (startstop == ide_stopped) {
+ rq = hwif->rq;
+ hwif->rq = NULL;
goto repeat;
+ }
} else
goto plug_device;
out:
@@ -576,18 +577,24 @@ plug_device:
plug_device_2:
spin_lock_irq(q->queue_lock);
+ if (rq)
+ blk_requeue_request(q, rq);
if (!elv_queue_empty(q))
blk_plug_device(q);
}
-static void ide_plug_device(ide_drive_t *drive)
+static void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
{
struct request_queue *q = drive->queue;
unsigned long flags;
spin_lock_irqsave(q->queue_lock, flags);
+
+ if (rq)
+ blk_requeue_request(q, rq);
if (!elv_queue_empty(q))
blk_plug_device(q);
+
spin_unlock_irqrestore(q->queue_lock, flags);
}
@@ -636,6 +643,7 @@ void ide_timer_expiry (unsigned long data)
unsigned long flags;
int wait = -1;
int plug_device = 0;
+ struct request *uninitialized_var(rq_in_flight);
spin_lock_irqsave(&hwif->lock, flags);
@@ -697,6 +705,8 @@ void ide_timer_expiry (unsigned long data)
spin_lock_irq(&hwif->lock);
enable_irq(hwif->irq);
if (startstop == ide_stopped) {
+ rq_in_flight = hwif->rq;
+ hwif->rq = NULL;
ide_unlock_port(hwif);
plug_device = 1;
}
@@ -705,7 +715,7 @@ void ide_timer_expiry (unsigned long data)
if (plug_device) {
ide_unlock_host(hwif->host);
- ide_plug_device(drive);
+ ide_requeue_and_plug(drive, rq_in_flight);
}
}
@@ -791,6 +801,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
ide_startstop_t startstop;
irqreturn_t irq_ret = IRQ_NONE;
int plug_device = 0;
+ struct request *uninitialized_var(rq_in_flight);
if (host->host_flags & IDE_HFLAG_SERIALIZE) {
if (hwif != host->cur_port)
@@ -870,6 +881,8 @@ irqreturn_t ide_intr (int irq, void *dev_id)
*/
if (startstop == ide_stopped) {
BUG_ON(hwif->handler);
+ rq_in_flight = hwif->rq;
+ hwif->rq = NULL;
ide_unlock_port(hwif);
plug_device = 1;
}
@@ -879,7 +892,7 @@ out:
out_early:
if (plug_device) {
ide_unlock_host(hwif->host);
- ide_plug_device(drive);
+ ide_requeue_and_plug(drive, rq_in_flight);
}
return irq_ret;
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index c1c25ebbaa1f..5991b23793f2 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -231,7 +231,6 @@ static int generic_drive_reset(ide_drive_t *drive)
rq->cmd_type = REQ_TYPE_SPECIAL;
rq->cmd_len = 1;
rq->cmd[0] = REQ_DRIVE_RESET;
- rq->cmd_flags |= REQ_SOFTBARRIER;
if (blk_execute_rq(drive->queue, NULL, rq, 1))
ret = rq->errors;
blk_put_request(rq);
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 56ff8c46c7d1..05b7fbc7ead5 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -114,7 +114,7 @@ static void ide_dump_ata_error(ide_drive_t *drive, u8 err)
if (rq)
printk(KERN_CONT ", sector=%llu",
- (unsigned long long)rq->sector);
+ (unsigned long long)blk_rq_pos(rq));
}
printk(KERN_CONT "\n");
}
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index 310d03f2b5b7..a914023d6d03 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -24,11 +24,8 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
start_queue = 1;
spin_unlock_irq(&hwif->lock);
- if (start_queue) {
- spin_lock_irq(q->queue_lock);
- blk_start_queueing(q);
- spin_unlock_irq(q->queue_lock);
- }
+ if (start_queue)
+ blk_run_queue(q);
return;
}
spin_unlock_irq(&hwif->lock);
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index 0d8a151c0a01..ba1488bd8430 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -7,7 +7,6 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
- struct ide_cmd cmd;
int ret;
/* call ACPI _GTM only once */
@@ -15,11 +14,9 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ide_acpi_get_timing(hwif);
memset(&rqpm, 0, sizeof(rqpm));
- memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_SUSPEND;
- rq->special = &cmd;
- rq->data = &rqpm;
+ rq->special = &rqpm;
rqpm.pm_step = IDE_PM_START_SUSPEND;
if (mesg.event == PM_EVENT_PRETHAW)
mesg.event = PM_EVENT_FREEZE;
@@ -41,7 +38,6 @@ int generic_ide_resume(struct device *dev)
ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
- struct ide_cmd cmd;
int err;
/* call ACPI _PS0 / _STM only once */
@@ -53,12 +49,10 @@ int generic_ide_resume(struct device *dev)
ide_acpi_exec_tfs(drive);
memset(&rqpm, 0, sizeof(rqpm));
- memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_RESUME;
rq->cmd_flags |= REQ_PREEMPT;
- rq->special = &cmd;
- rq->data = &rqpm;
+ rq->special = &rqpm;
rqpm.pm_step = IDE_PM_START_RESUME;
rqpm.pm_state = PM_EVENT_ON;
@@ -77,7 +71,7 @@ int generic_ide_resume(struct device *dev)
void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
{
- struct request_pm_state *pm = rq->data;
+ struct request_pm_state *pm = rq->special;
#ifdef DEBUG_PM
printk(KERN_INFO "%s: complete_power_step(step: %d)\n",
@@ -107,10 +101,8 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
{
- struct request_pm_state *pm = rq->data;
- struct ide_cmd *cmd = rq->special;
-
- memset(cmd, 0, sizeof(*cmd));
+ struct request_pm_state *pm = rq->special;
+ struct ide_cmd cmd = { };
switch (pm->pm_step) {
case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */
@@ -123,12 +115,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
return ide_stopped;
}
if (ata_id_flush_ext_enabled(drive->id))
- cmd->tf.command = ATA_CMD_FLUSH_EXT;
+ cmd.tf.command = ATA_CMD_FLUSH_EXT;
else
- cmd->tf.command = ATA_CMD_FLUSH;
+ cmd.tf.command = ATA_CMD_FLUSH;
goto out_do_tf;
case IDE_PM_STANDBY: /* Suspend step 2 (standby) */
- cmd->tf.command = ATA_CMD_STANDBYNOW1;
+ cmd.tf.command = ATA_CMD_STANDBYNOW1;
goto out_do_tf;
case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */
ide_set_max_pio(drive);
@@ -141,7 +133,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
ide_complete_power_step(drive, rq);
return ide_stopped;
case IDE_PM_IDLE: /* Resume step 2 (idle) */
- cmd->tf.command = ATA_CMD_IDLEIMMEDIATE;
+ cmd.tf.command = ATA_CMD_IDLEIMMEDIATE;
goto out_do_tf;
case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */
/*
@@ -163,11 +155,11 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
return ide_stopped;
out_do_tf:
- cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
- cmd->valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
- cmd->protocol = ATA_PROT_NODATA;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
+ cmd.protocol = ATA_PROT_NODATA;
- return do_rw_taskfile(drive, cmd);
+ return do_rw_taskfile(drive, &cmd);
}
/**
@@ -181,7 +173,7 @@ out_do_tf:
void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
{
struct request_queue *q = drive->queue;
- struct request_pm_state *pm = rq->data;
+ struct request_pm_state *pm = rq->special;
unsigned long flags;
ide_complete_power_step(drive, rq);
@@ -207,7 +199,7 @@ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
{
- struct request_pm_state *pm = rq->data;
+ struct request_pm_state *pm = rq->special;
if (blk_pm_suspend_request(rq) &&
pm->pm_step == IDE_PM_START_SUSPEND)
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index cb942a9b580f..e16604562f28 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -131,13 +131,6 @@ enum {
IDETAPE_DIR_WRITE = (1 << 2),
};
-struct idetape_bh {
- u32 b_size;
- atomic_t b_count;
- struct idetape_bh *b_reqnext;
- char *b_data;
-};
-
/* Tape door status */
#define DOOR_UNLOCKED 0
#define DOOR_LOCKED 1
@@ -219,18 +212,12 @@ typedef struct ide_tape_obj {
/* Data buffer size chosen based on the tape's recommendation */
int buffer_size;
- /* merge buffer */
- struct idetape_bh *merge_bh;
- /* size of the merge buffer */
- int merge_bh_size;
- /* pointer to current buffer head within the merge buffer */
- struct idetape_bh *bh;
- char *b_data;
- int b_count;
-
- int pages_per_buffer;
- /* Wasted space in each stage */
- int excess_bh_size;
+ /* Staging buffer of buffer_size bytes */
+ void *buf;
+ /* The read/write cursor */
+ void *cur;
+ /* The number of valid bytes in buf */
+ size_t valid;
/* Measures average tape speed */
unsigned long avg_time;
@@ -297,84 +284,6 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
return tape;
}
-static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount)
-{
- struct idetape_bh *bh = pc->bh;
- int count;
-
- while (bcount) {
- if (bh == NULL)
- break;
- count = min(
- (unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
- bcount);
- drive->hwif->tp_ops->input_data(drive, NULL, bh->b_data +
- atomic_read(&bh->b_count), count);
- bcount -= count;
- atomic_add(count, &bh->b_count);
- if (atomic_read(&bh->b_count) == bh->b_size) {
- bh = bh->b_reqnext;
- if (bh)
- atomic_set(&bh->b_count, 0);
- }
- }
-
- pc->bh = bh;
-
- return bcount;
-}
-
-static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount)
-{
- struct idetape_bh *bh = pc->bh;
- int count;
-
- while (bcount) {
- if (bh == NULL)
- break;
- count = min((unsigned int)pc->b_count, (unsigned int)bcount);
- drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
- bcount -= count;
- pc->b_data += count;
- pc->b_count -= count;
- if (!pc->b_count) {
- bh = bh->b_reqnext;
- pc->bh = bh;
- if (bh) {
- pc->b_data = bh->b_data;
- pc->b_count = atomic_read(&bh->b_count);
- }
- }
- }
-
- return bcount;
-}
-
-static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
-{
- struct idetape_bh *bh = pc->bh;
- int count;
- unsigned int bcount = pc->xferred;
-
- if (pc->flags & PC_FLAG_WRITING)
- return;
- while (bcount) {
- if (bh == NULL) {
- printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
- __func__);
- return;
- }
- count = min((unsigned int)bh->b_size, (unsigned int)bcount);
- atomic_set(&bh->b_count, count);
- if (atomic_read(&bh->b_count) == bh->b_size)
- bh = bh->b_reqnext;
- bcount -= count;
- }
- pc->bh = bh;
-}
-
/*
* called on each failed packet command retry to analyze the request sense. We
* currently do not utilize this information.
@@ -392,12 +301,10 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
pc->c[0], tape->sense_key, tape->asc, tape->ascq);
/* Correct pc->xferred by asking the tape. */
- if (pc->flags & PC_FLAG_DMA_ERROR) {
+ if (pc->flags & PC_FLAG_DMA_ERROR)
pc->xferred = pc->req_xfer -
tape->blk_size *
get_unaligned_be32(&sense[3]);
- idetape_update_buffers(drive, pc);
- }
/*
* If error was the result of a zero-length read or write command,
@@ -436,29 +343,6 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
}
}
-/* Free data buffers completely. */
-static void ide_tape_kfree_buffer(idetape_tape_t *tape)
-{
- struct idetape_bh *prev_bh, *bh = tape->merge_bh;
-
- while (bh) {
- u32 size = bh->b_size;
-
- while (size) {
- unsigned int order = fls(size >> PAGE_SHIFT)-1;
-
- if (bh->b_data)
- free_pages((unsigned long)bh->b_data, order);
-
- size &= (order-1);
- bh->b_data += (1 << order) * PAGE_SIZE;
- }
- prev_bh = bh;
- bh = bh->b_reqnext;
- kfree(prev_bh);
- }
-}
-
static void ide_tape_handle_dsc(ide_drive_t *);
static int ide_tape_callback(ide_drive_t *drive, int dsc)
@@ -496,7 +380,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
}
tape->first_frame += blocks;
- rq->current_nr_sectors -= blocks;
+ rq->resid_len = blk_rq_bytes(rq) - blocks * tape->blk_size;
if (pc->error) {
uptodate = 0;
@@ -558,19 +442,6 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
idetape_postpone_request(drive);
}
-static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount, int write)
-{
- unsigned int bleft;
-
- if (write)
- bleft = idetape_output_buffers(drive, pc, bcount);
- else
- bleft = idetape_input_buffers(drive, pc, bcount);
-
- return bcount - bleft;
-}
-
/*
* Packet Command Interface
*
@@ -614,12 +485,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
{
idetape_tape_t *tape = drive->driver_data;
- if (drive->pc->c[0] == REQUEST_SENSE &&
- pc->c[0] == REQUEST_SENSE) {
- printk(KERN_ERR "ide-tape: possible ide-tape.c bug - "
- "Two request sense in serial were issued\n");
- }
-
if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
drive->failed_pc = pc;
@@ -628,6 +493,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
if (pc->retries > IDETAPE_MAX_PC_RETRIES ||
(pc->flags & PC_FLAG_ABORT)) {
+ unsigned int done = blk_rq_bytes(drive->hwif->rq);
+
/*
* We will "abort" retrying a packet command in case legitimate
* error code was received (crossing a filemark, or end of the
@@ -647,8 +514,10 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
/* Giving up */
pc->error = IDE_DRV_ERROR_GENERAL;
}
+
drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
+ ide_complete_rq(drive, -EIO, done);
return ide_stopped;
}
debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]);
@@ -701,7 +570,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
printk(KERN_ERR "ide-tape: %s: I/O error, ",
tape->name);
/* Retry operation */
- ide_retry_pc(drive, tape->disk);
+ ide_retry_pc(drive);
return ide_stopped;
}
pc->error = 0;
@@ -717,27 +586,22 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
struct ide_atapi_pc *pc, struct request *rq,
u8 opcode)
{
- struct idetape_bh *bh = (struct idetape_bh *)rq->special;
- unsigned int length = rq->current_nr_sectors;
+ unsigned int length = blk_rq_sectors(rq);
ide_init_pc(pc);
put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]);
pc->c[1] = 1;
- pc->bh = bh;
pc->buf = NULL;
pc->buf_size = length * tape->blk_size;
pc->req_xfer = pc->buf_size;
if (pc->req_xfer == tape->buffer_size)
pc->flags |= PC_FLAG_DMA_OK;
- if (opcode == READ_6) {
+ if (opcode == READ_6)
pc->c[0] = READ_6;
- atomic_set(&bh->b_count, 0);
- } else if (opcode == WRITE_6) {
+ else if (opcode == WRITE_6) {
pc->c[0] = WRITE_6;
pc->flags |= PC_FLAG_WRITING;
- pc->b_data = bh->b_data;
- pc->b_count = atomic_read(&bh->b_count);
}
memcpy(rq->cmd, pc->c, 12);
@@ -753,12 +617,10 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
struct ide_cmd cmd;
u8 stat;
- debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu,"
- " current_nr_sectors: %u\n",
- (unsigned long long)rq->sector, rq->nr_sectors,
- rq->current_nr_sectors);
+ debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n"
+ (unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq));
- if (!blk_special_request(rq)) {
+ if (!(blk_special_request(rq) || blk_sense_request(rq))) {
/* We do not support buffer cache originated requests. */
printk(KERN_NOTICE "ide-tape: %s: Unsupported request in "
"request queue (%d)\n", drive->name, rq->cmd_type);
@@ -834,7 +696,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
goto out;
}
if (rq->cmd[13] & REQ_IDETAPE_PC1) {
- pc = (struct ide_atapi_pc *) rq->buffer;
+ pc = (struct ide_atapi_pc *)rq->special;
rq->cmd[13] &= ~(REQ_IDETAPE_PC1);
rq->cmd[13] |= REQ_IDETAPE_PC2;
goto out;
@@ -846,6 +708,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
BUG();
out:
+ /* prepare sense request for this command */
+ ide_prep_sense(drive, rq);
+
memset(&cmd, 0, sizeof(cmd));
if (rq_data_dir(rq))
@@ -853,167 +718,10 @@ out:
cmd.rq = rq;
- return ide_tape_issue_pc(drive, &cmd, pc);
-}
-
-/*
- * The function below uses __get_free_pages to allocate a data buffer of size
- * tape->buffer_size (or a bit more). We attempt to combine sequential pages as
- * much as possible.
- *
- * It returns a pointer to the newly allocated buffer, or NULL in case of
- * failure.
- */
-static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape,
- int full, int clear)
-{
- struct idetape_bh *prev_bh, *bh, *merge_bh;
- int pages = tape->pages_per_buffer;
- unsigned int order, b_allocd;
- char *b_data = NULL;
-
- merge_bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
- bh = merge_bh;
- if (bh == NULL)
- goto abort;
-
- order = fls(pages) - 1;
- bh->b_data = (char *) __get_free_pages(GFP_KERNEL, order);
- if (!bh->b_data)
- goto abort;
- b_allocd = (1 << order) * PAGE_SIZE;
- pages &= (order-1);
-
- if (clear)
- memset(bh->b_data, 0, b_allocd);
- bh->b_reqnext = NULL;
- bh->b_size = b_allocd;
- atomic_set(&bh->b_count, full ? bh->b_size : 0);
-
- while (pages) {
- order = fls(pages) - 1;
- b_data = (char *) __get_free_pages(GFP_KERNEL, order);
- if (!b_data)
- goto abort;
- b_allocd = (1 << order) * PAGE_SIZE;
-
- if (clear)
- memset(b_data, 0, b_allocd);
-
- /* newly allocated page frames below buffer header or ...*/
- if (bh->b_data == b_data + b_allocd) {
- bh->b_size += b_allocd;
- bh->b_data -= b_allocd;
- if (full)
- atomic_add(b_allocd, &bh->b_count);
- continue;
- }
- /* they are above the header */
- if (b_data == bh->b_data + bh->b_size) {
- bh->b_size += b_allocd;
- if (full)
- atomic_add(b_allocd, &bh->b_count);
- continue;
- }
- prev_bh = bh;
- bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
- if (!bh) {
- free_pages((unsigned long) b_data, order);
- goto abort;
- }
- bh->b_reqnext = NULL;
- bh->b_data = b_data;
- bh->b_size = b_allocd;
- atomic_set(&bh->b_count, full ? bh->b_size : 0);
- prev_bh->b_reqnext = bh;
-
- pages &= (order-1);
- }
+ ide_init_sg_cmd(&cmd, pc->req_xfer);
+ ide_map_sg(drive, &cmd);
- bh->b_size -= tape->excess_bh_size;
- if (full)
- atomic_sub(tape->excess_bh_size, &bh->b_count);
- return merge_bh;
-abort:
- ide_tape_kfree_buffer(tape);
- return NULL;
-}
-
-static int idetape_copy_stage_from_user(idetape_tape_t *tape,
- const char __user *buf, int n)
-{
- struct idetape_bh *bh = tape->bh;
- int count;
- int ret = 0;
-
- while (n) {
- if (bh == NULL) {
- printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
- __func__);
- return 1;
- }
- count = min((unsigned int)
- (bh->b_size - atomic_read(&bh->b_count)),
- (unsigned int)n);
- if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf,
- count))
- ret = 1;
- n -= count;
- atomic_add(count, &bh->b_count);
- buf += count;
- if (atomic_read(&bh->b_count) == bh->b_size) {
- bh = bh->b_reqnext;
- if (bh)
- atomic_set(&bh->b_count, 0);
- }
- }
- tape->bh = bh;
- return ret;
-}
-
-static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf,
- int n)
-{
- struct idetape_bh *bh = tape->bh;
- int count;
- int ret = 0;
-
- while (n) {
- if (bh == NULL) {
- printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
- __func__);
- return 1;
- }
- count = min(tape->b_count, n);
- if (copy_to_user(buf, tape->b_data, count))
- ret = 1;
- n -= count;
- tape->b_data += count;
- tape->b_count -= count;
- buf += count;
- if (!tape->b_count) {
- bh = bh->b_reqnext;
- tape->bh = bh;
- if (bh) {
- tape->b_data = bh->b_data;
- tape->b_count = atomic_read(&bh->b_count);
- }
- }
- }
- return ret;
-}
-
-static void idetape_init_merge_buffer(idetape_tape_t *tape)
-{
- struct idetape_bh *bh = tape->merge_bh;
- tape->bh = tape->merge_bh;
-
- if (tape->chrdev_dir == IDETAPE_DIR_WRITE)
- atomic_set(&bh->b_count, 0);
- else {
- tape->b_data = bh->b_data;
- tape->b_count = atomic_read(&bh->b_count);
- }
+ return ide_tape_issue_pc(drive, &cmd, pc);
}
/*
@@ -1113,10 +821,10 @@ static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
return;
clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags);
- tape->merge_bh_size = 0;
- if (tape->merge_bh != NULL) {
- ide_tape_kfree_buffer(tape);
- tape->merge_bh = NULL;
+ tape->valid = 0;
+ if (tape->buf != NULL) {
+ kfree(tape->buf);
+ tape->buf = NULL;
}
tape->chrdev_dir = IDETAPE_DIR_NONE;
@@ -1170,36 +878,43 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
* Generate a read/write request for the block device interface and wait for it
* to be serviced.
*/
-static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
- struct idetape_bh *bh)
+static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size)
{
idetape_tape_t *tape = drive->driver_data;
struct request *rq;
- int ret, errors;
+ int ret;
debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd);
+ BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE);
+ BUG_ON(size < 0 || size % tape->blk_size);
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_SPECIAL;
rq->cmd[13] = cmd;
rq->rq_disk = tape->disk;
- rq->special = (void *)bh;
- rq->sector = tape->first_frame;
- rq->nr_sectors = blocks;
- rq->current_nr_sectors = blocks;
- blk_execute_rq(drive->queue, tape->disk, rq, 0);
- errors = rq->errors;
- ret = tape->blk_size * (blocks - rq->current_nr_sectors);
- blk_put_request(rq);
+ if (size) {
+ ret = blk_rq_map_kern(drive->queue, rq, tape->buf, size,
+ __GFP_WAIT);
+ if (ret)
+ goto out_put;
+ }
- if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0)
- return 0;
+ blk_execute_rq(drive->queue, tape->disk, rq, 0);
- if (tape->merge_bh)
- idetape_init_merge_buffer(tape);
- if (errors == IDE_DRV_ERROR_GENERAL)
- return -EIO;
+ /* calculate the number of transferred bytes and update buffer state */
+ size -= rq->resid_len;
+ tape->cur = tape->buf;
+ if (cmd == REQ_IDETAPE_READ)
+ tape->valid = size;
+ else
+ tape->valid = 0;
+
+ ret = size;
+ if (rq->errors == IDE_DRV_ERROR_GENERAL)
+ ret = -EIO;
+out_put:
+ blk_put_request(rq);
return ret;
}
@@ -1236,153 +951,87 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
}
-/* Queue up a character device originated write request. */
-static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks)
-{
- idetape_tape_t *tape = drive->driver_data;
-
- debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
-
- return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE,
- blocks, tape->merge_bh);
-}
-
static void ide_tape_flush_merge_buffer(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
- int blocks, min;
- struct idetape_bh *bh;
if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer"
" but we are not writing.\n");
return;
}
- if (tape->merge_bh_size > tape->buffer_size) {
- printk(KERN_ERR "ide-tape: bug: merge_buffer too big\n");
- tape->merge_bh_size = tape->buffer_size;
- }
- if (tape->merge_bh_size) {
- blocks = tape->merge_bh_size / tape->blk_size;
- if (tape->merge_bh_size % tape->blk_size) {
- unsigned int i;
-
- blocks++;
- i = tape->blk_size - tape->merge_bh_size %
- tape->blk_size;
- bh = tape->bh->b_reqnext;
- while (bh) {
- atomic_set(&bh->b_count, 0);
- bh = bh->b_reqnext;
- }
- bh = tape->bh;
- while (i) {
- if (bh == NULL) {
- printk(KERN_INFO "ide-tape: bug,"
- " bh NULL\n");
- break;
- }
- min = min(i, (unsigned int)(bh->b_size -
- atomic_read(&bh->b_count)));
- memset(bh->b_data + atomic_read(&bh->b_count),
- 0, min);
- atomic_add(min, &bh->b_count);
- i -= min;
- bh = bh->b_reqnext;
- }
- }
- (void) idetape_add_chrdev_write_request(drive, blocks);
- tape->merge_bh_size = 0;
- }
- if (tape->merge_bh != NULL) {
- ide_tape_kfree_buffer(tape);
- tape->merge_bh = NULL;
+ if (tape->buf) {
+ size_t aligned = roundup(tape->valid, tape->blk_size);
+
+ memset(tape->cur, 0, aligned - tape->valid);
+ idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, aligned);
+ kfree(tape->buf);
+ tape->buf = NULL;
}
tape->chrdev_dir = IDETAPE_DIR_NONE;
}
-static int idetape_init_read(ide_drive_t *drive)
+static int idetape_init_rw(ide_drive_t *drive, int dir)
{
idetape_tape_t *tape = drive->driver_data;
- int bytes_read;
-
- /* Initialize read operation */
- if (tape->chrdev_dir != IDETAPE_DIR_READ) {
- if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
- ide_tape_flush_merge_buffer(drive);
- idetape_flush_tape_buffers(drive);
- }
- if (tape->merge_bh || tape->merge_bh_size) {
- printk(KERN_ERR "ide-tape: merge_bh_size should be"
- " 0 now\n");
- tape->merge_bh_size = 0;
- }
- tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
- if (!tape->merge_bh)
- return -ENOMEM;
- tape->chrdev_dir = IDETAPE_DIR_READ;
+ int rc;
- /*
- * Issue a read 0 command to ensure that DSC handshake is
- * switched from completion mode to buffer available mode.
- * No point in issuing this if DSC overlap isn't supported, some
- * drives (Seagate STT3401A) will return an error.
- */
- if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) {
- bytes_read = idetape_queue_rw_tail(drive,
- REQ_IDETAPE_READ, 0,
- tape->merge_bh);
- if (bytes_read < 0) {
- ide_tape_kfree_buffer(tape);
- tape->merge_bh = NULL;
- tape->chrdev_dir = IDETAPE_DIR_NONE;
- return bytes_read;
- }
- }
- }
+ BUG_ON(dir != IDETAPE_DIR_READ && dir != IDETAPE_DIR_WRITE);
- return 0;
-}
+ if (tape->chrdev_dir == dir)
+ return 0;
-/* called from idetape_chrdev_read() to service a chrdev read request. */
-static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
-{
- idetape_tape_t *tape = drive->driver_data;
+ if (tape->chrdev_dir == IDETAPE_DIR_READ)
+ ide_tape_discard_merge_buffer(drive, 1);
+ else if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
+ ide_tape_flush_merge_buffer(drive);
+ idetape_flush_tape_buffers(drive);
+ }
- debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks);
+ if (tape->buf || tape->valid) {
+ printk(KERN_ERR "ide-tape: valid should be 0 now\n");
+ tape->valid = 0;
+ }
- /* If we are at a filemark, return a read length of 0 */
- if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
- return 0;
+ tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL);
+ if (!tape->buf)
+ return -ENOMEM;
+ tape->chrdev_dir = dir;
+ tape->cur = tape->buf;
- idetape_init_read(drive);
+ /*
+ * Issue a 0 rw command to ensure that DSC handshake is
+ * switched from completion mode to buffer available mode. No
+ * point in issuing this if DSC overlap isn't supported, some
+ * drives (Seagate STT3401A) will return an error.
+ */
+ if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) {
+ int cmd = dir == IDETAPE_DIR_READ ? REQ_IDETAPE_READ
+ : REQ_IDETAPE_WRITE;
+
+ rc = idetape_queue_rw_tail(drive, cmd, 0);
+ if (rc < 0) {
+ kfree(tape->buf);
+ tape->buf = NULL;
+ tape->chrdev_dir = IDETAPE_DIR_NONE;
+ return rc;
+ }
+ }
- return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks,
- tape->merge_bh);
+ return 0;
}
static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
{
idetape_tape_t *tape = drive->driver_data;
- struct idetape_bh *bh;
- int blocks;
+
+ memset(tape->buf, 0, tape->buffer_size);
while (bcount) {
- unsigned int count;
+ unsigned int count = min(tape->buffer_size, bcount);
- bh = tape->merge_bh;
- count = min(tape->buffer_size, bcount);
+ idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, count);
bcount -= count;
- blocks = count / tape->blk_size;
- while (count) {
- atomic_set(&bh->b_count,
- min(count, (unsigned int)bh->b_size));
- memset(bh->b_data, 0, atomic_read(&bh->b_count));
- count -= atomic_read(&bh->b_count);
- bh = bh->b_reqnext;
- }
- idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks,
- tape->merge_bh);
}
}
@@ -1462,7 +1111,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
}
if (tape->chrdev_dir == IDETAPE_DIR_READ) {
- tape->merge_bh_size = 0;
+ tape->valid = 0;
if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
++count;
ide_tape_discard_merge_buffer(drive, 0);
@@ -1511,9 +1160,9 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
{
struct ide_tape_obj *tape = file->private_data;
ide_drive_t *drive = tape->drive;
- ssize_t bytes_read, temp, actually_read = 0, rc;
+ size_t done = 0;
ssize_t ret = 0;
- u16 ctl = *(u16 *)&tape->caps[12];
+ int rc;
debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
@@ -1523,49 +1172,43 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
(count % tape->blk_size) == 0)
tape->user_bs_factor = count / tape->blk_size;
}
- rc = idetape_init_read(drive);
+
+ rc = idetape_init_rw(drive, IDETAPE_DIR_READ);
if (rc < 0)
return rc;
- if (count == 0)
- return (0);
- if (tape->merge_bh_size) {
- actually_read = min((unsigned int)(tape->merge_bh_size),
- (unsigned int)count);
- if (idetape_copy_stage_to_user(tape, buf, actually_read))
- ret = -EFAULT;
- buf += actually_read;
- tape->merge_bh_size -= actually_read;
- count -= actually_read;
- }
- while (count >= tape->buffer_size) {
- bytes_read = idetape_add_chrdev_read_request(drive, ctl);
- if (bytes_read <= 0)
- goto finish;
- if (idetape_copy_stage_to_user(tape, buf, bytes_read))
- ret = -EFAULT;
- buf += bytes_read;
- count -= bytes_read;
- actually_read += bytes_read;
- }
- if (count) {
- bytes_read = idetape_add_chrdev_read_request(drive, ctl);
- if (bytes_read <= 0)
- goto finish;
- temp = min((unsigned long)count, (unsigned long)bytes_read);
- if (idetape_copy_stage_to_user(tape, buf, temp))
+
+ while (done < count) {
+ size_t todo;
+
+ /* refill if staging buffer is empty */
+ if (!tape->valid) {
+ /* If we are at a filemark, nothing more to read */
+ if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
+ break;
+ /* read */
+ if (idetape_queue_rw_tail(drive, REQ_IDETAPE_READ,
+ tape->buffer_size) <= 0)
+ break;
+ }
+
+ /* copy out */
+ todo = min_t(size_t, count - done, tape->valid);
+ if (copy_to_user(buf + done, tape->cur, todo))
ret = -EFAULT;
- actually_read += temp;
- tape->merge_bh_size = bytes_read-temp;
+
+ tape->cur += todo;
+ tape->valid -= todo;
+ done += todo;
}
-finish:
- if (!actually_read && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) {
+
+ if (!done && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) {
debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name);
idetape_space_over_filemarks(drive, MTFSF, 1);
return 0;
}
- return ret ? ret : actually_read;
+ return ret ? ret : done;
}
static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
@@ -1573,9 +1216,9 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
{
struct ide_tape_obj *tape = file->private_data;
ide_drive_t *drive = tape->drive;
- ssize_t actually_written = 0;
+ size_t done = 0;
ssize_t ret = 0;
- u16 ctl = *(u16 *)&tape->caps[12];
+ int rc;
/* The drive is write protected. */
if (tape->write_prot)
@@ -1584,80 +1227,31 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
/* Initialize write operation */
- if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
- if (tape->chrdev_dir == IDETAPE_DIR_READ)
- ide_tape_discard_merge_buffer(drive, 1);
- if (tape->merge_bh || tape->merge_bh_size) {
- printk(KERN_ERR "ide-tape: merge_bh_size "
- "should be 0 now\n");
- tape->merge_bh_size = 0;
- }
- tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
- if (!tape->merge_bh)
- return -ENOMEM;
- tape->chrdev_dir = IDETAPE_DIR_WRITE;
- idetape_init_merge_buffer(tape);
+ rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE);
+ if (rc < 0)
+ return rc;
- /*
- * Issue a write 0 command to ensure that DSC handshake is
- * switched from completion mode to buffer available mode. No
- * point in issuing this if DSC overlap isn't supported, some
- * drives (Seagate STT3401A) will return an error.
- */
- if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) {
- ssize_t retval = idetape_queue_rw_tail(drive,
- REQ_IDETAPE_WRITE, 0,
- tape->merge_bh);
- if (retval < 0) {
- ide_tape_kfree_buffer(tape);
- tape->merge_bh = NULL;
- tape->chrdev_dir = IDETAPE_DIR_NONE;
- return retval;
- }
- }
- }
- if (count == 0)
- return (0);
- if (tape->merge_bh_size) {
- if (tape->merge_bh_size >= tape->buffer_size) {
- printk(KERN_ERR "ide-tape: bug: merge buf too big\n");
- tape->merge_bh_size = 0;
- }
- actually_written = min((unsigned int)
- (tape->buffer_size - tape->merge_bh_size),
- (unsigned int)count);
- if (idetape_copy_stage_from_user(tape, buf, actually_written))
- ret = -EFAULT;
- buf += actually_written;
- tape->merge_bh_size += actually_written;
- count -= actually_written;
-
- if (tape->merge_bh_size == tape->buffer_size) {
- ssize_t retval;
- tape->merge_bh_size = 0;
- retval = idetape_add_chrdev_write_request(drive, ctl);
- if (retval <= 0)
- return (retval);
- }
- }
- while (count >= tape->buffer_size) {
- ssize_t retval;
- if (idetape_copy_stage_from_user(tape, buf, tape->buffer_size))
- ret = -EFAULT;
- buf += tape->buffer_size;
- count -= tape->buffer_size;
- retval = idetape_add_chrdev_write_request(drive, ctl);
- actually_written += tape->buffer_size;
- if (retval <= 0)
- return (retval);
- }
- if (count) {
- actually_written += count;
- if (idetape_copy_stage_from_user(tape, buf, count))
+ while (done < count) {
+ size_t todo;
+
+ /* flush if staging buffer is full */
+ if (tape->valid == tape->buffer_size &&
+ idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE,
+ tape->buffer_size) <= 0)
+ return rc;
+
+ /* copy in */
+ todo = min_t(size_t, count - done,
+ tape->buffer_size - tape->valid);
+ if (copy_from_user(tape->cur, buf + done, todo))
ret = -EFAULT;
- tape->merge_bh_size += count;
+
+ tape->cur += todo;
+ tape->valid += todo;
+ done += todo;
}
- return ret ? ret : actually_written;
+
+ return ret ? ret : done;
}
static int idetape_write_filemark(ide_drive_t *drive)
@@ -1818,7 +1412,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
idetape_flush_tape_buffers(drive);
}
if (cmd == MTIOCGET || cmd == MTIOCPOS) {
- block_offset = tape->merge_bh_size /
+ block_offset = tape->valid /
(tape->blk_size * tape->user_bs_factor);
position = idetape_read_position(drive);
if (position < 0)
@@ -1966,12 +1560,12 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor)
idetape_tape_t *tape = drive->driver_data;
ide_tape_flush_merge_buffer(drive);
- tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1, 0);
- if (tape->merge_bh != NULL) {
+ tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL);
+ if (tape->buf != NULL) {
idetape_pad_zeros(drive, tape->blk_size *
(tape->user_bs_factor - 1));
- ide_tape_kfree_buffer(tape);
- tape->merge_bh = NULL;
+ kfree(tape->buf);
+ tape->buf = NULL;
}
idetape_write_filemark(drive);
idetape_flush_tape_buffers(drive);
@@ -2165,8 +1759,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
u16 *ctl = (u16 *)&tape->caps[12];
drive->pc_callback = ide_tape_callback;
- drive->pc_update_buffers = idetape_update_buffers;
- drive->pc_io_buffers = ide_tape_io_buffers;
drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
@@ -2197,11 +1789,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
tape->buffer_size = *ctl * tape->blk_size;
}
buffer_size = tape->buffer_size;
- tape->pages_per_buffer = buffer_size / PAGE_SIZE;
- if (buffer_size % PAGE_SIZE) {
- tape->pages_per_buffer++;
- tape->excess_bh_size = PAGE_SIZE - buffer_size % PAGE_SIZE;
- }
/* select the "best" DSC read/write polling freq */
speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]);
@@ -2244,7 +1831,7 @@ static void ide_tape_release(struct device *dev)
ide_drive_t *drive = tape->drive;
struct gendisk *g = tape->disk;
- BUG_ON(tape->merge_bh_size);
+ BUG_ON(tape->valid);
drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
drive->driver_data = NULL;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 4aa6223c11be..a0c3e1b2f73c 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -385,7 +385,7 @@ out_end:
if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
ide_finish_cmd(drive, cmd, stat);
else
- ide_complete_rq(drive, 0, cmd->rq->nr_sectors << 9);
+ ide_complete_rq(drive, 0, blk_rq_sectors(cmd->rq) << 9);
return ide_stopped;
out_err:
ide_error_cmd(drive, cmd);
@@ -424,7 +424,9 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
- rq->buffer = buf;
+
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
+ rq->cmd_flags |= REQ_RW;
/*
* (ks) We transfer currently only whole sectors.
@@ -432,18 +434,20 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
* if we would find a solution to transfer any size.
* To support special commands like READ LONG.
*/
- rq->hard_nr_sectors = rq->nr_sectors = nsect;
- rq->hard_cur_sectors = rq->current_nr_sectors = nsect;
-
- if (cmd->tf_flags & IDE_TFLAG_WRITE)
- rq->cmd_flags |= REQ_RW;
+ if (nsect) {
+ error = blk_rq_map_kern(drive->queue, rq, buf,
+ nsect * SECTOR_SIZE, __GFP_WAIT);
+ if (error)
+ goto put_req;
+ }
rq->special = cmd;
cmd->rq = rq;
error = blk_execute_rq(drive->queue, NULL, rq, 0);
- blk_put_request(rq);
+put_req:
+ blk_put_request(rq);
return error;
}
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index 248a54bd2386..c2a16a8f486d 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -177,7 +177,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive)
u8 clock = inb(high_16 + 0x11);
outb(clock | (hwif->channel ? 0x08 : 0x02), high_16 + 0x11);
- word_count = (rq->nr_sectors << 8);
+ word_count = (blk_rq_sectors(rq) << 8);
word_count = (rq_data_dir(rq) == READ) ?
word_count | 0x05000000 :
word_count | 0x06000000;
diff --git a/drivers/ide/tc86c001.c b/drivers/ide/tc86c001.c
index b4cf42dc8a6f..05a93d6baecc 100644
--- a/drivers/ide/tc86c001.c
+++ b/drivers/ide/tc86c001.c
@@ -112,7 +112,7 @@ static void tc86c001_dma_start(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
unsigned long sc_base = hwif->config_data;
unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04);
- unsigned long nsectors = hwif->rq->nr_sectors;
+ unsigned long nsectors = blk_rq_sectors(hwif->rq);
/*
* We have to manually load the sector count and size into
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 564422d23976..5ca76224f6d1 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -307,7 +307,7 @@ static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ?
TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1);
- tx4939ide_writew(cmd->rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
+ tx4939ide_writew(blk_rq_sectors(cmd->rq), base, TX4939IDE_Sec_Cnt);
return 0;
}
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index 8d71086f5a1c..62f9cf2f94ec 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -410,6 +410,7 @@ int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count)
ptr = wq->sq_rptr + count;
sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
while (ptr != wq->sq_wptr) {
+ sqp->signaled = 0;
insert_sq_cqe(wq, cq, sqp);
ptr++;
sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 368311ce332b..85905ab9391f 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -52,7 +52,7 @@
#include "ehca_tools.h"
#include "hcp_if.h"
-#define HCAD_VERSION "0026"
+#define HCAD_VERSION "0027"
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 00c108159714..ead4e718c082 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -461,7 +461,7 @@ static struct ehca_qp *internal_create_qp(
ib_device);
struct ib_ucontext *context = NULL;
u64 h_ret;
- int is_llqp = 0, has_srq = 0;
+ int is_llqp = 0, has_srq = 0, is_user = 0;
int qp_type, max_send_sge, max_recv_sge, ret;
/* h_call's out parameters */
@@ -609,9 +609,6 @@ static struct ehca_qp *internal_create_qp(
}
}
- if (pd->uobject && udata)
- context = pd->uobject->context;
-
my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL);
if (!my_qp) {
ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd);
@@ -619,6 +616,11 @@ static struct ehca_qp *internal_create_qp(
return ERR_PTR(-ENOMEM);
}
+ if (pd->uobject && udata) {
+ is_user = 1;
+ context = pd->uobject->context;
+ }
+
atomic_set(&my_qp->nr_events, 0);
init_waitqueue_head(&my_qp->wait_completion);
spin_lock_init(&my_qp->spinlock_s);
@@ -707,7 +709,7 @@ static struct ehca_qp *internal_create_qp(
(parms.squeue.is_small || parms.rqueue.is_small);
}
- h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, &parms);
+ h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, &parms, is_user);
if (h_ret != H_SUCCESS) {
ehca_err(pd->device, "h_alloc_resource_qp() failed h_ret=%lli",
h_ret);
@@ -769,18 +771,20 @@ static struct ehca_qp *internal_create_qp(
goto create_qp_exit2;
}
- my_qp->sq_map.entries = my_qp->ipz_squeue.queue_length /
- my_qp->ipz_squeue.qe_size;
- my_qp->sq_map.map = vmalloc(my_qp->sq_map.entries *
- sizeof(struct ehca_qmap_entry));
- if (!my_qp->sq_map.map) {
- ehca_err(pd->device, "Couldn't allocate squeue "
- "map ret=%i", ret);
- goto create_qp_exit3;
+ if (!is_user) {
+ my_qp->sq_map.entries = my_qp->ipz_squeue.queue_length /
+ my_qp->ipz_squeue.qe_size;
+ my_qp->sq_map.map = vmalloc(my_qp->sq_map.entries *
+ sizeof(struct ehca_qmap_entry));
+ if (!my_qp->sq_map.map) {
+ ehca_err(pd->device, "Couldn't allocate squeue "
+ "map ret=%i", ret);
+ goto create_qp_exit3;
+ }
+ INIT_LIST_HEAD(&my_qp->sq_err_node);
+ /* to avoid the generation of bogus flush CQEs */
+ reset_queue_map(&my_qp->sq_map);
}
- INIT_LIST_HEAD(&my_qp->sq_err_node);
- /* to avoid the generation of bogus flush CQEs */
- reset_queue_map(&my_qp->sq_map);
}
if (HAS_RQ(my_qp)) {
@@ -792,20 +796,21 @@ static struct ehca_qp *internal_create_qp(
"and pages ret=%i", ret);
goto create_qp_exit4;
}
-
- my_qp->rq_map.entries = my_qp->ipz_rqueue.queue_length /
- my_qp->ipz_rqueue.qe_size;
- my_qp->rq_map.map = vmalloc(my_qp->rq_map.entries *
- sizeof(struct ehca_qmap_entry));
- if (!my_qp->rq_map.map) {
- ehca_err(pd->device, "Couldn't allocate squeue "
- "map ret=%i", ret);
- goto create_qp_exit5;
+ if (!is_user) {
+ my_qp->rq_map.entries = my_qp->ipz_rqueue.queue_length /
+ my_qp->ipz_rqueue.qe_size;
+ my_qp->rq_map.map = vmalloc(my_qp->rq_map.entries *
+ sizeof(struct ehca_qmap_entry));
+ if (!my_qp->rq_map.map) {
+ ehca_err(pd->device, "Couldn't allocate squeue "
+ "map ret=%i", ret);
+ goto create_qp_exit5;
+ }
+ INIT_LIST_HEAD(&my_qp->rq_err_node);
+ /* to avoid the generation of bogus flush CQEs */
+ reset_queue_map(&my_qp->rq_map);
}
- INIT_LIST_HEAD(&my_qp->rq_err_node);
- /* to avoid the generation of bogus flush CQEs */
- reset_queue_map(&my_qp->rq_map);
- } else if (init_attr->srq) {
+ } else if (init_attr->srq && !is_user) {
/* this is a base QP, use the queue map of the SRQ */
my_qp->rq_map = my_srq->rq_map;
INIT_LIST_HEAD(&my_qp->rq_err_node);
@@ -918,7 +923,7 @@ create_qp_exit7:
kfree(my_qp->mod_qp_parm);
create_qp_exit6:
- if (HAS_RQ(my_qp))
+ if (HAS_RQ(my_qp) && !is_user)
vfree(my_qp->rq_map.map);
create_qp_exit5:
@@ -926,7 +931,7 @@ create_qp_exit5:
ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue);
create_qp_exit4:
- if (HAS_SQ(my_qp))
+ if (HAS_SQ(my_qp) && !is_user)
vfree(my_qp->sq_map.map);
create_qp_exit3:
@@ -1244,6 +1249,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
u64 update_mask;
u64 h_ret;
int bad_wqe_cnt = 0;
+ int is_user = 0;
int squeue_locked = 0;
unsigned long flags = 0;
@@ -1266,6 +1272,8 @@ static int internal_modify_qp(struct ib_qp *ibqp,
ret = ehca2ib_return_code(h_ret);
goto modify_qp_exit1;
}
+ if (ibqp->uobject)
+ is_user = 1;
qp_cur_state = ehca2ib_qp_state(mqpcb->qp_state);
@@ -1728,7 +1736,8 @@ static int internal_modify_qp(struct ib_qp *ibqp,
goto modify_qp_exit2;
}
}
- if ((qp_new_state == IB_QPS_ERR) && (qp_cur_state != IB_QPS_ERR)) {
+ if ((qp_new_state == IB_QPS_ERR) && (qp_cur_state != IB_QPS_ERR)
+ && !is_user) {
ret = check_for_left_cqes(my_qp, shca);
if (ret)
goto modify_qp_exit2;
@@ -1738,16 +1747,17 @@ static int internal_modify_qp(struct ib_qp *ibqp,
ipz_qeit_reset(&my_qp->ipz_rqueue);
ipz_qeit_reset(&my_qp->ipz_squeue);
- if (qp_cur_state == IB_QPS_ERR) {
+ if (qp_cur_state == IB_QPS_ERR && !is_user) {
del_from_err_list(my_qp->send_cq, &my_qp->sq_err_node);
if (HAS_RQ(my_qp))
del_from_err_list(my_qp->recv_cq,
&my_qp->rq_err_node);
}
- reset_queue_map(&my_qp->sq_map);
+ if (!is_user)
+ reset_queue_map(&my_qp->sq_map);
- if (HAS_RQ(my_qp))
+ if (HAS_RQ(my_qp) && !is_user)
reset_queue_map(&my_qp->rq_map);
}
@@ -2138,10 +2148,12 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
int ret;
u64 h_ret;
u8 port_num;
+ int is_user = 0;
enum ib_qp_type qp_type;
unsigned long flags;
if (uobject) {
+ is_user = 1;
if (my_qp->mm_count_galpa ||
my_qp->mm_count_rqueue || my_qp->mm_count_squeue) {
ehca_err(dev, "Resources still referenced in "
@@ -2168,10 +2180,10 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
* SRQs will never get into an error list and do not have a recv_cq,
* so we need to skip them here.
*/
- if (HAS_RQ(my_qp) && !IS_SRQ(my_qp))
+ if (HAS_RQ(my_qp) && !IS_SRQ(my_qp) && !is_user)
del_from_err_list(my_qp->recv_cq, &my_qp->rq_err_node);
- if (HAS_SQ(my_qp))
+ if (HAS_SQ(my_qp) && !is_user)
del_from_err_list(my_qp->send_cq, &my_qp->sq_err_node);
/* now wait until all pending events have completed */
@@ -2209,13 +2221,13 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
if (HAS_RQ(my_qp)) {
ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue);
-
- vfree(my_qp->rq_map.map);
+ if (!is_user)
+ vfree(my_qp->rq_map.map);
}
if (HAS_SQ(my_qp)) {
ipz_queue_dtor(my_pd, &my_qp->ipz_squeue);
-
- vfree(my_qp->sq_map.map);
+ if (!is_user)
+ vfree(my_qp->sq_map.map);
}
kmem_cache_free(qp_cache, my_qp);
atomic_dec(&shca->num_qps);
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index d0ab0c0d5e91..4d5dc3304d42 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -284,7 +284,7 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
param->act_pages = (u32)outs[4];
if (ret == H_SUCCESS)
- hcp_galpas_ctor(&cq->galpas, outs[5], outs[6]);
+ hcp_galpas_ctor(&cq->galpas, 0, outs[5], outs[6]);
if (ret == H_NOT_ENOUGH_RESOURCES)
ehca_gen_err("Not enough resources. ret=%lli", ret);
@@ -293,7 +293,7 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
}
u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
- struct ehca_alloc_qp_parms *parms)
+ struct ehca_alloc_qp_parms *parms, int is_user)
{
u64 ret;
u64 allocate_controls, max_r10_reg, r11, r12;
@@ -359,7 +359,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
(u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);
if (ret == H_SUCCESS)
- hcp_galpas_ctor(&parms->galpas, outs[6], outs[6]);
+ hcp_galpas_ctor(&parms->galpas, is_user, outs[6], outs[6]);
if (ret == H_NOT_ENOUGH_RESOURCES)
ehca_gen_err("Not enough resources. ret=%lli", ret);
diff --git a/drivers/infiniband/hw/ehca/hcp_if.h b/drivers/infiniband/hw/ehca/hcp_if.h
index 2c3c6e0ea5c2..39c1c3618ec7 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.h
+++ b/drivers/infiniband/hw/ehca/hcp_if.h
@@ -78,7 +78,7 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
* initialize resources, create empty QPPTs (2 rings).
*/
u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
- struct ehca_alloc_qp_parms *parms);
+ struct ehca_alloc_qp_parms *parms, int is_user);
u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
const u8 port_id,
diff --git a/drivers/infiniband/hw/ehca/hcp_phyp.c b/drivers/infiniband/hw/ehca/hcp_phyp.c
index 214821095cb1..b3e0e72e8a73 100644
--- a/drivers/infiniband/hw/ehca/hcp_phyp.c
+++ b/drivers/infiniband/hw/ehca/hcp_phyp.c
@@ -54,12 +54,15 @@ int hcall_unmap_page(u64 mapaddr)
return 0;
}
-int hcp_galpas_ctor(struct h_galpas *galpas,
+int hcp_galpas_ctor(struct h_galpas *galpas, int is_user,
u64 paddr_kernel, u64 paddr_user)
{
- int ret = hcall_map_page(paddr_kernel, &galpas->kernel.fw_handle);
- if (ret)
- return ret;
+ if (!is_user) {
+ int ret = hcall_map_page(paddr_kernel, &galpas->kernel.fw_handle);
+ if (ret)
+ return ret;
+ } else
+ galpas->kernel.fw_handle = 0;
galpas->user.fw_handle = paddr_user;
diff --git a/drivers/infiniband/hw/ehca/hcp_phyp.h b/drivers/infiniband/hw/ehca/hcp_phyp.h
index 5305c2a3ed94..204227d5303a 100644
--- a/drivers/infiniband/hw/ehca/hcp_phyp.h
+++ b/drivers/infiniband/hw/ehca/hcp_phyp.h
@@ -78,7 +78,7 @@ static inline void hipz_galpa_store(struct h_galpa galpa, u32 offset, u64 value)
*(volatile u64 __force *)addr = value;
}
-int hcp_galpas_ctor(struct h_galpas *galpas,
+int hcp_galpas_ctor(struct h_galpas *galpas, int is_user,
u64 paddr_kernel, u64 paddr_user);
int hcp_galpas_dtor(struct h_galpas *galpas);
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
index c3a328465431..1227c593627a 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
@@ -220,10 +220,13 @@ int ipz_queue_ctor(struct ehca_pd *pd, struct ipz_queue *queue,
queue->small_page = NULL;
/* allocate queue page pointers */
- queue->queue_pages = vmalloc(nr_of_pages * sizeof(void *));
+ queue->queue_pages = kmalloc(nr_of_pages * sizeof(void *), GFP_KERNEL);
if (!queue->queue_pages) {
- ehca_gen_err("Couldn't allocate queue page list");
- return 0;
+ queue->queue_pages = vmalloc(nr_of_pages * sizeof(void *));
+ if (!queue->queue_pages) {
+ ehca_gen_err("Couldn't allocate queue page list");
+ return 0;
+ }
}
memset(queue->queue_pages, 0, nr_of_pages * sizeof(void *));
@@ -240,7 +243,10 @@ int ipz_queue_ctor(struct ehca_pd *pd, struct ipz_queue *queue,
ipz_queue_ctor_exit0:
ehca_gen_err("Couldn't alloc pages queue=%p "
"nr_of_pages=%x", queue, nr_of_pages);
- vfree(queue->queue_pages);
+ if (is_vmalloc_addr(queue->queue_pages))
+ vfree(queue->queue_pages);
+ else
+ kfree(queue->queue_pages);
return 0;
}
@@ -262,7 +268,10 @@ int ipz_queue_dtor(struct ehca_pd *pd, struct ipz_queue *queue)
free_page((unsigned long)queue->queue_pages[i]);
}
- vfree(queue->queue_pages);
+ if (is_vmalloc_addr(queue->queue_pages))
+ vfree(queue->queue_pages);
+ else
+ kfree(queue->queue_pages);
return 1;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index 8dc2bb781605..b3684060465e 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -347,7 +347,7 @@ static int ipathfs_fill_super(struct super_block *sb, void *data,
spin_unlock_irqrestore(&ipath_devs_lock, flags);
ret = create_device_files(sb, dd);
if (ret) {
- deactivate_super(sb);
+ deactivate_locked_super(sb);
goto bail;
}
spin_lock_irqsave(&ipath_devs_lock, flags);
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 9974e886b8de..8a7dd6795fa0 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -86,6 +86,7 @@ struct mlx4_ib_mr {
struct mlx4_ib_fast_reg_page_list {
struct ib_fast_reg_page_list ibfrpl;
+ __be64 *mapped_page_list;
dma_addr_t map;
};
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
index 8e4d26d56a95..8f3666b20ea4 100644
--- a/drivers/infiniband/hw/mlx4/mr.c
+++ b/drivers/infiniband/hw/mlx4/mr.c
@@ -231,7 +231,11 @@ struct ib_fast_reg_page_list *mlx4_ib_alloc_fast_reg_page_list(struct ib_device
if (!mfrpl)
return ERR_PTR(-ENOMEM);
- mfrpl->ibfrpl.page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
+ mfrpl->ibfrpl.page_list = kmalloc(size, GFP_KERNEL);
+ if (!mfrpl->ibfrpl.page_list)
+ goto err_free;
+
+ mfrpl->mapped_page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
size, &mfrpl->map,
GFP_KERNEL);
if (!mfrpl->ibfrpl.page_list)
@@ -242,6 +246,7 @@ struct ib_fast_reg_page_list *mlx4_ib_alloc_fast_reg_page_list(struct ib_device
return &mfrpl->ibfrpl;
err_free:
+ kfree(mfrpl->ibfrpl.page_list);
kfree(mfrpl);
return ERR_PTR(-ENOMEM);
}
@@ -252,8 +257,9 @@ void mlx4_ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list)
struct mlx4_ib_fast_reg_page_list *mfrpl = to_mfrpl(page_list);
int size = page_list->max_page_list_len * sizeof (u64);
- dma_free_coherent(&dev->dev->pdev->dev, size, page_list->page_list,
+ dma_free_coherent(&dev->dev->pdev->dev, size, mfrpl->mapped_page_list,
mfrpl->map);
+ kfree(mfrpl->ibfrpl.page_list);
kfree(mfrpl);
}
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index f385a24d31d2..20724aee76f4 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1365,7 +1365,7 @@ static void set_fmr_seg(struct mlx4_wqe_fmr_seg *fseg, struct ib_send_wr *wr)
int i;
for (i = 0; i < wr->wr.fast_reg.page_list_len; ++i)
- wr->wr.fast_reg.page_list->page_list[i] =
+ mfrpl->mapped_page_list[i] =
cpu_to_be64(wr->wr.fast_reg.page_list->page_list[i] |
MLX4_MTT_FLAG_PRESENT);
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 7a7a026ba712..c238116400b3 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -25,7 +25,6 @@ struct evdev {
int exist;
int open;
int minor;
- char name[16];
struct input_handle handle;
wait_queue_head_t wait;
struct evdev_client *grab;
@@ -609,7 +608,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
p, compat_mode);
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
- return str_to_user(dev->name, _IOC_SIZE(cmd), p);
+ return str_to_user(dev_name(&evdev->dev),
+ _IOC_SIZE(cmd), p);
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
return str_to_user(dev->phys, _IOC_SIZE(cmd), p);
@@ -807,16 +807,15 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
mutex_init(&evdev->mutex);
init_waitqueue_head(&evdev->wait);
- snprintf(evdev->name, sizeof(evdev->name), "event%d", minor);
+ dev_set_name(&evdev->dev, "event%d", minor);
evdev->exist = 1;
evdev->minor = minor;
evdev->handle.dev = input_get_device(dev);
- evdev->handle.name = evdev->name;
+ evdev->handle.name = dev_name(&evdev->dev);
evdev->handle.handler = handler;
evdev->handle.private = evdev;
- dev_set_name(&evdev->dev, evdev->name);
evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
evdev->dev.class = &input_class;
evdev->dev.parent = &dev->dev;
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
index bc4e40f3ede7..2d1415e16834 100644
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -226,7 +226,7 @@ static int get_compatible_type(struct ff_device *ff, int effect_type)
*/
static void ml_combine_effects(struct ff_effect *effect,
struct ml_effect_state *state,
- int gain)
+ unsigned int gain)
{
struct ff_effect *new = state->effect;
unsigned int strong, weak, i;
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c
index 1dec00e20dbc..8a1810f88b9e 100644
--- a/drivers/input/gameport/fm801-gp.c
+++ b/drivers/input/gameport/fm801-gp.c
@@ -167,5 +167,6 @@ module_exit(fm801_gp_exit);
MODULE_DEVICE_TABLE(pci, fm801_gp_id_table);
+MODULE_DESCRIPTION("FM801 gameport driver");
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 2d175b5928ff..ac11be08585e 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -30,16 +30,6 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Generic gameport layer");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(__gameport_register_port);
-EXPORT_SYMBOL(gameport_unregister_port);
-EXPORT_SYMBOL(__gameport_register_driver);
-EXPORT_SYMBOL(gameport_unregister_driver);
-EXPORT_SYMBOL(gameport_open);
-EXPORT_SYMBOL(gameport_close);
-EXPORT_SYMBOL(gameport_set_phys);
-EXPORT_SYMBOL(gameport_start_polling);
-EXPORT_SYMBOL(gameport_stop_polling);
-
/*
* gameport_mutex protects entire gameport subsystem and is taken
* every time gameport port or driver registrered or unregistered.
@@ -162,6 +152,7 @@ void gameport_start_polling(struct gameport *gameport)
spin_unlock(&gameport->timer_lock);
}
+EXPORT_SYMBOL(gameport_start_polling);
void gameport_stop_polling(struct gameport *gameport)
{
@@ -172,6 +163,7 @@ void gameport_stop_polling(struct gameport *gameport)
spin_unlock(&gameport->timer_lock);
}
+EXPORT_SYMBOL(gameport_stop_polling);
static void gameport_run_poll_handler(unsigned long d)
{
@@ -516,6 +508,7 @@ void gameport_set_phys(struct gameport *gameport, const char *fmt, ...)
vsnprintf(gameport->phys, sizeof(gameport->phys), fmt, args);
va_end(args);
}
+EXPORT_SYMBOL(gameport_set_phys);
/*
* Prepare gameport port for registration.
@@ -658,6 +651,7 @@ void __gameport_register_port(struct gameport *gameport, struct module *owner)
gameport_init_port(gameport);
gameport_queue_event(gameport, owner, GAMEPORT_REGISTER_PORT);
}
+EXPORT_SYMBOL(__gameport_register_port);
/*
* Synchronously unregisters gameport port.
@@ -669,6 +663,7 @@ void gameport_unregister_port(struct gameport *gameport)
gameport_destroy_port(gameport);
mutex_unlock(&gameport_mutex);
}
+EXPORT_SYMBOL(gameport_unregister_port);
/*
@@ -728,7 +723,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner
* Temporarily disable automatic binding because probing
* takes long time and we are better off doing it in kgameportd
*/
- drv->ignore = 1;
+ drv->ignore = true;
error = driver_register(&drv->driver);
if (error) {
@@ -741,7 +736,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner
/*
* Reset ignore flag and let kgameportd bind the driver to free ports
*/
- drv->ignore = 0;
+ drv->ignore = false;
error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER);
if (error) {
driver_unregister(&drv->driver);
@@ -750,6 +745,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner
return 0;
}
+EXPORT_SYMBOL(__gameport_register_driver);
void gameport_unregister_driver(struct gameport_driver *drv)
{
@@ -757,7 +753,7 @@ void gameport_unregister_driver(struct gameport_driver *drv)
mutex_lock(&gameport_mutex);
- drv->ignore = 1; /* so gameport_find_driver ignores it */
+ drv->ignore = true; /* so gameport_find_driver ignores it */
gameport_remove_pending_events(drv);
start_over:
@@ -774,6 +770,7 @@ start_over:
mutex_unlock(&gameport_mutex);
}
+EXPORT_SYMBOL(gameport_unregister_driver);
static int gameport_bus_match(struct device *dev, struct device_driver *drv)
{
@@ -812,6 +809,7 @@ int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mo
gameport_set_drv(gameport, drv);
return 0;
}
+EXPORT_SYMBOL(gameport_open);
void gameport_close(struct gameport *gameport)
{
@@ -822,6 +820,7 @@ void gameport_close(struct gameport *gameport)
if (gameport->close)
gameport->close(gameport);
}
+EXPORT_SYMBOL(gameport_close);
static int __init gameport_init(void)
{
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 4224f0112849..0e12f89276a3 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -39,7 +39,6 @@ struct joydev {
int exist;
int open;
int minor;
- char name[16];
struct input_handle handle;
wait_queue_head_t wait;
struct list_head client_list;
@@ -537,12 +536,14 @@ static int joydev_ioctl_common(struct joydev *joydev,
default:
if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) {
int len;
- if (!dev->name)
+ const char *name = dev_name(&dev->dev);
+
+ if (!name)
return 0;
- len = strlen(dev->name) + 1;
+ len = strlen(name) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
- if (copy_to_user(argp, dev->name, len))
+ if (copy_to_user(argp, name, len))
return -EFAULT;
return len;
}
@@ -742,13 +743,13 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
mutex_init(&joydev->mutex);
init_waitqueue_head(&joydev->wait);
- snprintf(joydev->name, sizeof(joydev->name), "js%d", minor);
+ dev_set_name(&joydev->dev, "js%d", minor);
joydev->exist = 1;
joydev->minor = minor;
joydev->exist = 1;
joydev->handle.dev = input_get_device(dev);
- joydev->handle.name = joydev->name;
+ joydev->handle.name = dev_name(&joydev->dev);
joydev->handle.handler = handler;
joydev->handle.private = joydev;
@@ -797,7 +798,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
}
}
- dev_set_name(&joydev->dev, joydev->name);
joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
joydev->dev.class = &input_class;
joydev->dev.parent = &dev->dev;
@@ -843,7 +843,13 @@ static const struct input_device_id joydev_blacklist[] = {
INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT_MASK(EV_KEY) },
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
- }, /* Avoid itouchpads, touchscreens and tablets */
+ }, /* Avoid itouchpads and touchscreens */
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .evbit = { BIT_MASK(EV_KEY) },
+ .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
+ }, /* Avoid tablets, digitisers and similar devices */
{ } /* Terminating entry */
};
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index ea2638b41982..54775aaa7be7 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -332,4 +332,14 @@ config KEYBOARD_SH_KEYSC
To compile this driver as a module, choose M here: the
module will be called sh_keysc.
++
+config KEYBOARD_EP93XX
+ tristate "EP93xx Matrix Keypad support"
+ depends on ARCH_EP93XX
+ help
+ Say Y here to enable the matrix keypad on the Cirrus EP93XX.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ep93xx_keypad.
+
endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 36351e1190f9..13ba9c954938 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
+obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 444dec07e5d8..df3f8aa68115 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -895,6 +895,13 @@ static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {
};
/*
+ * Amilo Xi 3650 key release for light touch bar not working
+ */
+static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = {
+ 0x67, 0xed, 0x90, 0xa2, 0x99, 0xa4, 0xae, 0xb0, -1U
+};
+
+/*
* atkbd_set_keycode_table() initializes keyboard's keycode table
* according to the selected scancode set
*/
@@ -1560,6 +1567,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
.callback = atkbd_setup_forced_release,
.driver_data = atkbd_amilo_pa1510_forced_release_keys,
},
+ {
+ .ident = "Fujitsu Amilo Xi 3650",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"),
+ },
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_amilo_xi3650_forced_release_keys,
+ },
{ }
};
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c
new file mode 100644
index 000000000000..181d30e3018e
--- /dev/null
+++ b/drivers/input/keyboard/ep93xx_keypad.c
@@ -0,0 +1,470 @@
+/*
+ * Driver for the Cirrus EP93xx matrix keypad controller.
+ *
+ * Copyright (c) 2008 H Hartley Sweeten <hsweeten@visionengravers.com>
+ *
+ * Based on the pxa27x matrix keypad controller by Rodolfo Giometti.
+ *
+ * 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.
+ *
+ * NOTE:
+ *
+ * The 3-key reset is triggered by pressing the 3 keys in
+ * Row 0, Columns 2, 4, and 7 at the same time. This action can
+ * be disabled by setting the EP93XX_KEYPAD_DISABLE_3_KEY flag.
+ *
+ * Normal operation for the matrix does not autorepeat the key press.
+ * This action can be enabled by setting the EP93XX_KEYPAD_AUTOREPEAT
+ * flag.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/ep93xx_keypad.h>
+
+/*
+ * Keypad Interface Register offsets
+ */
+#define KEY_INIT 0x00 /* Key Scan Initialization register */
+#define KEY_DIAG 0x04 /* Key Scan Diagnostic register */
+#define KEY_REG 0x08 /* Key Value Capture register */
+
+/* Key Scan Initialization Register bit defines */
+#define KEY_INIT_DBNC_MASK (0x00ff0000)
+#define KEY_INIT_DBNC_SHIFT (16)
+#define KEY_INIT_DIS3KY (1<<15)
+#define KEY_INIT_DIAG (1<<14)
+#define KEY_INIT_BACK (1<<13)
+#define KEY_INIT_T2 (1<<12)
+#define KEY_INIT_PRSCL_MASK (0x000003ff)
+#define KEY_INIT_PRSCL_SHIFT (0)
+
+/* Key Scan Diagnostic Register bit defines */
+#define KEY_DIAG_MASK (0x0000003f)
+#define KEY_DIAG_SHIFT (0)
+
+/* Key Value Capture Register bit defines */
+#define KEY_REG_K (1<<15)
+#define KEY_REG_INT (1<<14)
+#define KEY_REG_2KEYS (1<<13)
+#define KEY_REG_1KEY (1<<12)
+#define KEY_REG_KEY2_MASK (0x00000fc0)
+#define KEY_REG_KEY2_SHIFT (6)
+#define KEY_REG_KEY1_MASK (0x0000003f)
+#define KEY_REG_KEY1_SHIFT (0)
+
+#define keypad_readl(off) __raw_readl(keypad->mmio_base + (off))
+#define keypad_writel(v, off) __raw_writel((v), keypad->mmio_base + (off))
+
+#define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS)
+
+struct ep93xx_keypad {
+ struct ep93xx_keypad_platform_data *pdata;
+
+ struct clk *clk;
+ struct input_dev *input_dev;
+ void __iomem *mmio_base;
+
+ int irq;
+ int enabled;
+
+ int key1;
+ int key2;
+
+ unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM];
+};
+
+static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad)
+{
+ struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
+ struct input_dev *input_dev = keypad->input_dev;
+ int i;
+
+ for (i = 0; i < pdata->matrix_key_map_size; i++) {
+ unsigned int key = pdata->matrix_key_map[i];
+ int row = (key >> 28) & 0xf;
+ int col = (key >> 24) & 0xf;
+ int code = key & 0xffffff;
+
+ keypad->matrix_keycodes[(row << 3) + col] = code;
+ __set_bit(code, input_dev->keybit);
+ }
+}
+
+static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id)
+{
+ struct ep93xx_keypad *keypad = dev_id;
+ struct input_dev *input_dev = keypad->input_dev;
+ unsigned int status = keypad_readl(KEY_REG);
+ int keycode, key1, key2;
+
+ keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT;
+ key1 = keypad->matrix_keycodes[keycode];
+
+ keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT;
+ key2 = keypad->matrix_keycodes[keycode];
+
+ if (status & KEY_REG_2KEYS) {
+ if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1)
+ input_report_key(input_dev, keypad->key1, 0);
+
+ if (keypad->key2 && key1 != keypad->key2 && key2 != keypad->key2)
+ input_report_key(input_dev, keypad->key2, 0);
+
+ input_report_key(input_dev, key1, 1);
+ input_report_key(input_dev, key2, 1);
+
+ keypad->key1 = key1;
+ keypad->key2 = key2;
+
+ } else if (status & KEY_REG_1KEY) {
+ if (keypad->key1 && key1 != keypad->key1)
+ input_report_key(input_dev, keypad->key1, 0);
+
+ if (keypad->key2 && key1 != keypad->key2)
+ input_report_key(input_dev, keypad->key2, 0);
+
+ input_report_key(input_dev, key1, 1);
+
+ keypad->key1 = key1;
+ keypad->key2 = 0;
+
+ } else {
+ input_report_key(input_dev, keypad->key1, 0);
+ input_report_key(input_dev, keypad->key2, 0);
+
+ keypad->key1 = keypad->key2 = 0;
+ }
+ input_sync(input_dev);
+
+ return IRQ_HANDLED;
+}
+
+static void ep93xx_keypad_config(struct ep93xx_keypad *keypad)
+{
+ struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
+ unsigned int val = 0;
+
+ clk_set_rate(keypad->clk, pdata->flags & EP93XX_KEYPAD_KDIV);
+
+ if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY)
+ val |= KEY_INIT_DIS3KY;
+ if (pdata->flags & EP93XX_KEYPAD_DIAG_MODE)
+ val |= KEY_INIT_DIAG;
+ if (pdata->flags & EP93XX_KEYPAD_BACK_DRIVE)
+ val |= KEY_INIT_BACK;
+ if (pdata->flags & EP93XX_KEYPAD_TEST_MODE)
+ val |= KEY_INIT_T2;
+
+ val |= ((pdata->debounce << KEY_INIT_DBNC_SHIFT) & KEY_INIT_DBNC_MASK);
+
+ val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK);
+
+ keypad_writel(val, KEY_INIT);
+}
+
+static int ep93xx_keypad_open(struct input_dev *pdev)
+{
+ struct ep93xx_keypad *keypad = input_get_drvdata(pdev);
+
+ if (!keypad->enabled) {
+ ep93xx_keypad_config(keypad);
+ clk_enable(keypad->clk);
+ keypad->enabled = 1;
+ }
+
+ return 0;
+}
+
+static void ep93xx_keypad_close(struct input_dev *pdev)
+{
+ struct ep93xx_keypad *keypad = input_get_drvdata(pdev);
+
+ if (keypad->enabled) {
+ clk_disable(keypad->clk);
+ keypad->enabled = 0;
+ }
+}
+
+
+#ifdef CONFIG_PM
+/*
+ * NOTE: I don't know if this is correct, or will work on the ep93xx.
+ *
+ * None of the existing ep93xx drivers have power management support.
+ * But, this is basically what the pxa27x_keypad driver does.
+ */
+static int ep93xx_keypad_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
+ struct input_dev *input_dev = keypad->input_dev;
+
+ mutex_lock(&input_dev->mutex);
+
+ if (keypad->enabled) {
+ clk_disable(keypad->clk);
+ keypad->enabled = 0;
+ }
+
+ mutex_unlock(&input_dev->mutex);
+
+ if (device_may_wakeup(&pdev->dev))
+ enable_irq_wake(keypad->irq);
+
+ return 0;
+}
+
+static int ep93xx_keypad_resume(struct platform_device *pdev)
+{
+ struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
+ struct input_dev *input_dev = keypad->input_dev;
+
+ if (device_may_wakeup(&pdev->dev))
+ disable_irq_wake(keypad->irq);
+
+ mutex_lock(&input_dev->mutex);
+
+ if (input_dev->users) {
+ if (!keypad->enabled) {
+ ep93xx_keypad_config(keypad);
+ clk_enable(keypad->clk);
+ keypad->enabled = 1;
+ }
+ }
+
+ mutex_unlock(&input_dev->mutex);
+
+ return 0;
+}
+#else /* !CONFIG_PM */
+#define ep93xx_keypad_suspend NULL
+#define ep93xx_keypad_resume NULL
+#endif /* !CONFIG_PM */
+
+static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
+{
+ struct ep93xx_keypad *keypad;
+ struct ep93xx_keypad_platform_data *pdata = pdev->dev.platform_data;
+ struct input_dev *input_dev;
+ struct resource *res;
+ int irq, err, i, gpio;
+
+ if (!pdata ||
+ !pdata->matrix_key_rows ||
+ pdata->matrix_key_rows > MAX_MATRIX_KEY_ROWS ||
+ !pdata->matrix_key_cols ||
+ pdata->matrix_key_cols > MAX_MATRIX_KEY_COLS) {
+ dev_err(&pdev->dev, "invalid or missing platform data\n");
+ return -EINVAL;
+ }
+
+ keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL);
+ if (!keypad) {
+ dev_err(&pdev->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ keypad->pdata = pdata;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "failed to get keypad irq\n");
+ err = -ENXIO;
+ goto failed_free;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get I/O memory\n");
+ err = -ENXIO;
+ goto failed_free;
+ }
+
+ res = request_mem_region(res->start, resource_size(res), pdev->name);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to request I/O memory\n");
+ err = -EBUSY;
+ goto failed_free;
+ }
+
+ keypad->mmio_base = ioremap(res->start, resource_size(res));
+ if (keypad->mmio_base == NULL) {
+ dev_err(&pdev->dev, "failed to remap I/O memory\n");
+ err = -ENXIO;
+ goto failed_free_mem;
+ }
+
+ /* Request the needed GPIO's */
+ gpio = EP93XX_GPIO_LINE_ROW0;
+ for (i = 0; i < keypad->pdata->matrix_key_rows; i++, gpio++) {
+ err = gpio_request(gpio, pdev->name);
+ if (err) {
+ dev_err(&pdev->dev, "failed to request gpio-%d\n",
+ gpio);
+ goto failed_free_rows;
+ }
+ }
+
+ gpio = EP93XX_GPIO_LINE_COL0;
+ for (i = 0; i < keypad->pdata->matrix_key_cols; i++, gpio++) {
+ err = gpio_request(gpio, pdev->name);
+ if (err) {
+ dev_err(&pdev->dev, "failed to request gpio-%d\n",
+ gpio);
+ goto failed_free_cols;
+ }
+ }
+
+ keypad->clk = clk_get(&pdev->dev, "key_clk");
+ if (IS_ERR(keypad->clk)) {
+ dev_err(&pdev->dev, "failed to get keypad clock\n");
+ err = PTR_ERR(keypad->clk);
+ goto failed_free_io;
+ }
+
+ /* Create and register the input driver */
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ dev_err(&pdev->dev, "failed to allocate input device\n");
+ err = -ENOMEM;
+ goto failed_put_clk;
+ }
+
+ keypad->input_dev = input_dev;
+
+ input_dev->name = pdev->name;
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->open = ep93xx_keypad_open;
+ input_dev->close = ep93xx_keypad_close;
+ input_dev->dev.parent = &pdev->dev;
+ input_dev->keycode = keypad->matrix_keycodes;
+ input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]);
+ input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes);
+
+ input_set_drvdata(input_dev, keypad);
+
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
+ if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT)
+ input_dev->evbit[0] |= BIT_MASK(EV_REP);
+
+ ep93xx_keypad_build_keycode(keypad);
+ platform_set_drvdata(pdev, keypad);
+
+ err = request_irq(irq, ep93xx_keypad_irq_handler, IRQF_DISABLED,
+ pdev->name, keypad);
+ if (err) {
+ dev_err(&pdev->dev, "failed to request IRQ\n");
+ goto failed_free_dev;
+ }
+
+ keypad->irq = irq;
+
+ /* Register the input device */
+ err = input_register_device(input_dev);
+ if (err) {
+ dev_err(&pdev->dev, "failed to register input device\n");
+ goto failed_free_irq;
+ }
+
+ device_init_wakeup(&pdev->dev, 1);
+
+ return 0;
+
+failed_free_irq:
+ free_irq(irq, pdev);
+ platform_set_drvdata(pdev, NULL);
+failed_free_dev:
+ input_free_device(input_dev);
+failed_put_clk:
+ clk_put(keypad->clk);
+failed_free_io:
+ i = keypad->pdata->matrix_key_cols - 1;
+ gpio = EP93XX_GPIO_LINE_COL0 + i;
+failed_free_cols:
+ for ( ; i >= 0; i--, gpio--)
+ gpio_free(gpio);
+ i = keypad->pdata->matrix_key_rows - 1;
+ gpio = EP93XX_GPIO_LINE_ROW0 + i;
+failed_free_rows:
+ for ( ; i >= 0; i--, gpio--)
+ gpio_free(gpio);
+ iounmap(keypad->mmio_base);
+failed_free_mem:
+ release_mem_region(res->start, resource_size(res));
+failed_free:
+ kfree(keypad);
+ return err;
+}
+
+static int __devexit ep93xx_keypad_remove(struct platform_device *pdev)
+{
+ struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
+ struct resource *res;
+ int i, gpio;
+
+ free_irq(keypad->irq, pdev);
+
+ platform_set_drvdata(pdev, NULL);
+
+ if (keypad->enabled)
+ clk_disable(keypad->clk);
+ clk_put(keypad->clk);
+
+ input_unregister_device(keypad->input_dev);
+
+ i = keypad->pdata->matrix_key_cols - 1;
+ gpio = EP93XX_GPIO_LINE_COL0 + i;
+ for ( ; i >= 0; i--, gpio--)
+ gpio_free(gpio);
+
+ i = keypad->pdata->matrix_key_rows - 1;
+ gpio = EP93XX_GPIO_LINE_ROW0 + i;
+ for ( ; i >= 0; i--, gpio--)
+ gpio_free(gpio);
+
+ iounmap(keypad->mmio_base);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+
+ kfree(keypad);
+
+ return 0;
+}
+
+static struct platform_driver ep93xx_keypad_driver = {
+ .driver = {
+ .name = "ep93xx-keypad",
+ .owner = THIS_MODULE,
+ },
+ .probe = ep93xx_keypad_probe,
+ .remove = __devexit_p(ep93xx_keypad_remove),
+ .suspend = ep93xx_keypad_suspend,
+ .resume = ep93xx_keypad_resume,
+};
+
+static int __init ep93xx_keypad_init(void)
+{
+ return platform_driver_register(&ep93xx_keypad_driver);
+}
+
+static void __exit ep93xx_keypad_exit(void)
+{
+ platform_driver_unregister(&ep93xx_keypad_driver);
+}
+
+module_init(ep93xx_keypad_init);
+module_exit(ep93xx_keypad_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
+MODULE_DESCRIPTION("EP93xx Matrix Keypad Controller");
+MODULE_ALIAS("platform:ep93xx-keypad");
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index ad67d763fdbd..9767213b6c8f 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -142,8 +142,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
}
error = request_irq(irq, gpio_keys_isr,
- IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
button->desc ? button->desc : "gpio_keys",
bdata);
if (error) {
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 5c0a631d1455..4399f54c043c 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -193,6 +193,16 @@ config INPUT_CM109
To compile this driver as a module, choose M here: the module will be
called cm109.
+config INPUT_TWL4030_PWRBUTTON
+ tristate "TWL4030 Power button Driver"
+ depends on TWL4030_CORE
+ help
+ Say Y here if you want to enable power key reporting via the
+ TWL4030 family of chips.
+
+ To compile this driver as a module, choose M here. The module will
+ be called twl4030_pwrbutton.
+
config INPUT_UINPUT
tristate "User level driver support"
help
@@ -250,4 +260,13 @@ config INPUT_RB532_BUTTON
To compile this driver as a module, choose M here: the
module will be called rb532_button.
+config INPUT_DM355EVM
+ tristate "TI DaVinci DM355 EVM Keypad and IR Remote"
+ depends on MFD_DM355EVM_MSP
+ help
+ Supports the pushbuttons and IR remote used with
+ the DM355 EVM board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called dm355evm_keys.
endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index eb3f407baedf..0d979fd4cd57 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
obj-$(CONFIG_INPUT_CM109) += cm109.o
obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
+obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
@@ -21,6 +22,7 @@ obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
+obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c
new file mode 100644
index 000000000000..a63315ce4a6c
--- /dev/null
+++ b/drivers/input/misc/dm355evm_keys.c
@@ -0,0 +1,329 @@
+/*
+ * dm355evm_keys.c - support buttons and IR remote on DM355 EVM board
+ *
+ * Copyright (c) 2008 by David Brownell
+ *
+ * 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/input.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+#include <linux/i2c/dm355evm_msp.h>
+
+
+/*
+ * The MSP430 firmware on the DM355 EVM monitors on-board pushbuttons
+ * and an IR receptor used for the remote control. When any key is
+ * pressed, or its autorepeat kicks in, an event is sent. This driver
+ * read those events from the small (32 event) queue and reports them.
+ *
+ * Because we communicate with the MSP430 using I2C, and all I2C calls
+ * in Linux sleep, we need to cons up a kind of threaded IRQ handler
+ * using a work_struct. The IRQ is active low, but we use it through
+ * the GPIO controller so we can trigger on falling edges.
+ *
+ * Note that physically there can only be one of these devices.
+ *
+ * This driver was tested with firmware revision A4.
+ */
+struct dm355evm_keys {
+ struct work_struct work;
+ struct input_dev *input;
+ struct device *dev;
+ int irq;
+};
+
+static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
+{
+ struct dm355evm_keys *keys = _keys;
+
+ schedule_work(&keys->work);
+ return IRQ_HANDLED;
+}
+
+/* These initial keycodes can be remapped by dm355evm_setkeycode(). */
+static struct {
+ u16 event;
+ u16 keycode;
+} dm355evm_keys[] = {
+
+ /*
+ * Pushbuttons on the EVM board ... note that the labels for these
+ * are SW10/SW11/etc on the PC board. The left/right orientation
+ * comes only from the firmware's documentation, and presumes the
+ * power connector is immediately in front of you and the IR sensor
+ * is to the right. (That is, rotate the board counter-clockwise
+ * by 90 degrees from the SW10/etc and "DM355 EVM" labels.)
+ */
+ { 0x00d8, KEY_OK, }, /* SW12 */
+ { 0x00b8, KEY_UP, }, /* SW13 */
+ { 0x00e8, KEY_DOWN, }, /* SW11 */
+ { 0x0078, KEY_LEFT, }, /* SW14 */
+ { 0x00f0, KEY_RIGHT, }, /* SW10 */
+
+ /*
+ * IR buttons ... codes assigned to match the universal remote
+ * provided with the EVM (Philips PM4S) using DVD code 0020.
+ *
+ * These event codes match firmware documentation, but other
+ * remote controls could easily send more RC5-encoded events.
+ * The PM4S manual was used in several cases to help select
+ * a keycode reflecting the intended usage.
+ *
+ * RC5 codes are 14 bits, with two start bits (0x3 prefix)
+ * and a toggle bit (masked out below).
+ */
+ { 0x300c, KEY_POWER, }, /* NOTE: docs omit this */
+ { 0x3000, KEY_NUMERIC_0, },
+ { 0x3001, KEY_NUMERIC_1, },
+ { 0x3002, KEY_NUMERIC_2, },
+ { 0x3003, KEY_NUMERIC_3, },
+ { 0x3004, KEY_NUMERIC_4, },
+ { 0x3005, KEY_NUMERIC_5, },
+ { 0x3006, KEY_NUMERIC_6, },
+ { 0x3007, KEY_NUMERIC_7, },
+ { 0x3008, KEY_NUMERIC_8, },
+ { 0x3009, KEY_NUMERIC_9, },
+ { 0x3022, KEY_ENTER, },
+ { 0x30ec, KEY_MODE, }, /* "tv/vcr/..." */
+ { 0x300f, KEY_SELECT, }, /* "info" */
+ { 0x3020, KEY_CHANNELUP, }, /* "up" */
+ { 0x302e, KEY_MENU, }, /* "in/out" */
+ { 0x3011, KEY_VOLUMEDOWN, }, /* "left" */
+ { 0x300d, KEY_MUTE, }, /* "ok" */
+ { 0x3010, KEY_VOLUMEUP, }, /* "right" */
+ { 0x301e, KEY_SUBTITLE, }, /* "cc" */
+ { 0x3021, KEY_CHANNELDOWN, }, /* "down" */
+ { 0x3022, KEY_PREVIOUS, },
+ { 0x3026, KEY_SLEEP, },
+ { 0x3172, KEY_REWIND, }, /* NOTE: docs wrongly say 0x30ca */
+ { 0x3175, KEY_PLAY, },
+ { 0x3174, KEY_FASTFORWARD, },
+ { 0x3177, KEY_RECORD, },
+ { 0x3176, KEY_STOP, },
+ { 0x3169, KEY_PAUSE, },
+};
+
+static void dm355evm_keys_work(struct work_struct *work)
+{
+ struct dm355evm_keys *keys;
+ int status;
+
+ keys = container_of(work, struct dm355evm_keys, work);
+
+ /* For simplicity we ignore INPUT_COUNT and just read
+ * events until we get the "queue empty" indicator.
+ * Reading INPUT_LOW decrements the count.
+ */
+ for (;;) {
+ static u16 last_event;
+ u16 event;
+ int keycode;
+ int i;
+
+ status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH);
+ if (status < 0) {
+ dev_dbg(keys->dev, "input high err %d\n",
+ status);
+ break;
+ }
+ event = status << 8;
+
+ status = dm355evm_msp_read(DM355EVM_MSP_INPUT_LOW);
+ if (status < 0) {
+ dev_dbg(keys->dev, "input low err %d\n",
+ status);
+ break;
+ }
+ event |= status;
+ if (event == 0xdead)
+ break;
+
+ /* Press and release a button: two events, same code.
+ * Press and hold (autorepeat), then release: N events
+ * (N > 2), same code. For RC5 buttons the toggle bits
+ * distinguish (for example) "1-autorepeat" from "1 1";
+ * but PCB buttons don't support that bit.
+ *
+ * So we must synthesize release events. We do that by
+ * mapping events to a press/release event pair; then
+ * to avoid adding extra events, skip the second event
+ * of each pair.
+ */
+ if (event == last_event) {
+ last_event = 0;
+ continue;
+ }
+ last_event = event;
+
+ /* ignore the RC5 toggle bit */
+ event &= ~0x0800;
+
+ /* find the key, or leave it as unknown */
+ keycode = KEY_UNKNOWN;
+ for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) {
+ if (dm355evm_keys[i].event != event)
+ continue;
+ keycode = dm355evm_keys[i].keycode;
+ break;
+ }
+ dev_dbg(keys->dev,
+ "input event 0x%04x--> keycode %d\n",
+ event, keycode);
+
+ /* report press + release */
+ input_report_key(keys->input, keycode, 1);
+ input_sync(keys->input);
+ input_report_key(keys->input, keycode, 0);
+ input_sync(keys->input);
+ }
+}
+
+static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode)
+{
+ u16 old_keycode;
+ unsigned i;
+
+ if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys))
+ return -EINVAL;
+
+ old_keycode = dm355evm_keys[index].keycode;
+ dm355evm_keys[index].keycode = keycode;
+ set_bit(keycode, dev->keybit);
+
+ for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) {
+ if (dm355evm_keys[index].keycode == old_keycode)
+ goto done;
+ }
+ clear_bit(old_keycode, dev->keybit);
+done:
+ return 0;
+}
+
+static int dm355evm_getkeycode(struct input_dev *dev, int index, int *keycode)
+{
+ if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys))
+ return -EINVAL;
+
+ return dm355evm_keys[index].keycode;
+}
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
+{
+ struct dm355evm_keys *keys;
+ struct input_dev *input;
+ int status;
+ int i;
+
+ /* allocate instance struct and input dev */
+ keys = kzalloc(sizeof *keys, GFP_KERNEL);
+ input = input_allocate_device();
+ if (!keys || !input) {
+ status = -ENOMEM;
+ goto fail1;
+ }
+
+ keys->dev = &pdev->dev;
+ keys->input = input;
+ INIT_WORK(&keys->work, dm355evm_keys_work);
+
+ /* set up "threaded IRQ handler" */
+ status = platform_get_irq(pdev, 0);
+ if (status < 0)
+ goto fail1;
+ keys->irq = status;
+
+ input_set_drvdata(input, keys);
+
+ input->name = "DM355 EVM Controls";
+ input->phys = "dm355evm/input0";
+ input->dev.parent = &pdev->dev;
+
+ input->id.bustype = BUS_I2C;
+ input->id.product = 0x0355;
+ input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV);
+
+ input->evbit[0] = BIT(EV_KEY);
+ for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++)
+ __set_bit(dm355evm_keys[i].keycode, input->keybit);
+
+ input->setkeycode = dm355evm_setkeycode;
+ input->getkeycode = dm355evm_getkeycode;
+
+ /* REVISIT: flush the event queue? */
+
+ status = request_irq(keys->irq, dm355evm_keys_irq,
+ IRQF_TRIGGER_FALLING,
+ dev_name(&pdev->dev), keys);
+ if (status < 0)
+ goto fail1;
+
+ /* register */
+ status = input_register_device(input);
+ if (status < 0)
+ goto fail2;
+
+ platform_set_drvdata(pdev, keys);
+
+ return 0;
+
+fail2:
+ free_irq(keys->irq, keys);
+fail1:
+ input_free_device(input);
+ kfree(keys);
+ dev_err(&pdev->dev, "can't register, err %d\n", status);
+
+ return status;
+}
+
+static int __devexit dm355evm_keys_remove(struct platform_device *pdev)
+{
+ struct dm355evm_keys *keys = platform_get_drvdata(pdev);
+
+ free_irq(keys->irq, keys);
+ input_unregister_device(keys->input);
+ kfree(keys);
+
+ return 0;
+}
+
+/* REVISIT: add suspend/resume when DaVinci supports it. The IRQ should
+ * be able to wake up the system. When device_may_wakeup(&pdev->dev), call
+ * enable_irq_wake() on suspend, and disable_irq_wake() on resume.
+ */
+
+/*
+ * I2C is used to talk to the MSP430, but this platform device is
+ * exposed by an MFD driver that manages I2C communications.
+ */
+static struct platform_driver dm355evm_keys_driver = {
+ .probe = dm355evm_keys_probe,
+ .remove = __devexit_p(dm355evm_keys_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "dm355evm_keys",
+ },
+};
+
+static int __init dm355evm_keys_init(void)
+{
+ return platform_driver_register(&dm355evm_keys_driver);
+}
+module_init(dm355evm_keys_init);
+
+static void __exit dm355evm_keys_exit(void)
+{
+ platform_driver_unregister(&dm355evm_keys_driver);
+}
+module_exit(dm355evm_keys_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index 5bb3ab51b8c6..c806fbf1e174 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -26,13 +26,17 @@
#define DRV_NAME "rotary-encoder"
struct rotary_encoder {
- unsigned int irq_a;
- unsigned int irq_b;
- unsigned int pos;
- unsigned int armed;
- unsigned int dir;
struct input_dev *input;
struct rotary_encoder_platform_data *pdata;
+
+ unsigned int axis;
+ unsigned int pos;
+
+ unsigned int irq_a;
+ unsigned int irq_b;
+
+ bool armed;
+ unsigned char dir; /* 0 - clockwise, 1 - CCW */
};
static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
@@ -53,21 +57,32 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
if (!encoder->armed)
break;
- if (encoder->dir) {
- /* turning counter-clockwise */
- encoder->pos += pdata->steps;
- encoder->pos--;
- encoder->pos %= pdata->steps;
+ if (pdata->relative_axis) {
+ input_report_rel(encoder->input, pdata->axis,
+ encoder->dir ? -1 : 1);
} else {
- /* turning clockwise */
- encoder->pos++;
- encoder->pos %= pdata->steps;
+ unsigned int pos = encoder->pos;
+
+ if (encoder->dir) {
+ /* turning counter-clockwise */
+ if (pdata->rollover)
+ pos += pdata->steps;
+ if (pos)
+ pos--;
+ } else {
+ /* turning clockwise */
+ if (pdata->rollover || pos < pdata->steps)
+ pos++;
+ }
+ if (pdata->rollover)
+ pos %= pdata->steps;
+ encoder->pos = pos;
+ input_report_abs(encoder->input, pdata->axis,
+ encoder->pos);
}
-
- input_report_abs(encoder->input, pdata->axis, encoder->pos);
input_sync(encoder->input);
- encoder->armed = 0;
+ encoder->armed = false;
break;
case 0x1:
@@ -77,7 +92,7 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
break;
case 0x3:
- encoder->armed = 1;
+ encoder->armed = true;
break;
}
@@ -113,9 +128,15 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
input->name = pdev->name;
input->id.bustype = BUS_HOST;
input->dev.parent = &pdev->dev;
- input->evbit[0] = BIT_MASK(EV_ABS);
- input_set_abs_params(encoder->input,
- pdata->axis, 0, pdata->steps, 0, 1);
+
+ if (pdata->relative_axis) {
+ input->evbit[0] = BIT_MASK(EV_REL);
+ input->relbit[0] = BIT_MASK(pdata->axis);
+ } else {
+ input->evbit[0] = BIT_MASK(EV_ABS);
+ input_set_abs_params(encoder->input,
+ pdata->axis, 0, pdata->steps, 0, 1);
+ }
err = input_register_device(input);
if (err) {
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c
new file mode 100644
index 000000000000..f5fc9974a111
--- /dev/null
+++ b/drivers/input/misc/twl4030-pwrbutton.c
@@ -0,0 +1,145 @@
+/**
+ * twl4030-pwrbutton.c - TWL4030 Power Button Input Driver
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Peter De Schrijver <peter.de-schrijver@nokia.com>
+ * Several fixes by Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * 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.
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/i2c/twl4030.h>
+
+#define PWR_PWRON_IRQ (1 << 0)
+
+#define STS_HW_CONDITIONS 0xf
+
+static irqreturn_t powerbutton_irq(int irq, void *_pwr)
+{
+ struct input_dev *pwr = _pwr;
+ int err;
+ u8 value;
+
+#ifdef CONFIG_LOCKDEP
+ /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
+ * we don't want and can't tolerate since this is a threaded
+ * IRQ and can sleep due to the i2c reads it has to issue.
+ * Although it might be friendlier not to borrow this thread
+ * context...
+ */
+ local_irq_enable();
+#endif
+
+ err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value,
+ STS_HW_CONDITIONS);
+ if (!err) {
+ input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ);
+ input_sync(pwr);
+ } else {
+ dev_err(pwr->dev.parent, "twl4030: i2c error %d while reading"
+ " TWL4030 PM_MASTER STS_HW_CONDITIONS register\n", err);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit twl4030_pwrbutton_probe(struct platform_device *pdev)
+{
+ struct input_dev *pwr;
+ int irq = platform_get_irq(pdev, 0);
+ int err;
+
+ pwr = input_allocate_device();
+ if (!pwr) {
+ dev_dbg(&pdev->dev, "Can't allocate power button\n");
+ return -ENOMEM;
+ }
+
+ pwr->evbit[0] = BIT_MASK(EV_KEY);
+ pwr->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
+ pwr->name = "twl4030_pwrbutton";
+ pwr->phys = "twl4030_pwrbutton/input0";
+ pwr->dev.parent = &pdev->dev;
+
+ err = request_irq(irq, powerbutton_irq,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "twl4030_pwrbutton", pwr);
+ if (err < 0) {
+ dev_dbg(&pdev->dev, "Can't get IRQ for pwrbutton: %d\n", err);
+ goto free_input_dev;
+ }
+
+ err = input_register_device(pwr);
+ if (err) {
+ dev_dbg(&pdev->dev, "Can't register power button: %d\n", err);
+ goto free_irq;
+ }
+
+ platform_set_drvdata(pdev, pwr);
+
+ return 0;
+
+free_irq:
+ free_irq(irq, NULL);
+free_input_dev:
+ input_free_device(pwr);
+ return err;
+}
+
+static int __devexit twl4030_pwrbutton_remove(struct platform_device *pdev)
+{
+ struct input_dev *pwr = platform_get_drvdata(pdev);
+ int irq = platform_get_irq(pdev, 0);
+
+ free_irq(irq, pwr);
+ input_unregister_device(pwr);
+
+ return 0;
+}
+
+struct platform_driver twl4030_pwrbutton_driver = {
+ .probe = twl4030_pwrbutton_probe,
+ .remove = __devexit_p(twl4030_pwrbutton_remove),
+ .driver = {
+ .name = "twl4030_pwrbutton",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init twl4030_pwrbutton_init(void)
+{
+ return platform_driver_register(&twl4030_pwrbutton_driver);
+}
+module_init(twl4030_pwrbutton_init);
+
+static void __exit twl4030_pwrbutton_exit(void)
+{
+ platform_driver_unregister(&twl4030_pwrbutton_driver);
+}
+module_exit(twl4030_pwrbutton_exit);
+
+MODULE_ALIAS("platform:twl4030_pwrbutton");
+MODULE_DESCRIPTION("Triton2 Power Button");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Peter De Schrijver <peter.de-schrijver@nokia.com>");
+MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
+
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index daecc75c72e6..cd4203c4deb9 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -38,25 +38,25 @@
static const struct alps_model_info alps_model_data[] = {
{ { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
- { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */
+ { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */
{ { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
{ { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
- { { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 }, /* HP ze1115 */
+ { { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 }, /* HP ze1115 */
{ { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
{ { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
- { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
- { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
- { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
+ { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
+ { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
+ { { 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 */
+ { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* 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 */
+ { { 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 */
{ { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */
- { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */
+ { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 }, /* Dell Vostro 1400 */
};
/*
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 15ac3205ac05..dcd4236af1e3 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -159,21 +159,22 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
if (!dev2)
printk(KERN_WARNING "lifebook.c: got relative packet "
"but no relative device set up\n");
- } else if (lifebook_use_6byte_proto) {
- input_report_abs(dev1, ABS_X,
- ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f));
- input_report_abs(dev1, ABS_Y,
- 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f)));
} else {
- input_report_abs(dev1, ABS_X,
- (packet[1] | ((packet[0] & 0x30) << 4)));
- input_report_abs(dev1, ABS_Y,
- 1024 - (packet[2] | ((packet[0] & 0xC0) << 2)));
+ if (lifebook_use_6byte_proto) {
+ input_report_abs(dev1, ABS_X,
+ ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f));
+ input_report_abs(dev1, ABS_Y,
+ 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f)));
+ } else {
+ input_report_abs(dev1, ABS_X,
+ (packet[1] | ((packet[0] & 0x30) << 4)));
+ input_report_abs(dev1, ABS_Y,
+ 1024 - (packet[2] | ((packet[0] & 0xC0) << 2)));
+ }
+ input_report_key(dev1, BTN_TOUCH, packet[0] & 0x04);
+ input_sync(dev1);
}
- input_report_key(dev1, BTN_TOUCH, packet[0] & 0x04);
- input_sync(dev1);
-
if (dev2) {
if (relative_packet) {
input_report_rel(dev2, REL_X,
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 17fd6d46d082..966b8868f792 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -60,7 +60,6 @@ struct mousedev {
int exist;
int open;
int minor;
- char name[16];
struct input_handle handle;
wait_queue_head_t wait;
struct list_head client_list;
@@ -863,19 +862,17 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
init_waitqueue_head(&mousedev->wait);
if (minor == MOUSEDEV_MIX)
- strlcpy(mousedev->name, "mice", sizeof(mousedev->name));
+ dev_set_name(&mousedev->dev, "mice");
else
- snprintf(mousedev->name, sizeof(mousedev->name),
- "mouse%d", minor);
+ dev_set_name(&mousedev->dev, "mouse%d", minor);
mousedev->minor = minor;
mousedev->exist = 1;
mousedev->handle.dev = input_get_device(dev);
- mousedev->handle.name = mousedev->name;
+ mousedev->handle.name = dev_name(&mousedev->dev);
mousedev->handle.handler = handler;
mousedev->handle.private = mousedev;
- dev_set_name(&mousedev->dev, mousedev->name);
mousedev->dev.class = &input_class;
if (dev)
mousedev->dev.parent = &dev->dev;
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 3cffb704e374..f919bf57293c 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -10,6 +10,7 @@
* the Free Software Foundation.
*/
+#include <linux/types.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
@@ -921,6 +922,9 @@ static void i8042_dritek_enable(void)
#endif
#ifdef CONFIG_PM
+
+static bool i8042_suspended;
+
/*
* Here we try to restore the original BIOS settings. We only want to
* do that once, when we really suspend, not when we taking memory
@@ -930,11 +934,9 @@ static void i8042_dritek_enable(void)
static int i8042_suspend(struct platform_device *dev, pm_message_t state)
{
- if (dev->dev.power.power_state.event != state.event) {
- if (state.event == PM_EVENT_SUSPEND)
- i8042_controller_reset();
-
- dev->dev.power.power_state = state;
+ if (!i8042_suspended && state.event == PM_EVENT_SUSPEND) {
+ i8042_controller_reset();
+ i8042_suspended = true;
}
return 0;
@@ -952,7 +954,7 @@ static int i8042_resume(struct platform_device *dev)
/*
* Do not bother with restoring state if we haven't suspened yet
*/
- if (dev->dev.power.power_state.event == PM_EVENT_ON)
+ if (!i8042_suspended)
return 0;
error = i8042_controller_check();
@@ -998,10 +1000,9 @@ static int i8042_resume(struct platform_device *dev)
if (i8042_ports[I8042_KBD_PORT_NO].serio)
i8042_enable_kbd_port();
+ i8042_suspended = false;
i8042_interrupt(0, NULL);
- dev->dev.power.power_state = PMSG_ON;
-
return 0;
}
#endif /* CONFIG_PM */
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index bc033250dfcd..fb17573f8f2d 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -41,17 +41,6 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Serio abstraction core");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(serio_interrupt);
-EXPORT_SYMBOL(__serio_register_port);
-EXPORT_SYMBOL(serio_unregister_port);
-EXPORT_SYMBOL(serio_unregister_child_port);
-EXPORT_SYMBOL(__serio_register_driver);
-EXPORT_SYMBOL(serio_unregister_driver);
-EXPORT_SYMBOL(serio_open);
-EXPORT_SYMBOL(serio_close);
-EXPORT_SYMBOL(serio_rescan);
-EXPORT_SYMBOL(serio_reconnect);
-
/*
* serio_mutex protects entire serio subsystem and is taken every time
* serio port or driver registrered or unregistered.
@@ -506,9 +495,9 @@ static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute *
retval = count;
if (!strncmp(buf, "manual", count)) {
- serio->manual_bind = 1;
+ serio->manual_bind = true;
} else if (!strncmp(buf, "auto", count)) {
- serio->manual_bind = 0;
+ serio->manual_bind = false;
} else {
retval = -EINVAL;
}
@@ -581,7 +570,7 @@ static void serio_add_port(struct serio *serio)
"serio: device_add() failed for %s (%s), error: %d\n",
serio->phys, serio->name, error);
else {
- serio->registered = 1;
+ serio->registered = true;
error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
if (error)
printk(KERN_ERR
@@ -617,7 +606,7 @@ static void serio_destroy_port(struct serio *serio)
if (serio->registered) {
sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group);
device_del(&serio->dev);
- serio->registered = 0;
+ serio->registered = false;
}
list_del_init(&serio->node);
@@ -692,11 +681,13 @@ void serio_rescan(struct serio *serio)
{
serio_queue_event(serio, NULL, SERIO_RESCAN_PORT);
}
+EXPORT_SYMBOL(serio_rescan);
void serio_reconnect(struct serio *serio)
{
serio_queue_event(serio, NULL, SERIO_RECONNECT_CHAIN);
}
+EXPORT_SYMBOL(serio_reconnect);
/*
* Submits register request to kseriod for subsequent execution.
@@ -707,6 +698,7 @@ void __serio_register_port(struct serio *serio, struct module *owner)
serio_init_port(serio);
serio_queue_event(serio, owner, SERIO_REGISTER_PORT);
}
+EXPORT_SYMBOL(__serio_register_port);
/*
* Synchronously unregisters serio port.
@@ -718,6 +710,7 @@ void serio_unregister_port(struct serio *serio)
serio_destroy_port(serio);
mutex_unlock(&serio_mutex);
}
+EXPORT_SYMBOL(serio_unregister_port);
/*
* Safely unregisters child port if one is present.
@@ -731,6 +724,7 @@ void serio_unregister_child_port(struct serio *serio)
}
mutex_unlock(&serio_mutex);
}
+EXPORT_SYMBOL(serio_unregister_child_port);
/*
@@ -756,9 +750,9 @@ static ssize_t serio_driver_set_bind_mode(struct device_driver *drv, const char
retval = count;
if (!strncmp(buf, "manual", count)) {
- serio_drv->manual_bind = 1;
+ serio_drv->manual_bind = true;
} else if (!strncmp(buf, "auto", count)) {
- serio_drv->manual_bind = 0;
+ serio_drv->manual_bind = false;
} else {
retval = -EINVAL;
}
@@ -818,7 +812,7 @@ static void serio_attach_driver(struct serio_driver *drv)
int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name)
{
- int manual_bind = drv->manual_bind;
+ bool manual_bind = drv->manual_bind;
int error;
drv->driver.bus = &serio_bus;
@@ -829,7 +823,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons
* Temporarily disable automatic binding because probing
* takes long time and we are better off doing it in kseriod
*/
- drv->manual_bind = 1;
+ drv->manual_bind = true;
error = driver_register(&drv->driver);
if (error) {
@@ -844,7 +838,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons
* driver to free ports
*/
if (!manual_bind) {
- drv->manual_bind = 0;
+ drv->manual_bind = false;
error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER);
if (error) {
driver_unregister(&drv->driver);
@@ -854,6 +848,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons
return 0;
}
+EXPORT_SYMBOL(__serio_register_driver);
void serio_unregister_driver(struct serio_driver *drv)
{
@@ -861,7 +856,7 @@ void serio_unregister_driver(struct serio_driver *drv)
mutex_lock(&serio_mutex);
- drv->manual_bind = 1; /* so serio_find_driver ignores it */
+ drv->manual_bind = true; /* so serio_find_driver ignores it */
serio_remove_pending_events(drv);
start_over:
@@ -877,6 +872,7 @@ start_over:
driver_unregister(&drv->driver);
mutex_unlock(&serio_mutex);
}
+EXPORT_SYMBOL(serio_unregister_driver);
static void serio_set_drv(struct serio *serio, struct serio_driver *drv)
{
@@ -937,11 +933,11 @@ static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
#ifdef CONFIG_PM
static int serio_suspend(struct device *dev, pm_message_t state)
{
- if (dev->power.power_state.event != state.event) {
- if (state.event == PM_EVENT_SUSPEND)
- serio_cleanup(to_serio_port(dev));
+ struct serio *serio = to_serio_port(dev);
- dev->power.power_state = state;
+ if (!serio->suspended && state.event == PM_EVENT_SUSPEND) {
+ serio_cleanup(serio);
+ serio->suspended = true;
}
return 0;
@@ -949,14 +945,15 @@ static int serio_suspend(struct device *dev, pm_message_t state)
static int serio_resume(struct device *dev)
{
+ struct serio *serio = to_serio_port(dev);
+
/*
* Driver reconnect can take a while, so better let kseriod
* deal with it.
*/
- if (dev->power.power_state.event != PM_EVENT_ON) {
- dev->power.power_state = PMSG_ON;
- serio_queue_event(to_serio_port(dev), NULL,
- SERIO_RECONNECT_PORT);
+ if (serio->suspended) {
+ serio->suspended = false;
+ serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT);
}
return 0;
@@ -974,6 +971,7 @@ int serio_open(struct serio *serio, struct serio_driver *drv)
}
return 0;
}
+EXPORT_SYMBOL(serio_open);
/* called from serio_driver->connect/disconnect methods under serio_mutex */
void serio_close(struct serio *serio)
@@ -983,6 +981,7 @@ void serio_close(struct serio *serio)
serio_set_drv(serio, NULL);
}
+EXPORT_SYMBOL(serio_close);
irqreturn_t serio_interrupt(struct serio *serio,
unsigned char data, unsigned int dfl)
@@ -1003,6 +1002,7 @@ irqreturn_t serio_interrupt(struct serio *serio,
return ret;
}
+EXPORT_SYMBOL(serio_interrupt);
static struct bus_type serio_bus = {
.name = "serio",
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
index 2e18a1c0c351..3d32d3f4e486 100644
--- a/drivers/input/tablet/gtco.c
+++ b/drivers/input/tablet/gtco.c
@@ -1050,4 +1050,5 @@ static void __exit gtco_exit(void)
module_init(gtco_init);
module_exit(gtco_exit);
+MODULE_DESCRIPTION("GTCO digitizer USB driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index 9710bfd49cf9..9114ae1c7488 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -68,6 +68,7 @@
* v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX
* v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A)
* v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28
+ * v1.51 (pc) - Added support for Intuos4
*/
/*
@@ -88,7 +89,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.50"
+#define DRIVER_VERSION "v1.51"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
#define DRIVER_LICENSE "GPL"
@@ -128,6 +129,8 @@ extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac
extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
+extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
+extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index b8624f27abf9..a9d5031b855e 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -229,6 +229,19 @@ void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
}
+void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
+{
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
+ input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3);
+ input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6);
+ input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+}
+
+void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
+{
+ input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_7) | BIT_MASK(BTN_8);
+}
+
void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 2638811c61ac..2ff89904f26f 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -283,10 +283,11 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
{
unsigned char *data = wacom->data;
- int idx;
+ int idx = 0;
/* tool number */
- idx = data[1] & 0x01;
+ if (wacom->features->type == INTUOS)
+ idx = data[1] & 0x01;
/* Enter report */
if ((data[1] & 0xfc) == 0xc0) {
@@ -299,6 +300,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
switch (wacom->id[idx]) {
case 0x812: /* Inking pen */
case 0x801: /* Intuos3 Inking pen */
+ case 0x20802: /* Intuos4 Classic Pen */
case 0x012:
wacom->tool[idx] = BTN_TOOL_PENCIL;
break;
@@ -308,6 +310,9 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
case 0x823: /* Intuos3 Grip Pen */
case 0x813: /* Intuos3 Classic Pen */
case 0x885: /* Intuos3 Marker Pen */
+ case 0x802: /* Intuos4 Grip Pen Eraser */
+ case 0x804: /* Intuos4 Marker Pen */
+ case 0x40802: /* Intuos4 Classic Pen */
case 0x022:
wacom->tool[idx] = BTN_TOOL_PEN;
break;
@@ -319,10 +324,12 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
case 0x09c:
case 0x094:
case 0x017: /* Intuos3 2D Mouse */
+ case 0x806: /* Intuos4 Mouse */
wacom->tool[idx] = BTN_TOOL_MOUSE;
break;
case 0x096: /* Lens cursor */
case 0x097: /* Intuos3 Lens cursor */
+ case 0x006: /* Intuos4 Lens cursor */
wacom->tool[idx] = BTN_TOOL_LENS;
break;
case 0x82a: /* Eraser */
@@ -333,12 +340,17 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
case 0x82b: /* Intuos3 Grip Pen Eraser */
case 0x81b: /* Intuos3 Classic Pen Eraser */
case 0x91b: /* Intuos3 Airbrush Eraser */
+ case 0x80c: /* Intuos4 Marker Pen Eraser */
+ case 0x80a: /* Intuos4 Grip Pen Eraser */
+ case 0x4080a: /* Intuos4 Classic Pen Eraser */
+ case 0x90a: /* Intuos4 Airbrush Eraser */
wacom->tool[idx] = BTN_TOOL_RUBBER;
break;
case 0xd12:
case 0x912:
case 0x112:
case 0x913: /* Intuos3 Airbrush */
+ case 0x902: /* Intuos4 Airbrush */
wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
break;
default: /* Unknown tool */
@@ -349,9 +361,15 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
/* Exit report */
if ((data[1] & 0xfe) == 0x80) {
+ /*
+ * Reset all states otherwise we lose the initial states
+ * when in-prox next time
+ */
wacom_report_abs(wcombo, ABS_X, 0);
wacom_report_abs(wcombo, ABS_Y, 0);
wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+ wacom_report_abs(wcombo, ABS_TILT_X, 0);
+ wacom_report_abs(wcombo, ABS_TILT_Y, 0);
if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
wacom_report_key(wcombo, BTN_LEFT, 0);
wacom_report_key(wcombo, BTN_MIDDLE, 0);
@@ -362,8 +380,6 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
wacom_report_abs(wcombo, ABS_RZ, 0);
} else {
wacom_report_abs(wcombo, ABS_PRESSURE, 0);
- wacom_report_abs(wcombo, ABS_TILT_X, 0);
- wacom_report_abs(wcombo, ABS_TILT_Y, 0);
wacom_report_key(wcombo, BTN_STYLUS, 0);
wacom_report_key(wcombo, BTN_STYLUS2, 0);
wacom_report_key(wcombo, BTN_TOUCH, 0);
@@ -372,6 +388,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, wacom->tool[idx], 0);
wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
+ wacom->id[idx] = 0;
return 2;
}
return 0;
@@ -385,6 +402,8 @@ static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo)
/* general pen packet */
if ((data[1] & 0xb8) == 0xa0) {
t = (data[6] << 2) | ((data[7] >> 6) & 3);
+ if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L)
+ t = (t << 1) | (data[1] & 1);
wacom_report_abs(wcombo, ABS_PRESSURE, t);
wacom_report_abs(wcombo, ABS_TILT_X,
((data[7] << 1) & 0x7e) | (data[8] >> 7));
@@ -409,7 +428,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
{
unsigned char *data = wacom->data;
unsigned int t;
- int idx, result;
+ int idx = 0, result;
if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) {
dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
@@ -417,7 +436,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
}
/* tool number */
- idx = data[1] & 0x01;
+ if (wacom->features->type == INTUOS)
+ idx = data[1] & 0x01;
/* pad packets. Works as a second tool and is always in prox */
if (data[0] == 12) {
@@ -425,25 +445,51 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
if (wacom->tool[1] != BTN_TOOL_FINGER)
wacom->tool[1] = BTN_TOOL_FINGER;
- wacom_report_key(wcombo, BTN_0, (data[5] & 0x01));
- wacom_report_key(wcombo, BTN_1, (data[5] & 0x02));
- wacom_report_key(wcombo, BTN_2, (data[5] & 0x04));
- wacom_report_key(wcombo, BTN_3, (data[5] & 0x08));
- wacom_report_key(wcombo, BTN_4, (data[6] & 0x01));
- wacom_report_key(wcombo, BTN_5, (data[6] & 0x02));
- wacom_report_key(wcombo, BTN_6, (data[6] & 0x04));
- wacom_report_key(wcombo, BTN_7, (data[6] & 0x08));
- wacom_report_key(wcombo, BTN_8, (data[5] & 0x10));
- wacom_report_key(wcombo, BTN_9, (data[6] & 0x10));
- wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
- wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
-
- if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) |
- data[2] | (data[3] & 0x1f) | data[4])
- wacom_report_key(wcombo, wacom->tool[1], 1);
- else
- wacom_report_key(wcombo, wacom->tool[1], 0);
- wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
+ if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) {
+ wacom_report_key(wcombo, BTN_0, (data[2] & 0x01));
+ wacom_report_key(wcombo, BTN_1, (data[3] & 0x01));
+ wacom_report_key(wcombo, BTN_2, (data[3] & 0x02));
+ wacom_report_key(wcombo, BTN_3, (data[3] & 0x04));
+ wacom_report_key(wcombo, BTN_4, (data[3] & 0x08));
+ wacom_report_key(wcombo, BTN_5, (data[3] & 0x10));
+ wacom_report_key(wcombo, BTN_6, (data[3] & 0x20));
+ if (data[1] & 0x80) {
+ wacom_report_abs(wcombo, ABS_WHEEL, (data[1] & 0x7f));
+ }
+ if (wacom->features->type != INTUOS4S) {
+ wacom_report_key(wcombo, BTN_7, (data[3] & 0x40));
+ wacom_report_key(wcombo, BTN_8, (data[3] & 0x80));
+ }
+ if (data[1] | (data[2] & 0x01) | data[3]) {
+ wacom_report_key(wcombo, wacom->tool[1], 1);
+ wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
+ } else {
+ wacom_report_key(wcombo, wacom->tool[1], 0);
+ wacom_report_abs(wcombo, ABS_MISC, 0);
+ }
+ } else {
+ wacom_report_key(wcombo, BTN_0, (data[5] & 0x01));
+ wacom_report_key(wcombo, BTN_1, (data[5] & 0x02));
+ wacom_report_key(wcombo, BTN_2, (data[5] & 0x04));
+ wacom_report_key(wcombo, BTN_3, (data[5] & 0x08));
+ wacom_report_key(wcombo, BTN_4, (data[6] & 0x01));
+ wacom_report_key(wcombo, BTN_5, (data[6] & 0x02));
+ wacom_report_key(wcombo, BTN_6, (data[6] & 0x04));
+ wacom_report_key(wcombo, BTN_7, (data[6] & 0x08));
+ wacom_report_key(wcombo, BTN_8, (data[5] & 0x10));
+ wacom_report_key(wcombo, BTN_9, (data[6] & 0x10));
+ wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
+ wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
+
+ if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) |
+ data[2] | (data[3] & 0x1f) | data[4]) {
+ wacom_report_key(wcombo, wacom->tool[1], 1);
+ wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
+ } else {
+ wacom_report_key(wcombo, wacom->tool[1], 0);
+ wacom_report_abs(wcombo, ABS_MISC, 0);
+ }
+ }
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff);
return 1;
}
@@ -453,10 +499,16 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
if (result)
return result-1;
- /* Only large I3 and I1 & I2 support Lense Cursor */
+ /* don't proceed if we don't know the ID */
+ if (!wacom->id[idx])
+ return 0;
+
+ /* Only large Intuos support Lense Cursor */
if ((wacom->tool[idx] == BTN_TOOL_LENS)
&& ((wacom->features->type == INTUOS3)
- || (wacom->features->type == INTUOS3S)))
+ || (wacom->features->type == INTUOS3S)
+ || (wacom->features->type == INTUOS4)
+ || (wacom->features->type == INTUOS4S)))
return 0;
/* Cintiq doesn't send data when RDY bit isn't set */
@@ -476,8 +528,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
/* process general packets */
wacom_intuos_general(wacom, wcombo);
- /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */
- if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) {
+ /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */
+ if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) {
if (data[1] & 0x02) {
/* Rotation packet */
@@ -506,20 +558,36 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_abs(wcombo, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
} else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
- /* 2D mouse packet */
- wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x04);
- wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x08);
- wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x10);
- wacom_report_rel(wcombo, REL_WHEEL, (data[8] & 0x01)
+ /* I4 mouse */
+ if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) {
+ wacom_report_key(wcombo, BTN_LEFT, data[6] & 0x01);
+ wacom_report_key(wcombo, BTN_MIDDLE, data[6] & 0x02);
+ wacom_report_key(wcombo, BTN_RIGHT, data[6] & 0x04);
+ wacom_report_rel(wcombo, REL_WHEEL, ((data[7] & 0x80) >> 7)
+ - ((data[7] & 0x40) >> 6));
+ wacom_report_key(wcombo, BTN_SIDE, data[6] & 0x08);
+ wacom_report_key(wcombo, BTN_EXTRA, data[6] & 0x10);
+
+ wacom_report_abs(wcombo, ABS_TILT_X,
+ ((data[7] << 1) & 0x7e) | (data[8] >> 7));
+ wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f);
+ } else {
+ /* 2D mouse packet */
+ wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x04);
+ wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x08);
+ wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x10);
+ wacom_report_rel(wcombo, REL_WHEEL, (data[8] & 0x01)
- ((data[8] & 0x02) >> 1));
- /* I3 2D mouse side buttons */
- if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) {
- wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40);
- wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20);
+ /* I3 2D mouse side buttons */
+ if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) {
+ wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40);
+ wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20);
+ }
}
-
- } else if (wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L) {
+ } else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L ||
+ wacom->features->type == INTUOS4L) &&
+ wacom->tool[idx] == BTN_TOOL_LENS) {
/* Lens cursor packets */
wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01);
wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02);
@@ -581,6 +649,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
}
} else if (touchOut || !prox) { /* force touch out-prox */
wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID);
+ wacom_report_key(wcombo, wacom->tool[1], 0);
wacom_report_key(wcombo, BTN_TOUCH, 0);
touchOut = 0;
touchInProx = 1;
@@ -669,6 +738,9 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
case INTUOS3S:
case INTUOS3:
case INTUOS3L:
+ case INTUOS4S:
+ case INTUOS4:
+ case INTUOS4L:
case CINTIQ:
case WACOM_BEE:
return wacom_intuos_irq(wacom_wac, wcombo);
@@ -706,6 +778,14 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w
case INTUOS:
input_dev_i(input_dev, wacom_wac);
break;
+ case INTUOS4:
+ case INTUOS4L:
+ input_dev_i4(input_dev, wacom_wac);
+ /* fall through */
+ case INTUOS4S:
+ input_dev_i4s(input_dev, wacom_wac);
+ input_dev_i(input_dev, wacom_wac);
+ break;
case PL:
case PTU:
case TABLETPC:
@@ -766,6 +846,10 @@ static struct wacom_features wacom_features[] = {
{ "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L },
{ "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 },
{ "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S },
+ { "Wacom Intuos4 4x6", 10, 31496, 19685, 2047, 63, INTUOS4S },
+ { "Wacom Intuos4 6x9", 10, 44704, 27940, 2047, 63, INTUOS4 },
+ { "Wacom Intuos4 8x13", 10, 65024, 40640, 2047, 63, INTUOS4L },
+ { "Wacom Intuos4 12x19", 10, 97536, 60960, 2047, 63, INTUOS4L },
{ "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ },
{ "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE },
{ "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE },
@@ -825,6 +909,10 @@ static struct usb_device_id wacom_ids[] = {
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index f9c8b69673b7..c10235aba7e5 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -25,6 +25,9 @@ enum {
INTUOS3S,
INTUOS3,
INTUOS3L,
+ INTUOS4S,
+ INTUOS4,
+ INTUOS4L,
CINTIQ,
WACOM_BEE,
WACOM_MO,
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index b01fd61dadcc..82c388e0fe3e 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -341,6 +341,21 @@ config TOUCHSCREEN_WM9713
Say Y here to enable support for the Wolfson Microelectronics
WM9713 touchscreen controller.
+config TOUCHSCREEN_WM97XX_ATMEL
+ tristate "WM97xx Atmel accelerated touch"
+ depends on TOUCHSCREEN_WM97XX && (AVR32 || ARCH_AT91)
+ help
+ Say Y here for support for streaming mode with WM97xx touchscreens
+ on Atmel AT91 or AVR32 systems with an AC97C module.
+
+ Be aware that this will use channel B in the controller for
+ streaming data, this must not conflict with other AC97C drivers.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the module will
+ be called atmel-wm97xx.
+
config TOUCHSCREEN_WM97XX_MAINSTONE
tristate "WM97xx Mainstone accelerated touch"
depends on TOUCHSCREEN_WM97XX && ARCH_PXA
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 6700f7b9d165..bef741522954 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -35,5 +35,6 @@ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
+obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o
obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c
new file mode 100644
index 000000000000..35377f583e28
--- /dev/null
+++ b/drivers/input/touchscreen/atmel-wm97xx.c
@@ -0,0 +1,446 @@
+/*
+ * Atmel AT91 and AVR32 continuous touch screen driver for Wolfson WM97xx AC97
+ * codecs.
+ *
+ * Copyright (C) 2008 - 2009 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/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/wm97xx.h>
+#include <linux/timer.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#define AC97C_ICA 0x10
+#define AC97C_CBRHR 0x30
+#define AC97C_CBSR 0x38
+#define AC97C_CBMR 0x3c
+#define AC97C_IER 0x54
+#define AC97C_IDR 0x58
+
+#define AC97C_RXRDY (1 << 4)
+#define AC97C_OVRUN (1 << 5)
+
+#define AC97C_CMR_SIZE_20 (0 << 16)
+#define AC97C_CMR_SIZE_18 (1 << 16)
+#define AC97C_CMR_SIZE_16 (2 << 16)
+#define AC97C_CMR_SIZE_10 (3 << 16)
+#define AC97C_CMR_CEM_LITTLE (1 << 18)
+#define AC97C_CMR_CEM_BIG (0 << 18)
+#define AC97C_CMR_CENA (1 << 21)
+
+#define AC97C_INT_CBEVT (1 << 4)
+
+#define AC97C_SR_CAEVT (1 << 3)
+
+#define AC97C_CH_MASK(slot) \
+ (0x7 << (3 * (slot - 3)))
+#define AC97C_CH_ASSIGN(slot, channel) \
+ (AC97C_CHANNEL_##channel << (3 * (slot - 3)))
+#define AC97C_CHANNEL_NONE 0x0
+#define AC97C_CHANNEL_B 0x2
+
+#define ac97c_writel(chip, reg, val) \
+ __raw_writel((val), (chip)->regs + AC97C_##reg)
+#define ac97c_readl(chip, reg) \
+ __raw_readl((chip)->regs + AC97C_##reg)
+
+#ifdef CONFIG_CPU_AT32AP700X
+#define ATMEL_WM97XX_AC97C_IOMEM (0xfff02800)
+#define ATMEL_WM97XX_AC97C_IRQ (29)
+#define ATMEL_WM97XX_GPIO_DEFAULT (32+16) /* Pin 16 on port B. */
+#else
+#error Unkown CPU, this driver only supports AT32AP700X CPUs.
+#endif
+
+struct continuous {
+ u16 id; /* codec id */
+ u8 code; /* continuous code */
+ u8 reads; /* number of coord reads per read cycle */
+ u32 speed; /* number of coords per second */
+};
+
+#define WM_READS(sp) ((sp / HZ) + 1)
+
+static const struct continuous cinfo[] = {
+ {WM9705_ID2, 0, WM_READS(94), 94},
+ {WM9705_ID2, 1, WM_READS(188), 188},
+ {WM9705_ID2, 2, WM_READS(375), 375},
+ {WM9705_ID2, 3, WM_READS(750), 750},
+ {WM9712_ID2, 0, WM_READS(94), 94},
+ {WM9712_ID2, 1, WM_READS(188), 188},
+ {WM9712_ID2, 2, WM_READS(375), 375},
+ {WM9712_ID2, 3, WM_READS(750), 750},
+ {WM9713_ID2, 0, WM_READS(94), 94},
+ {WM9713_ID2, 1, WM_READS(120), 120},
+ {WM9713_ID2, 2, WM_READS(154), 154},
+ {WM9713_ID2, 3, WM_READS(188), 188},
+};
+
+/* Continuous speed index. */
+static int sp_idx;
+
+/*
+ * Pen sampling frequency (Hz) in continuous mode.
+ */
+static int cont_rate = 188;
+module_param(cont_rate, int, 0);
+MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
+
+/*
+ * Pen down detection.
+ *
+ * This driver can either poll or use an interrupt to indicate a pen down
+ * event. If the irq request fails then it will fall back to polling mode.
+ */
+static int pen_int = 1;
+module_param(pen_int, int, 0);
+MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)");
+
+/*
+ * Pressure readback.
+ *
+ * Set to 1 to read back pen down pressure.
+ */
+static int pressure;
+module_param(pressure, int, 0);
+MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
+
+/*
+ * AC97 touch data slot.
+ *
+ * Touch screen readback data ac97 slot.
+ */
+static int ac97_touch_slot = 5;
+module_param(ac97_touch_slot, int, 0);
+MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
+
+/*
+ * GPIO line number.
+ *
+ * Set to GPIO number where the signal from the WM97xx device is hooked up.
+ */
+static int atmel_gpio_line = ATMEL_WM97XX_GPIO_DEFAULT;
+module_param(atmel_gpio_line, int, 0);
+MODULE_PARM_DESC(atmel_gpio_line, "GPIO line number connected to WM97xx");
+
+struct atmel_wm97xx {
+ struct wm97xx *wm;
+ struct timer_list pen_timer;
+ void __iomem *regs;
+ unsigned long ac97c_irq;
+ unsigned long gpio_pen;
+ unsigned long gpio_irq;
+ unsigned short x;
+ unsigned short y;
+};
+
+static irqreturn_t atmel_wm97xx_channel_b_interrupt(int irq, void *dev_id)
+{
+ struct atmel_wm97xx *atmel_wm97xx = dev_id;
+ struct wm97xx *wm = atmel_wm97xx->wm;
+ int status = ac97c_readl(atmel_wm97xx, CBSR);
+ irqreturn_t retval = IRQ_NONE;
+
+ if (status & AC97C_OVRUN) {
+ dev_dbg(&wm->touch_dev->dev, "AC97C overrun\n");
+ ac97c_readl(atmel_wm97xx, CBRHR);
+ retval = IRQ_HANDLED;
+ } else if (status & AC97C_RXRDY) {
+ u16 data;
+ u16 value;
+ u16 source;
+ u16 pen_down;
+
+ data = ac97c_readl(atmel_wm97xx, CBRHR);
+ value = data & 0x0fff;
+ source = data & WM97XX_ADCSRC_MASK;
+ pen_down = (data & WM97XX_PEN_DOWN) >> 8;
+
+ if (source == WM97XX_ADCSEL_X)
+ atmel_wm97xx->x = value;
+ if (source == WM97XX_ADCSEL_Y)
+ atmel_wm97xx->y = value;
+
+ if (!pressure && source == WM97XX_ADCSEL_Y) {
+ input_report_abs(wm->input_dev, ABS_X, atmel_wm97xx->x);
+ input_report_abs(wm->input_dev, ABS_Y, atmel_wm97xx->y);
+ input_report_key(wm->input_dev, BTN_TOUCH, pen_down);
+ input_sync(wm->input_dev);
+ } else if (pressure && source == WM97XX_ADCSEL_PRES) {
+ input_report_abs(wm->input_dev, ABS_X, atmel_wm97xx->x);
+ input_report_abs(wm->input_dev, ABS_Y, atmel_wm97xx->y);
+ input_report_abs(wm->input_dev, ABS_PRESSURE, value);
+ input_report_key(wm->input_dev, BTN_TOUCH, value);
+ input_sync(wm->input_dev);
+ }
+
+ retval = IRQ_HANDLED;
+ }
+
+ return retval;
+}
+
+static void atmel_wm97xx_acc_pen_up(struct wm97xx *wm)
+{
+ struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(wm->touch_dev);
+ struct input_dev *input_dev = wm->input_dev;
+ int pen_down = gpio_get_value(atmel_wm97xx->gpio_pen);
+
+ if (pen_down != 0) {
+ mod_timer(&atmel_wm97xx->pen_timer,
+ jiffies + msecs_to_jiffies(1));
+ } else {
+ if (pressure)
+ input_report_abs(input_dev, ABS_PRESSURE, 0);
+ input_report_key(input_dev, BTN_TOUCH, 0);
+ input_sync(input_dev);
+ }
+}
+
+static void atmel_wm97xx_pen_timer(unsigned long data)
+{
+ atmel_wm97xx_acc_pen_up((struct wm97xx *)data);
+}
+
+static int atmel_wm97xx_acc_startup(struct wm97xx *wm)
+{
+ struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(wm->touch_dev);
+ int idx = 0;
+
+ if (wm->ac97 == NULL)
+ return -ENODEV;
+
+ for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
+ if (wm->id != cinfo[idx].id)
+ continue;
+
+ sp_idx = idx;
+
+ if (cont_rate <= cinfo[idx].speed)
+ break;
+ }
+
+ wm->acc_rate = cinfo[sp_idx].code;
+ wm->acc_slot = ac97_touch_slot;
+ dev_info(&wm->touch_dev->dev, "atmel accelerated touchscreen driver, "
+ "%d samples/sec\n", cinfo[sp_idx].speed);
+
+ if (pen_int) {
+ unsigned long reg;
+
+ wm->pen_irq = atmel_wm97xx->gpio_irq;
+
+ switch (wm->id) {
+ case WM9712_ID2: /* Fall through. */
+ case WM9713_ID2:
+ /*
+ * Use GPIO 13 (PEN_DOWN) to assert GPIO line 3
+ * (PENDOWN).
+ */
+ wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
+ WM97XX_GPIO_POL_HIGH,
+ WM97XX_GPIO_STICKY,
+ WM97XX_GPIO_WAKE);
+ wm97xx_config_gpio(wm, WM97XX_GPIO_3, WM97XX_GPIO_OUT,
+ WM97XX_GPIO_POL_HIGH,
+ WM97XX_GPIO_NOTSTICKY,
+ WM97XX_GPIO_NOWAKE);
+ case WM9705_ID2: /* Fall through. */
+ /*
+ * Enable touch data slot in AC97 controller channel B.
+ */
+ reg = ac97c_readl(atmel_wm97xx, ICA);
+ reg &= ~AC97C_CH_MASK(wm->acc_slot);
+ reg |= AC97C_CH_ASSIGN(wm->acc_slot, B);
+ ac97c_writel(atmel_wm97xx, ICA, reg);
+
+ /*
+ * Enable channel and interrupt for RXRDY and OVERRUN.
+ */
+ ac97c_writel(atmel_wm97xx, CBMR, AC97C_CMR_CENA
+ | AC97C_CMR_CEM_BIG
+ | AC97C_CMR_SIZE_16
+ | AC97C_OVRUN
+ | AC97C_RXRDY);
+ /* Dummy read to empty RXRHR. */
+ ac97c_readl(atmel_wm97xx, CBRHR);
+ /*
+ * Enable interrupt for channel B in the AC97
+ * controller.
+ */
+ ac97c_writel(atmel_wm97xx, IER, AC97C_INT_CBEVT);
+ break;
+ default:
+ dev_err(&wm->touch_dev->dev, "pen down irq not "
+ "supported on this device\n");
+ pen_int = 0;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void atmel_wm97xx_acc_shutdown(struct wm97xx *wm)
+{
+ if (pen_int) {
+ struct atmel_wm97xx *atmel_wm97xx =
+ platform_get_drvdata(wm->touch_dev);
+ unsigned long ica;
+
+ switch (wm->id & 0xffff) {
+ case WM9705_ID2: /* Fall through. */
+ case WM9712_ID2: /* Fall through. */
+ case WM9713_ID2:
+ /* Disable slot and turn off channel B interrupts. */
+ ica = ac97c_readl(atmel_wm97xx, ICA);
+ ica &= ~AC97C_CH_MASK(wm->acc_slot);
+ ac97c_writel(atmel_wm97xx, ICA, ica);
+ ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT);
+ ac97c_writel(atmel_wm97xx, CBMR, 0);
+ wm->pen_irq = 0;
+ break;
+ default:
+ dev_err(&wm->touch_dev->dev, "unknown codec\n");
+ break;
+ }
+ }
+}
+
+static void atmel_wm97xx_irq_enable(struct wm97xx *wm, int enable)
+{
+ /* Intentionally left empty. */
+}
+
+static struct wm97xx_mach_ops atmel_mach_ops = {
+ .acc_enabled = 1,
+ .acc_pen_up = atmel_wm97xx_acc_pen_up,
+ .acc_startup = atmel_wm97xx_acc_startup,
+ .acc_shutdown = atmel_wm97xx_acc_shutdown,
+ .irq_enable = atmel_wm97xx_irq_enable,
+ .irq_gpio = WM97XX_GPIO_3,
+};
+
+static int __init atmel_wm97xx_probe(struct platform_device *pdev)
+{
+ struct wm97xx *wm = platform_get_drvdata(pdev);
+ struct atmel_wm97xx *atmel_wm97xx;
+ int ret;
+
+ atmel_wm97xx = kzalloc(sizeof(struct atmel_wm97xx), GFP_KERNEL);
+ if (!atmel_wm97xx) {
+ dev_dbg(&pdev->dev, "out of memory\n");
+ return -ENOMEM;
+ }
+
+ atmel_wm97xx->wm = wm;
+ atmel_wm97xx->regs = (void *)ATMEL_WM97XX_AC97C_IOMEM;
+ atmel_wm97xx->ac97c_irq = ATMEL_WM97XX_AC97C_IRQ;
+ atmel_wm97xx->gpio_pen = atmel_gpio_line;
+ atmel_wm97xx->gpio_irq = gpio_to_irq(atmel_wm97xx->gpio_pen);
+
+ setup_timer(&atmel_wm97xx->pen_timer, atmel_wm97xx_pen_timer,
+ (unsigned long)wm);
+
+ ret = request_irq(atmel_wm97xx->ac97c_irq,
+ atmel_wm97xx_channel_b_interrupt,
+ IRQF_SHARED, "atmel-wm97xx-ch-b", atmel_wm97xx);
+ if (ret) {
+ dev_dbg(&pdev->dev, "could not request ac97c irq\n");
+ goto err;
+ }
+
+ platform_set_drvdata(pdev, atmel_wm97xx);
+
+ ret = wm97xx_register_mach_ops(wm, &atmel_mach_ops);
+ if (ret)
+ goto err_irq;
+
+ return ret;
+
+err_irq:
+ free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx);
+err:
+ platform_set_drvdata(pdev, NULL);
+ kfree(atmel_wm97xx);
+ return ret;
+}
+
+static int __exit atmel_wm97xx_remove(struct platform_device *pdev)
+{
+ struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev);
+ struct wm97xx *wm = atmel_wm97xx->wm;
+
+ ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT);
+ free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx);
+ del_timer_sync(&atmel_wm97xx->pen_timer);
+ wm97xx_unregister_mach_ops(wm);
+ platform_set_drvdata(pdev, NULL);
+ kfree(atmel_wm97xx);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int atmel_wm97xx_suspend(struct platform_device *pdev, pm_message_t msg)
+{
+ struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev);
+
+ ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT);
+ disable_irq(atmel_wm97xx->gpio_irq);
+ del_timer_sync(&atmel_wm97xx->pen_timer);
+
+ return 0;
+}
+
+static int atmel_wm97xx_resume(struct platform_device *pdev)
+{
+ struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev);
+ struct wm97xx *wm = atmel_wm97xx->wm;
+
+ if (wm->input_dev->users) {
+ enable_irq(atmel_wm97xx->gpio_irq);
+ ac97c_writel(atmel_wm97xx, IER, AC97C_INT_CBEVT);
+ }
+
+ return 0;
+}
+#else
+#define atmel_wm97xx_suspend NULL
+#define atmel_wm97xx_resume NULL
+#endif
+
+static struct platform_driver atmel_wm97xx_driver = {
+ .remove = __exit_p(atmel_wm97xx_remove),
+ .driver = {
+ .name = "wm97xx-touch",
+ },
+ .suspend = atmel_wm97xx_suspend,
+ .resume = atmel_wm97xx_resume,
+};
+
+static int __init atmel_wm97xx_init(void)
+{
+ return platform_driver_probe(&atmel_wm97xx_driver, atmel_wm97xx_probe);
+}
+module_init(atmel_wm97xx_init);
+
+static void __exit atmel_wm97xx_exit(void)
+{
+ platform_driver_unregister(&atmel_wm97xx_driver);
+}
+module_exit(atmel_wm97xx_exit);
+
+MODULE_AUTHOR("Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>");
+MODULE_DESCRIPTION("wm97xx continuous touch driver for Atmel AT91 and AVR32");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index 536668fbda22..948e167557f1 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -200,8 +200,9 @@ static int tsc2007_read_values(struct tsc2007 *tsc)
static enum hrtimer_restart tsc2007_timer(struct hrtimer *handle)
{
struct tsc2007 *ts = container_of(handle, struct tsc2007, timer);
+ unsigned long flags;
- spin_lock_irq(&ts->lock);
+ spin_lock_irqsave(&ts->lock, flags);
if (unlikely(!ts->get_pendown_state() && ts->pendown)) {
struct input_dev *input = ts->input;
@@ -222,7 +223,7 @@ static enum hrtimer_restart tsc2007_timer(struct hrtimer *handle)
tsc2007_send_event(ts);
}
- spin_unlock_irq(&ts->lock);
+ spin_unlock_irqrestore(&ts->lock, flags);
return HRTIMER_NORESTART;
}
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index 69af8385ab14..2957d48e0045 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -569,7 +569,7 @@ static int wm97xx_probe(struct device *dev)
mutex_init(&wm->codec_mutex);
wm->dev = dev;
- dev->driver_data = wm;
+ dev_set_drvdata(dev, wm);
wm->ac97 = to_ac97_t(dev);
/* check that we have a supported codec */
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index b129409925af..bff72d81f263 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -75,15 +75,17 @@ static int capifs_remount(struct super_block *s, int *flags, char *data)
}
}
- kfree(s->s_options);
- s->s_options = new_opt;
+ mutex_lock(&s->s_root->d_inode->i_mutex);
+ replace_mount_options(s, new_opt);
config.setuid = setuid;
config.setgid = setgid;
config.uid = uid;
config.gid = gid;
config.mode = mode;
+ mutex_unlock(&s->s_root->d_inode->i_mutex);
+
return 0;
}
@@ -154,13 +156,16 @@ void capifs_new_ncci(unsigned int number, dev_t device)
if (!inode)
return;
inode->i_ino = number+2;
+
+ dentry = get_node(number);
+
+ /* config contents is protected by root's i_mutex */
inode->i_uid = config.setuid ? config.uid : current_fsuid();
inode->i_gid = config.setgid ? config.gid : current_fsgid();
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
init_special_inode(inode, S_IFCHR|config.mode, device);
//inode->i_op = &capifs_file_inode_operations;
- dentry = get_node(number);
if (!IS_ERR(dentry) && !dentry->d_inode)
d_instantiate(dentry, inode);
mutex_unlock(&capifs_root->d_inode->i_mutex);
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index c0621d50c8a0..4a8bf467ff43 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -71,7 +71,7 @@ MODULE_PARM_DESC(verbose,"Verbose log operations "
"(default 0)");
struct thermostat {
- struct i2c_client clt;
+ struct i2c_client *clt;
u8 temps[3];
u8 cached_temp[3];
u8 initial_limits[3];
@@ -86,9 +86,6 @@ static struct of_device * of_dev;
static struct thermostat* thermostat;
static struct task_struct *thread_therm = NULL;
-static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
- int busno);
-
static void write_both_fan_speed(struct thermostat *th, int speed);
static void write_fan_speed(struct thermostat *th, int speed, int fan);
@@ -100,7 +97,7 @@ write_reg(struct thermostat* th, int reg, u8 data)
tmp[0] = reg;
tmp[1] = data;
- rc = i2c_master_send(&th->clt, (const char *)tmp, 2);
+ rc = i2c_master_send(th->clt, (const char *)tmp, 2);
if (rc < 0)
return rc;
if (rc != 2)
@@ -115,12 +112,12 @@ read_reg(struct thermostat* th, int reg)
int rc;
reg_addr = (u8)reg;
- rc = i2c_master_send(&th->clt, &reg_addr, 1);
+ rc = i2c_master_send(th->clt, &reg_addr, 1);
if (rc < 0)
return rc;
if (rc != 1)
return -ENODEV;
- rc = i2c_master_recv(&th->clt, (char *)&data, 1);
+ rc = i2c_master_recv(th->clt, (char *)&data, 1);
if (rc < 0)
return rc;
return data;
@@ -130,26 +127,36 @@ static int
attach_thermostat(struct i2c_adapter *adapter)
{
unsigned long bus_no;
+ struct i2c_board_info info;
+ struct i2c_client *client;
if (strncmp(adapter->name, "uni-n", 5))
return -ENODEV;
bus_no = simple_strtoul(adapter->name + 6, NULL, 10);
if (bus_no != therm_bus)
return -ENODEV;
- return attach_one_thermostat(adapter, therm_address, bus_no);
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "therm_adt746x", I2C_NAME_SIZE);
+ info.addr = therm_address;
+ client = i2c_new_device(adapter, &info);
+ if (!client)
+ return -ENODEV;
+
+ /*
+ * Let i2c-core delete that device on driver removal.
+ * This is safe because i2c-core holds the core_lock mutex for us.
+ */
+ list_add_tail(&client->detected, &client->driver->clients);
+ return 0;
}
static int
-detach_thermostat(struct i2c_adapter *adapter)
+remove_thermostat(struct i2c_client *client)
{
- struct thermostat* th;
+ struct thermostat *th = i2c_get_clientdata(client);
int i;
- if (thermostat == NULL)
- return 0;
-
- th = thermostat;
-
if (thread_therm != NULL) {
kthread_stop(thread_therm);
}
@@ -165,8 +172,6 @@ detach_thermostat(struct i2c_adapter *adapter)
write_both_fan_speed(th, -1);
- i2c_detach_client(&th->clt);
-
thermostat = NULL;
kfree(th);
@@ -174,14 +179,6 @@ detach_thermostat(struct i2c_adapter *adapter)
return 0;
}
-static struct i2c_driver thermostat_driver = {
- .driver = {
- .name = "therm_adt746x",
- },
- .attach_adapter = attach_thermostat,
- .detach_adapter = detach_thermostat,
-};
-
static int read_fan_speed(struct thermostat *th, u8 addr)
{
u8 tmp[2];
@@ -369,8 +366,8 @@ static void set_limit(struct thermostat *th, int i)
th->limits[i] = default_limits_local[i] + limit_adjust;
}
-static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
- int busno)
+static int probe_thermostat(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct thermostat* th;
int rc;
@@ -383,16 +380,12 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
if (!th)
return -ENOMEM;
- th->clt.addr = addr;
- th->clt.adapter = adapter;
- th->clt.driver = &thermostat_driver;
- strcpy(th->clt.name, "thermostat");
+ i2c_set_clientdata(client, th);
+ th->clt = client;
rc = read_reg(th, 0);
if (rc < 0) {
- printk(KERN_ERR "adt746x: Thermostat failed to read config "
- "from bus %d !\n",
- busno);
+ dev_err(&client->dev, "Thermostat failed to read config!\n");
kfree(th);
return -ENODEV;
}
@@ -421,14 +414,6 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
thermostat = th;
- if (i2c_attach_client(&th->clt)) {
- printk(KERN_INFO "adt746x: Thermostat failed to attach "
- "client !\n");
- thermostat = NULL;
- kfree(th);
- return -ENODEV;
- }
-
/* be sure to really write fan speed the first time */
th->last_speed[0] = -2;
th->last_speed[1] = -2;
@@ -454,6 +439,21 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
return 0;
}
+static const struct i2c_device_id therm_adt746x_id[] = {
+ { "therm_adt746x", 0 },
+ { }
+};
+
+static struct i2c_driver thermostat_driver = {
+ .driver = {
+ .name = "therm_adt746x",
+ },
+ .attach_adapter = attach_thermostat,
+ .probe = probe_thermostat,
+ .remove = remove_thermostat,
+ .id_table = therm_adt746x_id,
+};
+
/*
* Now, unfortunately, sysfs doesn't give us a nice void * we could
* pass around to the attribute functions, so we don't really have
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 817607e2af6a..a028598af2d3 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -287,22 +287,6 @@ struct fcu_fan_table fcu_fans[] = {
};
/*
- * i2c_driver structure to attach to the host i2c controller
- */
-
-static int therm_pm72_attach(struct i2c_adapter *adapter);
-static int therm_pm72_detach(struct i2c_adapter *adapter);
-
-static struct i2c_driver therm_pm72_driver =
-{
- .driver = {
- .name = "therm_pm72",
- },
- .attach_adapter = therm_pm72_attach,
- .detach_adapter = therm_pm72_detach,
-};
-
-/*
* Utility function to create an i2c_client structure and
* attach it to one of u3 adapters
*/
@@ -310,6 +294,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name)
{
struct i2c_client *clt;
struct i2c_adapter *adap;
+ struct i2c_board_info info;
if (id & 0x200)
adap = k2;
@@ -320,31 +305,21 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name)
if (adap == NULL)
return NULL;
- clt = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (clt == NULL)
- return NULL;
-
- clt->addr = (id >> 1) & 0x7f;
- clt->adapter = adap;
- clt->driver = &therm_pm72_driver;
- strncpy(clt->name, name, I2C_NAME_SIZE-1);
-
- if (i2c_attach_client(clt)) {
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = (id >> 1) & 0x7f;
+ strlcpy(info.type, "therm_pm72", I2C_NAME_SIZE);
+ clt = i2c_new_device(adap, &info);
+ if (!clt) {
printk(KERN_ERR "therm_pm72: Failed to attach to i2c ID 0x%x\n", id);
- kfree(clt);
return NULL;
}
- return clt;
-}
-/*
- * Utility function to get rid of the i2c_client structure
- * (will also detach from the adapter hopepfully)
- */
-static void detach_i2c_chip(struct i2c_client *clt)
-{
- i2c_detach_client(clt);
- kfree(clt);
+ /*
+ * Let i2c-core delete that device on driver removal.
+ * This is safe because i2c-core holds the core_lock mutex for us.
+ */
+ list_add_tail(&clt->detected, &clt->driver->clients);
+ return clt;
}
/*
@@ -1203,8 +1178,6 @@ static int init_cpu_state(struct cpu_pid_state *state, int index)
return 0;
fail:
- if (state->monitor)
- detach_i2c_chip(state->monitor);
state->monitor = NULL;
return -ENODEV;
@@ -1232,7 +1205,6 @@ static void dispose_cpu_state(struct cpu_pid_state *state)
device_remove_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm);
}
- detach_i2c_chip(state->monitor);
state->monitor = NULL;
}
@@ -1407,7 +1379,6 @@ static void dispose_backside_state(struct backside_pid_state *state)
device_remove_file(&of_dev->dev, &dev_attr_backside_temperature);
device_remove_file(&of_dev->dev, &dev_attr_backside_fan_pwm);
- detach_i2c_chip(state->monitor);
state->monitor = NULL;
}
@@ -1532,7 +1503,6 @@ static void dispose_drives_state(struct drives_pid_state *state)
device_remove_file(&of_dev->dev, &dev_attr_drives_temperature);
device_remove_file(&of_dev->dev, &dev_attr_drives_fan_rpm);
- detach_i2c_chip(state->monitor);
state->monitor = NULL;
}
@@ -1654,7 +1624,6 @@ static void dispose_dimms_state(struct dimm_pid_state *state)
device_remove_file(&of_dev->dev, &dev_attr_dimms_temperature);
- detach_i2c_chip(state->monitor);
state->monitor = NULL;
}
@@ -1779,7 +1748,6 @@ static void dispose_slots_state(struct slots_pid_state *state)
device_remove_file(&of_dev->dev, &dev_attr_slots_temperature);
device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm);
- detach_i2c_chip(state->monitor);
state->monitor = NULL;
}
@@ -2008,8 +1976,6 @@ static int attach_fcu(void)
*/
static void detach_fcu(void)
{
- if (fcu)
- detach_i2c_chip(fcu);
fcu = NULL;
}
@@ -2060,12 +2026,21 @@ static int therm_pm72_attach(struct i2c_adapter *adapter)
return 0;
}
+static int therm_pm72_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ /* Always succeed, the real work was done in therm_pm72_attach() */
+ return 0;
+}
+
/*
- * Called on every adapter when the driver or the i2c controller
+ * Called when any of the devices which participates into thermal management
* is going away.
*/
-static int therm_pm72_detach(struct i2c_adapter *adapter)
+static int therm_pm72_remove(struct i2c_client *client)
{
+ struct i2c_adapter *adapter = client->adapter;
+
mutex_lock(&driver_lock);
if (state != state_detached)
@@ -2096,6 +2071,30 @@ static int therm_pm72_detach(struct i2c_adapter *adapter)
return 0;
}
+/*
+ * i2c_driver structure to attach to the host i2c controller
+ */
+
+static const struct i2c_device_id therm_pm72_id[] = {
+ /*
+ * Fake device name, thermal management is done by several
+ * chips but we don't need to differentiate between them at
+ * this point.
+ */
+ { "therm_pm72", 0 },
+ { }
+};
+
+static struct i2c_driver therm_pm72_driver = {
+ .driver = {
+ .name = "therm_pm72",
+ },
+ .attach_adapter = therm_pm72_attach,
+ .probe = therm_pm72_probe,
+ .remove = therm_pm72_remove,
+ .id_table = therm_pm72_id,
+};
+
static int fan_check_loc_match(const char *loc, int fan)
{
char tmp[64];
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 3da0a02efd76..40023313a760 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -48,16 +48,6 @@
#define LOG_TEMP 0 /* continously log temperature */
-static int do_probe( struct i2c_adapter *adapter, int addr, int kind);
-
-/* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
-static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
- 0x4c, 0x4d, 0x4e, 0x4f,
- 0x2c, 0x2d, 0x2e, 0x2f,
- I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
static struct {
volatile int running;
struct task_struct *poll_task;
@@ -315,53 +305,54 @@ static int control_loop(void *dummy)
static int
do_attach( struct i2c_adapter *adapter )
{
- int ret = 0;
+ /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
+ static const unsigned short scan_ds1775[] = {
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ I2C_CLIENT_END
+ };
+ static const unsigned short scan_adm1030[] = {
+ 0x2c, 0x2d, 0x2e, 0x2f,
+ I2C_CLIENT_END
+ };
if( strncmp(adapter->name, "uni-n", 5) )
return 0;
if( !x.running ) {
- ret = i2c_probe( adapter, &addr_data, &do_probe );
+ struct i2c_board_info info;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE);
+ i2c_new_probed_device(adapter, &info, scan_ds1775);
+
+ strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE);
+ i2c_new_probed_device(adapter, &info, scan_adm1030);
+
if( x.thermostat && x.fan ) {
x.running = 1;
x.poll_task = kthread_run(control_loop, NULL, "g4fand");
}
}
- return ret;
+ return 0;
}
static int
-do_detach( struct i2c_client *client )
+do_remove(struct i2c_client *client)
{
- int err;
-
- if( (err=i2c_detach_client(client)) )
- printk(KERN_ERR "failed to detach thermostat client\n");
- else {
- if( x.running ) {
- x.running = 0;
- kthread_stop(x.poll_task);
- x.poll_task = NULL;
- }
- if( client == x.thermostat )
- x.thermostat = NULL;
- else if( client == x.fan )
- x.fan = NULL;
- else {
- printk(KERN_ERR "g4fan: bad client\n");
- }
- kfree( client );
+ if (x.running) {
+ x.running = 0;
+ kthread_stop(x.poll_task);
+ x.poll_task = NULL;
}
- return err;
-}
+ if (client == x.thermostat)
+ x.thermostat = NULL;
+ else if (client == x.fan)
+ x.fan = NULL;
+ else
+ printk(KERN_ERR "g4fan: bad client\n");
-static struct i2c_driver g4fan_driver = {
- .driver = {
- .name = "therm_windtunnel",
- },
- .attach_adapter = do_attach,
- .detach_client = do_detach,
-};
+ return 0;
+}
static int
attach_fan( struct i2c_client *cl )
@@ -374,13 +365,8 @@ attach_fan( struct i2c_client *cl )
goto out;
printk("ADM1030 fan controller [@%02x]\n", cl->addr );
- strlcpy( cl->name, "ADM1030 fan controller", sizeof(cl->name) );
-
- if( !i2c_attach_client(cl) )
- x.fan = cl;
+ x.fan = cl;
out:
- if( cl != x.fan )
- kfree( cl );
return 0;
}
@@ -412,39 +398,47 @@ attach_thermostat( struct i2c_client *cl )
x.temp = temp;
x.overheat_temp = os_temp;
x.overheat_hyst = hyst_temp;
-
- strlcpy( cl->name, "DS1775 thermostat", sizeof(cl->name) );
-
- if( !i2c_attach_client(cl) )
- x.thermostat = cl;
+ x.thermostat = cl;
out:
- if( cl != x.thermostat )
- kfree( cl );
return 0;
}
+enum chip { ds1775, adm1030 };
+
+static const struct i2c_device_id therm_windtunnel_id[] = {
+ { "therm_ds1775", ds1775 },
+ { "therm_adm1030", adm1030 },
+ { }
+};
+
static int
-do_probe( struct i2c_adapter *adapter, int addr, int kind )
+do_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
- struct i2c_client *cl;
+ struct i2c_adapter *adapter = cl->adapter;
if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA
| I2C_FUNC_SMBUS_WRITE_BYTE) )
return 0;
- if( !(cl=kzalloc(sizeof(*cl), GFP_KERNEL)) )
- return -ENOMEM;
-
- cl->addr = addr;
- cl->adapter = adapter;
- cl->driver = &g4fan_driver;
- cl->flags = 0;
-
- if( addr < 0x48 )
+ switch (id->driver_data) {
+ case adm1030:
return attach_fan( cl );
- return attach_thermostat( cl );
+ case ds1775:
+ return attach_thermostat(cl);
+ }
+ return 0;
}
+static struct i2c_driver g4fan_driver = {
+ .driver = {
+ .name = "therm_windtunnel",
+ },
+ .attach_adapter = do_attach,
+ .probe = do_probe,
+ .remove = do_remove,
+ .id_table = therm_windtunnel_id,
+};
+
/************************************************************************/
/* initialization / cleanup */
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index b92b959fe16e..529886c7a826 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -37,34 +37,22 @@
struct wf_lm75_sensor {
int ds1775 : 1;
int inited : 1;
- struct i2c_client i2c;
+ struct i2c_client *i2c;
struct wf_sensor sens;
};
#define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens)
-#define i2c_to_lm75(c) container_of(c, struct wf_lm75_sensor, i2c)
-
-static int wf_lm75_attach(struct i2c_adapter *adapter);
-static int wf_lm75_detach(struct i2c_client *client);
-
-static struct i2c_driver wf_lm75_driver = {
- .driver = {
- .name = "wf_lm75",
- },
- .attach_adapter = wf_lm75_attach,
- .detach_client = wf_lm75_detach,
-};
static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
{
struct wf_lm75_sensor *lm = wf_to_lm75(sr);
s32 data;
- if (lm->i2c.adapter == NULL)
+ if (lm->i2c == NULL)
return -ENODEV;
/* Init chip if necessary */
if (!lm->inited) {
- u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(&lm->i2c, 1);
+ u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(lm->i2c, 1);
DBG("wf_lm75: Initializing %s, cfg was: %02x\n",
sr->name, cfg);
@@ -73,7 +61,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
* the firmware for now
*/
cfg_new = cfg & ~0x01;
- i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new);
+ i2c_smbus_write_byte_data(lm->i2c, 1, cfg_new);
lm->inited = 1;
/* If we just powered it up, let's wait 200 ms */
@@ -81,7 +69,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
}
/* Read temperature register */
- data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0));
+ data = (s32)le16_to_cpu(i2c_smbus_read_word_data(lm->i2c, 0));
data <<= 8;
*value = data;
@@ -92,12 +80,6 @@ static void wf_lm75_release(struct wf_sensor *sr)
{
struct wf_lm75_sensor *lm = wf_to_lm75(sr);
- /* check if client is registered and detach from i2c */
- if (lm->i2c.adapter) {
- i2c_detach_client(&lm->i2c);
- lm->i2c.adapter = NULL;
- }
-
kfree(lm);
}
@@ -107,59 +89,77 @@ static struct wf_sensor_ops wf_lm75_ops = {
.owner = THIS_MODULE,
};
-static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
- u8 addr, int ds1775,
- const char *loc)
+static int wf_lm75_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct wf_lm75_sensor *lm;
int rc;
- DBG("wf_lm75: creating %s device at address 0x%02x\n",
- ds1775 ? "ds1775" : "lm75", addr);
-
lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL);
if (lm == NULL)
- return NULL;
+ return -ENODEV;
+
+ lm->inited = 0;
+ lm->ds1775 = id->driver_data;
+ lm->i2c = client;
+ lm->sens.name = client->dev.platform_data;
+ lm->sens.ops = &wf_lm75_ops;
+ i2c_set_clientdata(client, lm);
+
+ rc = wf_register_sensor(&lm->sens);
+ if (rc) {
+ i2c_set_clientdata(client, NULL);
+ kfree(lm);
+ }
+
+ return rc;
+}
+
+static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
+ u8 addr, int ds1775,
+ const char *loc)
+{
+ struct i2c_board_info info;
+ struct i2c_client *client;
+ char *name;
+
+ DBG("wf_lm75: creating %s device at address 0x%02x\n",
+ ds1775 ? "ds1775" : "lm75", addr);
/* Usual rant about sensor names not beeing very consistent in
* the device-tree, oh well ...
* Add more entries below as you deal with more setups
*/
if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY"))
- lm->sens.name = "hd-temp";
+ name = "hd-temp";
else if (!strcmp(loc, "Incoming Air Temp"))
- lm->sens.name = "incoming-air-temp";
+ name = "incoming-air-temp";
else if (!strcmp(loc, "ODD Temp"))
- lm->sens.name = "optical-drive-temp";
+ name = "optical-drive-temp";
else if (!strcmp(loc, "HD Temp"))
- lm->sens.name = "hard-drive-temp";
+ name = "hard-drive-temp";
else
goto fail;
- lm->inited = 0;
- lm->sens.ops = &wf_lm75_ops;
- lm->ds1775 = ds1775;
- lm->i2c.addr = (addr >> 1) & 0x7f;
- lm->i2c.adapter = adapter;
- lm->i2c.driver = &wf_lm75_driver;
- strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1);
-
- rc = i2c_attach_client(&lm->i2c);
- if (rc) {
- printk(KERN_ERR "windfarm: failed to attach %s %s to i2c,"
- " err %d\n", ds1775 ? "ds1775" : "lm75",
- lm->i2c.name, rc);
- goto fail;
- }
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = (addr >> 1) & 0x7f;
+ info.platform_data = name;
+ strlcpy(info.type, ds1775 ? "wf_ds1775" : "wf_lm75", I2C_NAME_SIZE);
- if (wf_register_sensor(&lm->sens)) {
- i2c_detach_client(&lm->i2c);
+ client = i2c_new_device(adapter, &info);
+ if (client == NULL) {
+ printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n",
+ ds1775 ? "ds1775" : "lm75", name);
goto fail;
}
- return lm;
+ /*
+ * Let i2c-core delete that device on driver removal.
+ * This is safe because i2c-core holds the core_lock mutex for us.
+ */
+ list_add_tail(&client->detected, &client->driver->clients);
+ return client;
fail:
- kfree(lm);
return NULL;
}
@@ -202,21 +202,38 @@ static int wf_lm75_attach(struct i2c_adapter *adapter)
return 0;
}
-static int wf_lm75_detach(struct i2c_client *client)
+static int wf_lm75_remove(struct i2c_client *client)
{
- struct wf_lm75_sensor *lm = i2c_to_lm75(client);
+ struct wf_lm75_sensor *lm = i2c_get_clientdata(client);
DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name);
/* Mark client detached */
- lm->i2c.adapter = NULL;
+ lm->i2c = NULL;
/* release sensor */
wf_unregister_sensor(&lm->sens);
+ i2c_set_clientdata(client, NULL);
return 0;
}
+static const struct i2c_device_id wf_lm75_id[] = {
+ { "wf_lm75", 0 },
+ { "wf_ds1775", 1 },
+ { }
+};
+
+static struct i2c_driver wf_lm75_driver = {
+ .driver = {
+ .name = "wf_lm75",
+ },
+ .attach_adapter = wf_lm75_attach,
+ .probe = wf_lm75_probe,
+ .remove = wf_lm75_remove,
+ .id_table = wf_lm75_id,
+};
+
static int __init wf_lm75_sensor_init(void)
{
/* Don't register on old machines that use therm_pm72 for now */
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index e207a90d6b27..e2a55ecda2b2 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -26,34 +26,22 @@
#define MAX6690_EXTERNAL_TEMP 1
struct wf_6690_sensor {
- struct i2c_client i2c;
+ struct i2c_client *i2c;
struct wf_sensor sens;
};
#define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens)
-#define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c)
-
-static int wf_max6690_attach(struct i2c_adapter *adapter);
-static int wf_max6690_detach(struct i2c_client *client);
-
-static struct i2c_driver wf_max6690_driver = {
- .driver = {
- .name = "wf_max6690",
- },
- .attach_adapter = wf_max6690_attach,
- .detach_client = wf_max6690_detach,
-};
static int wf_max6690_get(struct wf_sensor *sr, s32 *value)
{
struct wf_6690_sensor *max = wf_to_6690(sr);
s32 data;
- if (max->i2c.adapter == NULL)
+ if (max->i2c == NULL)
return -ENODEV;
/* chip gets initialized by firmware */
- data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP);
+ data = i2c_smbus_read_byte_data(max->i2c, MAX6690_EXTERNAL_TEMP);
if (data < 0)
return data;
*value = data << 16;
@@ -64,10 +52,6 @@ static void wf_max6690_release(struct wf_sensor *sr)
{
struct wf_6690_sensor *max = wf_to_6690(sr);
- if (max->i2c.adapter) {
- i2c_detach_client(&max->i2c);
- max->i2c.adapter = NULL;
- }
kfree(max);
}
@@ -77,19 +61,40 @@ static struct wf_sensor_ops wf_max6690_ops = {
.owner = THIS_MODULE,
};
-static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr,
- const char *loc)
+static int wf_max6690_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct wf_6690_sensor *max;
- char *name;
+ int rc;
max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
if (max == NULL) {
- printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: "
- "no memory\n", loc);
- return;
+ printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: "
+ "no memory\n");
+ return -ENOMEM;
+ }
+
+ max->i2c = client;
+ max->sens.name = client->dev.platform_data;
+ max->sens.ops = &wf_max6690_ops;
+ i2c_set_clientdata(client, max);
+
+ rc = wf_register_sensor(&max->sens);
+ if (rc) {
+ i2c_set_clientdata(client, NULL);
+ kfree(max);
}
+ return rc;
+}
+
+static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
+ u8 addr, const char *loc)
+{
+ struct i2c_board_info info;
+ struct i2c_client *client;
+ char *name;
+
if (!strcmp(loc, "BACKSIDE"))
name = "backside-temp";
else if (!strcmp(loc, "NB Ambient"))
@@ -99,27 +104,26 @@ static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr,
else
goto fail;
- max->sens.ops = &wf_max6690_ops;
- max->sens.name = name;
- max->i2c.addr = addr >> 1;
- max->i2c.adapter = adapter;
- max->i2c.driver = &wf_max6690_driver;
- strncpy(max->i2c.name, name, I2C_NAME_SIZE-1);
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = addr >> 1;
+ info.platform_data = name;
+ strlcpy(info.type, "wf_max6690", I2C_NAME_SIZE);
- if (i2c_attach_client(&max->i2c)) {
+ client = i2c_new_device(adapter, &info);
+ if (client == NULL) {
printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n");
goto fail;
}
- if (wf_register_sensor(&max->sens)) {
- i2c_detach_client(&max->i2c);
- goto fail;
- }
-
- return;
+ /*
+ * Let i2c-core delete that device on driver removal.
+ * This is safe because i2c-core holds the core_lock mutex for us.
+ */
+ list_add_tail(&client->detected, &client->driver->clients);
+ return client;
fail:
- kfree(max);
+ return NULL;
}
static int wf_max6690_attach(struct i2c_adapter *adapter)
@@ -154,16 +158,31 @@ static int wf_max6690_attach(struct i2c_adapter *adapter)
return 0;
}
-static int wf_max6690_detach(struct i2c_client *client)
+static int wf_max6690_remove(struct i2c_client *client)
{
- struct wf_6690_sensor *max = i2c_to_6690(client);
+ struct wf_6690_sensor *max = i2c_get_clientdata(client);
- max->i2c.adapter = NULL;
+ max->i2c = NULL;
wf_unregister_sensor(&max->sens);
return 0;
}
+static const struct i2c_device_id wf_max6690_id[] = {
+ { "wf_max6690", 0 },
+ { }
+};
+
+static struct i2c_driver wf_max6690_driver = {
+ .driver = {
+ .name = "wf_max6690",
+ },
+ .attach_adapter = wf_max6690_attach,
+ .probe = wf_max6690_probe,
+ .remove = wf_max6690_remove,
+ .id_table = wf_max6690_id,
+};
+
static int __init wf_max6690_sensor_init(void)
{
/* Don't register on old machines that use therm_pm72 for now */
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index 7847e981ac33..5da729e58f99 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -39,7 +39,7 @@ struct wf_sat {
struct mutex mutex;
unsigned long last_read; /* jiffies when cache last updated */
u8 cache[16];
- struct i2c_client i2c;
+ struct i2c_client *i2c;
struct device_node *node;
};
@@ -54,18 +54,6 @@ struct wf_sat_sensor {
};
#define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens)
-#define i2c_to_sat(c) container_of(c, struct wf_sat, i2c)
-
-static int wf_sat_attach(struct i2c_adapter *adapter);
-static int wf_sat_detach(struct i2c_client *client);
-
-static struct i2c_driver wf_sat_driver = {
- .driver = {
- .name = "wf_smu_sat",
- },
- .attach_adapter = wf_sat_attach,
- .detach_client = wf_sat_detach,
-};
struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
unsigned int *size)
@@ -81,13 +69,13 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
if (sat_id > 1 || (sat = sats[sat_id]) == NULL)
return NULL;
- err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8);
+ err = i2c_smbus_write_word_data(sat->i2c, 8, id << 8);
if (err) {
printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err);
return NULL;
}
- err = i2c_smbus_read_word_data(&sat->i2c, 9);
+ err = i2c_smbus_read_word_data(sat->i2c, 9);
if (err < 0) {
printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n");
return NULL;
@@ -105,7 +93,7 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
return NULL;
for (i = 0; i < len; i += 4) {
- err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0xa, 4, data);
+ err = i2c_smbus_read_i2c_block_data(sat->i2c, 0xa, 4, data);
if (err < 0) {
printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n",
err);
@@ -138,7 +126,7 @@ static int wf_sat_read_cache(struct wf_sat *sat)
{
int err;
- err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0x3f, 16, sat->cache);
+ err = i2c_smbus_read_i2c_block_data(sat->i2c, 0x3f, 16, sat->cache);
if (err < 0)
return err;
sat->last_read = jiffies;
@@ -161,7 +149,7 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value)
int i, err;
s32 val;
- if (sat->i2c.adapter == NULL)
+ if (sat->i2c == NULL)
return -ENODEV;
mutex_lock(&sat->mutex);
@@ -193,10 +181,6 @@ static void wf_sat_release(struct wf_sensor *sr)
struct wf_sat *sat = sens->sat;
if (atomic_dec_and_test(&sat->refcnt)) {
- if (sat->i2c.adapter) {
- i2c_detach_client(&sat->i2c);
- sat->i2c.adapter = NULL;
- }
if (sat->nr >= 0)
sats[sat->nr] = NULL;
kfree(sat);
@@ -212,38 +196,58 @@ static struct wf_sensor_ops wf_sat_ops = {
static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
{
+ struct i2c_board_info info;
+ struct i2c_client *client;
+ const u32 *reg;
+ u8 addr;
+
+ reg = of_get_property(dev, "reg", NULL);
+ if (reg == NULL)
+ return;
+ addr = *reg;
+ DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr);
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = (addr >> 1) & 0x7f;
+ info.platform_data = dev;
+ strlcpy(info.type, "wf_sat", I2C_NAME_SIZE);
+
+ client = i2c_new_device(adapter, &info);
+ if (client == NULL) {
+ printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n");
+ return;
+ }
+
+ /*
+ * Let i2c-core delete that device on driver removal.
+ * This is safe because i2c-core holds the core_lock mutex for us.
+ */
+ list_add_tail(&client->detected, &client->driver->clients);
+}
+
+static int wf_sat_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device_node *dev = client->dev.platform_data;
struct wf_sat *sat;
struct wf_sat_sensor *sens;
const u32 *reg;
const char *loc, *type;
- u8 addr, chip, core;
+ u8 chip, core;
struct device_node *child;
int shift, cpu, index;
char *name;
int vsens[2], isens[2];
- reg = of_get_property(dev, "reg", NULL);
- if (reg == NULL)
- return;
- addr = *reg;
- DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr);
-
sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL);
if (sat == NULL)
- return;
+ return -ENOMEM;
sat->nr = -1;
sat->node = of_node_get(dev);
atomic_set(&sat->refcnt, 0);
mutex_init(&sat->mutex);
- sat->i2c.addr = (addr >> 1) & 0x7f;
- sat->i2c.adapter = adapter;
- sat->i2c.driver = &wf_sat_driver;
- strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1);
-
- if (i2c_attach_client(&sat->i2c)) {
- printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n");
- goto fail;
- }
+ sat->i2c = client;
+ i2c_set_clientdata(client, sat);
vsens[0] = vsens[1] = -1;
isens[0] = isens[1] = -1;
@@ -344,10 +348,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
if (sat->nr >= 0)
sats[sat->nr] = sat;
- return;
-
- fail:
- kfree(sat);
+ return 0;
}
static int wf_sat_attach(struct i2c_adapter *adapter)
@@ -366,16 +367,32 @@ static int wf_sat_attach(struct i2c_adapter *adapter)
return 0;
}
-static int wf_sat_detach(struct i2c_client *client)
+static int wf_sat_remove(struct i2c_client *client)
{
- struct wf_sat *sat = i2c_to_sat(client);
+ struct wf_sat *sat = i2c_get_clientdata(client);
/* XXX TODO */
- sat->i2c.adapter = NULL;
+ sat->i2c = NULL;
+ i2c_set_clientdata(client, NULL);
return 0;
}
+static const struct i2c_device_id wf_sat_id[] = {
+ { "wf_sat", 0 },
+ { }
+};
+
+static struct i2c_driver wf_sat_driver = {
+ .driver = {
+ .name = "wf_smu_sat",
+ },
+ .attach_adapter = wf_sat_attach,
+ .probe = wf_sat_probe,
+ .remove = wf_sat_remove,
+ .id_table = wf_sat_id,
+};
+
static int __init sat_sensors_init(void)
{
return i2c_add_driver(&wf_sat_driver);
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 1fb91edc7de2..47c68bc75a17 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -986,6 +986,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
oldindex = index;
oldpage = page;
+ bitmap->filemap[bitmap->file_pages++] = page;
+ bitmap->last_page_size = count;
+
if (outofdate) {
/*
* if bitmap is out of date, dirty the
@@ -998,15 +1001,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
write_page(bitmap, page, 1);
ret = -EIO;
- if (bitmap->flags & BITMAP_WRITE_ERROR) {
- /* release, page not in filemap yet */
- put_page(page);
+ if (bitmap->flags & BITMAP_WRITE_ERROR)
goto err;
- }
}
-
- bitmap->filemap[bitmap->file_pages++] = page;
- bitmap->last_page_size = count;
}
paddr = kmap_atomic(page, KM_USER0);
if (bitmap->flags & BITMAP_HOSTENDIAN)
@@ -1016,9 +1013,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
kunmap_atomic(paddr, KM_USER0);
if (b) {
/* if the disk bit is set, set the memory bit */
- bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap),
- ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start)
- );
+ int needed = ((sector_t)(i+1) << (CHUNK_BLOCK_SHIFT(bitmap))
+ >= start);
+ bitmap_set_memory_bits(bitmap,
+ (sector_t)i << CHUNK_BLOCK_SHIFT(bitmap),
+ needed);
bit_cnt++;
set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
}
@@ -1154,8 +1153,9 @@ void bitmap_daemon_work(struct bitmap *bitmap)
spin_lock_irqsave(&bitmap->lock, flags);
clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
}
- bmc = bitmap_get_counter(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap),
- &blocks, 0);
+ bmc = bitmap_get_counter(bitmap,
+ (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap),
+ &blocks, 0);
if (bmc) {
/*
if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc);
@@ -1169,7 +1169,8 @@ void bitmap_daemon_work(struct bitmap *bitmap)
} else if (*bmc == 1) {
/* we can clear the bit */
*bmc = 0;
- bitmap_count_page(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap),
+ bitmap_count_page(bitmap,
+ (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap),
-1);
/* clear the bit */
@@ -1514,7 +1515,7 @@ void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e)
unsigned long chunk;
for (chunk = s; chunk <= e; chunk++) {
- sector_t sec = chunk << CHUNK_BLOCK_SHIFT(bitmap);
+ sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap);
bitmap_set_memory_bits(bitmap, sec, 1);
bitmap_file_set_bit(bitmap, sec);
}
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 53394e863c74..04db6c4004a8 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1132,6 +1132,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad_crypt_queue;
}
+ ti->num_flush_requests = 1;
ti->private = cc;
return 0;
@@ -1189,6 +1190,13 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
union map_info *map_context)
{
struct dm_crypt_io *io;
+ struct crypt_config *cc;
+
+ if (unlikely(bio_empty_barrier(bio))) {
+ cc = ti->private;
+ bio->bi_bdev = cc->dev->bdev;
+ return DM_MAPIO_REMAPPED;
+ }
io = crypt_io_alloc(ti, bio, bio->bi_sector - ti->begin);
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
index 559dbb52bc85..8ad8a9044bbf 100644
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -197,6 +197,7 @@ out:
mutex_init(&dc->timer_lock);
atomic_set(&dc->may_delay, 1);
+ ti->num_flush_requests = 1;
ti->private = dc;
return 0;
@@ -278,8 +279,9 @@ static int delay_map(struct dm_target *ti, struct bio *bio,
if ((bio_data_dir(bio) == WRITE) && (dc->dev_write)) {
bio->bi_bdev = dc->dev_write->bdev;
- bio->bi_sector = dc->start_write +
- (bio->bi_sector - ti->begin);
+ if (bio_sectors(bio))
+ bio->bi_sector = dc->start_write +
+ (bio->bi_sector - ti->begin);
return delay_bio(dc, dc->write_delay, bio);
}
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index e73aabd61cd7..3a2e6a2f8bdd 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -22,6 +22,7 @@ struct dm_io_client {
/* FIXME: can we shrink this ? */
struct io {
unsigned long error_bits;
+ unsigned long eopnotsupp_bits;
atomic_t count;
struct task_struct *sleeper;
struct dm_io_client *client;
@@ -107,8 +108,11 @@ static inline unsigned bio_get_region(struct bio *bio)
*---------------------------------------------------------------*/
static void dec_count(struct io *io, unsigned int region, int error)
{
- if (error)
+ if (error) {
set_bit(region, &io->error_bits);
+ if (error == -EOPNOTSUPP)
+ set_bit(region, &io->eopnotsupp_bits);
+ }
if (atomic_dec_and_test(&io->count)) {
if (io->sleeper)
@@ -360,7 +364,9 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
return -EIO;
}
+retry:
io.error_bits = 0;
+ io.eopnotsupp_bits = 0;
atomic_set(&io.count, 1); /* see dispatch_io() */
io.sleeper = current;
io.client = client;
@@ -377,6 +383,11 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
}
set_current_state(TASK_RUNNING);
+ if (io.eopnotsupp_bits && (rw & (1 << BIO_RW_BARRIER))) {
+ rw &= ~(1 << BIO_RW_BARRIER);
+ goto retry;
+ }
+
if (error_bits)
*error_bits = io.error_bits;
@@ -397,6 +408,7 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions,
io = mempool_alloc(client->pool, GFP_NOIO);
io->error_bits = 0;
+ io->eopnotsupp_bits = 0;
atomic_set(&io->count, 1); /* see dispatch_io() */
io->sleeper = NULL;
io->client = client;
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 79fb53e51c70..ecbb17421da4 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -53,6 +53,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad;
}
+ ti->num_flush_requests = 1;
ti->private = lc;
return 0;
@@ -81,7 +82,8 @@ static void linear_map_bio(struct dm_target *ti, struct bio *bio)
struct linear_c *lc = ti->private;
bio->bi_bdev = lc->dev->bdev;
- bio->bi_sector = linear_map_sector(ti, bio->bi_sector);
+ if (bio_sectors(bio))
+ bio->bi_sector = linear_map_sector(ti, bio->bi_sector);
}
static int linear_map(struct dm_target *ti, struct bio *bio,
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 6a386ab4f7eb..c8dadeb6bca5 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -35,6 +35,7 @@ struct pgpath {
struct dm_path path;
struct work_struct deactivate_path;
+ struct work_struct activate_path;
};
#define path_to_pgpath(__pgp) container_of((__pgp), struct pgpath, path)
@@ -64,8 +65,6 @@ struct multipath {
spinlock_t lock;
const char *hw_handler_name;
- struct work_struct activate_path;
- struct pgpath *pgpath_to_activate;
unsigned nr_priority_groups;
struct list_head priority_groups;
unsigned pg_init_required; /* pg_init needs calling? */
@@ -128,6 +127,7 @@ static struct pgpath *alloc_pgpath(void)
if (pgpath) {
pgpath->is_active = 1;
INIT_WORK(&pgpath->deactivate_path, deactivate_path);
+ INIT_WORK(&pgpath->activate_path, activate_path);
}
return pgpath;
@@ -160,7 +160,6 @@ static struct priority_group *alloc_priority_group(void)
static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
{
- unsigned long flags;
struct pgpath *pgpath, *tmp;
struct multipath *m = ti->private;
@@ -169,10 +168,6 @@ static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
if (m->hw_handler_name)
scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev));
dm_put_device(ti, pgpath->path.dev);
- spin_lock_irqsave(&m->lock, flags);
- if (m->pgpath_to_activate == pgpath)
- m->pgpath_to_activate = NULL;
- spin_unlock_irqrestore(&m->lock, flags);
free_pgpath(pgpath);
}
}
@@ -202,7 +197,6 @@ static struct multipath *alloc_multipath(struct dm_target *ti)
m->queue_io = 1;
INIT_WORK(&m->process_queued_ios, process_queued_ios);
INIT_WORK(&m->trigger_event, trigger_event);
- INIT_WORK(&m->activate_path, activate_path);
m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache);
if (!m->mpio_pool) {
kfree(m);
@@ -427,8 +421,8 @@ static void process_queued_ios(struct work_struct *work)
{
struct multipath *m =
container_of(work, struct multipath, process_queued_ios);
- struct pgpath *pgpath = NULL;
- unsigned init_required = 0, must_queue = 1;
+ struct pgpath *pgpath = NULL, *tmp;
+ unsigned must_queue = 1;
unsigned long flags;
spin_lock_irqsave(&m->lock, flags);
@@ -446,19 +440,15 @@ static void process_queued_ios(struct work_struct *work)
must_queue = 0;
if (m->pg_init_required && !m->pg_init_in_progress && pgpath) {
- m->pgpath_to_activate = pgpath;
m->pg_init_count++;
m->pg_init_required = 0;
- m->pg_init_in_progress = 1;
- init_required = 1;
+ list_for_each_entry(tmp, &pgpath->pg->pgpaths, list) {
+ queue_work(kmpath_handlerd, &tmp->activate_path);
+ m->pg_init_in_progress++;
+ }
}
-
out:
spin_unlock_irqrestore(&m->lock, flags);
-
- if (init_required)
- queue_work(kmpath_handlerd, &m->activate_path);
-
if (!must_queue)
dispatch_queued_ios(m);
}
@@ -553,6 +543,12 @@ static int parse_path_selector(struct arg_set *as, struct priority_group *pg,
return -EINVAL;
}
+ if (ps_argc > as->argc) {
+ dm_put_path_selector(pst);
+ ti->error = "not enough arguments for path selector";
+ return -EINVAL;
+ }
+
r = pst->create(&pg->ps, ps_argc, as->argv);
if (r) {
dm_put_path_selector(pst);
@@ -591,9 +587,20 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
}
if (m->hw_handler_name) {
- r = scsi_dh_attach(bdev_get_queue(p->path.dev->bdev),
- m->hw_handler_name);
+ struct request_queue *q = bdev_get_queue(p->path.dev->bdev);
+
+ r = scsi_dh_attach(q, m->hw_handler_name);
+ if (r == -EBUSY) {
+ /*
+ * Already attached to different hw_handler,
+ * try to reattach with correct one.
+ */
+ scsi_dh_detach(q);
+ r = scsi_dh_attach(q, m->hw_handler_name);
+ }
+
if (r < 0) {
+ ti->error = "error attaching hardware handler";
dm_put_device(ti, p->path.dev);
goto bad;
}
@@ -699,6 +706,11 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m)
if (!hw_argc)
return 0;
+ if (hw_argc > as->argc) {
+ ti->error = "not enough arguments for hardware handler";
+ return -EINVAL;
+ }
+
m->hw_handler_name = kstrdup(shift(as), GFP_KERNEL);
request_module("scsi_dh_%s", m->hw_handler_name);
if (scsi_dh_handler_exist(m->hw_handler_name) == 0) {
@@ -823,6 +835,8 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
goto bad;
}
+ ti->num_flush_requests = 1;
+
return 0;
bad:
@@ -836,6 +850,7 @@ static void multipath_dtr(struct dm_target *ti)
flush_workqueue(kmpath_handlerd);
flush_workqueue(kmultipathd);
+ flush_scheduled_work();
free_multipath(m);
}
@@ -924,9 +939,13 @@ static int reinstate_path(struct pgpath *pgpath)
pgpath->is_active = 1;
- m->current_pgpath = NULL;
- if (!m->nr_valid_paths++ && m->queue_size)
+ if (!m->nr_valid_paths++ && m->queue_size) {
+ m->current_pgpath = NULL;
queue_work(kmultipathd, &m->process_queued_ios);
+ } else if (m->hw_handler_name && (m->current_pg == pgpath->pg)) {
+ m->pg_init_in_progress++;
+ queue_work(kmpath_handlerd, &pgpath->activate_path);
+ }
dm_path_uevent(DM_UEVENT_PATH_REINSTATED, m->ti,
pgpath->path.dev->name, m->nr_valid_paths);
@@ -1102,35 +1121,30 @@ static void pg_init_done(struct dm_path *path, int errors)
spin_lock_irqsave(&m->lock, flags);
if (errors) {
- DMERR("Could not failover device. Error %d.", errors);
- m->current_pgpath = NULL;
- m->current_pg = NULL;
+ if (pgpath == m->current_pgpath) {
+ DMERR("Could not failover device. Error %d.", errors);
+ m->current_pgpath = NULL;
+ m->current_pg = NULL;
+ }
} else if (!m->pg_init_required) {
m->queue_io = 0;
pg->bypassed = 0;
}
- m->pg_init_in_progress = 0;
- queue_work(kmultipathd, &m->process_queued_ios);
+ m->pg_init_in_progress--;
+ if (!m->pg_init_in_progress)
+ queue_work(kmultipathd, &m->process_queued_ios);
spin_unlock_irqrestore(&m->lock, flags);
}
static void activate_path(struct work_struct *work)
{
int ret;
- struct multipath *m =
- container_of(work, struct multipath, activate_path);
- struct dm_path *path;
- unsigned long flags;
+ struct pgpath *pgpath =
+ container_of(work, struct pgpath, activate_path);
- spin_lock_irqsave(&m->lock, flags);
- path = &m->pgpath_to_activate->path;
- m->pgpath_to_activate = NULL;
- spin_unlock_irqrestore(&m->lock, flags);
- if (!path)
- return;
- ret = scsi_dh_activate(bdev_get_queue(path->dev->bdev));
- pg_init_done(path, ret);
+ ret = scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev));
+ pg_init_done(&pgpath->path, ret);
}
/*
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c
index 7b899be0b087..36dbe29f2fd6 100644
--- a/drivers/md/dm-region-hash.c
+++ b/drivers/md/dm-region-hash.c
@@ -283,7 +283,7 @@ static struct dm_region *__rh_alloc(struct dm_region_hash *rh, region_t region)
nreg = mempool_alloc(rh->region_pool, GFP_ATOMIC);
if (unlikely(!nreg))
- nreg = kmalloc(sizeof(*nreg), GFP_NOIO);
+ nreg = kmalloc(sizeof(*nreg), GFP_NOIO | __GFP_NOFAIL);
nreg->state = rh->log->type->in_sync(rh->log, region, 1) ?
DM_RH_CLEAN : DM_RH_NOSYNC;
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index e75c6dd76a9a..9761468aa474 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -636,7 +636,7 @@ static void persistent_commit_exception(struct dm_exception_store *store,
/*
* Commit exceptions to disk.
*/
- if (ps->valid && area_io(ps, WRITE))
+ if (ps->valid && area_io(ps, WRITE_BARRIER))
ps->valid = 0;
/*
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index d73f17fc7778..d573165cd2b7 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -678,6 +678,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
ti->private = s;
ti->split_io = s->store->chunk_size;
+ ti->num_flush_requests = 1;
return 0;
@@ -1030,6 +1031,11 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
chunk_t chunk;
struct dm_snap_pending_exception *pe = NULL;
+ if (unlikely(bio_empty_barrier(bio))) {
+ bio->bi_bdev = s->store->cow->bdev;
+ return DM_MAPIO_REMAPPED;
+ }
+
chunk = sector_to_chunk(s->store, bio->bi_sector);
/* Full snapshots are not usable */
@@ -1338,6 +1344,8 @@ static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
ti->private = dev;
+ ti->num_flush_requests = 1;
+
return 0;
}
@@ -1353,6 +1361,9 @@ static int origin_map(struct dm_target *ti, struct bio *bio,
struct dm_dev *dev = ti->private;
bio->bi_bdev = dev->bdev;
+ if (unlikely(bio_empty_barrier(bio)))
+ return DM_MAPIO_REMAPPED;
+
/* Only tell snapshots if this is a write */
return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED;
}
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 41569bc60abc..c64fe827a5f1 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -167,6 +167,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
sc->stripes = stripes;
sc->stripe_width = width;
ti->split_io = chunk_size;
+ ti->num_flush_requests = stripes;
sc->chunk_mask = ((sector_t) chunk_size) - 1;
for (sc->chunk_shift = 0; chunk_size; sc->chunk_shift++)
@@ -211,10 +212,18 @@ static int stripe_map(struct dm_target *ti, struct bio *bio,
union map_info *map_context)
{
struct stripe_c *sc = (struct stripe_c *) ti->private;
+ sector_t offset, chunk;
+ uint32_t stripe;
- sector_t offset = bio->bi_sector - ti->begin;
- sector_t chunk = offset >> sc->chunk_shift;
- uint32_t stripe = sector_div(chunk, sc->stripes);
+ if (unlikely(bio_empty_barrier(bio))) {
+ BUG_ON(map_context->flush_request >= sc->stripes);
+ bio->bi_bdev = sc->stripe[map_context->flush_request].dev->bdev;
+ return DM_MAPIO_REMAPPED;
+ }
+
+ offset = bio->bi_sector - ti->begin;
+ chunk = offset >> sc->chunk_shift;
+ stripe = sector_div(chunk, sc->stripes);
bio->bi_bdev = sc->stripe[stripe].dev->bdev;
bio->bi_sector = sc->stripe[stripe].physical_start +
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 429b50b975d5..443fd6a1702d 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -384,15 +384,42 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
/*
* If possible, this checks an area of a destination device is valid.
*/
-static int check_device_area(struct dm_dev_internal *dd, sector_t start,
- sector_t len)
+static int device_area_is_valid(struct dm_target *ti, struct block_device *bdev,
+ sector_t start, sector_t len)
{
- sector_t dev_size = dd->dm_dev.bdev->bd_inode->i_size >> SECTOR_SHIFT;
+ sector_t dev_size = bdev->bd_inode->i_size >> SECTOR_SHIFT;
+ unsigned short hardsect_size_sectors = ti->limits.hardsect_size >>
+ SECTOR_SHIFT;
+ char b[BDEVNAME_SIZE];
if (!dev_size)
return 1;
- return ((start < dev_size) && (len <= (dev_size - start)));
+ if ((start >= dev_size) || (start + len > dev_size)) {
+ DMWARN("%s: %s too small for target",
+ dm_device_name(ti->table->md), bdevname(bdev, b));
+ return 0;
+ }
+
+ if (hardsect_size_sectors <= 1)
+ return 1;
+
+ if (start & (hardsect_size_sectors - 1)) {
+ DMWARN("%s: start=%llu not aligned to h/w sector of %s",
+ dm_device_name(ti->table->md),
+ (unsigned long long)start, bdevname(bdev, b));
+ return 0;
+ }
+
+ if (len & (hardsect_size_sectors - 1)) {
+ DMWARN("%s: len=%llu not aligned to h/w sector size %hu of %s",
+ dm_device_name(ti->table->md),
+ (unsigned long long)len,
+ ti->limits.hardsect_size, bdevname(bdev, b));
+ return 0;
+ }
+
+ return 1;
}
/*
@@ -478,14 +505,7 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti,
}
atomic_inc(&dd->count);
- if (!check_device_area(dd, start, len)) {
- DMWARN("device %s too small for target", path);
- dm_put_device(ti, &dd->dm_dev);
- return -EINVAL;
- }
-
*result = &dd->dm_dev;
-
return 0;
}
@@ -553,8 +573,16 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
int r = __table_get_device(ti->table, ti, path,
start, len, mode, result);
- if (!r)
- dm_set_device_limits(ti, (*result)->bdev);
+ if (r)
+ return r;
+
+ dm_set_device_limits(ti, (*result)->bdev);
+
+ if (!device_area_is_valid(ti, (*result)->bdev, start, len)) {
+ dm_put_device(ti, *result);
+ *result = NULL;
+ return -EINVAL;
+ }
return r;
}
@@ -693,6 +721,71 @@ static void check_for_valid_limits(struct io_restrictions *rs)
rs->bounce_pfn = -1;
}
+/*
+ * Impose necessary and sufficient conditions on a devices's table such
+ * that any incoming bio which respects its hardsect_size can be
+ * processed successfully. If it falls across the boundary between
+ * two or more targets, the size of each piece it gets split into must
+ * be compatible with the hardsect_size of the target processing it.
+ */
+static int validate_hardsect_alignment(struct dm_table *table)
+{
+ /*
+ * This function uses arithmetic modulo the hardsect_size
+ * (in units of 512-byte sectors).
+ */
+ unsigned short device_hardsect_size_sects =
+ table->limits.hardsect_size >> SECTOR_SHIFT;
+
+ /*
+ * Offset of the start of the next table entry, mod hardsect_size.
+ */
+ unsigned short next_target_start = 0;
+
+ /*
+ * Given an aligned bio that extends beyond the end of a
+ * target, how many sectors must the next target handle?
+ */
+ unsigned short remaining = 0;
+
+ struct dm_target *uninitialized_var(ti);
+ unsigned i = 0;
+
+ /*
+ * Check each entry in the table in turn.
+ */
+ while (i < dm_table_get_num_targets(table)) {
+ ti = dm_table_get_target(table, i++);
+
+ /*
+ * If the remaining sectors fall entirely within this
+ * table entry are they compatible with its hardsect_size?
+ */
+ if (remaining < ti->len &&
+ remaining & ((ti->limits.hardsect_size >>
+ SECTOR_SHIFT) - 1))
+ break; /* Error */
+
+ next_target_start =
+ (unsigned short) ((next_target_start + ti->len) &
+ (device_hardsect_size_sects - 1));
+ remaining = next_target_start ?
+ device_hardsect_size_sects - next_target_start : 0;
+ }
+
+ if (remaining) {
+ DMWARN("%s: table line %u (start sect %llu len %llu) "
+ "not aligned to hardware sector size %hu",
+ dm_device_name(table->md), i,
+ (unsigned long long) ti->begin,
+ (unsigned long long) ti->len,
+ table->limits.hardsect_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
int dm_table_add_target(struct dm_table *t, const char *type,
sector_t start, sector_t len, char *params)
{
@@ -792,6 +885,10 @@ int dm_table_complete(struct dm_table *t)
check_for_valid_limits(&t->limits);
+ r = validate_hardsect_alignment(t);
+ if (r)
+ return r;
+
/* how many indexes will the btree have ? */
leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE);
t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 424f7b048c30..7b73ebc83207 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -159,13 +159,16 @@ struct mapped_device {
* freeze/thaw support require holding onto a super block
*/
struct super_block *frozen_sb;
- struct block_device *suspended_bdev;
+ struct block_device *bdev;
/* forced geometry settings */
struct hd_geometry geometry;
/* sysfs handle */
struct kobject kobj;
+
+ /* zero-length barrier that will be cloned and submitted to targets */
+ struct bio barrier_bio;
};
#define MIN_IOS 256
@@ -393,11 +396,6 @@ static void free_io(struct mapped_device *md, struct dm_io *io)
mempool_free(io, md->io_pool);
}
-static struct dm_target_io *alloc_tio(struct mapped_device *md)
-{
- return mempool_alloc(md->tio_pool, GFP_NOIO);
-}
-
static void free_tio(struct mapped_device *md, struct dm_target_io *tio)
{
mempool_free(tio, md->tio_pool);
@@ -538,9 +536,11 @@ static void dec_pending(struct dm_io *io, int error)
* Target requested pushing back the I/O.
*/
spin_lock_irqsave(&md->deferred_lock, flags);
- if (__noflush_suspending(md))
- bio_list_add_head(&md->deferred, io->bio);
- else
+ if (__noflush_suspending(md)) {
+ if (!bio_barrier(io->bio))
+ bio_list_add_head(&md->deferred,
+ io->bio);
+ } else
/* noflush suspend was interrupted. */
io->error = -EIO;
spin_unlock_irqrestore(&md->deferred_lock, flags);
@@ -555,7 +555,8 @@ static void dec_pending(struct dm_io *io, int error)
* a per-device variable for error reporting.
* Note that you can't touch the bio after end_io_acct
*/
- md->barrier_error = io_error;
+ if (!md->barrier_error && io_error != -EOPNOTSUPP)
+ md->barrier_error = io_error;
end_io_acct(io);
} else {
end_io_acct(io);
@@ -636,11 +637,6 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
sector_t sector;
struct mapped_device *md;
- /*
- * Sanity checks.
- */
- BUG_ON(!clone->bi_size);
-
clone->bi_end_io = clone_endio;
clone->bi_private = tio;
@@ -656,8 +652,7 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
/* the bio has been remapped so dispatch it */
trace_block_remap(bdev_get_queue(clone->bi_bdev), clone,
- tio->io->bio->bi_bdev->bd_dev,
- clone->bi_sector, sector);
+ tio->io->bio->bi_bdev->bd_dev, sector);
generic_make_request(clone);
} else if (r < 0 || r == DM_MAPIO_REQUEUE) {
@@ -755,6 +750,48 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector,
return clone;
}
+static struct dm_target_io *alloc_tio(struct clone_info *ci,
+ struct dm_target *ti)
+{
+ struct dm_target_io *tio = mempool_alloc(ci->md->tio_pool, GFP_NOIO);
+
+ tio->io = ci->io;
+ tio->ti = ti;
+ memset(&tio->info, 0, sizeof(tio->info));
+
+ return tio;
+}
+
+static void __flush_target(struct clone_info *ci, struct dm_target *ti,
+ unsigned flush_nr)
+{
+ struct dm_target_io *tio = alloc_tio(ci, ti);
+ struct bio *clone;
+
+ tio->info.flush_request = flush_nr;
+
+ clone = bio_alloc_bioset(GFP_NOIO, 0, ci->md->bs);
+ __bio_clone(clone, ci->bio);
+ clone->bi_destructor = dm_bio_destructor;
+
+ __map_bio(ti, clone, tio);
+}
+
+static int __clone_and_map_empty_barrier(struct clone_info *ci)
+{
+ unsigned target_nr = 0, flush_nr;
+ struct dm_target *ti;
+
+ while ((ti = dm_table_get_target(ci->map, target_nr++)))
+ for (flush_nr = 0; flush_nr < ti->num_flush_requests;
+ flush_nr++)
+ __flush_target(ci, ti, flush_nr);
+
+ ci->sector_count = 0;
+
+ return 0;
+}
+
static int __clone_and_map(struct clone_info *ci)
{
struct bio *clone, *bio = ci->bio;
@@ -762,6 +799,9 @@ static int __clone_and_map(struct clone_info *ci)
sector_t len = 0, max;
struct dm_target_io *tio;
+ if (unlikely(bio_empty_barrier(bio)))
+ return __clone_and_map_empty_barrier(ci);
+
ti = dm_table_find_target(ci->map, ci->sector);
if (!dm_target_is_valid(ti))
return -EIO;
@@ -771,10 +811,7 @@ static int __clone_and_map(struct clone_info *ci)
/*
* Allocate a target io object.
*/
- tio = alloc_tio(ci->md);
- tio->io = ci->io;
- tio->ti = ti;
- memset(&tio->info, 0, sizeof(tio->info));
+ tio = alloc_tio(ci, ti);
if (ci->sector_count <= max) {
/*
@@ -830,10 +867,7 @@ static int __clone_and_map(struct clone_info *ci)
max = max_io_len(ci->md, ci->sector, ti);
- tio = alloc_tio(ci->md);
- tio->io = ci->io;
- tio->ti = ti;
- memset(&tio->info, 0, sizeof(tio->info));
+ tio = alloc_tio(ci, ti);
}
len = min(remaining, max);
@@ -868,7 +902,8 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
if (!bio_barrier(bio))
bio_io_error(bio);
else
- md->barrier_error = -EIO;
+ if (!md->barrier_error)
+ md->barrier_error = -EIO;
return;
}
@@ -881,6 +916,8 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
ci.io->md = md;
ci.sector = bio->bi_sector;
ci.sector_count = bio_sectors(bio);
+ if (unlikely(bio_empty_barrier(bio)))
+ ci.sector_count = 1;
ci.idx = bio->bi_idx;
start_io_acct(ci.io);
@@ -1173,6 +1210,10 @@ static struct mapped_device *alloc_dev(int minor)
if (!md->wq)
goto bad_thread;
+ md->bdev = bdget_disk(md->disk, 0);
+ if (!md->bdev)
+ goto bad_bdev;
+
/* Populate the mapping, nobody knows we exist yet */
spin_lock(&_minor_lock);
old_md = idr_replace(&_minor_idr, md, minor);
@@ -1182,6 +1223,8 @@ static struct mapped_device *alloc_dev(int minor)
return md;
+bad_bdev:
+ destroy_workqueue(md->wq);
bad_thread:
put_disk(md->disk);
bad_disk:
@@ -1207,10 +1250,8 @@ static void free_dev(struct mapped_device *md)
{
int minor = MINOR(disk_devt(md->disk));
- if (md->suspended_bdev) {
- unlock_fs(md);
- bdput(md->suspended_bdev);
- }
+ unlock_fs(md);
+ bdput(md->bdev);
destroy_workqueue(md->wq);
mempool_destroy(md->tio_pool);
mempool_destroy(md->io_pool);
@@ -1252,9 +1293,9 @@ static void __set_size(struct mapped_device *md, sector_t size)
{
set_capacity(md->disk, size);
- mutex_lock(&md->suspended_bdev->bd_inode->i_mutex);
- i_size_write(md->suspended_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT);
- mutex_unlock(&md->suspended_bdev->bd_inode->i_mutex);
+ mutex_lock(&md->bdev->bd_inode->i_mutex);
+ i_size_write(md->bdev->bd_inode, (loff_t)size << SECTOR_SHIFT);
+ mutex_unlock(&md->bdev->bd_inode->i_mutex);
}
static int __bind(struct mapped_device *md, struct dm_table *t)
@@ -1270,8 +1311,7 @@ static int __bind(struct mapped_device *md, struct dm_table *t)
if (size != get_capacity(md->disk))
memset(&md->geometry, 0, sizeof(md->geometry));
- if (md->suspended_bdev)
- __set_size(md, size);
+ __set_size(md, size);
if (!size) {
dm_table_destroy(t);
@@ -1429,34 +1469,36 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
return r;
}
-static int dm_flush(struct mapped_device *md)
+static void dm_flush(struct mapped_device *md)
{
dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
- return 0;
+
+ bio_init(&md->barrier_bio);
+ md->barrier_bio.bi_bdev = md->bdev;
+ md->barrier_bio.bi_rw = WRITE_BARRIER;
+ __split_and_process_bio(md, &md->barrier_bio);
+
+ dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
}
static void process_barrier(struct mapped_device *md, struct bio *bio)
{
- int error = dm_flush(md);
+ md->barrier_error = 0;
- if (unlikely(error)) {
- bio_endio(bio, error);
- return;
- }
- if (bio_empty_barrier(bio)) {
- bio_endio(bio, 0);
- return;
- }
+ dm_flush(md);
- __split_and_process_bio(md, bio);
-
- error = dm_flush(md);
-
- if (!error && md->barrier_error)
- error = md->barrier_error;
+ if (!bio_empty_barrier(bio)) {
+ __split_and_process_bio(md, bio);
+ dm_flush(md);
+ }
if (md->barrier_error != DM_ENDIO_REQUEUE)
- bio_endio(bio, error);
+ bio_endio(bio, md->barrier_error);
+ else {
+ spin_lock_irq(&md->deferred_lock);
+ bio_list_add_head(&md->deferred, bio);
+ spin_unlock_irq(&md->deferred_lock);
+ }
}
/*
@@ -1513,11 +1555,6 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table)
if (!dm_suspended(md))
goto out;
- /* without bdev, the device size cannot be changed */
- if (!md->suspended_bdev)
- if (get_capacity(md->disk) != dm_table_get_size(table))
- goto out;
-
__unbind(md);
r = __bind(md, table);
@@ -1536,7 +1573,7 @@ static int lock_fs(struct mapped_device *md)
WARN_ON(md->frozen_sb);
- md->frozen_sb = freeze_bdev(md->suspended_bdev);
+ md->frozen_sb = freeze_bdev(md->bdev);
if (IS_ERR(md->frozen_sb)) {
r = PTR_ERR(md->frozen_sb);
md->frozen_sb = NULL;
@@ -1545,9 +1582,6 @@ static int lock_fs(struct mapped_device *md)
set_bit(DMF_FROZEN, &md->flags);
- /* don't bdput right now, we don't want the bdev
- * to go away while it is locked.
- */
return 0;
}
@@ -1556,7 +1590,7 @@ static void unlock_fs(struct mapped_device *md)
if (!test_bit(DMF_FROZEN, &md->flags))
return;
- thaw_bdev(md->suspended_bdev, md->frozen_sb);
+ thaw_bdev(md->bdev, md->frozen_sb);
md->frozen_sb = NULL;
clear_bit(DMF_FROZEN, &md->flags);
}
@@ -1594,24 +1628,14 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
/* This does not get reverted if there's an error later. */
dm_table_presuspend_targets(map);
- /* bdget() can stall if the pending I/Os are not flushed */
- if (!noflush) {
- md->suspended_bdev = bdget_disk(md->disk, 0);
- if (!md->suspended_bdev) {
- DMWARN("bdget failed in dm_suspend");
- r = -ENOMEM;
+ /*
+ * Flush I/O to the device. noflush supersedes do_lockfs,
+ * because lock_fs() needs to flush I/Os.
+ */
+ if (!noflush && do_lockfs) {
+ r = lock_fs(md);
+ if (r)
goto out;
- }
-
- /*
- * Flush I/O to the device. noflush supersedes do_lockfs,
- * because lock_fs() needs to flush I/Os.
- */
- if (do_lockfs) {
- r = lock_fs(md);
- if (r)
- goto out;
- }
}
/*
@@ -1668,11 +1692,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
set_bit(DMF_SUSPENDED, &md->flags);
out:
- if (r && md->suspended_bdev) {
- bdput(md->suspended_bdev);
- md->suspended_bdev = NULL;
- }
-
dm_table_put(map);
out_unlock:
@@ -1701,11 +1720,6 @@ int dm_resume(struct mapped_device *md)
unlock_fs(md);
- if (md->suspended_bdev) {
- bdput(md->suspended_bdev);
- md->suspended_bdev = NULL;
- }
-
clear_bit(DMF_SUSPENDED, &md->flags);
dm_table_unplug_all(map);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 612343fdde94..fccc8343a250 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3066,11 +3066,8 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
} else
err = -EBUSY;
spin_unlock_irq(&mddev->write_lock);
- } else {
- mddev->ro = 0;
- mddev->recovery_cp = MaxSector;
- err = do_md_run(mddev);
- }
+ } else
+ err = -EINVAL;
break;
case active:
if (mddev->pers) {
@@ -4297,6 +4294,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
{
int err = 0;
struct gendisk *disk = mddev->gendisk;
+ mdk_rdev_t *rdev;
if (atomic_read(&mddev->openers) > is_open) {
printk("md: %s still in use.\n",mdname(mddev));
@@ -4339,6 +4337,13 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
/* tell userspace to handle 'inactive' */
sysfs_notify_dirent(mddev->sysfs_state);
+ list_for_each_entry(rdev, &mddev->disks, same_set)
+ if (rdev->raid_disk >= 0) {
+ char nm[20];
+ sprintf(nm, "rd%d", rdev->raid_disk);
+ sysfs_remove_link(&mddev->kobj, nm);
+ }
+
set_capacity(disk, 0);
mddev->changed = 1;
@@ -4359,7 +4364,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
* Free resources if final stop
*/
if (mode == 0) {
- mdk_rdev_t *rdev;
printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
@@ -4371,13 +4375,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
}
mddev->bitmap_offset = 0;
- list_for_each_entry(rdev, &mddev->disks, same_set)
- if (rdev->raid_disk >= 0) {
- char nm[20];
- sprintf(nm, "rd%d", rdev->raid_disk);
- sysfs_remove_link(&mddev->kobj, nm);
- }
-
/* make sure all md_delayed_delete calls have finished */
flush_scheduled_work();
@@ -5705,37 +5702,38 @@ static void status_unused(struct seq_file *seq)
static void status_resync(struct seq_file *seq, mddev_t * mddev)
{
- sector_t max_blocks, resync, res;
- unsigned long dt, db, rt;
+ sector_t max_sectors, resync, res;
+ unsigned long dt, db;
+ sector_t rt;
int scale;
unsigned int per_milli;
- resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active))/2;
+ resync = mddev->curr_resync - atomic_read(&mddev->recovery_active);
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
- max_blocks = mddev->resync_max_sectors >> 1;
+ max_sectors = mddev->resync_max_sectors;
else
- max_blocks = mddev->dev_sectors / 2;
+ max_sectors = mddev->dev_sectors;
/*
* Should not happen.
*/
- if (!max_blocks) {
+ if (!max_sectors) {
MD_BUG();
return;
}
/* Pick 'scale' such that (resync>>scale)*1000 will fit
- * in a sector_t, and (max_blocks>>scale) will fit in a
+ * in a sector_t, and (max_sectors>>scale) will fit in a
* u32, as those are the requirements for sector_div.
* Thus 'scale' must be at least 10
*/
scale = 10;
if (sizeof(sector_t) > sizeof(unsigned long)) {
- while ( max_blocks/2 > (1ULL<<(scale+32)))
+ while ( max_sectors/2 > (1ULL<<(scale+32)))
scale++;
}
res = (resync>>scale)*1000;
- sector_div(res, (u32)((max_blocks>>scale)+1));
+ sector_div(res, (u32)((max_sectors>>scale)+1));
per_milli = res;
{
@@ -5756,25 +5754,35 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev)
(test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ?
"resync" : "recovery"))),
per_milli/10, per_milli % 10,
- (unsigned long long) resync,
- (unsigned long long) max_blocks);
+ (unsigned long long) resync/2,
+ (unsigned long long) max_sectors/2);
/*
- * We do not want to overflow, so the order of operands and
- * the * 100 / 100 trick are important. We do a +1 to be
- * safe against division by zero. We only estimate anyway.
- *
* dt: time from mark until now
* db: blocks written from mark until now
* rt: remaining time
+ *
+ * rt is a sector_t, so could be 32bit or 64bit.
+ * So we divide before multiply in case it is 32bit and close
+ * to the limit.
+ * We scale the divisor (db) by 32 to avoid loosing precision
+ * near the end of resync when the number of remaining sectors
+ * is close to 'db'.
+ * We then divide rt by 32 after multiplying by db to compensate.
+ * The '+1' avoids division by zero if db is very small.
*/
dt = ((jiffies - mddev->resync_mark) / HZ);
if (!dt) dt++;
db = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active))
- mddev->resync_mark_cnt;
- rt = (dt * ((unsigned long)(max_blocks-resync) / (db/2/100+1)))/100;
- seq_printf(seq, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
+ rt = max_sectors - resync; /* number of remaining sectors */
+ sector_div(rt, db/32+1);
+ rt *= dt;
+ rt >>= 5;
+
+ seq_printf(seq, " finish=%lu.%lumin", (unsigned long)rt / 60,
+ ((unsigned long)rt % 60)/6);
seq_printf(seq, " speed=%ldK/sec", db/2/dt);
}
@@ -5965,7 +5973,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
return 0;
}
-static struct seq_operations md_seq_ops = {
+static const struct seq_operations md_seq_ops = {
.start = md_seq_start,
.next = md_seq_next,
.stop = md_seq_stop,
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 81a54f17417e..499620afb44b 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1809,17 +1809,17 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
r10_bio->sector = sect;
raid10_find_phys(conf, r10_bio);
- /* Need to check if this section will still be
+
+ /* Need to check if the array will still be
* degraded
*/
- for (j=0; j<conf->copies;j++) {
- int d = r10_bio->devs[j].devnum;
- if (conf->mirrors[d].rdev == NULL ||
- test_bit(Faulty, &conf->mirrors[d].rdev->flags)) {
+ for (j=0; j<conf->raid_disks; j++)
+ if (conf->mirrors[j].rdev == NULL ||
+ test_bit(Faulty, &conf->mirrors[j].rdev->flags)) {
still_degraded = 1;
break;
}
- }
+
must_sync = bitmap_start_sync(mddev->bitmap, sect,
&sync_blocks, still_degraded);
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 53bfc8e42fb9..965d7bd1b76c 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -40,7 +40,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static DEFINE_MUTEX(af9015_usb_mutex);
static struct af9015_config af9015_config;
-static struct dvb_usb_device_properties af9015_properties[2];
+static struct dvb_usb_device_properties af9015_properties[3];
static int af9015_properties_count = ARRAY_SIZE(af9015_properties);
static struct af9013_config af9015_af9013_config[] = {
@@ -1261,7 +1261,9 @@ static struct usb_device_id af9015_usb_table[] = {
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
{USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
- {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
+/* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
+ {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)},
+ {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
{0},
};
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1321,7 +1323,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.i2c_algo = &af9015_i2c_algo,
- .num_device_descs = 9,
+ .num_device_descs = 9, /* max 9 */
.devices = {
{
.name = "Afatech AF9015 DVB-T USB2.0 stick",
@@ -1426,7 +1428,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.i2c_algo = &af9015_i2c_algo,
- .num_device_descs = 9,
+ .num_device_descs = 9, /* max 9 */
.devices = {
{
.name = "Xtensions XD-380",
@@ -1478,7 +1480,75 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.warm_ids = {NULL},
},
}
- }
+ }, {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .download_firmware = af9015_download_firmware,
+ .firmware = "dvb-usb-af9015.fw",
+ .no_reconnect = 1,
+
+ .size_of_priv = sizeof(struct af9015_state), \
+
+ .num_adapters = 2,
+ .adapter = {
+ {
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+ .pid_filter_count = 32,
+ .pid_filter = af9015_pid_filter,
+ .pid_filter_ctrl = af9015_pid_filter_ctrl,
+
+ .frontend_attach =
+ af9015_af9013_frontend_attach,
+ .tuner_attach = af9015_tuner_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 6,
+ .endpoint = 0x84,
+ },
+ },
+ {
+ .frontend_attach =
+ af9015_af9013_frontend_attach,
+ .tuner_attach = af9015_tuner_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 6,
+ .endpoint = 0x85,
+ .u = {
+ .bulk = {
+ .buffersize =
+ TS_USB20_MAX_PACKET_SIZE,
+ }
+ }
+ },
+ }
+ },
+
+ .identify_state = af9015_identify_state,
+
+ .rc_query = af9015_rc_query,
+ .rc_interval = 150,
+
+ .i2c_algo = &af9015_i2c_algo,
+
+ .num_device_descs = 2, /* max 9 */
+ .devices = {
+ {
+ .name = "AverMedia AVerTV Volar GPS 805 (A805)",
+ .cold_ids = {&af9015_usb_table[21], NULL},
+ .warm_ids = {NULL},
+ },
+ {
+ .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \
+ "V3.0",
+ .cold_ids = {&af9015_usb_table[22], NULL},
+ .warm_ids = {NULL},
+ },
+ }
+ },
};
static int af9015_usb_probe(struct usb_interface *intf,
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 8ddbadf62194..6251b384fb53 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1493,6 +1493,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) },
{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) },
+/* 50 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_Dlx) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1692,7 +1693,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 11,
+ .num_device_descs = 12,
.devices = {
{ "DiBcom STK7070P reference design",
{ &dib0700_usb_id_table[15], NULL },
@@ -1738,6 +1739,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[45], NULL },
{ NULL },
},
+ { "Elgato EyeTV Dtt Dlx PD378S",
+ { &dib0700_usb_id_table[50], NULL },
+ { NULL },
+ },
},
.rc_interval = DEFAULT_RC_INTERVAL,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index f506c74119f3..6a4062d5d0af 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -80,6 +80,7 @@
#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
#define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78
#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80
+#define USB_PID_CONCEPTRONIC_CTVDIGRCU 0xe397
#define USB_PID_CONEXANT_D680_DMB 0x86d6
#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
@@ -171,6 +172,7 @@
#define USB_PID_AVERMEDIA_A309 0xa309
#define USB_PID_AVERMEDIA_A310 0xa310
#define USB_PID_AVERMEDIA_A850 0x850a
+#define USB_PID_AVERMEDIA_A805 0xa805
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
@@ -251,5 +253,6 @@
#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
#define USB_PID_SONY_PLAYTV 0x0003
#define USB_PID_ELGATO_EYETV_DTT 0x0021
+#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 2d5352e54dc0..97495154f746 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -223,7 +223,7 @@ struct dvb_usb_device_properties {
int generic_bulk_ctrl_endpoint;
int num_device_descs;
- struct dvb_usb_device_description devices[11];
+ struct dvb_usb_device_description devices[12];
};
/**
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 23e4cffeba38..be967ac09a39 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -35,6 +35,21 @@ config DVB_STB6100
A Silicon tuner from ST used in conjunction with the STB0899
demodulator. Say Y when you want to support this tuner.
+config DVB_STV090x
+ tristate "STV0900/STV0903(A/B) based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
+ Say Y when you want to support these frontends.
+
+config DVB_STV6110x
+ tristate "STV6110/(A) based tuners"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A Silicon tuner that supports DVB-S and DVB-S2 modes
+
comment "DVB-S (satellite) frontends"
depends on DVB_CORE
@@ -506,6 +521,13 @@ config DVB_ISL6421
help
An SEC control chip.
+config DVB_ISL6423
+ tristate "ISL6423 SEC controller"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A SEC controller chip from Intersil
+
config DVB_LGS8GL5
tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
depends on DVB_CORE && I2C
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index bc2b00abd106..832473c1e512 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -71,4 +71,6 @@ obj-$(CONFIG_DVB_STB6000) += stb6000.o
obj-$(CONFIG_DVB_S921) += s921.o
obj-$(CONFIG_DVB_STV6110) += stv6110.o
obj-$(CONFIG_DVB_STV0900) += stv0900.o
-
+obj-$(CONFIG_DVB_STV090x) += stv090x.o
+obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
+obj-$(CONFIG_DVB_ISL6423) += isl6423.o
diff --git a/drivers/media/dvb/frontends/isl6423.c b/drivers/media/dvb/frontends/isl6423.c
new file mode 100644
index 000000000000..dca5bebfeeb5
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6423.c
@@ -0,0 +1,308 @@
+/*
+ Intersil ISL6423 SEC and LNB Power supply controller
+
+ Copyright (C) Manu Abraham <abraham.manu@gmail.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "isl6423.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+
+#define FE_ERROR 0
+#define FE_NOTICE 1
+#define FE_INFO 2
+#define FE_DEBUG 3
+#define FE_DEBUGREG 4
+
+#define dprintk(__y, __z, format, arg...) do { \
+ if (__z) { \
+ if ((verbose > FE_ERROR) && (verbose > __y)) \
+ printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
+ else if ((verbose > FE_NOTICE) && (verbose > __y)) \
+ printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
+ else if ((verbose > FE_INFO) && (verbose > __y)) \
+ printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
+ else if ((verbose > FE_DEBUG) && (verbose > __y)) \
+ printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
+ } else { \
+ if (verbose > __y) \
+ printk(format, ##arg); \
+ } \
+} while (0)
+
+struct isl6423_dev {
+ const struct isl6423_config *config;
+ struct i2c_adapter *i2c;
+
+ u8 reg_3;
+ u8 reg_4;
+
+ unsigned int verbose;
+};
+
+static int isl6423_write(struct isl6423_dev *isl6423, u8 reg)
+{
+ struct i2c_adapter *i2c = isl6423->i2c;
+ u8 addr = isl6423->config->addr;
+ int err = 0;
+
+ struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = &reg, .len = 1 };
+
+ dprintk(FE_DEBUG, 1, "write reg %02X", reg);
+ err = i2c_transfer(i2c, &msg, 1);
+ if (err < 0)
+ goto exit;
+ return 0;
+
+exit:
+ dprintk(FE_ERROR, 1, "I/O error <%d>", err);
+ return err;
+}
+
+static int isl6423_set_modulation(struct dvb_frontend *fe)
+{
+ struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
+ const struct isl6423_config *config = isl6423->config;
+ int err = 0;
+ u8 reg_2 = 0;
+
+ reg_2 = 0x01 << 5;
+
+ if (config->mod_extern)
+ reg_2 |= (1 << 3);
+ else
+ reg_2 |= (1 << 4);
+
+ err = isl6423_write(isl6423, reg_2);
+ if (err < 0)
+ goto exit;
+ return 0;
+
+exit:
+ dprintk(FE_ERROR, 1, "I/O error <%d>", err);
+ return err;
+}
+
+static int isl6423_voltage_boost(struct dvb_frontend *fe, long arg)
+{
+ struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
+ u8 reg_3 = isl6423->reg_3;
+ u8 reg_4 = isl6423->reg_4;
+ int err = 0;
+
+ if (arg) {
+ /* EN = 1, VSPEN = 1, VBOT = 1 */
+ reg_4 |= (1 << 4);
+ reg_4 |= 0x1;
+ reg_3 |= (1 << 3);
+ } else {
+ /* EN = 1, VSPEN = 1, VBOT = 0 */
+ reg_4 |= (1 << 4);
+ reg_4 &= ~0x1;
+ reg_3 |= (1 << 3);
+ }
+ err = isl6423_write(isl6423, reg_3);
+ if (err < 0)
+ goto exit;
+
+ err = isl6423_write(isl6423, reg_4);
+ if (err < 0)
+ goto exit;
+
+ isl6423->reg_3 = reg_3;
+ isl6423->reg_4 = reg_4;
+
+ return 0;
+exit:
+ dprintk(FE_ERROR, 1, "I/O error <%d>", err);
+ return err;
+}
+
+
+static int isl6423_set_voltage(struct dvb_frontend *fe,
+ enum fe_sec_voltage voltage)
+{
+ struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
+ u8 reg_3 = isl6423->reg_3;
+ u8 reg_4 = isl6423->reg_4;
+ int err = 0;
+
+ switch (voltage) {
+ case SEC_VOLTAGE_OFF:
+ /* EN = 0 */
+ reg_4 &= ~(1 << 4);
+ break;
+
+ case SEC_VOLTAGE_13:
+ /* EN = 1, VSPEN = 1, VTOP = 0, VBOT = 0 */
+ reg_4 |= (1 << 4);
+ reg_4 &= ~0x3;
+ reg_3 |= (1 << 3);
+ break;
+
+ case SEC_VOLTAGE_18:
+ /* EN = 1, VSPEN = 1, VTOP = 1, VBOT = 0 */
+ reg_4 |= (1 << 4);
+ reg_4 |= 0x2;
+ reg_4 &= ~0x1;
+ reg_3 |= (1 << 3);
+ break;
+
+ default:
+ break;
+ }
+ err = isl6423_write(isl6423, reg_3);
+ if (err < 0)
+ goto exit;
+
+ err = isl6423_write(isl6423, reg_4);
+ if (err < 0)
+ goto exit;
+
+ isl6423->reg_3 = reg_3;
+ isl6423->reg_4 = reg_4;
+
+ return 0;
+exit:
+ dprintk(FE_ERROR, 1, "I/O error <%d>", err);
+ return err;
+}
+
+static int isl6423_set_current(struct dvb_frontend *fe)
+{
+ struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
+ u8 reg_3 = isl6423->reg_3;
+ const struct isl6423_config *config = isl6423->config;
+ int err = 0;
+
+ switch (config->current_max) {
+ case SEC_CURRENT_275m:
+ /* 275mA */
+ /* ISELH = 0, ISELL = 0 */
+ reg_3 &= ~0x3;
+ break;
+
+ case SEC_CURRENT_515m:
+ /* 515mA */
+ /* ISELH = 0, ISELL = 1 */
+ reg_3 &= ~0x2;
+ reg_3 |= 0x1;
+ break;
+
+ case SEC_CURRENT_635m:
+ /* 635mA */
+ /* ISELH = 1, ISELL = 0 */
+ reg_3 &= ~0x1;
+ reg_3 |= 0x2;
+ break;
+
+ case SEC_CURRENT_800m:
+ /* 800mA */
+ /* ISELH = 1, ISELL = 1 */
+ reg_3 |= 0x3;
+ break;
+ }
+
+ err = isl6423_write(isl6423, reg_3);
+ if (err < 0)
+ goto exit;
+
+ switch (config->curlim) {
+ case SEC_CURRENT_LIM_ON:
+ /* DCL = 0 */
+ reg_3 &= ~0x10;
+ break;
+
+ case SEC_CURRENT_LIM_OFF:
+ /* DCL = 1 */
+ reg_3 |= 0x10;
+ break;
+ }
+
+ err = isl6423_write(isl6423, reg_3);
+ if (err < 0)
+ goto exit;
+
+ isl6423->reg_3 = reg_3;
+
+ return 0;
+exit:
+ dprintk(FE_ERROR, 1, "I/O error <%d>", err);
+ return err;
+}
+
+static void isl6423_release(struct dvb_frontend *fe)
+{
+ isl6423_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+ kfree(fe->sec_priv);
+ fe->sec_priv = NULL;
+}
+
+struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
+ const struct isl6423_config *config)
+{
+ struct isl6423_dev *isl6423;
+
+ isl6423 = kzalloc(sizeof(struct isl6423_dev), GFP_KERNEL);
+ if (!isl6423)
+ return NULL;
+
+ isl6423->config = config;
+ isl6423->i2c = i2c;
+ fe->sec_priv = isl6423;
+
+ /* SR3H = 0, SR3M = 1, SR3L = 0 */
+ isl6423->reg_3 = 0x02 << 5;
+ /* SR4H = 0, SR4M = 1, SR4L = 1 */
+ isl6423->reg_4 = 0x03 << 5;
+
+ if (isl6423_set_current(fe))
+ goto exit;
+
+ if (isl6423_set_modulation(fe))
+ goto exit;
+
+ fe->ops.release_sec = isl6423_release;
+ fe->ops.set_voltage = isl6423_set_voltage;
+ fe->ops.enable_high_lnb_voltage = isl6423_voltage_boost;
+ isl6423->verbose = verbose;
+
+ return fe;
+
+exit:
+ kfree(isl6423);
+ fe->sec_priv = NULL;
+ return NULL;
+}
+EXPORT_SYMBOL(isl6423_attach);
+
+MODULE_DESCRIPTION("ISL6423 SEC");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/isl6423.h b/drivers/media/dvb/frontends/isl6423.h
new file mode 100644
index 000000000000..e1a37fba01ca
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6423.h
@@ -0,0 +1,63 @@
+/*
+ Intersil ISL6423 SEC and LNB Power supply controller
+
+ Copyright (C) Manu Abraham <abraham.manu@gmail.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __ISL_6423_H
+#define __ISL_6423_H
+
+#include <linux/dvb/frontend.h>
+
+enum isl6423_current {
+ SEC_CURRENT_275m = 0,
+ SEC_CURRENT_515m,
+ SEC_CURRENT_635m,
+ SEC_CURRENT_800m,
+};
+
+enum isl6423_curlim {
+ SEC_CURRENT_LIM_ON = 1,
+ SEC_CURRENT_LIM_OFF
+};
+
+struct isl6423_config {
+ enum isl6423_current current_max;
+ enum isl6423_curlim curlim;
+ u8 addr;
+ u8 mod_extern;
+};
+
+#if defined(CONFIG_DVB_ISL6423) || (defined(CONFIG_DVB_ISL6423_MODULE) && defined(MODULE))
+
+
+extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
+ const struct isl6423_config *config);
+
+#else
+static inline struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
+ const struct isl6423_config *config)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+#endif /* CONFIG_DVB_ISL6423 */
+
+#endif /* __ISL_6423_H */
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
index 762d5af62d7a..67dc8ec634e2 100644
--- a/drivers/media/dvb/frontends/stv0900_priv.h
+++ b/drivers/media/dvb/frontends/stv0900_priv.h
@@ -60,8 +60,6 @@
} \
} while (0)
-#define dmd_choose(a, b) (demod = STV0900_DEMOD_2 ? b : a))
-
static int stvdebug;
#define dprintk(args...) \
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
new file mode 100644
index 000000000000..96ef745a2e4e
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -0,0 +1,4299 @@
+/*
+ STV0900/0903 Multistandard Broadcast Frontend driver
+ Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+ Copyright (C) ST Microelectronics
+
+ 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.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/mutex.h>
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+#include "stv6110x.h" /* for demodulator internal modes */
+
+#include "stv090x_reg.h"
+#include "stv090x.h"
+#include "stv090x_priv.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+
+struct mutex demod_lock;
+
+/* DVBS1 and DSS C/N Lookup table */
+static const struct stv090x_tab stv090x_s1cn_tab[] = {
+ { 0, 8917 }, /* 0.0dB */
+ { 5, 8801 }, /* 0.5dB */
+ { 10, 8667 }, /* 1.0dB */
+ { 15, 8522 }, /* 1.5dB */
+ { 20, 8355 }, /* 2.0dB */
+ { 25, 8175 }, /* 2.5dB */
+ { 30, 7979 }, /* 3.0dB */
+ { 35, 7763 }, /* 3.5dB */
+ { 40, 7530 }, /* 4.0dB */
+ { 45, 7282 }, /* 4.5dB */
+ { 50, 7026 }, /* 5.0dB */
+ { 55, 6781 }, /* 5.5dB */
+ { 60, 6514 }, /* 6.0dB */
+ { 65, 6241 }, /* 6.5dB */
+ { 70, 5965 }, /* 7.0dB */
+ { 75, 5690 }, /* 7.5dB */
+ { 80, 5424 }, /* 8.0dB */
+ { 85, 5161 }, /* 8.5dB */
+ { 90, 4902 }, /* 9.0dB */
+ { 95, 4654 }, /* 9.5dB */
+ { 100, 4417 }, /* 10.0dB */
+ { 105, 4186 }, /* 10.5dB */
+ { 110, 3968 }, /* 11.0dB */
+ { 115, 3757 }, /* 11.5dB */
+ { 120, 3558 }, /* 12.0dB */
+ { 125, 3366 }, /* 12.5dB */
+ { 130, 3185 }, /* 13.0dB */
+ { 135, 3012 }, /* 13.5dB */
+ { 140, 2850 }, /* 14.0dB */
+ { 145, 2698 }, /* 14.5dB */
+ { 150, 2550 }, /* 15.0dB */
+ { 160, 2283 }, /* 16.0dB */
+ { 170, 2042 }, /* 17.0dB */
+ { 180, 1827 }, /* 18.0dB */
+ { 190, 1636 }, /* 19.0dB */
+ { 200, 1466 }, /* 20.0dB */
+ { 210, 1315 }, /* 21.0dB */
+ { 220, 1181 }, /* 22.0dB */
+ { 230, 1064 }, /* 23.0dB */
+ { 240, 960 }, /* 24.0dB */
+ { 250, 869 }, /* 25.0dB */
+ { 260, 792 }, /* 26.0dB */
+ { 270, 724 }, /* 27.0dB */
+ { 280, 665 }, /* 28.0dB */
+ { 290, 616 }, /* 29.0dB */
+ { 300, 573 }, /* 30.0dB */
+ { 310, 537 }, /* 31.0dB */
+ { 320, 507 }, /* 32.0dB */
+ { 330, 483 }, /* 33.0dB */
+ { 400, 398 }, /* 40.0dB */
+ { 450, 381 }, /* 45.0dB */
+ { 500, 377 } /* 50.0dB */
+};
+
+/* DVBS2 C/N Lookup table */
+static const struct stv090x_tab stv090x_s2cn_tab[] = {
+ { -30, 13348 }, /* -3.0dB */
+ { -20, 12640 }, /* -2d.0B */
+ { -10, 11883 }, /* -1.0dB */
+ { 0, 11101 }, /* -0.0dB */
+ { 5, 10718 }, /* 0.5dB */
+ { 10, 10339 }, /* 1.0dB */
+ { 15, 9947 }, /* 1.5dB */
+ { 20, 9552 }, /* 2.0dB */
+ { 25, 9183 }, /* 2.5dB */
+ { 30, 8799 }, /* 3.0dB */
+ { 35, 8422 }, /* 3.5dB */
+ { 40, 8062 }, /* 4.0dB */
+ { 45, 7707 }, /* 4.5dB */
+ { 50, 7353 }, /* 5.0dB */
+ { 55, 7025 }, /* 5.5dB */
+ { 60, 6684 }, /* 6.0dB */
+ { 65, 6331 }, /* 6.5dB */
+ { 70, 6036 }, /* 7.0dB */
+ { 75, 5727 }, /* 7.5dB */
+ { 80, 5437 }, /* 8.0dB */
+ { 85, 5164 }, /* 8.5dB */
+ { 90, 4902 }, /* 9.0dB */
+ { 95, 4653 }, /* 9.5dB */
+ { 100, 4408 }, /* 10.0dB */
+ { 105, 4187 }, /* 10.5dB */
+ { 110, 3961 }, /* 11.0dB */
+ { 115, 3751 }, /* 11.5dB */
+ { 120, 3558 }, /* 12.0dB */
+ { 125, 3368 }, /* 12.5dB */
+ { 130, 3191 }, /* 13.0dB */
+ { 135, 3017 }, /* 13.5dB */
+ { 140, 2862 }, /* 14.0dB */
+ { 145, 2710 }, /* 14.5dB */
+ { 150, 2565 }, /* 15.0dB */
+ { 160, 2300 }, /* 16.0dB */
+ { 170, 2058 }, /* 17.0dB */
+ { 180, 1849 }, /* 18.0dB */
+ { 190, 1663 }, /* 19.0dB */
+ { 200, 1495 }, /* 20.0dB */
+ { 210, 1349 }, /* 21.0dB */
+ { 220, 1222 }, /* 22.0dB */
+ { 230, 1110 }, /* 23.0dB */
+ { 240, 1011 }, /* 24.0dB */
+ { 250, 925 }, /* 25.0dB */
+ { 260, 853 }, /* 26.0dB */
+ { 270, 789 }, /* 27.0dB */
+ { 280, 734 }, /* 28.0dB */
+ { 290, 690 }, /* 29.0dB */
+ { 300, 650 }, /* 30.0dB */
+ { 310, 619 }, /* 31.0dB */
+ { 320, 593 }, /* 32.0dB */
+ { 330, 571 }, /* 33.0dB */
+ { 400, 498 }, /* 40.0dB */
+ { 450, 484 }, /* 45.0dB */
+ { 500, 481 } /* 50.0dB */
+};
+
+/* RF level C/N lookup table */
+static const struct stv090x_tab stv090x_rf_tab[] = {
+ { -5, 0xcaa1 }, /* -5dBm */
+ { -10, 0xc229 }, /* -10dBm */
+ { -15, 0xbb08 }, /* -15dBm */
+ { -20, 0xb4bc }, /* -20dBm */
+ { -25, 0xad5a }, /* -25dBm */
+ { -30, 0xa298 }, /* -30dBm */
+ { -35, 0x98a8 }, /* -35dBm */
+ { -40, 0x8389 }, /* -40dBm */
+ { -45, 0x59be }, /* -45dBm */
+ { -50, 0x3a14 }, /* -50dBm */
+ { -55, 0x2d11 }, /* -55dBm */
+ { -60, 0x210d }, /* -60dBm */
+ { -65, 0xa14f }, /* -65dBm */
+ { -70, 0x07aa } /* -70dBm */
+};
+
+
+static struct stv090x_reg stv0900_initval[] = {
+
+ { STV090x_OUTCFG, 0x00 },
+ { STV090x_MODECFG, 0xff },
+ { STV090x_AGCRF1CFG, 0x11 },
+ { STV090x_AGCRF2CFG, 0x13 },
+ { STV090x_TSGENERAL1X, 0x14 },
+ { STV090x_TSTTNR2, 0x21 },
+ { STV090x_TSTTNR4, 0x21 },
+ { STV090x_P2_DISTXCTL, 0x22 },
+ { STV090x_P2_F22TX, 0xc0 },
+ { STV090x_P2_F22RX, 0xc0 },
+ { STV090x_P2_DISRXCTL, 0x00 },
+ { STV090x_P2_DMDCFGMD, 0xF9 },
+ { STV090x_P2_DEMOD, 0x08 },
+ { STV090x_P2_DMDCFG3, 0xc4 },
+ { STV090x_P2_CARFREQ, 0xed },
+ { STV090x_P2_LDT, 0xd0 },
+ { STV090x_P2_LDT2, 0xb8 },
+ { STV090x_P2_TMGCFG, 0xd2 },
+ { STV090x_P2_TMGTHRISE, 0x20 },
+ { STV090x_P1_TMGCFG, 0xd2 },
+
+ { STV090x_P2_TMGTHFALL, 0x00 },
+ { STV090x_P2_FECSPY, 0x88 },
+ { STV090x_P2_FSPYDATA, 0x3a },
+ { STV090x_P2_FBERCPT4, 0x00 },
+ { STV090x_P2_FSPYBER, 0x10 },
+ { STV090x_P2_ERRCTRL1, 0x35 },
+ { STV090x_P2_ERRCTRL2, 0xc1 },
+ { STV090x_P2_CFRICFG, 0xf8 },
+ { STV090x_P2_NOSCFG, 0x1c },
+ { STV090x_P2_DMDTOM, 0x20 },
+ { STV090x_P2_CORRELMANT, 0x70 },
+ { STV090x_P2_CORRELABS, 0x88 },
+ { STV090x_P2_AGC2O, 0x5b },
+ { STV090x_P2_AGC2REF, 0x38 },
+ { STV090x_P2_CARCFG, 0xe4 },
+ { STV090x_P2_ACLC, 0x1A },
+ { STV090x_P2_BCLC, 0x09 },
+ { STV090x_P2_CARHDR, 0x08 },
+ { STV090x_P2_KREFTMG, 0xc1 },
+ { STV090x_P2_SFRUPRATIO, 0xf0 },
+ { STV090x_P2_SFRLOWRATIO, 0x70 },
+ { STV090x_P2_SFRSTEP, 0x58 },
+ { STV090x_P2_TMGCFG2, 0x01 },
+ { STV090x_P2_CAR2CFG, 0x26 },
+ { STV090x_P2_BCLC2S2Q, 0x86 },
+ { STV090x_P2_BCLC2S28, 0x86 },
+ { STV090x_P2_SMAPCOEF7, 0x77 },
+ { STV090x_P2_SMAPCOEF6, 0x85 },
+ { STV090x_P2_SMAPCOEF5, 0x77 },
+ { STV090x_P2_TSCFGL, 0x20 },
+ { STV090x_P2_DMDCFG2, 0x3b },
+ { STV090x_P2_MODCODLST0, 0xff },
+ { STV090x_P2_MODCODLST1, 0xff },
+ { STV090x_P2_MODCODLST2, 0xff },
+ { STV090x_P2_MODCODLST3, 0xff },
+ { STV090x_P2_MODCODLST4, 0xff },
+ { STV090x_P2_MODCODLST5, 0xff },
+ { STV090x_P2_MODCODLST6, 0xff },
+ { STV090x_P2_MODCODLST7, 0xcc },
+ { STV090x_P2_MODCODLST8, 0xcc },
+ { STV090x_P2_MODCODLST9, 0xcc },
+ { STV090x_P2_MODCODLSTA, 0xcc },
+ { STV090x_P2_MODCODLSTB, 0xcc },
+ { STV090x_P2_MODCODLSTC, 0xcc },
+ { STV090x_P2_MODCODLSTD, 0xcc },
+ { STV090x_P2_MODCODLSTE, 0xcc },
+ { STV090x_P2_MODCODLSTF, 0xcf },
+ { STV090x_P1_DISTXCTL, 0x22 },
+ { STV090x_P1_F22TX, 0xc0 },
+ { STV090x_P1_F22RX, 0xc0 },
+ { STV090x_P1_DISRXCTL, 0x00 },
+ { STV090x_P1_DMDCFGMD, 0xf9 },
+ { STV090x_P1_DEMOD, 0x08 },
+ { STV090x_P1_DMDCFG3, 0xc4 },
+ { STV090x_P1_DMDTOM, 0x20 },
+ { STV090x_P1_CARFREQ, 0xed },
+ { STV090x_P1_LDT, 0xd0 },
+ { STV090x_P1_LDT2, 0xb8 },
+ { STV090x_P1_TMGCFG, 0xd2 },
+ { STV090x_P1_TMGTHRISE, 0x20 },
+ { STV090x_P1_TMGTHFALL, 0x00 },
+ { STV090x_P1_SFRUPRATIO, 0xf0 },
+ { STV090x_P1_SFRLOWRATIO, 0x70 },
+ { STV090x_P1_TSCFGL, 0x20 },
+ { STV090x_P1_FECSPY, 0x88 },
+ { STV090x_P1_FSPYDATA, 0x3a },
+ { STV090x_P1_FBERCPT4, 0x00 },
+ { STV090x_P1_FSPYBER, 0x10 },
+ { STV090x_P1_ERRCTRL1, 0x35 },
+ { STV090x_P1_ERRCTRL2, 0xc1 },
+ { STV090x_P1_CFRICFG, 0xf8 },
+ { STV090x_P1_NOSCFG, 0x1c },
+ { STV090x_P1_CORRELMANT, 0x70 },
+ { STV090x_P1_CORRELABS, 0x88 },
+ { STV090x_P1_AGC2O, 0x5b },
+ { STV090x_P1_AGC2REF, 0x38 },
+ { STV090x_P1_CARCFG, 0xe4 },
+ { STV090x_P1_ACLC, 0x1A },
+ { STV090x_P1_BCLC, 0x09 },
+ { STV090x_P1_CARHDR, 0x08 },
+ { STV090x_P1_KREFTMG, 0xc1 },
+ { STV090x_P1_SFRSTEP, 0x58 },
+ { STV090x_P1_TMGCFG2, 0x01 },
+ { STV090x_P1_CAR2CFG, 0x26 },
+ { STV090x_P1_BCLC2S2Q, 0x86 },
+ { STV090x_P1_BCLC2S28, 0x86 },
+ { STV090x_P1_SMAPCOEF7, 0x77 },
+ { STV090x_P1_SMAPCOEF6, 0x85 },
+ { STV090x_P1_SMAPCOEF5, 0x77 },
+ { STV090x_P1_DMDCFG2, 0x3b },
+ { STV090x_P1_MODCODLST0, 0xff },
+ { STV090x_P1_MODCODLST1, 0xff },
+ { STV090x_P1_MODCODLST2, 0xff },
+ { STV090x_P1_MODCODLST3, 0xff },
+ { STV090x_P1_MODCODLST4, 0xff },
+ { STV090x_P1_MODCODLST5, 0xff },
+ { STV090x_P1_MODCODLST6, 0xff },
+ { STV090x_P1_MODCODLST7, 0xcc },
+ { STV090x_P1_MODCODLST8, 0xcc },
+ { STV090x_P1_MODCODLST9, 0xcc },
+ { STV090x_P1_MODCODLSTA, 0xcc },
+ { STV090x_P1_MODCODLSTB, 0xcc },
+ { STV090x_P1_MODCODLSTC, 0xcc },
+ { STV090x_P1_MODCODLSTD, 0xcc },
+ { STV090x_P1_MODCODLSTE, 0xcc },
+ { STV090x_P1_MODCODLSTF, 0xcf },
+ { STV090x_GENCFG, 0x1d },
+ { STV090x_NBITER_NF4, 0x37 },
+ { STV090x_NBITER_NF5, 0x29 },
+ { STV090x_NBITER_NF6, 0x37 },
+ { STV090x_NBITER_NF7, 0x33 },
+ { STV090x_NBITER_NF8, 0x31 },
+ { STV090x_NBITER_NF9, 0x2f },
+ { STV090x_NBITER_NF10, 0x39 },
+ { STV090x_NBITER_NF11, 0x3a },
+ { STV090x_NBITER_NF12, 0x29 },
+ { STV090x_NBITER_NF13, 0x37 },
+ { STV090x_NBITER_NF14, 0x33 },
+ { STV090x_NBITER_NF15, 0x2f },
+ { STV090x_NBITER_NF16, 0x39 },
+ { STV090x_NBITER_NF17, 0x3a },
+ { STV090x_NBITERNOERR, 0x04 },
+ { STV090x_GAINLLR_NF4, 0x0C },
+ { STV090x_GAINLLR_NF5, 0x0F },
+ { STV090x_GAINLLR_NF6, 0x11 },
+ { STV090x_GAINLLR_NF7, 0x14 },
+ { STV090x_GAINLLR_NF8, 0x17 },
+ { STV090x_GAINLLR_NF9, 0x19 },
+ { STV090x_GAINLLR_NF10, 0x20 },
+ { STV090x_GAINLLR_NF11, 0x21 },
+ { STV090x_GAINLLR_NF12, 0x0D },
+ { STV090x_GAINLLR_NF13, 0x0F },
+ { STV090x_GAINLLR_NF14, 0x13 },
+ { STV090x_GAINLLR_NF15, 0x1A },
+ { STV090x_GAINLLR_NF16, 0x1F },
+ { STV090x_GAINLLR_NF17, 0x21 },
+ { STV090x_RCCFGH, 0x20 },
+ { STV090x_P1_FECM, 0x01 }, /* disable DSS modes */
+ { STV090x_P2_FECM, 0x01 }, /* disable DSS modes */
+ { STV090x_P1_PRVIT, 0x2F }, /* disable PR 6/7 */
+ { STV090x_P2_PRVIT, 0x2F }, /* disable PR 6/7 */
+};
+
+static struct stv090x_reg stv0903_initval[] = {
+ { STV090x_OUTCFG, 0x00 },
+ { STV090x_AGCRF1CFG, 0x11 },
+ { STV090x_STOPCLK1, 0x48 },
+ { STV090x_STOPCLK2, 0x14 },
+ { STV090x_TSTTNR1, 0x27 },
+ { STV090x_TSTTNR2, 0x21 },
+ { STV090x_P1_DISTXCTL, 0x22 },
+ { STV090x_P1_F22TX, 0xc0 },
+ { STV090x_P1_F22RX, 0xc0 },
+ { STV090x_P1_DISRXCTL, 0x00 },
+ { STV090x_P1_DMDCFGMD, 0xF9 },
+ { STV090x_P1_DEMOD, 0x08 },
+ { STV090x_P1_DMDCFG3, 0xc4 },
+ { STV090x_P1_CARFREQ, 0xed },
+ { STV090x_P1_TNRCFG2, 0x82 },
+ { STV090x_P1_LDT, 0xd0 },
+ { STV090x_P1_LDT2, 0xb8 },
+ { STV090x_P1_TMGCFG, 0xd2 },
+ { STV090x_P1_TMGTHRISE, 0x20 },
+ { STV090x_P1_TMGTHFALL, 0x00 },
+ { STV090x_P1_SFRUPRATIO, 0xf0 },
+ { STV090x_P1_SFRLOWRATIO, 0x70 },
+ { STV090x_P1_TSCFGL, 0x20 },
+ { STV090x_P1_FECSPY, 0x88 },
+ { STV090x_P1_FSPYDATA, 0x3a },
+ { STV090x_P1_FBERCPT4, 0x00 },
+ { STV090x_P1_FSPYBER, 0x10 },
+ { STV090x_P1_ERRCTRL1, 0x35 },
+ { STV090x_P1_ERRCTRL2, 0xc1 },
+ { STV090x_P1_CFRICFG, 0xf8 },
+ { STV090x_P1_NOSCFG, 0x1c },
+ { STV090x_P1_DMDTOM, 0x20 },
+ { STV090x_P1_CORRELMANT, 0x70 },
+ { STV090x_P1_CORRELABS, 0x88 },
+ { STV090x_P1_AGC2O, 0x5b },
+ { STV090x_P1_AGC2REF, 0x38 },
+ { STV090x_P1_CARCFG, 0xe4 },
+ { STV090x_P1_ACLC, 0x1A },
+ { STV090x_P1_BCLC, 0x09 },
+ { STV090x_P1_CARHDR, 0x08 },
+ { STV090x_P1_KREFTMG, 0xc1 },
+ { STV090x_P1_SFRSTEP, 0x58 },
+ { STV090x_P1_TMGCFG2, 0x01 },
+ { STV090x_P1_CAR2CFG, 0x26 },
+ { STV090x_P1_BCLC2S2Q, 0x86 },
+ { STV090x_P1_BCLC2S28, 0x86 },
+ { STV090x_P1_SMAPCOEF7, 0x77 },
+ { STV090x_P1_SMAPCOEF6, 0x85 },
+ { STV090x_P1_SMAPCOEF5, 0x77 },
+ { STV090x_P1_DMDCFG2, 0x3b },
+ { STV090x_P1_MODCODLST0, 0xff },
+ { STV090x_P1_MODCODLST1, 0xff },
+ { STV090x_P1_MODCODLST2, 0xff },
+ { STV090x_P1_MODCODLST3, 0xff },
+ { STV090x_P1_MODCODLST4, 0xff },
+ { STV090x_P1_MODCODLST5, 0xff },
+ { STV090x_P1_MODCODLST6, 0xff },
+ { STV090x_P1_MODCODLST7, 0xcc },
+ { STV090x_P1_MODCODLST8, 0xcc },
+ { STV090x_P1_MODCODLST9, 0xcc },
+ { STV090x_P1_MODCODLSTA, 0xcc },
+ { STV090x_P1_MODCODLSTB, 0xcc },
+ { STV090x_P1_MODCODLSTC, 0xcc },
+ { STV090x_P1_MODCODLSTD, 0xcc },
+ { STV090x_P1_MODCODLSTE, 0xcc },
+ { STV090x_P1_MODCODLSTF, 0xcf },
+ { STV090x_GENCFG, 0x1c },
+ { STV090x_NBITER_NF4, 0x37 },
+ { STV090x_NBITER_NF5, 0x29 },
+ { STV090x_NBITER_NF6, 0x37 },
+ { STV090x_NBITER_NF7, 0x33 },
+ { STV090x_NBITER_NF8, 0x31 },
+ { STV090x_NBITER_NF9, 0x2f },
+ { STV090x_NBITER_NF10, 0x39 },
+ { STV090x_NBITER_NF11, 0x3a },
+ { STV090x_NBITER_NF12, 0x29 },
+ { STV090x_NBITER_NF13, 0x37 },
+ { STV090x_NBITER_NF14, 0x33 },
+ { STV090x_NBITER_NF15, 0x2f },
+ { STV090x_NBITER_NF16, 0x39 },
+ { STV090x_NBITER_NF17, 0x3a },
+ { STV090x_NBITERNOERR, 0x04 },
+ { STV090x_GAINLLR_NF4, 0x0C },
+ { STV090x_GAINLLR_NF5, 0x0F },
+ { STV090x_GAINLLR_NF6, 0x11 },
+ { STV090x_GAINLLR_NF7, 0x14 },
+ { STV090x_GAINLLR_NF8, 0x17 },
+ { STV090x_GAINLLR_NF9, 0x19 },
+ { STV090x_GAINLLR_NF10, 0x20 },
+ { STV090x_GAINLLR_NF11, 0x21 },
+ { STV090x_GAINLLR_NF12, 0x0D },
+ { STV090x_GAINLLR_NF13, 0x0F },
+ { STV090x_GAINLLR_NF14, 0x13 },
+ { STV090x_GAINLLR_NF15, 0x1A },
+ { STV090x_GAINLLR_NF16, 0x1F },
+ { STV090x_GAINLLR_NF17, 0x21 },
+ { STV090x_RCCFGH, 0x20 },
+ { STV090x_P1_FECM, 0x01 }, /*disable the DSS mode */
+ { STV090x_P1_PRVIT, 0x2f } /*disable puncture rate 6/7*/
+};
+
+static struct stv090x_reg stv0900_cut20_val[] = {
+
+ { STV090x_P2_DMDCFG3, 0xe8 },
+ { STV090x_P2_DMDCFG4, 0x10 },
+ { STV090x_P2_CARFREQ, 0x38 },
+ { STV090x_P2_CARHDR, 0x20 },
+ { STV090x_P2_KREFTMG, 0x5a },
+ { STV090x_P2_SMAPCOEF7, 0x06 },
+ { STV090x_P2_SMAPCOEF6, 0x00 },
+ { STV090x_P2_SMAPCOEF5, 0x04 },
+ { STV090x_P2_NOSCFG, 0x0c },
+ { STV090x_P1_DMDCFG3, 0xe8 },
+ { STV090x_P1_DMDCFG4, 0x10 },
+ { STV090x_P1_CARFREQ, 0x38 },
+ { STV090x_P1_CARHDR, 0x20 },
+ { STV090x_P1_KREFTMG, 0x5a },
+ { STV090x_P1_SMAPCOEF7, 0x06 },
+ { STV090x_P1_SMAPCOEF6, 0x00 },
+ { STV090x_P1_SMAPCOEF5, 0x04 },
+ { STV090x_P1_NOSCFG, 0x0c },
+ { STV090x_GAINLLR_NF4, 0x21 },
+ { STV090x_GAINLLR_NF5, 0x21 },
+ { STV090x_GAINLLR_NF6, 0x20 },
+ { STV090x_GAINLLR_NF7, 0x1F },
+ { STV090x_GAINLLR_NF8, 0x1E },
+ { STV090x_GAINLLR_NF9, 0x1E },
+ { STV090x_GAINLLR_NF10, 0x1D },
+ { STV090x_GAINLLR_NF11, 0x1B },
+ { STV090x_GAINLLR_NF12, 0x20 },
+ { STV090x_GAINLLR_NF13, 0x20 },
+ { STV090x_GAINLLR_NF14, 0x20 },
+ { STV090x_GAINLLR_NF15, 0x20 },
+ { STV090x_GAINLLR_NF16, 0x20 },
+ { STV090x_GAINLLR_NF17, 0x21 },
+};
+
+static struct stv090x_reg stv0903_cut20_val[] = {
+ { STV090x_P1_DMDCFG3, 0xe8 },
+ { STV090x_P1_DMDCFG4, 0x10 },
+ { STV090x_P1_CARFREQ, 0x38 },
+ { STV090x_P1_CARHDR, 0x20 },
+ { STV090x_P1_KREFTMG, 0x5a },
+ { STV090x_P1_SMAPCOEF7, 0x06 },
+ { STV090x_P1_SMAPCOEF6, 0x00 },
+ { STV090x_P1_SMAPCOEF5, 0x04 },
+ { STV090x_P1_NOSCFG, 0x0c },
+ { STV090x_GAINLLR_NF4, 0x21 },
+ { STV090x_GAINLLR_NF5, 0x21 },
+ { STV090x_GAINLLR_NF6, 0x20 },
+ { STV090x_GAINLLR_NF7, 0x1F },
+ { STV090x_GAINLLR_NF8, 0x1E },
+ { STV090x_GAINLLR_NF9, 0x1E },
+ { STV090x_GAINLLR_NF10, 0x1D },
+ { STV090x_GAINLLR_NF11, 0x1B },
+ { STV090x_GAINLLR_NF12, 0x20 },
+ { STV090x_GAINLLR_NF13, 0x20 },
+ { STV090x_GAINLLR_NF14, 0x20 },
+ { STV090x_GAINLLR_NF15, 0x20 },
+ { STV090x_GAINLLR_NF16, 0x20 },
+ { STV090x_GAINLLR_NF17, 0x21 }
+};
+
+/* Cut 2.0 Long Frame Tracking CR loop */
+static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = {
+ /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV090x_QPSK_12, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x1e },
+ { STV090x_QPSK_35, 0x2f, 0x3f, 0x2e, 0x2f, 0x3d, 0x0f, 0x0e, 0x2e, 0x3d, 0x0e },
+ { STV090x_QPSK_23, 0x2f, 0x3f, 0x2e, 0x2f, 0x0e, 0x0f, 0x0e, 0x1e, 0x3d, 0x3d },
+ { STV090x_QPSK_34, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
+ { STV090x_QPSK_45, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
+ { STV090x_QPSK_56, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
+ { STV090x_QPSK_89, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
+ { STV090x_QPSK_910, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
+ { STV090x_8PSK_35, 0x3c, 0x3e, 0x1c, 0x2e, 0x0c, 0x1e, 0x2b, 0x2d, 0x1b, 0x1d },
+ { STV090x_8PSK_23, 0x1d, 0x3e, 0x3c, 0x2e, 0x2c, 0x1e, 0x0c, 0x2d, 0x2b, 0x1d },
+ { STV090x_8PSK_34, 0x0e, 0x3e, 0x3d, 0x2e, 0x0d, 0x1e, 0x2c, 0x2d, 0x0c, 0x1d },
+ { STV090x_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
+ { STV090x_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
+ { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d }
+};
+
+/* Cut 3.0 Long Frame Tracking CR loop */
+static struct stv090x_long_frame_crloop stv090x_s2_crl_cut30[] = {
+ /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV090x_QPSK_12, 0x3c, 0x2c, 0x0c, 0x2c, 0x1b, 0x2c, 0x1b, 0x1c, 0x0b, 0x3b },
+ { STV090x_QPSK_35, 0x0d, 0x0d, 0x0c, 0x0d, 0x1b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
+ { STV090x_QPSK_23, 0x1d, 0x0d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
+ { STV090x_QPSK_34, 0x1d, 0x1d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
+ { STV090x_QPSK_45, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
+ { STV090x_QPSK_56, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
+ { STV090x_QPSK_89, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
+ { STV090x_QPSK_910, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
+ { STV090x_8PSK_35, 0x39, 0x29, 0x39, 0x19, 0x19, 0x19, 0x19, 0x19, 0x09, 0x19 },
+ { STV090x_8PSK_23, 0x2a, 0x39, 0x1a, 0x0a, 0x39, 0x0a, 0x29, 0x39, 0x29, 0x0a },
+ { STV090x_8PSK_34, 0x2b, 0x3a, 0x1b, 0x1b, 0x3a, 0x1b, 0x1a, 0x0b, 0x1a, 0x3a },
+ { STV090x_8PSK_56, 0x0c, 0x1b, 0x3b, 0x3b, 0x1b, 0x3b, 0x3a, 0x3b, 0x3a, 0x1b },
+ { STV090x_8PSK_89, 0x0d, 0x3c, 0x2c, 0x2c, 0x2b, 0x0c, 0x0b, 0x3b, 0x0b, 0x1b },
+ { STV090x_8PSK_910, 0x0d, 0x0d, 0x2c, 0x3c, 0x3b, 0x1c, 0x0b, 0x3b, 0x0b, 0x1b }
+};
+
+/* Cut 2.0 Long Frame Tracking CR Loop */
+static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = {
+ /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV090x_16APSK_23, 0x0c, 0x0c, 0x0c, 0x0c, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x0c },
+ { STV090x_16APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0c, 0x2d, 0x0c, 0x1d, 0x0c },
+ { STV090x_16APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },
+ { STV090x_16APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },
+ { STV090x_16APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },
+ { STV090x_16APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },
+ { STV090x_32APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
+ { STV090x_32APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
+ { STV090x_32APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
+ { STV090x_32APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
+ { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }
+};
+
+/* Cut 3.0 Long Frame Tracking CR Loop */
+static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut30[] = {
+ /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV090x_16APSK_23, 0x0a, 0x0a, 0x0a, 0x0a, 0x1a, 0x0a, 0x3a, 0x0a, 0x2a, 0x0a },
+ { STV090x_16APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x3b, 0x0a, 0x1b, 0x0a },
+ { STV090x_16APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },
+ { STV090x_16APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },
+ { STV090x_16APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },
+ { STV090x_16APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },
+ { STV090x_32APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
+ { STV090x_32APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
+ { STV090x_32APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
+ { STV090x_32APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
+ { STV090x_32APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }
+};
+
+static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = {
+ /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV090x_QPSK_14, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x2d, 0x1f, 0x3d, 0x3e },
+ { STV090x_QPSK_13, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x3d, 0x0f, 0x3d, 0x2e },
+ { STV090x_QPSK_25, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x2e }
+};
+
+static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut30[] = {
+ /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV090x_QPSK_14, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x2a, 0x1c, 0x3a, 0x3b },
+ { STV090x_QPSK_13, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b },
+ { STV090x_QPSK_25, 0x1c, 0x3c, 0x1b, 0x3c, 0x3a, 0x1c, 0x3a, 0x3b, 0x3a, 0x2b }
+};
+
+/* Cut 2.0 Short Frame Tracking CR Loop */
+static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = {
+ /* MODCOD 2M 5M 10M 20M 30M */
+ { STV090x_QPSK, 0x2f, 0x2e, 0x0e, 0x0e, 0x3d },
+ { STV090x_8PSK, 0x3e, 0x0e, 0x2d, 0x0d, 0x3c },
+ { STV090x_16APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d },
+ { STV090x_32APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d }
+};
+
+/* Cut 3.0 Short Frame Tracking CR Loop */
+static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = {
+ /* MODCOD 2M 5M 10M 20M 30M */
+ { STV090x_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A },
+ { STV090x_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 },
+ { STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
+ { STV090x_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A }
+};
+
+static inline s32 comp2(s32 __x, s32 __width)
+{
+ if (__width == 32)
+ return __x;
+ else
+ return (__x >= (1 << (__width - 1))) ? (__x - (1 << __width)) : __x;
+}
+
+static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg)
+{
+ const struct stv090x_config *config = state->config;
+ int ret;
+
+ u8 b0[] = { reg >> 8, reg & 0xff };
+ u8 buf;
+
+ struct i2c_msg msg[] = {
+ { .addr = config->address, .flags = 0, .buf = b0, .len = 2 },
+ { .addr = config->address, .flags = I2C_M_RD, .buf = &buf, .len = 1 }
+ };
+
+ ret = i2c_transfer(state->i2c, msg, 2);
+ if (ret != 2) {
+ if (ret != -ERESTARTSYS)
+ dprintk(FE_ERROR, 1,
+ "Read error, Reg=[0x%02x], Status=%d",
+ reg, ret);
+
+ return ret < 0 ? ret : -EREMOTEIO;
+ }
+ if (unlikely(*state->verbose >= FE_DEBUGREG))
+ dprintk(FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
+ reg, buf);
+
+ return (unsigned int) buf;
+}
+
+static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 *data, u32 count)
+{
+ const struct stv090x_config *config = state->config;
+ int ret;
+ u8 buf[2 + count];
+ struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count };
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+ memcpy(&buf[2], data, count);
+
+ if (unlikely(*state->verbose >= FE_DEBUGREG)) {
+ int i;
+
+ printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
+ for (i = 0; i < count; i++)
+ printk(" %02x", data[i]);
+ printk("\n");
+ }
+
+ ret = i2c_transfer(state->i2c, &i2c_msg, 1);
+ if (ret != 1) {
+ if (ret != -ERESTARTSYS)
+ dprintk(FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
+ reg, data[0], count, ret);
+ return ret < 0 ? ret : -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
+{
+ return stv090x_write_regs(state, reg, &data, 1);
+}
+
+static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u32 reg;
+
+ reg = STV090x_READ_DEMOD(state, I2CRPT);
+ if (enable) {
+ dprintk(FE_DEBUG, 1, "Enable Gate");
+ STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0)
+ goto err;
+
+ } else {
+ dprintk(FE_DEBUG, 1, "Disable Gate");
+ STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 0);
+ if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0)
+ goto err;
+ }
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static void stv090x_get_lock_tmg(struct stv090x_state *state)
+{
+ switch (state->algo) {
+ case STV090x_BLIND_SEARCH:
+ dprintk(FE_DEBUG, 1, "Blind Search");
+ if (state->srate <= 1500000) { /*10Msps< SR <=15Msps*/
+ state->DemodTimeout = 1500;
+ state->FecTimeout = 400;
+ } else if (state->srate <= 5000000) { /*10Msps< SR <=15Msps*/
+ state->DemodTimeout = 1000;
+ state->FecTimeout = 300;
+ } else { /*SR >20Msps*/
+ state->DemodTimeout = 700;
+ state->FecTimeout = 100;
+ }
+ break;
+
+ case STV090x_COLD_SEARCH:
+ case STV090x_WARM_SEARCH:
+ default:
+ dprintk(FE_DEBUG, 1, "Normal Search");
+ if (state->srate <= 1000000) { /*SR <=1Msps*/
+ state->DemodTimeout = 4500;
+ state->FecTimeout = 1700;
+ } else if (state->srate <= 2000000) { /*1Msps < SR <= 2Msps */
+ state->DemodTimeout = 2500;
+ state->FecTimeout = 1100;
+ } else if (state->srate <= 5000000) { /*2Msps < SR <= 5Msps */
+ state->DemodTimeout = 1000;
+ state->FecTimeout = 550;
+ } else if (state->srate <= 10000000) { /*5Msps < SR <= 10Msps */
+ state->DemodTimeout = 700;
+ state->FecTimeout = 250;
+ } else if (state->srate <= 20000000) { /*10Msps < SR <= 20Msps */
+ state->DemodTimeout = 400;
+ state->FecTimeout = 130;
+ } else { /*SR >20Msps*/
+ state->DemodTimeout = 300;
+ state->FecTimeout = 100;
+ }
+ break;
+ }
+
+ if (state->algo == STV090x_WARM_SEARCH)
+ state->DemodTimeout /= 2;
+}
+
+static int stv090x_set_srate(struct stv090x_state *state, u32 srate)
+{
+ u32 sym;
+
+ if (srate > 60000000) {
+ sym = (srate << 4); /* SR * 2^16 / master_clk */
+ sym /= (state->mclk >> 12);
+ } else if (srate > 6000000) {
+ sym = (srate << 6);
+ sym /= (state->mclk >> 10);
+ } else {
+ sym = (srate << 9);
+ sym /= (state->mclk >> 7);
+ }
+
+ if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRINIT0, (sym & 0xff)) < 0) /* LSB */
+ goto err;
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate)
+{
+ u32 sym;
+
+ srate = 105 * (srate / 100);
+ if (srate > 60000000) {
+ sym = (srate << 4); /* SR * 2^16 / master_clk */
+ sym /= (state->mclk >> 12);
+ } else if (srate > 6000000) {
+ sym = (srate << 6);
+ sym /= (state->mclk >> 10);
+ } else {
+ sym = (srate << 9);
+ sym /= (state->mclk >> 7);
+ }
+
+ if (sym < 0x7fff) {
+ if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */
+ goto err;
+ } else {
+ if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x7f) < 0) /* MSB */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xff) < 0) /* LSB */
+ goto err;
+ }
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate)
+{
+ u32 sym;
+
+ srate = 95 * (srate / 100);
+ if (srate > 60000000) {
+ sym = (srate << 4); /* SR * 2^16 / master_clk */
+ sym /= (state->mclk >> 12);
+ } else if (srate > 6000000) {
+ sym = (srate << 6);
+ sym /= (state->mclk >> 10);
+ } else {
+ sym = (srate << 9);
+ sym /= (state->mclk >> 7);
+ }
+
+ if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0xff)) < 0) /* MSB */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */
+ goto err;
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static u32 stv090x_car_width(u32 srate, enum stv090x_rolloff rolloff)
+{
+ u32 ro;
+
+ switch (rolloff) {
+ case STV090x_RO_20:
+ ro = 20;
+ break;
+ case STV090x_RO_25:
+ ro = 25;
+ break;
+ case STV090x_RO_35:
+ default:
+ ro = 35;
+ break;
+ }
+
+ return srate + (srate * ro) / 100;
+}
+
+static int stv090x_set_vit_thacq(struct stv090x_state *state)
+{
+ if (STV090x_WRITE_DEMOD(state, VTH12, 0x96) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VTH23, 0x64) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VTH34, 0x36) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VTH56, 0x23) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VTH67, 0x1e) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VTH78, 0x19) < 0)
+ goto err;
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_set_vit_thtracq(struct stv090x_state *state)
+{
+ if (STV090x_WRITE_DEMOD(state, VTH12, 0xd0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VTH23, 0x7d) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VTH34, 0x53) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VTH56, 0x2f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VTH67, 0x24) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VTH78, 0x1f) < 0)
+ goto err;
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_set_viterbi(struct stv090x_state *state)
+{
+ switch (state->search_mode) {
+ case STV090x_SEARCH_AUTO:
+ if (STV090x_WRITE_DEMOD(state, FECM, 0x10) < 0) /* DVB-S and DVB-S2 */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x3f) < 0) /* all puncture rate */
+ goto err;
+ break;
+ case STV090x_SEARCH_DVBS1:
+ if (STV090x_WRITE_DEMOD(state, FECM, 0x00) < 0) /* disable DSS */
+ goto err;
+ switch (state->fec) {
+ case STV090x_PR12:
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)
+ goto err;
+ break;
+
+ case STV090x_PR23:
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)
+ goto err;
+ break;
+
+ case STV090x_PR34:
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x04) < 0)
+ goto err;
+ break;
+
+ case STV090x_PR56:
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x08) < 0)
+ goto err;
+ break;
+
+ case STV090x_PR78:
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x20) < 0)
+ goto err;
+ break;
+
+ default:
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x2f) < 0) /* all */
+ goto err;
+ break;
+ }
+ break;
+ case STV090x_SEARCH_DSS:
+ if (STV090x_WRITE_DEMOD(state, FECM, 0x80) < 0)
+ goto err;
+ switch (state->fec) {
+ case STV090x_PR12:
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)
+ goto err;
+ break;
+
+ case STV090x_PR23:
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)
+ goto err;
+ break;
+
+ case STV090x_PR67:
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x10) < 0)
+ goto err;
+ break;
+
+ default:
+ if (STV090x_WRITE_DEMOD(state, PRVIT, 0x13) < 0) /* 1/2, 2/3, 6/7 */
+ goto err;
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_stop_modcod(struct stv090x_state *state)
+{
+ if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xff) < 0)
+ goto err;
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_activate_modcod(struct stv090x_state *state)
+{
+ if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)
+ goto err;
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_activate_modcod_single(struct stv090x_state *state)
+{
+
+ if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xf0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0x0f) < 0)
+ goto err;
+
+ return 0;
+
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable)
+{
+ u32 reg;
+
+ switch (state->demod) {
+ case STV090x_DEMODULATOR_0:
+ mutex_lock(&demod_lock);
+ reg = stv090x_read_reg(state, STV090x_STOPCLK2);
+ STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable);
+ if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
+ goto err;
+ mutex_unlock(&demod_lock);
+ break;
+
+ case STV090x_DEMODULATOR_1:
+ mutex_lock(&demod_lock);
+ reg = stv090x_read_reg(state, STV090x_STOPCLK2);
+ STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable);
+ if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
+ goto err;
+ mutex_unlock(&demod_lock);
+ break;
+
+ default:
+ dprintk(FE_ERROR, 1, "Wrong demodulator!");
+ break;
+ }
+ return 0;
+err:
+ mutex_unlock(&demod_lock);
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_dvbs_track_crl(struct stv090x_state *state)
+{
+ if (state->dev_ver >= 0x30) {
+ /* Set ACLC BCLC optimised value vs SR */
+ if (state->srate >= 15000000) {
+ if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, BCLC, 0x1a) < 0)
+ goto err;
+ } else if ((state->srate >= 7000000) && (15000000 > state->srate)) {
+ if (STV090x_WRITE_DEMOD(state, ACLC, 0x0c) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, BCLC, 0x1b) < 0)
+ goto err;
+ } else if (state->srate < 7000000) {
+ if (STV090x_WRITE_DEMOD(state, ACLC, 0x2c) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, BCLC, 0x1c) < 0)
+ goto err;
+ }
+
+ } else {
+ /* Cut 2.0 */
+ if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
+ goto err;
+ }
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_delivery_search(struct stv090x_state *state)
+{
+ u32 reg;
+
+ switch (state->search_mode) {
+ case STV090x_SEARCH_DVBS1:
+ case STV090x_SEARCH_DSS:
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+ STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+
+ /* Activate Viterbi decoder in legacy search,
+ * do not use FRESVIT1, might impact VITERBI2
+ */
+ if (stv090x_vitclk_ctl(state, 0) < 0)
+ goto err;
+
+ if (stv090x_dvbs_track_crl(state) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x22) < 0) /* disable DVB-S2 */
+ goto err;
+
+ if (stv090x_set_vit_thacq(state) < 0)
+ goto err;
+ if (stv090x_set_viterbi(state) < 0)
+ goto err;
+ break;
+
+ case STV090x_SEARCH_DVBS2:
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
+ STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+ STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+ STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+
+ if (stv090x_vitclk_ctl(state, 1) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) /* stop DVB-S CR loop */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
+ goto err;
+
+ if (state->dev_ver <= 0x20) {
+ /* enable S2 carrier loop */
+ if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
+ goto err;
+ } else {
+ /* > Cut 3: Stop carrier 3 */
+ if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)
+ goto err;
+ }
+
+ if (state->demod_mode != STV090x_SINGLE) {
+ /* Cut 2: enable link during search */
+ if (stv090x_activate_modcod(state) < 0)
+ goto err;
+ } else {
+ /* Single demodulator
+ * Authorize SHORT and LONG frames,
+ * QPSK, 8PSK, 16APSK and 32APSK
+ */
+ if (stv090x_activate_modcod_single(state) < 0)
+ goto err;
+ }
+
+ break;
+
+ case STV090x_SEARCH_AUTO:
+ default:
+ /* enable DVB-S2 and DVB-S2 in Auto MODE */
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+ STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+
+ if (stv090x_vitclk_ctl(state, 0) < 0)
+ goto err;
+
+ if (stv090x_dvbs_track_crl(state) < 0)
+ goto err;
+
+ if (state->dev_ver <= 0x20) {
+ /* enable S2 carrier loop */
+ if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
+ goto err;
+ } else {
+ /* > Cut 3: Stop carrier 3 */
+ if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)
+ goto err;
+ }
+
+ if (state->demod_mode != STV090x_SINGLE) {
+ /* Cut 2: enable link during search */
+ if (stv090x_activate_modcod(state) < 0)
+ goto err;
+ } else {
+ /* Single demodulator
+ * Authorize SHORT and LONG frames,
+ * QPSK, 8PSK, 16APSK and 32APSK
+ */
+ if (stv090x_activate_modcod_single(state) < 0)
+ goto err;
+ }
+
+ if (state->srate >= 2000000) {
+ /* Srate >= 2MSPS, Viterbi threshold to acquire */
+ if (stv090x_set_vit_thacq(state) < 0)
+ goto err;
+ } else {
+ /* Srate < 2MSPS, Reset Viterbi thresholdto track
+ * and then re-acquire
+ */
+ if (stv090x_set_vit_thtracq(state) < 0)
+ goto err;
+ }
+
+ if (stv090x_set_viterbi(state) < 0)
+ goto err;
+ break;
+ }
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_start_search(struct stv090x_state *state)
+{
+ u32 reg, freq_abs;
+ s16 freq;
+
+ /* Reset demodulator */
+ reg = STV090x_READ_DEMOD(state, DMDISTATE);
+ STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f);
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
+ goto err;
+
+ if (state->dev_ver <= 0x20) {
+ if (state->srate <= 5000000) {
+ if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRUP1, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0)
+ goto err;
+
+ /*enlarge the timing bandwith for Low SR*/
+ if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0)
+ goto err;
+ } else {
+ /* If the symbol rate is >5 Msps
+ Set The carrier search up and low to auto mode */
+ if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
+ goto err;
+ /*reduce the timing bandwith for high SR*/
+ if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
+ goto err;
+ }
+ } else {
+ /* >= Cut 3 */
+ if (state->srate <= 5000000) {
+ /* enlarge the timing bandwith for Low SR */
+ STV090x_WRITE_DEMOD(state, RTCS2, 0x68);
+ } else {
+ /* reduce timing bandwith for high SR */
+ STV090x_WRITE_DEMOD(state, RTCS2, 0x44);
+ }
+
+ /* Set CFR min and max to manual mode */
+ STV090x_WRITE_DEMOD(state, CARCFG, 0x46);
+
+ if (state->algo == STV090x_WARM_SEARCH) {
+ /* WARM Start
+ * CFR min = -1MHz,
+ * CFR max = +1MHz
+ */
+ freq_abs = 1000 << 16;
+ freq_abs /= (state->mclk / 1000);
+ freq = (s16) freq_abs;
+ } else {
+ /* COLD Start
+ * CFR min =- (SearchRange / 2 + 600KHz)
+ * CFR max = +(SearchRange / 2 + 600KHz)
+ * (600KHz for the tuner step size)
+ */
+ freq_abs = (state->search_range / 2000) + 600;
+ freq_abs = freq_abs << 16;
+ freq_abs /= (state->mclk / 1000);
+ freq = (s16) freq_abs;
+ }
+
+ if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRUP1, LSB(freq)) < 0)
+ goto err;
+
+ freq *= -1;
+
+ if (STV090x_WRITE_DEMOD(state, CFRLOW1, MSB(freq)) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRLOW0, LSB(freq)) < 0)
+ goto err;
+
+ }
+
+ if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0)
+ goto err;
+
+ if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
+ goto err;
+
+ if ((state->search_mode == STV090x_DVBS1) ||
+ (state->search_mode == STV090x_DSS) ||
+ (state->search_mode == STV090x_SEARCH_AUTO)) {
+
+ if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0)
+ goto err;
+ }
+ }
+
+ if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xe0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xc0) < 0)
+ goto err;
+
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
+ STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+ reg = STV090x_READ_DEMOD(state, DMDCFG2);
+ STV090x_SETFIELD_Px(reg, S1S2_SEQUENTIAL_FIELD, 0x0);
+ if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0)
+ goto err;
+
+ if (state->dev_ver >= 0x20) {
+ /*Frequency offset detector setting*/
+ if (state->srate < 2000000) {
+ if (state->dev_ver <= 0x20) {
+ /* Cut 2 */
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
+ goto err;
+ } else {
+ /* Cut 2 */
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0)
+ goto err;
+ }
+ if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0)
+ goto err;
+ }
+
+ if (state->srate < 10000000) {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0)
+ goto err;
+ } else {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0)
+ goto err;
+ }
+ } else {
+ if (state->srate < 10000000) {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0)
+ goto err;
+ } else {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0)
+ goto err;
+ }
+ }
+
+ switch (state->algo) {
+ case STV090x_WARM_SEARCH:
+ /* The symbol rate and the exact
+ * carrier Frequency are known
+ */
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
+ goto err;
+ break;
+
+ case STV090x_COLD_SEARCH:
+ /* The symbol rate is known */
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
+ goto err;
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_get_agc2_min_level(struct stv090x_state *state)
+{
+ u32 agc2_min = 0, agc2 = 0, freq_init, freq_step, reg;
+ s32 i, j, steps, dir;
+
+ if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+ goto err;
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
+ STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) /* SR = 65 Msps Max */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) /* SR= 400 ksps Min */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) /* stop acq @ coarse carrier state */
+ goto err;
+ if (stv090x_set_srate(state, 1000000) < 0)
+ goto err;
+
+ steps = -1 + state->search_range / 1000000;
+ steps /= 2;
+ steps = (2 * steps) + 1;
+ if (steps < 0)
+ steps = 1;
+
+ dir = 1;
+ freq_step = (1000000 * 256) / (state->mclk / 256);
+ freq_init = 0;
+
+ for (i = 0; i < steps; i++) {
+ if (dir > 0)
+ freq_init = freq_init + (freq_step * i);
+ else
+ freq_init = freq_init - (freq_step * i);
+
+ dir = -1;
+
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_init >> 8) & 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_init & 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */
+ goto err;
+ msleep(10);
+ for (j = 0; j < 10; j++) {
+ agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8;
+ agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+ }
+ agc2 /= 10;
+ agc2_min = 0xffff;
+ if (agc2 < 0xffff)
+ agc2_min = agc2;
+ }
+
+ return agc2_min;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk)
+{
+ u8 r3, r2, r1, r0;
+ s32 srate, int_1, int_2, tmp_1, tmp_2;
+
+ r3 = STV090x_READ_DEMOD(state, SFR3);
+ r2 = STV090x_READ_DEMOD(state, SFR2);
+ r1 = STV090x_READ_DEMOD(state, SFR1);
+ r0 = STV090x_READ_DEMOD(state, SFR0);
+
+ srate = ((r3 << 24) | (r2 << 16) | (r1 << 8) | r0);
+
+ int_1 = clk >> 16;
+ int_2 = srate >> 16;
+
+ tmp_1 = clk % 0x10000;
+ tmp_2 = srate % 0x10000;
+
+ srate = (int_1 * int_2) +
+ ((int_1 * tmp_2) >> 16) +
+ ((int_2 * tmp_1) >> 16);
+
+ return srate;
+}
+
+static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
+{
+ struct dvb_frontend *fe = &state->frontend;
+
+ int tmg_lock = 0, i;
+ s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq;
+ u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
+
+ reg = STV090x_READ_DEMOD(state, DMDISTATE);
+ STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0)
+ goto err;
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
+ STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0)
+ goto err;
+
+ if (state->dev_ver >= 0x30) {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
+ goto err;
+
+ } else if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
+ goto err;
+ }
+
+ if (state->srate <= 2000000)
+ car_step = 1000;
+ else if (state->srate <= 5000000)
+ car_step = 2000;
+ else if (state->srate <= 12000000)
+ car_step = 3000;
+ else
+ car_step = 5000;
+
+ steps = -1 + ((state->search_range / 1000) / car_step);
+ steps /= 2;
+ steps = (2 * steps) + 1;
+ if (steps < 0)
+ steps = 1;
+ else if (steps > 10) {
+ steps = 11;
+ car_step = (state->search_range / 1000) / 10;
+ }
+ cur_step = 0;
+ dir = 1;
+ freq = state->frequency;
+
+ while ((!tmg_lock) && (cur_step < steps)) {
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */
+ goto err;
+ reg = STV090x_READ_DEMOD(state, DMDISTATE);
+ STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x00); /* trigger acquisition */
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
+ goto err;
+ msleep(50);
+ for (i = 0; i < 10; i++) {
+ reg = STV090x_READ_DEMOD(state, DSTATUS);
+ if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
+ tmg_cpt++;
+ agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8;
+ agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+ }
+ agc2 /= 10;
+ srate_coarse = stv090x_get_srate(state, state->mclk);
+ cur_step++;
+ dir *= -1;
+ if ((tmg_cpt >= 5) && (agc2 < 0x1f00) && (srate_coarse < 55000000) && (srate_coarse > 850000))
+ tmg_lock = 1;
+ else if (cur_step < steps) {
+ if (dir > 0)
+ freq += cur_step * car_step;
+ else
+ freq -= cur_step * car_step;
+
+ /* Setup tuner */
+ if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+ goto err;
+
+ if (state->config->tuner_set_frequency) {
+ if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
+ goto err;
+ }
+
+ if (state->config->tuner_set_bandwidth) {
+ if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
+ goto err;
+ }
+
+ if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
+ goto err;
+
+ msleep(50);
+
+ if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+ goto err;
+
+ if (state->config->tuner_get_status) {
+ if (state->config->tuner_get_status(fe, &reg) < 0)
+ goto err;
+ }
+
+ if (reg)
+ dprintk(FE_DEBUG, 1, "Tuner phase locked");
+ else
+ dprintk(FE_DEBUG, 1, "Tuner unlocked");
+
+ if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
+ goto err;
+
+ }
+ }
+ if (!tmg_lock)
+ srate_coarse = 0;
+ else
+ srate_coarse = stv090x_get_srate(state, state->mclk);
+
+ return srate_coarse;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
+{
+ u32 srate_coarse, freq_coarse, sym, reg;
+
+ srate_coarse = stv090x_get_srate(state, state->mclk);
+ freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8;
+ freq_coarse |= STV090x_READ_DEMOD(state, CFR1);
+ sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
+
+ if (sym < state->srate)
+ srate_coarse = 0;
+ else {
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)
+ goto err;
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+
+ if (state->dev_ver >= 0x30) {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
+ goto err;
+ } else if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
+ goto err;
+ }
+
+ if (srate_coarse > 3000000) {
+ sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
+ sym = (sym / 1000) * 65536;
+ sym /= (state->mclk / 1000);
+ if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
+ goto err;
+ sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */
+ sym = (sym / 1000) * 65536;
+ sym /= (state->mclk / 1000);
+ if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
+ goto err;
+ sym = (srate_coarse / 1000) * 65536;
+ sym /= (state->mclk / 1000);
+ if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
+ goto err;
+ } else {
+ sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
+ sym = (sym / 100) * 65536;
+ sym /= (state->mclk / 100);
+ if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
+ goto err;
+ sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */
+ sym = (sym / 100) * 65536;
+ sym /= (state->mclk / 100);
+ if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
+ goto err;
+ sym = (srate_coarse / 100) * 65536;
+ sym /= (state->mclk / 100);
+ if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
+ goto err;
+ }
+ if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_coarse >> 8) & 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_coarse & 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) /* trigger acquisition */
+ goto err;
+ }
+
+ return srate_coarse;
+
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout)
+{
+ s32 timer = 0, lock = 0;
+ u32 reg;
+ u8 stat;
+
+ while ((timer < timeout) && (!lock)) {
+ reg = STV090x_READ_DEMOD(state, DMDSTATE);
+ stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
+
+ switch (stat) {
+ case 0: /* searching */
+ case 1: /* first PLH detected */
+ default:
+ dprintk(FE_DEBUG, 1, "Demodulator searching ..");
+ lock = 0;
+ break;
+ case 2: /* DVB-S2 mode */
+ case 3: /* DVB-S1/legacy mode */
+ reg = STV090x_READ_DEMOD(state, DSTATUS);
+ lock = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
+ break;
+ }
+
+ if (!lock)
+ msleep(10);
+ else
+ dprintk(FE_DEBUG, 1, "Demodulator acquired LOCK");
+
+ timer += 10;
+ }
+ return lock;
+}
+
+static int stv090x_blind_search(struct stv090x_state *state)
+{
+ u32 agc2, reg, srate_coarse;
+ s32 timeout_dmd = 500, cpt_fail, agc2_ovflw, i;
+ u8 k_ref, k_max, k_min;
+ int coarse_fail, lock;
+
+ k_max = 120;
+ k_min = 30;
+
+ agc2 = stv090x_get_agc2_min_level(state);
+
+ if (agc2 > STV090x_SEARCH_AGC2_TH(state->dev_ver)) {
+ lock = 0;
+ } else {
+
+ if (state->dev_ver <= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
+ goto err;
+ } else {
+ /* > Cut 3 */
+ if (STV090x_WRITE_DEMOD(state, CARCFG, 0x06) < 0)
+ goto err;
+ }
+
+ if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
+ goto err;
+
+ if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) /* set viterbi hysteresis */
+ goto err;
+ }
+
+ k_ref = k_max;
+ do {
+ if (STV090x_WRITE_DEMOD(state, KREFTMG, k_ref) < 0)
+ goto err;
+ if (stv090x_srate_srch_coarse(state) != 0) {
+ srate_coarse = stv090x_srate_srch_fine(state);
+ if (srate_coarse != 0) {
+ stv090x_get_lock_tmg(state);
+ lock = stv090x_get_dmdlock(state, timeout_dmd);
+ } else {
+ lock = 0;
+ }
+ } else {
+ cpt_fail = 0;
+ agc2_ovflw = 0;
+ for (i = 0; i < 10; i++) {
+ agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8;
+ agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+ if (agc2 >= 0xff00)
+ agc2_ovflw++;
+ reg = STV090x_READ_DEMOD(state, DSTATUS2);
+ if ((STV090x_GETFIELD_Px(reg, CFR_OVERFLOW_FIELD) == 0x01) &&
+ (STV090x_GETFIELD_Px(reg, DEMOD_DELOCK_FIELD) == 0x01))
+
+ cpt_fail++;
+ }
+ if ((cpt_fail > 7) || (agc2_ovflw > 7))
+ coarse_fail = 1;
+
+ lock = 0;
+ }
+ k_ref -= 30;
+ } while ((k_ref >= k_min) && (!lock) && (!coarse_fail));
+ }
+
+ return lock;
+
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_chk_tmg(struct stv090x_state *state)
+{
+ u32 reg;
+ s32 tmg_cpt = 0, i;
+ u8 freq, tmg_thh, tmg_thl;
+ int tmg_lock;
+
+ freq = STV090x_READ_DEMOD(state, CARFREQ);
+ tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE);
+ tmg_thl = STV090x_READ_DEMOD(state, TMGTHFALL);
+ if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)
+ goto err;
+
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); /* stop carrier offset search */
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, RTC, 0x80) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, RTCS2, 0x40) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x00) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) /* set car ofset to 0 */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x65) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* trigger acquisition */
+ goto err;
+ msleep(10);
+
+ for (i = 0; i < 10; i++) {
+ reg = STV090x_READ_DEMOD(state, DSTATUS);
+ if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
+ tmg_cpt++;
+ msleep(1);
+ }
+ if (tmg_cpt >= 3)
+ tmg_lock = 1;
+
+ if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) /* DVB-S1 timing */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) /* DVB-S2 timing */
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, freq) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGTHRISE, tmg_thh) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGTHFALL, tmg_thl) < 0)
+ goto err;
+
+ return tmg_lock;
+
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
+{
+ struct dvb_frontend *fe = &state->frontend;
+
+ u32 reg;
+ s32 car_step, steps, cur_step, dir, freq, timeout_lock;
+ int lock = 0;
+
+ if (state->srate >= 10000000)
+ timeout_lock = timeout_dmd / 3;
+ else
+ timeout_lock = timeout_dmd / 2;
+
+ lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */
+ if (!lock) {
+ if (state->srate >= 10000000) {
+ if (stv090x_chk_tmg(state)) {
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
+ goto err;
+ lock = stv090x_get_dmdlock(state, timeout_dmd);
+ } else {
+ lock = 0;
+ }
+ } else {
+ if (state->srate <= 4000000)
+ car_step = 1000;
+ else if (state->srate <= 7000000)
+ car_step = 2000;
+ else if (state->srate <= 10000000)
+ car_step = 3000;
+ else
+ car_step = 5000;
+
+ steps = (state->search_range / 1000) / car_step;
+ steps /= 2;
+ steps = 2 * (steps + 1);
+ if (steps < 0)
+ steps = 2;
+ else if (steps > 12)
+ steps = 12;
+
+ cur_step = 1;
+ dir = 1;
+
+ if (!lock) {
+ freq = state->frequency;
+ state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
+ while ((cur_step <= steps) && (!lock)) {
+ if (dir > 0)
+ freq += cur_step * car_step;
+ else
+ freq -= cur_step * car_step;
+
+ /* Setup tuner */
+ if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+ goto err;
+
+ if (state->config->tuner_set_frequency) {
+ if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
+ goto err;
+ }
+
+ if (state->config->tuner_set_bandwidth) {
+ if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
+ goto err;
+ }
+
+ if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
+ goto err;
+
+ msleep(50);
+
+ if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+ goto err;
+
+ if (state->config->tuner_get_status) {
+ if (state->config->tuner_get_status(fe, &reg) < 0)
+ goto err;
+ }
+
+ if (reg)
+ dprintk(FE_DEBUG, 1, "Tuner phase locked");
+ else
+ dprintk(FE_DEBUG, 1, "Tuner unlocked");
+
+ if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
+ goto err;
+
+ STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
+ if (state->delsys == STV090x_DVBS2) {
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
+ STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+ STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+ STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+ }
+ if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
+ goto err;
+ lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
+
+ dir *= -1;
+ cur_step++;
+ }
+ }
+ }
+ }
+
+ return lock;
+
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s32 *timeout_sw, s32 *steps)
+{
+ s32 timeout, inc, steps_max, srate, car_max;
+
+ srate = state->srate;
+ car_max = state->search_range / 1000;
+ car_max += car_max / 10;
+ car_max = 65536 * (car_max / 2);
+ car_max /= (state->mclk / 1000);
+
+ if (car_max > 0x4000)
+ car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */
+
+ inc = srate;
+ inc /= state->mclk / 1000;
+ inc *= 256;
+ inc *= 256;
+ inc /= 1000;
+
+ switch (state->search_mode) {
+ case STV090x_SEARCH_DVBS1:
+ case STV090x_SEARCH_DSS:
+ inc *= 3; /* freq step = 3% of srate */
+ timeout = 20;
+ break;
+
+ case STV090x_SEARCH_DVBS2:
+ inc *= 4;
+ timeout = 25;
+ break;
+
+ case STV090x_SEARCH_AUTO:
+ default:
+ inc *= 3;
+ timeout = 25;
+ break;
+ }
+ inc /= 100;
+ if ((inc > car_max) || (inc < 0))
+ inc = car_max / 2; /* increment <= 1/8 Mclk */
+
+ timeout *= 27500; /* 27.5 Msps reference */
+ if (srate > 0)
+ timeout /= (srate / 1000);
+
+ if ((timeout > 100) || (timeout < 0))
+ timeout = 100;
+
+ steps_max = (car_max / inc) + 1; /* min steps = 3 */
+ if ((steps_max > 100) || (steps_max < 0)) {
+ steps_max = 100; /* max steps <= 100 */
+ inc = car_max / steps_max;
+ }
+ *freq_inc = inc;
+ *timeout_sw = timeout;
+ *steps = steps_max;
+
+ return 0;
+}
+
+static int stv090x_chk_signal(struct stv090x_state *state)
+{
+ s32 offst_car, agc2, car_max;
+ int no_signal;
+
+ offst_car = STV090x_READ_DEMOD(state, CFR2) << 8;
+ offst_car |= STV090x_READ_DEMOD(state, CFR1);
+ offst_car = comp2(offst_car, 16);
+
+ agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8;
+ agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+ car_max = state->search_range / 1000;
+
+ car_max += (car_max / 10); /* 10% margin */
+ car_max = (65536 * car_max / 2);
+ car_max /= state->mclk / 1000;
+
+ if (car_max > 0x4000)
+ car_max = 0x4000;
+
+ if ((agc2 > 0x2000) || (offst_car > 2 * car_max) || (offst_car < -2 * car_max)) {
+ no_signal = 1;
+ dprintk(FE_DEBUG, 1, "No Signal");
+ } else {
+ no_signal = 0;
+ dprintk(FE_DEBUG, 1, "Found Signal");
+ }
+
+ return no_signal;
+}
+
+static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 timeout, int zigzag, s32 steps_max)
+{
+ int no_signal, lock = 0;
+ s32 cpt_step = 0, offst_freq, car_max;
+ u32 reg;
+
+ car_max = state->search_range / 1000;
+ car_max += (car_max / 10);
+ car_max = (65536 * car_max / 2);
+ car_max /= (state->mclk / 1000);
+ if (car_max > 0x4000)
+ car_max = 0x4000;
+
+ if (zigzag)
+ offst_freq = 0;
+ else
+ offst_freq = -car_max + inc;
+
+ do {
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT1, ((offst_freq / 256) & 0xff)) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT0, offst_freq & 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
+ goto err;
+
+ reg = STV090x_READ_DEMOD(state, PDELCTRL1);
+ STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x1); /* stop DVB-S2 packet delin */
+ if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
+ goto err;
+
+ if (zigzag) {
+ if (offst_freq >= 0)
+ offst_freq = -offst_freq - 2 * inc;
+ else
+ offst_freq = -offst_freq;
+ } else {
+ offst_freq += 2 * inc;
+ }
+
+ cpt_step++;
+
+ lock = stv090x_get_dmdlock(state, timeout);
+ no_signal = stv090x_chk_signal(state);
+
+ } while ((!lock) &&
+ (!no_signal) &&
+ ((offst_freq - inc) < car_max) &&
+ ((offst_freq + inc) > -car_max) &&
+ (cpt_step < steps_max));
+
+ reg = STV090x_READ_DEMOD(state, PDELCTRL1);
+ STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
+ goto err;
+
+ return lock;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_sw_algo(struct stv090x_state *state)
+{
+ int no_signal, zigzag, lock = 0;
+ u32 reg;
+
+ s32 dvbs2_fly_wheel;
+ s32 inc, timeout_step, trials, steps_max;
+
+ /* get params */
+ stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max);
+
+ switch (state->search_mode) {
+ case STV090x_SEARCH_DVBS1:
+ case STV090x_SEARCH_DSS:
+ /* accelerate the frequency detector */
+ if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0)
+ goto err;
+ }
+
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x49) < 0)
+ goto err;
+ zigzag = 0;
+ break;
+
+ case STV090x_SEARCH_DVBS2:
+ if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
+ goto err;
+ }
+
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)
+ goto err;
+ zigzag = 1;
+ break;
+
+ case STV090x_SEARCH_AUTO:
+ default:
+ /* accelerate the frequency detector */
+ if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
+ goto err;
+ }
+
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0xc9) < 0)
+ goto err;
+ zigzag = 0;
+ break;
+ }
+
+ trials = 0;
+ do {
+ lock = stv090x_search_car_loop(state, inc, timeout_step, zigzag, steps_max);
+ no_signal = stv090x_chk_signal(state);
+ trials++;
+
+ /*run the SW search 2 times maximum*/
+ if (lock || no_signal || (trials == 2)) {
+ /*Check if the demod is not losing lock in DVBS2*/
+ if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
+ goto err;
+ }
+
+ reg = STV090x_READ_DEMOD(state, DMDSTATE);
+ if ((lock) && (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == STV090x_DVBS2)) {
+ /*Check if the demod is not losing lock in DVBS2*/
+ msleep(timeout_step);
+ reg = STV090x_READ_DEMOD(state, DMDFLYW);
+ dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);
+ if (dvbs2_fly_wheel < 0xd) { /*if correct frames is decrementing */
+ msleep(timeout_step);
+ reg = STV090x_READ_DEMOD(state, DMDFLYW);
+ dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);
+ }
+ if (dvbs2_fly_wheel < 0xd) {
+ /*FALSE lock, The demod is loosing lock */
+ lock = 0;
+ if (trials < 2) {
+ if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
+ goto err;
+ }
+
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)
+ goto err;
+ }
+ }
+ }
+ }
+ } while ((!lock) && (trials < 2) && (!no_signal));
+
+ return lock;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static enum stv090x_delsys stv090x_get_std(struct stv090x_state *state)
+{
+ u32 reg;
+ enum stv090x_delsys delsys;
+
+ reg = STV090x_READ_DEMOD(state, DMDSTATE);
+ if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 2)
+ delsys = STV090x_DVBS2;
+ else if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) {
+ reg = STV090x_READ_DEMOD(state, FECM);
+ if (STV090x_GETFIELD_Px(reg, DSS_DVB_FIELD) == 1)
+ delsys = STV090x_DSS;
+ else
+ delsys = STV090x_DVBS1;
+ } else {
+ delsys = STV090x_ERROR;
+ }
+
+ return delsys;
+}
+
+/* in Hz */
+static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk)
+{
+ s32 derot, int_1, int_2, tmp_1, tmp_2;
+
+ derot = STV090x_READ_DEMOD(state, CFR2) << 16;
+ derot |= STV090x_READ_DEMOD(state, CFR1) << 8;
+ derot |= STV090x_READ_DEMOD(state, CFR0);
+
+ derot = comp2(derot, 24);
+ int_1 = state->mclk >> 12;
+ int_2 = derot >> 12;
+
+ /* carrier_frequency = MasterClock * Reg / 2^24 */
+ tmp_1 = state->mclk % 0x1000;
+ tmp_2 = derot % 0x1000;
+
+ derot = (int_1 * int_2) +
+ ((int_1 * tmp_2) >> 12) +
+ ((int_1 * tmp_1) >> 12);
+
+ return derot;
+}
+
+static int stv090x_get_viterbi(struct stv090x_state *state)
+{
+ u32 reg, rate;
+
+ reg = STV090x_READ_DEMOD(state, VITCURPUN);
+ rate = STV090x_GETFIELD_Px(reg, VIT_CURPUN_FIELD);
+
+ switch (rate) {
+ case 13:
+ state->fec = STV090x_PR12;
+ break;
+
+ case 18:
+ state->fec = STV090x_PR23;
+ break;
+
+ case 21:
+ state->fec = STV090x_PR34;
+ break;
+
+ case 24:
+ state->fec = STV090x_PR56;
+ break;
+
+ case 25:
+ state->fec = STV090x_PR67;
+ break;
+
+ case 26:
+ state->fec = STV090x_PR78;
+ break;
+
+ default:
+ state->fec = STV090x_PRERR;
+ break;
+ }
+
+ return 0;
+}
+
+static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state)
+{
+ struct dvb_frontend *fe = &state->frontend;
+
+ u8 tmg;
+ u32 reg;
+ s32 i = 0, offst_freq;
+
+ msleep(5);
+
+ if (state->algo == STV090x_BLIND_SEARCH) {
+ tmg = STV090x_READ_DEMOD(state, TMGREG2);
+ STV090x_WRITE_DEMOD(state, SFRSTEP, 0x5c);
+ while ((i <= 50) && (tmg != 0) && (tmg != 0xff)) {
+ tmg = STV090x_READ_DEMOD(state, TMGREG2);
+ msleep(5);
+ i += 5;
+ }
+ }
+ state->delsys = stv090x_get_std(state);
+
+ if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+ goto err;
+
+ if (state->config->tuner_get_frequency) {
+ if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
+ goto err;
+ }
+
+ if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
+ goto err;
+
+ offst_freq = stv090x_get_car_freq(state, state->mclk) / 1000;
+ state->frequency += offst_freq;
+
+ if (stv090x_get_viterbi(state) < 0)
+ goto err;
+
+ reg = STV090x_READ_DEMOD(state, DMDMODCOD);
+ state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
+ state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;
+ state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1;
+ reg = STV090x_READ_DEMOD(state, TMGOBS);
+ state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD);
+ reg = STV090x_READ_DEMOD(state, FECM);
+ state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD);
+
+ if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) {
+
+ if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+ goto err;
+
+ if (state->config->tuner_get_frequency) {
+ if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
+ goto err;
+ }
+
+ if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
+ goto err;
+
+ if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
+ return STV090x_RANGEOK;
+ else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000))
+ return STV090x_RANGEOK;
+ else
+ return STV090x_OUTOFRANGE; /* Out of Range */
+ } else {
+ if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
+ return STV090x_RANGEOK;
+ else
+ return STV090x_OUTOFRANGE;
+ }
+
+ return STV090x_OUTOFRANGE;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate)
+{
+ s32 offst_tmg;
+
+ offst_tmg = STV090x_READ_DEMOD(state, TMGREG2) << 16;
+ offst_tmg |= STV090x_READ_DEMOD(state, TMGREG1) << 8;
+ offst_tmg |= STV090x_READ_DEMOD(state, TMGREG0);
+
+ offst_tmg = comp2(offst_tmg, 24); /* 2's complement */
+ if (!offst_tmg)
+ offst_tmg = 1;
+
+ offst_tmg = ((s32) srate * 10) / ((s32) 0x1000000 / offst_tmg);
+ offst_tmg /= 320;
+
+ return offst_tmg;
+}
+
+static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_modcod modcod, s32 pilots)
+{
+ u8 aclc = 0x29;
+ s32 i;
+ struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low;
+
+ if (state->dev_ver == 0x20) {
+ car_loop = stv090x_s2_crl_cut20;
+ car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20;
+ car_loop_apsk_low = stv090x_s2_apsk_crl_cut20;
+ } else {
+ /* >= Cut 3 */
+ car_loop = stv090x_s2_crl_cut30;
+ car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut30;
+ car_loop_apsk_low = stv090x_s2_apsk_crl_cut30;
+ }
+
+ if (modcod < STV090x_QPSK_12) {
+ i = 0;
+ while ((i < 3) && (modcod != car_loop_qpsk_low[i].modcod))
+ i++;
+
+ if (i >= 3)
+ i = 2;
+
+ } else {
+ i = 0;
+ while ((i < 14) && (modcod != car_loop[i].modcod))
+ i++;
+
+ if (i >= 14) {
+ i = 0;
+ while ((i < 11) && (modcod != car_loop_apsk_low[i].modcod))
+ i++;
+
+ if (i >= 11)
+ i = 10;
+ }
+ }
+
+ if (modcod <= STV090x_QPSK_25) {
+ if (pilots) {
+ if (state->srate <= 3000000)
+ aclc = car_loop_qpsk_low[i].crl_pilots_on_2;
+ else if (state->srate <= 7000000)
+ aclc = car_loop_qpsk_low[i].crl_pilots_on_5;
+ else if (state->srate <= 15000000)
+ aclc = car_loop_qpsk_low[i].crl_pilots_on_10;
+ else if (state->srate <= 25000000)
+ aclc = car_loop_qpsk_low[i].crl_pilots_on_20;
+ else
+ aclc = car_loop_qpsk_low[i].crl_pilots_on_30;
+ } else {
+ if (state->srate <= 3000000)
+ aclc = car_loop_qpsk_low[i].crl_pilots_off_2;
+ else if (state->srate <= 7000000)
+ aclc = car_loop_qpsk_low[i].crl_pilots_off_5;
+ else if (state->srate <= 15000000)
+ aclc = car_loop_qpsk_low[i].crl_pilots_off_10;
+ else if (state->srate <= 25000000)
+ aclc = car_loop_qpsk_low[i].crl_pilots_off_20;
+ else
+ aclc = car_loop_qpsk_low[i].crl_pilots_off_30;
+ }
+
+ } else if (modcod <= STV090x_8PSK_910) {
+ if (pilots) {
+ if (state->srate <= 3000000)
+ aclc = car_loop[i].crl_pilots_on_2;
+ else if (state->srate <= 7000000)
+ aclc = car_loop[i].crl_pilots_on_5;
+ else if (state->srate <= 15000000)
+ aclc = car_loop[i].crl_pilots_on_10;
+ else if (state->srate <= 25000000)
+ aclc = car_loop[i].crl_pilots_on_20;
+ else
+ aclc = car_loop[i].crl_pilots_on_30;
+ } else {
+ if (state->srate <= 3000000)
+ aclc = car_loop[i].crl_pilots_off_2;
+ else if (state->srate <= 7000000)
+ aclc = car_loop[i].crl_pilots_off_5;
+ else if (state->srate <= 15000000)
+ aclc = car_loop[i].crl_pilots_off_10;
+ else if (state->srate <= 25000000)
+ aclc = car_loop[i].crl_pilots_off_20;
+ else
+ aclc = car_loop[i].crl_pilots_off_30;
+ }
+ } else { /* 16APSK and 32APSK */
+ if (state->srate <= 3000000)
+ aclc = car_loop_apsk_low[i].crl_pilots_on_2;
+ else if (state->srate <= 7000000)
+ aclc = car_loop_apsk_low[i].crl_pilots_on_5;
+ else if (state->srate <= 15000000)
+ aclc = car_loop_apsk_low[i].crl_pilots_on_10;
+ else if (state->srate <= 25000000)
+ aclc = car_loop_apsk_low[i].crl_pilots_on_20;
+ else
+ aclc = car_loop_apsk_low[i].crl_pilots_on_30;
+ }
+
+ return aclc;
+}
+
+static u8 stv090x_optimize_carloop_short(struct stv090x_state *state)
+{
+ struct stv090x_short_frame_crloop *short_crl;
+ s32 index = 0;
+ u8 aclc = 0x0b;
+
+ switch (state->modulation) {
+ case STV090x_QPSK:
+ default:
+ index = 0;
+ break;
+ case STV090x_8PSK:
+ index = 1;
+ break;
+ case STV090x_16APSK:
+ index = 2;
+ break;
+ case STV090x_32APSK:
+ index = 3;
+ break;
+ }
+
+ if (state->dev_ver >= 0x30)
+ short_crl = stv090x_s2_short_crl_cut20;
+ else if (state->dev_ver >= 0x20)
+ short_crl = stv090x_s2_short_crl_cut30;
+
+ if (state->srate <= 3000000)
+ aclc = short_crl[index].crl_2;
+ else if (state->srate <= 7000000)
+ aclc = short_crl[index].crl_5;
+ else if (state->srate <= 15000000)
+ aclc = short_crl[index].crl_10;
+ else if (state->srate <= 25000000)
+ aclc = short_crl[index].crl_20;
+ else
+ aclc = short_crl[index].crl_30;
+
+ return aclc;
+}
+
+static int stv090x_optimize_track(struct stv090x_state *state)
+{
+ struct dvb_frontend *fe = &state->frontend;
+
+ enum stv090x_rolloff rolloff;
+ enum stv090x_modcod modcod;
+
+ s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0;
+ u32 reg;
+
+ srate = stv090x_get_srate(state, state->mclk);
+ srate += stv090x_get_tmgoffst(state, srate);
+
+ switch (state->delsys) {
+ case STV090x_DVBS1:
+ case STV090x_DSS:
+ if (state->algo == STV090x_SEARCH_AUTO) {
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+ STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+ }
+ reg = STV090x_READ_DEMOD(state, DEMOD);
+ STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);
+ STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x01);
+ if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
+ goto err;
+
+ if (state->dev_ver >= 0x30) {
+ if (stv090x_get_viterbi(state) < 0)
+ goto err;
+
+ if (state->fec == STV090x_PR12) {
+ if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x98) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)
+ goto err;
+ } else {
+ if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x18) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)
+ goto err;
+ }
+ }
+
+ if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)
+ goto err;
+ break;
+
+ case STV090x_DVBS2:
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
+ STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0)
+ goto err;
+ if (state->frame_len == STV090x_LONG_FRAME) {
+ reg = STV090x_READ_DEMOD(state, DMDMODCOD);
+ modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
+ pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;
+ aclc = stv090x_optimize_carloop(state, modcod, pilots);
+ if (modcod <= STV090x_QPSK_910) {
+ STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc);
+ } else if (modcod <= STV090x_8PSK_910) {
+ if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)
+ goto err;
+ }
+ if ((state->demod_mode == STV090x_SINGLE) && (modcod > STV090x_8PSK_910)) {
+ if (modcod <= STV090x_16APSK_910) {
+ if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)
+ goto err;
+ } else {
+ if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)
+ goto err;
+ }
+ }
+ } else {
+ /*Carrier loop setting for short frame*/
+ aclc = stv090x_optimize_carloop_short(state);
+ if (state->modulation == STV090x_QPSK) {
+ if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc) < 0)
+ goto err;
+ } else if (state->modulation == STV090x_8PSK) {
+ if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)
+ goto err;
+ } else if (state->modulation == STV090x_16APSK) {
+ if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)
+ goto err;
+ } else if (state->modulation == STV090x_32APSK) {
+ if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)
+ goto err;
+ }
+ }
+
+ STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */
+ break;
+
+ case STV090x_UNKNOWN:
+ default:
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+ STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+ break;
+ }
+
+ f_1 = STV090x_READ_DEMOD(state, CFR2);
+ f_0 = STV090x_READ_DEMOD(state, CFR1);
+ reg = STV090x_READ_DEMOD(state, TMGOBS);
+ rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD);
+
+ if (state->algo == STV090x_BLIND_SEARCH) {
+ STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00);
+ reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+ STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0x00);
+ STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);
+ if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
+ goto err;
+
+ if (stv090x_set_srate(state, srate) < 0)
+ goto err;
+ blind_tune = 1;
+ }
+
+ if (state->dev_ver >= 0x20) {
+ if ((state->search_mode == STV090x_SEARCH_DVBS1) ||
+ (state->search_mode == STV090x_SEARCH_DSS) ||
+ (state->search_mode == STV090x_SEARCH_AUTO)) {
+
+ if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x0a) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x00) < 0)
+ goto err;
+ }
+ }
+
+ if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+ goto err;
+
+ /* AUTO tracking MODE */
+ if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x80) < 0)
+ goto err;
+ /* AUTO tracking MODE */
+ if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0)
+ goto err;
+
+ if ((state->dev_ver >= 0x20) || (blind_tune == 1) || (state->srate < 10000000)) {
+ /* update initial carrier freq with the found freq offset */
+ if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
+ goto err;
+ state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000;
+
+ if ((state->dev_ver >= 0x20) || (blind_tune == 1)) {
+
+ if (state->algo != STV090x_WARM_SEARCH) {
+
+ if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+ goto err;
+
+ if (state->config->tuner_set_bandwidth) {
+ if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
+ goto err;
+ }
+
+ if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
+ goto err;
+
+ }
+ }
+ if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000))
+ msleep(50); /* blind search: wait 50ms for SR stabilization */
+ else
+ msleep(5);
+
+ stv090x_get_lock_tmg(state);
+
+ if (!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) {
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
+ goto err;
+
+ i = 0;
+
+ while ((!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) && (i <= 2)) {
+
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
+ goto err;
+ i++;
+ }
+ }
+
+ }
+
+ if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
+ goto err;
+ }
+
+ if ((state->delsys == STV090x_DVBS1) || (state->delsys == STV090x_DSS))
+ stv090x_set_vit_thtracq(state);
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_get_feclock(struct stv090x_state *state, s32 timeout)
+{
+ s32 timer = 0, lock = 0, stat;
+ u32 reg;
+
+ while ((timer < timeout) && (!lock)) {
+ reg = STV090x_READ_DEMOD(state, DMDSTATE);
+ stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
+
+ switch (stat) {
+ case 0: /* searching */
+ case 1: /* first PLH detected */
+ default:
+ lock = 0;
+ break;
+
+ case 2: /* DVB-S2 mode */
+ reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
+ lock = STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD);
+ break;
+
+ case 3: /* DVB-S1/legacy mode */
+ reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
+ lock = STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD);
+ break;
+ }
+ if (!lock) {
+ msleep(10);
+ timer += 10;
+ }
+ }
+ return lock;
+}
+
+static int stv090x_get_lock(struct stv090x_state *state, s32 timeout_dmd, s32 timeout_fec)
+{
+ u32 reg;
+ s32 timer = 0;
+ int lock;
+
+ lock = stv090x_get_dmdlock(state, timeout_dmd);
+ if (lock)
+ lock = stv090x_get_feclock(state, timeout_fec);
+
+ if (lock) {
+ lock = 0;
+
+ while ((timer < timeout_fec) && (!lock)) {
+ reg = STV090x_READ_DEMOD(state, TSSTATUS);
+ lock = STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD);
+ msleep(1);
+ timer++;
+ }
+ }
+
+ return lock;
+}
+
+static int stv090x_set_s2rolloff(struct stv090x_state *state)
+{
+ u32 reg;
+
+ if (state->dev_ver <= 0x20) {
+ /* rolloff to auto mode if DVBS2 */
+ reg = STV090x_READ_DEMOD(state, DEMOD);
+ STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00);
+ if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
+ goto err;
+ } else {
+ /* DVB-S2 rolloff to auto mode if DVBS2 */
+ reg = STV090x_READ_DEMOD(state, DEMOD);
+ STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 0x00);
+ if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
+ goto err;
+ }
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+
+static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
+{
+ struct dvb_frontend *fe = &state->frontend;
+ enum stv090x_signal_state signal_state = STV090x_NOCARRIER;
+ u32 reg;
+ s32 timeout_dmd = 500, timeout_fec = 50, agc1_power, power_iq = 0, i;
+ int lock = 0, low_sr = 0, no_signal = 0;
+
+ reg = STV090x_READ_DEMOD(state, TSCFGH);
+ STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */
+ if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */
+ goto err;
+
+ if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) /* cut 2.0 */
+ goto err;
+ }
+
+ stv090x_get_lock_tmg(state);
+
+ if (state->algo == STV090x_BLIND_SEARCH) {
+ state->tuner_bw = 2 * 36000000; /* wide bw for unknown srate */
+ if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) /* wider srate scan */
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)
+ goto err;
+ if (stv090x_set_srate(state, 1000000) < 0) /* inital srate = 1Msps */
+ goto err;
+ } else {
+ /* known srate */
+ if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)
+ goto err;
+
+ if (state->srate < 2000000) {
+ /* SR < 2MSPS */
+ if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x63) < 0)
+ goto err;
+ } else {
+ /* SR >= 2Msps */
+ if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)
+ goto err;
+ }
+
+ if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+ goto err;
+
+ if (state->dev_ver >= 0x20) {
+ if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0)
+ goto err;
+ if (state->algo == STV090x_COLD_SEARCH)
+ state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10;
+ else if (state->algo == STV090x_WARM_SEARCH)
+ state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000;
+ }
+
+ /* if cold start or warm (Symbolrate is known)
+ * use a Narrow symbol rate scan range
+ */
+ if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) /* narrow srate scan */
+ goto err;
+
+ if (stv090x_set_srate(state, state->srate) < 0)
+ goto err;
+
+ if (stv090x_set_max_srate(state, state->mclk, state->srate) < 0)
+ goto err;
+ if (stv090x_set_min_srate(state, state->mclk, state->srate) < 0)
+ goto err;
+
+ if (state->srate >= 10000000)
+ low_sr = 0;
+ else
+ low_sr = 1;
+ }
+
+ /* Setup tuner */
+ if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+ goto err;
+
+ if (state->config->tuner_set_bbgain) {
+ if (state->config->tuner_set_bbgain(fe, 10) < 0) /* 10dB */
+ goto err;
+ }
+
+ if (state->config->tuner_set_frequency) {
+ if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
+ goto err;
+ }
+
+ if (state->config->tuner_set_bandwidth) {
+ if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
+ goto err;
+ }
+
+ if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
+ goto err;
+
+ msleep(50);
+
+ if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+ goto err;
+
+ if (state->config->tuner_get_status) {
+ if (state->config->tuner_get_status(fe, &reg) < 0)
+ goto err;
+ }
+
+ if (reg)
+ dprintk(FE_DEBUG, 1, "Tuner phase locked");
+ else
+ dprintk(FE_DEBUG, 1, "Tuner unlocked");
+
+ if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
+ goto err;
+
+ msleep(10);
+ agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1),
+ STV090x_READ_DEMOD(state, AGCIQIN0));
+
+ if (agc1_power == 0) {
+ /* If AGC1 integrator value is 0
+ * then read POWERI, POWERQ
+ */
+ for (i = 0; i < 5; i++) {
+ power_iq += (STV090x_READ_DEMOD(state, POWERI) +
+ STV090x_READ_DEMOD(state, POWERQ)) >> 1;
+ }
+ power_iq /= 5;
+ }
+
+ if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) {
+ dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq);
+ lock = 0;
+
+ } else {
+ reg = STV090x_READ_DEMOD(state, DEMOD);
+ STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);
+
+ if (state->dev_ver <= 0x20) {
+ /* rolloff to auto mode if DVBS2 */
+ STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1);
+ } else {
+ /* DVB-S2 rolloff to auto mode if DVBS2 */
+ STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 1);
+ }
+ if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
+ goto err;
+
+ if (stv090x_delivery_search(state) < 0)
+ goto err;
+
+ if (state->algo != STV090x_BLIND_SEARCH) {
+ if (stv090x_start_search(state) < 0)
+ goto err;
+ }
+ }
+
+ /* need to check for AGC1 state */
+
+
+
+ if (state->algo == STV090x_BLIND_SEARCH)
+ lock = stv090x_blind_search(state);
+
+ else if (state->algo == STV090x_COLD_SEARCH)
+ lock = stv090x_get_coldlock(state, timeout_dmd);
+
+ else if (state->algo == STV090x_WARM_SEARCH)
+ lock = stv090x_get_dmdlock(state, timeout_dmd);
+
+ if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) {
+ if (!low_sr) {
+ if (stv090x_chk_tmg(state))
+ lock = stv090x_sw_algo(state);
+ }
+ }
+
+ if (lock)
+ signal_state = stv090x_get_sig_params(state);
+
+ if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */
+ stv090x_optimize_track(state);
+
+ if (state->dev_ver >= 0x20) {
+ /* >= Cut 2.0 :release TS reset after
+ * demod lock and optimized Tracking
+ */
+ reg = STV090x_READ_DEMOD(state, TSCFGH);
+ STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */
+ if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
+ goto err;
+
+ msleep(3);
+
+ STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */
+ if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
+ goto err;
+
+ STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */
+ if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
+ goto err;
+ }
+
+ if (stv090x_get_lock(state, timeout_fec, timeout_fec)) {
+ lock = 1;
+ if (state->delsys == STV090x_DVBS2) {
+ stv090x_set_s2rolloff(state);
+
+ reg = STV090x_READ_DEMOD(state, PDELCTRL2);
+ STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 1);
+ if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)
+ goto err;
+ /* Reset DVBS2 packet delinator error counter */
+ reg = STV090x_READ_DEMOD(state, PDELCTRL2);
+ STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 0);
+ if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67) < 0) /* PER */
+ goto err;
+ } else {
+ if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)
+ goto err;
+ }
+ /* Reset the Total packet counter */
+ if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0x00) < 0)
+ goto err;
+ /* Reset the packet Error counter2 */
+ if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
+ goto err;
+ } else {
+ lock = 0;
+ signal_state = STV090x_NODATA;
+ no_signal = stv090x_chk_signal(state);
+ }
+ }
+ return signal_state;
+
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *props = &fe->dtv_property_cache;
+
+ state->delsys = props->delivery_system;
+ state->frequency = p->frequency;
+ state->srate = p->u.qpsk.symbol_rate;
+ state->search_mode = STV090x_SEARCH_AUTO;
+ state->algo = STV090x_COLD_SEARCH;
+ state->fec = STV090x_PRERR;
+ state->search_range = 2000000;
+
+ if (stv090x_algo(state) == STV090x_RANGEOK) {
+ dprintk(FE_DEBUG, 1, "Search success!");
+ return DVBFE_ALGO_SEARCH_SUCCESS;
+ } else {
+ dprintk(FE_DEBUG, 1, "Search failed!");
+ return DVBFE_ALGO_SEARCH_FAILED;
+ }
+
+ return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+/* FIXME! */
+static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u32 reg;
+ u8 search_state;
+
+ reg = STV090x_READ_DEMOD(state, DMDSTATE);
+ search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
+
+ switch (search_state) {
+ case 0: /* searching */
+ case 1: /* first PLH detected */
+ default:
+ dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)");
+ *status = 0;
+ break;
+
+ case 2: /* DVB-S2 mode */
+ dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");
+ reg = STV090x_READ_DEMOD(state, DSTATUS);
+ if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) {
+ reg = STV090x_READ_DEMOD(state, TSSTATUS);
+ if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
+ *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+ }
+ }
+ break;
+
+ case 3: /* DVB-S1/legacy mode */
+ dprintk(FE_DEBUG, 1, "Delivery system: DVB-S");
+ reg = STV090x_READ_DEMOD(state, DSTATUS);
+ if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) {
+ reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
+ if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) {
+ reg = STV090x_READ_DEMOD(state, TSSTATUS);
+ if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
+ *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+ }
+ }
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int stv090x_read_per(struct dvb_frontend *fe, u32 *per)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+
+ s32 count_4, count_3, count_2, count_1, count_0, count;
+ u32 reg, h, m, l;
+ enum fe_status status;
+
+ stv090x_read_status(fe, &status);
+ if (!(status & FE_HAS_LOCK)) {
+ *per = 1 << 23; /* Max PER */
+ } else {
+ /* Counter 2 */
+ reg = STV090x_READ_DEMOD(state, ERRCNT22);
+ h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD);
+
+ reg = STV090x_READ_DEMOD(state, ERRCNT21);
+ m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD);
+
+ reg = STV090x_READ_DEMOD(state, ERRCNT20);
+ l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD);
+
+ *per = ((h << 16) | (m << 8) | l);
+
+ count_4 = STV090x_READ_DEMOD(state, FBERCPT4);
+ count_3 = STV090x_READ_DEMOD(state, FBERCPT3);
+ count_2 = STV090x_READ_DEMOD(state, FBERCPT2);
+ count_1 = STV090x_READ_DEMOD(state, FBERCPT1);
+ count_0 = STV090x_READ_DEMOD(state, FBERCPT0);
+
+ if ((!count_4) && (!count_3)) {
+ count = (count_2 & 0xff) << 16;
+ count |= (count_1 & 0xff) << 8;
+ count |= count_0 & 0xff;
+ } else {
+ count = 1 << 24;
+ }
+ if (count == 0)
+ *per = 1;
+ }
+ if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
+ goto err;
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val)
+{
+ int res = 0;
+ int min = 0, med;
+
+ if (val < tab[min].read)
+ res = tab[min].real;
+ else if (val >= tab[max].read)
+ res = tab[max].real;
+ else {
+ while ((max - min) > 1) {
+ med = (max + min) / 2;
+ if (val >= tab[min].read && val < tab[med].read)
+ max = med;
+ else
+ min = med;
+ }
+ res = ((val - tab[min].read) *
+ (tab[max].real - tab[min].real) /
+ (tab[max].read - tab[min].read)) +
+ tab[min].real;
+ }
+
+ return res;
+}
+
+static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u32 reg;
+ s32 agc;
+
+ reg = STV090x_READ_DEMOD(state, AGCIQIN1);
+ agc = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
+
+ *strength = stv090x_table_lookup(stv090x_rf_tab, ARRAY_SIZE(stv090x_rf_tab) - 1, agc);
+ if (agc > stv090x_rf_tab[0].read)
+ *strength = 5;
+ else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
+ *strength = -100;
+
+ return 0;
+}
+
+static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u32 reg_0, reg_1, reg, i;
+ s32 val_0, val_1, val = 0;
+ u8 lock_f;
+
+ switch (state->delsys) {
+ case STV090x_DVBS2:
+ reg = STV090x_READ_DEMOD(state, DSTATUS);
+ lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
+ if (lock_f) {
+ msleep(5);
+ for (i = 0; i < 16; i++) {
+ reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1);
+ val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
+ reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0);
+ val_0 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
+ val += MAKEWORD16(val_1, val_0);
+ msleep(1);
+ }
+ val /= 16;
+ *cnr = stv090x_table_lookup(stv090x_s2cn_tab, ARRAY_SIZE(stv090x_s2cn_tab) - 1, val);
+ if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s2cn_tab) - 1].read)
+ *cnr = 1000;
+ }
+ break;
+
+ case STV090x_DVBS1:
+ case STV090x_DSS:
+ reg = STV090x_READ_DEMOD(state, DSTATUS);
+ lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
+ if (lock_f) {
+ msleep(5);
+ for (i = 0; i < 16; i++) {
+ reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1);
+ val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
+ reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0);
+ val_0 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
+ val += MAKEWORD16(val_1, val_0);
+ msleep(1);
+ }
+ val /= 16;
+ *cnr = stv090x_table_lookup(stv090x_s1cn_tab, ARRAY_SIZE(stv090x_s1cn_tab) - 1, val);
+ if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s1cn_tab) - 1].read)
+ *cnr = 1000;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u32 reg;
+
+ reg = STV090x_READ_DEMOD(state, DISTXCTL);
+ switch (tone) {
+ case SEC_TONE_ON:
+ STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);
+ STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+ STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+ break;
+
+ case SEC_TONE_OFF:
+ STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);
+ STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+
+static enum dvbfe_algo stv090x_frontend_algo(struct dvb_frontend *fe)
+{
+ return DVBFE_ALGO_CUSTOM;
+}
+
+static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u32 reg, idle = 0, fifo_full = 1;
+ int i;
+
+ reg = STV090x_READ_DEMOD(state, DISTXCTL);
+
+ STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 2);
+ STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+ STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+
+ STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+
+ for (i = 0; i < cmd->msg_len; i++) {
+
+ while (fifo_full) {
+ reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
+ fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);
+ }
+
+ if (STV090x_WRITE_DEMOD(state, DISTXDATA, cmd->msg[i]) < 0)
+ goto err;
+ }
+ reg = STV090x_READ_DEMOD(state, DISTXCTL);
+ STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+
+ i = 0;
+
+ while ((!idle) && (i < 10)) {
+ reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
+ idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);
+ msleep(10);
+ i++;
+ }
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u32 reg, idle = 0, fifo_full = 1;
+ u8 mode, value;
+ int i;
+
+ reg = STV090x_READ_DEMOD(state, DISTXCTL);
+
+ if (burst == SEC_MINI_A) {
+ mode = 3;
+ value = 0x00;
+ } else {
+ mode = 2;
+ value = 0xFF;
+ }
+
+ STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, mode);
+ STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+ STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+
+ STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+
+ while (fifo_full) {
+ reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
+ fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);
+ }
+
+ if (STV090x_WRITE_DEMOD(state, DISTXDATA, value) < 0)
+ goto err;
+
+ reg = STV090x_READ_DEMOD(state, DISTXCTL);
+ STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);
+ if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+ goto err;
+
+ i = 0;
+
+ while ((!idle) && (i < 10)) {
+ reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
+ idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);
+ msleep(10);
+ i++;
+ }
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u32 reg = 0, i = 0, rx_end = 0;
+
+ while ((rx_end != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ reg = STV090x_READ_DEMOD(state, DISRX_ST0);
+ rx_end = STV090x_GETFIELD_Px(reg, RX_END_FIELD);
+ }
+
+ if (rx_end) {
+ reply->msg_len = STV090x_GETFIELD_Px(reg, FIFO_BYTENBR_FIELD);
+ for (i = 0; i < reply->msg_len; i++)
+ reply->msg[i] = STV090x_READ_DEMOD(state, DISRXDATA);
+ }
+
+ return 0;
+}
+
+static int stv090x_sleep(struct dvb_frontend *fe)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u32 reg;
+
+ dprintk(FE_DEBUG, 1, "Set %s to sleep",
+ state->device == STV0900 ? "STV0900" : "STV0903");
+
+ reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
+ STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
+ if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
+ goto err;
+
+ reg = stv090x_read_reg(state, STV090x_TSTTNR1);
+ STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
+ if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
+ goto err;
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_wakeup(struct dvb_frontend *fe)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u32 reg;
+
+ dprintk(FE_DEBUG, 1, "Wake %s from standby",
+ state->device == STV0900 ? "STV0900" : "STV0903");
+
+ reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
+ STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00);
+ if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
+ goto err;
+
+ reg = stv090x_read_reg(state, STV090x_TSTTNR1);
+ STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1);
+ if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
+ goto err;
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static void stv090x_release(struct dvb_frontend *fe)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+
+ kfree(state);
+}
+
+static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc_mode)
+{
+ u32 reg = 0;
+
+ switch (ldpc_mode) {
+ case STV090x_DUAL:
+ default:
+ if ((state->demod_mode != STV090x_DUAL) || (STV090x_GETFIELD(reg, DDEMOD_FIELD) != 1)) {
+ /* set LDPC to dual mode */
+ if (stv090x_write_reg(state, STV090x_GENCFG, 0x1d) < 0)
+ goto err;
+
+ state->demod_mode = STV090x_DUAL;
+
+ reg = stv090x_read_reg(state, STV090x_TSTRES0);
+ STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);
+ if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
+ goto err;
+ STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);
+ if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)
+ goto err;
+
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)
+ goto err;
+ }
+ break;
+
+ case STV090x_SINGLE:
+ if (stv090x_stop_modcod(state) < 0)
+ goto err;
+ if (stv090x_activate_modcod_single(state) < 0)
+ goto err;
+
+ if (state->demod == STV090x_DEMODULATOR_1) {
+ if (stv090x_write_reg(state, STV090x_GENCFG, 0x06) < 0) /* path 2 */
+ goto err;
+ } else {
+ if (stv090x_write_reg(state, STV090x_GENCFG, 0x04) < 0) /* path 1 */
+ goto err;
+ }
+
+ reg = stv090x_read_reg(state, STV090x_TSTRES0);
+ STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);
+ if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
+ goto err;
+ STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);
+ if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
+ goto err;
+
+ reg = STV090x_READ_DEMOD(state, PDELCTRL1);
+ STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x01);
+ if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
+ goto err;
+ STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x00);
+ if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
+ goto err;
+ break;
+ }
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+/* return (Hz), clk in Hz*/
+static u32 stv090x_get_mclk(struct stv090x_state *state)
+{
+ const struct stv090x_config *config = state->config;
+ u32 div, reg;
+ u8 ratio;
+
+ div = stv090x_read_reg(state, STV090x_NCOARSE);
+ reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
+ ratio = STV090x_GETFIELD(reg, SELX1RATIO_FIELD) ? 4 : 6;
+
+ return (div + 1) * config->xtal / ratio; /* kHz */
+}
+
+static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk)
+{
+ const struct stv090x_config *config = state->config;
+ u32 reg, div, clk_sel;
+
+ reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
+ clk_sel = ((STV090x_GETFIELD(reg, SELX1RATIO_FIELD) == 1) ? 4 : 6);
+
+ div = ((clk_sel * mclk) / config->xtal) - 1;
+
+ reg = stv090x_read_reg(state, STV090x_NCOARSE);
+ STV090x_SETFIELD(reg, M_DIV_FIELD, div);
+ if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0)
+ goto err;
+
+ state->mclk = stv090x_get_mclk(state);
+
+ /*Set the DiseqC frequency to 22KHz */
+ div = state->mclk / 704000;
+ if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0)
+ goto err;
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_set_tspath(struct stv090x_state *state)
+{
+ u32 reg;
+
+ if (state->dev_ver >= 0x20) {
+ switch (state->config->ts1_mode) {
+ case STV090x_TSMODE_PARALLEL_PUNCTURED:
+ case STV090x_TSMODE_DVBCI:
+ switch (state->config->ts2_mode) {
+ case STV090x_TSMODE_SERIAL_PUNCTURED:
+ case STV090x_TSMODE_SERIAL_CONTINUOUS:
+ default:
+ stv090x_write_reg(state, STV090x_TSGENERAL, 0x00);
+ break;
+
+ case STV090x_TSMODE_PARALLEL_PUNCTURED:
+ case STV090x_TSMODE_DVBCI:
+ if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x06) < 0) /* Mux'd stream mode */
+ goto err;
+ reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
+ STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+ if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
+ goto err;
+ reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
+ STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+ if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
+ goto err;
+ if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)
+ goto err;
+ if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)
+ goto err;
+ break;
+ }
+ break;
+
+ case STV090x_TSMODE_SERIAL_PUNCTURED:
+ case STV090x_TSMODE_SERIAL_CONTINUOUS:
+ default:
+ switch (state->config->ts2_mode) {
+ case STV090x_TSMODE_SERIAL_PUNCTURED:
+ case STV090x_TSMODE_SERIAL_CONTINUOUS:
+ default:
+ if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
+ goto err;
+ break;
+
+ case STV090x_TSMODE_PARALLEL_PUNCTURED:
+ case STV090x_TSMODE_DVBCI:
+ if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0a) < 0)
+ goto err;
+ break;
+ }
+ break;
+ }
+ } else {
+ switch (state->config->ts1_mode) {
+ case STV090x_TSMODE_PARALLEL_PUNCTURED:
+ case STV090x_TSMODE_DVBCI:
+ switch (state->config->ts2_mode) {
+ case STV090x_TSMODE_SERIAL_PUNCTURED:
+ case STV090x_TSMODE_SERIAL_CONTINUOUS:
+ default:
+ stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10);
+ break;
+
+ case STV090x_TSMODE_PARALLEL_PUNCTURED:
+ case STV090x_TSMODE_DVBCI:
+ stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16);
+ reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
+ STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+ if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
+ goto err;
+ reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
+ STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 0);
+ if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
+ goto err;
+ if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)
+ goto err;
+ if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)
+ goto err;
+ break;
+ }
+ break;
+
+ case STV090x_TSMODE_SERIAL_PUNCTURED:
+ case STV090x_TSMODE_SERIAL_CONTINUOUS:
+ default:
+ switch (state->config->ts2_mode) {
+ case STV090x_TSMODE_SERIAL_PUNCTURED:
+ case STV090x_TSMODE_SERIAL_CONTINUOUS:
+ default:
+ stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14);
+ break;
+
+ case STV090x_TSMODE_PARALLEL_PUNCTURED:
+ case STV090x_TSMODE_DVBCI:
+ stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12);
+ break;
+ }
+ break;
+ }
+ }
+
+ switch (state->config->ts1_mode) {
+ case STV090x_TSMODE_PARALLEL_PUNCTURED:
+ reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
+ STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
+ if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+ goto err;
+ break;
+
+ case STV090x_TSMODE_DVBCI:
+ reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
+ STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
+ if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+ goto err;
+ break;
+
+ case STV090x_TSMODE_SERIAL_PUNCTURED:
+ reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
+ STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
+ if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+ goto err;
+ break;
+
+ case STV090x_TSMODE_SERIAL_CONTINUOUS:
+ reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
+ STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
+ if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+ goto err;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (state->config->ts2_mode) {
+ case STV090x_TSMODE_PARALLEL_PUNCTURED:
+ reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
+ STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
+ if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+ goto err;
+ break;
+
+ case STV090x_TSMODE_DVBCI:
+ reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
+ STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
+ if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+ goto err;
+ break;
+
+ case STV090x_TSMODE_SERIAL_PUNCTURED:
+ reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
+ STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
+ if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+ goto err;
+ break;
+
+ case STV090x_TSMODE_SERIAL_CONTINUOUS:
+ reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
+ STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
+ if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+ goto err;
+ break;
+
+ default:
+ break;
+ }
+ reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+ STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
+ if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+ goto err;
+ STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
+ if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+ goto err;
+
+ reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+ STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
+ if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+ goto err;
+ STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
+ if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+ goto err;
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_init(struct dvb_frontend *fe)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ const struct stv090x_config *config = state->config;
+ u32 reg;
+
+ if (stv090x_wakeup(fe) < 0) {
+ dprintk(FE_ERROR, 1, "Error waking device");
+ goto err;
+ }
+
+ if (stv090x_ldpc_mode(state, state->demod_mode) < 0)
+ goto err;
+
+ reg = STV090x_READ_DEMOD(state, TNRCFG2);
+ STV090x_SETFIELD_Px(reg, TUN_IQSWAP_FIELD, state->inversion);
+ if (STV090x_WRITE_DEMOD(state, TNRCFG2, reg) < 0)
+ goto err;
+ reg = STV090x_READ_DEMOD(state, DEMOD);
+ STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);
+ if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
+ goto err;
+
+ if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+ goto err;
+
+ if (config->tuner_set_mode) {
+ if (config->tuner_set_mode(fe, TUNER_WAKE) < 0)
+ goto err;
+ }
+
+ if (config->tuner_init) {
+ if (config->tuner_init(fe) < 0)
+ goto err;
+ }
+
+ if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
+ goto err;
+
+ if (stv090x_set_tspath(state) < 0)
+ goto err;
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static int stv090x_setup(struct dvb_frontend *fe)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ const struct stv090x_config *config = state->config;
+ const struct stv090x_reg *stv090x_initval = NULL;
+ const struct stv090x_reg *stv090x_cut20_val = NULL;
+ unsigned long t1_size = 0, t2_size = 0;
+ u32 reg = 0;
+
+ int i;
+
+ if (state->device == STV0900) {
+ dprintk(FE_DEBUG, 1, "Initializing STV0900");
+ stv090x_initval = stv0900_initval;
+ t1_size = ARRAY_SIZE(stv0900_initval);
+ stv090x_cut20_val = stv0900_cut20_val;
+ t2_size = ARRAY_SIZE(stv0900_cut20_val);
+ } else if (state->device == STV0903) {
+ dprintk(FE_DEBUG, 1, "Initializing STV0903");
+ stv090x_initval = stv0903_initval;
+ t1_size = ARRAY_SIZE(stv0903_initval);
+ stv090x_cut20_val = stv0903_cut20_val;
+ t2_size = ARRAY_SIZE(stv0903_cut20_val);
+ }
+
+ /* STV090x init */
+ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Stop Demod */
+ goto err;
+
+ msleep(5);
+
+ if (STV090x_WRITE_DEMOD(state, TNRCFG, 0x6c) < 0) /* check register ! (No Tuner Mode) */
+ goto err;
+
+ STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level);
+ if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) /* repeater OFF */
+ goto err;
+
+ if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */
+ goto err;
+ msleep(5);
+ if (stv090x_write_reg(state, STV090x_I2CCFG, 0x08) < 0) /* 1/41 oversampling */
+ goto err;
+ if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) /* enable PLL */
+ goto err;
+ msleep(5);
+
+ /* write initval */
+ dprintk(FE_DEBUG, 1, "Setting up initial values");
+ for (i = 0; i < t1_size; i++) {
+ if (stv090x_write_reg(state, stv090x_initval[i].addr, stv090x_initval[i].data) < 0)
+ goto err;
+ }
+
+ state->dev_ver = stv090x_read_reg(state, STV090x_MID);
+ if (state->dev_ver >= 0x20) {
+ if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
+ goto err;
+
+ /* write cut20_val*/
+ dprintk(FE_DEBUG, 1, "Setting up Cut 2.0 initial values");
+ for (i = 0; i < t2_size; i++) {
+ if (stv090x_write_reg(state, stv090x_cut20_val[i].addr, stv090x_cut20_val[i].data) < 0)
+ goto err;
+ }
+
+ } else if (state->dev_ver < 0x20) {
+ dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!",
+ state->dev_ver);
+
+ goto err;
+ } else if (state->dev_ver > 0x30) {
+ /* we shouldn't bail out from here */
+ dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!",
+ state->dev_ver);
+ }
+
+ if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0)
+ goto err;
+ if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
+ goto err;
+
+ stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
+ msleep(5);
+ if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0)
+ goto err;
+ stv090x_get_mclk(state);
+
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
+static struct dvb_frontend_ops stv090x_ops = {
+
+ .info = {
+ .name = "STV090x Multistandard",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 0,
+ .frequency_tolerance = 0,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK |
+ FE_CAN_2G_MODULATION
+ },
+
+ .release = stv090x_release,
+ .init = stv090x_init,
+
+ .sleep = stv090x_sleep,
+ .get_frontend_algo = stv090x_frontend_algo,
+
+ .i2c_gate_ctrl = stv090x_i2c_gate_ctrl,
+
+ .diseqc_send_master_cmd = stv090x_send_diseqc_msg,
+ .diseqc_send_burst = stv090x_send_diseqc_burst,
+ .diseqc_recv_slave_reply = stv090x_recv_slave_reply,
+ .set_tone = stv090x_set_tone,
+
+ .search = stv090x_search,
+ .read_status = stv090x_read_status,
+ .read_ber = stv090x_read_per,
+ .read_signal_strength = stv090x_read_signal_strength,
+ .read_snr = stv090x_read_cnr
+};
+
+
+struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
+ struct i2c_adapter *i2c,
+ enum stv090x_demodulator demod)
+{
+ struct stv090x_state *state = NULL;
+
+ state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ state->verbose = &verbose;
+ state->config = config;
+ state->i2c = i2c;
+ state->frontend.ops = stv090x_ops;
+ state->frontend.demodulator_priv = state;
+ state->demod = demod;
+ state->demod_mode = config->demod_mode; /* Single or Dual mode */
+ state->device = config->device;
+ state->rolloff = STV090x_RO_35; /* default */
+
+ if (state->demod == STV090x_DEMODULATOR_0)
+ mutex_init(&demod_lock);
+
+ if (stv090x_sleep(&state->frontend) < 0) {
+ dprintk(FE_ERROR, 1, "Error putting device to sleep");
+ goto error;
+ }
+
+ if (stv090x_setup(&state->frontend) < 0) {
+ dprintk(FE_ERROR, 1, "Error setting up device");
+ goto error;
+ }
+ if (stv090x_wakeup(&state->frontend) < 0) {
+ dprintk(FE_ERROR, 1, "Error waking device");
+ goto error;
+ }
+
+ dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x\n",
+ state->device == STV0900 ? "STV0900" : "STV0903",
+ demod,
+ state->dev_ver);
+
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(stv090x_attach);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h
new file mode 100644
index 000000000000..e968c98bb70f
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x.h
@@ -0,0 +1,106 @@
+/*
+ STV0900/0903 Multistandard Broadcast Frontend driver
+ Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+ Copyright (C) ST Microelectronics
+
+ 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.
+*/
+
+#ifndef __STV090x_H
+#define __STV090x_H
+
+enum stv090x_demodulator {
+ STV090x_DEMODULATOR_0 = 1,
+ STV090x_DEMODULATOR_1
+};
+
+enum stv090x_device {
+ STV0903 = 0,
+ STV0900,
+};
+
+enum stv090x_mode {
+ STV090x_DUAL = 0,
+ STV090x_SINGLE
+};
+
+enum stv090x_tsmode {
+ STV090x_TSMODE_SERIAL_PUNCTURED = 1,
+ STV090x_TSMODE_SERIAL_CONTINUOUS,
+ STV090x_TSMODE_PARALLEL_PUNCTURED,
+ STV090x_TSMODE_DVBCI
+};
+
+enum stv090x_clkmode {
+ STV090x_CLK_INT = 0, /* Clk i/p = CLKI */
+ STV090x_CLK_EXT = 2 /* Clk i/p = XTALI */
+};
+
+enum stv090x_i2crpt {
+ STV090x_RPTLEVEL_256 = 0,
+ STV090x_RPTLEVEL_128 = 1,
+ STV090x_RPTLEVEL_64 = 2,
+ STV090x_RPTLEVEL_32 = 3,
+ STV090x_RPTLEVEL_16 = 4,
+ STV090x_RPTLEVEL_8 = 5,
+ STV090x_RPTLEVEL_4 = 6,
+ STV090x_RPTLEVEL_2 = 7,
+};
+
+struct stv090x_config {
+ enum stv090x_device device;
+ enum stv090x_mode demod_mode;
+ enum stv090x_clkmode clk_mode;
+
+ u32 xtal; /* default: 8000000 */
+ u8 address; /* default: 0x68 */
+
+ u32 ref_clk; /* default: 16000000 FIXME to tuner config */
+
+ u8 ts1_mode;
+ u8 ts2_mode;
+
+ enum stv090x_i2crpt repeater_level;
+
+ int (*tuner_init) (struct dvb_frontend *fe);
+ int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
+ int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
+ int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
+ int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
+ int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
+ int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
+ int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
+ int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
+ int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
+};
+
+#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
+ struct i2c_adapter *i2c,
+ enum stv090x_demodulator demod);
+#else
+
+static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
+ struct i2c_adapter *i2c,
+ enum stv090x_demodulator demod)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_STV090x */
+
+#endif /* __STV090x_H */
diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h
new file mode 100644
index 000000000000..5a4a01740d88
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x_priv.h
@@ -0,0 +1,269 @@
+/*
+ STV0900/0903 Multistandard Broadcast Frontend driver
+ Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+ Copyright (C) ST Microelectronics
+
+ 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.
+*/
+
+#ifndef __STV090x_PRIV_H
+#define __STV090x_PRIV_H
+
+#include "dvb_frontend.h"
+
+#define FE_ERROR 0
+#define FE_NOTICE 1
+#define FE_INFO 2
+#define FE_DEBUG 3
+#define FE_DEBUGREG 4
+
+#define dprintk(__y, __z, format, arg...) do { \
+ if (__z) { \
+ if ((verbose > FE_ERROR) && (verbose > __y)) \
+ printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
+ else if ((verbose > FE_NOTICE) && (verbose > __y)) \
+ printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
+ else if ((verbose > FE_INFO) && (verbose > __y)) \
+ printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
+ else if ((verbose > FE_DEBUG) && (verbose > __y)) \
+ printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
+ } else { \
+ if (verbose > __y) \
+ printk(format, ##arg); \
+ } \
+} while (0)
+
+#define STV090x_READ_DEMOD(__state, __reg) (( \
+ (__state)->demod == STV090x_DEMODULATOR_1) ? \
+ stv090x_read_reg(__state, STV090x_P2_##__reg) : \
+ stv090x_read_reg(__state, STV090x_P1_##__reg))
+
+#define STV090x_WRITE_DEMOD(__state, __reg, __data) (( \
+ (__state)->demod == STV090x_DEMODULATOR_1) ? \
+ stv090x_write_reg(__state, STV090x_P2_##__reg, __data) :\
+ stv090x_write_reg(__state, STV090x_P1_##__reg, __data))
+
+#define STV090x_ADDR_OFFST(__state, __x) (( \
+ (__state->demod) == STV090x_DEMODULATOR_1) ? \
+ STV090x_P1_##__x : \
+ STV090x_P2_##__x)
+
+
+#define STV090x_SETFIELD(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_##bitf) - 1) <<\
+ STV090x_OFFST_##bitf))) | \
+ (val << STV090x_OFFST_##bitf))
+
+#define STV090x_GETFIELD(val, bitf) ((val >> STV090x_OFFST_##bitf) & ((1 << STV090x_WIDTH_##bitf) - 1))
+
+
+#define STV090x_SETFIELD_Px(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_Px_##bitf) - 1) <<\
+ STV090x_OFFST_Px_##bitf))) | \
+ (val << STV090x_OFFST_Px_##bitf))
+
+#define STV090x_GETFIELD_Px(val, bitf) ((val >> STV090x_OFFST_Px_##bitf) & ((1 << STV090x_WIDTH_Px_##bitf) - 1))
+
+#define MAKEWORD16(__a, __b) (((__a) << 8) | (__b))
+
+#define MSB(__x) ((__x >> 8) & 0xff)
+#define LSB(__x) (__x & 0xff)
+
+
+#define STV090x_IQPOWER_THRESHOLD 30
+#define STV090x_SEARCH_AGC2_TH_CUT20 700
+#define STV090x_SEARCH_AGC2_TH_CUT30 1200
+
+#define STV090x_SEARCH_AGC2_TH(__ver) \
+ ((__ver <= 0x20) ? \
+ STV090x_SEARCH_AGC2_TH_CUT20 : \
+ STV090x_SEARCH_AGC2_TH_CUT30)
+
+enum stv090x_signal_state {
+ STV090x_NOCARRIER,
+ STV090x_NODATA,
+ STV090x_DATAOK,
+ STV090x_RANGEOK,
+ STV090x_OUTOFRANGE
+};
+
+enum stv090x_fec {
+ STV090x_PR12 = 0,
+ STV090x_PR23,
+ STV090x_PR34,
+ STV090x_PR45,
+ STV090x_PR56,
+ STV090x_PR67,
+ STV090x_PR78,
+ STV090x_PR89,
+ STV090x_PR910,
+ STV090x_PRERR
+};
+
+enum stv090x_modulation {
+ STV090x_QPSK,
+ STV090x_8PSK,
+ STV090x_16APSK,
+ STV090x_32APSK,
+ STV090x_UNKNOWN
+};
+
+enum stv090x_frame {
+ STV090x_LONG_FRAME,
+ STV090x_SHORT_FRAME
+};
+
+enum stv090x_pilot {
+ STV090x_PILOTS_OFF,
+ STV090x_PILOTS_ON
+};
+
+enum stv090x_rolloff {
+ STV090x_RO_35,
+ STV090x_RO_25,
+ STV090x_RO_20
+};
+
+enum stv090x_inversion {
+ STV090x_IQ_AUTO,
+ STV090x_IQ_NORMAL,
+ STV090x_IQ_SWAP
+};
+
+enum stv090x_modcod {
+ STV090x_DUMMY_PLF = 0,
+ STV090x_QPSK_14,
+ STV090x_QPSK_13,
+ STV090x_QPSK_25,
+ STV090x_QPSK_12,
+ STV090x_QPSK_35,
+ STV090x_QPSK_23,
+ STV090x_QPSK_34,
+ STV090x_QPSK_45,
+ STV090x_QPSK_56,
+ STV090x_QPSK_89,
+ STV090x_QPSK_910,
+ STV090x_8PSK_35,
+ STV090x_8PSK_23,
+ STV090x_8PSK_34,
+ STV090x_8PSK_56,
+ STV090x_8PSK_89,
+ STV090x_8PSK_910,
+ STV090x_16APSK_23,
+ STV090x_16APSK_34,
+ STV090x_16APSK_45,
+ STV090x_16APSK_56,
+ STV090x_16APSK_89,
+ STV090x_16APSK_910,
+ STV090x_32APSK_34,
+ STV090x_32APSK_45,
+ STV090x_32APSK_56,
+ STV090x_32APSK_89,
+ STV090x_32APSK_910,
+ STV090x_MODCODE_UNKNOWN
+};
+
+enum stv090x_search {
+ STV090x_SEARCH_DSS = 0,
+ STV090x_SEARCH_DVBS1,
+ STV090x_SEARCH_DVBS2,
+ STV090x_SEARCH_AUTO
+};
+
+enum stv090x_algo {
+ STV090x_BLIND_SEARCH,
+ STV090x_COLD_SEARCH,
+ STV090x_WARM_SEARCH
+};
+
+enum stv090x_delsys {
+ STV090x_ERROR = 0,
+ STV090x_DVBS1 = 1,
+ STV090x_DVBS2,
+ STV090x_DSS
+};
+
+struct stv090x_long_frame_crloop {
+ enum stv090x_modcod modcod;
+
+ u8 crl_pilots_on_2;
+ u8 crl_pilots_off_2;
+ u8 crl_pilots_on_5;
+ u8 crl_pilots_off_5;
+ u8 crl_pilots_on_10;
+ u8 crl_pilots_off_10;
+ u8 crl_pilots_on_20;
+ u8 crl_pilots_off_20;
+ u8 crl_pilots_on_30;
+ u8 crl_pilots_off_30;
+};
+
+struct stv090x_short_frame_crloop {
+ enum stv090x_modulation modulation;
+
+ u8 crl_2; /* SR < 3M */
+ u8 crl_5; /* 3 < SR <= 7M */
+ u8 crl_10; /* 7 < SR <= 15M */
+ u8 crl_20; /* 10 < SR <= 25M */
+ u8 crl_30; /* 10 < SR <= 45M */
+};
+
+struct stv090x_reg {
+ u16 addr;
+ u8 data;
+};
+
+struct stv090x_tab {
+ s32 real;
+ s32 read;
+};
+
+struct stv090x_state {
+ enum stv090x_device device;
+ enum stv090x_demodulator demod;
+ enum stv090x_mode demod_mode;
+ u32 dev_ver;
+
+ struct i2c_adapter *i2c;
+ const struct stv090x_config *config;
+ struct dvb_frontend frontend;
+
+ u32 *verbose; /* Cached module verbosity */
+
+ enum stv090x_delsys delsys;
+ enum stv090x_fec fec;
+ enum stv090x_modulation modulation;
+ enum stv090x_modcod modcod;
+ enum stv090x_search search_mode;
+ enum stv090x_frame frame_len;
+ enum stv090x_pilot pilots;
+ enum stv090x_rolloff rolloff;
+ enum stv090x_inversion inversion;
+ enum stv090x_algo algo;
+
+ u32 frequency;
+ u32 srate;
+
+ s32 mclk; /* Masterclock Divider factor */
+ s32 tuner_bw;
+
+ u32 tuner_refclk;
+
+ s32 search_range;
+
+ s32 DemodTimeout;
+ s32 FecTimeout;
+};
+
+#endif /* __STV090x_PRIV_H */
diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h
new file mode 100644
index 000000000000..57b6abbbd32d
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x_reg.h
@@ -0,0 +1,2373 @@
+/*
+ STV0900/0903 Multistandard Broadcast Frontend driver
+ Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+ Copyright (C) ST Microelectronics
+
+ 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.
+*/
+
+#ifndef __STV090x_REG_H
+#define __STV090x_REG_H
+
+#define STV090x_MID 0xf100
+#define STV090x_OFFST_MCHIP_IDENT_FIELD 4
+#define STV090x_WIDTH_MCHIP_IDENT_FIELD 4
+#define STV090x_OFFST_MRELEASE_FIELD 0
+#define STV090x_WIDTH_MRELEASE_FIELD 4
+
+#define STV090x_DACR1 0xf113
+#define STV090x_OFFST_DACR1_MODE_FIELD 5
+#define STV090x_WIDTH_DACR1_MODE_FIELD 3
+#define STV090x_OFFST_DACR1_VALUE_FIELD 0
+#define STV090x_WIDTH_DACR1_VALUE_FIELD 4
+
+#define STV090x_DACR2 0xf114
+#define STV090x_OFFST_DACR2_VALUE_FIELD 0
+#define STV090x_WIDTH_DACR2_VALUE_FIELD 8
+
+#define STV090x_OUTCFG 0xf11c
+#define STV090x_OFFST_OUTSERRS1_HZ_FIELD 6
+#define STV090x_WIDTH_OUTSERRS1_HZ_FIELD 1
+#define STV090x_OFFST_OUTSERRS2_HZ_FIELD 5
+#define STV090x_WIDTH_OUTSERRS2_HZ_FIELD 1
+#define STV090x_OFFST_OUTSERRS3_HZ_FIELD 4
+#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1
+#define STV090x_OFFST_OUTPARRS3_HZ_FIELD 3
+#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1
+
+#define STV090x_MODECFG 0xf11d
+
+#define STV090x_IRQSTATUS3 0xf120
+#define STV090x_OFFST_SPLL_LOCK_FIELD 5
+#define STV090x_WIDTH_SPLL_LOCK_FIELD 1
+#define STV090x_OFFST_SSTREAM_LCK_3_FIELD 4
+#define STV090x_WIDTH_SSTREAM_LCK_3_FIELD 1
+#define STV090x_OFFST_SSTREAM_LCK_2_FIELD 3
+#define STV090x_WIDTH_SSTREAM_LCK_2_FIELD 1
+#define STV090x_OFFST_SSTREAM_LCK_1_FIELD 2
+#define STV090x_WIDTH_SSTREAM_LCK_1_FIELD 1
+#define STV090x_OFFST_SDVBS1_PRF_2_FIELD 1
+#define STV090x_WIDTH_SDVBS1_PRF_2_FIELD 1
+#define STV090x_OFFST_SDVBS1_PRF_1_FIELD 0
+#define STV090x_WIDTH_SDVBS1_PRF_1_FIELD 1
+
+#define STV090x_IRQSTATUS2 0xf121
+#define STV090x_OFFST_SSPY_ENDSIM_3_FIELD 7
+#define STV090x_WIDTH_SSPY_ENDSIM_3_FIELD 1
+#define STV090x_OFFST_SSPY_ENDSIM_2_FIELD 6
+#define STV090x_WIDTH_SSPY_ENDSIM_2_FIELD 1
+#define STV090x_OFFST_SSPY_ENDSIM_1_FIELD 5
+#define STV090x_WIDTH_SSPY_ENDSIM_1_FIELD 1
+#define STV090x_OFFST_SPKTDEL_ERROR_2_FIELD 4
+#define STV090x_WIDTH_SPKTDEL_ERROR_2_FIELD 1
+#define STV090x_OFFST_SPKTDEL_LOCKB_2_FIELD 3
+#define STV090x_WIDTH_SPKTDEL_LOCKB_2_FIELD 1
+#define STV090x_OFFST_SPKTDEL_LOCK_2_FIELD 2
+#define STV090x_WIDTH_SPKTDEL_LOCK_2_FIELD 1
+#define STV090x_OFFST_SPKTDEL_ERROR_1_FIELD 1
+#define STV090x_WIDTH_SPKTDEL_ERROR_1_FIELD 1
+#define STV090x_OFFST_SPKTDEL_LOCKB_1_FIELD 0
+#define STV090x_WIDTH_SPKTDEL_LOCKB_1_FIELD 1
+
+#define STV090x_IRQSTATUS1 0xf122
+#define STV090x_OFFST_SPKTDEL_LOCK_1_FIELD 7
+#define STV090x_WIDTH_SPKTDEL_LOCK_1_FIELD 1
+#define STV090x_OFFST_SDEMOD_LOCKB_2_FIELD 2
+#define STV090x_WIDTH_SDEMOD_LOCKB_2_FIELD 1
+#define STV090x_OFFST_SDEMOD_LOCK_2_FIELD 1
+#define STV090x_WIDTH_SDEMOD_LOCK_2_FIELD 1
+#define STV090x_OFFST_SDEMOD_IRQ_2_FIELD 0
+#define STV090x_WIDTH_SDEMOD_IRQ_2_FIELD 1
+
+#define STV090x_IRQSTATUS0 0xf123
+#define STV090x_OFFST_SDEMOD_LOCKB_1_FIELD 7
+#define STV090x_WIDTH_SDEMOD_LOCKB_1_FIELD 1
+#define STV090x_OFFST_SDEMOD_LOCK_1_FIELD 6
+#define STV090x_WIDTH_SDEMOD_LOCK_1_FIELD 1
+#define STV090x_OFFST_SDEMOD_IRQ_1_FIELD 5
+#define STV090x_WIDTH_SDEMOD_IRQ_1_FIELD 1
+#define STV090x_OFFST_SBCH_ERRFLAG_FIELD 4
+#define STV090x_WIDTH_SBCH_ERRFLAG_FIELD 1
+#define STV090x_OFFST_SDISEQC2RX_IRQ_FIELD 3
+#define STV090x_WIDTH_SDISEQC2RX_IRQ_FIELD 1
+#define STV090x_OFFST_SDISEQC2TX_IRQ_FIELD 2
+#define STV090x_WIDTH_SDISEQC2TX_IRQ_FIELD 1
+#define STV090x_OFFST_SDISEQC1RX_IRQ_FIELD 1
+#define STV090x_WIDTH_SDISEQC1RX_IRQ_FIELD 1
+#define STV090x_OFFST_SDISEQC1TX_IRQ_FIELD 0
+#define STV090x_WIDTH_SDISEQC1TX_IRQ_FIELD 1
+
+#define STV090x_IRQMASK3 0xf124
+#define STV090x_OFFST_MPLL_LOCK_FIELD 5
+#define STV090x_WIDTH_MPLL_LOCK_FIELD 1
+#define STV090x_OFFST_MSTREAM_LCK_3_FIELD 2
+#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD 3
+#define STV090x_OFFST_MSTREAM_LCK_2_FIELD 2
+#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD 3
+#define STV090x_OFFST_MSTREAM_LCK_1_FIELD 2
+#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD 3
+#define STV090x_OFFST_MDVBS1_PRF_2_FIELD 1
+#define STV090x_WIDTH_MDVBS1_PRF_2_FIELD 1
+#define STV090x_OFFST_MDVBS1_PRF_1_FIELD 0
+#define STV090x_WIDTH_MDVBS1_PRF_1_FIELD 1
+
+#define STV090x_IRQMASK2 0xf125
+#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD 5
+#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD 3
+#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD 5
+#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD 3
+#define STV090x_OFFST_MSPY_ENDSIM_1_FIELD 5
+#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD 3
+#define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD 4
+#define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD 1
+#define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD 3
+#define STV090x_WIDTH_MPKTDEL_LOCKB_2_FIELD 1
+#define STV090x_OFFST_MPKTDEL_LOCK_2_FIELD 2
+#define STV090x_WIDTH_MPKTDEL_LOCK_2_FIELD 1
+#define STV090x_OFFST_MPKTDEL_ERROR_1_FIELD 1
+#define STV090x_WIDTH_MPKTDEL_ERROR_1_FIELD 1
+#define STV090x_OFFST_MPKTDEL_LOCKB_1_FIELD 0
+#define STV090x_WIDTH_MPKTDEL_LOCKB_1_FIELD 1
+
+#define STV090x_IRQMASK1 0xf126
+#define STV090x_OFFST_MPKTDEL_LOCK_1_FIELD 7
+#define STV090x_WIDTH_MPKTDEL_LOCK_1_FIELD 1
+#define STV090x_OFFST_MEXTPINB2_FIELD 6
+#define STV090x_WIDTH_MEXTPINB2_FIELD 1
+#define STV090x_OFFST_MEXTPIN2_FIELD 5
+#define STV090x_WIDTH_MEXTPIN2_FIELD 1
+#define STV090x_OFFST_MEXTPINB1_FIELD 4
+#define STV090x_WIDTH_MEXTPINB1_FIELD 1
+#define STV090x_OFFST_MEXTPIN1_FIELD 3
+#define STV090x_WIDTH_MEXTPIN1_FIELD 1
+#define STV090x_OFFST_MDEMOD_LOCKB_2_FIELD 2
+#define STV090x_WIDTH_MDEMOD_LOCKB_2_FIELD 1
+#define STV090x_OFFST_MDEMOD_LOCK_2_FIELD 1
+#define STV090x_WIDTH_MDEMOD_LOCK_2_FIELD 1
+#define STV090x_OFFST_MDEMOD_IRQ_2_FIELD 0
+#define STV090x_WIDTH_MDEMOD_IRQ_2_FIELD 1
+
+#define STV090x_IRQMASK0 0xf127
+#define STV090x_OFFST_MDEMOD_LOCKB_1_FIELD 7
+#define STV090x_WIDTH_MDEMOD_LOCKB_1_FIELD 1
+#define STV090x_OFFST_MDEMOD_LOCK_1_FIELD 6
+#define STV090x_WIDTH_MDEMOD_LOCK_1_FIELD 1
+#define STV090x_OFFST_MDEMOD_IRQ_1_FIELD 5
+#define STV090x_WIDTH_MDEMOD_IRQ_1_FIELD 1
+#define STV090x_OFFST_MBCH_ERRFLAG_FIELD 4
+#define STV090x_WIDTH_MBCH_ERRFLAG_FIELD 1
+#define STV090x_OFFST_MDISEQC2RX_IRQ_FIELD 3
+#define STV090x_WIDTH_MDISEQC2RX_IRQ_FIELD 1
+#define STV090x_OFFST_MDISEQC2TX_IRQ_FIELD 2
+#define STV090x_WIDTH_MDISEQC2TX_IRQ_FIELD 1
+#define STV090x_OFFST_MDISEQC1RX_IRQ_FIELD 1
+#define STV090x_WIDTH_MDISEQC1RX_IRQ_FIELD 1
+#define STV090x_OFFST_MDISEQC1TX_IRQ_FIELD 0
+#define STV090x_WIDTH_MDISEQC1TX_IRQ_FIELD 1
+
+#define STV090x_I2CCFG 0xf129
+#define STV090x_OFFST_12C_FASTMODE_FIELD 3
+#define STV090x_WIDTH_12C_FASTMODE_FIELD 1
+#define STV090x_OFFST_12CADDR_INC_FIELD 0
+#define STV090x_WIDTH_12CADDR_INC_FIELD 2
+
+#define STV090x_Px_I2CRPT(__x) (0xf12a + (__x - 1) * 0x1)
+#define STV090x_P1_I2CRPT STV090x_Px_I2CRPT(1)
+#define STV090x_P2_I2CRPT STV090x_Px_I2CRPT(2)
+#define STV090x_OFFST_Px_I2CT_ON_FIELD 7
+#define STV090x_WIDTH_Px_I2CT_ON_FIELD 1
+#define STV090x_OFFST_Px_ENARPT_LEVEL_FIELD 4
+#define STV090x_WIDTH_Px_ENARPT_LEVEL_FIELD 3
+#define STV090x_OFFST_Px_SCLT_DELAY_FIELD 3
+#define STV090x_WIDTH_Px_SCLT_DELAY_FIELD 1
+#define STV090x_OFFST_Px_STOP_ENABLE_FIELD 2
+#define STV090x_WIDTH_Px_STOP_ENABLE_FIELD 1
+#define STV090x_OFFST_Px_STOP_SDAT2SDA_FIELD 1
+#define STV090x_WIDTH_Px_STOP_SDAT2SDA_FIELD 1
+
+#define STV090x_CLKI2CFG 0xf140
+#define STV090x_OFFST_CLKI2_OPD_FIELD 7
+#define STV090x_WIDTH_CLKI2_OPD_FIELD 1
+#define STV090x_OFFST_CLKI2_CONFIG_FIELD 1
+#define STV090x_WIDTH_CLKI2_CONFIG_FIELD 6
+#define STV090x_OFFST_CLKI2_XOR_FIELD 0
+#define STV090x_WIDTH_CLKI2_XOR_FIELD 1
+
+#define STV090x_GPIOxCFG(__x) (0xf141 + (__x - 1))
+#define STV090x_GPIO1CFG STV090x_GPIOxCFG(1)
+#define STV090x_GPIO2CFG STV090x_GPIOxCFG(2)
+#define STV090x_GPIO3CFG STV090x_GPIOxCFG(3)
+#define STV090x_GPIO4CFG STV090x_GPIOxCFG(4)
+#define STV090x_GPIO5CFG STV090x_GPIOxCFG(5)
+#define STV090x_GPIO6CFG STV090x_GPIOxCFG(6)
+#define STV090x_GPIO7CFG STV090x_GPIOxCFG(7)
+#define STV090x_GPIO8CFG STV090x_GPIOxCFG(8)
+#define STV090x_GPIO9CFG STV090x_GPIOxCFG(9)
+#define STV090x_GPIO10CFG STV090x_GPIOxCFG(10)
+#define STV090x_GPIO11CFG STV090x_GPIOxCFG(11)
+#define STV090x_GPIO12CFG STV090x_GPIOxCFG(12)
+#define STV090x_GPIO13CFG STV090x_GPIOxCFG(13)
+#define STV090x_OFFST_GPIOx_OPD_FIELD 7
+#define STV090x_WIDTH_GPIOx_OPD_FIELD 1
+#define STV090x_OFFST_GPIOx_CONFIG_FIELD 1
+#define STV090x_WIDTH_GPIOx_CONFIG_FIELD 6
+#define STV090x_OFFST_GPIOx_XOR_FIELD 0
+#define STV090x_WIDTH_GPIOx_XOR_FIELD 1
+
+#define STV090x_CSxCFG(__x) (0xf14e + __x * 0x1)
+#define STV090x_CS0CFG STV090x_CSxCFG(0)
+#define STV090x_CS1CFG STV090x_CSxCFG(1)
+#define STV090x_OFFST_CSX_OPD_FIELD 7
+#define STV090x_WIDTH_CSX_OPD_FIELD 1
+#define STV090x_OFFST_CSX_CONFIG_FIELD 1
+#define STV090x_WIDTH_CSX_CONFIG_FIELD 6
+#define STV090x_OFFST_CSX_XOR_FIELD 0
+#define STV090x_WIDTH_CSX_XOR_FIELD 1
+
+
+#define STV090x_STDBYCFG 0xf150
+#define STV090x_OFFST_STDBY_OPD_FIELD 7
+#define STV090x_WIDTH_STDBY_OPD_FIELD 1
+#define STV090x_OFFST_STDBY_CONFIG_FIELD 1
+#define STV090x_WIDTH_STDBY_CONFIG_FIELD 6
+#define STV090x_OFFST_STDBY_XOR_FIELD 0
+#define STV090x_WIDTH_STDBY_XOR_FIELD 1
+
+#define STV090x_DIRCLKCFG 0xf151
+#define STV090x_OFFST_DIRCLK_OPD_FIELD 7
+#define STV090x_WIDTH_DIRCLK_OPD_FIELD 1
+#define STV090x_OFFST_DIRCLK_CONFIG_FIELD 1
+#define STV090x_WIDTH_DIRCLK_CONFIG_FIELD 6
+#define STV090x_OFFST_DIRCLK_XOR_FIELD 0
+#define STV090x_WIDTH_DIRCLK_XOR_FIELD 1
+
+
+#define STV090x_AGCRFxCFG(__x) (0xf152 + (__x - 1) * 0x4)
+#define STV090x_AGCRF1CFG STV090x_AGCRFxCFG(1)
+#define STV090x_AGCRF2CFG STV090x_AGCRFxCFG(2)
+#define STV090x_OFFST_AGCRFx_OPD_FIELD 7
+#define STV090x_WIDTH_AGCRFx_OPD_FIELD 1
+#define STV090x_OFFST_AGCRFx_CONFIG_FIELD 1
+#define STV090x_WIDTH_AGCRFx_CONFIG_FIELD 6
+#define STV090x_OFFST_AGCRFx_XOR_FIELD 0
+#define STV090x_WIDTH_AGCRFx_XOR_FIELD 1
+
+#define STV090x_SDATxCFG(__x) (0xf153 + (__x - 1) * 0x4)
+#define STV090x_SDAT1CFG STV090x_SDATxCFG(1)
+#define STV090x_SDAT2CFG STV090x_SDATxCFG(2)
+#define STV090x_OFFST_SDATx_OPD_FIELD 7
+#define STV090x_WIDTH_SDATx_OPD_FIELD 1
+#define STV090x_OFFST_SDATx_CONFIG_FIELD 1
+#define STV090x_WIDTH_SDATx_CONFIG_FIELD 6
+#define STV090x_OFFST_SDATx_XOR_FIELD 0
+#define STV090x_WIDTH_SDATx_XOR_FIELD 1
+
+#define STV090x_SCLTxCFG(__x) (0xf154 + (__x - 1) * 0x4)
+#define STV090x_SCLT1CFG STV090x_SCLTxCFG(1)
+#define STV090x_SCLT2CFG STV090x_SCLTxCFG(2)
+#define STV090x_OFFST_SCLTx_OPD_FIELD 7
+#define STV090x_WIDTH_SCLTx_OPD_FIELD 1
+#define STV090x_OFFST_SCLTx_CONFIG_FIELD 1
+#define STV090x_WIDTH_SCLTx_CONFIG_FIELD 6
+#define STV090x_OFFST_SCLTx_XOR_FIELD 0
+#define STV090x_WIDTH_SCLTx_XOR_FIELD 1
+
+#define STV090x_DISEQCOxCFG(__x) (0xf155 + (__x - 1) * 0x4)
+#define STV090x_DISEQCO1CFG STV090x_DISEQCOxCFG(1)
+#define STV090x_DISEQCO2CFG STV090x_DISEQCOxCFG(2)
+#define STV090x_OFFST_DISEQCOx_OPD_FIELD 7
+#define STV090x_WIDTH_DISEQCOx_OPD_FIELD 1
+#define STV090x_OFFST_DISEQCOx_CONFIG_FIELD 1
+#define STV090x_WIDTH_DISEQCOx_CONFIG_FIELD 6
+#define STV090x_OFFST_DISEQCOx_XOR_FIELD 0
+#define STV090x_WIDTH_DISEQCOx_XOR_FIELD 1
+
+#define STV090x_CLKOUT27CFG 0xf15a
+#define STV090x_OFFST_CLKOUT27_OPD_FIELD 7
+#define STV090x_WIDTH_CLKOUT27_OPD_FIELD 1
+#define STV090x_OFFST_CLKOUT27_CONFIG_FIELD 1
+#define STV090x_WIDTH_CLKOUT27_CONFIG_FIELD 6
+#define STV090x_OFFST_CLKOUT27_XOR_FIELD 0
+#define STV090x_WIDTH_CLKOUT27_XOR_FIELD 1
+
+#define STV090x_ERRORxCFG(__x) (0xf15b + (__x - 1) * 0x5)
+#define STV090x_ERROR1CFG STV090x_ERRORxCFG(1)
+#define STV090x_ERROR2CFG STV090x_ERRORxCFG(2)
+#define STV090x_ERROR3CFG STV090x_ERRORxCFG(3)
+#define STV090x_OFFST_ERRORx_OPD_FIELD 7
+#define STV090x_WIDTH_ERRORx_OPD_FIELD 1
+#define STV090x_OFFST_ERRORx_CONFIG_FIELD 1
+#define STV090x_WIDTH_ERRORx_CONFIG_FIELD 6
+#define STV090x_OFFST_ERRORx_XOR_FIELD 0
+#define STV090x_WIDTH_ERRORx_XOR_FIELD 1
+
+#define STV090x_DPNxCFG(__x) (0xf15c + (__x - 1) * 0x5)
+#define STV090x_DPN1CFG STV090x_DPNxCFG(1)
+#define STV090x_DPN2CFG STV090x_DPNxCFG(2)
+#define STV090x_DPN3CFG STV090x_DPNxCFG(3)
+#define STV090x_OFFST_DPNx_OPD_FIELD 7
+#define STV090x_WIDTH_DPNx_OPD_FIELD 1
+#define STV090x_OFFST_DPNx_CONFIG_FIELD 1
+#define STV090x_WIDTH_DPNx_CONFIG_FIELD 6
+#define STV090x_OFFST_DPNx_XOR_FIELD 0
+#define STV090x_WIDTH_DPNx_XOR_FIELD 1
+
+#define STV090x_STROUTxCFG(__x) (0xf15d + (__x - 1) * 0x5)
+#define STV090x_STROUT1CFG STV090x_STROUTxCFG(1)
+#define STV090x_STROUT2CFG STV090x_STROUTxCFG(2)
+#define STV090x_STROUT3CFG STV090x_STROUTxCFG(3)
+#define STV090x_OFFST_STROUTx_OPD_FIELD 7
+#define STV090x_WIDTH_STROUTx_OPD_FIELD 1
+#define STV090x_OFFST_STROUTx_CONFIG_FIELD 1
+#define STV090x_WIDTH_STROUTx_CONFIG_FIELD 6
+#define STV090x_OFFST_STROUTx_XOR_FIELD 0
+#define STV090x_WIDTH_STROUTx_XOR_FIELD 1
+
+#define STV090x_CLKOUTxCFG(__x) (0xf15e + (__x - 1) * 0x5)
+#define STV090x_CLKOUT1CFG STV090x_CLKOUTxCFG(1)
+#define STV090x_CLKOUT2CFG STV090x_CLKOUTxCFG(2)
+#define STV090x_CLKOUT3CFG STV090x_CLKOUTxCFG(3)
+#define STV090x_OFFST_CLKOUTx_OPD_FIELD 7
+#define STV090x_WIDTH_CLKOUTx_OPD_FIELD 1
+#define STV090x_OFFST_CLKOUTx_CONFIG_FIELD 1
+#define STV090x_WIDTH_CLKOUTx_CONFIG_FIELD 6
+#define STV090x_OFFST_CLKOUTx_XOR_FIELD 0
+#define STV090x_WIDTH_CLKOUTx_XOR_FIELD 1
+
+#define STV090x_DATAxCFG(__x) (0xf15f + (__x - 71) * 0x5)
+#define STV090x_DATA71CFG STV090x_DATAxCFG(71)
+#define STV090x_DATA72CFG STV090x_DATAxCFG(72)
+#define STV090x_DATA73CFG STV090x_DATAxCFG(73)
+#define STV090x_OFFST_DATAx_OPD_FIELD 7
+#define STV090x_WIDTH_DATAx_OPD_FIELD 1
+#define STV090x_OFFST_DATAx_CONFIG_FIELD 1
+#define STV090x_WIDTH_DATAx_CONFIG_FIELD 6
+#define STV090x_OFFST_DATAx_XOR_FIELD 0
+#define STV090x_WIDTH_DATAx_XOR_FIELD 1
+
+#define STV090x_NCOARSE 0xf1b3
+#define STV090x_OFFST_M_DIV_FIELD 0
+#define STV090x_WIDTH_M_DIV_FIELD 8
+
+#define STV090x_SYNTCTRL 0xf1b6
+#define STV090x_OFFST_STANDBY_FIELD 7
+#define STV090x_WIDTH_STANDBY_FIELD 1
+#define STV090x_OFFST_BYPASSPLLCORE_FIELD 6
+#define STV090x_WIDTH_BYPASSPLLCORE_FIELD 1
+#define STV090x_OFFST_SELX1RATIO_FIELD 5
+#define STV090x_WIDTH_SELX1RATIO_FIELD 1
+#define STV090x_OFFST_STOP_PLL_FIELD 3
+#define STV090x_WIDTH_SELX1RATIO_FIELD 1
+#define STV090x_OFFST_BYPASSPLLFSK_FIELD 2
+#define STV090x_WIDTH_BYPASSPLLFSK_FIELD 1
+#define STV090x_OFFST_SELOSCI_FIELD 1
+#define STV090x_WIDTH_SELOSCI_FIELD 1
+#define STV090x_OFFST_BYPASSPLLADC_FIELD 0
+#define STV090x_WIDTH_BYPASSPLLADC_FIELD 1
+
+#define STV090x_FILTCTRL 0xf1b7
+#define STV090x_OFFST_INV_CLK135_FIELD 7
+#define STV090x_WIDTH_INV_CLK135_FIELD 1
+#define STV090x_OFFST_SEL_FSKCKDIV_FIELD 2
+#define STV090x_WIDTH_SEL_FSKCKDIV_FIELD 1
+#define STV090x_OFFST_INV_CLKFSK_FIELD 1
+#define STV090x_WIDTH_INV_CLKFSK_FIELD 1
+#define STV090x_OFFST_BYPASS_APPLI_FIELD 0
+#define STV090x_WIDTH_BYPASS_APPLI_FIELD 1
+
+#define STV090x_PLLSTAT 0xf1b8
+#define STV090x_OFFST_PLLLOCK_FIELD 0
+#define STV090x_WIDTH_PLLLOCK_FIELD 1
+
+#define STV090x_STOPCLK1 0xf1c2
+#define STV090x_OFFST_STOP_CLKPKDT2_FIELD 6
+#define STV090x_WIDTH_STOP_CLKPKDT2_FIELD 1
+#define STV090x_OFFST_STOP_CLKPKDT1_FIELD 5
+#define STV090x_WIDTH_STOP_CLKPKDT1_FIELD 1
+#define STV090x_OFFST_STOP_CLKFEC_FIELD 4
+#define STV090x_WIDTH_STOP_CLKFEC_FIELD 1
+#define STV090x_OFFST_STOP_CLKADCI2_FIELD 3
+#define STV090x_WIDTH_STOP_CLKADCI2_FIELD 1
+#define STV090x_OFFST_INV_CLKADCI2_FIELD 2
+#define STV090x_WIDTH_INV_CLKADCI2_FIELD 1
+#define STV090x_OFFST_STOP_CLKADCI1_FIELD 1
+#define STV090x_WIDTH_STOP_CLKADCI1_FIELD 1
+#define STV090x_OFFST_INV_CLKADCI1_FIELD 0
+#define STV090x_WIDTH_INV_CLKADCI1_FIELD 1
+
+#define STV090x_STOPCLK2 0xf1c3
+#define STV090x_OFFST_STOP_CLKSAMP2_FIELD 4
+#define STV090x_WIDTH_STOP_CLKSAMP2_FIELD 1
+#define STV090x_OFFST_STOP_CLKSAMP1_FIELD 3
+#define STV090x_WIDTH_STOP_CLKSAMP1_FIELD 1
+#define STV090x_OFFST_STOP_CLKVIT2_FIELD 2
+#define STV090x_WIDTH_STOP_CLKVIT2_FIELD 1
+#define STV090x_OFFST_STOP_CLKVIT1_FIELD 1
+#define STV090x_WIDTH_STOP_CLKVIT1_FIELD 1
+#define STV090x_OFFST_STOP_CLKTS_FIELD 0
+#define STV090x_WIDTH_STOP_CLKTS_FIELD 1
+
+#define STV090x_TSTTNR0 0xf1df
+#define STV090x_OFFST_SEL_FSK_FIELD 7
+#define STV090x_WIDTH_SEL_FSK_FIELD 1
+#define STV090x_OFFST_FSK_PON_FIELD 2
+#define STV090x_WIDTH_FSK_PON_FIELD 1
+
+#define STV090x_TSTTNR1 0xf1e0
+#define STV090x_OFFST_ADC1_PON_FIELD 1
+#define STV090x_WIDTH_ADC1_PON_FIELD 1
+#define STV090x_OFFST_ADC1_INMODE_FIELD 0
+#define STV090x_WIDTH_ADC1_INMODE_FIELD 1
+
+#define STV090x_TSTTNR2 0xf1e1
+#define STV090x_OFFST_DISEQC1_PON_FIELD 5
+#define STV090x_WIDTH_DISEQC1_PON_FIELD 1
+
+#define STV090x_TSTTNR3 0xf1e2
+#define STV090x_OFFST_ADC2_PON_FIELD 1
+#define STV090x_WIDTH_ADC2_PON_FIELD 1
+#define STV090x_OFFST_ADC2_INMODE_FIELD 0
+#define STV090x_WIDTH_ADC2_INMODE_FIELD 1
+
+#define STV090x_TSTTNR4 0xf1e3
+#define STV090x_OFFST_DISEQC2_PON_FIELD 5
+#define STV090x_WIDTH_DISEQC2_PON_FIELD 1
+
+#define STV090x_FSKTFC2 0xf170
+#define STV090x_OFFST_FSKT_KMOD_FIELD 2
+#define STV090x_WIDTH_FSKT_KMOD_FIELD 6
+#define STV090x_OFFST_FSKT_CAR_FIELD 0
+#define STV090x_WIDTH_FSKT_CAR_FIELD 2
+
+#define STV090x_FSKTFC1 0xf171
+#define STV090x_OFFST_FSKTC1_CAR_FIELD 0
+#define STV090x_WIDTH_FSKTC1_CAR_FIELD 8
+
+#define STV090x_FSKTFC0 0xf172
+#define STV090x_OFFST_FSKTC0_CAR_FIELD 0
+#define STV090x_WIDTH_FSKTC0_CAR_FIELD 8
+
+#define STV090x_FSKTDELTAF1 0xf173
+#define STV090x_OFFST_FSKTF1_DELTAF_FIELD 0
+#define STV090x_WIDTH_FSKTF1_DELTAF_FIELD 4
+
+#define STV090x_FSKTDELTAF0 0xf174
+#define STV090x_OFFST_FSKTF0_DELTAF_FIELD 0
+#define STV090x_WIDTH_FSKTF0_DELTAF_FIELD 8
+
+#define STV090x_FSKTCTRL 0xf175
+#define STV090x_OFFST_FSKT_EN_SGN_FIELD 6
+#define STV090x_WIDTH_FSKT_EN_SGN_FIELD 1
+#define STV090x_OFFST_FSKT_MOD_SGN_FIELD 5
+#define STV090x_WIDTH_FSKT_MOD_SGN_FIELD 1
+#define STV090x_OFFST_FSKT_MOD_EN_FIELD 2
+#define STV090x_WIDTH_FSKT_MOD_EN_FIELD 3
+#define STV090x_OFFST_FSKT_DACMODE_FIELD 0
+#define STV090x_WIDTH_FSKT_DACMODE_FIELD 2
+
+#define STV090x_FSKRFC2 0xf176
+#define STV090x_OFFST_FSKRC2_DETSGN_FIELD 6
+#define STV090x_WIDTH_FSKRC2_DETSGN_FIELD 1
+#define STV090x_OFFST_FSKRC2_OUTSGN_FIELD 5
+#define STV090x_WIDTH_FSKRC2_OUTSGN_FIELD 1
+#define STV090x_OFFST_FSKRC2_KAGC_FIELD 2
+#define STV090x_WIDTH_FSKRC2_KAGC_FIELD 3
+#define STV090x_OFFST_FSKRC2_CAR_FIELD 0
+#define STV090x_WIDTH_FSKRC2_CAR_FIELD 2
+
+#define STV090x_FSKRFC1 0xf177
+#define STV090x_OFFST_FSKRC1_CAR_FIELD 0
+#define STV090x_WIDTH_FSKRC1_CAR_FIELD 8
+
+#define STV090x_FSKRFC0 0xf178
+#define STV090x_OFFST_FSKRC0_CAR_FIELD 0
+#define STV090x_WIDTH_FSKRC0_CAR_FIELD 8
+
+#define STV090x_FSKRK1 0xf179
+#define STV090x_OFFST_FSKR_K1_EXP_FIELD 5
+#define STV090x_WIDTH_FSKR_K1_EXP_FIELD 3
+#define STV090x_OFFST_FSKR_K1_MANT_FIELD 0
+#define STV090x_WIDTH_FSKR_K1_MANT_FIELD 5
+
+#define STV090x_FSKRK2 0xf17a
+#define STV090x_OFFST_FSKR_K2_EXP_FIELD 5
+#define STV090x_WIDTH_FSKR_K2_EXP_FIELD 3
+#define STV090x_OFFST_FSKR_K2_MANT_FIELD 0
+#define STV090x_WIDTH_FSKR_K2_MANT_FIELD 5
+
+#define STV090x_FSKRAGCR 0xf17b
+#define STV090x_OFFST_FSKR_OUTCTL_FIELD 6
+#define STV090x_WIDTH_FSKR_OUTCTL_FIELD 2
+#define STV090x_OFFST_FSKR_AGC_REF_FIELD 0
+#define STV090x_WIDTH_FSKR_AGC_REF_FIELD 6
+
+#define STV090x_FSKRAGC 0xf17c
+#define STV090x_OFFST_FSKR_AGC_ACCU_FIELD 0
+#define STV090x_WIDTH_FSKR_AGC_ACCU_FIELD 8
+
+#define STV090x_FSKRALPHA 0xf17d
+#define STV090x_OFFST_FSKR_ALPHA_EXP_FIELD 2
+#define STV090x_WIDTH_FSKR_ALPHA_EXP_FIELD 3
+#define STV090x_OFFST_FSKR_ALPHA_M_FIELD 0
+#define STV090x_WIDTH_FSKR_ALPHA_M_FIELD 2
+
+#define STV090x_FSKRPLTH1 0xf17e
+#define STV090x_OFFST_FSKR_BETA_FIELD 4
+#define STV090x_WIDTH_FSKR_BETA_FIELD 4
+#define STV090x_OFFST_FSKR_PLL_TRESH1_FIELD 0
+#define STV090x_WIDTH_FSKR_PLL_TRESH1_FIELD 4
+
+#define STV090x_FSKRPLTH0 0xf17f
+#define STV090x_OFFST_FSKR_PLL_TRESH0_FIELD 0
+#define STV090x_WIDTH_FSKR_PLL_TRESH0_FIELD 8
+
+#define STV090x_FSKRDF1 0xf180
+#define STV090x_OFFST_FSKR_DELTAF1_FIELD 0
+#define STV090x_WIDTH_FSKR_DELTAF1_FIELD 5
+
+#define STV090x_FSKRDF0 0xf181
+#define STV090x_OFFST_FSKR_DELTAF0_FIELD 0
+#define STV090x_WIDTH_FSKR_DELTAF0_FIELD 8
+
+#define STV090x_FSKRSTEPP 0xf182
+#define STV090x_OFFST_FSKR_STEP_PLUS_FIELD 0
+#define STV090x_WIDTH_FSKR_STEP_PLUS_FIELD 8
+
+#define STV090x_FSKRSTEPM 0xf183
+#define STV090x_OFFST_FSKR_STEP_MINUS_FIELD 0
+#define STV090x_WIDTH_FSKR_STEP_MINUS_FIELD 8
+
+#define STV090x_FSKRDET1 0xf184
+#define STV090x_OFFST_FSKR_CARDET1_ACCU_FIELD 0
+#define STV090x_WIDTH_FSKR_CARDET1_ACCU_FIELD 4
+
+#define STV090x_FSKRDET0 0xf185
+#define STV090x_OFFST_FSKR_CARDET0_ACCU_FIELD 0
+#define STV090x_WIDTH_FSKR_CARDET0_ACCU_FIELD 8
+
+#define STV090x_FSKRDTH1 0xf186
+#define STV090x_OFFST_FSKR_CARLOSS_THRESH1_FIELD 4
+#define STV090x_WIDTH_FSKR_CARLOSS_THRESH1_FIELD 4
+#define STV090x_OFFST_FSKR_CARDET_THRESH1_FIELD 0
+#define STV090x_WIDTH_FSKR_CARDET_THRESH1_FIELD 4
+
+#define STV090x_FSKRDTH0 0xf187
+#define STV090x_OFFST_FSKR_CARDET_THRESH0_FIELD 0
+#define STV090x_WIDTH_FSKR_CARDET_THRESH0_FIELD 8
+
+#define STV090x_FSKRLOSS 0xf188
+#define STV090x_OFFST_FSKR_CARLOSS_THRESH_FIELD 0
+#define STV090x_WIDTH_FSKR_CARLOSS_THRESH_FIELD 8
+
+#define STV090x_Px_DISTXCTL(__x) (0xF1A0 - (__x - 1) * 0x10)
+#define STV090x_P1_DISTXCTL STV090x_Px_DISTXCTL(1)
+#define STV090x_P2_DISTXCTL STV090x_Px_DISTXCTL(2)
+#define STV090x_OFFST_Px_TIM_OFF_FIELD 7
+#define STV090x_WIDTH_Px_TIM_OFF_FIELD 1
+#define STV090x_OFFST_Px_DISEQC_RESET_FIELD 6
+#define STV090x_WIDTH_Px_DISEQC_RESET_FIELD 1
+#define STV090x_OFFST_Px_TIM_CMD_FIELD 4
+#define STV090x_WIDTH_Px_TIM_CMD_FIELD 2
+#define STV090x_OFFST_Px_DIS_PRECHARGE_FIELD 3
+#define STV090x_WIDTH_Px_DIS_PRECHARGE_FIELD 1
+#define STV090x_OFFST_Px_DISTX_MODE_FIELD 0
+#define STV090x_WIDTH_Px_DISTX_MODE_FIELD 3
+
+#define STV090x_Px_DISRXCTL(__x) (0xf1a1 - (__x - 1) * 0x10)
+#define STV090x_P1_DISRXCTL STV090x_Px_DISRXCTL(1)
+#define STV090x_P2_DISRXCTL STV090x_Px_DISRXCTL(2)
+#define STV090x_OFFST_Px_RECEIVER_ON_FIELD 7
+#define STV090x_WIDTH_Px_RECEIVER_ON_FIELD 1
+#define STV090x_OFFST_Px_IGNO_SHORT22K_FIELD 6
+#define STV090x_WIDTH_Px_IGNO_SHORT22K_FIELD 1
+#define STV090x_OFFST_Px_ONECHIP_TRX_FIELD 5
+#define STV090x_WIDTH_Px_ONECHIP_TRX_FIELD 1
+#define STV090x_OFFST_Px_EXT_ENVELOP_FIELD 4
+#define STV090x_WIDTH_Px_EXT_ENVELOP_FIELD 1
+#define STV090x_OFFST_Px_PIN_SELECT_FIELD 2
+#define STV090x_WIDTH_Px_PIN_SELECT_FIELD 2
+#define STV090x_OFFST_Px_IRQ_RXEND_FIELD 1
+#define STV090x_WIDTH_Px_IRQ_RXEND_FIELD 1
+#define STV090x_OFFST_Px_IRQ_4NBYTES_FIELD 0
+#define STV090x_WIDTH_Px_IRQ_4NBYTES_FIELD 1
+
+#define STV090x_Px_DISRX_ST0(__x) (0xf1a4 - (__x - 1) * 0x10)
+#define STV090x_P1_DISRX_ST0 STV090x_Px_DISRX_ST0(1)
+#define STV090x_P2_DISRX_ST0 STV090x_Px_DISRX_ST0(2)
+#define STV090x_OFFST_Px_RX_END_FIELD 7
+#define STV090x_WIDTH_Px_RX_END_FIELD 1
+#define STV090x_OFFST_Px_RX_ACTIVE_FIELD 6
+#define STV090x_WIDTH_Px_RX_ACTIVE_FIELD 1
+#define STV090x_OFFST_Px_SHORT_22KHZ_FIELD 5
+#define STV090x_WIDTH_Px_SHORT_22KHZ_FIELD 1
+#define STV090x_OFFST_Px_CONT_TONE_FIELD 4
+#define STV090x_WIDTH_Px_CONT_TONE_FIELD 1
+#define STV090x_OFFST_Px_FIFO_4BREADY_FIELD 3
+#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD 2
+#define STV090x_OFFST_Px_FIFO_EMPTY_FIELD 2
+#define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD 1
+#define STV090x_OFFST_Px_ABORT_DISRX_FIELD 0
+#define STV090x_WIDTH_Px_ABORT_DISRX_FIELD 1
+
+#define STV090x_Px_DISRX_ST1(__x) (0xf1a5 - (__x - 1) * 0x10)
+#define STV090x_P1_DISRX_ST1 STV090x_Px_DISRX_ST1(1)
+#define STV090x_P2_DISRX_ST1 STV090x_Px_DISRX_ST1(2)
+#define STV090x_OFFST_Px_RX_FAIL_FIELD 7
+#define STV090x_WIDTH_Px_RX_FAIL_FIELD 1
+#define STV090x_OFFST_Px_FIFO_PARITYFAIL_FIELD 6
+#define STV090x_WIDTH_Px_FIFO_PARITYFAIL_FIELD 1
+#define STV090x_OFFST_Px_RX_NONBYTE_FIELD 5
+#define STV090x_WIDTH_Px_RX_NONBYTE_FIELD 1
+#define STV090x_OFFST_Px_FIFO_OVERFLOW_FIELD 4
+#define STV090x_WIDTH_Px_FIFO_OVERFLOW_FIELD 1
+#define STV090x_OFFST_Px_FIFO_BYTENBR_FIELD 0
+#define STV090x_WIDTH_Px_FIFO_BYTENBR_FIELD 4
+
+#define STV090x_Px_DISRXDATA(__x) (0xf1a6 - (__x - 1) * 0x10)
+#define STV090x_P1_DISRXDATA STV090x_Px_DISRXDATA(1)
+#define STV090x_P2_DISRXDATA STV090x_Px_DISRXDATA(2)
+#define STV090x_OFFST_Px_DISRX_DATA_FIELD 0
+#define STV090x_WIDTH_Px_DISRX_DATA_FIELD 8
+
+#define STV090x_Px_DISTXDATA(__x) (0xf1a7 - (__x - 1) * 0x10)
+#define STV090x_P1_DISTXDATA STV090x_Px_DISTXDATA(1)
+#define STV090x_P2_DISTXDATA STV090x_Px_DISTXDATA(2)
+#define STV090x_OFFST_Px_DISEQC_FIFO_FIELD 0
+#define STV090x_WIDTH_Px_DISEQC_FIFO_FIELD 8
+
+#define STV090x_Px_DISTXSTATUS(__x) (0xf1a8 - (__x - 1) * 0x10)
+#define STV090x_P1_DISTXSTATUS STV090x_Px_DISTXSTATUS(1)
+#define STV090x_P2_DISTXSTATUS STV090x_Px_DISTXSTATUS(2)
+#define STV090x_OFFST_Px_TX_FAIL_FIELD 7
+#define STV090x_WIDTH_Px_TX_FAIL_FIELD 1
+#define STV090x_OFFST_Px_FIFO_FULL_FIELD 6
+#define STV090x_WIDTH_Px_FIFO_FULL_FIELD 1
+#define STV090x_OFFST_Px_TX_IDLE_FIELD 5
+#define STV090x_WIDTH_Px_TX_IDLE_FIELD 1
+#define STV090x_OFFST_Px_GAP_BURST_FIELD 4
+#define STV090x_WIDTH_Px_GAP_BURST_FIELD 1
+#define STV090x_OFFST_Px_TXFIFO_BYTES_FIELD 0
+#define STV090x_WIDTH_Px_TXFIFO_BYTES_FIELD 4
+
+#define STV090x_Px_F22TX(__x) (0xf1a9 - (__x - 1) * 0x10)
+#define STV090x_P1_F22TX STV090x_Px_F22TX(1)
+#define STV090x_P2_F22TX STV090x_Px_F22TX(2)
+#define STV090x_OFFST_Px_F22_REG_FIELD 0
+#define STV090x_WIDTH_Px_F22_REG_FIELD 8
+
+#define STV090x_Px_F22RX(__x) (0xf1aa - (__x - 1) * 0x10)
+#define STV090x_P1_F22RX STV090x_Px_F22RX(1)
+#define STV090x_P2_F22RX STV090x_Px_F22RX(2)
+#define STV090x_OFFST_Px_F22RX_REG_FIELD 0
+#define STV090x_WIDTH_Px_F22RX_REG_FIELD 8
+
+#define STV090x_Px_ACRPRESC(__x) (0xf1ac - (__x - 1) * 0x10)
+#define STV090x_P1_ACRPRESC STV090x_Px_ACRPRESC(1)
+#define STV090x_P2_ACRPRESC STV090x_Px_ACRPRESC(2)
+#define STV090x_OFFST_Px_ACR_PRESC_FIELD 0
+#define STV090x_WIDTH_Px_ACR_PRESC_FIELD 3
+
+#define STV090x_Px_ACRDIV(__x) (0xf1ad - (__x - 1) * 0x10)
+#define STV090x_P1_ACRDIV STV090x_Px_ACRDIV(1)
+#define STV090x_P2_ACRDIV STV090x_Px_ACRDIV(2)
+#define STV090x_OFFST_Px_ACR_DIV_FIELD 0
+#define STV090x_WIDTH_Px_ACR_DIV_FIELD 8
+
+#define STV090x_Px_IQCONST(__x) (0xF400 - (__x - 1) * 0x200)
+#define STV090x_P1_IQCONST STV090x_Px_IQCONST(1)
+#define STV090x_P2_IQCONST STV090x_Px_IQCONST(2)
+#define STV090x_OFFST_Px_CONSTEL_SELECT_FIELD 5
+#define STV090x_WIDTH_Px_CONSTEL_SELECT_FIELD 2
+
+#define STV090x_Px_NOSCFG(__x) (0xF401 - (__x - 1) * 0x200)
+#define STV090x_P1_NOSCFG STV090x_Px_NOSCFG(1)
+#define STV090x_P2_NOSCFG STV090x_Px_NOSCFG(2)
+#define STV090x_OFFST_Px_NOSPLH_BETA_FIELD 3
+#define STV090x_WIDTH_Px_NOSPLH_BETA_FIELD 2
+#define STV090x_OFFST_Px_NOSDATA_BETA_FIELD 0
+#define STV090x_WIDTH_Px_NOSDATA_BETA_FIELD 3
+
+#define STV090x_Px_ISYMB(__x) (0xF402 - (__x - 1) * 0x200)
+#define STV090x_P1_ISYMB STV090x_Px_ISYMB(1)
+#define STV090x_P2_ISYMB STV090x_Px_ISYMB(2)
+#define STV090x_OFFST_Px_I_SYMBOL_FIELD 0
+#define STV090x_WIDTH_Px_I_SYMBOL_FIELD 8
+
+#define STV090x_Px_QSYMB(__x) (0xF403 - (__x - 1) * 0x200)
+#define STV090x_P1_QSYMB STV090x_Px_QSYMB(1)
+#define STV090x_P2_QSYMB STV090x_Px_QSYMB(2)
+#define STV090x_OFFST_Px_Q_SYMBOL_FIELD 0
+#define STV090x_WIDTH_Px_Q_SYMBOL_FIELD 8
+
+#define STV090x_Px_AGC1CFG(__x) (0xF404 - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1CFG STV090x_Px_AGC1CFG(1)
+#define STV090x_P2_AGC1CFG STV090x_Px_AGC1CFG(2)
+#define STV090x_OFFST_Px_DC_FROZEN_FIELD 7
+#define STV090x_WIDTH_Px_DC_FROZEN_FIELD 1
+#define STV090x_OFFST_Px_DC_CORRECT_FIELD 6
+#define STV090x_WIDTH_Px_DC_CORRECT_FIELD 1
+#define STV090x_OFFST_Px_AMM_FROZEN_FIELD 5
+#define STV090x_WIDTH_Px_AMM_FROZEN_FIELD 1
+#define STV090x_OFFST_Px_AMM_CORRECT_FIELD 4
+#define STV090x_WIDTH_Px_AMM_CORRECT_FIELD 1
+#define STV090x_OFFST_Px_QUAD_FROZEN_FIELD 3
+#define STV090x_WIDTH_Px_QUAD_FROZEN_FIELD 1
+#define STV090x_OFFST_Px_QUAD_CORRECT_FIELD 2
+#define STV090x_WIDTH_Px_QUAD_CORRECT_FIELD 1
+
+#define STV090x_Px_AGC1CN(__x) (0xF406 - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1CN STV090x_Px_AGC1CN(1)
+#define STV090x_P2_AGC1CN STV090x_Px_AGC1CN(2)
+#define STV090x_WIDTH_Px_AGC1_LOCKED_FIELD 7
+#define STV090x_OFFST_Px_AGC1_LOCKED_FIELD 1
+#define STV090x_OFFST_Px_AGC1_MINPOWER_FIELD 4
+#define STV090x_WIDTH_Px_AGC1_MINPOWER_FIELD 1
+#define STV090x_OFFST_Px_AGCOUT_FAST_FIELD 3
+#define STV090x_WIDTH_Px_AGCOUT_FAST_FIELD 1
+#define STV090x_OFFST_Px_AGCIQ_BETA_FIELD 0
+#define STV090x_WIDTH_Px_AGCIQ_BETA_FIELD 3
+
+#define STV090x_Px_AGC1REF(__x) (0xF407 - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1REF STV090x_Px_AGC1REF(1)
+#define STV090x_P2_AGC1REF STV090x_Px_AGC1REF(2)
+#define STV090x_OFFST_Px_AGCIQ_REF_FIELD 0
+#define STV090x_WIDTH_Px_AGCIQ_REF_FIELD 8
+
+#define STV090x_Px_IDCCOMP(__x) (0xF408 - (__x - 1) * 0x200)
+#define STV090x_P1_IDCCOMP STV090x_Px_IDCCOMP(1)
+#define STV090x_P2_IDCCOMP STV090x_Px_IDCCOMP(2)
+#define STV090x_OFFST_Px_IAVERAGE_ADJ_FIELD 0
+#define STV090x_WIDTH_Px_IAVERAGE_ADJ_FIELD 8
+
+#define STV090x_Px_QDCCOMP(__x) (0xF409 - (__x - 1) * 0x200)
+#define STV090x_P1_QDCCOMP STV090x_Px_QDCCOMP(1)
+#define STV090x_P2_QDCCOMP STV090x_Px_QDCCOMP(2)
+#define STV090x_OFFST_Px_QAVERAGE_ADJ_FIELD 0
+#define STV090x_WIDTH_Px_QAVERAGE_ADJ_FIELD 8
+
+#define STV090x_Px_POWERI(__x) (0xF40A - (__x - 1) * 0x200)
+#define STV090x_P1_POWERI STV090x_Px_POWERI(1)
+#define STV090x_P2_POWERI STV090x_Px_POWERI(2)
+#define STV090x_OFFST_Px_POWER_I_FIELD 0
+#define STV090x_WIDTH_Px_POWER_I_FIELD 8
+
+#define STV090x_Px_POWERQ(__x) (0xF40B - (__x - 1) * 0x200)
+#define STV090x_P1_POWERQ STV090x_Px_POWERQ(1)
+#define STV090x_P2_POWERQ STV090x_Px_POWERQ(2)
+#define STV090x_OFFST_Px_POWER_Q_FIELD 0
+#define STV090x_WIDTH_Px_POWER_Q_FIELD 8
+
+#define STV090x_Px_AGC1AMM(__x) (0xF40C - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1AMM STV090x_Px_AGC1AMM(1)
+#define STV090x_P2_AGC1AMM STV090x_Px_AGC1AMM(2)
+#define STV090x_OFFST_Px_AMM_VALUE_FIELD 0
+#define STV090x_WIDTH_Px_AMM_VALUE_FIELD 8
+
+#define STV090x_Px_AGC1QUAD(__x) (0xF40D - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1QUAD STV090x_Px_AGC1QUAD(1)
+#define STV090x_P2_AGC1QUAD STV090x_Px_AGC1QUAD(2)
+#define STV090x_OFFST_Px_QUAD_VALUE_FIELD 0
+#define STV090x_WIDTH_Px_QUAD_VALUE_FIELD 8
+
+#define STV090x_Px_AGCIQINy(__x, __y) (0xF40F - (__x-1) * 0x200 - __y * 0x1)
+#define STV090x_P1_AGCIQIN0 STV090x_Px_AGCIQINy(1, 0)
+#define STV090x_P1_AGCIQIN1 STV090x_Px_AGCIQINy(1, 1)
+#define STV090x_P2_AGCIQIN0 STV090x_Px_AGCIQINy(2, 0)
+#define STV090x_P2_AGCIQIN1 STV090x_Px_AGCIQINy(2, 1)
+#define STV090x_OFFST_Px_AGCIQ_VALUE_FIELD 0
+#define STV090x_WIDTH_Px_AGCIQ_VALUE_FIELD 8
+
+#define STV090x_Px_DEMOD(__x) (0xF410 - (__x - 1) * 0x200)
+#define STV090x_P1_DEMOD STV090x_Px_DEMOD(1)
+#define STV090x_P2_DEMOD STV090x_Px_DEMOD(2)
+#define STV090x_OFFST_Px_MANUAL_S2ROLLOFF_FIELD 7
+#define STV090x_WIDTH_Px_MANUAL_S2ROLLOFF_FIELD 1
+#define STV090x_OFFST_Px_DEMOD_STOP_FIELD 6
+#define STV090x_WIDTH_Px_DEMOD_STOP_FIELD 1
+#define STV090x_OFFST_Px_SPECINV_CONTROL_FIELD 4
+#define STV090x_WIDTH_Px_SPECINV_CONTROL_FIELD 2
+#define STV090x_OFFST_Px_FORCE_ENASAMP_FIELD 3
+#define STV090x_WIDTH_Px_FORCE_ENASAMP_FIELD 1
+#define STV090x_OFFST_Px_MANUAL_SXROLLOFF_FIELD 2
+#define STV090x_WIDTH_Px_MANUAL_SXROLLOFF_FIELD 1
+#define STV090x_OFFST_Px_ROLLOFF_CONTROL_FIELD 0
+#define STV090x_WIDTH_Px_ROLLOFF_CONTROL_FIELD 2
+
+#define STV090x_Px_DMDMODCOD(__x) (0xF411 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDMODCOD STV090x_Px_DMDMODCOD(1)
+#define STV090x_P2_DMDMODCOD STV090x_Px_DMDMODCOD(2)
+#define STV090x_OFFST_Px_MANUAL_MODCOD_FIELD 7
+#define STV090x_WIDTH_Px_MANUAL_MODCOD_FIELD 1
+#define STV090x_OFFST_Px_DEMOD_MODCOD_FIELD 2
+#define STV090x_WIDTH_Px_DEMOD_MODCOD_FIELD 5
+#define STV090x_OFFST_Px_DEMOD_TYPE_FIELD 0
+#define STV090x_WIDTH_Px_DEMOD_TYPE_FIELD 2
+
+#define STV090x_Px_DSTATUS(__x) (0xF412 - (__x - 1) * 0x200)
+#define STV090x_P1_DSTATUS STV090x_Px_DSTATUS(1)
+#define STV090x_P2_DSTATUS STV090x_Px_DSTATUS(2)
+#define STV090x_OFFST_Px_CAR_LOCK_FIELD 7
+#define STV090x_WIDTH_Px_CAR_LOCK_FIELD 1
+#define STV090x_OFFST_Px_TMGLOCK_QUALITY_FIELD 5
+#define STV090x_WIDTH_Px_TMGLOCK_QUALITY_FIELD 2
+#define STV090x_OFFST_Px_LOCK_DEFINITIF_FIELD 3
+#define STV090x_WIDTH_Px_LOCK_DEFINITIF_FIELD 1
+
+#define STV090x_Px_DSTATUS2(__x) (0xF413 - (__x - 1) * 0x200)
+#define STV090x_P1_DSTATUS2 STV090x_Px_DSTATUS2(1)
+#define STV090x_P2_DSTATUS2 STV090x_Px_DSTATUS2(2)
+#define STV090x_OFFST_Px_DEMOD_DELOCK_FIELD 7
+#define STV090x_WIDTH_Px_DEMOD_DELOCK_FIELD 1
+#define STV090x_OFFST_Px_AGC1_NOSIGNALACK_FIELD 3
+#define STV090x_WIDTH_Px_AGC1_NOSIGNALACK_FIELD 1
+#define STV090x_OFFST_Px_AGC2_OVERFLOW_FIELD 2
+#define STV090x_WIDTH_Px_AGC2_OVERFLOW_FIELD 1
+#define STV090x_OFFST_Px_CFR_OVERFLOW_FIELD 1
+#define STV090x_WIDTH_Px_CFR_OVERFLOW_FIELD 1
+#define STV090x_OFFST_Px_GAMMA_OVERUNDER_FIELD 0
+#define STV090x_WIDTH_Px_GAMMA_OVERUNDER_FIELD 1
+
+#define STV090x_Px_DMDCFGMD(__x) (0xF414 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDCFGMD STV090x_Px_DMDCFGMD(1)
+#define STV090x_P2_DMDCFGMD STV090x_Px_DMDCFGMD(2)
+#define STV090x_OFFST_Px_DVBS2_ENABLE_FIELD 7
+#define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD 1
+#define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD 6
+#define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD 1
+#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD 5 /* check */
+#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD 1
+#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD 4 /* check */
+#define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD 1
+#define STV090x_OFFST_Px_TUN_AUTOSCAN_FIELD 3
+#define STV090x_WIDTH_Px_TUN_AUTOSCAN_FIELD 1
+#define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD 2
+#define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD 1
+#define STV090x_OFFST_Px_TUN_RNG_FIELD 0
+#define STV090x_WIDTH_Px_TUN_RNG_FIELD 2
+
+#define STV090x_Px_DMDCFG2(__x) (0xF415 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDCFG2 STV090x_Px_DMDCFG2(1)
+#define STV090x_P2_DMDCFG2 STV090x_Px_DMDCFG2(2)
+#define STV090x_OFFST_Px_S1S2_SEQUENTIAL_FIELD 6
+#define STV090x_WIDTH_Px_S1S2_SEQUENTIAL_FIELD 1
+
+#define STV090x_Px_DMDISTATE(__x) (0xF416 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDISTATE STV090x_Px_DMDISTATE(1)
+#define STV090x_P2_DMDISTATE STV090x_Px_DMDISTATE(2)
+#define STV090x_OFFST_Px_I2C_DEMOD_MODE_FIELD 0
+#define STV090x_WIDTH_Px_I2C_DEMOD_MODE_FIELD 5
+
+#define STV090x_Px_DMDTOM(__x) (0xF417 - (__x - 1) * 0x200) /* check */
+#define STV090x_P1_DMDTOM STV090x_Px_DMDTOM(1)
+#define STV090x_P2_DMDTOM STV090x_Px_DMDTOM(2)
+
+#define STV090x_Px_DMDSTATE(__x) (0xF41B - (__x - 1) * 0x200)
+#define STV090x_P1_DMDSTATE STV090x_Px_DMDSTATE(1)
+#define STV090x_P2_DMDSTATE STV090x_Px_DMDSTATE(2)
+#define STV090x_OFFST_Px_HEADER_MODE_FIELD 5
+#define STV090x_WIDTH_Px_HEADER_MODE_FIELD 2
+
+#define STV090x_Px_DMDFLYW(__x) (0xF41C - (__x - 1) * 0x200)
+#define STV090x_P1_DMDFLYW STV090x_Px_DMDFLYW(1)
+#define STV090x_P2_DMDFLYW STV090x_Px_DMDFLYW(2)
+#define STV090x_OFFST_Px_I2C_IRQVAL_FIELD 4
+#define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD 4
+#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD 0 /* check */
+#define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD 4
+
+#define STV090x_Px_DSTATUS3(__x) (0xF41D - (__x - 1) * 0x200)
+#define STV090x_P1_DSTATUS3 STV090x_Px_DSTATUS3(1)
+#define STV090x_P2_DSTATUS3 STV090x_Px_DSTATUS3(2)
+#define STV090x_OFFST_Px_DEMOD_CFGMODE_FIELD 5
+#define STV090x_WIDTH_Px_DEMOD_CFGMODE_FIELD 2
+
+#define STV090x_Px_DMDCFG3(__x) (0xF41E - (__x - 1) * 0x200)
+#define STV090x_P1_DMDCFG3 STV090x_Px_DMDCFG3(1)
+#define STV090x_P2_DMDCFG3 STV090x_Px_DMDCFG3(2)
+#define STV090x_OFFST_Px_NOSTOP_FIFOFULL_FIELD 3
+#define STV090x_WIDTH_Px_NOSTOP_FIFOFULL_FIELD 1
+
+#define STV090x_Px_DMDCFG4(__x) (0xf41f - (__x - 1) * 0x200)
+#define STV090x_P1_DMDCFG4 STV090x_Px_DMDCFG4(1)
+#define STV090x_P2_DMDCFG4 STV090x_Px_DMDCFG4(2)
+
+#define STV090x_Px_CORRELMANT(__x) (0xF420 - (__x - 1) * 0x200)
+#define STV090x_P1_CORRELMANT STV090x_Px_CORRELMANT(1)
+#define STV090x_P2_CORRELMANT STV090x_Px_CORRELMANT(2)
+#define STV090x_OFFST_Px_CORREL_MANT_FIELD 0
+#define STV090x_WIDTH_Px_CORREL_MANT_FIELD 8
+
+#define STV090x_Px_CORRELABS(__x) (0xF421 - (__x - 1) * 0x200)
+#define STV090x_P1_CORRELABS STV090x_Px_CORRELABS(1)
+#define STV090x_P2_CORRELABS STV090x_Px_CORRELABS(2)
+#define STV090x_OFFST_Px_CORREL_ABS_FIELD 0
+#define STV090x_WIDTH_Px_CORREL_ABS_FIELD 8
+
+#define STV090x_Px_CORRELEXP(__x) (0xF422 - (__x - 1) * 0x200)
+#define STV090x_P1_CORRELEXP STV090x_Px_CORRELEXP(1)
+#define STV090x_P2_CORRELEXP STV090x_Px_CORRELEXP(2)
+#define STV090x_OFFST_Px_CORREL_ABSEXP_FIELD 4
+#define STV090x_WIDTH_Px_CORREL_ABSEXP_FIELD 4
+#define STV090x_OFFST_Px_CORREL_EXP_FIELD 0
+#define STV090x_WIDTH_Px_CORREL_EXP_FIELD 4
+
+#define STV090x_Px_PLHMODCOD(__x) (0xF424 - (__x - 1) * 0x200)
+#define STV090x_P1_PLHMODCOD STV090x_Px_PLHMODCOD(1)
+#define STV090x_P2_PLHMODCOD STV090x_Px_PLHMODCOD(2)
+#define STV090x_OFFST_Px_SPECINV_DEMOD_FIELD 7
+#define STV090x_WIDTH_Px_SPECINV_DEMOD_FIELD 1
+#define STV090x_OFFST_Px_PLH_MODCOD_FIELD 2
+#define STV090x_WIDTH_Px_PLH_MODCOD_FIELD 5
+#define STV090x_OFFST_Px_PLH_TYPE_FIELD 0
+#define STV090x_WIDTH_Px_PLH_TYPE_FIELD 2
+
+#define STV090x_Px_AGCK32(__x) (0xf42b - (__x - 1) * 0x200)
+#define STV090x_P1_AGCK32 STV090x_Px_AGCK32(1)
+#define STV090x_P2_AGCK32 STV090x_Px_AGCK32(2)
+
+#define STV090x_Px_AGC2O(__x) (0xF42C - (__x - 1) * 0x200)
+#define STV090x_P1_AGC2O STV090x_Px_AGC2O(1)
+#define STV090x_P2_AGC2O STV090x_Px_AGC2O(2)
+
+#define STV090x_Px_AGC2REF(__x) (0xF42D - (__x - 1) * 0x200)
+#define STV090x_P1_AGC2REF STV090x_Px_AGC2REF(1)
+#define STV090x_P2_AGC2REF STV090x_Px_AGC2REF(2)
+#define STV090x_OFFST_Px_AGC2_REF_FIELD 0
+#define STV090x_WIDTH_Px_AGC2_REF_FIELD 8
+
+#define STV090x_Px_AGC1ADJ(__x) (0xF42E - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1ADJ STV090x_Px_AGC1ADJ(1)
+#define STV090x_P2_AGC1ADJ STV090x_Px_AGC1ADJ(2)
+#define STV090x_OFFST_Px_AGC1_ADJUSTED_FIELD 0
+#define STV090x_WIDTH_Px_AGC1_ADJUSTED_FIELD 7
+
+#define STV090x_Px_AGC2Iy(__x, __y) (0xF437 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_AGC2I0 STV090x_Px_AGC2Iy(1, 0)
+#define STV090x_P1_AGC2I1 STV090x_Px_AGC2Iy(1, 1)
+#define STV090x_P2_AGC2I0 STV090x_Px_AGC2Iy(2, 0)
+#define STV090x_P2_AGC2I1 STV090x_Px_AGC2Iy(2, 1)
+#define STV090x_OFFST_Px_AGC2_INTEGRATOR_FIELD 0
+#define STV090x_WIDTH_Px_AGC2_INTEGRATOR_FIELD 8
+
+#define STV090x_Px_CARCFG(__x) (0xF438 - (__x - 1) * 0x200)
+#define STV090x_P1_CARCFG STV090x_Px_CARCFG(1)
+#define STV090x_P2_CARCFG STV090x_Px_CARCFG(2)
+#define STV090x_OFFST_Px_EN_CAR2CENTER_FIELD 5
+#define STV090x_WIDTH_Px_EN_CAR2CENTER_FIELD 1
+#define STV090x_OFFST_Px_ROTATON_FIELD 2
+#define STV090x_WIDTH_Px_ROTATON_FIELD 1
+#define STV090x_OFFST_Px_PH_DET_ALGO_FIELD 0
+#define STV090x_WIDTH_Px_PH_DET_ALGO_FIELD 2
+
+#define STV090x_Px_ACLC(__x) (0xF439 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC STV090x_Px_ACLC(1)
+#define STV090x_P2_ACLC STV090x_Px_ACLC(2)
+#define STV090x_OFFST_Px_CAR_ALPHA_MANT_FIELD 4
+#define STV090x_WIDTH_Px_CAR_ALPHA_MANT_FIELD 2
+#define STV090x_OFFST_Px_CAR_ALPHA_EXP_FIELD 0
+#define STV090x_WIDTH_Px_CAR_ALPHA_EXP_FIELD 4
+
+#define STV090x_Px_BCLC(__x) (0xF43A - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC STV090x_Px_BCLC(1)
+#define STV090x_P2_BCLC STV090x_Px_BCLC(2)
+#define STV090x_OFFST_Px_CAR_BETA_MANT_FIELD 4
+#define STV090x_WIDTH_Px_CAR_BETA_MANT_FIELD 2
+#define STV090x_OFFST_Px_CAR_BETA_EXP_FIELD 0
+#define STV090x_WIDTH_Px_CAR_BETA_EXP_FIELD 4
+
+#define STV090x_Px_CARFREQ(__x) (0xF43D - (__x - 1) * 0x200)
+#define STV090x_P1_CARFREQ STV090x_Px_CARFREQ(1)
+#define STV090x_P2_CARFREQ STV090x_Px_CARFREQ(2)
+#define STV090x_OFFST_Px_KC_COARSE_EXP_FIELD 4
+#define STV090x_WIDTH_Px_KC_COARSE_EXP_FIELD 4
+#define STV090x_OFFST_Px_BETA_FREQ_FIELD 0
+#define STV090x_WIDTH_Px_BETA_FREQ_FIELD 4
+
+#define STV090x_Px_CARHDR(__x) (0xF43E - (__x - 1) * 0x200)
+#define STV090x_P1_CARHDR STV090x_Px_CARHDR(1)
+#define STV090x_P2_CARHDR STV090x_Px_CARHDR(2)
+#define STV090x_OFFST_Px_FREQ_HDR_FIELD 0
+#define STV090x_WIDTH_Px_FREQ_HDR_FIELD 8
+
+#define STV090x_Px_LDT(__x) (0xF43F - (__x - 1) * 0x200)
+#define STV090x_P1_LDT STV090x_Px_LDT(1)
+#define STV090x_P2_LDT STV090x_Px_LDT(2)
+#define STV090x_OFFST_Px_CARLOCK_THRES_FIELD 0
+#define STV090x_WIDTH_Px_CARLOCK_THRES_FIELD 8
+
+#define STV090x_Px_LDT2(__x) (0xF440 - (__x - 1) * 0x200)
+#define STV090x_P1_LDT2 STV090x_Px_LDT2(1)
+#define STV090x_P2_LDT2 STV090x_Px_LDT2(2)
+#define STV090x_OFFST_Px_CARLOCK_THRES2_FIELD 0
+#define STV090x_WIDTH_Px_CARLOCK_THRES2_FIELD 8
+
+#define STV090x_Px_CFRICFG(__x) (0xF441 - (__x - 1) * 0x200)
+#define STV090x_P1_CFRICFG STV090x_Px_CFRICFG(1)
+#define STV090x_P2_CFRICFG STV090x_Px_CFRICFG(2)
+#define STV090x_OFFST_Px_NEG_CFRSTEP_FIELD 0
+#define STV090x_WIDTH_Px_NEG_CFRSTEP_FIELD 1
+
+#define STV090x_Pn_CFRUPy(__x, __y) (0xF443 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_CFRUP0 STV090x_Pn_CFRUPy(1, 0)
+#define STV090x_P1_CFRUP1 STV090x_Pn_CFRUPy(1, 1)
+#define STV090x_P2_CFRUP0 STV090x_Pn_CFRUPy(2, 0)
+#define STV090x_P2_CFRUP1 STV090x_Pn_CFRUPy(2, 1)
+#define STV090x_OFFST_Px_CFR_UP_FIELD 0
+#define STV090x_WIDTH_Px_CFR_UP_FIELD 8
+
+#define STV090x_Pn_CFRLOWy(__x, __y) (0xF447 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_CFRLOW0 STV090x_Pn_CFRLOWy(1, 0)
+#define STV090x_P1_CFRLOW1 STV090x_Pn_CFRLOWy(1, 1)
+#define STV090x_P2_CFRLOW0 STV090x_Pn_CFRLOWy(2, 0)
+#define STV090x_P2_CFRLOW1 STV090x_Pn_CFRLOWy(2, 1)
+#define STV090x_OFFST_Px_CFR_LOW_FIELD 0
+#define STV090x_WIDTH_Px_CFR_LOW_FIELD 8
+
+#define STV090x_Pn_CFRINITy(__x, __y) (0xF449 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_CFRINIT0 STV090x_Pn_CFRINITy(1, 0)
+#define STV090x_P1_CFRINIT1 STV090x_Pn_CFRINITy(1, 1)
+#define STV090x_P2_CFRINIT0 STV090x_Pn_CFRINITy(2, 0)
+#define STV090x_P2_CFRINIT1 STV090x_Pn_CFRINITy(2, 1)
+#define STV090x_OFFST_Px_CFR_INIT_FIELD 0
+#define STV090x_WIDTH_Px_CFR_INIT_FIELD 8
+
+#define STV090x_Px_CFRINC1(__x) (0xF44A - (__x - 1) * 0x200)
+#define STV090x_P1_CFRINC1 STV090x_Px_CFRINC1(1)
+#define STV090x_P2_CFRINC1 STV090x_Px_CFRINC1(2)
+#define STV090x_OFFST_Px_CFR_INC1_FIELD 0
+#define STV090x_WIDTH_Px_CFR_INC1_FIELD 7
+
+#define STV090x_Px_CFRINC0(__x) (0xF44B - (__x - 1) * 0x200)
+#define STV090x_P1_CFRINC0 STV090x_Px_CFRINC0(1)
+#define STV090x_P2_CFRINC0 STV090x_Px_CFRINC0(2)
+#define STV090x_OFFST_Px_CFR_INC0_FIELD 4
+#define STV090x_WIDTH_Px_CFR_INC0_FIELD 4
+
+#define STV090x_Pn_CFRy(__x, __y) (0xF44E - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_CFR0 STV090x_Pn_CFRy(1, 0)
+#define STV090x_P1_CFR1 STV090x_Pn_CFRy(1, 1)
+#define STV090x_P1_CFR2 STV090x_Pn_CFRy(1, 2)
+#define STV090x_P2_CFR0 STV090x_Pn_CFRy(2, 0)
+#define STV090x_P2_CFR1 STV090x_Pn_CFRy(2, 1)
+#define STV090x_P2_CFR2 STV090x_Pn_CFRy(2, 2)
+#define STV090x_OFFST_Px_CAR_FREQ_FIELD 0
+#define STV090x_WIDTH_Px_CAR_FREQ_FIELD 8
+
+#define STV090x_Px_LDI(__x) (0xF44F - (__x - 1) * 0x200)
+#define STV090x_P1_LDI STV090x_Px_LDI(1)
+#define STV090x_P2_LDI STV090x_Px_LDI(2)
+#define STV090x_OFFST_Px_LOCK_DET_INTEGR_FIELD 0
+#define STV090x_WIDTH_Px_LOCK_DET_INTEGR_FIELD 8
+
+#define STV090x_Px_TMGCFG(__x) (0xF450 - (__x - 1) * 0x200)
+#define STV090x_P1_TMGCFG STV090x_Px_TMGCFG(1)
+#define STV090x_P2_TMGCFG STV090x_Px_TMGCFG(2)
+#define STV090x_OFFST_Px_TMGLOCK_BETA_FIELD 6
+#define STV090x_WIDTH_Px_TMGLOCK_BETA_FIELD 2
+#define STV090x_OFFST_Px_DO_TIMING_FIELD 4
+#define STV090x_WIDTH_Px_DO_TIMING_FIELD 1
+#define STV090x_OFFST_Px_TMG_MINFREQ_FIELD 0
+#define STV090x_WIDTH_Px_TMG_MINFREQ_FIELD 2
+
+#define STV090x_Px_RTC(__x) (0xF451 - (__x - 1) * 0x200)
+#define STV090x_P1_RTC STV090x_Px_RTC(1)
+#define STV090x_P2_RTC STV090x_Px_RTC(2)
+#define STV090x_OFFST_Px_TMGALPHA_EXP_FIELD 4
+#define STV090x_WIDTH_Px_TMGALPHA_EXP_FIELD 4
+#define STV090x_OFFST_Px_TMGBETA_EXP_FIELD 0
+#define STV090x_WIDTH_Px_TMGBETA_EXP_FIELD 4
+
+#define STV090x_Px_RTCS2(__x) (0xF452 - (__x - 1) * 0x200)
+#define STV090x_P1_RTCS2 STV090x_Px_RTCS2(1)
+#define STV090x_P2_RTCS2 STV090x_Px_RTCS2(2)
+#define STV090x_OFFST_Px_TMGALPHAS2_EXP_FIELD 4
+#define STV090x_WIDTH_Px_TMGALPHAS2_EXP_FIELD 4
+#define STV090x_OFFST_Px_TMGBETAS2_EXP_FIELD 0
+#define STV090x_WIDTH_Px_TMGBETAS2_EXP_FIELD 4
+
+#define STV090x_Px_TMGTHRISE(__x) (0xF453 - (__x - 1) * 0x200)
+#define STV090x_P1_TMGTHRISE STV090x_Px_TMGTHRISE(1)
+#define STV090x_P2_TMGTHRISE STV090x_Px_TMGTHRISE(2)
+#define STV090x_OFFST_Px_TMGLOCK_THRISE_FIELD 0
+#define STV090x_WIDTH_Px_TMGLOCK_THRISE_FIELD 8
+
+#define STV090x_Px_TMGTHFALL(__x) (0xF454 - (__x - 1) * 0x200)
+#define STV090x_P1_TMGTHFALL STV090x_Px_TMGTHFALL(1)
+#define STV090x_P2_TMGTHFALL STV090x_Px_TMGTHFALL(2)
+#define STV090x_OFFST_Px_TMGLOCK_THFALL_FIELD 0
+#define STV090x_WIDTH_Px_TMGLOCK_THFALL_FIELD 8
+
+#define STV090x_Px_SFRUPRATIO(__x) (0xF455 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRUPRATIO STV090x_Px_SFRUPRATIO(1)
+#define STV090x_P2_SFRUPRATIO STV090x_Px_SFRUPRATIO(2)
+#define STV090x_OFFST_Px_SFR_UPRATIO_FIELD 0
+#define STV090x_WIDTH_Px_SFR_UPRATIO_FIELD 8
+
+#define STV090x_Px_SFRLOWRATIO(__x) (0xF456 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRLOWRATIO STV090x_Px_SFRLOWRATIO(1)
+#define STV090x_P2_SFRLOWRATIO STV090x_Px_SFRLOWRATIO(2)
+#define STV090x_OFFST_Px_SFR_LOWRATIO_FIELD 0
+#define STV090x_WIDTH_Px_SFR_LOWRATIO_FIELD 8
+
+#define STV090x_Px_KREFTMG(__x) (0xF458 - (__x - 1) * 0x200)
+#define STV090x_P1_KREFTMG STV090x_Px_KREFTMG(1)
+#define STV090x_P2_KREFTMG STV090x_Px_KREFTMG(2)
+#define STV090x_OFFST_Px_KREF_TMG_FIELD 0
+#define STV090x_WIDTH_Px_KREF_TMG_FIELD 8
+
+#define STV090x_Px_SFRSTEP(__x) (0xF459 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRSTEP STV090x_Px_SFRSTEP(1)
+#define STV090x_P2_SFRSTEP STV090x_Px_SFRSTEP(2)
+#define STV090x_OFFST_Px_SFR_SCANSTEP_FIELD 4
+#define STV090x_WIDTH_Px_SFR_SCANSTEP_FIELD 4
+#define STV090x_OFFST_Px_SFR_CENTERSTEP_FIELD 0
+#define STV090x_WIDTH_Px_SFR_CENTERSTEP_FIELD 4
+
+#define STV090x_Px_TMGCFG2(__x) (0xF45A - (__x - 1) * 0x200)
+#define STV090x_P1_TMGCFG2 STV090x_Px_TMGCFG2(1)
+#define STV090x_P2_TMGCFG2 STV090x_Px_TMGCFG2(2)
+#define STV090x_OFFST_Px_SFRRATIO_FINE_FIELD 0
+#define STV090x_WIDTH_Px_SFRRATIO_FINE_FIELD 1
+
+#define STV090x_Px_SFRINIT1(__x) (0xF45E - (__x - 1) * 0x200)
+#define STV090x_P1_SFRINIT1 STV090x_Px_SFRINIT1(1)
+#define STV090x_P2_SFRINIT1 STV090x_Px_SFRINIT1(2)
+#define STV090x_OFFST_Px_SFR_INIT_FIELD 0
+#define STV090x_WIDTH_Px_SFR_INIT_FIELD 8
+
+#define STV090x_Px_SFRINIT0(__x) (0xF45F - (__x - 1) * 0x200)
+#define STV090x_P1_SFRINIT0 STV090x_Px_SFRINIT0(1)
+#define STV090x_P2_SFRINIT0 STV090x_Px_SFRINIT0(2)
+#define STV090x_OFFST_Px_SFR_INIT_FIELD 0
+#define STV090x_WIDTH_Px_SFR_INIT_FIELD 8
+
+#define STV090x_Px_SFRUP1(__x) (0xF460 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRUP1 STV090x_Px_SFRUP1(1)
+#define STV090x_P2_SFRUP1 STV090x_Px_SFRUP1(2)
+#define STV090x_OFFST_Px_SYMB_FREQ_UP1_FIELD 0
+#define STV090x_WIDTH_Px_SYMB_FREQ_UP1_FIELD 7
+
+#define STV090x_Px_SFRUP0(__x) (0xF461 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRUP0 STV090x_Px_SFRUP0(1)
+#define STV090x_P2_SFRUP0 STV090x_Px_SFRUP0(2)
+#define STV090x_OFFST_Px_SYMB_FREQ_UP0_FIELD 0
+#define STV090x_WIDTH_Px_SYMB_FREQ_UP0_FIELD 8
+
+#define STV090x_Px_SFRLOW1(__x) (0xF462 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRLOW1 STV090x_Px_SFRLOW1(1)
+#define STV090x_P2_SFRLOW1 STV090x_Px_SFRLOW1(2)
+#define STV090x_OFFST_Px_SYMB_FREQ_LOW1_FIELD 0
+#define STV090x_WIDTH_Px_SYMB_FREQ_LOW1_FIELD 7
+
+#define STV090x_Px_SFRLOW0(__x) (0xF463 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRLOW0 STV090x_Px_SFRLOW0(1)
+#define STV090x_P2_SFRLOW0 STV090x_Px_SFRLOW0(2)
+#define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD 0
+#define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD 8
+
+#define STV090x_Px_SFRy(__x, __y) (0xF464 - (__x-1) * 0x200 + (3 - __y))
+#define STV090x_P1_SFR0 STV090x_Px_SFRy(1, 0)
+#define STV090x_P1_SFR1 STV090x_Px_SFRy(1, 1)
+#define STV090x_P1_SFR2 STV090x_Px_SFRy(1, 2)
+#define STV090x_P1_SFR3 STV090x_Px_SFRy(1, 3)
+#define STV090x_P2_SFR0 STV090x_Px_SFRy(2, 0)
+#define STV090x_P2_SFR1 STV090x_Px_SFRy(2, 1)
+#define STV090x_P2_SFR2 STV090x_Px_SFRy(2, 2)
+#define STV090x_P2_SFR3 STV090x_Px_SFRy(2, 3)
+#define STV090x_OFFST_Px_SYMB_FREQ_FIELD 0
+#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD 32
+
+#define STV090x_Px_TMGREG2(__x) (0xF468 - (__x - 1) * 0x200)
+#define STV090x_P1_TMGREG2 STV090x_Px_TMGREG2(1)
+#define STV090x_P2_TMGREG2 STV090x_Px_TMGREG2(2)
+#define STV090x_OFFST_Px_TMGREG_FIELD 0
+#define STV090x_WIDTH_Px_TMGREG_FIELD 8
+
+#define STV090x_Px_TMGREG1(__x) (0xF469 - (__x - 1) * 0x200)
+#define STV090x_P1_TMGREG1 STV090x_Px_TMGREG1(1)
+#define STV090x_P2_TMGREG1 STV090x_Px_TMGREG1(2)
+#define STV090x_OFFST_Px_TMGREG_FIELD 0
+#define STV090x_WIDTH_Px_TMGREG_FIELD 8
+
+#define STV090x_Px_TMGREG0(__x) (0xF46A - (__x - 1) * 0x200)
+#define STV090x_P1_TMGREG0 STV090x_Px_TMGREG0(1)
+#define STV090x_P2_TMGREG0 STV090x_Px_TMGREG0(2)
+#define STV090x_OFFST_Px_TMGREG_FIELD 0
+#define STV090x_WIDTH_Px_TMGREG_FIELD 8
+
+#define STV090x_Px_TMGLOCKy(__x, __y) (0xF46C - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_TMGLOCK0 STV090x_Px_TMGLOCKy(1, 0)
+#define STV090x_P1_TMGLOCK1 STV090x_Px_TMGLOCKy(1, 1)
+#define STV090x_P2_TMGLOCK0 STV090x_Px_TMGLOCKy(2, 0)
+#define STV090x_P2_TMGLOCK1 STV090x_Px_TMGLOCKy(2, 1)
+#define STV090x_OFFST_Px_TMGLOCK_LEVEL_FIELD 0
+#define STV090x_WIDTH_Px_TMGLOCK_LEVEL_FIELD 8
+
+#define STV090x_Px_TMGOBS(__x) (0xF46D - (__x - 1) * 0x200)
+#define STV090x_P1_TMGOBS STV090x_Px_TMGOBS(1)
+#define STV090x_P2_TMGOBS STV090x_Px_TMGOBS(2)
+#define STV090x_OFFST_Px_ROLLOFF_STATUS_FIELD 6
+#define STV090x_WIDTH_Px_ROLLOFF_STATUS_FIELD 2
+
+#define STV090x_Px_EQUALCFG(__x) (0xF46F - (__x - 1) * 0x200)
+#define STV090x_P1_EQUALCFG STV090x_Px_EQUALCFG(1)
+#define STV090x_P2_EQUALCFG STV090x_Px_EQUALCFG(2)
+#define STV090x_OFFST_Px_EQUAL_ON_FIELD 6
+#define STV090x_WIDTH_Px_EQUAL_ON_FIELD 1
+#define STV090x_OFFST_Px_MU_EQUALDFE_FIELD 0
+#define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD 3
+
+#define STV090x_Px_EQUAIy(__x, __y) (0xf470 - (__x - 1) * 0x200 + (__y - 1))
+#define STV090x_P1_EQUAI1 STV090x_Px_EQUAIy(1, 1)
+#define STV090x_P1_EQUAI2 STV090x_Px_EQUAIy(1, 2)
+#define STV090x_P1_EQUAI3 STV090x_Px_EQUAIy(1, 3)
+#define STV090x_P1_EQUAI4 STV090x_Px_EQUAIy(1, 4)
+#define STV090x_P1_EQUAI5 STV090x_Px_EQUAIy(1, 5)
+#define STV090x_P1_EQUAI6 STV090x_Px_EQUAIy(1, 6)
+#define STV090x_P1_EQUAI7 STV090x_Px_EQUAIy(1, 7)
+#define STV090x_P1_EQUAI8 STV090x_Px_EQUAIy(1, 8)
+
+#define STV090x_P2_EQUAI1 STV090x_Px_EQUAIy(2, 1)
+#define STV090x_P2_EQUAI2 STV090x_Px_EQUAIy(2, 2)
+#define STV090x_P2_EQUAI3 STV090x_Px_EQUAIy(2, 3)
+#define STV090x_P2_EQUAI4 STV090x_Px_EQUAIy(2, 4)
+#define STV090x_P2_EQUAI5 STV090x_Px_EQUAIy(2, 5)
+#define STV090x_P2_EQUAI6 STV090x_Px_EQUAIy(2, 6)
+#define STV090x_P2_EQUAI7 STV090x_Px_EQUAIy(2, 7)
+#define STV090x_P2_EQUAI8 STV090x_Px_EQUAIy(2, 8)
+#define STV090x_OFFST_Px_EQUA_ACCIy_FIELD 0
+#define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD 8
+
+#define STV090x_Px_EQUAQy(__x, __y) (0xf471 - (__x - 1) * 0x200 + (__y - 1))
+#define STV090x_P1_EQUAQ1 STV090x_Px_EQUAQy(1, 1)
+#define STV090x_P1_EQUAQ2 STV090x_Px_EQUAQy(1, 2)
+#define STV090x_P1_EQUAQ3 STV090x_Px_EQUAQy(1, 3)
+#define STV090x_P1_EQUAQ4 STV090x_Px_EQUAQy(1, 4)
+#define STV090x_P1_EQUAQ5 STV090x_Px_EQUAQy(1, 5)
+#define STV090x_P1_EQUAQ6 STV090x_Px_EQUAQy(1, 6)
+#define STV090x_P1_EQUAQ7 STV090x_Px_EQUAQy(1, 7)
+#define STV090x_P1_EQUAQ8 STV090x_Px_EQUAQy(1, 8)
+
+#define STV090x_P2_EQUAQ1 STV090x_Px_EQUAQy(2, 1)
+#define STV090x_P2_EQUAQ2 STV090x_Px_EQUAQy(2, 2)
+#define STV090x_P2_EQUAQ3 STV090x_Px_EQUAQy(2, 3)
+#define STV090x_P2_EQUAQ4 STV090x_Px_EQUAQy(2, 4)
+#define STV090x_P2_EQUAQ5 STV090x_Px_EQUAQy(2, 5)
+#define STV090x_P2_EQUAQ6 STV090x_Px_EQUAQy(2, 6)
+#define STV090x_P2_EQUAQ7 STV090x_Px_EQUAQy(2, 7)
+#define STV090x_P2_EQUAQ8 STV090x_Px_EQUAQy(2, 8)
+#define STV090x_OFFST_Px_EQUA_ACCQy_FIELD 0
+#define STV090x_WIDTH_Px_EQUA_ACCQy_FIELD 8
+
+#define STV090x_Px_NNOSDATATy(__x, __y) (0xf481 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NNOSDATAT0 STV090x_Px_NNOSDATATy(1, 0)
+#define STV090x_P1_NNOSDATAT1 STV090x_Px_NNOSDATATy(1, 1)
+#define STV090x_P2_NNOSDATAT0 STV090x_Px_NNOSDATATy(2, 0)
+#define STV090x_P2_NNOSDATAT1 STV090x_Px_NNOSDATATy(2, 1)
+#define STV090x_OFFST_Px_NOSDATAT_NORMED_FIELD 0
+#define STV090x_WIDTH_Px_NOSDATAT_NORMED_FIELD 8
+
+#define STV090x_Px_NNOSDATAy(__x, __y) (0xf483 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NNOSDATA0 STV090x_Px_NNOSDATAy(1, 0)
+#define STV090x_P1_NNOSDATA1 STV090x_Px_NNOSDATAy(1, 1)
+#define STV090x_P2_NNOSDATA0 STV090x_Px_NNOSDATAy(2, 0)
+#define STV090x_P2_NNOSDATA1 STV090x_Px_NNOSDATAy(2, 1)
+#define STV090x_OFFST_Px_NOSDATA_NORMED_FIELD 0
+#define STV090x_WIDTH_Px_NOSDATA_NORMED_FIELD 8
+
+#define STV090x_Px_NNOSPLHTy(__x, __y) (0xf485 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NNOSPLHT0 STV090x_Px_NNOSPLHTy(1, 0)
+#define STV090x_P1_NNOSPLHT1 STV090x_Px_NNOSPLHTy(1, 1)
+#define STV090x_P2_NNOSPLHT0 STV090x_Px_NNOSPLHTy(2, 0)
+#define STV090x_P2_NNOSPLHT1 STV090x_Px_NNOSPLHTy(2, 1)
+#define STV090x_OFFST_Px_NOSPLHT_NORMED_FIELD 0
+#define STV090x_WIDTH_Px_NOSPLHT_NORMED_FIELD 8
+
+#define STV090x_Px_NNOSPLHy(__x, __y) (0xf487 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NNOSPLH0 STV090x_Px_NNOSPLHy(1, 0)
+#define STV090x_P1_NNOSPLH1 STV090x_Px_NNOSPLHy(1, 1)
+#define STV090x_P2_NNOSPLH0 STV090x_Px_NNOSPLHy(2, 0)
+#define STV090x_P2_NNOSPLH1 STV090x_Px_NNOSPLHy(2, 1)
+#define STV090x_OFFST_Px_NOSPLH_NORMED_FIELD 0
+#define STV090x_WIDTH_Px_NOSPLH_NORMED_FIELD 8
+
+#define STV090x_Px_NOSDATATy(__x, __y) (0xf489 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NOSDATAT0 STV090x_Px_NOSDATATy(1, 0)
+#define STV090x_P1_NOSDATAT1 STV090x_Px_NOSDATATy(1, 1)
+#define STV090x_P2_NOSDATAT0 STV090x_Px_NOSDATATy(2, 0)
+#define STV090x_P2_NOSDATAT1 STV090x_Px_NOSDATATy(2, 1)
+#define STV090x_OFFST_Px_NOSDATAT_UNNORMED_FIELD 0
+#define STV090x_WIDTH_Px_NOSDATAT_UNNORMED_FIELD 8
+
+#define STV090x_Px_NOSDATAy(__x, __y) (0xf48b - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NOSDATA0 STV090x_Px_NOSDATAy(1, 0)
+#define STV090x_P1_NOSDATA1 STV090x_Px_NOSDATAy(1, 1)
+#define STV090x_P2_NOSDATA0 STV090x_Px_NOSDATAy(2, 0)
+#define STV090x_P2_NOSDATA1 STV090x_Px_NOSDATAy(2, 1)
+#define STV090x_OFFST_Px_NOSDATA_UNNORMED_FIELD 0
+#define STV090x_WIDTH_Px_NOSDATA_UNNORMED_FIELD 8
+
+#define STV090x_Px_NOSPLHTy(__x, __y) (0xf48d - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NOSPLHT0 STV090x_Px_NOSPLHTy(1, 0)
+#define STV090x_P1_NOSPLHT1 STV090x_Px_NOSPLHTy(1, 1)
+#define STV090x_P2_NOSPLHT0 STV090x_Px_NOSPLHTy(2, 0)
+#define STV090x_P2_NOSPLHT1 STV090x_Px_NOSPLHTy(2, 1)
+#define STV090x_OFFST_Px_NOSPLHT_UNNORMED_FIELD 0
+#define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD 8
+
+#define STV090x_Px_NOSPLHy(__x, __y) (0xf48f - (__x - 1) * 0x200 - __y * 0x1)
+#define STv090x_P1_NOSPLH0 STV090x_Px_NOSPLHy(1, 0)
+#define STv090x_P1_NOSPLH1 STV090x_Px_NOSPLHy(1, 1)
+#define STv090x_P2_NOSPLH0 STV090x_Px_NOSPLHy(2, 0)
+#define STv090x_P2_NOSPLH1 STV090x_Px_NOSPLHy(2, 1)
+#define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0
+#define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8
+
+#define STV090x_Px_CAR2CFG(__x) (0xf490 - (__x - 1) * 0x200)
+#define STV090x_P1_CAR2CFG STV090x_Px_CAR2CFG(1)
+#define STV090x_P2_CAR2CFG STV090x_Px_CAR2CFG(2)
+#define STV090x_OFFST_Px_PN4_SELECT_FIELD 6
+#define STV090x_WIDTH_Px_PN4_SELECT_FIELD 1
+#define STV090x_OFFST_Px_CFR2_STOPDVBS1_FIELD 5
+#define STV090x_WIDTH_Px_CFR2_STOPDVBS1_FIELD 1
+#define STV090x_OFFST_Px_ROTA2ON_FIELD 2
+#define STV090x_WIDTH_Px_ROTA2ON_FIELD 1
+#define STV090x_OFFST_Px_PH_DET_ALGO2_FIELD 0
+#define STV090x_WIDTH_Px_PH_DET_ALGO2_FIELD 2
+
+#define STV090x_Px_ACLC2(__x) (0xf491 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC2 STV090x_Px_ACLC2(1)
+#define STV090x_P2_ACLC2 STV090x_Px_ACLC2(2)
+#define STV090x_OFFST_Px_CAR2_ALPHA_MANT_FIELD 4
+#define STV090x_WIDTH_Px_CAR2_ALPHA_MANT_FIELD 2
+#define STV090x_OFFST_Px_CAR2_ALPHA_EXP_FIELD 0
+#define STV090x_WIDTH_Px_CAR2_ALPHA_EXP_FIELD 4
+
+#define STV090x_Px_BCLC2(__x) (0xf492 - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC2 STV090x_Px_BCLC2(1)
+#define STV090x_P2_BCLC2 STV090x_Px_BCLC2(2)
+#define STV090x_OFFST_Px_CAR2_BETA_MANT_FIELD 4
+#define STV090x_WIDTH_Px_CAR2_BETA_MANT_FIELD 2
+#define STV090x_OFFST_Px_CAR2_BETA_EXP_FIELD 0
+#define STV090x_WIDTH_Px_CAR2_BETA_EXP_FIELD 4
+
+#define STV090x_Px_ACLC2S2Q(__x) (0xf497 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC2S2Q STV090x_Px_ACLC2S2Q(1)
+#define STV090x_P2_ACLC2S2Q STV090x_Px_ACLC2S2Q(2)
+#define STV090x_OFFST_Px_ENAB_SPSKSYMB_FIELD 7
+#define STV090x_WIDTH_Px_ENAB_SPSKSYMB_FIELD 1
+#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_E_FIELD 4
+
+#define STV090x_Px_ACLC2S28(__x) (0xf498 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC2S28 STV090x_Px_ACLC2S28(1)
+#define STV090x_P2_ACLC2S28 STV090x_Px_ACLC2S28(2)
+#define STV090x_OFFST_Px_CAR2S2_8_ALPH_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_8_ALPH_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_E_FIELD 4
+
+#define STV090x_Px_ACLC2S216A(__x) (0xf499 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC2S216A STV090x_Px_ACLC2S216A(1)
+#define STV090x_P2_ACLC2S216A STV090x_Px_ACLC2S216A(2)
+#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD 4
+
+#define STV090x_Px_ACLC2S232A(__x) (0xf499 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC2S232A STV090x_Px_ACLC2S232A(1)
+#define STV090x_P2_ACLC2S232A STV090x_Px_ACLC2S232A(2)
+#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_E_FIELD 4
+
+#define STV090x_Px_BCLC2S2Q(__x) (0xf49c - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC2S2Q STV090x_Px_BCLC2S2Q(1)
+#define STV090x_P2_BCLC2S2Q STV090x_Px_BCLC2S2Q(2)
+#define STV090x_OFFST_Px_CAR2S2_Q_BETA_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_Q_BETA_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_E_FIELD 4
+
+#define STV090x_Px_BCLC2S28(__x) (0xf49d - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC2S28 STV090x_Px_BCLC2S28(1)
+#define STV090x_P2_BCLC2S28 STV090x_Px_BCLC2S28(1)
+#define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD 4
+
+#define STV090x_Px_BCLC2S216A(__x) (0xf49d - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1)
+#define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(1)
+#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD 4
+
+#define STV090x_Px_BCLC2S232A(__x) (0xf49d - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1)
+#define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(1)
+#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_E_FIELD 4
+
+#define STV090x_Px_PLROOT2(__x) (0xf4ac - (__x - 1) * 0x200)
+#define STV090x_P1_PLROOT2 STV090x_Px_PLROOT2(1)
+#define STV090x_P2_PLROOT2 STV090x_Px_PLROOT2(2)
+#define STV090x_OFFST_Px_PLSCRAMB_MODE_FIELD 2
+#define STV090x_WIDTH_Px_PLSCRAMB_MODE_FIELD 2
+#define STV090x_OFFST_Px_PLSCRAMB_ROOT_FIELD 0
+#define STV090x_WIDTH_Px_PLSCRAMB_ROOT_FIELD 2
+
+#define STV090x_Px_PLROOT1(__x) (0xf4ad - (__x - 1) * 0x200)
+#define STV090x_P1_PLROOT1 STV090x_Px_PLROOT1(1)
+#define STV090x_P2_PLROOT1 STV090x_Px_PLROOT1(2)
+#define STV090x_OFFST_Px_PLSCRAMB_ROOT1_FIELD 0
+#define STV090x_WIDTH_Px_PLSCRAMB_ROOT1_FIELD 8
+
+#define STV090x_Px_PLROOT0(__x) (0xf4ae - (__x - 1) * 0x200)
+#define STV090x_P1_PLROOT0 STV090x_Px_PLROOT0(1)
+#define STV090x_P2_PLROOT0 STV090x_Px_PLROOT0(2)
+#define STV090x_OFFST_Px_PLSCRAMB_ROOT0_FIELD 0
+#define STV090x_WIDTH_Px_PLSCRAMB_ROOT0_FIELD 8
+
+#define STV090x_Px_MODCODLST0(__x) (0xf4b0 - (__x - 1) * 0x200) /* check */
+#define STV090x_P1_MODCODLST0 STV090x_Px_MODCODLST0(1)
+#define STV090x_P2_MODCODLST0 STV090x_Px_MODCODLST0(2)
+
+#define STV090x_Px_MODCODLST1(__x) (0xf4b1 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST1 STV090x_Px_MODCODLST1(1)
+#define STV090x_P2_MODCODLST1 STV090x_Px_MODCODLST1(2)
+#define STV090x_OFFST_Px_DIS_MODCOD29_FIELD 4
+#define STV090x_WIDTH_Px_DIS_MODCOD29T_FIELD 4
+#define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD 0
+#define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD 4
+
+#define STV090x_Px_MODCODLST2(__x) (0xf4b2 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST2 STV090x_Px_MODCODLST2(1)
+#define STV090x_P2_MODCODLST2 STV090x_Px_MODCODLST2(2)
+#define STV090x_OFFST_Px_DIS_32PSK_8_9_FIELD 4
+#define STV090x_WIDTH_Px_DIS_32PSK_8_9_FIELD 4
+#define STV090x_OFFST_Px_DIS_32PSK_5_6_FIELD 0
+#define STV090x_WIDTH_Px_DIS_32PSK_5_6_FIELD 4
+
+#define STV090x_Px_MODCODLST3(__x) (0xf4b3 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST3 STV090x_Px_MODCODLST3(1)
+#define STV090x_P2_MODCODLST3 STV090x_Px_MODCODLST3(2)
+#define STV090x_OFFST_Px_DIS_32PSK_4_5_FIELD 4
+#define STV090x_WIDTH_Px_DIS_32PSK_4_5_FIELD 4
+#define STV090x_OFFST_Px_DIS_32PSK_3_4_FIELD 0
+#define STV090x_WIDTH_Px_DIS_32PSK_3_4_FIELD 4
+
+#define STV090x_Px_MODCODLST4(__x) (0xf4b4 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST4 STV090x_Px_MODCODLST4(1)
+#define STV090x_P2_MODCODLST4 STV090x_Px_MODCODLST4(2)
+#define STV090x_OFFST_Px_DIS_16PSK_9_10_FIELD 4
+#define STV090x_WIDTH_Px_DIS_16PSK_9_10_FIELD 4
+#define STV090x_OFFST_Px_DIS_16PSK_8_9_FIELD 0
+#define STV090x_WIDTH_Px_DIS_16PSK_8_9_FIELD 4
+
+#define STV090x_Px_MODCODLST5(__x) (0xf4b5 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST5 STV090x_Px_MODCODLST5(1)
+#define STV090x_P2_MODCODLST5 STV090x_Px_MODCODLST5(2)
+#define STV090x_OFFST_Px_DIS_16PSK_5_6_FIELD 4
+#define STV090x_WIDTH_Px_DIS_16PSK_5_6_FIELD 4
+#define STV090x_OFFST_Px_DIS_16PSK_4_5_FIELD 0
+#define STV090x_WIDTH_Px_DIS_16PSK_4_5_FIELD 4
+
+#define STV090x_Px_MODCODLST6(__x) (0xf4b6 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST6 STV090x_Px_MODCODLST6(1)
+#define STV090x_P2_MODCODLST6 STV090x_Px_MODCODLST6(2)
+#define STV090x_OFFST_Px_DIS_16PSK_3_4_FIELD 4
+#define STV090x_WIDTH_Px_DIS_16PSK_3_4_FIELD 4
+#define STV090x_OFFST_Px_DIS_16PSK_2_3_FIELD 0
+#define STV090x_WIDTH_Px_DIS_16PSK_2_3_FIELD 4
+
+#define STV090x_Px_MODCODLST7(__x) (0xf4b7 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST7 STV090x_Px_MODCODLST7(1)
+#define STV090x_P2_MODCODLST7 STV090x_Px_MODCODLST7(2)
+#define STV090x_OFFST_Px_DIS_8P_9_10_FIELD 4
+#define STV090x_WIDTH_Px_DIS_8P_9_10_FIELD 4
+#define STV090x_OFFST_Px_DIS_8P_8_9_FIELD 0
+#define STV090x_WIDTH_Px_DIS_8P_8_9_FIELD 4
+
+#define STV090x_Px_MODCODLST8(__x) (0xf4b8 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST8 STV090x_Px_MODCODLST8(1)
+#define STV090x_P2_MODCODLST8 STV090x_Px_MODCODLST8(2)
+#define STV090x_OFFST_Px_DIS_8P_5_6_FIELD 4
+#define STV090x_WIDTH_Px_DIS_8P_5_6_FIELD 4
+#define STV090x_OFFST_Px_DIS_8P_3_4_FIELD 0
+#define STV090x_WIDTH_Px_DIS_8P_3_4_FIELD 4
+
+#define STV090x_Px_MODCODLST9(__x) (0xf4b9 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST9 STV090x_Px_MODCODLST9(1)
+#define STV090x_P2_MODCODLST9 STV090x_Px_MODCODLST9(2)
+#define STV090x_OFFST_Px_DIS_8P_2_3_FIELD 4
+#define STV090x_WIDTH_Px_DIS_8P_2_3_FIELD 4
+#define STV090x_OFFST_Px_DIS_8P_3_5_FIELD 0
+#define STV090x_WIDTH_Px_DIS_8P_3_5_FIELD 4
+
+#define STV090x_Px_MODCODLSTA(__x) (0xf4ba - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTA STV090x_Px_MODCODLSTA(1)
+#define STV090x_P2_MODCODLSTA STV090x_Px_MODCODLSTA(2)
+#define STV090x_OFFST_Px_DIS_QP_9_10_FIELD 4
+#define STV090x_WIDTH_Px_DIS_QP_9_10_FIELD 4
+#define STV090x_OFFST_Px_DIS_QP_8_9_FIELD 0
+#define STV090x_WIDTH_Px_DIS_QP_8_9_FIELD 4
+
+#define STV090x_Px_MODCODLSTB(__x) (0xf4bb - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTB STV090x_Px_MODCODLSTB(1)
+#define STV090x_P2_MODCODLSTB STV090x_Px_MODCODLSTB(2)
+#define STV090x_OFFST_Px_DIS_QP_5_6_FIELD 4
+#define STV090x_WIDTH_Px_DIS_QP_5_6_FIELD 4
+#define STV090x_OFFST_Px_DIS_QP_4_5_FIELD 0
+#define STV090x_WIDTH_Px_DIS_QP_4_5_FIELD 4
+
+#define STV090x_Px_MODCODLSTC(__x) (0xf4bc - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTC STV090x_Px_MODCODLSTC(1)
+#define STV090x_P2_MODCODLSTC STV090x_Px_MODCODLSTC(2)
+#define STV090x_OFFST_Px_DIS_QP_3_4_FIELD 4
+#define STV090x_WIDTH_Px_DIS_QP_3_4_FIELD 4
+#define STV090x_OFFST_Px_DIS_QP_2_3_FIELD 0
+#define STV090x_WIDTH_Px_DIS_QP_2_3_FIELD 4
+
+#define STV090x_Px_MODCODLSTD(__x) (0xf4bd - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTD STV090x_Px_MODCODLSTD(1)
+#define STV090x_P2_MODCODLSTD STV090x_Px_MODCODLSTD(2)
+#define STV090x_OFFST_Px_DIS_QP_3_5_FIELD 4
+#define STV090x_WIDTH_Px_DIS_QP_3_5_FIELD 4
+#define STV090x_OFFST_Px_DIS_QP_1_2_FIELD 0
+#define STV090x_WIDTH_Px_DIS_QP_1_2_FIELD 4
+
+#define STV090x_Px_MODCODLSTE(__x) (0xf4be - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTE STV090x_Px_MODCODLSTE(1)
+#define STV090x_P2_MODCODLSTE STV090x_Px_MODCODLSTE(2)
+#define STV090x_OFFST_Px_DIS_QP_2_5_FIELD 4
+#define STV090x_WIDTH_Px_DIS_QP_2_5_FIELD 4
+#define STV090x_OFFST_Px_DIS_QP_1_3_FIELD 0
+#define STV090x_WIDTH_Px_DIS_QP_1_3_FIELD 4
+
+#define STV090x_Px_MODCODLSTF(__x) (0xf4bf - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTF STV090x_Px_MODCODLSTF(1)
+#define STV090x_P2_MODCODLSTF STV090x_Px_MODCODLSTF(2)
+#define STV090x_OFFST_Px_DIS_QP_1_4_FIELD 4
+#define STV090x_WIDTH_Px_DIS_QP_1_4_FIELD 4
+
+#define STV090x_Px_GAUSSR0(__x) (0xf4c0 - (__x - 1) * 0x200)
+#define STV090x_P1_GAUSSR0 STV090x_Px_GAUSSR0(1)
+#define STV090x_P2_GAUSSR0 STV090x_Px_GAUSSR0(2)
+#define STV090x_OFFST_Px_EN_CCIMODE_FIELD 7
+#define STV090x_WIDTH_Px_EN_CCIMODE_FIELD 1
+#define STV090x_OFFST_Px_R0_GAUSSIEN_FIELD 0
+#define STV090x_WIDTH_Px_R0_GAUSSIEN_FIELD 7
+
+#define STV090x_Px_CCIR0(__x) (0xf4c1 - (__x - 1) * 0x200)
+#define STV090x_P1_CCIR0 STV090x_Px_CCIR0(1)
+#define STV090x_P2_CCIR0 STV090x_Px_CCIR0(2)
+#define STV090x_OFFST_Px_CCIDETECT_PLH_FIELD 7
+#define STV090x_WIDTH_Px_CCIDETECT_PLH_FIELD 1
+#define STV090x_OFFST_Px_R0_CCI_FIELD 0
+#define STV090x_WIDTH_Px_R0_CCI_FIELD 7
+
+#define STV090x_Px_CCIQUANT(__x) (0xf4c2 - (__x - 1) * 0x200)
+#define STV090x_P1_CCIQUANT STV090x_Px_CCIQUANT(1)
+#define STV090x_P2_CCIQUANT STV090x_Px_CCIQUANT(2)
+#define STV090x_OFFST_Px_CCI_BETA_FIELD 5
+#define STV090x_WIDTH_Px_CCI_BETA_FIELD 3
+#define STV090x_OFFST_Px_CCI_QUANT_FIELD 0
+#define STV090x_WIDTH_Px_CCI_QUANT_FIELD 5
+
+#define STV090x_Px_CCITHRESH(__x) (0xf4c3 - (__x - 1) * 0x200)
+#define STV090x_P1_CCITHRESH STV090x_Px_CCITHRESH(1)
+#define STV090x_P2_CCITHRESH STV090x_Px_CCITHRESH(2)
+#define STV090x_OFFST_Px_CCI_THRESHOLD_FIELD 0
+#define STV090x_WIDTH_Px_CCI_THRESHOLD_FIELD 8
+
+#define STV090x_Px_CCIACC(__x) (0xf4c4 - (__x - 1) * 0x200)
+#define STV090x_P1_CCIACC STV090x_Px_CCIACC(1)
+#define STV090x_P2_CCIACC STV090x_Px_CCIACC(1)
+#define STV090x_OFFST_Px_CCI_VALUE_FIELD 0
+#define STV090x_WIDTH_Px_CCI_VALUE_FIELD 8
+
+#define STV090x_Px_DMDRESCFG(__x) (0xF4C6 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDRESCFG STV090x_Px_DMDRESCFG(1)
+#define STV090x_P2_DMDRESCFG STV090x_Px_DMDRESCFG(2)
+#define STV090x_OFFST_Px_DMDRES_RESET_FIELD 7
+#define STV090x_WIDTH_Px_DMDRES_RESET_FIELD 1
+
+#define STV090x_Px_DMDRESADR(__x) (0xF4C7 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDRESADR STV090x_Px_DMDRESADR(1)
+#define STV090x_P2_DMDRESADR STV090x_Px_DMDRESADR(2)
+#define STV090x_OFFST_Px_DMDRES_RESNBR_FIELD 0
+#define STV090x_WIDTH_Px_DMDRES_RESNBR_FIELD 4
+
+#define STV090x_Px_DMDRESDATAy(__x, __y) (0xF4C8 - (__x - 1) * 0x200 + (7 - __y))
+#define STV090x_P1_DMDRESDATA0 STV090x_Px_DMDRESDATAy(1, 0)
+#define STV090x_P1_DMDRESDATA1 STV090x_Px_DMDRESDATAy(1, 1)
+#define STV090x_P1_DMDRESDATA2 STV090x_Px_DMDRESDATAy(1, 2)
+#define STV090x_P1_DMDRESDATA3 STV090x_Px_DMDRESDATAy(1, 3)
+#define STV090x_P1_DMDRESDATA4 STV090x_Px_DMDRESDATAy(1, 4)
+#define STV090x_P1_DMDRESDATA5 STV090x_Px_DMDRESDATAy(1, 5)
+#define STV090x_P1_DMDRESDATA6 STV090x_Px_DMDRESDATAy(1, 6)
+#define STV090x_P1_DMDRESDATA7 STV090x_Px_DMDRESDATAy(1, 7)
+#define STV090x_P2_DMDRESDATA0 STV090x_Px_DMDRESDATAy(2, 0)
+#define STV090x_P2_DMDRESDATA1 STV090x_Px_DMDRESDATAy(2, 1)
+#define STV090x_P2_DMDRESDATA2 STV090x_Px_DMDRESDATAy(2, 2)
+#define STV090x_P2_DMDRESDATA3 STV090x_Px_DMDRESDATAy(2, 3)
+#define STV090x_P2_DMDRESDATA4 STV090x_Px_DMDRESDATAy(2, 4)
+#define STV090x_P2_DMDRESDATA5 STV090x_Px_DMDRESDATAy(2, 5)
+#define STV090x_P2_DMDRESDATA6 STV090x_Px_DMDRESDATAy(2, 6)
+#define STV090x_P2_DMDRESDATA7 STV090x_Px_DMDRESDATAy(2, 7)
+#define STV090x_OFFST_Px_DMDRES_DATA_FIELD 0
+#define STV090x_WIDTH_Px_DMDRES_DATA_FIELD 8
+
+#define STV090x_Px_FFEIy(__x, __y) (0xf4d0 - (__x - 1) * 0x200 + 0x2 * (__y - 1))
+#define STV090x_P1_FFEI1 STV090x_Px_FFEIy(1, 1)
+#define STV090x_P1_FFEI2 STV090x_Px_FFEIy(1, 2)
+#define STV090x_P1_FFEI3 STV090x_Px_FFEIy(1, 3)
+#define STV090x_P1_FFEI4 STV090x_Px_FFEIy(1, 4)
+#define STV090x_P2_FFEI1 STV090x_Px_FFEIy(2, 1)
+#define STV090x_P2_FFEI2 STV090x_Px_FFEIy(2, 2)
+#define STV090x_P2_FFEI3 STV090x_Px_FFEIy(2, 3)
+#define STV090x_P2_FFEI4 STV090x_Px_FFEIy(2, 4)
+#define STV090x_OFFST_Px_FFE_ACCIy_FIELD 0
+#define STV090x_WIDTH_Px_FFE_ACCIy_FIELD 8
+
+#define STV090x_Px_FFEQy(__x, __y) (0xf4d1 - (__x - 1) * 0x200 + 0x2 * (__y - 1))
+#define STV090x_P1_FFEQ1 STV090x_Px_FFEQy(1, 1)
+#define STV090x_P1_FFEQ2 STV090x_Px_FFEQy(1, 2)
+#define STV090x_P1_FFEQ3 STV090x_Px_FFEQy(1, 3)
+#define STV090x_P1_FFEQ4 STV090x_Px_FFEQy(1, 4)
+#define STV090x_P2_FFEQ1 STV090x_Px_FFEQy(2, 1)
+#define STV090x_P2_FFEQ2 STV090x_Px_FFEQy(2, 2)
+#define STV090x_P2_FFEQ3 STV090x_Px_FFEQy(2, 3)
+#define STV090x_P2_FFEQ4 STV090x_Px_FFEQy(2, 4)
+#define STV090x_OFFST_Px_FFE_ACCQy_FIELD 0
+#define STV090x_WIDTH_Px_FFE_ACCQy_FIELD 8
+
+#define STV090x_Px_FFECFG(__x) (0xf4d8 - (__x - 1) * 0x200)
+#define STV090x_P1_FFECFG STV090x_Px_FFECFG(1)
+#define STV090x_P2_FFECFG STV090x_Px_FFECFG(2)
+#define STV090x_OFFST_Px_EQUALFFE_ON_FIELD 6
+#define STV090x_WIDTH_Px_EQUALFFE_ON_FIELD 1
+
+#define STV090x_Px_SMAPCOEF7(__x) (0xf500 - (__x - 1) * 0x200)
+#define STV090x_P1_SMAPCOEF7 STV090x_Px_SMAPCOEF7(1)
+#define STV090x_P2_SMAPCOEF7 STV090x_Px_SMAPCOEF7(2)
+#define STV090x_OFFST_Px_DIS_QSCALE_FIELD 7
+#define STV090x_WIDTH_Px_DIS_QSCALE_FIELD 1
+#define STV090x_OFFST_Px_SMAPCOEF_Q_LLR12_FIELD 0
+#define STV090x_WIDTH_Px_SMAPCOEF_Q_LLR12_FIELD 7
+
+#define STV090x_Px_SMAPCOEF6(__x) (0xf501 - (__x - 1) * 0x200)
+#define STV090x_P1_SMAPCOEF6 STV090x_Px_SMAPCOEF6(1)
+#define STV090x_P2_SMAPCOEF6 STV090x_Px_SMAPCOEF6(2)
+#define STV090x_OFFST_Px_ADJ_8PSKLLR1_FIELD 2
+#define STV090x_WIDTH_Px_ADJ_8PSKLLR1_FIELD 1
+#define STV090x_OFFST_Px_OLD_8PSKLLR1_FIELD 1
+#define STV090x_WIDTH_Px_OLD_8PSKLLR1_FIELD 1
+#define STV090x_OFFST_Px_DIS_AB8PSK_FIELD 0
+#define STV090x_WIDTH_Px_DIS_AB8PSK_FIELD 1
+
+#define STV090x_Px_SMAPCOEF5(__x) (0xf502 - (__x - 1) * 0x200)
+#define STV090x_P1_SMAPCOEF5 STV090x_Px_SMAPCOEF5(1)
+#define STV090x_P2_SMAPCOEF5 STV090x_Px_SMAPCOEF5(2)
+#define STV090x_OFFST_Px_DIS_8SCALE_FIELD 7
+#define STV090x_WIDTH_Px_DIS_8SCALE_FIELD 1
+#define STV090x_OFFST_Px_SMAPCOEF_8P_LLR23_FIELD 0
+#define STV090x_WIDTH_Px_SMAPCOEF_8P_LLR23_FIELD 7
+
+#define STV090x_Px_DMDPLHSTAT(__x) (0xF520 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(1)
+#define STV090x_P2_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(2)
+#define STV090x_OFFST_Px_PLH_STATISTIC_FIELD 0
+#define STV090x_WIDTH_Px_PLH_STATISTIC_FIELD 8
+
+#define STV090x_Px_LOCKTIMEy(__x, __y) (0xF525 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_LOCKTIME0 STV090x_Px_LOCKTIMEy(1, 0)
+#define STV090x_P1_LOCKTIME1 STV090x_Px_LOCKTIMEy(1, 1)
+#define STV090x_P1_LOCKTIME2 STV090x_Px_LOCKTIMEy(1, 2)
+#define STV090x_P1_LOCKTIME3 STV090x_Px_LOCKTIMEy(1, 3)
+#define STV090x_P2_LOCKTIME0 STV090x_Px_LOCKTIMEy(2, 0)
+#define STV090x_P2_LOCKTIME1 STV090x_Px_LOCKTIMEy(2, 1)
+#define STV090x_P2_LOCKTIME2 STV090x_Px_LOCKTIMEy(2, 2)
+#define STV090x_P2_LOCKTIME3 STV090x_Px_LOCKTIMEy(2, 3)
+#define STV090x_OFFST_Px_DEMOD_LOCKTIME_FIELD 0
+#define STV090x_WIDTH_Px_DEMOD_LOCKTIME_FIELD 8
+
+#define STV090x_Px_TNRCFG(__x) (0xf4e0 - (__x - 1) * 0x200) /* check */
+#define STV090x_P1_TNRCFG STV090x_Px_TNRCFG(1)
+#define STV090x_P2_TNRCFG STV090x_Px_TNRCFG(2)
+
+#define STV090x_Px_TNRCFG2(__x) (0xf4e1 - (__x - 1) * 0x200)
+#define STV090x_P1_TNRCFG2 STV090x_Px_TNRCFG2(1)
+#define STV090x_P2_TNRCFG2 STV090x_Px_TNRCFG2(2)
+#define STV090x_OFFST_Px_TUN_IQSWAP_FIELD 7
+#define STV090x_WIDTH_Px_TUN_IQSWAP_FIELD 1
+
+#define STV090x_Px_VITSCALE(__x) (0xf532 - (__x - 1) * 0x200)
+#define STV090x_P1_VITSCALE STV090x_Px_VITSCALE(1)
+#define STV090x_P2_VITSCALE STV090x_Px_VITSCALE(2)
+#define STV090x_OFFST_Px_NVTH_NOSRANGE_FIELD 7
+#define STV090x_WIDTH_Px_NVTH_NOSRANGE_FIELD 1
+#define STV090x_OFFST_Px_VERROR_MAXMODE_FIELD 6
+#define STV090x_WIDTH_Px_VERROR_MAXMODE_FIELD 1
+#define STV090x_OFFST_Px_NSLOWSN_LOCKED_FIELD 3
+#define STV090x_WIDTH_Px_NSLOWSN_LOCKED_FIELD 1
+#define STV090x_OFFST_Px_DIS_RSFLOCK_FIELD 1
+#define STV090x_WIDTH_Px_DIS_RSFLOCK_FIELD 1
+
+#define STV090x_Px_FECM(__x) (0xf533 - (__x - 1) * 0x200)
+#define STV090x_P1_FECM STV090x_Px_FECM(1)
+#define STV090x_P2_FECM STV090x_Px_FECM(2)
+#define STV090x_OFFST_Px_DSS_DVB_FIELD 7
+#define STV090x_WIDTH_Px_DSS_DVB_FIELD 1
+#define STV090x_OFFST_Px_DSS_SRCH_FIELD 4
+#define STV090x_WIDTH_Px_DSS_SRCH_FIELD 1
+#define STV090x_OFFST_Px_SYNCVIT_FIELD 1
+#define STV090x_WIDTH_Px_SYNCVIT_FIELD 1
+#define STV090x_OFFST_Px_IQINV_FIELD 0
+#define STV090x_WIDTH_Px_IQINV_FIELD 1
+
+#define STV090x_Px_VTH12(__x) (0xf534 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH12 STV090x_Px_VTH12(1)
+#define STV090x_P2_VTH12 STV090x_Px_VTH12(2)
+#define STV090x_OFFST_Px_VTH12_FIELD 0
+#define STV090x_WIDTH_Px_VTH12_FIELD 8
+
+#define STV090x_Px_VTH23(__x) (0xf535 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH23 STV090x_Px_VTH23(1)
+#define STV090x_P2_VTH23 STV090x_Px_VTH23(2)
+#define STV090x_OFFST_Px_VTH23_FIELD 0
+#define STV090x_WIDTH_Px_VTH23_FIELD 8
+
+#define STV090x_Px_VTH34(__x) (0xf536 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH34 STV090x_Px_VTH34(1)
+#define STV090x_P2_VTH34 STV090x_Px_VTH34(2)
+#define STV090x_OFFST_Px_VTH34_FIELD 0
+#define STV090x_WIDTH_Px_VTH34_FIELD 8
+
+#define STV090x_Px_VTH56(__x) (0xf537 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH56 STV090x_Px_VTH56(1)
+#define STV090x_P2_VTH56 STV090x_Px_VTH56(2)
+#define STV090x_OFFST_Px_VTH56_FIELD 0
+#define STV090x_WIDTH_Px_VTH56_FIELD 8
+
+#define STV090x_Px_VTH67(__x) (0xf538 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH67 STV090x_Px_VTH67(1)
+#define STV090x_P2_VTH67 STV090x_Px_VTH67(2)
+#define STV090x_OFFST_Px_VTH67_FIELD 0
+#define STV090x_WIDTH_Px_VTH67_FIELD 8
+
+#define STV090x_Px_VTH78(__x) (0xf539 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH78 STV090x_Px_VTH78(1)
+#define STV090x_P2_VTH78 STV090x_Px_VTH78(2)
+#define STV090x_OFFST_Px_VTH78_FIELD 0
+#define STV090x_WIDTH_Px_VTH78_FIELD 8
+
+#define STV090x_Px_VITCURPUN(__x) (0xf53a - (__x - 1) * 0x200)
+#define STV090x_P1_VITCURPUN STV090x_Px_VITCURPUN(1)
+#define STV090x_P2_VITCURPUN STV090x_Px_VITCURPUN(2)
+#define STV090x_OFFST_Px_VIT_CURPUN_FIELD 0
+#define STV090x_WIDTH_Px_VIT_CURPUN_FIELD 5
+
+#define STV090x_Px_VERROR(__x) (0xf53b - (__x - 1) * 0x200)
+#define STV090x_P1_VERROR STV090x_Px_VERROR(1)
+#define STV090x_P2_VERROR STV090x_Px_VERROR(2)
+#define STV090x_OFFST_Px_REGERR_VIT_FIELD 0
+#define STV090x_WIDTH_Px_REGERR_VIT_FIELD 8
+
+#define STV090x_Px_PRVIT(__x) (0xf53c - (__x - 1) * 0x200)
+#define STV090x_P1_PRVIT STV090x_Px_PRVIT(1)
+#define STV090x_P2_PRVIT STV090x_Px_PRVIT(2)
+#define STV090x_OFFST_Px_DIS_VTHLOCK_FIELD 6
+#define STV090x_WIDTH_Px_DIS_VTHLOCK_FIELD 1
+#define STV090x_OFFST_Px_E7_8VIT_FIELD 5
+#define STV090x_WIDTH_Px_E7_8VIT_FIELD 1
+#define STV090x_OFFST_Px_E6_7VIT_FIELD 4
+#define STV090x_WIDTH_Px_E6_7VIT_FIELD 1
+#define STV090x_OFFST_Px_E5_6VIT_FIELD 3
+#define STV090x_WIDTH_Px_E5_6VIT_FIELD 1
+#define STV090x_OFFST_Px_E3_4VIT_FIELD 2
+#define STV090x_WIDTH_Px_E3_4VIT_FIELD 1
+#define STV090x_OFFST_Px_E2_3VIT_FIELD 1
+#define STV090x_WIDTH_Px_E2_3VIT_FIELD 1
+#define STV090x_OFFST_Px_E1_2VIT_FIELD 0
+#define STV090x_WIDTH_Px_E1_2VIT_FIELD 1
+
+#define STV090x_Px_VAVSRVIT(__x) (0xf53d - (__x - 1) * 0x200)
+#define STV090x_P1_VAVSRVIT STV090x_Px_VAVSRVIT(1)
+#define STV090x_P2_VAVSRVIT STV090x_Px_VAVSRVIT(2)
+#define STV090x_OFFST_Px_SNVIT_FIELD 4
+#define STV090x_WIDTH_Px_SNVIT_FIELD 2
+#define STV090x_OFFST_Px_TOVVIT_FIELD 2
+#define STV090x_WIDTH_Px_TOVVIT_FIELD 2
+#define STV090x_OFFST_Px_HYPVIT_FIELD 0
+#define STV090x_WIDTH_Px_HYPVIT_FIELD 2
+
+#define STV090x_Px_VSTATUSVIT(__x) (0xf53e - (__x - 1) * 0x200)
+#define STV090x_P1_VSTATUSVIT STV090x_Px_VSTATUSVIT(1)
+#define STV090x_P2_VSTATUSVIT STV090x_Px_VSTATUSVIT(2)
+#define STV090x_OFFST_Px_PRFVIT_FIELD 4
+#define STV090x_WIDTH_Px_PRFVIT_FIELD 1
+#define STV090x_OFFST_Px_LOCKEDVIT_FIELD 3
+#define STV090x_WIDTH_Px_LOCKEDVIT_FIELD 1
+
+#define STV090x_Px_VTHINUSE(__x) (0xf53f - (__x - 1) * 0x200)
+#define STV090x_P1_VTHINUSE STV090x_Px_VTHINUSE(1)
+#define STV090x_P2_VTHINUSE STV090x_Px_VTHINUSE(2)
+#define STV090x_OFFST_Px_VIT_INUSE_FIELD 0
+#define STV090x_WIDTH_Px_VIT_INUSE_FIELD 8
+
+#define STV090x_Px_KDIV12(__x) (0xf540 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV12 STV090x_Px_KDIV12(1)
+#define STV090x_P2_KDIV12 STV090x_Px_KDIV12(2)
+#define STV090x_OFFST_Px_K_DIVIDER_12_FIELD 0
+#define STV090x_WIDTH_Px_K_DIVIDER_12_FIELD 7
+
+#define STV090x_Px_KDIV23(__x) (0xf541 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV23 STV090x_Px_KDIV23(1)
+#define STV090x_P2_KDIV23 STV090x_Px_KDIV23(2)
+#define STV090x_OFFST_Px_K_DIVIDER_23_FIELD 0
+#define STV090x_WIDTH_Px_K_DIVIDER_23_FIELD 7
+
+#define STV090x_Px_KDIV34(__x) (0xf542 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV34 STV090x_Px_KDIV34(1)
+#define STV090x_P2_KDIV34 STV090x_Px_KDIV34(2)
+#define STV090x_OFFST_Px_K_DIVIDER_34_FIELD 0
+#define STV090x_WIDTH_Px_K_DIVIDER_34_FIELD 7
+
+#define STV090x_Px_KDIV56(__x) (0xf543 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV56 STV090x_Px_KDIV56(1)
+#define STV090x_P2_KDIV56 STV090x_Px_KDIV56(2)
+#define STV090x_OFFST_Px_K_DIVIDER_56_FIELD 0
+#define STV090x_WIDTH_Px_K_DIVIDER_56_FIELD 7
+
+#define STV090x_Px_KDIV67(__x) (0xf544 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV67 STV090x_Px_KDIV67(1)
+#define STV090x_P2_KDIV67 STV090x_Px_KDIV67(2)
+#define STV090x_OFFST_Px_K_DIVIDER_67_FIELD 0
+#define STV090x_WIDTH_Px_K_DIVIDER_67_FIELD 7
+
+#define STV090x_Px_KDIV78(__x) (0xf545 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV78 STV090x_Px_KDIV78(1)
+#define STV090x_P2_KDIV78 STV090x_Px_KDIV78(2)
+#define STV090x_OFFST_Px_K_DIVIDER_78_FIELD 0
+#define STV090x_WIDTH_Px_K_DIVIDER_78_FIELD 7
+
+#define STV090x_Px_PDELCTRL1(__x) (0xf550 - (__x - 1) * 0x200)
+#define STV090x_P1_PDELCTRL1 STV090x_Px_PDELCTRL1(1)
+#define STV090x_P2_PDELCTRL1 STV090x_Px_PDELCTRL1(2)
+#define STV090x_OFFST_Px_INV_MISMASK_FIELD 7
+#define STV090x_WIDTH_Px_INV_MISMASK_FIELD 1
+#define STV090x_OFFST_Px_FILTER_EN_FIELD 5
+#define STV090x_WIDTH_Px_FILTER_EN_FIELD 1
+#define STV090x_OFFST_Px_EN_MIS00_FIELD 1
+#define STV090x_WIDTH_Px_EN_MIS00_FIELD 1
+#define STV090x_OFFST_Px_ALGOSWRST_FIELD 0
+#define STV090x_WIDTH_Px_ALGOSWRST_FIELD 1
+
+#define STV090x_Px_PDELCTRL2(__x) (0xf551 - (__x - 1) * 0x200)
+#define STV090x_P1_PDELCTRL2 STV090x_Px_PDELCTRL2(1)
+#define STV090x_P2_PDELCTRL2 STV090x_Px_PDELCTRL2(2)
+#define STV090x_OFFST_Px_FORCE_CONTINUOUS 7
+#define STV090x_WIDTH_Px_FORCE_CONTINUOUS 1
+#define STV090x_OFFST_Px_RESET_UPKO_COUNT 6
+#define STV090x_WIDTH_Px_RESET_UPKO_COUNT 1
+#define STV090x_OFFST_Px_USER_PKTDELIN_NB 5
+#define STV090x_WIDTH_Px_USER_PKTDELIN_NB 1
+#define STV090x_OFFST_Px_FORCE_LOCKED 4
+#define STV090x_WIDTH_Px_FORCE_LOCKED 1
+#define STV090x_OFFST_Px_DATA_UNBBSCRAM 3
+#define STV090x_WIDTH_Px_DATA_UNBBSCRAM 1
+#define STV090x_OFFST_Px_FORCE_LONGPACKET 2
+#define STV090x_WIDTH_Px_FORCE_LONGPACKET 1
+#define STV090x_OFFST_Px_FRAME_MODE_FIELD 1
+#define STV090x_WIDTH_Px_FRAME_MODE_FIELD 1
+
+#define STV090x_Px_HYSTTHRESH(__x) (0xf554 - (__x - 1) * 0x200)
+#define STV090x_P1_HYSTTHRESH STV090x_Px_HYSTTHRESH(1)
+#define STV090x_P2_HYSTTHRESH STV090x_Px_HYSTTHRESH(2)
+#define STV090x_OFFST_Px_UNLCK_THRESH_FIELD 4
+#define STV090x_WIDTH_Px_UNLCK_THRESH_FIELD 4
+#define STV090x_OFFST_Px_DELIN_LCK_THRESH_FIELD 0
+#define STV090x_WIDTH_Px_DELIN_LCK_THRESH_FIELD 4
+
+#define STV090x_Px_ISIENTRY(__x) (0xf55e - (__x - 1) * 0x200)
+#define STV090x_P1_ISIENTRY STV090x_Px_ISIENTRY(1)
+#define STV090x_P2_ISIENTRY STV090x_Px_ISIENTRY(2)
+#define STV090x_OFFST_Px_ISI_ENTRY_FIELD 0
+#define STV090x_WIDTH_Px_ISI_ENTRY_FIELD 8
+
+#define STV090x_Px_ISIBITENA(__x) (0xf55f - (__x - 1) * 0x200)
+#define STV090x_P1_ISIBITENA STV090x_Px_ISIBITENA(1)
+#define STV090x_P2_ISIBITENA STV090x_Px_ISIBITENA(2)
+#define STV090x_OFFST_Px_ISI_BIT_EN_FIELD 0
+#define STV090x_WIDTH_Px_ISI_BIT_EN_FIELD 8
+
+#define STV090x_Px_MATSTRy(__x, __y) (0xf561 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_MATSTR0 STV090x_Px_MATSTRy(1, 0)
+#define STV090x_P1_MATSTR1 STV090x_Px_MATSTRy(1, 1)
+#define STV090x_P2_MATSTR0 STV090x_Px_MATSTRy(2, 0)
+#define STV090x_P2_MATSTR1 STV090x_Px_MATSTRy(2, 1)
+#define STV090x_OFFST_Px_MATYPE_CURRENT_FIELD 0
+#define STV090x_WIDTH_Px_MATYPE_CURRENT_FIELD 8
+
+#define STV090x_Px_UPLSTRy(__x, __y) (0xf563 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_UPLSTR0 STV090x_Px_UPLSTRy(1, 0)
+#define STV090x_P1_UPLSTR1 STV090x_Px_UPLSTRy(1, 1)
+#define STV090x_P2_UPLSTR0 STV090x_Px_UPLSTRy(2, 0)
+#define STV090x_P2_UPLSTR1 STV090x_Px_UPLSTRy(2, 1)
+#define STV090x_OFFST_Px_UPL_CURRENT_FIELD 0
+#define STV090x_WIDTH_Px_UPL_CURRENT_FIELD 8
+
+#define STV090x_Px_DFLSTRy(__x, __y) (0xf565 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_DFLSTR0 STV090x_Px_DFLSTRy(1, 0)
+#define STV090x_P1_DFLSTR1 STV090x_Px_DFLSTRy(1, 1)
+#define STV090x_P2_DFLSTR0 STV090x_Px_DFLSTRy(2, 0)
+#define STV090x_P2_DFLSTR1 STV090x_Px_DFLSTRy(2, 1)
+#define STV090x_OFFST_Px_DFL_CURRENT_FIELD 0
+#define STV090x_WIDTH_Px_DFL_CURRENT_FIELD 8
+
+#define STV090x_Px_SYNCSTR(__x) (0xf566 - (__x - 1) * 0x200)
+#define STV090x_P1_SYNCSTR STV090x_Px_SYNCSTR(1)
+#define STV090x_P2_SYNCSTR STV090x_Px_SYNCSTR(2)
+#define STV090x_OFFST_Px_SYNC_CURRENT_FIELD 0
+#define STV090x_WIDTH_Px_SYNC_CURRENT_FIELD 8
+
+#define STV090x_Px_SYNCDSTRy(__x, __y) (0xf568 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_SYNCDSTR0 STV090x_Px_SYNCDSTRy(1, 0)
+#define STV090x_P1_SYNCDSTR1 STV090x_Px_SYNCDSTRy(1, 1)
+#define STV090x_P2_SYNCDSTR0 STV090x_Px_SYNCDSTRy(2, 0)
+#define STV090x_P2_SYNCDSTR1 STV090x_Px_SYNCDSTRy(2, 1)
+#define STV090x_OFFST_Px_SYNCD_CURRENT_FIELD 0
+#define STV090x_WIDTH_Px_SYNCD_CURRENT_FIELD 8
+
+#define STV090x_Px_PDELSTATUS1(__x) (0xf569 - (__x - 1) * 0x200)
+#define STV090x_P1_PDELSTATUS1 STV090x_Px_PDELSTATUS1(1)
+#define STV090x_P2_PDELSTATUS1 STV090x_Px_PDELSTATUS1(2)
+#define STV090x_OFFST_Px_PKTDELIN_LOCK_FIELD 1
+#define STV090x_WIDTH_Px_PKTDELIN_LOCK_FIELD 1
+#define STV090x_OFFST_Px_FIRST_LOCK_FIELD 0
+#define STV090x_WIDTH_Px_FIRST_LOCK_FIELD 1
+
+#define STV090x_Px_PDELSTATUS2(__x) (0xf56a - (__x - 1) * 0x200)
+#define STV090x_P1_PDELSTATUS2 STV090x_Px_PDELSTATUS2(1)
+#define STV090x_P2_PDELSTATUS2 STV090x_Px_PDELSTATUS2(2)
+#define STV090x_OFFST_Px_FRAME_MODCOD_FIELD 2
+#define STV090x_WIDTH_Px_FRAME_MODCOD_FIELD 5
+#define STV090x_OFFST_Px_FRAME_TYPE_FIELD 0
+#define STV090x_WIDTH_Px_FRAME_TYPE_FIELD 2
+
+#define STV090x_Px_BBFCRCKO1(__x) (0xf56b - (__x - 1) * 0x200)
+#define STV090x_P1_BBFCRCKO1 STV090x_Px_BBFCRCKO1(1)
+#define STV090x_P2_BBFCRCKO1 STV090x_Px_BBFCRCKO1(2)
+#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD 0
+#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD 8
+
+#define STV090x_Px_BBFCRCKO0(__x) (0xf56c - (__x - 1) * 0x200)
+#define STV090x_P1_BBFCRCKO0 STV090x_Px_BBFCRCKO0(1)
+#define STV090x_P2_BBFCRCKO0 STV090x_Px_BBFCRCKO0(2)
+#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD 0
+#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD 8
+
+#define STV090x_Px_UPCRCKO1(__x) (0xf56d - (__x - 1) * 0x200)
+#define STV090x_P1_UPCRCKO1 STV090x_Px_UPCRCKO1(1)
+#define STV090x_P2_UPCRCKO1 STV090x_Px_UPCRCKO1(2)
+#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD 0
+#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD 8
+
+#define STV090x_Px_UPCRCKO0(__x) (0xf56e - (__x - 1) * 0x200)
+#define STV090x_P1_UPCRCKO0 STV090x_Px_UPCRCKO0(1)
+#define STV090x_P2_UPCRCKO0 STV090x_Px_UPCRCKO0(2)
+#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD 0
+#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD 8
+
+#define STV090x_NBITER_NFx(__x) (0xFA03 + (__x - 4) * 0x1)
+#define STV090x_NBITER_NF4 STV090x_NBITER_NFx(4)
+#define STV090x_NBITER_NF5 STV090x_NBITER_NFx(5)
+#define STV090x_NBITER_NF6 STV090x_NBITER_NFx(6)
+#define STV090x_NBITER_NF7 STV090x_NBITER_NFx(7)
+#define STV090x_NBITER_NF8 STV090x_NBITER_NFx(8)
+#define STV090x_NBITER_NF9 STV090x_NBITER_NFx(9)
+#define STV090x_NBITER_NF10 STV090x_NBITER_NFx(10)
+#define STV090x_NBITER_NF11 STV090x_NBITER_NFx(11)
+#define STV090x_NBITER_NF12 STV090x_NBITER_NFx(12)
+#define STV090x_NBITER_NF13 STV090x_NBITER_NFx(13)
+#define STV090x_NBITER_NF14 STV090x_NBITER_NFx(14)
+#define STV090x_NBITER_NF15 STV090x_NBITER_NFx(15)
+#define STV090x_NBITER_NF16 STV090x_NBITER_NFx(16)
+#define STV090x_NBITER_NF17 STV090x_NBITER_NFx(17)
+
+#define STV090x_NBITERNOERR 0xFA3F
+#define STV090x_OFFST_NBITER_STOP_CRIT_FIELD 0
+#define STV090x_WIDTH_NBITER_STOP_CRIT_FIELD 4
+
+#define STV090x_GAINLLR_NFx(__x) (0xFA43 + (__x - 4) * 0x1)
+#define STV090x_GAINLLR_NF4 STV090x_GAINLLR_NFx(4)
+#define STV090x_OFFST_GAINLLR_NF_QP_1_2_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_QP_1_2_FIELD 7
+
+#define STV090x_GAINLLR_NF5 STV090x_GAINLLR_NFx(5)
+#define STV090x_OFFST_GAINLLR_NF_QP_3_5_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_QP_3_5_FIELD 7
+
+#define STV090x_GAINLLR_NF6 STV090x_GAINLLR_NFx(6)
+#define STV090x_OFFST_GAINLLR_NF_QP_2_3_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_QP_2_3_FIELD 7
+
+#define STV090x_GAINLLR_NF7 STV090x_GAINLLR_NFx(7)
+#define STV090x_OFFST_GAINLLR_NF_QP_3_4_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_QP_3_4_FIELD 7
+
+#define STV090x_GAINLLR_NF8 STV090x_GAINLLR_NFx(8)
+#define STV090x_OFFST_GAINLLR_NF_QP_4_5_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_QP_4_5_FIELD 7
+
+#define STV090x_GAINLLR_NF9 STV090x_GAINLLR_NFx(9)
+#define STV090x_OFFST_GAINLLR_NF_QP_5_6_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_QP_5_6_FIELD 7
+
+#define STV090x_GAINLLR_NF10 STV090x_GAINLLR_NFx(10)
+#define STV090x_OFFST_GAINLLR_NF_QP_8_9_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_QP_8_9_FIELD 7
+
+#define STV090x_GAINLLR_NF11 STV090x_GAINLLR_NFx(11)
+#define STV090x_OFFST_GAINLLR_NF_QP_9_10_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_QP_9_10_FIELD 7
+
+#define STV090x_GAINLLR_NF12 STV090x_GAINLLR_NFx(12)
+#define STV090x_OFFST_GAINLLR_NF_8P_3_5_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_8P_3_5_FIELD 7
+
+#define STV090x_GAINLLR_NF13 STV090x_GAINLLR_NFx(13)
+#define STV090x_OFFST_GAINLLR_NF_8P_2_3_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_8P_2_3_FIELD 7
+
+#define STV090x_GAINLLR_NF14 STV090x_GAINLLR_NFx(14)
+#define STV090x_OFFST_GAINLLR_NF_8P_3_4_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_8P_3_4_FIELD 7
+
+#define STV090x_GAINLLR_NF15 STV090x_GAINLLR_NFx(15)
+#define STV090x_OFFST_GAINLLR_NF_8P_5_6_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_8P_5_6_FIELD 7
+
+#define STV090x_GAINLLR_NF16 STV090x_GAINLLR_NFx(16)
+#define STV090x_OFFST_GAINLLR_NF_8P_8_9_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_8P_8_9_FIELD 7
+
+#define STV090x_GAINLLR_NF17 STV090x_GAINLLR_NFx(17)
+#define STV090x_OFFST_GAINLLR_NF_8P_9_10_FIELD 0
+#define STV090x_WIDTH_GAINLLR_NF_8P_9_10_FIELD 7
+
+#define STV090x_GENCFG 0xFA86
+#define STV090x_OFFST_BROADCAST_FIELD 4
+#define STV090x_WIDTH_BROADCAST_FIELD 1
+#define STV090x_OFFST_PRIORITY_FIELD 1
+#define STV090x_WIDTH_PRIORITY_FIELD 1
+#define STV090x_OFFST_DDEMOD_FIELD 0
+#define STV090x_WIDTH_DDEMOD_FIELD 1
+
+#define STV090x_LDPCERRx(__x) (0xFA97 - (__x * 0x1))
+#define STV090x_LDPCERR0 STV090x_LDPCERRx(0)
+#define STV090x_LDPCERR1 STV090x_LDPCERRx(1)
+#define STV090x_OFFST_Px_LDPC_ERRORS_COUNTER_FIELD 0
+#define STV090x_WIDTH_Px_LDPC_ERRORS_COUNTER_FIELD 8
+
+#define STV090x_BCHERR 0xFA98
+#define STV090x_OFFST_Px_ERRORFLAG_FIELD 4
+#define STV090x_WIDTH_Px_ERRORFLAG_FIELD 1
+#define STV090x_OFFST_Px_BCH_ERRORS_COUNTER_FIELD 0
+#define STV090x_WIDTH_Px_BCH_ERRORS_COUNTER_FIELD 4
+
+#define STV090x_Px_TSSTATEM(__x) (0xF570 - (__x - 1) * 0x200)
+#define STV090x_P1_TSSTATEM STV090x_Px_TSSTATEM(1)
+#define STV090x_P2_TSSTATEM STV090x_Px_TSSTATEM(2)
+#define STV090x_OFFST_Px_TSDIL_ON_FIELD 7
+#define STV090x_WIDTH_Px_TSDIL_ON_FIELD 1
+#define STV090x_OFFST_Px_TSRS_ON_FIELD 5
+#define STV090x_WIDTH_Px_TSRS_ON_FIELD 1
+
+#define STV090x_Px_TSCFGH(__x) (0xF572 - (__x - 1) * 0x200)
+#define STV090x_P1_TSCFGH STV090x_Px_TSCFGH(1)
+#define STV090x_P2_TSCFGH STV090x_Px_TSCFGH(2)
+#define STV090x_OFFST_Px_TSFIFO_DVBCI_FIELD 7
+#define STV090x_WIDTH_Px_TSFIFO_DVBCI_FIELD 1
+#define STV090x_OFFST_Px_TSFIFO_SERIAL_FIELD 6
+#define STV090x_WIDTH_Px_TSFIFO_SERIAL_FIELD 1
+#define STV090x_OFFST_Px_TSFIFO_TEIUPDATE_FIELD 5
+#define STV090x_WIDTH_Px_TSFIFO_TEIUPDATE_FIELD 1
+#define STV090x_OFFST_Px_TSFIFO_DUTY50_FIELD 4
+#define STV090x_WIDTH_Px_TSFIFO_DUTY50_FIELD 1
+#define STV090x_OFFST_Px_TSFIFO_HSGNLOUT_FIELD 3
+#define STV090x_WIDTH_Px_TSFIFO_HSGNLOUT_FIELD 1
+#define STV090x_OFFST_Px_TSFIFO_ERRORMODE_FIELD 1
+#define STV090x_WIDTH_Px_TSFIFO_ERRORMODE_FIELD 2
+#define STV090x_OFFST_Px_RST_HWARE_FIELD 0
+#define STV090x_WIDTH_Px_RST_HWARE_FIELD 1
+
+#define STV090x_Px_TSCFGM(__x) (0xF573 - (__x - 1) * 0x200)
+#define STV090x_P1_TSCFGM STV090x_Px_TSCFGM(1)
+#define STV090x_P2_TSCFGM STV090x_Px_TSCFGM(2)
+#define STV090x_OFFST_Px_TSFIFO_MANSPEED_FIELD 6
+#define STV090x_WIDTH_Px_TSFIFO_MANSPEED_FIELD 2
+#define STV090x_OFFST_Px_TSFIFO_PERMDATA_FIELD 5
+#define STV090x_WIDTH_Px_TSFIFO_PERMDATA_FIELD 1
+#define STV090x_OFFST_Px_TSFIFO_INVDATA_FIELD 0
+#define STV090x_WIDTH_Px_TSFIFO_INVDATA_FIELD 1
+
+#define STV090x_Px_TSCFGL(__x) (0xF574 - (__x - 1) * 0x200)
+#define STV090x_P1_TSCFGL STV090x_Px_TSCFGL(1)
+#define STV090x_P2_TSCFGL STV090x_Px_TSCFGL(2)
+#define STV090x_OFFST_Px_TSFIFO_BCLKDEL1CK_FIELD 6
+#define STV090x_WIDTH_Px_TSFIFO_BCLKDEL1CK_FIELD 2
+#define STV090x_OFFST_Px_BCHERROR_MODE_FIELD 4
+#define STV090x_WIDTH_Px_BCHERROR_MODE_FIELD 2
+#define STV090x_OFFST_Px_TSFIFO_NSGNL2DATA_FIELD 3
+#define STV090x_WIDTH_Px_TSFIFO_NSGNL2DATA_FIELD 1
+#define STV090x_OFFST_Px_TSFIFO_EMBINDVB_FIELD 2
+#define STV090x_WIDTH_Px_TSFIFO_EMBINDVB_FIELD 1
+#define STV090x_OFFST_Px_TSFIFO_DPUNACT_FIELD 1
+#define STV090x_WIDTH_Px_TSFIFO_DPUNACT_FIELD 1
+
+#define STV090x_Px_TSINSDELH(__x) (0xF576 - (__x - 1) * 0x200)
+#define STV090x_P1_TSINSDELH STV090x_Px_TSINSDELH(1)
+#define STV090x_P2_TSINSDELH STV090x_Px_TSINSDELH(2)
+#define STV090x_OFFST_Px_TSDEL_SYNCBYTE_FIELD 7
+#define STV090x_WIDTH_Px_TSDEL_SYNCBYTE_FIELD 1
+#define STV090x_OFFST_Px_TSDEL_XXHEADER_FIELD 6
+#define STV090x_WIDTH_Px_TSDEL_XXHEADER_FIELD 1
+
+#define STV090x_Px_TSSPEED(__x) (0xF580 - (__x - 1) * 0x200)
+#define STV090x_P1_TSSPEED STV090x_Px_TSSPEED(1)
+#define STV090x_P2_TSSPEED STV090x_Px_TSSPEED(2)
+#define STV090x_OFFST_Px_TSFIFO_OUTSPEED_FIELD 0
+#define STV090x_WIDTH_Px_TSFIFO_OUTSPEED_FIELD 8
+
+#define STV090x_Px_TSSTATUS(__x) (0xF581 - (__x - 1) * 0x200)
+#define STV090x_P1_TSSTATUS STV090x_Px_TSSTATUS(1)
+#define STV090x_P2_TSSTATUS STV090x_Px_TSSTATUS(2)
+#define STV090x_OFFST_Px_TSFIFO_LINEOK_FIELD 7
+#define STV090x_WIDTH_Px_TSFIFO_LINEOK_FIELD 1
+#define STV090x_OFFST_Px_TSFIFO_ERROR_FIELD 6
+#define STV090x_WIDTH_Px_TSFIFO_ERROR_FIELD 1
+
+#define STV090x_Px_TSSTATUS2(__x) (0xF582 - (__x - 1) * 0x200)
+#define STV090x_P1_TSSTATUS2 STV090x_Px_TSSTATUS2(1)
+#define STV090x_P2_TSSTATUS2 STV090x_Px_TSSTATUS2(2)
+#define STV090x_OFFST_Px_TSFIFO_DEMODSEL_FIELD 7
+#define STV090x_WIDTH_Px_TSFIFO_DEMODSEL_FIELD 1
+#define STV090x_OFFST_Px_TSFIFOSPEED_STORE_FIELD 6
+#define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD 1
+#define STV090x_OFFST_Px_DILXX_RESET_FIELD 5
+#define STV090x_WIDTH_Px_DILXX_RESET_FIELD 1
+#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD 5
+#define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD 1
+#define STV090x_OFFST_Px_SCRAMBDETECT_FIELD 1
+#define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD 1
+
+#define STV090x_Px_TSBITRATEy(__x, __y) (0xF584 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_TSBITRATE0 STV090x_Px_TSBITRATEy(1, 0)
+#define STV090x_P1_TSBITRATE1 STV090x_Px_TSBITRATEy(1, 1)
+#define STV090x_P2_TSBITRATE0 STV090x_Px_TSBITRATEy(2, 0)
+#define STV090x_P2_TSBITRATE1 STV090x_Px_TSBITRATEy(2, 1)
+#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD 7
+#define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD 8
+
+#define STV090x_Px_ERRCTRL1(__x) (0xF598 - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCTRL1 STV090x_Px_ERRCTRL1(1)
+#define STV090x_P2_ERRCTRL1 STV090x_Px_ERRCTRL1(2)
+#define STV090x_OFFST_Px_ERR_SOURCE_FIELD 4
+#define STV090x_WIDTH_Px_ERR_SOURCE_FIELD 4
+#define STV090x_OFFST_Px_NUM_EVENT_FIELD 0
+#define STV090x_WIDTH_Px_NUM_EVENT_FIELD 3
+
+#define STV090x_Px_ERRCNT12(__x) (0xF599 - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT12 STV090x_Px_ERRCNT12(1)
+#define STV090x_P2_ERRCNT12 STV090x_Px_ERRCNT12(2)
+#define STV090x_OFFST_Px_ERRCNT1_OLDVALUE_FIELD 7
+#define STV090x_WIDTH_Px_ERRCNT1_OLDVALUE_FIELD 1
+#define STV090x_OFFST_Px_ERR_CNT12_FIELD 0
+#define STV090x_WIDTH_Px_ERR_CNT12_FIELD 7
+
+#define STV090x_Px_ERRCNT11(__x) (0xF59A - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT11 STV090x_Px_ERRCNT11(1)
+#define STV090x_P2_ERRCNT11 STV090x_Px_ERRCNT11(2)
+#define STV090x_OFFST_Px_ERR_CNT11_FIELD 0
+#define STV090x_WIDTH_Px_ERR_CNT11_FIELD 8
+
+#define STV090x_Px_ERRCNT10(__x) (0xF59B - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT10 STV090x_Px_ERRCNT10(1)
+#define STV090x_P2_ERRCNT10 STV090x_Px_ERRCNT10(2)
+#define STV090x_OFFST_Px_ERR_CNT10_FIELD 0
+#define STV090x_WIDTH_Px_ERR_CNT10_FIELD 8
+
+#define STV090x_Px_ERRCTRL2(__x) (0xF59C - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCTRL2 STV090x_Px_ERRCTRL2(1)
+#define STV090x_P2_ERRCTRL2 STV090x_Px_ERRCTRL2(2)
+#define STV090x_OFFST_Px_ERR_SOURCE2_FIELD 4
+#define STV090x_WIDTH_Px_ERR_SOURCE2_FIELD 4
+#define STV090x_OFFST_Px_NUM_EVENT2_FIELD 0
+#define STV090x_WIDTH_Px_NUM_EVENT2_FIELD 3
+
+#define STV090x_Px_ERRCNT22(__x) (0xF59D - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT22 STV090x_Px_ERRCNT22(1)
+#define STV090x_P2_ERRCNT22 STV090x_Px_ERRCNT22(2)
+#define STV090x_OFFST_Px_ERRCNT2_OLDVALUE_FIELD 7
+#define STV090x_WIDTH_Px_ERRCNT2_OLDVALUE_FIELD 1
+#define STV090x_OFFST_Px_ERR_CNT2_FIELD 0
+#define STV090x_WIDTH_Px_ERR_CNT2_FIELD 7
+
+#define STV090x_Px_ERRCNT21(__x) (0xF59E - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT21 STV090x_Px_ERRCNT21(1)
+#define STV090x_P2_ERRCNT21 STV090x_Px_ERRCNT21(2)
+#define STV090x_OFFST_Px_ERR_CNT21_FIELD 0
+#define STV090x_WIDTH_Px_ERR_CNT21_FIELD 8
+
+#define STV090x_Px_ERRCNT20(__x) (0xF59F - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT20 STV090x_Px_ERRCNT20(1)
+#define STV090x_P2_ERRCNT20 STV090x_Px_ERRCNT20(2)
+#define STV090x_OFFST_Px_ERR_CNT20_FIELD 0
+#define STV090x_WIDTH_Px_ERR_CNT20_FIELD 8
+
+#define STV090x_Px_FECSPY(__x) (0xF5A0 - (__x - 1) * 0x200)
+#define STV090x_P1_FECSPY STV090x_Px_FECSPY(1)
+#define STV090x_P2_FECSPY STV090x_Px_FECSPY(2)
+#define STV090x_OFFST_Px_SPY_ENABLE_FIELD 7
+#define STV090x_WIDTH_Px_SPY_ENABLE_FIELD 1
+#define STV090x_OFFST_Px_BERMETER_DATAMAODE_FIELD 2
+#define STV090x_WIDTH_Px_BERMETER_DATAMAODE_FIELD 2
+
+#define STV090x_Px_FSPYCFG(__x) (0xF5A1 - (__x - 1) * 0x200)
+#define STV090x_P1_FSPYCFG STV090x_Px_FSPYCFG(1)
+#define STV090x_P2_FSPYCFG STV090x_Px_FSPYCFG(2)
+#define STV090x_OFFST_Px_RST_ON_ERROR_FIELD 5
+#define STV090x_WIDTH_Px_RST_ON_ERROR_FIELD 1
+#define STV090x_OFFST_Px_ONE_SHOT_FIELD 4
+#define STV090x_WIDTH_Px_ONE_SHOT_FIELD 1
+#define STV090x_OFFST_Px_I2C_MODE_FIELD 2
+#define STV090x_WIDTH_Px_I2C_MODE_FIELD 2
+
+#define STV090x_Px_FSPYDATA(__x) (0xF5A2 - (__x - 1) * 0x200)
+#define STV090x_P1_FSPYDATA STV090x_Px_FSPYDATA(1)
+#define STV090x_P2_FSPYDATA STV090x_Px_FSPYDATA(2)
+#define STV090x_OFFST_Px_SPY_STUFFING_FIELD 7
+#define STV090x_WIDTH_Px_SPY_STUFFING_FIELD 1
+#define STV090x_OFFST_Px_SPY_CNULLPKT_FIELD 5
+#define STV090x_WIDTH_Px_SPY_CNULLPKT_FIELD 1
+#define STV090x_OFFST_Px_SPY_OUTDATA_MODE_FIELD 0
+#define STV090x_WIDTH_Px_SPY_OUTDATA_MODE_FIELD 5
+
+#define STV090x_Px_FSPYOUT(__x) (0xF5A3 - (__x - 1) * 0x200)
+#define STV090x_P1_FSPYOUT STV090x_Px_FSPYOUT(1)
+#define STV090x_P2_FSPYOUT STV090x_Px_FSPYOUT(2)
+#define STV090x_OFFST_Px_FSPY_DIRECT_FIELD 7
+#define STV090x_WIDTH_Px_FSPY_DIRECT_FIELD 1
+#define STV090x_OFFST_Px_STUFF_MODE_FIELD 0
+#define STV090x_WIDTH_Px_STUFF_MODE_FIELD 3
+
+#define STV090x_Px_FSTATUS(__x) (0xF5A4 - (__x - 1) * 0x200)
+#define STV090x_P1_FSTATUS STV090x_Px_FSTATUS(1)
+#define STV090x_P2_FSTATUS STV090x_Px_FSTATUS(2)
+#define STV090x_OFFST_Px_SPY_ENDSIM_FIELD 7
+#define STV090x_WIDTH_Px_SPY_ENDSIM_FIELD 1
+#define STV090x_OFFST_Px_VALID_SIM_FIELD 6
+#define STV090x_WIDTH_Px_VALID_SIM_FIELD 1
+#define STV090x_OFFST_Px_FOUND_SIGNAL_FIELD 5
+#define STV090x_WIDTH_Px_FOUND_SIGNAL_FIELD 1
+#define STV090x_OFFST_Px_DSS_SYNCBYTE_FIELD 4
+#define STV090x_WIDTH_Px_DSS_SYNCBYTE_FIELD 1
+#define STV090x_OFFST_Px_RESULT_STATE_FIELD 0
+#define STV090x_WIDTH_Px_RESULT_STATE_FIELD 4
+
+#define STV090x_Px_FBERCPT4(__x) (0xF5A8 - (__x - 1) * 0x200)
+#define STV090x_P1_FBERCPT4 STV090x_Px_FBERCPT4(1)
+#define STV090x_P2_FBERCPT4 STV090x_Px_FBERCPT4(2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
+
+#define STV090x_Px_FBERCPT3(__x) (0xF5A9 - (__x - 1) * 0x200)
+#define STV090x_P1_FBERCPT3 STV090x_Px_FBERCPT3(1)
+#define STV090x_P2_FBERCPT3 STV090x_Px_FBERCPT3(2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
+
+#define STV090x_Px_FBERCPT2(__x) (0xF5AA - (__x - 1) * 0x200)
+#define STV090x_P1_FBERCPT2 STV090x_Px_FBERCPT2(1)
+#define STV090x_P2_FBERCPT2 STV090x_Px_FBERCPT2(2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
+
+#define STV090x_Px_FBERCPT1(__x) (0xF5AB - (__x - 1) * 0x200)
+#define STV090x_P1_FBERCPT1 STV090x_Px_FBERCPT1(1)
+#define STV090x_P2_FBERCPT1 STV090x_Px_FBERCPT1(2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
+
+#define STV090x_Px_FBERCPT0(__x) (0xF5AC - (__x - 1) * 0x200)
+#define STV090x_P1_FBERCPT0 STV090x_Px_FBERCPT0(1)
+#define STV090x_P2_FBERCPT0 STV090x_Px_FBERCPT0(2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
+
+#define STV090x_Px_FBERERRy(__x, __y) (0xF5AF - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_FBERERR0 STV090x_Px_FBERERRy(1, 0)
+#define STV090x_P1_FBERERR1 STV090x_Px_FBERERRy(1, 1)
+#define STV090x_P1_FBERERR2 STV090x_Px_FBERERRy(1, 2)
+#define STV090x_P2_FBERERR0 STV090x_Px_FBERERRy(2, 0)
+#define STV090x_P2_FBERERR1 STV090x_Px_FBERERRy(2, 1)
+#define STV090x_P2_FBERERR2 STV090x_Px_FBERERRy(2, 2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_ERR_FIELD 0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_ERR_FIELD 8
+
+#define STV090x_Px_FSPYBER(__x) (0xF5B2 - (__x - 1) * 0x200)
+#define STV090x_P1_FSPYBER STV090x_Px_FSPYBER(1)
+#define STV090x_P2_FSPYBER STV090x_Px_FSPYBER(2)
+#define STV090x_OFFST_Px_FSPYBER_SYNCBYTE_FIELD 4
+#define STV090x_WIDTH_Px_FSPYBER_SYNCBYTE_FIELD 1
+#define STV090x_OFFST_Px_FSPYBER_UNSYNC_FIELD 3
+#define STV090x_WIDTH_Px_FSPYBER_UNSYNC_FIELD 1
+#define STV090x_OFFST_Px_FSPYBER_CTIME_FIELD 0
+#define STV090x_WIDTH_Px_FSPYBER_CTIME_FIELD 3
+
+#define STV090x_RCCFGH 0xf600
+
+#define STV090x_TSGENERAL 0xF630
+#define STV090x_OFFST_Px_MUXSTREAM_OUT_FIELD 3
+#define STV090x_WIDTH_Px_MUXSTREAM_OUT_FIELD 1
+#define STV090x_OFFST_Px_TSFIFO_PERMPARAL_FIELD 1
+#define STV090x_WIDTH_Px_TSFIFO_PERMPARAL_FIELD 2
+
+#define STV090x_TSGENERAL1X 0xf670
+#define STV090x_CFGEXT 0xfa80
+
+#define STV090x_TSTRES0 0xFF11
+#define STV090x_OFFST_FRESFEC_FIELD 7
+#define STV090x_WIDTH_FRESFEC_FIELD 1
+
+#define STV090x_Px_TSTDISRX(__x) (0xFF67 - (__x - 1) * 0x2)
+#define STV090x_P1_TSTDISRX STV090x_Px_TSTDISRX(1)
+#define STV090x_P2_TSTDISRX STV090x_Px_TSTDISRX(2)
+#define STV090x_OFFST_Px_TSTDISRX_SELECT_FIELD 3
+#define STV090x_WIDTH_Px_TSTDISRX_SELECT_FIELD 1
+
+#endif /* __STV090x_REG_H */
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
new file mode 100644
index 000000000000..3d8a2e01c9c4
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x.c
@@ -0,0 +1,373 @@
+/*
+ STV6110(A) Silicon tuner driver
+
+ Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+ Copyright (C) ST Microelectronics
+
+ 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.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include "dvb_frontend.h"
+
+#include "stv6110x_reg.h"
+#include "stv6110x.h"
+#include "stv6110x_priv.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+
+static u8 stv6110x_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
+
+static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
+{
+ int ret;
+ const struct stv6110x_config *config = stv6110x->config;
+ u8 b0[] = { reg };
+ u8 b1[] = { 0 };
+ struct i2c_msg msg[] = {
+ { .addr = config->addr, .flags = 0, .buf = b0, .len = 1 },
+ { .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }
+ };
+
+ ret = i2c_transfer(stv6110x->i2c, msg, 2);
+ if (ret != 2) {
+ dprintk(FE_ERROR, 1, "I/O Error");
+ return -EREMOTEIO;
+ }
+ *data = b1[0];
+
+ return 0;
+}
+
+static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
+{
+ int ret;
+ const struct stv6110x_config *config = stv6110x->config;
+ u8 buf[] = { reg, data };
+ struct i2c_msg msg = { .addr = config->addr, .flags = 0, . buf = buf, .len = 2 };
+
+ ret = i2c_transfer(stv6110x->i2c, &msg, 1);
+ if (ret != 1) {
+ dprintk(FE_ERROR, 1, "I/O Error");
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int stv6110x_init(struct dvb_frontend *fe)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+ int ret;
+ u8 i;
+
+ for (i = 0; i < ARRAY_SIZE(stv6110x_regs); i++) {
+ ret = stv6110x_write_reg(stv6110x, i, stv6110x_regs[i]);
+ if (ret < 0) {
+ dprintk(FE_ERROR, 1, "Initialization failed");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+ u32 rDiv, divider;
+ s32 pVal, pCalc, rDivOpt = 0;
+ u8 i;
+
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
+
+ if (frequency <= 1023000) {
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
+ pVal = 40;
+ } else if (frequency <= 1300000) {
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
+ pVal = 40;
+ } else if (frequency <= 2046000) {
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
+ pVal = 20;
+ } else {
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
+ pVal = 20;
+ }
+
+ for (rDiv = 0; rDiv <= 3; rDiv++) {
+ pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv);
+
+ if ((abs((s32)(pCalc - pVal))) < (abs((s32)(1000 - pVal))))
+ rDivOpt = rDiv;
+ }
+
+ divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
+ divider = (divider + 5) / 10;
+
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt);
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider));
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider));
+
+ /* VCO Auto calibration */
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1);
+
+ stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]);
+ stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x_regs[STV6110x_TNG1]);
+ stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x_regs[STV6110x_TNG0]);
+ stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]);
+
+ for (i = 0; i < TRIALS; i++) {
+ stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]);
+ if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x_regs[STV6110x_STAT1]))
+ break;
+ msleep(1);
+ }
+
+ return 0;
+}
+
+static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+ stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x_regs[STV6110x_TNG1]);
+ stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x_regs[STV6110x_TNG0]);
+
+ *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x_regs[STV6110x_TNG1]),
+ STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x_regs[STV6110x_TNG0]))) * REFCLOCK_kHz;
+
+ *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x_regs[STV6110x_TNG1]) +
+ STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x_regs[STV6110x_TNG1])));
+
+ *frequency >>= 2;
+
+ return 0;
+}
+
+static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+ u32 halfbw;
+ u8 i;
+
+ halfbw = bandwidth >> 1;
+
+ if (halfbw > 36000000)
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */
+ else if (halfbw < 5000000)
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */
+ else
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */
+
+
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */
+
+ stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]);
+ stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]);
+
+ for (i = 0; i < TRIALS; i++) {
+ stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]);
+ if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x_regs[STV6110x_STAT1]))
+ break;
+ msleep(1);
+ }
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */
+ stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]);
+
+ return 0;
+}
+
+static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+ stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x_regs[STV6110x_CTRL3]);
+ *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x_regs[STV6110x_CTRL3]) + 5) * 2000000;
+
+ return 0;
+}
+
+static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+ /* setup divider */
+ switch (refclock) {
+ default:
+ case 1:
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
+ break;
+ case 2:
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
+ break;
+ case 4:
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
+ break;
+ case 8:
+ case 0:
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
+ break;
+ }
+ stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]);
+
+ return 0;
+}
+
+static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+ stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x_regs[STV6110x_CTRL2]);
+ *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x_regs[STV6110x_CTRL2]);
+
+ return 0;
+}
+
+static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2);
+ stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]);
+
+ return 0;
+}
+
+static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+ int ret;
+
+ switch (mode) {
+ case TUNER_SLEEP:
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 0);
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 0);
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 0);
+ break;
+
+ case TUNER_WAKE:
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 1);
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 1);
+ STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 1);
+ break;
+ }
+
+ ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]);
+ if (ret < 0) {
+ dprintk(FE_ERROR, 1, "I/O Error");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int stv6110x_sleep(struct dvb_frontend *fe)
+{
+ return stv6110x_set_mode(fe, TUNER_SLEEP);
+}
+
+static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+ stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]);
+
+ if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x_regs[STV6110x_STAT1]))
+ *status = TUNER_PHASELOCKED;
+ else
+ *status = 0;
+
+ return 0;
+}
+
+
+static int stv6110x_release(struct dvb_frontend *fe)
+{
+ struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+ fe->tuner_priv = NULL;
+ kfree(stv6110x);
+
+ return 0;
+}
+
+static struct dvb_tuner_ops stv6110x_ops = {
+ .info = {
+ .name = "STV6110(A) Silicon Tuner",
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_step = 0,
+ },
+
+ .init = stv6110x_init,
+ .sleep = stv6110x_sleep,
+ .release = stv6110x_release
+};
+
+static struct stv6110x_devctl stv6110x_ctl = {
+ .tuner_init = stv6110x_init,
+ .tuner_set_mode = stv6110x_set_mode,
+ .tuner_set_frequency = stv6110x_set_frequency,
+ .tuner_get_frequency = stv6110x_get_frequency,
+ .tuner_set_bandwidth = stv6110x_set_bandwidth,
+ .tuner_get_bandwidth = stv6110x_get_bandwidth,
+ .tuner_set_bbgain = stv6110x_set_bbgain,
+ .tuner_get_bbgain = stv6110x_get_bbgain,
+ .tuner_set_refclk = stv6110x_set_refclock,
+ .tuner_get_status = stv6110x_get_status,
+};
+
+struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
+ const struct stv6110x_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct stv6110x_state *stv6110x;
+
+ stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
+ if (stv6110x == NULL)
+ goto error;
+
+ stv6110x->i2c = i2c;
+ stv6110x->config = config;
+ stv6110x->devctl = &stv6110x_ctl;
+
+ fe->tuner_priv = stv6110x;
+ fe->ops.tuner_ops = stv6110x_ops;
+
+ printk("%s: Attaching STV6110x \n", __func__);
+ return stv6110x->devctl;
+
+error:
+ kfree(stv6110x);
+ return NULL;
+}
+EXPORT_SYMBOL(stv6110x_attach);
+
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("STV6110x Silicon tuner");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb/frontends/stv6110x.h
new file mode 100644
index 000000000000..a38257080e01
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x.h
@@ -0,0 +1,71 @@
+/*
+ STV6110(A) Silicon tuner driver
+
+ Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+ Copyright (C) ST Microelectronics
+
+ 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.
+*/
+
+#ifndef __STV6110x_H
+#define __STV6110x_H
+
+struct stv6110x_config {
+ u8 addr;
+ u32 refclk;
+};
+
+enum tuner_mode {
+ TUNER_SLEEP = 1,
+ TUNER_WAKE,
+};
+
+enum tuner_status {
+ TUNER_PHASELOCKED = 1,
+};
+
+struct stv6110x_devctl {
+ int (*tuner_init) (struct dvb_frontend *fe);
+ int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
+ int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
+ int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
+ int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
+ int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
+ int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
+ int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
+ int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
+ int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
+};
+
+
+#if defined(CONFIG_DVB_STV6110x) || (defined(CONFIG_DVB_STV6110x_MODULE) && defined(MODULE))
+
+extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
+ const struct stv6110x_config *config,
+ struct i2c_adapter *i2c);
+
+#else
+static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
+ const struct stv6110x_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+#endif /* CONFIG_DVB_STV6110x */
+
+#endif /* __STV6110x_H */
diff --git a/drivers/media/dvb/frontends/stv6110x_priv.h b/drivers/media/dvb/frontends/stv6110x_priv.h
new file mode 100644
index 000000000000..7260da633d49
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x_priv.h
@@ -0,0 +1,75 @@
+/*
+ STV6110(A) Silicon tuner driver
+
+ Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+ Copyright (C) ST Microelectronics
+
+ 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.
+*/
+
+#ifndef __STV6110x_PRIV_H
+#define __STV6110x_PRIV_H
+
+#define FE_ERROR 0
+#define FE_NOTICE 1
+#define FE_INFO 2
+#define FE_DEBUG 3
+#define FE_DEBUGREG 4
+
+#define dprintk(__y, __z, format, arg...) do { \
+ if (__z) { \
+ if ((verbose > FE_ERROR) && (verbose > __y)) \
+ printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
+ else if ((verbose > FE_NOTICE) && (verbose > __y)) \
+ printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
+ else if ((verbose > FE_INFO) && (verbose > __y)) \
+ printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
+ else if ((verbose > FE_DEBUG) && (verbose > __y)) \
+ printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
+ } else { \
+ if (verbose > __y) \
+ printk(format, ##arg); \
+ } \
+} while (0)
+
+
+#define STV6110x_SETFIELD(mask, bitf, val) \
+ (mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) << \
+ STV6110x_OFFST_##bitf))) | \
+ (val << STV6110x_OFFST_##bitf))
+
+#define STV6110x_GETFIELD(bitf, val) \
+ ((val >> STV6110x_OFFST_##bitf) & \
+ ((1 << STV6110x_WIDTH_##bitf) - 1))
+
+#define MAKEWORD16(a, b) (((a) << 8) | (b))
+
+#define LSB(x) ((x & 0xff))
+#define MSB(y) ((y >> 8) & 0xff)
+
+#define TRIALS 10
+#define R_DIV(__div) (1 << (__div + 1))
+#define REFCLOCK_kHz (stv6110x->config->refclk / 1000)
+#define REFCLOCK_MHz (stv6110x->config->refclk / 1000000)
+
+struct stv6110x_state {
+ struct i2c_adapter *i2c;
+ const struct stv6110x_config *config;
+
+ struct stv6110x_devctl *devctl;
+};
+
+#endif /* __STV6110x_PRIV_H */
diff --git a/drivers/media/dvb/frontends/stv6110x_reg.h b/drivers/media/dvb/frontends/stv6110x_reg.h
new file mode 100644
index 000000000000..93e5c70e5fd8
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x_reg.h
@@ -0,0 +1,82 @@
+/*
+ STV6110(A) Silicon tuner driver
+
+ Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+ Copyright (C) ST Microelectronics
+
+ 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.
+*/
+
+#ifndef __STV6110x_REG_H
+#define __STV6110x_REG_H
+
+#define STV6110x_CTRL1 0x00
+#define STV6110x_OFFST_CTRL1_K 3
+#define STV6110x_WIDTH_CTRL1_K 5
+#define STV6110x_OFFST_CTRL1_LPT 2
+#define STV6110x_WIDTH_CTRL1_LPT 1
+#define STV6110x_OFFST_CTRL1_RX 1
+#define STV6110x_WIDTH_CTRL1_RX 1
+#define STV6110x_OFFST_CTRL1_SYN 0
+#define STV6110x_WIDTH_CTRL1_SYN 1
+
+#define STV6110x_CTRL2 0x01
+#define STV6110x_OFFST_CTRL2_CO_DIV 6
+#define STV6110x_WIDTH_CTRL2_CO_DIV 2
+#define STV6110x_OFFST_CTRL2_RSVD 5
+#define STV6110x_WIDTH_CTRL2_RSVD 1
+#define STV6110x_OFFST_CTRL2_REFOUT_SEL 4
+#define STV6110x_WIDTH_CTRL2_REFOUT_SEL 1
+#define STV6110x_OFFST_CTRL2_BBGAIN 0
+#define STV6110x_WIDTH_CTRL2_BBGAIN 4
+
+#define STV6110x_TNG0 0x02
+#define STV6110x_OFFST_TNG0_N_DIV_7_0 0
+#define STV6110x_WIDTH_TNG0_N_DIV_7_0 8
+
+#define STV6110x_TNG1 0x03
+#define STV6110x_OFFST_TNG1_R_DIV 6
+#define STV6110x_WIDTH_TNG1_R_DIV 2
+#define STV6110x_OFFST_TNG1_PRESC32_ON 5
+#define STV6110x_WIDTH_TNG1_PRESC32_ON 1
+#define STV6110x_OFFST_TNG1_DIV4SEL 4
+#define STV6110x_WIDTH_TNG1_DIV4SEL 1
+#define STV6110x_OFFST_TNG1_N_DIV_11_8 0
+#define STV6110x_WIDTH_TNG1_N_DIV_11_8 4
+
+
+#define STV6110x_CTRL3 0x04
+#define STV6110x_OFFST_CTRL3_DCLOOP_OFF 7
+#define STV6110x_WIDTH_CTRL3_DCLOOP_OFF 1
+#define STV6110x_OFFST_CTRL3_RCCLK_OFF 6
+#define STV6110x_WIDTH_CTRL3_RCCLK_OFF 1
+#define STV6110x_OFFST_CTRL3_ICP 5
+#define STV6110x_WIDTH_CTRL3_ICP 1
+#define STV6110x_OFFST_CTRL3_CF 0
+#define STV6110x_WIDTH_CTRL3_CF 5
+
+#define STV6110x_STAT1 0x05
+#define STV6110x_OFFST_STAT1_CALVCO_STRT 2
+#define STV6110x_WIDTH_STAT1_CALVCO_STRT 1
+#define STV6110x_OFFST_STAT1_CALRC_STRT 1
+#define STV6110x_WIDTH_STAT1_CALRC_STRT 1
+#define STV6110x_OFFST_STAT1_LOCK 0
+#define STV6110x_WIDTH_STAT1_LOCK 1
+
+#define STV6110x_STAT2 0x06
+#define STV6110x_STAT3 0x07
+
+#endif /* __STV6110x_REG_H */
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c
index 2a8bbcd44cd0..28f580f858c6 100644
--- a/drivers/media/dvb/frontends/tda10048.c
+++ b/drivers/media/dvb/frontends/tda10048.c
@@ -25,6 +25,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <asm/div64.h>
#include "dvb_frontend.h"
#include "dvb_math.h"
#include "tda10048.h"
@@ -143,6 +144,15 @@ struct tda10048_state {
struct dvb_frontend frontend;
int fwloaded;
+
+ u32 freq_if_hz;
+ u32 xtal_hz;
+ u32 pll_mfactor;
+ u32 pll_nfactor;
+ u32 pll_pfactor;
+ u32 sample_freq;
+
+ enum fe_bandwidth bandwidth;
};
static struct init_tab {
@@ -271,6 +281,199 @@ error:
return ret;
}
+static int tda10048_set_phy2(struct dvb_frontend *fe, u32 sample_freq_hz,
+ u32 if_hz)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ u64 t;
+
+ dprintk(1, "%s()\n", __func__);
+
+ if (sample_freq_hz == 0)
+ return -EINVAL;
+
+ if (if_hz < (sample_freq_hz / 2)) {
+ /* PHY2 = (if2/fs) * 2^15 */
+ t = if_hz;
+ t *= 10;
+ t *= 32768;
+ do_div(t, sample_freq_hz);
+ t += 5;
+ do_div(t, 10);
+ } else {
+ /* PHY2 = ((IF1-fs)/fs) * 2^15 */
+ t = sample_freq_hz - if_hz;
+ t *= 10;
+ t *= 32768;
+ do_div(t, sample_freq_hz);
+ t += 5;
+ do_div(t, 10);
+ t = ~t + 1;
+ }
+
+ tda10048_writereg(state, TDA10048_FREQ_PHY2_LSB, (u8)t);
+ tda10048_writereg(state, TDA10048_FREQ_PHY2_MSB, (u8)(t >> 8));
+
+ return 0;
+}
+
+static int tda10048_set_wref(struct dvb_frontend *fe, u32 sample_freq_hz,
+ u32 bw)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ u64 t, z;
+ u32 b = 8000000;
+
+ dprintk(1, "%s()\n", __func__);
+
+ if (sample_freq_hz == 0)
+ return -EINVAL;
+
+ if (bw == BANDWIDTH_6_MHZ)
+ b = 6000000;
+ else
+ if (bw == BANDWIDTH_7_MHZ)
+ b = 7000000;
+
+ /* WREF = (B / (7 * fs)) * 2^31 */
+ t = b * 10;
+ /* avoid warning: this decimal constant is unsigned only in ISO C90 */
+ /* t *= 2147483648 on 32bit platforms */
+ t *= (2048 * 1024);
+ t *= 1024;
+ z = 7 * sample_freq_hz;
+ do_div(t, z);
+ t += 5;
+ do_div(t, 10);
+
+ tda10048_writereg(state, TDA10048_TIME_WREF_LSB, (u8)t);
+ tda10048_writereg(state, TDA10048_TIME_WREF_MID1, (u8)(t >> 8));
+ tda10048_writereg(state, TDA10048_TIME_WREF_MID2, (u8)(t >> 16));
+ tda10048_writereg(state, TDA10048_TIME_WREF_MSB, (u8)(t >> 24));
+
+ return 0;
+}
+
+static int tda10048_set_invwref(struct dvb_frontend *fe, u32 sample_freq_hz,
+ u32 bw)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ u64 t;
+ u32 b = 8000000;
+
+ dprintk(1, "%s()\n", __func__);
+
+ if (sample_freq_hz == 0)
+ return -EINVAL;
+
+ if (bw == BANDWIDTH_6_MHZ)
+ b = 6000000;
+ else
+ if (bw == BANDWIDTH_7_MHZ)
+ b = 7000000;
+
+ /* INVWREF = ((7 * fs) / B) * 2^5 */
+ t = sample_freq_hz;
+ t *= 7;
+ t *= 32;
+ t *= 10;
+ do_div(t, b);
+ t += 5;
+ do_div(t, 10);
+
+ tda10048_writereg(state, TDA10048_TIME_INVWREF_LSB, (u8)t);
+ tda10048_writereg(state, TDA10048_TIME_INVWREF_MSB, (u8)(t >> 8));
+
+ return 0;
+}
+
+static int tda10048_set_bandwidth(struct dvb_frontend *fe,
+ enum fe_bandwidth bw)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ dprintk(1, "%s(bw=%d)\n", __func__, bw);
+
+ /* Bandwidth setting may need to be adjusted */
+ switch (bw) {
+ case BANDWIDTH_6_MHZ:
+ case BANDWIDTH_7_MHZ:
+ case BANDWIDTH_8_MHZ:
+ tda10048_set_wref(fe, state->sample_freq, bw);
+ tda10048_set_invwref(fe, state->sample_freq, bw);
+ break;
+ default:
+ printk(KERN_ERR "%s() invalid bandwidth\n", __func__);
+ return -EINVAL;
+ }
+
+ state->bandwidth = bw;
+
+ return 0;
+}
+
+static int tda10048_set_pll(struct dvb_frontend *fe)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ int ret = 0;
+
+ dprintk(1, "%s()\n", __func__);
+
+ if ((state->config->clk_freq_khz == TDA10048_CLK_4000) &&
+ (state->config->if_freq_khz == TDA10048_IF_36130)) {
+ state->freq_if_hz = TDA10048_IF_36130 * 1000;
+ state->xtal_hz = TDA10048_CLK_4000 * 1000;
+ state->pll_mfactor = 10;
+ state->pll_nfactor = 0;
+ state->pll_pfactor = 0;
+ } else
+ if ((state->config->clk_freq_khz == TDA10048_CLK_16000) &&
+ (state->config->if_freq_khz == TDA10048_IF_4300)) {
+ state->freq_if_hz = TDA10048_IF_4300 * 1000;
+ state->xtal_hz = TDA10048_CLK_16000 * 1000;
+ state->pll_mfactor = 10;
+ state->pll_nfactor = 3;
+ state->pll_pfactor = 0;
+ } else
+ if ((state->config->clk_freq_khz == TDA10048_CLK_16000) &&
+ (state->config->if_freq_khz == TDA10048_IF_4000)) {
+ state->freq_if_hz = TDA10048_IF_4000 * 1000;
+ state->xtal_hz = TDA10048_CLK_16000 * 1000;
+ state->pll_mfactor = 10;
+ state->pll_nfactor = 3;
+ state->pll_pfactor = 0;
+ } else
+ if ((state->config->clk_freq_khz == TDA10048_CLK_16000) &&
+ (state->config->if_freq_khz == TDA10048_IF_36130)) {
+ state->freq_if_hz = TDA10048_IF_36130 * 1000;
+ state->xtal_hz = TDA10048_CLK_16000 * 1000;
+ state->pll_mfactor = 10;
+ state->pll_nfactor = 3;
+ state->pll_pfactor = 0;
+ } else {
+ printk(KERN_ERR "%s() Incorrect attach settings\n", __func__);
+ ret = -EINVAL;
+ }
+
+ dprintk(1, "- freq_if_hz = %d\n", state->freq_if_hz);
+ dprintk(1, "- xtal_hz = %d\n", state->xtal_hz);
+ dprintk(1, "- pll_mfactor = %d\n", state->pll_mfactor);
+ dprintk(1, "- pll_nfactor = %d\n", state->pll_nfactor);
+ dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor);
+
+ /* Calculate the sample frequency */
+ state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45);
+ state->sample_freq /= (state->pll_nfactor + 1);
+ state->sample_freq /= (state->pll_pfactor + 4);
+ dprintk(1, "- sample_freq = %d\n", state->sample_freq);
+
+ tda10048_set_phy2(fe, state->sample_freq,
+ state->config->if_freq_khz * 1000);
+ tda10048_set_wref(fe, state->sample_freq, state->bandwidth);
+ tda10048_set_invwref(fe, state->sample_freq, state->bandwidth);
+
+ return ret;
+}
+
static int tda10048_firmware_upload(struct dvb_frontend *fe)
{
struct tda10048_state *state = fe->demodulator_priv;
@@ -523,6 +726,9 @@ static int tda10048_set_frontend(struct dvb_frontend *fe,
dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency);
+ if (p->u.ofdm.bandwidth != state->bandwidth)
+ tda10048_set_bandwidth(fe, p->u.ofdm.bandwidth);
+
if (fe->ops.tuner_ops.set_params) {
if (fe->ops.i2c_gate_ctrl)
@@ -558,9 +764,15 @@ static int tda10048_init(struct dvb_frontend *fe)
/* Set either serial or parallel */
tda10048_output_mode(fe, state->config->output_mode);
- /* set inversion */
+ /* Set inversion */
tda10048_set_inversion(fe, state->config->inversion);
+ /* Establish default PLL values */
+ tda10048_set_pll(fe);
+
+ /* Establish default bandwidth */
+ tda10048_set_bandwidth(fe, BANDWIDTH_8_MHZ);
+
/* Ensure we leave the gate closed */
tda10048_i2c_gate_ctrl(fe, 0);
@@ -830,6 +1042,7 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
state->config = config;
state->i2c = i2c;
state->fwloaded = 0;
+ state->bandwidth = BANDWIDTH_8_MHZ;
/* check if the demod is present */
if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048)
@@ -840,6 +1053,10 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
+ /* Set the xtal and freq defaults */
+ if (tda10048_set_pll(&state->frontend) != 0)
+ goto error;
+
/* Leave the gate closed */
tda10048_i2c_gate_ctrl(&state->frontend, 0);
diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h
index 0457b24601fa..ab9cf5bd421e 100644
--- a/drivers/media/dvb/frontends/tda10048.h
+++ b/drivers/media/dvb/frontends/tda10048.h
@@ -43,6 +43,20 @@ struct tda10048_config {
#define TDA10048_INVERSION_OFF 0
#define TDA10048_INVERSION_ON 1
u8 inversion;
+
+#define TDA10048_IF_3300 3300
+#define TDA10048_IF_3500 3500
+#define TDA10048_IF_3800 3800
+#define TDA10048_IF_4000 4000
+#define TDA10048_IF_4300 4300
+#define TDA10048_IF_4500 4500
+#define TDA10048_IF_4750 4750
+#define TDA10048_IF_36130 36130
+ u16 if_freq_khz;
+
+#define TDA10048_CLK_4000 4000
+#define TDA10048_CLK_16000 16000
+ u16 clk_freq_khz;
};
#if defined(CONFIG_DVB_TDA10048) || \
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index 7bd4d1dee2b3..f3e1cc733fe7 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -58,42 +58,6 @@ struct smscore_client_t {
onremove_t onremove_handler;
};
-struct smscore_device_t {
- struct list_head entry;
-
- struct list_head clients;
- struct list_head subclients;
- spinlock_t clientslock;
-
- struct list_head buffers;
- spinlock_t bufferslock;
- int num_buffers;
-
- void *common_buffer;
- int common_buffer_size;
- dma_addr_t common_buffer_phys;
-
- void *context;
- struct device *device;
-
- char devpath[32];
- unsigned long device_flags;
-
- setmode_t setmode_handler;
- detectmode_t detectmode_handler;
- sendrequest_t sendrequest_handler;
- preload_t preload_handler;
- postload_t postload_handler;
-
- int mode, modes_supported;
-
- struct completion version_ex_done, data_download_done, trigger_done;
- struct completion init_device_done, reload_start_done, resume_done;
-
- int board_id;
- int led_state;
-};
-
void smscore_set_board_id(struct smscore_device_t *core, int id)
{
core->board_id = id;
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
index 548de9056e8b..d7284482eced 100644
--- a/drivers/media/dvb/siano/smscoreapi.h
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -46,13 +46,14 @@
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
-#define SMS_ALLOC_ALIGNMENT 128
-#define SMS_DMA_ALIGNMENT 16
+#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000)
+#define SMS_ALLOC_ALIGNMENT 128
+#define SMS_DMA_ALIGNMENT 16
#define SMS_ALIGN_ADDRESS(addr) \
((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
-#define SMS_DEVICE_FAMILY2 1
-#define SMS_ROM_NO_RESPONSE 2
+#define SMS_DEVICE_FAMILY2 1
+#define SMS_ROM_NO_RESPONSE 2
#define SMS_DEVICE_NOT_READY 0x8000000
enum sms_device_type_st {
@@ -83,13 +84,13 @@ typedef void (*onremove_t)(void *context);
struct smscore_buffer_t {
/* public members, once passed to clients can be changed freely */
struct list_head entry;
- int size;
- int offset;
+ int size;
+ int offset;
/* private members, read-only for clients */
- void *p;
- dma_addr_t phys;
- unsigned long offset_in_common;
+ void *p;
+ dma_addr_t phys;
+ unsigned long offset_in_common;
};
struct smsdevice_params_t {
@@ -116,10 +117,63 @@ struct smsclient_params_t {
int data_type;
onresponse_t onresponse_handler;
onremove_t onremove_handler;
-
void *context;
};
+struct smscore_device_t {
+ struct list_head entry;
+
+ struct list_head clients;
+ struct list_head subclients;
+ spinlock_t clientslock;
+
+ struct list_head buffers;
+ spinlock_t bufferslock;
+ int num_buffers;
+
+ void *common_buffer;
+ int common_buffer_size;
+ dma_addr_t common_buffer_phys;
+
+ void *context;
+ struct device *device;
+
+ char devpath[32];
+ unsigned long device_flags;
+
+ setmode_t setmode_handler;
+ detectmode_t detectmode_handler;
+ sendrequest_t sendrequest_handler;
+ preload_t preload_handler;
+ postload_t postload_handler;
+
+ int mode, modes_supported;
+
+ /* host <--> device messages */
+ struct completion version_ex_done, data_download_done, trigger_done;
+ struct completion init_device_done, reload_start_done, resume_done;
+ struct completion gpio_configuration_done, gpio_set_level_done;
+ struct completion gpio_get_level_done, ir_init_done;
+
+ /* Buffer management */
+ wait_queue_head_t buffer_mng_waitq;
+
+ /* GPIO */
+ int gpio_get_res;
+
+ /* Target hardware board */
+ int board_id;
+
+ /* Firmware */
+ u8 *fw_buf;
+ u32 fw_buf_size;
+
+ /* Infrared (IR) */
+ /* struct ir_t ir; */
+
+ int led_state;
+};
+
/* GPIO definitions for antenna frequency domain control (SMS8021) */
#define SMS_ANTENNA_GPIO_0 1
#define SMS_ANTENNA_GPIO_1 0
@@ -161,6 +215,7 @@ struct smsclient_params_t {
#define MSG_SMS_GET_PID_FILTER_LIST_RES 609
#define MSG_SMS_GET_STATISTICS_REQ 615
#define MSG_SMS_GET_STATISTICS_RES 616
+#define MSG_SMS_HO_PER_SLICES_IND 630
#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651
#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652
#define MSG_SMS_GET_STATISTICS_EX_REQ 653
@@ -190,14 +245,31 @@ struct smsclient_params_t {
#define MSG_SMS_GPIO_CONFIG_EX_RES 713
#define MSG_SMS_ISDBT_TUNE_REQ 776
#define MSG_SMS_ISDBT_TUNE_RES 777
+#define MSG_SMS_TRANSMISSION_IND 782
+#define MSG_SMS_START_IR_REQ 800
+#define MSG_SMS_START_IR_RES 801
+#define MSG_SMS_IR_SAMPLES_IND 802
+#define MSG_SMS_SIGNAL_DETECTED_IND 827
+#define MSG_SMS_NO_SIGNAL_IND 828
#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
(ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
(ptr)->msgLength = len; (ptr)->msgFlags = 0; \
} while (0)
+
#define SMS_INIT_MSG(ptr, type, len) \
SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
+enum SMS_DVB3_EVENTS {
+ DVB3_EVENT_INIT = 0,
+ DVB3_EVENT_SLEEP,
+ DVB3_EVENT_HOTPLUG,
+ DVB3_EVENT_FE_LOCK,
+ DVB3_EVENT_FE_UNLOCK,
+ DVB3_EVENT_UNC_OK,
+ DVB3_EVENT_UNC_ERR
+};
+
enum SMS_DEVICE_MODE {
DEVICE_MODE_NONE = -1,
DEVICE_MODE_DVBT = 0,
@@ -221,8 +293,13 @@ struct SmsMsgHdr_ST {
};
struct SmsMsgData_ST {
- struct SmsMsgHdr_ST xMsgHeader;
- u32 msgData[1];
+ struct SmsMsgHdr_ST xMsgHeader;
+ u32 msgData[1];
+};
+
+struct SmsMsgData_ST2 {
+ struct SmsMsgHdr_ST xMsgHeader;
+ u32 msgData[2];
};
struct SmsDataDownload_ST {
@@ -238,11 +315,12 @@ struct SmsVersionRes_ST {
u8 Step; /* 0 - Step A */
u8 MetalFix; /* 0 - Metal 0 */
- u8 FirmwareId; /* 0xFF � ROM, otherwise the
- * value indicated by
- * SMSHOSTLIB_DEVICE_MODES_E */
- u8 SupportedProtocols; /* Bitwise OR combination of
+ /* FirmwareId 0xFF if ROM, otherwise the
+ * value indicated by SMSHOSTLIB_DEVICE_MODES_E */
+ u8 FirmwareId;
+ /* SupportedProtocols Bitwise OR combination of
* supported protocols */
+ u8 SupportedProtocols;
u8 VersionMajor;
u8 VersionMinor;
@@ -276,10 +354,12 @@ struct SMSHOSTLIB_STATISTICS_ST {
s32 SNR; /* dB */
u32 BER; /* Post Viterbi BER [1E-5] */
u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */
- u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A,
+ /* Transport stream PER, 0xFFFFFFFF indicate N/A,
* valid only for DVB-T/H */
- u32 MFER; /* DVB-H frame error rate in percentage,
+ u32 TS_PER;
+ /* DVB-H frame error rate in percentage,
* 0xFFFFFFFF indicate N/A, valid only for DVB-H */
+ u32 MFER;
s32 RSSI; /* dBm */
s32 InBandPwr; /* In band power in dBM */
s32 CarrierOffset; /* Carrier Offset in bin/1024 */
@@ -287,8 +367,9 @@ struct SMSHOSTLIB_STATISTICS_ST {
/* Transmission parameters, valid only for DVB-T/H */
u32 Frequency; /* Frequency in Hz */
u32 Bandwidth; /* Bandwidth in MHz */
- u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4,
+ /* Transmission Mode, for DAB modes 1-4,
* for DVB-T/H FFT mode carriers in Kilos */
+ u32 TransmissionMode;
u32 ModemState; /* from SMS_DvbModemState_ET */
u32 GuardInterval; /* Guard Interval, 1 divided by value */
u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET */
diff --git a/drivers/media/dvb/siano/smsendian.c b/drivers/media/dvb/siano/smsendian.c
new file mode 100644
index 000000000000..d79aa051269a
--- /dev/null
+++ b/drivers/media/dvb/siano/smsendian.c
@@ -0,0 +1,100 @@
+/****************************************************************
+
+ Siano Mobile Silicon, Inc.
+ MDTV receiver kernel modules.
+ Copyright (C) 2006-2009, Uri Shkolnik
+
+ 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 <http://www.gnu.org/licenses/>.
+
+ ****************************************************************/
+
+#include <asm/byteorder.h>
+
+#include "smsendian.h"
+#include "smscoreapi.h"
+
+void smsendian_handle_tx_message(void *buffer)
+{
+#ifdef __BIG_ENDIAN
+ struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
+ int i;
+ int msgWords;
+
+ switch (msg->xMsgHeader.msgType) {
+ case MSG_SMS_DATA_DOWNLOAD_REQ:
+ {
+ msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
+ break;
+ }
+
+ default:
+ msgWords = (msg->xMsgHeader.msgLength -
+ sizeof(struct SmsMsgHdr_ST))/4;
+
+ for (i = 0; i < msgWords; i++)
+ msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
+
+ break;
+ }
+#endif /* __BIG_ENDIAN */
+}
+
+void smsendian_handle_rx_message(void *buffer)
+{
+#ifdef __BIG_ENDIAN
+ struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
+ int i;
+ int msgWords;
+
+ switch (msg->xMsgHeader.msgType) {
+ case MSG_SMS_GET_VERSION_EX_RES:
+ {
+ struct SmsVersionRes_ST *ver =
+ (struct SmsVersionRes_ST *) msg;
+ ver->ChipModel = le16_to_cpu(ver->ChipModel);
+ break;
+ }
+
+ case MSG_SMS_DVBT_BDA_DATA:
+ case MSG_SMS_DAB_CHANNEL:
+ case MSG_SMS_DATA_MSG:
+ {
+ break;
+ }
+
+ default:
+ {
+ msgWords = (msg->xMsgHeader.msgLength -
+ sizeof(struct SmsMsgHdr_ST))/4;
+
+ for (i = 0; i < msgWords; i++)
+ msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
+
+ break;
+ }
+ }
+#endif /* __BIG_ENDIAN */
+}
+
+void smsendian_handle_message_header(void *msg)
+{
+#ifdef __BIG_ENDIAN
+ struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
+
+ phdr->msgType = le16_to_cpu(phdr->msgType);
+ phdr->msgLength = le16_to_cpu(phdr->msgLength);
+ phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
+#endif /* __BIG_ENDIAN */
+}
+
diff --git a/drivers/media/dvb/siano/smsendian.h b/drivers/media/dvb/siano/smsendian.h
new file mode 100644
index 000000000000..7fbedc6a6527
--- /dev/null
+++ b/drivers/media/dvb/siano/smsendian.h
@@ -0,0 +1,32 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2009, Uri Shkolnik
+
+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 <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#ifndef __SMS_ENDIAN_H__
+#define __SMS_ENDIAN_H__
+
+#include <asm/byteorder.h>
+
+void smsendian_handle_tx_message(void *buffer);
+void smsendian_handle_rx_message(void *buffer);
+void smsendian_handle_message_header(void *msg);
+
+#endif /* __SMS_ENDIAN_H__ */
+
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c
new file mode 100644
index 000000000000..a5f302c58fdb
--- /dev/null
+++ b/drivers/media/dvb/siano/smsir.c
@@ -0,0 +1,301 @@
+/****************************************************************
+
+ Siano Mobile Silicon, Inc.
+ MDTV receiver kernel modules.
+ Copyright (C) 2006-2009, Uri Shkolnik
+
+ 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 <http://www.gnu.org/licenses/>.
+
+ ****************************************************************/
+
+
+#include <linux/types.h>
+#include <linux/input.h>
+
+#include "smscoreapi.h"
+#include "smsir.h"
+#include "sms-cards.h"
+
+/* In order to add new IR remote control -
+ * 1) Add it to the <enum ir_kb_type> @ smsir,h,
+ * 2) Add its map to keyboard_layout_maps below
+ * 3) Set your board (sms-cards sub-module) to use it
+ */
+
+static struct keyboard_layout_map_t keyboard_layout_maps[] = {
+ [SMS_IR_KB_DEFAULT_TV] = {
+ .ir_protocol = IR_RC5,
+ .rc5_kbd_address = KEYBOARD_ADDRESS_TV1,
+ .keyboard_layout_map = {
+ KEY_0, KEY_1, KEY_2,
+ KEY_3, KEY_4, KEY_5,
+ KEY_6, KEY_7, KEY_8,
+ KEY_9, 0, 0, KEY_POWER,
+ KEY_MUTE, 0, 0,
+ KEY_VOLUMEUP, KEY_VOLUMEDOWN,
+ KEY_BRIGHTNESSUP,
+ KEY_BRIGHTNESSDOWN, KEY_CHANNELUP,
+ KEY_CHANNELDOWN,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }
+ },
+ [SMS_IR_KB_HCW_SILVER] = {
+ .ir_protocol = IR_RC5,
+ .rc5_kbd_address = KEYBOARD_ADDRESS_LIGHTING1,
+ .keyboard_layout_map = {
+ KEY_0, KEY_1, KEY_2,
+ KEY_3, KEY_4, KEY_5,
+ KEY_6, KEY_7, KEY_8,
+ KEY_9, KEY_TEXT, KEY_RED,
+ KEY_RADIO, KEY_MENU,
+ KEY_SUBTITLE,
+ KEY_MUTE, KEY_VOLUMEUP,
+ KEY_VOLUMEDOWN, KEY_PREVIOUS, 0,
+ KEY_UP, KEY_DOWN, KEY_LEFT,
+ KEY_RIGHT, KEY_VIDEO, KEY_AUDIO,
+ KEY_MHP, KEY_EPG, KEY_TV,
+ 0, KEY_NEXTSONG, KEY_EXIT,
+ KEY_CHANNELUP, KEY_CHANNELDOWN,
+ KEY_CHANNEL, 0,
+ KEY_PREVIOUSSONG, KEY_ENTER,
+ KEY_SLEEP, 0, 0, KEY_BLUE,
+ 0, 0, 0, 0, KEY_GREEN, 0,
+ KEY_PAUSE, 0, KEY_REWIND,
+ 0, KEY_FASTFORWARD, KEY_PLAY,
+ KEY_STOP, KEY_RECORD,
+ KEY_YELLOW, 0, 0, KEY_SELECT,
+ KEY_ZOOM, KEY_POWER, 0, 0
+ }
+ },
+ { } /* Terminating entry */
+};
+
+u32 ir_pos;
+u32 ir_word;
+u32 ir_toggle;
+
+#define RC5_PUSH_BIT(dst, bit, pos) \
+ { dst <<= 1; dst |= bit; pos++; }
+
+
+static void sms_ir_rc5_event(struct smscore_device_t *coredev,
+ u32 toggle, u32 addr, u32 cmd)
+{
+ bool toggle_changed;
+ u16 keycode;
+
+ sms_info("IR RC5 word: address %d, command %d, toggle %d",
+ addr, cmd, toggle);
+
+ toggle_changed = ir_toggle != toggle;
+ /* keep toggle */
+ ir_toggle = toggle;
+
+ if (addr !=
+ keyboard_layout_maps[coredev->ir.ir_kb_type].rc5_kbd_address)
+ return; /* Check for valid address */
+
+ keycode =
+ keyboard_layout_maps
+ [coredev->ir.ir_kb_type].keyboard_layout_map[cmd];
+
+ if (!toggle_changed &&
+ (keycode != KEY_VOLUMEUP && keycode != KEY_VOLUMEDOWN))
+ return; /* accept only repeated volume, reject other keys */
+
+ sms_info("kernel input keycode (from ir) %d", keycode);
+ input_report_key(coredev->ir.input_dev, keycode, 1);
+ input_sync(coredev->ir.input_dev);
+
+}
+
+/* decode raw bit pattern to RC5 code */
+/* taken from ir-functions.c */
+static u32 ir_rc5_decode(unsigned int code)
+{
+/* unsigned int org_code = code;*/
+ unsigned int pair;
+ unsigned int rc5 = 0;
+ int i;
+
+ for (i = 0; i < 14; ++i) {
+ pair = code & 0x3;
+ code >>= 2;
+
+ rc5 <<= 1;
+ switch (pair) {
+ case 0:
+ case 2:
+ break;
+ case 1:
+ rc5 |= 1;
+ break;
+ case 3:
+/* dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);*/
+ sms_info("bad code");
+ return 0;
+ }
+ }
+/*
+ dprintk(1, "ir-common: code=%x, rc5=%x, start=%x,
+ toggle=%x, address=%x, "
+ "instr=%x\n", rc5, org_code, RC5_START(rc5),
+ RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
+*/
+ return rc5;
+}
+
+static void sms_rc5_parse_word(struct smscore_device_t *coredev)
+{
+ #define RC5_START(x) (((x)>>12)&3)
+ #define RC5_TOGGLE(x) (((x)>>11)&1)
+ #define RC5_ADDR(x) (((x)>>6)&0x1F)
+ #define RC5_INSTR(x) ((x)&0x3F)
+
+ int i, j;
+ u32 rc5_word = 0;
+
+ /* Reverse the IR word direction */
+ for (i = 0 ; i < 28 ; i++)
+ RC5_PUSH_BIT(rc5_word, (ir_word>>i)&1, j)
+
+ rc5_word = ir_rc5_decode(rc5_word);
+ /* sms_info("temp = 0x%x, rc5_code = 0x%x", ir_word, rc5_word); */
+
+ sms_ir_rc5_event(coredev,
+ RC5_TOGGLE(rc5_word),
+ RC5_ADDR(rc5_word),
+ RC5_INSTR(rc5_word));
+}
+
+
+static void sms_rc5_accumulate_bits(struct smscore_device_t *coredev,
+ s32 ir_sample)
+{
+ #define RC5_TIME_GRANULARITY 200
+ #define RC5_DEF_BIT_TIME 889
+ #define RC5_MAX_SAME_BIT_CONT 4
+ #define RC5_WORD_LEN 27 /* 28 bit */
+
+ u32 i, j;
+ s32 delta_time;
+ u32 time = (ir_sample > 0) ? ir_sample : (0-ir_sample);
+ u32 level = (ir_sample < 0) ? 0 : 1;
+
+ for (i = RC5_MAX_SAME_BIT_CONT; i > 0; i--) {
+ delta_time = time - (i*RC5_DEF_BIT_TIME) + RC5_TIME_GRANULARITY;
+ if (delta_time < 0)
+ continue; /* not so many consecutive bits */
+ if (delta_time > (2 * RC5_TIME_GRANULARITY)) {
+ /* timeout */
+ if (ir_pos == (RC5_WORD_LEN-1))
+ /* complete last bit */
+ RC5_PUSH_BIT(ir_word, level, ir_pos)
+
+ if (ir_pos == RC5_WORD_LEN)
+ sms_rc5_parse_word(coredev);
+ else if (ir_pos) /* timeout within a word */
+ sms_info("IR error parsing a word");
+
+ ir_pos = 0;
+ ir_word = 0;
+ /* sms_info("timeout %d", time); */
+ break;
+ }
+ /* The time is within the range of this number of bits */
+ for (j = 0 ; j < i ; j++)
+ RC5_PUSH_BIT(ir_word, level, ir_pos)
+
+ break;
+ }
+}
+
+void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
+{
+ #define IR_DATA_RECEIVE_MAX_LEN 520 /* 128*4 + 4 + 4 */
+ u32 i;
+ enum ir_protocol ir_protocol =
+ keyboard_layout_maps[coredev->ir.ir_kb_type]
+ .ir_protocol;
+ s32 *samples;
+ int count = len>>2;
+
+ samples = (s32 *)buf;
+/* sms_info("IR buffer received, length = %d", count);*/
+
+ for (i = 0; i < count; i++)
+ if (ir_protocol == IR_RC5)
+ sms_rc5_accumulate_bits(coredev, samples[i]);
+ /* IR_RCMM not implemented */
+}
+
+int sms_ir_init(struct smscore_device_t *coredev)
+{
+ struct input_dev *input_dev;
+
+ sms_info("Allocating input device");
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ sms_err("Not enough memory");
+ return -ENOMEM;
+ }
+
+ coredev->ir.input_dev = input_dev;
+ coredev->ir.ir_kb_type =
+ sms_get_board(smscore_get_board_id(coredev))->ir_kb_type;
+ coredev->ir.keyboard_layout_map =
+ keyboard_layout_maps[coredev->ir.ir_kb_type].
+ keyboard_layout_map;
+ sms_info("IR remote keyboard type is %d", coredev->ir.ir_kb_type);
+
+ coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
+ coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
+ sms_info("IR port %d, timeout %d ms",
+ coredev->ir.controller, coredev->ir.timeout);
+
+ snprintf(coredev->ir.name,
+ IR_DEV_NAME_MAX_LEN,
+ "SMS IR w/kbd type %d",
+ coredev->ir.ir_kb_type);
+ input_dev->name = coredev->ir.name;
+ input_dev->phys = coredev->ir.name;
+ input_dev->dev.parent = coredev->device;
+
+ /* Key press events only */
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
+ input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+
+ sms_info("Input device (IR) %s is set for key events", input_dev->name);
+
+ if (input_register_device(input_dev)) {
+ sms_err("Failed to register device");
+ input_free_device(input_dev);
+ return -EACCES;
+ }
+
+ return 0;
+}
+
+void sms_ir_exit(struct smscore_device_t *coredev)
+{
+ if (coredev->ir.input_dev)
+ input_unregister_device(coredev->ir.input_dev);
+
+ sms_info("");
+}
+
diff --git a/drivers/media/dvb/siano/smsir.h b/drivers/media/dvb/siano/smsir.h
new file mode 100644
index 000000000000..b7d703e2d338
--- /dev/null
+++ b/drivers/media/dvb/siano/smsir.h
@@ -0,0 +1,93 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2009, Uri Shkolnik
+
+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 <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#ifndef __SMS_IR_H__
+#define __SMS_IR_H__
+
+#include <linux/input.h>
+
+#define IR_DEV_NAME_MAX_LEN 23 /* "SMS IR kbd type nn\0" */
+#define IR_KEYBOARD_LAYOUT_SIZE 64
+#define IR_DEFAULT_TIMEOUT 100
+
+enum ir_kb_type {
+ SMS_IR_KB_DEFAULT_TV,
+ SMS_IR_KB_HCW_SILVER
+};
+
+enum rc5_keyboard_address {
+ KEYBOARD_ADDRESS_TV1 = 0,
+ KEYBOARD_ADDRESS_TV2 = 1,
+ KEYBOARD_ADDRESS_TELETEXT = 2,
+ KEYBOARD_ADDRESS_VIDEO = 3,
+ KEYBOARD_ADDRESS_LV1 = 4,
+ KEYBOARD_ADDRESS_VCR1 = 5,
+ KEYBOARD_ADDRESS_VCR2 = 6,
+ KEYBOARD_ADDRESS_EXPERIMENTAL = 7,
+ KEYBOARD_ADDRESS_SAT1 = 8,
+ KEYBOARD_ADDRESS_CAMERA = 9,
+ KEYBOARD_ADDRESS_SAT2 = 10,
+ KEYBOARD_ADDRESS_CDV = 12,
+ KEYBOARD_ADDRESS_CAMCORDER = 13,
+ KEYBOARD_ADDRESS_PRE_AMP = 16,
+ KEYBOARD_ADDRESS_TUNER = 17,
+ KEYBOARD_ADDRESS_RECORDER1 = 18,
+ KEYBOARD_ADDRESS_PRE_AMP1 = 19,
+ KEYBOARD_ADDRESS_CD_PLAYER = 20,
+ KEYBOARD_ADDRESS_PHONO = 21,
+ KEYBOARD_ADDRESS_SATA = 22,
+ KEYBOARD_ADDRESS_RECORDER2 = 23,
+ KEYBOARD_ADDRESS_CDR = 26,
+ KEYBOARD_ADDRESS_LIGHTING = 29,
+ KEYBOARD_ADDRESS_LIGHTING1 = 30, /* KEYBOARD_ADDRESS_HCW_SILVER */
+ KEYBOARD_ADDRESS_PHONE = 31,
+ KEYBOARD_ADDRESS_NOT_RC5 = 0xFFFF
+};
+
+enum ir_protocol {
+ IR_RC5,
+ IR_RCMM
+};
+
+struct keyboard_layout_map_t {
+ enum ir_protocol ir_protocol;
+ enum rc5_keyboard_address rc5_kbd_address;
+ u16 keyboard_layout_map[IR_KEYBOARD_LAYOUT_SIZE];
+};
+
+struct smscore_device_t;
+
+struct ir_t {
+ struct input_dev *input_dev;
+ enum ir_kb_type ir_kb_type;
+ char name[IR_DEV_NAME_MAX_LEN+1];
+ u16 *keyboard_layout_map;
+ u32 timeout;
+ u32 controller;
+};
+
+int sms_ir_init(struct smscore_device_t *coredev);
+void sms_ir_exit(struct smscore_device_t *coredev);
+void sms_ir_event(struct smscore_device_t *coredev,
+ const char *buf, int len);
+
+#endif /* __SMS_IR_H__ */
+
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c
new file mode 100644
index 000000000000..4f8fa59a995a
--- /dev/null
+++ b/drivers/media/dvb/siano/smssdio.c
@@ -0,0 +1,354 @@
+/*
+ * smssdio.c - Siano 1xxx SDIO interface driver
+ *
+ * Copyright 2008 Pierre Ossman
+ *
+ * Based on code by Siano Mobile Silicon, Inc.,
+ * Copyright (C) 2006-2008, Uri Shkolnik
+ *
+ * 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 is a bit odd in that all transfers should be done
+ * to/from the SMSSDIO_DATA register, yet the "increase address" bit
+ * always needs to be set.
+ *
+ * Also, buffers from the card are always aligned to 128 byte
+ * boundaries.
+ */
+
+/*
+ * General cleanup notes:
+ *
+ * - only typedefs should be name *_t
+ *
+ * - use ERR_PTR and friends for smscore_register_device()
+ *
+ * - smscore_getbuffer should zero fields
+ *
+ * Fix stop command
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+
+/* Registers */
+
+#define SMSSDIO_DATA 0x00
+#define SMSSDIO_INT 0x04
+
+static const struct sdio_device_id smssdio_ids[] = {
+ {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
+ .driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
+ {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
+ .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A},
+ {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0),
+ .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B},
+ {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0),
+ .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
+ {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE),
+ .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
+ { /* end: all zeroes */ },
+};
+
+MODULE_DEVICE_TABLE(sdio, smssdio_ids);
+
+struct smssdio_device {
+ struct sdio_func *func;
+
+ struct smscore_device_t *coredev;
+
+ struct smscore_buffer_t *split_cb;
+};
+
+/*******************************************************************/
+/* Siano core callbacks */
+/*******************************************************************/
+
+static int smssdio_sendrequest(void *context, void *buffer, size_t size)
+{
+ int ret;
+ struct smssdio_device *smsdev;
+
+ smsdev = context;
+
+ sdio_claim_host(smsdev->func);
+
+ while (size >= smsdev->func->cur_blksize) {
+ ret = sdio_write_blocks(smsdev->func, SMSSDIO_DATA, buffer, 1);
+ if (ret)
+ goto out;
+
+ buffer += smsdev->func->cur_blksize;
+ size -= smsdev->func->cur_blksize;
+ }
+
+ if (size) {
+ ret = sdio_write_bytes(smsdev->func, SMSSDIO_DATA,
+ buffer, size);
+ }
+
+out:
+ sdio_release_host(smsdev->func);
+
+ return ret;
+}
+
+/*******************************************************************/
+/* SDIO callbacks */
+/*******************************************************************/
+
+static void smssdio_interrupt(struct sdio_func *func)
+{
+ int ret, isr;
+
+ struct smssdio_device *smsdev;
+ struct smscore_buffer_t *cb;
+ struct SmsMsgHdr_ST *hdr;
+ size_t size;
+
+ smsdev = sdio_get_drvdata(func);
+
+ /*
+ * The interrupt register has no defined meaning. It is just
+ * a way of turning of the level triggered interrupt.
+ */
+ isr = sdio_readb(func, SMSSDIO_INT, &ret);
+ if (ret) {
+ dev_err(&smsdev->func->dev,
+ "Unable to read interrupt register!\n");
+ return;
+ }
+
+ if (smsdev->split_cb == NULL) {
+ cb = smscore_getbuffer(smsdev->coredev);
+ if (!cb) {
+ dev_err(&smsdev->func->dev,
+ "Unable to allocate data buffer!\n");
+ return;
+ }
+
+ ret = sdio_read_blocks(smsdev->func, cb->p, SMSSDIO_DATA, 1);
+ if (ret) {
+ dev_err(&smsdev->func->dev,
+ "Error %d reading initial block!\n", ret);
+ return;
+ }
+
+ hdr = cb->p;
+
+ if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) {
+ smsdev->split_cb = cb;
+ return;
+ }
+
+ size = hdr->msgLength - smsdev->func->cur_blksize;
+ } else {
+ cb = smsdev->split_cb;
+ hdr = cb->p;
+
+ size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST);
+
+ smsdev->split_cb = NULL;
+ }
+
+ if (hdr->msgLength > smsdev->func->cur_blksize) {
+ void *buffer;
+
+ size = ALIGN(size, 128);
+ buffer = cb->p + hdr->msgLength;
+
+ BUG_ON(smsdev->func->cur_blksize != 128);
+
+ /*
+ * First attempt to transfer all of it in one go...
+ */
+ ret = sdio_read_blocks(smsdev->func, buffer,
+ SMSSDIO_DATA, size / 128);
+ if (ret && ret != -EINVAL) {
+ smscore_putbuffer(smsdev->coredev, cb);
+ dev_err(&smsdev->func->dev,
+ "Error %d reading data from card!\n", ret);
+ return;
+ }
+
+ /*
+ * ..then fall back to one block at a time if that is
+ * not possible...
+ *
+ * (we have to do this manually because of the
+ * problem with the "increase address" bit)
+ */
+ if (ret == -EINVAL) {
+ while (size) {
+ ret = sdio_read_blocks(smsdev->func,
+ buffer, SMSSDIO_DATA, 1);
+ if (ret) {
+ smscore_putbuffer(smsdev->coredev, cb);
+ dev_err(&smsdev->func->dev,
+ "Error %d reading "
+ "data from card!\n", ret);
+ return;
+ }
+
+ buffer += smsdev->func->cur_blksize;
+ if (size > smsdev->func->cur_blksize)
+ size -= smsdev->func->cur_blksize;
+ else
+ size = 0;
+ }
+ }
+ }
+
+ cb->size = hdr->msgLength;
+ cb->offset = 0;
+
+ smscore_onresponse(smsdev->coredev, cb);
+}
+
+static int smssdio_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ int ret;
+
+ int board_id;
+ struct smssdio_device *smsdev;
+ struct smsdevice_params_t params;
+
+ board_id = id->driver_data;
+
+ smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL);
+ if (!smsdev)
+ return -ENOMEM;
+
+ smsdev->func = func;
+
+ memset(&params, 0, sizeof(struct smsdevice_params_t));
+
+ params.device = &func->dev;
+ params.buffer_size = 0x5000; /* ?? */
+ params.num_buffers = 22; /* ?? */
+ params.context = smsdev;
+
+ snprintf(params.devpath, sizeof(params.devpath),
+ "sdio\\%s", sdio_func_id(func));
+
+ params.sendrequest_handler = smssdio_sendrequest;
+
+ params.device_type = sms_get_board(board_id)->type;
+
+ if (params.device_type != SMS_STELLAR)
+ params.flags |= SMS_DEVICE_FAMILY2;
+ else {
+ /*
+ * FIXME: Stellar needs special handling...
+ */
+ ret = -ENODEV;
+ goto free;
+ }
+
+ ret = smscore_register_device(&params, &smsdev->coredev);
+ if (ret < 0)
+ goto free;
+
+ smscore_set_board_id(smsdev->coredev, board_id);
+
+ sdio_claim_host(func);
+
+ ret = sdio_enable_func(func);
+ if (ret)
+ goto release;
+
+ ret = sdio_set_block_size(func, 128);
+ if (ret)
+ goto disable;
+
+ ret = sdio_claim_irq(func, smssdio_interrupt);
+ if (ret)
+ goto disable;
+
+ sdio_set_drvdata(func, smsdev);
+
+ sdio_release_host(func);
+
+ ret = smscore_start_device(smsdev->coredev);
+ if (ret < 0)
+ goto reclaim;
+
+ return 0;
+
+reclaim:
+ sdio_claim_host(func);
+ sdio_release_irq(func);
+disable:
+ sdio_disable_func(func);
+release:
+ sdio_release_host(func);
+ smscore_unregister_device(smsdev->coredev);
+free:
+ kfree(smsdev);
+
+ return ret;
+}
+
+static void smssdio_remove(struct sdio_func *func)
+{
+ struct smssdio_device *smsdev;
+
+ smsdev = sdio_get_drvdata(func);
+
+ /* FIXME: racy! */
+ if (smsdev->split_cb)
+ smscore_putbuffer(smsdev->coredev, smsdev->split_cb);
+
+ smscore_unregister_device(smsdev->coredev);
+
+ sdio_claim_host(func);
+ sdio_release_irq(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+
+ kfree(smsdev);
+}
+
+static struct sdio_driver smssdio_driver = {
+ .name = "smssdio",
+ .id_table = smssdio_ids,
+ .probe = smssdio_probe,
+ .remove = smssdio_remove,
+};
+
+/*******************************************************************/
+/* Module functions */
+/*******************************************************************/
+
+int smssdio_register(void)
+{
+ int ret = 0;
+
+ printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n");
+ printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n");
+
+ ret = sdio_register_driver(&smssdio_driver);
+
+ return ret;
+}
+
+void smssdio_unregister(void)
+{
+ sdio_unregister_driver(&smssdio_driver);
+}
+
+MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver");
+MODULE_AUTHOR("Pierre Ossman");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 5e3f88911a1d..e162691b515d 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -1089,7 +1089,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
else {
int i, len = dc->x0-dc->color+1;
u8 __user *colors = (u8 __user *)dc->data;
- u8 r, g, b, blend;
+ u8 r, g = 0, b = 0, blend = 0;
ret = 0;
for (i = 0; i<len; i++) {
if (get_user(r, colors + i * 4) ||
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 83e9e7750c8c..e48380c48990 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -47,6 +47,9 @@
#include "bsru6.h"
#include "bsbe1.h"
#include "tdhd1.h"
+#include "stv6110x.h"
+#include "stv090x.h"
+#include "isl6423.h"
static int diseqc_method;
module_param(diseqc_method, int, 0444);
@@ -425,6 +428,44 @@ static u8 read_pwm(struct budget* budget)
return pwm;
}
+static struct stv090x_config tt1600_stv090x_config = {
+ .device = STV0903,
+ .demod_mode = STV090x_SINGLE,
+ .clk_mode = STV090x_CLK_EXT,
+
+ .xtal = 27000000,
+ .address = 0x68,
+ .ref_clk = 27000000,
+
+ .ts1_mode = STV090x_TSMODE_DVBCI,
+ .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS,
+
+ .repeater_level = STV090x_RPTLEVEL_16,
+
+ .tuner_init = NULL,
+ .tuner_set_mode = NULL,
+ .tuner_set_frequency = NULL,
+ .tuner_get_frequency = NULL,
+ .tuner_set_bandwidth = NULL,
+ .tuner_get_bandwidth = NULL,
+ .tuner_set_bbgain = NULL,
+ .tuner_get_bbgain = NULL,
+ .tuner_set_refclk = NULL,
+ .tuner_get_status = NULL,
+};
+
+static struct stv6110x_config tt1600_stv6110x_config = {
+ .addr = 0x60,
+ .refclk = 27000000,
+};
+
+static struct isl6423_config tt1600_isl6423_config = {
+ .current_max = SEC_CURRENT_515m,
+ .curlim = SEC_CURRENT_LIM_ON,
+ .mod_extern = 1,
+ .addr = 0x08,
+};
+
static void frontend_init(struct budget *budget)
{
(void)alps_bsbe1_config; /* avoid warning */
@@ -566,6 +607,48 @@ static void frontend_init(struct budget *budget)
}
break;
}
+
+ case 0x101c: { /* TT S2-1600 */
+ struct stv6110x_devctl *ctl;
+ saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
+ msleep(50);
+ saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
+ msleep(250);
+
+ budget->dvb_frontend = dvb_attach(stv090x_attach,
+ &tt1600_stv090x_config,
+ &budget->i2c_adap,
+ STV090x_DEMODULATOR_0);
+
+ if (budget->dvb_frontend) {
+
+ ctl = dvb_attach(stv6110x_attach,
+ budget->dvb_frontend,
+ &tt1600_stv6110x_config,
+ &budget->i2c_adap);
+
+ tt1600_stv090x_config.tuner_init = ctl->tuner_init;
+ tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode;
+ tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
+ tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
+ tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+ tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+ tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain;
+ tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain;
+ tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk;
+ tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status;
+
+ dvb_attach(isl6423_attach,
+ budget->dvb_frontend,
+ &budget->i2c_adap,
+ &tt1600_isl6423_config);
+
+ } else {
+ dvb_frontend_detach(budget->dvb_frontend);
+ budget->dvb_frontend = NULL;
+ }
+ }
+ break;
}
if (budget->dvb_frontend == NULL) {
@@ -641,6 +724,7 @@ MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC);
MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT);
MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY);
MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY);
@@ -653,6 +737,7 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018),
+ MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c),
MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60),
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 1dba8f0832a0..5cf6c45b91fe 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -153,7 +153,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
v->rangelow = RSF16_MINFREQ / mult;
v->rangehigh = RSF16_MAXFREQ / mult;
- v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
v->capability = fmi->flags & V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_STEREO;
v->signal = fmi_getsigstr(fmi);
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index c09ca8600ea1..935ff9bcdfcc 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -233,7 +233,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
v->rangelow = RSF16_MINFREQ / mult;
v->rangehigh = RSF16_MAXFREQ / mult;
- v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW;
v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
V4L2_TUNER_MODE_MONO;
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index bd945d04dc90..640421ceb24a 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -1214,7 +1214,6 @@ static int si470x_fops_release(struct file *file)
usb_autopm_put_interface(radio->intf);
}
-unlock:
mutex_unlock(&radio->disconnect_lock);
done:
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 3f1a0350a569..7aefac64330f 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -134,10 +134,6 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/
obj-$(CONFIG_VIDEO_VIVI) += vivi.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885/
-obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
-obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
-obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
-obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
@@ -147,6 +143,11 @@ obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
+# soc-camera host drivers have to be linked after camera drivers
+obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
+obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
+obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
+obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
obj-$(CONFIG_VIDEO_AU0828) += au0828/
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index a99d92fac3dc..ebd1ee9dc871 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -389,6 +389,27 @@ int __devinit init_bttv_i2c(struct bttv *btv)
}
if (0 == btv->i2c_rc && i2c_scan)
do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
+
+ /* Instantiate the IR receiver device, if present */
+ if (0 == btv->i2c_rc) {
+ struct i2c_board_info info;
+ /* The external IR receiver is at i2c address 0x34 (0x35 for
+ reads). Future Hauppauge cards will have an internal
+ receiver at 0x30 (0x31 for reads). In theory, both can be
+ fitted, and Hauppauge suggest an external overrides an
+ internal.
+
+ That's why we probe 0x1a (~0x34) first. CB
+ */
+ const unsigned short addr_list[] = {
+ 0x1a, 0x18, 0x4b, 0x64, 0x30,
+ I2C_CLIENT_END
+ };
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list);
+ }
return btv->i2c_rc;
}
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 5f582726985d..c4d181dde1ca 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -774,6 +774,7 @@ static int cafe_cam_init(struct cafe_camera *cam)
ret = __cafe_cam_reset(cam);
if (ret)
goto out;
+ chip.ident = V4L2_IDENT_NONE;
chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
chip.match.addr = cam->sensor_addr;
ret = sensor_call(cam, core, g_chip_ident, &chip);
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index 7a8ad5963de8..35268923911c 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -26,14 +26,18 @@
#include "cx18-cards.h"
#include "cx18-audio.h"
-#define CX18_AUDIO_ENABLE 0xc72014
+#define CX18_AUDIO_ENABLE 0xc72014
+#define CX18_AI1_MUX_MASK 0x30
+#define CX18_AI1_MUX_I2S1 0x00
+#define CX18_AI1_MUX_I2S2 0x10
+#define CX18_AI1_MUX_843_I2S 0x20
/* Selects the audio input and output according to the current
settings. */
int cx18_audio_set_io(struct cx18 *cx)
{
const struct cx18_card_audio_input *in;
- u32 val;
+ u32 u, v;
int err;
/* Determine which input to use */
@@ -52,9 +56,37 @@ int cx18_audio_set_io(struct cx18 *cx)
return err;
/* FIXME - this internal mux should be abstracted to a subdev */
- val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30;
- val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
- (in->audio_input << 4);
- cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30);
+ u = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
+ v = u & ~CX18_AI1_MUX_MASK;
+ switch (in->audio_input) {
+ case CX18_AV_AUDIO_SERIAL1:
+ v |= CX18_AI1_MUX_I2S1;
+ break;
+ case CX18_AV_AUDIO_SERIAL2:
+ v |= CX18_AI1_MUX_I2S2;
+ break;
+ default:
+ v |= CX18_AI1_MUX_843_I2S;
+ break;
+ }
+ if (v == u) {
+ /* force a toggle of some AI1 MUX control bits */
+ u &= ~CX18_AI1_MUX_MASK;
+ switch (in->audio_input) {
+ case CX18_AV_AUDIO_SERIAL1:
+ u |= CX18_AI1_MUX_843_I2S;
+ break;
+ case CX18_AV_AUDIO_SERIAL2:
+ u |= CX18_AI1_MUX_843_I2S;
+ break;
+ default:
+ u |= CX18_AI1_MUX_I2S1;
+ break;
+ }
+ cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE,
+ u, CX18_AI1_MUX_MASK);
+ }
+ cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+ v, CX18_AI1_MUX_MASK);
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index cf2bd888a429..2b07b156340b 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -99,9 +99,39 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
or_value);
}
-static void cx18_av_initialize(struct cx18 *cx)
+static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
{
- struct cx18_av_state *state = &cx->av_state;
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ /*
+ * The crystal freq used in calculations in this driver will be
+ * 28.636360 MHz.
+ * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
+ */
+
+ /*
+ * VDCLK Integer = 0x0f, Post Divider = 0x04
+ * AIMCLK Integer = 0x0e, Post Divider = 0x16
+ */
+ cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
+
+ /* VDCLK Fraction = 0x2be2fe */
+ /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
+ cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
+
+ /* AIMCLK Fraction = 0x05227ad */
+ /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
+ cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
+
+ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
+ cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
+ return 0;
+}
+
+static void cx18_av_initialize(struct v4l2_subdev *sd)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
u32 v;
cx18_av_loadfw(cx);
@@ -150,6 +180,26 @@ static void cx18_av_initialize(struct cx18 *cx)
cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
+ /*
+ * Disable Video Auto-config of the Analog Front End and Video PLL.
+ *
+ * Since we only use BT.656 pixel mode, which works for both 525 and 625
+ * line systems, it's just easier for us to set registers
+ * 0x102 (CXADEC_CHIP_CTRL), 0x104-0x106 (CXADEC_AFE_CTRL),
+ * 0x108-0x109 (CXADEC_PLL_CTRL1), and 0x10c-0x10f (CXADEC_VID_PLL_FRAC)
+ * ourselves, than to run around cleaning up after the auto-config.
+ *
+ * (Note: my CX23418 chip doesn't seem to let the ACFG_DIS bit
+ * get set to 1, but OTOH, it doesn't seem to do AFE and VID PLL
+ * autoconfig either.)
+ *
+ * As a default, also turn off Dual mode for ADC2 and set ADC2 to CH3.
+ */
+ cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
+
+ /* Setup the Video and and Aux/Audio PLLs */
+ cx18_av_init(sd, 0);
+
/* set video to auto-detect */
/* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
/* set the comb notch = 1 */
@@ -176,12 +226,23 @@ static void cx18_av_initialize(struct cx18 *cx)
/* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
/* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
- v = cx18_av_read4(cx, CXADEC_AFE_CTRL);
- v &= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */
- v &= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */
- v &= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */
- /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */
- cx18_av_write4(cx, CXADEC_AFE_CTRL, v);
+ /*
+ * Analog Front End (AFE)
+ * Default to luma on ch1/ADC1, chroma on ch2/ADC2, SIF on ch3/ADC2
+ * bypass_ch[1-3] use filter
+ * droop_comp_ch[1-3] disable
+ * clamp_en_ch[1-3] disable
+ * aud_in_sel ADC2
+ * luma_in_sel ADC1
+ * chroma_in_sel ADC2
+ * clamp_sel_ch[2-3] midcode
+ * clamp_sel_ch1 video decoder
+ * vga_sel_ch3 audio decoder
+ * vga_sel_ch[1-2] video decoder
+ * half_bw_ch[1-3] disable
+ * +12db_ch[1-3] disable
+ */
+ cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00);
/* if(dwEnable && dw3DCombAvailable) { */
/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
@@ -195,50 +256,18 @@ static void cx18_av_initialize(struct cx18 *cx)
static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- cx18_av_initialize(cx);
- return 0;
-}
-
-static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- /*
- * The crystal freq used in calculations in this driver will be
- * 28.636360 MHz.
- * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
- */
-
- /*
- * VDCLK Integer = 0x0f, Post Divider = 0x04
- * AIMCLK Integer = 0x0e, Post Divider = 0x16
- */
- cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
-
- /* VDCLK Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
- cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
-
- /* AIMCLK Fraction = 0x05227ad */
- /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
- cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
- cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
+ cx18_av_initialize(sd);
return 0;
}
static int cx18_av_load_fw(struct v4l2_subdev *sd)
{
struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
if (!state->is_initialized) {
/* initialize on first use */
state->is_initialized = 1;
- cx18_av_initialize(cx);
+ cx18_av_initialize(sd);
}
return 0;
}
@@ -470,16 +499,23 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
{
struct cx18_av_state *state = &cx->av_state;
struct v4l2_subdev *sd = &state->sd;
- u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
- vid_input <= CX18_AV_COMPOSITE8);
- u8 reg;
- u8 v;
+
+ enum analog_signal_type {
+ NONE, CVBS, Y, C, SIF, Pb, Pr
+ } ch[3] = {NONE, NONE, NONE};
+
+ u8 afe_mux_cfg;
+ u8 adc2_cfg;
+ u32 afe_cfg;
+ int i;
CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
vid_input, aud_input);
- if (is_composite) {
- reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
+ if (vid_input >= CX18_AV_COMPOSITE1 &&
+ vid_input <= CX18_AV_COMPOSITE8) {
+ afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
+ ch[0] = CVBS;
} else {
int luma = vid_input & 0xf0;
int chroma = vid_input & 0xf00;
@@ -493,26 +529,45 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
vid_input);
return -EINVAL;
}
- reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
+ afe_mux_cfg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
+ ch[0] = Y;
if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
- reg &= 0x3f;
- reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
+ afe_mux_cfg &= 0x3f;
+ afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
+ ch[2] = C;
} else {
- reg &= 0xcf;
- reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
+ afe_mux_cfg &= 0xcf;
+ afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
+ ch[1] = C;
}
}
+ /* TODO: LeadTek WinFast DVR3100 H & WinFast PVR2100 can do Y/Pb/Pr */
switch (aud_input) {
case CX18_AV_AUDIO_SERIAL1:
case CX18_AV_AUDIO_SERIAL2:
/* do nothing, use serial audio input */
break;
- case CX18_AV_AUDIO4: reg &= ~0x30; break;
- case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
- case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
- case CX18_AV_AUDIO7: reg &= ~0xc0; break;
- case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
+ case CX18_AV_AUDIO4:
+ afe_mux_cfg &= ~0x30;
+ ch[1] = SIF;
+ break;
+ case CX18_AV_AUDIO5:
+ afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x10;
+ ch[1] = SIF;
+ break;
+ case CX18_AV_AUDIO6:
+ afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x20;
+ ch[1] = SIF;
+ break;
+ case CX18_AV_AUDIO7:
+ afe_mux_cfg &= ~0xc0;
+ ch[2] = SIF;
+ break;
+ case CX18_AV_AUDIO8:
+ afe_mux_cfg = (afe_mux_cfg & ~0xc0) | 0x40;
+ ch[2] = SIF;
+ break;
default:
CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
@@ -520,24 +575,65 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
return -EINVAL;
}
- cx18_av_write_expect(cx, 0x103, reg, reg, 0xf7);
+ /* Set up analog front end multiplexers */
+ cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7);
/* Set INPUT_MODE to Composite (0) or S-Video (1) */
- cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
+ cx18_av_and_or(cx, 0x401, ~0x6, ch[0] == CVBS ? 0 : 0x02);
/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
- v = cx18_av_read(cx, 0x102);
- if (reg & 0x80)
- v &= ~0x2;
+ adc2_cfg = cx18_av_read(cx, 0x102);
+ if (ch[2] == NONE)
+ adc2_cfg &= ~0x2; /* No sig on CH3, set ADC2 to CH2 for input */
else
- v |= 0x2;
+ adc2_cfg |= 0x2; /* Signal on CH3, set ADC2 to CH3 for input */
+
/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
- if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
- v |= 0x4;
+ if (ch[1] != NONE && ch[2] != NONE)
+ adc2_cfg |= 0x4; /* Set dual mode */
else
- v &= ~0x4;
- cx18_av_write_expect(cx, 0x102, v, v, 0x17);
+ adc2_cfg &= ~0x4; /* Clear dual mode */
+ cx18_av_write_expect(cx, 0x102, adc2_cfg, adc2_cfg, 0x17);
+
+ /* Configure the analog front end */
+ afe_cfg = cx18_av_read4(cx, CXADEC_AFE_CTRL);
+ afe_cfg &= 0xff000000;
+ afe_cfg |= 0x00005000; /* CHROMA_IN, AUD_IN: ADC2; LUMA_IN: ADC1 */
+ if (ch[1] != NONE && ch[2] != NONE)
+ afe_cfg |= 0x00000030; /* half_bw_ch[2-3] since in dual mode */
+
+ for (i = 0; i < 3; i++) {
+ switch (ch[i]) {
+ default:
+ case NONE:
+ /* CLAMP_SEL = Fixed to midcode clamp level */
+ afe_cfg |= (0x00000200 << i);
+ break;
+ case CVBS:
+ case Y:
+ if (i > 0)
+ afe_cfg |= 0x00002000; /* LUMA_IN_SEL: ADC2 */
+ break;
+ case C:
+ case Pb:
+ case Pr:
+ /* CLAMP_SEL = Fixed to midcode clamp level */
+ afe_cfg |= (0x00000200 << i);
+ if (i == 0 && ch[i] == C)
+ afe_cfg &= ~0x00001000; /* CHROMA_IN_SEL ADC1 */
+ break;
+ case SIF:
+ /*
+ * VGA_GAIN_SEL = Audio Decoder
+ * CLAMP_SEL = Fixed to midcode clamp level
+ */
+ afe_cfg |= (0x00000240 << i);
+ if (i == 0)
+ afe_cfg &= ~0x00004000; /* AUD_IN_SEL ADC1 */
+ break;
+ }
+ }
- /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/
+ cx18_av_write4(cx, CXADEC_AFE_CTRL, afe_cfg);
state->vid_input = vid_input;
state->aud_input = aud_input;
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index 49a55cc8d839..b9e8cc5d264a 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -24,15 +24,63 @@
#include "cx18-io.h"
#include <linux/firmware.h>
-#define CX18_AUDIO_ENABLE 0xc72014
+#define CX18_AUDIO_ENABLE 0xc72014
+#define CX18_AI1_MUX_MASK 0x30
+#define CX18_AI1_MUX_I2S1 0x00
+#define CX18_AI1_MUX_I2S2 0x10
+#define CX18_AI1_MUX_843_I2S 0x20
+#define CX18_AI1_MUX_INVALID 0x30
+
#define FWFILE "v4l-cx23418-dig.fw"
+static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw)
+{
+ struct v4l2_subdev *sd = &cx->av_state.sd;
+ int ret = 0;
+ const u8 *data;
+ u32 size;
+ int addr;
+ u32 expected, dl_control;
+
+ /* Ensure we put the 8051 in reset and enable firmware upload mode */
+ dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+ do {
+ dl_control &= 0x00ffffff;
+ dl_control |= 0x0f000000;
+ cx18_av_write4_noretry(cx, CXADEC_DL_CTL, dl_control);
+ dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+ } while ((dl_control & 0xff000000) != 0x0f000000);
+
+ /* Read and auto increment until at address 0x0000 */
+ while (dl_control & 0x3fff)
+ dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+
+ data = fw->data;
+ size = fw->size;
+ for (addr = 0; addr < size; addr++) {
+ dl_control &= 0xffff3fff; /* ignore top 2 bits of address */
+ expected = 0x0f000000 | ((u32)data[addr] << 16) | addr;
+ if (expected != dl_control) {
+ CX18_ERR_DEV(sd, "verification of %s firmware load "
+ "failed: expected %#010x got %#010x\n",
+ FWFILE, expected, dl_control);
+ ret = -EIO;
+ break;
+ }
+ dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+ }
+ if (ret == 0)
+ CX18_INFO_DEV(sd, "verified load of %s firmware (%d bytes)\n",
+ FWFILE, size);
+ return ret;
+}
+
int cx18_av_loadfw(struct cx18 *cx)
{
struct v4l2_subdev *sd = &cx->av_state.sd;
const struct firmware *fw = NULL;
u32 size;
- u32 v;
+ u32 u, v;
const u8 *ptr;
int i;
int retries1 = 0;
@@ -95,6 +143,12 @@ int cx18_av_loadfw(struct cx18 *cx)
}
cx18_av_write4_expect(cx, CXADEC_DL_CTL,
+ 0x03000000 | fw->size, 0x03000000, 0x13000000);
+
+ CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
+
+ if (cx18_av_verifyfw(cx, fw) == 0)
+ cx18_av_write4_expect(cx, CXADEC_DL_CTL,
0x13000000 | fw->size, 0x13000000, 0x13000000);
/* Output to the 416 */
@@ -135,6 +189,28 @@ int cx18_av_loadfw(struct cx18 *cx)
cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
0, 0x400);
+ /* Toggle the AI1 MUX */
+ v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
+ u = v & CX18_AI1_MUX_MASK;
+ v &= ~CX18_AI1_MUX_MASK;
+ if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) {
+ /* Switch to I2S1 */
+ v |= CX18_AI1_MUX_I2S1;
+ cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+ v, CX18_AI1_MUX_MASK);
+ /* Switch back to the A/V decoder core I2S output */
+ v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S;
+ } else {
+ /* Switch to the A/V decoder core I2S output */
+ v |= CX18_AI1_MUX_843_I2S;
+ cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+ v, CX18_AI1_MUX_MASK);
+ /* Switch back to I2S1 or I2S2 */
+ v = (v & ~CX18_AI1_MUX_MASK) | u;
+ }
+ cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+ v, CX18_AI1_MUX_MASK);
+
/* Enable WW auto audio standard detection */
v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
v |= 0xFF; /* Auto by default */
@@ -143,7 +219,5 @@ int cx18_av_loadfw(struct cx18 *cx)
cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);
release_firmware(fw);
-
- CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 82fc2f9d4021..8e35c3aed544 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -176,8 +176,10 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx,
return -EBUSY;
if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
- type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
- /* We don't do VBI insertion aside from IVTV format in a PS */
+ !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS ||
+ type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD ||
+ type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) {
+ /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */
cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
"the MPEG stream\n");
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 49b1c3d7b1a8..f0006edc635d 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -30,6 +30,7 @@
#include "cx18-irq.h"
#include "cx18-gpio.h"
#include "cx18-firmware.h"
+#include "cx18-queue.h"
#include "cx18-streams.h"
#include "cx18-av-core.h"
#include "cx18-scb.h"
@@ -546,6 +547,40 @@ done:
cx->card_i2c = cx->card->i2c;
}
+static int __devinit cx18_create_in_workq(struct cx18 *cx)
+{
+ snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
+ cx->v4l2_dev.name);
+ cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name);
+ if (cx->in_work_queue == NULL) {
+ CX18_ERR("Unable to create incoming mailbox handler thread\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int __devinit cx18_create_out_workq(struct cx18 *cx)
+{
+ snprintf(cx->out_workq_name, sizeof(cx->out_workq_name), "%s-out",
+ cx->v4l2_dev.name);
+ cx->out_work_queue = create_workqueue(cx->out_workq_name);
+ if (cx->out_work_queue == NULL) {
+ CX18_ERR("Unable to create outgoing mailbox handler threads\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
+{
+ int i;
+ for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
+ cx->in_work_order[i].cx = cx;
+ cx->in_work_order[i].str = cx->epu_debug_str;
+ INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler);
+ }
+}
+
/* Precondition: the cx18 structure has been memset to 0. Only
the dev and instance fields have been filled in.
No assumptions on the card type may be made here (see cx18_init_struct2
@@ -553,7 +588,7 @@ done:
*/
static int __devinit cx18_init_struct1(struct cx18 *cx)
{
- int i;
+ int ret;
cx->base_addr = pci_resource_start(cx->pci_dev, 0);
@@ -562,18 +597,18 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
mutex_init(&cx->epu2apu_mb_lock);
mutex_init(&cx->epu2cpu_mb_lock);
- cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name);
- if (cx->work_queue == NULL) {
- CX18_ERR("Unable to create work hander thread\n");
- return -ENOMEM;
- }
+ ret = cx18_create_out_workq(cx);
+ if (ret)
+ return ret;
- for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) {
- cx->epu_work_order[i].cx = cx;
- cx->epu_work_order[i].str = cx->epu_debug_str;
- INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler);
+ ret = cx18_create_in_workq(cx);
+ if (ret) {
+ destroy_workqueue(cx->out_work_queue);
+ return ret;
}
+ cx18_init_in_work_orders(cx);
+
/* start counting open_id at 1 */
cx->open_id = 1;
@@ -759,17 +794,17 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
retval = -ENODEV;
goto err;
}
- if (cx18_init_struct1(cx)) {
- retval = -ENOMEM;
+
+ retval = cx18_init_struct1(cx);
+ if (retval)
goto err;
- }
CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
/* PCI Device Setup */
retval = cx18_setup_pci(cx, pci_dev, pci_id);
if (retval != 0)
- goto free_workqueue;
+ goto free_workqueues;
/* map io memory */
CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
@@ -943,8 +978,9 @@ free_map:
cx18_iounmap(cx);
free_mem:
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
-free_workqueue:
- destroy_workqueue(cx->work_queue);
+free_workqueues:
+ destroy_workqueue(cx->in_work_queue);
+ destroy_workqueue(cx->out_work_queue);
err:
if (retval == 0)
retval = -ENODEV;
@@ -1053,11 +1089,19 @@ int cx18_init_on_first_open(struct cx18 *cx)
return 0;
}
-static void cx18_cancel_epu_work_orders(struct cx18 *cx)
+static void cx18_cancel_in_work_orders(struct cx18 *cx)
{
int i;
- for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++)
- cancel_work_sync(&cx->epu_work_order[i].work);
+ for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++)
+ cancel_work_sync(&cx->in_work_order[i].work);
+}
+
+static void cx18_cancel_out_work_orders(struct cx18 *cx)
+{
+ int i;
+ for (i = 0; i < CX18_MAX_STREAMS; i++)
+ if (&cx->streams[i].video_dev != NULL)
+ cancel_work_sync(&cx->streams[i].out_work_order);
}
static void cx18_remove(struct pci_dev *pci_dev)
@@ -1073,15 +1117,20 @@ static void cx18_remove(struct pci_dev *pci_dev)
if (atomic_read(&cx->tot_capturing) > 0)
cx18_stop_all_captures(cx);
- /* Interrupts */
+ /* Stop interrupts that cause incoming work to be queued */
cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
+
+ /* Incoming work can cause outgoing work, so clean up incoming first */
+ cx18_cancel_in_work_orders(cx);
+ cx18_cancel_out_work_orders(cx);
+
+ /* Stop ack interrupts that may have been needed for work to finish */
cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
cx18_halt_firmware(cx);
- cx18_cancel_epu_work_orders(cx);
-
- destroy_workqueue(cx->work_queue);
+ destroy_workqueue(cx->in_work_queue);
+ destroy_workqueue(cx->out_work_queue);
cx18_streams_cleanup(cx, 1);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index ece4f281ef42..f89b82367963 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -254,6 +254,7 @@ struct cx18_options {
#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
+#define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */
/* per-cx18, i_flags */
#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */
@@ -285,6 +286,7 @@ struct cx18_queue {
struct list_head list;
atomic_t buffers;
u32 bytesused;
+ spinlock_t lock;
};
struct cx18_dvb {
@@ -305,7 +307,7 @@ struct cx18_scb; /* forward reference */
#define CX18_MAX_MDL_ACKS 2
-#define CX18_MAX_EPU_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
+#define CX18_MAX_IN_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */
#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1
@@ -313,7 +315,7 @@ struct cx18_scb; /* forward reference */
#define CX18_F_EWO_MB_STALE \
(CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC)
-struct cx18_epu_work_order {
+struct cx18_in_work_order {
struct work_struct work;
atomic_t pending;
struct cx18 *cx;
@@ -337,7 +339,6 @@ struct cx18_stream {
unsigned mdl_offset;
u32 id;
- struct mutex qlock; /* locks access to the queues */
unsigned long s_flags; /* status flags, see above */
int dma; /* can be PCI_DMA_TODEVICE,
PCI_DMA_FROMDEVICE or
@@ -353,6 +354,8 @@ struct cx18_stream {
struct cx18_queue q_busy; /* busy buffers - in use by firmware */
struct cx18_queue q_full; /* full buffers - data for user apps */
+ struct work_struct out_work_order;
+
/* DVB / Digital Transport */
struct cx18_dvb dvb;
};
@@ -568,10 +571,14 @@ struct cx18 {
u32 sw2_irq_mask;
u32 hw2_irq_mask;
- struct workqueue_struct *work_queue;
- struct cx18_epu_work_order epu_work_order[CX18_MAX_EPU_WORK_ORDERS];
+ struct workqueue_struct *in_work_queue;
+ char in_workq_name[11]; /* "cx18-NN-in" */
+ struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
+ struct workqueue_struct *out_work_queue;
+ char out_workq_name[12]; /* "cx18-NN-out" */
+
/* i2c */
struct i2c_adapter i2c_adap[2];
struct i2c_algo_bit_data i2c_algo[2];
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 3b86f57cd15a..e7285a1096f2 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -23,6 +23,7 @@
#include "cx18-version.h"
#include "cx18-dvb.h"
#include "cx18-io.h"
+#include "cx18-queue.h"
#include "cx18-streams.h"
#include "cx18-cards.h"
#include "s5h1409.h"
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index b3889c0b2697..29969c18949c 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -265,8 +265,13 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
* an MPEG-2 Program Pack start code, and provide only
* up to that point to the user, so it's easy to insert VBI data
* the next time around.
+ *
+ * This will not work for an MPEG-2 TS and has only been
+ * verified by analysis to work for an MPEG-2 PS. Helen Buus
+ * pointed out this works for the CX23416 MPEG-2 DVD compatible
+ * stream, and research indicates both the MPEG 2 SVCD and DVD
+ * stream types use an MPEG-2 PS container.
*/
- /* FIXME - This only works for an MPEG-2 PS, not a TS */
/*
* An MPEG-2 Program Stream (PS) is a series of
* MPEG-2 Program Packs terminated by an
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 2226e5791e99..afe46c3d4057 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -131,7 +131,7 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
* Functions that run in a work_queue work handling context
*/
-static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order)
+static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
{
u32 handle, mdl_ack_count, id;
struct cx18_mailbox *mb;
@@ -191,29 +191,30 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order)
if (buf == NULL) {
CX18_WARN("Could not find buf %d for stream %s\n",
id, s->name);
- /* Put as many buffers as possible back into fw use */
- cx18_stream_load_fw_queue(s);
continue;
}
- if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) {
- CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n",
- buf->bytesused);
- dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
- buf->bytesused);
+ CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
+ s->name, buf->bytesused);
+
+ if (s->type != CX18_ENC_STREAM_TYPE_TS)
+ cx18_enqueue(s, buf, &s->q_full);
+ else {
+ if (s->dvb.enabled)
+ dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
+ buf->bytesused);
+ cx18_enqueue(s, buf, &s->q_free);
}
- /* Put as many buffers as possible back into fw use */
- cx18_stream_load_fw_queue(s);
- /* Put back TS buffer, since it was removed from all queues */
- if (s->type == CX18_ENC_STREAM_TYPE_TS)
- cx18_stream_put_buf_fw(s, buf);
}
+ /* Put as many buffers as possible back into fw use */
+ cx18_stream_load_fw_queue(s);
+
wake_up(&cx->dma_waitq);
if (s->id != -1)
wake_up(&s->waitq);
}
-static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order)
+static void epu_debug(struct cx18 *cx, struct cx18_in_work_order *order)
{
char *p;
char *str = order->str;
@@ -224,7 +225,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order)
CX18_INFO("FW version: %s\n", p - 1);
}
-static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order)
+static void epu_cmd(struct cx18 *cx, struct cx18_in_work_order *order)
{
switch (order->rpu) {
case CPU:
@@ -253,18 +254,18 @@ static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order)
}
static
-void free_epu_work_order(struct cx18 *cx, struct cx18_epu_work_order *order)
+void free_in_work_order(struct cx18 *cx, struct cx18_in_work_order *order)
{
atomic_set(&order->pending, 0);
}
-void cx18_epu_work_handler(struct work_struct *work)
+void cx18_in_work_handler(struct work_struct *work)
{
- struct cx18_epu_work_order *order =
- container_of(work, struct cx18_epu_work_order, work);
+ struct cx18_in_work_order *order =
+ container_of(work, struct cx18_in_work_order, work);
struct cx18 *cx = order->cx;
epu_cmd(cx, order);
- free_epu_work_order(cx, order);
+ free_in_work_order(cx, order);
}
@@ -272,7 +273,7 @@ void cx18_epu_work_handler(struct work_struct *work)
* Functions that run in an interrupt handling context
*/
-static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
+static void mb_ack_irq(struct cx18 *cx, struct cx18_in_work_order *order)
{
struct cx18_mailbox __iomem *ack_mb;
u32 ack_irq, req;
@@ -308,7 +309,7 @@ static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
return;
}
-static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
+static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order)
{
u32 handle, mdl_ack_offset, mdl_ack_count;
struct cx18_mailbox *mb;
@@ -334,7 +335,7 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
}
static
-int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
+int epu_debug_irq(struct cx18 *cx, struct cx18_in_work_order *order)
{
u32 str_offset;
char *str = order->str;
@@ -355,7 +356,7 @@ int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
}
static inline
-int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
+int epu_cmd_irq(struct cx18 *cx, struct cx18_in_work_order *order)
{
int ret = -1;
@@ -387,12 +388,12 @@ int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
}
static inline
-struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx)
+struct cx18_in_work_order *alloc_in_work_order_irq(struct cx18 *cx)
{
int i;
- struct cx18_epu_work_order *order = NULL;
+ struct cx18_in_work_order *order = NULL;
- for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) {
+ for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
/*
* We only need "pending" atomic to inspect its contents,
* and need not do a check and set because:
@@ -401,8 +402,8 @@ struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx)
* 2. "pending" is only set here, and we're serialized because
* we're called in an IRQ handler context.
*/
- if (atomic_read(&cx->epu_work_order[i].pending) == 0) {
- order = &cx->epu_work_order[i];
+ if (atomic_read(&cx->in_work_order[i].pending) == 0) {
+ order = &cx->in_work_order[i];
atomic_set(&order->pending, 1);
break;
}
@@ -414,7 +415,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
{
struct cx18_mailbox __iomem *mb;
struct cx18_mailbox *order_mb;
- struct cx18_epu_work_order *order;
+ struct cx18_in_work_order *order;
int submit;
switch (rpu) {
@@ -428,7 +429,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
return;
}
- order = alloc_epu_work_order_irq(cx);
+ order = alloc_in_work_order_irq(cx);
if (order == NULL) {
CX18_WARN("Unable to find blank work order form to schedule "
"incoming mailbox command processing\n");
@@ -461,7 +462,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
*/
submit = epu_cmd_irq(cx, order);
if (submit > 0) {
- queue_work(cx->work_queue, &order->work);
+ queue_work(cx->in_work_queue, &order->work);
}
}
@@ -478,9 +479,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
u32 __iomem *xpu_state;
wait_queue_head_t *waitq;
struct mutex *mb_lock;
- long int timeout, ret;
+ unsigned long int t0, timeout, ret;
int i;
char argstr[MAX_MB_ARGUMENTS*11+1];
+ DEFINE_WAIT(w);
if (info == NULL) {
CX18_WARN("unknown cmd %x\n", cmd);
@@ -562,25 +564,49 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
irq, info->name);
+
+ /* So we don't miss the wakeup, prepare to wait before notifying fw */
+ prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE);
cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
- ret = wait_event_timeout(
- *waitq,
- cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request),
- timeout);
+ t0 = jiffies;
+ ack = cx18_readl(cx, &mb->ack);
+ if (ack != req) {
+ schedule_timeout(timeout);
+ ret = jiffies - t0;
+ ack = cx18_readl(cx, &mb->ack);
+ } else {
+ ret = jiffies - t0;
+ }
- if (ret == 0) {
- /* Timed out */
+ finish_wait(waitq, &w);
+
+ if (req != ack) {
mutex_unlock(mb_lock);
- CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU "
- "acknowledgement\n",
- info->name, jiffies_to_msecs(timeout));
+ if (ret >= timeout) {
+ /* Timed out */
+ CX18_DEBUG_WARN("sending %s timed out waiting %d msecs "
+ "for RPU acknowledgement\n",
+ info->name, jiffies_to_msecs(ret));
+ } else {
+ CX18_DEBUG_WARN("woken up before mailbox ack was ready "
+ "after submitting %s to RPU. only "
+ "waited %d msecs on req %u but awakened"
+ " with unmatched ack %u\n",
+ info->name,
+ jiffies_to_msecs(ret),
+ req, ack);
+ }
return -EINVAL;
}
- if (ret != timeout)
+ if (ret >= timeout)
+ CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment "
+ "sending %s; timed out waiting %d msecs\n",
+ info->name, jiffies_to_msecs(ret));
+ else
CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
- jiffies_to_msecs(timeout-ret), info->name);
+ jiffies_to_msecs(ret), info->name);
/* Collect data returned by the XPU */
for (i = 0; i < MAX_MB_ARGUMENTS; i++)
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index ce2b6686aa00..e23aaac5b280 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -95,6 +95,6 @@ int cx18_api_func(void *priv, u32 cmd, int in, int out,
void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu);
-void cx18_epu_work_handler(struct work_struct *work);
+void cx18_in_work_handler(struct work_struct *work);
#endif
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 3046b8e74345..fa1ed7897d97 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -23,8 +23,8 @@
*/
#include "cx18-driver.h"
-#include "cx18-streams.h"
#include "cx18-queue.h"
+#include "cx18-streams.h"
#include "cx18-scb.h"
void cx18_buf_swap(struct cx18_buffer *buf)
@@ -53,13 +53,13 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
buf->skipped = 0;
}
- mutex_lock(&s->qlock);
-
/* q_busy is restricted to a max buffer count imposed by firmware */
if (q == &s->q_busy &&
atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM)
q = &s->q_free;
+ spin_lock(&q->lock);
+
if (to_front)
list_add(&buf->list, &q->list); /* LIFO */
else
@@ -67,7 +67,7 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
q->bytesused += buf->bytesused - buf->readpos;
atomic_inc(&q->buffers);
- mutex_unlock(&s->qlock);
+ spin_unlock(&q->lock);
return q;
}
@@ -75,7 +75,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
{
struct cx18_buffer *buf = NULL;
- mutex_lock(&s->qlock);
+ spin_lock(&q->lock);
if (!list_empty(&q->list)) {
buf = list_first_entry(&q->list, struct cx18_buffer, list);
list_del_init(&buf->list);
@@ -83,7 +83,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
buf->skipped = 0;
atomic_dec(&q->buffers);
}
- mutex_unlock(&s->qlock);
+ spin_unlock(&q->lock);
return buf;
}
@@ -94,9 +94,23 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
struct cx18_buffer *buf;
struct cx18_buffer *tmp;
struct cx18_buffer *ret = NULL;
-
- mutex_lock(&s->qlock);
+ LIST_HEAD(sweep_up);
+
+ /*
+ * We don't have to acquire multiple q locks here, because we are
+ * serialized by the single threaded work handler.
+ * Buffers from the firmware will thus remain in order as
+ * they are moved from q_busy to q_full or to the dvb ring buffer.
+ */
+ spin_lock(&s->q_busy.lock);
list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) {
+ /*
+ * We should find what the firmware told us is done,
+ * right at the front of the queue. If we don't, we likely have
+ * missed a buffer done message from the firmware.
+ * Once we skip a buffer repeatedly, relative to the size of
+ * q_busy, we have high confidence we've missed it.
+ */
if (buf->id != id) {
buf->skipped++;
if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) {
@@ -105,38 +119,41 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
"times - it must have dropped out of "
"rotation\n", s->name, buf->id,
buf->skipped);
- /* move it to q_free */
- list_move_tail(&buf->list, &s->q_free.list);
- buf->bytesused = buf->readpos = buf->b_flags =
- buf->skipped = 0;
+ /* Sweep it up to put it back into rotation */
+ list_move_tail(&buf->list, &sweep_up);
atomic_dec(&s->q_busy.buffers);
- atomic_inc(&s->q_free.buffers);
}
continue;
}
-
- buf->bytesused = bytesused;
- /* Sync the buffer before we release the qlock */
- cx18_buf_sync_for_cpu(s, buf);
- if (s->type == CX18_ENC_STREAM_TYPE_TS) {
- /*
- * TS doesn't use q_full. As we pull the buffer off of
- * the queue here, the caller will have to put it back.
- */
- list_del_init(&buf->list);
- } else {
- /* Move buffer from q_busy to q_full */
- list_move_tail(&buf->list, &s->q_full.list);
- set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
- s->q_full.bytesused += buf->bytesused;
- atomic_inc(&s->q_full.buffers);
- }
+ /*
+ * We pull the desired buffer off of the queue here. Something
+ * will have to put it back on a queue later.
+ */
+ list_del_init(&buf->list);
atomic_dec(&s->q_busy.buffers);
-
ret = buf;
break;
}
- mutex_unlock(&s->qlock);
+ spin_unlock(&s->q_busy.lock);
+
+ /*
+ * We found the buffer for which we were looking. Get it ready for
+ * the caller to put on q_full or in the dvb ring buffer.
+ */
+ if (ret != NULL) {
+ ret->bytesused = bytesused;
+ ret->skipped = 0;
+ /* readpos and b_flags were 0'ed when the buf went on q_busy */
+ cx18_buf_sync_for_cpu(s, ret);
+ if (s->type != CX18_ENC_STREAM_TYPE_TS)
+ set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags);
+ }
+
+ /* Put any buffers the firmware is ignoring back into normal rotation */
+ list_for_each_entry_safe(buf, tmp, &sweep_up, list) {
+ list_del_init(&buf->list);
+ cx18_enqueue(s, buf, &s->q_free);
+ }
return ret;
}
@@ -148,7 +165,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
if (q == &s->q_free)
return;
- mutex_lock(&s->qlock);
+ spin_lock(&q->lock);
while (!list_empty(&q->list)) {
buf = list_first_entry(&q->list, struct cx18_buffer, list);
list_move_tail(&buf->list, &s->q_free.list);
@@ -156,7 +173,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
atomic_inc(&s->q_free.buffers);
}
cx18_queue_init(q);
- mutex_unlock(&s->qlock);
+ spin_unlock(&q->lock);
}
void cx18_flush_queues(struct cx18_stream *s)
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 0932b76b2373..41a1b2618aac 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -116,12 +116,16 @@ static void cx18_stream_init(struct cx18 *cx, int type)
s->buffers = cx->stream_buffers[type];
s->buf_size = cx->stream_buf_size[type];
- mutex_init(&s->qlock);
init_waitqueue_head(&s->waitq);
s->id = -1;
+ spin_lock_init(&s->q_free.lock);
cx18_queue_init(&s->q_free);
+ spin_lock_init(&s->q_busy.lock);
cx18_queue_init(&s->q_busy);
+ spin_lock_init(&s->q_full.lock);
cx18_queue_init(&s->q_full);
+
+ INIT_WORK(&s->out_work_order, cx18_out_work_handler);
}
static int cx18_prep_dev(struct cx18 *cx, int type)
@@ -431,14 +435,16 @@ static void cx18_vbi_setup(struct cx18_stream *s)
cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
}
-struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
- struct cx18_buffer *buf)
+static
+struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s,
+ struct cx18_buffer *buf)
{
struct cx18 *cx = s->cx;
struct cx18_queue *q;
/* Don't give it to the firmware, if we're not running a capture */
if (s->handle == CX18_INVALID_TASK_HANDLE ||
+ test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
!test_bit(CX18_F_S_STREAMING, &s->s_flags))
return cx18_enqueue(s, buf, &s->q_free);
@@ -453,7 +459,8 @@ struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
return q;
}
-void cx18_stream_load_fw_queue(struct cx18_stream *s)
+static
+void _cx18_stream_load_fw_queue(struct cx18_stream *s)
{
struct cx18_queue *q;
struct cx18_buffer *buf;
@@ -467,11 +474,19 @@ void cx18_stream_load_fw_queue(struct cx18_stream *s)
buf = cx18_dequeue(s, &s->q_free);
if (buf == NULL)
break;
- q = cx18_stream_put_buf_fw(s, buf);
+ q = _cx18_stream_put_buf_fw(s, buf);
} while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM
&& q == &s->q_busy);
}
+void cx18_out_work_handler(struct work_struct *work)
+{
+ struct cx18_stream *s =
+ container_of(work, struct cx18_stream, out_work_order);
+
+ _cx18_stream_load_fw_queue(s);
+}
+
int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
{
u32 data[MAX_MB_ARGUMENTS];
@@ -600,19 +615,20 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
/* Init all the cpu_mdls for this stream */
cx18_flush_queues(s);
- mutex_lock(&s->qlock);
+ spin_lock(&s->q_free.lock);
list_for_each_entry(buf, &s->q_free.list, list) {
cx18_writel(cx, buf->dma_handle,
&cx->scb->cpu_mdl[buf->id].paddr);
cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
}
- mutex_unlock(&s->qlock);
- cx18_stream_load_fw_queue(s);
+ spin_unlock(&s->q_free.lock);
+ _cx18_stream_load_fw_queue(s);
/* begin_capture */
if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
CX18_DEBUG_WARN("Error starting capture!\n");
/* Ensure we're really not capturing before releasing MDLs */
+ set_bit(CX18_F_S_STOPPING, &s->s_flags);
if (s->type == CX18_ENC_STREAM_TYPE_MPG)
cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1);
else
@@ -622,6 +638,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
s->handle = CX18_INVALID_TASK_HANDLE;
+ clear_bit(CX18_F_S_STOPPING, &s->s_flags);
if (atomic_read(&cx->tot_capturing) == 0) {
set_bit(CX18_F_I_EOS, &cx->i_flags);
cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
@@ -666,6 +683,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
if (atomic_read(&cx->tot_capturing) == 0)
return 0;
+ set_bit(CX18_F_S_STOPPING, &s->s_flags);
if (s->type == CX18_ENC_STREAM_TYPE_MPG)
cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
else
@@ -689,6 +707,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
s->handle = CX18_INVALID_TASK_HANDLE;
+ clear_bit(CX18_F_S_STOPPING, &s->s_flags);
if (atomic_read(&cx->tot_capturing) > 0)
return 0;
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 420e0a172945..1afc3fd9d822 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -28,10 +28,24 @@ int cx18_streams_setup(struct cx18 *cx);
int cx18_streams_register(struct cx18 *cx);
void cx18_streams_cleanup(struct cx18 *cx, int unregister);
+/* Related to submission of buffers to firmware */
+static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
+{
+ struct cx18 *cx = s->cx;
+ queue_work(cx->out_work_queue, &s->out_work_order);
+}
+
+static inline void cx18_stream_put_buf_fw(struct cx18_stream *s,
+ struct cx18_buffer *buf)
+{
+ /* Put buf on q_free; the out work handler will move buf(s) to q_busy */
+ cx18_enqueue(s, buf, &s->q_free);
+ cx18_stream_load_fw_queue(s);
+}
+
+void cx18_out_work_handler(struct work_struct *work);
+
/* Capture related */
-void cx18_stream_load_fw_queue(struct cx18_stream *s);
-struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
- struct cx18_buffer *buf);
int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index bd9bd44da791..45494b094e7f 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -24,7 +24,7 @@
#define CX18_DRIVER_NAME "cx18"
#define CX18_DRIVER_VERSION_MAJOR 1
-#define CX18_DRIVER_VERSION_MINOR 1
+#define CX18_DRIVER_VERSION_MINOR 2
#define CX18_DRIVER_VERSION_PATCHLEVEL 0
#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index 1be3881be991..6a9464079b4c 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -29,7 +29,6 @@
#include <linux/bitmap.h>
#include <linux/usb.h>
#include <linux/i2c.h>
-#include <linux/version.h>
#include <linux/mm.h>
#include <linux/mutex.h>
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index c8a32b1b5381..63d2239fd324 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -281,12 +281,12 @@ static void cx231xx_config_tuner(struct cx231xx *dev)
}
/* ----------------------------------------------------------------------- */
-void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir)
+void cx231xx_register_i2c_ir(struct cx231xx *dev)
{
- if (disable_ir) {
- ir->get_key = NULL;
+ if (disable_ir)
return;
- }
+
+ /* REVISIT: instantiate IR device */
/* detect & configure */
switch (dev->model) {
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c
index b4a03d813e00..33219dc4d649 100644
--- a/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/video/cx231xx/cx231xx-i2c.c
@@ -424,34 +424,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
}
-/*
- * attach_inform()
- * gets called when a device attaches to the i2c bus
- * does some basic configuration
- */
-static int attach_inform(struct i2c_client *client)
-{
- struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter);
- struct cx231xx *dev = bus->dev;
-
- switch (client->addr << 1) {
- case 0x8e:
- {
- struct IR_i2c *ir = i2c_get_clientdata(client);
- dprintk1(1, "attach_inform: IR detected (%s).\n",
- ir->phys);
- cx231xx_set_ir(dev, ir);
- break;
- }
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
static struct i2c_algorithm cx231xx_algo = {
.master_xfer = cx231xx_i2c_xfer,
.functionality = functionality,
@@ -462,7 +434,6 @@ static struct i2c_adapter cx231xx_adap_template = {
.name = "cx231xx",
.id = I2C_HW_B_CX231XX,
.algo = &cx231xx_algo,
- .client_register = attach_inform,
};
static struct i2c_client cx231xx_client_template = {
@@ -537,6 +508,9 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus)
if (0 == bus->i2c_rc) {
if (i2c_scan)
cx231xx_do_i2c_scan(dev, &bus->i2c_client);
+
+ /* Instantiate the IR receiver device, if present */
+ cx231xx_register_i2c_ir(dev);
} else
cx231xx_warn("%s: i2c bus %d register FAILED\n",
dev->name, bus->nr);
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index 97e304c3c799..48f22fa38e6c 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
#define i2cdprintk(fmt, arg...) \
if (ir_debug) { \
- printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
}
#define dprintk(fmt, arg...) \
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c
index 94180526909c..e97b8023a655 100644
--- a/drivers/media/video/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/video/cx231xx/cx231xx-vbi.c
@@ -26,7 +26,6 @@
#include <linux/bitmap.h>
#include <linux/usb.h>
#include <linux/i2c.h>
-#include <linux/version.h>
#include <linux/mm.h>
#include <linux/mutex.h>
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index aa4a23ef491a..e38eb2d425f7 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -738,7 +738,7 @@ extern void cx231xx_card_setup(struct cx231xx *dev);
extern struct cx231xx_board cx231xx_boards[];
extern struct usb_device_id cx231xx_id_table[];
extern const unsigned int cx231xx_bcount;
-void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir);
+void cx231xx_register_i2c_ir(struct cx231xx *dev);
int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
/* Provided by cx231xx-input.c */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index beda42925ce7..9e4d37eb918e 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1700,9 +1700,13 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
}
if (cx23885_boards[dev->board].cimax > 0 &&
- ((pci_status & PCI_MSK_GPIO0) || (pci_status & PCI_MSK_GPIO1)))
- /* handled += cx23885_irq_gpio(dev, pci_status); */
- handled += netup_ci_slot_status(dev, pci_status);
+ ((pci_status & PCI_MSK_GPIO0) ||
+ (pci_status & PCI_MSK_GPIO1))) {
+
+ if (cx23885_boards[dev->board].cimax > 0)
+ handled += netup_ci_slot_status(dev, pci_status);
+
+ }
if (ts1_status) {
if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 0c49a98213c4..07b76053a050 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -122,7 +122,9 @@ static struct tda10048_config hauppauge_hvr1200_config = {
.demod_address = 0x10 >> 1,
.output_mode = TDA10048_SERIAL_OUTPUT,
.fwbulkwritelen = TDA10048_BULKWRITE_200,
- .inversion = TDA10048_INVERSION_ON
+ .inversion = TDA10048_INVERSION_ON,
+ .if_freq_khz = TDA10048_IF_4300,
+ .clk_freq_khz = TDA10048_CLK_16000,
};
static struct s5h1409_config hauppauge_ezqam_config = {
@@ -472,7 +474,7 @@ static int dvb_register(struct cx23885_tsport *port)
static struct xc2028_ctrl ctl = {
.fname = XC2028_DEFAULT_FIRMWARE,
.max_len = 64,
- .scode_table = XC3028_FE_OREN538,
+ .demod = XC3028_FE_OREN538,
};
fe = dvb_attach(xc2028_attach,
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index 3421bd12056a..384dec34134f 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -357,6 +357,18 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
dev->name, bus->nr);
+ /* Instantiate the IR receiver device, if present */
+ if (0 == bus->i2c_rc) {
+ struct i2c_board_info info;
+ const unsigned short addr_list[] = {
+ 0x6b, I2C_CLIENT_END
+ };
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ i2c_new_probed_device(&bus->i2c_adap, &info, addr_list);
+ }
+
return bus->i2c_rc;
}
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index b06b1275a9ec..5b7e26761f0a 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -1,5 +1,5 @@
cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \
- cx88-input.o
+ cx88-dsp.o cx88-input.o
cx8800-objs := cx88-video.o cx88-vbi.o
cx8802-objs := cx88-mpeg.o
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 6bbbfc66bb4b..1039757e2c4e 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1969,6 +1969,13 @@ static const struct cx88_board cx88_boards[] = {
},
.mpeg = CX88_MPEG_DVB,
},
+ [CX88_BOARD_HAUPPAUGE_IRONLY] = {
+ .name = "Hauppauge WinTV-IR Only",
+ .tuner_type = UNSET,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
};
/* ------------------------------------------------------------------ */
@@ -2382,6 +2389,10 @@ static const struct cx88_subid cx88_subids[] = {
.subvendor = 0x153b,
.subdevice = 0x1177,
.card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x9290,
+ .card = CX88_BOARD_HAUPPAUGE_IRONLY,
},
};
@@ -2448,6 +2459,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
case 90500: /* Nova-T-PCI (oem) */
case 90501: /* Nova-T-PCI (oem/IR) */
case 92000: /* Nova-SE2 (OEM, No Video or IR) */
+ case 92900: /* WinTV-IROnly (No analog or digital Video inputs) */
case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */
@@ -2907,6 +2919,7 @@ static void cx88_card_setup(struct cx88_core *core)
case CX88_BOARD_HAUPPAUGE_HVR1300:
case CX88_BOARD_HAUPPAUGE_HVR4000:
case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
+ case CX88_BOARD_HAUPPAUGE_IRONLY:
if (0 == core->i2c_rc)
hauppauge_eeprom(core, eeprom);
break;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 0e149b22bd19..a3548c7f9dbb 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -231,7 +231,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
* can use the whole SDRAM for the DMA fifos. To simplify things, we
* use a static memory layout. That surely will waste memory in case
* we don't use all DMA channels at the same time (which will be the
- * case most of the time). But that still gives us enougth FIFO space
+ * case most of the time). But that still gives us enough FIFO space
* to be able to deal with insane long pci latencies ...
*
* FIFO space allocations:
@@ -241,6 +241,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
* channel 24 (vbi) - 4.0k
* channels 25+26 (audio) - 4.0k
* channel 28 (mpeg) - 4.0k
+ * channel 27 (audio rds)- 3.0k
* TOTAL = 29.0k
*
* Every channel has 160 bytes control data (64 bytes instruction
@@ -337,6 +338,18 @@ struct sram_channel cx88_sram_channels[] = {
.cnt1_reg = MO_DMA28_CNT1,
.cnt2_reg = MO_DMA28_CNT2,
},
+ [SRAM_CH27] = {
+ .name = "audio rds",
+ .cmds_start = 0x1801C0,
+ .ctrl_start = 0x180860,
+ .cdt = 0x180860 + 64,
+ .fifo_start = 0x187400,
+ .fifo_size = 0x000C00,
+ .ptr1_reg = MO_DMA27_PTR1,
+ .ptr2_reg = MO_DMA27_PTR2,
+ .cnt1_reg = MO_DMA27_CNT1,
+ .cnt2_reg = MO_DMA27_CNT2,
+ },
};
int cx88_sram_channel_setup(struct cx88_core *core,
@@ -598,6 +611,7 @@ int cx88_reset(struct cx88_core *core)
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
+ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0);
/* misc init ... */
cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable
@@ -796,6 +810,8 @@ int cx88_start_audio_dma(struct cx88_core *core)
/* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
+ int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size/AUD_RDS_LINES;
+
/* If downstream RISC is enabled, bail out; ALSA is managing DMA */
if (cx_read(MO_AUD_DMACNTRL) & 0x10)
return 0;
@@ -803,12 +819,14 @@ int cx88_start_audio_dma(struct cx88_core *core)
/* setup fifo + format */
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
+ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27],
+ rds_bpl, 0);
cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
- cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */
+ cx_write(MO_AUDR_LNGTH, rds_bpl); /* fifo bpl size */
- /* start dma */
- cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
+ /* enable Up, Down and Audio RDS fifo */
+ cx_write(MO_AUD_DMACNTRL, 0x0007);
return 0;
}
diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c
new file mode 100644
index 000000000000..3e5eaf3fe2a6
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-dsp.c
@@ -0,0 +1,312 @@
+/*
+ *
+ * Stereo and SAP detection for cx88
+ *
+ * Copyright (c) 2009 Marton Balint <cus@fazekas.hu>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <asm/div64.h>
+
+#include "cx88.h"
+#include "cx88-reg.h"
+
+#define INT_PI ((s32)(3.141592653589 * 32768.0))
+
+#define compat_remainder(a, b) \
+ ((float)(((s32)((a)*100))%((s32)((b)*100)))/100.0)
+
+#define baseband_freq(carrier, srate, tone) ((s32)( \
+ (compat_remainder(carrier + tone, srate)) / srate * 2 * INT_PI))
+
+/* We calculate the baseband frequencies of the carrier and the pilot tones
+ * based on the the sampling rate of the audio rds fifo. */
+
+#define FREQ_A2_CARRIER baseband_freq(54687.5, 2689.36, 0.0)
+#define FREQ_A2_DUAL baseband_freq(54687.5, 2689.36, 274.1)
+#define FREQ_A2_STEREO baseband_freq(54687.5, 2689.36, 117.5)
+
+/* The frequencies below are from the reference driver. They probably need
+ * further adjustments, because they are not tested at all. You may even need
+ * to play a bit with the registers of the chip to select the proper signal
+ * for the input of the audio rds fifo, and measure it's sampling rate to
+ * calculate the proper baseband frequencies... */
+
+#define FREQ_A2M_CARRIER ((s32)(2.114516 * 32768.0))
+#define FREQ_A2M_DUAL ((s32)(2.754916 * 32768.0))
+#define FREQ_A2M_STEREO ((s32)(2.462326 * 32768.0))
+
+#define FREQ_EIAJ_CARRIER ((s32)(1.963495 * 32768.0)) /* 5pi/8 */
+#define FREQ_EIAJ_DUAL ((s32)(2.562118 * 32768.0))
+#define FREQ_EIAJ_STEREO ((s32)(2.601053 * 32768.0))
+
+#define FREQ_BTSC_DUAL ((s32)(1.963495 * 32768.0)) /* 5pi/8 */
+#define FREQ_BTSC_DUAL_REF ((s32)(1.374446 * 32768.0)) /* 7pi/16 */
+
+#define FREQ_BTSC_SAP ((s32)(2.471532 * 32768.0))
+#define FREQ_BTSC_SAP_REF ((s32)(1.730072 * 32768.0))
+
+/* The spectrum of the signal should be empty between these frequencies. */
+#define FREQ_NOISE_START ((s32)(0.100000 * 32768.0))
+#define FREQ_NOISE_END ((s32)(1.200000 * 32768.0))
+
+static unsigned int dsp_debug;
+module_param(dsp_debug, int, 0644);
+MODULE_PARM_DESC(dsp_debug, "enable audio dsp debug messages");
+
+#define dprintk(level, fmt, arg...) if (dsp_debug >= level) \
+ printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
+
+static s32 int_cos(u32 x)
+{
+ u32 t2, t4, t6, t8;
+ s32 ret;
+ u16 period = x / INT_PI;
+ if (period % 2)
+ return -int_cos(x - INT_PI);
+ x = x % INT_PI;
+ if (x > INT_PI/2)
+ return -int_cos(INT_PI/2 - (x % (INT_PI/2)));
+ /* Now x is between 0 and INT_PI/2.
+ * To calculate cos(x) we use it's Taylor polinom. */
+ t2 = x*x/32768/2;
+ t4 = t2*x/32768*x/32768/3/4;
+ t6 = t4*x/32768*x/32768/5/6;
+ t8 = t6*x/32768*x/32768/7/8;
+ ret = 32768-t2+t4-t6+t8;
+ return ret;
+}
+
+static u32 int_goertzel(s16 x[], u32 N, u32 freq)
+{
+ /* We use the Goertzel algorithm to determine the power of the
+ * given frequency in the signal */
+ s32 s_prev = 0;
+ s32 s_prev2 = 0;
+ s32 coeff = 2*int_cos(freq);
+ u32 i;
+
+ u64 tmp;
+ u32 divisor;
+
+ for (i = 0; i < N; i++) {
+ s32 s = x[i] + ((s64)coeff*s_prev/32768) - s_prev2;
+ s_prev2 = s_prev;
+ s_prev = s;
+ }
+
+ tmp = (s64)s_prev2 * s_prev2 + (s64)s_prev * s_prev -
+ (s64)coeff * s_prev2 * s_prev / 32768;
+
+ /* XXX: N must be low enough so that N*N fits in s32.
+ * Else we need two divisions. */
+ divisor = N * N;
+ do_div(tmp, divisor);
+
+ return (u32) tmp;
+}
+
+static u32 freq_magnitude(s16 x[], u32 N, u32 freq)
+{
+ u32 sum = int_goertzel(x, N, freq);
+ return (u32)int_sqrt(sum);
+}
+
+static u32 noise_magnitude(s16 x[], u32 N, u32 freq_start, u32 freq_end)
+{
+ int i;
+ u32 sum = 0;
+ u32 freq_step;
+ int samples = 5;
+
+ if (N > 192) {
+ /* The last 192 samples are enough for noise detection */
+ x += (N-192);
+ N = 192;
+ }
+
+ freq_step = (freq_end - freq_start) / (samples - 1);
+
+ for (i = 0; i < samples; i++) {
+ sum += int_goertzel(x, N, freq_start);
+ freq_start += freq_step;
+ }
+
+ return (u32)int_sqrt(sum / samples);
+}
+
+static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N)
+{
+ s32 carrier, stereo, dual, noise;
+ s32 carrier_freq, stereo_freq, dual_freq;
+ s32 ret;
+
+ switch (core->tvaudio) {
+ case WW_BG:
+ case WW_DK:
+ carrier_freq = FREQ_A2_CARRIER;
+ stereo_freq = FREQ_A2_STEREO;
+ dual_freq = FREQ_A2_DUAL;
+ break;
+ case WW_M:
+ carrier_freq = FREQ_A2M_CARRIER;
+ stereo_freq = FREQ_A2M_STEREO;
+ dual_freq = FREQ_A2M_DUAL;
+ break;
+ case WW_EIAJ:
+ carrier_freq = FREQ_EIAJ_CARRIER;
+ stereo_freq = FREQ_EIAJ_STEREO;
+ dual_freq = FREQ_EIAJ_DUAL;
+ break;
+ default:
+ printk(KERN_WARNING "%s/0: unsupported audio mode %d for %s\n",
+ core->name, core->tvaudio, __func__);
+ return UNSET;
+ }
+
+ carrier = freq_magnitude(x, N, carrier_freq);
+ stereo = freq_magnitude(x, N, stereo_freq);
+ dual = freq_magnitude(x, N, dual_freq);
+ noise = noise_magnitude(x, N, FREQ_NOISE_START, FREQ_NOISE_END);
+
+ dprintk(1, "detect a2/a2m/eiaj: carrier=%d, stereo=%d, dual=%d, "
+ "noise=%d\n", carrier, stereo, dual, noise);
+
+ if (stereo > dual)
+ ret = V4L2_TUNER_SUB_STEREO;
+ else
+ ret = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+
+ if (core->tvaudio == WW_EIAJ) {
+ /* EIAJ checks may need adjustments */
+ if ((carrier > max(stereo, dual)*2) &&
+ (carrier < max(stereo, dual)*6) &&
+ (carrier > 20 && carrier < 200) &&
+ (max(stereo, dual) > min(stereo, dual))) {
+ /* For EIAJ the carrier is always present,
+ so we probably don't need noise detection */
+ return ret;
+ }
+ } else {
+ if ((carrier > max(stereo, dual)*2) &&
+ (carrier < max(stereo, dual)*8) &&
+ (carrier > 20 && carrier < 200) &&
+ (noise < 10) &&
+ (max(stereo, dual) > min(stereo, dual)*2)) {
+ return ret;
+ }
+ }
+ return V4L2_TUNER_SUB_MONO;
+}
+
+static s32 detect_btsc(struct cx88_core *core, s16 x[], u32 N)
+{
+ s32 sap_ref = freq_magnitude(x, N, FREQ_BTSC_SAP_REF);
+ s32 sap = freq_magnitude(x, N, FREQ_BTSC_SAP);
+ s32 dual_ref = freq_magnitude(x, N, FREQ_BTSC_DUAL_REF);
+ s32 dual = freq_magnitude(x, N, FREQ_BTSC_DUAL);
+ dprintk(1, "detect btsc: dual_ref=%d, dual=%d, sap_ref=%d, sap=%d"
+ "\n", dual_ref, dual, sap_ref, sap);
+ /* FIXME: Currently not supported */
+ return UNSET;
+}
+
+static s16 *read_rds_samples(struct cx88_core *core, u32 *N)
+{
+ struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27];
+ s16 *samples;
+
+ unsigned int i;
+ unsigned int bpl = srch->fifo_size/AUD_RDS_LINES;
+ unsigned int spl = bpl/4;
+ unsigned int sample_count = spl*(AUD_RDS_LINES-1);
+
+ u32 current_address = cx_read(srch->ptr1_reg);
+ u32 offset = (current_address - srch->fifo_start + bpl);
+
+ dprintk(1, "read RDS samples: current_address=%08x (offset=%08x), "
+ "sample_count=%d, aud_intstat=%08x\n", current_address,
+ current_address - srch->fifo_start, sample_count,
+ cx_read(MO_AUD_INTSTAT));
+
+ samples = kmalloc(sizeof(s16)*sample_count, GFP_KERNEL);
+ if (!samples)
+ return NULL;
+
+ *N = sample_count;
+
+ for (i = 0; i < sample_count; i++) {
+ offset = offset % (AUD_RDS_LINES*bpl);
+ samples[i] = cx_read(srch->fifo_start + offset);
+ offset += 4;
+ }
+
+ if (dsp_debug >= 2) {
+ dprintk(2, "RDS samples dump: ");
+ for (i = 0; i < sample_count; i++)
+ printk("%hd ", samples[i]);
+ printk(".\n");
+ }
+
+ return samples;
+}
+
+s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core)
+{
+ s16 *samples;
+ u32 N = 0;
+ s32 ret = UNSET;
+
+ /* If audio RDS fifo is disabled, we can't read the samples */
+ if (!(cx_read(MO_AUD_DMACNTRL) & 0x04))
+ return ret;
+ if (!(cx_read(AUD_CTL) & EN_FMRADIO_EN_RDS))
+ return ret;
+
+ /* Wait at least 500 ms after an audio standard change */
+ if (time_before(jiffies, core->last_change + msecs_to_jiffies(500)))
+ return ret;
+
+ samples = read_rds_samples(core, &N);
+
+ if (!samples)
+ return ret;
+
+ switch (core->tvaudio) {
+ case WW_BG:
+ case WW_DK:
+ ret = detect_a2_a2m_eiaj(core, samples, N);
+ break;
+ case WW_BTSC:
+ ret = detect_btsc(core, samples, N);
+ break;
+ }
+
+ kfree(samples);
+
+ if (UNSET != ret)
+ dprintk(1, "stereo/sap detection result:%s%s%s\n",
+ (ret & V4L2_TUNER_SUB_MONO) ? " mono" : "",
+ (ret & V4L2_TUNER_SUB_STEREO) ? " stereo" : "",
+ (ret & V4L2_TUNER_SUB_LANG2) ? " dual" : "");
+
+ return ret;
+}
+EXPORT_SYMBOL(cx88_dsp_detect_stereo_sap);
+
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 996b4ed5a4fc..ee1ca39db06a 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -180,6 +180,19 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
do_i2c_scan(core->name,&core->i2c_client);
} else
printk("%s: i2c register FAILED\n", core->name);
+
+ /* Instantiate the IR receiver device, if present */
+ if (0 == core->i2c_rc) {
+ struct i2c_board_info info;
+ const unsigned short addr_list[] = {
+ 0x18, 0x6b, 0x71,
+ I2C_CLIENT_END
+ };
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ i2c_new_probed_device(&core->i2c_adap, &info, addr_list);
+ }
return core->i2c_rc;
}
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index ec05312a9b62..bd2baa76203f 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -217,6 +217,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
case CX88_BOARD_PCHDTV_HD3000:
case CX88_BOARD_PCHDTV_HD5500:
+ case CX88_BOARD_HAUPPAUGE_IRONLY:
ir_codes = ir_codes_hauppauge_new;
ir_type = IR_TYPE_RC5;
ir->sampling = 1;
@@ -459,6 +460,7 @@ void cx88_ir_irq(struct cx88_core *core)
case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
case CX88_BOARD_PCHDTV_HD3000:
case CX88_BOARD_PCHDTV_HD5500:
+ case CX88_BOARD_HAUPPAUGE_IRONLY:
ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
ir_dprintk("biphase decoded: %x\n", ircode);
/*
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 7dd506b987fe..e8316cf7f32f 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -163,6 +163,8 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
/* unmute */
volume = cx_sread(SHADOW_AUD_VOL_CTL);
cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume);
+
+ core->last_change = jiffies;
}
/* ----------------------------------------------------------- */
@@ -745,6 +747,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
break;
case WW_BG:
case WW_DK:
+ case WW_M:
case WW_I:
case WW_L:
/* prepare all dsp registers */
@@ -756,6 +759,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
if (0 == cx88_detect_nicam(core)) {
/* fall back to fm / am mono */
set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
+ core->audiomode_current = V4L2_TUNER_MODE_MONO;
core->use_nicam = 0;
} else {
core->use_nicam = 1;
@@ -787,6 +791,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
void cx88_newstation(struct cx88_core *core)
{
core->audiomode_manual = UNSET;
+ core->last_change = jiffies;
}
void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
@@ -805,12 +810,50 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
aud_ctl_names[cx_read(AUD_CTL) & 63]);
core->astat = reg;
-/* TODO
- Reading from AUD_STATUS is not enough
- for auto-detecting sap/dual-fm/nicam.
- Add some code here later.
-*/
+ t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
+ V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
+ t->rxsubchans = UNSET;
+ t->audmode = V4L2_TUNER_MODE_MONO;
+
+ switch (mode) {
+ case 0:
+ t->audmode = V4L2_TUNER_MODE_STEREO;
+ break;
+ case 1:
+ t->audmode = V4L2_TUNER_MODE_LANG2;
+ break;
+ case 2:
+ t->audmode = V4L2_TUNER_MODE_MONO;
+ break;
+ case 3:
+ t->audmode = V4L2_TUNER_MODE_SAP;
+ break;
+ }
+ switch (core->tvaudio) {
+ case WW_BTSC:
+ case WW_BG:
+ case WW_DK:
+ case WW_M:
+ case WW_EIAJ:
+ if (!core->use_nicam) {
+ t->rxsubchans = cx88_dsp_detect_stereo_sap(core);
+ break;
+ }
+ break;
+ default:
+ /* nothing */
+ break;
+ }
+
+ /* If software stereo detection is not supported... */
+ if (UNSET == t->rxsubchans) {
+ t->rxsubchans = V4L2_TUNER_SUB_MONO;
+ /* If the hardware itself detected stereo, also return
+ stereo as an available subchannel */
+ if (V4L2_TUNER_MODE_STEREO == t->audmode)
+ t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
+ }
return;
}
@@ -847,6 +890,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
break;
case WW_BG:
case WW_DK:
+ case WW_M:
case WW_I:
case WW_L:
if (1 == core->use_nicam) {
@@ -872,20 +916,18 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
} else {
/* TODO: Add A2 autodection */
+ mask = 0x3f;
switch (mode) {
case V4L2_TUNER_MODE_MONO:
case V4L2_TUNER_MODE_LANG1:
- set_audio_standard_A2(core,
- EN_A2_FORCE_MONO1);
+ ctl = EN_A2_FORCE_MONO1;
break;
case V4L2_TUNER_MODE_LANG2:
- set_audio_standard_A2(core,
- EN_A2_FORCE_MONO2);
+ ctl = EN_A2_FORCE_MONO2;
break;
case V4L2_TUNER_MODE_STEREO:
case V4L2_TUNER_MODE_LANG1_LANG2:
- set_audio_standard_A2(core,
- EN_A2_FORCE_STEREO);
+ ctl = EN_A2_FORCE_STEREO;
break;
}
}
@@ -932,24 +974,39 @@ int cx88_audio_thread(void *data)
break;
try_to_freeze();
- /* just monitor the audio status for now ... */
- memset(&t, 0, sizeof(t));
- cx88_get_stereo(core, &t);
-
- if (UNSET != core->audiomode_manual)
- /* manually set, don't do anything. */
- continue;
-
- /* monitor signal */
- if (t.rxsubchans & V4L2_TUNER_SUB_STEREO)
- mode = V4L2_TUNER_MODE_STEREO;
- else
- mode = V4L2_TUNER_MODE_MONO;
- if (mode == core->audiomode_current)
- continue;
-
- /* automatically switch to best available mode */
- cx88_set_stereo(core, mode, 0);
+ switch (core->tvaudio) {
+ case WW_BG:
+ case WW_DK:
+ case WW_M:
+ case WW_I:
+ case WW_L:
+ if (core->use_nicam)
+ goto hw_autodetect;
+
+ /* just monitor the audio status for now ... */
+ memset(&t, 0, sizeof(t));
+ cx88_get_stereo(core, &t);
+
+ if (UNSET != core->audiomode_manual)
+ /* manually set, don't do anything. */
+ continue;
+
+ /* monitor signal and set stereo if available */
+ if (t.rxsubchans & V4L2_TUNER_SUB_STEREO)
+ mode = V4L2_TUNER_MODE_STEREO;
+ else
+ mode = V4L2_TUNER_MODE_MONO;
+ if (mode == core->audiomode_current)
+ continue;
+ /* automatically switch to best available mode */
+ cx88_set_stereo(core, mode, 0);
+ break;
+ default:
+hw_autodetect:
+ /* stereo autodetection is supported by hardware so
+ we don't need to do it manually. Do nothing. */
+ break;
+ }
}
dprintk("cx88: tvaudio thread exiting\n");
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 7724d168fc04..cc17272ed3b7 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -65,6 +65,8 @@
#define VBI_LINE_COUNT 17
#define VBI_LINE_LENGTH 2048
+#define AUD_RDS_LINES 4
+
/* need "shadow" registers for some write-only ones ... */
#define SHADOW_AUD_VOL_CTL 1
#define SHADOW_AUD_BAL_CTL 2
@@ -132,6 +134,7 @@ struct cx88_ctrl {
#define SRAM_CH25 4 /* audio */
#define SRAM_CH26 5
#define SRAM_CH28 6 /* mpeg */
+#define SRAM_CH27 7 /* audio rds */
/* more */
struct sram_channel {
@@ -232,6 +235,7 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_TBS_8910 77
#define CX88_BOARD_PROF_6200 78
#define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79
+#define CX88_BOARD_HAUPPAUGE_IRONLY 80
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
@@ -350,6 +354,7 @@ struct cx88_core {
u32 input;
u32 astat;
u32 use_nicam;
+ unsigned long last_change;
/* IR remote control state */
struct cx88_IR *ir;
@@ -652,6 +657,7 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl);
#define WW_I2SPT 8
#define WW_FM 9
#define WW_I2SADC 10
+#define WW_M 11
void cx88_set_tvaudio(struct cx88_core *core);
void cx88_newstation(struct cx88_core *core);
@@ -665,6 +671,11 @@ struct cx8802_dev *cx8802_get_device(int minor);
struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
/* ----------------------------------------------------------- */
+/* cx88-dsp.c */
+
+s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core);
+
+/* ----------------------------------------------------------- */
/* cx88-input.c */
int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci);
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 7c70738479dd..d4bc862a1a78 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1095,6 +1095,31 @@ struct em28xx_board em28xx_boards[] = {
.gpio = default_analog,
} },
},
+ [EM2880_BOARD_EMPIRE_DUAL_TV] = {
+ .name = "Empire dual TV",
+ .tuner_type = TUNER_XC2028,
+ .tuner_gpio = default_tuner_gpio,
+ .has_dvb = 1,
+ .dvb_gpio = default_digital,
+ .mts_firmware = 1,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_VIDEO,
+ .gpio = default_analog,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = EM28XX_AMUX_LINE_IN,
+ .gpio = default_analog,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ .gpio = default_analog,
+ } },
+ },
[EM2881_BOARD_DNT_DA2_HYBRID] = {
.name = "DNT DA2 Hybrid",
.valid = EM28XX_BOARD_NOT_VALIDATED,
@@ -1437,6 +1462,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
{0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
+ {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
};
/* I2C devicelist hash table for devices with generic USB IDs */
@@ -1664,6 +1690,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
ctl->mts = em28xx_boards[dev->model].mts_firmware;
switch (dev->model) {
+ case EM2880_BOARD_EMPIRE_DUAL_TV:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
ctl->demod = XC3028_FE_ZARLINK456;
break;
@@ -1835,12 +1862,20 @@ static int em28xx_hint_board(struct em28xx *dev)
}
/* ----------------------------------------------------------------------- */
-void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
+void em28xx_register_i2c_ir(struct em28xx *dev)
{
- if (disable_ir) {
- ir->get_key = NULL;
- return ;
- }
+ struct i2c_board_info info;
+ struct IR_i2c_init_data init_data;
+ const unsigned short addr_list[] = {
+ 0x30, 0x47, I2C_CLIENT_END
+ };
+
+ if (disable_ir)
+ return;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
/* detect & configure */
switch (dev->model) {
@@ -1850,22 +1885,19 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
break;
case (EM2800_BOARD_TERRATEC_CINERGY_200):
case (EM2820_BOARD_TERRATEC_CINERGY_250):
- ir->ir_codes = ir_codes_em_terratec;
- ir->get_key = em28xx_get_key_terratec;
- snprintf(ir->c.name, sizeof(ir->c.name),
- "i2c IR (EM28XX Terratec)");
+ init_data.ir_codes = ir_codes_em_terratec;
+ init_data.get_key = em28xx_get_key_terratec;
+ init_data.name = "i2c IR (EM28XX Terratec)";
break;
case (EM2820_BOARD_PINNACLE_USB_2):
- ir->ir_codes = ir_codes_pinnacle_grey;
- ir->get_key = em28xx_get_key_pinnacle_usb_grey;
- snprintf(ir->c.name, sizeof(ir->c.name),
- "i2c IR (EM28XX Pinnacle PCTV)");
+ init_data.ir_codes = ir_codes_pinnacle_grey;
+ init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
+ init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
break;
case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
- ir->ir_codes = ir_codes_hauppauge_new;
- ir->get_key = em28xx_get_key_em_haup;
- snprintf(ir->c.name, sizeof(ir->c.name),
- "i2c IR (EM2840 Hauppauge)");
+ init_data.ir_codes = ir_codes_hauppauge_new;
+ init_data.get_key = em28xx_get_key_em_haup;
+ init_data.name = "i2c IR (EM2840 Hauppauge)";
break;
case (EM2820_BOARD_MSI_VOX_USB_2):
break;
@@ -1876,6 +1908,10 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
case (EM2800_BOARD_GRABBEEX_USB2800):
break;
}
+
+ if (init_data.name)
+ info.platform_data = &init_data;
+ i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
}
void em28xx_card_setup(struct em28xx *dev)
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 192b76cdd5d7..7375353c04eb 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -938,7 +938,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
GFP_KERNEL);
if (!dev->isoc_ctl.transfer_buffer) {
- em28xx_errdev("cannot allocate memory for usbtransfer\n");
+ em28xx_errdev("cannot allocate memory for usb transfer\n");
kfree(dev->isoc_ctl.urb);
return -ENOMEM;
}
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index fcd25511209b..c8188dc2b4b5 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -431,6 +431,7 @@ static int dvb_init(struct em28xx *dev)
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
case EM2880_BOARD_TERRATEC_HYBRID_XS:
case EM2880_BOARD_KWORLD_DVB_310U:
+ case EM2880_BOARD_EMPIRE_DUAL_TV:
dvb->frontend = dvb_attach(zl10353_attach,
&em28xx_zl10353_with_xc3028,
&dev->i2c_adap);
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index f0bf1d960c75..2c86fcf089f5 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -451,27 +451,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL;
}
-/*
- * attach_inform()
- * gets called when a device attaches to the i2c bus
- * does some basic configuration
- */
-static int attach_inform(struct i2c_client *client)
-{
- struct em28xx *dev = client->adapter->algo_data;
- struct IR_i2c *ir = i2c_get_clientdata(client);
-
- switch (client->addr << 1) {
- case 0x60:
- case 0x8e:
- dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys);
- em28xx_set_ir(dev, ir);
- break;
- }
-
- return 0;
-}
-
static struct i2c_algorithm em28xx_algo = {
.master_xfer = em28xx_i2c_xfer,
.functionality = functionality,
@@ -482,7 +461,6 @@ static struct i2c_adapter em28xx_adap_template = {
.name = "em28xx",
.id = I2C_HW_B_EM28XX,
.algo = &em28xx_algo,
- .client_register = attach_inform,
};
static struct i2c_client em28xx_client_template = {
@@ -575,6 +553,9 @@ int em28xx_i2c_register(struct em28xx *dev)
if (i2c_scan)
em28xx_do_i2c_scan(dev);
+ /* Instantiate the IR receiver device, if present */
+ em28xx_register_i2c_ir(dev);
+
return 0;
}
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index a5abfd7a19f5..7a0fe3816e3d 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
#define i2cdprintk(fmt, arg...) \
if (ir_debug) { \
- printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
}
#define dprintk(fmt, arg...) \
@@ -85,7 +85,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char b;
/* poll IR chip */
- if (1 != i2c_master_recv(&ir->c, &b, 1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
i2cdprintk("read error\n");
return -EIO;
}
@@ -114,7 +114,7 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char code;
/* poll IR chip */
- if (2 != i2c_master_recv(&ir->c, buf, 2))
+ if (2 != i2c_master_recv(ir->c, buf, 2))
return -EIO;
/* Does eliminate repeated parity code */
@@ -147,7 +147,7 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
/* poll IR chip */
- if (3 != i2c_master_recv(&ir->c, buf, 3)) {
+ if (3 != i2c_master_recv(ir->c, buf, 3)) {
i2cdprintk("read error\n");
return -EIO;
}
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 4c4e58004f54..a8094926ca6a 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -102,6 +102,7 @@
#define EM2860_BOARD_KAIOMY_TVNPC_U2 63
#define EM2860_BOARD_EASYCAP 64
#define EM2820_BOARD_IODATA_GVMVP_SZ 65
+#define EM2880_BOARD_EMPIRE_DUAL_TV 66
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -639,7 +640,7 @@ extern void em28xx_card_setup(struct em28xx *dev);
extern struct em28xx_board em28xx_boards[];
extern struct usb_device_id em28xx_id_table[];
extern const unsigned int em28xx_bcount;
-void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir);
+void em28xx_register_i2c_ir(struct em28xx *dev);
int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
void em28xx_release_resources(struct em28xx *dev);
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 00e6863ed666..480ec5c87d0e 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -168,6 +168,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = fpix_mode;
cam->nmodes = 1;
+ cam->bulk = 1;
cam->bulk_size = FPIX_MAX_TRANSFER;
INIT_WORK(&dev->work_struct, dostream);
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index a2741d7dccfe..ae0e14033d66 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1,7 +1,7 @@
/*
* Main USB camera driver
*
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr)
*
* 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
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0)
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 6, 0)
#ifdef GSPCA_DEBUG
int gspca_debug = D_ERR | D_PROBE;
@@ -441,7 +441,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
* look for an input transfer endpoint in an alternate setting
*/
static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
- __u8 xfer)
+ int xfer)
{
struct usb_host_endpoint *ep;
int i, attr;
@@ -449,7 +449,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
for (i = 0; i < alt->desc.bNumEndpoints; i++) {
ep = &alt->endpoint[i];
attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
- if (attr == xfer)
+ if (attr == xfer
+ && ep->desc.wMaxPacketSize != 0)
return ep;
}
return NULL;
@@ -467,37 +468,28 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
{
struct usb_interface *intf;
struct usb_host_endpoint *ep;
- int i, ret;
+ int xfer, i, ret;
intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
ep = NULL;
+ xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
+ : USB_ENDPOINT_XFER_ISOC;
i = gspca_dev->alt; /* previous alt setting */
-
- /* try isoc */
while (--i >= 0) {
- ep = alt_xfer(&intf->altsetting[i],
- USB_ENDPOINT_XFER_ISOC);
+ ep = alt_xfer(&intf->altsetting[i], xfer);
if (ep)
break;
}
-
- /* if no isoc, try bulk (alt 0 only) */
if (ep == NULL) {
- ep = alt_xfer(&intf->altsetting[0],
- USB_ENDPOINT_XFER_BULK);
- if (ep == NULL) {
- err("no transfer endpoint found");
- return NULL;
- }
- i = 0;
- gspca_dev->bulk = 1;
+ err("no transfer endpoint found");
+ return NULL;
}
PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
i, ep->desc.bEndpointAddress);
- if (i > 0) {
+ if (gspca_dev->nbalt > 1) {
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
if (ret < 0) {
- err("set interface err %d", ret);
+ err("set alt %d err %d", i, ret);
return NULL;
}
}
@@ -517,13 +509,13 @@ static int create_urbs(struct gspca_dev *gspca_dev,
/* calculate the packet size and the number of packets */
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- if (!gspca_dev->bulk) { /* isoc */
+ if (!gspca_dev->cam.bulk) { /* isoc */
/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
- npkt = ISO_MAX_SIZE / psize;
- if (npkt > ISO_MAX_PKT)
- npkt = ISO_MAX_PKT;
+ npkt = gspca_dev->cam.npkt;
+ if (npkt == 0)
+ npkt = 32; /* default value */
bsize = psize * npkt;
PDEBUG(D_STREAM,
"isoc %d pkts size %d = bsize:%d",
@@ -617,7 +609,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
goto out;
/* clear the bulk endpoint */
- if (gspca_dev->bulk)
+ if (gspca_dev->cam.bulk)
usb_clear_halt(gspca_dev->dev,
gspca_dev->urb[0]->pipe);
@@ -630,7 +622,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
gspca_dev->streaming = 1;
/* some bulk transfers are started by the subdriver */
- if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0)
+ if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0)
break;
/* submit the URBs */
@@ -661,6 +653,8 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
{
int ret;
+ if (gspca_dev->alt == 0)
+ return 0;
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
if (ret < 0)
PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
@@ -1943,7 +1937,7 @@ int gspca_dev_probe(struct usb_interface *intf,
/* init video stuff */
memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
- gspca_dev->vdev.parent = &dev->dev;
+ gspca_dev->vdev.parent = &intf->dev;
gspca_dev->module = module;
gspca_dev->present = 1;
ret = video_register_device(&gspca_dev->vdev,
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 58e8ff02136a..bd1faff88644 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -44,8 +44,6 @@ extern int gspca_debug;
#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
/* image transfers */
#define MAX_NURBS 4 /* max number of URBs */
-#define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */
-#define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */
/* device information - set at probe time */
struct cam {
@@ -56,6 +54,9 @@ struct cam {
* - cannot be > MAX_NURBS
* - when 0 and bulk_size != 0 means
* 1 URB and submit done by subdriver */
+ u8 bulk; /* image transfer by 0:isoc / 1:bulk */
+ u8 npkt; /* number of packets in an ISOC message
+ * 0 is the default value: 32 packets */
u32 input_flags; /* value for ENUM_INPUT status flags */
};
@@ -168,7 +169,6 @@ struct gspca_dev {
__u8 iface; /* USB interface number */
__u8 alt; /* USB alternate setting */
__u8 nbalt; /* number of USB alternate settings */
- u8 bulk; /* image transfer by 0:isoc / 1:bulk */
};
int gspca_dev_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile
index 9fa3644f4869..bf7a19a1e6d1 100644
--- a/drivers/media/video/gspca/m5602/Makefile
+++ b/drivers/media/video/gspca/m5602/Makefile
@@ -2,9 +2,10 @@ obj-$(CONFIG_USB_M5602) += gspca_m5602.o
gspca_m5602-objs := m5602_core.o \
m5602_ov9650.o \
+ m5602_ov7660.o \
m5602_mt9m111.o \
m5602_po1030.o \
m5602_s5k83a.o \
m5602_s5k4aa.o
-EXTRA_CFLAGS += -Idrivers/media/video/gspca \ No newline at end of file
+EXTRA_CFLAGS += -Idrivers/media/video/gspca
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index 8f1cea6fd3bf..1127a405c9b2 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -45,6 +45,15 @@
#define M5602_XB_SEN_CLK_DIV 0x15
#define M5602_XB_AUD_CLK_CTRL 0x16
#define M5602_XB_AUD_CLK_DIV 0x17
+#define M5602_OB_AC_LINK_STATE 0x22
+#define M5602_OB_PCM_SLOT_INDEX 0x24
+#define M5602_OB_GPIO_SLOT_INDEX 0x25
+#define M5602_OB_ACRX_STATUS_ADDRESS_H 0x28
+#define M5602_OB_ACRX_STATUS_DATA_L 0x29
+#define M5602_OB_ACRX_STATUS_DATA_H 0x2a
+#define M5602_OB_ACTX_COMMAND_ADDRESS 0x31
+#define M5602_OB_ACRX_COMMAND_DATA_L 0x32
+#define M5602_OB_ACTX_COMMAND_DATA_H 0X33
#define M5602_XB_DEVCTR1 0x41
#define M5602_XB_EPSETR0 0x42
#define M5602_XB_EPAFCTR 0x47
@@ -77,7 +86,18 @@
#define M5602_XB_GPIO_EN_L 0x75
#define M5602_XB_GPIO_DAT 0x76
#define M5602_XB_GPIO_DIR 0x77
-#define M5602_XB_MISC_CTL 0x70
+#define M5602_XB_SEN_CLK_CONTROL 0x80
+#define M5602_XB_SEN_CLK_DIVISION 0x81
+#define M5602_XB_CPR_CLK_CONTROL 0x82
+#define M5602_XB_CPR_CLK_DIVISION 0x83
+#define M5602_XB_MCU_CLK_CONTROL 0x84
+#define M5602_XB_MCU_CLK_DIVISION 0x85
+#define M5602_XB_DCT_CLK_CONTROL 0x86
+#define M5602_XB_DCT_CLK_DIVISION 0x87
+#define M5602_XB_EC_CLK_CONTROL 0x88
+#define M5602_XB_EC_CLK_DIVISION 0x89
+#define M5602_XB_LBUF_CLK_CONTROL 0x8a
+#define M5602_XB_LBUF_CLK_DIVISION 0x8b
#define I2C_BUSY 0x80
@@ -128,10 +148,10 @@ struct sd {
};
int m5602_read_bridge(
- struct sd *sd, u8 address, u8 *i2c_data);
+ struct sd *sd, const u8 address, u8 *i2c_data);
int m5602_write_bridge(
- struct sd *sd, u8 address, u8 i2c_data);
+ struct sd *sd, const u8 address, const u8 i2c_data);
int m5602_write_sensor(struct sd *sd, const u8 address,
u8 *i2c_data, const u8 len);
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 1aac2985fee6..8a5bba16ff32 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -17,6 +17,7 @@
*/
#include "m5602_ov9650.h"
+#include "m5602_ov7660.h"
#include "m5602_mt9m111.h"
#include "m5602_po1030.h"
#include "m5602_s5k83a.h"
@@ -35,7 +36,7 @@ static const __devinitdata struct usb_device_id m5602_table[] = {
MODULE_DEVICE_TABLE(usb, m5602_table);
/* Reads a byte from the m5602 */
-int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
+int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data)
{
int err;
struct usb_device *udev = sd->gspca_dev.dev;
@@ -56,7 +57,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
}
/* Writes a byte to to the m5602 */
-int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
+int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data)
{
int err;
struct usb_device *udev = sd->gspca_dev.dev;
@@ -80,6 +81,17 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
return (err < 0) ? err : 0;
}
+int m5602_wait_for_i2c(struct sd *sd)
+{
+ int err;
+ u8 data;
+
+ do {
+ err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data);
+ } while ((data & I2C_BUSY) && !err);
+ return err;
+}
+
int m5602_read_sensor(struct sd *sd, const u8 address,
u8 *i2c_data, const u8 len)
{
@@ -88,9 +100,7 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
if (!len || len > sd->sensor->i2c_regW)
return -EINVAL;
- do {
- err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
- } while ((*i2c_data & I2C_BUSY) && !err);
+ err = m5602_wait_for_i2c(sd);
if (err < 0)
return err;
@@ -103,21 +113,25 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
if (err < 0)
return err;
+ /* Sensors with registers that are of only
+ one byte width are differently read */
+
+ /* FIXME: This works with the ov9650, but has issues with the po1030 */
if (sd->sensor->i2c_regW == 1) {
- err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len);
+ err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1);
if (err < 0)
return err;
err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
- if (err < 0)
- return err;
} else {
err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
- if (err < 0)
- return err;
}
for (i = 0; (i < len) && !err; i++) {
+ err = m5602_wait_for_i2c(sd);
+ if (err < 0)
+ return err;
+
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
PDEBUG(D_CONF, "Reading sensor register "
@@ -206,6 +220,11 @@ static int m5602_probe_sensor(struct sd *sd)
if (!sd->sensor->probe(sd))
return 0;
+ /* Try the ov7660 */
+ sd->sensor = &ov7660;
+ if (!sd->sensor->probe(sd))
+ return 0;
+
/* Try the s5k83a */
sd->sensor = &s5k83a;
if (!sd->sensor->probe(sd))
@@ -409,8 +428,9 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(force_sensor, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(force_sensor,
- "force detection of sensor, "
- "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, 4 = MT9M111, 5 = PO1030");
+ "forces detection of a sensor, "
+ "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, "
+ "4 = MT9M111, 5 = PO1030, 6 = OV7660");
module_param(dump_bridge, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup");
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 7d3f9e348ef4..8d071dff6944 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -18,6 +18,23 @@
#include "m5602_mt9m111.h"
+static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 val);
+static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 *val);
+static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
+
static struct v4l2_pix_format mt9m111_modes[] = {
{
640,
@@ -32,6 +49,7 @@ static struct v4l2_pix_format mt9m111_modes[] = {
};
const static struct ctrl mt9m111_ctrls[] = {
+#define VFLIP_IDX 0
{
{
.id = V4L2_CID_VFLIP,
@@ -44,7 +62,9 @@ const static struct ctrl mt9m111_ctrls[] = {
},
.set = mt9m111_set_vflip,
.get = mt9m111_get_vflip
- }, {
+ },
+#define HFLIP_IDX 1
+ {
{
.id = V4L2_CID_HFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -56,7 +76,9 @@ const static struct ctrl mt9m111_ctrls[] = {
},
.set = mt9m111_set_hflip,
.get = mt9m111_get_hflip
- }, {
+ },
+#define GAIN_IDX 2
+ {
{
.id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -64,21 +86,80 @@ const static struct ctrl mt9m111_ctrls[] = {
.minimum = 0,
.maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
.step = 1,
- .default_value = DEFAULT_GAIN,
+ .default_value = MT9M111_DEFAULT_GAIN,
.flags = V4L2_CTRL_FLAG_SLIDER
},
.set = mt9m111_set_gain,
.get = mt9m111_get_gain
- }
+ },
+#define AUTO_WHITE_BALANCE_IDX 3
+ {
+ {
+ .id = V4L2_CID_AUTO_WHITE_BALANCE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "auto white balance",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = mt9m111_set_auto_white_balance,
+ .get = mt9m111_get_auto_white_balance
+ },
+#define GREEN_BALANCE_IDX 4
+ {
+ {
+ .id = M5602_V4L2_CID_GREEN_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "green balance",
+ .minimum = 0x00,
+ .maximum = 0x7ff,
+ .step = 0x1,
+ .default_value = MT9M111_GREEN_GAIN_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = mt9m111_set_green_balance,
+ .get = mt9m111_get_green_balance
+ },
+#define BLUE_BALANCE_IDX 5
+ {
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "blue balance",
+ .minimum = 0x00,
+ .maximum = 0x7ff,
+ .step = 0x1,
+ .default_value = MT9M111_BLUE_GAIN_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = mt9m111_set_blue_balance,
+ .get = mt9m111_get_blue_balance
+ },
+#define RED_BALANCE_IDX 5
+ {
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "red balance",
+ .minimum = 0x00,
+ .maximum = 0x7ff,
+ .step = 0x1,
+ .default_value = MT9M111_RED_GAIN_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = mt9m111_set_red_balance,
+ .get = mt9m111_get_red_balance
+ },
};
-
static void mt9m111_dump_registers(struct sd *sd);
int mt9m111_probe(struct sd *sd)
{
u8 data[2] = {0x00, 0x00};
int i;
+ s32 *sensor_settings;
if (force_sensor) {
if (force_sensor == MT9M111_SENSOR) {
@@ -117,16 +198,27 @@ int mt9m111_probe(struct sd *sd)
return -ENODEV;
sensor_found:
+ sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32),
+ GFP_KERNEL);
+ if (!sensor_settings)
+ return -ENOMEM;
+
sd->gspca_dev.cam.cam_mode = mt9m111_modes;
sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes);
sd->desc->ctrls = mt9m111_ctrls;
sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls);
+
+ for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++)
+ sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value;
+ sd->sensor_priv = sensor_settings;
+
return 0;
}
int mt9m111_init(struct sd *sd)
{
int i, err = 0;
+ s32 *sensor_settings = sd->sensor_priv;
/* Init the sensor */
for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
@@ -147,36 +239,154 @@ int mt9m111_init(struct sd *sd)
if (dump_sensor)
mt9m111_dump_registers(sd);
- return (err < 0) ? err : 0;
+ err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+ if (err < 0)
+ return err;
+
+ err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+ if (err < 0)
+ return err;
+
+ err = mt9m111_set_green_balance(&sd->gspca_dev,
+ sensor_settings[GREEN_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = mt9m111_set_blue_balance(&sd->gspca_dev,
+ sensor_settings[BLUE_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = mt9m111_set_red_balance(&sd->gspca_dev,
+ sensor_settings[RED_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
}
-int mt9m111_power_down(struct sd *sd)
+int mt9m111_start(struct sd *sd)
{
- return 0;
+ int i, err = 0;
+ u8 data[2];
+ struct cam *cam = &sd->gspca_dev.cam;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1;
+ int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
+
+ for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) {
+ if (start_mt9m111[i][0] == BRIDGE) {
+ err = m5602_write_bridge(sd,
+ start_mt9m111[i][1],
+ start_mt9m111[i][2]);
+ } else {
+ data[0] = start_mt9m111[i][2];
+ data[1] = start_mt9m111[i][3];
+ err = m5602_write_sensor(sd,
+ start_mt9m111[i][1], data, 2);
+ }
+ }
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < 2 && !err; i++)
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < 2 && !err; i++)
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
+ (width >> 8) & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
+ if (err < 0)
+ return err;
+
+ switch (width) {
+ case 640:
+ PDEBUG(D_V4L2, "Configuring camera for VGA mode");
+ data[0] = MT9M111_RMB_OVER_SIZED;
+ data[1] = MT9M111_RMB_ROW_SKIP_2X |
+ MT9M111_RMB_COLUMN_SKIP_2X |
+ (sensor_settings[VFLIP_IDX] << 0) |
+ (sensor_settings[HFLIP_IDX] << 1);
+
+ err = m5602_write_sensor(sd,
+ MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
+ break;
+
+ case 320:
+ PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
+ data[0] = MT9M111_RMB_OVER_SIZED;
+ data[1] = MT9M111_RMB_ROW_SKIP_4X |
+ MT9M111_RMB_COLUMN_SKIP_4X |
+ (sensor_settings[VFLIP_IDX] << 0) |
+ (sensor_settings[HFLIP_IDX] << 1);
+ err = m5602_write_sensor(sd,
+ MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
+ break;
+ }
+ return err;
}
-int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+void mt9m111_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
+static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 data[2] = {0x00, 0x00};
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
- data, 2);
- *val = data[0] & MT9M111_RMB_MIRROR_ROWS;
+ *val = sensor_settings[VFLIP_IDX];
PDEBUG(D_V4L2, "Read vertical flip %d", *val);
- return err;
+ return 0;
}
-int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 data[2] = {0x00, 0x00};
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
PDEBUG(D_V4L2, "Set vertical flip to %d", val);
+ sensor_settings[VFLIP_IDX] = val;
+
+ /* The mt9m111 is flipped by default */
+ val = !val;
+
/* Set the correct page map */
err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
if (err < 0)
@@ -186,34 +396,37 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
if (err < 0)
return err;
- data[0] = (data[0] & 0xfe) | val;
+ data[1] = (data[1] & 0xfe) | val;
err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
data, 2);
return err;
}
-int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 data[2] = {0x00, 0x00};
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
- data, 2);
- *val = data[0] & MT9M111_RMB_MIRROR_COLS;
+ *val = sensor_settings[HFLIP_IDX];
PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
- return err;
+ return 0;
}
-int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 data[2] = {0x00, 0x00};
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
+ sensor_settings[HFLIP_IDX] = val;
+
+ /* The mt9m111 is flipped by default */
+ val = !val;
+
/* Set the correct page map */
err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
if (err < 0)
@@ -223,36 +436,62 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
if (err < 0)
return err;
- data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02);
+ data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02);
err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
data, 2);
return err;
}
-int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err, tmp;
- u8 data[2] = {0x00, 0x00};
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2);
- tmp = ((data[1] << 8) | data[0]);
+ *val = sensor_settings[GAIN_IDX];
+ PDEBUG(D_V4L2, "Read gain %d", *val);
- *val = ((tmp & (1 << 10)) * 2) |
- ((tmp & (1 << 9)) * 2) |
- ((tmp & (1 << 8)) * 2) |
- (tmp & 0x7f);
+ return 0;
+}
- PDEBUG(D_V4L2, "Read gain %d", *val);
+static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+ int err;
+ u8 data[2];
+
+ err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
+ if (err < 0)
+ return err;
+
+ sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01;
+ data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1));
+ err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
+
+ PDEBUG(D_V4L2, "Set auto white balance %d", val);
return err;
}
-int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 *val) {
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
+ PDEBUG(D_V4L2, "Read auto white balance %d", *val);
+ return 0;
+}
+
+static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
{
int err, tmp;
u8 data[2] = {0x00, 0x00};
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[GAIN_IDX] = val;
/* Set the correct page map */
err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
@@ -275,8 +514,8 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
else
tmp = val;
- data[1] = (tmp & 0xff00) >> 8;
- data[0] = (tmp & 0xff);
+ data[1] = (tmp & 0xff);
+ data[0] = (tmp & 0xff00) >> 8;
PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
data[1], data[0]);
@@ -286,6 +525,89 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
return err;
}
+static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+ int err;
+ u8 data[2];
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[GREEN_BALANCE_IDX] = val;
+ data[1] = (val & 0xff);
+ data[0] = (val & 0xff00) >> 8;
+
+ PDEBUG(D_V4L2, "Set green balance %d", val);
+ err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
+ data, 2);
+ if (err < 0)
+ return err;
+
+ return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN,
+ data, 2);
+}
+
+static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[GREEN_BALANCE_IDX];
+ PDEBUG(D_V4L2, "Read green balance %d", *val);
+ return 0;
+}
+
+static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+ u8 data[2];
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[BLUE_BALANCE_IDX] = val;
+ data[1] = (val & 0xff);
+ data[0] = (val & 0xff00) >> 8;
+
+ PDEBUG(D_V4L2, "Set blue balance %d", val);
+
+ return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN,
+ data, 2);
+}
+
+static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[BLUE_BALANCE_IDX];
+ PDEBUG(D_V4L2, "Read blue balance %d", *val);
+ return 0;
+}
+
+static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+ u8 data[2];
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[RED_BALANCE_IDX] = val;
+ data[1] = (val & 0xff);
+ data[0] = (val & 0xff00) >> 8;
+
+ PDEBUG(D_V4L2, "Set red balance %d", val);
+
+ return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN,
+ data, 2);
+}
+
+static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[RED_BALANCE_IDX];
+ PDEBUG(D_V4L2, "Read red balance %d", *val);
+ return 0;
+}
+
static void mt9m111_dump_registers(struct sd *sd)
{
u8 address, value[2] = {0x00, 0x00};
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 00c6db02bdb7..b3de77823091 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -37,7 +37,6 @@
#define MT9M111_SC_VBLANK_CONTEXT_A 0x08
#define MT9M111_SC_SHUTTER_WIDTH 0x09
#define MT9M111_SC_ROW_SPEED 0x0a
-
#define MT9M111_SC_EXTRA_DELAY 0x0b
#define MT9M111_SC_SHUTTER_DELAY 0x0c
#define MT9M111_SC_RESET 0x0d
@@ -50,9 +49,6 @@
#define MT9M111_SC_GREEN_2_GAIN 0x2e
#define MT9M111_SC_GLOBAL_GAIN 0x2f
-#define MT9M111_RMB_MIRROR_ROWS (1 << 0)
-#define MT9M111_RMB_MIRROR_COLS (1 << 1)
-
#define MT9M111_CONTEXT_CONTROL 0xc8
#define MT9M111_PAGE_MAP 0xf0
#define MT9M111_BYTEWISE_ADDRESS 0xf1
@@ -74,8 +70,37 @@
#define MT9M111_COLORPIPE 0x01
#define MT9M111_CAMERA_CONTROL 0x02
+#define MT9M111_RESET (1 << 0)
+#define MT9M111_RESTART (1 << 1)
+#define MT9M111_ANALOG_STANDBY (1 << 2)
+#define MT9M111_CHIP_ENABLE (1 << 3)
+#define MT9M111_CHIP_DISABLE (0 << 3)
+#define MT9M111_OUTPUT_DISABLE (1 << 4)
+#define MT9M111_SHOW_BAD_FRAMES (1 << 0)
+#define MT9M111_RESTART_BAD_FRAMES (1 << 1)
+#define MT9M111_SYNCHRONIZE_CHANGES (1 << 7)
+
+#define MT9M111_RMB_OVER_SIZED (1 << 0)
+#define MT9M111_RMB_MIRROR_ROWS (1 << 0)
+#define MT9M111_RMB_MIRROR_COLS (1 << 1)
+#define MT9M111_RMB_ROW_SKIP_2X (1 << 2)
+#define MT9M111_RMB_COLUMN_SKIP_2X (1 << 3)
+#define MT9M111_RMB_ROW_SKIP_4X (1 << 4)
+#define MT9M111_RMB_COLUMN_SKIP_4X (1 << 5)
+
+#define MT9M111_COLOR_MATRIX_BYPASS (1 << 4)
+#define MT9M111_SEL_CONTEXT_B (1 << 3)
+
+#define MT9M111_TRISTATE_PIN_IN_STANDBY (1 << 1)
+#define MT9M111_SOC_SOFT_STANDBY (1 << 0)
+
+#define MT9M111_2D_DEFECT_CORRECTION_ENABLE (1 << 0)
+
#define INITIAL_MAX_GAIN 64
-#define DEFAULT_GAIN 283
+#define MT9M111_DEFAULT_GAIN 283
+#define MT9M111_GREEN_GAIN_DEFAULT 0x20
+#define MT9M111_BLUE_GAIN_DEFAULT 0x20
+#define MT9M111_RED_GAIN_DEFAULT 0x20
/*****************************************************************************/
@@ -85,16 +110,10 @@ extern int dump_sensor;
int mt9m111_probe(struct sd *sd);
int mt9m111_init(struct sd *sd);
-int mt9m111_power_down(struct sd *sd);
+int mt9m111_start(struct sd *sd);
+void mt9m111_disconnect(struct sd *sd);
-int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-
-const static struct m5602_sensor mt9m111 = {
+static const struct m5602_sensor mt9m111 = {
.name = "MT9M111",
.i2c_slave_id = 0xba,
@@ -102,7 +121,8 @@ const static struct m5602_sensor mt9m111 = {
.probe = mt9m111_probe,
.init = mt9m111_init,
- .power_down = mt9m111_power_down
+ .disconnect = mt9m111_disconnect,
+ .start = mt9m111_start,
};
static const unsigned char preinit_mt9m111[][4] =
@@ -117,7 +137,14 @@ static const unsigned char preinit_mt9m111[][4] =
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7},
+ {SENSOR, MT9M111_SC_RESET,
+ MT9M111_RESET |
+ MT9M111_RESTART |
+ MT9M111_ANALOG_STANDBY |
+ MT9M111_CHIP_DISABLE,
+ MT9M111_SHOW_BAD_FRAMES |
+ MT9M111_RESTART_BAD_FRAMES |
+ MT9M111_SYNCHRONIZE_CHANGES},
{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
@@ -145,731 +172,42 @@ static const unsigned char init_mt9m111[][4] =
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
- {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
- {SENSOR, MT9M111_SC_RESET, 0xff, 0xde},
- {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
- {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
-
- {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0xff, 0xff},
-
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
-
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
- {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
- {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
- {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
- {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
- {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
- {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
-
- {SENSOR, 0xcd, 0x00, 0x0e},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
- {SENSOR, 0xd0, 0x00, 0x40},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
- {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
- {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
- {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
- {SENSOR, 0x33, 0x03, 0x49},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-
- {SENSOR, 0x33, 0x03, 0x49},
- {SENSOR, 0x34, 0xc0, 0x19},
- {SENSOR, 0x3f, 0x20, 0x20},
- {SENSOR, 0x40, 0x20, 0x20},
- {SENSOR, 0x5a, 0xc0, 0x0a},
- {SENSOR, 0x70, 0x7b, 0x0a},
- {SENSOR, 0x71, 0xff, 0x00},
- {SENSOR, 0x72, 0x19, 0x0e},
- {SENSOR, 0x73, 0x18, 0x0f},
- {SENSOR, 0x74, 0x57, 0x32},
- {SENSOR, 0x75, 0x56, 0x34},
- {SENSOR, 0x76, 0x73, 0x35},
- {SENSOR, 0x77, 0x30, 0x12},
- {SENSOR, 0x78, 0x79, 0x02},
- {SENSOR, 0x79, 0x75, 0x06},
- {SENSOR, 0x7a, 0x77, 0x0a},
- {SENSOR, 0x7b, 0x78, 0x09},
- {SENSOR, 0x7c, 0x7d, 0x06},
- {SENSOR, 0x7d, 0x31, 0x10},
- {SENSOR, 0x7e, 0x00, 0x7e},
- {SENSOR, 0x80, 0x59, 0x04},
- {SENSOR, 0x81, 0x59, 0x04},
- {SENSOR, 0x82, 0x57, 0x0a},
- {SENSOR, 0x83, 0x58, 0x0b},
- {SENSOR, 0x84, 0x47, 0x0c},
- {SENSOR, 0x85, 0x48, 0x0e},
- {SENSOR, 0x86, 0x5b, 0x02},
- {SENSOR, 0x87, 0x00, 0x5c},
- {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
- {SENSOR, 0x60, 0x00, 0x80},
- {SENSOR, 0x61, 0x00, 0x00},
- {SENSOR, 0x62, 0x00, 0x00},
- {SENSOR, 0x63, 0x00, 0x00},
- {SENSOR, 0x64, 0x00, 0x00},
-
- {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
- {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
- {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
- {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
- {SENSOR, 0x30, 0x04, 0x00},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
- {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
- {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
-
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
- {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
- {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
- {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
- {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
- {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
- {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
-
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
- {SENSOR, 0xcd, 0x00, 0x0e},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
- {SENSOR, 0xd0, 0x00, 0x40},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
- {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
- {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
- {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
- {SENSOR, 0x33, 0x03, 0x49},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-
- {SENSOR, 0x33, 0x03, 0x49},
- {SENSOR, 0x34, 0xc0, 0x19},
- {SENSOR, 0x3f, 0x20, 0x20},
- {SENSOR, 0x40, 0x20, 0x20},
- {SENSOR, 0x5a, 0xc0, 0x0a},
- {SENSOR, 0x70, 0x7b, 0x0a},
- {SENSOR, 0x71, 0xff, 0x00},
- {SENSOR, 0x72, 0x19, 0x0e},
- {SENSOR, 0x73, 0x18, 0x0f},
- {SENSOR, 0x74, 0x57, 0x32},
- {SENSOR, 0x75, 0x56, 0x34},
- {SENSOR, 0x76, 0x73, 0x35},
- {SENSOR, 0x77, 0x30, 0x12},
- {SENSOR, 0x78, 0x79, 0x02},
- {SENSOR, 0x79, 0x75, 0x06},
- {SENSOR, 0x7a, 0x77, 0x0a},
- {SENSOR, 0x7b, 0x78, 0x09},
- {SENSOR, 0x7c, 0x7d, 0x06},
- {SENSOR, 0x7d, 0x31, 0x10},
- {SENSOR, 0x7e, 0x00, 0x7e},
- {SENSOR, 0x80, 0x59, 0x04},
- {SENSOR, 0x81, 0x59, 0x04},
- {SENSOR, 0x82, 0x57, 0x0a},
- {SENSOR, 0x83, 0x58, 0x0b},
- {SENSOR, 0x84, 0x47, 0x0c},
- {SENSOR, 0x85, 0x48, 0x0e},
- {SENSOR, 0x86, 0x5b, 0x02},
- {SENSOR, 0x87, 0x00, 0x5c},
- {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
- {SENSOR, 0x60, 0x00, 0x80},
- {SENSOR, 0x61, 0x00, 0x00},
- {SENSOR, 0x62, 0x00, 0x00},
- {SENSOR, 0x63, 0x00, 0x00},
- {SENSOR, 0x64, 0x00, 0x00},
-
- {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
- {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
- {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
- {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
- {SENSOR, 0x30, 0x04, 0x00},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
- {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
- {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
{BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
{BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
- {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
+ {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
+ MT9M111_CP_OPERATING_MODE_CTL},
{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
+ {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00,
+ MT9M111_2D_DEFECT_CORRECTION_ENABLE},
+ {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00,
+ MT9M111_2D_DEFECT_CORRECTION_ENABLE},
{SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
{SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
-
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
{SENSOR, 0xcd, 0x00, 0x0e},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
{SENSOR, 0xd0, 0x00, 0x40},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
- {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
- {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
- {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
- {SENSOR, 0x33, 0x03, 0x49},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-
- {SENSOR, 0x33, 0x03, 0x49},
- {SENSOR, 0x34, 0xc0, 0x19},
- {SENSOR, 0x3f, 0x20, 0x20},
- {SENSOR, 0x40, 0x20, 0x20},
- {SENSOR, 0x5a, 0xc0, 0x0a},
- {SENSOR, 0x70, 0x7b, 0x0a},
- {SENSOR, 0x71, 0xff, 0x00},
- {SENSOR, 0x72, 0x19, 0x0e},
- {SENSOR, 0x73, 0x18, 0x0f},
- {SENSOR, 0x74, 0x57, 0x32},
- {SENSOR, 0x75, 0x56, 0x34},
- {SENSOR, 0x76, 0x73, 0x35},
- {SENSOR, 0x77, 0x30, 0x12},
- {SENSOR, 0x78, 0x79, 0x02},
- {SENSOR, 0x79, 0x75, 0x06},
- {SENSOR, 0x7a, 0x77, 0x0a},
- {SENSOR, 0x7b, 0x78, 0x09},
- {SENSOR, 0x7c, 0x7d, 0x06},
- {SENSOR, 0x7d, 0x31, 0x10},
- {SENSOR, 0x7e, 0x00, 0x7e},
- {SENSOR, 0x80, 0x59, 0x04},
- {SENSOR, 0x81, 0x59, 0x04},
- {SENSOR, 0x82, 0x57, 0x0a},
- {SENSOR, 0x83, 0x58, 0x0b},
- {SENSOR, 0x84, 0x47, 0x0c},
- {SENSOR, 0x85, 0x48, 0x0e},
- {SENSOR, 0x86, 0x5b, 0x02},
- {SENSOR, 0x87, 0x00, 0x5c},
- {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
- {SENSOR, 0x60, 0x00, 0x80},
- {SENSOR, 0x61, 0x00, 0x00},
- {SENSOR, 0x62, 0x00, 0x00},
- {SENSOR, 0x63, 0x00, 0x00},
- {SENSOR, 0x64, 0x00, 0x00},
- {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
- {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
- {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
- {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
- {SENSOR, 0x30, 0x04, 0x00},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
- {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
- {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
- {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
- {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
- {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
- {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
- {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
-
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, 0xcd, 0x00, 0x0e},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, 0xd0, 0x00, 0x40},
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
{SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, 0x33, 0x03, 0x49},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-
- {SENSOR, 0x33, 0x03, 0x49},
- {SENSOR, 0x34, 0xc0, 0x19},
- {SENSOR, 0x3f, 0x20, 0x20},
- {SENSOR, 0x40, 0x20, 0x20},
- {SENSOR, 0x5a, 0xc0, 0x0a},
- {SENSOR, 0x70, 0x7b, 0x0a},
- {SENSOR, 0x71, 0xff, 0x00},
- {SENSOR, 0x72, 0x19, 0x0e},
- {SENSOR, 0x73, 0x18, 0x0f},
- {SENSOR, 0x74, 0x57, 0x32},
- {SENSOR, 0x75, 0x56, 0x34},
- {SENSOR, 0x76, 0x73, 0x35},
- {SENSOR, 0x77, 0x30, 0x12},
- {SENSOR, 0x78, 0x79, 0x02},
- {SENSOR, 0x79, 0x75, 0x06},
- {SENSOR, 0x7a, 0x77, 0x0a},
- {SENSOR, 0x7b, 0x78, 0x09},
- {SENSOR, 0x7c, 0x7d, 0x06},
- {SENSOR, 0x7d, 0x31, 0x10},
- {SENSOR, 0x7e, 0x00, 0x7e},
- {SENSOR, 0x80, 0x59, 0x04},
- {SENSOR, 0x81, 0x59, 0x04},
- {SENSOR, 0x82, 0x57, 0x0a},
- {SENSOR, 0x83, 0x58, 0x0b},
- {SENSOR, 0x84, 0x47, 0x0c},
- {SENSOR, 0x85, 0x48, 0x0e},
- {SENSOR, 0x86, 0x5b, 0x02},
- {SENSOR, 0x87, 0x00, 0x5c},
- {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
- {SENSOR, 0x60, 0x00, 0x80},
- {SENSOR, 0x61, 0x00, 0x00},
- {SENSOR, 0x62, 0x00, 0x00},
- {SENSOR, 0x63, 0x00, 0x00},
- {SENSOR, 0x64, 0x00, 0x00},
- {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
- {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12},
- {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00},
- {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10},
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60},
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60},
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f},
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
- {SENSOR, 0x30, 0x04, 0x00},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe3, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
- {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xe6},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
- {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
- {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
- {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
- {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
- {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
- {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
-
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, 0xcd, 0x00, 0x0e},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, 0xd0, 0x00, 0x40},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
- {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
- {SENSOR, 0x33, 0x03, 0x49},
- {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
- {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
- {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-
{SENSOR, 0x33, 0x03, 0x49},
{SENSOR, 0x34, 0xc0, 0x19},
{SENSOR, 0x3f, 0x20, 0x20},
@@ -898,25 +236,29 @@ static const unsigned char init_mt9m111[][4] =
{SENSOR, 0x85, 0x48, 0x0e},
{SENSOR, 0x86, 0x5b, 0x02},
{SENSOR, 0x87, 0x00, 0x5c},
- {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
+ {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B},
{SENSOR, 0x60, 0x00, 0x80},
{SENSOR, 0x61, 0x00, 0x00},
{SENSOR, 0x62, 0x00, 0x00},
{SENSOR, 0x63, 0x00, 0x00},
{SENSOR, 0x64, 0x00, 0x00},
- {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
- {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12},
- {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00},
- {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10},
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60},
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60},
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f},
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
+ {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */
+ {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */
+ {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */
+ {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */
+ {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */
+ {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */
+ {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */
+ {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */
+ {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */
{SENSOR, 0x30, 0x04, 0x00},
+ /* Set number of blank rows chosen to 400 */
+ {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
+};
+static const unsigned char start_mt9m111[][4] =
+{
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -928,25 +270,6 @@ static const unsigned char init_mt9m111[][4] =
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, /* 639*/
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- /* Set number of blank rows chosen to 400 */
- {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
- /* Set the global gain to 283 (of 512) */
- {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x03, 0x63}
};
#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
new file mode 100644
index 000000000000..7aafeb7cfa07
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -0,0 +1,227 @@
+/*
+ * Driver for the ov7660 sensor
+ *
+ * Copyright (C) 2009 Erik Andrén
+ * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
+ * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
+ *
+ * Portions of code to USB interface and ALi driver software,
+ * Copyright (c) 2006 Willem Duinker
+ * v4l2 interface modeled after the V4L2 driver
+ * for SN9C10x PC Camera Controllers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "m5602_ov7660.h"
+
+static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+
+const static struct ctrl ov7660_ctrls[] = {
+#define GAIN_IDX 1
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x1,
+ .default_value = OV7660_DEFAULT_GAIN,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = ov7660_set_gain,
+ .get = ov7660_get_gain
+ },
+};
+
+static struct v4l2_pix_format ov7660_modes[] = {
+ {
+ 640,
+ 480,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ 640 * 480,
+ .bytesperline = 640,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
+static void ov7660_dump_registers(struct sd *sd);
+
+int ov7660_probe(struct sd *sd)
+{
+ int err = 0, i;
+ u8 prod_id = 0, ver_id = 0;
+
+ s32 *sensor_settings;
+
+ if (force_sensor) {
+ if (force_sensor == OV7660_SENSOR) {
+ info("Forcing an %s sensor", ov7660.name);
+ goto sensor_found;
+ }
+ /* If we want to force another sensor,
+ don't try to probe this one */
+ return -ENODEV;
+ }
+
+ /* Do the preinit */
+ for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) {
+ u8 data[2];
+
+ if (preinit_ov7660[i][0] == BRIDGE) {
+ err = m5602_write_bridge(sd,
+ preinit_ov7660[i][1],
+ preinit_ov7660[i][2]);
+ } else {
+ data[0] = preinit_ov7660[i][2];
+ err = m5602_write_sensor(sd,
+ preinit_ov7660[i][1], data, 1);
+ }
+ }
+ if (err < 0)
+ return err;
+
+ if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1))
+ return -ENODEV;
+
+ if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1))
+ return -ENODEV;
+
+ info("Sensor reported 0x%x%x", prod_id, ver_id);
+
+ if ((prod_id == 0x76) && (ver_id == 0x60)) {
+ info("Detected a ov7660 sensor");
+ goto sensor_found;
+ }
+ return -ENODEV;
+
+sensor_found:
+ sensor_settings = kmalloc(
+ ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL);
+ if (!sensor_settings)
+ return -ENOMEM;
+
+ sd->gspca_dev.cam.cam_mode = ov7660_modes;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
+ sd->desc->ctrls = ov7660_ctrls;
+ sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls);
+
+ for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++)
+ sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value;
+ sd->sensor_priv = sensor_settings;
+
+ return 0;
+}
+
+int ov7660_init(struct sd *sd)
+{
+ int i, err = 0;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ /* Init the sensor */
+ for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
+ u8 data[2];
+
+ if (init_ov7660[i][0] == BRIDGE) {
+ err = m5602_write_bridge(sd,
+ init_ov7660[i][1],
+ init_ov7660[i][2]);
+ } else {
+ data[0] = init_ov7660[i][2];
+ err = m5602_write_sensor(sd,
+ init_ov7660[i][1], data, 1);
+ }
+ }
+
+ if (dump_sensor)
+ ov7660_dump_registers(sd);
+
+ err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+ if (err < 0)
+ return err;
+
+ return err;
+}
+
+int ov7660_start(struct sd *sd)
+{
+ return 0;
+}
+
+int ov7660_stop(struct sd *sd)
+{
+ return 0;
+}
+
+void ov7660_disconnect(struct sd *sd)
+{
+ ov7660_stop(sd);
+
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
+static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[GAIN_IDX];
+ PDEBUG(D_V4L2, "Read gain %d", *val);
+ return 0;
+}
+
+static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ int err;
+ u8 i2c_data;
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ PDEBUG(D_V4L2, "Setting gain to %d", val);
+
+ sensor_settings[GAIN_IDX] = val;
+
+ err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
+ return err;
+}
+
+static void ov7660_dump_registers(struct sd *sd)
+{
+ int address;
+ info("Dumping the ov7660 register state");
+ for (address = 0; address < 0xa9; address++) {
+ u8 value;
+ m5602_read_sensor(sd, address, &value, 1);
+ info("register 0x%x contains 0x%x",
+ address, value);
+ }
+
+ info("ov7660 register state dump complete");
+
+ info("Probing for which registers that are read/write");
+ for (address = 0; address < 0xff; address++) {
+ u8 old_value, ctrl_value;
+ u8 test_value[2] = {0xff, 0xff};
+
+ m5602_read_sensor(sd, address, &old_value, 1);
+ m5602_write_sensor(sd, address, test_value, 1);
+ m5602_read_sensor(sd, address, &ctrl_value, 1);
+
+ if (ctrl_value == test_value[0])
+ info("register 0x%x is writeable", address);
+ else
+ info("register 0x%x is read only", address);
+
+ /* Restore original value */
+ m5602_write_sensor(sd, address, &old_value, 1);
+ }
+}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
new file mode 100644
index 000000000000..3f2c169a93ea
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -0,0 +1,279 @@
+/*
+ * Driver for the ov7660 sensor
+ *
+ * Copyright (C) 2009 Erik Andrén
+ * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
+ * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
+ *
+ * Portions of code to USB interface and ALi driver software,
+ * Copyright (c) 2006 Willem Duinker
+ * v4l2 interface modeled after the V4L2 driver
+ * for SN9C10x PC Camera Controllers
+ *
+ * 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.
+ *
+ */
+
+#ifndef M5602_OV7660_H_
+#define M5602_OV7660_H_
+
+#include "m5602_sensor.h"
+
+#define OV7660_GAIN 0x00
+#define OV7660_BLUE_GAIN 0x01
+#define OV7660_RED_GAIN 0x02
+#define OV7660_VREF 0x03
+#define OV7660_COM1 0x04
+#define OV7660_BAVE 0x05
+#define OV7660_GEAVE 0x06
+#define OV7660_AECHH 0x07
+#define OV7660_RAVE 0x08
+#define OV7660_COM2 0x09
+#define OV7660_PID 0x0a
+#define OV7660_VER 0x0b
+#define OV7660_COM3 0x0c
+#define OV7660_COM4 0x0d
+#define OV7660_COM5 0x0e
+#define OV7660_COM6 0x0f
+#define OV7660_AECH 0x10
+#define OV7660_CLKRC 0x11
+#define OV7660_COM7 0x12
+#define OV7660_COM8 0x13
+#define OV7660_COM9 0x14
+#define OV7660_COM10 0x15
+#define OV7660_RSVD16 0x16
+#define OV7660_HSTART 0x17
+#define OV7660_HSTOP 0x18
+#define OV7660_VSTART 0x19
+#define OV7660_VSTOP 0x1a
+#define OV7660_PSHFT 0x1b
+#define OV7660_MIDH 0x1c
+#define OV7660_MIDL 0x1d
+#define OV7660_MVFP 0x1e
+#define OV7660_LAEC 0x1f
+#define OV7660_BOS 0x20
+#define OV7660_GBOS 0x21
+#define OV7660_GROS 0x22
+#define OV7660_ROS 0x23
+#define OV7660_AEW 0x24
+#define OV7660_AEB 0x25
+#define OV7660_VPT 0x26
+#define OV7660_BBIAS 0x27
+#define OV7660_GbBIAS 0x28
+#define OV7660_RSVD29 0x29
+#define OV7660_RBIAS 0x2c
+#define OV7660_HREF 0x32
+#define OV7660_ADC 0x37
+#define OV7660_OFON 0x39
+#define OV7660_TSLB 0x3a
+#define OV7660_COM12 0x3c
+#define OV7660_COM13 0x3d
+#define OV7660_LCC1 0x62
+#define OV7660_LCC2 0x63
+#define OV7660_LCC3 0x64
+#define OV7660_LCC4 0x65
+#define OV7660_LCC5 0x66
+#define OV7660_HV 0x69
+#define OV7660_RSVDA1 0xa1
+
+#define OV7660_DEFAULT_GAIN 0x0e
+#define OV7660_DEFAULT_RED_GAIN 0x80
+#define OV7660_DEFAULT_BLUE_GAIN 0x80
+#define OV7660_DEFAULT_SATURATION 0x00
+#define OV7660_DEFAULT_EXPOSURE 0x20
+
+/* Kernel module parameters */
+extern int force_sensor;
+extern int dump_sensor;
+
+int ov7660_probe(struct sd *sd);
+int ov7660_init(struct sd *sd);
+int ov7660_start(struct sd *sd);
+int ov7660_stop(struct sd *sd);
+void ov7660_disconnect(struct sd *sd);
+
+const static struct m5602_sensor ov7660 = {
+ .name = "ov7660",
+ .i2c_slave_id = 0x42,
+ .i2c_regW = 1,
+ .probe = ov7660_probe,
+ .init = ov7660_init,
+ .start = ov7660_start,
+ .stop = ov7660_stop,
+ .disconnect = ov7660_disconnect,
+};
+
+static const unsigned char preinit_ov7660[][4] =
+{
+ {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
+ {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+ {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+ {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
+ {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
+ {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+ {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+
+ {SENSOR, OV7660_OFON, 0x0c},
+ {SENSOR, OV7660_COM2, 0x11},
+ {SENSOR, OV7660_COM7, 0x05},
+
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
+ {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
+ {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+ {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+ {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+ {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+ {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}
+};
+
+static const unsigned char init_ov7660[][4] =
+{
+ {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
+ {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+ {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+ {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
+ {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
+ {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+ {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+
+ {SENSOR, OV7660_OFON, 0x0c},
+ {SENSOR, OV7660_COM2, 0x11},
+ {SENSOR, OV7660_COM7, 0x05},
+
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
+ {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
+ {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+ {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+ {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+ {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+ {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
+
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+
+ {SENSOR, OV7660_AECH, OV7660_DEFAULT_EXPOSURE},
+ {SENSOR, OV7660_COM1, 0x00},
+
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
+ {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
+ {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+ {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+ {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+ {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+ {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
+
+ {SENSOR, OV7660_COM7, 0x80},
+ {SENSOR, OV7660_CLKRC, 0x80},
+ {SENSOR, OV7660_BLUE_GAIN, 0x80},
+ {SENSOR, OV7660_RED_GAIN, 0x80},
+ {SENSOR, OV7660_COM9, 0x4c},
+ {SENSOR, OV7660_OFON, 0x43},
+ {SENSOR, OV7660_COM12, 0x28},
+ {SENSOR, OV7660_COM8, 0x00},
+ {SENSOR, OV7660_COM10, 0x40},
+ {SENSOR, OV7660_HSTART, 0x0c},
+ {SENSOR, OV7660_HSTOP, 0x61},
+ {SENSOR, OV7660_HREF, 0xa4},
+ {SENSOR, OV7660_PSHFT, 0x0b},
+ {SENSOR, OV7660_VSTART, 0x01},
+ {SENSOR, OV7660_VSTOP, 0x7a},
+ {SENSOR, OV7660_VREF, 0x00},
+ {SENSOR, OV7660_COM7, 0x05},
+ {SENSOR, OV7660_COM6, 0x4b},
+ {SENSOR, OV7660_BBIAS, 0x98},
+ {SENSOR, OV7660_GbBIAS, 0x98},
+ {SENSOR, OV7660_RSVD29, 0x98},
+ {SENSOR, OV7660_RBIAS, 0x98},
+ {SENSOR, OV7660_COM1, 0x00},
+ {SENSOR, OV7660_AECH, 0x00},
+ {SENSOR, OV7660_AECHH, 0x00},
+ {SENSOR, OV7660_ADC, 0x04},
+ {SENSOR, OV7660_COM13, 0x00},
+ {SENSOR, OV7660_RSVDA1, 0x23},
+ {SENSOR, OV7660_TSLB, 0x0d},
+ {SENSOR, OV7660_HV, 0x80},
+ {SENSOR, OV7660_LCC1, 0x00},
+ {SENSOR, OV7660_LCC2, 0x00},
+ {SENSOR, OV7660_LCC3, 0x10},
+ {SENSOR, OV7660_LCC4, 0x40},
+ {SENSOR, OV7660_LCC5, 0x01},
+
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+ {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+ {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+ {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
+ {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
+ {BRIDGE, M5602_XB_SIG_INI, 0x01},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+ {BRIDGE, M5602_XB_SIG_INI, 0x00},
+ {BRIDGE, M5602_XB_SIG_INI, 0x02},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */
+ {BRIDGE, M5602_XB_SIG_INI, 0x00},
+
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+
+ {SENSOR, OV7660_AECH, 0x20},
+ {SENSOR, OV7660_COM1, 0x00},
+ {SENSOR, OV7660_OFON, 0x0c},
+ {SENSOR, OV7660_COM2, 0x11},
+ {SENSOR, OV7660_COM7, 0x05},
+ {SENSOR, OV7660_BLUE_GAIN, 0x80},
+ {SENSOR, OV7660_RED_GAIN, 0x80},
+
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
+ {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
+ {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}
+};
+
+#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index fc4548fd441d..e0ec7a6ffa6c 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -18,12 +18,41 @@
#include "m5602_ov9650.h"
+static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 *val);
+static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 val);
+static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
+
/* Vertically and horizontally flips the image if matched, needed for machines
where the sensor is mounted upside down */
static
const
struct dmi_system_id ov9650_flip_dmi_table[] = {
{
+ .ident = "ASUS A6VA",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
+ }
+ },
+ {
+
.ident = "ASUS A6VC",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
@@ -59,6 +88,13 @@ static
}
},
{
+ .ident = "ASUS A6K",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
+ }
+ },
+ {
.ident = "Alienware Aurora m9700",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "alienware"),
@@ -68,7 +104,7 @@ static
{}
};
-const static struct ctrl ov9650_ctrls[] = {
+static const struct ctrl ov9650_ctrls[] = {
#define EXPOSURE_IDX 0
{
{
@@ -102,6 +138,7 @@ const static struct ctrl ov9650_ctrls[] = {
#define RED_BALANCE_IDX 2
{
{
+ .id = V4L2_CID_RED_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "red balance",
.minimum = 0x00,
@@ -116,6 +153,7 @@ const static struct ctrl ov9650_ctrls[] = {
#define BLUE_BALANCE_IDX 3
{
{
+ .id = V4L2_CID_BLUE_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "blue balance",
.minimum = 0x00,
@@ -182,7 +220,22 @@ const static struct ctrl ov9650_ctrls[] = {
},
.set = ov9650_set_auto_gain,
.get = ov9650_get_auto_gain
+ },
+#define AUTO_EXPOSURE_IDX 8
+ {
+ {
+ .id = V4L2_CID_EXPOSURE_AUTO,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "auto exposure",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = ov9650_set_auto_exposure,
+ .get = ov9650_get_auto_exposure
}
+
};
static struct v4l2_pix_format ov9650_modes[] = {
@@ -289,12 +342,6 @@ sensor_found:
for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++)
sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value;
sd->sensor_priv = sensor_settings;
-
- if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
- info("vflip quirk active");
- sensor_settings[VFLIP_IDX] = 1;
- }
-
return 0;
}
@@ -316,7 +363,8 @@ int ov9650_init(struct sd *sd)
err = m5602_write_bridge(sd, init_ov9650[i][1], data);
}
- err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
+ err = ov9650_set_exposure(&sd->gspca_dev,
+ sensor_settings[EXPOSURE_IDX]);
if (err < 0)
return err;
@@ -324,11 +372,13 @@ int ov9650_init(struct sd *sd)
if (err < 0)
return err;
- err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]);
+ err = ov9650_set_red_balance(&sd->gspca_dev,
+ sensor_settings[RED_BALANCE_IDX]);
if (err < 0)
return err;
- err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]);
+ err = ov9650_set_blue_balance(&sd->gspca_dev,
+ sensor_settings[BLUE_BALANCE_IDX]);
if (err < 0)
return err;
@@ -340,11 +390,18 @@ int ov9650_init(struct sd *sd)
if (err < 0)
return err;
- err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+ err = ov9650_set_auto_exposure(&sd->gspca_dev,
+ sensor_settings[AUTO_EXPOSURE_IDX]);
if (err < 0)
return err;
- err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]);
+ err = ov9650_set_auto_white_balance(&sd->gspca_dev,
+ sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = ov9650_set_auto_gain(&sd->gspca_dev,
+ sensor_settings[AUTO_GAIN_CTRL_IDX]);
return err;
}
@@ -360,7 +417,10 @@ int ov9650_start(struct sd *sd)
int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
int hor_offs = OV9650_LEFT_OFFSET;
- if (sensor_settings[VFLIP_IDX])
+ if ((!dmi_check_system(ov9650_flip_dmi_table) &&
+ sensor_settings[VFLIP_IDX]) ||
+ (dmi_check_system(ov9650_flip_dmi_table) &&
+ !sensor_settings[VFLIP_IDX]))
ver_offs--;
if (width <= 320)
@@ -406,6 +466,14 @@ int ov9650_start(struct sd *sd)
if (err < 0)
return err;
+ err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
+ if (err < 0)
+ return err;
+
err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
(hor_offs >> 8) & 0xff);
if (err < 0)
@@ -425,6 +493,10 @@ int ov9650_start(struct sd *sd)
if (err < 0)
return err;
+ err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
+ if (err < 0)
+ return err;
+
switch (width) {
case 640:
PDEBUG(D_V4L2, "Configuring camera for VGA mode");
@@ -467,32 +539,15 @@ int ov9650_stop(struct sd *sd)
return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
}
-int ov9650_power_down(struct sd *sd)
-{
- int i, err = 0;
- for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) {
- u8 data = power_down_ov9650[i][2];
- if (power_down_ov9650[i][0] == SENSOR)
- err = m5602_write_sensor(sd,
- power_down_ov9650[i][1], &data, 1);
- else
- err = m5602_write_bridge(sd, power_down_ov9650[i][1],
- data);
- }
-
- return err;
-}
-
void ov9650_disconnect(struct sd *sd)
{
ov9650_stop(sd);
- ov9650_power_down(sd);
sd->sensor = NULL;
kfree(sd->sensor_priv);
}
-int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
@@ -502,7 +557,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
@@ -532,7 +587,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
return err;
}
-int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
@@ -542,7 +597,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 i2c_data;
@@ -573,7 +628,7 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
return err;
}
-int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
@@ -583,7 +638,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 i2c_data;
@@ -599,7 +654,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
return err;
}
-int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
@@ -610,7 +665,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 i2c_data;
@@ -626,7 +681,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
return err;
}
-int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
@@ -636,7 +691,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 i2c_data;
@@ -646,13 +701,20 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
sensor_settings[HFLIP_IDX] = val;
- i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4);
+
+ if (!dmi_check_system(ov9650_flip_dmi_table))
+ i2c_data = ((val & 0x01) << 5) |
+ (sensor_settings[VFLIP_IDX] << 4);
+ else
+ i2c_data = ((val & 0x01) << 5) |
+ (!sensor_settings[VFLIP_IDX] << 4);
+
err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
return err;
}
-int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
@@ -663,7 +725,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 i2c_data;
@@ -673,6 +735,9 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
PDEBUG(D_V4L2, "Set vertical flip to %d", val);
sensor_settings[VFLIP_IDX] = val;
+ if (dmi_check_system(ov9650_flip_dmi_table))
+ val = !val;
+
i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
if (err < 0)
@@ -685,48 +750,38 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
return err;
}
-int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
- *val = sensor_settings[GAIN_IDX];
- PDEBUG(D_V4L2, "Read gain %d", *val);
-
+ *val = sensor_settings[AUTO_EXPOSURE_IDX];
+ PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
return 0;
}
-int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
+ __s32 val)
{
int err;
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
- PDEBUG(D_V4L2, "Set gain to %d", val);
-
- sensor_settings[GAIN_IDX] = val;
+ PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
- /* Read the OV9650_VREF register first to avoid
- corrupting the VREF high and low bits */
- err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
- if (err < 0)
- return err;
-
- /* Mask away all uninteresting bits */
- i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F);
- err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
+ sensor_settings[AUTO_EXPOSURE_IDX] = val;
+ err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
if (err < 0)
return err;
- /* The 8 LSBs */
- i2c_data = val & 0xff;
- err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
+ i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
- return err;
+ return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
}
-int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
@@ -735,7 +790,8 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 val)
{
int err;
u8 i2c_data;
@@ -755,7 +811,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
return err;
}
-int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
@@ -765,7 +821,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 i2c_data;
@@ -780,9 +836,8 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
return err;
i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
- err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
- return err;
+ return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
}
static void ov9650_dump_registers(struct sd *sd)
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index fcc54e4c0f4f..c98c40d69e05 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -120,6 +120,10 @@
#define OV9650_SOFT_SLEEP (1 << 4)
#define OV9650_OUTPUT_DRIVE_2X (1 << 0)
+#define OV9650_DENOISE_ENABLE (1 << 5)
+#define OV9650_WHITE_PIXEL_ENABLE (1 << 1)
+#define OV9650_WHITE_PIXEL_OPTION (1 << 0)
+
#define OV9650_LEFT_OFFSET 0x62
#define GAIN_DEFAULT 0x14
@@ -137,29 +141,9 @@ int ov9650_probe(struct sd *sd);
int ov9650_init(struct sd *sd);
int ov9650_start(struct sd *sd);
int ov9650_stop(struct sd *sd);
-int ov9650_power_down(struct sd *sd);
void ov9650_disconnect(struct sd *sd);
-int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
-
-const static struct m5602_sensor ov9650 = {
+static const struct m5602_sensor ov9650 = {
.name = "OV9650",
.i2c_slave_id = 0x60,
.i2c_regW = 1,
@@ -167,7 +151,6 @@ const static struct m5602_sensor ov9650 = {
.init = ov9650_init,
.start = ov9650_start,
.stop = ov9650_stop,
- .power_down = ov9650_power_down,
.disconnect = ov9650_disconnect,
};
@@ -219,7 +202,7 @@ static const unsigned char init_ov9650[][3] =
/* Reset chip */
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
/* One extra reset is needed in order to make the sensor behave
- properly when resuming from ram */
+ properly when resuming from ram, could be a timing issue */
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
/* Enable double clock */
@@ -229,8 +212,7 @@ static const unsigned char init_ov9650[][3] =
/* Set fast AGC/AEC algorithm with unlimited step size */
{SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
- OV9650_AEC_UNLIM_STEP_SIZE |
- OV9650_AWB_EN | OV9650_AGC_EN},
+ OV9650_AEC_UNLIM_STEP_SIZE},
{SENSOR, OV9650_CHLF, 0x10},
{SENSOR, OV9650_ARBLM, 0xbf},
@@ -301,8 +283,11 @@ static const unsigned char init_ov9650[][3] =
{SENSOR, OV9650_VREF, 0x10},
{SENSOR, OV9650_ADC, 0x04},
{SENSOR, OV9650_HV, 0x40},
+
/* Enable denoise, and white-pixel erase */
- {SENSOR, OV9650_COM22, 0x23},
+ {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE |
+ OV9650_WHITE_PIXEL_ENABLE |
+ OV9650_WHITE_PIXEL_OPTION},
/* Enable VARIOPIXEL */
{SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
@@ -312,26 +297,6 @@ static const unsigned char init_ov9650[][3] =
{SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
};
-static const unsigned char power_down_ov9650[][3] =
-{
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {SENSOR, OV9650_COM7, 0x80},
- {SENSOR, OV9650_OFON, 0xf4},
- {SENSOR, OV9650_MVFP, 0x80},
- {SENSOR, OV9650_DBLV, 0x3f},
- {SENSOR, OV9650_RSVD36, 0x49},
- {SENSOR, OV9650_COM7, 0x05},
-
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x06},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-};
-
static const unsigned char res_init_ov9650[][3] =
{
{SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index eaddf488bad1..8d74d8065b79 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -18,6 +18,29 @@
#include "m5602_po1030.h"
+static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 val);
+static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 *val);
+static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
+ __s32 val);
+static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
+ __s32 *val);
+
static struct v4l2_pix_format po1030_modes[] = {
{
640,
@@ -27,11 +50,12 @@ static struct v4l2_pix_format po1030_modes[] = {
.sizeimage = 640 * 480,
.bytesperline = 640,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
+ .priv = 2
}
};
-const static struct ctrl po1030_ctrls[] = {
+static const struct ctrl po1030_ctrls[] = {
+#define GAIN_IDX 0
{
{
.id = V4L2_CID_GAIN,
@@ -45,7 +69,9 @@ const static struct ctrl po1030_ctrls[] = {
},
.set = po1030_set_gain,
.get = po1030_get_gain
- }, {
+ },
+#define EXPOSURE_IDX 1
+ {
{
.id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -58,7 +84,9 @@ const static struct ctrl po1030_ctrls[] = {
},
.set = po1030_set_exposure,
.get = po1030_get_exposure
- }, {
+ },
+#define RED_BALANCE_IDX 2
+ {
{
.id = V4L2_CID_RED_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -71,7 +99,9 @@ const static struct ctrl po1030_ctrls[] = {
},
.set = po1030_set_red_balance,
.get = po1030_get_red_balance
- }, {
+ },
+#define BLUE_BALANCE_IDX 3
+ {
{
.id = V4L2_CID_BLUE_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -84,7 +114,9 @@ const static struct ctrl po1030_ctrls[] = {
},
.set = po1030_set_blue_balance,
.get = po1030_get_blue_balance
- }, {
+ },
+#define HFLIP_IDX 4
+ {
{
.id = V4L2_CID_HFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -96,7 +128,9 @@ const static struct ctrl po1030_ctrls[] = {
},
.set = po1030_set_hflip,
.get = po1030_get_hflip
- }, {
+ },
+#define VFLIP_IDX 5
+ {
{
.id = V4L2_CID_VFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -108,14 +142,58 @@ const static struct ctrl po1030_ctrls[] = {
},
.set = po1030_set_vflip,
.get = po1030_get_vflip
- }
+ },
+#define AUTO_WHITE_BALANCE_IDX 6
+ {
+ {
+ .id = V4L2_CID_AUTO_WHITE_BALANCE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "auto white balance",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = po1030_set_auto_white_balance,
+ .get = po1030_get_auto_white_balance
+ },
+#define AUTO_EXPOSURE_IDX 7
+ {
+ {
+ .id = V4L2_CID_EXPOSURE_AUTO,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "auto exposure",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = po1030_set_auto_exposure,
+ .get = po1030_get_auto_exposure
+ },
+#define GREEN_BALANCE_IDX 8
+ {
+ {
+ .id = M5602_V4L2_CID_GREEN_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "green balance",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x1,
+ .default_value = PO1030_GREEN_GAIN_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = po1030_set_green_balance,
+ .get = po1030_get_green_balance
+ },
};
static void po1030_dump_registers(struct sd *sd);
int po1030_probe(struct sd *sd)
{
- u8 prod_id = 0, ver_id = 0, i;
+ u8 dev_id_h = 0, i;
+ s32 *sensor_settings;
if (force_sensor) {
if (force_sensor == PO1030_SENSOR) {
@@ -139,28 +217,36 @@ int po1030_probe(struct sd *sd)
m5602_write_bridge(sd, preinit_po1030[i][1], data);
}
- if (m5602_read_sensor(sd, 0x3, &prod_id, 1))
+ if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
return -ENODEV;
- if (m5602_read_sensor(sd, 0x4, &ver_id, 1))
- return -ENODEV;
-
- if ((prod_id == 0x02) && (ver_id == 0xef)) {
+ if (dev_id_h == 0x30) {
info("Detected a po1030 sensor");
goto sensor_found;
}
return -ENODEV;
sensor_found:
+ sensor_settings = kmalloc(
+ ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL);
+ if (!sensor_settings)
+ return -ENOMEM;
+
sd->gspca_dev.cam.cam_mode = po1030_modes;
sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
sd->desc->ctrls = po1030_ctrls;
sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
+
+ for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++)
+ sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
+ sd->sensor_priv = sensor_settings;
+
return 0;
}
int po1030_init(struct sd *sd)
{
+ s32 *sensor_settings = sd->sensor_priv;
int i, err = 0;
/* Init the sensor */
@@ -185,47 +271,206 @@ int po1030_init(struct sd *sd)
return -EINVAL;
}
}
+ if (err < 0)
+ return err;
if (dump_sensor)
po1030_dump_registers(sd);
+ err = po1030_set_exposure(&sd->gspca_dev,
+ sensor_settings[EXPOSURE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+ if (err < 0)
+ return err;
+
+ err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+ if (err < 0)
+ return err;
+
+ err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+ if (err < 0)
+ return err;
+
+ err = po1030_set_red_balance(&sd->gspca_dev,
+ sensor_settings[RED_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = po1030_set_blue_balance(&sd->gspca_dev,
+ sensor_settings[BLUE_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = po1030_set_green_balance(&sd->gspca_dev,
+ sensor_settings[GREEN_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = po1030_set_auto_white_balance(&sd->gspca_dev,
+ sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = po1030_set_auto_exposure(&sd->gspca_dev,
+ sensor_settings[AUTO_EXPOSURE_IDX]);
return err;
}
-int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+int po1030_start(struct sd *sd)
{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 i2c_data;
- int err;
+ struct cam *cam = &sd->gspca_dev.cam;
+ int i, err = 0;
+ int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
+ int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
+ int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
+ u8 data;
+
+ switch (width) {
+ case 320:
+ data = PO1030_SUBSAMPLING;
+ err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
+ if (err < 0)
+ return err;
+
+ data = ((width + 3) >> 8) & 0xff;
+ err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
+ if (err < 0)
+ return err;
+
+ data = (width + 3) & 0xff;
+ err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
+ if (err < 0)
+ return err;
+
+ data = ((height + 1) >> 8) & 0xff;
+ err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
+ if (err < 0)
+ return err;
+
+ data = (height + 1) & 0xff;
+ err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
+
+ height += 6;
+ width -= 1;
+ break;
+
+ case 640:
+ data = 0;
+ err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
+ if (err < 0)
+ return err;
+
+ data = ((width + 7) >> 8) & 0xff;
+ err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
+ if (err < 0)
+ return err;
+
+ data = (width + 7) & 0xff;
+ err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
+ if (err < 0)
+ return err;
+
+ data = ((height + 3) >> 8) & 0xff;
+ err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
+ if (err < 0)
+ return err;
+
+ data = (height + 3) & 0xff;
+ err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
+
+ height += 12;
+ width -= 2;
+ break;
+ }
+ err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c);
+ if (err < 0)
+ return err;
- err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H,
- &i2c_data, 1);
+ err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81);
if (err < 0)
return err;
- *val = (i2c_data << 8);
- err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M,
- &i2c_data, 1);
- *val |= i2c_data;
+ err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82);
+ if (err < 0)
+ return err;
- PDEBUG(D_V4L2, "Exposure read as %d", *val);
+ err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
+ ((ver_offs >> 8) & 0xff));
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < 2 && !err; i++)
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < 2 && !err; i++)
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+
+ for (i = 0; i < 2 && !err; i++)
+ err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
+
+ for (i = 0; i < 2 && !err; i++)
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff);
+ if (err < 0)
+ return err;
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff));
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
return err;
}
-int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[EXPOSURE_IDX];
+ PDEBUG(D_V4L2, "Exposure read as %d", *val);
+ return 0;
+}
+
+static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 i2c_data;
int err;
+ sensor_settings[EXPOSURE_IDX] = val;
PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
i2c_data = ((val & 0xff00) >> 8);
PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
i2c_data);
- err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H,
+ err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
&i2c_data, 1);
if (err < 0)
return err;
@@ -233,167 +478,256 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
i2c_data = (val & 0xff);
PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
i2c_data);
- err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M,
+ err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
&i2c_data, 1);
return err;
}
-int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- u8 i2c_data;
- int err;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
- &i2c_data, 1);
- *val = i2c_data;
+ *val = sensor_settings[GAIN_IDX];
PDEBUG(D_V4L2, "Read global gain %d", *val);
-
- return err;
+ return 0;
}
-int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 i2c_data;
int err;
- err = m5602_read_sensor(sd, PO1030_REG_CONTROL2,
+ sensor_settings[GAIN_IDX] = val;
+
+ i2c_data = val & 0xff;
+ PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
+ err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
&i2c_data, 1);
+ return err;
+}
- *val = (i2c_data >> 7) & 0x01 ;
+static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+ *val = sensor_settings[HFLIP_IDX];
PDEBUG(D_V4L2, "Read hflip %d", *val);
- return err;
+ return 0;
}
-int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 i2c_data;
int err;
+ sensor_settings[HFLIP_IDX] = val;
+
PDEBUG(D_V4L2, "Set hflip %d", val);
- err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
+ err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
if (err < 0)
return err;
i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
- err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
+ err = m5602_write_sensor(sd, PO1030_CONTROL2,
&i2c_data, 1);
return err;
}
-int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- u8 i2c_data;
- int err;
-
- err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
- &i2c_data, 1);
-
- *val = (i2c_data >> 6) & 0x01;
+ s32 *sensor_settings = sd->sensor_priv;
+ *val = sensor_settings[VFLIP_IDX];
PDEBUG(D_V4L2, "Read vflip %d", *val);
- return err;
+ return 0;
}
-int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 i2c_data;
int err;
+ sensor_settings[VFLIP_IDX] = val;
+
PDEBUG(D_V4L2, "Set vflip %d", val);
- err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
+ err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
if (err < 0)
return err;
i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
- err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
+ err = m5602_write_sensor(sd, PO1030_CONTROL2,
&i2c_data, 1);
return err;
}
-int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[RED_BALANCE_IDX];
+ PDEBUG(D_V4L2, "Read red gain %d", *val);
+ return 0;
+}
+
+static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 i2c_data;
int err;
+ sensor_settings[RED_BALANCE_IDX] = val;
+
i2c_data = val & 0xff;
- PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
- err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
+ PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
+ err = m5602_write_sensor(sd, PO1030_RED_GAIN,
&i2c_data, 1);
return err;
}
-int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- u8 i2c_data;
- int err;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN,
- &i2c_data, 1);
- *val = i2c_data;
- PDEBUG(D_V4L2, "Read red gain %d", *val);
- return err;
+ *val = sensor_settings[BLUE_BALANCE_IDX];
+ PDEBUG(D_V4L2, "Read blue gain %d", *val);
+
+ return 0;
}
-int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 i2c_data;
int err;
+ sensor_settings[BLUE_BALANCE_IDX] = val;
+
i2c_data = val & 0xff;
- PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
- err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN,
+ PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
+ err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
&i2c_data, 1);
+
return err;
}
-int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[GREEN_BALANCE_IDX];
+ PDEBUG(D_V4L2, "Read green gain %d", *val);
+
+ return 0;
+}
+
+static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 i2c_data;
int err;
- err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN,
+ sensor_settings[GREEN_BALANCE_IDX] = val;
+ i2c_data = val & 0xff;
+ PDEBUG(D_V4L2, "Set green gain to %d", i2c_data);
+
+ err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
+ &i2c_data, 1);
+ if (err < 0)
+ return err;
+
+ return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN,
&i2c_data, 1);
- *val = i2c_data;
- PDEBUG(D_V4L2, "Read blue gain %d", *val);
+}
- return err;
+static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
+ PDEBUG(D_V4L2, "Auto white balancing is %d", *val);
+
+ return 0;
}
-int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
+ __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 i2c_data;
int err;
- i2c_data = val & 0xff;
- PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
- err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
- &i2c_data, 1);
+ sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
+
+ err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
+ if (err < 0)
+ return err;
+
+ PDEBUG(D_V4L2, "Set auto white balance to %d", val);
+ i2c_data = (i2c_data & 0xfe) | (val & 0x01);
+ err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
return err;
}
-int po1030_power_down(struct sd *sd)
+static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
+ __s32 *val)
{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[AUTO_EXPOSURE_IDX];
+ PDEBUG(D_V4L2, "Auto exposure is %d", *val);
return 0;
}
+static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
+ __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+ u8 i2c_data;
+ int err;
+
+ sensor_settings[AUTO_EXPOSURE_IDX] = val;
+ err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
+ if (err < 0)
+ return err;
+
+ PDEBUG(D_V4L2, "Set auto exposure to %d", val);
+ i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
+ return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
+}
+
+void po1030_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
static void po1030_dump_registers(struct sd *sd)
{
int address;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index c10b12335818..1ea380b2bbe7 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -25,98 +25,123 @@
/*****************************************************************************/
-#define PO1030_REG_DEVID_H 0x00
-#define PO1030_REG_DEVID_L 0x01
-#define PO1030_REG_FRAMEWIDTH_H 0x04
-#define PO1030_REG_FRAMEWIDTH_L 0x05
-#define PO1030_REG_FRAMEHEIGHT_H 0x06
-#define PO1030_REG_FRAMEHEIGHT_L 0x07
-#define PO1030_REG_WINDOWX_H 0x08
-#define PO1030_REG_WINDOWX_L 0x09
-#define PO1030_REG_WINDOWY_H 0x0a
-#define PO1030_REG_WINDOWY_L 0x0b
-#define PO1030_REG_WINDOWWIDTH_H 0x0c
-#define PO1030_REG_WINDOWWIDTH_L 0x0d
-#define PO1030_REG_WINDOWHEIGHT_H 0x0e
-#define PO1030_REG_WINDOWHEIGHT_L 0x0f
-
-#define PO1030_REG_GLOBALIBIAS 0x12
-#define PO1030_REG_PIXELIBIAS 0x13
-
-#define PO1030_REG_GLOBALGAIN 0x15
-#define PO1030_REG_RED_GAIN 0x16
-#define PO1030_REG_GREEN_1_GAIN 0x17
-#define PO1030_REG_BLUE_GAIN 0x18
-#define PO1030_REG_GREEN_2_GAIN 0x19
-
-#define PO1030_REG_INTEGLINES_H 0x1a
-#define PO1030_REG_INTEGLINES_M 0x1b
-#define PO1030_REG_INTEGLINES_L 0x1c
-
-#define PO1030_REG_CONTROL1 0x1d
-#define PO1030_REG_CONTROL2 0x1e
-#define PO1030_REG_CONTROL3 0x1f
-#define PO1030_REG_CONTROL4 0x20
-
-#define PO1030_REG_PERIOD50_H 0x23
-#define PO1030_REG_PERIOD50_L 0x24
-#define PO1030_REG_PERIOD60_H 0x25
-#define PO1030_REG_PERIOD60_L 0x26
-#define PO1030_REG_REGCLK167 0x27
-#define PO1030_REG_DELTA50 0x28
-#define PO1030_REG_DELTA60 0x29
-
-#define PO1030_REG_ADCOFFSET 0x2c
+#define PO1030_DEVID_H 0x00
+#define PO1030_DEVID_L 0x01
+#define PO1030_FRAMEWIDTH_H 0x04
+#define PO1030_FRAMEWIDTH_L 0x05
+#define PO1030_FRAMEHEIGHT_H 0x06
+#define PO1030_FRAMEHEIGHT_L 0x07
+#define PO1030_WINDOWX_H 0x08
+#define PO1030_WINDOWX_L 0x09
+#define PO1030_WINDOWY_H 0x0a
+#define PO1030_WINDOWY_L 0x0b
+#define PO1030_WINDOWWIDTH_H 0x0c
+#define PO1030_WINDOWWIDTH_L 0x0d
+#define PO1030_WINDOWHEIGHT_H 0x0e
+#define PO1030_WINDOWHEIGHT_L 0x0f
+
+#define PO1030_GLOBALIBIAS 0x12
+#define PO1030_PIXELIBIAS 0x13
+
+#define PO1030_GLOBALGAIN 0x15
+#define PO1030_RED_GAIN 0x16
+#define PO1030_GREEN_1_GAIN 0x17
+#define PO1030_BLUE_GAIN 0x18
+#define PO1030_GREEN_2_GAIN 0x19
+
+#define PO1030_INTEGLINES_H 0x1a
+#define PO1030_INTEGLINES_M 0x1b
+#define PO1030_INTEGLINES_L 0x1c
+
+#define PO1030_CONTROL1 0x1d
+#define PO1030_CONTROL2 0x1e
+#define PO1030_CONTROL3 0x1f
+#define PO1030_CONTROL4 0x20
+
+#define PO1030_PERIOD50_H 0x23
+#define PO1030_PERIOD50_L 0x24
+#define PO1030_PERIOD60_H 0x25
+#define PO1030_PERIOD60_L 0x26
+#define PO1030_REGCLK167 0x27
+#define PO1030_FLICKER_DELTA50 0x28
+#define PO1030_FLICKERDELTA60 0x29
+
+#define PO1030_ADCOFFSET 0x2c
/* Gamma Correction Coeffs */
-#define PO1030_REG_GC0 0x2d
-#define PO1030_REG_GC1 0x2e
-#define PO1030_REG_GC2 0x2f
-#define PO1030_REG_GC3 0x30
-#define PO1030_REG_GC4 0x31
-#define PO1030_REG_GC5 0x32
-#define PO1030_REG_GC6 0x33
-#define PO1030_REG_GC7 0x34
+#define PO1030_GC0 0x2d
+#define PO1030_GC1 0x2e
+#define PO1030_GC2 0x2f
+#define PO1030_GC3 0x30
+#define PO1030_GC4 0x31
+#define PO1030_GC5 0x32
+#define PO1030_GC6 0x33
+#define PO1030_GC7 0x34
/* Color Transform Matrix */
-#define PO1030_REG_CT0 0x35
-#define PO1030_REG_CT1 0x36
-#define PO1030_REG_CT2 0x37
-#define PO1030_REG_CT3 0x38
-#define PO1030_REG_CT4 0x39
-#define PO1030_REG_CT5 0x3a
-#define PO1030_REG_CT6 0x3b
-#define PO1030_REG_CT7 0x3c
-#define PO1030_REG_CT8 0x3d
-
-#define PO1030_REG_AUTOCTRL1 0x3e
-#define PO1030_REG_AUTOCTRL2 0x3f
-
-#define PO1030_REG_YTARGET 0x40
-#define PO1030_REG_GLOBALGAINMIN 0x41
-#define PO1030_REG_GLOBALGAINMAX 0x42
+#define PO1030_CT0 0x35
+#define PO1030_CT1 0x36
+#define PO1030_CT2 0x37
+#define PO1030_CT3 0x38
+#define PO1030_CT4 0x39
+#define PO1030_CT5 0x3a
+#define PO1030_CT6 0x3b
+#define PO1030_CT7 0x3c
+#define PO1030_CT8 0x3d
+
+#define PO1030_AUTOCTRL1 0x3e
+#define PO1030_AUTOCTRL2 0x3f
+
+#define PO1030_YTARGET 0x40
+#define PO1030_GLOBALGAINMIN 0x41
+#define PO1030_GLOBALGAINMAX 0x42
+
+#define PO1030_AWB_RED_TUNING 0x47
+#define PO1030_AWB_BLUE_TUNING 0x48
/* Output format control */
-#define PO1030_REG_OUTFORMCTRL1 0x5a
-#define PO1030_REG_OUTFORMCTRL2 0x5b
-#define PO1030_REG_OUTFORMCTRL3 0x5c
-#define PO1030_REG_OUTFORMCTRL4 0x5d
-#define PO1030_REG_OUTFORMCTRL5 0x5e
+#define PO1030_OUTFORMCTRL1 0x5a
+#define PO1030_OUTFORMCTRL2 0x5b
+#define PO1030_OUTFORMCTRL3 0x5c
+#define PO1030_OUTFORMCTRL4 0x5d
+#define PO1030_OUTFORMCTRL5 0x5e
-/* Imaging coefficients */
-#define PO1030_REG_YBRIGHT 0x73
-#define PO1030_REG_YCONTRAST 0x74
-#define PO1030_REG_YSATURATION 0x75
+#define PO1030_EDGE_ENH_OFF 0x5f
+#define PO1030_EGA 0x60
-#define PO1030_HFLIP (1 << 7)
-#define PO1030_VFLIP (1 << 6)
+#define PO1030_Cb_U_GAIN 0x63
+#define PO1030_Cr_V_GAIN 0x64
+
+#define PO1030_YCONTRAST 0x74
+#define PO1030_YSATURATION 0x75
+
+#define PO1030_HFLIP (1 << 7)
+#define PO1030_VFLIP (1 << 6)
+
+#define PO1030_HREF_ENABLE (1 << 6)
+
+#define PO1030_RAW_RGB_BAYER 0x4
+
+#define PO1030_FRAME_EQUAL (1 << 3)
+#define PO1030_AUTO_SUBSAMPLING (1 << 4)
+
+#define PO1030_WEIGHT_WIN_2X (1 << 3)
+
+#define PO1030_SHUTTER_MODE (1 << 6)
+#define PO1030_AUTO_SUBSAMPLING (1 << 4)
+#define PO1030_FRAME_EQUAL (1 << 3)
+
+#define PO1030_SENSOR_RESET (1 << 5)
+
+#define PO1030_SUBSAMPLING (1 << 6)
/*****************************************************************************/
#define PO1030_GLOBAL_GAIN_DEFAULT 0x12
#define PO1030_EXPOSURE_DEFAULT 0x0085
-#define PO1030_BLUE_GAIN_DEFAULT 0x40
-#define PO1030_RED_GAIN_DEFAULT 0x40
+#define PO1030_BLUE_GAIN_DEFAULT 0x36
+#define PO1030_RED_GAIN_DEFAULT 0x36
+#define PO1030_GREEN_GAIN_DEFAULT 0x40
/*****************************************************************************/
@@ -126,20 +151,8 @@ extern int dump_sensor;
int po1030_probe(struct sd *sd);
int po1030_init(struct sd *sd);
-int po1030_power_down(struct sd *sd);
-
-int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+int po1030_start(struct sd *sd);
+void po1030_disconnect(struct sd *sd);
static const struct m5602_sensor po1030 = {
.name = "PO1030",
@@ -149,7 +162,8 @@ static const struct m5602_sensor po1030 = {
.probe = po1030_probe,
.init = po1030_init,
- .power_down = po1030_power_down,
+ .start = po1030_start,
+ .disconnect = po1030_disconnect,
};
static const unsigned char preinit_po1030[][3] =
@@ -159,248 +173,103 @@ static const unsigned char preinit_po1030[][3] =
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-
- {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
-
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
- {BRIDGE, M5602_XB_SIG_INI, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
- {BRIDGE, M5602_XB_SIG_INI, 0x00},
-
- {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
-
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
+
+ {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
+
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
{BRIDGE, M5602_XB_GPIO_DAT, 0x00}
};
-static const unsigned char init_po1030[][4] =
+static const unsigned char init_po1030[][3] =
{
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
- /*sequence 1*/
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
-
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- /*end of sequence 1*/
-
- /*sequence 2 (same as stop sequence)*/
- {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- /*end of sequence 2*/
- /*sequence 5*/
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
- {BRIDGE, M5602_XB_SIG_INI, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
- {BRIDGE, M5602_XB_SIG_INI, 0x00},
- /*end of sequence 5*/
-
- /*sequence 2 stop */
- {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
+ {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- /*end of sequence 2 stop */
-
-/* ---------------------------------
- * end of init - begin of start
- * --------------------------------- */
-
- /*sequence 3*/
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- /*end of sequence 3*/
- /*sequence 4*/
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
- {SENSOR, PO1030_REG_AUTOCTRL2, 0x04},
+ {SENSOR, PO1030_AUTOCTRL2, 0x04},
+
+ {SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER},
+ {SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X},
+
+ {SENSOR, PO1030_CONTROL2, 0x03},
+ {SENSOR, 0x21, 0x90},
+ {SENSOR, PO1030_YTARGET, 0x60},
+ {SENSOR, 0x59, 0x13},
+ {SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE},
+ {SENSOR, PO1030_EDGE_ENH_OFF, 0x00},
+ {SENSOR, PO1030_EGA, 0x80},
+ {SENSOR, 0x78, 0x14},
+ {SENSOR, 0x6f, 0x01},
+ {SENSOR, PO1030_GLOBALGAINMAX, 0x14},
+ {SENSOR, PO1030_Cb_U_GAIN, 0x38},
+ {SENSOR, PO1030_Cr_V_GAIN, 0x38},
+ {SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE |
+ PO1030_AUTO_SUBSAMPLING |
+ PO1030_FRAME_EQUAL},
+ {SENSOR, PO1030_GC0, 0x10},
+ {SENSOR, PO1030_GC1, 0x20},
+ {SENSOR, PO1030_GC2, 0x40},
+ {SENSOR, PO1030_GC3, 0x60},
+ {SENSOR, PO1030_GC4, 0x80},
+ {SENSOR, PO1030_GC5, 0xa0},
+ {SENSOR, PO1030_GC6, 0xc0},
+ {SENSOR, PO1030_GC7, 0xff},
/* Set the width to 751 */
- {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02},
- {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef},
+ {SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
+ {SENSOR, PO1030_FRAMEWIDTH_L, 0xef},
/* Set the height to 540 */
- {SENSOR, PO1030_REG_FRAMEHEIGHT_H, 0x02},
- {SENSOR, PO1030_REG_FRAMEHEIGHT_L, 0x1c},
+ {SENSOR, PO1030_FRAMEHEIGHT_H, 0x02},
+ {SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c},
/* Set the x window to 1 */
- {SENSOR, PO1030_REG_WINDOWX_H, 0x00},
- {SENSOR, PO1030_REG_WINDOWX_L, 0x01},
+ {SENSOR, PO1030_WINDOWX_H, 0x00},
+ {SENSOR, PO1030_WINDOWX_L, 0x01},
/* Set the y window to 1 */
- {SENSOR, PO1030_REG_WINDOWY_H, 0x00},
- {SENSOR, PO1030_REG_WINDOWY_L, 0x01},
-
- {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02},
- {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87},
- {SENSOR, PO1030_REG_WINDOWHEIGHT_H, 0x01},
- {SENSOR, PO1030_REG_WINDOWHEIGHT_L, 0xe3},
-
- {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04},
- {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04},
- {SENSOR, PO1030_REG_AUTOCTRL1, 0x08},
- {SENSOR, PO1030_REG_CONTROL2, 0x03},
- {SENSOR, 0x21, 0x90},
- {SENSOR, PO1030_REG_YTARGET, 0x60},
- {SENSOR, 0x59, 0x13},
- {SENSOR, PO1030_REG_OUTFORMCTRL1, 0x40},
- {SENSOR, 0x5f, 0x00},
- {SENSOR, 0x60, 0x80},
- {SENSOR, 0x78, 0x14},
- {SENSOR, 0x6f, 0x01},
- {SENSOR, PO1030_REG_CONTROL1, 0x18},
- {SENSOR, PO1030_REG_GLOBALGAINMAX, 0x14},
- {SENSOR, 0x63, 0x38},
- {SENSOR, 0x64, 0x38},
- {SENSOR, PO1030_REG_CONTROL1, 0x58},
- {SENSOR, PO1030_REG_RED_GAIN, 0x30},
- {SENSOR, PO1030_REG_GREEN_1_GAIN, 0x30},
- {SENSOR, PO1030_REG_BLUE_GAIN, 0x30},
- {SENSOR, PO1030_REG_GREEN_2_GAIN, 0x30},
- {SENSOR, PO1030_REG_GC0, 0x10},
- {SENSOR, PO1030_REG_GC1, 0x20},
- {SENSOR, PO1030_REG_GC2, 0x40},
- {SENSOR, PO1030_REG_GC3, 0x60},
- {SENSOR, PO1030_REG_GC4, 0x80},
- {SENSOR, PO1030_REG_GC5, 0xa0},
- {SENSOR, PO1030_REG_GC6, 0xc0},
- {SENSOR, PO1030_REG_GC7, 0xff},
- /*end of sequence 4*/
- /*sequence 5*/
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
- {BRIDGE, M5602_XB_SIG_INI, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x7e},
- {BRIDGE, M5602_XB_SIG_INI, 0x00},
- /*end of sequence 5*/
-
- /*sequence 6*/
- /* Changing 40 in f0 the image becomes green in bayer mode and red in
- * rgb mode */
- {SENSOR, PO1030_REG_RED_GAIN, PO1030_RED_GAIN_DEFAULT},
- /* in changing 40 in f0 the image becomes green in bayer mode and red in
- * rgb mode */
- {SENSOR, PO1030_REG_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT},
+ {SENSOR, PO1030_WINDOWY_H, 0x00},
+ {SENSOR, PO1030_WINDOWY_L, 0x01},
/* with a very low lighted environment increase the exposure but
* decrease the FPS (Frame Per Second) */
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- /* Controls high exposure more than SENSOR_LOW_EXPOSURE, use only in
- * low lighted environment (f0 is more than ff ?)*/
- {SENSOR, PO1030_REG_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2)
- & 0xff)},
-
- /* Controls middle exposure, use only in high lighted environment */
- {SENSOR, PO1030_REG_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff},
-
- /* Controls clarity (not sure) */
- {SENSOR, PO1030_REG_INTEGLINES_L, 0x00},
- /* Controls gain (the image is more lighted) */
- {SENSOR, PO1030_REG_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT},
-
- /* Sets the width */
- {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02},
- {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}
- /*end of sequence 6*/
+ {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+ {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+ {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+ {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
};
#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 4306d596056d..e5fed5b89ff4 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -18,6 +18,19 @@
#include "m5602_s5k4aa.h"
+static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
+
static
const
struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
@@ -46,6 +59,12 @@ static
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700")
}
+ }, {
+ .ident = "MSI L735",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X")
+ }
},
{ }
};
@@ -61,10 +80,22 @@ static struct v4l2_pix_format s5k4aa_modes[] = {
.bytesperline = 640,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 0
+ },
+ {
+ 1280,
+ 1024,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ 1280 * 1024,
+ .bytesperline = 1280,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
}
};
-const static struct ctrl s5k4aa_ctrls[] = {
+static const struct ctrl s5k4aa_ctrls[] = {
+#define VFLIP_IDX 0
{
{
.id = V4L2_CID_VFLIP,
@@ -77,8 +108,9 @@ const static struct ctrl s5k4aa_ctrls[] = {
},
.set = s5k4aa_set_vflip,
.get = s5k4aa_get_vflip
-
- }, {
+ },
+#define HFLIP_IDX 1
+ {
{
.id = V4L2_CID_HFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -90,8 +122,9 @@ const static struct ctrl s5k4aa_ctrls[] = {
},
.set = s5k4aa_set_hflip,
.get = s5k4aa_get_hflip
-
- }, {
+ },
+#define GAIN_IDX 2
+ {
{
.id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -99,12 +132,14 @@ const static struct ctrl s5k4aa_ctrls[] = {
.minimum = 0,
.maximum = 127,
.step = 1,
- .default_value = 0xa0,
+ .default_value = S5K4AA_DEFAULT_GAIN,
.flags = V4L2_CTRL_FLAG_SLIDER
},
.set = s5k4aa_set_gain,
.get = s5k4aa_get_gain
- }, {
+ },
+#define EXPOSURE_IDX 3
+ {
{
.id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -117,7 +152,36 @@ const static struct ctrl s5k4aa_ctrls[] = {
},
.set = s5k4aa_set_exposure,
.get = s5k4aa_get_exposure
- }
+ },
+#define NOISE_SUPP_IDX 4
+ {
+ {
+ .id = V4L2_CID_PRIVATE_BASE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Noise suppression (smoothing)",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ .set = s5k4aa_set_noise,
+ .get = s5k4aa_get_noise
+ },
+#define BRIGHTNESS_IDX 5
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 0x1f,
+ .step = 1,
+ .default_value = S5K4AA_DEFAULT_BRIGHTNESS,
+ },
+ .set = s5k4aa_set_brightness,
+ .get = s5k4aa_get_brightness
+ },
+
};
static void s5k4aa_dump_registers(struct sd *sd);
@@ -127,6 +191,7 @@ int s5k4aa_probe(struct sd *sd)
u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75};
int i, err = 0;
+ s32 *sensor_settings;
if (force_sensor) {
if (force_sensor == S5K4AA_SENSOR) {
@@ -185,10 +250,20 @@ int s5k4aa_probe(struct sd *sd)
info("Detected a s5k4aa sensor");
sensor_found:
+ sensor_settings = kmalloc(
+ ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL);
+ if (!sensor_settings)
+ return -ENOMEM;
+
sd->gspca_dev.cam.cam_mode = s5k4aa_modes;
sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes);
sd->desc->ctrls = s5k4aa_ctrls;
sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls);
+
+ for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++)
+ sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value;
+ sd->sensor_priv = sensor_settings;
+
return 0;
}
@@ -197,9 +272,45 @@ int s5k4aa_start(struct sd *sd)
int i, err = 0;
u8 data[2];
struct cam *cam = &sd->gspca_dev.cam;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
+ case 1280:
+ PDEBUG(D_V4L2, "Configuring camera for SXGA mode");
+
+ for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) {
+ switch (SXGA_s5k4aa[i][0]) {
+ case BRIDGE:
+ err = m5602_write_bridge(sd,
+ SXGA_s5k4aa[i][1],
+ SXGA_s5k4aa[i][2]);
+ break;
+
+ case SENSOR:
+ data[0] = SXGA_s5k4aa[i][2];
+ err = m5602_write_sensor(sd,
+ SXGA_s5k4aa[i][1],
+ data, 1);
+ break;
+
+ case SENSOR_LONG:
+ data[0] = SXGA_s5k4aa[i][2];
+ data[1] = SXGA_s5k4aa[i][3];
+ err = m5602_write_sensor(sd,
+ SXGA_s5k4aa[i][1],
+ data, 2);
+ break;
+
+ default:
+ err("Invalid stream command, exiting init");
+ return -EINVAL;
+ }
+ }
+ err = s5k4aa_set_noise(&sd->gspca_dev, 0);
+ if (err < 0)
+ return err;
+ break;
- switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
- {
case 640:
PDEBUG(D_V4L2, "Configuring camera for VGA mode");
@@ -231,8 +342,37 @@ int s5k4aa_start(struct sd *sd)
return -EINVAL;
}
}
+ err = s5k4aa_set_noise(&sd->gspca_dev, 1);
+ if (err < 0)
+ return err;
+ break;
}
- return err;
+ if (err < 0)
+ return err;
+
+ err = s5k4aa_set_exposure(&sd->gspca_dev,
+ sensor_settings[EXPOSURE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+ if (err < 0)
+ return err;
+
+ err = s5k4aa_set_brightness(&sd->gspca_dev,
+ sensor_settings[BRIGHTNESS_IDX]);
+ if (err < 0)
+ return err;
+
+ err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]);
+ if (err < 0)
+ return err;
+
+ err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+ if (err < 0)
+ return err;
+
+ return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
}
int s5k4aa_init(struct sd *sd)
@@ -270,62 +410,28 @@ int s5k4aa_init(struct sd *sd)
if (dump_sensor)
s5k4aa_dump_registers(sd);
- if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) {
- u8 data = 0x02;
- info("vertical flip quirk active");
- m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
- data |= S5K4AA_RM_V_FLIP;
- data &= ~S5K4AA_RM_H_FLIP;
- m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
-
- /* Decrement COLSTART to preserve color order (BGGR) */
- m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
- data--;
- m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
-
- /* Increment ROWSTART to preserve color order (BGGR) */
- m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
- data++;
- m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
- }
-
- return (err < 0) ? err : 0;
-}
-
-int s5k4aa_power_down(struct sd *sd)
-{
- return 0;
+ return err;
}
-int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- u8 data = S5K4AA_PAGE_MAP_2;
- int err;
-
- err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- if (err < 0)
- return err;
-
- err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
- if (err < 0)
- return err;
+ s32 *sensor_settings = sd->sensor_priv;
- *val = data << 8;
- err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
- *val |= data;
+ *val = sensor_settings[EXPOSURE_IDX];
PDEBUG(D_V4L2, "Read exposure %d", *val);
- return err;
+ return 0;
}
-int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 data = S5K4AA_PAGE_MAP_2;
int err;
+ sensor_settings[EXPOSURE_IDX] = val;
PDEBUG(D_V4L2, "Set exposure to %d", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
@@ -340,29 +446,26 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
return err;
}
-int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- u8 data = S5K4AA_PAGE_MAP_2;
- int err;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- if (err < 0)
- return err;
-
- err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- *val = (data & S5K4AA_RM_V_FLIP) >> 7;
+ *val = sensor_settings[VFLIP_IDX];
PDEBUG(D_V4L2, "Read vertical flip %d", *val);
- return err;
+ return 0;
}
-int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 data = S5K4AA_PAGE_MAP_2;
int err;
+ sensor_settings[VFLIP_IDX] = val;
+
PDEBUG(D_V4L2, "Set vertical flip to %d", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
@@ -370,56 +473,48 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
if (err < 0)
return err;
- data = ((data & ~S5K4AA_RM_V_FLIP)
- | ((val & 0x01) << 7));
- err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
+
+ err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
if (err < 0)
return err;
- if (val) {
- err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
- if (err < 0)
- return err;
-
- data++;
- err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
- } else {
- err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
- if (err < 0)
- return err;
+ if (dmi_check_system(s5k4aa_vflip_dmi_table))
+ val = !val;
- data--;
- err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
- }
+ data = ((data & ~S5K4AA_RM_V_FLIP) | ((val & 0x01) << 7));
+ err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
+ if (err < 0)
+ return err;
+ err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
+ if (err < 0)
+ return err;
+ data = (data & 0xfe) | !val;
+ err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
return err;
}
-int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- u8 data = S5K4AA_PAGE_MAP_2;
- int err;
-
- err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- if (err < 0)
- return err;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- *val = (data & S5K4AA_RM_H_FLIP) >> 6;
+ *val = sensor_settings[HFLIP_IDX];
PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
- return err;
+ return 0;
}
-int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(D_V4L2, "Set horizontal flip to %d",
- val);
+ sensor_settings[HFLIP_IDX] = val;
+
+ PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
return err;
@@ -427,62 +522,116 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
if (err < 0)
return err;
+ err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
+ if (err < 0)
+ return err;
+
+ if (dmi_check_system(s5k4aa_vflip_dmi_table))
+ val = !val;
+
data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
if (err < 0)
return err;
- if (val) {
- err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
- if (err < 0)
- return err;
- data++;
- err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
- if (err < 0)
- return err;
- } else {
- err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
- if (err < 0)
- return err;
- data--;
- err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
- }
-
+ err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
+ if (err < 0)
+ return err;
+ data = (data & 0xfe) | !val;
+ err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
return err;
}
-int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[GAIN_IDX];
+ PDEBUG(D_V4L2, "Read gain %d", *val);
+ return 0;
+}
+
+static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 data = S5K4AA_PAGE_MAP_2;
int err;
+ sensor_settings[GAIN_IDX] = val;
+
+ PDEBUG(D_V4L2, "Set gain to %d", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
return err;
- err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
- *val = data;
- PDEBUG(D_V4L2, "Read gain %d", *val);
+ data = val & 0xff;
+ err = m5602_write_sensor(sd, S5K4AA_GAIN, &data, 1);
return err;
}
-int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[BRIGHTNESS_IDX];
+ PDEBUG(D_V4L2, "Read brightness %d", *val);
+ return 0;
+}
+
+static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(D_V4L2, "Set gain to %d", val);
+ sensor_settings[BRIGHTNESS_IDX] = val;
+
+ PDEBUG(D_V4L2, "Set brightness to %d", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
return err;
data = val & 0xff;
- err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1);
+ return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1);
+}
- return err;
+static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[NOISE_SUPP_IDX];
+ PDEBUG(D_V4L2, "Read noise %d", *val);
+ return 0;
+}
+
+static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+ u8 data = S5K4AA_PAGE_MAP_2;
+ int err;
+
+ sensor_settings[NOISE_SUPP_IDX] = val;
+
+ PDEBUG(D_V4L2, "Set noise to %d", val);
+ err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
+ if (err < 0)
+ return err;
+
+ data = val & 0x01;
+ return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1);
+}
+
+void s5k4aa_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
}
static void s5k4aa_dump_registers(struct sd *sd)
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index ca854d4f9475..4440da4e7f0f 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -47,8 +47,9 @@
#define S5K4AA_H_BLANK_LO__ 0x1e
#define S5K4AA_EXPOSURE_HI 0x17
#define S5K4AA_EXPOSURE_LO 0x18
-#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */
-#define S5K4AA_GAIN_2 0x20 /* (analogue?) gain : 7 bits */
+#define S5K4AA_BRIGHTNESS 0x1f /* (digital?) gain : 5 bits */
+#define S5K4AA_GAIN 0x20 /* (analogue?) gain : 7 bits */
+#define S5K4AA_NOISE_SUPP 0x37
#define S5K4AA_RM_ROW_SKIP_4X 0x08
#define S5K4AA_RM_ROW_SKIP_2X 0x04
@@ -57,6 +58,9 @@
#define S5K4AA_RM_H_FLIP 0x40
#define S5K4AA_RM_V_FLIP 0x80
+#define S5K4AA_DEFAULT_GAIN 0x5f
+#define S5K4AA_DEFAULT_BRIGHTNESS 0x10
+
/*****************************************************************************/
/* Kernel module parameters */
@@ -66,25 +70,17 @@ extern int dump_sensor;
int s5k4aa_probe(struct sd *sd);
int s5k4aa_init(struct sd *sd);
int s5k4aa_start(struct sd *sd);
-int s5k4aa_power_down(struct sd *sd);
-
-int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+void s5k4aa_disconnect(struct sd *sd);
static const struct m5602_sensor s5k4aa = {
.name = "S5K4AA",
+ .i2c_slave_id = 0x5a,
+ .i2c_regW = 2,
+
.probe = s5k4aa_probe,
.init = s5k4aa_init,
.start = s5k4aa_start,
- .power_down = s5k4aa_power_down,
- .i2c_slave_id = 0x5a,
- .i2c_regW = 2,
+ .disconnect = s5k4aa_disconnect,
};
static const unsigned char preinit_s5k4aa[][4] =
@@ -179,30 +175,12 @@ static const unsigned char init_s5k4aa[][4] =
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
{SENSOR, 0x0c, 0x05, 0x00},
{SENSOR, 0x02, 0x0e, 0x00},
- {SENSOR, S5K4AA_GAIN_1, 0x0f, 0x00},
- {SENSOR, S5K4AA_GAIN_2, 0x00, 0x00},
- {SENSOR, S5K4AA_GLOBAL_GAIN__, 0x01, 0x00},
- {SENSOR, 0x11, 0x00, 0x00},
- {SENSOR, 0x12, 0x00, 0x00},
- {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
{SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00},
{SENSOR, 0x37, 0x00, 0x00},
- {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
- {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
- {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
- {SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00},
- {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
- {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc4, 0x00},
- {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
- {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x08, 0x00},
- {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
- {SENSOR, S5K4AA_H_BLANK_LO__, 0x48, 0x00},
- {SENSOR, S5K4AA_EXPOSURE_HI, 0x00, 0x00},
- {SENSOR, S5K4AA_EXPOSURE_LO, 0x43, 0x00},
- {SENSOR, 0x11, 0x04, 0x00},
- {SENSOR, 0x12, 0xc3, 0x00},
- {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
+};
+static const unsigned char VGA_s5k4aa[][4] =
+{
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -238,7 +216,7 @@ static const unsigned char init_s5k4aa[][4] =
{SENSOR, 0x37, 0x01, 0x00},
/* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
- {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
+ {SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00},
{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
{SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
/* window_height_hi, window_height_lo : 960 = 0x03c0 */
@@ -255,12 +233,9 @@ static const unsigned char init_s5k4aa[][4] =
{SENSOR, 0x12, 0xc3, 0x00},
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
{SENSOR, 0x02, 0x0e, 0x00},
- {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
- {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
- {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
};
-static const unsigned char VGA_s5k4aa[][4] =
+static const unsigned char SXGA_s5k4aa[][4] =
{
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
@@ -273,50 +248,42 @@ static const unsigned char VGA_s5k4aa[][4] =
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
+ /* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00},
+ /* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */
+ {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
+ {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
- {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X
- | S5K4AA_RM_COL_SKIP_2X, 0x00},
- /* 0x37 : Fix image stability when light is too bright and improves
- * image quality in 640x480, but worsens it in 1280x1024 */
+ {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00},
{SENSOR, 0x37, 0x01, 0x00},
- /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
- {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
+ {SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00},
{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
- {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
- /* window_height_hi, window_height_lo : 960 = 0x03c0 */
- {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
- {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00},
- /* window_width_hi, window_width_lo : 1280 = 0x0500 */
+ {SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00},
+ {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00},
+ {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00},
{SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
{SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
- {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
- {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */
+ {SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00},
+ {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00},
{SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
{SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
{SENSOR, 0x11, 0x04, 0x00},
{SENSOR, 0x12, 0xc3, 0x00},
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
{SENSOR, 0x02, 0x0e, 0x00},
- {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
- {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
- {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
};
+
#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 42c86aa4dc8d..7127321ace8c 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -16,8 +16,20 @@
*
*/
+#include <linux/kthread.h>
#include "m5602_s5k83a.h"
+static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+
static struct v4l2_pix_format s5k83a_modes[] = {
{
640,
@@ -32,68 +44,77 @@ static struct v4l2_pix_format s5k83a_modes[] = {
}
};
-const static struct ctrl s5k83a_ctrls[] = {
+static const struct ctrl s5k83a_ctrls[] = {
+#define GAIN_IDX 0
{
{
- .id = V4L2_CID_BRIGHTNESS,
+ .id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
- .name = "brightness",
+ .name = "gain",
.minimum = 0x00,
.maximum = 0xff,
.step = 0x01,
- .default_value = S5K83A_DEFAULT_BRIGHTNESS,
+ .default_value = S5K83A_DEFAULT_GAIN,
.flags = V4L2_CTRL_FLAG_SLIDER
},
- .set = s5k83a_set_brightness,
- .get = s5k83a_get_brightness
+ .set = s5k83a_set_gain,
+ .get = s5k83a_get_gain
- }, {
+ },
+#define BRIGHTNESS_IDX 1
+ {
{
- .id = V4L2_CID_WHITENESS,
+ .id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER,
- .name = "whiteness",
+ .name = "brightness",
.minimum = 0x00,
.maximum = 0xff,
.step = 0x01,
- .default_value = S5K83A_DEFAULT_WHITENESS,
+ .default_value = S5K83A_DEFAULT_BRIGHTNESS,
.flags = V4L2_CTRL_FLAG_SLIDER
},
- .set = s5k83a_set_whiteness,
- .get = s5k83a_get_whiteness,
- }, {
+ .set = s5k83a_set_brightness,
+ .get = s5k83a_get_brightness,
+ },
+#define EXPOSURE_IDX 2
+ {
{
- .id = V4L2_CID_GAIN,
+ .id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
+ .name = "exposure",
.minimum = 0x00,
- .maximum = S5K83A_MAXIMUM_GAIN,
+ .maximum = S5K83A_MAXIMUM_EXPOSURE,
.step = 0x01,
- .default_value = S5K83A_DEFAULT_GAIN,
+ .default_value = S5K83A_DEFAULT_EXPOSURE,
.flags = V4L2_CTRL_FLAG_SLIDER
},
- .set = s5k83a_set_gain,
- .get = s5k83a_get_gain
- }, {
+ .set = s5k83a_set_exposure,
+ .get = s5k83a_get_exposure
+ },
+#define HFLIP_IDX 3
+ {
{
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
},
.set = s5k83a_set_hflip,
.get = s5k83a_get_hflip
- }, {
+ },
+#define VFLIP_IDX 4
+ {
{
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
},
.set = s5k83a_set_vflip,
.get = s5k83a_get_vflip
@@ -101,9 +122,14 @@ const static struct ctrl s5k83a_ctrls[] = {
};
static void s5k83a_dump_registers(struct sd *sd);
+static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
+static int s5k83a_set_led_indication(struct sd *sd, u8 val);
+static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
+ __s32 vflip, __s32 hflip);
int s5k83a_probe(struct sd *sd)
{
+ struct s5k83a_priv *sens_priv;
u8 prod_id = 0, ver_id = 0;
int i, err = 0;
@@ -145,16 +171,36 @@ int s5k83a_probe(struct sd *sd)
info("Detected a s5k83a sensor");
sensor_found:
+ sens_priv = kmalloc(
+ sizeof(struct s5k83a_priv), GFP_KERNEL);
+ if (!sens_priv)
+ return -ENOMEM;
+
+ sens_priv->settings =
+ kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
+ if (!sens_priv->settings)
+ return -ENOMEM;
+
sd->gspca_dev.cam.cam_mode = s5k83a_modes;
sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
sd->desc->ctrls = s5k83a_ctrls;
sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
+
+ /* null the pointer! thread is't running now */
+ sens_priv->rotation_thread = NULL;
+
+ for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++)
+ sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value;
+
+ sd->sensor_priv = sens_priv;
return 0;
}
int s5k83a_init(struct sd *sd)
{
int i, err = 0;
+ s32 *sensor_settings =
+ ((struct s5k83a_priv *) sd->sensor_priv)->settings;
for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
u8 data[2] = {0x00, 0x00};
@@ -187,87 +233,138 @@ int s5k83a_init(struct sd *sd)
if (dump_sensor)
s5k83a_dump_registers(sd);
- return (err < 0) ? err : 0;
-}
+ err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+ if (err < 0)
+ return err;
-int s5k83a_start(struct sd *sd)
-{
- return s5k83a_set_led_indication(sd, 1);
-}
+ err = s5k83a_set_brightness(&sd->gspca_dev,
+ sensor_settings[BRIGHTNESS_IDX]);
+ if (err < 0)
+ return err;
-int s5k83a_stop(struct sd *sd)
-{
- return s5k83a_set_led_indication(sd, 0);
+ err = s5k83a_set_exposure(&sd->gspca_dev,
+ sensor_settings[EXPOSURE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+ if (err < 0)
+ return err;
+
+ err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+
+ return err;
}
-int s5k83a_power_down(struct sd *sd)
+static int rotation_thread_function(void *data)
{
+ struct sd *sd = (struct sd *) data;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
+ u8 reg, previous_rotation = 0;
+ __s32 vflip, hflip;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ while (!schedule_timeout(100)) {
+ if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
+ break;
+
+ s5k83a_get_rotation(sd, &reg);
+ if (previous_rotation != reg) {
+ previous_rotation = reg;
+ info("Camera was flipped");
+
+ s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
+ s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
+
+ if (reg) {
+ vflip = !vflip;
+ hflip = !hflip;
+ }
+ s5k83a_set_flip_real((struct gspca_dev *) sd,
+ vflip, hflip);
+ }
+
+ mutex_unlock(&sd->gspca_dev.usb_lock);
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+
+ /* return to "front" flip */
+ if (previous_rotation) {
+ s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
+ s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
+ s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
+ }
+
+ sens_priv->rotation_thread = NULL;
return 0;
}
-static void s5k83a_dump_registers(struct sd *sd)
+int s5k83a_start(struct sd *sd)
{
- int address;
- u8 page, old_page;
- m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
+ int i, err = 0;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
- for (page = 0; page < 16; page++) {
- m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
- info("Dumping the s5k83a register state for page 0x%x", page);
- for (address = 0; address <= 0xff; address++) {
- u8 val = 0;
- m5602_read_sensor(sd, address, &val, 1);
- info("register 0x%x contains 0x%x",
- address, val);
- }
+ /* Create another thread, polling the GPIO ports of the camera to check
+ if it got rotated. This is how the windows driver does it so we have
+ to assume that there is no better way of accomplishing this */
+ sens_priv->rotation_thread = kthread_create(rotation_thread_function,
+ sd, "rotation thread");
+ wake_up_process(sens_priv->rotation_thread);
+
+ /* Preinit the sensor */
+ for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
+ u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]};
+ if (start_s5k83a[i][0] == SENSOR)
+ err = m5602_write_sensor(sd, start_s5k83a[i][1],
+ data, 2);
+ else
+ err = m5602_write_bridge(sd, start_s5k83a[i][1],
+ data[0]);
}
- info("s5k83a register state dump complete");
+ if (err < 0)
+ return err;
- for (page = 0; page < 16; page++) {
- m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
- info("Probing for which registers that are read/write "
- "for page 0x%x", page);
- for (address = 0; address <= 0xff; address++) {
- u8 old_val, ctrl_val, test_val = 0xff;
+ return s5k83a_set_led_indication(sd, 1);
+}
- m5602_read_sensor(sd, address, &old_val, 1);
- m5602_write_sensor(sd, address, &test_val, 1);
- m5602_read_sensor(sd, address, &ctrl_val, 1);
+int s5k83a_stop(struct sd *sd)
+{
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
- if (ctrl_val == test_val)
- info("register 0x%x is writeable", address);
- else
- info("register 0x%x is read only", address);
+ if (sens_priv->rotation_thread)
+ kthread_stop(sens_priv->rotation_thread);
- /* Restore original val */
- m5602_write_sensor(sd, address, &old_val, 1);
- }
- }
- info("Read/write register probing complete");
- m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
+ return s5k83a_set_led_indication(sd, 0);
}
-int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
+void s5k83a_disconnect(struct sd *sd)
{
- int err;
- u8 data[2];
- struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
- err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
- if (err < 0)
- return err;
+ s5k83a_stop(sd);
+
+ sd->sensor = NULL;
+ kfree(sens_priv->settings);
+ kfree(sens_priv);
+}
- data[1] = data[1] << 1;
- *val = data[1];
+static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
- return err;
+ *val = sens_priv->settings[GAIN_IDX];
+ return 0;
}
-int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 data[2];
struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
+
+ sens_priv->settings[GAIN_IDX] = val;
data[0] = 0x00;
data[1] = 0x20;
@@ -283,89 +380,69 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
/* FIXME: This is not sane, we need to figure out the composition
of these registers */
- data[0] = val >> 3; /* brightness, high 5 bits */
- data[1] = val >> 1; /* brightness, high 7 bits */
- err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
+ data[0] = val >> 3; /* gain, high 5 bits */
+ data[1] = val >> 1; /* gain, high 7 bits */
+ err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
return err;
}
-int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 data;
struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
- err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1);
- if (err < 0)
- return err;
-
- *val = data;
-
- return err;
+ *val = sens_priv->settings[BRIGHTNESS_IDX];
+ return 0;
}
-int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 data[1];
struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
+ sens_priv->settings[BRIGHTNESS_IDX] = val;
data[0] = val;
- err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1);
-
+ err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
return err;
}
-int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 data[2];
struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
- err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2);
- if (err < 0)
- return err;
-
- data[1] = data[1] & 0x3f;
- if (data[1] > S5K83A_MAXIMUM_GAIN)
- data[1] = S5K83A_MAXIMUM_GAIN;
-
- *val = data[1];
-
- return err;
+ *val = sens_priv->settings[EXPOSURE_IDX];
+ return 0;
}
-int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
u8 data[2];
struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
+ sens_priv->settings[EXPOSURE_IDX] = val;
data[0] = 0;
data[1] = val;
- err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
+ err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
return err;
}
-int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 data[1];
struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
- data[0] = 0x05;
- err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
- if (err < 0)
- return err;
-
- err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
- *val = (data[0] | 0x40) ? 1 : 0;
-
- return err;
+ *val = sens_priv->settings[VFLIP_IDX];
+ return 0;
}
-int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
+ __s32 vflip, __s32 hflip)
{
int err;
u8 data[1];
@@ -376,69 +453,83 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
if (err < 0)
return err;
- err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
- if (err < 0)
- return err;
+ /* six bit is vflip, seven is hflip */
+ data[0] = S5K83A_FLIP_MASK;
+ data[0] = (vflip) ? data[0] | 0x40 : data[0];
+ data[0] = (hflip) ? data[0] | 0x80 : data[0];
- /* set or zero six bit, seven is hflip */
- data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
- : (data[0] & 0x80) | S5K83A_FLIP_MASK;
err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
if (err < 0)
return err;
- data[0] = (val) ? 0x0b : 0x0a;
+ data[0] = (vflip) ? 0x0b : 0x0a;
err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
+ if (err < 0)
+ return err;
+ data[0] = (hflip) ? 0x0a : 0x0b;
+ err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
return err;
}
-int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
- u8 data[1];
+ u8 reg;
+ __s32 hflip;
struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
- data[0] = 0x05;
- err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
+ sens_priv->settings[VFLIP_IDX] = val;
+
+ s5k83a_get_hflip(gspca_dev, &hflip);
+
+ err = s5k83a_get_rotation(sd, &reg);
if (err < 0)
return err;
+ if (reg) {
+ val = !val;
+ hflip = !hflip;
+ }
- err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
- *val = (data[0] | 0x80) ? 1 : 0;
-
+ err = s5k83a_set_flip_real(gspca_dev, val, hflip);
return err;
}
-int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
+
+ *val = sens_priv->settings[HFLIP_IDX];
+ return 0;
+}
+
+static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
- u8 data[1];
+ u8 reg;
+ __s32 vflip;
struct sd *sd = (struct sd *) gspca_dev;
+ struct s5k83a_priv *sens_priv = sd->sensor_priv;
- data[0] = 0x05;
- err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
- if (err < 0)
- return err;
+ sens_priv->settings[HFLIP_IDX] = val;
- err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
- if (err < 0)
- return err;
+ s5k83a_get_vflip(gspca_dev, &vflip);
- /* set or zero seven bit, six is vflip */
- data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
- : (data[0] & 0x40) | S5K83A_FLIP_MASK;
- err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
+ err = s5k83a_get_rotation(sd, &reg);
if (err < 0)
return err;
+ if (reg) {
+ val = !val;
+ vflip = !vflip;
+ }
- data[0] = (val) ? 0x0a : 0x0b;
- err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
-
+ err = s5k83a_set_flip_real(gspca_dev, vflip, val);
return err;
}
-int s5k83a_set_led_indication(struct sd *sd, u8 val)
+static int s5k83a_set_led_indication(struct sd *sd, u8 val)
{
int err = 0;
u8 data[1];
@@ -454,5 +545,55 @@ int s5k83a_set_led_indication(struct sd *sd, u8 val)
err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
- return (err < 0) ? err : 0;
+ return err;
+}
+
+/* Get camera rotation on Acer notebooks */
+static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
+{
+ int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
+ *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
+ return err;
+}
+
+static void s5k83a_dump_registers(struct sd *sd)
+{
+ int address;
+ u8 page, old_page;
+ m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
+
+ for (page = 0; page < 16; page++) {
+ m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
+ info("Dumping the s5k83a register state for page 0x%x", page);
+ for (address = 0; address <= 0xff; address++) {
+ u8 val = 0;
+ m5602_read_sensor(sd, address, &val, 1);
+ info("register 0x%x contains 0x%x",
+ address, val);
+ }
+ }
+ info("s5k83a register state dump complete");
+
+ for (page = 0; page < 16; page++) {
+ m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
+ info("Probing for which registers that are read/write "
+ "for page 0x%x", page);
+ for (address = 0; address <= 0xff; address++) {
+ u8 old_val, ctrl_val, test_val = 0xff;
+
+ m5602_read_sensor(sd, address, &old_val, 1);
+ m5602_write_sensor(sd, address, &test_val, 1);
+ m5602_read_sensor(sd, address, &ctrl_val, 1);
+
+ if (ctrl_val == test_val)
+ info("register 0x%x is writeable", address);
+ else
+ info("register 0x%x is read only", address);
+
+ /* Restore original val */
+ m5602_write_sensor(sd, address, &old_val, 1);
+ }
+ }
+ info("Read/write register probing complete");
+ m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 819ab25272be..7814b078acde 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -21,20 +21,21 @@
#include "m5602_sensor.h"
-#define S5K83A_FLIP 0x01
-#define S5K83A_HFLIP_TUNE 0x03
-#define S5K83A_VFLIP_TUNE 0x05
-#define S5K83A_WHITENESS 0x0a
-#define S5K83A_GAIN 0x18
-#define S5K83A_BRIGHTNESS 0x1b
-#define S5K83A_PAGE_MAP 0xec
-
-#define S5K83A_DEFAULT_BRIGHTNESS 0x71
-#define S5K83A_DEFAULT_WHITENESS 0x7e
-#define S5K83A_DEFAULT_GAIN 0x00
-#define S5K83A_MAXIMUM_GAIN 0x3c
-#define S5K83A_FLIP_MASK 0x10
+#define S5K83A_FLIP 0x01
+#define S5K83A_HFLIP_TUNE 0x03
+#define S5K83A_VFLIP_TUNE 0x05
+#define S5K83A_BRIGHTNESS 0x0a
+#define S5K83A_EXPOSURE 0x18
+#define S5K83A_GAIN 0x1b
+#define S5K83A_PAGE_MAP 0xec
+
+#define S5K83A_DEFAULT_GAIN 0x71
+#define S5K83A_DEFAULT_BRIGHTNESS 0x7e
+#define S5K83A_DEFAULT_EXPOSURE 0x00
+#define S5K83A_MAXIMUM_EXPOSURE 0x3c
+#define S5K83A_FLIP_MASK 0x10
#define S5K83A_GPIO_LED_MASK 0x10
+#define S5K83A_GPIO_ROTATION_MASK 0x40
/*****************************************************************************/
@@ -46,20 +47,7 @@ int s5k83a_probe(struct sd *sd);
int s5k83a_init(struct sd *sd);
int s5k83a_start(struct sd *sd);
int s5k83a_stop(struct sd *sd);
-int s5k83a_power_down(struct sd *sd);
-
-int s5k83a_set_led_indication(struct sd *sd, u8 val);
-
-int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
-int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
-int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+void s5k83a_disconnect(struct sd *sd);
static const struct m5602_sensor s5k83a = {
.name = "S5K83A",
@@ -67,11 +55,18 @@ static const struct m5602_sensor s5k83a = {
.init = s5k83a_init,
.start = s5k83a_start,
.stop = s5k83a_stop,
- .power_down = s5k83a_power_down,
+ .disconnect = s5k83a_disconnect,
.i2c_slave_id = 0x5a,
.i2c_regW = 2,
};
+struct s5k83a_priv {
+ /* We use another thread periodically
+ probing the orientation of the camera */
+ struct task_struct *rotation_thread;
+ s32 *settings;
+};
+
static const unsigned char preinit_s5k83a[][4] =
{
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
@@ -108,8 +103,6 @@ static const unsigned char preinit_s5k83a[][4] =
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
-
- {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}
};
/* This could probably be considerably shortened.
@@ -117,86 +110,8 @@ static const unsigned char preinit_s5k83a[][4] =
*/
static const unsigned char init_s5k83a[][4] =
{
- {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
- {SENSOR, 0xaf, 0x01, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
- {SENSOR, 0x7b, 0xff, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
- {SENSOR, 0x01, 0x50, 0x00},
- {SENSOR, 0x12, 0x20, 0x00},
- {SENSOR, 0x17, 0x40, 0x00},
- {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
- {SENSOR, 0x1c, 0x00, 0x00},
- {SENSOR, 0x02, 0x70, 0x00},
- {SENSOR, 0x03, 0x0b, 0x00},
- {SENSOR, 0x04, 0xf0, 0x00},
- {SENSOR, 0x05, 0x0b, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
- {SENSOR, 0x06, 0x71, 0x00},
- {SENSOR, 0x07, 0xe8, 0x00},
- {SENSOR, 0x08, 0x02, 0x00},
- {SENSOR, 0x09, 0x88, 0x00},
- {SENSOR, 0x14, 0x00, 0x00},
- {SENSOR, 0x15, 0x20, 0x00},
- {SENSOR, 0x19, 0x00, 0x00},
- {SENSOR, 0x1a, 0x98, 0x00},
- {SENSOR, 0x0f, 0x02, 0x00},
- {SENSOR, 0x10, 0xe5, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
- {SENSOR_LONG, 0x14, 0x00, 0x20},
- {SENSOR_LONG, 0x0d, 0x00, 0x7d},
- {SENSOR_LONG, 0x1b, 0x0d, 0x05},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
-
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
+ /* The following sequence is useless after a clean boot
+ but is necessary after resume from suspend */
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
@@ -216,7 +131,7 @@ static const unsigned char init_s5k83a[][4] =
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
+ {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
@@ -225,109 +140,34 @@ static const unsigned char init_s5k83a[][4] =
{SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
{SENSOR, 0xaf, 0x01, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
- /* ff ( init value )is very dark) || 71 and f0 better */
+ {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
{SENSOR, 0x7b, 0xff, 0x00},
{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
{SENSOR, 0x01, 0x50, 0x00},
{SENSOR, 0x12, 0x20, 0x00},
{SENSOR, 0x17, 0x40, 0x00},
- {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
{SENSOR, 0x1c, 0x00, 0x00},
{SENSOR, 0x02, 0x70, 0x00},
- /* some values like 0x10 give a blue-purple image */
{SENSOR, 0x03, 0x0b, 0x00},
{SENSOR, 0x04, 0xf0, 0x00},
{SENSOR, 0x05, 0x0b, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- /* under 80 don't work, highter depend on value */
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
-
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
{SENSOR, 0x06, 0x71, 0x00},
- {SENSOR, 0x07, 0xe8, 0x00},
+ {SENSOR, 0x07, 0xe8, 0x00}, /* 488 */
{SENSOR, 0x08, 0x02, 0x00},
- {SENSOR, 0x09, 0x88, 0x00},
+ {SENSOR, 0x09, 0x88, 0x00}, /* 648 */
{SENSOR, 0x14, 0x00, 0x00},
- {SENSOR, 0x15, 0x20, 0x00},
+ {SENSOR, 0x15, 0x20, 0x00}, /* 32 */
{SENSOR, 0x19, 0x00, 0x00},
- {SENSOR, 0x1a, 0x98, 0x00},
+ {SENSOR, 0x1a, 0x98, 0x00}, /* 152 */
{SENSOR, 0x0f, 0x02, 0x00},
- {SENSOR, 0x10, 0xe5, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
- {SENSOR_LONG, 0x14, 0x00, 0x20},
- {SENSOR_LONG, 0x0d, 0x00, 0x7d},
- {SENSOR_LONG, 0x1b, 0x0d, 0x05},
-
- /* The following sequence is useless after a clean boot
- but is necessary after resume from suspend */
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
-
- {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
- {SENSOR, 0xaf, 0x01, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
- {SENSOR, 0x7b, 0xff, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
- {SENSOR, 0x01, 0x50, 0x00},
- {SENSOR, 0x12, 0x20, 0x00},
- {SENSOR, 0x17, 0x40, 0x00},
- {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
- {SENSOR, 0x1c, 0x00, 0x00},
- {SENSOR, 0x02, 0x70, 0x00},
- {SENSOR, 0x03, 0x0b, 0x00},
- {SENSOR, 0x04, 0xf0, 0x00},
- {SENSOR, 0x05, 0x0b, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
+ {SENSOR, 0x10, 0xe5, 0x00}, /* 741 */
+ /* normal colors
+ (this is value after boot, but after tries can be different) */
+ {SENSOR, 0x00, 0x06, 0x00},
+};
+static const unsigned char start_s5k83a[][4] =
+{
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -340,7 +180,7 @@ static const unsigned char init_s5k83a[][4] =
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
@@ -348,50 +188,10 @@ static const unsigned char init_s5k83a[][4] =
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
+ {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
- {SENSOR, 0x06, 0x71, 0x00},
- {SENSOR, 0x07, 0xe8, 0x00},
- {SENSOR, 0x08, 0x02, 0x00},
- {SENSOR, 0x09, 0x88, 0x00},
- {SENSOR, 0x14, 0x00, 0x00},
- {SENSOR, 0x15, 0x20, 0x00},
- {SENSOR, 0x19, 0x00, 0x00},
- {SENSOR, 0x1a, 0x98, 0x00},
- {SENSOR, 0x0f, 0x02, 0x00},
-
- {SENSOR, 0x10, 0xe5, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
- {SENSOR_LONG, 0x14, 0x00, 0x20},
- {SENSOR_LONG, 0x0d, 0x00, 0x7d},
- {SENSOR_LONG, 0x1b, 0x0d, 0x05},
-
- /* normal colors
- (this is value after boot, but after tries can be different) */
- {SENSOR, 0x00, 0x06, 0x00},
-
- /* set default brightness */
- {SENSOR_LONG, 0x14, 0x00, 0x20},
- {SENSOR_LONG, 0x0d, 0x01, 0x00},
- {SENSOR_LONG, 0x1b, S5K83A_DEFAULT_BRIGHTNESS >> 3,
- S5K83A_DEFAULT_BRIGHTNESS >> 1},
-
- /* set default whiteness */
- {SENSOR, S5K83A_WHITENESS, S5K83A_DEFAULT_WHITENESS, 0x00},
-
- /* set default gain */
- {SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN},
-
- /* set default flip */
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
- {SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00},
- {SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00},
- {SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00}
-
};
#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 0d3026936f2e..edff4f1f586f 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -21,13 +21,17 @@
#include "m5602_bridge.h"
+#define M5602_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 0)
+#define M5602_V4L2_CID_NOISE_SUPPRESION (V4L2_CID_PRIVATE_BASE + 1)
+
/* Enumerates all supported sensors */
enum sensors {
OV9650_SENSOR = 1,
S5K83A_SENSOR = 2,
S5K4AA_SENSOR = 3,
MT9M111_SENSOR = 4,
- PO1030_SENSOR = 5
+ PO1030_SENSOR = 5,
+ OV7660_SENSOR = 6,
};
/* Enumerates all possible instruction types */
@@ -61,9 +65,6 @@ struct m5602_sensor {
/* Executed when the device is disconnected */
void (*disconnect)(struct sd *sd);
-
- /* Performs a power down sequence */
- int (*power_down)(struct sd *sd);
};
#endif
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 2a901a4a6f00..30132513400c 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -321,6 +321,7 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x08ca, 0x0111)},
+ {USB_DEVICE(0x093a, 0x010f)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -347,8 +348,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 19e0bc60de14..6d9b102be70c 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -708,8 +708,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
- cam->bulk_size = 16384;
- cam->bulk_nurbs = 2;
+ if (sd->sensor == SENSOR_OV772X) {
+ cam->bulk = 1;
+ cam->bulk_size = 16384;
+ cam->bulk_nurbs = 2;
+ }
return 0;
}
@@ -864,18 +867,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
/* If PTS or FID has changed, start a new frame. */
if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
- gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
- NULL, 0);
+ if (gspca_dev->last_packet_type == INTER_PACKET)
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET, frame,
+ NULL, 0);
sd->last_pts = this_pts;
sd->last_fid = this_fid;
- }
-
- /* Add the data from this payload */
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
data + 12, len - 12);
-
/* If this packet is marked as EOF, end the frame */
- if (data[1] & UVC_STREAM_EOF) {
+ } else if (data[1] & UVC_STREAM_EOF) {
sd->last_pts = 0;
if (frame->data_end - frame->data !=
@@ -883,11 +884,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
PDEBUG(D_PACK, "short frame");
goto discard;
}
-
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
- NULL, 0);
+ data + 12, len - 12);
+ } else {
+
+ /* Add the data from this payload */
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ data + 12, len - 12);
}
+
/* Done this payload */
goto scan_next;
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 153d0a91d4b5..cf3af8de6e97 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -877,6 +877,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
}
+ cam->npkt = 36; /* 36 packets per ISOC message */
+
sd->brightness = BRIGHTNESS_DEF;
sd->gain = GAIN_DEF;
sd->exposure = EXPOSURE_DEF;
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index c72e19d3ac37..dc6a6f11354a 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -62,7 +62,6 @@ struct sd {
#define BRIDGE_SN9C105 1
#define BRIDGE_SN9C110 2
#define BRIDGE_SN9C120 3
-#define BRIDGE_SN9C325 4
u8 sensor; /* Type of image sensor chip */
#define SENSOR_HV7131R 0
#define SENSOR_MI0360 1
@@ -354,9 +353,9 @@ static const u8 sn_ov7648[0x1c] = {
static const u8 sn_ov7660[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
+ 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
/* reg18 reg19 reg1a reg1b */
@@ -757,6 +756,7 @@ static const u8 ov7660_sensor_init[][8] = {
{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
+ {0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
/****** (some exchanges in the win trace) ******/
{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
/* bits[3..0]reserved */
@@ -1065,9 +1065,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
const u8 *reg9a;
static const u8 reg9a_def[] =
- {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
- static const u8 reg9a_sn9c325[] =
- {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
+ {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
+ static const u8 reg9a_spec[] =
+ {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
static const u8 regd4[] = {0x60, 0x00, 0x00};
reg_w1(gspca_dev, 0xf1, 0x00);
@@ -1077,9 +1077,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
- switch (sd->bridge) {
- case BRIDGE_SN9C325:
- reg9a = reg9a_sn9c325;
+ switch (sd->sensor) {
+ case SENSOR_OV7660:
+ case SENSOR_SP80708:
+ reg9a = reg9a_spec;
break;
default:
reg9a = reg9a_def;
@@ -1104,7 +1105,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
reg_w1(gspca_dev, 0x17, 0x64);
reg_w1(gspca_dev, 0x01, 0x42);
break;
-/*jfm: from win trace */
case SENSOR_OV7630:
reg_w1(gspca_dev, 0x01, 0x61);
reg_w1(gspca_dev, 0x17, 0xe2);
@@ -1114,18 +1114,15 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
case SENSOR_OV7648:
reg_w1(gspca_dev, 0x01, 0x63);
reg_w1(gspca_dev, 0x17, 0x20);
+ reg_w1(gspca_dev, 0x01, 0x62);
reg_w1(gspca_dev, 0x01, 0x42);
break;
-/*jfm: from win trace */
case SENSOR_OV7660:
- if (sd->bridge == BRIDGE_SN9C120) {
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0x20);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- break;
- }
- /* fall thru */
+ reg_w1(gspca_dev, 0x01, 0x61);
+ reg_w1(gspca_dev, 0x17, 0x20);
+ reg_w1(gspca_dev, 0x01, 0x60);
+ reg_w1(gspca_dev, 0x01, 0x40);
+ break;
case SENSOR_SP80708:
reg_w1(gspca_dev, 0x01, 0x63);
reg_w1(gspca_dev, 0x17, 0x20);
@@ -1134,6 +1131,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
mdelay(100);
reg_w1(gspca_dev, 0x02, 0x62);
break;
+/* case SENSOR_HV7131R: */
+/* case SENSOR_MI0360: */
+/* case SENSOR_MO4000: */
default:
reg_w1(gspca_dev, 0x01, 0x43);
reg_w1(gspca_dev, 0x17, 0x61);
@@ -1280,6 +1280,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam = &gspca_dev->cam;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
+ cam->npkt = 24; /* 24 packets per ISOC message */
sd->bridge = id->driver_info >> 16;
sd->sensor = id->driver_info >> 8;
@@ -1683,13 +1684,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
case SENSOR_OV7648:
reg17 = 0x20;
break;
-/*jfm: from win trace */
case SENSOR_OV7660:
- if (sd->bridge == BRIDGE_SN9C120) {
- reg17 = 0xa0;
- break;
- }
- /* fall thru */
+ reg17 = 0xa0;
+ break;
default:
reg17 = 0x60;
break;
@@ -1714,16 +1711,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x9a, 0x0a);
reg_w1(gspca_dev, 0x99, 0x60);
break;
+ case SENSOR_OV7660:
+ reg_w1(gspca_dev, 0x9a, 0x05);
+ if (sd->bridge == BRIDGE_SN9C105)
+ reg_w1(gspca_dev, 0x99, 0xff);
+ else
+ reg_w1(gspca_dev, 0x99, 0x5b);
+ break;
case SENSOR_SP80708:
reg_w1(gspca_dev, 0x9a, 0x05);
reg_w1(gspca_dev, 0x99, 0x59);
break;
- case SENSOR_OV7660:
- if (sd->bridge == BRIDGE_SN9C120) {
- reg_w1(gspca_dev, 0x9a, 0x05);
- break;
- }
- /* fall thru */
default:
reg_w1(gspca_dev, 0x9a, 0x08);
reg_w1(gspca_dev, 0x99, 0x59);
@@ -2193,6 +2191,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
{USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
{USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
+ {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)},
{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
/* bw600.inf:
{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
@@ -2211,7 +2210,12 @@ static const __devinitdata struct usb_device_id device_table[] = {
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
#endif
+ {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
+ {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
+ {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
+ {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
+ {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/
/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
{USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 6f38fa6d86b6..8806b2ff82be 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- __u8 packet[ISO_MAX_SIZE + 128];
- /* !! no more than 128 ff in an ISO packet */
-
unsigned char brightness;
unsigned char contrast;
unsigned char colors;
@@ -906,7 +903,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
int i;
- __u8 *s, *d;
static __u8 ffd9[] = {0xff, 0xd9};
/* frames are jpeg 4.1.1 without 0xff escape */
@@ -930,22 +926,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
}
/* add 0x00 after 0xff */
- for (i = len; --i >= 0; )
- if (data[i] == 0xff)
- break;
- if (i < 0) { /* no 0xff */
- gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
- return;
- }
- s = data;
- d = sd->packet;
- for (i = 0; i < len; i++) {
- *d++ = *s++;
- if (s[-1] == 0xff)
- *d++ = 0x00;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- sd->packet, d - sd->packet);
+ i = 0;
+ do {
+ if (data[i] == 0xff) {
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ data, i + 1);
+ len -= i;
+ data += i;
+ *data = 0x00;
+ i = 0;
+ }
+ i++;
+ } while (i < len);
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
index 2e1cdf068fda..715a68f0156e 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -309,6 +309,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *dev = (struct sd *) gspca_dev;
/* We don't use the buffer gspca allocates so make it small. */
+ cam->bulk = 1;
cam->bulk_size = 64;
INIT_WORK(&dev->work_struct, sq905_dostream);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index 0bcb74a1b143..916892505432 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -206,6 +206,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->nmodes = 1;
/* We don't use the buffer gspca allocates so make it small. */
cam->bulk_size = 32;
+ cam->bulk = 1;
INIT_WORK(&dev->work_struct, sq905c_dostream);
return 0;
}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index 69c77c932fc0..11a0c002f5dc 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -80,12 +80,26 @@ static const struct ctrl vv6410_ctrl[] = {
.minimum = 0,
.maximum = 15,
.step = 1,
- .default_value = 0
+ .default_value = 10
},
.set = vv6410_set_analog_gain,
.get = vv6410_get_analog_gain
+ },
+#define EXPOSURE_IDX 3
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0,
+ .maximum = 32768,
+ .step = 1,
+ .default_value = 20000
+ },
+ .set = vv6410_set_exposure,
+ .get = vv6410_get_exposure
}
-};
+ };
static int vv6410_probe(struct sd *sd)
{
@@ -121,6 +135,7 @@ static int vv6410_probe(struct sd *sd)
static int vv6410_init(struct sd *sd)
{
int err = 0, i;
+ s32 *sensor_settings = sd->sensor_priv;
for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) {
/* if NULL then len contains single value */
@@ -142,6 +157,16 @@ static int vv6410_init(struct sd *sd)
err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init,
ARRAY_SIZE(vv6410_sensor_init));
+ if (err < 0)
+ return err;
+
+ err = vv6410_set_exposure(&sd->gspca_dev,
+ sensor_settings[EXPOSURE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = vv6410_set_analog_gain(&sd->gspca_dev,
+ sensor_settings[GAIN_IDX]);
return (err < 0) ? err : 0;
}
@@ -318,3 +343,50 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
return (err < 0) ? err : 0;
}
+
+static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ *val = sensor_settings[EXPOSURE_IDX];
+
+ PDEBUG(D_V4L2, "Read exposure %d", *val);
+
+ return 0;
+}
+
+static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+ int err;
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+ unsigned int fine, coarse;
+
+ sensor_settings[EXPOSURE_IDX] = val;
+
+ val = (val * val >> 14) + val / 4;
+
+ fine = val % VV6410_CIF_LINELENGTH;
+ coarse = min(512, val / VV6410_CIF_LINELENGTH);
+
+ PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d",
+ coarse, fine);
+
+ err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8);
+ if (err < 0)
+ goto out;
+
+ err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff);
+ if (err < 0)
+ goto out;
+
+ err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8);
+ if (err < 0)
+ goto out;
+
+ err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff);
+
+out:
+ return err;
+}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index 95ac55891bd4..487d40555343 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -173,6 +173,8 @@
#define VV6410_SUBSAMPLE 0x01
#define VV6410_CROP_TO_QVGA 0x02
+#define VV6410_CIF_LINELENGTH 415
+
static int vv6410_probe(struct sd *sd);
static int vv6410_start(struct sd *sd);
static int vv6410_init(struct sd *sd);
@@ -187,6 +189,8 @@ static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val);
static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
.name = "ST VV6410",
@@ -242,12 +246,6 @@ static const u8 vv6410_sensor_init[][2] = {
/* Pre-clock generator divide off */
{VV6410_DATAFORMAT, BIT(7) | BIT(0)},
- /* Exposure registers */
- {VV6410_FINEH, VV6410_FINE_EXPOSURE >> 8},
- {VV6410_FINEL, VV6410_FINE_EXPOSURE & 0xff},
- {VV6410_COARSEH, VV6410_COARSE_EXPOSURE >> 8},
- {VV6410_COARSEL, VV6410_COARSE_EXPOSURE & 0xff},
- {VV6410_ANALOGGAIN, 0xf0 | VV6410_DEFAULT_GAIN},
{VV6410_CLKDIV, VV6410_CLK_DIV_2},
/* System registers */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index c2b8c10c075a..9623f294bdac 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- __u8 packet[ISO_MAX_SIZE + 128];
- /* !! no more than 128 ff in an ISO packet */
-
unsigned char brightness;
unsigned char contrast;
unsigned char colors;
@@ -1103,7 +1100,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
int i, sof = 0;
- unsigned char *s, *d;
static unsigned char ffd9[] = {0xff, 0xd9};
/* frames are jpeg 4.1.1 without 0xff escape */
@@ -1177,22 +1173,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
}
/* add 0x00 after 0xff */
- for (i = len; --i >= 0; )
- if (data[i] == 0xff)
- break;
- if (i < 0) { /* no 0xff */
- gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
- return;
- }
- s = data;
- d = sd->packet;
- for (i = 0; i < len; i++) {
- *d++ = *s++;
- if (s[-1] == 0xff)
- *d++ = 0x00;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- sd->packet, d - sd->packet);
+ i = 0;
+ do {
+ if (data[i] == 0xff) {
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ data, i + 1);
+ len -= i;
+ data += i;
+ *data = 0x00;
+ i = 0;
+ }
+ i++;
+ } while (i < len);
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index f63e37e2e4fd..404214b8cd2b 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -697,7 +697,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
return -EINVAL;
}
- if (sd->sensor != SENSOR_OTHER) {
+ if (sd->sensor == SENSOR_OM6802) {
reg_w_buf(gspca_dev, n1, sizeof n1);
i = 5;
while (--i >= 0) {
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index e4e933c400bc..26dd155efcc3 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -42,7 +42,7 @@ struct sd {
char bridge;
#define BRIDGE_VC0321 0
#define BRIDGE_VC0323 1
- char sensor;
+ u8 sensor;
#define SENSOR_HV7131R 0
#define SENSOR_MI0360 1
#define SENSOR_MI1310_SOC 2
@@ -159,17 +159,17 @@ static const struct v4l2_pix_format vc0323_mode[] = {
.priv = 2},
};
static const struct v4l2_pix_format bi_mode[] = {
- {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 2},
- {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 640 * 480 * 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 1},
- {1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ {1280, 1024, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
.bytesperline = 1280,
.sizeimage = 1280 * 1024 * 2,
.colorspace = V4L2_COLORSPACE_SRGB,
@@ -2453,6 +2453,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct usb_device *dev = gspca_dev->dev;
struct cam *cam;
int sensor;
+ static u8 npkt[] = { /* number of packets per ISOC message */
+ 64, /* HV7131R 0 */
+ 32, /* MI0360 1 */
+ 32, /* MI1310_SOC 2 */
+ 64, /* MI1320 3 */
+ 128, /* MI1320_SOC 4 */
+ 32, /* OV7660 5 */
+ 64, /* OV7670 6 */
+ 128, /* PO1200 7 */
+ 128, /* PO3130NC 8 */
+ };
cam = &gspca_dev->cam;
sd->bridge = id->driver_info;
@@ -2508,6 +2519,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
case SENSOR_MI1320_SOC:
cam->cam_mode = bi_mode;
cam->nmodes = ARRAY_SIZE(bi_mode);
+ cam->input_flags = V4L2_IN_ST_VFLIP |
+ V4L2_IN_ST_HFLIP;
break;
default:
cam->cam_mode = vc0323_mode;
@@ -2515,6 +2528,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
break;
}
}
+ cam->npkt = npkt[sd->sensor];
sd->hflip = HFLIP_DEF;
sd->vflip = VFLIP_DEF;
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 4fe01d8b6c87..08422d315e68 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -6307,7 +6307,7 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */
- PDEBUG(D_USBO, "i2c r [%02x] -> %04x (%02x)",
+ PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)",
reg, retval, retbyte);
return retval;
}
@@ -6868,7 +6868,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
{0x8001, 0x13},
{0x8000, 0x14}, /* CS2102K */
{0x8400, 0x15}, /* TAS5130K */
- {0x4001, 0x16}, /* ADCM2700 */
};
static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6904,12 +6903,15 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
retword |= reg_r(gspca_dev, 0x000a);
PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
reg_r(gspca_dev, 0x0010);
- /* this is tested only once anyway */
- for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
- if (chipset_revision_sensor[i].revision == retword) {
- sd->chip_revision = retword;
- send_unknown(dev, SENSOR_PB0330);
- return chipset_revision_sensor[i].internal_sensor_id;
+ /* value 0x4001 is meaningless */
+ if (retword != 0x4001) {
+ for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
+ if (chipset_revision_sensor[i].revision == retword) {
+ sd->chip_revision = retword;
+ send_unknown(dev, SENSOR_PB0330);
+ return chipset_revision_sensor[i]
+ .internal_sensor_id;
+ }
}
}
@@ -6980,12 +6982,12 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x01, 0x0001);
reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012);
- reg_w(dev, 0x05, 0x0001);
+ reg_w(dev, 0x05, 0x0012);
reg_w(dev, 0xd3, 0x008b);
retword = i2c_read(gspca_dev, 0x01);
if (retword != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
- return retword;
+ return 0x16; /* adcm2700 (6100/6200) */
}
return -1;
}
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 092c7da0f37a..86f2fefe1edf 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -74,7 +74,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
int start, range, toggle, dev, code, ircode;
/* poll IR chip */
- if (size != i2c_master_recv(&ir->c,buf,size))
+ if (size != i2c_master_recv(ir->c, buf, size))
return -EIO;
/* split rc5 data block ... */
@@ -137,7 +137,7 @@ static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char b;
/* poll IR chip */
- if (1 != i2c_master_recv(&ir->c,&b,1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
dprintk(1,"read error\n");
return -EIO;
}
@@ -151,7 +151,7 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char b;
/* poll IR chip */
- if (1 != i2c_master_recv(&ir->c,&b,1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
dprintk(1,"read error\n");
return -EIO;
}
@@ -171,7 +171,7 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char buf[4];
/* poll IR chip */
- if (4 != i2c_master_recv(&ir->c,buf,4)) {
+ if (4 != i2c_master_recv(ir->c, buf, 4)) {
dprintk(1,"read error\n");
return -EIO;
}
@@ -195,7 +195,7 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char b;
/* poll IR chip */
- if (1 != i2c_master_recv(&ir->c,&b,1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
dprintk(1,"read error\n");
return -EIO;
}
@@ -222,12 +222,12 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
u32 *ir_key, u32 *ir_raw)
{
unsigned char subaddr, key, keygroup;
- struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0,
+ struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0,
.buf = &subaddr, .len = 1},
- { .addr = ir->c.addr, .flags = I2C_M_RD,
+ { .addr = ir->c->addr, .flags = I2C_M_RD,
.buf = &key, .len = 1} };
subaddr = 0x0d;
- if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+ if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
dprintk(1, "read error\n");
return -EIO;
}
@@ -237,7 +237,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
subaddr = 0x0b;
msg[1].buf = &keygroup;
- if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+ if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
dprintk(1, "read error\n");
return -EIO;
}
@@ -286,7 +286,7 @@ static void ir_work(struct work_struct *work)
/* MSI TV@nywhere Plus requires more frequent polling
otherwise it will miss some keypresses */
- if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30)
+ if (ir->c->adapter->id == I2C_HW_SAA7134 && ir->c->addr == 0x30)
polling_interval = 50;
ir_key_poll(ir);
@@ -295,34 +295,15 @@ static void ir_work(struct work_struct *work)
/* ----------------------------------------------------------------------- */
-static int ir_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind);
-static int ir_detach(struct i2c_client *client);
-static int ir_probe(struct i2c_adapter *adap);
-
-static struct i2c_driver driver = {
- .driver = {
- .name = "ir-kbd-i2c",
- },
- .id = I2C_DRIVERID_INFRARED,
- .attach_adapter = ir_probe,
- .detach_client = ir_detach,
-};
-
-static struct i2c_client client_template =
-{
- .name = "unset",
- .driver = &driver
-};
-
-static int ir_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
+static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
IR_KEYTAB_TYPE *ir_codes = NULL;
- char *name;
+ const char *name = NULL;
int ir_type;
struct IR_i2c *ir;
struct input_dev *input_dev;
+ struct i2c_adapter *adap = client->adapter;
+ unsigned short addr = client->addr;
int err;
ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
@@ -332,13 +313,9 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
goto err_out_free;
}
- ir->c = client_template;
+ ir->c = client;
ir->input = input_dev;
-
- ir->c.adapter = adap;
- ir->c.addr = addr;
-
- i2c_set_clientdata(&ir->c, ir);
+ i2c_set_clientdata(client, ir);
switch(addr) {
case 0x64:
@@ -403,44 +380,46 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
ir_codes = ir_codes_avermedia_cardbus;
break;
default:
- /* shouldn't happen */
- printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr);
+ dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr);
err = -ENODEV;
goto err_out_free;
}
- /* Sets name */
- snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
- ir->ir_codes = ir_codes;
+ /* Let the caller override settings */
+ if (client->dev.platform_data) {
+ const struct IR_i2c_init_data *init_data =
+ client->dev.platform_data;
- /* register i2c device
- * At device register, IR codes may be changed to be
- * board dependent.
- */
- err = i2c_attach_client(&ir->c);
- if (err)
- goto err_out_free;
+ ir_codes = init_data->ir_codes;
+ name = init_data->name;
+ ir->get_key = init_data->get_key;
+ }
- /* If IR not supported or disabled, unregisters driver */
- if (ir->get_key == NULL) {
+ /* Make sure we are all setup before going on */
+ if (!name || !ir->get_key || !ir_codes) {
+ dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n",
+ addr);
err = -ENODEV;
- goto err_out_detach;
+ goto err_out_free;
}
- /* Phys addr can only be set after attaching (for ir->c.dev) */
+ /* Sets name */
+ snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
+ ir->ir_codes = ir_codes;
+
snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
- dev_name(&ir->c.adapter->dev),
- dev_name(&ir->c.dev));
+ dev_name(&adap->dev),
+ dev_name(&client->dev));
/* init + register input device */
ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
input_dev->id.bustype = BUS_I2C;
- input_dev->name = ir->c.name;
+ input_dev->name = ir->name;
input_dev->phys = ir->phys;
err = input_register_device(ir->input);
if (err)
- goto err_out_detach;
+ goto err_out_free;
printk(DEVNAME ": %s detected at %s [%s]\n",
ir->input->name, ir->input->phys, adap->name);
@@ -451,135 +430,42 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
return 0;
- err_out_detach:
- i2c_detach_client(&ir->c);
err_out_free:
input_free_device(input_dev);
kfree(ir);
return err;
}
-static int ir_detach(struct i2c_client *client)
+static int ir_remove(struct i2c_client *client)
{
struct IR_i2c *ir = i2c_get_clientdata(client);
/* kill outstanding polls */
cancel_delayed_work_sync(&ir->work);
- /* unregister devices */
+ /* unregister device */
input_unregister_device(ir->input);
- i2c_detach_client(&ir->c);
/* free memory */
kfree(ir);
return 0;
}
-static int ir_probe(struct i2c_adapter *adap)
-{
-
- /* The external IR receiver is at i2c address 0x34 (0x35 for
- reads). Future Hauppauge cards will have an internal
- receiver at 0x30 (0x31 for reads). In theory, both can be
- fitted, and Hauppauge suggest an external overrides an
- internal.
-
- That's why we probe 0x1a (~0x34) first. CB
- */
-
- static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
- static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 };
- static const int probe_em28XX[] = { 0x30, 0x47, -1 };
- static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 };
- static const int probe_cx23885[] = { 0x6b, -1 };
- const int *probe;
- struct i2c_msg msg = {
- .flags = I2C_M_RD,
- .len = 0,
- .buf = NULL,
- };
- int i, rc;
-
- switch (adap->id) {
- case I2C_HW_B_BT848:
- probe = probe_bttv;
- break;
- case I2C_HW_B_CX2341X:
- probe = probe_bttv;
- break;
- case I2C_HW_SAA7134:
- probe = probe_saa7134;
- break;
- case I2C_HW_B_EM28XX:
- probe = probe_em28XX;
- break;
- case I2C_HW_B_CX2388x:
- probe = probe_cx88;
- break;
- case I2C_HW_B_CX23885:
- probe = probe_cx23885;
- break;
- default:
- return 0;
- }
-
- for (i = 0; -1 != probe[i]; i++) {
- msg.addr = probe[i];
- rc = i2c_transfer(adap, &msg, 1);
- dprintk(1,"probe 0x%02x @ %s: %s\n",
- probe[i], adap->name,
- (1 == rc) ? "yes" : "no");
- if (1 == rc) {
- ir_attach(adap, probe[i], 0, 0);
- return 0;
- }
- }
-
- /* Special case for MSI TV@nywhere Plus remote */
- if (adap->id == I2C_HW_SAA7134) {
- u8 temp;
-
- /* MSI TV@nywhere Plus controller doesn't seem to
- respond to probes unless we read something from
- an existing device. Weird... */
-
- msg.addr = 0x50;
- rc = i2c_transfer(adap, &msg, 1);
- dprintk(1, "probe 0x%02x @ %s: %s\n",
- msg.addr, adap->name,
- (1 == rc) ? "yes" : "no");
-
- /* Now do the probe. The controller does not respond
- to 0-byte reads, so we use a 1-byte read instead. */
- msg.addr = 0x30;
- msg.len = 1;
- msg.buf = &temp;
- rc = i2c_transfer(adap, &msg, 1);
- dprintk(1, "probe 0x%02x @ %s: %s\n",
- msg.addr, adap->name,
- (1 == rc) ? "yes" : "no");
- if (1 == rc)
- ir_attach(adap, msg.addr, 0, 0);
- }
-
- /* Special case for AVerMedia Cardbus remote */
- if (adap->id == I2C_HW_SAA7134) {
- unsigned char subaddr, data;
- struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0,
- .buf = &subaddr, .len = 1},
- { .addr = 0x40, .flags = I2C_M_RD,
- .buf = &data, .len = 1} };
- subaddr = 0x0d;
- rc = i2c_transfer(adap, msg, 2);
- dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n",
- msg[0].addr, subaddr, adap->name,
- (2 == rc) ? "yes" : "no");
- if (2 == rc)
- ir_attach(adap, msg[0].addr, 0, 0);
- }
+static const struct i2c_device_id ir_kbd_id[] = {
+ /* Generic entry for any IR receiver */
+ { "ir_video", 0 },
+ /* IR device specific entries could be added here */
+ { }
+};
- return 0;
-}
+static struct i2c_driver driver = {
+ .driver = {
+ .name = "ir-kbd-i2c",
+ },
+ .probe = ir_probe,
+ .remove = ir_remove,
+ .id_table = ir_kbd_id,
+};
/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index b0195e8ee4d1..e9ca9a064ae5 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -305,14 +305,17 @@ int ivtv_waitq(wait_queue_head_t *waitq)
/* Generic utility functions */
int ivtv_msleep_timeout(unsigned int msecs, int intr)
{
- int ret;
int timeout = msecs_to_jiffies(msecs);
do {
set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
timeout = schedule_timeout(timeout);
- if (intr && (ret = signal_pending(current)))
- return ret;
+ if (intr) {
+ int ret = signal_pending(current);
+
+ if (ret)
+ return ret;
+ }
} while (timeout);
return 0;
}
@@ -943,17 +946,14 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
if (itv == NULL)
return -ENOMEM;
itv->pdev = pdev;
- itv->instance = atomic_inc_return(&ivtv_instance) - 1;
+ itv->instance = v4l2_device_set_name(&itv->v4l2_dev, "ivtv",
+ &ivtv_instance);
retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev);
if (retval) {
kfree(itv);
return retval;
}
- /* "ivtv + PCI ID" is a bit of a mouthful, so use
- "ivtv + instance" instead. */
- snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name),
- "ivtv%d", itv->instance);
IVTV_INFO("Initializing card %d\n", itv->instance);
ivtv_process_options(itv);
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index ceb05bdcaf62..85ac707228e7 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -190,8 +190,8 @@ static int subdev_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
mask = itv->card->gpio_audio_detect.mask;
if (mask == 0 || (read_reg(IVTV_REG_GPIO_IN) & mask))
- vt->rxsubchans = V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
+ vt->rxsubchans = V4L2_TUNER_SUB_STEREO |
+ V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
else
vt->rxsubchans = V4L2_TUNER_SUB_MONO;
return 0;
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 9e3d32b8004c..e52aa322b134 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -579,9 +579,11 @@ static struct i2c_client ivtv_i2c_client_template = {
.name = "ivtv internal",
};
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter + instantiate IR receiver */
int init_ivtv_i2c(struct ivtv *itv)
{
+ int retval;
+
IVTV_DEBUG_I2C("i2c init\n");
/* Sanity checks for the I2C hardware arrays. They must be the
@@ -619,9 +621,37 @@ int init_ivtv_i2c(struct ivtv *itv)
ivtv_setsda(itv, 1);
if (itv->options.newi2c > 0)
- return i2c_add_adapter(&itv->i2c_adap);
+ retval = i2c_add_adapter(&itv->i2c_adap);
else
- return i2c_bit_add_bus(&itv->i2c_adap);
+ retval = i2c_bit_add_bus(&itv->i2c_adap);
+
+ /* Instantiate the IR receiver device, if present */
+ if (retval == 0) {
+ struct i2c_board_info info;
+ /* The external IR receiver is at i2c address 0x34 (0x35 for
+ reads). Future Hauppauge cards will have an internal
+ receiver at 0x30 (0x31 for reads). In theory, both can be
+ fitted, and Hauppauge suggest an external overrides an
+ internal.
+
+ That's why we probe 0x1a (~0x34) first. CB
+ */
+ const unsigned short addr_list[] = {
+ 0x1a, /* Hauppauge IR external */
+ 0x18, /* Hauppauge IR internal */
+ 0x71, /* Hauppauge IR (PVR150) */
+ 0x64, /* Pixelview IR */
+ 0x30, /* KNC ONE IR */
+ 0x6b, /* Adaptec IR */
+ I2C_CLIENT_END
+ };
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
+ }
+
+ return retval;
}
void exit_ivtv_i2c(struct ivtv *itv)
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 4a2d464f055e..c342a9fe983e 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -180,7 +180,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed)
/* Wait for any DMA to finish */
prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- while (itv->i_flags & IVTV_F_I_DMA) {
+ while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
got_sig = signal_pending(current);
if (got_sig)
break;
@@ -1710,7 +1710,8 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
we are waiting unlock first and later lock again. */
mutex_unlock(&itv->serialize_lock);
prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
- if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)
+ if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
+ !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
schedule();
finish_wait(&itv->event_waitq, &wait);
mutex_lock(&itv->serialize_lock);
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index 01c14d2b381a..cd9db0bf33bf 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -196,7 +196,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
bytes_needed, s->name);
return -1;
}
- if (rc && !s->buffers_stolen && (s->s_flags & IVTV_F_S_APPL_IO)) {
+ if (rc && !s->buffers_stolen && test_bit(IVTV_F_S_APPL_IO, &s->s_flags)) {
IVTV_WARN("All %s stream buffers are full. Dropping data.\n", s->name);
IVTV_WARN("Cause: the application is not reading fast enough.\n");
}
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index 7912ed6b72ee..c0875378acc2 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -1063,7 +1063,8 @@ static int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
/* if no UDMA is pending and no UDMA is in progress, then the DMA
is finished */
- while (itv->i_flags & (IVTV_F_I_UDMA_PENDING | IVTV_F_I_UDMA)) {
+ while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
+ test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
/* don't interrupt if the DMA is in progress but break off
a still pending DMA. */
got_sig = signal_pending(current);
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 66e6eb513076..fa6bb85cb4b0 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -298,7 +298,8 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
/* if no UDMA is pending and no UDMA is in progress, then the DMA
is finished */
- while (itv->i_flags & (IVTV_F_I_UDMA_PENDING | IVTV_F_I_UDMA)) {
+ while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
+ test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
/* don't interrupt if the DMA is in progress but break off
a still pending DMA. */
got_sig = signal_pending(current);
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 684f62fa7897..459c04cbf69d 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -75,53 +75,50 @@ struct mt9m001 {
unsigned char autoexposure;
};
-static int reg_read(struct soc_camera_device *icd, const u8 reg)
+static int reg_read(struct i2c_client *client, const u8 reg)
{
- struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
- struct i2c_client *client = mt9m001->client;
s32 data = i2c_smbus_read_word_data(client, reg);
return data < 0 ? data : swab16(data);
}
-static int reg_write(struct soc_camera_device *icd, const u8 reg,
+static int reg_write(struct i2c_client *client, const u8 reg,
const u16 data)
{
- struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
- return i2c_smbus_write_word_data(mt9m001->client, reg, swab16(data));
+ return i2c_smbus_write_word_data(client, reg, swab16(data));
}
-static int reg_set(struct soc_camera_device *icd, const u8 reg,
+static int reg_set(struct i2c_client *client, const u8 reg,
const u16 data)
{
int ret;
- ret = reg_read(icd, reg);
+ ret = reg_read(client, reg);
if (ret < 0)
return ret;
- return reg_write(icd, reg, ret | data);
+ return reg_write(client, reg, ret | data);
}
-static int reg_clear(struct soc_camera_device *icd, const u8 reg,
+static int reg_clear(struct i2c_client *client, const u8 reg,
const u16 data)
{
int ret;
- ret = reg_read(icd, reg);
+ ret = reg_read(client, reg);
if (ret < 0)
return ret;
- return reg_write(icd, reg, ret & ~data);
+ return reg_write(client, reg, ret & ~data);
}
static int mt9m001_init(struct soc_camera_device *icd)
{
- struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
- struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+ struct i2c_client *client = to_i2c_client(icd->control);
+ struct soc_camera_link *icl = client->dev.platform_data;
int ret;
dev_dbg(icd->vdev->parent, "%s\n", __func__);
if (icl->power) {
- ret = icl->power(&mt9m001->client->dev, 1);
+ ret = icl->power(&client->dev, 1);
if (ret < 0) {
dev_err(icd->vdev->parent,
"Platform failed to power-on the camera.\n");
@@ -131,49 +128,53 @@ static int mt9m001_init(struct soc_camera_device *icd)
/* The camera could have been already on, we reset it additionally */
if (icl->reset)
- ret = icl->reset(&mt9m001->client->dev);
+ ret = icl->reset(&client->dev);
else
ret = -ENODEV;
if (ret < 0) {
/* Either no platform reset, or platform reset failed */
- ret = reg_write(icd, MT9M001_RESET, 1);
+ ret = reg_write(client, MT9M001_RESET, 1);
if (!ret)
- ret = reg_write(icd, MT9M001_RESET, 0);
+ ret = reg_write(client, MT9M001_RESET, 0);
}
/* Disable chip, synchronous option update */
if (!ret)
- ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
+ ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
return ret;
}
static int mt9m001_release(struct soc_camera_device *icd)
{
- struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
- struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+ struct i2c_client *client = to_i2c_client(icd->control);
+ struct soc_camera_link *icl = client->dev.platform_data;
/* Disable the chip */
- reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
+ reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
if (icl->power)
- icl->power(&mt9m001->client->dev, 0);
+ icl->power(&client->dev, 0);
return 0;
}
static int mt9m001_start_capture(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
+
/* Switch to master "normal" mode */
- if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 2) < 0)
+ if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0)
return -EIO;
return 0;
}
static int mt9m001_stop_capture(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
+
/* Stop sensor readout */
- if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 0) < 0)
+ if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0)
return -EIO;
return 0;
}
@@ -222,28 +223,29 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
static int mt9m001_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
int ret;
const u16 hblank = 9, vblank = 25;
/* Blanking and start values - default... */
- ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank);
+ ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
if (!ret)
- ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank);
+ ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank);
/* The caller provides a supported format, as verified per
* call to icd->try_fmt() */
if (!ret)
- ret = reg_write(icd, MT9M001_COLUMN_START, rect->left);
+ ret = reg_write(client, MT9M001_COLUMN_START, rect->left);
if (!ret)
- ret = reg_write(icd, MT9M001_ROW_START, rect->top);
+ ret = reg_write(client, MT9M001_ROW_START, rect->top);
if (!ret)
- ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1);
+ ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect->width - 1);
if (!ret)
- ret = reg_write(icd, MT9M001_WINDOW_HEIGHT,
+ ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
rect->height + icd->y_skip_top - 1);
if (!ret && mt9m001->autoexposure) {
- ret = reg_write(icd, MT9M001_SHUTTER_WIDTH,
+ ret = reg_write(client, MT9M001_SHUTTER_WIDTH,
rect->height + icd->y_skip_top + vblank);
if (!ret) {
const struct v4l2_queryctrl *qctrl =
@@ -312,16 +314,16 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd,
static int mt9m001_get_register(struct soc_camera_device *icd,
struct v4l2_dbg_register *reg)
{
- struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+ struct i2c_client *client = to_i2c_client(icd->control);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != mt9m001->client->addr)
+ if (reg->match.addr != client->addr)
return -ENODEV;
reg->size = 2;
- reg->val = reg_read(icd, reg->reg);
+ reg->val = reg_read(client, reg->reg);
if (reg->val > 0xffff)
return -EIO;
@@ -332,15 +334,15 @@ static int mt9m001_get_register(struct soc_camera_device *icd,
static int mt9m001_set_register(struct soc_camera_device *icd,
struct v4l2_dbg_register *reg)
{
- struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+ struct i2c_client *client = to_i2c_client(icd->control);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != mt9m001->client->addr)
+ if (reg->match.addr != client->addr)
return -ENODEV;
- if (reg_write(icd, reg->reg, reg->val) < 0)
+ if (reg_write(client, reg->reg, reg->val) < 0)
return -EIO;
return 0;
@@ -416,12 +418,13 @@ static struct soc_camera_ops mt9m001_ops = {
static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
int data;
switch (ctrl->id) {
case V4L2_CID_VFLIP:
- data = reg_read(icd, MT9M001_READ_OPTIONS2);
+ data = reg_read(client, MT9M001_READ_OPTIONS2);
if (data < 0)
return -EIO;
ctrl->value = !!(data & 0x8000);
@@ -435,6 +438,7 @@ static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_contro
static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
const struct v4l2_queryctrl *qctrl;
int data;
@@ -447,9 +451,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
switch (ctrl->id) {
case V4L2_CID_VFLIP:
if (ctrl->value)
- data = reg_set(icd, MT9M001_READ_OPTIONS2, 0x8000);
+ data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000);
else
- data = reg_clear(icd, MT9M001_READ_OPTIONS2, 0x8000);
+ data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000);
if (data < 0)
return -EIO;
break;
@@ -463,7 +467,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
dev_dbg(&icd->dev, "Setting gain %d\n", data);
- data = reg_write(icd, MT9M001_GLOBAL_GAIN, data);
+ data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
if (data < 0)
return -EIO;
} else {
@@ -481,8 +485,8 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
data = ((gain - 64) * 7 + 28) / 56 + 96;
dev_dbg(&icd->dev, "Setting gain from %d to %d\n",
- reg_read(icd, MT9M001_GLOBAL_GAIN), data);
- data = reg_write(icd, MT9M001_GLOBAL_GAIN, data);
+ reg_read(client, MT9M001_GLOBAL_GAIN), data);
+ data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
if (data < 0)
return -EIO;
}
@@ -500,8 +504,8 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
range / 2) / range + 1;
dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n",
- reg_read(icd, MT9M001_SHUTTER_WIDTH), shutter);
- if (reg_write(icd, MT9M001_SHUTTER_WIDTH, shutter) < 0)
+ reg_read(client, MT9M001_SHUTTER_WIDTH), shutter);
+ if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
return -EIO;
icd->exposure = ctrl->value;
mt9m001->autoexposure = 0;
@@ -510,7 +514,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
case V4L2_CID_EXPOSURE_AUTO:
if (ctrl->value) {
const u16 vblank = 25;
- if (reg_write(icd, MT9M001_SHUTTER_WIDTH, icd->height +
+ if (reg_write(client, MT9M001_SHUTTER_WIDTH, icd->height +
icd->y_skip_top + vblank) < 0)
return -EIO;
qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
@@ -529,8 +533,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
* this wasn't our capture interface, so, we wait for the right one */
static int mt9m001_video_probe(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
- struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+ struct soc_camera_link *icl = client->dev.platform_data;
s32 data;
int ret;
unsigned long flags;
@@ -542,11 +547,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
return -ENODEV;
/* Enable the chip */
- data = reg_write(icd, MT9M001_CHIP_ENABLE, 1);
+ data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
dev_dbg(&icd->dev, "write: %d\n", data);
/* Read out the chip version register */
- data = reg_read(icd, MT9M001_CHIP_VERSION);
+ data = reg_read(client, MT9M001_CHIP_VERSION);
/* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
switch (data) {
@@ -604,10 +609,13 @@ ei2c:
static void mt9m001_video_remove(struct soc_camera_device *icd)
{
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+ struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr,
icd->dev.parent, icd->vdev);
soc_camera_video_stop(icd);
+ if (icl->free_bus)
+ icl->free_bus(icl);
}
static int mt9m001_probe(struct i2c_client *client,
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index cdd1ddb51388..fc5e2de03766 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -113,10 +113,10 @@
* mt9m111: Camera control register addresses (0x200..0x2ff not implemented)
*/
-#define reg_read(reg) mt9m111_reg_read(icd, MT9M111_##reg)
-#define reg_write(reg, val) mt9m111_reg_write(icd, MT9M111_##reg, (val))
-#define reg_set(reg, val) mt9m111_reg_set(icd, MT9M111_##reg, (val))
-#define reg_clear(reg, val) mt9m111_reg_clear(icd, MT9M111_##reg, (val))
+#define reg_read(reg) mt9m111_reg_read(client, MT9M111_##reg)
+#define reg_write(reg, val) mt9m111_reg_write(client, MT9M111_##reg, (val))
+#define reg_set(reg, val) mt9m111_reg_set(client, MT9M111_##reg, (val))
+#define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val))
#define MT9M111_MIN_DARK_ROWS 8
#define MT9M111_MIN_DARK_COLS 24
@@ -184,58 +184,55 @@ static int reg_page_map_set(struct i2c_client *client, const u16 reg)
return ret;
}
-static int mt9m111_reg_read(struct soc_camera_device *icd, const u16 reg)
+static int mt9m111_reg_read(struct i2c_client *client, const u16 reg)
{
- struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
- struct i2c_client *client = mt9m111->client;
int ret;
ret = reg_page_map_set(client, reg);
if (!ret)
ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff)));
- dev_dbg(&icd->dev, "read reg.%03x -> %04x\n", reg, ret);
+ dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret);
return ret;
}
-static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg,
+static int mt9m111_reg_write(struct i2c_client *client, const u16 reg,
const u16 data)
{
- struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
- struct i2c_client *client = mt9m111->client;
int ret;
ret = reg_page_map_set(client, reg);
if (!ret)
- ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff),
+ ret = i2c_smbus_write_word_data(client, (reg & 0xff),
swab16(data));
- dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
+ dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
return ret;
}
-static int mt9m111_reg_set(struct soc_camera_device *icd, const u16 reg,
+static int mt9m111_reg_set(struct i2c_client *client, const u16 reg,
const u16 data)
{
int ret;
- ret = mt9m111_reg_read(icd, reg);
+ ret = mt9m111_reg_read(client, reg);
if (ret >= 0)
- ret = mt9m111_reg_write(icd, reg, ret | data);
+ ret = mt9m111_reg_write(client, reg, ret | data);
return ret;
}
-static int mt9m111_reg_clear(struct soc_camera_device *icd, const u16 reg,
+static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
const u16 data)
{
int ret;
- ret = mt9m111_reg_read(icd, reg);
- return mt9m111_reg_write(icd, reg, ret & ~data);
+ ret = mt9m111_reg_read(client, reg);
+ return mt9m111_reg_write(client, reg, ret & ~data);
}
static int mt9m111_set_context(struct soc_camera_device *icd,
enum mt9m111_context ctxt)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B
| MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B
| MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B
@@ -252,6 +249,7 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
static int mt9m111_setup_rect(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
int ret, is_raw_format;
int width = rect->width;
@@ -296,6 +294,7 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd,
static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
int ret;
ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt);
@@ -357,12 +356,13 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
static int mt9m111_enable(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
- struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
+ struct soc_camera_link *icl = client->dev.platform_data;
int ret;
if (icl->power) {
- ret = icl->power(&mt9m111->client->dev, 1);
+ ret = icl->power(&client->dev, 1);
if (ret < 0) {
dev_err(icd->vdev->parent,
"Platform failed to power-on the camera.\n");
@@ -378,8 +378,9 @@ static int mt9m111_enable(struct soc_camera_device *icd)
static int mt9m111_disable(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
- struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
+ struct soc_camera_link *icl = client->dev.platform_data;
int ret;
ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
@@ -387,15 +388,15 @@ static int mt9m111_disable(struct soc_camera_device *icd)
mt9m111->powered = 0;
if (icl->power)
- icl->power(&mt9m111->client->dev, 0);
+ icl->power(&client->dev, 0);
return ret;
}
static int mt9m111_reset(struct soc_camera_device *icd)
{
- struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
- struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
+ struct i2c_client *client = to_i2c_client(icd->control);
+ struct soc_camera_link *icl = client->dev.platform_data;
int ret;
ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -406,7 +407,7 @@ static int mt9m111_reset(struct soc_camera_device *icd)
| MT9M111_RESET_RESET_SOC);
if (icl->reset)
- icl->reset(&mt9m111->client->dev);
+ icl->reset(&client->dev);
return ret;
}
@@ -562,15 +563,14 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
struct v4l2_dbg_register *reg)
{
int val;
-
- struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+ struct i2c_client *client = to_i2c_client(icd->control);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
return -EINVAL;
- if (reg->match.addr != mt9m111->client->addr)
+ if (reg->match.addr != client->addr)
return -ENODEV;
- val = mt9m111_reg_read(icd, reg->reg);
+ val = mt9m111_reg_read(client, reg->reg);
reg->size = 2;
reg->val = (u64)val;
@@ -583,15 +583,15 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
static int mt9m111_set_register(struct soc_camera_device *icd,
struct v4l2_dbg_register *reg)
{
- struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+ struct i2c_client *client = to_i2c_client(icd->control);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
return -EINVAL;
- if (reg->match.addr != mt9m111->client->addr)
+ if (reg->match.addr != client->addr)
return -ENODEV;
- if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0)
+ if (mt9m111_reg_write(client, reg->reg, reg->val) < 0)
return -EIO;
return 0;
@@ -672,6 +672,7 @@ static struct soc_camera_ops mt9m111_ops = {
static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
int ret;
@@ -692,6 +693,7 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
static int mt9m111_get_global_gain(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
int data;
data = reg_read(GLOBAL_GAIN);
@@ -703,6 +705,7 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd)
static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
u16 val;
if (gain > 63 * 2 * 2)
@@ -721,6 +724,7 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
int ret;
@@ -737,6 +741,7 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
int ret;
@@ -754,6 +759,7 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
static int mt9m111_get_control(struct soc_camera_device *icd,
struct v4l2_control *ctrl)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
int data;
@@ -898,6 +904,7 @@ static int mt9m111_release(struct soc_camera_device *icd)
*/
static int mt9m111_video_probe(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
s32 data;
int ret;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 2b0927bfd217..f72aeb7c4deb 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -76,64 +76,61 @@ struct mt9t031 {
u16 yskip;
};
-static int reg_read(struct soc_camera_device *icd, const u8 reg)
+static int reg_read(struct i2c_client *client, const u8 reg)
{
- struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
- struct i2c_client *client = mt9t031->client;
s32 data = i2c_smbus_read_word_data(client, reg);
return data < 0 ? data : swab16(data);
}
-static int reg_write(struct soc_camera_device *icd, const u8 reg,
+static int reg_write(struct i2c_client *client, const u8 reg,
const u16 data)
{
- struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
- return i2c_smbus_write_word_data(mt9t031->client, reg, swab16(data));
+ return i2c_smbus_write_word_data(client, reg, swab16(data));
}
-static int reg_set(struct soc_camera_device *icd, const u8 reg,
+static int reg_set(struct i2c_client *client, const u8 reg,
const u16 data)
{
int ret;
- ret = reg_read(icd, reg);
+ ret = reg_read(client, reg);
if (ret < 0)
return ret;
- return reg_write(icd, reg, ret | data);
+ return reg_write(client, reg, ret | data);
}
-static int reg_clear(struct soc_camera_device *icd, const u8 reg,
+static int reg_clear(struct i2c_client *client, const u8 reg,
const u16 data)
{
int ret;
- ret = reg_read(icd, reg);
+ ret = reg_read(client, reg);
if (ret < 0)
return ret;
- return reg_write(icd, reg, ret & ~data);
+ return reg_write(client, reg, ret & ~data);
}
-static int set_shutter(struct soc_camera_device *icd, const u32 data)
+static int set_shutter(struct i2c_client *client, const u32 data)
{
int ret;
- ret = reg_write(icd, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16);
+ ret = reg_write(client, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16);
if (ret >= 0)
- ret = reg_write(icd, MT9T031_SHUTTER_WIDTH, data & 0xffff);
+ ret = reg_write(client, MT9T031_SHUTTER_WIDTH, data & 0xffff);
return ret;
}
-static int get_shutter(struct soc_camera_device *icd, u32 *data)
+static int get_shutter(struct i2c_client *client, u32 *data)
{
int ret;
- ret = reg_read(icd, MT9T031_SHUTTER_WIDTH_UPPER);
+ ret = reg_read(client, MT9T031_SHUTTER_WIDTH_UPPER);
*data = ret << 16;
if (ret >= 0)
- ret = reg_read(icd, MT9T031_SHUTTER_WIDTH);
+ ret = reg_read(client, MT9T031_SHUTTER_WIDTH);
*data |= ret & 0xffff;
return ret < 0 ? ret : 0;
@@ -141,12 +138,12 @@ static int get_shutter(struct soc_camera_device *icd, u32 *data)
static int mt9t031_init(struct soc_camera_device *icd)
{
- struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
- struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
+ struct i2c_client *client = to_i2c_client(icd->control);
+ struct soc_camera_link *icl = client->dev.platform_data;
int ret;
if (icl->power) {
- ret = icl->power(&mt9t031->client->dev, 1);
+ ret = icl->power(&client->dev, 1);
if (ret < 0) {
dev_err(icd->vdev->parent,
"Platform failed to power-on the camera.\n");
@@ -155,44 +152,48 @@ static int mt9t031_init(struct soc_camera_device *icd)
}
/* Disable chip output, synchronous option update */
- ret = reg_write(icd, MT9T031_RESET, 1);
+ ret = reg_write(client, MT9T031_RESET, 1);
if (ret >= 0)
- ret = reg_write(icd, MT9T031_RESET, 0);
+ ret = reg_write(client, MT9T031_RESET, 0);
if (ret >= 0)
- ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
+ ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
if (ret < 0 && icl->power)
- icl->power(&mt9t031->client->dev, 0);
+ icl->power(&client->dev, 0);
return ret >= 0 ? 0 : -EIO;
}
static int mt9t031_release(struct soc_camera_device *icd)
{
- struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
- struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
+ struct i2c_client *client = to_i2c_client(icd->control);
+ struct soc_camera_link *icl = client->dev.platform_data;
/* Disable the chip */
- reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
+ reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
if (icl->power)
- icl->power(&mt9t031->client->dev, 0);
+ icl->power(&client->dev, 0);
return 0;
}
static int mt9t031_start_capture(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
+
/* Switch to master "normal" mode */
- if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 2) < 0)
+ if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
return -EIO;
return 0;
}
static int mt9t031_stop_capture(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
+
/* Stop sensor readout */
- if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2) < 0)
+ if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
return -EIO;
return 0;
}
@@ -200,14 +201,16 @@ static int mt9t031_stop_capture(struct soc_camera_device *icd)
static int mt9t031_set_bus_param(struct soc_camera_device *icd,
unsigned long flags)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
+
/* The caller should have queried our parameters, check anyway */
if (flags & ~MT9T031_BUS_PARAM)
return -EINVAL;
if (flags & SOCAM_PCLK_SAMPLE_FALLING)
- reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
+ reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
else
- reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
+ reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
return 0;
}
@@ -235,6 +238,7 @@ static void recalculate_limits(struct soc_camera_device *icd,
static int mt9t031_set_params(struct soc_camera_device *icd,
struct v4l2_rect *rect, u16 xskip, u16 yskip)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
int ret;
u16 xbin, ybin, width, height, left, top;
@@ -277,22 +281,22 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
}
/* Disable register update, reconfigure atomically */
- ret = reg_set(icd, MT9T031_OUTPUT_CONTROL, 1);
+ ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1);
if (ret < 0)
return ret;
/* Blanking and start values - default... */
- ret = reg_write(icd, MT9T031_HORIZONTAL_BLANKING, hblank);
+ ret = reg_write(client, MT9T031_HORIZONTAL_BLANKING, hblank);
if (ret >= 0)
- ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank);
+ ret = reg_write(client, MT9T031_VERTICAL_BLANKING, vblank);
if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) {
/* Binning, skipping */
if (ret >= 0)
- ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE,
+ ret = reg_write(client, MT9T031_COLUMN_ADDRESS_MODE,
((xbin - 1) << 4) | (xskip - 1));
if (ret >= 0)
- ret = reg_write(icd, MT9T031_ROW_ADDRESS_MODE,
+ ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
((ybin - 1) << 4) | (yskip - 1));
}
dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top);
@@ -300,16 +304,16 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
/* The caller provides a supported format, as guaranteed by
* icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
if (ret >= 0)
- ret = reg_write(icd, MT9T031_COLUMN_START, left);
+ ret = reg_write(client, MT9T031_COLUMN_START, left);
if (ret >= 0)
- ret = reg_write(icd, MT9T031_ROW_START, top);
+ ret = reg_write(client, MT9T031_ROW_START, top);
if (ret >= 0)
- ret = reg_write(icd, MT9T031_WINDOW_WIDTH, width - 1);
+ ret = reg_write(client, MT9T031_WINDOW_WIDTH, width - 1);
if (ret >= 0)
- ret = reg_write(icd, MT9T031_WINDOW_HEIGHT,
+ ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
height + icd->y_skip_top - 1);
if (ret >= 0 && mt9t031->autoexposure) {
- ret = set_shutter(icd, height + icd->y_skip_top + vblank);
+ ret = set_shutter(client, height + icd->y_skip_top + vblank);
if (ret >= 0) {
const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
const struct v4l2_queryctrl *qctrl =
@@ -324,7 +328,7 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
/* Re-enable register update, commit all changes */
if (ret >= 0)
- ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1);
+ ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1);
return ret < 0 ? ret : 0;
}
@@ -417,15 +421,15 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd,
static int mt9t031_get_register(struct soc_camera_device *icd,
struct v4l2_dbg_register *reg)
{
- struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+ struct i2c_client *client = to_i2c_client(icd->control);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != mt9t031->client->addr)
+ if (reg->match.addr != client->addr)
return -ENODEV;
- reg->val = reg_read(icd, reg->reg);
+ reg->val = reg_read(client, reg->reg);
if (reg->val > 0xffff)
return -EIO;
@@ -436,15 +440,15 @@ static int mt9t031_get_register(struct soc_camera_device *icd,
static int mt9t031_set_register(struct soc_camera_device *icd,
struct v4l2_dbg_register *reg)
{
- struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+ struct i2c_client *client = to_i2c_client(icd->control);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != mt9t031->client->addr)
+ if (reg->match.addr != client->addr)
return -ENODEV;
- if (reg_write(icd, reg->reg, reg->val) < 0)
+ if (reg_write(client, reg->reg, reg->val) < 0)
return -EIO;
return 0;
@@ -528,18 +532,19 @@ static struct soc_camera_ops mt9t031_ops = {
static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
int data;
switch (ctrl->id) {
case V4L2_CID_VFLIP:
- data = reg_read(icd, MT9T031_READ_MODE_2);
+ data = reg_read(client, MT9T031_READ_MODE_2);
if (data < 0)
return -EIO;
ctrl->value = !!(data & 0x8000);
break;
case V4L2_CID_HFLIP:
- data = reg_read(icd, MT9T031_READ_MODE_2);
+ data = reg_read(client, MT9T031_READ_MODE_2);
if (data < 0)
return -EIO;
ctrl->value = !!(data & 0x4000);
@@ -553,6 +558,7 @@ static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_contro
static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
const struct v4l2_queryctrl *qctrl;
int data;
@@ -565,17 +571,17 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
switch (ctrl->id) {
case V4L2_CID_VFLIP:
if (ctrl->value)
- data = reg_set(icd, MT9T031_READ_MODE_2, 0x8000);
+ data = reg_set(client, MT9T031_READ_MODE_2, 0x8000);
else
- data = reg_clear(icd, MT9T031_READ_MODE_2, 0x8000);
+ data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000);
if (data < 0)
return -EIO;
break;
case V4L2_CID_HFLIP:
if (ctrl->value)
- data = reg_set(icd, MT9T031_READ_MODE_2, 0x4000);
+ data = reg_set(client, MT9T031_READ_MODE_2, 0x4000);
else
- data = reg_clear(icd, MT9T031_READ_MODE_2, 0x4000);
+ data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000);
if (data < 0)
return -EIO;
break;
@@ -589,7 +595,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
dev_dbg(&icd->dev, "Setting gain %d\n", data);
- data = reg_write(icd, MT9T031_GLOBAL_GAIN, data);
+ data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
if (data < 0)
return -EIO;
} else {
@@ -609,8 +615,8 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n",
- reg_read(icd, MT9T031_GLOBAL_GAIN), data);
- data = reg_write(icd, MT9T031_GLOBAL_GAIN, data);
+ reg_read(client, MT9T031_GLOBAL_GAIN), data);
+ data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
if (data < 0)
return -EIO;
}
@@ -628,10 +634,10 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
range / 2) / range + 1;
u32 old;
- get_shutter(icd, &old);
+ get_shutter(client, &old);
dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n",
old, shutter);
- if (set_shutter(icd, shutter) < 0)
+ if (set_shutter(client, shutter) < 0)
return -EIO;
icd->exposure = ctrl->value;
mt9t031->autoexposure = 0;
@@ -641,7 +647,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
if (ctrl->value) {
const u16 vblank = MT9T031_VERTICAL_BLANK;
const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
- if (set_shutter(icd, icd->height +
+ if (set_shutter(client, icd->height +
icd->y_skip_top + vblank) < 0)
return -EIO;
qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
@@ -661,6 +667,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
* this wasn't our capture interface, so, we wait for the right one */
static int mt9t031_video_probe(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
s32 data;
int ret;
@@ -672,11 +679,11 @@ static int mt9t031_video_probe(struct soc_camera_device *icd)
return -ENODEV;
/* Enable the chip */
- data = reg_write(icd, MT9T031_CHIP_ENABLE, 1);
+ data = reg_write(client, MT9T031_CHIP_ENABLE, 1);
dev_dbg(&icd->dev, "write: %d\n", data);
/* Read out the chip version register */
- data = reg_read(icd, MT9T031_CHIP_VERSION);
+ data = reg_read(client, MT9T031_CHIP_VERSION);
switch (data) {
case 0x1621:
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 4d3b4813c322..be20d312b1dc 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -91,51 +91,49 @@ struct mt9v022 {
u16 chip_control;
};
-static int reg_read(struct soc_camera_device *icd, const u8 reg)
+static int reg_read(struct i2c_client *client, const u8 reg)
{
- struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
- struct i2c_client *client = mt9v022->client;
s32 data = i2c_smbus_read_word_data(client, reg);
return data < 0 ? data : swab16(data);
}
-static int reg_write(struct soc_camera_device *icd, const u8 reg,
+static int reg_write(struct i2c_client *client, const u8 reg,
const u16 data)
{
- struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
- return i2c_smbus_write_word_data(mt9v022->client, reg, swab16(data));
+ return i2c_smbus_write_word_data(client, reg, swab16(data));
}
-static int reg_set(struct soc_camera_device *icd, const u8 reg,
+static int reg_set(struct i2c_client *client, const u8 reg,
const u16 data)
{
int ret;
- ret = reg_read(icd, reg);
+ ret = reg_read(client, reg);
if (ret < 0)
return ret;
- return reg_write(icd, reg, ret | data);
+ return reg_write(client, reg, ret | data);
}
-static int reg_clear(struct soc_camera_device *icd, const u8 reg,
+static int reg_clear(struct i2c_client *client, const u8 reg,
const u16 data)
{
int ret;
- ret = reg_read(icd, reg);
+ ret = reg_read(client, reg);
if (ret < 0)
return ret;
- return reg_write(icd, reg, ret & ~data);
+ return reg_write(client, reg, ret & ~data);
}
static int mt9v022_init(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
- struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+ struct soc_camera_link *icl = client->dev.platform_data;
int ret;
if (icl->power) {
- ret = icl->power(&mt9v022->client->dev, 1);
+ ret = icl->power(&client->dev, 1);
if (ret < 0) {
dev_err(icd->vdev->parent,
"Platform failed to power-on the camera.\n");
@@ -148,27 +146,27 @@ static int mt9v022_init(struct soc_camera_device *icd)
* if available. Soft reset is done in video_probe().
*/
if (icl->reset)
- icl->reset(&mt9v022->client->dev);
+ icl->reset(&client->dev);
/* Almost the default mode: master, parallel, simultaneous, and an
* undocumented bit 0x200, which is present in table 7, but not in 8,
* plus snapshot mode to disable scan for now */
mt9v022->chip_control |= 0x10;
- ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
+ ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
if (!ret)
- ret = reg_write(icd, MT9V022_READ_MODE, 0x300);
+ ret = reg_write(client, MT9V022_READ_MODE, 0x300);
/* All defaults */
if (!ret)
/* AEC, AGC on */
- ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3);
+ ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
if (!ret)
- ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
+ ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
if (!ret)
/* default - auto */
- ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
+ ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
if (!ret)
- ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0);
+ ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
return ret;
}
@@ -186,10 +184,11 @@ static int mt9v022_release(struct soc_camera_device *icd)
static int mt9v022_start_capture(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
/* Switch to master "normal" mode */
mt9v022->chip_control &= ~0x10;
- if (reg_write(icd, MT9V022_CHIP_CONTROL,
+ if (reg_write(client, MT9V022_CHIP_CONTROL,
mt9v022->chip_control) < 0)
return -EIO;
return 0;
@@ -197,10 +196,11 @@ static int mt9v022_start_capture(struct soc_camera_device *icd)
static int mt9v022_stop_capture(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
/* Switch to snapshot mode */
mt9v022->chip_control |= 0x10;
- if (reg_write(icd, MT9V022_CHIP_CONTROL,
+ if (reg_write(client, MT9V022_CHIP_CONTROL,
mt9v022->chip_control) < 0)
return -EIO;
return 0;
@@ -209,8 +209,9 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd)
static int mt9v022_set_bus_param(struct soc_camera_device *icd,
unsigned long flags)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
- struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+ struct soc_camera_link *icl = client->dev.platform_data;
unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
int ret;
u16 pixclk = 0;
@@ -243,14 +244,14 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
pixclk |= 0x2;
- ret = reg_write(icd, MT9V022_PIXCLK_FV_LV, pixclk);
+ ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
if (ret < 0)
return ret;
if (!(flags & SOCAM_MASTER))
mt9v022->chip_control &= ~0x8;
- ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
+ ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
if (ret < 0)
return ret;
@@ -282,35 +283,36 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
static int mt9v022_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
int ret;
/* Like in example app. Contradicts the datasheet though */
- ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE);
+ ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
if (ret >= 0) {
if (ret & 1) /* Autoexposure */
- ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
+ ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
rect->height + icd->y_skip_top + 43);
else
- ret = reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH,
+ ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
rect->height + icd->y_skip_top + 43);
}
/* Setup frame format: defaults apart from width and height */
if (!ret)
- ret = reg_write(icd, MT9V022_COLUMN_START, rect->left);
+ ret = reg_write(client, MT9V022_COLUMN_START, rect->left);
if (!ret)
- ret = reg_write(icd, MT9V022_ROW_START, rect->top);
+ ret = reg_write(client, MT9V022_ROW_START, rect->top);
if (!ret)
/* Default 94, Phytec driver says:
* "width + horizontal blank >= 660" */
- ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING,
+ ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
rect->width > 660 - 43 ? 43 :
660 - rect->width);
if (!ret)
- ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45);
+ ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
if (!ret)
- ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width);
+ ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width);
if (!ret)
- ret = reg_write(icd, MT9V022_WINDOW_HEIGHT,
+ ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
rect->height + icd->y_skip_top);
if (ret < 0)
@@ -396,16 +398,16 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd,
static int mt9v022_get_register(struct soc_camera_device *icd,
struct v4l2_dbg_register *reg)
{
- struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+ struct i2c_client *client = to_i2c_client(icd->control);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != mt9v022->client->addr)
+ if (reg->match.addr != client->addr)
return -ENODEV;
reg->size = 2;
- reg->val = reg_read(icd, reg->reg);
+ reg->val = reg_read(client, reg->reg);
if (reg->val > 0xffff)
return -EIO;
@@ -416,15 +418,15 @@ static int mt9v022_get_register(struct soc_camera_device *icd,
static int mt9v022_set_register(struct soc_camera_device *icd,
struct v4l2_dbg_register *reg)
{
- struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+ struct i2c_client *client = to_i2c_client(icd->control);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != mt9v022->client->addr)
+ if (reg->match.addr != client->addr)
return -ENODEV;
- if (reg_write(icd, reg->reg, reg->val) < 0)
+ if (reg_write(client, reg->reg, reg->val) < 0)
return -EIO;
return 0;
@@ -517,29 +519,30 @@ static struct soc_camera_ops mt9v022_ops = {
static int mt9v022_get_control(struct soc_camera_device *icd,
struct v4l2_control *ctrl)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
int data;
switch (ctrl->id) {
case V4L2_CID_VFLIP:
- data = reg_read(icd, MT9V022_READ_MODE);
+ data = reg_read(client, MT9V022_READ_MODE);
if (data < 0)
return -EIO;
ctrl->value = !!(data & 0x10);
break;
case V4L2_CID_HFLIP:
- data = reg_read(icd, MT9V022_READ_MODE);
+ data = reg_read(client, MT9V022_READ_MODE);
if (data < 0)
return -EIO;
ctrl->value = !!(data & 0x20);
break;
case V4L2_CID_EXPOSURE_AUTO:
- data = reg_read(icd, MT9V022_AEC_AGC_ENABLE);
+ data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
if (data < 0)
return -EIO;
ctrl->value = !!(data & 0x1);
break;
case V4L2_CID_AUTOGAIN:
- data = reg_read(icd, MT9V022_AEC_AGC_ENABLE);
+ data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
if (data < 0)
return -EIO;
ctrl->value = !!(data & 0x2);
@@ -552,6 +555,7 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
struct v4l2_control *ctrl)
{
int data;
+ struct i2c_client *client = to_i2c_client(icd->control);
const struct v4l2_queryctrl *qctrl;
qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
@@ -562,17 +566,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
switch (ctrl->id) {
case V4L2_CID_VFLIP:
if (ctrl->value)
- data = reg_set(icd, MT9V022_READ_MODE, 0x10);
+ data = reg_set(client, MT9V022_READ_MODE, 0x10);
else
- data = reg_clear(icd, MT9V022_READ_MODE, 0x10);
+ data = reg_clear(client, MT9V022_READ_MODE, 0x10);
if (data < 0)
return -EIO;
break;
case V4L2_CID_HFLIP:
if (ctrl->value)
- data = reg_set(icd, MT9V022_READ_MODE, 0x20);
+ data = reg_set(client, MT9V022_READ_MODE, 0x20);
else
- data = reg_clear(icd, MT9V022_READ_MODE, 0x20);
+ data = reg_clear(client, MT9V022_READ_MODE, 0x20);
if (data < 0)
return -EIO;
break;
@@ -593,12 +597,12 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
/* The user wants to set gain manually, hope, she
* knows, what she's doing... Switch AGC off. */
- if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
+ if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
return -EIO;
dev_info(&icd->dev, "Setting gain from %d to %lu\n",
- reg_read(icd, MT9V022_ANALOG_GAIN), gain);
- if (reg_write(icd, MT9V022_ANALOG_GAIN, gain) < 0)
+ reg_read(client, MT9V022_ANALOG_GAIN), gain);
+ if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
return -EIO;
icd->gain = ctrl->value;
}
@@ -614,13 +618,13 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
/* The user wants to set shutter width manually, hope,
* she knows, what she's doing... Switch AEC off. */
- if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
+ if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
return -EIO;
dev_dbg(&icd->dev, "Shutter width from %d to %lu\n",
- reg_read(icd, MT9V022_TOTAL_SHUTTER_WIDTH),
+ reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
shutter);
- if (reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH,
+ if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
shutter) < 0)
return -EIO;
icd->exposure = ctrl->value;
@@ -628,17 +632,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
break;
case V4L2_CID_AUTOGAIN:
if (ctrl->value)
- data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x2);
+ data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
else
- data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2);
+ data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
if (data < 0)
return -EIO;
break;
case V4L2_CID_EXPOSURE_AUTO:
if (ctrl->value)
- data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x1);
+ data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
else
- data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1);
+ data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
if (data < 0)
return -EIO;
break;
@@ -650,8 +654,9 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
* this wasn't our capture interface, so, we wait for the right one */
static int mt9v022_video_probe(struct soc_camera_device *icd)
{
+ struct i2c_client *client = to_i2c_client(icd->control);
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
- struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+ struct soc_camera_link *icl = client->dev.platform_data;
s32 data;
int ret;
unsigned long flags;
@@ -661,7 +666,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
return -ENODEV;
/* Read out the chip version register */
- data = reg_read(icd, MT9V022_CHIP_VERSION);
+ data = reg_read(client, MT9V022_CHIP_VERSION);
/* must be 0x1311 or 0x1313 */
if (data != 0x1311 && data != 0x1313) {
@@ -672,12 +677,12 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
}
/* Soft reset */
- ret = reg_write(icd, MT9V022_RESET, 1);
+ ret = reg_write(client, MT9V022_RESET, 1);
if (ret < 0)
goto ei2c;
/* 15 clock cycles */
udelay(200);
- if (reg_read(icd, MT9V022_RESET)) {
+ if (reg_read(client, MT9V022_RESET)) {
dev_err(&icd->dev, "Resetting MT9V022 failed!\n");
goto ei2c;
}
@@ -685,11 +690,11 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
/* Set monochrome or colour sensor type */
if (sensor_type && (!strcmp("colour", sensor_type) ||
!strcmp("color", sensor_type))) {
- ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
+ ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
icd->formats = mt9v022_colour_formats;
} else {
- ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11);
+ ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
icd->formats = mt9v022_monochrome_formats;
}
@@ -735,10 +740,13 @@ ei2c:
static void mt9v022_video_remove(struct soc_camera_device *icd)
{
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+ struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr,
icd->dev.parent, icd->vdev);
soc_camera_video_stop(icd);
+ if (icl->free_bus)
+ icl->free_bus(icl);
}
static int mt9v022_probe(struct i2c_client *client,
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 86fab56c5a20..2d075205bdfe 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -102,10 +102,10 @@ struct mx1_buffer {
* Interface. If anyone ever builds hardware to enable more than
* one camera, they will have to modify this driver too */
struct mx1_camera_dev {
+ struct soc_camera_host soc_host;
struct soc_camera_device *icd;
struct mx1_camera_pdata *pdata;
struct mx1_buffer *active;
- struct device *dev;
struct resource *res;
struct clk *clk;
struct list_head capture;
@@ -219,7 +219,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
int ret;
if (unlikely(!pcdev->active)) {
- dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n");
+ dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n");
return -EFAULT;
}
@@ -229,7 +229,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
vbuf->size, pcdev->res->start +
CSIRXR, DMA_MODE_READ);
if (unlikely(ret))
- dev_err(pcdev->dev, "Failed to setup DMA sg list\n");
+ dev_err(pcdev->soc_host.dev, "Failed to setup DMA sg list\n");
return ret;
}
@@ -338,14 +338,14 @@ static void mx1_camera_dma_irq(int channel, void *data)
imx_dma_disable(channel);
if (unlikely(!pcdev->active)) {
- dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n");
+ dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n");
goto out;
}
vb = &pcdev->active->vb;
buf = container_of(vb, struct mx1_buffer, vb);
WARN_ON(buf->inwork || list_empty(&vb->queue));
- dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+ dev_dbg(pcdev->soc_host.dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
vb, vb->baddr, vb->bsize);
mx1_camera_wakeup(pcdev, vb, buf);
@@ -366,7 +366,7 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q,
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct mx1_camera_dev *pcdev = ici->priv;
- videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, pcdev->dev,
+ videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, ici->dev,
&pcdev->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_NONE,
@@ -385,7 +385,7 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
* they get a nice Oops */
div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
- dev_dbg(pcdev->dev, "System clock %lukHz, target freq %dkHz, "
+ dev_dbg(pcdev->soc_host.dev, "System clock %lukHz, target freq %dkHz, "
"divisor %lu\n", lcdclk / 1000, mclk / 1000, div);
return div;
@@ -395,7 +395,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
{
unsigned int csicr1 = CSICR1_EN;
- dev_dbg(pcdev->dev, "Activate device\n");
+ dev_dbg(pcdev->soc_host.dev, "Activate device\n");
clk_enable(pcdev->clk);
@@ -411,7 +411,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
{
- dev_dbg(pcdev->dev, "Deactivate device\n");
+ dev_dbg(pcdev->soc_host.dev, "Deactivate device\n");
/* Disable all CSI interface */
__raw_writel(0x00, pcdev->base + CSICR1);
@@ -550,7 +550,7 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
if (!xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+ dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
return -EINVAL;
}
@@ -633,12 +633,6 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
.querycap = mx1_camera_querycap,
};
-/* Should be allocated dynamically too, but we have only one. */
-static struct soc_camera_host mx1_soc_camera_host = {
- .drv_name = DRIVER_NAME,
- .ops = &mx1_soc_camera_host_ops,
-};
-
static struct fiq_handler fh = {
.name = "csi_sof"
};
@@ -673,7 +667,6 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
goto exit_put_clk;
}
- dev_set_drvdata(&pdev->dev, pcdev);
pcdev->res = res;
pcdev->clk = clk;
@@ -707,16 +700,15 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
}
pcdev->irq = irq;
pcdev->base = base;
- pcdev->dev = &pdev->dev;
/* request dma */
pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH);
if (pcdev->dma_chan < 0) {
- dev_err(pcdev->dev, "Can't request DMA for MX1 CSI\n");
+ dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n");
err = -EBUSY;
goto exit_iounmap;
}
- dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
+ dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL,
pcdev);
@@ -729,7 +721,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
/* request irq */
err = claim_fiq(&fh);
if (err) {
- dev_err(pcdev->dev, "Camera interrupt register failed \n");
+ dev_err(&pdev->dev, "Camera interrupt register failed \n");
goto exit_free_dma;
}
@@ -746,10 +738,12 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
mxc_set_irq_fiq(irq, 1);
enable_fiq(irq);
- mx1_soc_camera_host.priv = pcdev;
- mx1_soc_camera_host.dev.parent = &pdev->dev;
- mx1_soc_camera_host.nr = pdev->id;
- err = soc_camera_host_register(&mx1_soc_camera_host);
+ pcdev->soc_host.drv_name = DRIVER_NAME;
+ pcdev->soc_host.ops = &mx1_soc_camera_host_ops;
+ pcdev->soc_host.priv = pcdev;
+ pcdev->soc_host.dev = &pdev->dev;
+ pcdev->soc_host.nr = pdev->id;
+ err = soc_camera_host_register(&pcdev->soc_host);
if (err)
goto exit_free_irq;
@@ -777,7 +771,9 @@ exit:
static int __exit mx1_camera_remove(struct platform_device *pdev)
{
- struct mx1_camera_dev *pcdev = platform_get_drvdata(pdev);
+ struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
+ struct mx1_camera_dev *pcdev = container_of(soc_host,
+ struct mx1_camera_dev, soc_host);
struct resource *res;
imx_dma_free(pcdev->dma_chan);
@@ -787,7 +783,7 @@ static int __exit mx1_camera_remove(struct platform_device *pdev)
clk_put(pcdev->clk);
- soc_camera_host_unregister(&mx1_soc_camera_host);
+ soc_camera_host_unregister(soc_host);
iounmap(pcdev->base);
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 2d0781118eb0..4d47eeb14452 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -87,7 +87,6 @@ struct mx3_camera_buffer {
* @soc_host: embedded soc_host object
*/
struct mx3_camera_dev {
- struct device *dev;
/*
* i.MX3x is only supposed to handle one camera on its Camera Sensor
* Interface. If anyone ever builds hardware to enable more than one
@@ -431,7 +430,7 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q,
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
- videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, mx3_cam->dev,
+ videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, ici->dev,
&mx3_cam->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_NONE,
@@ -599,7 +598,8 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
*flags |= SOCAM_DATAWIDTH_4;
break;
default:
- dev_info(mx3_cam->dev, "Unsupported bus width %d\n", buswidth);
+ dev_info(mx3_cam->soc_host.dev, "Unsupported bus width %d\n",
+ buswidth);
return -EINVAL;
}
@@ -614,7 +614,7 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
unsigned long bus_flags, camera_flags;
int ret = test_platform_param(mx3_cam, depth, &bus_flags);
- dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", depth, ret);
+ dev_dbg(ici->dev, "requested bus width %d bit: %d\n", depth, ret);
if (ret < 0)
return ret;
@@ -637,7 +637,7 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
if (!rq)
return false;
- pdata = rq->mx3_cam->dev->platform_data;
+ pdata = rq->mx3_cam->soc_host.dev->platform_data;
return rq->id == chan->chan_id &&
pdata->dma_dev == chan->device->dev;
@@ -697,7 +697,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
xlate->cam_fmt = icd->formats + idx;
xlate->buswidth = buswidth;
xlate++;
- dev_dbg(&ici->dev, "Providing format %s using %s\n",
+ dev_dbg(ici->dev, "Providing format %s using %s\n",
mx3_camera_formats[0].name,
icd->formats[idx].name);
}
@@ -709,7 +709,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
xlate->cam_fmt = icd->formats + idx;
xlate->buswidth = buswidth;
xlate++;
- dev_dbg(&ici->dev, "Providing format %s using %s\n",
+ dev_dbg(ici->dev, "Providing format %s using %s\n",
mx3_camera_formats[0].name,
icd->formats[idx].name);
}
@@ -722,7 +722,7 @@ passthrough:
xlate->cam_fmt = icd->formats + idx;
xlate->buswidth = buswidth;
xlate++;
- dev_dbg(&ici->dev,
+ dev_dbg(ici->dev,
"Providing format %s in pass-through mode\n",
icd->formats[idx].name);
}
@@ -829,7 +829,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
if (!xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+ dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
return -EINVAL;
}
@@ -866,7 +866,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (pixfmt && !xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+ dev_warn(ici->dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
@@ -933,11 +933,11 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (!xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+ dev_warn(ici->dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
- dev_dbg(&ici->dev, "requested bus width %d bit: %d\n",
+ dev_dbg(ici->dev, "requested bus width %d bit: %d\n",
icd->buswidth, ret);
if (ret < 0)
@@ -947,7 +947,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
if (!common_flags) {
- dev_dbg(&ici->dev, "no common flags: camera %lx, host %lx\n",
+ dev_dbg(ici->dev, "no common flags: camera %lx, host %lx\n",
camera_flags, bus_flags);
return -EINVAL;
}
@@ -1054,7 +1054,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
- dev_dbg(&ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw);
+ dev_dbg(ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw);
return 0;
}
@@ -1102,8 +1102,6 @@ static int mx3_camera_probe(struct platform_device *pdev)
goto eclkget;
}
- dev_set_drvdata(&pdev->dev, mx3_cam);
-
mx3_cam->pdata = pdev->dev.platform_data;
mx3_cam->platform_flags = mx3_cam->pdata->flags;
if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 |
@@ -1135,14 +1133,14 @@ static int mx3_camera_probe(struct platform_device *pdev)
}
mx3_cam->base = base;
- mx3_cam->dev = &pdev->dev;
soc_host = &mx3_cam->soc_host;
soc_host->drv_name = MX3_CAM_DRV_NAME;
soc_host->ops = &mx3_soc_camera_host_ops;
soc_host->priv = mx3_cam;
- soc_host->dev.parent = &pdev->dev;
+ soc_host->dev = &pdev->dev;
soc_host->nr = pdev->id;
+
err = soc_camera_host_register(soc_host);
if (err)
goto ecamhostreg;
@@ -1165,11 +1163,13 @@ egetres:
static int __devexit mx3_camera_remove(struct platform_device *pdev)
{
- struct mx3_camera_dev *mx3_cam = platform_get_drvdata(pdev);
+ struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
+ struct mx3_camera_dev *mx3_cam = container_of(soc_host,
+ struct mx3_camera_dev, soc_host);
clk_put(mx3_cam->clk);
- soc_camera_host_unregister(&mx3_cam->soc_host);
+ soc_camera_host_unregister(soc_host);
iounmap(mx3_cam->base);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 1cb6a260e8b0..76d42d92e603 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -284,6 +284,8 @@ static struct tda10048_config hauppauge_tda10048_config = {
.output_mode = TDA10048_PARALLEL_OUTPUT,
.fwbulkwritelen = TDA10048_BULKWRITE_50,
.inversion = TDA10048_INVERSION_ON,
+ .if_freq_khz = TDA10048_IF_4300,
+ .clk_freq_khz = TDA10048_CLK_16000,
};
static struct tda829x_config tda829x_no_probe = {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index add3395d3248..dcfae62b7f43 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -4824,9 +4824,6 @@ static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw,
struct v4l2_subdev *sd;
unsigned int tcnt = 0;
unsigned int ccnt;
- struct i2c_client *client;
- struct list_head *item;
- void *cd;
const char *p;
unsigned int id;
@@ -4848,42 +4845,6 @@ static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw,
ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
tcnt += ccnt;
- ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n");
- tcnt += ccnt;
-
- mutex_lock(&hdw->i2c_adap.clist_lock);
- list_for_each(item, &hdw->i2c_adap.clients) {
- client = list_entry(item, struct i2c_client, list);
- ccnt = scnprintf(buf + tcnt, acnt - tcnt,
- " %s: i2c=%02x", client->name, client->addr);
- tcnt += ccnt;
- cd = i2c_get_clientdata(client);
- v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
- if (cd == sd) {
- id = sd->grp_id;
- p = NULL;
- if (id < ARRAY_SIZE(module_names)) {
- p = module_names[id];
- }
- if (p) {
- ccnt = scnprintf(buf + tcnt,
- acnt - tcnt,
- " subdev=%s", p);
- tcnt += ccnt;
- } else {
- ccnt = scnprintf(buf + tcnt,
- acnt - tcnt,
- " subdev= id %u)",
- id);
- tcnt += ccnt;
- }
- break;
- }
- }
- ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
- tcnt += ccnt;
- }
- mutex_unlock(&hdw->i2c_adap.clist_lock);
return tcnt;
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 9af282f9e765..c3020e1752bf 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -559,6 +559,27 @@ static void do_i2c_scan(struct pvr2_hdw *hdw)
printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
}
+static void pvr2_i2c_register_ir(struct i2c_adapter *i2c_adap)
+{
+ struct i2c_board_info info;
+ /* The external IR receiver is at i2c address 0x34 (0x35 for
+ reads). Future Hauppauge cards will have an internal
+ receiver at 0x30 (0x31 for reads). In theory, both can be
+ fitted, and Hauppauge suggest an external overrides an
+ internal.
+
+ That's why we probe 0x1a (~0x34) first. CB
+ */
+ const unsigned short addr_list[] = {
+ 0x1a, 0x18, 0x64, 0x30,
+ I2C_CLIENT_END
+ };
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ i2c_new_probed_device(i2c_adap, &info, addr_list);
+}
+
void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
{
unsigned int idx;
@@ -606,6 +627,9 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
}
}
if (i2c_scan) do_i2c_scan(hdw);
+
+ /* Instantiate the IR receiver device, if present */
+ pvr2_i2c_register_ir(&hdw->i2c_adap);
}
void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index c639845460ff..2da5eef19b70 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -202,7 +202,7 @@ struct pxa_buffer {
};
struct pxa_camera_dev {
- struct device *dev;
+ struct soc_camera_host soc_host;
/* PXA27x is only supposed to handle one camera on its Quick Capture
* interface. If anyone ever builds hardware to enable more than
* one camera, they will have to modify this driver too */
@@ -261,7 +261,6 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
{
struct soc_camera_device *icd = vq->priv_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
- struct pxa_camera_dev *pcdev = ici->priv;
struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
int i;
@@ -278,7 +277,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
if (buf->dmas[i].sg_cpu)
- dma_free_coherent(pcdev->dev, buf->dmas[i].sg_size,
+ dma_free_coherent(ici->dev, buf->dmas[i].sg_size,
buf->dmas[i].sg_cpu,
buf->dmas[i].sg_dma);
buf->dmas[i].sg_cpu = NULL;
@@ -338,14 +337,14 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
int dma_len = 0, xfer_len = 0;
if (pxa_dma->sg_cpu)
- dma_free_coherent(pcdev->dev, pxa_dma->sg_size,
+ dma_free_coherent(pcdev->soc_host.dev, pxa_dma->sg_size,
pxa_dma->sg_cpu, pxa_dma->sg_dma);
sglen = calculate_dma_sglen(*sg_first, dma->sglen,
*sg_first_ofs, size);
pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
- pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->dev, pxa_dma->sg_size,
+ pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->soc_host.dev, pxa_dma->sg_size,
&pxa_dma->sg_dma, GFP_KERNEL);
if (!pxa_dma->sg_cpu)
return -ENOMEM;
@@ -353,7 +352,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
pxa_dma->sglen = sglen;
offset = *sg_first_ofs;
- dev_dbg(pcdev->dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
+ dev_dbg(pcdev->soc_host.dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
*sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
@@ -376,7 +375,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
pxa_dma->sg_cpu[i].ddadr =
pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
- dev_vdbg(pcdev->dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
+ dev_vdbg(pcdev->soc_host.dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
sg_dma_address(sg) + offset, xfer_len);
offset = 0;
@@ -488,7 +487,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
&sg, &next_ofs);
if (ret) {
- dev_err(pcdev->dev,
+ dev_err(pcdev->soc_host.dev,
"DMA initialization for Y/RGB failed\n");
goto fail;
}
@@ -498,7 +497,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
size_u, &sg, &next_ofs);
if (ret) {
- dev_err(pcdev->dev,
+ dev_err(pcdev->soc_host.dev,
"DMA initialization for U failed\n");
goto fail_u;
}
@@ -508,7 +507,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
size_v, &sg, &next_ofs);
if (ret) {
- dev_err(pcdev->dev,
+ dev_err(pcdev->soc_host.dev,
"DMA initialization for V failed\n");
goto fail_v;
}
@@ -522,10 +521,10 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
return 0;
fail_v:
- dma_free_coherent(pcdev->dev, buf->dmas[1].sg_size,
+ dma_free_coherent(pcdev->soc_host.dev, buf->dmas[1].sg_size,
buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
fail_u:
- dma_free_coherent(pcdev->dev, buf->dmas[0].sg_size,
+ dma_free_coherent(pcdev->soc_host.dev, buf->dmas[0].sg_size,
buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
fail:
free_buffer(vq, buf);
@@ -549,7 +548,7 @@ static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
active = pcdev->active;
for (i = 0; i < pcdev->channels; i++) {
- dev_dbg(pcdev->dev, "%s (channel=%d) ddadr=%08x\n", __func__,
+ dev_dbg(pcdev->soc_host.dev, "%s (channel=%d) ddadr=%08x\n", __func__,
i, active->dmas[i].sg_dma);
DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
@@ -561,7 +560,7 @@ static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
int i;
for (i = 0; i < pcdev->channels; i++) {
- dev_dbg(pcdev->dev, "%s (channel=%d)\n", __func__, i);
+ dev_dbg(pcdev->soc_host.dev, "%s (channel=%d)\n", __func__, i);
DCSR(pcdev->dma_chans[i]) = 0;
}
}
@@ -597,7 +596,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
{
unsigned long cicr0, cifr;
- dev_dbg(pcdev->dev, "%s\n", __func__);
+ dev_dbg(pcdev->soc_host.dev, "%s\n", __func__);
/* Reset the FIFOs */
cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
__raw_writel(cifr, pcdev->base + CIFR);
@@ -617,7 +616,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
__raw_writel(cicr0, pcdev->base + CICR0);
pcdev->active = NULL;
- dev_dbg(pcdev->dev, "%s\n", __func__);
+ dev_dbg(pcdev->soc_host.dev, "%s\n", __func__);
}
static void pxa_videobuf_queue(struct videobuf_queue *vq,
@@ -686,7 +685,7 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
do_gettimeofday(&vb->ts);
vb->field_count++;
wake_up(&vb->done);
- dev_dbg(pcdev->dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb);
+ dev_dbg(pcdev->soc_host.dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb);
if (list_empty(&pcdev->capture)) {
pxa_camera_stop_capture(pcdev);
@@ -722,7 +721,7 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
for (i = 0; i < pcdev->channels; i++)
if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
is_dma_stopped = 0;
- dev_dbg(pcdev->dev, "%s : top queued buffer=%p, dma_stopped=%d\n",
+ dev_dbg(pcdev->soc_host.dev, "%s : top queued buffer=%p, dma_stopped=%d\n",
__func__, pcdev->active, is_dma_stopped);
if (pcdev->active && is_dma_stopped)
pxa_camera_start_capture(pcdev);
@@ -747,12 +746,12 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
overrun |= CISR_IFO_1 | CISR_IFO_2;
if (status & DCSR_BUSERR) {
- dev_err(pcdev->dev, "DMA Bus Error IRQ!\n");
+ dev_err(pcdev->soc_host.dev, "DMA Bus Error IRQ!\n");
goto out;
}
if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
- dev_err(pcdev->dev, "Unknown DMA IRQ source, "
+ dev_err(pcdev->soc_host.dev, "Unknown DMA IRQ source, "
"status: 0x%08x\n", status);
goto out;
}
@@ -776,7 +775,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
buf = container_of(vb, struct pxa_buffer, vb);
WARN_ON(buf->inwork || list_empty(&vb->queue));
- dev_dbg(pcdev->dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
+ dev_dbg(pcdev->soc_host.dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
__func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
@@ -787,7 +786,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
*/
if (camera_status & overrun &&
!list_is_last(pcdev->capture.next, &pcdev->capture)) {
- dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n",
+ dev_dbg(pcdev->soc_host.dev, "FIFO overrun! CISR: %x\n",
camera_status);
pxa_camera_stop_capture(pcdev);
pxa_camera_start_capture(pcdev);
@@ -854,7 +853,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
/* mclk <= ciclk / 4 (27.4.2) */
if (mclk > lcdclk / 4) {
mclk = lcdclk / 4;
- dev_warn(pcdev->dev, "Limiting master clock to %lu\n", mclk);
+ dev_warn(pcdev->soc_host.dev, "Limiting master clock to %lu\n", mclk);
}
/* We verify mclk != 0, so if anyone breaks it, here comes their Oops */
@@ -864,7 +863,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
pcdev->mclk = lcdclk / (2 * (div + 1));
- dev_dbg(pcdev->dev, "LCD clock %luHz, target freq %luHz, "
+ dev_dbg(pcdev->soc_host.dev, "LCD clock %luHz, target freq %luHz, "
"divisor %u\n", lcdclk, mclk, div);
return div;
@@ -884,12 +883,12 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
struct pxacamera_platform_data *pdata = pcdev->pdata;
u32 cicr4 = 0;
- dev_dbg(pcdev->dev, "Registered platform device at %p data %p\n",
+ dev_dbg(pcdev->soc_host.dev, "Registered platform device at %p data %p\n",
pcdev, pdata);
if (pdata && pdata->init) {
- dev_dbg(pcdev->dev, "%s: Init gpios\n", __func__);
- pdata->init(pcdev->dev);
+ dev_dbg(pcdev->soc_host.dev, "%s: Init gpios\n", __func__);
+ pdata->init(pcdev->soc_host.dev);
}
/* disable all interrupts */
@@ -931,7 +930,7 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
struct videobuf_buffer *vb;
status = __raw_readl(pcdev->base + CISR);
- dev_dbg(pcdev->dev, "Camera interrupt status 0x%lx\n", status);
+ dev_dbg(pcdev->soc_host.dev, "Camera interrupt status 0x%lx\n", status);
if (!status)
return IRQ_NONE;
@@ -1259,7 +1258,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
xlate->cam_fmt = icd->formats + idx;
xlate->buswidth = buswidth;
xlate++;
- dev_dbg(&ici->dev, "Providing format %s using %s\n",
+ dev_dbg(ici->dev, "Providing format %s using %s\n",
pxa_camera_formats[0].name,
icd->formats[idx].name);
}
@@ -1274,7 +1273,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
xlate->cam_fmt = icd->formats + idx;
xlate->buswidth = buswidth;
xlate++;
- dev_dbg(&ici->dev, "Providing format %s packed\n",
+ dev_dbg(ici->dev, "Providing format %s packed\n",
icd->formats[idx].name);
}
break;
@@ -1286,7 +1285,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
xlate->cam_fmt = icd->formats + idx;
xlate->buswidth = icd->formats[idx].depth;
xlate++;
- dev_dbg(&ici->dev,
+ dev_dbg(ici->dev,
"Providing format %s in pass-through mode\n",
icd->formats[idx].name);
}
@@ -1315,11 +1314,11 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
icd->sense = NULL;
if (ret < 0) {
- dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n",
+ dev_warn(ici->dev, "Failed to crop to %ux%u@%u:%u\n",
rect->width, rect->height, rect->left, rect->top);
} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
if (sense.pixel_clock > sense.pixel_clock_max) {
- dev_err(&ici->dev,
+ dev_err(ici->dev,
"pixel clock %lu set by the camera too high!",
sense.pixel_clock);
return -EIO;
@@ -1347,7 +1346,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
if (!xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+ dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
return -EINVAL;
}
@@ -1363,11 +1362,11 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
icd->sense = NULL;
if (ret < 0) {
- dev_warn(&ici->dev, "Failed to configure for format %x\n",
+ dev_warn(ici->dev, "Failed to configure for format %x\n",
pix->pixelformat);
} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
if (sense.pixel_clock > sense.pixel_clock_max) {
- dev_err(&ici->dev,
+ dev_err(ici->dev,
"pixel clock %lu set by the camera too high!",
sense.pixel_clock);
return -EIO;
@@ -1395,7 +1394,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (!xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+ dev_warn(ici->dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
@@ -1552,12 +1551,6 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
.set_bus_param = pxa_camera_set_bus_param,
};
-/* Should be allocated dynamically too, but we have only one. */
-static struct soc_camera_host pxa_soc_camera_host = {
- .drv_name = PXA_CAM_DRV_NAME,
- .ops = &pxa_soc_camera_host_ops,
-};
-
static int pxa_camera_probe(struct platform_device *pdev)
{
struct pxa_camera_dev *pcdev;
@@ -1586,7 +1579,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
goto exit_kfree;
}
- dev_set_drvdata(&pdev->dev, pcdev);
pcdev->res = res;
pcdev->pdata = pdev->dev.platform_data;
@@ -1607,7 +1599,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
pcdev->mclk = 20000000;
}
- pcdev->dev = &pdev->dev;
pcdev->mclk_divisor = mclk_get_divisor(pcdev);
INIT_LIST_HEAD(&pcdev->capture);
@@ -1616,13 +1607,13 @@ static int pxa_camera_probe(struct platform_device *pdev)
/*
* Request the regions.
*/
- if (!request_mem_region(res->start, res->end - res->start + 1,
+ if (!request_mem_region(res->start, resource_size(res),
PXA_CAM_DRV_NAME)) {
err = -EBUSY;
goto exit_clk;
}
- base = ioremap(res->start, res->end - res->start + 1);
+ base = ioremap(res->start, resource_size(res));
if (!base) {
err = -ENOMEM;
goto exit_release;
@@ -1634,29 +1625,29 @@ static int pxa_camera_probe(struct platform_device *pdev)
err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH,
pxa_camera_dma_irq_y, pcdev);
if (err < 0) {
- dev_err(pcdev->dev, "Can't request DMA for Y\n");
+ dev_err(&pdev->dev, "Can't request DMA for Y\n");
goto exit_iounmap;
}
pcdev->dma_chans[0] = err;
- dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]);
+ dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]);
err = pxa_request_dma("CI_U", DMA_PRIO_HIGH,
pxa_camera_dma_irq_u, pcdev);
if (err < 0) {
- dev_err(pcdev->dev, "Can't request DMA for U\n");
+ dev_err(&pdev->dev, "Can't request DMA for U\n");
goto exit_free_dma_y;
}
pcdev->dma_chans[1] = err;
- dev_dbg(pcdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]);
+ dev_dbg(&pdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]);
err = pxa_request_dma("CI_V", DMA_PRIO_HIGH,
pxa_camera_dma_irq_v, pcdev);
if (err < 0) {
- dev_err(pcdev->dev, "Can't request DMA for V\n");
+ dev_err(&pdev->dev, "Can't request DMA for V\n");
goto exit_free_dma_u;
}
pcdev->dma_chans[2] = err;
- dev_dbg(pcdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
+ dev_dbg(&pdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
@@ -1666,14 +1657,17 @@ static int pxa_camera_probe(struct platform_device *pdev)
err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME,
pcdev);
if (err) {
- dev_err(pcdev->dev, "Camera interrupt register failed \n");
+ dev_err(&pdev->dev, "Camera interrupt register failed \n");
goto exit_free_dma;
}
- pxa_soc_camera_host.priv = pcdev;
- pxa_soc_camera_host.dev.parent = &pdev->dev;
- pxa_soc_camera_host.nr = pdev->id;
- err = soc_camera_host_register(&pxa_soc_camera_host);
+ pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME;
+ pcdev->soc_host.ops = &pxa_soc_camera_host_ops;
+ pcdev->soc_host.priv = pcdev;
+ pcdev->soc_host.dev = &pdev->dev;
+ pcdev->soc_host.nr = pdev->id;
+
+ err = soc_camera_host_register(&pcdev->soc_host);
if (err)
goto exit_free_irq;
@@ -1690,7 +1684,7 @@ exit_free_dma_y:
exit_iounmap:
iounmap(base);
exit_release:
- release_mem_region(res->start, res->end - res->start + 1);
+ release_mem_region(res->start, resource_size(res));
exit_clk:
clk_put(pcdev->clk);
exit_kfree:
@@ -1701,7 +1695,9 @@ exit:
static int __devexit pxa_camera_remove(struct platform_device *pdev)
{
- struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev);
+ struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
+ struct pxa_camera_dev *pcdev = container_of(soc_host,
+ struct pxa_camera_dev, soc_host);
struct resource *res;
clk_put(pcdev->clk);
@@ -1711,12 +1707,12 @@ static int __devexit pxa_camera_remove(struct platform_device *pdev)
pxa_free_dma(pcdev->dma_chans[2]);
free_irq(pcdev->irq, pcdev);
- soc_camera_host_unregister(&pxa_soc_camera_host);
+ soc_camera_host_unregister(soc_host);
iounmap(pcdev->base);
res = pcdev->res;
- release_mem_region(res->start, res->end - res->start + 1);
+ release_mem_region(res->start, resource_size(res));
kfree(pcdev);
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 30f4698be90a..90e1dbc1aa89 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -77,6 +77,8 @@
#define MAX_CHANNELS 4
#define S2255_MARKER_FRAME 0x2255DA4AL
#define S2255_MARKER_RESPONSE 0x2255ACACL
+#define S2255_RESPONSE_SETMODE 0x01
+#define S2255_RESPONSE_FW 0x10
#define S2255_USB_XFER_SIZE (16 * 1024)
#define MAX_CHANNELS 4
#define MAX_PIPE_BUFFERS 1
@@ -178,9 +180,6 @@ struct s2255_bufferi {
struct s2255_dmaqueue {
struct list_head active;
- /* thread for acquisition */
- struct task_struct *kthread;
- int frame;
struct s2255_dev *dev;
int channel;
};
@@ -210,16 +209,11 @@ struct s2255_pipeinfo {
u32 max_transfer_size;
u32 cur_transfer_size;
u8 *transfer_buffer;
- u32 transfer_flags;;
u32 state;
- u32 prev_state;
- u32 urb_size;
void *stream_urb;
void *dev; /* back pointer to s2255_dev struct*/
u32 err_count;
- u32 buf_index;
u32 idx;
- u32 priority_set;
};
struct s2255_fmt; /*forward declaration */
@@ -239,8 +233,6 @@ struct s2255_dev {
struct list_head s2255_devlist;
struct timer_list timer;
struct s2255_fw *fw_data;
- int board_num;
- int is_open;
struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS];
struct s2255_bufferi buffer[MAX_CHANNELS];
struct s2255_mode mode[MAX_CHANNELS];
@@ -297,9 +289,10 @@ struct s2255_fh {
int resources[MAX_CHANNELS];
};
-#define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */
+/* current cypress EEPROM firmware version */
+#define S2255_CUR_USB_FWVER ((3 << 8) | 6)
#define S2255_MAJOR_VERSION 1
-#define S2255_MINOR_VERSION 13
+#define S2255_MINOR_VERSION 14
#define S2255_RELEASE 0
#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
S2255_MINOR_VERSION, \
@@ -1818,7 +1811,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
INIT_LIST_HEAD(&dev->vidq[i].active);
dev->vidq[i].dev = dev;
dev->vidq[i].channel = i;
- dev->vidq[i].kthread = NULL;
/* register 4 video devices */
dev->vdev[i] = video_device_alloc();
memcpy(dev->vdev[i], &template, sizeof(struct video_device));
@@ -1839,7 +1831,9 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
return ret;
}
}
- printk(KERN_INFO "Sensoray 2255 V4L driver\n");
+ printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
+ S2255_MAJOR_VERSION,
+ S2255_MINOR_VERSION);
return ret;
}
@@ -1929,14 +1923,14 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
if (!(cc >= 0 && cc < MAX_CHANNELS))
break;
switch (pdword[2]) {
- case 0x01:
+ case S2255_RESPONSE_SETMODE:
/* check if channel valid */
/* set mode ready */
dev->setmode_ready[cc] = 1;
wake_up(&dev->wait_setmode[cc]);
dprintk(5, "setmode ready %d\n", cc);
break;
- case 0x10:
+ case S2255_RESPONSE_FW:
dev->chn_ready |= (1 << cc);
if ((dev->chn_ready & 0x0f) != 0x0f)
@@ -2172,10 +2166,15 @@ static int s2255_board_init(struct s2255_dev *dev)
/* query the firmware */
fw_ver = s2255_get_fx2fw(dev);
- printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver);
- if (fw_ver < CUR_USB_FWVER)
+ printk(KERN_INFO "2255 usb firmware version %d.%d\n",
+ (fw_ver >> 8) & 0xff,
+ fw_ver & 0xff);
+
+ if (fw_ver < S2255_CUR_USB_FWVER)
dev_err(&dev->udev->dev,
- "usb firmware not up to date %d\n", fw_ver);
+ "usb firmware not up to date %d.%d\n",
+ (fw_ver >> 8) & 0xff,
+ fw_ver & 0xff);
for (j = 0; j < MAX_CHANNELS; j++) {
dev->b_acquire[j] = 0;
@@ -2283,8 +2282,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
for (i = 0; i < MAX_PIPE_BUFFERS; i++) {
pipe_info->state = 1;
- pipe_info->buf_index = (u32) i;
- pipe_info->priority_set = 0;
+ pipe_info->err_count = 0;
pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!pipe_info->stream_urb) {
dev_err(&dev->udev->dev,
@@ -2298,7 +2296,6 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
pipe_info->cur_transfer_size,
read_pipe_completion, pipe_info);
- pipe_info->urb_size = sizeof(pipe_info->stream_urb);
dprintk(4, "submitting URB %p\n", pipe_info->stream_urb);
retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
if (retval) {
@@ -2403,8 +2400,6 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
if (pipe_info->state == 0)
continue;
pipe_info->state = 0;
- pipe_info->prev_state = 1;
-
}
}
@@ -2542,7 +2537,9 @@ static int s2255_probe(struct usb_interface *interface,
s2255_probe_v4l(dev);
usb_reset_device(dev->udev);
/* load 2255 board specific */
- s2255_board_init(dev);
+ retval = s2255_board_init(dev);
+ if (retval)
+ goto error;
dprintk(4, "before probe done %p\n", dev);
spin_lock_init(&dev->slock);
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index fdb19449d269..40e620284f56 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1669,6 +1669,39 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
},
},
+ [SAA7134_BOARD_AVERMEDIA_CARDBUS_501] = {
+ /* Oldrich Jedlicka <oldium.pro@seznam.cz> */
+ .name = "AVerMedia Cardbus TV/Radio (E501R)",
+ .audio_clock = 0x187de7,
+ .tuner_type = TUNER_ALPS_TSBE5_PAL,
+ .radio_type = TUNER_TEA5767,
+ .tuner_addr = 0x61,
+ .radio_addr = 0x60,
+ .tda9887_conf = TDA9887_PRESENT,
+ .gpiomask = 0x08000000,
+ .inputs = { {
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x08000000,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x08000000,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ .gpio = 0x08000000,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ .gpio = 0x00000000,
+ },
+ },
[SAA7134_BOARD_CINERGY400_CARDBUS] = {
.name = "Terratec Cinergy 400 mobile",
.audio_clock = 0x187de7,
@@ -4006,7 +4039,7 @@ struct saa7134_board saa7134_boards[] = {
[SAA7134_BOARD_BEHOLD_505FM] = {
/* Beholder Intl. Ltd. 2008 */
/*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 505 FM/RDS",
+ .name = "Beholder BeholdTV 505 FM",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
.radio_type = UNSET,
@@ -4019,6 +4052,40 @@ struct saa7134_board saa7134_boards[] = {
.vmux = 3,
.amux = LINE2,
.tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .mute = {
+ .name = name_mute,
+ .amux = LINE1,
+ },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_BEHOLD_505RDS] = {
+ /* Beholder Intl. Ltd. 2008 */
+ /*Dmitry Belimov <d.belimov@gmail.com> */
+ .name = "Beholder BeholdTV 505 RDS",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .gpiomask = 0x00008000,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = LINE2,
+ .tv = 1,
},{
.name = name_comp1,
.vmux = 1,
@@ -4040,7 +4107,7 @@ struct saa7134_board saa7134_boards[] = {
[SAA7134_BOARD_BEHOLD_507_9FM] = {
/* Beholder Intl. Ltd. 2008 */
/*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM",
+ .name = "Beholder BeholdTV 507 FM / BeholdTV 509 FM",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
.radio_type = UNSET,
@@ -4067,6 +4134,66 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
},
},
+ [SAA7134_BOARD_BEHOLD_507RDS_MK5] = {
+ /* Beholder Intl. Ltd. 2008 */
+ /*Dmitry Belimov <d.belimov@gmail.com> */
+ .name = "Beholder BeholdTV 507 RDS",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .gpiomask = 0x00008000,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_BEHOLD_507RDS_MK3] = {
+ /* Beholder Intl. Ltd. 2008 */
+ /*Dmitry Belimov <d.belimov@gmail.com> */
+ .name = "Beholder BeholdTV 507 RDS",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .gpiomask = 0x00008000,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
[SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = {
/* Beholder Intl. Ltd. 2008 */
/*Dmitry Belimov <d.belimov@gmail.com> */
@@ -4101,9 +4228,121 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x000A8000,
},
},
- [SAA7134_BOARD_BEHOLD_607_9FM] = {
+ [SAA7134_BOARD_BEHOLD_607FM_MK3] = {
+ /* Andrey Melnikoff <temnota@kmv.ru> */
+ .name = "Beholder BeholdTV 607 FM",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_BEHOLD_609FM_MK3] = {
+ /* Andrey Melnikoff <temnota@kmv.ru> */
+ .name = "Beholder BeholdTV 609 FM",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_BEHOLD_607FM_MK5] = {
+ /* Andrey Melnikoff <temnota@kmv.ru> */
+ .name = "Beholder BeholdTV 607 FM",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_BEHOLD_609FM_MK5] = {
+ /* Andrey Melnikoff <temnota@kmv.ru> */
+ .name = "Beholder BeholdTV 609 FM",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_BEHOLD_607RDS_MK3] = {
/* Andrey Melnikoff <temnota@kmv.ru> */
- .name = "Beholder BeholdTV 607 / BeholdTV 609",
+ .name = "Beholder BeholdTV 607 RDS",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
.radio_type = UNSET,
@@ -4115,6 +4354,90 @@ struct saa7134_board saa7134_boards[] = {
.vmux = 3,
.amux = TV,
.tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_BEHOLD_609RDS_MK3] = {
+ /* Andrey Melnikoff <temnota@kmv.ru> */
+ .name = "Beholder BeholdTV 609 RDS",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_BEHOLD_607RDS_MK5] = {
+ /* Andrey Melnikoff <temnota@kmv.ru> */
+ .name = "Beholder BeholdTV 607 RDS",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_BEHOLD_609RDS_MK5] = {
+ /* Andrey Melnikoff <temnota@kmv.ru> */
+ .name = "Beholder BeholdTV 609 RDS",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
},{
.name = name_comp1,
.vmux = 1,
@@ -4209,8 +4532,7 @@ struct saa7134_board saa7134_boards[] = {
/* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
.name = "Beholder BeholdTV M6 Extra",
.audio_clock = 0x00187de7,
- /* FIXME: Must be PHILIPS_FM1216ME_MK5*/
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
@@ -4753,6 +5075,44 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x01,
},
},
+ [SAA7134_BOARD_AVERMEDIA_STUDIO_507UA] = {
+ /* Andy Shevchenko <andy@smile.org.ua> */
+ .name = "Avermedia AVerTV Studio 507UA",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* Should be MK5 */
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .gpiomask = 0x03,
+ .inputs = { {
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x00,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x00,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ .gpio = 0x00,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ .gpio = 0x01,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = LINE1,
+ .gpio = 0x00,
+ },
+ },
};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -5027,6 +5387,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0xd6ee,
.driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS,
},{
+ /* AVerMedia CardBus */
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0xb7e9,
+ .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_501,
+ }, {
/* TransGear 3000TV */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
@@ -5441,6 +5808,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0xa11b,
+ .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507UA,
+ }, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x1043,
.subdevice = 0x4876,
@@ -5647,14 +6020,8 @@ struct pci_device_id saa7134_pci_tbl[] = {
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
.subvendor = 0x0000,
- .subdevice = 0x5051,
- .driver_data = SAA7134_BOARD_BEHOLD_505FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
.subdevice = 0x505B,
- .driver_data = SAA7134_BOARD_BEHOLD_505FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_505RDS,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
@@ -5666,13 +6033,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x0000,
.subdevice = 0x5071,
- .driver_data = SAA7134_BOARD_BEHOLD_507_9FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK3,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x0000,
.subdevice = 0x507B,
- .driver_data = SAA7134_BOARD_BEHOLD_507_9FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK5,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -5696,49 +6063,49 @@ struct pci_device_id saa7134_pci_tbl[] = {
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x5ace,
.subdevice = 0x6070,
- .driver_data = SAA7134_BOARD_BEHOLD_607_9FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK3,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x5ace,
.subdevice = 0x6071,
- .driver_data = SAA7134_BOARD_BEHOLD_607_9FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK5,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x5ace,
.subdevice = 0x6072,
- .driver_data = SAA7134_BOARD_BEHOLD_607_9FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK3,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x5ace,
.subdevice = 0x6073,
- .driver_data = SAA7134_BOARD_BEHOLD_607_9FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK5,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5ace,
.subdevice = 0x6090,
- .driver_data = SAA7134_BOARD_BEHOLD_607_9FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK3,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5ace,
.subdevice = 0x6091,
- .driver_data = SAA7134_BOARD_BEHOLD_607_9FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK5,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5ace,
.subdevice = 0x6092,
- .driver_data = SAA7134_BOARD_BEHOLD_607_9FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK3,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5ace,
.subdevice = 0x6093,
- .driver_data = SAA7134_BOARD_BEHOLD_607_9FM,
+ .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK5,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -6142,7 +6509,10 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_BEHOLD_407FM:
case SAA7134_BOARD_BEHOLD_409:
case SAA7134_BOARD_BEHOLD_505FM:
+ case SAA7134_BOARD_BEHOLD_505RDS:
case SAA7134_BOARD_BEHOLD_507_9FM:
+ case SAA7134_BOARD_BEHOLD_507RDS_MK3:
+ case SAA7134_BOARD_BEHOLD_507RDS_MK5:
case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
case SAA7134_BOARD_REAL_ANGEL_220:
case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
@@ -6196,6 +6566,16 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
msleep(10);
break;
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
+ /* power-down tuner chip */
+ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08400000, 0x08400000);
+ saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0);
+ msleep(10);
+ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08400000, 0x08400000);
+ saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0x08400000);
+ msleep(10);
+ dev->has_remote = SAA7134_REMOTE_I2C;
+ break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
saa7134_set_gpio(dev, 23, 0);
msleep(10);
@@ -6253,7 +6633,14 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_UPMOST_PURPLE_TV:
case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
- case SAA7134_BOARD_BEHOLD_607_9FM:
+ case SAA7134_BOARD_BEHOLD_607FM_MK3:
+ case SAA7134_BOARD_BEHOLD_607FM_MK5:
+ case SAA7134_BOARD_BEHOLD_609FM_MK3:
+ case SAA7134_BOARD_BEHOLD_609FM_MK5:
+ case SAA7134_BOARD_BEHOLD_607RDS_MK3:
+ case SAA7134_BOARD_BEHOLD_607RDS_MK5:
+ case SAA7134_BOARD_BEHOLD_609RDS_MK3:
+ case SAA7134_BOARD_BEHOLD_609RDS_MK5:
case SAA7134_BOARD_BEHOLD_M6:
case SAA7134_BOARD_BEHOLD_M63:
case SAA7134_BOARD_BEHOLD_M6_EXTRA:
@@ -6635,6 +7022,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
{
struct v4l2_priv_tun_config tea5767_cfg;
struct tea5767_ctrl ctl;
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index f3e285aa2fb4..a8a355e28799 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -321,33 +321,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL;
}
-static int attach_inform(struct i2c_client *client)
-{
- struct saa7134_dev *dev = client->adapter->algo_data;
-
- d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
-
- /* Am I an i2c remote control? */
-
- switch (client->addr) {
- case 0x7a:
- case 0x47:
- case 0x71:
- case 0x2d:
- case 0x30:
- {
- struct IR_i2c *ir = i2c_get_clientdata(client);
- d1printk("%s i2c IR detected (%s).\n",
- client->driver->driver.name, ir->phys);
- saa7134_set_i2c_ir(dev,ir);
- break;
- }
- }
-
- return 0;
-}
-
static struct i2c_algorithm saa7134_algo = {
.master_xfer = saa7134_i2c_xfer,
.functionality = functionality,
@@ -358,7 +331,6 @@ static struct i2c_adapter saa7134_adap_template = {
.name = "saa7134",
.id = I2C_HW_SAA7134,
.algo = &saa7134_algo,
- .client_register = attach_inform,
};
static struct i2c_client saa7134_client_template = {
@@ -433,6 +405,9 @@ int saa7134_i2c_register(struct saa7134_dev *dev)
saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
if (i2c_scan)
do_i2c_scan(dev->name,&dev->i2c_client);
+
+ /* Instantiate the IR receiver device, if present */
+ saa7134_probe_i2c_ir(dev);
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 8a106d36e723..02705c9879fc 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of "
#define dprintk(fmt, arg...) if (ir_debug) \
printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
#define i2cdprintk(fmt, arg...) if (ir_debug) \
- printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg)
/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */
static int saa7134_rc5_irq(struct saa7134_dev *dev);
@@ -134,10 +134,10 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
int gpio;
/* <dev> is needed to access GPIO. Used by the saa_readl macro. */
- struct saa7134_dev *dev = ir->c.adapter->algo_data;
+ struct saa7134_dev *dev = ir->c->adapter->algo_data;
if (dev == NULL) {
dprintk("get_key_msi_tvanywhere_plus: "
- "gir->c.adapter->algo_data is NULL!\n");
+ "gir->c->adapter->algo_data is NULL!\n");
return -EIO;
}
@@ -156,7 +156,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
/* GPIO says there is a button press. Get it. */
- if (1 != i2c_master_recv(&ir->c, &b, 1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
i2cdprintk("read error\n");
return -EIO;
}
@@ -179,7 +179,7 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char b;
/* poll IR chip */
- if (1 != i2c_master_recv(&ir->c,&b,1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
i2cdprintk("read error\n");
return -EIO;
}
@@ -202,7 +202,7 @@ static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char buf[5], cod4, code3, code4;
/* poll IR chip */
- if (5 != i2c_master_recv(&ir->c,buf,5))
+ if (5 != i2c_master_recv(ir->c, buf, 5))
return -EIO;
cod4 = buf[4];
@@ -224,7 +224,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char data[12];
u32 gpio;
- struct saa7134_dev *dev = ir->c.adapter->algo_data;
+ struct saa7134_dev *dev = ir->c->adapter->algo_data;
/* rising SAA7134_GPIO_GPRESCAN reads the status */
saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
@@ -235,9 +235,9 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if (0x400000 & ~gpio)
return 0; /* No button press */
- ir->c.addr = 0x5a >> 1;
+ ir->c->addr = 0x5a >> 1;
- if (12 != i2c_master_recv(&ir->c, data, 12)) {
+ if (12 != i2c_master_recv(ir->c, data, 12)) {
i2cdprintk("read error\n");
return -EIO;
}
@@ -267,7 +267,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
unsigned int start = 0,parity = 0,code = 0;
/* poll IR chip */
- if (4 != i2c_master_recv(&ir->c, b, 4)) {
+ if (4 != i2c_master_recv(ir->c, b, 4)) {
i2cdprintk("read error\n");
return -EIO;
}
@@ -447,6 +447,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
+ case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA:
case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
case SAA7134_BOARD_AVERMEDIA_M102:
case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
@@ -506,7 +507,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_BEHOLD_407FM:
case SAA7134_BOARD_BEHOLD_409:
case SAA7134_BOARD_BEHOLD_505FM:
+ case SAA7134_BOARD_BEHOLD_505RDS:
case SAA7134_BOARD_BEHOLD_507_9FM:
+ case SAA7134_BOARD_BEHOLD_507RDS_MK3:
+ case SAA7134_BOARD_BEHOLD_507RDS_MK5:
ir_codes = ir_codes_manli;
mask_keycode = 0x003f00;
mask_keyup = 0x004000;
@@ -678,55 +682,100 @@ void saa7134_input_fini(struct saa7134_dev *dev)
dev->remote = NULL;
}
-void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
+void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
{
+ struct i2c_board_info info;
+ struct IR_i2c_init_data init_data;
+ const unsigned short addr_list[] = {
+ 0x7a, 0x47, 0x71, 0x2d,
+ I2C_CLIENT_END
+ };
+
+ struct i2c_msg msg_msi = {
+ .addr = 0x50,
+ .flags = I2C_M_RD,
+ .len = 0,
+ .buf = NULL,
+ };
+
+ int rc;
+
if (disable_ir) {
- dprintk("Found supported i2c remote, but IR has been disabled\n");
- ir->get_key=NULL;
+ dprintk("IR has been disabled, not probing for i2c remote\n");
return;
}
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+
switch (dev->board) {
case SAA7134_BOARD_PINNACLE_PCTV_110i:
case SAA7134_BOARD_PINNACLE_PCTV_310i:
- snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
+ init_data.name = "Pinnacle PCTV";
if (pinnacle_remote == 0) {
- ir->get_key = get_key_pinnacle_color;
- ir->ir_codes = ir_codes_pinnacle_color;
+ init_data.get_key = get_key_pinnacle_color;
+ init_data.ir_codes = ir_codes_pinnacle_color;
} else {
- ir->get_key = get_key_pinnacle_grey;
- ir->ir_codes = ir_codes_pinnacle_grey;
+ init_data.get_key = get_key_pinnacle_grey;
+ init_data.ir_codes = ir_codes_pinnacle_grey;
}
break;
case SAA7134_BOARD_UPMOST_PURPLE_TV:
- snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
- ir->get_key = get_key_purpletv;
- ir->ir_codes = ir_codes_purpletv;
+ init_data.name = "Purple TV";
+ init_data.get_key = get_key_purpletv;
+ init_data.ir_codes = ir_codes_purpletv;
break;
case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
- snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus");
- ir->get_key = get_key_msi_tvanywhere_plus;
- ir->ir_codes = ir_codes_msi_tvanywhere_plus;
+ init_data.name = "MSI TV@nywhere Plus";
+ init_data.get_key = get_key_msi_tvanywhere_plus;
+ init_data.ir_codes = ir_codes_msi_tvanywhere_plus;
+ info.addr = 0x30;
+ /* MSI TV@nywhere Plus controller doesn't seem to
+ respond to probes unless we read something from
+ an existing device. Weird...
+ REVISIT: might no longer be needed */
+ rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
+ dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
+ msg_msi.addr, dev->i2c_adap.name,
+ (1 == rc) ? "yes" : "no");
break;
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
- snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110");
- ir->get_key = get_key_hvr1110;
- ir->ir_codes = ir_codes_hauppauge_new;
- break;
- case SAA7134_BOARD_BEHOLD_607_9FM:
+ init_data.name = "HVR 1110";
+ init_data.get_key = get_key_hvr1110;
+ init_data.ir_codes = ir_codes_hauppauge_new;
+ break;
+ case SAA7134_BOARD_BEHOLD_607FM_MK3:
+ case SAA7134_BOARD_BEHOLD_607FM_MK5:
+ case SAA7134_BOARD_BEHOLD_609FM_MK3:
+ case SAA7134_BOARD_BEHOLD_609FM_MK5:
+ case SAA7134_BOARD_BEHOLD_607RDS_MK3:
+ case SAA7134_BOARD_BEHOLD_607RDS_MK5:
+ case SAA7134_BOARD_BEHOLD_609RDS_MK3:
+ case SAA7134_BOARD_BEHOLD_609RDS_MK5:
case SAA7134_BOARD_BEHOLD_M6:
case SAA7134_BOARD_BEHOLD_M63:
case SAA7134_BOARD_BEHOLD_M6_EXTRA:
case SAA7134_BOARD_BEHOLD_H6:
- snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV");
- ir->get_key = get_key_beholdm6xx;
- ir->ir_codes = ir_codes_behold;
+ init_data.name = "BeholdTV";
+ init_data.get_key = get_key_beholdm6xx;
+ init_data.ir_codes = ir_codes_behold;
break;
- default:
- dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ info.addr = 0x40;
break;
}
+ if (init_data.name)
+ info.platform_data = &init_data;
+ /* No need to probe if address is known */
+ if (info.addr) {
+ i2c_new_device(&dev->i2c_adap, &info);
+ return;
+ }
+
+ /* Address not known, fallback to probing */
+ i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
}
static int saa7134_rc5_irq(struct saa7134_dev *dev)
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 0cbaf90d4874..87b9cd996178 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -252,7 +252,7 @@ struct saa7134_format {
#define SAA7134_BOARD_BEHOLD_505FM 126
#define SAA7134_BOARD_BEHOLD_507_9FM 127
#define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128
-#define SAA7134_BOARD_BEHOLD_607_9FM 129
+#define SAA7134_BOARD_BEHOLD_607FM_MK3 129
#define SAA7134_BOARD_BEHOLD_M6 130
#define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131
#define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132
@@ -280,6 +280,18 @@ struct saa7134_format {
#define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154
#define SAA7134_BOARD_HAUPPAUGE_HVR1120 155
#define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156
+#define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
+#define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158
+#define SAA7134_BOARD_BEHOLD_505RDS 159
+#define SAA7134_BOARD_BEHOLD_507RDS_MK3 160
+#define SAA7134_BOARD_BEHOLD_507RDS_MK5 161
+#define SAA7134_BOARD_BEHOLD_607FM_MK5 162
+#define SAA7134_BOARD_BEHOLD_609FM_MK3 163
+#define SAA7134_BOARD_BEHOLD_609FM_MK5 164
+#define SAA7134_BOARD_BEHOLD_607RDS_MK3 165
+#define SAA7134_BOARD_BEHOLD_607RDS_MK5 166
+#define SAA7134_BOARD_BEHOLD_609RDS_MK3 167
+#define SAA7134_BOARD_BEHOLD_609RDS_MK5 168
#define SAA7134_MAXBOARDS 32
#define SAA7134_INPUT_MAX 8
@@ -786,7 +798,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
int saa7134_input_init1(struct saa7134_dev *dev);
void saa7134_input_fini(struct saa7134_dev *dev);
void saa7134_input_irq(struct saa7134_dev *dev);
-void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
+void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
void saa7134_ir_stop(struct saa7134_dev *dev);
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index b5e37a530c62..d369e8409ab8 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -81,7 +81,6 @@ struct sh_mobile_ceu_buffer {
};
struct sh_mobile_ceu_dev {
- struct device *dev;
struct soc_camera_host ici;
struct soc_camera_device *icd;
@@ -617,7 +616,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
xlate->cam_fmt = icd->formats + idx;
xlate->buswidth = icd->formats[idx].depth;
xlate++;
- dev_dbg(&ici->dev, "Providing format %s using %s\n",
+ dev_dbg(ici->dev, "Providing format %s using %s\n",
sh_mobile_ceu_formats[k].name,
icd->formats[idx].name);
}
@@ -630,7 +629,7 @@ add_single_format:
xlate->cam_fmt = icd->formats + idx;
xlate->buswidth = icd->formats[idx].depth;
xlate++;
- dev_dbg(&ici->dev,
+ dev_dbg(ici->dev,
"Providing format %s in pass-through mode\n",
icd->formats[idx].name);
}
@@ -657,7 +656,7 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (!xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+ dev_warn(ici->dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
@@ -684,7 +683,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (!xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+ dev_warn(ici->dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
@@ -782,7 +781,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
videobuf_queue_dma_contig_init(q,
&sh_mobile_ceu_videobuf_ops,
- &ici->dev, &pcdev->lock,
+ ici->dev, &pcdev->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
pcdev->is_interlaced ?
V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
@@ -829,7 +828,6 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
goto exit;
}
- platform_set_drvdata(pdev, pcdev);
INIT_LIST_HEAD(&pcdev->capture);
spin_lock_init(&pcdev->lock);
@@ -840,7 +838,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
goto exit_kfree;
}
- base = ioremap_nocache(res->start, res->end - res->start + 1);
+ base = ioremap_nocache(res->start, resource_size(res));
if (!base) {
err = -ENXIO;
dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n");
@@ -850,13 +848,12 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
pcdev->irq = irq;
pcdev->base = base;
pcdev->video_limit = 0; /* only enabled if second resource exists */
- pcdev->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res) {
err = dma_declare_coherent_memory(&pdev->dev, res->start,
res->start,
- (res->end - res->start) + 1,
+ resource_size(res),
DMA_MEMORY_MAP |
DMA_MEMORY_EXCLUSIVE);
if (!err) {
@@ -865,7 +862,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
goto exit_iounmap;
}
- pcdev->video_limit = (res->end - res->start) + 1;
+ pcdev->video_limit = resource_size(res);
}
/* request irq */
@@ -885,7 +882,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
}
pcdev->ici.priv = pcdev;
- pcdev->ici.dev.parent = &pdev->dev;
+ pcdev->ici.dev = &pdev->dev;
pcdev->ici.nr = pdev->id;
pcdev->ici.drv_name = dev_name(&pdev->dev);
pcdev->ici.ops = &sh_mobile_ceu_host_ops;
@@ -913,9 +910,11 @@ exit:
static int sh_mobile_ceu_remove(struct platform_device *pdev)
{
- struct sh_mobile_ceu_dev *pcdev = platform_get_drvdata(pdev);
+ struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
+ struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
+ struct sh_mobile_ceu_dev, ici);
- soc_camera_host_unregister(&pcdev->ici);
+ soc_camera_host_unregister(soc_host);
clk_put(pcdev->clk);
free_irq(pcdev->irq, pcdev);
if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 0e890cc23377..2014e9e32b35 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -16,19 +16,21 @@
* published by the Free Software Foundation.
*/
-#include <linux/module.h>
-#include <linux/init.h>
#include <linux/device.h>
-#include <linux/list.h>
#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/platform_device.h>
#include <linux/vmalloc.h>
+#include <media/soc_camera.h>
#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
#include <media/videobuf-core.h>
-#include <media/soc_camera.h>
/* Default to VGA resolution */
#define DEFAULT_WIDTH 640
@@ -279,7 +281,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
return ret;
} else if (!icd->current_fmt ||
icd->current_fmt->fourcc != pix->pixelformat) {
- dev_err(&ici->dev,
+ dev_err(ici->dev,
"Host driver hasn't set up current format correctly!\n");
return -EINVAL;
}
@@ -794,7 +796,7 @@ static void scan_add_host(struct soc_camera_host *ici)
list_for_each_entry(icd, &devices, list) {
if (icd->iface == ici->nr) {
- icd->dev.parent = &ici->dev;
+ icd->dev.parent = ici->dev;
device_register_link(icd);
}
}
@@ -818,7 +820,7 @@ static int scan_add_device(struct soc_camera_device *icd)
list_for_each_entry(ici, &hosts, list) {
if (icd->iface == ici->nr) {
ret = 1;
- icd->dev.parent = &ici->dev;
+ icd->dev.parent = ici->dev;
break;
}
}
@@ -952,7 +954,6 @@ static void dummy_release(struct device *dev)
int soc_camera_host_register(struct soc_camera_host *ici)
{
- int ret;
struct soc_camera_host *ix;
if (!ici || !ici->ops ||
@@ -965,12 +966,10 @@ int soc_camera_host_register(struct soc_camera_host *ici)
!ici->ops->reqbufs ||
!ici->ops->add ||
!ici->ops->remove ||
- !ici->ops->poll)
+ !ici->ops->poll ||
+ !ici->dev)
return -EINVAL;
- /* Number might be equal to the platform device ID */
- dev_set_name(&ici->dev, "camera_host%d", ici->nr);
-
mutex_lock(&list_lock);
list_for_each_entry(ix, &hosts, list) {
if (ix->nr == ici->nr) {
@@ -979,26 +978,14 @@ int soc_camera_host_register(struct soc_camera_host *ici)
}
}
+ dev_set_drvdata(ici->dev, ici);
+
list_add_tail(&ici->list, &hosts);
mutex_unlock(&list_lock);
- ici->dev.release = dummy_release;
-
- ret = device_register(&ici->dev);
-
- if (ret)
- goto edevr;
-
scan_add_host(ici);
return 0;
-
-edevr:
- mutex_lock(&list_lock);
- list_del(&ici->list);
- mutex_unlock(&list_lock);
-
- return ret;
}
EXPORT_SYMBOL(soc_camera_host_register);
@@ -1012,7 +999,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
list_del(&ici->list);
list_for_each_entry(icd, &devices, list) {
- if (icd->dev.parent == &ici->dev) {
+ if (icd->dev.parent == ici->dev) {
device_unregister(&icd->dev);
/* Not before device_unregister(), .remove
* needs parent to call ici->ops->remove() */
@@ -1023,7 +1010,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
mutex_unlock(&list_lock);
- device_unregister(&ici->dev);
+ dev_set_drvdata(ici->dev, NULL);
}
EXPORT_SYMBOL(soc_camera_host_unregister);
@@ -1130,7 +1117,7 @@ int soc_camera_video_start(struct soc_camera_device *icd)
vdev = video_device_alloc();
if (!vdev)
goto evidallocd;
- dev_dbg(&ici->dev, "Allocated video_device %p\n", vdev);
+ dev_dbg(ici->dev, "Allocated video_device %p\n", vdev);
strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
@@ -1174,6 +1161,57 @@ void soc_camera_video_stop(struct soc_camera_device *icd)
}
EXPORT_SYMBOL(soc_camera_video_stop);
+static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
+{
+ struct soc_camera_link *icl = pdev->dev.platform_data;
+ struct i2c_adapter *adap;
+ struct i2c_client *client;
+
+ if (!icl)
+ return -EINVAL;
+
+ adap = i2c_get_adapter(icl->i2c_adapter_id);
+ if (!adap) {
+ dev_warn(&pdev->dev, "Cannot get adapter #%d. No driver?\n",
+ icl->i2c_adapter_id);
+ /* -ENODEV and -ENXIO do not produce an error on probe()... */
+ return -ENOENT;
+ }
+
+ icl->board_info->platform_data = icl;
+ client = i2c_new_device(adap, icl->board_info);
+ if (!client) {
+ i2c_put_adapter(adap);
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, client);
+
+ return 0;
+}
+
+static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
+{
+ struct i2c_client *client = platform_get_drvdata(pdev);
+
+ if (!client)
+ return -ENODEV;
+
+ i2c_unregister_device(client);
+ i2c_put_adapter(client->adapter);
+
+ return 0;
+}
+
+static struct platform_driver __refdata soc_camera_pdrv = {
+ .probe = soc_camera_pdrv_probe,
+ .remove = __exit_p(soc_camera_pdrv_remove),
+ .driver = {
+ .name = "soc-camera-pdrv",
+ .owner = THIS_MODULE,
+ },
+};
+
static int __init soc_camera_init(void)
{
int ret = bus_register(&soc_camera_bus_type);
@@ -1183,8 +1221,14 @@ static int __init soc_camera_init(void)
if (ret)
goto edrvr;
+ ret = platform_driver_register(&soc_camera_pdrv);
+ if (ret)
+ goto epdr;
+
return 0;
+epdr:
+ driver_unregister(&ic_drv);
edrvr:
bus_unregister(&soc_camera_bus_type);
return ret;
@@ -1192,6 +1236,7 @@ edrvr:
static void __exit soc_camera_exit(void)
{
+ platform_driver_unregister(&soc_camera_pdrv);
driver_unregister(&ic_drv);
bus_unregister(&soc_camera_bus_type);
}
@@ -1202,3 +1247,4 @@ module_exit(soc_camera_exit);
MODULE_DESCRIPTION("Image capture bus driver");
MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:soc-camera-pdrv");
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 005f8a468031..80f1cee23fa5 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -20,20 +20,6 @@
* loudness - set between 0 and 15 for varying degrees of loudness effect
*
* maxvol - set maximium volume to +20db (1), default is 0db(0)
- *
- *
- * Revision: 0.7 - maxvol module parm to set maximium volume 0db or +20db
- * store if muted so we can return it
- * change balance only if flaged to
- * Revision: 0.6 - added tone controls
- * Revision: 0.5 - Fixed odd balance problem
- * Revision: 0.4 - added muting
- * Revision: 0.3 - Fixed silly reversed volume controls. :)
- * Revision: 0.2 - Cleaned up #defines
- * fixed volume control
- * Added I2C_DRIVERID_TDA7432
- * added loudness insmod control
- * Revision: 0.1 - initial version
*/
#include <linux/module.h>
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 78c377a399cb..1dac524fc8f1 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -309,32 +309,6 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
}
}
-static void tuner_i2c_address_check(struct tuner *t)
-{
- if ((t->type == UNSET || t->type == TUNER_ABSENT) ||
- ((t->i2c->addr < 0x64) || (t->i2c->addr > 0x6f)))
- return;
-
- /* We already know that the XC5000 can only be located at
- * i2c address 0x61, 0x62, 0x63 or 0x64 */
- if ((t->type == TUNER_XC5000) &&
- ((t->i2c->addr <= 0x64)) && (t->i2c->addr >= 0x61))
- return;
-
- tuner_warn("====================== WARNING! ======================\n");
- tuner_warn("Support for tuners in i2c address range 0x64 thru 0x6f\n");
- tuner_warn("will soon be dropped. This message indicates that your\n");
- tuner_warn("hardware has a %s tuner at i2c address 0x%02x.\n",
- t->name, t->i2c->addr);
- tuner_warn("To ensure continued support for your device, please\n");
- tuner_warn("send a copy of this message, along with full dmesg\n");
- tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n");
- tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n");
- tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n",
- t->i2c->adapter->name, t->i2c->addr, t->type, t->name);
- tuner_warn("====================== WARNING! ======================\n");
-}
-
static struct xc5000_config xc5000_cfg;
static void set_type(struct i2c_client *c, unsigned int type,
@@ -490,7 +464,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
c->adapter->name, c->driver->driver.name, c->addr << 1, type,
t->mode_mask);
- tuner_i2c_address_check(t);
return;
attach_failed:
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 399412d7f020..507dc85646b2 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1726,14 +1726,17 @@ static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
static int __uvc_resume(struct usb_interface *intf, int reset)
{
struct uvc_device *dev = usb_get_intfdata(intf);
- int ret;
uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n",
intf->cur_altsetting->desc.bInterfaceNumber);
if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) {
- if (reset && (ret = uvc_ctrl_resume_device(dev)) < 0)
- return ret;
+ if (reset) {
+ int ret = uvc_ctrl_resume_device(dev);
+
+ if (ret < 0)
+ return ret;
+ }
return uvc_status_resume(dev);
}
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 2a80caa54fb4..ad7e64ff3add 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -46,6 +46,8 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
struct uvc_menu_info *menu_info;
struct uvc_control_mapping *mapping;
struct uvc_control *ctrl;
+ u32 index = query_menu->index;
+ u32 id = query_menu->id;
ctrl = uvc_find_control(video, query_menu->id, &mapping);
if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
@@ -54,6 +56,10 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
if (query_menu->index >= mapping->menu_count)
return -EINVAL;
+ memset(query_menu, 0, sizeof(*query_menu));
+ query_menu->id = id;
+ query_menu->index = index;
+
menu_info = &mapping->menu_info[query_menu->index];
strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
return 0;
@@ -648,7 +654,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_S_INPUT:
{
- u8 input = *(u32 *)arg + 1;
+ u32 input = *(u32 *)arg + 1;
if ((ret = uvc_acquire_privileges(handle)) < 0)
return ret;
@@ -660,7 +666,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
break;
}
- if (input > video->selector->selector.bNrInPins)
+ if (input == 0 || input > video->selector->selector.bNrInPins)
return -EINVAL;
return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id,
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index a95e17329c5b..6ce974d7362f 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -742,7 +742,7 @@ static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
/* Buffers are already allocated, bail out. */
if (video->urb_size)
- return 0;
+ return video->urb_size / psize;
/* Compute the number of packets. Bulk endpoints might transfer UVC
* payloads accross multiple URBs.
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index f576ef66b807..f96475626da7 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -746,6 +746,7 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
const struct v4l2_subdev_ops *ops)
{
v4l2_subdev_init(sd, ops);
+ sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
/* the owner is the same as the i2c_client's driver owner */
sd->owner = client->driver->driver.owner;
/* i2c_client and v4l2_subdev point to one another */
@@ -897,8 +898,7 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
};
static const unsigned short tv_addrs[] = {
0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x60, 0x61, 0x62, 0x63, 0x64,
I2C_CLIENT_END
};
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 94aa485ade52..e1520bc84f71 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -49,6 +49,22 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
}
EXPORT_SYMBOL_GPL(v4l2_device_register);
+int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
+ atomic_t *instance)
+{
+ int num = atomic_inc_return(instance) - 1;
+ int len = strlen(basename);
+
+ if (basename[len - 1] >= '0' && basename[len - 1] <= '9')
+ snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
+ "%s-%d", basename, num);
+ else
+ snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
+ "%s%d", basename, num);
+ return num;
+}
+EXPORT_SYMBOL_GPL(v4l2_device_set_name);
+
void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
{
if (v4l2_dev->dev) {
@@ -67,8 +83,19 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
v4l2_device_disconnect(v4l2_dev);
/* Unregister subdevs */
- list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list)
+ list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) {
v4l2_device_unregister_subdev(sd);
+ if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) {
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ /* We need to unregister the i2c client explicitly.
+ We cannot rely on i2c_del_adapter to always
+ unregister clients for us, since if the i2c bus
+ is a platform bus, then it is never deleted. */
+ if (client)
+ i2c_unregister_device(client);
+ }
+ }
}
EXPORT_SYMBOL_GPL(v4l2_device_unregister);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 88f10d6cbc92..be64a502ea27 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -42,6 +42,12 @@
printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
} while (0)
+/* Zero out the end of the struct pointed to by p. Everthing after, but
+ * not including, the specified field is cleared. */
+#define CLEAR_AFTER_FIELD(p, field) \
+ memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
+ 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
+
struct std_descr {
v4l2_std_id std;
const char *descr;
@@ -544,39 +550,39 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (ops->vidioc_try_fmt_vid_cap)
+ if (ops->vidioc_g_fmt_vid_cap)
return 0;
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (ops->vidioc_try_fmt_vid_overlay)
+ if (ops->vidioc_g_fmt_vid_overlay)
return 0;
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (ops->vidioc_try_fmt_vid_out)
+ if (ops->vidioc_g_fmt_vid_out)
return 0;
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (ops->vidioc_try_fmt_vid_out_overlay)
+ if (ops->vidioc_g_fmt_vid_out_overlay)
return 0;
break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (ops->vidioc_try_fmt_vbi_cap)
+ if (ops->vidioc_g_fmt_vbi_cap)
return 0;
break;
case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (ops->vidioc_try_fmt_vbi_out)
+ if (ops->vidioc_g_fmt_vbi_out)
return 0;
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (ops->vidioc_try_fmt_sliced_vbi_cap)
+ if (ops->vidioc_g_fmt_sliced_vbi_cap)
return 0;
break;
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (ops->vidioc_try_fmt_sliced_vbi_out)
+ if (ops->vidioc_g_fmt_sliced_vbi_out)
return 0;
break;
case V4L2_BUF_TYPE_PRIVATE:
- if (ops->vidioc_try_fmt_type_private)
+ if (ops->vidioc_g_fmt_type_private)
return 0;
break;
}
@@ -782,44 +788,53 @@ static long __video_do_ioctl(struct file *file,
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ CLEAR_AFTER_FIELD(f, fmt.pix);
v4l_print_pix_fmt(vfd, &f->fmt.pix);
if (ops->vidioc_s_fmt_vid_cap)
ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ CLEAR_AFTER_FIELD(f, fmt.win);
if (ops->vidioc_s_fmt_vid_overlay)
ret = ops->vidioc_s_fmt_vid_overlay(file,
fh, f);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ CLEAR_AFTER_FIELD(f, fmt.pix);
v4l_print_pix_fmt(vfd, &f->fmt.pix);
if (ops->vidioc_s_fmt_vid_out)
ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ CLEAR_AFTER_FIELD(f, fmt.win);
if (ops->vidioc_s_fmt_vid_out_overlay)
ret = ops->vidioc_s_fmt_vid_out_overlay(file,
fh, f);
break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
+ CLEAR_AFTER_FIELD(f, fmt.vbi);
if (ops->vidioc_s_fmt_vbi_cap)
ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
break;
case V4L2_BUF_TYPE_VBI_OUTPUT:
+ CLEAR_AFTER_FIELD(f, fmt.vbi);
if (ops->vidioc_s_fmt_vbi_out)
ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ CLEAR_AFTER_FIELD(f, fmt.sliced);
if (ops->vidioc_s_fmt_sliced_vbi_cap)
ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
fh, f);
break;
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ CLEAR_AFTER_FIELD(f, fmt.sliced);
if (ops->vidioc_s_fmt_sliced_vbi_out)
ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
fh, f);
break;
case V4L2_BUF_TYPE_PRIVATE:
+ /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
if (ops->vidioc_s_fmt_type_private)
ret = ops->vidioc_s_fmt_type_private(file,
fh, f);
@@ -836,46 +851,55 @@ static long __video_do_ioctl(struct file *file,
v4l2_type_names));
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ CLEAR_AFTER_FIELD(f, fmt.pix);
if (ops->vidioc_try_fmt_vid_cap)
ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
if (!ret)
v4l_print_pix_fmt(vfd, &f->fmt.pix);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ CLEAR_AFTER_FIELD(f, fmt.win);
if (ops->vidioc_try_fmt_vid_overlay)
ret = ops->vidioc_try_fmt_vid_overlay(file,
fh, f);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ CLEAR_AFTER_FIELD(f, fmt.pix);
if (ops->vidioc_try_fmt_vid_out)
ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
if (!ret)
v4l_print_pix_fmt(vfd, &f->fmt.pix);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ CLEAR_AFTER_FIELD(f, fmt.win);
if (ops->vidioc_try_fmt_vid_out_overlay)
ret = ops->vidioc_try_fmt_vid_out_overlay(file,
fh, f);
break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
+ CLEAR_AFTER_FIELD(f, fmt.vbi);
if (ops->vidioc_try_fmt_vbi_cap)
ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
break;
case V4L2_BUF_TYPE_VBI_OUTPUT:
+ CLEAR_AFTER_FIELD(f, fmt.vbi);
if (ops->vidioc_try_fmt_vbi_out)
ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ CLEAR_AFTER_FIELD(f, fmt.sliced);
if (ops->vidioc_try_fmt_sliced_vbi_cap)
ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
fh, f);
break;
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ CLEAR_AFTER_FIELD(f, fmt.sliced);
if (ops->vidioc_try_fmt_sliced_vbi_out)
ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
fh, f);
break;
case V4L2_BUF_TYPE_PRIVATE:
+ /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
if (ops->vidioc_try_fmt_type_private)
ret = ops->vidioc_try_fmt_type_private(file,
fh, f);
@@ -898,6 +922,9 @@ static long __video_do_ioctl(struct file *file,
if (ret)
break;
+ if (p->type < V4L2_BUF_TYPE_PRIVATE)
+ CLEAR_AFTER_FIELD(p, memory);
+
ret = ops->vidioc_reqbufs(file, fh, p);
dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
p->count,
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 092333b1c34f..643cccaa1aab 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -1863,22 +1863,20 @@ static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability
static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
{
- int num = -1, i;
-
- for (i = 0; i < NUM_FORMATS; i++) {
- if (zoran_formats[i].flags & flag)
- num++;
- if (num == fmt->index)
- break;
+ unsigned int num, i;
+
+ for (num = i = 0; i < NUM_FORMATS; i++) {
+ if (zoran_formats[i].flags & flag && num++ == fmt->index) {
+ strncpy(fmt->description, zoran_formats[i].name,
+ sizeof(fmt->description) - 1);
+ /* fmt struct pre-zeroed, so adding '\0' not neeed */
+ fmt->pixelformat = zoran_formats[i].fourcc;
+ if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
+ fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
+ return 0;
+ }
}
- if (fmt->index < 0 /* late, but not too late */ || i == NUM_FORMATS)
- return -EINVAL;
-
- strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1);
- fmt->pixelformat = zoran_formats[i].fourcc;
- if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
- fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
- return 0;
+ return -EINVAL;
}
static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index de143deb06f0..c0bebc6a2f2c 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -672,15 +672,14 @@ try_again:
msb->req_sg);
if (!msb->seg_count) {
- chunk = __blk_end_request(msb->block_req, -ENOMEM,
- blk_rq_cur_bytes(msb->block_req));
+ chunk = __blk_end_request_cur(msb->block_req, -ENOMEM);
continue;
}
- t_sec = msb->block_req->sector << 9;
+ t_sec = blk_rq_pos(msb->block_req) << 9;
sector_div(t_sec, msb->page_size);
- count = msb->block_req->nr_sectors << 9;
+ count = blk_rq_bytes(msb->block_req);
count /= msb->page_size;
param.system = msb->system;
@@ -705,8 +704,8 @@ try_again:
return 0;
}
- dev_dbg(&card->dev, "elv_next\n");
- msb->block_req = elv_next_request(msb->queue);
+ dev_dbg(&card->dev, "blk_fetch\n");
+ msb->block_req = blk_fetch_request(msb->queue);
if (!msb->block_req) {
dev_dbg(&card->dev, "issue end\n");
return -EAGAIN;
@@ -745,7 +744,7 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error)
t_len *= msb->page_size;
}
} else
- t_len = msb->block_req->nr_sectors << 9;
+ t_len = blk_rq_bytes(msb->block_req);
dev_dbg(&card->dev, "transferred %x (%d)\n", t_len, error);
@@ -825,8 +824,8 @@ static void mspro_block_submit_req(struct request_queue *q)
return;
if (msb->eject) {
- while ((req = elv_next_request(q)) != NULL)
- __blk_end_request(req, -ENODEV, blk_rq_bytes(req));
+ while ((req = blk_fetch_request(q)) != NULL)
+ __blk_end_request_all(req, -ENODEV);
return;
}
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index a9019f081b97..4e6fcf06a6f2 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -1277,8 +1277,8 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
/* do we need to support multiple segments? */
if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
- ioc->name, __func__, req->bio->bi_vcnt, req->data_len,
- rsp->bio->bi_vcnt, rsp->data_len);
+ ioc->name, __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
+ rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
return -EINVAL;
}
@@ -1295,7 +1295,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
smpreq = (SmpPassthroughRequest_t *)mf;
memset(smpreq, 0, sizeof(*smpreq));
- smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4);
+ smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
if (rphy)
@@ -1321,10 +1321,10 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
MPI_SGE_FLAGS_END_OF_BUFFER |
MPI_SGE_FLAGS_DIRECTION |
mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT;
- flagsLength |= (req->data_len - 4);
+ flagsLength |= (blk_rq_bytes(req) - 4);
dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
- req->data_len, PCI_DMA_BIDIRECTIONAL);
+ blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
if (!dma_addr_out)
goto put_mf;
mpt_add_sge(psge, flagsLength, dma_addr_out);
@@ -1332,9 +1332,9 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
/* response */
flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
- flagsLength |= rsp->data_len + 4;
+ flagsLength |= blk_rq_bytes(rsp) + 4;
dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
- rsp->data_len, PCI_DMA_BIDIRECTIONAL);
+ blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
if (!dma_addr_in)
goto unmap;
mpt_add_sge(psge, flagsLength, dma_addr_in);
@@ -1357,8 +1357,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
memcpy(req->sense, smprep, sizeof(*smprep));
req->sense_len = sizeof(*smprep);
- req->data_len = 0;
- rsp->data_len -= smprep->ResponseDataLength;
+ rsp->resid_len = blk_rq_bytes(rsp) - smprep->ResponseDataLength;
} else {
printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n",
ioc->name, __func__);
@@ -1366,10 +1365,10 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
}
unmap:
if (dma_addr_out)
- pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len,
+ pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
PCI_DMA_BIDIRECTIONAL);
if (dma_addr_in)
- pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len,
+ pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
PCI_DMA_BIDIRECTIONAL);
put_mf:
if (mf)
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index a443e136dc41..6573ef4408f1 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -426,15 +426,9 @@ static void i2o_block_end_request(struct request *req, int error,
struct request_queue *q = req->q;
unsigned long flags;
- if (blk_end_request(req, error, nr_bytes)) {
- int leftover = (req->hard_nr_sectors << KERNEL_SECTOR_SHIFT);
-
- if (blk_pc_request(req))
- leftover = req->data_len;
-
+ if (blk_end_request(req, error, nr_bytes))
if (error)
- blk_end_request(req, -EIO, leftover);
- }
+ blk_end_request_all(req, -EIO);
spin_lock_irqsave(q->queue_lock, flags);
@@ -761,7 +755,7 @@ static int i2o_block_transfer(struct request *req)
break;
case CACHE_SMARTFETCH:
- if (req->nr_sectors > 16)
+ if (blk_rq_sectors(req) > 16)
ctl_flags = 0x201F0008;
else
ctl_flags = 0x001F0000;
@@ -781,13 +775,13 @@ static int i2o_block_transfer(struct request *req)
ctl_flags = 0x001F0010;
break;
case CACHE_SMARTBACK:
- if (req->nr_sectors > 16)
+ if (blk_rq_sectors(req) > 16)
ctl_flags = 0x001F0004;
else
ctl_flags = 0x001F0010;
break;
case CACHE_SMARTTHROUGH:
- if (req->nr_sectors > 16)
+ if (blk_rq_sectors(req) > 16)
ctl_flags = 0x001F0004;
else
ctl_flags = 0x001F0010;
@@ -827,22 +821,22 @@ static int i2o_block_transfer(struct request *req)
*mptr++ = cpu_to_le32(scsi_flags);
- *((u32 *) & cmd[2]) = cpu_to_be32(req->sector * hwsec);
- *((u16 *) & cmd[7]) = cpu_to_be16(req->nr_sectors * hwsec);
+ *((u32 *) & cmd[2]) = cpu_to_be32(blk_rq_pos(req) * hwsec);
+ *((u16 *) & cmd[7]) = cpu_to_be16(blk_rq_sectors(req) * hwsec);
memcpy(mptr, cmd, 10);
mptr += 4;
- *mptr++ = cpu_to_le32(req->nr_sectors << KERNEL_SECTOR_SHIFT);
+ *mptr++ = cpu_to_le32(blk_rq_bytes(req));
} else
#endif
{
msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid);
*mptr++ = cpu_to_le32(ctl_flags);
- *mptr++ = cpu_to_le32(req->nr_sectors << KERNEL_SECTOR_SHIFT);
+ *mptr++ = cpu_to_le32(blk_rq_bytes(req));
*mptr++ =
- cpu_to_le32((u32) (req->sector << KERNEL_SECTOR_SHIFT));
+ cpu_to_le32((u32) (blk_rq_pos(req) << KERNEL_SECTOR_SHIFT));
*mptr++ =
- cpu_to_le32(req->sector >> (32 - KERNEL_SECTOR_SHIFT));
+ cpu_to_le32(blk_rq_pos(req) >> (32 - KERNEL_SECTOR_SHIFT));
}
if (!i2o_block_sglist_alloc(c, ireq, &mptr)) {
@@ -883,7 +877,7 @@ static void i2o_block_request_fn(struct request_queue *q)
struct request *req;
while (!blk_queue_plugged(q)) {
- req = elv_next_request(q);
+ req = blk_peek_request(q);
if (!req)
break;
@@ -896,7 +890,7 @@ static void i2o_block_request_fn(struct request_queue *q)
if (queue_depth < I2O_BLOCK_MAX_OPEN_REQUESTS) {
if (!i2o_block_transfer(req)) {
- blkdev_dequeue_request(req);
+ blk_start_request(req);
continue;
} else
osm_info("transfer error\n");
@@ -922,8 +916,10 @@ static void i2o_block_request_fn(struct request_queue *q)
blk_stop_queue(q);
break;
}
- } else
- end_request(req, 0);
+ } else {
+ blk_start_request(req);
+ __blk_end_request_all(req, -EIO);
+ }
}
};
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index 386da1566fcc..cb73051e43db 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -35,7 +35,7 @@ struct pasic3_data {
*/
void pasic3_write_register(struct device *dev, u32 reg, u8 val)
{
- struct pasic3_data *asic = dev->driver_data;
+ struct pasic3_data *asic = dev_get_drvdata(dev);
int bus_shift = asic->bus_shift;
void __iomem *addr = asic->mapping + (REG_ADDR << bus_shift);
void __iomem *data = asic->mapping + (REG_DATA << bus_shift);
@@ -50,7 +50,7 @@ EXPORT_SYMBOL(pasic3_write_register); /* for leds-pasic3 */
*/
u8 pasic3_read_register(struct device *dev, u32 reg)
{
- struct pasic3_data *asic = dev->driver_data;
+ struct pasic3_data *asic = dev_get_drvdata(dev);
int bus_shift = asic->bus_shift;
void __iomem *addr = asic->mapping + (REG_ADDR << bus_shift);
void __iomem *data = asic->mapping + (REG_DATA << bus_shift);
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 7793932a513b..8d25a8ba3910 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -618,7 +618,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
pdev->dev.parent = pcf->dev;
pdev->dev.platform_data = &pdata->reg_init_data[i];
- pdev->dev.driver_data = pcf;
+ dev_set_drvdata(&pdev->dev, pcf);
pcf->regulator_pdev[i] = pdev;
platform_device_add(pdev);
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index ec90e953adce..cd1008c19cd7 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -647,7 +647,7 @@ static inline int __init unprotect_pm_master(void)
return e;
}
-static void __init clocks_init(struct device *dev)
+static void clocks_init(struct device *dev)
{
int e = 0;
struct clk *osc;
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index c2be3088e2e1..fe24079387c5 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -79,10 +79,6 @@ static int wm8350_phys_read(struct wm8350 *wm8350, u8 reg, int num_regs,
/* Cache is CPU endian */
dest[i - reg] = be16_to_cpu(dest[i - reg]);
- /* Satisfy non-volatile bits from cache */
- dest[i - reg] &= wm8350_reg_io_map[i].vol;
- dest[i - reg] |= wm8350->reg_cache[i];
-
/* Mask out non-readable bits */
dest[i - reg] &= wm8350_reg_io_map[i].readable;
}
@@ -182,9 +178,6 @@ static int wm8350_write(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *src)
(wm8350->reg_cache[i] & ~wm8350_reg_io_map[i].writable)
| src[i - reg];
- /* Don't store volatile bits */
- wm8350->reg_cache[i] &= ~wm8350_reg_io_map[i].vol;
-
src[i - reg] = cpu_to_be16(src[i - reg]);
}
@@ -1261,7 +1254,6 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode)
(i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) {
value = be16_to_cpu(wm8350->reg_cache[i]);
value &= wm8350_reg_io_map[i].readable;
- value &= ~wm8350_reg_io_map[i].vol;
wm8350->reg_cache[i] = value;
} else
wm8350->reg_cache[i] = reg_map[i];
diff --git a/drivers/mfd/wm8350-regmap.c b/drivers/mfd/wm8350-regmap.c
index 9a4cc954cb7c..7ccc1eab98ab 100644
--- a/drivers/mfd/wm8350-regmap.c
+++ b/drivers/mfd/wm8350-regmap.c
@@ -3186,7 +3186,7 @@ const struct wm8350_reg_access wm8350_reg_io_map[] = {
/* read write volatile */
{ 0xFFFF, 0xFFFF, 0xFFFF }, /* R0 - Reset/ID */
{ 0x7CFF, 0x0C00, 0x7FFF }, /* R1 - ID */
- { 0x0000, 0x0000, 0x0000 }, /* R2 */
+ { 0x007F, 0x0000, 0x0000 }, /* R2 - ROM Mask ID */
{ 0xBE3B, 0xBE3B, 0x8000 }, /* R3 - System Control 1 */
{ 0xFEF7, 0xFEF7, 0xF800 }, /* R4 - System Control 2 */
{ 0x80FF, 0x80FF, 0x8000 }, /* R5 - System Hibernate */
@@ -3411,7 +3411,7 @@ const struct wm8350_reg_access wm8350_reg_io_map[] = {
{ 0x0000, 0x0000, 0x0000 }, /* R224 */
{ 0x8F3F, 0x0000, 0xFFFF }, /* R225 - DCDC/LDO status */
{ 0x0000, 0x0000, 0xFFFF }, /* R226 - Charger status */
- { 0x0000, 0x0000, 0xFFFF }, /* R227 */
+ { 0x34FE, 0x0000, 0xFFFF }, /* R227 */
{ 0x0000, 0x0000, 0x0000 }, /* R228 */
{ 0x0000, 0x0000, 0x0000 }, /* R229 */
{ 0xFFFF, 0x1FFF, 0xFFFF }, /* R230 - GPIO Pin Status */
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
index cf30d06a0104..7c21bf791569 100644
--- a/drivers/mfd/wm8400-core.c
+++ b/drivers/mfd/wm8400-core.c
@@ -265,7 +265,7 @@ static int wm8400_init(struct wm8400 *wm8400,
mutex_init(&wm8400->io_lock);
- wm8400->dev->driver_data = wm8400;
+ dev_set_drvdata(wm8400->dev, wm8400);
/* Check that this is actually a WM8400 */
ret = wm8400->read_dev(wm8400->io_data, WM8400_RESET_ID, 1, &reg);
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig
index 89fec052f3b4..9118613af321 100644
--- a/drivers/misc/eeprom/Kconfig
+++ b/drivers/misc/eeprom/Kconfig
@@ -48,6 +48,20 @@ config EEPROM_LEGACY
This driver can also be built as a module. If so, the module
will be called eeprom.
+config EEPROM_MAX6875
+ tristate "Maxim MAX6874/5 power supply supervisor"
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get read-only support for the user EEPROM of
+ the Maxim MAX6874/5 EEPROM-programmable, quad power-supply
+ sequencer/supervisor.
+
+ All other features of this chip should be accessed via i2c-dev.
+
+ This driver can also be built as a module. If so, the module
+ will be called max6875.
+
+
config EEPROM_93CX6
tristate "EEPROM 93CX6 support"
help
diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile
index 539dd8f88128..df3d68ffa9d1 100644
--- a/drivers/misc/eeprom/Makefile
+++ b/drivers/misc/eeprom/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_EEPROM_AT24) += at24.o
obj-$(CONFIG_EEPROM_AT25) += at25.o
obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o
+obj-$(CONFIG_EEPROM_MAX6875) += max6875.o
obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
diff --git a/drivers/i2c/chips/max6875.c b/drivers/misc/eeprom/max6875.c
index 033d9d81ec8a..3c0c58eed347 100644
--- a/drivers/i2c/chips/max6875.c
+++ b/drivers/misc/eeprom/max6875.c
@@ -3,7 +3,7 @@
Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
- Based on i2c/chips/eeprom.c
+ Based on eeprom.c
The MAX6875 has a bank of registers and two banks of EEPROM.
Address ranges are defined as follows:
diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c
index 2e2a5923d4c2..a71e245801ee 100644
--- a/drivers/misc/isl29003.c
+++ b/drivers/misc/isl29003.c
@@ -64,6 +64,7 @@ struct isl29003_data {
struct i2c_client *client;
struct mutex lock;
u8 reg_cache[ISL29003_NUM_CACHABLE_REGS];
+ u8 power_state_before_suspend;
};
static int gain_range[] = {
@@ -411,6 +412,9 @@ static int __devexit isl29003_remove(struct i2c_client *client)
#ifdef CONFIG_PM
static int isl29003_suspend(struct i2c_client *client, pm_message_t mesg)
{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+
+ data->power_state_before_suspend = isl29003_get_power_state(client);
return isl29003_set_power_state(client, 0);
}
@@ -421,10 +425,11 @@ static int isl29003_resume(struct i2c_client *client)
/* restore registers from cache */
for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++)
- if (!i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
+ if (i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
return -EIO;
- return 0;
+ return isl29003_set_power_state(client,
+ data->power_state_before_suspend);
}
#else
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index b25e9b6516ae..c5df86546458 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -243,7 +243,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.mrq.cmd = &brq.cmd;
brq.mrq.data = &brq.data;
- brq.cmd.arg = req->sector;
+ brq.cmd.arg = blk_rq_pos(req);
if (!mmc_card_blockaddr(card))
brq.cmd.arg <<= 9;
brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
@@ -251,7 +251,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.stop.opcode = MMC_STOP_TRANSMISSION;
brq.stop.arg = 0;
brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
- brq.data.blocks = req->nr_sectors;
+ brq.data.blocks = blk_rq_sectors(req);
/*
* The block layer doesn't support all sector count
@@ -301,7 +301,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
* Adjust the sg list so it is the same size as the
* request.
*/
- if (brq.data.blocks != req->nr_sectors) {
+ if (brq.data.blocks != blk_rq_sectors(req)) {
int i, data_size = brq.data.blocks << 9;
struct scatterlist *sg;
@@ -352,8 +352,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
printk(KERN_ERR "%s: error %d transferring data,"
" sector %u, nr %u, card status %#x\n",
req->rq_disk->disk_name, brq.data.error,
- (unsigned)req->sector,
- (unsigned)req->nr_sectors, status);
+ (unsigned)blk_rq_pos(req),
+ (unsigned)blk_rq_sectors(req), status);
}
if (brq.stop.error) {
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 7a72e75d5c67..49e582356c65 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -55,7 +55,7 @@ static int mmc_queue_thread(void *d)
spin_lock_irq(q->queue_lock);
set_current_state(TASK_INTERRUPTIBLE);
if (!blk_queue_plugged(q))
- req = elv_next_request(q);
+ req = blk_fetch_request(q);
mq->req = req;
spin_unlock_irq(q->queue_lock);
@@ -88,16 +88,11 @@ static void mmc_request(struct request_queue *q)
{
struct mmc_queue *mq = q->queuedata;
struct request *req;
- int ret;
if (!mq) {
printk(KERN_ERR "MMC: killing requests for dead queue\n");
- while ((req = elv_next_request(q)) != NULL) {
- do {
- ret = __blk_end_request(req, -EIO,
- blk_rq_cur_bytes(req));
- } while (ret);
- }
+ while ((req = blk_fetch_request(q)) != NULL)
+ __blk_end_request_all(req, -EIO);
return;
}
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 264911732756..24f08de4bf2d 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -708,7 +708,13 @@ static void mmc_power_up(struct mmc_host *host)
*/
mmc_delay(10);
- host->ios.clock = host->f_min;
+ if (host->f_min > 400000) {
+ pr_warning("%s: Minimum clock frequency too high for "
+ "identification mode\n", mmc_hostname(host));
+ host->ios.clock = host->f_min;
+ } else
+ host->ios.clock = 400000;
+
host->ios.power_mode = MMC_POWER_ON;
mmc_set_ios(host);
@@ -855,61 +861,72 @@ void mmc_rescan(struct work_struct *work)
mmc_bus_get(host);
- if (host->bus_ops == NULL) {
- /*
- * Only we can add a new handler, so it's safe to
- * release the lock here.
- */
+ /* if there is a card registered, check whether it is still present */
+ if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
+ host->bus_ops->detect(host);
+
+ mmc_bus_put(host);
+
+
+ mmc_bus_get(host);
+
+ /* if there still is a card present, stop here */
+ if (host->bus_ops != NULL) {
mmc_bus_put(host);
+ goto out;
+ }
- if (host->ops->get_cd && host->ops->get_cd(host) == 0)
- goto out;
+ /* detect a newly inserted card */
- mmc_claim_host(host);
+ /*
+ * Only we can add a new handler, so it's safe to
+ * release the lock here.
+ */
+ mmc_bus_put(host);
- mmc_power_up(host);
- mmc_go_idle(host);
+ if (host->ops->get_cd && host->ops->get_cd(host) == 0)
+ goto out;
- mmc_send_if_cond(host, host->ocr_avail);
+ mmc_claim_host(host);
- /*
- * First we search for SDIO...
- */
- err = mmc_send_io_op_cond(host, 0, &ocr);
- if (!err) {
- if (mmc_attach_sdio(host, ocr))
- mmc_power_off(host);
- goto out;
- }
+ mmc_power_up(host);
+ mmc_go_idle(host);
- /*
- * ...then normal SD...
- */
- err = mmc_send_app_op_cond(host, 0, &ocr);
- if (!err) {
- if (mmc_attach_sd(host, ocr))
- mmc_power_off(host);
- goto out;
- }
+ mmc_send_if_cond(host, host->ocr_avail);
- /*
- * ...and finally MMC.
- */
- err = mmc_send_op_cond(host, 0, &ocr);
- if (!err) {
- if (mmc_attach_mmc(host, ocr))
- mmc_power_off(host);
- goto out;
- }
+ /*
+ * First we search for SDIO...
+ */
+ err = mmc_send_io_op_cond(host, 0, &ocr);
+ if (!err) {
+ if (mmc_attach_sdio(host, ocr))
+ mmc_power_off(host);
+ goto out;
+ }
- mmc_release_host(host);
- mmc_power_off(host);
- } else {
- if (host->bus_ops->detect && !host->bus_dead)
- host->bus_ops->detect(host);
+ /*
+ * ...then normal SD...
+ */
+ err = mmc_send_app_op_cond(host, 0, &ocr);
+ if (!err) {
+ if (mmc_attach_sd(host, ocr))
+ mmc_power_off(host);
+ goto out;
+ }
- mmc_bus_put(host);
+ /*
+ * ...and finally MMC.
+ */
+ err = mmc_send_op_cond(host, 0, &ocr);
+ if (!err) {
+ if (mmc_attach_mmc(host, ocr))
+ mmc_power_off(host);
+ goto out;
}
+
+ mmc_release_host(host);
+ mmc_power_off(host);
+
out:
if (host->caps & MMC_CAP_NEEDS_POLL)
mmc_schedule_delayed_work(&host->detect, HZ);
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index cf6a100bb38f..7b603e4b41db 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -177,6 +177,7 @@ struct atmel_mci {
* available.
* @wp_pin: GPIO pin used for card write protect sending, or negative
* if not available.
+ * @detect_is_active_high: The state of the detect pin when it is active.
* @detect_timer: Timer used for debouncing @detect_pin interrupts.
*/
struct atmel_mci_slot {
@@ -196,6 +197,7 @@ struct atmel_mci_slot {
int detect_pin;
int wp_pin;
+ bool detect_is_active_high;
struct timer_list detect_timer;
};
@@ -924,7 +926,8 @@ static int atmci_get_cd(struct mmc_host *mmc)
struct atmel_mci_slot *slot = mmc_priv(mmc);
if (gpio_is_valid(slot->detect_pin)) {
- present = !gpio_get_value(slot->detect_pin);
+ present = !(gpio_get_value(slot->detect_pin) ^
+ slot->detect_is_active_high);
dev_dbg(&mmc->class_dev, "card is %spresent\n",
present ? "" : "not ");
}
@@ -1028,7 +1031,8 @@ static void atmci_detect_change(unsigned long data)
return;
enable_irq(gpio_to_irq(slot->detect_pin));
- present = !gpio_get_value(slot->detect_pin);
+ present = !(gpio_get_value(slot->detect_pin) ^
+ slot->detect_is_active_high);
present_old = test_bit(ATMCI_CARD_PRESENT, &slot->flags);
dev_vdbg(&slot->mmc->class_dev, "detect change: %d (was %d)\n",
@@ -1456,6 +1460,7 @@ static int __init atmci_init_slot(struct atmel_mci *host,
slot->host = host;
slot->detect_pin = slot_data->detect_pin;
slot->wp_pin = slot_data->wp_pin;
+ slot->detect_is_active_high = slot_data->detect_is_active_high;
slot->sdc_reg = sdc_reg;
mmc->ops = &atmci_ops;
@@ -1477,7 +1482,8 @@ static int __init atmci_init_slot(struct atmel_mci *host,
if (gpio_request(slot->detect_pin, "mmc_detect")) {
dev_dbg(&mmc->class_dev, "no detect pin available\n");
slot->detect_pin = -EBUSY;
- } else if (gpio_get_value(slot->detect_pin)) {
+ } else if (gpio_get_value(slot->detect_pin) ^
+ slot->detect_is_active_high) {
clear_bit(ATMCI_CARD_PRESENT, &slot->flags);
}
}
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index f48349d18c92..a789db8eed28 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -97,6 +97,14 @@
*/
#define r1b_timeout (HZ * 3)
+/* One of the critical speed parameters is the amount of data which may
+ * be transfered in one command. If this value is too low, the SD card
+ * controller has to do multiple partial block writes (argggh!). With
+ * today (2008) SD cards there is little speed gain if we transfer more
+ * than 64 KBytes at a time. So use this value until there is any indication
+ * that we should do more here.
+ */
+#define MMC_SPI_BLOCKSATONCE 128
/****************************************************************************/
@@ -1366,6 +1374,10 @@ static int mmc_spi_probe(struct spi_device *spi)
mmc->ops = &mmc_spi_ops;
mmc->max_blk_size = MMC_SPI_BLOCKSIZE;
+ mmc->max_hw_segs = MMC_SPI_BLOCKSATONCE;
+ mmc->max_phys_segs = MMC_SPI_BLOCKSATONCE;
+ mmc->max_req_size = MMC_SPI_BLOCKSATONCE * MMC_SPI_BLOCKSIZE;
+ mmc->max_blk_count = MMC_SPI_BLOCKSATONCE;
mmc->caps = MMC_CAP_SPI;
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index b4a615c55f28..bc14bb1b0579 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -140,6 +140,8 @@ struct mxcmci_host {
struct work_struct datawork;
};
+static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
+
static inline int mxcmci_use_dma(struct mxcmci_host *host)
{
return host->do_dma;
@@ -160,7 +162,7 @@ static void mxcmci_softreset(struct mxcmci_host *host)
writew(0xff, host->base + MMC_REG_RES_TO);
}
-static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
+static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
{
unsigned int nob = data->blocks;
unsigned int blksz = data->blksz;
@@ -168,6 +170,7 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
#ifdef HAS_DMA
struct scatterlist *sg;
int i;
+ int ret;
#endif
if (data->flags & MMC_DATA_STREAM)
nob = 0xffff;
@@ -183,7 +186,7 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
for_each_sg(data->sg, sg, data->sg_len, i) {
if (sg->offset & 3 || sg->length & 3) {
host->do_dma = 0;
- return;
+ return 0;
}
}
@@ -192,23 +195,30 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
data->sg_len, host->dma_dir);
- imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
- host->res->start + MMC_REG_BUFFER_ACCESS,
- DMA_MODE_READ);
+ ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents,
+ datasize,
+ host->res->start + MMC_REG_BUFFER_ACCESS,
+ DMA_MODE_READ);
} else {
host->dma_dir = DMA_TO_DEVICE;
host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
data->sg_len, host->dma_dir);
- imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
- host->res->start + MMC_REG_BUFFER_ACCESS,
- DMA_MODE_WRITE);
+ ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents,
+ datasize,
+ host->res->start + MMC_REG_BUFFER_ACCESS,
+ DMA_MODE_WRITE);
}
+ if (ret) {
+ dev_err(mmc_dev(host->mmc), "failed to setup DMA : %d\n", ret);
+ return ret;
+ }
wmb();
imx_dma_enable(host->dma);
#endif /* HAS_DMA */
+ return 0;
}
static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
@@ -345,8 +355,11 @@ static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
stat = readl(host->base + MMC_REG_STATUS);
if (stat & STATUS_ERR_MASK)
return stat;
- if (time_after(jiffies, timeout))
+ if (time_after(jiffies, timeout)) {
+ mxcmci_softreset(host);
+ mxcmci_set_clk_rate(host, host->clock);
return STATUS_TIME_OUT_READ;
+ }
if (stat & mask)
return 0;
cpu_relax();
@@ -531,6 +544,7 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
{
struct mxcmci_host *host = mmc_priv(mmc);
unsigned int cmdat = host->cmdat;
+ int error;
WARN_ON(host->req != NULL);
@@ -540,7 +554,12 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
host->do_dma = 1;
#endif
if (req->data) {
- mxcmci_setup_data(host, req->data);
+ error = mxcmci_setup_data(host, req->data);
+ if (error) {
+ req->cmd->error = error;
+ goto out;
+ }
+
cmdat |= CMD_DAT_CONT_DATA_ENABLE;
@@ -548,7 +567,9 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
cmdat |= CMD_DAT_CONT_WRITE;
}
- if (mxcmci_start_cmd(host, req->cmd, cmdat))
+ error = mxcmci_start_cmd(host, req->cmd, cmdat);
+out:
+ if (error)
mxcmci_finish_request(host, req);
}
@@ -724,7 +745,7 @@ static int mxcmci_probe(struct platform_device *pdev)
goto out_clk_put;
}
- mmc->f_min = clk_get_rate(host->clk) >> 7;
+ mmc->f_min = clk_get_rate(host->clk) >> 16;
mmc->f_max = clk_get_rate(host->clk) >> 1;
/* recommended in data sheet */
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index bfa25c01c872..c80437928700 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1593,7 +1593,6 @@ static int mmc_omap_resume(struct platform_device *pdev)
#endif
static struct platform_driver mmc_omap_driver = {
- .probe = mmc_omap_probe,
.remove = mmc_omap_remove,
.suspend = mmc_omap_suspend,
.resume = mmc_omap_resume,
@@ -1605,7 +1604,7 @@ static struct platform_driver mmc_omap_driver = {
static int __init mmc_omap_init(void)
{
- return platform_driver_register(&mmc_omap_driver);
+ return platform_driver_probe(&mmc_omap_driver, mmc_omap_probe);
}
static void __exit mmc_omap_exit(void)
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index e62a22a7f00c..c40cb96255a2 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -680,7 +680,7 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
host->dma_ch = -1;
/*
* DMA Callback: run in interrupt context.
- * mutex_unlock will through a kernel warning if used.
+ * mutex_unlock will throw a kernel warning if used.
*/
up(&host->sem);
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9234be2226e7..1432a35690dd 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1005,12 +1005,34 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
{
u8 pwr;
- if (host->power == power)
+ if (power == (unsigned short)-1)
+ pwr = 0;
+ else {
+ switch (1 << power) {
+ case MMC_VDD_165_195:
+ pwr = SDHCI_POWER_180;
+ break;
+ case MMC_VDD_29_30:
+ case MMC_VDD_30_31:
+ pwr = SDHCI_POWER_300;
+ break;
+ case MMC_VDD_32_33:
+ case MMC_VDD_33_34:
+ pwr = SDHCI_POWER_330;
+ break;
+ default:
+ BUG();
+ }
+ }
+
+ if (host->pwr == pwr)
return;
- if (power == (unsigned short)-1) {
+ host->pwr = pwr;
+
+ if (pwr == 0) {
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
- goto out;
+ return;
}
/*
@@ -1020,35 +1042,16 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
- pwr = SDHCI_POWER_ON;
-
- switch (1 << power) {
- case MMC_VDD_165_195:
- pwr |= SDHCI_POWER_180;
- break;
- case MMC_VDD_29_30:
- case MMC_VDD_30_31:
- pwr |= SDHCI_POWER_300;
- break;
- case MMC_VDD_32_33:
- case MMC_VDD_33_34:
- pwr |= SDHCI_POWER_330;
- break;
- default:
- BUG();
- }
-
/*
* At least the Marvell CaFe chip gets confused if we set the voltage
* and set turn on power at the same time, so set the voltage first.
*/
if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
- sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
- sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+ pwr |= SDHCI_POWER_ON;
-out:
- host->power = power;
+ sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
}
/*****************************************************************************\
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 65c6f996bbd3..2de08349c3ca 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -255,7 +255,7 @@ struct sdhci_host {
unsigned int timeout_clk; /* Timeout freq (KHz) */
unsigned int clock; /* Current clock (MHz) */
- unsigned short power; /* Current voltage */
+ u8 pwr; /* Current voltage */
struct mmc_request *mrq; /* Current request */
struct mmc_command *cmd; /* Current command */
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 8185b1f3e5e6..cc6369ea67dd 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -54,7 +54,7 @@
#define SR_SRWD 0x80 /* SR write protect */
/* Define max times to check status register before we give up. */
-#define MAX_READY_WAIT_COUNT 100000
+#define MAX_READY_WAIT_JIFFIES (10 * HZ) /* eg. M25P128 specs 6s max sector erase */
#define CMD_SIZE 4
#ifdef CONFIG_M25PXX_USE_FAST_READ
@@ -139,20 +139,20 @@ static inline int write_enable(struct m25p *flash)
*/
static int wait_till_ready(struct m25p *flash)
{
- int count;
+ unsigned long deadline;
int sr;
- /* one chip guarantees max 5 msec wait here after page writes,
- * but potentially three seconds (!) after page erase.
- */
- for (count = 0; count < MAX_READY_WAIT_COUNT; count++) {
+ deadline = jiffies + MAX_READY_WAIT_JIFFIES;
+
+ do {
if ((sr = read_sr(flash)) < 0)
break;
else if (!(sr & SR_WIP))
return 0;
- /* REVISIT sometimes sleeping would be best */
- }
+ cond_resched();
+
+ } while (!time_after_eq(jiffies, deadline));
return 1;
}
@@ -246,10 +246,12 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
mutex_lock(&flash->lock);
/* whole-chip erase? */
- if (len == flash->mtd.size && erase_chip(flash)) {
- instr->state = MTD_ERASE_FAILED;
- mutex_unlock(&flash->lock);
- return -EIO;
+ if (len == flash->mtd.size) {
+ if (erase_chip(flash)) {
+ instr->state = MTD_ERASE_FAILED;
+ mutex_unlock(&flash->lock);
+ return -EIO;
+ }
/* REVISIT in some cases we could speed up erasing large regions
* by using OPCODE_SE instead of OPCODE_BE_4K. We may have set up
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index a49a9c8f2cb1..502622f628bc 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -47,40 +47,41 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
unsigned long block, nsect;
char *buf;
- block = req->sector << 9 >> tr->blkshift;
- nsect = req->current_nr_sectors << 9 >> tr->blkshift;
+ block = blk_rq_pos(req) << 9 >> tr->blkshift;
+ nsect = blk_rq_cur_bytes(req) >> tr->blkshift;
buf = req->buffer;
if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
req->cmd[0] == REQ_LB_OP_DISCARD)
- return !tr->discard(dev, block, nsect);
+ return tr->discard(dev, block, nsect);
if (!blk_fs_request(req))
- return 0;
+ return -EIO;
- if (req->sector + req->current_nr_sectors > get_capacity(req->rq_disk))
- return 0;
+ if (blk_rq_pos(req) + blk_rq_cur_sectors(req) >
+ get_capacity(req->rq_disk))
+ return -EIO;
switch(rq_data_dir(req)) {
case READ:
for (; nsect > 0; nsect--, block++, buf += tr->blksize)
if (tr->readsect(dev, block, buf))
- return 0;
- return 1;
+ return -EIO;
+ return 0;
case WRITE:
if (!tr->writesect)
- return 0;
+ return -EIO;
for (; nsect > 0; nsect--, block++, buf += tr->blksize)
if (tr->writesect(dev, block, buf))
- return 0;
- return 1;
+ return -EIO;
+ return 0;
default:
printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
- return 0;
+ return -EIO;
}
}
@@ -88,19 +89,18 @@ static int mtd_blktrans_thread(void *arg)
{
struct mtd_blktrans_ops *tr = arg;
struct request_queue *rq = tr->blkcore_priv->rq;
+ struct request *req = NULL;
/* we might get involved when memory gets low, so use PF_MEMALLOC */
current->flags |= PF_MEMALLOC;
spin_lock_irq(rq->queue_lock);
+
while (!kthread_should_stop()) {
- struct request *req;
struct mtd_blktrans_dev *dev;
- int res = 0;
-
- req = elv_next_request(rq);
+ int res;
- if (!req) {
+ if (!req && !(req = blk_fetch_request(rq))) {
set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irq(rq->queue_lock);
schedule();
@@ -119,8 +119,13 @@ static int mtd_blktrans_thread(void *arg)
spin_lock_irq(rq->queue_lock);
- end_request(req, res);
+ if (!__blk_end_request_cur(req, res))
+ req = NULL;
}
+
+ if (req)
+ __blk_end_request_all(req, -EIO);
+
spin_unlock_irq(rq->queue_lock);
return 0;
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index fdd6ae859397..bccb4b1ffc46 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -48,11 +48,11 @@ static LIST_HEAD(mtd_notifiers);
*/
static void mtd_release(struct device *dev)
{
- struct mtd_info *mtd = dev_to_mtd(dev);
+ dev_t index = MTD_DEVT(dev_to_mtd(dev)->index);
/* remove /dev/mtdXro node if needed */
- if (MTD_DEVT(mtd->index))
- device_destroy(mtd_class, MTD_DEVT(mtd->index) + 1);
+ if (index)
+ device_destroy(mtd_class, index + 1);
}
static ssize_t mtd_type_show(struct device *dev,
@@ -132,6 +132,17 @@ static ssize_t mtd_writesize_show(struct device *dev,
}
static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL);
+static ssize_t mtd_subpagesize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+ unsigned int subpagesize = mtd->writesize >> mtd->subpage_sft;
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", subpagesize);
+
+}
+static DEVICE_ATTR(subpagesize, S_IRUGO, mtd_subpagesize_show, NULL);
+
static ssize_t mtd_oobsize_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -169,6 +180,7 @@ static struct attribute *mtd_attrs[] = {
&dev_attr_size.attr,
&dev_attr_erasesize.attr,
&dev_attr_writesize.attr,
+ &dev_attr_subpagesize.attr,
&dev_attr_oobsize.attr,
&dev_attr_numeraseregions.attr,
&dev_attr_name.attr,
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c
index 92285d0089c2..af8b42e0a55b 100644
--- a/drivers/mtd/mtdsuper.c
+++ b/drivers/mtd/mtdsuper.c
@@ -74,8 +74,7 @@ static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags,
ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
if (ret < 0) {
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ deactivate_locked_super(sb);
return ret;
}
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index fbb371921991..393e4e711965 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -653,11 +653,11 @@ static int __init el3_mca_probe(struct device *device)
netdev_boot_setup_check(dev);
el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
- device->driver_data = dev;
+ dev_set_drvdata(device, dev);
err = el3_common_init(dev);
if (err) {
- device->driver_data = NULL;
+ dev_set_drvdata(device, NULL);
free_netdev(dev);
return -ENOMEM;
}
@@ -721,12 +721,12 @@ static int __init el3_eisa_probe (struct device *device)
/* This remove works for all device types.
*
- * The net dev must be stored in the driver_data field */
+ * The net dev must be stored in the driver data field */
static int __devexit el3_device_remove (struct device *device)
{
struct net_device *dev;
- dev = device->driver_data;
+ dev = dev_get_drvdata(device);
el3_common_remove (dev);
return 0;
@@ -1451,7 +1451,7 @@ el3_suspend(struct device *pdev, pm_message_t state)
struct el3_private *lp;
int ioaddr;
- dev = pdev->driver_data;
+ dev = dev_get_drvdata(pdev);
lp = netdev_priv(dev);
ioaddr = dev->base_addr;
@@ -1475,7 +1475,7 @@ el3_resume(struct device *pdev)
struct el3_private *lp;
int ioaddr;
- dev = pdev->driver_data;
+ dev = dev_get_drvdata(pdev);
lp = netdev_priv(dev);
ioaddr = dev->base_addr;
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 1fc45431a620..d90177509bf6 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -2292,11 +2292,11 @@ static int rtl8139_close (struct net_device *dev)
other threads or interrupts aren't messing with the 8139. */
static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
- struct rtl8139_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->mmio_addr;
+ struct rtl8139_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
- spin_lock_irq(&np->lock);
- if (rtl_chip_info[np->chipset].flags & HasLWake) {
+ spin_lock_irq(&tp->lock);
+ if (rtl_chip_info[tp->chipset].flags & HasLWake) {
u8 cfg3 = RTL_R8 (Config3);
u8 cfg5 = RTL_R8 (Config5);
@@ -2317,7 +2317,7 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (cfg5 & Cfg5_BWF)
wol->wolopts |= WAKE_BCAST;
}
- spin_unlock_irq(&np->lock);
+ spin_unlock_irq(&tp->lock);
}
@@ -2326,19 +2326,19 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
aren't messing with the 8139. */
static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
- struct rtl8139_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->mmio_addr;
+ struct rtl8139_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
u32 support;
u8 cfg3, cfg5;
- support = ((rtl_chip_info[np->chipset].flags & HasLWake)
+ support = ((rtl_chip_info[tp->chipset].flags & HasLWake)
? (WAKE_PHY | WAKE_MAGIC
| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
: 0);
if (wol->wolopts & ~support)
return -EINVAL;
- spin_lock_irq(&np->lock);
+ spin_lock_irq(&tp->lock);
cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
if (wol->wolopts & WAKE_PHY)
cfg3 |= Cfg3_LinkUp;
@@ -2359,87 +2359,87 @@ static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (wol->wolopts & WAKE_BCAST)
cfg5 |= Cfg5_BWF;
RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */
- spin_unlock_irq(&np->lock);
+ spin_unlock_irq(&tp->lock);
return 0;
}
static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- struct rtl8139_private *np = netdev_priv(dev);
+ struct rtl8139_private *tp = netdev_priv(dev);
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
- strcpy(info->bus_info, pci_name(np->pci_dev));
- info->regdump_len = np->regs_len;
+ strcpy(info->bus_info, pci_name(tp->pci_dev));
+ info->regdump_len = tp->regs_len;
}
static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- struct rtl8139_private *np = netdev_priv(dev);
- spin_lock_irq(&np->lock);
- mii_ethtool_gset(&np->mii, cmd);
- spin_unlock_irq(&np->lock);
+ struct rtl8139_private *tp = netdev_priv(dev);
+ spin_lock_irq(&tp->lock);
+ mii_ethtool_gset(&tp->mii, cmd);
+ spin_unlock_irq(&tp->lock);
return 0;
}
static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- struct rtl8139_private *np = netdev_priv(dev);
+ struct rtl8139_private *tp = netdev_priv(dev);
int rc;
- spin_lock_irq(&np->lock);
- rc = mii_ethtool_sset(&np->mii, cmd);
- spin_unlock_irq(&np->lock);
+ spin_lock_irq(&tp->lock);
+ rc = mii_ethtool_sset(&tp->mii, cmd);
+ spin_unlock_irq(&tp->lock);
return rc;
}
static int rtl8139_nway_reset(struct net_device *dev)
{
- struct rtl8139_private *np = netdev_priv(dev);
- return mii_nway_restart(&np->mii);
+ struct rtl8139_private *tp = netdev_priv(dev);
+ return mii_nway_restart(&tp->mii);
}
static u32 rtl8139_get_link(struct net_device *dev)
{
- struct rtl8139_private *np = netdev_priv(dev);
- return mii_link_ok(&np->mii);
+ struct rtl8139_private *tp = netdev_priv(dev);
+ return mii_link_ok(&tp->mii);
}
static u32 rtl8139_get_msglevel(struct net_device *dev)
{
- struct rtl8139_private *np = netdev_priv(dev);
- return np->msg_enable;
+ struct rtl8139_private *tp = netdev_priv(dev);
+ return tp->msg_enable;
}
static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
{
- struct rtl8139_private *np = netdev_priv(dev);
- np->msg_enable = datum;
+ struct rtl8139_private *tp = netdev_priv(dev);
+ tp->msg_enable = datum;
}
static int rtl8139_get_regs_len(struct net_device *dev)
{
- struct rtl8139_private *np;
+ struct rtl8139_private *tp;
/* TODO: we are too slack to do reg dumping for pio, for now */
if (use_io)
return 0;
- np = netdev_priv(dev);
- return np->regs_len;
+ tp = netdev_priv(dev);
+ return tp->regs_len;
}
static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
{
- struct rtl8139_private *np;
+ struct rtl8139_private *tp;
/* TODO: we are too slack to do reg dumping for pio, for now */
if (use_io)
return;
- np = netdev_priv(dev);
+ tp = netdev_priv(dev);
regs->version = RTL_REGS_VER;
- spin_lock_irq(&np->lock);
- memcpy_fromio(regbuf, np->mmio_addr, regs->len);
- spin_unlock_irq(&np->lock);
+ spin_lock_irq(&tp->lock);
+ memcpy_fromio(regbuf, tp->mmio_addr, regs->len);
+ spin_unlock_irq(&tp->lock);
}
static int rtl8139_get_sset_count(struct net_device *dev, int sset)
@@ -2454,12 +2454,12 @@ static int rtl8139_get_sset_count(struct net_device *dev, int sset)
static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
{
- struct rtl8139_private *np = netdev_priv(dev);
+ struct rtl8139_private *tp = netdev_priv(dev);
- data[0] = np->xstats.early_rx;
- data[1] = np->xstats.tx_buf_mapped;
- data[2] = np->xstats.tx_timeouts;
- data[3] = np->xstats.rx_lost_in_ring;
+ data[0] = tp->xstats.early_rx;
+ data[1] = tp->xstats.tx_buf_mapped;
+ data[2] = tp->xstats.tx_timeouts;
+ data[3] = tp->xstats.rx_lost_in_ring;
}
static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -2486,15 +2486,15 @@ static const struct ethtool_ops rtl8139_ethtool_ops = {
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct rtl8139_private *np = netdev_priv(dev);
+ struct rtl8139_private *tp = netdev_priv(dev);
int rc;
if (!netif_running(dev))
return -EINVAL;
- spin_lock_irq(&np->lock);
- rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
- spin_unlock_irq(&np->lock);
+ spin_lock_irq(&tp->lock);
+ rc = generic_mii_ioctl(&tp->mii, if_mii(rq), cmd, NULL);
+ spin_unlock_irq(&tp->lock);
return rc;
}
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index ec3e22e6306f..21153dea8ebe 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -74,14 +74,8 @@ EXPORT_SYMBOL(ei_netdev_ops);
struct net_device *__alloc_ei_netdev(int size)
{
struct net_device *dev = ____alloc_ei_netdev(size);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
- if (dev) {
- dev->hard_start_xmit = ei_start_xmit;
- dev->get_stats = ei_get_stats;
- dev->set_multicast_list = ei_set_multicast_list;
- dev->tx_timeout = ei_tx_timeout;
- }
-#endif
+ if (dev)
+ dev->netdev_ops = &ei_netdev_ops;
return dev;
}
EXPORT_SYMBOL(__alloc_ei_netdev);
diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c
index da863c91d1d0..d225c291fd93 100644
--- a/drivers/net/8390p.c
+++ b/drivers/net/8390p.c
@@ -79,14 +79,8 @@ EXPORT_SYMBOL(eip_netdev_ops);
struct net_device *__alloc_eip_netdev(int size)
{
struct net_device *dev = ____alloc_ei_netdev(size);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
- if (dev) {
- dev->hard_start_xmit = eip_start_xmit;
- dev->get_stats = eip_get_stats;
- dev->set_multicast_list = eip_set_multicast_list;
- dev->tx_timeout = eip_tx_timeout;
- }
-#endif
+ if (dev)
+ dev->netdev_ops = &eip_netdev_ops;
return dev;
}
EXPORT_SYMBOL(__alloc_eip_netdev);
@@ -97,16 +91,15 @@ void NS8390p_init(struct net_device *dev, int startp)
}
EXPORT_SYMBOL(NS8390p_init);
-#if defined(MODULE)
-
-int init_module(void)
+static int __init NS8390p_init_module(void)
{
return 0;
}
-void cleanup_module(void)
+static void __exit NS8390p_cleanup_module(void)
{
}
-#endif /* MODULE */
+module_init(NS8390p_init_module);
+module_exit(NS8390p_cleanup_module);
MODULE_LICENSE("GPL");
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 214a92d1ef75..b8727d54bdbb 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2362,6 +2362,14 @@ config MV643XX_ETH
Some boards that use the Discovery chipset are the Momenco
Ocelot C and Jaguar ATX and Pegasos II.
+config XILINX_LL_TEMAC
+ tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
+ select PHYLIB
+ depends on PPC_DCR_NATIVE
+ help
+ This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
+ core used in Xilinx Spartan and Virtex FPGAs
+
config QLA3XXX
tristate "QLogic QLA3XXX Network Driver Support"
depends on PCI
@@ -2435,10 +2443,14 @@ menuconfig NETDEV_10000
if NETDEV_10000
+config MDIO
+ tristate
+
config CHELSIO_T1
tristate "Chelsio 10Gb Ethernet support"
depends on PCI
select CRC32
+ select MDIO
help
This driver supports Chelsio gigabit and 10-gigabit
Ethernet cards. More information about adapter features and
@@ -2471,6 +2483,7 @@ config CHELSIO_T3
tristate "Chelsio Communications T3 10Gb Ethernet support"
depends on CHELSIO_T3_DEPENDS
select FW_LOADER
+ select MDIO
help
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
adapters.
@@ -2506,6 +2519,7 @@ config ENIC
config IXGBE
tristate "Intel(R) 10GbE PCI Express adapters support"
depends on PCI && INET
+ select MDIO
---help---
This driver supports Intel(R) 10GbE PCI Express family of
adapters. For more information on how to identify your adapter, go
@@ -2668,6 +2682,7 @@ config TEHUTI
config BNX2X
tristate "Broadcom NetXtremeII 10Gb support"
depends on PCI
+ select FW_LOADER
select ZLIB_INFLATE
select LIBCRC32C
help
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1fc4602a6ff2..dcd5f15dd9e3 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_SH_ETH) += sh_eth.o
#
obj-$(CONFIG_MII) += mii.o
+obj-$(CONFIG_MDIO) += mdio.o
obj-$(CONFIG_PHYLIB) += phy/
obj-$(CONFIG_SUNDANCE) += sundance.o
@@ -134,6 +135,8 @@ obj-$(CONFIG_AX88796) += ax88796.o
obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
+ll_temac-objs := ll_temac_main.o ll_temac_mdio.o
+obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
obj-$(CONFIG_QLA3XXX) += qla3xxx.o
obj-$(CONFIG_QLGE) += qlge/
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index 448487e22fa3..a740053d3af3 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -338,12 +338,12 @@ static int ixp4xx_mdio_register(void)
if (cpu_is_ixp43x()) {
/* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */
if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH))
- return -ENOSYS;
+ return -ENODEV;
mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT;
} else {
/* All MII PHY accesses use NPE-B Ethernet registers */
if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
- return -ENOSYS;
+ return -ENODEV;
mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
}
@@ -1174,7 +1174,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
regs_phys = IXP4XX_EthC_BASE_PHYS;
break;
default:
- err = -ENOSYS;
+ err = -ENODEV;
goto err_free;
}
@@ -1189,15 +1189,10 @@ static int __devinit eth_init_one(struct platform_device *pdev)
goto err_free;
}
- if (register_netdev(dev)) {
- err = -EIO;
- goto err_npe_rel;
- }
-
port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name);
if (!port->mem_res) {
err = -EBUSY;
- goto err_unreg;
+ goto err_npe_rel;
}
port->plat = plat;
@@ -1215,20 +1210,25 @@ static int __devinit eth_init_one(struct platform_device *pdev)
snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy);
port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
PHY_INTERFACE_MODE_MII);
- if (IS_ERR(port->phydev)) {
- printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
- return PTR_ERR(port->phydev);
- }
+ if ((err = IS_ERR(port->phydev)))
+ goto err_free_mem;
port->phydev->irq = PHY_POLL;
+ if ((err = register_netdev(dev)))
+ goto err_phy_dis;
+
printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy,
npe_name(port->npe));
return 0;
-err_unreg:
- unregister_netdev(dev);
+err_phy_dis:
+ phy_disconnect(port->phydev);
+err_free_mem:
+ npe_port_tab[NPE_ID(port->id)] = NULL;
+ platform_set_drvdata(pdev, NULL);
+ release_resource(port->mem_res);
err_npe_rel:
npe_release(port->npe);
err_free:
@@ -1242,6 +1242,7 @@ static int __devexit eth_remove_one(struct platform_device *pdev)
struct port *port = netdev_priv(dev);
unregister_netdev(dev);
+ phy_disconnect(port->phydev);
npe_port_tab[NPE_ID(port->id)] = NULL;
platform_set_drvdata(pdev, NULL);
npe_release(port->npe);
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index 83a12125b94e..fc1092b835d2 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -220,11 +220,11 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
/* link down */
if (netif_carrier_ok(netdev)) {
hw->hibernate = true;
- atl1c_set_aspm(hw, false);
if (atl1c_stop_mac(hw) != 0)
if (netif_msg_hw(adapter))
dev_warn(&pdev->dev,
"stop mac failed\n");
+ atl1c_set_aspm(hw, false);
}
netif_carrier_off(netdev);
} else {
@@ -240,10 +240,10 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
adapter->link_duplex != duplex) {
adapter->link_speed = speed;
adapter->link_duplex = duplex;
+ atl1c_set_aspm(hw, true);
atl1c_enable_tx_ctrl(hw);
atl1c_enable_rx_ctrl(hw);
atl1c_setup_mac_ctrl(adapter);
- atl1c_set_aspm(hw, true);
if (netif_msg_link(adapter))
dev_info(&pdev->dev,
"%s: %s NIC Link is Up<%d Mbps %s>\n",
@@ -1242,9 +1242,7 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
- pm_ctrl_data &= PM_CTRL_SERDES_PD_EX_L1;
- pm_ctrl_data |= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
- pm_ctrl_data |= ~PM_CTRL_SERDES_L1_EN;
+ pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1;
pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
PM_CTRL_L1_ENTRY_TIMER_SHIFT);
@@ -1254,19 +1252,11 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
- if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) {
- pm_ctrl_data |= AT_ASPM_L1_TIMER <<
- PM_CTRL_L1_ENTRY_TIMER_SHIFT;
- pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
- } else
- pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
-
- if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT)
- pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN;
- else
- pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
-
+ pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
+ pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
} else {
+ pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
+ pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN;
pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN;
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index fb57b750866b..adac06195c8f 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -1794,8 +1794,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
- if (tx_buffer->skb)
- BUG();
+ BUG_ON(tx_buffer->skb);
tx_buffer->skb = NULL;
tx_buffer->length =
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 0ab22540bf59..13f0bdc32449 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2207,8 +2207,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
nr_frags = skb_shinfo(skb)->nr_frags;
next_to_use = atomic_read(&tpd_ring->next_to_use);
buffer_info = &tpd_ring->buffer_info[next_to_use];
- if (unlikely(buffer_info->skb))
- BUG();
+ BUG_ON(buffer_info->skb);
/* put skb in last TPD */
buffer_info->skb = NULL;
@@ -2274,8 +2273,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
ATL1_MAX_TX_BUF_LEN;
for (i = 0; i < nseg; i++) {
buffer_info = &tpd_ring->buffer_info[next_to_use];
- if (unlikely(buffer_info->skb))
- BUG();
+ BUG_ON(buffer_info->skb);
+
buffer_info->skb = NULL;
buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
ATL1_MAX_TX_BUF_LEN : buf_len;
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 30d0c81c989e..c23ea16135ca 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -637,6 +637,22 @@ static void be_rx_stats_update(struct be_adapter *adapter,
stats->be_rx_bytes += pktsize;
}
+static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
+{
+ u8 l4_cksm, ip_version, ipcksm, tcpf = 0, udpf = 0, ipv6_chk;
+
+ l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
+ ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp);
+ ip_version = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp);
+ if (ip_version) {
+ tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
+ udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp);
+ }
+ ipv6_chk = (ip_version && (tcpf || udpf));
+
+ return ((l4_cksm && ipv6_chk && ipcksm) && cso) ? false : true;
+}
+
static struct be_rx_page_info *
get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
{
@@ -752,9 +768,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
{
struct sk_buff *skb;
u32 vtp, vid;
- int l4_cksm;
- l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
@@ -769,10 +783,10 @@ static void be_rx_compl_process(struct be_adapter *adapter,
skb_fill_rx_data(adapter, skb, rxcp);
- if (l4_cksm && adapter->rx_csum)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
+ if (do_pkt_csum(rxcp, adapter->rx_csum))
skb->ip_summed = CHECKSUM_NONE;
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
skb->truesize = skb->len + sizeof(struct sk_buff);
skb->protocol = eth_type_trans(skb, adapter->netdev);
@@ -1626,10 +1640,12 @@ static void be_netdev_init(struct net_device *netdev)
netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+ NETIF_F_IPV6_CSUM;
netdev->flags |= IFF_MULTICAST;
+ adapter->rx_csum = true;
+
BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 44d015f70d1c..9578a3dfac01 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1247,6 +1247,16 @@ static const struct ethtool_ops bmac_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
+static const struct net_device_ops bmac_netdev_ops = {
+ .ndo_open = bmac_open,
+ .ndo_stop = bmac_close,
+ .ndo_start_xmit = bmac_output,
+ .ndo_set_multicast_list = bmac_set_multicast,
+ .ndo_set_mac_address = bmac_set_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
int j, rev, ret;
@@ -1308,12 +1318,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
bmac_enable_and_reset_chip(dev);
bmwrite(dev, INTDISABLE, DisableAll);
- dev->open = bmac_open;
- dev->stop = bmac_close;
+ dev->netdev_ops = &bmac_netdev_ops;
dev->ethtool_ops = &bmac_ethtool_ops;
- dev->hard_start_xmit = bmac_output;
- dev->set_multicast_list = bmac_set_multicast;
- dev->set_mac_address = bmac_set_address;
bmac_get_station_address(dev, addr);
if (bmac_verify_checksum(dev) != 0)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d47839184a06..b0cb29d4cc01 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -54,8 +54,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "2.0.0"
-#define DRV_MODULE_RELDATE "April 2, 2009"
+#define DRV_MODULE_VERSION "2.0.1"
+#define DRV_MODULE_RELDATE "May 6, 2009"
#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-4.6.16.fw"
#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-4.6.16.fw"
#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-4.6.17.fw"
@@ -2600,6 +2600,7 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi)
/* Tell compiler that status block fields can change. */
barrier();
cons = *bnapi->hw_tx_cons_ptr;
+ barrier();
if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT))
cons++;
return cons;
@@ -2879,6 +2880,7 @@ bnx2_get_hw_rx_cons(struct bnx2_napi *bnapi)
/* Tell compiler that status block fields can change. */
barrier();
cons = *bnapi->hw_rx_cons_ptr;
+ barrier();
if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT))
cons++;
return cons;
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index a329bee25550..8678457849f9 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -965,6 +965,21 @@ struct bnx2x {
int gunzip_outlen;
#define FW_BUF_SIZE 0x8000
+ struct raw_op *init_ops;
+ /* Init blocks offsets inside init_ops */
+ u16 *init_ops_offsets;
+ /* Data blob - has 32 bit granularity */
+ u32 *init_data;
+ /* Zipped PRAM blobs - raw data */
+ const u8 *tsem_int_table_data;
+ const u8 *tsem_pram_data;
+ const u8 *usem_int_table_data;
+ const u8 *usem_pram_data;
+ const u8 *xsem_int_table_data;
+ const u8 *xsem_pram_data;
+ const u8 *csem_int_table_data;
+ const u8 *csem_pram_data;
+ const struct firmware *firmware;
};
diff --git a/drivers/net/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x_fw_file_hdr.h
new file mode 100644
index 000000000000..3f5ee5d7cc2a
--- /dev/null
+++ b/drivers/net/bnx2x_fw_file_hdr.h
@@ -0,0 +1,37 @@
+/* bnx2x_fw_file_hdr.h: FW binary file header structure.
+ *
+ * Copyright (c) 2007-2009 Broadcom 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.
+ *
+ * Maintained by: Eilon Greenstein <eilong@broadcom.com>
+ * Written by: Vladislav Zolotarov <vladz@broadcom.com>
+ * Based on the original idea of John Wright <john.wright@hp.com>.
+ */
+
+#ifndef BNX2X_INIT_FILE_HDR_H
+#define BNX2X_INIT_FILE_HDR_H
+
+struct bnx2x_fw_file_section {
+ __be32 len;
+ __be32 offset;
+};
+
+struct bnx2x_fw_file_hdr {
+ struct bnx2x_fw_file_section init_ops;
+ struct bnx2x_fw_file_section init_ops_offsets;
+ struct bnx2x_fw_file_section init_data;
+ struct bnx2x_fw_file_section tsem_int_table_data;
+ struct bnx2x_fw_file_section tsem_pram_data;
+ struct bnx2x_fw_file_section usem_int_table_data;
+ struct bnx2x_fw_file_section usem_pram_data;
+ struct bnx2x_fw_file_section csem_int_table_data;
+ struct bnx2x_fw_file_section csem_pram_data;
+ struct bnx2x_fw_file_section xsem_int_table_data;
+ struct bnx2x_fw_file_section xsem_pram_data;
+ struct bnx2x_fw_file_section fw_version;
+};
+
+#endif /* BNX2X_INIT_FILE_HDR_H */
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 39ba2936c0c2..3ba4d888068f 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -1,4 +1,5 @@
/* bnx2x_init.h: Broadcom Everest network driver.
+ * Structures and macroes needed during the initialization.
*
* Copyright (c) 2007-2009 Broadcom Corporation
*
@@ -8,6 +9,7 @@
*
* Maintained by: Eilon Greenstein <eilong@broadcom.com>
* Written by: Eliezer Tamir
+ * Modified by: Vladislav Zolotarov <vladz@broadcom.com>
*/
#ifndef BNX2X_INIT_H
@@ -45,33 +47,71 @@
#define OP_WR_64 0x8 /* write 64 bit pattern */
#define OP_WB 0x9 /* copy a string using DMAE */
-/* Operation specific for E1 */
-#define OP_RD_E1 0xa /* read single register */
-#define OP_WR_E1 0xb /* write single register */
-#define OP_IW_E1 0xc /* write single register using mailbox */
-#define OP_SW_E1 0xd /* copy a string to the device */
-#define OP_SI_E1 0xe /* copy a string using mailbox */
-#define OP_ZR_E1 0xf /* clear memory */
-#define OP_ZP_E1 0x10 /* unzip then copy with DMAE */
-#define OP_WR_64_E1 0x11 /* write 64 bit pattern on E1 */
-#define OP_WB_E1 0x12 /* copy a string using DMAE */
-
-/* Operation specific for E1H */
-#define OP_RD_E1H 0x13 /* read single register */
-#define OP_WR_E1H 0x14 /* write single register */
-#define OP_IW_E1H 0x15 /* write single register using mailbox */
-#define OP_SW_E1H 0x16 /* copy a string to the device */
-#define OP_SI_E1H 0x17 /* copy a string using mailbox */
-#define OP_ZR_E1H 0x18 /* clear memory */
-#define OP_ZP_E1H 0x19 /* unzip then copy with DMAE */
-#define OP_WR_64_E1H 0x1a /* write 64 bit pattern on E1H */
-#define OP_WB_E1H 0x1b /* copy a string using DMAE */
-
/* FPGA and EMUL specific operations */
-#define OP_WR_EMUL_E1H 0x1c /* write single register on E1H Emul */
-#define OP_WR_EMUL 0x1d /* write single register on Emulation */
-#define OP_WR_FPGA 0x1e /* write single register on FPGA */
-#define OP_WR_ASIC 0x1f /* write single register on ASIC */
+#define OP_WR_EMUL 0xa /* write single register on Emulation */
+#define OP_WR_FPGA 0xb /* write single register on FPGA */
+#define OP_WR_ASIC 0xc /* write single register on ASIC */
+
+/* Init stages */
+#define COMMON_STAGE 0
+#define PORT0_STAGE 1
+#define PORT1_STAGE 2
+/* Never reorder FUNCx stages !!! */
+#define FUNC0_STAGE 3
+#define FUNC1_STAGE 4
+#define FUNC2_STAGE 5
+#define FUNC3_STAGE 6
+#define FUNC4_STAGE 7
+#define FUNC5_STAGE 8
+#define FUNC6_STAGE 9
+#define FUNC7_STAGE 10
+#define STAGE_IDX_MAX 11
+
+#define STAGE_START 0
+#define STAGE_END 1
+
+
+/* Indices of blocks */
+#define PRS_BLOCK 0
+#define SRCH_BLOCK 1
+#define TSDM_BLOCK 2
+#define TCM_BLOCK 3
+#define BRB1_BLOCK 4
+#define TSEM_BLOCK 5
+#define PXPCS_BLOCK 6
+#define EMAC0_BLOCK 7
+#define EMAC1_BLOCK 8
+#define DBU_BLOCK 9
+#define MISC_BLOCK 10
+#define DBG_BLOCK 11
+#define NIG_BLOCK 12
+#define MCP_BLOCK 13
+#define UPB_BLOCK 14
+#define CSDM_BLOCK 15
+#define USDM_BLOCK 16
+#define CCM_BLOCK 17
+#define UCM_BLOCK 18
+#define USEM_BLOCK 19
+#define CSEM_BLOCK 20
+#define XPB_BLOCK 21
+#define DQ_BLOCK 22
+#define TIMERS_BLOCK 23
+#define XSDM_BLOCK 24
+#define QM_BLOCK 25
+#define PBF_BLOCK 26
+#define XCM_BLOCK 27
+#define XSEM_BLOCK 28
+#define CDU_BLOCK 29
+#define DMAE_BLOCK 30
+#define PXP_BLOCK 31
+#define CFC_BLOCK 32
+#define HC_BLOCK 33
+#define PXP2_BLOCK 34
+#define MISC_AEU_BLOCK 35
+
+/* Returns the index of start or end of a specific block stage in ops array*/
+#define BLOCK_OPS_IDX(block, stage, end) \
+ (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end))
struct raw_op {
@@ -118,292 +158,6 @@ union init_op {
struct raw_op raw;
};
-#include "bnx2x_init_values.h"
-
-static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
-static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len);
-
-static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
- u32 len)
-{
- int i;
-
- for (i = 0; i < len; i++) {
- REG_WR(bp, addr + i*4, data[i]);
- if (!(i % 10000)) {
- touch_softlockup_watchdog();
- cpu_relax();
- }
- }
-}
-
-static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
- u16 len)
-{
- int i;
-
- for (i = 0; i < len; i++) {
- REG_WR_IND(bp, addr + i*4, data[i]);
- if (!(i % 10000)) {
- touch_softlockup_watchdog();
- cpu_relax();
- }
- }
-}
-
-static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
-{
- int offset = 0;
-
- if (bp->dmae_ready) {
- while (len > DMAE_LEN32_WR_MAX) {
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, DMAE_LEN32_WR_MAX);
- offset += DMAE_LEN32_WR_MAX * 4;
- len -= DMAE_LEN32_WR_MAX;
- }
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, len);
- } else
- bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
-}
-
-static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
-{
- u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
- u32 buf_len32 = buf_len / 4;
- int i;
-
- memset(bp->gunzip_buf, fill, buf_len);
-
- for (i = 0; i < len; i += buf_len32) {
- u32 cur_len = min(buf_len32, len - i);
-
- bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
- }
-}
-
-static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
- u32 len64)
-{
- u32 buf_len32 = FW_BUF_SIZE / 4;
- u32 len = len64 * 2;
- u64 data64 = 0;
- int i;
-
- /* 64 bit value is in a blob: first low DWORD, then high DWORD */
- data64 = HILO_U64((*(data + 1)), (*data));
- len64 = min((u32)(FW_BUF_SIZE/8), len64);
- for (i = 0; i < len64; i++) {
- u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
-
- *pdata = data64;
- }
-
- for (i = 0; i < len; i += buf_len32) {
- u32 cur_len = min(buf_len32, len - i);
-
- bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
- }
-}
-
-/*********************************************************
- There are different blobs for each PRAM section.
- In addition, each blob write operation is divided into a few operations
- in order to decrease the amount of phys. contiguous buffer needed.
- Thus, when we select a blob the address may be with some offset
- from the beginning of PRAM section.
- The same holds for the INT_TABLE sections.
-**********************************************************/
-#define IF_IS_INT_TABLE_ADDR(base, addr) \
- if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
-
-#define IF_IS_PRAM_ADDR(base, addr) \
- if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
-
-static const u32 *bnx2x_sel_blob(u32 addr, const u32 *data, int is_e1)
-{
- IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
- data = is_e1 ? tsem_int_table_data_e1 :
- tsem_int_table_data_e1h;
- else
- IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
- data = is_e1 ? csem_int_table_data_e1 :
- csem_int_table_data_e1h;
- else
- IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
- data = is_e1 ? usem_int_table_data_e1 :
- usem_int_table_data_e1h;
- else
- IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
- data = is_e1 ? xsem_int_table_data_e1 :
- xsem_int_table_data_e1h;
- else
- IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
- data = is_e1 ? tsem_pram_data_e1 : tsem_pram_data_e1h;
- else
- IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
- data = is_e1 ? csem_pram_data_e1 : csem_pram_data_e1h;
- else
- IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
- data = is_e1 ? usem_pram_data_e1 : usem_pram_data_e1h;
- else
- IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
- data = is_e1 ? xsem_pram_data_e1 : xsem_pram_data_e1h;
-
- return data;
-}
-
-static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
- u32 len, int gunzip, int is_e1, u32 blob_off)
-{
- int offset = 0;
-
- data = bnx2x_sel_blob(addr, data, is_e1) + blob_off;
-
- if (gunzip) {
- int rc;
-#ifdef __BIG_ENDIAN
- int i, size;
- u32 *temp;
-
- temp = kmalloc(len, GFP_KERNEL);
- size = (len / 4) + ((len % 4) ? 1 : 0);
- for (i = 0; i < size; i++)
- temp[i] = swab32(data[i]);
- data = temp;
-#endif
- rc = bnx2x_gunzip(bp, (u8 *)data, len);
- if (rc) {
- BNX2X_ERR("gunzip failed ! rc %d\n", rc);
-#ifdef __BIG_ENDIAN
- kfree(temp);
-#endif
- return;
- }
- len = bp->gunzip_outlen;
-#ifdef __BIG_ENDIAN
- kfree(temp);
- for (i = 0; i < len; i++)
- ((u32 *)bp->gunzip_buf)[i] =
- swab32(((u32 *)bp->gunzip_buf)[i]);
-#endif
- } else {
- if ((len * 4) > FW_BUF_SIZE) {
- BNX2X_ERR("LARGE DMAE OPERATION ! "
- "addr 0x%x len 0x%x\n", addr, len*4);
- return;
- }
- memcpy(bp->gunzip_buf, data, len * 4);
- }
-
- if (bp->dmae_ready) {
- while (len > DMAE_LEN32_WR_MAX) {
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, DMAE_LEN32_WR_MAX);
- offset += DMAE_LEN32_WR_MAX * 4;
- len -= DMAE_LEN32_WR_MAX;
- }
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, len);
- } else
- bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
-}
-
-static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
-{
- int is_e1 = CHIP_IS_E1(bp);
- int is_e1h = CHIP_IS_E1H(bp);
- int is_emul_e1h = (CHIP_REV_IS_EMUL(bp) && is_e1h);
- int hw_wr, i;
- union init_op *op;
- u32 op_type, addr, len;
- const u32 *data, *data_base;
-
- if (CHIP_REV_IS_FPGA(bp))
- hw_wr = OP_WR_FPGA;
- else if (CHIP_REV_IS_EMUL(bp))
- hw_wr = OP_WR_EMUL;
- else
- hw_wr = OP_WR_ASIC;
-
- if (is_e1)
- data_base = init_data_e1;
- else /* CHIP_IS_E1H(bp) */
- data_base = init_data_e1h;
-
- for (i = op_start; i < op_end; i++) {
-
- op = (union init_op *)&(init_ops[i]);
-
- op_type = op->str_wr.op;
- addr = op->str_wr.offset;
- len = op->str_wr.data_len;
- data = data_base + op->str_wr.data_off;
-
- /* careful! it must be in order */
- if (unlikely(op_type > OP_WB)) {
-
- /* If E1 only */
- if (op_type <= OP_WB_E1) {
- if (is_e1)
- op_type -= (OP_RD_E1 - OP_RD);
-
- /* If E1H only */
- } else if (op_type <= OP_WB_E1H) {
- if (is_e1h)
- op_type -= (OP_RD_E1H - OP_RD);
- }
-
- /* HW/EMUL specific */
- if (op_type == hw_wr)
- op_type = OP_WR;
-
- /* EMUL on E1H is special */
- if ((op_type == OP_WR_EMUL_E1H) && is_emul_e1h)
- op_type = OP_WR;
- }
-
- switch (op_type) {
- case OP_RD:
- REG_RD(bp, addr);
- break;
- case OP_WR:
- REG_WR(bp, addr, op->write.val);
- break;
- case OP_SW:
- bnx2x_init_str_wr(bp, addr, data, len);
- break;
- case OP_WB:
- bnx2x_init_wr_wb(bp, addr, data, len, 0, is_e1, 0);
- break;
- case OP_SI:
- bnx2x_init_ind_wr(bp, addr, data, len);
- break;
- case OP_ZR:
- bnx2x_init_fill(bp, addr, 0, op->zero.len);
- break;
- case OP_ZP:
- bnx2x_init_wr_wb(bp, addr, data, len, 1, is_e1,
- op->str_wr.data_off);
- break;
- case OP_WR_64:
- bnx2x_init_wr_64(bp, addr, data, len);
- break;
- default:
- /* happens whenever an op is of a diff HW */
-#if 0
- DP(NETIF_MSG_HW, "skipping init operation "
- "index %d[%d:%d]: type %d addr 0x%x "
- "len %d(0x%x)\n",
- i, op_start, op_end, op_type, addr, len, len);
-#endif
- break;
- }
- }
-}
-
-
/****************************************************************************
* PXP
****************************************************************************/
@@ -567,111 +321,6 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
PXP2_REG_RQ_BW_WR_UBOUND30}
};
-static void bnx2x_init_pxp(struct bnx2x *bp)
-{
- u16 devctl;
- int r_order, w_order;
- u32 val, i;
-
- pci_read_config_word(bp->pdev,
- bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
- DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
- w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
- if (bp->mrrs == -1)
- r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
- else {
- DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
- r_order = bp->mrrs;
- }
-
- if (r_order > MAX_RD_ORD) {
- DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
- r_order, MAX_RD_ORD);
- r_order = MAX_RD_ORD;
- }
- if (w_order > MAX_WR_ORD) {
- DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n",
- w_order, MAX_WR_ORD);
- w_order = MAX_WR_ORD;
- }
- if (CHIP_REV_IS_FPGA(bp)) {
- DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
- w_order = 0;
- }
- DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
-
- for (i = 0; i < NUM_RD_Q-1; i++) {
- REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
- REG_WR(bp, read_arb_addr[i].add,
- read_arb_data[i][r_order].add);
- REG_WR(bp, read_arb_addr[i].ubound,
- read_arb_data[i][r_order].ubound);
- }
-
- for (i = 0; i < NUM_WR_Q-1; i++) {
- if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
- (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
-
- REG_WR(bp, write_arb_addr[i].l,
- write_arb_data[i][w_order].l);
-
- REG_WR(bp, write_arb_addr[i].add,
- write_arb_data[i][w_order].add);
-
- REG_WR(bp, write_arb_addr[i].ubound,
- write_arb_data[i][w_order].ubound);
- } else {
-
- val = REG_RD(bp, write_arb_addr[i].l);
- REG_WR(bp, write_arb_addr[i].l,
- val | (write_arb_data[i][w_order].l << 10));
-
- val = REG_RD(bp, write_arb_addr[i].add);
- REG_WR(bp, write_arb_addr[i].add,
- val | (write_arb_data[i][w_order].add << 10));
-
- val = REG_RD(bp, write_arb_addr[i].ubound);
- REG_WR(bp, write_arb_addr[i].ubound,
- val | (write_arb_data[i][w_order].ubound << 7));
- }
- }
-
- val = write_arb_data[NUM_WR_Q-1][w_order].add;
- val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
- val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
- REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
-
- val = read_arb_data[NUM_RD_Q-1][r_order].add;
- val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
- val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
- REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
-
- REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
- REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
- REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
- REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
-
- if (r_order == MAX_RD_ORD)
- REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
-
- REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
-
- if (CHIP_IS_E1H(bp)) {
- val = ((w_order == 0) ? 2 : 3);
- REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
- REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
- REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
- REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
- REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
- }
-}
-
/****************************************************************************
* CDU
@@ -695,128 +344,12 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
(0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7))
#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80)
-/*****************************************************************************
- * Description:
- * Calculates crc 8 on a word value: polynomial 0-1-2-8
- * Code was translated from Verilog.
- ****************************************************************************/
-static u8 calc_crc8(u32 data, u8 crc)
-{
- u8 D[32];
- u8 NewCRC[8];
- u8 C[8];
- u8 crc_res;
- u8 i;
-
- /* split the data into 31 bits */
- for (i = 0; i < 32; i++) {
- D[i] = data & 1;
- data = data >> 1;
- }
-
- /* split the crc into 8 bits */
- for (i = 0; i < 8; i++) {
- C[i] = crc & 1;
- crc = crc >> 1;
- }
-
- NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
- D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
- C[6] ^ C[7];
- NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
- D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
- D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
- NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
- D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
- C[0] ^ C[1] ^ C[4] ^ C[5];
- NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
- D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
- C[1] ^ C[2] ^ C[5] ^ C[6];
- NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
- D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
- C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
- NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
- D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
- C[3] ^ C[4] ^ C[7];
- NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
- D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
- C[5];
- NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
- D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
- C[6];
-
- crc_res = 0;
- for (i = 0; i < 8; i++)
- crc_res |= (NewCRC[i] << i);
-
- return crc_res;
-}
/* registers addresses are not in order
so these arrays help simplify the code */
-static const int cm_start[E1H_FUNC_MAX][9] = {
- {MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START,
- XCM_FUNC0_START, TSEM_FUNC0_START, USEM_FUNC0_START, CSEM_FUNC0_START,
- XSEM_FUNC0_START},
- {MISC_FUNC1_START, TCM_FUNC1_START, UCM_FUNC1_START, CCM_FUNC1_START,
- XCM_FUNC1_START, TSEM_FUNC1_START, USEM_FUNC1_START, CSEM_FUNC1_START,
- XSEM_FUNC1_START},
- {MISC_FUNC2_START, TCM_FUNC2_START, UCM_FUNC2_START, CCM_FUNC2_START,
- XCM_FUNC2_START, TSEM_FUNC2_START, USEM_FUNC2_START, CSEM_FUNC2_START,
- XSEM_FUNC2_START},
- {MISC_FUNC3_START, TCM_FUNC3_START, UCM_FUNC3_START, CCM_FUNC3_START,
- XCM_FUNC3_START, TSEM_FUNC3_START, USEM_FUNC3_START, CSEM_FUNC3_START,
- XSEM_FUNC3_START},
- {MISC_FUNC4_START, TCM_FUNC4_START, UCM_FUNC4_START, CCM_FUNC4_START,
- XCM_FUNC4_START, TSEM_FUNC4_START, USEM_FUNC4_START, CSEM_FUNC4_START,
- XSEM_FUNC4_START},
- {MISC_FUNC5_START, TCM_FUNC5_START, UCM_FUNC5_START, CCM_FUNC5_START,
- XCM_FUNC5_START, TSEM_FUNC5_START, USEM_FUNC5_START, CSEM_FUNC5_START,
- XSEM_FUNC5_START},
- {MISC_FUNC6_START, TCM_FUNC6_START, UCM_FUNC6_START, CCM_FUNC6_START,
- XCM_FUNC6_START, TSEM_FUNC6_START, USEM_FUNC6_START, CSEM_FUNC6_START,
- XSEM_FUNC6_START},
- {MISC_FUNC7_START, TCM_FUNC7_START, UCM_FUNC7_START, CCM_FUNC7_START,
- XCM_FUNC7_START, TSEM_FUNC7_START, USEM_FUNC7_START, CSEM_FUNC7_START,
- XSEM_FUNC7_START}
-};
-
-static const int cm_end[E1H_FUNC_MAX][9] = {
- {MISC_FUNC0_END, TCM_FUNC0_END, UCM_FUNC0_END, CCM_FUNC0_END,
- XCM_FUNC0_END, TSEM_FUNC0_END, USEM_FUNC0_END, CSEM_FUNC0_END,
- XSEM_FUNC0_END},
- {MISC_FUNC1_END, TCM_FUNC1_END, UCM_FUNC1_END, CCM_FUNC1_END,
- XCM_FUNC1_END, TSEM_FUNC1_END, USEM_FUNC1_END, CSEM_FUNC1_END,
- XSEM_FUNC1_END},
- {MISC_FUNC2_END, TCM_FUNC2_END, UCM_FUNC2_END, CCM_FUNC2_END,
- XCM_FUNC2_END, TSEM_FUNC2_END, USEM_FUNC2_END, CSEM_FUNC2_END,
- XSEM_FUNC2_END},
- {MISC_FUNC3_END, TCM_FUNC3_END, UCM_FUNC3_END, CCM_FUNC3_END,
- XCM_FUNC3_END, TSEM_FUNC3_END, USEM_FUNC3_END, CSEM_FUNC3_END,
- XSEM_FUNC3_END},
- {MISC_FUNC4_END, TCM_FUNC4_END, UCM_FUNC4_END, CCM_FUNC4_END,
- XCM_FUNC4_END, TSEM_FUNC4_END, USEM_FUNC4_END, CSEM_FUNC4_END,
- XSEM_FUNC4_END},
- {MISC_FUNC5_END, TCM_FUNC5_END, UCM_FUNC5_END, CCM_FUNC5_END,
- XCM_FUNC5_END, TSEM_FUNC5_END, USEM_FUNC5_END, CSEM_FUNC5_END,
- XSEM_FUNC5_END},
- {MISC_FUNC6_END, TCM_FUNC6_END, UCM_FUNC6_END, CCM_FUNC6_END,
- XCM_FUNC6_END, TSEM_FUNC6_END, USEM_FUNC6_END, CSEM_FUNC6_END,
- XSEM_FUNC6_END},
- {MISC_FUNC7_END, TCM_FUNC7_END, UCM_FUNC7_END, CCM_FUNC7_END,
- XCM_FUNC7_END, TSEM_FUNC7_END, USEM_FUNC7_END, CSEM_FUNC7_END,
- XSEM_FUNC7_END},
-};
-
-static const int hc_limits[E1H_FUNC_MAX][2] = {
- {HC_FUNC0_START, HC_FUNC0_END},
- {HC_FUNC1_START, HC_FUNC1_END},
- {HC_FUNC2_START, HC_FUNC2_END},
- {HC_FUNC3_START, HC_FUNC3_END},
- {HC_FUNC4_START, HC_FUNC4_END},
- {HC_FUNC5_START, HC_FUNC5_END},
- {HC_FUNC6_START, HC_FUNC6_END},
- {HC_FUNC7_START, HC_FUNC7_END}
+static const int cm_blocks[9] = {
+ MISC_BLOCK, TCM_BLOCK, UCM_BLOCK, CCM_BLOCK, XCM_BLOCK,
+ TSEM_BLOCK, USEM_BLOCK, CSEM_BLOCK, XSEM_BLOCK
};
#endif /* BNX2X_INIT_H */
diff --git a/drivers/net/bnx2x_init_ops.h b/drivers/net/bnx2x_init_ops.h
new file mode 100644
index 000000000000..32552b9366cb
--- /dev/null
+++ b/drivers/net/bnx2x_init_ops.h
@@ -0,0 +1,442 @@
+/* bnx2x_init_ops.h: Broadcom Everest network driver.
+ * Static functions needed during the initialization.
+ * This file is "included" in bnx2x_main.c.
+ *
+ * Copyright (c) 2007-2009 Broadcom 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.
+ *
+ * Maintained by: Eilon Greenstein <eilong@broadcom.com>
+ * Written by: Vladislav Zolotarov <vladz@broadcom.com>
+ */
+#ifndef BNX2X_INIT_OPS_H
+#define BNX2X_INIT_OPS_H
+
+static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
+static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len);
+
+static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
+ u32 len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ REG_WR(bp, addr + i*4, data[i]);
+ if (!(i % 10000)) {
+ touch_softlockup_watchdog();
+ cpu_relax();
+ }
+ }
+}
+
+static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
+ u16 len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ REG_WR_IND(bp, addr + i*4, data[i]);
+ if (!(i % 10000)) {
+ touch_softlockup_watchdog();
+ cpu_relax();
+ }
+ }
+}
+
+static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
+{
+ int offset = 0;
+
+ if (bp->dmae_ready) {
+ while (len > DMAE_LEN32_WR_MAX) {
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, DMAE_LEN32_WR_MAX);
+ offset += DMAE_LEN32_WR_MAX * 4;
+ len -= DMAE_LEN32_WR_MAX;
+ }
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, len);
+ } else
+ bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
+}
+
+static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
+{
+ u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
+ u32 buf_len32 = buf_len / 4;
+ int i;
+
+ memset(bp->gunzip_buf, fill, buf_len);
+
+ for (i = 0; i < len; i += buf_len32) {
+ u32 cur_len = min(buf_len32, len - i);
+
+ bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+ }
+}
+
+static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
+ u32 len64)
+{
+ u32 buf_len32 = FW_BUF_SIZE / 4;
+ u32 len = len64 * 2;
+ u64 data64 = 0;
+ int i;
+
+ /* 64 bit value is in a blob: first low DWORD, then high DWORD */
+ data64 = HILO_U64((*(data + 1)), (*data));
+ len64 = min((u32)(FW_BUF_SIZE/8), len64);
+ for (i = 0; i < len64; i++) {
+ u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
+
+ *pdata = data64;
+ }
+
+ for (i = 0; i < len; i += buf_len32) {
+ u32 cur_len = min(buf_len32, len - i);
+
+ bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+ }
+}
+
+/*********************************************************
+ There are different blobs for each PRAM section.
+ In addition, each blob write operation is divided into a few operations
+ in order to decrease the amount of phys. contiguous buffer needed.
+ Thus, when we select a blob the address may be with some offset
+ from the beginning of PRAM section.
+ The same holds for the INT_TABLE sections.
+**********************************************************/
+#define IF_IS_INT_TABLE_ADDR(base, addr) \
+ if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
+
+#define IF_IS_PRAM_ADDR(base, addr) \
+ if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
+
+static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data)
+{
+ IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
+ data = bp->tsem_int_table_data;
+ else IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
+ data = bp->csem_int_table_data;
+ else IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
+ data = bp->usem_int_table_data;
+ else IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
+ data = bp->xsem_int_table_data;
+ else IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
+ data = bp->tsem_pram_data;
+ else IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
+ data = bp->csem_pram_data;
+ else IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
+ data = bp->usem_pram_data;
+ else IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
+ data = bp->xsem_pram_data;
+
+ return data;
+}
+
+static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
+{
+ int offset = 0;
+
+ if (bp->dmae_ready) {
+ while (len > DMAE_LEN32_WR_MAX) {
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, DMAE_LEN32_WR_MAX);
+ offset += DMAE_LEN32_WR_MAX * 4;
+ len -= DMAE_LEN32_WR_MAX;
+ }
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, len);
+ } else
+ bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
+}
+
+static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
+ u32 len)
+{
+ /* This is needed for NO_ZIP mode, currently supported
+ in little endian mode only */
+ data = (const u32*)bnx2x_sel_blob(bp, addr, (const u8*)data);
+
+ if ((len * 4) > FW_BUF_SIZE) {
+ BNX2X_ERR("LARGE DMAE OPERATION ! "
+ "addr 0x%x len 0x%x\n", addr, len*4);
+ return;
+ }
+ memcpy(bp->gunzip_buf, data, len * 4);
+
+ bnx2x_write_big_buf_wb(bp, addr, len);
+}
+
+static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr,
+ u32 len, u32 blob_off)
+{
+ int rc, i;
+ const u8 *data = NULL;
+
+ data = bnx2x_sel_blob(bp, addr, data) + 4*blob_off;
+
+ if (data == NULL) {
+ panic("Blob not found for addr 0x%x\n", addr);
+ return;
+ }
+
+ rc = bnx2x_gunzip(bp, data, len);
+ if (rc) {
+ BNX2X_ERR("gunzip failed ! addr 0x%x rc %d\n", addr, rc);
+ BNX2X_ERR("blob_offset=0x%x\n", blob_off);
+ return;
+ }
+
+ /* gunzip_outlen is in dwords */
+ len = bp->gunzip_outlen;
+ for (i = 0; i < len; i++)
+ ((u32 *)bp->gunzip_buf)[i] =
+ cpu_to_le32(((u32 *)bp->gunzip_buf)[i]);
+
+ bnx2x_write_big_buf_wb(bp, addr, len);
+}
+
+static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
+{
+ int hw_wr, i;
+ u16 op_start =
+ bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_START)];
+ u16 op_end =
+ bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_END)];
+ union init_op *op;
+ u32 op_type, addr, len;
+ const u32 *data, *data_base;
+
+ /* If empty block */
+ if (op_start == op_end)
+ return;
+
+ if (CHIP_REV_IS_FPGA(bp))
+ hw_wr = OP_WR_FPGA;
+ else if (CHIP_REV_IS_EMUL(bp))
+ hw_wr = OP_WR_EMUL;
+ else
+ hw_wr = OP_WR_ASIC;
+
+ data_base = bp->init_data;
+
+ for (i = op_start; i < op_end; i++) {
+
+ op = (union init_op *)&(bp->init_ops[i]);
+
+ op_type = op->str_wr.op;
+ addr = op->str_wr.offset;
+ len = op->str_wr.data_len;
+ data = data_base + op->str_wr.data_off;
+
+ /* HW/EMUL specific */
+ if (unlikely((op_type > OP_WB) && (op_type == hw_wr)))
+ op_type = OP_WR;
+
+ switch (op_type) {
+ case OP_RD:
+ REG_RD(bp, addr);
+ break;
+ case OP_WR:
+ REG_WR(bp, addr, op->write.val);
+ break;
+ case OP_SW:
+ bnx2x_init_str_wr(bp, addr, data, len);
+ break;
+ case OP_WB:
+ bnx2x_init_wr_wb(bp, addr, data, len);
+ break;
+ case OP_SI:
+ bnx2x_init_ind_wr(bp, addr, data, len);
+ break;
+ case OP_ZR:
+ bnx2x_init_fill(bp, addr, 0, op->zero.len);
+ break;
+ case OP_ZP:
+ bnx2x_init_wr_zp(bp, addr, len,
+ op->str_wr.data_off);
+ break;
+ case OP_WR_64:
+ bnx2x_init_wr_64(bp, addr, data, len);
+ break;
+ default:
+ /* happens whenever an op is of a diff HW */
+#if 0
+ DP(NETIF_MSG_HW, "skipping init operation "
+ "index %d[%d:%d]: type %d addr 0x%x "
+ "len %d(0x%x)\n",
+ i, op_start, op_end, op_type, addr, len, len);
+#endif
+ break;
+ }
+ }
+}
+
+/* PXP */
+static void bnx2x_init_pxp(struct bnx2x *bp)
+{
+ u16 devctl;
+ int r_order, w_order;
+ u32 val, i;
+
+ pci_read_config_word(bp->pdev,
+ bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
+ DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
+ w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+ if (bp->mrrs == -1)
+ r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+ else {
+ DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
+ r_order = bp->mrrs;
+ }
+
+ if (r_order > MAX_RD_ORD) {
+ DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
+ r_order, MAX_RD_ORD);
+ r_order = MAX_RD_ORD;
+ }
+ if (w_order > MAX_WR_ORD) {
+ DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n",
+ w_order, MAX_WR_ORD);
+ w_order = MAX_WR_ORD;
+ }
+ if (CHIP_REV_IS_FPGA(bp)) {
+ DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
+ w_order = 0;
+ }
+ DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
+
+ for (i = 0; i < NUM_RD_Q-1; i++) {
+ REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
+ REG_WR(bp, read_arb_addr[i].add,
+ read_arb_data[i][r_order].add);
+ REG_WR(bp, read_arb_addr[i].ubound,
+ read_arb_data[i][r_order].ubound);
+ }
+
+ for (i = 0; i < NUM_WR_Q-1; i++) {
+ if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
+ (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
+
+ REG_WR(bp, write_arb_addr[i].l,
+ write_arb_data[i][w_order].l);
+
+ REG_WR(bp, write_arb_addr[i].add,
+ write_arb_data[i][w_order].add);
+
+ REG_WR(bp, write_arb_addr[i].ubound,
+ write_arb_data[i][w_order].ubound);
+ } else {
+
+ val = REG_RD(bp, write_arb_addr[i].l);
+ REG_WR(bp, write_arb_addr[i].l,
+ val | (write_arb_data[i][w_order].l << 10));
+
+ val = REG_RD(bp, write_arb_addr[i].add);
+ REG_WR(bp, write_arb_addr[i].add,
+ val | (write_arb_data[i][w_order].add << 10));
+
+ val = REG_RD(bp, write_arb_addr[i].ubound);
+ REG_WR(bp, write_arb_addr[i].ubound,
+ val | (write_arb_data[i][w_order].ubound << 7));
+ }
+ }
+
+ val = write_arb_data[NUM_WR_Q-1][w_order].add;
+ val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
+ val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
+ REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
+
+ val = read_arb_data[NUM_RD_Q-1][r_order].add;
+ val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
+ val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
+ REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
+
+ REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
+ REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
+ REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
+ REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
+
+ if (r_order == MAX_RD_ORD)
+ REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
+
+ REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
+
+ if (CHIP_IS_E1H(bp)) {
+ val = ((w_order == 0) ? 2 : 3);
+ REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
+ REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
+ }
+}
+
+/*****************************************************************************
+ * Description:
+ * Calculates crc 8 on a word value: polynomial 0-1-2-8
+ * Code was translated from Verilog.
+ ****************************************************************************/
+static u8 calc_crc8(u32 data, u8 crc)
+{
+ u8 D[32];
+ u8 NewCRC[8];
+ u8 C[8];
+ u8 crc_res;
+ u8 i;
+
+ /* split the data into 31 bits */
+ for (i = 0; i < 32; i++) {
+ D[i] = data & 1;
+ data = data >> 1;
+ }
+
+ /* split the crc into 8 bits */
+ for (i = 0; i < 8; i++) {
+ C[i] = crc & 1;
+ crc = crc >> 1;
+ }
+
+ NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
+ D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
+ C[6] ^ C[7];
+ NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
+ D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
+ D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
+ NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
+ D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
+ C[0] ^ C[1] ^ C[4] ^ C[5];
+ NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
+ D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
+ C[1] ^ C[2] ^ C[5] ^ C[6];
+ NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
+ D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
+ C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
+ NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
+ D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
+ C[3] ^ C[4] ^ C[7];
+ NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
+ D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
+ C[5];
+ NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
+ D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
+ C[6];
+
+ crc_res = 0;
+ for (i = 0; i < 8; i++)
+ crc_res |= (NewCRC[i] << i);
+
+ return crc_res;
+}
+
+#endif /* BNX2X_INIT_OPS_H */
diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h
deleted file mode 100644
index 1f22c9ab66d4..000000000000
--- a/drivers/net/bnx2x_init_values.h
+++ /dev/null
@@ -1,16322 +0,0 @@
-#ifndef __BNX2X_INIT_VALUES_H__
-#define __BNX2X_INIT_VALUES_H__
-
-/* bnx2x_init_values.h: Broadcom NX2 10G network driver.
- *
- * Copyright (c) 2007-2009 Broadcom 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, except as noted below.
- *
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2007-2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- *
- *
- * This array contains the list of operations needed to initialize the chip.
- *
- * For each block in the chip there are three init stages:
- * common - HW used by both ports,
- * port1 and port2 - initialization for a specific Ethernet port.
- * When a port is opened or closed, the management CPU tells the driver
- * whether to init/disable common HW in addition to the port HW.
- * This way the first port going up will first initializes the common HW,
- * and the last port going down also resets the common HW
- *
- * For each init stage/block there is a list of actions needed in a format:
- * {operation, register, data}
- * where:
- * OP_WR - write a value to the chip.
- * OP_RD - read a register (usually a clear on read register).
- * OP_SW - string write, write a section of consecutive addresses to the chip.
- * OP_SI - copy a string using indirect writes.
- * OP_ZR - clear a range of memory.
- * OP_ZP - unzip and copy using DMAE.
- * OP_WB - string copy using DMAE.
- *
- * The #defines mark the stages.
- *
- */
-
-static const struct raw_op init_ops[] = {
-#define PRS_COMMON_START 0
- {OP_WR, PRS_REG_INC_VALUE, 0xf},
- {OP_WR, PRS_REG_EVENT_ID_1, 0x45},
- {OP_WR, PRS_REG_EVENT_ID_2, 0x84},
- {OP_WR, PRS_REG_EVENT_ID_3, 0x6},
- {OP_WR, PRS_REG_NO_MATCH_EVENT_ID, 0x4},
- {OP_WR, PRS_REG_CM_HDR_TYPE_0, 0x0},
- {OP_WR, PRS_REG_CM_HDR_TYPE_1, 0x12170000},
- {OP_WR, PRS_REG_CM_HDR_TYPE_2, 0x22170000},
- {OP_WR, PRS_REG_CM_HDR_TYPE_3, 0x32170000},
- {OP_ZR, PRS_REG_CM_HDR_TYPE_4, 0x5},
- {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_1, 0x12150000},
- {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_2, 0x22150000},
- {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_3, 0x32150000},
- {OP_ZR, PRS_REG_CM_HDR_LOOPBACK_TYPE_4, 0x4},
- {OP_WR, PRS_REG_CM_NO_MATCH_HDR, 0x2100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_0, 0x100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1, 0x10100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2, 0x20100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3, 0x30100000},
- {OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4},
- {OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x40100000},
- {OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_5, 0x3},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_0, 0x100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_1, 0x12140000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2, 0x22140000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3, 0x32140000},
- {OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4},
- {OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x42140000},
- {OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_5, 0x3},
- {OP_RD, PRS_REG_NUM_OF_PACKETS, 0x0},
- {OP_RD, PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES, 0x0},
- {OP_RD, PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES, 0x0},
- {OP_RD, PRS_REG_NUM_OF_DEAD_CYCLES, 0x0},
- {OP_WR_E1H, PRS_REG_FCOE_TYPE, 0x8906},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_0, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_1, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_2, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_3, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_4, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_5, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_6, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_7, 0xff},
- {OP_WR, PRS_REG_PURE_REGIONS, 0x3e},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_0, 0x0},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_1, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_2, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_3, 0x3f},
- {OP_WR_E1, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0},
- {OP_WR_E1H, PRS_REG_PACKET_REGIONS_TYPE_4, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_5, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_6, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_7, 0x3f},
-#define PRS_COMMON_END 52
-#define SRCH_COMMON_START 52
- {OP_WR_E1H, SRC_REG_E1HMF_ENABLE, 0x1},
-#define SRCH_COMMON_END 53
-#define TSDM_COMMON_START 53
- {OP_WR_E1, TSDM_REG_CFC_RSP_START_ADDR, 0x411},
- {OP_WR_E1H, TSDM_REG_CFC_RSP_START_ADDR, 0x211},
- {OP_WR_E1, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400},
- {OP_WR_E1H, TSDM_REG_CMP_COUNTER_START_ADDR, 0x200},
- {OP_WR_E1, TSDM_REG_Q_COUNTER_START_ADDR, 0x404},
- {OP_WR_E1H, TSDM_REG_Q_COUNTER_START_ADDR, 0x204},
- {OP_WR_E1, TSDM_REG_PCK_END_MSG_START_ADDR, 0x419},
- {OP_WR_E1H, TSDM_REG_PCK_END_MSG_START_ADDR, 0x219},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_0, 0x2},
- {OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_0, 0x20},
- {OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_1, 0x0},
- {OP_WR, TSDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, TSDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_4, 0x7c},
- {OP_ZR_E1H, TSDM_REG_AGG_INT_EVENT_4, 0x1c},
- {OP_WR_E1H, TSDM_REG_AGG_INT_T_0, 0x1},
- {OP_ZR_E1H, TSDM_REG_AGG_INT_T_1, 0x5f},
- {OP_WR, TSDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, TSDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, TSDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, TSDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, TSDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, TSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, TSDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, TSDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, TSDM_REG_TIMER_TICK, 0xa},
-#define TSDM_COMMON_END 96
-#define TCM_COMMON_START 96
- {OP_WR, TCM_REG_XX_MAX_LL_SZ, 0x20},
- {OP_WR, TCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, TCM_REG_TQM_TCM_HDR_P, 0x2150020},
- {OP_WR, TCM_REG_TQM_TCM_HDR_S, 0x2150020},
- {OP_WR, TCM_REG_TM_TCM_HDR, 0x30},
- {OP_WR, TCM_REG_ERR_TCM_HDR, 0x8100000},
- {OP_WR, TCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, TCM_REG_EXPR_EVNT_ID, 0x30},
- {OP_WR, TCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, TCM_REG_STORM_WEIGHT, 0x2},
- {OP_WR, TCM_REG_PRS_WEIGHT, 0x5},
- {OP_WR, TCM_REG_PBF_WEIGHT, 0x6},
- {OP_WR, TCM_REG_USEM_WEIGHT, 0x2},
- {OP_WR, TCM_REG_CSEM_WEIGHT, 0x2},
- {OP_WR, TCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, TCM_REG_TSDM_WEIGHT, 0x5},
- {OP_WR, TCM_REG_TQM_P_WEIGHT, 0x2},
- {OP_WR, TCM_REG_TQM_S_WEIGHT, 0x2},
- {OP_WR, TCM_REG_TM_WEIGHT, 0x2},
- {OP_WR, TCM_REG_TCM_TQM_USE_Q, 0x1},
- {OP_WR, TCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, TCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, TCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, TCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, TCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, TCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, TCM_REG_TQM_INIT_CRD, 0x20},
- {OP_WR, TCM_REG_XX_INIT_CRD, 0x13},
- {OP_WR, TCM_REG_XX_MSG_NUM, 0x20},
- {OP_ZR, TCM_REG_XX_TABLE, 0xa},
- {OP_SW, TCM_REG_XX_DESCR_TABLE, 0x200000},
- {OP_WR, TCM_REG_N_SM_CTX_LD_0, 0x7},
- {OP_WR, TCM_REG_N_SM_CTX_LD_1, 0x7},
- {OP_WR, TCM_REG_N_SM_CTX_LD_2, 0x8},
- {OP_WR, TCM_REG_N_SM_CTX_LD_3, 0x8},
- {OP_ZR_E1, TCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR_E1H, TCM_REG_N_SM_CTX_LD_4, 0x1},
- {OP_ZR_E1H, TCM_REG_N_SM_CTX_LD_5, 0x3},
- {OP_WR, TCM_REG_TCM_REG0_SZ, 0x6},
- {OP_WR_E1, TCM_REG_PHYS_QNUM0_0, 0xd},
- {OP_WR_E1, TCM_REG_PHYS_QNUM0_1, 0x2d},
- {OP_WR_E1, TCM_REG_PHYS_QNUM1_0, 0x7},
- {OP_WR_E1, TCM_REG_PHYS_QNUM1_1, 0x27},
- {OP_WR_E1, TCM_REG_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1, TCM_REG_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1, TCM_REG_PHYS_QNUM3_0, 0x7},
- {OP_WR_E1, TCM_REG_PHYS_QNUM3_1, 0x27},
- {OP_WR, TCM_REG_TCM_STORM0_IFEN, 0x1},
- {OP_WR, TCM_REG_TCM_STORM1_IFEN, 0x1},
- {OP_WR, TCM_REG_TCM_TQM_IFEN, 0x1},
- {OP_WR, TCM_REG_STORM_TCM_IFEN, 0x1},
- {OP_WR, TCM_REG_TQM_TCM_IFEN, 0x1},
- {OP_WR, TCM_REG_TSDM_IFEN, 0x1},
- {OP_WR, TCM_REG_TM_TCM_IFEN, 0x1},
- {OP_WR, TCM_REG_PRS_IFEN, 0x1},
- {OP_WR, TCM_REG_PBF_IFEN, 0x1},
- {OP_WR, TCM_REG_USEM_IFEN, 0x1},
- {OP_WR, TCM_REG_CSEM_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, TCM_REG_TCM_CFC_IFEN, 0x1},
-#define TCM_COMMON_END 159
-#define TCM_FUNC0_START 159
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0xd},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x7},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x7},
-#define TCM_FUNC0_END 163
-#define TCM_FUNC1_START 163
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x2d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x27},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x27},
-#define TCM_FUNC1_END 167
-#define TCM_FUNC2_START 167
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x1d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x17},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x17},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x17},
-#define TCM_FUNC2_END 171
-#define TCM_FUNC3_START 171
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x3d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x37},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x37},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x37},
-#define TCM_FUNC3_END 175
-#define TCM_FUNC4_START 175
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x4d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x47},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x47},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x47},
-#define TCM_FUNC4_END 179
-#define TCM_FUNC5_START 179
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x6d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x67},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x67},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x67},
-#define TCM_FUNC5_END 183
-#define TCM_FUNC6_START 183
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x5d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x57},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x57},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x57},
-#define TCM_FUNC6_END 187
-#define TCM_FUNC7_START 187
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x7d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x77},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x77},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x77},
-#define TCM_FUNC7_END 191
-#define BRB1_COMMON_START 191
- {OP_SW, BRB1_REG_LL_RAM, 0x2000020},
- {OP_WR, BRB1_REG_SOFT_RESET, 0x1},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_4, 0x0},
- {OP_SW, BRB1_REG_FREE_LIST_PRS_CRDT, 0x30220},
- {OP_WR, BRB1_REG_SOFT_RESET, 0x0},
-#define BRB1_COMMON_END 196
-#define BRB1_PORT0_START 196
- {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0xb8},
- {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 0x114},
- {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0},
-#define BRB1_PORT0_END 200
-#define BRB1_PORT1_START 200
- {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0xb8},
- {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 0x114},
- {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0},
-#define BRB1_PORT1_END 204
-#define TSEM_COMMON_START 204
- {OP_RD, TSEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, TSEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, TSEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, TSEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, TSEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, TSEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, TSEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, TSEM_REG_TS_0_AS, 0x0},
- {OP_WR, TSEM_REG_TS_1_AS, 0x1},
- {OP_WR, TSEM_REG_TS_2_AS, 0x4},
- {OP_WR, TSEM_REG_TS_3_AS, 0x0},
- {OP_WR, TSEM_REG_TS_4_AS, 0x1},
- {OP_WR, TSEM_REG_TS_5_AS, 0x3},
- {OP_WR, TSEM_REG_TS_6_AS, 0x0},
- {OP_WR, TSEM_REG_TS_7_AS, 0x1},
- {OP_WR, TSEM_REG_TS_8_AS, 0x4},
- {OP_WR, TSEM_REG_TS_9_AS, 0x0},
- {OP_WR, TSEM_REG_TS_10_AS, 0x1},
- {OP_WR, TSEM_REG_TS_11_AS, 0x3},
- {OP_WR, TSEM_REG_TS_12_AS, 0x0},
- {OP_WR, TSEM_REG_TS_13_AS, 0x1},
- {OP_WR, TSEM_REG_TS_14_AS, 0x4},
- {OP_WR, TSEM_REG_TS_15_AS, 0x0},
- {OP_WR, TSEM_REG_TS_16_AS, 0x4},
- {OP_WR, TSEM_REG_TS_17_AS, 0x3},
- {OP_ZR, TSEM_REG_TS_18_AS, 0x2},
- {OP_WR, TSEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, TSEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, TSEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, TSEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, TSEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, TSEM_REG_THREADS_LIST, 0xff},
- {OP_ZR, TSEM_REG_PASSIVE_BUFFER, 0x400},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18000, 0x34},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18040, 0x18},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18080, 0xc},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x180c0, 0x20},
- {OP_WR_ASIC, TSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
- {OP_WR_EMUL, TSEM_REG_FAST_MEMORY + 0x18300, 0x138},
- {OP_WR_FPGA, TSEM_REG_FAST_MEMORY + 0x18300, 0x1388},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2000, 0xb2},
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x23c8, 0xc1},
- {OP_WR_EMUL_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x23c8 + 0x304, 0x10223},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1000, 0x2b3},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x1000 + 0xacc, 0x10223},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa020, 0xc8},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c18, 0x4},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa000, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c10, 0x2},
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad0, 0x0},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad8, 0x4},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3678, 0x6},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x810, 0x4},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3670, 0x2},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x40224},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x4cb0, 0x80228},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5008, 0x4},
- {OP_ZP_E1, TSEM_REG_INT_TABLE, 0x930000},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5018, 0x4},
- {OP_WR_64_E1, TSEM_REG_INT_TABLE + 0x360, 0x140230},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM, 0x324f0000},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5038, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33250c94},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5048, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xe4d195e},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5058, 0x4},
- {OP_WR_64_E1, TSEM_REG_PRAM + 0x11e00, 0x5c400232},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5068, 0x4},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5078, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x62c0, 0x200224},
- {OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x9b0000},
- {OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x398, 0xd0244},
- {OP_ZP_E1H, TSEM_REG_PRAM, 0x325e0000},
- {OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x35960c98},
- {OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0x1aea19fe},
- {OP_WR_64_E1H, TSEM_REG_PRAM + 0x143d0, 0x57860246},
-#define TSEM_COMMON_END 297
-#define TSEM_PORT0_START 297
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x22c8, 0x20},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x2000, 0x16c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x4000, 0x16c},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb000, 0x28},
- {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b60, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb140, 0xc},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1400, 0xa},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32c0, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1450, 0x6},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3350, 0x64},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8108, 0x2},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x8, 0x50234},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x1c, 0x7},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1570, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x9c0, 0x4c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x820, 0xe},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20239},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2908, 0x2},
-#define TSEM_PORT0_END 317
-#define TSEM_PORT1_START 317
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2348, 0x20},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x25b0, 0x16c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x45b0, 0x16c},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb0a0, 0x28},
- {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b64, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb170, 0xc},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1428, 0xa},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3308, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1468, 0x6},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x34e0, 0x64},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8110, 0x2},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x8, 0x5023b},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x1c, 0x7},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x15b8, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0xaf0, 0x4c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x858, 0xe},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20240},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2910, 0x2},
-#define TSEM_PORT1_END 337
-#define TSEM_FUNC0_START 337
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b60, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x8, 0x50248},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31c0, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5080, 0x12},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
-#define TSEM_FUNC0_END 345
-#define TSEM_FUNC1_START 345
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b64, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x8, 0x5024d},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31e0, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5010, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x50c8, 0x12},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
-#define TSEM_FUNC1_END 353
-#define TSEM_FUNC2_START 353
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b68, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x8, 0x50252},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3200, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5020, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5110, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4010, 0x20257},
-#define TSEM_FUNC2_END 361
-#define TSEM_FUNC3_START 361
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b6c, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x8, 0x50259},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3220, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5030, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5158, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4018, 0x2025e},
-#define TSEM_FUNC3_END 369
-#define TSEM_FUNC4_START 369
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b70, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x8, 0x50260},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3240, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5040, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51a0, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4020, 0x20265},
-#define TSEM_FUNC4_END 377
-#define TSEM_FUNC5_START 377
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b74, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x8, 0x50267},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3260, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5050, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51e8, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4028, 0x2026c},
-#define TSEM_FUNC5_END 385
-#define TSEM_FUNC6_START 385
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b78, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x8, 0x5026e},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3280, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5060, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5230, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4030, 0x20273},
-#define TSEM_FUNC6_END 393
-#define TSEM_FUNC7_START 393
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b7c, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x8, 0x50275},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32a0, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5070, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5278, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4038, 0x2027a},
-#define TSEM_FUNC7_END 401
-#define MISC_COMMON_START 401
- {OP_WR_E1, MISC_REG_GRC_TIMEOUT_EN, 0x1},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_1, 0x71d2911},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_2, 0x0},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_3, 0x9c0424},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_4, 0x0},
- {OP_WR, MISC_REG_LCPLL_CTRL_1, 0x209},
- {OP_WR_E1, MISC_REG_SPIO, 0xff000000},
-#define MISC_COMMON_END 408
-#define MISC_FUNC0_START 408
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC0_END 409
-#define MISC_FUNC1_START 409
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC1_END 410
-#define MISC_FUNC2_START 410
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC2_END 411
-#define MISC_FUNC3_START 411
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC3_END 412
-#define MISC_FUNC4_START 412
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC4_END 413
-#define MISC_FUNC5_START 413
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC5_END 414
-#define MISC_FUNC6_START 414
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC6_END 415
-#define MISC_FUNC7_START 415
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC7_END 416
-#define NIG_COMMON_START 416
- {OP_WR, NIG_REG_PBF_LB_IN_EN, 0x1},
- {OP_WR, NIG_REG_PRS_REQ_IN_EN, 0x1},
- {OP_WR, NIG_REG_EGRESS_DEBUG_IN_EN, 0x1},
- {OP_WR, NIG_REG_BRB_LB_OUT_EN, 0x1},
- {OP_WR, NIG_REG_PRS_EOP_OUT_EN, 0x1},
-#define NIG_COMMON_END 421
-#define NIG_PORT0_START 421
- {OP_WR, NIG_REG_LLH0_CM_HEADER, 0x300000},
- {OP_WR, NIG_REG_LLH0_EVENT_ID, 0x28},
- {OP_WR, NIG_REG_LLH0_ERROR_MASK, 0x0},
- {OP_WR, NIG_REG_LLH0_XCM_MASK, 0x4},
- {OP_WR, NIG_REG_LLH0_BRB1_NOT_MCP, 0x1},
- {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT0, 0x0},
- {OP_WR_E1H, NIG_REG_LLH0_CLS_TYPE, 0x1},
- {OP_WR, NIG_REG_LLH0_XCM_INIT_CREDIT, 0x30},
- {OP_WR, NIG_REG_BRB0_PAUSE_IN_EN, 0x1},
- {OP_WR, NIG_REG_EGRESS_PBF0_IN_EN, 0x1},
- {OP_WR, NIG_REG_BRB0_OUT_EN, 0x1},
- {OP_WR, NIG_REG_XCM0_OUT_EN, 0x1},
-#define NIG_PORT0_END 433
-#define NIG_PORT1_START 433
- {OP_WR, NIG_REG_LLH1_CM_HEADER, 0x300000},
- {OP_WR, NIG_REG_LLH1_EVENT_ID, 0x28},
- {OP_WR, NIG_REG_LLH1_ERROR_MASK, 0x0},
- {OP_WR, NIG_REG_LLH1_XCM_MASK, 0x4},
- {OP_WR, NIG_REG_LLH1_BRB1_NOT_MCP, 0x1},
- {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT1, 0x0},
- {OP_WR_E1H, NIG_REG_LLH1_CLS_TYPE, 0x1},
- {OP_WR, NIG_REG_LLH1_XCM_INIT_CREDIT, 0x30},
- {OP_WR, NIG_REG_BRB1_PAUSE_IN_EN, 0x1},
- {OP_WR, NIG_REG_EGRESS_PBF1_IN_EN, 0x1},
- {OP_WR, NIG_REG_BRB1_OUT_EN, 0x1},
- {OP_WR, NIG_REG_XCM1_OUT_EN, 0x1},
-#define NIG_PORT1_END 445
-#define UPB_COMMON_START 445
- {OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20},
-#define UPB_COMMON_END 446
-#define CSDM_COMMON_START 446
- {OP_WR_E1, CSDM_REG_CFC_RSP_START_ADDR, 0xa11},
- {OP_WR_E1H, CSDM_REG_CFC_RSP_START_ADDR, 0x211},
- {OP_WR_E1, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
- {OP_WR_E1H, CSDM_REG_CMP_COUNTER_START_ADDR, 0x200},
- {OP_WR_E1, CSDM_REG_Q_COUNTER_START_ADDR, 0xa04},
- {OP_WR_E1H, CSDM_REG_Q_COUNTER_START_ADDR, 0x204},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_0, 0xc6},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_1, 0x0},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR, CSDM_REG_AGG_INT_EVENT_4, 0x1c},
- {OP_WR, CSDM_REG_AGG_INT_T_0, 0x1},
- {OP_ZR, CSDM_REG_AGG_INT_T_1, 0x5f},
- {OP_WR, CSDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, CSDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, CSDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, CSDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, CSDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, CSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, CSDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, CSDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, CSDM_REG_TIMER_TICK, 0xa},
-#define CSDM_COMMON_END 485
-#define USDM_COMMON_START 485
- {OP_WR_E1, USDM_REG_CFC_RSP_START_ADDR, 0xa11},
- {OP_WR_E1H, USDM_REG_CFC_RSP_START_ADDR, 0x411},
- {OP_WR_E1, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
- {OP_WR_E1H, USDM_REG_CMP_COUNTER_START_ADDR, 0x400},
- {OP_WR_E1, USDM_REG_Q_COUNTER_START_ADDR, 0xa04},
- {OP_WR_E1H, USDM_REG_Q_COUNTER_START_ADDR, 0x404},
- {OP_WR_E1, USDM_REG_PCK_END_MSG_START_ADDR, 0xa21},
- {OP_WR_E1H, USDM_REG_PCK_END_MSG_START_ADDR, 0x421},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_WR, USDM_REG_AGG_INT_EVENT_0, 0x46},
- {OP_WR, USDM_REG_AGG_INT_EVENT_1, 0x5},
- {OP_WR, USDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, USDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR_E1, USDM_REG_AGG_INT_EVENT_4, 0x5c},
- {OP_WR_E1H, USDM_REG_AGG_INT_EVENT_4, 0x7},
- {OP_ZR_E1H, USDM_REG_AGG_INT_EVENT_5, 0x5b},
- {OP_WR, USDM_REG_AGG_INT_MODE_0, 0x1},
- {OP_ZR_E1, USDM_REG_AGG_INT_MODE_1, 0x1f},
- {OP_ZR_E1H, USDM_REG_AGG_INT_MODE_1, 0x3},
- {OP_WR_E1H, USDM_REG_AGG_INT_MODE_4, 0x1},
- {OP_ZR_E1H, USDM_REG_AGG_INT_MODE_5, 0x1b},
- {OP_WR, USDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, USDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, USDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, USDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, USDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q2_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, USDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, USDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, USDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, USDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, USDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, USDM_REG_TIMER_TICK, 0xa},
-#define USDM_COMMON_END 532
-#define CCM_COMMON_START 532
- {OP_WR, CCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, CCM_REG_CQM_CCM_HDR_P, 0x2150020},
- {OP_WR, CCM_REG_CQM_CCM_HDR_S, 0x2150020},
- {OP_WR, CCM_REG_ERR_CCM_HDR, 0x8100000},
- {OP_WR, CCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, CCM_REG_STORM_WEIGHT, 0x2},
- {OP_WR, CCM_REG_TSEM_WEIGHT, 0x0},
- {OP_WR, CCM_REG_XSEM_WEIGHT, 0x5},
- {OP_WR, CCM_REG_USEM_WEIGHT, 0x5},
- {OP_ZR, CCM_REG_PBF_WEIGHT, 0x2},
- {OP_WR, CCM_REG_CSDM_WEIGHT, 0x2},
- {OP_WR, CCM_REG_CQM_P_WEIGHT, 0x3},
- {OP_WR, CCM_REG_CQM_S_WEIGHT, 0x2},
- {OP_WR, CCM_REG_CCM_CQM_USE_Q, 0x1},
- {OP_WR, CCM_REG_CNT_AUX1_Q, 0x2},
- {OP_WR, CCM_REG_CNT_AUX2_Q, 0x2},
- {OP_WR, CCM_REG_INV_DONE_Q, 0x1},
- {OP_WR, CCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, CCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, CCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, CCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, CCM_REG_CQM_INIT_CRD, 0x20},
- {OP_WR, CCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, CCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, CCM_REG_XX_INIT_CRD, 0x3},
- {OP_WR, CCM_REG_XX_MSG_NUM, 0x18},
- {OP_ZR, CCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, CCM_REG_XX_DESCR_TABLE, 0x240242},
- {OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x24027c},
- {OP_WR, CCM_REG_N_SM_CTX_LD_0, 0x1},
- {OP_WR, CCM_REG_N_SM_CTX_LD_1, 0x2},
- {OP_WR, CCM_REG_N_SM_CTX_LD_2, 0x8},
- {OP_WR, CCM_REG_N_SM_CTX_LD_3, 0x8},
- {OP_ZR, CCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR, CCM_REG_CCM_REG0_SZ, 0x4},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_0, 0x7},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_1, 0x27},
- {OP_WR_E1, CCM_REG_PHYS_QNUM1_0, 0xc},
- {OP_WR_E1, CCM_REG_PHYS_QNUM1_1, 0x2c},
- {OP_WR_E1, CCM_REG_PHYS_QNUM2_0, 0xc},
- {OP_WR_E1, CCM_REG_PHYS_QNUM2_1, 0x2c},
- {OP_WR_E1, CCM_REG_PHYS_QNUM3_0, 0xc},
- {OP_WR_E1, CCM_REG_PHYS_QNUM3_1, 0x2c},
- {OP_WR, CCM_REG_CCM_STORM0_IFEN, 0x1},
- {OP_WR, CCM_REG_CCM_STORM1_IFEN, 0x1},
- {OP_WR, CCM_REG_CCM_CQM_IFEN, 0x1},
- {OP_WR, CCM_REG_STORM_CCM_IFEN, 0x1},
- {OP_WR, CCM_REG_CQM_CCM_IFEN, 0x1},
- {OP_WR, CCM_REG_CSDM_IFEN, 0x1},
- {OP_WR, CCM_REG_TSEM_IFEN, 0x1},
- {OP_WR, CCM_REG_XSEM_IFEN, 0x1},
- {OP_WR, CCM_REG_USEM_IFEN, 0x1},
- {OP_WR, CCM_REG_PBF_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, CCM_REG_CCM_CFC_IFEN, 0x1},
-#define CCM_COMMON_END 596
-#define CCM_FUNC0_START 596
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x7},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0xc},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0xb},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x7},
-#define CCM_FUNC0_END 603
-#define CCM_FUNC1_START 603
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x27},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x2c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x2b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x27},
-#define CCM_FUNC1_END 610
-#define CCM_FUNC2_START 610
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x19},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x1a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x17},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x17},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x1c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x1b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x17},
-#define CCM_FUNC2_END 617
-#define CCM_FUNC3_START 617
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x39},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x3a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x37},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x37},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x3c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x3b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x37},
-#define CCM_FUNC3_END 624
-#define CCM_FUNC4_START 624
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x49},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x4a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x47},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x47},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x4c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x4b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x47},
-#define CCM_FUNC4_END 631
-#define CCM_FUNC5_START 631
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x69},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x6a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x67},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x67},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x6c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x6b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x67},
-#define CCM_FUNC5_END 638
-#define CCM_FUNC6_START 638
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x59},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x5a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x57},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x57},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x5c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x5b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x57},
-#define CCM_FUNC6_END 645
-#define CCM_FUNC7_START 645
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x79},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x7a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x77},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x77},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x7c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x7b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x77},
-#define CCM_FUNC7_END 652
-#define UCM_COMMON_START 652
- {OP_WR, UCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, UCM_REG_UQM_UCM_HDR_P, 0x2150020},
- {OP_WR, UCM_REG_UQM_UCM_HDR_S, 0x2150020},
- {OP_WR, UCM_REG_TM_UCM_HDR, 0x30},
- {OP_WR, UCM_REG_ERR_UCM_HDR, 0x8100000},
- {OP_WR, UCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, UCM_REG_EXPR_EVNT_ID, 0x30},
- {OP_WR, UCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, UCM_REG_STORM_WEIGHT, 0x2},
- {OP_WR, UCM_REG_TSEM_WEIGHT, 0x4},
- {OP_WR, UCM_REG_CSEM_WEIGHT, 0x0},
- {OP_WR, UCM_REG_XSEM_WEIGHT, 0x2},
- {OP_WR, UCM_REG_DORQ_WEIGHT, 0x2},
- {OP_WR, UCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, UCM_REG_USDM_WEIGHT, 0x2},
- {OP_WR, UCM_REG_UQM_P_WEIGHT, 0x7},
- {OP_WR, UCM_REG_UQM_S_WEIGHT, 0x2},
- {OP_WR, UCM_REG_TM_WEIGHT, 0x2},
- {OP_WR, UCM_REG_UCM_UQM_USE_Q, 0x1},
- {OP_WR, UCM_REG_INV_CFLG_Q, 0x1},
- {OP_WR, UCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, UCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, UCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, UCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, UCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, UCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, UCM_REG_TM_INIT_CRD, 0x4},
- {OP_WR, UCM_REG_UQM_INIT_CRD, 0x20},
- {OP_WR, UCM_REG_XX_INIT_CRD, 0xe},
- {OP_WR, UCM_REG_XX_MSG_NUM, 0x1b},
- {OP_ZR, UCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, UCM_REG_XX_DESCR_TABLE, 0x1b0266},
- {OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b02a0},
- {OP_WR, UCM_REG_N_SM_CTX_LD_0, 0x10},
- {OP_WR, UCM_REG_N_SM_CTX_LD_1, 0x7},
- {OP_WR, UCM_REG_N_SM_CTX_LD_2, 0xf},
- {OP_WR, UCM_REG_N_SM_CTX_LD_3, 0x10},
- {OP_ZR_E1, UCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR_E1H, UCM_REG_N_SM_CTX_LD_4, 0xb},
- {OP_ZR_E1H, UCM_REG_N_SM_CTX_LD_5, 0x3},
- {OP_WR, UCM_REG_UCM_REG0_SZ, 0x3},
- {OP_WR_E1, UCM_REG_PHYS_QNUM0_0, 0xf},
- {OP_WR_E1, UCM_REG_PHYS_QNUM0_1, 0x2f},
- {OP_WR_E1, UCM_REG_PHYS_QNUM1_0, 0xe},
- {OP_WR_E1, UCM_REG_PHYS_QNUM1_1, 0x2e},
- {OP_WR, UCM_REG_UCM_STORM0_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_STORM1_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_UQM_IFEN, 0x1},
- {OP_WR, UCM_REG_STORM_UCM_IFEN, 0x1},
- {OP_WR, UCM_REG_UQM_UCM_IFEN, 0x1},
- {OP_WR, UCM_REG_USDM_IFEN, 0x1},
- {OP_WR, UCM_REG_TM_UCM_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_TM_IFEN, 0x1},
- {OP_WR, UCM_REG_TSEM_IFEN, 0x1},
- {OP_WR, UCM_REG_CSEM_IFEN, 0x1},
- {OP_WR, UCM_REG_XSEM_IFEN, 0x1},
- {OP_WR, UCM_REG_DORQ_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_CFC_IFEN, 0x1},
-#define UCM_COMMON_END 714
-#define UCM_FUNC0_START 714
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0xf},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0xe},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC0_END 718
-#define UCM_FUNC1_START 718
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x2f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x2e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC1_END 722
-#define UCM_FUNC2_START 722
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x1f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x1e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC2_END 726
-#define UCM_FUNC3_START 726
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x3f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x3e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC3_END 730
-#define UCM_FUNC4_START 730
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x4f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x4e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC4_END 734
-#define UCM_FUNC5_START 734
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x6f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x6e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC5_END 738
-#define UCM_FUNC6_START 738
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x5f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x5e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC6_END 742
-#define UCM_FUNC7_START 742
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x7f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x7e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC7_END 746
-#define USEM_COMMON_START 746
- {OP_RD, USEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, USEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, USEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, USEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, USEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, USEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, USEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, USEM_REG_TS_0_AS, 0x0},
- {OP_WR, USEM_REG_TS_1_AS, 0x1},
- {OP_WR, USEM_REG_TS_2_AS, 0x4},
- {OP_WR, USEM_REG_TS_3_AS, 0x0},
- {OP_WR, USEM_REG_TS_4_AS, 0x1},
- {OP_WR, USEM_REG_TS_5_AS, 0x3},
- {OP_WR, USEM_REG_TS_6_AS, 0x0},
- {OP_WR, USEM_REG_TS_7_AS, 0x1},
- {OP_WR, USEM_REG_TS_8_AS, 0x4},
- {OP_WR, USEM_REG_TS_9_AS, 0x0},
- {OP_WR, USEM_REG_TS_10_AS, 0x1},
- {OP_WR, USEM_REG_TS_11_AS, 0x3},
- {OP_WR, USEM_REG_TS_12_AS, 0x0},
- {OP_WR, USEM_REG_TS_13_AS, 0x1},
- {OP_WR, USEM_REG_TS_14_AS, 0x4},
- {OP_WR, USEM_REG_TS_15_AS, 0x0},
- {OP_WR, USEM_REG_TS_16_AS, 0x4},
- {OP_WR, USEM_REG_TS_17_AS, 0x3},
- {OP_ZR, USEM_REG_TS_18_AS, 0x2},
- {OP_WR, USEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, USEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, USEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, USEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, USEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, USEM_REG_THREADS_LIST, 0xffff},
- {OP_ZR, USEM_REG_PASSIVE_BUFFER, 0x800},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18000, 0x1a},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18040, 0x4e},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18080, 0x10},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x180c0, 0x20},
- {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
- {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18300, 0x138},
- {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18300, 0x1388},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
- {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
- {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5000, 0xc2},
- {OP_WR_EMUL_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2000, 0x102},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4640, 0x40},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8980, 0xc8},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57f0, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8960, 0x2},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d8, 0x5},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3228, 0x4},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d8 + 0x14, 0x10281},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3200, 0x9},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1c60, 0x20},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3200 + 0x24, 0x102bb},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x20282},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x400},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x102bc},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0xc, 0x3},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b68, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x202bd},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b10, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x202bf},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x100284},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x1002c1},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x100294},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002d1},
- {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc30000},
- {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xd20000},
- {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x1302a4},
- {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x3a8, 0xb02e1},
- {OP_ZP_E1, USEM_REG_PRAM, 0x314c0000},
- {OP_ZP_E1H, USEM_REG_PRAM, 0x31b60000},
- {OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x35ef0c53},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x36500c6e},
- {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x361319cf},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x37591a02},
- {OP_ZP_E1, USEM_REG_PRAM + 0x18000, 0x7112754},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x286127d9},
- {OP_WR_64_E1, USEM_REG_PRAM + 0x18ee0, 0x4e2402a6},
- {OP_WR_64_E1H, USEM_REG_PRAM + 0x1ff40, 0x401802e3},
-#define USEM_COMMON_END 842
-#define USEM_PORT0_START 842
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1400, 0xa0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9000, 0xa0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0x10},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x40},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1980, 0x30},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9700, 0x3c},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4740, 0xb4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2450, 0xb4},
- {OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d90, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad0, 0x2},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b40, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3080, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b60, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x12c},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5318, 0x98},
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x3238, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5200, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5300, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5400, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5500, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5600, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5700, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5800, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5900, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b78, 0x52},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e08, 0xc},
-#define USEM_PORT0_END 876
-#define USEM_PORT1_START 876
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1680, 0xa0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9280, 0xa0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1940, 0x10},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9600, 0x40},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a40, 0x30},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x97f0, 0x3c},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4a10, 0xb4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2720, 0xb4},
- {OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d94, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad8, 0x2},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b50, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3100, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1be0, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x84b0, 0x12c},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5578, 0x98},
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x323c, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5080, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5280, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5380, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5480, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5580, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5680, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5780, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5880, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5980, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6cc0, 0x52},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e38, 0xc},
-#define USEM_PORT1_END 910
-#define USEM_FUNC0_START 910
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a30, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3000, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4018, 0x2},
-#define USEM_FUNC0_END 913
-#define USEM_FUNC1_START 913
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a34, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3010, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4028, 0x2},
-#define USEM_FUNC1_END 916
-#define USEM_FUNC2_START 916
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a38, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3020, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4038, 0x2},
-#define USEM_FUNC2_END 919
-#define USEM_FUNC3_START 919
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a3c, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3030, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4048, 0x2},
-#define USEM_FUNC3_END 922
-#define USEM_FUNC4_START 922
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a40, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3040, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4058, 0x2},
-#define USEM_FUNC4_END 925
-#define USEM_FUNC5_START 925
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a44, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3050, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4068, 0x2},
-#define USEM_FUNC5_END 928
-#define USEM_FUNC6_START 928
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a48, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3060, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4078, 0x2},
-#define USEM_FUNC6_END 931
-#define USEM_FUNC7_START 931
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a4c, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3070, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4088, 0x2},
-#define USEM_FUNC7_END 934
-#define CSEM_COMMON_START 934
- {OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, CSEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, CSEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, CSEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, CSEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, CSEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, CSEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, CSEM_REG_TS_0_AS, 0x0},
- {OP_WR, CSEM_REG_TS_1_AS, 0x1},
- {OP_WR, CSEM_REG_TS_2_AS, 0x4},
- {OP_WR, CSEM_REG_TS_3_AS, 0x0},
- {OP_WR, CSEM_REG_TS_4_AS, 0x1},
- {OP_WR, CSEM_REG_TS_5_AS, 0x3},
- {OP_WR, CSEM_REG_TS_6_AS, 0x0},
- {OP_WR, CSEM_REG_TS_7_AS, 0x1},
- {OP_WR, CSEM_REG_TS_8_AS, 0x4},
- {OP_WR, CSEM_REG_TS_9_AS, 0x0},
- {OP_WR, CSEM_REG_TS_10_AS, 0x1},
- {OP_WR, CSEM_REG_TS_11_AS, 0x3},
- {OP_WR, CSEM_REG_TS_12_AS, 0x0},
- {OP_WR, CSEM_REG_TS_13_AS, 0x1},
- {OP_WR, CSEM_REG_TS_14_AS, 0x4},
- {OP_WR, CSEM_REG_TS_15_AS, 0x0},
- {OP_WR, CSEM_REG_TS_16_AS, 0x4},
- {OP_WR, CSEM_REG_TS_17_AS, 0x3},
- {OP_ZR, CSEM_REG_TS_18_AS, 0x2},
- {OP_WR, CSEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, CSEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, CSEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, CSEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, CSEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, CSEM_REG_THREADS_LIST, 0xffff},
- {OP_ZR, CSEM_REG_PASSIVE_BUFFER, 0x800},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18000, 0x10},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18040, 0x12},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18080, 0x30},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x180c0, 0xe},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x5000, 0x42},
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_WR_EMUL_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x1000, 0x42},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2000, 0xc0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7020, 0xc8},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3070, 0x80},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7000, 0x2},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x4280, 0x4},
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11e8, 0x0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3000, 0xc0},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a8},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4070, 0x80},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x5280, 0x4},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6700, 0x100},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x9000, 0x400},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b08, 0x2002e5},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002b0},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x100305},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002c0},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x100315},
- {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x710000},
- {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x740000},
- {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002d0},
- {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x100325},
- {OP_ZP_E1, CSEM_REG_PRAM, 0x32290000},
- {OP_ZP_E1H, CSEM_REG_PRAM, 0x32260000},
- {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x23630c8b},
- {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x246e0c8a},
- {OP_WR_64_E1, CSEM_REG_PRAM + 0xc930, 0x654002d2},
- {OP_WR_64_E1H, CSEM_REG_PRAM + 0xcbb0, 0x64f00327},
-#define CSEM_COMMON_END 1014
-#define CSEM_PORT0_START 1014
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8000, 0xa0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1900, 0x10},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8500, 0x40},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1980, 0x30},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8700, 0x3c},
- {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x5118, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4040, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2300, 0xe},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
-#define CSEM_PORT0_END 1025
-#define CSEM_PORT1_START 1025
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8280, 0xa0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1940, 0x10},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8600, 0x40},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1a40, 0x30},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x87f0, 0x3c},
- {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x511c, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4058, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2338, 0xe},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
-#define CSEM_PORT1_END 1036
-#define CSEM_FUNC0_START 1036
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1148, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3300, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
-#define CSEM_FUNC0_END 1039
-#define CSEM_FUNC1_START 1039
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x114c, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3308, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
-#define CSEM_FUNC1_END 1042
-#define CSEM_FUNC2_START 1042
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1150, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3310, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x61c0, 0x30},
-#define CSEM_FUNC2_END 1045
-#define CSEM_FUNC3_START 1045
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1154, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3318, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x30},
-#define CSEM_FUNC3_END 1048
-#define CSEM_FUNC4_START 1048
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1158, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3320, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6340, 0x30},
-#define CSEM_FUNC4_END 1051
-#define CSEM_FUNC5_START 1051
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x115c, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3328, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6400, 0x30},
-#define CSEM_FUNC5_END 1054
-#define CSEM_FUNC6_START 1054
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1160, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3330, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x64c0, 0x30},
-#define CSEM_FUNC6_END 1057
-#define CSEM_FUNC7_START 1057
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1164, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3338, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6580, 0x30},
-#define CSEM_FUNC7_END 1060
-#define XPB_COMMON_START 1060
- {OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20},
-#define XPB_COMMON_END 1061
-#define DQ_COMMON_START 1061
- {OP_WR, DORQ_REG_MODE_ACT, 0x2},
- {OP_WR, DORQ_REG_NORM_CID_OFST, 0x3},
- {OP_WR, DORQ_REG_OUTST_REQ, 0x4},
- {OP_WR, DORQ_REG_DPM_CID_ADDR, 0x8},
- {OP_WR, DORQ_REG_RSP_INIT_CRD, 0x2},
- {OP_WR, DORQ_REG_NORM_CMHEAD_TX, 0x90},
- {OP_WR, DORQ_REG_CMHEAD_RX, 0x90},
- {OP_WR, DORQ_REG_SHRT_CMHEAD, 0x800090},
- {OP_WR, DORQ_REG_ERR_CMHEAD, 0x8140000},
- {OP_WR, DORQ_REG_AGG_CMD0, 0x8a},
- {OP_WR, DORQ_REG_AGG_CMD1, 0x80},
- {OP_WR, DORQ_REG_AGG_CMD2, 0x90},
- {OP_WR, DORQ_REG_AGG_CMD3, 0x80},
- {OP_WR, DORQ_REG_SHRT_ACT_CNT, 0x6},
- {OP_WR, DORQ_REG_DQ_FIFO_FULL_TH, 0x7d0},
- {OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c},
- {OP_WR, DORQ_REG_REGN, 0x7c1004},
- {OP_WR, DORQ_REG_IF_EN, 0xf},
-#define DQ_COMMON_END 1079
-#define TIMERS_COMMON_START 1079
- {OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2},
- {OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c},
- {OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1},
- {OP_WR, TM_REG_CFC_CLD_CRDCNT_VAL, 0x1},
- {OP_WR, TM_REG_CLOUT_CRDCNT0_VAL, 0x1},
- {OP_WR, TM_REG_CLOUT_CRDCNT1_VAL, 0x1},
- {OP_WR, TM_REG_CLOUT_CRDCNT2_VAL, 0x1},
- {OP_WR, TM_REG_EXP_CRDCNT_VAL, 0x1},
- {OP_WR_E1, TM_REG_PCIARB_CRDCNT_VAL, 0x1},
- {OP_WR_E1H, TM_REG_PCIARB_CRDCNT_VAL, 0x2},
- {OP_WR_ASIC, TM_REG_TIMER_TICK_SIZE, 0x3d090},
- {OP_WR_EMUL, TM_REG_TIMER_TICK_SIZE, 0x9c},
- {OP_WR_FPGA, TM_REG_TIMER_TICK_SIZE, 0x9c4},
- {OP_WR, TM_REG_CL0_CONT_REGION, 0x8},
- {OP_WR, TM_REG_CL1_CONT_REGION, 0xc},
- {OP_WR, TM_REG_CL2_CONT_REGION, 0x10},
- {OP_WR, TM_REG_TM_CONTEXT_REGION, 0x20},
- {OP_WR, TM_REG_EN_TIMERS, 0x1},
- {OP_WR, TM_REG_EN_REAL_TIME_CNT, 0x1},
- {OP_WR, TM_REG_EN_CL0_INPUT, 0x1},
- {OP_WR, TM_REG_EN_CL1_INPUT, 0x1},
- {OP_WR, TM_REG_EN_CL2_INPUT, 0x1},
-#define TIMERS_COMMON_END 1101
-#define TIMERS_PORT0_START 1101
- {OP_WR, TM_REG_LIN0_LOGIC_ADDR, 0x0},
- {OP_WR, TM_REG_LIN0_PHY_ADDR_VALID, 0x0},
- {OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2},
-#define TIMERS_PORT0_END 1104
-#define TIMERS_PORT1_START 1104
- {OP_WR, TM_REG_LIN1_LOGIC_ADDR, 0x0},
- {OP_WR, TM_REG_LIN1_PHY_ADDR_VALID, 0x0},
- {OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2},
-#define TIMERS_PORT1_END 1107
-#define XSDM_COMMON_START 1107
- {OP_WR_E1, XSDM_REG_CFC_RSP_START_ADDR, 0x614},
- {OP_WR_E1H, XSDM_REG_CFC_RSP_START_ADDR, 0x424},
- {OP_WR_E1, XSDM_REG_CMP_COUNTER_START_ADDR, 0x600},
- {OP_WR_E1H, XSDM_REG_CMP_COUNTER_START_ADDR, 0x410},
- {OP_WR_E1, XSDM_REG_Q_COUNTER_START_ADDR, 0x604},
- {OP_WR_E1H, XSDM_REG_Q_COUNTER_START_ADDR, 0x414},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_0, 0x20},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_1, 0x20},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_4, 0x23},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_5, 0x24},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_6, 0x25},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_7, 0x26},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_8, 0x27},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_9, 0x29},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_10, 0x2a},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_11, 0x2b},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_12, 0x2c},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_13, 0x2d},
- {OP_ZR, XSDM_REG_AGG_INT_EVENT_14, 0x52},
- {OP_WR, XSDM_REG_AGG_INT_MODE_0, 0x1},
- {OP_ZR, XSDM_REG_AGG_INT_MODE_1, 0x1f},
- {OP_WR, XSDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, XSDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, XSDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, XSDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, XSDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, XSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, XSDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, XSDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, XSDM_REG_TIMER_TICK, 0xa},
-#define XSDM_COMMON_END 1156
-#define QM_COMMON_START 1156
- {OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6},
- {OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5},
- {OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa},
- {OP_WR, QM_REG_ACTCTRINITVAL_3, 0x5},
- {OP_WR, QM_REG_PCIREQAT, 0x2},
- {OP_WR, QM_REG_CMINITCRD_0, 0x4},
- {OP_WR, QM_REG_CMINITCRD_1, 0x4},
- {OP_WR, QM_REG_CMINITCRD_2, 0x4},
- {OP_WR, QM_REG_CMINITCRD_3, 0x4},
- {OP_WR, QM_REG_CMINITCRD_4, 0x4},
- {OP_WR, QM_REG_CMINITCRD_5, 0x4},
- {OP_WR, QM_REG_CMINITCRD_6, 0x4},
- {OP_WR, QM_REG_CMINITCRD_7, 0x4},
- {OP_WR, QM_REG_OUTLDREQ, 0x4},
- {OP_WR, QM_REG_CTXREG_0, 0x7c},
- {OP_WR, QM_REG_CTXREG_1, 0x3d},
- {OP_WR, QM_REG_CTXREG_2, 0x3f},
- {OP_WR, QM_REG_CTXREG_3, 0x9c},
- {OP_WR, QM_REG_ENSEC, 0x7},
- {OP_ZR, QM_REG_QVOQIDX_0, 0x5},
- {OP_WR, QM_REG_WRRWEIGHTS_0, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_5, 0x0},
- {OP_WR, QM_REG_QVOQIDX_6, 0x4},
- {OP_WR, QM_REG_QVOQIDX_7, 0x4},
- {OP_WR, QM_REG_QVOQIDX_8, 0x2},
- {OP_WR, QM_REG_WRRWEIGHTS_1, 0x8012004},
- {OP_WR, QM_REG_QVOQIDX_9, 0x5},
- {OP_WR, QM_REG_QVOQIDX_10, 0x5},
- {OP_WR, QM_REG_QVOQIDX_11, 0x5},
- {OP_WR, QM_REG_QVOQIDX_12, 0x5},
- {OP_WR, QM_REG_WRRWEIGHTS_2, 0x20081001},
- {OP_WR, QM_REG_QVOQIDX_13, 0x8},
- {OP_WR, QM_REG_QVOQIDX_14, 0x6},
- {OP_WR, QM_REG_QVOQIDX_15, 0x7},
- {OP_WR, QM_REG_QVOQIDX_16, 0x0},
- {OP_WR, QM_REG_WRRWEIGHTS_3, 0x1010120},
- {OP_ZR, QM_REG_QVOQIDX_17, 0x4},
- {OP_WR, QM_REG_WRRWEIGHTS_4, 0x1010101},
- {OP_ZR_E1, QM_REG_QVOQIDX_21, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_21, 0x0},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_5, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_22, 0x4},
- {OP_ZR_E1, QM_REG_QVOQIDX_25, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_23, 0x4},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_6, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_24, 0x2},
- {OP_ZR_E1, QM_REG_QVOQIDX_29, 0x3},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_5, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_25, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_26, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_27, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_28, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_6, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_29, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_30, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_31, 0x7},
- {OP_WR, QM_REG_QVOQIDX_32, 0x1},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_7, 0x1010101},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_7, 0x1010120},
- {OP_WR, QM_REG_QVOQIDX_33, 0x1},
- {OP_WR, QM_REG_QVOQIDX_34, 0x1},
- {OP_WR, QM_REG_QVOQIDX_35, 0x1},
- {OP_WR, QM_REG_QVOQIDX_36, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_8, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_37, 0x1},
- {OP_WR, QM_REG_QVOQIDX_38, 0x4},
- {OP_WR, QM_REG_QVOQIDX_39, 0x4},
- {OP_WR, QM_REG_QVOQIDX_40, 0x2},
- {OP_WR, QM_REG_WRRWEIGHTS_9, 0x8012004},
- {OP_WR, QM_REG_QVOQIDX_41, 0x5},
- {OP_WR, QM_REG_QVOQIDX_42, 0x5},
- {OP_WR, QM_REG_QVOQIDX_43, 0x5},
- {OP_WR, QM_REG_QVOQIDX_44, 0x5},
- {OP_WR, QM_REG_WRRWEIGHTS_10, 0x20081001},
- {OP_WR, QM_REG_QVOQIDX_45, 0x8},
- {OP_WR, QM_REG_QVOQIDX_46, 0x6},
- {OP_WR, QM_REG_QVOQIDX_47, 0x7},
- {OP_WR, QM_REG_QVOQIDX_48, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_11, 0x1010120},
- {OP_WR, QM_REG_QVOQIDX_49, 0x1},
- {OP_WR, QM_REG_QVOQIDX_50, 0x1},
- {OP_WR, QM_REG_QVOQIDX_51, 0x1},
- {OP_WR, QM_REG_QVOQIDX_52, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_12, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_53, 0x1},
- {OP_WR_E1, QM_REG_QVOQIDX_54, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_54, 0x4},
- {OP_WR_E1, QM_REG_QVOQIDX_55, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_55, 0x4},
- {OP_WR_E1, QM_REG_QVOQIDX_56, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_56, 0x2},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_13, 0x1010101},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_13, 0x8012004},
- {OP_WR_E1, QM_REG_QVOQIDX_57, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_57, 0x5},
- {OP_WR_E1, QM_REG_QVOQIDX_58, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_58, 0x5},
- {OP_WR_E1, QM_REG_QVOQIDX_59, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_59, 0x5},
- {OP_WR_E1, QM_REG_QVOQIDX_60, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_60, 0x5},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_14, 0x1010101},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_14, 0x20081001},
- {OP_WR_E1, QM_REG_QVOQIDX_61, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_61, 0x8},
- {OP_WR_E1, QM_REG_QVOQIDX_62, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_62, 0x6},
- {OP_WR_E1, QM_REG_QVOQIDX_63, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_63, 0x7},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_15, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_64, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_0_LSB, 0xffff003f},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_15, 0x1010120},
- {OP_ZR_E1, QM_REG_VOQQMASK_0_MSB, 0x2},
- {OP_ZR_E1H, QM_REG_QVOQIDX_65, 0x4},
- {OP_WR_E1, QM_REG_VOQQMASK_1_MSB, 0xffff003f},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_16, 0x1010101},
- {OP_WR_E1, QM_REG_VOQQMASK_2_LSB, 0x100},
- {OP_WR_E1H, QM_REG_QVOQIDX_69, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_2_MSB, 0x100},
- {OP_WR_E1H, QM_REG_QVOQIDX_70, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_71, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_72, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_17, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_73, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_74, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_75, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_76, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_18, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_77, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_78, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_79, 0x7},
- {OP_WR_E1H, QM_REG_QVOQIDX_80, 0x0},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_19, 0x1010120},
- {OP_ZR_E1H, QM_REG_QVOQIDX_81, 0x4},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_20, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_85, 0x0},
- {OP_WR_E1H, QM_REG_QVOQIDX_86, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_87, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_88, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_21, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_89, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_90, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_91, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_92, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_22, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_93, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_94, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_95, 0x7},
- {OP_WR_E1H, QM_REG_QVOQIDX_96, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_23, 0x1010120},
- {OP_WR_E1H, QM_REG_QVOQIDX_97, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_98, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_99, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_100, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_24, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_101, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_102, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_103, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_104, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_25, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_105, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_106, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_107, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_108, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_26, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_109, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_110, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_111, 0x7},
- {OP_WR_E1H, QM_REG_QVOQIDX_112, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_27, 0x1010120},
- {OP_WR_E1H, QM_REG_QVOQIDX_113, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_114, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_115, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_116, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_28, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_117, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_118, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_119, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_120, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_29, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_121, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_122, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_123, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_124, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_30, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_125, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_126, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_127, 0x7},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_31, 0x1010120},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB_EXT_A, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB_EXT_A, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB, 0x1000100},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB, 0x1000100},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB_EXT_A, 0x1000100},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB_EXT_A, 0x1000100},
- {OP_ZR, QM_REG_VOQQMASK_3_LSB, 0x2},
- {OP_WR_E1, QM_REG_VOQQMASK_4_LSB, 0xc0},
- {OP_WR_E1H, QM_REG_VOQQMASK_3_LSB_EXT_A, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_4_MSB, 0xc0},
- {OP_WR_E1H, QM_REG_VOQQMASK_3_MSB_EXT_A, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_5_LSB, 0x1e00},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_5_MSB, 0x1e00},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_6_LSB, 0x4000},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB_EXT_A, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_6_MSB, 0x4000},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB_EXT_A, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_7_LSB, 0x8000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB, 0x1e001e00},
- {OP_WR_E1, QM_REG_VOQQMASK_7_MSB, 0x8000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB, 0x1e001e00},
- {OP_WR_E1, QM_REG_VOQQMASK_8_LSB, 0x2000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB_EXT_A, 0x1e001e00},
- {OP_WR_E1, QM_REG_VOQQMASK_8_MSB, 0x2000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB_EXT_A, 0x1e001e00},
- {OP_ZR_E1, QM_REG_VOQQMASK_9_LSB, 0x7},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB_EXT_A, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB_EXT_A, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB_EXT_A, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB_EXT_A, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB, 0x20002000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB, 0x20002000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB_EXT_A, 0x20002000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB_EXT_A, 0x20002000},
- {OP_ZR_E1H, QM_REG_VOQQMASK_9_LSB, 0x2},
- {OP_WR_E1H, QM_REG_VOQQMASK_9_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_9_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQPORT_0, 0x0},
- {OP_WR, QM_REG_VOQPORT_1, 0x1},
- {OP_ZR, QM_REG_VOQPORT_2, 0xa},
- {OP_WR, QM_REG_CMINTVOQMASK_0, 0xc08},
- {OP_WR, QM_REG_CMINTVOQMASK_1, 0x40},
- {OP_WR, QM_REG_CMINTVOQMASK_2, 0x100},
- {OP_WR, QM_REG_CMINTVOQMASK_3, 0x20},
- {OP_WR, QM_REG_CMINTVOQMASK_4, 0x17},
- {OP_WR, QM_REG_CMINTVOQMASK_5, 0x80},
- {OP_WR, QM_REG_CMINTVOQMASK_6, 0x200},
- {OP_WR, QM_REG_CMINTVOQMASK_7, 0x0},
- {OP_WR_E1, QM_REG_HWAEMPTYMASK_LSB, 0xffff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB, 0x1ff01ff},
- {OP_WR_E1, QM_REG_HWAEMPTYMASK_MSB, 0xffff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB, 0x1ff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB_EXT_A, 0x1ff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB_EXT_A, 0x1ff01ff},
- {OP_WR, QM_REG_ENBYPVOQMASK, 0x13},
- {OP_WR, QM_REG_VOQCREDITAFULLTHR, 0x13f},
- {OP_WR, QM_REG_VOQINITCREDIT_0, 0x140},
- {OP_WR, QM_REG_VOQINITCREDIT_1, 0x140},
- {OP_ZR, QM_REG_VOQINITCREDIT_2, 0x2},
- {OP_WR, QM_REG_VOQINITCREDIT_4, 0xc0},
- {OP_ZR, QM_REG_VOQINITCREDIT_5, 0x7},
- {OP_WR, QM_REG_TASKCRDCOST_0, 0x48},
- {OP_WR, QM_REG_TASKCRDCOST_1, 0x48},
- {OP_ZR, QM_REG_TASKCRDCOST_2, 0x2},
- {OP_WR, QM_REG_TASKCRDCOST_4, 0x48},
- {OP_ZR, QM_REG_TASKCRDCOST_5, 0x7},
- {OP_WR, QM_REG_BYTECRDINITVAL, 0x8000},
- {OP_WR, QM_REG_BYTECRDCOST, 0x25e4},
- {OP_WR, QM_REG_BYTECREDITAFULLTHR, 0x7fff},
- {OP_WR_E1, QM_REG_ENBYTECRD_LSB, 0x7},
- {OP_WR_E1H, QM_REG_ENBYTECRD_LSB, 0x70007},
- {OP_WR_E1, QM_REG_ENBYTECRD_MSB, 0x7},
- {OP_WR_E1H, QM_REG_ENBYTECRD_MSB, 0x70007},
- {OP_WR_E1H, QM_REG_ENBYTECRD_LSB_EXT_A, 0x70007},
- {OP_WR_E1H, QM_REG_ENBYTECRD_MSB_EXT_A, 0x70007},
- {OP_WR, QM_REG_BYTECRDPORT_LSB, 0x0},
- {OP_WR, QM_REG_BYTECRDPORT_MSB, 0xffffffff},
- {OP_WR_E1, QM_REG_FUNCNUMSEL_LSB, 0x0},
- {OP_WR_E1H, QM_REG_BYTECRDPORT_LSB_EXT_A, 0x0},
- {OP_WR_E1, QM_REG_FUNCNUMSEL_MSB, 0xffffffff},
- {OP_WR_E1H, QM_REG_BYTECRDPORT_MSB_EXT_A, 0xffffffff},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_0, 0x0},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_1, 0x2},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_2, 0x1},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_3, 0x3},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_4, 0x4},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_5, 0x6},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_6, 0x5},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_7, 0x7},
- {OP_WR, QM_REG_CMINTEN, 0xff},
-#define QM_COMMON_END 1456
-#define PBF_COMMON_START 1456
- {OP_WR, PBF_REG_INIT, 0x1},
- {OP_WR, PBF_REG_INIT_P4, 0x1},
- {OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1},
- {OP_WR, PBF_REG_IF_ENABLE_REG, 0x7fff},
- {OP_WR, PBF_REG_INIT_P4, 0x0},
- {OP_WR, PBF_REG_INIT, 0x0},
- {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0},
-#define PBF_COMMON_END 1463
-#define PBF_PORT0_START 1463
- {OP_WR, PBF_REG_INIT_P0, 0x1},
- {OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1},
- {OP_WR, PBF_REG_INIT_P0, 0x0},
- {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0},
-#define PBF_PORT0_END 1467
-#define PBF_PORT1_START 1467
- {OP_WR, PBF_REG_INIT_P1, 0x1},
- {OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1},
- {OP_WR, PBF_REG_INIT_P1, 0x0},
- {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0},
-#define PBF_PORT1_END 1471
-#define XCM_COMMON_START 1471
- {OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020},
- {OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020},
- {OP_WR, XCM_REG_TM_XCM_HDR, 0x1000030},
- {OP_WR, XCM_REG_ERR_XCM_HDR, 0x8100000},
- {OP_WR, XCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, XCM_REG_EXPR_EVNT_ID, 0x30},
- {OP_WR, XCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, XCM_REG_STORM_WEIGHT, 0x3},
- {OP_WR, XCM_REG_TSEM_WEIGHT, 0x6},
- {OP_WR, XCM_REG_CSEM_WEIGHT, 0x3},
- {OP_WR, XCM_REG_USEM_WEIGHT, 0x3},
- {OP_WR, XCM_REG_DORQ_WEIGHT, 0x2},
- {OP_WR, XCM_REG_PBF_WEIGHT, 0x0},
- {OP_WR, XCM_REG_NIG0_WEIGHT, 0x2},
- {OP_WR, XCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, XCM_REG_XSDM_WEIGHT, 0x6},
- {OP_WR, XCM_REG_XQM_P_WEIGHT, 0x4},
- {OP_WR, XCM_REG_XQM_S_WEIGHT, 0x2},
- {OP_WR, XCM_REG_TM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_XCM_XQM_USE_Q, 0x1},
- {OP_WR, XCM_REG_XQM_BYP_ACT_UPD, 0x6},
- {OP_WR, XCM_REG_UNA_GT_NXT_Q, 0x0},
- {OP_WR, XCM_REG_AUX1_Q, 0x2},
- {OP_WR, XCM_REG_AUX_CNT_FLG_Q_19, 0x1},
- {OP_WR, XCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, XCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, XCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, XCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, XCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, XCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, XCM_REG_TM_INIT_CRD, 0x4},
- {OP_WR, XCM_REG_XQM_INIT_CRD, 0x20},
- {OP_WR, XCM_REG_XX_INIT_CRD, 0x2},
- {OP_WR_E1, XCM_REG_XX_MSG_NUM, 0x1f},
- {OP_WR_E1H, XCM_REG_XX_MSG_NUM, 0x20},
- {OP_ZR, XCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02d4},
- {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0329},
- {OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf},
- {OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7},
- {OP_WR, XCM_REG_N_SM_CTX_LD_2, 0xb},
- {OP_WR, XCM_REG_N_SM_CTX_LD_3, 0xe},
- {OP_ZR_E1, XCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR_E1H, XCM_REG_N_SM_CTX_LD_4, 0xe},
- {OP_ZR_E1H, XCM_REG_N_SM_CTX_LD_5, 0x3},
- {OP_WR, XCM_REG_XCM_REG0_SZ, 0x4},
- {OP_WR, XCM_REG_XCM_STORM0_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_STORM1_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_XQM_IFEN, 0x1},
- {OP_WR, XCM_REG_STORM_XCM_IFEN, 0x1},
- {OP_WR, XCM_REG_XQM_XCM_IFEN, 0x1},
- {OP_WR, XCM_REG_XSDM_IFEN, 0x1},
- {OP_WR, XCM_REG_TM_XCM_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_TM_IFEN, 0x1},
- {OP_WR, XCM_REG_TSEM_IFEN, 0x1},
- {OP_WR, XCM_REG_CSEM_IFEN, 0x1},
- {OP_WR, XCM_REG_USEM_IFEN, 0x1},
- {OP_WR, XCM_REG_DORQ_IFEN, 0x1},
- {OP_WR, XCM_REG_PBF_IFEN, 0x1},
- {OP_WR, XCM_REG_NIG0_IFEN, 0x1},
- {OP_WR, XCM_REG_NIG1_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1},
-#define XCM_COMMON_END 1538
-#define XCM_PORT0_START 1538
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-#define XCM_PORT0_END 1546
-#define XCM_PORT1_START 1546
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-#define XCM_PORT1_END 1554
-#define XCM_FUNC0_START 1554
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC0_END 1563
-#define XCM_FUNC1_START 1563
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC1_END 1572
-#define XCM_FUNC2_START 1572
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC2_END 1581
-#define XCM_FUNC3_START 1581
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC3_END 1590
-#define XCM_FUNC4_START 1590
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC4_END 1599
-#define XCM_FUNC5_START 1599
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC5_END 1608
-#define XCM_FUNC6_START 1608
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC6_END 1617
-#define XCM_FUNC7_START 1617
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC7_END 1626
-#define XSEM_COMMON_START 1626
- {OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, XSEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, XSEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, XSEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, XSEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, XSEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, XSEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, XSEM_REG_TS_0_AS, 0x0},
- {OP_WR, XSEM_REG_TS_1_AS, 0x1},
- {OP_WR, XSEM_REG_TS_2_AS, 0x4},
- {OP_WR, XSEM_REG_TS_3_AS, 0x0},
- {OP_WR, XSEM_REG_TS_4_AS, 0x1},
- {OP_WR, XSEM_REG_TS_5_AS, 0x3},
- {OP_WR, XSEM_REG_TS_6_AS, 0x0},
- {OP_WR, XSEM_REG_TS_7_AS, 0x1},
- {OP_WR, XSEM_REG_TS_8_AS, 0x4},
- {OP_WR, XSEM_REG_TS_9_AS, 0x0},
- {OP_WR, XSEM_REG_TS_10_AS, 0x1},
- {OP_WR, XSEM_REG_TS_11_AS, 0x3},
- {OP_WR, XSEM_REG_TS_12_AS, 0x0},
- {OP_WR, XSEM_REG_TS_13_AS, 0x1},
- {OP_WR, XSEM_REG_TS_14_AS, 0x4},
- {OP_WR, XSEM_REG_TS_15_AS, 0x0},
- {OP_WR, XSEM_REG_TS_16_AS, 0x4},
- {OP_WR, XSEM_REG_TS_17_AS, 0x3},
- {OP_ZR, XSEM_REG_TS_18_AS, 0x2},
- {OP_WR, XSEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, XSEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, XSEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, XSEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, XSEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, XSEM_REG_THREADS_LIST, 0xffff},
- {OP_ZR, XSEM_REG_PASSIVE_BUFFER, 0x800},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18000, 0x0},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18040, 0x18},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18080, 0xc},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x180c0, 0x66},
- {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
- {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18300, 0x138},
- {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18300, 0x1388},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18340, 0x1f4},
- {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18340, 0x0},
- {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18340, 0x5},
- {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
- {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
- {OP_WR_EMUL_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3d60, 0x4},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d60 + 0x10, 0x202f3},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x29c8, 0x4},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3000, 0x48},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29c8 + 0x10, 0x20348},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2080, 0x48},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9020, 0xc8},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3128, 0x8e},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9000, 0x2},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3368, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x21a8, 0x86},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202f5},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2000, 0x20},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402f7},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x23c8, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3e20, 0x202fb},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x2034a},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1518, 0x1},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x4034c},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1830, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c20, 0x0},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1838, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c10, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202fd},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2c08, 0x20350},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3010, 0x1},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b00, 0x4},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x4040, 0x10},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f48, 0x202ff},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100352},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6ac0, 0x2},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b00, 0x4},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x8408, 0x20362},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100301},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100364},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80311},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80374},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80319},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8037c},
- {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xb50000},
- {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xbd0000},
- {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130321},
- {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x3a8, 0xb0384},
- {OP_ZP_E1, XSEM_REG_PRAM, 0x33660000},
- {OP_ZP_E1H, XSEM_REG_PRAM, 0x34060000},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38b30cda},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x37960d02},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3bb11b07},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3bc31ae8},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x2a2629f4},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x382629d9},
- {OP_WR_64_E1, XSEM_REG_PRAM + 0x1d6c0, 0x45280323},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x20000, 0x124537e3},
- {OP_WR_64_E1H, XSEM_REG_PRAM + 0x22220, 0x3bbc0386},
-#define XSEM_COMMON_END 1741
-#define XSEM_PORT0_START 1741
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x14},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc000, 0xfc},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c40, 0x24},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x14},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1400, 0xa},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2548, 0x24},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1450, 0x6},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2668, 0x24},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3378, 0xfc},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2788, 0x24},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b58, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x24},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d78, 0x20325},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa000, 0x28},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d88, 0x100327},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa140, 0xc},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e0, 0x20388},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1508, 0x1},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3000, 0x1},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5020, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5030, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5000, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5010, 0x2},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5040, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x5208, 0x1},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2038a},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50b8, 0x1},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b10, 0x42},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x20337},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d20, 0x4},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b10, 0x42},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d20, 0x4},
-#define XSEM_PORT0_END 1775
-#define XSEM_PORT1_START 1775
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3bf0, 0x14},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc3f0, 0xfc},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3cd0, 0x24},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24f8, 0x14},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1428, 0xa},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x25d8, 0x24},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1468, 0x6},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26f8, 0x24},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3768, 0xfc},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2818, 0x24},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b5c, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x24},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d80, 0x20339},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa0a0, 0x28},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3dc8, 0x10033b},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa170, 0xc},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e8, 0x2038c},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x150c, 0x1},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3004, 0x1},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5028, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5038, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5008, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5018, 0x2},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5044, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x520c, 0x1},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2038e},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50bc, 0x1},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6c18, 0x42},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2034b},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d30, 0x4},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4c18, 0x42},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d30, 0x4},
-#define XSEM_PORT1_END 1809
-#define XSEM_FUNC0_START 1809
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e0, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f0, 0x100390},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
-#define XSEM_FUNC0_END 1812
-#define XSEM_FUNC1_START 1812
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e4, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a30, 0x1003a0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
-#define XSEM_FUNC1_END 1815
-#define XSEM_FUNC2_START 1815
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e8, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a70, 0x1003b0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe},
-#define XSEM_FUNC2_END 1818
-#define XSEM_FUNC3_START 1818
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7ec, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2ab0, 0x1003c0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe},
-#define XSEM_FUNC3_END 1821
-#define XSEM_FUNC4_START 1821
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f0, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2af0, 0x1003d0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe},
-#define XSEM_FUNC4_END 1824
-#define XSEM_FUNC5_START 1824
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f4, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b30, 0x1003e0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe},
-#define XSEM_FUNC5_END 1827
-#define XSEM_FUNC6_START 1827
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f8, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b70, 0x1003f0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe},
-#define XSEM_FUNC6_END 1830
-#define XSEM_FUNC7_START 1830
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7fc, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2bb0, 0x100400},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe},
-#define XSEM_FUNC7_END 1833
-#define CDU_COMMON_START 1833
- {OP_WR, CDU_REG_CDU_CONTROL0, 0x1},
- {OP_WR_E1H, CDU_REG_MF_MODE, 0x1},
- {OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000},
- {OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d},
- {OP_WB_E1, CDU_REG_L1TT, 0x200034d},
- {OP_WB_E1H, CDU_REG_L1TT, 0x2000410},
- {OP_WB_E1, CDU_REG_MATT, 0x20054d},
- {OP_WB_E1H, CDU_REG_MATT, 0x280610},
- {OP_ZR_E1, CDU_REG_MATT + 0x80, 0x2},
- {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6056d},
- {OP_ZR, CDU_REG_MATT + 0xa0, 0x18},
-#define CDU_COMMON_END 1844
-#define DMAE_COMMON_START 1844
- {OP_ZR, DMAE_REG_CMD_MEM, 0xe0},
- {OP_WR, DMAE_REG_CRC16C_INIT, 0x0},
- {OP_WR, DMAE_REG_CRC16T10_INIT, 0x1},
- {OP_WR_E1, DMAE_REG_PXP_REQ_INIT_CRD, 0x1},
- {OP_WR_E1H, DMAE_REG_PXP_REQ_INIT_CRD, 0x2},
- {OP_WR, DMAE_REG_PCI_IFEN, 0x1},
- {OP_WR, DMAE_REG_GRC_IFEN, 0x1},
-#define DMAE_COMMON_END 1851
-#define PXP_COMMON_START 1851
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50573},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50638},
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50578},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5063d},
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5057d},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x20, 0x50642},
-#define PXP_COMMON_END 1857
-#define CFC_COMMON_START 1857
- {OP_ZR_E1H, CFC_REG_LINK_LIST, 0x100},
- {OP_WR, CFC_REG_CONTROL0, 0x10},
- {OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff},
- {OP_WR, CFC_REG_INTERFACES, 0x280000},
- {OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a},
- {OP_WR, CFC_REG_INTERFACES, 0x0},
-#define CFC_COMMON_END 1863
-#define HC_COMMON_START 1863
- {OP_ZR_E1, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4},
-#define HC_COMMON_END 1864
-#define HC_PORT0_START 1864
- {OP_WR_E1, HC_REG_CONFIG_0, 0x1080},
- {OP_ZR_E1, HC_REG_UC_RAM_ADDR_0, 0x2},
- {OP_WR_E1, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1, HC_REG_LEADING_EDGE_0, 0xffff},
- {OP_WR_E1, HC_REG_TRAILING_EDGE_0, 0xffff},
- {OP_WR_E1, HC_REG_AGG_INT_0, 0x0},
- {OP_WR_E1, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_PORT0_END 1882
-#define HC_PORT1_START 1882
- {OP_WR_E1, HC_REG_CONFIG_1, 0x1080},
- {OP_ZR_E1, HC_REG_UC_RAM_ADDR_1, 0x2},
- {OP_WR_E1, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1, HC_REG_LEADING_EDGE_1, 0xffff},
- {OP_WR_E1, HC_REG_TRAILING_EDGE_1, 0xffff},
- {OP_WR_E1, HC_REG_AGG_INT_1, 0x0},
- {OP_WR_E1, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_PORT1_END 1900
-#define HC_FUNC0_START 1900
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x0},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC0_END 1915
-#define HC_FUNC1_START 1915
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x1},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC1_END 1930
-#define HC_FUNC2_START 1930
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x2},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC2_END 1945
-#define HC_FUNC3_START 1945
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x3},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC3_END 1960
-#define HC_FUNC4_START 1960
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x4},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC4_END 1975
-#define HC_FUNC5_START 1975
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x5},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC5_END 1990
-#define HC_FUNC6_START 1990
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x6},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC6_END 2005
-#define HC_FUNC7_START 2005
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x7},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC7_END 2020
-#define PXP2_COMMON_START 2020
- {OP_WR_E1H, PXP2_REG_RQ_DRAM_ALIGN, 0x1},
- {OP_WR, PXP2_REG_PGL_CONTROL0, 0xe38340},
- {OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10},
- {OP_WR_E1H, PXP2_REG_RQ_ELT_DISABLE, 0x1},
- {OP_WR_E1H, PXP2_REG_WR_REV_MODE, 0x0},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_0, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_7, 0xffffffff},
- {OP_WR_E1, PXP2_REG_PGL_INT_USDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_7, 0xffffffff},
- {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_7, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_0, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_7, 0xffffffff},
- {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_0, 0xffff3330},
- {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_0, 0xff802000},
- {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_1, 0xffff3340},
- {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_0, 0xf0005000},
- {OP_WR_E1, PXP2_REG_PGL_INT_USDM_0, 0xf0003000},
- {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_1, 0xf0008000},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ6, 0x8},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ9, 0x8},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ10, 0x8},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ11, 0x2},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ17, 0x4},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ18, 0x5},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ19, 0x4},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ22, 0x0},
- {OP_WR, PXP2_REG_RD_START_INIT, 0x1},
- {OP_WR, PXP2_REG_WR_DMAE_TH, 0x3f},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD0, 0x40},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD1, 0x1808},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD2, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD3, 0x803},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD4, 0x40},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD5, 0x3},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD6, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD7, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD8, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD9, 0x10003},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD10, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD11, 0x803},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD12, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD13, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD14, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD15, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD16, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD17, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD18, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD19, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD20, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD22, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD23, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD24, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD25, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD26, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD27, 0x3},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD28, 0x2403},
- {OP_WR, PXP2_REG_RQ_BW_WR_ADD29, 0x2f},
- {OP_WR, PXP2_REG_RQ_BW_WR_ADD30, 0x9},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND0, 0x19},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB1, 0x184},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB2, 0x183},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB3, 0x306},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND4, 0x19},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND5, 0x6},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB6, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB7, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB8, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB9, 0xc86},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB10, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB11, 0x306},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND12, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND13, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND14, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND15, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND16, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND17, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND18, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND19, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND20, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND22, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND23, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND24, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND25, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND26, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND27, 0x6},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB28, 0x306},
- {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND29, 0x13},
- {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND30, 0x6},
- {OP_WR, PXP2_REG_PSWRQ_BW_L1, 0x1004},
- {OP_WR, PXP2_REG_PSWRQ_BW_L2, 0x1004},
- {OP_WR, PXP2_REG_PSWRQ_BW_RD, 0x106440},
- {OP_WR, PXP2_REG_PSWRQ_BW_WR, 0x106440},
- {OP_WR_E1H, PXP2_REG_RQ_ILT_MODE, 0x1},
- {OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1},
-#define PXP2_COMMON_END 2137
-#define MISC_AEU_COMMON_START 2137
- {OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_0, 0xf0000000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_0, 0xf0000000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_1, 0xf0000000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_1, 0x0},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_1, 0x10000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_1, 0x5014},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
- {OP_WR_E1H, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0xc00},
- {OP_WR_E1H, MISC_REG_AEU_GENERAL_MASK, 0x3},
-#define MISC_AEU_COMMON_END 2156
-#define MISC_AEU_PORT0_START 2156
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xff5c0000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff55fff},
- {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_0, 0xffff},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0x500003e0},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0xf00003e0},
- {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1, 0x0},
- {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_1, 0xa000},
- {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_1, 0x5},
- {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2, 0xfe00000},
- {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x14},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x7},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_4, 0x400},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_5, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_5, 0x1000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_0, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_6, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_6, 0x4000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_7, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_7, 0x10000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_0, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x4},
- {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0},
- {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3},
- {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7},
-#define MISC_AEU_PORT0_END 2188
-#define MISC_AEU_PORT1_START 2188
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xff5c0000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff55fff},
- {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0, 0xffff},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0x500003e0},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0xf00003e0},
- {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1, 0x0},
- {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_1, 0xa000},
- {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_1, 0x5},
- {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2, 0xfe00000},
- {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x14},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x7},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_4, 0x800},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_5, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_5, 0x2000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_1, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_6, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_1, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_6, 0x8000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_1, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_7, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_1, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_7, 0x20000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x4},
- {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0},
- {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3},
- {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7},
-#define MISC_AEU_PORT1_END 2220
-
-};
-
-static const u32 init_data_e1[] = {
- 0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0,
- 0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440,
- 0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0,
- 0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40,
- 0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0,
- 0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000,
- 0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000,
- 0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000,
- 0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000,
- 0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000,
- 0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000,
- 0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000,
- 0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000,
- 0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000,
- 0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000,
- 0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000,
- 0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000,
- 0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000,
- 0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000,
- 0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000,
- 0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000,
- 0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000,
- 0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000,
- 0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000,
- 0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000,
- 0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000,
- 0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000,
- 0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000,
- 0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000,
- 0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000,
- 0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000,
- 0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000,
- 0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000,
- 0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000,
- 0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000,
- 0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000,
- 0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000,
- 0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000,
- 0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000,
- 0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000,
- 0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000,
- 0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000,
- 0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000,
- 0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000,
- 0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000,
- 0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000,
- 0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000,
- 0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000,
- 0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000,
- 0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000,
- 0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000,
- 0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000,
- 0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000,
- 0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000,
- 0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000,
- 0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000,
- 0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000,
- 0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000,
- 0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000,
- 0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000,
- 0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000,
- 0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000,
- 0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000,
- 0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000,
- 0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000,
- 0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000,
- 0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000,
- 0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000,
- 0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000,
- 0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000,
- 0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000,
- 0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000,
- 0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000,
- 0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000,
- 0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000,
- 0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000,
- 0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000,
- 0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000,
- 0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000,
- 0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000,
- 0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000,
- 0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000,
- 0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000,
- 0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000,
- 0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000,
- 0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000,
- 0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000,
- 0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000,
- 0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000,
- 0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000,
- 0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff,
- 0x00000200, 0x00000001, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8, 0x00000000, 0x00003500,
- 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003,
- 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
- 0x00000003, 0x00bebc20, 0x00002000, 0x000040c0, 0x00006180, 0x00008240,
- 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540, 0x00012600, 0x000146c0,
- 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40,
- 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0,
- 0x0002f080, 0x00031140, 0x00033200, 0x000352c0, 0x00037380, 0x00039440,
- 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740, 0x00043800, 0x000458c0,
- 0x00047980, 0x00049a40, 0x00008000, 0x00010380, 0x00018700, 0x00020a80,
- 0x00028e00, 0x00031180, 0x00039500, 0x00041880, 0x00049c00, 0x00051f80,
- 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480,
- 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980,
- 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900,
- 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x00000000, 0x00007ff8, 0x00000000, 0x00001500, 0x00001000, 0x00002080,
- 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300, 0x00008380,
- 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680,
- 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900, 0x00014980,
- 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80,
- 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00, 0x10000000,
- 0x000028ad, 0x00000000, 0x00010001, 0x00350804, 0xccccccc1, 0xffffffff,
- 0xffffffff, 0x7058103c, 0x00000000, 0xcccc0201, 0xcccccccc, 0x00000000,
- 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000,
- 0x00003500, 0x000e01b7, 0x011600d6, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x00100000, 0x00000000, 0x007201bb, 0x012300f3, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x00100000, 0x00000000, 0xfffffff3,
- 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
- 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7,
- 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
- 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xfffffff3, 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
- 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
- 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffff97, 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
- 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
- 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
- 0x05cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x300fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
- 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
- 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x040fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
- 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0x00100000, 0x00070100, 0x00028170, 0x000b8198, 0x00020250,
- 0x00010270, 0x000f0280, 0x00010370, 0x00080000, 0x00080080, 0x00028100,
- 0x000b8128, 0x000201e0, 0x00010200, 0x00070210, 0x00020280, 0x000f0000,
- 0x000800f0, 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000b8280,
- 0x00080338, 0x00100000, 0x00080100, 0x00028180, 0x000b81a8, 0x00020260,
- 0x00018280, 0x000e8298, 0x00080380, 0x00028000, 0x000b8028, 0x000200e0,
- 0x00010100, 0x00008110, 0x00000118, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000
-};
-
-static const u32 init_data_e1h[] = {
- 0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0,
- 0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440,
- 0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0,
- 0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40,
- 0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0,
- 0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000,
- 0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000,
- 0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000,
- 0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000,
- 0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000,
- 0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000,
- 0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000,
- 0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000,
- 0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000,
- 0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000,
- 0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000,
- 0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000,
- 0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000,
- 0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000,
- 0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000,
- 0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000,
- 0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000,
- 0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000,
- 0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000,
- 0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000,
- 0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000,
- 0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000,
- 0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000,
- 0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000,
- 0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000,
- 0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000,
- 0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000,
- 0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000,
- 0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000,
- 0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000,
- 0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000,
- 0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000,
- 0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000,
- 0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000,
- 0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000,
- 0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000,
- 0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000,
- 0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000,
- 0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000,
- 0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000,
- 0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000,
- 0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000,
- 0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000,
- 0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000,
- 0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000,
- 0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000,
- 0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000,
- 0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000,
- 0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000,
- 0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000,
- 0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000,
- 0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000,
- 0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000,
- 0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000,
- 0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000,
- 0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000,
- 0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000,
- 0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000,
- 0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000,
- 0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000,
- 0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000,
- 0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000,
- 0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000,
- 0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000,
- 0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000,
- 0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000,
- 0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000,
- 0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000,
- 0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000,
- 0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000,
- 0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000,
- 0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000,
- 0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000,
- 0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000,
- 0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000,
- 0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000,
- 0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000,
- 0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000,
- 0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000,
- 0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000,
- 0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000,
- 0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000,
- 0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000,
- 0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000,
- 0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000,
- 0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff,
- 0x00000200, 0x00000001, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00003500, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
- 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
- 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003,
- 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
- 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
- 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff,
- 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000,
- 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff,
- 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20,
- 0x00002000, 0x000040c0, 0x00006180, 0x00008240, 0x0000a300, 0x0000c3c0,
- 0x0000e480, 0x00010540, 0x00012600, 0x000146c0, 0x00016780, 0x00018840,
- 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40, 0x00022c00, 0x00024cc0,
- 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0, 0x0002f080, 0x00031140,
- 0x00033200, 0x000352c0, 0x00037380, 0x00039440, 0x0003b500, 0x0003d5c0,
- 0x0003f680, 0x00041740, 0x00043800, 0x000458c0, 0x00047980, 0x00049a40,
- 0x00008000, 0x00010380, 0x00018700, 0x00020a80, 0x00028e00, 0x00031180,
- 0x00039500, 0x00041880, 0x00049c00, 0x00051f80, 0x0005a300, 0x00062680,
- 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480, 0x0008b800, 0x00093b80,
- 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980, 0x000bcd00, 0x000c5080,
- 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900, 0x00000028, 0x00100000,
- 0x00000000, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000,
- 0x00007ff8, 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500, 0x00001000,
- 0x00002080, 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300,
- 0x00008380, 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600,
- 0x0000e680, 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900,
- 0x00014980, 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00,
- 0x0001ac80, 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00,
- 0x10000000, 0x000028ad, 0x00000000, 0x00010001, 0x00350804, 0xccccccc5,
- 0xffffffff, 0xffffffff, 0x7058103c, 0x00000000, 0xcccc0201, 0xcccccccc,
- 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc,
- 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc,
- 0xcccc0201, 0xcccccccc, 0x00000000, 0xffffffff, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x00000000, 0x00007ff8, 0x00000000, 0x00003500, 0x000e0232, 0x011600d6,
- 0x00100000, 0x00000000, 0x00720236, 0x012300f3, 0x00100000, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x30efffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
- 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3,
- 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
- 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x302fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
- 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
- 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3,
- 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
- 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x31efffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
- 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff,
- 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
- 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x056fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
- 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
- 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3,
- 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
- 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3,
- 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
- 0xfffffff3, 0x316fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x302fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
- 0xfffffff6, 0x30bfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf314, 0xf3cf3cf3,
- 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
- 0xfffffff7, 0x31cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0020cf3c, 0xcdcdcdcd, 0xfffffff0, 0x307fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000, 0x00070100,
- 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000f0280, 0x00010370,
- 0x00080000, 0x00080080, 0x00028100, 0x000b8128, 0x000201e0, 0x00010200,
- 0x00070210, 0x00020280, 0x000f0000, 0x000800f0, 0x00028170, 0x000b8198,
- 0x00020250, 0x00010270, 0x000b8280, 0x00080338, 0x00100000, 0x00080100,
- 0x00028180, 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298, 0x00080380,
- 0x000b0000, 0x000100b0, 0x000280c0, 0x000580e8, 0x00020140, 0x00010160,
- 0x000e0170, 0x00038250, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000,
- 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x04002000
-};
-
-static const u32 tsem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x19d9458a, 0x1138fc18,
- 0x5980a1fc, 0xd8181998, 0x88039880, 0x81b8803d, 0x91a18191, 0xdafd7891,
- 0xbf760862, 0x6ec30330, 0x0211e620, 0x1082239a, 0xf354029f, 0x0f5fc806,
- 0x6512b315, 0x3a263860, 0x06a77ef0, 0x298d2ade, 0xc1124536, 0x1e4586de,
- 0x93476f19, 0xca8922ff, 0xff4041df, 0x65296340, 0x229dbe54, 0x04a65e84,
- 0xe4d1a5a1, 0xd7f2a1ed, 0x5192fea1, 0x0dee6ec6, 0xf8003ca8, 0x6065495c,
- 0x00606549
-};
-
-static const u32 tsem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x49999cce,
- 0x424e4cce, 0x4c22f212, 0x21a08812, 0x8a80af0c, 0x2201277f, 0x282039f5,
- 0x4201d458, 0xd4837908, 0xcdedaf4b, 0x11102484, 0x0547f435, 0x5088768b,
- 0x340da2d1, 0x0ec160d2, 0x6d7b1420, 0xc0faf06f, 0x480bf5ea, 0xb12f3141,
- 0xcbc57e20, 0xe7dad6bf, 0x264ce664, 0xafdbd880, 0xb4fdffff, 0xece7d9b8,
- 0xebdaf7b3, 0x7b5ad7b5, 0x75923ded, 0xc7bf9302, 0x03fc45d8, 0x8c4d4fe5,
- 0xf2c109b1, 0x80f66667, 0xc9b18727, 0x473afebd, 0x6d55633c, 0x9da23b19,
- 0x99ec258c, 0x50281421, 0x2c23d5fe, 0xbfdf8250, 0xf097c365, 0x4219b6ff,
- 0xd0977c3e, 0xc3e611e9, 0x02d5e4fb, 0x933a876b, 0xea0c319c, 0x4b19b98c,
- 0x126b2c64, 0x4b223fa3, 0xe0ff828d, 0x8f392573, 0x27fc34b1, 0x61467574,
- 0xc678c0ae, 0x5c531e32, 0x38a9d0d4, 0x843f7815, 0xbcd2c67f, 0x0731b725,
- 0xbc03cf63, 0xbcf071c9, 0x61de3a5a, 0xc22eefe5, 0x3af3a1df, 0xae58cd6a,
- 0x32773e30, 0x416589a7, 0xf3e33ebf, 0x3d6346ac, 0x4fe3d99b, 0xec3fc346,
- 0x8c517ecc, 0xb1138f30, 0xcb3c018c, 0x632f0e54, 0x5467b2bd, 0x6a9b1f10,
- 0x2c32a258, 0x852f0f58, 0x56338765, 0xed975e03, 0xf8165c16, 0x2f6c39fe,
- 0xbed7e631, 0x15ead66b, 0xa362593e, 0xb50404a1, 0x67eff4e4, 0x11bfcb11,
- 0x2b30fef1, 0xea4ab2a0, 0xaf805595, 0xfb765aaa, 0x67edfe95, 0x54e88933,
- 0x5bf6b929, 0x5adefc61, 0xf1866ae6, 0x02d59997, 0x91fb2fac, 0x7a83e5d3,
- 0x21476366, 0x36d0fa83, 0xc1198981, 0x9e00afef, 0x007f91db, 0xa52b2a1e,
- 0x740642de, 0xb02bddec, 0x871c0ce6, 0x776cbbf7, 0x0c65f306, 0x6658e70c,
- 0x32e73826, 0x74893a41, 0xd2073071, 0xf324bcc1, 0xcea84289, 0xb0f3dc54,
- 0x9de29f7f, 0xe7f4ed87, 0x38e60b49, 0xf25700bd, 0x57a06650, 0x9d3ab5b1,
- 0xea563265, 0xbe442969, 0x8decb538, 0x9e025855, 0xf7c02413, 0x08a78b7c,
- 0x5798a9fb, 0xa780cd9d, 0x8d1859e6, 0xff2db43f, 0x0cf80933, 0xc4c5f3ba,
- 0x76313f21, 0xf04f843c, 0x5a11f1cf, 0xde981c5d, 0xb08b2b97, 0x05f1091f,
- 0x1f011772, 0x26a0423f, 0x544d28e0, 0x29fc573a, 0xd0a0d86b, 0xc3595bfa,
- 0xe50069c6, 0x3f0cbc11, 0x0843ac61, 0x1cbd4be5, 0xb0ff3bba, 0x3c303b94,
- 0x04f3d3ff, 0xab7e1274, 0x1fc8b700, 0xbfd97615, 0xca61f812, 0xf7c0e6ab,
- 0x362a3f80, 0xd40b7e0b, 0xe8dbaf4d, 0x5e26f77d, 0x3765d80f, 0x16d74ff2,
- 0xbdf00ba8, 0x1bf1fda5, 0x155ebf91, 0x3b763359, 0xfa84ca22, 0x3b06a4e5,
- 0xc0750f1b, 0x578db147, 0xbbef362b, 0x692fbf1f, 0xf41b30b3, 0xf17bb157,
- 0x7d42371d, 0xc33361f1, 0x6b5b1526, 0x2fa814e5, 0x582d0bf1, 0xf0e029ef,
- 0xfe8976f9, 0xc7bed0ad, 0x1b389ed1, 0xc6ba73e8, 0x63329cca, 0xc4f6f675,
- 0xa567c059, 0xf8851dfe, 0xc176e95d, 0xf29f6885, 0xc943d6ea, 0xb917af38,
- 0x8b6d977c, 0x7f1d4e66, 0xab64f7f0, 0xbc1ef818, 0x64f3065f, 0xd662efd0,
- 0xb07a8854, 0xd93aeb62, 0xebe20f69, 0xe34a8d74, 0x8bdfc9f4, 0x577c0e30,
- 0xc2e08af9, 0x989a5629, 0x7bb0e517, 0xf3ce6db7, 0x56afce0a, 0xbce3b6ce,
- 0x6ed8cb56, 0x2efe7fb1, 0xfea5cd54, 0xbc2172cd, 0x59b4dd2f, 0xdb910e2e,
- 0x8c836db2, 0x1ac86d70, 0xd7208dec, 0xd7807841, 0x52f583b2, 0x0fa803d4,
- 0x233cbf25, 0x852acf84, 0xb2cbe258, 0x1a73226d, 0xddd388f8, 0x13fc2ef7,
- 0x6bdbe5f0, 0x74eabc27, 0x1aa7d3eb, 0x1aa8cedd, 0xbcdea51d, 0xf8f81119,
- 0xc003a471, 0x827884d3, 0x9f06ad72, 0x97cb3263, 0x9b877fa0, 0x3cbb02a9,
- 0xd999365f, 0xf563067c, 0xd2dd07b0, 0xd99750f5, 0xf582e652, 0x7bb1fa50,
- 0x0493d42a, 0x9f3867ef, 0xc25bc17a, 0x2496abd7, 0x9579e00f, 0xfce0e6c0,
- 0x30d0218f, 0xc0c955af, 0xa6f7809f, 0x8bcf7969, 0x3c7b0682, 0xb17f8bd6,
- 0x39fa8326, 0xa198fd43, 0xf7cbac9f, 0x324e16a3, 0x9616a3f4, 0x8dfcfde8,
- 0x595db1fa, 0x37854d3f, 0x2c29e118, 0x0491fbd5, 0xbf6f5768, 0x37a979b2,
- 0x73c2364f, 0x13f53973, 0xbcc5d53b, 0x1ae7ae0a, 0xb776b03f, 0xed95ef08,
- 0xb0d763b1, 0x5028be50, 0x0edb8005, 0x17ca1252, 0x0ca29331, 0x8eeb187c,
- 0x27a1d433, 0x4175e4f5, 0x958813fd, 0x45397c69, 0x9f90bd26, 0x43faa562,
- 0x85e90a29, 0x5ef06e87, 0x8e20eb83, 0x2ea192cd, 0x11ab477b, 0x14e01af8,
- 0x60961258, 0x7ff52417, 0xf1ccdabf, 0x217a9050, 0x5f7c18fb, 0x8ecdea65,
- 0xa635fa85, 0x6f116bfc, 0xe5eb812e, 0x63559128, 0x230b28bb, 0x233ab4fd,
- 0x085f79ef, 0x00871a9e, 0xbf6085fd, 0x126f668d, 0xdaf8d7f2, 0xc0127c67,
- 0xcc086ab7, 0x12ba0527, 0x60f8099e, 0xa43d5a3d, 0x69f10938, 0x43be4191,
- 0xfc6197c7, 0x06ff1a1c, 0xc71ba3c4, 0xbe3fe84f, 0x61927325, 0x897a6b7c,
- 0x0cab7c61, 0x4fbf03e3, 0xc6d66dad, 0xc0ddfc07, 0x99a134d8, 0x97a4b7c6,
- 0x65abf8d0, 0x3f186256, 0x5bfc6faa, 0x819efe70, 0x83799fe6, 0xa5e9fe71,
- 0x7ccbf9c6, 0x5f6ab3fe, 0xa28fc6d2, 0x5e16cff9, 0x2f4ff3e2, 0xf0b7f3e5,
- 0x77c6fb7e, 0x5effe1f4, 0x8077bf9c, 0x93592df1, 0x5a1ff38d, 0x85bf9c6e,
- 0xbb545f8f, 0xa15f1b53, 0x3b0917f1, 0x9687fcf9, 0xc5b2f8d3, 0x923e42eb,
- 0xfdaaa353, 0x81a44f68, 0x1d260c40, 0x0472a6e5, 0x1fa00518, 0x04990a86,
- 0x9c5143c7, 0x0145ceef, 0x7d4129bf, 0x5120fcc7, 0x352acfa0, 0x9edb2f9e,
- 0xa59ea32f, 0x376889f7, 0x6d453ff1, 0x6c37ad22, 0x1c3fc5bd, 0x136eede0,
- 0x5a2f587d, 0xa45f937f, 0xe5db8ef5, 0xf005c660, 0x1c9e5ff9, 0xaf3a1cd5,
- 0x935172f0, 0x418764f9, 0xbe3c388e, 0x1aa23602, 0x26476be0, 0x9fac1098,
- 0xc60a3d04, 0x7a0e3b2f, 0x6653cb14, 0x009c8f6e, 0x50e4cb3d, 0xf6e5a9b9,
- 0x93bd8f88, 0x5bbaf303, 0xc4a4ff83, 0xb9727df1, 0x9ffc47e0, 0x4654b75b,
- 0x09a8b4fd, 0x7910e98c, 0xd4e8d2af, 0x6fe2dbbb, 0x4e9f0816, 0x243dcfc4,
- 0x97fd8c8a, 0xde2fd766, 0xddf0c830, 0x486fe63c, 0xd70bf682, 0xc2a21fce,
- 0xc7307ffc, 0x53ed1632, 0x13548490, 0x354b31c9, 0xa7316f81, 0x15399d75,
- 0x31ccf72a, 0xb9faec1b, 0x07fd635e, 0xb77ac625, 0xa1366fd9, 0x6044b1bd,
- 0xfbdfa19b, 0xf5ef8daa, 0x71093671, 0x78daae9c, 0x78722777, 0x2c72c3ef,
- 0xae89563e, 0x5bfcabf7, 0x87aa9e1d, 0xeb402ccd, 0x43024765, 0xc812fa3a,
- 0x7caaf35e, 0xdef0e1de, 0x3dbab66f, 0x3ffdcf00, 0xe19f0912, 0x1ebc77f0,
- 0x1d8136ed, 0x4be1b1d7, 0xe1b7da33, 0xff8709f3, 0xf3e11581, 0xf7d46551,
- 0xcfe17df3, 0xf3849f39, 0xfe5b5553, 0xed2113a0, 0x3fbe5a2a, 0x7f0844e8,
- 0x619b6d95, 0xcff12fa8, 0xbc5fb435, 0xfde1be61, 0x8625a6a2, 0x971b0bf7,
- 0x7df3ea1a, 0x7fb4323f, 0xe1ad4560, 0x8fd57dfd, 0xa0ffde18, 0x3ea19d64,
- 0xd0d1bbd7, 0x9b399efe, 0xaf4def0d, 0xe513bc8f, 0x915deea8, 0x5671bae1,
- 0xda38f939, 0xc9156783, 0xb4f8f485, 0xe0e48926, 0xca938d74, 0x5671b6ee,
- 0xc583d72f, 0x5e9c4c0c, 0x71af9ce1, 0x4665ea32, 0xc2aff3fa, 0xea0f9f05,
- 0x849c137f, 0xcc83713f, 0x02c2c002, 0xe3e3eb8b, 0x7de4315e, 0x6fde65c7,
- 0xd71f4100, 0x11d8bdff, 0xf35579f9, 0x046aa1fc, 0xb72821ff, 0xb9d7152c,
- 0x0f7d6d1e, 0x302e5f7f, 0xc673e84f, 0xd79c9256, 0xb94ceb69, 0xf941f5cc,
- 0xf402e4ce, 0x40e5cbbf, 0xc6a5f576, 0xa2a4016b, 0x3ceb449e, 0xa401f901,
- 0x592fc0c0, 0xdceef906, 0x955c1227, 0xaf4013a8, 0xc19e63ae, 0x8133d426,
- 0x8d77e903, 0x49dc3842, 0xa04b6f54, 0x66b3bd75, 0x1213a0fa, 0xe543c7d2,
- 0xa87335a7, 0xa5e3593c, 0x094d44f2, 0xaa6bc795, 0x59a8eca9, 0x35c7e541,
- 0xaa3f2a3e, 0xcff2a469, 0x1e544d35, 0xe540d9ad, 0x2a7e357b, 0x54dc6bbb,
- 0xba2bf9f6, 0xecd78dfe, 0x80afcd55, 0x67ea8795, 0x43d4b9b4, 0x739276db,
- 0xf9ca1257, 0x365ce519, 0x8e67e3da, 0x31996382, 0xf9c2be30, 0xba3a606d,
- 0xf6295ec9, 0xf5c7fd03, 0xe28b6f7f, 0xd899b274, 0xd9a67074, 0xe17fc323,
- 0x7543905a, 0x16065909, 0x7b0cd724, 0xed617e84, 0x8e5d7a43, 0x9bddcc4e,
- 0x71e8133b, 0xe5bf99f2, 0xda75bf61, 0x407517fa, 0x059875a4, 0xbd21779e,
- 0xeb46f042, 0x9aabef5a, 0xfe0cbfbe, 0xd7f0faba, 0xfbfe8e9e, 0xfea54141,
- 0x985ab4cf, 0x13dc7884, 0x67e607ed, 0xef3f0e67, 0x965c7940, 0x444f5264,
- 0x565e83c0, 0x4aa864b4, 0x66d3fae8, 0x12699fac, 0x7ad0b7a6, 0x35998cec,
- 0x554af90a, 0xfa430c4f, 0xf7a95127, 0x56492cb3, 0x9ebc804f, 0xc31596de,
- 0x5f3f6fd7, 0x12c7b707, 0x485f82bf, 0xf0deffed, 0x0e8fd40c, 0xecad630f,
- 0x03ea2b13, 0xedf59778, 0xfd2672fd, 0x6c57e295, 0xda1cf98f, 0x7bf8160b,
- 0x1207e291, 0xab7ef5d5, 0x659f445a, 0x6edf3e34, 0x73be0f18, 0xc5f73eea,
- 0xadf14bcc, 0xc4864ec4, 0xf169d611, 0x366db2c6, 0xc4aeb8d5, 0x6d55ea1a,
- 0x9d61aac9, 0xfc807fc1, 0x42416ab3, 0xb8d729be, 0x1a5247a8, 0xdcaf8005,
- 0xab7ea4e4, 0xc2aede04, 0xe17b21da, 0xa72b5751, 0x9df040db, 0x94ec39ae,
- 0xac4bde40, 0x7c0201e0, 0xa7232d25, 0x6aeb9ea2, 0x7b444bad, 0xf33c4cb0,
- 0xf7c22790, 0x8d024d3b, 0xee6fc4b7, 0x1aa3ae35, 0x57e8307f, 0x167e4e7f,
- 0xd4864e53, 0xcedc4d3b, 0x80f7ef0e, 0xf0e5efd6, 0x48fdb953, 0xfece8de1,
- 0xfb6caa78, 0x1c92f642, 0x82f2ffc1, 0x57f1d278, 0x401cf26e, 0xedba5a7d,
- 0x9fa3d918, 0x0fd97d9a, 0xf53f425f, 0x44929f9f, 0x5e7d5271, 0x6129303e,
- 0x7c5a059c, 0x9ef7f817, 0xfd3d610f, 0x6ccddfec, 0x2ec7c00d, 0x6f782b40,
- 0x13335fd6, 0xa17d4133, 0x5ad05b56, 0xcfdd7146, 0x2a8edc4c, 0xd1071e62,
- 0xa1e53581, 0x4cc5d91d, 0x5d4f11d3, 0xb8c76dec, 0x329c3a10, 0x1667a4c9,
- 0x18ed1a36, 0xf50d7fb0, 0xf58c1bc5, 0x11333662, 0x7af149f5, 0x340bf333,
- 0xf7fbc33f, 0x7fe12a4d, 0x855eab31, 0xf9a4aaeb, 0x26540b23, 0x157c02a5,
- 0x6f3679bf, 0x4c5fc63e, 0xe3d10fdc, 0x38e24b23, 0x7ef1a5fc, 0x3fef0dd9,
- 0xf7771d69, 0x8b06488d, 0x89c6157f, 0x6d730c58, 0xfbf1fd65, 0x870fe16d,
- 0xfbaf5f57, 0x383469c5, 0xdb826dc4, 0x2f7f811f, 0xeba67c68, 0xd5445beb,
- 0x8ddc17e0, 0x21bf10f5, 0xb2e2d446, 0xee911322, 0x67d5aa5d, 0x14f7a18a,
- 0xb4edf7b7, 0xde80eab8, 0x0679373f, 0x4ec81389, 0xed2165c8, 0xd2f26e7e,
- 0xade14ef3, 0x995bb462, 0x3b45c814, 0xe218d614, 0x07e35953, 0x8b91ca31,
- 0x833b66f1, 0x6fe81475, 0x9fa0f841, 0xdb92f655, 0xbbc62e58, 0xbfa1de41,
- 0x87851cc7, 0x94dba805, 0x59fd8656, 0x7cf18c92, 0xaf58d39b, 0x1d207fc2,
- 0x3f8a3046, 0xc2908f45, 0xa86018f0, 0xe32eed0f, 0x84e851f3, 0x201fdd91,
- 0x8b10763e, 0x02556943, 0x26cf8c22, 0xfe7d9d49, 0x7bfa2656, 0x2f8a7e1c,
- 0x2ae5fb40, 0xc5a95f6f, 0x507f97cf, 0x12ee3830, 0x3ceaa8fa, 0x21419068,
- 0x7fbe3d75, 0x71fe625e, 0x3a6f41df, 0xd10d5561, 0xde4d739b, 0xd40f4869,
- 0x009f0893, 0x760d78e3, 0x2a1a9a60, 0xf8c20be7, 0x88e1aae3, 0x5dfd0667,
- 0x2ddef26e, 0xe387f426, 0xea4ffbaa, 0x4882ffd7, 0xfeeabcf3, 0xbfebf587,
- 0x15ff5232, 0x977979bf, 0xf4a9f80f, 0x803a4f57, 0x5267d999, 0xe80ba253,
- 0xc1b5be5e, 0xa9f97281, 0x5d2073e4, 0xd38bf33f, 0x16e7c923, 0xb74f9751,
- 0xff11e422, 0x7e9d1f10, 0xd03bd1e9, 0xd5b73aae, 0x607c52ac, 0x0160259b,
- 0x5d6caca6, 0x9b63e5c2, 0xafaf18e5, 0xb3f902fe, 0x2fa8cdaa, 0x32785f4a,
- 0x40cde311, 0x0e7fcd49, 0xb9507f90, 0x68852fe5, 0x5eb15577, 0xdfe17bd2,
- 0xe3e7f8e1, 0x2f981ec8, 0xaf7ff4c7, 0x6955f3ef, 0x7d6aa978, 0x84910bf4,
- 0xcdfc83a5, 0x9a25f6f0, 0x68a4ffbd, 0xdf38a78f, 0xf9113644, 0xf307c74c,
- 0xeebf7b73, 0x8f73a7c5, 0x5b9d3c01, 0xe421ddfe, 0xd727f284, 0x165a677b,
- 0xe735fcfe, 0x0dd4f2c0, 0xaed4317a, 0x6767d7d6, 0xeca7e69b, 0x39b965e1,
- 0xb03f40e0, 0xe5d9b37c, 0xfcbeba43, 0xc19e2ffc, 0x1607ccb8, 0xbfe870d7,
- 0xef83e5ec, 0xb2f500dd, 0xdbf8e61d, 0x211434f8, 0x2a974831, 0x6c62bbf8,
- 0xbfa50e90, 0x473b283e, 0x8e3fe7f1, 0x6ca3d20b, 0x8d993ec7, 0x298f8fea,
- 0x0ee4fb2d, 0x5a5d0225, 0x3fa2158e, 0x57e2f751, 0xcfafea32, 0xe0d8175e,
- 0xdcf8088c, 0x62ec907c, 0x51d113c4, 0xdd1f53a3, 0x0157dac2, 0xeabf505d,
- 0xff7f0a74, 0xc7fe9a2f, 0xc4399cfe, 0x86bcafcf, 0xb67f28fb, 0x25fe70b8,
- 0xc0e83caf, 0xaa929c79, 0xdb3f5f39, 0x7186e890, 0x44becc4b, 0xbcfe4a95,
- 0x121fb9e4, 0xf23e2dbf, 0x7f8a44c3, 0x89b27730, 0x325f056c, 0xa6d16fce,
- 0x62bf34d9, 0x2bbe25e6, 0xe0f45679, 0x8959e0fe, 0x4111df4d, 0xae24522e,
- 0x5b354f8f, 0xa7654d70, 0x7dc0e170, 0xff45b785, 0x2dff8a56, 0x0fcaf8a5,
- 0xb620fdf5, 0xad67ea8c, 0x885f4e9c, 0xac1abefa, 0xbafca13c, 0xd23b7565,
- 0xf710f4e7, 0x571b8c60, 0xe1a7c931, 0xfd08b843, 0x0da6478a, 0x4e61f4e6,
- 0x0efb4f29, 0x7c14fdf4, 0xcddbed8e, 0xe1ae5b6e, 0x2331763b, 0x6d72fe38,
- 0x0a3b807c, 0x8953d5ed, 0x9845ff60, 0xafa4a15f, 0x85576037, 0x7c8857f0,
- 0xf2df7973, 0x5d6f9708, 0xa633fdde, 0xbebffbe3, 0xbf07e5c3, 0xe0057b43,
- 0xf7a60c0a, 0xa40966fb, 0x102c2c0f, 0x98b7ae49, 0xbe36b935, 0xe004f9d7,
- 0xeddd7096, 0x3fec17e3, 0x764ff08e, 0xf87af16c, 0x565f442e, 0xfe8e78e1,
- 0xbb72e9fd, 0x04ff9358, 0x6cff28c9, 0x81fb9713, 0x8f1f09fd, 0xbffd984b,
- 0x15e50678, 0xaff713e4, 0x7b365fcb, 0x6f9fde70, 0xbddef03f, 0xb79fa720,
- 0xd46a72e8, 0x5a72e19f, 0x8b0273b2, 0x639fa724, 0x3924421a, 0xe511e785,
- 0x3e20e954, 0x4fe947fe, 0x85377f1d, 0x87d74fe1, 0x5c31e103, 0x7459fe1f,
- 0xf087d446, 0xd7961de7, 0xbe74ff9f, 0xf4adf9d3, 0x29431597, 0xa5f3a63e,
- 0x7c7d77ce, 0xbf5df3a9, 0x7f01a378, 0x182defe1, 0x3cb80183, 0x4714cdbb,
- 0xf7c3df28, 0x43bbe17f, 0x4f09e3a9, 0x58c65a6e, 0xf8d4a1d3, 0xac3fbad0,
- 0xded612de, 0x84f7561d, 0xd586f7b5, 0xcbed0dab, 0x3cc80edb, 0x686025af,
- 0x8678ae27, 0x1228327d, 0x5fb9fabf, 0xec85fada, 0x7a50be43, 0x4af37be9,
- 0x3c63b3e6, 0xf148af7c, 0xf1c01e91, 0x67a7182a, 0xf31f867b, 0x3c6c1a24,
- 0xf6a3d4ee, 0x6c5ed03a, 0xdef5e588, 0xea157904, 0xaf79fd3d, 0x7af5c78d,
- 0xd88ebd3c, 0xd8edfb10, 0x76f4911e, 0x8f4d9f87, 0x8ac267e4, 0xc1d47242,
- 0xe3cf7a06, 0x2544d3fd, 0x5fc6057d, 0x8617449a, 0xef6a8a74, 0x419e6071,
- 0x3bac9ecf, 0x45f3c0e7, 0x8db48a6f, 0x7b7683d8, 0x2dc7920c, 0x77f88725,
- 0x53df329f, 0xbf7e3193, 0x4579fb87, 0x11ecc36b, 0xa9f896b6, 0xa32e5958,
- 0xecbf053e, 0x82ff71b8, 0xd6a945cb, 0xe326c95f, 0xdc7bfd7b, 0xbdfb45c1,
- 0xbdf18b74, 0x34078b57, 0x863272eb, 0x71fcd18d, 0xf4d28f1e, 0xe73134f2,
- 0x8f4039ce, 0xc322c39e, 0x7b33fbfd, 0x99c7a244, 0x9ebf7ced, 0x23d7f6e2,
- 0x3e92f77f, 0x89d4f1d4, 0xac0f24f2, 0xfd5f3aaf, 0x9187bcaf, 0x987d766f,
- 0x3b2833fb, 0xfd907d77, 0xe6ffac5b, 0x590ff4fd, 0x5e53f6ff, 0x493ed1b7,
- 0xe276ebcf, 0x7fbd9ef7, 0xeb187f4c, 0x9f142dbb, 0xabfd79ee, 0x9e9fe45c,
- 0xd4129695, 0x80433d77, 0xec1f68fe, 0x83b72afd, 0xa27ad7d6, 0x99251fdb,
- 0xfe7b47db, 0x8f10b1f6, 0xed0acc25, 0x49a3d786, 0xb35eaa9e, 0x67ad3c51,
- 0xa17957ef, 0x9d77ff76, 0x7fb6a54f, 0x736763d9, 0xb17c2276, 0xeaa7df7c,
- 0x5f3fd7b7, 0xad17f98b, 0xf085e4fb, 0xbeefca7e, 0xda3d45c9, 0x43db93b3,
- 0xe78ee6dd, 0x68ee7f70, 0x6695dcfd, 0x0a3773c0, 0x9bac0a55, 0xa014cf0d,
- 0xcbc7f4dc, 0xbc271437, 0xfcf47c52, 0xc10f835f, 0xdd9df5cd, 0xde70156f,
- 0x21fc7f5f, 0x2dd785ea, 0x7cfa97c4, 0x25a96f3f, 0xf372e57b, 0x9c799876,
- 0x799dffe4, 0x992b810b, 0x3ff328f7, 0x2d7fbd37, 0xe12e8939, 0xcf9fd072,
- 0xf5443ef7, 0x822eed97, 0xfdf90af7, 0xf9f27ff6, 0xefba6b7f, 0x2e3bba04,
- 0x7ff2ef3f, 0x4c0f79f2, 0xd7ef37f7, 0x7e62aee8, 0xbeefd54b, 0xadbef821,
- 0x4ffb5b9e, 0xcd03ef2e, 0xd7ebb75f, 0x994d5c98, 0xaf439f18, 0xc569d601,
- 0xc311b33e, 0xcc466b85, 0x14ced154, 0xf52bf6c3, 0xfb99af72, 0x5bee224d,
- 0x086f9c62, 0xcd31f38f, 0x3d2da28f, 0x8a525a18, 0x94958ec9, 0x96bedc55,
- 0xc06eed5c, 0x176b9acb, 0x887728b8, 0xc5ea3d8d, 0x1764da7a, 0xfcc3afc5,
- 0xb9817ac9, 0xa56fb005, 0x8c396f6b, 0x84798dfe, 0xa5c96029, 0xab9618f2,
- 0x59a4b8b5, 0x8f7e0d95, 0xdbac6392, 0x45bac69c, 0x38cacfeb, 0xe624d6fc,
- 0x38b4f8c7, 0x798abf72, 0x8918e26d, 0xb1b75009, 0x17fa1f26, 0xf7e32496,
- 0x1ec0311b, 0x5abdcf12, 0xe1f6f63c, 0x1bbb6c71, 0x44d238f1, 0x2e4a6b71,
- 0xfcb8bc25, 0x8d9e786b, 0x55d788d5, 0x094f88ed, 0x7f6e5ffd, 0x34ccdf91,
- 0xbad2597f, 0xdc984690, 0xcd3b6336, 0x9d2cbe4f, 0xcbd25d38, 0x332d3a35,
- 0x43a745d0, 0xe818fa04, 0xdbf9e3a2, 0x2e9c27d2, 0x6fdff8e1, 0x07fe1276,
- 0x974e97a2, 0x50cdc534, 0xbf9acd5e, 0x49fd1530, 0x1879a7ac, 0xfe6b33ed,
- 0x66ef1482, 0xea93a43e, 0xf42f4862, 0xb7e002db, 0xf3fb7efd, 0x7aea2714,
- 0x081dd8e9, 0x456fd94f, 0x75fc0566, 0x00b3b76f, 0x65f92f7e, 0x5b4b43f4,
- 0x33fb8a45, 0x57779029, 0x6eafbec8, 0xcafd97f7, 0xdd29f34e, 0x06dff169,
- 0xfaee97df, 0xb0ec9724, 0xd7e4bd95, 0x38125ef8, 0xb91d7ddd, 0x2a5bafb8,
- 0x9c23ff71, 0x9e65625f, 0x3bb9d027, 0x6dc60e7a, 0xdf3c6d84, 0x1ee5b4b6,
- 0x7f90c5b3, 0x91dbd666, 0x28bdf05e, 0xc213be50, 0xa9e79a17, 0x2f9d1dfb,
- 0x36be1c0a, 0x76f31fb3, 0xe8edb74b, 0xe953f8c6, 0xc30b8b51, 0xbedb55d2,
- 0x298dfda0, 0xd1d97abf, 0x68b6fe41, 0xf3f43f88, 0xc489b7fb, 0x15ad951f,
- 0x9d4087e4, 0x25b2a2f8, 0x72ebfc72, 0xafd969fe, 0x01f2eef6, 0xfd7ecb0a,
- 0x5be30382, 0x3ab7dba7, 0x76dfffc8, 0x3f5bb8e9, 0x91e5bf3f, 0xa7f9fa4b,
- 0xbfe01ff1, 0xc58720dc, 0x220db649, 0xcbe0047f, 0xadef948b, 0xcbd95bf3,
- 0x38c39f67, 0xcfcee774, 0xcb78439f, 0xe7cbfbff, 0xaf609fd0, 0x88add4db,
- 0xa5de9797, 0xddfe9e38, 0x9dc7992c, 0x817c5fbb, 0x1fdd9fe2, 0x7f01df80,
- 0x4a9ef7ba, 0x7bb27f47, 0x1889d7c7, 0x77be592f, 0xef9c60da, 0x0ca757f2,
- 0x88f41166, 0xfadf225e, 0x1afe20af, 0xad03af4e, 0xe9efc807, 0xdfa37a02,
- 0x69b717d9, 0x3071e0a9, 0xd9af16a7, 0xddce391e, 0x7ad33e2f, 0x8d379dd7,
- 0x72ecd2c7, 0xd3882bb2, 0x1c7403bc, 0xdbf4057d, 0x7fe688fe, 0x175fa646,
- 0xb4e803fe, 0x677e8c2c, 0xfcfd175b, 0x3ad77c19, 0x4d38c068, 0xa6f00ae0,
- 0x27bfd1c7, 0xa3227fbb, 0x25fced7c, 0x6e90c5c5, 0xbb44c1b7, 0x8e9b3e5f,
- 0x9a9f0ffb, 0xe7e7ef7b, 0xc62a2c32, 0xbef74a1b, 0xfdd3f24f, 0x538a11ea,
- 0xdd9e2d33, 0xf0fefacd, 0x5396a3f8, 0xcec5b559, 0xfe1a3be3, 0x74e3fe31,
- 0xce2d73d0, 0x8f58f9c3, 0xf7140cff, 0xde799569, 0xafdf1e88, 0x16a1f2d8,
- 0x4bd2094f, 0x3a748498, 0x08fdc976, 0xe22a0f1d, 0x1c686261, 0xad7c7233,
- 0xd1adde2f, 0xf187e90b, 0x2538becb, 0x6e30d3d4, 0x67de17e5, 0xf741f411,
- 0xecff1e66, 0xa3ce4736, 0xbf9ae3d2, 0xff53970a, 0x2f33c595, 0xc5b7ff07,
- 0x52765f8f, 0xea78e1bf, 0x8f5910bc, 0x75f32dbf, 0xc5f7aaff, 0xbe4305ca,
- 0x7bc9b941, 0xa2b1f904, 0xcfcc98f5, 0x52f3f0a5, 0xb53b7cfa, 0x97ced1bc,
- 0xad778a44, 0x7a40396a, 0xe85f5c3c, 0xf0e1a6fb, 0xade0d09e, 0x44ebe36c,
- 0x5fbb4ee7, 0xf73a7e81, 0xae7e26ef, 0xe28c7edc, 0xfdb6876d, 0x5908ee5a,
- 0xf09d7157, 0xf9dfc087, 0x1e5cbeca, 0xec79e5b7, 0xd19ce3e1, 0x9ed561f4,
- 0x6d54e3c8, 0x4e30c2ff, 0xe645af99, 0xc7a5fdeb, 0xefb92d3b, 0xb74efec1,
- 0x79e6199b, 0xa7116e9e, 0xf5173a47, 0xea6eb6ae, 0xbd707ee7, 0x23fd7ca4,
- 0xf8cc5cfc, 0x1f28a3b7, 0xe991f97e, 0x63c4c61f, 0xfe878409, 0x9f396b5a,
- 0x9dc4feb6, 0x3d6ef48a, 0xeb88af72, 0x6fc42ed4, 0xf79f9d88, 0x3b14f54e,
- 0x8fbc85e8, 0x5d91e33c, 0xc4cdf5c3, 0xfc0326a3, 0x5c60ce30, 0x1fa1ea07,
- 0xf982a73c, 0xe88f086e, 0xf08e9c28, 0xb549aa88, 0x61e7fd09, 0x5e743c56,
- 0xacd7ef40, 0xb003cf1a, 0xd89ce30b, 0x1e4cd24f, 0x8bbe4c47, 0x3cfd3e97,
- 0xbf94714e, 0xa059e60e, 0xf02cd378, 0x7d7d927d, 0xe78641c6, 0xde5126bf,
- 0x78c59676, 0x554bac6e, 0xdfd0267c, 0x596ce4cf, 0xf949d937, 0x4258d707,
- 0x20580ff3, 0x6f51f917, 0x587defd7, 0x7e1a427e, 0x1a88fd02, 0x7e5a597c,
- 0x21d610c2, 0xc9bd7da0, 0x0e27cfce, 0xf84de255, 0xbd9af3fd, 0xec3f9fa9,
- 0xec315e77, 0xcee5e29c, 0xc94fc627, 0x05d43a5f, 0xcf7ab4fc, 0x8f5fcc14,
- 0x477f27bf, 0x12798aaa, 0xe7829e7f, 0xc85fe257, 0xf50c931f, 0x9c1fab13,
- 0xc8fff54a, 0xf50e931f, 0x8dff1a6f, 0xca04cbd7, 0x3d582d57, 0xebf22a7a,
- 0x2cf9cb55, 0xce5188c0, 0x75bc40ef, 0x7bba3e79, 0x1ff31391, 0x5f8e657a,
- 0x4376c1e6, 0xa5bc7126, 0x40ed1f29, 0x75350d3c, 0xfe7f22d4, 0xb157ef7c,
- 0x4c9c17a8, 0xaca8fc25, 0xc1fa455e, 0x2f1749a3, 0x9e174791, 0x93eba64f,
- 0x01f78acd, 0xf991e384, 0xe05ce823, 0xad332533, 0x98cf5f3c, 0x78d4c0c7,
- 0x469167a2, 0x1ad3844f, 0x58bf8f92, 0x5cfcc9f4, 0xafa6934c, 0x9e38aaa6,
- 0x2f172be0, 0xe1edf75e, 0x4be7507a, 0xc8695ced, 0x1087c679, 0x7de29f5e,
- 0xffd092c8, 0x161de33c, 0x9f7c0acf, 0x1d3e7c5c, 0x9f3f5bf9, 0x91ce7e18,
- 0x48a6bd49, 0x76b35ff6, 0x782071ce, 0x2aef563d, 0x77f3371c, 0x41879dce,
- 0xc91746be, 0x1ccd4c2e, 0x827c62bd, 0x5215cfc4, 0x4695439e, 0x971324bf,
- 0xa310f643, 0x8b1ed67d, 0xb9bf46e0, 0xf49541e7, 0x6dd15a77, 0x44f557e4,
- 0x3e60b467, 0xfcc3cf50, 0x4c66295c, 0xd90d1ca3, 0xbf401313, 0x5ce0e40f,
- 0x339c1c98, 0x71c673ae, 0xdb3a2e7b, 0x553fa83a, 0xb00c0feb, 0xe0b9e0c4,
- 0xe5eb911e, 0xc1271a9e, 0xf6f98431, 0xa57efae1, 0x18b56de3, 0xde02fdcf,
- 0xe8bc405f, 0xc0e5ff78, 0xa3457bf4, 0xe8912bdf, 0x74fe7e17, 0x6bfbc5be,
- 0xf8aa7f6c, 0x15742ad0, 0x869dcfc3, 0x6a4ab5d3, 0x78ae88da, 0x682f9ee2,
- 0x36e9d19d, 0x412b857a, 0xe3a0641a, 0xe8efd8eb, 0x10985f3d, 0x4f7e9d5e,
- 0xfdef900f, 0xcf5f0b07, 0x9c4bc7c2, 0x8de291d3, 0x1060feb4, 0xcf58212e,
- 0xf8d1e6b5, 0xde3c4d83, 0x10bdbfd3, 0x7fd03e71, 0x30f2a5e6, 0x2fde5573,
- 0x50fdffe0, 0xf110ffbe, 0xfe22223f, 0x03bc463f, 0xf6c63ffe, 0x4fff8057,
- 0xdd7f852e, 0xf4d32fae, 0x2bee1942, 0xc5fcff01, 0x13313339, 0x15142dc6,
- 0x5b25ffe2, 0xd21f6d45, 0x62725b7d, 0xb92c8f50, 0x199f7abe, 0xb3c970f8,
- 0x9169f102, 0x73fd5e76, 0x784b5ced, 0x1cf15f5e, 0xcbc9e91f, 0x49f9f7e7,
- 0x336d950f, 0xe410bf3e, 0xc7ca74db, 0x93f3f1f5, 0xe11726a2, 0x68a33ff8,
- 0xd628a2fa, 0x0e9c2ed0, 0x864daa43, 0x29e4f03c, 0x9f90fd7d, 0xbe726497,
- 0x3fb5f14f, 0x07c61998, 0xf8fc52dc, 0xbc63e200, 0xcdfb1530, 0xef56e4d7,
- 0xe30ae86f, 0x33e19f3a, 0x6acbfb9e, 0x1bfb9e34, 0x686294de, 0x4c86cd7f,
- 0xfe91fbc3, 0xafef0d6b, 0x50d636db, 0x8372d51f, 0xb6e8fda1, 0x4c7d4302,
- 0xfb4316e0, 0x1a678771, 0xefda13ea, 0x789fb435, 0xfde18174, 0x86a51df5,
- 0xba7e37f7, 0xa9bf50cc, 0xed0d5ff7, 0x5eb88b03, 0x94935fdc, 0x740ae786,
- 0x2a5fecbc, 0xbe7c549b, 0xe6a4db34, 0x744f3e86, 0xccb1733b, 0x357fa373,
- 0xb14cbc90, 0xae85a726, 0x6cccf9cf, 0xac536bd0, 0x55817ac6, 0xe07497e3,
- 0xcdfe2017, 0xa55ca356, 0x026bcf56, 0x2ca59bb3, 0xd2f94619, 0x58b75f20,
- 0xc5bb7eb9, 0xedfa657a, 0xaa7f6c4e, 0xece74032, 0x444be5c3, 0xd2a2caf9,
- 0xcca9fb47, 0x1b96f945, 0x4d3e466d, 0xccaf401a, 0xc3cf1ab3, 0x9b61ea8b,
- 0xfd139064, 0xd0a8f9f9, 0xdbe2c2e7, 0xa0676f28, 0x05a4e57e, 0x7d016eb7,
- 0xa97b2729, 0x9aaf9fd4, 0x97988a63, 0x3bf590f7, 0xfa1b49fa, 0x210f4fd9,
- 0xde92bb7e, 0xccf30a7e, 0x92f5e72a, 0x316c94bf, 0x775825e2, 0x5479e60d,
- 0x508e7e4e, 0x54dcffe5, 0xae2b78d3, 0x173cfaf7, 0x1133307d, 0x06d203f3,
- 0xd55e9ff0, 0x4d5cf1e6, 0xc345adc9, 0x14d53fb0, 0x7a45bf7a, 0xfd10aaa0,
- 0x1e5aa198, 0xc8a653f4, 0xd53f4af9, 0x0a8c19fa, 0x5503ed14, 0xaba0fb21,
- 0x048723f8, 0x9377f8f3, 0x17c8a7f7, 0xe7b7460b, 0x6ecb73f1, 0xabb24cd7,
- 0xd75f8254, 0xe78ae943, 0xe92bd429, 0x66731249, 0xf06787f4, 0x06636f3c,
- 0x338fafbc, 0xf7aa14b9, 0xe59e380a, 0x820d8cc7, 0x5bffeaf1, 0xf7eaf824,
- 0x3cf94f5f, 0xe29aa516, 0x993cfaa7, 0xc7afdfb6, 0xcd26cf8b, 0xd63c418a,
- 0x6e77db5f, 0xacfd6187, 0x7ec76de2, 0xd337aecf, 0x8205f5b8, 0x6f3ebde1,
- 0x741dc369, 0xe15d2b1e, 0x79862ef3, 0x3496dc23, 0x73fd570e, 0xb8234b02,
- 0x43d2f7fe, 0x8aecbfe8, 0x0dbc6176, 0xe889b1f0, 0x6738ceed, 0xf30f27d2,
- 0x34a418aa, 0x25fb21af, 0x96fa1fb2, 0x4cdbaf95, 0xf688959d, 0x4635f254,
- 0x66f5c5b8, 0xc51707f2, 0xe0af942a, 0xd1a159af, 0x55ef38d5, 0x9cef3349,
- 0xbdd4f00b, 0xfd4c3223, 0x2d347671, 0x15df043d, 0xfcbb46b7, 0xef78fece,
- 0x01387272, 0x6e10b7ee, 0xcd214371, 0xdc21da9b, 0x33d8173f, 0xde77c819,
- 0x14ff44e9, 0x977dc313, 0xd3fff870, 0xefc4e3ca, 0x879a5558, 0xeb7c549c,
- 0x16584196, 0xb51ddc91, 0x7fceb80e, 0xfcebe568, 0xeb08d687, 0xfdeee5fc,
- 0x7ed39f28, 0x6dd14b08, 0xeadaecd2, 0x197b50ec, 0xec49d6f4, 0x318baf57,
- 0x7ec5ce3f, 0x3ccbb607, 0x9719d94d, 0x1ed0cbb7, 0xedd3fe43, 0x8d5abfb1,
- 0x9e886476, 0xb3d34afd, 0x9ea15d5f, 0x4eed80bd, 0x68881bdd, 0x91c824c7,
- 0x1b38dcf5, 0x2a957fc7, 0x1be3ca33, 0x6d9f9e20, 0x0e1f6c8b, 0xce5d0eb4,
- 0xd68cc8cf, 0xefd754f9, 0xc560dfdc, 0x9c2fed32, 0x247fe0d9, 0xe329f71b,
- 0xedde5187, 0xaea4fd40, 0xf10d83f8, 0x886de3ab, 0xc04f88cd, 0xf9c6d3a3,
- 0x648b69c4, 0x1e03960f, 0x0e3c064d, 0xd903f6c7, 0xdfad5783, 0x6ee78c4b,
- 0x837c35ba, 0xbc71979e, 0xce3ebbae, 0xe545b8c3, 0xe7a473ec, 0x399c7aaf,
- 0xf74475c6, 0x011c61bf, 0xd77ddfe7, 0xb7716b7f, 0xd5178a0e, 0x0c4d7abd,
- 0x0a2aa7c6, 0x9586f4fa, 0xa49985db, 0x5976bb07, 0x576708dc, 0xece7cf1c,
- 0x10f135da, 0xaf3e39c6, 0x85299c39, 0xaf5d2dd8, 0x4333c91c, 0x8f3b5d7f,
- 0x209449e4, 0xd17e27e7, 0xfc5c57df, 0x128f3ccf, 0xc7d0273c, 0x0ebe566f,
- 0xf8f1b7ad, 0xc798d3c9, 0xf7b19a36, 0xfaf963a3, 0x1c7a6891, 0xe3bf479f,
- 0x7f7ea1f3, 0xc7e57054, 0xdd262b00, 0xab664c55, 0x00a68de5, 0x6e0a8f96,
- 0xbe55e311, 0x4d3cfc91, 0x911b1652, 0x4728fd01, 0x8e0803db, 0x8dd7a3a3,
- 0xa7ea29db, 0x0b2c3eea, 0xc402ef14, 0x2baf5c7b, 0x37fc7d09, 0xa1b38d87,
- 0xe14d215f, 0x7e77b77a, 0x29ef1f94, 0x8fb9344a, 0x6767aa80, 0xc58c2f0e,
- 0xe68b7ff7, 0xd258f2f2, 0x8e5c2689, 0x38a03970, 0x5a669bd4, 0x710d96df,
- 0xef822f27, 0xe7884d97, 0x9805e97e, 0x9639c87d, 0x0967e3c7, 0x00b90714,
- 0x14e78178, 0xb53e02fa, 0x3317cc4b, 0x89b0f416, 0x0bf055b9, 0xee4293ec,
- 0x68ffc1d9, 0x4d60fc76, 0x4d38f6ff, 0x45e0333e, 0xd5db1976, 0x5c0cee09,
- 0xfc81774f, 0xb4fa030d, 0x7ca958d5, 0x184d46ad, 0xa7b8f206, 0xafea8926,
- 0x0ca938d7, 0xe7a08cd4, 0x545c6bfb, 0xa7b5368f, 0x552c7ad3, 0xfe879baf,
- 0x0b12fdf5, 0xbc23b7bd, 0x8e567bc4, 0x97f9c887, 0x0093e62e, 0x3d352fae,
- 0x38d6fb52, 0xc6a7afe2, 0xfd31d400, 0x8ad9ffbf, 0x054d643f, 0xa3fa983d,
- 0x415359c3, 0x78129f8e, 0x181e02fe, 0x552e748e, 0xb7329f2f, 0xf0a9a2c4,
- 0x4df31b6b, 0xc8bcc24d, 0x8e153fde, 0xe8f6cc61, 0x1d4ea69f, 0xfdc7f309,
- 0xf6c614fe, 0xc7abdeda, 0xfba9d873, 0x818bab3f, 0xfc6dc8f9, 0x82899f3e,
- 0x7d4056a7, 0x0bf39b33, 0x98b53c93, 0x3773d9cf, 0xbefee273, 0x1b5ece3e,
- 0xdb7613b7, 0x51399db8, 0xe6c1fce0, 0x411e5aca, 0xbae86e6f, 0xef3ede11,
- 0x8f74d7c0, 0x2fb78c0f, 0x2f5e30d5, 0xfa0711c5, 0xd7ff752e, 0xe95c8eb4,
- 0x491f3d77, 0xc4847cfc, 0xe6ba2bf3, 0xfda66e26, 0xba1f6878, 0x4723da8f,
- 0xd2ded7b6, 0xed0681d6, 0x659fb7be, 0xa68372f0, 0xf5c62457, 0x05d16bff,
- 0x61b947bf, 0x5fda38de, 0x09e2d3aa, 0xe57a3a93, 0x2f7e76f9, 0x13d43e5c,
- 0x3c04784e, 0xd1a5d70f, 0x1e605533, 0x6048ffcc, 0x28028433, 0xdbcf36dd,
- 0xc2d24fd8, 0xd197be4d, 0x7165d85e, 0xe3a3d9a2, 0xd903eeab, 0x6121fa8a,
- 0x8fda31cf, 0x643a13aa, 0x8f97f7a4, 0xcb714d7c, 0x3275733a, 0x1b176dd5,
- 0xbdb4feb0, 0x99d6237a, 0x6fa9ebef, 0xd60c3f00, 0x13e3e1ce, 0x90bb63d4,
- 0x3b5829e8, 0x7e06ef57, 0xf5e665d8, 0x4b391f2f, 0x5ccbb1fc, 0xe18d9f3d,
- 0xef987af5, 0xaa6f58ae, 0x52905409, 0xe1fd65fb, 0xb7aeb09b, 0x77da92ff,
- 0x3f6e54db, 0xa40cde2a, 0x855d5f7f, 0x2ea43dba, 0xf2b33af1, 0xc55f9f52,
- 0x7f29af81, 0xe70f72b8, 0xce1bc447, 0xc3cdef13, 0x7a8ce975, 0xa4eb51d4,
- 0xd73673b8, 0x9f0301d7, 0xb753e7e9, 0x2a2cbc98, 0x085ecf44, 0xce42ff5b,
- 0x84a8b1d9, 0x38b4fe90, 0xbb033a76, 0x6f182b34, 0x2a2e64cd, 0x950f3187,
- 0xee96dbd9, 0xbb2db447, 0x7a89d5af, 0xfad73e2b, 0x68e89780, 0xd09e1ff4,
- 0xe8fae2f4, 0x01a31bfc, 0x7782f59e, 0xf17a888d, 0xe74ab365, 0xb2243a2f,
- 0x35b53b37, 0x5330ad8c, 0xf73b5cbd, 0x5de95e6d, 0xeef51233, 0x19ab9322,
- 0x4f0cb3d7, 0x2fbe19be, 0xaae19ddb, 0xe7bcc165, 0xc496d8b2, 0xef304ab1,
- 0xaa3faf59, 0xb546d9f1, 0xd2f786c9, 0x9543fbe8, 0x71d2eb6d, 0x7db3fb7f,
- 0xbd3c901f, 0x7c41951f, 0x447ad15c, 0xbf69daf6, 0x29f3c64c, 0xd6fad99f,
- 0xbef75a3f, 0x0b74196c, 0xeb2ff5ea, 0x79b8744d, 0x06f43d20, 0x38373fe8,
- 0xac6a87c8, 0x5dc2fe54, 0xde9a2d7d, 0xd3295105, 0xbfb4606c, 0x9156e990,
- 0xb9ade68f, 0x7c0ac1a6, 0x8eac82f4, 0x179b3e44, 0x5b7c4b95, 0xbe722b16,
- 0xdd07b964, 0x0dcfb692, 0x6535d4f5, 0x3c53bed3, 0x6f68c8be, 0x88526d54,
- 0xc80ec00f, 0xdca83e47, 0x7ee1f260, 0x4edac9a2, 0x45e77de7, 0x368fcd31,
- 0xaf5c4f9e, 0x6cdf3be9, 0xdcbddf1e, 0xf392c539, 0x511e7451, 0xe51fbfaf,
- 0x9128be24, 0x55ffb47c, 0xe741de72, 0x38fbbf18, 0xc879c356, 0x0428e3fe,
- 0x794e3e87, 0x57d21c70, 0x27ec1fe5, 0x6b8df83f, 0x4dd67b75, 0x3be5ac71,
- 0x9b05fcb4, 0xf3f6307b, 0x1827a6b4, 0x7780b1fa, 0xeeafa329, 0x1ccf4093,
- 0xf933d3ec, 0x90d3530d, 0x6cf7c1be, 0xb90f4192, 0xc1d3a025, 0xfbeead28,
- 0x51f6e47e, 0xf533ed61, 0xa986ccfa, 0xf3c3fb93, 0xb7582db4, 0x1be97b42,
- 0xe11d5f4b, 0xa1f573a3, 0xe3e9c5fd, 0xe9fd4bdf, 0xb51a97fc, 0xf80fa0f0,
- 0x27ac60ef, 0x7a7cf31f, 0xca273367, 0x8d4966e1, 0x21d08572, 0x37af8a35,
- 0x35afe725, 0xf7883fe0, 0x4ffd035c, 0xfb0d38d5, 0x968b8b8a, 0x549879d1,
- 0xc7cc5e9d, 0xca6d77cf, 0xfe27ec32, 0x16ae387f, 0x7000f70e, 0xc307fd4c,
- 0x5e30c231, 0x031c8e10, 0x870b577c, 0x7a6b3b18, 0x8f6bda06, 0x280f2898,
- 0x66b3e4d1, 0x6ff65da2, 0x0ca78a26, 0x880f3c67, 0xfb0de329, 0x2c7b99b4,
- 0x9efe31f3, 0xd2c3b129, 0xb7279458, 0xa9d716b3, 0x5f64489f, 0x39ab73c1,
- 0x726e870e, 0x204ffde3, 0x665fd495, 0x1f82b7b9, 0x82fbe6f2, 0x70d33efa,
- 0xbde3e595, 0xe7a39ba0, 0xfb8d18df, 0xaa1e7366, 0xe7983cc2, 0x352ff195,
- 0x92bc8330, 0x2c20d21d, 0xabe33b25, 0x701b87a8, 0x147076bf, 0xf6045bb7,
- 0xe4e1c370, 0xbcb9ef48, 0xf0f35b9e, 0x341b8c34, 0x8b5e74af, 0xcdb353fe,
- 0xf31fb2df, 0xe8531e76, 0x47acd6de, 0x50998dfd, 0x6899d717, 0xfd6314bd,
- 0xdf719adb, 0x176cc9fd, 0x68cd11da, 0x47fb60bf, 0x566bf214, 0xf0d338d5,
- 0x6d3a927e, 0x76b2d81d, 0xc1798ab2, 0x87148af5, 0x732addeb, 0x773c5cf5,
- 0x8dd1ee31, 0x51ebd60d, 0x071ab98f, 0x949ebca9, 0x339aeb8c, 0x7b463ad3,
- 0xae68c80f, 0xb1a8a675, 0x6ff0fac1, 0x3d20fac0, 0x9dc1b1b3, 0x2b2efd86,
- 0x883bfad5, 0xe2178a71, 0xef68bc34, 0xd2f4fb33, 0xcbcc06c6, 0xf5836b12,
- 0xaddf30a9, 0x353d72cf, 0xfb47fa18, 0xc3e3e60b, 0x877b057b, 0xca4e744b,
- 0x603b6306, 0x9991b67e, 0x0cd7dfb4, 0x2bef117a, 0xdfc91dee, 0xf234fbeb,
- 0xd3ed1370, 0x6f5c7b60, 0xbdbcc96c, 0x57df833c, 0x8a15db20, 0x307ac037,
- 0x149ef315, 0xf371ffa6, 0x8fb6a4b8, 0x01f78511, 0x75a3f084, 0xf73a32ed,
- 0xdc661d69, 0x8cd3979f, 0x16798975, 0xaa27bfa0, 0x4637e7c6, 0x8341f96b,
- 0x6dda0a58, 0x133e4dc3, 0xfcc91bb6, 0x02c75e54, 0x628d8f64, 0x8d1f541d,
- 0x1e16635e, 0x41d2725b, 0x2dcc71ab, 0x47aa38f2, 0x71313b44, 0xf2471eae,
- 0x74be414e, 0x61766b47, 0x7e3fef0a, 0xf7ca2cc6, 0xcdef69f5, 0x313d8633,
- 0x7eb5e60d, 0x50ceddc6, 0x2f5f4efb, 0x48adfb75, 0x68cbf983, 0xa0bda221,
- 0x364575db, 0xe5984f5e, 0xc6147a7e, 0x26cddb11, 0x58ad9fbc, 0x6f16638b,
- 0xbb444fc8, 0x5cdf68ac, 0x44d787b2, 0xd16cbb73, 0x77b219fa, 0x9af79e14,
- 0xfe7f764f, 0x183109ba, 0xb9b06fa7, 0xfe47ae62, 0xdfbf23fd, 0xb1ed4af5,
- 0x0a6bc4e6, 0xc19b1e50, 0x8ffbc6af, 0xcadd9a0e, 0x758be418, 0x6ccec8c3,
- 0xc7d6f28e, 0xffcdbf42, 0x41d574ea, 0xf73667fd, 0x4e3823f8, 0x8f7f1443,
- 0x6f2126f7, 0x3ff7edf6, 0x1e8c5c2f, 0xfdf0fc78, 0x91b183fe, 0x43bdf1ef,
- 0xfed05fc3, 0xd9dd90f0, 0xdcc4f660, 0xcbbdf087, 0xead679e7, 0x112f5189,
- 0x86b4fb67, 0xd67603e7, 0xe64058b8, 0xbd62d1f7, 0xdd3f68a4, 0x22d25caf,
- 0x097cdc50, 0x3a3d226b, 0xeed5894c, 0xc5e631a7, 0x4dbd1696, 0x795b4bed,
- 0x42d632fb, 0xe17a75ed, 0x8301b5bd, 0xf0ce3a1d, 0xdcd11dfd, 0x78acdd6f,
- 0xfffb431f, 0xc4d91991, 0x1167c04f, 0x07e22df3, 0x31b977d8, 0x371faf9a,
- 0xf6c8db62, 0xb863f128, 0xe05cb87d, 0xc207b3e7, 0x9379d553, 0xde0a3d61,
- 0x7ad3219f, 0x49f9add4, 0xeb7c9387, 0x7ff9846f, 0x244af59f, 0x23bddaa7,
- 0x425f8275, 0x33befaf9, 0x2d1bdeec, 0xa6ba680f, 0xcb43fe25, 0x6b3ef9ef,
- 0xfd0dc379, 0xf402cedc, 0x9eed61dd, 0x48a41412, 0xafd01979, 0x3adc1f41,
- 0xddbf58c2, 0x39dfac65, 0x7d3df229, 0xb4d46b6b, 0xd6aa7bd0, 0xf38e700e,
- 0x575e8d2d, 0x0b12df7f, 0x0b7bebcf, 0xf9815ee9, 0xc17fb494, 0x1b14faf3,
- 0xd91ea0f3, 0xfb46cfbf, 0xbc8a5521, 0x55164319, 0xbde2efe0, 0x9f9d8af0,
- 0x17ff4037, 0x998a05e3, 0x97de0fb7, 0x1251f7c4, 0x3c5a493c, 0x633495c3,
- 0x1b87b7d4, 0x0bca2afd, 0xdc46d896, 0x27e60d77, 0xe8edef1a, 0x0f38fe8a,
- 0xcf9863fd, 0xe84f8c6c, 0x3e7d5a71, 0x2c7f28ff, 0x39cfbb5a, 0x346b6e9c,
- 0xa30ba8f9, 0x39d23d73, 0xb973df07, 0x87bb52f9, 0x43c129ff, 0x26896879,
- 0xb3ac171e, 0x9c528eb9, 0xea0ff344, 0xf306b8b4, 0x56ef5d7d, 0x1095ecc2,
- 0xed7d22ff, 0x39f5f5d7, 0x38f377e4, 0x156a2d88, 0x360dc3ae, 0xfaa66ebd,
- 0x00a6e6d3, 0x5aaffdf9, 0x831f189c, 0x6718ddef, 0x411dcdf3, 0x065d5d7e,
- 0x0e7bc14b, 0xb4cbb0de, 0x6abdd6fe, 0xd8f5c669, 0xdb76f36d, 0xba49f242,
- 0xf9d1efec, 0xf9fd08a6, 0xf90dfd0c, 0xf8c1fd76, 0xfd7788ad, 0xa7f61bfd,
- 0xceff2202, 0x691bf949, 0xa17b1fed, 0x42cbb89e, 0xf7fd4f71, 0xe7cfca0f,
- 0x7a8cfdd1, 0x4e14137f, 0xd51ace87, 0x8e5d8f90, 0xe507377a, 0x67f49da0,
- 0x8320cb45, 0x69f5d4de, 0x681bf9c5, 0x57482cbf, 0xb5212e2d, 0x38aa5e93,
- 0xbc68bfff, 0x349e903b, 0xf7e9124e, 0x3549c781, 0x38e0e3e8, 0xf7700c93,
- 0xc132671f, 0xdac38fa1, 0x9fe70ca2, 0xae3ccceb, 0x33986672, 0x1e823626,
- 0x83714bd1, 0x60ff70c9, 0x62b2e49d, 0x4eca75ff, 0x287f3435, 0xef005f7c,
- 0xf02164c5, 0x867ac1d5, 0xf30b72c1, 0x3d405e52, 0x072213f6, 0x62a5d9a2,
- 0xf8c262bf, 0xc62ef9e9, 0xbdb945fe, 0x33727d10, 0x8bd82df2, 0x7e3b583f,
- 0x49ec0f95, 0x4769ecc9, 0x93764aba, 0x6b68f313, 0x45c51315, 0x64ac92eb,
- 0xca12adff, 0xbd739455, 0x2243a95f, 0x8f7df438, 0x9f29e681, 0xc33cd077,
- 0x9ffb3bef, 0x76a14f1b, 0x3b57eefd, 0x0f93d730, 0x93545bfd, 0x4e5d450b,
- 0x2127d853, 0x47ef0ff4, 0xec4520da, 0x8e9dbc27, 0x6ce901ff, 0x3d2070ee,
- 0x88a5e3ba, 0x951b1079, 0x310798ef, 0x271f4c2f, 0xe00ecd1c, 0x238742f7,
- 0xe5f48323, 0xa5f50546, 0xdc9fccfd, 0xb4cbd24e, 0x7fafadef, 0x56a984e6,
- 0xbc6c4f9e, 0xfe206f57, 0x7d62f1d3, 0xf3c641f3, 0x7f94bd53, 0x483c3972,
- 0xfb43cb82, 0xe2297600, 0x425836be, 0x4938fc86, 0x354fe631, 0x63e21e48,
- 0x56d54df3, 0x5b4927da, 0x927dc569, 0x063392d5, 0x37ded8fd, 0xf983fec1,
- 0xbe793a35, 0x6bff786a, 0xb4661ef0, 0xc4531573, 0x06a379fb, 0x34baafb0,
- 0x77d9acfa, 0xf501fe69, 0x3775c1e1, 0x71524e2a, 0x399b35dd, 0x4bad03bc,
- 0xe103bf7a, 0xfc7dd1eb, 0x392c1bf7, 0xffae3f56, 0x4a35e3e1, 0xbc3e4f1e,
- 0x7078046f, 0xcd31acdf, 0x546df84d, 0xd5fd1525, 0xcc5111e8, 0x656fea1a,
- 0x67f7a2cc, 0xccf1e3e2, 0x8f8c6b22, 0xe3a3979c, 0x1df2b769, 0x186f1ded,
- 0x8f7f0e5f, 0x7c21e8e2, 0xe84ca9d9, 0x91bb97cf, 0xfc381317, 0x5aa6f7a1,
- 0xbc458633, 0x7f1fb27f, 0xde4df186, 0xf7e74664, 0x19b94306, 0xeed56efa,
- 0xb5c0aa43, 0xf2f4fc0b, 0xc2a6147b, 0xe477e6fa, 0xc939405f, 0xcfcfdf6b,
- 0xf026b4d1, 0xefb51e7b, 0x625dc7c3, 0x12c8fee7, 0xcc654abb, 0xf12ff751,
- 0xdb5a37f7, 0x5e789ca3, 0xb22e35b1, 0xd763931f, 0xb49a68f3, 0xb41d0873,
- 0xcfb7a14f, 0xcddcc79b, 0x1b3dc50a, 0x257fe0ad, 0xa9ffb5f4, 0x82023fb6,
- 0xf9dce30b, 0xf99aebdb, 0x7f3e51f9, 0xfb62ab8c, 0x5c8ec4c4, 0x740efc41,
- 0xf70cc6db, 0x3b5855db, 0xe7ce51b2, 0x7699bc9a, 0x68eaa718, 0x5bd62247,
- 0x4e9d3edf, 0xb71d6f7e, 0x47777b37, 0x3fa0dc53, 0x79f96a7d, 0xcc29f3f2,
- 0xdd3fa837, 0xad00a5ca, 0xd3e7e5ab, 0xcd1c6f99, 0x0b8d67db, 0xc2d3bfbe,
- 0xc8b1a4d8, 0x884f1c00, 0x30f4489f, 0x7a064ddb, 0x675e3c80, 0x7881e8d7,
- 0x76b7a3ea, 0x76a74bef, 0xcd71e0bf, 0xf72a615f, 0xa5fbf5d7, 0xe5f7678e,
- 0x5b7dd05b, 0x13f736e5, 0x3b0b4f78, 0xe6be5222, 0xfefc29c2, 0x771685c4,
- 0x0b57da0c, 0x6a1453ff, 0xf3937f69, 0x7f0d22fd, 0xf745cc9d, 0xdad6f80e,
- 0x984ebef8, 0x54f1967f, 0xc23fb8fe, 0x44da8bf7, 0x305f1bca, 0xbf61f145,
- 0xbf05ed79, 0xe2f9fdc4, 0x773a68c6, 0xae7bf0be, 0x2dd76893, 0xc4e6c27c,
- 0xfe597bdf, 0x327e6641, 0xc9fcbbf4, 0xdf07d50c, 0x24f0af45, 0x27a05d59,
- 0x8853db1f, 0x3083457e, 0x0630be7f, 0x0ec7cafc, 0x98b8c2ac, 0xcf94cdf4,
- 0xf47f506d, 0x615677b1, 0x18b7e9bc, 0xf63b26e7, 0x63b442dd, 0xf4d0425f,
- 0xc1c03ffd, 0x5a4d874b, 0xa9aac4fd, 0x4daff2a0, 0x2a293568, 0x562765fa,
- 0xc4d939e1, 0x1318f738, 0xfd8ef78c, 0x6fec42b3, 0xcea313c1, 0xe7f7806d,
- 0xbec817ed, 0xdf693a00, 0x014f370b, 0xb278bbbb, 0x582d975e, 0x86668f8f,
- 0x3339be38, 0xd9da3e38, 0x8b7c7aad, 0x718cdd45, 0xd505e3f7, 0x3fe82453,
- 0xceaea1c3, 0xc4d8c919, 0x1baaf9f5, 0xc476cfc6, 0x98f18cdd, 0x837dbed6,
- 0x1f18d5f8, 0x03de656b, 0xd37f7866, 0xb66e43e3, 0x07e36202, 0x30a8c679,
- 0x29d641ff, 0xf4dfa7ab, 0x4463e41d, 0x0d59f3bf, 0x939204f6, 0xf4d28843,
- 0xc2defc15, 0xe34ef93e, 0x1f57db7c, 0xc3cfc1d1, 0x5e24f5e8, 0x59195d6f,
- 0xc312dc5f, 0x2a35baf9, 0x4d66fbf2, 0x03be003f, 0x8b6d7f14, 0x08cf0ff6,
- 0x1f900fea, 0xa79224eb, 0x807f5c75, 0x93b4cd1c, 0xefec46dc, 0xab6bcadb,
- 0xab79af76, 0xf8c68ee4, 0x30c7ae82, 0xcce38682, 0xfa0d3bb5, 0x017daf39,
- 0x3151d7e9, 0xc9c7872a, 0xc53093f1, 0xb59847a8, 0xdf743b3d, 0x3cda77fe,
- 0xe3d3ae33, 0x7439013f, 0x8ef969df, 0x9f9e4bfc, 0x7f38c72d, 0x9c1dbd88,
- 0x678a54c7, 0xfa17ebf4, 0xbbfd6a73, 0x5f04ae72, 0x15f065ea, 0xdcbaf84f,
- 0x19fd833c, 0xfbfd2fe3, 0xc17db593, 0x223ae326, 0xa4f38647, 0x7f8027ce,
- 0x2cfe8853, 0x9ea9f4d6, 0x6bbdd107, 0x064fe524, 0x31e7e5c7, 0xc4bfbe81,
- 0x81f25ddf, 0x963d453e, 0xc56fb927, 0x71ed79f6, 0xc0efda2a, 0xbf1af56f,
- 0x3a6fc849, 0xaae35b9d, 0xebbe69f3, 0xfa4bb204, 0x3ada41d9, 0xd024d79a,
- 0x9e0d99ef, 0x87e715e7, 0x7beba7c0, 0xeb55bfe8, 0xe7e73c7f, 0xf9f8fb67,
- 0xcd1f943e, 0x0eae679f, 0x1c3d5fba, 0x732885fe, 0xd5eb2109, 0xeb8a36ab,
- 0x5abb78eb, 0x85edd7fe, 0x25d701f2, 0xf8377d07, 0x84e1c068, 0x1e518b76,
- 0x7cb55f50, 0xb664f742, 0x7f0c89b6, 0x8de700b2, 0xd74f237a, 0x8795be93,
- 0x5bb2240a, 0x49d97a82, 0x37ae8bf6, 0xb06b5603, 0x2bb5b9fd, 0xaf51eb0b,
- 0xc7ecf76a, 0xc7c5a08b, 0x7348e106, 0x9277bb70, 0xddfc4597, 0x5dbb1cb8,
- 0x8f3423d7, 0xe80a2b8d, 0x6d2a855e, 0xe1d49d3d, 0x345378a3, 0x104271e2,
- 0x7d7afa1f, 0x15e3a5a7, 0x8197bced, 0xd83af51f, 0xaca69525, 0x7ef8ff60,
- 0xe7df0866, 0x841f3839, 0xeabbe7d3, 0x0f83c027, 0x0d43f0f1, 0xc75009ef,
- 0x04982d7b, 0xfde617eb, 0x6b5c50cc, 0x56e04232, 0x104e3eb8, 0x5d8f5c4d,
- 0x07e22e46, 0x58f7ed31, 0x41cf24ec, 0xe5bb707c, 0xe7168701, 0x3f29eed5,
- 0xa1390268, 0xcf3e367d, 0xd4c95dee, 0xddad6cef, 0x6f2f4bdf, 0x7496f2d6,
- 0xb5e2b17b, 0xf846cdd4, 0x1cbb7f79, 0x47792f1c, 0x8ed063dd, 0x5c51ee19,
- 0xb5e41fe8, 0xf98fdccf, 0xf07bd924, 0x7c820407, 0xe5c2dd9e, 0xc34bb814,
- 0x43db9bcb, 0xd874adfb, 0xbbfb3975, 0x28fb23cc, 0xcba457e7, 0x5a72217d,
- 0xbe3850e3, 0xc4167e60, 0xa3d464a7, 0x83f7f97a, 0xcf1fb3c3, 0x3e039525,
- 0x78eb6d50, 0xbf996d6b, 0x7c7286d2, 0x8e50b994, 0x9be65bbb, 0x315d2146,
- 0xa219cc11, 0x79f3d61f, 0xf02876e8, 0xe5f20b65, 0x1a10c73a, 0x7751f86f,
- 0x1fbc0e74, 0xc613768e, 0x7eec5b7d, 0x0efc23f4, 0xe2072eef, 0x14ef5673,
- 0x8cad4fdc, 0x85b5aeae, 0xdf6bef3c, 0x8f89ed06, 0x1fee22bd, 0xf8c03f95,
- 0x7cdaf1bd, 0x02cfa9a0, 0x20c855e3, 0x0f5459a7, 0x655ade20, 0x3ef7bede,
- 0x5611a5fa, 0xf97bf229, 0x95befd60, 0x536df3f8, 0xfd17d21c, 0xcb93b424,
- 0xee1a4f45, 0x16c1b27b, 0xe003ae17, 0x1fbf1077, 0x06c931b4, 0x4a1efffd,
- 0xc4d3d3d4, 0x6b8e74a5, 0xfb40965a, 0x8f7fba44, 0xa4fd0b7a, 0x4d17bf3b,
- 0x3c2ec8fc, 0xd3e30c38, 0x4e9cd109, 0xeb558fd0, 0x1b1d6ac7, 0x48ffbf94,
- 0x8efe491f, 0x141dbebe, 0xe0e7ea04, 0xd735d74d, 0xd841f885, 0x83ffea1f,
- 0xa5b48cc2, 0x1f9affc8, 0x7c61f647, 0x7b45dd70, 0xce21ac65, 0xebe0d3e6,
- 0x0a3e4748, 0x3ed147b5, 0x7d67b3ed, 0x0cdf57f3, 0xf4e2767a, 0x715e0096,
- 0x6e8acb5f, 0x6fe817fe, 0x36b3d81a, 0x8d3ec3c0, 0xf8660e2f, 0x3d4fdc44,
- 0xfba05c38, 0x79450fdc, 0xe095aa73, 0x5c5a8938, 0x33cb5120, 0xe5e28c4f,
- 0x1eb8620f, 0xaf863cfc, 0xbca837d7, 0x1c88e89e, 0xbdad9847, 0xeb89a9ff,
- 0x91f935f7, 0x684fd1f3, 0xedaaf5fa, 0xfc211cde, 0x8e13eebe, 0xdd7dda09,
- 0xe3c76f94, 0xfe340bfd, 0xe8873b06, 0xf8abb414, 0x876e9d7e, 0x4d9f6d9e,
- 0xf78213f5, 0x2c047bbd, 0x9f904f3d, 0xf148aef4, 0x6f58e2a1, 0x55a5e622,
- 0xcb8e4544, 0xf4f0d20c, 0x38a30d59, 0xcfdc29ef, 0xb7bfe6cb, 0x1b25f585,
- 0x1d7ba49e, 0xe29f994a, 0x1a1b45bd, 0xc8aebf68, 0x80a7302f, 0xc78799fe,
- 0x943a3581, 0x710d116e, 0xb552c5e7, 0xe4139b1c, 0xae1dfc5b, 0x9b25f7d0,
- 0x57ea19c6, 0x1816976f, 0x7a823bf2, 0xbfec90a7, 0x3e757ef0, 0x8f4fb70f,
- 0xf10d38d7, 0x861b05ee, 0x78cdf217, 0x73217ede, 0x36177cd1, 0x11ef1966,
- 0xb2b84c6e, 0x1ec1827b, 0x538445f5, 0x3fa8fd26, 0xf7f80e3f, 0x17f7c485,
- 0xe08c3a7c, 0x7bc38bf8, 0x8e018c5d, 0xc433e668, 0xdff326cf, 0xf8f1b429,
- 0xef8ff023, 0x7e407652, 0x07f577cc, 0x1fc01dae, 0xfa87fdc8, 0xb9937903,
- 0x024d65fe, 0x9c4ce0e5, 0x66cfb46a, 0x6e75f0c7, 0xc1b44c76, 0x679a2b3e,
- 0x6b57376c, 0x776b5737, 0xa84a38b9, 0xa164265d, 0xe9fde33e, 0x71951fbf,
- 0xffca6dfa, 0xedc310dc, 0x6eaa9fd7, 0xbbf40c6f, 0xd0773b56, 0xefdade6f,
- 0xf735ad4a, 0x5e5285e5, 0x1e6fe6e0, 0x09dfc3ac, 0xf601dde9, 0xfcc1e83f,
- 0x7ba0df67, 0x6eeff4ba, 0xb432d15f, 0xa954f008, 0x8bb973c9, 0x15dcafcf,
- 0x3f418790, 0xae1ce529, 0x827d96b4, 0x5a5df214, 0x22b76f09, 0x2ff06cc6,
- 0xffd5a27f, 0x6549c635, 0x1840495a, 0x3652ed06, 0xec24116d, 0x0b577f0f,
- 0x66a949e0, 0x93dfd0fe, 0xedcf194a, 0x6fc7db9a, 0x04e61616, 0x9a68d0f1,
- 0x5c62a391, 0x85da3135, 0xaa47cceb, 0x50f10eb7, 0xce8051fe, 0xa8fc4c49,
- 0xbdbb425d, 0x23d7755b, 0x7078eb7f, 0xae0a6a8a, 0x711fd1a3, 0xfcfa9b38,
- 0x30bebe62, 0x4766a8f6, 0xe976eb37, 0x42edc661, 0x5712a75a, 0x3efc308e,
- 0xb69c6261, 0xef32244e, 0x37da854e, 0xa327a232, 0xccae24f9, 0x2c76e66e,
- 0x2cb4f7a7, 0x3e7c16cf, 0xb1c8f06d, 0xd647df78, 0xbf8480da, 0x26dafe3b,
- 0x51fbc453, 0xc3fc359a, 0xf9c59e3c, 0x9cb8f3e9, 0x99dbd05e, 0xe84f8807,
- 0x3d3d10f2, 0xd8c1dfb2, 0xff3ef4e3, 0xe97bf8d9, 0x997acafe, 0xc74e4f7e,
- 0x69eab77f, 0xb4a6bc41, 0x3708166c, 0xdc7a78da, 0x5ca39f0e, 0xe78d971e,
- 0xfb94073a, 0x16873b15, 0xbd7dca85, 0x1cd9f44c, 0xdbafe796, 0xe1887ff7,
- 0x5890eaeb, 0x4bc43ecf, 0x8a3adb65, 0xc2d92cef, 0x4067f77f, 0xfe215cfc,
- 0x07ee1284, 0xfbe1cf94, 0x4acff95e, 0x7ab2ff44, 0xe5acfbfe, 0xb8f077db,
- 0x0b998fce, 0xcb7943f5, 0x0728a10e, 0x8773077f, 0x9f0428b0, 0xca7ee5a9,
- 0xaec6bf83, 0x5bd71fcb, 0x718efce1, 0x0e53b462, 0xe87eb8d9, 0xb87c57cc,
- 0xf669dc1f, 0xcebb6396, 0xe61768e4, 0xfff8e977, 0xe99b8efd, 0xa77db5dc,
- 0xa3658025, 0x8ac939a9, 0xcad70efb, 0x6eabe42e, 0xe9127bd5, 0x5a792713,
- 0x78d8fbf1, 0xbe16abbb, 0x58d85a75, 0x3c72b955, 0x8fe30c4c, 0x72e63f89,
- 0xf43aa493, 0x24b186bc, 0xeb9daa37, 0x67d7132d, 0x1e7ccc87, 0xf787193b,
- 0xb3ee3107, 0xe3878724, 0xf294dc68, 0xca1f9d00, 0x70d3bd38, 0x5fc830ce,
- 0x1b7dbfee, 0x2c3fff7e, 0x00284ba1, 0x0000284b, 0x00088b1f, 0x00000000,
- 0x7dd5ff00, 0xc5547c7b, 0xbddcf8f5, 0x0dd90afb, 0xdc3bf79b, 0x24280c10,
- 0x01049e6c, 0x878424d9, 0x28026e20, 0x47796bc8, 0xd2026c92, 0x6dfad0fe,
- 0xe5318316, 0x16d46b6b, 0x882ea945, 0x835ab696, 0xb80d06a2, 0x47d62228,
- 0x2d8aa523, 0x2220a5da, 0xfb1b6484, 0x6fcb56c0, 0xec9999ce, 0x0f0d9bde,
- 0x7cf9fb6b, 0xdcc98fe1, 0xe6739f79, 0x9ce7339c, 0xb5331d99, 0x228ca8cd,
- 0x389aa6a4, 0xfd2d34bc, 0x84e90ee9, 0xf00b9085, 0x8321226f, 0xf121326c,
- 0xbd3ca484, 0x582c524d, 0x1c5a7fbe, 0x052627d6, 0xaed84bbe, 0xa0af9686,
- 0x84225ba9, 0xa0e4258c, 0x31cc7881, 0x2ae8b484, 0xfd68d947, 0x7b488496,
- 0x663b2d13, 0x68db4573, 0x9d63967f, 0xeab4ac07, 0xa33e6398, 0xda4bf68b,
- 0x4264c7e9, 0x121230de, 0x8c1ddb41, 0x6dd3ed60, 0x42229074, 0x07891b26,
- 0x233d1bbf, 0xc1dfda14, 0xbfb083a1, 0xa6eab797, 0xc37b697a, 0x19d8b220,
- 0x9b74ef32, 0x6ca5db0e, 0xe8e921dd, 0x5a48b8f7, 0x513f321e, 0x595b01ef,
- 0xcc67cc26, 0x43844ed4, 0xae3d56dd, 0x1ce8c2a7, 0xb05466b6, 0x8fe868de,
- 0xe6ed7bd6, 0xfa7e8c4f, 0xbd2fc7fd, 0xbf50246f, 0xc1b47255, 0x37df5bfc,
- 0xa9a1c9ce, 0x4932e7e7, 0x613a6420, 0xf0bf36ff, 0xdfa151be, 0x70a6efa7,
- 0x76eaf5a2, 0xa32fd2ef, 0xc5a95769, 0x24268d23, 0x8b6bccf3, 0xdefd2148,
- 0x74112266, 0x5736dd6e, 0xfbce8d91, 0x0e535dcd, 0x58845149, 0x20f9339f,
- 0xc421f015, 0x06b4e19f, 0x3a5225e7, 0x722fce30, 0x10b3fd2a, 0x55ef46b2,
- 0x95ddf099, 0xb7eb4559, 0xccf830c6, 0x42e0cc1f, 0x157bec2c, 0x0b80975f,
- 0x8c0a7f1d, 0xdce5915f, 0x2454fd01, 0x329bd846, 0xaff99e61, 0xebdc2999,
- 0x823d92ec, 0x672b8d56, 0x579d0cf0, 0x79b84e65, 0xe2f1c06d, 0x44f8d963,
- 0x7180cfef, 0xefb2f109, 0xf9216932, 0x3873f6c1, 0x1f77e9be, 0x3a864efb,
- 0xd7f38273, 0x4d836fe2, 0xe861fac2, 0xa3ac116c, 0xc7cf98f6, 0x0f53ace8,
- 0xe6799674, 0xd043e230, 0xeab6cfcd, 0xd5fd1531, 0x5fd88cd9, 0x708f4d9d,
- 0x1a780cd9, 0x2c03534c, 0xcc1ba69a, 0xc7850f5e, 0x1f26f39b, 0x7e297292,
- 0x20fa316e, 0xb4b7437d, 0x48dfca16, 0xe8b7e361, 0xdf216b74, 0x34859772,
- 0x6e1d5e21, 0x376bcf98, 0x6a7e2147, 0x26bd1ae7, 0x9f8fcfda, 0x63de5897,
- 0x67fa12f1, 0x72f66bad, 0x22e24768, 0xfe024fec, 0x738c075c, 0x4ae9fdac,
- 0x51bf6e79, 0xb7a7dfa1, 0xf027fdb1, 0xe8c6db50, 0x0107ec4b, 0xbd3c20d7,
- 0xf024fdaa, 0x8db07f31, 0x17a505d1, 0xcecd7780, 0x3349db08, 0x0102eb1b,
- 0xe5568cfa, 0x6d93dbeb, 0xf3044727, 0xd007f035, 0x81620ec1, 0x79f2d679,
- 0xeeb9d3ce, 0x6755fd83, 0x50341ff6, 0x0d1f16d4, 0x881f7ee0, 0xffd66b7e,
- 0x0164fb3a, 0x0e93ab21, 0xadf62a61, 0x7f7aa861, 0x6f78e56f, 0x7bb69482,
- 0x4d4dd382, 0xcbee1b61, 0xb80d939a, 0x19532d9f, 0x231cb35f, 0x133c508e,
- 0xdebe43f2, 0x457db17b, 0x9964db64, 0x71e2bdc2, 0xfa44d6c9, 0xaba44fcf,
- 0xa36ce224, 0xf5b67dfd, 0x0025a8f5, 0xc82eafdf, 0x37ae98a4, 0x3777ad82,
- 0x3b5d3be7, 0xde91c029, 0xcc248c1b, 0x3fb72f7a, 0x01223be2, 0xec386b3c,
- 0x1f2e9ebb, 0x17a529fb, 0xf6c1cecf, 0xcf92e8ab, 0xf6eb3d3e, 0xbbbce94f,
- 0xcbb44c76, 0x4e4d3640, 0x7c409fa4, 0xa53b7d84, 0x4c99389f, 0x37de2895,
- 0x351ebdb4, 0xfcfbb68e, 0x81f3a397, 0xf7cdbf6f, 0xe5e799fd, 0xbb9700f5,
- 0x75ecf67e, 0x95e35e50, 0xce304d62, 0x95ffc7ce, 0xdea9fb42, 0x26100f51,
- 0xd57cbf4d, 0x74f5a7e8, 0xfbec6dde, 0xa836c1ce, 0xf713f9f7, 0x6ef0075f,
- 0xf2c26b6a, 0xc36c4f33, 0x7b3f6bfc, 0x683fdf76, 0x94675abd, 0x799dea1d,
- 0xa5e23f7e, 0xc077a5d6, 0xeba2077a, 0x33f6bbcd, 0xe126d97e, 0x1973237e,
- 0x2d74131f, 0x9ff3f7e8, 0x2a1b1e2d, 0x16f7c437, 0x833b9723, 0xcb391c98,
- 0x994d6ff7, 0xb3d205a5, 0x85cc44cf, 0xfe8dbaf5, 0xcf9868ec, 0x1f174628,
- 0xb6d47871, 0x2db831ad, 0xf9fb1ed8, 0x487bee80, 0x9e7d2873, 0x6b4ef4a2,
- 0x0050b8ed, 0xeb0afde3, 0x11257ad3, 0x2f37be14, 0x7cc12e38, 0x18354722,
- 0xbf9e706a, 0xd574e564, 0xebc5e5a1, 0xe96a3d18, 0x059b0be0, 0x907d8beb,
- 0x4d32bbb2, 0xb2603e41, 0xd6ce3e33, 0x6aed5297, 0xd7efd2b2, 0x65d973af,
- 0x4f97c78a, 0x4a9c9e1f, 0x211b3ff3, 0x65fe2015, 0x8f39c989, 0x5ba9c705,
- 0xd04e465f, 0xd9a2eaf9, 0x11b0497e, 0x07c8b5fd, 0xd7ba31b6, 0xf205bd13,
- 0x89f200fa, 0x072e16ba, 0x1279b077, 0x96632073, 0xae59db15, 0x83ce098d,
- 0x3058b3b6, 0x29b8c81f, 0x678ee407, 0xc51dca2e, 0x233df388, 0xe4f101f8,
- 0xee09cc2e, 0x711d04b7, 0x8c13fe01, 0x7e30b534, 0x4ffb4953, 0x8a4d2e8f,
- 0x09a60a2e, 0x16b95883, 0xf2f0b74e, 0x923b451f, 0x3b5e01a2, 0x60f25563,
- 0xdaf2be20, 0x6e4cddcd, 0xe91c72bf, 0x08740dd0, 0xaa4ebbe3, 0x6472f6e4,
- 0xf70e94ae, 0x5c3a471c, 0xabf8cede, 0xb8d4bdbb, 0x259ba68c, 0xefe61732,
- 0x7404f4e6, 0x9bf9a764, 0x7d71a3a2, 0xd9fcebee, 0x39baa7c0, 0x61ef75dd,
- 0x4e86f6f4, 0xbcf801e7, 0x36e47db1, 0xf95a0790, 0x113b5528, 0x6f8a6edf,
- 0xd67a0493, 0x67a0c3ba, 0x3b1355d5, 0x6ef757ec, 0x081a1fbe, 0x7b7707ee,
- 0x2fe872e5, 0x5d9a6e35, 0x992f5096, 0xeef34a9c, 0xfb04525a, 0xd96b652d,
- 0xd20ba01e, 0x20ab912e, 0x0ddced5f, 0xab8fafed, 0x2099cbb3, 0x9927b6f7,
- 0x47ebfd69, 0xcdfb6314, 0xf4294ae9, 0xb620a9e7, 0x706f2127, 0x9cdb3ca1,
- 0xf20ed23c, 0x88daedce, 0x0651177a, 0xb89ca1d9, 0xbea16bf4, 0x6c80b3db,
- 0xe3ecc292, 0xcb03923d, 0x08de91bd, 0x3b7a7eda, 0xeddc7fd3, 0x139f1f6c,
- 0xa1a911f0, 0xd78c1173, 0x788982fd, 0xbd9d20a4, 0x930a67b9, 0x509a2fb3,
- 0x746d9ece, 0x34541390, 0x10568c8f, 0x358e02af, 0xa03a99ad, 0x9966425b,
- 0xf8cb1e60, 0x4c0d5a3c, 0x3973446e, 0x9b2f7590, 0x1fbe72c7, 0x78eb4796,
- 0xaffbe46a, 0x9b05c995, 0xe0e41727, 0x921e3e39, 0x73970245, 0xe5bae874,
- 0xb527dc3e, 0xe2feb34f, 0xdbbc8e4c, 0xe855e842, 0x6c7a5a47, 0x6ca6e3e2,
- 0x3301203d, 0xa55ad949, 0x57d7e7da, 0x5d3d5f13, 0x755bf5e7, 0xa8b989be,
- 0xfc82dd37, 0x6c91837c, 0x77f7fa97, 0x5be3344f, 0x3cceb115, 0xcdd7e409,
- 0xfa3fd416, 0x8720e9f6, 0xb8f4022e, 0x84dec97c, 0xea1670ab, 0x09d3bd68,
- 0xede03b56, 0x5a8e1c47, 0xbdafab7d, 0xd19c0f46, 0x4325c9ea, 0x4186e969,
- 0x549e0173, 0xa198b75f, 0xa7b68d9d, 0x8fb612f5, 0xf213627b, 0xf7ec26ab,
- 0xeb1b68f6, 0xd859d627, 0xcb2e2c00, 0x27c98eb9, 0x7adc3dab, 0x9e85a3d2,
- 0x074f28bd, 0x82db33f4, 0xafc7e1fb, 0xbd194b48, 0x01284151, 0x41fdb23d,
- 0x5278fee8, 0x3d447a41, 0xf4e0ddca, 0xb647a786, 0xaf54dc5f, 0xd29b3d02,
- 0x27a65ae3, 0x4fdb085b, 0xa7232e8c, 0x7c007932, 0x159f542b, 0xefbb54fb,
- 0xedf6fd05, 0xefdccbfb, 0x1fb606dd, 0x801c29bb, 0xfce8fbde, 0x9be74665,
- 0x48fdd036, 0xfdd137cb, 0xffc214d8, 0x981fe7b5, 0x04079c27, 0x73663dbf,
- 0x745f0076, 0x19ab7f6f, 0x47f396c9, 0xc83fcbf7, 0x65de98be, 0x5fb4ca86,
- 0xa1afdd33, 0xe0a663f4, 0xea63e6b6, 0xb9113901, 0x8947ad5e, 0x266883f4,
- 0xdeb1bebf, 0xa3d24238, 0x55f1c3de, 0x007d73ab, 0x46f41e7c, 0x6324114a,
- 0x131bd33d, 0xde00e640, 0x417a47b6, 0x20484e3f, 0xccc2e7ae, 0x67df3f67,
- 0xfce29f02, 0xeac51090, 0xff7df2f7, 0x4ff7af29, 0x4b9c869e, 0x3a283f70,
- 0x0f2271d7, 0x3b448f2c, 0x172c2f3a, 0xd73be9f3, 0x137cd998, 0xbedecaee,
- 0xc18f0429, 0x3e75757d, 0x5eeb37e0, 0x25a97e9f, 0x8b908e38, 0xf981ba5a,
- 0xf581fc83, 0xb81a8e54, 0x7e7eeb5e, 0x71d0d33e, 0x7b5fdf04, 0xb482b8a8,
- 0x2bfbe0d5, 0x5635c7ee, 0x2522fa02, 0x9d2c4707, 0xe1befd57, 0x088d1f6c,
- 0xeafb4364, 0x314dd758, 0x9331dfb4, 0xdfa0fef8, 0xa09ce0ab, 0x0c531e27,
- 0xf5e0dde0, 0xd3f9e087, 0x8f7fd618, 0xe991ecd5, 0xd623b8fe, 0x3ded0d15,
- 0x03eec465, 0xe5077339, 0x896fb027, 0x4df808af, 0x0147f13d, 0x5d58c79c,
- 0xbf4031f1, 0xc9366772, 0xf257fca2, 0x63f7c2e7, 0x84b95111, 0xfb71f3f6,
- 0x85799f6f, 0xcaf85ab6, 0x03df85b9, 0x22317afa, 0x18e2e803, 0x513b97d5,
- 0x830656df, 0x944bddbe, 0xfc30b6c1, 0xcc0ba457, 0x20beb33a, 0x55663f98,
- 0x7a442f9f, 0x6fc30c4d, 0xe214f9fd, 0x09fe8589, 0x627bbf9e, 0x1f5df614,
- 0x56ea8230, 0x78833e7f, 0xeb1f7f68, 0x985b7548, 0x30c53771, 0xc84ddb7a,
- 0xf7e570d4, 0x0f7671f1, 0xb030fb65, 0x7f02f24d, 0xe1bf5eac, 0x07e532cf,
- 0x3eacebd5, 0xe831694c, 0x8f36d56f, 0xc7f3474f, 0xd11f8c0c, 0xc5cdb37f,
- 0xeb47b941, 0x0e03c7e9, 0x4b20f43c, 0x2e52e0f9, 0xbc3596b7, 0x13d825f9,
- 0x3cc4f5aa, 0xdcb3f69e, 0x4a983cec, 0x2cb33e8b, 0xbfb6028f, 0x25b73bf2,
- 0x5c4a5c80, 0x32eccad0, 0xf40d9264, 0x4331c95e, 0x317910be, 0xfa8f4b3d,
- 0xe29fe231, 0xe7188beb, 0x82f7c04c, 0x80f504c1, 0x7a45b705, 0xd07c213d,
- 0xa5a1e1cc, 0x7eb84f9b, 0x767feda5, 0xfe81196c, 0x739ca23a, 0xdc163e81,
- 0xcfc54e76, 0x53ff25ba, 0xad5d028f, 0x649fdab1, 0x433865dd, 0x623bfee8,
- 0xc43af3bc, 0x675e4f53, 0xa04cfaf6, 0x87c640df, 0x30eacf60, 0x940a3cd9,
- 0xa2cf111b, 0x291a9fdd, 0xe60ecbe3, 0x361e9e97, 0x196be819, 0xde0337b1,
- 0x1244b597, 0x033f084f, 0xc3e81805, 0x3f609e7d, 0x3cde3b4b, 0xaddcfc0a,
- 0x2c9d23f7, 0x8f105b35, 0x9c7af3ee, 0x74316907, 0x8a7b45f9, 0x8e5123fb,
- 0x9e7d60db, 0x9f47c67b, 0x263f491a, 0x7eb8efd2, 0xfdf0edd7, 0xe228c8a1,
- 0x4b78fa00, 0xf3a70ef6, 0x832b35ef, 0xeabc2863, 0x460e948d, 0x734e3763,
- 0xd243fe88, 0x77fc6aac, 0xcc25f5bc, 0x65d9b967, 0xc2be3904, 0x32a7cf41,
- 0x6457c9e0, 0xef8a151b, 0x9185f2f1, 0x45ef8f97, 0x6c7fbf7c, 0x661ff4a4,
- 0xe1c7dd1f, 0xa5ea23df, 0x71f27db0, 0x0e7ea906, 0x4a686bd2, 0x943c7ddb,
- 0x3e79f3e7, 0x604bd79b, 0x9f7c1df9, 0xeacb9c7c, 0xc5f1c769, 0x3b36fe30,
- 0xe015b1d6, 0x8cf9db45, 0x22fb1740, 0x16b7a8bc, 0xfc077e52, 0xea3a6d6d,
- 0xedaf94ad, 0xc4d97ac0, 0x4cf58d17, 0x03485728, 0xcfb07be5, 0xcf84148b,
- 0x274a52a6, 0xd7b03cb4, 0x04aedb64, 0xa9f02af1, 0x8c7b63c5, 0xc3c9eff4,
- 0xd43e9251, 0x61e5428e, 0xa3b30c7b, 0xd27f6118, 0x9e991899, 0x85f10c36,
- 0x3e5f2274, 0x608c6ebe, 0xf4fba078, 0x7bd418b5, 0xfba1397d, 0x97c704e5,
- 0x0f1f67e0, 0x8ab5e352, 0x5e6de1e3, 0x8d8c516f, 0x007b4fc9, 0x31c7ddf7,
- 0x165c7eac, 0x0f424393, 0xcb8703ff, 0xc8549a4d, 0xd5533195, 0x1c4dc5fa,
- 0x44c5379f, 0x087ebc09, 0x88f215f3, 0x345f17f2, 0x5e0b0fdd, 0x217f2135,
- 0xb0d9031b, 0x63bd68ff, 0x2c0a6e58, 0xe472a58a, 0x18dfaa26, 0x22ddb1f3,
- 0x3cefdf68, 0x85d04a3f, 0x3e9c8095, 0x1853d625, 0xe54f7e40, 0x296bae1d,
- 0xba437ca1, 0xd037fe34, 0xd694c93a, 0xd8560c87, 0x03a64ef9, 0x208fed02,
- 0xe147f40a, 0xb850e7fe, 0xc63bc76b, 0x319fe0e9, 0x96f11e92, 0x9f70f247,
- 0x7585ffbd, 0x9cf2ed21, 0x51d1eccd, 0xceb8ffbe, 0xe9fa0175, 0xd42dfdba,
- 0x7d198fcb, 0x3096add9, 0x63df46e5, 0xf2c1490f, 0x3d973fc5, 0x762fca46,
- 0xe4fd7677, 0xa5eeba66, 0x861db29d, 0x5fe77a5c, 0x7a031ddf, 0x0ec1a775,
- 0xdf2a46e7, 0xbcc3d5ef, 0x791e981b, 0x83a6a74c, 0x9f55dfb3, 0x1962d273,
- 0x83dea8be, 0x3be09cfa, 0x4adf7e42, 0x5c81577c, 0x461c465f, 0x66b4ff48,
- 0xe1420cd5, 0x0eb2c2b7, 0x6be7d1f9, 0xbc1ea1a7, 0x7cb07892, 0x4fe18b59,
- 0x4561f2a1, 0xeabf3aab, 0x56fe7561, 0x67df3aaf, 0x2f0f2e7f, 0x32c7a7df,
- 0xd94b3e3a, 0xb03fe03e, 0x3d05e4c1, 0x98af5b48, 0x3ca4cbd7, 0x24f813b1,
- 0x4760fb95, 0x48e11758, 0x6ebebe04, 0xc5e2696f, 0xe7f57cec, 0x10de21af,
- 0x37a8237d, 0x6c6f12e4, 0x63cb7eff, 0xf4238415, 0xe071f0ab, 0x2cb671bc,
- 0xc6263afc, 0x10653d0a, 0x8bbe27f6, 0x45e3827e, 0xcfea3ce1, 0x8f98079b,
- 0x5d9fdb05, 0x1b9c7e19, 0xa9b1c6fa, 0x7db064e4, 0xfc6b931c, 0xa3e82d1c,
- 0x7e127cfe, 0x07a17917, 0x31a5db07, 0xd9a48afd, 0xf906454e, 0x8b63b094,
- 0x224270fd, 0x3bb464e6, 0xebcfcfdd, 0x5fb05cf6, 0x083d009f, 0x6514e3f6,
- 0x714e9f9f, 0x66c6f7d9, 0xf70687eb, 0x941d768b, 0x43f8ceae, 0x58b2eef8,
- 0x6b8e1c6b, 0x57187627, 0xdba2fbd0, 0xe8bb062b, 0x6778ff7c, 0x546ba279,
- 0x30f53f28, 0xe85189bf, 0x9c95165f, 0xbc391a25, 0xd42dfdac, 0x95bea8bb,
- 0xd3e74c0d, 0xbd23b7bd, 0x04ce24af, 0xbd9ef3a0, 0xff5c33c3, 0xf315fc86,
- 0x6259e599, 0x9ba79820, 0x2abfee98, 0x1d599f3e, 0x99d3ef4c, 0xc71c061d,
- 0x025b1441, 0x7cd9a51e, 0xd3d4f329, 0xf9be84fc, 0x908e9183, 0x12fe7cf1,
- 0x9df0a7b4, 0xd4b253c0, 0x36f30495, 0xbc74b8c1, 0x824de208, 0x5dac69b4,
- 0xe4a27481, 0x3079b3d4, 0x0d264f3c, 0x675f5069, 0x9d6ccbf6, 0xd0090674,
- 0x985e0fbe, 0xc6fcf2b7, 0x568bbdd9, 0x158b77c0, 0xcf9188f9, 0xe52c4763,
- 0x2fe46687, 0xc9b75866, 0xfd1cfbe2, 0x94f53c64, 0x3d8fb829, 0x3bda0943,
- 0x02369106, 0xe72c5ae3, 0x1b58b03c, 0x8f9049b1, 0xe0faf5b0, 0x66ce70fc,
- 0x2346e8f1, 0x0b19dc9f, 0x677a527c, 0xf285e025, 0x19ff6665, 0xc3ef5ca8,
- 0x73e0b773, 0x4d7e7c31, 0x1325cf9c, 0xe2588706, 0xb01ef1c0, 0x40419cae,
- 0x49d65984, 0xd44b7ed0, 0x25eff454, 0x7969e000, 0x8abd54ec, 0xd53bc56f,
- 0xeab9c4f9, 0x9d4bb27c, 0x3f93d337, 0xcf928be8, 0x16217499, 0xc02359cf,
- 0xfce062de, 0xebcf99a2, 0x3d74a408, 0xfd3e71ef, 0xbb13f58d, 0x8eeebcfa,
- 0xe3b41231, 0xd0cd9825, 0xde57d53f, 0xcafa658b, 0x97281e27, 0xf3cfc803,
- 0xc0f9b626, 0x837cd3ae, 0x7e8bbf64, 0x1b2ab66f, 0x3d5494f4, 0xc76624d3,
- 0xf54adbd1, 0x865b7cb4, 0xe689becd, 0x1d7ec1eb, 0xd5b7f30b, 0x49f68d3c,
- 0x0247ab13, 0xdc8fe0cd, 0x8366c9b6, 0x81e5717a, 0x8bd046c9, 0x76db1057,
- 0xbfbe8612, 0xce86fba2, 0x53c809f7, 0x5e9c48bc, 0xf3290f22, 0x7cbc0d71,
- 0xc59dfc07, 0xe18b13f2, 0x65feca5c, 0x3a75e475, 0x90e0eec0, 0x77d62e51,
- 0xa16ebde4, 0xcecd65e3, 0xb3bc3b43, 0x0973f99c, 0x3463f7df, 0x905c6afb,
- 0x8f3cb1ce, 0x707587e7, 0x899c6ebb, 0x746d6bf9, 0x36666288, 0x8c71fac0,
- 0xfc44edfe, 0x5af2fb63, 0xfd07fc12, 0x47fb0795, 0x5829343e, 0x7467dc1c,
- 0xbdb37ca8, 0x1bd696a9, 0x87edf7a3, 0xa78e3c7d, 0xa37d3c79, 0xbf9406f4,
- 0x628b3a9d, 0x6d7db1d4, 0x861302ce, 0x14b80653, 0x04d07edb, 0x7c904cfd,
- 0xbd4c6698, 0x5fa609bf, 0xd147edc5, 0x06ef4649, 0x12a68eba, 0x77b4678a,
- 0xd820f9fc, 0x4907e5a5, 0x88e9e001, 0x0739c841, 0x7a15d39e, 0x3a1afb1c,
- 0xfd406c98, 0x2a932ffc, 0xd5013bf0, 0xd2bbce8c, 0xbe2116c6, 0x755f2c0f,
- 0xe36a3f28, 0xb337e464, 0x6abf32a6, 0x57b35cfd, 0x10ce4092, 0xbbd277e6,
- 0xb10a6f32, 0xc43f0897, 0x773206fb, 0x44f39857, 0x4fd31c6d, 0x3b3066ab,
- 0xa346fd6f, 0x1d537fca, 0x335eecc7, 0x8c8f26e3, 0xfcc47943, 0x5c7179a7,
- 0x46411b6f, 0xe10a9f00, 0xaf504523, 0x81edf4ab, 0x9cba8cf8, 0x8e3999f3,
- 0xfdea0302, 0xbe08df9c, 0xf6c41cee, 0xd2423cf3, 0x9367ae81, 0x87ffe406,
- 0x7e456f4b, 0x18f11373, 0x951f6f00, 0x310278b1, 0xd55359ef, 0xa71cd27a,
- 0x5cf37f3a, 0xf0c51ead, 0xe79dc621, 0x09579752, 0x5aaa783d, 0xfff05e0f,
- 0xb9468abe, 0xdd54f89a, 0xe7e02185, 0xc000f660, 0xe873f30b, 0x1bdc6e91,
- 0xbebc3f99, 0x388def3d, 0x127767d8, 0x4976cfbe, 0xb2ffd1cb, 0x82115a4b,
- 0xaf5ad4ff, 0xb8647204, 0x987dd855, 0x7934e4de, 0xc3df83f7, 0x91128359,
- 0x49e3cebc, 0x493c400e, 0xadbe907e, 0x57165665, 0x30b51c41, 0xa45b349f,
- 0x16fef41d, 0x65da3e5d, 0x2aaca25b, 0x0da6fa3b, 0x13d4054a, 0x44c558f6,
- 0x6e9c6df2, 0xd7779dc2, 0xbafe31c5, 0x71766259, 0x9e333ccf, 0x9cb3e32b,
- 0xbc413f2a, 0x9d828e4c, 0x229c6470, 0x63fda3ea, 0x5c95c1b3, 0x44af5340,
- 0xd2171197, 0xd11b265e, 0x4fe1a8ae, 0xb476b1f1, 0xce0fc7eb, 0x9cfd3b41,
- 0x2fb43c8e, 0xfd844b12, 0xffd8292a, 0xf4dbd99c, 0xdf53a710, 0xdcbf4db1,
- 0x7bbba412, 0x8d5cb8e2, 0xaf409124, 0xe7ba767d, 0x7ba7684c, 0x5ffce75c,
- 0xa35acba0, 0x2171ed0f, 0x07df8af4, 0x38ab8b92, 0x9cca18bd, 0xf9d056f3,
- 0xb46bbcf5, 0x1d19f9c3, 0xe7ffb46d, 0x9da344f7, 0x50455f51, 0x652c6d3e,
- 0xec07a47c, 0x9f1d745f, 0xf9e35745, 0x8ad4a360, 0x663ba3f2, 0x6af1d232,
- 0x073c01cb, 0x74a56f57, 0x569f2218, 0x6be750ef, 0xdf9e2748, 0x47ee9f6b,
- 0x0517c8cf, 0x56ef761f, 0xd4c323b7, 0xcb8f377c, 0x7da77c8b, 0x7d4c0556,
- 0x9d8b3dae, 0x8641e9c3, 0x1de8a3ae, 0x2eefb723, 0x008a9db0, 0x7494fb56,
- 0xc7adfd31, 0xfb665a7a, 0x2283c99f, 0x6e568e3e, 0xedbd7115, 0xe0bfca3a,
- 0xb0f42afc, 0x07f2c222, 0x92721d74, 0x42df382e, 0x7fe84ede, 0x7c084e42,
- 0x52109695, 0xa743f742, 0xc9434fe0, 0xed37c050, 0x0489f71f, 0xd8314391,
- 0x7dce07bf, 0x9478f8e3, 0xb7203c1e, 0x17b33a3d, 0x6a59abe8, 0x06693940,
- 0x9ba69f3d, 0x83ca1724, 0x323daa97, 0x692c7bc0, 0xd6833598, 0x8cee6f1b,
- 0x3a513804, 0x3f4a1239, 0xb197c44d, 0x11d1524b, 0xbf457796, 0x848e961d,
- 0xc47df33c, 0x74e998f4, 0x054fd0c5, 0x7a687e38, 0xc8e76240, 0xeb1f9629,
- 0xbadbfda1, 0x53274869, 0xf30f5789, 0xf1a9b0ab, 0x9d49253f, 0xa3f4a69f,
- 0x70c38c0f, 0x1f4e7870, 0x08772ea1, 0xfcd4477e, 0x857c932e, 0xc1f9187a,
- 0x5d80efc1, 0x193d7221, 0xd50dfa01, 0x6a1f7144, 0xb8ebe0e9, 0xf26fdd6f,
- 0xbf185c75, 0x13b70f49, 0x2bfc4b5f, 0xd3fa969f, 0xeb1bf759, 0x7a10a4e5,
- 0x65e2fb14, 0x907f8b03, 0xa9fe655e, 0xe5193312, 0x642afa03, 0x3fb14576,
- 0x8cfa05ae, 0x315dd209, 0xcf119eff, 0x19086ce9, 0xa1367402, 0x5327c23d,
- 0xfef1e4bc, 0xcbba05ae, 0xe223ea0f, 0xd254d15c, 0xa532be8f, 0x705fd42c,
- 0xa47d09df, 0xd26b6a40, 0xb91f0267, 0x1be609a7, 0xe3434f42, 0x512f808b,
- 0xda7dc27a, 0xcbaace4f, 0xf026f435, 0x52e5f42e, 0x367480d2, 0xea60a75b,
- 0xf2855cab, 0x5b32dcb5, 0xacdfed0f, 0x0936f462, 0xea0b31e8, 0xdca5e9ab,
- 0xe96bceac, 0x0ba88e91, 0x9f4b571d, 0x10dbd103, 0x5f2137a0, 0x6f4d2f63,
- 0x75bfe3d3, 0x7f1e9b7a, 0xd2d37a11, 0xbb5fe099, 0xa0e56c22, 0x4b57d73f,
- 0xde0a0f28, 0xf904d61d, 0xa89975e1, 0xb68aef4f, 0xdf5d7ea3, 0x3b0bcac0,
- 0xbdc4321d, 0xe5e3ad64, 0xc872ce99, 0xe5a7afd7, 0x23a2ebb4, 0xd8662e2c,
- 0xef3cac9d, 0xadd786ae, 0x587867a0, 0x6f3f97fb, 0xb968a396, 0x2fb799b7,
- 0x7c872d6d, 0xff6b0b7d, 0x46a9f819, 0xb79a7c43, 0x7d5fbe09, 0x1d9da66f,
- 0x3efe99ab, 0x9777af91, 0xd8ebdcf4, 0x5bb595ae, 0x883cd075, 0xe99ff9e0,
- 0x75f1d7e5, 0xd6cadc4e, 0xfae27719, 0x8ba50aa9, 0xea0f0115, 0xb574a76f,
- 0x06dfc8c5, 0x4a973f38, 0x4e9069ad, 0x5217eca1, 0x22ded987, 0xcc7e650f,
- 0x7b8874ed, 0x45fd99e2, 0xce20fff8, 0x9f4432a0, 0xd99e27b8, 0x84bd4563,
- 0xa0018a18, 0xa8ac4787, 0xa4ff0b5f, 0x812221ef, 0x723587bc, 0xbfac243d,
- 0x03564a72, 0x865311ea, 0x5fa53f08, 0x9b8e94bf, 0xc98be177, 0x3f43ece1,
- 0xe69ee3e2, 0x7a7d1371, 0x075337b2, 0x880bb174, 0xf4800524, 0x7f41afde,
- 0x487e05db, 0xa43ca426, 0xf2caf004, 0xbd7fe35b, 0x853c65a9, 0xef41aeaf,
- 0x2196a101, 0xccc9dc61, 0x1c1be24e, 0x53fe7fd5, 0xc467c4f4, 0xff362638,
- 0x1e544d95, 0x7e31d123, 0x8fe38736, 0xe90abf8c, 0xd3c73677, 0x2a7f05cf,
- 0x9fc00520, 0xddbc70e6, 0x347aa664, 0x8356c3f2, 0x133c6f86, 0xcb6a720f,
- 0xbabbfa80, 0xaa57c35c, 0xb92bb8f9, 0x092b7ede, 0x4a727ea0, 0x7a7a62f2,
- 0x6bdbd30b, 0xbf50472c, 0xe98479e9, 0x8fc4b5ed, 0xbed68ffa, 0x9d53b359,
- 0xe7536baf, 0xf9d5dbeb, 0x8e0f1c9e, 0xaea5b3d3, 0xd58aec18, 0x768bbf0f,
- 0x5fc16aec, 0x42fe6abc, 0x5fc67115, 0xed06ba1e, 0x6f98df51, 0x6f4f4d3c,
- 0xd0b8aac5, 0xfa9c02df, 0xb22f35ec, 0x613714f8, 0xeb1e8276, 0x4e70f988,
- 0xa4791a25, 0x9c7927e5, 0x86fb089f, 0x84792fe0, 0x8e7a23c9, 0x8241d77d,
- 0xd7ab5c7c, 0xbd73c4f5, 0x84d39f97, 0xfa0793fe, 0x35d3d00f, 0x4164480d,
- 0xdb7f6439, 0x9fc88724, 0xc0668579, 0xee99be73, 0x6c978067, 0x545971c9,
- 0xca05f0f4, 0x7bcf8199, 0xbd0d72ea, 0x2dd6f388, 0x81665e9c, 0xff8e8527,
- 0xe781c97b, 0x32b7c3ba, 0x5963997a, 0xd1faf487, 0xe22f466a, 0xe7e577dc,
- 0x4dfc873c, 0x747d79ce, 0x5ef54112, 0x17491e9a, 0x8fe67ce7, 0x1d1897af,
- 0xf87d55d4, 0x82cfe818, 0x246e1c2f, 0x3e10faf1, 0x64cd34d1, 0x934a3b06,
- 0xaa839d81, 0xbc5c7fa6, 0x38cf8434, 0x13134a22, 0x88ee5940, 0x5d6cfb47,
- 0x669c7aa4, 0x7fbbf3a9, 0x4fd2f380, 0xd44ed123, 0x954130fb, 0x70eb77a4,
- 0x6b3edb8c, 0x31527e60, 0x7707559f, 0x7ec3f3ee, 0x08ebff5c, 0x359f953d,
- 0x5ac5f792, 0xe4c4b65a, 0x6a7186ca, 0xb3233e74, 0x5fa27663, 0xb03b8c57,
- 0xf283d65d, 0x931af8d5, 0x106901c3, 0xefd2e1c6, 0xb5fea1d9, 0x4f8c89d1,
- 0x2aeb11df, 0xca0f8848, 0xa43f614b, 0xc6a49652, 0xc126fd04, 0x376606f8,
- 0x5c710bf9, 0x6361be32, 0xb69e7d88, 0x568f1b0f, 0xf5f8c096, 0x61ce29f7,
- 0x1da307de, 0xd39f30e5, 0x9a7b8fdc, 0x474efdfb, 0xcce03f31, 0x752cfabe,
- 0xf734f4f1, 0x518e9e13, 0xbd4487fb, 0x8ecc09a5, 0x6cd1b272, 0xbf07a8de,
- 0x1c6f313a, 0x21ec4946, 0x93c60353, 0xea78602c, 0x6dbd13d9, 0xa5ff8853,
- 0xfbf4a12e, 0xd87f9f30, 0xba43379c, 0x31b8f5bc, 0x23df0ed4, 0x0f77f3b1,
- 0x089e97a7, 0xeb718a96, 0x0fbf2a12, 0xe799ec78, 0xe5f63c47, 0x13bc8ac7,
- 0xc099effb, 0xfe5f6bf8, 0xb84f2c3b, 0xf5d843dd, 0x69f7f207, 0xd0547bfd,
- 0x044073b0, 0xfd6bcfb3, 0x3f050bf3, 0x05f9fee3, 0xec2d1f9c, 0x45827e60,
- 0x4a9cd266, 0x247717cb, 0x946e73b2, 0x9fe55b27, 0x515e44f7, 0xcba0863c,
- 0x3ecef49e, 0x2123f67f, 0xee3aecfe, 0xeb13accf, 0xdf5eaddb, 0xbadf0903,
- 0x8481fb3f, 0x6d6cfe30, 0xa08bc3dc, 0xe20b0c47, 0xc18dad61, 0x2dae42ad,
- 0xef6f7b07, 0xe8718272, 0xd65adf6b, 0xb5e0f604, 0x2a0b003f, 0xa7d431f2,
- 0x079c38eb, 0x53bc575a, 0x9d951447, 0x4251107d, 0x8aec9fe6, 0x4351e551,
- 0x4d03890f, 0xb5514ead, 0xaa186f4f, 0xfd643faa, 0x4cf2aa35, 0x9f2abe4f,
- 0xaaad72d5, 0x65ad55fe, 0x87f0fcaa, 0xcfd557af, 0xa3074323, 0x0c90ecfd,
- 0xb57221b6, 0x3e554ab7, 0xaa2de772, 0x86919ff6, 0xbd69e3cd, 0x79fe42dd,
- 0x8aa39d1c, 0x39ce7183, 0xed554b6d, 0x62b6a49b, 0x9f46f01f, 0xbd6893e4,
- 0xcb5f1c15, 0x62ff993b, 0x556afb74, 0xd8a367ff, 0x5fad183d, 0xa32e7696,
- 0x912ed61e, 0x7efea447, 0xfb8eeada, 0xa8ee219b, 0xf296bfbf, 0x356eda4d,
- 0xfe80bf3d, 0x8e6fd5a6, 0x5d3f7026, 0x7461490a, 0x0b0ba5ad, 0x5bbd7fea,
- 0xe627b465, 0xc687ec91, 0xc40cbc23, 0x5fc7f4ab, 0xae76612f, 0x76ada7de,
- 0xf559ff88, 0x47a432d6, 0x2e9a9253, 0x5d351422, 0xd3508e44, 0xa6aed585,
- 0x6a25c183, 0x3dc2d03a, 0x0ba6a1da, 0x43ffa7e2, 0x2ae02de0, 0x553b1ee0,
- 0x785a374d, 0xda0093e7, 0xc95eddd9, 0xfc6123ee, 0x70dbede2, 0x1fd2975d,
- 0xf86a89f5, 0x34701c16, 0x2c6e1059, 0x61e84cbe, 0x68ffae26, 0xaf4213fd,
- 0x7ae44b89, 0xf847ef15, 0x0f259a17, 0xfe7d51ea, 0x865f12c2, 0xa7f4132f,
- 0x44ecc206, 0xf0c4a4ce, 0x3efc4676, 0xc0519d90, 0x2620f675, 0x03886b2f,
- 0x882be1ed, 0xc9ddf90b, 0x3ed15bca, 0x63f2cab4, 0xad9ebbf4, 0x35527a62,
- 0xbf9f22f1, 0xaa02b8e2, 0xfb109287, 0x528e16ab, 0x02b3e487, 0x20f2e1bf,
- 0x79087485, 0x1378c2e0, 0x62e6864a, 0xad471f95, 0x30df82e7, 0xbd097f84,
- 0xe0278c57, 0x189af829, 0xe41a44cf, 0x1a17d824, 0x6846473e, 0x3b6a48fd,
- 0xe0f3b08d, 0x22fe2160, 0x44265dad, 0xe9916e0f, 0xcc90f238, 0x57f14226,
- 0xdda07360, 0xce7488af, 0xe625ef87, 0xc2bd26b6, 0x935713ed, 0x80c4fb3e,
- 0xfe12eaf2, 0xc91e59e8, 0x7f6668ff, 0x6bf0b43f, 0xf89fe5d3, 0x5e3c6d03,
- 0x55ef1052, 0x078f0f2f, 0xa76fea7a, 0x857d1fb4, 0x02eb23f6, 0xc3f6a1b1,
- 0x9206fbbe, 0x1373d71f, 0x424ddc71, 0x693710f4, 0x133f3c9b, 0x4e54c4ec,
- 0xecca4146, 0xab5da458, 0x8ed1eb07, 0x012ba3ac, 0x2121afba, 0x60ccda7e,
- 0xfee5e639, 0x74371179, 0x42e27d29, 0x3fc78da2, 0xc22778b0, 0x5f38a0f9,
- 0x139e740e, 0xcf701471, 0x2221fc16, 0x9139a84e, 0x4973839f, 0xf74ff42e,
- 0xb444a6db, 0x29fdd01f, 0xbec7ee85, 0xef2c22b8, 0xeb351fb7, 0xb2147117,
- 0x42ed10b5, 0x7bd742cb, 0x7a10f019, 0x3ea86fcb, 0x1234f780, 0x0dd7a615,
- 0x0381f63a, 0x553b0b8a, 0x46f59e71, 0x7b01807a, 0x8e3c8bc1, 0xafad4daf,
- 0xe3c89b3f, 0xe739f893, 0x181af052, 0x4eee3c1f, 0xf532e3e0, 0x27771130,
- 0x7f42f8e0, 0xc151efb8, 0xd8bcefb5, 0xe13df707, 0x72e02ee0, 0x29f3a8ae,
- 0x3d6c97c0, 0xeef00092, 0x83ee7288, 0xfd47e9fa, 0x705d24a7, 0x1772155e,
- 0xb6f6cbc6, 0xcf3f78cb, 0x5bc5813d, 0xc8c8f7b9, 0x4c3bba1a, 0x6ead37e8,
- 0xc2f51d7f, 0x68ca46ae, 0xa6761ea9, 0xbfa90e91, 0x0340bd88, 0x47ce81ef,
- 0x681f3d62, 0x75e22fd6, 0x7f7f3ae8, 0x3efc3809, 0xe42a1c1c, 0x9ee18351,
- 0x919c5f57, 0x1551903e, 0x75da1f42, 0xb0f4e66c, 0x013cef56, 0x4cef1dfd,
- 0x55fd0cdb, 0x53071dc8, 0x24eb3e00, 0xd1357fbc, 0x26cbeec4, 0x2574fbf3,
- 0xdc3b06fe, 0xb34a4e37, 0xe1a9fde0, 0xe09d91df, 0xdd78fe17, 0x4f70316d,
- 0x5c3ff44c, 0x4efde1d2, 0xe4fb9e42, 0x57f0428e, 0xa26fb02e, 0x162685b9,
- 0xddf99197, 0xe5165f48, 0x891aaf23, 0x61a3f619, 0x6bde0368, 0x68cb4409,
- 0xc9938cb7, 0x313ba024, 0x561f716f, 0xfafb877c, 0x7c52ef70, 0x2814d89f,
- 0x0ed34b58, 0xdd620f4e, 0x0503cb13, 0xfc20960d, 0x16a65c45, 0x3c385b3e,
- 0x66c6f1dc, 0xcdbb17d0, 0x52c9fce2, 0x9f23d362, 0xfb666759, 0xe255d8e6,
- 0xc2b3edfc, 0xe11dd4b9, 0xf6063c18, 0x7932fbdf, 0xb17f2692, 0xe3470639,
- 0xc7d415fa, 0xbb58d9d7, 0xbf071e6e, 0x44b2a3ee, 0x6f8e5f88, 0xa66f1f0a,
- 0x5c73b124, 0x8beff72d, 0x1f7ab5ef, 0x42d58dc6, 0xf04176bc, 0x6bc695fb,
- 0x01fc788b, 0x27ad10e1, 0xef78d1fa, 0x7ab179dc, 0x0e4bfcaf, 0x3ebebe7b,
- 0x0fe22749, 0xcf4defd1, 0x0be3615b, 0xf9d8934b, 0xe807182a, 0x7dc37bc7,
- 0x4a7b85f1, 0xce45c913, 0x0ef3eefb, 0x889fdc55, 0x9f9f7737, 0xfd7e7184,
- 0x29fda5fa, 0xe15c6096, 0x92dff040, 0x86e5e6c8, 0xd082bf78, 0xdefb0aef,
- 0x8f1c4e37, 0xc147f3df, 0xbb45fd3e, 0x7feaf78c, 0x75374871, 0xd779987b,
- 0x5db83127, 0x7dc7af13, 0x1c47d233, 0x2f8cc2db, 0x35fb89ea, 0x76aa9ee2,
- 0xfccbbb7e, 0x10fe608b, 0xbc6e1c47, 0xc48e9ca5, 0x30c777bc, 0x99f7b87c,
- 0xed059ef0, 0x77bde317, 0xe257f8c7, 0xf1a9b0be, 0xd7b73b7c, 0x9fdebeec,
- 0xa6bcf781, 0x40c33b31, 0x728de0f4, 0xd8f504fd, 0x4a65699b, 0x06fac53f,
- 0xffb216c9, 0x410f452e, 0x7854ebb8, 0x23770fed, 0xfbf457e2, 0x4fbe61f9,
- 0xe702c389, 0xbe5c25b7, 0x8351d92d, 0x1f38affa, 0x8cb0fe7d, 0x139f17f1,
- 0xbcf927e6, 0xcff3c255, 0xeb211752, 0xf95a1f29, 0x88334164, 0x844925b9,
- 0xbec3175c, 0x46e909df, 0xf97c9fb5, 0x87ecfdbd, 0xaeae5424, 0x57280d20,
- 0xdd58fe56, 0xfbdc9aae, 0xb49fd067, 0xdce1fbfe, 0xb1d6272e, 0x479e8939,
- 0x2629ef40, 0xd61f20c5, 0x3185f93e, 0x1f78194a, 0x777ca69c, 0xaff81e98,
- 0x46aed319, 0x48bfa61b, 0x44963c72, 0xc927b7f1, 0x9ed20db5, 0xbdff59f7,
- 0x7e4cbdb5, 0xb9438d6c, 0x2efd64d5, 0x087975f2, 0xc0f7ebe3, 0x1e14093b,
- 0x97d31326, 0x720d7412, 0x5e2dea14, 0xf1e387a4, 0x6266aa6b, 0x74049ede,
- 0x29cbf71f, 0xefce3153, 0x800e9197, 0x4752a6f7, 0x3625d81e, 0x997bb255,
- 0xb3f31366, 0xf6317f7b, 0x0c837035, 0x0cbfbb6b, 0x8eb6c1ce, 0xf7b03efd,
- 0x7cfee8b4, 0x5a57e210, 0x8bf163ae, 0xfeff3a09, 0xe2f190d4, 0xe049bd23,
- 0x691f8f87, 0x388f38c4, 0x21af34b9, 0xcdca5e24, 0x9edbd171, 0x1ec27685,
- 0xb61bb083, 0xa8bde045, 0x8183a1da, 0x18435c8f, 0x1bdc459e, 0xdf5421cc,
- 0x8470a2ed, 0xbf914ba0, 0x19f24da6, 0x12fdf0a2, 0xded4e3f4, 0x0f984be5,
- 0x7ae7ea72, 0xf98983f4, 0x5c9abdc5, 0x212efe06, 0x364be69f, 0xfae34766,
- 0xfe223cfc, 0x5cd97f31, 0xb8f3274e, 0x923f3f1e, 0xb1297bc1, 0x5bbb4067,
- 0x474a24cc, 0xf2fcd4b7, 0x675c22b6, 0xf41a218d, 0x19f7e105, 0x6f08cf58,
- 0x653f72ff, 0xa58df765, 0x72743640, 0x62e7c286, 0xf9c030fb, 0xdd9b3bb2,
- 0x88c323bb, 0xee8cfc03, 0x81b7c37d, 0x8834c27d, 0x7f29aff9, 0xa3e49732,
- 0x73866d5e, 0x44afadd4, 0x2f22f8f0, 0xc8ec4fbf, 0xfa9cf883, 0x8c7cb4aa,
- 0xc01a3913, 0x0dba3777, 0xc7dc0cfe, 0x5448ef94, 0xf2da0e36, 0xb87a19fd,
- 0xf54299af, 0xd92f9a35, 0x0fcb2f72, 0xd1d4aff5, 0x4f2d92fc, 0xfdd3d0cd,
- 0x7fc6bee1, 0x5b35f20a, 0xbe7cb176, 0xf34ca57f, 0x655e5bcd, 0x4960e1f5,
- 0x2dc1ec09, 0x68786707, 0xb9a267ff, 0xf1fbb7bc, 0xe5fbb59e, 0x3b50bae1,
- 0xe332636b, 0x9db8675b, 0x59264cf8, 0x1ef0055c, 0xb2febe11, 0x5a0f1d64,
- 0xac54c569, 0x4927b457, 0xf325dbe1, 0xf7e56e71, 0x924627a3, 0xb7e60896,
- 0x3c5144f3, 0x8e18e81c, 0x93afc77e, 0x6e9e9862, 0x38fbe3f3, 0x4f011fa2,
- 0x77189fd1, 0xe067c835, 0xac789acb, 0x3f8664ec, 0x1c46ce3a, 0xdd839867,
- 0xcb4aae2b, 0xbc51fc03, 0xf4de39e9, 0x8dbbfcec, 0x1bf68fcd, 0xa0728b9d,
- 0x07f8ec00, 0x33f5a2be, 0xd2d6f383, 0x93324149, 0x3136b72f, 0x3a206b7f,
- 0x6269e90b, 0xa5677f24, 0x668ebd50, 0xe4c6870e, 0x466f7e68, 0xc2512bc0,
- 0x1c389a71, 0xcf78fcd3, 0x5dd74af2, 0x775a1ff1, 0xf01cbe08, 0xf681ca5e,
- 0xf5b3b7ab, 0xcd7bf0c4, 0xd4188cfe, 0xf557eef7, 0xa6836677, 0xb8c1097d,
- 0x164c7736, 0x8227bfb6, 0xd93bf198, 0x332ed7de, 0xa0ade997, 0x2c778acf,
- 0x123ae788, 0x7bec47ea, 0xc58da2af, 0x39d70667, 0xd3af90a3, 0x6369d7c6,
- 0xe8aaf4eb, 0x64091c95, 0xa7f6b6cc, 0xf7f83ee3, 0x9f2a37f5, 0xe7daa7f7,
- 0x7d83fae1, 0xd65e103d, 0xd6f93a73, 0xa9e622f0, 0x9c1f6781, 0xf013f335,
- 0xed8dfd84, 0x52e9a946, 0x5926b3cc, 0xfb35939c, 0x8e1bf33b, 0xd5daca57,
- 0xb9e2cedd, 0xeba6a289, 0x3a99ddba, 0xed102b88, 0x1027c16a, 0x3dffb41f,
- 0x89edcc9a, 0x806d2469, 0x93c7c4f8, 0x0ddac28b, 0x9cf6bbf1, 0xe2cd13d8,
- 0x8af6b5d5, 0x277b789e, 0x9cf4afdc, 0x8c0aef63, 0xc06fd8d3, 0x259cf4cf,
- 0x5f282ed8, 0x9c73f9d4, 0x3fb7f63f, 0x7e603205, 0xe7b2a685, 0x47d53b15,
- 0x7e431cb6, 0xecb8385d, 0x7f9a4cb6, 0xc88ff935, 0xcb530bcf, 0xfca4c8be,
- 0x9fb27f7c, 0x7d9647e5, 0x5bf21431, 0x44feacfc, 0xefc0f3c7, 0x633fc789,
- 0xaf507252, 0x41592d78, 0x3ae5c9b8, 0x02647402, 0xc7ae8625, 0xe309aaf4,
- 0x075c04f6, 0xba4d0b4a, 0x6ff77086, 0x07a3eedf, 0x812957e6, 0xf3b0153f,
- 0x5f803b71, 0xf403b2af, 0xdf7bb144, 0x8eff7b3d, 0x483e5df7, 0x1e027576,
- 0x16bb23ea, 0x5dfcd265, 0x1fa09f91, 0x3dd0724f, 0xc515f601, 0xf9d01646,
- 0x9c9b5d4a, 0xd5913fa0, 0xe11eb376, 0x745eedca, 0xfc28178d, 0xf3f7d95e,
- 0x61b2a5ef, 0xb18f309c, 0xefd40f9c, 0xe06ff2fb, 0x633fadf7, 0x7af983b1,
- 0xdb96c76c, 0xdb1aff40, 0x4c97f6f1, 0x39fbb30e, 0xc163de62, 0x97bf49ae,
- 0xfe709bb4, 0x5eae3b63, 0xfdc7f501, 0xe80b23b6, 0x5f31c264, 0x9e85b013,
- 0xaaa52fbd, 0xcf90e5ee, 0x39d71a2e, 0xc04ddfa0, 0x54aa53e3, 0xf478460d,
- 0x857c7832, 0xf1dd67f1, 0x68fd9b87, 0x7fdf54fc, 0xfa3afaa2, 0x20c97b91,
- 0xc433f83b, 0xbdad7a7d, 0x5d2568f4, 0x213efd1f, 0xa2106740, 0x6f3c4f4f,
- 0x98248ca6, 0xaad1252f, 0x5939b97c, 0x96c2bf55, 0x929f2aa9, 0x7caab574,
- 0xcaa7929a, 0x56311f4f, 0x7b06ff55, 0x637f2aa9, 0xfd5534c9, 0x2aa5474a,
- 0x536be79f, 0xd4382fd5, 0x423f2eae, 0xfe43c064, 0x90ebfb51, 0xa0749d16,
- 0x74f8b5d9, 0x8e90ebc3, 0x87030bfd, 0xed7c5ed6, 0xe1d7b6f9, 0x6b17b0bb,
- 0xfb0933ef, 0xc5b2cdf1, 0x276f0c6b, 0x0567d24e, 0x75901fdf, 0x18d33eec,
- 0x94eaebab, 0xa67de0a2, 0xa62f6089, 0x7c58a848, 0x00e347ee, 0x3d980b4f,
- 0x062028ed, 0x68adbee3, 0x686a3c87, 0x2c0fe678, 0xf81d200e, 0x5cc084de,
- 0x9e27bad5, 0x5dd6a977, 0xe0d56e4a, 0x5f2a8d69, 0x555dbb61, 0x06d24a7f,
- 0xe534f955, 0xdd3c1a07, 0x60dfcaaf, 0xd3c1a2df, 0x7e9e0d36, 0xf4172aae,
- 0x5aedc1dd, 0x451ec0fb, 0xcefef1d3, 0x75c3c072, 0x8f8803a7, 0x72d6ce92,
- 0x47b5d3c0, 0x855f10db, 0xb039673e, 0x0d43e2cb, 0xa3ea43af, 0xf76831e7,
- 0xa612635a, 0xb4151a07, 0x1c6c1d6b, 0x46a1e981, 0x75ff7e3b, 0xefa60963,
- 0x7d303a34, 0xa62a71af, 0x4c4e8d9d, 0xb0db1adb, 0xed8d73fe, 0xdb162ecc,
- 0x3a45def7, 0x75ba07d8, 0x8278377e, 0x77923f17, 0xeecbf003, 0xc86efe41,
- 0x37ec45df, 0x25f9a24c, 0xbee844c0, 0x374f29fc, 0x80023aa4, 0xca1c3757,
- 0x18f1828a, 0x1e473a6d, 0xa477e1e8, 0x3ea1f84c, 0x37bb909d, 0xd16c9338,
- 0x79a66f2c, 0xb3c63644, 0x83a1f84d, 0x2033d712, 0x33a9d04a, 0xf7c806e1,
- 0x7772b044, 0x401b84ca, 0xfec6ff0f, 0xff3f4773, 0x61291df9, 0x9ccfe7fc,
- 0xd760ac56, 0x70d5fc39, 0x30e3c02b, 0x48396fb7, 0x4d09619e, 0x0679f54b,
- 0x0747b390, 0x80f0b7b8, 0xe009b4ae, 0xcfb3a6d0, 0xebef78c1, 0xb7e8040d,
- 0x5fe7624a, 0xca95cf51, 0x0dcf41e4, 0x1d4f3c26, 0x605639d1, 0x7814995c,
- 0x3dbce00c, 0xdee112a5, 0x00640d63, 0x4e29bcfc, 0x3c0f8f96, 0xf243d926,
- 0x079f0606, 0xb6fc6e52, 0x3858f3e1, 0x62913cf8, 0xcfb6fa63, 0x807a0e91,
- 0x74a91fc8, 0x3e7ec1d4, 0x0ab8ea52, 0x4d38cfef, 0xad3aff6c, 0x3ed0abde,
- 0x139a28e4, 0x9219e762, 0xd1f7606a, 0xd82262e1, 0x71916f3b, 0x39e16b9f,
- 0x7be99521, 0xce702748, 0xe789179c, 0xf63a2382, 0xfeb6819e, 0xb3d70e02,
- 0xe3dbc283, 0xbd32a616, 0xdd566ca2, 0xfed02f33, 0x6045d67a, 0xe1ce3dd7,
- 0x34f58fa8, 0x342ae850, 0x8e70dd3d, 0x1cec9b95, 0x9dbfe824, 0xf2d17f0f,
- 0xfb6e3a67, 0xfd68efeb, 0xda45d64f, 0xaed88651, 0xc2ddf841, 0x358c2f2b,
- 0xb0b4fea3, 0xe40cbd2a, 0x07ee7ce2, 0x27d5645c, 0x1f503ba0, 0x1727846d,
- 0x9af25b97, 0xcac90429, 0x3c234ab8, 0xb69d5525, 0xd5d219a6, 0xc237eec3,
- 0xa3b52913, 0x1a833576, 0x70b7475b, 0xff3ff211, 0x5e748dbb, 0x0acbd78b,
- 0xfb89cf3b, 0x145735ae, 0xf7e822cf, 0xa23b8f08, 0xeaf3c040, 0xd16f0e22,
- 0xd787116e, 0x3fae1489, 0x0b9c90e6, 0x67d63f6a, 0x0b5def40, 0xc01ecddf,
- 0xe72ea0cf, 0x4607e3fa, 0xfdf6ae36, 0xe2ee3112, 0x3afe7654, 0x0994a462,
- 0x4c2de4fa, 0xfdcee40e, 0xba22aee2, 0x9b0edcfe, 0x1615e30e, 0x7800bdd7,
- 0x78e76de8, 0xd8769034, 0x4b3cb34f, 0x221df93e, 0x8f754e26, 0xd2f252f7,
- 0x0f2b69de, 0x7e859795, 0xbca87967, 0x96b4092c, 0xf2145c83, 0x7d4ff851,
- 0x2f9cd58d, 0x3d3f2037, 0xf31eb8d0, 0x983d1b07, 0xe16c6a1e, 0xcb15b97c,
- 0x987c69df, 0xe72f65f3, 0x7bf13bcb, 0x4c5ce347, 0x58ba35f7, 0x9519ca3e,
- 0xecc4fb0a, 0x37c4f8c2, 0xf80898b6, 0x4c3b7ae7, 0x77419f18, 0xc68f63c4,
- 0x0991fc41, 0xe36a71ef, 0xbe7cb490, 0xf7761e8f, 0x0525377b, 0x1f8be9c6,
- 0xc8717d02, 0x9874f4c0, 0x4be05628, 0xe4fe8ff9, 0x0fafd006, 0xf4158a2b,
- 0xcdd482e9, 0xac50ef2c, 0x7c2f9a06, 0x8a5de794, 0x22ac04d5, 0x5be421f5,
- 0x358a3d87, 0x1f8be682, 0x7b95887d, 0xc7f33a09, 0x06f5ba3d, 0x2259f00f,
- 0x51fd801d, 0x449cce6e, 0xd79505c5, 0x5f6007a5, 0x325a494c, 0xcec5f609,
- 0x63e90514, 0x00e1b29a, 0xd88fa7e4, 0xfaab87a6, 0x46de4b0e, 0x57165768,
- 0x937687a9, 0x846cd6d2, 0xdd879376, 0x376d0faf, 0x8daed475, 0xdf619f90,
- 0x74fd07a6, 0xf8b1f027, 0x2f223f60, 0x169f05ca, 0x3ba37271, 0x720f289c,
- 0x0f289ddb, 0x66ca5c04, 0xf60dde57, 0xc976facf, 0x663cc126, 0x0a417d4b,
- 0x86e89310, 0xbf2949f7, 0x97f53ebe, 0x5db40dd6, 0xc5afe43d, 0x7c370ffc,
- 0xa6fbfcbb, 0xfbfc30d4, 0x41dfbe43, 0xfbdc43de, 0x0ef64687, 0x2e1c33cc,
- 0xac4b1df5, 0x712a8ef8, 0x7acf4159, 0x97f3cb9e, 0x9fe5a520, 0x7f8bb4f1,
- 0x70e7407f, 0x52ab38c1, 0x3fb21fb9, 0x6549a87f, 0x8f735ffb, 0xce728064,
- 0x6d52ea1f, 0xea3cf7aa, 0x76bfbb08, 0x6d3b38a9, 0xee36b89c, 0x3b693564,
- 0x1fecc8e8, 0xf70b526f, 0xc7fab2dc, 0x6a788b7f, 0xdf781c6d, 0xe3106ab9,
- 0xd78173a7, 0x496eba50, 0xde4f901d, 0xdc38097b, 0xfd0e0e1b, 0x9c5843d6,
- 0x2438bf7b, 0x5daeef1e, 0xb3c57117, 0xfc798d77, 0x827d76bb, 0xafaffa2e,
- 0xcf5fc195, 0xbbf54fe0, 0x157e60c7, 0xec04ad8b, 0xe7fca156, 0x3fe11777,
- 0x6df67e5a, 0x179bc9f1, 0x65bbe1d7, 0xf3d8f861, 0xb898f8e1, 0x854dafcf,
- 0xf3f70a9e, 0xde121e20, 0x7e738239, 0x1f6ba265, 0x1653d3f4, 0xce0e9bf8,
- 0xddec71a1, 0xaed183f0, 0x325df0fd, 0x1106b8b2, 0xe75a7c97, 0x6de815f9,
- 0x19fa3def, 0x106eb3f2, 0xbc8f7416, 0x97a0f341, 0x7ce6c3fd, 0x4647e013,
- 0xefa18df8, 0x7f140f8f, 0xff2e1bfb, 0xdf6ca7fa, 0x9ed43889, 0xa0665f6d,
- 0xfb12eefd, 0x54782062, 0x70fde3c8, 0x24b7a43f, 0x9767e512, 0xdef07c44,
- 0x02695771, 0xe95d2dea, 0xdfa43d46, 0x2bb8b9f6, 0xd7fb1b3d, 0x92bb8f9e,
- 0xdc6ccc4b, 0x7d2153c9, 0x2154f92f, 0xf0dfbdc8, 0xa376cbf8, 0xb03de0a7,
- 0x408d8f0f, 0x928dfeff, 0xa0e010bf, 0xbd77573d, 0xc94ca0b5, 0xa6be7fed,
- 0xeb049beb, 0xbbae3dab, 0xe95dbe1b, 0xfd76bb79, 0xb9c408df, 0x15ff5b8f,
- 0xaeeff781, 0x19ddfcfc, 0x5e80ab93, 0x12026ae1, 0xf545d319, 0x54bf9a09,
- 0x8939d6fc, 0x4333d39e, 0x6f25e5ce, 0x9e2e38b3, 0xfde7cf6a, 0xed5c09de,
- 0x960dc751, 0x5e308afa, 0xe147f645, 0x7b1d60bd, 0x73c4436f, 0xf3cfc9bd,
- 0x243ebcf4, 0x9d70ed0d, 0xfaf3aa19, 0xfa2d1f1d, 0x0881f21e, 0xa678ef8c,
- 0xcc3c44fd, 0xf19d8ff5, 0x0945793f, 0xedbd77d2, 0x9df4246f, 0xbdf5dac0,
- 0x86d77caa, 0x7056fbe0, 0x5ff6ab1f, 0x2a25ca32, 0x4f105ac7, 0xdae335e4,
- 0xda4af910, 0xef07dcfe, 0x55df94d1, 0xbe50c002, 0xd074cf36, 0x3cfc9576,
- 0x8de44844, 0x92aeda0e, 0x67891f9f, 0xe78f2b25, 0xb09f3df5, 0xff28ba7c,
- 0x7fac4ce3, 0x1c6fe895, 0x79164f2b, 0x22d5dfde, 0x9623789f, 0x25f68a67,
- 0xc6239f2c, 0xaded64af, 0xade4feac, 0x7a099cff, 0x33f7e08d, 0xe09cb8d2,
- 0xfe5152ef, 0xba2b4cef, 0xba8ebc68, 0xf107cb9c, 0x1dc5550e, 0x85df22d3,
- 0x6126dc7d, 0x9ded61ec, 0x9fe7b406, 0x0dcb698d, 0xe22f2fbd, 0x56e59c7a,
- 0x7baaf38c, 0x9976f871, 0x1e813bc7, 0xe9fb9cb3, 0xfa0b642b, 0x65ef7a61,
- 0x3d207e7c, 0x97fae570, 0x57ecf855, 0x46d3dfce, 0xef1d2547, 0xf1130fdc,
- 0xd619027e, 0xee02f189, 0x27c44934, 0x116abde0, 0x45971757, 0x8e7e701c,
- 0xbd82297b, 0x13b27aa7, 0x97caeff9, 0x6ebb7d98, 0xef28ebcb, 0xda0aca96,
- 0xea1ebe97, 0xe9f0075a, 0x2f77b2b6, 0x87dfae57, 0xc531f4fb, 0x8160fdc6,
- 0xbcf0a151, 0x3dfc3fb3, 0x8517f169, 0x3ffcbabf, 0x5dad7f0c, 0x5fd7dc5d,
- 0x7ff1857d, 0x07e656dd, 0xfd3c73b6, 0x7314a749, 0xf0023d78, 0x33a2b73a,
- 0x20865a3b, 0x778c4eee, 0x29df90ab, 0x6f56f382, 0xde009583, 0xdccea5bb,
- 0x5fe0c30f, 0x9f38ae7b, 0x69715441, 0xf7c3fb3b, 0xf7d04be9, 0xfa4dffd3,
- 0x8dfbd44e, 0x1f1bf076, 0x15e5ef65, 0x18c9fe77, 0x4ef41f1a, 0x0f073b1a,
- 0x317e676e, 0x2c171711, 0x713c32b7, 0xd55d53ff, 0xffc1e33b, 0xc4c3f624,
- 0xfe06d248, 0x76d74a04, 0xa076d74e, 0x41bf416b, 0x176d143f, 0xfa41be06,
- 0x912e2c25, 0xfdb7e9c3, 0x25e1fae1, 0x7fe1fae0, 0xa9bbae13, 0xdbfe8c3e,
- 0x4ed02217, 0x3ff385a3, 0xbc055c38, 0x0e2fd323, 0xfff4c8e7, 0xd3239c0c,
- 0x439d9515, 0xf9207bc0, 0x988fc5a4, 0x5a7d9877, 0xe9f64df4, 0x4f9c1923,
- 0x8f18fde9, 0x4c7bc5ab, 0x27bc3f7a, 0xef1c5fa4, 0x30fff2ea, 0xd370b5de,
- 0x9fdcb5a6, 0x985efdab, 0xfbbf203e, 0x7ff8e056, 0xb0b04fcd, 0x7caabf61,
- 0x54b7faf1, 0xef3c4be5, 0x415f965f, 0x5bfffbd8, 0x57e105fe, 0x2afcf998,
- 0xb51ff81d, 0xc43741f2, 0xc7a023f9, 0x7afe5f1b, 0xf93087d4, 0xb78c6cea,
- 0xe5af8dba, 0xff7ff18b, 0xbe947be4, 0xf66068be, 0x3ffb63d6, 0xfd392837,
- 0x79e165e9, 0xd084711d, 0xeff5c2d9, 0x5acf401b, 0x54fbd848, 0xa60ffada,
- 0xc6307b33, 0x30be5149, 0x710c4cd7, 0x9dcc1f94, 0xcf4beecb, 0x0c630705,
- 0x2d173ea6, 0x3e27a99f, 0xd2bb8f78, 0xd099f7a2, 0xffbea9ef, 0x75efe26e,
- 0xd558b893, 0x21d9783d, 0x9cdf9c63, 0xbd2fe612, 0xf786d2c5, 0xba1de787,
- 0x60f7dceb, 0x14f46f2f, 0x7177b8b1, 0xbaf7f0ff, 0x3e83f12b, 0x9c2a7a08,
- 0x5fee24fb, 0xff40635f, 0x2addb6ba, 0xca669fbe, 0xd9a38b12, 0xc533e2c3,
- 0x3beba4fe, 0xf767ca64, 0x48f7e060, 0xbe0c1b2a, 0x67a0b9e1, 0xbb3d47ef,
- 0x2e4364be, 0x927eafe0, 0x1b94dc74, 0xafd4ef3c, 0xd7b60bff, 0x7a6d67f2,
- 0x4fd5f6b9, 0xbd210f1a, 0xb1d17388, 0xb5e61f46, 0x1305d6f6, 0x93fd17ff,
- 0x6de2ff63, 0x57dc7482, 0xd0c70f8e, 0x3b1bfb75, 0x827b2dff, 0xbb0823b0,
- 0x214ed682, 0xbf7888f8, 0xe36e97d2, 0xa296b2ef, 0x59e883df, 0xc1edf82a,
- 0xd7f9fcfe, 0x27d717e9, 0x61ffe5d5, 0xf4b97cfe, 0xe4c49b5f, 0x8fee96aa,
- 0xed0cfd56, 0xb5be82cf, 0x6200bff4, 0x0bf8e852, 0x27bc25ea, 0xab55773e,
- 0xcdf49c61, 0xe5b57de9, 0x9b830664, 0xb15c2e46, 0x3c78503c, 0x0be78c87,
- 0x0ec6bc93, 0x87810f76, 0xefd5d3af, 0x48bc5303, 0xab971719, 0xfafff2ea,
- 0xa2e4e039, 0x8917266f, 0xcb489f4a, 0xe56eb7e8, 0xfe56eb12, 0xb90eeb9b,
- 0xd648b4a7, 0x40e3ef05, 0x81c435fc, 0xfdd978f6, 0x56ccead4, 0x5203ddfc,
- 0x7e028812, 0x995eeb77, 0xde8e9efd, 0x790e4fa1, 0xf88bad3f, 0x5c7a003e,
- 0x3bbd9e35, 0x769b8da4, 0xd5ea78f3, 0xbf78dd96, 0x9a0efb51, 0xf376cb88,
- 0xa1efb4fe, 0x9de2f689, 0x687bed03, 0x1c783253, 0x67c93e76, 0xe7172971,
- 0xcf20dda3, 0xdd35fc43, 0x5da2355f, 0x4ac7c6e1, 0x05a4f3ee, 0xa32732f1,
- 0x9799df1f, 0xa3be7171, 0xd32fff2e, 0x81dd6caf, 0x94aed8f7, 0x3a64477e,
- 0x827f40dc, 0x9bf1f72f, 0x6fc84c57, 0x3df33bc4, 0xf7c19e6b, 0x24be7a87,
- 0xd4bd97e8, 0xbb13e33b, 0x09c435d8, 0x564dbd27, 0xc771d78a, 0x1baf683c,
- 0xf785c47b, 0xe3bcc776, 0x927f8880, 0xc329c077, 0x233e85bc, 0xff209bf4,
- 0x78d9f7e2, 0xf2e5d59c, 0x37f52bb9, 0x8cfca7fe, 0xb75d5ee2, 0xbf0457c1,
- 0x13d9e0e7, 0xa103bf81, 0x1993ff9d, 0x93be8bba, 0x7ae511dc, 0x8b34f012,
- 0x5ef109cb, 0xdecc8572, 0x94edef49, 0xeeb85ed1, 0xabfb7e7f, 0xdb4b9547,
- 0xbd6dea15, 0x2265cf61, 0x7bb1d7ad, 0x0ae5f92d, 0x79c249c6, 0xc287ec0d,
- 0x7fada89e, 0x297b294a, 0xe35bed03, 0xdeda3df1, 0x067cd987, 0xfafd57c2,
- 0x603f8e00, 0x7ebf1f39, 0xf42d916f, 0x19f3959d, 0xdb43e77d, 0xdf107329,
- 0xff174b97, 0x332dced7, 0xa891e265, 0xbc91cd7c, 0x4c25ef4c, 0x3a405dff,
- 0x02445d31, 0xbb08ba98, 0xd894b0cf, 0x9c4e5d31, 0x5c55ae98, 0x3718195d,
- 0xf8c04814, 0x39ff17d3, 0xdce6e80a, 0x215ae375, 0xf2dbf146, 0xbef56923,
- 0xbd853c9e, 0x3fc2f497, 0xd9f4077f, 0xcb863ff3, 0xa2471be2, 0x1848641c,
- 0xa57bd33f, 0x54d7bb32, 0x17dc5df2, 0x325dfde2, 0x96e1f989, 0xfee26627,
- 0xc4cdf209, 0x826f826d, 0xb8e7393f, 0xdcc3c58e, 0xc67be12a, 0x6e1d7eed,
- 0x99159cb1, 0xb9ddf85e, 0x3cacddf6, 0x2bda2ea7, 0xd8ce7cd1, 0x26be5608,
- 0x4ff70bda, 0xee3f1216, 0xfb70c5cb, 0x4bfb8644, 0xdf8a2f8c, 0x8227a00b,
- 0xbf6d12a1, 0xeeccc3a2, 0x30ff1051, 0x70b9ffe0, 0x4f170a7e, 0xf1f18433,
- 0xbf1943d1, 0xb6a65d1f, 0xe5e50c87, 0xdf6529f7, 0x0cb47807, 0x810d6471,
- 0x9b9d31fa, 0x3b042c1e, 0x9f808e90, 0xb7b1b3e6, 0xb4535fa3, 0x1b29517b,
- 0x959ff501, 0x67bfbc58, 0x4c6fbf2f, 0xfea10902, 0x794ab5b1, 0x1a2bd42e,
- 0x40d3f8c2, 0x51df8570, 0x2f398674, 0xd1d1f88a, 0xbb436670, 0xd277c13c,
- 0x7e58959e, 0x6f5be3f2, 0x5f4168dc, 0xe3f40782, 0x44d71517, 0x91b46f18,
- 0xffcc0b10, 0x1b7efca7, 0xbb00c869, 0x4cc7aae8, 0x3e2fd03a, 0xee18e2a2,
- 0x9e81fcf7, 0x98fd21b7, 0xfd219b9e, 0x43373d23, 0x9b9e9c7a, 0xcf413d21,
- 0x38ae90cd, 0xccc7876f, 0x8e2189c9, 0xf0bfd0b9, 0x5be769f7, 0xd7f18439,
- 0x1af7f1be, 0x14fbfc71, 0x0fb7c217, 0xfe087bdf, 0xd1b3edde, 0x8b989481,
- 0xdecf5bd0, 0x749fa3bf, 0xff08b820, 0x0a7cb6a3, 0x6eee6bc7, 0xdcffca3d,
- 0xcad47f76, 0x872b7a90, 0xce7db118, 0xa0a3270b, 0x1f5b6eff, 0x5d121d7c,
- 0xcb1d4cf2, 0xb9fc7caf, 0x828e371b, 0x0fbe3bf9, 0xf9f74174, 0xdb73486a,
- 0xfc00fb7f, 0x1fed2a5e, 0xa47a24e3, 0x2f3c66c0, 0x85a1d668, 0xb3d75883,
- 0xa09b9dd1, 0x0c2fb3fd, 0xbe509585, 0x01bed843, 0xadc2923a, 0xe7ae0377,
- 0x10a05346, 0x78dd0bee, 0xa71b0e41, 0x8a529f7d, 0x7a064e70, 0xcaddfe43,
- 0x025f4653, 0x7f74df6f, 0xe223fb6b, 0xa5e015fd, 0xafa5c80a, 0xac2f40a2,
- 0xed04f1e4, 0x06fd87bb, 0x2439e9d6, 0xdabdf813, 0xfdea31d1, 0x49e38bb7,
- 0x8d7b39a4, 0xb3d7c04e, 0x830d4f7b, 0x7e2989f7, 0xc57bc186, 0x455c86db,
- 0x31ef7f42, 0x8f97ec67, 0xf587183c, 0xe769f7f1, 0x10156d91, 0xbcdf3337,
- 0xd2580dff, 0x0af1db42, 0x9c599b88, 0x74841d24, 0x19399289, 0x7dc465e2,
- 0x4a236583, 0x9a96c20f, 0x7d44af61, 0x4c9814ae, 0x37287c88, 0xd847f247,
- 0x558a3c85, 0xa524a7e5, 0x534feaaa, 0xd3e554b2, 0x95548c47, 0xd867718b,
- 0x46f5540b, 0xc28604c7, 0x83ae8e79, 0xa4ff03bd, 0x3986f18c, 0x7eb91c2f,
- 0x7ccfcd24, 0x43be0e6a, 0x9f2f2cf9, 0x17b95cf9, 0xe143d1f0, 0xd50aa469,
- 0x6c1f92e9, 0xd33a107e, 0xf76a179c, 0xa1d0713e, 0xe179c65c, 0x8184e712,
- 0xed164fde, 0xca04e7b5, 0xbe001f37, 0xd9c5fa39, 0x3edbf036, 0x14cbf63b,
- 0xcdfd4788, 0x0caefe10, 0x440c3f3f, 0x43fb7d37, 0xbcdd1852, 0xc3279325,
- 0xf2440dd0, 0xe9643a32, 0x7eecc3cc, 0xb5f295de, 0xa1af814f, 0x4243c0bd,
- 0x6b577f7f, 0xb46d1bdf, 0xb036e6ff, 0xc32bbd47, 0x7bbea50d, 0x6fe12b93,
- 0x64ef4839, 0x93bbb6f9, 0x07bbf0e3, 0xb73761f4, 0xb8520df7, 0xffbb553e,
- 0x60c2e4ee, 0x5c775939, 0x29dc9f55, 0x1bf2ab35, 0x7bf9d533, 0xdb439b4b,
- 0xad8fa40f, 0xd189787c, 0x6ef70395, 0x37bfb0a5, 0xfff3e62c, 0xd5800901,
- 0x00800020, 0x00000000, 0x00088b1f, 0x00000000, 0x19b5ff00, 0x6554540b,
- 0xcef7bbfa, 0x7860190b, 0x77421028, 0x840a4498, 0xb0285789, 0xd71ea08d,
- 0x8f4c1ada, 0xe5935654, 0xe04d7903, 0xe3d8f4b6, 0xb68fad18, 0x695b6d07,
- 0x9656356b, 0xb139e4e7, 0x36254644, 0xeb495bae, 0x66a254d6, 0x42d899e4,
- 0x7a26704c, 0xf75a9d6d, 0x5efffefb, 0x5b602e67, 0xe74ed69d, 0xffffef9f,
- 0x27ef7ffb, 0x70ca1490, 0xf60800ce, 0x9970ccac, 0xd6f70601, 0x8018e41a,
- 0xe2eff4d3, 0xf9b8daf0, 0xcf03837a, 0x3a380057, 0x01cfe3cc, 0x031401d6,
- 0x7b81295c, 0x5914f3a2, 0xff60e760, 0x2fbdf165, 0x00490801, 0xde8d179e,
- 0xe38456ed, 0x6e67065c, 0xf08d9ef8, 0xd918064e, 0xbfefff72, 0x25f5c22a,
- 0x8c0ee3b0, 0xbd0d43c4, 0x5c75d79b, 0x9fcd7114, 0x77d1d704, 0x98809679,
- 0x55706b80, 0x00e207b4, 0x3c636a9a, 0x679e3e62, 0x2e990e86, 0xa6f1c804,
- 0x01529bb5, 0xc0228a8e, 0x78074439, 0xe3ef14a0, 0x245f041b, 0xa4ef39a7,
- 0x67c8b9df, 0xe7c72fcc, 0x35b03245, 0xe99432bf, 0x7ed77bc6, 0xbf1ce787,
- 0xce91a203, 0x8f4a803f, 0x2e5c4c03, 0x19bdbb04, 0x3f233ffe, 0x1812bd4d,
- 0xf0619f90, 0x605aba1d, 0x25a9ccd7, 0xa7e92b00, 0x061dfb4c, 0x196fd890,
- 0xb2957f70, 0xe57cb2bf, 0xf08b10a5, 0x2040fd56, 0xa70fbd9b, 0x7fd5fff1,
- 0xf198376f, 0xda53f57c, 0x530f427d, 0xfbe52f90, 0x77b3f03a, 0x3de277eb,
- 0x235ef853, 0x8499fddc, 0x697636ef, 0xc7245fbf, 0xe0e60d24, 0x3828028f,
- 0x916db12d, 0xf1366bde, 0xdf4ae6f7, 0xea097bbd, 0xc925e9b1, 0xd1adc46e,
- 0x00e2d3dd, 0xa83983f9, 0xf2f1d4e4, 0x7a8cda6b, 0xa7c30c2a, 0xbdf34b76,
- 0xca175f74, 0x5e319ea8, 0xe2c960ce, 0x5f1c2cf8, 0x0bd7c573, 0xf735f101,
- 0x7ed0d0e8, 0x1146cf00, 0xcf3c08e4, 0xf2ae31ed, 0x07f4c39a, 0xfcc79c2d,
- 0x66132f9e, 0x1d75f2e7, 0x1ced01d1, 0x98bf702f, 0x093e8021, 0x60b541f1,
- 0x5f4b8edf, 0xc925724f, 0x9f004fbf, 0x589ec05c, 0x5cfd4264, 0x7da39fc1,
- 0x8fe02433, 0xe11d6c94, 0xfdc8a859, 0x7c7fd28a, 0x8b77e023, 0x434f167b,
- 0xd750e00a, 0x0cd43eb2, 0x0c6d906c, 0xe8f012df, 0xf17d2f49, 0xa416f4ce,
- 0x604932f3, 0x1f17dff6, 0x7f10161a, 0xd0b4455f, 0xeff7b026, 0xbe55f7a4,
- 0x74cef4fa, 0x8e6be337, 0x26f51065, 0x4e902e38, 0x47978f47, 0x183aae58,
- 0x712bf554, 0x9c7f2177, 0xfb3edd2b, 0xd1dbf412, 0x223160a5, 0x684b97bd,
- 0xabc30838, 0x49ab8fdc, 0xae5133d6, 0xe8813f82, 0x6e17966c, 0xe4bbf191,
- 0x97417bd6, 0x1d372118, 0x2f5533f7, 0xd3c71caa, 0xf72de2a1, 0xd1bf903b,
- 0x9fb3021d, 0xecccbb46, 0xe4fcb1b3, 0x7f104b83, 0x0bb25fa3, 0xeeb2cf48,
- 0x7e4847bd, 0x403b6b1d, 0xe7401e77, 0x2eb66eda, 0x527d9933, 0xd98be31e,
- 0x414688ad, 0x6056ad7c, 0x7c35a7c6, 0x0c7be61e, 0x7c3f51bc, 0x3804ce06,
- 0x9e7ceb18, 0xfbf35bf8, 0x1096fbcf, 0xe3ca1bb5, 0xad901f99, 0x3fa61b9d,
- 0x466000df, 0xa3db43fa, 0x3c304fbd, 0x6125af68, 0x27b13d7b, 0x9e0b70eb,
- 0xcf53789f, 0xc55f75cc, 0x416ea7c3, 0x68f6cd78, 0x0913e726, 0xf3a549e0,
- 0x3d7ba627, 0x18a56178, 0xb9216fea, 0xb7d8c677, 0x47f1f9e3, 0x13bb3fa7,
- 0xa767dae1, 0xf24c89d9, 0x7de5191f, 0xda011d3c, 0x7d953e7f, 0xef1c2907,
- 0xa52fc50a, 0x57dc6667, 0x24cfe74e, 0xaa8f09da, 0xa347a1bf, 0xfaf2801c,
- 0x16797c12, 0x8293bd34, 0x87c45067, 0xc79dc4eb, 0xdbcbb404, 0xc483ae0c,
- 0xfe47eaf7, 0xf90ca87a, 0x37e67aa9, 0xfa44cf0f, 0x0c9bdf6a, 0xaf584ef4,
- 0x6c40e2e3, 0xdffc9720, 0x915ffdc6, 0x288edd4f, 0x7111c7cb, 0x5e23a1a6,
- 0xa7753703, 0x888e3e5a, 0x65c07537, 0x8e82f50c, 0xfc57a9f8, 0x1d745eaa,
- 0x201aba25, 0x8422e3c0, 0x0557640c, 0x78a0e092, 0xc8c7ba10, 0xced63fe4,
- 0xd1916546, 0x8b822f51, 0x224179e2, 0x6fc85298, 0xc17e5c5d, 0x713fa67b,
- 0x9266ca17, 0xfbf54135, 0x223385ac, 0xf1bfb3ed, 0xcdcfb215, 0xc39f6646,
- 0x8d2f3c51, 0x391ff3c5, 0xc2bf7d9e, 0x87f305f4, 0xf5a4f933, 0x17385adf,
- 0x0aef141c, 0x9bc2e4da, 0xf4516d70, 0x29c52c72, 0x1dee4958, 0xc03aeff7,
- 0xe6f5b9e4, 0xbf7784a3, 0x0e0fe999, 0x0507b970, 0xf7d5279e, 0xa0429856,
- 0xb77a242b, 0xfdd57a31, 0xf3872dc1, 0xe0fef85c, 0x8079390b, 0xf24cbcf6,
- 0xe505fe0f, 0x7fc62a73, 0x3b5c36ec, 0x853bbff7, 0x7a58e0f2, 0xd9475beb,
- 0x2c3c2a7b, 0x4f5438f0, 0xf7fee07c, 0xa264ce99, 0x8b08c313, 0xcd77030f,
- 0x2b9bf260, 0xfe91c6e5, 0xf4b42783, 0x7d53a58d, 0x7d4fa55f, 0xcd37bd5f,
- 0x8e39322a, 0x9479fc18, 0x90cc5ff7, 0xc48d7c35, 0xcde2f3fa, 0x75e16fb4,
- 0x11c20244, 0x3f4356f6, 0x2635bf51, 0x5f48db8c, 0x6f608d4d, 0xa1efb603,
- 0xcfab89b8, 0x29f5e785, 0x03722b2f, 0x78ed09a7, 0x906762b1, 0x6eecc894,
- 0x5ebb7011, 0xabedc4ac, 0xe80f43a0, 0x75c4472f, 0xfda035bf, 0xa03c770d,
- 0x5dc64577, 0x74f151cf, 0xbb8f4fce, 0xa6c84a9e, 0x31623df8, 0x9e66bab3,
- 0x7bb1d055, 0xf74e90e9, 0x43eedcf0, 0x1a74f03b, 0xcf486ded, 0x8173a2e3,
- 0x6f53e515, 0x1f91e5f0, 0x2e3ddfa8, 0xb0fed8ba, 0xe9056070, 0x3cbe741b,
- 0x1bc4ef56, 0x233ac040, 0x77eed938, 0x25f65d50, 0xd412b8b0, 0xe2274d43,
- 0xdd12aa2d, 0x3c70e69d, 0x5167e354, 0x5ca3ee0e, 0xf55f682b, 0xa29bb457,
- 0x30fded7c, 0xb8f85a3f, 0x515dfb95, 0x98eee8a2, 0x576e5fc0, 0x1d06dcf4,
- 0x9e67f712, 0xb914cb47, 0x4522dd63, 0x4a8d2dd6, 0x9ac60f9c, 0x53f2123c,
- 0x82f51bb6, 0xb7ce9970, 0x028c5697, 0x9dfa8ad0, 0x5efe3e05, 0x539e36b7,
- 0xf2ca590e, 0xcbcb0e72, 0xaf7514b3, 0x7a40dc17, 0xc2fe5135, 0x2fc12ef5,
- 0x082bfad1, 0x1601d5b1, 0x06a8ad1d, 0x2701ceb6, 0x9b81e75b, 0x9da1f3ad,
- 0x83a00bad, 0x9f8297ad, 0xaf8170ad, 0xb83e580d, 0xf98832dd, 0x52bd7e18,
- 0xb45cbca4, 0xfc7ae264, 0x675e4571, 0xf9460797, 0x8f2f9f92, 0x614ae079,
- 0x2e4d9d74, 0xdd99b353, 0x923172ab, 0x5177e27d, 0xb5a14de0, 0x9dec0202,
- 0xf190c98b, 0xeb20d99d, 0x0702ae08, 0x48fee783, 0x5c069479, 0x04ee573a,
- 0xd89aa972, 0x7628764e, 0x5d364c52, 0x87d7d61c, 0x54171e56, 0x49d201bd,
- 0x3ebc60f9, 0x2ce88321, 0x5cfcae8a, 0xdaf190c6, 0x3a9df7b6, 0x8545a38c,
- 0x84362d95, 0xe53f590f, 0xf3e55970, 0xd91f0899, 0x9ba9d276, 0x595e7649,
- 0x1563b7a8, 0x39d86eba, 0x184dcf07, 0x4e50a3fc, 0x52824d92, 0xb1515d5c,
- 0x677e8079, 0x74ebac94, 0xdbc657e8, 0x5719c580, 0xd59f8014, 0xe46568b3,
- 0x7ebc3527, 0x7ae1635d, 0xbd706bdb, 0x60da7e4a, 0xc8cac5f2, 0x73759ad3,
- 0x6e5f2993, 0x3ff7f030, 0xbce72c9a, 0x22327282, 0x9841533e, 0x44f73c4f,
- 0xe4101c21, 0x186b5696, 0xf7c08fff, 0x77c21fcf, 0x5deb8a6b, 0x594dcf16,
- 0x534ffa40, 0x676779f2, 0x245d8a59, 0x3f8616fc, 0xd2d59310, 0x5207478a,
- 0x7bd21f9c, 0x776e18c1, 0x5eb95a1f, 0x329ab6ce, 0x27581f1d, 0xfbae0fd8,
- 0xe28f977a, 0x084827d0, 0xd599f3be, 0x34744035, 0x428c8189, 0xd11dd7d4,
- 0x27640cc7, 0xa80b1daa, 0x7fc8a5bc, 0x06bc039b, 0x96e51fe6, 0x2d98f533,
- 0xe5c107ec, 0xa5ca1ef8, 0xd2ace9c8, 0x8d4971e3, 0xa5ad1f7b, 0x3c2af6ae,
- 0xa2413c21, 0xad0a49a7, 0x1538bb20, 0x13e19eff, 0xb953a7e6, 0xabf12a3d,
- 0x6def4f67, 0x42741c69, 0xed361f84, 0x0fabe6f9, 0xa34ddf50, 0x0f5d3b66,
- 0x1696dffb, 0x1ab00bea, 0xd517c4d4, 0x1b75672f, 0x955fd47d, 0x397f3eed,
- 0xaf78abdd, 0xfa7146df, 0x1b40fee2, 0x9ec1cb95, 0x2fdc69c3, 0x6bfe3ad4,
- 0x93e4e7e1, 0x750512b9, 0x905ecbac, 0xabe446bc, 0x050bea99, 0xdc7c20f6,
- 0x47137684, 0xa9bf79f7, 0xbd0d95f6, 0x2fa819af, 0xc43c67c1, 0xff42ad6f,
- 0x5c37adaa, 0xad62f54a, 0xd62fdb57, 0x13d77bf5, 0xb43b75dd, 0xd9bf6afb,
- 0x4f5f7ca4, 0xea8d9af5, 0x26bded3e, 0xa8f337ea, 0x67eed3fe, 0xa6fd2a66,
- 0xa940ff92, 0x772a5733, 0xeb333f88, 0x235e0cff, 0x68fcd6f2, 0x7042dd8b,
- 0xe2ced9ba, 0x6606fd6d, 0xd87deac7, 0x446cc89a, 0x8ddadbf5, 0x5567eac0,
- 0x1b4ff98e, 0xfc8fa41d, 0x5d5993a7, 0xab3cf58c, 0xf09e3047, 0x22651efe,
- 0x173ddda0, 0x1114ca1f, 0xd93d73cf, 0x5fb7aa76, 0x7f80eb5e, 0x4fa6179d,
- 0x4ae7f7ad, 0xd40cab3b, 0x7d88dd47, 0xf7356e14, 0x4266d93e, 0xd01379b8,
- 0x3b2d240d, 0xe2a6ea8e, 0xe97812fd, 0x503ef01d, 0x1a976b8e, 0xbeb0524f,
- 0x9447908f, 0x09e4093c, 0xa2a379fa, 0x04ece8b7, 0xfd8c79cd, 0x71f7cd1c,
- 0xefda99a5, 0x6e7f0e3d, 0xfe73c509, 0x02e3bc7d, 0xc136fdcd, 0xcd91f76d,
- 0xbc3ff004, 0xb188ae57, 0xcd82bfc2, 0x17e7121d, 0x886fee68, 0xec9fb79d,
- 0xdd0bfcbb, 0x4b703b18, 0x01657764, 0x2f504780, 0xe7b586b3, 0x21db07c5,
- 0x1d47f116, 0x57998dd4, 0x16ea8078, 0x5fddaca3, 0x54c5daae, 0x4399aa98,
- 0xb73b919c, 0x9121d1fb, 0x9c0945d9, 0x117970f7, 0x5e0f59c9, 0x46dcbc79,
- 0x66fba569, 0x598bf303, 0x8a762dbd, 0x5a9d9347, 0x68d727f9, 0xd2ea9fe5,
- 0x956d3bca, 0x6ee9de56, 0x6dcfbcad, 0xead7cad5, 0xb6cfcad1, 0xfee69671,
- 0x0d4af6b4, 0x02f37d3c, 0xbdf3fdcd, 0xce70350b, 0xf734ab8e, 0xd32c7467,
- 0xaf77e79c, 0x76ab9cd6, 0x2e0ed636, 0xb18f35f4, 0x08c41133, 0x567aabfd,
- 0xff70a0ed, 0xff3c1aad, 0x1f6ffd6f, 0xc8a7ffa3, 0xbdde31d7, 0x37743b15,
- 0xd165ebb9, 0x999dae3c, 0x59eb9427, 0x9cb6f6bf, 0x77431558, 0x54e6fc95,
- 0xff941bf2, 0x0e16c391, 0x7df6fddb, 0x8e0acf14, 0xae88ab38, 0x1f7b80a2,
- 0xa192f385, 0xba38aaf6, 0x32d900ef, 0xe89c8f85, 0x02a5e5fe, 0x857e34e8,
- 0x3cb094f0, 0x93acf0af, 0xd972f0e2, 0x1636de77, 0x4be9c96e, 0xa120f3c2,
- 0x6a85e794, 0x22e81447, 0xeca152e4, 0x29e92503, 0xf3abf961, 0xc007ec23,
- 0x6880fd40, 0x2759b6f2, 0x9bec77aa, 0xb98f5625, 0x86f67d58, 0xa57362e0,
- 0x067f2645, 0x25dff7c5, 0xc4cedebb, 0xb44a76b8, 0x139eaccb, 0x54c46d02,
- 0xa4a31890, 0x76afa9e5, 0xed871f50, 0xff2bcd2c, 0xb56d4774, 0x6f919727,
- 0xb6f09409, 0x67f5fe99, 0xa2648eba, 0xcb0407fc, 0xf6fc42fa, 0x332759ad,
- 0x25197f28, 0xcd014494, 0xe9471c4f, 0x24dcccfc, 0x78c3f919, 0x0f65101b,
- 0xab73c289, 0x9390fac0, 0x08ccd8f4, 0x67a8ddff, 0xbe940b79, 0x5e451aec,
- 0x54b65f6a, 0x4f803fc1, 0x7e78c2ac, 0x4c1bf74d, 0xc329752e, 0x6dca1cca,
- 0x37fbe0b7, 0x5017354c, 0x428e0a5f, 0xd5e7ef3b, 0xfa4d2d3e, 0xed557929,
- 0xbf76cf6b, 0xd348652e, 0xc4cec32f, 0x6391e709, 0xbe615ee7, 0x9b03fbf9,
- 0x1a1e59a2, 0xe6ce94d8, 0x4ff7e18b, 0x71aff7b1, 0x93b1a3bf, 0xd7df5aeb,
- 0x9ef5dfd8, 0x81e7348f, 0x0d3e90a4, 0x4aec0ff9, 0xca35779d, 0x6305e46f,
- 0xa8abf509, 0x715b38b7, 0x3dc0fdf8, 0xbe10e7d3, 0xa7e7cdff, 0x6bfdbe4c,
- 0xa6ee6cfd, 0xed6c79f2, 0xd6070611, 0x963ad806, 0x55bfb54f, 0x20dfc357,
- 0x90e5ea9b, 0xd13ec930, 0x1b31e6bc, 0x67fa83ef, 0x7ca4a94f, 0xd06e9fdc,
- 0xc38b35f1, 0x0e26a5a9, 0x6b4f9bcf, 0x48de6f50, 0x00bf6dfd, 0x61ed010e,
- 0xec7ce0a9, 0x3abbe47a, 0xa36b95d9, 0x2875727a, 0xd0fe874f, 0x56b81f94,
- 0x1ebe7d40, 0xfe27caef, 0x53062c05, 0x599d1813, 0x890c37d4, 0x63013c9e,
- 0x764f4dc1, 0x3ffd5357, 0x8a73c934, 0xadad7632, 0x83fa9aab, 0x8ff70321,
- 0x847c9e5b, 0x16b7c3f9, 0xe77a4cd7, 0x31f24113, 0xf0497e7b, 0x16f6676e,
- 0xf88c2c30, 0xaf3a82bb, 0xfa9b7ea1, 0x5f14609b, 0xdff8db67, 0xacc72a5f,
- 0xae3c6d4b, 0x316b42dd, 0x2ceee5e9, 0xe8ca7bfa, 0x5f902366, 0x48873e20,
- 0x5cf87af8, 0x40f20a76, 0x6f560d75, 0x78285fac, 0xf8a3e8d5, 0x1675cea1,
- 0xbdecacdb, 0xd79f1b24, 0xf467dd24, 0xeefcb1b6, 0x3a46a8cf, 0xef58f5db,
- 0x1070df50, 0x846d1cd8, 0x7a1161e6, 0xfde36c59, 0xc008dc17, 0xd1b793cf,
- 0xc0ef4379, 0xdf278a31, 0x24aeba67, 0x72880c39, 0x8693c509, 0xdeacbdd8,
- 0xecc9b66b, 0xf197a43b, 0x4ee1718f, 0x382fcfd2, 0xfa455c0f, 0x7805306d,
- 0x03ccaadd, 0x91b726cf, 0x7287fee5, 0x9ecbfcd9, 0xf4a9f441, 0xb6cdfd22,
- 0x4a9db988, 0x1f9df87f, 0xae750bf6, 0x5b83c2a5, 0x9f916436, 0xbcf85ea1,
- 0x5bae1251, 0x0ff7c138, 0x963efa2a, 0xfe10f4e2, 0xf73e6ed5, 0xfb4ddb0b,
- 0xcf4947cd, 0x271666bd, 0x58fdf6cf, 0xf4f61b3e, 0x9f207932, 0x117f12d7,
- 0xc91bde7c, 0xe1cf48e7, 0x9fe57287, 0x9d305fcf, 0xb8291dff, 0x190c9bed,
- 0xfdd86fbf, 0xbbb211c6, 0xdf1e7506, 0x18339da5, 0x9aff6127, 0x1d1cd130,
- 0x5d444fb3, 0x9fbf5466, 0x8f7ed3aa, 0xa9cd3905, 0xa9dfc9bb, 0xbff0717e,
- 0xb8f9a98b, 0x846be94b, 0x1f2cebc0, 0x87f23e10, 0xe58782f5, 0xd18e7545,
- 0x23de6026, 0x585abadd, 0x35ce909e, 0xbb9ec9db, 0xe4fd06d0, 0x34473a07,
- 0xe98f5f9b, 0xb835bfa3, 0xd6fc9176, 0x4c9953bc, 0x9be7767d, 0x8d7e940b,
- 0xc562a9e7, 0x3f098b2e, 0xc71b9fd1, 0xa148b5ec, 0xf584c4af, 0x7c852650,
- 0x15e7c48f, 0xd363fcca, 0xef3e9aeb, 0x685932bf, 0x001e0053, 0x00000000
-};
-
-static const u32 usem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x1915c58a, 0x19d44418,
- 0x18344c18, 0x20685618, 0xb58969c4, 0x9fd329b8, 0x90c0c2c9, 0x40b9c40d,
- 0x7cc40f9c, 0xfc0c0c4c, 0x17ebc44c, 0xf5b04514, 0x84181904, 0x026ffc80,
- 0x85d70c0c, 0x8bbe1818, 0x03083030, 0xf1402ef9, 0x01ce2004, 0x58a06f62,
- 0x045e900b, 0x2c40ddc4, 0x7cdf8a22, 0x6bf20251, 0x37f95185, 0x847bf8d1,
- 0x1057ebf0, 0x47af2fc1, 0x161b1e40, 0x3e3f22d1, 0x3bd02922, 0x015f5810,
- 0xc7265f95, 0x0f27d0c0, 0xb8a87f8c, 0x4bfc9201, 0x0e5cbb20, 0x6096f6c2,
- 0xf2062860, 0x9bb0150d, 0x2f9403eb, 0x857dca01, 0xcc0003ca, 0x688cbacc,
- 0x00688cba
-};
-
-static const u32 usem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0x4514780b, 0x74f570b6, 0x9924ccf7,
- 0xf2124c99, 0x00493de0, 0x210e0311, 0x9970c044, 0x46a2c024, 0x141a020d,
- 0x84920275, 0x7e889790, 0x33feaeec, 0xa8a08901, 0x17acb9f1, 0x376141dd,
- 0x0c06e8b2, 0x60e03518, 0xba2eb300, 0xe7c045c1, 0x36bc8026, 0xb9f04324,
- 0x9d6f5ecb, 0xdd33d553, 0xc7c4099d, 0xffef7fde, 0xa55f9f8f, 0x71ebaaba,
- 0xe9d4e7de, 0x278f3242, 0xdf210a64, 0x9f968fc1, 0xf890848b, 0x206f5950,
- 0x8841922e, 0x6df466d7, 0x88cfa64c, 0x68e67a23, 0xd11d985a, 0xef435837,
- 0x9ed5cbe9, 0x186934a4, 0x1c790f21, 0x23e21258, 0x5ab54e84, 0x16f50520,
- 0xe0933ba8, 0x213e3a7d, 0x0ff8e8fd, 0x30f8e246, 0x1a18992d, 0xe0311067,
- 0xf9ad537b, 0x421eb089, 0xc3e6476a, 0x213b16fc, 0x9f9f7bfd, 0xa7eb888e,
- 0xf7c10def, 0xb59efa24, 0x6529efef, 0x13fd0e57, 0xf66ddff6, 0xf108146d,
- 0x71c7fcef, 0x8699ef58, 0x5d130e39, 0xd9b7766f, 0xbeea053f, 0xb6899f6c,
- 0xc0fb6ee7, 0xe5fed126, 0xda0944db, 0xf0233b0d, 0x8275cefd, 0xa695ea0f,
- 0xa4ae47d6, 0x9136c0f5, 0xf8d30f3c, 0x4092062d, 0x613371c8, 0xeb15873f,
- 0x5aac1145, 0x6dd77ebe, 0xa3495f30, 0xf7d04489, 0x2e88378f, 0x28d92fa8,
- 0xaf9d08f8, 0x8c07b5fc, 0xc578e803, 0xc23ea13e, 0x1f1beb41, 0x3ee83a33,
- 0xd8fcef97, 0x7ce146d6, 0x0e2663da, 0xa4a3ee23, 0x52908d3e, 0x03e996df,
- 0x9ba5fbe8, 0xbe802705, 0x4ed9dd74, 0x83695f58, 0xe3a45c3c, 0x228bae2d,
- 0xee6c918e, 0xd7cc08ef, 0xdbe7147c, 0xf9830f26, 0x65dfce4a, 0x6ee52404,
- 0xca2e9193, 0xdf603ae9, 0x3da7bcca, 0x053e716b, 0xd22fe59e, 0x8abf68f9,
- 0x6c270597, 0xdc40c2b1, 0xd7ce8eb0, 0xb05e0a22, 0x8daafec0, 0x7deaac23,
- 0x7d876e14, 0x1bd6fa94, 0x7d605ba7, 0x69458deb, 0xd716f1a1, 0x7d76a7fd,
- 0xdd13536b, 0xf3e3bd69, 0x748287b4, 0x4a5ea844, 0x4fe90b88, 0x8e8119f2,
- 0x85e7e795, 0xe2f7c418, 0xcc38913a, 0x3a15f1a1, 0xe9c07ef0, 0xf1958774,
- 0x12dbc701, 0x842ce03b, 0xc73b6eb7, 0x54c814a3, 0x8f94af8f, 0x7ae83e00,
- 0x2c763d6a, 0x6124f71f, 0x81c7a4f9, 0x33da7b70, 0x1eb5cb12, 0xc67f3e27,
- 0x75cb0133, 0xcf96171e, 0xe9606679, 0xbf63e4f3, 0x58053de7, 0xf1b8f06e,
- 0x253d6ff9, 0xaa79d658, 0xcf26f9f0, 0x7b372c32, 0x65fcf8bc, 0xeb2c2acf,
- 0x6e58b53d, 0xb2d17c05, 0x7ec3e3c1, 0x58753ddb, 0xf1ea7a36, 0x469eebf9,
- 0x3870d72c, 0xb648b2da, 0x7360e144, 0x3b453b11, 0x6573cd89, 0x9b1eb4cb,
- 0xf309eacf, 0x5a46d9bc, 0x3ad3704f, 0x3280cb85, 0xd689b67f, 0xf6b15407,
- 0x1c92f721, 0xf10fad33, 0x3594f6b2, 0x5a089cae, 0xed65a94f, 0x7379d623,
- 0x847d6922, 0xda8fb58f, 0xa289cfec, 0xacf551f5, 0xc9134c7d, 0x18fad0b5,
- 0xefa7ab3f, 0x695ae573, 0xd595bd3d, 0xe6f13f33, 0xb33d68da, 0xa93fbd8d,
- 0x2c3a27c3, 0x55b0f13d, 0x14202c76, 0xb9de4d57, 0x9bca892e, 0x5dc746ad,
- 0x7bc849c4, 0x892ef9de, 0xd90687ca, 0xde6ded85, 0x746eacc5, 0x77b77b61,
- 0x2edff629, 0xaa5db1bb, 0xb7db0fbe, 0x9ed8dd1b, 0xed835d50, 0xdb17b28d,
- 0x8a3f5647, 0x2f468ded, 0x5eaa4fb6, 0x65d7f58b, 0x55e7b61f, 0xaffec7af,
- 0xfed87d1b, 0x5c9bfdf8, 0x05fd6953, 0xe41dbdc1, 0x5dc10ade, 0x9e815242,
- 0xee4093ea, 0xf9f970d5, 0x6d1d101c, 0x446fe9af, 0x6efadc3e, 0xbfc00be6,
- 0xf507ebf8, 0x983edfa2, 0x89bce38c, 0x1c74c8e3, 0xa4e3e2f1, 0x334137bf,
- 0x257bfa4e, 0x382d38ca, 0xc6df444e, 0x24defad9, 0x2bde7aed, 0x0fd9c655,
- 0xdac2b4fc, 0xffa57db7, 0x9ebb4b39, 0xe329973f, 0x89eb847c, 0x1a7adbe9,
- 0xa7c2d03e, 0x7c2083e1, 0xf138e28e, 0xc64f5b7d, 0x327c2d41, 0xd3e1060e,
- 0xeff4e381, 0x070d38db, 0x3869f0b5, 0x97cf8418, 0x7dc19f08, 0x21c657db,
- 0x0e327c2d, 0x5ff3e105, 0xbee49eb8, 0x53fdb38d, 0x7fb67c2d, 0x498f841a,
- 0xef0cf580, 0x3f32bedb, 0xf327c2d3, 0xec7c20b3, 0x7da5ce38, 0x67fb671b,
- 0xff6cf85a, 0xfe9f082c, 0xbee8ce38, 0xaff32bed, 0xfe64f85a, 0x149f0835,
- 0xb633e001, 0xfc69eb6f, 0xc69f0b5c, 0xb9f083cf, 0xdf19c70c, 0x384cf5b7,
- 0x84cf85ae, 0x64f841e3, 0xf626bee0, 0xe3c69c6d, 0x1e34f85a, 0x3267c20f,
- 0x6fb9338e, 0x42709afb, 0x27099f0b, 0x8e99f082, 0xebbb64e3, 0xc7465198,
- 0xce3ef6b1, 0xf0b467eb, 0x104cfd79, 0x38e3d73e, 0xa938e8d3, 0x52671f17,
- 0x933e16a7, 0x29f0833a, 0xeaae71c0, 0x77af38db, 0x7af3e16a, 0x853e1067,
- 0x7db5ce38, 0x2ea4d7db, 0x75267c2d, 0x3b8cf831, 0xa36b9550, 0x3a1754ed,
- 0x95cafa45, 0x40972e1d, 0xd59da2eb, 0x8093bb45, 0xf62a225d, 0x89756906,
- 0xe6cb7df4, 0x8907f498, 0xb9c8eeda, 0x4ac7e813, 0xddb531ad, 0x52213d11,
- 0xb8c4e763, 0xb8f53562, 0xfd340319, 0x3453f3e3, 0xa30589ed, 0xddfded34,
- 0xc0fa9ae9, 0xfe9a4992, 0x3472ab83, 0xaecba1f5, 0xf64ff4d6, 0xa7a9a0de,
- 0xd359baae, 0x7ced787f, 0x6b25fb4d, 0x97ed354b, 0xea6896fa, 0x42fdd597,
- 0xfd747fd3, 0xe5fb4d72, 0xda6a0f8d, 0xd71ffac7, 0x3cb5c7d4, 0xbe3fe9a3,
- 0xfb4d79f5, 0x69378715, 0x6db627da, 0x3cafd4d5, 0xcecebaf9, 0x5f8fd8b3,
- 0xd022ebc6, 0x7f76613d, 0xf8f7e67f, 0x1bac46ad, 0x8ed05807, 0x722d65df,
- 0x35f8a31c, 0xd1c0b5be, 0x7017e28f, 0xf6457e0a, 0xda4b9280, 0x267bf3e8,
- 0xd3b12fb9, 0xdd18f7e7, 0xd8c3db97, 0x041e94a7, 0xc3a50492, 0xfdbea500,
- 0x63d19901, 0x23f3c0ce, 0x95fbe9da, 0x1888c086, 0xb312cf5a, 0x777e811b,
- 0x8a2fcc0a, 0xf4154914, 0xf411348b, 0xce481e0b, 0xa2abc17c, 0x298355d7,
- 0x71a10a1f, 0x24eec957, 0xaade33b0, 0x1d82f76e, 0xee983352, 0xcd21006b,
- 0x4bdfbb42, 0x0607b4fd, 0xe9b92517, 0xb5232678, 0x1bf3d5d3, 0x3869fce9,
- 0xebd00b7f, 0x7c7f307b, 0x294df9cf, 0x9bf33413, 0xe6689487, 0xfce91b37,
- 0xafde4276, 0xa7e7c53e, 0xc8449848, 0x3853845f, 0x094869bf, 0x9180ffce,
- 0xf9ea2bfa, 0x1ff38323, 0xd67ffd86, 0x2653fedb, 0xa43ff769, 0x237fbb54,
- 0xea91ffdb, 0x48fe7cb3, 0xe151ffdc, 0x90ffdb2c, 0x137fb652, 0xbf38371b,
- 0x93ff082d, 0x2f677f30, 0xb3529bf3, 0x5a1ffbb4, 0x89bfdda6, 0xfd5ddfcd,
- 0x82df9f2d, 0xbe139ff3, 0x5a1ffb65, 0x4d1bf386, 0x8fd0276e, 0x95646071,
- 0x1d4fce8f, 0x04490761, 0x40f3a172, 0xfd163239, 0x148497e4, 0x913dc75c,
- 0x8abede8c, 0xf286f4a4, 0x58fccbc6, 0x996c951f, 0xb4e2efd4, 0xb67378be,
- 0xb612e411, 0x21657f53, 0x8d1dea5f, 0x7937d222, 0x4e1be4d2, 0x28d9dbd7,
- 0xc77ea17a, 0x207d9393, 0xe44d2aff, 0x4f787cf6, 0xfe787e22, 0x9fa353f9,
- 0x5f4bef57, 0x8f95ac2e, 0x2df8a9b7, 0x90e547e8, 0x98165591, 0x1fa9aed7,
- 0xa1107ea1, 0xd427c5fe, 0x249420cf, 0xbe6cca8f, 0x04bfa8cf, 0x2fea36f5,
- 0xd5213b41, 0x75e25fb8, 0xae8c307d, 0x3f289f3f, 0x26f3ee17, 0x9e3a2964,
- 0xc8f7f8c4, 0xf807c11a, 0x14597db8, 0x3d687e05, 0x4d38de85, 0xfb0fee9d,
- 0x7c12ae07, 0x86380bcf, 0x9333e01b, 0xbd60478f, 0x67605eb4, 0xe8a21cef,
- 0xb0514fef, 0x8a40d560, 0xb338d08b, 0xa44e4b88, 0x5a59cfef, 0xa2e84328,
- 0x2f061055, 0x2059fa01, 0xe0119753, 0x69278de7, 0x7ae8389c, 0xf1b3b66f,
- 0x63e4ba67, 0x14f5aa6d, 0x3e5766c8, 0xa1414f5d, 0x359feb88, 0xd1fedb43,
- 0x619728ce, 0x3d572d0c, 0xc9ccf381, 0x54dfb6d7, 0x75cfada0, 0xef54eb6b,
- 0x6ef7a0c9, 0xa73fd129, 0x9cfba160, 0x5d2b8417, 0xade75d28, 0x56b70e1c,
- 0x5e0d5ec9, 0xda556dc1, 0x26e0a021, 0x5f7c2fb8, 0xf6ffd9ec, 0xa17ada65,
- 0xb05f5b57, 0xa73e374a, 0xff1ce39b, 0x683e8047, 0x83e80279, 0xa718f3c2,
- 0xd55c908f, 0xc18dc7d2, 0x50fa306d, 0x625c71f6, 0x8ebe3828, 0xdac2c7d1,
- 0x50f4f0a8, 0x9707a418, 0x7a14be9a, 0xc3d38db8, 0x8a1e9ca7, 0x6ae96ad7,
- 0x4cadf12e, 0xb2dfefa2, 0xe9e21766, 0xe8c850a0, 0x3d0a97e1, 0xc1e869b4,
- 0x8f41e9cd, 0x3d38dbbf, 0x4673f6dc, 0xb67c7a0f, 0x5b687a71, 0x29264e7b,
- 0xf14af13d, 0x3c53a9a0, 0x376ef0e8, 0x7c503d02, 0xf987a584, 0x8dd37dc1,
- 0xde02fad3, 0x9c5f03d6, 0x053db01e, 0x4e104ec0, 0xcf6a7ef8, 0x684e54fe,
- 0xc36bc5ea, 0x31b2bfe3, 0x6a98ee3b, 0x57f5e55d, 0xf5531dc5, 0x53375c5b,
- 0x9be45f53, 0xbc5fe9ab, 0xbed350b6, 0xa69176b0, 0x3baac17d, 0xef42f535,
- 0x6ffd35cf, 0x69ad565f, 0xb56ab5bf, 0x9296fda6, 0xb9f534c7, 0xfa6b5fee,
- 0x5eb054df, 0xff273ed3, 0xacfb4d45, 0xf5345b19, 0x34d7ae99, 0x2f3b0dfd,
- 0x31e81ebd, 0xc048a0eb, 0x71e638fe, 0xf71fdd20, 0xa4f2c48c, 0x717c89c7,
- 0xcb0133da, 0x4fcd8d7d, 0x7cbb495c, 0x26882819, 0x91167f4c, 0x2cf64218,
- 0xcaaf5777, 0x504e7d02, 0x7971feef, 0x1077b551, 0x07065395, 0xad6f39c2,
- 0x11c7f891, 0xe2528022, 0x50c407f3, 0x6d1b567b, 0x3dbdeb8f, 0xb614ad6f,
- 0x0a4dab3d, 0xe3e56e3b, 0x61ed4385, 0x7e2133e2, 0x3ec10326, 0xb9f6e2ea,
- 0x204cbdbe, 0x84e7eaf9, 0x8ffe472c, 0x5cfd3031, 0xa2726466, 0x1cff6b6c,
- 0x7fba8362, 0xe685d544, 0x95cca7ab, 0xaa91f408, 0xb5e2e3e1, 0x3ce46997,
- 0x3c6de881, 0xcd38d9d0, 0x5775c5f3, 0xd8ebde6a, 0x2bbae225, 0x7d508640,
- 0x07e48c3d, 0xfd97a00c, 0x8d6643cd, 0xceba7586, 0x355e401a, 0xd8fda3c6,
- 0x771199e1, 0xe63c024c, 0x53d27963, 0x8f71e580, 0x9e63cb1b, 0x788f2c12,
- 0xf36cb0aa, 0x33f2c32c, 0x4fcb178f, 0xfcb0ab3c, 0xe58b53c8, 0x2c5acf61,
- 0x587c7a0f, 0x61d4f01e, 0x1ea7bef9, 0x234f56cb, 0x171e9d96, 0x29bf0a96,
- 0xddd3d0f0, 0x4fa7ae49, 0x805dfd03, 0x07c4e2ce, 0x0a0d57aa, 0x8ae259d1,
- 0x59bdab87, 0xd6f371a1, 0x249d389a, 0x0861e868, 0x81e364f8, 0x5e9c4c5e,
- 0xade7b7c2, 0x9ed82f95, 0x1d8726d5, 0x7ff9f2bf, 0xf9cdbd0d, 0xa216f491,
- 0x7a3a81a7, 0x3d18bd4a, 0x87c7124d, 0xc18e69e8, 0xa71ff4ce, 0x1f6087a7,
- 0x628ffc61, 0xabc6ea30, 0x14573aec, 0x73f3678b, 0xb2d16a07, 0x7b9f3678,
- 0x15ae1d05, 0x48df3fed, 0xc8f773c0, 0x78808fbf, 0xaa61f77d, 0xdf7b9328,
- 0x7a5e9e9f, 0xfd0bbb87, 0x551f22a0, 0xb67ae3a2, 0xb8324447, 0x0cc81846,
- 0xeac84e92, 0xce75bfe1, 0x44bac34f, 0x9f7de162, 0xf3986673, 0x4f670228,
- 0xeb871789, 0x6357eb0a, 0xcfe3bc60, 0xca1323fc, 0xe6148639, 0x688b34df,
- 0x0bff13df, 0x506f804e, 0x499c991f, 0x0c0f0710, 0x3ed1da37, 0xf0b459f0,
- 0x667ad2f3, 0x29ab7e08, 0xdf515a8c, 0xfc2126d7, 0xa2357d86, 0x77e01f7f,
- 0x317f3931, 0x0df7ce78, 0xf3c097f8, 0x62f1f262, 0x1cb89172, 0xfdd2372f,
- 0x9d1ced77, 0xe403a0fe, 0xade185e0, 0xd7e95f9c, 0x7d28bcf3, 0x4aee3a2f,
- 0x75b8e850, 0x88f3a108, 0xefc71da2, 0xc984b86e, 0xdbeec52f, 0x05f5f266,
- 0xb59267af, 0xf9c53de3, 0xbbaf194f, 0xf81b05e5, 0x0c924b5b, 0xf06163f6,
- 0xf5e594a0, 0xda8b76c9, 0xd6d46cfe, 0x19856bbb, 0x3a2768f5, 0x068f67a2,
- 0x1fb7613d, 0x3b72061b, 0x9c654b09, 0xfb464925, 0x4ef72a31, 0x3346a5d7,
- 0xe4c7cf3f, 0x9418e6c1, 0x663da717, 0xaf53ffec, 0x9471b7a7, 0x40d210f5,
- 0x1e419a8e, 0xded4b6d3, 0xcf4af7fb, 0x3c4617d2, 0xbf926df7, 0x4cd0fb02,
- 0xfc0effff, 0x5d61220d, 0x5eb2b719, 0x872e9af4, 0xf3359be7, 0xca1cf7d1,
- 0x2977eb19, 0x891be217, 0x96e8571c, 0x5c638bea, 0x8bae2c9f, 0xcfed6bb0,
- 0xb2bd4d18, 0x635dbfb1, 0x541fc28f, 0x412a92fe, 0xe329fa02, 0x5925d3e4,
- 0x7d740956, 0x1090426f, 0xfd6056e8, 0x466dcdca, 0x95ce03b7, 0x5b7ade19,
- 0x4cdfc51f, 0x897c9289, 0x61cf16b9, 0x9d2fea4b, 0x4ce67a0a, 0x88048ac3,
- 0xbb162c1b, 0xf30fc9ef, 0x79312cbe, 0x0727c8bf, 0xa73df6b4, 0x55c7420f,
- 0x945c639e, 0xeaab8e58, 0x8f16061d, 0x009b8fd1, 0x1c5fc6e3, 0xf79b153e,
- 0x413b074f, 0xc68aa70f, 0xca3746b3, 0x665ffa45, 0xfc0a4e08, 0x13f314de,
- 0x697e3a24, 0x2dc63b5d, 0x11deca4e, 0xbc80bcbf, 0x4b3fb9ec, 0xd528f1d2,
- 0x15a4bcbe, 0x813f99e6, 0x371c444f, 0xf8e54c7d, 0x04c93fa9, 0x4f3910e4,
- 0x4862657b, 0x063bfb86, 0xf90cc862, 0x161bf33b, 0x4fbc01e7, 0xe547bf81,
- 0xdf241de6, 0xb5207886, 0x9cdfe099, 0x00198621, 0x7de433a7, 0x1e1538db,
- 0x87232572, 0x94829533, 0xf1c14c1e, 0xefc1fddd, 0xb4d41532, 0xb9e0638a,
- 0xc23ff8a4, 0x72471877, 0x50b7980b, 0x897b9ec0, 0x97e81ab9, 0x3f1a51fa,
- 0x9a51fa8d, 0x34a3f53a, 0x437222f5, 0x1425e402, 0x9f13293d, 0xb4d27080,
- 0x88ec928f, 0x555262c7, 0xafd1f603, 0xbe6dfc79, 0xe903489d, 0x7d5fcb3e,
- 0xee90b336, 0xc5896ae7, 0xf57394fd, 0x0e0cb145, 0xa33e25a5, 0x7f73d2cb,
- 0xddc61b47, 0x8c3f2548, 0x6fcfcec7, 0x051e6236, 0xdc994ab4, 0x7de949f4,
- 0xa20d89ff, 0xfd06c22b, 0xbd6573e8, 0xff7fdfc9, 0xf212fdfa, 0xb4a3ee38,
- 0xfa01266e, 0xc02791eb, 0x09d723f7, 0x7e185f2e, 0xaf74e42a, 0x013ba7e8,
- 0xf143e37e, 0xf574fbac, 0x4abe1cd5, 0xfb5d29fd, 0xfd2f960f, 0xbcbe4688,
- 0x93efba29, 0x027933c6, 0x00a417f0, 0x1e0fd7f2, 0xf8c7a93f, 0x7f1f81ab,
- 0x6907f1b2, 0xff8e9ef9, 0xfeba4fd4, 0xbfd63d61, 0xcbfadc3e, 0xbb697d5f,
- 0xd297ea97, 0x23653c3f, 0x494edf94, 0x8a4e09b5, 0x2b8db2f7, 0x3b902e6d,
- 0x7c06d792, 0xce27ca71, 0x870f4708, 0x06a57cb8, 0x78804588, 0xc749fc2b,
- 0xa1e9bd3f, 0xf89ec0eb, 0xc76ca36a, 0xc99d6a38, 0x5cf4a26f, 0x8f28b0d1,
- 0x3b7ac18c, 0x16703fab, 0x51b2bfe8, 0xd3a6a23e, 0x953ddfd2, 0x94357900,
- 0x921a0652, 0x7fa3f4a0, 0xf3e1b152, 0x546f60e9, 0xabf20092, 0xff983dfe,
- 0x87d4589b, 0x9ee8c685, 0x499818ed, 0xafd9f780, 0xb3a1e1b2, 0x6afe0da2,
- 0xbe9038c3, 0x37f7097f, 0x3f6b245a, 0x82b9273c, 0x54f2015c, 0x31f10781,
- 0x8bc5637f, 0x4ed31abf, 0xe1b1d3d7, 0x0541364f, 0xea4fc527, 0x9bf05fae,
- 0xcbbd1dd7, 0x87ca4eef, 0xd156bb6a, 0xee468e4f, 0xb2b13527, 0xaedbf64c,
- 0x6ca4f2a4, 0xd2f4ecbd, 0xbd2f65c7, 0x2067dbf0, 0xc9a1fd7e, 0xbf8e9c39,
- 0x073da5f8, 0xe2fad127, 0x3cbf722d, 0x908b0db6, 0x254bc210, 0x7a597ffd,
- 0xafa50f08, 0x463a31ec, 0xc6f7e7b3, 0x78b1f086, 0x19232ecb, 0xb91e13dd,
- 0x6d8cbbf5, 0xa9783096, 0x760e9f6f, 0xbf178adf, 0x3bbc8236, 0x892053b5,
- 0xb9e061c9, 0x85da0f7e, 0x23c42700, 0x6f1053c7, 0x1495feba, 0x145fa02f,
- 0x37dbe93c, 0xe3027971, 0x9e90d239, 0xce9d7e5f, 0xc991f25f, 0x792ffb09,
- 0xec1b2ef9, 0xc55484e3, 0x95d9fae8, 0x4adf2009, 0x1d826f64, 0xe4bcf64b,
- 0xde91bbb9, 0x9ddff78a, 0xae92e2c0, 0x95d406fe, 0xbfb0fede, 0xe0e6eb85,
- 0x1b888afe, 0x59e4aee9, 0xcb47df31, 0x6332252f, 0xb8be184b, 0xf2726656,
- 0x2354f3c4, 0x509dfdd0, 0x22fbc0f4, 0x627703d7, 0xbe6ef3dc, 0x62316a17,
- 0xc3334bfd, 0xc0d930d3, 0x2bd32ce5, 0xf0dd7a41, 0xd38bea00, 0x70895d83,
- 0xd21956be, 0xc437a80f, 0x1912d3fd, 0xc19e987e, 0xc99ea8f7, 0xbfd0e785,
- 0x8c457655, 0x7a87bcd1, 0x297f9945, 0x3bae9f9f, 0x13b5ec12, 0x8ffde109,
- 0xdf0acb9f, 0x4542bb53, 0x66fe2a5f, 0x3561befc, 0xdf856fe3, 0x4067337d,
- 0x180717fb, 0xa07bc0ff, 0xfcbae967, 0x6bbed889, 0xc0f280b6, 0xf8e1fc44,
- 0xf9cc837a, 0xd0aedb5a, 0x24b75d09, 0x05e8ab44, 0xf8458fc6, 0x7a2f5ea3,
- 0x92a7be92, 0x9f309597, 0x0a78e7ad, 0xfe7316df, 0xf96b219f, 0xef8bac9f,
- 0x99653e53, 0x33edfbec, 0x3f94afc0, 0x57e00ebd, 0xfdf61f39, 0x07cdcdb7,
- 0xfa7ca66f, 0x4f857ab7, 0xcf53f2b5, 0xef5b25a7, 0x7a9f4026, 0xa0dbfd3e,
- 0x4f96122a, 0x7cb0f3e9, 0x7feda83a, 0xf02a7e54, 0x45f802ab, 0xc8a7e085,
- 0xa8e0dec3, 0xd9568797, 0xd21e5611, 0xd99201df, 0xba14fe93, 0xf4ade853,
- 0x4143e5f7, 0x52e904ee, 0x5d20bba1, 0xdfa7742a, 0xfa7e16af, 0xc13249f6,
- 0x26bfe575, 0xd65cffa3, 0xe942f2c4, 0x66077b7b, 0xa85c9c20, 0xdeed48c6,
- 0x75d4fd81, 0xaf5eae9f, 0xd5d2efeb, 0xddfd75f3, 0xa6957aba, 0xb363597f,
- 0xfdfe2091, 0xb2e27e9a, 0xb8d1c867, 0x63eaf470, 0x59c3597e, 0xc2e817a3,
- 0xe5f7c012, 0x790bc4e5, 0x221d8186, 0x28ba05c6, 0x7e206b8c, 0xe7d939b1,
- 0x656372a5, 0x743f8b04, 0x58b603d9, 0x618cae5a, 0xb1bc40f5, 0xf29ee406,
- 0xe2c1103c, 0x01f95d8a, 0x9fca8c5b, 0x51126f6a, 0xc8f9b76e, 0x167e708c,
- 0x47c828d5, 0x76b7a46d, 0x4d35ee76, 0x06590cb4, 0xd15aa571, 0x1df83609,
- 0xe0d937d5, 0x29aba9dc, 0xfa02faf5, 0x451fe17c, 0x8ae97b4c, 0x75818db4,
- 0xea4baf11, 0x4e6ff2af, 0x59d3ef12, 0x9a0b7f74, 0xc7739f98, 0x423d9d1a,
- 0x153d20d6, 0x411a9659, 0xe27f529e, 0x86bcf688, 0x1f2945f1, 0xb69d64af,
- 0xd29f795d, 0xa5f3fa01, 0x6eedb41b, 0xa07f0fee, 0x3258c9f0, 0x2ca3fb96,
- 0xf2e5c30e, 0xfaed3134, 0xae8f8a02, 0x68989116, 0x4449bbbd, 0x166f747c,
- 0x234f107c, 0xb7e478de, 0x7940120a, 0x03a9c0a8, 0xbbd8c9f8, 0xf6d8eabc,
- 0x812fe669, 0x3c7fb66e, 0xd9693fe6, 0x11c3fdb1, 0xd5fd406f, 0x263e4343,
- 0xeee7fb3d, 0xff73c08c, 0xa4569dae, 0xef1daef7, 0xd425f90e, 0x6139335f,
- 0xbf3b5d9d, 0xd3f4031e, 0x0254dcb5, 0x306baef2, 0xd8aec78b, 0x3698f5f1,
- 0x33f7afd4, 0xfe6461fd, 0x3fd37761, 0x41fa133e, 0x76057749, 0xe428cec3,
- 0x23d7caa7, 0x6bbbdf30, 0x6e99d7c7, 0x9fb74fcb, 0xd1e79e0a, 0x5b052565,
- 0x2c317d61, 0x8df2a18f, 0xd3542f89, 0x761bcbf9, 0xf6d01719, 0x39ff37dc,
- 0xd768e406, 0x750f6656, 0x41cf6dca, 0xf194431e, 0xe29972dc, 0x8a9813ab,
- 0x33bfcd3a, 0xdf02e466, 0x3fcb84f4, 0x57d63e31, 0xaffca478, 0x62e08781,
- 0x33eacef2, 0x6fefb00b, 0xe318fb3f, 0x4ba4269a, 0xab7fbf65, 0xe57b46af,
- 0xfecefb62, 0x82df6e7f, 0x76fb2fbf, 0xfbef9bff, 0x7abbd738, 0xe749e83e,
- 0xfac1ee3b, 0xae27564b, 0xeef48fb7, 0xffc7fd85, 0x7bffeefb, 0xc52b7de3,
- 0xfbe2edbb, 0x5affcdfe, 0x36f1ffbc, 0x7e3b778e, 0x3fe6f3d7, 0x57df7d71,
- 0x6ff9bdce, 0xf6def78e, 0xadf5d8af, 0x067b2a86, 0xa9015f5d, 0x316182b5,
- 0x92dbbe37, 0xd76c80e1, 0x8f30fd73, 0xc34bce0e, 0x23014df8, 0x904d0bf3,
- 0xfb7e0747, 0x0b89411c, 0x1d751fa2, 0x1bae1fb7, 0xc8768254, 0x9987ae75,
- 0xb55520dd, 0xadfed366, 0x989c0b39, 0x0fd24973, 0x7b3ea1bb, 0xfd6baf32,
- 0xe204f7c9, 0x7f1da812, 0x2d35ce5d, 0xef5ed760, 0xa5eed112, 0x1fbbda25,
- 0x9ece990c, 0x3dfad04f, 0xfadadd73, 0xfada054d, 0x8dde3e1c, 0xc6ffad84,
- 0x7107c17c, 0x13f65355, 0x356710f1, 0x9089942d, 0x5542f90c, 0x98bfc12b,
- 0x7f7daf93, 0xe3c1f81f, 0x531c3c7f, 0x971c0a4d, 0xb6485c20, 0xfa48dce8,
- 0xeebe4700, 0x7d63d9d6, 0x244ccf90, 0x8de38327, 0x838c4ee5, 0xe65b7f73,
- 0x5596cbef, 0xb2cfc0ad, 0xfc56cfce, 0x4de0dee5, 0xe38dffb8, 0x2fe084a4,
- 0xbff444bb, 0xadff9d65, 0xe2fbe5e0, 0x8fe3c143, 0x3a97cbc5, 0xb8b20cbc,
- 0xccabf008, 0x16a985fd, 0xca0fab27, 0xc8de7827, 0x9fa905fd, 0x42d3788b,
- 0xcc8bdf79, 0x5f386ce6, 0x30148f33, 0x1afd71de, 0x3983f511, 0xe575c04d,
- 0x8f31904f, 0x7e4373f8, 0x6f3be026, 0xbf1515dc, 0x0270cb60, 0xb871173c,
- 0xb42a9117, 0xeff9c95f, 0x84cacbbe, 0xf6820673, 0x211722ef, 0xadbf52d7,
- 0x47f04b28, 0x4b157852, 0x0e9d1bc4, 0x1c816f71, 0xb5bdc4d1, 0x47fdf875,
- 0x8b9c6842, 0xbe4deff5, 0x5fe5d4fc, 0x323b3ca9, 0x1e41fa8c, 0x5849bb9e,
- 0xaff156dc, 0x70626f6f, 0x7c132cac, 0x7e774829, 0xee755f39, 0x83e71cf8,
- 0x0e3bdebf, 0xa3f664e5, 0xefd1a3a3, 0x6fd03977, 0x437ee4a8, 0x0d11d7b7,
- 0xa6eeae71, 0x9b3e7e54, 0x55cb536b, 0xfdcfdca5, 0x7e40bfee, 0xa6bb2d21,
- 0xf822b50a, 0xf1802471, 0x08d4ef5c, 0xfe4c31b2, 0x1931ffeb, 0x6154fd38,
- 0x627e001c, 0xfd91e026, 0xd1abe98a, 0xadbc2ab1, 0x3494f6b9, 0xe01e27a6,
- 0x0e754477, 0x0be163f9, 0x75c03e7e, 0xf4db447f, 0xadfb30fc, 0x5638b135,
- 0xe2df5bde, 0x34379c77, 0x9700cb25, 0x9a8aa61b, 0x2655fb73, 0x238d97ee,
- 0x795d60e3, 0x9b655d6f, 0x11697808, 0x66ddf09d, 0xa359d365, 0xb079cc3b,
- 0x3e309e1e, 0xca8fd5c4, 0xe78022ce, 0x082387d1, 0xf2efd1f8, 0xf834c673,
- 0x430d226e, 0x2b882e3a, 0xb5c39afe, 0x72c764d3, 0x1cb65e56, 0x6b4de74f,
- 0xa3858fb0, 0x7fbc01d4, 0xe3211827, 0xbd878921, 0x501bf4a7, 0x1bb5fac6,
- 0xf6e115ed, 0xed823c3f, 0xef3898bf, 0xfbfc2099, 0x51fb2de1, 0xec073fab,
- 0xae3ca983, 0x09ae83d2, 0x0cf747f2, 0x1bfa07c1, 0xe7ac61fc, 0xdf84efb1,
- 0xbeb3be55, 0x8559e981, 0xde70f5ee, 0xccace1cb, 0xe2c4dc7f, 0xfce27faf,
- 0x8159c0a5, 0x4abd7eaf, 0xa6af2a7f, 0xd751e3a8, 0x197d8e37, 0x268a9bec,
- 0x43a06ec1, 0x466d4855, 0xc6cac3e0, 0x6f3864c7, 0xe360eb99, 0x8c7f2912,
- 0xd3a09f3a, 0x9a3bf2c4, 0x0dbcafd3, 0x1adce4e8, 0xe242e813, 0x0dace3ba,
- 0x06bbf0e4, 0x7be19fe7, 0x227bef6a, 0x790178d9, 0xcea7b1f5, 0x8f525535,
- 0x9ceb8c9b, 0x432d9655, 0xb296ecf8, 0x8aa2725d, 0xb14d3a9e, 0x1f3caed8,
- 0x8748e650, 0x5c3e74e7, 0x1311f787, 0xd242ef81, 0xfbf15bea, 0x62aa5bd4,
- 0xd4961d18, 0x3d6232ef, 0xf32bfb19, 0xf9e8f329, 0x369e7669, 0x6e4178ef,
- 0x4b8020db, 0xd4bfc99e, 0x1f4e8619, 0x8ee72b33, 0xb84f53df, 0xf98edd28,
- 0x2c4f48ff, 0x1b44f455, 0xef2bb9e6, 0x3e3335cf, 0xc489e957, 0x49627a70,
- 0xf01123b5, 0x6a4764b0, 0x92c93022, 0x084b4e3f, 0xf03e27a7, 0x43e373b0,
- 0xaeeebbfc, 0x5c4f54d9, 0xb313d2ae, 0xf44e9023, 0x959ae5ef, 0xe88b8d73,
- 0xff6f0509, 0x03e6f2c3, 0xf86113d0, 0x56b346fb, 0x54d8dc4f, 0xc6e27a88,
- 0xfbe6a2d9, 0x17cd6baa, 0x09d913d3, 0x3b2eb173, 0xcfd0c2a3, 0x39bfdc07,
- 0x61fbf3c4, 0x6b17d01e, 0x9b8476cc, 0x26f46f5e, 0x55f6c7d7, 0x825fffae,
- 0x97d722b3, 0x43f761cc, 0x8243a4f4, 0x2e64bcf4, 0xd002eb95, 0x4beb9323,
- 0x4e71e56e, 0x07cd9c9d, 0x96a19b39, 0x0afdecb3, 0x950bd337, 0x9abfc98d,
- 0xae6fdb47, 0xda669d95, 0xdc90e6ff, 0xddcb54cd, 0xe1096635, 0x96ee43dc,
- 0xae7bb930, 0x4fda1c69, 0x53efedbd, 0x3ca96f2e, 0x430ce61b, 0xa2f3051f,
- 0x1ddfdf34, 0xda76fb1d, 0xef2fc02b, 0xfb7e788a, 0xf603b739, 0x033b7d8d,
- 0x7c53e9ec, 0xfcb8db3d, 0x5cf8f4eb, 0xc81ca953, 0xd3d983bd, 0x84459be5,
- 0xe303455f, 0x91618aff, 0x4fad073e, 0xcf16ff4f, 0x60ef1761, 0x0774b0e7,
- 0xfc2ad979, 0xadb77e2f, 0x1605ce06, 0x1cf017af, 0x005fbe19, 0x78731678,
- 0xe3173916, 0xdaf14a39, 0xe53fe7f0, 0xa6a2dfbc, 0x5f0f18f5, 0x2bf6d3e4,
- 0x29f5761f, 0x4cf247f0, 0xaf790f0c, 0xc9f5be08, 0xeba0cf90, 0xe78d5ce7,
- 0xdaf5e547, 0x7ef907e7, 0xb4fe8a17, 0xe4fbe857, 0xd3bfcccf, 0x1ea0fbc3,
- 0x123f252e, 0x5c29fb2e, 0x70f5fe32, 0xd40e0de9, 0x01f3c7be, 0x2b0e3c3d,
- 0x649d2572, 0x6e7e1f00, 0xf15ca170, 0x42e143be, 0xb1e3bbe7, 0x40fb9ae1,
- 0xbcb8738e, 0xf4d7706b, 0x02157e87, 0xb75e2bf6, 0xad024f65, 0x6327abcf,
- 0x78a178e1, 0x070f56ad, 0x03837ef5, 0xaabcfaf5, 0xc7e4022d, 0xfbdfe42e,
- 0xc31ef895, 0x5d6e547b, 0xed3cf546, 0xe4dd20bf, 0xfdf07386, 0x9b940111,
- 0x47c6dd0a, 0x8e25fb30, 0x03a3a1cb, 0x3f515302, 0xe4760a35, 0xd3047f47,
- 0x704f1457, 0xc4f34bbf, 0xbc73a7af, 0x2352b8b0, 0xc52563c3, 0xf4f3f01b,
- 0x63af5e26, 0x4a2de076, 0x39f05ebd, 0xbbab9004, 0x8c5f7664, 0x8e04e240,
- 0x847e9504, 0x04ecd5f3, 0xb4779e15, 0x28dffa33, 0x8f81f138, 0xf043f7fe,
- 0x33dd2bdc, 0xf4afa63b, 0x3e29c0ae, 0xfde78b42, 0xe379ad11, 0x9bf9c1fa,
- 0x737bc4e0, 0x9cf0629a, 0xbb2d58e8, 0xbf9525ff, 0xf00be7a7, 0xd1f7d43b,
- 0x438584cc, 0x088cf37e, 0x79c50fcc, 0xa65d9853, 0x7bfa4f96, 0xfe6fbe80,
- 0x45692551, 0xc7942c7b, 0x04de7ee8, 0x3410cde3, 0x09104ef9, 0x09ff3a03,
- 0x7cd5bfc6, 0x9249f181, 0xef96f31d, 0xedcf2bb2, 0x5e2cbbec, 0x799c1e6f,
- 0xef851e68, 0x13a255b9, 0x0c9ba85c, 0x2059838e, 0x09941e6f, 0x7db9cbf0,
- 0x81e98bb2, 0x853bd428, 0xefc51eef, 0x0e590ad9, 0x8fbc291a, 0x7ca397e9,
- 0xbd511f3d, 0x0a5882ed, 0xf70f1fa9, 0xee76cce0, 0x7880e69a, 0x95fec64b,
- 0x2b39ce70, 0x20f07ed7, 0xbb3573e0, 0xaac8e907, 0xeed3f45c, 0x7e4053ba,
- 0x06f14c3b, 0x9d99cfef, 0x9d20f07c, 0xf155d6f7, 0xcf396e78, 0x9c237f15,
- 0x27dbce63, 0xdfb41d3a, 0x16adeb82, 0x66bcc738, 0x2adc48a4, 0x5a4adcf8,
- 0xaf33be31, 0xb039ceea, 0x0faa12ee, 0xf72864c5, 0xfa844b4f, 0xafdf013a,
- 0xf08dbaf4, 0xdaeb66bd, 0x3a0cc6b3, 0x07ed117f, 0xc75caf60, 0x106e55fa,
- 0x5dfa909c, 0xca18f4d4, 0x020da2cb, 0x4ad3345e, 0x1b335fed, 0xe3a667d7,
- 0xefa3aeb6, 0xbc317ad3, 0x886ee30f, 0x27ce11b9, 0xf13ae92b, 0x78d509fd,
- 0xdf445d2e, 0x75a4cda3, 0xde389dc3, 0x810275a2, 0x264b03ef, 0x01323f24,
- 0x3b27dbc6, 0xaed0fda1, 0xdd611b5f, 0xfaf9d1b7, 0x8817f1d3, 0x3fa0d36d,
- 0xc760a5f9, 0x46ea87fb, 0x0baddc60, 0x542f0c36, 0xe63ac70d, 0x0c103b13,
- 0x651f3a92, 0x4efb0447, 0x755968b8, 0xcdabec0d, 0x406c9f1b, 0x046b3aba,
- 0xc28c7e3d, 0x3c874ddb, 0x2e79646a, 0xc6a3decd, 0xfd1c9536, 0xdf152228,
- 0x1b31a3bf, 0x921626f3, 0x709bcc7c, 0xa47b3357, 0x0f84657d, 0xb2ed6ae2,
- 0x6f3c087d, 0xe7c2695e, 0xfd312f9d, 0x0db839d3, 0xd627dbe3, 0x5fbe04c9,
- 0xf52eb15c, 0x89e3c069, 0x9bd232cd, 0x1bcb2cf8, 0xc5897e28, 0xb1d79ac9,
- 0x352c4f71, 0xa0b57bb2, 0x5f8bd69d, 0xb40af254, 0x51c8ac72, 0x2f4a728a,
- 0x6b72f497, 0x46d593d1, 0xf21ed920, 0x9474e96a, 0xef54a557, 0x90f5a100,
- 0x306a8357, 0x5797aa6e, 0xc8a2c495, 0x5f8874a9, 0xbe0f9616, 0xf1d02d6d,
- 0x8183ecad, 0x5f6bff56, 0xb77a053e, 0x49e04acc, 0x5a7f6485, 0x80417460,
- 0x6d35e65f, 0xa0f812f9, 0xde045e64, 0xf01c75c7, 0x26b37c00, 0x8bafcf0e,
- 0x6f08857c, 0x78b72f25, 0x95ce96ad, 0xb75ce3f8, 0xfd6a5c48, 0x5c451255,
- 0xee877eaa, 0xe74af4a3, 0xf051bdb9, 0x743ca881, 0xbbdefb5f, 0xc76eb033,
- 0xf6e32d75, 0xd22b1ac1, 0x9f9fa1f3, 0x7af4095d, 0x0102bddb, 0xdd789d7b,
- 0x2b0fa035, 0x880e0ad6, 0xcbdf170f, 0xefa62fde, 0xfd0fbac3, 0xa515d19a,
- 0x7fd0076f, 0xf6c7bac5, 0x820dff62, 0xb43fc603, 0x89ed10be, 0xb048af12,
- 0xfa3b437d, 0x614f540f, 0x57b3599e, 0xaffa004c, 0x0764dfb8, 0x23a14953,
- 0xf9db2e85, 0xecc4087d, 0xbe8b331c, 0x15160ab7, 0xc51e93df, 0x4fa82102,
- 0xbd2a4e81, 0x5fdace8c, 0x36409d92, 0xf64ba717, 0xae09fc1d, 0xe767c55f,
- 0x74ef874c, 0x047ea98a, 0x975e6d3a, 0xe23b046b, 0xfcc04f84, 0x49749e8a,
- 0x4a3b6a2c, 0x0567cba1, 0xd07baf26, 0x7b0e8ea3, 0x4ba71dd0, 0x5128fe85,
- 0xb6595fa3, 0xfdf0264f, 0xdd1e9ebd, 0x908dfd72, 0x32f851ff, 0x6f5d0fdd,
- 0xd1cfcd6e, 0x48e0575e, 0x2f5009eb, 0x8fde5892, 0x12e50fc2, 0xdefb0fcb,
- 0xbfcdd3eb, 0x87e78229, 0x2c883f01, 0xe74fc97f, 0x0bf37b7d, 0x66792f98,
- 0x6875fb53, 0xe941bcdf, 0xd9bfe000, 0x7fe8fc4a, 0x950e50f8, 0x6f988836,
- 0xe67f244d, 0xaedf952c, 0xfe2cbfe4, 0x5de11583, 0xcbe4d5ba, 0x6e97efa3,
- 0xf3063a3f, 0x30079611, 0x49bbc7bf, 0xde1fe760, 0xfdf031b6, 0xf2c4a950,
- 0xc176f470, 0xe71648f0, 0xaa2d78ea, 0xa136ec00, 0x57b3dd8e, 0x6c937f5a,
- 0x0775c552, 0x2f38ca45, 0x63e787ed, 0xb8678a5e, 0xa7d6011f, 0xc94ddfbe,
- 0x9178e9bf, 0xa3695fd1, 0x695cf68c, 0xc84e96dd, 0x6c3d2cc3, 0xb2b73f42,
- 0xfc11acee, 0xbc3fdcd8, 0x55f3f784, 0x3c9a8a36, 0x6ff91ebc, 0x04dfa275,
- 0xe50d5bf9, 0xeb437e78, 0x0faf58ed, 0xb17a079f, 0x7fc5ad3c, 0x4bddb1d8,
- 0x95f8b841, 0xbef0d9df, 0x368dd6be, 0xeea9eefc, 0x3da7f9c2, 0x57eaddf2,
- 0xeddf305f, 0x0941fc34, 0x5d48baeb, 0x931d60be, 0x997d746b, 0xc4e261f9,
- 0xa5eb7b41, 0x7c839f2f, 0x7fad8eec, 0x5bd60e7b, 0x9ee75ff6, 0xb21abc83,
- 0xf60ec233, 0x0fa6e548, 0x79559f30, 0xd99224af, 0xfe2f9d7f, 0x3b80f30e,
- 0x6139343f, 0x271dceb4, 0xd1bd8086, 0x04dbe5b9, 0xba5defc8, 0x73c61a63,
- 0x4dcb6e96, 0x05e26124, 0xeb74094a, 0xb21e43eb, 0x0dcd5f1e, 0x73ff98cd,
- 0xe41be286, 0xb17f3043, 0x83e59cbe, 0xe2de783a, 0xdef9f0e6, 0x1b14f23d,
- 0x193f5d66, 0xb30362e4, 0xaf9a2e0b, 0xf1e28078, 0x6fe03ef2, 0x4f2e6af3,
- 0x0cefe3c2, 0x54f141fc, 0x57cda913, 0xe161b2fc, 0xb6819e6f, 0xf35eb886,
- 0x807dfd15, 0x3e4f929b, 0x58f5d22b, 0xd6cdf024, 0x287e63df, 0x01cf2de0,
- 0x21cbf9f2, 0x293e1710, 0x10fe3007, 0xefc261d8, 0x1c774b2c, 0xdce9fe42,
- 0xb5f31fb6, 0xeeebcf09, 0xcb1fc124, 0x9eb1e5c3, 0x96560dca, 0x0fe1c8e7,
- 0x1b0e9079, 0x8ef9e73e, 0x3c958e8c, 0x1ff2dec8, 0xf853225b, 0x4f2c2a7d,
- 0xc7c37cb3, 0x8430af3c, 0xe002612f, 0x7982fda9, 0xec1c0aa5, 0xd42b8700,
- 0xf3e1bcf9, 0xdf79834c, 0x3f805f1c, 0x7cc1d390, 0x041f5a5d, 0xe13e9bf9,
- 0x0f230910, 0x3cb3d73a, 0xfc394ee0, 0x7e4accf7, 0x4f9eb36f, 0xebcb7d7d,
- 0xbffad8bd, 0x221a7c2f, 0x1eae381d, 0xc3e71d4e, 0x9ce3f1cb, 0xf7f07fef,
- 0xfe826521, 0x81cf93fb, 0xda1bcb1e, 0x899f788d, 0xfdf13fe2, 0x5a78f076,
- 0xf31126c7, 0x9bea6b3e, 0xe5eb8e51, 0x273f0545, 0x1bf7afd1, 0x468adebe,
- 0xb63a27a6, 0x3a167d5a, 0xaf5bc74e, 0x6c573d21, 0xd3bcc76e, 0x18af75bd,
- 0xcbe754db, 0xaa7c27a0, 0xbcbc77f5, 0x6dca0c6b, 0x7e98bf7e, 0x9b14631e,
- 0xfc29b2a7, 0xcf9b953c, 0xec59e66a, 0x2dda37ad, 0xb4ef9f17, 0xc609bae4,
- 0xeccadd3b, 0xe2f5d3a5, 0xf9985f0c, 0x49bd714f, 0x0f3b2d48, 0xef12faa5,
- 0x7bb2b359, 0x245b44d5, 0xad4b5fda, 0xf7470e13, 0x7988d283, 0x79aa2b2f,
- 0xce7dcc9e, 0x0af7c024, 0xd604d5eb, 0xabe012bb, 0xbb65e3f2, 0x26dd809b,
- 0xa867e527, 0xf59459cf, 0x8819fb1b, 0xa5ff854f, 0xe08919d6, 0x3bc9127f,
- 0x5d71d608, 0xe812d7ca, 0x8b0f56bf, 0x47f393df, 0x56f3c187, 0x8e27bec9,
- 0x553adb8e, 0xb5e84270, 0x34fbdd27, 0x2e998671, 0xf8b17ded, 0x5fdd1c0d,
- 0xf680d3b7, 0xb7e0d5a0, 0x1ac42ed3, 0x0e849ad1, 0xa43883ac, 0x0214fc04,
- 0xf41e21f3, 0xfdc16798, 0xcd4236c8, 0x94e7e853, 0x449ff734, 0xf774904f,
- 0xc30390a1, 0x385abd28, 0x39712abd, 0x8e9bfb2b, 0xacf786db, 0x6a91a4c4,
- 0x5635df20, 0x4f0dda37, 0xe869fbf0, 0x41e4246f, 0xa74892c4, 0x3a26fefa,
- 0x38fbe6af, 0x1ea6af3a, 0xe3d6d2e3, 0xc2c74866, 0xbe3897e9, 0x05a2e98e,
- 0xcd3310e1, 0x796bf8a0, 0xeb4213c3, 0x4e27898e, 0x6b5fb43f, 0x2801efc1,
- 0xfbd5797b, 0xebb458b0, 0xc8d3eba6, 0x36b4e889, 0x53ad81af, 0x1c4edcf3,
- 0xa5dfee02, 0xabd74e7d, 0x714617a9, 0x09112779, 0xdcc59de4, 0xbbfc384a,
- 0x5fbef035, 0x013837da, 0x5fb843f0, 0xcf9025ed, 0x41f7cd12, 0xb7f4d7e7,
- 0xcd807443, 0x0c871daf, 0x43bfabb2, 0xbfeb9cbd, 0x25fc9651, 0x329e9451,
- 0x62615687, 0x49125676, 0x9ba5efc3, 0x4a7ca1fa, 0x79839659, 0xa32d4227,
- 0x086b61ab, 0x00b0cdf2, 0x3fba9bcf, 0x9351ed12, 0xd2237899, 0xe2367be1,
- 0x1661d395, 0x7043cf1f, 0xa1d0372c, 0xd69455a4, 0x814d7be8, 0x8a42c31c,
- 0xa2687a84, 0xb94657e3, 0x9f28a3aa, 0x2774ccd6, 0xf6c2c619, 0x3bb95ede,
- 0x52f6b90b, 0xaa1a0888, 0x1969eef7, 0xef04228c, 0xbdde20f1, 0x6bc6807b,
- 0xec153a95, 0x6d7f9df0, 0x32eeb064, 0x9b5f7953, 0x3e8feac2, 0xdc2577b4,
- 0xcf6e9337, 0x49f6147f, 0x7851f6cc, 0xd58fe5de, 0x9bddf3dc, 0x39d6517e,
- 0x173f8372, 0x3abe05ee, 0x1df5eec0, 0x777e0d6e, 0xa3787a8f, 0xd1fba945,
- 0xd86fc88f, 0xbcad728f, 0x1bb63f7e, 0xa1cb4ea0, 0x81dcfe71, 0x472f9f74,
- 0x74969a1d, 0xa1af1d29, 0xd93e0930, 0xd0ea357f, 0x30eef81e, 0x578f8704,
- 0x82141eee, 0xc3fcb483, 0xd5932d3d, 0x0f70f870, 0x857d21d8, 0x7d0fabc3,
- 0xebe87088, 0x6c5d29be, 0x935cbc07, 0xd6fbc06d, 0xc16c38ae, 0x45fd0af8,
- 0xe3e23ea0, 0xbbe5efac, 0xa11fc56c, 0xd354ece3, 0x429ef297, 0x4dd1bd57,
- 0x628fb12a, 0xe96a6cf7, 0xf5ca2ba7, 0x25abac36, 0x358f75ca, 0xf78ff71e,
- 0x76e35c00, 0x0b8ea73b, 0xb8b135d1, 0xeefdc1c7, 0x5bf32ca3, 0xf2f254a3,
- 0x6225ec9a, 0x81c9c40a, 0xfb43e217, 0x8de65f89, 0x19f74118, 0xde6032ef,
- 0xfb8b28fc, 0x2b63cc20, 0x7721f808, 0x1ee20aec, 0xbe218827, 0xd9abe650,
- 0x9af5fcc1, 0x396f8342, 0x6015ef3b, 0xb47d10bc, 0xc023e8e9, 0x1db1a3e8,
- 0xa9a2a3e9, 0x6347d19d, 0x06644e75, 0x3f03373b, 0xc60496bf, 0xa23bde02,
- 0x51269abe, 0x151a1ffa, 0x91ba01a8, 0xe5a6e7bd, 0x3d708a5d, 0x7c3f161d,
- 0x7abeca7d, 0x4b6d6fc3, 0xe06943ca, 0xe033ee4f, 0x37029779, 0x858c5fa5,
- 0x58b6c5e5, 0xfc035fdd, 0xedb4272a, 0x6d6fed85, 0x36f31f79, 0xd86efb6c,
- 0x66dbef05, 0x42390c53, 0x5beed6f3, 0xd767f78e, 0xd87dd806, 0x05e024d1,
- 0x3c3bdebd, 0xe104ff18, 0x1a4f7601, 0xf91da3c0, 0x5eff1365, 0x7051ab2c,
- 0x1a1f9e81, 0x890deec5, 0xebf3b0b4, 0xd7111621, 0xcec2c439, 0xbdf7e259,
- 0x95bf8225, 0xfb01bf75, 0xa69943c7, 0xbcfdffde, 0xaf89a4bf, 0xe854f82b,
- 0x28d24a89, 0x4ce47fb8, 0xa2d13b8c, 0xa8d89fa1, 0xca78d514, 0x88788f7b,
- 0x47aa0ef3, 0xff3dd8af, 0x94abd02e, 0xfc00be7e, 0x968dfb04, 0x4a6e0023,
- 0x70cfa07f, 0x0defa1f8, 0x1e60f987, 0xecb617b0, 0x3de2225e, 0x6bc47d1a,
- 0x491bdc26, 0x914667fb, 0xfdf4adaa, 0x425a68cc, 0x13d78e3d, 0x2b207d79,
- 0x1a713f53, 0x3d7cfa04, 0xb64ebb8f, 0xc931fcf0, 0xd186ea3e, 0x5c766750,
- 0xea245256, 0xe16f8505, 0xb738080e, 0x75f9f896, 0x00c5204a, 0x58f85378,
- 0x56fc180a, 0x2452b4aa, 0x18f20187, 0x7dd0f1de, 0x9dcbbd4b, 0xdf652fab,
- 0xcf9fea71, 0xc1f9ebe4, 0x3d17f5f6, 0x099eefbe, 0xb7372df0, 0xad03723d,
- 0x0e7a5c57, 0x479707cf, 0xa1795c55, 0xebf42f7b, 0xdbfce77f, 0x4d874051,
- 0x7ec298df, 0xe1c3550f, 0xc029e2d6, 0xbdf932f7, 0xc951242e, 0xb1e55633,
- 0xcbb71b42, 0xf8299510, 0xffaced1c, 0xf8081140, 0xf0b14af4, 0x9e32547e,
- 0xe5d14e1f, 0x9f87fead, 0xc132f9c5, 0x71250030, 0xcf3628c9, 0x324ecc37,
- 0x9ce0ffd3, 0x173f1a69, 0xaf72477b, 0xdef1d2b0, 0x357cec21, 0x19aaae33,
- 0xc6c4c4ea, 0xfbda26cf, 0x6b13320a, 0xb8c2c6a7, 0xdf18c9d1, 0xdaeb35ca,
- 0xc812bd53, 0x8c9a9269, 0x88d38979, 0x7a633eca, 0x08eeed03, 0xe3902eba,
- 0x742c8cd7, 0xe7ede54e, 0x4d43ffe8, 0x2a99f6e4, 0xc72ae37f, 0x8d54e75c,
- 0xf78b52fd, 0x9fe9fd01, 0xf2e1ede2, 0xfce33e2c, 0x77c9e2df, 0x1eb3f9c2,
- 0xe10e399e, 0x27a3ab7e, 0xd470f5dc, 0xab815dc3, 0x9fd98e1e, 0x86c6a738,
- 0x2e1e9381, 0x48ed48d3, 0xdc0a63d0, 0xc77970f5, 0x9de2e8cc, 0xabde1334,
- 0xe0c48ef8, 0x23350ef8, 0x9ba41ea1, 0x01ef1168, 0xf5e28cce, 0xbab04737,
- 0x64a8ef82, 0xae1eb7c4, 0xc666387a, 0x58e3f7f1, 0x2f00bdff, 0xe202e509,
- 0xcc9ba147, 0x31ddaad4, 0xec507a2a, 0x2e1c69eb, 0xfb46bed4, 0x8ade3739,
- 0xafb02671, 0xe08425a7, 0xd6ce5b96, 0xf2dc3b95, 0xf4a9f83c, 0x72bfbc75,
- 0xff3fe10a, 0xca2f3c14, 0xce0555e4, 0xdad1be53, 0xa69ad3c9, 0xc338829f,
- 0x7efb9350, 0x1080cfa0, 0x1475e783, 0x707447ee, 0xd767bed7, 0xf870f5d6,
- 0xb131fc03, 0x3a14bc27, 0xe3c2c0fb, 0x20c8034e, 0xbcc797b0, 0xf20d1196,
- 0x86c5349b, 0x715c4b8d, 0x0e383f38, 0x63a457a7, 0xcf83b881, 0x423fa9ed,
- 0x5aa3ed8e, 0x36c72552, 0x96d3ee8b, 0x4c729ef8, 0x8e64d3c1, 0xbbc4c987,
- 0x934be20b, 0xd045f489, 0xed0e481f, 0xe7d95bbf, 0xf6103240, 0xc1c58379,
- 0x67df3fe4, 0xbcd4df70, 0xf8b3f984, 0x0b6659fc, 0x02435f7e, 0xce104752,
- 0x91df7829, 0x5a1b18d7, 0x4fbf9287, 0x66115486, 0x7bc3cdcf, 0xc85c29ae,
- 0x75a15177, 0x8482ac98, 0x75f0fdf7, 0x7b33a99c, 0x5bad8f21, 0x9d814774,
- 0x1bec21d7, 0xfc93fb83, 0xe9ff4023, 0xee35cfdb, 0xda7680ae, 0xf1fb08af,
- 0x59162ff5, 0xc3b021fc, 0xb93e7be4, 0xb2953b77, 0x8509ea35, 0xfbe0b37e,
- 0xde81cbd4, 0xdd6103fd, 0xd1d54053, 0xf659e772, 0x6376431d, 0xecf304ba,
- 0xff7966e9, 0x8125c439, 0xdfa7ab7d, 0xa1a74bef, 0x08604578, 0x5d8a29f8,
- 0x1eead536, 0x57cfa569, 0x9b66eff3, 0x05188ece, 0xf4c1f978, 0x4f4b4074,
- 0xba511d0a, 0xecf00f1a, 0x69fcf8ca, 0xcddfc730, 0x7a009738, 0x43dfb151,
- 0x026b8a76, 0x3b37a7ac, 0x3dd5897e, 0x3b017ac5, 0x2e67b15e, 0xdd9087e6,
- 0x74a641d4, 0xcbc71b74, 0xccab733c, 0x600fcdee, 0x48eafdfe, 0x473b5ee5,
- 0xb791d824, 0x54d94ead, 0xd586e707, 0x6b7efe2c, 0x83f1ac95, 0x86dd90dd,
- 0x66fbb3ef, 0x6da65f6f, 0xfe604cff, 0xfb57a17e, 0x3412589c, 0x9cf6edf7,
- 0xc035e0d7, 0x3123c3bc, 0xaf3f413f, 0x79fa7f7e, 0xe6adf3f5, 0x636ad57e,
- 0xcaa748ed, 0x6560592e, 0xaaf750f6, 0xcae0ebc7, 0xe7e0deba, 0x93480f36,
- 0xb5abf754, 0x082c8ead, 0x328c6f77, 0x79ef029e, 0x00e2cfc4, 0xc3dff255,
- 0xe59b83dd, 0xde81f166, 0x98161de6, 0xe1a0768a, 0xf608bf49, 0x4100b0fc,
- 0xe02b3bfb, 0xf8d02c32, 0xee4fcc01, 0xbdc007e1, 0xd65eb426, 0x01f98bb0,
- 0x4fe8d5f5, 0x027f5194, 0x387accf4, 0x17c01e9b, 0x41fe8694, 0xfc85dfd0,
- 0xcfb82ca9, 0x12c3fb92, 0x5ad497a5, 0xf5a37fd6, 0x096ae35d, 0x927755fc,
- 0xe363294c, 0x98d7efc3, 0x93555fa9, 0xf508224c, 0xf8785eab, 0xc06be9fd,
- 0x09758e5f, 0xad287f70, 0xf7fa58d7, 0xf8debfdd, 0xb81afef0, 0x65fa946f,
- 0x7f2aaceb, 0x78fe37b7, 0x0b918c04, 0x3dba47f0, 0xa1f0237f, 0x8a68af12,
- 0x111f7ce0, 0x8068bba4, 0x57274297, 0x7e8f9b2f, 0xe725c445, 0x589e4087,
- 0x16ffc716, 0x46c38f2b, 0x129ff7b1, 0xbf905bdd, 0x023f3adf, 0x8cefcbe2,
- 0x5cfe8a3c, 0xe7c59593, 0xd04a79f7, 0xb9f0527e, 0x3f702acb, 0xf8103fc9,
- 0xcdf1daed, 0x6497e071, 0x43de02c9, 0x9efb24da, 0x7900cf4c, 0x82bedb34,
- 0xa26b296e, 0x6b13bf11, 0xbc0ff08a, 0x35a7655b, 0x9b4cfbf1, 0xa81deece,
- 0x661e63ce, 0x4565ddcd, 0x308bf3fa, 0xeec6567e, 0x7befa0c3, 0xfd212fd3,
- 0x7f4012e1, 0x13fbf390, 0x61a8fcf0, 0x42e20d8f, 0x827efc1d, 0x09cd0d33,
- 0xbe5969f3, 0xf0362fe5, 0x70e7ded7, 0xe2b52338, 0xdb654a3d, 0x83ffbc44,
- 0x0b709bce, 0x161ba7c4, 0xf7efb264, 0x8a6777d8, 0x67ff4cfe, 0x167cc0f3,
- 0xc8efc434, 0xb2727b14, 0xf583ebd9, 0x188b5535, 0xbbac9e2f, 0xbf0a6c37,
- 0x5f6f4c37, 0x712ab49e, 0x87cc04e9, 0xf3676a5a, 0x594fc6f4, 0x9f12c4df,
- 0x24b2df8a, 0xcfeb08bf, 0xc08126fa, 0x5a679715, 0x03c89e52, 0xcec89e3f,
- 0x44ac30e1, 0xcafda376, 0x6fe89fcf, 0xbe43dc37, 0x6cde5793, 0x4aeb3738,
- 0xfdfb6624, 0x77600997, 0xe0b1fbb9, 0x8a07d322, 0x1be5377d, 0x6f557c6d,
- 0x8d34e6e7, 0x41207fbd, 0xa77fb378, 0x55eec022, 0x06ff61eb, 0x7bb587a6,
- 0xe10c7909, 0xf52dbe90, 0x2947b81a, 0x3b068ffd, 0x7c02dbcc, 0x3cf80f11,
- 0x54fcf787, 0xd08dff10, 0xda20d15e, 0x927eb0fd, 0x95f01971, 0x70283762,
- 0x6cdf3c69, 0x91d7431e, 0x5f60d675, 0x3378874e, 0xcffa05f0, 0x2fbcfee3,
- 0x5357f40e, 0x8273c240, 0xa3bbb3ac, 0x60e4a816, 0x3e0379d3, 0x5bfcf37f,
- 0xd881e7da, 0x2dbde0cb, 0xef17e606, 0x28f7fbde, 0x9e6f4b90, 0x82f1c6ef,
- 0xbb4f4376, 0x6b91e118, 0x67718315, 0xc44c5db5, 0xb79003ac, 0xaa9a2d35,
- 0xbb77a131, 0x7213fb37, 0xb4f495bf, 0x1ec0721f, 0x11d8c311, 0x3e74ce1c,
- 0x6f48f809, 0xe36e5c57, 0x24c1e6f1, 0x6ca3ee1d, 0x18b71f3c, 0x8a6e1fbf,
- 0x7d472fb2, 0xaea5eccc, 0xbf1fa7dd, 0x13ef9e06, 0xe711fdd9, 0xb7a7e445,
- 0xda1e2e76, 0x2a5be2a6, 0x5f4f1139, 0xf9db3ff5, 0xd5ffed06, 0x4716489e,
- 0xa9979c97, 0xf50877bf, 0xf97871f7, 0x38f3b007, 0xd7b800ef, 0x2fdb07e9,
- 0xfafc3d1d, 0xc3da1b3c, 0x1ea0e981, 0x376bac46, 0xac5bfe02, 0x90d9d7f9,
- 0x00a3eadf, 0x33925e2e, 0xf3804c90, 0x7403927a, 0x7626a815, 0xb5b627f0,
- 0x97800c18, 0x98c98d8c, 0x9f89b3a7, 0xafaa2e57, 0xe8ab2635, 0xef3f1162,
- 0x877b293a, 0x1f9eaac4, 0x72f931b0, 0x6fe94f72, 0x43e34f30, 0xc61e1913,
- 0x31b06cde, 0xd18afb7d, 0xe866cd7b, 0xdf80c477, 0xfbdeed0d, 0xcfb85efa,
- 0xc761d178, 0x3dff8858, 0xbf607362, 0x6a9b7dc6, 0xf1b7cf20, 0x5452d013,
- 0x14286caf, 0x37de740d, 0xefc58388, 0x1fd0180e, 0x893dc60f, 0xf9f60e2b,
- 0x1bcf5f10, 0xf9cd062d, 0xdefc1bd8, 0x326d7bdd, 0x89b12fb6, 0x2dadc788,
- 0x37a07139, 0xbbeeac5a, 0x8e2fa06d, 0x12c0d5b5, 0x629f7894, 0xb03c4daf,
- 0xf4d19af5, 0x061d89cf, 0x71dba03b, 0xf61179e0, 0x484938eb, 0xd87a408c,
- 0x8f3c746f, 0x3a37bc7a, 0x1d7478d8, 0x2abf016f, 0xff9aa7f0, 0x7f5a34a1,
- 0x858a55a3, 0xfe052efc, 0xf9943eca, 0xb5c4f51d, 0xe4ac82de, 0xb8817ada,
- 0x3a5f92b3, 0x7f944ece, 0xd2e9012f, 0x6a3d7368, 0xda0ef663, 0x30f727d7,
- 0xae15e8bb, 0xe1524947, 0x829f8050, 0x8b1b7aa7, 0xe9eb2a33, 0xdbdffe6d,
- 0xca549e98, 0x9bd74bef, 0xe9178764, 0x0fcb1b66, 0xe6fd7877, 0x6b23c854,
- 0xcf7fc54c, 0xfb679549, 0x93e7a47b, 0x1b057bda, 0xf8060cdb, 0x8762ac0e,
- 0x6de68310, 0x20ebed1f, 0x48f5499d, 0x09878d7f, 0xdd6971f2, 0x48ee2c9d,
- 0x7fbf0de5, 0x81d1cf0d, 0x7a79f87f, 0x1396817f, 0x18afd69b, 0xdbf5f088,
- 0x7042af80, 0x65037ca2, 0xe811ad55, 0x5652d175, 0xe973f316, 0xc8dd6b45,
- 0x58eb459f, 0x5b1ee17e, 0x0ce7ae32, 0x886257a7, 0x27f9001c, 0x657f0e2e,
- 0x6e9c79dd, 0xd13c354f, 0xfa52f30c, 0x73e013fa, 0x4f63e352, 0x7a1572c3,
- 0xc641b53d, 0xb5224a71, 0x7cadf6e7, 0x18076dbc, 0x20dc4fbd, 0x5ffdc0e7,
- 0x0ec4bd13, 0x3637ec71, 0x7e41146c, 0x9cf401bf, 0xf41cf8cc, 0x0f3dc9ed,
- 0xf402fd46, 0x4081bb5c, 0x2315fcbc, 0xe2a2d929, 0x5febdd8b, 0x696ff0d5,
- 0x1835f55d, 0x158b6f97, 0x7c2bce40, 0x15fdc0ab, 0xe42af3a3, 0xfc74ebff,
- 0x2fbd953f, 0xdfb03b47, 0x9fff9c13, 0x9ff94198, 0x10d98a3e, 0xaf38c023,
- 0x07dfc318, 0xa40ff5f7, 0x6d5ca0bf, 0xbf5721eb, 0xcdb57266, 0xafe74a96,
- 0xe31bb6b8, 0x71f5c10c, 0xaa6279ba, 0x02c93742, 0x6296bfc0, 0x8bc01870,
- 0x99e815c2, 0xdfb7cdda, 0xd95c8690, 0x0f39e122, 0xf9e2473f, 0x0277ca1f,
- 0xe486bf0a, 0x6eb7c299, 0xd5d83473, 0x8056ab53, 0xe7971f5d, 0x253cfa45,
- 0x52c687b8, 0xf80a767d, 0x383c8c38, 0x57c7e5c1, 0xf762fbb2, 0x7a000fee,
- 0x221ea12e, 0x13ac87ec, 0xa51780ec, 0xdd8eb1dd, 0x5a3c3ac3, 0x2bbf9cd0,
- 0xef0c1ff5, 0x41fb8f40, 0x7c634787, 0x3c84603a, 0xa63e11d5, 0x839088c7,
- 0x570c40fc, 0x5b3e000f, 0xcdd7f544, 0x4a75fd2a, 0x553a45ae, 0x347970e0,
- 0xc55f5f93, 0x95ff7db0, 0xe21585d3, 0x2f73aa85, 0x024890ea, 0x605167e3,
- 0xf8c22e7c, 0xba4cf6a7, 0xdafde90a, 0x076ef4f0, 0xfe162aff, 0x48f5a73d,
- 0xec33319f, 0x13cb1df8, 0x46223392, 0xb0f91f63, 0x57f1bddc, 0xfd01d7e8,
- 0x46f7bf02, 0xff4025ff, 0xfbdd0c24, 0xf0abdd28, 0xa501d0a7, 0x55a26b8b,
- 0x174f41f2, 0x02a379ca, 0xe7745797, 0x33474f95, 0x9780b079, 0x66f25e8e,
- 0x60fcfd94, 0x81ec9f3c, 0xcf0cf9e7, 0x7c02be21, 0x67e1f22b, 0x3dafe117,
- 0xaf6c76d1, 0xe60174f9, 0x73f2d4a9, 0x9f3e7aab, 0xd1a5eeb2, 0x4b7ce682,
- 0xca34ee7f, 0x5a2bbee2, 0x48ea3e77, 0x34c7d10b, 0xd92ecf6e, 0xff73c268,
- 0x7802d02d, 0xbdfecddb, 0xbb3de56c, 0x0a4f0d44, 0x4cd115ea, 0xe1f42b8e,
- 0xc3246658, 0x55f2ffa8, 0xc86ee172, 0xab59f9ff, 0xdd346f37, 0x77a316c7,
- 0x07e8b5f6, 0xf182af38, 0xd833caaf, 0xc6241f21, 0xde201765, 0x7c0a2481,
- 0x33cd8fb8, 0x1979d52e, 0xe70ec9fa, 0x0f079038, 0xf8297c73, 0x9bd0e055,
- 0xaf0deb9e, 0xe27c387b, 0x8e5ebb79, 0x9efe7314, 0x5c5dfbc2, 0xe045788e,
- 0x2f711b27, 0x59fd6117, 0xe505fe4c, 0x73c11648, 0x727597c9, 0x5e9fe5e4,
- 0x91acbc8e, 0xc2da1323, 0x0bfa11ca, 0x1bf1ffcb, 0x4b1da216, 0x63b7870e,
- 0x3d334677, 0x93fa0f1c, 0xb2f78bf6, 0x3987def3, 0xc48a52dd, 0x0ddac9bc,
- 0x5713cc26, 0x366d90e4, 0xaf7f81c9, 0x16fa06d9, 0x1f76cd7a, 0xc5e70c9e,
- 0x9c074649, 0x03929f5f, 0xd453f788, 0xfa45af01, 0xc7fbc7c8, 0x0223c8c3,
- 0x47ef12f1, 0x9cefd083, 0x9f213626, 0x5046992c, 0x78deee7f, 0x4955d205,
- 0x74008a5e, 0x23175a5b, 0x54ec7b40, 0x94e401bb, 0x962b8fb2, 0x71b0c819,
- 0xd40707c8, 0x6f0ae472, 0xcdbbfe15, 0x49dce343, 0x47210c72, 0x33fb3d1f,
- 0x8da8bc75, 0x22f1d5d6, 0xfbe07f5a, 0x468e8bc4, 0x78801e07, 0xae6c3fd1,
- 0x94779876, 0xea28ff25, 0x912ac4b7, 0xc5d6e4a8, 0x4a1fb7ec, 0x2e3c952f,
- 0x34a95a45, 0x81c4d04e, 0x6073ab6f, 0x582bf81c, 0xe380c54f, 0x7870c34f,
- 0x7b5846af, 0x1fa3ad9b, 0x13e40b97, 0x97e8f882, 0xfc42255f, 0x063b9145,
- 0x2fe2ac7b, 0xa197900b, 0x037fdbf0, 0xd7b57d1c, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7dcdff00, 0xd5947809, 0xe77df0d5, 0x24cb2d9d, 0x7642c993,
- 0x03bbec26, 0x4eb1ab09, 0x04906008, 0x8d441007, 0xb0900938, 0xd2910364,
- 0x208196d6, 0x2b188a06, 0x0eb154b5, 0x4551fa14, 0xdb1ab61b, 0x1a4013a0,
- 0xad563414, 0x61a5afd8, 0x80891d91, 0xe58ad3fd, 0x7bdce73b, 0x264ef333,
- 0xe79f6a02, 0xcdcf0f0f, 0xcf7bde5d, 0x773dfb3d, 0x79632d49, 0x9b19223b,
- 0xed50b390, 0xccc9a906, 0x831b163c, 0x43632f1f, 0x087a3e79, 0x6b9859e6,
- 0xf26b6320, 0x01de7975, 0x9fc75d8c, 0xa269fd3b, 0x678e3e15, 0x30d6fe6c,
- 0xb53349eb, 0x7fe1d767, 0x268c5d79, 0x649f595f, 0x9fc7d93d, 0x24bf8f9f,
- 0x4c33ffc1, 0x2b1812cf, 0xe1a7e263, 0x70ffdfcb, 0xdfc7b418, 0x54dec655,
- 0x805689dd, 0x12dcdca7, 0xd8ceddd5, 0x13c7f933, 0x52d491dc, 0x223ddf87,
- 0xb97178c6, 0x71debde3, 0x55de798c, 0x0fc816d9, 0x4a3d1936, 0x64e2fc34,
- 0xe8826b76, 0x06947e0f, 0x041967c5, 0x55437ff9, 0xfe97632c, 0xc5f4a3ad,
- 0x32f2b89f, 0x7a8afbe0, 0xb439639d, 0x185068ab, 0xd1cc62cb, 0x19cd7995,
- 0x4785d58c, 0x5fd0620d, 0xa748bece, 0x292fca01, 0x8329af66, 0x870800d1,
- 0xa23fc241, 0xd41b7d35, 0xd8983757, 0xca5ec86a, 0xe119ac61, 0xd9a23bd5,
- 0x077e3f00, 0x0fa67e1d, 0x6bca00cc, 0x630b2e1d, 0xff78c29b, 0x7b64c29b,
- 0xb483347b, 0xecd192db, 0xd7a7c004, 0xf40d1633, 0x6983c481, 0x036e92f6,
- 0x1f3099f4, 0x8018f33d, 0x3eadd94e, 0xadd2f115, 0x9163aed5, 0xadf471fe,
- 0x4ddbe68c, 0x6039d76f, 0xf7813afc, 0x543b4d9d, 0xd873e03d, 0x156ada98,
- 0xf728d2d2, 0xa8f3c458, 0x2c6aaaec, 0xa8f7cd8f, 0xa59f686e, 0x00b3ed54,
- 0xe678d85e, 0xcce502d8, 0x848f8307, 0x18d616fa, 0x2398d905, 0x2828ce2d,
- 0xd9c6751f, 0x1de60038, 0xf60a62ed, 0x1a32d8c7, 0xcba45fbf, 0x38b2fd85,
- 0xfd0052a7, 0x2307fb0c, 0x767ec8bc, 0xec568d36, 0xf35c6f00, 0xc01ec518,
- 0xe24d305f, 0xfeccf5ab, 0x73d7ec53, 0xba40e748, 0x7398ebda, 0xfaefb423,
- 0x2c31bf72, 0xd2bedfca, 0xb778d0aa, 0x46b9ddbb, 0xd879f346, 0x9c8fdf0a,
- 0x0067ddee, 0xf1cf8678, 0x03da33ec, 0x519733e6, 0x1e2d297f, 0x11d2479a,
- 0x8ba60e77, 0xcfd4312d, 0xc6be33a8, 0x4baed001, 0xca07cc15, 0x543f9ad3,
- 0x5569af10, 0x71d20acd, 0x825ed367, 0x3f79b537, 0xea11814f, 0x7201dd20,
- 0x8f301755, 0xcd1d16c5, 0xa145b163, 0x99c5e574, 0x7fa82e89, 0x6c5eeac4,
- 0xc79fea19, 0x62771cca, 0xbebff415, 0x7cfb5ba9, 0xb7bc027b, 0x278867c1,
- 0xab72dfd9, 0xb269fa91, 0xf3847fb8, 0x72de9cab, 0x476f7900, 0x48a39fd3,
- 0x88e21a2e, 0x8e8709be, 0x96123d13, 0x78a0ce00, 0x0a85a1fd, 0x85f5aa83,
- 0x23a53340, 0xddb8279e, 0x8899318e, 0xf89f806f, 0x09311ac7, 0x8c62f2f8,
- 0x91c706bb, 0xd91427ed, 0xb45f5022, 0xcf77c5e7, 0x598e652e, 0xfbcf003d,
- 0x6eb2778b, 0x12f77748, 0xbb7b7ba4, 0x21878f81, 0xb38b313f, 0xa4bbfb16,
- 0xce38e9b0, 0xf942984b, 0x979e064b, 0x95abfaf8, 0xeb11ebe3, 0x7896c5a4,
- 0xf02b278e, 0xbc614bf1, 0x7a1eb05d, 0xb3bfcad7, 0xcd617e0b, 0x1e705f9c,
- 0xbb64bfa8, 0xdbdfa2dd, 0x3d5cee9d, 0x08cd93e7, 0xde11c8e7, 0xc3b7c87d,
- 0x90fb3cf3, 0xe098d3ff, 0x27ce3c93, 0xcfbefcc1, 0x467ea36a, 0x8865699d,
- 0xb9852cf7, 0xd32ee902, 0xa1ae10d7, 0x89a3dfc8, 0xb61e407f, 0x52c378e3,
- 0x800354aa, 0x13acc712, 0xdec67758, 0x5da9dab6, 0x3ee708e6, 0xd3ab37e4,
- 0x207cf245, 0x2be54ac2, 0xc07f3833, 0xfc407ff7, 0x2ed3cb05, 0x7e01a394,
- 0x7e438a39, 0x8fc8ec8c, 0xbcf013bf, 0x63a5e42d, 0x613feeff, 0x3acd71ff,
- 0x0c9d02a7, 0x65e9123f, 0xa2f874d0, 0x8fe1152a, 0x00ffc063, 0x358e6da0,
- 0xa52ce507, 0x5d20a1cc, 0x875c229b, 0x230fd4ad, 0x4732b9bd, 0xef86ade7,
- 0x893b46e6, 0x3ed8df7e, 0x366667ec, 0xc01f6fcc, 0xe115fc1e, 0xb6b07b03,
- 0x6ff4f508, 0x3d4469ff, 0xd7f2976a, 0x38a22434, 0x48ae3f80, 0xf7a7e0bd,
- 0x410bd271, 0x73d60ef4, 0xebf6f4c1, 0x039ead05, 0xf4e05d7c, 0x9f226770,
- 0x522f35c5, 0xead07eb9, 0xd1e8ceb5, 0x3a083f41, 0x7e708a5c, 0x0c5cf881,
- 0x7ae38832, 0x583eb346, 0x0e1d99de, 0x76a4898b, 0x1c3b45ff, 0xd1df1316,
- 0xadcceb0e, 0x47c01507, 0x576a8379, 0x8fd50a61, 0xff489cd9, 0x8714eb17,
- 0x41a4e509, 0x71787e25, 0x4bd93865, 0xbb67ef09, 0xdbb107a3, 0xcff21520,
- 0x8ec9dddc, 0xf188c656, 0xf18790ed, 0xd679592f, 0xc5277568, 0x1793e804,
- 0x4308be1b, 0x644ff73c, 0x62c64e03, 0x0ed6a70b, 0xf0290883, 0x537f09bd,
- 0x6b83af10, 0x69ac1454, 0x95269dee, 0xfb1dd6e8, 0xfe5ace1b, 0xbd700d9c,
- 0xceb46dbc, 0xf537c81d, 0x05ec6757, 0xb8232bf8, 0xf7b4be5d, 0x33e42f5a,
- 0x92f77f59, 0x3f7bd262, 0x13192b07, 0xeedf1fa0, 0x61eb8273, 0xd53d6856,
- 0x2a76871f, 0x850023d7, 0x7a3ee651, 0x70d427f4, 0x27f5aa87, 0x7baa3988,
- 0x7f107e02, 0xbf84e18d, 0x77209eea, 0x48e70419, 0xc5bf7fec, 0xfca092c8,
- 0xb623c80a, 0x037f7093, 0xe2074778, 0xaa6f0fd1, 0xe08454f5, 0x5f0fd50b,
- 0x0e905d3b, 0xd16abfd0, 0xb12e3cd3, 0xb3d20770, 0x4864e8ce, 0xe151cf7f,
- 0x55ba081f, 0xd4bb9e08, 0x1b88f430, 0x91e2f7e6, 0x7f7e0754, 0x984afea9,
- 0x46fd122e, 0x979c14f7, 0x851ad69a, 0xc35f70f6, 0x032dbe95, 0xc54dbf48,
- 0x4e872bf2, 0xbe03dcd8, 0x8466fcd1, 0x7e7687a6, 0x9ac8fa95, 0x6150ff40,
- 0x7cc17e7c, 0xfe3434a4, 0xf244194b, 0x7a1f50c7, 0x1ab799d2, 0xa072bde6,
- 0x997ba7e0, 0x983ee51d, 0xabab46de, 0x6e402622, 0xaaed15ff, 0x9c70b842,
- 0xcf342194, 0x741f9885, 0x41a66678, 0xc31bf387, 0x7f4a6ed0, 0xb0effd0f,
- 0x4eff7e21, 0xfe7dafce, 0x3a0daf3d, 0x3fbe68c4, 0xf80071c6, 0xaf803ae5,
- 0xeac18c12, 0xfb79c08c, 0x62e51e88, 0x48e6e57e, 0x61f30a9f, 0x5a170cbb,
- 0xd6e81ea4, 0x4fa07e11, 0x19e7c20d, 0x46e238ed, 0xd235fefa, 0xd1f88d51,
- 0x5fd15b37, 0xc6acf985, 0x28a2367a, 0x2fdfe711, 0xf505b9d2, 0x18cb4bfc,
- 0x57a5f3f1, 0x4c137798, 0x1d7efb76, 0xd646cbf1, 0x9fbef88f, 0x570cf2ee,
- 0x3af3c924, 0xb9ab3b84, 0xb77a8756, 0x43aed7a7, 0xb9b7da7d, 0x3e23a74e,
- 0x8622ff70, 0x5799e4fc, 0xff5f00f4, 0x37ea556d, 0x686f07e4, 0xaf40ef7e,
- 0x92f481cd, 0x7c16cb78, 0x43788d90, 0xbfaad083, 0xe3f662d0, 0x52c3e80d,
- 0x63fb1d6c, 0xf11d25ac, 0xe9faf8d4, 0x5fd02d5e, 0x67a71bc5, 0xfe2a5e20,
- 0x18262260, 0xd1be87f3, 0xe59fefc8, 0x2e67f684, 0xe872ad2c, 0x257a9fc1,
- 0x85d91ba6, 0x446cd632, 0x6ebca13f, 0xa01f4381, 0x76ffa5cf, 0x8f9cd0c8,
- 0xaa1a1ffd, 0xe78065b2, 0x5de18e2b, 0xd13b0858, 0xbfa12fee, 0x472fb006,
- 0xafcf11d8, 0xff734567, 0x20f646d1, 0xa5a1fdb8, 0x7a631c73, 0xa1dfde74,
- 0xbdd361c1, 0x907e7df0, 0x8634741f, 0x18b6b5db, 0x2141876e, 0x8bce113b,
- 0x3d78b7bf, 0xc8717450, 0xfd0c5147, 0x641f5dcc, 0x2e8f807a, 0xfe47e6b2,
- 0x35767288, 0xf971d692, 0x5cca3f83, 0xe5cbf166, 0xdcf8231d, 0x70ed78ef,
- 0xe7da1d94, 0xe717df6f, 0x1ddfc009, 0x9db57f4c, 0x5c7033af, 0x7d33e346,
- 0x07a42f4b, 0x04d9e3fb, 0xaff9a43b, 0xf9c715bf, 0x74874120, 0xdbf4245e,
- 0xc028b0ef, 0x525fcedf, 0xf3247c41, 0xe6666de5, 0xebc80d8d, 0x04b88d9b,
- 0x648b6f2e, 0x37b7685e, 0x7a4712c6, 0xa3259926, 0x5f14e99e, 0xe0cf8937,
- 0x43cf8972, 0xa3a6cf83, 0x2759f15f, 0x1b6f70fe, 0xf7ced76f, 0xd74fc14b,
- 0x7ceff3fb, 0x0aec3ea5, 0x8d845df1, 0x638ae9d3, 0xf7f41764, 0x1ebe8df2,
- 0xe4ed10d6, 0x4f1832fa, 0x8d2b5f6f, 0xdf7f7ec0, 0x050bca66, 0xfba6de97,
- 0x21ca7e76, 0x1fc02a80, 0x53baa6dc, 0x9c1fc26d, 0xbe8af90c, 0xbad1c657,
- 0xd08bf25a, 0x4f30777b, 0x306fca23, 0xf77a487f, 0xfadd01b0, 0x296672a3,
- 0x318bb748, 0x4237ce76, 0x047ca41e, 0x9d3831e3, 0x50ee6460, 0x62af80eb,
- 0x98c35e24, 0x23e1f407, 0xdf640d1b, 0xf8fb5f0f, 0xf7e04cde, 0xd60c1bd3,
- 0x9ce430e5, 0x3ea5f617, 0x0673f503, 0xe40aac9b, 0x3d7ddb4f, 0x5f4bee50,
- 0x0fc85d50, 0x923c37a7, 0xf3d21330, 0x0065bf20, 0x0346e947, 0xf8d9cf95,
- 0x159f9528, 0x42fa5d72, 0x97d47f7c, 0x4eaff787, 0xf9ce3a40, 0x486989ea,
- 0x6b46ed97, 0x9690c1ff, 0x631c536d, 0x6f3df002, 0xbf269873, 0xe0e6c75d,
- 0x995d243c, 0x47af6ee2, 0xa6d53f13, 0x1f7176fb, 0x04dfd69f, 0xa0aa72ff,
- 0x3029c4e3, 0x57a18aef, 0x77dfafc8, 0xc9ec9c20, 0xf92a919b, 0xffc1be8f,
- 0x20db9def, 0xde95fb9f, 0xa09dbe41, 0x674158f3, 0xb7a45cb0, 0x9f3ccc4b,
- 0xfc9ebafb, 0x4a8b5ccf, 0x91f686f8, 0x7bfea163, 0xf40fbda2, 0x5321ca2c,
- 0x848dd7b3, 0x0da36376, 0xf7d0ed0c, 0x19f2f37c, 0xdb3bc9d8, 0x025bc7f4,
- 0xd59a33e6, 0x387f41f6, 0xca821987, 0xcf2c7a9d, 0xc7cb6b35, 0x2cfbb8f6,
- 0xad630ffa, 0x77c972da, 0xfab4d88f, 0x7381df62, 0xf3009b3f, 0x92a4392b,
- 0x7d237cff, 0xafc22efc, 0x5dbf3a47, 0x3bbe0db8, 0xf872b02c, 0x4915e9da,
- 0x142357c8, 0xd3acf186, 0xe3cb42d7, 0x665ea41f, 0x7e3edf40, 0xe63816fa,
- 0xdc51e7b6, 0xa0b119ef, 0xdff08f3d, 0x7afb1ebc, 0x8d9b753d, 0xed8233c7,
- 0xfcdcb046, 0xfe46ecb7, 0x3dd2b7e0, 0x837f4a16, 0x5ced85e9, 0x89eb06ef,
- 0xe1213b60, 0xbcb7860a, 0x0fb1a74d, 0x191ea15f, 0x8c27681a, 0xc3be2764,
- 0x6d8370f5, 0x30f5c768, 0x2f8431f8, 0xad3d30cf, 0x6adfc1c3, 0x220376c4,
- 0x0039b1ed, 0xb76b0ad2, 0x167fb208, 0x405b7ef7, 0xb6ffaa1c, 0x8dea1d5a,
- 0x418cf8f6, 0xeb91a71b, 0x9d8477d5, 0x1cfa13a8, 0xceb4abd6, 0x4eee18df,
- 0xc9b8e3d4, 0x8c96c746, 0x48f9f88e, 0xcfccefb4, 0xbeac7e95, 0x8fb1fb86,
- 0x389a5d58, 0xa893eb19, 0x5fa2fb89, 0xd9edf28e, 0xfcf34e1b, 0x420d7154,
- 0xe733d439, 0xf4016ddf, 0xf87036a9, 0x8f89e183, 0x319276e5, 0xb207f917,
- 0xd0e8f67c, 0xd5895c7a, 0x679cfb53, 0xff474fef, 0x07c6d3ed, 0x7ebf51d2,
- 0xede7141a, 0x169e1e4c, 0xb0a4faf2, 0x2e223123, 0x11ca14f0, 0x9dda41e4,
- 0x55fbe1db, 0x57245d4b, 0x9d3a5d3f, 0x2e9667d2, 0xb613faa1, 0x9adf1a0c,
- 0x775767f3, 0x35c9d3c0, 0xd989d92a, 0x18af5746, 0x59a4eef8, 0x1385f147,
- 0xbb799155, 0xd19cb122, 0xb3f6727a, 0x0278b613, 0x6c277ee2, 0x6743a27a,
- 0xfd8f8cf3, 0x9cbdfa66, 0xbda144b5, 0x23d7e76a, 0x2db5ec1d, 0xac7fe316,
- 0x55db0125, 0xb6bdcd2a, 0xb7c71d29, 0x2c7c6732, 0xf59197f2, 0x0ba9b947,
- 0xb828f6e7, 0xe72c4a5d, 0x1fa1bfc3, 0x8a7efd0b, 0x9e842b76, 0x2f3a0bb1,
- 0xb1ed38b4, 0xc922efa4, 0x81b8275f, 0x728cbe5f, 0x60b84776, 0xd313d65d,
- 0x7c785d61, 0x2ac5b16e, 0xf0a9c3f8, 0x5fab8e75, 0x5bf8886c, 0x609ef167,
- 0x7811de38, 0xc9038e0d, 0x8681c654, 0xbcf9f2c6, 0xe26ab36d, 0x0eff1842,
- 0x79f9ff15, 0x1ba3d72c, 0x2a3c5bc3, 0x7c03c3ca, 0xdb25de3d, 0x2b7c60a3,
- 0x0736bf25, 0xc5775fe3, 0x2da5b8f2, 0xeb889dcf, 0xa344e4f6, 0x3736e303,
- 0xea038f2b, 0xc05f7c9c, 0xd63823ad, 0x7ac27b37, 0xcd095c01, 0xa4231cee,
- 0x0d317153, 0xaac2edf8, 0xa0dd2196, 0x6b23211d, 0x9157b87f, 0x92686c8b,
- 0x4028f429, 0x6772861a, 0x454f728c, 0x559b0cba, 0xfa718d55, 0xffbe3294,
- 0x77715670, 0x9c9f01b5, 0xa43c2b7d, 0xe8225c3f, 0xc9d194cf, 0x36b3fa68,
- 0xacae081b, 0x819f3fcd, 0xf9b59f7c, 0xa012bd2e, 0x1ac79687, 0xdf67fe68,
- 0xe295d79a, 0x58989f16, 0xea7a10cf, 0x1e5f8287, 0x69d87410, 0x8b7fcd0c,
- 0xac6fbb45, 0x55405bcf, 0xe2f9f569, 0x5b3880d8, 0xd265f945, 0xed6393e7,
- 0xfaf3ce34, 0x80c903ba, 0x3167e7cf, 0xe68a0787, 0xf148dd6d, 0xbac69dd7,
- 0xe4efb8f1, 0xa431d0a9, 0x7f03fefb, 0x7e8c9038, 0x60fb2ce4, 0xbfda23f4,
- 0x4ad2f43f, 0x0e7e7f2c, 0x4ff88c1b, 0x60ad3ef2, 0x619fe63c, 0x7faf84b5,
- 0x65b1316e, 0xbf7db718, 0x210ffc6e, 0xc74cbebf, 0xcf04bf50, 0xe832461b,
- 0x19f53112, 0xfd382374, 0xba4a0f51, 0x91190303, 0x886e921e, 0xee90edbf,
- 0xc11af2df, 0x2a9ae12f, 0xb6f3dee2, 0x7c8f1f6e, 0x53665c92, 0xe1204e30,
- 0x793d91ba, 0xd9dbf631, 0x0ed0ef93, 0x221b12bf, 0x0ec21d2e, 0x610d88ef,
- 0x2fed8387, 0x637738b3, 0xe1d91bbb, 0x36ff82e1, 0x7fed06c6, 0x08597ee0,
- 0xed8d0dba, 0x1fdf0f10, 0xe3ff621b, 0xdef0f146, 0x43ff72b1, 0xc97f0f1b,
- 0xad6ff5c8, 0x293c3d8d, 0x1374bc84, 0xb5d6ebe3, 0xc67ed11a, 0xf5212835,
- 0x518b62d9, 0x1c7e1fee, 0x125fb01b, 0xe0438fac, 0xefb628f7, 0x17b7cdbb,
- 0xe9890d5b, 0x5bee8111, 0xdeb0ebbf, 0x29ce310d, 0x22fb3f81, 0xf6a6fb46,
- 0x0afa462a, 0x141e5ef2, 0x371429f4, 0x934f38b0, 0xbec1badd, 0x1cd69dd5,
- 0x3ee483f2, 0xd6ab54d5, 0x938b8c4f, 0x239f9ced, 0xd89d699c, 0x3c097f89,
- 0x70dbfcc1, 0x4c45b8dc, 0xf7231fb3, 0x3caae261, 0xcd0b318a, 0x6af8a311,
- 0x32f758d7, 0x1d6bb403, 0x209b1cc9, 0xcd685d1f, 0x9b6a7d41, 0xfdc468e3,
- 0x7917959a, 0x02e57e3c, 0xfd4e5de6, 0x7732f9f0, 0x17ca2f37, 0x2e302dd2,
- 0xe1c71110, 0x72e38888, 0x1cd27606, 0x8f0ae1c7, 0x9293b00b, 0x3e75ba1e,
- 0x1adae895, 0xd0054eda, 0x77df46d5, 0x50efd742, 0x3771ed2e, 0x8cf71fe7,
- 0x19be05bb, 0x7c737718, 0x4b4c14f3, 0x8f04dfec, 0x0ff38997, 0x2cf80f1e,
- 0xf826ee2b, 0xee2deaec, 0x50881e8f, 0xa5dc5dbe, 0xc4275e23, 0x6b77d085,
- 0x487d75f2, 0x4770b35f, 0x233abb28, 0x7dbff22e, 0xa086645e, 0x179d2df7,
- 0x2d27f179, 0xdcb3a446, 0x06f090f7, 0xe591139f, 0x264a0d15, 0xf6733fae,
- 0xc075a35d, 0xd37fc6a5, 0x79e3a03a, 0x42ee3e0f, 0x678003e4, 0xcea03aac,
- 0x7977f207, 0xea56919b, 0x22ffb32a, 0x4df6e31b, 0x53b5e606, 0xefb6337b,
- 0x7efb78c7, 0x633656db, 0xd31faadc, 0x547ac47b, 0xa8fdceb9, 0x7ee39468,
- 0x8d5b2a4d, 0xbebcadf9, 0x6197998a, 0x847a3a5c, 0xf003d98e, 0x670ce319,
- 0xc67c00f6, 0x7934d9e6, 0x2f9e4eb9, 0x25778dc6, 0x32efbe6b, 0x7da69bbd,
- 0xa69fbb92, 0x10ce653e, 0x6aad3e4d, 0x577da694, 0xf981cfb0, 0x9addcf0c,
- 0x266bddf6, 0x6b3df26b, 0x3fb4d01f, 0xcd9eaacd, 0x9c7a79c6, 0xce003dcd,
- 0xdece0259, 0xdf358beb, 0x0dd5d7f5, 0xf920a1f3, 0xffee1f14, 0x326c16cd,
- 0xfa73c44b, 0xfa69e77a, 0x5e6aff3d, 0x9df80293, 0x19386b5d, 0x7c219f18,
- 0xea4b7e00, 0x8c1cf615, 0x5b5eba5b, 0xe9e1a73f, 0xce902995, 0xe7cb6af5,
- 0x829cbee1, 0xdf2dadfc, 0x823d73ad, 0x71ed9deb, 0xe228ce22, 0x7f03ac3d,
- 0x97b8d244, 0x9778f037, 0xc41de9ea, 0xb13a5a1f, 0x762fc96f, 0x44a62fc1,
- 0xd984bf2d, 0x7a52fcb5, 0x1f30e770, 0x88ff88eb, 0xe47c413e, 0x78017f81,
- 0xf895f897, 0x7cb438b7, 0x9de15df5, 0xdb91af31, 0x3ff96d0d, 0xb5f1b4e2,
- 0xe3ee917e, 0xd4aeb7a8, 0xbf71522f, 0x7df1e58d, 0x57f52bfb, 0x6bb21d07,
- 0xdb3ad7f6, 0x17173a4f, 0xfb175718, 0x3f709749, 0x137636f1, 0xfefb89fb,
- 0xd900f885, 0x1f801b77, 0xb98708d8, 0xcc30ff7d, 0xac147fbf, 0x760a6537,
- 0xb238cbe3, 0xd77dfe27, 0x587af86a, 0x085c5ff4, 0x9387dcaf, 0xf9e472e7,
- 0xe7c91621, 0x3c01fb29, 0xf143f1a8, 0x022d9ffc, 0xf7dbadd7, 0x96f5a42f,
- 0xc4c43f3c, 0x7e10bfb9, 0x3aefe93f, 0xfc8935fc, 0x6e78f081, 0x6d3123cf,
- 0xf9c407f7, 0x3bcf692e, 0xb7ee47eb, 0x7b2a9675, 0x6c3fda55, 0x9b1dc255,
- 0x5e93d842, 0xfd72dff1, 0x1c43a675, 0xe07c57ba, 0x2bd1ebfa, 0x00aed007,
- 0xb962fbde, 0x5af602c5, 0x5febdbf1, 0xbf114444, 0xbd541eb6, 0xb2e0a1bd,
- 0x036d1ed9, 0x6984363c, 0xab4c88ed, 0xf403c9cc, 0x3daf58b1, 0x11f727e7,
- 0x6367db83, 0x27fd80fb, 0x8fe34ef8, 0xfdc21cac, 0x6e78ecb5, 0xe488bfdf,
- 0x9114c1fe, 0x175a0caf, 0xbf70d655, 0xe9f8236c, 0x4cfd010d, 0xfb50b789,
- 0x533911a5, 0xc08e29e2, 0x332bbbd7, 0x5627f214, 0x21f90a2a, 0x5347a267,
- 0x9cb8b5fd, 0x623fc4c9, 0xbbe8299c, 0x6edaffc1, 0x38bb1e1c, 0x37fb238f,
- 0xe6f6f3c7, 0x4e94d1f8, 0xb88ab789, 0xf21fb5b3, 0x93846547, 0xa1aa35fa,
- 0xc7a6a5f7, 0xb5ad79f3, 0x6a27e930, 0x84e3fee2, 0xbf38c4de, 0xf9a3fb89,
- 0x71fc1363, 0x7f66a67e, 0xf1138c68, 0x773e857d, 0x53ba9ea2, 0x78b3bdd0,
- 0x758fb3bf, 0x75276e3f, 0x12fbf78c, 0x1dfbc643, 0x0fde28e3, 0x5e71ea5f,
- 0xa47f71c1, 0x2fcd8443, 0xb7c48f3f, 0xd45483db, 0x7746f54f, 0x5abbae35,
- 0x0eff8377, 0x2dbc7dc5, 0xf0301fb4, 0xae077750, 0xb06656af, 0xb7e416bd,
- 0x7fa18c65, 0x5ba2df5f, 0x6bf5061e, 0xf58acc3c, 0x75f03723, 0xbb7ae95b,
- 0x8069a703, 0x8865b075, 0x8bac1f5f, 0xd7bc218f, 0xc46e4cb7, 0xf73581fd,
- 0xa19a1b32, 0x1b9b565a, 0x06d0fe85, 0xf8dd7216, 0x09b39094, 0xd4557b39,
- 0xdfe8f117, 0x53d3a087, 0x0fa04e82, 0x879d22d6, 0xf0afbab7, 0x4fae38fd,
- 0xfae22548, 0x1bcebf74, 0x373f3d6a, 0xf21d773a, 0xe86f40c1, 0x0b5ac3f5,
- 0x1175b7e7, 0xdda8e7ae, 0xb5ee7e2e, 0x59dfea54, 0xba07a63a, 0x9d74114f,
- 0xdf9f81b2, 0x5faed760, 0xc89fa557, 0x7a867fa8, 0x8b5ef4a5, 0xa543e317,
- 0x821e190d, 0x7a38a5cb, 0x7868bea2, 0xd2f985df, 0xc62b2cac, 0x657f9c23,
- 0xe43ea9ca, 0xbfae3262, 0xd494ecf4, 0xe3c76427, 0xb269df68, 0x16b5b7e0,
- 0x0d473f3b, 0xfc008e28, 0xb6586e97, 0x7cefcf17, 0xfb466bf4, 0xd6d4474b,
- 0x54d9d861, 0x2192ce40, 0x2159ea98, 0xfef82bc5, 0x1fa2bdd5, 0x5c61bfcf,
- 0xa9dc7fb3, 0x3e69070d, 0x63cc0c47, 0xb4ba3e06, 0xfa3b3ee7, 0xcde32bdb,
- 0xfb93c714, 0xf75547b2, 0xf48464e3, 0xda0815ad, 0x56110dfd, 0x43fc7f8c,
- 0x82465df0, 0xc7d21f7b, 0x057c7cbd, 0x6596c1da, 0xa3c474a6, 0x1a92797b,
- 0xd7ba7007, 0xd1ef342a, 0x788c93cb, 0x8ae6617e, 0x4f50e3c1, 0x95ce610d,
- 0x2879df18, 0xd3948596, 0x9d7cf1f3, 0x60655c58, 0x849a68c6, 0x172fe311,
- 0xbf8a146b, 0x015bfee0, 0x988e67d0, 0xf7aaf95f, 0xec3f88a3, 0x1e186ff0,
- 0x733fe5cb, 0x1e494aaa, 0xe46bcec1, 0x19d58ca7, 0x799fa093, 0xdb39606b,
- 0xf1fdec8d, 0xc043fe0e, 0x3af2ef79, 0x5b257d6d, 0x7f9d39f3, 0x5befe061,
- 0xeb682ed0, 0xe8f2953f, 0xaba40e60, 0x8cc5b17b, 0x0b4684e7, 0x51ad14bc,
- 0x665fa8ac, 0xbf8c68ae, 0x9b33f20f, 0xb4f20754, 0xe8eb0bc4, 0x8f39d3ef,
- 0x693d4dcb, 0x6ed9703d, 0xdced82ef, 0x2bff5c51, 0x2c70f77a, 0x3dd6287f,
- 0xadf1d71c, 0x9e18589f, 0x06d6399b, 0x1ec618fe, 0xc5106ccd, 0xd06cac1f,
- 0x5a3b00a4, 0x6026b064, 0x16c3dfbc, 0xb7be3226, 0x779c0e65, 0xf90d79a5,
- 0x07e89581, 0x1f91f9f2, 0x672c50f8, 0x15d7d6d5, 0xeac39f3a, 0x9a07e40d,
- 0xd6781f85, 0xae009b5e, 0x6e3d7317, 0xde2d3920, 0x687e4316, 0x235c8af1,
- 0xaef16ff2, 0xe043d218, 0x63d87e07, 0xc78e9f98, 0x481e6456, 0xeb8b7e84,
- 0x96aa1c32, 0xb8ff5a7e, 0x5ba498e6, 0x4b4fbf47, 0xe8a193b7, 0x94d2f406,
- 0xff0824a7, 0x3d8bd04e, 0x477e4b16, 0x7ab782e1, 0xcb9e019a, 0xee746155,
- 0x83ff33a8, 0xbed1c6a5, 0xe6175c9e, 0xdfafb725, 0xcafcdf68, 0xb744a19a,
- 0xfde57a60, 0xb470e667, 0x16afec27, 0xa1ec7a86, 0xc9e1ecee, 0xc2b0fe50,
- 0xeaa1ebe5, 0xa72879f1, 0x6f5c0959, 0x6614b7be, 0xfdec6468, 0xece666a5,
- 0x4b07d8c5, 0x68ff94ad, 0x3fe52269, 0xf4a76a5e, 0x287da593, 0x68e2293d,
- 0x0180ce52, 0x25475f88, 0x951af970, 0x6cdee220, 0x8caa2251, 0x307cffbc,
- 0xa1c56754, 0x4d8c27d2, 0x271eec63, 0xdfc02320, 0x046f7e99, 0xdf3db912,
- 0x4b8eb062, 0x9571ff44, 0xd8befa42, 0x3da6bb75, 0x3c4625f8, 0x64facdff,
- 0x9ce9cbfa, 0x1938dd98, 0xfcfef0f8, 0x69fb4d58, 0xfc9a2935, 0xcd3b04e4,
- 0x775e527b, 0x8503f94d, 0xa2f935fd, 0x9e024036, 0xf8db302f, 0xb7d8aafe,
- 0xd7c6cc67, 0xf6de56eb, 0x2ef0d56a, 0xaf7807df, 0x7d50321e, 0x5d243d30,
- 0x31d7ad67, 0x73368037, 0xfa0dcc3d, 0x933b593d, 0x11fceae4, 0x95fdd90b,
- 0x1ddf32db, 0xdb63f901, 0x7ebfb40c, 0x5aec456c, 0xb63e3fdc, 0x418a3e2d,
- 0x32a95eea, 0x7ac1fa1f, 0xe80591ab, 0xcb15dcb7, 0x9156fce8, 0xf940e4d7,
- 0xf9efda2f, 0xd1dbcc95, 0x5120441f, 0xbd543e3e, 0xe7e8853e, 0x14befc24,
- 0xf902dde6, 0xf1afa033, 0x16ccf8c8, 0x8519d70e, 0xd9fcc0ad, 0xfaf5bfb0,
- 0xb171c03e, 0x8744b6a0, 0x50f501eb, 0x1dcbe93c, 0x2dbe432a, 0xfda0605c,
- 0xa91fb9bb, 0x94cf311b, 0xde9c2921, 0x64479d2a, 0x7fa8992f, 0x021c0ad6,
- 0xd6fd16ed, 0x77d689b4, 0x0f77e44c, 0xfc16aef4, 0x26747c89, 0x08633986,
- 0x3de08558, 0x46fc7ef7, 0xd3e3f7ac, 0xfde7083b, 0x32b5dea5, 0x5cebf801,
- 0xe9107789, 0x49e2c7b5, 0x7ef182ae, 0x96f5c8d2, 0xf140e507, 0x9cbf4beb,
- 0x9d3e272d, 0x38247069, 0x25655f48, 0xb93abea1, 0x98e740c6, 0x3519de99,
- 0x3b3fd689, 0x38e58f88, 0x71f6f527, 0x9ac9df08, 0x96fb860c, 0xf2546bc5,
- 0x78ff9007, 0xffe72f7b, 0x1b3755a7, 0x28d6fd0e, 0x23a5d66e, 0x60b23cdf,
- 0x9a639d38, 0xc141d621, 0x9033e07a, 0x7f2f7755, 0x7e1ede7e, 0xb56586ce,
- 0x181defe8, 0x7c158f38, 0xbfde44bc, 0xd650073c, 0xd1474fed, 0xd4dcbee5,
- 0xf0ed1a3d, 0xe2550fd9, 0x6addb3b3, 0x3d022587, 0x0ef6e82f, 0xcfe43efb,
- 0xe94e7817, 0xb854ff21, 0xae02677b, 0xd26b7457, 0x3e786e95, 0xdbdac4f6,
- 0xaf73bbe1, 0xe6241c18, 0x7f49e24b, 0x6e697bcc, 0x8ef3c0d7, 0x2f97f51d,
- 0x38bfef99, 0xe7c01493, 0x38dd7b7c, 0x775c00eb, 0xe21d84bb, 0xe6e3b1f8,
- 0xbac5e02a, 0xc343c14e, 0xcb50c4ec, 0x3d773c6a, 0x3024c413, 0xec42784e,
- 0x7a101f8f, 0x1109fa45, 0xa67e785d, 0x7b37f38e, 0x0dbf2155, 0xbffa347e,
- 0x944f9c52, 0xebea5f7a, 0xfb4b5632, 0xf81247c1, 0x8ab9c639, 0xe055da97,
- 0xa8a82ece, 0x420f2b12, 0x79356d97, 0x97d419bd, 0x480fd035, 0xfbe762ee,
- 0x9e57c643, 0x652db645, 0x417e7ccd, 0xbc19ceed, 0x1d19cd25, 0x75894ded,
- 0xf51b0ae3, 0xfc60706f, 0x69c854a4, 0xf5e2ad79, 0xdd9079f1, 0xd98af194,
- 0xdb066ec2, 0x28f60ea7, 0x0ecd0ec8, 0x56acb3b2, 0xde01576b, 0xc2471c48,
- 0x2ba70c1b, 0x987842c2, 0xbda17007, 0x0f7b712d, 0x15b8244c, 0x03b25007,
- 0x35cca53c, 0x01e70626, 0x477b3ef5, 0xd5e782f8, 0xcf315e01, 0x1c4bb860,
- 0xff70fb9f, 0x5187cf18, 0x1e6829bc, 0xfec11e92, 0x894ba49a, 0xa4b7e387,
- 0x7e7a2141, 0x3207eeda, 0x7e491b8a, 0x9d500581, 0x44d77bf6, 0xeba567d4,
- 0xf866ff40, 0xd3f247f9, 0x8517563c, 0x7cc152fc, 0xbe50932b, 0x46d3757c,
- 0xe1bedfa2, 0x49ca237d, 0x53d7cda1, 0x5c288317, 0xb4bcd3fb, 0x1044f580,
- 0xd7446f9e, 0x9c378a6f, 0xbdc65e95, 0x37b34f00, 0x41b0ceab, 0x1ce2769a,
- 0x60e48791, 0xc463c78e, 0xb11cc6f8, 0x9c11bfee, 0x6e7e7a95, 0x76f086fc,
- 0x5b7d27e2, 0x68baf3b8, 0x9fbf62fd, 0x943a33d5, 0xaff76a9e, 0xdffaec82,
- 0x217e3c0c, 0xbd55f1f5, 0x5025e293, 0x2aaefc2e, 0x079b8f2b, 0x2cb4f1e9,
- 0xc225e3d2, 0x4e71cbae, 0xf149dfad, 0xf768d9b7, 0x5d3fca03, 0xfee293b7,
- 0x476657c6, 0x6a7dffa1, 0x78b5ccfd, 0xb6d4ebbe, 0x4be76499, 0xde76939f,
- 0x1ff40c6d, 0xbd17d772, 0xdfe463f8, 0x9f1461ad, 0x16efd92f, 0xabd01eeb,
- 0x9ebeced0, 0x8eb651eb, 0xb452d5eb, 0x1ec80387, 0x8b76c6f6, 0x51bddc4b,
- 0xc9ca020e, 0xe99e2e4e, 0xe81eddfe, 0x11cbf177, 0xc2a10f0e, 0xdf91d3ea,
- 0x3da1f56e, 0xf1f85f2c, 0x0ee73c51, 0x1fa3fff6, 0xd90ffb48, 0x92f77a8d,
- 0xc26f282e, 0x1bab97ee, 0x27e8add3, 0x5ff13b08, 0x3439bfc0, 0xfe1087fe,
- 0x01ff118b, 0x6bc720fb, 0x06679e38, 0x1ac4ffe1, 0xdb95974e, 0xfae147ba,
- 0x774d78f1, 0x6f8eb3f2, 0x9ff849eb, 0xcff01ab5, 0x3f5a5fe3, 0x8ff006ab,
- 0x3fc408eb, 0xdfbc5bc0, 0xe0eff02e, 0x78e1aff8, 0x3a786b67, 0x3d9e03ab,
- 0xf1618e74, 0xf40e4daf, 0xf984ce1b, 0xb33a9fc8, 0x01d5655d, 0x83f4987e,
- 0xbfb560be, 0xe24d7f42, 0xe6af6e7f, 0x0a7fa841, 0x1453fe9f, 0x76ee61d2,
- 0x80efa41e, 0x82ece67f, 0xfc7fb8fe, 0x95e9bf76, 0x7e01f12e, 0xa9d24dd3,
- 0xd918b982, 0x1d3f86c5, 0xe28375c1, 0x786d4f84, 0xd7dc468f, 0xd7ded7a8,
- 0x851933c0, 0x382f8c36, 0x278466cc, 0x8a1ef835, 0xf91c619b, 0x9f3f3d9f,
- 0xbce490b1, 0x6dbe7355, 0xba19f322, 0xa758ffa0, 0xf2c6fdd0, 0x39513945,
- 0x55d4e30c, 0x2ee9c704, 0x78fce68a, 0xff23aab9, 0xfdc8ccb1, 0xf93fb948,
- 0xde0ff0ae, 0x25d7c2ed, 0xd2b175ef, 0x18c29777, 0x164b81d9, 0x23ef17a3,
- 0x112a7ac0, 0x31ecf7c7, 0x228edd11, 0xd57f804c, 0x6036e228, 0x1f4f9102,
- 0x1f4f9c64, 0x38a26c8c, 0x5e54ac39, 0xd0f8bb40, 0xfc839312, 0x8a68b8da,
- 0xf4203ed7, 0x2b9183dd, 0x1e1f685d, 0x313a348a, 0x783d7e85, 0x1a30ce88,
- 0x0df18786, 0xafba46c9, 0x796e6853, 0x0fbe9705, 0xd4789e27, 0x06dea00c,
- 0x55c637ee, 0xd75dd7e0, 0xc5d23b63, 0x9c6d1f4f, 0x743c32a7, 0xe055a3dc,
- 0x293a714b, 0xbe82639e, 0x2b8e01c3, 0xdcb12f68, 0x9df1e56e, 0x8b27400d,
- 0xe5c1be9f, 0x03f7c3cc, 0xe35cf0ca, 0x6419c628, 0x935fe104, 0xfaf2332f,
- 0x26afc4f0, 0xec66cbac, 0x103ecccf, 0x3a8656e9, 0x45f7d704, 0x978c5ed1,
- 0x25f183df, 0xe27aa61b, 0xe67ac997, 0x26b4f1d1, 0x89cccf12, 0x8144d378,
- 0x9823a9cf, 0xeef01a2f, 0x778da83b, 0xf9d3e7dd, 0xef7e037a, 0x911afbd1,
- 0xbb66753f, 0xb8e30ac1, 0xb82194f2, 0x7e5b292e, 0x25a6f073, 0xa5d7f39a,
- 0xcfc75e42, 0x80feb585, 0x041e21c7, 0xcdbc4561, 0xeafdb3d0, 0x8807ce10,
- 0xdd9b4a97, 0x2816ed43, 0x71950f14, 0xc1ff4936, 0x1d207dd0, 0x41f0141f,
- 0xf851353f, 0xbd3431bd, 0xf5ca26fa, 0xabad1d73, 0x9bb90be7, 0x9b6de52f,
- 0x27c6de56, 0x82bda9da, 0xede0307e, 0x26769141, 0xff44e317, 0x5cb912e3,
- 0x78e2dd64, 0x9d35b22c, 0x7908b7ce, 0xfef13729, 0x88f7f8e5, 0x8da24c74,
- 0x00f095fa, 0x7ec71ebf, 0x9001a074, 0x56d64f5f, 0x87347f93, 0x33b5c405,
- 0x5f24edfc, 0xebb7cc77, 0x4c75dd11, 0x10b3ad8d, 0xc2f7caf5, 0x1f47a81c,
- 0xacf5d634, 0x4ed8ec8a, 0xb214dbee, 0x3d230366, 0xc261e229, 0x23558cfe,
- 0xa1407ce9, 0x5e0fefc2, 0x7478b1ca, 0x31a718d1, 0x630b6910, 0xf13f3a14,
- 0xf27fb137, 0x89e2f450, 0x5185d728, 0x33a63d46, 0xfbf52b58, 0xe8b76b77,
- 0x33de18fb, 0x0e763156, 0x77c88f03, 0xa8d5b8c2, 0x8d7e7877, 0x4aa29b33,
- 0x21c77f22, 0xdee1e027, 0xca7f406b, 0x09df2f7f, 0x4b7a5ffd, 0xe93bb3d4,
- 0x0b8f4bfb, 0xf2e4f63e, 0x7d65cffc, 0x92afcf1e, 0xff3cf9f5, 0xe45feca4,
- 0x5faa0e9f, 0x4bff5416, 0x3ebc5f9e, 0x7e83df3f, 0xd2ce68eb, 0xd214a385,
- 0xbe847b53, 0x23ee5c28, 0xf6ea16fc, 0xf33474f2, 0xdc6eb2e9, 0x6ba2536e,
- 0xd51fda0f, 0xf682d272, 0x2764d5f7, 0x704f9fe5, 0x75c44b2f, 0x63c524d4,
- 0xa1fb7d44, 0xc4c1ec97, 0xed1fce4e, 0xf8e3c2e9, 0xbfa0929b, 0x05fb7ea1,
- 0x8c4eacfd, 0x1c7ef5bf, 0x80ae1c49, 0x26f99e7e, 0x23a7fcf0, 0x49be1b3c,
- 0xb592b33f, 0x487f48fd, 0x86be7549, 0xe32763f3, 0xe645e734, 0x8d11c4ff,
- 0xe78627f1, 0xf3f50045, 0x67a5d797, 0x5ff3ff42, 0x04bd3d7d, 0xe76125fd,
- 0xcc74da2b, 0xdb34f789, 0x1be7a518, 0x7de2313f, 0x8d5d8ab3, 0xaed071c6,
- 0x00dcd212, 0x9c04cab8, 0x93f4e760, 0x8373ec03, 0x3d8c1bd0, 0x5f37f7cd,
- 0x7a47ab3d, 0x9dd5d7ce, 0xf6ed0e7a, 0x3ee42528, 0xddf166cd, 0x17ce4ed1,
- 0xe87a15ef, 0x11b39a6a, 0x8c6bf9e7, 0xb73e4021, 0x60fb93ba, 0x855f1c49,
- 0x1ccdeec2, 0x01db3166, 0xe43f43cf, 0x1b2554fb, 0x3c608632, 0xd184cdf8,
- 0x6d7e24ef, 0xc795b53c, 0x3c781b53, 0xbcd6d0b5, 0x33379408, 0x31ad9526,
- 0x84d8c1df, 0x0339485f, 0xf36f8591, 0x9d5f324c, 0xc79b263f, 0x767f30bb,
- 0x506b63fd, 0xb9c29a6e, 0xf0d0fb1f, 0x17a8e181, 0x7422325a, 0x37e79056,
- 0x498c8be3, 0x8efcb143, 0x639e5871, 0x222af4b2, 0x8be232fc, 0xc75de337,
- 0x3db05f90, 0x46dc41c6, 0x307dfc5f, 0x2adbf70f, 0x0f75a79d, 0xda87708a,
- 0xc087fa77, 0x4ac931ab, 0x19901369, 0x870917fd, 0xf9fc1f1c, 0xdfd0cd45,
- 0x8349e5c9, 0x9f71db57, 0x3490c725, 0x467e3fd4, 0xe072fb82, 0xac7527f8,
- 0x6e292e17, 0x024b8e16, 0x5dee030e, 0xd95dbe03, 0xac06732a, 0x898f26f3,
- 0xcdefe4d0, 0xc0ce658f, 0x29bded38, 0xc2f4fc9a, 0x0ff69aee, 0xa9afeacc,
- 0x6735302f, 0xb1f80555, 0x1e49fb9d, 0x62d2a782, 0xee7f4709, 0xfc5f0def,
- 0xfff441e5, 0xf40eab36, 0xd9eee755, 0xa1db97f2, 0x4e3c65d5, 0x3b47f145,
- 0xc9cecbc5, 0xa77a28f3, 0xe85f703e, 0xf3a66b22, 0x03ed9d3e, 0x7cee75c9,
- 0x773a7eeb, 0x03ef5df6, 0xeb124af5, 0x086c21dd, 0x55cbc3da, 0xaebc511f,
- 0xefcf9222, 0x8cc7ebe2, 0xfb8a0fb8, 0xdf81d78a, 0xd10fc2ef, 0x50f36c3f,
- 0xfeb73b3c, 0x1d9bed18, 0xba7ae448, 0x1e817522, 0x42551def, 0x1c68768a,
- 0xe068abe8, 0x3646e697, 0xbbee1770, 0x1fb85866, 0xb19936de, 0x1e2be458,
- 0x884a69df, 0xf3d77ba1, 0xbca8f26b, 0xfa9c2da2, 0x1e6d4f7f, 0x5f09e747,
- 0xa1ff6853, 0xe5a1e520, 0x29b87e78, 0x11e033dc, 0x77e0b718, 0xde21e577,
- 0xf3f1762a, 0x9fea05b5, 0x5a4016b3, 0xdf479b56, 0x49aca817, 0x42617f01,
- 0x05bfb72e, 0xaf21f368, 0x46acb30e, 0x7d1aabbb, 0x3d479ebd, 0x9e90b463,
- 0x807b6e89, 0x336cafc6, 0x24f7f7d3, 0xd0d77f71, 0xdb1ae1c2, 0xc972a2e6,
- 0xba93530f, 0x860fd669, 0x7c7acdf8, 0xc2d0c397, 0x6dddfda8, 0xf39528fd,
- 0xafcfbb7d, 0x21ae3ee9, 0x14b8eafe, 0x71dbf798, 0x90dc958a, 0xa57c3d20,
- 0x0b34786a, 0xc7daa7a1, 0xf4e7e369, 0xdcfc6d4c, 0x738a615e, 0x31c0127e,
- 0x3d16b1f1, 0x48b107ee, 0x35f115b3, 0x7b60c471, 0xa97c8049, 0x2237ef7b,
- 0xdeeb0c7d, 0x369da237, 0x501b9a41, 0x33ce2e5f, 0x05e9eb04, 0x2f4f5249,
- 0x1dda54a3, 0xf9067576, 0x82ac33a9, 0xccfc8501, 0x7e54fa10, 0x1a6b4cdf,
- 0x1e6ee3a0, 0xc5347fc7, 0x45f502bd, 0xbe9b0e73, 0x7366f483, 0x7cc3ee3a,
- 0x9d03f057, 0x89f90acd, 0x751e742d, 0x0ebb08e2, 0x04abffe3, 0x6f8e525c,
- 0xa2c58f34, 0x5b2a7bfd, 0x77befd82, 0x4ecd9de7, 0x47f1afe8, 0x0f689999,
- 0x25cfb8e4, 0xcc297bf1, 0xd70d7ada, 0x446f9583, 0x0bde51d8, 0xfb863170,
- 0xb44c7b9d, 0xda72814e, 0xc37ca8cf, 0x89ef09b4, 0x7ac14654, 0x7dcfc615,
- 0x7c87cc33, 0x9866f8dc, 0xef46ed1e, 0x4873f774, 0x7b37dccf, 0xa1f5c18f,
- 0x67a4c1b3, 0x9f38f7e4, 0x09db3d27, 0x5bd237bc, 0xe5267cc1, 0xe5c35dd3,
- 0x69f048a5, 0xb73f90b1, 0x552ba390, 0xaf0e485d, 0xe340063c, 0xca63e93e,
- 0x27e85dc0, 0x7ef42dd8, 0x02cb9493, 0x79410f5c, 0x3a18ff41, 0x8dfd2bff,
- 0x6b2c3960, 0xe5bf52b3, 0xef21766d, 0xb94bca36, 0x6372162b, 0x2cc67e12,
- 0x53bbe7c1, 0x5e20efdc, 0xee41aa0a, 0x3f1f68a3, 0xcfc9e50b, 0xf22b4637,
- 0x624df017, 0x54fc8049, 0xd0cfde37, 0xb9c5313f, 0x41666f88, 0xcc9fe81a,
- 0xac4ff76e, 0xfe0012e3, 0x74322b89, 0x9da9df78, 0xe6f9db7f, 0x8f7ff8e6,
- 0x48e29790, 0x67f44f5f, 0x0e61550d, 0x397e873c, 0x2cf7ef8e, 0xb8f1c55c,
- 0x45cae0d0, 0x2fe162ff, 0xa1978a15, 0x697a81df, 0x632a91d8, 0xfee51c60,
- 0x0ecc41b6, 0xd6d29878, 0x1337d283, 0x0f1147dc, 0x04d36d45, 0xa37d06be,
- 0x4ea1c5fd, 0x7832471e, 0x198d8e4d, 0xab724718, 0x6933e748, 0xe04cfacc,
- 0x1d7ade7e, 0xbee4c3c5, 0x992b8ca3, 0x807cbcf0, 0x5f42fd1d, 0x37ef4e9b,
- 0x7299c704, 0xb0bfddb8, 0xbf7640d9, 0xc3cff1ac, 0x2e7f5074, 0xed05d9c3,
- 0x777a97c9, 0xbcf5f21b, 0x0d57dec9, 0xe4ff9f90, 0x7691a8ce, 0xf4eb3e3f,
- 0x47689ebe, 0x188f00eb, 0xa35baaef, 0xbfb979e6, 0xc9f7c113, 0x7e4b7f38,
- 0x79f3e60e, 0x9f88dd6d, 0xc89954ae, 0xbe015d0e, 0x48760165, 0xe7a91dda,
- 0x7c91fda5, 0xfae7ae5d, 0xda323cab, 0xb408c9eb, 0x395c933b, 0xf87d77c8,
- 0xddbf1a79, 0x1476b4d9, 0x38a5c1ca, 0xed28b73a, 0xbc1cb046, 0xd31c14b6,
- 0x8eed1d5e, 0xcf52ebd4, 0xfa35bb4b, 0xfe772fe5, 0x8a55cd15, 0xe032407b,
- 0xb73d6eeb, 0x2deb775f, 0xe3633fc4, 0x6f91e926, 0x1e8f5e6e, 0x98f47a13,
- 0x74568f46, 0x27060762, 0x741c9adf, 0x4cf3ed15, 0x3d447fdc, 0xa3dfd81f,
- 0xe0c7a329, 0x7327c63c, 0xc15dfb3b, 0x1ffe99dd, 0xfa6b7c9f, 0x88b2587f,
- 0xff40ddf7, 0xfd732617, 0x99efac1f, 0x73a7bf95, 0x2f5f4f69, 0x0ca383da,
- 0xc1da03ec, 0x16fb0886, 0x5ec80f61, 0xbf7b4784, 0x4d5c1ece, 0x7888599b,
- 0x1e0f610a, 0xf616fe4a, 0x94a1f240, 0x5227291b, 0x48e5822e, 0x9f84c5ca,
- 0xe9113ac2, 0x57bf1ef4, 0x6cf7ae50, 0x7b46fda3, 0xcf9460c4, 0x976e3f76,
- 0xc1d6f242, 0xf1f9084e, 0x6ed68bcb, 0xf290b948, 0x5ca7e522, 0x20ecc5c8,
- 0xd6a7d8b9, 0xf70a333d, 0x6bdd92cb, 0x72fde393, 0xd823b652, 0x57ca743e,
- 0xb3645918, 0xf218aae3, 0x81a43955, 0x44ea657c, 0xbe499e1e, 0xd968bf35,
- 0x6fd3f24d, 0xf4fcfbfe, 0xe9f84e9b, 0x3f0dbe7f, 0x3f63f475, 0x3c03b2ce,
- 0xdf40b257, 0x6df9f866, 0xfb8c3bc2, 0x7af9dd0f, 0x0497d600, 0x8d319377,
- 0xae133ee2, 0x2f8a2ab3, 0x7494be0a, 0x6cc0fe96, 0x93387711, 0xe1077ae2,
- 0x82c0f5c5, 0x447bd39b, 0xb35c5367, 0xb327d711, 0x03f40d21, 0x9b7ff33a,
- 0xbdef516f, 0x3e749371, 0xfb9dfc96, 0x4392c78d, 0xb1c78dfb, 0xb5d29bfc,
- 0xf8899720, 0x300b8fde, 0x29e138de, 0x0acb6791, 0x46d38f10, 0x3c9ffac8,
- 0xfa81ece9, 0x38b8c981, 0x53de39c5, 0xf4b3de45, 0x3f6818f0, 0x8fe619e1,
- 0xd8fd439b, 0xb8f6e8ec, 0xedfcc288, 0x3b1fe795, 0x51e886bc, 0xddcce5cb,
- 0x3ffbe7a2, 0x79059f22, 0x447e404b, 0x6f037e50, 0x616fa51f, 0x9045e781,
- 0x9c21949f, 0xff00aece, 0x7fdf8601, 0x5585ed05, 0xa8d71861, 0xd6f8db8c,
- 0xf56bd415, 0xb545ed0a, 0x14d581e3, 0xfbc55338, 0x735f94b9, 0xc23e09d8,
- 0xbe78bb03, 0x93ed4a4f, 0x37e8bd1e, 0xa1bddce0, 0xb9d2714e, 0xb78a1183,
- 0x7c47465b, 0xdad149f7, 0x6bd1fc27, 0x1e7867bf, 0x6fbe56ef, 0x8dd6cfbf,
- 0x6e99f7be, 0xb2fbfc61, 0xfe7f9f43, 0xefe70a5e, 0x21d15931, 0xa8a5c7eb,
- 0x37111fbc, 0x68a1f1a0, 0x7be85d4a, 0xb8c513b0, 0x425fb8cd, 0x24f6dcf8,
- 0x28d9b7e2, 0x93f2fdf1, 0x196377c8, 0x60cfc4d3, 0x9fdfca7c, 0x8d4172f2,
- 0x19d74f9e, 0x9bafaf84, 0xa91480ef, 0xf2f8fdbf, 0xf4cbd104, 0x8476f835,
- 0xfb5db7c0, 0xe8ebefbd, 0xf7c3ac35, 0x48e76f82, 0xf86a763e, 0x22ef5a3d,
- 0x538e8cfe, 0x5747e8ac, 0xe0d6c2b8, 0x9f2fc17a, 0x6cbe27bf, 0x1d03fb96,
- 0x02b5efe4, 0x890abf94, 0x4febcf47, 0x74bafca2, 0x3cb9eded, 0x7335f3b6,
- 0x52bc01f6, 0x7fbe0fc8, 0x27faf9e4, 0x7c092e31, 0xd794f541, 0x2c1dc007,
- 0xf941758f, 0x15f920ec, 0x03fa47f2, 0xa9e001ed, 0xb8b7ea27, 0x007b4663,
- 0xd04cfc9f, 0x27b8a2e9, 0xfb9a3cda, 0x78ddcd93, 0xfb8523ba, 0x7c09cf8f,
- 0x9bed126e, 0x90f003c3, 0x1f1fe1aa, 0xe6025bae, 0x3fba784d, 0x93fbce4e,
- 0x63d07c82, 0xbf5e36cd, 0x27a3e52d, 0x7cfed93d, 0xa6af7f70, 0x7880527c,
- 0xf1fff7f1, 0xee23f461, 0x91db7817, 0x27b0e472, 0xc139d052, 0xf0214eff,
- 0x5163bd07, 0x74a1fc8e, 0x761f8fe4, 0xd04f4fe4, 0x774ef4f7, 0x3a7bdf67,
- 0xfa0cef7e, 0xea3de19e, 0xd05eff9b, 0xae883f2d, 0x1d744179, 0x942f9413,
- 0xff46af79, 0x5c5cbd4a, 0x09e3f4ff, 0x54df1871, 0x9fbf38e8, 0xbd934f9f,
- 0xfc956f99, 0xf230e67b, 0xcf9f9fab, 0xd7279e12, 0xce79ba09, 0x787a893d,
- 0x51e1ea12, 0xd414fcfe, 0x5f3f9443, 0x7e61fb80, 0xea81757b, 0xed91abef,
- 0x7afd922f, 0xefec8560, 0x3a4bca33, 0xb225cf32, 0xbd0bf777, 0xa4ad3cc3,
- 0xf035e7f7, 0xfe7d3fef, 0x2b5fc3f3, 0x7841b50f, 0xf79410d9, 0x775fb504,
- 0x22b6fb03, 0x82c7fbe8, 0xe504d7ea, 0x6be507d7, 0xcd17dfb4, 0x8b0e4852,
- 0xc9fdf046, 0xe60cb960, 0xda522f8f, 0xf6ed63e3, 0xff24895c, 0x1357234e,
- 0xfafe79aa, 0xa829fff3, 0xa7c80c89, 0xb21e89b0, 0xc05a30ef, 0xb9d041fd,
- 0xc1f8151e, 0xbcde89d0, 0xecde99d8, 0x79ef6c13, 0xd7f03ffd, 0xd22fda24,
- 0x54fb25f8, 0x9551be6d, 0xbbbd4770, 0x5f603228, 0xe2265995, 0xfdf3baba,
- 0x6389889b, 0x22fc0352, 0x6744f84f, 0xfb653cc0, 0x575d5f71, 0xd4f8bc71,
- 0x719b89f0, 0xd8b4687f, 0x14f1b4d7, 0xf68aa5ec, 0x6fc452ba, 0x5d39e1c6,
- 0xebee176c, 0x0fd030b9, 0x70bd7562, 0x523f8d9e, 0xd550bbf9, 0x53c01f40,
- 0x79d3b311, 0xea7899d3, 0x47d43bbe, 0x0df92f47, 0x47efb77c, 0xd3b412ea,
- 0xd2c49747, 0xa945a639, 0x17dcefdc, 0x366135dd, 0x1e231be4, 0xf8db7d26,
- 0xf74a58c4, 0xad95ceaa, 0x353ae856, 0x5f646279, 0x3c268fac, 0x4fc43639,
- 0x9dfc065c, 0x38276a99, 0x426b36dc, 0xabdbfa3d, 0x085fb40d, 0xfc457e2d,
- 0x3069a4f3, 0x968bb7ae, 0xb0fda7f5, 0x1a4f9fe2, 0x8ab0f787, 0x3ed0371f,
- 0x4ace8b49, 0xeaf72271, 0x6a2e74b1, 0x7a910ad6, 0xcdf4a2ee, 0x1abafcff,
- 0xbeb569ef, 0x0efbd0a0, 0x7bad5c77, 0x9b9e1067, 0xf74ee9ac, 0x7580de2e,
- 0x3efb9e00, 0x17b7bebe, 0x089f21cf, 0xa473a2ab, 0x8bee9ed0, 0xbfb35e95,
- 0xdb0b313b, 0xd0e5d6ab, 0xa39414fe, 0x956a7cff, 0x41ef09ba, 0xc2594515,
- 0xa9f6fcf1, 0x75c518af, 0xa26e3d4e, 0x478e2277, 0x8fac67ba, 0xe8b8fba3,
- 0x8a53b3e9, 0x3c014a3d, 0x67d0da4c, 0x96126262, 0xfb7d049b, 0x1e011544,
- 0xfced748a, 0x24a4f643, 0xa527e786, 0x05b899f6, 0x97ea71e6, 0xd87ce9bd,
- 0xe4e754c1, 0x2fd7c054, 0x52539cd2, 0x6e5e11e3, 0x0ffcdeb7, 0xe3fc8fdf,
- 0xe404e285, 0x395287af, 0x56d1bf5f, 0xbef8109c, 0x3d45c977, 0x469bc1f1,
- 0x277a22fb, 0xc14d3c30, 0x41f03675, 0x67cdc62c, 0xf00b7589, 0x219d92f3,
- 0xa9e1abfc, 0xf1abd12a, 0x48d9f1a7, 0x0f5f3f5f, 0x19f5177f, 0x5f2037ad,
- 0x2d7321b1, 0xa693b9da, 0x0f44ec25, 0x91fe7ed6, 0x3c230bed, 0x7985b619,
- 0x7e3032c3, 0xfc871cea, 0x7aeb12cd, 0xc804b64d, 0x77ff68a1, 0xfbe73f0f,
- 0xeb8f6877, 0xfe7bbfbe, 0x9fb812d7, 0x4697db21, 0x5ce83c59, 0xf458b69c,
- 0xfaa38f48, 0x3cf0a7a5, 0x060bc95a, 0x2f2503b2, 0x8ad63fc4, 0x06f807fa,
- 0xf3c16be3, 0x81aa63fa, 0x933a31c7, 0xad18cf4b, 0x1331b25c, 0xc99dbe71,
- 0xdc86cd65, 0x3b239b89, 0x2b52cb97, 0x5ee34fd7, 0x9651efe0, 0x71e8b50e,
- 0x0bf4737f, 0x7ba16d6f, 0x86c20b74, 0xd289bde0, 0xaf444c17, 0x63c58b16,
- 0x13ef0dbd, 0x9031f458, 0xedca9b3e, 0x9f90bd69, 0xcde9955c, 0x7ba52843,
- 0xf0df7212, 0x9e6792ec, 0xe797e3c5, 0x70da7798, 0x2765dfc0, 0xbbcbd3e7,
- 0x063f8a54, 0x1f9623ef, 0x61cc69dc, 0x788fb137, 0x32c3fd83, 0xdfde22d6,
- 0xf07dfd0d, 0xa9abe1fe, 0x0687fbc1, 0x2a5e4fba, 0x37730ff6, 0xe9770428,
- 0x3fcf7e12, 0x8dc79637, 0xfa052e4f, 0x1ede691b, 0x0f3c10eb, 0x294eedcd,
- 0xf866bc53, 0x0b0daef5, 0x13d98e28, 0x6e7184f1, 0x89e26ef1, 0xae3a4730,
- 0x085e4bf3, 0xfe96fc23, 0x7e5fee6a, 0xfaf78599, 0xd702e20a, 0x2f91fbd5,
- 0xde197e38, 0x9cfd941f, 0x7a63f65e, 0x45f731a7, 0x7cc31f58, 0xabd8634a,
- 0xbd2067f7, 0x9f71d292, 0x5d2bb653, 0xbc5ea3fe, 0x61afac1d, 0x4ab45d1d,
- 0xecc7efe5, 0x041d9136, 0x01644f59, 0xad672cf7, 0x72346838, 0x8712c63b,
- 0xeedaff09, 0x1c769fbf, 0x6eeaf1ea, 0x2687b8a5, 0x51ef27f1, 0xfbf8e915,
- 0x853a8574, 0x268157ee, 0x97497ba3, 0x7b5fb953, 0x679f953a, 0xd0774a28,
- 0xb5f29cfd, 0x0cf2c726, 0x7dfb4fde, 0x95df584f, 0x684b9aeb, 0x26f7f33f,
- 0xae54ab8a, 0x45867308, 0x3b17f3f1, 0x6af9d006, 0x51f011bd, 0xe2fae766,
- 0xa56f98b2, 0x745dd27d, 0x8ecf419f, 0xdcbea1e8, 0x7963f5c2, 0x923de00c,
- 0x186e8a33, 0xe8c767be, 0x9bf624dc, 0x7c602834, 0x3f439445, 0xbf7f28f6,
- 0x83563a4d, 0xdf6c1b71, 0x31e21077, 0x8474da76, 0xe49515ef, 0x76b49019,
- 0xaf7dfa04, 0xdeb899a8, 0x6fb55a2e, 0xf9dfea1c, 0x8de307db, 0xeaf45609,
- 0xe63f6407, 0x88b7fa0b, 0x90c56773, 0x22b677c7, 0xb93cb8d2, 0x8a2f1e55,
- 0xef345348, 0xf2fac910, 0xbf1e0655, 0x8a8f3d07, 0xc7d97ca5, 0xa5b96fd4,
- 0x6ff50139, 0x30c36ef9, 0x6951d3d4, 0x978b2e5c, 0x011f65a5, 0x44362abe,
- 0x6583bbd3, 0xe623029e, 0xca156acb, 0x4f8bbffb, 0xbf3d3e47, 0xe428b5e2,
- 0xbe61139f, 0x5a97689e, 0xe8398417, 0xc795a1de, 0xe8afceeb, 0x6695f749,
- 0xf82d9b59, 0x45acc19e, 0xbfa86ddd, 0x467d5a8f, 0x975a3fac, 0xd3bcc3a1,
- 0xbcc6cd6a, 0xe51b7f53, 0x2df38bcf, 0xa57c83f4, 0x6d973a70, 0xbfc467db,
- 0xcc44324f, 0x1f2be2f7, 0x4ff8c2f4, 0x2f737a79, 0x07c02bb4, 0xcf1052bd,
- 0x9764292f, 0xf3f1b62b, 0x2a0f92ee, 0xee400f90, 0xa83e09e6, 0xf7daf5d8,
- 0x902a1e51, 0xf23a43fe, 0x7ef3f011, 0x71b1df2a, 0xefdfe31c, 0x76913e47,
- 0x0c2bf20c, 0xf1df8c36, 0xa71a667c, 0xe18f943f, 0xfc019ee5, 0x39fb5d1c,
- 0x741c8d04, 0x1a575f46, 0xcbc587b7, 0x5d6fa44c, 0x5a1e5c69, 0x428eed56,
- 0x657c5dfa, 0x67dc01df, 0x5601df29, 0x1e421eda, 0x712a3e04, 0x3f0451fe,
- 0x389517f9, 0xfcff28df, 0xc85ef9db, 0xf3e32561, 0xd4adf393, 0x7acbf98b,
- 0xc124fdf1, 0xe04c652f, 0x2e6f576b, 0x50ce4277, 0x0ebde98e, 0x4db73f31,
- 0xf7e50efb, 0x22dcfcc5, 0x28bad665, 0x17d20fc4, 0x103e0ff5, 0x04fa9469,
- 0xbedc5c9a, 0x4bf1ce91, 0x57f8497a, 0xdf403809, 0x7e6c6339, 0xf274b63a,
- 0xe095644e, 0x778f639b, 0xfc07af49, 0xcf4adf9d, 0xeabf116c, 0x7c93c603,
- 0x7dcbc723, 0x38ddd279, 0x87dfe86f, 0x8f71cbfd, 0xd8f4227a, 0xe5c651cf,
- 0xe52fc243, 0xa1fab732, 0x614707bb, 0xee968bbb, 0x9cde7003, 0xacd2ab8e,
- 0xfd13bdf4, 0x59def805, 0xfadc50af, 0x1fe75898, 0xa8b5fc7b, 0x7e7e01e2,
- 0x277c427f, 0x307f0cf9, 0x6de1263e, 0x7038f1b2, 0x0f52dc30, 0x9f73b849,
- 0x2c6eefb8, 0xbee3f097, 0x4a9f2051, 0x957e4a3c, 0xf982f5f7, 0xda4e7896,
- 0xfe73b54f, 0x463d4cae, 0x943a77e7, 0xfc27f707, 0x5ce213a2, 0xe33c6b79,
- 0x8915ff71, 0x8af735fb, 0xb40c8b18, 0xc08ed23f, 0x807d1acf, 0xa7bf69fd,
- 0x8b3ce716, 0xd690bb74, 0xc73ffa8d, 0xd0398cea, 0xe699d96f, 0x9dcef871,
- 0xb8ef43f4, 0x31a353ea, 0x9f8bb55e, 0x52fc9377, 0xc93f6176, 0xffb8b941,
- 0x83eab454, 0xefc8e182, 0xbed035bf, 0x63e3d14e, 0xcfdfe88d, 0x187332dd,
- 0x41ef01a2, 0xbb3f5ea0, 0xbf266879, 0x984d6059, 0x3621f786, 0x01ed333f,
- 0xaf559f28, 0xd80dbbd2, 0xd16fca0f, 0x5f1499a3, 0x52d6113d, 0xf8fd0a30,
- 0xf456a81f, 0x32df6fe3, 0x7f6c31f4, 0x0c6ba5bb, 0x39b1b63d, 0x7d4ef296,
- 0xe907d934, 0x8073caf7, 0xc7dee2d5, 0x3fde845f, 0xe22a9edc, 0x2f755ffc,
- 0xdd6f8fdc, 0xacef4618, 0x75ed1a14, 0x4f6f1c3e, 0x54675a17, 0x23eaf11a,
- 0xbf255bdd, 0x99918e6c, 0xb9508693, 0x0fca0939, 0x451f9a1a, 0x51f0723b,
- 0x3f7c60cb, 0x86d7a992, 0x9a7f7315, 0x6ac63bef, 0x70912ddf, 0x0fc6247c,
- 0xdf7e4fee, 0x1b08eb84, 0xefa44fdd, 0xedf8aecf, 0x6783b434, 0xe1b4f6b7,
- 0x09ef4fbc, 0xa703fba3, 0xcf77da0d, 0x57def56e, 0x79297df0, 0x9a74f56f,
- 0xfc938fd6, 0x377bc37e, 0x839ed37f, 0xa5b9d1bc, 0xdd194b0b, 0x8d397efb,
- 0x2263f7d1, 0xe789dabe, 0x4d6a4b08, 0x7307bc56, 0xf71ef912, 0xfcab76b3,
- 0xcb99a5fe, 0x99ddc9c1, 0xe4b7bf74, 0x525f3c6f, 0x3ef178a7, 0x9fa7fef2,
- 0xb30af3a0, 0xabc4cfc1, 0xf3feed09, 0xa1a7a7ba, 0xb8765c38, 0xfe7de257,
- 0xf9f95bcb, 0x32ef0e8a, 0x2079dc1c, 0xdfb9dec9, 0xcbfb5dfc, 0x9f110e32,
- 0x2fcfbdae, 0x4fd72cf1, 0x8c3f026f, 0xdbc7e218, 0x90e74b67, 0xa9617cbf,
- 0xca4bd29b, 0x23b7b5b1, 0xe9a25b1f, 0xeb1fc0be, 0xbdf1519f, 0x835df2a8,
- 0x783ae1af, 0xbd346454, 0xd2d9f293, 0x7a8fb425, 0xa5156961, 0x0e32de92,
- 0x46aec777, 0xfab3eefa, 0x9fbc06cc, 0xb46446fb, 0x90b603b0, 0xdeeced74,
- 0xb9d79cb1, 0x4afa701f, 0x9d6dcfb8, 0x6af38519, 0x61b63e7c, 0x2235d224,
- 0x5f7e8ada, 0x724738a9, 0xabf73d6a, 0x7fa398cf, 0x3df40f93, 0x024a61b3,
- 0xbb3737be, 0x5869def1, 0xb147b25e, 0xb1c07ae2, 0xae145267, 0xb7d53edb,
- 0xa8fde144, 0x7bcbd74f, 0x3bfa5e55, 0xd8f2a354, 0xca3f6c14, 0x0cf667a7,
- 0x7c8d75be, 0x9e82f232, 0x879ebfee, 0x5c938a72, 0x0938a70b, 0xb9e2c4fc,
- 0xf3afd991, 0x3afb4af8, 0x6ef3ac57, 0x347ef317, 0x31f726dd, 0x04773ca8,
- 0x61bd3f2f, 0xefec44e7, 0x158366ec, 0xb36cfee1, 0x079ffa81, 0xc01d33eb,
- 0x5f2b667b, 0xd71e60f7, 0xf2b767cb, 0x3abccdf5, 0x5f29bebe, 0xfbf27060,
- 0xcc7e5aa2, 0xef47680d, 0x5ef274fb, 0x9f273cc8, 0x97b03cdf, 0xbe60df38,
- 0x7475618d, 0x9e9bec8f, 0xdbe60d17, 0x855f92f9, 0xd7e7687e, 0xe044f8ce,
- 0xf91de513, 0xbcc3f255, 0xdedf7cf5, 0x07383756, 0x47f24ef9, 0xd5593bf0,
- 0x57dfc646, 0x7bd385d4, 0xed2293b8, 0x530fb406, 0x20c65ae2, 0xe74e3e5a,
- 0xab9a807e, 0x37bde273, 0xf90a6d56, 0x748acece, 0x744557ee, 0xdeefc465,
- 0xcf3f2b74, 0xc97fee29, 0x86922614, 0x84527b76, 0x343b0bed, 0xaefd3a79,
- 0xcfc0f47b, 0x3db76e93, 0xd8c1ddda, 0xee0bd32f, 0x267cc3d1, 0x7776da65,
- 0xbff3fc83, 0xb7f3c09a, 0x201a86d9, 0x78994cbf, 0xd7c818cf, 0x4a9f3ba7,
- 0xece7180f, 0x38692e96, 0x19ff283f, 0xbbc5d796, 0xa5698e7f, 0x49760fb8,
- 0x24b41d69, 0xfdfedfc3, 0x7fa3963d, 0x2df3fbb4, 0x18ee9606, 0x7f097980,
- 0xdd25b4e8, 0xf8f4abf9, 0x8cc5e58e, 0xf5e74e3d, 0x0e1efc3c, 0x09ccb8fc,
- 0xf38a4f78, 0x97bcb15b, 0x2f741353, 0x9fefc1c7, 0xf252fbc9, 0xff5f543e,
- 0xb70db27d, 0x92ec9f72, 0x2a1dff81, 0x0fbda9c5, 0x89fc34a6, 0xf6a9f9de,
- 0xa23096b0, 0x4d9ef683, 0x7753be39, 0xa20bdd1b, 0x6f4c87fb, 0x57337d27,
- 0xac683bfa, 0x29dff987, 0xfcfc8960, 0x1f82a3c1, 0x3d652f4f, 0x9fe8807a,
- 0xca39b77f, 0x985c700e, 0xfa85ebe8, 0xfddc3220, 0xe9d7c427, 0x0ba9d50d,
- 0xaa1ef0e3, 0xed0f91c9, 0x7df978cf, 0xb7e132ce, 0x42f1cdb2, 0x3bbea82f,
- 0x46535da1, 0x87684ddf, 0x757c17de, 0xfe97c321, 0x192bd423, 0xed049d7c,
- 0xde5d3ce8, 0xb1e2bbf2, 0x4fed85dd, 0x700d98f4, 0xbc06009b, 0xfa1e35a7,
- 0xf7a3611c, 0xfb4a98aa, 0x7efe5ecf, 0xa2799e92, 0xd5eef86c, 0x3ee2e933,
- 0x9413dd11, 0xeff89274, 0x1a181740, 0x999d59fd, 0xbeee1019, 0xfdfd036c,
- 0xf91f492f, 0xddc2e2ce, 0x7742fe3c, 0xe31e4524, 0xe2cda748, 0xb0759fef,
- 0xbf916f8b, 0xd1e9620a, 0x330d9fe8, 0x11c9db43, 0xf5d88d1b, 0xff2f6d77,
- 0x92fc2e9d, 0xe0706cc1, 0xa2a5923b, 0xd0b558cd, 0x2d5bef8e, 0x7bd3378c,
- 0xe85f0b25, 0x96c1fc4e, 0xb60590fc, 0x89621b63, 0xa866565f, 0xf5b9ff84,
- 0x2a1dde8c, 0xf3a64fa8, 0x36f5f994, 0x12daa34a, 0x6fecfca9, 0x7ae2c9de,
- 0xe0a7d389, 0xa68cba7f, 0xd3ff4b73, 0xd9d6529b, 0x6691a77b, 0xf0bbcfba,
- 0x0b6bb720, 0xc7bfcaa7, 0xbbafefc2, 0xc8ae3804, 0xb90b8a1a, 0xe753dc3a,
- 0xf0ba57ef, 0xe77e00be, 0x677d5034, 0xfc4a57ef, 0x82dd049a, 0x7a9cb3df,
- 0xde913330, 0x59ef147f, 0x9aed174e, 0xceb3bdc5, 0x4fbcb5de, 0x6a227bb4,
- 0xddf2135c, 0xc8696774, 0x9ef52d77, 0xcffa0730, 0x7a48d486, 0x373ee147,
- 0xf59a97f8, 0xf11e8b4c, 0xbf9b2d30, 0xba753973, 0xfd90deb6, 0x4373e939,
- 0x92778776, 0x4d8fa80c, 0xecfb6d2e, 0xf50ec2ae, 0xf6bf7d65, 0x2354d15d,
- 0xbe3d4fd9, 0x69f90b3b, 0xf4515de2, 0xbfffd10f, 0xff10b4ec, 0xb83bc49b,
- 0x112b2ccd, 0xbeadc2f5, 0xdbfffb27, 0xefc1b1fb, 0x03bf06c4, 0x42eb7fdb,
- 0xdd607e4d, 0x6fed350f, 0xa9ae5fab, 0xad5bec1f, 0xfa6ccfa9, 0xb43f2699,
- 0xfb4d39f9, 0x693647e1, 0xbcb647ea, 0xfdbfa9a4, 0xfe4d0ecc, 0x683fd68e,
- 0xb6d9dfda, 0x61cf9357, 0xe7da68ef, 0xe4d03f9a, 0x57ff5ac7, 0xc4aefed3,
- 0xf1fa9a13, 0xfa9af3f6, 0x68ae7d09, 0x2f8e05f2, 0x373fed35, 0x457757ba,
- 0x0cea22bf, 0x433aadf1, 0xf944f861, 0x6629a6e5, 0xba6b07d4, 0xf8247d0a,
- 0xd3b0b96f, 0x7ba307ac, 0x6cd563ac, 0x3d5ff11f, 0xc1a0bbff, 0xde7f4f76,
- 0x1ff8c4e5, 0x6bdf8d7b, 0x527f068b, 0x8c7e301f, 0xff02ccd3, 0x9e6c5dee,
- 0x778f9355, 0x77da6a25, 0xd4d76e99, 0x68fbb927, 0x38e653ea, 0xaab4f934,
- 0x5df69a11, 0xf9353897, 0xa69e4f0c, 0x971af77d, 0x76b3df26, 0xef7da6ba,
- 0x7d4d6ef5, 0x4d1cef5f, 0x55adff7d, 0xbac0fc9a, 0xb7f69a25, 0xf5347bd5,
- 0x9a357d83, 0x5aa6ccfa, 0xf3687e4d, 0xe1fb4d7a, 0xfa9abc47, 0x355b2d91,
- 0xa99fb7f5, 0x68efe4d3, 0xbfb4d7ad, 0xc9a7cdb3, 0x9a83b0e7, 0xf7e6b9f6,
- 0xd6b1f935, 0xefed344f, 0xa9a63c4a, 0xab3f6f1f, 0xce7e97a9, 0x6b9f3e84,
- 0x53df85cb, 0xe697f8e0, 0x6ef7f6fb, 0x1f742877, 0x6ed75cea, 0x96c57df2,
- 0x24fd1530, 0x6c99c517, 0xf5111078, 0xb727de15, 0x8539f3f1, 0x238aaf14,
- 0x944c887f, 0x810bcf1d, 0xab8510df, 0xf40c8cb6, 0xfefc23ab, 0xccf5ea5b,
- 0xdadff79b, 0xd5dcff84, 0xf288beee, 0xfb6eaf31, 0x989f7a38, 0x1c225679,
- 0x77bffdf2, 0x956dde83, 0x19f378e9, 0x17f00fa6, 0xa6d5860f, 0x389af90e,
- 0x05f378c1, 0xb6c1ef86, 0x22e22bf7, 0x17bdc7f8, 0x16bff406, 0xf7f817d6,
- 0x9a976b23, 0xffc76fe9, 0xf295a96c, 0x522696eb, 0x3a00fffe, 0x0047bf29,
- 0x000047bf, 0x00088b1f, 0x00000000, 0x7dedff00, 0x4554780b, 0xeedd7096,
- 0x9d248fdb, 0x777579d0, 0x493cdc9e, 0xf09d0848, 0x3a3e00d8, 0xc0406021,
- 0x490435e6, 0x41a8c1a4, 0xf881ba43, 0xbb75744f, 0xb2021031, 0x10d191b3,
- 0x0186c195, 0x099d1964, 0x09d1a32e, 0xe09af09a, 0x1c604c3a, 0x3719d9c5,
- 0x8ee2a3a0, 0xcfe31e10, 0x7fc38fee, 0x937ba9ce, 0x380e9dbe, 0xf7ff3afe,
- 0xb4fbfa3f, 0xab755538, 0x739d554e, 0x2aaa3cea, 0x89895ead, 0xde6d6322,
- 0xf39f4a1c, 0xc99899da, 0x316f36d8, 0x0ebddbc1, 0x72defd82, 0x9d7a774a,
- 0x5bcbbf94, 0xaf1ef041, 0xdebdd28b, 0x79f74a1a, 0x92fe543d, 0x9fe081b7,
- 0xb6947d7a, 0xff299b7b, 0xc10b6f15, 0x046dbc07, 0x53f5eabf, 0x4bdde1da,
- 0x76de1be9, 0x76f4ef2a, 0xb7a6fc10, 0x6f2ee08b, 0xbc87c10f, 0xf11f04bd,
- 0x98f8269e, 0x1ed28fb7, 0xbe9467ef, 0xf2a7eded, 0x0957bc77, 0xdbbf8ebe,
- 0xcd2afc19, 0x2631e49f, 0x7ae69730, 0xc9ccc21e, 0x00f63226, 0xff824bfe,
- 0xcc8846e2, 0x8cfdd8c2, 0xb0d73eff, 0x9413769a, 0x3ff2fe77, 0x74c60285,
- 0x1f8d8ca5, 0xf662690f, 0xc634c6ce, 0xe675b026, 0xd318724f, 0x63d75740,
- 0x4e09fb07, 0xd6191319, 0x2d75dfc3, 0x58c7dffe, 0x94bffc3c, 0x834c78e5,
- 0x14095369, 0x55befb42, 0x1a777f82, 0x3e20d755, 0xbf1c8dab, 0x95135a69,
- 0xf82c3e57, 0x5563020d, 0x8be9f322, 0x587dfb18, 0xc11b0154, 0x2e8f25d8,
- 0x2172c447, 0x04830edc, 0x443a8ff8, 0x2c5d7e0e, 0x9da5b18e, 0xd29b1d86,
- 0x84aaf106, 0xfdf035ef, 0x0c1a562b, 0x3a3d64ab, 0x1df203c4, 0x9ec618da,
- 0x4ba6b8b7, 0x8a60ff90, 0xf687a7c6, 0xed9fc999, 0x2dec648c, 0xe6066b8b,
- 0x77dcf25f, 0xc07f1b0c, 0x7ec6cf6c, 0xe2ba1b66, 0xfdff4117, 0x9df6b5c7,
- 0xe1f3f0d2, 0x6c67296e, 0xdfca0ddc, 0x02ec973c, 0xa2ffca3c, 0x9ffce175,
- 0xf85645d0, 0x492f01f3, 0x1a4a78e0, 0xeadb3a55, 0x7cf8825a, 0x47b9e919,
- 0xe5f85303, 0xacf6ab6d, 0xae552181, 0x82e11aca, 0x2582eeef, 0xcd8c1963,
- 0x418e9265, 0x38e67cf9, 0x2d4d069a, 0x17822e64, 0x6fa51f31, 0xb1aabbc5,
- 0x4fccc59d, 0x21b26bb0, 0x82b8d435, 0x78cb72f1, 0x947c65b9, 0xabab71f4,
- 0x20e5e38e, 0xba4c4ebc, 0xa5c71b23, 0x5596f5e0, 0x58737aa2, 0xefc476ff,
- 0x3f1783cb, 0xd2863211, 0x174077c7, 0xeb1e6826, 0x73ac3d31, 0xf7d18ea3,
- 0x7e088f8d, 0x2e856ba4, 0xb791992a, 0x0be418fb, 0xf4027481, 0xd2fc8451,
- 0x92373a9f, 0x0949e4e8, 0x92707c1a, 0x0b1fa7d6, 0xb3f8d4e3, 0x87d12d05,
- 0x1efc005e, 0x48fa0388, 0xea0e9e1f, 0xe00d219a, 0x67afa01f, 0xaff3bdb0,
- 0xce0e5dff, 0x49cdfb97, 0xa357ce12, 0xe801d606, 0xd6b6f7d8, 0x99925bbe,
- 0x94ed6014, 0x6ba47e31, 0x73edda26, 0xb17ae0c7, 0xdfa84ea5, 0xfb0d65ad,
- 0xfbf687f3, 0xb417ae2a, 0x2ba6c27f, 0x9cbb53f7, 0x9ff295cf, 0x63c5fae2,
- 0x5eadebca, 0x16ad69f5, 0xe8713ff0, 0x131a5e9c, 0x6f0d1c62, 0xe00666e7,
- 0x3338eeef, 0xe44261dd, 0x45e7f2fa, 0x949fe60e, 0x1fa144e9, 0xb5d23ead,
- 0x178814c3, 0xf9e817ef, 0xd13744e7, 0x4419cf40, 0xe0f89fcf, 0x690639d3,
- 0xfb4822c4, 0x20ba6a60, 0xd660bd75, 0x672cdd23, 0x99ab4a76, 0x6007d293,
- 0x9d7e91f9, 0x38f4a7be, 0x76b20fef, 0xbe2bafca, 0x7cf482d7, 0x8a95c6bf,
- 0xa5eb2d70, 0x2feb377c, 0x2dfcc1b3, 0xd47b5e6c, 0x6fcf5806, 0x025a6a79,
- 0xff3cefcc, 0xce98a3b2, 0xe27c25dd, 0x7a3f8893, 0xc13eaf10, 0xfa113eb3,
- 0x92a5fbbf, 0x3f9049f5, 0x85d7cb47, 0x175f2bfd, 0x8f047e45, 0x97a1f81b,
- 0xe341cb8f, 0xab9546d2, 0x09f2a1f8, 0x9da010e6, 0xff0683fe, 0xfe00b4ce,
- 0xdfe87e28, 0x898e5093, 0x7ae0f7fd, 0xc434dfbb, 0x083f7ae0, 0x29c71be2,
- 0x806b1838, 0x2ad690fe, 0x882a8863, 0xe1621fde, 0xb9f7ac76, 0xa79fdf4c,
- 0xcfefa230, 0x4060e605, 0xa67417bf, 0x5ae50166, 0x0456cbaa, 0xbe60acf8,
- 0x6ee50626, 0x38054bcd, 0xd725234f, 0x1fd744a7, 0xa61537b5, 0xa7f7fca1,
- 0xf7ff280a, 0x698dec19, 0x5d84fdaa, 0xe321408f, 0x3f9f3861, 0x0ec776c0,
- 0x3e284bc5, 0x14429ff6, 0xf33d0663, 0xbf888b19, 0xebe444d9, 0x57f13d44,
- 0x066d4e23, 0x3c94e3f6, 0x9feda1a6, 0xf9edf190, 0xef744b4a, 0x16ecf183,
- 0xf7c3f542, 0x60f8432b, 0x2c3f243f, 0xa7d1fa8c, 0xfa563e71, 0x64bea663,
- 0x6a75d027, 0x86974b84, 0xc716c182, 0xcb998be5, 0x4fb49e97, 0xe67d7133,
- 0xc8a8de4c, 0xdd8f6a65, 0x09d1e5c6, 0xf843e49d, 0x1d9a4944, 0x9c80d724,
- 0x97f8abbd, 0xbb8f11a7, 0x2d2ea68c, 0xdd16eca4, 0x7d94fa9f, 0xff707d30,
- 0x7fd94bbd, 0xeffbe16f, 0xefb5991c, 0xf1babb12, 0x3aecc67b, 0xfd972fc4,
- 0x6d8f995e, 0xf22adfb8, 0x0b7ec871, 0xf9c5eb03, 0x832b2513, 0xc7c0b574,
- 0xdc253abf, 0x36c47c8f, 0xf4f8d2e7, 0xfe0cfcb2, 0x58c15ade, 0x13c651a6,
- 0x19704bfe, 0x20ce6659, 0x5663549c, 0x9b1e29c1, 0x06c8feaa, 0xe69e5549,
- 0x679551cb, 0x7055db34, 0xaab14b56, 0x8736a8fe, 0x97f5ce0a, 0xede7eaab,
- 0x31e0aa75, 0xfaaa15ed, 0xaa5c3b63, 0x1aaec2f2, 0x1eb8f955, 0xd09e0a8f,
- 0xffaaa0db, 0xaa7da777, 0xcd7d49f2, 0x9f29f2aa, 0x5be0a8b5, 0xf554dbfb,
- 0x57eabf6f, 0x7fb09795, 0x354f9556, 0xd3c157ee, 0xeaabafcc, 0x16fb80bf,
- 0xb61dcff0, 0x0cfe556e, 0xbbeab8e9, 0xaa4e733b, 0x75e417e0, 0x270e2df6,
- 0xe72d68be, 0xfb6cd1fb, 0x5876aa07, 0xfebe68e7, 0x7b6f3c61, 0x510b1fcf,
- 0xf4d76e4e, 0x4add21a7, 0xf222735a, 0xdcf16671, 0x2c664043, 0x14aab1db,
- 0xf94e5bc5, 0x1d308753, 0x8a5fdced, 0x715f926c, 0x05a610f2, 0xd0a58bae,
- 0x44d7b31c, 0xc8b4c61f, 0x8ad53853, 0x3dcc34a8, 0xdf44e98c, 0x5728a9aa,
- 0x3f5c785f, 0x2a28f91a, 0x074fa146, 0x827d67d1, 0x7eb9f886, 0xf28fc9b1,
- 0x24c532c7, 0x96139032, 0xb1d65a1f, 0x9a8b4c02, 0x1af66d31, 0xfa0f5f99,
- 0xba519780, 0xfe666bc9, 0xaf67206c, 0x93fae08d, 0x43a795f7, 0x44ab233b,
- 0xe699aa33, 0x48258f51, 0xe5f5bed0, 0x765d9c96, 0xb0edd6c6, 0x42e5d7cf,
- 0xc59e19ff, 0x4e01a23b, 0x30058e63, 0x2398167f, 0x25b19936, 0xfa76df3b,
- 0x97c287f2, 0x244d9d33, 0x5cf6c417, 0x7694ffd4, 0x6e7e9637, 0xdf2198d7,
- 0x11e74bf7, 0xf1adf798, 0xc21df4e1, 0xa75f9925, 0xb60b475d, 0xf69ef90b,
- 0x4cfc7c10, 0x977fdf1a, 0x0a7d73a4, 0x66eb8487, 0xacc6cbe5, 0x808ca7a0,
- 0xa93adcb9, 0xf0ea0ce1, 0xa027d9a2, 0xe0d7627c, 0x892b907b, 0xe0832958,
- 0x4e01c3db, 0x6c625840, 0xc7eb967f, 0xc5d5afd8, 0xfa00d9d8, 0xc351a849,
- 0xcf9e615b, 0xa3e20e66, 0x89f1aa5b, 0x8fdd0630, 0xf43b769d, 0xc60aadb3,
- 0x3d56f00b, 0x7a9437d7, 0xf68c34a3, 0xf8d32ff7, 0xcdaece7e, 0xf49ea3b7,
- 0xe79e3ca5, 0x3e8bfdbc, 0xeb7b44ce, 0x3589a52a, 0xf205c11e, 0xb4e95acd,
- 0xae9ea0fb, 0x8423e611, 0x348bf2de, 0x1dd7be91, 0xa090447e, 0x1269a7de,
- 0x7e9589c1, 0x0d52771a, 0xbf801bb4, 0x6609f44d, 0xe63db7c8, 0x9b3f1013,
- 0xf06769d9, 0x885a331d, 0x3cc8d7fe, 0xcbf86b61, 0x0f418fa2, 0x769d79d3,
- 0x13bba7ac, 0x271f33e8, 0xb86663d4, 0x47e3c94e, 0xa3eb10b0, 0x0d3e86a4,
- 0x9f40dc73, 0xd47d4a8f, 0xddc5fb43, 0xe80b2926, 0xa6c585fb, 0xda211d8a,
- 0x9f9e54fb, 0xfeea310d, 0x1f3e5a2d, 0x6cbedc8a, 0xf0a8ebe6, 0xa6689af1,
- 0x526be392, 0x846f5bc6, 0xc8cdb5af, 0x6ef8015c, 0xd0cc7e85, 0x55abe1be,
- 0xe83f1c66, 0x4fea4ed0, 0xc764f2e4, 0x6ec8728f, 0x21c75e0a, 0x3f9408f4,
- 0xa3e908a2, 0x7c08dfcf, 0xdbd2a868, 0xfeb26f51, 0x7b809343, 0x116b2273,
- 0x5358be50, 0xdc447aca, 0xae5744d7, 0x793e8433, 0xd654ba33, 0x839fd94f,
- 0x3d774bd7, 0x9c12fde3, 0x31d57fef, 0x1f56c7d4, 0x05718f8f, 0x3a4c53d0,
- 0xd662cba7, 0x98fe45a2, 0xbd29dacc, 0x7a52f585, 0xd4a7eb1b, 0xa622ccc1,
- 0x694ecca5, 0x3a527319, 0x2d28799d, 0xce942d67, 0xce94ed64, 0x8294bd62,
- 0x93a9433d, 0x9aeec999, 0xa637fb07, 0xd293980b, 0xa50f31ef, 0x7e9ce999,
- 0xc10b582b, 0x4a76b377, 0x24ef803b, 0x8c01fa3d, 0x9c827694, 0x904df4c3,
- 0x79769873, 0xa3652625, 0xd287201f, 0xa53b5e23, 0x94c5bcc7, 0x541d78f6,
- 0x396f6def, 0x9d78efa5, 0x56f09e94, 0x75ebda50, 0xde53bd51, 0xf5df4a1a,
- 0xcf7d287a, 0x69e940db, 0xdfd28faf, 0x1d299b79, 0xc67e07a5, 0x2be9cdf9,
- 0xf53e7d44, 0x0243bd23, 0xe591ecf9, 0xe68761d2, 0xb8f1dc99, 0x40661a6e,
- 0x235b283a, 0x7359fd20, 0xa43f0e34, 0x0b56729b, 0xe1ba42f7, 0x0cdfd704,
- 0x0fd248d6, 0x82f56dad, 0x0876ed04, 0x5808da7d, 0xa9e9e9cb, 0x9f208d73,
- 0xbad93a4b, 0x19c23b08, 0xee81194f, 0xfd3ce876, 0x64bca03b, 0x08d734a7,
- 0xc8e4d67b, 0x8fb1ff53, 0xe93e54c3, 0x03346b08, 0xfb3d2b3c, 0xe38138a9,
- 0x7befc281, 0xaee6733b, 0x253c44cd, 0x34c5f3c2, 0xbf512c30, 0xfa44c47e,
- 0xd9db6175, 0x93c00d42, 0x68454c1a, 0xebd40617, 0xae1fba42, 0xf2b9705e,
- 0x9655b6dd, 0x0d879c46, 0x0e5a809f, 0x7d19a959, 0xd5f3ab85, 0x5ebe6aed,
- 0x837b4cff, 0x09eb03fe, 0x7f6f6837, 0x7d32a396, 0x3a7effc2, 0xdd6fa60f,
- 0x6bf68ff5, 0x8e640fc8, 0x5774fdc1, 0xfd339734, 0x04ee9fa0, 0xc8c577bc,
- 0x1a4cc6f0, 0x5c43ca17, 0xd29b0db7, 0x77803efd, 0x1f573985, 0xd47ff2c7,
- 0xd14277d8, 0xa6d770ae, 0xc933825c, 0xc621b13f, 0x8f931393, 0x97df3cfa,
- 0x0d1f935a, 0xbff80293, 0xafcb9d39, 0xe95cb7ad, 0x447681dd, 0xc16586b3,
- 0x979b3b77, 0x7681cc6f, 0xf419bc7e, 0xdc478007, 0x0b31bd5a, 0x6a37d3ca,
- 0x19656a26, 0x78fc7887, 0x4d9ef573, 0x8f255fa8, 0x7686c98e, 0x99796433,
- 0xb857db1a, 0x55bce806, 0x95a7b6af, 0x7e649ff4, 0xce6686a9, 0x954d6c82,
- 0x3a1df4ed, 0xdfb81156, 0xefc64cfd, 0xd53c5957, 0x57fdcedd, 0xfee19186,
- 0x25fc6027, 0xc3bfb923, 0xfe48ceb2, 0x7ff24b0e, 0xca03bc9d, 0x7634db2d,
- 0x6b44e954, 0xea1d5aed, 0x3b598bfb, 0x810ee3f2, 0xe14bef7f, 0x0a28217a,
- 0xec0373e9, 0xd3deadf2, 0xfc03328b, 0x9f0ab684, 0xc97bf680, 0x0fa15ac8,
- 0x07e49ff7, 0x2dfbb405, 0x15c12e15, 0x8781f689, 0xb965cfca, 0xf80e927e,
- 0xfbe12ad9, 0xb992fd40, 0xa15d7012, 0xd2768adf, 0x605158f3, 0xf8b3a77f,
- 0x3b07ac3c, 0x75d5f499, 0x782bc27a, 0x97654ebe, 0x95f6c01e, 0xff2e0c75,
- 0xabb7067e, 0x5d013d77, 0xe24c1f20, 0xdd89f376, 0xce3fa489, 0xa0770d69,
- 0xa9e274fd, 0x6f0465d1, 0x3d40ec99, 0xc9eec4f2, 0xb39d31d3, 0x3bd52665,
- 0xb41eb021, 0xb96ce787, 0xd4fcc45b, 0xdb0bc00c, 0x7a27a33b, 0x41e5b39c,
- 0xcb47fbf9, 0xe358bcb0, 0x91da09fb, 0x22fb8dc5, 0x1c9e4ed0, 0xa6124af9,
- 0xf57d3427, 0x5dffd0dd, 0xdc2bf666, 0xe31b9d9e, 0xfe1cb1fe, 0x74a9f731,
- 0xbfd7ea1d, 0xf5a74f4b, 0xc41ccf9c, 0xec835007, 0xf6f65bba, 0x8a4d061e,
- 0x3fded6dd, 0xe65ccc15, 0xc11f30e8, 0x5ecbb4b4, 0xd657d386, 0xe9823ce3,
- 0x194f5ef4, 0xa7e52faa, 0xba608e5b, 0x3bf5d724, 0xff179f9c, 0xbcaf7be1,
- 0xc7c8f008, 0x07a8cdeb, 0x37d13e65, 0xebf92763, 0x21f90c74, 0x45a7926b,
- 0x746c048b, 0x787ca0c6, 0x835169f6, 0xad21b9fb, 0xc3610c25, 0xb41ae97d,
- 0xb745770b, 0xb3b8d0d4, 0xe3ce19c2, 0x210fb0db, 0x3b45645d, 0x809f9063,
- 0x3e1d692f, 0x10d3e993, 0x634731ed, 0x1fcf187e, 0xe1ce17a8, 0x5af503f3,
- 0x27ea04c2, 0x13fb2046, 0xbfdc06d4, 0xddfef26d, 0x38093cc6, 0xcf48d61f,
- 0x64ebf40e, 0x67fe7095, 0xb02e9c91, 0xfa44d37a, 0x96cd9c84, 0xb89dcf16,
- 0xe897560e, 0x3ba40beb, 0xf40706d8, 0x19827491, 0x055bd7da, 0x219c830e,
- 0x7e87f0bc, 0x42c98b0c, 0xbf828d7a, 0x0bda02b5, 0x1c7033d0, 0xdf834cf3,
- 0x9b177429, 0x4235c7c1, 0x65acbfa6, 0xdf053dbc, 0x9f2e0cb8, 0x83496f01,
- 0x7c6568f8, 0x009a1c60, 0xd1ea027c, 0x66f006f8, 0x05d21b76, 0xa7817a48,
- 0xc703124c, 0x8471ad5f, 0x7a645da1, 0x4fe8fbf5, 0x02394289, 0xf753fe78,
- 0x69f22324, 0x327238f0, 0x46df08d2, 0x6f5187d0, 0xfce2e99f, 0x11e958db,
- 0x18423ec8, 0x3a2c9fc7, 0x35681fd0, 0x017416ad, 0xf326b5e3, 0xa5667a7d,
- 0xcae51ba7, 0x3b08e2cc, 0xac9df7d2, 0xf3999d7d, 0xc04c91f7, 0xf81b146f,
- 0x41c4d899, 0x4f47f0bd, 0x97127bbf, 0x97b59934, 0xf9fee2e4, 0x70b3fdf8,
- 0x3a3eb6fd, 0x4ff107b3, 0x3baa79cc, 0x5e741a06, 0x197dd794, 0x6ca4ebf7,
- 0x1c0e3f13, 0xe0079247, 0x8d44bf40, 0x41e81cba, 0x65742b05, 0x71a21a13,
- 0xe444d1bf, 0x7a819ccf, 0xe486944a, 0x6129c83b, 0x33fd4841, 0xf9e4ae88,
- 0xaee7d657, 0x375a4c8c, 0x03af89ab, 0x171bb7eb, 0x5583ca46, 0x6dfa09d6,
- 0x011f3604, 0xa658df74, 0xd7680bf5, 0xac28fd62, 0x919de2cf, 0x8769d743,
- 0x03399a4e, 0x1ac3f4e5, 0x74366ef3, 0x7edc815e, 0xc3ed7a4b, 0xf90e5471,
- 0x7dfc91a2, 0x436af801, 0xb8f5eac1, 0xac6dfd59, 0xb48cee6b, 0xc989f9a1,
- 0x3ee2660b, 0x68cb589b, 0x47cb83fd, 0x575ea63d, 0xa3c737b2, 0xbbf988ff,
- 0xce7ac1be, 0x8655de4c, 0xbaf07cfa, 0x1a97742a, 0x105f7a1b, 0xa65f3933,
- 0x954fd846, 0x92215e93, 0x114ce09e, 0xa2ed03e3, 0x1f7c190d, 0x1335fdba,
- 0x23ec43ed, 0x5cb71fa3, 0x93ef577b, 0xa50eb0b9, 0xae683457, 0x1cefa3b0,
- 0x484ce1fa, 0xddeafda7, 0xf50affd5, 0x1a657da6, 0xb06ff987, 0x10e819be,
- 0x9d80f5f1, 0x2fdaf001, 0xa3a0b4f6, 0xd992b1a4, 0xfa55df71, 0xf3f723d9,
- 0x49df9d0b, 0x645735f2, 0x820e493b, 0x2f401e65, 0x7e896900, 0x56731978,
- 0x68dd90b6, 0x5907cccd, 0xf6bd6e8d, 0xfe5fb425, 0xefd0cf49, 0xd242af38,
- 0xe7f8c095, 0x65ba4a55, 0x5917c7e8, 0xf311ea39, 0x3f94ec2b, 0xf3ced2bf,
- 0x417f3c8d, 0x17f28385, 0xbe783a54, 0x3e61f209, 0x7bf85616, 0x42eed0bd,
- 0x41a48c53, 0x93a5783f, 0x50355f97, 0x0f603bf9, 0x87c90264, 0xde49f987,
- 0xe1a67cb7, 0xb84f12f1, 0x0d5c005f, 0x123d4591, 0x1a7ddfce, 0x8624167b,
- 0x01999114, 0xe9c2b67e, 0xf3f942d7, 0x13809fcc, 0x6af546f9, 0xbfe43667,
- 0x719a2c91, 0xc0386f7c, 0xabf9c66e, 0xe9de6915, 0x351bf007, 0xd8cf14c9,
- 0x7dadfb21, 0x67e48c2b, 0xfc875d05, 0xa2456cac, 0xf2f0c7ac, 0x7ecdcb6d,
- 0x0e40c7d4, 0xdff63ad2, 0x001e9227, 0x1cedf0f2, 0xca5e8bd4, 0x484987b4,
- 0xb37e6ab7, 0xa12f2f54, 0x19992af6, 0x9559f2ed, 0x97c6bdbc, 0xea0d7e34,
- 0x3379a655, 0xf71a0e91, 0xafda3b32, 0x2a9f56cf, 0x9b78458b, 0x87e5cedd,
- 0x56342e5a, 0xe12e396f, 0x731a3c78, 0x7ee7d516, 0xe94f46ad, 0xc830ad2e,
- 0xd2deb4cf, 0x2a18fca0, 0xd83dec6f, 0xa955424e, 0xb3d4137d, 0x8fd138c0,
- 0xf3cf4dbd, 0x1488f77d, 0x8b54b067, 0x4182e65d, 0xa7914efe, 0x187c82d0,
- 0xc545f245, 0x525fa35f, 0xf9923fc3, 0xc45df814, 0x3176f971, 0x5d95c93b,
- 0x27207aea, 0x52af2835, 0x67f9d4da, 0x2fc504b2, 0xe0879aa5, 0xb87ab679,
- 0xe71e0bdc, 0xc2bab8e0, 0x34b8d146, 0xd7285c7c, 0x74d73f20, 0x2b73f288,
- 0xa124bb45, 0x853f6bbc, 0x92f51fe3, 0x9e00bac8, 0x13345d55, 0x66d669e9,
- 0x6643b90d, 0x0b925eb3, 0xe2b71b37, 0x671e08df, 0x6436f8f0, 0x1cdf6968,
- 0x1bd707d0, 0x7d6c1f49, 0xb8c1a4c4, 0xe15be822, 0x973857e8, 0x099e1a55,
- 0x532230f3, 0x6bafd7d6, 0x34693cb9, 0xacea9d11, 0xfa04e58f, 0xa5d1841f,
- 0xeebeb023, 0x72bcec7a, 0x68e91b8a, 0xac72c1dc, 0x93639658, 0x2a7c60fa,
- 0x933873ff, 0xd6f7e602, 0x7c1518fe, 0x5544d5fb, 0x2e1012fd, 0x8d53e581,
- 0x69f2aa79, 0xf82a71e6, 0x5514db0e, 0x54d219fd, 0xce677c15, 0xb3faaa9d,
- 0xf055f3ed, 0x544bc55d, 0xee3ae7f5, 0x2fcf9555, 0xbe55487f, 0x0546b9d0,
- 0x7bf8aa2f, 0xaec5fd55, 0x92f95546, 0xe555279a, 0x9293f6c1, 0x3f726696,
- 0xe79b56cf, 0x8be483a4, 0x0e46704b, 0x14a967ad, 0x3dd703fb, 0x53eb822a,
- 0xe51af5c1, 0xe04178f5, 0x48feb1fd, 0xe29df20d, 0x91ed637f, 0xd75cff2a,
- 0x3ec6c9e4, 0xec72fa13, 0xb2dd23ef, 0xc51fdc13, 0xc53bfcfc, 0x04fdd57f,
- 0x56f683d4, 0x715ba647, 0xabbf43bf, 0xf9fd0f4b, 0xb7bfe435, 0xb40bd736,
- 0xe7ae6e0f, 0x7aab957e, 0xc00d8ae6, 0x7ef38583, 0x828e78e5, 0x70447327,
- 0xcf1860ff, 0x95fb26df, 0x52bf439e, 0xb03f6336, 0x17787e28, 0xac509bb5,
- 0x467fa1f7, 0x7a08f6a8, 0x662e5b94, 0x07284836, 0x97ff5397, 0x5823ec2b,
- 0xd2567988, 0x398daf56, 0xbd5b7da0, 0xc61ead6f, 0x69399756, 0xbcd0b3cb,
- 0x1fc8c3cd, 0x94e668f3, 0xe7816b2d, 0xa25321ff, 0xf9104975, 0xf75f3f3c,
- 0xd03db9c6, 0xa5956b5f, 0x706ae508, 0xf3bb9279, 0x941bb1e2, 0xd5f2bf3f,
- 0xd1bfee0f, 0x671d75f7, 0x87ca029a, 0x24568bf5, 0x1d004732, 0x7ed08648,
- 0x74c81ff9, 0x27ac9ee5, 0x5a33d63f, 0xcfc893d7, 0xd7ff2617, 0xddf0bdc4,
- 0x3dcae979, 0xfe43a7a8, 0xea1f300f, 0xcf9ebcd1, 0x29e744bc, 0xbf40f352,
- 0x2c3bfd47, 0x941edd34, 0x95ad17db, 0x5a07e8fd, 0xd097a91d, 0x7e324fce,
- 0x0eea7e46, 0x83abb71d, 0x07e7f7ed, 0xb276edec, 0xedcbf7bf, 0xad5396ec,
- 0x8ccf7f99, 0xe45a263e, 0xf98840f8, 0x09b546d0, 0xab12af28, 0xf9024fc5,
- 0x4f523ba2, 0x498b047e, 0x6a983bf6, 0xc5017e54, 0x791dd06f, 0x6f7480bf,
- 0x7e415ae9, 0x6017f47a, 0x75e5077b, 0x2417f609, 0xe8b4ff19, 0xb51bd8e3,
- 0x23f206cf, 0x04fd1084, 0x27f8a1e1, 0xa3f1fb82, 0xccfb813e, 0x27d270ca,
- 0x397dc782, 0x6650e4b3, 0xff48f23c, 0x7e503bc9, 0x7ed1d29f, 0x84bd1c38,
- 0x1fcce149, 0x266f7ed0, 0x7223efb7, 0x91f95462, 0x0fe644f6, 0x64b35ff4,
- 0x321127f3, 0x48cc5b0c, 0x51c6df7d, 0xbcdbdfd8, 0xbb3a13bf, 0xd841f48d,
- 0x7bfed0f6, 0xeee7e64f, 0xab69465c, 0x01b7976c, 0x9cfa631f, 0xd9fa4cd7,
- 0x843fe036, 0x4a257bb7, 0x4a1cdefd, 0x54ed7a77, 0x4c5bcbbe, 0x83af1ef0,
- 0x72debde0, 0x9d79f74a, 0xb792ff94, 0x7a9fe082, 0x7bb6945d, 0x15ff286b,
- 0x03e087af, 0x5f8206de, 0x44507d45, 0xa533753f, 0xa85b786f, 0x46dbd3bc,
- 0x3f5e9bf0, 0xbdde5da5, 0xdbc87f94, 0x6f11f04e, 0xbcc7c107, 0x78f7045d,
- 0xdb7d287b, 0xeff94bdb, 0xdc134f78, 0xb1938f2b, 0xfa2f5ee6, 0x84a25c2b,
- 0xaeb3ddfa, 0xd7ea336a, 0x331a65b6, 0x9736f38a, 0x39fa0566, 0x78f255b6,
- 0x86956d9f, 0x87a040fc, 0xb39f51fa, 0xf8fa7b2d, 0x405f2a34, 0x49b15be5,
- 0xabac4a30, 0x56cafeb8, 0x159ea9ea, 0x77c1020f, 0xfd2b6adb, 0xb25b805a,
- 0xbadca9c3, 0xedbb244a, 0x3a278d79, 0x245deb9b, 0xae3aadbf, 0x1074283f,
- 0x22e9fb21, 0x974a44b2, 0xa3fc7365, 0x23ef4232, 0xfc4a5919, 0xc707b9a4,
- 0xf182ab67, 0xf555be21, 0x5a5f8c46, 0x49f183ef, 0x3aae3fa4, 0xc3247804,
- 0xc07f1178, 0x6cc2fc87, 0xad97d719, 0xaf08eb55, 0x94f365e4, 0xda346778,
- 0xfa9e6de9, 0xa56f84b9, 0x36cd7e48, 0xfbe8a1d7, 0xe7ca4e50, 0xe1f1ac7c,
- 0x50fe7f4e, 0xf082327c, 0xddb8c6df, 0xd2fa0c90, 0x00e310fe, 0xc7a9478b,
- 0x198f78fd, 0x26f1fa43, 0xb2627acb, 0x3d8ff9c0, 0x6dff122c, 0xc1f7a067,
- 0x7e81cf77, 0x503943e7, 0xfa156fba, 0x72cd1eab, 0x3c02cc4d, 0x3f8d247e,
- 0x531c0224, 0xaf4fdbce, 0x1ea0f717, 0xae7deb0d, 0x3e37f209, 0xb689d9b8,
- 0x6966ec71, 0xdb5bb22d, 0xd01357b2, 0xa82c95ff, 0xcb4947d7, 0x3bb63c65,
- 0xd5cf7b78, 0xb64fe48b, 0x76903aae, 0x865bf784, 0xfa8e26fd, 0x61ba187d,
- 0x1a481632, 0x55c91914, 0x2fec45e2, 0xe5cda1ec, 0x66fc5fd8, 0x215fd287,
- 0xe775f7f6, 0x65e3e469, 0xbc085756, 0x37279386, 0xb38b2393, 0x8e48e322,
- 0x9424b124, 0xb8ebcf23, 0xe49df2dc, 0x861d24fa, 0x1fb43499, 0xc4ae7e25,
- 0xe8e383d3, 0x243d3235, 0x61c74219, 0xfde80d57, 0xddb7aa3e, 0xe749c9b1,
- 0x0b3e304b, 0x6c75ab45, 0xeaf3ae05, 0xdaf37092, 0xa4a0f410, 0x018e505b,
- 0x468bdfdf, 0xb9b3b523, 0xe1a3b79c, 0x56cadced, 0x32625c11, 0x6bc842fb,
- 0x6e5a7d25, 0x4e2c81e7, 0xbe0f49b7, 0xae18f1b4, 0x3a3adbef, 0xc69cf413,
- 0x04ed11bf, 0xc92d09df, 0xfb6d44d7, 0x78013d8e, 0x79e3cb35, 0xb5cfef4e,
- 0x7b40ff23, 0x915728f9, 0x7fc9f25f, 0xcc0566c1, 0x5addf2bb, 0xa3fd8fd9,
- 0x29a21b6b, 0x2eb55cbe, 0x36a3f50c, 0xb07a2466, 0x85d13cea, 0x4560f401,
- 0x1f410cba, 0x4af4b2fb, 0x3254d53c, 0x7c32e311, 0x728a9e5f, 0x583ef009,
- 0xe1fb451d, 0xdeef65d4, 0x5be01639, 0xd47688ae, 0xe5ab9ecb, 0xfd2713e7,
- 0x26e74351, 0xdb9c7cde, 0xb7fdb77d, 0x7bf41eb2, 0xb3e9c827, 0x7a41e768,
- 0x77b3334b, 0x52dcbac1, 0xcdff226d, 0xb3c557ad, 0xb91a7681, 0x7da3c7a4,
- 0x5335fdc1, 0x803ca1fa, 0xa67d26fe, 0xaa330fae, 0xa1233d45, 0xab6f9d4f,
- 0x1a66703a, 0xcb56d3f4, 0xf6bb6e3f, 0x7d8471fe, 0x93f21af5, 0xf429f500,
- 0x4dfe4093, 0xe78097d1, 0x191a3716, 0x32eb73c9, 0x41e519a3, 0xe49c25b7,
- 0x1362db5f, 0x321ba1e9, 0x9ea18757, 0x8faaa86c, 0xdea474c6, 0xa77d03b7,
- 0x7dffbbdd, 0xe4812d9e, 0x817f3f2d, 0xfa0c5984, 0xae7abdc0, 0xb6faf8e4,
- 0x7944cb4c, 0xc3f2a1a9, 0x8b7dffbb, 0xac077d0f, 0x3490f085, 0x7e0f912c,
- 0xe29bbe00, 0x2fdf02d4, 0x444e6740, 0xabae74f8, 0x4243e507, 0x8b1baf9c,
- 0x56ce9ab6, 0xcae2f9d2, 0x5d33e238, 0x31e987b5, 0x18c8b2bf, 0x9f0ae7c8,
- 0xfffcb5fc, 0xbbe71cb4, 0x59b81c99, 0xf7e337bb, 0xbe73a59f, 0x369ece19,
- 0x154f230c, 0x9acf18fb, 0x4b6c8a63, 0x7d59eafb, 0xf6eafd48, 0xc567ce6c,
- 0x643e7e7a, 0x72f4c54e, 0xfaf8c38a, 0x96c73c44, 0xa9f9cd93, 0x714912cd,
- 0xd674b6e2, 0xdf037185, 0xf7f70d72, 0xdafff1c4, 0x3fc9d32a, 0xa2782ad4,
- 0x3e78197d, 0xeb8695c2, 0x147306d7, 0xa6b7fd09, 0xfcceb972, 0xabc6331e,
- 0x409a9da1, 0xf3dec1fc, 0x9198e9a9, 0x0bfe4c3e, 0xa49ef12d, 0xa3b7f00f,
- 0x17fd1c5f, 0xdadddfc1, 0xbf6f86af, 0x984b86aa, 0x354f054e, 0x6669e1aa,
- 0xe6c96c35, 0x361dfa7a, 0x490cfe75, 0x1ca7270d, 0x73f0d309, 0x7f01a6ed,
- 0xbbf044b3, 0xa07e0199, 0x01769a0d, 0xafa525e7, 0xadb2fc96, 0x93dfdca9,
- 0x73f6af5c, 0xb596b224, 0x6df90231, 0xfcb6f954, 0x73fa0255, 0x7cead56c,
- 0x8c150798, 0xbff48acb, 0x9f95d724, 0x02e9718d, 0x4b3aee7e, 0xc5cde9eb,
- 0x238b6875, 0xcf934a3e, 0x1fdd0d05, 0x95b8d0b7, 0x7c0f9076, 0xfa45e301,
- 0xe62f840f, 0xc76726ba, 0x05f03e73, 0x7df997ee, 0xa503e43a, 0x41f8e1bf,
- 0x3962c7e1, 0xab9ca26e, 0xa5b722b9, 0x97a9ab9c, 0x0475c7cf, 0x92b9c79d,
- 0x81e7465c, 0x09aef4ae, 0xc877c50f, 0xce6cbe67, 0x946e9877, 0xdf20d7cf,
- 0xef9cf4f9, 0xd5f0df30, 0xfd28672a, 0xafbcbcf0, 0xcc37b43c, 0xf8c071fc,
- 0xab47b656, 0x82477760, 0xd3bcf039, 0x740ff843, 0x3a3337ba, 0x0f2b5a47,
- 0xbf338be7, 0xe908d3db, 0x0b975a5b, 0xd66567d7, 0x338f3d59, 0xfe51ebf5,
- 0xdff7979e, 0x38dd820d, 0xdb94c05a, 0xbb668da5, 0xccbdfd11, 0x57f2a19f,
- 0xd5877e28, 0x31acd22b, 0x0188ff80, 0x4cd3823f, 0x33e34de7, 0x35118fc9,
- 0x2b3771d5, 0xccf73c04, 0xa2046f98, 0x554e85dc, 0x658fc790, 0x97d0fd97,
- 0x035e383c, 0xce02abfa, 0x0f441923, 0x3573b923, 0xe7014995, 0xff655bca,
- 0x9b1f00c5, 0x7f609796, 0x7896cc3f, 0xd679863c, 0xda9fff72, 0x6ab8665f,
- 0xd833b553, 0xdfaab27e, 0x722fd956, 0xfed5f6f3, 0xf4d5c337, 0x0ecfda61,
- 0xb21cdf6a, 0xd576c1fd, 0x11afbc7e, 0x3e436f1f, 0xb5ffce18, 0x1ba7965f,
- 0xf45e9e6c, 0xd818e97f, 0x06071495, 0x6a8898fa, 0xc369ff23, 0x5d5379f9,
- 0xa60fdab2, 0x1f927e63, 0x90d647cf, 0x3e6048fc, 0x9859df8a, 0x47d7f287,
- 0xbbf1e74d, 0x1371b960, 0x8798c179, 0xfd00dea1, 0x3f57f2a9, 0x46d3f7c2,
- 0x3c42eec1, 0xfff3c783, 0x89abdd8a, 0xfa4bdf1c, 0x64b84a73, 0xdbde81b8,
- 0xe32575ea, 0x3dc21bf7, 0xfeeb1835, 0x762ebb3c, 0x1b3de83d, 0x7c08c630,
- 0x71bb3576, 0xfb84cfbe, 0xf58fa724, 0x27a21a71, 0x1d96ddcb, 0xb27a00da,
- 0xa8695de8, 0xf2345af7, 0xa1fc2f39, 0x65bd6cbf, 0xfd10a6e7, 0x029bfa2b,
- 0x8f002b5b, 0x956dba00, 0xfe81e6f5, 0xd0ee2496, 0x3163b406, 0x3fa90ab8,
- 0xd2a35ce5, 0xeb37d35f, 0xf7ecab6f, 0xdeb3fa52, 0x559f1ea3, 0x59f1a1ef,
- 0xe947fde5, 0x2f8e2b6f, 0xb4dd5f04, 0x1e8ed93f, 0x7aa96fe8, 0x8783567c,
- 0x72d567c6, 0x7f40e1ff, 0xbfacdf4d, 0x931ef936, 0xe1d3e64d, 0x0e37fdce,
- 0x1a76ab9c, 0x29b4ae51, 0x7f7940fe, 0xbfb414bb, 0x37f796ad, 0x714bfbe5,
- 0xbddfe4e9, 0x18df33d4, 0xfdc35f6a, 0x247ac98c, 0x2648f593, 0xcf0891eb,
- 0x3ea67a99, 0xf0b0e81e, 0x22f9b6c5, 0x1e73e3ec, 0x153e333a, 0xf62f19e0,
- 0x5f6117cf, 0x99e2f39a, 0xc9f04903, 0xccbe2fcb, 0xe6787fcb, 0x9b94324a,
- 0x2fcdef7c, 0x962a3803, 0xde0ac7ef, 0x8db7bf4a, 0xbba37ae2, 0xbfee73e1,
- 0xfb8af904, 0x87aa6356, 0x42f17fa1, 0x32d47f72, 0xe94eefa8, 0x310f2cb7,
- 0x6eea4a2f, 0x467e4f38, 0xff287914, 0x40bfe1e6, 0xee53cfb4, 0xefab9467,
- 0x6d454467, 0x8c2ffd22, 0xef28cdf9, 0xba0e8c22, 0x28d6f84f, 0x642c1fbe,
- 0x376e0af6, 0x39f25948, 0x31cfba0d, 0xd76e58bf, 0xb1cfcb7c, 0xb1c6a17c,
- 0xdfd9ed1e, 0x478aaa4e, 0x173958f5, 0x7f783797, 0x1bf5d772, 0xbe0e1f9c,
- 0x23e7393f, 0x23c2eb81, 0x3ba5bfb8, 0xb9f7e257, 0xa886fc02, 0x9f370ef7,
- 0x7db8a3b5, 0x0e9f383f, 0x0e319f3e, 0xfee69f3e, 0xfeb0b5a8, 0xcb7ee8ee,
- 0x5d9fc413, 0xc86be721, 0x5fcd06bc, 0xd8a628fd, 0xb7a45a79, 0x32b7cd9b,
- 0xc1f9caaf, 0xa2ca4146, 0x794feafd, 0x3183fd2a, 0x8e2a14bb, 0xb819f483,
- 0x4e6deabf, 0x5d19fe86, 0xcf073d9c, 0x45fe3795, 0xde5cf21b, 0xd63e796e,
- 0xb9d38546, 0x3d28c6ce, 0x51dddbd9, 0x97fa1933, 0x9a74d345, 0x72a8b297,
- 0x8da96f3a, 0x8f68ed65, 0xd7239f06, 0xce9bb88e, 0x68ad6901, 0x703a4041,
- 0xa461d92e, 0xe8b989f8, 0xc5c8e786, 0x8f239d9b, 0x91cfc999, 0x7425e947,
- 0xea45b459, 0x7f239e43, 0xf7df146c, 0x713c71bb, 0x278c3f88, 0xa21c706d,
- 0x31d1c799, 0xf5f2023f, 0x7f231766, 0xc7de3cba, 0xea5075e4, 0x861ecc1b,
- 0xb7ab40f2, 0x68a7a84b, 0x613ef9c3, 0x4e5869b0, 0xf7c8bf08, 0xfbe8e947,
- 0x34cd724f, 0xd7231aaf, 0x5afce7cb, 0x7a4fe908, 0x4fe29475, 0xc3674d0a,
- 0x0d3cc9d1, 0xf0a7473f, 0x9e9302e1, 0x302df7ce, 0x0fd14ad9, 0xef0800b2,
- 0xfa8098b3, 0xf7e22db7, 0x0dbb4581, 0x5337e7e9, 0x6ff9ff6e, 0xb9f9ba18,
- 0x43353e7c, 0x4ee3f747, 0x8f61cc09, 0xd57e7a19, 0x869e8ce9, 0x66bb9a6e,
- 0xec87599d, 0xeff2e2f7, 0x867b6115, 0x167553e3, 0x779fec89, 0xa85ca146,
- 0x0f1f5b4e, 0x42caa2f0, 0x94dfdd1d, 0x08ee44e3, 0xd19fc72e, 0xa28e4eba,
- 0x51e7d178, 0x624748a5, 0xa3e22a7f, 0xea0289c4, 0x9e2a37bd, 0xd7e1cdea,
- 0x18dea0c5, 0x7f67d394, 0x1eb462ef, 0x127a50b6, 0x302c4fda, 0x07cb236e,
- 0xf302a3b4, 0x01627ed1, 0x2f2c27eb, 0x9085f6b6, 0x609a4a17, 0x0d5292db,
- 0xd0909e7c, 0xff92a942, 0xee5b43ac, 0x57aeb10f, 0xc6fd75e5, 0x601b4c76,
- 0x8ed0713b, 0x2ae5fb01, 0xd517dbce, 0x61e32ca7, 0x17657548, 0xe9b18ec9,
- 0x88933e15, 0x1e6106bf, 0x45fb04af, 0xd5b0de75, 0xfba14beb, 0x6d38f2fe,
- 0xa346d62b, 0x1c55031d, 0xbcdb9f48, 0x9965296d, 0xcec8e383, 0x8d13e991,
- 0x17a889b6, 0x5c725ff3, 0x97f40ccb, 0x74349b24, 0x5326013e, 0x6e612f75,
- 0x38b4f459, 0xccdd4534, 0x2ed0926e, 0x3f3d25ef, 0xf896bae1, 0x62f0e120,
- 0xa4ab7186, 0xef0176b8, 0x23f40d03, 0x97ae6fdf, 0x5c57b9e3, 0x048e3465,
- 0xcefec0eb, 0xf38d0ec8, 0x747945cd, 0x518e69e5, 0xe5d58fc2, 0xdcfc71c9,
- 0xe1d5fdc2, 0x3ae8097e, 0x4057b6a9, 0x380c0138, 0x5c27c5f4, 0x426b4c6f,
- 0x045af279, 0x6db58bf9, 0xf207cc99, 0x45745527, 0xfb3ce0e5, 0xc9a6ffa5,
- 0xdf0b0790, 0x9c207cad, 0xa136b3f4, 0x25d90665, 0x285869f7, 0x1c98cf3f,
- 0xc828c7ee, 0x609ffce1, 0x1ea94d6b, 0x44d3e987, 0xcf975f37, 0x1db39067,
- 0x9f11d9f4, 0x1c58fa2d, 0x759a7bd4, 0x9b73e9a1, 0x7ec0efdc, 0x185fcf21,
- 0x7f911973, 0x3b9382b5, 0xdbeef739, 0xce82cfb7, 0x55e74613, 0x8d7ac936,
- 0x4e444ed2, 0xd846153b, 0x45cf0c1d, 0xdf07660a, 0x9b3ecc07, 0xf9abd60f,
- 0x7b486d2b, 0x791cc1eb, 0xb26b491f, 0x4cb2fd61, 0x94fd0dbb, 0x1a55f7c1,
- 0x70da26d3, 0x0c671a7d, 0x7031a9d0, 0xcb4ee85f, 0x53cf1f7e, 0x2c747a99,
- 0x70591cf0, 0x2173c7aa, 0x972837b1, 0x1d3797cf, 0x9b42e7e2, 0x78bd454c,
- 0x14c9a10e, 0xfec74457, 0xa99cfc4c, 0x3a64df52, 0x64def246, 0x1356f1e7,
- 0xa2020fee, 0x3ba1e7c7, 0x83cd18ed, 0x0e5a6f52, 0x7b26ab97, 0x5bfbc317,
- 0xd53f76e1, 0x3e9d130b, 0x161fe00d, 0x4ffee8c7, 0x55f39198, 0x318fac04,
- 0x7e95ef80, 0xd1d1cb6f, 0x172535bc, 0x7e1096f5, 0x6704de22, 0x1b22b64d,
- 0xdf38dbed, 0xb4636fd0, 0xaf9cdf42, 0x5be7971f, 0x3e51a769, 0x434f7aff,
- 0x58b2fcce, 0xd73913f4, 0xa6bb60e4, 0x83b446e5, 0x6fe391b4, 0x6186ded8,
- 0x285e6bdb, 0xf238f7b7, 0xc8b23685, 0x50e9ed8c, 0xc3a0845e, 0xfe76e467,
- 0x30ede357, 0x97df74b3, 0x9f305a60, 0xa3de942d, 0xa38c46a4, 0xddfa1b8f,
- 0xebbf9637, 0x90247ed4, 0xfc717bbf, 0x1ecf932b, 0xee1ca12b, 0xdb2eda3f,
- 0x619d8a27, 0x2ededb91, 0x3ee87bf0, 0xef4edc21, 0x8776c836, 0x0f3d4c25,
- 0xf941f783, 0xe0ae5c3a, 0xc72ee6e7, 0x046b8a31, 0x77e5f3f3, 0xb40e8a3e,
- 0x73ef504f, 0x04bb7364, 0x1c4bb453, 0x610d9fb2, 0x9da01bf4, 0x80fdf0a2,
- 0xfa42b75f, 0x3f005ba7, 0x0d6fc803, 0x7b242bb4, 0xc90dbe88, 0xe7c8697d,
- 0x053bf2a9, 0x5cd7f643, 0x4785a72e, 0xfe434b3f, 0x4feb8b2e, 0xf982efc0,
- 0xae4785fc, 0x5e78e026, 0xce703198, 0xab43e286, 0x7bf3a717, 0x1cffc7d9,
- 0xfed10aed, 0x457feecd, 0x86b4dd9d, 0x5ce5c0f4, 0xdf5bfc0f, 0x8cbedb07,
- 0x821d9deb, 0xcda4efda, 0x5fe77ae5, 0x7acc7de4, 0x2df7a455, 0x2eb965ce,
- 0x0ab61f20, 0x7f28e5e6, 0xe7e11f53, 0x5e3f56e6, 0x2103d9ff, 0xed1841f8,
- 0x804e73fa, 0xacdc5c3d, 0xa35a3f27, 0x8dc47d29, 0xafc31ce2, 0x71cb87b3,
- 0x1e4b7d79, 0x24f3f235, 0x5b17ae2e, 0x39d3f75c, 0x23f3e095, 0x243bd5c3,
- 0xbea53dcb, 0x7947db01, 0xfe479a62, 0x23684b80, 0x964dbfa0, 0x7678c17b,
- 0xf3c864e2, 0x12b90463, 0x18456875, 0xed93abb6, 0x3f8aedb1, 0xe8c8a2a3,
- 0xb75ef808, 0x1a58c8b8, 0x8c8d2f40, 0x6e0ddf9f, 0x01dcceff, 0xafa55a7d,
- 0x459f70e8, 0xf89c50df, 0x433901a7, 0xcab8658a, 0x0ffa518e, 0x70163f3e,
- 0xf38c2c5e, 0x5a67b729, 0xe818dcf1, 0x962b6bb7, 0x6df9c48f, 0x582f5d15,
- 0x3ffa1e61, 0xe739d030, 0xecbe650f, 0xb872f993, 0x43b1f3f5, 0xf6318ca0,
- 0x97823b04, 0xc64e80d6, 0x68fe408f, 0xfb94d4cc, 0x5cb38c43, 0xfd08671e,
- 0xafdcd6fa, 0xe6975fa7, 0x51afd086, 0xc504767f, 0xd461021f, 0xf4211d9b,
- 0xec8213eb, 0xedcf900f, 0x1d49d09c, 0x270f307d, 0x6f611d6e, 0x919ee894,
- 0xf6045ec3, 0x32678bc3, 0x239f6f51, 0x23c7bc0c, 0x608c31db, 0x221623b0,
- 0x6799735e, 0xc50203df, 0x48ee5a51, 0x5c04eea3, 0xa7ad9b8f, 0x3711fb24,
- 0xdc613ac2, 0xb2daf5a1, 0x0ce2a119, 0x274038ff, 0xef02ba28, 0x042ac007,
- 0xc48695c4, 0x63e282cb, 0x38194e18, 0x5a1dabff, 0x7562aeff, 0x35e36afc,
- 0xac30bfee, 0x0427fe60, 0x2eaa1f3c, 0x0bae5f9f, 0xe2a9cf8e, 0xba9d0b5a,
- 0x887c7c60, 0x6f8cb26f, 0x2907b6ca, 0x452d3e0e, 0x64acfde4, 0xc707cf64,
- 0xbd850cbd, 0xc3ea2d0e, 0xf7f48c15, 0x9e363f60, 0x5eff2517, 0x09cf6305,
- 0x7d5ade74, 0x59e9e4df, 0x1cfbf8e7, 0x8fd8e52d, 0x50c3532d, 0xafbe0e3f,
- 0xf09bc4a0, 0x7de04c98, 0x22dde569, 0xe10d62cb, 0x53b77cc7, 0x8797e2b9,
- 0x4b12a6fa, 0x55eeb9c0, 0xdd3ea06c, 0x1e85f2a3, 0x59d6d6f7, 0x1c4fef14,
- 0x82ec29ef, 0xa33b24a2, 0x66aa4879, 0x3cc00764, 0x86fae2a8, 0xce345d94,
- 0xc58c354b, 0xaaa038f2, 0x7076013c, 0xbf184fa4, 0xe30fce2a, 0x76c1c154,
- 0x4deccde7, 0x0de64a43, 0xfccdf9e5, 0x5e39068d, 0x646e46f8, 0x633be91c,
- 0x77d418d8, 0xa69f8b2c, 0xeb04b8f5, 0x34597e81, 0x03c54284, 0x68fb4337,
- 0x5f90ba07, 0xc4dfd1e2, 0x30caef54, 0xc9f74887, 0xb38e6284, 0xf1e4eb10,
- 0xfc467ce1, 0x9507086d, 0x9859f80b, 0xbce0706c, 0xc3000c1b, 0x333d0590,
- 0x56be4026, 0x15af37f6, 0x33308898, 0x4fdc8ddb, 0xe36bbca8, 0x866d77a7,
- 0xff7407eb, 0xcfec30be, 0xfa53bfc7, 0xdb8ef219, 0xfb27be0d, 0x7dfc1ccd,
- 0x951df919, 0xff9b87fe, 0xfb6ddee1, 0x2777d4c3, 0x3267bf70, 0x20e56bd1,
- 0x4cbc12bd, 0x1efc47a6, 0x4abdc2e5, 0x0c77adb1, 0xfb3c37de, 0xfd1d8470,
- 0xf0e303e0, 0xefe5a9dd, 0xed75fdd1, 0x9361e00d, 0x8c0fbe48, 0xafef6e4b,
- 0x02fd171d, 0xbc06dae4, 0x4fe78434, 0x279d192a, 0xcf4ab8b0, 0x000e7489,
- 0x1392a0c6, 0x4013ef01, 0xf10e1b7b, 0xf15baf73, 0xb0710b9d, 0xd02bd45f,
- 0x4255b06e, 0x483b087e, 0xbf19ab49, 0xd5e0ac1f, 0x1a3d07a8, 0xf5c352e9,
- 0x3ea6d9e8, 0xe935cf11, 0xe445fae2, 0x2e68e71f, 0x37e807c7, 0x0bf9d19e,
- 0xce7c926d, 0xdfc4a471, 0xfbe4cb4d, 0x84cfd29b, 0xfe591ad1, 0x47fbd2f7,
- 0xd54e23b3, 0xf2c6764b, 0x442fc5f6, 0x11ecfcff, 0x00d3eaa7, 0xe167d82e,
- 0x2ba9d270, 0xecc66669, 0xd10bacfb, 0xef3b3f9f, 0x807495d4, 0x78d9f68b,
- 0x464614f9, 0x097df8ce, 0x319fd10b, 0xd559b461, 0xd7385bfe, 0xd53cdff1,
- 0xcf21341a, 0x5a36df63, 0xe8c94f39, 0xf3b3ad3e, 0x2e31a797, 0x47f654e9,
- 0xdf482e87, 0xde0b2281, 0x717f9323, 0x9d0f1451, 0x9dd9d329, 0x1452eef8,
- 0x68bb2dfa, 0xfa0d477e, 0x6bfe9fe9, 0x4382f4fc, 0xccca9779, 0x1bff812a,
- 0x2c2b981b, 0x99ee8023, 0x9f9d7343, 0x81b8a603, 0xffd28f82, 0x6960bc10,
- 0xbc4098c5, 0x0a3b51b6, 0x0d0a175e, 0xc70587a4, 0xfd082e87, 0x549cf1db,
- 0x2fd6cfc4, 0x10ba75c2, 0x002a9fd9, 0x9eb79e1c, 0x7c42edd6, 0x1ec176ff,
- 0x3af8eb00, 0xa22bef56, 0xd6a3fc75, 0x027a3d51, 0xdfc5dbbe, 0xe396686f,
- 0xbbc64f50, 0x019f687c, 0x32b9d1dd, 0xfc9e8a5f, 0x05e36548, 0xb03fa047,
- 0xcbf7346e, 0x69d3925c, 0x49cf1686, 0x01f74ba0, 0xfa85ad81, 0xf5976bee,
- 0xeecc9fa8, 0x3d47a33c, 0x19c0eeba, 0xad4bde3d, 0xa9da1843, 0x8477a6db,
- 0x32feffd2, 0x97f2ab5a, 0xd1d77629, 0xe8f5ec94, 0x16abab77, 0xeade1ee8,
- 0x6e1fb9d7, 0x251c32f5, 0xb2df7763, 0x55b8fc9f, 0x98f5eece, 0x477d652e,
- 0xc588ddf1, 0xdceaad2e, 0x089a92c0, 0xcabe3c55, 0x9782ab13, 0xc0eac0b6,
- 0x21b4bb3e, 0xc31df549, 0xef82cf5d, 0xd0fe0e28, 0xd790affe, 0x736db171,
- 0x16bbfa2f, 0xcc7ad4bb, 0x62b5ceec, 0x11ede20c, 0xfece1aec, 0x84b77e12,
- 0x00d2108f, 0x7de60abd, 0xa3d7075a, 0x648c2aea, 0x0c22549f, 0xab595af3,
- 0x7393e3f5, 0x54f45347, 0xa810eeee, 0xbb972ddc, 0x576e046b, 0xa975f2cb,
- 0x8392e38c, 0x75d1a727, 0x37a39f52, 0xa5df0033, 0x88e7e515, 0x437d651e,
- 0xc4855719, 0x290d8df5, 0xddb0e9ef, 0x5817dfa5, 0x4b8d1a6c, 0xa92d47a5,
- 0x1e55c351, 0xd59e905d, 0xbdf943a7, 0xff9d41b4, 0xbef2d1f3, 0x90f2c79e,
- 0x2d18de9f, 0x07189f88, 0xbca53fe1, 0x81ef0277, 0x0f3ad25d, 0xead67d22,
- 0xdf700abb, 0x1175a4bb, 0x7e4394ac, 0xb8afdf1d, 0xce01a2be, 0x751befc3,
- 0xa7de330e, 0x8814adf5, 0x00b0976e, 0xb06d27bd, 0xa1dac13e, 0x7722bf70,
- 0xe4f59cc3, 0x98283d0f, 0x13286f51, 0x83de221d, 0x8fc61c6f, 0x83e6517e,
- 0x1f2fac13, 0x2246caf1, 0x9eca7585, 0x99f6823f, 0xf996b7ec, 0x3d948e30,
- 0xc4bf204e, 0x4371809d, 0xc922a611, 0x37b03991, 0xad9a4184, 0xf920af6d,
- 0xe66f563e, 0x58da62ef, 0xfc70bca0, 0xbe701333, 0x0bb27510, 0xfde87b93,
- 0x9b6d39bd, 0xcc5ca22f, 0x3d1470cc, 0x193df805, 0xf27ffbc6, 0x16bfc175,
- 0x3fcba9da, 0x0ad3f246, 0xd6fd81e4, 0xda3964d9, 0x5acff6a1, 0xc121ae51,
- 0x7ea7cacc, 0x32f89413, 0xc3ed15d0, 0x9fa4a55d, 0x9f7ee558, 0xddb8942d,
- 0x2e7ca0fc, 0xe2d6f98d, 0xd1befaf9, 0xf495f28c, 0xcaabfb1b, 0x5e283104,
- 0xe61a3750, 0x4fada579, 0x5be9de75, 0xe901bf6c, 0x187db82c, 0x395e2abe,
- 0x8a2d7b4d, 0xcc1d77ee, 0xfee8deb0, 0x3ea8d694, 0x8733a4b7, 0x53bbdd07,
- 0xf6d99fcb, 0x777ba0a4, 0xeef74119, 0xddee82f2, 0x2df9efa9, 0xba094e74,
- 0xe7bea777, 0x54cdb067, 0xe6930fd5, 0x9c88e0a9, 0x23f555bb, 0xe7d5cbed,
- 0xbcff8eae, 0x77c74842, 0x2e7d7d06, 0xe0668798, 0xc198e28d, 0x0a2f247d,
- 0x3e1a432a, 0x6984cc2e, 0x0ba1a173, 0x9139a4e9, 0xe386e7db, 0xa0badb0f,
- 0x9788e31d, 0xfc6fe88c, 0x452fe089, 0x9f28c4fb, 0x18fd1953, 0xaf33ed53,
- 0x52be7015, 0x5cf2dbd2, 0x7d61f3b3, 0x494af7f2, 0xdee01dfc, 0x463eb8d1,
- 0xf9036c7c, 0xaf7e55e6, 0x476cac78, 0x5f3ced28, 0x0f353258, 0xcc7fcfbe,
- 0xece28331, 0xf07efc1d, 0xa78f3d4e, 0xe7e55ef8, 0xfa3bf35b, 0xfe008e34,
- 0xf5c7993e, 0xa59c6790, 0xeba91f14, 0xf9165d84, 0x1eaceda9, 0x75d465ef,
- 0x7ee14776, 0xab3ce056, 0x60c9bf47, 0x89cfbcbe, 0xaf68e1fd, 0x743dacff,
- 0x9e6d6d3c, 0x98e3f89e, 0x1eabd72c, 0x91bb72d6, 0xb9e16639, 0x575e4571,
- 0xabe3e7ed, 0xe7e7a85a, 0x1d1a3160, 0x9c836e42, 0xc396ab3e, 0x707ef50e,
- 0xca3d7f8b, 0xaadf900e, 0x4c174b7a, 0x12b7bb27, 0x31f236e4, 0x797573c8,
- 0x17c91372, 0x7caae790, 0x3c80de77, 0xdf0ebfcf, 0x426a769d, 0x8170f38e,
- 0xda78f348, 0xffe69535, 0xf4479819, 0x64333da7, 0xde7cf8de, 0xc65ebe6c,
- 0xb7580fb5, 0x2ebf7ae0, 0xf2f6ebe0, 0x7dfaf230, 0x0a775d79, 0x4c2845bd,
- 0xa270cedd, 0x634625db, 0x387b9e09, 0x1365f296, 0x7eaae1c6, 0xfd3dd02e,
- 0x6e3eeb7f, 0xbf5ffd41, 0xfd05a8ff, 0xa3f6ee61, 0x594db016, 0x8b5a4ead,
- 0x85d03c7a, 0xba9ef51d, 0x7fc22e8e, 0x6eb8fb65, 0x21d95fcc, 0xee3dfbd0,
- 0xd3a71703, 0x135f5938, 0x0e770bc6, 0xf28fd783, 0x37befeb8, 0x307ee24f,
- 0xfb89f417, 0xdf8301fd, 0x801d202f, 0x5ebc425c, 0x35e5f017, 0xb1a373b6,
- 0xf51e9422, 0x1f7cf26f, 0xe867a8d9, 0xef85afaf, 0x52c71c71, 0x488de98e,
- 0xb205fb47, 0x27edddb5, 0xfb604617, 0xfa863af5, 0x17df8285, 0xe21fbd29,
- 0xd6a83ff8, 0x3580a7a1, 0xbe696b56, 0x52d7a83f, 0x74fbda3b, 0xc15e2f04,
- 0xae1c55cf, 0x0929a8fe, 0x56a0fdda, 0x530c7ba0, 0x31f3fbef, 0xe0af1784,
- 0x3d305afa, 0x4c1af42b, 0x3bf4c19f, 0xbe6b4e84, 0xc91e9d19, 0xe4d5ef93,
- 0xe7dc02b1, 0x59a7dd61, 0xe11e7e91, 0xae2be3f7, 0x7fa1d61d, 0x6cc9bd33,
- 0x31e0027f, 0x0b7aff5a, 0xbcc389ca, 0x8776b0bc, 0x748de5c0, 0x5261f237,
- 0xbda19eb3, 0x971e7efb, 0x7ae3ef4b, 0xfad0e3c5, 0x31af8c05, 0xe51d37b1,
- 0x4f1c9a52, 0x2ac7457a, 0x905c53f6, 0xaf319bcb, 0x96ef54d9, 0xbd71e537,
- 0x40839143, 0xe4fdaee6, 0xc44f6d97, 0xcb2f147b, 0xe55341e7, 0xfa32b2f6,
- 0xf485cfa7, 0x672f4caa, 0xf8143c64, 0x6cff4cb2, 0x1f68cfdb, 0x59c72d9f,
- 0xd1743666, 0x833ccc79, 0x879453eb, 0xabdf52b3, 0x39ae7dc5, 0x3a7cedfd,
- 0x25378d67, 0xc9fbe226, 0xd27877fc, 0x60d6dba7, 0x9c372fdc, 0xe0ec31d6,
- 0x381e7453, 0x35bc6b2c, 0x49439c54, 0x7a2557dd, 0x6aeeb08f, 0x3c0aa53a,
- 0x7d39d0f7, 0x1701d91f, 0x5c9f13a7, 0x2ddea9b5, 0x7bc654fc, 0x5d3ef28c,
- 0x80f3f727, 0x8b8b169c, 0xf329eb06, 0x1c659e80, 0x2ed6586f, 0xab35af5a,
- 0x75a92158, 0xcefe29ec, 0x0149ed66, 0xa458bddf, 0x304ce873, 0x608defdf,
- 0xfc8b1f25, 0x3657241d, 0x748c4dc6, 0xd784fb2f, 0xd7af704c, 0xaf29f046,
- 0x61ade944, 0x687c88ce, 0x4f11e167, 0xe1dbce16, 0xde275694, 0x8ef0bc57,
- 0x336ba64e, 0xd32e2fbf, 0x2d4ee5da, 0xeb9c6233, 0xc2e3e800, 0x5cf7fe20,
- 0xddfba44d, 0xa0fec3bf, 0xbf0d959f, 0xaf677921, 0xed1d38b9, 0x33dac2a2,
- 0x1bbb084d, 0xf51d3cfe, 0xff610f89, 0xf41ebd20, 0x72809b7b, 0xd3bd24e4,
- 0x8635795d, 0xd35979da, 0xcbf91d3f, 0xf740a6f7, 0xb8ec3e6f, 0xfdf2b7a8,
- 0x7873dc89, 0xf2fd1c2f, 0xb9a3f2b3, 0xd42ce91c, 0x243afad0, 0xddeb3bd5,
- 0x0a2bffa3, 0x20d8c3d7, 0x7e0a7afd, 0xc865a3df, 0xfb4a9bbf, 0xe421cca3,
- 0xdff469ef, 0xb071f365, 0x15e5a1ec, 0x9e165f7a, 0xe990ac93, 0x3cbcb838,
- 0xa13fc07f, 0xebefca73, 0xa1fe0108, 0x3fdfc62a, 0x2ba7bb05, 0xaab8f81c,
- 0x67f92a73, 0x0dc23caa, 0xd1c333fd, 0xeb4dd7e1, 0x28cff718, 0x818dda30,
- 0x1bb44d7e, 0x1f7faa99, 0x252b077f, 0x74f786f3, 0x14897ddc, 0x666bafcf,
- 0x795aef14, 0xe7a53475, 0x2120df5f, 0xfbc318ff, 0x6b7ee95b, 0x8cec86b6,
- 0xfeb53e95, 0xcb80a533, 0x7c052985, 0x60f95cde, 0x01b0e52f, 0xa2ec097b,
- 0x5db9f37b, 0xa9887514, 0x7ce0a5ec, 0xf28c97b2, 0x13101d3d, 0xe04257ae,
- 0x6941477d, 0xca977e0d, 0xd9ce885a, 0x72fefc3b, 0xe4d738f0, 0xf8553e73,
- 0x35f2317a, 0xe7076fd2, 0xe776e0eb, 0x41ac9415, 0x4c38da3e, 0xe65cab7c,
- 0x8c6d95fb, 0x16ddcbe6, 0x05f4f343, 0x0296736b, 0x78017e5d, 0x0bd23de0,
- 0x3444674e, 0xe5c17f7c, 0x3df3c08c, 0x6ba81c8a, 0x36efa70b, 0xc58bce66,
- 0x48cda373, 0xf9ded0f7, 0x9c46a98e, 0x38da7be7, 0x7dfd29ff, 0x1638b5d8,
- 0xae8269f9, 0xf2876f5f, 0x5133cee4, 0x784df7a8, 0xf22c7e7d, 0xfe7870e1,
- 0xcf1918fd, 0x1e12c486, 0x70bd8797, 0x004f6ca2, 0xba27ee7e, 0x87fa9de8,
- 0x6fd1181a, 0x56ffabf7, 0xbe7c7c87, 0xfb8cc233, 0x230717e6, 0x0bcabde8,
- 0x3de81a6f, 0x7df95a9a, 0x7d742fd5, 0x7cbf4873, 0x22f74b5d, 0x47fe6fdd,
- 0xfba3f22b, 0x3b9d0355, 0xc373a87c, 0x6af7dc45, 0xc39c673b, 0x5f6b5677,
- 0xc3f2dbfa, 0xd25486ca, 0x3ff8148b, 0xbe2746bc, 0xe45e7bf3, 0x8ea1e272,
- 0xf77d217f, 0x0b976ba1, 0x17ca7cf0, 0x44c7ff07, 0xb7ee6b94, 0x79444f2e,
- 0xe5c5fee6, 0x7eee5889, 0x4a13c22d, 0xc05eb95f, 0x7eca3efd, 0xa8aef699,
- 0x90ad0ff2, 0x5d6d23e9, 0x3d07bd0b, 0x7b02e4e1, 0x130fbbe0, 0xac4e34b2,
- 0x65b7e13f, 0x7c05f7b1, 0xa457aeb7, 0x93f8e338, 0x01d51165, 0x814f7974,
- 0x7e2ff14e, 0x930ebf23, 0xf019c7df, 0x77f2f4e3, 0x8af6367f, 0x1aa37dfc,
- 0x83a1ee81, 0x5ee432fe, 0x8affad1a, 0x88df7a58, 0xc73bce89, 0x8b38478c,
- 0x3e6205de, 0x00ccd1e3, 0xaf71693d, 0x7400cba6, 0xe869d154, 0x57befd22,
- 0xacb0433c, 0xf173dd3f, 0x2134c8d3, 0xe7267f84, 0xe39434d4, 0xf81a7ec1,
- 0x8ade2245, 0x71e955be, 0xc1fe20a5, 0x15a59bfe, 0x287f9077, 0xd6937fd8,
- 0x8f666a2b, 0xe9dff7c7, 0xf78c2f3a, 0x8bf22369, 0xfae287a2, 0xffc1081d,
- 0x3970c66b, 0xbad5f0a6, 0x5dff1e5e, 0xcc6a5bd7, 0xe656b484, 0x9db003ab,
- 0x75fda0fa, 0xa377f39d, 0xb5dd611f, 0x60631145, 0x3bbdd6be, 0xfc813d8f,
- 0x66352e6f, 0xeed777e1, 0x1fcc2e30, 0xfee097a4, 0xf2e18ca6, 0x184f4072,
- 0x97cbdf66, 0xed5bfaf1, 0xe463397f, 0x87ff6cf3, 0x87607fef, 0xedc31d8f,
- 0x4fdc25f0, 0xe0f0edc2, 0xc791437d, 0x792ebb4a, 0x63ca879d, 0xc04877fe,
- 0xec79265e, 0xbd51231a, 0xb1b9cee4, 0xbbbf4764, 0x0d325620, 0xb4433f6d,
- 0x87f2626b, 0x71e8afb6, 0xa8e39f6e, 0x871ced11, 0x1749fb96, 0x99bef408,
- 0x9db9f7a2, 0xeee3e902, 0xeb1f9d4a, 0x2ef57829, 0x85d57ee0, 0x4c3f9d0e,
- 0x150fd418, 0xdca071fd, 0xa2b9502e, 0x637a2a4f, 0x71fb93af, 0xe5e78c17,
- 0x16b986b7, 0xd87d7ce1, 0x13f94615, 0xc67cf126, 0x0093479c, 0x813df45e,
- 0xfacbff11, 0xc1a742a4, 0xcea5e6fa, 0xd7be1b8c, 0x4fa64db3, 0x8352cf85,
- 0xbfd943f8, 0xdd39f39a, 0x1dfee1d7, 0x7ff7fb8b, 0xe0f2f4aa, 0x7eff6176,
- 0x466ff108, 0x1fbe121d, 0x19d15bff, 0x4aff3eca, 0x5efe0bd6, 0x23debf59,
- 0x72af8825, 0x7db8764e, 0x6fd64eb5, 0xce6f2b86, 0xbcfc7aff, 0xdfdf1e47,
- 0x8e779f8a, 0x9f43bff9, 0xf50bd01d, 0x4779c7a1, 0xc64fc941, 0x6b86bcc0,
- 0x739e743d, 0x1ecdf7b8, 0xb055f595, 0x7c745573, 0x41af4534, 0xc35dc8bb,
- 0xd1cd03fd, 0x7ec9afd2, 0xf7a5ae39, 0xef921e57, 0xd5783e73, 0xea2d694c,
- 0xd92e90c9, 0xd9de927b, 0xc6a3525d, 0xb77d19bf, 0x34aafdf8, 0xb157eb8a,
- 0x552bf232, 0xf19b4675, 0x7c737fbc, 0x2be431fb, 0xb4ad6edf, 0xc6feb03b,
- 0x237d72d1, 0x44d5b7f7, 0x618fdfd3, 0x95407a41, 0x57df5827, 0x645305eb,
- 0xfa70d13f, 0xc3ba2fc1, 0xd1e95cb8, 0x39d79f12, 0xd055dff9, 0xe0b97277,
- 0xbf23086e, 0x886bda09, 0x820d67d7, 0x5f3ddf1f, 0x4cfbd729, 0x13ff25ec,
- 0xcaa0d3c5, 0x2ca7ceb9, 0xd4dfb20e, 0xbb95a3f1, 0x33724b7e, 0x73148e38,
- 0x0d0b8e40, 0xd2268dc4, 0x60959079, 0xbc9fe24f, 0x5dd24b72, 0x1f80ff38,
- 0x71dc93f3, 0x9730fca8, 0xfb223e7a, 0x3cebc973, 0x7e2433fe, 0xc7933cd4,
- 0x95ddf08f, 0xa5c87e10, 0xc51d8f23, 0xb374a3bf, 0xc75d51b8, 0x3247ba49,
- 0xd208ff44, 0x518dae3b, 0x8a4719fb, 0xb23b8fdc, 0x7fa33053, 0x8f3ca46a,
- 0x9c31b77f, 0x7fe9eaf4, 0x79458ea8, 0xf9d3aca0, 0xcf5e7cb9, 0x04a5707f,
- 0x07f89bbf, 0xe3061cd1, 0xf507c5fa, 0xb0e249bf, 0xbbf09464, 0x63b408fa,
- 0x7561ffce, 0x2febce04, 0x2fbfc520, 0x3169daf1, 0x2bd23fa4, 0x0fd82dcb,
- 0xbfc80ba3, 0x45a5fb2c, 0x07230fd8, 0xdfc139fd, 0x6bbf976d, 0xfc853306,
- 0xf8f3af98, 0x6b82737e, 0xa6cfc126, 0xa61efe33, 0xffcefc83, 0xfe8d7402,
- 0x2c183ca2, 0x1a7f9fc6, 0xbc61d6ce, 0xf5de39a8, 0xb3d1f136, 0x08f9091a,
- 0x9338a7be, 0xfb44bf6f, 0xc6194e23, 0xfcf40a73, 0x0cea465d, 0xbcb46bd6,
- 0xc760098e, 0xb0093c62, 0xe6f18059, 0x53ae393c, 0x6c44ce10, 0x6b9d49ff,
- 0xf997be13, 0x5f68b764, 0x8f604c4b, 0x83bf77c5, 0x83824be3, 0x3895c5c7,
- 0x1f1f1293, 0x6024ce2e, 0xee9c053f, 0x8715b9f8, 0x25737180, 0xe7bec49e,
- 0x635720a4, 0xf7ce87b1, 0x48c8533f, 0x718b7fae, 0x21f9259e, 0xc83548e2,
- 0xd5cf2463, 0x394dc571, 0xfe9d10af, 0x3dc4f1b5, 0x1cb7d863, 0x13f3e2ff,
- 0xe8f8f78c, 0xb7b2164b, 0x51effabe, 0x5e76cfb4, 0x42f0fda6, 0x8fbe41bf,
- 0xecfdc7d0, 0x2ff23a9d, 0x2dbb005c, 0x3d9f603e, 0x3ddbcf9a, 0xe89539d4,
- 0x596f40ff, 0x2f3fd604, 0x777c6fe7, 0x48d9fcc1, 0xbd22bd97, 0xe3e78b07,
- 0xd03b0ed0, 0xbd404e2b, 0x975c5be5, 0xb1098fef, 0xd0f0c62e, 0xcbe44cef,
- 0xc05f947c, 0x07ea63e9, 0xd772fedc, 0x598a38f3, 0x72ee0b96, 0x63c1c93d,
- 0xf1411629, 0xc5435b9f, 0xa7ef5e59, 0x856aa37d, 0xbe1cf740, 0xa3a59c71,
- 0x82b7de5b, 0xd3e5d3fc, 0xe70e6e49, 0x9b880eb7, 0x15b7caab, 0x23879c0c,
- 0x815475ff, 0xe31dc699, 0xb3c12c29, 0xbff8ca87, 0x73b875c5, 0xfb3a086c,
- 0x695fdb16, 0x9fdb6eff, 0xb6ddf792, 0x6e3be6bf, 0x77de6d7f, 0xf1dee71b,
- 0xf57fe31d, 0xccff6e3b, 0xaf3f3c77, 0x73ffffe5, 0x70700300, 0x5cf83f9c,
- 0xdfbc7040, 0x1f3efc70, 0x36106d96, 0x6a4177f7, 0x42b57a8c, 0x462d5100,
- 0x0877a2ef, 0x71e24d66, 0x46658db0, 0xf0610eff, 0x5f32807c, 0x1db90b4b,
- 0xe8bfce61, 0x4e79858b, 0xc596f475, 0x126c9fa2, 0x82fd877f, 0x132acefc,
- 0x18cef4cd, 0xfbc04cd4, 0xa161cdf1, 0x7261aae3, 0x23edc37b, 0xdc9617cf,
- 0xfe9e3631, 0xfbc8436c, 0xfec82f1d, 0x23077347, 0xa51324bf, 0xafd47984,
- 0xd0fa8094, 0x3f3c2388, 0x76398baa, 0xda525e10, 0xa507b23c, 0x8b6fc434,
- 0x998def1c, 0xfe869d99, 0x0bd018e8, 0x14f81e31, 0x8e2905c6, 0x4a7aa665,
- 0xe58c1f7f, 0x31d16dfd, 0xe55bee81, 0xac4cf3f2, 0x9e2aa0f9, 0xebae8ef7,
- 0xc50265e3, 0xfe2396f3, 0xe574d2bf, 0x89934cef, 0xff37e618, 0x8ce29980,
- 0x48bd2627, 0x8956777f, 0xf331adef, 0x6ed1872a, 0x1cd63c06, 0xbbf4471c,
- 0xf7a4d0e4, 0x7733e9f1, 0x750f68a6, 0x17f1514f, 0x1dfd969c, 0x8940bf8a,
- 0xf65efd6b, 0xfe887c93, 0x221fba17, 0xab1dea51, 0x27f7b6f9, 0xfc10d8ef,
- 0xfee045bf, 0xb8afdf21, 0xde9c687f, 0x6e78119e, 0xaf3cb372, 0xdc78bacb,
- 0xecf7f142, 0xee33c793, 0x01976d11, 0x4d71d2f6, 0xcfb8f463, 0x094a6b8f,
- 0xe1c0b4c7, 0xf07de0d7, 0x35fbd5c5, 0xa285faca, 0xb2b1d6a3, 0x9fa7a31f,
- 0x12ff7ae2, 0x60ffe714, 0x30bf3f2c, 0xf1e390af, 0x0824d801, 0x1b12c9af,
- 0x711c7d51, 0x2a1b598b, 0x7605549e, 0xacb9e231, 0xccade399, 0x34975577,
- 0x7339fb15, 0xd309bfb4, 0xa9b49aa2, 0xbdaf6fe4, 0x9bfa84d8, 0x63e5dafb,
- 0x4cbf93b7, 0x713da12f, 0xefda9f4f, 0xa5a30ab6, 0xfd2784f1, 0x0cdf5a9d,
- 0x71e3ec91, 0x9fa24433, 0xb230aa98, 0x4c74635f, 0x2e78426b, 0xca8a8bd7,
- 0xcc22a6e3, 0x3e934416, 0x4523d458, 0xe83f97df, 0x51998b07, 0x74f38f1f,
- 0xe2aaf8b3, 0xcc35bb4f, 0xe7ae1af1, 0x5d5f1b5f, 0x74bbcef9, 0x971954ae,
- 0x9c4a2f32, 0xaaf8b874, 0x5dc1ce72, 0x2e75457e, 0x4ff62dc3, 0xb8e3ff47,
- 0xf2f46783, 0xfe334b39, 0xfe25611d, 0x8bf5ee3a, 0xe2557714, 0x45cf6eac,
- 0x3be1abd2, 0x0e3f7e3d, 0x06213f96, 0xf1e217df, 0x9ef157d7, 0xffef1e94,
- 0xd4bee999, 0xc5fdf21b, 0xe63f184e, 0xa1cde9bf, 0xa76bcbb4, 0x98b790f4,
- 0x45e77752, 0x387ed78a, 0x53ef1d56, 0xb49779e2, 0xd56333ce, 0x0e0923e7,
- 0xc369f78e, 0xddc6bfb9, 0x97bfa3a3, 0x48c77ee1, 0x73a4bbf2, 0xfaebdd19,
- 0x246ba4f2, 0xf1875de2, 0x38ba00b6, 0xe187b0ef, 0x9de7613b, 0xb38c30f6,
- 0xa73eeb8d, 0x752ff3c7, 0xfd1eaf62, 0x12718061, 0x1f744d1e, 0xf7cfc8b8,
- 0xdfd09676, 0x5c69bae3, 0x136fe3ac, 0xe59ffb17, 0x00210141, 0x00002101,
- 0x00088b1f, 0x00000000, 0x17b5ff00, 0x67534c5d, 0xb7b77cf4, 0x0bdf96e5,
- 0x72223f2a, 0xa29862c1, 0xa740c2dc, 0xac741631, 0x4a8a5c13, 0x66b50102,
- 0x2d09922e, 0xcbc2ccd9, 0x01893ad2, 0xb8b2c3dd, 0x26a9f364, 0x87b6e883,
- 0x6ead93fa, 0x840b0b55, 0xc3e22e25, 0x52c9719c, 0xba33330d, 0xd8dc6281,
- 0xdf39d85c, 0xd8bdb5bd, 0xa4da2cbd, 0xdf3f3d39, 0xfff9df39, 0x0730000a,
- 0xb956e7da, 0xf84ce706, 0xffc6cfa5, 0x4fa43d0f, 0xbddde38c, 0x1726eb4b,
- 0x3ebbf1c4, 0x036935c9, 0xce9c5df8, 0xf6002b94, 0x1c5ace87, 0xaccf1f04,
- 0xedfc2176, 0x4ab5dfc2, 0xd2f7803a, 0xee202d4c, 0x96a666fd, 0xd2afdef8,
- 0x4fe9027a, 0x8ed77bdb, 0x70045e97, 0x106b4196, 0xc12e55f9, 0xb8e08271,
- 0x4546fac3, 0x25c06e5c, 0x80fce938, 0xe89b34ad, 0xd9a55cc7, 0xf5f4137b,
- 0x00674539, 0xdaaf39e9, 0x09f489ac, 0x06a019bb, 0xc15c0ce9, 0x556bf624,
- 0x7fdfdb81, 0x4a4f2ad2, 0xdbf11c7a, 0xe036cc1d, 0x3c8150de, 0xf7c71e59,
- 0xfc028fd3, 0xd422666e, 0xb9e97402, 0xd77264b8, 0x3bafa8aa, 0x52816a3f,
- 0x5c5b4ca2, 0xdf5e30ab, 0x12acfd4b, 0xbefcf860, 0x170568e2, 0xa0172095,
- 0xe0373f4d, 0xb19c5bdc, 0x3d7fc010, 0x4698ca05, 0x4adf9113, 0x2a8e143f,
- 0xa769da22, 0xb6e5785f, 0x4c27f7fc, 0xcdba11ab, 0xbdc268fe, 0xc3829dda,
- 0x2eedc99a, 0x7920ce6d, 0x212fce31, 0xb74bd3a5, 0x51cc22ad, 0xf413e428,
- 0x025ac217, 0x36ada8d2, 0x0406ef6e, 0x7ca1b07e, 0xa488539b, 0x70d69da0,
- 0x6f50044a, 0xdf045395, 0xcd7b088b, 0x7c461281, 0x2be726f1, 0xbf11366f,
- 0x042aae4f, 0xcbe7e3f4, 0x09417916, 0x3464dfbf, 0xf3aa8e21, 0x3c52fed3,
- 0x953176af, 0x34ef6adc, 0x4193f1f2, 0xe3d6ee7e, 0xfc3433b2, 0x5ff72172,
- 0xcb9e0136, 0x8e38031d, 0x18f67776, 0x756eedcf, 0x3f7461de, 0x337fa0f8,
- 0x904d81ca, 0x6bde8907, 0x3b3aa394, 0x001ff18d, 0x43d62670, 0x0d41d537,
- 0xe7e1c641, 0x45d513e8, 0x582a0615, 0xbf373f11, 0xf974467e, 0xf062faf9,
- 0x5117f10c, 0xd80d567d, 0x024dbf28, 0xf5e10194, 0x9f412d92, 0x9eb9155f,
- 0xfc01650f, 0xde17d728, 0x7e30c83e, 0x915f8f7d, 0x4a6e505a, 0xd2ca97ae,
- 0x32f7b8e3, 0x401653d6, 0x036cf0f5, 0x9858fbc5, 0x794d1581, 0x28bef1f3,
- 0x6eb17d57, 0xbc4ead9c, 0x31dfe6a7, 0x3a44f9cc, 0x0d9a81d5, 0x61205f9a,
- 0x5817fcbc, 0x55ed1060, 0x491c3d35, 0xb2b9f8a3, 0xec8532d5, 0x23a50ed8,
- 0x6b126dee, 0x3c2ee118, 0x160ef840, 0xf6e7f090, 0x005b9d2b, 0xd8b754ed,
- 0x5bdc52af, 0x15aacc3a, 0x40dade88, 0x50596bf4, 0xff122937, 0xc4a97bc4,
- 0x55aa672f, 0x9eb3be21, 0x445f8df8, 0xade7aa44, 0x7865a514, 0x8d28cbb7,
- 0xeac1b37d, 0x551f500e, 0xf411a337, 0x3587476f, 0x84b5fe40, 0xce90cd9b,
- 0xbea041eb, 0xedcf5b7b, 0x328f45b7, 0x099f48a3, 0x5f916757, 0x16d3cc0b,
- 0xea356115, 0x7841c82e, 0xb005bee1, 0xb4e2bc1f, 0x73b94645, 0x05ac4c3e,
- 0xc49f4be0, 0x8327c861, 0xd7c03963, 0xc30e7cbe, 0x2fd3853e, 0x8c39cafa,
- 0x470e54f8, 0xa8356b7c, 0x959e3cca, 0xdd02fbe1, 0x7059a727, 0x7e6f9b25,
- 0xf9623ebd, 0x29ef0baa, 0xba3e7ba6, 0x93962eea, 0x5a20c7c8, 0x6ad6142c,
- 0x6730c9fd, 0x06c3e75e, 0xe881e3b2, 0x60a73a61, 0x460d61be, 0xef308421,
- 0xaa6febbf, 0xd96f9b52, 0xf193b802, 0x04faf467, 0x3cd02287, 0xfad24b7a,
- 0x5fc5787f, 0x48529e3c, 0xf31eb2b9, 0x413719e6, 0xd48fd20a, 0xbe7f736b,
- 0x4f18eb9e, 0xc0ddb8c0, 0xcf9c1278, 0xcbf8b56f, 0x74ad1f28, 0xa7e7248f,
- 0x0ac4faf4, 0xb432bb30, 0x4fbc329c, 0x600e6c47, 0x8f30b220, 0x4916211d,
- 0x19df3ec5, 0x244774de, 0x96e0c3d8, 0xd73c7e71, 0x46e6d87d, 0xb6f389a5,
- 0xf9268d33, 0xd54a5c13, 0x34592ce2, 0xf6d56fd8, 0x8b5d935a, 0xb56e0c73,
- 0x9471756b, 0xfbeb059a, 0x381679e8, 0xa9e7fd88, 0x734ebb18, 0xd001cf2c,
- 0x93c7c38b, 0xd1311e9f, 0xef990f3c, 0xd8e3993d, 0x0c8a791f, 0x3794391d,
- 0x41f6260c, 0x24077e81, 0x63946dc0, 0x6e611c91, 0x192dca25, 0x9f7d259f,
- 0x2f6e15d8, 0x01905777, 0xfe0450ba, 0x465f3483, 0x1a77502d, 0x639d77ed,
- 0x3bfa9070, 0xf70502e0, 0x1bf1e8fd, 0xdd214f87, 0xb4c98e73, 0x5783ba8e,
- 0x16ef9ef9, 0x78ff7827, 0xbc2d77c2, 0x3537831e, 0x0239887a, 0x403af249,
- 0x6eed1dfb, 0x6e687f46, 0x05301f74, 0xc36ed052, 0xbdafad39, 0x41404b0e,
- 0x1de8ac7c, 0xe79df091, 0x1cd1e419, 0xa5162653, 0x1980ff11, 0xafdc2502,
- 0xfd84baa6, 0xfc855f84, 0xd8cfed8e, 0xf4c0f1fe, 0x6bd52158, 0x0a235327,
- 0x8cb73fdf, 0x922f05fb, 0xed2fdf1b, 0xcd3361a1, 0x0643dc1b, 0x868eddb9,
- 0x713f343b, 0x4be918cf, 0xf9e7df0e, 0x53af2880, 0x7e062fdc, 0xe1633d8d,
- 0x58092c6d, 0x38731509, 0xca5536cf, 0x6eaddf3c, 0x1f18dcc6, 0x91757049,
- 0xc991709f, 0xc7e76f34, 0xf5aed1ab, 0x419fa341, 0xc877e62f, 0xd0c7d5a2,
- 0xa3f0163a, 0x94a2237c, 0x7b8ba1f7, 0x1cfd0cfc, 0x40aa62aa, 0x8c2120f1,
- 0x3e3d16c7, 0x6e1f802f, 0x70a9fc4b, 0xe01aae6c, 0x2b61ac35, 0x5ea353d6,
- 0x6e01000f, 0xd4e3f9a7, 0x8e23bd08, 0x2af9839a, 0xf9f8977f, 0xe055677d,
- 0xe814d4fc, 0x6bafd649, 0x6ab375ec, 0xf33dc90d, 0x7b2ed3f7, 0x47d3f792,
- 0x3b2276f8, 0x244ced7b, 0x2bbe30bf, 0x15efbfa9, 0x411ccb5d, 0xb5c981f4,
- 0x5975ce8f, 0xbea9ab22, 0x1cdc981f, 0xee91f18f, 0x8b82fda1, 0x91f516ef,
- 0x87cf8c00, 0xcc67e523, 0xa2769794, 0x125beec7, 0xe9b8e397, 0x0aa1fc69,
- 0xa1efdacf, 0xfda79aca, 0x17fa867e, 0x7f57cfab, 0x1dbcb26e, 0xa497f9a2,
- 0xe7d27e7e, 0x9912c01f, 0x3893cbf7, 0x6487b683, 0xaa3c75e0, 0xa67ef5ef,
- 0xc87b48fc, 0x06199dff, 0xed5cf895, 0x7ff4d0cf, 0xc18beba6, 0x9bf61d51,
- 0xf6f9b935, 0xfc39f427, 0x8a71c98b, 0xa4f2bdee, 0xdf824a00, 0xa0a982ab,
- 0x195df824, 0xf6e031ca, 0x7c8362c8, 0x81a978f5, 0xc2b1335f, 0xbd735fc0,
- 0x14bf80ca, 0x5f90675d, 0x01bd6bff, 0xc5bd30df, 0xcff1bf20, 0xd63c066d,
- 0xb95875bf, 0x4936e789, 0x0ae41baf, 0x157e8d3b, 0x2afd18f5, 0x15fa35ee,
- 0x37e25bd3, 0xdfacb7fa, 0xf64e5fe8, 0xde855c83, 0x91fcffa1, 0x2060fb49,
- 0x34f3c33c, 0x13029d35, 0xa8c44734, 0x66c21fb6, 0xf0a617be, 0x84a2e2ff,
- 0xd7a72c3c, 0x0919da3f, 0xb9d2b32f, 0x2b369d0f, 0x512edbbd, 0xfe3e600d,
- 0x2e76d705, 0x000ee017, 0x00000000
-};
-
-static const u32 csem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0xe3e3ff00, 0x51f86066, 0xb8d3c10f, 0x72361818,
- 0x0143f821, 0x684333b7, 0x0606163e, 0xc77e2001, 0x9ef0c0c8, 0x38330491,
- 0x207eec10, 0x27880abb, 0x7dcf5071, 0xe52f1143, 0x5f5d9fa1, 0x153d76a0,
- 0x837f7818, 0x031083b0, 0x03309b83, 0x8408b483, 0x55045fbf, 0xc10851de,
- 0x99412e7e, 0xfa819f5d, 0xbbeb8d01, 0x00038031, 0x00000000
-};
-
-static const u32 csem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c0b, 0x733ef7b5, 0x9993331e,
- 0x420f264c, 0x084f0042, 0x21842a20, 0x38880840, 0x8d069009, 0x8808089a,
- 0x420100ca, 0xa9113248, 0x676d5e97, 0x6ad11422, 0xa36d2d1b, 0x4101da97,
- 0x180d45a3, 0x1d0340e8, 0x5abc414c, 0x5b4a0a8d, 0x3c3141b5, 0xe878490a,
- 0xef5bd6c5, 0x33ef6b5e, 0x42667399, 0xfddfb6a2, 0x7f17dfbe, 0xecfb36fe,
- 0x7b5ef673, 0x7b5affad, 0x231fb5ed, 0xd313c659, 0x057c8415, 0x7213d77f,
- 0xf4842448, 0x0b3b4eeb, 0x108e3a68, 0xb0398e7f, 0xb4242055, 0x24edefef,
- 0x4db39085, 0x267355b3, 0x98c7fb21, 0xf2d3d743, 0x80fc81b3, 0xdd4f9699,
- 0xd121c479, 0x514ed57c, 0x3ed37282, 0xb1df7e2b, 0xde400851, 0xf1fd6e6b,
- 0xb5df34b5, 0x699b2453, 0x376424d5, 0xda425491, 0xa9fd842d, 0x6a5f98f1,
- 0x4daad965, 0xf682effb, 0x626683ca, 0x37b7dfa5, 0xafc86e89, 0x08042adc,
- 0xf76aaf6d, 0x5a00ca83, 0xd080b2df, 0x7e695568, 0x1a8a63eb, 0xfb03c84f,
- 0xb368ecfe, 0x67da7213, 0xfd82aa21, 0x491c6f28, 0x7b604548, 0x7dfa00e1,
- 0x65c136c5, 0x6c57f5a2, 0xf401d73c, 0xc3c93455, 0x8adf5a44, 0x47511b06,
- 0x22bfb6b0, 0x07cb5ed0, 0x794eded8, 0xfe57b428, 0x110a3de5, 0x1bb29fa1,
- 0x74a2abbe, 0x76b5bf40, 0xb1eafb4f, 0x559f8d3d, 0xe8f6d1cf, 0x0a2fd57b,
- 0xb562e82e, 0x8e807889, 0xb9d6dd8e, 0x7fa1db4f, 0xf8f0cab5, 0xdc2c7ec8,
- 0x08a8fd05, 0xed0a526c, 0x6526df40, 0xfaeec8e9, 0x87fc3456, 0xacfabe9e,
- 0x72889efe, 0x47da7a63, 0x3bbc3a59, 0xbb88415f, 0xa44bd691, 0xaa3a5280,
- 0x4207f9fb, 0xa1e32122, 0x96a8917e, 0xe4a9faee, 0x23fe0711, 0x0f949ff4,
- 0x81f1bdfe, 0x72dd99ad, 0x9904e95b, 0xbcedcb75, 0xea51cb93, 0x5fac8dca,
- 0xf20c7f4b, 0xf9d4f4a0, 0xee3e989c, 0x8374c34b, 0xfdbe454f, 0xd30237dc,
- 0x9f0b9f7a, 0xc3cbe93f, 0x8dcfa374, 0x22be53e9, 0x12be034c, 0x6fb36f7c,
- 0x7c5ba62e, 0x8cfe7c1e, 0x06d31caf, 0x7f3e0d5f, 0xd31ab7de, 0x3e3f3e6d,
- 0x1eb7d17f, 0x1d5f46d3, 0x5e403ba6, 0x05f26d34, 0xbe5dbdf0, 0xbe834c06,
- 0xc7be7c46, 0x11f4c417, 0x64c747ce, 0x3e512f92, 0x49c4dc38, 0x8a924ec5,
- 0xcd32f9dd, 0x7cb09527, 0x7cfe1dea, 0x3d53e685, 0x32f94f34, 0x6f9432a0,
- 0x3501f9a6, 0xfdf07cac, 0xf342c0a4, 0x7cacfd83, 0x02ee23c8, 0xa90fcd2b,
- 0x37c3e563, 0x68e20bfa, 0x9580787e, 0x542dbd5f, 0xabf9a360, 0x7679591b,
- 0xa76a9933, 0xcb10ecf9, 0x9ee1bce7, 0x39f34f1a, 0xfb9f2cad, 0x83aa7f81,
- 0xd8db73e6, 0x04ce93f7, 0x2d1ed544, 0xbab21d87, 0x6d595098, 0x4b70cff4,
- 0x515e6913, 0xca2e21ef, 0x6eadff1f, 0x43f29d29, 0xc8796376, 0x9bcb1f3f,
- 0xbf963714, 0xfcc32fe3, 0xe583d92e, 0x2c55fdc7, 0xfcb078af, 0x98bdff73,
- 0x2c7eca0f, 0x58fad4b7, 0xf963f15e, 0x58f5da80, 0x80391eff, 0x1f6b23e5,
- 0x4a3df2c3, 0x5f1fcb00, 0x1a7ba4fb, 0x3c11afcd, 0xd23c073f, 0x01649cb4,
- 0x4ad31a9e, 0x09d69e28, 0xf7e02e64, 0x8a3a0007, 0x0ae975cb, 0x3f8ee1ea,
- 0xfa0d3ee4, 0x90297f8b, 0xc3ccfa5f, 0xaffdf899, 0xd6991eb0, 0x4f5ef623,
- 0xba799bce, 0x2cde727a, 0x8069ead7, 0xfb58d6f7, 0x378ecf56, 0x79e9e927,
- 0x67ab42b3, 0xdf13d23b, 0xbce57eb7, 0xcf4f5935, 0x3d5a955b, 0xc49e907b,
- 0x74d3d1be, 0xa69fcf44, 0xb4fe6123, 0xfafd3d20, 0xf7b8cf46, 0xf719fcf4,
- 0x6f3f985e, 0x7de93d60, 0x3de9a7ab, 0xde9a7f3d, 0x08e7f30b, 0xdf506bf6,
- 0x7dee35fa, 0xbdc67f3d, 0x47cfe61f, 0xdf664f48, 0xa1f5d9ea, 0x3ebb3f9e,
- 0x04e7f30c, 0x6fac33d6, 0x48fdcafd, 0x8fdc9fcf, 0xc2e9fcc2, 0x5beaae7a,
- 0xd23ebb3d, 0x47d767f3, 0x817cfe61, 0x5bea8cf5, 0xa2ff72bf, 0x5fee4fe7,
- 0x0931fcc2, 0xbe98cf50, 0x54fc13d1, 0xa7e09fcf, 0xb0d8fe61, 0xa37df19e,
- 0xcf5daf27, 0x30f6bc9f, 0x9004527f, 0xd5bec4fb, 0xf3d76c13, 0xe61ed827,
- 0xe7ac20cf, 0x2bf5beba, 0x3f9e84ef, 0xfcc22779, 0xcafd8e19, 0xf40f7aa7,
- 0x7c4f5a10, 0x39ecf5cf, 0x9ecfe7ab, 0x8cfe61b3, 0xd3a67ac6, 0xaf7ab27a,
- 0x9e875267, 0xc23a933f, 0x7ac3c9fc, 0x9eadf466, 0xfe7a1d3d, 0xf308e9ec,
- 0x73f91f27, 0x35fadf53, 0x9fcf53a9, 0x3f8c9d49, 0x4cd70f63, 0x3a72d075,
- 0xfa44ba16, 0xdc67b5c9, 0x45e6816e, 0x4e8bcb27, 0x44bf0117, 0xd20dfcd4,
- 0xf7e916ea, 0x39896df6, 0xbf48930f, 0xfa14a0a3, 0xb1bd4f15, 0x2123bf48,
- 0xe7e74e2f, 0x7493ba24, 0x01a2e4f9, 0x95fbf7ba, 0xf795d10c, 0xaeb57b9f,
- 0xa393dd3c, 0x4f9467cb, 0xa83fbdd2, 0xbf9740a6, 0xba0df562, 0xb7fd33f7,
- 0xeb59f2ea, 0x3fbdd76f, 0xae916eac, 0x0afacafc, 0x8155f95d, 0x35fcba95,
- 0x7baeff0d, 0x03e3547f, 0xc1d1f2ba, 0x63e57587, 0xf2eb8f42, 0xa93d0f63,
- 0xeb7c7f7b, 0x84f95d66, 0xcaebcfa3, 0xd0edb627, 0xb93dafe5, 0xd9e7e0c7,
- 0xf0d7ed9d, 0x27b808bc, 0x574fefcc, 0xc50bdfd0, 0x0657982b, 0xdf8fd1d8,
- 0x3d54bf1f, 0xbcabe54e, 0xa14d58b2, 0x129905f2, 0x0fe7ae3a, 0x8db2bf28,
- 0x9277bf3e, 0x7d274ae7, 0x19e2af7e, 0x9fe18ced, 0x24083c52, 0x04d5520d,
- 0x41fcb1a9, 0x20b1e199, 0xc7e1cbe3, 0x535ef7e8, 0x9a44f0d7, 0xd7e62fef,
- 0x129e5e03, 0x38d3884c, 0x7bc0d491, 0xf3826671, 0x73330782, 0xe047f69f,
- 0xaa20fd75, 0xbd774287, 0x1a4f65eb, 0x6b9b19f8, 0x1f83f6df, 0xed106eb2,
- 0x9e4200d7, 0xf90ede16, 0x07efd287, 0xd0f34d2d, 0xf50accfa, 0x57db23d3,
- 0xb123fb68, 0xff6806fd, 0x37da1ec5, 0xb5d3c90f, 0xae5c196f, 0xd0a2df6b,
- 0x1fd49df6, 0x6f23fda8, 0x12610a9f, 0x7f0b2f21, 0x83cdf6c4, 0x07fdb1cb,
- 0x895f3a15, 0xdc2e3f6c, 0x77f4107e, 0x3e3fb41f, 0x4c87ff46, 0x707ff7d2,
- 0x0affbe85, 0xb52bffeb, 0x71fb78c7, 0xe116ffd8, 0xe0ffeb18, 0x337fd60a,
- 0xbedc37ab, 0x43ffcc23, 0x7b37ffd0, 0x64d67fea, 0xa8afff7d, 0xccdff7d4,
- 0xf6a77fda, 0x8edf6f14, 0x9c2bbfed, 0xa2bffd62, 0xcc57db12, 0x47e0171e,
- 0x09ab88c9, 0x40c9f6d0, 0x03fa986a, 0x903b685c, 0xa0a2488e, 0x6151e426,
- 0x6f71d208, 0xe7dbc31c, 0x686f1471, 0x9cf8fc6f, 0xcb65a804, 0x8e2ef3a5,
- 0xf2db15f5, 0x584bb015, 0x4b2be74e, 0x4165a938, 0x364df111, 0x28c30398,
- 0xd1411dbd, 0x0db2f90f, 0xfec005d7, 0x4164cd79, 0x91277c09, 0xf4ff3c10,
- 0x4736a367, 0x2e98cbf6, 0xdbdb93a9, 0x3c2df422, 0x23202a8f, 0xd37d286a,
- 0xbbe30401, 0x79d31ff3, 0x8bf3a110, 0x833ce80f, 0x227e4850, 0xa23ef6b3,
- 0xb7c825f3, 0x9412f9d1, 0xdf8b5213, 0xa70eead1, 0x384bfa51, 0x4c4b1ffd,
- 0x43be3f5f, 0x7ea9f808, 0x31bdfe7e, 0xb05d4f38, 0xde9946da, 0x7f42c74d,
- 0xfb4f2eb2, 0x753907e5, 0x360736ed, 0x155fc80b, 0xaa8a55f8, 0xf5e2c849,
- 0xddd79419, 0xc54fbfef, 0x7f594e9e, 0xfdcb711b, 0xae77fbe9, 0x69390612,
- 0xe6ddb3bb, 0xb84e361c, 0xd7a84c33, 0x4794c324, 0x634dadc8, 0x29035a64,
- 0xb71fcb75, 0xb33bb445, 0x5d9f9f48, 0xc877cfa2, 0xe944d96e, 0xc81528ea,
- 0x9cef5a26, 0xad72fab9, 0x8929bb1d, 0x57b799c9, 0x9be8ca92, 0x3c0e6903,
- 0xe79ca276, 0x1ab7d93a, 0x32c5de3d, 0x3c82c29d, 0xc808fdfd, 0xef829fd5,
- 0xfd64eedd, 0x573bd236, 0x684bb8b6, 0x142ee73f, 0x236f8003, 0x67da7ffd,
- 0x69b29b73, 0x32a7feba, 0xc7f74531, 0x8f3cff48, 0x328d3fb1, 0xcbf3c38c,
- 0x6e19cf8d, 0x3ffcb9da, 0xf4d07c06, 0xd283e004, 0xa3e39c7f, 0x7c32aedb,
- 0x9b9ecd78, 0x4f5d0f01, 0xcae50488, 0xc71b72f1, 0x3d3a92cb, 0xc8f1082e,
- 0x7365c720, 0x23879c85, 0xe3873070, 0x1ebd5960, 0xbf127737, 0x2e431e9c,
- 0xfa6c36f3, 0xdd1a9a61, 0x6e390fbf, 0x1fb23fe6, 0x4fdd13f9, 0xb8bba726,
- 0xd1acee9c, 0xe5c6df97, 0xeb97277a, 0x0ec7fadc, 0x6e41f350, 0xe8320357,
- 0x4d3ef7bb, 0x793a6d9e, 0x8d3cb87a, 0xe5c5de74, 0x98f7d779, 0xb6f48d3c,
- 0xd5b67971, 0x90c9905f, 0xf48d7a68, 0xd51d582d, 0xb9e4051f, 0x9e5b1fd0,
- 0xf27e60de, 0x55e788f1, 0x8f92338d, 0x8ad9e847, 0x7e5d5286, 0xee9e6079,
- 0x0bf565fd, 0xea4be575, 0x17caeb96, 0x975bbfaf, 0x9effe85f, 0xab05fdee,
- 0x77e5756b, 0x2ba43cd6, 0x98fe5f9f, 0xf3cf3f2e, 0x39fdee84, 0xcae93773,
- 0xa73c9767, 0xb4599f2b, 0x752f975d, 0x6fbdd6ef, 0x2dd577da, 0x8e37cf80,
- 0x89fc0488, 0x30275ccf, 0x4b99f82e, 0xc73bc176, 0xbae22a7d, 0xd30237dd,
- 0xe2173e93, 0x0f2fb4fe, 0x8b608ed3, 0x3a09c61d, 0x89252e2e, 0x6e9bccd4,
- 0x103f5dae, 0xe38269c6, 0xacd316e9, 0x4264ff5a, 0x91526d7e, 0x0af5c5df,
- 0x44258d09, 0xd386c180, 0x944625d1, 0x5e52f5b7, 0x727f0d4f, 0x5b717974,
- 0xc7dee7ec, 0x8ce15e17, 0xd6e97711, 0x7e019253, 0xbbf7274f, 0x0295e58d,
- 0x4e7c8929, 0xd7a803c8, 0x5bb8f8e7, 0xaffd30a9, 0x405e91dc, 0x0d0f901c,
- 0x7b5cb9af, 0xfde4148d, 0x3a592701, 0x7f565e3d, 0x13bece8d, 0x03f6ca88,
- 0x3dd58dbc, 0xad70d15f, 0xfb33bbee, 0x1abba445, 0x1844c56c, 0x375e4b16,
- 0xb50e1d81, 0x0a399e0c, 0x61bf74e8, 0xd82a7182, 0x33c2fd0f, 0xe3e4a2be,
- 0x04afc812, 0xb9be93d3, 0x3cfbb698, 0x95f71e98, 0xafb1fa63, 0xdf36d306,
- 0xf23f4c6a, 0xc0fd31f9, 0x3fd31eb7, 0x3d30eaf9, 0xf4c7abea, 0xd3005f3d,
- 0x4c06bec3, 0x6235f1df, 0x620beada, 0x6373e1da, 0x6f5de9aa, 0xc7c93bb8,
- 0xbf80d3e1, 0x78eb3818, 0xfaed5560, 0x3b38ddc9, 0xd6afba6f, 0xcf9bb03f,
- 0x8e66f5c5, 0x1e1d5487, 0x336080be, 0xf297ace2, 0xb0e3997a, 0x9763efa7,
- 0x6bff377b, 0xc4de36f0, 0x8a6fccfc, 0x653c6eb7, 0xd594f018, 0x89fa9e1b,
- 0x34f1bbe3, 0x7e64e4de, 0x8fd3c70f, 0xe6311fa0, 0x84e00515, 0xd7f08bf4,
- 0xa71636dc, 0xd409ebe6, 0x6a716553, 0xfa1af6de, 0x75fa2b6e, 0x6e301181,
- 0xb7f11f9c, 0x3f8710e1, 0x274cd47f, 0xcff73d7d, 0xf99e9388, 0xcdf9c6ee,
- 0xbc1d00d2, 0x5b9746c6, 0xad5f18e3, 0xe8445226, 0xb0d0f6b8, 0x468b5c67,
- 0x49225e62, 0x55c07df0, 0x5ea31f1a, 0x7f032bea, 0x9aebe37b, 0xa1b3cff8,
- 0xff27f6be, 0x78e90b9e, 0xe397f313, 0xdbf4445a, 0x1769e849, 0x2e3c37f0,
- 0x10695d99, 0xa61aeedf, 0x086fd138, 0xf3fcf5d8, 0x376e7cd3, 0x3ca21eff,
- 0xb771c56a, 0x37f90d2e, 0xe9e1f3f4, 0x6f5fe07d, 0x7e37bdf6, 0xf80c0a2e,
- 0x37b3f097, 0x5d9bd8fb, 0xc5f56e24, 0xe77fed20, 0x0f3951be, 0x870760ab,
- 0x0f5a79b0, 0xa5d6d6fc, 0xff7cf48c, 0x33b8e26b, 0xeb71c355, 0xf9db4260,
- 0xf9cbeb88, 0x40132ba6, 0x9c1eb42e, 0xe4ed741f, 0x722f7e7e, 0xafa99b3d,
- 0x2fac6bcf, 0x68c22141, 0xa2bc6eda, 0x6a420490, 0x22a3cf44, 0x6d5c6fce,
- 0xec1b887e, 0xa8d6b9b3, 0xfd3c6f30, 0x1a854866, 0xf385f1f5, 0xc0769e87,
- 0x9a656c3c, 0x863c79c9, 0xaab4b51c, 0x8f69d331, 0xf504af9c, 0x4275f3f9,
- 0xe7ce2351, 0xa35984d4, 0x3a719c60, 0xbb050f8f, 0x56a9869f, 0xc534cacf,
- 0xddda9c79, 0x09590dd3, 0x6017fe6c, 0x225b64f6, 0x3ed39bda, 0xcfffbe0b,
- 0x7aa7a7a6, 0x69087a34, 0xc0589f22, 0xacb2d39e, 0x51efdf9e, 0x0a8ba41f,
- 0xb34937c4, 0x37cc39fc, 0xaffff4ad, 0x12bd4086, 0xbd7ab5e6, 0x3cdfa28d,
- 0xd36f9e1a, 0x53bf47b5, 0xf857b5b5, 0x93bd67ae, 0x7b86bb48, 0xf957bf2a,
- 0x068af0fa, 0xc7ef53ab, 0xdef2ea26, 0xe753ba60, 0xc03fc2d7, 0x2411af71,
- 0x87255fc0, 0x5f64a75f, 0x0cda780f, 0xbf9843c1, 0x2abdec08, 0x51e29b4b,
- 0x015a5d51, 0x34f28b9f, 0xfe73abfc, 0xa9d4ed4c, 0x7a0265d7, 0x54a4be46,
- 0x20a9f2e5, 0x4c44cde2, 0xbf98bf34, 0x4569a8bd, 0xa75b8c31, 0x50fe6c4c,
- 0x301c4a46, 0x75272e3f, 0x3d4f10b9, 0xa0454c4b, 0x3bc9679f, 0xfa11b18e,
- 0xb0544e78, 0xf5ebc5d2, 0xdf9d3c7e, 0xeacbf2eb, 0xe4a5f9f5, 0x075854d6,
- 0x2641ba5f, 0x86ec0101, 0xe898fcbe, 0x91977ac4, 0x6e30759a, 0xbbc79cff,
- 0x94893916, 0xfaabe941, 0x17732fcd, 0x892e3a52, 0xd6d5fc6c, 0x31279771,
- 0x05662bfa, 0xff7d3714, 0xb7b1a693, 0xbf440b51, 0x7583ac0f, 0x71297f6d,
- 0xf2d1256d, 0x1bf4bafb, 0x81fcd5e9, 0x4e64f5a8, 0xe0834a47, 0x63b0c40e,
- 0x3d30248a, 0x6aeef6e3, 0x838ba9c9, 0x223e42e4, 0xf18df20e, 0x78744294,
- 0x067a2cda, 0x7e19e34b, 0xd4820f00, 0x4dbe78a5, 0xf55169fd, 0xfbf52d5f,
- 0x903fd627, 0xabab9fd6, 0x4a9ff73f, 0xfa28d0ff, 0x5fd5620b, 0x76179bf5,
- 0xa93da9f9, 0x0e67e978, 0x53c9c742, 0x8baa5d52, 0xeb72b5ca, 0x9a6e1d0f,
- 0x0efc949e, 0x80a9ebc0, 0xde4b1458, 0x76f2c3ab, 0xbb8805db, 0xfd693fc1,
- 0x11ff9fa7, 0xdf3e23c6, 0x9e313b2a, 0x990e60d6, 0x37563ea9, 0xd9262f2d,
- 0xf2c63f98, 0x21139e0f, 0xafe3d41f, 0xa59fd9e2, 0x8a0afec2, 0x0a5f1e14,
- 0xbd5b3fa1, 0x1c42d3e5, 0xea17489f, 0x683bf191, 0xda1252ff, 0x424a85bf,
- 0x13a53974, 0xce5e04e3, 0x8fd36f17, 0xf80e89ce, 0xdfce1b57, 0x7397ef8d,
- 0x14b974ff, 0xa36ed29f, 0x26409eff, 0xf8d43d80, 0x3fcc0241, 0x2fdcf35d,
- 0x7a518fb2, 0xdd796cce, 0x49f04421, 0x8df3a3d3, 0x47b57f8b, 0x76ded9ed,
- 0xf48b3d50, 0x4af1b483, 0xbabf720d, 0x7295a599, 0xd52d71c8, 0xb24dcafb,
- 0x571f4fcb, 0x33f4f0be, 0xf31c424f, 0x30d7668f, 0x178aff5a, 0x8937bc0e,
- 0x976c57e6, 0x37598a53, 0xb76a42ec, 0xfff4bc5c, 0x72dd39d5, 0x80f978a8,
- 0xcf628ea2, 0x96ea4fef, 0xfbed8ac7, 0x9a2a3215, 0xf71b531f, 0x18f66d2b,
- 0x563c6972, 0x9ac27e08, 0x814bfee7, 0x7da9e2f8, 0x199fe902, 0x0e9b9f83,
- 0x7c001fa0, 0x39723942, 0x7866e585, 0x02e54bdf, 0x93935af6, 0x6e46fcb1,
- 0x753ea04f, 0xc5f9e224, 0xf2fdb43d, 0xd05d993f, 0xef17f2ff, 0x4e3f4071,
- 0xd70c3548, 0x2a61fcbf, 0xd972afd8, 0x94c4ea9f, 0xea7f2f3d, 0x65b788bb,
- 0x15377f6f, 0x9dc449e3, 0xc7b1c26e, 0x5bfd0e9f, 0xf63671b2, 0x20f1296f,
- 0x297fcaee, 0xfa680496, 0xb68a4499, 0x0e8bd0c7, 0x362717ae, 0xf68c4753,
- 0x1fcc04ef, 0x23bf5ec1, 0x422abee2, 0xffa026ee, 0xa17de5df, 0x3fe6021e,
- 0x1d3930b3, 0xaf5c4c90, 0x8919b7a8, 0xb60f2dd7, 0x0f4e7c82, 0x7587f772,
- 0xfc912f16, 0x57c21f9c, 0xedf15eb4, 0x7c99fde9, 0xf2e52a88, 0x3f38e8ef,
- 0xfbc39e15, 0x9adbb2ad, 0x7c8efbad, 0xfeddd995, 0xa53ede2a, 0xe7c60e3b,
- 0xfdb1a913, 0xa6b201d5, 0x8e9c74f7, 0x7e8457c0, 0xf2df7d33, 0x4d6fd310,
- 0x45a503df, 0x30f17e50, 0x0ef81fd3, 0x574a3fc6, 0xef963fa8, 0x3da0259f,
- 0x58e6f3a0, 0xe645bd7a, 0xd72fad7a, 0x96e94270, 0xbc088484, 0xc849fd40,
- 0x595f5c7f, 0x177e81ba, 0xd0bd2f61, 0x3eba239e, 0x71976f4d, 0xfa053ffd,
- 0xfeb74d7f, 0xef4c8d93, 0xfc9ff67b, 0x07236e2c, 0xf412799e, 0x5fa7ea95,
- 0x4b957d05, 0xdd7fdfa0, 0xeddef2d6, 0xdaff4f54, 0xdea9e9a8, 0xb4f51a7e,
- 0x1278c77c, 0x6aff4f4b, 0x7a989177, 0xd4c79f4a, 0xe21b7b53, 0xfd94fff8,
- 0x2897f8d4, 0xd9a7f9eb, 0x68f89ec3, 0x4a2f87b4, 0x68d3f22a, 0x61dfe90f,
- 0x3f8d1b92, 0xde1a770d, 0x755d7e2a, 0x309dd805, 0x85dc352e, 0x2ee1a971,
- 0xe3ab7e2a, 0xcffcb19f, 0x74a26b10, 0x4fd4b7cd, 0xa5847981, 0x2bbce08b,
- 0xeb88967f, 0x048b96a6, 0xc880bef5, 0x7df06fb8, 0xf078cd53, 0xfdfca743,
- 0x52f7b3b6, 0xbf13e77a, 0xebe5d6cc, 0xbfebf464, 0xc9abeafc, 0x73b73fb4,
- 0xeca7cefe, 0x63ca89be, 0xe28424ae, 0x24f39d28, 0x82484fe2, 0x3e40acf8,
- 0x7e63a08e, 0x7f0f3eb9, 0xebbb5253, 0xaffdede9, 0xa6f90f3b, 0xb63edbe9,
- 0xa42ef576, 0x2979b143, 0x20a54f12, 0xef3fca57, 0x04302138, 0x549b52ed,
- 0x7aaf3112, 0xb79ddb9c, 0x0f1ccda7, 0x9cfe4bfe, 0xe70c0951, 0xeb7e7183,
- 0xbcebf6e5, 0xbb004d5f, 0x0b39be7e, 0x0fe7afe7, 0xb58f8e2d, 0xe385b26f,
- 0x575f00ec, 0x750bb4e9, 0x277dc522, 0xc5ff42e9, 0xad92b76f, 0xbefdd631,
- 0xe4f89b2f, 0xfe8dcb83, 0x736e5489, 0xd1e70e39, 0x2272134f, 0xa6eb36e4,
- 0x5a239253, 0x71f7f00e, 0xdbeb3cc4, 0x0d7017f2, 0xb6b16dfc, 0x88c49615,
- 0xf384fdd7, 0x5f2bca6f, 0x69d5fee0, 0xf012f9cd, 0xd45d9a71, 0xd41e39c5,
- 0x192475f4, 0x794d7409, 0xe3a3f965, 0x87bd8e29, 0x57ec1744, 0x539f36f5,
- 0xbbe6313c, 0xfd427e46, 0x901e47e0, 0x23afc89d, 0xe012c972, 0x56d991eb,
- 0xef96eb02, 0x58aaae2a, 0xb3374e74, 0x523cc878, 0xe138d9f2, 0xe6fe3eff,
- 0x150f89cf, 0xb79c7e50, 0xd1c0fdb3, 0x7f7a63f8, 0x6a0429de, 0xc8a1c005,
- 0x004229f2, 0xc48564e2, 0x0164e8f3, 0x48fafdf5, 0x2c1f95fb, 0xd5f6017d,
- 0x4e0b3754, 0x96af2d13, 0xb1c014da, 0x025db837, 0x9546fcff, 0x20de31b8,
- 0x159a8cd5, 0x203ad711, 0x96afc84b, 0x277eddbf, 0x2cc2f7f0, 0xdcba0133,
- 0x6039cf23, 0x3cd0bfdc, 0xa7a0f516, 0x47c1fd7e, 0xa0934ca6, 0x30f8821e,
- 0xc530a1e2, 0x9ecfcba6, 0xa8ba064a, 0xdb98a6dc, 0x90c571ee, 0xe18532df,
- 0xcdf6cfac, 0x7d99fff2, 0x1bed4c9b, 0x691cb5c3, 0x512b46df, 0x2c7fadf6,
- 0x56b2b6fb, 0x58b80fed, 0x3fab37b9, 0x6be575c8, 0xb2c5fa4b, 0xd8faaf6f,
- 0xbe35fdfc, 0x2073bb0f, 0x23a36fb5, 0x6a40dbec, 0x6dc462df, 0xffcd15d3,
- 0x59bec5ec, 0xeff477fe, 0x316fb055, 0xd1523bfa, 0xe6a2b7db, 0x456fb45a,
- 0x7edd4503, 0xcf852ca8, 0x6fb47ae7, 0x1b367f0b, 0x16cbb2f3, 0x57c03f03,
- 0x71af6fb0, 0x80ed073b, 0x38a45b9d, 0xdabefdb1, 0xdabed2b9, 0x3e25ffb9,
- 0xe56e766b, 0x239e7620, 0xcecc871a, 0x7664ccad, 0x665ee56e, 0x630e56e7,
- 0xdf68ce76, 0x1beca20a, 0x047abefb, 0x8be71efd, 0x83b8bf99, 0x95cf1796,
- 0x7efa165d, 0x5f9daab1, 0x691f19a8, 0x122916ef, 0xdeca39f2, 0x39e1ceb9,
- 0xddecde90, 0x86ef605b, 0x0a1b1da2, 0xc7c4647a, 0xba6d430d, 0xbe4772fd,
- 0x4bf5ff68, 0x107f2fa0, 0xbefd9e71, 0xf68bcd89, 0x163ed17d, 0xa7376ef4,
- 0xc98551e7, 0x47e7c3b3, 0x24753a7b, 0x43aaf7d3, 0x544e3871, 0xbfac0937,
- 0x15010bf7, 0x5dbf81c6, 0x9df2f9c2, 0x797cd97b, 0x83f1998e, 0xcec89bfc,
- 0x2c16505d, 0xdcc3c08c, 0xd718154b, 0x0b112b9c, 0x0e0baff8, 0xfc0a70dd,
- 0xd69705d6, 0x00bbbfa3, 0x89bec39e, 0x32eb6ded, 0x2e77bb68, 0xa1de7017,
- 0x1798efed, 0x3f7a97b6, 0xec737e76, 0x38531a7d, 0x13ee533d, 0xa72fb002,
- 0x2f107db7, 0x239bfd72, 0xc8bf21b6, 0xf8cc625b, 0x985ef6a4, 0x97c62e4f,
- 0x6fcc55aa, 0xf289f30e, 0xf9a2154d, 0xbc5d2544, 0x2f9bb530, 0xfda4ee77,
- 0xbfb9e94d, 0xf7a2df1a, 0x3e71b8e1, 0xd7bf80b3, 0x3e341f13, 0xf39ff547,
- 0xb8a9fa9d, 0x8fc8c79f, 0x5ccecd46, 0x5e814643, 0x3cf26fbe, 0xf4701e3a,
- 0x942f949f, 0x0de6dbce, 0xd9e79dd3, 0x9372f9c5, 0x54b4d8e7, 0x6a48f815,
- 0x97b76700, 0x4a903f6f, 0x3b8b77fb, 0xe6420733, 0x78a6ffb3, 0x62d0fe20,
- 0xa83b42ed, 0xcccd30e1, 0x8e57f870, 0x9c0323c3, 0x09bc70d3, 0xafd44e0a,
- 0xf1cec190, 0xca5e647d, 0x6f5fd067, 0x144f8f90, 0x859fa09f, 0x720578da,
- 0xa9bcffa1, 0x5bc5c999, 0x6e5ca023, 0x81075d26, 0x8229d5ef, 0x2aab442b,
- 0x21ff6e0c, 0xd57ab7ec, 0x9e839f4a, 0xcdae0b97, 0xf4f61d8c, 0x963898d4,
- 0x3718e162, 0x9b8c4609, 0x24bde00b, 0xc668b7d8, 0x1efceff6, 0x3f4647b3,
- 0xf5b98a65, 0xe533d008, 0x09b264df, 0x7fe8061e, 0xfa303811, 0xf07a5131,
- 0xa4fdf735, 0x2afdfb72, 0xfc0ec1c8, 0x1fc052ee, 0xf8d886f2, 0x257b95a3,
- 0x4df21a75, 0x8e904393, 0x1c98e32f, 0xc8dfa960, 0x3cb45be7, 0x6fde1fe0,
- 0x7ef86416, 0x324f9506, 0xfa6a9a2d, 0x7786a0e2, 0x2fcd1ab3, 0x47a42788,
- 0x6fb00dd8, 0xd596eb91, 0x4f91b7c1, 0xeea2ac37, 0x27cd1a99, 0x07603e4d,
- 0x28afc72f, 0x8fee09fd, 0x9bea7fb9, 0x599a4fea, 0xacfb3faf, 0x868faf5d,
- 0x015eda38, 0x4e690aed, 0xf20fc5d4, 0xd65e6ccc, 0xce20f562, 0x5d935ebb,
- 0xfb68d59b, 0x0b971573, 0xcf2257cc, 0x0e854def, 0xd3b1bac1, 0xfad13e4a,
- 0x2ce1843d, 0xd5783c72, 0xf5f941ea, 0x5e04ff54, 0x98fe4f7f, 0xb40eff96,
- 0x5516fb07, 0xf1c67b7d, 0xf5278b48, 0x6669afd6, 0x69be3f66, 0xbe76b4bf,
- 0x9783baee, 0x4dfc62b4, 0x2cd87f5b, 0xc32e7e7a, 0xd048b8fc, 0xca5073ad,
- 0x9ff2fd71, 0xe558ff50, 0xfc43f532, 0xfcf94428, 0x31a7b6ea, 0xf9f67d5e,
- 0xfe833763, 0x48adf8ac, 0x3a9f542c, 0x1093c5b6, 0x80a207db, 0x24d1509f,
- 0x91167ae2, 0x2333b942, 0xd6420cfc, 0x14bc7e30, 0x62a7768f, 0x4c503987,
- 0xf5d8afbf, 0xddc43649, 0xf6601e3a, 0xc73cffcf, 0x1b2dbfa3, 0x242bfbd6,
- 0x946f8eb6, 0x9f1cbdcf, 0xe6db7667, 0x1a16fd82, 0x8ad779d8, 0x39b239c6,
- 0x6550ce22, 0x7b5c5996, 0x59f70db7, 0x70139ffb, 0x17d0329f, 0xdb52ce79,
- 0x39e679ff, 0x822b9766, 0xcdce0072, 0xef6c3456, 0xc5783880, 0xaffa3351,
- 0x0a7386de, 0x5f53a7f8, 0x23fd017a, 0xc5d4506f, 0x8fe2a341, 0x0cc8620d,
- 0x2aa6b3f1, 0x7f3403b4, 0xb18df30c, 0xc5bdf0e3, 0xb4bc56c9, 0xb29f9777,
- 0xcfcbc570, 0x6cdcf03a, 0xc60756eb, 0x1f2e1b21, 0x378a8fff, 0xd9743e36,
- 0x8e69e378, 0xf5995f8f, 0x21a435eb, 0x9490e319, 0x1892dcbe, 0xee308b71,
- 0x29ecf85f, 0xb33b0f58, 0x014fafe3, 0xb8ff95bd, 0xe07dd4f0, 0x3ab3ed8f,
- 0x3ef6bc61, 0x13d7047f, 0x7376efb4, 0xee78ef3d, 0xe9875c59, 0x05d9a3f8,
- 0x3dec75b5, 0x23d61831, 0x917fb63a, 0x55db710a, 0x3ce3a77b, 0xa9ced56d,
- 0x798c49fd, 0x6e029680, 0x07587d03, 0xa5abca32, 0xd03065a9, 0x1bca9679,
- 0xfc70b65c, 0xc58ab1b8, 0x371e55e3, 0xbd7b16de, 0xdc4e2a2d, 0xeb96f334,
- 0x926efc60, 0x43e92a5d, 0x9530f8bc, 0xc83ee8e3, 0x9a43db6f, 0xbf298fbd,
- 0x2a0ff0b3, 0xf20df7a7, 0xc969acfb, 0xb2849eaf, 0xe31ee4a6, 0xf03ea1c5,
- 0xdbcf5b4d, 0x6c7f7662, 0xf1d9bd06, 0x83cf8c6b, 0x835ce8dc, 0xd9f0bc74,
- 0x9cb38860, 0xc2eebb94, 0xcd7b33fd, 0x62aa2fb8, 0x3fa8fbef, 0xc6df3b1d,
- 0xd7c232f5, 0xf8483ad5, 0xf083ad8f, 0x4b779c39, 0x73338b3c, 0x5a1c43fe,
- 0x1e73e075, 0xd638666f, 0xc53dd0e2, 0x6c2dd39f, 0xceb6913f, 0xcfe5b558,
- 0xf5c4310a, 0xd3903c85, 0x8baecbb1, 0x02707c6a, 0xae44261f, 0xf38ec4a7,
- 0xb8ddd787, 0xe07e40bc, 0x4bd7857f, 0xc4207e68, 0xfbc203cf, 0xe83d8624,
- 0x61d6c4d8, 0xfbd8e43a, 0x95f5b50f, 0x4f418b14, 0x575b7d03, 0xaffe8de9,
- 0x26191fcb, 0xf9a3e39b, 0xd8cbe674, 0x45827c76, 0x61fb76f8, 0xf5a8852a,
- 0xcfac0b7f, 0x60531d37, 0x638da1fe, 0xf0cf7f5a, 0xe799f279, 0xb1ef3c45,
- 0xed05b1ae, 0x545ed1b8, 0x341f1613, 0xd3833bd2, 0xe3641d5b, 0xf11d99c4,
- 0xe7ad3b01, 0x11bb2bcc, 0x8edbd5cf, 0xdf5a7e29, 0x959786c1, 0x52fd88b6,
- 0x22044e30, 0xe2f33fe8, 0x7eb66cfe, 0xc6e5e6c4, 0x76f0e676, 0xdbb1cdbc,
- 0xa73b6ef1, 0xbf85676b, 0x77e76151, 0x69dedf2e, 0xea073dc9, 0x132add3b,
- 0xba7fbfd8, 0xc40a2c51, 0x45927f68, 0x4cf2e2d6, 0x8978e86f, 0xd9e31de7,
- 0x493146f9, 0x557aff41, 0x84d1de7c, 0x15154814, 0x6a6b14e2, 0x35d2fed9,
- 0x81a577df, 0xde24d7bc, 0x756deb86, 0x533afe06, 0xbf10f99c, 0x192b4e70,
- 0xda357007, 0x49b7449b, 0xf8aaff47, 0x1e70fea2, 0xc7f72d7f, 0xf3c2e488,
- 0xb0a3a297, 0x3a23fa08, 0x8c6b4e4d, 0x5ed905f5, 0x7c113c42, 0xf3fa9d91,
- 0xb1cbe492, 0xeda3d42a, 0xb4b4a9a3, 0xa742c41e, 0x4b0ab71b, 0xfcddec79,
- 0x77ec4e59, 0x4f3e36e7, 0x99d51370, 0xc183f6ca, 0x23b9d1b8, 0xc68c9b21,
- 0xe29b890f, 0x0b9fc6d1, 0x07eff6db, 0x41d6b47b, 0xcf5489dc, 0x31555728,
- 0x8e8dce0b, 0x805908b1, 0xfe6f73d3, 0x6d6bd696, 0xd0fe7116, 0x85f6d769,
- 0xcf4113ba, 0xdc11e46c, 0xfe5007ff, 0x4e9bb92a, 0x0240bee3, 0xdf76a4af,
- 0xb45d312b, 0xfce7bce3, 0x10071646, 0x98bfd5c9, 0x2470e2cc, 0xf1f3f400,
- 0xf3a70564, 0x7ef0a43c, 0x3ae78299, 0x72f6bd96, 0x3930886e, 0xb92bf244,
- 0xb4be7f48, 0x86c8eade, 0x77e27975, 0x9939c2b7, 0xbf5f5e32, 0x53b9fd12,
- 0xd07e7eaa, 0x4f5c25d3, 0xf0b4baff, 0x32bfd810, 0xebb452cf, 0xcfeae7fd,
- 0x59f71aa5, 0x2fb0bd21, 0x93ddea8c, 0xabbef442, 0xd6c7e6f2, 0x7a397cc1,
- 0x011915ff, 0x482ac9fb, 0xe7ce0b9c, 0x97d068ac, 0x79bb03ef, 0xd893b015,
- 0xebef172f, 0xc36dbf95, 0xdc79317f, 0x0aebf965, 0xe2dbfbc1, 0xecb2ae31,
- 0x9f68c5b5, 0xfe7a69cc, 0x7f3d555a, 0x7c8c236d, 0xde39f3d4, 0x369be7a5,
- 0xcf89ecff, 0xf3fa7909, 0x4b3e46be, 0x021bc784, 0xb5110e2c, 0x09b82dbf,
- 0xd9f236e9, 0x0b76d7c8, 0x7ce2f75f, 0x96257fa5, 0x81b26654, 0x842974ee,
- 0xa3d4617a, 0x80487b0c, 0x094a0f7f, 0xae57e2d4, 0x69efb478, 0x19423fbc,
- 0x7a06cefb, 0x2ebd0224, 0xd13823d4, 0x46de7607, 0x5bb6703e, 0x909f5841,
- 0x59e9aeaf, 0xfe94f79e, 0xfa22d8fe, 0xefc046d5, 0x762bd468, 0x0489376e,
- 0x9e8264d6, 0x6e309cba, 0x6a2cfa37, 0x9ff70499, 0x286cb510, 0xc4e27bdc,
- 0x1f7cc7f4, 0x8248e74a, 0x431b82fb, 0x3ec15317, 0xeba738fd, 0xde7bb066,
- 0xec04a425, 0x6c71cde0, 0xa798b29e, 0xdc2ab77f, 0xed7b4eae, 0x59bef87a,
- 0x785ce156, 0xcb56f367, 0x4507c830, 0x9bc47fbc, 0xb4157758, 0x332cd1df,
- 0x812ccaba, 0xd8bf1061, 0x1dbb632b, 0x7cf19365, 0x6b6fd865, 0x3a40fb66,
- 0x2c713f9b, 0x1de7b08e, 0x055e9fc1, 0x4c27acf1, 0x0c9ff7b1, 0xfdf89ab7,
- 0xfc70df35, 0x7fda8c6d, 0xf6cadc37, 0x0878fdc7, 0xe97547ed, 0x330e3e79,
- 0xcb96b87d, 0x6f4bf7f9, 0x6ceffec0, 0x47185416, 0x6e3bc50a, 0x39fb451c,
- 0xe3c488f1, 0x392e2c30, 0x9bbfbf8e, 0x1f80d2b8, 0x0223af13, 0x3fc4f3e8,
- 0x35b7dc12, 0xce2966ae, 0xa0eb7eab, 0x7586cf38, 0xb05b8a52, 0xe8ec6773,
- 0x956f8fbf, 0x9c4cb874, 0x798169e6, 0x04a384e6, 0xa384eded, 0x123cf2fa,
- 0x369db110, 0x4f6bf3fd, 0x5605f3ea, 0x49076f8e, 0xf86f7c05, 0x3aba4452,
- 0x01eb88bb, 0xd9676f5a, 0xa6efbc00, 0xda9c22f3, 0x6297e9a5, 0x7e71ac51,
- 0xf281e026, 0xe08509eb, 0x52c4f2f8, 0x5fefc63b, 0x05715a59, 0x7f9feb8c,
- 0xac4573cf, 0x7611e073, 0xafed8129, 0xe2502772, 0x0ad7ae29, 0xe975df8c,
- 0xebf63125, 0x70d6386b, 0x7d39e1ad, 0xd6279c69, 0xad0fc4be, 0x58290fcc,
- 0x6050423a, 0x204fb65e, 0x078ed7c0, 0x373d973c, 0x640f27e3, 0xe0de3d00,
- 0x2db3f405, 0x963b82cd, 0xeacab19f, 0x07bef360, 0x1fb0b5fc, 0x94aa5eef,
- 0xae7b1f60, 0xabce0377, 0x2ba0876e, 0x5ba9677c, 0x9770e788, 0x8866c858,
- 0xe9754b67, 0xee03c6b7, 0x4758cea7, 0xc4b27de9, 0x427e7284, 0xfefd2176,
- 0xbe30422a, 0x03b5e3c0, 0x229b266f, 0xc0ff23cf, 0x95b0ff9a, 0xd5b0fbd6,
- 0xf6497289, 0xdfa004b8, 0xe5ffdff5, 0xbceebd00, 0x0e394664, 0xed1ff3e0,
- 0x4f9cadbb, 0x6bdce3a3, 0x3ca4ff01, 0xe5c3f505, 0xc965a871, 0xe5012f70,
- 0x54758c7b, 0xf24d2fcd, 0xe946db50, 0xf09bb249, 0x76e22e7e, 0xdf6d4eab,
- 0x45efe119, 0x090903e8, 0x69a5f604, 0x166854f6, 0xff14f142, 0x10f62ce3,
- 0xca9233cc, 0x0929bf69, 0xf5616256, 0xc2674ab5, 0x9f71aae7, 0x2e65c53b,
- 0xb8226e1c, 0xd2360daf, 0x9d9afd42, 0xdaf3ecd5, 0x66f68244, 0x605263ed,
- 0xa367ad0d, 0xf88566d4, 0x2d5ba649, 0x4944ad80, 0xbde78a92, 0x7d339507,
- 0x32fd65b4, 0x50afec31, 0x0ff31f65, 0xf5ac4171, 0xfcc38fba, 0xfc00bcf2,
- 0xf5d43eca, 0x2e35b80a, 0x75cf6b2b, 0x79fe82c0, 0x3f706ed8, 0xbb8f90ac,
- 0xb1353f13, 0xeba102fd, 0xb69dbf71, 0x1bb4668e, 0x15de0f54, 0x953eaf41,
- 0x75cf9e08, 0xb572ffd3, 0xf611772d, 0xb9938f83, 0xf4169ac1, 0x2d91c4dd,
- 0x5f6bc780, 0xa238bbc7, 0x3784c8ec, 0xde806b3c, 0x8c3f6a6f, 0xa2131878,
- 0x33e5c8fa, 0x2a7b8552, 0x943ce19c, 0xfcf95ab7, 0x949bdb8e, 0xd1fd71d2,
- 0x3338e5af, 0x6bd357f2, 0xace7bea3, 0xb198b576, 0xc13200d6, 0xba110ed8,
- 0xc0b350e9, 0x8221bd1e, 0x4f99df7f, 0xbae942f1, 0xfc0ef417, 0x19818bf3,
- 0xcd0d9b80, 0x7e82b1df, 0xa3f1e37c, 0xb11d7e99, 0xa227fabf, 0xf6cac3a7,
- 0x0f803b87, 0xf22ffbd5, 0x728423f1, 0xea95cb0e, 0x443c6447, 0xe711bdc3,
- 0x81ac5e9a, 0xf0b2330b, 0xf9011c7c, 0x0a234288, 0x3a364cd6, 0x7f9aaf81,
- 0xcfec26bd, 0x9eb9e226, 0xded64e55, 0xcbf3591a, 0xefe8165d, 0xfe82f8aa,
- 0xf5175b97, 0x97f3a25e, 0x5e30f388, 0x67e70ba9, 0x090a4bde, 0x7e0b7f24,
- 0xb9eb6905, 0xc4a57e3a, 0x0757e0c5, 0xfff8d1e8, 0x6d93fb27, 0x6a83cfec,
- 0x25ae7f77, 0x51b6df9e, 0x4f7b90bb, 0x05c33a7d, 0x89169c39, 0xd95ebe0b,
- 0x51e77e93, 0x2dd706fd, 0x7a0d9f4a, 0xea99b13c, 0x8f5a29b1, 0xde09725d,
- 0x6bdae75b, 0xd4677b43, 0x5fbc8beb, 0x7be31b5e, 0x1199e88d, 0x5371f307,
- 0x5dc060d7, 0x8b924ab6, 0x41d9b129, 0xb6afad91, 0x91c6eb26, 0x8fddf1e8,
- 0x2ff35276, 0xf8d2bf35, 0xe4afd85e, 0xcf1686e3, 0xff148214, 0xc7f7dfb4,
- 0x5f01e679, 0xfcd938d7, 0x829a0e13, 0xab03fcbf, 0xcfa00ee7, 0x0710fb46,
- 0x42231aeb, 0x125e2c99, 0x4f5be9d2, 0xe83365fa, 0xc248634f, 0xc74fcc71,
- 0xcf4261b1, 0x4b8bf4f4, 0xab52f464, 0xc0ca7e02, 0xab1ac25c, 0x7bafb826,
- 0x47bb3660, 0xbb0e6066, 0xe3dff1f7, 0x7dcc7ad8, 0xd0dc6c71, 0x4b581fd2,
- 0xc97e81ee, 0x739bf112, 0x40dd39be, 0xef0fc42a, 0x0ddf738f, 0xb914b0fc,
- 0x4e191fb1, 0xde2812e2, 0x0146a432, 0x552437f6, 0x1b8b02aa, 0x40ee3612,
- 0x28cbeb4a, 0xdc61f356, 0x16b6a0ca, 0xcd1920e2, 0x6cf5cfb1, 0x5dbf9388,
- 0xea29abbc, 0x3886ca3c, 0x541f6fe6, 0x8b937f68, 0x709479d9, 0x0f9286dc,
- 0xbf88edfc, 0xf1db3b0d, 0xf50f5b19, 0x1b3e3227, 0x30205fe7, 0xf3c497e8,
- 0x6488543f, 0x91f9c24d, 0x99df04df, 0xb23f382c, 0xd8235711, 0x58e297cf,
- 0xe09d755c, 0x9ff90f5a, 0xb8165d48, 0xffc3476f, 0xeadf278f, 0x8e2be892,
- 0xc367ceeb, 0xc3ea959c, 0x8eaf20f3, 0xaf87e7c9, 0x0d741ec5, 0x8b737866,
- 0x9aeffdba, 0x4eb282dc, 0x8788566e, 0x78ebda44, 0x1df7e705, 0xe60b9c42,
- 0x05cb1d43, 0xe160a746, 0x7d2403e7, 0x43db869c, 0x27781c6d, 0xb7e9132e,
- 0xbc18ff11, 0xb2e2cc1f, 0xfd1a3d00, 0x86a473e1, 0x73c69e73, 0xe15969a0,
- 0xee3a4db8, 0xe0512d93, 0xbe722f8e, 0x97fe86d9, 0xdff4c1d7, 0x60fe8788,
- 0x6e732e3c, 0x15abf292, 0xae5fdbe4, 0xdb7b0449, 0x0ee3ceff, 0x0f91af90,
- 0xcc7f829d, 0xfadf5841, 0x9f731c83, 0xa5a69688, 0x7f05280d, 0x0d3d2d34,
- 0xbd79ed53, 0x07198a5d, 0xeef5cd3c, 0x9eb5e31b, 0xc3f30c58, 0xb39fd0d3,
- 0x73de779e, 0x6177baa3, 0x8e3ebc7c, 0xd15ebbf1, 0x8026a8f8, 0x5de7759e,
- 0x927eec09, 0x90ff7644, 0x8373c993, 0x492a52cf, 0xd1b9ef91, 0xdc47e91f,
- 0x1181e633, 0xad9320d8, 0xbf166b88, 0x5065ced1, 0x97e4c743, 0xb9fae8c8,
- 0xec294c6f, 0xcc6d919f, 0x30dc5d2e, 0x254bdb1d, 0x5387580f, 0x312d2ebe,
- 0x73ae20b9, 0x1c9fd176, 0x517c1470, 0xe02e6b46, 0x91e888fd, 0xd431e36d,
- 0x65b7f38d, 0x88409573, 0x9ea52a42, 0x9726241a, 0xb8eeb819, 0xff7314d0,
- 0xe6c6ddb3, 0x4e71cddf, 0x06d2d34c, 0x8d8d9697, 0x39440fcc, 0x7aa47869,
- 0xae365e98, 0xc5309cfb, 0x6fb40a47, 0x994ea7d4, 0x40dd6104, 0x9c2987b3,
- 0xd63d9aff, 0xf40521f4, 0x4b01d60c, 0xe4d47da8, 0x9abf8439, 0xfc4af18a,
- 0xfd5f9a13, 0x8e03e602, 0xded00aeb, 0x8f5ffd51, 0xd98232fa, 0xd3d82b6f,
- 0xe7653888, 0xc107f7de, 0xdf87dffa, 0xeb0f10bf, 0xba917f40, 0x9e7ec1e2,
- 0x78ddffbc, 0xe1f43738, 0x715e2cfd, 0x351e6197, 0xfaecc6c1, 0x6c92b6a3,
- 0xdf02d7e8, 0x227ae77f, 0xb3564970, 0x01e58d75, 0x5c9e70d1, 0x554f2f7f,
- 0x9ee1b263, 0x5bd63f1e, 0x32e7efc5, 0xcb92a1ca, 0x4db6f961, 0xed0a864a,
- 0x7eb6dc7b, 0xa08f6e70, 0x14d93cbd, 0x8d11f38f, 0xc6db459e, 0xfa773028,
- 0xaf99b34b, 0x6ccab77f, 0xc317705c, 0xf387967a, 0xc1e748cd, 0x6fac367d,
- 0xfed8cfc9, 0xadb48594, 0x7abed4d5, 0x0b79d99a, 0x7c963f63, 0xa7f616a8,
- 0x90f25bc2, 0x7862f380, 0x4e3a7eff, 0x883f5679, 0x7ec65eeb, 0x31cdef1a,
- 0xe6d55f9e, 0xfcb8cb53, 0xf50788cb, 0x6b5cea2f, 0x369f5b33, 0x1fceffc6,
- 0xff61b2ca, 0x91fe3c6d, 0x79c0264b, 0x86871de8, 0x3eee5c24, 0x1efc33e5,
- 0x1a57b826, 0x823e93d2, 0x654db669, 0xbf3464f7, 0xaae02f7d, 0xef1db83a,
- 0xf6bafb19, 0x94f9aaa6, 0x6b30f603, 0x91fa8776, 0xa43f01ab, 0x97f9d04c,
- 0x282e9bd5, 0xf8cbbe6c, 0x7e7f0770, 0x1b37f407, 0x3fab59f6, 0x7ce54c9a,
- 0x317ca547, 0xbf321ef2, 0xa6ee7f4d, 0xfad5fdaf, 0x2b5bf5a9, 0xd1fbe2af,
- 0xf869df8c, 0x2c78e6cf, 0x6eba52db, 0x9ad16500, 0xf30627bd, 0x4e7868f3,
- 0x1197c347, 0x4948cb3f, 0x8110ba61, 0xb147e693, 0xcb3c9a5f, 0xfef216ea,
- 0xbaf8d3fb, 0x8fc41a5e, 0x118dc37a, 0xdb721d1f, 0x2367d060, 0xb87a3a3e,
- 0x3627e45f, 0xa99427e6, 0x678842ee, 0x9d763751, 0x394fc233, 0xbc1dd529,
- 0x0b6cf40f, 0xf8c479c3, 0xd7b99ccb, 0x57cf1c65, 0xe1fdabc6, 0xdb943d3e,
- 0x6017d844, 0x5a7bc3f6, 0xb73eed3b, 0x7c04a86b, 0xb4f4c22f, 0x7435c4af,
- 0xd2f97768, 0xc0382e27, 0x411cee8f, 0x11d38e30, 0x77f7a7af, 0xf9e91136,
- 0xa543971d, 0x3f8ffad4, 0xd2da8d83, 0xda1dfb8a, 0xa071e4bf, 0xb145cd2f,
- 0xfe27f9fa, 0x86f7e11d, 0x4cf5c5dd, 0xe02c979b, 0x99abbb72, 0xda2f67ad,
- 0x30f28a58, 0x437ad7ee, 0xd0661670, 0x638d3caa, 0x51bf9014, 0xdf5c4b3e,
- 0x51607dc1, 0xf08f2272, 0xdc1e017d, 0x2f5653a7, 0x28c3dc62, 0x93bb7cbf,
- 0x6b57a39d, 0x42b71e70, 0x790ebd8a, 0xb5f4dda5, 0xc7ec63fa, 0xed0126c2,
- 0x65fe91a4, 0x0dd76a5b, 0xd67fd020, 0x847ee8bf, 0xe25da206, 0x55fad4fd,
- 0xff785c46, 0x50fad440, 0x7224f5db, 0xe6f2f53f, 0xbf2fb8c5, 0xb09ff69a,
- 0x85c61238, 0x7a35fa34, 0x1428fd8d, 0x8816c8cf, 0x5c16aee3, 0xefa39f60,
- 0xeeeb7327, 0xb0d85c3f, 0xafc8207f, 0x66fb625d, 0xce02fddb, 0x203f3b0b,
- 0xbd607d6c, 0x3d69eb80, 0xed99afca, 0x8e59ea07, 0xe7dc0a35, 0x8851b657,
- 0xf565c729, 0x11a1aef9, 0x60796a76, 0x8ea86b86, 0x1fdc46de, 0x54a1a2b2,
- 0x9d807cf7, 0xfdb893c7, 0x48df4dee, 0x38cc624d, 0x9a5fa693, 0x97fa69be,
- 0x3cd9576f, 0xcc1c0a47, 0xfebb04c8, 0xa84bce18, 0xcedabe5d, 0xd1e607d7,
- 0xb89faa57, 0x581f5ba0, 0xb3e4c792, 0xe7c62c44, 0xca57d93d, 0x1e7d9d07,
- 0x7fefd767, 0xd1fdb6f8, 0x85e9a1fa, 0x5ea33fd6, 0xc5aff918, 0x30728cd5,
- 0x82e81ff2, 0x7b1bc1f9, 0x0407816d, 0xa74677d0, 0xe915af7f, 0x702b48ec,
- 0x3fc839c1, 0xce9407c0, 0x31dbf4ea, 0x9496235f, 0xc75e71da, 0xfae34de7,
- 0xe1c83f16, 0xab4ed67e, 0x473b2c7b, 0xb80c9254, 0x36db5298, 0xf8a4e2d3,
- 0x2174647c, 0xe53a2bdc, 0x1099b6b1, 0xc8f25efa, 0x5fb84298, 0xb6d6ca7e,
- 0xea2e2d77, 0x2d8ed5d7, 0x57e5fb84, 0xf680dd80, 0x10db9607, 0x89e53d57,
- 0x9579f2e7, 0x5cce3fbd, 0xcbdd9f32, 0x292bcacc, 0x3c742d8f, 0xfc3c3cab,
- 0x959fa0f7, 0x1045c5ad, 0x8884a9b7, 0xaacf1d37, 0x2d908edc, 0x93e78d9b,
- 0x6cdb7be8, 0xf076559e, 0xc5ad2eeb, 0xb0f2adf1, 0x0e44fa84, 0x44a8b8b1,
- 0xdfa56afb, 0x7ea38dad, 0xdaefe52f, 0xe60b8b24, 0x1fb9f4af, 0x936bb5e6,
- 0xf11aaadc, 0x7c1f935c, 0x35ac7407, 0xfdfb75b1, 0x684f0daf, 0xbf78ccbb,
- 0xc32647df, 0x67c5a43c, 0x9e58d4c1, 0x7cf138af, 0xc589be44, 0xbfe58c35,
- 0x512cecd2, 0xd5170033, 0xaf161487, 0x4fe07fa6, 0x17a61156, 0xeb9d84d5,
- 0xf04c3aaa, 0xa1f54b1c, 0x02c73c42, 0xd63ffcfb, 0x735ff0e1, 0x571ba58e,
- 0x92054f8c, 0xc08a5930, 0x55bb34f5, 0x9bfb1797, 0x887f4046, 0x7382e718,
- 0xa9866218, 0xbfed0766, 0x294d0578, 0x4ba7243f, 0xea5afb84, 0xe1114ea6,
- 0x3235a9be, 0x62623fdf, 0xf6b5cce7, 0xb47f389a, 0x64bdb4f4, 0xecfdc807,
- 0x36b9ad5b, 0xf3817eb6, 0x6bbfad61, 0x60113704, 0xe08075de, 0x149c80f9,
- 0xb3fc02d2, 0xe01e7711, 0x127b3ded, 0x375b37e7, 0x90197fa6, 0x97a6ccba,
- 0x57f78a55, 0xfa84591f, 0xdd304ae0, 0x6ff34993, 0x7cb197d9, 0x2642e986,
- 0xf6dbf085, 0xc6bf9672, 0xcd086174, 0xce5f6bbf, 0x49c0b0f2, 0xf623b607,
- 0x48ff428a, 0x7de38768, 0xc01afb9b, 0xf16264b7, 0x0515e917, 0x7db453d7,
- 0x44e96b21, 0x1ef8f00b, 0xa7884dd8, 0xdafc16d4, 0x02eaf106, 0x3dfb0ab7,
- 0x837bf336, 0xf1aa69be, 0x7099b455, 0xf02903fe, 0x4fce43ff, 0xc9a42e4d,
- 0x8bec0d7d, 0x6bee8d25, 0xb4ed1d60, 0xf606d3dd, 0xad1bec66, 0x377ec053,
- 0x5ca7f3bd, 0x0afc9fbc, 0x37d8cf56, 0xf6909ce8, 0x066fece7, 0x8f5c8a6d,
- 0xffcf6d3e, 0x62a3be14, 0x5054ff40, 0xaa0ee49d, 0x44dc6b87, 0xbe60b255,
- 0x362f9fac, 0xb69f6611, 0x82ce4ad9, 0x10c0c95c, 0xf6455b8e, 0x6bc84e92,
- 0x26b49cf6, 0x9b5f69f5, 0x845abd92, 0x23293971, 0xd8117478, 0x7bb1dfff,
- 0x1bb7043d, 0x14be73f7, 0xed8cd7be, 0xfec1b10f, 0x177fd010, 0xf2a7f349,
- 0x2f8b17f8, 0x88dc9493, 0x07ef3079, 0xec1a7efd, 0x63609f37, 0xbf6807fb,
- 0x63abb044, 0x58e98a88, 0x81656788, 0xdf983d28, 0xde8f1a43, 0xdc7feb47,
- 0x9649e2ca, 0x0f8ba206, 0x38b3c766, 0x8b074ccb, 0x8dc9c60f, 0x10ff82b7,
- 0xc1388e77, 0xa5fce87f, 0x22fee122, 0xae2379c9, 0x11341d8f, 0x3959f7a0,
- 0x99f584e0, 0x7524abae, 0xafaee933, 0xab5bcb93, 0xbd4571f7, 0x7372e20a,
- 0x7d3fcc1d, 0x7ee09f36, 0x4a53aee8, 0x934dd600, 0x91352c32, 0xf92b9ff1,
- 0x0b390f77, 0xfe21e332, 0x408e37bc, 0xc5f613fb, 0xbf0e4099, 0x056396de,
- 0x3c04bc3c, 0x32487ca2, 0xfa86ef3b, 0x7a502e92, 0xdb39f133, 0x63a92f27,
- 0x277f2812, 0xe15760dd, 0xad67a9be, 0x7ee0378d, 0x784c17d0, 0x8a4beebf,
- 0x2ff214ab, 0x609d579d, 0x6ccd9f7f, 0xbcfec38c, 0xbcfec260, 0xf575d714,
- 0xc3f74a4a, 0x4a7c5823, 0xec0911b2, 0x502a64b2, 0x73cfa6ef, 0x493cd9e3,
- 0xe3cbd3b3, 0x2e3cfe99, 0x200f3c10, 0x7f51f299, 0x9d3afdb4, 0xebf7045d,
- 0x2ad59bf4, 0x4ae38e02, 0x4851b8b5, 0xe4cf7884, 0xdb7e8212, 0xe78cbb64,
- 0x307f6072, 0xc29b1b9c, 0x0f94efed, 0x813d712a, 0xdc30e04a, 0xe762d97f,
- 0x75f168f7, 0x4e39ebc5, 0x226d23ae, 0x5dd791f8, 0x07882e22, 0x8a497f5d,
- 0xe74e47e9, 0x10233ef5, 0x97be8129, 0x0095517f, 0xef44f977, 0x2faf4de7,
- 0xe0e3053c, 0x39e18b54, 0x8f4889f8, 0x4ff7cf1b, 0x4fee1a77, 0xd6f3e78e,
- 0xe47064c1, 0x1d6d313e, 0xf238ba68, 0x8b53f409, 0x65f01714, 0x3efdddbb,
- 0x5bfa7bac, 0x38b97265, 0xb63e33e2, 0xa5c46f9f, 0xa1ff5c38, 0x2e03b4f8,
- 0xf3afaeae, 0xafbf695b, 0x07eaca1e, 0xb95d821c, 0xc92997f2, 0xf1cde760,
- 0xa968decc, 0x97c03b86, 0xcbe18133, 0x3f5bba39, 0xe267c557, 0x01be9a7b,
- 0x3d9ea0ee, 0xac7e6072, 0xd78a6575, 0xedd78055, 0xb3f38276, 0xe65ba51f,
- 0xed699e82, 0xf86789ec, 0x6aeba637, 0x7587ee57, 0x6c67ff1d, 0xe03698bc,
- 0xde391292, 0x3864e87f, 0x3375aaf3, 0xf3fda66f, 0xbf5c65da, 0x8be7e549,
- 0x1e92f122, 0x770d1781, 0xef16761d, 0x7533f0d1, 0x3c22bbf7, 0x2119fa9f,
- 0x9e124cce, 0x99f86887, 0x9c3867e2, 0x138d8872, 0xddc7e1bd, 0xe6069ce5,
- 0x87370a31, 0x280a6e18, 0xb7f7f03e, 0x118fc07a, 0x8af54f37, 0x3cf12f9b,
- 0x53bdaafc, 0x186ebb2f, 0x7df7e9f4, 0xb689d31a, 0x8f82fbd8, 0x56ef7e72,
- 0x06cc6eea, 0x8993717b, 0x48937f9d, 0xe714adc6, 0x7bb4e3bb, 0x20b26be5,
- 0xf6625dbf, 0x19b37b67, 0xbb76cfed, 0xd77183c7, 0xcb9e0b34, 0x0da79226,
- 0x06bbf5f6, 0xdfc8d458, 0xc72ef8d1, 0x9a1ca361, 0xeffc0278, 0xf3fc98d7,
- 0x1b81ca6e, 0x197a48ec, 0x93b8c393, 0xe21126ca, 0xfdfc8e42, 0xe04faf80,
- 0xc3c02d4e, 0x25ef0571, 0xa0ae3eaa, 0xbecdfc5d, 0xbe210bb7, 0x9e1feda9,
- 0xc2ede7b0, 0x3ef09182, 0xdc6bd9c3, 0x3c796aae, 0xd276014a, 0xc4fd2f70,
- 0xfd2679f0, 0x8025f2bd, 0x72eeec9f, 0x73eb7de3, 0x1d1784e0, 0x736d6e77,
- 0x60b3074d, 0x4e7d6fbc, 0x9b1f9d88, 0x1d3dd47d, 0x7dd4654c, 0xb70f1ceb,
- 0x715dd691, 0xdffdf462, 0x163e7c74, 0xd7fbf10f, 0xc1c40a43, 0x6b9a951b,
- 0x26a27cd8, 0xa68fec0b, 0xf947f877, 0x08e1f8d6, 0xc3ff7ddd, 0x88f3f8f8,
- 0x38f7624b, 0x4eb829b5, 0xdf6128f8, 0xeb71f235, 0x39f7ae2b, 0x0f9c5eab,
- 0xb96c70f6, 0x576dd71b, 0xfe7c4539, 0x64b21213, 0x125cbc81, 0xca3477ae,
- 0x4213d4ea, 0x2a447bf7, 0xe5a76119, 0x8dc5fa7b, 0x70eff685, 0xf00e4c78,
- 0x43aea42b, 0x4984ddf0, 0x6ec16339, 0x4dacc7db, 0xa34c7186, 0xb455d29b,
- 0x874dded5, 0xc7275746, 0x858e1dc9, 0xf678c726, 0xe0a1d81d, 0x7c0b76b1,
- 0x71a0e1af, 0xff2639ef, 0xfc803c08, 0x2c20f1bb, 0x07c6bc80, 0xfcb54f1b,
- 0xa10f1f3f, 0x1e9f2081, 0x087100f1, 0x43c2b7c7, 0xc355f016, 0xaed7f503,
- 0xfe68fe02, 0xf6c2a35a, 0x0d796a1d, 0x7cf64507, 0x10a5cf7c, 0xf6443fdc,
- 0x6d39d959, 0x57ae224f, 0x6d64ecbc, 0x3ed87e74, 0x6498ba98, 0xebf983b2,
- 0x8c89efda, 0x57e80909, 0xe106a18e, 0x06e3f40e, 0x71743da2, 0x4176917e,
- 0x71377b80, 0xf806796f, 0xd064a197, 0xe2e6318b, 0x877fe010, 0xf8064a6d,
- 0xc9b63987, 0x5daf8059, 0x0ebd5623, 0x01aed643, 0x516f2fe5, 0xcd27fdbb,
- 0x6af0b5ee, 0x746ff6b5, 0xbd74fb30, 0x020f9d9b, 0x87491dbb, 0x2c41ff66,
- 0x9a108740, 0x86cafa63, 0x0db9baf6, 0x41d039ec, 0x205fbaf9, 0xe41fe04d,
- 0x5329dc9b, 0x17ebcfc1, 0xcece8092, 0x860c5fbd, 0xf3716538, 0xde8147ab,
- 0xd43d6d62, 0x350f5fa5, 0xbf9ad1fa, 0x342bcda3, 0xcf9b487f, 0xe504df82,
- 0xd3b9fcd9, 0x26add6cc, 0x6e782c87, 0xeaf3f1f9, 0xbfae6e55, 0x3147ed12,
- 0xa42dc7ef, 0xeed2e915, 0xf399b91d, 0x9d10f8a3, 0x39436687, 0x3e513721,
- 0x1defc4dc, 0xbfa5c9b9, 0xbc96e157, 0x688ef7d8, 0xbef6f4f5, 0xd6b87c71,
- 0x6df46eb0, 0x763e43d3, 0xfa7fc8cf, 0xd2773cd8, 0xc12fd110, 0xce979a80,
- 0x327069ee, 0x62521c3e, 0xb9fb578f, 0xb5324efe, 0xe5b9c365, 0x8efe7bfd,
- 0x7b2be3e3, 0xf81efefe, 0x494f1389, 0x4eb5f604, 0x012e353a, 0xd2f3e7d7,
- 0xab593d70, 0x9369fbd7, 0x88e7b08d, 0x5777ed1f, 0xdc7a520e, 0xc167d00a,
- 0x1e67b7f4, 0x77d429ff, 0x2244b8f1, 0x2a144dcf, 0xc710a19e, 0xbfbfe42d,
- 0xfe605073, 0x907e5692, 0xf3c5eeff, 0x21b0b71c, 0xc48fbb42, 0x9be7211c,
- 0x9a193df8, 0x593a6f5c, 0x8eca4a74, 0xfdfc0f96, 0x5a0be233, 0xf399a15c,
- 0x11fcb48f, 0xa77cb7cf, 0xfc096ee9, 0x89a4eff3, 0xeed11dc4, 0xe0ce950c,
- 0x2f1ce223, 0x4a7e0c3b, 0xbd3f73cb, 0xde2b8e99, 0x4adc4437, 0xfede6de8,
- 0x5be4367a, 0x8ff798c5, 0x9dfbf918, 0xfef1bbe6, 0x2a092191, 0xfb5bd3d2,
- 0x38a6ae93, 0x27720d19, 0x65cbcfcc, 0xe51877f7, 0xff9ecafb, 0xd91b6e48,
- 0x927bbf33, 0xbf0e51bf, 0xeb80533d, 0xc3c9bd4e, 0xb47ddb88, 0xbfda7e9f,
- 0x9fa7ed10, 0xf8af63fa, 0xbdff989c, 0x1af30d2f, 0x9f7bbd5e, 0x4e7f064e,
- 0x64f4e9c3, 0xbb899b86, 0xec4c9a7f, 0xf232f2dd, 0xf30773ed, 0xd710e66b,
- 0x3fe99bec, 0x78ae0a77, 0xd27e17b4, 0x4ab3fb0a, 0x0e738d38, 0x41ffa217,
- 0xe31079f8, 0x1c473638, 0x7bdee789, 0xa19bddfd, 0x5b9832f9, 0xbf0578e3,
- 0x36b802c7, 0x6f45538e, 0xb2e049d4, 0x98ab4a15, 0xba7ee31d, 0xce519746,
- 0xf6094847, 0x8d3a27a3, 0xabd23038, 0xefdae7f9, 0x4c7e50c0, 0xddf5a24f,
- 0xff63e6aa, 0xce61c6a2, 0xdfc69e97, 0x9c95fa9e, 0x1cdee3c0, 0x4e4e17ff,
- 0xdbd80b7b, 0xe519be93, 0xecd72c66, 0x90342147, 0xfc1fa983, 0xa9092191,
- 0x97850fa8, 0xe3a6e214, 0x3fa8190c, 0xaf8a4eff, 0xe3ddbc40, 0xc27acf64,
- 0x1325f55b, 0xe37724f1, 0x663e0e4e, 0x96eddc03, 0x1f106cea, 0xba5ecebd,
- 0xda6f5406, 0xf0b305a7, 0x1336879e, 0xf4d99081, 0x102d73e6, 0x251ef047,
- 0xa0a03e78, 0xc054ff79, 0x56a5efe9, 0x5e75479c, 0x08b1e424, 0xbcd8333f,
- 0x587e06c6, 0x6f9d8530, 0x7448983b, 0x27f790fb, 0x8f06bc30, 0x1dd9bf9f,
- 0x2f12fca3, 0x29dc499f, 0xc72e38d9, 0x70a3fc63, 0x3ffb09bd, 0x481d704d,
- 0x9e65bf01, 0xce85f380, 0xa40e13bd, 0xee3b7a50, 0x333b444c, 0xdde0f83d,
- 0xc6882a4e, 0xcf8b1eff, 0x780a16bb, 0xeaa140cf, 0x59617cc2, 0x98dfee26,
- 0x99e48ff0, 0x433e50c5, 0x74cdf9c6, 0x788252b1, 0x2134d9d4, 0x7b8be607,
- 0xf85ab684, 0x297f5c1d, 0xfd38876b, 0x7cff30c9, 0x0c7938a7, 0xaa9c76fe,
- 0xefe187e5, 0x3cc31203, 0x0bced56d, 0x7cb4cdfb, 0xf7016cd5, 0x66774eef,
- 0x7e047f10, 0x7953d70a, 0x6cb8a58e, 0xb8005fee, 0x3fa4599e, 0xc4bb3837,
- 0xeb910246, 0xef138216, 0xf7c83b21, 0xfc097769, 0xe7ae7c5e, 0xcfbc7037,
- 0xfbac9b99, 0x3f3094ae, 0x6453bbd3, 0xb3e471f7, 0xf4d6a1df, 0x87ae46eb,
- 0xf1f9f037, 0x8e864f3c, 0xd288628e, 0x5b3f4088, 0x62e5be47, 0xa5cf0e1b,
- 0xe78707e2, 0x1c6ef6d3, 0x8ad79861, 0x17116b95, 0x6f1d6c69, 0x1382ec36,
- 0xdfea6ec1, 0x9f4f25bb, 0x97c7a18f, 0x3d9a13b5, 0xc457bd98, 0xf9d9c375,
- 0x8902cf94, 0xaebfd3f2, 0x726098bd, 0xd078801d, 0x78dc97ad, 0xbd944e8f,
- 0x1be8a0f8, 0x50df8bd9, 0x7aa3cc1d, 0x1f0264fd, 0x41910737, 0x8ba63760,
- 0x380a7edb, 0xa6e3a4ea, 0xb48e0639, 0xef9b4771, 0x063d5217, 0x6c3390dc,
- 0xa5fa659d, 0xa4efdc34, 0x76c3f7cd, 0xae25fa84, 0x6fd2fe18, 0xf774b212,
- 0x4aed847a, 0xe7225f84, 0x64bf7b7e, 0x9547f53a, 0x206fa01c, 0x7b458ff1,
- 0x42c97186, 0xf10518d8, 0x1873b4c1, 0x744af1e7, 0xf3e38afe, 0xb02f88d3,
- 0xb752427f, 0x15fd187e, 0xd63cce2d, 0x7a53f9a9, 0x8de3849c, 0xa57dd8b3,
- 0x810a4e1a, 0xb3ffa09f, 0xf4eb8c44, 0xfdad1b86, 0xa212f0de, 0x564c08f6,
- 0xfae1788f, 0xf2f175f7, 0x197c6d17, 0x05f6864a, 0x343e1a27, 0x9bc718bc,
- 0x83c434ff, 0xba6f1a7a, 0x0e6f197a, 0xaed1908c, 0x7cd7e6f7, 0xeaf3e4ea,
- 0x37a62704, 0x7f1b355c, 0xd82c6897, 0xf937f011, 0x6b8e15b8, 0x1c9c33d5,
- 0xc1245b68, 0xec1791fa, 0x1cb76647, 0xfff078b4, 0x81c4c600, 0x008000d5,
- 0x00000000, 0x00088b1f, 0x00000000, 0x7cbdff00, 0xd5547c0b, 0x67b7efb9,
- 0x332479ef, 0x49926649, 0x1d843c32, 0x09212108, 0x11bc210e, 0x11084937,
- 0x88a80ca2, 0x1f01d68f, 0x4d092060, 0x6f53d5ad, 0x52812133, 0xbd583d6c,
- 0xf4f47bd6, 0x41ed5837, 0x0108750d, 0x26702783, 0xd0f098a0, 0x7ac0f820,
- 0x452968da, 0x5a18921b, 0xf5cf6a0f, 0xf6b7df7c, 0x8326664e, 0x73def7a5,
- 0xd62e9f87, 0xf5af6b5e, 0x5ff9efad, 0x4a9b5adf, 0x500a9fc0, 0x982015b3,
- 0xe1f95006, 0x06484a86, 0x01203be8, 0x96d40314, 0xfe1b41c9, 0xb1fdb4b5,
- 0x0cdd45c7, 0x51df8956, 0xf5c02661, 0x950b7e20, 0x06e6c50e, 0xbc95e658,
- 0xd6801672, 0xe1bfde2e, 0x62a82592, 0xf9af7afd, 0xe89b1ee3, 0x5fff35fb,
- 0xb800c803, 0x197f7f51, 0x2ffb0ffd, 0x1860a4d3, 0x3b365d5f, 0x978dffba,
- 0xa6913fca, 0x62d72c02, 0x3e4fc39e, 0x22f2a793, 0xac24becc, 0x8fb74457,
- 0xcfb92673, 0xe32ff1d9, 0x32d7fc61, 0x65f3c5c0, 0xaff7516f, 0xc8ed77e9,
- 0x523d48f2, 0xace80166, 0xdb1971b7, 0x7f016e5e, 0x4d2581c8, 0x0065c450,
- 0x9d0a0152, 0x581998b8, 0x0d0164bf, 0x136308f9, 0x3ab9f7e0, 0xdf86131d,
- 0x07e3883f, 0x8e30dc70, 0x3801c81f, 0xfae4ef54, 0xae1ef56b, 0x2f82935f,
- 0x877fe3a4, 0xb8a8b0bf, 0xdfedc59e, 0xdf38fc51, 0x8f0a4be2, 0x93d69b3b,
- 0x71830b4f, 0xf73f9eb4, 0x0de3fd16, 0xb6bfdc30, 0xbf8b33fd, 0xf9ebf2f0,
- 0xa7e7f35b, 0xcd3f3ca8, 0xcf0c15ab, 0x180144bb, 0x9a5ceb83, 0x635fcd1b,
- 0xc6f9589e, 0xfeb96fca, 0x56fcac7e, 0x90c7acc4, 0x32a2f40f, 0xffc38a8d,
- 0xa6d0264b, 0x437e5e5f, 0xb3f8b1f2, 0xdb2305bd, 0x72c97e01, 0x974f1e1a,
- 0xbe2b7417, 0x19974142, 0xb752baf5, 0x40efd40b, 0xb2b9ca0a, 0x4889c213,
- 0x2be7f5d8, 0xf4a8513e, 0x9471f04a, 0x6c7c033e, 0x1e1e5bc8, 0xe425d17f,
- 0xbcf0da6b, 0x7764148b, 0x0b1f3d11, 0xa8eb3881, 0xea1471a1, 0x6c39601f,
- 0x155a61d9, 0x635c75c2, 0x547d3b81, 0xe0328a26, 0x937db894, 0xf6e3c4d3,
- 0x8266c5ff, 0x3e5e01ab, 0x48025998, 0x3cead79f, 0x42011306, 0xbff7e066,
- 0xdfb9524e, 0x240824e6, 0x74a0fce0, 0x945ec8db, 0xb45c8012, 0x25b4653b,
- 0x364388d8, 0xd91f612b, 0x8157bf61, 0x2fdbb406, 0x050ef78d, 0xc914076e,
- 0x4c738fe6, 0x7ef4598d, 0xf61e7bb8, 0xa8a4559b, 0xcb8bb0db, 0xda877eaa,
- 0x9d580efb, 0xfeff5ef4, 0x699877ef, 0x1780bf9c, 0x0ed78429, 0xe7da8158,
- 0xf241cc3b, 0xe3e48b1f, 0xfdeb09b2, 0xec560003, 0xb8557f3f, 0xd76e5014,
- 0x13a37740, 0xc724b9cb, 0x8d7bf238, 0xfece9bd6, 0xe50a31c3, 0xd39740b4,
- 0x956fdd02, 0x8fd9901e, 0x41c92694, 0x53f61ac8, 0x5a32ead7, 0x3a256c80,
- 0x7ae1b416, 0x4bdafdb1, 0xb4bf5c4a, 0xe1771f48, 0x9321419f, 0x7ad1085c,
- 0xf84da8bb, 0x14d012a3, 0x6d4b29c0, 0x97e4ed31, 0xce459e90, 0xc973e7e8,
- 0xef5ea277, 0xf84bf18e, 0xf7bcd133, 0x8bbcc53b, 0xf726bfe4, 0xb65ffae0,
- 0x43cdef68, 0x9a4e077a, 0x0e7c59e1, 0x6732b1e7, 0xd0da5f24, 0x973983ae,
- 0x07fd8bb7, 0xe9153513, 0xc7f49979, 0x9ad1f541, 0xfdf2f53a, 0x940cf6a7,
- 0xb9787760, 0x13028579, 0x7b4f1d58, 0x3df98632, 0xff3aaf82, 0x22d9f963,
- 0xf91d9341, 0x5bddb0bc, 0x0465ae46, 0x8f913b1f, 0x80c95ef8, 0x295cf3c6,
- 0x78fb0d1f, 0x46a25cf9, 0xb9f2fefa, 0xffcd1ad1, 0xfa6be92a, 0x3feffeb0,
- 0xfe48983b, 0x2aa8f913, 0x2e0317a8, 0xd659f79b, 0xa1f7a15f, 0x6dc13951,
- 0xf5d16f58, 0x81c4e5fc, 0xefc4f9a3, 0x67de4deb, 0xe3651a69, 0xe48515c4,
- 0x9c96b737, 0x0d2477c5, 0x7ed107a4, 0x7709d524, 0xfb401960, 0xa40b7d21,
- 0x1993eb02, 0x36f34042, 0x9534f06a, 0x29abe60b, 0x1c41efc4, 0xe341dbb3,
- 0xe7a429a9, 0x338bd7f0, 0xf923857d, 0x0a8f52de, 0xd6b4f385, 0x1b2534db,
- 0x93bd5f60, 0x1ef56deb, 0x57ad5f2e, 0x2c74dcb9, 0x8e20c1f9, 0x3459ab53,
- 0x7df86d25, 0x8fb0aa57, 0x8867e805, 0x052005ae, 0x0b73a803, 0x5ef5d61e,
- 0x249b8291, 0x27ae1392, 0x97289f82, 0x08dc9ec1, 0x4d2936fe, 0x35b26693,
- 0xf28bbcb0, 0x063efc4d, 0x59f3e0ff, 0xdca3fb23, 0x4baaeaa3, 0xbae67e62,
- 0x961724b4, 0x52f8743f, 0x6e916ca8, 0xb8017c39, 0x5bf512ee, 0xfe380be5,
- 0x7842f0f4, 0x74c3e310, 0x15f10c14, 0xfd13b77f, 0x402c3a33, 0xca80c1f2,
- 0xd3a45976, 0x492e7da3, 0x323e70e7, 0xe0c7af9d, 0x30cad67b, 0xe83ed1e9,
- 0x17be2349, 0xb4767cdb, 0xc843a428, 0xf66e9355, 0x9cde3848, 0x26578b74,
- 0xa6fa26d2, 0x75fe446f, 0xd884e3a4, 0x6323a3bf, 0xa6f68aac, 0x4fbc6f29,
- 0x1cd9ad76, 0xcc2b8161, 0x71113dbd, 0x719e133c, 0x9f22bc52, 0xbdf235f6,
- 0x01c977f3, 0x73886bf6, 0x9e758fc8, 0x7186f64a, 0xd92e6b9e, 0x7fd256bc,
- 0xf5ed117a, 0x54f26260, 0x5dd0cff2, 0xd6b8ebc6, 0x6f91d626, 0xd8bb17f6,
- 0x9f0f859f, 0x6dfef7c0, 0xe9fc8010, 0xca1fdd35, 0x9a94f480, 0x907b32f2,
- 0xe4d2c3ce, 0xfc9f2a14, 0x9701725d, 0x897b92a7, 0x764d073f, 0xa77de695,
- 0x46ce2d5e, 0x72ded17d, 0xd61d0098, 0x0a1cb782, 0xa1ea2795, 0xe5f51b38,
- 0x971b7aad, 0x5c9deb27, 0x70f7aa9e, 0x49db1879, 0x76c75e9f, 0xb037b7d2,
- 0xd85dea9d, 0x1c31e54e, 0xdba2ca97, 0x96bc7893, 0xb42c92db, 0xd0c9838e,
- 0xfa4fcc6c, 0xb70c4e14, 0x3fe01782, 0xab6afb1e, 0x978c2aed, 0x34a17f56,
- 0xb3f4f90d, 0xac142aaf, 0xee3c5b1f, 0xbb60bfa1, 0x1fa667f9, 0x9bde90db,
- 0x8f5a394e, 0xaa9edd63, 0xfa41d8fc, 0x9d112c79, 0xb9b59923, 0xa63a434b,
- 0xcd1c6f93, 0x3660d76c, 0x7af4d3d6, 0xd95d7cc0, 0xa595807c, 0x42e0f93d,
- 0xaf597125, 0x577f21b3, 0xa3dffdda, 0xabb025ba, 0xaa2aeca2, 0x7b248863,
- 0xb641cc97, 0x7b92b1f7, 0x95bbc605, 0x127fff0e, 0xd17b0dbf, 0x91a43fa4,
- 0x49a9987f, 0xbcb372e0, 0xe1a49383, 0x95bf46e7, 0x49ff458e, 0x25debafa,
- 0x98cd7db3, 0xc741692f, 0xfa35fb48, 0x96ab38cd, 0x9e66fc91, 0x72a26f2f,
- 0xeb8b8559, 0x9ab355be, 0x1ccbfec8, 0x94bf7b97, 0x65d07fdf, 0x512dbd66,
- 0x389c5fb0, 0x8e9bf468, 0x7bb8464a, 0xf8312ba0, 0x69f5e92c, 0xd612637f,
- 0x8ab27917, 0x0337dd64, 0xb63b5dd7, 0xebe57b51, 0xde576cad, 0xf2e12f24,
- 0x6990a899, 0x21d0bed8, 0x2a64c379, 0x4a6a3ff3, 0xe4a776a3, 0xd42db625,
- 0xa6289da6, 0xbbd96cf6, 0xd5a7ea90, 0xa7510a32, 0x2ef38594, 0xb9c5bf60,
- 0xbe1b5e29, 0xd0fc2a77, 0x85dfd245, 0x04de49b9, 0xf04af3f2, 0x7baa1ae9,
- 0x9506dead, 0x6958f1d6, 0x4aa38d32, 0x5bd6135e, 0x1ffd286e, 0x2f894744,
- 0xda892405, 0xd7e10a5d, 0xc3f77f27, 0x6bf62732, 0xd9012719, 0xde70a9cf,
- 0x85fe889f, 0x026a899d, 0xb38b69f9, 0xb16bde8c, 0x5c4dce48, 0xff5295f7,
- 0x7d598e40, 0x7e3dc71e, 0x41e39d9b, 0x8c055be5, 0x36df8e83, 0xe542e386,
- 0xa84bf35b, 0x78126e3c, 0xcaadf2bd, 0x41376e0a, 0xe54a9c98, 0xf7e2dfed,
- 0xb0fe97b6, 0x1fe38dcc, 0xdf62ef1b, 0x562a7282, 0xf624fc22, 0xbfde8907,
- 0x77fb9abd, 0x9d0f9948, 0x0b17fec5, 0x38ac8a52, 0x213bb97f, 0x58c57faa,
- 0x497d5457, 0x2562a8f6, 0x16564fc2, 0x6fd54564, 0xb38a9628, 0xe6fbfa23,
- 0x57d54427, 0xb38ab994, 0x54dffa23, 0xbeaa2a39, 0xa8aca6f2, 0x1cd342fa,
- 0x61ea3fe1, 0xf3b0997e, 0x20d965f9, 0xa9fc898c, 0x037df453, 0x3b26efdb,
- 0xa9f812ef, 0x09f885c8, 0x55d652e5, 0xd8b971cc, 0x00affbae, 0x92667b74,
- 0x2ebf17ff, 0x83de8f1c, 0x4999fe20, 0x16fc4878, 0x201e2376, 0xdc60a47c,
- 0xcca7a08e, 0x2bc71d11, 0xff27cd40, 0x84b9d15b, 0x67b954f1, 0x319a1979,
- 0xbdfa31f2, 0x8161f90a, 0x2ee86243, 0xa5c732ea, 0xf46c62b7, 0xabae06fb,
- 0x316be9d0, 0x09529bf9, 0x6eb4058b, 0x7ac635c2, 0xb72e3a0c, 0x8ef90a9e,
- 0xdfff1432, 0xfd2c575c, 0x7f791b00, 0xa0d74b11, 0x8881c74b, 0x760718a7,
- 0xc43e32a6, 0x3e1e3b9f, 0x254f7030, 0xa45737fa, 0xee48737f, 0xf79785e5,
- 0x97b8c66f, 0xb8c67bc3, 0x2cd0fbc6, 0xfbc6fcf3, 0x2955cf43, 0xd89df3fe,
- 0x73ce293f, 0xf9ff14b7, 0x17fdd173, 0x03a36a28, 0x4828f8ed, 0xfbf100de,
- 0x2410aab8, 0x35ad3d2b, 0x43e8b951, 0x747842bf, 0x1340d9f1, 0x837af395,
- 0xfeb8adc7, 0x956572eb, 0x1e060df2, 0x8cd75d8a, 0x3a4fb154, 0xabb5497a,
- 0x5012ded8, 0x68bfb4ed, 0xd3b55879, 0x8345aa3e, 0x6a2fda0a, 0x691b4d13,
- 0x63e5a1bf, 0x549cf589, 0x52f3e7e1, 0xca318e05, 0x5e7f6567, 0xb6d5962a,
- 0x8b09479e, 0x60317cd4, 0x94703021, 0x48c15e70, 0x0954779c, 0xa3be683a,
- 0xbe1d070f, 0xa57e3f08, 0x29146f38, 0xa7e93a5b, 0x91fa45a4, 0x16825b52,
- 0x391637e9, 0xaff5515d, 0xc7d8aa9c, 0xbd45467b, 0x159a9d77, 0x6bf10fd5,
- 0x46a0e12e, 0xe42ae40b, 0x5e894d47, 0x7cb177c2, 0xfd7d17fc, 0xe093875e,
- 0xaadd9813, 0x97138fec, 0x7f82a5bc, 0xa457cfb1, 0x6fea7d8a, 0x6e583d68,
- 0x35f4154f, 0xe2013ec9, 0x3e933710, 0x4f71d6c4, 0xc3c68aba, 0x77a43d91,
- 0x22e9bb5e, 0x4ef86f42, 0x29d7d5ea, 0xe9decfa8, 0xc44eefa6, 0x8ba923fa,
- 0x699e7d44, 0xffac04cf, 0xd45cb534, 0x374d36af, 0x057e017b, 0xc32baf8b,
- 0xe7dbba7a, 0xfb79c54f, 0x12ad8ecd, 0x24c519e2, 0x787b9141, 0x0588fbff,
- 0x160a29e3, 0x21734c95, 0xd8ab76ad, 0xa024d72f, 0x25fea3ff, 0xaafc4a9a,
- 0xdce43049, 0x1d714193, 0x9134ceee, 0x6ff630bf, 0x87be0b76, 0xfcd8e7ef,
- 0xc25f42b5, 0xa5fa2ac9, 0xca2ff7fb, 0x9ed8bd24, 0xe7f5e4ea, 0x21e799ef,
- 0x7d74857f, 0x7ffdfa97, 0x3c536ba4, 0x62cc9aba, 0xfc96de9e, 0xf9bb8a52,
- 0xd21c51e3, 0xbb70bcb0, 0x4213cfcf, 0xcb8c2ba8, 0xf5848f35, 0x4bc59746,
- 0x90fb7d38, 0x6cacaf7c, 0xb213f3d4, 0x9c8de85d, 0x1bb8da62, 0xfaeb9fcb,
- 0x3bcd14f2, 0x1819e683, 0x01f51cb7, 0x56e3039c, 0xe93a8a14, 0x0d172c83,
- 0xf81ede10, 0xf7979256, 0x7e0763c7, 0xbfac03fb, 0x97be4777, 0x8907f470,
- 0x82ab3f82, 0xb07b1a13, 0xbc1acd3e, 0x3e748c2a, 0x967fe694, 0x6b36e0f4,
- 0x9beb1270, 0x8d126363, 0xfbc0692f, 0x877f6310, 0x32d538fb, 0x1fee2471,
- 0x88d82f39, 0x11ccb7cf, 0x45e6367c, 0xee28da9e, 0x3c5b37bc, 0xf9c0e837,
- 0x06ff885b, 0xc074433d, 0x03c72758, 0x45a47910, 0x61e443b2, 0xbce260ff,
- 0x1f192d49, 0x359cf7d6, 0xcfaebef1, 0xe68057d8, 0x9b933d58, 0x27399e78,
- 0x6c4cc936, 0xd4ccff00, 0xb6af4859, 0xfa7de7ad, 0x7de8ee8c, 0x7f4eacfa,
- 0x9bdf03a9, 0x7cfc7ef5, 0xdc7d3cc8, 0x299410d9, 0x89e9cf5e, 0xdf4f37ee,
- 0x1f3bcfa7, 0x54cdfcfd, 0x868dbe3d, 0x8e7991d1, 0x33ff7d3a, 0x0a427c78,
- 0x3af929e9, 0x516ef919, 0x3a9d9865, 0xeb5a37ec, 0xf90e5fb1, 0x85971b47,
- 0x11779da7, 0xa8f56dfd, 0x93f216d0, 0x7b0d2e1e, 0x770d3c2a, 0x7988d4c2,
- 0xf837bd74, 0xe0bef838, 0xdc9eb4e3, 0xbac7cf9f, 0x410cd3b9, 0x739d7875,
- 0x820d3e75, 0xd3a0f3e0, 0xd99e7cc2, 0x61e9cbf5, 0x98f5647c, 0x5f588d40,
- 0x6a089a82, 0xe7b53f84, 0x65d546a6, 0xce3a3e43, 0x9f8fae98, 0x351d1de4,
- 0x0c37818e, 0x5a9abdf9, 0x643849de, 0xe31d63ba, 0x13d9948e, 0x3e2dc6a2,
- 0x64272b1e, 0x2476e11c, 0xd7089ff2, 0x70a2569f, 0x80772cc6, 0x3fb30038,
- 0xc9706254, 0x68ec9976, 0xe7e8d9ee, 0xc8cbb4e6, 0x84fc72ed, 0xef9f3fa9,
- 0xe9f9fbfe, 0x99f9a2d2, 0xcfcd1156, 0x3f345f74, 0xf3455733, 0x9a3f946d,
- 0x4dd6632f, 0x6abf6a89, 0x7d545163, 0xa37383fc, 0x006167fa, 0xdc4fac8c,
- 0xffaa24ba, 0xa22beda4, 0xba9f93ea, 0x5e7faa2d, 0x7b544d70, 0x2baacefe,
- 0xa8617f92, 0xb11faa2e, 0xf20df4d7, 0x1fedbabf, 0xeff9e6a2, 0x34a2ff96,
- 0xcbaf2f3d, 0x438e997f, 0xc7fa1a5c, 0x4538e1a2, 0x93f215e9, 0xbe37f6ae,
- 0xa04bfca0, 0x53bce544, 0x1b780960, 0xd909edb1, 0x1b5f9127, 0xa136ac83,
- 0xc13268df, 0x8ff7f23a, 0x879c4c9a, 0x2abcec34, 0xaa8be04d, 0x9ff7e134,
- 0xf8a69b46, 0xeccff066, 0x78449ede, 0xa0993643, 0xe29ae29b, 0xc671bf65,
- 0x716be101, 0x7034793e, 0x7934ab5e, 0xa899b2f6, 0x329bf287, 0xd1e51fef,
- 0x7d71507e, 0x3f1fc78d, 0x8b9ff941, 0xfa4a9b0e, 0x03faa72a, 0x7d70b714,
- 0x2461e7a1, 0x3eaf795e, 0x49f6893c, 0x67957d46, 0xbfea66e3, 0x93858eea,
- 0xf43aff68, 0x498e8efc, 0x88721165, 0x388adf5c, 0x697be8f8, 0xc4673f22,
- 0x6aacdb87, 0x6bca0f63, 0x3ffc2c9a, 0xa5ef85c6, 0x903ffae1, 0x9c0b361e,
- 0xbad33015, 0xde724e31, 0xba8085df, 0xe194cb0e, 0x8d7ea478, 0x84c1f54a,
- 0x26f9dc68, 0x08fb4411, 0xffc72a5b, 0xbb7f0d5b, 0x36f98f2e, 0x3fee88e8,
- 0xc144f778, 0xd7236fcf, 0x2c67df90, 0xdd061d62, 0xfc3f75e7, 0x7b87eea9,
- 0xe446ffc9, 0x78edd79b, 0xf5f0893c, 0xa7815c99, 0xe8cfe78d, 0x4d267d72,
- 0x3bf5e9e0, 0x79919c13, 0x2b90eac7, 0x36db5eaa, 0x423679ca, 0xeb1bd70f,
- 0xad0a4bf0, 0x3f6e8363, 0xc93d9dd5, 0xf1e301b7, 0xdc70d3a7, 0xbf171d9a,
- 0x37de8fbd, 0x3888640d, 0x6ef9e01a, 0xd7180f79, 0x4415f2df, 0xd297d2e1,
- 0x25e57e44, 0x95cb0ba2, 0xdf513858, 0x776c6256, 0xfcc6f951, 0x7c3bb272,
- 0xbeb0961e, 0x84cc13ac, 0xb3fb96d3, 0x53f4c4cc, 0x2f677de0, 0x9a5f6d2e,
- 0x04dcf3ca, 0xc5c5333e, 0x9d5dbf77, 0xc686fd44, 0x4319c633, 0x2bd459b9,
- 0x419cc057, 0x246b9af9, 0x9f380dc6, 0xeefb9e8d, 0xe299b318, 0xbbdf31af,
- 0x0ef0bfe0, 0xf00ac5ea, 0xf8c6b8f2, 0x7e51a900, 0x90cb03f8, 0xbf24ed1c,
- 0x98532eba, 0x677539f2, 0xd1fe7cac, 0xebf030df, 0xdfce9007, 0x57b17d55,
- 0xbb7fba42, 0xfb57e07a, 0x4fadf9f0, 0xb5c5dfa1, 0x87fddb66, 0xc3ce22d3,
- 0x917ddcce, 0xc8f10ced, 0x33924ff3, 0x25eac97a, 0xeaa0f8fb, 0xbc489ca5,
- 0x616d227f, 0xb307bd27, 0x479ee2d3, 0xab2beec4, 0x6ed93f48, 0x8699c655,
- 0xeba7de5e, 0x930bdd65, 0xd25d79f9, 0xfd447ad0, 0x57f39979, 0xbcac0775,
- 0xd7477fbf, 0xbf17aa87, 0x9f991998, 0x54bd416b, 0x7274a873, 0x2a9ce749,
- 0xf1cf66f2, 0x6fd4a9c1, 0x21efeca3, 0xe978393d, 0xefaa64e3, 0x5e4bf379,
- 0x6574dc0f, 0xf323f7f4, 0x9b5cf922, 0xf92ef034, 0x567dea93, 0xa550f295,
- 0xdd8ef2fb, 0x4e9af58e, 0x9eb83bf4, 0x239eae0b, 0x6a7ed34f, 0x979404bf,
- 0xb02709aa, 0x9569af73, 0xaac79482, 0x65bddb6a, 0x9aabd60c, 0xba931797,
- 0x3f0b26d6, 0x0522d356, 0xa7f03c69, 0x748a7f31, 0x357d28db, 0xb00b1fef,
- 0x18a8efbd, 0x787d5cff, 0x4ff459ea, 0x9d9f2d7d, 0xb4363a23, 0x763f3959,
- 0x196c292e, 0xd85ef383, 0xea02852d, 0xb9f6ddb0, 0x5d6a3ec4, 0xcd0b31e8,
- 0xe5b9eebb, 0xfb0f04d9, 0x90b49df6, 0xfad75c7f, 0xbcfeb958, 0x20fb8458,
- 0x9dfac5db, 0xf322931d, 0xfc21f749, 0x81f8c883, 0xf70805f4, 0x09e39082,
- 0xdaab3e5d, 0xbb123627, 0x7dedafd0, 0xe6bf625a, 0x3bdf9374, 0xffdfebb8,
- 0xffdde695, 0xff98932f, 0x7fc657c5, 0x4f1805f0, 0xc0f3e8d4, 0xda1653f9,
- 0x9ab4d61f, 0x173bc5cf, 0x77dbbefa, 0xf0c67b95, 0x571636fe, 0x3880b16f,
- 0xc10099b7, 0x381e29e7, 0x91ab2c06, 0x07511f9e, 0x0e7147a4, 0xdd60d658,
- 0x71467646, 0xc608e3c2, 0xb9d717db, 0xf70f9e15, 0x9de31b08, 0xedead657,
- 0x858f6aa5, 0x9e3570f2, 0x75e90b5e, 0x7113f84d, 0x51f6df5e, 0xbf6716b9,
- 0x7e16ed5c, 0xc303d0d3, 0xa7d2ebde, 0x87985db0, 0xc6c860e2, 0x66b85f76,
- 0xdd53e280, 0xda0ed47e, 0x03fcb817, 0x6f607744, 0x2beb4a82, 0xccc9f7dd,
- 0xfe79889e, 0x5187dba4, 0xa3f979af, 0xe7e266a9, 0x2aa68f9e, 0xfbcfc349,
- 0xe2eb1c32, 0xddaa55e5, 0x4e6f4e22, 0xb68f9df6, 0x186f0483, 0xb769ade7,
- 0xda07f9f3, 0xe28e96c1, 0x75b83b48, 0xf3d20edd, 0x168bd976, 0xcb6d3501,
- 0x3fdc0dfd, 0x91e24bc9, 0x480616db, 0x8fa7650f, 0x8afe13f5, 0xcfd4cdf3,
- 0xae52267d, 0xe91b7fdb, 0x4f08e291, 0xd46bcc8a, 0xd17e7a98, 0xb75c9121,
- 0xaf9a266b, 0xc96fd808, 0xef0f5f0e, 0x54338a9f, 0x9e1ec7da, 0xa7c40e51,
- 0x38901e9f, 0xf54e6b5f, 0xf922cd6f, 0xbfb9951e, 0x010bf0e5, 0x9bee973a,
- 0x9f44c506, 0x4e9fdeb1, 0xe38c830b, 0x2f042e6c, 0xff79bb4d, 0xdfd21e2d,
- 0x611fa69f, 0x86f7617c, 0x234afc80, 0xe7ca06e2, 0x61420bd8, 0xd721271a,
- 0x3ce32c57, 0xf3276e79, 0x7bf562cb, 0x4d941f29, 0x4d875c75, 0xfa23adf1,
- 0xb144ee6c, 0x657b1e9f, 0xb23eba79, 0x1bce857f, 0xe92f9cfd, 0xed3d0b33,
- 0x5f180abb, 0x399d1df3, 0xbe09a4d4, 0x6b2e76c1, 0x46a63adb, 0xf044dbc6,
- 0xdf79e8db, 0x44bc5bfe, 0xd75139bf, 0xb6448cf7, 0xfff9d88b, 0xe499f499,
- 0x35b35a6e, 0x7c4cf88b, 0x7bf64753, 0xf067ef5a, 0x2e7f1403, 0xaa922bd9,
- 0x8d0fcbc5, 0x4e3c9777, 0xea9cdd72, 0xf01575cb, 0xc300acf1, 0x76b8c49e,
- 0x57fffd87, 0xe91fff64, 0xf8a2dcfc, 0x4ddfc46d, 0xf16cdd7a, 0x7fb64ea9,
- 0x0ff34a9f, 0xfc746fad, 0xf6e9b5f5, 0xff8265ba, 0x4fb7d71b, 0x15399f5f,
- 0x4bc68df5, 0x4e67ee06, 0xff48060e, 0x78a0929a, 0xec3e3e13, 0xdd90f72a,
- 0xc5f4396d, 0xa6f7b238, 0x2807af24, 0xd66075af, 0x2dfbb22a, 0xfd636fa3,
- 0xbc85f4ff, 0x9e623922, 0xad256913, 0x697ebfe4, 0xcfe2cbac, 0x42fc75a5,
- 0x5d6323d7, 0xabdf6ee9, 0x11bc88ee, 0x915f758c, 0x9fbe80fe, 0x17f1eaf3,
- 0xff9c73f7, 0x2f4487eb, 0xd6ee279d, 0x3e02b771, 0x783b1bd6, 0x1a55c655,
- 0x1f7ba31c, 0xd8261d8d, 0xe4a6cb46, 0x5d39c454, 0x36326cb2, 0xb70d9a7d,
- 0x4c6c74e6, 0xebba6fed, 0xbd213496, 0x0b2021fb, 0xaf9d167c, 0xa4d24d00,
- 0x6bc53cc8, 0x14f3f155, 0xc91bf8cf, 0x9e56ff2e, 0xb4d84e62, 0xf7f292da,
- 0xbace2be7, 0x9f3df7a3, 0x2a2655ba, 0x31f42b94, 0x8a0c4e14, 0xa74c17bc,
- 0xf133537d, 0x067bff12, 0x2df6cad7, 0x5cdae5f5, 0xfbee4f68, 0x8b1d6db7,
- 0xd62d9776, 0xfa46f54f, 0x3dc0a77b, 0xd78ff943, 0x46ee30a6, 0xfef3273f,
- 0x12d3a9df, 0xc462b723, 0x88f7c06b, 0x27f2a352, 0x265f23e1, 0x4aed7e93,
- 0xb922df55, 0x7cc9740c, 0xe941244f, 0xd8e2b8b1, 0x03c23ed9, 0xd38bf7e8,
- 0xd6c43ec5, 0x6d17ce26, 0x317ec6aa, 0x269ce9c1, 0x79c5d847, 0x579fc8b7,
- 0x9c60f91f, 0x05dc3105, 0x02e4f1d3, 0xdec37f1c, 0xc34a6496, 0xf6f33fad,
- 0x5392ba4c, 0xe91df8a2, 0xa54ffeb8, 0xc236391d, 0x53835ba9, 0xf0a13f89,
- 0x93f21484, 0x94040a85, 0xf1f138a2, 0x14de22a9, 0x87c53cd7, 0x3ed850ff,
- 0xe5e12d7d, 0x2f58b0da, 0xa6c661cd, 0x7ae036bc, 0x2a635b5f, 0x6ffb578d,
- 0xbf934607, 0xe05d297a, 0x4d2f179a, 0xa02bef11, 0x74acff50, 0x41e7ae97,
- 0x5f0be513, 0x7d8cf3d2, 0xcfdc4c97, 0x6db0bf98, 0x3d44eca1, 0x3f6f0828,
- 0x76cd79c4, 0x4df24aab, 0x3f040e78, 0x771813da, 0x0c5c1ed6, 0x5dfae714,
- 0x7db095e0, 0x6fc0e257, 0x0e061f49, 0x773a5558, 0x876e704d, 0x977f1c54,
- 0x0f2b4f7e, 0x31c5b215, 0x2f98dcfc, 0x94e7fda1, 0xe0bd2413, 0x6504dff3,
- 0x88e35c3b, 0xd31277e4, 0xd5eba25d, 0x89b0c4ae, 0x260645ce, 0xe9875ee1,
- 0x7813a61a, 0x3cce835e, 0x2cbbfbf6, 0xe07ee703, 0xa49cba66, 0xe8207907,
- 0x2ac9f684, 0xa704d1f9, 0x7048ebc6, 0x3480deaa, 0xa9daae92, 0x6ed0fc08,
- 0x35e7251e, 0x6baed877, 0x36eb8713, 0x135d85b4, 0xff8f3f40, 0x8f3a36d5,
- 0x8393aa1f, 0xfefc3d99, 0x6c2fe92d, 0xf9cb1a6b, 0xa28c80bd, 0x949963b6,
- 0x7954eb4a, 0xb545e87d, 0x07c122f4, 0xb767afba, 0xfea1f689, 0xaa0ee7a8,
- 0xaf3f443b, 0x925f69d5, 0x8742f6c5, 0xf07843d7, 0xee7c297e, 0xded7b45a,
- 0x05297cc7, 0xd35eaeb8, 0xb19a07a1, 0x87569fdf, 0xe93ee872, 0x1aff5673,
- 0x3e57cfd2, 0x2148f35c, 0x665ddbf9, 0x9df9256f, 0x18cfc09e, 0x5668bf87,
- 0x1dd845b7, 0xe0c81d8c, 0xf33180fb, 0xf4d99ed4, 0xfdd7c233, 0xce9525fb,
- 0x03cdfbbd, 0x9aee88e3, 0xe85a3ff6, 0xfeed64be, 0x4b4f188f, 0x9a1afe19,
- 0x035b766f, 0x039b6bdf, 0x1b5ef9db, 0x9fbe43fa, 0x7f08f218, 0xe73a7832,
- 0x390886d9, 0xec2e913c, 0xe3fc060d, 0xebb55e29, 0xf6907af6, 0xedee58dd,
- 0x8d2275b8, 0x07cf57bf, 0xc035ef18, 0xf7c431a1, 0x971af04d, 0xa0fef3c6,
- 0x967a4152, 0x4eedaeff, 0xa3ffa22d, 0x3dbf02e9, 0x66702e9a, 0x89bf8676,
- 0xf1df5de8, 0xd69925b1, 0x8e343679, 0x4521b9f6, 0xf1c6714d, 0x1bf64323,
- 0xcab54f63, 0xd7fa8580, 0x2bf6079e, 0x14a6ef28, 0xef4bdf94, 0x8d594db6,
- 0x4ca2f7cf, 0xe2ae2852, 0xefe294fe, 0x0c6fb35e, 0xe7786ff5, 0xc7e4a9f3,
- 0xe74f481e, 0x607e7ff5, 0x1be278fd, 0x22497fea, 0x606ed9d9, 0x69d866bf,
- 0xbe29d901, 0x5ffa405f, 0xf63cf54c, 0xdd2cbbcb, 0xf72ed84b, 0x12ec809a,
- 0x01ed9ff5, 0xf849dff5, 0xf689c0ae, 0x664fefc0, 0x6dd5df3b, 0xa32718d2,
- 0xf5c49f5f, 0xbea91b92, 0xc9ccbbab, 0x05f74e76, 0xc35ec88a, 0x109c7887,
- 0x9d1224c0, 0xfca8be04, 0xe9993b88, 0xe7e5fc36, 0x86e3d06e, 0x75c5e29a,
- 0xca3965d8, 0xa4e2223e, 0xf4711ba8, 0x9edb33c9, 0xee817b40, 0x0fdc28d4,
- 0xffbf0bef, 0xd5563d5d, 0x59773ebd, 0xeeb3ae33, 0x07edcc84, 0x585e7df5,
- 0x7a4393d7, 0x86e2867e, 0xefdc5d3a, 0xb033e7a5, 0x675df74e, 0x094b1b6a,
- 0xd8aecd63, 0xb9ca987e, 0x412950be, 0xbaabf9c8, 0x99859b0f, 0xb5fe93e7,
- 0x9f2eba1e, 0x9ff5cdee, 0x920242b1, 0xc0e5fad8, 0xb5c45f6f, 0xf910703d,
- 0xe14e271f, 0x10ff5872, 0xcf018d6f, 0xc97ef6c8, 0x4bbd23f0, 0x5afb1f48,
- 0x123ae1e5, 0x4d8a8352, 0x3fd277f5, 0xbac016dd, 0x9f7b433f, 0x99c7e254,
- 0x3f49f7fe, 0x997e4ffb, 0xf7b96641, 0xb7c7d8b4, 0xd27cb45a, 0xb809d69f,
- 0xa7a38db5, 0x3c8ba5af, 0xe215b14f, 0xa57e4b9e, 0x009cc1c7, 0xfef1223c,
- 0x5106765c, 0x655a17ee, 0xe7f882cd, 0xce56043c, 0xe7a37f23, 0xfd01ef6f,
- 0x941fe1a7, 0xf57abdcf, 0x182bc21e, 0x627deeb7, 0x89bfb9c4, 0xbb6d69f4,
- 0x6b84ff04, 0xfc4cf75f, 0x5e46097b, 0x1db6beeb, 0x3ca0c647, 0xee8b9eab,
- 0x9ee861b7, 0xbdf7887b, 0xefa39a1b, 0xae957c1b, 0x308996e3, 0xea0b7091,
- 0xb307fb13, 0xd4569d02, 0xfd3257df, 0x7e5e109f, 0x84f824c9, 0xf2ed957e,
- 0x671eb713, 0x1a3f844a, 0x8f7c00b8, 0xe8676f28, 0x99d7dd30, 0xa5e59cdb,
- 0xa22ae639, 0x165b6e7d, 0x825019c7, 0x9837dd32, 0x19cbf9ad, 0xd3b4075f,
- 0x9d642f74, 0x89c127ee, 0xa3bf287f, 0x8e9d6baf, 0x460beee7, 0x82073dd3,
- 0xdacf348d, 0xd1fee29d, 0xbff19dfa, 0xc7d5a813, 0xc9d4f0d9, 0xac0e9423,
- 0xabf7450e, 0xdb53f9d5, 0x05bcfd16, 0x9f181278, 0xfccf7d11, 0xfc43ef4a,
- 0xc5f02cc9, 0x4638fadb, 0xc219b5fb, 0x7920d67f, 0x410ddf24, 0xb37a4839,
- 0x0b240a4e, 0xd58e0b7c, 0x865df748, 0x65f7e8be, 0x73f9d6ef, 0xbc2fae97,
- 0xfabf7c2e, 0xe7482919, 0x24ff7780, 0x427bfe9a, 0x1f49cbab, 0x5d6af562,
- 0x6df199b3, 0x10b46c15, 0xabd58dbe, 0xd97d21aa, 0x1638a16e, 0x7e354fab,
- 0x0b7432e9, 0x4b7ffe5c, 0x98737af7, 0xffeb4cf3, 0x3ca5e4a7, 0xdfadbdd4,
- 0x745e50b1, 0xf9087da4, 0xa27a1956, 0x5defebaf, 0x7c86edcf, 0x9614c0a7,
- 0x15da456f, 0xf1a283ee, 0x50cb6ef4, 0x7cf3929e, 0x38139d83, 0x51e86e3f,
- 0x3ae538ec, 0x14fc5f2e, 0xada17970, 0xa2f84ed4, 0x2bc9b8ff, 0x4c7f9ca9,
- 0x4c3e442e, 0xe103203f, 0x89f6fe8d, 0xfe90078f, 0x37c513a2, 0xfa7cbe52,
- 0xd83f8c09, 0xf8b3a7be, 0x115fe457, 0x7d91a4e1, 0x4ecaec2f, 0xc783bdfb,
- 0x7fddf8e1, 0x4af1e8bc, 0xcbc7c3f2, 0x095c698a, 0x787ee9db, 0x1a871e91,
- 0x7bd9178e, 0xfdd1e222, 0xbedf2219, 0x47fbf3c5, 0x78b05f69, 0xf94bd9b7,
- 0xff66c58e, 0xafa404a6, 0xdbc905e8, 0xe91db380, 0x8d24f43e, 0x52a4f68b,
- 0xeef166be, 0xf6a21def, 0xd3125dda, 0x28bedfdf, 0xc7c5177f, 0xb8a5eca0,
- 0x577edfd7, 0x7384bdc1, 0x7053dc0e, 0x477cc457, 0x595f8552, 0xe399957c,
- 0xfb68ef71, 0xcf292b2f, 0xff60eda9, 0x1eeafbd0, 0xb0577f0b, 0xae0f024b,
- 0xf0e788f3, 0xbd0f89af, 0x085a4efb, 0x9eb697e4, 0xf1c4f4b4, 0x017946cf,
- 0xce6171b7, 0xf0b76ebf, 0x7fbdca3d, 0x6b7ad0b0, 0xf388fb9e, 0x126d5569,
- 0x67aaa7fb, 0x794aa0e4, 0x58af039e, 0x9a6b3f48, 0x8accc825, 0x3b73376c,
- 0xffaa51f9, 0x65f859b1, 0xe8d7ef43, 0xbde86e7a, 0x746b0761, 0xd6d775ff,
- 0x17bf3d68, 0xf1a32db4, 0x579a7bfd, 0x7ba03df3, 0x5ff7c7b6, 0x4b5c1f86,
- 0x2b8c52fb, 0xee8a9f6b, 0x7e90df77, 0xc7bfd807, 0x3257c9fa, 0x3cd8f3f4,
- 0x1efd23c8, 0xaf19af0c, 0x7e7d3da0, 0xc43c6ab2, 0xd71e3bc9, 0x8f1180f1,
- 0x8e26c307, 0xfafdb167, 0x285a2eda, 0xfe76d68e, 0x796bf199, 0x872c67fb,
- 0xbe0ef6ca, 0xf83d7aaf, 0xaf1f1037, 0x093bb76f, 0x08f65747, 0x6ed25fbb,
- 0x6a25060d, 0x7c91350f, 0xef8a0ffb, 0x4aaf023b, 0xf740a38c, 0x7e756b7f,
- 0xb7f9d5ae, 0x6367f716, 0xbe8adee8, 0x772fbeff, 0xe2ba11c7, 0xdf3fa351,
- 0x993875d0, 0x8404b8f8, 0x12125a7f, 0x8790c9fe, 0xc6465f11, 0x936f81d1,
- 0x5bb7d73c, 0x52f8bef9, 0x6d2d3fdd, 0xc593df16, 0x51fe8bfa, 0xddff9176,
- 0x8d8de82b, 0xd1ad35a7, 0xd232bbfd, 0xea0fdfd9, 0xc313f878, 0xa8f2e8df,
- 0xe53b001c, 0xb2a897e7, 0x756fc837, 0xe77f342b, 0x63cf8954, 0x2989d53b,
- 0x194beef1, 0xce3a9be5, 0x28cbea37, 0x43fd864f, 0xc88eedce, 0x998dfc7d,
- 0xcd54af02, 0xcf240391, 0xb2cf7d88, 0xfbb8aca2, 0xba44c81e, 0xd77b18df,
- 0xee45a64f, 0x391db47b, 0xf23f67a4, 0xf7495e3c, 0x859b6a8c, 0x8d9be87f,
- 0x8e10a6e3, 0xb5c5c607, 0xed20d6cd, 0x4f516a4f, 0xd2307bf8, 0x76bfb20f,
- 0x07e91169, 0x991c1bee, 0x3a72cf48, 0x2ff5c4aa, 0x8e38c36f, 0xfb2f2fc3,
- 0x2baaf58c, 0xf91bac5b, 0x1f6f1996, 0x6a1fec61, 0x6a9c092e, 0x7a51af3c,
- 0xd3511f78, 0xb749ee2e, 0x5c62fa1e, 0x7fdbd216, 0xadc63fe0, 0xa64172c6,
- 0x25adbf88, 0xbee98fa1, 0x6cbbe7cf, 0x90e8f171, 0xd89a97bf, 0x3dcc6a0e,
- 0xf6578c19, 0x859c2e23, 0x4fedf37e, 0x7ad1df79, 0xca4ee128, 0xf1adf5c7,
- 0x837e778f, 0x13601a9c, 0xd04ddae3, 0x9ee125c4, 0xd6b81c48, 0xdd0fee29,
- 0xaa49c7ab, 0x7d7a8c3f, 0x505df62f, 0x03eecf14, 0x2349e65b, 0x1bf0dded,
- 0xafbebad5, 0x85b1d82f, 0xf163e08e, 0x476eb551, 0x2e39fc88, 0x1ba2e2c6,
- 0xb4f5a333, 0xc644ede1, 0xb25dfdb9, 0xc8c47293, 0x268c5fd7, 0x7ef887dc,
- 0xeb3c9c42, 0xf65ebaa7, 0x0dbee7ea, 0x9be665b3, 0x0d288e69, 0x63fc851c,
- 0xe93fe97d, 0xcb1c5208, 0x04caf83f, 0x9dfaff92, 0x2445e7d1, 0xdfdf3f3f,
- 0xaafcb20a, 0x433e7643, 0x3a5fda32, 0xd214caf8, 0xbfb786b3, 0xf97211cc,
- 0xbee2c722, 0x29467d3c, 0x6bff6249, 0x77fec492, 0x4c93d2af, 0xfddaaefb,
- 0xfef22fb2, 0xbbe721bc, 0x4501fd75, 0x65d7f3ec, 0x686f5caa, 0x3a617a17,
- 0x7f9c4a20, 0x98f3c8a5, 0xed11fe79, 0xdf2fa825, 0xe880b710, 0x9ad7d942,
- 0x6aef5807, 0x9e989a4f, 0x198393da, 0x05ef11d9, 0xf24cdc68, 0x801b0d7b,
- 0xc81d88fd, 0xefa52ebf, 0xf4beb10f, 0x59c604fd, 0x523c2647, 0x64adce29,
- 0xc0f5bf20, 0x239355db, 0x3d05fffd, 0xc1f103ee, 0x09e72843, 0x87cebf31,
- 0xcf42b04d, 0xae3d0813, 0xee2c71d2, 0x8ec89aaf, 0x5757f763, 0x0e1b938a,
- 0xc7f28158, 0xf9581fb5, 0x07e7d03e, 0x1dfef2d6, 0x9327f92e, 0xffbf019f,
- 0x381f2a6a, 0x3d3276b8, 0x7de0fcff, 0x53de7357, 0xaf9514da, 0x1e7d1008,
- 0x797f51c2, 0x97c276f7, 0x90e30a5d, 0xefd3aea2, 0x9eeaf9d2, 0x9b7f3356,
- 0xc677bd59, 0xc22481e3, 0xe94b454f, 0x9d3d9dbb, 0xe21feb0a, 0xd947032a,
- 0x289d4719, 0xe3851c66, 0x165c82f8, 0x71a4ab1f, 0x5314944f, 0xc9db0937,
- 0x1c274d9f, 0x55c618e5, 0x9cff3d06, 0xdfd9f829, 0x13f9c091, 0x3d082609,
- 0xba28ec83, 0xcebeb437, 0x9b436438, 0x86bdf51c, 0x4ceedef1, 0xd7b0ae71,
- 0xa490b3d0, 0x16ed1eb1, 0x3db686e5, 0xf58eb419, 0x49eb10e6, 0xb459b343,
- 0xd02512ef, 0xfe0ccdf9, 0xfc4038d8, 0x508f4639, 0xc12c4b2e, 0x77db84b1,
- 0xea079d0f, 0xe28239f7, 0xe7635d5e, 0x686efe44, 0x3b8f73b0, 0x4e39fc5e,
- 0xda4833e7, 0xcfb12cd1, 0xf3af6d89, 0xd1c67c88, 0x1e2fc233, 0x1c9fe85d,
- 0xa0063fcf, 0x25fbec44, 0xe6ad7e5d, 0x86e7788a, 0xdf223d1b, 0xe06c73b4,
- 0xef71e928, 0x373e04ee, 0xfc8975ec, 0x974b696c, 0xac9fdf42, 0x5066956f,
- 0xfb9f5a3c, 0x829f7f1e, 0x83f662f5, 0x6e7cfde1, 0xbbbcdd5a, 0xc7438b5c,
- 0x1f111eb5, 0x01dfe897, 0xbd57d08f, 0xd37814fd, 0x23da7df5, 0xaa735e74,
- 0xdf14ecd2, 0x4aef8999, 0xf9fdd06f, 0x199bd78d, 0xd5029d37, 0xc43fce2c,
- 0xdd32c539, 0xfba0df2f, 0x3bdf11f9, 0xe99b033f, 0x7bf6229c, 0xdfafc367,
- 0x02bf8fac, 0xf6371e34, 0x759bf5bb, 0x2fb3783c, 0x4ca5f9fa, 0x40e6071d,
- 0x10f3f90e, 0x1fbe17c6, 0x71c09791, 0xa4e1697a, 0xbe8338b8, 0xeff55703,
- 0xe434a9c0, 0x1ef790de, 0x1da3bfc7, 0xdfcd7e67, 0x80499c13, 0xc5ce7109,
- 0xe19fe386, 0xf2126e3f, 0xaa2dcfd6, 0x4346829d, 0x077017ee, 0x331f9916,
- 0xe7463ee4, 0x3df1ffff, 0x22505ca0, 0xcacf25f3, 0x3a1e31fe, 0x32f5b09f,
- 0x7015c6fe, 0x8d75c41c, 0xce35d7d3, 0x2edf111a, 0x571d5a8c, 0x97d7877f,
- 0xc471101a, 0x9e4765cd, 0x75627195, 0xfbefe248, 0x5f62c3aa, 0xf6265d5b,
- 0x02ad39b5, 0x49bcaea7, 0xbb126a0a, 0x9f44d3c3, 0x6ccb3fa1, 0x7a180f02,
- 0x5d2fc432, 0xf09da87f, 0x3e3a0dc1, 0xc9a3d588, 0xf94e5dd0, 0xc9345be6,
- 0x472af74b, 0x6abf3f7c, 0xeee4ebda, 0xa83fa72f, 0x22effc6f, 0xf7d1eac4,
- 0x0f12fe3d, 0x07bad3e5, 0xb8e21657, 0x38fef347, 0xe6a6f48e, 0x2df37632,
- 0x3b13888f, 0x7ca3811d, 0x3f45a4df, 0x6bc96fef, 0x747e21eb, 0x5ec7e302,
- 0x3a96f757, 0xbcf9ab81, 0xc09c3abf, 0xb75643df, 0xb0bbf9db, 0xc486d6ea,
- 0xdb7fe429, 0xeb1daf65, 0xcb27ad95, 0xc5959f88, 0xad4a3ee2, 0xb38bdc5d,
- 0x10b7fdb9, 0x3b7bd77d, 0x2df9cfa2, 0xfba8bf3d, 0xf58f3d06, 0xa3091b6b,
- 0xf9f7ffa5, 0x5f3a8d9b, 0x662ebaea, 0xfea9c14c, 0x26afe690, 0xfd7fec7d,
- 0xd71d0b45, 0xa5794ed5, 0x6d88ae9c, 0xefdca8f4, 0x268ee6fa, 0xf41af34a,
- 0xf93a6477, 0x707351f9, 0x82d2e32c, 0xd30fbb2b, 0xa98dffb0, 0x3afaa714,
- 0x225aa6ba, 0x0eb7bbf4, 0xf91c73fd, 0xb7498035, 0x494b855b, 0x25e3a15a,
- 0x07b5c761, 0x3e50670e, 0xb7ec97a2, 0x9277ca80, 0xdeacb1b3, 0x12792a7d,
- 0xa2bd96e1, 0xed19c21c, 0xa503f732, 0xa4e6e727, 0x3336fa48, 0x6242177d,
- 0x9c9e801c, 0xdb230b1b, 0xdb5fff1b, 0x27a4d3ff, 0x289eb6d5, 0x84f837fb,
- 0x3efe7cbb, 0xcad07037, 0xbce808f7, 0xc72115c6, 0x347f7457, 0x644b370b,
- 0x7ce873a7, 0x3b41227a, 0xbaa0ee05, 0x95256102, 0xb2c38bce, 0x96377fb8,
- 0x7d4cf7fd, 0xb84a59fe, 0xcee9ee83, 0xe737cfd1, 0x5bf73742, 0x6a5c0300,
- 0x8befe4e0, 0xe5cbc04b, 0x29785b6c, 0x5082f1c1, 0x099fbf88, 0x73ae2867,
- 0xe63bfd36, 0xe61ef238, 0x0ce7029b, 0x0e74c87e, 0xc51bee26, 0xd75ba7ae,
- 0xf09a59c7, 0xe81d043b, 0x086cee7e, 0x35fbb9f1, 0xbf9fa3d0, 0x3cc75fc7,
- 0xb9d1f7dc, 0x3b6835db, 0x208fcc89, 0xeb4f9ff7, 0xa7ade391, 0x198b2967,
- 0x9f449cca, 0x7d30ce14, 0x75f2bf6d, 0x4d6dd3f4, 0x35df57ca, 0xe283f7d0,
- 0x6f4b73e1, 0xd3ef1bfb, 0xd349627d, 0x97b1bef8, 0x7da6c7be, 0x1de9584e,
- 0x001363f2, 0xe6b3ddfe, 0xc66f6437, 0x07e01af7, 0xfb11e7be, 0xf72d06bd,
- 0x3df0c67c, 0xedfee335, 0x950ae0ce, 0x72ac6fee, 0xaddff8db, 0x9b8db229,
- 0x87ca794e, 0x21bffcd2, 0x6a40fabd, 0x2883c49e, 0x638c19c1, 0x83b2bd75,
- 0x2fd69b36, 0x22f7c669, 0xf432fac0, 0x006401ef, 0xb763b77f, 0x1e69ef8a,
- 0xa5b43d41, 0x74abf6b2, 0x2e1e1a0f, 0x6f2f0955, 0xf4bcd971, 0xe895ae5d,
- 0xdbd30fb5, 0x2ff71368, 0xb16bfb8c, 0x19b46c7c, 0x8daf4a79, 0x77cc7671,
- 0xfcda773e, 0xbfe89bff, 0x9324a93f, 0xcbfe6070, 0x3f7c3df3, 0x7758c129,
- 0xc3eb8d89, 0x37191af7, 0x6a7dd136, 0x1d31aba4, 0xe1e21ef8, 0xba149ca4,
- 0x25d8d51f, 0xa63753ee, 0x9b7fd807, 0xf3fb12fd, 0x4ed2cec6, 0x0e83078a,
- 0x6eabdf0b, 0xaa34f974, 0x4421d207, 0x3ef89ffe, 0x69bbe0df, 0xfd21ef98,
- 0xed91505e, 0xde5157d7, 0x4a1b9a7f, 0x6169bde9, 0xc0f1126d, 0xe5061ef8,
- 0x4e9519e0, 0x7befa3cf, 0xfbe4e281, 0x501c8617, 0x9d995831, 0xb90d7cba,
- 0xf8ef8d38, 0x3bea2535, 0x8f5e437e, 0x98b90a24, 0x44cc26e9, 0x71a5577e,
- 0xf061e563, 0x8f00bffd, 0x30b1ae40, 0x0030b1ae
-};
-
-static const u32 xsem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x243bff00, 0xa3f0c0c3, 0x4aef811e, 0xf1303031,
- 0x12d18aa2, 0x6064e3ef, 0x6062e010, 0xfbe20530, 0x330c0c3c, 0x204cf480,
- 0x6066e516, 0x1ae20310, 0xc40dde20, 0x19f8807b, 0x1039fc50, 0x1be200ef,
- 0xbefd103c, 0xfe0c0c4c, 0xc4081c40, 0x95fc40c1, 0x1be18181, 0x73f6f103,
- 0x4c30330a, 0x2ff04715, 0x249fd903, 0xc1ffe7e9, 0xe90c4386, 0xa071df6b,
- 0x10acf37d, 0x7b20467c, 0x9aaa15be, 0xcdf85605, 0xbf268858, 0x18bf8d08,
- 0x0372fe8f, 0x4d5afe54, 0x81b5b334, 0xcd4909e9, 0x6efc4d3a, 0x40aac741,
- 0x3101a9ff, 0x5ff1ad00, 0x000368ca, 0x00000000
-};
-
-static const u32 xsem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5947809, 0xe77df0d5, 0x9926665d,
- 0x6c81bc99, 0x44d84eac, 0x4242740b, 0x61db101a, 0x8311688b, 0x9817054b,
- 0x264f6408, 0xdac7f520, 0x0040cfef, 0x8b435151, 0x03b45a35, 0x341b0504,
- 0x024180d8, 0x2d82e00e, 0x5d6ad8d5, 0xc8a0d2da, 0x1b80931a, 0xcefc5dfe,
- 0xc9bef739, 0x82264efb, 0xf5ffffb5, 0xf8f8fefb, 0xf77bee5c, 0xce73ddb3,
- 0xe28ef73d, 0x8b94c718, 0xff12fb18, 0xdd98c7be, 0xd71b18c6, 0x2356329d,
- 0xcf2d4ad2, 0x03d058cd, 0xac62ccff, 0x9785addc, 0x653633a7, 0x5ef91a87,
- 0x4837e412, 0x6de43b61, 0xde549d7b, 0x23e79ebe, 0xa0cfcd6e, 0xc83aa3fc,
- 0xdeded04b, 0x5065c0f2, 0x6643b9de, 0x91dbb11b, 0xc2963671, 0xe30731d8,
- 0xcf90597f, 0xc9c0ac66, 0xf61be5b3, 0x45f6c5cd, 0x84e6764d, 0x1577cafe,
- 0xf20cbcce, 0x86550785, 0x2f37ca55, 0xbe43fad3, 0x60352c38, 0x9f3263be,
- 0x1ca7685f, 0x3bf50cde, 0x37292d3c, 0x553b18b8, 0x8d5e60e5, 0x4b776ab1,
- 0x18a3f5ca, 0xcf6f092b, 0xf52576c5, 0x3a970f92, 0x97e6c765, 0xb6bae1fb,
- 0x97bb3e4a, 0xf12dd2b1, 0xcf923bcc, 0xfff84be1, 0xf91ca358, 0x862f941e,
- 0xb7e83275, 0x32e4d590, 0xab5fc719, 0xf0dddd79, 0xd3a5553b, 0x7cbe4638,
- 0xed038c2b, 0x7c969e2a, 0x1b0ac4b8, 0xf8c0340b, 0xb39cbbed, 0x7d70b937,
- 0x6e11b4cb, 0x1addd75c, 0xe70c2bd6, 0x717a74ef, 0x5cb41b7e, 0xbf592f28,
- 0xd5182b41, 0x96e95fdd, 0xd579d6be, 0x980d4d0e, 0x53d3a3ca, 0x47798c55,
- 0x184be774, 0xbf4037f3, 0xb36b094c, 0xff7f7746, 0x96322580, 0xcccbfd8c,
- 0x1feee8eb, 0x43df4920, 0x013fc16f, 0x6e3da15e, 0xb781ab82, 0xdbfc3ac5,
- 0xb3b78ddb, 0xd2a3c0ba, 0xdfee6d99, 0x3c401f48, 0x106a7cc0, 0x11ae904e,
- 0x644cf3f3, 0xdfe81493, 0xc4ba67e3, 0x918f5f7a, 0x9f2ca8d6, 0x420b58c1,
- 0x78cafda3, 0x116c6bc8, 0x93f631f3, 0xa9fed915, 0x059fbf90, 0x57bce2e6,
- 0xc4228148, 0x690d6313, 0x24abbf48, 0xffd71b36, 0x94349c03, 0xf407eaaf,
- 0x99af7009, 0x9649bd96, 0x3093dcc4, 0xbdc4f05f, 0x214fd4e9, 0x3f42a3f5,
- 0x8fdfcf43, 0xe9639b9e, 0x322dcf47, 0x7ea4a9fa, 0x4fd6179c, 0xeb04ee4d,
- 0x8c4b727c, 0x7ea4ee7e, 0x2eb617dc, 0xd6898afd, 0x46515cf9, 0xf54e24fd,
- 0x97d400b1, 0x2d607a0d, 0x5dca197e, 0xef6389f5, 0x98ba6665, 0xdff912bc,
- 0xa6625c0d, 0x389c848b, 0xfa261d0b, 0xd0f258fb, 0x5bec7e93, 0x44830f22,
- 0x5f1a3512, 0x5c91afeb, 0x41dfd498, 0xbbfa3bf9, 0x31dc2e48, 0x0eb17021,
- 0x59b1c0f3, 0x816bc83f, 0xe831eb6f, 0xb129e61a, 0x36bd4c34, 0xefcba34c,
- 0x261c3956, 0x88dbf80f, 0x683ed023, 0x08911ceb, 0xa4d2f5f9, 0x365c205f,
- 0x27c11b33, 0x5895664e, 0x48cece2f, 0x9e9ddd3e, 0x826429bd, 0x8041ead3,
- 0xdfbba97f, 0x0d206ad5, 0xbb2b6be9, 0xb6f48421, 0xa7ac106a, 0x854f633f,
- 0x14848fae, 0x20a83f68, 0xd769e10d, 0xe3cdbf80, 0x28fe306b, 0x1c19ff1a,
- 0x3f8e0777, 0xf6f8e7ae, 0xf1963921, 0x2c8b831d, 0x18343be3, 0x177de81f,
- 0x0f8c55bb, 0xd8c09bf0, 0x685ba1f3, 0x22e0fb7c, 0x8d6eff1a, 0x8fc65915,
- 0x05ff1aeb, 0xdea5f71c, 0x82643fd6, 0x4b83fd75, 0xf8d7ebac, 0x0b655ffa,
- 0xb471f8c5, 0x16875ffe, 0x2e0ff5f0, 0xf3b7ebe1, 0xf7c6bb7e, 0x75ffc174,
- 0xdeadf71c, 0xa2743fd6, 0x9517fd75, 0xe76fd759, 0xcacbbfe3, 0x1a2ef8c5,
- 0x1950bdff, 0x6545ff5f, 0x0f66be34, 0xb48e90f8, 0x61957101, 0x040d9f18,
- 0x19254886, 0x6474a7e5, 0xfda0c61f, 0xe084363a, 0xa71c4770, 0x80e2cfbb,
- 0xf2dd5cde, 0xa381858e, 0x08559e40, 0x9fad2f9a, 0xa59ca1a4, 0x0b7b9072,
- 0x341754c5, 0xb0dfb4c9, 0x70f0f675, 0x937b6f98, 0x82fcc21c, 0x65879775,
- 0xbcd8efda, 0xb0a76c3c, 0xf0ff7e08, 0xcd1bd1a1, 0x174e8aeb, 0x5ac7a8d6,
- 0xe7c47c2d, 0x46cc9a13, 0xa6fcc256, 0xeb8c1121, 0x39031fce, 0xbe7e40ca,
- 0xd314720f, 0x078c2ae3, 0x9c828fdf, 0x6f999a65, 0x3c7df196, 0x991cdec4,
- 0xff827282, 0xbc38531d, 0xc2912d8f, 0xd6cfff08, 0x3e50d22e, 0x0789ac2d,
- 0x23cf77a0, 0xb9d4f028, 0x28de1ecb, 0x08bd3c11, 0x15891b9f, 0xa033fb19,
- 0xb6801fb5, 0xa5afb6b0, 0xbc2c2ddd, 0xcfea0d32, 0x483f935f, 0x3cdff587,
- 0xc6563edb, 0x07f983fd, 0xd98f88d8, 0x630e5b00, 0xaad71bb3, 0xe3732003,
- 0x56fdf56c, 0x0139fb53, 0x22e6fe6b, 0x0d5dbe6b, 0x37d436ab, 0x01b6258a,
- 0xd2b5bdfa, 0x938c6e5a, 0x78e1f528, 0x20fde315, 0x56f7cf85, 0x67e2c74c,
- 0x573af09d, 0xf98d6de7, 0x5952ef04, 0xd6cbf684, 0x4ff84664, 0x9d017aa6,
- 0xbe7a3baf, 0x3f875573, 0xf733e60f, 0x19e0994e, 0xbdd6ff3d, 0x18db7ef1,
- 0x563f6b48, 0xd7a30491, 0x79ff3d13, 0xa3d7a34b, 0x1f961e93, 0xe9cefe8a,
- 0x829e9a24, 0x1efa934d, 0x6f2bd535, 0x51efb2b8, 0x6e957d13, 0x17c96599,
- 0xea58e787, 0x5be6d617, 0x14d617ca, 0xafe7ca5b, 0xe7c9645e, 0xd4b4ee87,
- 0x9974b79f, 0xcad6fca5, 0x37e52c7b, 0xe4b5ad17, 0xb11e04e7, 0xf671bfd4,
- 0x6db94b06, 0x20d725ef, 0x25bf551f, 0x3e37dc33, 0x007b1d75, 0x5d4fc1f5,
- 0x71f10f8a, 0xf88d2aa2, 0x979554e0, 0x4ca6f6d2, 0xc1cb8047, 0x16715402,
- 0xad086b2e, 0x9972889e, 0x5e2cfc91, 0x1a1433b6, 0xe4adda08, 0xb5c9f825,
- 0x09008b1a, 0x174fac4b, 0xa6ca771d, 0x94f3d6f2, 0x67a302d7, 0x5b972cf6,
- 0x6e0f7f63, 0xe508bfcc, 0x00f26f4e, 0x3ee006fe, 0xf7f621d7, 0x8932f2e8,
- 0x33bf99e5, 0xfcf89cb6, 0x65b3909c, 0x6507971a, 0xcc9bf6cf, 0x8c8f983c,
- 0xf1aafca8, 0x28a8001a, 0x4f3b5127, 0x2e007a46, 0x50cbd0b0, 0xedb77f0b,
- 0x155e6993, 0xa3c61328, 0x235bc9c8, 0x1c899ca1, 0x68dd7c18, 0x7eff879c,
- 0x29aef909, 0xb6f5f699, 0x8f7de9aa, 0x3c9f882a, 0xcd544f4a, 0x5558f4a6,
- 0x55a3d280, 0x5fbe9445, 0x6b694955, 0x0f4a52d5, 0xfd288557, 0x4a6ad553,
- 0xa1aaabdf, 0x5aaa9df4, 0x1550ff4a, 0xcabdb4a6, 0x0fc1a94f, 0x4937f25d,
- 0xaec2abe8, 0xf2879d80, 0x565ac567, 0xe216dd40, 0xf21a5f73, 0x67d759f9,
- 0x3f1f5023, 0xa19d8efb, 0xbc1bdfbe, 0x77ade9a2, 0x5f49fa3c, 0xfe030829,
- 0x3b967b33, 0x9c9e38e3, 0x819d3636, 0xf867ba3c, 0x46dbbe13, 0x92415e51,
- 0x37c90d81, 0xdfa31dcb, 0x75f08c61, 0x7f313c3e, 0x016b98e7, 0xfd1ec71f,
- 0x7bf6366b, 0x717fec4e, 0x87da6407, 0x0f936459, 0x1b8265f1, 0x3b9d6bed,
- 0x0f3fbc84, 0x82ea3efc, 0x0660cb5f, 0x274904e9, 0x68db3bfa, 0xb1c20a67,
- 0xc40c3e39, 0xdc1ececf, 0x5c7e41e4, 0x8fd3669c, 0x918380c6, 0xeba43796,
- 0xd3fef32e, 0xad9fcd64, 0x9037a691, 0x5c26f63c, 0x4ae91a3f, 0x430e8fd7,
- 0x6a51a7fc, 0x4d38b3f4, 0xbf028fd3, 0x3432da9e, 0x61dfef81, 0x27d60fbe,
- 0x5d82bd12, 0xd5fff548, 0x1fade9f3, 0x358c3e63, 0x281c0fb2, 0xe86ca00f,
- 0x1e9dedf9, 0xd13e5778, 0xcd5f10f2, 0x2fa867ea, 0x5fffc1c4, 0x157ec10e,
- 0x06fd1bca, 0xfd90e41b, 0xdebdf8db, 0xf3b41e32, 0xb637361a, 0x156e9deb,
- 0x2ba0cc76, 0x1a1a5790, 0x3a2764cb, 0x92beeb75, 0x9b07c968, 0x7d96e9fa,
- 0xfc01ff06, 0x4152820f, 0x541329ba, 0x56b8a1d4, 0x23bf304b, 0x2f013f28,
- 0x2bd78941, 0x016ab477, 0x0b63912f, 0xe5b719ea, 0xbde77418, 0xef208ff1,
- 0x6546fe4f, 0xdff962f7, 0xae505660, 0xf720c51a, 0x2f9f906c, 0x9635b772,
- 0x77b940ce, 0xf9f7c6d2, 0x83cf2c05, 0xab114f46, 0xe73d46c9, 0x8e9b6623,
- 0xfb11fff4, 0x64d3279d, 0x1a6cf86f, 0x6afe73ad, 0xfa0b3eeb, 0x585f2599,
- 0xb017cd6b, 0xde90536b, 0x2ca9d60b, 0x5a5f212c, 0x9d36bdcb, 0x95642dfa,
- 0x41dec8ab, 0xbdc6057b, 0x00ca674d, 0x73f95f98, 0x43e7658f, 0xae363bfe,
- 0x7bf61ba7, 0xff3e1f71, 0xe6b0a492, 0x1a0ff287, 0x19707f33, 0x55e1f6c3,
- 0x6e42a728, 0x7accdbe6, 0xceebefe2, 0xc6be7a3f, 0x8fc3d27e, 0x6f21e620,
- 0x18e1fc91, 0x9b34da76, 0x10adf424, 0xbae037a5, 0xbe6b7a4d, 0x2f918380,
- 0x19dfca8f, 0xe9a7ff95, 0xe859892d, 0xc81488ed, 0xfa7325b7, 0x52417d42,
- 0x37c0b53a, 0x47ad3fe9, 0xd2ffe5ff, 0xff4207fe, 0xeffe96d9, 0x3ff697fc,
- 0x57fcc7ac, 0xfcbfeac6, 0x433b6db9, 0x9e4a6f20, 0x60c3c879, 0xd4a93a1f,
- 0xef00f8a4, 0x7a579b65, 0x284e0e90, 0xf3d20f21, 0x3d3cb0c9, 0x46ec3d16,
- 0xa23f207a, 0x5da125df, 0xfe84ff85, 0xdf753d4f, 0x3e67dc4c, 0x64eaacdb,
- 0x47b16d2f, 0x15afc0ec, 0xd833c58d, 0xe11fca18, 0xc8cfbbf9, 0xd2b26f98,
- 0x0f93c967, 0x0dffa0a5, 0x13d84528, 0x2a97d211, 0xc5cc3eea, 0x3ac8287d,
- 0xdba2cf89, 0xfae7f8e1, 0xd7cc7c90, 0xc3967a12, 0x0fcf493c, 0x1b04b80a,
- 0xa3233bef, 0x72b593ef, 0xfd54683f, 0xd4ffa122, 0xc749dcdb, 0xdf6274c0,
- 0x7941df61, 0x8583c069, 0xbd53feb9, 0x4731e1f5, 0x756d3e60, 0x2648f1bf,
- 0x767c1938, 0x2ffe61b6, 0x2ef6f79e, 0x9d85db8f, 0x4c2eddd7, 0x424dbced,
- 0x69e66b6f, 0xa0f11a99, 0x41b65c5e, 0x73e085f5, 0x4f4db6d9, 0xea768a3c,
- 0x70df76bb, 0xdb74bfe8, 0x00987f4b, 0x6aedd2f9, 0x0cbe0cd2, 0x8dd29497,
- 0xbffc2097, 0x1e376c74, 0x92f57e4a, 0xbfcd1de6, 0x374fb8ff, 0xefb74a3e,
- 0x9ee8d8d3, 0xb0d298f0, 0xc5756b4f, 0x91c34bc0, 0xaaafd45c, 0xa1ae7eb7,
- 0xaf72793d, 0x63d352c4, 0x4bc373c0, 0x9c2027a4, 0x4f028f08, 0xaa8b785d,
- 0xa0bc041f, 0x14f0373c, 0x9080fe5d, 0x779fd83f, 0xd3f3d114, 0xf95fa3cf,
- 0xd70fbb3d, 0xedf4f45f, 0x71c75c1e, 0xf5d392a5, 0xfc532b63, 0x1a916e30,
- 0xe529d14a, 0xff1e8bdf, 0xe15bd121, 0xe14c3f1b, 0x9fbfa0f6, 0x50a6f68d,
- 0xc2df5c3f, 0xfad037f5, 0xe880580a, 0x3931e8ae, 0xa7e90c2f, 0x3dbe9b0a,
- 0xc8645f06, 0x6f8e2f9c, 0xd60b8504, 0x12ed1c77, 0x4efeb3f4, 0x7f266f0e,
- 0xfc8622c8, 0x3fc343ff, 0xfe5316ce, 0x93c70753, 0xbe09b643, 0x4ccf6d02,
- 0xb77775af, 0x0d4e7e20, 0x1fa2a7f2, 0x9094c82d, 0x25f48780, 0x31bf2bf4,
- 0x87e3952d, 0xd16c9579, 0x2980f40e, 0xb7eb1df8, 0x18e77ea8, 0x65f63b4b,
- 0x4bf8f77a, 0xef30f8c4, 0x8fbfdc38, 0x86a2b0a7, 0x55bbeb18, 0xf61ef836,
- 0x997d1371, 0x7bf39bf8, 0xbf9c3ddd, 0xcf0f7e0d, 0x9fe58e9a, 0x07f9c9bc,
- 0x08fee1db, 0x52a48af3, 0x25ebbef9, 0x16760792, 0x75d7c589, 0x6b6be0aa,
- 0x302741b9, 0x304a456f, 0xdff60bd1, 0xfe4fe087, 0xd07582b3, 0x832f24ce,
- 0x67a79e38, 0x16df067f, 0x251ffe0a, 0xad9ff95b, 0xbbdf7ce7, 0x7da2157e,
- 0x3f0d4cae, 0x2bf228f1, 0x8bc867f0, 0xe1e6aafc, 0x1fd74fba, 0xc04dc3f8,
- 0x0c1ba7a7, 0xcfcab53e, 0x7a2d3e68, 0xf484b376, 0xa7a7cd19, 0x891b408b,
- 0x3df0a7c5, 0xb5169f26, 0x9f953ffe, 0x8faefc06, 0x0f219f82, 0xb463837b,
- 0xf3633c3c, 0xe5a33c12, 0xc9bdfc21, 0x9fd27bb2, 0xbd067741, 0xfcb2fc95,
- 0x1817f222, 0x5dd06974, 0x741a5d17, 0x62ffc3d7, 0xf9745f81, 0xa005a460,
- 0x2a5dbc93, 0xcd6555d9, 0xda0c3cfc, 0x8b203cbd, 0x6da7e4e0, 0x3cbcd58c,
- 0x0f9cc920, 0xa21be547, 0xf2a3fbea, 0x03f55179, 0x4b4af951, 0x03a6b2fd,
- 0x47fc231a, 0x4becf52c, 0xc41f651f, 0xfd8c87b0, 0x4678d826, 0x0c5d210b,
- 0xde50d4ec, 0x0541cba9, 0x1ee0ff45, 0x0ec5ec99, 0x182af180, 0x3d3ea3a7,
- 0xb1b9021c, 0xf0edc9d2, 0xd3d3bd0e, 0x8995d207, 0xac99df3c, 0x67b942ad,
- 0x7274ef7c, 0x5e47473f, 0xe4d127a7, 0x2cd238a7, 0x0d6edc93, 0xfcb1e9b3,
- 0x10a3b020, 0x6f595bde, 0x39ffdce5, 0x5e0d764d, 0x8d68f68a, 0x771343ec,
- 0x3d1bb2c1, 0x68e92ae8, 0x6ccd7a1e, 0x55f0bef8, 0x3a558e99, 0x70633ce2,
- 0x57e42c5e, 0x89ec99fa, 0xb3f42c13, 0x6ccfe889, 0x82c576e6, 0x08fa5135,
- 0x54f4435b, 0xa1a25ae0, 0xe03b053c, 0x973fab7d, 0xe88945f3, 0xb5bd68af,
- 0x278f68dc, 0x95df685a, 0x03cb59d4, 0x65da3ec2, 0xcb0649f0, 0x86833920,
- 0x42e7da0f, 0x47934f2e, 0xf01b335d, 0x665071d1, 0xb6799e78, 0x9c7c2659,
- 0x97e7e7ad, 0xfc4c942c, 0x493ac156, 0x6a701a1e, 0x7ad27e43, 0x3b6d5797,
- 0x177d9cfe, 0x3fcecdd2, 0xa439f98e, 0x1ddf3b6d, 0xcff31bb1, 0x8ff83dbd,
- 0x29fd67ac, 0x37e49d7b, 0x26ebd8ee, 0xf3d8ef7a, 0x6177c1db, 0xfc9d977e,
- 0x3f7b1d75, 0xd7f4831f, 0x845edcb1, 0x1063aef2, 0xf7aa87b7, 0x95a63e7c,
- 0x8415d7f6, 0xc6b2a3b7, 0xbfe6a3f5, 0x3092961e, 0xdea15585, 0xf89e37b0,
- 0x93bcf829, 0x7b1d0bfc, 0xb80ecf3e, 0xa9eb75fe, 0x1d39e710, 0x59fb366e,
- 0xf7225f9c, 0x8f770783, 0xcf0cb4df, 0x69f71ba3, 0xca7ca1f3, 0x831f7f0b,
- 0x59e3b472, 0xabb50fae, 0x79e38fad, 0xe1fc8745, 0xdce01532, 0x9fd54c8e,
- 0x1194fbb1, 0x62a34393, 0xe4efe5c1, 0x7850b937, 0x4fb70a68, 0x21e1fdff,
- 0x73bcb9f9, 0xae121d87, 0x7fc38bfb, 0xd7b0b944, 0xac69744e, 0x32c374f7,
- 0xb7ce57d2, 0x7fcae1ee, 0xd0b83a17, 0x0b914b75, 0x7fd4f759, 0x5aff7c73,
- 0xa2fcd2f6, 0x9d27a0f9, 0xf283b9ef, 0x9a3edcdb, 0xfbd205ef, 0x7869ff82,
- 0xeef0167f, 0xabbaff39, 0xddd7cdff, 0x9d5fde3b, 0xe3aef02b, 0x85f07f79,
- 0xbefcd3bf, 0xf4db9cae, 0x0dee94df, 0x9b15febd, 0xa80ccdf7, 0xb8d59d3f,
- 0xb2b8b150, 0x19abff7c, 0xc0cafa50, 0xdf388903, 0x37e751c9, 0xc2a6fa46,
- 0x92c9a6ed, 0x9641ec8d, 0x907b0928, 0x840351db, 0x496030fe, 0x0321e901,
- 0xf5cfde06, 0x0ebbc506, 0x195f1fcf, 0xb147df3c, 0x3bec6c14, 0x97ebcc01,
- 0x9ed5bc8b, 0xfcc4b9fc, 0x603a3478, 0xa20ff7f0, 0xa0703b5e, 0xa42f7a4c,
- 0xe8beefa4, 0x97bfce99, 0xe7bb1669, 0x0ed5af4a, 0xdab24dca, 0x7f45534b,
- 0xff9f18d3, 0x0e149734, 0x0f261c03, 0xfa1269fa, 0x570f2747, 0x5cf90499,
- 0xf6815816, 0xb59754c5, 0xc33c06bf, 0xe1cdf719, 0x380d5768, 0x8797590e,
- 0x93241c70, 0x70bcf49f, 0xdc1379c4, 0x2f18c232, 0x871f14c3, 0x1f729f63,
- 0xbd859df9, 0x904d474d, 0x5aab5c57, 0xb4159f90, 0xc81c3997, 0xe5ec36ce,
- 0x84cde0de, 0x2188adfd, 0x032bf80d, 0xdad3bf65, 0x06dfd91f, 0x3e2ebe5e,
- 0x537e3c0c, 0x851bbcbc, 0x45ae8197, 0x74ebf20a, 0x62fa17b4, 0x1f9e0cfd,
- 0xdce85218, 0x570bd84d, 0xa4291778, 0x50cc0cf7, 0x8e855f10, 0x1cf0aba6,
- 0x6893e1c4, 0xd9b7171e, 0x64707f68, 0x91f70449, 0xdfe50ab5, 0x10e3e9b0,
- 0x7b2f33df, 0x0c9df4ee, 0x8d7ee6fd, 0xf1e53dc7, 0x7dbf8ff3, 0x8c44e5f9,
- 0x2c781417, 0x46afff84, 0x167aff3f, 0x2d380389, 0xa1285854, 0x25bdfa0f,
- 0xefc5bef6, 0xdfe3cd6d, 0xfbba5377, 0xdefd5f39, 0x3abfcae4, 0xd8e40e7d,
- 0x5df300fb, 0xe1a30e98, 0xfd5db315, 0xaf0e669d, 0x1e1621e0, 0xe42ae3c2,
- 0xe139d33c, 0x9ffe821d, 0x99b3d3fb, 0xea4ed768, 0xe5c09518, 0x17b230eb,
- 0x385ec282, 0x3e09bccb, 0xa1d7ca17, 0x79fe7409, 0x8ac77650, 0xec2adc2b,
- 0x7c625fed, 0x751da409, 0xfb4646ac, 0x1f92758d, 0x60e75437, 0xb7c4639b,
- 0x9f86abe4, 0xfe0de04a, 0x8f3c6ce4, 0x842fe3e1, 0xbc6609a6, 0xa938cdb5,
- 0x0789e98c, 0x74df7bfc, 0xe14df51e, 0xc23df68b, 0x35b3ab77, 0xfc862f37,
- 0x6fc05db8, 0xc82ffee6, 0xf36979ff, 0xefd21b06, 0xcb3675a5, 0x2aa96af9,
- 0x6cb1b1ec, 0xe66bce2c, 0x0b3ba77e, 0xf65072f1, 0xb0673c61, 0x88168cf9,
- 0x0d182e71, 0xfd1fec4f, 0x9d555be9, 0xdab76bf8, 0xbae11f30, 0x430723fb,
- 0x56977a3b, 0x9e6b1a53, 0x9e7cec03, 0xedc3590b, 0xfdffd263, 0xc3a93be0,
- 0xf68c9915, 0x7e131d67, 0x63fa688f, 0xb767c744, 0xafee30b0, 0x5ca2af68,
- 0x68cf5b38, 0xdc90077f, 0xf037768f, 0x7eccf7fb, 0xb69b8b9c, 0x82f512ff,
- 0xc749668a, 0xa50a8623, 0x6d3f4355, 0xc65129b0, 0x6bc3387d, 0xa3eabbc4,
- 0xc5f137af, 0xf8215556, 0xfbb0981e, 0xe3f71c66, 0x9ea18d36, 0xd3b17fe2,
- 0xc7f8fb83, 0x07c499cd, 0x57ebadbd, 0xa9aaec55, 0x972a3748, 0x30f4d187,
- 0x92ce3eaa, 0xf40e4cbf, 0x699afe47, 0x8be25d6f, 0x6befbf81, 0xbc173892,
- 0xfe16f940, 0xbdbe4cff, 0x80b7c869, 0xa3e2679c, 0xf90f5abe, 0xbe4b1a96,
- 0xa9bc962d, 0x7bc5f708, 0x5e22a686, 0x26aabf17, 0xdb6f92c7, 0xe739f8aa,
- 0xb94e2233, 0xdbe411a3, 0xadf24db7, 0x8c5be411, 0x5fbf9078, 0xff0b7ca8,
- 0x36dff0d7, 0xd6316f94, 0xf9566bab, 0x08f9a636, 0x8d31b7c9, 0xaf3c4b36,
- 0x7c9f3b5d, 0x47af9293, 0xeaa0f8fd, 0x3f418f8b, 0xfe3e84db, 0xc44b888c,
- 0xe5ce5071, 0x7f8d3a6a, 0xe2ee72a1, 0xff73950b, 0xe4367045, 0x8c1de2dc,
- 0xd27b9ce2, 0x8b739721, 0x939c8177, 0x9cb91e90, 0x7187bc5b, 0x7c945cbf,
- 0xbe43d91b, 0x115faa31, 0x4d83ede1, 0x02df0fe9, 0xabf58dfd, 0x1fd4073e,
- 0xc6ef2ddb, 0xae5de599, 0x7adc10a6, 0x1783bbc8, 0x0876ef26, 0x6c720779,
- 0x68d7ca08, 0x5b35f0fa, 0x8f77c1e3, 0x2bff5e3f, 0xcadf97e4, 0x86f8de74,
- 0xbd0f9f8d, 0x1678fe36, 0x6263d7d2, 0xdc848b3e, 0x510aaf6b, 0xe45e53ff,
- 0xf1772beb, 0x468af138, 0xd4561fae, 0xfc2f614b, 0x17c27733, 0x78bfce1a,
- 0x2152c48f, 0xebcecb3f, 0xf38d27b3, 0xc3233632, 0x720b0f44, 0xbfcfc94a,
- 0xf40e6140, 0x72ba97e3, 0x5bfea24f, 0xfefdc39a, 0xf17be2a5, 0xd0abadab,
- 0x88fc5dff, 0x46a5e744, 0xe711ab7c, 0xa26e23db, 0x77f91979, 0x6627e3a3,
- 0x99a9b88a, 0x1bc294bf, 0x947fc462, 0x7fe6b16e, 0x966ff822, 0x62f04adc,
- 0xe331cbaf, 0x5d7a8c38, 0xe0283a70, 0x7ed32754, 0x802705da, 0x27bd379b,
- 0x33d3009c, 0xe1ba5232, 0x585bfc52, 0xebef566f, 0xbd16e035, 0x5d7fc36e,
- 0x0de9fa2a, 0x7b9c060e, 0x1dc05fac, 0x939202ec, 0xa758f0d1, 0x33b5f975,
- 0xe8094e31, 0xe84ce486, 0x181700d7, 0x70d26f2f, 0x47977dcb, 0xd664fd05,
- 0xe1829a4c, 0xae30b30c, 0x6a0bca1c, 0x0fdcbd17, 0x1dee31e0, 0x4edc58ef,
- 0x0f609b2f, 0x56ec39e0, 0x41c92767, 0x35db0e83, 0x141c07ae, 0xbfddddf0,
- 0xf9d93272, 0x7a8e924d, 0x24e23048, 0xae0106b8, 0xa828ff78, 0x8106fc70,
- 0x0eff911e, 0x8719f23c, 0x8bc91ee3, 0x635c9dfe, 0x40bc42bf, 0x8e66ccfd,
- 0x22586097, 0x4eb164bc, 0xa8a97f3a, 0x84117c95, 0x8206d35f, 0xe19f219f,
- 0x93c665cf, 0x58957e89, 0x4c954bf4, 0xa8a965fb, 0xf35ed337, 0x99e7a407,
- 0x036caa4f, 0xfbfe1b81, 0x4f3e7a2a, 0x9e34501c, 0xb6bc04da, 0x085d3c21,
- 0x77ae4eb7, 0xfba0be45, 0x50794650, 0x39e05909, 0x5f73d1e5, 0x0671af09,
- 0x518e90bc, 0xcbe735be, 0x92682f98, 0x9ef4df58, 0x50f3c5eb, 0xef17bf33,
- 0x7ffbc239, 0x18b1f24c, 0xba60beeb, 0x8b9e85ee, 0xbcf16e80, 0x8eba37a4,
- 0xd23b5386, 0xe9bab7f3, 0xe76735f9, 0xe7a44ca1, 0x43f7123d, 0xce5a2734,
- 0x1e763d35, 0x09d5b5f7, 0xeeeb0f74, 0x6df5557c, 0xcb90c6f4, 0x7ed1ee82,
- 0xbb37df30, 0xf1821704, 0x141c5ba2, 0x18f347ef, 0xb353f5c2, 0x64e6de7c,
- 0xf567d7c9, 0x2edbbfde, 0x37278cc5, 0x3f2323f4, 0xf8c3c71a, 0x6f1826f9,
- 0xd178f764, 0x2fe183fb, 0xfabadf38, 0xbad9bfdb, 0x6ebe718c, 0xb590543c,
- 0xb88d5e10, 0xe05223a8, 0x73ea2a47, 0xfc4b25d3, 0xc85ccc15, 0x7fdc6fad,
- 0x7bdc96aa, 0xa74d2cff, 0xebb774fb, 0xe89d77c6, 0xe2674f33, 0xdbe26f7c,
- 0xec7fefb8, 0x5998e7e7, 0x44d6f636, 0xab263fdc, 0xe3eae90c, 0xa1f92a43,
- 0xe3ca9e3f, 0xedf9af6e, 0x3e5d0501, 0x3898f0d7, 0x8938cd76, 0xb037acec,
- 0x87a8f1eb, 0x047f983b, 0xef132fc1, 0xd5d465ed, 0x5f02f14c, 0xae12dd8f,
- 0xa537d4c6, 0xc435e933, 0x219924db, 0x7dfc5ade, 0x7f20b8a7, 0x032c87fb,
- 0x1fa0a05d, 0x07b1fb50, 0x9bd63259, 0x33264fe0, 0x27e37c66, 0xf3075e6f,
- 0xf6487f18, 0xacdea179, 0x03172e03, 0x7ae47a7d, 0xe0980b1b, 0xab858135,
- 0xfe34dfd1, 0x9c3affa8, 0x3be81177, 0xa8a44f78, 0x07b54379, 0x6a25ebf3,
- 0x72050c1f, 0x6d9eb03d, 0xbf7267b5, 0xea017285, 0xf5c13761, 0x4eb05ebc,
- 0x728861f2, 0x8a5af341, 0x93a82a2f, 0xb6e142e8, 0xbc1cc4b0, 0xfa03b0df,
- 0xda1eb6dd, 0x05fee167, 0xbadfb1ed, 0x875e6f33, 0x49e60772, 0xb9f9ebed,
- 0xf3b4017c, 0x2dd4bf22, 0xd78afea2, 0xb3ef0c4b, 0x7df3d514, 0xea90e8a9,
- 0x7dc6f2c3, 0x3b7ed08f, 0x97ebc603, 0x6450fb8e, 0xca0bdd2a, 0x2fba7494,
- 0xf84c1a19, 0x7f1c60eb, 0xf220fa6c, 0xabbc520b, 0x98a0c097, 0x64fe63e3,
- 0xb3f2421f, 0xeb4cb7c0, 0x96bcfd0b, 0x236e9c93, 0xe7433aba, 0xde0147ed,
- 0x1bf78001, 0x40e55e22, 0xab5a07ce, 0xc2fc5f69, 0x9b9f943e, 0x38a24d34,
- 0x8f2c858e, 0x8e6638e2, 0xebe6fae7, 0xe8c33b97, 0xed5d7be7, 0x0fdf881c,
- 0xefa76e5c, 0x1cb8dbed, 0x4ad41f6e, 0xebe3f6fe, 0x58f78655, 0x24cbd7aa,
- 0xabd78e2f, 0x7e563f74, 0x1431c78c, 0xc7fae36e, 0xdfbcf581, 0xe1b7a8e3,
- 0x439607b9, 0x11ab70be, 0xb4e5c0e7, 0xe8167f61, 0x90c2fe3c, 0xdd62e5bb,
- 0x75a1f63d, 0xd92434cb, 0x2e5b7968, 0x8b0971e4, 0x2d1cbd90, 0x1cf1cb77,
- 0x197c83dd, 0xeae6271d, 0x0e9063b6, 0x5d105f22, 0x19521c57, 0x07d231da,
- 0x9714b96d, 0x73a247b6, 0x92cdf18b, 0x8a1ae31f, 0x4987b1de, 0xcfe70eff,
- 0x2fee11fb, 0x8619daef, 0x3c431f2c, 0xb1ca9c80, 0xa7e9fe77, 0x1be4fdf0,
- 0x02088c0e, 0xb827c9ba, 0x59be711b, 0x4f3c799b, 0x52eb1bd6, 0x9b2f3ef0,
- 0x40e497da, 0x02ccad61, 0x52713926, 0x13775ff2, 0xd4741fdf, 0x667c0c77,
- 0xb8053569, 0xc1cb7ebf, 0x66ef55f7, 0xd8646315, 0x043d84ef, 0xf51f81f6,
- 0x6b5de29b, 0x1d133453, 0x9b59ef14, 0x55f7c322, 0x1aa61e22, 0x576857f7,
- 0x8a71f1ac, 0x06fa4af7, 0x3f4638d3, 0x2edabf46, 0x1ee86ede, 0x7fd6f69e,
- 0xd68fce31, 0xf286a9f9, 0x1e9fba22, 0x4fd2f7e3, 0xadcfefce, 0x395e6093,
- 0xac14cbaf, 0x8cc1f39e, 0x1d73e6a1, 0xcafc3523, 0x98da6fd9, 0x9cbf04df,
- 0xbf31c53f, 0xe38ddf09, 0x7f01ef80, 0x61493757, 0x23f984a7, 0xe516795a,
- 0x0af3e475, 0x98ae7fe1, 0x1aebcfca, 0x8158de33, 0x4b233f7c, 0xa1607a22,
- 0x8937d680, 0xfa2f35f4, 0x78b30bfd, 0x8f6842fb, 0x08f8d8fc, 0x13904fe7,
- 0x1523945e, 0x52e6d7eb, 0x8bc93afd, 0xc86e37fd, 0x28a47d27, 0x5e546647,
- 0xa3f48477, 0x4923a6a2, 0xb7c0c7c8, 0xa81f50eb, 0x51d76898, 0x68fc1b8e,
- 0xe2ebf7f0, 0xe8732b3e, 0xc67ef1a3, 0x8be646ff, 0x21f2d7c1, 0xf583d72e,
- 0x39831f9c, 0xdf5f5f9c, 0x2f0ae2a6, 0x9f89bf84, 0xfce16f8f, 0x43763f2a,
- 0x2f87de2e, 0xc3efccdc, 0x453f581f, 0x78fa7d43, 0xa6fda258, 0xbd737f27,
- 0xabbf9a35, 0x7defbe25, 0xe0d2fd5d, 0xe18f836f, 0xaf1c6aef, 0xef14f80c,
- 0xf5f3464f, 0x0fe1b54c, 0xaf7cc3b7, 0x03d61a79, 0xddf29df3, 0x26ad3d3b,
- 0x14f90939, 0x3c2817cc, 0x2b90cb9e, 0xfb8f0ae5, 0x8bf3dafb, 0xb76c3f1a,
- 0x677e47fa, 0xebf1e44f, 0xfdd12a75, 0x07b3f8f9, 0x7f205d9f, 0x9d5f285e,
- 0xf18d3f8f, 0x7ed63de5, 0x2de8277e, 0x8076bfba, 0xfae0046b, 0x8a26fd4a,
- 0xa9e8fdf3, 0x3f113323, 0xce81bba5, 0xddeabe91, 0x4e72822c, 0x557ed309,
- 0x3dd328d2, 0xb244a601, 0xf99b73af, 0x956dc798, 0x7a26e33e, 0x1ed6792a,
- 0x4bed019e, 0x86307e76, 0x779668e2, 0xe85a5c52, 0x872fa129, 0x1f20c75a,
- 0x7e3c2894, 0x042e5a2c, 0xd70fdc1c, 0x367e2bb6, 0xc2da4fae, 0x69288fdf,
- 0x9bb551b8, 0x746e25ce, 0x3a3d46a8, 0x1d010dd7, 0x9c5dfde3, 0x02ddf99f,
- 0x6dac6e23, 0x2513972b, 0x81d92a4d, 0xb7b65b25, 0xc970fc63, 0x77f2763b,
- 0xa19cb705, 0x9e5310fb, 0x94fe46d9, 0x396c9360, 0xb711eb7f, 0xd88e45b9,
- 0xb1b0ee31, 0x211dce9c, 0x0df2847f, 0xcf97e3b1, 0xfa585f17, 0x219d9ecc,
- 0xafe96100, 0x7ca0f49e, 0xd9b2d539, 0x7e877083, 0xba6e32bf, 0xc3669c47,
- 0xa7195f3d, 0x01ff0a79, 0x438f738c, 0x9c4635d8, 0xa4be96eb, 0xb2fcc247,
- 0x739c62f3, 0xdbe5e974, 0xef1c7d3e, 0x7b3db411, 0x6f9c71fa, 0x7e3e3fd9,
- 0xd8c1e31c, 0x77ed275e, 0xa2dea7c1, 0xdda36c38, 0xb5dfb126, 0xe2927d6f,
- 0xb5dfdbd7, 0xf6b7b0fb, 0x6307c73d, 0xf6fb603c, 0x6fd0522f, 0x34cf64b9,
- 0xd92eebf2, 0xc5952531, 0x148c2fd8, 0x017c36e9, 0xf8d1f3f1, 0x8078d03a,
- 0x023ed6e2, 0xebfca37c, 0x286dbb8a, 0x5ecc71e7, 0x1f5b6f11, 0x8f429efb,
- 0xebc6daf8, 0xe51cb9ae, 0x1fd7237e, 0xfb671bcf, 0xdbf1e026, 0x7abf8017,
- 0x1b102fc3, 0x3fe11f7f, 0xa2fb4f00, 0xe369f7f0, 0x8a3c5fc2, 0x7b7d8d65,
- 0x5c8db38d, 0x7b8cdc00, 0xfc380f10, 0x88c91c87, 0x5c525fe7, 0x866de233,
- 0x4f9ff717, 0x91fde307, 0x5ce76a13, 0xc7b85fba, 0x68bc63ae, 0x89b79ec9,
- 0xbc77da7f, 0x26687e41, 0xb3b423ee, 0x3f1e3fae, 0xd675892e, 0xae7c79b9,
- 0xefc63f80, 0x5df43d7a, 0x3a72e9c4, 0x7b77e236, 0x9d95db8b, 0xee36cf5c,
- 0xfdd79467, 0x76c3c451, 0x41ca4be3, 0xcaf91d3c, 0x0e036878, 0xddc390ba,
- 0xe3b1e871, 0x2beebba3, 0xfe217c08, 0x8aea1f70, 0xc0fc8733, 0x7a37e4b1,
- 0x0790c59b, 0xfc781bed, 0xfb1abb7a, 0x9711b05e, 0x3e688ffe, 0x3c585f0d,
- 0xffe6f9fa, 0x81d3e175, 0x4f724fca, 0x2dfdb538, 0x774f1cb6, 0x9eecdf4a,
- 0x7d149961, 0x1cebca6f, 0x473b7187, 0xbb83b434, 0xdeb16cec, 0x6f57e136,
- 0x78a64a7b, 0x070d55e5, 0xcb478e48, 0x2f7c0a8b, 0x337cc625, 0x9a2b7cc5,
- 0xf6d13ef8, 0x82ec3bac, 0xeff6da7e, 0xa8ae7a22, 0xd2f1423f, 0x95f96f2f,
- 0x8b8a6ad6, 0x6c227dc0, 0xd3db7f9a, 0xdc90c6fb, 0x44b2ef16, 0x8c49338f,
- 0x3d8e6c13, 0x8cfeb04e, 0x50d29c65, 0xcebba683, 0xc529de3f, 0x77f6237f,
- 0x83eb85aa, 0xe9e41aa7, 0x0fe318e1, 0x77d6aa73, 0xa4bf60a1, 0xfcdc67f7,
- 0x13d919bd, 0x12e5fa47, 0x093bce77, 0x146a9849, 0x4cbd55af, 0x87fd77c4,
- 0x5df10d2f, 0xe18abeed, 0x7c22577c, 0x551e7e4d, 0x4bd4300f, 0x2cbcb4d5,
- 0xcb442bf4, 0xc6c92d1b, 0x2ffc26c2, 0xf54f4f71, 0x644779d2, 0x70f3e220,
- 0xfb1571c6, 0x9f944bfd, 0x5b0a2fea, 0xfbf30a95, 0x2df2484b, 0xdfd97e83,
- 0xe794183e, 0x977fd9ee, 0xd963f11e, 0xb0aa57e2, 0xbb461e77, 0xa4e0bd84,
- 0xaf7906f8, 0x08f9de93, 0xf5a4ee3e, 0xf9f1d81e, 0xff5fa413, 0xb9f8cec2,
- 0x202f580f, 0xde750aaf, 0x9f1df1c7, 0xd457fe3f, 0x8c31b19f, 0xd438f85f,
- 0x3ea1bb47, 0x8e9cec9e, 0xa0c61367, 0x85f0a45f, 0x3ca266bb, 0xf4e78c2b,
- 0x6a4cf858, 0x3bfa1ab8, 0xc7f3cc96, 0x77a20db6, 0x759f4a25, 0x81e8dc53,
- 0xe055cf1d, 0x4cfed4be, 0xa97dc33c, 0xe7a105fd, 0x53bc52ff, 0xcd7aab55,
- 0x4cc5e3f1, 0xf3ef9af1, 0x12de6294, 0x2fc8c4af, 0xfe847c41, 0xba04a6aa,
- 0xaffa0407, 0xd48f9fa5, 0x447c3bce, 0xfcfea1c7, 0x3fa453fe, 0x7ae883ca,
- 0xcebdf946, 0x395ee221, 0xd77573b4, 0x059d6a0f, 0x9fd35f3c, 0xaa1693cb,
- 0xf853b0ff, 0xcf79458f, 0x87fd797e, 0xeeeefc84, 0x10afb787, 0xd344d0ef,
- 0x6fd146ef, 0x5fbf96e9, 0x959deb1c, 0xefa7f318, 0xc858943f, 0x76ca7a86,
- 0x857fbd27, 0x7de028ef, 0x3f1a9d85, 0x44f32ad7, 0xdd9b9de8, 0xc5971e42,
- 0x9ddde845, 0x581e62fe, 0xd1ccf31f, 0x9fbd34fa, 0x61939cf6, 0x0bf9595c,
- 0xbbe23f6e, 0xc7e7e77c, 0x71859e7e, 0x1714f189, 0xffc2fe5f, 0xb7283a22,
- 0x3f22e647, 0xb3b76e74, 0xdbe7c88d, 0xfc8c1d5f, 0x0646a6da, 0xf38af9f7,
- 0xbb06f2ba, 0x58bffef5, 0xdaaaa9c7, 0xbbbef0cb, 0xa4b6af71, 0x57f33917,
- 0x5fa3d727, 0x725ffa71, 0xdf5bbf12, 0x35553a73, 0x59df133b, 0x3897ea30,
- 0x77c5cb62, 0x137c5e51, 0x71eaee39, 0x9c5df53f, 0x25ac47cf, 0x153efd05,
- 0x3ca377a0, 0x3e92d92f, 0xfb04fd10, 0x043bc69d, 0x8fdc04de, 0xb25eabf6,
- 0xef3531a7, 0x7caa2733, 0xf430ca99, 0x54cc8cdf, 0x1b1d1d60, 0x67f414ce,
- 0x9cea4718, 0x9dee4b1d, 0x3ad3c676, 0x98f61c4a, 0x09cf9df7, 0x8d0f7aba,
- 0x1e3e64fe, 0xee3187f2, 0x724c357e, 0x2f388ef8, 0xbb012bd5, 0x6e97bf08,
- 0x79699399, 0xa1a9457f, 0x04a7c07a, 0x4eb662cf, 0x6fc932cb, 0xa5e2bc63,
- 0x264a9959, 0x4ffe577e, 0xddcabd17, 0x24a16678, 0x01150bd2, 0x9faeb663,
- 0xa2887ee5, 0x7e1039e6, 0x15d3cb1a, 0x86a54919, 0x358e3df8, 0x7502ea50,
- 0x5653bf8b, 0x9e4e50c9, 0xe8f6e710, 0x1bb4c2ef, 0xdc92775e, 0x6c620d0f,
- 0x07be3a78, 0x4dd04de1, 0x10f153f0, 0x5763e61e, 0x1797192a, 0x93b47433,
- 0x7d8050a5, 0x5d54f409, 0xe9133d35, 0x18fcfe11, 0x07a64907, 0xbfa3cfcc,
- 0x41ea05fc, 0x3dfca740, 0x70b2efbf, 0xc3188035, 0x3aafc981, 0xe877f199,
- 0xccc3bf56, 0x71a5c6f6, 0x68e77892, 0x1731c91f, 0x84ebfeeb, 0x94558a3c,
- 0xff09d5b7, 0x4473c1c8, 0xa822ce97, 0x58bbc617, 0xd7521e24, 0x9994e528,
- 0x90593dff, 0x3ea9d137, 0xcd1e5ad1, 0xa2d72017, 0xf8206dc6, 0x449fbf41,
- 0x5449fbf5, 0x557c9fbf, 0x829c06bf, 0x7c3e8d8e, 0x556562a7, 0x1f1b809e,
- 0x06e021cf, 0xef8919f0, 0x9c5b31e8, 0x13879c4f, 0x6cc4e35c, 0xf01f58ec,
- 0x4e971e5a, 0x612fb978, 0x41c6276f, 0x865aa4b3, 0x890aef76, 0x97f0d3ef,
- 0x63b532e7, 0xf0f883ba, 0xb94e311e, 0xc30af380, 0xbea3d53f, 0x1eaff493,
- 0xd5bd9df5, 0xdf5d8b8f, 0xe27cdbdd, 0xb127cf63, 0xe26bfe97, 0x75fff663,
- 0x0bc552e5, 0xe786bf6f, 0x49f25db6, 0xf55bd007, 0xd438f2cc, 0xfd8f1333,
- 0x70be95a3, 0xd031d33d, 0xa438ef8a, 0xb8b7a06f, 0xd1efd661, 0x7d1bd274,
- 0x40758be5, 0xe00fd5de, 0x7f189370, 0xf73f1d6a, 0xf70965be, 0xe87981d3,
- 0x8b37fac7, 0x0a3937fa, 0xc470dfc9, 0xbabfdfc6, 0x91eb96a5, 0xa658fcb7,
- 0xef1ee9f3, 0x803fe151, 0x2a5d6edf, 0xb1e92385, 0x7562d7de, 0x9e6e3f78,
- 0xbdfa3f18, 0xe6f300aa, 0xbd6396ae, 0xd2e9c557, 0xfd1757b8, 0x9602c54e,
- 0xb321de27, 0xd4eb3f7e, 0xcd67e4bb, 0x2c7deea8, 0x1ee816b4, 0x7ba04ff5,
- 0xebc7973c, 0xe2171462, 0x485c78d1, 0x4f3a20cb, 0xd9dfe433, 0xdc04de91,
- 0x307f99af, 0xeff3aeff, 0xa6f4af8b, 0x2a1def9a, 0xef2ce2e7, 0xbeab54f5,
- 0xea6f9434, 0xc15fd039, 0x0dced654, 0x39535e61, 0xfcc4ade8, 0x7249be18,
- 0xa3094d2a, 0x3cf4545c, 0xaf7a8856, 0xa8c3ef78, 0xd55d25af, 0x0ebe67a5,
- 0x4b8e6fff, 0xbc5cbe26, 0xb6f74bd6, 0xdbcf8b3f, 0x7b24f489, 0x57017c72,
- 0xed087a4f, 0xc6aeebe0, 0x5cf7a775, 0xf3e6b54f, 0x157dbe91, 0x6ffc8080,
- 0x4fce073e, 0xf6df7bb6, 0xa37efce2, 0xf4bbf432, 0x44ef8f84, 0x86cfca18,
- 0x887c5007, 0x0463309c, 0xbc46bf8e, 0x6ababa6f, 0xaa2ba524, 0xbc794898,
- 0xaf2a8adc, 0xea447348, 0xaa74e917, 0x1a556f77, 0xf95557e5, 0xebe03528,
- 0xfbd0d5f0, 0x7c618e93, 0xf02e877c, 0xf0136497, 0xe5fe900b, 0x73a4ab48,
- 0x195ea745, 0xd8df77c1, 0x7077d840, 0xc10d7a59, 0xf919d357, 0xe53ea135,
- 0x548798ed, 0xf8419dad, 0x564af452, 0xc56fe508, 0x5c228e07, 0x2d4bde9d,
- 0xd3da5aef, 0x7fbd46c6, 0x836f051a, 0xb871b6de, 0x7a712fdf, 0xfdfb868b,
- 0xe3178b6a, 0xb2bfee22, 0x82295deb, 0x1c43983b, 0xe7e6bfee, 0xdee13db4,
- 0x09be7b32, 0xe9eceeee, 0x04fbf704, 0x7016ef9c, 0xa87816ad, 0x46acf016,
- 0xa47e53b8, 0x3a44fbc8, 0xc47bd29d, 0x112bb7fb, 0x08ca901f, 0x7d878077,
- 0x30c98854, 0xf179ba1e, 0x7412eecf, 0x1fc8dbab, 0xfcf2bb2a, 0x127b7708,
- 0x05c3bb87, 0x06ba2078, 0x3cb17bb8, 0x5d54f044, 0x9f50ce1c, 0x15e441e3,
- 0x7e267b84, 0xb800f8e7, 0x871f8df7, 0x058270f2, 0xe4d25ace, 0x23fb830b,
- 0x124b7f7c, 0xbf0d1e7c, 0xafbf8d24, 0x6f77f06b, 0x88b571fa, 0xef16aeb7,
- 0x511c2227, 0xe00879af, 0x4f0e34c3, 0xc8a47dfe, 0x164d28fb, 0xe0357ff6,
- 0x161fcb01, 0x19c210fa, 0x73c51fd3, 0x56c93cfb, 0x38454fb9, 0xf2efe1f5,
- 0x1b10a4b0, 0x6878cd98, 0x85a5fe2f, 0xc6f31798, 0x4ad7aff9, 0x44aeb23f,
- 0x7de903bd, 0xdd6de918, 0xcf0daaab, 0x57a5e43f, 0xcb67ee59, 0x5e89fdb3,
- 0x42407f82, 0xc13ee6bd, 0x5e916b87, 0x1edc7e68, 0xe0e8295e, 0xeefef16e,
- 0xee7e823d, 0xa0fcfc17, 0x7e3e3741, 0x74cd643f, 0x9498c71e, 0x20ef1361,
- 0x4e399846, 0xc0d7d130, 0xd9179834, 0xe94a5e36, 0x8ef64b9d, 0x7e36f89d,
- 0x7d23f314, 0x6773be25, 0x9b43bf98, 0xa1f50fd7, 0xd9dde344, 0x39c4de89,
- 0xa23d3174, 0x6520f788, 0xc4b64f6e, 0xdab5df7c, 0x7e81dfb7, 0x13e6de99,
- 0xafa7f3ef, 0x6be2f184, 0xf54764dd, 0x59cde40d, 0x2d577908, 0xcb0c55d8,
- 0xc1707cb9, 0xf44d0bbc, 0x5f8bdf11, 0x595d7547, 0xf64af480, 0xa93fa438,
- 0xf844ea1d, 0xe8bdac02, 0xcd487abf, 0xc1fb87eb, 0xfdb18943, 0xb9e2b370,
- 0x7593c4bf, 0xb09fc5a9, 0x3b53f54e, 0xde55a27d, 0x43fb13ac, 0xfe56a99f,
- 0xcb83f630, 0xc59f7f44, 0x0f147e07, 0x6e729674, 0xa4cfc92a, 0x0fef636b,
- 0xc216aad5, 0x47aa39f7, 0xe50ebe73, 0xee6f5c6b, 0x9d187721, 0x8c0d9c83,
- 0x2ffe88d8, 0x3396be83, 0x8c42e72e, 0xbac693eb, 0x3ef4867e, 0x9d01f702,
- 0x01f71ee8, 0x34c3cbcc, 0x5b949ba2, 0x587fe46c, 0x5eecf825, 0x046b5fc1,
- 0x7c803d5f, 0x81df0235, 0x13fa51f6, 0x90eb4fc1, 0x12dd20ff, 0x78f5ce9f,
- 0x6197bef1, 0x8c772cc7, 0xab1cf7a5, 0x0fda365d, 0x61ed7794, 0xfb05da17,
- 0xf7e8ebc6, 0x7a59dd91, 0x59e58dc0, 0x43c03f0e, 0x91d2cc4a, 0x2f733e5e,
- 0xe2abe8b8, 0xf4fd015b, 0x72a2b0ae, 0x949ea47f, 0x451fdec7, 0x9ef453a7,
- 0xcb5faa80, 0x70fd3fd0, 0xe113a552, 0x8f3c70fc, 0xcfcdaad3, 0x3e03b826,
- 0xe29bc5b6, 0x5f6752a5, 0x1f1ef5d5, 0x2f70ff76, 0x12ec12ef, 0x0c0d82f2,
- 0xf92661b1, 0x7bde2b50, 0x1b10de64, 0xcb139269, 0xf432e787, 0x0f94f5eb,
- 0xcdcbc8bd, 0x90ae5e5c, 0x434bcb62, 0x65e4377f, 0xd2315cb4, 0xb74d1795,
- 0x5d54a7dc, 0x66f2463e, 0xc1ff6c64, 0xfcede3ef, 0xf3e66a1d, 0x2cf7a7e5,
- 0xdefd7807, 0x83d42f0c, 0xf7c57f0c, 0x5a27ac62, 0xcab89e3e, 0xf40357d8,
- 0xcd02d03e, 0xaff8f0fb, 0xfbad57dc, 0xd5b9e141, 0x9c140fa4, 0xa8b4a1cb,
- 0x11f13a76, 0x9318d3c3, 0xfd7c7c9d, 0xdf883d0f, 0x7ce2b5e3, 0xc61abd7c,
- 0x1b7da4b8, 0x0e607aef, 0xe3c175c0, 0xe38f9d32, 0x14d90d3d, 0xbcb2c2df,
- 0xef1ba7a4, 0xdf0f1e23, 0x31c731ee, 0xe9d4fc14, 0x37bffd47, 0x1f582c7a,
- 0x8d537fdb, 0x83bb44ff, 0x5da246f9, 0x675dfa01, 0x9fbff504, 0x18dde938,
- 0x18da1f23, 0x8fc733ef, 0xf15be918, 0xdc21ced3, 0x33f78adf, 0xab9dd217,
- 0xf4d79d0f, 0xdc7c17ce, 0xc733e863, 0x4547d273, 0x7dc0359c, 0xca7fc596,
- 0x098f49cf, 0xf473187f, 0xca271e52, 0x7b94bdbd, 0xd3133c78, 0xd3ff9763,
- 0x3d51a47e, 0xb821b4ec, 0xd3daf2fe, 0x2fa5deab, 0x6280f3d6, 0x60bdc711,
- 0x79787c63, 0x2059be0c, 0x102f07ee, 0x7d065de7, 0xd0df7f15, 0x465d39b3,
- 0xd4f4add3, 0x1fa74425, 0x5fc9541f, 0x87f4015b, 0xd4f4987a, 0x698f7a78,
- 0x3d9713d9, 0xf9c00b78, 0x95324393, 0x10739d97, 0x87ffb65d, 0x3bfce28f,
- 0xefd2ab7f, 0x70727c26, 0xb7ebc51a, 0xbb9ef78b, 0xedc5cef8, 0x5c5c1bda,
- 0xbb9c14ae, 0x8bbbe897, 0x35f3c2ae, 0x7382dbe4, 0x565e900f, 0x4ebdef80,
- 0x788f75c0, 0xe8229279, 0x1fb60277, 0xea1cbb92, 0x3e72b615, 0x15431361,
- 0x10de8fe4, 0x0637bbef, 0xf2e0df3f, 0x0b45e25a, 0xff50d75b, 0x24c3f40c,
- 0x02c85c53, 0x8507fbf1, 0xe584b878, 0x21a5887a, 0xd6f908df, 0x77d6ff4d,
- 0xd69ddbb0, 0xc2e91a75, 0xb04e75ae, 0xebdd61d8, 0x73e72efc, 0xb6146fa1,
- 0x7579f0e6, 0xe3e7e7ad, 0x7ba7ad63, 0x7da9131d, 0xf1ec627b, 0x1fe317ef,
- 0x9bc22aab, 0xbc44ac5b, 0xbe105bb7, 0xd5f7c35d, 0xf627d60a, 0x2aeb4c91,
- 0xc4b52dac, 0xe6d4152b, 0x857afbd3, 0xdbb5f3eb, 0x1753fb4c, 0x97fe425e,
- 0xc6eb0d27, 0x2e6bfdcb, 0xaea8bc23, 0x7e913bbc, 0x7c553d8f, 0xec5e7bc7,
- 0x84e9e397, 0x49531a16, 0x4f76eaf2, 0xf74dfbac, 0x56a9e347, 0x80ec09e0,
- 0x0c9e132c, 0x3fb744fc, 0x8efcb9b6, 0xe21cf0f7, 0x509afe11, 0x0a2bf2ef,
- 0xe1b1e97f, 0xd7a0a4f7, 0x040fa063, 0xdf7e082e, 0xf5cbc4b2, 0x6f813f0a,
- 0x77c63e03, 0x08c2e7d0, 0x379127b7, 0x4e3fb193, 0x5b83e70f, 0x1e82f8f7,
- 0xcf5ec526, 0x59eb5d6b, 0xc7a042ca, 0x3eb8d49c, 0xee7afbd1, 0x05c72162,
- 0x4f8ba7ac, 0xfa7c2df3, 0x385b9ada, 0x9ffc0a9f, 0xd10f7fdc, 0xbc70b1f5,
- 0x7a54e30f, 0x486bcf5b, 0xd062e307, 0x1b10b0c1, 0x8f7ffd95, 0xfe684e0e,
- 0x3ee08f11, 0xee15fb02, 0xde4fc5d3, 0xbf3cc63f, 0xfd27e2b7, 0x9aa5f69e,
- 0x0ea73b0b, 0xf41df64d, 0xfb277ed2, 0x434961aa, 0x633f815d, 0xa3cf12fb,
- 0x6e9fa19f, 0xc6cfe245, 0x578bd2c4, 0xc72e0556, 0xaaea8bf3, 0x8fd1cba2,
- 0x973d0aaa, 0xce9b9ea1, 0xd623177f, 0xcdcc7d7b, 0xaab2bbf1, 0x983fce92,
- 0x94f4c423, 0xd80077ee, 0x47f24c89, 0x7eab2e2b, 0x1d01a9a6, 0x789adffd,
- 0x025540a7, 0xd0b3d3ab, 0x1194945f, 0x1fefc132, 0xb2ee7e2e, 0x8ebf6d26,
- 0xe8761ae7, 0x8e60fd1f, 0x8b59ca81, 0x6545ecff, 0x93c05f41, 0x1c731cf1,
- 0x124bf06b, 0x46cf13f9, 0x5acf13f9, 0xf30491e6, 0x5b3b0afe, 0x1ce87871,
- 0x8fc26152, 0x5f01e02c, 0x5bbb1f68, 0x1e5cebe7, 0x607d21ef, 0xb23645d5,
- 0xff09d6eb, 0x2fd0cff4, 0xe851704d, 0xe0c301bc, 0xc096beb0, 0x73c4e1d7,
- 0xaded190c, 0xf8dde508, 0x4f4c9762, 0x4f984a1f, 0xf3095e64, 0x1564597d,
- 0x931d0fda, 0x3f20ef5a, 0xe69033a0, 0xd67ebc06, 0x84b0e5af, 0x817912e7,
- 0xb5ce118b, 0x0bc32872, 0x77217ff5, 0xc1bd6066, 0x1f4ef450, 0xf7845e9e,
- 0xf3a60212, 0x8eb421ce, 0x33dcbcee, 0x2552d17f, 0x6feffcea, 0x5fcb9b17,
- 0xc62ffa71, 0xf93b5479, 0x1f4960fb, 0x57be7448, 0x94ee75dd, 0x64f2fb47,
- 0xd123c737, 0x41d5d205, 0x559d37ae, 0xc87d09bc, 0xf3323d9f, 0x7c3ccb45,
- 0xec22bc96, 0x53a03ad1, 0xe832a73c, 0xb7e29863, 0xaf0d1d21, 0x3c66ef81,
- 0xfb77d0c6, 0xf079e8b8, 0x31b9fa98, 0xe897183f, 0xcb973e55, 0x7a28e3f7,
- 0xf9f12dd8, 0xdced8a87, 0x1921646e, 0x20c73af1, 0xcf05653c, 0x8fe33227,
- 0x8d77b5ec, 0x82b62773, 0x0b9e75e7, 0xb9cfc6de, 0xa733e7a3, 0x3c16eef9,
- 0xdcd399ef, 0x7b9e3e6f, 0xf8ba29ce, 0xab774c43, 0x51e3fb9d, 0x2250fc5e,
- 0xb7a6f67d, 0x21e3545e, 0x46e6f1dd, 0xae609f7a, 0x73bfef9b, 0xf88aa759,
- 0xe35d300f, 0x5a6156e7, 0x27cc6ddf, 0xfa2a0df2, 0x84896e1d, 0x721ab86f,
- 0xbe18beb7, 0xb9bdd51a, 0x425f3b07, 0xf41a05b4, 0x321b3a5c, 0x5ef935da,
- 0xaede79e6, 0xf14e0e0b, 0x838a47fb, 0x6ebdd5d6, 0x58c1c107, 0x7c24d427,
- 0xbc49c174, 0xa5c066cf, 0x37f1dd6b, 0xf8fe855f, 0x1cdce4de, 0x790fe8c7,
- 0x579f3c9c, 0xc13e9c34, 0x0b939022, 0xb91ffedd, 0xb77afca1, 0xcb4c2eff,
- 0x95839d1c, 0x5537c421, 0x0390af98, 0x1c00a517, 0xb8141a3e, 0xd1e11938,
- 0xf482f7d2, 0x2e4ec3fe, 0x1ba70e0f, 0x1bab6d7a, 0xc8bd9be9, 0xf7e35af5,
- 0x38ed5632, 0x008dff7e, 0xe55e8f9f, 0xcb95cdef, 0x22ee6bde, 0x62ccb2ff,
- 0x7a4621d9, 0x1e0df858, 0x7bc4db76, 0xf39d7cd1, 0x79ef0e14, 0xcf74f18d,
- 0xd952de6e, 0xbcfdbef2, 0x957e3ca5, 0xae632d29, 0x2b09d8b7, 0xecf75d04,
- 0xd11afd07, 0x3a5fccfd, 0xd92dde99, 0xc893e9a9, 0xa738f1cf, 0xfd53f9b3,
- 0x4ffdc632, 0x1f912d58, 0x6f51fc69, 0xe7e42b53, 0xc87d1387, 0x5ceff3ae,
- 0x97ef899c, 0x3f70b454, 0x28bcaa67, 0x7d203fe3, 0xefdf3f68, 0xe108bf31,
- 0x5d7bf2e4, 0x369af3a6, 0x474332b5, 0xe5d5be7a, 0x7f907947, 0xc45dffbd,
- 0x30e7e1a7, 0x40e7ddf6, 0xce38c00f, 0x39bc5bfc, 0x0df91f48, 0x0ea53f4e,
- 0x5c81c4a6, 0x039857cb, 0x298d54d3, 0x98e34c4e, 0xe5ecd303, 0x9daa7f42,
- 0x2783fa45, 0xf7c34f27, 0x9f9bf3c4, 0x17db14fc, 0x927d912a, 0x9bf29e89,
- 0xee82fd5f, 0x28f3f9c3, 0x5b5bf74e, 0x39dd8b34, 0xff9ac1ba, 0x9f359376,
- 0x33e6b111, 0x03f35a0f, 0x7d266d70, 0x1e1eff73, 0x9a7a529f, 0x1e7defdf,
- 0x3c22a060, 0x3e49d9b6, 0xce6d294e, 0xd38778c6, 0x586dbb4f, 0xdceffbbe,
- 0xeadceeee, 0xf72577a4, 0xe2c717bd, 0x6a1df092, 0x3f2c46e7, 0x8d90d71d,
- 0x4fa845fe, 0xbbb04b71, 0x71bb408e, 0xbd06a5e7, 0x69be2986, 0xfdf83fe7,
- 0xf6adce94, 0x9c51c630, 0xd3e4f5de, 0xb7a79f48, 0xec7d200e, 0xc3642979,
- 0x70f7437e, 0xf3884ffc, 0xe954e458, 0x7e3dab16, 0x1d01e842, 0xe879b527,
- 0xd6b8ba17, 0xc24beeba, 0xa8a77cd6, 0x7d331b7f, 0x10f8c74f, 0xdc34aaef,
- 0x7ec53767, 0xc173fdbf, 0xa53d4f17, 0x8b2b7419, 0x37991ef7, 0xe2befba5,
- 0xdb73eeee, 0x8e800325, 0x4316114a, 0x4697bfba, 0x0f85db8d, 0x38927fd1,
- 0xadfceb2f, 0x5539f04c, 0xef896455, 0xaafbd2e8, 0x4d53697c, 0xed4151fb,
- 0xd27c94be, 0xdca5f757, 0xca67da66, 0xb9481eb6, 0xdb6bfa19, 0xebefd0a2,
- 0xe279cd95, 0xf8490981, 0xf9c06e5d, 0xe7fa3962, 0xf25e1ada, 0x8bd03d60,
- 0xbde39ac7, 0xa5c76b0a, 0xe9f1354d, 0x834ba5d7, 0x0e74ca9f, 0x5a72e79f,
- 0x461ef172, 0x1dff2d69, 0x1b86d2be, 0xe11abbae, 0x4fdf9ebe, 0x9e5856cf,
- 0xb653fc0c, 0x8fef86fd, 0xc7c1ef86, 0x3e70f9c6, 0x2d24f8d9, 0x3fadbbde,
- 0xee76f743, 0x44ff71b5, 0x7b465c34, 0xfdef7e38, 0xe508ab81, 0xa2f7f412,
- 0x3fb52c6d, 0xe47d0368, 0x6bd0e4c4, 0xd3954337, 0x570fe1ac, 0x95965c53,
- 0x253e809e, 0x373ab7d4, 0xf48dbe4b, 0xb5f67975, 0x97fb5aa8, 0x943a3c51,
- 0x8a37b4c7, 0xa27ed6c3, 0x47a57cf1, 0x68f77e32, 0xa25e99a4, 0x119df5eb,
- 0x2ab7dfa2, 0xcd720a5b, 0x1d97efa4, 0xd878a1ad, 0x19c871e8, 0xc13b8a68,
- 0x7c4bd1fd, 0x027a14ec, 0x22d91c93, 0xcf287c5e, 0x48a7bbd3, 0xa5104097,
- 0x5ea9b297, 0x6cb5eb84, 0x4bcfa63a, 0x99640791, 0x33f203cb, 0x79278b6d,
- 0x3eb7a6d0, 0xa3a473f1, 0x1e74d1fa, 0xefdc5fd6, 0xe846f36e, 0x77e358bd,
- 0x9e74da71, 0x5276692f, 0x8fe9d53c, 0xcb979234, 0xeb138e30, 0xd9b4ed3f,
- 0xbd3b5f40, 0x8c64efbd, 0xe06b6e0b, 0x6a9f8aef, 0xfb593be8, 0x9a37fd8a,
- 0xf17d8def, 0xdf13fe08, 0x8bf8f54f, 0xacdfb83d, 0xa9d371e0, 0x2a332b7d,
- 0x68c9e063, 0x6655a497, 0x79d2bda0, 0x91b7cbab, 0x0ae953eb, 0xc8d3ddf9,
- 0xfc2f92af, 0x79e9f749, 0xbea07877, 0xe1faea1b, 0xe5073eff, 0xfc77e88d,
- 0xa1ddf640, 0x1f3eed0f, 0xa015905f, 0x03f4e3fb, 0x7cfe3036, 0xa0144585,
- 0xafb8f9b7, 0xc93ca18c, 0x25ebf9cf, 0xb05c238a, 0x7c1ebac6, 0x1fbcdae7,
- 0x292fe116, 0xb0b8c50e, 0xd68b4a06, 0x718bcb5b, 0xbc50f0ff, 0x94cbc517,
- 0x19cb59d4, 0xad1f908b, 0x7b4bfeac, 0xca7db82c, 0x6bf9f58c, 0xa3b9163c,
- 0x50f9dc92, 0x95f5a3ce, 0xd20037a2, 0x1cfec49b, 0x6d2733bc, 0x4b1da401,
- 0xc82da427, 0x7cee7bc4, 0x8ed3231f, 0x8fbf98f8, 0x45953a57, 0x7177f106,
- 0xa58fee18, 0x346452cd, 0xe42c1de6, 0xe3bfcb19, 0x6eb820fb, 0x63313df3,
- 0xf35eb8dd, 0xc726f677, 0x10cf71ab, 0x2f2e6bd7, 0xab287013, 0x3afc5bb7,
- 0x90a5ea13, 0x7f78dbfb, 0x55da95a9, 0xb7697e34, 0x5ff62bf4, 0x1399b7d8,
- 0x68a135f0, 0x798b8c83, 0x878e4ba8, 0x0f75892f, 0xdf80b0e5, 0xf4143743,
- 0x107d7e43, 0x02fecff5, 0x9f2439c0, 0x45809f84, 0x5c5e301c, 0xca9e5766,
- 0xfcf397b3, 0x8ae04f3e, 0xaf6081da, 0x873a01a9, 0xbde72f9a, 0x471bf78c,
- 0x425e0626, 0xf9b7ccbc, 0xb7c42b07, 0x17e411fe, 0xf0e1ca5d, 0x4bcad8f0,
- 0xc5d9632a, 0x933fbf02, 0x3e5ce81a, 0xa3ef8bb4, 0xd54eacee, 0x8bfef7ec,
- 0xfb094790, 0x4f5ee95b, 0xee890ee7, 0x1d223f13, 0x8fb6fba1, 0x6865e95c,
- 0x9e01a7c7, 0x223eee50, 0x5ef815b1, 0xace3565e, 0x9e212f45, 0x787ce2b3,
- 0x38de5fde, 0xd1772e49, 0x15beb9fa, 0xcf01b95f, 0x8de75283, 0x0e748b1c,
- 0x2d779eeb, 0xe3d0ff7c, 0xb9faf1a5, 0x96d3de38, 0x8f17d287, 0x16f3f1c2,
- 0x387c84bd, 0xa1ee8e3a, 0xdcac02a7, 0x8d5d287d, 0xcb1a547a, 0x60fa87d8,
- 0x58ef0cda, 0xe43fb9f4, 0xdb24e3e1, 0x50b379e4, 0xf3cb1bcf, 0xf92c7e7d,
- 0xae111237, 0xed5271a5, 0x17ce3a6c, 0xe85ea3bf, 0xcb823f40, 0x9529ef84,
- 0xea7e3819, 0x69269e50, 0x3c0f8a11, 0x99bde064, 0xd12de9c7, 0x25e9c919,
- 0x454a4c5f, 0x1b50ee3b, 0xbf20d418, 0xec340d0e, 0xf48b88cc, 0x792361f0,
- 0x2df7617d, 0x5ff7e0c9, 0xfa1b0692, 0xa1d7af0f, 0x513213fa, 0xf5c1beae,
- 0x7e5c4ff1, 0xa65f57f2, 0x4fbf8ec5, 0x0a78e048, 0x61638b9e, 0x3838ff93,
- 0x13d233fb, 0x2c3ce783, 0xf027da6c, 0x1c734dbd, 0x7ed15977, 0x72841dfa,
- 0x01f742d6, 0x71ac1bca, 0xc5c597e7, 0xf3a0d71e, 0x0b1b39e0, 0x1e3225f5,
- 0x21d7f688, 0xc2d573a9, 0x4b17ba24, 0x73c13be7, 0xc6990b1a, 0x63eb9e0f,
- 0x33cd77cd, 0xaee9fa85, 0x9af5acc7, 0x2c7aa73e, 0xe383d5a7, 0xb4adebb4,
- 0x29cf048f, 0x6fd8ced4, 0x90b6c23a, 0xeedcfc0a, 0xe21de5e5, 0x6fa8cf3c,
- 0x5b3ed7f4, 0xf8def713, 0x556de8bb, 0x2e007820, 0x219f368f, 0xf359747f,
- 0x418b823e, 0x89f0dd0f, 0x7c132167, 0x225baa52, 0x69ede036, 0x7bb86e0f,
- 0xc990d814, 0x871f05fb, 0x9feddd36, 0xbbf8e508, 0x8ebe260f, 0x73e2eacf,
- 0xd90f3312, 0x42172e64, 0x9d4f7775, 0xfa8bca68, 0x9b43ed5d, 0x340a98af,
- 0xb78a3595, 0x27c1e6bf, 0x4e4e595e, 0xdf111a8b, 0xcf3839df, 0xa23bca6d,
- 0x8fc82ef2, 0xa8f5e536, 0xf2a8a4f2, 0x40fca8b4, 0x1dcdbf5e, 0x40fb2c19,
- 0xd4f83fde, 0x9efbf815, 0x7322fd6d, 0x358f05f1, 0xf02bb6f2, 0xb3cb7cf7,
- 0x56d3eff8, 0xc93e4b34, 0xba2b3f24, 0xb55bf3ce, 0x0e10a3f9, 0x1ca32f2d,
- 0x74926b28, 0x0d5debd4, 0xc79423db, 0xbb535e76, 0x963f6e06, 0x76a11c35,
- 0xd23ff6bd, 0xef7c7c46, 0xdea9f7c8, 0xd89fcef9, 0x5befeb0c, 0x751e76f5,
- 0x4e2c0a44, 0x7f7eee48, 0xdbfb6dbd, 0x0a2fbfdd, 0xf9fbdbdf, 0x8d1c900f,
- 0xc41e07ba, 0xf9bab8f9, 0xbde380c4, 0x7bd2cf23, 0xdd1c7fb4, 0x03aa16fc,
- 0x2cce4bf1, 0x9fdda053, 0x438f8fcb, 0xb4df0b7d, 0x67e37dc5, 0xdc12f852,
- 0x81651e8f, 0x5bdc704b, 0xc3ef87cb, 0xac384c9f, 0xef863eb6, 0xf0786f95,
- 0x98142be5, 0xeb7761df, 0xb709fc20, 0xf06f094d, 0x7f2b727c, 0x1dff4551,
- 0xa0f0e7e1, 0xc83641d6, 0xa6c0993f, 0xeb787e53, 0x3d7f9863, 0x3faf04e1,
- 0xac9075ba, 0xf27209a3, 0xdf90a98a, 0xf7e6c7ac, 0x37ae04da, 0x369bf31b,
- 0x8453ffdc, 0xfbe32b0b, 0x76335e0d, 0x5b9d3c80, 0x66db6a72, 0x1fdcc780,
- 0xdb9c93c5, 0x55dd76dc, 0x50870479, 0xa611c61e, 0x7ed3780a, 0x215d7248,
- 0xee1fa27d, 0xf1ba7d81, 0xe2dc1ee9, 0xd2e2fda5, 0x37a8edca, 0x451dcea4,
- 0xc7a145fb, 0xddc9e92f, 0x52193869, 0x3ae92fa8, 0x8db2eb97, 0xef5223e2,
- 0xf51e9372, 0x033df8a0, 0x0fa23be0, 0x36cbc097, 0x096d9eb1, 0x80f6bfdc,
- 0xf3f51a67, 0xc47fe49e, 0x42ca6321, 0xc5a7f24e, 0xf372be91, 0x202b9006,
- 0x7989d7d7, 0x097b5baf, 0x466e29f9, 0xfc28f13f, 0x67d7efee, 0xbffeb754,
- 0xaef2032e, 0xdd6ebb6e, 0xf33f7f2c, 0x0dbaf6b9, 0x5b90dcbc, 0x7b79d2eb,
- 0xad4abf63, 0x3ea4e3e6, 0x5c46c978, 0x28c2bc47, 0xece17b7e, 0xd1971b11,
- 0xad2d7ffe, 0xfdfdf99f, 0x5a3f0ed0, 0x7a86c43c, 0xc29f81a9, 0x1257fee1,
- 0x89373d60, 0xf035efdf, 0xb74f8c64, 0x907f51e2, 0x3b407f41, 0xeb403135,
- 0x0c627d07, 0xfae06e0f, 0x3316d204, 0xad2997c1, 0xfffbf0e3, 0xfdb53820,
- 0x4ff4e02b, 0xc947779f, 0x0c379021, 0x7a5f2ffb, 0xedff72dc, 0x23d1013f,
- 0x8000702a, 0x00008000, 0x00088b1f, 0x00000000, 0x7dc5ff00, 0xd554780b,
- 0x733ef0b5, 0x9992bcce, 0x924c2664, 0x84e3c849, 0x71100840, 0xf0444312,
- 0x51888431, 0xd4503b69, 0x20717ad8, 0x9926023c, 0x4b62d5a8, 0x79120cff,
- 0x22341809, 0x0281c150, 0x06f55bc5, 0x701a8c45, 0xaf7a8a44, 0xb7ad8ef6,
- 0xff7f6c57, 0x4a8f8808, 0xd2f5a232, 0x5ad7fd97, 0xce64ef7b, 0xb6b4a924,
- 0xdc3ef9bd, 0xd9cfb3ee, 0xd7b5ed7b, 0xf6b5af6b, 0x4cf5a61e, 0xd8c05c0a,
- 0xce6a2566, 0x7c2c64ae, 0x61edf148, 0x67cf07f0, 0xf7fb193b, 0x95d5a0b4,
- 0xf19fd8c9, 0xe6c60aef, 0x2729bf7e, 0x8ded0658, 0x61cb1823, 0xcfbbf52c,
- 0xd500ded4, 0x7a3f4bb9, 0x3f7c0f7c, 0x8ca97bf7, 0x43ef03e9, 0xf7c18c8f,
- 0x5b6dbcef, 0xd2842ecf, 0x793519d2, 0xf986bca0, 0xef7bc056, 0x27435898,
- 0xbe0ef7f4, 0x5563097a, 0x35e5bbdf, 0xdbb19136, 0x93632a5d, 0xf8ab5b18,
- 0x258a9873, 0xbbe0db0b, 0x644b2cf0, 0x7d63114f, 0x0cd85311, 0x23b875fd,
- 0xb8c1175b, 0xf995d71d, 0x1f5fd0c2, 0xef867e63, 0xf7a54b2d, 0x4c3ddc3a,
- 0x744bf6c3, 0x0ec24017, 0x19faa17e, 0x5a37e3d4, 0x7814bb22, 0x76c2ce5e,
- 0x3e325f6c, 0xf3fa8612, 0x7f7d0e30, 0x0f644a63, 0x8f82cfb6, 0xa371dea0,
- 0xfe861237, 0x47622cec, 0xfa763a78, 0x8c1c3273, 0x05acaae5, 0x8228efe1,
- 0x2b59943a, 0x0701cdd9, 0x713fcfe2, 0x0f007396, 0x6899775f, 0x3d95a93e,
- 0xf437ff4f, 0x7ddbd6c7, 0xe1b0a063, 0xcf6f58ab, 0x3b997826, 0x66f88558,
- 0xb803fc1a, 0x89c81fea, 0xcce7c3ac, 0xb1eb8557, 0x479fe9da, 0x5520fff0,
- 0xb61ff847, 0x0ab635b3, 0x66d61528, 0x0bfc00cb, 0x43fb5878, 0x37630c00,
- 0x978000e3, 0xd670d7ff, 0x2bf3c3a9, 0x07ad0a5d, 0x556df9fc, 0xbc67cd8c,
- 0xd4f2fe7d, 0x58899577, 0x1a6b51aa, 0xa5735b3c, 0xef46c7bf, 0xe28f3fb1,
- 0x0bfa0da5, 0x25b7f132, 0x09ba44ee, 0xd86977e2, 0xba9defff, 0xfdf0eb03,
- 0xf8765c44, 0xfbe074be, 0xf9a3173a, 0xfc3955cf, 0x475535ac, 0xc8fc4afc,
- 0xd7c24eb2, 0x713f90fe, 0x724e393c, 0xfcbaf7bf, 0x00be2237, 0x0f74d1ef,
- 0x75a545e2, 0x63d7864d, 0x43b06f89, 0xd556dcfb, 0x33e0377d, 0xf349ccb8,
- 0x9cdef095, 0x158cbf1d, 0x74ffee0f, 0x8695736a, 0xe9c65ff3, 0x02b72d9d,
- 0x62f112e2, 0x5d03a819, 0x63f1642c, 0xe7886526, 0x8445f45a, 0xc247517f,
- 0x2fdff4f7, 0x49ef89ac, 0x92ba617e, 0x2ba0bf04, 0xdd70d15d, 0x375f0a82,
- 0x373e258b, 0x6e183650, 0x82d5cf89, 0x245d24ee, 0xe2357be3, 0x7c60d27b,
- 0xf93d2c7b, 0x99706fd8, 0xdc94f095, 0xfa11633f, 0xf03b21ee, 0x16ddd00f,
- 0xdd7a2145, 0x646a5772, 0x3da7f225, 0x19f117be, 0xad157c3a, 0x1492ef77,
- 0xdb2bc19d, 0x9441302c, 0x9c9d8733, 0x4a7a4b8f, 0x617a9f90, 0x9f587ece,
- 0x9dd5d7de, 0xc1024561, 0xeaebf358, 0xdeffa42e, 0xfde6af67, 0x19d548ac,
- 0x618843d4, 0xfe143718, 0xbc032b43, 0x2cc5349e, 0xe0175e34, 0xff09c257,
- 0x435fe17a, 0xe8bc80c5, 0xbf1c06c3, 0x9807cb8b, 0xe71a12e1, 0x1d6c29db,
- 0x526cdb8c, 0x6f6826fc, 0xb23e3a5e, 0x4361c392, 0x20146a3e, 0x9b589b35,
- 0xf7c03152, 0x2513a6cd, 0x36f195b7, 0x85bbde0d, 0xf78175f1, 0x5f002a8e,
- 0x4c7d6da3, 0xfa45ba45, 0xd8a5f687, 0xff80345e, 0xf9bff5e6, 0x7cdfc213,
- 0x8d1748c0, 0xb1e7198f, 0x8a9e9134, 0xb524e806, 0xd589e392, 0x8018c8b0,
- 0xa9ea29d7, 0x8a88b1b5, 0xcd565a78, 0x66e9024e, 0x8199e91e, 0xecace3f4,
- 0x0ca1f364, 0x11fcc07d, 0xf74a7b80, 0xc24697ce, 0x58daeefb, 0xb4374e3e,
- 0x4e8bb6ec, 0xbeb0345d, 0xba4bce12, 0x41cca937, 0x0077d1e3, 0x83bf7f8a,
- 0xfb371bde, 0x6ef2c482, 0xa4d32efa, 0xe0f6bd12, 0xcd1be423, 0x38c0a39f,
- 0x328c979b, 0x82a67ae1, 0xbcb9437c, 0xaeec7db0, 0x7f678415, 0x07b7ca09,
- 0x09ce80d3, 0x942abe9f, 0xeaeea52f, 0xbfa0bb5f, 0xffd5dca7, 0x138e258d,
- 0x47f4e270, 0xa648be90, 0x23bd64e7, 0x6e2ecbdf, 0x0c716f29, 0x17f01eff,
- 0x35be2de1, 0x4d0fcb9d, 0xffa2faa1, 0x475cef30, 0x374469f0, 0x222f6db7,
- 0xdac0dc79, 0x591ade89, 0xbbf482c4, 0x69c2c6c8, 0xe08b1740, 0x172874b5,
- 0x3d32b16f, 0x4496fd61, 0x2146f58c, 0x31616e0f, 0x7d96fefa, 0x2c35ed49,
- 0x26f684ea, 0x62a68b1b, 0x6f6c69d9, 0xef417166, 0x3e26b67f, 0xbe7c1d67,
- 0x77758b37, 0x20d444d7, 0x1dab7bcc, 0xbe065774, 0x33eb4ed0, 0x5a4ef965,
- 0x7f0af4cf, 0x4fa83dd1, 0x76fb355e, 0x27bedd01, 0xe7e24bd6, 0xbbf5575e,
- 0xd514f788, 0xdf8ff344, 0x9cfc2563, 0xeb8dbd02, 0xdd9b9f7f, 0xdeca1b3c,
- 0x7a3bdd56, 0x55c9a234, 0x1839db30, 0xb39eebcf, 0xb8dd2037, 0xb7c226dd,
- 0x65cc7e7c, 0xddd57aa6, 0x522bff02, 0x088abb23, 0x9e9113dd, 0x7d4946aa,
- 0x82ce26ca, 0x5666bbfa, 0xe6f509d7, 0xec411deb, 0x07ed07af, 0xb9b817a8,
- 0x5b7028de, 0x2eb27e68, 0x06e92be7, 0x52fea1c6, 0x84a5e22e, 0xc85b8c63,
- 0x7f89b641, 0xe6eff427, 0x493b2925, 0xafd3f6ff, 0x96fd1189, 0xd7882c05,
- 0x795c84e7, 0x3695ca4e, 0x9a2b972b, 0xa832ee6b, 0x9941f73f, 0x95e01d6f,
- 0x83de8295, 0x4a3f1bef, 0x5e9e91d1, 0xef5fe8f9, 0x9fb419fd, 0x5ba2c0fd,
- 0xd2017da1, 0x73dbac18, 0x6047970a, 0x8fd4307f, 0x38f6c08d, 0xb1c1e36e,
- 0xb41c7f64, 0xc846fb08, 0xe0b4c6cf, 0x4fd085d6, 0x3e9993e3, 0xbcf664a0,
- 0x5ee8f239, 0xf7643f6c, 0x1b7e81ed, 0x1b5e3853, 0xdf491b9f, 0x4e0f613f,
- 0x733cc377, 0x3c9f91ad, 0x05e37281, 0x677bd92b, 0xc2117459, 0xaed3b67f,
- 0x70277be0, 0x4250e95e, 0xeaf3829b, 0x043d9276, 0x10b39a7c, 0x36b93bbe,
- 0xe04bcf9b, 0x0986e4e9, 0xcd9b17c4, 0xb3f0bc7c, 0xc27fbd0a, 0x0391981c,
- 0x974f13f5, 0x534056fb, 0xb512c05f, 0xee873d00, 0xbd5e76e3, 0x7881df49,
- 0x09538762, 0xa11eb95e, 0x62678b8d, 0xf2e9687b, 0x1c7ca3af, 0xde51cf8e,
- 0xd9b904b3, 0xc805e2cb, 0x461adb4f, 0x9f514675, 0x91f38f74, 0x585e655a,
- 0x171ba07c, 0x9994f77f, 0xc87e35e3, 0xbe7cf44c, 0xb57ce3fd, 0x707fae2a,
- 0x65c8109c, 0xe48ff926, 0x1d5d4272, 0xfec8ceaa, 0x2d973d0c, 0xfb633aec,
- 0x1de0ceeb, 0xe6bfa06e, 0x9de7fffb, 0x38df8465, 0x9ed645c9, 0xca797c49,
- 0x748b9fec, 0x5a89aeeb, 0xf3e827e6, 0xeaaf820d, 0x63fec2ad, 0x1f224b51,
- 0x6aaaf6ca, 0x72cbdd23, 0x677fa0bd, 0xc1f7cb8c, 0x1fc126ed, 0x1ea2b4df,
- 0x6641c29b, 0x1c47a885, 0xfd4ebfd8, 0x6a20f94f, 0xe17a87a9, 0x9165a8f2,
- 0x004f9128, 0xcc1b51df, 0x2756d4fb, 0x03406fe7, 0x3268b3f6, 0x48b97d23,
- 0x02b5fb05, 0x3d5deb9f, 0x9fa72eb0, 0xfafa7376, 0xf0056023, 0xf7898f3d,
- 0x82ef60ac, 0x4da67b1c, 0x607ee289, 0x2eeb16de, 0xb5f2117b, 0x7ae2755f,
- 0x8e48576e, 0x569b6bcd, 0x4bea15b2, 0xeb405c0f, 0xd399369f, 0x9b88d2e5,
- 0x2114e2f4, 0x11adeb1f, 0x3fdfd90b, 0x01f21851, 0x74764ff4, 0x53947c23,
- 0x280f1831, 0x10f40dd7, 0x5d83a849, 0xcb93a534, 0x9cf20655, 0x524bd825,
- 0x671ca3de, 0x919ff649, 0x1f52c23e, 0xf4c7b971, 0x527b946c, 0x0aebdf2e,
- 0xae49b974, 0xf5c6ce8d, 0x72e4f585, 0x7842bf73, 0xa42d626d, 0xe81ea44f,
- 0x91e8571f, 0xeb986ad3, 0x2a26eb2b, 0xd117775f, 0x27594b78, 0x57a913e9,
- 0xd783a386, 0x7e0e84bf, 0xed007486, 0xe8b01f8d, 0xe35e3065, 0x9a6d1672,
- 0x44e74bc8, 0x4f5c8fd2, 0xc49eb8da, 0xf43ce532, 0x4c7eb265, 0x7ac987d6,
- 0xf5c2db30, 0x69675c9d, 0xe74f64cf, 0xe594c076, 0xfcc19511, 0x3ff9a636,
- 0x60349cce, 0xb2de84d7, 0xb10bf4d9, 0xe0a3601e, 0xd369c5bd, 0xf686ca6e,
- 0xc8fcc690, 0x9780a957, 0xbb7cf09d, 0xb36b7bb0, 0x2d7bdd39, 0x5acd7e9c,
- 0x703b9580, 0xcfb4625d, 0x1732678d, 0xe7c4a3d2, 0x577c2776, 0xfd71df81,
- 0x8dbdffd4, 0x7c24a5b5, 0x9d9cfd5f, 0xcfe7eae4, 0xb256233a, 0x6e858247,
- 0x57eb2fe8, 0x7b53b256, 0x3e92739f, 0xd0fa15ed, 0xd128f683, 0x5fae2acb,
- 0x21275d71, 0x648f5535, 0x35cafb48, 0x4a045123, 0xcdc9acfb, 0xf6c1aced,
- 0x8a2f6890, 0xcae9cf5d, 0xcfccfb4a, 0x62773ddd, 0x6861e01d, 0x588fff9f,
- 0xe981d0e7, 0xe787dfe5, 0xc7c380a1, 0x472c1fb1, 0xdfaab57a, 0xf406deb9,
- 0x1e5d4335, 0xd1e60bbf, 0xa170ef94, 0xfc29ab9e, 0x846f2ff5, 0xcc0787fa,
- 0xbceb8acc, 0x1b1d7a67, 0x5dfcbc35, 0xe89f3112, 0x5b97e049, 0x4deb19f6,
- 0xa87ac69d, 0xc82f58cb, 0x4f4e7a70, 0xfbe1d920, 0xd5b5d033, 0x4ec1f2da,
- 0xbcfad780, 0xa7d1f495, 0x067160ee, 0xfc535bca, 0x5ad9e218, 0xf444f1f8,
- 0x3fba846f, 0x02b4b051, 0x38cac4ed, 0x3faf91fe, 0x742bcfb7, 0x01b7810d,
- 0x899b31fc, 0x3ad60cf0, 0x85ce492f, 0x2c789f04, 0x845f0ffe, 0x9d9a2ff9,
- 0x9e9bbae2, 0xaa4e67f8, 0x60927b42, 0x572da164, 0x2dfb887f, 0xae096f78,
- 0xf059e9ff, 0xb0d5c01e, 0x46c3eb85, 0xbe434b16, 0xd3bb066d, 0x477c4b06,
- 0x5b875f06, 0x5155e2da, 0x8c8edff8, 0xa70871da, 0x802d27f6, 0xfb1ab1f4,
- 0xaf93b04d, 0xe07ae0cd, 0xd7767d96, 0xdd1e0329, 0x2ba87a86, 0x912a75c7,
- 0x61fc84ff, 0xb8968a79, 0x09577a1f, 0x6bf88b5e, 0xa658f5b2, 0xfc57f8c1,
- 0xf79233e9, 0xa7cd978b, 0x5d80c47d, 0xb4f9256d, 0x3d20aef8, 0xdf2b697f,
- 0x6ade9e17, 0xa7ef11d7, 0xe3fdf3b7, 0xc4473ce2, 0x857bff06, 0x8bdbdb9b,
- 0x19453be1, 0xbc64c78c, 0x55f0ffbd, 0xf7a3a45e, 0xdc2f1f19, 0xf78fedc9,
- 0x62af805d, 0xf7f60efe, 0xefd8177e, 0xaaf9e20a, 0x2e2e510f, 0xd0faaede,
- 0x9c87604e, 0xbc598fe4, 0x0b71cafd, 0xa7dfd81d, 0x5fa1a623, 0xe895c768,
- 0x02f7c289, 0x89d7ee11, 0xb5cf015d, 0x1d93171d, 0x95bb7477, 0xedb6e9c3,
- 0xf15c79c5, 0x4af89527, 0xda20b133, 0xff161dc7, 0xfd67e438, 0x70333de1,
- 0x959fde5d, 0x1ff7a26b, 0xf10b9857, 0x85965ee1, 0x5a2b17cf, 0x61b7f900,
- 0x899992cb, 0x866a4ef6, 0xad35eb4a, 0x8f567970, 0x7ae9f883, 0xdb4da3d4,
- 0xfc707f81, 0xf2ff6fd9, 0x3f224f46, 0x4cc55edd, 0xc3cbf609, 0xc27a235f,
- 0x6be028bf, 0x57d7c0b1, 0xaa6b2be5, 0x12968be4, 0xef8ba394, 0x0d71296e,
- 0xf3f45761, 0x0f9cc3c5, 0xb850cbef, 0xc32f20ff, 0x6e18cfb0, 0x3528e65f,
- 0xf9b15e91, 0x940f7f98, 0xc62db0d9, 0x0c81f7fd, 0x640fda8d, 0xfb5f7b70,
- 0x5efb6ddd, 0xcd4d7987, 0x80cf6e08, 0x97f3217a, 0x71ebbae3, 0xb1983557,
- 0xbbb26288, 0x6e56c3d8, 0x8edc6ac7, 0xf6c99cde, 0x8fd84bae, 0x997f6277,
- 0x62f61724, 0xffc7bd3f, 0xdaf10c78, 0x44f1f05c, 0xe7420fb4, 0x1fa0b33e,
- 0x90add1cd, 0x02f8773c, 0xd425e90c, 0x282d8b3d, 0x21c3901b, 0xc913d71f,
- 0x0653faf3, 0x3c84efdf, 0xfde7ea71, 0x3b7f9c11, 0xb73e9cdc, 0x3f214b2d,
- 0xc44f36e4, 0xb5ff408e, 0xa5ed2a7c, 0x67efc225, 0x5f94fddb, 0x288efa45,
- 0xd75831ae, 0x35f47f39, 0x30a88dcc, 0x8bbb87ce, 0x77d9dfc9, 0x854f9a60,
- 0x1feec736, 0x788519ad, 0xf0fb32ea, 0x27af877d, 0xe1f7e70d, 0x386993ee,
- 0x2add86bf, 0xf221bbcd, 0xb2c2d649, 0x33f0b901, 0xca3af825, 0x1c52e601,
- 0x0f94be38, 0x34feee1f, 0xfb83816b, 0x567f480b, 0xa7978d0e, 0x8e7ed3dc,
- 0x39715fdf, 0x1e8f975f, 0xee5046b7, 0xfd07647d, 0x3f6f2096, 0x777d7272,
- 0xefee432a, 0xdf500b3a, 0x2a6fd7f4, 0xf89ca135, 0xdfcf8b8e, 0x402ce963,
- 0x628dfc7e, 0x1ae967ec, 0x6c808b13, 0x5006b25f, 0xa3e8f203, 0x40299f47,
- 0x9ee1ff79, 0x27e60a67, 0x9dfc97c0, 0x78e57b2c, 0xfd266fc2, 0x344b1ea8,
- 0xef9bc70f, 0xe57f72b3, 0xf9547e30, 0xfdc2db3e, 0xab3e7da1, 0xbf28748e,
- 0xf1486beb, 0xc7db7da3, 0xe6ff246c, 0xacbf0b77, 0x83da3fdf, 0x7df918fb,
- 0x1e15ff52, 0x974a4f4e, 0xd483fe42, 0xe3c938b2, 0x7bde59bf, 0xe4133d60,
- 0xbff3ac3d, 0xd9345f21, 0x3246c7e2, 0xe20b0fa2, 0xd0ecd2cd, 0xad653f50,
- 0xbf15f4e4, 0x2afb44c3, 0x81d7ae4b, 0x928aecf2, 0x30133694, 0x6d2527a2,
- 0xf201c622, 0xfde94b73, 0xfba73570, 0x7f231670, 0x516b0e5b, 0xb8bb5e48,
- 0x326f3edf, 0xea83ad73, 0x9edc11ac, 0x16df32f1, 0x5dd698b5, 0xc490ff41,
- 0x480bd487, 0x3f1f283f, 0x3f446c52, 0x7642b74a, 0x9cea6aa7, 0x470efd8b,
- 0xc847134f, 0xa7a73ffd, 0x893ffafe, 0x188f269e, 0x3a829e8e, 0x36d793d1,
- 0x3f093d34, 0xcfbf79f1, 0xbfdc01c2, 0xdd7c0b66, 0xfc4ee427, 0x9bf49b0e,
- 0x99df382b, 0x3699bfa2, 0xfd455447, 0x9c7f33e1, 0x187dffe8, 0x27dc5fec,
- 0x0efda0e5, 0xf395c8e5, 0x16375a74, 0x417f41eb, 0xd236c5ea, 0x629af78f,
- 0x64af6845, 0x8fd96f8f, 0xb73d9174, 0xed2562ac, 0xa8dcf2ff, 0x92b7500f,
- 0x7559741f, 0x0488d4e0, 0xdf10e17b, 0xe5df34cf, 0xbbd3e7a7, 0x1a107db9,
- 0x387b216d, 0x7184a5d4, 0x96039b9d, 0x6b41da08, 0x095fee15, 0x3cebb06f,
- 0xa0afa3ee, 0x740fcfb8, 0x488a171e, 0x8ecf6fff, 0x35bd23ef, 0x91efc838,
- 0xf83a3f1c, 0x1fc7ca85, 0x8efc68c3, 0xeaaf1e72, 0xfee75ab8, 0x1d7eb115,
- 0x6e39fcb3, 0x18d607b4, 0x85c659f9, 0x18809cfa, 0x7afe6f18, 0xae43ad3b,
- 0xd2ccf1ca, 0x0cff5c6d, 0x67e40b96, 0x162c9ace, 0xfa6fc446, 0x05241cf9,
- 0xbb4573d6, 0xcb39378c, 0x79684502, 0xb7e9bbbf, 0xbd00a4af, 0x8e9fa166,
- 0x68c2ca6f, 0x987f93f7, 0xfc7dc9d7, 0xc90009a0, 0x5cffd6c5, 0x42697357,
- 0xf03fbc5d, 0x6b6bdcfd, 0xf6ef48f2, 0xa0d823b7, 0x6fdd658f, 0x351e31d7,
- 0xbd81aed0, 0xf852eb6b, 0xb5c761f7, 0x3c068e57, 0xfffc7228, 0x7f47eb5c,
- 0xc6199da1, 0x4b4f844b, 0xfd0cdfea, 0x7ef9743b, 0x784af6bc, 0x590ac1e1,
- 0x1fad66bf, 0x6ccfbbe0, 0x2a508fec, 0x1c8ac7be, 0x6dacd6ef, 0x0de7d6eb,
- 0x276005d8, 0x39911aec, 0x7eac1f60, 0x85fb667b, 0xebaa5630, 0x5dea0b53,
- 0x1e43e7a9, 0x648fec85, 0xe4203d7e, 0x572cdfc3, 0xf47641f5, 0x57241181,
- 0x4b20667b, 0xe483fec2, 0x80796876, 0xf6073da1, 0xdbc21748, 0xd3e3fc7b,
- 0xef7b422f, 0x1b1fdfec, 0xb77be3a9, 0x37bb45ce, 0xba234e74, 0x2353ed0d,
- 0x4dadd00a, 0x71e80bf0, 0x7a480b8a, 0x7412ea5a, 0x8c330eea, 0x521c7473,
- 0xbe898526, 0x83ae0a5a, 0xf8f7ccb5, 0xe438425f, 0xde7932be, 0xf7c11ebf,
- 0xead2a10f, 0xffd825ad, 0x9da1856e, 0x44f4aeb0, 0x37da02d6, 0x30b59bbd,
- 0x5d25bbe1, 0x973e120f, 0x890f33ec, 0xe08f5fc7, 0x67e6de71, 0xdca3f69f,
- 0x90a228f8, 0x22d0684c, 0xbd40a76b, 0x9684c1a1, 0xcc8cab20, 0x1ce291bb,
- 0x06361675, 0xed0477e6, 0xdf638426, 0x7053c337, 0x814ff0de, 0x8b02db47,
- 0xab6e9f48, 0x4e2839b3, 0x56ff3a54, 0xc52b83c2, 0x5758788f, 0xe3839d5a,
- 0xe19acf34, 0xd808f8a2, 0x7cded871, 0x2fc8b7d7, 0xd75ae124, 0x3b45ae65,
- 0xb9ec0aa7, 0xfcee00a7, 0x7d6a6b8c, 0xd523c7c0, 0x3bb7e5fd, 0xb43e5e30,
- 0x266eff1c, 0x25368ba7, 0x2546fe10, 0xa25941f9, 0x8bb0b35f, 0x8d9f8ddb,
- 0x2be218b0, 0xf6e08d9f, 0xd8e1a5ec, 0xc39f2474, 0xda2a4f5a, 0xffe621d3,
- 0x2ccff704, 0xd0f7d0e0, 0xe479713a, 0x3fc9d569, 0xdcf4f366, 0x5fb6217b,
- 0x85fed1aa, 0xe00f3d69, 0x3d6bbdb8, 0xf04c75be, 0x2aefd601, 0xbd4f7da3,
- 0x3278a827, 0x7d70bcf9, 0xaabd9f7b, 0xd288fd1c, 0xa8fb5aee, 0x5ae6f49d,
- 0x2d7f7ea7, 0x69dfd3ca, 0x16c01f3c, 0x7e874d8f, 0x833efe96, 0x8f6b5dc6,
- 0x0ff5c5ac, 0xbda954ef, 0x607411d8, 0xb9be4bbf, 0x2bd22265, 0x504a4473,
- 0xed3d9a8f, 0xb618e90c, 0xb12fe42b, 0xe30c0279, 0xf3c3d3c4, 0x45f50534,
- 0x1d333d92, 0x5fb455fd, 0xb6bf90f1, 0x18c7f05a, 0x36d382a0, 0x3fb68562,
- 0x6fb0188f, 0x1ce3f95e, 0xbb4a1f0d, 0xfee364c7, 0x14ba9af3, 0x5b2df686,
- 0x42663f15, 0xc627bd7f, 0xea6e0ed0, 0xa69c6854, 0xb82d27d2, 0x93a5b96f,
- 0xec4877f3, 0x057f0033, 0xf18c5768, 0xa07b0aa4, 0x5839fb8d, 0xc448d8ec,
- 0x3d7c63f3, 0x12f78319, 0xad8cabfc, 0xf440f2e0, 0x86711167, 0x0257e126,
- 0x3eed484d, 0xef5bb48f, 0xf3b7fd16, 0x59bb8c52, 0xc455f989, 0xf062b96b,
- 0x2af2cb87, 0x91fa7df1, 0xdfe40cf8, 0xfa17d038, 0xb32ab697, 0xcc29fd6e,
- 0xf1a4eb6f, 0xbcc1343e, 0x056a4e40, 0x0452073e, 0x7d7657bc, 0x86e90332,
- 0xd7e232d5, 0x6a69aee6, 0x6fc78393, 0x4ec85ed0, 0xed89d96d, 0x929737d9,
- 0xc8f8c67e, 0x35fe786c, 0x1cb3e70f, 0x79d7f707, 0x61170eef, 0x48fd33bc,
- 0xe29fd6e0, 0x90a417f8, 0xd61b35bf, 0xe54199c6, 0x796ff41a, 0xa88bf959,
- 0xf533bd7f, 0xc647840a, 0x382e30f5, 0x38e48cab, 0x8a7c33d5, 0x3794177f,
- 0x0e34dc78, 0x116aefec, 0x711e7c5e, 0xd119c40c, 0x62e3876f, 0xdecb0f1c,
- 0x7e46a89c, 0x7be7d07e, 0xacbb4e90, 0xccd7c42e, 0x42df97ae, 0xc6d33b7d,
- 0x9aee293a, 0xd3c4b764, 0x3a4419be, 0x7a733bed, 0xd7083dc7, 0x947d0775,
- 0x8f6492cf, 0xb739715c, 0x93da3fcb, 0xec3f23aa, 0xec1b7212, 0x797f1e47,
- 0x9323ef9c, 0xf6efc8ed, 0x23b72faf, 0x777febfb, 0x17c3923b, 0x28f3c3de,
- 0x890f7ca4, 0xc35f5f7d, 0x5fd434d9, 0xaed23d2b, 0xd8f7ca4d, 0xba3df22d,
- 0xd0f7ce87, 0x0ff8f276, 0xee494186, 0xae222dba, 0x43cef7e5, 0x84bb87ff,
- 0x7b2bc0e4, 0x3748c353, 0x64ed3b67, 0x4b6e6997, 0x7b6ae114, 0x3cc11ada,
- 0xe0453688, 0x578890eb, 0x2c1c4459, 0x834744a3, 0x4025a0e2, 0xa4fc3f72,
- 0xd2abc799, 0x85ee8f22, 0x1ce1e37a, 0xd462cf11, 0x54d9f87f, 0x8a6377c2,
- 0x37fd8e9e, 0x8608fbfe, 0x183eaa71, 0x09f9d70f, 0x87bb707b, 0x7fbc5ae2,
- 0xe75582f6, 0x8968b3f1, 0x33b0f01b, 0x93bfedc2, 0x05a8a6a5, 0x8993bde6,
- 0x32f59f3c, 0xd9e7c5ae, 0x8f2461b7, 0x8231a0cb, 0xdcb5b2fb, 0xe32f545f,
- 0x1fb98755, 0xa5c45eae, 0xf45ece4e, 0xb458a608, 0xb8b52d29, 0xdd7cfb4f,
- 0xdf9ff234, 0x2a2cff79, 0xfd18d7eb, 0x3fd08bfd, 0x3f103c5f, 0xf9f77e96,
- 0xf6e167cc, 0xd0ff80f3, 0xbe8cf604, 0xfd46ab46, 0x775cc459, 0xc3d03ea3,
- 0x43177ab0, 0x1a2506d9, 0x19600af1, 0x7ad6d3de, 0x57bd7052, 0x6f4899b7,
- 0x7e4cdb85, 0xcbd24f7c, 0x67ae1eab, 0xbd70f5df, 0xe08ea803, 0x336cb238,
- 0xe883788b, 0x4533056f, 0xbc2934b1, 0x6ad2ed5c, 0xb2dfd287, 0x8b7336bf,
- 0xcdda1a6d, 0x77f226f9, 0xd7f16e7f, 0xa338bf91, 0xcda9d684, 0x96a6b2d9,
- 0x7d2f13b7, 0xa8078f6e, 0x1b8d32fd, 0x40cf4c96, 0x8782fa79, 0xf19217c7,
- 0x58ddb0b6, 0x2cc38e4f, 0xf5eb1889, 0xa736382c, 0x120dc798, 0xf420bf9f,
- 0x8aebe7c4, 0x167dbe04, 0xfe72bb94, 0xde38f22b, 0x1cbcf94c, 0x875d5f95,
- 0xe30a3074, 0x725845ca, 0x84cc2abf, 0x99751fe0, 0x48fa2147, 0xcdcdb782,
- 0x96bc29e9, 0x5aff21fb, 0xfee193f8, 0xf82593d0, 0xb8c5efd8, 0x42cbbd65,
- 0xf5f3e871, 0x1a64a497, 0xf5fdb7f7, 0x96feffbf, 0xaad7e7ef, 0x45c6bf22,
- 0x8bbe6972, 0xe2a4e5cf, 0xe7c51bdb, 0x701fb00e, 0x0ad56b1e, 0xbfd32394,
- 0x3479a0e9, 0x8239061f, 0x3de5ac71, 0x9bd7a805, 0x304a7bab, 0x5f8c935e,
- 0xf2935684, 0xef9bde0c, 0xda08fd81, 0xf18c6b0d, 0x55f1c1b8, 0x2666617f,
- 0xee4e7bee, 0xd7f5197f, 0x2fe93b7e, 0xad17bff8, 0x16cfffc8, 0x388b5c91,
- 0x2e316383, 0xee894a14, 0xda1171f8, 0x6a8edc31, 0x44eeb6ea, 0x5b7e713b,
- 0xff0f7c42, 0xef18deb3, 0xc8326b63, 0x8c3aceef, 0x4e1e1bcf, 0xfc506efa,
- 0x65d69daf, 0x0e3825b3, 0x10f41df9, 0x599c1de5, 0xbeb86262, 0x116faaf5,
- 0x7633a92a, 0xc67e7da3, 0x466bd7c9, 0x3e3fd4a6, 0xebfabfb2, 0x57d9d683,
- 0x6f5ceb82, 0x7ec4c162, 0x619d709a, 0x3ac51b7d, 0xe2fa799f, 0x8fe75c12,
- 0x825c5ff7, 0xdcd9bceb, 0x29be47ee, 0x41af0775, 0x32ba9cfc, 0xe615f640,
- 0x9d1f20ef, 0x94de3d2f, 0xfd378f44, 0x2eb1e8e3, 0x59321f31, 0xe3f4363f,
- 0x3d1fa8cb, 0xe50f3d16, 0xf59b7cc1, 0xfc49ea2f, 0x679fd21b, 0xe3ff92b3,
- 0xdd3f1ff0, 0xdd18f948, 0xb227d92a, 0xb05ac3bf, 0xc3a3ed18, 0x617d796f,
- 0xd3fef865, 0xb5e5fd85, 0x59fa30b1, 0xda40bee4, 0x78f2c997, 0x03cf98b9,
- 0x8cdffe99, 0x3ce21bf8, 0x20dc7fd2, 0x3e45b1de, 0x6eef76e5, 0xc7fdc7c5,
- 0x6e4fe49d, 0x85cf343e, 0x220fe2fe, 0xfcdc7fdc, 0x8ff93974, 0x8a5e4497,
- 0xeb193e62, 0x1fb85c56, 0xddfbb259, 0x9003cc34, 0xe7d85efb, 0xf9499fde,
- 0xeffdc635, 0x69939107, 0x70003798, 0xa7708fbf, 0xa416e27a, 0xffd866fb,
- 0xb360de61, 0xfd863f16, 0xd9187b36, 0xc65d9505, 0xef8ca0fd, 0x48580b6e,
- 0x56eb6eee, 0xb3af2822, 0x3ca2c12c, 0xcf2c6bd4, 0x80753a75, 0xfe9922cf,
- 0x077e9017, 0x5dfeeae2, 0xa7fe9758, 0x44e9ad9e, 0xe6663dbf, 0xdb3ca177,
- 0x4cf214ea, 0xdbf6f923, 0x7591dd87, 0x6fc37609, 0x584edc23, 0x34c1f322,
- 0xbd60d516, 0x1ff1cd16, 0x7946f5c7, 0xf7924d1f, 0xaf197589, 0x494585bf,
- 0x9eb1352f, 0xc4b0bcfe, 0xf9e392f7, 0xf4370718, 0x75ca5ac3, 0xe4dd93f4,
- 0xab9c51f0, 0x6356cfeb, 0x9bef987b, 0x55961f81, 0x5cafd00c, 0xcdbf4907,
- 0x6a1d1fc2, 0xe90ab138, 0xb8a5d437, 0xe8dd7f70, 0x08dbf4e3, 0x9bcc2ffb,
- 0xd677e64d, 0x1d13cc69, 0xdd7fff8e, 0xff9c77cf, 0x9cac3d7f, 0x5bf8c7fa,
- 0x3f97efdf, 0xfce5ef9c, 0x7fbeffa5, 0xe70add9e, 0x2579a4cb, 0xfd935bef,
- 0x79df72ee, 0x8bf0f2be, 0xf17c7c24, 0x70c7c60f, 0x6b2530f2, 0x7242fde8,
- 0x96afe35c, 0xf8e0ff87, 0x1e8723c6, 0xa881334a, 0xf6145258, 0x6fcebb72,
- 0x50cf1788, 0x371e7e1d, 0x453e7955, 0x9f5ddc72, 0x9ceee221, 0x5a7a5f9f,
- 0x126af5a5, 0x43a6e1f1, 0xdabe1f4e, 0xf14c58e0, 0xe9f8e4d9, 0x067fb652,
- 0x1c72512e, 0xb8f911b5, 0xa9e3cbf8, 0x3d396517, 0x56749f24, 0xc90a7984,
- 0x392f5a79, 0x4c111d3e, 0x32eaef58, 0x410c08d8, 0xcc2d36d7, 0x4f9e1232,
- 0xf4f6e2cb, 0xc89f224b, 0x05e7e16b, 0xfaa673ee, 0x35e31f71, 0x7ca77cf1,
- 0xd67a604f, 0x02ef9424, 0xc0decf9f, 0x4797804c, 0x4f249dcc, 0x1f0e4dc2,
- 0xc7e93fca, 0x10effd91, 0xa5f38b71, 0x19676ff3, 0xfebfbce9, 0x85fbe24f,
- 0xdaffbe92, 0xc016ddb8, 0x181f818d, 0x186befd1, 0x4c1a2a67, 0x33f5c3b7,
- 0xcb2efd1c, 0x459edc0a, 0xa44ff178, 0x94f3e6fc, 0xf195a92f, 0x622fe893,
- 0xfa3aac07, 0xfce26d37, 0x239f5b0b, 0xaabeebf6, 0xcd979459, 0x73c88fcf,
- 0x8fd9c336, 0x9ff9fb1b, 0xf5fd8fdb, 0xc8fd93bf, 0x9c7681dc, 0x7e69a9e7,
- 0xed5ffbca, 0x5f71f804, 0xc875a8f8, 0xdcf22cf3, 0x5df997c5, 0xcdc3f6f6,
- 0xb0ef6ae9, 0xe563ff70, 0x34ff93e7, 0x34fbf9f9, 0xdf0ea3f4, 0x7be4584f,
- 0x9e22fcc6, 0xf82576c6, 0x9e3143b7, 0x8092f7af, 0x447f3e57, 0x6cf4c5e8,
- 0xa75c51ff, 0x6cdb8f8f, 0x9e4c1d2c, 0x9b172e4a, 0x2f8a0e03, 0xbcf27734,
- 0x8ce5e697, 0xfa3377e4, 0xafd0cb4f, 0xbda18b38, 0xf8233537, 0xf57efc33,
- 0x9ab08edb, 0xd9f77e8e, 0xdebbed0c, 0xa9febce3, 0x6c73f83b, 0xa1ef2d0f,
- 0xecc74678, 0xaaef288f, 0xae9fcfea, 0x7824adaa, 0xb1e08fc9, 0x7cadcf1a,
- 0x0fe3c591, 0xbf43fcb2, 0x5f93f13c, 0x9e06e3ff, 0xf8f21d9f, 0x908fe85d,
- 0x3d54f17e, 0xe6a67e46, 0xab68dc03, 0xd87cf952, 0x9e88f3f7, 0x2b4c0f9a,
- 0xeb29ff47, 0x9da397b4, 0x072bf55b, 0xbe3ef7ed, 0x24f2972b, 0x0fc13dea,
- 0x2b3a3e51, 0x5da35723, 0xa0e3085a, 0xfef1fbbd, 0x6e11cbab, 0xa336ff29,
- 0xdfc61cff, 0xc7fa34ec, 0xd9e78d99, 0x4f9bdd2f, 0x4762cbfb, 0x6fec53f0,
- 0x11c39db3, 0xa3ce23de, 0x3279bf08, 0xcfbe4bff, 0x4e344d56, 0x146db7f6,
- 0x6172972f, 0x6d0599b3, 0xe4f203c5, 0xf22e9678, 0x635e444c, 0xa79e2cf7,
- 0x8f0eea22, 0x81f3bf31, 0x238f2bcc, 0xb4b3c73c, 0xe61f96af, 0x402f9418,
- 0x187e62fd, 0x9c5805c5, 0xe7a92dfc, 0xca3d1db8, 0x727a2165, 0x9c51df02,
- 0xed09e806, 0xb1e34bf9, 0x6b9e78e9, 0x52f44774, 0x73e1f3c4, 0x3693c226,
- 0xd38a35eb, 0xbc7c2ba4, 0x6b3df5e2, 0xc61fa2c7, 0xb865e6f5, 0xabbb7aa4,
- 0x353a511a, 0x4d9f9023, 0x52968cfb, 0xbffaaf1c, 0xf29f3ccc, 0x17f92a50,
- 0x291a0a3a, 0x6df7b29f, 0x4e3ce1ab, 0x77661972, 0xa8e4fe53, 0xbc505fae,
- 0x194079c0, 0x72762f32, 0xd6f083b6, 0xa0cd8e1c, 0x3d4b9b1c, 0x43b56724,
- 0xb538a2bf, 0x094356b6, 0x7eccdac4, 0x0b439e13, 0xefe460af, 0x32e1d31c,
- 0x8a157ae1, 0xc3be98fc, 0xa418987f, 0x0f8c8afd, 0x937e7844, 0xee1567b9,
- 0x3d15b4c3, 0x3d718797, 0xcd4db80e, 0xbc5fd865, 0x872dfc99, 0x4fd21952,
- 0xddf15761, 0xb85ea153, 0xb0f145c6, 0x296ee7be, 0xcc2aff24, 0xf310cc73,
- 0xf336ca2c, 0x9aa50ffe, 0x9b699f50, 0xd5470f98, 0x04d559dc, 0x875083f7,
- 0x3c8a467e, 0x453f1955, 0xa9ea143f, 0xd7e0ecf4, 0xffb63f30, 0x14b2d21c,
- 0xe3490e7e, 0xb2e712fe, 0xf3c71fb7, 0xfc2c3b3d, 0xc391e79c, 0xdf936613,
- 0xe0a6ad6f, 0xe6ee7c3a, 0x663794f9, 0x42e70c9b, 0x847ff006, 0x1d4756f2,
- 0x6bd705fa, 0xaff61630, 0x68bd3999, 0xd13b3d6b, 0x2d38b8bf, 0x97ba7948,
- 0x8a5545b5, 0x3d4eb99f, 0xec27ab50, 0x3d70b673, 0xef8fbcd3, 0x35f793cb,
- 0x6e5fa65f, 0x2dda36cb, 0x927ff5fd, 0xfe83f2dd, 0xfdc6fff1, 0xf3ee330a,
- 0xe497ed92, 0x3b20dd7d, 0xe1bfa93c, 0x8f9918ec, 0x0e303d52, 0xd29da7b7,
- 0xf21b0a4e, 0xe21daa75, 0xd8cda17c, 0x5c23e5ff, 0xbf995f34, 0x5f52b593,
- 0xf1fa7981, 0xd7f2301f, 0x70a23cc9, 0x09f7cf35, 0xee746c9b, 0x29dacbd0,
- 0x8b24687f, 0xd3f90a2a, 0x6d7ce87a, 0xc111e636, 0x47b2eb77, 0x99dbbf51,
- 0xf24a8d6f, 0x6e105752, 0x509fe63b, 0xeb646abe, 0x3ae71c22, 0xc7638d07,
- 0x308b93fc, 0x15bfc085, 0x06f4ebe5, 0x05c85f1e, 0x9bf48c7d, 0xa1d39a3b,
- 0xa1e78ebd, 0x99133cc8, 0x50f12217, 0x3b9bf02d, 0xca115176, 0xf04ab5c1,
- 0x99ae7151, 0x4e0dffcb, 0xec195e71, 0x79c0cf6b, 0xfbc63ee4, 0xf898370f,
- 0xaf376479, 0xf9d18c77, 0xf82fa079, 0x728ebb39, 0x2832779e, 0xaf09253f,
- 0xc9e53f32, 0xe411e0b4, 0xcbf3e497, 0xd6124e92, 0x6f47ce8f, 0xfaedc43b,
- 0xcd0b06ea, 0x35c96fa3, 0x5bec97e4, 0xffa86262, 0x9cadbbab, 0xdbc692ee,
- 0x51616756, 0xd88b57ec, 0xf5ca7e51, 0x16bb32ff, 0xfd14b5d6, 0x6b5a47be,
- 0x38053a2f, 0xa01ada3e, 0x74aecfb2, 0xf9d217aa, 0xa928b9d2, 0xf9f2d89e,
- 0xe60e5ab5, 0x140bc4db, 0xb7e79920, 0xea93347e, 0xb077f199, 0xcf16eafe,
- 0xc39034d7, 0x3be2637d, 0xffff7814, 0xdbc47f79, 0x19731691, 0x87a1f77b,
- 0x5f1d8666, 0x91fddf41, 0x9c71e725, 0xc4d3bd41, 0xc8c5567a, 0x5df4245f,
- 0x5e879725, 0x25ec8587, 0x653fc8af, 0x151f2235, 0x5f503b23, 0x714e5399,
- 0x0fd3077b, 0x8f3db0c4, 0x7682cf9f, 0x6395ffa2, 0x26da7fb8, 0x49e582e8,
- 0x184f54bf, 0x22cadbe5, 0x2fdf7d37, 0x23580f8f, 0xc7c63fdc, 0x0be9e37f,
- 0xf325be28, 0xe573196a, 0xf280b9cf, 0xfbf50c6c, 0xa61ce2ec, 0x73c7cae6,
- 0xc2cd2bec, 0x36f515ee, 0x8bc53067, 0x043e44f3, 0x2b8dee7b, 0x7c865bbf,
- 0xf7e0e674, 0xbb5ca347, 0x82fb02ca, 0xeed8e421, 0xfac72e1c, 0x0a358ecc,
- 0x0ce3577c, 0xfac2f08e, 0x773a95bf, 0xa8291e06, 0x82cd311b, 0xf8581747,
- 0x9af11551, 0x3dc4e829, 0xaee7c387, 0x77982809, 0xc7ced2ba, 0x7e6a0ccd,
- 0x9c10f73a, 0x70075ca3, 0xbcb854af, 0xc9d28f86, 0xd3d52a8e, 0xa3611cf1,
- 0x0aaad738, 0xe74971b9, 0xf5ed1526, 0x35beb79f, 0xe006d355, 0x878885fb,
- 0x78c8a2ff, 0xcbdca23e, 0xce5962ed, 0x900bf556, 0xf0ad56fe, 0x12f336bc,
- 0xf8e9ce7c, 0x9565b4ca, 0x557da798, 0xfa254b6a, 0x4f3d0769, 0x0965e787,
- 0xaf7f2b75, 0xc02f16d1, 0xed0be673, 0x8f8849c1, 0x7bbde7cf, 0x3b87ca27,
- 0x0778df73, 0x30de24f3, 0xaf91390b, 0x98eef588, 0x79eb069e, 0xf22dd8ac,
- 0x0f446c3c, 0x3f72c6c7, 0xdb1e7f64, 0xfaf28538, 0xe7e1ce66, 0xb165af49,
- 0x9ef81eb6, 0x3ed0159c, 0xd9117263, 0xde453391, 0x02b78cc5, 0x9817e869,
- 0x435c4371, 0x5d9c3a39, 0xacd79574, 0xc3f024f7, 0x7eb1bad5, 0xfeb1a96d,
- 0xfeb19f35, 0x1a7fc98d, 0xd97f589b, 0xf48d9fee, 0xf3c2bcf4, 0x3097c33e,
- 0x47bdd117, 0x32fda309, 0x715c99e1, 0x27e7970e, 0x77d8abfe, 0x5199333d,
- 0xdb3ed67b, 0x20373c2e, 0x68aad7fd, 0xb665e09f, 0xef7e0cc2, 0xb8bbea03,
- 0x3d1cf222, 0x0761d314, 0x3f71756f, 0x816bbc2e, 0xd3ce0e7e, 0x46aa3f89,
- 0x4e9052da, 0x76261cb2, 0xa552f239, 0x239aec8d, 0xb9e4ee82, 0x058d2aea,
- 0x8602cf30, 0x1be5839c, 0xe88bd766, 0xc87f0ea7, 0x69dbe718, 0x8a5be51a,
- 0x415b1831, 0x5d0487f5, 0xfff2911f, 0x57589a07, 0xef1840e0, 0x1e5cfaec,
- 0x74652e87, 0x656cfe5e, 0xdd25d509, 0xae01fe4b, 0x41a18d1e, 0xe927f445,
- 0x0b4ea7f9, 0xbf7a83d1, 0x34bbf849, 0xea590213, 0xb8807092, 0xc93d42c9,
- 0x7195fec8, 0x6c9b7cba, 0x7ef8fcd7, 0x7e75930e, 0xd44b2bde, 0xaa6a29a1,
- 0xf2fcfd40, 0x3b7f48ef, 0x879c417c, 0xe746cd25, 0xa3e38693, 0x767f825d,
- 0x4b91f125, 0xe8f89abb, 0x3b92cea7, 0x9c6bee08, 0xa5afd42e, 0x0cba9730,
- 0x2a23fd2a, 0x4fce3bf0, 0x474f8a6a, 0xed66f9be, 0x825aa9f1, 0x9bef869c,
- 0xc6a9f7f8, 0x7df0bdef, 0x69f7c246, 0xe0d97df0, 0x6d3b77ef, 0xec44d351,
- 0x21ef4aa7, 0xc9a5187d, 0xade6235e, 0xaeeff166, 0xa3b17911, 0xd47de0d3,
- 0x3cc6a55b, 0x67d93613, 0xa4e4fca3, 0x94ab92bc, 0x57c839e5, 0xba9adb57,
- 0x97bfa07b, 0x655e3ac5, 0x82e67e0a, 0x2dcf2fe7, 0x57fc8a39, 0x98688b6b,
- 0x8b2d77d7, 0xedc5c2ae, 0xc47c169b, 0xe1f24c5d, 0x6693e459, 0x03363835,
- 0xedcc67ea, 0x222d6fa3, 0x9bce79fe, 0x495e1839, 0xa45e1227, 0x493fa417,
- 0xf770c92f, 0x3bd7e7af, 0x3b6f1129, 0x4a5851d8, 0x16b18abb, 0xe7ad779e,
- 0x880bcc0f, 0x65ad8668, 0x2f35da34, 0xdc93092f, 0x00fdcab8, 0x9cbd65e5,
- 0x944ffc1b, 0x7e177567, 0xcbe1a052, 0x716379de, 0xc6f000df, 0x95e137fe,
- 0xbca0e3f6, 0x862d0fe3, 0xf8e1e3bc, 0x421b8e4c, 0xfcc550bb, 0x47949de4,
- 0xf0e39a1c, 0x109179e1, 0x5256c1e6, 0xc2ec8afc, 0x6f6e14e7, 0xb09b1587,
- 0x3f37cee3, 0xaf7b7199, 0x33dedfa9, 0x9477d7e4, 0x6e3bb873, 0x35fde5d5,
- 0xc79c5edc, 0x4b393db8, 0x51742fb4, 0xefc3ccbb, 0x86fdc9d8, 0xd58f4f1d,
- 0x03b05fb1, 0xe9607ec9, 0x322ccec2, 0x7f839bde, 0xde40d64a, 0xb73366f8,
- 0x7c99b75f, 0x62e79455, 0x9ce2f7e1, 0x318cfe91, 0xff64fc7c, 0x628e6e62,
- 0xd7f74f88, 0xc5fe4eff, 0x3f307752, 0x585bfa07, 0x4c502fe6, 0x33f71708,
- 0x1c3e7d02, 0xd6fe9863, 0xfeed1a32, 0x9bcb59ab, 0xcfa262a6, 0xcfa41ce2,
- 0xc59f4009, 0x9d1cfa06, 0x24e5c993, 0xb3e925c2, 0x934b2e9f, 0x1782caf3,
- 0xee1d3f60, 0xa3355fce, 0xf56ddcbd, 0x9e5abcf1, 0x072c9827, 0xa059e012,
- 0xaa3c7871, 0xc24cf04a, 0x39e19371, 0xa4493e1f, 0xf9c66ccf, 0xc97e3861,
- 0x59d858d6, 0x2f2fc031, 0x083583db, 0xacdf3f7f, 0x41a3fbe2, 0xa20eab70,
- 0xe46febaf, 0x2a509471, 0x4f1847d7, 0x67f181c9, 0x5faff189, 0xfaf0e9cb,
- 0xdd10b17f, 0x8451f802, 0x9f68b67f, 0x7944ddd5, 0xcc6bb354, 0x00ed1227,
- 0x13a9b719, 0x94f1cdef, 0xe605919b, 0x4bc634cc, 0xf1e26eea, 0x8b58eb9a,
- 0x7ebde119, 0x3a9fb18e, 0xcc13feb6, 0xc9bbab0b, 0xd3983cf8, 0x8b19671f,
- 0xc2a39671, 0xfc07d08f, 0xd3f4fc82, 0xdf0fc5cc, 0xf63bf40a, 0xe8156587,
- 0x6b32ba77, 0x504deec9, 0xf1b6f1ff, 0xd669ff54, 0x06f3bfb7, 0xa128efb6,
- 0xb9260d7a, 0xf9083ee1, 0xd54df511, 0xc114d78d, 0xa2ed47b8, 0x39f95bdf,
- 0xb04a6f02, 0xe7bc1663, 0xf28a389d, 0xbc846b21, 0xdbc85be9, 0xc9d0bdaf,
- 0xd66f5e53, 0x9358dfc9, 0x79f5efc2, 0x2bbffcad, 0x66b73f30, 0x3c57a894,
- 0x47eb1e3f, 0x1ee84f95, 0x8726de80, 0xce6ff886, 0x09da7ee5, 0x1c744aa5,
- 0x4326a5e0, 0xe7c4dff4, 0xd1e2b335, 0x9a8fe45c, 0x04cfde6a, 0xc5b5b4df,
- 0x2ce99ef8, 0x6d737bd5, 0x250f2869, 0x70e7b59f, 0xa9ed2cfd, 0x67fbe080,
- 0x8db6effc, 0x36037e80, 0x0c5387c5, 0xdf977e4c, 0xe7e0e55f, 0x22fe02cb,
- 0xd3bcfd0d, 0xb37f3cfd, 0x0722b6da, 0x0f5fe7f7, 0x5e712a5a, 0x51f95b2e,
- 0x27d26fb4, 0xf9449b4f, 0x466636be, 0xdf74073d, 0xf1787c41, 0x48690527,
- 0xdd230e6c, 0x259aba4b, 0x48c6bde9, 0xdbafc0d7, 0x5cbf3272, 0xdae81b5e,
- 0xc3d7403e, 0xd700b9d9, 0xa9ae098f, 0x3fd5fd46, 0x265f124e, 0xbc9c3b8f,
- 0x7944bfc0, 0x275f003a, 0x661e5ff1, 0x7f2315c5, 0xecfe4bb6, 0xa62c3842,
- 0x29b39d18, 0xe9e37c54, 0x7630ea60, 0x1f2f8486, 0x8315ae7d, 0x4d3fc2e1,
- 0xcffc7fda, 0x3cf2fb83, 0xf9df0ed1, 0x5c00c659, 0x242bfe30, 0x7871570f,
- 0x5c2d2bb6, 0x5c7b08be, 0xe59be7ee, 0xf38cbb7c, 0xe7e14aad, 0x77e8bdde,
- 0xf97bdf21, 0xcfb87ef8, 0x7ce41d63, 0xcf6f4242, 0x169c05b1, 0xee75db98,
- 0x1b9fa27a, 0xb469f858, 0x8339968f, 0x74f117ff, 0x843e14c4, 0xcc859cfb,
- 0xa057f14f, 0x1272778f, 0x6f090dec, 0x879a9e32, 0xf3c9a791, 0xc0cfc649,
- 0xbec8c5ba, 0xfad8e793, 0xf39e7be7, 0xc7897694, 0x6577f462, 0x8654ff08,
- 0x452147f0, 0xc99e7ea1, 0x2fb87c52, 0xc853ee98, 0x6cc998be, 0xd6679724,
- 0xe19e7d72, 0xd487f6e0, 0xc7f1c3fb, 0x92339715, 0x991b3357, 0xe7c73738,
- 0xd9874c95, 0x2c0ee7ac, 0xadf4da67, 0xd1ef900b, 0xe007d14e, 0x7ee0e99f,
- 0x215cecec, 0x24cf583f, 0xf5fdf3d4, 0x67be7a41, 0xe49fca12, 0x9e66c9fb,
- 0x8cd2fee3, 0x99ca8c73, 0xa12777be, 0xeda8cf9e, 0xcc728499, 0x737bf2e9,
- 0x1fdc0d27, 0xd1c78c98, 0x871926b9, 0x4cfa2f3b, 0x3f191fe6, 0xc706736b,
- 0xcfd238e2, 0x55894671, 0x1e154be1, 0x583fe897, 0x76ec7484, 0xff434d15,
- 0xe81b1cc5, 0xcbba1823, 0x1730bc15, 0x008fede9, 0xf10e6e0f, 0x75e3c055,
- 0x347bc135, 0xe1e12c3e, 0x2b878136, 0xfb3d5e85, 0x89f14ab0, 0x43e97f1a,
- 0xbd084218, 0xe2116662, 0x45e93f57, 0x59d8bf79, 0xf8a2a030, 0xb24e63fe,
- 0x5abf1633, 0xb195f14f, 0x4f4c4c5b, 0x22e393d0, 0x327b8629, 0x30cbec26,
- 0xcce82fd4, 0x617fbc35, 0x7b4328d7, 0xa1bc7479, 0x2a57a2fd, 0xb149f50c,
- 0x2ff78629, 0x50daab7e, 0x1ae7a4bf, 0x3f53fbc3, 0x83a86d98, 0xde70d0c6,
- 0xd8559f7b, 0x65f79836, 0xbe196ff1, 0x19b6cdff, 0xf3bc60af, 0xb2f7d8a4,
- 0x0a563fb0, 0xe9205878, 0x637cdcf6, 0xaa25517f, 0xf3df2154, 0x79eb05bf,
- 0xc034f6be, 0x0bbf625c, 0xc4f68ddb, 0x7ac62de2, 0x55a6f743, 0xe7071b28,
- 0xe354b479, 0x79c93955, 0x79ae351e, 0x50cfa426, 0xe317d82e, 0x62ec1110,
- 0x8e1b33cc, 0xfd6cbfcf, 0x2fe8d84b, 0xfefe7f5b, 0xf5d90b16, 0xaa7d5f8b,
- 0xac8f0a2a, 0xdbfae35e, 0xa7fae375, 0xdfd71a96, 0x7fae33e9, 0xfae364fa,
- 0xf5c6fdbb, 0x5c6b511f, 0x7180ccff, 0x8cebb3fd, 0x34139feb, 0x06c8ffae,
- 0xb7e7fae3, 0x70bbd718, 0x8b3d7199, 0xed0d4bc2, 0xe52febc9, 0xdb9af165,
- 0x7a01ef8c, 0x2074094d, 0xa04168e9, 0xc677f281, 0x30cf7fb4, 0xc03d324e,
- 0xf744d1be, 0x6e3ec1bf, 0xf4fe729b, 0xfc8ad201, 0xf1f4c9bd, 0xeec2b96f,
- 0xfa017414, 0x0ae513a8, 0x614f17d8, 0xd8563759, 0xeda181fb, 0x12bf290b,
- 0xbee279f5, 0x36b93878, 0x7d894f48, 0x0a7ab0f2, 0x81f6c9f7, 0xf470f27d,
- 0x8fb31c7b, 0x4f5a8ec8, 0x5d1ba57e, 0xf14f8e1c, 0xcfe825d1, 0xf2f4827d,
- 0x32700071, 0xe71c7bc0, 0x4f1fe303, 0x8dfe4099, 0xd928b36f, 0x1982ffed,
- 0xcdd83096, 0xe2ada898, 0x953a4f3d, 0x2f6f42f5, 0x858ffe14, 0xb95be0f6,
- 0x9851efdc, 0xc5e6e385, 0x7b14bce8, 0xdd79c46d, 0xe3027123, 0x4f782008,
- 0xca011c61, 0x9ba73b5e, 0xf8ae52d3, 0xc049ee99, 0x4ae9fce7, 0x6ab5d929,
- 0xcd3de50a, 0xfd2141bf, 0x787fff34, 0x2cfa1719, 0x4cb95cb9, 0xd85db3e2,
- 0x482edc03, 0x149ac3c7, 0x07416277, 0xc2e7cde1, 0xb8fe8675, 0xfc47ff1f,
- 0x0ae3cd7c, 0xd06726d3, 0x675a3331, 0x0f3c6f5c, 0x9c38daa5, 0x0d999b8f,
- 0x058139f1, 0x57bc0ec9, 0xfbc6d103, 0x7bfbcf1b, 0xd3fa1463, 0x7cfff554,
- 0xcfe306ad, 0x9ffa2e38, 0xfe863e1d, 0x63ebd566, 0xf41abfe8, 0xba14c0fc,
- 0xcebfa324, 0x87f87bf8, 0xc27e9178, 0xbb2f413c, 0xbdfb8c9d, 0x2386fc92,
- 0x98c09055, 0xe7e663bf, 0x16dabdc3, 0xe63c9fbe, 0x984d635b, 0x37666337,
- 0x32fbe79e, 0x6df3087b, 0xc7e4274f, 0x790cbac3, 0x3cb4e98f, 0xb657efae,
- 0x71865c36, 0x07115ea2, 0x7835a7bb, 0xaab7ae19, 0x0e2f28f9, 0x277257ef,
- 0x40f16f7c, 0x6a9f027b, 0xdd43068e, 0x5e1008ec, 0x10b6b556, 0x3dc598dd,
- 0x6ef3ab50, 0xfc130573, 0x148e1712, 0xcc2d86f6, 0x984c595c, 0xc1f7f0c6,
- 0x55f38674, 0xc4e9da5d, 0x0bd5a87d, 0x2bca25fd, 0xfa2590ad, 0xb6b4d7ad,
- 0x94abdc10, 0xb33b1060, 0x3b51668e, 0xe1aadbe0, 0xbe785459, 0x67922af5,
- 0x3e6de716, 0x3867f7bc, 0xdabd59fc, 0xc87289e7, 0x8728d23f, 0x5db56fee,
- 0xd95af88e, 0x93c68cba, 0x756f6b78, 0x8df58e5d, 0xbed15ead, 0xb54dda82,
- 0x71f482ba, 0x8621681a, 0xc7ad1671, 0xb03d7189, 0x03c61933, 0x045b5ecd,
- 0xe1eac899, 0x05a3b2f0, 0x5d731f44, 0x8df4061c, 0xbc7d03e5, 0xfb4cccb3,
- 0x1df3dbd3, 0xafedfef4, 0x0fd1798f, 0x1e01607c, 0xf98aff51, 0xf0238ff4,
- 0x88721167, 0xf200c169, 0x23572595, 0x6b86747f, 0xdfe3ad36, 0xbbc49fda,
- 0x1f28cec5, 0x20ef92d4, 0xe17cebbb, 0xf7148d0c, 0x27bc0950, 0x44f00fe3,
- 0x8176f472, 0xe2efdba7, 0xefdbbe7e, 0xcec79460, 0xd55fc196, 0x148d5d00,
- 0x059b25f2, 0x056f6ca8, 0xeb8252c1, 0x0b416365, 0x49d675e8, 0xbfd1db2f,
- 0xcd7eed83, 0x4deaa18d, 0x58599e35, 0xaa7c9c6e, 0xbef1d91d, 0x618b3f4b,
- 0xc474be89, 0x4581ab97, 0xc51fccf0, 0x1d783d8e, 0x89a7af35, 0x5e3ab4f6,
- 0xe9ed174f, 0xf7cf5e01, 0x20d4a93f, 0x97f14960, 0xd5c6477c, 0x2dbe51a3,
- 0xb27cfc60, 0x3b60e7b8, 0x91c2f213, 0xdb06ab31, 0xbe74626f, 0x50ffb640,
- 0x4e38e7b4, 0x394629ac, 0xfdf8c73c, 0x6c878156, 0xe9f689c7, 0xb6319f14,
- 0xa64af8cb, 0xf42bece3, 0xfdb1997d, 0xd3bdf141, 0x1d363671, 0xc71b47db,
- 0x53da20df, 0x08ef3c1d, 0x473f21c4, 0x15efda2f, 0xc76c76ed, 0xed8d4bf1,
- 0x2bf8c56b, 0x43ad0095, 0xf8899f3f, 0x9d568ee4, 0xf67cc9ea, 0x7e0cc8ea,
- 0x99f0598e, 0xf21b196b, 0x23abfcdc, 0x9a4cbe79, 0x0ff7e3de, 0x7b650f21,
- 0xb8a34b86, 0x10b5eaaf, 0x421d591d, 0xec3e088e, 0x8b4a2397, 0xf717138f,
- 0x3d197f97, 0x8e7ee103, 0xfe00acf2, 0xbef39e90, 0x04c16263, 0x98db9679,
- 0xef0982c2, 0x1864177b, 0xe53759ea, 0xccf7de1a, 0x77686519, 0xb4378e54,
- 0xf13e58b3, 0xae826dc7, 0x0c2aca52, 0x02bef2ed, 0x923e73a6, 0xf479b576,
- 0x677bc314, 0xa474f54b, 0xcb57d3ed, 0x367cabfb, 0x39b70b94, 0x1f236547,
- 0x3275a4fe, 0xef20df1a, 0x8974a26c, 0xc9474bd2, 0xa2eab656, 0xc7f54a5e,
- 0x7aaf3cdc, 0xd78fab65, 0x6f9d188b, 0x4b5ad95e, 0x2f81c7f5, 0x56d7fcb1,
- 0xa07b953f, 0xfb0e160e, 0x43aff411, 0x7fa13b3f, 0xfd023fac, 0xfa1db963,
- 0xd087f2c7, 0x856fb63f, 0x10feb17e, 0x83e585c0, 0x7f3e0fd0, 0xfac7fa00,
- 0xd500d6a6, 0xa3ad6bef, 0x20d686fa, 0x36b6f795, 0xadb5f3d0, 0xdd5f542d,
- 0x7bca8cba, 0xae54c35a, 0xed435d6c, 0x1f37a116, 0x1f1fe713, 0x7dcfc69b,
- 0x467faf27, 0xeed5f29e, 0x4504a8bb, 0x93c8655e, 0x7dc3c8c8, 0x2f31a775,
- 0x7047f110, 0x931e39d8, 0xe02b18e1, 0x2b62cf18, 0xa0dcb952, 0x2e98eb38,
- 0xc0a9dddf, 0xf85b23a7, 0xc57517ba, 0x81a73da9, 0xcc56378f, 0x2cc27993,
- 0xef1f8aaf, 0x957af7c5, 0x8f2a7558, 0x831f9337, 0x553f0179, 0x9133dce2,
- 0x7084c479, 0x7f419369, 0x1fb3cc27, 0x270e6e5f, 0x78286de2, 0x7c78f22b,
- 0xe4ecad43, 0xb6d49bf7, 0x52cd9147, 0xbf742dfc, 0x102ead89, 0x04f4a0d5,
- 0xc24f7482, 0x603373f8, 0xed720593, 0x874ce5dc, 0xb8d1af32, 0x505dcaff,
- 0xa8e7d861, 0xfd3236e7, 0xccb7e822, 0x194a4fb8, 0x3be19b7d, 0x0cf7de5b,
- 0xddcf16ed, 0xb7f9f686, 0x22f2ad14, 0x8a32473e, 0xafd7593b, 0xd7003960,
- 0x044d8ec2, 0xbde05057, 0xfdf9d157, 0xefc5fbed, 0xfffb0844, 0x2f812ec7,
- 0xd7da7adb, 0x6af3758e, 0x84d87a49, 0xa7e3e7fa, 0xee8e49d2, 0xfe44c47d,
- 0x622c71ed, 0x01337942, 0xbf6c48cc, 0x56726f00, 0x151ccae9, 0x574ce5eb,
- 0x8b117eb1, 0xec08bed3, 0x17a43aff, 0xb11fffb0, 0x7e4cfd43, 0xbf3cc7f0,
- 0xba7a4a2b, 0x8967ac44, 0xd16d07dc, 0x73c3fd92, 0x635fc8f3, 0x26d6073c,
- 0xdc2b01f6, 0xef18d955, 0xff261ded, 0xd6fde9ce, 0x1eb005d4, 0x2a3a9cce,
- 0xba0df3e5, 0xd173c869, 0xbf2abecb, 0x623d016c, 0x086597e4, 0x9fca99ff,
- 0xaabba167, 0xf89c7479, 0xe52ccda6, 0x728e9e98, 0x4beea06c, 0x3ba2bb27,
- 0x89a3f087, 0x1adbd9f5, 0x3900fca4, 0xd377ed4f, 0x560f985c, 0xf74ff222,
- 0xb53adeb5, 0x661f2126, 0x52dfa0b7, 0x3d45ab16, 0xf2665a5a, 0xaf27a845,
- 0x1f617fc1, 0x73c7eedd, 0xf3055afa, 0xc71e18a1, 0xbabce9da, 0x794a85f6,
- 0x4b91da40, 0xb0760e98, 0xe16511c3, 0x997e81b2, 0x477c83f0, 0x5ccff5c8,
- 0xad0f3435, 0x3e47da40, 0x33ecddd4, 0x74863f87, 0x998759f7, 0x6309e5b3,
- 0x9183a97b, 0x6a545b9e, 0xa60ae889, 0x3dd3b423, 0x850eda8b, 0x1c2115e5,
- 0x50f3bdd3, 0x254c1f8f, 0x52dd4dba, 0x7bc35745, 0x79f5c14c, 0x1e99c700,
- 0x1a49a0fd, 0xd35ef057, 0xb42ecb04, 0x5e22c71b, 0xa5d19c70, 0x6285c784,
- 0x575afbbe, 0x159e9e10, 0xefcb68f3, 0x87873bc7, 0xcf78fcf9, 0xe90ea2e9,
- 0x73ce31bf, 0x37f56543, 0x95c6def0, 0x74d85531, 0x33ae7c46, 0x53ce26c7,
- 0x3802e006, 0x5538459f, 0xbffc9b84, 0x8f4d7e7c, 0xc819bf70, 0xbb8a5ab1,
- 0xc4b1324e, 0xa32cabb8, 0xc8cdfe42, 0x4ebc1173, 0x0ba9dcef, 0xdfac4a2e,
- 0xb8fd7444, 0x761fe7c2, 0xcd2f3c6a, 0xfd13d7ef, 0x7ee4ebc4, 0x487f9c59,
- 0xdff6f011, 0xe79e36e3, 0x6c583a61, 0x0d2de60b, 0x25fe1fb7, 0xc4a4ca2e,
- 0x18e830fd, 0x649d5718, 0x759f3ca3, 0x7f4b8f32, 0x337cc743, 0x8afcf12c,
- 0x6ae9d04d, 0xe4af31a7, 0x77b71e5c, 0xe8f589ce, 0xc6be71b3, 0x567964b8,
- 0xdd17bdc2, 0x91ffe4f5, 0x6ebecc71, 0xfd2e0f9e, 0x09044b6b, 0x78e51df4,
- 0xa5587be8, 0xee92e5f8, 0xa17df96b, 0x7ba01e87, 0x1d2fa156, 0xbc5ea1e9,
- 0xe8c6bf5f, 0x3bb059ef, 0x1f452ab0, 0xc45a57ec, 0x48d7e4c2, 0xfb2527f6,
- 0x279b7e91, 0x563e69f6, 0x93ca718e, 0xa58f8beb, 0x88a67ee0, 0x91dbb9d1,
- 0x8f7493ea, 0xedfb5831, 0x2b294f78, 0x24f4f7e3, 0x0525fbaf, 0x3ef3c216,
- 0x1c63aeb9, 0x37d867e4, 0xbefff389, 0x7d7ecf17, 0x96f3f40c, 0x81ce18ae,
- 0x099ba5bc, 0xae81e38f, 0xac64ecb1, 0xa0fba876, 0x5f4df3b2, 0xa5c0bced,
- 0x68d7dfc6, 0x9639eaea, 0xcbbc93aa, 0xfa7807ca, 0xad3efd8e, 0x4e27f88c,
- 0x575107bf, 0xb841e1c4, 0x7ecbfcf1, 0x137327d3, 0xbe7c60e9, 0x7c83edc6,
- 0xbf9357d3, 0xceb84635, 0x7599bd94, 0x1c6b870d, 0x3d1bd5c2, 0xb7689591,
- 0x0ff6b848, 0xa5fabf73, 0x934f155f, 0x0120fa8d, 0x12ff534f, 0x865bf69e,
- 0xc0966786, 0xf28e4fcf, 0xb70642fb, 0xd5fd457f, 0xccf78461, 0x51ebb163,
- 0xb3bc023c, 0x53de7f08, 0x15331459, 0x14acebf8, 0xe42959f4, 0xa8ce8f8e,
- 0x17dbd0b0, 0xa75e7e53, 0x7743dbc6, 0x79e08a2e, 0x0b8bdf02, 0xe0dfd10a,
- 0x7ba56e3c, 0x7949429e, 0x2f5cb222, 0x573fb1e6, 0xab0f1219, 0x78bcb9f3,
- 0xd4f9b5f1, 0x596fbddf, 0xed83ca19, 0x5ef5df22, 0xef0da757, 0xc47895ef,
- 0x2194057a, 0x2a117c4b, 0x3f2b7bba, 0x218ee9b3, 0xf1f133c6, 0x1be24bee,
- 0x572c9e39, 0xbb7297e4, 0xe2aa3954, 0x2efb8739, 0xd9ee937d, 0x2352afba,
- 0xe337fb99, 0xfe127d7f, 0x7d666fa3, 0x8acbd39d, 0x2aa3f47c, 0x037da5ef,
- 0xfe2521ea, 0x9fc432b3, 0x0ff34825, 0x3b656dbd, 0x6a78c195, 0xe72bf414,
- 0xe12fe727, 0x80b65e76, 0x7ae099ce, 0xc5abe020, 0xa44f52fb, 0xf387bd0b,
- 0xa9713d22, 0x4c89cfc6, 0xef5d68d2, 0xce853c9b, 0xf917ecf5, 0x2c4bf114,
- 0xc32efe43, 0xf76f0233, 0x0c45fb9e, 0x770da9ef, 0x055ee99b, 0xbf78f5a6,
- 0x7a147409, 0x9a7ba35d, 0xf16a9e81, 0x5f17a8de, 0xfb869b3b, 0x66f903e8,
- 0x3e40fb82, 0xe77d8797, 0x6f3a5ad4, 0x2e67daf3, 0x9ffe8135, 0x5d8557ce,
- 0x39e18b12, 0xfc158d9a, 0xd84380dc, 0x4ed78e01, 0x8efc2035, 0x2ab3dfc9,
- 0x4f767a09, 0xdbbe95be, 0xf9678968, 0x48740e30, 0xdfee5165, 0xfaeffba1,
- 0x38ba0bcf, 0x8f2b9a1e, 0xe8e09d92, 0x3de2f7e6, 0x5c13af9d, 0x7841f708,
- 0x33ee329e, 0x57b63d57, 0x06a378c2, 0xf8ba77be, 0xe24ca67a, 0x77dcd0f7,
- 0x785dcfe9, 0xc2ba5eef, 0x4be8fee8, 0x3906cc0a, 0xd7c45f5e, 0x1632b3a1,
- 0xe5fc851b, 0xb6af28d2, 0x0d9b7a33, 0x17c97aed, 0xf4a947a3, 0x97916add,
- 0x29727abe, 0xe3a499f1, 0x57c105b9, 0x02366e91, 0x76493c5f, 0x9d302c4e,
- 0xc72ae3f0, 0x95c7e3fc, 0x3fb71d58, 0x2fd42e2c, 0x819326a5, 0x380b8adf,
- 0xec12c8dd, 0xee77b252, 0xf52cb410, 0xc6c45b7d, 0xb7ffbf30, 0xa3a566e7,
- 0x2796da5d, 0x0dbf3ced, 0x095db5f1, 0x38e117a4, 0xbed2a5ff, 0x4ed7c5ef,
- 0x6db8e034, 0xdbe42f30, 0x58ea7e7b, 0x9b49f68f, 0x2a7c4fcb, 0x26dcd7c7,
- 0x9fbc1eb1, 0x2bff16fd, 0xbb8c6fe8, 0x47447df9, 0x43635ca6, 0x4cf787fa,
- 0xad7bcfd8, 0xd81a0bf8, 0x07f90d4f, 0xcf66ba16, 0xb116efc0, 0x6bb42ae0,
- 0x86a87517, 0x11ee177b, 0xb9e162f2, 0xd84d1614, 0xfc9c2c1f, 0xb6373a2d,
- 0x8b1a5cf0, 0x8f75bd82, 0x8f7d1738, 0x0ac45738, 0x443b3d38, 0xdfe515e9,
- 0x24bef7cc, 0xcbf995bd, 0xdf39f3bd, 0xb7e802b3, 0x14b1e949, 0xa71b10c1,
- 0xebce9efc, 0x62ead7bc, 0x780492d1, 0x0473cd07, 0xd38c268b, 0x1b39deff,
- 0x7d6067cd, 0xcc0efd39, 0x787841d7, 0x784bd5af, 0x91ffbe1c, 0xf40e3c06,
- 0xc780ca3f, 0xd097fdc1, 0x96b5eff8, 0x13ff497e, 0x375fe986, 0xefd03fc0,
- 0xf7b71a68, 0xa71ffcc8, 0x891ddf02, 0xf9edbdde, 0x331dfc4a, 0x017efd2b,
- 0xa6aceaeb, 0x338f8473, 0xe77a673a, 0x83bddfe1, 0xee779af9, 0x8c70f8b2,
- 0xae7c733e, 0x333d086f, 0x78c2b99a, 0xc72c979f, 0x7cd31417, 0xb4db9f92,
- 0x32f30b88, 0x0b9aa56d, 0xc6d11f7f, 0x71bb9162, 0x236952df, 0x42e32739,
- 0xe53fdfb2, 0x3b3cf2a9, 0x6f7907c9, 0x979112cb, 0x5e08ec57, 0xd4beeb81,
- 0x13fcded4, 0xd283f6f8, 0xcc373a36, 0x33f69b98, 0xe1a36e32, 0xa315bf2f,
- 0xf0c0305f, 0x7a13cdfc, 0xf77e0670, 0x18271043, 0xd82f51c7, 0xb5bcc41d,
- 0xb8df620d, 0xfaf31ec1, 0x0de6e412, 0xb357da05, 0xe893da17, 0xf72fd276,
- 0xdedd3946, 0x227e8050, 0xfcc4f635, 0xedb7cc22, 0xe976f711, 0x55778a16,
- 0xfefba31e, 0xff7dcbe6, 0x8ebce49a, 0xd1da377c, 0x8694ce32, 0x6b687779,
- 0xbef7e46c, 0x7af2a7d5, 0xa08c7ffd, 0xffb01073, 0xf9432d49, 0xfee55fb2,
- 0x3adf1120, 0x67d0e62b, 0xf94058db, 0xe41f22f7, 0x744bf76c, 0x35d9e4af,
- 0xebfd6863, 0xdd3ef85f, 0x973fb70b, 0x43beb1eb, 0xf563d24e, 0xde155f56,
- 0x973fb85b, 0x5a9dabdb, 0xc122ad34, 0x579d5d7e, 0xe3f9f24d, 0x894c6335,
- 0x0aef8ff1, 0xfa51b079, 0x1578b537, 0xb8f9679e, 0xd233fa32, 0xf4ec07a3,
- 0x83a6513b, 0xfba2abbf, 0xe95a372d, 0x0faa0177, 0x875cdb8e, 0x8d34c3fb,
- 0x074d91f2, 0x99cf04ed, 0x2d7efc75, 0x5de516fc, 0xf491c1d3, 0xa9f556fb,
- 0x6c27ca71, 0x6095f14a, 0xe0feafdc, 0xffd7ba54, 0x057186e4, 0x644eff28,
- 0xaf7405ea, 0xf43c06f1, 0x6343f509, 0x17b5f3f9, 0xe75579d3, 0x50e0d4c6,
- 0x8fa9107e, 0xdaefef92, 0xdbde5b9f, 0x6719f885, 0x7dfca1f3, 0xb8f1f14f,
- 0xd9f12bef, 0xf915c53a, 0xd77ad2f9, 0xbc7dfa69, 0x6f778efa, 0x43dcf462,
- 0x73f72b74, 0x0bd5e3c9, 0x12dfb57d, 0x4bbf8b9f, 0xe052bf56, 0x624efc5d,
- 0x7e9ca9bd, 0x7de24faf, 0xb73dd263, 0x24fd084f, 0x69af93cb, 0xd8205f74,
- 0x1fe80511, 0x4ad8793a, 0xe3727674, 0x2eaf3a04, 0x9c07abc7, 0x4f2f80b8,
- 0x7113e864, 0xf2169f5d, 0xdf257eaa, 0x30e7caa7, 0xe77f0c7e, 0xa5487e30,
- 0x573eaebc, 0x92e30d3c, 0xef593df2, 0x4ab74f9f, 0x3fb597bf, 0x6f5a45f7,
- 0xf48627a0, 0x49c17a64, 0x82f43a7a, 0xe7ae1775, 0x8c2c95c7, 0x5bf0cffe,
- 0x8ec7f7fc, 0xfd92b21c, 0xef9c77dc, 0x9fdd076f, 0xe01788e6, 0x17a1a1fd,
- 0xeb1c9246, 0xe0ef8fcb, 0xdf9db6f6, 0xf046f8ab, 0xcdff1162, 0xe611f711,
- 0xf9f79da0, 0xed147b21, 0x9e29283c, 0xbdbb6610, 0x2a70fcf4, 0x940fff43,
- 0xca63cf14, 0xeefd2f01, 0xdf176b0c, 0x3bfbe8c7, 0x5163820b, 0x0c59df2e,
- 0xfbf03bfd, 0xe7def453, 0x521782a3, 0x5cb18a0c, 0xf52e5e31, 0xa42c1f9b,
- 0x5e67cae7, 0xed2a7bfe, 0xed463da2, 0x62f06b21, 0x9cafc79a, 0xf310e76c,
- 0xeef7aafc, 0x41182d1d, 0x06e128eb, 0x98dd933c, 0x05b3978c, 0x3b7bf126,
- 0x74c91f1c, 0x5f9ebfd9, 0x5ffa1f02, 0x21f6bce8, 0xc6eb8ebe, 0x591cb859,
- 0x63ec813b, 0xc86296d6, 0x88715b9f, 0xbbd0c3df, 0xdceb49c1, 0x843ff667,
- 0x86fe28fa, 0xed7bf199, 0x3f4022c0, 0xf9a1e4c5, 0x4f9123e5, 0xcf2d64bf,
- 0xd1e8fbb3, 0x39e60bf7, 0xfbf25cf0, 0xd2c97386, 0xa49d085f, 0xe1c63fa1,
- 0x97e6d3d3, 0x255d7b71, 0x7aeff8f8, 0xf4eb346d, 0x0de16bbb, 0x711fc8e3,
- 0xa41fa2d2, 0x775b87df, 0x4ae90981, 0x77f2172d, 0xbc9f9f13, 0x7bde4b2f,
- 0x8a9f8c95, 0x7f9262c2, 0x33782c4d, 0x827ea1de, 0x61c259e9, 0x91fff746,
- 0x6984df7b, 0xe29f9a88, 0xf485acb6, 0xf67be0c2, 0xbbf25f2c, 0xf5bbff6c,
- 0xf42b5c2a, 0xd38795ef, 0xe07eaf50, 0x3a46fbe2, 0x5d7a8f7d, 0xc36cf3e5,
- 0x83af300f, 0x4e14a605, 0x879276a2, 0x5dbc281f, 0xf341b9ca, 0x7ec17a47,
- 0xebe83df0, 0x7fee429a, 0x710cae63, 0xc16c2bc8, 0x9fa94d3c, 0xc2668a42,
- 0xdca7f373, 0xe3d21a7a, 0x19c5b5a9, 0xc60f302b, 0xda2567ad, 0x8ca3a1d5,
- 0x78eb8bce, 0xf8c5f8df, 0x89fe32fb, 0x9fdbf7e8, 0x243bf461, 0xb4e4f3c3,
- 0xed89b99e, 0x9eb90a73, 0xf6285f9b, 0xe44c8599, 0x8de32657, 0xb162fbaf,
- 0xf0796aee, 0x2687da72, 0x4b78b7bd, 0xa487a0ba, 0x7fcfede7, 0x1ea0f297,
- 0x4913de36, 0xef185fb1, 0x612c5783, 0x532c42e5, 0x61bdaf28, 0x0d739713,
- 0xb92cceaf, 0x5ee9d78b, 0xef3b6985, 0x59e3dfa1, 0x12caebb0, 0xad16e5c6,
- 0x05c7a483, 0xb412fe05, 0x555be2e3, 0xc345f217, 0x51e09516, 0x56d73ecd,
- 0x8b7a7e78, 0x06bbec99, 0xbce9cf01, 0x9bad1a60, 0xe00b34c6, 0x4c16b4fd,
- 0xab75fb23, 0xa4a1ddf8, 0x6f7bc079, 0xe043156a, 0x99d7c6c7, 0x043c53f0,
- 0xa261bc1d, 0xbf805a75, 0xec70890b, 0x79bfc854, 0x33783f3a, 0xfec14fd6,
- 0xabe9cf1f, 0x7dd0969b, 0x3ef8c936, 0x7d120b6d, 0x91f3162e, 0x471e4cf8,
- 0xf10fb3e2, 0x2bd2f689, 0x85ef4853, 0x6291541e, 0x9fdd8bd9, 0xda7cbed2,
- 0x99df2ba1, 0x8137cf8a, 0x9ea3a2dd, 0x6fb3f51d, 0xa35b9ea3, 0xfe7a8c52,
- 0x962ce2a1, 0xff71afa4, 0x39f5ff39, 0x3d04a669, 0xf1c83ea9, 0xa4e73aa4,
- 0xcff7a42d, 0xebe91d7e, 0xaacbee84, 0xf1ef7848, 0x83b8fec2, 0x37eabd61,
- 0xc70d21fd, 0xa66f5869, 0xe975c979, 0x7ca079c3, 0x208d4f6b, 0xc5e5f7fd,
- 0x4eb95fa9, 0xeb8df4fd, 0xde09e920, 0x9742affb, 0xf24c2718, 0xb05154e8,
- 0x9d0437ca, 0xc6007a2c, 0x38b6fec5, 0xf3d2fee9, 0xa3e2571d, 0x5f05bd7f,
- 0x71d71d53, 0xd1f91147, 0x74686f4d, 0xfb44e0c8, 0xc7c80555, 0xd02fa0f5,
- 0xc4af516f, 0x647ba1df, 0x1ee9590f, 0xb74dfae6, 0xd5e38cdc, 0xb09ab71f,
- 0xabe1d4fd, 0x495c1226, 0x2a780aeb, 0xfbde8a18, 0xbe05e28a, 0x3d81fc04,
- 0xe72dfc41, 0xc1370093, 0xba29fb01, 0x08afa88f, 0x0e4133d6, 0xedc859bc,
- 0x65df782e, 0xf7e6fa21, 0xd7cff561, 0x575f3495, 0x64df7cd2, 0x17ccdf44,
- 0x782cf9a4, 0xe7c26adb, 0xb6bfee0b, 0xa73df704, 0x79a74dd6, 0x4ff0ca9d,
- 0x553afe44, 0x210ffd00, 0x0fdc172f, 0x0bfb2cf3, 0xd3b76cf3, 0xcf3b0d7a,
- 0xf60ef88c, 0x89f9e617, 0xcf3943a0, 0x0d3d34f7, 0xcf43f9f3, 0x2efd0caa,
- 0xc6c0fca1, 0xbf4ebca9, 0x73321713, 0x4a6d087a, 0xdedf7ca5, 0x04fbfe6e,
- 0x78c00e52, 0x260f49e7, 0xd55387a2, 0xd0c9e6fa, 0x3f07ffdf, 0x00b71737,
- 0x0000b717, 0x00088b1f, 0x00000000, 0x7dcdff00, 0xd554780b, 0x733effb5,
- 0x64932666, 0x08124c92, 0x3c984081, 0x49849009, 0x768a8802, 0x02d10478,
- 0x89794f0d, 0x42100793, 0x69b5a05e, 0x0240cd6b, 0x350d45a2, 0x01d45a2a,
- 0x0da2a281, 0xbc150a0a, 0x45622a03, 0xb68b57c5, 0x514026e5, 0x5ea0c679,
- 0xffd7b5ae, 0x4e7dadfa, 0x5490ce72, 0x7dfbdedb, 0xdf1f7cff, 0x5afd9f66,
- 0xd7b5ed7b, 0xe7bdaf5e, 0xcbaa3dc2, 0xe4e216ef, 0xff6f05dd, 0xf7a517bc,
- 0xfc812eaa, 0x02cddf58, 0x2cc38ff9, 0x934a14fe, 0xfe70a68b, 0xa56b9b65,
- 0xa689c422, 0xa141fdbf, 0x367d85fc, 0x0bf2a0b7, 0xcef74529, 0xea8f7e46,
- 0x2fed415a, 0x259f680c, 0xd8b97386, 0x5deae544, 0x2e509a23, 0xcae61e1e,
- 0x0df2f2a0, 0x09644261, 0x6856fbfe, 0x3be9237f, 0x6ba50b52, 0x34786f55,
- 0xfd2f4da5, 0x6fa5c944, 0x578f3756, 0xf724abf3, 0xb97e34dd, 0xf9ed5855,
- 0x399edca8, 0xf388472d, 0x03136d7b, 0x233f32d9, 0xb03fcb87, 0x5d8d7952,
- 0x7bf85af8, 0x0e6a7dad, 0xd2b6e28f, 0x0fa98b38, 0xfae94a91, 0xea60ef18,
- 0x938d317f, 0x8b7de342, 0x0e5c1fbf, 0xe7cb0edf, 0x9fa88a0b, 0xf6626d7b,
- 0xf55dd973, 0x4ddb34f4, 0x6d46f61d, 0x553b577b, 0x3cc62588, 0x2422a1e1,
- 0x477914bf, 0xa432be57, 0x7ca42abc, 0xa7cfbf47, 0x1f2f3914, 0x1fc6037f,
- 0x12c785d1, 0x2c3b8f0d, 0x72eb1df4, 0x44d8128f, 0xbab12dff, 0xfe09cbed,
- 0x9b88c6e7, 0x55a94fd1, 0x47cdae38, 0x5f9e0ebd, 0x86345589, 0x87bbe3e5,
- 0xa6f3e9eb, 0xe2c31afe, 0xced11f28, 0x89bd53e3, 0xda9e4376, 0xab9ae09b,
- 0x4ba7a3c1, 0x4ebb85b7, 0x7fa0f3ea, 0xa6b12d55, 0xbeeecd7c, 0x7c0693ae,
- 0xfa7fc52f, 0x3449bfd2, 0x8bc091fb, 0xdddaabfc, 0xe892307a, 0xcdf14da7,
- 0x17bf5375, 0x9d1d7e0e, 0x1f75e6ed, 0x9beb4459, 0x7f3ea6af, 0xbedbe698,
- 0x426cf547, 0xfdd86fbf, 0xe7fd0c4a, 0x6e0f8b9b, 0x2fd5efa7, 0xddbb89a7,
- 0xc50ff35d, 0x17dd85e3, 0xfbe953a3, 0x08f643f9, 0xb9e68c31, 0x9dac7e37,
- 0x5c4762e8, 0xaf78b77b, 0xef5dd6d5, 0x35b5bcef, 0xdea1aa7a, 0x3d1ad179,
- 0x252f40cd, 0x8bd62fbb, 0x5f9fc65c, 0xefc2efcd, 0xc7bd7d89, 0xf4bdf4aa,
- 0x5ac6fdf7, 0xc35fbd28, 0xf736bddb, 0x6e096b13, 0xcf309eff, 0xfcfb8216,
- 0x682db31b, 0x728dfe7f, 0xcbcdbd2d, 0x244f5fe9, 0x8b68fc63, 0xbc7d77a4,
- 0xf70b6e35, 0x7b696a53, 0x8fda1aec, 0x93ebbfa5, 0x55d290d2, 0xcfc96a5e,
- 0xb76f3ac4, 0xdc002fb5, 0x46b115e7, 0xe7eaeb89, 0xdb9bb77e, 0xc9f3df9f,
- 0x270fe063, 0x4f901dee, 0x41f94d64, 0x3f2a3eb9, 0xa64151ff, 0x7f3dfa8b,
- 0xf80f5f4f, 0xfb9b76c2, 0xbbb7a636, 0xf7d83ca2, 0xa7187f7a, 0xb9effd16,
- 0xe90fa462, 0xca5e1247, 0xb8e4fae7, 0xabbf257e, 0xfb8b68df, 0x17e0d1be,
- 0xb679b7bf, 0xeffcb250, 0x31627d69, 0x6ee7ec3f, 0x4d74a1d6, 0xf89b7098,
- 0xbb864ac9, 0x22ec7844, 0x030b964d, 0x228995bd, 0xc9b0befe, 0xf1117dfc,
- 0xbc5f7c09, 0x5cbdfcde, 0xa56ead34, 0x98092df9, 0x3fda0bbf, 0x6bec04fe,
- 0x5ec5affd, 0xff7a0514, 0x4f54cc36, 0x40fe35f8, 0x255f091f, 0xc7c11fb4,
- 0x8102519e, 0xbbdf5895, 0xe8679e54, 0xa775debc, 0x2287bb70, 0xab4167ff,
- 0x5b8f5d61, 0xf0913584, 0x1c2edc7a, 0x47e8f989, 0xf5fa8508, 0x6c0b0bef,
- 0x0f7726a1, 0x04b92afe, 0xc231af7c, 0x5bbe0822, 0x427ce05d, 0x49f7d8ac,
- 0x5d29fa32, 0x356de853, 0xe6c177c0, 0xd4e7e87d, 0xe25dfdbe, 0xf8ef54d7,
- 0x58d340d8, 0xddf8eb82, 0x1ba1a7aa, 0xb1af4eb8, 0xe1014088, 0x02212ee3,
- 0xf27f94f1, 0x5a62e493, 0x7cb6cf97, 0xa4625c92, 0x36cc457f, 0x129ea3d2,
- 0xef3ebc24, 0xfcd2ef61, 0x305cd38e, 0x5d7ad09f, 0x57866beb, 0x2ab867c7,
- 0x87a3bb6a, 0x54f740cf, 0x5577f59e, 0xf7efb178, 0xcfa002d9, 0x3c5f8dc8,
- 0xb9f40f38, 0xa14ae6d7, 0xa9f66bb1, 0x2de6955e, 0x0c81a8f6, 0x4f7b639c,
- 0x9ce05744, 0x52e053d9, 0xd9aef30d, 0x7ce116a3, 0x62fbbf39, 0xf7366942,
- 0x44edc533, 0xa03c07fb, 0xf8e09edf, 0xf7fd5b9b, 0xccd79ff8, 0x7f65ceff,
- 0xf8037090, 0x9953c6c0, 0x07c4efe0, 0x79a6e6ff, 0xc6fccf9e, 0xad10bc8e,
- 0x047f4123, 0xe09bb45f, 0x2af810bc, 0x8e5c105a, 0xd037aabd, 0xa5443acd,
- 0xff4f19d8, 0x09137c32, 0xf82e84be, 0x94a89e08, 0x56705d11, 0x38eddbbb,
- 0xa2382f67, 0x694fc173, 0x12f29342, 0x0dc9f3b4, 0x493a5afe, 0xbf1d7f10,
- 0x70cae167, 0x8a4d0bc8, 0x97be8c27, 0xdcf955ed, 0x191bdb2a, 0x3f1816c0,
- 0xd2f9c9c8, 0x1840d547, 0xa3a827e5, 0xea9b30ff, 0xf547be2f, 0xfb148ed0,
- 0x07f6de37, 0x8375d61b, 0x881ca04d, 0x344b5c03, 0xfdec96b8, 0x8d0a67e1,
- 0x2ddf78b3, 0xe2ce3007, 0x170f1407, 0xe8edf3a8, 0x8a43c977, 0x67405788,
- 0x3a46e3b6, 0xce64d85b, 0x0bad122f, 0xc1fc1554, 0x9ef09dfc, 0x96fd415c,
- 0xdd730eef, 0xa102f18d, 0x4abc42e5, 0xff68d4f0, 0x3b58cacf, 0xcfd500f7,
- 0x3c6768da, 0xe2170f9c, 0xb5abf608, 0x0d204135, 0x1d6326b6, 0x6bf9efcf,
- 0xe6b1d632, 0x2995ff77, 0xcebf59ba, 0xaa37b4fd, 0x2148a9d7, 0xc4514eae,
- 0xfba0a9b7, 0xba8a538b, 0x201b6fa9, 0x9b36c5f7, 0xca879fbf, 0x8afc6c0f,
- 0x3d85c1f9, 0x6eae81be, 0xbf6bb7e8, 0x892dc3fa, 0x02e18348, 0xd716f0e9,
- 0x2427d80d, 0x35be620f, 0xdb4f569b, 0x97f0f944, 0x44b9386c, 0xf793864d,
- 0x42c7f60b, 0x3efabf43, 0x80be06d9, 0x0fe48474, 0x1cf201b6, 0x7b9daa3d,
- 0x4c77f6db, 0x9e06e8c9, 0xd71b6ea3, 0x5c100db3, 0xd17759ef, 0x845bd05c,
- 0xbe0d1fc5, 0x775ebc2d, 0xa2b3c22f, 0x5d4357d1, 0x89ef82ad, 0xfed389a2,
- 0x47d385a2, 0x5139f085, 0xc05c785f, 0x620310b3, 0xf3de3f81, 0xccbecf8c,
- 0xadac7f37, 0xe8357821, 0x022b1fc4, 0xeaffe85b, 0x63508746, 0x46b5ed20,
- 0xce5451a3, 0x5206fbb4, 0xd503edb9, 0x1dde40a2, 0xc7a7afa0, 0xa5f7fd85,
- 0x718c4673, 0x2e1ff6fd, 0xaafe8899, 0x8c22a976, 0xd3b73bfa, 0xd44e8226,
- 0x7c02fda7, 0x9ec2fe1c, 0x57b4be02, 0x6b979011, 0x35ef8f28, 0x80deada3,
- 0xa4772f01, 0xd50f18d8, 0x9cf29929, 0x4d0f7ab6, 0xbbcf7ea2, 0xeb90ec4a,
- 0x26cb876d, 0x25b1bce2, 0xd701d896, 0x1d63c3fe, 0x58b75829, 0xd59bef2b,
- 0x8f71f57b, 0x547fd0b8, 0x6f0c07ec, 0x4445b663, 0xa3c6bb53, 0xa6460161,
- 0x30a1f243, 0xc18daf0d, 0x37770ef1, 0xe317e3eb, 0x2a28c493, 0x044ea9df,
- 0x255ce79c, 0x2da3ac2e, 0x0aeee896, 0x4ef36f6a, 0x0dfa9abc, 0x078b8d8b,
- 0xd2526b7c, 0x8abf3d78, 0xbf3865ad, 0xcfc2f122, 0x08b6b7fb, 0x65fec6f9,
- 0xe9bee32a, 0x35cfde21, 0xd47e390e, 0x51cf953e, 0xe343a571, 0x4abbefdb,
- 0xc9059c69, 0x0f4147be, 0xc46dfc9d, 0x39fc02ab, 0xf96162cb, 0xe735f1ac,
- 0xbd21f05a, 0xa48a6cfc, 0x563d7d37, 0xc0bab2f5, 0xe8d51e3f, 0xc8ab9573,
- 0xa7986f91, 0xc345b7ad, 0x78039157, 0x3a2f61da, 0x9da5f384, 0x3cdce3be,
- 0x01cd3890, 0x59ea853d, 0x7aa9cfd0, 0xf47631da, 0xfc01c33b, 0x3255ea2e,
- 0x8b16ed01, 0x6fd8d5da, 0x22abd78b, 0x8dabe068, 0xa2ee3936, 0x1822114b,
- 0x22ee35df, 0x7f6e3f5a, 0xe9045a29, 0x970c6ddc, 0xe4a31af5, 0x452379fe,
- 0xb50f9fee, 0xf969b4f9, 0x7baf997f, 0x5cfd7ccc, 0x96b61fec, 0x46fefe48,
- 0xa55bf50a, 0xa1484eb4, 0xec4eadf9, 0xa7bf03b0, 0x98225dea, 0xb2f78069,
- 0xa08bc679, 0x7acedc61, 0x9f3c1c97, 0x3370f5ae, 0x75f35dfc, 0xd54e1e32,
- 0x7b1e3227, 0x84c93fee, 0x53feaec7, 0xbcbc784d, 0xff1e4cff, 0x77d67d54,
- 0x87b43ff4, 0xf826ddfe, 0xe74dfabb, 0xdf6ec571, 0x3b97f040, 0x980fc45d,
- 0x505f886e, 0x3df15db9, 0xdbe4357e, 0xe404c28f, 0x7dc2afbe, 0xfe065c83,
- 0x65ce0df0, 0x4982e7d6, 0xd17eb7e0, 0xeecd69cc, 0xded0138b, 0xfb017c4d,
- 0x11af2f49, 0xf8270ced, 0x3583e885, 0x7cb9bab4, 0xf4106fb7, 0x4e8e1d22,
- 0xa775e679, 0x20fb42df, 0xa3dfdf6c, 0x582f8fb1, 0x2878a7db, 0x46abd96d,
- 0x7c75f71a, 0xb1a7a4aa, 0x6dc8be03, 0x68d5efa5, 0xb6ef7c47, 0x020e9797,
- 0xdac3aa7e, 0x81f70173, 0x8b96ff97, 0x7dabe473, 0xfbe2074b, 0xf2cfaa36,
- 0xdabdbd87, 0x5d2fe863, 0x5196fcb8, 0x5533a95d, 0xefd0ffee, 0xf435f6db,
- 0x89db1c03, 0x0b9209bd, 0x0a2aebab, 0x0d83c64e, 0xff07ef79, 0x58b7c412,
- 0x5d3dda1f, 0xeef9031d, 0x28799243, 0x948f7c3f, 0x100f861b, 0xe40a4b01,
- 0x83670fbe, 0xb08f544f, 0x470aa0bb, 0x79611de4, 0xc384623b, 0xbffd50a5,
- 0xdbe397f7, 0xa1a42f21, 0xe83c617d, 0xf164caf9, 0x1b6dc9ef, 0xf04ff642,
- 0x34edeabd, 0x3ada955e, 0xfbc29c65, 0x7c153f28, 0xde2fadfb, 0x04d7f4d6,
- 0x9c01cfac, 0xfbcf046b, 0xa9653f5a, 0xcf502bbe, 0xe7bd68e7, 0x7337aa0a,
- 0xe864df56, 0x7e9ac547, 0x52112626, 0x947e64ae, 0xe5c83b03, 0x83d4b6e7,
- 0x3e7c525e, 0xd7dfc1e0, 0x35f9c1e1, 0xfa384934, 0x62455e12, 0x8d1a7520,
- 0xa2d5213b, 0xc0140fdb, 0xe39b443d, 0x965afd33, 0x1939f2c7, 0xfd1d0388,
- 0x4b4ee3b3, 0xfc064ef5, 0x670ffd7a, 0x75f1cbcd, 0xf2e86e73, 0xb2deddbc,
- 0x57b6700c, 0xfc7f5939, 0xeed44500, 0x41615989, 0x8a7a1a35, 0xf9f40d73,
- 0x0e0b91a3, 0x8c7c26f6, 0x43cdf28f, 0xbc6fb3ff, 0xcaf2357e, 0x72f77881,
- 0xeb7173d0, 0xc2efd648, 0xbca3377d, 0x981be1d2, 0x373c5340, 0x062837c0,
- 0xbc517c87, 0x9451275c, 0xfc2dd453, 0x45629e12, 0xe518df8e, 0xc53f472b,
- 0x5d8f2396, 0x23d66f81, 0x8d106f6c, 0x739fb9bd, 0x9dde5176, 0xe1e3affc,
- 0xfd8f3698, 0x25ed7136, 0x75fedf9a, 0x82069e31, 0x1bceecb7, 0xba50d417,
- 0x109452d0, 0xdf704d54, 0x575d4a96, 0xf6078bfa, 0x9cee7925, 0x4ebb834d,
- 0xcaeadb83, 0x50e7ee34, 0x79741bb8, 0xeb0a17e5, 0xf947fc83, 0x81b1fd17,
- 0x661f29bb, 0x74c1f8b9, 0x16395b9c, 0x886c93b6, 0x7a45bda0, 0x9c1a3be4,
- 0x73bed28f, 0x35f7f1c4, 0x21189ef8, 0x683e27db, 0x507ec009, 0xaf0f7634,
- 0x4ed513d3, 0x15634a8f, 0x721db70b, 0xb2f0a950, 0x31d7fcfe, 0x4ad7db7f,
- 0xf54e6af3, 0xddbc07dd, 0xfe496f1c, 0x0df0e180, 0x6b790a9d, 0x3fc79cb4,
- 0x1e793790, 0xc6cb84d3, 0x6b589942, 0xcd31fc81, 0x50b2a725, 0xba63fb91,
- 0xde30daf0, 0x7ae3e14c, 0x7bb79def, 0x07bc4fa1, 0xbee0885d, 0xfbf9f851,
- 0x74e0111c, 0xfd72089e, 0xe72b449b, 0x7d137c75, 0xd24bdcdc, 0x547d27c7,
- 0xc056ffc6, 0xee646efd, 0xc79a3a80, 0x650687d4, 0xdcd57eb0, 0x5df3f19b,
- 0xe8d54f70, 0x6feff686, 0xbfd88eb1, 0x699fa833, 0xdfec8437, 0xf5f5bdf1,
- 0xfb47f8cc, 0xa74748e8, 0x4bece4fe, 0x5b4eb878, 0x4bbcebd2, 0xc2127f59,
- 0x8fd1f2c5, 0xa85b7db4, 0x5a2f453a, 0xd26e239f, 0x89960897, 0x62259663,
- 0x10afafbe, 0x3ad0156f, 0x15463ebe, 0xcbd35c0d, 0xfd68a6ed, 0xe13fe94d,
- 0x0f5bd833, 0xe1af608b, 0x92f0aed4, 0x8218d5ef, 0xbdba8a7b, 0x27ca9631,
- 0xc6bd27f6, 0xefaeefc0, 0xfd0ac3b5, 0xf37486ee, 0x66d949f7, 0x68b267fd,
- 0x94fe3152, 0xfb7ae6e1, 0xb3a22781, 0xfea553f7, 0x21888622, 0x0b7af2df,
- 0x1d3e718b, 0x2fda2e93, 0x69111c10, 0x2eb18fbe, 0x75ff27cb, 0x5615c601,
- 0xb7ea9f39, 0x1debb655, 0x288b7927, 0xa7ac9c50, 0xca532293, 0x4a7fc825,
- 0xd3d203f2, 0xcf4e6ef5, 0xf28f79d2, 0xce1ef5f3, 0x9d15a417, 0x6b25bf40,
- 0x7d62b73e, 0xf8970cee, 0x9a696f2e, 0x762ab000, 0x5a441cb7, 0x809a2c16,
- 0xa1d17663, 0xef4883da, 0x6adbd4ec, 0xe1d3be59, 0xd3a345be, 0xfda6a25b,
- 0xe1d68730, 0x87aa3d96, 0x4da603f3, 0x790bdc9f, 0xa27be71b, 0x444baaa3,
- 0x54572433, 0x012fdeab, 0xdb6f7797, 0xdf9a78c1, 0x18a3f527, 0xbdeacfee,
- 0xfa99f70c, 0x4a4e9c89, 0xe81bfa2b, 0x673e2bcc, 0xf6f26c79, 0xd5126b36,
- 0x5e2af42f, 0xbd6bdbec, 0xfda01022, 0xcf26deb7, 0x0e74f581, 0xc98f1f60,
- 0xade8f699, 0x67da7c02, 0x6671a34b, 0x10a4b0de, 0x55194ce3, 0x1bbd456c,
- 0x201921bf, 0xbf4e8ba5, 0xf9f5ee8b, 0x76eb6957, 0xf18565ee, 0x2d33b1d8,
- 0xf2c17206, 0x907d695d, 0xf5d4bf12, 0xade048dd, 0xe18592e3, 0xc11a38ec,
- 0x6ede86fa, 0xe648aef9, 0xd807cb3b, 0xb760c203, 0x2ceb433c, 0x99e6f20c,
- 0x36e27e67, 0xe2672b9e, 0x18fabe5a, 0x922fedfc, 0x736491bf, 0xbff011ea,
- 0xa03cfdfe, 0x9c9af393, 0x24467a4d, 0xcd6abfce, 0x84fe08ae, 0x690899fc,
- 0x6cf91dcf, 0x2fec58d2, 0x4e1c478c, 0xf32bfce8, 0x7f5287d9, 0x6f1aeeee,
- 0x8fc2cb5b, 0xb9fca11f, 0xa36fc580, 0x689ce9f3, 0xf03bff39, 0xb64ecddf,
- 0x10a9ddeb, 0xb77f383c, 0x967ce3f4, 0xc3a88d62, 0xbc022bf9, 0xb714b3bf,
- 0x55f88eb5, 0xf70f73e5, 0x44bdfd03, 0xe5451838, 0x648bad2f, 0xcd92f67e,
- 0xfd0eac73, 0xfbfb2a3d, 0x3d3fbdcd, 0x3de91bbe, 0xc53ff955, 0x31c5a4f2,
- 0xb57ecbfe, 0xd3da0864, 0x52fa2ef9, 0xa8bf4f7f, 0x3f69c304, 0x5fef34e7,
- 0x1be097d9, 0xd2cda1b6, 0xcdbcd28f, 0xa1d2034a, 0x04386e03, 0x690df3bb,
- 0xb05f6e6e, 0xc24d453d, 0xf817ec36, 0xee7c07f8, 0xec81e59b, 0xf6c7cfe6,
- 0xc1725d13, 0xf4e5a510, 0x2c358246, 0x8fbe68f9, 0xf3c4d7f1, 0xfa77b5d9,
- 0xe604f3fb, 0xe0071241, 0xf87bb62e, 0x37f80a1c, 0xf9cf3d62, 0xd7ac3cb2,
- 0x061ff915, 0x25f39d9d, 0xbd2e7078, 0x55fc7a40, 0xcacc7fa8, 0xf3717cf3,
- 0xebb0d1bb, 0x1c7e90c4, 0x5e487f0e, 0xafd404fb, 0x7e16e01a, 0xb1e03f6a,
- 0x3f0226eb, 0x6d773bd5, 0x1d2a7ee4, 0xe5b9e81e, 0x4c1e2ebb, 0xbd789c82,
- 0x0e8064f0, 0x2ffcca77, 0x2a3d7bc7, 0xe37cb54d, 0xa47f3297, 0xa445f388,
- 0xbf515a75, 0x0f47ca54, 0x689fe769, 0xc8fe65cd, 0x5aeeeda4, 0x31525faf,
- 0xf8a7d7ca, 0xadaec2fb, 0xde749b9f, 0xab61a555, 0x23fb65d8, 0x3325e763,
- 0x79e7be5e, 0x2dced767, 0xec87bfbd, 0xfd4e1fc2, 0x3b036cc0, 0x3cbb06fa,
- 0x7f10b7a7, 0xe7e8bd01, 0x0bfb8d34, 0xef6a5fec, 0x524d3f05, 0x849d9c95,
- 0xc287a48f, 0xbef8ce58, 0x598ecfe3, 0x2eb6e7cd, 0x4844d567, 0x0567c83e,
- 0xe5185fb5, 0x5bf30bbb, 0xc2f39da8, 0x1c86ceea, 0x7bca2332, 0x3a57be37,
- 0x073193da, 0x45ef3f3a, 0xb9255abe, 0x7720cd2b, 0xd7bee339, 0xe51759f9,
- 0xbe7cc66d, 0x91b1fd6f, 0x520c6704, 0xad22cf5d, 0x9c7e5ba3, 0xfc05bdba,
- 0xc93081f8, 0x980aa38f, 0x0bf3e91f, 0xda15ffed, 0x33e23ef7, 0xe279d1af,
- 0x738fdc23, 0x7af2b18e, 0x3ca96abe, 0xa170e748, 0x6c84011c, 0x79ce1d8d,
- 0x6fe1146f, 0xbe1553bc, 0x3d45f46e, 0x1e7af5a5, 0x2bd099f8, 0xb0af54d2,
- 0xfb1dac57, 0x5bcefbf7, 0x8d47d6d5, 0xbba9f9d0, 0x37767097, 0x5bcf396f,
- 0x01f447c2, 0xdf2ac65e, 0x5b0ebe6f, 0xc3ac41d1, 0x9f1e6738, 0x539ce38b,
- 0xc304f98f, 0x43df187f, 0x1f3a19e7, 0xf27ef8e1, 0xe1158fd2, 0x7dff60b7,
- 0xdafb676e, 0xd3eb5b5e, 0xee7c25bf, 0x81ed925d, 0xf005e89d, 0x68cff05e,
- 0x7bb3cb3b, 0x7c1f84a3, 0x84d4ef65, 0x2f45ec00, 0xdf044f41, 0x79642de8,
- 0x77bfacb8, 0x7f53950e, 0x5f68c2fd, 0x2f345ec0, 0x069feb42, 0x7d15fb46,
- 0x52837db8, 0xda0e66fb, 0xbe6488af, 0xf9203473, 0x706c7378, 0x9bdf4a9e,
- 0xa814cf3f, 0xd6045477, 0xeddea2a4, 0xe5435fd2, 0x6fd43549, 0x122192f3,
- 0xf951ffce, 0xf3ce68dc, 0x32738df6, 0x4cfb671f, 0x5f6f54f3, 0x697aaff8,
- 0x51bcd5eb, 0x3d83f796, 0x9429e514, 0x9b63f4a7, 0xab573fac, 0x974691f7,
- 0x0f99cfb4, 0x5a44a6f8, 0xd2fde741, 0x99d2c24b, 0xc2fb7929, 0x5948f3ef,
- 0xe728db06, 0xc29f5c56, 0xcbd9a3f4, 0x5b7c6b66, 0x1c0d0fef, 0xcb2f2123,
- 0xb70b39bf, 0x679e8384, 0x41b78796, 0xbe5a3bee, 0xfb7a0a32, 0x0c1a9f4c,
- 0xa3395c83, 0xaf29dbd0, 0xaf5c62a5, 0xd74cb71c, 0xc0a582ff, 0x0eedcbeb,
- 0xf7cb3771, 0x3ea302c1, 0x556fafa5, 0xa37898cb, 0x27615cde, 0x2cf042fe,
- 0x9a6df6d1, 0x7d3bd7d3, 0xebe9f404, 0xf4fa8de3, 0xe40f65a7, 0xc6d2fef2,
- 0x8def5b3b, 0xb90e993f, 0xfaa7226d, 0x0f7a9d78, 0x57e74dd6, 0x25db97a0,
- 0xfb6b08bd, 0xdf298b47, 0x07887b30, 0xd389eaf6, 0x1d6f4c1c, 0x1f2ce12d,
- 0xf08ecc37, 0xb0d76ec2, 0x06ed8c2b, 0x83fb6b37, 0x1ba628f4, 0xee28beff,
- 0xf32ed2a7, 0x3065cf95, 0x0f60bcdd, 0xe515b93c, 0x7fb3872f, 0x8e5a32b6,
- 0x24bbf95b, 0x29bd2e8d, 0x5fb17aab, 0x32a5e98e, 0xe5c31dc2, 0x7a678fbf,
- 0x57dc367a, 0x7d127c00, 0xd2bc5db2, 0x258ccc1e, 0xe8d31ffc, 0xfb237a0f,
- 0x98a36af5, 0xf796856e, 0xf59e3cfd, 0x797f9238, 0x437ddf3c, 0x7bb3ef39,
- 0x3ec42efb, 0xf0c91e5a, 0xf2c9731c, 0xbcb19563, 0xb7dfe60f, 0xc5fc30f4,
- 0xbcec8ac7, 0x55ed8e5f, 0x73fade59, 0x9f841a9d, 0x9acfa75b, 0x86dfc725,
- 0xe1baa8f9, 0xd4dde4a3, 0x5595fccf, 0x7e6ed093, 0x7053edc5, 0xf69af6de,
- 0x4369fb29, 0x4afcf3f7, 0x97d47fb3, 0xf98c9dee, 0x760764d5, 0x1e7ea41c,
- 0x116a739c, 0xee9fd3d6, 0x3ef5869b, 0xe17d6f6f, 0xeb77044f, 0x5eb23f8a,
- 0x6fb47d74, 0xd85fbe26, 0x5fae1bf3, 0x16bff2bd, 0xb6afce41, 0xcfd17a4a,
- 0x7e8d1ae3, 0x1e6f8645, 0x7cae57ea, 0xc881f59d, 0x7f9223ec, 0xf8fdfede,
- 0x5bbde9ce, 0xdda8505e, 0xd5bd88d2, 0x5c81aa9c, 0x94676b9c, 0x0692b460,
- 0xed3d4a7c, 0x8d182bac, 0xa459f175, 0x5b74b89c, 0x4b181f88, 0x7fd9a091,
- 0x16d2dda8, 0xf242bf19, 0x19f41d82, 0x7d297f5a, 0xf3df7ae7, 0x9168857b,
- 0xdf7763df, 0xf75cb57b, 0xfc387060, 0xb09b19ae, 0xfd76e7ee, 0x77e8d326,
- 0x872f4d0d, 0xacffce57, 0xeace5fb6, 0xbdb665fb, 0xb9005ed3, 0x7d33fceb,
- 0xfe76744c, 0x3f9cc1c9, 0x112bb4ad, 0x577f974a, 0x72465a78, 0x65b78d7c,
- 0x07e7e424, 0xe34befb5, 0xaf82465b, 0x384e7ce9, 0xff59725a, 0x85c96acf,
- 0x47f3abbe, 0xc992d451, 0x992d03df, 0x4582ff68, 0x8ff853da, 0x3a78a8e0,
- 0xd2dde369, 0x0cb7e10f, 0x26e87e47, 0x1a71f5e4, 0xe91f25c2, 0xa58fbe69,
- 0xf9e63b4b, 0xbd9bf639, 0x7ad07f54, 0x707ca9bb, 0x9adf9cc0, 0x03e7ed2e,
- 0xfa6fe243, 0xc3fbeda9, 0x213c8e70, 0x3fd7f5ba, 0xd4f38da3, 0x3c719d53,
- 0x0acfa6aa, 0x6e1f4eb7, 0x80dbdf29, 0xf13a8fef, 0xf1126b7d, 0x6398a5e5,
- 0x9e5fcf2a, 0xfb494f67, 0xbe790bcd, 0xe7179c24, 0xff821781, 0x67ca5885,
- 0x7892be43, 0x3e3af3d5, 0xf2bfe743, 0xb04945a3, 0xae947edf, 0x7d3cf9db,
- 0xde3a9740, 0xefa46c1a, 0x2e3f4364, 0x8569382f, 0x2c49ecde, 0xdaec1ab3,
- 0xd81cf3eb, 0xe4378b57, 0xd6748c39, 0x10e0adb0, 0xece21c49, 0x2007ab36,
- 0xf7035837, 0xd86f7e42, 0x05f8b6a6, 0x54bc3b97, 0xc0f3acff, 0x68b7a8db,
- 0xe43e6c43, 0xe2fdbd6d, 0xcb1223f5, 0xdd0e700c, 0x9c875e66, 0xd87e7316,
- 0x04fe736e, 0xffde80ce, 0xa0bcbb7c, 0xc8705f39, 0x83e4ff9c, 0x9c81675b,
- 0xbdff55cb, 0x3f89f42a, 0xf384384d, 0x5e17d3f1, 0x2cfac68c, 0x41d94bfd,
- 0x71a149e8, 0x0a6eb422, 0x56ff08f4, 0xb2e3e985, 0xf81e9178, 0x810f1e81,
- 0x93a4619d, 0x683fe10a, 0xfebcb94d, 0xcb32d119, 0x5955744b, 0x64e0bcb7,
- 0x57bf5741, 0x43b3acb6, 0xb71d0bce, 0x9c2ffda7, 0x6aec375e, 0xd964a3c5,
- 0xc5637555, 0xd62df809, 0xf4013bbe, 0x854bfc57, 0xe7e28ae5, 0xbe0abd07,
- 0xce63b6df, 0x9ace9c0d, 0xedd0f8c8, 0x2af78b7d, 0xbbca28c1, 0x5dba4946,
- 0x7d615eb8, 0x1cd1a4bd, 0x36b65747, 0xd9a6de24, 0xf778be5c, 0x9f86fffe,
- 0x18f1dcbe, 0x1e5c33c7, 0x05781827, 0xa7c55b7a, 0x153ded82, 0x330dbf9b,
- 0x2d79cb97, 0xbfe1e7d4, 0xaee1e396, 0xcf3a5592, 0xd0c893b7, 0x574bf0f9,
- 0xe1066a51, 0x8de6aafd, 0xbd9b94aa, 0x7597ecc5, 0xb0ce39da, 0x918221ca,
- 0x28a1cf04, 0xdf45d7bb, 0x628fae2f, 0x18516179, 0x9cf99fc9, 0x438e708a,
- 0xdda0c4f4, 0x965477a9, 0x25e2aa83, 0x571eaa1e, 0x56c5b002, 0xfc8a48c1,
- 0x04bf3213, 0xd25526de, 0x3f00d78f, 0x1798cdd6, 0xab6f524d, 0x03f706b4,
- 0xc0e79d2f, 0x4abd7336, 0x38d1e79a, 0xefe659c8, 0xeb9da2d5, 0x36feecd7,
- 0x60ddf8cc, 0x527d65df, 0xc8556bd7, 0x7aa70433, 0xb3cb0447, 0x402398c4,
- 0xef14ab57, 0x29150ec3, 0xefa0e39d, 0x2f964e25, 0xe7946ee6, 0x838c3347,
- 0x0dd78390, 0xae67b966, 0xbe04cde2, 0xd670bac4, 0x1fdca9a7, 0x64e58bde,
- 0x4e484396, 0x7daa3966, 0x12e39d8e, 0x825af39b, 0x1f9ac790, 0x0ad0f148,
- 0xf3e47f32, 0x96709ee8, 0x4aa79a7b, 0x5d79a7b9, 0x31ff6e1f, 0x390beb40,
- 0xf9b9e25a, 0xb71e1c9e, 0x89db2a9f, 0x200f523e, 0x7a133ab9, 0x41e5c102,
- 0x67472eb9, 0xb04afac5, 0x9bfcfaee, 0xe0a3db63, 0xf1e512c7, 0xd86e4bdf,
- 0xed879da2, 0xf003c2eb, 0x8a549c53, 0xf60c5a0e, 0xe4325ba9, 0xac7231f9,
- 0x8f56ab77, 0x966519fd, 0x80ff77a9, 0xd07b29e0, 0xe9486ee2, 0xf5e1075a,
- 0x27fe6266, 0x83e785d7, 0x958e46ee, 0x7963a7f6, 0x0e479f92, 0x73bf1c17,
- 0xedefd6bb, 0x9a531619, 0x48f44118, 0x942c9cfd, 0xe1a8edf6, 0xa4076c45,
- 0xbbb9ba35, 0x19359038, 0xb32a9cf2, 0x9afefd17, 0xa4e9e06e, 0xde52f18b,
- 0xd94cb93d, 0x72f2e124, 0x5fc8dfbc, 0xf0fdb385, 0xe8de76a4, 0x347441eb,
- 0x8d71cf82, 0xe8d3ad9f, 0x74cf5d66, 0xb98ba263, 0x3741b790, 0xd8b9e473,
- 0xfada5749, 0x7af0dd12, 0x485d13b7, 0x6be211ba, 0x4b742fb4, 0xdf443b79,
- 0x7bb7d4ea, 0x0e88b7d0, 0x6de8c89e, 0x074217a8, 0xf1181ac2, 0x252cfc8f,
- 0x2a4762a3, 0x564904b4, 0x2cdc47e1, 0xd7c646ce, 0x4ac0d65d, 0x55bfa782,
- 0xab00cbae, 0x653a3ba4, 0x5cf911fc, 0xd9f88bdf, 0x0b17fbe2, 0x4e2fd52f,
- 0x4ab76c12, 0x2626f927, 0xa409db8e, 0xb0aa0770, 0xf68a50e7, 0xffb231c5,
- 0xc46fa262, 0x5e7f51b3, 0xdcc69c4b, 0x2a7fc246, 0xfb407e58, 0xef6e7ce8,
- 0x5ef6c8b7, 0xd303a52b, 0x5f6a3ee4, 0x2bf8c615, 0x264073be, 0x58d264e8,
- 0x66249d33, 0x4f41394a, 0xbadd331b, 0x7e0890dc, 0x9838d250, 0xf08699cf,
- 0xd85daaa2, 0x7d48cfa7, 0x4df578a3, 0xbe004793, 0xd83de367, 0xeca7a7c2,
- 0x494aff60, 0x7f1f9ce3, 0x5b653d08, 0x98df7f38, 0x780f7be9, 0x17b8ad3f,
- 0x250fa2ec, 0x27b15f33, 0xcb5f7b52, 0xa3bf73d4, 0xc77f8a74, 0xa62390db,
- 0xfeb950cc, 0xb9ed2114, 0x338e51a2, 0x35b9ffd9, 0x3c9bfa91, 0x94f0e15a,
- 0xf25770b6, 0xb455f832, 0xd1a63df5, 0x98b84377, 0x70139cfd, 0xcd4cc80d,
- 0x24821f86, 0xe4e46ed4, 0xfd5a9901, 0xc806ca31, 0xc9c70343, 0x47d7a7fd,
- 0x2d37e83f, 0xcfb7ee53, 0xe7a77db4, 0xbf5caf09, 0x5b584d6c, 0x5b52345a,
- 0xf3a51070, 0x039ec6b2, 0x2a94999f, 0xde07ac26, 0x4d8aaa7f, 0x317b6f0c,
- 0x4ca885f3, 0x8f82f837, 0xfba65914, 0xee99836d, 0xb7b4c6db, 0xb6f949dd,
- 0x7ed2392d, 0x0bf3e9a7, 0x82e5825d, 0xef9231b6, 0x64896fb5, 0xd5cc73fe,
- 0xed27151a, 0x97dfac5d, 0xd7f1246a, 0xe17b86ba, 0xda752e37, 0x2c7e70db,
- 0xfb3a607c, 0x499b4bfb, 0xfd5c47bf, 0x4f7eb35a, 0x6658787a, 0xa87afa37,
- 0x019a0e5e, 0x55ad951d, 0x36070e98, 0x997dec78, 0xcc2e29cf, 0x4c19ccaf,
- 0xf32fff07, 0xf05c7384, 0x37fb7a65, 0xb091f784, 0xba0e0b1f, 0xd7c83a1a,
- 0x3716e30b, 0x1a7eb315, 0xfe63ed99, 0xbc255035, 0xd4cf1d10, 0xec126fe8,
- 0xd64be0a0, 0x97d8bed6, 0xdf6865af, 0x4e995ce3, 0xbe70eba6, 0x7366d06f,
- 0xb6be0265, 0x9c16e155, 0x4a5693b7, 0xe77da6fa, 0xbb80bdc0, 0xfc0222ac,
- 0x7ed6b8e0, 0xd16b0afe, 0x77f7ca46, 0x1c546b08, 0xe98f2be8, 0xfbe5903b,
- 0xe9f7eb0c, 0xc828c42f, 0xd76ba50d, 0xfa34b849, 0xe323d610, 0x4f9c69e3,
- 0xc3e4a4b7, 0x53d3a0ae, 0x766c6b20, 0x5d0308e6, 0x1e9850cc, 0x60873e68,
- 0x55979d9f, 0xfa728f92, 0x32f41fbe, 0x1d306c69, 0x6a85d871, 0x76abc725,
- 0xe20f0a24, 0x3b443a87, 0x241d23cb, 0xea3f808f, 0x27e7467c, 0x475e1744,
- 0xeb7ad742, 0x3d6b657c, 0xde784681, 0xf4e0ef56, 0xb0977aa9, 0x5ed84f12,
- 0x67f9c89f, 0xb69cddeb, 0xf7f167d4, 0x9c3deae7, 0x8a3f59df, 0x7bd42ff3,
- 0x7ebbbf39, 0xabbfa722, 0x84efe22f, 0x3a4be61f, 0x93f9d1df, 0x9f3a5f4e,
- 0x05aba50a, 0x33dc6684, 0x0fccf6a0, 0x79883e75, 0xf8bbf258, 0xa9cebe93,
- 0x113f914a, 0xceb450fc, 0x5428ff01, 0x22f33ecf, 0xdca3b9e1, 0x1da1f1c9,
- 0x0ec1f242, 0x8dcf83a7, 0x0dd8bb64, 0x32c340fb, 0x869ddb6f, 0xb95e7873,
- 0xba06ac22, 0x5c36a9bd, 0x7d740d58, 0x29ac5d73, 0xfdeebf3f, 0xff50fad7,
- 0x2df18b3f, 0xbb1cfac2, 0x7fa3d4e3, 0xdf8fefa4, 0xeb033a71, 0x796c704e,
- 0x1edee308, 0x2ad1c1a1, 0xceddbae1, 0x08c0d2f2, 0xcfe14fa9, 0x2d738861,
- 0xfb7d894e, 0x31e70437, 0xda061d6d, 0xc146b35d, 0x754ab32e, 0x1f2aa4ad,
- 0xfbe8bd63, 0x2af5b59f, 0x7c630ba9, 0xfb6a3496, 0x4cff18d4, 0x57de3cf8,
- 0x78a75cb0, 0xe91f8085, 0x41ec2ff8, 0x71c41192, 0x685011c5, 0xad94851c,
- 0xae17b0f9, 0xe428fd79, 0x10eea574, 0x873ed5cb, 0x8428e393, 0xd8d676df,
- 0x9077529f, 0xfed689eb, 0xc8c838a6, 0xf83b5ee1, 0xeb1b6805, 0x40759256,
- 0x268b9f60, 0x94f1ef85, 0xd6cbdf69, 0xe2f8a628, 0xe655337b, 0xac32878b,
- 0x14ca0e9c, 0x89a5139a, 0x5e9d29cf, 0x3c707f89, 0x9e535963, 0x2f81917d,
- 0x4bdf6897, 0x78a62cb3, 0x321943c7, 0x98106a2e, 0x6777a505, 0x3217daa5,
- 0xdc7373df, 0x24bf5ebd, 0xea757f2b, 0xe883f470, 0x8ff6aea0, 0xddb95a64,
- 0x84970ca1, 0x59e741c7, 0x74e9c714, 0x72e82e7b, 0xeff8a7cc, 0xeb3f0c95,
- 0x3ecf1559, 0x7bfc2cfd, 0xe30a7f15, 0x9862a9f3, 0x0ec8df66, 0xf2ce9c8c,
- 0x8ca9d78f, 0xd72dfc84, 0x7fd3fc7f, 0x547c4689, 0x57694ecd, 0x690db4a5,
- 0x6ce5edf5, 0xd0f6ab57, 0x9f0388fe, 0x5fcdfb35, 0xd14ff67d, 0xf897acad,
- 0x5bf8b493, 0xdeaaf78e, 0xc0e38279, 0xd0afb8f4, 0x37ca3576, 0x71eaa7ac,
- 0xb63fba01, 0xf78d9f70, 0x851ecd4d, 0x5d9a98f5, 0xe7c01317, 0x4aadf66a,
- 0x272e2ee8, 0x5e3d5fb4, 0xd5bfb740, 0xc39fb588, 0xc384487f, 0xffad0ff8,
- 0xaf546676, 0x62054353, 0x3b60aed5, 0x1c705588, 0x8e2d72c7, 0xc19023b3,
- 0xe49ee17e, 0xc4f59aed, 0xedbf49f0, 0x1063bab0, 0x88417caf, 0x53addd89,
- 0x7e7920fc, 0x047da39f, 0xed85f0bf, 0x1791cb2a, 0x7ef147b6, 0xff7edea8,
- 0x55dbc441, 0x8dd8566f, 0x308e2557, 0xaa77aade, 0x0fe061c2, 0xc50bb035,
- 0xd2e70cf7, 0x416aa3a7, 0x145a4b5f, 0xadf816ef, 0xde98ee1d, 0x35da7806,
- 0xd61a5afa, 0x45d79232, 0xf814ff83, 0x5cce419a, 0x8e7ef7b2, 0xe77aa413,
- 0x6df9ae59, 0x51b3c724, 0xce036f0f, 0xd80a1b33, 0x65a4bd4f, 0x05cb3547,
- 0x105d23db, 0xccdb4e69, 0xd1be29f7, 0x9346fbc6, 0x4fc0ced3, 0xaacff682,
- 0x4e030f2c, 0x5ad3cbec, 0xcedeab3c, 0xb3b64832, 0x0dfb7868, 0xae88e7f6,
- 0xda5a4bfa, 0xfea9d3a2, 0xe7dfbb27, 0xee4839d4, 0x23ce25e3, 0x3f4738b9,
- 0xf7c919d9, 0xf9d93eed, 0xd12f09eb, 0xc65ae778, 0xfb0c52f4, 0x1b20e06c,
- 0x41b73fd7, 0x25f301c6, 0x5a0fd611, 0xb6673e78, 0x27ac2927, 0x9f84df03,
- 0x8f9f3b33, 0xf63ef0b6, 0xab717bff, 0xc86b15b3, 0xb2eb847d, 0x5bfe8047,
- 0xed11fbb5, 0x7fe5fd9a, 0xed6affa7, 0xa4529b7b, 0x3bef238d, 0xc20e3d08,
- 0xd53beda5, 0x796efbc9, 0x2fef9d94, 0xbee6182c, 0xe8f81e71, 0x518e329b,
- 0x043f77f4, 0x3bc16ffd, 0x596f6cf1, 0x41f7736e, 0x36c38bfe, 0x282c13f6,
- 0xa1f51cf0, 0xed9d8c7e, 0x75b1224a, 0x6dadec04, 0xa8be5229, 0x933b435c,
- 0xe88fdc50, 0xacf84fcd, 0x8f84580c, 0xa50793f2, 0x523ebaf2, 0xd9daf16e,
- 0xfbe413ff, 0xc2ecc792, 0xfe2f7b8f, 0x5d7ea4e7, 0x0efd2a99, 0x517f608f,
- 0xcc17195a, 0x4edd878c, 0x69ca9ba3, 0x9fa06e54, 0x4cc14dca, 0xed674fc8,
- 0x72891ed2, 0xf9954de8, 0x46835eb2, 0xfd07e8a7, 0xceb8a5b6, 0x2bbbbcb3,
- 0xb0ef404a, 0xed2518bc, 0xdf09bf21, 0xaf386614, 0xe9241a6f, 0x07f341b8,
- 0xf848b7fa, 0xf8e41700, 0x4ca6f625, 0xb8fab9c8, 0x789ba24b, 0x78dab3bc,
- 0xa49a224b, 0xc78b44ff, 0xdf1e7d43, 0xd3bfd826, 0xcb1864fe, 0x1efba7cb,
- 0x9fe30179, 0xc730727e, 0x04a5b411, 0xf2e6ed16, 0xaee38e70, 0x082c2a78,
- 0x327b3f78, 0x9f58ed8a, 0xf61ca4d9, 0xcb025459, 0x1ea28761, 0x3afe805c,
- 0xe0298736, 0xc2299fa3, 0x2df2889e, 0xa80e59bd, 0x3f63afa8, 0x17b10549,
- 0x4e94afc8, 0xd9f7dc84, 0x276cc196, 0x950decfa, 0xf7d0292f, 0x13eef835,
- 0xc67e0b4d, 0x3ff4bff2, 0x6fea7e9e, 0xaff3bb83, 0xdb366c54, 0xd7f5f4c3,
- 0x2418efcb, 0x0c7703ed, 0xcac97a92, 0x7fe92e41, 0x30796c8b, 0xf929e795,
- 0xeb03ad03, 0x131fb47f, 0xd63f6f60, 0x714127b2, 0xccc1cf02, 0xdbef035f,
- 0x7a759ea4, 0x42fd8dbb, 0x79462f15, 0xe774fed9, 0xb0ef7c15, 0x78729542,
- 0xdbde4585, 0x99eed0ab, 0xb2674456, 0xcdf08b7d, 0x16fb6d7a, 0x8e471b55,
- 0x01d6d9fb, 0xd4109fd2, 0xf0e42ff2, 0x7149b83d, 0x2c69e6e2, 0x05c86d5f,
- 0x8e6e2f5e, 0x1a79f8e4, 0x87b88bc7, 0x5cfd9f8a, 0x116633e2, 0xae7407eb,
- 0xd4ae7f31, 0x9dd573f8, 0x5ee0c757, 0xe5477881, 0xad1712fb, 0xbfe03e9e,
- 0x4f7af8a1, 0x5f4b63e3, 0x41f99478, 0xc417ed25, 0xfcd52d59, 0x529f4bcb,
- 0xba5c9e58, 0x9887eafa, 0x136dbeef, 0xb6705fb8, 0xe368fee5, 0xf8d5ec7a,
- 0x0f7b5767, 0xf54a5fd7, 0xa337fb65, 0x36ad9e19, 0x5d09e00f, 0xfeddefc7,
- 0x6a5ff529, 0xf242d15f, 0xf3e5ee45, 0xdc8e28bf, 0x95f027f6, 0x676ce1ed,
- 0x7be7f5a3, 0x2d6c6746, 0x33ff308b, 0xbf3384cf, 0xf72b1339, 0x9e7427fd,
- 0xe780edfa, 0x5db1f787, 0x02e9bded, 0x80e2d0e7, 0xae1d5fb9, 0xafdf1afd,
- 0xc0c4f78a, 0xeb45534f, 0x7d68fe81, 0xdfedc47e, 0xd0fb71b1, 0x768e3cf9,
- 0xf4fb0c23, 0x9ba64899, 0xbae4fd33, 0x1076799c, 0xb16d679f, 0xde09de92,
- 0x674be864, 0x1b8a6562, 0x0a87a03e, 0x3387a497, 0x1ed85a63, 0xc1d94670,
- 0xb64d9b69, 0xfcd3a8ab, 0x897f44da, 0x26d01fa0, 0xb58ea9ec, 0x80c72047,
- 0xe7cc8fcf, 0xcefb8834, 0xd07376a1, 0xbebfce29, 0x84dcf259, 0xcf3e0578,
- 0xe3f61b7e, 0x733df0b4, 0x564f269f, 0x4fdcbf6e, 0xdcaa7588, 0xeb3fb0ae,
- 0x02fe7692, 0xddba5eea, 0xa972e89f, 0x6e22f15f, 0xb2e3696b, 0xa5fba025,
- 0x81e6ebb5, 0x2c79f5ee, 0xb75feed5, 0xd3c32a29, 0x27fb4e16, 0x74f1f2fb,
- 0x8a59aafc, 0x5c279f1e, 0x7b45f9fa, 0x2dcb2c38, 0x4db288e9, 0xa3655fd4,
- 0x49c796b2, 0x395bf5d1, 0xb84f1d3f, 0x5efb02cd, 0xb9df769b, 0x70ebf9a7,
- 0x524f04f6, 0x6d4fe496, 0x6f9ef229, 0xbef25bfb, 0x0a6fc5f6, 0x81fee262,
- 0xfa91c83c, 0x7f047f7a, 0x72106816, 0x96e7c68f, 0x704eaec2, 0xfb306e66,
- 0x9b36b273, 0x9bb643f3, 0xcd3bd9f3, 0xe6bddcf9, 0x7355e7bc, 0x7b7185de,
- 0xfa09e177, 0xa103e236, 0xbe85236f, 0xfa94ceed, 0xb7d0f236, 0xc6df4291,
- 0xc8dbe877, 0x1e46df43, 0xd0f236fa, 0xdf4291b7, 0x1a39f7c6, 0x7b352a9e,
- 0xe381d629, 0xeb84f6d4, 0x5fbc00f1, 0x6049cc2e, 0x52ac2a3e, 0x24b0bd1f,
- 0x4ec7e59b, 0x0754d33b, 0x38f499db, 0x7ca2b7a7, 0xc37ab2e3, 0x75647b7f,
- 0xc76e14df, 0xdf9ae7f6, 0x6573fb49, 0xf613b87e, 0x9f55d68e, 0x13d886ac,
- 0x444df288, 0xf6b60bfd, 0x556fc0ad, 0x6fec2bdd, 0x7ee15d6f, 0xfd7207e7,
- 0xc7a2eed8, 0xdce3152d, 0x7d26df03, 0x7b6fc649, 0x6a3b461c, 0xac485fa8,
- 0x3f21e435, 0xa1f39b35, 0x35f0207e, 0x355f69af, 0x6e3c1d31, 0xbe0bef6b,
- 0x0749e27f, 0xa13af3df, 0x6cc4edd9, 0xba63cb17, 0x8f29df3c, 0xc26ca3dd,
- 0x2b24bdf9, 0x1c77db8e, 0xd3dd30ca, 0x2f4b4d0b, 0xdabcb3e5, 0x58ab5f99,
- 0x8cd94e30, 0xaf59fb15, 0x73e68c4e, 0xb60d16e9, 0x0dff9041, 0x440e0f70,
- 0xe868e898, 0xbf10b8b6, 0xfd533f65, 0x4353bb61, 0x4c4396fc, 0x16d7d3e5,
- 0x17b5ef98, 0x1f2a6d5d, 0x878cef68, 0x96ff4873, 0xd64b9f06, 0xe7cce8b9,
- 0x4bd686f9, 0x847f3c56, 0x25bc56bf, 0x9a32d3e5, 0x7b40b787, 0xfe1f239f,
- 0xe014ef39, 0x16c5bcaf, 0x54bef38b, 0x9d44873b, 0xb72e5cf9, 0xae2bbf0a,
- 0x5dcaee8b, 0xed4b1bc2, 0x2536b4bf, 0x71dd1d33, 0x14255934, 0x2472192d,
- 0xe57d0837, 0x8246278d, 0x8dd4aaae, 0xbf2a2ec9, 0xc56c0955, 0x71d3ec45,
- 0xa4ae123b, 0xf8b4fff2, 0x75a2c91e, 0xef05b64a, 0xba3e0f9d, 0xbde04d23,
- 0x9f6b1391, 0x3cb8e68f, 0x6d92fe8d, 0xc1d008ae, 0xf59526c6, 0xd4cdd814,
- 0xd93a2eb8, 0x011f14d8, 0x8c7ca6bd, 0x717297e2, 0x0bdf49b4, 0x9aa147c5,
- 0xe69b8efd, 0x2a90f17b, 0xf36a40ef, 0xf592ee5c, 0xaf6cba45, 0xe7d7b3df,
- 0x47d3527b, 0x96be362b, 0x3f7d0b79, 0x2e7f783b, 0xd65784ae, 0x2f79e6ef,
- 0xdadf6cb5, 0x1d7bd297, 0xd7985dbe, 0x45c6b7f2, 0x7ce3495f, 0x87c65db9,
- 0x89f9b5ff, 0x4fc4fcc7, 0xc27a6cef, 0x8541fb0e, 0x1e876035, 0x46e4fe5c,
- 0xae18e23b, 0xbf91b6db, 0xcc56da2f, 0xbefd00f6, 0x7c7aa7da, 0xf28f86b3,
- 0x1706cab1, 0x60ffb3cd, 0x23ca4fc9, 0xa14b1c64, 0xdc35fa3a, 0x4db8b813,
- 0x66bcc3c9, 0xe3b0ed14, 0x1a3bff1e, 0x37dd09df, 0x17a7871d, 0xabbd86f6,
- 0xdf20f145, 0x89993ed3, 0x0f4472cb, 0x39b92fd3, 0x0869719d, 0x0a1fd5eb,
- 0x8e70bed2, 0xd7e88764, 0xcf695587, 0xad123c43, 0xd83db973, 0x85e43a6b,
- 0x0ffbe597, 0x8d0e7455, 0x2ede87ca, 0x169455c4, 0x744d568d, 0xd23e335e,
- 0x0b660fb4, 0xfea2bec3, 0xa67e8966, 0x69498cfc, 0xce37faa6, 0x67e21a18,
- 0x672aefce, 0xe99575fe, 0xdbaa975d, 0xe3856efd, 0xbf9ac67b, 0xd33b7a53,
- 0xf6a60dd9, 0xe99a6255, 0x9b25975d, 0x133c65df, 0x8fa1d995, 0x41f76b95,
- 0xb4dafb66, 0x9dfcadef, 0xafda6226, 0x7f3cd303, 0x8da5e794, 0x1dba08fd,
- 0x9ffe367d, 0x1979ddd6, 0x898f19d1, 0x3bd85bf8, 0xe479667c, 0x42a9eb08,
- 0x669543ae, 0x92caaa8f, 0xff2aa8f6, 0x9be23b11, 0x24d6ff09, 0x93754942,
- 0xaa46f6c2, 0x938a48ef, 0x7df1dbf9, 0x075ef9a7, 0xf284bbfa, 0xf6316a43,
- 0x35796857, 0x42e71bcd, 0xb047ec35, 0x6bfde983, 0x19f4eafd, 0xb43ecf7a,
- 0x3760df1f, 0x6d8ae7ef, 0x23f60e3b, 0x8a2f4cbc, 0x497c43cd, 0x5b54cb65,
- 0x74e5f671, 0x8bfdf3a6, 0x7fb616e5, 0x857e1c75, 0xdca3ace9, 0xddf191ea,
- 0xd51f18ff, 0x0d6f695e, 0x3445bfa5, 0x1799f81f, 0x013c54ed, 0x5e03d645,
- 0x432e81fa, 0x0dd492f0, 0x753c74be, 0x7ca42de2, 0x1c33fe31, 0x004a11f1,
- 0xbc32f27c, 0xfad478e8, 0x2c13e45f, 0x013c1267, 0x3fa42786, 0xff742a31,
- 0x20efc2dd, 0x84506c74, 0x3c6ef94b, 0xed24bb4c, 0xe4d30336, 0x2977dbbc,
- 0xb3ebc81e, 0x7bf9592e, 0xc914bd27, 0x9319f538, 0x93b3fbcc, 0x7ee48a7e,
- 0x81297999, 0xd36ffddb, 0x8fd177d1, 0x8d099fee, 0x5defd6ff, 0xddac1a2d,
- 0x46211a4b, 0xc44ffb7c, 0x4072ebaf, 0xe749e74f, 0xf0d2e379, 0xf6ed4cef,
- 0x951e5e1c, 0x3edaf1ca, 0xf3a88ecd, 0x4ed69f63, 0xca98b71f, 0xefa005dd,
- 0x17b009fe, 0x4b4c6eaf, 0xe317be36, 0x3b63655b, 0x788af26f, 0x5dc38b4e,
- 0x8a473809, 0x4d77c857, 0x27d5df8e, 0xe388fe01, 0x26bd6cab, 0x7fc7d751,
- 0xe4593c3a, 0xe9c85f20, 0xb3617589, 0x3d78768d, 0xed2c1a6d, 0x7e39fa35,
- 0x7a3872ce, 0xaadff636, 0x0508d15d, 0xfdeaba5a, 0xcf3a2e91, 0x8f7c5957,
- 0xef7f660f, 0x85cf3e46, 0xec2e636b, 0x513cba70, 0x0fb0aab1, 0xffcafdce,
- 0x9c31e579, 0xb615befb, 0x9fa3c804, 0x840aa07d, 0xc679d0ce, 0xe1a7c472,
- 0xdd3fae92, 0x10f7c912, 0x1784553f, 0xea25a6fe, 0xe9975cfe, 0x0b3bdd5c,
- 0x41deffe3, 0xb8c08ee3, 0x1889ad81, 0xc4cfe3d7, 0x1915beb8, 0x57d9dd31,
- 0xbd66b4f4, 0xeab6f394, 0xeecd64f6, 0x791ef90c, 0x6270f7c8, 0x1e47be41,
- 0xc8523df2, 0x4dbef8f7, 0x6c0c2ff3, 0x7e83cf68, 0xb22b1fea, 0x75bcf96a,
- 0xbf7e4166, 0x80f08945, 0x78a2dcff, 0xc1bc70fa, 0xc4def966, 0xd57590f2,
- 0x49da6bd3, 0xedd03306, 0x84392e0f, 0x8c6e6e31, 0xc7e53588, 0xea9afa39,
- 0x4c52ba17, 0x0e25d7e5, 0xef5f9536, 0x7fe533ce, 0xa9a57598, 0x18cf64fe,
- 0xa347fe53, 0x9fd537ae, 0xca6a9dea, 0xc7389f4f, 0x51667f54, 0xc6fca9b1,
- 0xe54c4bd9, 0x4ccb7c73, 0x3fe579f9, 0xa9bfd535, 0xdca98576, 0x9c565c2b,
- 0x77a17b77, 0x865fde11, 0x2de945de, 0x8d38656f, 0x9c7a3aeb, 0x7977dba5,
- 0x5072694e, 0x36dea1bf, 0xd7ee25d0, 0x68070e80, 0xc0be67f7, 0x7e1bd2b9,
- 0xf522a0c9, 0x417d23de, 0x42f5a137, 0x1e4747cb, 0x35a6e8b8, 0x7a2a7a2c,
- 0xc4f895a6, 0x140e2be8, 0xf57e51a4, 0xad338553, 0x5f465fc4, 0x54f9e07d,
- 0xb53d37ca, 0x3b0f964a, 0x51e51170, 0xf320df4f, 0x1a8b05d3, 0x7af90c8f,
- 0x31e69f86, 0x6ba907fa, 0xd26ed23d, 0xa769bc6d, 0x80f0883d, 0x01e04d78,
- 0x13e89069, 0x4fa201e9, 0x7d12afa4, 0x710ba596, 0xe913e890, 0xf13fd221,
- 0x7fa4f7fd, 0xfa4c3d22, 0x49b7d227, 0x847a44ff, 0xefa44ff4, 0xf4e6cfd5,
- 0xb71f7a83, 0x397d43fb, 0x6beb47a7, 0xf5c7fbf9, 0xb9fe9c75, 0x5ddfcfde,
- 0x433b7443, 0xba31ed90, 0x7e1aabff, 0x76edd847, 0xfd1acedb, 0x9e578ac2,
- 0xb2bfbaa7, 0x46b456a1, 0x5ab69f62, 0xba394f63, 0xf33d90fc, 0x6538ab5b,
- 0x0f5ebf90, 0xe10d26f7, 0x98bbfbf1, 0x8fdf6b6f, 0xf203e989, 0x520a9d69,
- 0x9f28297d, 0x2aba5f99, 0x0fc7f886, 0x81b5a9be, 0x74b43e5e, 0x0bfb7f7f,
- 0x87da4e8d, 0x8c873378, 0xebbbf2e8, 0xf8ceef7e, 0x1e5f831a, 0x8e3d6cfe,
- 0xf3c7f747, 0x473e219f, 0xf1eb93f7, 0xef6ad741, 0x707ee923, 0xef47fe3d,
- 0x6092f0b7, 0x1acd77be, 0x512dcb2b, 0x38c41156, 0x35cf9c7a, 0xc43c968e,
- 0xe9535c3b, 0x3eb738e4, 0x23ef1df4, 0xde2f3d52, 0x25fcdb99, 0xf2edcfd5,
- 0xe6d1f7bb, 0x8f3ce541, 0xb63e4bc2, 0xc5a35ed7, 0x43bda01d, 0x753bf396,
- 0xfc831188, 0xe1db2941, 0x7da8551e, 0x001c577e, 0xfaca47ea, 0xfe97f441,
- 0xdd178d15, 0xc4068fb5, 0x6e21e4b5, 0x93b5406c, 0x8c36c6e3, 0xb9bdf209,
- 0xded7b1e9, 0x4e22aad3, 0xd8c7e638, 0xfaa74f47, 0xefcf0266, 0xf00f73ee,
- 0x5c5a7e50, 0x53a46f5a, 0xebb5de43, 0x62e67d66, 0xe97c755d, 0x4bd7d778,
- 0x9e21b7c7, 0x5dfcf18a, 0x6eba17eb, 0xafa5eba1, 0x2ea5e153, 0x977f03fc,
- 0xfad74faf, 0xfffb3ec1, 0xb70cfacb, 0xcc7df0b6, 0x07874ab0, 0x7ad77d70,
- 0x262edcdd, 0xf1783ee0, 0xa441f725, 0x5f7cd24b, 0x8a967f80, 0xc05c1331,
- 0x81cd4b91, 0xdeb4279d, 0xef59eff2, 0x077a90e1, 0x7cd60ae2, 0xbd79769d,
- 0x1af521dd, 0x7ed60b62, 0x374ced2d, 0xe43d7ce2, 0xed1fb1b6, 0x1e3d70cd,
- 0xa3ccebc3, 0xf1a71c75, 0x96a243a3, 0xd7120fcf, 0xf1df58fc, 0xcb8f52da,
- 0xee72cc5e, 0x6e59a778, 0x514df09c, 0xd09dc623, 0xd68e442b, 0x6837e1fc,
- 0x9a275efd, 0x7bd0dfb8, 0xf26837f2, 0xf93de869, 0xf26886e7, 0x01488a65,
- 0x3c2f1a9f, 0xbded2e12, 0xd92ef183, 0x2f46926f, 0x8c556e69, 0x9f083d06,
- 0x55f1cc15, 0x8b9077bc, 0xbf9cfd71, 0xfd38045e, 0x3f7208a1, 0x22918993,
- 0x6c2123ff, 0x79039df2, 0xf55ab33f, 0x2ce427fd, 0xc2e65efd, 0xd8abdf70,
- 0x4e44af77, 0x28f78f99, 0x4b8c15c6, 0xe303bb47, 0x1c9f2cdd, 0xbcb1a470,
- 0x8b657d84, 0x6f7fdaeb, 0x6e92f9d0, 0x9106f795, 0x3a60dee2, 0xe9d7966d,
- 0x86fe41fc, 0xed0215ac, 0x71cdb826, 0x1ffb7a38, 0x6b0ac6ba, 0xfdfccf41,
- 0xfa7bb987, 0x66f3aec3, 0xb0f1a0ec, 0x7b19bf83, 0xf7cc78c5, 0x163ed8cd,
- 0x39d98699, 0xbd3179cd, 0xa74e793b, 0x26f1aee7, 0xcf7c6b08, 0x1af1d678,
- 0xcf1d4f8a, 0x2f5e02ff, 0x2fd78774, 0x37290b06, 0xa23e4a47, 0xac2ab7e3,
- 0x1f671ef3, 0xa5445c63, 0x33e9e243, 0xb87b8c80, 0x3cf15775, 0xfd17a93e,
- 0x7545ef81, 0xd43cb8a3, 0xc736250e, 0xc77f5e70, 0xef83ccec, 0x7c122746,
- 0xea7c39d7, 0xd9cbc250, 0x492660fc, 0x0d93e230, 0xfaef7c0d, 0x07aab3dc,
- 0xeaa57ff2, 0x4f01eb5e, 0x3f655379, 0x95e6f8a0, 0xc509f864, 0xa3e3eee6,
- 0xaf121d2b, 0x32b3feba, 0xa7f788ad, 0xca241570, 0x3de4d5f7, 0xe81e5d72,
- 0x8be3261f, 0x3dccfbf5, 0x232307c9, 0x1feb1f24, 0xbeaef926, 0xf38ed49e,
- 0x48cfd449, 0xf74953e2, 0xb03eb045, 0x1a4de5db, 0x78ca7f0a, 0x75a79261,
- 0x97a3bfbd, 0x5af03f7c, 0x68d0f991, 0x643f8fca, 0xef2a0113, 0xf14c2f18,
- 0x946f8564, 0xfa16bbf2, 0x44b098fd, 0xfc0cafd2, 0x611ddc20, 0x32346f7a,
- 0x8f94ce2b, 0xd533f4f2, 0x6a95198f, 0x0ef58f2a, 0x4fc79531, 0x7be537cc,
- 0xaa655d17, 0x58f667df, 0xefafbe53, 0xa4fd5306, 0xbca669f2, 0xe49297ce,
- 0x76a03127, 0xc0fda9ae, 0xfd5312ba, 0xf9857f14, 0xf7bf54fd, 0x9e025648,
- 0x697f9477, 0xbc87966b, 0x96116aaf, 0x90ef5d91, 0xde5a3afc, 0x5ce89907,
- 0x6491efc4, 0x0cccfd34, 0x8a8dfa8f, 0x46292673, 0xae24f7e1, 0x60f99b73,
- 0x3f39a261, 0x2af795de, 0x2b9c6e96, 0xa828fe34, 0x6a929e80, 0xf3efa6ad,
- 0x347c6a86, 0x9eb2e457, 0xefeb5dfe, 0xff5a621b, 0x4e5d7c50, 0x05e7cf0f,
- 0x6f9ed2dd, 0xf9ec179c, 0x9ec0bc46, 0x9ec3cc6f, 0x7b0fac6f, 0xf61cb1be,
- 0xc179637c, 0x8c1d3321, 0x83a66238, 0xe99a8e2b, 0xd0cfa740, 0xd5b2baf5,
- 0xa7c21f4c, 0xb07f94f8, 0x6a7f575e, 0xf5d09fa6, 0xd78b0921, 0x1153826f,
- 0xfbfca48f, 0x642eb5eb, 0x87d73abd, 0xf6f90df0, 0xbe50e0da, 0x48785b27,
- 0xe4b77815, 0xd79e6d51, 0x27e5ad0d, 0x7d5bb6c3, 0xae7de6bf, 0x5f4355d1,
- 0x871d5749, 0x1f070f9e, 0xffa4347d, 0x02f9fbd7, 0xfe3b3fa8, 0xf41db262,
- 0x45df2ed1, 0xee1f036b, 0x49b715dd, 0x77bcba7a, 0xe39533f2, 0x9a598e18,
- 0x82ebf014, 0xf036df18, 0x6bb39bcb, 0x1367f815, 0x458ed145, 0x8ff9cb88,
- 0x17e464b0, 0x77f7940c, 0xdf2b7645, 0xe2f9d07f, 0x17192482, 0xf35432d8,
- 0xdc647af3, 0xa543f3ce, 0xe3ca24dd, 0xe2e338e2, 0x83bf796c, 0x05e499d4,
- 0xe1c7c039, 0x47c041f0, 0x69df85b3, 0x39b9b56c, 0x86ffc46e, 0x83f7e02a,
- 0x72f90b1c, 0x35df2680, 0x0070e47c, 0x85eb41fe, 0x1c1d9ce9, 0x5be29870,
- 0x99736e87, 0x892d39f2, 0x76c3faa6, 0x79e54dbb, 0x79532cc1, 0x298f21c1,
- 0x28c8e23f, 0x8e2bfd53, 0x2bf94d7a, 0xea9a275b, 0x9169fd5f, 0xda249f29,
- 0x077e061f, 0x3e8f522a, 0xe2553433, 0x7e382dc9, 0xb19dc16f, 0xa6a7def2,
- 0xba72eb5f, 0xd3ecf71e, 0xde5439e8, 0x71f7681f, 0x5f43751c, 0x187be1e1,
- 0x129f4d0e, 0xa7c03d66, 0xde772dc5, 0xe39bf0a3, 0xe578f596, 0xd3417d4e,
- 0xdd39740f, 0x35ecaf10, 0x082f2bc6, 0xe03dfeeb, 0x3dd6d2ff, 0x7681fe14,
- 0x9f86df39, 0x88def9da, 0x3c28570e, 0xda38b533, 0xefee8e2d, 0x25b2d8f5,
- 0x1465259d, 0xfef41dfd, 0xcad3cd98, 0x365fdd6f, 0x4fd5a79e, 0x0bf0d5f4,
- 0xfba567bb, 0x305bc7bb, 0xbe67ce4c, 0xd4f372c5, 0x32cf8e6c, 0x3bdf83bd,
- 0x51fdea5b, 0xf3b74ab9, 0xe323105b, 0xdd8c44a7, 0x79edfa0d, 0x44cf893c,
- 0xfbe468bb, 0xff9c5a47, 0xee5b6b4d, 0xf3454419, 0x7bda4ded, 0xe81b0160,
- 0x9258d261, 0xd884f2c3, 0xb35765b6, 0xc7a2e493, 0x3f6cacea, 0x35ddbfe9,
- 0xceb8248b, 0x49031bfb, 0x407d01ef, 0xb4be81b6, 0x71e54721, 0x1b9ec1ae,
- 0x4df6fd81, 0xfb3d9c67, 0xced08405, 0x754fa90b, 0x874c6f43, 0xaffe3cfa,
- 0xf143ede3, 0x42adeba4, 0xd74c338b, 0xd7f1d2e0, 0xf0d07769, 0x707fdfa7,
- 0x6d15b32f, 0x8a3df272, 0xd2db8889, 0x4725afd7, 0x86ad65d2, 0x3f03d40f,
- 0xa15ea9ea, 0xfb031d9a, 0xc7708772, 0x43a1bab8, 0xc2bffd3d, 0x9eff8e8b,
- 0xc4f557ee, 0xc2f9421f, 0xeab7dd77, 0xd9ff4e89, 0x3e06577b, 0xb468e321,
- 0x5ba40975, 0x677d3fd8, 0x6f3f7994, 0x8d7696cc, 0xa2beda71, 0x6799ddf3,
- 0xf60217e6, 0xaa5586f1, 0x39e42fc6, 0xc4529c5e, 0x3a8b11ef, 0xe533cb17,
- 0xcfd62f1a, 0xc80f85d7, 0xf5aee0f7, 0x455c2516, 0x9b6692f9, 0x15a048d8,
- 0xf38fbbfb, 0x1b93bf66, 0x449efe71, 0x3726cdc0, 0x49b4b71a, 0xb94fec09,
- 0xc5ecbdfc, 0x5c7ef94e, 0x8bd9bbe8, 0x2f17fd35, 0x86df602a, 0xcfee65fa,
- 0x8f6bced6, 0xe12b7cf0, 0x0ba5bd67, 0x02de8d7e, 0xe8311df2, 0xf3b4aac3,
- 0x8e969c70, 0x24fc3737, 0xc2795df1, 0xce16446f, 0xb76b46f3, 0xf89d7471,
- 0x9d2afdd5, 0x1cc3c27e, 0x171a1faf, 0x4affd670, 0x1a7e7774, 0xd3d37fdd,
- 0xdff4e83e, 0xa85f877c, 0x1e8969c3, 0xff043e05, 0x57e8dbbf, 0x8248f3f9,
- 0x3127fd90, 0x6ab48ff0, 0xb98d89fd, 0xf44fdddd, 0xf1c5d8ad, 0xbe2cab10,
- 0xf25c40ff, 0xef1fea19, 0x3ce5deb0, 0xf8fb8090, 0xd3bb3493, 0xe4d6f3e5,
- 0x7ef2d1b0, 0xe55f8740, 0x2898eef5, 0x1f1373ef, 0xba77d815, 0x08aa7f1f,
- 0xfbaa42f6, 0x466b7c49, 0x3f75fe31, 0x14707149, 0x61b339c3, 0x484f0db1,
- 0x7b7c3eb6, 0xcbbb8461, 0x403ad27f, 0xe4f4e7c6, 0xc97e9947, 0xb8cdfdc3,
- 0x73f71574, 0xca453b2c, 0x2cf78d6b, 0xd90d9d03, 0x67986c26, 0xdffbadab,
- 0x23929819, 0xf852d1f7, 0xe21b7bd2, 0xac28567e, 0x84572c07, 0x7cc4071e,
- 0x6c5fcf5e, 0x3285f2d2, 0x992acb7f, 0xc5ded56f, 0x3bd9aada, 0x98a44f30,
- 0xedf0f40f, 0xf3043d9a, 0xe0798a40, 0xf21af83b, 0x83c86be0, 0xbe0f21af,
- 0x0d7c1486, 0x51444bdf, 0xfd2a9e72, 0xfb0de33d, 0xf19efe03, 0xfe09b906,
- 0xfe1e631e, 0xf87d631e, 0xf0e58c7b, 0xe1cb18f7, 0xe1e631ef, 0x87d631ef,
- 0x8798c7bf, 0x1f58c7bf, 0x1e631efe, 0x7d631efe, 0xe58c7bf8, 0xcb18f7f0,
- 0xe631efe1, 0xd631efe1, 0x58c7bf87, 0x629d737e, 0xacdd07f2, 0xba503bbd,
- 0xa3e98e3e, 0x2928b539, 0x3ff7d687, 0xc7e7ff23, 0xf3ac54b6, 0x6efc25de,
- 0x47845560, 0x44d373ae, 0x2116eeb9, 0x0e7db9d7, 0x76edf3af, 0xf1942f99,
- 0x03f4a1c2, 0x74f8cabf, 0x0a4157e9, 0xf8520abf, 0xafc29055, 0xfd2ade32,
- 0x57e1482a, 0x55f877c1, 0x82afc290, 0xa4157e14, 0x8520abf0, 0xfc29055f,
- 0xbf07682a, 0x55f8520a, 0x157e1df0, 0xe0abf0a4, 0x038231fb, 0x2e1d15fe,
- 0x26e9f9c8, 0xd0e8943d, 0x4cba87a4, 0xc6f9c879, 0x8df390fa, 0x8df390e5,
- 0x8df390e5, 0xc6f9c879, 0x8df390fa, 0x88f11bf9, 0xef296f71, 0xde41db1b,
- 0x9a73e637, 0x86c1affc, 0xf9c37935, 0x46b69157, 0x2e298f29, 0x9e72eb92,
- 0x58ff059a, 0x1c92b86b, 0x763921eb, 0x8d676fc5, 0x89f892bf, 0x2b976f16,
- 0x6f582dda, 0xbad37bf6, 0xe38282f9, 0x3bfe7383, 0x7f75cb91, 0xbad1ff2b,
- 0xac14ede7, 0x90cb6c37, 0x3dede970, 0xd522a5c2, 0xbbe577eb, 0xbe3a17af,
- 0xa5f98f5e, 0x28520e01, 0x910710f3, 0x1f33bb77, 0x2d5bedf1, 0x5d0b8c8a,
- 0x4372e329, 0xe349aae9, 0x3b2d5b4b, 0xbb50440e, 0x83c562f6, 0x5699077b,
- 0x0f96c871, 0x43e6d53c, 0x89cba89e, 0x6b83e2d5, 0x903c42af, 0x7f6eb70e,
- 0xf7c13e24, 0x0bb746dd, 0x738d197b, 0x8ec217cd, 0x64985bdf, 0xda04f297,
- 0xea1cdf41, 0x0c9bbc57, 0x4732bdf4, 0xff3e7b9e, 0xe8caabb2, 0xb5edd0fb,
- 0xdd1ee157, 0xeed908a4, 0x33478f37, 0x2a34a71e, 0xc9fef09b, 0x8bc2ede8,
- 0xd4bfb1fb, 0xddba1ee0, 0x71e32f65, 0x4eff7c5d, 0x4378b7ef, 0x2c17df32,
- 0x13e3ad16, 0xf0a127d9, 0xde3ae6fb, 0x62af7e68, 0x0fe2c47e, 0x2ffc8ec1,
- 0x7121c3df, 0xc3dcfbf1, 0x6c7866b9, 0xc4dbe221, 0xe40ef95e, 0xabc5e1e4,
- 0xbe5c137a, 0xf2077c80, 0x5f6a2f9a, 0xf966fce3, 0xcf93240e, 0xcf8f8648,
- 0x857e41c3, 0xe298ffdf, 0xe5e968df, 0x15e0bdc6, 0xdfd404b6, 0x0b503c2e,
- 0xaf790906, 0xb6579f55, 0x57096238, 0x95e22f40, 0x11fd0378, 0x7a0198e7,
- 0xf8d8f3c9, 0x56a9907d, 0x46fc0d97, 0x5d8a7397, 0x7542ec72, 0xf7df0c74,
- 0x2e13910b, 0xb8e6f636, 0x8e3d7f8d, 0x93ef83a4, 0xce15df2f, 0xf88f8572,
- 0xb9e6f807, 0x5977193c, 0x91c3ecb9, 0x38aed496, 0x8129d392, 0xf3df78ad,
- 0xe88eea74, 0x11cb0a51, 0xdb5fc087, 0x7be79f1a, 0x5eabc582, 0x1710fbe3,
- 0x96881f1b, 0x7fa4aaf7, 0x9bc34ca5, 0xa85a6f6e, 0x16994fad, 0x5ebc743f,
- 0xe74bcfbe, 0x71f7bf30, 0x72c6d1b1, 0x28bca846, 0x880feb84, 0xb46f2b73,
- 0xc5d3ddf1, 0x27578b6b, 0x777eee8a, 0xcfe32bc5, 0x349771b5, 0xa84e38da,
- 0x2b477b5c, 0x965877f4, 0xd2e8726a, 0x27efe66d, 0x4fe44272, 0xad44fdfd,
- 0xaf5bf14e, 0xa83964cc, 0xee71c6d6, 0xb94857f3, 0x0110ec48, 0xbf9867dc,
- 0xef059c62, 0xe5dfcc58, 0xd0dd28f5, 0x7c9a3bd1, 0x12830934, 0x8a5ea7de,
- 0xed32be60, 0xcfce3f52, 0xe9c894ba, 0xe4b2978d, 0xd11dac77, 0xbca16b4b,
- 0x26beff5f, 0x1c44cd17, 0xb2e40165, 0x1dd74c3e, 0x2218d744, 0x4357e357,
- 0x302bcabc, 0xf9b24fc3, 0x734e2156, 0xf7c146d2, 0x7e432691, 0x90d982a2,
- 0x2fb00aa7, 0x3ef90a52, 0xef8544c6, 0xbe1e4cb7, 0xb407db4c, 0x11f3042f,
- 0x37c3f77e, 0xf1006a7e, 0x3b7db337, 0x7d77582c, 0x6dfcf83f, 0x64e60efc,
- 0x7bc762bf, 0xcf4d3e81, 0x743de9d6, 0xd4882c5f, 0x694e63ec, 0x8fb4eaff,
- 0x9c7e5801, 0xc446f227, 0x2d802eb3, 0xb0b69fb3, 0x6ca8aa84, 0x1b9c9e59,
- 0x94236379, 0x6ed37fac, 0x9162df32, 0xfe489ff7, 0x717578e3, 0xe50fb0a4,
- 0xf92ad78b, 0xe1d79788, 0xd8d87afa, 0x777ac349, 0xe74941d1, 0x03eeccfe,
- 0x5df960bd, 0x4cff2619, 0xf84a5a68, 0x105a3ec6, 0xfc63fad3, 0x5c84d0d2,
- 0x889f1de1, 0xf9f5c877, 0x02e2208a, 0xdbf96ae7, 0x8ff2bd9e, 0x278c9c6b,
- 0xedcd8fce, 0x3fe22377, 0x38fe65fe, 0x7f1ab15f, 0xf14daa37, 0x3de57379,
- 0xdf5809c8, 0x7e76ecc8, 0xa66660c7, 0x212f9e4b, 0x72db9676, 0x845df2dd,
- 0x694b7b10, 0x846f3cb6, 0x8f3c9dd5, 0xb66e3afd, 0x3ef3ea57, 0x33df336e,
- 0x5cead3d5, 0xbff83769, 0xa0f127ba, 0x7ffbde45, 0xf1d812c4, 0xa06bd122,
- 0xe6016fb7, 0xbde208fb, 0xcf1f7e19, 0xa3477f4f, 0xef694f93, 0x74f4e865,
- 0xdf22eeac, 0xda712897, 0x9e81aadd, 0x7c28d6ca, 0x4ea4b11f, 0xadf627de,
- 0xfcbde451, 0x8f57ec1e, 0xdf9af9cf, 0x17fc7a51, 0xc350b211, 0x91fb7cef,
- 0x5d291cd7, 0xdd53fdf8, 0x7f926caf, 0x6f103306, 0x9c36b73f, 0x7afe41df,
- 0x018fd158, 0x87b6647f, 0xf11269d7, 0x1a9fd434, 0xbe29fbe3, 0x07238897,
- 0xf05c6f61, 0x7df8b7f3, 0x29bd9ae1, 0xf161eefc, 0x78d5bcee, 0x61ebe547,
- 0x89723bbe, 0x2e9d8b7e, 0xea90e43b, 0x973e58c6, 0xeed1f417, 0xf6768ba9,
- 0xf3ebe9e7, 0x0794ae60, 0x9c723c8a, 0x453e9a0b, 0x354db308, 0x7fe793d5,
- 0xedd43ee8, 0x95f6a1a2, 0xbe2af7d0, 0x7b029ecb, 0x5760dd89, 0xb631edd5,
- 0x7073e3ac, 0x77b7cf9e, 0xaf8dbbff, 0x4d4776eb, 0xa9d85d9f, 0xe84f66cf,
- 0x9d7fb903, 0xbd1d82e2, 0x11bee9cc, 0x8765f5f1, 0x14f0886c, 0xf2dce293,
- 0xe4bb92dd, 0xb72525bb, 0x9b3f31e6, 0xc7c9358f, 0xbc5187bd, 0x9402cb8f,
- 0xdfbcf7c6, 0x657bade7, 0x53d01ec0, 0xe0f7cbd0, 0x7b5e5ccb, 0x2a2e419c,
- 0xef4c526d, 0x17f9e818, 0x721da573, 0xc019a93e, 0xa6b74ddf, 0xd086f1d8,
- 0x108f127c, 0x46baf837, 0xaa3b7a27, 0x932571c7, 0xf941c552, 0x9dc114ae,
- 0xfe33c722, 0x9349514e, 0xaa063df9, 0xfedd72cf, 0xafee28dc, 0x4ef345d8,
- 0x3862ea41, 0xa78c0f09, 0x3fa87bf6, 0xebc38f37, 0xd80c1a51, 0x8f983760,
- 0xcfca1678, 0x186c0575, 0xbe51a4a7, 0x2b5be28f, 0x89adf1c7, 0x2e40e7b5,
- 0x03ecbab0, 0xa360f28c, 0xbe78cf7c, 0x0411fbf6, 0x65cbcb2f, 0xf3dc2784,
- 0x867defd2, 0x8358abe2, 0xd629acbf, 0xad365f2c, 0xe67d61b3, 0xc35ef0f4,
- 0x971d1a97, 0xfbe18e34, 0x2f5665f5, 0x69f097df, 0xb2ebfef8, 0x27e1bbf0,
- 0x90fcd399, 0x8d79052d, 0x3c097d2f, 0x829e06f7, 0xd23efc19, 0x678e70b2,
- 0xe26ae39e, 0xfbe276f9, 0xe40fc201, 0xe3115715, 0x8fc4e89b, 0x66b2c038,
- 0xc176faf3, 0x65df2513, 0xfde62e6f, 0xb3eac8b7, 0xac708cbb, 0xfb819fdf,
- 0xdf68735b, 0xe127fde3, 0xcc7df1f2, 0xc8dc0f53, 0x3806fbbf, 0x8f28e781,
- 0x3bde027b, 0xba61ba22, 0x4167e9d6, 0xfacfdc81, 0xacc35178, 0xec3f0ed2,
- 0xf7a9f6bb, 0x06f3e420, 0xffd86f5a, 0x76a7da7b, 0x71a4005c, 0xddf265ed,
- 0xab7dd0ba, 0x9f7d57ef, 0xdf56fbea, 0x8ad98fcf, 0x174a8982, 0xbdf3a1df,
- 0xf06eb9f6, 0x77834934, 0x84aeb6ae, 0xc18557d7, 0x986237ae, 0x53f3dfdc,
- 0xfd1ffbcd, 0xbd54dfa1, 0x03306c7c, 0xfaf53df7, 0xe3f3b8fa, 0x03ec3b64,
- 0x30ea5bd0, 0xe5fd674b, 0xe262df5c, 0xfc9da51f, 0x04aafb63, 0x0a1d8ff0,
- 0xdf96e1fb, 0xe5bee523, 0xe17bc8cf, 0xf8bf9667, 0x77aa2cf6, 0x0b8dc1fa,
- 0xca2ff78c, 0x2c5f9282, 0xfc0b7924, 0x0f269163, 0xe5f4cc6c, 0xe7ec330d,
- 0xc99ffbb2, 0xdb98fec4, 0x6f0a7792, 0xf9bcd1a8, 0x3f3fa3bd, 0x5787d2f3,
- 0x5dcebbb9, 0x6b251e7d, 0x3b15b5de, 0xf493788d, 0x0756777e, 0x38a55b9f,
- 0x6953e8b7, 0x61f33163, 0x8f7a4891, 0xa1eeb5d2, 0xa8dc50f4, 0x5a579cb0,
- 0xfea03237, 0xd2ebf22f, 0x8df953b5, 0xf4bd7d28, 0x73f45f77, 0xa67f8757,
- 0x35734eb6, 0x4c3d9e7a, 0xe5b9c3ee, 0xbc45f629, 0xf8ec53ff, 0x5a39cdbd,
- 0xf3329cf9, 0x72f5cef7, 0xd5fbf275, 0x9fb827d8, 0x58eaf584, 0xcbf6936b,
- 0x57ad97ed, 0x1d02e432, 0x9d9ac58e, 0x6f66a172, 0xcbc9a45c, 0x8d8b5eb4,
- 0x71f8b5eb, 0xcfa55eb9, 0xbc17f5be, 0xd3f34653, 0xef93a3de, 0xecb4940a,
- 0xb39b75e0, 0x852d9d66, 0x5864fdea, 0xa8fe298a, 0x05cf36b4, 0x35dcfd3b,
- 0x07e06d1b, 0xf126193f, 0xf3f74a16, 0x1d62f8b5, 0x148f38af, 0xaf473f83,
- 0x83b83e0f, 0x5975b9c6, 0x77f1b478, 0x3d1a02ed, 0xc6c6d697, 0xdad2bc61,
- 0x7fa17be2, 0xe840e7e9, 0x2e113bfe, 0xf50945f7, 0x6279fd87, 0x55ef878c,
- 0x377ed7cf, 0x43feb42f, 0xdafddd1a, 0x4cbfdf26, 0x92796c8a, 0x226a3be3,
- 0xe913e03c, 0x8c01ade9, 0xdc067a0b, 0x2f7c8b76, 0xf5b2bd33, 0xa241c073,
- 0x20f5c73c, 0x105b7bc5, 0xbf2813ed, 0x79ef22c9, 0xdd32aaa5, 0xa607e1a7,
- 0x5e8b9437, 0x5f1efcad, 0x2151bbe7, 0x9b176af4, 0x1fdde0d7, 0xefc12f7b,
- 0xa9f4e9a6, 0xa7d3a3f7, 0xcd3dbf4e, 0x9cf7d76f, 0xcd1489df, 0x49e592ce,
- 0x0bb8d076, 0xbfc41bee, 0xf35df16b, 0x35ef6bb4, 0x4c37ce76, 0x65c7defe,
- 0xfa974df3, 0x6df3cf52, 0x66e84c2e, 0xd4f3a1be, 0x431e89f7, 0x694fe9df,
- 0x1394fe92, 0xd4639d0a, 0x70b2c4ee, 0xe7d3ab8e, 0xbff5dba5, 0x8f87bdef,
- 0xf669c586, 0xc828d6aa, 0xdfb5f397, 0x99411151, 0x86a9f7c7, 0xaff9faef,
- 0xf3a75fbf, 0xdab593e9, 0xef5a28f9, 0x75167ec1, 0xf50f7c69, 0x2889d358,
- 0x627313bc, 0x6f4f848c, 0xde4dab77, 0x76511673, 0xbbcfde37, 0xfe3cd6e9,
- 0x8d8594bd, 0xbd9f587d, 0xf98d2ea9, 0x587e4dc2, 0x1ea74517, 0x83e348b0,
- 0xaf16b791, 0xd7f502be, 0xc2eff0a7, 0x4e7a742d, 0x43f6e7ad, 0x2313903d,
- 0x53daa79b, 0xfa961e59, 0xbb17ee82, 0x7c451155, 0x127c0d4f, 0x3fb2cbfb,
- 0xe2cfe71d, 0x983f52f5, 0xe06b1164, 0x50d81d3f, 0xf82fa134, 0xfc8ac3c4,
- 0xe60d9a3d, 0x0e86bcf7, 0x7c02fa2a, 0xbc5df426, 0x5e2d6d5b, 0xe482a7e8,
- 0x16d1d80e, 0x9e588b3a, 0x93e345bf, 0xf8db9ac7, 0xaf1d7ebd, 0x78bfe08f,
- 0x7ec42aa7, 0x1a276a14, 0xff07d9a8, 0x7b8faf1f, 0x0080003d, 0x00000000,
- 0x00088b1f, 0x00000000, 0x7cb5ff00, 0x65545c0b, 0xce7bf8da, 0xc0cc2b99,
- 0x1245c880, 0x85848b87, 0xd780c034, 0x508151da, 0xb9bba0bb, 0x658e21ba,
- 0x500665ca, 0xd7775ddb, 0xa6a18cfe, 0x45fa7d66, 0x80ed65a6, 0x76c36a97,
- 0xa8283448, 0x59990bc9, 0x6a37627f, 0x5b63b92f, 0xba402de6, 0x6dbfedfc,
- 0xbcf3cf7d, 0x511730e7, 0x6fbefddb, 0x797bf9fc, 0x9f5ef3df, 0xcfbcf3fb,
- 0x8c346339, 0x63181b75, 0x418e8b2a, 0x89486839, 0x8d8c9964, 0x615f6909,
- 0xf6c3894c, 0xc645db25, 0x7cfb4046, 0x1962c893, 0xfa31d72b, 0x1fbf8f7d,
- 0x3c1f7631, 0x42f3c337, 0x07d634a9, 0xcc37d7fd, 0xd6c972a0, 0xf1ae6dc2,
- 0x2509258c, 0x606393b1, 0xb66ae3c0, 0xce258a07, 0x2b307719, 0x8da4d3cc,
- 0x73c325d2, 0xc7292bb5, 0x496f9fe0, 0x0c4943e3, 0xd4699dc6, 0x7b4377cf,
- 0x414e6981, 0xba5f8c14, 0x325b2a33, 0x6f5dfbfb, 0xc91b1811, 0x4673a558,
- 0xcc614b1c, 0x67e1ddf1, 0x1fb0a94c, 0xf304d398, 0x7709e57f, 0xa38ba0bb,
- 0x82492dae, 0xb3aa3c23, 0x7fa058a7, 0x6f31d895, 0x4e73cc12, 0xa04def70,
- 0x5338e6fe, 0xe5a1fac0, 0xccc63ae9, 0xff398ce9, 0xcf3487cf, 0x3b89e2e7,
- 0x8778c016, 0xce047f73, 0x1ff8f553, 0x6c3201f2, 0xb2cf689d, 0x8dbce1e4,
- 0x1c124d7b, 0x56637b74, 0xbee39c09, 0xda46c7c7, 0xf79f2f33, 0xa8b668b6,
- 0xdbcbda04, 0x6957c118, 0xd48ee85f, 0x5eeddc20, 0x696131a6, 0x28689a62,
- 0x956c48cf, 0x52dbca07, 0x06b9a2d8, 0xe10dbb7f, 0x899eeb00, 0x025492dc,
- 0x9f7b15ed, 0x79433248, 0xa5ebc8d6, 0x9c7a7f7b, 0xddff4045, 0xd5e20d5a,
- 0x0b1a62ae, 0x25d7bb8c, 0xb250dcd8, 0x12c668f2, 0x7d6ea310, 0x59b19199,
- 0xaf9a7096, 0x630e7b62, 0xc17dfeb9, 0xab3f6a73, 0x8fb8c562, 0xd903f531,
- 0x8bfca1cb, 0xe21f7bca, 0x7ab52ff3, 0xf1192b8b, 0xfcbc2662, 0x84548b65,
- 0x05fbaeed, 0xfac05636, 0xac1a637e, 0x6ac9165f, 0xf4a17c71, 0xcf049b57,
- 0xb2101c57, 0x787b30b5, 0x1ee6b766, 0xd1169103, 0xd389b559, 0x75768ad9,
- 0x7fe02251, 0x2d408b45, 0x3357950e, 0x2f2abe1c, 0x80e6664d, 0xb6b656fd,
- 0x8eb0cc68, 0x09ce19a3, 0x539e1dfd, 0x5e78a59a, 0x7cb185b6, 0x89fe27c0,
- 0xa53e6bf8, 0x3f0037b9, 0x2e1cadd5, 0xbede56ce, 0x3b900338, 0x1362b699,
- 0x26dea0d2, 0x6b3ebd50, 0xaa35fcc2, 0xfcfe7ac0, 0x9a586935, 0x354c4e08,
- 0xf0025490, 0xa3d194dc, 0xd73bfc41, 0x5d42f3ca, 0x0d5eb01d, 0xde48e512,
- 0xf1c06a9e, 0x3caf1a66, 0xd146b677, 0x6c33af78, 0x3609bb03, 0x61506d51,
- 0x4434ef59, 0x56b3b960, 0x715950cc, 0x09166173, 0x1611dfe0, 0x6122c591,
- 0x3d5eaaca, 0x3b501240, 0xf6845870, 0x83fb48dc, 0x0c719f48, 0x33e802b8,
- 0x06057991, 0xf9dfdff4, 0x7fce2e59, 0x17df18cb, 0x5eaeb60c, 0x017e7d33,
- 0x8b26c3d0, 0x5f4c8e7c, 0xc8f1d22e, 0xb0af4043, 0x6cd5a7bf, 0xcf073e83,
- 0x42e6c257, 0x08c2cc3b, 0xb984dfcf, 0xafdfc0f7, 0xce226f31, 0x54de74cf,
- 0xcc9af71c, 0xc35a25a7, 0xf5f60106, 0x63fb149b, 0x053b8fb8, 0x116cf8f5,
- 0xc58d2071, 0xfe6afd7e, 0xc2796d9c, 0x4ffc03a6, 0xa367e8e7, 0x4062e645,
- 0xf1519aa2, 0xc163a406, 0x60ab6366, 0x0f3307fd, 0x2e80cbdd, 0x31d01e1e,
- 0x5eaf9c2d, 0x7d3dcfcf, 0x0094ec20, 0x2a8f46fd, 0xf4165916, 0x2958ab37,
- 0x29943ff4, 0x9fd8557a, 0x9fd8dce9, 0xbe6d0ae9, 0x8196590c, 0x7a88d0fc,
- 0x78eff51b, 0xca011bf3, 0xe1e2e944, 0xe2573848, 0x3d4b052f, 0x3c1b29f4,
- 0x85fff4fd, 0x5352f4b2, 0xfca1efcb, 0x19bda475, 0xb0727751, 0x501d94f8,
- 0xa3c9b0f6, 0xf9f264b3, 0xf1dff702, 0xa2226fab, 0xfabeff45, 0x7bef4e07,
- 0xcea58ad9, 0xe9b8c022, 0x9b57921d, 0xfa7ef975, 0xa9e361e3, 0x39e18fd4,
- 0x5ba20dfb, 0xe1ffb010, 0xd37f710f, 0x14af0675, 0x17d4e381, 0x38ff3a7c,
- 0x751d1e66, 0x284646fa, 0xb1913ef8, 0x8c3cdc58, 0x7068b81f, 0x6fb9c137,
- 0xa14ff991, 0x488b1eaf, 0xf191e9f8, 0xe991c0a4, 0x7e9122b2, 0x5e8ad5eb,
- 0x4cb385f0, 0xe8d67f3f, 0x5e0cff38, 0xff386d12, 0xcdd6b960, 0x8ec18a60,
- 0x5727d254, 0x007fa792, 0xd740ca79, 0xfb6a97bc, 0xf90fc233, 0x78fc074a,
- 0xc02f0c97, 0x25f9c33f, 0x64bbfe79, 0x1065ddb8, 0x127e9c39, 0x6e992702,
- 0xf650ba14, 0x5863982f, 0x9f1fb469, 0x47ddd7ec, 0x8f099323, 0xe383ffe3,
- 0xdfc213ef, 0x01d62737, 0xff51b11b, 0xfc784598, 0x579fc05f, 0xf80bfeb4,
- 0x9fc50eeb, 0xe23d7f57, 0xd2d171ef, 0x0880fc84, 0x26d2a1c8, 0x0658f9c2,
- 0x932ffe23, 0xe09b2cc2, 0xffe4767c, 0x8fef889b, 0xfc2bdf22, 0x37d8a63e,
- 0x49e4f51e, 0x7dc19ec6, 0xb50f44f9, 0x10a766a7, 0xbac75f9f, 0xf01db013,
- 0xf117379c, 0xe876d82e, 0xfb7d2c24, 0x5df5865e, 0x1ecb0615, 0x5bbf6f38,
- 0xfe61a974, 0x8ef72886, 0xc36eb0a5, 0x1716995d, 0xd59633b6, 0x3ca07286,
- 0xbe7a82cc, 0x85cb8a21, 0xa4e90586, 0x277e0f87, 0x73c2ad25, 0x34b3082c,
- 0x6c86ff41, 0xa01323df, 0x6cd630de, 0x57d74171, 0x1dbe9605, 0xd1d1cfc7,
- 0x38730d3a, 0x323c36dd, 0x057a8dda, 0x7af3cff4, 0x1e593fa8, 0x0d9cf0c6,
- 0x6884b68d, 0x2297cba0, 0x61b3a3ec, 0x4e24a3ff, 0xd0c90dd7, 0xa136e50e,
- 0x387dc164, 0x6fbe78df, 0x17b082df, 0xfa2cc2f7, 0xd0591034, 0xb195727e,
- 0x42a5e509, 0x73a57797, 0x75c63779, 0xc9c2076a, 0xd4659d35, 0x937ffcc2,
- 0xbb814be9, 0x556c6360, 0x0afe1fb4, 0x70c8c59d, 0x7a735617, 0xe5974d73,
- 0xd7733562, 0xe65f080b, 0x96f8070b, 0x42414169, 0xadd93469, 0xe5faefb8,
- 0xf7091780, 0x527fe1cf, 0x619ee564, 0x2847e7f8, 0x4c88f32c, 0x328fe404,
- 0x0ca3f9c6, 0x6fe908e9, 0x0051d015, 0x75df31fd, 0x65c3a751, 0x6bf1823a,
- 0x70d3258d, 0x3f85cfbd, 0x89e363e4, 0x87f34a7f, 0x3656675b, 0xf40b0397,
- 0x9fd899f6, 0x51148eed, 0xf130ae5f, 0x7f644ef5, 0xc5f51a36, 0x79bd5fc9,
- 0x23c7961d, 0x86cb6e4a, 0x7c16dbfe, 0xfce2845d, 0x353e096f, 0x0b6fe39e,
- 0xb468fffe, 0xbf56ca43, 0x43fef449, 0x192859f7, 0xaf4e5032, 0x15a67d04,
- 0xb074e4b0, 0x74463ef2, 0x896ac890, 0xfd65e36e, 0x47a30c05, 0x00f37539,
- 0xbcca8ed8, 0x9747fff0, 0xce896c74, 0xa2c69f5f, 0x7433ea82, 0x0bfd4109,
- 0xcf41c94d, 0x171f8d6f, 0x39a67cf4, 0x3b3ea83b, 0xff505263, 0x82d32ddb,
- 0x9c4e77ea, 0x8e7fd419, 0xdd504e6d, 0x1f244cc6, 0x738aea3a, 0xe1bb013f,
- 0xdc92bab5, 0xe397544f, 0xd0f6aa63, 0xe805b37e, 0x5f3bdb24, 0x91ea0935,
- 0x43265687, 0x11cb537d, 0xf43c4f5e, 0x66e03245, 0xf9d1cb73, 0x53dbd02a,
- 0x45f43c6f, 0x6d1fd40a, 0xa7cfe2e9, 0x40a362c0, 0x39bcb6ac, 0x9af805df,
- 0x8adf629b, 0xa9779af8, 0xf98a28f6, 0xbdccd7f7, 0xb942592f, 0x06746730,
- 0xc53727ec, 0xbf3e10fe, 0x759ef62b, 0x1ffb0091, 0x46ab5b7d, 0x5d98bf3c,
- 0xa1e915b2, 0xf3a722ff, 0x91978853, 0x96097eff, 0x8a61d903, 0x3c92bd9c,
- 0x03adf854, 0x1512c6f4, 0xa54749c2, 0xe544ceb7, 0x2a78baa1, 0xd999d48f,
- 0x57638012, 0xc795065d, 0x7ed42cea, 0x95226ebc, 0x546cea27, 0x4c575bbe,
- 0x095d7765, 0xb2ff0a95, 0x6a0d96bd, 0x2a974224, 0x4fceb4ea, 0x63d2578f,
- 0x69d92820, 0xf9d09f05, 0x39adbd4d, 0x9d75ce9b, 0x6959e909, 0x81f9da3f,
- 0x9dfa0459, 0x3d11d56a, 0x9b74354f, 0x475e5675, 0x22fbb8b9, 0xbc118af3,
- 0x5fb02a9f, 0xfd1b278c, 0x030ea998, 0x841b4bf5, 0xefd8597e, 0xf79404cd,
- 0x16356b53, 0x509e63b4, 0xf61e9733, 0x90df146f, 0x20e31d70, 0x05d86cca,
- 0x903ad518, 0x6ba07157, 0x63f439f1, 0x0f77283a, 0x4746f5f2, 0xf9472ed7,
- 0x60ccba34, 0x95f2e7a9, 0x08e24be4, 0x2fee026f, 0xda86a571, 0x198f628d,
- 0x9d5f60e5, 0x69d21677, 0x0ae72c81, 0x30ef5c34, 0x80bde411, 0x576dfb7c,
- 0xedf3da22, 0xd02f9edc, 0xfa44ec96, 0xfe7156ae, 0xf77a3165, 0xd5475c1e,
- 0xf42cf15d, 0xb44d89eb, 0xc568426c, 0x6069641f, 0x14d617b7, 0xeddca267,
- 0xaf885b61, 0x13fd5ec1, 0x338fdbd2, 0x9945df81, 0xf89e6048, 0x4da6f0e2,
- 0xd7adda02, 0xce5d21e7, 0x300f9ad5, 0xf65f07e0, 0xdcfbd100, 0x7a1e7348,
- 0xafecbe0a, 0x7cce3d79, 0x26e78040, 0x00bf3036, 0xe9cf55ea, 0xf0049f4d,
- 0x1513d3a9, 0x4b69af54, 0xc0127d30, 0x07f855a7, 0x09b747fa, 0x0ebb942a,
- 0x04a72b79, 0xb7c405fb, 0x0d73f8b3, 0x0680dfdf, 0xd98bd8ed, 0xb06fa266,
- 0x0fef4997, 0x9bba34cc, 0x2371bf60, 0xa057b36a, 0xce6994fd, 0xea497ec3,
- 0x63f40881, 0x1555bffa, 0x19efc9bb, 0x78c9f888, 0xd33d7d3f, 0x287b5121,
- 0x70e6b5dd, 0xcd26af7f, 0x50f119b0, 0x51d3af1d, 0x88b171d9, 0x92569d91,
- 0x4db97686, 0xd0cbfdc3, 0xb8737bf1, 0xaf5e491e, 0xa240b921, 0x0b6cb608,
- 0xc5dd4a63, 0xf8d63226, 0xbf21b08b, 0x34c9c007, 0xc83f6563, 0x41476235,
- 0x1b7f505a, 0x8e7a1ff6, 0x8ff31cf6, 0xbb49794f, 0x5e4aad63, 0x2965e90f,
- 0x183fa373, 0x72abc72a, 0xc0b965a3, 0x8c74fcf1, 0x9cf111be, 0xe77d0126,
- 0x504cc950, 0xb2338626, 0xd75f1337, 0x773e91bb, 0xa7fd39eb, 0x2ddcbc89,
- 0x309afef2, 0x577a42e6, 0xb94d87fc, 0x79b929f6, 0xe6978f34, 0x91b25a91,
- 0x879813ae, 0x24ec57d6, 0x43d81fa5, 0xaa02127a, 0xd7c47481, 0x161c4954,
- 0xa672279e, 0x448ce515, 0x4fb1b0fe, 0x5f77e403, 0x40aac478, 0x78e355fc,
- 0xe9b8e043, 0xef194e34, 0x4fb2255c, 0x245c9047, 0x89a6723a, 0x4b562fe4,
- 0xfe8088ec, 0xa0d6eb16, 0xf5c6539e, 0x14fc1c82, 0x9047f0f0, 0x087e588b,
- 0xffd710f2, 0x2c43c833, 0x10f20aff, 0x3c824fdb, 0xf207d2c4, 0x063fdb10,
- 0xbce58879, 0xe4568dbb, 0x69b69a9f, 0x7e20d3ec, 0x017ddb50, 0xc369def5,
- 0xa64391d3, 0xe1e4dea3, 0xe1cbaf9f, 0x2def457e, 0xa0fd9f1c, 0x00ffd1bf,
- 0x8a6b5cba, 0xef1eb2be, 0x1ef9b237, 0x7cb6d380, 0x27f4876e, 0x1cd2faf0,
- 0x226dd535, 0xb7e38edb, 0xfaf86be5, 0x3e396229, 0x79f345b7, 0xb245d37b,
- 0x9e4ea69f, 0x9e0724b6, 0x3da162db, 0xbdef5fc7, 0x8db73f81, 0x7a43ede2,
- 0x253e7e56, 0xeff8a4d7, 0x652fdce9, 0xbd012764, 0xff4afcd3, 0x3e7226f7,
- 0x4eefed0c, 0xc3dd8b13, 0x992de3c0, 0xd02f896f, 0x483e469e, 0x6a8be00e,
- 0x4285f133, 0x55fd0a87, 0xa73872e5, 0x073a6569, 0x43f042dd, 0x3a72831d,
- 0x25f64f4e, 0xe0c6c5c0, 0x9905bb3c, 0x01f9425f, 0x0a07d44a, 0xa07c283f,
- 0xf0227bd0, 0x3fed1099, 0xf421cdc7, 0xca8f94aa, 0x358ee8e7, 0xdaf09cfe,
- 0xdfa136a1, 0x87cc3377, 0xc1c513e3, 0xfe46ef77, 0xd19a358c, 0xc87c2cf5,
- 0x1c9c3b50, 0xc2effaeb, 0x570b9143, 0x7065c780, 0x5ff2f0d0, 0x39c90385,
- 0xbf48e394, 0xfdadc8c3, 0x5db2d139, 0x44f7e9ce, 0xd21f6d8e, 0x57a0bf51,
- 0xafd0dfa1, 0xd9dac367, 0x7f39f2db, 0x05547428, 0x89eb103a, 0xcbd4ce78,
- 0x9e729ee5, 0x632e73a1, 0xc2d2ff24, 0x9e287b78, 0xc8057395, 0x0139c3bf,
- 0xb8c61ff1, 0xd81d717d, 0x4d4fe817, 0x3ed335c9, 0x567e47fa, 0xcff995b6,
- 0x6f0e477f, 0x88944a7f, 0x32fd141e, 0x8b482ed4, 0xe90664e6, 0x3f42661d,
- 0xfc4b53af, 0xe67f05ee, 0x3e871825, 0x3fe49b21, 0x71e320bf, 0x1158fe70,
- 0xafbebbed, 0x63d42e0d, 0x4e06a37d, 0x6fbe300a, 0x6436183b, 0x136ed897,
- 0x07deef40, 0xd4f5063a, 0x2c7b9005, 0x7273b19d, 0x73cfa11c, 0x73fa24f1,
- 0xa6243b35, 0x3b4a5003, 0xf4879abe, 0x6d53b4b4, 0xf6d0b8a2, 0x3d218ec7,
- 0xcc156e9e, 0xb5f49768, 0xbfa1f1c2, 0xd6e8c1b3, 0xa822ff43, 0x0665ff63,
- 0xd7ccdb8d, 0x4383f8a3, 0x7d53ef5e, 0x85c60a75, 0x1350ec66, 0x2f3e97dc,
- 0x3b3ed1b9, 0x0aa57dbc, 0x02dda7eb, 0x4571838b, 0x04aeead2, 0x2d3e57a8,
- 0xce30b458, 0x8b3a2861, 0xe7ca82f1, 0xf30bc599, 0xc918b657, 0xa0da5dcf,
- 0x6017d8fe, 0xb7bb945f, 0x29eed06a, 0x5edc19df, 0x0eb83bb9, 0xeff922f8,
- 0x00f68668, 0x8e6dfcf9, 0xcdec8631, 0xed1b2c71, 0xe3c0d64d, 0xbf7c8ab9,
- 0x71756edc, 0xcb82ba39, 0x8cbec66d, 0xea5f7f45, 0x63e92afc, 0x91cfaf03,
- 0xfea0a7eb, 0x2f1c57f9, 0xe5aa5c0a, 0x604f3fb5, 0xb79c0f56, 0x426f53ba,
- 0xfdbabfff, 0xb71811ef, 0x51f309af, 0x22bd9f7c, 0xdbded099, 0x10b926d8,
- 0xfd0ecebe, 0x56e0112e, 0x8d3de07d, 0x5f7088d9, 0xadcaf64e, 0xe31eb5cc,
- 0x64515edc, 0xdd4744dd, 0xb666a714, 0x4f38a581, 0x84debb5f, 0x2bf54076,
- 0x8ddd741f, 0xd30203f5, 0xfb471e23, 0xee964e88, 0x2da58640, 0xfbe426dd,
- 0xbc4244e9, 0x913d9e22, 0x8865af84, 0xe033c477, 0x212cf11d, 0x51bc713e,
- 0x2274e6e3, 0x73f4fd51, 0xde0abf1c, 0x1acda48b, 0xe46caf6c, 0x63b19e78,
- 0xa230b6cf, 0xe9933503, 0x7a7ef080, 0xa6bbc727, 0x14669d73, 0x08636fd2,
- 0x876bb41d, 0x77f700e8, 0xe0841d19, 0x8df002bf, 0x0e942072, 0x93dff142,
- 0xd806e5c3, 0x429fa7df, 0x7e08dbfb, 0x23c7f301, 0x1ef55646, 0xcaf5818d,
- 0x973bcfa2, 0xf8d8fb43, 0x08da5897, 0xe4157f8a, 0xe66bfc62, 0x5d10eb3b,
- 0xc85eb33d, 0x57a97a46, 0x813cf6fb, 0x70a88b71, 0x27f4e38a, 0x32f9d9cf,
- 0xfa20bb9c, 0xd816a49b, 0x5a6bcd7f, 0xc928deba, 0x35ec8715, 0xf129978c,
- 0xc533c074, 0x5a1d9cc9, 0x2d6b171e, 0x73fa05b4, 0x5cfc09fd, 0xb2819a85,
- 0xc017e8e5, 0x608eb87c, 0x555e7ee3, 0x28178f07, 0x1295597e, 0x8e0e6837,
- 0x77a6081b, 0x2e455fa8, 0xc6a55f8f, 0x3b466cdd, 0xb3017ebc, 0x4d5ea587,
- 0xcc78f03f, 0x74dfb2d3, 0x0af1fb45, 0x1bb1427a, 0x6e382b99, 0x65a9c8a1,
- 0x8f1ef913, 0x6ab8e2fe, 0x76fdc604, 0x8a8f840b, 0x704f900e, 0xdab70ade,
- 0xf802166d, 0x19ffee49, 0xedc01bd2, 0xa0f6ab8c, 0x19dd2128, 0x990ebf68,
- 0x8e91ab3e, 0xd695bce0, 0x9cf02237, 0x38ae590e, 0x7f148dda, 0x8a5b64ab,
- 0x612aee90, 0xf430ef3d, 0x0b5cf954, 0xa2d729f9, 0xaccec527, 0xb7ee0d6e,
- 0xce487731, 0xe01eff8c, 0x396401bb, 0x992e7bd7, 0xf12332fe, 0x99906fde,
- 0x879f9123, 0xedc09ff4, 0x5cfe4537, 0x3c581dbf, 0x6e71de60, 0xac05531d,
- 0xa673e37f, 0x4f78faa0, 0x9bff507c, 0xcf41ccda, 0x4119bdb3, 0x598f73cf,
- 0xdd79ea82, 0x4ffa8313, 0x5416d0f8, 0x0e2be49f, 0x4ce53fea, 0x307d5049,
- 0x9573ce13, 0xe35bc1fb, 0x33fea085, 0xf9a0facd, 0x05446767, 0x320d07d5,
- 0x52bb647c, 0xce5f77b1, 0x686ef6e5, 0x76f7c0a9, 0x8a3af04b, 0xc4e77ebf,
- 0xd8e6f5e0, 0xa1fbd782, 0xfa0bd978, 0xc27e0554, 0xb15fa073, 0x13f81dfc,
- 0x9a13f02a, 0xfac09fc1, 0x604fe08b, 0x027f01e9, 0x7f025fdb, 0xe0adeb02,
- 0x20fd604f, 0x6f583ff8, 0xf2a62bab, 0x6a12ba95, 0xbafc16bf, 0xc98f75e4,
- 0xd7971eeb, 0x74e177fd, 0x5def9e42, 0x9c6ebe79, 0xdcffcd2f, 0xbc563c59,
- 0x2d3cfc04, 0x87c6acfa, 0x5f0ac37e, 0x062dc611, 0xc61892de, 0x7ddd99a5,
- 0xf5062eac, 0x338a08d9, 0xb78192b3, 0x7d52ae31, 0xc9b4d520, 0x0fecfa8c,
- 0xbef3e2ef, 0x7c8cc956, 0xefeda879, 0x85cf3811, 0x5f74614b, 0xef107a4a,
- 0x5461bf1b, 0x31cf04df, 0x05b33a0e, 0x37e90804, 0x0bb7e90f, 0x4ddd4a69,
- 0xcd25bdf7, 0x53c41a2d, 0x3c29f215, 0x0ea3cb7f, 0x635cfe7e, 0xf61373d0,
- 0xe54ab287, 0xb9c238a6, 0x2f3e6536, 0xf1a477f5, 0xcf73cf7b, 0x053f5e1d,
- 0xe2cb6ff5, 0x5e7f7811, 0xec5efcd5, 0xc7c157bd, 0xc85f07e7, 0x76cafba4,
- 0x9fe0cf98, 0x96aed9cf, 0x8eff7ceb, 0x68a296b4, 0x02cd1c54, 0x05c50b1b,
- 0x5fee85b6, 0x38f6daaa, 0x65556e50, 0x0066addc, 0x248f7e9f, 0xbdf837c7,
- 0xb8c4c391, 0x22f9e71d, 0x5f57ef02, 0xc3bd1cf7, 0x38edf886, 0xf6eb811c,
- 0xfe414ab7, 0xb72b68d3, 0x355b478f, 0xad0bbf84, 0x5ef02387, 0x30e7a377,
- 0x4bcabb87, 0xd7243fe7, 0x7824a1fb, 0xfe7449b7, 0xd0624b8a, 0x5586763d,
- 0xb66679a2, 0xb9e2358d, 0xbd7c3c7a, 0xb799ab1c, 0x825e2da7, 0xbf1e3ffb,
- 0x7b224f20, 0xca350410, 0xef661bf1, 0xcaa43b41, 0xf386d923, 0x79e40aef,
- 0x4e9cd4bb, 0xdfdb4adf, 0x78f8f285, 0xd26c88f1, 0x699f8a11, 0x916f76e5,
- 0x7a869ec6, 0x3660c7a4, 0x583f9d22, 0xfc446a9c, 0xdb12c21e, 0xec69778b,
- 0xe6c7bc06, 0xba98f5eb, 0x7aee9023, 0xb425735a, 0xf2f99477, 0xe88775e5,
- 0x2e6f087b, 0xbbb953c2, 0xf8f380d1, 0x73dbc7f1, 0x7fea26ac, 0x3cdefddc,
- 0x327aabb4, 0xe92ec9c2, 0xa7f230d2, 0x5db99aab, 0xd891d3dc, 0x924f7818,
- 0xf2fd9563, 0xdaf0910c, 0xfb96a6d7, 0x0587bddd, 0x39d353f5, 0xde0eec2f,
- 0xea7dc98f, 0x1dc7b451, 0xf50c4b4f, 0x1b5d43a2, 0x6cffe78b, 0xcafef067,
- 0xd43b3865, 0x00d8d8de, 0x0fb4757a, 0xe8818df1, 0x13e15dbc, 0xc153e133,
- 0xb7064f63, 0xf9e27ae7, 0x65a3a4bd, 0xe5f5d10f, 0x64eea4f1, 0x7f121ff4,
- 0xe778a3a9, 0xc567fcb5, 0xaff0086e, 0xea8bfa18, 0x313cd4e2, 0xbc1f6fc5,
- 0xb6ab6b96, 0xabbf448e, 0x1ecafc84, 0xac2cf606, 0x3a7b44e9, 0xb61ff292,
- 0xad83bae1, 0x76bfba6a, 0x7d66daea, 0xa0d97602, 0xf6051805, 0x2d53b83d,
- 0x0cd97bdf, 0x952ed768, 0xcccfdaed, 0xf4097cf6, 0x488d73af, 0x866473e7,
- 0x27d31f91, 0x5bcfbdcb, 0xbb24ef92, 0x426498e1, 0x8786687f, 0x668ec1db,
- 0x7b56d76e, 0x2a63ff92, 0x6acdedda, 0x8a60d4cc, 0xed94e21d, 0xddb2d390,
- 0x80cd7a7b, 0x4e9bfc86, 0x8c963d81, 0xbb5b2a79, 0x33b9e112, 0xb3d91673,
- 0xec99a94e, 0x83db6589, 0x6fb007ed, 0xcf55ea82, 0x7217da85, 0xdc13cb7c,
- 0xdb87f8ae, 0xc67643ac, 0x0a67f438, 0xc871a9a5, 0x78c82f0f, 0x959bfc55,
- 0xb7942de3, 0x9e6551b3, 0x1021c4a5, 0xfb9d355e, 0x6edf702b, 0xfc859847,
- 0x10af558d, 0xe4bffb5c, 0x3c7f4c7e, 0x33f47823, 0x36fedf0e, 0x6a35e74e,
- 0x48f98dc1, 0x34b64035, 0xaf704e9f, 0x6bb338c1, 0x13e48230, 0x17c8c563,
- 0x7f70162b, 0x5f3186d5, 0x7e156b28, 0xb7abd108, 0x54527ca8, 0xb3689c80,
- 0x02bf50a6, 0x3ea3b30d, 0x90b4695b, 0xe3a31b7e, 0x6ae17a76, 0xc3d2364f,
- 0xb5c7f018, 0x31f8f101, 0xfb010186, 0xc7807eed, 0xc27895ff, 0x1d49951c,
- 0x191fa015, 0x95fd435b, 0xf0a241f9, 0xdf9ad7f1, 0xfc1bf304, 0x23bc03f3,
- 0x585fde11, 0x93b7a42d, 0xfff728e6, 0xca97c4b5, 0xbd002e79, 0x63181c61,
- 0xc7378834, 0x9fc837ce, 0xf5eeb273, 0x8228ae38, 0xf708a3ef, 0x5e30f583,
- 0xe79651fe, 0xbcbc79b1, 0xf9152e4d, 0x7b6790d5, 0x95f50adf, 0x593ff679,
- 0x8899ae49, 0xb4ca573e, 0x9c4cf602, 0xbbf9186f, 0xf0891de2, 0x03f005fa,
- 0x5ac2fbf2, 0x64169cc1, 0xaf3a712f, 0x3cec4de1, 0x454ef4f3, 0xdd6cb838,
- 0xc6d79819, 0x5a2d7f38, 0x05a737a5, 0xbd2007de, 0x0251ffa3, 0x2fd1f2ff,
- 0x5372bfe3, 0x57946dc5, 0x8cd62ab5, 0xc83517f7, 0xa6d7290f, 0x87ba50ff,
- 0xb7a44edf, 0xa0b5a66a, 0x0b69a97e, 0xa1516e7d, 0x084dfe3d, 0x74c9245f,
- 0xe81768da, 0x5bf1bd7e, 0x95a38f15, 0xbb37140a, 0x4e911a0b, 0xcafd87e9,
- 0x7e71b9a7, 0xfba0b3cc, 0x391886ae, 0xee862bef, 0x9f227ee1, 0xf7952eff,
- 0xa3efe40d, 0xc6324f6a, 0xf93a8e71, 0xe602d53d, 0x52dd7ba1, 0x6f654dd6,
- 0x2f01f578, 0x8d1aee4d, 0x7607f87e, 0x1a91c52d, 0x511936d7, 0xb5b166ce,
- 0x031fbc26, 0xfbee7936, 0x1bdb2bdc, 0x9468f7a1, 0xc7e7959f, 0x92bccaf3,
- 0x83a03cf8, 0xf8a38033, 0x57c7cb9c, 0x02207fbd, 0xfefe7ee1, 0xca7ef3fd,
- 0xb9020fd0, 0xd654f305, 0xbdd064b6, 0x67758b8c, 0xabf1fbe4, 0x1fc153e0,
- 0xf08399b4, 0x0eb9670a, 0x0d9f33e0, 0xd36e63e4, 0xc0a9f0b5, 0xf03d4939,
- 0xe8250463, 0xa1439231, 0x5ee05678, 0x3cd56acd, 0xeefb56fe, 0xb3ffe802,
- 0xed19a2b5, 0x7ef0cbca, 0xf578fc0d, 0x28d791fc, 0x257b3f90, 0x5a78297c,
- 0xff54bcc8, 0xfb8f8a30, 0xf144a170, 0x7c69ffc3, 0x4bd9e435, 0xb7c2aef2,
- 0x257a7ca1, 0x2ab45cbe, 0xf8437f84, 0x2d2f8874, 0x7f002ff0, 0xc41155f6,
- 0x1d7e0a8f, 0x5193f066, 0x2d1875ff, 0x3e39766e, 0xfdc5dfd1, 0xec0ab654,
- 0xf087e149, 0xe3fc8fab, 0xad017c50, 0x541f50d8, 0xa9f305e7, 0xc92bc782,
- 0x7dee452d, 0x4d47bcc4, 0x7067dd02, 0x9685fe3e, 0xfb94e9f2, 0xe2dee50c,
- 0x6fae3cd1, 0xc08fcb42, 0xa27bc16e, 0x233d194d, 0xd5ebded1, 0x7bf0f328,
- 0x74d68fd7, 0xcd7cc68f, 0xb2f1a68f, 0x4cf3c357, 0x8c2dba94, 0x4a3f03c7,
- 0x6e10bad0, 0xa6e3091f, 0x91f01da3, 0x783bcbf0, 0xc6634e3d, 0xe9b882fa,
- 0xaaf7a826, 0x83e1f895, 0x5376fcb2, 0x0982d1f9, 0x604fd405, 0x661e1047,
- 0x3ad09581, 0x0c5d1082, 0xe7e8f9fb, 0x5ef07363, 0x03ff3940, 0xf48e3c79,
- 0x431cf91b, 0x095ff6f1, 0x045f6f14, 0xf784c3aa, 0x289fd302, 0x93f6814e,
- 0xa6cd4ebf, 0xc115cafb, 0x4dfea3eb, 0x56e538a6, 0x4b96e79a, 0x99c5ea03,
- 0xe90d7dfe, 0xbc8b82cd, 0xa0d8c97d, 0xf45b667c, 0xbb27ee38, 0x8f512353,
- 0xf06d7a29, 0x60437ed8, 0x1cacf51c, 0x8faa1e77, 0x5029247b, 0xf7b1be2f,
- 0xa79c74e1, 0xb2cae35c, 0xf98f3018, 0x1fb424a9, 0x943ef7ca, 0xdeed764e,
- 0x9fe8e98d, 0x9c3d3794, 0xb87aa36e, 0x1523fc9d, 0x7df9f73f, 0x0a6d7693,
- 0x9d6fa3b0, 0x52fbedc0, 0x68851bdd, 0xf1bacedf, 0xb71875f3, 0x816bfb1f,
- 0x590b70e2, 0xb7d43af7, 0xaf9c1965, 0xe48e8358, 0xf747cc3f, 0xddc67ba4,
- 0xfee51bbe, 0xabbf8cf1, 0xcdfea097, 0x657cd153, 0x0e39bdcc, 0x041b6fe3,
- 0xfbf9bf8a, 0xd77ba68f, 0x4d056bc5, 0x51ea0c7c, 0xc7fd779e, 0xe38228bc,
- 0xbbb21b3d, 0x356cbdb0, 0x75a59f6f, 0x3ce0f6b7, 0xcf28684f, 0x4a65140a,
- 0xf63dc049, 0x3df8f31f, 0x72cda2dd, 0xcebcb1be, 0x8db16dd8, 0xa3fce781,
- 0xfe567f8c, 0x3b83c901, 0xb6dcbc65, 0xf123bdfa, 0xdaa46f30, 0x2b9467fe,
- 0x3a7e3eef, 0x4159e50d, 0xa44cd9f4, 0xfb1ab1f3, 0xee781593, 0x2bc52d26,
- 0x528959ad, 0xb9cff41c, 0x5863da7f, 0xf8bd5a2e, 0xfb8c0ac9, 0x1f91d76e,
- 0x856feca6, 0x5fd11660, 0xd3f8dc3d, 0x676e107b, 0xa479e71e, 0x8faf1a2b,
- 0xe2fe5abb, 0x1f3c75b3, 0x1d3af9fc, 0x99d42f95, 0xb88e1998, 0xea9e2eaf,
- 0x5333afbf, 0xfa73e6c9, 0xaea6f252, 0xa5ee5f34, 0xb65bca30, 0x1e51d06e,
- 0xf6d6ae7d, 0x6bc01e55, 0xa6ce0dec, 0xc6b9f28d, 0x576cf8c2, 0x83840cf2,
- 0x2ef2e375, 0xe54f6134, 0xedeaff71, 0x64490d9e, 0xf53eaf87, 0xcf3c054c,
- 0x0ef92fcc, 0x5e76ebc7, 0xe1c178a4, 0x10ca87f6, 0x5a4de5de, 0xdcf93e7e,
- 0x8f4f1e67, 0xbce3127b, 0x7fc9a96f, 0xea79d9af, 0xde508d99, 0x26b979bb,
- 0xe87fde90, 0xf795bf79, 0xbabe2d73, 0x75fe1c12, 0x89387abe, 0xf809a7f8,
- 0xe7dff32a, 0x6bd59aab, 0xf3737e08, 0xc3e6c64b, 0x5da8cffe, 0x674fc849,
- 0x744cddc6, 0x0814eaee, 0x571c8afe, 0xf3e6a7c6, 0xd12ae8fb, 0x48ec99b3,
- 0x057f8e59, 0xf7c2239e, 0xd2cff68d, 0xaafe8ed1, 0xcf55c16d, 0x3d0eb07d,
- 0xe99b8c22, 0x9e7d0ca8, 0x62a7b1af, 0xc8be715e, 0xe7d0e7ed, 0x712be7b7,
- 0xc5b71e78, 0xa790109f, 0x458d84e2, 0x13fea346, 0x972061bc, 0x9eb76d9d,
- 0x06ffa155, 0xc1c7e17e, 0x38fb2876, 0x695faf40, 0xab2ad7bf, 0x5f951e71,
- 0x50f84eee, 0x3d00de64, 0xc617c93e, 0x0eeb01bc, 0xa6d02bf9, 0x049efba1,
- 0x37880b92, 0x6bea87cc, 0xf584d71f, 0xc78e1ab3, 0x97e083be, 0x930cb8f1,
- 0x3ce7fdf2, 0x0b3e7edb, 0x79e86ce5, 0x4f395fab, 0x7b68e1f4, 0xe740a2e8,
- 0x9556799f, 0xbff3ed75, 0x167cf7b1, 0xdaacefe2, 0x57fe8f97, 0x8597c69f,
- 0x957ea878, 0x157ff3cb, 0xc57b4a0e, 0x138f0d06, 0x23f2260a, 0x140ba50b,
- 0xc63be807, 0xedd500e3, 0x0e9e48bb, 0x4c78f076, 0x145dd88d, 0xda8bf187,
- 0xcf285d53, 0x5fb9e306, 0x28dbf306, 0xd65521cf, 0xa481aa83, 0x1ed72039,
- 0xee07a219, 0xfe419e0f, 0x1e3ce0d5, 0x6561e507, 0x2bb43385, 0x433f21ce,
- 0xe4aad97b, 0x67e748f5, 0x507323dc, 0xf59dbe3e, 0xdf8a6a8f, 0x926e1ebd,
- 0x30958ec8, 0x4e0878c7, 0x4b70e743, 0x2987d13c, 0xb3387176, 0xd1abf405,
- 0xbf24ef98, 0x9fbf38fa, 0xf381b9ab, 0xf3857b13, 0x1bed7393, 0xf980f89a,
- 0x93f3257e, 0x7ace4f62, 0x97c41ffd, 0x9edae70f, 0x470cbe40, 0xc5f38859,
- 0xb51e5247, 0x72871ef2, 0x90e8691f, 0x8962f8fd, 0x49b4d79e, 0x58e5ef0c,
- 0x0af291bc, 0xca16d98a, 0x3cc59cb7, 0x8f5e7953, 0xf029d1ef, 0x52ebf67c,
- 0x81a1e62e, 0xdbf74d3d, 0x34f66145, 0x15ead3cc, 0x1eae1905, 0x7d009ceb,
- 0xf73e7ef6, 0x024aa757, 0x8481b1e9, 0x6653b270, 0xe29677ce, 0x5a7e957e,
- 0x9833eb91, 0xe62cec87, 0x7bc2c81e, 0xc81de655, 0xa556fbc2, 0xc3d7bcdf,
- 0x322f496b, 0xc05e758f, 0x79f3a73a, 0xbc0bf3bc, 0x5279071f, 0x16c3df23,
- 0x436edf4a, 0x27456b7f, 0x15ec7fbf, 0x3cc03f93, 0x19c01733, 0xf01e7af1,
- 0x63fd436a, 0xf21b3667, 0x6e91f8cf, 0x7d9a9fe4, 0xbd7cc302, 0x136d76ea,
- 0xd5aa85c6, 0xe7a458be, 0x6bef6d8d, 0xf06b9e90, 0x8e3c765e, 0xdcbc7267,
- 0x35bf7944, 0xf5efc626, 0x00ffaeda, 0x63ce76e3, 0x553a8b5c, 0x003c51ef,
- 0x57ae36e5, 0xfe42dad5, 0xc97983bf, 0x073477ff, 0x3c60cdd3, 0xf287e78f,
- 0x737ce9c9, 0xdccc7f10, 0x1e63f9ce, 0x681b73e6, 0x675fc538, 0x5d91c7c6,
- 0xf1c71fe2, 0xafce9360, 0x3fa63b43, 0xfc7ca045, 0x5ad730fe, 0xe95c8fb4,
- 0x7fe9aedc, 0xbd2b05ed, 0x5b73a3f7, 0x3cf98c7f, 0x733bddb2, 0x149556c3,
- 0x1d999fb0, 0x1fd8de3c, 0x120fcac6, 0x21d7edde, 0x25b97c3e, 0xbe31f267,
- 0x777819a3, 0x4483c60a, 0x3d0d1f1e, 0x6b8e5d87, 0xfdfc671c, 0xb3df6528,
- 0x3cb91313, 0xa3a26e63, 0x5bbf392e, 0xc651d7c9, 0x504132df, 0x9fb8d1ee,
- 0xfaae5824, 0xd7de1a5e, 0xde2b9e60, 0x3bf960d7, 0xef161f39, 0xa2feb06b,
- 0xf78b0f9c, 0xf78ed835, 0x956f5835, 0xbef161f3, 0x5f78eb06, 0x722be583,
- 0xdc71ec3e, 0x6df1e52a, 0xa2e90a7c, 0x946d790b, 0x1d1bdebf, 0xdc151f52,
- 0x085a37bf, 0xa8128fae, 0xc6c269bf, 0x78ff30a7, 0xc52f9293, 0xc3b446cc,
- 0xfbf9c22a, 0x7b06a91a, 0xf3f404ec, 0x45ed778b, 0x9bf81e7f, 0x882b9fde,
- 0xef4a505e, 0x1968c497, 0x27dba3ca, 0x804f47d8, 0xcd8ec7f1, 0x724adb48,
- 0xecf74f52, 0x31bb3fbd, 0x6f7ae292, 0x25824c49, 0xaee465a7, 0x9a7d42b5,
- 0x85fa2041, 0x512a6ef9, 0x67984cfc, 0xab62c746, 0x1307cb8a, 0x9285cbda,
- 0xb3ae0963, 0x8b9f4122, 0xd588f872, 0x51fb819e, 0x6a345de0, 0x45da1a59,
- 0x07f36a5d, 0xbd759f18, 0x57e866a3, 0xa53c7129, 0x69d693df, 0x99bfb8f9,
- 0x736ba919, 0x36607e70, 0x0d367794, 0xd9fdc66b, 0x9ea170c4, 0x855997e4,
- 0x027f20f2, 0x66e99ba7, 0x357b1f6e, 0xfa345566, 0x62d361f5, 0x4bb75ef0,
- 0x1931f3c6, 0x3c65c7cf, 0x81573de3, 0x6173df8a, 0x585cf789, 0x2da3e686,
- 0x4db12fcf, 0x240f7820, 0xcdb3e605, 0x0097df92, 0xd4f7a10a, 0xf31c729c,
- 0x34ee594b, 0xcadc95e6, 0x9e6879c7, 0x778e392a, 0x6f7c1d5e, 0x8ff38ca8,
- 0xbdce5467, 0x166bcb89, 0xbf79e1a9, 0xe61731d7, 0x397dcf15, 0x7d50e281,
- 0x06a5d16e, 0x5e05cfbc, 0x5ec67947, 0x8b2efee6, 0x77337ce7, 0xabf51c7f,
- 0xcea9e397, 0x7c74eee8, 0xe64fa3af, 0xf07ea52f, 0xe4979e3b, 0x81ba81cc,
- 0xf3a123de, 0xa776e739, 0x4fbd4147, 0x5f488bd0, 0xbcfe26ce, 0x673fe647,
- 0x7c9f3c8a, 0x24f3a61e, 0x3bfa3e21, 0xf7c24e5f, 0xbc193710, 0xf7fcb94b,
- 0x66dc93a6, 0x6fcc74de, 0x4e782f3a, 0xadf1be62, 0x98a5296d, 0xed5e7f6f,
- 0xb3eb0679, 0x5d78d2db, 0x0a693968, 0x93d23e7c, 0xb7c8f984, 0x6296a5b6,
- 0x91f9f23e, 0x5944cf2d, 0x97eaea02, 0xcd73e24e, 0x98a56983, 0xeb5b3c9f,
- 0x7487563e, 0x5f4e7bf3, 0x4e077dfa, 0xdaaa7c23, 0x7d3efdb9, 0x2f0b81df,
- 0x603e7ea1, 0x7582bca4, 0xdf099213, 0x6ecfedf5, 0x6beb7a46, 0x6c3f1351,
- 0x99ff7e6a, 0x2d3f50df, 0x6b665985, 0xc90c563d, 0xba1db494, 0x3b35f71b,
- 0xd625f3dc, 0x89bc4f17, 0x047b31f6, 0x13a5ebe7, 0x4f914a73, 0xfbec0efb,
- 0xd9b3ea05, 0xe2d86091, 0x13d05e7e, 0x8ff72a7e, 0x40b8c02b, 0x0cbbb19f,
- 0x9dfeafe7, 0xec1fe796, 0x718e9b8f, 0xc09cff82, 0x6e2a31f3, 0xfa8492d8,
- 0xf9e57c56, 0xf8c1bfbd, 0x74f4efe6, 0xcd1353df, 0xa94abded, 0xe1397f31,
- 0xcc5ed76f, 0x5e7be95b, 0x15aff74f, 0xe2b39318, 0x2963ac7b, 0x3feaff3e,
- 0x78865eff, 0xee769428, 0x772ff6c5, 0x438445eb, 0x7916c68f, 0x8f61f233,
- 0x0acefc9a, 0x3bd15eb9, 0xdc27ef82, 0x8bf84457, 0xfa8492d9, 0xafc472b6,
- 0xcf7dc0ee, 0x833cb696, 0x567b0f7e, 0x670e774b, 0xc1b8079f, 0xd47bb3b8,
- 0xfb034998, 0x5e90aa30, 0xca5b0bce, 0xf7f9c49e, 0xf5e77ef0, 0xae9e085b,
- 0x5c33d73d, 0xd431fa0f, 0xad85e7c7, 0xf767ed41, 0x7e859b3c, 0xcddfb9e9,
- 0xa154ff26, 0x2a5f8573, 0xf4836b77, 0x58824922, 0x3fca5b8c, 0x02198b93,
- 0x0ee759e2, 0x927be8ee, 0x6b9fc7f9, 0x00357b56, 0x5b2d0aa3, 0x0acdf98b,
- 0xde26543f, 0xabe78c5a, 0xd1d31b14, 0xf5c8a97e, 0x9c5f2195, 0x3c5d33d5,
- 0xd65b7bf4, 0x6bad955b, 0x7c1da0e6, 0x45fcfda5, 0xc95f4796, 0x9b55f87c,
- 0xdf781dde, 0xb5fe5a18, 0xa84f998e, 0xb585f5fc, 0x95e5b25a, 0x78d6def9,
- 0x55afe81c, 0x71f97347, 0x8337fa12, 0xac93fb1c, 0x0aad16ef, 0x04eeffee,
- 0xad594f9e, 0xfea3a5f1, 0x7b7fe653, 0x87db8982, 0xca3a5f2a, 0xb371d0ab,
- 0xbcde5925, 0xa9bc9020, 0xd14e156c, 0xd20824fb, 0x2b3c3f58, 0xe6372e75,
- 0x87870d13, 0x0f197cf8, 0x70f1e612, 0xd66caabe, 0x4f30f4db, 0x022f9855,
- 0xd18725ed, 0x50768117, 0x6b122bdf, 0xa317d192, 0x5fe29fcc, 0x5653894f,
- 0xfd36d478, 0x71c1eb70, 0x865e4fd0, 0x5628037f, 0x537ce44f, 0xeb4e16de,
- 0x1f2f9331, 0x677cb6e9, 0xa73c38f0, 0xfb1f8029, 0x06c576da, 0xf70cebfa,
- 0xa751f74d, 0xfffa6f88, 0x07bd31f9, 0xb5b2295e, 0x4e794f78, 0x4083efe0,
- 0x3907de9d, 0x5677df27, 0x43086d7e, 0x95f739fa, 0x4fb8f883, 0x7b9c91f0,
- 0x7246cdb1, 0x23ed4fac, 0x626bb739, 0xf947af11, 0xbd6e50ca, 0x24a7f138,
- 0x7c12fa3f, 0xd29ef865, 0x2f8ea566, 0xd01d81cc, 0xe490b6d1, 0xe7896cc9,
- 0x6a5db051, 0x71138f13, 0xe1932f78, 0xde86d8c4, 0xd443f23a, 0x3a97b466,
- 0x42f72a27, 0x25f9ff1a, 0x31f53f3f, 0xe456bef3, 0xc50372cf, 0x6abec07d,
- 0xc0ed097e, 0x8c16b105, 0x4dc287a7, 0x898c5fb9, 0xe22966fe, 0x7da31de9,
- 0xbc3cc4ec, 0x9f91f4cf, 0xf64ed401, 0x5a6bf57c, 0xd5fb37f2, 0x7e517b03,
- 0x71f68db9, 0x0e9e0113, 0x547af74d, 0xbed41771, 0x67ed342e, 0x1c91bd21,
- 0x97d6f4e1, 0x07bf8bb9, 0x4e4fdf22, 0xfa00f192, 0x7d22358c, 0x87cf1c08,
- 0x409ff6db, 0x9dd7d379, 0x943a724a, 0x3db6ce9f, 0xe3728116, 0xaeefd043,
- 0x87c07880, 0x7ca59f8b, 0x0798f980, 0x6b3de502, 0xf837cf83, 0x2fc98fed,
- 0xda039b64, 0x821b1e91, 0x4170a1eb, 0xf106f4ba, 0x7df68b81, 0xc01bf23f,
- 0x777a6aa7, 0xa861c235, 0x52ea173e, 0x4850fd40, 0x2b3fa43d, 0xfdc3f6e1,
- 0xebcd1813, 0x25eded18, 0xcf1f7e3f, 0xbd07adef, 0xe103f546, 0xee2d3f74,
- 0xc315bd03, 0x8bea16f5, 0x8a6e88aa, 0xd01df55f, 0x83cabdd2, 0xe1259fed,
- 0x291e81f9, 0xfed5534e, 0xf7fa2c72, 0x699826eb, 0xb18fd07e, 0xa0731794,
- 0x11fd163d, 0x7a21dda5, 0x0cf7e5d2, 0x287e50b2, 0x9bc94eed, 0x42e5794e,
- 0x5f3e1677, 0x8719cb27, 0xeb097508, 0x10e1ce8c, 0x76b3df38, 0x287ce489,
- 0xf4c956de, 0x8b21f20a, 0xe15e39f2, 0x1e4503f1, 0xe572c854, 0x7267b610,
- 0xf72937fe, 0x84cf7852, 0x9c8c3f7c, 0x23815af8, 0xcef8a5ab, 0xbccd13fd,
- 0x79a78f2e, 0xe789fc79, 0x3e7abded, 0xc713252b, 0x45f79599, 0xd528f2fd,
- 0x0e505f2f, 0x781c93c4, 0xe70b1d50, 0xb0467caa, 0x8a90c3d4, 0xd04535d2,
- 0x2d532d9d, 0x1ab8a22f, 0x2e1ae7e6, 0x1d2857df, 0xf8e44e45, 0x1fb914ad,
- 0xa057b95e, 0x6a73a5fb, 0xf2076f7e, 0x580fde86, 0x08a6b056, 0x18beeff9,
- 0x5fd026a7, 0x4bfcd6be, 0xcbeb821b, 0xc514d76a, 0x95e7c30d, 0x8d76b6ab,
- 0x57cf9764, 0x8a2c6f61, 0xaede5f35, 0x5e9cfbec, 0xf574e7d9, 0xcc7840c8,
- 0x1234535f, 0x7fba65ca, 0xdcfc1e17, 0x5eb5dae7, 0x5d2d57ca, 0xb7c4f743,
- 0x8a0daa5c, 0xbe6b5eb3, 0x7ba6e60a, 0x3fed2b90, 0xde0874b4, 0x312b8c5e,
- 0xc43dafe0, 0x0137c067, 0xf4cbc5eb, 0x289f143a, 0xfd063c5f, 0x3c5f6653,
- 0x113e3026, 0x339be25a, 0xb88ae522, 0x2c3e04a8, 0x0f030cb3, 0x89d1ffa5,
- 0x3f1ace3c, 0xa8f1d391, 0x5e3b55d9, 0xe9d71462, 0xa57bf941, 0x22fe4cf7,
- 0xbf07efef, 0x9c233267, 0x9bd4ebf7, 0xdfd3fe30, 0x87c50df9, 0xe619d7fb,
- 0x03077bf3, 0x5de7804b, 0x029be3f1, 0x26abc0e3, 0xdc243b71, 0x9a9dedca,
- 0xe3d5f50c, 0xa1c6994b, 0x1bd912f8, 0xdf74e199, 0x05f6d7d2, 0x8efeb7e9,
- 0x8bde133c, 0x0dbb75f4, 0xff356fc8, 0xa8b17ffc, 0x3e3afb87, 0xbeb4bca5,
- 0x7ca33f6f, 0xde728db5, 0x3936a1e0, 0x6cdbabdf, 0xe2fef6c4, 0xbf6117bf,
- 0x8fe9724d, 0x98f8f02f, 0x83f12a52, 0x3bf9ff00, 0x4c7b53d4, 0x54c51f1b,
- 0x2db0ca99, 0x7fc0bf24, 0xe1bd468e, 0xe3982b8f, 0x04c38b86, 0x54d215c6,
- 0x2580ae3c, 0xd2d215c6, 0xeb015c78, 0x12c05718, 0x8ed80ae3, 0x63ac0571,
- 0x18eb015c, 0xc63ac057, 0xb8c4b015, 0x297fb602, 0x0fd1e7bf, 0x3dc78b82,
- 0x57f7240d, 0xc0337e62, 0xbf27656f, 0x47b95abf, 0x7c617ba2, 0xdff503cf,
- 0xad3b7965, 0x678ede72, 0xd607dd2b, 0x882c901c, 0xc41f7c22, 0x3bf98e95,
- 0x1e314703, 0x5822d354, 0x7db198d6, 0x6363ed3e, 0xa507de47, 0x6d47bed8,
- 0x4f44cd11, 0x828d9f1c, 0xd57c8f5b, 0x57e287b1, 0x949d7105, 0x2cd35fef,
- 0xcebb8c30, 0xd93f72d3, 0x0e6b4129, 0x1d92abdd, 0x9376d4ed, 0x9cf552ff,
- 0xef7c0e60, 0x45e266bb, 0x7dca1392, 0x88fe52f5, 0xf37a3d39, 0x6b3d2092,
- 0xf85779e3, 0x29c7ec27, 0x1d9377e7, 0x2d176012, 0x6c6c7bc5, 0xf7a5be97,
- 0xe0e09c4d, 0x9dae108e, 0xd1d95577, 0xb5f31eb2, 0x55fe687e, 0xdef924e1,
- 0x47bf9b3a, 0x92f8fc52, 0xbd60077d, 0xb25a2dc1, 0x609f6e53, 0x1e526dbf,
- 0x28d819e6, 0x53b472ee, 0x27d67e4f, 0x8a0faf5b, 0xd74a14bb, 0x8563dc51,
- 0x7dfd205a, 0x3b9f6ac4, 0x4672e809, 0x6f14bdf1, 0x246f1199, 0xf0e8563e,
- 0x4fc96b49, 0xe315de70, 0x0a9877f9, 0x34e7ecb5, 0xa5cf9c9f, 0x5eb0a9e0,
- 0x2cf7e370, 0xbd0b3316, 0xc008b03f, 0xe5517187, 0x188b1ffb, 0xe850afcf,
- 0x8156c56a, 0xbcbe8ae8, 0x84bdf010, 0x103df845, 0x6af77fd0, 0x289bfdb9,
- 0xc4f27bf2, 0xe28f3c4d, 0xfca7663e, 0x7d486591, 0xd7d7e912, 0x0f6ed07c,
- 0xdb892ebf, 0x9c38e6f7, 0x3571f17f, 0xc61707e5, 0x276e9edd, 0xf9405f3d,
- 0x6ef78213, 0xaf1bfbe9, 0xf3833f26, 0xb9aa8e27, 0x927801dc, 0xf485d59f,
- 0x3b1ef14a, 0xcaebc795, 0xbf229ca9, 0x5efa161f, 0xcbe77f43, 0xb0be382d,
- 0xf84160c6, 0xc03df15f, 0xffbfabb0, 0xebf394e6, 0x5c9ec512, 0x6be3c233,
- 0x51e10583, 0xef49d718, 0xf3caa589, 0xb25b9c3f, 0x8b69f109, 0x1f5c2e60,
- 0x00b669ef, 0x40f08b7c, 0x3dd1c602, 0x66cf7c36, 0x513053a0, 0x7265f53e,
- 0xcc3aeb74, 0x1349a953, 0x2daf184c, 0x1852db0a, 0xa517f30b, 0x7677d324,
- 0x1c78da6a, 0x4e4a0fb6, 0x92dc5307, 0x62aac7c0, 0xf1cf7e31, 0x3fb5cbe8,
- 0xdfcf293d, 0xb3e65b3e, 0x782f8efe, 0xe3b5f11e, 0xfbe9bbb4, 0xef4f4c1c,
- 0xf60fd3af, 0xd1c6fb35, 0xe855af14, 0xae39b068, 0x45a8e909, 0xa5a513d6,
- 0x8ed1a9ef, 0x37b3cc68, 0x96ca1c23, 0x4b175c5c, 0x4e3e1ce7, 0x87dfe4a6,
- 0xe502c9c6, 0xde46ffed, 0x5aba89fd, 0x5baddf2a, 0x9d776545, 0xe8079e8b,
- 0xbf08238b, 0x7d6f101f, 0xf130d27b, 0x4733a656, 0xbe05be92, 0x90edf1e7,
- 0xbbf02af8, 0x33efc018, 0xd9eea23a, 0x8348f680, 0xcdf782c6, 0xd2bcff98,
- 0xfde1f240, 0x59c6c349, 0x2819f815, 0xf4c83b2e, 0xe9878839, 0x112aa919,
- 0x926dff9e, 0x44e71410, 0x2273c1be, 0x7c8960df, 0xf9f952a3, 0xa30d69e6,
- 0x7da194ef, 0x40fb22e0, 0xbf5df84f, 0xd40ae406, 0x20a665ef, 0x442172b9,
- 0xf32380ae, 0xac5f7a33, 0x0936cb43, 0xe9cffcfe, 0x19ca5c50, 0xb878ce46,
- 0xe61d199c, 0xb3be9e79, 0xf9461d50, 0x44efc0c5, 0xf2374767, 0xac25bdbc,
- 0x461dd684, 0x3e7bd0de, 0x38188ef7, 0xbff414f9, 0xd90361f7, 0x9613eb39,
- 0xe477ffe6, 0x71279fcd, 0xdf813c78, 0xed5d5073, 0x059b0e7b, 0xb15d8fbc,
- 0xbe236590, 0xc439ef95, 0x7bf218c1, 0x39eff5ff, 0x123c988c, 0x0ae0e7bf,
- 0xdc439efa, 0x30e7be15, 0x6171b26a, 0x461cf7e0, 0x30b11e4d, 0xc60e7bf8,
- 0xb29df885, 0x39efc1ff, 0xbbce4fa4, 0x370e7bfc, 0xa0ff364e, 0x3d8039ef,
- 0x4fe3899b, 0x63c6d8e4, 0x3b9f2899, 0xe3e5fdf4, 0x97643df2, 0xb2c52f68,
- 0xa2a5c228, 0xc56dd176, 0x73d16df2, 0x5f03b63f, 0x1578444c, 0x037d963d,
- 0x5125977e, 0xf2bca1eb, 0x49b6ad27, 0xb96bff38, 0x3cf8c9b6, 0x2f5fde34,
- 0x73f60f9f, 0xcd0bf60b, 0xe2e8531f, 0x0e5cc9ae, 0xa9cb93cd, 0xc7bfc3f5,
- 0xbf326f3f, 0xbed6be4f, 0xe077bf61, 0xd9feca7a, 0xdc56c596, 0x4ef7ec0f,
- 0xb7ec27dc, 0x88664b04, 0xf80f7a0e, 0xc9757a72, 0x2e7462fb, 0x3fb38f90,
- 0x9528f6e1, 0x14772ae9, 0x1ea30dda, 0x7ee14770, 0xe80e3547, 0xdf907df1,
- 0x68f406ba, 0xf576fc3f, 0x7fdb1e80, 0xdaf9e36b, 0x9f6ff3a1, 0xf491fdcc,
- 0x7e3403a9, 0x4dddfc0c, 0x1440c1fe, 0xe5e96dda, 0x14ae3447, 0xf66d4f7a,
- 0x93764127, 0x8c7bf899, 0x01e636dc, 0x8c3d2191, 0x1e78c1d9, 0xe90c4163,
- 0xef1d4ab9, 0xfdc0f95a, 0x38d1d222, 0x803bec37, 0xaedfaefe, 0xaf7e0c1a,
- 0xaae34bd7, 0x5ec025e4, 0x64ee7a0b, 0x9474bf3c, 0x5ed08f2c, 0x39d9efc4,
- 0x77d08fcb, 0x0b8ec0a6, 0x79be8f99, 0x594f9430, 0xe6bfb3ad, 0x62be5333,
- 0x77a5bf50, 0xfa3d66ff, 0x5ba5e5b5, 0x2f17e435, 0xa58f5969, 0x269ef1c3,
- 0x197d918e, 0xcbec1fd4, 0xfb65faa0, 0xf547d90c, 0xc7d717fd, 0xd02eb30d,
- 0x13a456c1, 0xaa8e0e85, 0x4fd0e33d, 0xb30cea3d, 0x3c1df7f0, 0x269a5df4,
- 0x5df4bdf9, 0xcadd39ff, 0x5d3965f3, 0x3f1df8c0, 0xa9ea8e8c, 0xaf1df2bf,
- 0x1c8a956b, 0x8dcefa1c, 0x5e28b986, 0x7248cb39, 0xfff646ae, 0xc89897aa,
- 0xbaf8511e, 0xb539e55a, 0x18c5fb1e, 0x8a9bfe79, 0x7aabf7d1, 0xcf9451c4,
- 0xcfac3f4d, 0xacfba54a, 0x178f7ad8, 0x5db81de7, 0x15b9efa0, 0x5ab97384,
- 0x9e389628, 0x4447e785, 0xa7815dfe, 0x98487e51, 0x37bfc147, 0xbf972530,
- 0xf8cf103f, 0xca98db77, 0x369df21c, 0xed7a1e39, 0xeff1b4ef, 0xf7e7cd92,
- 0x25510d72, 0xf9f1cba5, 0xf9e81b82, 0x1f52efc1, 0x2afee2b1, 0x71b4ef94,
- 0x4e61bf7b, 0x557f3d06, 0x3d41af30, 0x5d807ae1, 0x7a6d3be9, 0xef80fbe4,
- 0xf887bdb3, 0xd9f7d6ba, 0x1c0fef94, 0x23c3705d, 0xbd1c397b, 0x3355ef78,
- 0xafe418cb, 0x3c3117ff, 0x56c0d29e, 0x000056c0
-};
-
-static const u32 tsem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x3370278a, 0x45e39c30,
- 0x8381e9f0, 0x5fd32918, 0x50c0cec6, 0x4055c401, 0x3f880bbc, 0x7c3032b1,
- 0xff5e2566, 0xdb042935, 0x21818248, 0x88d7881e, 0x49a83031, 0xa41dc422,
- 0x03261819, 0xb150a1f9, 0x5f3a4047, 0x0f77328a, 0x80a69c16, 0x872ae629,
- 0x9163a760, 0x6819c647, 0x50e54bf2, 0xf40499f9, 0xa2be340f, 0xa2ffca8e,
- 0xa013a10a, 0xe4d157e2, 0x3be542bf, 0xa6bafea0, 0x4edcdd8e, 0xc35dfd32,
- 0xfc01a102, 0x9847b099, 0x009847b0
-};
-
-static const u32 tsem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x7993331e,
- 0x31e424e4, 0x1e4e1081, 0x03086820, 0xb78a8884, 0xf6301027, 0xd57876d2,
- 0xaf0e2d58, 0x6b86f210, 0x7fb6bd2d, 0x78490806, 0x111fc1a8, 0x29e1d5ad,
- 0x311d82f6, 0x0388b622, 0xbdabd228, 0x557c5837, 0x0bd11feb, 0x2a44908a,
- 0xe5b5ef6a, 0x3ef6b5ee, 0x09939cc9, 0xafdb7b04, 0x7cfdffff, 0xc7ecee9f,
- 0xf5ed7bd9, 0xfdad6bda, 0x8131c918, 0xe4230da4, 0x06fbfc22, 0x109d9221,
- 0x9d37a132, 0xd72120e3, 0x66924218, 0x92ddfd2f, 0xbadc4214, 0xa349bfe2,
- 0xe4febba9, 0x5f5f9a1a, 0xa4aff0ec, 0x4d1f5b4d, 0x2d096a78, 0x2fa1efbf,
- 0x7cd04fc3, 0xad79ecfa, 0xce7eb4c5, 0x5d0fc924, 0x10ab1a1d, 0xd8e7ed02,
- 0x520176c2, 0x9097e581, 0x927fa130, 0x45f8e8af, 0x9fe8b884, 0x37fe9724,
- 0xa5b21c89, 0xd1e43e60, 0x99029ea0, 0x31364846, 0x7e6055fe, 0xf509fc36,
- 0xd0677744, 0x779e75ef, 0x7fec13e5, 0xdb0a5f8e, 0xf27347e9, 0x4dc87203,
- 0x6d08c6d3, 0xfb1dc749, 0xf908395d, 0xe4990cc0, 0xd8b68763, 0x0fca6ffe,
- 0xd214754c, 0x080b67fe, 0x49d9f9ff, 0xcc82da36, 0x3be1eda6, 0x1a1f4e22,
- 0xd99f67cc, 0xe0dfb8e8, 0x40dfdddf, 0x5fc0a7ff, 0xe5a1094b, 0x9e0c1ccb,
- 0xc5d9d9e4, 0x1989ce30, 0xbf4316d7, 0x3213a673, 0x9d4d5688, 0x4490f63d,
- 0x891aebf3, 0xcddb4edf, 0xcf1c0d29, 0xcbf8d981, 0xe80293a7, 0x60ee8e97,
- 0xffc45f7d, 0x64ef38eb, 0xcc3fde3e, 0xfa102b1e, 0x8a97f641, 0xa0725da9,
- 0x4bd153f9, 0x2d056a48, 0xee53191f, 0xd09a769f, 0xe6e9e4f2, 0x721340f6,
- 0xc425211d, 0x1aea7293, 0xc91677fa, 0xad4228ba, 0xee8c0b6a, 0x4a6b0fe5,
- 0x22f9fdff, 0x12fa01d0, 0x6a1fd6fb, 0xa0e9e99c, 0x7b375af8, 0xf4d08796,
- 0x0f2cc0f5, 0xd9f5efe0, 0xd68f10b3, 0x676673f6, 0xfb5e0227, 0x06feef1b,
- 0xfa08d03a, 0xb5b3c73d, 0xea48907e, 0x39fbf423, 0x31c3d13a, 0x9301dffd,
- 0x0964254d, 0xb34d1b30, 0xd2a6d525, 0xe88d6cfa, 0x95e33891, 0x3b69b102,
- 0x28994992, 0x0ff352e3, 0x2637bb61, 0x71c34ad9, 0xef0773e6, 0xb81a55c7,
- 0x6fa50e67, 0x751274d6, 0x2912ba51, 0x75e2c6aa, 0x1a548a5d, 0xddc7038e,
- 0x68425e1c, 0xe1c0cf7b, 0x02d86571, 0x47329fd0, 0xf5c2c40c, 0x42678003,
- 0x4ca24a6f, 0x18f8e6ee, 0xfbbf72fd, 0x338f506c, 0x8e00bb8f, 0xecaa9009,
- 0x0c8f0e3b, 0xb201937c, 0x43fc8296, 0xe02463c2, 0xb91eccfb, 0xe5070124,
- 0x17f0a18f, 0xa42dae15, 0x1412d47b, 0x47ec56b2, 0x0324a4f4, 0xde1157bd,
- 0x4f51290f, 0x42157e51, 0xd78b84ab, 0x129e6a5c, 0x35f06539, 0x193ba9f0,
- 0x5e1cbfc7, 0xe518a048, 0x88d43152, 0xe307c078, 0xed4df92b, 0xbacba502,
- 0x947ee5d1, 0x90218a6f, 0xe17e4333, 0x3bf457df, 0xbdccff37, 0xca91d29c,
- 0xd3396b91, 0x2cdf8a8f, 0x8e92eb67, 0xc82008b5, 0x0f49b964, 0x40241210,
- 0xeb6f0377, 0xbc78a2be, 0xfb5bbf04, 0xe7c86fdd, 0xc9983260, 0x053f9327,
- 0x79bd07fa, 0xf0077ed3, 0x5edf3af5, 0x5d6bcc07, 0x7a825efe, 0xe8c7d38a,
- 0x5daf95d7, 0x81d6ce52, 0xee808d7c, 0x9ea748c3, 0xc6a7d1f2, 0xa6767e02,
- 0x748bf72a, 0x08933b7e, 0x6b75d9ea, 0xd02b7848, 0xb5e594b5, 0xb5e1696f,
- 0x9d3b8e74, 0xd698bebc, 0xed06bcd3, 0x3adbbea9, 0x68870b49, 0x8d8b6b7e,
- 0x85ab1fb5, 0x311f9a45, 0x8a148491, 0xc2c56d4f, 0xbe5a4e95, 0x17eaa375,
- 0x34fd5eb5, 0x2d6725a2, 0xdeb2dfb4, 0xbdf00aa6, 0x3b23ad8f, 0x443849f3,
- 0x39b1dfc7, 0x69239bf9, 0xf9b2143e, 0xf24fd387, 0xd945faf8, 0x022844a5,
- 0x9c3a31b4, 0xae5c7921, 0xa9e50204, 0x7ecb7cbc, 0xa48ebfff, 0x5d363df0,
- 0x45a0aff2, 0x4ccfd63b, 0x769e28d0, 0x3f048168, 0xc0f07f4d, 0xccefcc7c,
- 0xdd00260c, 0x9f9c6e76, 0xc0f14c00, 0x461b99e6, 0xd2617b41, 0x6ce91d61,
- 0x1f47ffd6, 0x00ec3a28, 0x9e994b38, 0x7e0d6a4f, 0xbcf9a253, 0x89b91249,
- 0xadcf214e, 0x1fdbdc21, 0x4f5811b2, 0x8b6de8fb, 0xcdd44ebe, 0xb4eb5779,
- 0x5d7f818f, 0x2009160f, 0x86353bda, 0x923741e7, 0xbeec8af0, 0xc85cefe3,
- 0x5d2913ea, 0xbf2e0e80, 0x96675962, 0x4756f85a, 0x3c717079, 0x1c755ab9,
- 0x897a488f, 0x578bd690, 0x62469ffa, 0xf07ae9f0, 0xe9f58128, 0x8163e78a,
- 0x7ca05d27, 0x9cab830f, 0x1c1eb9ef, 0x6357caf7, 0x21b1f1e3, 0x7fa01eef,
- 0x6177c522, 0x50eb0424, 0x0a24617a, 0x57c9e2fc, 0x9a0bb034, 0xc5c93109,
- 0x7cfbd1a1, 0x1337201d, 0xaf583e22, 0x837e8dd7, 0x81568fc9, 0x6fe630f8,
- 0xb7e4f7b4, 0xc1fb5893, 0xf87287a8, 0x697853ce, 0xcb87bb39, 0x847f4f59,
- 0x732447ad, 0x4f75c21c, 0x5e7561e1, 0xc84c7d1c, 0x97cb940a, 0x817ae049,
- 0xedcddea6, 0x6c06a751, 0x7900dfae, 0x910240b7, 0x134ddf38, 0x42d27ad8,
- 0xe9a05d74, 0x162f44a3, 0x664b9d70, 0x2eb2d7fa, 0xbc9fd1f5, 0x16e9165d,
- 0xd468df40, 0x8734803e, 0x23cd31f8, 0x92474c01, 0x26af4c56, 0x49f34c11,
- 0xa405a63b, 0xaf43531b, 0x422a89f8, 0xfac4c47e, 0xa4e720c9, 0xe58b63da,
- 0x3264d0bb, 0x3cce3eb2, 0x73782d9a, 0xf8ebf890, 0xe75f021d, 0xfc8aa648,
- 0xf17af843, 0xe818b06e, 0xfc2854c5, 0xefccdbbb, 0x0ebe24e2, 0x693dea38,
- 0xdd335780, 0xcd54548d, 0xf06d5a7c, 0x1c2444a9, 0xc41f32c7, 0xd6b8cc63,
- 0xfb7356fe, 0x9c9f98c6, 0x491f23a2, 0x50cf666e, 0x71bdf438, 0x0828d1f0,
- 0xab419e7c, 0x29b23adc, 0xb6494bbf, 0x6b9a5ac8, 0xe8764f74, 0x893f2f38,
- 0x7ceb6747, 0xbe2af0ac, 0xa9b3c181, 0xcb0a9e07, 0xc297fa3a, 0xfea64ff3,
- 0x1db24ca4, 0x86a20bd6, 0xbc56de70, 0x42def9f6, 0xd2e4fe8f, 0x57d66991,
- 0x02d78a4a, 0x069f8587, 0xe37c7f68, 0xe47fea4b, 0x211bfac3, 0xa9ec2a41,
- 0xe60101f9, 0x1a40ad7f, 0xc85e2913, 0xa0eda268, 0x6af5cd70, 0x698b8ecc,
- 0x91f41937, 0x74c90b66, 0xee92cfbe, 0xe43ed023, 0xf41d9127, 0x6df367b3,
- 0x7d695ba5, 0x63b69faa, 0x1e4005fd, 0x0b6d1dae, 0x9fd1b940, 0xf5329e4e,
- 0x112efd47, 0xe836e1f0, 0xe4c3f163, 0x1fb436b1, 0x6fa27c95, 0xc75f2389,
- 0x1d157cb9, 0x9eb0ea71, 0xb094cab8, 0x8ffa1b33, 0xb53e4314, 0x5d61f89a,
- 0xe6cdd49f, 0x30e1c651, 0x59fa9de6, 0x6a7e0040, 0xc03b31f7, 0x3fd04855,
- 0x74da3254, 0xb4dd1ff0, 0x7e42f50e, 0x50531754, 0xd83fa23f, 0x5f3d9e1f,
- 0xd00bed3d, 0xb9d47d7e, 0x92be076a, 0x9fa0e9fc, 0xc8568f57, 0xf8bdfa60,
- 0xfff63b3b, 0x1862a7b9, 0x47cf9989, 0x0bb1d10d, 0xa670c1a9, 0x67a618e1,
- 0xed31da1b, 0xd30b786c, 0x594ae9fe, 0xebceda8e, 0xc0d7e27e, 0x3f0f101e,
- 0xc00f3447, 0x5c75d51d, 0x12a21c17, 0x82802eb3, 0xd36fff06, 0xdaf0bcd8,
- 0x086bc46c, 0x67d54de6, 0xe0367878, 0x9e000a5b, 0xc2223887, 0x77867cd2,
- 0x01d03fc0, 0x3c8e8bca, 0x5cf102b7, 0x9e02c64d, 0x0ca4c937, 0x13e03cf4,
- 0x827d89d6, 0x03800eed, 0xfe69f3f2, 0xc1fa8ffa, 0xf78659fb, 0x9e29978c,
- 0x4b494e00, 0x8eadc664, 0x913b95f2, 0x27d7120b, 0xf9927abd, 0xbdf6bdd9,
- 0xcf00eff6, 0xac894696, 0x68a6bc85, 0xf7b7114a, 0x15824a41, 0xdcdfc1d3,
- 0x28fd3e56, 0xe2b90bd8, 0x5a648757, 0x3a5eb43e, 0x4f2311d9, 0xfd746559,
- 0xb0c276a4, 0xecf2e6e5, 0x074f3990, 0xb7347f40, 0xc43e5cc5, 0x87aef5c6,
- 0xad1e4078, 0xe8b65af3, 0xd3fd7157, 0xea240d55, 0x02f26396, 0x1791a7c3,
- 0x423b13bc, 0x46cb7e74, 0x4c038c11, 0xb3f5b1b7, 0x7ca3be15, 0xd74f2f71,
- 0x5231fa5b, 0x46dba269, 0x193d30c6, 0xddba7d6f, 0x46ce3c56, 0x4db06bfb,
- 0x72a3671e, 0x042292e4, 0x5b9777ec, 0x93f9e3d1, 0x8e126dd3, 0xebb5209f,
- 0xfbab8522, 0x4adfe23a, 0xee4cbef1, 0x2c7c828e, 0x21fcd62b, 0x30fe4750,
- 0xd51263ca, 0x15f66261, 0x700253c1, 0x6c4a7850, 0xfb044e38, 0x0738a6e9,
- 0xcc997dfb, 0x4a365dfa, 0xf6376823, 0x3655e703, 0xd80ce119, 0x34fd0904,
- 0x1555974e, 0xa34df739, 0x9f554ed9, 0x2667fd05, 0x78c16705, 0x7e6fb946,
- 0x1963fa29, 0x2bf4ccc3, 0x0167d477, 0x2206547f, 0x4e7f80d3, 0x926c5f7b,
- 0x36b7bce9, 0xf144bf10, 0x702b9eff, 0x7357f41b, 0xb008fd7b, 0x5e06df7f,
- 0x3b2a0098, 0xa5ac7a80, 0xa25fa564, 0x148972e5, 0xca3f2995, 0x25bf0f13,
- 0x2a1a4017, 0x938b3886, 0x477d33d4, 0x35224bf5, 0xf5231cbd, 0xa27e218f,
- 0x72d03c80, 0x60256f55, 0xdba8380f, 0xef863270, 0x1e734c94, 0x7cd8fa6c,
- 0x72e37a7f, 0x27e79829, 0x09fe0387, 0x49dde9da, 0x26927fcc, 0xde000bfa,
- 0xa6ffaf7b, 0xc4fcf006, 0x67f93366, 0x5a4d7f56, 0x79696ffe, 0xfee26810,
- 0xd5fcb4b6, 0x80f1bcb4, 0x979c5697, 0x9432ca63, 0x24f0050b, 0xbf07f932,
- 0xe41d67be, 0xcf5bf878, 0x572f58db, 0xf835bc37, 0xa720e1c3, 0xa43f831d,
- 0x052d59c4, 0x3e42ff91, 0x1c28b5f0, 0x098f9992, 0x62134f78, 0x18176e52,
- 0x5a9c9bf6, 0xdc947488, 0x988ea9d2, 0x8fc0ddf5, 0xc1ddfcb2, 0xf4878e1f,
- 0x78ad4c6d, 0x0120a455, 0xd768d03f, 0xe018b713, 0xe234effa, 0x1fc479a9,
- 0xa47338a5, 0x7a6a78b0, 0xf30a285e, 0x09fd5272, 0x233dd3eb, 0xf0c56b5f,
- 0x3b0fc581, 0x3f20ad94, 0x61b68cb4, 0x7865b35c, 0xf90290e4, 0xd1406a0c,
- 0x5dca677a, 0x4c6d8821, 0xe37c63cd, 0xd4f5b3f4, 0x7e8c3c35, 0xbdbfa198,
- 0xad5e1f1c, 0x67b3f51c, 0x31ded9a2, 0x2b2701d6, 0xdb36f4a2, 0xa694ce51,
- 0xbe82c54f, 0x9b539a7e, 0x69e51a76, 0x233fb9a4, 0xe36ed1de, 0xc96b8bf1,
- 0x593768b5, 0xe1fd12e2, 0x71f86bcd, 0xdcbcd913, 0xfc1849d3, 0x5189f4e6,
- 0xcfd79bc4, 0x9bd866f0, 0x9bbf3e1e, 0xfc04234a, 0xf3f89ebe, 0xeb6f0ccd,
- 0x7fa28baf, 0x29ec7eb7, 0x85bd67b4, 0xce3f261d, 0xa1ca1ef8, 0x76c4fcfe,
- 0x18f6a1a8, 0x23711bcb, 0x19e9a78a, 0x61ebbd69, 0xaddbb72b, 0x92275374,
- 0x4763d062, 0x8315a747, 0x84b7bede, 0x3cab4ec2, 0x6297587a, 0x7ef2adf0,
- 0xdf867cd4, 0x7cd8cb7b, 0xd3f47b69, 0x93989def, 0xf266e304, 0x7f11b0f8,
- 0xebcbf1ee, 0x284f78cd, 0x2d85c4b4, 0x67eab77e, 0xcc4b52f4, 0x5f39abe5,
- 0x57a7222b, 0xe8ce192a, 0x4f3e3035, 0x84bcf832, 0xdf3279f1, 0xd12f4837,
- 0x921d010e, 0x4dff994a, 0x4df37e2c, 0x5e8c1d29, 0x00c88f37, 0xa9fefc3f,
- 0x97663edd, 0x7126ba30, 0xc6efbc7e, 0x71c80211, 0x40268972, 0xc33e727d,
- 0x13c53253, 0xa5c977ac, 0x4ef6efcc, 0x525db0d4, 0x0b5ba309, 0x5fe14c7c,
- 0x898a7403, 0x5b4b3b1f, 0x6b7fa075, 0x741d4ef1, 0xe1c53259, 0xd4cf0a20,
- 0xd81b0a52, 0x805fb49d, 0xc51853d7, 0x49525ab8, 0xfca5d870, 0x82a2427a,
- 0x10f887cd, 0xe94b686c, 0x7e58253c, 0x20b26268, 0xa7ef7ed0, 0x80f1c07c,
- 0x8f173c71, 0x785fdfa3, 0xfddcf512, 0xc8364df0, 0x1cebf6a9, 0x36a5279a,
- 0xf707f83f, 0xf108e697, 0xbcc6e7e2, 0x2acb83fb, 0x35f812c7, 0x9572fc31,
- 0x16dee3c8, 0x22475dfe, 0x57c82e6a, 0xa5f76f48, 0x830feaf5, 0x65e47aff,
- 0xfecbe312, 0x87a189f4, 0xb21824dd, 0x1fd5f765, 0xdef8ce92, 0x7940179e,
- 0x24ef03eb, 0x8a52afc6, 0x9136fcb9, 0x5e867fdb, 0x140792d1, 0x00a12727,
- 0xd72277ae, 0x02da4f4f, 0xf054c50b, 0x4eb8c3bb, 0xae74c8b8, 0xca9f1937,
- 0xe6a6ff9c, 0x4ae2bd33, 0x9776b089, 0x903aa78d, 0xa834d6df, 0xc65a1fa8,
- 0x439ed5de, 0x7866b0f1, 0x73be1f93, 0xb9196b8c, 0x3cdbf68d, 0x2b70797c,
- 0x30fdc00c, 0xac22bfd4, 0x8d5f8c83, 0x0e03307d, 0x61d21992, 0x7e09cc9f,
- 0x2467e011, 0x24905fdb, 0xeb8fb512, 0x4795df1d, 0x6967cde1, 0x0dc19f28,
- 0xb6ebc9fe, 0x6f9c2ae0, 0xa2946b7e, 0xc99bce9b, 0x42216acb, 0xebcc225c,
- 0xb21e7c72, 0x9f8ebe31, 0x025df7f6, 0xe1c4d3ec, 0xdb22dddf, 0x472d59a7,
- 0x7e085088, 0xf289ed1b, 0x6a6ceac9, 0xa381c797, 0xd56bf391, 0xc3f8672e,
- 0x89ab7e18, 0x75f29924, 0x1fc233fb, 0x7711fac6, 0x514fb80a, 0x4358d1cd,
- 0xcf00b23a, 0xf61a29ef, 0x48eb6b57, 0xe9177c83, 0x78025b4e, 0x8b8f0310,
- 0x5277fd74, 0x90b8c4be, 0xd6eb607b, 0x81a7f0e5, 0x4085d10c, 0x0fa9e4cb,
- 0x178e9879, 0x69e307dc, 0xd2bf2b2a, 0xf5f0e371, 0x4d7cb10b, 0x6a5957c4,
- 0x147f6be5, 0x129ddaf9, 0x9fb77ac5, 0x8fc1b5f1, 0xad1f9c89, 0xbf8c687c,
- 0xd6afc79e, 0x335f3e72, 0x708549a1, 0x9b51dadf, 0x2ce69e30, 0x7c015cda,
- 0x25aa32de, 0x64de7c0c, 0x17df35f0, 0xdb2efea1, 0xa35ad31f, 0x72264eb0,
- 0xeed456be, 0xeb7b9006, 0x38935d7c, 0xbe0534bc, 0x5f39b806, 0x93f807bf,
- 0xae08ddfd, 0x076bd7c1, 0x45bad7cc, 0xfed39b6f, 0xc2d927fc, 0xf1891ed7,
- 0xd7c067e7, 0xb30a4f00, 0x963edc63, 0xdfea7eca, 0x06e7e9c7, 0x6b99f989,
- 0xe5ac1cb9, 0x1fb6b072, 0x223ff839, 0x9afe03f3, 0xc98b3072, 0xe5a24381,
- 0x8cae9389, 0xd3b0251f, 0x9e7bc8e3, 0xe1b5fc24, 0xbc4334de, 0x27fe3c72,
- 0xbe84cd30, 0xcfd234f4, 0xe4c0e744, 0x73c98f3b, 0x76be727f, 0xfe387c68,
- 0xa7f46453, 0x26922ef8, 0xffbe395c, 0x7215705a, 0x43f0367e, 0xb728c582,
- 0x3a667a31, 0x86a92bc0, 0xd304799e, 0x28ad79a9, 0x81be86a7, 0x2bfa0a58,
- 0x3bc62b6a, 0x68ad999c, 0x98f3399f, 0x24fc31be, 0xb88d7ceb, 0x33d71378,
- 0x02217949, 0x853d9feb, 0x9eaa3f70, 0xcc9951f9, 0xd5e2301f, 0x18a8fd86,
- 0xbbd0d47e, 0x79a79f70, 0x97da3d78, 0x3bd637cd, 0x36c3ede2, 0xf077eefb,
- 0x3ed35f4d, 0x0e5a1aeb, 0xbbc9aefd, 0xc3b3c49f, 0xfb18798c, 0x6e3e4e46,
- 0xa8b51e73, 0x32df5c60, 0xc76adefc, 0xfeb26734, 0x7ae7be7a, 0xbbd1ee57,
- 0x54768f2c, 0x6f9f8c6e, 0x03e0c7e9, 0xa343e885, 0xe4183710, 0x4ce7091e,
- 0x3f04849a, 0x924dc7d8, 0x90729d20, 0x5aa97b1e, 0xff401689, 0x9cbc6627,
- 0x3db2f685, 0xbce406b8, 0x0380abe9, 0x53aba9e2, 0x96c6f35e, 0xe6f19d9f,
- 0xa56cc1b7, 0x7ee2d5df, 0xb148838e, 0xdc2763fb, 0x4b7ed1db, 0xe9c737c8,
- 0x09ae149c, 0xcc13c402, 0xbf8f0ae5, 0x72e69928, 0xa45fc799, 0xe7394b14,
- 0xbe34b90f, 0xeb93795e, 0x7602df15, 0x1cc4e74e, 0x713bd716, 0x30674f2b,
- 0xdbc73efe, 0xc234f375, 0x535feef5, 0xf6e5251f, 0xe29befc2, 0x9922f8c7,
- 0x3ebb4765, 0x2b9d852b, 0x26e7b120, 0xa26b5fe0, 0xccfc6244, 0xff9781a1,
- 0x61d4f108, 0x06cabe0b, 0xea156b3c, 0xdb465861, 0xc79c6ca5, 0x28f74263,
- 0x3ae6cf18, 0x02f5fb8b, 0x6a72e345, 0xdbf40b12, 0xef8521db, 0x3a52c0bd,
- 0x91057b8f, 0x37c0ecbf, 0x8c29d022, 0xb1448ba9, 0x303a43de, 0xe61b089f,
- 0x5187e0b9, 0x33c44bbf, 0xc61b614c, 0xf6cc7e8d, 0x7888d643, 0x03a8836e,
- 0xedc9bfb4, 0x4297f82a, 0x1ae77e88, 0x40be77f8, 0xc4c8316b, 0xc608b2e0,
- 0x7cedad93, 0xa039d853, 0xaffb7a3e, 0x5237df4f, 0x548f8173, 0x1ce8372c,
- 0x694ef514, 0x5ff2df42, 0x12f38189, 0xdc58abc6, 0x2a5f5acd, 0xde4017e9,
- 0x0bc2e5ac, 0x7e053a7f, 0x6467aaf4, 0x3ca7a3f4, 0x41bf4723, 0x045b35f3,
- 0x076d53f4, 0x770fe89d, 0x51f2c23e, 0xfb43a28f, 0x8c05db73, 0xdbd9d507,
- 0xe201bdef, 0x0488cf8a, 0x19708dfd, 0xe29d8bee, 0x59fb2673, 0x80079cbe,
- 0x9a1cb66a, 0xec57df0b, 0x77d813b7, 0xf16e79a8, 0xf9a06fb7, 0xf464c7c5,
- 0xac766a51, 0x657f6050, 0x40885849, 0xc1326bbe, 0xc4fb43f1, 0xbeda0ef0,
- 0x369edbcb, 0x2bfb0dc7, 0x455da20e, 0xa7b4f6e1, 0xa9f4a6cd, 0x0d353f0c,
- 0x2ddcabbe, 0x98ffc1f8, 0xa38eccf2, 0x9abbf419, 0xa73c0427, 0x45cbb550,
- 0x9cba18b4, 0xdfa3136a, 0x9d33f880, 0x8bc5f827, 0xc034eb49, 0x0d8ecd7b,
- 0xb713168a, 0x9230d33c, 0x7cdef668, 0x1c7413cd, 0x93ed5dfa, 0x58a61f82,
- 0xe041236b, 0x9ce7ce8f, 0x30dcdb65, 0x08ca15bf, 0x59abcc0f, 0xc38b7681,
- 0x7ec1f6f3, 0x8b78657a, 0x57d68d32, 0x2945b23e, 0xaaa7e18f, 0x2d10d75d,
- 0x6d4e3f86, 0xd4bf4dce, 0xae867b7a, 0x54f0b15b, 0x88b7a612, 0xc4665614,
- 0xc8767bec, 0x453f9c49, 0xdf06ff53, 0x18275e87, 0xef3d0ac7, 0x741abc41,
- 0xbd32a65b, 0xbcedd060, 0x7528e9ca, 0xb388cd17, 0xd02f7aaf, 0x2af10ec1,
- 0x1bfbd315, 0x6c6e987c, 0x9b3e90d0, 0xe1577f00, 0x7b9606be, 0x88629127,
- 0xa275788b, 0x3c9f52c2, 0x21962f5d, 0xf960124e, 0x8283dbb4, 0x1bf98976,
- 0x383926e9, 0xb75c820f, 0x964c4fc9, 0x49bebae8, 0x7e252e09, 0x77b4be3a,
- 0x6075c972, 0xc8e705a7, 0x1d9fb0a9, 0xe8f160ac, 0xa2e40f88, 0x7ccbef89,
- 0xd6f2664b, 0x7c60a194, 0x8bf7d364, 0x41eda1b6, 0x7d365e18, 0xec277cbf,
- 0xe67ed1ab, 0x1aae54ca, 0xee4fda65, 0x9b49fbe5, 0x4fd4d13b, 0xa30adcda,
- 0x8fd8c59f, 0x6cfd6073, 0x19bd7b9a, 0x4695b99e, 0x8fd8f53f, 0x4af36067,
- 0x199263bb, 0xb1aa3b9e, 0xfddbf49f, 0x06881f68, 0xdc7690ff, 0x4eef7517,
- 0xc496b71a, 0x1fe4d1f2, 0x2a1e78c3, 0x947cb155, 0x24c13138, 0xb27a494f,
- 0x74a83f29, 0x6a7da9b0, 0x9f54c720, 0x85b5765e, 0xbfa8dd2f, 0x8a814f31,
- 0xab38b126, 0xbd415832, 0x81d83c53, 0xbb06bbf9, 0x75dcef51, 0xb02af07d,
- 0xd05600f7, 0xc12977f3, 0xbe1c6a31, 0x0812f3a1, 0x1b34cfc6, 0x32ec7da4,
- 0x7939efbe, 0xde2357c8, 0xd9d7dfa7, 0xd12447ba, 0xf14a43fc, 0xadef3023,
- 0x8de3b332, 0x9d824338, 0xce6bfea0, 0x8a16da2e, 0x50cb6bc1, 0x6f422fca,
- 0xd0722dbf, 0x73b8fc07, 0x4a576ff5, 0xa1a6be14, 0x7a6e1e0a, 0xe1edfe5c,
- 0x9b99b510, 0x00fb9687, 0xea8576ff, 0x15f1d88f, 0x8e3e7e3a, 0xdfc61bbf,
- 0xd93b332b, 0x673dbe3a, 0x477c69a2, 0x7c698556, 0xa7c74287, 0xf56fb1f2,
- 0x8a7c7c3b, 0x7909ebbf, 0xc7077e56, 0xe05567b7, 0xa90acdf8, 0xd09f8d30,
- 0x9001fe33, 0xcdfdc39f, 0xf37ae73f, 0xcd2ab3fc, 0xfcd857f3, 0x80feae8f,
- 0xf3809f8f, 0x80fe597f, 0x92ab3fcd, 0xfacedfcd, 0xdbdf19ed, 0x6157ff83,
- 0x37f5affe, 0xe649dcff, 0x36ab0ff9, 0xc6cedfcf, 0x27f5637f, 0x8e377c7c,
- 0x09fca6ff, 0x6ab0ff9b, 0x07b15f1c, 0xca47c0fd, 0xf07a8490, 0xa461a99f,
- 0xa35d4061, 0x923a40e3, 0xc837a9c5, 0x5dc70839, 0x3eef8c09, 0xe6fca04f,
- 0x24a7d5ee, 0xea90254c, 0xd3ce5acb, 0x158bbb55, 0xd0842fe6, 0x41c4585f,
- 0xc45fb85d, 0xb46c8cf5, 0x78538787, 0x218bf73b, 0x78dc2fc8, 0xac5b9e23,
- 0x77dc13b3, 0xfa3056a7, 0xc0f1ff1f, 0xf3b1ade8, 0x5a8ba6b2, 0x13fecb65,
- 0xef38c783, 0xa6ab2454, 0xa78829fc, 0x127c3d50, 0x9e9a1ffc, 0xb478e996,
- 0x83f043fc, 0x1b958aae, 0x768c2e76, 0xce9f2277, 0xfe1cbbeb, 0xf7c31253,
- 0xdc053ba9, 0xc37cf847, 0xd9f40552, 0xc99756a2, 0x74e3a86f, 0x8ece7eea,
- 0x79c68dfb, 0x14505bbe, 0xc1fdf909, 0xbb051d6f, 0x41e6f171, 0x276eefa6,
- 0x1470d5e1, 0x79fac173, 0xff3a5543, 0xe3eccadb, 0xeb6b8c44, 0x9c1c5843,
- 0x49b8810c, 0x7906db59, 0x52dccd08, 0xf9ec9b26, 0xfce6835b, 0x7ce6156d,
- 0x6d961ca7, 0x112ccf60, 0xefda16c8, 0xcb65ebf7, 0x8e3600b9, 0x76e64957,
- 0xbbef1b25, 0xb4198694, 0x8e90fbe8, 0xe9156283, 0xdf65573a, 0xddd4f01a,
- 0xae28932d, 0xb8a91dc7, 0x454a140f, 0xb2a82dbf, 0x9de15b79, 0x00f43b2b,
- 0x8fee6785, 0x15a7c444, 0x2e838efe, 0xf3ed46dd, 0x907fcd8e, 0x9d6c7e21,
- 0x3bfe158f, 0xa3e75b96, 0xcc3eb02a, 0x19cb590b, 0xa9f9589f, 0x36f17f6e,
- 0xf37b3db3, 0xb5fb58b6, 0x530cd76a, 0x56f8497e, 0x9bc5fb53, 0x17ea99e7,
- 0xd5312eb5, 0x6a59682f, 0xfd0bcfca, 0x8efed4c8, 0xf54c2be5, 0x635fafdf,
- 0x62adbfaa, 0x6b7f2983, 0xfb5321f0, 0x98b6ca5b, 0x47076dea, 0x68e4077d,
- 0x9e22ebd5, 0x3ee0bdfd, 0x9bd82f75, 0xee12dc17, 0xed447e73, 0x33839015,
- 0xb4815ed4, 0xf478ff73, 0x2c1ea9a7, 0xf9a24d87, 0x2d5598ca, 0x0997a099,
- 0x6572cfea, 0x24d0aac2, 0xd7b0178a, 0x9b887ca9, 0x041d1215, 0x0f724cce,
- 0x318b771f, 0xa9971df5, 0x7d054cdf, 0xb17adf7c, 0xdd797e23, 0xd4c379d6,
- 0xaf6a7e38, 0xb02192dc, 0xce5975ce, 0xb569189f, 0xb1a73ce5, 0xeb817dbf,
- 0xe9856ad9, 0x19bdea83, 0x86736193, 0xe223e5fa, 0xf9ec9b9d, 0x0db0223e,
- 0x53feb048, 0x98861f81, 0x76aa6bf6, 0xfbe49ae5, 0xe11121ec, 0x409d05aa,
- 0x5217eaf5, 0x72028d60, 0x35923d16, 0xa1c0346b, 0xef4055af, 0x75c54fec,
- 0xe9436cfd, 0x3fafd836, 0xf4c010d3, 0x4c3286a3, 0x3104354f, 0x02a1b0fd,
- 0xf50d93d3, 0x2c347698, 0x86bdf4c7, 0x36efa610, 0xbbfa60b4, 0xdf4c5686,
- 0xe98cd86a, 0x4c610d1b, 0x4c741b3b, 0xd1e8790d, 0x0f6e01bf, 0x84d71b1b,
- 0x2e7cc3db, 0xe73da98d, 0xf7ff70c2, 0x11f3fbbc, 0x7f9fef60, 0x6cfb8ecb,
- 0xcacbe1fd, 0x51d3fd6f, 0x3ca57b47, 0x639d083c, 0x8133bd6b, 0x2369c9d1,
- 0xec1c64a5, 0xcff4ecff, 0xc4bcc7cf, 0xfd84f52e, 0xfa713c33, 0xfa5d7885,
- 0xf444e9e5, 0x949982ee, 0xfe1ea71e, 0xf7e822af, 0x607fac02, 0x71111c07,
- 0x6dd1261d, 0x95d7a07e, 0xe1784de2, 0x2f1059f7, 0xbf83d73b, 0x8b882cf6,
- 0xd8a8ab5d, 0x3b36f9ff, 0xf9d2f881, 0xcfbc2e03, 0x36d8fe75, 0x32e3c82f,
- 0x3d8e189f, 0x6b4d6147, 0xb761d922, 0xe736efc9, 0xa50ab7cf, 0x689a1e78,
- 0x0347b389, 0x3861a95f, 0xe0d9d20f, 0x67e8d4c3, 0x71c14f99, 0x65caecce,
- 0x5e7e3371, 0x424eec83, 0x277ea57e, 0x869fffb6, 0x0c7ebfa7, 0x23690878,
- 0x5e08381f, 0xdb98bb71, 0xf97efb7f, 0x814cfa49, 0x20392af8, 0x82f60e7f,
- 0x1177fe9d, 0x6122651c, 0x2eb7e8de, 0x63ec8622, 0x69b77ca0, 0x669dfa3c,
- 0x7317f4f8, 0xe6b7c52e, 0x042234fb, 0x9c46bf68, 0x80fe0aa4, 0x02f530f3,
- 0x788cabc6, 0x6ee49749, 0xc6f4c611, 0xbc78ea4b, 0xa1d1c6b8, 0xb9d16904,
- 0xee4bdcb6, 0x38699e9f, 0xaf39c2a6, 0x02ab470a, 0x64454fce, 0xb9e80954,
- 0xd2ab6d73, 0x12ac1ec0, 0x2f15dfcf, 0x67679b7e, 0x6125bd71, 0x8ebcdbb9,
- 0xb420fe72, 0x1d9ca35f, 0x8a9f7472, 0x31b59fc9, 0xefdadb3b, 0xf6c0fb04,
- 0x1f776a2d, 0xd683769f, 0xfbb54f17, 0x3e30553f, 0x5c53112e, 0x7bdfc0c9,
- 0x9d82604a, 0xd772a9e2, 0x7e8f68fb, 0xdc468724, 0xd4fd097d, 0x9f6e7e77,
- 0x88727ce9, 0xf338c3b4, 0x8881f227, 0x743bcb76, 0x15f8fd3d, 0xe4db9d99,
- 0xf67b80e7, 0xfebef995, 0xdf9b9e02, 0x84e78556, 0x8ff7de3e, 0x242dff68,
- 0x81d22f01, 0x1d8116b4, 0x4ad88e79, 0xc8e74f01, 0x31f1de6b, 0x3a95b874,
- 0x05ef404a, 0x863b662d, 0xfca6bfda, 0x7ce6cde2, 0x06999939, 0xa37ca4fa,
- 0xce02c24c, 0xb37f54cf, 0x177ec55d, 0x5826fa93, 0x8fee2557, 0x348957cc,
- 0x9ad5ea84, 0x34567f67, 0xb411c28f, 0x88c83f33, 0x66492cbf, 0x4a656076,
- 0xc27d8158, 0x7fc6da0f, 0x832006f7, 0x7104dc3d, 0xfc489228, 0xfc5f483b,
- 0x56fc295e, 0xbaf58d78, 0xc3881c4f, 0xe212ee21, 0xdad603ee, 0x86cf6e05,
- 0xe7c03d30, 0xc705f86d, 0x7615f92c, 0x2452de7e, 0x9cfdd022, 0x12d908ea,
- 0x851fdeb1, 0xbb5edc78, 0x7106957f, 0x7b6ac0fc, 0xdfdc6f6a, 0x0f649768,
- 0xe159f962, 0xf73c72d5, 0xf00b4520, 0xef8f21de, 0xc41f9c2b, 0x9c016f04,
- 0xdc40f523, 0x3a75ce1e, 0xdf215bbd, 0xf3c0a9e4, 0xef20751f, 0xbc7bbfb4,
- 0x9c418ed3, 0xa35a41da, 0xbb5fe53a, 0xa01fb2cf, 0x902ef399, 0x5067d04b,
- 0x09a2e780, 0x235cb9c6, 0x7e3cedcd, 0x2e31fe73, 0x4381748f, 0xdf39ee3e,
- 0xe14770e6, 0x2899093c, 0xb7f1ed9d, 0x63dfc072, 0x56fdc3f0, 0xcaa77f68,
- 0x7df2d7da, 0x9edf3bdd, 0x097c9e9c, 0xa5f7547d, 0xeb31c240, 0xadd49d48,
- 0x7dd61f00, 0xd7f96129, 0x5d1a9bd6, 0xe6f46355, 0x59f04a2b, 0x27a604fb,
- 0x8e813e01, 0x64dfbb13, 0x027087bd, 0x2f4261f8, 0x386d7c3f, 0x7f498852,
- 0x8f04a7bf, 0x6be383c5, 0xd3ebeff7, 0xbbe009ff, 0xf3feb1ff, 0x11dff4fa,
- 0x679afe0f, 0xd10becf7, 0x17f2b5f5, 0x10e1780f, 0x6b52c7d3, 0xacef9c1a,
- 0x0bdab1de, 0x1491f972, 0x3f5d02f2, 0xef718b0e, 0x0c3ba6e7, 0x70ddd3be,
- 0xf396b08f, 0xaf9f99dd, 0x2ff836fb, 0x5590ef9f, 0xb2ec0f8c, 0x2994ed47,
- 0x3096db6b, 0x7f65d8f9, 0xf19be59f, 0x7edd53bc, 0x7ca8beb3, 0x0d3481fc,
- 0xb885550f, 0xff451cff, 0x7ffb76a0, 0xabbb034c, 0xdea3748e, 0xe3077eb3,
- 0xf68c997f, 0xb1253cc0, 0x0e71bd6f, 0xa5e38eab, 0xde1d6dae, 0xbb6baf13,
- 0x9a1334f9, 0xad3bf40e, 0xbb7055df, 0x9f30e1df, 0x42f034df, 0x5feeccc2,
- 0x0583c4f5, 0xceb853ef, 0x2bc57f6e, 0x29f2c7e4, 0x23e77fd3, 0xa5fb1e0b,
- 0x755cbfd6, 0x6b18fd52, 0xb4eb1b5f, 0x2bfb9fb6, 0x2d5a5807, 0x0fe0bd47,
- 0xf1916f56, 0x9ef57bbc, 0x861f3b6d, 0x76dbccf8, 0x7fda70ff, 0xde979ed5,
- 0xabe69eb8, 0xa653929e, 0xe1b869b3, 0x9f41a29e, 0xf2dffa3a, 0xa8f4bd71,
- 0x4525fa7c, 0x7fcacd1b, 0x974bdc9c, 0x290ea7aa, 0x7c5f7464, 0x521c894c,
- 0x85b67ed8, 0xa7f7913e, 0xeab15f81, 0xd0142f89, 0x141f1f5f, 0x1c767a48,
- 0x09796e7c, 0x13c063ed, 0xabd393d2, 0xf6967e87, 0xa82e9475, 0xb2f42d17,
- 0xaf98fbb6, 0xc42fd007, 0x3f7f29e3, 0xb7d84bf9, 0x0fdd9df9, 0xf278a878,
- 0x9f30bc9f, 0xe33d52d3, 0x4ead9ff3, 0x1520fb83, 0xc54d2872, 0x3c579594,
- 0xbfe403fa, 0x907fc7c5, 0xeac5cec6, 0x575cfc19, 0xd173cc06, 0x9e707323,
- 0x7c8824e5, 0x7633f158, 0x4482fccf, 0x238a9f4a, 0xd839f727, 0xab7a763a,
- 0x4f11371d, 0xfb0242c3, 0xe189af18, 0x640f181d, 0x607f0de7, 0x65913fec,
- 0x60e0bf98, 0x30e45af4, 0xa5d1f1ee, 0xb77f9624, 0x9d03b737, 0xd3d50cce,
- 0x475c8e21, 0x87c710a4, 0x2bf69170, 0xce9a9f1e, 0x52681dcf, 0xea8eff11,
- 0x0e5029ff, 0xdd65dbed, 0x8efa6059, 0x1deecc5c, 0x3e3e4eff, 0xec013b85,
- 0xd469d3d7, 0xbf338c1e, 0x9d630e03, 0x0c5676a6, 0x3bc8c59f, 0x6bedff93,
- 0xf21bbc98, 0x0a519e1f, 0x609d9ff5, 0x81df0472, 0x8ae142fd, 0xa1fd63a6,
- 0x07ea02d9, 0x93c6893b, 0x9732edf3, 0x95bd7373, 0x12fc285f, 0x7c3dc7ac,
- 0x2324e303, 0x2dbed01d, 0x8fbf48df, 0xae30abd5, 0x86bf6fb7, 0xfae62f1c,
- 0x1f45ad60, 0x07524790, 0x2d5b7fb4, 0x0c3e7787, 0x35e54bf2, 0xcafc81a4,
- 0x27c15ef8, 0xf1bc8fbb, 0x9fb72a3d, 0x35b90c44, 0xdcab55eb, 0x409dec56,
- 0x27edc9e2, 0x2b893f6e, 0xae3cb4b7, 0x903bbadc, 0x7ad6ff9f, 0xd3e3c0d5,
- 0x7a1a3c16, 0x5a7c3fb2, 0x1db7e4f5, 0x493d5c5a, 0x45209dff, 0xe0d1f97d,
- 0x2aff8343, 0xcf06a5ff, 0xa9f0f50b, 0x7c3d87c1, 0x9f61f06a, 0x8f09a478,
- 0xe1bbfad6, 0xc0853a6f, 0xcfc63273, 0xfdb00fab, 0xd1ddfa67, 0x2f888521,
- 0xd239971d, 0x4a48747a, 0xc96c3e6c, 0x75ed2c47, 0x69603e4b, 0xebe4b41f,
- 0xf7abed4d, 0xb9d8511f, 0x9da9a89e, 0xe4a7fcb8, 0x01f13883, 0x6baa1d63,
- 0x010954fb, 0xf1bbb87f, 0x0925797b, 0xfe5e2079, 0xf2f188bc, 0x26e38a2e,
- 0xeed74e3a, 0x608f7c6c, 0x57c593b5, 0x2f6ed4ba, 0x93ab93d8, 0x553bbe58,
- 0x683d0269, 0x593b7794, 0xd02bafdc, 0xb18a4ded, 0x203fdeef, 0x08ef1ea2,
- 0x7e78d293, 0xa140de28, 0xfd20edf8, 0x80fdb3d5, 0x61d7b02e, 0x30ac84bc,
- 0xd154e3f0, 0xe21cb59d, 0xde22ad35, 0xe2b85b6b, 0x239c2f16, 0xfb903ae9,
- 0xbe5a329d, 0xdb22d7e8, 0x52e90ca6, 0xf81f8c46, 0x9a6d0911, 0xf5fec024,
- 0x059fe47a, 0xb85f9807, 0x797c7d70, 0x95dfe4a8, 0x4054efbb, 0xee7f52ef,
- 0x87beec64, 0x23c54fd1, 0xff03f296, 0x15a6e5c8, 0xdb951fe3, 0x1e41f5cd,
- 0xe4ec183f, 0x92c7bee7, 0xb77fdcb1, 0x9e0fdec5, 0xa77fe62a, 0xeba7d28c,
- 0x3ce04898, 0x2203f9c1, 0x6efce7d2, 0xe3007e76, 0xbf01d7fc, 0xe7b12b77,
- 0x7c82cea9, 0x1ebfd55d, 0xefccfb3b, 0x3e06ee8b, 0xc14ef7da, 0x767a694f,
- 0x7e23dbdf, 0xdf67f905, 0xf4877acc, 0xa0e53f6d, 0xba55f713, 0xff907a0e,
- 0x4dff9ebb, 0x7f90ddd6, 0xecf18ece, 0x145f83ae, 0xad753f00, 0x1e8057b4,
- 0xefe7e2ec, 0x45ff3d56, 0xbfae0741, 0xa9c7488d, 0x9f4fe64e, 0xef5ff03f,
- 0xf381fdc1, 0xc0ace807, 0x42e838be, 0xa5fbaaf9, 0x5d6fe313, 0x14517fcf,
- 0xa5fc27eb, 0xfbe5a9f3, 0x521e5d9d, 0x4be017b6, 0x7544fb62, 0x1b6ebabf,
- 0xd3512fbc, 0x40594876, 0xf0bca7eb, 0xafd002a7, 0xdd997b5d, 0x3c7729d4,
- 0x8179fb0a, 0xca340f35, 0x209d5e94, 0xff698364, 0x0128de6b, 0x978bea39,
- 0x715c613f, 0xfc58f8a0, 0x043e0d7f, 0x4f3fe99d, 0x29854c18, 0xdef8ff07,
- 0x0e27a03b, 0x8d2f91da, 0x59127ef9, 0xe5ccf681, 0xfff4dde6, 0xe885bcdc,
- 0x03bde640, 0xefe13de6, 0xc0d7de77, 0xbed4a1a1, 0xcf97d072, 0xf30bbf9f,
- 0x847e3c7b, 0xfefc8077, 0xfcf9dfd2, 0x7bee98af, 0x97bddd29, 0x7f87f79f,
- 0x9feef3e7, 0xcb9ebfee, 0x79c2aee9, 0xfe17ba98, 0xa95df084, 0xfe12939e,
- 0xbfbde5be, 0xfef61bf9, 0x35bf9b5a, 0x93cf1b27, 0x70b0c03a, 0x40b6667b,
- 0xc8ed7178, 0x9dd82a99, 0xd5ef3f62, 0x7e60484c, 0xf7b02895, 0x1650c821,
- 0xcfdc240f, 0xf80d6382, 0xdd9b880e, 0x4ddc933b, 0xc9137768, 0xbc53aedf,
- 0xbe7abdac, 0x911acf1f, 0x21056f71, 0x8fc9399f, 0xbf8b6ef1, 0x5d1028d9,
- 0x74aef6a0, 0x818f37f5, 0xb48f23df, 0x9805ed45, 0x33690fbe, 0xaaca638f,
- 0xdc87f262, 0x53bce6f9, 0xbcede733, 0xf061073f, 0x0c247c3b, 0xd4716cf1,
- 0xd3ce1561, 0x02256389, 0x4938a54f, 0x0efc086b, 0x7dfccfbb, 0x7ee10252,
- 0xc7865fef, 0xa716048a, 0xed718512, 0x9471e03a, 0x78dce30d, 0xe2f11b48,
- 0x08baf7c7, 0xf17baff7, 0xf80ed4da, 0x663fc094, 0xd5fa17f6, 0x12d3fb84,
- 0x691a42ef, 0x76e69dd3, 0x2cbe8fdc, 0xb25d189d, 0x969d39aa, 0xd062e899,
- 0x4c7d0e21, 0x7cf03174, 0xd2b1f4a5, 0xebff8ac5, 0xf75f1813, 0x2e832f47,
- 0xef1d6e99, 0x7fdcc9d7, 0x133f0128, 0x820199f2, 0x7fdcabfb, 0xbc745290,
- 0x7eaa24a7, 0x7e0097bc, 0xe01a945c, 0x86deef2f, 0x3f73a4f1, 0x00dbff7f,
- 0x44afd54f, 0xebf8a0e2, 0x5121eddc, 0x2b0a5ef8, 0xb6569fe0, 0x404fb889,
- 0xacd168a4, 0xc3627d98, 0x85faa80f, 0xb953e707, 0x4e9e1ed7, 0xf7dcafbf,
- 0x61da0141, 0xcfd1bb2b, 0x605cfd09, 0x14750f74, 0xa5703ec0, 0x2b11fcc4,
- 0x6049acbf, 0xcfb396f1, 0xae20cab9, 0xe762ec23, 0xb7232b7f, 0x7398f6c8,
- 0x9904a14d, 0x739e9bc5, 0x3d085ea1, 0x28f9e021, 0xdcf62f80, 0x9c87e1a9,
- 0xf060427d, 0x9df197ed, 0x4f5dca98, 0xaa7c4275, 0x1fbb2df2, 0x5dbaf8cc,
- 0xc87ee29f, 0xf1ec5f94, 0x2e1fa076, 0x7d12e29a, 0x44bb01e2, 0xb6da8fe4,
- 0x6843f41a, 0x36a2f91e, 0x2beffdc2, 0x7eab57f4, 0xb83efcf1, 0xf4f55670,
- 0x7f885ee3, 0xe1df699d, 0xaec0b8c5, 0xfae7c74b, 0x3591fff8, 0xd6ffffdc,
- 0x3b4f7669, 0x067fffbe, 0xf176a0fe, 0xfb9609d3, 0xb106bbab, 0xb44914f7,
- 0x71ef52e8, 0xf0b9ed55, 0xcfafc428, 0x51e4fdee, 0xcffabb80, 0xfc14787f,
- 0xa9d0720a, 0xba827dc2, 0xf18ebf9f, 0xdfbbe33e, 0xf9d03d70, 0x2f18e3c4,
- 0xfa9b7ced, 0xe75ff41f, 0xc0b3a7f3, 0xea7ceccf, 0x4f10698f, 0xa9f9f3b9,
- 0x9dce6ef8, 0x27494ccf, 0x9189f471, 0x0786ff02, 0xd2b5af10, 0x11db48ed,
- 0x51ce7ff4, 0xd9ff83ba, 0xd489d713, 0xc69978b0, 0xe3bb39e3, 0xc4fbc7c7,
- 0x7d66da6f, 0x4842c6e7, 0x0646bf65, 0x4139c710, 0x006639e9, 0xe3cddc74,
- 0x5d6f9175, 0x0e738e32, 0x3af4a0fe, 0x85e3a16b, 0x3d8f45b6, 0x836d750c,
- 0x44e38dfa, 0x233f8007, 0x413fbefe, 0xe40122ff, 0x60bfef68, 0x37e80cfc,
- 0x73b84e9d, 0xd82c85cf, 0xee48f8bf, 0x85ef8b9e, 0x21576f3c, 0xfcf9511e,
- 0x9d4f289b, 0xf8c71ccf, 0xf071e136, 0x8ff3d24e, 0x99f92bc5, 0x1eedbacc,
- 0x74e1ff16, 0xe690f880, 0x071e72c5, 0xc46d7c62, 0x0b8bfa87, 0x73b1718d,
- 0x40bec627, 0x7877f6cd, 0x6e97a5bc, 0xd7a044c2, 0xcfdc97fb, 0x02a0f030,
- 0x8d8dae1e, 0xc38fc67b, 0x2d3dc4f5, 0x427a0374, 0xae27b3bc, 0x7b13d849,
- 0xcde16175, 0xcef47178, 0xda5e2c2d, 0x8f3fc729, 0xaf41c465, 0x9fe25976,
- 0x3fc581e1, 0x2b8f372f, 0x9760d3c5, 0xf15afd86, 0xf8abf675, 0xae5bfdfa,
- 0xe85f9d81, 0xdaad7f77, 0x3de61f7c, 0x05dd3825, 0xef6d6bfb, 0xa7cf042b,
- 0x2b73b374, 0xf967be7c, 0x3fb3d3f9, 0xd62e3117, 0xfa823914, 0x8c3faadd,
- 0xbc2b57fd, 0x6b787077, 0xe3f5b3f7, 0xd84f5eec, 0x7b39fb4d, 0xebe439f8,
- 0x63efddda, 0xaee8ee5c, 0x988e95a7, 0x8fd616f5, 0xce7ccc70, 0x80a8793e,
- 0xdfe379c5, 0x3171ab1b, 0x40eeb37b, 0x76ea71fc, 0xa71a6a7f, 0x9851142a,
- 0xf1e9701d, 0x2dfa48ce, 0x7699dfd0, 0x3a4ddf19, 0xbee31113, 0xc9701c17,
- 0x95a11f7c, 0x475d0fc9, 0x71c09ef1, 0xf0a77f76, 0x573c04b5, 0xd2f1e77f,
- 0xb7fde077, 0x8358a93b, 0x82b6dfdd, 0x4fdb69f1, 0xef4021f4, 0x13dfe3b6,
- 0x07dafd61, 0xffb18df8, 0x4fd44e8b, 0x50fd50f1, 0x10a06ef4, 0x77aad5d8,
- 0x66cb7dae, 0x938e9f82, 0x2342eb0e, 0x83ee07ed, 0xbc39b9c0, 0x569dee57,
- 0xaa88f00a, 0x7d0a754d, 0xf9bb21e7, 0xafde557d, 0x21ef9aac, 0x6bc6af90,
- 0x266f8fd0, 0xcc664b8b, 0x9f165232, 0x87f7190c, 0xabc213ca, 0xaf7f7ce8,
- 0x28bb3706, 0x8d9e7c5e, 0x78112fd9, 0x06a26a27, 0x2e63d3f6, 0x4bc1de7e,
- 0x83bcecbc, 0x7aa3643b, 0xf6ff61fd, 0x9e08930d, 0x7c06d867, 0x819e73d9,
- 0x2f800b44, 0xea7d768d, 0x321de72d, 0x5a2a13e1, 0x17338722, 0xfd5025ee,
- 0x77866ab2, 0xf11fe42b, 0xb2cdf7b0, 0x3821f748, 0xdb8db0df, 0x1560d9a3,
- 0xe77df6e7, 0x6fbeebec, 0x78a53296, 0x853f30e9, 0x535ff5d3, 0xca7c5ce1,
- 0x0d4fc52d, 0x2d856951, 0xa3dc1a63, 0x78bc7949, 0xcfcd066c, 0x34f4ff5f,
- 0xe2f7ffac, 0xff3459b1, 0xb20e7b93, 0xcf012afa, 0xaeb0bec1, 0xeff01a76,
- 0xd9fb96d7, 0xb9663314, 0x77f0057f, 0x77eef02e, 0xae706917, 0xefe15ba2,
- 0xdda00465, 0x7f0c89d0, 0x9f77ee99, 0x98657f02, 0xf00563ad, 0x7fcf63eb,
- 0x16f78491, 0x2aa1fbf9, 0xdce15469, 0x789a2d15, 0xf3e712f1, 0xccfbbcfa,
- 0x498dcbf5, 0x3f8177c1, 0xbc8de79a, 0xef1d1a6f, 0x0e718ae1, 0xf2d00e76,
- 0x829aa34e, 0xe9c85d74, 0xcb3df84a, 0x8b3e7c45, 0x02c290c5, 0x7f5caddf,
- 0x5751ef19, 0x1ef4578b, 0xdbab8735, 0x67fbefd5, 0x3378007f, 0x007f8293,
- 0x3fdf59fc, 0xb815c57b, 0xe519f500, 0x5c7de25f, 0xeb333de3, 0xea4468bb,
- 0xfb3efb8e, 0x5a2efe56, 0x9bfef07f, 0x69ba283b, 0x682f39ff, 0x39518f7b,
- 0xf150b31b, 0x31cfd1c3, 0xd2fd0bcb, 0x0426c220, 0x1fa71076, 0xf788cf3c,
- 0xb822ee1f, 0x1765db5f, 0xbbaff074, 0x7d4549fe, 0x3a70b99e, 0xae5d5ffa,
- 0x339c08ec, 0xc35bbaea, 0x018a3d7d, 0xe869e401, 0xf828c481, 0x3e1e5487,
- 0xe7c3c8b7, 0x8f37fe66, 0xdb5175db, 0xa9fd81df, 0xa06a3fbc, 0xed8bdcc5,
- 0xee9e9912, 0x8e10d06a, 0x087424a1, 0x8e81fdd6, 0xebe6e397, 0x46cfa737,
- 0x9eeb9e9b, 0xee1ff880, 0x28ffc18e, 0xcc74bf77, 0xe63a3377, 0xd1d0e3bb,
- 0x7bdd6efa, 0x6858e0ae, 0x28fcba77, 0x7d675fbe, 0xdf4aceaf, 0x21f5a93a,
- 0xed2b3b78, 0xfeb8a7c0, 0xb31bf418, 0x29d22c7c, 0x00939e86, 0x3e07318e,
- 0x06bc01b5, 0xe7ec1f1d, 0x9ba9793c, 0xf1d673ad, 0x063acad2, 0x9fb4e307,
- 0xf74cd6e5, 0x451c0a0e, 0x69ca897e, 0x87c58dba, 0xb7efb6fa, 0x9d4b9cff,
- 0x59502cf3, 0x73ff14bf, 0xfe064f00, 0xfbf3756f, 0x7ff17dea, 0xf8a3b43b,
- 0x3fe61dbf, 0xbbcffc00, 0xfb0dfe14, 0x87eb8abf, 0xa29fd82a, 0xda1ff47c,
- 0x3a1cb4cc, 0x8dd134ee, 0x8764b072, 0xd931f7c8, 0x3e865ffb, 0xfd5d7259,
- 0xb917b821, 0xf20267e4, 0xfefe42eb, 0xfdfc27e5, 0xc1b9eb4b, 0xea10b2f2,
- 0x1f9fcbcb, 0xaa3ea30c, 0xff2e65da, 0xbbcf7767, 0xde785997, 0xad352417,
- 0x2b4ebdf7, 0xb9bbcffe, 0xb4e858de, 0xd72f7bc5, 0xdbd68748, 0x33cce74c,
- 0x83f4f4a6, 0xa6cfa0fe, 0xb8f189bd, 0xc409957f, 0xa5297413, 0x2019de10,
- 0xf4094285, 0xd7e5cc5b, 0x72d86fe8, 0x1d9ffaf3, 0xcc43df32, 0x43df316d,
- 0xbe6ade1c, 0x66d57887, 0x51c43df3, 0xc43df361, 0x338d766b, 0xae4747e5,
- 0xb31fb537, 0x3f29b27f, 0x534dfa36, 0x66c7f1fb, 0xda13f29a, 0x7f6a67bf,
- 0x4df35bed, 0x5475d7f5, 0xf86fea9a, 0x7f299968, 0x9b3ff763, 0x311747da,
- 0x61b878fd, 0x5bdc1179, 0x7872f030, 0xa15362a9, 0x9b08e97c, 0x9e5b105a,
- 0x90056ba6, 0x7fe0e916, 0x532f27f5, 0x8a2a3f1c, 0x898ba75d, 0x536fd26c,
- 0xd47ce61c, 0x8f7dfe6d, 0x35722c97, 0xcb527ea4, 0xbc1d9a08, 0x63cf0f24,
- 0xc63af953, 0x01b1dbf5, 0xa0dfb7ea, 0x9b46d57c, 0x2f956f20, 0x9a01bde3,
- 0xad8fd886, 0x1f9f77b0, 0xd4f99a72, 0xf95e8fd7, 0x0738db9d, 0x53facad4,
- 0x264bc6cb, 0x3fca3139, 0x172d8c2a, 0x73c74f16, 0xabf5fd40, 0xb35c16f8,
- 0x3bbc107d, 0xa3530f3c, 0x16cca9bc, 0x67dfdcf7, 0x7fd0bfee, 0x8ec7dcda,
- 0x7cf00cfa, 0x26daf7ce, 0x7b56bf38, 0x51fa377b, 0x5e337619, 0x5decf37a,
- 0x479e0363, 0xac3e481a, 0xb6fdc6f7, 0xebe13445, 0xd177ce36, 0xe0d333db,
- 0x3f66419c, 0x87a155fe, 0x1b47ebe9, 0x042cd742, 0xe98711c2, 0xb456795e,
- 0x39f81a6e, 0xeb79f8c3, 0xe7f8b64d, 0x0c3c92a0, 0x48a0e92f, 0xdd505ec1,
- 0x2b9c2f68, 0x4f0bd77f, 0x0f68dcc7, 0x38e87926, 0x17b4c7f3, 0xbad4fbb1,
- 0x5ee8e67f, 0x947d0db8, 0x026c0ee5, 0x93e592fd, 0x17dd9688, 0x83dbf49e,
- 0x788ef02d, 0xefcdb263, 0x00b77cc6, 0x4c7fd9e3, 0x5e3a20c8, 0x84459fe3,
- 0x75f0f1af, 0xeec83e78, 0xabb8c7ae, 0xcfc24f31, 0xe6711809, 0x89d9be0b,
- 0xabc6cf80, 0xe107ee7b, 0xdc17907b, 0xf7e876c1, 0xc71946c2, 0x982c9c6d,
- 0x4b798dea, 0xf78dbf9b, 0x6cdcb2be, 0xde74e5de, 0x933db700, 0xa8f8d5c1,
- 0xae113240, 0x28f4bdff, 0x5cfb35f8, 0xc507def8, 0xc7c010c7, 0x73fb3d39,
- 0x3a79319b, 0xee419aaf, 0x9ed16bad, 0x4ea7ef89, 0x8fa1e637, 0xe33bd134,
- 0xe2fc332a, 0xc6fd1946, 0x3c6e4945, 0x886e10ef, 0xe79afa72, 0xf99be4df,
- 0x5c295b9d, 0xf8884eab, 0xd1d6b6de, 0xfd28f4ba, 0xe5cdbcae, 0xf17d6b0f,
- 0xf0634e7f, 0x7ba7f852, 0x4f36de40, 0x79e3f9c3, 0x31ff806a, 0x0d9c3c81,
- 0x452c17fc, 0x236c183e, 0xc7d36fb0, 0x7930f04e, 0xd951ed9e, 0x72be357b,
- 0x85be8726, 0xfda76cd7, 0x5dfa7995, 0xb0f36ff7, 0x4f36ff75, 0x72ff759c,
- 0x975707ef, 0x54851fb5, 0x37b445d4, 0x111fa908, 0x3d53476b, 0x1bfd0e56,
- 0xc7f13179, 0xff6fd005, 0x65bf9a76, 0xede5f644, 0x80cfb034, 0xecfb0d0f,
- 0xaed98f4e, 0x3fbbd18c, 0xfbbd30f4, 0xf4c0cf43, 0xfda18fee, 0xe345efe9,
- 0x4aa935da, 0xb4f7bd7c, 0xac1fdd87, 0xe7821553, 0x0fd9fb03, 0xdae5c9d8,
- 0xd6feef3a, 0x1ff9cba5, 0x4f832e39, 0xfcfefacd, 0xf4112d31, 0x4207ca54,
- 0x86b777dc, 0x3c6dbf2c, 0xad9b6bd0, 0xf7cc3378, 0x78fe1667, 0xf59f4d68,
- 0x18f1cc2b, 0x6ac78b8e, 0x099b478a, 0x973c3b8f, 0xb6bf0fb0, 0xdf30afbe,
- 0xf8e4e9f3, 0x09bf7aa6, 0xeb373bc6, 0x6b8822bd, 0x1cf9ced4, 0x1ed7fef5,
- 0xaebccca7, 0x1d397e18, 0xa1e00567, 0x799fd673, 0xe303ae7c, 0xb99eab4a,
- 0x58e2112a, 0x7a0d9335, 0xaa7df044, 0x4839f9f3, 0xecfb7397, 0x2e79c03a,
- 0x3d139d99, 0xa3daefb7, 0xa4f8f710, 0x2c7258e1, 0x793dcf7d, 0xfda648bc,
- 0xbc7bdb9d, 0x7703c248, 0xd43bd361, 0x5b7f1735, 0xdef77014, 0x37e1e84b,
- 0x368f5b07, 0xe57c593a, 0x37173841, 0x6abfda86, 0x7a65f212, 0x285eed9a,
- 0x1dbf1d17, 0x395c21fc, 0xa62fe63f, 0xd04ab259, 0x7ec11633, 0xee373cd3,
- 0xc972f967, 0x9dfa6cc8, 0xe387ad12, 0x6af9c4cc, 0x04efc098, 0xf1444eb8,
- 0xef3c02f7, 0x3ef86076, 0x02b243f1, 0xbdffc29e, 0x78093c1a, 0x09ab3a4f,
- 0x77c41a89, 0x471e6e8a, 0xd30a6953, 0x3ab7ddbf, 0x848cf7f0, 0x53aaaf05,
- 0x3cdafea8, 0xdd8efd93, 0x920b63f9, 0x55691fc0, 0x0df2de99, 0xb463e1eb,
- 0x6be7078b, 0xe6231737, 0x40577c75, 0x921d1955, 0x8a6b6c33, 0xf9c78c35,
- 0x25fe98f3, 0x3dff1a52, 0x1eb7ca29, 0x1c43a6cd, 0xc5cef8d8, 0xfc522bbf,
- 0x7803cebf, 0xf0fcdb46, 0xabfb8f4e, 0x92ca386f, 0x28ccfb69, 0x945e5fbe,
- 0xc39de1c0, 0xfbef07de, 0xd345e34e, 0xd4b5187d, 0x27b74efc, 0xe214b4d0,
- 0x6defd0fc, 0x8bcef8c9, 0x38a29eb9, 0x0bbb9691, 0x0aaee5cd, 0x47e18f9a,
- 0xf6d677eb, 0xae925f86, 0x37f63832, 0xbf0f1038, 0x79fd506c, 0x340e8f94,
- 0xb07f30f8, 0xda34c341, 0x0fcb1230, 0x2f31f837, 0x986cf4da, 0x7faffa4f,
- 0xeebb1490, 0x9d54efc2, 0x75c3e18c, 0xf9ade472, 0x88df8f80, 0xaf15af88,
- 0xdefe478e, 0x3a8e9a34, 0x7367bd86, 0xfefec632, 0xd257f2e9, 0x0d5f284a,
- 0xd3afd1f9, 0xefc3c64a, 0x17f3b096, 0xf63a4170, 0x257aee1e, 0xe093f9a0,
- 0x34c63477, 0xfbc2863b, 0xc95bc1a4, 0xfd239458, 0xbbf089c5, 0x6c337b0b,
- 0x949a7eb4, 0x07f8ecd7, 0x64deab80, 0xe7e7afe7, 0x6c9f1f33, 0xbce3afd6,
- 0x0a66ff4c, 0x71bce3c5, 0x537e09f8, 0x39acfd00, 0x3307b9c6, 0xbf54891e,
- 0xeb8a76e1, 0xdfb3efe6, 0xc754485f, 0xf7bde1fb, 0xcec35ecd, 0xbec5f7a9,
- 0xff99bee7, 0xe1e2440e, 0x29176825, 0x103bf63e, 0x0f7b0a29, 0x4d930489,
- 0xe5cdedef, 0x0606ccfd, 0x1f57d09a, 0x15fde6cf, 0xfb0e791d, 0x8897df83,
- 0xf087eff5, 0xccd8c3df, 0x3574d3f5, 0xed4dec50, 0x5bd4676d, 0x7759ebbf,
- 0x0bd1216d, 0x890143f6, 0xed04bd80, 0xd4bb698a, 0xdc02030f, 0xd7ce33ef,
- 0xcdf80b3e, 0x93ddfdef, 0xebc3027d, 0x8a7d3c93, 0xd4494eff, 0xe3079813,
- 0x123c16fb, 0xca7603da, 0x6206bb3e, 0x8fe47452, 0xf8947ef8, 0xe701c53b,
- 0xbc0f53fc, 0xd9e5eecf, 0xbf38143a, 0x7c5bd2b8, 0x4551c413, 0xf3033ea5,
- 0x816f4ef7, 0xfa9e83fc, 0xdda3d887, 0x1f0137c5, 0x06f7f3a4, 0x01000408,
- 0xe1aa080e, 0x43fd638f, 0x64654eb3, 0x2bf2cc9f, 0x873637bd, 0x3f5f2132,
- 0xf208f80f, 0x7dbfb48d, 0xc021c149, 0x86e16e47, 0x423763e6, 0x037f68de,
- 0x5789ffb6, 0x3b8ffe65, 0x4af60d98, 0x79a55e4f, 0x625e4c4f, 0xa960e279,
- 0x239abf31, 0xd073c47f, 0x3bd807b5, 0x6607a95d, 0xd4cf3008, 0xff1033fd,
- 0xbcb7d5e7, 0x878c342b, 0x04eb608f, 0xf41b978b, 0xa6e1ee30, 0x79f783d9,
- 0x9d61f863, 0xc4c76cd7, 0x0fbc27dc, 0x1fd3ddf0, 0x36cbaf8f, 0xf74a9ef6,
- 0xc6efd88f, 0x547b030d, 0x86b9b884, 0xa3dc2e69, 0x70c1fea7, 0x98395c12,
- 0xcde35fd6, 0xb55e3a41, 0xa9cdfb3b, 0xa75f2f5a, 0x80772964, 0xf8b54e3e,
- 0x3f5cd935, 0x7f8b508f, 0x372b4893, 0xf0b5c10a, 0x8f686c9e, 0x937de2ac,
- 0x4728195d, 0x228eb967, 0x5f3183f5, 0xcbbfefcd, 0x476b832b, 0xc4591e81,
- 0x76556ef4, 0xdfa658a0, 0x8d973d57, 0xf0670bbf, 0x2452555d, 0xf7bb9c6d,
- 0x3791b75c, 0x21e4477e, 0xef09d5b5, 0x5afb18f2, 0x6437fbb5, 0xc7fd3ec1,
- 0x3b46de87, 0x36624971, 0x76d359c2, 0x69df815c, 0x7ca36da9, 0xd8fbbf47,
- 0xa3c763d9, 0xc887f25f, 0xbe026fa0, 0xc368d0fe, 0xd9fdddcb, 0xfd522f55,
- 0xea85d3a6, 0xd3038368, 0xd5fd7a9d, 0xf09c0ae0, 0x49c9b82e, 0x1cf1e9f9,
- 0xeafe055d, 0xf51eb7bc, 0x3a8ae3d8, 0xd3aff80a, 0xe066c3fb, 0x9124aae7,
- 0x5f0febf3, 0x7ef8f3d6, 0xb9efcd3d, 0xbfa6edb7, 0xa160df68, 0x7ba9fed9,
- 0x41fc8dc4, 0x02df92ed, 0xb66ed51f, 0xb3fd6085, 0xbef1da39, 0x1be82773,
- 0xfbe65fd4, 0xa6051b99, 0x5873430f, 0xf772fa1c, 0x74be2b34, 0xfd8c7091,
- 0xe99124bd, 0x84290aab, 0x5f1576fb, 0x2ffeb17a, 0xba69c71f, 0x1c77da0f,
- 0xe31bd637, 0x838ef754, 0xf6fd527c, 0x5fcff461, 0xafb0dabc, 0x77ffd475,
- 0x61cfc53e, 0xe874f538, 0xd0d941e7, 0xa4cfd427, 0x1ee78678, 0xf9243e79,
- 0x47a97908, 0x2e6dacff, 0xf6fa04c9, 0x7eb313d6, 0xb74a25d2, 0x3e781297,
- 0xc9737f74, 0x13ed38a4, 0x8c73ed2c, 0x7fb14ffc, 0x3a0f3c2b, 0xda0ef37b,
- 0xbd93fa5e, 0x6df00f27, 0x4bfa59b0, 0x86dfc636, 0xb7fc19fd, 0x65fbbbc7,
- 0xa5e9ef78, 0x10f140a4, 0x2068df66, 0x15245b87, 0xc0d1877f, 0x3ebe1ef3,
- 0x8d797c55, 0x78bdff09, 0x9f95302f, 0xfb4cd06e, 0x2e178ba1, 0x7b3f7bc3,
- 0x41563af8, 0xdb3eec42, 0x7da6b923, 0xc70fffd0, 0xb8a385d7, 0xfe4a381f,
- 0x328c70c6, 0x385e81e9, 0x5fe54df2, 0x69310e17, 0xec366976, 0xa1b1ad53,
- 0x0b66909f, 0x6ec07239, 0xf7ec5ffb, 0x0734201a, 0x61a899e7, 0xce57da6c,
- 0x079f6039, 0x448e79c6, 0x40e3498e, 0x056d749e, 0x913f53ac, 0xe5a1afd0,
- 0x8619390e, 0xfde1d56e, 0xd8952a2b, 0xb0754e5f, 0xe6f51986, 0xab876277,
- 0xe5a258a4, 0xb879d5e3, 0xdd94e5ee, 0xfdf60755, 0xcfe17736, 0xbc931357,
- 0x5ab27da2, 0xc7f68a58, 0x9b17c49a, 0x3d38df61, 0x0233d981, 0x58f9b179,
- 0x267abc46, 0xbdf72daf, 0x31c41378, 0xaed4aeb6, 0xab6e7f06, 0x0c391c33,
- 0x6e3df9eb, 0xdcaa3dfc, 0xf816e175, 0x83710abd, 0x314bd70d, 0x2b6bbc29,
- 0x6078179c, 0x8bec1f84, 0x40d760ad, 0x5c6e35fb, 0x421a5bff, 0xe2af2f68,
- 0xf5f6c0eb, 0xe7385493, 0x9296e8dc, 0x916bbd61, 0xb8056feb, 0x64efba5e,
- 0xd03ae3b3, 0x4196fe63, 0x80cbef3c, 0x71cb4d75, 0x14f5e58c, 0x68575b19,
- 0x3485c183, 0x44ffc3f2, 0x33d412ad, 0x6b0ed127, 0x04ab2f74, 0xbfd68e3b,
- 0x7a78a0ec, 0x85e3993c, 0xe8f4e7d7, 0xa0cd93a5, 0xbd15c507, 0xef3a12f9,
- 0x7a633f1d, 0x3fda09ea, 0xe7452bbc, 0x18778213, 0xe84947bb, 0xc1242587,
- 0x74d0c76f, 0x9dfb0e74, 0xbd17aa5b, 0x3849c7e8, 0x491f635f, 0x0f7ec519,
- 0x7ac3da1d, 0x83919093, 0x0cca98fb, 0xe2835ef6, 0x66fde371, 0xdd5677e3,
- 0xb3a7f8c4, 0x67df2978, 0x43de5971, 0x895fae70, 0x784ee99b, 0x4f862137,
- 0x0b7bcb15, 0x07cc0912, 0xcd544b7b, 0xe449bfe5, 0xd8834afb, 0xb70eadef,
- 0xa32ed085, 0x35e98452, 0xd9f68a24, 0xf981d268, 0xe66de031, 0x0d2c35c2,
- 0x278d8e2f, 0xbbe2c8ba, 0xc7ec1101, 0x788d5bb4, 0x44f5f04c, 0x96bfdeba,
- 0xfc36e3c8, 0x66538c77, 0x7d7ee214, 0x5fab1266, 0x0fbbc815, 0x338dbcec,
- 0xc69c61a6, 0xf58cefb0, 0x16dfb0d2, 0xab579872, 0xc17b5c42, 0x3a16ebb0,
- 0xb6753e59, 0x8868e0fe, 0x0b53b66b, 0x2fee1b34, 0xf96af8b3, 0xb034e2e6,
- 0xba1e16cb, 0x4ce4ed15, 0x8b65d995, 0x8250ce36, 0xdadee1a3, 0x8a07f43c,
- 0x84484c37, 0x4ed5847d, 0x8575e27f, 0xfbe267e8, 0xc7b503b9, 0x355da6b6,
- 0xab71e419, 0xca90128d, 0xeeb24bfb, 0xb17c0b1e, 0xcced0f21, 0xc6c109ad,
- 0xd6efda24, 0xabfcd67f, 0x4ea7fe68, 0x8c38f0bd, 0xd5813ab3, 0xc051bbc3,
- 0x12e73d9b, 0xc9bbe1b6, 0x3d6f8dfd, 0x1252f097, 0xa8ca7f7b, 0x7e536fff,
- 0x80007d7c, 0x00008000, 0x00088b1f, 0x00000000, 0x7dbdff00, 0xd5947c0b,
- 0x66fdf895, 0x666579be, 0xf263c992, 0xc2130922, 0x9e4e5e4b, 0x124c2280,
- 0x4cb443c2, 0xe8202a10, 0xa79034f0, 0xbadc5d48, 0x30040cff, 0x5706b650,
- 0x84ea2b11, 0xbbaac562, 0x351ba341, 0xb88080ea, 0xda446dd6, 0x8ffd16d2,
- 0x4810154a, 0xfed2b58a, 0x39cf65dd, 0x7cccdef7, 0xb5f01993, 0x3efeb4ff,
- 0xe7ddf7ee, 0xce73df79, 0x12e973bd, 0x2c614dfc, 0x5630a494, 0x51c1d8ca,
- 0x618cf58c, 0x24dea98c, 0x064dcf06, 0x34e2d26f, 0xa37efac6, 0xf5e1bb67,
- 0x926f6617, 0x25d8c6c3, 0x79fa2ed1, 0xa0b199aa, 0xcdb3b189, 0xc11c166e,
- 0x336699d8, 0x1f966b95, 0x9fa0c698, 0xb9850e9a, 0xc55b19f2, 0x3f6336da,
- 0x69923baf, 0x3d0155dc, 0xf4648e0b, 0x5bfe0977, 0xd528fcbd, 0xebc9dd5f,
- 0xaa0eb2d7, 0x4f3192bf, 0xf76b3c07, 0x1cd0595a, 0x51df5fae, 0x4a1f69ac,
- 0xd7bf51d2, 0x3b06fb25, 0x5bdd8c9c, 0x2abefc3d, 0x5d569f78, 0xfae1f662,
- 0x13e38e58, 0x87afa8ab, 0xebe63af7, 0x77aeb188, 0x49de5c04, 0xac4e8a82,
- 0x32b1d0ed, 0xe03ad6c6, 0x1ec62e9f, 0x6c7cd850, 0x15f7f6b7, 0xc2632919,
- 0x9e2ad6ed, 0xf898c70c, 0xa8bc6a70, 0x88d48167, 0xc467dab2, 0x345e35f5,
- 0x0ef3fbd2, 0x63075fb3, 0x3ff4c91e, 0x7fac2d70, 0x1953eb26, 0x909f53cc,
- 0xcd5d8e38, 0x71258b58, 0xba673e37, 0x08a17d0c, 0x53333038, 0xf8337e71,
- 0xc4ebf62b, 0x71944769, 0xed403ed8, 0xa98ed967, 0xc473400c, 0x8303735e,
- 0x90b037f7, 0xce060aca, 0x28fdfa0f, 0x2359dfb2, 0xdd1be5b5, 0x09ecf2da,
- 0x7e6332da, 0x9a4fd782, 0x1a4eca9b, 0x04fefdc2, 0x0311d6a6, 0x5802b72e,
- 0x5eed7eb1, 0x0464e04b, 0x923beb1e, 0xaec6e535, 0x88c9c0ac, 0x1ff16a71,
- 0x135ff059, 0x589d775f, 0xdf4607f7, 0x5bc00ead, 0x71190b3d, 0x46c140dd,
- 0xacc658ef, 0x7c45e616, 0xf16fd81d, 0xcfe812b0, 0x00b76e66, 0xabbb1b7c,
- 0xdef02595, 0x30ef876a, 0xe196273f, 0xfaf03569, 0x0e88058c, 0x39da8fe0,
- 0x5bed99bd, 0xb713e415, 0xcdfedaab, 0xff00dde7, 0x4f0293dd, 0x24ac3d95,
- 0x0ea3ac46, 0x5e1e91d6, 0x07eb39c7, 0x582f8865, 0xa5ec6fcf, 0xa6461748,
- 0xf3d78524, 0x5cb5e1ad, 0x5dc6af0b, 0x1837a236, 0x1844bde7, 0xcea761a7,
- 0xceb2846f, 0x7e4463dc, 0x3ce917b9, 0x1c72de06, 0x6f3c4c4a, 0xe0c73c43,
- 0xfcaceda7, 0x1cc7e43e, 0xc7181fe4, 0x6527eeb6, 0x8f818b27, 0xfa1737aa,
- 0x054dbea0, 0x547186fe, 0x08a9bff8, 0x6d3bd9c8, 0xe9d03255, 0xc3e73b29,
- 0x7a2e890d, 0x0abc50ee, 0xe75d35e2, 0xd5fa47c9, 0xcc43b827, 0x66a3f1c1,
- 0xcb601942, 0xf962c1ae, 0xefe81ebd, 0xcb1b9821, 0xf0098416, 0xcbc2c878,
- 0xefca392f, 0x6ee308dd, 0x0de5e64a, 0xd5b9bd3f, 0x16ca093f, 0xe5439e59,
- 0x416d0c87, 0xffdde03d, 0x44f5c982, 0x28f7b53e, 0x32305e58, 0x4d4c04f0,
- 0x2365843f, 0x4226a65e, 0xf4b720e7, 0x9b769a2f, 0xeed05ea0, 0xa78427fb,
- 0xfb39ff5c, 0x26363cf1, 0x4d7e7f66, 0xacdf797f, 0x53bf183f, 0xfbf87577,
- 0x419dc4d4, 0xc2e76f3d, 0xe7a72c76, 0x9ff43f03, 0x6d89a2fe, 0x0623e285,
- 0xda179b76, 0x632c5dd5, 0xd43908c1, 0xb679f023, 0x5b7241d9, 0xf943afbe,
- 0xa9f9063d, 0x7d70e487, 0xfe46aa47, 0x7f5cb94a, 0x7f4d5af1, 0xc27c8e39,
- 0x43dabd57, 0xe2feadf2, 0x121efa64, 0x736cf4f2, 0xf889e926, 0xc8d20ce3,
- 0x1338f0f5, 0x72f8b059, 0xefa24ce3, 0xcbe61c72, 0x06bdb922, 0xa4240ce7,
- 0x87bc8237, 0x750c2e71, 0x465f2525, 0x0276d99f, 0x67ac4591, 0x63341a9b,
- 0x07dcdbff, 0xfc18be1c, 0xb844e520, 0x1edb51bd, 0x811b23f4, 0x4863edf4,
- 0x7aacffb7, 0xd4fa91cc, 0x5038f066, 0x8af6a86f, 0x34372e23, 0x86647e4d,
- 0x5169280a, 0xd97f3d39, 0xd1e881b6, 0x411f706e, 0x3aeddafc, 0xafbe1f97,
- 0x483ce9b7, 0x730e2d27, 0x51bdf100, 0x7281c1b9, 0x076bf643, 0xb8f38f31,
- 0x7a421b60, 0xd57ade3d, 0x0f54898b, 0xa9199266, 0xc6f7ff1f, 0x0f17c583,
- 0x31bd8f1c, 0xfa0b88f1, 0x6e744b57, 0x910be00b, 0x1d0471fa, 0xdf63f744,
- 0x779cc6a9, 0xff093d74, 0x8436f8b8, 0xe7fe1112, 0x8119ba6d, 0x4d2ef318,
- 0x9e9bbe56, 0xdf25145a, 0x3c3b7f93, 0xd095ed88, 0x49f20a0f, 0xa32696fe,
- 0x90bc2dfc, 0x3922e958, 0x73b5ee9f, 0xb6e385b1, 0x7d9a8ed8, 0xed988fa4,
- 0x3ebfd913, 0xb849fd3e, 0x64aade18, 0x04601f88, 0x4ae37a86, 0x412bb070,
- 0x1597e22f, 0xd3e50caa, 0xa76f3a40, 0x77d7f4f9, 0xeb11e743, 0x0edd516f,
- 0x75fd6ba4, 0x99ca331e, 0xe6398ef5, 0xaa379410, 0x20f9d9ae, 0x02defa87,
- 0xb7d6127b, 0x1cc8ad29, 0xc15a8f8b, 0x2df9c46e, 0xd669d64d, 0x1d669f23,
- 0xf7e8dfe7, 0x9eb9925b, 0xb13fdd68, 0x9f1253c7, 0x79d2407e, 0xcb9b8f51,
- 0x5856c754, 0xe7c0de9f, 0x0763896b, 0xc1e37eca, 0x0b7ecb6b, 0xa87569c9,
- 0x44f68039, 0x549b78f4, 0xbe078f77, 0xf8f9826f, 0xc7c39cb1, 0x3aa254df,
- 0x16d74376, 0x47330257, 0x4b3837d4, 0x6c17fe08, 0xdf0f4c69, 0xc63d2137,
- 0xd3849798, 0x68efe4bc, 0xe8a2f93f, 0xc3b7f732, 0x5d0d10d9, 0xcba2c6b6,
- 0x4b37a879, 0x3999fcf9, 0x9343fe72, 0x8c7c8ebe, 0x49b29ba6, 0x977c83cc,
- 0x5876cf01, 0x66caa76f, 0x807d43ec, 0x9844d6b6, 0xe636cddf, 0x393e9900,
- 0x32677cb5, 0xe7acb7ac, 0x3f219180, 0x1d693a74, 0xf47da275, 0x8e14a6b8,
- 0x838a533f, 0x3dc7499e, 0xf8014f4f, 0xb824f676, 0x99d4f814, 0x0630fa02,
- 0xbc088f7c, 0x9fc6d633, 0xf21c686a, 0xb65fac8f, 0xc3767988, 0x6b0250f3,
- 0xb2bd8335, 0xc607c84f, 0x154fe7ee, 0x99c61718, 0xdde8cafd, 0xf58a2f64,
- 0x80b5021f, 0x43d3d3f5, 0x77fd14e3, 0x585edbc0, 0xeade047d, 0xdbc221cd,
- 0x6bdf46db, 0xe3c69f08, 0x772c74a1, 0x87933d1e, 0x70b670f8, 0x25efb5fb,
- 0x6ee9006b, 0xd3d67e20, 0x0e2eeafc, 0x81e2fe62, 0x8353ab78, 0x2eeb5fa4,
- 0x5877d1e6, 0x129cdfb7, 0x6c1b3efe, 0x2eb00986, 0x4270e666, 0x47c2c4f8,
- 0x896be0bb, 0xa3eb500f, 0x081f02ed, 0x3ec48fa7, 0x4eef1fa7, 0x780666e3,
- 0xefe66b3f, 0xdf246799, 0xfe7d0987, 0x005e4251, 0x0d1f33f7, 0x7a46ce07,
- 0x91e95d50, 0xe2cea77a, 0xac3e6fb9, 0x67abbd9b, 0x5963c04f, 0xed15ada5,
- 0x4f2665ab, 0xcb5dda12, 0xeb2bd3de, 0xc48409f3, 0x3c042b07, 0x5df732cf,
- 0x36ff3f88, 0xc209e38b, 0x97ff769f, 0xf8bca3bf, 0xa2bf681d, 0x9346ef4b,
- 0xcda56971, 0xf596fd8f, 0x876d3c54, 0xad5b2bf7, 0x2efd062e, 0x04fee29b,
- 0xf765bded, 0xf21b5c59, 0xa438bf71, 0x5dfa0b3c, 0x03be60fb, 0x9d7581e5,
- 0x06ecd337, 0xeb7ee093, 0x6de02b4c, 0x8964b293, 0x7dac0852, 0x1516ca7f,
- 0x57feacf0, 0x281667e5, 0xc17f755f, 0x8c75f316, 0x1cb282bd, 0xd0ff59ed,
- 0xfedf6899, 0xf646a712, 0x7f6fb72e, 0xca274479, 0x82a65bc5, 0xece5180a,
- 0xce60d9d4, 0xb78a532b, 0xf4fc6198, 0x0ea14f14, 0x32935bc6, 0xb7f62661,
- 0x7fb1bef4, 0x77df09dd, 0xa99acca4, 0x44de13e6, 0xcaccef7b, 0x926ed0a1,
- 0x54b3cf2c, 0x56697f42, 0x27a7b616, 0x090fbf00, 0x77f68f8f, 0xbdfdbf67,
- 0x1cd4e660, 0x53454bc0, 0xbffd0aa5, 0x96db729e, 0x36315731, 0x877281fe,
- 0x983fc607, 0x15a664b2, 0x9469dff0, 0xf16d97f5, 0xcc9d58c0, 0xbe0186f7,
- 0xbafef1ff, 0x9fa86699, 0x742dea96, 0xcd53fac0, 0x91996ff7, 0x65f81dfb,
- 0x4fbd12a4, 0x1271482c, 0x90461cdf, 0x33ebade6, 0xf82afd72, 0x71d3873d,
- 0x9424797f, 0x4ce511ed, 0x10dcee5e, 0x4e9c7e5b, 0x33b972e5, 0x8f77f621,
- 0xef004b90, 0xb3e90ea0, 0x96181acb, 0xc027961f, 0xc409e64f, 0x3cb9db5f,
- 0x639abe01, 0xd98e3e27, 0x5fe537df, 0xd3f53b80, 0xe8ac7aa9, 0x0d7290bf,
- 0x71c56666, 0x69764cbe, 0xcf5975e4, 0xbfb79252, 0xeb7c154a, 0x5671f0e2,
- 0x330ae56a, 0xb8470cf7, 0xc58b76c8, 0x4b47f33a, 0x88d052ff, 0xe2d6b9fc,
- 0xacf9c0c9, 0xc19e57dd, 0xd787632e, 0xf8d72c5d, 0x98ebc24b, 0xf407ef4a,
- 0x44b9fd0b, 0x5f31eeff, 0x57c95e07, 0x7d1a5780, 0xc33ad2bf, 0x3bfd69fd,
- 0x7ee3fb03, 0xc57a019e, 0x1b9e7b18, 0x415eb853, 0xe422ebf8, 0x5f214ada,
- 0x3d916a41, 0xabc5fe7e, 0x8fcd6f76, 0xf503771c, 0x7a7df80f, 0x412fee0a,
- 0x2b1ca2be, 0xb0b33d53, 0x8a4f597e, 0xa079ed03, 0xde828db7, 0x8937a454,
- 0xa694cee7, 0x76ef5a72, 0x863bb1c5, 0x3913f81d, 0x83c536af, 0x22c649f6,
- 0xc4497e9f, 0x87fca4fc, 0xff453bfe, 0x1f9e9c25, 0xc5e7a7ed, 0x2fc23fc8,
- 0xdf40dcc4, 0x5fce0763, 0x08ce36c1, 0x2582f5fd, 0x7091f380, 0x2ff4b6fb,
- 0xb8ba87ed, 0xda912a7a, 0x260f1c65, 0x219ea0ba, 0xb9f9c5c5, 0x6bc4e3e3,
- 0xe9755f51, 0xebe2e299, 0x2651b946, 0xe7bfa4e5, 0x764a8548, 0xbb2e584c,
- 0x72919ec8, 0x87366833, 0xbdbfdfeb, 0x9446c667, 0x2fbe26ab, 0x1483d34f,
- 0xe3cf0a2f, 0x2fae14e5, 0x2798f827, 0x24781d96, 0x08e52ed9, 0x75e1e3ad,
- 0x5863ec95, 0xd7e85d9f, 0xf93f2109, 0x664c9eb3, 0xf0e13ec2, 0xb67bfa90,
- 0xdcaff429, 0x47a5a64f, 0xa53b0659, 0xee105741, 0x89cfbf1f, 0x8263fba0,
- 0xf3f1a20e, 0xc013e55d, 0x48708fc1, 0xc872e14d, 0xed056509, 0x17f4150b,
- 0xb55cffc0, 0x3f35bdcd, 0x2e36de62, 0x1d7a9d8f, 0xe0576397, 0xfe54b48b,
- 0x3b25efbd, 0x1e1873f1, 0x2ff98edc, 0x1d76f701, 0xc17dc1ab, 0x09f01d21,
- 0xaf8da2d2, 0x598bfcf3, 0x29e7efd4, 0xeffeb93a, 0x1bb72e45, 0xd7ce3c61,
- 0xbfd63f64, 0x3b5da83c, 0xdcdfde7f, 0x658f4e54, 0x68853dc7, 0xdaf30cc7,
- 0x285fb8dc, 0xc07399eb, 0xdde1e500, 0x4b6b038a, 0xc1de1f3a, 0x4ba814f9,
- 0x67ade5c0, 0xa5b5fb22, 0xbefa3a72, 0x38fc31d6, 0xcbc457a7, 0xcd3e08e2,
- 0x7871b54d, 0x084cfac1, 0x472b554f, 0x9bfbf3e5, 0x0180f787, 0xf0075bd6,
- 0xe12db140, 0x64b1d9d6, 0xf8f90583, 0x1f237338, 0xa258ef9f, 0xdd788b1b,
- 0xebbec8c9, 0xf00f0f97, 0x147b4875, 0xe903b2e8, 0x5cd4eaf2, 0x71d86f1a,
- 0x7c0c758f, 0x1376861f, 0xec3b95fa, 0x4c57dc01, 0x4dcdf54e, 0xedce7845,
- 0x4a2064ab, 0xeb4dac1a, 0xfbef112d, 0x7d4177eb, 0x7e9f63a2, 0x36f3ce2c,
- 0xc2bab6c6, 0xfaa981eb, 0x6f5a1fd1, 0xa02d3e04, 0xd6e11072, 0xfbf5e469,
- 0xcf8a3316, 0x8cfbe834, 0xf7f41df8, 0xa3cfa22c, 0x2fc414ba, 0x6ed09bee,
- 0x737bd3ae, 0x67d7dc14, 0x07a8dc98, 0xf4421f60, 0x54c2c87e, 0x26fff40b,
- 0x574e513c, 0x8fd8efe9, 0x502aaaf0, 0xae242ddc, 0x60dc85da, 0xcd37dc41,
- 0x7a25629e, 0x39dd5f64, 0xbff51ab4, 0xfa09e395, 0xcc7e8b31, 0xff30a2e6,
- 0x2aef3afd, 0xfd48ffda, 0xa8514876, 0x8dd7439f, 0xb112ddde, 0x50fec22f,
- 0xaa521ffe, 0xfa40ee73, 0xb23afb17, 0x7ac2d30f, 0x2295ed17, 0xfdde245b,
- 0x3ca17e62, 0x7b48a3a4, 0x7ed3ed14, 0xb1dfd67b, 0xd9c83a65, 0x823a33f1,
- 0xd152073a, 0x01ff33f3, 0xf60551d6, 0x70e005ac, 0x33972a5b, 0xfafdf287,
- 0x30df9c44, 0x3abc3f58, 0xd31be09c, 0x938f0b64, 0xe90ffc2e, 0x482fee46,
- 0xbfcfe04f, 0xe73b72a7, 0x1e5c6927, 0x978d21fe, 0xfb6313d3, 0xf510be2b,
- 0x1f971354, 0xfcb9cb5b, 0x41b7ae8f, 0xedadfbf4, 0x668a31de, 0xef760f7f,
- 0xf76e5486, 0x885fb91a, 0x0a9613c7, 0x873b06fa, 0xabb614f0, 0xda503c78,
- 0xccf45fa1, 0xf372f2a3, 0xbfe8d97b, 0xe69fedbf, 0xb6f487dd, 0xf27a37f2,
- 0xf1149c57, 0xbec99582, 0xbfdc64f4, 0xabf6c427, 0x75d6273c, 0x1f9199ba,
- 0x1b8c53f8, 0x893dec82, 0xaf284371, 0x34e0f9da, 0x2cd5bfe4, 0xe5e0fe40,
- 0x5c51373b, 0x61407970, 0x69f7052e, 0x1627ee5e, 0x47bd58f8, 0xdf4bf1af,
- 0x931936ae, 0x77e984c7, 0x6e369b45, 0x58abb358, 0xf6f6fe53, 0x440b2569,
- 0xfcb0a1c8, 0xa3ef4699, 0x1ef495fb, 0xd47ea76d, 0xc3f8d2ec, 0x461cee97,
- 0x97f597eb, 0x77ad3731, 0x66816b59, 0xf395acde, 0x49f9bc49, 0xd4bb45ba,
- 0x469e731f, 0x008ffbcd, 0xff08fefe, 0x4353d2ff, 0xa92d1e69, 0xba40ffbe,
- 0xcac3cf09, 0xdabf1afc, 0xb027c724, 0x7ee16656, 0xff23a049, 0x5081ece5,
- 0x6fffa72a, 0x71d1f70f, 0xfee305f6, 0xca0beebf, 0xcc397126, 0x0c3614da,
- 0x6aa7e31e, 0xa0bfb4ed, 0xa7c52bbe, 0x616beb95, 0xa45f2d47, 0xd45177ad,
- 0x5dea28bb, 0x6912bfc9, 0x2805299f, 0x0d7f78d7, 0xcff38f82, 0xa0ba351c,
- 0x6e34f8de, 0x3d3916c7, 0x6cef5097, 0x438e24b3, 0x4b36ca7f, 0x52f5005e,
- 0x38bafaff, 0x48336d1d, 0x033b8a3f, 0x5ffed6e1, 0x88a8b677, 0x0fb07dc7,
- 0xfe587900, 0x8a1641e8, 0xae375390, 0x01cb3c53, 0xef2176de, 0x7d7cdcea,
- 0x71a0ee75, 0x5d93f428, 0xd395e7c7, 0x23515fb1, 0x08d4e5da, 0x419a5f7f,
- 0xc1cccfb3, 0x8d254e32, 0x9a9ce3cb, 0xea1432a0, 0xa3daef65, 0x875fd8a8,
- 0xbb337a42, 0x41130009, 0xdc25d957, 0xa4b1b9be, 0x2636595d, 0x5d56870c,
- 0xe00718f5, 0xeadd35a7, 0x8f737d46, 0x0d2437d3, 0x182279e7, 0xf8fcedc4,
- 0xda2a3d13, 0x7a753fef, 0x619cd20a, 0x8ef4b838, 0xd6a7d46c, 0x6d9e7c13,
- 0xae63fbfd, 0x4da22867, 0xdcddabfe, 0x23b3d19e, 0xa487db8c, 0x8c37d2af,
- 0xe727bd24, 0xf4229e97, 0x3df33a45, 0xadfaa367, 0x68c9f08c, 0x861be93d,
- 0x2cf6e6ef, 0x815577c7, 0xafbe0f77, 0xa8aab8ca, 0x6c17de05, 0xa14baa0b,
- 0x62bbcbdd, 0x85cb83fb, 0x4c75813e, 0x75c9f5c2, 0xc82e495c, 0x7e38867a,
- 0xd60fc90a, 0x1ff7b119, 0x2f7d2230, 0x216d347f, 0xa36eb7ce, 0x30949991,
- 0xf4ea7ffc, 0x64f9c6ce, 0x082bb477, 0x93dfe91b, 0x1dff4ae3, 0xfcfe477e,
- 0x96f928c8, 0xfe5c5fd3, 0x2cf7a75f, 0x1b67948f, 0x6927848d, 0xc7e7873f,
- 0x69d5fded, 0xeabecf5c, 0xf9c12ef4, 0x276d7434, 0x3daacf7f, 0xf9631a1f,
- 0xe2f9a3ab, 0x6a54704a, 0x6ea0bef8, 0xeb8039be, 0x25547f2f, 0x68dda83a,
- 0xdd5938a4, 0x9fb8fb33, 0x46e61ee7, 0xb1d75139, 0xe30e594f, 0x4fb33ed6,
- 0xd7011159, 0x05017541, 0x2ec233e7, 0xafcb90f9, 0x3f47ba68, 0x872dda32,
- 0x9c4e5c2d, 0x15f9b72d, 0x8359eb80, 0x9deb0eaf, 0xfdbab2cd, 0xbc3c61f9,
- 0x11fa6fb9, 0x3fb037cc, 0xb3e20a67, 0xd33bb755, 0x475af50c, 0x5f48dd19,
- 0x36fa753f, 0x54525c23, 0x4fb6276f, 0xd7bbb34e, 0x89975b43, 0xfbbca115,
- 0x1f1870ba, 0xefe32745, 0x85d3fce1, 0x91db8872, 0x813fc845, 0xa7b4bb34,
- 0x361dae48, 0xc73c75f0, 0x9eff7cf8, 0xe89079ea, 0x8d0a48f8, 0x54175d9b,
- 0x7f9d9fd0, 0x6b9239e6, 0x9d30ffb2, 0xe4891e79, 0xb3cf2bdf, 0x56f488c3,
- 0xf950e42b, 0x8f947ba3, 0x4bfde623, 0x6e91f430, 0xba019fb2, 0xfdf7d1b4,
- 0x3ea8d333, 0xbdf0b933, 0xe16aed42, 0x79088afb, 0x4311d723, 0xf5c3ecee,
- 0x1cf44ed8, 0xc82772e4, 0xbe628dfd, 0x157cf8d1, 0x9a7c1fe5, 0xde99ea06,
- 0x3123fd1b, 0x48787a2e, 0xe527f502, 0xbedf3440, 0xe51ce82a, 0xfe46cea5,
- 0xe52bb25a, 0x22bd64fc, 0x34fec567, 0xc10f4382, 0x4a977ea1, 0x7a32a9eb,
- 0xc111de87, 0xfd16bf0f, 0x03f9b81d, 0x07fdca23, 0xa25dfdfe, 0x8536fac7,
- 0xedacf1e2, 0xd43ce35d, 0xf4a7fe47, 0xe2ce6768, 0xf1db0126, 0xa784bbc2,
- 0x2e5c9d59, 0x53ee77d7, 0x74c2d997, 0xc0e67f9a, 0xf56748ad, 0xfb86261d,
- 0xdfbfa022, 0xe9a27c20, 0xca47c254, 0xb4f878dd, 0x9472e0ce, 0x47e48df9,
- 0x3e54fd85, 0xdca429fa, 0x4eaa7bfe, 0xfbf809f8, 0x1cbc690b, 0xa7df1fa6,
- 0xdcb08f08, 0xe45f10b5, 0x603a299f, 0x5bb87dc6, 0x5a7f3f21, 0xe4678725,
- 0xc6c7aabc, 0x54ce9b97, 0x50d437a1, 0x587b1cde, 0x7fcbf7be, 0x810bfed1,
- 0xe41f786f, 0xd410d9ef, 0xd1fe72f3, 0x7277cbf8, 0xce831b7d, 0x11d71bfe,
- 0x3da4dfad, 0xc9e6e920, 0x8f46aa5d, 0xea469dd8, 0x731b0ecf, 0x728ec79c,
- 0x61d8cf1e, 0xc76cfae0, 0xe500737a, 0x780b9bc9, 0xa17d995e, 0x43cf8831,
- 0xf875a5ba, 0x1f3650fd, 0x5ba755bf, 0x0dd6e583, 0x7842d636, 0x4b3a24f5,
- 0x19127e91, 0x1e5c8f97, 0x973cf03e, 0x5b7e7567, 0xeb3fc180, 0x5397737c,
- 0xe2cd39dc, 0xf333b8c6, 0xb3ce341d, 0xd72ba40f, 0x2e8dfb73, 0x83ab3f78,
- 0x03c49ff3, 0x2fa253c8, 0xae120fc9, 0xb8727861, 0xf8927e4b, 0x67f4bbf8,
- 0xa77cbd03, 0xda3daabc, 0x46dbdc78, 0xbe4ed5df, 0x706c3acf, 0xc7869fa1,
- 0x6fd1e217, 0xb3b7baed, 0xb51d824f, 0x7a2df33a, 0xfd85be4a, 0x27bf86ac,
- 0x3817bc09, 0x74afbeb9, 0x2da9ba72, 0xacbe20e9, 0xfc44d93d, 0xe5c19b6c,
- 0x5684ed9a, 0xcff6331e, 0xa8dbbd62, 0x63b5955d, 0x5477e61a, 0x7038ae3d,
- 0x6e4f1fbf, 0xfcf0aede, 0xbd774fb8, 0x72f98891, 0xf2b02bec, 0xe1629e31,
- 0xe4eb9deb, 0x5eece272, 0x7bd13800, 0xf672f193, 0x63fa95fb, 0xc20a63c1,
- 0xfac056b3, 0x139533ec, 0xec7e84ff, 0x61ee49bd, 0x9ecfe4b0, 0x3feee9b9,
- 0xeecfbcc1, 0xf746e299, 0x978b5a65, 0x69cfa7e8, 0x037ee371, 0xf40cf7c4,
- 0x78efae17, 0x685af123, 0xabe9fa77, 0xd76e508b, 0x799e798a, 0xe10ebf5e,
- 0x7fc9e1b2, 0x6bdf8c9b, 0x09aa4a03, 0xf8fbd9c7, 0xbe63677f, 0xf2469eea,
- 0xfd3cb517, 0x17f311ba, 0xfe768174, 0x03926f7e, 0xf9fe9deb, 0xef08c9f6,
- 0xfa168e96, 0xede7e67e, 0xe4f03e54, 0x77f6bdbf, 0x1378e3f4, 0xccef58dd,
- 0x2f09fbf3, 0xf2953e75, 0xf5d1e2db, 0xb9fb7d8e, 0x8f3d44bc, 0xcb9f307c,
- 0x92d74931, 0x793f4f7e, 0xbd48c4db, 0x0ab7df21, 0x026b4e7f, 0x099f23d7,
- 0xe0adadfe, 0x9ecfcef1, 0xfda7ccb5, 0x1c343181, 0x6375c5f7, 0x2ddc5d38,
- 0x71d751e0, 0x46c1a187, 0xdf9fa9ed, 0x73e3df02, 0x27e7d02c, 0x64852923,
- 0xd7ca25cf, 0x0faa57f9, 0xbfa026f5, 0x1f45e6e7, 0xeb1f382a, 0x2d432698,
- 0xfe69f3cd, 0xf91d561d, 0x6c6d6cbd, 0x38bffb3f, 0xe02ec26d, 0x59dd907c,
- 0x3922e39d, 0x8b0f7260, 0x6bb387b0, 0x27182d7c, 0xcfad7ebe, 0xbe3c07ad,
- 0xb4e8ea7c, 0x727e5041, 0xf84c52a4, 0xcf5c2bd7, 0x4e346df9, 0x81c1fa3d,
- 0x3e0b768f, 0xf5307749, 0xdc03921a, 0x32a5501f, 0xaa7e46d5, 0xf513923e,
- 0xee0f42ad, 0x736e7e11, 0x764dde5f, 0x26bb676a, 0xed061f62, 0xf72a366c,
- 0xf310fde5, 0xe7f8674a, 0x1971de93, 0xa467be69, 0xf27e603c, 0x8b7e4a7b,
- 0xbca11bf6, 0x57d1fcc1, 0x285de59d, 0x3d33e51f, 0xefe4bf8e, 0x74b8fbe2,
- 0x15ca174f, 0xa35537b6, 0x95c9e20f, 0xe79f3703, 0x0f95fb7a, 0x901b0e89,
- 0xdf7c710e, 0x5ede8d49, 0xe815c24e, 0x890fa5f0, 0x7177970e, 0x55d0daf9,
- 0xd4fdc46e, 0x69d7e10e, 0x7484f410, 0xbfe8fb84, 0x9c69933a, 0xe1a1c986,
- 0x0bcea728, 0x12ff3bba, 0x3a43b7a7, 0x0e01f91d, 0xdedd1eed, 0x8fd40ca2,
- 0xf0978d4a, 0xe6f800dd, 0xa3daf376, 0xd7d56768, 0x6bf23730, 0x07e0a743,
- 0xbe117bb0, 0xcbd55d0d, 0x6941bfb1, 0x0ddfc933, 0x41b4c976, 0x63a86e50,
- 0xd96fc8a5, 0x425e2abb, 0x7c5d60ba, 0x035d9e3f, 0x4dd22cf6, 0x9f5bbd5a,
- 0xdb8f7a8f, 0x2c8fd7bd, 0x723bf6a3, 0xf2e7145d, 0xf38a3157, 0x19fb40ef,
- 0x68d65df5, 0x36fb3f6e, 0x5cc5dd92, 0x6537e409, 0xd60d753e, 0x622ff06f,
- 0xcd11d794, 0xb4292fc7, 0x5808680f, 0x56681f29, 0x1a7fb717, 0x9f1f38ba,
- 0x4f91f093, 0xe4adcf43, 0xc4c17f8f, 0xd0fe11fc, 0xce9a5f37, 0x268becf5,
- 0x359fb3d2, 0xb0c7d87b, 0xbc85b7a0, 0x6dac7097, 0xdd21d7cb, 0x09937632,
- 0xcc4cb1e7, 0xf5c0cda3, 0x03d0b246, 0x3cf8db05, 0x77e174d4, 0xa789d74c,
- 0xe2e79b51, 0xe17f93f0, 0xc88f189c, 0x39e85d22, 0x797eba18, 0xeea4f890,
- 0x9a5fde19, 0x677853c9, 0xfb4abd04, 0x0b1e9a28, 0xbbd9b8c4, 0x4c282a0e,
- 0xd1cd77b2, 0x35f5f9f0, 0xeb08d82c, 0x2e977ebc, 0xd91c6538, 0x9e490b4d,
- 0x58b237af, 0xd2232af9, 0x9556fdb9, 0xbf442dea, 0x36cdd576, 0xb93fa477,
- 0xb3a3c12a, 0x24571da0, 0x12ded8fd, 0x4a9d1b8c, 0x6f11bbb7, 0xd25dd2e3,
- 0x5bd8d30e, 0xdcdff703, 0xcda1bc0e, 0x1ff70e3f, 0xf309f581, 0xda09ae29,
- 0x0edcfc8d, 0xf7fb8f68, 0x9cfed7dd, 0xb85bdfef, 0x070402ff, 0x6f5499c9,
- 0x9d8ffa09, 0x5cb5de05, 0xb1ddd93f, 0x93aaf3d6, 0xcdc0e7af, 0x3ee216b7,
- 0x8dae61b1, 0x5781e1f8, 0xde9ca594, 0xbee21140, 0x83f9c7da, 0xe13c7f01,
- 0x3b247a22, 0x1bc9a1aa, 0x9c8f4d88, 0xaec01a5f, 0xe81b3b42, 0x93b70d71,
- 0x13f38c6d, 0xbfb94ba7, 0x6915b947, 0x8d3e4acf, 0xbf497be6, 0x35ff7cfd,
- 0x81bcfdf9, 0x8079e3f3, 0x3f7bd203, 0xe9ccbf9d, 0xe07aeb7c, 0x15bef847,
- 0x4225b1f8, 0x7fef47fe, 0x1fb89e70, 0x1ef6f290, 0x3a5177a7, 0x6fdda1ca,
- 0xab50c66d, 0x2f0d8f94, 0x397e196f, 0x958ccbbb, 0xf0335fa1, 0x60fd246b,
- 0x445ed68c, 0x09ea3f4f, 0xfed8baeb, 0x6dd2bb8f, 0x3f3fcddf, 0xaee52f30,
- 0x7981d2f4, 0x73a8e929, 0xadbb6f10, 0xa58fb401, 0x3e7a291f, 0x499f044b,
- 0x03fdca7c, 0xfeb021c6, 0x37ef82fd, 0x888f7a89, 0x84bec467, 0xf3a5c1f8,
- 0xf679487d, 0x6c91f471, 0xb5f97df7, 0x2f5238e4, 0x8c8dd346, 0xaa7ae0a3,
- 0xd7afc4c7, 0xcfec5fb6, 0x29f8e8a2, 0x800b5fc1, 0x6dde7037, 0xc417e086,
- 0x19d8778f, 0x99f813e5, 0x71e31527, 0x7ce08daf, 0x386fb234, 0xfa66b7b6,
- 0x92ba44be, 0x8f7c5d7e, 0x115aaa71, 0x6bddacbf, 0x7f9e4408, 0xd18337b9,
- 0xb376bd38, 0x91fc0f5f, 0x87dbe99b, 0xcc15fded, 0xf33d441d, 0x2b8a168f,
- 0x8a5b8181, 0x8591a6f2, 0xefce1112, 0x205efb25, 0x0cf7d5fa, 0x39e3bf47,
- 0xdf0e3425, 0xdafe109f, 0xfb5fc213, 0xcf7bd77e, 0x17ad02be, 0xf16e72bf,
- 0x5ece918f, 0x7d21e4b4, 0xe7f4b09c, 0xdda125bf, 0x92b9817d, 0x690e772e,
- 0x55ef5991, 0x2767fc23, 0x7ffdb1ec, 0x373c0b6f, 0x532b788a, 0xb7c3ed19,
- 0x19f97067, 0xe3c4bf3e, 0xb4ebefad, 0x1cf937fe, 0xdfe1c193, 0x501ce719,
- 0xd7df0661, 0xfce10e74, 0x50aed7d8, 0xdd66afbc, 0x41eb3ffa, 0xb5acd42e,
- 0x9f09e907, 0x71ab8ed1, 0x283a83f8, 0xb970309f, 0xcd737f04, 0x07fd6165,
- 0xc849d4f5, 0xc5077e33, 0xfd0a96bf, 0xcde9acb5, 0xa15fa1bf, 0x49e66546,
- 0xf2c71845, 0x9f041e1e, 0x4f2db53e, 0xf2bff144, 0xa3a67747, 0xd458ca7e,
- 0xa6c1f226, 0x55fed03a, 0x2fe8373c, 0x6f672f59, 0x132764a9, 0x1ede001d,
- 0x22f6f0cc, 0xe24a2f1f, 0x7745c17e, 0x08fe035a, 0xf057b879, 0x7cfd3461,
- 0xcdbce710, 0x01151997, 0xaa616fec, 0xefd46ff7, 0x7234e79d, 0xfa12bced,
- 0x5f4823c5, 0x4fddd877, 0x22f2eef0, 0x05d263f3, 0x0e316bfc, 0xb7b1a204,
- 0xbaf867b0, 0xbee3a47c, 0x5fa1dfbc, 0xf0e4dbab, 0x91bbf0bb, 0xf176cbbe,
- 0xe3f141e2, 0xd2232e40, 0x8545c347, 0xf76961e8, 0xae51c79b, 0xa221a837,
- 0x1b66a593, 0xa2e1b1e1, 0xd5a9e9ca, 0xdb243670, 0xa4d7ee03, 0x6032d27a,
- 0x277bfe9e, 0x093c5325, 0x17c389f8, 0xe39c452a, 0x37c332f8, 0xf7e00328,
- 0x36f13590, 0x305d7fdc, 0x8f3092bb, 0xf408d1ad, 0xe7753570, 0x43d84735,
- 0xa5aec72c, 0xfeb7ee83, 0x6e5af386, 0xaf5119f6, 0xd134f0af, 0x4945b179,
- 0x98c752c1, 0xd24fbc48, 0xf5fd1a5f, 0xc8497ef1, 0x3c8df797, 0x9d20646f,
- 0xcf6c3c73, 0x39b2f510, 0xc79fbcbf, 0xe7c39e6a, 0xbb427828, 0x728887f7,
- 0x170f2891, 0x7979d2f5, 0xf797e09a, 0xd17af1c7, 0xe3152ce3, 0x99e1997c,
- 0x7682708c, 0xc7d22341, 0x673a166b, 0xfe404ac4, 0x935bbca1, 0xc82c764b,
- 0x770869b9, 0x4c982718, 0x67a44cf5, 0x41c81358, 0xa96f67c0, 0xb5b3e08b,
- 0xe305e81c, 0x289aaf41, 0x2bf1241e, 0xcf8d1af1, 0x77ca1985, 0x181f4fcb,
- 0x51985ebf, 0xcd7e303a, 0x17c250d8, 0xf38c4bd1, 0xf5f0f11f, 0x03c73b6b,
- 0x0cf2ebf0, 0xb1c183d2, 0x49b37c91, 0xb5ca51c0, 0x78b413f7, 0xe39d3cfd,
- 0xbbd45ea1, 0xda1f7684, 0xe23eeed1, 0x7853f7bf, 0xae02b4fd, 0xfe5da497,
- 0x5f2e024f, 0x529f6ba6, 0xd1fb44cf, 0xe2f214bf, 0x47ee74cb, 0x8ddebc07,
- 0x09fa95f3, 0x19304ce4, 0xebd178f8, 0x6c339226, 0xd5e51f63, 0x83ffbd40,
- 0xea645af0, 0xf41535bb, 0xdec10fca, 0xbb511631, 0x0647284b, 0x48c7efec,
- 0xd433b0ba, 0x0e19addb, 0xf4941f6e, 0x48d7b8f1, 0x0ca5aebe, 0x657287e4,
- 0x210c63fc, 0x6bf0e40b, 0xc142bf22, 0x6214aebc, 0x07f61767, 0x8c97ff70,
- 0xa3dc30d2, 0xe8213bc7, 0x450cd1e0, 0xb215bc25, 0xaddbc442, 0x5f6e7eef,
- 0x139e5d0c, 0x4d9365e7, 0xe7ec76be, 0x916fddec, 0x18c27e9d, 0x8b66de1c,
- 0x7c18ddf1, 0xfc2521ec, 0xf4a7b6fd, 0x98d5e37e, 0xc1f67e7f, 0x4bdd619b,
- 0x1c6ef47b, 0x5f3de972, 0xed1e33bc, 0xc5031eec, 0x6fdf406b, 0x4dde7153,
- 0xa13caedc, 0x67c1d2d3, 0x3df76977, 0x907a0baf, 0xdca572e7, 0x157cfa91,
- 0x93797373, 0xcb1bb890, 0x3b71dd1f, 0xce5dcb9d, 0x003d87bc, 0x666bd3f7,
- 0x3b7c5d92, 0xcf5e51f3, 0x39ed56b2, 0xda6d15db, 0x073bedf2, 0x3925c39c,
- 0xfd102abc, 0x2ba5f85e, 0xf3fbeb63, 0x333f2e82, 0x7afdf88a, 0xfdf8cc53,
- 0x09fc85ef, 0xb4fbd9c7, 0x2f57fbf1, 0x8c6fbf1f, 0xed87df8a, 0x3df8e888,
- 0x6113f7ef, 0x91bf606f, 0x2acffc71, 0xa3e3af62, 0x58b7690c, 0x9f19f935,
- 0x125bb00c, 0x45e37be9, 0xd8f99c4b, 0x2b67fde8, 0xd7d38f63, 0x5f368e3f,
- 0xe79edc20, 0xb5fdc809, 0x8bc693a4, 0x6567a459, 0xe1c7da59, 0x3df43976,
- 0xf4babcfa, 0xf8be4b6f, 0x2ce66158, 0x176d47f2, 0xf29bbc76, 0xbb463f33,
- 0xba72f908, 0x4c10b5eb, 0x278fd971, 0x8487570e, 0x1d7a26f9, 0x42675f40,
- 0x98d8f211, 0xfd234f69, 0x3a6e66eb, 0xfee82797, 0xe8abbbd6, 0xbdffcf7c,
- 0x322332a7, 0x53f72a6e, 0x8f69460d, 0x96fa34d9, 0x65e3e945, 0x1d916f5d,
- 0x70d7f606, 0x7a7f3e14, 0xc3d26ef5, 0x1d37992b, 0xd5f7bde9, 0xe56e7411,
- 0x3961eadb, 0x4bfc9b9f, 0x35bf3c0c, 0x3987ec8d, 0x75373e62, 0x67503b73,
- 0x1c6818f6, 0xd239730f, 0xe7cd8b69, 0x8554420b, 0xf3fd75f2, 0x631de747,
- 0x15fcc493, 0xbdf00f6c, 0x52d93c4e, 0xdbce265f, 0x31eae384, 0x8990260d,
- 0x6e8996cf, 0x28a73e17, 0x83cf955e, 0x6b1a79e3, 0x3afac1ca, 0xd7cf4873,
- 0xc7483309, 0xa2f0fdf6, 0x37945db2, 0xeb70bdce, 0xb36f7c0a, 0x8a313c93,
- 0x04cf4c79, 0x6dfc88b9, 0xb75c6666, 0x4d3c16c9, 0xf4f133f1, 0x8f88b857,
- 0xf91843fd, 0x07581241, 0xd9b53f9d, 0xb171f9ce, 0xb050e60e, 0x085c716c,
- 0x9ce27ee2, 0xf3c7e6c3, 0x672f20c4, 0x5f3fa265, 0xc44ad5f9, 0xee67c80b,
- 0x5df78a17, 0x11f3f20d, 0x88a5de42, 0x7908b5f9, 0x8adcc597, 0xe480c7b8,
- 0x95f6fddd, 0x267ee037, 0xa3f7798d, 0x71387bbc, 0x32fdc506, 0x93e68f98,
- 0xc8d5433a, 0x5b57a72d, 0x46af98ce, 0xe7053bcb, 0xbed3e597, 0x9413b337,
- 0xbd04a497, 0x69529799, 0xfd12361f, 0x37210631, 0x3e78598e, 0xcf3166c2,
- 0x8853333b, 0x78598e6e, 0xb6b7c25e, 0x7ddadc5b, 0x3f0a437d, 0xdd3e7fbf,
- 0xc0f1c66c, 0xe113b98e, 0x07cc7607, 0xdfce167e, 0x41d29c2c, 0x6f9b0279,
- 0xe01bdc54, 0x6bbb66fd, 0xeba40abd, 0x7f70a99f, 0xc728ea8f, 0x3cf69c7c,
- 0x44f31b87, 0xf7be451b, 0xf6a38b66, 0x9a63f219, 0xb7d63d78, 0xed96e319,
- 0xac0e1d5b, 0x37d95697, 0xaafb88cd, 0x9bb1cc15, 0xaff7a0c5, 0xbe608f80,
- 0xe032c73f, 0x63f41149, 0x85bae23d, 0xefbe20d6, 0xf0177fc1, 0xdc3294f2,
- 0x82bff2bf, 0x773a42ee, 0xd27a3cc9, 0x85dd8d97, 0xbc60d86f, 0xe485b982,
- 0xf256f7af, 0x72132fb8, 0x571cbc60, 0x61b5d9f0, 0x85efa7ba, 0x5bb43ca2,
- 0x4cd37ff8, 0x80ebae3c, 0x91c4ca21, 0xc69fac43, 0xe4cdc1f9, 0x6bd3e71f,
- 0xfb0ff858, 0x4ff70cab, 0xf86a6972, 0x60ef9873, 0xbbb322a8, 0x8dea0ea5,
- 0x91fb8357, 0xcf15afaf, 0x543cf142, 0xe5e9237e, 0x65cd9d1e, 0x373e71d4,
- 0xc3aba017, 0x94b847ab, 0x60b4b639, 0x4129d73f, 0xd8cde67a, 0x9fd382de,
- 0xc94cfc23, 0x9e00c699, 0x00996b37, 0xc8bf2678, 0xffa30f9f, 0xac2fff5a,
- 0xcc74f118, 0x279ef520, 0xb9ffe789, 0x0ed53d68, 0xce97593e, 0xc22e7b33,
- 0xcf3f28f9, 0x8b74d0c6, 0xa997fef8, 0xd7974955, 0x300f3cbb, 0xe5cf4b25,
- 0x871e0ce3, 0xa66f9c6d, 0x7146e5bc, 0x7d53030f, 0xf08c3ff9, 0xc5b8c8af,
- 0x7f3606bb, 0x46fd8c5f, 0x07b7164a, 0xfdc0dce6, 0x1f228dc2, 0xcc4f7e47,
- 0xbfb27ee2, 0x377b4e64, 0x1e3dec93, 0x949dfd6f, 0x48d9235f, 0xf2115f94,
- 0x5f248fe5, 0x278edfca, 0x85dfb47f, 0x29e799fc, 0x40bed036, 0xef2921c8,
- 0x68ef22bd, 0x1018f301, 0x1ee23d4f, 0xabe5a395, 0xccdd0e48, 0xf7fef47c,
- 0x00ff3c15, 0xfd80d308, 0x6b4334dd, 0x6af3cd3f, 0x8fcf37cb, 0x3e38afb6,
- 0x7c0bb8e4, 0xa473efda, 0x6b433c9d, 0x87fa2f27, 0xcf4992af, 0xfea2fc67,
- 0x3e70e0d2, 0x3e546351, 0x27c88351, 0x3c2aec6a, 0x4f911694, 0xf3cdd8d4,
- 0xaeba1a89, 0xedc44f94, 0xb029af29, 0xde24e31f, 0xec94d25a, 0x727f910d,
- 0x8a4ff310, 0xaf6e74c2, 0x0c3cf3b0, 0xa2bca1e6, 0xce95871c, 0x8aeab45d,
- 0x9adb8fc8, 0xddf8d768, 0x5577aeb7, 0xbfe93d61, 0x4843f995, 0xc3f6b137,
- 0x5f7c59d9, 0x7ee143b3, 0x3302ff74, 0x059d3bed, 0xc15c4d5e, 0xd1c767a9,
- 0xa66ef8af, 0x3f27d64b, 0x2f830ec9, 0x019e18ab, 0x8979d185, 0xb67af6fe,
- 0x5190fc91, 0xea99ca72, 0x338038a6, 0xf5f92c69, 0x921775e7, 0x2cd9923f,
- 0xb84a61ee, 0xdb7379ff, 0x69ebcc55, 0x97576eec, 0x3774c2db, 0x43ec4b36,
- 0xf48accac, 0x7bd7efda, 0xbd7e44ce, 0x30b79364, 0x19d7da0b, 0x8bbfe483,
- 0x1f7a57a0, 0x2ede5f4f, 0xe150c5e8, 0xe602b05d, 0xd18efbd7, 0x0a6bfb8d,
- 0xcfff41cc, 0x7e4c94bf, 0x230e7549, 0x9cb1b53d, 0xf45e93cb, 0x3e3ac193,
- 0xfaf7e64d, 0xa466ac6c, 0x4ca7cf5f, 0xc55e3a23, 0xe83d8702, 0x7405db47,
- 0xd2cf7918, 0x8eb96d1e, 0xa9fe9075, 0x3d00667b, 0xf2947c93, 0xf4b99eb8,
- 0x741b8c06, 0xa1b3db6a, 0x285c395a, 0xbcf147f4, 0xff982da9, 0xf2e3ac50,
- 0x0f772d91, 0xf5fb439a, 0x2c4f8e45, 0xa17f7228, 0xebaece5c, 0x73d29fb5,
- 0xa17ae7fe, 0xad1ff454, 0x3d854abf, 0x17e41937, 0x7da56fee, 0x7ca9f506,
- 0xcfadd750, 0x59e785d4, 0xbb49da22, 0x890bea50, 0x8c09f2af, 0xbbb579e1,
- 0x1a7c84b2, 0xbe2086c2, 0x13e27fa1, 0x29583705, 0xf71fbfd4, 0xf18ad785,
- 0xa8fc1e80, 0x733afdbf, 0xb36be900, 0xd2fa44d2, 0x3c3ff68c, 0xd23e2ab7,
- 0xe35eff0b, 0x4c7d23d7, 0xdd374d64, 0x9926f500, 0xb728ac7b, 0x31fe4e80,
- 0x585a7e92, 0xa29f6f30, 0x7efa23a1, 0x98edf936, 0x5af52474, 0x9edcf7f0,
- 0x74bcc599, 0x0fe793cf, 0xa83aeedc, 0xd8267df0, 0xeed1079f, 0x93375b7a,
- 0x2c2664e8, 0x3955eb03, 0x9e9ff8b4, 0xdf472da9, 0x5ad0c50f, 0x48744328,
- 0x9c540678, 0x51bdf44f, 0x98f7291e, 0xb3e5ee56, 0xf8de78af, 0x423fc396,
- 0x1d7583ff, 0x0ef6891b, 0x8fc4aa58, 0x27b0f4d1, 0xb78f7beb, 0x118ac9ec,
- 0x7e15e96f, 0x68586be5, 0x40ca33e5, 0x687f3b7a, 0x82333e9d, 0xbc7f252e,
- 0x1379e06c, 0xae3cebca, 0xc6ccc135, 0x252e1104, 0xf928ffdc, 0xd3a41ae3,
- 0x95fd3094, 0xa487f789, 0x06cc197c, 0xd75dbd23, 0x01ea0965, 0xbfa2853f,
- 0x8afe906b, 0xdc89f6c2, 0x184cb477, 0x98f96740, 0x4cf60e17, 0xb495d201,
- 0x8e958a4f, 0xfde73c16, 0xb6f74bfc, 0xe8237ce0, 0xc3842dea, 0x8ae80559,
- 0xf4036afc, 0x147bf6ad, 0x4bfc49dd, 0x359cba7b, 0x6e677ed1, 0xc1b3d702,
- 0xcf49dbea, 0xba24b882, 0xa70e737b, 0x21e62abb, 0x5a672bba, 0x6b34a97a,
- 0x0974d1cb, 0x74b4ea23, 0x8bba23e7, 0x7478d7a6, 0x4ee91837, 0x2bd4dbea,
- 0x48e7ddd3, 0x8fc5df77, 0x3eee9039, 0xa7c672cf, 0x937a68bb, 0xc59f6cf2,
- 0x75768951, 0xfa428d63, 0xa19df8a1, 0x511e582d, 0xf6764f9f, 0xd93764be,
- 0xfc4d8ddd, 0x478f497b, 0x0533798f, 0x7cf7c56b, 0x1b96256f, 0xe877c1d7,
- 0xcf18f4ba, 0x0f7a19ab, 0xa1b85eff, 0xbfbc0de9, 0xdbcfd1a0, 0x337a7cbf,
- 0x6c0a879d, 0xdbcbed16, 0xd8dcb12a, 0x8a7fdbca, 0x31abae71, 0x82d02dbf,
- 0x96daafef, 0x6fdbe6ef, 0x114fd76e, 0x3ca7ddeb, 0x6bb506f7, 0x3f6eede3,
- 0xe4604e6c, 0xfaf6e027, 0x29ceb164, 0xd33af8bb, 0x867ebe3e, 0x4563e80b,
- 0xb9ec9f9f, 0x6575744f, 0xece2ef24, 0xb695cbb3, 0x474e7c1c, 0xbc47a639,
- 0x43f55bbb, 0x37741c78, 0x3675710c, 0xf8c8d3f7, 0x5429e621, 0x5717d847,
- 0x443b7367, 0x614f4bd6, 0xfd8d7e74, 0x72fe4ecc, 0x3e0cdf19, 0x07d414c4,
- 0x976146b8, 0x4e778cc4, 0xbb22682f, 0x1960fa62, 0x4ba90ce7, 0x4bc2dc61,
- 0xe58b4f9f, 0xe6cb2a47, 0x9129f3f6, 0xd7df2177, 0x4875f204, 0x4890fb17,
- 0x90f0fce8, 0xdb9ed077, 0xe734cc97, 0xf3e5f6dc, 0xbcecd4f2, 0x01cd6e7f,
- 0x549aeaf8, 0xe58bf7bc, 0xf2b79429, 0x4c161e83, 0xff381c4a, 0x1a0b2ae9,
- 0xcf8a0f29, 0x518b657f, 0xe5c257dc, 0x3f813cda, 0xd1186936, 0xa7815cef,
- 0x17a16cea, 0xca31598b, 0x6f0279a9, 0x1937343f, 0x336ebeb8, 0x798fc944,
- 0x1e3f28d9, 0x6bcf6b8e, 0x97c947bf, 0x4aee311a, 0x62afc761, 0xfd3fe47d,
- 0xa7f1d844, 0xfc76e61e, 0xfe41d66a, 0x719fded3, 0x961ebe3b, 0xed12f487,
- 0xabddad07, 0x6877d72d, 0xdea00dcb, 0xaec6ffb1, 0x8633b928, 0x1f7ba5fb,
- 0x3f432fae, 0x77cecd64, 0x235dffc8, 0x2b404ce5, 0xe740c067, 0x51a1e672,
- 0xd6fabfe4, 0xd819e3f2, 0xf26995d5, 0x76c9ef4b, 0x5e77f846, 0x0d2e79e4,
- 0x7a11fb8c, 0xc16f23ed, 0xd28b2c7d, 0xa572d14f, 0xe915c850, 0x5bf290ff,
- 0xc6429bca, 0x77ec14f5, 0x9b60f1df, 0xe1ef3b28, 0xc4afa16c, 0x4dfa4dfe,
- 0x88547da4, 0xd7d211f6, 0xba2226a8, 0xbf727eb0, 0xe847d26d, 0x662505a5,
- 0x19917bc4, 0xa6e11bf8, 0xd9f58db7, 0x68f1f434, 0x83f7e5f6, 0xf451efda,
- 0x0b63f723, 0x84dcfd05, 0xff181891, 0xb81f720f, 0x5ccfd38a, 0xf4843de6,
- 0x9cd5fbf3, 0xf0bee47e, 0x3d03ef9b, 0xa07dc8fa, 0xdd7e4fdc, 0xdd3f60fd,
- 0x863ec058, 0xe95cb1e7, 0xfdf1e017, 0x45d38546, 0x3ddf9cfd, 0xf2c2c556,
- 0x733368e2, 0xb97086ab, 0x8cc9a665, 0x0316977e, 0x99cd2fdf, 0xd2d97ef5,
- 0xb413f908, 0xb8401f97, 0xf9276eb1, 0xdaadeb77, 0x3d2b3671, 0xf711fd77,
- 0xc95a8f55, 0x08e174af, 0xc2e59323, 0x0f9411ae, 0xc78199fe, 0x6e7ce55b,
- 0xb5f7bc3f, 0xb95bd410, 0xcc6296ee, 0x0255a82f, 0xb7c1d62f, 0x77beac0f,
- 0x756bbf91, 0x672f7141, 0xe427c50f, 0xbafdf1b8, 0xc6c7927e, 0xf73f5c03,
- 0xdf940929, 0x4787ef0b, 0x38fee9c6, 0xdcefcb88, 0xb807df4c, 0x5b47a91e,
- 0xf827f3fa, 0x1b30b413, 0xa7ce1294, 0x704de708, 0x985fcb7f, 0x13798ae7,
- 0x04e2231b, 0xbe663ed0, 0xcf2179db, 0x01726147, 0xba6567cc, 0x7fd717a7,
- 0x4f85c44a, 0xa9e23889, 0xfc571e44, 0xfe7d7f7b, 0x7ae20db4, 0x3b8894e8,
- 0xc6d14a9e, 0x44bd649b, 0x6cd93cf1, 0x60346ef6, 0x37799ebc, 0x3d70fe82,
- 0x7ca26a64, 0x5f1c4595, 0x6b252fbd, 0x1ac811ee, 0x106a3e54, 0xd399fbb4,
- 0xe3041fab, 0x9ed36f2c, 0xf715ea83, 0xba0af6db, 0xa7f0b5e9, 0x506b371c,
- 0xd76c28f5, 0xb3df80bb, 0x289e5fda, 0xbfea5ecb, 0xc910baf7, 0x8ff2fea3,
- 0x3a9ce242, 0xf8c893f7, 0x61f8bc40, 0xfa30bc74, 0xbc74699c, 0x37e4b17f,
- 0x245fef11, 0x6ee2d4e4, 0xd5b86f1e, 0x820f36cc, 0x6775b7ef, 0x26b8fc50,
- 0x135c3fd1, 0xbf5bf7ef, 0xa4879e51, 0x9edcdecf, 0xcff8f8fe, 0xf5e3e222,
- 0x2f5a3e22, 0x5da9d7d7, 0xcf0164df, 0x3e3e31ef, 0x60739079, 0x9f3a3c7c,
- 0x33b445e2, 0xac3c610c, 0x55b87071, 0xd12aebe9, 0x39617c4f, 0x35f73ca3,
- 0x416b2d6f, 0x2d9af23f, 0x615596e2, 0x380bd777, 0xd3975bc7, 0x8d2e63ab,
- 0xb9813ebf, 0xe593d622, 0xc994d14b, 0x33c88f92, 0xad93541d, 0x34db9f69,
- 0xf07f5344, 0xef9a51ba, 0x4d22fef9, 0x1af5a0b9, 0x6d61fd4d, 0x88f29a15,
- 0xea6bd79d, 0x4921b217, 0xa23b6fe4, 0xbb125f47, 0xf347302a, 0x85def47d,
- 0xb29ff69a, 0xa0931da6, 0x7b45a75e, 0x7bf3332f, 0x8594c67a, 0x76c7a9f3,
- 0xc3f4d52c, 0x29504a82, 0xf633df0b, 0x79a7b899, 0x878f0f79, 0x5ab5dd5c,
- 0xbead4e33, 0x1d18f08e, 0x7d622def, 0x086e37e4, 0x1b20ee28, 0xd55dff18,
- 0xaeed4ed5, 0x78c8f764, 0x2241c6c8, 0xb2cd97de, 0xd3475d39, 0xc3ec8d85,
- 0xe4f4bb0b, 0xc3642c7f, 0xf0449a1f, 0x6b80b032, 0x302efe20, 0xf0bb17ee,
- 0x798ddd8c, 0xb5bfb745, 0xca63e68c, 0xde05d2d4, 0x5eb9181f, 0x5d2d48eb,
- 0x3a5addd8, 0xa5a09a48, 0x27786883, 0xc174b47b, 0xcbbff042, 0x86753bc0,
- 0xb7fe6e96, 0xf081dce0, 0x5be186b5, 0x62d3d07c, 0xbcf1b823, 0x999f6935,
- 0x1d143d84, 0x4e7690d7, 0xbbb09070, 0x2e323f45, 0x93f159b1, 0x771fd55d,
- 0x0bcc109c, 0xd53da3e6, 0xc95fb8c4, 0x6fe5107b, 0xbd24bf0c, 0x9497e78f,
- 0xc09b9d70, 0xf32d67f5, 0x663efc92, 0x93a4fee1, 0x9fc8abd5, 0x913592b4,
- 0x9cd9fddd, 0xe8efc2e9, 0xca577aa7, 0x9f901853, 0x8b29f600, 0x06aed7f0,
- 0x1fef1a8b, 0xd2a7868a, 0x78ed04ad, 0x4b75986e, 0xfca3e07d, 0xedde0f15,
- 0x68ff89a9, 0x51e65fed, 0xb497e522, 0x1278e587, 0xc9ae529e, 0x49ac4c71,
- 0x117c899f, 0xc8d8e725, 0xd693f8e8, 0x41fd239f, 0xe3238e32, 0x9bfed14c,
- 0x55b8bb08, 0xc1d2718f, 0xce782df9, 0x21e1d8b7, 0xeb29613f, 0x4fdf05b9,
- 0xa8b47730, 0xb8bfe12e, 0x2ffbf58a, 0x2babeae2, 0xf26fb5c4, 0xf247a12b,
- 0x65b3c607, 0xff961c7c, 0xf1a11ff1, 0x8b95c524, 0xf2f398f3, 0xd3d22708,
- 0xfba6bf40, 0x8fd02bf8, 0x8a97d75e, 0x3130aaf5, 0xfdde223d, 0xf5a212a6,
- 0x367990fc, 0x6fdb9e45, 0x6ed31d60, 0xe8327f21, 0xa727bc49, 0x58bbfb93,
- 0xac3db457, 0x0759bf92, 0xafba412b, 0xde711165, 0x2a77f0fc, 0x659607eb,
- 0xec95d21e, 0x82f1a789, 0xe0a3ca72, 0xc84c53f9, 0x8cffb941, 0xf993cfb7,
- 0x4f7ef218, 0x94547799, 0x1c75f823, 0x03fd871b, 0x94e595bf, 0xf8017fa2,
- 0xc7e48953, 0xfa253cfe, 0xa31f803e, 0x31f32fd6, 0xf212f6f4, 0x5c8b2d1b,
- 0x8780d7ef, 0x9c7e5bb4, 0xc8e9e8c3, 0x3eb3d171, 0x3d6fc4e1, 0x47a4b9f8,
- 0x68da3f93, 0xfa0d0d84, 0x79145e13, 0xbb5a1d81, 0x9d1c96fd, 0xf7df1b80,
- 0xf15e095c, 0xf8f221f1, 0xaebe3e04, 0xf8f3261d, 0x0c971c24, 0x0d0afb84,
- 0x8ff7fb5c, 0x115f70fd, 0x2e12ee0b, 0x7e7b4ae7, 0xdbd2f881, 0xbc23a58f,
- 0x577aa617, 0xe3dcfd63, 0x5d144fa1, 0xfa555e78, 0x7b8794b3, 0xe74f4ba1,
- 0xe3ae1aff, 0x25e1b072, 0xf386893d, 0xb38a26dd, 0x41bd74d6, 0x66d9e176,
- 0xfc06b410, 0x72180cbd, 0x08fc65d8, 0xb78ef051, 0xd9eb924f, 0xe5f62390,
- 0xef32fd62, 0x39b9d607, 0x475e6627, 0xdfb41c3f, 0xf4aa1c05, 0x1cf09263,
- 0x92be7f59, 0x791797da, 0x3af45f5f, 0xfe78722a, 0xf7b329db, 0xc3efec3e,
- 0xd81d9c9e, 0xfbbe955f, 0x67c23670, 0xbbe742ad, 0x79f898a6, 0x5e712cdc,
- 0xc9a8426f, 0x3399e78d, 0x667df873, 0xf7a47e23, 0xfdf91c62, 0xe0a677b5,
- 0xffd93439, 0xe7474508, 0xee7b1947, 0xc12c7f83, 0x3722e6f8, 0xd8bf6fde,
- 0xba2fee24, 0x002c1acb, 0x91baf239, 0x186547df, 0x66e744d2, 0xe4f592fa,
- 0xb3d34cd7, 0x727748a9, 0xadbcf2de, 0x01f78f7c, 0x7cb15e60, 0xafa5a53f,
- 0x7bfa0d78, 0x75c83d04, 0x2beca94f, 0xe185b26e, 0xa33cf32f, 0xf82553e1,
- 0x1b43ee43, 0xd05b5ef0, 0xbccde7bf, 0x6daf7d1c, 0x5874feff, 0xf6363dff,
- 0x837eb8c8, 0x1e3493c5, 0x6bdc51f9, 0x278717fb, 0xa477df89, 0xbcf6a7bd,
- 0xbf97b7c8, 0xdeef1253, 0x51ccff9b, 0x827b97be, 0xcb85e5e2, 0x7078ffbc,
- 0x99564869, 0x739d357a, 0xdeae5ef7, 0x8fadff2b, 0x28bedfb9, 0xd3dff7be,
- 0xbcec6af9, 0xceb15ec5, 0x88617e70, 0xe7f729ce, 0x7e54be2d, 0x1a477bd9,
- 0x08d23ef0, 0xf6bcc838, 0xb48fbc06, 0xd0bf4638, 0xe576cb9f, 0xc4aa877b,
- 0x8f301abc, 0x3df23530, 0x38f0b7a7, 0x302f2269, 0xfb7c8894, 0x9d3d2ecb,
- 0x11e5ffe3, 0x31dd8cdd, 0xcb9b9de6, 0xa9ca32e1, 0x0e8d1f12, 0xe3b5fbf2,
- 0x79e793d5, 0xe8d8b9e4, 0x845675f9, 0x63f9c56e, 0xf1ac729e, 0x3f7cb91c,
- 0x99dde72b, 0xf0d1f1c2, 0x9bdf899a, 0xf27cf2aa, 0x4ad094ce, 0x168713e2,
- 0x1e04c3cf, 0xe50faf3b, 0x99b2b9d1, 0x8f10efdc, 0xfaa7261e, 0xc8be51ca,
- 0xd4caee7b, 0xc111c526, 0x87a2578f, 0x1af5dc30, 0xbb840ebc, 0x7ecbbe91,
- 0x7c151f4f, 0xdc363ccb, 0xfa112dcf, 0x5a9ec96e, 0x7ee587b2, 0x3d4ef4e9,
- 0x669c6fe5, 0xba72ae3c, 0xd0fda14d, 0xeb631f52, 0x7cad2e40, 0xaa3378a2,
- 0xb09925ae, 0x1efe1496, 0xe9661f7f, 0xbaf8a8c6, 0xbd495fd8, 0xbe5fc72a,
- 0xd7176b4d, 0x467f6db0, 0x51f4e9fb, 0xb0563f2e, 0x2b3fd226, 0x57f6d01f,
- 0xa7d667b3, 0xbce8cf38, 0x8fc21180, 0xec572d37, 0x1958ca57, 0x4f358fea,
- 0x9fc46e7c, 0x17c78960, 0x434ffbf8, 0x7ddff187, 0x8efe27c2, 0xc96f3e08,
- 0x1720fcf5, 0xf2ef3efd, 0xf5ceaef9, 0x7f45c9cd, 0x7e7cbbc9, 0x702eea17,
- 0x8d2bb33d, 0xfd8b5bf4, 0xfaff922e, 0xdffe5cc1, 0x0035f78b, 0x71264c9c,
- 0x49aeba6f, 0x4df6489f, 0x43ece880, 0x7e731de7, 0x26776540, 0xd3da43f2,
- 0xbf6067d3, 0x1eada7ce, 0x72d6df5c, 0x2ffa214f, 0xf3f356b6, 0x8f1366a1,
- 0x397e07df, 0x538600f1, 0xaf6c7686, 0xa39d1740, 0xfd107f7b, 0x3fbaad42,
- 0x98bcc61f, 0x5f3cc9d6, 0xda175d32, 0x3c62283f, 0x899035a7, 0x68e77df1,
- 0x9a4e6f7e, 0xcb90bcbe, 0x36276e7f, 0xe85c5c08, 0x627f202a, 0x17fa41af,
- 0x2e742c3b, 0x2eff8eab, 0xf1c628c6, 0x70eaf32f, 0xf176910e, 0xf9a666d9,
- 0x1d51869d, 0x4890d04a, 0x3c50a8f7, 0x30436ea8, 0x67d416fd, 0x4f14a94f,
- 0x7b4bf393, 0xe302ab3d, 0xdd8f5266, 0xbfb838a2, 0x0bfdd84d, 0x71e3fc98,
- 0x9e82f9b7, 0xff7b0816, 0xf7872b16, 0xc3cee652, 0x2ccd0b76, 0x76ac0751,
- 0x2947654b, 0x90d6b3ad, 0x8c85768c, 0x47b7c51f, 0x1ac9fb62, 0xe7e7617e,
- 0xe1be959e, 0xf419c9d8, 0x3f865d41, 0x693c85db, 0xffcfce18, 0x83cca1b1,
- 0xd786caf1, 0x30efd046, 0x3c781299, 0x1996e41c, 0x843a11ef, 0xbdd61efa,
- 0xc88b15ea, 0x73880a5b, 0xd8defccd, 0x453939c6, 0x78f11e74, 0x71ffdd1f,
- 0x23ca10de, 0x847906fe, 0x92bea637, 0xe01fbbfb, 0xd90debbd, 0xf941d760,
- 0x789fee74, 0x25684879, 0x92991bde, 0x47978977, 0x72c13e85, 0x6cc25e4e,
- 0x5685172a, 0x3e3ca1ea, 0x7197932f, 0x36040a03, 0x6cf06f35, 0xc92dda3f,
- 0x87702ec2, 0xc377bce8, 0x917423cb, 0x1e7758fe, 0x84676797, 0x3e4cf93f,
- 0xc20e6dbb, 0xfaec647b, 0xded27969, 0xc9f5a36e, 0x2cf6caf5, 0xffbb7633,
- 0x957e7210, 0xc53da738, 0x3c2d5aca, 0x044fe7fe, 0x1eec1c3c, 0x7fcbf141,
- 0xfde14dcd, 0x4f74423b, 0xfa27ec8f, 0xb8e41c77, 0x7bfe15ab, 0xf2a3e759,
- 0xcb977ebc, 0xb38c2be5, 0xea19c691, 0xe79be7e1, 0xfe2214e4, 0xc0aa6f00,
- 0xc9f7ca9b, 0xd07e7ced, 0x13fefe2f, 0xf46287e8, 0x0afc1ffb, 0xe787e7ea,
- 0x27274d1d, 0x5aab38c5, 0x2fb6dc78, 0x69e880b9, 0xf7dc558a, 0xc75da252,
- 0x9f6e3cf8, 0xc592f3ba, 0xaf091d79, 0x69c6850c, 0x09cc7011, 0xf6339f0d,
- 0xaffbaf9b, 0x8eeb4bff, 0xef0797c0, 0xc5d8396d, 0x9f1e37ef, 0xf485f1c7,
- 0xe076429c, 0x677f4d76, 0x9fb547d6, 0xae5f28c0, 0xda80a521, 0x6fee2bdf,
- 0x61d9f795, 0xdc71fcbb, 0x57bb45be, 0xfcc1a7de, 0x1c645993, 0x8cdeffb2,
- 0x70bf710e, 0x286f3aff, 0x8874eb11, 0xef223a75, 0xcfe7ec33, 0x73797d63,
- 0xb8e903ed, 0xfdfdfe1f, 0xfd12298d, 0x563cf869, 0xf1d7c87f, 0x1e5572f0,
- 0x1bdf2797, 0xa33ce45e, 0xe70fd9e0, 0x7849f9a8, 0xbb537f22, 0x94ba5a31,
- 0xf411ccf3, 0xf3bf8039, 0xe278e5bf, 0xbbfad97e, 0x7338be79, 0xbebae969,
- 0xf9875f33, 0x07ddb209, 0x34a0c078, 0x21bc27ec, 0x7327ec4f, 0xbc9c4e58,
- 0x339e6f47, 0xde917fa6, 0x7b27ef47, 0xd9efe593, 0xbd1afd69, 0x397bfe4e,
- 0x7efc73fe, 0xfca36b83, 0x7a8f183c, 0x176e16ce, 0xf2da2fd6, 0x037e0263,
- 0x797d54fd, 0x5312bf38, 0x3bf8f3c5, 0x4af3ab5b, 0x7760ab67, 0xdc552494,
- 0xa6e50f99, 0xfc93c6c7, 0xf154192e, 0xf3c83e79, 0xe04d8f35, 0x7c5747df,
- 0x79cb043e, 0x8a797913, 0xf79479e7, 0x9eccb460, 0x2bb6159a, 0xd173ccee,
- 0x1d4afab8, 0x42676bdd, 0x63d60623, 0xf944dd7a, 0xf1ae1280, 0x5d26259e,
- 0xbff3ac53, 0x03d3f4f7, 0xc04cbf8f, 0x1fd0ba7f, 0x2105fc28, 0xe82fe355,
- 0xcfe7e44d, 0x92fd5f7b, 0x9bdcd7ce, 0x079f5be7, 0x67ad1bed, 0xf287cd6f,
- 0x1407eb06, 0x603c53ef, 0xc61fa087, 0x608b60e5, 0xadd9cabe, 0xd89fb45e,
- 0x2559b76a, 0x18ff0ab8, 0xf007a9de, 0xa7b5e57b, 0x0f883c7e, 0x4c79c5e3,
- 0xf1a07214, 0x15fdbfb5, 0x678dc4e3, 0x1b346e6c, 0x7c3f7627, 0x135fda27,
- 0x1bfedfbb, 0x3cfcc3d7, 0x44f79c90, 0xfbc27ff4, 0x9a265d09, 0xabeec4ff,
- 0x6bfd6056, 0x402eebdf, 0x44eeb93a, 0x42c505b0, 0x3effabef, 0x880e7348,
- 0x7cd97a7d, 0x39f1b8d1, 0x013f8f09, 0x1e0893a0, 0xf8f0e73f, 0xced9f28a,
- 0x0e6e8f3b, 0x7b549391, 0x78ec0ade, 0x605f3b8a, 0x7b8c6e09, 0xd1fd73c8,
- 0xd5e3d57e, 0x7f783eb0, 0x20cc1f5d, 0x729e9ec2, 0x24820cd1, 0xc9672e5c,
- 0x39a5729a, 0xcabf534b, 0x3ef9af91, 0xcd2af33d, 0x42ae99f7, 0xc8d6794d,
- 0x37fa9a89, 0xe535cbba, 0x6a6613d9, 0xaa7b57ea, 0x60c2e535, 0xf17ea687,
- 0xf7ed2e91, 0x788f4c63, 0x7eee3a28, 0x27a59f03, 0x2d9ee43d, 0x06f4d53b,
- 0x85fe273e, 0xafda2383, 0x8ec5cd7c, 0xf4bdf037, 0x9f9f472b, 0x9be67e92,
- 0x3180b6f5, 0x53393fb6, 0x83df082d, 0xf3f1d7a0, 0xfb25ef53, 0x937880fe,
- 0xa0a6a7e7, 0x5090195f, 0x9fb9db75, 0x5c32efe2, 0x6efdc458, 0x943111c7,
- 0x7f276e4f, 0xd34371e5, 0x79e47fb3, 0xf728b903, 0xaf9bebae, 0x8b94f759,
- 0xcbbacd3e, 0x3c28aad9, 0x5729a1dd, 0xd4d6ee39, 0x5eb99e9f, 0x6ba67df3,
- 0xb69e144b, 0xba37ca6b, 0x53c28e1f, 0x9e9e147b, 0xf4977cd2, 0x5ffc2ddd,
- 0x0adfa1af, 0x3d42939e, 0xc9878895, 0x1f08faa7, 0x2ada7a13, 0x1cd74f11,
- 0x957c20ef, 0x2895bd04, 0x348ecb2e, 0x20cf81bd, 0xddb0cbec, 0x7a4ce681,
- 0x91766c1e, 0xf370ebff, 0x691e7a48, 0xfffbd376, 0xcf409e68, 0xe87b355f,
- 0x33cd9ff9, 0xecd3d9e8, 0x734767a5, 0xae7fd507, 0xcffb8bb9, 0xddeffb52,
- 0xc1bf45c8, 0x01a85d79, 0xc18ec623, 0x9e9e495b, 0xc79d084f, 0xeb7f06f2,
- 0x3420a9ec, 0x901d67f0, 0x9e207f2f, 0xfb4f2e45, 0x1e0e7860, 0x19fdf8cc,
- 0x43a37f22, 0x3b4429e7, 0x0fe3f47c, 0x32e6a7de, 0x37bd69b6, 0x183a7f13,
- 0x132866cb, 0x90f7e9b2, 0x93cfbc1e, 0xa8b3d8c3, 0xf7bee84a, 0xb9636707,
- 0xe79efc57, 0x241fc7e0, 0xc75bfc3b, 0xe2033dd9, 0xc707a3ec, 0x7b3fb388,
- 0x7f4765ca, 0x46afd1cf, 0x471e11d8, 0xc3cbdf85, 0x3bf80d0a, 0xa16ae51c,
- 0xf1ecf501, 0x5421e738, 0xe0c97953, 0x7bb75c52, 0x5f91e51e, 0xe1dfa06f,
- 0xfdf0a39b, 0xec97acaf, 0xf7a0fae2, 0xa7ed1346, 0x2b3ce98e, 0x957a3f90,
- 0xce10c7be, 0x14fe3d37, 0x7b5ea9e9, 0xafc21e5f, 0xbcbdf1fa, 0x4c7becec,
- 0x0d944771, 0x8f953e1c, 0x6fdb393f, 0x33e15efb, 0x0d11d71b, 0x1d83b99f,
- 0xf4115f7c, 0x201da2e4, 0x3daac7cb, 0x2c5714f5, 0x75c30cf7, 0x389af51c,
- 0x81ed7aff, 0xf237e461, 0xf08bce94, 0x360cf4ff, 0xa2e7fad0, 0xe83f44de,
- 0xd6207d42, 0x1f9e15ef, 0xa23dedcc, 0x2e67dc13, 0xe0bed2b0, 0xa3df8e98,
- 0xeedf5d10, 0xcfa3fbe2, 0x9c87dce2, 0xdc57be28, 0x0becff54, 0x5aef5fd0,
- 0xebdd750b, 0x58f6411d, 0x1740136f, 0x54f7ba68, 0xddfe39d3, 0xa12016e4,
- 0xf82def38, 0x6cfef82f, 0xfc5f9df7, 0xb07fea06, 0x1d26ead6, 0xf04518e2,
- 0x2f2a285b, 0xfd93354e, 0x6e4e78b4, 0x5bc5ea05, 0x56f0bc44, 0x614e9abb,
- 0xe8d93543, 0xdb967e80, 0x0403370a, 0x6ab4cad9, 0x5364fe23, 0x9b1dce4d,
- 0xe87ab9f1, 0x58f22376, 0x9b7d98dd, 0x07ad8cd1, 0xf9252e16, 0x19a77a17,
- 0x3adb75e6, 0xe7ef8bbd, 0xdadaf9e4, 0x22f7946f, 0xc898f7e9, 0xd020024f,
- 0xa5c9357e, 0x4949f668, 0x181f4e82, 0x6331e22c, 0xda4bd8d9, 0xe44ed778,
- 0xdf8bb3a3, 0x1e271e19, 0xec2efda1, 0x7b8adfc7, 0x4fefa39e, 0x5c3ae391,
- 0xcc75ff7c, 0xf6899408, 0x07ae42e4, 0x7cffcdc6, 0x7fac2943, 0x4743b75c,
- 0xd5b70d79, 0xb87880bf, 0x68f025d0, 0x4fc85d60, 0x7c97f937, 0x4c421bf0,
- 0xf0dce69a, 0xbba5f495, 0xa91951c7, 0xde424b2f, 0x397d48ca, 0x12adafa1,
- 0x8fd4a2f5, 0x211ae6c1, 0x8e489b8f, 0x475e6c1e, 0x7ecdc3e5, 0x6e691e7a,
- 0x8db8f215, 0x79aaffbe, 0x01c790a7, 0xd2f78f21, 0xf9e6eefb, 0xd9ad7cf4,
- 0xa985cf47, 0x6e11d7be, 0xd73b8e32, 0xdcbca3ec, 0x189b0f43, 0x742ef1c6,
- 0x038f289b, 0x47b1e238, 0xc94f30d2, 0xa344e744, 0xe5a295f3, 0x743d3f7c,
- 0xe5b7b80e, 0xfef7e46d, 0x17b4233c, 0xa7a7c707, 0x4765cca3, 0xe0f1f4b9,
- 0x8e8724f3, 0xb4765cba, 0x2e3e4fa7, 0xdd971eca, 0x0d3fe500, 0x71fd25ee,
- 0x9bb2e7d4, 0xe3c9fca0, 0xdfbbfcbd, 0xf940b765, 0xfc7dc1d3, 0xd051807b,
- 0x2fe0ecff, 0x33958e48, 0x47f220e5, 0x2a7f39a5, 0xd7d00ba8, 0x2f9107e5,
- 0x992e67a6, 0x60b17c8a, 0x72e88bb0, 0x41fd6ba6, 0xd91acf2c, 0x1515e2ae,
- 0x46e15b1e, 0x5691576c, 0xa9bb62ad, 0xc46c7739, 0x6e86d376, 0xcddb2357,
- 0x236fb318, 0xb7706f96, 0x2e9f68ab, 0x1a563940, 0xe59647ee, 0x65a72977,
- 0xddd5dd3e, 0xe307d25e, 0x0fa4bcba, 0xe62a5c24, 0xff426f56, 0xe2976367,
- 0xa9a5dfc0, 0x27f4ab98, 0x62ee6033, 0x0a93de03, 0x3dfffaf2, 0x87ac77ae,
- 0xf9623675, 0xadb72a1a, 0xedfa06ff, 0xe2f6007f, 0x8000e831, 0x00008000,
- 0x00088b1f, 0x00000000, 0x3cd5ff00, 0xe5547809, 0x9dcee7b5, 0x4c92642d,
- 0xe2420836, 0x96249964, 0x26b6432c, 0x0c486410, 0xf90130ee, 0x10196544,
- 0x044816c2, 0x7eab17eb, 0xe0171a19, 0xd16b8d69, 0xb5c46faa, 0x61e4b6af,
- 0x1d0958d4, 0x87d252aa, 0xb410553a, 0x88a47479, 0x119099f0, 0xc7d278dc,
- 0xf7fce73b, 0x24cee666, 0xbefd1480, 0xff938607, 0xcfd9fbfe, 0x005ffff9,
- 0xb3f85380, 0x34607f02, 0x3d2538fe, 0x0468048c, 0xd1bf67f1, 0x0395b26d,
- 0x8c0734ac, 0x412fa3a0, 0x6010aba3, 0x76960eaf, 0x24a40014, 0x0b7afcc3,
- 0x74b08d96, 0x5de7960b, 0x05480368, 0x20bada68, 0xda85816e, 0x6066e3bb,
- 0xe21745fb, 0x52ce38af, 0xe0546e05, 0x9bd40a93, 0x4f34899c, 0x1fd24d9a,
- 0x856fc7ca, 0x064a7850, 0x3d9ab7e8, 0x448004ba, 0x0dac7b93, 0xfb9bedc7,
- 0x8758834e, 0x31d688af, 0xeb1ebd6c, 0x6c3200e3, 0xca1f1e56, 0x5e541982,
- 0xc846ed09, 0xcff5b846, 0xda22a4fb, 0x2327c597, 0x5f434e84, 0xf9ec5f20,
- 0x63fe1654, 0xe0543d06, 0x6e03e97a, 0x70d79969, 0xea566020, 0x743967f1,
- 0x226670ec, 0x7ed45ede, 0x18bf046f, 0x7dfb43bf, 0xbe8de215, 0xbf697537,
- 0x0f5b5403, 0x0230438d, 0xd9dfb8cb, 0x855efe12, 0x878f0dff, 0xc3c06749,
- 0x10f0a1a4, 0x1af01fb5, 0xd7de8e41, 0xa66ecb0a, 0xc0bee473, 0xd1fcca9d,
- 0xf7218108, 0xf445f2a7, 0xfe05dafe, 0x25ff02f5, 0x5a74e736, 0x38fcdd5f,
- 0x8e005390, 0x4d79356d, 0xa9ffdc99, 0x1744293d, 0x2d837593, 0x5b5b3e9a,
- 0x00de8367, 0xcdd5adb0, 0x14bad7d0, 0x3f8076f4, 0xf97336b5, 0x2e16d6ad,
- 0x30f568ef, 0x8ebad9dc, 0xdb5a5fe1, 0xeb577eb9, 0xdbbf2e46, 0x6fe865ea,
- 0x5fbf917d, 0x86657f3b, 0xff4d12db, 0x45cec9d5, 0x7b9e8fc4, 0x3e9913aa,
- 0xc853f7b8, 0xc81a9eab, 0xc344b66f, 0x9d658301, 0x8f65c094, 0xd9e1f711,
- 0xc36de316, 0x8c73fd7d, 0x19c689bb, 0xad7e09a8, 0x4a437c43, 0x30d0f180,
- 0xbe9abdd2, 0x3a1c464b, 0xe4f56689, 0xeb0efe12, 0x6407bf3c, 0xd39b56d9,
- 0x383e47a5, 0x17558f1a, 0x6582dc00, 0x78f3ce0f, 0xfa85abaa, 0x48c07e41,
- 0x3fa29ce3, 0x097c7193, 0x3af07766, 0x0e1ca210, 0xb1e808c4, 0xd18f2c49,
- 0x40ddc850, 0x60f99fba, 0x1913e9e0, 0xcb3382b6, 0xa8f870c5, 0x9e03ab93,
- 0x6567a432, 0xd584c3ac, 0xa4f8127d, 0x46538412, 0xd38e00d6, 0x13d46e97,
- 0x5644149c, 0x9fc3c750, 0x6322dfc9, 0x14cbf186, 0x6b94d448, 0xed35a3cd,
- 0x9a99aceb, 0x5cf4befa, 0xb4d2ff1e, 0xfaed348b, 0xc59a5746, 0x232f53bc,
- 0x6f7465d8, 0x0974805c, 0x9b1c9956, 0x98bdfeb0, 0x062822f8, 0xbf1b1698,
- 0x317be089, 0x376a5e19, 0x14c9c0ed, 0x934e7dc0, 0x108b237d, 0xc6db9755,
- 0x99edc76b, 0x76c36353, 0x6957e657, 0x25c121d7, 0x1dabdfb4, 0xa7df3453,
- 0xe9ae5e57, 0x93fb32ef, 0xcef5ad08, 0xc6f7cd7a, 0x9f41af96, 0xe5b1300c,
- 0x014be824, 0x343afbc6, 0xecee94e3, 0xbf1fb4d2, 0xeb12641b, 0x378e7d92,
- 0x741f9609, 0x152ac4ca, 0x24df9b87, 0x3fa5f558, 0x4e01f683, 0x9f5159b0,
- 0x83dc8a4b, 0x963d0247, 0xcae52927, 0x812db7a0, 0xf21270e8, 0x89bf48f5,
- 0x6321c230, 0xbff2a963, 0x4c1f104e, 0x32002052, 0x16abf607, 0x3a79804b,
- 0x4598d78b, 0x1be5056a, 0xc906c1f5, 0x3847a691, 0x50540e47, 0x8a0428f9,
- 0x973aca08, 0x2a6bf89e, 0xb2a58f34, 0x0469dc09, 0xbf74483f, 0x2fdc7c4f,
- 0xe2c4da05, 0xcfc4c982, 0x68ff3f75, 0x17ac6dde, 0x5c261c62, 0xfebaefdf,
- 0xfd6b4a91, 0x91f53fbb, 0x7e216c37, 0xcd7eb26f, 0x8dcb5278, 0x7f19c72d,
- 0x2d6fb96a, 0x92e177cc, 0x9f680ddb, 0xaffe3610, 0xed0a76cc, 0x53a23ada,
- 0xb8c9fc23, 0x1ed420ba, 0xc418be3a, 0xbfea3177, 0x04d35a7a, 0x5ddfd7c2,
- 0x6f576c4e, 0x9e087210, 0x1c4ef545, 0x29463ea7, 0xa7d44f83, 0xb2a1ed2a,
- 0x6ae9cb9e, 0x6f68957d, 0x587bc757, 0x96ad1fb4, 0x522ef195, 0x9ca2cdcb,
- 0xa0f7cea9, 0xe5aa1728, 0x397170ff, 0x613fb44e, 0x29ef559b, 0x53ffe908,
- 0x0f18ddaa, 0xa06ec9e3, 0xc933903d, 0x1abb481e, 0xeda21f98, 0xb15eb685,
- 0x237ff317, 0x44c58c7b, 0xdf63cb8f, 0x90eeb921, 0xf1bae480, 0x8bd38376,
- 0xd49e7ff3, 0x12c6b451, 0xb7e7dfc2, 0x6abb7c08, 0xb6329ce3, 0xde6af95f,
- 0x3923e226, 0x85c8f76e, 0x563addf8, 0x4ea77ac7, 0xe88138b6, 0xfbd0af7b,
- 0xd848ff6a, 0x8686f2d0, 0xb2f5519e, 0x6cc1f3c4, 0xfaf9c1fc, 0xf4f51bef,
- 0x8e59c206, 0x9370973f, 0xdcf42999, 0x95add448, 0xea36f3f8, 0x3dd23359,
- 0x3a9c1b25, 0x1af29f6c, 0xf1a267ea, 0xc7d0bf41, 0x24f8c5af, 0x8f959c14,
- 0x6ff6c9bd, 0x8e528ca1, 0xcf2d7bf8, 0x7c89979d, 0x9fce347a, 0xd0db7c4b,
- 0x75d78db2, 0xe3cadd8d, 0x10583583, 0xcce2cf8e, 0x9e97fc28, 0x3fa5ff01,
- 0x8271fe26, 0x75cfa403, 0xbeb47428, 0x78b796e5, 0xef95cbbf, 0x43325fac,
- 0x472cb8ed, 0x39c68f97, 0x0e1f0832, 0x74074e85, 0x5f050ab6, 0xfabe1357,
- 0x1373fb17, 0xf9f0ecb1, 0x3ed9ba47, 0x88972aec, 0x4071cdee, 0xf92a3f74,
- 0x410ef68b, 0x0ed68eff, 0x5a5bcbb6, 0x84be18bb, 0x55bad073, 0x8d10dd7c,
- 0xc067f9df, 0x131ffcef, 0x01f4a3bf, 0xadfb03a3, 0x4e3c07da, 0x1180ff85,
- 0x2b4cf4c2, 0x27e225f1, 0xfae24ba1, 0x2120b93a, 0x138fa9a0, 0x738e52fe,
- 0xcae9f13c, 0x37aabb19, 0x98792148, 0x311d0b1c, 0x0ed7cc49, 0xc41daf85,
- 0x22ff2ad7, 0x11ea963f, 0xc49d6fcf, 0x37e0437e, 0xf3c0bfc4, 0x3bba78a8,
- 0x881baf1a, 0xabc1a78e, 0xc607feb6, 0xc7fa276b, 0xaf8237a4, 0x653778c4,
- 0x77f9e346, 0x7c555e0a, 0x7fe4536f, 0x236f3c38, 0x7f9ea73c, 0xb4cb6f3c,
- 0xf891b8f1, 0x453ece1e, 0xf75d47d2, 0x7e5a7210, 0x2d3a722e, 0xdff8aadb,
- 0x461677e8, 0xa26dfdd3, 0xf74359bb, 0x53c8339e, 0x4f298fcf, 0x848b7891,
- 0x3ab8128d, 0x3fdfd12c, 0xdf561ccb, 0x4e3c179d, 0xf8d6ce0a, 0x75bf9367,
- 0x29b3fc6b, 0xfd696118, 0xe5349bd8, 0x9aadeb3a, 0xada697f6, 0x6e5fd4d5,
- 0xbfa9af5b, 0x4d01ff32, 0x63c76af9, 0xd3e67e11, 0xe77afa9a, 0x73f5346f,
- 0xea6bb79b, 0x68f4b7e7, 0xfe7817ea, 0x78ab29aa, 0x1c0adadc, 0x356b6d2f,
- 0x65d3f12b, 0xfe03ab0c, 0x8b83125a, 0xdfd9070f, 0xd7b7f4ac, 0xafb24bb2,
- 0x32d1fd83, 0xc296ab9f, 0xcd9d8aaa, 0xb5f4126f, 0x2d78955a, 0xad5be18d,
- 0x3befd636, 0xee19f35a, 0xf128756c, 0x5dc3255a, 0x4e254ead, 0xb48c3173,
- 0xbb66af0b, 0x3d2164a7, 0x44bcbda6, 0xe980b807, 0xc167f87f, 0x77bc5a5e,
- 0xdce28ebc, 0x8e5eca35, 0xffb37f57, 0xe3afe436, 0x950726cd, 0x311fb77b,
- 0xf9a30ad8, 0x32b7ee65, 0x6cf8c338, 0x0d5fcb6e, 0x45cd67e4, 0x0863ba0f,
- 0xa59a9d39, 0xf7207e63, 0xcc2f5003, 0x05218336, 0xd9ecc1f5, 0xf80da392,
- 0x189207bb, 0x3f58dcfa, 0x133e0f4d, 0x7a2deb96, 0x979e299f, 0x3fa332e6,
- 0x132c4b3d, 0x50f07a4c, 0x7324a43d, 0x7d0d7e9c, 0x383ca1b4, 0xbf18b865,
- 0x1c3f22cf, 0xe96f5dfb, 0xbddd9030, 0xfa2fe76e, 0xb87ac36f, 0xf1ce53d3,
- 0x25625c3d, 0x3e792dfd, 0x371a9dd6, 0x3520bcbc, 0x5f1850e1, 0x4e19254f,
- 0xe1d1f8a5, 0x7adc5277, 0x9cf1c193, 0x05dfba2d, 0xc9a77eca, 0xc16ffb12,
- 0x4dde4dd7, 0x713e4852, 0xb84d3b7f, 0x01e226cf, 0xc1b367da, 0x7e445797,
- 0xb3f676f6, 0x16d72a9b, 0x2e9a9d11, 0x15313e91, 0xa69de285, 0x8fd92f96,
- 0x91cfd48f, 0x90f14cf0, 0xfe656fc3, 0x93badfdb, 0x8b8d45f9, 0x5c7d5b7a,
- 0x6ab80b2e, 0x39a3e3c3, 0xa64dff93, 0x4beaa7b8, 0x3c4cff11, 0x53fbdce9,
- 0xd5a077dc, 0x17e52fff, 0x9a82bcd4, 0x5bcc8867, 0xde647aa8, 0x6e0975ad,
- 0x2c9aefdc, 0x94f30651, 0x5ea3a674, 0xdedf5540, 0x9765159a, 0xbd3ac8ef,
- 0xffd6d67e, 0x6cf9fac0, 0x4d31bff9, 0xbe48d5d8, 0x05e337df, 0xe553ad03,
- 0x9ffe48ef, 0xfe707d43, 0xd7924d39, 0xf67a7a83, 0x44c37692, 0x7df9dce9,
- 0x88a0e5b9, 0xc2ed238b, 0x3607b6f7, 0x2b5c9ba6, 0x92617c73, 0x1e50726f,
- 0x4743a544, 0xcf3add34, 0x1fceb740, 0x76d16e93, 0x73bce0f1, 0xf1a08bb3,
- 0x8acbdfcf, 0xc83e27f2, 0xa91fbd3a, 0xf781ffad, 0x636b1d6d, 0xef4472b8,
- 0xea27593c, 0x01627c45, 0x80eff21d, 0x74b8e657, 0x3c7b6669, 0x195033c5,
- 0xb77d278c, 0xf2065bac, 0xd4ef410f, 0x5cfe468f, 0x1f67f0a2, 0x7e243ef8,
- 0x7ef7055c, 0x25980941, 0x22ae4bd5, 0x09f4b73d, 0xfc4f0843, 0x27f393af,
- 0xcb7e94ab, 0xda469d2d, 0xb567f2ef, 0x1a71d4ed, 0x1fc88a5f, 0x19fa5f57,
- 0x73f0ddb0, 0xa7556fde, 0x5977dfb6, 0x62872971, 0x084b1659, 0xa7d267ef,
- 0x1baec947, 0x5b27cac2, 0x3f20bf39, 0x9e03e0f3, 0xc4fa21b1, 0x71f14764,
- 0xf9e9f65c, 0x23ff5b58, 0xf71cb1f3, 0xf9e891ac, 0xbf78f97d, 0xeb4599dd,
- 0xa0f3f556, 0xc4c379de, 0xdca0677a, 0x37a4f226, 0x9e2daefd, 0x3804e4f8,
- 0x2a161d88, 0x6a85d2f9, 0x369d74be, 0xcfb93a5f, 0x49b979c7, 0x716dbd07,
- 0xbd89f748, 0x55dbce1e, 0x59b776ed, 0x5dd3fcb0, 0xa3fc994e, 0x64b96ff1,
- 0xdfeab75a, 0x484efea8, 0xbeb0e58f, 0xf66bbce3, 0xd53bebd9, 0x30f6aa2e,
- 0x06560ed2, 0xfec96bdb, 0xe3b6f84d, 0x2be7824d, 0xf7691eaf, 0x7a138bde,
- 0x57c1a8e2, 0x8cfc97be, 0xcf1c63d7, 0xaffaf441, 0xc67e16cb, 0x0302cf4c,
- 0x1f091fcb, 0x450cdbca, 0x764fae6e, 0xf54d975f, 0x99d0bd8a, 0xa3b2069d,
- 0x23df7275, 0xf95f12d7, 0xde1bce65, 0xbf07c77c, 0xccedb5ff, 0xeb2685f9,
- 0x863ff671, 0x749a338b, 0xa2f8a6e0, 0x4a56d6a4, 0x6dc50c7e, 0xf3544794,
- 0x9fed918a, 0xc8acd7b0, 0xb5573ce6, 0xd9eb49df, 0x1c33d628, 0xbe5a9abd,
- 0x8731e4d0, 0xbba9bf9b, 0x4c30badc, 0x16ca5e3e, 0xdbd22ef1, 0xa21cc87a,
- 0xc5f2d9f7, 0x65f8b7ff, 0x091e0c9a, 0xe4a16ced, 0x082ffe15, 0xf80e783f,
- 0x2083ce19, 0xf9583743, 0x38216a7c, 0x17022e18, 0xdbbb7cc3, 0x60337c4b,
- 0xbe248e08, 0xbbf57fea, 0xfe9be202, 0x57b6278b, 0x5f3bf9c1, 0x06fff48a,
- 0xfe78dbc6, 0xdbbe5781, 0x7039fc43, 0xf4ace187, 0x6764eac6, 0xe451f127,
- 0x53bbcb79, 0x01d73e64, 0x8b967afd, 0x03e8ab7a, 0x1b72a497, 0xe64cd8eb,
- 0x1cde908b, 0x37aab4f5, 0xc2bf6017, 0xd7ac744f, 0xb5e49960, 0x80aed363,
- 0x70ac458e, 0xa657a671, 0x2fa8a772, 0x95e8995c, 0x15585cb0, 0x4a6fea23,
- 0xc52642f4, 0xcb960143, 0x0fac00f9, 0x8bd08017, 0xf7938237, 0x96419189,
- 0x6f17fd84, 0x3e709735, 0xa4390216, 0x8e288bff, 0xb74e221a, 0x2f7908e6,
- 0xbefa12ce, 0x179b46b8, 0xc95b30f9, 0x4a6bdb1b, 0xe7561072, 0x1d12f738,
- 0x1bfc938b, 0x7ca32a1e, 0xa1360e90, 0x75567d7c, 0xaa779f2b, 0x35ed1afd,
- 0xcdbf84bd, 0xe2bc7012, 0x9f7936e9, 0x238ce713, 0xf2cdcfc3, 0xa807b5ed,
- 0x7b5a11dd, 0xc578f0f9, 0x47f71c7e, 0xd78795cb, 0x1bb14c57, 0x43f1fbe7,
- 0xe5cbcf25, 0xebe679ff, 0xf80b3bfa, 0x7e43c14c, 0x7ddda372, 0x046fd79c,
- 0x9ffad0b0, 0x40147114, 0x47e50673, 0xd2653c97, 0x11f19f91, 0x03c8639a,
- 0xddc61bf8, 0xe31bff04, 0xc77f8267, 0x27e099f8, 0xfc133f18, 0x04cfc607,
- 0x1e3b7f17, 0x8d802283, 0x4e4b4e39, 0x301ce879, 0x1c86bd72, 0xf9c1cf81,
- 0x7f3c8dbb, 0xf8cddd9d, 0xebf7a41d, 0x9973a5e0, 0x0bc189cd, 0x6fc34e92,
- 0xf0dfdd03, 0x7870e9f9, 0x2325cf51, 0xe853bfeb, 0x67a9d45a, 0x15d45ffb,
- 0x6b086f88, 0x918e4177, 0x395f0beb, 0x1fe34f18, 0xd7e20eb5, 0xa796e129,
- 0x82f944e9, 0x08332d67, 0x677675bf, 0xe51bed09, 0x51f6833c, 0x83c1f5d4,
- 0x7c78cb13, 0x75a364ab, 0xb8e51f04, 0x911f6221, 0xb5f75078, 0x81bfd139,
- 0x257e6ffa, 0x7a82768b, 0x10dc8407, 0xed43491f, 0xcff32d77, 0xccb05374,
- 0x7e9deb8a, 0x0a1e6e4a, 0x29f675ff, 0x5477e78c, 0xc7cf537e, 0xe952fe15,
- 0x1df2ae76, 0x6b901e39, 0x6ae77e84, 0xb236a5d2, 0xc9e3274b, 0xee57ac2f,
- 0xe6757419, 0xf4fb47bc, 0x6ec194ec, 0xc8d63e63, 0x5f8562df, 0x6dd85854,
- 0x36bd1174, 0x59ca1f77, 0xe4fa6164, 0xb3f6c62c, 0xbc9aec72, 0x89d56167,
- 0xe14a1fc7, 0xea9a56f6, 0xceba783a, 0x60dfe38a, 0x6d36fede, 0x93f5ae69,
- 0xcf2c44ba, 0x1076934f, 0x9ccb605c, 0xe5a3649a, 0x37fd797a, 0x41d94fe6,
- 0xa3957522, 0x29b9fd9e, 0xecc264a4, 0x9639ad43, 0xcb071f0e, 0x4d64d675,
- 0x31b4d2f9, 0xdb97f69a, 0x57f535b2, 0xd4d38fe6, 0xe55ef3ab, 0x2bb4d528,
- 0x51660a4e, 0x60fb875c, 0x64e780b9, 0x7da25daf, 0x1c62beef, 0x3f3da796,
- 0xca6e41cb, 0xda7ea566, 0xd12f5a96, 0x69f10063, 0x70ea8744, 0x1f47fae5,
- 0xe222c1a2, 0x67eec686, 0xe76d3876, 0x130c3710, 0x7100ac2f, 0xdc5c3f8e,
- 0xa02f1910, 0xf4907cfe, 0xd7abf167, 0xdc70db58, 0x2e2755cd, 0xef3ee1b0,
- 0x8238c1cc, 0x47128dec, 0x833fc70c, 0x04d92272, 0xf0c8f4ff, 0x03fc10dc,
- 0x1f850bf0, 0x3ef69c05, 0xdf0533fa, 0x4a7dbf5f, 0x07f38dfa, 0x57efc51e,
- 0xafbe4460, 0x6f78e8d8, 0xdea7e50d, 0xf9ce8191, 0x03ae24e1, 0x77e81beb,
- 0xb0f7c439, 0x46bbe9e8, 0x0f77f0a7, 0x94aba6b9, 0x731fdffc, 0x71aabf14,
- 0xcba35dfb, 0xf370f542, 0x70f69a27, 0xa6b774bb, 0xb6a6677c, 0xbb94ef7c,
- 0xe70ffbc3, 0x5c6c3597, 0x9ca37460, 0x392c3c36, 0x8be843bd, 0x28a4f5c1,
- 0x097ba1fa, 0xdb43dbeb, 0x716d1997, 0xe157edd1, 0x6cb79478, 0xaadec618,
- 0x193aea7a, 0x7faa879a, 0x71cf9d47, 0x08fbe77e, 0xcdf64f71, 0xc3b09af3,
- 0x8db8251f, 0x2fb27ce1, 0xf47b9c47, 0x1dc0f63f, 0xee79d35f, 0xeabe22eb,
- 0xa3f6144f, 0x9d33f3a8, 0x08f1610e, 0xd6455fc1, 0xd2ec8e80, 0x0f58d2c0,
- 0x2d359ca0, 0x8ae8f38b, 0x7e088fc9, 0x5e4f1e68, 0x9a0f2dc7, 0xeb1fce91,
- 0x3cbb1a74, 0x9616c140, 0xd9fd9efb, 0xf7e93b8c, 0xe92f7102, 0x2fb3ed7c,
- 0xad7d8407, 0x1e637a11, 0xb7629ff1, 0xd3565500, 0xc768305d, 0x5e10cf48,
- 0xbf6b9ca8, 0xc987fdf5, 0x7a11efcf, 0x370af283, 0xb4e05fb0, 0x1d0df368,
- 0xbbf8e72c, 0xd73efc2d, 0xb78feb59, 0xf3968dda, 0xd84647a8, 0x218779b5,
- 0x57fbc5f4, 0x5e9b3d22, 0xd05ef997, 0x04f6adb1, 0x911fd308, 0x28da6c78,
- 0xe5ab9cb3, 0xcbe55ba3, 0x830f6cbc, 0xd185f519, 0x83a706f8, 0x55b57fe5,
- 0xd27ab7cc, 0x4ec83337, 0x8bd6eeaf, 0xcdc32f4b, 0x5b064eb3, 0xb79b3cd8,
- 0x5d929699, 0x603fd753, 0xf749f455, 0x0a534957, 0x843b5c04, 0xc0bf457d,
- 0x417e4290, 0xecf1c4bd, 0x3551ee9e, 0x123da784, 0x3c256cf8, 0x5c6635c4,
- 0x1c314cdf, 0x5e50b77d, 0xf9f2d214, 0xd71aa59e, 0xacecf1aa, 0xf27659ee,
- 0x5cec3f63, 0x072907b8, 0xccd9ec93, 0x8782d74f, 0x893deefd, 0x93ca74ae,
- 0x3fee534c, 0xf60c49ec, 0x67bdbf91, 0xf744ac52, 0x3bfc7019, 0x5f757c69,
- 0xf4ae0c7b, 0x9297de66, 0x44fe752f, 0xf67b153e, 0x67aaa271, 0xa7dbe4eb,
- 0xf7e7495c, 0xf14ac073, 0xf85974ec, 0x2147f0d5, 0x6d5eaacf, 0x6c49fc92,
- 0xa633edaa, 0xa34f11db, 0xe4a97e5a, 0xf735db7d, 0xafd6cf00, 0x5fa38c1e,
- 0x567f9894, 0xb1bc4439, 0x47f3faaa, 0x57f9c5ae, 0xfe4fbc61, 0xedaec2dd,
- 0x917f08fb, 0x7c60fdf1, 0x7be62ff5, 0xd733e3a3, 0xcddfda32, 0x73df1c77,
- 0x69c7442d, 0xea817183, 0xcb173e5f, 0x58a8d6e7, 0xfc287c85, 0xee5b647a,
- 0x7f5835de, 0x66062fe4, 0xfd2737d7, 0x58ade8ea, 0x58b9f9be, 0x2491f3c6,
- 0x391d90f0, 0xebcf29b2, 0x744b06c1, 0x6fb25ec1, 0xcf8e25b0, 0x327b3e69,
- 0x512fb7ef, 0x76b7f27e, 0x7e4843f6, 0x7cc2e86c, 0xe88ff746, 0xb9a3cbfb,
- 0xbcc5b81f, 0xca5c8a0d, 0x5fde142f, 0x242ff54d, 0xa5427e73, 0x6327e1df,
- 0x7dac149c, 0x2b22be05, 0x92e7deb2, 0x5bdd10e7, 0x697ba15c, 0xf97c84bf,
- 0x06f708d5, 0xc7f2f7da, 0x89c3f3ff, 0x17da9fb8, 0x1555feae, 0x07d96fae,
- 0x84e340a9, 0xdfb43ae8, 0xb66b6c70, 0x3f057f90, 0xf18c5e2b, 0x27d30c1e,
- 0x35123b2b, 0xd1aea6e5, 0x7a6183de, 0x729ef068, 0x04e7c4a3, 0xed5c8a8d,
- 0xeddbba37, 0xfba5d794, 0x713f4ca9, 0xce84b51f, 0xf7ff08ab, 0x91ff1899,
- 0x5da2f67c, 0xf3566739, 0x4e60c93c, 0x0b75b923, 0x97dc0dfc, 0x31e289b7,
- 0xf1493d9f, 0x33b9823b, 0xb3f9c30a, 0x9c1bd577, 0x7b8931e7, 0x9f43318f,
- 0x13da77eb, 0xf9837db9, 0x699e4d4b, 0x4d09cb55, 0x015567fe, 0xd2501fb0,
- 0x89bd2b66, 0xba1487ce, 0x7aee9fdc, 0xf1def18d, 0x18bbabc0, 0xf2dc4f9f,
- 0xd3bbcd31, 0x5d83f4c2, 0x11163c4a, 0xbf98356f, 0x69efe450, 0xe87e7f8d,
- 0x9445bdb1, 0xcaf438ff, 0xd3ca22b8, 0x87fd942e, 0xf7c99d7e, 0x86dff69c,
- 0xf7cecb70, 0xb91e2f39, 0x0c7ba8de, 0x8d43d092, 0xba648fb4, 0xc77ae3ff,
- 0xf42e72ce, 0x850d81c3, 0x1f353f8c, 0xe864703d, 0xa75d5078, 0x3ebabe3a,
- 0xddb57c75, 0x5f22ecdf, 0x17f46fd0, 0x415ffd91, 0xfb6130e7, 0x17f78fea,
- 0xbbe85a25, 0x4913f855, 0xb7e30e58, 0x2abcf57f, 0xf06a7cf2, 0x47c9565c,
- 0xfdadd3ed, 0xaff91199, 0x8321e3af, 0x7eef5c3b, 0x752a73cf, 0xdafdeabd,
- 0xfd85ab7e, 0x2576939b, 0xe90e9f1f, 0x1deb0ed4, 0xb7bff23e, 0xc7e41c98,
- 0x905c9a27, 0x3469f88b, 0x9afef8fa, 0xe4d12fda, 0x7991efe6, 0x234481f9,
- 0x81e5bdd0, 0xf7fce554, 0x42bd602b, 0x9c16e871, 0xd756acb7, 0xd212c5bc,
- 0x2cfeaa87, 0x0bdf871b, 0x3ea91ee8, 0xdf2027e4, 0xdb6b1594, 0x2da3f687,
- 0xa0ae7bff, 0x6eb25963, 0x24b938c8, 0x1b65c857, 0x9e42c874, 0xa89d1d85,
- 0xbf0d1de0, 0xacd7ee1c, 0x40fcf452, 0x0743d9bc, 0x8ab713bb, 0xf513ab7b,
- 0x5104edbe, 0x124b400b, 0x89f4995d, 0xfab4baf1, 0x1cc86c9c, 0xd8e3cbb6,
- 0xc8504f2e, 0xccd4b77d, 0xf7435bf7, 0xc132fd5c, 0xd0c8218b, 0x413d5609,
- 0x4bc30324, 0x2a70c5c0, 0x0cbc3334, 0x015e19da, 0x02af0c1d, 0x89f8433f,
- 0x1ed80daf, 0xff656edc, 0x3a25f2e9, 0xd765cbb2, 0xcf97ed0e, 0x3c35f052,
- 0x57cb503e, 0xa63e3b9c, 0x8772f72a, 0x7cd8cbc5, 0x2f157be6, 0xec4fe226,
- 0x34de0317, 0xc0209382, 0x46264ce3, 0xdd78a6ce, 0x6b7ef7c6, 0xbae5c9c1,
- 0x6547c4b3, 0x1777adc0, 0xda97810c, 0x9e64f9a1, 0xb90327c2, 0xe951f8c0,
- 0x8dae48f5, 0x30dd2acb, 0x7b234c50, 0xc84f4d10, 0xc59675a0, 0xa7a71cd6,
- 0x5f3fb722, 0x7a8f5336, 0x66b4acb4, 0x5f90a90d, 0xe5154ee6, 0xd32f3589,
- 0xf3fb7d51, 0x71728a97, 0x81c1a94d, 0xcbdae85e, 0xfa825e66, 0x27dcadd9,
- 0xa011a337, 0xb672637b, 0x2b761738, 0x724dcaf7, 0x2fba5ae6, 0x580dba66,
- 0x0063b8df, 0x22d7ecfc, 0xb8bc91b7, 0xb37b1c45, 0x3aafd055, 0x2e4b7dd6,
- 0x2fb333d9, 0xb87486de, 0x28dd6d79, 0x18f79bb2, 0xa49ff8c5, 0x81bdc6da,
- 0xc49932f8, 0xbf7556bd, 0xc189ef58, 0xadb24072, 0xad0cc969, 0x59c75d4b,
- 0xe9d77bcc, 0x774fcde6, 0x023d206f, 0x15c70736, 0xbefb1463, 0x34c4cb65,
- 0x1d7030f4, 0x20475e56, 0x0b4d772e, 0xee91dd56, 0x1bc6847a, 0xf87c1388,
- 0x7529d108, 0x75cbe878, 0xc43b943e, 0xdfb581f7, 0xbd23eabc, 0x042e29f4,
- 0xae4df9c7, 0x475a71fb, 0x51902e93, 0x45fbf48a, 0x05007a2c, 0x9096be21,
- 0x0f107398, 0x1af04e6d, 0x77945e59, 0x99f9ca36, 0x8b03172a, 0x4fc43c71,
- 0x8b55cb99, 0xcc5422ee, 0x60937e6e, 0x16bdbba5, 0x179e686b, 0x724d3d68,
- 0xe4f881b0, 0xc607e268, 0xc76e594f, 0xf454fe0a, 0x9eb6f759, 0xa288c6db,
- 0xb2e4c20b, 0xaf89db69, 0x6f7486ff, 0x5071663a, 0x3e3c90f3, 0xe79c46b6,
- 0x46fa345a, 0x5d09d395, 0x9c383e26, 0xc5a2f5b8, 0x07d26ed4, 0xb7a4d9bd,
- 0xda06f727, 0xe81e7dc8, 0xc8463bde, 0x7fd7ea89, 0x7d8b9d23, 0xfc8cccf9,
- 0xf9104091, 0x839c5e23, 0x8af4fc73, 0xad5f0738, 0xeca93de4, 0x788b7de1,
- 0x573b8d54, 0xde2dbcf6, 0x6ff07985, 0x122bbd05, 0x713e967f, 0x6fc455e3,
- 0xd48bef91, 0x6949b478, 0x7bd7a2b7, 0xf227ed37, 0xc51351bd, 0xbfc345a3,
- 0xa27a6a37, 0xc8d1e396, 0xb9bd46f7, 0xb14afe4a, 0xa1f8a08f, 0xb436944b,
- 0x87c70b3f, 0xf709af46, 0x35c9fab6, 0xd3952b0e, 0xc7d60e2d, 0xe10e3d57,
- 0x6489e1ed, 0x9e5519e6, 0xd893ad97, 0x5af156bf, 0x49c9bcfc, 0x7e7e28eb,
- 0xe8cdfb14, 0xe97b8bef, 0xde913e4a, 0x837bd012, 0x2cc189cd, 0xb9ba67ba,
- 0xfe41df3b, 0x9d5a1ff8, 0x68430ff0, 0x503c6a7d, 0x4b54bf27, 0x2d8e87ef,
- 0x3f0b38c2, 0xa679eead, 0xd5e58ccd, 0x1055e9eb, 0x13f384a5, 0xdf2aafc8,
- 0xc6978329, 0xd543ef01, 0x39153b08, 0xc0e9a537, 0x188f8616, 0x0db008db,
- 0x29300f91, 0x4fcd8bf4, 0x39c7d4d2, 0x4ff4d02e, 0xd4d2cca8, 0xf788c5b7,
- 0xfa71e032, 0xef422a0b, 0x3f9d1248, 0x0083f4d1, 0xbd08adfe, 0x7e27b917,
- 0x4f7e4eea, 0x3ce06fe2, 0x2565f245, 0x7926f69a, 0x5dfc4cab, 0x435ea5fd,
- 0xa6529fcf, 0xb956f11b, 0x9c1cfd1b, 0xb69f4267, 0x01e0263e, 0x5bb317ea,
- 0x984bc9af, 0x85f2da6c, 0x629e4a79, 0xe4d58c2c, 0x2ef10629, 0x61d8fef8,
- 0x0545f31d, 0xbaaafce4, 0x006cf08c, 0x6f1a2daf, 0x5df840c7, 0x1c5ac6c7,
- 0x426a96f4, 0xc932cbcf, 0x8b4baa41, 0xb5b351ff, 0xd6ed1ff8, 0x52cc7be2,
- 0x9bd3be2d, 0xb0bef8b5, 0x4cd78b45, 0xd96f168f, 0xda6826eb, 0x346bdbdb,
- 0x578dbce5, 0xe45fda68, 0x8f29a19d, 0x4d7af17b, 0x858ec2fb, 0xaee2fa9a,
- 0x957a9ae5, 0x83e386cf, 0x11d5bef1, 0xdd03a6fc, 0x74a0f869, 0xf335cfe7,
- 0x9ff450fd, 0x05e8a79f, 0x2bd7fe85, 0xf8dde576, 0xb892f7c3, 0x7a158b4e,
- 0x50df3070, 0xee78e06d, 0x6d725b3d, 0xc505e91c, 0x7b14b9de, 0x894f3907,
- 0x1d9455b2, 0xa2bf717e, 0x36ab9f64, 0x2cf746de, 0x8a8afdc4, 0x09b5edc3,
- 0x1de23ed4, 0x494af4d6, 0xf91dde73, 0x67a66b2e, 0xd1209cad, 0x3f7144bd,
- 0x841ef231, 0xdeab3efa, 0x2739a319, 0x96bdee1f, 0x78c25f9a, 0x2f148c01,
- 0x3efccce8, 0x721fda31, 0x5fd9946c, 0xf6ffb373, 0x79cdc967, 0xfecc6ba7,
- 0xecefe20c, 0x79f5eeb1, 0x3aa3b788, 0x3dfd8d87, 0x00d6fde5, 0x2fdf8c6d,
- 0x3ca4ccf5, 0xbb8600e9, 0xdfd4d794, 0xbd2663b3, 0x5be5c45b, 0xac221503,
- 0xe68f3fa6, 0x71a41fb9, 0xbbd6480e, 0xbbefb14b, 0x20cf3e13, 0x73a2667b,
- 0xff3e12fe, 0xfc2f387e, 0xee147bfc, 0x406df50f, 0x79f0f367, 0x8e25cfee,
- 0xc1a73e53, 0x77e4c2aa, 0x4f79419d, 0xb9b6e22a, 0xb8d4be0a, 0xff328e6d,
- 0x29621c01, 0x5db9f3ea, 0xacbc667f, 0xe253eb48, 0x158766bd, 0xac71bfc7,
- 0x7bef84a5, 0x221d4b39, 0xb8e357de, 0xb1f7f231, 0x87ba67b3, 0x88ed22b5,
- 0x97869e26, 0x57cc8792, 0x42c5e646, 0x1fe316fb, 0x76cb1f58, 0x74fac0e8,
- 0xc6863fce, 0x85f9ca3f, 0xfbdacdb9, 0x3e5bf3dd, 0x02dff0d2, 0xfa9a27cf,
- 0x30d04a40, 0x781ff706, 0x1bd4f475, 0xaffd7f10, 0x9e282a98, 0xe4f5ba45,
- 0x0fc68795, 0x897797dc, 0xb4ce1bf0, 0x1d79cfcf, 0x5afdcabd, 0x5bfb9f75,
- 0xd03971f7, 0xefb8881a, 0xbfc4d1e4, 0x09fe342a, 0x0e8fc9f2, 0x431c234a,
- 0xe76673e5, 0x57a9388b, 0xabda7779, 0x55ed3bbc, 0x2af689de, 0x957b42ef,
- 0xbbeaa177, 0x9c095edd, 0x8e64bf74, 0x816a7ae4, 0x0f76efc4, 0x969b3ed1,
- 0x5de88b07, 0x60715363, 0xbbf3249e, 0x7df423dd, 0x45bb7788, 0x69f49592,
- 0x6ef435ea, 0xcf08f0f7, 0xd9d8b251, 0x50d789f9, 0x28d870bc, 0xc5f4a3e4,
- 0x7bd2666f, 0xdd53c7bd, 0x3fbf89c7, 0xf31f6495, 0x9f12ebf3, 0x6033832b,
- 0xef16719c, 0x13cbbf7a, 0xf32734e7, 0x0a89b9c4, 0xbd0be647, 0x9cb04a56,
- 0x2e6f72e8, 0x68dabbbf, 0x385777e2, 0x7617539f, 0x7df2221f, 0x4d1fc95c,
- 0x6a1fd23e, 0x5f2127de, 0xbbd3379c, 0xca675a39, 0x6ef126fd, 0xa0cfe02e,
- 0x0f747677, 0xbdf245ca, 0x1de29c1b, 0xf0a6de5e, 0xf90930f7, 0x45bd3dca,
- 0xb7a779a0, 0x7ec0e7b2, 0xe5af27d2, 0x53f393b9, 0x56c7ef43, 0x7f676fc6,
- 0xc6df20af, 0x797ae2f3, 0xee17a8ff, 0xc79cfa24, 0x7e56617c, 0xd7fff479,
- 0xf5bc3860, 0x5a3ff62f, 0xf77a1990, 0xaddef616, 0xaf2c3f20, 0x343faea7,
- 0x42e5e9ce, 0xe5a97bcd, 0x93dd8f43, 0x7486724b, 0x5948f911, 0x88633f9a,
- 0x05f3d3fe, 0x774feffd, 0x97f9a04d, 0x60bc8b37, 0x6fda6f88, 0xdce898f9,
- 0x3ef21963, 0x723fdabf, 0xf5b72b9f, 0x9f703e30, 0x617f68f3, 0xf08cbcfb,
- 0xbfb3eea5, 0x05a3ef7b, 0xdfdf73b6, 0x6e777df7, 0x6d71811a, 0x767950d2,
- 0x7e613eb4, 0x3fed4999, 0x8fedaf56, 0xb1e5390e, 0xd1de48bb, 0xe254e96f,
- 0xc4cbb21e, 0xee5daa17, 0x2920e254, 0x02ed83b0, 0x71724bcd, 0xfb61e4b7,
- 0xda3be6a8, 0x947fb424, 0x61af7057, 0x685f217b, 0x775f1071, 0x49f9ef22,
- 0x58cef41e, 0xc44773ce, 0x758b3fd7, 0xbc7844df, 0xa335aff9, 0xf2defe28,
- 0x38942b97, 0x72abd84e, 0x69cb3f85, 0x4147da7e, 0x996df302, 0x730abeb2,
- 0x55c9fb33, 0x5e4591e0, 0xac93c943, 0xdff1c1df, 0x141a01ff, 0x43d0aaaf,
- 0x000043d0
-};
-
-static const u32 usem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x1894738a, 0x18357a18,
- 0x326b3618, 0x31686830, 0x20318830, 0xaf8568e4, 0x9fa65371, 0x8181959b,
- 0x81f98817, 0xd7881058, 0x6c303133, 0xff5e2260, 0xfb045111, 0xc303209e,
- 0x197f2051, 0x6614ee90, 0x64055860, 0x2fe2031f, 0x1080be40, 0x100c8303,
- 0x606115ff, 0xc1d20530, 0xc4036c40, 0x9bf145c7, 0x7c80827f, 0xbf2a08bc,
- 0x279f8d1b, 0x25ff5f8c, 0x0ff2fc11, 0xc363c808, 0xc7e41632, 0x7a052247,
- 0x29370207, 0xca8ff2a2, 0x543c3033, 0x51d06060, 0x919bf082, 0x6280ede4,
- 0xec21e4c7, 0xb8c09229, 0x28b5ca07, 0x2a773762, 0x5004fe50, 0x34894bce,
- 0x41d3dcf7, 0x8434afe5, 0x3ebc00d0, 0x03a8e414, 0x000003a8
-};
-
-static const u32 usem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xc5547c0b, 0x3d9cf8b9, 0x926eece7,
- 0x2126cddd, 0x26c2bc21, 0xb80d4401, 0x41a00c40, 0x94520f37, 0xa2a1e1a8,
- 0x24786c22, 0xf622ef21, 0xddbf1f62, 0x52c488f0, 0xd4c51f1b, 0xb051768b,
- 0x40368bd1, 0x5c1758d0, 0x6d8b459e, 0xd5a045e8, 0x5e40137a, 0xa540b206,
- 0xcffd45b6, 0xdd9ccdf7, 0x26364e73, 0xf6ffef6a, 0x9fdbfffe, 0xcccce61d,
- 0x7cdf3337, 0x9be6bdf3, 0x91be6489, 0xf21387d8, 0x256efc25, 0x108951e4,
- 0x9b4e1892, 0x9fc6933c, 0xedb10994, 0x3bea247e, 0x9e0c8499, 0xd146706b,
- 0x64085fa2, 0x21064b4e, 0x758d65c9, 0x793dfa46, 0xe8bc7d91, 0x9819c308,
- 0xbdbae47c, 0x720c8409, 0x8266f6d3, 0x7fe92fbf, 0xc637b73f, 0x79c87491,
- 0xe131a285, 0xbc9a4afa, 0x877bfa48, 0x149bbeaa, 0x48dda675, 0xfd51fbfb,
- 0x9085b720, 0x4678c31f, 0x40cba942, 0x78b8e8b2, 0xfd2e6f5d, 0xaf0e3a3f,
- 0x295be8cd, 0x1c1a2210, 0x242444b1, 0xa0482326, 0x679fbe9d, 0x49d7ed3c,
- 0xaa36a708, 0x49e74ac8, 0x0896b4c8, 0x808972f5, 0x76cd8878, 0x78e97b25,
- 0xe22e7d57, 0x220d57bc, 0x27d69da4, 0x684ed392, 0x61c4953a, 0x232dc7bd,
- 0xd57e4206, 0x07123fae, 0x199b1b85, 0xdc155e24, 0x0e210f06, 0xc7afc513,
- 0x8f2ae98c, 0xc4c9a79d, 0xab210d71, 0x574c0e3d, 0xfa634679, 0xdb27d0d8,
- 0xf9d00673, 0xe9d8320c, 0x63834848, 0x1191dda6, 0x2dc72786, 0x0938e730,
- 0xae2926c9, 0x2f5a54c4, 0x4dc840d1, 0xf342dc84, 0x19082375, 0x5084ec49,
- 0xbc933dfc, 0x019dca2c, 0x45e60779, 0x7cc37103, 0x2e033263, 0xc62de291,
- 0x1c95cf69, 0x1bf8efe1, 0x785fdf80, 0xc1d6152c, 0xefcc1b7d, 0xf0ece219,
- 0x46dd9e02, 0x7f5a26e7, 0x5e4ceca5, 0x468ae14a, 0xad832eda, 0x1e1094bb,
- 0x1fc04cdf, 0xc9cc8fed, 0x30d7acd5, 0xb4224718, 0xeb05dc73, 0x75b27164,
- 0x1574095a, 0xf2e61d61, 0x77655875, 0x38fd19d9, 0x11fa2449, 0xb1fa5aed,
- 0x8fe96864, 0xba9fb17e, 0xbf69e79e, 0x3bed424d, 0xbd3ce953, 0x4dce0c4b,
- 0xa160dbf4, 0x0af80051, 0x80c425bc, 0x41f92afd, 0x63a05265, 0x179e1ab4,
- 0xf6f7e9cb, 0xefcf730e, 0x52e2062d, 0x2a5372e8, 0xcec4777c, 0x6626e3a0,
- 0x6b4cec47, 0xe987f1cf, 0xc925d924, 0x4c0eef40, 0xac47041b, 0x477ce300,
- 0x9c049b24, 0xf6a4727f, 0x08edd3ff, 0x377ae1f1, 0xda5475f0, 0x3d203c51,
- 0x468b1f79, 0x3450883c, 0x17e70c39, 0xad17cf1c, 0x4a434f45, 0x5868e348,
- 0x875f9a5f, 0x79a663f4, 0xb09be62b, 0x3fca1edc, 0xacc9e58b, 0xba5e5d3e,
- 0x55e3bd18, 0x6eda1759, 0x4291c203, 0x38445e70, 0x9bbf5096, 0x94203f30,
- 0x1fd625ff, 0xb7f7eaca, 0xceed251f, 0xf9c29e0d, 0x003b2ebf, 0xd6dbc29f,
- 0x2e94adc0, 0x7c106e0e, 0xec0f9a26, 0x75fe418c, 0x9f0cfd7e, 0xd767e289,
- 0xea0b9338, 0x8398df9f, 0xefedbcf9, 0x5e5a24db, 0x20945db5, 0xd679d86f,
- 0x5bf141d6, 0xfc7f6a63, 0xb83dfa66, 0x602f245d, 0x9f71d377, 0x48b4e29d,
- 0x92f9633e, 0xdaad9628, 0xc01e6bb0, 0x91336b2d, 0xeaa70a28, 0x6f3bd2cd,
- 0x03d2f9a6, 0x552a8132, 0x838cea9b, 0x4f897e69, 0x8afc8168, 0x3f601f9d,
- 0x0ca4b9dd, 0xe039f7f6, 0x752f945b, 0xee93dadb, 0x7dcbdfa6, 0x7ea00a5b,
- 0x09c166f9, 0x7ebe5c4b, 0xbf0087d7, 0x211e55bc, 0xcd15f852, 0xdaa1c431,
- 0x17db792f, 0xade309df, 0x9426477a, 0xabb291ed, 0x1891190f, 0xe02346a4,
- 0x13d36ab5, 0xe79be046, 0x1fb0073c, 0x2f559f05, 0xbb687ed3, 0x2704d7ea,
- 0xc0daad4c, 0x3785cdf8, 0x68bce6a3, 0x19d57981, 0x37fb4147, 0xbd42351f,
- 0xebf15f52, 0xdf180e51, 0x8c016306, 0x6306fd73, 0x566f8a89, 0x3356ff34,
- 0xe94d53ae, 0xbd19dd03, 0xce39e7af, 0x397c95b7, 0xdf484015, 0x4338cf92,
- 0x339e87c5, 0x57fd21c4, 0x11c48b34, 0xdf781f81, 0x8760fbe7, 0xbe03f195,
- 0xc0ed4b5e, 0x75ebc21a, 0x4fd7cec9, 0x88cd660a, 0xe71ee7c0, 0xcb91a3f2,
- 0x7e41278f, 0x2e69f4d0, 0xf971d63f, 0xe271e4d1, 0x933d67f7, 0x71ef5d30,
- 0x67bcfa61, 0x4f3ea61a, 0xc17bd611, 0x8dd30733, 0x7f7e371e, 0x698653c9,
- 0xbf16a7b3, 0x8e59e2bf, 0x178f66e9, 0x59e6bfbf, 0xa78b6983, 0x9eadd311,
- 0x3d5b4c26, 0xbaf7ac3e, 0x36d319a7, 0xff7e0b4f, 0x530da7b5, 0xe98027bf,
- 0x9a5f584e, 0x98ed3c06, 0xc31cf6ee, 0x03a7af74, 0x9cf7eddb, 0xc72d74c1,
- 0xe49b2dbb, 0x366f1448, 0x18394117, 0x91cae85f, 0x88be3e69, 0x7ae693e5,
- 0x9f348c73, 0x8a79a6e4, 0x8195c1c7, 0x0fcd131c, 0x29e565ae, 0x66b9243f,
- 0xb2f14f9a, 0xaeb5b4f2, 0x4f9a28dc, 0xa3e5646b, 0xa3737bd6, 0x8f947e69,
- 0x39b75f95, 0xf3431b90, 0xf2b0b5d7, 0x67927eb1, 0x01b1f9a1, 0xd07f1f96,
- 0xf9a56795, 0x9f2cedf1, 0xcf37a1f5, 0x1d59f346, 0x5d4dfdac, 0x9a58bc81,
- 0xcac829bf, 0xf24ab96f, 0x2e4003ed, 0xb5cf980b, 0xd1c7e4e4, 0xe59dae7c,
- 0x4b16860b, 0xb7f4088e, 0x0858ee53, 0xb0867c22, 0x7e5125d1, 0xf1d8d3b3,
- 0x647d1510, 0x4baaf0a1, 0x2033fca2, 0xfe504593, 0x963af0b0, 0x19648c07,
- 0xbc2a3f94, 0x65bbe58d, 0x5cff9607, 0x46f2c038, 0x87ff9607, 0x7bf30870,
- 0xef961765, 0xf2c4fe10, 0xff961746, 0xf981385e, 0xcb1bb2fd, 0x962e853b,
- 0xfcb1ba37, 0x5753e949, 0xdf2fed3e, 0xdc2e9ee0, 0x5ddb7208, 0x6a597286,
- 0x597e0649, 0x04fff9cf, 0xaf2d0640, 0x3944641f, 0xacf3f3b8, 0xd3814517,
- 0x97c800f6, 0x05fa04bc, 0x485b3385, 0xc2827d04, 0x7386fb11, 0x349317cb,
- 0xa2f96e70, 0x20f3814c, 0x1fea89c2, 0xdc5f9d9c, 0x17cf1da4, 0x129c0ae5,
- 0x7fb5979c, 0xcbe5baf3, 0xbe78ed6c, 0xd4e054ac, 0xfeb89c20, 0x4f20278d,
- 0xc809c0d4, 0xe59c0aa5, 0x7fb12708, 0x271971e3, 0x8cb8e06b, 0x7538144b,
- 0xff506708, 0x378c04e0, 0xac63c76b, 0x863ce050, 0xbfd61e78, 0x534cb979,
- 0x5531e3b4, 0xc29e7029, 0x0ff6a4f1, 0x16ab6ece, 0x21adbb3f, 0x3847acfc,
- 0xaf37fb23, 0x3f169b5c, 0x7e10b6b9, 0x6b9c2136, 0xb76707fb, 0xdd9f8b4d,
- 0x5e7e10b6, 0xe98cfc43, 0x6372bcdf, 0x8dc9f8b5, 0x0de7e10d, 0xfeb8cf1c,
- 0xa26f678d, 0x137b3f16, 0x2009f843, 0x37fb1b9c, 0x2d24fc9e, 0x4293f27e,
- 0xe10779f8, 0x9c1fee4c, 0xfc5a49bd, 0xe10a4dec, 0x67080fe7, 0x95e6ff4a,
- 0x9f8b503f, 0xfc2181fc, 0x7270807c, 0xa94ccddc, 0xbdac70a4, 0x4c3fd9c3,
- 0xc3fd9f8b, 0x8939f842, 0x3852a670, 0x29c37de9, 0xa7e2d148, 0x9f842520,
- 0xb6e708f3, 0x9fd9c1fe, 0xfecfc5a2, 0xae7e1094, 0xfa3b9c20, 0xe182af37,
- 0x0c14fc5a, 0x55b9f867, 0x8672871a, 0xd8274eca, 0x9a19dfe7, 0xc13212e3,
- 0xd179624e, 0xf7a024ee, 0x433e8a88, 0xad225dda, 0x371cd96f, 0xd6a231fe,
- 0x068d726b, 0xaa56cf4a, 0x9af5a9e5, 0x1ad149d8, 0x15ce2a3d, 0x4c27c9af,
- 0x9fa9ac1b, 0x29a69458, 0x3ae7381f, 0xf720f94d, 0x487e4d78, 0xfa9a4dd9,
- 0x35736ac3, 0x6fcbe1f9, 0xf54fd4d7, 0xd3e4d4ce, 0xa9afdcd7, 0x8171b23f,
- 0xa69afca6, 0xb5f94d72, 0xfc9aa5be, 0xd7dfcdf5, 0xb2d31fd4, 0x437e5342,
- 0xf29a63db, 0x35278171, 0x9e0709f9, 0xb1bfd4d5, 0xf94d05fd, 0x68af63c4,
- 0x6c7727ca, 0x3e6fe4d5, 0xfd4d6bf3, 0x9addc129, 0xbd9fadfc, 0x439fa9ab,
- 0x6fab53fe, 0xd4d03f9b, 0xa13f6a9f, 0xf24eff29, 0x553d3a27, 0xccaf1f6b,
- 0x32afcc21, 0x01afd988, 0xc6f311ab, 0xa76616c1, 0x271c4b58, 0x7718fd29,
- 0xa00c742f, 0x033403f4, 0xe0ce5176, 0xe83a6bb2, 0xe4ddeff7, 0xbf4ec6be,
- 0xbee8cf7f, 0xbf411ec1, 0x9026f4a1, 0x061d4864, 0x8fe5f548, 0x73de8cca,
- 0xd51d5c87, 0x18d7db49, 0x68e2a382, 0xe73123fe, 0xf9c7a03e, 0x83ee0306,
- 0x42d49168, 0x411368bd, 0xd4d1e9bb, 0xaabd17ac, 0x1866b0fd, 0x308433d5,
- 0x3bb235dc, 0xc328f519, 0x9bd03af8, 0x79d187ea, 0xd164260d, 0xbcbb718a,
- 0x61fb6823, 0x8fe0c925, 0x3f991930, 0x91bfd424, 0xfd819ff6, 0x6bfe812f,
- 0x94dfe97a, 0xbfd34936, 0xd34ca539, 0xfb48d9bf, 0x90f213b7, 0xbfde26e1,
- 0xcb36fd19, 0xfec64c56, 0xd865294d, 0x6a46a3ff, 0x8ffba977, 0x88fff50e,
- 0x31ebf681, 0xc7b9bb30, 0xd26ed3fc, 0x5ca53fce, 0x9b237f3b, 0x2e434aff,
- 0xe71a3fef, 0x0e456abf, 0x394a7f9b, 0xc189bf9b, 0x0b6ff50d, 0xfa01bfe1,
- 0xfd2f69ff, 0xb5b3d29b, 0xa95e1ff3, 0xf589bf9d, 0x76e194ff, 0xfb05bfde,
- 0x6dc57a7f, 0x2bc3fe6c, 0xc9a37fb1, 0x31fa04ed, 0xf5ae890e, 0x50c9fed1,
- 0x040d256a, 0x40fda172, 0xfd1e3a3a, 0xd21a7708, 0x8bdf1c70, 0x2576f466,
- 0xf21bd29a, 0xc3b32f33, 0x5273947d, 0xd39aaabb, 0x1ce6c57a, 0x2c3df023,
- 0x3164224f, 0x36a2ea1f, 0x3c9be911, 0xa48df26d, 0x26d0bde3, 0xe8bf217a,
- 0xe03e29e9, 0x322635af, 0x49da08bf, 0x3fdf0024, 0x1798d9fe, 0xa7d2f3d4,
- 0x53e51b8b, 0xde45fc91, 0x96ba325c, 0x1002ef8e, 0x9c7f2a81, 0x186071da,
- 0x1eed487f, 0x139fed42, 0x23efeb32, 0xbe41ef6a, 0x687bda83, 0xe63a9338,
- 0xdebaf357, 0x5fc7411f, 0x0b9f9444, 0x6e2f79e7, 0x624f0a29, 0x5af8f7fb,
- 0x31eb07c1, 0x450c797f, 0xc53c787e, 0xbe4d04de, 0x07eac4c6, 0x2f7c136f,
- 0x0dc30808, 0xe1c199f8, 0xcd2f1811, 0x36b3b1cf, 0xb1de7747, 0x7dd1b05f,
- 0x5d0866b4, 0x599c308b, 0xa40f25c4, 0x565eefed, 0xa76b832c, 0x8186105d,
- 0xa166b09f, 0x3768024c, 0x0649137b, 0xde3a0e27, 0xfe0cedfb, 0x527c970c,
- 0x239b47ed, 0x74455d9b, 0x458a733c, 0x69acff1c, 0xed3ff2da, 0xc619718c,
- 0x53cd74d2, 0x45ddcfd8, 0xe77bf2da, 0xb9f7f368, 0x572a79b5, 0x0fab9065,
- 0x53bfe994, 0xdf8124b4, 0x001bf431, 0xe3907ce3, 0xd95ac1e1, 0x6a5759ab,
- 0x72951b76, 0x09b88470, 0x8bdb0bce, 0x5fcfeb3d, 0x7b17cdae, 0x6b85f9b5,
- 0xdd39f074, 0x7febe29c, 0xa683e81c, 0x283e81a7, 0xfa724f3e, 0x2d55f308,
- 0x9a13dc7d, 0x650fa306, 0xb624a71e, 0x33d6a704, 0x18dc58fa, 0x8a1e9913,
- 0x52e0f443, 0x0f4297d3, 0xfc3d38f3, 0x6943d399, 0xeeae9693, 0xc9d5be23,
- 0x6b03fdb4, 0x1d3ae177, 0x3d198a11, 0x87a140fc, 0xb83d0d0e, 0xd7e83d39,
- 0x87a71e6f, 0x7a308f79, 0x0767afd0, 0xa68e87a7, 0xeb4932cb, 0x1d74aeb9,
- 0x0eba7934, 0xa3b775ba, 0x47ae8a1f, 0x10587a44, 0x389d379a, 0x65e42fcd,
- 0xd38bd63d, 0x01a79603, 0x09e209da, 0xacf7a7db, 0x2684f94f, 0x7914da5f,
- 0x36da6bfd, 0xfaa93dac, 0xf2f2d55e, 0xbb7fb55a, 0x268b79a2, 0xa6f7c4bf,
- 0xd3697ea6, 0x717e4d2e, 0xfa9a3be3, 0xd21cd70b, 0x7fbd8be4, 0xbf9fd4d4,
- 0xfe5353bc, 0x4d59ed60, 0x176503f9, 0xdcfbf935, 0xbfd4d37f, 0x13f08e77,
- 0xa2eefe75, 0xeba89fa8, 0xa7169acf, 0x0d70cfc9, 0xec37d4d2, 0xa02ef6bc,
- 0x8bef83c7, 0x4f8ff404, 0xffd1a79d, 0x7653a9f9, 0x1e939d42, 0x5383ee07,
- 0x9e98d19e, 0x9f7138f1, 0xc24cf39c, 0x1edb42f4, 0x2a15c80b, 0xc8e04b47,
- 0x96e574a6, 0x20d935ba, 0xdfca09d7, 0xd46f958a, 0xb2128779, 0x8a639414,
- 0x2326c2ef, 0x44204c09, 0xc7c4e100, 0xe5551415, 0x37947d1d, 0xd0914151,
- 0x23b0bcb3, 0x279af7f2, 0x23db878b, 0xf7847f9c, 0x7a021935, 0xe72f7752,
- 0x29029524, 0x64277f52, 0xad81f205, 0x34a94f5c, 0xb9517e32, 0xb12e5075,
- 0xaa303e41, 0x6bfaabf6, 0x206c9ba1, 0x66ba49d0, 0x5d36973f, 0x04f7e1af,
- 0x4089cfbc, 0xdf34136f, 0xd66f9a2b, 0x25daebb4, 0x81abb8e2, 0xfdb95097,
- 0x527a292a, 0xd8153e04, 0x0c6b3293, 0x14f5d38c, 0x5112dbe6, 0x34f2ec8f,
- 0xc7f385af, 0x4c169e73, 0x30da78cf, 0xac09e53d, 0x93c07385, 0x1e98039e,
- 0xda63b4f7, 0xe98639e1, 0x4c0e9e47, 0xc19cf43f, 0x209e4ff4, 0x9f3cc7a6,
- 0x43c47a61, 0x0e70027e, 0xfe98cc7b, 0xb4c763c1, 0xe98c93dd, 0xfb0f8f05,
- 0x5f5df651, 0xcb867774, 0x7f4073ed, 0xbb6ce811, 0xcd6eac78, 0xbd9d30d0,
- 0xa423f2b9, 0x85cf0533, 0x0f4e264d, 0x087a1a49, 0x2377ed80, 0xe51f4bd0,
- 0xc3a7324d, 0x2e47dade, 0xbfe179af, 0x7caede87, 0xd30b7a4b, 0x3d1d10d3,
- 0x4f45f7a5, 0xe9e9aa1f, 0xe4cec18a, 0x1fa7a720, 0x7d6b73f3, 0x3b1251bf,
- 0x77e90ca7, 0x800cdbae, 0xdcfca5aa, 0x98699084, 0x5efbc4bf, 0xa3b5c149,
- 0x0d1be81e, 0xe8d2eb72, 0x73828fbf, 0xe8c74b87, 0x3ef6a7e2, 0xf49d3d3f,
- 0xda17778e, 0xba3e2543, 0xc61109e8, 0x1af0cd1b, 0xc8d32065, 0x461a4278,
- 0x905ce4be, 0xc4897981, 0x739f7b43, 0x3af38446, 0xc06b7542, 0x5d785f6f,
- 0x1632bd69, 0xf67a9de0, 0x5e90591f, 0xf475fae1, 0x7cf5111e, 0x09d17812,
- 0x25c90df8, 0xfc193393, 0x4691c1f3, 0x6409ea3b, 0xde7f16ba, 0x6bf835db,
- 0xcfce5548, 0x7f11931b, 0x1a8cae23, 0xf5fc0fd4, 0xc2fbdfc5, 0xf79802e7,
- 0xfb3e037f, 0xf17d8fe2, 0xbc72e245, 0xdfe746d6, 0xf8cc73bd, 0x07c01cc7,
- 0xcadf1abf, 0x3c7e9c79, 0xb5f492f9, 0x493bb8e8, 0x14f6e3a1, 0x24d85b88,
- 0xa5fe11da, 0x61626bd6, 0xfa70425d, 0xede14f58, 0xbd80a73f, 0x0b553e7f,
- 0xef074b2f, 0x6d1781d2, 0x4d2d7760, 0x3270d85e, 0x69283ac2, 0x835d4b55,
- 0xb687ad45, 0x1a97f369, 0x382d6985, 0xecec472e, 0x6a272031, 0x5edf181b,
- 0x6702a98e, 0xf6097269, 0x3d39ae73, 0x3e7bd996, 0xc7360fc6, 0xe738bf21,
- 0xfffac329, 0x06f4f1ec, 0x210f1947, 0x1984e4ad, 0x4b2d31f8, 0xaf7ebdef,
- 0xc5fd2cf4, 0x7edde788, 0x89e80af9, 0x97dffa66, 0x09107760, 0x9adc0af3,
- 0xba6bd116, 0xd66fbe01, 0x39db47f4, 0x2fe23394, 0xdf6abed3, 0x4294e448,
- 0xd45e54b7, 0xe780bd83, 0xd41a4b9b, 0xcb55597a, 0x9af93577, 0xd41a47b6,
- 0xfc055c7a, 0x525ff283, 0x3740482b, 0xba8c9c95, 0x811acb25, 0x8218af8e,
- 0x088f804f, 0xb9955eac, 0x9fa6e8c3, 0x75b2b7ce, 0xe77c6deb, 0x8854e63c,
- 0x3733283b, 0x597239e2, 0x20f9b5cb, 0xaeb7ce67, 0x5bf9024c, 0x5efa5e21,
- 0xbff68451, 0x5f2e0494, 0xcf56a0e4, 0x2841f4e7, 0xe9bcd55c, 0x17c212cf,
- 0x981977cd, 0xb70f465f, 0xbe91cb8d, 0xf9bd53f0, 0x8ecdc150, 0x6eaa789e,
- 0x237468bb, 0xcbffa45f, 0xc149e30a, 0xd454b15f, 0x9771d126, 0xffa27737,
- 0x1dec8ce2, 0xe0af83f5, 0x67e73d97, 0xa3153e49, 0xb497979a, 0x260b3f43,
- 0xe3888ef1, 0x1f280fde, 0x995bfb3f, 0x57221f00, 0x742cad69, 0xc7bb70cd,
- 0x61590c40, 0x6b4167bb, 0xfbe02145, 0xd1d3ebec, 0x8a445bee, 0xa40eb86c,
- 0x9cec0b31, 0x7180c4f3, 0x1fc9e755, 0xeb54136c, 0xe464b1f0, 0x305ca678,
- 0x1034bb89, 0xd8107bbe, 0xf539a65f, 0xf858e2ed, 0x9076292e, 0x15ca25f0,
- 0x17f180b7, 0x2f77d873, 0xfd01d731, 0x634a7b52, 0x4a7b51af, 0x94f6a793,
- 0x66425f26, 0x453c4126, 0xf132d3c9, 0x4d278809, 0x8ec941f9, 0xb5252be3,
- 0xfd1fa0f5, 0x16e1fb9c, 0x843489d8, 0x37aa87ca, 0xa62acb9e, 0x9892e9f3,
- 0x0f894bff, 0xc5654258, 0x5e5e5a20, 0x2cba33e6, 0xa277e73d, 0x943dc275,
- 0x163c03f3, 0xd1bf7007, 0x886be2c7, 0xaae2ca43, 0xf3ef5a4f, 0xba2ad81f,
- 0x8f506ca2, 0x9bc6577e, 0xafe7f5fa, 0x4f212f9f, 0x9bca3ce2, 0x561c6067,
- 0x3e07788f, 0x7059b91f, 0x27ec22f9, 0xf1341651, 0xc332092e, 0x1ad7e29f,
- 0x0f5fcbae, 0x6bdf9579, 0x1bfcaea2, 0x440197f3, 0x258a5fc3, 0x913970f7,
- 0xbfc013f1, 0x7f710520, 0xc9f8637d, 0x2f5fe03d, 0x844ff8df, 0xefbb543f,
- 0xff89fc29, 0xe88ff1d4, 0x48bcfe31, 0x78deabf0, 0x778875f5, 0xcfd5ff2c,
- 0xb7ee846c, 0x926352b3, 0xe57bae93, 0x1736d5a6, 0x6bc91df0, 0xd6717d83,
- 0x448b4e27, 0x7997df0f, 0x59711fdc, 0xc2bbf004, 0x73fc293f, 0x4ef8fcaf,
- 0x6caea3b0, 0x4fe8ed92, 0x4c05366d, 0x5bab9e94, 0xb1921497, 0xf964ef98,
- 0xfd022f47, 0xc7c9b4d7, 0xfe5a74d5, 0x41259fcb, 0x94a5107c, 0x48648621,
- 0x549f6803, 0x00b8fc6f, 0x121a8df4, 0x6faafdc4, 0x167ffd07, 0xd8b0f28f,
- 0x1cb3db18, 0xd049341d, 0x5a6afd9e, 0xb4517c7f, 0x69db7a41, 0xb2d46fe0,
- 0xbe90bf44, 0x3bb7195d, 0x00eb642a, 0xc913abe4, 0x0aabe044, 0xd98f885e,
- 0x7e5f2b1d, 0x1d276c66, 0xdfc6d757, 0xbe1504da, 0x52e97b14, 0xfc5fc2cb,
- 0x1f3bd1da, 0xa3f740bf, 0xe455bf5a, 0xdb8da394, 0x56967e4b, 0xc41b01ca,
- 0x906e5573, 0xb9fa5e9d, 0x5f17d5f2, 0xd9fc167a, 0x4739347f, 0xaf15f852,
- 0x13723bee, 0x916c57cd, 0x69b21407, 0xf0a48458, 0xffd0d4fa, 0xaf0f8f96,
- 0x7db6f947, 0xf618c746, 0xe1f187fd, 0xb2d8a975, 0xf4c648cb, 0xcb5e47c4,
- 0x2587632e, 0x74b4fac2, 0xb7fe8016, 0x1abfe5f2, 0xdd9def81, 0xa9819029,
- 0x61b9f011, 0x8087ea1f, 0xbe4f5c27, 0xd3f5a15e, 0xeba1afd5, 0xbf467202,
- 0x857afa5e, 0x5c00bf9c, 0xf4a1b388, 0x21afdafd, 0x264fee0e, 0xeca1e027,
- 0x306c87b5, 0x2d52d39f, 0x56e7f3a3, 0x2bbf0127, 0x7649bd93, 0xb2f7d94c,
- 0xfa461fe7, 0x70f43d2b, 0xba57f312, 0x76501906, 0x3cc1077a, 0x1bbfaf17,
- 0xdc4259e7, 0xcf658748, 0x9a3e4589, 0x69912a7e, 0x93ec225b, 0x9c9f7c4b,
- 0x2e2e817e, 0x4569e79d, 0xe441fc2e, 0xe8bbe172, 0xcf987d0f, 0x98906a85,
- 0xd6ccd4ff, 0xd06c80eb, 0xfd10d1c8, 0xe5147c6e, 0xae61b9c7, 0x56ee7081,
- 0x28179613, 0x5343c447, 0x6275b207, 0x51db0772, 0xdf0793b9, 0xecbb7ea1,
- 0x69ab1a8a, 0xe9467287, 0x9fef197f, 0xf41a3b8e, 0x9149d3b7, 0x46e191ed,
- 0x3d500f85, 0xaa674543, 0xfff6cefd, 0xdfb606c6, 0x9beffd95, 0xffca0d31,
- 0x23ed9872, 0x97720768, 0x10302b8e, 0x16cd77cb, 0x48983f90, 0xdf3ed220,
- 0xae7df328, 0x0bd3d72d, 0xc424bf1d, 0xfa06e8aa, 0x4075c789, 0x34f25f79,
- 0xa3e2af6d, 0xadafd035, 0x1f655c27, 0x707e7297, 0xf5c1f81e, 0xd6407e61,
- 0x5e2bf627, 0xbdf652b4, 0x5fec2cf4, 0x0ebd5fba, 0x1172bfd8, 0xcd93ffcc,
- 0x4fdc8e7b, 0x2d27edf7, 0xf2d5beca, 0x2dbefd55, 0xc630fadb, 0xedf7eb9f,
- 0x496b4327, 0xbf4b7dc4, 0x43b7dc47, 0xf847fe3b, 0x24c782aa, 0x2aaf96a3,
- 0x7c37b27c, 0x16e4f9ea, 0xd57881d9, 0x3bfa49f3, 0xd27ab24c, 0x0a8742a3,
- 0x47ff95fd, 0x47e070d5, 0xe8553a21, 0x0aa74430, 0xade7ea1d, 0xfcbea3c5,
- 0x522df023, 0x537a297a, 0x4a95f3c6, 0xa6038b3f, 0xc90ff6ed, 0x50b97c44,
- 0xfdc691cc, 0xf3a80643, 0x45be5d3e, 0xcba5df57, 0xbbeae917, 0x4d5af975,
- 0x3db6cafd, 0x10748246, 0x9713d4d0, 0x31393bff, 0xfadd1221, 0xf5a1bf98,
- 0x39ee11a2, 0xd88258d4, 0xbc415e5e, 0xdc191f10, 0x51b9e221, 0x3d71c537,
- 0xa73637f8, 0x8f94bcfa, 0x7e628eac, 0xd07b6e85, 0xd5d34f16, 0x4c1f2c71,
- 0x1f03d634, 0xa307be54, 0xbbb1df98, 0x538b6828, 0x7e9d5bd9, 0x8778f911,
- 0x0dbdf22f, 0xdd70692a, 0xd7b97a3b, 0x758f9ca1, 0x62c6db47, 0x3e29d17f,
- 0xa2a9c7a0, 0xf8396525, 0x27451aa1, 0xea8bece8, 0x79c1b5ee, 0xfd3fb755,
- 0xfbf439ae, 0x164477e2, 0x4975e38e, 0xd0765483, 0x975de219, 0xf05c402d,
- 0x859fa45a, 0x2d17667e, 0x3f791b5a, 0x2576f394, 0xe0466596, 0x390ed4bb,
- 0x51ef3eae, 0xd7ad94e0, 0xe74ff77d, 0xed11a6fb, 0xda8df2ff, 0x9fb73772,
- 0xfce4647f, 0xc7191c67, 0xbfe657ed, 0xaa7b7ce1, 0x1cd77198, 0x07dd3eba,
- 0xf9a26244, 0xd7117e4b, 0xc166d2e7, 0xe237fe07, 0x57fdc44d, 0xf546824d,
- 0xd82e887d, 0xcef4d75f, 0xffb6bac7, 0x4007eb39, 0x307faf47, 0xda69dff6,
- 0x471ffaf5, 0x37f905bd, 0x407ca68e, 0xdbcfd67a, 0x02f18519, 0x48ad3bdd,
- 0xde3bddff, 0xe401f94b, 0x613934df, 0xff3bdd9c, 0xa9e8163a, 0x0ca9857b,
- 0x30f760f8, 0xb95dbfe6, 0x3b63afe3, 0xc2aefe50, 0x1a366c75, 0xffc99f99,
- 0xdee08f8f, 0x9d3f25c2, 0x3c17e815, 0xd7e6beae, 0xf0823e51, 0xbea59aff,
- 0xe76df40f, 0x43e3cd53, 0xce64adba, 0x1c5f1856, 0x79a87f8b, 0x758bf26b,
- 0xd6aaffb4, 0xb485c65d, 0xcfedef3c, 0xfd1c62c7, 0x5d37a656, 0x879e3b90,
- 0xc66d87f8, 0x2994acef, 0x26c02f9e, 0x5df646a3, 0xb07935a6, 0xe5e27a8f,
- 0xf5a7f473, 0x1aef1f17, 0xaffd7d99, 0xc5c10f8f, 0x67d59ff8, 0x7fde6016,
- 0xf403e8fb, 0x2e909a83, 0xd27ef995, 0x4cfa8752, 0xfb3ef35f, 0xfa0e86bf,
- 0xd0216f3b, 0x4d9b799f, 0xfdebdaff, 0xeb81d1b8, 0x3d07dfa2, 0xf7c77ce9,
- 0xd5aaff30, 0x27ede389, 0xfd368fbd, 0x5beeb63f, 0xfadbbae9, 0xfe77f79e,
- 0xfbdde7c5, 0x8f33bfba, 0xce1dbbaf, 0xfede6b53, 0x75f7c71c, 0xffe95cf9,
- 0xf457ba52, 0xad4376fd, 0x6f8e933d, 0x82b4690e, 0xe25f7162, 0x03a64b25,
- 0x0f2f70a2, 0x383bf8c0, 0x57608d5f, 0xbf989935, 0x581824cd, 0x82dddabc,
- 0x3b4447e2, 0x5fae4eeb, 0x0cb439dc, 0x5d3b90f5, 0x827d413f, 0x39edb548,
- 0xee7b7eb4, 0x6ac62742, 0xdcc7f192, 0x853d9f90, 0xe6f6b5e7, 0x12e204ef,
- 0x677f7ea8, 0xa003f4ee, 0x12e5dee7, 0x29a60f51, 0xa7efbfea, 0x93efb014,
- 0x7dd0f6b4, 0xdefe6d6e, 0xddfcda39, 0x843dde1c, 0x229eff8d, 0x587e07c1,
- 0x8953ce53, 0x2d3597e0, 0x0a908996, 0xabb54671, 0xbbb8eec1, 0x197edb48,
- 0x7f2a6728, 0xe3c537e3, 0x5c78436f, 0x3921788a, 0xed03de22, 0xdc7c8f13,
- 0xf9c7b3ed, 0x489ace20, 0x7bc7864e, 0x37e89caa, 0xccb8f6e7, 0x3596cbdb,
- 0x659fb0ed, 0xd8ae1d9d, 0x9be1bdd3, 0xe11cfb70, 0x2ff185a4, 0xcfb444bb,
- 0xae7d9d65, 0x5dd7cbac, 0xbf1d650f, 0x073cbaed, 0x786372eb, 0x5c5a865d,
- 0xccabf604, 0x8b7c87ed, 0x1687e593, 0xe8ae7611, 0x00d2fac3, 0x8466f117,
- 0x9897d1e3, 0x9ce02b8b, 0x405a3ccc, 0x6b5dc87f, 0xe60f9445, 0x55c7010c,
- 0xf8c64934, 0x450d8fe3, 0x85deb059, 0x7f562613, 0x09c30d9f, 0xf1c25cf8,
- 0x516a425e, 0xbf57257f, 0x0b3b32fc, 0xea0825ce, 0x845c4bbf, 0xb8ed41dc,
- 0x10216c92, 0x126af10d, 0x078ec6f1, 0x8e40b93f, 0xdae4fc6b, 0x496efc3c,
- 0xabe9c30a, 0xe5fc6f7e, 0x17fe9d9f, 0x29c767e5, 0x3a427491, 0xd497bb12,
- 0x3f7cf776, 0xa54d63c3, 0xba434be0, 0xfbeac80b, 0xb66605d3, 0x87ebfe0f,
- 0xe64f9013, 0x2c4c74fc, 0xe26407f3, 0x6e1ac47d, 0x3af25c37, 0x760fc162,
- 0xcfce9fc9, 0x6a6cf373, 0x87a4aabe, 0x9ffe1db8, 0xd3489710, 0x51a17cee,
- 0x048b3b04, 0xcdebffd1, 0xc57bc28f, 0xcca376fa, 0x6bafbe06, 0x3f002fd1,
- 0xf2afee11, 0xa6d29479, 0x75aaf1b1, 0x59c77b5b, 0x75cf6c69, 0xd571df80,
- 0xc5b7ddf9, 0x80fdd82f, 0x1d5143d7, 0xe6114505, 0xafe3893b, 0xf0dff770,
- 0x7f4ceafe, 0x99780caa, 0xce6a2f99, 0xee669df9, 0x264098cf, 0x770ab8c0,
- 0x0c9b66df, 0x744072eb, 0x1ad57dc2, 0x3ba345ff, 0x1eb1f9c2, 0xfc1f009f,
- 0x676427f0, 0xc4f3e009, 0xd808a24f, 0x73f1efd5, 0xcfb80cc9, 0x1eae8191,
- 0x731df817, 0xb84fcccc, 0x74c76cce, 0x9c8e6156, 0x68cdfb48, 0x50838fb5,
- 0xfebcc1b5, 0xcb03b33a, 0x4a76f087, 0xac95c1bd, 0x5ed1a75e, 0xbffe691d,
- 0x79f8128b, 0x937bf399, 0x75bd7f84, 0x35a9f9cb, 0x41fa0b90, 0xd167e2be,
- 0xfdc135d3, 0xe09a6971, 0xf60df903, 0x050be630, 0x53de1fd4, 0x64cfafee,
- 0x7ba15672, 0xcdab9e3d, 0x1e02f7da, 0x887f78e7, 0x678287d3, 0xf1fabf05,
- 0xbf29f52a, 0x9fed55ba, 0xdc6dabba, 0x54dfa06b, 0x81bb05fb, 0x3a96aa82,
- 0x6b0fb08c, 0xe1909eda, 0x073ee67c, 0xa2a44b83, 0x83f8eab1, 0x0f166675,
- 0xcdfc67b2, 0x2e4e80f3, 0x2c8135af, 0x1745ae24, 0xdf87c06d, 0x0f7f3833,
- 0xdfde6c71, 0x57d36489, 0x3c0fabf0, 0x597cf2f6, 0xe715370d, 0x4732ab33,
- 0x03da7706, 0x81e4bb95, 0x675a7a2a, 0xe572c78e, 0x074ae0fb, 0xfb420fbe,
- 0x1f7871c3, 0x4fb81137, 0x8ed2d192, 0xa81f6cf7, 0x5874638d, 0x88cbb2d6,
- 0x7bcd54f9, 0xfa3f4a22, 0x50bb34fd, 0x30bcaf1b, 0xe02863af, 0x5814d0a5,
- 0xa7408ce6, 0x7394a393, 0x2729afca, 0xc76e945c, 0x27247ffe, 0xa2722996,
- 0x95e3e303, 0xe7df02f6, 0x3031392a, 0x5a589c92, 0xeb0818e7, 0xfa4774b0,
- 0x4b24d840, 0x149a99df, 0xefbc4e49, 0x47cce761, 0xeef67df9, 0xdc4e54d9,
- 0xb31392a0, 0xf44e90a3, 0xf6513eed, 0x42725f49, 0xcbffb759, 0x907de6fc,
- 0xf7f61113, 0x71393a17, 0xe518bf8f, 0x45b33dc4, 0x4facbdcd, 0x391394fb,
- 0x5e61f749, 0xa044c676, 0x7db9f79f, 0x0bdf9473, 0x5e407e80, 0x11d94664,
- 0xd1b97a6f, 0x53ff5f1b, 0xfffaf97f, 0xbe159e10, 0x3fda94be, 0x7448d4a6,
- 0x979e9048, 0xbaf947de, 0xf8c8f400, 0xb907d2fa, 0x67c7539f, 0x66cf808b,
- 0x6b2cf9aa, 0x7266ed5f, 0xf52da6a1, 0xfcb4b999, 0x09d946fe, 0x30fef2a2,
- 0xf352cddf, 0x5ea8ccdd, 0xe3196ef8, 0x13fd97bb, 0x6dea7f50, 0xfce67f7e,
- 0x11b3f296, 0x31f408ce, 0xe68c6e67, 0x7189dede, 0x06d8c9bf, 0x113de5fb,
- 0xe63f79cf, 0x71c1c07a, 0x7d04c9bf, 0x9e3e49fa, 0x2f3d7c79, 0x3e794878,
- 0x22de5fc5, 0x6d574fa6, 0xd57f1116, 0x57ff6cad, 0x073e0b37, 0xff8c17cd,
- 0x56d79e1b, 0xb5e760ec, 0x39850674, 0x78aff5aa, 0xce1ea3af, 0x08362a09,
- 0xf70cde78, 0xa59f001e, 0xce259f1c, 0x29573c0a, 0xc1fad26d, 0x2f6da21b,
- 0x1e101b90, 0x78abc3fa, 0x105342fd, 0x7f0a1dcf, 0x20373829, 0xabb6d49f,
- 0x59fb711a, 0x9a2a4fb0, 0x0d9ddf75, 0x3704ae78, 0xadaf41d4, 0x7b96d16a,
- 0x8b17bcf8, 0x146d8c81, 0xb33df93e, 0xf778f4f3, 0xf653f1e8, 0x8873f12d,
- 0x9ff327e2, 0xfe259f87, 0xf05e785d, 0xc7a2f175, 0x3f145d47, 0x324f181f,
- 0x6c7e3f61, 0xf17f2170, 0xbbe22bbe, 0x189e8b4e, 0xe50f79a9, 0xef2f1ca7,
- 0x83f5dc19, 0x80b55ea0, 0x6fd74af5, 0xf34497d9, 0x38c85b73, 0x6d286638,
- 0x90e3cad2, 0xa0756ffc, 0xbb5b9f7c, 0xdab88045, 0x60befcc5, 0x7c09ef99,
- 0xe5c1e63f, 0xfad3de54, 0xdc9bc70b, 0x287e5e70, 0x53fc882a, 0x409ddfa1,
- 0xfa6f94bf, 0x0c4e38f9, 0x9ca3e60e, 0xb8ec136a, 0x4c51032f, 0x8275d16e,
- 0x4cf66d77, 0x5f016bfe, 0x6a5fe617, 0x4358eb63, 0x75f60dd7, 0x5be79f81,
- 0x80f83e98, 0xe73b22ff, 0xd992eff4, 0x490238fb, 0x44e77e40, 0x8f915cfb,
- 0x939aee70, 0x1ddf5aa4, 0x37fe8c9d, 0xe0fc4e09, 0x36fbffa3, 0xbacbdbeb,
- 0x7f4cfa2a, 0xd3c157d7, 0x1f3add4e, 0x9c2f6a8a, 0x8272e780, 0xf20bdf13,
- 0xd179e1c7, 0xfef646c9, 0x1fae41cd, 0xd805f7e9, 0x78f7ea1f, 0x21c0c066,
- 0x145a7a2e, 0xbf6295c6, 0x533f4c69, 0x3bfd29f3, 0x6e375f48, 0xa3b486a9,
- 0x7f8e165e, 0x066edf74, 0xd04d3fb9, 0x19d149c4, 0x27ffbee1, 0xbea397c0,
- 0x36493e02, 0xc8797ca3, 0x19eebece, 0x1ef02466, 0x3235e5da, 0x06bdd1d2,
- 0xe06c91c7, 0x04c98f2f, 0x83e5c7f6, 0x3b9d1e37, 0xa445ca00, 0x26f7e28f,
- 0xa56b8354, 0x91aac598, 0x5c9847e2, 0xfffbc13a, 0xaed79513, 0xa097786b,
- 0x7ce27b07, 0xb674bf70, 0x0754d773, 0x0f325bf8, 0xcf7386ad, 0x23f67959,
- 0x1b1d6047, 0xc74fbbd8, 0x9da1e4d7, 0x0577d0f6, 0xe8c767dc, 0xbb9c017a,
- 0x391ea767, 0xe0f7c742, 0xb73c449a, 0xbc4aeb9c, 0xe731ce07, 0x0e9d141e,
- 0x5de16f5a, 0x7f9c0b56, 0x122d1f4e, 0x0f2f0ab7, 0xeff47692, 0xeefdadcc,
- 0xca4fb0dd, 0xf7843ca8, 0x87fcca9c, 0xfc840ea6, 0xd7db017a, 0xb846dd78,
- 0x74ded9e7, 0xfb4998d1, 0x00f5a12f, 0x59eb35dd, 0x028d9abd, 0xe25817be,
- 0x64f9027f, 0x1f0146c9, 0xfaa769c4, 0xf5c199af, 0xbed12981, 0xf9a7b69e,
- 0x700f6852, 0x03ddc637, 0x743593e7, 0x527ed89c, 0x97539e1d, 0x98b476d0,
- 0x2efc6fb4, 0x5eb25bc2, 0xb0af7020, 0xe3ea526c, 0x41de0093, 0x47e509d9,
- 0x08dcfd77, 0xfb479ee3, 0x2fe1441b, 0x42a63b14, 0xc103f27d, 0x152eef8e,
- 0xbafb8b5e, 0x623bef9b, 0x14e2cd1f, 0xefdca204, 0x2af1d493, 0xb869d125,
- 0xd7964a9f, 0x3abcc3d5, 0x06a989bc, 0x468ba7a4, 0x2927e390, 0x7f54ddbe,
- 0x7164613d, 0x27bc7b30, 0xfe2a1d8c, 0x1d3a32b9, 0xcb6a2fdb, 0x98b33e41,
- 0x853c6114, 0x23e98ebb, 0x7ca3ab9d, 0x94eb57e0, 0x7df029ed, 0x7e136acf,
- 0x932af0bf, 0x7586173b, 0xf4fb7fa0, 0xbdc0997a, 0xd3eb95c7, 0x9e3ac1d7,
- 0xe13b2cde, 0x8e7c40dc, 0xbe9411c5, 0x7b64fcca, 0xa7b833d6, 0xcb7f199b,
- 0x02eeee7b, 0x94a5dbe0, 0x7e70994f, 0xe2563e5a, 0xf53e4728, 0x4be3145c,
- 0xe7a57e7a, 0x1b8d6553, 0x65a1cb22, 0xd0e59105, 0x37ee7ad0, 0x6b9f2c8d,
- 0xbbe98588, 0xf078c9e3, 0x0d571663, 0xf404d79b, 0x70bb20fc, 0xf3781ed0,
- 0xdc819fd3, 0x3be2b4ad, 0x7d92d565, 0x83e8c09d, 0xeb9fff00, 0xec29f2df,
- 0x51b9b287, 0x29d90ef8, 0x47d80f58, 0x1cf0136b, 0x8c57c4bb, 0x79e25778,
- 0xf4b49b4b, 0xef21f8ae, 0xa5c48b73, 0x31655f96, 0x77aaa5c4, 0x6e9447f4,
- 0xdbf33f69, 0xcab01f04, 0xdcea3fa3, 0xe62670ff, 0xe5ae38ed, 0x6b583f5c,
- 0xfa3eba45, 0x40d5c5c8, 0x287ef3b7, 0x89dbd010, 0xf20f5dd7, 0x7049bab0,
- 0xf4b89f80, 0x297dac87, 0x3ee30f6d, 0x5f4673fa, 0xb01dce94, 0x3fd7aa0f,
- 0x6feb1fb1, 0xff001c14, 0xd46286e8, 0x22bcca27, 0x9d8df2c1, 0x79504768,
- 0x7b68f185, 0xec1262bc, 0x2655ea83, 0x1562b83b, 0xb3e8527a, 0x40a7bf93,
- 0xb3b1cecc, 0xb4673b68, 0x9eb2f903, 0x4239c52e, 0xfd029e48, 0xbd1978d4,
- 0x3b2abe75, 0x4df48b61, 0xbd1eec9f, 0xd0227f42, 0xfe98665f, 0x33cfacf6,
- 0xf69e3d02, 0x91671809, 0xf40bf407, 0x9fe2b2f9, 0x1eb51621, 0xea7d17d5,
- 0xfd07b0e9, 0xe958cbc1, 0xe854fa61, 0xc7874f51, 0x8c0f7225, 0x51d5a1fb,
- 0xfabc8f38, 0xce59ef37, 0xcf9e19f6, 0x923fd5e5, 0x44bafb04, 0x0a407162,
- 0x1624ab5e, 0x5c63d637, 0x0719d74f, 0xba7c67f5, 0x0e8acc71, 0x20f1edc9,
- 0x4a3ea9b7, 0xdf9fb402, 0xe3117e6c, 0xd2bfcf2b, 0x37ea2779, 0x003a516f,
- 0x92b66ffc, 0x3e21da00, 0xade547e4, 0x1369c622, 0x4b359029, 0x712bbf65,
- 0xb2bf1531, 0xb7cbbe22, 0xb4857c9a, 0x27ebf97d, 0xc25c62c6, 0x7b7fa60a,
- 0x39d8115f, 0x2c63b788, 0x972a3bdc, 0x5e8e7c58, 0x345df82f, 0xdebbc3b3,
- 0x7a03998c, 0xdeccd09b, 0xb96f2c17, 0xfca93657, 0x65a2fbbb, 0x939e1ea5,
- 0xc33ae979, 0x3e300afb, 0x4a76fbf5, 0xcbd74e5c, 0xdbcafe8c, 0xcae7d464,
- 0x805cb79b, 0x63f2cd78, 0x6b77b426, 0xc11a2f9a, 0xd5fbcd9e, 0xc41decab,
- 0xa7135136, 0xae3e23d7, 0x20980c59, 0x0ab5abae, 0xbe6871cf, 0x3c2df313,
- 0xc66bed1e, 0x6afc556f, 0x8a5eebc7, 0xbf6d8ac2, 0x857be1b4, 0x786c9bed,
- 0xabf9aa5f, 0xc47b55e3, 0xf034b5c3, 0x4e3bb878, 0x918fe413, 0xc1cee1e3,
- 0x7d21283f, 0x878dad16, 0xbf8ccd23, 0x456671d1, 0xa4350f7a, 0xe9fabd77,
- 0xddcf10f3, 0xe793f5b5, 0x5f95dc61, 0xe21e7e5c, 0x6882a86c, 0xe6a53d07,
- 0xfe31f795, 0x1f176955, 0x97a0edc3, 0xc3f1897f, 0x7268fe17, 0x3b0bb402,
- 0xfe80a74e, 0xdfcb6171, 0x782e2092, 0xe8a98ed9, 0x3db659df, 0xedbddf0f,
- 0xfa059ecd, 0x7e23f5f5, 0x7b6ebf59, 0x3c60f75a, 0xeeba79d0, 0x714227c0,
- 0x2c552d8e, 0xe3c1d47e, 0x8e47371b, 0xcf11ef17, 0xaeeb3ad8, 0x5b1fc029,
- 0x67d09e99, 0xba61e35c, 0x63f4379e, 0xf8f3371d, 0xbe3b96d5, 0x3cf1ae32,
- 0xd7ae83fc, 0x7c6d18b8, 0x8bada7e8, 0x942cf17f, 0x1af426b5, 0x07e818d7,
- 0xf47894fe, 0xd95da3cf, 0xdeb08931, 0xa4f181ff, 0x0e857eb0, 0xa69fd7e0,
- 0x8cf8bf80, 0x44bf441c, 0xef098770, 0x38ef966b, 0xc2e9fb8a, 0xef1843f6,
- 0xf85c784d, 0xb1fa1205, 0x03ee5df8, 0x6568d9aa, 0x1d7c90f1, 0x61d25e20,
- 0x2e3cefc3, 0x12b5d192, 0x9c5bd92f, 0x3498b2e4, 0x8b0b3efe, 0xf8daace7,
- 0x0c3f8f01, 0x09309baf, 0x2bf3abd6, 0x3c1550e3, 0x130f01d8, 0x91c071d5,
- 0x714352e3, 0x8375bac0, 0x1e3e04f5, 0xf9a5f38a, 0xe9ef10a1, 0x8a468e13,
- 0x81b0bf2b, 0x905f0fc5, 0x568fdf23, 0x626b82e2, 0xd7d6fb74, 0xbee078bf,
- 0xf175f1e6, 0xa1c63f34, 0x5f051ba1, 0xf323575d, 0x846327f7, 0x85b7646f,
- 0x0a549bee, 0x4f2cfbfa, 0x997dc0c4, 0xbe234ed6, 0x55d8a293, 0xdc5dbe7c,
- 0x8af5d6df, 0xf5a27188, 0xbf907b2d, 0x3547f9eb, 0x8fd1473f, 0x6f1f2377,
- 0x1f931b75, 0x3ead5b5d, 0xb5d3850b, 0xeba44dfb, 0x189dcdea, 0x79bfbaa7,
- 0x7543b19b, 0xc3f20cfe, 0xd77f1aa7, 0x22c6bb6b, 0xa2efe73f, 0xcad9fbe9,
- 0x3f8d63f9, 0x9b353f72, 0xa9fa6a2f, 0xed18b6f0, 0x3bfbbe96, 0x05eeb927,
- 0x99dae778, 0x45ae751e, 0xd08be69c, 0x6462cfff, 0x3237576e, 0xa395383f,
- 0x959c3ef8, 0xda2707bd, 0x5b2f51a2, 0x0c749d66, 0x665d21de, 0xcc5c6235,
- 0x471e3aca, 0x326723f3, 0xeb4af7ac, 0xbbc604ed, 0xb2abf01a, 0x9bbb65ef,
- 0x27273e80, 0xcfaa6517, 0x1bf19461, 0x4f881807, 0xd3ad8fbd, 0x4a7d8206,
- 0x1850ef24, 0x7f699dc7, 0xb62e4095, 0x9f7f987b, 0x02313d5c, 0xf64bb7be,
- 0x6e14097d, 0x04e0be7b, 0xba4f6cd7, 0x7e43f067, 0x1df69706, 0x4753bc5d,
- 0x69c977e7, 0x6ad13d40, 0x1569d808, 0x4f6a8d62, 0x41d70346, 0x5e12521c,
- 0x8978c0a5, 0x11e63cc7, 0x46d43f70, 0xf50adaa8, 0x5de6929c, 0x9249d895,
- 0x72159dee, 0x57a50478, 0xc557a70b, 0xff65675f, 0xf03b70a6, 0x0cb896fd,
- 0xbbe40752, 0x7d46ead6, 0x0b9b29e2, 0xdfd23fef, 0x88938868, 0xf54ed127,
- 0x5fb450bb, 0xda3b7dcd, 0xe71f26af, 0xa613e6d2, 0xc9232749, 0x8e3e049b,
- 0x7882d102, 0xe06a9b88, 0x70abb2fa, 0xdc785264, 0x19c48971, 0x2c3bf280,
- 0x6e808f78, 0x1e7aaf2f, 0xdc768b16, 0x3e1a7c74, 0xe1d19b11, 0x6a71b035,
- 0x0389dbbe, 0xe3a747df, 0xaf1bae3d, 0x70b56f26, 0x0911277e, 0xdcc59df8,
- 0x2ffe384e, 0x4abdf069, 0x224f8a2a, 0x38c2644c, 0xde2130e9, 0x83cf9625,
- 0x6fa9aff6, 0xeb01ef07, 0x0c870b5f, 0xb5efabb5, 0xe0e5c0de, 0x8a514b11,
- 0xac93ee85, 0xb818b5e1, 0xb82c9d9d, 0x65a04e4e, 0x9fc801fe, 0x61e796d2,
- 0xc8d08a5c, 0x5ac46ae8, 0x4466fb82, 0xad55c790, 0xd53d468a, 0xa8de2664,
- 0x8e3f70f1, 0xd0f1e578, 0x3f9f8f8b, 0x28185639, 0xa50d6928, 0x1fceda35,
- 0xa62c35cc, 0x4502d08b, 0x8b10fe14, 0x5ff40c6b, 0x6c9dc33f, 0x1bd30718,
- 0x2877bf56, 0xc16bdaee, 0x1ba86863, 0x14c0ffba, 0x2ef82164, 0xdd0ef108,
- 0x51b8720f, 0x0ec653c9, 0x463406ef, 0x332ef287, 0x698df7e5, 0xdaf37f2c,
- 0x7ef0f5a1, 0xe8bda74d, 0xc78c0b66, 0xcf0ebf6c, 0x9af102c3, 0x937bd5f7,
- 0x4738ca2f, 0xc1e40c6f, 0x07b7c7fb, 0x23c5fbd9, 0xfc7ba1ad, 0x59378f28,
- 0xed007c94, 0x43d6a28b, 0x5aaad7c8, 0x01b9610e, 0x9e1d34f2, 0x421bc810,
- 0x65bf79e7, 0xb5f2414c, 0x716b5e14, 0xb1c13c32, 0xbf6632d0, 0xb8c3c1a4,
- 0x61d9bdfa, 0x6e2b483c, 0x86e1e1d0, 0x858785af, 0x87a86f6b, 0x3bfa55f7,
- 0x0b174a6f, 0x73d35f00, 0xdb8ef80c, 0xf41663c4, 0x145fd0bf, 0x670e23ca,
- 0xbcf72f43, 0xc2853b15, 0x97d35729, 0xaba14ed2, 0x9d26e8de, 0xef63afd8,
- 0xe7e96a83, 0x87ae2ddf, 0x8b32de00, 0x8896dd2b, 0x0577c7f3, 0x8b8bbba6,
- 0x74c213f2, 0x09ee2c4d, 0x11feaef0, 0x5a1f82cb, 0xe9dafe54, 0x34c54b39,
- 0x011fde3a, 0x3c31b823, 0xdee5c49f, 0x9e7451a8, 0xc6032e89, 0xb8b11fd5,
- 0xdb3b4057, 0x6200609c, 0xf71226cb, 0xf70c4104, 0xfa8feca3, 0xaf8ecc1d,
- 0x56f8362f, 0xfc60f3b0, 0xfa611dbb, 0x47d1d0e8, 0x5b47d190, 0xb547d227,
- 0x47d193bf, 0x346e5d5b, 0x3b03573f, 0xc70491ba, 0x5937bac1, 0x61a40b0a,
- 0x82626e94, 0xb23740f5, 0xc282b6f7, 0x3aebc428, 0xf58f5f18, 0xe652e3e1,
- 0x36fadbd5, 0x71fb481e, 0x0799d806, 0xa61e780d, 0xb7a94de0, 0x46e2c2c3,
- 0x7ee6cdff, 0x99a9fa11, 0x961fb1d4, 0x3f81eb6f, 0xed875c60, 0xd05dcce0,
- 0xae9b36de, 0x6fdc2390, 0xf815c1e3, 0x7f23784e, 0x04963bd7, 0x7bd720bd,
- 0x3fdb07c7, 0xde807c21, 0xe8f80193, 0x0af2fdc4, 0xdd9667bf, 0xce40b826,
- 0xef618f0f, 0x616ebc90, 0x16bbf576, 0xaf4ca791, 0x5bb83c49, 0x7b2bfb04,
- 0x27eb0195, 0x9ea19a42, 0x5f5e2aff, 0x95ddf8d2, 0x89e85575, 0x7818d272,
- 0x78f9e4cf, 0xfd2d1ef7, 0xa9a4c7c4, 0x1eed29e0, 0x45a290f7, 0xee265094,
- 0xc810f05d, 0x3e3f4a55, 0x7231bb4d, 0x442de014, 0x233e943f, 0x776d0fad,
- 0x7c6bad88, 0x5b0be80c, 0xf1152ef6, 0xae7e8e5d, 0x47bc166b, 0xc567eb49,
- 0xb4adda90, 0x4d2c567d, 0xf3c09f21, 0x087e7903, 0x743fd34b, 0x7dfa041a,
- 0x9ecbf703, 0x922578e5, 0x6399bafd, 0xb8f4cf20, 0x9418e4ec, 0x85beca0b,
- 0x5ce05467, 0xdbe7e25b, 0x0334c169, 0x8fb29bac, 0x6021a0a5, 0x4d2b42a5,
- 0xce201872, 0xbb8f5de1, 0x7b0bce08, 0x5fb73be3, 0xea81eecb, 0xc7ce7fbf,
- 0xebf58df3, 0x2fb8f4bf, 0xb7e039fe, 0xf8f1dcca, 0xbeaf9a4c, 0x69fa32f6,
- 0xdf54c457, 0x68ef55fc, 0xeeffc7e8, 0x00c4dfd5, 0x333ffa1d, 0x353fbc45,
- 0xf1e8cace, 0xb60e6780, 0x04efe2cb, 0x1c4a8192, 0x15ce2ab2, 0x865eb8ca,
- 0xdf86994b, 0x05bacf51, 0xa7ac2059, 0xf6878a57, 0xae78a931, 0xae2eab78,
- 0xbb2f3955, 0x80fcc025, 0x42beb159, 0x74faefec, 0x3e49f7f6, 0x9992fa63,
- 0xa1ce0ffe, 0x3373f2a6, 0x5efb31d7, 0x09598710, 0x3f08f98d, 0x5afd1536,
- 0xfefb4439, 0xaf40d641, 0xf4f28064, 0x67978454, 0x13a795d6, 0x6b915bf4,
- 0x4df9c3ae, 0x0cfd2a25, 0x13a346e5, 0xd1f4f1f8, 0xf7f9fe94, 0xe1bff4cb,
- 0x867f3226, 0xcdb8ceca, 0xbe515f71, 0xc4696f46, 0xfb7e8577, 0x523f38b9,
- 0x2163c5fc, 0x4115173c, 0x8f1e803c, 0x95610eb9, 0xdf13d1d5, 0xf1e9fc7a,
- 0x8f51e0ad, 0x9d0f9cb7, 0x9e8ef1f9, 0x23e3d1f8, 0x5be97e7c, 0x7530eb0b,
- 0x4bf288b4, 0xfc4f7bc1, 0xedfaf5b0, 0x009eb4b5, 0x0df142f4, 0x30174cf8,
- 0x862b27be, 0x3a6c4fd3, 0x140b37e2, 0x0f4801c0, 0x55e3d798, 0x04acc78f,
- 0xd5813ede, 0x1af80fdf, 0xed00fc89, 0xb2dd6521, 0xc6f76bd2, 0xe8c4de41,
- 0xa7abd14c, 0xbd50bc72, 0xbce6f51a, 0x9bfa2b44, 0x9a9eaf40, 0x5e5bc614,
- 0xde571b15, 0x600bcb48, 0xfc0afe9f, 0x0608b1d1, 0x95bcc5df, 0x56e05ff0,
- 0xe2ca5f3c, 0xb7df0559, 0x93d5a67e, 0xce0bfaa7, 0xdc3dfe82, 0x05655ee4,
- 0x87108c7f, 0xff1479e7, 0xd7f875c7, 0xf36bb3b6, 0x0afc7c7a, 0x27b931fe,
- 0xab7a14de, 0x7cfd72b3, 0xfa0a1930, 0x3337d8f2, 0x137f8163, 0xbf447c7f,
- 0x4563c4c4, 0x6e9c3821, 0xe2059e91, 0xa7b77d0e, 0x763e0b7f, 0x15494a90,
- 0x7253bb1f, 0xd8deb3af, 0xeb298f93, 0xc7af8535, 0x05dde214, 0x4429a67e,
- 0x1ec84bfa, 0xffcf0d48, 0xb3f72b79, 0x6043210d, 0x1c585f9e, 0x79f3ff8c,
- 0xd54de686, 0x9b3fe84b, 0xb66d9ff7, 0x121bfde0, 0x7842ba94, 0x93f7c34e,
- 0xf0f8c6bc, 0xbd656438, 0xd3096a53, 0xfbe2e6e7, 0xe42f14d9, 0x38f098cb,
- 0x090559b6, 0xe3e20fdf, 0xf66cdf38, 0xd3db9c42, 0x2b0dfb92, 0x83843df8,
- 0x527e7163, 0x3fc81460, 0xb6e5f97d, 0x4e50d5bd, 0x3d6095eb, 0x910afe3e,
- 0x3b821ff9, 0x5217be4c, 0xe953d77b, 0xa13946f6, 0xdc3671d0, 0xe801bd7b,
- 0xb8c2283e, 0x655cfcfd, 0xcf7645e7, 0xabec45c1, 0xf6f0a7ae, 0x02f7625d,
- 0x81db28f2, 0xedfa7a7a, 0x49f34e8b, 0xd3b41e70, 0xcf22abd3, 0x5bfdf81b,
- 0x68bb3f45, 0xeb0fbf75, 0xe3efc0de, 0xba8e2ffa, 0x1be7d60e, 0x2d61d5d3,
- 0x44f4295d, 0xf438ebe9, 0xf1f99dd3, 0xdfcb503a, 0x049cbccb, 0xe3d151f2,
- 0xeb8afac3, 0x9bd7a863, 0xe6dc3f3e, 0x857eb2ee, 0x35e8af3e, 0x6423d97d,
- 0xd34644af, 0xebe3ce71, 0x2edcd733, 0x41c68bb3, 0x886fd38c, 0x73cbde56,
- 0x393e8344, 0x95ed21af, 0xac573866, 0x07f97e63, 0x3d8d656b, 0xbedb86ec,
- 0x67bd9ed8, 0xb6b97f3b, 0xef8a23fc, 0xcef8f141, 0x868ed6ad, 0x7e1491fd,
- 0xbf67b7cf, 0xc9c82f06, 0x31a32379, 0xafdf4e7e, 0x7efa7e7e, 0x7035fdf5,
- 0xd8c1aafb, 0xd2a9da38, 0x1636ec4f, 0xcd697d47, 0x14f0cd93, 0x73f86f5e,
- 0xd4b8879b, 0xa3ae6f7f, 0xa44e7a21, 0x781468f7, 0xc2e7be0a, 0x0fe098cb,
- 0x1eff95a8, 0x6cdd9de9, 0xf413f337, 0x6088efd6, 0x8683ea3e, 0xe82203a7,
- 0x048223f5, 0xa0ecf0f5, 0x6350b0cb, 0xb97b300f, 0xef003d87, 0x657cd0a4,
- 0x0f662eeb, 0x5da1d4b4, 0x0aed4951, 0xe01b3b90, 0x7cc1901d, 0x27681940,
- 0x885eec84, 0x7786caaf, 0x0c5db932, 0x37a5a74f, 0x1f33fab2, 0x8c35374f,
- 0x9dd5bb00, 0xce932f0c, 0xa8fb5db4, 0xf557da99, 0x508a24a9, 0x76c8aafb,
- 0x4ed677ed, 0xde3bdca2, 0xa4bbc025, 0x65a8ff34, 0xecedff72, 0x8fd1b699,
- 0xda81bf82, 0x54d9b767, 0xfb6f6f76, 0x039b66e3, 0xfedbd9f1, 0xcd17b4e8,
- 0xdf8a3804, 0xe421f282, 0xbe28fe07, 0xf442a3ff, 0x53780b17, 0xe5f6e5e8,
- 0x88ced10b, 0x0a6ae6ba, 0x736593c4, 0xb8db703a, 0xc186365f, 0x706189a9,
- 0x376e4a26, 0xfbbdd3f4, 0x3bf028ea, 0x04fa3bbf, 0x2b7e79da, 0xf41fdbf3,
- 0xe3a91594, 0x026d6bdb, 0x10c097a7, 0xdc777fd8, 0xec0127b8, 0xc0596c95,
- 0xb2fd4ef7, 0x99f1e9ef, 0xdb669fc0, 0x6629d257, 0xfde2364f, 0x60547f32,
- 0x3d2ac3c8, 0x4ddfcfce, 0x3fdc5ff5, 0xdcff1d44, 0xb5abcd6e, 0xc022f831,
- 0x7bdccecf, 0xde80f40c, 0xae584ee4, 0x2b9004b8, 0x24a1eae4, 0xdd6a5f3c,
- 0x689f0367, 0xe0e77f17, 0xa49eeb7c, 0xdaad3405, 0xb0369ff2, 0x3e38eae3,
- 0xf8ed4bce, 0x76e5535e, 0xa113df11, 0x003d26fd, 0x85d6eb7e, 0x1fdeec59,
- 0xc8a6afbb, 0xef9ff1d5, 0x9cc45219, 0x4cff7889, 0x98a737d1, 0x9f183ebd,
- 0x1dfd8ebf, 0xf7ba29cc, 0xefe56ec9, 0xcff5e993, 0xe2b26c67, 0xa9f8c32f,
- 0x4fd67665, 0xfb2bfb6f, 0x53e204b3, 0x296cbfed, 0xb3f8c220, 0xefc24b3f,
- 0x3da40fe7, 0x3df60855, 0x01239d91, 0xa2f644ac, 0xa7cfcb7e, 0xbc2f6fe8,
- 0x6793be7b, 0x3cbd6ede, 0x6e2466eb, 0xd004d72a, 0x9803dcc7, 0x07c991d3,
- 0xf5bbff45, 0x55dfad33, 0x722b07af, 0x6e3fd732, 0x780210d5, 0xfbc2cc77,
- 0x8c240713, 0xc9ebd2f7, 0xbd058353, 0x204fc3e8, 0x4d6d6d7d, 0xfe7b018f,
- 0x009f60df, 0xc65eb6dd, 0x49aa83f7, 0xc7781ee0, 0xb455baa9, 0x24fc6007,
- 0x67d87af3, 0xe0a13e8a, 0x1eeaeda5, 0x7fda58f3, 0x7d8345f6, 0x76f10505,
- 0x57682ff0, 0xc1fdf84f, 0xfe679004, 0x07e784a0, 0xc6f717d9, 0x45f1542c,
- 0x7e0355ff, 0x6eeafb7f, 0xfc60f7ed, 0x8b6ed0f5, 0x7bcbd981, 0x063dfff7,
- 0x57dbd4f8, 0x90bc212f, 0x6f53d13e, 0xcf3bfd46, 0xd1fc862a, 0x8899bd6a,
- 0xde2187d9, 0x152c6a6b, 0xfaef426b, 0x6487ce70, 0xd4f49595, 0x2778422b,
- 0xd0f0092e, 0xf0561f43, 0x3e33d3ac, 0x773d71b2, 0xef0f1918, 0x4d5db65e,
- 0xc77bc0a8, 0x0afb18fe, 0x8f4ccf94, 0xee7bdeea, 0xfdf0e9c9, 0x9ddec8a0,
- 0x7ee22ab8, 0x62b3bdda, 0xdf6a8778, 0xeb8a4e52, 0xc5d06576, 0xfad16f0b,
- 0x3345f657, 0xbce4baff, 0x224f7d5e, 0xf1c7df5c, 0xcecc1815, 0xe183bce9,
- 0xac6fa8bd, 0xb0f574cf, 0x4361fff7, 0x0058393d, 0xfad462e2, 0xffac234e,
- 0x3e8ad9bf, 0x25a5fc67, 0x978bf806, 0xb4210ee4, 0x9268b2df, 0xac15740b,
- 0x33b07623, 0x18301fb6, 0x37325d60, 0xcf5c62a5, 0x731cfc2b, 0x31a34b49,
- 0x4b174555, 0x19d839f8, 0xaf129bd9, 0x9632befa, 0xfb3397f1, 0x71817fca,
- 0x91347f1d, 0xd0f41191, 0xfe4cb185, 0xa77a336e, 0xc77a866f, 0x68df780d,
- 0xef5ffeef, 0x97937787, 0x038c731c, 0x5894e0bf, 0x0eda0fb6, 0x710f52be,
- 0x821f6dc1, 0x6672a2d4, 0xa068b163, 0x1c45befd, 0x9877afcc, 0x90d6bdfd,
- 0x12b8943f, 0xc5379e60, 0xd6fdbe32, 0xdce68301, 0xbefe2dec, 0x8cb1f5ef,
- 0x32c6a50f, 0x03d6dabf, 0x700b09b9, 0xc447b9ff, 0x64f01f82, 0x456c3d47,
- 0xe8a80fc5, 0x6f0f936f, 0xfe863e9d, 0xc1977273, 0x38edcb0e, 0xf30882fc,
- 0x24219c75, 0xf43d204e, 0xac6f0a39, 0x5d5bde1a, 0xc71d1e0c, 0x0aafd86e,
- 0xfe04a9fe, 0xbfcd0671, 0x43c52ed5, 0x7f82983c, 0xff4a1e65, 0xdae2168e,
- 0xe4adc160, 0xfe15fada, 0x31efe568, 0xe513b04c, 0x5d2033ef, 0x6eb9b76e,
- 0x6f72c589, 0xeccfe40a, 0x36d27a63, 0x72494f2e, 0x9fc070f1, 0x79f34eb2,
- 0xb7a78caa, 0xe3e7effe, 0x4bafd254, 0x0ec8afd7, 0x76cdd22f, 0xf0ee4f16,
- 0x10e9cc06, 0x8e96d677, 0x154a9f7f, 0x8e3f7b97, 0xfdf68cff, 0x830eb6c2,
- 0x558fee01, 0x50e210ef, 0xbea7eddd, 0xa933a21d, 0xedafe905, 0x5c7dc118,
- 0xe65dfcde, 0x9f72a48f, 0xe786ebbf, 0xf87fb0eb, 0x8120fb39, 0x1bfd93a6,
- 0xfc410e56, 0xafb06c06, 0xfba278c2, 0x46dad206, 0x92ebd023, 0xe52d2c65,
- 0x9a4bd5e7, 0x4b3fb8dc, 0xc478b3d6, 0x4ca9b165, 0x257a733e, 0xf8c1e886,
- 0x7b4dbade, 0x5c1ff08f, 0x7d6d9e7e, 0x4bf40f6a, 0x80fbebe9, 0x9eda9b8f,
- 0x55c30758, 0x46ecf5e8, 0x4594e119, 0x3df3cf6b, 0xb8cfccb1, 0xf7a330fd,
- 0x5ce51bc9, 0xb26c4f78, 0xbfc1d897, 0x4dc6d6fd, 0xb7eff022, 0xd9539e80,
- 0x7b79073e, 0x3163df66, 0xd6f907df, 0x47e02069, 0x652466df, 0x62fb545b,
- 0x343786ef, 0xb9bcb7fb, 0xebfa3a6e, 0xe005e23b, 0x55becaf3, 0xe8cdbef0,
- 0xfff70dbc, 0x9ffdba9d, 0xc2b7dacf, 0x4f7ad0ba, 0xd4fffdf1, 0xe9ffba34,
- 0x718db8a7, 0x66d9c002, 0xdccefc8c, 0xfe90df4b, 0xa3b57c42, 0x297d5f07,
- 0x6c1ff996, 0xeaffb4e9, 0xffa12e3b, 0x4e3e3421, 0x2be54f37, 0x002a9374,
- 0x0ae91bfe, 0x517c008e, 0x533d02bc, 0xccfe7a3d, 0x0795dc0c, 0xe1ff3c24,
- 0x2e3c4be7, 0x6a947704, 0x99f986bf, 0x6fdd6fb2, 0xf2b238c0, 0x9e82576b,
- 0x45e8509f, 0xb82b3cfa, 0x7953c787, 0x71f61676, 0x8eb07e04, 0xec8ae3e3,
- 0xff7debee, 0x65cf40c1, 0xf98462d4, 0x1d82f590, 0x772945d6, 0xbdef67ac,
- 0x94f0e61e, 0x2dbf87ef, 0xde3d83be, 0xf0cc3d21, 0x5c42341d, 0x931f28eb,
- 0xc5c84463, 0xb70c40fd, 0xb67d860f, 0xfbafca84, 0xacebf255, 0xaa7488dc,
- 0xce23e1e0, 0xb1c4aeb7, 0xc7ce3f79, 0x5d1f07e9, 0x82ff0aa2, 0x3f6c0924,
- 0xe7db028b, 0xbb3fc022, 0x90dba6ef, 0x4c88efde, 0xb7b076ef, 0x47efe1e2,
- 0x8cfa406d, 0x7bc7669b, 0xce494f2f, 0x7e8d38a8, 0xef74c3e4, 0xced067a6,
- 0xfd85fa03, 0x97fd1bde, 0x0893fd01, 0x74a3ef74, 0x853f5aaf, 0xfc5d280e,
- 0x7ca5f01d, 0x7285d3d7, 0x65e0a90e, 0x731cee9b, 0xe9e19daa, 0x8d5200ff,
- 0x8000b56e, 0x00008000, 0x00088b1f, 0x00000000, 0x7dbdff00, 0xd5547c09,
- 0xf37df8d5, 0x3332c966, 0xb2764c99, 0xa00c4930, 0x80490e2c, 0x084ed8b0,
- 0xc3884a20, 0x93a0d752, 0x364b0900, 0x94569510, 0x8b062081, 0xb62d1518,
- 0xef858320, 0x106d1b43, 0x268358a8, 0x622d1110, 0xa57fb1dc, 0x41459041,
- 0xed1fa822, 0xe73bf587, 0x33337bdc, 0x6a02266f, 0xefc7e1ff, 0xdf77dee6,
- 0xcf7ece5d, 0x6ec5f739, 0x843631d3, 0xae630731, 0x7d8c01e6, 0xf4bf3f8f,
- 0xa12d8c97, 0xcf3773e7, 0x8224715e, 0xf0f7cfd1, 0x5e79babf, 0xc776bd50,
- 0xe91c57af, 0xc5cfafe7, 0xffe0525f, 0x8967a671, 0x47f1558c, 0x89ef4cac,
- 0xfbc025b5, 0x6cd69d11, 0xe266b498, 0x03846319, 0x8319789f, 0x1c636ff6,
- 0x6faa3e54, 0x1f2bd3de, 0xe9cc31ca, 0x9b39a685, 0x998f1533, 0x1b3605b1,
- 0x27f967ad, 0xb0dd93d3, 0xc6c646de, 0xc59bbae3, 0xd9dd727c, 0x99c68536,
- 0x8f7329e0, 0x66678389, 0xa07b9e4f, 0x6607f9ff, 0x886d964f, 0x70a13ebf,
- 0x4018eabe, 0x7ec48c4b, 0x0c985563, 0xc9bf9fe6, 0x326533e4, 0xc49f05b6,
- 0xa3db2ac3, 0xfd329b7c, 0xccf4d9ef, 0x9633b7a5, 0x75a4cb6b, 0xb15aeac1,
- 0x646858ee, 0xdfbcc197, 0x9bb59666, 0x1dd5d1e1, 0xb081e2de, 0xef462d8f,
- 0x389989d4, 0x1c1af398, 0x9d629aff, 0x6a5801ed, 0x38a6cbac, 0x6992d007,
- 0xcf8fb65e, 0xeced9793, 0xeea1b2cf, 0x2db9e670, 0xf8128d8c, 0xc930ad62,
- 0x421c3f70, 0xd9e1c6f1, 0x20175e13, 0x1750867c, 0xd5e27e7a, 0x667d1ba8,
- 0x0144f3ff, 0x78632fbf, 0xd3c1adf9, 0x1d0e66db, 0x553e6027, 0xcacc6649,
- 0x5c554b3c, 0xdb6628ff, 0x773ff0e4, 0x1c2e628c, 0x57189a7f, 0x8ffacbb6,
- 0x10aeafa6, 0x78869afa, 0x22e88ead, 0xd053eaba, 0xbcc07469, 0x8bdd194c,
- 0xee98fac1, 0x80ac5eda, 0xbd71eaba, 0x29554800, 0xf6c7ebe0, 0xd7338d84,
- 0x01d99e23, 0x0cc9cb13, 0xcdb567dd, 0xd1b6e1c0, 0xe866fa30, 0xb865e097,
- 0x838bc003, 0xde3585e3, 0xdc6bf88a, 0xd7886268, 0xdc39636f, 0x68d953ac,
- 0x42b7f403, 0xc6f7247f, 0x57039ea9, 0xd931bd41, 0x9e6050e8, 0xc22e8613,
- 0xa0ab89fb, 0xadc3e88d, 0xbc4fbe20, 0xdf9ae23a, 0xa277bb40, 0x8bc0e58e,
- 0x05b08d5b, 0xa7bfc3a4, 0x482936f9, 0x27c42da7, 0xc1b2c7f3, 0xbede7826,
- 0xd5d11869, 0x052ce2ac, 0xe6ce76e9, 0xdb9f0558, 0x2a74d8c7, 0xd863eff3,
- 0x13e89542, 0x16dea0f8, 0xde618f80, 0xd5e1153a, 0x6c93ce3b, 0x11ec6588,
- 0x23e335db, 0x32ce81d2, 0xcc1b2459, 0x5f5043d8, 0xb46b7009, 0x4b1614bb,
- 0x0a7306f5, 0x236321f1, 0x0cadae08, 0xd518d4f0, 0x6045775d, 0x7f5e2cff,
- 0x86eaf1a4, 0x9ec63486, 0x22357189, 0xbb303e9e, 0x87f9c11f, 0x44a9d526,
- 0x7fae82e7, 0x127ece80, 0x2c2ed4bd, 0xe0f38762, 0x0e660ef7, 0x47901ba4,
- 0xf8066eb7, 0x9b3de895, 0xbd355d70, 0xc38e3e8e, 0x657cb6d5, 0x7ba184f4,
- 0x21788eb9, 0x8cc7d817, 0xaeef11f0, 0x7ecdcb53, 0x66c5b3b9, 0x52ed4c17,
- 0xfcfc5b26, 0x79eb7286, 0x593b9733, 0x98229a50, 0x7ec762d7, 0xac23a23e,
- 0xe5fae4c7, 0xdd62cad1, 0x3e185f78, 0xeb890d7e, 0xaccf9467, 0xf2ff7fe5,
- 0x1fd0a19b, 0x9f89577f, 0xc4fce35e, 0xc5a3f5e5, 0x3c22269f, 0xbdf09390,
- 0xeb1cc5db, 0xeadf3a97, 0x5fb9748b, 0x3ea09b65, 0x2af464d8, 0xe66db831,
- 0xf18a25b0, 0x945b0d90, 0xa820cb56, 0x2e614bff, 0x7fe9c3c0, 0xbfae54a9,
- 0x133e3dd7, 0xa1d9afde, 0x7e852e73, 0xf10a2d35, 0xf337b383, 0x371d0045,
- 0x31075947, 0xb770af18, 0xf68065d9, 0xc9044ad3, 0xd7009c65, 0x2feb9061,
- 0x8268cae8, 0xc02df5e7, 0x5d3d507f, 0xf5c6a808, 0x6c319dea, 0x83be1f80,
- 0x1fb47cde, 0x1bda00ec, 0x4f67c89d, 0x9ff1f245, 0x81f0cc8a, 0xbe528310,
- 0x4a0188e7, 0x6e825961, 0x62c67af4, 0x78504f00, 0x30b51cb1, 0x3c07a5db,
- 0x35e67a2b, 0x7546be00, 0x9f08aab5, 0x8e872eac, 0xe9f3fd99, 0x3bed18bb,
- 0x39d0ef4b, 0xd6d5f403, 0x7aabcfbd, 0x31d0eb80, 0x942af58d, 0x6f9e3189,
- 0x4623de10, 0x7b63d5d5, 0xf557b15c, 0xa57cff40, 0xe905b76e, 0x44e61aec,
- 0x24f92ab9, 0xc1b593ae, 0x81ec5972, 0xda15974e, 0xb5771c47, 0xc7fd800d,
- 0xe38299b8, 0x7c0dfd49, 0x0e9162c6, 0x44ca5de3, 0x3fe86718, 0x8e47c118,
- 0x68ef75b3, 0xbe3ef905, 0x18e28c63, 0x6be74a10, 0x38b7e398, 0xce9f77ae,
- 0x3475f889, 0x9406d733, 0x62ba7f13, 0xf64bc20c, 0xf5cb1def, 0xa78f48ca,
- 0xee154408, 0x1de70627, 0xb76fa37e, 0x6c33d601, 0xd1b77796, 0xd99fb011,
- 0xed4bc68c, 0x523ed2f4, 0xb10a780e, 0xd2c6b6cc, 0xb78e2338, 0x7e800db6,
- 0x1fb07549, 0x78ef4f68, 0xa6b8414f, 0x882875d7, 0x777badcf, 0x3ad37ad1,
- 0xf82979da, 0x176179eb, 0x5603db74, 0xdb23ed1d, 0xf2cdf5ca, 0x666f5c53,
- 0xadb27ac7, 0x2c7dfe09, 0xd724f42f, 0xf66bf8c1, 0x17ef7566, 0x2895eee5,
- 0x52e403e4, 0xc691ac6e, 0xe9eacbb9, 0xbdabfb8f, 0xd20f73b1, 0xdf7bf3e0,
- 0xb47f12b1, 0x137e13c4, 0xf84a7df7, 0xba485c48, 0x37d9ad98, 0xb179415f,
- 0xa67014a6, 0xca59c284, 0x7eb8358d, 0xf45b1fa2, 0x27cfa024, 0xd8829eed,
- 0xcca57b40, 0x20159d1e, 0x8f7be497, 0x19ee662f, 0xed6190b0, 0x16595be5,
- 0xb17ef7c9, 0xc27df201, 0x9122fbc0, 0x2e2c9a9e, 0x569fb617, 0xcf388dd8,
- 0xfb425833, 0x975e0633, 0xe0407af0, 0x52763b33, 0x870875b6, 0xf8e80d93,
- 0x4fde4899, 0x8dee8f2b, 0x83bb09d5, 0xe0eb0bd3, 0x08fb82f4, 0xc666bfb4,
- 0x748c3c72, 0x9cf48a79, 0xfee2a64e, 0x76f81786, 0x1b0edd23, 0xf48dddef,
- 0x9d04ce9f, 0xa274e78c, 0x63dbf7a5, 0x711d7cb9, 0xdc218bbc, 0x0ee615f3,
- 0xc654ef67, 0xbe29bb72, 0x0fd13463, 0xce1943f0, 0x4eb53437, 0x66dca035,
- 0x7fa809b6, 0xa0eb137e, 0xae05797e, 0x366f48dd, 0x79f89b97, 0xe9c6d9be,
- 0x07d39326, 0x1c273fbc, 0x3e436d3f, 0xa3e7e01a, 0x7347a478, 0x26de3d28,
- 0x011bf4e0, 0x3df1d0df, 0xf1f8e177, 0x02973a1d, 0x603b0c83, 0x3ae831f6,
- 0x49e8016c, 0xf40653e4, 0xcfb40b0f, 0x9f2215b2, 0x153956a5, 0xb302ebc4,
- 0xd7dc1efb, 0xf98d9472, 0x5f3acf48, 0x6c97bc3d, 0x7efe1173, 0x67689eb4,
- 0x90686c11, 0x2c40f59d, 0x9557e3b7, 0xfa7ebca1, 0x53ca235b, 0xbdbfe487,
- 0x01e5d1b9, 0x50c7f1f4, 0x0e123f7c, 0xa7395adf, 0x2e5fb7c5, 0x8039cb04,
- 0x0f8e5ad7, 0x77c7e76e, 0x7cb9502c, 0x3d6b9608, 0x3e4423e1, 0xc1fc3c08,
- 0xeb84daec, 0x4045c6cc, 0xfacd1de9, 0xfa4f7b61, 0xf358c5f8, 0x2f67b34f,
- 0x8c5f8fac, 0xc7d5084d, 0xd7ae88ba, 0x75478015, 0x6150ea8b, 0xec8bf50b,
- 0xfaffc42e, 0x7689c566, 0x9516eee1, 0xf2fd61e8, 0x729bd228, 0x8f6e5fbd,
- 0x84aec419, 0x6b3ff052, 0x5a7d258f, 0x5fe62b1b, 0xfcc0bf06, 0xbabc6da7,
- 0x3d79e6dd, 0x6fad0e50, 0xe11226f9, 0x71593fdc, 0x4abb411d, 0x85818fab,
- 0x84df7814, 0xd70829bf, 0x322a0dc1, 0xad9ef5d6, 0xf6f09526, 0x8c378e2e,
- 0x0a33be75, 0xa6a7f5d6, 0x7b40bad1, 0xaf8eeceb, 0xeb05dd6f, 0xfae68daf,
- 0xeb9a36b9, 0xcebbd3e7, 0xbb7a41f7, 0x9274e176, 0x9ef4c37b, 0xdce5038f,
- 0x730efd1b, 0x6d4acc39, 0xd4e3fb47, 0x68fbe52e, 0xa235a100, 0x0aed1e9f,
- 0x06a9ca35, 0x1c4415db, 0x1f0039f5, 0x145b5f84, 0x073eafc1, 0xd6932ef8,
- 0xd9d70279, 0x14b2316e, 0xfc0b3f68, 0xbae4fd88, 0xcf7ac47f, 0x9a6f5f84,
- 0xa0b468ed, 0xbebfd50b, 0x1e20bc6e, 0xa2d57c60, 0x669c7da7, 0x67c44e51,
- 0x10c5d1b3, 0xc283deff, 0xab78103e, 0xba773411, 0x0f01c865, 0x81fd6fec,
- 0x7fbe2734, 0x48d9c77a, 0x47ed199d, 0x7d876a8f, 0x565de9a9, 0x5bbb87d4,
- 0x39de5ece, 0xc19be480, 0xbb3beb0e, 0x33ddb0ef, 0xcfed47e0, 0xfd88bf6a,
- 0x0dcdead5, 0xaa227681, 0x1a945259, 0xda5a523a, 0x220ca9fe, 0x0f2863fe,
- 0x57cc19bd, 0x3e5efb0f, 0x54d3d050, 0xd7be40e6, 0xcdbb7be2, 0xe00f619d,
- 0xb736cddb, 0xf385d703, 0x3ed2e6a4, 0xe83eb0b3, 0x0679e9cd, 0x0c6fee1d,
- 0xed29bd43, 0xb44fb93d, 0xfd7323c7, 0x5ef693fb, 0xce73fef7, 0x68c7da0f,
- 0x74ec83df, 0xc52c740e, 0x282d5a73, 0x03320785, 0x784adff7, 0xacfb16a9,
- 0xaab7308e, 0xcdb62fb0, 0xca53b270, 0x7dd0ac83, 0xf3869e00, 0x780f387d,
- 0x377fcf10, 0x4e11eb3b, 0xda1b0efa, 0x91afb0af, 0x50560fb8, 0xf8708c96,
- 0x8c9aecc0, 0x2599fef2, 0xf4fae88c, 0x14f7ccb3, 0xbb4b7a6c, 0x0366e88e,
- 0xffe882bb, 0x5b99dd0a, 0xebe266dd, 0x7e7ef8b1, 0xe50ea347, 0xa1cf8e6f,
- 0x797ab943, 0x474eb347, 0x2f19e0f4, 0x0f5674e0, 0x54dfebeb, 0xba48fea7,
- 0x2e9e1498, 0xabf6f042, 0xb849bc40, 0x30f4128d, 0x3286e10a, 0xb27f4bb9,
- 0x370fc233, 0xb54b0bc0, 0x58c78e87, 0xa9c20667, 0x7d63c5ed, 0x9abc613a,
- 0x8add8f97, 0xabf9a970, 0xcc618889, 0x418f2f5f, 0x30b2ffba, 0x72735dbc,
- 0x0f5b9d71, 0x3dab78c4, 0x157be48b, 0xbda230eb, 0xaddd7200, 0xd2eb900f,
- 0xe867db8e, 0xf7f1c628, 0x12d9510d, 0xe759f380, 0x461624b0, 0x3f72c85f,
- 0x00396dda, 0xe155f47f, 0xfcc5e4f9, 0xda476e18, 0xb25afc83, 0x9678b7dc,
- 0xe7a18c7b, 0x8e0df6f1, 0xb14e7f24, 0xc87a1ec6, 0xa78dedce, 0x81cf5ced,
- 0x3ae17660, 0xe2c5fd4f, 0xa9d342f3, 0x0cadf7dc, 0xdb6a74e0, 0xa05e79bb,
- 0xe3ac53a3, 0xdf9097f6, 0xb9d336be, 0xfbf078ae, 0x7e2c4b79, 0xfb8abcfe,
- 0x2f55d852, 0x407569bc, 0xbb2de2ff, 0xf001bde3, 0xbfe98abb, 0x4ceba6ee,
- 0x8fef979c, 0x20fb3be9, 0x274bd83e, 0x16501d12, 0x3c6af8bf, 0x373803a7,
- 0x14ff450d, 0x633f8fe7, 0x5ddd8053, 0x3dc6b0bc, 0x1fc02f26, 0xf9922e73,
- 0x0efaeb02, 0xab891e23, 0xfda999cf, 0x9e25bb76, 0xd62f4de4, 0x8f4de50b,
- 0x7848baf0, 0x3c25db6a, 0x913e0df7, 0x97c5f681, 0x07c5d83d, 0xaf7ec1ec,
- 0xdc7b1637, 0xf5fc7263, 0xdea77dbf, 0x5ef30ee6, 0xacff188b, 0xda127873,
- 0xd6c6c57d, 0xe1f9c2cb, 0x0b5339e4, 0x57ce37a7, 0x7fb8e346, 0x1f1a6739,
- 0xeddb5d6e, 0x3fe69fba, 0x0aab07d8, 0xf44b0bb0, 0xdced379e, 0x326ab05f,
- 0x3f2e6bd4, 0xd9ce8e3b, 0xdc845e92, 0xdb798abb, 0xf4b57f90, 0xbefdf121,
- 0x4b2a5bc4, 0x693dbc45, 0x11ba7077, 0x43f920fc, 0x396d470b, 0xe13cc8c1,
- 0x75cf03ce, 0x799235c3, 0xbede1e41, 0xfe7a40c1, 0x4e1ff3cd, 0x3f7a03cd,
- 0x5b60d6b6, 0x5ace530a, 0x51ed3bb7, 0x360da7f4, 0x1fa814d9, 0x865eb473,
- 0x4eb95f7c, 0x1c3d2375, 0xe27b7b5b, 0x00bf2874, 0x7582adfe, 0x50306e54,
- 0x770dacfb, 0xc109fb50, 0x12eb95d7, 0x7cbca3fa, 0x4481fdb3, 0xeface3c4,
- 0xf11ebfee, 0xeb68c5b2, 0xaaca183f, 0x263dc526, 0x3673de00, 0xb7d50646,
- 0xdc2cd8e8, 0x532bc487, 0x1dcfdd3c, 0xdc631eb0, 0x6b63c44f, 0x18d51f88,
- 0x92ccedc7, 0x9aefb029, 0xbec96721, 0x8a27bddf, 0x662bc9f4, 0xd6c8ec95,
- 0xb7f3ffc1, 0xf45ea12b, 0x3649de9d, 0x58f3c09e, 0xce866781, 0x8a8fa040,
- 0x7a2f5e08, 0x68764f51, 0x78254591, 0x1d5c82b7, 0x65de4a43, 0x7efd0b1e,
- 0x4753df21, 0xfd0e1ead, 0x1818c6c6, 0xb45fa1ea, 0xa06629ce, 0x4e797f27,
- 0xc06769ff, 0x9733467e, 0x42e2ed1e, 0x5f6a0866, 0x0a7d6511, 0x4c185aed,
- 0x28b0fa8f, 0xd8f9f822, 0x813daecb, 0x5b58c4f6, 0xbfa4bb70, 0xbfa0389c,
- 0xb1b97efe, 0x8fe7cf7b, 0x567d804c, 0x9ec953ec, 0xde5c90be, 0x41cafb8f,
- 0xda51bf7c, 0x29bdef04, 0xf9e6f3a0, 0x9052cb63, 0x86140abe, 0xe763ae7e,
- 0x5ce5f3c3, 0x018c9f41, 0xf1f9fb9e, 0xbb39d13c, 0x7f6c8ebb, 0xeebcc15d,
- 0xe2ffae3a, 0xcb0fd9e5, 0xf73b4eab, 0x87f5686f, 0x53fe7f96, 0xf078a3fa,
- 0x0b5e19ab, 0xe585ff95, 0xfe5c2dc9, 0x5685e56a, 0x6975c85f, 0x4e7d5bd7,
- 0xcf13d20d, 0xd7e27909, 0xfe7a4617, 0x6b8f9e33, 0x9e8486e2, 0x219ec18f,
- 0xea877978, 0x760e5ce9, 0x6fd8edd7, 0x5711d980, 0x665a4b08, 0xb9468acb,
- 0xdcf164d6, 0x97e01719, 0xa8d4dfea, 0xedd1f943, 0xfb0431af, 0xf5f9e46d,
- 0xffbe389e, 0x875e38f2, 0xfb9d2bf3, 0x92794437, 0x2f6f38f5, 0x7e3033a3,
- 0x85fbcb25, 0xaf7690fc, 0x9da577b4, 0x7d59ed2b, 0xb367b703, 0x7e41dd63,
- 0x5fafd633, 0xed183f90, 0xef73e474, 0xe7da28ae, 0x107b8a67, 0x731569f2,
- 0xa017143d, 0x7c0deb07, 0xbcf5dafd, 0x13ec2716, 0x413b26e6, 0x1d1ccfb6,
- 0x8d6f9e5e, 0xc2ff53d3, 0x40ca6fc7, 0xb6b3ee3b, 0xce50339b, 0xfff1a67e,
- 0x0f0fc4f6, 0x507d7e0b, 0xe15893e8, 0xf9087827, 0xedc0ea08, 0xfef02dae,
- 0xe26ec58a, 0xbe2edfab, 0x1747ca91, 0x8fe7a42f, 0xfcd265c5, 0xdc77c2b6,
- 0x23a700d9, 0x17d2552b, 0x3eee8d33, 0x91def0b1, 0x1bf91d08, 0xc799d70e,
- 0x3b63336f, 0xcce5f3a3, 0xf26c27c7, 0x1f01f806, 0xe90c7dc3, 0x09af9f79,
- 0x9d2a5ebc, 0x2b4eb356, 0x7a6eadea, 0xb7a2103d, 0xa72f11db, 0xf6226759,
- 0xfa3a55ab, 0xf3a12934, 0xaf5cc83f, 0x2366bf61, 0xd37c8feb, 0x92f5c51c,
- 0x029bdfb6, 0x9ed0ab7f, 0xd433f285, 0xcce4615f, 0x7b5e823b, 0xc4ef5d5b,
- 0x9333bc91, 0x56eb4edd, 0x3ef44e29, 0xb4e707ce, 0xc639f10f, 0x975fd089,
- 0xc775b56d, 0xc779f855, 0x185c71fd, 0xfe4f5c7f, 0xee3aed1f, 0xd570e789,
- 0x296485fa, 0xc4c742fd, 0xd9c5167e, 0xe844fc82, 0x0fe70f0f, 0x48de3aba,
- 0xd510dbfb, 0xa8b8c5e9, 0x3e7e66f7, 0x55e51a4f, 0x5a95dfd0, 0xfe8858dc,
- 0x71c67fb0, 0xbc7da63f, 0xf1cf1927, 0x4e8d92bd, 0x2c5ce3f4, 0x76680e3f,
- 0x478138f1, 0xd358eb47, 0x03ec8de1, 0xf0ec4aeb, 0x34a11a14, 0xf8d226c4,
- 0x096eac49, 0x11fa0de2, 0xa3dbf230, 0x743c8a7c, 0x213c9743, 0x91a56147,
- 0xaddb77c8, 0xbc3c531e, 0x5d467437, 0x53edfa3d, 0xe23c78ab, 0x6de9e284,
- 0x1b8d0ecf, 0x5e3932cb, 0xbb88aff0, 0xd0346fe6, 0x3e37f2ba, 0xfcd1f146,
- 0x95eb578d, 0x1f943900, 0x27fea06f, 0x9bd39d5e, 0x851f18fc, 0x880ebf8f,
- 0x4662f4e7, 0x8a10e11f, 0xbfa58687, 0x313ff17e, 0xf609dcae, 0xef3cb050,
- 0x20243f17, 0x0cfaa16f, 0x3c7d73c9, 0xc07f23d7, 0xd358057c, 0x7cc8661f,
- 0x8fe40d85, 0xbe6c6add, 0xde51e306, 0xbc431d1a, 0x2bf9efb7, 0xcd676bc5,
- 0xb6bc5070, 0xcf7dfdfb, 0x3ff6c72c, 0x118362cc, 0x87be29fe, 0x7ccff415,
- 0xc9e3c91b, 0xb1326edf, 0xd9a5b025, 0x3c53376f, 0x8e954d78, 0xeed17ca1,
- 0xe832661b, 0xa0db5c78, 0x47f8e02b, 0x0ef12839, 0x7c446404, 0xfc21bc48,
- 0x6e3198b6, 0x5fad02fc, 0x7e80cbae, 0xc7dc04f0, 0x4e906b96, 0x15d9557a,
- 0x75c817f4, 0x4c9f485d, 0xfa69ff8a, 0xc3d467e4, 0x9c5fc5b7, 0x74819e1e,
- 0x5ac3d5ae, 0x7164dbfd, 0x0bbf6255, 0x4213e1e9, 0xd7894dfe, 0x7e3043c4,
- 0xc76f0616, 0xf00c1c84, 0xff19df8f, 0x1fe3fc23, 0xe3091ca1, 0xc8c67f1f,
- 0x9da36fe5, 0x0c2936dd, 0xe627bcbf, 0x32eeadd7, 0x6f8cfea2, 0xb3cac251,
- 0xc651ab6c, 0xfae05713, 0x2b44fc64, 0xb7c0c38f, 0xde5ffb11, 0x7b0bbad4,
- 0x165ec6e5, 0x15dbe68d, 0x37b9c3df, 0x046b3ccc, 0x30163b9f, 0xea3aa38a,
- 0xa82bc918, 0xb093b8fb, 0x0023f295, 0xb8e04f1f, 0x9d638a17, 0x1d9215b6,
- 0x8656e324, 0xf8f3e0d8, 0xcfd9789e, 0x6fc447f5, 0xe27a0f7a, 0xb05d624f,
- 0x5fb067ff, 0x141602fc, 0x9971919f, 0x62af3af8, 0xc47547cc, 0x3bdadfc8,
- 0xf304b3ce, 0x3386ba3f, 0x8f5053e7, 0xa215b529, 0x72cfb53c, 0x66fc61b6,
- 0x9fee29f9, 0xf98f3e5f, 0x79012a96, 0xca2c9e05, 0x05bc4203, 0x0a7607fa,
- 0xac53b6f9, 0x5fe4f41b, 0x5abaf9e3, 0xa4f403e2, 0x756e87c4, 0xed784aab,
- 0x02a7af0a, 0x43fedaf0, 0xf919fd78, 0xe48b9df2, 0x852f0fcb, 0x9171fe6e,
- 0x8c4bf374, 0x3b090c6f, 0x578867df, 0x67407ced, 0xbef88347, 0x78db3a07,
- 0xf9d2f189, 0xa7a89fe6, 0x5dfae142, 0x5c28427c, 0xfaeb1657, 0x5166bc91,
- 0xd57a70ce, 0x4ffe6096, 0x12d891e7, 0x1e7a5c86, 0x3b7bfac9, 0x1967888d,
- 0xd5eb9107, 0xf6c88fe6, 0x0f25169a, 0xbb859fcf, 0xe039d3cf, 0xe8bfdb74,
- 0x079a101c, 0x0f9de7c2, 0x39fc8de4, 0xdcd01d56, 0xa677fc0a, 0x752748c9,
- 0x377e3995, 0x7bf7fd0a, 0xa0e7cc0d, 0xffd811fe, 0x5ffbc60a, 0x03bcb4d1,
- 0x305757fd, 0x479c57bd, 0x1db9ef95, 0x7c7c8315, 0xf2955ec5, 0xfe66d8bf,
- 0x2c458ebc, 0x4c74ff41, 0x02398e81, 0x8aeb19e0, 0x78008e62, 0x07b78dc6,
- 0x7939e5d5, 0xc13798ae, 0xfde82bdd, 0x82b31ba4, 0xae78a7fa, 0x3a9e7a08,
- 0x9ea8372b, 0xa822375e, 0xa385ef7f, 0xde99ea83, 0x67fa836b, 0xaa0e4c37,
- 0x1cde34e7, 0xab18ffd4, 0xec147c7b, 0x5bfa3fb3, 0xebcc3f00, 0xd60cb8ea,
- 0xb7ac433b, 0xa0f29aef, 0x5afd81f7, 0x53381e31, 0xcf17c990, 0x00abdf8d,
- 0xff08671c, 0x39bee5ce, 0x55cfe341, 0x677e88ab, 0x048e1a36, 0xacf469fa,
- 0xc02a4f6b, 0x38a7c6b9, 0xb95ea15b, 0xecf9f826, 0xbde81b1d, 0xf6e0bed9,
- 0xeb839bb9, 0xd29cde83, 0xb901e79f, 0x4672bf29, 0x87dfb042, 0x9989d085,
- 0xb599f4e4, 0x7aa5ffdc, 0x24e86afb, 0x27ec5f18, 0xd0438dd2, 0x9839298d,
- 0xc11d226e, 0xfaf95374, 0x0708a1d6, 0xfba3fc2d, 0x0bc9e869, 0xfe007eff,
- 0x7d306716, 0xfb4ee169, 0xec567583, 0x95efd850, 0x6acfb850, 0x2a797879,
- 0x633b850b, 0x1fd7233e, 0x688fedc1, 0xd981fde0, 0x89ca18f3, 0xa8163bb3,
- 0xe3638718, 0xecff3c79, 0xed07af8e, 0x2f898473, 0x97c484e5, 0xf80425d6,
- 0xe97c647f, 0xaf19c634, 0x67111764, 0x844ffddc, 0x8f00c807, 0x0b11f301,
- 0x71dd119c, 0x3c7f48c5, 0x653f2b49, 0xb9e3fa09, 0xfe2bd204, 0xbc3d6c78,
- 0x03e6343d, 0xc653ae37, 0x8ebe64e5, 0x930a2bcc, 0x8497fc9f, 0xb40fcc04,
- 0x75f9e347, 0x3a7cfb4b, 0x22bcc977, 0xc302f226, 0x4fa4ffd8, 0x14d7f19a,
- 0x26760bb2, 0x0afebd70, 0x176dd78e, 0xa92fbc88, 0x471a7bd7, 0x2a7adfc6,
- 0xc52a5d95, 0x2894bb13, 0xf46153e7, 0x3f0947ca, 0xe685bf51, 0xa8147f8f,
- 0x38ee6a47, 0x0bf507bb, 0x6c63fdc0, 0x6f4058b7, 0xfdbd7e2b, 0xd12b68bb,
- 0xaaebd76b, 0x9c342faf, 0xd8c47089, 0x222d8e01, 0xe445afdf, 0xd6f5c9fb,
- 0xf4baa445, 0x9c1ed879, 0x8ae327ff, 0xc28dfdda, 0x3afe71fe, 0x976417bc,
- 0x76e5cf2c, 0x870169db, 0x276e160d, 0x9db91318, 0x1f39ab50, 0xfb7036d5,
- 0xacd7a40c, 0x8c718096, 0xdfea1689, 0x4c685cdf, 0xdf8471c4, 0x42a67965,
- 0x4572c576, 0x77e47b21, 0xfcf4d1b6, 0x868509cf, 0x6fffe844, 0x6011af31,
- 0x16636588, 0x93438f5f, 0xe892fe17, 0x68c252ff, 0x36898d2a, 0x5db67fe1,
- 0x6a91f481, 0x5da91976, 0x8aa71f0d, 0x1afbe44e, 0xb464f229, 0x42718071,
- 0xdfdfa26e, 0xe2d2edc4, 0xfe4189b1, 0xf18cf7fe, 0xd0afdfc2, 0x53942eeb,
- 0xef7814bf, 0xeaefffc9, 0xf1476b67, 0xaffff5ad, 0x7ffee48c, 0xf1081f19,
- 0x85c73bff, 0x1e23fff5, 0xfe7eeda2, 0x2dd893e9, 0x3e50d29f, 0xea7a30ed,
- 0xb5d5fcf1, 0x6878ec1d, 0xa4ebe7ee, 0x7dc0c0b8, 0x673c4ed9, 0xbb64cf2d,
- 0x4b6f482c, 0x7f3b4318, 0x696ea747, 0xe95f3c24, 0x3e7c3665, 0xbf3f2d7c,
- 0x3871ae55, 0x0e529b71, 0xfdc89d5c, 0x1f380687, 0xbdf1725b, 0x27186dc9,
- 0xd9953958, 0xb2350d51, 0xda2b22c6, 0xd8596b45, 0x4168e3f3, 0x770a134f,
- 0x4276fe51, 0x0fb7cf17, 0x7693a7ed, 0x73e2217e, 0x2ce79758, 0x7971cf8f,
- 0xcf112242, 0x5f3aeda9, 0xb27d73b8, 0xa46ae8ad, 0xf0be81af, 0xc29188e7,
- 0xbb32e64f, 0x03f8e227, 0xd87cf1b7, 0x677f294a, 0xf01e98e8, 0x75e0453e,
- 0xd79e5aca, 0xff7fcec1, 0x45ed2abd, 0x9433e346, 0x2d53952b, 0x5513f43e,
- 0x697a64b6, 0x99c56e5d, 0xe5a2f283, 0x2bd6376d, 0xe86df3f3, 0x9dfd7097,
- 0x91fb4729, 0xfcb8c9a9, 0x52a3b3d2, 0x8f1e909e, 0x64d438a7, 0xf1236f41,
- 0x72409cb0, 0xc034657e, 0x92ed72bb, 0xf3d7985d, 0xc5191ffe, 0x5da80e9b,
- 0x5fb07143, 0xe6167001, 0xa567a962, 0xa648b7e4, 0x718aa671, 0x7982ffbc,
- 0xfef3fc23, 0xda75e5aa, 0xf30301cf, 0x9d1d0046, 0x038379de, 0x09e5eeed,
- 0x93cfe411, 0xaa83da71, 0x42523ee7, 0x5c1aaefa, 0xd12d4dda, 0x9c83f436,
- 0x3a61f9de, 0xb93e4dc6, 0xed05ace7, 0xbbe87fd8, 0x7c2f982c, 0x16bbd17c,
- 0x93f1c017, 0x9de52a45, 0x86f42add, 0x897dfb84, 0x271fee1c, 0xdc2117ba,
- 0xddfc5b6f, 0x2a3cc0d0, 0xe88130b6, 0xa54fb679, 0x9cb75c90, 0x168d1cdd,
- 0xbabd774a, 0x2ea82e39, 0x89b540f5, 0xbf3b85d5, 0x69e824bc, 0x6306d376,
- 0xf7e703aa, 0x38fa42ac, 0x7474e7ae, 0xe7c59b7c, 0xa7aff4cd, 0x11b069bc,
- 0xb47f83ed, 0xea2b5898, 0x81877d33, 0x8abb49e7, 0x8f0ba015, 0x9d76bfc0,
- 0xa68e5e7b, 0xc63e66f1, 0xcc1947e5, 0xebe010b5, 0x724d9969, 0x998fbb41,
- 0x25c6389f, 0xae675c01, 0xe3fa1850, 0xc022ffb0, 0xfde1679f, 0xa5fda15f,
- 0x379967dd, 0xf9480e58, 0x3cf02955, 0x79f821bd, 0x696fcb65, 0x43cc199c,
- 0x27602079, 0x735f9e69, 0xd80af50c, 0x67ed4147, 0x519b66f6, 0x14496f8f,
- 0x6ca1edf1, 0xfef0f7d8, 0x18ec88ae, 0x927e184f, 0x36c5c9e5, 0x17cfd622,
- 0x7c795047, 0x5172a331, 0xaae3a722, 0x44efb796, 0xc766a97b, 0x738e2316,
- 0x9681f1c9, 0x999bd613, 0xe896ef5f, 0x1e21af3d, 0x28252cd9, 0xe1b3504e,
- 0x32ec91ac, 0xd1529f01, 0x00f08a5e, 0x1cc2dc3c, 0x503cf1ab, 0xc7f0655a,
- 0x5bffe0e9, 0x60c3bf72, 0xd1da80bf, 0xb5173991, 0xb94fb95f, 0x5abcf96f,
- 0xf30c7a05, 0x4583e4be, 0xd8cd1f42, 0x2f796938, 0xcefd5100, 0xfc9d1963,
- 0x78f649bc, 0x516bc091, 0x8f64fdc4, 0xe3d88517, 0xb7dc3dec, 0xe64ac7a4,
- 0xa5a23d24, 0xcc07493b, 0x23f7a06c, 0x4ddebd84, 0x120f2d6f, 0xcc3d245c,
- 0xe4685d5c, 0xc8c79be6, 0xb26f4aed, 0xa326d7f0, 0x30e816bf, 0xba063ec8,
- 0xed6baa0b, 0x9d0d2ff1, 0xb41f2819, 0xe7ccb876, 0x60e7c2d4, 0x9a5fcf22,
- 0xb38d70e1, 0x8073c00d, 0x85f9397b, 0x10ca46f1, 0x3dc6dbe4, 0x6edf2377,
- 0x0ff37ce4, 0x92b30f41, 0xf049113c, 0x9af4b3dc, 0xe77fc41a, 0xf2065312,
- 0x8a6967b3, 0x3dfd0f1a, 0xc39214ab, 0x18a697a3, 0x97d3ce11, 0x7c871e0d,
- 0x345ccb9d, 0x1638b4fe, 0x9c186ed6, 0x7947e5c4, 0x6319819d, 0xf4462908,
- 0x506a9f0b, 0x9a8c2fc8, 0x6be02264, 0xf557c096, 0xa4adb78a, 0x6ff01caf,
- 0xe01f5e28, 0x2aeab33f, 0xee701f09, 0x52c7cb08, 0x66b154af, 0x3b8c0a63,
- 0xd11b6567, 0x82479c31, 0x95b2d7fa, 0x66eaaf84, 0xd5dd7b4d, 0xb9d83f84,
- 0xb589cf11, 0xf79f823b, 0x8276124f, 0xbe913993, 0x225a773d, 0xb471af30,
- 0x4ad94f80, 0x6b7286c5, 0x84b6b2fa, 0x7d3ea01b, 0xed84eaaf, 0x8587c374,
- 0x1f2823fa, 0x1cdecced, 0x719c57f2, 0x9fb09238, 0x52edcac7, 0x8619ef45,
- 0x3ce2d3ed, 0xd8cfd0c3, 0x618591f5, 0x73a1df7e, 0x11e4732a, 0xfca20f95,
- 0x341b1b2a, 0x2fbec029, 0x3112d833, 0xf365e91e, 0xb83dc593, 0xd4f84088,
- 0x7e24ac46, 0x887e45a8, 0x34c3f3f0, 0xdda17b8c, 0x7942a2f3, 0x30476c84,
- 0x34709fbd, 0x9091c226, 0x9033efb9, 0x8a6f2e9c, 0xf971f3a5, 0xea2322b2,
- 0xb16df2d5, 0xf9c11f64, 0x86cbbdf4, 0x6879f1fa, 0x649ede59, 0x39bcb718,
- 0xe306a9d3, 0x19dcf431, 0x0d39ceb0, 0x8efe2487, 0x23bf80f4, 0x7807f0e1,
- 0x4f2f6a0b, 0xe0497212, 0x238a2d8d, 0xef3a5abd, 0x58089cd5, 0x48ba99d7,
- 0xe9ec93ca, 0x8c66c47c, 0xe903fca0, 0xabdf1abf, 0x7944cfdb, 0x0e57673e,
- 0xf169fc21, 0xd3dffe36, 0xcbbda187, 0x68616efe, 0x66cb4d67, 0xf6864db7,
- 0x6fce14db, 0x19afead3, 0xddc4768f, 0xbd9e5c49, 0xd5d07205, 0x41b7b197,
- 0x0e40ba0e, 0x11f20bbe, 0x4e2fefeb, 0x8b87faa6, 0xb47e541d, 0x47951fb8,
- 0xf25fbf84, 0xd102101d, 0x2e2492ed, 0xc9249717, 0x6482faf8, 0xffc66934,
- 0x3a21ddfb, 0x6c67de1b, 0x9d36309b, 0xc15cebb1, 0xa9c6f7fa, 0xd3b5fac1,
- 0x8c971b60, 0x0a15dbe7, 0xeee5a3d9, 0xe1fd4191, 0x7bc464dc, 0x9e5fac2b,
- 0x86f49dbf, 0xe81938c3, 0xb8e2a6f1, 0x37d7fea0, 0x9fd506a4, 0xfad07248,
- 0x0ecf8d26, 0xb4b9bf6a, 0xecbd507f, 0xa431919c, 0xf1014777, 0x679102cf,
- 0x8e770704, 0xfbef1b17, 0xa4b0dd75, 0x5fbd60bb, 0x73d033ef, 0x5e243e2d,
- 0x9951ac67, 0xbe9bc607, 0x2c1fe406, 0x74e348f1, 0x0e2fafe2, 0xb25ce858,
- 0x7f6f29bc, 0x350fd401, 0xe80f2819, 0x55b8b2d0, 0x6a1daf68, 0x2832b04a,
- 0x6155cb3d, 0x2c8cd8d7, 0x2d15de40, 0xa6f9425b, 0x93933e65, 0xef7697ec,
- 0xc0eeb293, 0x122e2af3, 0xd53de4f9, 0xfe10aad7, 0x67df045c, 0xe15ee922,
- 0xf127b071, 0x4ef4e12a, 0x0ae3aebe, 0x13f5865b, 0xb9f71f91, 0x6a71d60b,
- 0x0e856362, 0xbeea15fd, 0xcf9f9204, 0xb6e90cab, 0xf2819e74, 0xafbf660c,
- 0x533ac06e, 0xbe395372, 0x66a3ca55, 0x7c6898cf, 0x021405d6, 0x6d3c16fd,
- 0xae01ea7a, 0xfb7d78ff, 0x8203df40, 0x8e8e913e, 0x2c5732c7, 0xf5a1562d,
- 0xc276fe7e, 0x87ee7c06, 0xee106fa7, 0xfdc1bd7b, 0xefe01266, 0x20df0af3,
- 0x128b6f92, 0x70b4af88, 0xf2e4623f, 0xa07c8bcb, 0x9fa6e5f8, 0x7e9296cf,
- 0x26706e98, 0xe56e493a, 0x3adca0a7, 0x7640d2b2, 0xacbbd330, 0x3e8f4893,
- 0xe72c744f, 0x8c77a239, 0x691df5c3, 0x5f9864c8, 0xa552be51, 0x1fd20af3,
- 0xe7e3efef, 0x0f5587d4, 0xdbcc24d8, 0x525878a0, 0x3edcdd28, 0x5de5186f,
- 0x596ded6a, 0xeabc097e, 0xe64bb009, 0x8179e4ec, 0x3f53bf2c, 0x3ee06075,
- 0x3cf9f196, 0x4af94105, 0x1daf5955, 0x2ec8eb34, 0xc273c18c, 0xa254f789,
- 0x8d5913b3, 0x9f019343, 0x86bb7527, 0x2ff505de, 0xea8f7a26, 0xda223ea1,
- 0xeb842ff3, 0x0ccadd5c, 0xfaf30b25, 0x091aaf0f, 0xacfe7def, 0x2e6c49c1,
- 0xcf39fcec, 0x43fdeecc, 0x1bd815f6, 0xe1ddb8bd, 0xcffbc14a, 0x1acd1d73,
- 0xc7c3807b, 0x00204981, 0x056adb17, 0x7876376d, 0x3c01e588, 0x31d74f57,
- 0xe079e04f, 0xb1e3c8b0, 0xa873f324, 0x24a61bb4, 0x5d333973, 0xbd9be9c7,
- 0x037a70ac, 0x0f502afb, 0x173db948, 0xbf55aaf3, 0xbb72901e, 0xfe52358a,
- 0xdb99238a, 0x1f15b32f, 0x9835ddd9, 0x2bfd0289, 0x56683c6c, 0xf3e4d9b5,
- 0xb698d265, 0x7a60fb40, 0x73279732, 0x8e3ecf8c, 0x3ac95be4, 0xfd353ef8,
- 0x2af8373e, 0xf543323a, 0xc36d854f, 0x6f8d3b32, 0xb79fa270, 0x756bf052,
- 0x256be2a3, 0x51eb853b, 0x299d57e9, 0x3f56a8f4, 0x8d25e885, 0xd1a99a3e,
- 0x5831acbb, 0xe97ac2cf, 0xaf5cb2de, 0x68ee9d76, 0x0e61c10b, 0x6ff50bac,
- 0xa7b7c785, 0x38add684, 0xeb21a301, 0x31ee64a9, 0x780fb8b1, 0x5d08eade,
- 0x215f769f, 0xd4fb15eb, 0xf9c2bbae, 0xbbe62b55, 0x04293554, 0x243eed2f,
- 0x9c76b43e, 0x97854bc4, 0x45a2b7c3, 0xd67e7c21, 0xf2321f6d, 0x61ba4b6f,
- 0xe02ff0cd, 0xb047497d, 0x6f9412af, 0x1e41ab95, 0xd3d28667, 0x456cd61c,
- 0xad61a9ba, 0xdf9053cb, 0x1faf9b5a, 0xb5867e8e, 0xa9f9d36f, 0xa39aded4,
- 0x7a50058b, 0xbf8e5773, 0x17e74fca, 0x5cfc278a, 0xe9ddc3f0, 0xe01e9fa5,
- 0xeaa37335, 0xd4141c8a, 0x7a3fe44f, 0xbcb38e09, 0x63fa235e, 0xe53f0967,
- 0xab59d685, 0x2e5ff7e7, 0xcf015eb8, 0x0fdd7b9f, 0x7764f727, 0x76173f85,
- 0x3d1a5bdb, 0xfb81b1ff, 0xfe7ca55b, 0xff22ef5a, 0x3b0bb42e, 0xe3c6ceac,
- 0x9eb91a7d, 0xbd724f9e, 0x3979e842, 0x5b35d1cf, 0x13305e29, 0xf68080ed,
- 0xa56f56cf, 0xd9f1a578, 0xcbb45699, 0xbe99ae8f, 0x8f52f30a, 0xbd274d36,
- 0xa97bf95f, 0x40c63df7, 0x4d68a27b, 0x907bfad9, 0x5247378e, 0xdda2b15c,
- 0x2045ce23, 0x639fa167, 0x6cab970d, 0x95b39735, 0x90071fa8, 0xfd8bec7e,
- 0xf4f0acee, 0x68087e45, 0xe779bd27, 0x779fcf74, 0xfe77b8c2, 0x25e9da29,
- 0x755ad850, 0x5adbcf64, 0xcf563f51, 0xde20f0ff, 0xe07b01d3, 0x7b4b5ffd,
- 0x0645aa00, 0xea325b4f, 0x54076121, 0x6c321bab, 0xbd083768, 0x7f801ff1,
- 0xe7f87844, 0x11cbfc12, 0xdbf101fe, 0x9c381b4f, 0x7fe06ba7, 0xcbc72578,
- 0x2b6ca6f2, 0x6d3f2f9e, 0xebbb26c8, 0x821ca6d3, 0x00078cff, 0x1f5fdcfe,
- 0x0035776c, 0x817cf1fc, 0x96f587f0, 0xfc043bb7, 0x0dfe1c9d, 0x256cee1c,
- 0xc084672f, 0x57f94bd9, 0xe4d1fe77, 0x78e23b44, 0x57d92b64, 0xaca8b7c7,
- 0x932ec03e, 0xac37d176, 0xdfb449f1, 0xf767fc24, 0xf28418e9, 0xd7e1f4a7,
- 0xd98788ac, 0x3150785b, 0x95ccfe04, 0xeec7f144, 0xa8edbbf9, 0xdd5f116f,
- 0xe245d476, 0x19b986a9, 0xd796c7e9, 0x4239e00e, 0x45bf7171, 0xb66fbc8d,
- 0x19bef823, 0xda9592e6, 0x8ce2c5d1, 0xa4f5c088, 0x79d3ef69, 0xbebdc618,
- 0xd6eaf9cd, 0x5de7c4f9, 0x25b97941, 0xfe80d5ac, 0xd0acd636, 0x05eaed3d,
- 0x8642d685, 0x5a3ab571, 0x09453387, 0x56aecbca, 0x564f6475, 0x447c4519,
- 0x892455e4, 0xdc29497e, 0x629c902f, 0x2474f2a3, 0xda707d23, 0x7de1f462,
- 0x255f382a, 0x9ddefce3, 0x41dbc226, 0x5fc0135c, 0x333f0a35, 0xb7a442a8,
- 0xd3a7185b, 0x297bcc5b, 0x972707ae, 0xa71fa875, 0xc939342d, 0xa18f8dce,
- 0x42cdd2f8, 0x5e62ddde, 0x313d46ee, 0x61746ccd, 0x317ae309, 0x1a30d7f9,
- 0x0df987a6, 0xef748cbd, 0xf3a234b0, 0xdf123c59, 0x8ef87c96, 0x95ea5808,
- 0x1fa38e60, 0xf6dd7e18, 0x5e285c7d, 0xf609f8fc, 0x8546d74b, 0x170c8bf7,
- 0x2e5c5070, 0x609b3ff2, 0xc75828ec, 0x6f0714a8, 0x3fb8d877, 0xc9e02d7a,
- 0xb6afc7e2, 0xfc79799d, 0xb1f30ab2, 0xbc58f7f9, 0x5d541f24, 0xc8cabd50,
- 0x62794f9f, 0x34eaf143, 0x8e61dec6, 0x2ab78881, 0xee782194, 0x61f18b2f,
- 0xf43aef7c, 0xd4b1db87, 0xd64cbd13, 0x978eaf33, 0x0e3b660d, 0x25e3fdc7,
- 0x2abf9e02, 0x0031ad60, 0x83d7d6f7, 0xb437f3fd, 0x02fb5aea, 0xb7d3af7c,
- 0xea7d21b6, 0x1b061c22, 0xaf1ee3cc, 0xa539e2e4, 0xadc5e96a, 0xa689e2b7,
- 0xa0a3d5e2, 0xacf9e3ae, 0xfee6bf5d, 0x59805b89, 0xeab76e11, 0xcb9abb59,
- 0x52e100e9, 0xa978776b, 0xe2853cdf, 0x202e3237, 0x86183ff1, 0x2de3c40f,
- 0x4e307d62, 0x37df1583, 0x7cd7c786, 0x8ccc2f81, 0x15cfb846, 0xf257377c,
- 0xbf30535b, 0x0478823d, 0x2ed0553e, 0x22ddb806, 0xe2f89eca, 0x476e14a1,
- 0xcfc2943f, 0xe25cf7ef, 0x95dccc7c, 0x82797941, 0x7c4daa5f, 0x75ff397c,
- 0xc5307ca2, 0xf5cbe34e, 0x8a7ebd00, 0x0240e8e3, 0x691ebd20, 0x68fb27ac,
- 0xc3880b16, 0x49fbfa65, 0x77ad0eba, 0xf7dd11cb, 0x66bb1a58, 0x5f95e820,
- 0x8e513a44, 0xce6c62de, 0xf68733a9, 0x52e67193, 0xefa061d6, 0x993f4903,
- 0x55633fd0, 0x9535e533, 0xf41efc2a, 0x578b42e9, 0xc7e27607, 0x067bbe22,
- 0xa79c46ec, 0xfca15634, 0x773169af, 0x975f2096, 0x2c7a8d5a, 0xdff1163f,
- 0x8d17595b, 0x2b2d89ff, 0xdf8606e6, 0xe631504d, 0xa4f80b07, 0xadfb05d8,
- 0xebc3f947, 0xe4695d2b, 0x4ff5128d, 0x665c61f7, 0x03a079ea, 0x762e1faa,
- 0x5fa7bcc1, 0x91d9cf15, 0xfa7e7c62, 0xdecf413e, 0xe9de34e3, 0x53f3e4c7,
- 0xf90af9fc, 0x7f5e2bfc, 0xea2f8e50, 0x2f9e6b0f, 0x827f3cd1, 0xf89f5bd7,
- 0xf68bd8aa, 0xda4e68eb, 0x921423a5, 0x37214657, 0x12b6974a, 0xbb754b9c,
- 0xb59a3978, 0xdc2ff2ea, 0xdb8a64ef, 0xf7809298, 0x50588fce, 0xd533ff0f,
- 0x7e814c65, 0xfe79269f, 0x499ce586, 0x7288d78a, 0xe91f3df7, 0xf21e9285,
- 0xae428d27, 0xa6e5ea9f, 0x831ea5f7, 0xf1c3de71, 0xbb9c752f, 0xe4f9c743,
- 0x4d738cc7, 0x4738c86a, 0xfebecc7f, 0x24e1ca9c, 0x517691c7, 0xe94bba71,
- 0x663afc85, 0x70bf9064, 0x18cebdee, 0xcc314bf4, 0xcfd00377, 0x919cda5d,
- 0x7dcfe307, 0x0a8cc5ee, 0xbe849bb4, 0x32a739af, 0xdaa3c817, 0x5f950a73,
- 0xc4647db4, 0xdb35b37b, 0xa0e38cda, 0x45942d5f, 0x12aaeb01, 0xa77d04eb,
- 0xa7a01c9f, 0x4274bd8d, 0xf3cc3c6e, 0xa13b9e32, 0xd5ce7c47, 0x3dfd1f35,
- 0x4a11efea, 0x97f2f8d8, 0x7b077f62, 0xee611fb8, 0x6151e5c5, 0xee34576f,
- 0x390614f3, 0xfaa2fc60, 0xbf02f9f0, 0x1528eb12, 0x50fa6ffa, 0xe003844b,
- 0x1e3de43c, 0x9b58af5f, 0x62fe8b99, 0x04e8f263, 0x7e8f5b82, 0x67ee2ed6,
- 0xd67ee16d, 0x02c77b52, 0xbb994efc, 0xf883ec57, 0xbf09b2dd, 0x2c067c93,
- 0x378eef0b, 0x89bf7ac9, 0x3f714663, 0x7ef3d618, 0xf220f99f, 0x6e28decd,
- 0x361b4ecf, 0x43e50a30, 0xceb46667, 0x4facfc06, 0x4af7732a, 0xc6abf6c0,
- 0xc9a17b61, 0xe08ca7d2, 0xf42e88cb, 0xb8feee49, 0xfe8fec4e, 0x35b18f11,
- 0x87d806e1, 0xee950de7, 0x45067803, 0xcbc5c27b, 0xe5c5ef2f, 0x8d97bbb9,
- 0x0757b1e0, 0xaff5cceb, 0x760fce43, 0x180e82fd, 0x94d2c8ef, 0x30380fc1,
- 0x5d78531e, 0xfcff04af, 0xa33c92b3, 0xa23fe702, 0x68f07d63, 0x18ebb171,
- 0x1d71f02e, 0xf74a06c2, 0x80b7a028, 0x31e4def3, 0xa9f541d1, 0x15cc71c5,
- 0x9a9dbfe8, 0xb1bf541a, 0xffa83b34, 0x07fa33cd, 0xea689f3d, 0xb00bafc8,
- 0x97b67b67, 0x5a9f04bc, 0xed0a258b, 0xbe5a4fba, 0xb416e0f9, 0x4eaa3703,
- 0xef6759b4, 0x48c1f4dc, 0xf00675e8, 0x497e471b, 0x3ed1f907, 0x7a747997,
- 0x7e303e97, 0x50758a74, 0xd73ca2be, 0x68dc6c5e, 0xf29dadae, 0x78ae7f09,
- 0xe25ebcd1, 0x72cb9bfc, 0xa99e3f51, 0x79fc9f7b, 0xcfbe6635, 0xe21e2f53,
- 0xbd442ddf, 0x357f7402, 0xe2f688be, 0xc0fc1039, 0x0e3b45ff, 0x86cd9c51,
- 0xf7b44dc1, 0xf1e9e6d3, 0x942d64fe, 0x81c65fa8, 0xba018adc, 0x036368e9,
- 0x48de61b7, 0xe5db85a6, 0xbf90a6e7, 0xf7146f7c, 0x8c4decfb, 0xcc48efa5,
- 0xda86b86d, 0xd345ce6b, 0x1da96ff8, 0xfa2f28e3, 0x13e28505, 0x2da75313,
- 0x8decfdc5, 0x1db80ef2, 0xe7f89de6, 0xdc23c7ab, 0x7bf1b66a, 0x77d51302,
- 0x5941e7f2, 0xbd0d78d5, 0x7b65513f, 0x621fb015, 0xe342ddce, 0x001b444e,
- 0xcb50eaea, 0x5597a803, 0x3f9f6b63, 0x5a31bca0, 0x9ed4de48, 0x26f7a48b,
- 0xfdfd7114, 0x0c4f217b, 0x635d7c9d, 0xe7a24dcf, 0xbd7c2e92, 0xf7f282b2,
- 0xf51b090d, 0x4321bdf8, 0xaffd42a7, 0x4a9fd73d, 0xfa37dfb9, 0x2fbe91fd,
- 0x7af84860, 0xbe8de61c, 0xc8d8af11, 0xe3c8d12c, 0x62c375b3, 0xd5791858,
- 0x9e39cf3d, 0xc73a6c6f, 0x3bff8ff3, 0xe417f5cd, 0x9d4592c3, 0x31178c7a,
- 0xe10d8473, 0xd8305255, 0x67c01151, 0x8c9baeea, 0xeac31f88, 0xafa88db7,
- 0x0516504d, 0xf916af3c, 0xdd795a58, 0xfc83e422, 0x3fd49b8e, 0xd106792c,
- 0x4136ade7, 0x9e8f82a0, 0xdf2c7c16, 0x0e33a0ef, 0xf73b71e0, 0x79a6b7f3,
- 0xd13942de, 0x7c6ec851, 0x4767e49e, 0x7e69c606, 0x9e03f5ae, 0x1bb21423,
- 0xbeaf293b, 0xc3a1c0a4, 0xdd7bc0f8, 0xf3f3877a, 0x26d1f685, 0xca96fdf6,
- 0x6fb8e216, 0x1d97f2fd, 0xedaf182e, 0xd43cbcee, 0xcfde720b, 0x0b7bf17a,
- 0x1e75d6cc, 0x2fb587cf, 0xef903b47, 0x0ce1e227, 0x4d3ba2e3, 0x76816e74,
- 0xbed4778a, 0xef0a7a6c, 0xe15ad5bb, 0x17f30afc, 0x8ad912bd, 0x4af6dc74,
- 0xc7f51ea4, 0x9f3dbd1d, 0x5e8a7c21, 0xcf063be9, 0x9316ae8b, 0xe3fd919e,
- 0xb6f24a3a, 0x485ef587, 0x4ce9697e, 0x81a7a7f2, 0xa0994bf3, 0x7fc172d3,
- 0x6747c11e, 0x0f8892eb, 0x45822ecf, 0x91753c63, 0xda1b7032, 0x7d0b0e0b,
- 0xe5f24e97, 0x411f3c44, 0xb1fec4fb, 0xeaa18f74, 0x1f106c5c, 0x14cb9f56,
- 0xed471dfc, 0x05cadf92, 0x7d84989f, 0xb5d04331, 0x3f245bb4, 0x624f74b2,
- 0x6263ec2a, 0x95bdf03d, 0xc8f9fee2, 0x31ba7e4f, 0x80be90da, 0x022b926e,
- 0xedbea7f8, 0x8a768626, 0x744dde29, 0x40ca0333, 0xb766653b, 0x971b629d,
- 0x592feb08, 0x7bc3a996, 0x6a79f29b, 0x7fd1a5ea, 0x27c8aa44, 0xa0e6b730,
- 0x8ba86b5d, 0x9a7de274, 0x1e3cf133, 0x87057f34, 0xbb837ce3, 0xf98ced08,
- 0x3fe4284f, 0xe503fb43, 0x7503d0d2, 0xcabf40c6, 0x5106e74d, 0xb9ca7d3c,
- 0x2634a8cb, 0x38472e7b, 0x5ebb9d94, 0x8fd06be0, 0x710e3f8a, 0xc192bf71,
- 0xc86e7267, 0x4792bf44, 0x4f1f3c45, 0x0347b667, 0x546b7de3, 0xb8c98ff2,
- 0x9933f4a4, 0x804fdef0, 0xdf46fd3e, 0xa3df4198, 0x0a9dfad1, 0xb93ffeb9,
- 0xbffa40d1, 0xa19dedaa, 0x79fe783a, 0xf5092ba6, 0xa7837ac9, 0x6733f708,
- 0x0339efb2, 0xb83ee7d4, 0xe1dc3ad5, 0xbeb36787, 0x69f50735, 0xfd11c033,
- 0xd52bcd5f, 0xf76e3ef1, 0x1a38f344, 0xcf496fa7, 0x739f3a5a, 0x73e09b2e,
- 0x7a44ceb6, 0x2dd02ce8, 0x5243d00b, 0x2f3948ef, 0xeba48ff5, 0x5f973d6a,
- 0xca18e6d5, 0x9debf323, 0xa442ee49, 0x1f3c7ebb, 0x9e77afd0, 0xf902355a,
- 0xe53c74e0, 0x21bd4b5d, 0xc585e0f9, 0x244794c9, 0x03e492f5, 0x7ca5cf29,
- 0xf52f7497, 0xfd3fe8d6, 0xc3bfd6ef, 0x3cd293af, 0x7d02a577, 0xfae7ab5d,
- 0x85bd5aeb, 0xfc6c67e8, 0xcdd23d24, 0x43d1cbc5, 0x0a1e8e42, 0x3d35a392,
- 0xa94581e8, 0x1c5e7e52, 0x7c11cc1f, 0xedc4de33, 0x81f39448, 0x8da6b5e3,
- 0xb1f7087e, 0xd9eb953a, 0x3ddd6b9f, 0xa9d5ffc9, 0x97ff2697, 0xfc9c5ea4,
- 0xfe54efff, 0xbcad0a9d, 0xa3710fc7, 0xf3bd3fbc, 0x83ea1f72, 0x03f40c83,
- 0x6896c1ea, 0x0fa126c7, 0xc5445f48, 0x1f487ef8, 0xfe9ef614, 0xf5e1a9df,
- 0xff6c66c1, 0xd240fab1, 0xc91be497, 0xb42f9227, 0x62f9247c, 0xbce16fc2,
- 0x8b7a7888, 0xd6aa8fdf, 0x0e289b7b, 0x8c1e88e9, 0xc76dd9fc, 0xdf88536d,
- 0xe084f442, 0x04bf3f1f, 0x1fc90deb, 0xff245f92, 0x98fe0b54, 0xf243f829,
- 0xf9b56ec5, 0x0a9811d1, 0x08f9e690, 0x93e488e5, 0xfab5e7aa, 0x42ba47a1,
- 0x199b234f, 0xae90c75f, 0xa40ca1aa, 0xfc0f532b, 0xf512f070, 0xa48bbec2,
- 0xf3feafa7, 0x0f55f4f4, 0xa7e674f4, 0x1da853d0, 0x03be61fb, 0x1f3673d6,
- 0x9fa66de4, 0x8dfc26de, 0x9b21fb71, 0x46f6079f, 0x35ee7df1, 0x67ff93a6,
- 0xcf3cf7c2, 0x3303da57, 0xd241bf85, 0x01d81e69, 0xf8fc4369, 0xbcc0f3c7,
- 0x847b938b, 0x877c5367, 0x3327cf11, 0x03b40ca1, 0x537fb27a, 0xee4d2ed3,
- 0x17fe8a45, 0xb480f3c2, 0x1c6edd9f, 0xaf1e1690, 0x027ed303, 0xa262275e,
- 0xb22bf92a, 0x00a35c4b, 0xba890f3f, 0xc2094fb7, 0xf902faf1, 0x2e55b2fc,
- 0xd607ca3d, 0xf475ddfd, 0xcaa5bc77, 0x31fece7a, 0x8f099eb0, 0x1d1fbf32,
- 0x151d8f9e, 0x511fedd3, 0x717fbf98, 0x95fed65a, 0x451be7a4, 0x9ea74ade,
- 0x3d4483c7, 0x8096ea1f, 0xbea6817a, 0xeab7f796, 0x3e60593b, 0x928dd209,
- 0x0eecf1cb, 0xfa601fb0, 0x2fa8b3f6, 0xff430a6c, 0x86fc6d46, 0x5ca2cf57,
- 0x6c50a1db, 0xde0e1baa, 0xfa070481, 0x07d5383e, 0xc65d77ef, 0x78dbcdd8,
- 0x43b5f6fd, 0x132f7956, 0x1bdc06e3, 0x2e2b3432, 0x502847ca, 0xa199597c,
- 0x4d3dbef0, 0x1eb913ca, 0x0214f746, 0xaf9867de, 0x77ef2977, 0xd1674de7,
- 0x4ba6adfb, 0x5186ff98, 0xac6fefe1, 0xe4c6fd10, 0xfe7d84c7, 0xe1ca9a70,
- 0x3406fc2f, 0x694d343f, 0xff9f7f0e, 0x1d2fc109, 0x78213f18, 0xfe855a4e,
- 0x84a30eed, 0xc2157bb7, 0x41632c7b, 0x9f98347e, 0xbad71bea, 0x7cf41a4b,
- 0xbc0d2ebb, 0x77bf687e, 0x03db05a5, 0x5f069bf4, 0xf7801fa6, 0x77de61dd,
- 0xfadfbf04, 0x125af843, 0xdba0bef2, 0x5d8e9259, 0xa31ef441, 0xc67d1377,
- 0xb4362bc4, 0x91dc6ba3, 0xe0bcf12b, 0x12d2cfe7, 0x138c9b82, 0xb4dff084,
- 0xc8033192, 0x6fcf124e, 0xebfc855b, 0xe7f775d6, 0x1ae928fc, 0x5c0136af,
- 0xef07f5c9, 0xeb769cbf, 0x024ff42a, 0xaa73d05d, 0xadd603eb, 0x4d66c7e5,
- 0x7f86947d, 0xfc91ff05, 0x70007d40, 0x16f941ca, 0x08e8c87f, 0x044f93a0,
- 0x7c894e9c, 0xdcd18ef2, 0xe2c8ec9e, 0x3c6977e5, 0xa099f52e, 0x9e9253cb,
- 0x90e002a2, 0xf43f4416, 0xf60221f7, 0x29ba704d, 0xbdf3f25e, 0xbfc0c525,
- 0xfcfe761d, 0x66fed67f, 0x5fcd3795, 0xcff78ed7, 0x2096f7b5, 0xf7c7ba5c,
- 0x768fda2e, 0x6e024dc4, 0x67bdaddf, 0xc08077bf, 0xbbffa273, 0xf41f40ab,
- 0xa46a9e3d, 0x3e94250f, 0x2fa50d5e, 0xfa7de6af, 0xbd3d043b, 0x7950b7ff,
- 0xcfbcd2e0, 0x17107bf0, 0x5bc0beff, 0xe3af06b1, 0xa31d7835, 0xbaca97a9,
- 0x4afe482f, 0xe3be5cb9, 0xe312fbe1, 0xd0a9afd1, 0x3d3f2475, 0x3cf4483f,
- 0x77e926d7, 0x4fd5c115, 0x47ed0fcf, 0x2cdc9dfa, 0xf491b5e9, 0xc39424cf,
- 0x29f5fc23, 0xfea88728, 0xc5c60970, 0x91eafafc, 0x6fb72855, 0x1ffd9068,
- 0x2f37fea5, 0xa6ade393, 0x8c8f12e7, 0xeefa463d, 0xafa97ca6, 0x3fb9271e,
- 0xefbf85a7, 0xfeddff4c, 0x4687e41f, 0x6ad65c0d, 0xff4d5eea, 0x6fd017d5,
- 0x2fef34cb, 0xa95f3cd2, 0xd4d1afa9, 0x2fdf821b, 0x1f10a19b, 0x38f01596,
- 0xb52f96a5, 0xef4ae1f4, 0xf5ba73b6, 0xfb2662b9, 0x26af882e, 0xb5faf3d4,
- 0x1a4b1be9, 0x75f501cc, 0x5f384a9b, 0xf7016cc0, 0x7ae6419f, 0x4307a055,
- 0x20b3720f, 0xd9b907bd, 0xf9efab4f, 0xafe07ff3, 0x0a371429, 0xab764bb2,
- 0x5536f5c1, 0x75bbdbac, 0x810182ff, 0x4be7d5f1, 0x63dd5cf0, 0x5cdbc71c,
- 0x2ed02632, 0xae25cd62, 0xfeca7d80, 0x5efbbee3, 0xeb3cf9c5, 0xd1b25cfe,
- 0x114f718c, 0x12f3b4df, 0xfa8aa5f4, 0x6ff856ba, 0x2f1e61c6, 0x5aa293c6,
- 0x080fe673, 0xee6b27d8, 0xbb6cfb83, 0xb7dfe55b, 0x00fc07ab, 0x8398ca9c,
- 0x33a750f2, 0xb6a5e517, 0xfc2cc4c5, 0xf76f782f, 0xd442eadd, 0xc61707d3,
- 0x2bd35e51, 0xb17cfce9, 0xe277a63b, 0x45b7a84c, 0xb6f246df, 0x54b1feed,
- 0xcb5d52ee, 0x2d8c6cbb, 0x894af75e, 0x1e7c72f9, 0x3bba7043, 0x2592a5fd,
- 0xa6f7ef40, 0x8f7de83b, 0x03b896dd, 0x0c07eded, 0x0e043714, 0xe7e89278,
- 0x3c60d341, 0xe92d976f, 0xf2b1714f, 0xc38d26c7, 0xf7e5a47b, 0xd25e2819,
- 0x9f91b3a9, 0x58c0f3c8, 0xb19a93ca, 0xabde944c, 0xdfe57ca9, 0x7bc7ac7f,
- 0x14eb5da6, 0x55cd4efa, 0x6dff375f, 0x1b2bd410, 0xc67ee9b2, 0x9474e7cb,
- 0x9ae9fe17, 0x53cc3ebe, 0x47591c3e, 0x9fd0a5f9, 0x9e56bbee, 0xc92fec77,
- 0x0daafec7, 0x428e3853, 0x47cfda3b, 0xe14fa857, 0xab32ce3d, 0xbbf30a25,
- 0xc8c77e8f, 0x3ef473af, 0xe6ef7d13, 0xd6e7b353, 0x8f74f135, 0x767d2d09,
- 0x15587154, 0xf4dac380, 0x29c925fd, 0xf8126ed8, 0x032d6fdc, 0x75d32f3e,
- 0x93e90fd3, 0x5f5e588a, 0x92cdeebb, 0xa38fb04d, 0x7ca5f44f, 0xd70c84b1,
- 0xd78074ba, 0x93d70ce1, 0xd9fb8a54, 0xc79bfcaf, 0x593a5f25, 0xb5f4889e,
- 0xcbf5d059, 0x0313cae7, 0xc5416eff, 0xc1d13d29, 0x02c7462b, 0x5469eefa,
- 0x6ce782ba, 0xf43883a0, 0xe710cf9b, 0x85e7a016, 0x57d8c35b, 0x3db9d34b,
- 0x84dbf6d6, 0xba208e51, 0x29e498fe, 0xfea0379d, 0xa447fa62, 0x16988ee7,
- 0x77752e62, 0x1ddb243e, 0x34327049, 0x3322fa45, 0x1aea7fd1, 0x4ff3a2e7,
- 0x96c99f73, 0xfd143e00, 0xfcf2f13f, 0x3fa04fdf, 0xf13efb9e, 0x604b3ffe,
- 0xaff6433c, 0x68bc5ab4, 0x58b31c5c, 0x838f88f4, 0x3147c5fa, 0x9d62ad3f,
- 0xc540f481, 0x5d4584ba, 0x6e807f28, 0xdda6bfd0, 0xc0c32997, 0xc63d18fd,
- 0x192f3f57, 0x5e781693, 0xbbf24139, 0x377cbe27, 0xc6c944fd, 0x65f33d01,
- 0xa7cb8da5, 0xf7f8eb71, 0x58872b75, 0x7bbf74f4, 0xe89babdd, 0xc8bcf01e,
- 0x5157bc5c, 0xf844ceb9, 0xbc58b4ea, 0xbef12bb6, 0x0b1f4581, 0xae74a1e5,
- 0x0e19f54f, 0xca9147c2, 0x54b911f4, 0x190a3dd2, 0xf0b13c3f, 0x1d31c7d1,
- 0xbbe673f3, 0xefc0187e, 0xe9d38b8c, 0xf92a6d99, 0xc4f1b51f, 0x1ab7d7ea,
- 0x888fd90b, 0x4710f627, 0xe29d62ac, 0xe3e1e2bb, 0xe238da89, 0xbdc5d2bf,
- 0xa238eeb3, 0x5187be81, 0x4588e229, 0x7f5a156b, 0xbdfe42e5, 0xee38a292,
- 0x18b23e3f, 0xed2fa0e8, 0xc5cb6bdf, 0x7fae693c, 0x8be2992a, 0x5eaf5f80,
- 0x99fc8f3b, 0x5e1ce975, 0xb03be265, 0x199d2387, 0x58afde78, 0xae704917,
- 0x07f6727c, 0x7de3e44f, 0x81f189c0, 0xa09b6be7, 0xe19f180f, 0xce39683d,
- 0xd0f725b1, 0xd68b6777, 0xf31939c3, 0x73d963b4, 0xde226537, 0xde303252,
- 0x2e55fb29, 0xef0fbbbd, 0xd86ce707, 0x950ad977, 0xbb6b0f7f, 0xf021f489,
- 0xb80b327c, 0xd9633e2f, 0xd72346eb, 0xa8792c67, 0xfe1db3b0, 0xc29f6cfb,
- 0x4104fc73, 0x26b7b8ad, 0x5bef27e1, 0xf7f8e995, 0x0a754b36, 0x8902c3dd,
- 0x7e97f746, 0xa3fdc191, 0xcedc1979, 0xd270cb2d, 0x55ea9e3d, 0x4cd2e726,
- 0xbdf74e3e, 0x55e73875, 0x282a3aeb, 0x1317f9ae, 0x976a57f9, 0xad22ba45,
- 0xf9e31f3c, 0xad779401, 0xaa3c0237, 0xfc6e5c1c, 0xad63d042, 0x94d5d263,
- 0x0767ae9f, 0x5607eff0, 0xac9cb85b, 0x9bb8058e, 0x86e90139, 0x1939f7e2,
- 0xb8e253e5, 0xe6028329, 0x8c3b4457, 0xc7fab0e3, 0x0d63abdd, 0xfec1a7e8,
- 0x38420f97, 0x237f5dc6, 0x9559efae, 0xb4801af8, 0xbfed00aa, 0x3c3cd567,
- 0xd8ad9777, 0xf0e50e3d, 0xf1832ddc, 0x7b2b0546, 0x23d25dee, 0x3bfe0573,
- 0x395a3e45, 0x81bbf1d4, 0xb9706437, 0xdfb951e9, 0x2f0106e8, 0x79f20749,
- 0xf7030af5, 0x47bc83e3, 0xe4bd5301, 0xdab71a43, 0x728891d2, 0x81bb7ab8,
- 0x8cdf87ee, 0x973806eb, 0x751f492f, 0xdcaae800, 0x51df4310, 0x344ef2ad,
- 0x51aabd62, 0xbdffbaa1, 0xd3a40c84, 0x60bd962f, 0x1c39fa45, 0xfa839ad9,
- 0xa45e6ba9, 0xda29ee93, 0x8beedfb8, 0xaf743965, 0xc3ad8669, 0x9965df82,
- 0x8edb20b1, 0xada0fc72, 0x0fcf88d5, 0xb0ea6736, 0x46d9b2ee, 0xbfa5dd61,
- 0x885fea92, 0x41fa177c, 0x9e3852ba, 0x1b769aab, 0xdd2feff1, 0xd4e2e82b,
- 0x41f6efb3, 0x4675503f, 0x2fd41f47, 0x527d0740, 0x28cfce11, 0x9a6b9fa4,
- 0xa4bc1e78, 0x03a41a83, 0x8239bbe0, 0xbdb66a0e, 0x43f21770, 0x373fe20d,
- 0x9e808e94, 0xf9fda9db, 0x7f18e30d, 0x44e91dbf, 0x2fa833ea, 0xce3fa033,
- 0x058bebc8, 0x0c7da1fe, 0xe00ef76f, 0xf9dd75f9, 0xd07c4108, 0x66d77e13,
- 0x4c3e04e8, 0x8ad77724, 0xd8ae76fd, 0x9dfc456e, 0x1ef7767a, 0x3f54b78c,
- 0x11dada0f, 0x3c041f86, 0x56ff716a, 0x19d93f5a, 0xab5fb8b5, 0x74ddff7f,
- 0x96b0f82f, 0xfdc9fdf1, 0xfec5ead6, 0xfef173e5, 0x2acfb13a, 0xadb5e026,
- 0xc13be72f, 0xf4c7c867, 0x3fb121dd, 0xbbf83d8f, 0xfec5bbba, 0x6cc9449a,
- 0x0f8456cd, 0x0fe517e2, 0x28cb8fd0, 0x397409e5, 0xe50365b5, 0xc97c4bf7,
- 0xd7efbff5, 0x93fc2e2b, 0x9d8f1254, 0xb6f77c3d, 0xa1c9f045, 0x763292fb,
- 0xd8befc00, 0x240d9f4c, 0xcc07d57a, 0xce46e927, 0x49a7f457, 0x61bee2d7,
- 0x5f1c56fc, 0x1bd07bce, 0x0e71c7ad, 0x721fce32, 0x8b2f92fd, 0x3b5da7ea,
- 0x4efd8ad8, 0x5ed1b259, 0x3f7c7811, 0xbbef46c3, 0xf7806ed0, 0xf2143b5d,
- 0xe7121f5f, 0xbdf743fd, 0xe01f2d60, 0xc577f7a7, 0xe19d25ba, 0xe4c9fa0f,
- 0xb9daf77a, 0x6ebb583f, 0xbae48729, 0xe1bfee8b, 0xeb976c5a, 0x2051f8c7,
- 0x4a384a9d, 0xfaf7957a, 0x344b74b4, 0xdaaaf527, 0xa6d77d33, 0x9dfca21d,
- 0x78ed7690, 0x2c3a3ec2, 0x9ebbcdf2, 0xe77df956, 0x41edc965, 0x33188ef7,
- 0x259fea07, 0x15b6aef3, 0x49b73c62, 0x521e7ba1, 0x4acfc0af, 0x923e807d,
- 0xdef0c1f6, 0x36a57f3c, 0xf10275de, 0x63bc7559, 0x44927e1c, 0x7d57a5da,
- 0xa0c6aadd, 0xcf1b6aff, 0x53749383, 0xf89db275, 0x93dc5aa1, 0xeef15b2a,
- 0xf74861c4, 0xce281b4f, 0x58df7653, 0xb3fbda23, 0x8a1f4d37, 0x127bc0e0,
- 0x6c4fdf28, 0xe047921c, 0xebc4b661, 0xc6c4bef1, 0xbfc7af47, 0x87633a5f,
- 0xc1a1df4a, 0xcb8f9071, 0x7f23c8ee, 0xcec8e1eb, 0xaed02389, 0x436ab5ff,
- 0xa6e47ebb, 0xffb08b21, 0x58ef4b48, 0xc6d078fa, 0xf4bbaa38, 0xa427a431,
- 0x03f32c1d, 0x90bdc5eb, 0xaf9cdeec, 0x8a97757a, 0xefac0bc8, 0xaef9f183,
- 0xddf4910d, 0xa3a352a8, 0xdbe715b9, 0x8ee74499, 0x2526385a, 0x2b9ee9db,
- 0x8cb369d9, 0x9725222c, 0x453023da, 0xc74375f9, 0x5e4fa81d, 0x1832c3bf,
- 0xd4cb8bbf, 0xb9cb43f3, 0x90e3cd7d, 0x61dfc171, 0xeac8eb92, 0x3b57e9cd,
- 0x2f7f7c9e, 0x74ec2b9e, 0x3fde919f, 0xebe9ecb1, 0xd89e1f51, 0x7dc7639c,
- 0x4919db1f, 0x198e0bf7, 0x78e7bf82, 0xb4c2f7a9, 0x3de4a9f7, 0xc1defcd7,
- 0xfba49cf6, 0xb9cbde0b, 0x98f2d2ec, 0x74662e4e, 0x065cfc4f, 0xe8e4fee3,
- 0x7e62b6ef, 0xc9a34561, 0x8e64f786, 0x7c63fd20, 0xdf4abb6b, 0xdfbba201,
- 0xdb23af80, 0x703ee8f3, 0x5ebcc7c5, 0xf0f8acd1, 0xc3fb72fe, 0xc2fe53f7,
- 0xf137b04c, 0x3db7796a, 0xebe1fabd, 0x38ce0d91, 0x3bf1cb3d, 0xf3366700,
- 0xef908b7c, 0x75bebc3a, 0xffe38a4f, 0xfd2cfdbf, 0x077bd313, 0xf09347df,
- 0x57aae796, 0x720a2e80, 0x72fbf0fd, 0x9fb22cf1, 0x50f62e4f, 0xb4395a79,
- 0xb3d2246a, 0x15ee8625, 0x51e3b4bc, 0x5373bf15, 0x79f06dbd, 0x308f1f3c,
- 0x9ff7d0c7, 0x90bc5cbe, 0x17279a82, 0x8a3f89d7, 0x15f854b6, 0xb55e547c,
- 0xfbde8dad, 0x0b5e4772, 0xd97debde, 0x9ac5c31c, 0x3be820ab, 0x3dbf1299,
- 0xfb9657dd, 0x1cd7fcfa, 0x9fdd72cf, 0xc56e9e6f, 0x21fdb57d, 0xe23865ae,
- 0x86c63a37, 0xc8a56076, 0x86ba392f, 0x23c7d9db, 0x18abfe62, 0xed7c7cf0,
- 0x0efc4494, 0xa9b6ccd1, 0xc57b63d7, 0xe786c54e, 0x49cee703, 0x7dcf3c56,
- 0xe2b4efa6, 0xd6cfaa3d, 0x3e57fbc8, 0x237bbbfa, 0xd829b3c6, 0x9eab447f,
- 0x84293239, 0xfc32f44c, 0xcbee9ea4, 0xe4ed017e, 0x451f393f, 0x89f813fe,
- 0x99927cc3, 0x4bbf722f, 0x9c57f9f7, 0x7d8a46ff, 0xcbb6f7b7, 0x17b506f8,
- 0x63f6f015, 0xd096b76b, 0x68de4fdf, 0xbfbae1b0, 0xf1a068dc, 0x4db9c0e7,
- 0xbe3deb07, 0xb0839f99, 0x13e8e78e, 0x6779f99b, 0xef3f334e, 0xb833cf54,
- 0x60d2fdf8, 0xe80a2cba, 0xeb2ddf47, 0x7323bbe1, 0x737f7c5c, 0x7ee27f40,
- 0xb1bf442f, 0x9fee99ac, 0xa93e6a5d, 0xaaff7e96, 0x74dd1791, 0x08bd13db,
- 0x23ff22b8, 0x98ba4add, 0xf5c786b3, 0x0b83cded, 0x9d24fe91, 0x5803bf68,
- 0x3bfc646f, 0xfa28bab2, 0xb324f7ee, 0x62fa80c3, 0x18e77c4a, 0x075f4f04,
- 0x916aaf97, 0xe4f785ce, 0xec29bd58, 0x15dec477, 0xbc1a78f2, 0x7abbf74b,
- 0xcff7f8db, 0x59317dc4, 0x474abe82, 0xda293e7d, 0xba038dfe, 0xf2ffae74,
- 0xf5d03d3a, 0x3bf691a4, 0xd7809db2, 0x7af35ff5, 0x167b7d9e, 0x7def3fd4,
- 0xec3d3af6, 0xf695d26f, 0x2fa80621, 0x75cdf259, 0xc9b9e063, 0x3bd83ae1,
- 0x9b139e60, 0x7f71d292, 0xdb087ed0, 0x8e7a27a7, 0xee2b5960, 0xba569d8f,
- 0xf4cc2d06, 0xa77b7ff7, 0x0e4be0e5, 0xc0d3bd7f, 0xa73bbbe8, 0x87f5cb7b,
- 0xd70e9d2f, 0xa109dea9, 0xdd8ce5ed, 0x5e7cf947, 0x7e076f7e, 0x788911dc,
- 0x5dd38aaf, 0xd3c7bcb9, 0xe3c7b9a0, 0xe4d5f7e4, 0x7f792afd, 0xfdff72ea,
- 0x7297b5b3, 0x00ffecff, 0x4fb2f369, 0x00008000, 0x00088b1f, 0x00000000,
- 0x7de5ff00, 0x5554740b, 0x55b9e896, 0x2a493eb7, 0x54842549, 0xaa84a925,
- 0xc0902b7c, 0x310c7c25, 0x0403e548, 0x6a285888, 0xa205a0d4, 0x01148280,
- 0x55f4741d, 0x9a7c3061, 0x179f8ee9, 0x102d4622, 0xdd787195, 0x866db1d1,
- 0x3220538f, 0xb40e9afc, 0xd38ceb63, 0x68d1d01d, 0x38311b63, 0x6f360cf4,
- 0x4dce7def, 0x802a56ea, 0x6f7be7be, 0xf65e97ad, 0xee739f61, 0xffb3ecf9,
- 0x5f5bdf67, 0xa5eb2c19, 0x0f24c664, 0xa153ab63, 0x63595a74, 0xff7b9419,
- 0x68d2cfe9, 0xac839ac6, 0xc18f2e3b, 0xd3f5a35f, 0x7ccf5051, 0x2e504bba,
- 0xcd1a484b, 0x139960c6, 0x996fd062, 0x12aeb189, 0x6d3b26e8, 0x12d8c2cc,
- 0x019dfe09, 0x19caf9ff, 0x956c674b, 0x44edfe15, 0xf08742b8, 0x7f466683,
- 0x3f98059f, 0x1fd8c0df, 0x3925744f, 0x9d9d8cf5, 0xbb0c2e1d, 0xbc65fb18,
- 0x009ce6cf, 0x8ecd1ded, 0xbec634a6, 0xd4a4c37c, 0xd09eff43, 0x60f927df,
- 0xe67aa5fc, 0x6d9284ef, 0x24d8ce1f, 0xc3ea2f28, 0x61dfa053, 0x8db6f157,
- 0xa9cbbcf0, 0x3f9e0c63, 0xfce70aeb, 0x82c678f5, 0x32f2932e, 0x32777ea3,
- 0x9f1eeb80, 0x9dfb1c3e, 0xfe5d7d7d, 0x936eb03d, 0xec1258cc, 0x598c067b,
- 0x0030780e, 0x07c32fac, 0xb40e3442, 0xbea09307, 0x0e74f5c5, 0x2f307c23,
- 0x0dd8c89b, 0x06ebef8c, 0xf11fbc39, 0x196494c5, 0x6f9b37f7, 0x3283db0f,
- 0x3333a38c, 0x98bbae03, 0x4d3f5875, 0x8eb19800, 0x7f60c34b, 0x3263c066,
- 0x24c78096, 0xa1eaa6c6, 0xe9afac13, 0x0990fa97, 0x7884d7d6, 0x85d07014,
- 0xd72c7a23, 0xc58bf8c3, 0xbc8ecbbc, 0x58c1c46b, 0xeb07fe10, 0x5de62259,
- 0x3d7771dc, 0x9092cb9e, 0xc0b74ce1, 0x7ffa25f5, 0x72c79d0f, 0xf2feefd1,
- 0xe29c46ad, 0x7eda1dfe, 0xafa6d9cb, 0x52fcf0f5, 0xfdc46dd6, 0x6a8ceb2e,
- 0x0cf9a8ef, 0x977cbbd7, 0x99debeb6, 0xc2748698, 0x97b1b2c6, 0xe74d54f4,
- 0x99f448bd, 0xca746faa, 0x66e19fb8, 0x371304c5, 0xf4479f3d, 0xb00cdec2,
- 0x63ac7ec8, 0x8b4fd118, 0xb1e74f4b, 0x9cc49764, 0x7ebb18e3, 0x42731657,
- 0x61aefd53, 0xc85d2654, 0x5fcffaa0, 0x57de3639, 0xd75e7032, 0xc6ab6abf,
- 0x6aff5df5, 0x3aea9511, 0x4e1d049a, 0x867497d5, 0x2ce71d61, 0x9b800eb0,
- 0x8162c08e, 0xd66e9a7e, 0x99e11887, 0x57bfb199, 0x596bc72c, 0x424fa5df,
- 0xfd8a0e58, 0x3a24974a, 0x1f3c6484, 0x433d61ef, 0x031e627a, 0x79993bb5,
- 0xa05ca5cd, 0x398ebb1b, 0x24dfe063, 0x19ce2fce, 0x81ee9ccf, 0xfc583976,
- 0x87584ab3, 0x0941ae61, 0x5c737b41, 0x33e436d2, 0xe574f416, 0xe20d73c3,
- 0x4e38aeb9, 0x54ee0937, 0x1d2af3cd, 0xadfa2adc, 0x18769a4b, 0xb3c1b2e9,
- 0x5121e888, 0xc7acd4c9, 0x406a5fa4, 0x67d5b9fa, 0x623ba4f8, 0x585fa21c,
- 0x295e0dc7, 0x7378fc84, 0x50ddb683, 0x44ad75f9, 0x8e47d425, 0xfbf6d5e7,
- 0xd003d229, 0x717e103b, 0x9c0c3d24, 0xc3a3c583, 0x1224f073, 0xb9cccbbd,
- 0x5be012b9, 0xee181b0e, 0xf7cf14df, 0x97310e79, 0x0f80fd86, 0x8875e260,
- 0x2e4fa817, 0xc537e2d7, 0xb0e7c5a3, 0x867e2d3a, 0xb7fbb57b, 0xda6ae435,
- 0x35237c33, 0xcb8b59ed, 0xbfb67034, 0xc47fd342, 0xec0d6aea, 0xf4d4ce0a,
- 0xa37f5bcf, 0xbd682e06, 0xa8bfd35d, 0xbda6817d, 0xa69f7438, 0x268ed47d,
- 0xf9da5c0d, 0x98ffa688, 0xda6b8f5d, 0x6a3786c7, 0x7e1dc7da, 0xe84f034a,
- 0x7fe9a2da, 0x34db07cd, 0x5fba93ed, 0xdb5fb4d3, 0x9e0686f3, 0xd35bbbdc,
- 0x0385ca7f, 0x1d8ab81a, 0x31aff4d3, 0x4f0356ff, 0xa6abfeb5, 0xc7fb74ff,
- 0xce19f69a, 0x67da6a3f, 0xd2d1bfb9, 0x93973c6b, 0xa5ff2bd7, 0x9359ee79,
- 0x5f50dfef, 0xdd954b34, 0xebf48641, 0x35ba3e24, 0x0184a74d, 0x972a83fe,
- 0x1c9e1d04, 0xc1392561, 0xb78e59f2, 0x32b0e914, 0x6e7c7c8c, 0xe0f24497,
- 0x28bd28ab, 0x91ebd1ff, 0x4afd9da0, 0x22765e52, 0xc45d41dd, 0x331e29fc,
- 0x39d62393, 0x81aaceac, 0x9aed7b87, 0xa706b6fe, 0xe7c33da6, 0x2d67b4d6,
- 0xb6703456, 0x7fd35cbf, 0x068f6ac4, 0x34eb0576, 0x7bd6f3fd, 0x6b417035,
- 0x517fa683, 0x5ed34fbb, 0x69ac5a1c, 0xafc3b51f, 0x573b4b81, 0xd98ffa6b,
- 0x8fb4d415, 0xb4d7af0d, 0xaadc3b8f, 0xb5742781, 0xf35ffa6b, 0x3ed34841,
- 0xa6877ba9, 0x4e9edafd, 0x77b93c0d, 0x94ffa697, 0x5c0d610b, 0xfa688ec5,
- 0x6a4f98d7, 0x0fd6a9e0, 0xdba7fd35, 0x67da6b4f, 0xb4d73f38, 0x2cd076ab,
- 0x7adad7f7, 0xaf5d1761, 0x7cf359fc, 0x90c3dab0, 0x486f823e, 0xd613b34a,
- 0x3fe102eb, 0x777ce49c, 0x28ed1e9c, 0x8c14182f, 0x41ad2901, 0x420c92fd,
- 0x480ae90c, 0xe2a6358c, 0x20ac4028, 0xc15549b7, 0x4f68c9f3, 0x73aa9000,
- 0x1fa0fcb9, 0xeb5ad813, 0x1bb266a7, 0xdf40971c, 0x29bfc25d, 0xa0944b83,
- 0x85ebaa9f, 0x4ea166f9, 0x726f3a02, 0x582e3cf9, 0xaf9d7dcf, 0x6862cb4f,
- 0x705b0427, 0x9307a01d, 0x9e6f41bb, 0x79776388, 0x378f064b, 0x89780cc3,
- 0x5c48ef98, 0x32cca3ab, 0xcc33fcf4, 0xff7fa967, 0xae3e06b8, 0x8a6bfb04,
- 0xa0a7ff18, 0xfbb065ee, 0x37c0035a, 0x153d8c05, 0x4cfc12b0, 0x5b704ec0,
- 0x7b6549c0, 0x96e54dc0, 0x1ded4280, 0x5f827281, 0x0e087808, 0xdca8ea05,
- 0xfd52f016, 0xc10340f6, 0x547c04af, 0xa62c08ee, 0x9f80b5f2, 0x560677da,
- 0x40f3fc13, 0xc0ceca90, 0x237faa7a, 0x9bf04ad0, 0xdf827681, 0xdca8840a,
- 0xe541d815, 0xb52740ee, 0x22ec0def, 0x9840edf8, 0x30e070e0, 0x5d0207c1,
- 0x7c0c1f04, 0x40a1f040, 0x03879537, 0x0d1e543d, 0xf1fb52f4, 0x078205c0,
- 0x576b4bce, 0x2e576133, 0xd2c07412, 0x2f793db8, 0x85f6523f, 0xbb462d8e,
- 0x43a09177, 0x87983543, 0xcc867740, 0x2ecd6dc2, 0x13a06a3c, 0x71c9d137,
- 0x96af2fb4, 0x4070d04e, 0x33560d7a, 0x5a9bd237, 0xc9e954b6, 0x90ae0cfe,
- 0xbb732f42, 0x336feb88, 0xb537f553, 0x85283e37, 0x079b9ed0, 0xf811b276,
- 0x9f6123e6, 0xe5c7147c, 0xc1bf39f5, 0xa35f768d, 0x66c0af14, 0xb277fe01,
- 0x8c2fe03b, 0x5ed77fa4, 0x9fb456d3, 0xc235f5d4, 0xe7183a38, 0x5a2eecbf,
- 0x6c3b2357, 0xbd40f5c0, 0x72fc0f47, 0xe2dbe6c6, 0x2fbeba02, 0x2234175b,
- 0x85425913, 0x8cc644de, 0x48f3df76, 0xf7fce7e7, 0x17c1c21c, 0x9c429559,
- 0x78537ae7, 0x7f30adf8, 0xb2bd11ef, 0x5e3439cd, 0x00ceb796, 0xf6997de1,
- 0xa0773fb7, 0x17f75f1d, 0xe1cf0fbd, 0x21b12184, 0xe9dd7404, 0x3acf8892,
- 0xd94d3a5d, 0x02fdf766, 0xa26df9d7, 0xa01d4eff, 0x56ebdbf2, 0xb612b2bc,
- 0x20a2b8d4, 0xf055ed19, 0x5f680c0f, 0x034e61cf, 0x989b87ca, 0xea1c5de7,
- 0xf823e666, 0x52a41656, 0xe176f9b6, 0x21636ebe, 0xa6157d82, 0x8afb589c,
- 0x383bd75e, 0x752c70d8, 0xdd90f29a, 0xfbc70077, 0xeb43d136, 0x7a69313a,
- 0x5d4bee21, 0x49c33997, 0xdeb366fd, 0xdf7d7017, 0x53fafbee, 0x9d306f29,
- 0x61f488fc, 0x3fb06981, 0x3779c233, 0x38e0ef03, 0x214b0fcd, 0x3e9573a4,
- 0xa74cc11a, 0x7a851ff1, 0x805e9229, 0x4b7fd04e, 0x9399cdeb, 0x4dd2f448,
- 0x3e926ff2, 0xfa7b0468, 0x28542e84, 0x8c4e89e9, 0x5173ac12, 0xee49d01a,
- 0xc0f0f4d0, 0xe423287a, 0x17d9d020, 0xfe9fde38, 0xe2371ae1, 0x93dbf96d,
- 0x66b7889c, 0xd0079c1d, 0x9ea8f073, 0x442604ec, 0xd2dafebb, 0xb207f910,
- 0xc529cca2, 0x7172e373, 0x7ead9ebf, 0x4ddc863d, 0x74f4e5c8, 0x0ba86ec2,
- 0xef9cb8d1, 0x2e7d76d5, 0x2e7d473f, 0x15a6df3f, 0xc3d52d9f, 0xf81c4ffa,
- 0x8d2ce8dc, 0x3fd58fb1, 0x823f2879, 0x3aef97ae, 0x7e83cd3d, 0xb92eeb17,
- 0xbea07131, 0xd2abcc50, 0xe898de91, 0x5c896adb, 0xc75d3f57, 0xa75d22e7,
- 0x11e75d00, 0x768a7f5d, 0x33936cf9, 0xbb2856f9, 0x28613501, 0xc95a2f7d,
- 0x14c05c7f, 0x2f32172a, 0x0c808b95, 0xc1bd8e90, 0xf7888d27, 0xd52758fb,
- 0x777e503f, 0xbdf5d23a, 0xd9f91f3a, 0xd517594b, 0xb5bd672f, 0xaf37b478,
- 0x1daef35f, 0xeb537d56, 0x44915393, 0x7fcd0c6f, 0xdb39cb17, 0x4e834fa5,
- 0x5cec93e2, 0xe4b747c0, 0xe613227f, 0xd5677dbf, 0x3f505913, 0x85cfcf5b,
- 0xa2e7e31d, 0x7de891ca, 0xe0145f03, 0x78a6dff3, 0xa4fa5f68, 0x345f0d3a,
- 0x123cce3e, 0xcfbbd38c, 0x8ae6da14, 0xfbf293e0, 0xf28590ff, 0x13bdee4c,
- 0xdbf97bcf, 0xef3c54a6, 0xfbd718fb, 0xaf8d4792, 0x119efaa8, 0xe2cfdfbd,
- 0x85f7ec15, 0xb22fefa0, 0x17f7d119, 0x658a3812, 0xcb287603, 0xf2cbd9f1,
- 0x72f6f406, 0x88d1cedd, 0x95ebd027, 0x7df70e78, 0xd632d9dc, 0x9420fa85,
- 0xe1887683, 0xecd29335, 0x7617e8d2, 0x8d850129, 0x7f3e219f, 0x198ee38a,
- 0xfca92ebc, 0xeed19fd0, 0xd0591930, 0xce7c465c, 0x677f2226, 0x9abf891a,
- 0x3879b511, 0xb7e9d78f, 0x84ff1e0c, 0xefe1ef58, 0x841d3fb8, 0xc52cbcfd,
- 0x2feb879a, 0x3cc0fc53, 0x19d24724, 0x2e4773cd, 0x3e7563e7, 0xa076e966,
- 0xc1347e9d, 0x8f9e3b77, 0xfd52471a, 0xcfaec3c8, 0x667cf1f2, 0xe5506c57,
- 0xaec78d33, 0x84e972e3, 0xf84419c1, 0x014b9544, 0x6f2fd609, 0xa7ff286f,
- 0x371d700f, 0x8c612d98, 0xc34ab077, 0x35ff7ed9, 0xdf1f4077, 0xcae3eaa0,
- 0x1a8ef8a8, 0x018a61f7, 0x3ecc57d7, 0xf141f152, 0x0e4e551d, 0xb1b0bfd2,
- 0x889fc42e, 0x79c7f597, 0xce3fb9fe, 0x8d79c3a3, 0xe6328e42, 0xf8237b77,
- 0xae00d6d4, 0x307fc68b, 0xff8d7cb3, 0xd9c0d560, 0xffa6bb7e, 0x4d4ed588,
- 0xd6e82bbb, 0x57ade7b4, 0x6b417034, 0x517fa6b9, 0x170347bb, 0xfd34ea87,
- 0x6af0ed47, 0x06ced2e0, 0xbb31ff4d, 0xb1f69a7c, 0xf69ac5e1, 0x1afd8771,
- 0x6ad74278, 0x3e6bff4d, 0x27da6a08, 0xb4d7af75, 0xaad3db5f, 0xb6f72781,
- 0xb94ffa6b, 0x57b4d210, 0xb4d5bfb1, 0xd75f98d7, 0xf1c62fc0, 0xeb54e778,
- 0x9b9e683f, 0x81afdf6e, 0xf1e7885f, 0x23ce199a, 0xf9c5e7da, 0x278b6f06,
- 0x3ee5987e, 0xffdf69a9, 0x8dcdc8c8, 0x47a12fc0, 0xb67fe474, 0xc53d71d5,
- 0x1d39aa1a, 0xd7bef1c4, 0xe66a1f2b, 0xbaf7d1cb, 0x7a9d8e90, 0x75f2266b,
- 0x039cf97e, 0xd0ac7640, 0xc51aa2b3, 0xc9eebb9d, 0xf48e5803, 0x6c8d5ebe,
- 0xf270d253, 0x7da39600, 0x1903575f, 0xca716533, 0xf996583b, 0x70d8d6c7,
- 0xbce7ab89, 0xe0c4e583, 0xb3941a8a, 0xb17e2660, 0x3e7dd608, 0x846d9238,
- 0xaa652575, 0xd10f5e71, 0x1d0caaed, 0xdbaaf9f1, 0x4b37142c, 0xa322d6bf,
- 0xe81cdf3e, 0xec10791a, 0xd3a7f4dc, 0x69dc62d7, 0xa1f9d83d, 0xc017b022,
- 0x59f2c7ee, 0xe043ebb0, 0xbb046d1c, 0x604dcb1f, 0x73fd63f7, 0x9c23f760,
- 0x7ad974fe, 0xc9d56e7c, 0x6172ea7b, 0xca0f11fc, 0xd7533456, 0x0e2b7539,
- 0x0fec7ac0, 0x4b28ad1a, 0xe267ae8c, 0xec8eb09c, 0x0a8eb065, 0x51078b42,
- 0x3052ecfd, 0x1c39321c, 0x2becfd07, 0x1db81a74, 0x2eb045ff, 0x97cf8b58,
- 0xaedee93e, 0xb6f9f630, 0x8a1937b3, 0x5d799f61, 0x014d6db7, 0xe6799738,
- 0xf1d3be02, 0x93fc602c, 0x09cd8f79, 0x97860c96, 0x48ff7a14, 0x2cee4972,
- 0x16b53e46, 0xeb81947d, 0x85fd50da, 0x3ce2b3a2, 0x0839cc8f, 0x787e7eeb,
- 0x23e758bc, 0xaff2aa73, 0x79cf5c66, 0xef50ef94, 0x47218cef, 0xffe853fe,
- 0x2f5c7993, 0xe5159fc3, 0x08938d93, 0x949d81b3, 0xf376f20c, 0xd1a7d5a4,
- 0x41ad90a7, 0xbb23e509, 0x144fcf08, 0x7823c828, 0x1e44fc4a, 0x537947b2,
- 0xe733e454, 0x1f3678c1, 0xf1914ed8, 0x785ac5b1, 0x19e79c33, 0x0c7ac0c3,
- 0x3282e977, 0x92f0c1ec, 0x9e605157, 0x5fb0798e, 0xb51b3780, 0x8e9165fe,
- 0x9f717d91, 0x378beeba, 0xdda76829, 0xf0f5c797, 0xecbb8096, 0x7ffa0313,
- 0x4027d94a, 0xfd8b9947, 0xabe40f92, 0x04abd1ad, 0xd2e19fa1, 0x2237efdf,
- 0x3ac5df61, 0xfd639f51, 0x27bb089a, 0xb86b8c47, 0x19bc27a4, 0x6a4abd9a,
- 0xbd06fcc4, 0x618cefe4, 0xc9e69577, 0x4666b9fc, 0x1e7786ed, 0x5f309c96,
- 0xba486366, 0x4bf1c687, 0xc2dbd40a, 0xb1ab3ebc, 0xf0085a53, 0x3a4e791d,
- 0xac9c7507, 0x08feb0c5, 0xa0e5d93c, 0xede78564, 0xc425068f, 0x55eadd83,
- 0xdae22258, 0x52bdfc4b, 0xf57db4f0, 0x864fb2c4, 0x8abdbae1, 0xa59be717,
- 0xcadf9bf2, 0x2b1f3d70, 0xbd42a9bf, 0xc33d1bf6, 0x9c6f8cfb, 0x8c5a724a,
- 0xa9a5a87d, 0x973ccf5b, 0x729267f1, 0x9e93f11e, 0x2ce2ddbc, 0xf17dfe00,
- 0xd6c34b36, 0x47767418, 0x75b3a71e, 0xe2deaa99, 0x73d749eb, 0xeafaa93c,
- 0x1fa72b1b, 0x4cad6e55, 0xce3ab0e1, 0x24f1ecca, 0x8f5a8637, 0xf98e3dad,
- 0x19bbd622, 0xfde2b1e6, 0xac2b77cc, 0x21f03788, 0xcc9f34bc, 0xe7d6e9e5,
- 0x4637e4dd, 0x3e20cfd3, 0x5c9bd100, 0x1dd97486, 0x31ba066a, 0x682a33cd,
- 0x5bfeda2f, 0x2472848b, 0x284ab593, 0xb5d96d47, 0xe7d46587, 0x1bd8afb2,
- 0x12be8ec3, 0xa9e7a83f, 0xcf8325da, 0x2abbf9cf, 0x0c0d43b2, 0xe5c9b6e9,
- 0xa9f9e1b4, 0x6474da74, 0xe22faa78, 0x3a0bd73c, 0x7aad672e, 0xd60ad3e4,
- 0xeb256549, 0xd63af2a2, 0x5987a54b, 0x99ab2c65, 0xf32d6542, 0xf98d3952,
- 0xad63aca9, 0x9d64ce54, 0x2eb3d654, 0xa3bfc12a, 0xe4accbd2, 0x7608de87,
- 0x9973960c, 0x985bca97, 0x482dca9f, 0xfef013df, 0xdbe095a1, 0xbb952759,
- 0x459dff80, 0x53311f18, 0x39e417b9, 0x3c836f96, 0xf20c32c7, 0xf8c269dc,
- 0x83ca9b88, 0x43ca8501, 0x0f2a7281, 0xefd43c07, 0xca8ea068, 0x952f01e3,
- 0x540d0227, 0xd47c0576, 0x316054ef, 0xfc05ef95, 0x581fbe54, 0x8107e54d,
- 0x12ff9520, 0x91654f58, 0xe20ae411, 0x163ddddb, 0x8f9c9afd, 0xe8271e8d,
- 0x84f34fa3, 0xfdd1ebff, 0x78f1e2f7, 0x83ba3a8e, 0x94aed5b1, 0x6e6d1e90,
- 0xe504279d, 0x74937746, 0x4eeb9437, 0x64d63b70, 0xd93b244b, 0x724abed6,
- 0xa4bbb8c2, 0x9c027d6e, 0x0fbcdeed, 0x4f4198e7, 0x6b65ed54, 0x7f841413,
- 0xe819a4ff, 0xdfc1ab70, 0x7fda15bb, 0xcebfd2f5, 0xaece8331, 0xc7f53c48,
- 0xed4c38d7, 0x66b20e93, 0xf207c02b, 0x26993f4e, 0x10a075f1, 0xc7d2fe3e,
- 0xe3e4d673, 0x791cb93a, 0x368e05d5, 0x5b0f19fa, 0xdb18cfc8, 0x0eac667e,
- 0x2dab49e0, 0x471fe865, 0xf5b8a3f4, 0xdba2fd50, 0x563ae7d5, 0x1e2337a4,
- 0xee0a7dd6, 0x65e51389, 0xcf8c58f7, 0xbbab8e45, 0xfe99f9ba, 0xf647f332,
- 0x5e332e93, 0x54e79151, 0x7403ffde, 0x86df4d1e, 0xaebf1f4b, 0x3598f8a3,
- 0xf6faf515, 0x7a772e14, 0xdb43e3b3, 0x53dbdd60, 0x9f21bc05, 0x610eb5f6,
- 0x8dbad7d8, 0x6fc764b9, 0x1d36f38f, 0xd1bff6c1, 0x69a0db29, 0x636fbc7b,
- 0x14f9c131, 0xea9759af, 0xca5ea377, 0xb1fae049, 0x9c48f1cd, 0xffff8233,
- 0xe6eee422, 0xadaebeca, 0xd7ad4fe8, 0x6e7802b1, 0x1b05fadb, 0x4bce30dc,
- 0x022ec09b, 0xc2f27938, 0x9ed0050d, 0x513741bb, 0xae1e642f, 0x0b4da5e3,
- 0xe128d95f, 0x0b5323b8, 0x213cdc61, 0x7586733f, 0x74095d8f, 0xc6d466de,
- 0x63f5fa15, 0x8597e73e, 0xd019cc30, 0x5e2239bf, 0x1ac0d5b1, 0x4166f522,
- 0x35b7973e, 0x4c34bc45, 0xd33cf1e1, 0xe3d0f888, 0x11aaffb0, 0xbe93fe3c,
- 0x9ff14cd6, 0x9e7fc774, 0xe9ed0e9c, 0x4d053a1d, 0x74b6d95a, 0x9efd018d,
- 0xf22758db, 0x3f8956e3, 0x76e6cc1f, 0xb92c1832, 0x1efc2273, 0xf2ca37b0,
- 0xf6a7e223, 0x7184a086, 0x4b11aa8c, 0xa7378c25, 0x3093ee3b, 0xe0de91fe,
- 0xe8897c93, 0xfda9f927, 0x2b9f22ae, 0x6f67d61f, 0xf735e784, 0x3c0cbeb1,
- 0x81b79857, 0x566409f2, 0xecdf3916, 0x27878e22, 0xb43d2064, 0x691ad7df,
- 0x9af8d15d, 0x991eaee5, 0x1ce07c3f, 0xccbfdba3, 0xfdb8e7e7, 0xf9029871,
- 0x1f8f1260, 0x9339789c, 0x6dd9e5ec, 0x23f41ef1, 0xb2393c4f, 0x2aa7e096,
- 0x9eff683c, 0x1a62b978, 0x9a9fb396, 0x484efd49, 0x05c630ec, 0xbb753f66,
- 0x7939f58c, 0xef1c2eb0, 0x71e891b4, 0x89f753f6, 0xc5a91fe7, 0xf05d72f6,
- 0x2e9fd0ef, 0x012d7e6f, 0x891505e3, 0x7961646f, 0x6abdd742, 0x837fcc3f,
- 0xd51afd95, 0xda4377b5, 0x3fc1d4df, 0x6b993ce6, 0x378c78c0, 0xf3ce973f,
- 0xf031e626, 0xf92f077c, 0xba3b95b7, 0x8e8b01de, 0x5bd9d75d, 0x9ebad783,
- 0x5883d65d, 0x34158756, 0x61ed59a3, 0xa72c41ef, 0xd16bf975, 0xa0fba9bc,
- 0xdd9620f5, 0xc45e7d23, 0xedffabff, 0x055e3796, 0xab63c478, 0xe68768ac,
- 0x633dde3f, 0x0d2fc51b, 0x60a1f90c, 0x8f55bf92, 0xa6f66c04, 0xf6787ca2,
- 0xfa875919, 0x8d6ae4dd, 0x4f74d843, 0x4ce30eae, 0x175a53db, 0xe20bbed3,
- 0x28f1e219, 0x8ba421e8, 0x2a6f1482, 0x25f013f2, 0x829dc39d, 0x7e294d3e,
- 0x8bd60a6b, 0x7efe8e7b, 0xd85e1cf1, 0x4e35afdf, 0xa55279a2, 0x08cdc4a0,
- 0x42ec23b4, 0x7f33b79f, 0x96c3e206, 0xf18adfe8, 0xce2a82ad, 0xd3912cff,
- 0x996f7605, 0x10508f48, 0x3fd5bd3e, 0xe6c1cf0b, 0xe01bcfeb, 0xb06a0774,
- 0x25c93edf, 0x367fee98, 0x39061c4b, 0x3fc2eb43, 0x5ba4e78c, 0x51cec9d2,
- 0x806b6fd7, 0x0eec22f1, 0x968dc7dc, 0xba54e781, 0xf5f620db, 0xe60b2884,
- 0xf5d4f1f3, 0x7ae7cc6e, 0xd4edd61d, 0x62f47ae1, 0x5d0fb03d, 0xfa227ac4,
- 0xd7fafed1, 0xd23b14cd, 0x897e6305, 0x4729cc97, 0xcea17fee, 0xd71a3713,
- 0x615fd6ff, 0xe509295c, 0x67f3ac08, 0x919927fb, 0xf1f7a34f, 0xfb88be42,
- 0xfe8cbd80, 0xe71f4cc3, 0xbf46e6df, 0x0d94fe84, 0x43bfdc61, 0xd45c60f6,
- 0x0c926966, 0x39b5fb11, 0xd99e9eb8, 0x728fdfe8, 0x82796665, 0x8b3df482,
- 0x72b5ae75, 0x0f983efe, 0xfd622beb, 0x7136167f, 0xfe7c4ec0, 0xe24ef799,
- 0x67583a91, 0xcfea3155, 0xbca5eec7, 0xcc8fcd89, 0xcfeb8c3c, 0x3fb93f74,
- 0x7ef40615, 0x3e7dce2d, 0x77656f8f, 0x87bc9ac8, 0xc9acbf2c, 0xac58c88b,
- 0xd07a076d, 0xd95d2ac0, 0xa829d5a5, 0x2509746f, 0x9da06733, 0xf923a492,
- 0x9a4a720e, 0x8d1ed31b, 0x7f812ba2, 0xcdde7cf5, 0xb373a7cf, 0xb039f859,
- 0x737cc55e, 0x7aacd8a2, 0x336f304e, 0xd03279b0, 0x3ead737d, 0x8f1fa124,
- 0xb232f1fd, 0x26f70d97, 0xada73e0e, 0x19cce706, 0xd41fa728, 0x2aaf2959,
- 0x67a0af0a, 0x94fc99fe, 0x1da8d307, 0xc53365ea, 0xabd6233d, 0xcf6b058f,
- 0x3bfd4ae3, 0x0cce7858, 0x4cfae0d7, 0xa899dcc7, 0x32973367, 0xf6e8ff3a,
- 0xe7b547a2, 0x78ef7e4a, 0x50b1a38c, 0xe79c07f8, 0x5af6c74c, 0xcfa3efb4,
- 0x9cbba555, 0xc2f5b161, 0x2f5c0523, 0xa72824e4, 0x90aec8ea, 0x66f04ec9,
- 0xfd23c3cb, 0xb9f2efa4, 0x57e5301f, 0xec43d216, 0x1f087363, 0x3f5dc255,
- 0xa8738629, 0xfba1d3ee, 0x7e3ddec2, 0x5099e9e0, 0x7bf5fd4e, 0xdfa0c74d,
- 0xe32cefd4, 0xeb377eb0, 0xa081819e, 0xf90361e0, 0x7cbe6b8d, 0x440315a5,
- 0x414c8dcd, 0xe3ceabbd, 0x6efae028, 0x25e4218f, 0xb32c5af9, 0xd907246d,
- 0xf4114bc5, 0xe89e9002, 0x6f31b787, 0x91f92b63, 0x8612fcb6, 0xaccd3c79,
- 0x97d20ef3, 0xe30c8d67, 0x383637af, 0xffb0550d, 0x869d1b1b, 0x219f78f9,
- 0x23b43ab3, 0xa8506a6e, 0x8546a6fe, 0xfd799bd7, 0xd50f06dc, 0xf0f46dcf,
- 0x5bd40b7a, 0xd4290f30, 0x6f718015, 0x753aa4b6, 0xe8d01f78, 0x4c17ede5,
- 0xfc1c7ed4, 0x8c27cc01, 0xbc910b8f, 0xf1d1ed6f, 0x7c7f237b, 0x9ab58248,
- 0x3b0ecb12, 0xe8f77f11, 0xcc175014, 0x2b332d94, 0x7836cfc0, 0x7f687a43,
- 0x1032858e, 0x3617bb91, 0x7ea10b79, 0xe2b643b7, 0x7b8376fe, 0xc147f98b,
- 0x9de132a5, 0xbdde00fe, 0x3af741d8, 0x3efc455b, 0xf14cc4b8, 0x2875b066,
- 0x6496ccde, 0xb7863b0a, 0x86b02c77, 0x39031ed0, 0x7bd8e748, 0x00764c8f,
- 0x6ea3c3c8, 0xe6768bb4, 0xca9f182b, 0xb7e5aa5c, 0xaa0b85f4, 0x6646bc68,
- 0xbebd3f45, 0xbcd78f91, 0xa1d21753, 0x71b9655d, 0xf341d226, 0x3fa0a60e,
- 0x53c2ecfb, 0xee10c3b5, 0x3f2e1450, 0x79a172b4, 0x9c4753e1, 0xcebf1fb8,
- 0x79fd405a, 0x5fd9af1c, 0x0d2f5dbd, 0xb79d33f0, 0x0c7e4073, 0x61ca3796,
- 0x5e63271c, 0xc1f182b5, 0xc627d874, 0xbc8c3bf3, 0x4ca7783e, 0x0be92df7,
- 0xf475b0e5, 0x0b677f00, 0x1f23a614, 0xd17c9126, 0x9dc8d7f0, 0xc179f85a,
- 0x32efc0a7, 0x9db82bee, 0xd1673e51, 0x903f6d76, 0x57943a93, 0xfadaedd9,
- 0xe3fa8b5b, 0x443c1a02, 0xe7e6d9e3, 0x9f7a2f72, 0xc70afb03, 0x74bed115,
- 0xd7285f7c, 0x72d8bea0, 0x1b8bea80, 0x44e9c565, 0x0a79d779, 0x53b45ff7,
- 0xeb806166, 0x44cd9617, 0xa4dfaa7a, 0xf5c8f0a3, 0xc2e48bac, 0xc6adf695,
- 0x19f7a23b, 0xf2efbfbd, 0xa88e5cf5, 0x6613e0f6, 0x1edb07b2, 0x9ef0e8b6,
- 0x78adec15, 0x55dc2b8c, 0x402c1d54, 0x1dc8407b, 0x973d25c3, 0xa216cd27,
- 0x51ed8353, 0xa1fc6477, 0x13f55465, 0xd86fd405, 0x6e3c758d, 0x968efb41,
- 0xe3173f63, 0xe6d6ea4d, 0x13db5de3, 0xa63f951f, 0x729bc7cd, 0x7f2a3321,
- 0x7f2a2f2c, 0x7da6946c, 0x545c75aa, 0x51b5d8fe, 0x1a3563f9, 0x967b9678,
- 0xcaf5ffa6, 0x86f81a4d, 0xfd343bf2, 0xd6ee78e7, 0x7754dfb4, 0x66fda6bf,
- 0x7c0d4aef, 0x6b5fc36b, 0x6be6dffa, 0xb1dfb4d6, 0xf69a27f8, 0x2d49ff68,
- 0xf9701577, 0x3feed9be, 0xd06c0149, 0x3df791f7, 0x28de996a, 0x7b9e46f7,
- 0xa7b70252, 0xb9fdfba2, 0x8bfbd380, 0x058f9f12, 0x1c789aed, 0xf135d8f3,
- 0x854570ba, 0x71c61bb9, 0x21df951a, 0x0ee262dd, 0x6bb6bfbf, 0x3ff6d9ee,
- 0xbc60fd0e, 0x1b5cc4a6, 0xff8c3bea, 0x37b940fa, 0x5f747487, 0x4abf5b61,
- 0x69b83d22, 0x5cab8f15, 0xaf3c5230, 0x8eac1d7f, 0xdc46fbc6, 0xeceba96b,
- 0x2da47110, 0x85424718, 0xfd4199e4, 0x7ef1c656, 0xe3574d3f, 0x371a3e8e,
- 0xa418dca3, 0x7e85bcfc, 0xcdc0e309, 0x7bc5663e, 0x02cb7493, 0x069bff9a,
- 0x265d9925, 0xb016da2e, 0x67cc0f33, 0x635c155f, 0x527dbd84, 0xb3d4f7d0,
- 0xcfddbcf0, 0x5bd31e28, 0x1853edf0, 0xe143e98f, 0x219d7408, 0xf73f3c73,
- 0x5fcfeec0, 0xe6daf981, 0x5ca197a5, 0x5acf6e8d, 0x43ebf7be, 0x6e7f6997,
- 0xde1f5bd9, 0x1fe7b97b, 0x25ba75d8, 0x38c87da2, 0xf3264369, 0xe001d044,
- 0x80fde62c, 0xf9f5c85c, 0xc5230af2, 0xfc01aeb1, 0xbfbe0215, 0x89cff8aa,
- 0x3fb9e03b, 0x44eefb39, 0x65ea1d3b, 0x847e87ac, 0x9fe53fd7, 0x9c92fca3,
- 0xa3df6051, 0x9b171dfd, 0x7215c76e, 0x8d6d95ba, 0x6a0718bd, 0xd13a344a,
- 0xbb32cfcf, 0x07193eca, 0x7ee06d74, 0xfeffb475, 0xddbfbf5c, 0x9177fe49,
- 0x944b2718, 0x9e7f2b7a, 0x4e4c8399, 0x3114f717, 0x6a4fa1f0, 0x655e5097,
- 0x8d3f942e, 0x89fd8be4, 0xa4238a46, 0xc1dc445b, 0x171358b2, 0xfb06e350,
- 0x9095ef13, 0x4bc3d3ee, 0xf18f9e28, 0x5c6f1c02, 0x11d693a1, 0x32c82f1d,
- 0x86bad3e7, 0xd7f59f1e, 0xe6314827, 0x1a875a89, 0x279e889f, 0xea04f684,
- 0x64f16599, 0x7bef444f, 0x79556149, 0xd7e470e1, 0x51d393de, 0x90329f7e,
- 0x5e8a1c3e, 0x143ccf30, 0x42b4fe31, 0xfe63dfee, 0xe63d6478, 0xe3228787,
- 0xef41ccd9, 0x2a0c102b, 0x7bb18466, 0x77ce1143, 0xc277cf94, 0x1ec9d8a0,
- 0xfe87b504, 0xd7217d5f, 0x9730d303, 0x19f2386d, 0x81dbcbf7, 0x12dcb1af,
- 0xd67d92b0, 0xf087fc01, 0x9527010b, 0xca9b80a1, 0xda85016d, 0x09ca07b7,
- 0x21e0257e, 0x8ea04778, 0x5e02d7ca, 0x6819dfaa, 0x01e7f820, 0x819d951f,
- 0x46ff54c5, 0x9bf04fc0, 0xbf04d581, 0x0160f685, 0x53d7a9c6, 0x4ad03bb9,
- 0xed037bed, 0x081dbf04, 0xec0e1951, 0x8103faa0, 0x060f824e, 0x287c1176,
- 0x70f82610, 0x479530e0, 0x7f545d03, 0xc101f03c, 0xc93ee337, 0x15df58ae,
- 0x4f8578c0, 0xf77da276, 0x15a16fac, 0x7cfb6bed, 0x79c5159d, 0x04b74fbb,
- 0x8d1d1ce3, 0xef131efc, 0x040e3123, 0xed086876, 0x67fcfb39, 0xf6a54c8e,
- 0x19bed4b9, 0xc4a70487, 0xafdb82b6, 0xfa91996c, 0x0a2130d9, 0xda58eb9e,
- 0xdc03d218, 0xed4f185a, 0xf93215b6, 0xfce9cf6d, 0xeedc8529, 0x336df922,
- 0xa541fb70, 0x5c853583, 0xe429aede, 0x161f5cf7, 0xca4a73f1, 0x9e47ad8b,
- 0xa6ed542d, 0x7f7187f5, 0x3fb079f6, 0x55bcef5c, 0xb597bc66, 0x72b3a3dd,
- 0xcbdf937b, 0xb8bf603a, 0xc50f587e, 0x6e7cd985, 0xade6db2f, 0xe63975a5,
- 0xd6ed48df, 0xd05347a2, 0xaff76f4f, 0x6deb439a, 0xd9ae2994, 0x82903bee,
- 0x89cf6cf7, 0xf0db277c, 0x64a86f78, 0x8d9e7af0, 0xe3077f5a, 0xec03837e,
- 0xec63d7a5, 0x496ed303, 0xc71130cf, 0x331cd47b, 0xe829d78e, 0xfe7121d7,
- 0xc4ca0f63, 0xb0302f7f, 0x2db9e0fb, 0x5105df60, 0xb6bf540e, 0xbd55e302,
- 0x289dbe85, 0x8e779f37, 0x9c03203f, 0xcfc7c75a, 0x82bf255d, 0xf79c3476,
- 0xbf502de7, 0x5e4dbee1, 0x4db0ea5c, 0x6ec835ce, 0xcadff3ed, 0x4397f8c0,
- 0x5a8f9ed2, 0xf9f62dbe, 0xb78f8782, 0xf14c9565, 0x378adb64, 0xbcf9075d,
- 0x33ff91bb, 0xc38a3e8b, 0x5cde4c30, 0x86450ea7, 0x35fc9e63, 0xff7717ce,
- 0xcd423aa6, 0xdf3a8f26, 0x6aef9c58, 0xb1e234f1, 0xc62f9b5a, 0x279286ba,
- 0xbf239257, 0x81ef1429, 0x942cb164, 0xb819cf23, 0xe49e0adc, 0x052524f6,
- 0x8f3c1a4d, 0xe6a02f9a, 0x0be7440f, 0x29e05efc, 0xde62c4cb, 0x4fd67ee7,
- 0xd73a41bf, 0xbd1b3c17, 0x92e36794, 0x35874931, 0x7a12d819, 0xde2aa7ef,
- 0x3d0626ba, 0x2853e5a8, 0x1fc100c7, 0x2e713216, 0x38f8ea9b, 0x64ce3e3a,
- 0x2ae082b6, 0x4318358b, 0x33e5ab5e, 0x2b7f9c62, 0x759b74e4, 0x870dcedf,
- 0x1a8f7cf0, 0x8b6a3728, 0xfd01b42e, 0x3d09e084, 0x7d4cd7c9, 0x2257d6e7,
- 0x4117f5d6, 0xa18c5b9f, 0x6e87bc62, 0x504af187, 0x94bf22ae, 0xd582fc50,
- 0x7d5de047, 0x1d843fee, 0x75c5fcf0, 0x3cff7429, 0xda1c6d6f, 0x4ccced47,
- 0xf83360f4, 0xd046c653, 0x32e90d83, 0x8b387d06, 0xfc0e348c, 0xe226aa59,
- 0xcbd70cbd, 0x60972835, 0x2616fbdd, 0x99ac3e91, 0x31acdeff, 0xc9f65700,
- 0x65b2cf94, 0x9cd3cf29, 0xca3aeff4, 0x31fb7913, 0xf75df7ee, 0x9fbd2d50,
- 0x67ca2194, 0xb283cfd1, 0xc2533d72, 0x0b952e70, 0x99bf142d, 0x133e417c,
- 0x4851a7e9, 0x17fa3c7a, 0x6d735e3c, 0x0f79acaf, 0xb68f526d, 0x8f54603f,
- 0xb7464676, 0xef3edeb6, 0x6153d3cd, 0xfca5f69e, 0xbf8bf6e1, 0x7070823b,
- 0x24e28e95, 0x5064fbea, 0x4df14193, 0xf9819839, 0x8ccc1b9b, 0xbe6db9e4,
- 0x60f28ad9, 0xc93c7a7f, 0x2cdbf6bf, 0xcbae8764, 0x3b438a6f, 0x556f34d9,
- 0x8c23960a, 0x3b18adc1, 0x2dd5e6bd, 0x9127d937, 0x55f355bc, 0xec1cac82,
- 0xdc8dbb81, 0xf73e09c8, 0xe51954f4, 0x9967cf25, 0xa796eaf4, 0xadd8f983,
- 0xd4e1d695, 0xf9be4cb1, 0xba76f87e, 0xbeb896b7, 0x1da11a70, 0x7ca379e0,
- 0x7b4115d7, 0x3f705a46, 0x9cb66d36, 0x6b7ca469, 0xf982324c, 0xccfd0b0d,
- 0x658df588, 0x573e48e6, 0xf2fbe4f9, 0x87c63c7f, 0x0e595f87, 0x2bdc695c,
- 0x3e417bf1, 0xfca19be7, 0xf210d369, 0x1f8ff554, 0x8bfce029, 0xf57a4b6c,
- 0x7da6318c, 0xce22abf5, 0x9e46e567, 0x61bb32a7, 0xc3dd1d5a, 0xcc65bb04,
- 0xdc517be7, 0x27a7b50b, 0x7b713dd2, 0xbde30b2e, 0x8e817041, 0xf8d27bc7,
- 0xb98ded7f, 0x936a1f14, 0x3cc129fc, 0xb9f097cc, 0x01dafcf0, 0x7f308947,
- 0xeb970e5b, 0xe2b7e42c, 0xb38c357d, 0xe0fd7238, 0x74b505ef, 0xa61ec8cc,
- 0x789e85f8, 0x888c69cf, 0x1c5c63b7, 0xcfd117e3, 0xc2d5ee4d, 0xe1682e53,
- 0xc0d0662a, 0x3c2d6635, 0x3785aad5, 0x7d3b7115, 0x3f5b5dba, 0x1d85a9c3,
- 0x74e307d9, 0xc2dfcf3c, 0xf049e222, 0x447e5ef7, 0x68dd681c, 0x765f3efe,
- 0xcb8a52f7, 0x78f0e5b6, 0x3695638f, 0x42c591ce, 0x732fe212, 0xd63c5469,
- 0x863f66bd, 0xa30bed97, 0x5efc41e3, 0xa9a1f002, 0x7c8a3147, 0x9e68eaf0,
- 0xd23dde87, 0xce08bdb7, 0x5f0c60b3, 0x4d1dabc7, 0xdac53f74, 0x5caf88d3,
- 0xb0695f22, 0xe88a7cbe, 0xf90f1d40, 0x7fb11822, 0xf84887e4, 0x37be51a1,
- 0x8be41e70, 0x2cfea460, 0xfbd036e9, 0xa1be62ab, 0xcfe543f8, 0xa28f7172,
- 0x89f4dde6, 0x9bbcd4b1, 0x705f2255, 0x4ebe5457, 0x1936a39f, 0xaebee7fd,
- 0xf8b1f195, 0x682ef910, 0xe5887ce2, 0x837f9106, 0xe22c187c, 0xa6f5887c,
- 0x637856ef, 0x050b8bd9, 0x63bfdc5d, 0x224f86c9, 0x73acb7f6, 0xbe5e0685,
- 0x910de1eb, 0xe3f751f9, 0xbf08303f, 0xed7e519e, 0x2f9db152, 0x2bcbff4f,
- 0x48cd0ccd, 0xcf2807df, 0x319c1596, 0x5ea77bf2, 0x42eb9e23, 0xcc99ff61,
- 0x2fd1f2b3, 0xf2e211db, 0x37889d6c, 0x33155b34, 0x3b9981c6, 0x50c71355,
- 0x4b4d11e3, 0xd854b65c, 0x7c7f7247, 0x7ca56bc1, 0x14f9e1dc, 0xf1aa48df,
- 0x32c6cedc, 0x9c6453d6, 0xdd62066b, 0xc056c18e, 0xd957f9e9, 0xc0c74133,
- 0xf8174dbe, 0xb0fdc97b, 0x8f2467ec, 0xea68e42e, 0xa39c44db, 0x0b2dbf9f,
- 0x8b3e70aa, 0xb0fb49db, 0x1e1aff31, 0xd1c6d417, 0xe73de24c, 0x343be3c1,
- 0x7e226df5, 0xb5f1e572, 0x85d33971, 0x2fc621bc, 0x1adf1a8c, 0x7181fc73,
- 0xabbdf1b5, 0x714f37b8, 0x2e3a184f, 0xe9cdd236, 0xdfdd9d69, 0x83317185,
- 0x06667fe0, 0xf288993a, 0xe3e9ff80, 0xc1ae7e79, 0x198f8da1, 0xfa0baf30,
- 0x98b8973f, 0x3efa8ae4, 0x0599fdb5, 0x27cbca12, 0xa4e8fdf0, 0x5a24f2c1,
- 0xde44d88e, 0x811cb47c, 0xd37034f9, 0x36cf5cc3, 0xe50f8a4b, 0xfe7ef473,
- 0x7587f17f, 0xc8bbe389, 0x778eceae, 0x0f632e9a, 0x638205b7, 0xf175b9f1,
- 0x0778c5fe, 0x918ef77e, 0xe3944f69, 0xf88ceb7b, 0x298ec56c, 0xb60f3173,
- 0x13ebf04d, 0xa7a23a69, 0xb7d3dbf4, 0x29e823ea, 0xa173e8dd, 0x13ae9c3d,
- 0x87f85ff9, 0xd227b471, 0x318c6db7, 0xa9d76abf, 0xd601adb0, 0x6d8e7111,
- 0x9fee9ec2, 0xadcc8eef, 0xd27188fa, 0x34b1be4d, 0xa3fe7f5f, 0x87e5af98,
- 0xc459b7cd, 0x6cf9d4c3, 0x67f76a77, 0x7f69fa33, 0xd487a136, 0xfee336f9,
- 0x15d5f062, 0x75fe13e7, 0x69777cff, 0xf93367f7, 0xf5367f69, 0x7cea1b3b,
- 0x3e6c3f2d, 0x76cfe0bb, 0x3d97def1, 0x64377f9e, 0x9a23f7a8, 0xbdccf3fb,
- 0xed2f9466, 0xe850bc6a, 0xfa5173bb, 0x3be849ae, 0x6973f9f5, 0x3dff14b9,
- 0x7326f877, 0xfa873d2c, 0x933b098d, 0x09933b09, 0xd9e1133b, 0x0d57a735,
- 0xbbfc7a07, 0x95cf371d, 0xbecfaf41, 0x1cf8f4ff, 0xf1d9df80, 0xe832b98b,
- 0x9eafd9a9, 0x1e0b337e, 0xfbdbfe29, 0xe9f4fc38, 0x5bb4073e, 0xadcccf82,
- 0x18693805, 0xbaeacfd7, 0xb97779d5, 0x7cb95db9, 0x6f8f1e75, 0x3d459c82,
- 0x67e39cd6, 0xcafc7f18, 0x1f349bd1, 0xeecf2ffa, 0x03105f4d, 0x7cb96a2f,
- 0x1e7f2175, 0x9889c0ad, 0xaf48c6cf, 0xc7bea8dd, 0x8f7da752, 0x23692925,
- 0x2c7187d9, 0x96394564, 0xfbd0f660, 0x7316d797, 0x533370bd, 0xe15fb81a,
- 0x1c79102c, 0x4dcbdef4, 0x6b5c62e5, 0xfdb12fe5, 0x09e79d66, 0x79ff77f4,
- 0x68e1bcd2, 0x7379ab3e, 0x3bde06a3, 0xde7dfedd, 0xb1fd9e4f, 0x64e56dc4,
- 0x36998f1e, 0x7bdfc9ca, 0xa22b888b, 0x3e143c5d, 0xff73753f, 0x1e9f007e,
- 0x0f54cf8e, 0x37b5a7c7, 0xff9c0d69, 0xf4de94f2, 0xc34f89c7, 0x0835f131,
- 0xfbf851af, 0x7ea99b93, 0x88ed1ea0, 0xc55be12b, 0xd85f9aab, 0xc80b392c,
- 0x9a19675e, 0x14c660fc, 0x1e7bac67, 0x3d48cfa4, 0x197bb46b, 0x3486a3da,
- 0xeff98dc5, 0xc7d17fcd, 0x1573dbcc, 0x525ef88b, 0x367de53c, 0x1fc91927,
- 0x93349fdf, 0xb659fc61, 0xd4bc234c, 0x3e51d526, 0xeb187ea6, 0x3a357f44,
- 0x7c9f5d0f, 0xe909e53b, 0x4061e86d, 0xecc79fd9, 0xe95f2331, 0x5d92563f,
- 0x99570048, 0x295f2e87, 0x26753d0f, 0x324f43cf, 0xd85e313a, 0x998c689e,
- 0x9badfe87, 0x71fb5dfb, 0x1fb8697f, 0x886eff23, 0xe56c97d8, 0x9f58eef7,
- 0xab46f500, 0x5dfc518f, 0x615bffec, 0x4dfda907, 0xf9433f56, 0x4e2a37a0,
- 0xa9f45fb4, 0x77e07f5c, 0xe231dc5b, 0x0dbb5f28, 0xa3fdfcf4, 0x99cf5cac,
- 0xfb3eddb9, 0x27dfb137, 0x44962b28, 0xdd3624bc, 0x3737450d, 0x9dde78ea,
- 0x2d7397ca, 0x9c07ca46, 0xf7d3b16b, 0x2102e66c, 0xf446a4f6, 0xfe56eebf,
- 0xd8acb53e, 0x7b7e9e91, 0xfe5f94ed, 0x00b5e196, 0x66a7db97, 0xc2bde818,
- 0x28f31253, 0x5df383a9, 0xa994debd, 0xea1bccb8, 0x7645af4f, 0xc8c3182c,
- 0xc1757a4e, 0x4e95ad43, 0x8aea8ff2, 0x737d9e91, 0x770fa2a6, 0x77d8c363,
- 0x04f2ffb1, 0xfbd5cf2e, 0xfc09e5a5, 0x646bde7d, 0xffec6cdf, 0x4917c555,
- 0x725f48d5, 0x2bae0e6f, 0x33dd3fa2, 0x5b9ff445, 0xcffa813c, 0xf5ddafe6,
- 0xce3977d2, 0xc8f99da5, 0xec7ce8c7, 0xf429ecb1, 0xbde458b7, 0xe81f9086,
- 0xa3d64577, 0xce22c5bf, 0x6e505a53, 0x4f218eeb, 0x3ec332d4, 0xa042e46e,
- 0xb18c8cd7, 0xcff5aa54, 0xa175f47a, 0x90fce718, 0xec1fe738, 0x6ac3b4f7,
- 0x3df80e27, 0x843cefe0, 0xe172f8f8, 0xb0f1f4a9, 0xbf6a07a5, 0x6ec7bf26,
- 0x16ceffec, 0xb00371f9, 0x2db3bef6, 0xdf8c5bd0, 0x87886019, 0x8bf91189,
- 0x25f6bf62, 0xefd0526b, 0x20f4b381, 0xbc0476dd, 0x030d6b23, 0xe42cbfcf,
- 0xd2160b08, 0x2eb106f3, 0x0ceb5a47, 0x2c38bb8c, 0x6073ca3a, 0x6791aacc,
- 0xa6536a73, 0xbb0ba1a6, 0x2716299c, 0xe45df7fa, 0xfbe06417, 0x7c9f180d,
- 0xf78636e7, 0x9d69595f, 0xfd75da12, 0xc6f788f3, 0xe17b8957, 0xed2d5f3e,
- 0xefd6c327, 0x5ff23197, 0x507382d3, 0xc33df56e, 0x92f19457, 0xc691ddb6,
- 0x5dee1ff3, 0x02721f18, 0xed2d67bd, 0xb04f4fc2, 0x30f8700c, 0xa9719fa6,
- 0x7282d5d9, 0x140957e6, 0xe7b7d677, 0xfbc820b3, 0x1bfbecb0, 0xf9c877c2,
- 0x6c4f2e90, 0xb65b9e16, 0xb9ec9e28, 0x0675a976, 0xe8f731f9, 0xd178ac58,
- 0xa7ee62ce, 0x2b628ffc, 0x4fb5cfbf, 0x1f63f4e4, 0xb8e1723f, 0x77ffe7ab,
- 0x49f99e84, 0x7fde93b2, 0x4da3ed52, 0x8e47f843, 0x5f213a91, 0xf8115e84,
- 0x199f3333, 0x792f45f9, 0xc774b079, 0x96bdaf6b, 0x5b53e8ce, 0x841b4748,
- 0x138ea3fd, 0xc6a21f9f, 0xf243c578, 0xb87ab252, 0xedfab0be, 0x75af3841,
- 0xce63e9df, 0xfba085ff, 0xd90fd935, 0xd3ad7fb1, 0xfa32c6e7, 0x9c96983d,
- 0x3e78dd7b, 0xe9fb332d, 0x96baec95, 0x61dfce33, 0x28f0563e, 0x9fd837cf,
- 0xefc3685d, 0x1b0e5941, 0xe265d364, 0x27d046f1, 0x19d8cbce, 0xdeaf9146,
- 0x99e78072, 0xbaca58b6, 0xc5a1af30, 0x6a465692, 0x56f3c2d8, 0xcb16fed5,
- 0x1607d221, 0x5adfdf85, 0xb8487f50, 0x0947c04c, 0xe110ebae, 0x5077ed43,
- 0x128b5dc8, 0x5a5ef866, 0xfd4ad29c, 0x83d7b2cc, 0x34e6ca79, 0x6644f746,
- 0xe217f02b, 0xccc75f35, 0xbec9f431, 0x5a4fae62, 0xaabaca4a, 0x7e327d69,
- 0xd8b58eb9, 0xe7a4eccb, 0x7cf0ef11, 0xcf968673, 0x577813bf, 0xf91669c7,
- 0x4eae77b4, 0xc38ed609, 0x1bf79338, 0xcb16e7a4, 0xf5107302, 0xcbf8e25a,
- 0x391a678e, 0xd7fb78d4, 0x43bef18a, 0x2c4fae79, 0x0678e2b3, 0x8d15f7c6,
- 0x9c62e1f7, 0x7bfbd5ff, 0x47bd2cc0, 0x581d304d, 0x7deb1ed8, 0x13f3feac,
- 0xcfd1f2f7, 0xbc7960fd, 0x02871b56, 0x091eec79, 0x72565afb, 0xd53550e6,
- 0x0bd3f8f0, 0xfd519fc2, 0xf6317492, 0xbf7f120b, 0x2bc5283f, 0xe10c5df4,
- 0x69c7a4a7, 0x3ef030f1, 0x6f873f2d, 0xde1e781a, 0x7c4c6937, 0xd7cb4e87,
- 0x38ff1cdf, 0x059f9345, 0x7131ec7c, 0xde23c63f, 0x3888f5a7, 0x6f18c21d,
- 0x049d17a0, 0x89c7f7ff, 0xc33f9c1b, 0x4099acef, 0x5c60eb8e, 0xfa27e1c9,
- 0x5dba3936, 0xe239efc8, 0x78d10ffb, 0x2e48c9fe, 0x7a47a5af, 0x51af785c,
- 0x119bd69b, 0x7c5fdf8b, 0xee0642f8, 0xfd19c5e7, 0xdf743b79, 0xe769e2f4,
- 0xcbc402e6, 0x6ffbed11, 0x474df8ea, 0x22f8a7ce, 0xe5c0a5fd, 0x3a4b2fdf,
- 0xd92571b3, 0xddb80b8d, 0x7dfa7ff8, 0x73e617b3, 0xa497753b, 0x084fcf95,
- 0xfc141cb9, 0xd320bb60, 0x2aee43f7, 0x3a40adf2, 0x0bac936a, 0x3ce72e50,
- 0x9af2f3cc, 0xb3d55b1e, 0xb47f0628, 0xd5fdf28c, 0xbabf08c8, 0xe491bd7c,
- 0x3725b35e, 0x28f772f9, 0x9fbb9f43, 0xde7a94e4, 0x79988f55, 0xdb8f8abe,
- 0x7bbee9d1, 0x3a260f29, 0x7ea8653f, 0x449d23d5, 0x137f6a0f, 0xc5f28f8e,
- 0x15c52372, 0x818fa1ce, 0xb72b3b71, 0x59d7a233, 0xc098c889, 0x7d0663f1,
- 0x49607499, 0x106b8e1c, 0x6a0bdcfe, 0xcca1a45c, 0xde7889ec, 0xb9995b70,
- 0x9a4e823a, 0x8e0fcf19, 0x2337ff1e, 0xac22fb55, 0xa80c63b1, 0x94c6317f,
- 0x97ed9f26, 0xf278643b, 0x0395b4fc, 0x0ee3cc7c, 0xc5a3e743, 0x232dbe71,
- 0xf30dac7b, 0x5e0ec0d2, 0x0460b0d3, 0xf64db7e2, 0x3c0368bd, 0xa2687ef4,
- 0x0bdfea3c, 0x7c16ed3e, 0x05f9d43a, 0xd23001d9, 0x1d9c7b18, 0x80e297c4,
- 0x2327c64e, 0xebe7345f, 0xf63142ea, 0xf3ec5c79, 0x7878f632, 0xc7b3f7e4,
- 0x1afe890f, 0x6ded1c7b, 0x46fdd44f, 0xb6768c24, 0x7e3d8627, 0x05f11242,
- 0xc2742791, 0x0dd5dce0, 0x39313978, 0x5697be99, 0x5defc090, 0x527fa04e,
- 0xabc87e06, 0x7ed1f3a7, 0x7ff52d99, 0x43f84917, 0x47f0608c, 0x62f905fe,
- 0xb6bff30e, 0xe23e2248, 0x1b7835f7, 0x73e57e9f, 0xd19236de, 0xf9c036ba,
- 0xdb46fde1, 0x6233f9c5, 0x8ea467dd, 0x5037fd52, 0x13ef1165, 0x889d3c33,
- 0xf741acfb, 0x72f75174, 0x9fd36d78, 0xdc1fac77, 0xed7286ff, 0x8b86d9bd,
- 0x5a622e3c, 0x4b8f42c2, 0x6daa9798, 0x10cea9bf, 0xb9a82f7d, 0x6bd9bb4f,
- 0x7d0f5e88, 0xd621d417, 0x1f71dd9b, 0xcd4fbfdd, 0xa644f9e6, 0x04e28c65,
- 0xa66df7d1, 0x3d1e5db1, 0x8c0dcfda, 0x38e8fdec, 0x52a9e639, 0xb181b0fc,
- 0x79e5122d, 0x7973df6b, 0xfe73fea6, 0x3ad6947d, 0x760ec79c, 0xd1d3da10,
- 0xf7a849ef, 0x51f7ea5a, 0xdfab3c55, 0x4dbf4a8f, 0xc163eb47, 0xc6aed429,
- 0xb87bf1fd, 0xf911e955, 0x7f582be4, 0x2b7f7a7f, 0x9bdf7b18, 0xcf29eadb,
- 0x7fbc7320, 0xb29a186c, 0xc8784614, 0x6fc8c85a, 0xf2683c00, 0xdbd94c09,
- 0x16e79f69, 0x224c3633, 0x33da683c, 0xfdd3d340, 0x7e6d42c0, 0x0353ec01,
- 0x57abfb47, 0xd94d53f2, 0xf39597f9, 0x9a638a57, 0x94e4bdc4, 0x97fbe251,
- 0xed14aca5, 0x9edbf4a2, 0x0738f3a1, 0x5f7181e7, 0xdd629c74, 0xf1826e3b,
- 0x77fc8fd1, 0xe2cd2fc1, 0xaefd5b6e, 0xf4c8f30f, 0xce549b1e, 0xf30d2cd7,
- 0x12e97bf2, 0x8a6e7c46, 0x8fcc6667, 0x1e4c2a97, 0x04c9bbc4, 0x32596c30,
- 0xd4067332, 0x7b3c45eb, 0x8464c48d, 0xf3315599, 0x5dfaa3f8, 0x577d10a1,
- 0xd479a868, 0x20b22bef, 0x679d4e7f, 0x2ef577d0, 0x7bf93cf3, 0x6be7e8d6,
- 0xcea99e29, 0x87fe143f, 0xbfde8efa, 0x8137bcd5, 0x441d53c7, 0xf4038daf,
- 0x417cf04a, 0xca3cf88f, 0x66d5bb85, 0xfa29577b, 0x4c1e670f, 0x114a3650,
- 0xd2ce08fb, 0x7e03eff3, 0xd7faf1bf, 0xbc927761, 0x1897dfef, 0x8beefbef,
- 0xdae422fe, 0x09597c3a, 0x191a5ef3, 0xfba431e5, 0x29973faa, 0xa0f600ff,
- 0xdf111391, 0xd6f18049, 0x1fefce3d, 0x3e77e336, 0xc0e7fef0, 0x13edfe40,
- 0xd1f76c16, 0xbcd43677, 0x5da3cc5c, 0x3ef0325b, 0x837df472, 0x89c611bd,
- 0x99b26f98, 0x9f401305, 0x0531f4a4, 0xb9ecf3bf, 0x03a65468, 0xa07d6c7e,
- 0x93bf0150, 0xa5ee8999, 0x337ead2a, 0x0ae10eff, 0xef676916, 0xefa56e97,
- 0x64bf86bd, 0x3e14bf94, 0xc3ee88cf, 0x70c4c39f, 0xddf8ff2e, 0xcbe47afb,
- 0x7a5d7da9, 0xfb93f3d4, 0xf67fa4fc, 0xed3d4fd9, 0x9962e7e2, 0x751f9111,
- 0xcf545b1d, 0x979f8ae9, 0x5f27ea2c, 0xfdf86a30, 0x46a35eda, 0x5b17c81e,
- 0x65fd46be, 0x67aa89ea, 0xe3e33fd3, 0x2dde28f9, 0x53edb5db, 0xdbd03e44,
- 0xc35fdf2a, 0xbc73a1ae, 0xcf331698, 0xd5dce06e, 0x71e26e73, 0x79c7c674,
- 0x9ff7946e, 0xff404d46, 0xe87147c0, 0xd82fc464, 0xdd952917, 0x58798ecc,
- 0x8e994ce5, 0xf3b2bd72, 0xe487a41d, 0x3c0f3cb3, 0x5ffdfc7a, 0x7e8595be,
- 0x9dc99ec3, 0xed2f6859, 0x3d15f2f9, 0xd3d5578e, 0x193eb0cb, 0x58a41e4a,
- 0x10aa784c, 0xcf5033b4, 0xf59144e3, 0xe74a9eb4, 0xcfe4e565, 0x871a4e50,
- 0xd933df6e, 0x87e4c2c2, 0x3da02675, 0xfe7c7cc7, 0x57cab364, 0x70972fec,
- 0x9f81845e, 0x52ea54f6, 0x7b9f616a, 0x6c15919e, 0x46f3d3dc, 0xe7bfce02,
- 0x7acd39ec, 0xf322fe98, 0x5afbac45, 0x2b53ee71, 0x7efec97b, 0xf92bac4a,
- 0xa1c52f6c, 0x30de9553, 0xc3d4dbea, 0x37fefa7a, 0xc8bcf0b3, 0x38a14c61,
- 0xfc5eba9a, 0xd73e2a6e, 0x88de7282, 0x5632b3fb, 0x287eec28, 0x55832a33,
- 0xcc9a8f98, 0x6b484a76, 0x417d2b53, 0xa5e4e7a4, 0xad939e9c, 0xbf18c3fe,
- 0xa3af5e4f, 0x59f24538, 0xcbf406df, 0x0565cb92, 0xf84ae4c9, 0xb7f310ec,
- 0xf9d4f98a, 0xa88cf5d5, 0x7ee84bf4, 0x62e3b324, 0x132aaefe, 0xcc5abf8e,
- 0x59eb14ef, 0x2c3be8c5, 0x55ad67c9, 0x83272fe8, 0x33df419d, 0x9a79e2b8,
- 0xb745f335, 0x99d94f27, 0xb1e0e745, 0xe30ad91e, 0x365b64a5, 0xceb94154,
- 0x32ff23a1, 0x3c5187a9, 0x9d27a93d, 0x4f527de4, 0x8a2728a1, 0x0f4269fa,
- 0xd4933970, 0xaf2d50f3, 0xa4d2a16f, 0x3f8717ca, 0xda98fb8c, 0x717cb8cb,
- 0x98be4978, 0x517cb8d2, 0x9556b8e9, 0x325acc2b, 0x0ff7ea1f, 0x06b5acff,
- 0x73f77b9e, 0xbbe5fefe, 0xbcbe5cd9, 0xfbf725fb, 0xd3bf694d, 0x42aa5ca3,
- 0x4dfa05c3, 0x33edc0bb, 0xbaab1f95, 0x48113625, 0xe7839a63, 0xc8ba1f87,
- 0xd9843b9f, 0x63af00d5, 0x9529c912, 0xdd056b6e, 0x83eab3ae, 0x81fed849,
- 0x3477de89, 0x98e5ce39, 0x83fe1ec1, 0x7c41f7ae, 0x33f7f8ef, 0x415def7a,
- 0x437e82f5, 0x9a2e494b, 0xe4396c84, 0x3e416058, 0xae487984, 0xe918721e,
- 0x3a080ebc, 0xe9af673e, 0x5b3fc308, 0x69fcdfcc, 0xc1ffd43e, 0x9340eb9e,
- 0x1e973d4c, 0x885f2f41, 0xe82b3bf3, 0x7bdd29a6, 0xfc04c953, 0xcd1e62fe,
- 0x0dfece7b, 0xdcb27fbd, 0xc69f1ff6, 0x3aa72efa, 0x4f7cfa8e, 0xcf19a568,
- 0x1f9bd0f5, 0xabb4409f, 0x7b235fe3, 0x7ee3e4ef, 0xd0f89a33, 0x78cf3b12,
- 0xadf3fc90, 0x8b7f9688, 0xc80f864a, 0x91667abf, 0xe7121e79, 0x1e4259eb,
- 0xddb8554d, 0xe7e56f5e, 0x5fb25f55, 0x8b8afea6, 0xd2af55f6, 0x5ae4f28d,
- 0xf29b7fe4, 0x7d4bd124, 0xbd97a73e, 0x0a0f9e82, 0x63ecce7c, 0xed97e89d,
- 0x196e982f, 0xe23ef80b, 0x1cff13d2, 0x52c6bb19, 0x291dcf06, 0x024bf095,
- 0xd6c97a6c, 0xcf00a9b5, 0xa7a22452, 0x1dad92fa, 0x967fd04d, 0x03a94135,
- 0xb3f9e8f8, 0x0eaf3416, 0x9784bc05, 0xe3f872e9, 0x1b9e1754, 0xcaccd3c7,
- 0x4ffe8cb0, 0x8cbf63bd, 0xc46df6fa, 0x2ee311ab, 0x7567c11e, 0x6a571f04,
- 0x238fb82c, 0x2f2126a5, 0x5e51e33d, 0xd537cace, 0x7c75a18f, 0x1a4c6c7d,
- 0x506f77be, 0xa73c95f8, 0x7e82c9ff, 0x6b27ccea, 0xccdfa053, 0xd7196692,
- 0x912cd47b, 0xd7da3cfc, 0xc793f944, 0xd2ac393b, 0x74073d2d, 0x5b6fbc79,
- 0x6fb61273, 0xd53e4897, 0xe21d2f2b, 0xa7d38fea, 0x0b0f7e3a, 0x3077e1b6,
- 0xb7af29cf, 0xb1f53e60, 0xcccf05be, 0x7f1c3c01, 0xb8c43f53, 0xc0ad1f4d,
- 0x244cdf71, 0x356d9e3a, 0x8cb1f469, 0x5e84694e, 0xd36f1ead, 0x0d4af5c0,
- 0x29cfd3c5, 0x7806e592, 0xad5df3de, 0xd191397b, 0xbd77da52, 0xe14c7be8,
- 0xa1cc797c, 0xd63cbe23, 0x8a9cb8f7, 0xfb4659f0, 0xde769991, 0xb21a92fa,
- 0x5b29ceaf, 0x826744f5, 0x54f1d50f, 0x4f8a3e3a, 0x9ced1e23, 0x6df68fff,
- 0x1dbd20b3, 0xe323bf75, 0x89675d39, 0xa1d0571a, 0x5df0dfaa, 0xda9fa471,
- 0x7ef3fb51, 0x3851eb86, 0xd7946bfe, 0xd57d238f, 0xa7a2643b, 0x9afecaa3,
- 0x27bf8614, 0xffecd262, 0x9ac91dfe, 0xda7597f1, 0x5db47034, 0xdbfdcfb5,
- 0x0ec4cba7, 0xd847a466, 0x3ec2f947, 0xe0771fd2, 0x1768aefa, 0xf7e8eb29,
- 0x45d90649, 0x8a2edcf9, 0xbe5487b6, 0xb889d66e, 0x65c78eac, 0x58dff9a3,
- 0xf1eec3fa, 0x8e492ad8, 0xc65bbfbc, 0xbe9073ba, 0x8612a3e6, 0x75d01ef1,
- 0x15fc23a7, 0x078b6deb, 0xccad7c39, 0xbfbf6976, 0x3f37bfca, 0x1e77d4be,
- 0x367495e5, 0x6561df4c, 0x07e518ab, 0x9e786be8, 0xad665e11, 0x258bd488,
- 0x8d2df1fd, 0xd84ba45d, 0xac78859b, 0xf1e46b38, 0x38e89e8f, 0x851fea97,
- 0xae2bf225, 0x93ea2e52, 0xe67bb8f9, 0x7f6778f0, 0x938f3379, 0xe5fc0915,
- 0x5d691a94, 0xdcf7808a, 0xb59efb16, 0x41fa54a4, 0x07dfa2f9, 0xef8029df,
- 0x61e690af, 0xb1553d9e, 0xca5291d7, 0x9777b5e3, 0xa14af278, 0x15f12a2c,
- 0x3d5e2296, 0x77d35f60, 0x9f643dc5, 0x33bce3a9, 0xfd16e3ca, 0xbcc96146,
- 0xee8f0edc, 0x6863ed07, 0xe3d8869c, 0x7a38fb40, 0xf6ec6e7e, 0xfc39b843,
- 0x30fb237d, 0x0c0643d2, 0x52f2a664, 0x16e5e32a, 0x8846aefa, 0x1e0de7fb,
- 0x9146f3d2, 0x103788af, 0xf4c7fc91, 0x1cbe34f5, 0x58f7419e, 0x8325d82d,
- 0x7691f9fb, 0x6a84ac94, 0x6aade322, 0xdf94a8b9, 0x1528ce73, 0x604cf3ef,
- 0xa8afc813, 0xea3cfcbc, 0xc3cd43f3, 0xc85765ec, 0x63f35e7b, 0xc3fa49d3,
- 0xa55f27e4, 0x4a0e607d, 0x1f39df91, 0x4a89bf6a, 0xc28a1c94, 0x5cf350d3,
- 0x22dc79ed, 0xd76af6e8, 0xcc7a655d, 0x2ed1f94e, 0x056b07ce, 0xd5dbf57d,
- 0xbe3f1e3f, 0xfe861f3f, 0xfefbd9ca, 0x4a7ef893, 0x37a56842, 0x145e7ec6,
- 0xe531f9fb, 0xce70d3c1, 0xfba18c1b, 0x0799ded1, 0xd20263a7, 0xf1f2c77b,
- 0x9eb005f0, 0x2dfcc537, 0x6feb9596, 0x1c5b4785, 0x1ef998ba, 0x7a78fe6f,
- 0xd93f0da2, 0xdce395ff, 0xa7206dfb, 0xd07d1e5b, 0x7581b0ac, 0x15d96b30,
- 0xe347f9ce, 0x6d5d7513, 0x625e305b, 0xf7aabd4d, 0xaf5c5a14, 0x697de024,
- 0x764de7ed, 0xb4460efc, 0x43c6a03d, 0xc6a5bd54, 0xa4bb544d, 0x1fe3c1c2,
- 0x7bfced33, 0x69f6153d, 0xb20fdfa4, 0xaff21aae, 0x226d3b30, 0x19fd0ab1,
- 0xe4fb5add, 0x4657bf3a, 0x9eda2a3b, 0x45334da8, 0x7abd07d9, 0x1715df94,
- 0xfe54fdb5, 0xc454acf8, 0x17795451, 0xcf9a4765, 0xbb40499f, 0x670bedeb,
- 0x8d142e28, 0x5c2eeb9f, 0xaebd9fde, 0x83f74f5d, 0xb7ad71d1, 0xfdd2e42f,
- 0x1baf11a0, 0xcccad4c1, 0x808cc43f, 0x6b7b4c97, 0x18ec1195, 0xf82983a3,
- 0x58fc36dd, 0x8d0dc633, 0x7c9c7817, 0xd7fb9d84, 0x2fc18b89, 0x95335185,
- 0x78c17da0, 0xef48ce7c, 0xef5d99d3, 0x09bdbd91, 0x9e2186ea, 0xa6199ec7,
- 0x5307118b, 0xc08a63cf, 0xb7e66eef, 0x4d81efe3, 0xf7f78bb1, 0x59db462e,
- 0xa22d3cfc, 0x2d62e27f, 0x3ce22d3e, 0x435b8327, 0xd3ec79df, 0xe7116f3e,
- 0xfb1a596b, 0x63a3ec1c, 0x7aa2439f, 0xc5b6130e, 0x596c39e1, 0x758a4dbc,
- 0x2f8b990e, 0x845b0e7f, 0xefd2a95f, 0xb204acb4, 0xe8a6f7af, 0x7b41fbe8,
- 0xcb59c313, 0xb2fdfe31, 0xaccfde99, 0xb4367110, 0x6b9f10a4, 0x84bf97b7,
- 0xa371db71, 0x7b8e74f5, 0xbcffd125, 0x60feff8e, 0x1fea78cf, 0xf883b327,
- 0xfb0780bb, 0x1bbbe9aa, 0xd3bbfcd1, 0x33dd007a, 0x3db9ceb6, 0x839c016b,
- 0x9980fb25, 0xcf839bfb, 0x4a3fef07, 0x7b4bbe05, 0xa654b9f8, 0xbda3d49d,
- 0xec66f25e, 0x8fe351f3, 0x3a9da47b, 0xaa362b20, 0x98fc8baf, 0xeca33b91,
- 0x642db3e9, 0x47c65b67, 0x39c0f7d5, 0x9f8ebdd1, 0xa1d916ec, 0x87ebaf3d,
- 0x114aa738, 0x7d7f3087, 0xfb65e28a, 0x7e714efa, 0x25c6d1e9, 0xfe5df727,
- 0xe7135e9c, 0xa1c453b4, 0x00e22e7e, 0x7e7fc29d, 0xf2a4e023, 0xea9b80cd,
- 0x04280adf, 0x0b940aef, 0x77cfc161, 0x47cb3e56, 0x84aaaf17, 0xcf47edfb,
- 0x7f7dbf73, 0xbe83a862, 0x42de74ef, 0xbda417df, 0xdbbf144d, 0x2c727c07,
- 0x1fbf49ce, 0x4cdb3478, 0xa5a3b3f1, 0x8a7bfbbf, 0xd16b7cbb, 0xc70bb8f1,
- 0xeb4e7ab3, 0x6f184e70, 0xee8b855d, 0x47e036a5, 0xeeffa114, 0xffbe8932,
- 0x040e1b34, 0x3a5445ef, 0xf169f537, 0x65ff0f59, 0x1ddff195, 0x617f42c8,
- 0xa4e88b8c, 0x2273ef42, 0x4fba373e, 0x571e5f91, 0x871beed8, 0x7af18071,
- 0x14fbbe26, 0x3bac4534, 0xe0426f0e, 0x44895379, 0x0a1a73df, 0x86e5d1bf,
- 0xa32fae54, 0x3475ffeb, 0xdd1b83d7, 0x773ce8db, 0x50b2ba3b, 0xf913efaf,
- 0x2964b310, 0x285fbf48, 0x1cb1dd77, 0x65915bf6, 0xc011bb1f, 0x6853a32d,
- 0x4f4afbfd, 0xd8f81c53, 0x21c65785, 0x76b31dfd, 0x79ce305a, 0x53dfc9cc,
- 0xf9951387, 0xf29db77b, 0xa4f2312d, 0xe958f2d5, 0x95fdfa22, 0xef7cfc7f,
- 0xdf7cd1da, 0x0af5524c, 0xfb815b8c, 0xdef9424d, 0xc3f902b2, 0xfc83b998,
- 0xaa73e8cc, 0x88b35f70, 0xfc64f3de, 0xb6bf4f7b, 0x3f782c86, 0x0267ed1c,
- 0xff426c7d, 0x3d04f778, 0x5eadaf7d, 0xe782e7e6, 0x1fa4e788, 0x997e13a3,
- 0x65667c76, 0xc0fa633e, 0xde1d6079, 0xf13ad0d7, 0xadefaa3e, 0xf86292bf,
- 0xc9d683b5, 0xf9589efc, 0xcdcfd1b0, 0x9a20b276, 0x1615b386, 0x709fa176,
- 0x99c69f30, 0xcce3e56d, 0x9b7c7112, 0x1759ffa0, 0x81df9475, 0xcf80d6f4,
- 0x7927cc95, 0x50f5cc72, 0xb7ac1d57, 0x41c6ce1e, 0x569346fe, 0x5b39090e,
- 0xf745525f, 0x07dcc7bd, 0xbfbea3c6, 0xe1e574be, 0x9fc22732, 0xb74154d4,
- 0xd52fa529, 0x945a5d20, 0x4c2f8a2e, 0x5d74cb76, 0x36b97d78, 0x17afd14e,
- 0xb44bf4a3, 0x928fa8be, 0x54f7113b, 0xf9c4434e, 0x4b9f72cf, 0xab83a488,
- 0x2f1ccbc7, 0xd67baf7e, 0x1da71e05, 0xe9f7978c, 0x7803a573, 0xd8ef3e89,
- 0xa73e8978, 0xeaad3c01, 0x8c1dcbaa, 0xbf6f155f, 0x1ac9792e, 0x8d1be799,
- 0xaf8a1fb7, 0x4156d1e6, 0x579e5caf, 0x3b7dbe08, 0xb771443b, 0xeff94bb7,
- 0xff731d4b, 0xb3bfe296, 0x0d63a858, 0xcbe045ca, 0xe8f94239, 0x344ce423,
- 0xf4f8061e, 0xbf2e283f, 0x28b7f3fb, 0x21caaa2e, 0xea25f213, 0xea1fc113,
- 0x1f9099b9, 0xf02f6f91, 0x2d5e87ef, 0x457ca87f, 0x383f21eb, 0x1fcc8fa4,
- 0x5fc5dffc, 0x18cd717b, 0x52167617, 0xd1cab83c, 0xac7bc7a5, 0x3dd250c9,
- 0xd27f8892, 0xf5919c3a, 0x591c6e3c, 0xa12f714f, 0xa6b8d4f7, 0xbb3ebeda,
- 0x5518412b, 0xc24d47a4, 0xc4fd51de, 0x64538e7d, 0x54faaa7f, 0x57fef716,
- 0x08f74fab, 0xfb543a7d, 0x79bb73de, 0x43cbe7dc, 0x1c800f3d, 0xa46f9c9f,
- 0x0e4cb8ef, 0xa3dfcc3f, 0xfe498470, 0x9137746f, 0x69fb0c1f, 0xe604a346,
- 0xf3e64475, 0xf3bee5a9, 0xefd60a6d, 0x0af4bb95, 0x16ff07f5, 0x568603e0,
- 0x0d869dfa, 0x137d738f, 0xd651f457, 0xba83dee5, 0xe6994fb3, 0x61efc24a,
- 0xdf835f6f, 0x8c2a0b01, 0xb598ebbe, 0xee458bb4, 0xdc31a5f7, 0xff9c9daf,
- 0x68071dd6, 0x69ea1fdd, 0x035768dd, 0x9d964f9d, 0xcfe7050e, 0xfd23dbf6,
- 0xf7d97dec, 0xb7009dda, 0x086c697c, 0xa3c37ad1, 0xecf3017e, 0x078d5733,
- 0x73ed8d4b, 0x0bf5181f, 0x7346c7c0, 0xa3cc04d5, 0xdbdfb6ac, 0xdae51f3e,
- 0x60265bd9, 0xbcec1bfc, 0x83b7d456, 0xcdb7dff6, 0x5d3bbf8c, 0xd69f78ed,
- 0xabafa231, 0x5abfbf06, 0x48f7e0ed, 0x87bed1be, 0x7b404cc6, 0x73c1ec39,
- 0x0c9f344f, 0x164cdd22, 0x2f1765eb, 0xbd41fc51, 0x9e73d997, 0xf8ff47d3,
- 0x8fb80f40, 0x455cbf6b, 0x7db922f7, 0xa026f9ba, 0x3c7d75d5, 0xf1db0c7f,
- 0xbf58e07b, 0x001d8628, 0x4be75cf3, 0xcaebf3c6, 0xde8637ba, 0x36fbedcd,
- 0xf6e783e0, 0x44bc7064, 0xc31e6fb7, 0xafb882ed, 0x9272cfde, 0x7ff5c03d,
- 0xf312c0b0, 0xa9b7553b, 0x3b1ad2fa, 0x552d450f, 0x23daa579, 0x21b35f80,
- 0xc69bbf02, 0x7cfdff70, 0xf103a7a9, 0x7fe77df7, 0xe50b710a, 0xf6cf52f1,
- 0xae91c331, 0x97ad5f04, 0xee01c663, 0xc5a3f31c, 0x13416e2b, 0x73beabef,
- 0x86e96fe9, 0x7441dba6, 0xf8e95065, 0xffe3a221, 0xe27bf48b, 0x20efd0fb,
- 0x14fe7479, 0xd347c3dd, 0x03bf4ab1, 0x9be6c874, 0x79e80692, 0x7ec1ba28,
- 0xe806928b, 0xfb7ea87a, 0x931fbfce, 0xe9c607de, 0xabdd2cbd, 0xd059b7f4,
- 0x540f7a91, 0xfd79ce29, 0xfeec8cd7, 0xf5463da3, 0x7e35c677, 0xca3fe811,
- 0x72b0aea3, 0x37b47fb9, 0x3d19fb97, 0x9a9fba66, 0xbe295ee9, 0x235d0dbb,
- 0xf211adc6, 0x75dba67e, 0xeaaf3959, 0xfddf550b, 0x43777c4f, 0x00800098,
- 0x00000000, 0x00088b1f, 0x00000000, 0x7dedff00, 0xc754740b, 0xeebd6095,
- 0x91a93fd7, 0x16883e9e, 0xc085a092, 0xeb404616, 0x7d3d05ff, 0xa71f3210,
- 0x900b18c1, 0x04e08b4c, 0x60dd491b, 0x9e3d90e2, 0x123231a1, 0x1f62cd9f,
- 0xbd6678cc, 0x8c030d39, 0xc077b19d, 0x0b611c56, 0x3837e2dc, 0x71c6ec4b,
- 0x3c4c9c18, 0x6c0843c2, 0xc718d36c, 0xbc4ab243, 0x0f7adef7, 0x0b756bf5,
- 0xcceb43db, 0x40e75764, 0xaabd5ea9, 0xfeeb75ba, 0x7ad3d56f, 0xcecc6333,
- 0x53f817d8, 0x08acbc3d, 0x65cb191a, 0xfc05f3f4, 0xebf2e2db, 0xdf632b25,
- 0xb4cbeeb9, 0x2c93f943, 0x1e670adf, 0x355faf63, 0xb188acca, 0xf6e3a9ae,
- 0xfa87b3ea, 0x8c08758f, 0x127b4315, 0xef768674, 0x0077c154, 0x27d1311e,
- 0x7d1e9d2e, 0xfd4c9fde, 0x8795cdae, 0x9d32fab3, 0xaf7a6863, 0x59b18d3e,
- 0xca0e9bf8, 0x332d9320, 0x5aedcca0, 0xcca012c7, 0x9636f92c, 0xb12e624c,
- 0xf2933184, 0x6bcae99e, 0x39f015df, 0xfe831993, 0x56f595eb, 0x0d5d7f30,
- 0xcccf31c0, 0x3889f1bc, 0xc9c9d37a, 0x97cd5ed0, 0xd769e30a, 0xfe9fde1d,
- 0xe4f329a5, 0x572e3630, 0xfbcdf5a0, 0xf04cf98c, 0xeb6e756b, 0xe7033602,
- 0xd1cc7187, 0x1e60a9c7, 0x1d01e999, 0x2adb5ee5, 0xaa6b3fe8, 0xafe5e1c9,
- 0x6cdef84b, 0x3e1bdfc6, 0x4ac67ace, 0xe2d9c686, 0x54fac809, 0x4c498ec6,
- 0x6f5b2fe9, 0xf8e767c1, 0xb2857ac3, 0xcd6e533e, 0xebcbc455, 0x07e1c792,
- 0x860f6778, 0xcb1d6f8d, 0x55633a58, 0x8b9f699f, 0x387d6d0e, 0x58fb305c,
- 0x5f4fe5fa, 0x33467cc0, 0x5d398fc7, 0x5d79f847, 0x3e90fa32, 0xeed4ae2a,
- 0x4b189362, 0xfc87ec96, 0x992adcf0, 0x36053e1d, 0x7e53f633, 0x0402b8af,
- 0xc29fed04, 0x738014bf, 0x5aef6e9b, 0x16ddd027, 0xa21f4c6c, 0x4c0b2597,
- 0x2e96381a, 0x9bd4d449, 0xea69c79a, 0xd44f57cb, 0xdb736fec, 0x43fa9add,
- 0xea6a661b, 0x354a27ae, 0xd59d55f5, 0xef56f19a, 0xff69ab9c, 0x686feed6,
- 0x7f9e6bea, 0x747f5350, 0xe911caff, 0x885f1a22, 0x89e991b6, 0xd23b0579,
- 0x3a4d88bf, 0x9cc5cffc, 0xf7f7a3d3, 0x7ec27f21, 0xb7af6ebd, 0xd5fe82ad,
- 0xe78d3f57, 0xc5f4b4fd, 0xf90072bc, 0x17d956a3, 0x402bc798, 0xad528d7b,
- 0xf445be95, 0x4536635e, 0xee951be4, 0x11560ab6, 0xda66afc7, 0x6db0aafd,
- 0x7e47aebd, 0xebd01a2e, 0x3759be61, 0x2157fcb5, 0xc706fc35, 0xc7afcc67,
- 0xa5cb84f5, 0x9318eeff, 0x609e397a, 0xfc017fb5, 0x8cc9acc4, 0xa3c74795,
- 0x5db7a74a, 0x6f5f6337, 0xeafccadd, 0xa0582b7a, 0xda3ee90e, 0xfc3b67ba,
- 0x516b927a, 0x5ebe1dd6, 0x6feffe15, 0xef815f86, 0xf323ff5f, 0xdb1013ed,
- 0xe6fc88b2, 0xcfeb5ddf, 0x02402bb5, 0x7a1527bc, 0x278291a8, 0x0e908b12,
- 0x83650398, 0x51f99071, 0xc133d40e, 0x9652846f, 0x38af041c, 0x3034ef68,
- 0x7e71eb2a, 0xa6861071, 0x35eb45d2, 0x288dca0e, 0xa92c456f, 0xebc79cee,
- 0x875e068e, 0xd52ea8f7, 0x3ee7baf2, 0xea92875e, 0x43af275e, 0x5aefaa3f,
- 0xb8cef58c, 0x014489c0, 0x5825beeb, 0x5a1e0e37, 0x05ff4bca, 0xe4994a81,
- 0x5de83896, 0xec7ea7a7, 0x3707af22, 0xf2d0fa71, 0xf65e3183, 0x5f19b3f9,
- 0x813f3c3d, 0xfdc24dbf, 0x006fd75c, 0x828ad43c, 0xd5ef0ec3, 0x3f87320c,
- 0xe4d5f715, 0xe097d990, 0x3133a033, 0x8ccf886d, 0x4ab1982c, 0x0f793e20,
- 0xedcaadf1, 0xe968e3e1, 0x5af51eab, 0xfc3bec01, 0xe51931be, 0xfaa7a730,
- 0x2c12e0b2, 0xd013f9f1, 0xfc327b3e, 0x1f4e1e4b, 0x32a25c2a, 0x5fb5a55f,
- 0x32b6aa8f, 0x59b72618, 0x8559d117, 0xd92c9d79, 0x716dcb87, 0x2e2fe550,
- 0x56e1c22f, 0x1f39ade5, 0xfb1a6cf8, 0xb9967c3a, 0xaeb36a0a, 0xd9f0abbe,
- 0x933e30ba, 0x8496f7ad, 0x321019f0, 0xb7d9f0d3, 0x276e9e89, 0x83094e5f,
- 0x4f182675, 0x23e80cf6, 0xc05499ca, 0x3e244243, 0xb21bfb9b, 0x97c8a21f,
- 0x5817f037, 0x987e6e67, 0x5cf4519c, 0xfee7aab5, 0xdda2b3a8, 0x117a67e2,
- 0xc87c70cb, 0xd2313b2c, 0xbe3cb573, 0x6bba0609, 0x90f80ea8, 0x63be810f,
- 0x06dc151f, 0xcec99bcf, 0x805ab862, 0x31e2aac7, 0x71ad6e8c, 0xec909d2f,
- 0xecf505bc, 0x4e6e8518, 0xdf11a766, 0xc7bd76c3, 0xb59de442, 0x01f1cbe8,
- 0xc70937cd, 0xbf226673, 0xc6db40d5, 0x33fde182, 0x99f00fb1, 0x3e7cc835,
- 0x08eacf78, 0x46af5808, 0xf48d9efd, 0xfe51eacf, 0xe8095f57, 0xe5a5ea25,
- 0x00745b97, 0xa4013fbf, 0x517c8b57, 0x642e9c30, 0x7ee3d3e6, 0xaffdd57c,
- 0x90341fb6, 0xffdb0ebc, 0xcfb0419a, 0xd5394e00, 0x1afa20e4, 0xc8cf6464,
- 0x48c7c14e, 0xbc21acbe, 0xade3f6a8, 0x176826f6, 0x622e91e8, 0xf640b37b,
- 0xb36ca7d0, 0xf305f381, 0x867a55fa, 0x30afcbe7, 0x34ed1139, 0x7ed4f3cb,
- 0xfa23136c, 0x3c97b6a8, 0xb8476755, 0x44cc7606, 0x0abd24b8, 0xc7153f97,
- 0x70e260bd, 0x7f08daf9, 0xe4fe0ad5, 0x43331d41, 0x694fbfbb, 0xff5fa30f,
- 0xfcd3b720, 0x702bc44f, 0x43f0c8dd, 0x4ed007bf, 0xe5689306, 0x43ff03dd,
- 0x69dcf784, 0x01df3f77, 0xf028ae5d, 0x6e856ffc, 0x5124da3f, 0xf5cd3eb9,
- 0xc7a07cfd, 0x7c6e917f, 0x0fc866e2, 0xd5f74439, 0x9027cff6, 0xd9f1521e,
- 0x10f48637, 0xe8f84dc2, 0xdb8344b3, 0x387510aa, 0xe5bf0abc, 0x2a57c88c,
- 0x577c2a9c, 0x0bab7a7c, 0xe7b37bc6, 0xf61c135f, 0x454bf821, 0xfb847ee7,
- 0x674fc1cd, 0x92ef88b8, 0x34667635, 0xfc5266f9, 0x964ca488, 0x3ea2a62b,
- 0x85cc7388, 0x74cb8c75, 0x364cbad1, 0x02fd1da3, 0xf393274b, 0x82734860,
- 0xf7f08ccf, 0xd2ec37a7, 0xa9d6fb43, 0xfbc13322, 0x36bcb35b, 0x09fea75a,
- 0x9399eb86, 0xd60361e9, 0x6577f3e8, 0x9c11293e, 0xbf475083, 0xa2f1c6c7,
- 0xf8f4689f, 0xc75fb9e0, 0xc10a1cd6, 0xee02c1cb, 0xe7cd9d8f, 0x1e17dae5,
- 0x842976d9, 0xad0fda3f, 0xbdddd4d3, 0x2976dbdf, 0x106ede54, 0x3697dc44,
- 0xd9db8e85, 0x5ff404c0, 0xe13b455a, 0x903743a1, 0x2c6bf586, 0xae0a7e78,
- 0x008fe70f, 0x5be73fff, 0xd2ff3d62, 0x8ff650a9, 0xff69fee1, 0x0df91f24,
- 0x2b1ffcea, 0x5f38ffeb, 0xa6387317, 0xb3ba1e01, 0x9f70c5bf, 0x3f7c6c6a,
- 0x7a72504d, 0xf54372e6, 0x739e8677, 0x3ea55179, 0x73de3a0f, 0x1ce91d12,
- 0x994c76a8, 0x7de911f6, 0x71bbd227, 0x48b5bea8, 0xf08be8d7, 0x220573fe,
- 0x16c07bc1, 0xa15b3db9, 0x5c139d97, 0xdfe8d9dd, 0x6c73ab3f, 0xcbce2586,
- 0xe51e3adc, 0x7adb56fd, 0xe2e653a2, 0x38c058eb, 0xf4cbcebf, 0xd1e81978,
- 0x82b7fe79, 0x8dd62a42, 0xf886c2cc, 0xe70bf557, 0x01d13e89, 0xd7f2bbfd,
- 0x5ddd7199, 0x1c66f5b6, 0x82d684cf, 0xea3c386e, 0xe6ec0fba, 0xf4cbcef3,
- 0xb2e9e089, 0xc57bb9b9, 0xa33fa801, 0xee5e7bac, 0x6aaf6a3a, 0x09149ff4,
- 0x4367e07f, 0xf568e8dd, 0x87263ce2, 0x3ac246bd, 0xb2c66c73, 0xec89784f,
- 0x0dbf5513, 0x9dad4fe9, 0x91bafa72, 0x15d763e4, 0xf244cf9d, 0x07305e53,
- 0xbcaf9fde, 0x7b720d6d, 0xa3bf6bbe, 0x1cf7c45f, 0xf3e3f902, 0x764dbf73,
- 0x2e77359d, 0x56b3e7b7, 0x98549179, 0x3fa1f04f, 0x5bc54f31, 0x195f569e,
- 0xa0b7171d, 0xd4de30fa, 0x2c59d1ea, 0x2abe90c0, 0x70f3fcc2, 0x40bb3b7d,
- 0x5972d7b1, 0x2d2bda31, 0xc863df26, 0x420d960f, 0xe2a1c23a, 0x8e814575,
- 0x7c8620e8, 0x942667b0, 0xb465d95d, 0xd3ccfaaf, 0x5f980417, 0x4366df17,
- 0x8cdbd0be, 0xb31bc47e, 0xa80d1f8a, 0xffc24df3, 0xb7b22533, 0x2f848eb0,
- 0xfc79397d, 0x86c7966e, 0xb032eceb, 0xa7f248a6, 0xfdf380b6, 0x927e5907,
- 0x8ddad10f, 0x7bd2041b, 0x66377caa, 0xc237d932, 0x5c8cdb78, 0xd25f80ce,
- 0x3ebf402b, 0xffa017a4, 0xf7b35a17, 0x7ba205e9, 0xadf1e519, 0x12efb152,
- 0xfe1fb90b, 0xca898166, 0x547eca93, 0xc336717f, 0xaffc8235, 0x8430f2aa,
- 0xc7ca94df, 0xf1f26533, 0x732f224c, 0x2e3f7195, 0x5cdc7ce2, 0x5fb97b14,
- 0xfb7a339a, 0x8d7a4b1c, 0x90285287, 0x98dd79e8, 0xc52e4987, 0xa3396f12,
- 0x5da33788, 0xa7073fa1, 0x73fdb513, 0xaaffde45, 0xb274e620, 0xe51472b4,
- 0xa4e92c41, 0xde83cfe2, 0x79ff97cf, 0x68da47ec, 0x99a3e3ae, 0xe042d4f2,
- 0x2e9cbf93, 0x96e583df, 0xbbdb23d7, 0x772f63f3, 0x72801ed3, 0x37df04f1,
- 0x79b3e923, 0xfb97b185, 0x48bed14b, 0xf845f6e1, 0x3d15cbfc, 0xd2794b14,
- 0x11b36504, 0xff011fd6, 0xfcc28e8f, 0xef5073cb, 0xe5817b72, 0x0fa4b99e,
- 0x67e1dfb1, 0x3ec42eb2, 0x1c147b06, 0x0543b441, 0xeddd9239, 0x2d7efd8d,
- 0x643f487d, 0x5c61ccaf, 0x2ff3a81f, 0x7af8e12c, 0xb0e0147a, 0x25eade00,
- 0xc29baf6e, 0xbfcb50e0, 0x7dbd8c2d, 0xe043e92a, 0x1fbb0548, 0x444205cb,
- 0xd0a7af7b, 0x1a7e7318, 0xe2d9780b, 0xe4918d60, 0xefd8c9c9, 0xca0d9a4b,
- 0xd3cee9aa, 0x4b96d728, 0x5c60e787, 0x1ff8fbf9, 0x79d21be6, 0xc1a561be,
- 0xaeff45e5, 0xbc3bb24b, 0xac478c76, 0x7ccafaa2, 0x52af43bb, 0x94dfb63e,
- 0x6c05db7c, 0xe57d51d7, 0xda1f24ef, 0xd617dfc3, 0xf1c6c99d, 0xfb1deb36,
- 0x959dc618, 0xe78d837c, 0x9e36ac1b, 0x3c6d109f, 0x29b560ef, 0xcf1b0779,
- 0x4a6d583b, 0xf3c6c1de, 0x929b560e, 0xbcf1b077, 0xe4a6d583, 0xef3c6c1d,
- 0x7929b560, 0x3bcf1b07, 0xde6a6d58, 0x1538d3c1, 0x9e3691e3, 0x78dab077,
- 0xe36ac1de, 0x97980779, 0x3c6c1de7, 0xf17000ef, 0x722d83bc, 0x943ac1de,
- 0xf1ff2077, 0x67a49618, 0x547f5fb8, 0x7b06cfa9, 0x786334dd, 0xe76ab55e,
- 0x17182dfe, 0xfc7209ab, 0x5e783955, 0x77b414d9, 0x457e300a, 0x04dfb066,
- 0x114565fe, 0xb0d5f0c3, 0x13f3c3f9, 0xbde7d9dd, 0xb0a3fa02, 0x03bc2997,
- 0x18ea29e5, 0xfe7c3f7f, 0x3b577161, 0x65d6e78f, 0x3bf08b7e, 0x78482cbb,
- 0x8718e7c3, 0x13f253ad, 0xffad56b5, 0xb2e67f2a, 0x995f71f9, 0xf80899d4,
- 0xbb6d4590, 0x8c2ff988, 0xd7f15ebb, 0x6ab7dc61, 0x15771b50, 0xb8d41b33,
- 0x844bcf3c, 0xe1df39c1, 0x6b045f1c, 0x2a7f016a, 0xc1cfe601, 0x53ae15a4,
- 0xa45e7c12, 0x881bddb7, 0x453bbcbe, 0xaa6814c7, 0x9e606404, 0x6a2012a5,
- 0xc654d286, 0xf24cd2ac, 0xfe9d389b, 0xf1bdd4d7, 0x030f28d9, 0x6c04467a,
- 0xf9a83c23, 0xbf580485, 0x2bfc8334, 0x332aeff2, 0x3a47bffd, 0xcc82eb50,
- 0x5d8238f3, 0x2f80cd62, 0x5c266ef9, 0xceab9336, 0x45eb6f90, 0x73c335e6,
- 0x9b37e941, 0x2d4e2905, 0x76f28933, 0x6541ccb5, 0x695774d1, 0xcea3f011,
- 0x7ae175ec, 0x0966ecaa, 0xee3d85f9, 0xf148db3c, 0x32e97ae4, 0xf60049e0,
- 0x48da62f8, 0x2ec88a76, 0x451cf8ab, 0x2f1f48bb, 0xadc92278, 0x61ebd88a,
- 0x0a2a83b2, 0x2dc7c919, 0x7cfcb22c, 0xcfcb84ac, 0xdf5d4b37, 0xfbd73c44,
- 0x878fd516, 0xd0be8f2e, 0x6d9b794a, 0x5bc2f161, 0x6f628afd, 0x90e72447,
- 0xe901b93d, 0x8f04f17a, 0x1688e10d, 0xf62a78c7, 0x1b49ecf0, 0x767baec1,
- 0xd45aec14, 0x2aecb743, 0xfa9399fb, 0xb1ca3b50, 0xd0ba4f0e, 0x9092baef,
- 0xc3ddaa38, 0x8d67143c, 0x6979af1c, 0x9920e214, 0xfe13bfa8, 0xea639d0b,
- 0x87fb023a, 0x54bcfbe5, 0x428ef8e1, 0x634be387, 0xa0d317cf, 0x613e27d4,
- 0x771b8d0b, 0x970e0459, 0xf5c0d041, 0xfdff62b9, 0x78f624a0, 0x7d72812a,
- 0xf22efca9, 0xf974d561, 0x7caa5867, 0xbae1df3b, 0x2d29fc40, 0xf9024faa,
- 0x767f66bc, 0x0689ea01, 0x2ae35edb, 0x52d5f780, 0x3a22fdf9, 0x5b1ff46f,
- 0x1eb16e1e, 0xf7bc478f, 0xa3cb22b9, 0xc50911bb, 0x28de4fe4, 0x67e4fee2,
- 0xfe288784, 0x638bafe4, 0xea7b2fbe, 0xc9fc8673, 0x5b1ffe70, 0x639de3cc,
- 0x068e0147, 0xf1465728, 0xc28ca6eb, 0xbf5a8dfc, 0x443ebf6e, 0x854110ce,
- 0xdc6c69e6, 0xfc1163af, 0xba35973d, 0x147b37bf, 0xf310b1d6, 0xf591b571,
- 0x31c57dda, 0x7e96aff7, 0x3307ca03, 0xd0a9fd5b, 0x6f30bcc4, 0xb2be50da,
- 0x0fafd5c9, 0x383f738d, 0xe537e0e1, 0xb37e7008, 0xf272e638, 0xf91e9c7c,
- 0xe119bd75, 0x7e066ae9, 0x255fb08d, 0x9bffdc25, 0x9611e13b, 0x3a637688,
- 0xe411f743, 0x3637cf09, 0x83637e29, 0x2a767fa2, 0x2c53d472, 0xe52ce952,
- 0xe851b9f5, 0xfbcad7fa, 0xb69c4a8d, 0x2bf26251, 0xec7ff491, 0x38fce6e9,
- 0x71c6e728, 0xf30def38, 0xf453dfcf, 0xd3d89ec4, 0xa00c9ecf, 0x91b5b993,
- 0xf63075f1, 0x0274b174, 0xf6d4bfcc, 0xf8901cf4, 0x0d9b2fb0, 0x2e9c5f94,
- 0xef0c58bf, 0x57c28b6d, 0x69782b9f, 0xb03a3e86, 0x34a05bfb, 0x9010f942,
- 0xfa405481, 0x6fec55ed, 0x14308e01, 0xf1de0420, 0x3af4e7e8, 0xce7c1ee4,
- 0x7fe46d5c, 0xca1bc884, 0x3999569f, 0x83a774df, 0x0efe88ff, 0x9339d333,
- 0x9fcf20ae, 0xfcf26576, 0x6a3c3868, 0x456ff4fe, 0x71cf198f, 0xc4166577,
- 0xebddf285, 0x6f26989b, 0xe78575dc, 0x8a4fc185, 0xc949fad3, 0x8f8527e4,
- 0x74b9909f, 0x247fa85e, 0x021fdcc8, 0x5c50267f, 0xa917e43c, 0x7c98cffe,
- 0x7ff15cf9, 0xcd1dfd02, 0x4947119f, 0x07308b0f, 0x74ddff3e, 0x8f10dff9,
- 0x1fd3d023, 0x9fd3d0a3, 0x347fdfb0, 0x11cc627a, 0xf0cc68b7, 0x1eb2bb71,
- 0x708eb5b7, 0xd321203f, 0x54ce9119, 0x9b7a02fa, 0xe8763250, 0xb4f3217d,
- 0x4b136f4a, 0xbd3ebf8a, 0xf0bec05d, 0xafe1acef, 0xd149d6ec, 0x7ab59dfb,
- 0xfa0f28cc, 0xf19bd732, 0x99d4c49e, 0x6bce072e, 0x006c9911, 0x3e5cbb38,
- 0x007b9e33, 0x64bf2f3b, 0xcdc1bc84, 0x7e3f2e22, 0xdcffecad, 0x2aff9c09,
- 0x7dbe0b96, 0x6c4d7fc0, 0x4df70197, 0x4958ff7d, 0x7b88fdec, 0x35ee4872,
- 0xf7208c96, 0xe2f8565e, 0x2b5f0573, 0xe729d6da, 0xfb445899, 0xfdec5567,
- 0x942b348c, 0x45d75273, 0x745be3a4, 0x2285e787, 0xe21467ac, 0xe4c7e7e0,
- 0xcd4c3ce0, 0xfc406d2b, 0xf1c4563e, 0x7dfecd17, 0xb3fc146a, 0x4ad70089,
- 0xfd0199f6, 0xc7ff5969, 0x11e748ac, 0x39d9158e, 0x0390069c, 0x5995df80,
- 0xfc31b7ba, 0xb5a495d9, 0x67f7d487, 0x67aefe2b, 0x5267e414, 0xf1c3ce0e,
- 0x4c0e7e1a, 0x3ec5cf2d, 0x88b4b01e, 0x80ffb9fb, 0x73fc0efc, 0xe358a4a8,
- 0x64a8fee7, 0xb5f73f64, 0x1adc8f7f, 0xcba8e850, 0x7d9ed911, 0x40fbf621,
- 0xdd60e0e7, 0xb9157cef, 0xaa6f6e11, 0xdbd89ee5, 0x7a59697b, 0xd1c3879c,
- 0x24e7b4c8, 0x28dff16e, 0x8f5d2de0, 0x77e968f3, 0x5ffae325, 0x1a58c385,
- 0xe78c73f3, 0xff31e867, 0x7d79f9c3, 0x94be2ba9, 0x198f36ec, 0x07d837f5,
- 0xb95f6714, 0xcd1f2539, 0x6b67d82a, 0x93be96a9, 0xefa6474a, 0x403bd2e4,
- 0xfc9caadf, 0x534c6117, 0xa899bca8, 0xa5699bc8, 0x29afdfb1, 0x8e48af18,
- 0x632baf2c, 0x73dbe71f, 0x79744e77, 0xfb379eac, 0x4f1b4147, 0x8f25bd6e,
- 0x69474e63, 0x7921faa9, 0x7087eaac, 0x5e868d3c, 0x0bd10c48, 0xcce4510d,
- 0x3631c068, 0x9db51f04, 0x98afe502, 0xc0a6f98d, 0x39d89daf, 0x96c7dee4,
- 0x4f138851, 0xc87f8d0f, 0xa047af60, 0xb1a5dde3, 0xbca37fcf, 0xdb7c37e9,
- 0x47f9d236, 0x28c5d5a3, 0x3173623f, 0xb19fec3b, 0xf6f295b3, 0x94ad05c6,
- 0x029d6687, 0xf498fde5, 0xab79f92e, 0x30a7de6c, 0x9e5c367d, 0x5e398d6c,
- 0x97d8728b, 0x28c537f6, 0xf8ebcd7e, 0x37f93a4a, 0x153ca3af, 0xb347ee24,
- 0xf74ecc0d, 0xb97cafa4, 0x202f58fb, 0x9a2f3012, 0x763ee8c4, 0x7ac7e1a7,
- 0x051b47cc, 0xe65cfe3e, 0x974ff9e7, 0xf0a3fc77, 0x31a0e59e, 0x7f543b7f,
- 0xfb4d9a51, 0xcfe569de, 0xf39bf6bb, 0x9ea5849f, 0xc19e15b6, 0xa753e1f3,
- 0xec1c5327, 0x6b8f03c5, 0xbc5aecec, 0xdf7e80c7, 0x7e861e0b, 0x35d329a2,
- 0x9c3b2471, 0xae927f31, 0xa89a508c, 0xfa5e7a94, 0xf86d9d05, 0xf7f73bfb,
- 0xbd67e848, 0x724cc078, 0x9e81ea7f, 0xe32155f8, 0x3e719627, 0xfe3d06b6,
- 0x35af0019, 0x093273d3, 0xf92b1def, 0xce799173, 0x632bc2d4, 0x0f9d00a4,
- 0x6b5791df, 0x2ebba50e, 0x794cd6a9, 0x639d5ce4, 0xfceb1d8a, 0xf4fc431c,
- 0x4082fdda, 0x112edd7e, 0xe19aef50, 0xec7a86ba, 0xc3eb890d, 0x496b53a9,
- 0xe72a75ab, 0x2de4761e, 0xc7ef8039, 0xf1a7af4f, 0x7b64593b, 0xe5c658cc,
- 0x99068bf0, 0x80f17de6, 0x55c8e748, 0x7c69debc, 0x0f30cbd6, 0xa6dea3e0,
- 0xa7d87ba7, 0xe5114e8d, 0x8134e9d0, 0xdf2d82ed, 0xee8578e9, 0x0288ec99,
- 0xb94a2fef, 0xa96cca9f, 0xf7a77f44, 0x748f2e77, 0xbfa55f7e, 0xa96433c9,
- 0x49c0ed0c, 0xff94269e, 0x36e4b6cc, 0xdf24f17c, 0xe68743bf, 0xcffc03cf,
- 0x227fc17d, 0x6b21f70e, 0xf75c78cf, 0x6a76a507, 0x1f0f45bf, 0xb0f442bd,
- 0xe3efc8c5, 0x8e717578, 0x858eb003, 0xcf1101d6, 0x8352184f, 0x2a6de794,
- 0x8b74f2e3, 0x81630fca, 0x7d3de01f, 0xc507bf06, 0xcea9da26, 0x84270726,
- 0x559ea3de, 0x0597aca6, 0xc2f9f132, 0xd83777f8, 0xf6158c1d, 0xb08b37a6,
- 0xef8985fe, 0x7a86c86e, 0x5e78ef49, 0xb3f778cf, 0xb2b1896c, 0x9f5e0cde,
- 0x9367eef6, 0x9bd15ea0, 0x3095ebc9, 0x9bb078d4, 0xbd9ab37a, 0xa4be3879,
- 0x0f15bf19, 0xfd7f1472, 0x45d26f52, 0x28355f8c, 0x031f87eb, 0xfbece3ce,
- 0xe2ef3a47, 0x78fd5b34, 0x86c9832e, 0x3419f8b0, 0x6077dc85, 0xff2409a9,
- 0xf30bfbd4, 0xf63f7f45, 0x84fd99d7, 0x2759bbdf, 0xad8073d9, 0x7e145fdd,
- 0x5c2e7b79, 0xc8d96dee, 0x8c4e785c, 0xef0966b1, 0xd64c0833, 0x78e3c17d,
- 0x855f9c4e, 0x187f9d47, 0xc8b5b05c, 0x3d70439f, 0x70a8e34f, 0x7937cb5d,
- 0x6b7ade51, 0x0427ae59, 0xe084d74f, 0x456c180f, 0x0f1dacda, 0x1b5d3ee1,
- 0x40209c13, 0x1b7cb93d, 0xb1b5dbed, 0x8e081fc1, 0xef81ba90, 0x096f5b63,
- 0x289763ed, 0x9b9d21b7, 0x216ed68c, 0xb8eeb191, 0xe60c1984, 0xe5d631d9,
- 0x406e7bc5, 0xd8ef7477, 0x1c74659b, 0x8beb3800, 0xc7a1f9b4, 0x83fb3a15,
- 0x98e60f22, 0x01ce7976, 0x047bba5d, 0xdc70f786, 0xa88c3783, 0x5df616ff,
- 0xa4be6234, 0x11a2e7a3, 0xeb03bee9, 0xf3c74e30, 0x6ff988c6, 0xbd5eb963,
- 0x91e74a2f, 0x4f1c4bd6, 0x7aeeb2a7, 0xe9e0152a, 0xbdd02d58, 0x9247f5bc,
- 0x7d7d60e6, 0xb192ae2b, 0xe78755e5, 0x38b4b920, 0x72c29ffb, 0x95381b25,
- 0xccb4240a, 0x10f667a5, 0x4d62b93d, 0xe887b33c, 0x8a4f16c9, 0x1772bea6,
- 0x280cceec, 0xfa686637, 0xeafee531, 0x83f43632, 0x949a98e7, 0xdb665c7d,
- 0xeeb8c019, 0x3bc19732, 0xc2de3210, 0x3262cdbe, 0x1c11edc2, 0xcbd28d74,
- 0xe0ad3fcf, 0x1c52842b, 0xf7cf1f7a, 0xefc40af4, 0xba7a6d1d, 0xcbdcd3c7,
- 0x35e6aeed, 0x202ecf82, 0x0dbdf81e, 0xed40af77, 0xeba7deee, 0x1bef1193,
- 0x47000f00, 0x7d84f8da, 0x9347112c, 0x4ad5dce9, 0xdf775605, 0xb38e0339,
- 0xdd023be2, 0x9bbf5567, 0xb2bfc2a0, 0x91ce91a9, 0xa45e7c01, 0x4d9d754f,
- 0x5ce947f6, 0x9789cad5, 0x6187a80d, 0x3406977d, 0x5bd6d4f8, 0xcafada3c,
- 0xd1fada8d, 0xf29ee532, 0xf90d3634, 0x209978e9, 0xb52439e2, 0xf9d651fe,
- 0xe75ef1b7, 0x0a79d16e, 0xe8cdb3e9, 0x7efa819f, 0xbaa2e8b7, 0x3bcf0eda,
- 0xf89df118, 0xb1f100e1, 0xc5b9fc40, 0xf8354b20, 0x8176973d, 0xb60576e8,
- 0x0f67f3ab, 0xfd754fbd, 0x554dfaf0, 0x1b9c5aee, 0x4730bbe8, 0x90ed0905,
- 0x9316517a, 0x222f88f3, 0xbdf9779e, 0xa36f07c2, 0xeeb803f6, 0x7d852242,
- 0x44feebba, 0xbde6179f, 0x3a56cdeb, 0x215776e7, 0xf91d81d0, 0xd6e7475e,
- 0x2f79e3e6, 0x7903ef28, 0x2ef28168, 0x9226a1fd, 0x128d33ef, 0x9ce577c9,
- 0xe42f2a97, 0xb6e7b517, 0x219e67e6, 0xe7beeb3b, 0xb579d276, 0xc17239c9,
- 0x2d0fa8d3, 0x471dfe7c, 0x1866df04, 0x34ef23a7, 0x3271cfc9, 0x61d72f3f,
- 0x2f68e453, 0xfd7551c8, 0x50e3bfb0, 0x692261ae, 0x9bcd1e41, 0x5da9566e,
- 0xf8283926, 0xffe8756b, 0xdde6538e, 0x75a76d5f, 0x487a3da7, 0x316775c0,
- 0xe60166ef, 0x7c3a82bb, 0x55f950ec, 0xf8b5d7ed, 0x565de80b, 0x5b63b5af,
- 0x65e3d745, 0x6dbb5f30, 0x2dcfc8c0, 0x1fa88d06, 0xdef8e0ee, 0xf2c3e348,
- 0x50ee7475, 0x4730fbe2, 0x7680983f, 0x39a3face, 0xf608d8e3, 0xd3acde8d,
- 0x148311c8, 0xf33791a7, 0x67f2b573, 0x772b43a1, 0xa39651be, 0x4f245f69,
- 0xdfdfb4d3, 0x3fa9a858, 0xbcd4ace0, 0x9d5360ff, 0xcdb26ea6, 0xb16fbcd3,
- 0xe3d4d62f, 0xde6b9773, 0xa558e31f, 0xf5bd3769, 0xed0126a3, 0xc077b371,
- 0x06e87805, 0x1e4b28de, 0x12d323d2, 0xe32865e0, 0x2c562d0a, 0x744df3bb,
- 0x3c7bb64e, 0xec4497e8, 0x773a1dff, 0xc97c4e69, 0xdfe5035c, 0xfc5abe0b,
- 0xc9a00e7e, 0x3ddbf685, 0xf0e3684f, 0x5f38abc7, 0xb94365a9, 0x280ac1eb,
- 0x67b05ef3, 0x81e97bf0, 0xcc7f707b, 0x45db8c71, 0x2ec999af, 0x5376899a,
- 0xb071bf88, 0x397e66ba, 0xbe427bf6, 0xf582f917, 0xbc0a6932, 0x3b08cfb7,
- 0x35ee7a8b, 0xebcbf523, 0xe685d01d, 0xce597ff7, 0xceb3c1e5, 0xfc717bda,
- 0xb2d03e8e, 0x7dcf4fc8, 0xaebf4468, 0x013fafa3, 0xe70cd9f5, 0xcfb44687,
- 0x7a2b9e87, 0x61c60c4e, 0x0e1fe39c, 0x63de23e9, 0xa46e5edd, 0x722b4ff1,
- 0x7a3be5bd, 0xf78b4f3a, 0x864a6b37, 0xe1cb73e4, 0x63ef1fa0, 0x7bf3b4b7,
- 0x368e789b, 0xf9069c92, 0xbca861fc, 0xf41d367d, 0x4f1a4cc1, 0x97960fa3,
- 0x3edee9f9, 0xfbcd6fc8, 0x5c34972b, 0xc8257cc5, 0x4cf3ed71, 0xb1961e7e,
- 0x73fa0301, 0xed35d720, 0xfb95cb1b, 0xde58d39c, 0x2e072017, 0xdbdf2338,
- 0x9f8abb7d, 0xaae0b833, 0x16787da3, 0x47e789f0, 0x3f861d9f, 0xe1dbd78e,
- 0x81a465ed, 0x661bfd90, 0xff7157ff, 0x7228e5ea, 0xbfb2a2fb, 0x014084fb,
- 0x33b7550a, 0x8577e88e, 0xa5ed75b9, 0xcf97dc42, 0xdebfa2b7, 0xee8123f2,
- 0xffb2ffc1, 0xac3b34ad, 0x54f878df, 0x7697de1a, 0x86953a1f, 0x0cdb89f7,
- 0xcf68cdf6, 0x3dd07d03, 0x3f5e8ee4, 0xa87edfc1, 0xb79f1fb0, 0x140e0af7,
- 0xeb9eeec9, 0x364eb40d, 0xa3fd15b0, 0x3ae0517d, 0xabedce58, 0x2a76e5c3,
- 0x13982edd, 0xc98f7ef5, 0x1e9013e7, 0x5c213e40, 0x820fc047, 0xe66dbefa,
- 0xd4f648a6, 0x27df0565, 0xde1919b7, 0xfe836dfb, 0x59d38eb8, 0xbdf88da7,
- 0xb0c39685, 0x71d7012e, 0x1c7881ee, 0xa181837f, 0xf7c2a19d, 0x03e05671,
- 0xabfbff5c, 0x2dcf0c0d, 0x27ad596f, 0x81bfbf7c, 0x87fa27db, 0x0335bd7f,
- 0x2e80cbea, 0x270f3bf1, 0x9d38df56, 0xbfbee301, 0x7569db86, 0x2f881b0f,
- 0x6e13ad97, 0xa50e4bdd, 0xff6e956b, 0x70d3a146, 0xdba70dfa, 0xe6baf461,
- 0xdbebd1eb, 0x90ecb7e5, 0x61f7a819, 0x438ce7ff, 0x731efa3a, 0x1a7e401c,
- 0x0718613c, 0x2ada4f70, 0x63c3c039, 0xa7bef5d3, 0x9c6e50d2, 0x6df9ede0,
- 0x7f2e057b, 0x7d71cbec, 0x8646dd19, 0x2a2e08f7, 0xd95176fb, 0x0a0b3b37,
- 0x62cfc8f1, 0xa9ca1260, 0xf9ce256c, 0x1d35818a, 0xe452ff46, 0x8ffa67f2,
- 0x87b77b6d, 0x2b7fefd0, 0xcaab74e7, 0xe64669c5, 0xf7c56c3a, 0x045f8d0f,
- 0xe06cbce3, 0x282735e7, 0x09c94de3, 0x52822c36, 0xe4e5c157, 0xd438156f,
- 0x3e149ffa, 0x437f2760, 0xe6685cf8, 0xd1b79ff8, 0xf8eb8cdf, 0xbd75c999,
- 0x305fde1c, 0xea1b7ce1, 0x3f49eebd, 0xb9dfe3c9, 0xee1d9073, 0xa27ff056,
- 0x63cf37fc, 0x3532cfee, 0x72d7f68e, 0xe90969f4, 0x68a532d9, 0x30f148dc,
- 0xe66ccdf7, 0xbaba014a, 0x5aa54399, 0xaafc745f, 0x82fc8071, 0x2fc40deb,
- 0xb9e9d337, 0x0553efda, 0x8e46e9ee, 0x4a97d607, 0xb6e41b7a, 0x67921658,
- 0xfaa0f150, 0xfb2996e3, 0x5b1ebf69, 0xcfee28c7, 0x8f84d3d8, 0x84e76d15,
- 0x41e71856, 0x02b06c83, 0x3627cfbe, 0x8534bdad, 0x626c9fb1, 0x3a0b05cc,
- 0x5cccc9bb, 0x6c7d0377, 0xd81ea892, 0xbbfaa364, 0x5e54ec9b, 0xa2c738b6,
- 0xa4e079fe, 0xede20a67, 0x671ed644, 0xed73cc2d, 0x41f081ac, 0xfdf4063b,
- 0x376b4298, 0x0cccf4fa, 0x947a37ed, 0xf028adef, 0x8333743f, 0xfcbe40b9,
- 0x8e83e702, 0x467f1bed, 0xe6b1cf72, 0x49fa037a, 0xb7176df9, 0xf1bddd62,
- 0x5f680d77, 0x04fa007c, 0x7eec0ce9, 0x9e501366, 0x81da339c, 0xa66f9a0e,
- 0xeb2f38d0, 0x77c80d82, 0x430263de, 0xf7a0fcfa, 0xd71c71ba, 0xe12d7457,
- 0xe6744df9, 0x48ad2d9f, 0xfbb8fc22, 0x7f7c75f2, 0xf7a1748b, 0xf9effa29,
- 0x87ee0243, 0x9dfda379, 0x467fec4a, 0xb7af90cf, 0xa41306d7, 0x02f87208,
- 0xa3978b8c, 0x86581d70, 0xbd1937b7, 0x413cf053, 0xe1c74293, 0xfa158bed,
- 0x941b4c04, 0x213229ef, 0xc1239f8d, 0x5258169f, 0x41f93262, 0xe7e038fe,
- 0xabbabe96, 0x811e9622, 0xcff5a87d, 0x762187d8, 0xfc3a347c, 0x437e25b2,
- 0x4329c3e6, 0x4323f475, 0x1fa07fef, 0x82fbe919, 0xe3c9aca6, 0xb9778a46,
- 0x83bec007, 0xc300eafd, 0xf4829ec9, 0x4fca8d3e, 0x91d9748e, 0xc171cc7f,
- 0xd82fa83d, 0x3bf23a5d, 0x7b5abdda, 0x87e141a8, 0x7a1ec506, 0x3feb42b4,
- 0x5ed49f81, 0x84a4fdc1, 0x3fe34ce3, 0xff273f85, 0x057c8cc9, 0xfd834ef3,
- 0xfed22579, 0xc7aed554, 0x2ed8137e, 0x740673a2, 0xbe15f48e, 0xe0a8bfce,
- 0xebe5547a, 0x48d7c865, 0xaf9cbdbf, 0xa96dc7c3, 0x1c0bf9aa, 0x7b945b77,
- 0xf157f710, 0x139fdaf1, 0xe7ee5f08, 0x1f4f0852, 0xb59ce7b3, 0x031f9740,
- 0x2e80fb1c, 0xf19d39af, 0x9affd049, 0x6c9f19cb, 0x1d03921d, 0xbf53c5cf,
- 0xa717936d, 0x19fd42b4, 0xef187ba4, 0x8a3ade93, 0x1cf43e6f, 0xbe753fe7,
- 0x52cbfc0f, 0x0d8a9f90, 0xda03a341, 0x262efb33, 0x7c581da0, 0xe414fee4,
- 0x6e7068c3, 0xdce054ad, 0x4bdad8f8, 0xf01e9c29, 0x455aee1c, 0xf49fb9bf,
- 0x6bff111b, 0xdfa23237, 0xd97ed7fe, 0x49fc7c81, 0xfa84bc5f, 0xf1a3e3f0,
- 0xd7ff945e, 0x3a7c998e, 0x6f10fc81, 0x8fb5c822, 0x91f7030d, 0x2f4479bd,
- 0x3ee8ffa1, 0xc83ddbf6, 0x4cd7ee8f, 0xb5b1f968, 0x51d75d7d, 0xddf5b5ef,
- 0xf2c4557b, 0x87e5d1a5, 0xd38f8df6, 0x6ffad57a, 0x28ed9937, 0xb9113f47,
- 0xfbdb589c, 0x6bbfd92a, 0xc0cc6f07, 0x47c7ea38, 0xca094fff, 0x379bf735,
- 0xb99e504a, 0x8251b8df, 0xc71feeed, 0x2dd9227b, 0x84f4b371, 0x665f5557,
- 0xe26a27bf, 0xfa141b45, 0xd5dceec8, 0x57f00938, 0x03896e7c, 0x7b6ab6f3,
- 0x139d14f1, 0x79fe2fdf, 0x21c3ca7d, 0x22033afd, 0xce8a8de5, 0x0eafc7d5,
- 0xaa47cba1, 0x94ef9a0c, 0x0f38d57d, 0x2df7e2b6, 0x0275c56f, 0xec0efa3a,
- 0xbfc880b6, 0xf046bb2f, 0xf601bfa1, 0xb23f784b, 0x923daea7, 0x9910f742,
- 0xbd3f9ce8, 0x1c53eb08, 0x5628eddb, 0x8726a7cc, 0x02cb4bd8, 0xe809bf3a,
- 0xe4cfa9a8, 0x203f7b27, 0x62baa45e, 0xfd743d47, 0x85b26337, 0xdc9a7108,
- 0x1ca0e777, 0xc0d78f0f, 0x5b8418cf, 0xa7ceafb5, 0xa651f8f3, 0x042dd247,
- 0x993b9ab8, 0x161d7884, 0x4b9a69d7, 0xf8f0a2f1, 0xdbb03d8e, 0x93ecfd8c,
- 0xabc21275, 0x8fb8a5da, 0xc0e4113d, 0x7972565f, 0x6757f2a6, 0x3af5e780,
- 0xc9e6b503, 0x69577e50, 0xcc7491ef, 0xece9780b, 0xc600ffbb, 0x1f073a17,
- 0xf30e9f8c, 0x98b7be74, 0x9ae79e61, 0x829e6b54, 0x9ae706fd, 0xa21bc81f,
- 0x1af9f09b, 0x345db92a, 0xd6442f64, 0x5f0aa57f, 0x2c1e968f, 0xd0f3fcac,
- 0x579fe083, 0x7cff7254, 0x709f8f05, 0x7f5c3cff, 0x1d5972a8, 0xef82ad77,
- 0x2af972e1, 0x47e039d9, 0x5b5e5c93, 0x32f7a769, 0x90a516fb, 0x92defd7f,
- 0xf875bb14, 0x43a239f8, 0x7c379c97, 0x739ed57c, 0x6653e57b, 0x3d647bf4,
- 0x897ba7f1, 0x97fcc3e0, 0x9db9ff6a, 0xeee5d902, 0xdf0f8366, 0x2c0ae153,
- 0x07d8f1e1, 0x22cf8364, 0xaa89d90c, 0xddab791d, 0x6abb5021, 0x63f6aa57,
- 0xbbe3c9c0, 0xfb788a4b, 0x556b8b65, 0xa75c58e5, 0x97179e85, 0x398ce7f3,
- 0xf55fa14f, 0x918152e0, 0x4aec501c, 0xedc34e95, 0x72fb4fce, 0x438a4712,
- 0xa7d0af3d, 0xc21367ca, 0x63d543f8, 0x7e7054cf, 0x5e3d40eb, 0xf7fc7a88,
- 0x7c3cfb1a, 0x8fe3d05c, 0x463f5257, 0x2e7e8bfd, 0xebf9233a, 0xadfc6566,
- 0x4e05feea, 0x59bc20d6, 0xfd19b02c, 0xf5fa68cc, 0x139d8a7b, 0xc519fdad,
- 0x3f1dbc7e, 0xc8e4561f, 0xcbf3f168, 0x70f2b795, 0xf9f9a9ff, 0x8c687d96,
- 0xd557bf62, 0x1ffb86bc, 0x6a04f7a7, 0x97feff90, 0xe1eee281, 0xfaa53def,
- 0xecd3229f, 0xa32ca9cf, 0xf723fd0e, 0xe83f1e1a, 0x43bfb24e, 0x7a5bcc7e,
- 0x05ace386, 0xb8ed107f, 0x51266f47, 0x32f686d9, 0x385e2b94, 0x1588f947,
- 0x77f0b46b, 0xfb174c63, 0xf3a6cbaf, 0x9eac2d03, 0x7d2d4ce2, 0x5016d249,
- 0x0f63dd0a, 0xf2be469d, 0x0fdbd01e, 0x88ffbe84, 0xc799befa, 0xfba636e1,
- 0x661af728, 0xc278b40f, 0x7dad7eed, 0x8dc4a950, 0x6f09d9a2, 0x5cb85bf4,
- 0x3e27a339, 0xd378c0ef, 0x7d8cc64c, 0x37b82e5c, 0x474938f2, 0xfc04e6df,
- 0xd2bb6a08, 0x500c457e, 0x6bf28a1c, 0xbed5eaf0, 0x3ee8d3a7, 0x27cdac97,
- 0x39ffefb5, 0xbcf0cbc9, 0x970f7252, 0xbd36ee4b, 0xa12a4792, 0x83b797ef,
- 0xed0e393f, 0x1bfdbb4b, 0x8b807788, 0xc8de48f9, 0x3ecbb89a, 0xe9f4af25,
- 0x3f257f99, 0x2891c574, 0x79eea479, 0x7ca48f3c, 0x1e787727, 0x0ca9f4e9,
- 0x48f3edfb, 0xe8e7bd1d, 0xf2edcb1e, 0x5baaa649, 0x3b8a1c71, 0x7c79144e,
- 0x209f6277, 0x626abc61, 0xe9775f1f, 0xafb238b6, 0x3ab57e1b, 0xba81e505,
- 0xe22c9f4f, 0xfde4fdf8, 0x5fb06acf, 0xc944afc9, 0xe37aeb02, 0xcb3f0dfd,
- 0xd9bb75e0, 0xc436fd8e, 0xc9f33fa3, 0x23c7d6af, 0x1280df7e, 0x17c7e7f7,
- 0xc9f1c8c4, 0x667578a1, 0x959dc515, 0xfa08b578, 0x5c50cc70, 0x8bdfbc27,
- 0x746e5c55, 0x7142bb83, 0xef3c23cd, 0x9aee9ddf, 0x9ebff547, 0x29dff8c4,
- 0xfd1e2990, 0xc635d02a, 0x62c1a68d, 0x3ffd2f31, 0xe62758e3, 0xbac7ba91,
- 0xf47c427e, 0xf23b3ad7, 0xfca7f411, 0x9db0f793, 0x6a8623f4, 0x0333cf31,
- 0xf7405b3f, 0xdf295231, 0x8fb28f73, 0xa2cfe0e9, 0x2cd0095f, 0x34f43cc1,
- 0x2333df25, 0xfe38898e, 0xfb6b830e, 0xf52fcc54, 0xc4cd8e8b, 0x3c148e04,
- 0x779e196f, 0x2f9e6412, 0x6a4ff357, 0xfe5a3cde, 0x9479c049, 0xf3f056ef,
- 0xf980b296, 0xc4cf3574, 0xf9293a96, 0x43cca5b5, 0x807c42f7, 0xde73afb3,
- 0xcffc846b, 0xf21115c3, 0x982beb3f, 0xf3699f62, 0x5f73db8d, 0xaafd3a21,
- 0x78c3c679, 0xe68ee2ae, 0x0fdcecc5, 0x28bb830d, 0xf234d3e9, 0x6ff8febb,
- 0xfb67a409, 0xbc3e906e, 0x00b13416, 0x78071fc5, 0x40cfbddc, 0xe06b8671,
- 0xd10d8dbf, 0xf054efb3, 0xd5f78f71, 0x04f7fd11, 0xfdf1e3ea, 0xb7cf2bdf,
- 0x7ee4b7bd, 0x01bdf7b4, 0xc60b1dfe, 0x13d63fb8, 0x6ed18b10, 0xf2fb83b9,
- 0xf5846564, 0x7eb8e399, 0x52a3e70a, 0xab4aff85, 0xdeeb9e38, 0x7b987ee7,
- 0x48afcf03, 0x7b705c8a, 0x74fd5e78, 0xc6a09a56, 0xca45c7d3, 0x92091cbf,
- 0x447968de, 0x7cc9efa0, 0x33cbfcd9, 0xf1f391e9, 0x462f7a2b, 0x3634bfce,
- 0x168cfc90, 0x638f0ecf, 0xff2a9dff, 0x7638f3a6, 0xeb44957a, 0xd7e4f64e,
- 0xeb43638c, 0xb0fb83bf, 0x7d845674, 0x6fe383b8, 0xf1db1d9c, 0x3b63caeb,
- 0x1e3113fe, 0xc78c7b7f, 0x6c7961ff, 0x8abaebf3, 0xdbffc2d8, 0x1fdfc318,
- 0x57fffe09, 0xe78407cf, 0x0bcfc3ff, 0x30039f84, 0x17b0f5bd, 0x9d84badb,
- 0xefc33f41, 0x24d6bf8d, 0x93141c80, 0xce7dd3f6, 0x1f3ce505, 0xecdeadb6,
- 0x9d0c2bdb, 0xf5f1501b, 0x23f73568, 0x5eebbca5, 0x04d45efc, 0x829f5039,
- 0xfe72b2f1, 0x59ae4377, 0x898c5e78, 0xc9e63a52, 0xc5f4cde0, 0x5b749760,
- 0x5359e722, 0xe9a2f195, 0x35d58391, 0xe315678b, 0x7c8a3d1f, 0x4a87ff0e,
- 0xe5ea521c, 0x6899e9f7, 0xf34c5f4f, 0x1ed1d3da, 0x9fc93c4a, 0xbc99f827,
- 0x67b2e097, 0xdc7fe62f, 0x7be11b20, 0x26ffc946, 0x1b2bbbcf, 0x60c9d2e3,
- 0xf05e6217, 0x920fcc69, 0x7bd12b3f, 0x66977cea, 0x19ea3f71, 0x9f301303,
- 0xcfca9deb, 0xdf9eb139, 0xe6a6fd91, 0xfc1acef5, 0xca055a97, 0xfc23b5eb,
- 0xf3f9d53f, 0x442b65f6, 0xebcdf80c, 0xf8df2891, 0xe5dff976, 0x9e1e68ba,
- 0xe24c7be7, 0xbf409caf, 0xec78e019, 0xefd12168, 0xffe5e38a, 0xc7fe8cd4,
- 0x3cf09164, 0xe254afcc, 0x78941705, 0x502f1a87, 0xacff5bf3, 0xc03e49c4,
- 0x03940bf8, 0x72810f18, 0x9ddd2cfb, 0x67db4fd6, 0x67ffe045, 0xf21f1e04,
- 0x87c794fe, 0x9c8e8d0a, 0x7f94f3d0, 0x63ef8b35, 0x2fe79fab, 0x0fcf78d4,
- 0x7e14f595, 0xefc7ef4f, 0x9d6e15a1, 0x5f3d446e, 0x0e2b35b8, 0x4fb219cb,
- 0x5ef80697, 0x4eb0fab6, 0x7448bfdd, 0xe75957b4, 0xca4133b6, 0x961abdef,
- 0x8b34bff7, 0xa968679f, 0x097bfbe6, 0xd418a0ff, 0x6e229b1f, 0xb131f341,
- 0xca47d24a, 0x5f80b52b, 0x76b6708c, 0x7c55b873, 0x75edf8b7, 0x53c5cf38,
- 0x1658adc1, 0xa3aec9ac, 0xf5db7bb8, 0xb9bf68ad, 0xae9c6f07, 0xd19978a6,
- 0x43c4fe8e, 0xdbb8da03, 0xfe3cd513, 0xe01a2afe, 0x457bb788, 0xef0b8ff2,
- 0x927e8915, 0xbfe42c5b, 0xde981b26, 0xdc45f58a, 0x4c682a2e, 0x5b3ac3ad,
- 0x60f64492, 0xd27b19c1, 0x714379c3, 0x377be4b0, 0xdd3c458c, 0xc6aacf2e,
- 0xe45b2ed3, 0x5f9fb8e3, 0x7edacf35, 0x6f3a3df6, 0xc54baeaa, 0x8d2f9a8b,
- 0xcf556796, 0x3f1bb83d, 0x70d39cd3, 0x8c06c18b, 0xbd1e163f, 0x5fce5468,
- 0xa1ecb64a, 0x91e16c3c, 0x557f94eb, 0xcf6eadf3, 0xa1abb275, 0xf7fb119f,
- 0xd7f9e26c, 0x2c0e00d7, 0xb2dd617b, 0xdba1ef09, 0x7583eca8, 0x9b63f3e3,
- 0x6ff4a972, 0x7c795072, 0xf8951953, 0x64f4c999, 0xa75edbcc, 0x59d5edbc,
- 0x524dcec3, 0xe8b76f5e, 0x15f108fc, 0x7aa3f792, 0x1f4fde78, 0xee35e3c7,
- 0xbefa0633, 0x99acfba1, 0x5f4d77e4, 0x0ff444eb, 0x9ae73f3e, 0x60777088,
- 0x2e842dde, 0x961d913e, 0x9d83f424, 0xdbe60b0e, 0x1aaffb0a, 0x874c3cf1,
- 0x3c623018, 0xc0cf200c, 0x9eee8b23, 0x6fdcfceb, 0xf1058d5f, 0x58fcdb7b,
- 0x8fcfffef, 0x58fc957d, 0x273f3577, 0x0291caad, 0x8bde4ea7, 0xf2d919e5,
- 0xd89c8870, 0x94f9e4e6, 0x1127936d, 0x4e76ee1f, 0x321d5a4a, 0x8f23675e,
- 0x3bdf245f, 0xfcfa12d9, 0x1f3cd597, 0x67302c96, 0x33567924, 0xc7ddebfb,
- 0xd76e411b, 0x3ffbb244, 0xe5d029f9, 0x238ba04c, 0x90389edf, 0x343f19c7,
- 0x71adb71e, 0x2831c4f5, 0xd8982e9f, 0xd3af1e14, 0x5858e3c4, 0x5c5a2e5e,
- 0x4ea3456e, 0xa179d0b6, 0xdbd404e0, 0x2633f1e1, 0xbd702706, 0xbde0672e,
- 0x83319814, 0xf961b195, 0xdf305fb9, 0xfbc327cf, 0xa4751acb, 0x5d3cd42f,
- 0x36c8a341, 0x6c167d01, 0x3f28f834, 0xa45e28d7, 0xec6fc576, 0x90320a94,
- 0x6b383fce, 0x16ae3094, 0x34731f1e, 0x049eefee, 0x026d1dfd, 0x5dba0bdd,
- 0x073d4f1e, 0x3fdbd2de, 0xf96de307, 0x3d77576c, 0xac9fcff4, 0xf4fcf093,
- 0x3f1e7cf0, 0xd8a05dff, 0x3671e139, 0x4bb433a4, 0x1bf0e3c2, 0x38d83a15,
- 0xd7adeb9b, 0x1d537f14, 0x4e17ed47, 0xcd9d3f3f, 0xb8b46df5, 0xbc6551fe,
- 0x6d82c6ce, 0x177f7193, 0x93ea18e8, 0xf35ac6ce, 0x76f190e4, 0xdbe7e6cc,
- 0x60fcc19e, 0x907e686a, 0xf3c301e7, 0x2b9caa82, 0x037dffec, 0xc8377be2,
- 0x6e63d46b, 0x141fcf1b, 0x8339ab1e, 0x4e086372, 0xc377b7ae, 0xbec8079e,
- 0xbe312473, 0x457bfa2e, 0xc502a3de, 0x7c160ae7, 0xea1e3c76, 0xf74499cc,
- 0x2767dcb0, 0x3ca2b16f, 0xe316205a, 0x53b71ebd, 0xc26795b8, 0xeffdd27c,
- 0xbcefa1ac, 0x7f903e16, 0x81e5f70e, 0x0f9d0366, 0xfddef554, 0xf03534ef,
- 0xc64fbdf6, 0xe0ae7b61, 0x79f1d8b0, 0x763f7d23, 0xfa7e4bfe, 0x110b58bb,
- 0x81e7903a, 0xe44497b3, 0xd716cb9b, 0x151f23df, 0x4cf2522e, 0x3f4f5ccd,
- 0xc0c8b7d0, 0xead3cec8, 0x9f5913cd, 0x46e83c53, 0x8fe5215f, 0x43fcf052,
- 0x29be90de, 0x6c7a0a3c, 0x63d39dcc, 0x112d9d3f, 0x1e82673e, 0x17927843,
- 0xf87d3cf1, 0xf650effe, 0x8a5e9a3f, 0xff518726, 0xde63fbf0, 0x5c36c10c,
- 0xee31db8f, 0x3af68a53, 0xd3a2e394, 0x71661fdf, 0x628a4eba, 0xa149fdcf,
- 0xa7e7a8df, 0xcf27477a, 0x7fd987f4, 0xd563791e, 0x4df352ff, 0xa0f6bfaa,
- 0x65ab0f62, 0xbbfe5293, 0x72a037ef, 0x21bf788d, 0x86fdf239, 0x68090e87,
- 0x1bf7a8a7, 0xcd59194e, 0x4f3c54e1, 0xf277dcab, 0xe93b222d, 0x62fcdfd4,
- 0x78a98beb, 0x509049df, 0x3a1fb51d, 0x1dbe7a47, 0xa7b223ec, 0xe3cb7efa,
- 0xf9f887ad, 0xc8def6f0, 0xaddbdddf, 0x32f5dfd8, 0xaed1b923, 0xe86db79c,
- 0xb744f251, 0x8b8f96e2, 0xb74b71a1, 0x3d56303d, 0x7f23ebc7, 0x8cc71b4f,
- 0x60ecb716, 0xdbb73a41, 0xa07046b1, 0x39ddb87e, 0x79ca5ddc, 0x4c71a8dd,
- 0xb973e479, 0xb94c71e1, 0xb9c79b5a, 0xf7c4966f, 0x680825db, 0xce759aef,
- 0x7fb73a36, 0x9d22904c, 0xcd5a5ef3, 0x257cf4e5, 0xc8d0720f, 0x8560e3e9,
- 0xf06ff740, 0xfbee1e1e, 0x1efc63c1, 0x7e02c1ce, 0x7bcd470f, 0xa66bf7a8,
- 0xe83de50e, 0x2f7a9dfe, 0xc367bd47, 0x5ae08f98, 0x7d1c5cf4, 0xe1876bc7,
- 0xbddb8d90, 0x1a3f7e5e, 0x43e61065, 0x8913cc4d, 0x6bab6b5f, 0xef7a6ac4,
- 0x8f4fdb8e, 0x7bf04754, 0xe91f8a7d, 0x2fea8eae, 0xfad6afac, 0xf70f540b,
- 0xde54ee17, 0xecd98be3, 0x87fbfb4e, 0x9e8f1c63, 0xf1b63b32, 0xfb48ecc4,
- 0xfda2c5b6, 0x5e5aaf1e, 0xb0dfe456, 0xbb0dc5ef, 0x7af5c92f, 0xa7ff60b7,
- 0x1ba7ca4a, 0xcaae9f28, 0x7c31eed5, 0xe3291ffc, 0x294065a9, 0xd77ca3bb,
- 0xbc4a97f9, 0x7b944bac, 0x2f69ee10, 0xd397e368, 0x97e3690f, 0x35937b33,
- 0x78ff7cf5, 0x6785fbcd, 0x8bda6926, 0xda68f703, 0x68142f4b, 0x1503e5ea,
- 0xaf2bf79a, 0xb3ea6ad4, 0x65f8da82, 0x61c5cdf5, 0xb47d38f7, 0xdca01abe,
- 0xe6757ed0, 0xcbde6a6f, 0x575da358, 0xaebb4796, 0xebb51b89, 0xf6cdc752,
- 0xd397d76a, 0x325f5dad, 0xbef2e3e6, 0x7f2e3e7e, 0xc7c95db6, 0xdfb058e5,
- 0x2d938d33, 0xf7a9b768, 0xfef7d5a9, 0x5866372f, 0x007f40df, 0x00000000
-};
-
-static const u32 csem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0xe4b3ff00, 0x51f86066, 0xb97bc10f, 0x726e1818,
- 0x0143f821, 0xd08667cf, 0x0c0c2c6a, 0xc6cc401a, 0xcec0c0c4, 0x717ebc44,
- 0x1d7b044e, 0x4cc30307, 0x31c8de20, 0x481afef0, 0x7e879d7c, 0x42f3a976,
- 0x81c15968, 0x570837f7, 0xb430310a, 0xc430330a, 0x0cf84088, 0x55f2a8a2,
- 0xa9b60842, 0x39766524, 0x0003f502, 0x3471cc24, 0x00000380
-};
-
-static const u32 csem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd554780b, 0x733ef0b5, 0x7993331e,
- 0x0f20f264, 0x0084f102, 0x021842a2, 0x27088784, 0x01a8c421, 0x54bc8083,
- 0x48433c26, 0xbfa81132, 0x2677bd6d, 0xb5ad1104, 0xbc1b6951, 0x14101de8,
- 0xd1a07515, 0x40e81c06, 0xdbdab114, 0xd5a8f8a8, 0x40445076, 0x8bcbc248,
- 0xaf7fd52d, 0xe649cfb5, 0xd4484c9c, 0xffffbff6, 0xdbf3f1fd, 0xd9cfb3ec,
- 0xdaf5ed7b, 0xf6bdad6b, 0x9a32c11e, 0xe4224e24, 0x65a3f85b, 0xf4842784,
- 0x0adb2ce9, 0x64918fda, 0x8b2ffc42, 0x108e36f2, 0xf08e77ee, 0xbc8451a4,
- 0x980b99b5, 0xcfbc3d69, 0x9fad0846, 0x603d34de, 0xff6422ce, 0xef02b308,
- 0x8f9ade9f, 0xbd2fc9f5, 0x7b6814e7, 0x00bc4bd5, 0x13bed375, 0x109d88ce,
- 0xa1e5b9af, 0xf6f3e96b, 0x85b27897, 0x93fc450e, 0x9085244d, 0xfec21663,
- 0x52fab22e, 0x6d56ab2b, 0xf4077fde, 0x2664de5b, 0xd54fda56, 0xaed365ee,
- 0x8765f5a5, 0x54af0244, 0xfa95ab6d, 0x00f2fad2, 0x9afa8417, 0x71c67f7d,
- 0x79480ada, 0x27212870, 0x5f22167d, 0x96ceeb49, 0x79f45994, 0x11676045,
- 0x83b15fbc, 0xfbe89b73, 0x7ff69b15, 0x3457fd0c, 0xda79038a, 0x36ed8aff,
- 0x63610f22, 0x1e604b7f, 0xbc01a64b, 0xc4886f55, 0x97e5eb4c, 0x70044956,
- 0xa54bd424, 0x61ff180e, 0x38c07649, 0x0d1c7087, 0xd0cf559f, 0xd577e871,
- 0x986e702f, 0x7889b55a, 0xddd69e00, 0xda4f39d6, 0xd2b55e61, 0xf77ef860,
- 0xb7bc127d, 0xb2f6502c, 0x36f80655, 0xe700454b, 0xd2d2cda6, 0xadfd9da1,
- 0x0ea6fed8, 0xd90d63ae, 0x76a89ea9, 0x47d27963, 0xacee6c88, 0x04a21057,
- 0x407700ed, 0xf3ac3e9a, 0x812e79f9, 0x3fd0d190, 0x674b644f, 0xc83094ff,
- 0xe8f7fe07, 0xf60f813f, 0xb2db023a, 0xd2b5e93a, 0x772dff45, 0x4bacebd2,
- 0x9ed09fa5, 0x56bfdd17, 0xa074043e, 0x5cfbd4f0, 0x4be23e58, 0x4f8372c3,
- 0xcafdbc46, 0x06cb0437, 0x3f9f1b9f, 0xe58b1be6, 0xe5829f26, 0x2c62be13,
- 0x7c52be03, 0x0e6f8b6f, 0x1e7d5b96, 0xaf94fe7c, 0xbeedcb1c, 0xacfe7c1a,
- 0x772c6eef, 0xfcf8fcf8, 0x2c7adf05, 0x2c7abe83, 0xb01af977, 0xf005f46c,
- 0xdb7d97bd, 0x05f26cb1, 0x5f1ef9f1, 0x5f219613, 0x407dcb18, 0x7d865a5f,
- 0xf01e582d, 0xabe5887d, 0x777e08be, 0xcb1c77d0, 0x3bbc5507, 0x817c9027,
- 0x10a9cde2, 0x92171517, 0x8be4a258, 0xca589eb4, 0xf9b729ea, 0x4f5a25f3,
- 0xc53ad0f1, 0x70cadf63, 0xfbd699be, 0xccf6b0d6, 0x8581487b, 0xacfd33d6,
- 0x4a83c07d, 0x07d69581, 0xc1f6b3d4, 0x7105fc9b, 0xc0383eb4, 0x11deafda,
- 0xfad1b02e, 0x9ed641d5, 0xed932213, 0x66139eb4, 0x94b7dcf5, 0xcf5a0ec9,
- 0xbcf5616d, 0x9d93fd8f, 0x61179eb4, 0x153f8fdf, 0xeb4f1c9e, 0xfb59dbe3,
- 0xd0a44bc4, 0x0913eb45, 0x7b02f587, 0xad02617e, 0xbd58b817, 0x20995fa8,
- 0x7dbfe0c7, 0xa1116462, 0x7fddb0bc, 0xd3a422b3, 0x455914ba, 0xfe9f14dc,
- 0x8b0f5839, 0xbfb43164, 0x84532fe5, 0x912eb471, 0x17fed0d5, 0x1fb6057f,
- 0x6f6c6510, 0xf6c2aff7, 0xed8c9203, 0xb07bdaa6, 0x60a8aafe, 0xbded727b,
- 0x92abfef8, 0x6b83ed82, 0x41fac21f, 0x63ed83d1, 0xef8d7f6b, 0xd83c941f,
- 0x80dac8fe, 0xffeb4852, 0x00b679c1, 0x9e71d75f, 0xfc0d9272, 0xa52b4c1a,
- 0x238ebafc, 0x1e3e4073, 0xf2a6a600, 0x525d2eb0, 0xfbedbf40, 0x3c93de47,
- 0x3276f2a7, 0xf53e97d4, 0xf3f61640, 0xd223f61c, 0xfb9ef87e, 0x58cdf899,
- 0xbf133f5d, 0x69fad729, 0xaceaf784, 0xdf67ebbd, 0xf0f5e337, 0xf5a1537c,
- 0x71fb17b3, 0x135e6ef4, 0x87a09dbf, 0xad4adbe7, 0x4fd8839f, 0x09e0ef42,
- 0xfd74638b, 0x5a65c584, 0x7ec47f3f, 0x1e0ef4fa, 0xeba71a45, 0x6b969147,
- 0xfd887cfd, 0x9faef7a4, 0x1ead74b0, 0xd685691e, 0xa7ec11cf, 0xa5e6ef7f,
- 0xc3d3af98, 0xfad2ae63, 0xcf748939, 0x073f5dea, 0x1cfc7a1c, 0xe7e07470,
- 0xa833c21c, 0x702af377, 0xe053f1ea, 0x25cfc0ec, 0xdeaae7ec, 0xa9c073f5,
- 0x6701cfc7, 0x0e447e07, 0x77ac35e6, 0xd7882af3, 0xbe20a7e3, 0x0e4e3f03,
- 0x3bd119e0, 0xa3ed5e78, 0x7dabcfc7, 0x8a93f03a, 0x1dee8cf0, 0x7a29853c,
- 0x74a614fc, 0x784647e0, 0x9faef5c6, 0xf8f45357, 0x03a53579, 0x3f61573f,
- 0x5e6ef5d7, 0xfc7aa985, 0xe076a614, 0xc9fb1727, 0x78476cf7, 0xd1c7ed08,
- 0xfb073f7d, 0xb073f1eb, 0xae7e077f, 0xd0a67ec5, 0xee7bb27e, 0x8f5328a7,
- 0x0ecca29f, 0x9e2214fc, 0x3f5de86f, 0xf8f53307, 0x81d99839, 0xcfd8a99f,
- 0xabcdded4, 0x7e3d0ae8, 0xf860ae8a, 0xc08c2499, 0x9dae8675, 0x727e9e6e,
- 0x857cbf7d, 0x2ef3efa3, 0x6e5de756, 0xaf0f7602, 0x45a433d9, 0xf6fbe9e1,
- 0x0fb9091d, 0xa6bb6890, 0x8fc076e0, 0xd1795a83, 0xd8fc4d76, 0x951d9d38,
- 0xeaea24a0, 0x757dc549, 0x1d29f7ef, 0x9d4f6ba0, 0x3daeb573, 0xabab93dd,
- 0xd78f9467, 0xa6bfdfbd, 0xe2bf5740, 0xef751bee, 0xd16ff967, 0xcfd7b3d5,
- 0xa83fbdd3, 0xfdaea17e, 0x5d0a86ca, 0x958155fb, 0xdb35faba, 0x7f7ba27f,
- 0xae8d7058, 0x03d3787d, 0xe111f6ba, 0x91f57447, 0xbdd31e87, 0x8b65ba3f,
- 0x87cc7dae, 0xc7daeacf, 0xeae97645, 0xa3df1ed7, 0xf6baff7b, 0xa4faba03,
- 0xbdd7bf8b, 0xd5de4f9f, 0x3f96dbdb, 0xe29fdeeb, 0x7ed74cfa, 0x0697da7d,
- 0x3aeed53b, 0xe75a8d76, 0xfa08ae41, 0x0974fe25, 0x43b0d5ed, 0xd7d4bac2,
- 0xc714fcce, 0xe528f952, 0x22c0e91f, 0x92f91939, 0x21bb51fe, 0x95f96fbf,
- 0xaefcfa11, 0x5d2b9ef1, 0x925df9f4, 0x862bb867, 0x8df9437d, 0xca506923,
- 0xed8d2826, 0xdf8c89f7, 0x0d2e320b, 0xf7bf423e, 0x2707da9a, 0x3e70fad0,
- 0xf1f2083f, 0xbb426732, 0x35278e3a, 0x999c5ef0, 0x5f74dfa0, 0xfe93de56,
- 0xdf587928, 0x5c19da9f, 0x45ebbf67, 0x51da1a4f, 0xc1f89fb5, 0x9fd759ce,
- 0x212fabce, 0x849f70af, 0xf7e903fd, 0x79a697fd, 0x89667f68, 0xe3d119fa,
- 0xa1fc744b, 0xe4187e38, 0x3f8c20e1, 0xe6f8ebba, 0xe3756301, 0x75cb325b,
- 0x3a245be3, 0xdf908bbe, 0x8eae7ed7, 0x9e30894f, 0xcfb93790, 0x66737c71,
- 0x9f7f8e39, 0xe8aefd44, 0xc63ae3f1, 0xbff9816f, 0x07fcdddf, 0x3fcfd78c,
- 0x7f3f42b3, 0xa3ffcd89, 0xf8ead3da, 0x3fff3871, 0xfcd9a773, 0xfcd82b33,
- 0x8edfaccd, 0xf81d9df1, 0xc7f8c08f, 0x9cdf19ba, 0xff3f413d, 0xf3f52a2b,
- 0x4ff1b337, 0xc7505ed6, 0x5ff8e3b7, 0xfcd81772, 0xf1c4a8af, 0x0dc7b325,
- 0xc46523fc, 0xf8e804d5, 0x7c551fa4, 0x742ec0a9, 0x2487281c, 0x6421a152,
- 0xe100371b, 0xf18e2bb8, 0x947157db, 0xf99f50df, 0x500939f1, 0xfd4799cd,
- 0x57d79546, 0x4097c8ec, 0xf53b61ef, 0xa0a896b7, 0x91e26e2e, 0x7306c9bf,
- 0xb7851060, 0x43f789b5, 0xeb86f17d, 0xbd5fa002, 0x14a0b266, 0x184813be,
- 0xcbfe7f9e, 0xe7a25b61, 0xd4972c65, 0x5122c78b, 0x07e1d6f2, 0x35219016,
- 0xc029be14, 0xeb3ba304, 0x0e3f529f, 0xa98fe31c, 0xffa843df, 0xc6c899f3,
- 0xf7f50bfb, 0xfea11ea0, 0xa4ce3a1e, 0xdda3bf16, 0xf0a34e1d, 0x7ff0aa97,
- 0xfd79302a, 0xe02e36f4, 0xd5f9f2a7, 0x7fa0478f, 0x1b6ee0bd, 0x1c277a45,
- 0x5d24fe65, 0x0fcbce9d, 0x6ddf6a74, 0x10e16c0e, 0x6be032bf, 0x21268a3a,
- 0x5067d68b, 0xffbe775c, 0x07a9bec1, 0xb7212739, 0xa54c4512, 0x9abedfef,
- 0xe3a2efeb, 0xb9cc52ce, 0x32521d6c, 0x24d7284c, 0x909634c3, 0x88471a5b,
- 0x5d3207b4, 0x448d3f11, 0x58a33b8d, 0xaa559f5f, 0x8a8ab7af, 0xb570a268,
- 0x66c8e74e, 0x39ecefda, 0x9c6d76fa, 0x4644a681, 0x52bc7567, 0xfa74938a,
- 0xb9943668, 0x7485d8f0, 0xdf62e39e, 0x1778f06a, 0x7e8c2489, 0x010fbfbc,
- 0xf193faba, 0x362e79bd, 0x73bc236f, 0x4a528b44, 0x8ca739e7, 0x1b7f000f,
- 0x9f68ffe1, 0xd0e5314d, 0x22a3fd72, 0x8f9d7531, 0x1eb9fe11, 0x22827ce3,
- 0xcbf3f3ac, 0xdf19cf8d, 0xffe9531c, 0x2d07f029, 0xa0fe00bf, 0xf9551ff0,
- 0x32af53a3, 0x3d9af0fe, 0xda1f80d3, 0xe904f237, 0xadcbf2aa, 0xa92cbf2a,
- 0x2105f3d7, 0xb8e8111e, 0xfb970e6c, 0xcc1f1440, 0x5960f956, 0x6e6f9e83,
- 0x3d317e27, 0x6ee65d06, 0x9a6f7cd8, 0x9f7e75dc, 0xff337ca8, 0x9f88fdc1,
- 0x7464f3ae, 0xd3a543ba, 0xf6fa35ed, 0xdeba555b, 0x4e75d2ae, 0x51afc3c3,
- 0xc9e641f5, 0xdde41101, 0x9e8d53fb, 0x3d3d1d11, 0x708d3d2a, 0xf3d2a1de,
- 0x7a331f8e, 0xa88de11a, 0x9c348cf4, 0xae80c913, 0x5be11af0, 0xf9977770,
- 0xccab5c60, 0xde9e9b1f, 0x4755fca6, 0x05579ea3, 0x3475586f, 0x6c56ce4a,
- 0x2fabae9f, 0xbdd5cc0f, 0x4ca1acbf, 0x7ea4bed7, 0xd17daeb9, 0xf5753bfa,
- 0x758fff32, 0xbbb82fef, 0x7b7ed756, 0xf6bafdcd, 0xeb0fe5f9, 0x1b3d73ea,
- 0x9ecfef75, 0x3ed759b3, 0x5d19f4ab, 0x9de28cfb, 0x6574faba, 0xd37deeb7,
- 0x066eabbe, 0x3deb7cfe, 0x713d809e, 0xc605fdc1, 0x45b82f33, 0xd473bc37,
- 0x1f5f2327, 0xf2c10df3, 0x7c8dcfb8, 0x1637d27f, 0x66a6d6cb, 0x7413ac3b,
- 0x124a5c5d, 0xcd326908, 0x0fdf5dab, 0xeb8269d6, 0xa9e4c869, 0xb37ad3f5,
- 0x28794649, 0x78489069, 0x2c1c2124, 0xed1c2a36, 0xa47b547c, 0xaa06f687,
- 0xb6ba93f8, 0x3f624497, 0x76523ef7, 0x7765f005, 0xcbfd03eb, 0x4da7bb00,
- 0xed8debb5, 0x8d291c95, 0x1ac84e7e, 0x626ac384, 0xc4a54776, 0x5772bfe4,
- 0x4271017a, 0xe6b83c3d, 0x2905e372, 0x9f02a793, 0x78e4eb64, 0x3a35c359,
- 0x9a204efd, 0x6df807dc, 0x8af9eea4, 0xbeead7ed, 0x479fb53b, 0x5741abb8,
- 0xb165838c, 0xe81333f4, 0xe67370e1, 0xa700618c, 0x4deb1472, 0x3c2ed07d,
- 0x755e2be5, 0xafd01074, 0xbee3cb14, 0xf31e5839, 0xea3cb079, 0x53f2c72b,
- 0x11960d5f, 0xfe58dddf, 0xf2c7e7c5, 0x2c7adf63, 0x63d5f23f, 0x01afa1f9,
- 0x017df7cb, 0xb6fb0f2c, 0x2f8ef963, 0xaf8b6588, 0x9f56cb09, 0x7726a582,
- 0x71ddf13d, 0x093e1d75, 0xcf8317fc, 0xed7f3aa4, 0x7c9d09fa, 0x87dfc716,
- 0xb9e1a67c, 0xf2acc1a4, 0x1f8e8a43, 0x4397c012, 0xbda1eb3e, 0xb0f95441,
- 0xb763efbb, 0x6bfcb77b, 0x0fea6df8, 0x7e4eb7e4, 0x53f030ca, 0x34fc4f76,
- 0xa7e28f8c, 0xb31726a9, 0xfa7e547b, 0x8623cc19, 0x8c0f315f, 0xf6513e90,
- 0x826f929a, 0xbaa56c75, 0x601f420f, 0x763aacfd, 0x05b77d1d, 0x10c0baed,
- 0x0ece3758, 0xd860dbf9, 0x21fb3847, 0xf7567e25, 0x49f233f3, 0xd05778f7,
- 0xa01a59bf, 0xdaea4f44, 0x78638d6e, 0x31489ab5, 0xfddaeba1, 0x2f729e83,
- 0x81758a1c, 0x01f7c224, 0x8c4774f7, 0x0cada97e, 0xaf09edf8, 0x72af8e75,
- 0x8f63bfa0, 0xca0f3dfd, 0x2f6626a9, 0x68f335c7, 0x93f093b7, 0xc76fc06e,
- 0xa77664ba, 0x7dbdbc41, 0xbb42e490, 0xe3d64c81, 0xc3a05fcf, 0x4714fddf,
- 0xd6eeb82d, 0x06fe21a7, 0xbd38357e, 0x49ebf817, 0xcf84f7bf, 0x7fef3085,
- 0xd27b3e01, 0x45e93d8f, 0x342fc8a2, 0xedb7f9d1, 0x80fb961b, 0x1e5ee30c,
- 0x9afedadf, 0x7e5f9e11, 0x4b6e3e47, 0x25b8f8d1, 0xa41f8093, 0xc6d9cbca,
- 0x2e81e32b, 0x40f4fd1d, 0x9f77ee4f, 0x7eff8264, 0xdfdf4b3a, 0xe2fec67d,
- 0xa70dc225, 0x89243ae3, 0x92bf53c4, 0xd1e36cf7, 0xfc47719f, 0x67d83710,
- 0xe0c9d773, 0xaffc9e37, 0xeb3d0cb0, 0x0f670be3, 0x3f04e93d, 0x5f1a656c,
- 0x1d063473, 0x982ab2b5, 0xf68f6355, 0xf5f49a57, 0x715cf5b3, 0xc725e710,
- 0xeb061ccf, 0xa8e6ab8c, 0x0d3f7a08, 0x959fad4b, 0x738e1269, 0x3c767b72,
- 0x4c02fff3, 0x4048ec9f, 0x67d2737d, 0xd9fff7c1, 0x8fd774f0, 0x8d210f06,
- 0xe80b33e4, 0xdd96da73, 0xcaddfbfd, 0x825e7083, 0x890929f8, 0x69bf815f,
- 0x3b7fffa5, 0xb015fa00, 0x0debf5ae, 0x70f37ef2, 0x3743be78, 0xd64efd1e,
- 0xbbe18cf6, 0x204ee5ee, 0xa7be34c7, 0xbaabfbf4, 0xbb62bdbf, 0xc76f46b5,
- 0xdeeae826, 0x9d1af4a6, 0x00ff0b5d, 0x1386bdc3, 0x54ab0960, 0xb04db0d9,
- 0xda7e07af, 0xf049c103, 0x5ef6385f, 0x79222595, 0x16971464, 0x6385d3e0,
- 0x6797fe35, 0xa9ea99ff, 0x048a6f13, 0xa25c8ce4, 0xaea9e550, 0x899bf220,
- 0x917d6898, 0xc6c2f6fa, 0x6eb02515, 0x26f9789d, 0x931643f4, 0xc7f82752,
- 0x0f3ea4e5, 0x89a7b5e2, 0xf3e418a9, 0x39c77934, 0xad1e4a32, 0x2e9d8482,
- 0xe3b7af5a, 0xabaf7fa9, 0xd7d06b2f, 0x525b9297, 0xe97edf60, 0x38049106,
- 0xf6fa1bd0, 0xf61779af, 0xacd48cbb, 0x57fb7583, 0xa16bbc6a, 0x5419088b,
- 0xf6fd556f, 0x0a32bcf1, 0x71604b87, 0x7a1f6d16, 0x7ff32279, 0x2406662a,
- 0x59ffbe85, 0xa95bc8e3, 0x07dfa206, 0xbc7ec1d6, 0x6f713a7f, 0xf7e95d23,
- 0xc237e15d, 0x5d03d9ab, 0x3855c3f6, 0x4a73b792, 0xcb1e8620, 0x67263814,
- 0x102bbeaa, 0xc7b8ba5c, 0x7bfd4334, 0xd13253f3, 0xde1ed3f1, 0x668c2793,
- 0xc0fc03fc, 0xe792ed09, 0xd69ff487, 0x7f82ffa5, 0x68fdff6a, 0xfeba79ff,
- 0xfb53fda7, 0xfe05d81f, 0xaffab179, 0x2ff3edfa, 0xa93ea9fb, 0x4e97f178,
- 0x13c9d742, 0x9b8a7d42, 0xdb72b5d2, 0x96854ebd, 0x13bf05c7, 0x8044f5f8,
- 0xef458e2f, 0x154e0587, 0x41cec542, 0x49fe0ddc, 0xecf93ffb, 0xf11e30cf,
- 0x85d136d5, 0xe6edb4f1, 0x61ca99b0, 0x12f2e375, 0x23f58392, 0x19df7eac,
- 0x7a4dea1e, 0xfa78abfe, 0x1f902997, 0x8d453942, 0x9ed1852f, 0x79fadead,
- 0x5e4fac11, 0x64728ed2, 0xbfc60efc, 0xaffa8898, 0xdaef8a4c, 0x38c4e14e,
- 0x8bc55781, 0x6767f1b7, 0x37942778, 0x82fa017c, 0xc7e8227a, 0x572bbf1b,
- 0x8235d4ed, 0x8d98f923, 0x190c7bfe, 0xc3517a03, 0x3b30090b, 0x5f99eeb5,
- 0x70a11ce7, 0xa6fada9d, 0x97c28b93, 0x83674f26, 0x8f73fe8b, 0x6ddebddc,
- 0x6d16f2a5, 0x96eb690f, 0xd7daa4dc, 0x8a565621, 0xf3e42761, 0xdd166e54,
- 0xf2b8fa7e, 0x7a9f27f9, 0x7f99e20c, 0xd107bb32, 0xff3c57fe, 0x69e3fbda,
- 0x314ec57d, 0xc34d84b9, 0xd274a5ce, 0xbfff4bc7, 0x1e93b73b, 0x4d79bf15,
- 0xe7b18792, 0xd27624f7, 0xfdcec565, 0x15d61912, 0xfb83931f, 0x063d88a5,
- 0x8a47827d, 0x7ba85ec0, 0x8825bfe6, 0xc7d89e33, 0x18acd491, 0x1afcdcf8,
- 0x278003da, 0xaf4aa7a4, 0xde19fa0e, 0x80ba52f7, 0xcbd236de, 0x5522def8,
- 0x90bf40bf, 0xfbf94167, 0x07903d85, 0x0dd991f5, 0x617f2878, 0xf3e61395,
- 0xf8c35085, 0x537bf1fc, 0x8b959f40, 0x961714fe, 0x13f979ec, 0x5bfe423f,
- 0x528ff6f6, 0x9444be30, 0x45ae1374, 0xe79874fe, 0x70b34d92, 0x07894b9e,
- 0x71fcb0f9, 0xcb4034be, 0xde29020b, 0xac4e4319, 0x2f939322, 0xd2e250b6,
- 0xfe017e79, 0x77efe824, 0xb436c0f8, 0xa024efbb, 0xcea47e0f, 0x580c5a85,
- 0xf46160bf, 0x2ebaabfa, 0xa33eb010, 0x7deb77f9, 0x93a7402d, 0xd85495fd,
- 0xc112f177, 0xfb83e2af, 0xbfcbf696, 0xd195253d, 0x9e42c889, 0xf75d1dfa,
- 0x7873c327, 0xac5445bf, 0xc8efba39, 0xe39d59b7, 0xa7c756af, 0x7ac1c770,
- 0x6c4a45fd, 0xd44f35fb, 0xb75d00f4, 0x4a2cf8a3, 0x6ffc99de, 0xbbc99fbd,
- 0xe981ff26, 0xfe7ed0c5, 0xf8239330, 0x0a43d60e, 0xdb153857, 0x50e4cff7,
- 0x3a3f503f, 0x156f9c96, 0xb7d73955, 0xc285f91b, 0x51f1702f, 0x24e3037c,
- 0xdf701d22, 0xfa06e965, 0xf51e947d, 0xaeceb8c2, 0xbc726afd, 0x455bf34c,
- 0x9b203ebd, 0xdee81e98, 0x9e23f2ae, 0x53c0c52a, 0x52fc818f, 0x20cbf579,
- 0xcc2962bf, 0xcd1dcbff, 0x72a3cfef, 0x935065fb, 0x355ebd5b, 0xaef96dca,
- 0xdc9624d1, 0x9377697e, 0x9f4b7298, 0x7b5b94c7, 0xfff9f904, 0xf0d55eb4,
- 0x78f00c38, 0x351e274d, 0x3e1dd93d, 0x90f27a8d, 0x8d5e2320, 0x1dfe927a,
- 0xf95d7926, 0x8d43e351, 0xab9e2aff, 0x51f402ba, 0x7c6a9f07, 0x1aa7c1d8,
- 0xef89761f, 0x6c68f0ea, 0x34fb00bf, 0x96f9ae14, 0x528ed38d, 0x4ed2d257,
- 0x7f26df70, 0xaafb8f26, 0xe584f396, 0xf3111081, 0xd5303f43, 0x753b068c,
- 0x3d6fdfe2, 0x7785177d, 0x2c8bf13e, 0x445ea02f, 0xb7d2ffbb, 0xf3a04edf,
- 0x79e2a799, 0x54fb453e, 0x0239974a, 0x70a38e17, 0x3f8815ce, 0xb7e2113e,
- 0x0a34f91c, 0xfae5f98e, 0x4c4dfc3a, 0xa7a7ece9, 0x9fabbff7, 0xb7cb7df2,
- 0x1d3f5d29, 0x50bbc844, 0x10bc388a, 0x81d357cd, 0xde7f14ae, 0x00605c51,
- 0x5088a9ea, 0xbd77e51a, 0xf3fb3220, 0xa319c2ed, 0x9fc9bec1, 0xf19e2c3d,
- 0x7bf460fb, 0x3b3eaabd, 0x41e397eb, 0x650d9fcf, 0xf67b7fa3, 0xac4722d0,
- 0x9566d0bc, 0xf7535ecf, 0x5cecda5d, 0xbff94f3d, 0x7da3b48d, 0xc95bb7e3,
- 0x82fb18b6, 0x5f4d451b, 0x7fa374ab, 0x8e7f1d3c, 0xe97387ca, 0x51b9f1a7,
- 0xf5399b74, 0x4aece084, 0x34fbf807, 0xa1fb0fca, 0x06be05f8, 0x235b36fc,
- 0xe231a545, 0xf8a9cf79, 0x6be0789b, 0x0c2dcfcc, 0xc7800be5, 0x8baf3b42,
- 0xc9a93c83, 0x143250eb, 0x60789ae0, 0x5347cff9, 0xe21ef63e, 0xeb8f90dd,
- 0x3c919d0d, 0x2361fc31, 0xb07fa13e, 0x2e888f33, 0x627bd7c4, 0xebc012e9,
- 0x04acb37b, 0x95df35f6, 0xe0b155dc, 0xf5b3332c, 0xbd292e66, 0xbffb8a30,
- 0xb3f9bf0f, 0x8a02e11d, 0x9676b38f, 0xff95ddf7, 0x759fdc98, 0x0e5a8171,
- 0xf56790f8, 0x71002e64, 0xf9e222b4, 0xe50e04f9, 0xfeb4527d, 0xfe9a6fca,
- 0x54f5e43c, 0x89973887, 0x110b57b6, 0xdbd8f809, 0xfb0053b4, 0x289926fd,
- 0x6a108f18, 0x8a8ccd86, 0x05111d7b, 0xdff357c4, 0xf80edde6, 0x4cd3373d,
- 0xe8652e00, 0x01d82719, 0x512342e7, 0xd79bba0e, 0x5a647c1f, 0x10fd08a1,
- 0x3f230fe4, 0x74db2514, 0x499359f5, 0xdba5373f, 0x95647344, 0xeafd063b,
- 0xbd67c624, 0xff966fd6, 0x04dbf4cf, 0x5f18dfaa, 0xedfad18b, 0x7df18926,
- 0x8d4b7e94, 0xd656dfa5, 0x17c0a9ca, 0xa766f72b, 0xbe575d02, 0x2c4fa4b1,
- 0x8fbaf6fd, 0xa86ff7f9, 0xfd6de679, 0x1e1b7ea8, 0x51fadfa5, 0xae2316fd,
- 0xa5ea5a3b, 0xcffcb37e, 0xa0ebdfc8, 0xb7cc62df, 0xa69fc558, 0xb5438adf,
- 0xfb8adfa8, 0xa97cbaf1, 0xfa4f5249, 0xb397ecad, 0x6dba2eb0, 0xf007f831,
- 0x0dedfa0a, 0x38c1cf55, 0x5dfee7a0, 0x3d277d72, 0x3d5bd557, 0x67843ff7,
- 0xecadcf4d, 0xd33da1cf, 0x9e990f95, 0xf4c5995b, 0x4cbdcadc, 0xc41cadcf,
- 0xbf519cf4, 0x6fd17415, 0x21eafbec, 0x23f47bf4, 0x1b7d7eb3, 0x23992f6d,
- 0xfdf42dba, 0x9f3b5912, 0x5a3a3351, 0xd4bbfddf, 0x9f73be8d, 0x3d2e73c1,
- 0x823fbbe9, 0x7a841bbe, 0x91c8206c, 0x1c6e3f91, 0xd3e5d368, 0xb1f5f7bd,
- 0x79045ee7, 0xfe8f03f9, 0xe62607f7, 0xfafbed27, 0xbb9048d8, 0xaa1e00f7,
- 0xf9519eef, 0x47e7d5af, 0x28793a7d, 0x7baaf793, 0x1baafe18, 0xd5df3639,
- 0x7586407c, 0xd1176fe0, 0x2f7dbe8f, 0x9b67a3f3, 0xc0d8fa5b, 0x225fffcf,
- 0x2bfd25ca, 0x87e28b29, 0x302b1739, 0xce2bb9ee, 0xccfc05b9, 0x80b10239,
- 0xd0e0bb1d, 0x7ec0278d, 0x3d71705d, 0xe00bbdda, 0xc8e92279, 0xa1db98fb,
- 0xebf6f527, 0xaf9da6bc, 0xf9ae9065, 0x8ccd1310, 0x7157132e, 0x5d59cd81,
- 0x5da823f3, 0xc62df986, 0xabdf893c, 0x47cd9ff3, 0x8fe45f10, 0xe5f8cc7c,
- 0x72788def, 0xad54bc33, 0xaa78f5e6, 0x89e262e1, 0x2ca4ba52, 0xb72f13a5,
- 0x975914bf, 0x39cbed01, 0xf38cb7f4, 0x9c66f0d6, 0xcd4786bf, 0xbea059bf,
- 0x24743f3f, 0x86889e66, 0x22f92ee7, 0xf80dde1a, 0x33d34b78, 0x206190d7,
- 0x3c981f97, 0x7c0d1f3f, 0x178a7bf4, 0x73ade70a, 0x2bcee907, 0x65e2a3bd,
- 0x6148e7aa, 0x24780c8a, 0xf367c035, 0x96be77ca, 0xb377e742, 0x210b9592,
- 0x937f59f5, 0x688f103c, 0x1ea3b6b6, 0x9470f8d4, 0x5985c999, 0xf5ef2bd5,
- 0x7ae21575, 0x50b9c4d3, 0x3d06c2be, 0x7999e6a7, 0xd7f261ef, 0xbaf7fdcc,
- 0x6788518c, 0x91482e58, 0x5d015eb6, 0x86a73fe8, 0x40bc5d18, 0x69cffa17,
- 0xe020fda4, 0x73993abd, 0xa6fde187, 0x3f02f79d, 0xcfa56ebd, 0x39cbce41,
- 0x0e8616f7, 0x65ca7a7b, 0xc58858f9, 0xc8cc18c7, 0x173f5ceb, 0x5d897bc0,
- 0xe68993ed, 0x8e00f796, 0x366e5489, 0xfd00c3c3, 0x46fe8a2f, 0x07c8c5fb,
- 0x7503e53d, 0x2ab9efc7, 0x3a075f9e, 0xeddf01d8, 0xde43d812, 0xb47f5b30,
- 0x1720af76, 0x3a34de22, 0x65f5d134, 0x2983a314, 0xd66f9e06, 0xbd9e2aea,
- 0xef844e21, 0x6ffea06f, 0x7ebb0712, 0xf8d41f5f, 0xc5772cdd, 0xd215c413,
- 0xe806f4a3, 0xcd7de8b7, 0x11b7a6ea, 0xa6ae375f, 0x15dc99e6, 0x407d1a5f,
- 0x6f0e5e0f, 0xd34fcadd, 0x61799891, 0x467e55df, 0xb3f2f599, 0xe6fedacf,
- 0xedab8870, 0x90af50e5, 0x7e2e8250, 0xecccd330, 0x07ab6696, 0x0dfdbcf9,
- 0xee45bdd1, 0xa8a67faa, 0x257f0174, 0x64e27cfa, 0x4de80898, 0xa67c9597,
- 0xe3007bcd, 0xe0f5e8b7, 0xe907ab75, 0x33ff5dd7, 0xedfecccc, 0xead31ece,
- 0x9078c3d7, 0xc7eb28d7, 0x5a47ae33, 0x79a7a95c, 0xbf71d479, 0x71b4bcef,
- 0x84beebbe, 0x3c60b497, 0xd89fdb4e, 0x89767bc3, 0x73163f60, 0x0a107dba,
- 0xfe6fee39, 0x59bffa13, 0xff7ddd1a, 0x530a3f10, 0xe3bebf3c, 0x9f638c49,
- 0x34c8f67e, 0xaf159f90, 0xe542c4f0, 0x838775af, 0x889e5984, 0x45427604,
- 0x5dfb8f23, 0xcde70844, 0xa833b288, 0xf1f0c327, 0x5ef503a2, 0xa0732ec5,
- 0xf15f7e84, 0x103967f2, 0xc35d6b7f, 0x59ff9ff4, 0x91fd1f95, 0xa807c81c,
- 0xbcfed810, 0xa88f3e91, 0xb76a79fc, 0x6fe80e6d, 0xc73b3b6e, 0x2d9c115b,
- 0x0ce2a39a, 0x16459bf7, 0xc36ddee7, 0x33ff6c3c, 0x0331e61c, 0x48e7d17c,
- 0x53d0fcb5, 0x5cbd30cf, 0xe00624d1, 0xf6c5703c, 0x1710ad9d, 0x8cd0f8af,
- 0xfb77abf6, 0xd3ec0919, 0xcf3e2fc9, 0xf1371bce, 0x976878ba, 0x3e76e438,
- 0x59f8866c, 0x01ea1563, 0xf5823f5a, 0xfbf71aa0, 0x15b2718e, 0xd97dee2f,
- 0xe2b8514f, 0xf13b4f37, 0x36cb705c, 0xb723c627, 0xa05f7e5f, 0x7831dc4b,
- 0x9c771abf, 0xf5c105fa, 0xf1dc7621, 0x2127caa4, 0x48ee3eb3, 0x3c6127b6,
- 0x5799c292, 0xd17e231a, 0x5fcfffc1, 0xcdf60278, 0xf2faed4e, 0xf2bb8009,
- 0xfc4f739b, 0x2a93e294, 0xdbac1720, 0xc3df67de, 0xbbed067d, 0xd27d55f7,
- 0xb8d3ccfa, 0x27fad34f, 0x6b7a1bb3, 0x2645fbdd, 0xeeb453ec, 0xe2053afc,
- 0x4ef7abb8, 0xf56d7f41, 0x4953934b, 0x2b407f0c, 0xbd037f81, 0xd23227d8,
- 0x39b1b9ad, 0x4d3ce013, 0x77eb0ee9, 0x58393c47, 0xb2f4e2c5, 0x11de471a,
- 0x4bae5f7b, 0xc671b8dc, 0x3ac1d7cd, 0x65ba28de, 0xf1f88bd2, 0xe1cf4a61,
- 0x0ee3a0bd, 0x38209f75, 0xe3f1b2f5, 0x4a0ff0d3, 0x7d660baf, 0xe342fe1c,
- 0x0c7cff92, 0xba931ada, 0x7b871f8d, 0xdf6d3f81, 0x2159bf6f, 0x5da39016,
- 0x1edc61cf, 0x0f7d47e8, 0x85fcfad2, 0x1cbb884c, 0xc0efdb17, 0x66bdebfc,
- 0xd8aaa3cc, 0x53ca01fb, 0xe36f4beb, 0xf7511abe, 0xc7495adf, 0x5127db1f,
- 0x56ef3a7d, 0xab3b8b07, 0xb4b88074, 0x6ae7c4ec, 0xb5f199fc, 0x2eee9716,
- 0x32d63d1e, 0xabbfed80, 0x5b5591fb, 0x43112cff, 0x0b1b9fbc, 0xd9723af4,
- 0x0f0d547d, 0x98c3c02e, 0xd896fde8, 0xfd8efff1, 0x80dd0316, 0x758f609e,
- 0x7ad0a7ec, 0x07ab883f, 0xed620fb8, 0x666eb5df, 0x62ad34fb, 0x6d45bcec,
- 0xc5a465ff, 0xe812efb0, 0x4f4bbedd, 0x78aef8f3, 0xb42706ca, 0x9d7c574f,
- 0xbf5b14ba, 0xd4e16adf, 0xe7be037b, 0x67257ebe, 0x05981bcc, 0x78d5597c,
- 0x4a7b0244, 0xf9b4df5b, 0xe7fd529e, 0x78f2cf53, 0xb05d644e, 0x51bbf519,
- 0x1613547f, 0x5bc23437, 0xab7a616e, 0x1fad89ba, 0x023976a7, 0xa9cfda76,
- 0xaf91bb03, 0x911c77ab, 0x83bfb4fc, 0x45237fdb, 0x60acf2a2, 0xc14408fd,
- 0xfd85ea7f, 0x897f6c39, 0x71c6ebf9, 0xf1c752ee, 0xe38f6286, 0x374671dd,
- 0x507f0ace, 0x2e7ee762, 0x4149de3f, 0x9dfd0d99, 0xe409116c, 0xf20c9ffd,
- 0xe31881c5, 0x5a88b5cf, 0x0fc98b3c, 0x1cf1475d, 0xbb9d83a6, 0xb42513e4,
- 0xc63b57bb, 0xfde7087e, 0x19243b57, 0xb57517e2, 0xeeb52f2c, 0x4069dcdf,
- 0x5b84baef, 0xdeae3f71, 0xb2575f80, 0x1ae21f2b, 0x51d2c2ae, 0xbd46aec0,
- 0x7498a093, 0x1476aff0, 0xce14caa7, 0x469daab5, 0x0b9e3704, 0xc5459de5,
- 0x65de1f30, 0xec635972, 0x52f6883b, 0x8bc289e2, 0xe39fd2e8, 0xca469724,
- 0x7f968fd0, 0x39696953, 0x052e8d88, 0xb1858c53, 0x99fcddec, 0xdb779c2e,
- 0x507fd50e, 0x614aec88, 0x8eb06479, 0xcf8aedb4, 0x43f1c321, 0xb47e50a2,
- 0x1db9cfa9, 0x5e83f7fb, 0x4a24eb5a, 0x8a339502, 0x86cf9955, 0x2c23acf3,
- 0xe9f0365c, 0x857aff99, 0xf10d6bf6, 0xd9b457e8, 0x25527cb5, 0x46cce401,
- 0x41bcc41e, 0x936fe560, 0xe634e13a, 0x25781213, 0x298d3eea, 0xa1fd1dbc,
- 0x7c589bb3, 0xff572780, 0xcf8b027a, 0xafc00091, 0x542b2fae, 0xe212cf38,
- 0x3bfbc30e, 0x580f181c, 0x9422c6f6, 0x3443a01f, 0xf58a92be, 0xac1b5ee7,
- 0x67f01cce, 0xbf555a36, 0xc0b4afc6, 0x6ac59b39, 0xf54a7dbf, 0x18a962e7,
- 0x975e41fa, 0xe5faf2a8, 0x9843a2d2, 0x8a59e68f, 0x8e753e7a, 0x31acdcfe,
- 0xaa204b4f, 0xfe601c9f, 0xadbc9773, 0xb708cda6, 0xc56b7f31, 0xc35d7d76,
- 0x37a027e3, 0x127402af, 0x80e2e5fb, 0x3237e23d, 0x4613d7f8, 0x9afc777d,
- 0xb5f8f4d3, 0xdafc7aca, 0xa7f11886, 0xadc3afc7, 0x97e697c7, 0xf8df8776,
- 0xc873fab1, 0x8afc2aff, 0x548ed556, 0x4aff4af1, 0x654c292d, 0x42e9dc03,
- 0x28c2e518, 0x30f61947, 0x9feeff07, 0xafc5a81c, 0xefd40edc, 0xb87cea69,
- 0x1b3becc5, 0xf00f11c8, 0xe08e51ba, 0x79e82024, 0x75d8f91b, 0xfac40acc,
- 0x4d7b7c8c, 0x355cf4f7, 0x0b23d5fd, 0x809b57e9, 0x3f23877f, 0x89bef3b0,
- 0x05975024, 0xc176ea72, 0x59f41dfa, 0xb8458bdc, 0x17b885f7, 0x5efb820f,
- 0xa43e585c, 0x0db4abe6, 0x306e7825, 0x029f3e18, 0xdca1e9fa, 0xf7a069f6,
- 0x29484bbc, 0xc51fc1e8, 0x0f03f3b1, 0x38bf65a8, 0x85abd549, 0xef824c6f,
- 0xe70ca243, 0xdb42dbd5, 0xdea0832c, 0x2a3de3c4, 0xabfa84de, 0x90d6fc60,
- 0x6c5ae0c8, 0x38820c09, 0xc7115ec8, 0x013c5d6d, 0xd87665cf, 0x2f96216f,
- 0xccfa16d2, 0x9f4a28b9, 0x7a3d36b7, 0x36b9c415, 0xa9e7629a, 0x7e9ab14c,
- 0xec1bfad8, 0xc537b792, 0x1eeaf2ca, 0x51e7401a, 0xbaacfd3d, 0xb879330e,
- 0xabf3a556, 0xf9c46f4b, 0x64e214bf, 0xf88a4758, 0x461a6edb, 0x3dee39e7,
- 0xb0cf8d41, 0xf528e578, 0x2fd03afd, 0xdfeb5fa8, 0xddc3e9e5, 0xe7020547,
- 0x2cd546f4, 0x15eb7f45, 0xca73e527, 0x704a7917, 0x616df024, 0xcdef0128,
- 0xd04c7ef1, 0x22dd1fae, 0x4f33f8e8, 0x22f3575d, 0x44c05e54, 0x3edf50f9,
- 0xec18222e, 0xfc0f00a0, 0xfd71ed75, 0xd55685f3, 0x149272ee, 0x970df3e0,
- 0x5ef20e78, 0x7b89dadb, 0x6dbb850d, 0xa3845f71, 0xfa9c3ced, 0xbe25e5a5,
- 0xbf7ad638, 0x62f8caca, 0x9d7044a3, 0x8ed4b8d9, 0x4b03c5f1, 0xf580ae2b,
- 0x7b1fabfd, 0x8e7588ae, 0xc53f4a3c, 0x252c7cb3, 0xfe058c9e, 0xbc31cb5e,
- 0xc697a7d7, 0xf8d7f7c8, 0x8d6fe359, 0xc697d3af, 0x35e56279, 0x7665637e,
- 0x21d2c15a, 0xdafe049c, 0xe38f0e3e, 0x5cf1aeb6, 0x9f8ddcf6, 0x7800c9ac,
- 0xd0e74dbc, 0x3884b6ee, 0xb1bd9625, 0xfec4eac1, 0x6bf8d75b, 0x2eef8f21,
- 0x27a09c2a, 0x0377efbb, 0x813f5bfa, 0x677c2ca0, 0x73c32fa9, 0x642c4bbc,
- 0x85bbc40b, 0x1c5bf4fa, 0x6f93ffc0, 0x7de14758, 0xeb84d4ac, 0x8dd146eb,
- 0x08abfbf0, 0x1a83f8c1, 0x8d37edcf, 0xcf3e8e6c, 0xff3584fc, 0xc7a52b59,
- 0xd21756b3, 0xe6e3c925, 0x3ff77e00, 0xf209dbfe, 0x8cd176dd, 0xfaabec74,
- 0xaf77da43, 0x36dd9959, 0x0ad94e33, 0x64f293df, 0xc7b71394, 0x123c5ee9,
- 0x78a04dee, 0x4ea3928f, 0xbbf1f9fa, 0x71d50f44, 0xbb449e14, 0x2892f909,
- 0xc5d2ec8a, 0x4728fd29, 0x30905c9a, 0x4d8f2047, 0x885cabd3, 0x1ca83b0b,
- 0xc3d8b28c, 0x962477e0, 0x105379d3, 0xfac2c4ac, 0x754e116b, 0x3cc6cb9c,
- 0x7997ca79, 0x608a3870, 0x71121448, 0xdf4d7fa1, 0x6d7a7a6a, 0x59794102,
- 0xa810b0fb, 0x126cfda3, 0xaf885622, 0x01722964, 0x0a251aa4, 0xef179e32,
- 0xff304e5f, 0x78fd96d2, 0x42dd8742, 0x37c47e85, 0xfb5882fc, 0x869c7c79,
- 0x401fcf2f, 0x6a1ce46f, 0x8de6003f, 0x73c6cadb, 0x3b4166bf, 0xa87f43bd,
- 0xba9158f6, 0xdcfb8efe, 0xc209f2c4, 0x3ef44893, 0x687f519b, 0xebb8c9f6,
- 0xbf606b22, 0x189fdc68, 0x055bb49c, 0xcead1bbe, 0xa89f43b7, 0x1098e6eb,
- 0xfbf427d5, 0x66c8d0dc, 0xf72b07b8, 0x5dc72663, 0x3f21c9f4, 0xbefbf80f,
- 0x17c8c47a, 0x2e54c223, 0x32a1f6d5, 0xeae1a7dc, 0x19fb43a8, 0x9e49de83,
- 0xed152a3e, 0x8cdf955c, 0xdbe4d678, 0x77b9f728, 0x0ccd9bbb, 0x1a47e62e,
- 0x275c21c6, 0xe836721c, 0xb078b7a5, 0x29f2dbf7, 0xbf5c281e, 0xf4a3f902,
- 0xb81f384b, 0x21bfe601, 0xe415bd74, 0x27af7be4, 0x5475fa21, 0xbcd3f69e,
- 0x0fae3e27, 0xc04e27ae, 0xf3fef543, 0x46127aea, 0x01c8777a, 0x78e89395,
- 0x46ffc689, 0xa3e4d77e, 0xc8de2e0e, 0x047673c6, 0x0b9e59d6, 0x663065e2,
- 0x7805c9b2, 0x3aedecd5, 0xfe25bed5, 0x56ffb474, 0x1eba88bb, 0x4f800665,
- 0x5ecd44ea, 0xe3a25b77, 0x051dab53, 0x4fdb97a9, 0xfea45ef5, 0x1b39d459,
- 0xfe8ed0af, 0x84a2f79b, 0xfe37bfcf, 0x7914289a, 0x898dfc3a, 0x7f15dd1b,
- 0xb08471f1, 0x9ffec2fb, 0x230cdf9f, 0x7727dc7f, 0xe25aefce, 0xf5422579,
- 0xf5aade47, 0x3f193675, 0xd7969c39, 0xfb682f55, 0x01e9dd9f, 0xa98fbca3,
- 0x70c66fac, 0xeef20f4b, 0x25f8a9b5, 0xb3e80664, 0xb76a61f1, 0xff957564,
- 0xbcfceaf3, 0xb6f78636, 0x8307db5b, 0x3de7ad3c, 0x2f687135, 0xb0264c46,
- 0xb413762b, 0x8ffbdc7b, 0x5bde513a, 0x4feb7492, 0x8fc0bb57, 0xa7d9a9f2,
- 0x7c6a5d9a, 0x552ec3af, 0x3e2d1bd7, 0x795135ca, 0x193cf0a1, 0x1c03f1e7,
- 0xbfe62e75, 0xd05701c2, 0x3d584f63, 0x365fc075, 0xd838973a, 0xce12192f,
- 0xb096f162, 0x93bb3e4e, 0xde419b47, 0xb03f1482, 0xfae9f9fe, 0x1eeb8837,
- 0x0971b19e, 0x85aa5e0c, 0x97e9bec0, 0xd560d847, 0xfbc7f304, 0x6bfbb0e5,
- 0xfbb2e5fa, 0x31c73732, 0xa18b65fb, 0xfa5ac27c, 0x144bcc18, 0xfb9cdf88,
- 0x5006e1fd, 0x64f90e21, 0xf800d29c, 0x382b14b0, 0x71170c8f, 0x19de9473,
- 0xbc839042, 0x994ac489, 0xd247f163, 0xfb48ffb9, 0xf39128cb, 0x06323f81,
- 0x9a373c12, 0x9e7d8a11, 0xf13895e8, 0x8debd987, 0xbcc1ce5d, 0x41cfcaa2,
- 0xa937ce89, 0xe9839d84, 0xf050fb88, 0x8eadbf01, 0xadb2715b, 0xab3ed817,
- 0xd9e1813f, 0xc101bfe8, 0x5a825e60, 0x822257bf, 0x2bfd1135, 0xdfaff03f,
- 0xcaff4164, 0xd041dc46, 0xb1c41fb7, 0xce3aecf8, 0xbfea1ebd, 0x702dda10,
- 0x37268fcf, 0x343c3c9a, 0x40b716e1, 0x775e755f, 0x5f7c0736, 0x00ef172a,
- 0x9c275b9e, 0x6716bc1d, 0xf8c99ed2, 0xf975e14e, 0x9afd1af6, 0xacfd1d44,
- 0xd6895710, 0x08690ef3, 0x5cadedd8, 0xaafc1b9c, 0x831ce5d6, 0xe7a8b397,
- 0x3cdd0411, 0x1fcc6cd3, 0xe7f55369, 0x90b2e3df, 0x84f5b51f, 0xc63d6fce,
- 0xe8f30d7f, 0x386a8738, 0x973c6a77, 0x11dd969a, 0x7cc74a07, 0xee0952dc,
- 0x43672332, 0xbce3b436, 0x124cf6ce, 0x6a64bce3, 0x5cf31ac4, 0xbc5256b0,
- 0x4b780d7d, 0x40126b15, 0xcedea71f, 0x1f1188f4, 0xc47f9c6d, 0xfb47d841,
- 0x1f331883, 0xd2d32b45, 0x4c584a6e, 0xbf4b4fdf, 0x79ed4b01, 0x19885d83,
- 0x71b24c57, 0x64dcec3f, 0xfc18b103, 0xed1b24cd, 0x9de7b4ef, 0xff1415f7,
- 0x37bb8c76, 0x37bc31c4, 0x37bc31c4, 0xe53e1a48, 0xcebf9078, 0xf7975bba,
- 0x4967c1b4, 0xd10f2010, 0xb9f28e9f, 0xdde8c5c4, 0xf682bef9, 0xdca21f4d,
- 0xc4941730, 0x436c9106, 0x21f167be, 0xafc87ced, 0x4024cf7c, 0x96db94be,
- 0x16fbfaa5, 0x0604df46, 0x530df9f7, 0xb214dc70, 0xe2983ac6, 0xc9a96979,
- 0xd3a3710d, 0xc2723f0b, 0x1985e991, 0x0f20792d, 0x1b8f79a7, 0x984a97e6,
- 0x8e6cb85f, 0x2ed30814, 0xc2a81b93, 0x01ba7462, 0x4ccb3bf7, 0xc7aef331,
- 0xe9fed8d8, 0x961738d1, 0x90d36969, 0x92f59d4e, 0x8c4bf004, 0x35e54a7c,
- 0xcea8f17d, 0x6f94cc73, 0x790c5b14, 0x1349136b, 0x185beb87, 0xb1ac95f1,
- 0x35b7aab3, 0x39064979, 0x52ab7d84, 0x3a3547aa, 0x4d5f500f, 0xfe28b8c1,
- 0xbfd7a171, 0x79c37f06, 0x45ea015d, 0x10c88e4d, 0xa0ade7a6, 0xa1e2a377,
- 0xe83f7b6d, 0x9f8efb0f, 0x0739dbfc, 0x55fd3bec, 0x9e807768, 0xbbcf7e3d,
- 0xf4c7380e, 0x2e2c3dc9, 0x4fc18772, 0xfa63645b, 0x74ad8f7f, 0x8177e01e,
- 0x9e791fef, 0x77257e28, 0xe593fdb3, 0xde70de01, 0x506f7f5d, 0x70c93055,
- 0xf11f908f, 0x1fdea55a, 0x46c7a466, 0x2cb78b1b, 0xca59b1df, 0x4f7c6190,
- 0x5c7f8c25, 0x378f43f5, 0xd1dfd03a, 0x63b859e0, 0xd9be0484, 0x7566435f,
- 0x6445bdff, 0x025287eb, 0x151e67fb, 0x0f38466f, 0x2f6af7aa, 0x8fcb25f9,
- 0xdd63a329, 0x27b0f54d, 0x187bcec4, 0x13e4b1e7, 0x129528b9, 0x1cfdc96f,
- 0xfef0ddfa, 0xf33d743d, 0xee1f7ddc, 0xd9e719b3, 0x051f5ef5, 0x2a65b3fd,
- 0x6de78dbd, 0x3ed88597, 0x41e262f8, 0xfe72ecf9, 0xc5cec436, 0x678de318,
- 0x00db650f, 0xa9b0bf0f, 0x323cc4f1, 0xef6dce06, 0xfe20343a, 0x9f56f772,
- 0x828bef52, 0x3ca1bb7b, 0xce5823ee, 0xe2902303, 0xf6f432bf, 0xd55fc05d,
- 0x3ef13b4d, 0x8faaefb4, 0x9c2742aa, 0xe9ad4b90, 0x6e876a25, 0x8b20f903,
- 0x5a7d9d39, 0xc49cf9bd, 0x9f866afc, 0xb7e7d4db, 0x20723e01, 0xd9fe5bdf,
- 0xdbef4a04, 0xd1f3c52a, 0x6f3da5f7, 0xf7c3efd3, 0x3cdabe76, 0xed6b79b5,
- 0x9c5e6a55, 0x0e4d3bf1, 0xb97ca9e6, 0x75f4eb78, 0xea8a297d, 0xa9917ef6,
- 0xf3c3939e, 0x2d9f1a42, 0xe945a523, 0xa349f831, 0x84df076f, 0xd3f38e7e,
- 0xbeb8bae8, 0x3f83c54c, 0x4c4fdd4d, 0x91957883, 0xa73a7a8f, 0x32462add,
- 0x7c8dbe41, 0x7dcddad2, 0xb31b2128, 0x4acb162f, 0xa8cfc411, 0x15cebbf9,
- 0x171cdf65, 0x14fe0fea, 0xe32b6ee4, 0x083d0efb, 0xf7e8314e, 0xff5c4537,
- 0x54e43a57, 0xe90fffb8, 0x13f20e37, 0x4f787ecc, 0x4f98e71b, 0x808a0651,
- 0x4f2c62ff, 0x81954afa, 0x97db3a83, 0x04e73c6e, 0x086dbbfb, 0xab51b8c1,
- 0x69ef0f43, 0xe37a8f1b, 0x4a8f4ab4, 0x3f9be5a1, 0xdadace83, 0xc7177982,
- 0xa771a92e, 0x58e2e64b, 0x39d8b4f3, 0x7778bddd, 0xf9a872a8, 0xfa540b35,
- 0xfb6211dd, 0x4d370be9, 0xc9747a47, 0xa1fd54bf, 0xf50e46b2, 0x4b3e918e,
- 0x3e63d7dc, 0x3e40a2da, 0x5e85df7e, 0xbba441e4, 0xda776e91, 0x371eec5d,
- 0x7b8246a1, 0xe26d8eed, 0x8571ff70, 0x73ff7b10, 0x9df4ddb6, 0x479c63e6,
- 0xdb2ff077, 0x2faebb5a, 0x908ff981, 0xf08dcf80, 0x425ff36b, 0xd4a7a614,
- 0x2f3776f9, 0xf2c49912, 0x7f75d434, 0x815b9c39, 0x790793fd, 0xc6adcf96,
- 0x35f834a1, 0x28f38d78, 0x7cf12be2, 0x8f035b41, 0xf877d979, 0x77067dd9,
- 0xfd70e5ac, 0x9a4e8eed, 0x7bf6d15e, 0x30ca9baa, 0xfb43cb6f, 0xedb63b01,
- 0x29f6c263, 0xcf7873d6, 0x0cf4b75b, 0xeea57cb1, 0xa30849e8, 0x374a62db,
- 0xdebb3ff0, 0x0caf909f, 0x0a27de8c, 0x8c0ca0dc, 0x4122b7de, 0xb15957cc,
- 0xf9eeba7d, 0x8e35768d, 0x9ef5eaa5, 0x24d48fe4, 0x696f8cc4, 0x9fc9a6f2,
- 0xda778f26, 0x0a6f6665, 0x59198381, 0xd1879f80, 0x7afaa1bf, 0x3df99d9e,
- 0xafa5cd0f, 0xa73c6f54, 0x3258a7db, 0x096bd196, 0xbbcf825f, 0x0f14bbd3,
- 0xd8bdbd3a, 0xf8c3cfae, 0xe6d1f3a1, 0x3689c9a1, 0x189ca33f, 0x43d237bf,
- 0xe919ef8b, 0xc007a462, 0x5bc67e09, 0x35816d7b, 0x38b7ce14, 0xaf7fb706,
- 0x4d6ee115, 0xb9c0ac9b, 0xf9f4eacd, 0x3e01fe58, 0xb0fb074c, 0x768eceb4,
- 0x8d87eaae, 0x225c5dea, 0x5ecbb557, 0xd9232ab2, 0x24d2a7b9, 0xb58993e0,
- 0x17161991, 0x583e8f21, 0xa4f7045c, 0x32387c4e, 0xbff14203, 0x5646f07e,
- 0xd77916df, 0xfcfb86e2, 0x690a8a4b, 0x2fd071fd, 0x95fa2fa0, 0x6efbe0db,
- 0xf973c4eb, 0x1fdeccba, 0xcf9d2e65, 0xed66b1ee, 0xb33ed495, 0xf2aef5d0,
- 0x4157e0f0, 0x4a5b2b7e, 0x542e218a, 0xba781109, 0xce2955de, 0xad872db0,
- 0x7be9e3fb, 0x4f3cd91f, 0x76ee21d9, 0x8bae2d71, 0x94058795, 0xc588722f,
- 0x573a0567, 0x6d6efd2b, 0x2993b51c, 0x5a26d77e, 0xd317e0dc, 0x97f07ee7,
- 0xb22a26d7, 0xa35cf51c, 0x70077c1f, 0x7cb135ac, 0x0c6ffd82, 0xc65c8f8e,
- 0x23efd82e, 0x34cfe025, 0x1a582cfb, 0x1725f3db, 0x37c8e79e, 0xb18978b1,
- 0x76bb6dfd, 0x00ce49ae, 0x243ea8be, 0x1fc3fca1, 0x84559fd8, 0x613549c9,
- 0x0eaad0e7, 0x53773c13, 0xcf08a87d, 0x84b9c0dd, 0xe07a754f, 0xa6ee735f,
- 0x9e18af93, 0x44ae040a, 0xd0b71a88, 0xf9d5d56e, 0x9810d354, 0xdce3e10f,
- 0xcf846e70, 0xa2ecd530, 0xa0afe7f3, 0xe087c525, 0xff70f372, 0x89e4fd4c,
- 0x559fdc3c, 0x2d79aa27, 0xbe3e7626, 0xe557dd63, 0x39fb2b4f, 0xdd028f4a,
- 0x25b1ff4f, 0x53f6c6cf, 0xe6d6afd0, 0x8429c75b, 0x35ed7f03, 0x7219e782,
- 0xe0334993, 0xb19446cf, 0x47166fc0, 0x6c97caa2, 0x65fe9b3f, 0x9b36e940,
- 0x7e53237e, 0x9fc1faff, 0xe3bbff22, 0x68b2ab4d, 0x59f8739d, 0x2e74c33d,
- 0xef30b28b, 0x6bf565a8, 0xd006e74c, 0xc358e8ba, 0x4af1b0ea, 0xa3b33e17,
- 0x143fc8ae, 0xba3171c6, 0x01ae50ee, 0x2c4c16fe, 0x901c23ae, 0xcb477f70,
- 0x794b5957, 0xe2d1f806, 0x5d747a60, 0x3673c16d, 0x28179b88, 0xec4fe432,
- 0xfa41ef51, 0x5786a5be, 0x7f4266de, 0x7fc04a09, 0x53e183bc, 0x54690ba3,
- 0x5e3c81ae, 0x81ae5412, 0x0e7ebd7d, 0x7e83a24f, 0x96adf23f, 0x1bcfa089,
- 0x0f28f9df, 0x82bf73ef, 0x2df233f5, 0xf9d243ea, 0xff6dfe9c, 0xe4fbd1cd,
- 0xa9f91cfd, 0x03251df0, 0xec9cafda, 0x3951b722, 0x2c8853ac, 0xad9f8365,
- 0x091b2ff7, 0xd91f4fd3, 0xa070af4a, 0x3ae3093e, 0x67bb13f6, 0x7e8dd400,
- 0xec496933, 0x949dde55, 0x17ee3773, 0x7d346625, 0x85d610b8, 0x4a7bb1df,
- 0xfcc14538, 0xee3b17d3, 0x9718236b, 0x373891b2, 0x9b898dc4, 0xd453f9a4,
- 0xf1899af8, 0x945e7255, 0x87ceacff, 0x79085f7e, 0x2c6c63f2, 0x8fce81bf,
- 0x823afd07, 0x848e58c8, 0xa0365938, 0x3df583d8, 0x4fe1f824, 0x588fff69,
- 0xb2ca7c59, 0x8fe2e89d, 0xb7160e65, 0xe2c9c079, 0xf062718f, 0xe22bb016,
- 0xd81710ce, 0x4b8f6d15, 0x0bcfee02, 0xdf709bae, 0xe309a0ee, 0x018b4fdc,
- 0xb517ec17, 0x5bc8255f, 0x6d7f6748, 0x7eb5dd2a, 0xabe4911f, 0x0bf7ee20,
- 0x9d3fab27, 0xbb8f304f, 0x801484fd, 0x0cc4dcfd, 0x3c744d4b, 0xd9839e69,
- 0x1573bfbb, 0x043a04cc, 0x1811c6f7, 0x38becc7f, 0xb9e3d013, 0xe056b91d,
- 0x4701178b, 0x66890f14, 0x5fd09dd7, 0x6f0a39e2, 0xf9673e16, 0x223c82fd,
- 0xfc77e29e, 0xee19768d, 0x1ada7ad1, 0x56f311bc, 0xbde1379f, 0xee4a2fc1,
- 0xf17f50e9, 0x3d02ecac, 0x305674fc, 0xbcf3e70e, 0x62f3e709, 0x2bd5fb5c,
- 0x0c0fdc29, 0xc12ef161, 0xcfd00446, 0xbe40a982, 0xae5f3e93, 0xafa6b1f2,
- 0xd11c8137, 0xc11c23fa, 0x29820c73, 0xcb48e51f, 0x276b6a27, 0x67d44f98,
- 0xfc0f0b66, 0x8b5d371c, 0x8879853b, 0x25284d17, 0xb04dcf68, 0x05ce788b,
- 0xbce199f2, 0x0f5544db, 0xb2b8fc4f, 0xbb07e584, 0x9ebdc30f, 0x7ef576cd,
- 0x739f7530, 0xd727ca92, 0xa16f0891, 0x245dd7ed, 0x4d27886e, 0x8fdfa8ba,
- 0x5f60ca78, 0x57fb514e, 0xf0855dda, 0xede89f38, 0x450d29bf, 0x2c3d6027,
- 0xfc008a20, 0x6862d934, 0x09d23b07, 0x9febf0f7, 0xfd50e03f, 0x19924cdc,
- 0xeda6c79d, 0x87e14d43, 0xb5fb446e, 0x5e037258, 0x0f95da76, 0xdfc03f20,
- 0xc5cb9222, 0xb1f29f25, 0x1721c37c, 0x2cae046d, 0x8769fca4, 0x50dd5cf9,
- 0x79d2b7ef, 0xf5903d5f, 0xfa087c0f, 0x93c7cae5, 0x8fdf4093, 0x95a5e957,
- 0x7f01df1a, 0x7f19e2b9, 0xca7786b9, 0x2c8ed3e7, 0x37934f7c, 0x67e83be0,
- 0x1f98188f, 0xf29bbf6b, 0xafc0d3eb, 0xfd04ed3b, 0x5ba59fb8, 0x699c80e6,
- 0x7caab4e3, 0xd5d72c6d, 0xbf0fdcae, 0xc0bfe4fb, 0xbec28dd6, 0x75e8a517,
- 0x83024fbf, 0xcfd72bd7, 0x68790698, 0xccf31176, 0x5173d452, 0x1e92fcd1,
- 0xdf1a2fc5, 0x9c59dab5, 0xc99fe348, 0xe1e5dfbb, 0x840be4f9, 0x8748b2b8,
- 0xcff1a2bf, 0xf7187f44, 0xe6122781, 0x67f9189f, 0x93fc3757, 0x40165e7f,
- 0x9fe1756f, 0xba7f8c43, 0x0fda1be3, 0xe4616bde, 0xaa1c779f, 0xff2dddbd,
- 0xfcf3c25c, 0xbe4ef7ab, 0x93657eec, 0x6a9f9f4f, 0x62d9c72c, 0x54bb2fe7,
- 0xea96efbc, 0xbd01ca6f, 0xcec4d531, 0xe32409ef, 0xeeef0a16, 0xfcdeed38,
- 0xefa86c9a, 0xda1e9814, 0x1ea33219, 0x78f769da, 0x669b7e30, 0x0557e761,
- 0x23ce044f, 0xe45afbb8, 0xd921dfe8, 0x587660ee, 0xfb8f0c50, 0x37f1ec02,
- 0x9d8c1f18, 0x2a43cb9a, 0xa662fa5a, 0x971d4617, 0xcfefc336, 0xbfccea3d,
- 0x06967c00, 0x79dfa3b8, 0xcf784a8f, 0x0951f552, 0xf76fe3f5, 0xf1045dbd,
- 0x79cf2d51, 0x8bb79ecc, 0xfbc2860a, 0xa1fedf8c, 0x8ead65ea, 0x5f404047,
- 0x1fddee1a, 0x4b1e71d7, 0x297e6f7f, 0x674e51f0, 0xf93ef1bb, 0x3fdb1c60,
- 0x11644d99, 0xb4719886, 0xdeb85ef4, 0xfcaf78cc, 0xff3b30ec, 0x27b0f336,
- 0x2af2bdf6, 0x37ef187f, 0x8a77f6a7, 0xe7efec13, 0x6841f65a, 0xdd6cc884,
- 0xd7354a0e, 0x26a33f30, 0x9349f81b, 0xf8a3fc43, 0x44327e0b, 0xb706bbf7,
- 0xd07ff3a9, 0xa9fbb02d, 0x4bee1222, 0xefb09cfe, 0x363aea82, 0x40f4c9ca,
- 0xe617eaee, 0xcb239c03, 0xcba06695, 0xd7162eb3, 0x5b0905f9, 0x6e6e81b2,
- 0x8253f701, 0x0bf93ca2, 0x223df3ae, 0xd3b10e94, 0xe27d3df6, 0x8ff8c246,
- 0x9c633d3a, 0xed099f60, 0x31bbe087, 0x824773e3, 0x588fb71e, 0x9aeb049b,
- 0xab853706, 0x13bd9b78, 0x81ae0d0e, 0x8f97c64e, 0x00c6cb3a, 0xd03be01e,
- 0x8e474d4b, 0x8d7be059, 0xcf7b821f, 0xe2883e30, 0x4e83e00b, 0x4016e0be,
- 0xa283c35d, 0xfdb7cfae, 0x8b42f88b, 0x17c8f46b, 0x7e70b710, 0x0b98be2f,
- 0x05f23578, 0xce3ce7b5, 0x505cf618, 0xc6937962, 0xe7b13fe7, 0x896efbe3,
- 0xd913de60, 0x6bbf6567, 0x7dc049e8, 0xd8b8df90, 0x1c9f6d98, 0x28a6a4cb,
- 0x7664e559, 0x2a3bf6bd, 0xda1cc223, 0xa2a8239f, 0xbced0db8, 0xdd27a87e,
- 0x31c8fe2a, 0x46fb838e, 0x033e3731, 0x1270d0ec, 0xcc236bd8, 0x87906125,
- 0x1989b65d, 0xdae63f60, 0xfcc36426, 0xfab21e5f, 0x5ed2584d, 0x9bfe5bee,
- 0x7da772ad, 0x66c3e9a5, 0xfc6d5bb5, 0x4c7f2a35, 0x2779d852, 0x70d1ebd0,
- 0x9003eb68, 0xc2e0e009, 0xdadf4db3, 0x22878f50, 0x00936f14, 0xfd878a0e,
- 0xfb04691c, 0x24a4df21, 0xb03b064f, 0x3800584f, 0x9d7ef6db, 0x92cef109,
- 0x021febd0, 0x3eda25bc, 0x0fbf5bac, 0x35b7b46b, 0x3ff3487b, 0xf3497b34,
- 0x82aec17b, 0x1fd532f6, 0xbed99971, 0x05b084d8, 0xe47853ef, 0xa2957cac,
- 0xe740b3ca, 0xe3cea251, 0x7082d266, 0x4ca9f769, 0x7251f153, 0x39abfa88,
- 0x54c84ed0, 0xeaa9878a, 0xdd532a7d, 0x6e22fbfa, 0x3efb1b1e, 0x9e9fad15,
- 0x1bae37de, 0xa3f61ad7, 0xc879687e, 0xf94feec7, 0xc3f98fbd, 0x7ef007e3,
- 0xb1dfd601, 0x09feec59, 0x21c3c317, 0x763af629, 0xf1eb9551, 0x9c0e48a6,
- 0xe7bfdec7, 0x1e6eb8ef, 0xf7f7f3d8, 0x771c8ec1, 0x97902042, 0xa8c4fe3b,
- 0x180fcc78, 0x695f232b, 0x6f3f7afd, 0x9cf611b4, 0xccdeff44, 0x728f0a41,
- 0xc167c025, 0x8f5395f2, 0x9dfd0a3c, 0xe8902a3f, 0x92451f73, 0xe5c42067,
- 0x1ddfd48b, 0x7b31c83a, 0xa83f6b4a, 0x11c7defe, 0x21216f95, 0xc567bb43,
- 0xa9e7451c, 0x1a1ffdea, 0x2f1ea75d, 0x74e4213e, 0xfdfc0fa5, 0x5a10e233,
- 0xaa9ce1fc, 0x9ff3490f, 0xf5ce7cf0, 0x600a778d, 0xc69f5fbf, 0xdc6a2513,
- 0xe9ea641b, 0x4e21c547, 0x6ff60d3a, 0x4e8f33f3, 0xb7e5bc83, 0xf4814c78,
- 0x99be7686, 0x3e16f503, 0x462abde6, 0xba1f5efc, 0x9955ef13, 0xa3e4cf1b,
- 0x5fc7f1a7, 0x3864f94d, 0x3b309dd0, 0x4bdd8f30, 0x81efa462, 0x1491ff3d,
- 0xbe3dda19, 0x91bfa3bb, 0x2a9caf0e, 0x9eac7dc0, 0xdbe461e8, 0xfe9e747d,
- 0x5377e12b, 0xbf8fc42d, 0xfac2ea9b, 0xac34beab, 0xddeafc6b, 0xd81264fb,
- 0x4e9f1a79, 0x337c6249, 0x49a3f76e, 0x2f49dec4, 0xc586de23, 0xc97ffe33,
- 0xee25d9aa, 0xa3e8d359, 0x843ae977, 0x2d27ea8c, 0xaa563790, 0x70fb3ac2,
- 0x4425da11, 0x5c62cf3d, 0xb7f366df, 0xda75014d, 0xccfeefd3, 0xf57acb94,
- 0x6fc5397b, 0x0eb00bd5, 0x99ab0916, 0x78ed531e, 0x9d231e0d, 0x08a523df,
- 0x19f0777f, 0xe708c0f9, 0xf6f91d4b, 0xda07ae0a, 0x18cce0ef, 0xc6262598,
- 0x8f868798, 0xc7ae8499, 0x8f5fbdd9, 0xdbd78c6f, 0x178ee7ef, 0xdad011fe,
- 0xe919bc9d, 0xf4d76c66, 0x900c1147, 0xec1fa58b, 0x29f1b993, 0x8ba2df48,
- 0x3ae85112, 0xcfe9fa43, 0x2b9293f5, 0xb956df91, 0xf8eeb3d8, 0x4f22faad,
- 0xf93b233c, 0xd87a6c4e, 0x5bb77c06, 0x1c41b7a8, 0xf4fb3af5, 0xc2bd103a,
- 0xe2660bcf, 0x131115fd, 0x94dad081, 0x886699d0, 0x243f7833, 0x20a1be78,
- 0xf0327fb4, 0x0b42abe9, 0xe76d59fa, 0xca387909, 0xd50a6cee, 0x6b2ec0d9,
- 0xf3e7664a, 0x5d10260e, 0x78c5f4fe, 0x8e9a6fa6, 0xc4a69d9e, 0x62ee1f68,
- 0x28833cfc, 0x9ff439c9, 0x7f29eb45, 0xc7dc1f80, 0x42927181, 0x325afdce,
- 0x39732dd8, 0xf6da23f4, 0x992d798e, 0x7b7adbc2, 0x2999ea02, 0xe9ddf74d,
- 0xfe0884a2, 0x6f3e2463, 0xfef0e32f, 0x8dd92284, 0x59c5a2f5, 0xf98df7e8,
- 0x09466926, 0xa220dfb4, 0xaf8533df, 0x755e2014, 0xabc38d3a, 0x9170f63c,
- 0x623df85a, 0x0e3674ff, 0xc093f971, 0x24a77d3f, 0x66fe0469, 0x07d5ac9e,
- 0x122eefe1, 0xfab6ff83, 0xcdfb73a5, 0x2cf57db4, 0xa78df30e, 0x3f8832b8,
- 0xd68a7f8a, 0x5baf384b, 0xc005a942, 0xf58a33d7, 0xaac31ee7, 0xd4ab393d,
- 0xfbd10246, 0xe50b9cf9, 0xfdb5a0fa, 0xf11dfc56, 0xf98122bd, 0xa37e7269,
- 0xe7b3efca, 0x9bbee924, 0xa9dd984e, 0xaa4dd5c9, 0xfaa8ddfc, 0x193d73cd,
- 0x094bf1ba, 0x40fe87b3, 0x64810bda, 0x7ed8b8f7, 0x96f6b4f4, 0x25e1f3c3,
- 0xd068dfbe, 0x310d3787, 0xe57cbdf8, 0x348be45a, 0xc8f78dce, 0x37edf5b8,
- 0x8dd7d58f, 0x0fd46bf2, 0x8f8b20b3, 0x3427aaef, 0x2f6b307d, 0x683c422f,
- 0x33c53e56, 0xbb7ac5da, 0x317d27bd, 0x7d1bae26, 0x17be4971, 0xfa2e90cc,
- 0xefe2e3e2, 0x4b7e2fa5, 0x54b196dd, 0x578edfae, 0xa4fecdd7, 0x298de83f,
- 0x81478efc, 0xbae8da8f, 0x47c18e69, 0xc5a3bada, 0x1ca88a01, 0xc5381ea3,
- 0x5ca663f6, 0x91fe274c, 0x0e80719d, 0x12ed423d, 0xa97b0c77, 0xe51b3e35,
- 0x68ef43ab, 0x2eca257a, 0xb87ef311, 0xda85325d, 0xc02e52a3, 0x2be10fd7,
- 0x2925ef52, 0x882b8482, 0xc19da61f, 0xa0579038, 0xcfae2cfe, 0x817f224f,
- 0x3b12e3fe, 0xaf68c3e5, 0x0ae87168, 0xe94f6697, 0x1e23a5f9, 0xc3dd9339,
- 0x1149f1aa, 0x7fe413e0, 0x04fb8f26, 0x7fd41bff, 0x8000b303, 0x00008000,
- 0x00088b1f, 0x00000000, 0x7cc5ff00, 0x55547809, 0xf579f096, 0x55492d5e,
- 0x146caa92, 0xb612f08b, 0x84582484, 0x5916ec80, 0xa014a358, 0x8168cb80,
- 0x9a126b0b, 0x69ee9c71, 0x0242a6ff, 0x83b74343, 0xe8cedad2, 0x3ad857f4,
- 0x08b41a83, 0xd09d0301, 0x584c5015, 0xf82e0834, 0x1a6d1ad9, 0x84490ed1,
- 0xbfbb46d6, 0x739cffcf, 0x2aaa4bef, 0xffff4d85, 0xb49fdf3f, 0xdeefb97d,
- 0x67b9ef77, 0x979ee73f, 0xb3559bdb, 0xf6e008ad, 0x14078a99, 0x77f1d000,
- 0xe042c022, 0xadacc37f, 0xc78ef016, 0x69fcd7be, 0xe7f80d87, 0x9c2ffc3b,
- 0xa42cfc90, 0x900bcf50, 0xce54b009, 0x7d57fc5f, 0x3c5e3d33, 0x52fe7a27,
- 0x92b9fd98, 0xf81b700c, 0xf71c30cd, 0xff8ec5f3, 0xc7154bec, 0x7e8b2e97,
- 0x4a4ce99e, 0xff8790bf, 0xbe230118, 0xd4ca0153, 0x22b79dba, 0x5527ddbc,
- 0x334c558f, 0x390ffed1, 0x350ffec5, 0x7c800c97, 0x1674df80, 0x3db1f8a7,
- 0x1c2111b6, 0xd1bad00d, 0xec71edc6, 0xefc5f107, 0x3c66e7e8, 0x21fc059f,
- 0x52b4b607, 0x4801b721, 0xc4ed1805, 0xff602745, 0x0d3f9e2a, 0xc02486c7,
- 0x5c2473ef, 0xe7af00d9, 0xf104e798, 0x5eb8c3bd, 0xe30dd700, 0xf75c01fa,
- 0xf72746c8, 0xe6e8db5f, 0x442e0dfe, 0xfac0066a, 0x37af2714, 0x8776f72f,
- 0xe35bdf1f, 0x50e7e6cc, 0xf844da3e, 0x7b2fe036, 0x1004086a, 0xac77afdf,
- 0x807494d0, 0xb1e2b72a, 0x01d1f566, 0x8e58e34f, 0xbe25cbf3, 0x102ab72b,
- 0x1fe5e7c4, 0xc4072bae, 0xee33575f, 0x2aa9f887, 0xfc368355, 0x63d34967,
- 0x0cdf453b, 0xdefa08d6, 0x33028e22, 0x86cd16b5, 0x28f02cfb, 0xf1f7151e,
- 0x6ff78936, 0x1d412af5, 0x278b79ff, 0x63871e9a, 0xae58bee8, 0x0ffe80b3,
- 0x47305bdf, 0x9d718609, 0xdfa29305, 0xd6757c5b, 0xfed8cae7, 0xe898b47c,
- 0xbf3fb63e, 0xb7744edc, 0xc1863fe3, 0x95fba230, 0x8d6fa58b, 0xc5ba3e85,
- 0x8e74b1b6, 0x9d16bf1d, 0x673a27ef, 0xc6ce9b5c, 0xce8b7ffb, 0x904e110f,
- 0x1bf470be, 0x30049e8b, 0x1a07e9bb, 0x55f679d1, 0x32add78d, 0x861433ce,
- 0xd4fe79d2, 0xb76ff859, 0xaafcdf42, 0xfe2d2fa6, 0xe79f6b82, 0x22bfed6f,
- 0x69fde745, 0xdf7e6f5f, 0x8034f3be, 0xf9ce78c1, 0x8df8d139, 0xbd2c6ba5,
- 0x62f7ca16, 0xe635b5e9, 0xa05d061c, 0x60689913, 0x555fbc1c, 0xd16b8e19,
- 0x162e97ad, 0x7e4f08ff, 0x5f8071ff, 0xd6fab9f3, 0x76827493, 0xe02057cd,
- 0x03c84732, 0x052075f2, 0x0ade5be9, 0xec0444e1, 0x3e738b96, 0x28f5a8d7,
- 0x39c469f0, 0x8353e7e8, 0xfadf6ace, 0xb2075765, 0x96fb19fc, 0x14b01069,
- 0x972173d2, 0xd255f0b1, 0x7e69233a, 0xcb68f980, 0x10b2d32e, 0x05ba639e,
- 0x9b51f5ee, 0x4e03da28, 0x9d1a07a1, 0xfbb75e26, 0x6e099b2b, 0xf0e57804,
- 0xf8406280, 0x09e7563c, 0x33218bd2, 0xc945fbf0, 0x9cdfcf3a, 0xdc048104,
- 0x9b76b41f, 0x2b44f90f, 0x3941c806, 0x825906d3, 0x9d64b835, 0xdc91f616,
- 0xa8347b75, 0xd1bbb946, 0xe048ef78, 0x6c92402e, 0xa99474fe, 0x0fde8b26,
- 0x79c54fb7, 0xfa6a1537, 0xb2e29c36, 0xf1a03fea, 0x93ab66ae, 0xf83eebde,
- 0x5a662dcf, 0x20f02be7, 0x335af084, 0x4f8e1532, 0xa4839873, 0x93d4ca37,
- 0xddfb09aa, 0x8fa4003d, 0x970b2da6, 0x3a6dd200, 0xb138d7b4, 0x8c74429d,
- 0xd0bfbf43, 0xde843379, 0x9a74881a, 0x4334e921, 0x6692abea, 0x4946f595,
- 0xac841a92, 0xb374fd3e, 0x408cd1a4, 0xee0a497b, 0x3c53433b, 0xf9bfd835,
- 0x8fc516aa, 0xba3e932f, 0x951f4fb1, 0x3dbdf5c9, 0x019686ba, 0xff344266,
- 0x3d0a3596, 0x798b6254, 0xbe0fed2e, 0xe6557cc9, 0x429f1e8c, 0xfbf913ba,
- 0x825e8c62, 0xa653fb18, 0x03b935fe, 0xc58af0f1, 0x8454defb, 0x19b4e7bb,
- 0x70e7c59e, 0xfb933b11, 0xc631a7e3, 0x07b6c51e, 0x757a270f, 0xe215eb84,
- 0x07f50723, 0xd7b1f579, 0xa3b63f9e, 0xf18e98a7, 0x0d22dd4a, 0xcf2d99b2,
- 0xf0fb33ba, 0x92bf0fde, 0xad78b10e, 0xdbde7a97, 0x8e8d7ce8, 0xad8f0fdb,
- 0x979ed8b3, 0x48d749fc, 0xf8bdfdf5, 0x95e5e434, 0xe25e890b, 0x0c2e57ff,
- 0x4afdb2f2, 0x0c3e59d2, 0xfe783879, 0x51e92272, 0x21aea7c4, 0x6cb8f49f,
- 0x9f99679e, 0x06841c85, 0xc36e0a8e, 0xc12485fe, 0xf624aff7, 0xbc23cf1c,
- 0x3cf262df, 0xeb68db4b, 0x202a2f87, 0xd175b9fd, 0xe2803379, 0x2887e505,
- 0x84ee8a4f, 0xa00db1bb, 0x05ff113c, 0x72482152, 0xd0108662, 0x785e35be,
- 0xd319da9a, 0xfbc214f4, 0xddb35c65, 0x29e9eb41, 0xd7f0f7c4, 0x057d132b,
- 0xbf5ff1fd, 0xee1a7c11, 0xe6d1b0d3, 0x1c2f50d3, 0x7ee4e8d8, 0xb73746e3,
- 0xdcea3687, 0xfc913a6e, 0xaa1ff243, 0x169f16bc, 0xa5e657a1, 0x0330fd0a,
- 0x35c10ef5, 0x00609403, 0x23c66f79, 0x7288f2c0, 0x10a4dc10, 0x393cf0bd,
- 0xfa44f87d, 0xe888ee5c, 0x3b56ad43, 0x82a59321, 0x67985ee9, 0x09d1f7e2,
- 0xd59f3e08, 0x3fd23e7f, 0xfc8cbfaa, 0xefc38416, 0xb0b996f2, 0xb37c390d,
- 0x7adf885d, 0x4bd1e965, 0xf4b9fdc0, 0x43b95ebc, 0x8feb84bd, 0x1f84cf0f,
- 0x8f18bda2, 0xe2bc2184, 0xff045dcf, 0x100b1684, 0xb2b0d07d, 0xf21a167c,
- 0x5ca2b5f9, 0x8448fdc0, 0xef8c1bbe, 0xc4c3cb59, 0x23a0074f, 0x645ef08d,
- 0x7e49d9f3, 0x3f04b997, 0xdddb9578, 0x3937ae0a, 0x0951e2c3, 0xf1bee1b4,
- 0x2d7f11eb, 0xce21b819, 0x1cc9696f, 0xb713e7a2, 0xc93ef1bd, 0x08e6d7b7,
- 0xcc986cab, 0xf6111d9d, 0xe33c007c, 0x74927f24, 0x476877dc, 0x0e4e3f5a,
- 0x6abb9eb0, 0x6b5e9209, 0x09ec933d, 0xafd33ee3, 0xacbfd8da, 0x6e5117a7,
- 0x8f26270f, 0x42133d65, 0x63f2430d, 0x6d98e713, 0x3c23aff6, 0x7a3e65a0,
- 0xedfbdf0a, 0xafd20065, 0x543fdbd3, 0x312d0fc9, 0x40e80ee5, 0xa32a8f38,
- 0xf27da853, 0x6e7ce4e3, 0x127724cf, 0xec9b0e7e, 0xcefbed3a, 0x0474bd46,
- 0x8da9cbf2, 0xf9023a50, 0x368dade3, 0x746f4f6e, 0xa3667b72, 0x38a3db9b,
- 0x3af3fc4e, 0xbd7f138e, 0x6fd4e381, 0x4f6a71c3, 0x7ad43ae0, 0x489872df,
- 0xe5bc677e, 0xbc2da8d0, 0xfadb892b, 0x742c933b, 0x50c9c38e, 0xfc4fec67,
- 0x370c4e14, 0x2ee50780, 0xdb53fdd5, 0xad3f680d, 0x1c6502fe, 0xf754d4c0,
- 0xae3a6d5c, 0x8fe87b3b, 0x19f1c2be, 0x6a7ec3a9, 0x3b6f7843, 0x893868e3,
- 0xf5c7d2fd, 0x3f883a9f, 0x92a2244f, 0xb7643c24, 0xc7365179, 0xc418d293,
- 0x24c2f768, 0xfd19a7ec, 0xc8a5b9ec, 0x3a4a4b0a, 0xb005c0f2, 0x73e1b1f3,
- 0x25df886d, 0x513fff76, 0x9b6812df, 0xfa9d3a53, 0xbc927010, 0xcb20e62b,
- 0x7d2510fb, 0xadbfda11, 0xd4c4ff0e, 0xabc07f08, 0xf48d21fc, 0x02af44c3,
- 0x77a674ae, 0xf7d2a470, 0xd5b798dc, 0x15313651, 0x2ed7f7f9, 0xc269f995,
- 0x741bc534, 0x635f97f4, 0x7af384de, 0xe26fd129, 0xd4b559c5, 0xe2e3982e,
- 0x4dd96fbe, 0xa5ff24b5, 0x5fbd6b8e, 0x5c87efc2, 0xc547d666, 0x638bce1a,
- 0xe3798d17, 0xffc8c991, 0x0c4b69ee, 0x7d7c4b3e, 0x84935fd6, 0x567732fd,
- 0x34752aa1, 0x6bb5df70, 0xbf978d1b, 0xe572c0de, 0x59e8f249, 0xa5ed8ac4,
- 0xd33e3869, 0x24c278a1, 0xa93ed32a, 0xa771a34d, 0xcdb421e2, 0x553b8ef4,
- 0x5423e344, 0x9fea4ccf, 0xd89d4bd5, 0x4e66d19e, 0x66f384bd, 0x6c78a4e7,
- 0xf099def8, 0xff10ae8f, 0xf249ccce, 0x1714e824, 0xa4ae9f04, 0xa9eac7be,
- 0x8f1ce9d6, 0x3ad32495, 0x6131e2ba, 0x92d6febf, 0x147045ff, 0x514052fb,
- 0x91a5dc68, 0xc7e4fb1f, 0xe275293f, 0x0aa1fabc, 0x099cfc90, 0xe091fee7,
- 0xa89ad99f, 0xf5402027, 0xbd296716, 0x9c516f57, 0x2befb89b, 0x5181f9a1,
- 0x5c79fd66, 0x769de4f7, 0x6fe507b6, 0x745fb3e5, 0x6cc1cef2, 0x9adfca17,
- 0x49ed4c56, 0xcbdbf093, 0xc39f2adf, 0x930826e3, 0xebbf2952, 0x1dbdf81f,
- 0x4d293f25, 0x0c4ff5c7, 0x416eb173, 0x116a953a, 0x83e70d7a, 0x55dfef42,
- 0x945bf3c1, 0x8f3a3f01, 0xa7e4aff3, 0xff715a14, 0x5109e959, 0x710ce7f3,
- 0x8de7f545, 0x45aa5818, 0xfcf2b1d8, 0xadfea8ac, 0x88e94a45, 0x69bef988,
- 0x45fd5109, 0x11d2aea5, 0x2b6ff311, 0x5fd5181f, 0x54565b72, 0xb269a67f,
- 0xa11b1fd0, 0x7dc854bc, 0x9bfb2979, 0x0a87acd9, 0x1bee629d, 0x8e3f7e38,
- 0x7f09b617, 0xfe85d0aa, 0xb4a5d214, 0x80fd88ad, 0xc68f7c36, 0x8f52ec8b,
- 0x3ddda005, 0xfc80ec91, 0xf62fe209, 0x6677658b, 0x6305fa3b, 0xb768ae89,
- 0x752fe023, 0xfaf1db44, 0xcc27e144, 0x0bad7f01, 0x75a739e9, 0x6557fb1e,
- 0x6145d5e9, 0xbf467c20, 0x2a370b1f, 0x13779dd1, 0xac6ab61f, 0x890ce737,
- 0xd4adafd9, 0xf48c7ec1, 0xb7c8e6ef, 0xe0217d8c, 0xc6ff276d, 0xffb18738,
- 0x4733ceb5, 0xe17ec69d, 0xacd73adf, 0xa9a5859c, 0xcf5fe171, 0x9c2c4cfe,
- 0x4f32a979, 0xfb15fe81, 0xeca9ad85, 0x7a4fe22f, 0xf0c13f3c, 0xcf51ca7f,
- 0x9cf522b9, 0x585f4943, 0x673d6d70, 0xff2d7bac, 0x78d758cf, 0xde54ea1f,
- 0xf7bf78df, 0x7fc4aeb9, 0x27e71bbe, 0xae9e79c5, 0x5cfe7fc4, 0x9a19fcf4,
- 0x7940e35e, 0x278a0e3e, 0xa93f7840, 0x959ae46b, 0x52d6f59c, 0x5fa1f65b,
- 0xf670b723, 0xb52d40f9, 0x27833b53, 0xb9fe78ad, 0xf94eaa39, 0xea2fc307,
- 0x0aa56717, 0x55f8e47f, 0x78e3aedd, 0x53b7407d, 0x88ff51dc, 0xaaf8a76e,
- 0x28730bde, 0x370ef48e, 0xc438a7ad, 0xf62d879b, 0xfa154def, 0xdf7c857e,
- 0xfea90f68, 0x857f0415, 0xf251e3ad, 0xe9bf2a49, 0x1c5f10b1, 0xbf2f7f27,
- 0x5c77bfbf, 0xbf683a0b, 0x1d048fe3, 0x7e7d08be, 0x22defebd, 0xe20ca662,
- 0xa917c553, 0x096c4a4f, 0x51fd48be, 0xf54574e6, 0x83ff93c7, 0x0f76cdef,
- 0xae6f7a8c, 0x0f35159e, 0xf21cd8fd, 0x902c6a87, 0x353e91a3, 0xcfc87a25,
- 0xefe3c58b, 0x0e3df9e5, 0x6051b927, 0x7f55d74e, 0x29e4fb1c, 0x7d8bf811,
- 0xc4553dbe, 0x9ec88373, 0x52273ae3, 0x556b6e75, 0xd0e6709f, 0x887e267f,
- 0xbaac63ed, 0x95c3d68c, 0x1e77c4dd, 0xba0ae9bb, 0xe3d2f0e0, 0x686ae7f3,
- 0x4de33dff, 0xfb1c38ff, 0x215f1ec7, 0xfb4d53fa, 0xfadfb1b2, 0x7fa27df8,
- 0xd9bc69a3, 0xb819ec83, 0xf9296e7f, 0x7fbee90b, 0x9b75fa27, 0xd4155b1d,
- 0xa8099503, 0x4cd5b0d7, 0xf7a6140a, 0x2ddbc7c5, 0xc0915f68, 0x175e6cc8,
- 0x156ec0d2, 0xc26574f1, 0x13d920d0, 0x13abd8ad, 0x0c132ade, 0x9264777a,
- 0x09da879d, 0xdd9d7151, 0xfbe1ef82, 0x0bff3665, 0xc9c26f82, 0x87a5ea3a,
- 0x200d960e, 0xea9138fe, 0xede43c64, 0x7d26ea9b, 0x21edf085, 0x01fffefb,
- 0xf078e6be, 0x3ec59ad5, 0x2579f59d, 0x86f38f64, 0x3e947921, 0x3a6a15fa,
- 0x21084f3f, 0xeebfb0ef, 0xb1fe5375, 0x90f165c6, 0xf2427eff, 0x35b6f5ef,
- 0xdaa18f32, 0x29a91f05, 0xb17bf5a6, 0xcff25b7d, 0x6a2fb919, 0x910ba1be,
- 0x33d9c03f, 0xe8815174, 0x6aa87f13, 0xe1f90f61, 0xe490ff3d, 0x83f9f8a1,
- 0x183f8144, 0x8fd1f3d2, 0x777bf9f1, 0xf1b679e7, 0x65a78173, 0x0e9aecc1,
- 0x06b38fec, 0xe3fca06f, 0x47ff34a1, 0xad3b8784, 0x87cc91c1, 0xb449f58e,
- 0x8e05e28f, 0x0ff88c53, 0x32dd3ce3, 0x705c7fbc, 0x46c1fded, 0x64e96576,
- 0x7f637781, 0xe88db1c4, 0xf124def1, 0xe10780dc, 0x303e26e8, 0x0785eae0,
- 0x8f393886, 0xd4ff2200, 0x2e8be325, 0xa7ec8f5a, 0xdc7910ea, 0xff38983f,
- 0x8ac24552, 0x4de77dfd, 0x791a0f1c, 0xfb1022e0, 0x49b53e4d, 0xf803e065,
- 0x96a2513b, 0xcb5c695e, 0x7684fdf1, 0xf6fe262d, 0x2a9d3db2, 0xd5a9bfdf,
- 0xf6a0e25f, 0x5379e8fd, 0x093f1c65, 0x59c52a82, 0xc6623b93, 0x467fe71b,
- 0x18bd4feb, 0x4d293cfd, 0x3041c3da, 0xb24f3228, 0x974dc641, 0x10a7664f,
- 0x2b186b1f, 0x8b0f48a8, 0xd4a4c2ae, 0xb0d33d3e, 0x4959e711, 0x2db8da9f,
- 0x8fbceb38, 0x88dc69f6, 0xf49a3f0c, 0x435b9baa, 0xc2ce0aee, 0x623630bd,
- 0x0617291f, 0x2fbf2f1e, 0x23ae38f0, 0xb0d397e7, 0x43356e6f, 0xc3c3ef50,
- 0x0c2f8914, 0xbbfe38df, 0xf6c1d17c, 0x62db626b, 0xead9e495, 0x711e8136,
- 0x113d04be, 0x6c7d08f4, 0xea8d49cf, 0xb59e92ab, 0xca7ed109, 0x924fb978,
- 0x7ad45067, 0xd062bf86, 0xacea50f3, 0xc663f256, 0xdfb1563b, 0x3b293292,
- 0x93a2fd6a, 0x042ef8d1, 0x63e2979f, 0x71c087cf, 0x5ab3c4c0, 0x29327f94,
- 0x63f983bc, 0xcfd187d2, 0xee8f9ca7, 0xfcc9a697, 0xaedd2c56, 0xfb184f85,
- 0x7fe969cb, 0xde5d3e3f, 0xcda67c68, 0x8667c689, 0x039f1a2f, 0x6be34596,
- 0x1f1a3fa0, 0x898d5783, 0x7d61bf1a, 0xd87f5461, 0xcd44a70f, 0x198342cf,
- 0x75be1fd9, 0x91fcd45e, 0xf545163b, 0x67753f47, 0xe0dcfcd4, 0xbcf1a88a,
- 0x2efe6bdd, 0x368417fa, 0x3427cd44, 0xfe87be9b, 0x4bfe3637, 0x53ff7ed4,
- 0xa18daff4, 0xe7d256ff, 0xa85e8813, 0xecfb0b37, 0xa425b919, 0x6f4d5d3f,
- 0x9b79437c, 0xf9ceb140, 0xf03cc0aa, 0x2fd8e0d4, 0x7a429f54, 0xdaa2306e,
- 0xd6a37a84, 0x1ec8ab04, 0x71326a3c, 0xf390d31e, 0x3f84d317, 0xc89a62f2,
- 0x7b78197b, 0xd922ed1a, 0x43ea5541, 0x248efa73, 0x935453f2, 0xfec9da09,
- 0x1fd61e69, 0xbe101ce7, 0x0755f719, 0x4ac5e701, 0x982d2792, 0xbea8fc88,
- 0xa9fc72a9, 0x8e83f20e, 0xe4e6a4f6, 0x9f8453ce, 0x4e9b0e2b, 0xfaa6ab7c,
- 0xf0df6403, 0xa1e7a19c, 0xdef39fbf, 0xf1495846, 0xe65fd196, 0xe699bf5e,
- 0xe67bbb2f, 0x7b7f8a48, 0xacaddf9f, 0x43a08d2c, 0xc51739e4, 0xa40eabf1,
- 0xd867fb09, 0xdc7ec313, 0x3a6bd569, 0x538c3ed0, 0xbb407d85, 0xf10d2071,
- 0x88f281f1, 0x0169f859, 0xed1f9d33, 0xb827df2a, 0x80df21d0, 0xdd9f4a6d,
- 0xe643bfd2, 0xda3b20fa, 0x00937d6f, 0xf74438a3, 0x1de33df0, 0x955dfe86,
- 0xecbbf8cb, 0xf97f9e88, 0xaf02e1fe, 0x90f620f7, 0xe22ce70e, 0x17fc063c,
- 0x42fe5ea5, 0xd24ee5ea, 0xebf911c7, 0x2676bb55, 0x2e7e7f91, 0xc6e3f847,
- 0x3a49dff3, 0xe54d2eff, 0x9dddaff3, 0x047cfeb0, 0xae422ade, 0xe3557ea8,
- 0xf991f5c0, 0x39c6b5cd, 0xe7468afc, 0xa8e52758, 0xf923b5a2, 0xfe7f604e,
- 0xb75c34c3, 0x7b95d772, 0xa6fbd00e, 0x67614c9e, 0xd2dfbc03, 0x82e380f7,
- 0x28817fa5, 0xcd33b6bf, 0xa67570cc, 0x09613889, 0xbbe44e36, 0xb803e825,
- 0xda637da8, 0x7c3fe22c, 0xbfb0561e, 0xa4cc15a0, 0xb3fa16bf, 0x33f484cc,
- 0x3f6779e0, 0x69cfed1e, 0x1b73ef3a, 0xfb7ef8f8, 0x922a7bdd, 0xd6340fd8,
- 0x8141d633, 0x3def3f20, 0x499cc057, 0x0ae99f79, 0x9fb817fb, 0xeefb9e8d,
- 0xec99bc1e, 0xbbdfb1b0, 0x0ef4bfe0, 0xf022c5f2, 0xfac6baf0, 0x1134d740,
- 0x4b03f97a, 0x44ed1d2f, 0xa66d0dbf, 0x3685e530, 0xbdf2b39c, 0xcf75774a,
- 0x9c230fcb, 0x66f9af1f, 0x7f7082bf, 0xbfe7bcb4, 0x3bf3e00e, 0x4741529e,
- 0xfdd9f1be, 0xbc447a5a, 0x2bfeee79, 0xafe86f2c, 0x2924ff3c, 0x1eac97a5,
- 0xd60f9392, 0x322a34bc, 0x9f4e485e, 0xf74e9099, 0xe2d2933b, 0xc6c46fde,
- 0x3f886ba5, 0xf6757e59, 0x5cbe0d4b, 0xc372f92d, 0xf9f9a30b, 0xf3dea486,
- 0x2af3fe88, 0x3436c1e7, 0xf1af395b, 0x3587e48e, 0x31337e2f, 0x8f57cf32,
- 0xa95ba97c, 0xf74b7275, 0x09fa3aa6, 0x1e5e4efb, 0xeaab71cb, 0x1e73a2cf,
- 0x3269fabe, 0xf9bdf7f5, 0x6e079f2d, 0xbbf83ebb, 0x78917911, 0x79ea4aae,
- 0xc54af497, 0xf94eab01, 0xb90392ac, 0x7ec2ee27, 0x1fea2b65, 0x5725cf3c,
- 0x29a7b1c7, 0x00a83b1e, 0xc32ab7e5, 0x2be4ac09, 0xe520941b, 0xee34d6c3,
- 0xfb1832dd, 0x1616ea6b, 0x2556bb11, 0x59567d0b, 0xb13704af, 0xe9873e1f,
- 0xa365285c, 0xbfee50e4, 0xd778e3e5, 0x85feb171, 0x3cf6b08d, 0xf55d9dc6,
- 0x38205e5f, 0x395a35d6, 0x292176cf, 0xfb8c196c, 0x84abda5e, 0xdc9f7a02,
- 0x1c44b976, 0x98f42ab6, 0xf55df685, 0xe411c2dc, 0x381d7636, 0xb93d216d,
- 0x59b1e1aa, 0x309179f2, 0x8b9641ff, 0x9595bbb5, 0xd5ac7991, 0xa4420ee8,
- 0x02f842fd, 0x40eafb13, 0x2cfa494e, 0x435e1a6b, 0xb6bd42e8, 0xf58569ff,
- 0x97e242da, 0xf9ef0e0f, 0xdf686fdd, 0x923dff83, 0x7d745ff1, 0x805f07f8,
- 0xb94a8bfd, 0x633c5c0f, 0xb2b2f8a1, 0xde217cc1, 0xba6352fd, 0xcfda1eef,
- 0xfd638f88, 0x10162dee, 0x10d93ff7, 0x82ec9e7c, 0x1cb2c7a3, 0x9a57f9e1,
- 0xce68f080, 0xec0acb1e, 0xc8ce48db, 0xc11db85e, 0xbef57178, 0x84f18d74,
- 0x78fac4b1, 0x3921a0f7, 0x5877a25e, 0xe9579f28, 0x5f10b4ee, 0x173f8657,
- 0x9f8dfff7, 0x89c6f2cc, 0x574e5fb7, 0x273f33a4, 0x6437de4a, 0x30b9618c,
- 0x90c3daf7, 0x60bee58d, 0xa9d90f45, 0x3b91070d, 0xbfb7a214, 0xec0ee087,
- 0x7ce9d04f, 0x9f3e0725, 0xcfb111d8, 0xf47ca51f, 0xf95e59e6, 0xf099ac64,
- 0xb193efb9, 0xf3df525a, 0xaac74cae, 0x97997978, 0xdedd85d3, 0x18bbec9c,
- 0x9e09072d, 0xd95bee30, 0x147be764, 0x2d2d8394, 0x70729145, 0xc45daac7,
- 0x07aa4de7, 0x1b2a0225, 0x79abfa17, 0xc887927e, 0x0cce36a3, 0x4eaa1f10,
- 0xfc27f31f, 0x289bf715, 0xff508fef, 0x3ff74dcd, 0x39ac724d, 0x1e646560,
- 0xf1d4d2a4, 0xe88516ab, 0xa26bc3ba, 0xf5810afd, 0x75f0ea96, 0x94553c70,
- 0x7bdc53a9, 0x202cc274, 0x59bcfd3c, 0x39afbce1, 0x8b35bfd5, 0xe55c7be8,
- 0x2fa396f9, 0xbbbee804, 0x11141c6b, 0x7f79c67c, 0x2a0c2e3e, 0x00b9b3ae,
- 0xe6edb43c, 0xc4dd4b83, 0x38cf3fbf, 0xdd867ec6, 0x2bd20213, 0x503fe835,
- 0x1f9ec7de, 0x093ad30a, 0x1522be39, 0xee9359f7, 0x58b4be64, 0x27ca1efd,
- 0x36fb203d, 0xe08ab7cd, 0x8a27a5b3, 0xf5c87bf8, 0x48baf9e5, 0x6f74cdfe,
- 0x4b7ce7e9, 0x69f05997, 0x71c00dd7, 0x4cfcd722, 0xe32f21a6, 0xb83b06cd,
- 0xd6546aad, 0x44d7da46, 0x79e8dbf0, 0x1ea5c1d7, 0x2d9cdf82, 0x91333df9,
- 0xff7622e5, 0xa99f888f, 0x62b4c0ce, 0x99e1166b, 0x9ff7a6f0, 0x7be4a1f7,
- 0xf9a01f03, 0x115e4873, 0xfcbc6f54, 0xf8bd3f92, 0x7375d12c, 0x95c72faa,
- 0xc2bcd7cf, 0xc6277629, 0xff9c3b95, 0x31b7c901, 0x89f095bf, 0xfcd16fef,
- 0x51efc236, 0xc5b35f89, 0xfe593ba7, 0xdfed3a7d, 0xf141be7b, 0x3c8df7cf,
- 0xff6c96df, 0xcfef9ef7, 0x54e67cf2, 0x2f5a37e4, 0x399e7819, 0xfe201839,
- 0xa2824dab, 0xa8f8f84d, 0xe49b966b, 0x6f91cb6e, 0xd7bc9286, 0x40dc7926,
- 0x9be6b179, 0x6fdc9196, 0xf3277419, 0xe42f17ff, 0xfb11aa16, 0x7f17a724,
- 0x2f3be745, 0xe2c5b1cf, 0x7c73a1cf, 0x9c69cf2c, 0xefba496b, 0xf911e92f,
- 0x7e921826, 0xd7b3fc5d, 0x7194d7b8, 0x61da479e, 0x8f38f38c, 0x5c890dd8,
- 0xfa57b67f, 0x98f81ae1, 0xd1e0ec7f, 0xc2f2bfd9, 0xa92baa09, 0x36c13169,
- 0xb5253e3a, 0x92fdee22, 0x0c119355, 0xb2186d7a, 0x8d3435d3, 0x39d89f3b,
- 0x3ee116af, 0xf8550108, 0x0cf9d169, 0x255e2af0, 0xdaf18f32, 0x63cbeb9a,
- 0x21afe33c, 0x63cd8d79, 0x969b0e4c, 0x23ae525b, 0xbcdaf19f, 0xd18cf9b8,
- 0x5171d119, 0xc0ce8641, 0x7f047285, 0x4189c286, 0xf1833791, 0x26eabf94,
- 0x9fe3855b, 0xde5999e3, 0x9b1cae95, 0x13e0ed0b, 0x3adb6c4f, 0x8470e50d,
- 0x6bf503c0, 0xf1f5c988, 0xe6f507ec, 0xc31b5e47, 0x3dea387e, 0x4e02f395,
- 0x1d0c4b09, 0x137fd08b, 0x2a27a541, 0xf63e12bf, 0xdbf1326d, 0x2dfd549e,
- 0x9b4f4fa2, 0x092875ca, 0x15c5875a, 0x900eee47, 0xe076807f, 0x3e84339f,
- 0x7b8a35b7, 0x65ee9b4b, 0x74e0993d, 0xe423538e, 0xd8432f24, 0x1f638aa5,
- 0x2ca0b50c, 0x4c9d325d, 0xd7f5c7ce, 0xa64fafed, 0x73dade34, 0xd2a44f6f,
- 0xff353b9f, 0xff3c0c82, 0x51aeca17, 0xb75bf236, 0x7e12c706, 0xae6ce142,
- 0x20d02ccf, 0x87f615a0, 0x3c29eaa7, 0x9504ba14, 0x5b71a54f, 0x257e34d0,
- 0x58555ff1, 0x30f6979c, 0x6dcc8aa3, 0xd5dfb854, 0xeb4a9358, 0x79b6fd55,
- 0x97afe910, 0xf39f8432, 0xf13cd5e2, 0xcd1a06be, 0x25c33fbf, 0xa2682a99,
- 0x324be37c, 0x5575d94f, 0xfec679e5, 0x55338d05, 0x7e41f227, 0xce11c778,
- 0x7559368b, 0x73c26fa2, 0x94d1f020, 0xd5687ec0, 0x7640d9e1, 0x1e05dbaf,
- 0x24f7c705, 0xfc447cf6, 0xd56cd3d0, 0xc1373ee9, 0x715203b9, 0x1eb23dfd,
- 0xb619172c, 0xdcf7d1de, 0xe9a12fd8, 0x24439497, 0xe57be0be, 0x4c076d04,
- 0x3be24477, 0xc959d849, 0xc3127b57, 0xe967ba26, 0x59efdf41, 0x4e0fab86,
- 0x380d7de0, 0xec0ed973, 0xf85cf4b1, 0xe5c33a71, 0x05c83e24, 0x8d342701,
- 0x26af49d6, 0x8e7cbd38, 0x09eea704, 0xaae1fd28, 0x208e8b1a, 0xa4a3cfca,
- 0xc9f4a6cc, 0x5f625577, 0xb0b286df, 0xfca41b27, 0x9d2b6eb7, 0x8547d916,
- 0xfdefa933, 0xf8e278ff, 0x9c21dab6, 0x48a80bff, 0x49b63b7f, 0x214e74a9,
- 0xde122857, 0x0781428c, 0xdbb40baa, 0x7cef78c4, 0x2a4773e4, 0xe79e7fdb,
- 0xf3ed3ab1, 0xf85e58b2, 0x0ff0d17e, 0x17c2521f, 0x76d2466e, 0xc94be63e,
- 0x9a7573c7, 0x875c3c8e, 0x3cb8fef3, 0xfd8c2a34, 0x79ffab16, 0x3f57cfe2,
- 0x80bdb15c, 0xb31eeff4, 0x4ff49ca7, 0xf671e047, 0xeb345fcb, 0x0ee422db,
- 0x7264f486, 0x3ecc61dd, 0x3d36e755, 0xf776fe4e, 0xfba74541, 0xcf736ef4,
- 0xb2bb8250, 0xd50b33e9, 0xfc1d5663, 0xb2ebfd84, 0xda5eff4c, 0x3563526f,
- 0x864dcfd7, 0x873f5c1d, 0x20eb917a, 0x4fa16e43, 0xf51d9f2e, 0x1d04756c,
- 0x06f293de, 0x6461fe3d, 0xbca49abf, 0x1c38a61e, 0x772dfddb, 0xf7f5a70c,
- 0xf180fccb, 0x191c355e, 0x04df784c, 0x3c6b71af, 0x5c6a0eef, 0xaef79cbf,
- 0xc46f5eed, 0xfe52d3fc, 0x56fdcb4f, 0x20dffa67, 0x7cb6d778, 0xc2d2a16a,
- 0xa1a1f3aa, 0x3486f714, 0x4719c53d, 0x6fcaf48f, 0x69553c8c, 0x5f9a163d,
- 0xaf581175, 0x536bbd20, 0xbd2f7e90, 0x396638db, 0x348fdf3e, 0x8b3b2149,
- 0xe3d92af1, 0x60df66fd, 0xcefd5f9a, 0x8f4963d7, 0xf020241d, 0xaf375f7f,
- 0x4378461d, 0x244e2ffe, 0xac0bdb39, 0xcd390cd7, 0xf7c53927, 0x8bff89f3,
- 0x7acb9fa8, 0x7da58f79, 0x7ee5cb1e, 0x225c9013, 0x203cb3ff, 0xdfc93bff,
- 0x3ca277cb, 0x59a3fbf0, 0x9bb4f7ce, 0xa337ecbc, 0xfdc91f5e, 0xdfd4c5e2,
- 0x64ea5ed3, 0x843aa739, 0xf0d79242, 0x04275e11, 0x45f2d740, 0xfd22f80a,
- 0x648cbcff, 0xf1242f71, 0xd8433939, 0x9e8e5083, 0xd873c1e2, 0x3e4a3555,
- 0xe8a5ec22, 0x9a5a7b4b, 0xbf6d97f9, 0x26524698, 0xda5384ed, 0xd678ff49,
- 0x6d28fffb, 0xa7d786d5, 0x73c3a82c, 0xf2a5386e, 0xf71961f8, 0x1c9f2585,
- 0xb21af991, 0xa89a7a1b, 0x13e7a61f, 0xe5f54fb0, 0x4bebbd13, 0x9a4d1cc8,
- 0xb528e3b3, 0x12a17c53, 0x2da6db72, 0x166a3f6b, 0xfc479e62, 0x6e6470d7,
- 0x75e3d51e, 0x0242b39f, 0x6df0d882, 0x222f47cf, 0x8c3e1e1e, 0xa7638ff8,
- 0x7fcc38f0, 0x060d7fe8, 0x6ef1ff77, 0x4091ea45, 0xc7e27cd2, 0xafb506ae,
- 0x2254808f, 0xfddf5363, 0x007b7da4, 0x677fe76d, 0x2267077a, 0xf00ccf3e,
- 0xfa7ddb73, 0xcb124cdb, 0x5c4567fd, 0xe6f160df, 0x6434ff11, 0x871ba863,
- 0x2299ad4f, 0x856453ef, 0x379cf7b8, 0x18390a67, 0x0aed8015, 0x33aaebc7,
- 0xd4bf7488, 0xe82d7aa0, 0xc0845d2f, 0x6fa4a992, 0x01f75e64, 0xfc5e3f90,
- 0x283cfa45, 0xdf900fbb, 0xc1eb7682, 0x11d6c45f, 0x316fd978, 0xeb0058f2,
- 0x2b5fc44d, 0x0ff8149b, 0x67aac5c4, 0x93afe7a2, 0x1babf275, 0x8c1b1d77,
- 0x5cf35d74, 0x2df938cc, 0xe211ff7c, 0x5d5d7878, 0xcdc33d74, 0x197fd299,
- 0x7fc9c30e, 0x3d62be41, 0xd5a0d661, 0x60ac7c8a, 0xf6224314, 0x0be04992,
- 0x67cb2bf5, 0x8a6f61be, 0xb9ea5e85, 0x94a75c04, 0x94743bbb, 0xd4a681ea,
- 0x8f687965, 0x9f189a29, 0xee2598d2, 0x4aa0b4a7, 0xbc930c75, 0x77ec59fe,
- 0xa967bc07, 0xd49564de, 0x5fc4e097, 0xd3c8fbca, 0xddfe92af, 0x9d6c60ea,
- 0x9553c0a8, 0x8219379c, 0xcaefb435, 0x69dea2dd, 0xf9e8eeed, 0xeb4f1255,
- 0x8c7d3a9e, 0xa11585d2, 0xa7897198, 0x3a98c6aa, 0xdc38b116, 0xadef299f,
- 0xf5fb7d64, 0xd1fc5bd6, 0xb78dfc2c, 0xf8c63ae5, 0xef914ce6, 0x1063c4ad,
- 0xd505d77d, 0x2ad1f120, 0xfc2c9025, 0xc72c705e, 0xb067ddf3, 0xbdcfac81,
- 0x3ee9e25f, 0x7e7c3fc9, 0x19e2bf7c, 0xfdc57df1, 0x7f868b3f, 0x832cf80d,
- 0x0d83f9f1, 0xde50b03f, 0x56df9631, 0xffd999d5, 0x13f1235d, 0x7a6b5fcb,
- 0x858767f9, 0x7f2c5bec, 0x6b95fa55, 0xf6fc2fc0, 0x0df85bff, 0xcb91af3a,
- 0x398735ac, 0x09f6b53f, 0xabf943c5, 0xf7ab9d6b, 0x7f7cf23c, 0x359eb9ef,
- 0xc6063de8, 0xa4e7bd30, 0x63bd175d, 0x96bdedfd, 0xe726bcde, 0x66b72f05,
- 0xe0dd3e73, 0x6675d8ab, 0xf67dbf49, 0xbd7fc253, 0x276258d4, 0xa4fba3ff,
- 0x9ce8a3c9, 0xc02e4caf, 0x566f8ff3, 0xee91fc81, 0x033be1a6, 0xa9e17f08,
- 0x5f94c5a2, 0xed0a7f1f, 0xb707dd13, 0x0257fd16, 0xd27b07df, 0xb667ee48,
- 0xbdfb488d, 0xfb61d783, 0x70b27dde, 0xe9e93967, 0xb445a593, 0x54e382ae,
- 0xed285e9f, 0x42c9f554, 0xbd84477b, 0xc8a64dfa, 0xff716fcf, 0x1b8a51fe,
- 0x7b35ef66, 0xdb323f28, 0x8094dfec, 0xa0be15f0, 0xb771aa78, 0x9e47ed63,
- 0xbe5175a4, 0xf38acd28, 0x8d08e9fe, 0x1851ed57, 0xb2a6eefe, 0x3f643dbc,
- 0xec87aa83, 0x7dd37762, 0x1f920ff9, 0xfe40fcd4, 0x1dfb117d, 0x66fa154b,
- 0xb6660df6, 0xec839dd7, 0xbca72ebf, 0xeb1777a8, 0xfb43ce8d, 0xc37dfc2c,
- 0x78dc051e, 0xa3ee63ce, 0x3a1e132f, 0x50b69c0f, 0x70d25010, 0x4711d2da,
- 0x25ed1b7f, 0x9cc2f30c, 0xe161ddaf, 0x7ffdcdfa, 0x2b79d0b0, 0xf384fb9f,
- 0x7e286b6f, 0x19ef3f20, 0x3a77bf95, 0x85aafcda, 0x4eb2b4f8, 0x91590181,
- 0x271e66e3, 0xcffd4afd, 0x369e84ea, 0xe4857ff8, 0x0dff8377, 0xf5215879,
- 0xe35b7dda, 0xffa1bbf3, 0x96ef041e, 0x03deb841, 0x0eb9cb75, 0xd11d81e9,
- 0xfc5257f3, 0x17cd237a, 0xa9f2befc, 0xbdd5f1e8, 0xfd601e7c, 0xbf47ab1f,
- 0x2e7ff433, 0x5f9f12e4, 0xa618af0e, 0x7d7d3ca1, 0x8830cd7a, 0x293caf93,
- 0x6ec306fd, 0xd89b0e5f, 0xebcec5ee, 0x2162bc6a, 0xfad55b7b, 0x6773f627,
- 0xf4c97d35, 0xe16a6f28, 0xc05bd97a, 0x79f08ebf, 0x49dd934b, 0x877976fe,
- 0x9af303d0, 0x42a0c1ac, 0xa25aa1e3, 0xf161f773, 0x90e049bd, 0x4816fec2,
- 0xe252b8bd, 0xe3c4a575, 0x06e38c4a, 0x8c8c7d53, 0xbc652be3, 0xd7673abe,
- 0xa9292a31, 0xdaebe394, 0x1e13268e, 0x5bd081e7, 0x6f4242f3, 0xec31f419,
- 0x40beac50, 0xd10f770b, 0x95936d77, 0x4be7d6eb, 0x0ebf35bd, 0x5fd296f5,
- 0xb40f747f, 0x7ef1fc8b, 0xddac7701, 0x9e886cad, 0xfc201aef, 0x7fd2cbd8,
- 0x4d101c2e, 0xb01ef297, 0x9e7f7e53, 0xfc827aae, 0xfb46bb56, 0x7e458eb7,
- 0xf55bf5c3, 0xeaf129e1, 0x4df68cb5, 0xfd181719, 0xc3679405, 0x0ee721f9,
- 0xffdc6447, 0x7f84039f, 0x1ab266b3, 0xc446ba20, 0xb30a0b49, 0x7349c6e2,
- 0x8637f409, 0x71b3f7dc, 0x77927191, 0xb7e228d7, 0x2cef757f, 0xaaa6baa7,
- 0xba2fa13a, 0x29bae126, 0xfb03f7e4, 0xd67555d1, 0x5533c520, 0x7dfc2fc8,
- 0xc909f11a, 0x46529363, 0xc671827c, 0x42feb4ed, 0xf3c4eaba, 0xfb446c2f,
- 0x2c2fcb8e, 0xabf992fd, 0x3738846d, 0xbc406de2, 0x3788c3b8, 0xbf0aaf2a,
- 0xa95e78d6, 0x51dc7075, 0xb5ea24d9, 0x337c8e1b, 0xede10b34, 0xd0f3fe6e,
- 0x3e4f54e5, 0x86e7d840, 0x54a7d0e2, 0x1ef5f457, 0xb5ff5c5b, 0xb52bff57,
- 0xe6950f2c, 0x6bf64c8e, 0x791fa20e, 0xb7d1ea13, 0xa538e0bf, 0xbdc248e1,
- 0x5aebcf94, 0xfce61fe1, 0xc3553a1e, 0x3783f626, 0xe4b72d41, 0x8dfa451f,
- 0x4ea29d2b, 0x3f6941e9, 0xf208ffa9, 0x773883f5, 0xf97f6146, 0x8549f437,
- 0x10d5ebe4, 0xe95532d8, 0xa42a07af, 0xdfcdacdc, 0xf6ae85b5, 0x0aa7fd63,
- 0x31184f29, 0xf58cbdb0, 0x8633fe9f, 0x4edfab5f, 0xbbb8ff64, 0xae52754d,
- 0xabfbf119, 0x6227e441, 0x271d905c, 0xe485fb5f, 0x7f794ecf, 0x65493d5c,
- 0x8b2699fc, 0x10b7f0d6, 0xdd37cc8f, 0xb2411da7, 0x5f87796f, 0x583e26cd,
- 0xdefa3bbb, 0xe7e8e889, 0xc8a0b1ba, 0x7cec8547, 0xbf8c6517, 0x31d5f874,
- 0x6fd56fc4, 0xd04a3b7f, 0x96519be7, 0x67c36bf4, 0xe2228ab4, 0xe2229366,
- 0x475afde6, 0x556bc532, 0x645f5507, 0xef41bf3d, 0x813ca597, 0xf503f226,
- 0xabe67403, 0x1fc126ea, 0xe2d166a6, 0x7e444bfe, 0xf7fbccc8, 0xbe462f1b,
- 0x067b1ef9, 0x40f21704, 0xf987b995, 0x89b4eaaf, 0x7d3aa9e1, 0xc4447339,
- 0x775a017b, 0xeabfe900, 0xc4fac075, 0xe76fa40e, 0xd891f7d3, 0x027eff9f,
- 0xb2c761fb, 0xfb8b97b7, 0x7f48152f, 0x9af6fc3d, 0x60f691d1, 0x2f7100e2,
- 0x3707840e, 0x10bf3f79, 0x6c3c4bfb, 0xbf324582, 0xaf79f820, 0x2e309b8c,
- 0x9c40737b, 0xfd7aecb8, 0x2b66eae9, 0xeab9fe50, 0x19d72b03, 0x92bcdd7d,
- 0xeab87ee3, 0x06fa4d1f, 0xa91bfefc, 0xcaf0f87d, 0xebfcf4d1, 0xe46fabc3,
- 0x29b2a97c, 0x2011cf2a, 0x5fe4dcf8, 0x5deef57d, 0x69b67fe4, 0xb6149fec,
- 0xee977d9d, 0x9835f769, 0x8ad1dbf9, 0x067613fd, 0x2aafc892, 0x11df4f9c,
- 0x98d56bed, 0x32dfd0ff, 0xfb3b2bfc, 0xd88aa757, 0x7c75c2bf, 0x4e8b6e41,
- 0xa7bad394, 0x9a688b8a, 0xd7a4e382, 0xe57f93c6, 0x0cb7f3e8, 0xf8933e78,
- 0xe0496eec, 0xd9028bbc, 0x4460cf82, 0x1aebdc14, 0x64ff675e, 0xf51aa35d,
- 0xdef188fd, 0x7b88065f, 0x3e0cef87, 0xe65e290b, 0x5da2bda3, 0x932fb8d7,
- 0x1cd6b1ce, 0xaea93e62, 0x3df18b33, 0x07ba05a2, 0x411fc09a, 0x273f0807,
- 0x65d211e8, 0x8438259e, 0xbdbdfafc, 0x2eb28af7, 0xf5ea2824, 0xf3875a6a,
- 0x5b974c77, 0xb3c7a5f7, 0x9ee92743, 0xe3be1d07, 0x8a1e2259, 0x5badff1d,
- 0x9f8e41e4, 0xf8f1fa13, 0x78e8ff4c, 0xc500327a, 0x48a05f22, 0xef8835fa,
- 0x35e763ed, 0xfe787ad3, 0xc70243dd, 0xf73b8f89, 0x63fdf026, 0x75e44ba7,
- 0x34dbea4b, 0x6d661efa, 0xec813283, 0xf79cdad2, 0xec197bf8, 0x5c9e9117,
- 0xf7c83e1b, 0x7b7515af, 0xc0e37967, 0xec2dddb1, 0x9df93cc3, 0x7cf8ec72,
- 0x3c067e39, 0xdb9e3219, 0x673ef74e, 0xf14ecdca, 0xeef89bdd, 0xd7a956f5,
- 0x6662df17, 0xe80cea3f, 0x227f7166, 0x481639ee, 0xd4ab7dbd, 0x63dfb1f7,
- 0x76fdfa1b, 0x67c2ceb9, 0x73dd3360, 0x7d9f7ec4, 0x170ff4bb, 0xefd79781,
- 0xf4bd5df7, 0xfeff6313, 0xea5b8942, 0x8a3051f5, 0xed087af4, 0xe45bd70d,
- 0x9eddb026, 0xae32305f, 0xa9df41df, 0x753bf2eb, 0x57fa0d6a, 0xf6c7bee7,
- 0xb9cb78f0, 0x86fbf997, 0x1d900973, 0xcfad9ee7, 0xe47a1a1e, 0x79774136,
- 0x14e151ef, 0xbff41a30, 0x645a1184, 0xffa0cd7e, 0xff0e9283, 0x394575c7,
- 0x63e645a0, 0x07fea90e, 0x475419dd, 0x38fec9dd, 0x21ed809e, 0x3ca86b9e,
- 0x846b50d7, 0x7034bb9d, 0xee3e5c79, 0x406a5f3b, 0x6e7493d8, 0xecad725b,
- 0x14845637, 0x22b0eefe, 0x9b7fa20c, 0x51caf9c2, 0xbf5c2d0d, 0xf154a4b1,
- 0x3c5a8578, 0x7c19f04b, 0xfc26c0b4, 0x7a5f8303, 0x88f925f1, 0xb85fc9c6,
- 0xb10bfa55, 0xda1a34fc, 0x4bfad167, 0xea878abd, 0x47c9af36, 0x4ebdc6cb,
- 0xf8b5eee1, 0x4cd2f908, 0x9f96317a, 0x1ffb735e, 0xb775fc25, 0x80525e5f,
- 0xfdcf1feb, 0x4ff1286c, 0xe8e435e5, 0xddbf4945, 0xae71c08e, 0x7597a963,
- 0x8db9f504, 0x5697841d, 0xd3b2bf60, 0x8365bed5, 0x8eb9b7f0, 0xc09c22a0,
- 0x4d15a5f5, 0xad6efe76, 0x713aa1a2, 0x26e3e90c, 0x7ec763d5, 0x52e9c379,
- 0x179423ca, 0x2a973a89, 0xabbba8bb, 0xbbba8bb2, 0xe7fee9b9, 0xeff813dc,
- 0x11d74403, 0xb57e3a58, 0x3ef87be1, 0x9335df56, 0x7fe1370f, 0x4b350f4e,
- 0xbb686cfc, 0xc4863992, 0x887fdd34, 0xfd7eeee0, 0x8a7d0b45, 0xd5e63551,
- 0xd6825459, 0xde79d6ec, 0xb52d752d, 0xe0365694, 0x429dbbb7, 0x43839aef,
- 0xbfcd6fd8, 0xea9b7abe, 0x258c6f83, 0xd2d5d5fb, 0xc112d636, 0x501b9def,
- 0x63a1c76f, 0x1ca49835, 0xca2adc6b, 0x0947e922, 0x3e6aaeb9, 0x8bf9499a,
- 0x7ce7924e, 0x1e49df6a, 0xdec56d81, 0xc923c933, 0x5a2fd99f, 0x4d4bbd63,
- 0xad03cf2a, 0x49edd463, 0x666df091, 0xc4852ef8, 0xa31d003a, 0x8e441716,
- 0xd6bffcd7, 0x3e851707, 0x07d288e8, 0x16429e06, 0x0388efe0, 0xa75cad87,
- 0xae3ff740, 0x036a3a08, 0xc26efd05, 0x76e48a60, 0x0f7bdd32, 0x834f9727,
- 0x41afa9bb, 0xfba54b58, 0xea2ab0e9, 0xbeb086fb, 0xbff7289f, 0x50b70b49,
- 0x7964f03d, 0xda053a5f, 0xe80cde79, 0x4e0bd6e1, 0x18ba0efe, 0xb24edc3c,
- 0x5a53e785, 0xe2143f2b, 0x99c27bef, 0x4d82eb9a, 0x871d6f7e, 0xd3787dde,
- 0x0f8182e0, 0x44d5ee95, 0x79ec533d, 0xfc28186e, 0x42bc9bbc, 0x414b910f,
- 0x2093c0f5, 0xd3f9f7c4, 0xebde43a1, 0x54c73fc7, 0x1ee90b8c, 0x31ba3a6f,
- 0x208f8c89, 0xe7469fcf, 0xa79de351, 0x19933e63, 0x9f049d4a, 0x7d34ce12,
- 0x73febf67, 0x28355374, 0xebefbde5, 0x5171fae9, 0xa7a83ddf, 0xa9f78de9,
- 0x7af1597e, 0x43d9beb9, 0xfc538ddf, 0x7b3ad613, 0xc03659f5, 0x722b8198,
- 0xfbe84e06, 0xc0fc046e, 0xdfb12475, 0x277c448d, 0xfe231702, 0xe751922e,
- 0x48b83bbb, 0x65913aa7, 0x7bfe36e9, 0xa1b6853b, 0x79af29e3, 0x339fcd28,
- 0x7dea8330, 0x62f246eb, 0xfb02705a, 0xecbf92b9, 0x78449de0, 0xf7c6bc50,
- 0xd37cc02b, 0x320bf7fb, 0xb227bf81, 0x3e77c55b, 0x6d1f91db, 0x3a052ca9,
- 0x23c35fd5, 0xd3f93a25, 0x0f365c5b, 0x256c477d, 0x707dedb8, 0x1d44d8d7,
- 0xd44d8d48, 0x72f51879, 0xb1ad78b1, 0x8f4e7919, 0x98f1fd8d, 0x627e90ef,
- 0x7842dff3, 0x98a9287a, 0xde530eff, 0x5cdcd32b, 0x7fbf250f, 0xf03049aa,
- 0xe7e36c50, 0xec94f57d, 0x3d52d667, 0x9359c237, 0x78ff5c01, 0x0a546934,
- 0xb4d565d5, 0x9aee7a89, 0x77eb008c, 0x7d615fb3, 0xd25ad35f, 0xb2e2f64a,
- 0xdd75c2c3, 0x07512e35, 0xd080c81f, 0x3d347af3, 0xa0f419a6, 0x8f594bfb,
- 0x5c65d064, 0x7bd0943a, 0x91dec2e3, 0xdb429384, 0xfdd037cb, 0x7470b8c2,
- 0x69d2197d, 0xf7a9d135, 0xc9cd1e3b, 0x7d061ef5, 0xd9987190, 0x06ee929d,
- 0xdfc69cbd, 0x516af023, 0xa0c08f7f, 0x4144f6e3, 0xe055332f, 0x7577e70c,
- 0x4e96375a, 0x14e11bff, 0x4bb0bac1, 0x00004bb0
-};
-
-static const u32 xsem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x93cbff00, 0x51f86065, 0xd2f9c08f, 0xbcde0c0c,
- 0xc4b462a8, 0x0c0c5c0c, 0x0e5c4041, 0x7b401ac4, 0xdbe9016f, 0xcdce1c40,
- 0xc40110c0, 0x1ff881fb, 0x6207ff10, 0x04d6200d, 0x79405fe2, 0x5b1ba845,
- 0xda181898, 0x8803b880, 0x875880bb, 0x97418191, 0x93fb7891, 0xde181984,
- 0x7af82389, 0xcd0c0c12, 0xfff3f452, 0x5631c360, 0x29efb5f4, 0x174e3ed0,
- 0x19c73f04, 0x505c2498, 0xe0bb70d5, 0x4d078337, 0xcf8d179e, 0x9e7f4787,
- 0x5cbf2a21, 0x4d3f950b, 0x23e18187, 0x2d0a9a92, 0xc7416efc, 0x0c0c468a,
- 0xabc4464a, 0xca8c60df, 0xd081300f, 0xb1adf900, 0x0003a809, 0x00000000
-};
-
-static const u32 xsem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0xf37df0f5, 0x66499996,
- 0x0d909326, 0x8a027108, 0x081380a8, 0xc3b44069, 0x8e22a222, 0x260dc55b,
- 0x1037d902, 0xfdaff0fd, 0x2d361032, 0x4682d0d6, 0xa0c0748b, 0x0d0482c1,
- 0x00e02418, 0xd52ff82e, 0x5b7bbfd8, 0x16c34a0c, 0x7e1b8092, 0xce7fe5b5,
- 0xef25f7b9, 0x6d80264d, 0xfdfb5fbf, 0xe6f169bf, 0x5ddf7bbc, 0x3dcf76ce,
- 0x14fbdcf7, 0xf89628db, 0xe0cec663, 0x2cabd20f, 0xdd51b18c, 0xa0db6ce9,
- 0x74fa87a1, 0x6559ffe7, 0x4287ead3, 0x6ed0ab1e, 0x9cfdd61e, 0x7e5485b1,
- 0x386b8c40, 0xf4d31cbb, 0x8f0e1b10, 0x9616c96d, 0x6e7dd8cc, 0x0901bf46,
- 0x912974be, 0x5615ceb1, 0x780cbaf7, 0x085c7aae, 0x20c8f7df, 0xf7c25077,
- 0x1652c93c, 0xbaa23fe4, 0xbecc01d7, 0x6cb3233f, 0xe0da66c6, 0xc3fc0f6f,
- 0x7cbea07a, 0x63106cac, 0x059969ea, 0x77ea7fa0, 0x3403a512, 0x00efc336,
- 0x6c2df978, 0xfeeed0dc, 0xecfd13b9, 0xe8b78073, 0x5b7e89f9, 0x097f90c0,
- 0xecffa893, 0x5faa4afb, 0xf2f16f6f, 0x073e6c5b, 0x8d941636, 0x7f963bcf,
- 0x8be7c2e9, 0x7aa16e9b, 0xd82c5318, 0xc8b772cf, 0x635cfc4f, 0xbbfaee96,
- 0x76a214f1, 0x04d3d874, 0x3188feed, 0xb6bfb5e9, 0xd543c032, 0x0563d556,
- 0xaad84cbc, 0x700c7f86, 0x84295ae9, 0x9d9765b0, 0xfb4bc031, 0x9d870e6a,
- 0x9fcb0f9a, 0xaa1805a8, 0xff36b728, 0xdbc40afc, 0xa3ad9956, 0xf784fc66,
- 0x3bc71b56, 0x9e70e46b, 0x6ba5839d, 0xf7c74f77, 0xccad1a0b, 0x6e95f50e,
- 0x057a9fcf, 0x54fbf9c0, 0xd74a4586, 0x01fad02f, 0xea92185c, 0xcf18ee11,
- 0x36e0fda8, 0xca1eb439, 0x939ab877, 0x1ff1836f, 0xcf31b4ab, 0x676fd0c5,
- 0x80adf273, 0x96d0a287, 0xd15ef849, 0x2c8bc946, 0xfaeb6134, 0x7bc2fb37,
- 0xaf241ba5, 0x5c52f015, 0x433ccb17, 0xc0ce1f78, 0x3906d6bf, 0x9fc863fc,
- 0x1964e30b, 0x49ead748, 0x57f6c64c, 0x37671e68, 0x0e558e9e, 0x376b1e61,
- 0xda01ba5c, 0x5ecaf781, 0xc438bc94, 0x200b0b32, 0xb76fb65f, 0x81d67b4f,
- 0x0da05be3, 0x96b8e276, 0x3f2e586a, 0xeecdbb94, 0xd5adfec1, 0xd17e4126,
- 0x9e5ab5ea, 0x75c5fe81, 0xcd8f3197, 0x419aafd0, 0x88fe4629, 0x9b018f4c,
- 0xc453fb18, 0xf91eaf98, 0x37690944, 0x9fa2e419, 0x2ef44f14, 0xf54d93ae,
- 0x4b192603, 0x007eff82, 0x82be027f, 0x57849d3b, 0x05736e9d, 0x3b74e91f,
- 0x2987e425, 0xfac6d99d, 0x48e7f4f5, 0x754fe807, 0x5fd29ba5, 0xba52a654,
- 0xf443d2b2, 0x07f10279, 0x6fd172e9, 0x4e3658d7, 0x3e5d7681, 0x4b3146e6,
- 0xa71be298, 0xe7e09c02, 0x01ddf270, 0xf19673c9, 0x6a13e9eb, 0x72651720,
- 0x53e49b15, 0x05ac02fa, 0xb42f30e6, 0x9be8dcaf, 0xd7b19a38, 0x1c71e059,
- 0x502922ff, 0xac657480, 0x740fd53e, 0x1e812259, 0xc52d7c01, 0x961e0241,
- 0x067e05f4, 0x4f713d3a, 0x24b2b3f6, 0x70889ac6, 0x668f73de, 0x54353d50,
- 0x0cf50a8f, 0xc93d773a, 0xf54c73d3, 0xd02f4f24, 0xf54b59eb, 0x9eafcfd8,
- 0x318fa627, 0x917a67f7, 0x580bcf5e, 0xfcf3916e, 0x633c95c6, 0x333fb9ac,
- 0x949ea84a, 0x002cbdbb, 0x7f9d65e5, 0x864fb358, 0xf8c6c77c, 0x23328f11,
- 0x86df8d1f, 0xaa4139f5, 0x97147c8c, 0xa7926313, 0x09825f78, 0x9fb933ee,
- 0x7f927ca9, 0x653f29a0, 0x7c11a5da, 0x5eb770e9, 0x54e86026, 0xfea35e38,
- 0xd234fd6a, 0xd9fae33b, 0x9fa07e08, 0x03cef483, 0xbb170263, 0x57d8dfa1,
- 0x407ff406, 0x8eee5c0b, 0x2e3037c2, 0xea62a589, 0x991a60b1, 0x78e554bf,
- 0xfbffdf1b, 0xfde107c1, 0xe0e74b72, 0x4bff8078, 0x8e21f71a, 0x4ca88ffb,
- 0x32316e81, 0x3172c0ab, 0x6ffa4656, 0xb3f64669, 0x975e0341, 0x917e000d,
- 0xa65debba, 0x1f915206, 0x4115825b, 0x3025cfe4, 0x8c7eb041, 0xe115641d,
- 0xfef085e0, 0xc454bc80, 0xfd0355bf, 0x835f6c61, 0xfb5287f6, 0x5b7ed8ad,
- 0x075bed2f, 0xb7da98e6, 0xda9817a5, 0x3ed069b7, 0x706747c8, 0xf01f68be,
- 0x93b18637, 0x6fb53e6c, 0xf6a02f4d, 0xc0ac6a97, 0x574c7ed4, 0xbb60dffb,
- 0x49fb63df, 0x703fc651, 0xe9fc798c, 0x6bf1e645, 0x416cfc7c, 0x431fb450,
- 0x20a497e3, 0x117a7f1f, 0xd795bf1f, 0xabbed5db, 0x049aff0b, 0x5ea43aed,
- 0xac683fc6, 0x9417fc79, 0xe56fc798, 0x2c17bbed, 0xa83bed13, 0x196978fd,
- 0x2505ff1f, 0x0d66bed4, 0xb48f9178, 0x211531fe, 0x40d34f9c, 0x07485280,
- 0x921d28fa, 0x93e818c0, 0x8481b2df, 0x38620787, 0x03137ddf, 0xd6e8e6fc,
- 0x12042ca7, 0x9970f308, 0x8de2e9e0, 0x3f3e34e3, 0x9f5e6907, 0xab3aba2d,
- 0x8cf9a651, 0x2e86b4ad, 0x37b6fe82, 0x678441ca, 0x2432bcad, 0x760a7cd3,
- 0xb0a7be02, 0xf3ff3e30, 0x8ceb61aa, 0x674c8ae3, 0x2dadab57, 0xd2eab906,
- 0x90d9e3ef, 0x055fe80a, 0x6ea8c132, 0x34f415b8, 0x39fc3d03, 0x0f4c63e8,
- 0x392edcab, 0x5d9c7a04, 0x059b946c, 0xb2092edc, 0xff4087f7, 0xdffa227f,
- 0xb77c70aa, 0x884293ce, 0xcc566fff, 0xcd9f50d1, 0xa4058eae, 0x5ca3f777,
- 0xbb73a9d0, 0x14f64435, 0x9f88074c, 0x191449db, 0x1baed3fb, 0x305c94de,
- 0x31f4d63f, 0x0b3777bd, 0xf2854e2d, 0x0ee79733, 0xeff8c370, 0x211d669a,
- 0x7cc4fce3, 0xc7242dfd, 0x8725bfac, 0x2b0d69b1, 0xdc00fed4, 0xbcfd4d3e,
- 0x1dfef0c5, 0x577c3301, 0x576e1981, 0xed05aa43, 0xad894299, 0xa9ef7a85,
- 0xedebe730, 0x3812964c, 0x3f7b455d, 0x85f41c01, 0x3a60f747, 0x89bb1f02,
- 0xfcddd3ae, 0xe53fbd5d, 0x4c2ca90f, 0x124b71f3, 0x5127fa23, 0x8f9b80b9,
- 0xd3bfb23b, 0x0fcf9b55, 0xa0fe99fd, 0xec8cf84c, 0x58aecb7f, 0xd9ec059f,
- 0x552f9a96, 0xf1c8c164, 0xc67ff644, 0xb8f1c8fc, 0x721f9c35, 0x39cf9183,
- 0x53f2449f, 0x5fb8e379, 0x53f0321e, 0xbfb5fd69, 0xaf78643c, 0x1326eeb8,
- 0xc3ba185c, 0x26bf3e54, 0xbb3f94d7, 0x3f94d0ba, 0x131cd973, 0xd07c1b9c,
- 0xfcc67e54, 0x7bfca605, 0xe5311e2a, 0xc2b055df, 0x7811df04, 0xf6fe54ca,
- 0xf94d6b69, 0xdc975d96, 0xf5547288, 0xde70cc81, 0xfad1daf8, 0xbf37b473,
- 0xa45e2876, 0x57b011c7, 0x818e0e50, 0x7b6982bd, 0xabb248e3, 0x31e60f41,
- 0x4b56a130, 0xc6cb83fb, 0xa4665ea2, 0xefd2433f, 0xc634c183, 0x843c979e,
- 0x6346b93f, 0x89616061, 0x71f17425, 0x6fc86ca7, 0x0d7e4739, 0x9ec8fa08,
- 0xf44b72f9, 0x72ebe5e7, 0xd3bd402f, 0x5f803e9b, 0x3ae79c7f, 0x99103d84,
- 0xbf31225f, 0x7ebeb9f1, 0x7ae25cba, 0x53ac44be, 0x3bea5e4a, 0x0e10b99e,
- 0x5b38ae0f, 0x5480f57b, 0xfd6893d4, 0x803f2127, 0x51e81814, 0x24c8375c,
- 0x65bb6ddf, 0xea1957ea, 0x99abd004, 0x4257bfcc, 0x9bde133d, 0xec30cb7e,
- 0xd475ef87, 0x8931acfb, 0xcab6f5e6, 0xa43cbfc9, 0x94fc7d22, 0x469ca91e,
- 0x80656b69, 0x059543d2, 0x595e7e94, 0xe54b6941, 0x540f4a7c, 0x63fd2906,
- 0x3f4a32e5, 0xf4a6acad, 0x4a1acae3, 0x510cac3f, 0xa3e95eda, 0x2e879754,
- 0xf617ebfd, 0xc0b758b0, 0x8b0f6e03, 0xb2822cb1, 0xdee724cd, 0x53f39454,
- 0xa3066f8e, 0x63ea7fbd, 0xde8ca260, 0x6fc915f1, 0x47d1d3bd, 0x085e4af6,
- 0xcf4fa798, 0xa70c7b7c, 0x26c2dd93, 0x8f47d033, 0xf79cf45c, 0x2b04a1de,
- 0xa9c032c8, 0x519c9bde, 0x0fb985ea, 0x3a2e75e9, 0x70e75f31, 0x3eb7675c,
- 0xac6c97fd, 0x206972f7, 0xcaf7879f, 0xf0b30f34, 0xd7a45eb3, 0xf49bc50f,
- 0x5bd29fda, 0x2e89dca0, 0x33a735fc, 0x6e48e748, 0x8354ffaa, 0xc7882995,
- 0x2e10d8a6, 0x7bed4f8d, 0x38f285d6, 0x3eae5537, 0x7c77b234, 0x5467d695,
- 0x29e30c3b, 0xa7c3346f, 0xdcc9a5aa, 0xbb89e07f, 0x95f21875, 0x45d0fabb,
- 0x4a54ff48, 0xa6e67af5, 0xb1ced46a, 0x7c7141ba, 0x79f10efe, 0xf13c6370,
- 0xa93bac2b, 0x3fbb3ffc, 0xf7a3d5bd, 0xf606b187, 0x01f50d85, 0xf73a0de4,
- 0xdd07a8fa, 0x3f34af95, 0xfd49abd2, 0x1885ed06, 0x206677f8, 0xac10abd6,
- 0x2f5e5bd7, 0xe397ad07, 0xf6a68df3, 0xbe8f3de0, 0x7af7c7a6, 0xb5855be7,
- 0x7d04e3ea, 0xe7f0a575, 0xabd9d714, 0xbc4af3cd, 0xec6f2e09, 0x679a6d5b,
- 0x7f900ff0, 0xc8292156, 0x9b82253f, 0x32c7143a, 0x6a97fa09, 0xe5bd50f1,
- 0x6a572f12, 0x1e02d16b, 0xb466c762, 0xd1cdee33, 0xfb73cff9, 0x1fdf401f,
- 0x1ecaadfd, 0xd7e17cc5, 0xb06cf551, 0xe7e82d6f, 0x0dbdd011, 0xef5053c5,
- 0x3d76dd1d, 0x98b327d9, 0xa48b85df, 0x8d9d5602, 0x6609ce76, 0x7ffc8c99,
- 0x35defd82, 0xc8deb0d2, 0x9fd468b7, 0xf3cccb99, 0x2667d82c, 0x0cc6bf38,
- 0x939bb1e7, 0x56f3df91, 0xa0b730aa, 0x6ff39a5c, 0xbe49b8b7, 0x12c559f2,
- 0x3f08ef5a, 0xa66ebdd8, 0x2fb907f4, 0xec99e57d, 0x87e8a1dc, 0xf75bfae0,
- 0x7026140f, 0x3128a53b, 0xff20f9a4, 0x3f91868b, 0xfbe182b9, 0xa7a825a1,
- 0x5de64e82, 0xefd27acf, 0xb23ff687, 0xd27cfabf, 0xfa214fc3, 0xbe49d721,
- 0xda759450, 0xd84916c3, 0x974a415b, 0x76eb718b, 0x5c044d6b, 0x47d7011b,
- 0xbf377fc0, 0xbf133225, 0x35025aa5, 0x5fce2496, 0x4a482f68, 0x47f816a7,
- 0x51ed4fea, 0xb53fed7f, 0x3fa834fe, 0xfd7f54db, 0x0bfeb53f, 0x29bff47b,
- 0xafa5fd5a, 0x0416da6c, 0x79b4537d, 0x3cc18b95, 0x4ea95474, 0x4bdd02f6,
- 0x21762fd6, 0x82511c1f, 0xa3e7e42e, 0x34727921, 0x22d2f87e, 0xe7cca2fc,
- 0x855d7090, 0xc7fd427f, 0x54d9f85e, 0x59bee7b4, 0xbd69baaf, 0x5b0d6754,
- 0x1acb4e41, 0xdfa0a70a, 0x1c83e017, 0x46527a5e, 0x9fccd1b8, 0x4aafcf45,
- 0x701eff46, 0x844f588a, 0xab2a5ec9, 0x9c24f3fd, 0x2759ca87, 0x7be459c9,
- 0x04e9fed8, 0x5ab98fd2, 0xe87ccf5c, 0xe5f9d927, 0x0de52f02, 0xbb293b3f,
- 0x30f6bd30, 0x4cb013ea, 0x7c8f0ec8, 0x41d840af, 0xc4ce2c87, 0xb1425856,
- 0xa11fb11f, 0xc2f1d4de, 0xaa0edc42, 0xf0e4f0da, 0xb6afd083, 0x24badfda,
- 0x7974be03, 0xf33f553b, 0x7a7aafd7, 0x62edcbd7, 0x5efdd7bd, 0x34f3de88,
- 0x89adfb0a, 0xd86a25a7, 0xc971f685, 0x841bd55a, 0x9e9b25c7, 0x5c69ee7d,
- 0xf5627eaf, 0x17f5045e, 0xc3e37a6f, 0x6f170031, 0xf0a71351, 0xe4a43861,
- 0xc394fa6e, 0xba23f9bf, 0xf2f451e9, 0x18679a1b, 0x4270fe7f, 0xb78a5d37,
- 0xb0d8d6ec, 0x5098f89e, 0x716b5bbf, 0xfd4fa144, 0x676849c1, 0x56f86d55,
- 0xd1e575c3, 0xc94b125d, 0xb5cf8288, 0x80bd906f, 0x0a7a2278, 0x2fd1757a,
- 0xd0397ca2, 0x247af505, 0xbdcb22bd, 0x1465fa81, 0x93fd17af, 0xbe2fdfc0,
- 0x4fec7e8a, 0x43c45ead, 0xb9f78bc1, 0x95873c70, 0xcfe7ce0a, 0x3f464e2c,
- 0x4c1a817d, 0x9fca5376, 0x9fb9ac17, 0xbdff2ff8, 0xfaf993fb, 0x42d7d7d0,
- 0x2fb05573, 0xeaf6738e, 0x799c68db, 0x587c402c, 0x0fec8cf0, 0xc2b5fa41,
- 0x22896f26, 0x9732c527, 0x80ebc393, 0xc3ce30b8, 0xbf414eb8, 0xd0e5efee,
- 0xcc8ff27a, 0xee0fa861, 0x6cf1fdd7, 0x8b5fc12e, 0xb27184fd, 0xdae75f45,
- 0xbb5bfc4c, 0x74e919b4, 0x052f806c, 0x4ce56afd, 0x487c0a09, 0xf95ea067,
- 0x3853abbd, 0xc947989d, 0x5d81ef16, 0x639f0130, 0x67d566f9, 0x8f7a6e1f,
- 0x6ee8c99d, 0x1f689e7f, 0xf3831dfa, 0x5664e1f9, 0x7c651f50, 0x07aeb235,
- 0xf0375e60, 0xb9de4199, 0xc23ed7fc, 0xff975de5, 0x31934dd0, 0xb9f7abff,
- 0x387be11c, 0xc2bf425f, 0xfbbf9429, 0x83f48956, 0xc9a38595, 0xe42aad79,
- 0xc91f9cdc, 0x457fd02f, 0x0df0338a, 0x744093b6, 0xde5abf20, 0xa8df784a,
- 0x575db157, 0x39757acf, 0x20fa17ce, 0x707d064f, 0x603eb759, 0xe81eb9ab,
- 0xf20aeedd, 0x7a1a9bf5, 0x5f9469ee, 0x07a0d790, 0xe3f557e5, 0xdc6f8ff8,
- 0x209de1fb, 0x75ebc7b7, 0xd5eb35b9, 0x782db948, 0x7c84bd69, 0xc7b7291a,
- 0x894ac00b, 0x3cf0b726, 0xb416dcaa, 0xaaf44bfc, 0x65c7c78e, 0xf5d55eb3,
- 0x8cf86f64, 0xca9793d4, 0x127aa89e, 0xecb3ef7e, 0xf3a8fc9e, 0x457fcea1,
- 0x80bd29bf, 0x9f3a09fc, 0xc5d87cea, 0xf61f3aa7, 0xf098cff0, 0x3b7f9918,
- 0xc10c04f2, 0x7f255dbf, 0xdf134962, 0xdef7838f, 0xf8459fec, 0xc734d1f2,
- 0x9fecdfaa, 0x11438468, 0x79447d70, 0x8fec045f, 0x80881f28, 0x4be54c2b,
- 0x8c6af71a, 0x2a6c20f8, 0x2bff9d67, 0x759445f6, 0x950f3eac, 0x82d49c37,
- 0x9d691fc8, 0x753fea1a, 0xe8a89821, 0x9329dc3f, 0x7003b0ff, 0xe9da04bc,
- 0x0a1198d8, 0x6c591e82, 0x0ecdebe7, 0x012ba777, 0x1cf1c5d2, 0x96d24cee,
- 0x9fd41ea0, 0x1fb9da77, 0xe9dfc3a4, 0x31f8378a, 0xa4c9360e, 0x6c425bc7,
- 0x093f3472, 0xdf8434cc, 0x3e5bd616, 0xe0768ff7, 0x87b633be, 0xcf40cefb,
- 0xfa4765ab, 0x56bf5c7c, 0x23605ecb, 0xedc16b36, 0x77a1742e, 0x71ba0d34,
- 0xfd9f3c1a, 0x6db7ccb6, 0xafa53e82, 0x8471dd61, 0x2b189f05, 0x72de7ee1,
- 0x4d999fe2, 0x6b321d7c, 0x28797479, 0x39e5ef12, 0x77a869e6, 0xb9f0fd61,
- 0xd7ac0fd1, 0xe23ab053, 0x42f5d379, 0x3d69aa6e, 0xce6b5458, 0xd4f5880f,
- 0xc9feba37, 0x7fa49964, 0xeb84a170, 0xafb7a17a, 0x38de8796, 0xb1d3e80d,
- 0xbfb8664f, 0x2649aa7a, 0xc8da9cfa, 0x305953f7, 0x8cafe489, 0xd4be9275,
- 0xf286d6f1, 0x7aef7175, 0x9feb6dac, 0x3e421fb2, 0xe187f6da, 0x6db482bf,
- 0x778327db, 0x47cafc20, 0x3d607fe9, 0x65d84fcb, 0xc7733f27, 0x7ff1272e,
- 0xa5dfcec7, 0x76f0843f, 0x3af7f92b, 0x1c3b7d76, 0xa163b1f9, 0x60f500b5,
- 0x7ebe00c7, 0xedf9daaa, 0x7f9a16f0, 0x331d1117, 0x7de88d14, 0x072fe9aa,
- 0x54e02e30, 0xed0a8c13, 0x24b15d8b, 0xdaafe55f, 0xb1d11fc9, 0x80ecdbf3,
- 0x9e379fe3, 0xd3ffb132, 0x5ed364e1, 0x73c5fec2, 0x8ef979bf, 0xc02ecfd1,
- 0xdd86f1fd, 0x9fc84cda, 0x875fdaf0, 0x78ed7ea3, 0xed4ddb89, 0xdc1acb6a,
- 0x48ba18df, 0xbd02a85e, 0xfac851da, 0xd16fb631, 0x4728f1c4, 0x57f2f13d,
- 0x2f9cb3f2, 0x7c28263e, 0x8feffb3d, 0xf5c7c90f, 0x9364339f, 0x1ddfdc70,
- 0x89ea03f8, 0x4be2565d, 0xebc7bc7d, 0x733d9017, 0xfbdf71ae, 0x52dc6e3f,
- 0xbdc67cf8, 0xff9cdfe0, 0xfa878aad, 0x3d072917, 0x03e77cf9, 0x7a726f04,
- 0xc9e7bfa9, 0xa7ff6bef, 0xa025fdd1, 0xe3dcebbb, 0x4b3fff0e, 0x0ba7b7f7,
- 0x3e31bbba, 0xbfb5fca0, 0xa87eff52, 0x37f96b9e, 0xe36f7ba7, 0xb7fdedd7,
- 0x33f79e2c, 0x5664fca1, 0xe2c340ed, 0x6f3dd2da, 0x5bee4267, 0xb1e37b69,
- 0xf623e3bf, 0x5e34f47b, 0xf1b6fee5, 0xed03efb8, 0xac4978b2, 0xab3af917,
- 0xfa2fb0bf, 0x3b23cbcf, 0x63da7fa4, 0xc5304f64, 0x2bf712b3, 0xe99f4adf,
- 0x360bd8a5, 0xc200e3e2, 0x6c052bee, 0x4afe6f5e, 0x4adc3e62, 0xfd7e9fed,
- 0xd373b43e, 0x83b264d2, 0xf7fb2521, 0xfe64d775, 0xad3344bc, 0x98f5ae87,
- 0x129347d7, 0x89a8ebcd, 0x19abbea2, 0x0ed5ffef, 0x3c021429, 0xcbf01f8c,
- 0x8ea7f444, 0x126548bf, 0x605893c0, 0x263bae11, 0x9df5cc3a, 0x836c7dc0,
- 0xc5eff1bf, 0x3c2ec4e3, 0x47e95c0e, 0xc9900e3c, 0x3c4e7aaf, 0x6f09bf62,
- 0xc78c2199, 0xe3978a61, 0x4bd4a131, 0x1eb16a7e, 0x1da26ec7, 0x349638a3,
- 0xb82b3ca3, 0xa078e69e, 0x9ebeb875, 0x4cdf0dee, 0xd115cfac, 0x257f8ea4,
- 0xcdd9f64d, 0x5cfad1f5, 0xa50fcba7, 0x7fc74e87, 0xaac92e94, 0x8e692e99,
- 0xebca0a39, 0x8c3f5c64, 0x1c99f2c4, 0xb42a0b4e, 0x0fd624df, 0x28e678d7,
- 0xa4278041, 0xaf482a65, 0x22f6db7c, 0x79b51f8c, 0xc5c7ea25, 0x1f9a166d,
- 0xe112596c, 0x428d487d, 0xf7167bf0, 0xd4f7a428, 0xfe395e2b, 0xbb3f4320,
- 0xba06e34f, 0x7c97ef9f, 0xd8cce67f, 0xf0c7f46c, 0xde7fc61f, 0x59b7eb00,
- 0x063859ab, 0x615b34f0, 0xf404b8c1, 0x73ec4b93, 0x0cdc9f93, 0xe4aaefe3,
- 0x55ce7aee, 0xf2bd37be, 0x015f4ecf, 0x45f9f63d, 0x94c76d8c, 0xc6288a6f,
- 0x9a8ff6f5, 0xf7cabe38, 0x1e40d0b3, 0x0dfb2187, 0xab2f8afb, 0xcaf33fdc,
- 0x891a5f1f, 0x1d71dceb, 0x7eb8e343, 0xa971e2cd, 0x8a70bd62, 0x0ebce279,
- 0xe283afd4, 0x9f74bf68, 0xe7168cec, 0xbfac41b8, 0x28f1837f, 0xb2d47690,
- 0x57d7196a, 0xbefc93ac, 0x5b1b5ac1, 0x661e251f, 0x7e116a8d, 0xf8374122,
- 0x7fb8d9c9, 0x0d9fdbc3, 0xe919c6af, 0xa8e536d6, 0x1d27bc32, 0x61b9f7f0,
- 0xc51feaff, 0x11f7ae2f, 0x2dec1bbf, 0xf451fc93, 0xdfc0bd47, 0x91df3dd4,
- 0xa6d2f49f, 0xdfe416b5, 0xa62d6b4b, 0x553ad8fd, 0xb04631f8, 0xa9afd811,
- 0x2cceec7b, 0xd93ecba4, 0xe5a5f18b, 0x40b5274d, 0x48c47d94, 0xe8fd627c,
- 0xdd556f7f, 0xb50eeed4, 0x75e2267e, 0xc31b09c7, 0xad76f575, 0x3f5a38ba,
- 0x7ef2b4ef, 0xf7f566ce, 0xf7f8cf0d, 0x0eb8efc3, 0xae3c7847, 0xf0996b3f,
- 0x1ff24483, 0x553e3e23, 0xbf3842c7, 0xf5157ae2, 0x8c8da9c2, 0xc94077e6,
- 0x06feb863, 0xd1b1ff79, 0xe37173af, 0x5da0df96, 0xb924d650, 0x4ca24b71,
- 0x8fd0d169, 0x2f18de5b, 0xe99c3ce3, 0xdd6fe3d1, 0xc8356ec3, 0x10aaab45,
- 0xd98ef6be, 0xfbb61771, 0xd0c69b65, 0xdebdf14e, 0xfc79c2e9, 0x2491a6cb,
- 0xeb8dbd07, 0x34564ae5, 0x841ce311, 0x87e48c3e, 0x4c631ba1, 0xa07215f0,
- 0x54d7ca1f, 0x6f3ccb6b, 0xd32dfa14, 0x788fb124, 0xf42dfa9e, 0x7b7e99ff,
- 0x016fd75f, 0x23906fd9, 0x419bc0bf, 0xd344a5bf, 0x4f25736f, 0xee7de20a,
- 0x482941ce, 0xab6fb9d7, 0xdbf4d149, 0x2fbe4aa6, 0x4dc459ba, 0x7e803477,
- 0xdfa0dcbb, 0x45bf401a, 0xa3191f89, 0x73fa7ee9, 0xbfd0b7e8, 0xa136fe46,
- 0xde328b7e, 0x74fe041b, 0xe9bc36fd, 0xe1b7e920, 0x3c53160d, 0xf84d44f0,
- 0x6fd57a9b, 0x68add252, 0xbd53ef1f, 0x67f851b1, 0x37c7b093, 0x6c46388b,
- 0x955cf507, 0x5cf4c3f6, 0xb9eaf9de, 0x759e117f, 0x2b77373d, 0x9ee8b8a3,
- 0xdcf5c87c, 0xe7a0eddc, 0xae47e424, 0x64eee6e7, 0xa1172fdc, 0xd0f486df,
- 0x97ca8c6f, 0xe5fbf985, 0xde4f198d, 0xf08df50d, 0x941b5ea9, 0xefadd11f,
- 0x5df51946, 0xbe8bd695, 0xfa7e77db, 0x77d0ab6e, 0xa206c7a0, 0x0fe48d7e,
- 0xde39936f, 0xc3e8c77c, 0x79465f1b, 0xfb4c9df9, 0xf859ef92, 0xa33bd1fe,
- 0x7f21670f, 0xf3fa2a7d, 0xd9e9c6a2, 0xfaa4195e, 0xc7cebc27, 0xfb91ba57,
- 0xb81acbcb, 0x2b56587d, 0xe7f03c87, 0x69df31a4, 0x9dc2ffd8, 0xf8014b12,
- 0x13f56b26, 0x9febb40e, 0x1f589957, 0xf034c94d, 0x629cacc3, 0xd957fbf2,
- 0xfcf0eb5d, 0xd9852cd1, 0xec5fbfd0, 0xed147498, 0xbe1ce2e0, 0x9e2c501f,
- 0xb3b071eb, 0x4464f4bb, 0x9ce3483c, 0x9eb3fb37, 0xad531671, 0x9f53ae9c,
- 0xb7184295, 0x22ee33da, 0xb8a17a44, 0x5dfcfcce, 0xc9377f21, 0xf62f842d,
- 0xee351cae, 0x85d72f43, 0x4f027da7, 0x9e131780, 0x3c545242, 0x64a7a501,
- 0xa5e37726, 0x4b2d77f0, 0xf0a05f70, 0x91f68929, 0xe3adc723, 0x3afc722d,
- 0x773f751e, 0xbf2fa8b1, 0x6b9d2d69, 0x8e8bc48a, 0x747c48e7, 0x1f023de1,
- 0x7e5d69ef, 0xd71891ed, 0x7a437c04, 0x809ff826, 0x3fc76817, 0xf9d322ee,
- 0x5e048f9b, 0x9b8f5646, 0x370fe180, 0xe43a1c61, 0x79ccd5e7, 0x63e02fb3,
- 0x119ec7d4, 0x315e9d38, 0x7dc01ac6, 0x4ef60dda, 0x1f3a83d2, 0x3e72b30e,
- 0xd95e84d4, 0x3c62afd1, 0x251bf3ad, 0xe521da37, 0xb5e13b61, 0x0ed1f81c,
- 0xf53ef645, 0x578124cd, 0x6aaf9d37, 0xd013f314, 0x26eb82c1, 0xf10abe7d,
- 0x9b2358f3, 0xebca5d38, 0x58b25d38, 0x94c7ed27, 0x30de48d5, 0x71aca78c,
- 0xeba1c50e, 0x0e7e19fa, 0xf0a29d23, 0x7f8d12af, 0xb39b3a19, 0x62cde7bb,
- 0xb5aa6e51, 0xe7dc43fa, 0xb1f20a99, 0xfe10d896, 0x3efe1677, 0x2450fc57,
- 0x78132ebd, 0x757884db, 0xb93afe20, 0x8efe15fd, 0xf9e969ce, 0x84d04ae5,
- 0x9f4f09d7, 0x53b7fce6, 0xac5fa0f2, 0xcfc86f0b, 0xc74a3f90, 0xd233f21b,
- 0x465729a1, 0xddf00f38, 0x78e7a327, 0x28d4bf71, 0x0f3b85f7, 0x919ffaf2,
- 0xb8ca2cbc, 0xff7f307f, 0x4deebe40, 0xc55987de, 0xf7f0413a, 0xfdcef63b,
- 0x77bf9123, 0xd12fdc4a, 0xf7da6f14, 0xd7cac1bc, 0x20ec1b4d, 0xf6dfb807,
- 0xe75deab6, 0xae1fa9e9, 0xc03972b2, 0xe0c784f5, 0x0704baf7, 0x75a6f182,
- 0xa4178a36, 0xf6e40c7e, 0x6f5f51aa, 0x5ba4b3b2, 0x7faf7ab3, 0x37bfa88a,
- 0x8787497b, 0x47a87b61, 0x21bda11b, 0xce45eddd, 0xe0ffba17, 0x43bae35c,
- 0x3bdfcff0, 0x1f9dbd2e, 0xce554f1a, 0x4c5f699a, 0xb54aab8f, 0xd1515e04,
- 0x992c9bbe, 0xe7a0b7e2, 0x70ffce82, 0xa36ab7fd, 0xa59faf7a, 0xd08ec8da,
- 0x2d5ecbcf, 0xf010583b, 0x254fa5f6, 0xe32b0179, 0x7f38b183, 0x1079878c,
- 0x8ff72f92, 0xca6ee8fa, 0xed9f6997, 0x29f5dfc6, 0x1bc87dc5, 0xbb1d0c79,
- 0xfb225331, 0x6cac3de1, 0x36e1da34, 0x268ab3e6, 0x47e73f21, 0xd73c21f1,
- 0x3d5b5992, 0x3d7203c1, 0x85542ea2, 0x674277a9, 0xaf483be2, 0x7a433271,
- 0x4cfafb35, 0xbef7f9c0, 0xdc4cb33f, 0x813b078a, 0x8fb119ea, 0x31b96125,
- 0xce5a24be, 0xeaf86e8c, 0x7fa05bfd, 0x5ecbf7a3, 0x69bb940f, 0x7281c3af,
- 0x85b56436, 0x19780c05, 0xe85542c3, 0xc87d1a77, 0x83ea0b77, 0xf07bb002,
- 0xd341497c, 0xc2172ada, 0xbf7a25ab, 0xe498183c, 0xaa6dfe82, 0x32e93939,
- 0x0e500bd4, 0xcd5f29ab, 0x4ad795cb, 0xce710c5e, 0xf1415a6b, 0x12b57948,
- 0x14dc601d, 0xd78d9892, 0xbd41b21b, 0xfbc3569b, 0xc17f3859, 0xed6f58fb,
- 0x416ff7c9, 0xa4fd03bd, 0xfdf237f7, 0xcf783cfa, 0x3b527283, 0x5c2bea87,
- 0x073c312d, 0xcf91b053, 0x55fb054f, 0xec37e62f, 0xdde68a7e, 0xdf5ed029,
- 0xc28f9c0c, 0xd13ce913, 0xe74dc948, 0x80be1f38, 0x0e0756f4, 0xa5f05f18,
- 0x4909f8f3, 0xa3fd62c0, 0x6dfd7fdb, 0x9e535cfc, 0x07d68177, 0x272779ea,
- 0xfc42c329, 0xe1f69274, 0x03be010f, 0x79379c56, 0x9cdecb3c, 0xc316b42f,
- 0x1b6398fc, 0x6acfef44, 0x1e71471c, 0xe29f99b3, 0xe68ea63c, 0x57bbe776,
- 0xefe843da, 0x4ced577b, 0xaf7be7c3, 0xf6f3d2b4, 0xb70f5c4d, 0xbf21680f,
- 0x2ad5e1fb, 0x552ff3c3, 0x13d265ab, 0x74aa3787, 0x867e576e, 0x6fe437c7,
- 0xdec876e2, 0xc3debcd5, 0x9b7edc75, 0x936dccf0, 0x5fce1e70, 0xeaf9cfcf,
- 0x875f5a7a, 0x4d0bb9e6, 0x9ea45bf3, 0xa970f5d5, 0xf54147c0, 0x8f4fda5a,
- 0xfaa5bbd4, 0x6fa1187c, 0x9d9f714b, 0x24c3d3f6, 0x91f5a547, 0x6e8e65f1,
- 0x43f20dbf, 0xefe23bf8, 0xc32afdb2, 0x45f48d75, 0x678a24db, 0xf21ef9c3,
- 0x3e493747, 0xf8287b8c, 0x7b221ad8, 0xe33b943c, 0xf99e703f, 0xc8f0cac4,
- 0x03d22b48, 0xb58e54f4, 0x84bf8ff3, 0xb3df47e7, 0xf010e461, 0x5fe12e4f,
- 0x5ace138f, 0xb27ee3cf, 0x8c995bde, 0xc4d98de7, 0xf207a43e, 0x3016646b,
- 0x92a38de8, 0xf93b96ef, 0xfb46e0fc, 0x966ba747, 0xf3879d56, 0xeb8d916c,
- 0x957acf47, 0x0bc78bce, 0x3e0bd618, 0xb70a77b4, 0x0cd648af, 0x73b850fc,
- 0x0ea83245, 0xcbc444b6, 0xe6738954, 0xa76f1a85, 0x5ee49770, 0xaf47686b,
- 0xdb57af47, 0xb41bdfce, 0xd5bda793, 0xa3fd885f, 0xa1ad7e71, 0xa7ac88de,
- 0xd4bdfb47, 0xa75ff393, 0xffb9e257, 0x0a65779c, 0x62f9cf76, 0x3ee320ca,
- 0x7eea9e8f, 0x2df7ece6, 0x5fc067cc, 0x98631fce, 0x86ef40cf, 0x40ff2051,
- 0xb91a1bbf, 0xea30d73d, 0x459a56a0, 0xbde51bb0, 0xcba3f84c, 0xbbfdf226,
- 0x16f7cc86, 0xc94ffca1, 0x581f8892, 0x49f5a030, 0x83cdfb24, 0x59f900fb,
- 0x787cfdfc, 0xe1b2e51f, 0xa0a72e29, 0x4fa83c2f, 0x98af56ca, 0x256be544,
- 0xb0dfd60f, 0x92ec9736, 0x51991c82, 0xb241ed7e, 0x0f1a0a93, 0x833ca226,
- 0x7b44aefc, 0xd5ac6ca0, 0x9758ea8d, 0xdfce5d4b, 0x9961e715, 0xcf0c3dcd,
- 0x5876e077, 0xf796f934, 0x72b76133, 0xe1cf2cb9, 0x26eefb72, 0x3e784715,
- 0xad724e72, 0x728cb1cb, 0xc72dd59c, 0xd04f577b, 0x870fae50, 0x99a38a24,
- 0xe5007a80, 0xe71e837c, 0xf3d8edc4, 0xd973f395, 0xbf20a599, 0x72ea5f38,
- 0xa475cbae, 0x2d2b373c, 0xee3f62b7, 0xe34ed2bb, 0xf6d57098, 0xfae3ef0f,
- 0x275ff68a, 0x3260f55c, 0x853cc7ea, 0x78e979c7, 0x5c78552d, 0xad7e8f60,
- 0x3df5a05c, 0xf445fe9f, 0xd9ab33e3, 0x8b6f125f, 0xb5eff1e7, 0xb9fdf12a,
- 0x9c87b3e4, 0x9e7ca79d, 0x4b9d5caf, 0xe5f6f53e, 0xe27ae69d, 0xf5476991,
- 0xf01dafac, 0xbe3c0618, 0x8a59f1b5, 0xc2f13e0f, 0x8748a9c1, 0xe7c01de2,
- 0x9d1b5fc8, 0x4e7a8c2c, 0x55bcd109, 0x39d320d4, 0xb384a603, 0xe51a716f,
- 0x1575c798, 0x3f12766f, 0x0d64bd15, 0x8bf7814d, 0x9c317db6, 0x76166ae2,
- 0xf05adc52, 0x072f6105, 0x1ca3865b, 0xbe3c2914, 0xfc2f522c, 0xe7edc6da,
- 0xd3b1edb6, 0x1d527c70, 0xa8a2dfbf, 0x6ad576fe, 0xc278a7d8, 0x50bb52a6,
- 0x8379f68e, 0xfe78c7c0, 0xbc67fb17, 0x2b8f4157, 0xf5c0db6b, 0x1aa35144,
- 0x8a327bc2, 0x63b4b6ea, 0xc7d171bc, 0x957ff256, 0xf3a49dd7, 0x6f361314,
- 0x794aff22, 0x8fda6ca3, 0x59df11eb, 0x18ad8727, 0x4a50d897, 0x1f0090fb,
- 0xc45eb824, 0xf8c0fe53, 0x3bcde2c3, 0x850105b7, 0xef3f2fc5, 0xac72fd42,
- 0xf10bbd79, 0x359ef50e, 0x3c47bade, 0x2223fd67, 0xc386f39e, 0x2f4b6f74,
- 0xf0c79cf1, 0xb794100f, 0x4e78e66d, 0xec87d756, 0xb667e84b, 0x47feca3f,
- 0xe9be7d97, 0x1e7835eb, 0xe3a5eda1, 0x25dfb06b, 0x0d72fb7f, 0x5db189c6,
- 0xcaf79a76, 0xe280f85f, 0xbef7f5b7, 0xc87f09b0, 0xfe29e786, 0xab13fdbd,
- 0xdf6b6b17, 0xe31d3879, 0x7cb7db06, 0xccfe8c97, 0x26af3b79, 0xadbcef7f,
- 0x94585213, 0x914f4379, 0x11e7437f, 0xb7491f7f, 0x297b0dbd, 0xd004ed9e,
- 0x5760f51d, 0x297d6e9c, 0x88f67f8f, 0xd18ddcf8, 0x88f43bcf, 0xe5b86dc7,
- 0xff512bc6, 0xf27b7037, 0xefb9719c, 0x3f2f3d03, 0x146e3a0f, 0x37f5d7f1,
- 0xf72e359c, 0xf401fe04, 0x74cdd8b2, 0xf661bafc, 0xbcc69faf, 0xc6bd3e86,
- 0x03cf86e5, 0x8a79fa7f, 0xa73e6c77, 0xa5e8e51d, 0x343c50df, 0x078a6fd2,
- 0xd3afa3e7, 0x11ca3cf1, 0xce3a73b5, 0xad3b9d3f, 0xd14fdf74, 0x9e488fce,
- 0x47beb7da, 0xce266a7e, 0xaeb3b435, 0x973f8f1f, 0x9d6b78c4, 0xd0579e3c,
- 0x3d7de301, 0xe22e7a2e, 0xeb5f397a, 0xc5bdbef1, 0x1f6d5ef9, 0xe00fee28,
- 0xb5a5c8f1, 0xb3f1107f, 0x729374dd, 0xcf075e90, 0xe3ad471a, 0x72f42dc1,
- 0xf47b1c77, 0x38aeeab8, 0x21ba08f6, 0xea9e713d, 0x3807538a, 0x49f9046d,
- 0x2e768a3e, 0x8f2d7da2, 0xa3576f7f, 0xe3d6379f, 0xf4117dda, 0x9bdbc7d6,
- 0x7b72e8bc, 0x50fc71ae, 0x4266d13c, 0xb57c4f52, 0xbf5d1f7d, 0x7f4bb4cf,
- 0xebbefad7, 0x148954bc, 0x5eeb1e79, 0x86d2cbe4, 0xeccfe483, 0xf18b7f5a,
- 0x7bff09b6, 0xc5320bdb, 0xdfa92f39, 0x523dfa4b, 0xbde1947f, 0x7bfa512d,
- 0xe7d85dbf, 0x68fe7c8d, 0x7219c97b, 0x7b6d3d40, 0x975f13b6, 0x71483c6d,
- 0xbdd66fd6, 0xe218b5ac, 0x08fe7027, 0xf6d3c619, 0xa4e1eee2, 0x30fdc5cf,
- 0x8954ed91, 0xa29bca76, 0xf1be53b7, 0xe29da9a4, 0x76e6bd60, 0x63bdbb9c,
- 0xac76ef8a, 0xb73358ef, 0xcbd58f13, 0xf6d14393, 0xd8aaec69, 0x29e6afef,
- 0x0f74a3cc, 0x7bdf938e, 0xc862bb23, 0xcce79cee, 0x112e38f9, 0xbae28d53,
- 0x388816aa, 0x537a9fb0, 0xce55de91, 0x77f618eb, 0xe0d7e231, 0x01dd51ff,
- 0x9aaaf686, 0xbf42cfea, 0xd1dea443, 0x642c2d12, 0xe73cf7a0, 0xed0f14e4,
- 0x90d3848b, 0x0f32079e, 0x67ef58ab, 0xcfabfe11, 0x0524b614, 0x5059f7fa,
- 0x7a802ef2, 0x0c5ff7d9, 0xd67b3bf0, 0x8781c3af, 0xa9bf9365, 0x0079dacc,
- 0x35ec2bd7, 0xc847ed3b, 0x7f74ecbb, 0x3b1af948, 0xd6ef778d, 0xbb239f6f,
- 0xc656d7fb, 0x556087f7, 0xb996f783, 0xb7871d79, 0x2fe6bb7e, 0xcbe35768,
- 0x1afe7ed0, 0x89eb8f28, 0xfeb4b18d, 0x8e2978e9, 0x7fcb51ee, 0xa8a9a1ed,
- 0x3963f2d7, 0x4e6fe63f, 0x7d415509, 0x6e1c49ad, 0xee8034dd, 0xc97e28ab,
- 0x7ba5f149, 0x8652beb7, 0xe6fb54f3, 0x60330c58, 0xfb09afed, 0x7ee237ff,
- 0x63d51aad, 0x642f338c, 0x2e78c78a, 0x536118a8, 0x3f23135c, 0xfa11c906,
- 0xe8e31ab1, 0xc5d8113c, 0xa84e7aa6, 0x89780f9d, 0xf8fd838f, 0x3f70aa39,
- 0xe59107d4, 0x76fdfcf4, 0xdcbd8e7e, 0xba39ef0a, 0x9d6b97cb, 0xeeae1c79,
- 0x3349f5c7, 0xe744ff95, 0xb3df9173, 0x23fe5e5e, 0x7aaedebd, 0xe265fbf8,
- 0xfe489b7e, 0x57a5d43d, 0xb4717afe, 0xf4a25bfb, 0x2fdf9e9f, 0xed05a0b1,
- 0xba762d96, 0x67ef0bb7, 0xdb0e73c0, 0x55ffbe34, 0xfdd30ae2, 0x3e843b39,
- 0xd309892e, 0x44fd3e7d, 0xc23cb03f, 0x22f2d6cc, 0x15f4bdd2, 0xb3f8c33b,
- 0x3e9cd7d2, 0xb6e977a4, 0x957f5b6f, 0xb18bf185, 0x7d2bd7e4, 0x1f117fed,
- 0xd3c35a94, 0x2dbcfee9, 0xe7f78656, 0x3b796db5, 0x4db5e51d, 0x9c27a70d,
- 0xb4af5f65, 0x57be6ade, 0x58e38c40, 0xbc42e865, 0xaf3f4177, 0x9e8bd45b,
- 0xdb8632b9, 0x9f18f6d7, 0xdde48635, 0xb1d44f7c, 0xc641c6ca, 0x9e45fbf3,
- 0x7fb17ae8, 0x9d8ffa8c, 0x38f47743, 0x263fdaf7, 0xe699ed09, 0x96407464,
- 0xfa8e3d81, 0xe4eea8bc, 0x7c1ff430, 0x6fdfa316, 0xf9c389e0, 0x73ad33e8,
- 0xcfbfea18, 0x19873bd2, 0x952399e7, 0x92a28f36, 0x8ed2875f, 0xfaf327b5,
- 0xb5378c31, 0xf7a68b4f, 0x12c4c586, 0x8e1e8afe, 0x7a8e7a8d, 0xabe70c4c,
- 0x531f6834, 0x43e5176c, 0x2d33f76f, 0x31b87a44, 0x49ebc3c6, 0xbcf8690b,
- 0x20fb6eb8, 0x950a1e23, 0x72072a6a, 0x642cf84a, 0x832cb52b, 0x2bdbd6fe,
- 0x28f0ef9c, 0xf2813f74, 0x55f8ba7f, 0x3933a6ee, 0x518e3191, 0x5c6614e0,
- 0xe7eb33f2, 0x6fd51448, 0xcc69fc43, 0x646456ef, 0xf7926a95, 0xa94f5618,
- 0x7e2ecc03, 0x43055a5f, 0xec44793d, 0x0c1fa3ef, 0x3d7c6ed3, 0x383f7a48,
- 0x328bb180, 0x4f09bef0, 0xbf80db9c, 0x3eb3706b, 0x2b69e309, 0x5317d718,
- 0x488f68dc, 0x033b00c1, 0x595554fc, 0x03df8837, 0x2f187cc2, 0xf42c2649,
- 0xf37ee5cf, 0x8083b43b, 0x843df94f, 0x1550b157, 0x86c318a0, 0x9e3aefc9,
- 0x96f3fbf1, 0xeb8ccc7d, 0x0741128f, 0x7a4ddc16, 0x7fbac1cc, 0x5aa3009d,
- 0x155b7d45, 0xdc1cb7f7, 0x59b8739f, 0x58c3ed18, 0x42c70b07, 0x1caa18ea,
- 0x2bbfca33, 0x5f03600b, 0xf39ac7ba, 0xf402e523, 0xf5bb445a, 0xf7a83f84,
- 0xbf7a88ab, 0xabf7a88a, 0xe3abd5b3, 0x2836dca9, 0x58a5ef03, 0xf02f595c,
- 0x09b3dbc6, 0x867e01bc, 0xcc7f3de0, 0xfb15e312, 0x18d784e6, 0x962b1bd1,
- 0x8e6eba07, 0xfa7e20c9, 0x4eaedc59, 0x8966978c, 0xc3d70c35, 0xbefd248b,
- 0x1877e64f, 0x1b6e63de, 0xa223e1c9, 0xcf02cd9d, 0x55bf748b, 0xb276f28f,
- 0xb7947abf, 0x263e56f7, 0x6f67797a, 0xde8d89fd, 0xea5ef89f, 0x5a8d8eaf,
- 0x4bd50fff, 0xf47daf65, 0x76efee0e, 0xa03727e9, 0x6e676cde, 0x1a54fd46,
- 0x16b7fadf, 0x4cedc27a, 0xde999a5b, 0xc0dfc831, 0x9a17316f, 0x49f2479f,
- 0xf472fe14, 0x29df7185, 0x61f3bbda, 0xe74d5e7e, 0xbe315c83, 0x9f7cb589,
- 0xdc79eefc, 0x46cb078f, 0x25dfe61f, 0xe1aeeff2, 0x0fdde3f6, 0x1b0fb4cb,
- 0xc1d5bf79, 0xe1efcdff, 0x801f07b8, 0x5f33ddbc, 0xa233850a, 0xdec5dbdd,
- 0x677a878f, 0xde44fe88, 0x9e601583, 0x68e4cb49, 0xbe7160f7, 0x45e1cfd4,
- 0x8b317fde, 0x66fdc5f9, 0x3159e7e6, 0x22dbe26e, 0x0f55a425, 0x82c79eed,
- 0xd1ef802b, 0xc7be04fe, 0x9c592ffd, 0x8d2e66c7, 0x9adfd7c7, 0xa77fd260,
- 0x70e27886, 0x8baf66be, 0x7cfe6ee7, 0x149eb5ee, 0xe54579e3, 0x1ee9ac74,
- 0x9bd52aa0, 0x3d4dfa8a, 0x80f33d7d, 0x07a76a1c, 0x1f218f31, 0x7e1256ec,
- 0x3d24f30c, 0x5084aa95, 0x3f6e2a2f, 0x37bb47cb, 0x5eb3f39e, 0xaebc4b5e,
- 0x177ccecb, 0xe6461dfe, 0x5dcfff81, 0xdff3a1e1, 0xa7fc3957, 0x5d95fe71,
- 0xa380de39, 0xb7043f27, 0xe15771f2, 0x8e7a33b8, 0x7af34aa7, 0x0ebedec9,
- 0xcbf245e6, 0x3fd86d79, 0xc8f9ead9, 0xadfbfd83, 0xd30fd0ca, 0x23de3f13,
- 0x153fc821, 0x24714fea, 0xc194dc72, 0xbc72fed8, 0xfff4146f, 0xe8bf7132,
- 0x52264aa2, 0x08b7571e, 0x34a51fef, 0x913ea447, 0x8f72a64e, 0x974a7b8a,
- 0xd5297a54, 0x56f36bf1, 0xb6983dd3, 0x36fb790b, 0xa25fa0b7, 0x402fe045,
- 0xb52d97f6, 0xed1df682, 0xde308aee, 0x60d2c727, 0xb961c1de, 0x9abf09ab,
- 0x13bf919b, 0x456c13ca, 0x66b55218, 0x7149d10a, 0xc87cb057, 0x0604754f,
- 0xe37da2c7, 0x6987df31, 0xd6711d4d, 0xf8bb31fb, 0xfbc7136d, 0xb7e71263,
- 0xa63fbc48, 0x6e307b36, 0xbb6bb1e2, 0xbc22abee, 0xe38872c3, 0x7ef93ffd,
- 0x37bc4f6e, 0xc0699b4f, 0x327b33bb, 0x0267fde1, 0x5e054bcf, 0xaa1d04ab,
- 0xc4ab3e04, 0xe255afbd, 0x812adcde, 0x3bc42adf, 0x7b888fa4, 0x3d23177b,
- 0xef119520, 0xa1d6bfc0, 0x7b432641, 0x520f0f7c, 0xb75be087, 0xb2a4fc85,
- 0xbc43efc3, 0xde39135b, 0x03a00e6d, 0xdde035f1, 0xc241f983, 0x78e0eaa7,
- 0x0e9cf286, 0xef105602, 0xa739f123, 0xb6fde007, 0x87d424d8, 0xd6784c63,
- 0x1f9fc712, 0xf3e29fde, 0xf390a25b, 0x6a25fc48, 0x5d605efc, 0x8fb37bbe,
- 0x765c44ab, 0x1197b895, 0xcd7688f1, 0xbb0fc02a, 0x3f93e398, 0x2f60221f,
- 0xfd6249a5, 0xc074055f, 0x3d8527fc, 0x74c67884, 0xb75f2c67, 0x762a5a24,
- 0x04a788ab, 0x4b0fdf7e, 0x6cb4b20c, 0xf18043c6, 0x1e641a97, 0xe1fdf584,
- 0xc8ff335a, 0x7ee2256e, 0xc893cf49, 0x56df2b6f, 0x2f7fb82d, 0x74debfcf,
- 0xe69e5bae, 0xfe10f78b, 0x35da1203, 0xb872133f, 0xfa85f902, 0x8bc3d7c7,
- 0x152c1f05, 0x223f06f7, 0x2131e7f8, 0x7ceb8fcf, 0x48e7e5e3, 0xf1e64f96,
- 0x1699898e, 0x9862bf71, 0xe309e319, 0x834cf5bd, 0xc6dad17e, 0x9fdd2943,
- 0x92b63ec9, 0x650ec6dc, 0xf8afe43e, 0xf10c1f8f, 0x7dfd70fb, 0xd78a1ed1,
- 0xeb1dbfef, 0x0e83bf89, 0x711587b4, 0xd7cca4cf, 0xef51cd93, 0xeef2ad8d,
- 0xa65fa1b1, 0xbeecfeb7, 0x73f11b69, 0x1e44e5de, 0xbfe027d6, 0x8ec03663,
- 0xc157581a, 0xc81bd62f, 0xa57a8c5e, 0xebfc49c6, 0x1be7fe80, 0x17b624f8,
- 0xc754ceff, 0x5f501bb5, 0x240680bc, 0x6a2fc130, 0xcf11d906, 0xfa0f7380,
- 0xfea956b1, 0xac2f38be, 0x8fee8f8a, 0xdf2c65fb, 0x5d657087, 0xac2bf26a,
- 0x9ef47d54, 0xef59ac7b, 0x44f314ac, 0x9cb344c2, 0x4fc2f3e8, 0x39577d45,
- 0x5fb13b02, 0x9227a7c9, 0x1cde273c, 0x52a89e7d, 0xf7de20b5, 0xcb8c3551,
- 0xe3573077, 0xfd0f73f6, 0xe49f68c3, 0x3af06054, 0x7ce983f4, 0x7d7190b6,
- 0xaedc6417, 0x04f5c7d4, 0xe715bdf2, 0x3ff13703, 0xcb0807ce, 0xdefc6a17,
- 0xe42dbbe3, 0xe4225887, 0x672151ed, 0xfd7c85cb, 0x8acbe51c, 0x297b58f7,
- 0xab9085fd, 0x90872895, 0xe0cd8f1e, 0x3fb8bcf6, 0x2ccf5f4c, 0xfba08db4,
- 0x161cab22, 0x4f94179a, 0xae0721ac, 0x768f760f, 0x7647ffa3, 0x4e03b966,
- 0xfba2cfcc, 0x2cf8a5dc, 0x37cdf237, 0x9c1759ce, 0xc8161e2d, 0x2b16f74f,
- 0xea4bf72a, 0x8957c8f7, 0xf75408fb, 0xd5fd0ccd, 0xd856264f, 0x9635de29,
- 0xe4d787c7, 0x81de1366, 0x86b19d1e, 0xb4ca5a75, 0xfbeebaeb, 0xec9feac3,
- 0xef835ee5, 0x6960de85, 0x41a17641, 0xfb88d44f, 0xc8279924, 0xc5f41886,
- 0x31268bc2, 0xd4f5eff4, 0xcde8bd13, 0x2e6f5cf5, 0x4deba292, 0xf5d78edd,
- 0xd17ea466, 0x4c17c5d3, 0x54bf9d36, 0x7a465e1d, 0x3f744867, 0xcac3b242,
- 0xd7992ff7, 0x33d19b9b, 0xec95f01f, 0xed0be030, 0xf16fdd21, 0x89e328e3,
- 0xae4793d4, 0x00d7e7d3, 0x4b343bdd, 0xfa393cf3, 0x79abf3ac, 0xfd3fc85e,
- 0x794fcd08, 0x5a5347a7, 0xd92d7350, 0x69770c23, 0x1c2ef70c, 0x0bbf7d5e,
- 0x46b87be9, 0x56af9fec, 0x74bf1843, 0x197166b8, 0x0f76d5c1, 0x2fdc66d2,
- 0x3de1741e, 0xc8d6b34d, 0x247e9fb4, 0xf14e9826, 0x399fdf9f, 0x63e21b23,
- 0x9a5dac16, 0x6b38fc8e, 0x373a52dd, 0x37c1247b, 0x59806fd8, 0x79ec8796,
- 0xbcc6fefd, 0xb43ead67, 0xdbe37bc7, 0xfdd1d5bc, 0x27f8553d, 0x779853ae,
- 0x7643ae08, 0x8674c6bb, 0xfc8e0f81, 0x82eb4ec2, 0x8ed82d2a, 0x58bad570,
- 0x2555837c, 0x280fbf44, 0x0fb571d5, 0xf0ea94e9, 0x73298b5d, 0x4f7ed024,
- 0xdbc472ef, 0x3b5f456f, 0x2d3ebbee, 0x3a0245ee, 0xbbf264dd, 0x56d77df2,
- 0xb66347e1, 0x4463f25e, 0x7c97a7be, 0x62938f17, 0x7ff9e8ee, 0x6869ffb7,
- 0x315df58f, 0xe6b4bf8e, 0xe84f92f8, 0xa11f7989, 0xcf8bc450, 0x5a1b175a,
- 0x66ce4518, 0xb3c7f389, 0xce997ec4, 0xebd7858f, 0xe3e739f6, 0x5e973e48,
- 0xfaf884b8, 0xcd2a7dcb, 0xafc0656b, 0x17a5efa8, 0x507dd346, 0xe2bb9e0b,
- 0xfc0b8c71, 0xf94cbf6a, 0xc4eda725, 0xf53fedc7, 0xce8239d2, 0x9df4a9df,
- 0x5df6af88, 0xda01e74d, 0x3ad3fdc5, 0x7c9cd29e, 0xc1c6bc3d, 0xe9de50f5,
- 0x743c919f, 0xa66857f1, 0x779e7286, 0x5e5ce7fa, 0x31d9fef0, 0xdeebec38,
- 0xe0a1771c, 0x2cd7806b, 0x2169349f, 0xc2df9bd4, 0x0d8d8ae5, 0x7b1f9196,
- 0xd1f7ac6d, 0xc6bff228, 0xb5f931e1, 0xf3965bf2, 0x4caec0f7, 0xcc99c434,
- 0xc87bdf12, 0x65efcd3f, 0x4b20ee65, 0xfa127945, 0xcc0e5bb0, 0xdbb772f7,
- 0xd3d4e3cd, 0x79c6bb17, 0xd6fd6985, 0xe8abce3d, 0x53b09e79, 0x13465bf2,
- 0x5f9e3ddc, 0x9e368e8d, 0xa58c71ee, 0xd1f1edf2, 0xb450ffdb, 0xc0595adf,
- 0x8b4fa07c, 0x79bffdc4, 0xd434fba1, 0xe3ab791f, 0xb8c32413, 0x4d8a6bf2,
- 0x35794ff1, 0x5fdf74b9, 0xed5ceafe, 0x76bc835e, 0x36cd85d1, 0x4743e5d1,
- 0xd532e880, 0x40e3dfe1, 0xf0a17cb9, 0x583d4f81, 0x11d3a72f, 0x82bc382d,
- 0xae7ddbf4, 0x3ea7e768, 0x8d53a48c, 0x1fac13a0, 0xd2740cb2, 0x7ef913e9,
- 0x07d2faeb, 0x8bfdc53e, 0x45edf8a7, 0x08b1ebbd, 0xc74465fa, 0xf383a75f,
- 0x0fd82b6b, 0xdfc2f381, 0xbbf8a665, 0xe827f15e, 0x7f47e3ad, 0x51dff60e,
- 0x944efb94, 0x1f5851cd, 0xe17387e7, 0xc17dbbad, 0x8fa2e30f, 0xf3a9c527,
- 0x04167cc3, 0x71aa3e01, 0xf1f7a3fb, 0xb682c43c, 0x974f18f3, 0xf1362e9c,
- 0x01738a43, 0xff415397, 0x211e7ba3, 0xc50d6ebe, 0xbd19ed7a, 0xd9c5278f,
- 0x185c1f0b, 0xffb34364, 0x11c1f1ef, 0x29f837cd, 0xde60479c, 0xf0bd79c2,
- 0x1b86c7f9, 0x18ea97fb, 0x79c4e697, 0xf6fcfaa9, 0xbde383b7, 0x1e1d70fb,
- 0xab7b275c, 0x8e254860, 0xbf7c60c0, 0x37f4f5c8, 0x145bdfe8, 0x68f0c4ff,
- 0xcae2f476, 0xdfa0977d, 0x99b2aab5, 0xc5d85552, 0x0ce2ed0c, 0x688f5dfe,
- 0x2b5e05f7, 0xcae2ebf4, 0xb5b7ee66, 0x70db9905, 0x323b00cf, 0x8ad8fc92,
- 0x69cf6cc3, 0x7e8dc06a, 0x83dc4d73, 0x65812aa0, 0x67e85919, 0x1a0ccc4a,
- 0x938d77f0, 0x4f2cd7ef, 0xfdc6e3dd, 0x8fd42b10, 0x9a5b33fe, 0x77e4ca72,
- 0xe5995d7b, 0xd7e93a04, 0x7ab0c744, 0x1f91249f, 0x1f8454f2, 0x1fa994f2,
- 0x7da6cd89, 0x28bc488a, 0x281dfe36, 0xb3ff0985, 0x9dfe87c0, 0x3e6ea5a4,
- 0x8fc295ce, 0xaffa04fd, 0x363b022f, 0xc1f645d6, 0x7c2c0b92, 0xe853687d,
- 0x3c6b2bbe, 0xf1c5af2f, 0xff71d871, 0x59f5c643, 0xde276098, 0xd5d32610,
- 0xf1c2128b, 0xdc2123cc, 0xe0978587, 0x5c63a37a, 0xfcf803cb, 0xd7207b79,
- 0xa6ff7809, 0x0901f36f, 0x81fc33f7, 0x35cf118b, 0x03d33072, 0x772d7fe5,
- 0x74b96266, 0x8138fac8, 0x39e017a7, 0x9f618087, 0xdcd7df94, 0xe13dcb0d,
- 0x112be60b, 0x5fdf86fb, 0xc7b7cc6c, 0x1fb02af8, 0x4acbdf91, 0xfda242fc,
- 0x074cfc41, 0x34fdff9f, 0xf2772f3f, 0x07f10575, 0x6e3ed7f2, 0x3c529d3f,
- 0x87efb871, 0xb4dd79d8, 0xbcf363ef, 0x114f686e, 0xe05ad8eb, 0x4fb0c557,
- 0xb3e2a177, 0x545d3f20, 0xfd8dcf0d, 0x2727628d, 0xf2dae838, 0xdebd76a8,
- 0x83af3c3f, 0x4f4f94f8, 0x92247b22, 0xed74762f, 0x69eff027, 0x9e33a1dd,
- 0xf1c388b2, 0xfad1ff4c, 0xfdae93ee, 0x761c45aa, 0x5efca873, 0x69fe3fbe,
- 0x99c51c6e, 0xa3b8fdea, 0xda336969, 0xf53477c5, 0xbcf8899d, 0x3fe2e0a3,
- 0xed43ba63, 0xfa8b13dc, 0xce897ee2, 0xc1f9dd97, 0xa42c6aeb, 0x475fdf5b,
- 0x2f3c1ff7, 0xeb3a71e4, 0x01fe9154, 0x7ef8d6e6, 0x47df8857, 0xae02bcc5,
- 0x715fd157, 0xdb743877, 0xf3dd000d, 0x3406e87a, 0xebefa6f7, 0x43d5037c,
- 0x893ddea0, 0xf7f494f6, 0x726fbd1a, 0x35d7bf98, 0xe346c57e, 0x8daf1ee9,
- 0x0f8fafc6, 0xeff84a7a, 0xf7b88fc2, 0xf8c7c74d, 0x77dc7c99, 0x1d75dec4,
- 0xe03acb3b, 0x3fb0db0e, 0xde3e78f3, 0x7cfc489f, 0x1fa05985, 0xf6fa745f,
- 0xe33e3f20, 0xbd45edf4, 0x4ceb6257, 0xbc920657, 0xcbcf85bc, 0xc905c0e4,
- 0x0313fe30, 0x21271702, 0x9cfb9a1e, 0xc07fbd97, 0x80fbf9ce, 0x81f7f39d,
- 0x5baf9d0c, 0xecd7c89c, 0x538d2274, 0x92c77eff, 0xbb1f87ad, 0xc4fbf81d,
- 0xbb3efcdb, 0xe373d952, 0x9697e443, 0x3e2e3199, 0xfc203d32, 0x7c5d2d0c,
- 0x433bc7c8, 0xa332f2e1, 0xc1ce9621, 0x9b2f98cc, 0x319fdbee, 0x32c3c79f,
- 0xadf879a5, 0x22c275a6, 0xb3d2d711, 0x4483f41e, 0xfe7333d6, 0x6517ba04,
- 0x471ee69b, 0x9c35917e, 0xf44e66cf, 0x608e78c9, 0xf68932cc, 0xf21f47f1,
- 0x3c00b634, 0x45ef1433, 0xe0f99d31, 0xfbc20d7f, 0xb99aca51, 0x9e45347f,
- 0x4853f993, 0xf3e1ed57, 0x1073c23d, 0xc79f0e4f, 0x69cfd861, 0xdd322b53,
- 0x38f7cfc8, 0x7207a87c, 0x827df56f, 0x22fdd574, 0x0afbbcfa, 0x171801d8,
- 0x27b77b9a, 0xb724f907, 0xd4a3eede, 0xd01894c6, 0xb30ab96b, 0x31a29a61,
- 0x0c698ec5, 0xbd9a61b3, 0x354fd850, 0xe0fd9137, 0x786bf1ca, 0xd36e79bf,
- 0xfbe35ff3, 0xb7784af9, 0xdcabe064, 0xa3bfb7a6, 0x3f3e7673, 0x565efdc5,
- 0x9fd699a7, 0xf0cdeac3, 0x38668de5, 0x47866c33, 0x65c333ee, 0x67683638,
- 0xe11ef88c, 0x86569d9e, 0xde2b2bdf, 0xf438a56c, 0xa0ae7157, 0xe93b5e78,
- 0x4dc509c5, 0x712718d9, 0x05a745fc, 0xfe3b95fd, 0x59c532fa, 0x658a6e74,
- 0xfbb86718, 0x831618d3, 0xed9bbc71, 0x18bf30eb, 0xd9fe8768, 0xb5f6cde2,
- 0xedb34f18, 0x434f9d52, 0xedb50f14, 0x4bbcfc6f, 0x086b06e7, 0x6f8e2ee3,
- 0xe445fe7f, 0xfa1be3cb, 0xaaf61d93, 0x7d60b414, 0xdd3847c1, 0x3ebd08c7,
- 0xe2f5e846, 0xfc7af33a, 0xaf6e970a, 0xfce287ba, 0xe3812637, 0x2fb2b5bb,
- 0x2577c587, 0x8c6dfb74, 0x40dd67b0, 0x7687cfcf, 0xd08879d3, 0x7ba179cf,
- 0x6bd11f35, 0xb3ea0c41, 0x0cdaa38e, 0x5c5d4bf4, 0xcea3c663, 0xcc8497df,
- 0x24ba27cf, 0xcf0ce7a1, 0xc55e3033, 0xe71524b3, 0xdfa367ef, 0x8bbd7f53,
- 0xbc2f19db, 0x20f2e9a0, 0x992a7b8b, 0xb2ae70c7, 0x79b3ef5b, 0x089e31fd,
- 0xfbb035e9, 0xbb447179, 0x2eb1fd7a, 0xda5fcf2e, 0x448279f8, 0x95638781,
- 0xe86ec8fb, 0x7d2b23b2, 0x380689be, 0x727766af, 0x776fe12e, 0xf986bdf2,
- 0xdec364aa, 0x4e30bbe4, 0x8f414eae, 0xe3b92b36, 0x498f9fb9, 0x3d72e7c4,
- 0x11f313f6, 0x6ff56d8f, 0xd81cb0b8, 0x718c23d9, 0x5735f967, 0xe41a26fb,
- 0xb9f287fe, 0x3712b74e, 0x392bcbc7, 0x9cf093cd, 0xff0d7148, 0xfd71618e,
- 0x80dcb76d, 0xcfcd5ef8, 0xcc2b67d3, 0x963c832f, 0xfaedb96c, 0xfcbcf061,
- 0xec5e5199, 0x2b71540f, 0x78de2f3e, 0x3d15ce92, 0x8efee16a, 0x0504fa48,
- 0x13fa3d9f, 0x39ea0147, 0xcb75efa8, 0x9f7f7a08, 0x239bec05, 0xdcef83e3,
- 0xb38e4505, 0xa06f0ffa, 0x9f3330f8, 0x684bdf02, 0x97ae75bf, 0xe9e8ebbc,
- 0xd19becc2, 0xa02df754, 0x8fc87978, 0x0c297eba, 0xa489eb99, 0x6fc16aef,
- 0xe4621bf0, 0x7d72c893, 0xdce904a6, 0xd07cc974, 0x43ff0693, 0x8a6aa1c9,
- 0x076c8dcf, 0xc1985823, 0xe181da0e, 0x9b972875, 0xfc169c78, 0x88b65b24,
- 0x61c41f63, 0xf915c7ba, 0xf8a21811, 0x83d13652, 0x4d99bd78, 0x37d754c6,
- 0xc3f5396d, 0x52abfcb1, 0xa2bf73cb, 0xe7249cfa, 0xdd30ee6d, 0x9c4fdb6f,
- 0x70f36f47, 0x8feeff58, 0x64d45f9e, 0xe3aeb8a7, 0xbfd23427, 0x149e300b,
- 0xb768bfcb, 0x3d68c058, 0x78cfa5be, 0xab6e538c, 0x1fa5f7e7, 0x5e33efab,
- 0x1ebccb3b, 0xf9f44fa9, 0x39fe20f6, 0xbe7afd1a, 0x83ce1726, 0x771c788b,
- 0xcc8a9f4a, 0xd274288a, 0x2ad44bdf, 0xd3fd7132, 0xbbc38f79, 0xcc14f08e,
- 0x9fefc850, 0x5c9a7e4a, 0xe83a9fe1, 0x02edbff6, 0xaca139ba, 0xec25fe0f,
- 0xdfa1d793, 0xfbd90bf3, 0xf7507b80, 0xacacfd3e, 0xa3df9d00, 0xfb40f40f,
- 0x56161533, 0xe266df80, 0x609c353c, 0xae674f9a, 0x719e2896, 0x78f372d6,
- 0xe36ebef0, 0xaac05afc, 0x5622dea9, 0x6ac1694f, 0xce217e73, 0x273c2e47,
- 0x8a76e3c7, 0xfaf9cd6a, 0x8d92c0b9, 0xf0d1ac67, 0xc7d335f6, 0xc702fbe7,
- 0xa36cdd27, 0x2ab7ddfe, 0x6977ef8e, 0x6df387cc, 0xe9272ae7, 0xa01662ff,
- 0xe629dc7e, 0x7307f2fd, 0xed20b37d, 0x37d33f98, 0xcb9e0fab, 0x2d23f3e7,
- 0xf99e4919, 0x13c57ebd, 0xbf007859, 0xbce187cf, 0x8524dc5b, 0x036c2187,
- 0x9fc11d51, 0x3826bde3, 0x3679e37e, 0x6e38fc7d, 0x3ef673e3, 0x9e116fa7,
- 0xb8f9929b, 0x0225f98d, 0xad1b251f, 0x98d17f26, 0x79d0528d, 0x6aaf9e39,
- 0x1acaf7a1, 0xf54d58ce, 0xec1d798a, 0xba076601, 0x2b58298d, 0x755660e3,
- 0x25d0f1e9, 0x1ccbced1, 0x755c7810, 0x945f5e5b, 0xbed1c7db, 0x9d1027ed,
- 0xf84a7a43, 0x06d858a3, 0xec8cc5ed, 0x7b3f2982, 0xe2938721, 0x26a6bd1e,
- 0x4a2fbe8d, 0x653361fb, 0x0e789bff, 0xd03e32b3, 0x99da0e37, 0x2ba5f169,
- 0xc1bebf24, 0xcf9d6fe4, 0x88e4f0f1, 0xa22a4b8a, 0x3a75b7ac, 0x53d5213f,
- 0x3b70409c, 0x599da79f, 0x20c06a9d, 0xb8e32317, 0xd3db8cbe, 0x3a8fe742,
- 0xfe744ab7, 0x20e929f9, 0xea7e0f9d, 0xff430f5a, 0x09d02a40, 0x1253eff5,
- 0xfcf7845b, 0x34dc3565, 0x73a40de7, 0xe3178c56, 0xc61b4a0f, 0x1a0ea5c9,
- 0x62e3b73f, 0xbee2d62b, 0x218cca54, 0x61df9023, 0x866e33dc, 0x3ce3a3e7,
- 0x075f5ed4, 0xc2ea7ba7, 0xa1dcc660, 0xce7fbed8, 0xc38f281b, 0x7cbce862,
- 0x99cae00a, 0xb432e940, 0xe65952cf, 0x5333b46e, 0xa04678a7, 0x8b957f4f,
- 0x916493b7, 0xf684dc67, 0x270e08e3, 0xd6f92c3c, 0xa0ae1311, 0xfcac5276,
- 0x1cf87a93, 0xfa1b4ded, 0x7a061c27, 0xc4c8a84f, 0xf10653f6, 0xa70b5134,
- 0xbbfb3d61, 0x75a01ee8, 0x23373cc8, 0xbbef3d7d, 0x2eb82971, 0x0b06dfdc,
- 0xfb63d075, 0x97fdf4d3, 0xfbec83b0, 0xf2f0870b, 0x97994ec2, 0x24e7cfc9,
- 0x15f6eba6, 0xfaa1d72f, 0x5ea246e2, 0xf9db8f7d, 0xe47c395f, 0xeb42bf07,
- 0xa0803ce5, 0x58e9f953, 0x0bcc3216, 0x21bed3e5, 0xb4fcb3fb, 0xef1cf4cb,
- 0x95c63509, 0xa1ec1497, 0xb2943bef, 0x509f3a66, 0x838e6f5a, 0x7a2622bf,
- 0x979f3abb, 0x3059969f, 0xf99abb6a, 0x2c3ee9f9, 0xb95a27d8, 0xd3f3f364,
- 0xfc6e1992, 0xe8539456, 0x7169cb39, 0x0a71fae1, 0x67a847ce, 0x7aa09642,
- 0xda5d3779, 0x79a62ddd, 0xe1c3dda8, 0xa8bfb10e, 0xb7f5ebe7, 0x39c4d34f,
- 0x7bcf7e3d, 0x2028255b, 0x4dd3cfc0, 0x5ddfc927, 0xf09bb4d2, 0x3745f3a3,
- 0xd059629e, 0xaae4a780, 0x6405b0e6, 0xfdb8e9fc, 0x025e874b, 0xcba3d924,
- 0x7d4b3bf3, 0xbf1f2163, 0xef90616b, 0x792eacd8, 0xcab37527, 0xf0fd0b22,
- 0x6389d2ee, 0xdf2f308d, 0x35f37efd, 0xb2b78113, 0x6bf7f286, 0x6b7bdee3,
- 0x7506c621, 0x4ce83b9d, 0xb00d3bf7, 0x0076022d, 0xbb00cc3c, 0x2313f223,
- 0xe02353f2, 0xcdbe5e34, 0xbd974e19, 0xfb8e6d8c, 0xf4051ae0, 0xf0df5b5c,
- 0x6479bc74, 0xd747d579, 0x4b8ef7e0, 0x7bf7f8b3, 0xaf249acb, 0x65a3d064,
- 0xe4871e5e, 0x3368b6f0, 0x9a1e2287, 0x507d44df, 0x71b928d2, 0xdfa8e0fd,
- 0xdf182612, 0xabde18f3, 0x92d3ebe7, 0x5ef483fa, 0xb10ff5af, 0x3a3f3c90,
- 0x772a73e4, 0x362dfdae, 0xaf3dfcc5, 0x52bbf6de, 0x50b7812d, 0xc7f7eadf,
- 0xa8f96db7, 0x20aa7bfb, 0x7d7ded7f, 0x469f497b, 0xc72f5b9c, 0xe5ba38fe,
- 0xa3e3c745, 0x7dd14e43, 0xd6187fba, 0x079a01f4, 0x2e4ef3b1, 0xff75abc0,
- 0x14787a54, 0x27785fda, 0x4f1fce2f, 0x704ba148, 0x059a7a5e, 0xef76c12e,
- 0x3768bd29, 0x80ec6a7e, 0x5e0cf2da, 0xdc4df309, 0x01ffc249, 0xfc00cb67,
- 0xc7e9dd64, 0xa4e1c2ff, 0xe609ba16, 0xafefeab6, 0x1ecdefc1, 0xc032d018,
- 0x8ff7f002, 0xe0993a5f, 0x419e5a8b, 0x04eac2f8, 0x196b0f0e, 0x03fbc320,
- 0x23267d83, 0xa3bbd6fd, 0xa109fdcb, 0xc5fef46f, 0x891df60e, 0x84aafb43,
- 0x2c783bcf, 0x757a06da, 0x4db1d17a, 0xd31f01eb, 0xf49623ff, 0x5bb6fadd,
- 0x1e13f3ae, 0x6f8c7e82, 0xa6f8114c, 0xbbf49179, 0x5f44f642, 0xba130b9c,
- 0x6f4ce9e9, 0x71bcd0f6, 0xb416c569, 0x0fa6521f, 0x55e379a5, 0xee27ef97,
- 0xe9e9dd51, 0xc4fe9e24, 0x5bfae6ed, 0x46bc50b6, 0xb24e43ca, 0xdf171eab,
- 0x23b90067, 0xba0870fe, 0x3c7cdc58, 0x73190dff, 0x80001bd1, 0x00008000,
- 0x00088b1f, 0x00000000, 0x7dddff00, 0xc594780d, 0xbbbcf0b5, 0x26effeef,
- 0xb24d9bbb, 0xf379f909, 0x71100843, 0xa9189313, 0x18884dd6, 0x220bb531,
- 0x49716b62, 0xc93049f8, 0x2d16ad46, 0x544859bd, 0x46d10882, 0xe1b80a04,
- 0xfd2b6202, 0x1a8c4582, 0xf68882e8, 0x72dfbd2b, 0xbd3fadeb, 0x8a7e1bd7,
- 0xb4564288, 0xeb6dea5c, 0x2666739d, 0x5c9377d9, 0x9f7b7aa8, 0xbe8f8be7,
- 0xcef33bce, 0xfe73399c, 0xb3339ce6, 0x9086bb1a, 0x258e4264, 0x4ec730dc,
- 0xe631df9f, 0x224c9d15, 0xf433bba4, 0xc84b499c, 0xc421127b, 0x09f04845,
- 0x0e7b6853, 0xd1eddf21, 0xb4897504, 0x734de1de, 0x44b2d116, 0xc345bd7c,
- 0xd57fbde5, 0xd2b3e5de, 0xd32d3172, 0x9912abe7, 0xbd33f58b, 0xfe5a0e69,
- 0xa7aefe02, 0x9f561ee5, 0x58ad25ae, 0x7fbec39f, 0xe5dc84aa, 0x76d4cfa3,
- 0x7d296e3a, 0xb5b89dae, 0x916b8e9d, 0x0bca1789, 0x5d6c16e7, 0x736a614e,
- 0x897842cc, 0x51269bd7, 0xe6364ef8, 0x76d1566a, 0xc8afa7bf, 0x515c8435,
- 0x97b0cde0, 0xff40f9d1, 0x44d21c74, 0x3c369527, 0x37981cfe, 0x7ad7afad,
- 0xcf3a64b3, 0x39fe1ddb, 0xe35ebed0, 0xd0b4429d, 0x77c0b789, 0x8823b405,
- 0x3b76399f, 0x40f227b6, 0xffffbc19, 0xb8954f08, 0x4f115fee, 0x7534ef77,
- 0xf8242c9d, 0xb7fd05f7, 0x2aa1d7b9, 0xbad2fa07, 0xcb871a4e, 0xd0ffc377,
- 0x24ad4871, 0x2c3a1493, 0x8d6e22ab, 0xbfe836ff, 0x7a07e979, 0x513781a2,
- 0xf02ff43d, 0xeb0a4ebe, 0x82fce952, 0x76cf24fb, 0xb2cfdec2, 0xe8959211,
- 0x21e613bf, 0xc3f79ee0, 0xd17f34e6, 0x3f2c7cf0, 0x76e6a978, 0xe4b79c5a,
- 0xf4edaecc, 0x590f79fb, 0xdb865108, 0x9d711ed3, 0xb8cf7fdf, 0x9f495c9a,
- 0x86b0defa, 0x19fdebe2, 0xb69cb3c4, 0x1a435f7b, 0x73efff00, 0x743f95bc,
- 0x853211f7, 0xb5d95f90, 0xd0499df8, 0xbddbe483, 0x53b7e288, 0xd0234122,
- 0xd23d4cc3, 0xd28860c3, 0xfeb095c3, 0xfbe87d74, 0x872707ee, 0x067d7482,
- 0x619100c9, 0xbec4153e, 0xbfa9895d, 0x29eb00a3, 0xb44d049d, 0x0e68da3e,
- 0x5e80956d, 0x50a5a028, 0x5feb093f, 0x07fad895, 0x38e230ef, 0x1d1933dd,
- 0x433a3776, 0xb6001cc1, 0xc6de008b, 0x7694a3a2, 0x64487482, 0xb69994ef,
- 0xe36c7c61, 0x3a52c172, 0xb4dbe2f0, 0xe4dab23f, 0xb01f4f19, 0xbb943284,
- 0x4a3c7152, 0xbe91ab0f, 0xfd470664, 0xab42d38f, 0x394f5c70, 0x36a3cbac,
- 0x1f787cef, 0x014591fd, 0xc89937f8, 0x7d09634a, 0xe8c3a44a, 0xe1c0eba4,
- 0x134f5d21, 0x60bb83a0, 0x7f878a00, 0x536f386f, 0xd89ffbe8, 0x08038425,
- 0x484e58cd, 0x75f5611d, 0xa4c72ccb, 0x86d4f029, 0xddf4090d, 0x03bc1bca,
- 0xd972be82, 0xf3fb48d3, 0xeb22ba73, 0x83c036a3, 0x804bbe1f, 0x29b73ffe,
- 0xefd32856, 0xd3f2c0a7, 0xbf870bef, 0x7df039ff, 0xe0c7c019, 0x65166d27,
- 0x1f8c34bb, 0x80b9fcf1, 0x6f69ebaf, 0x9c6278ec, 0xd98f7ef8, 0xf007ffbd,
- 0x4e1ef145, 0xb45e0174, 0xf0f1aeb8, 0xc7d1f4ba, 0x5e7eb44d, 0x82b1d69b,
- 0xd4bfd3e2, 0xf015f386, 0xbd1a95de, 0xec8de48e, 0xa5a594ff, 0x2ff9865c,
- 0x964f7465, 0x62e22819, 0x2e1fa2f1, 0x485dd253, 0xd23587a2, 0xf0e5ef28,
- 0x517f8001, 0xf8f7cc77, 0x621abfdf, 0x21be09db, 0x3f07148a, 0x92452ba7,
- 0x12fcdd61, 0x3ebd375b, 0x56e40f3a, 0x9f02dc3c, 0x8de5c6ff, 0x7c788ba0,
- 0xbbe01bff, 0x5dbe246c, 0xe84c81fa, 0x80d4bfd7, 0x9fef8a78, 0xf77e1090,
- 0x4d0489b4, 0x4bd6ee94, 0xfaebd212, 0x90212d07, 0xe8a6839b, 0x6067c00e,
- 0xdeb88dff, 0x0acd1ae7, 0xea364da1, 0xf705bf19, 0x171f18db, 0xdc80140c,
- 0xece7473b, 0xee73eba5, 0xa09eda37, 0xa4208024, 0xadda37e5, 0x5ee7ff40,
- 0xb3f589be, 0x5a10a2dc, 0xe986000e, 0x7fe081b8, 0x578a11b6, 0xc7119669,
- 0x0a57b13f, 0x8fbea019, 0x5e4639e2, 0x36ffa39e, 0x8dcb0c94, 0x3800a841,
- 0x07082cfa, 0x8e23699d, 0x59335df7, 0xd16fc745, 0xad0d5e48, 0x2932596f,
- 0x31e0ced4, 0x16d5cac6, 0x4a90e90d, 0x45bff986, 0xdee0bc73, 0xa7275622,
- 0x60ac7970, 0x851243bb, 0x3ab8c9b3, 0x05fa05a2, 0x4bf5a03e, 0x78673ea0,
- 0x7f565a1d, 0x479817f4, 0x7d351ecb, 0x9eaf3d34, 0xba5892c7, 0x17a619ca,
- 0x17c3294b, 0xf1a126a9, 0x2f1b5e14, 0x21226a5b, 0xe963e02d, 0x2ae27234,
- 0xc0e0f4da, 0x5b23a074, 0xa3a92f69, 0xe269c0cf, 0xa7b8510d, 0x36bcf7f6,
- 0xd477b68e, 0xba613244, 0xcdbfa581, 0xf0d5793b, 0xaf380b3a, 0x4b427fe9,
- 0x7e1e38ac, 0xeef14147, 0x89bb62b6, 0x7d88aeb3, 0x92efc0ae, 0x0f2f4c35,
- 0x1fe02bc0, 0x75cde999, 0xfd526f5c, 0x617af28a, 0xafd404d7, 0xce40ffa0,
- 0xf4c0953d, 0x903dc831, 0xaa8e6d33, 0x9e741cab, 0x14d56766, 0xc71b1947,
- 0x27e98367, 0xa788fea1, 0x243d78eb, 0xb5e6a5da, 0xc75ab716, 0x0cf9476e,
- 0x90dd16f1, 0x2c88e4c8, 0xafd17961, 0x10ab3d75, 0xe6e9193e, 0x2839cdde,
- 0x97481b97, 0x89bce81e, 0xc740f484, 0x98248c8b, 0x1162e940, 0x9f48966d,
- 0x881bd78b, 0x8d7eb312, 0x89b97521, 0x49bb85cb, 0x7bbfbf04, 0x357d5c67,
- 0x7d68db09, 0x2d8491b3, 0xd755ecf0, 0x8e7d50b7, 0x85f7d67c, 0xe93df621,
- 0x8bbdf366, 0x3aa3bbaf, 0x79d3f5a4, 0xdd51306f, 0x5d0684ea, 0x97533eb8,
- 0x267ae0f5, 0x1e737896, 0x2bf2bd06, 0xa52b679d, 0xf5f03fdb, 0x6639f812,
- 0xbc00aaaf, 0x9c1ab59b, 0x0361f47f, 0xd524e7e2, 0x6bfeb0e3, 0x59aee41d,
- 0x8dae79f4, 0x8075f378, 0x2cd67b26, 0xaf3c48db, 0x00d4c57a, 0xd0e0d374,
- 0xd32ae8a8, 0xf972c3a1, 0xe5ff8e0a, 0x1cd6d096, 0xa014f744, 0xa15cf2a7,
- 0x9994c957, 0x474c7cb4, 0x6e5a3bed, 0x43f56399, 0x4f60037f, 0x0efdf2d0,
- 0x77eecf26, 0x453d71e8, 0xd057cc59, 0xfb071d0d, 0x9ec55f33, 0x43658e02,
- 0x74609fed, 0xbaf0f5c3, 0xea0f7346, 0xd5fa21e1, 0x22dfa410, 0xfaf01e9f,
- 0xf32b970a, 0xf8a16ec1, 0x1412857e, 0x2f608fc8, 0x3e295fb3, 0xe5a52de6,
- 0x79174e57, 0x67402956, 0xf2bcde4c, 0x4159331d, 0xccf37c87, 0x27fb1f4f,
- 0xb4fe7f5a, 0xfad0315e, 0x746b4005, 0x88915efd, 0xbe0bc617, 0xbe810868,
- 0x7b33d26c, 0x15ff69b4, 0xfbd19ecc, 0x71842c37, 0xc079d05e, 0x084a69de,
- 0xeb03b73d, 0xa2943cd3, 0x863aabc9, 0x16cbe0cf, 0xf439bdf6, 0xa0bb9fb3,
- 0xa413d53e, 0xff26a3ed, 0x74d75846, 0x7a889283, 0xc25ad7f9, 0x381709c6,
- 0x878f5e28, 0x9c7ddd98, 0x4e304956, 0xa1fb0dbf, 0x90b69a7c, 0x33a273f6,
- 0xe543e715, 0x2759da2f, 0x82b618d6, 0x34375dfc, 0x8fed84ae, 0xd3d37ceb,
- 0x8bf8f968, 0xb4e59ec5, 0x0fa7d06a, 0x073d29eb, 0xafbb32d6, 0x016ca35e,
- 0x16fd90fc, 0x8f58879c, 0xb5c59ac0, 0xb2581f50, 0x8f9016ec, 0xc839f163,
- 0x3723127b, 0x166891cf, 0x86c6d3f0, 0xe830dedc, 0x1e89fe95, 0x4dc4af54,
- 0x8dd29f17, 0xa93db59d, 0xee8df863, 0x5f3d21d3, 0x1740ff6e, 0x43d33972,
- 0xca804e30, 0x0ff82265, 0x594c72e5, 0xad995a3b, 0x5495e063, 0xeba9df6e,
- 0x47fc1253, 0x9e5a5d60, 0x97f78ffc, 0x145e302a, 0x4ae922e5, 0xa93cbe46,
- 0xba03cef3, 0xf5875475, 0xfd7a3175, 0x99d983a4, 0x076e06f5, 0x963eb092,
- 0x797d450f, 0xc5ee9a95, 0x7fa704f3, 0xf7c9845b, 0xce1af591, 0x401ab71f,
- 0x20654d8f, 0x23d06c93, 0xc15fe856, 0x0e9ea7fe, 0x3969ebeb, 0xbf58597b,
- 0x4f813f88, 0x46c3be28, 0x1b93ef3a, 0x29bf8c6c, 0x459fa01a, 0xe5f50415,
- 0x63b52d22, 0xd2bde04b, 0xe5d74037, 0xa40e8bd4, 0x8a67f22f, 0xf9ef8a15,
- 0x5033b784, 0xb1ca97bb, 0x30a43a97, 0xafe60bec, 0xe5356c37, 0xb57b5f00,
- 0xcdcf5836, 0xf9b1ca12, 0x1b05951d, 0x9ec97968, 0x13fd702b, 0x2e5d182a,
- 0x2f503909, 0xb1f2e54e, 0xa3d210de, 0x8933fe1d, 0xf6883ec0, 0x1374f68f,
- 0x64ad28fd, 0xae401e24, 0x1421e8ab, 0xd1f6a653, 0x57265ed4, 0x24e79509,
- 0xf2126ec6, 0x8938e41e, 0xf4d503b3, 0x88fa1411, 0xa4a23dc9, 0x7213dc82,
- 0x97dd98f9, 0x3e3b44e8, 0x97d6153f, 0x9b9327ae, 0x6bc425bb, 0x7d456933,
- 0xd0c0f422, 0x9c8f5cb8, 0xbe9906d2, 0xcf813c32, 0xae0e677c, 0x8bd212eb,
- 0x95e844fa, 0xdf20e8b1, 0x88fbe1a9, 0xbc60e9d1, 0x9afec153, 0x75f0934e,
- 0x65a6bc74, 0x853cdc24, 0x50536d3d, 0x693d323f, 0x9e127a64, 0x97d0cbe6,
- 0x5e31faf1, 0xc1ebc61f, 0x77d33d54, 0x3d859d62, 0xd98d3a93, 0x85975301,
- 0xfc08a4b4, 0x94eade35, 0x26bb61e4, 0xa8d18ef0, 0x1f65095c, 0x9ef905c9,
- 0x2a62f950, 0xc4c80fad, 0xa1657c0b, 0xefa1e978, 0xb7fb7337, 0xd7cd9527,
- 0xabf467ad, 0xd8a47d93, 0xc112eb0a, 0x99346f7d, 0x051e81d8, 0xe8db373e,
- 0x1df02577, 0xefa1b7e3, 0x1cc3a48d, 0x2bd57df3, 0x173fd426, 0x0c85b65e,
- 0xb3f88f68, 0x94bfb41d, 0x4ed01bdf, 0x0d8af73d, 0xae39e9f5, 0xefc25d0f,
- 0x7e611e40, 0x41aebe16, 0x008e3552, 0xc6334bed, 0xf6140881, 0xd983b359,
- 0x21ed2359, 0x99139f5e, 0x80cae8c3, 0x8e0bcdfb, 0x4ca00781, 0x7fa021e1,
- 0x7e32716e, 0x5699ec0f, 0x3efa43fc, 0x187ab3e0, 0x40c5fdf6, 0xf7ed06af,
- 0x7d2918e7, 0x8b2ed74d, 0xd1e7483e, 0x83b5699c, 0xfeceab7e, 0x41dddfd7,
- 0xd1ee1fcb, 0xf3ac0311, 0x497369f6, 0xb7f2d8ee, 0x3e3ba431, 0x772fc310,
- 0x9b9754ef, 0x40e5d57b, 0xbf7cba9f, 0x653ae6d3, 0xf9e1d941, 0xc1b5d282,
- 0x87ba7ad0, 0xd5786bc2, 0x8668fa80, 0x1390ffd3, 0x7a26ade4, 0xc86cf018,
- 0xf80a78fe, 0x9ffd023b, 0x5034f048, 0x31148a36, 0x5f5f03fc, 0xb6cfcd30,
- 0x61b7828f, 0x06a311fc, 0x75ad4cf1, 0x173944f6, 0xd2e27ce0, 0x403c3f7b,
- 0x9668bfe7, 0xdf02bed9, 0xcacb6b78, 0x18449ec1, 0x4dfd6049, 0x8bbec21f,
- 0xf5846bb6, 0xb693353f, 0xac3570a3, 0x89b0fa67, 0x6f801244, 0x69dda85b,
- 0x1bfc4ba4, 0x77776fce, 0xf4c3cb44, 0x359dbb7f, 0xf94e0113, 0xe80fb22f,
- 0x37e851e3, 0xeade4ec6, 0x4bfc7264, 0x463299fb, 0x02b699f8, 0x038d9afe,
- 0xfe3a4afa, 0x0cf97ff5, 0xa5e2fde5, 0x823ee1af, 0xb33e63ce, 0xc80a4dab,
- 0x1e0fc5a7, 0xdf62f7c0, 0x8ad32a76, 0x36d7b6fb, 0xa1d95818, 0xcda9f2c7,
- 0xb8b95f6c, 0x3cc10a57, 0x931759a5, 0x6c2f412a, 0x640dd9d6, 0xf1e35e24,
- 0xb7a6c1f8, 0xf5efc013, 0xf61d2201, 0xc7b3127b, 0xb809adec, 0x135a507f,
- 0xac0cbec0, 0x9043f1bf, 0x6b378b8f, 0x902f603d, 0xcff4367d, 0xc37cde2c,
- 0xe85685c4, 0x4aa4d3e7, 0xb96d13f0, 0xd0543c01, 0x7e6217ce, 0xf4f5c89e,
- 0x6ae5bcbd, 0xd0f1f805, 0x62ff0666, 0xd0077187, 0xd17ff5d1, 0x1ac97f22,
- 0xb93b07e2, 0x089def5b, 0xda6cad7c, 0xe7d61d3e, 0x1ae99983, 0x224bbf6c,
- 0x638bc076, 0x5fbc0a69, 0xe03ec92c, 0x8df586e3, 0x4f76b1b5, 0xc7f9939d,
- 0xa597b32a, 0xaf91580c, 0x6d3e80e6, 0x08f94cde, 0xdef59fc6, 0x0d70eeef,
- 0x6b3495f3, 0xa1532dfd, 0x1e7567ff, 0x7b21bbe0, 0x90b7d366, 0x4c2fe0be,
- 0xe398b5f1, 0x99f2abeb, 0xa4f822c1, 0xeae400b5, 0x05ad15e2, 0x8cec51f6,
- 0x44d93e21, 0x213272f9, 0xf9129da7, 0x1993fc02, 0x63bed54e, 0xb59a7dac,
- 0xc67a8350, 0xedde21e8, 0xb74a99f4, 0xb71fb0c9, 0x6f58c925, 0x7d23d24b,
- 0x77ba7fcb, 0xbce86fe7, 0x2ffa749e, 0x26ccbe80, 0x6bd062de, 0x455ed44a,
- 0x35405acd, 0x136461da, 0xcc89afb3, 0x92eb85fc, 0x31558ec9, 0x125373fb,
- 0x39504fdb, 0x73f405f1, 0x1f3fddee, 0x64b6fc06, 0xec053c7d, 0xcfc5c085,
- 0xb35fe0f4, 0xdf284bf6, 0x011f1ead, 0xcff409ba, 0x868a0b24, 0xc3c072e5,
- 0xbcfc46f4, 0x98e924e6, 0xb145751c, 0x82974a9f, 0x41076ee5, 0xd4b8da7a,
- 0x46fef68c, 0x4004c857, 0x2b7cadff, 0xee46a7ec, 0xfb6e340f, 0x740b5785,
- 0xe3ec921e, 0xfe30aca1, 0x17986c18, 0x3e71d2d2, 0xc41796dc, 0x8f4a9ef2,
- 0xb759d696, 0x5ccae3fd, 0xce9f53c0, 0x9eaded03, 0xdf980481, 0x244edb87,
- 0xb61afcc0, 0x0dde7169, 0x16524fa1, 0x09cb0d16, 0x905fc69d, 0x5d827604,
- 0x42f8c2b2, 0xedb87c5e, 0x560594d3, 0x7d403fe6, 0x5e3a3a5a, 0xc9cacecc,
- 0xdff5fdf0, 0x6672eb64, 0x72042197, 0xf9898cf0, 0x33bb45f7, 0xaeffa636,
- 0xcdfe124b, 0x3fd02cde, 0xa2796543, 0xf7c4e406, 0x2efe6ced, 0xf0166f7d,
- 0xba9247e5, 0xb52b259f, 0x52e54424, 0x84894ae3, 0xf33fcca8, 0x20594bdc,
- 0xfedc3fff, 0x0c5d5652, 0x89dff17c, 0x6a498de7, 0xaff09a7f, 0x0ce1f4ba,
- 0x63ceaf18, 0x31cc7e60, 0x3da2abfc, 0xa4fccf59, 0x816b9483, 0x8377c50e,
- 0xd82f660d, 0x18c483bb, 0x5d5b9702, 0x7ad7f73f, 0xd82ef9bd, 0xe3ef88d7,
- 0xf40d5ffa, 0xfa92e144, 0x5827f424, 0x9f28a28a, 0x77fcb4bf, 0x918cf5d1,
- 0x8d9d74ff, 0xc6cd4eb0, 0x0471e1e8, 0x780f43e9, 0x6558b7d3, 0xed2957d0,
- 0xf7a2be8c, 0xe59f706b, 0x814c2732, 0xdd3e80b8, 0x76f9056d, 0x43b9817d,
- 0xb3ef0893, 0x333ed042, 0x0bbf10bd, 0x0ffa3156, 0xc3f410a6, 0x095691a5,
- 0xe676b4fd, 0x20a8cfe7, 0xf8b455f6, 0xe76624b3, 0xbd6789b8, 0x5fd70f36,
- 0xc70738c2, 0x400fd08b, 0xcf2f2047, 0x23a44648, 0x7b425fa9, 0x9de9ab54,
- 0x458efd07, 0xbac52b57, 0x2a1aba72, 0xeae89dff, 0x23c74149, 0x20afcae8,
- 0xa38db95d, 0x23f715d3, 0x127b765f, 0x36bec1f4, 0x2d6be395, 0xfbd13f97,
- 0x2eafc28d, 0x796b7cc1, 0x6b46b57f, 0xc47a0b58, 0xd638fba3, 0xda89bc3f,
- 0x4a7fb0c5, 0x3e9ebb03, 0x57cfb5c7, 0x6448dd70, 0x9608fc00, 0x2fa88dab,
- 0x7244d31f, 0x9d498ec0, 0xe81bbad4, 0x515e7523, 0x0bee3b49, 0x17a01c33,
- 0x7fa2d740, 0x1f34e974, 0x1c5823b3, 0x8f533a28, 0x07969cfb, 0x8ecc7d2b,
- 0x097e41a8, 0xa02936ac, 0xe7f5a707, 0x08fa072c, 0x031e232c, 0x86cf71d2,
- 0x9dcfe045, 0xac80f56d, 0xb225f113, 0x9d77cd52, 0x05538b12, 0x0f18226f,
- 0x0d338e1b, 0xe821f96c, 0xf422c6ff, 0x8ff90c9b, 0x8dea09f3, 0xd6438dcb,
- 0xde2136ad, 0xd068fc45, 0x25741146, 0x3fb191fa, 0x7a646892, 0x407ca468,
- 0x054a73ff, 0xa1eb7f11, 0x3cca2e9c, 0x5ff823de, 0x456ca3c4, 0xc8b01cbe,
- 0xbf399c2b, 0x049c4332, 0xb36c77fc, 0x00fd8416, 0x19598dfa, 0x694fcadd,
- 0x50e92028, 0xaaab9ffb, 0xbcca6233, 0xc1f7d0fd, 0x5f573755, 0xa877fa8b,
- 0x7aa6c01e, 0x26bd9459, 0xc355e205, 0x83b532f5, 0xff127d8d, 0x1be6e2be,
- 0x941eaaa8, 0xee7ff8c4, 0xd11f82f4, 0xc5e35444, 0xf5c727c2, 0x5bfda3af,
- 0x383ede15, 0xefe826ee, 0x7e5112a9, 0xe14bd3a0, 0xf753ab5b, 0xdfe52887,
- 0xf78c4143, 0xaf0e537f, 0x6c319d5a, 0xe17b501f, 0xc36549cf, 0xefa3c276,
- 0x495d76d5, 0x3fd8b2c7, 0x15fe83d5, 0x92e03efa, 0xe7890ed0, 0xf49704d7,
- 0x656becd5, 0xe09d7d84, 0x74f5f662, 0x2fba4960, 0x581df941, 0xdf6023e6,
- 0xe9c4bb52, 0xe3e4bb42, 0xfd680753, 0x1f9f59b9, 0xbb40a71e, 0xbec1e67b,
- 0x4651702a, 0xa9d81bf9, 0x6f94490d, 0xaeccfd8c, 0xe31cfaa6, 0x967e8205,
- 0x38fd39d8, 0x97fc0482, 0x32a4fbdd, 0x5a4277a0, 0x6ba36eb3, 0x379703f9,
- 0xfbe1c713, 0x9779f8cd, 0x205f98bb, 0xa1b55850, 0x26dffa00, 0x5617b011,
- 0x594f1e15, 0x63a9fb80, 0xbe630b29, 0x0a7bec6b, 0x53b8d9f1, 0xcb1e2a37,
- 0x7804e1a9, 0x45f9796c, 0x338dc82f, 0x42650921, 0x04ea1c83, 0x41a1b6bb,
- 0x29211603, 0x03bfcd0d, 0xf5731fe3, 0x5f9d3c64, 0x8177d706, 0xa706b79d,
- 0xbfe9bcc2, 0xd1b57d12, 0xc4e508b7, 0x2b46b9c6, 0xeb0a91c6, 0xd83c41ee,
- 0xc3c05ecd, 0x34aac2aa, 0xe665a718, 0x4dc63b74, 0xf5073da8, 0x077e0f2d,
- 0xae0245fd, 0x1aba7d55, 0xa9ca77b0, 0x0a0bf75d, 0x4673a677, 0xf5f2878d,
- 0xe2eeed38, 0x5710acfb, 0xff8e5d1f, 0x174664bf, 0xf82f921d, 0x8ff452ed,
- 0x677f5892, 0x1fb31f76, 0x55e9716f, 0x5c5bf1fe, 0x36bdaecc, 0xe4069918,
- 0xb01e5fb2, 0x201d5d80, 0x5f604fde, 0x65567c4d, 0x9313ae3b, 0x0536ae5f,
- 0xd74666fd, 0x425763c0, 0xee32b5fd, 0xf03c8867, 0x5cf71863, 0x8ab3cba7,
- 0xf2803e70, 0x90214583, 0xfe5cfbc7, 0x96fac2ef, 0xdcf57b73, 0x831637cb,
- 0x5fd8517f, 0x5099cf9d, 0x94da766f, 0x4e406b27, 0x796649fe, 0x6468c603,
- 0xc967ed1a, 0xb71c4ee7, 0x84ea14d3, 0x68f60ff5, 0xeac9beb1, 0xdbf4045f,
- 0x29faeb78, 0x0d608798, 0xd51e8015, 0xd008bab9, 0xa0bedd31, 0xf2e8c51f,
- 0x4f238811, 0x2597ce0b, 0x767117d0, 0x63f034cd, 0x85c5bee1, 0xce2adc7e,
- 0x1529e31f, 0x2b22329c, 0x34917c74, 0xf9bce76c, 0xbc32d9e7, 0xc68ff614,
- 0xd5eefcc8, 0xec04cd73, 0xf448f25c, 0xf8fc06b0, 0x7b0108ae, 0xc257b9b8,
- 0x5f0b9a71, 0xe5fec3d0, 0xdfc65eee, 0xa0dfbe01, 0x78c2cbf8, 0xedc2cb94,
- 0x67460e81, 0x1c787224, 0xb679f9e0, 0x76d0849e, 0x42577e31, 0xc0793396,
- 0xf8f3d3fb, 0x37f73343, 0xf5884d51, 0xcec25cab, 0x5b8ea158, 0x49d771f0,
- 0xf016af11, 0xfca92c5a, 0xc3d9e2e4, 0x183c4fbf, 0x1bfc0e9d, 0x7e05f4a5,
- 0xccd20da7, 0xf3a75e7b, 0xc93650db, 0x9b98a603, 0x04b69392, 0xa45253de,
- 0xfbed2f78, 0x0dd03a64, 0xafc821a9, 0xda957d2d, 0xeb8b2b66, 0xa58c5e60,
- 0x53ea07b5, 0xfd442aef, 0x5993710c, 0x1cb3fdf4, 0xe65669af, 0x08af73c7,
- 0x341c40e6, 0x9eefa0f1, 0x2bfc61d7, 0x4d87e8cc, 0x73636ba5, 0xf82573e2,
- 0xf8a4dcbd, 0x7767e800, 0xf00252ad, 0xc41f7888, 0x0d16670b, 0x3d38e3e7,
- 0x7d2b7792, 0x983976ee, 0x6a40cedf, 0x1f785e00, 0x1fc70eb2, 0xe3079fc1,
- 0x9e0f7c42, 0x32c2d2e7, 0xc0c9fffa, 0xefb8ed96, 0x483e6037, 0xef1bdf6d,
- 0x35adfe80, 0xc78c5e92, 0xd52dd9c6, 0x02beb789, 0xf6783ff4, 0x018796d4,
- 0x7af6dbae, 0xce25ef30, 0x9bfeb91e, 0xb33f3ecc, 0x3f00a2dd, 0x9b72e56c,
- 0x27c88fda, 0x3f6c5dc1, 0x1e476f19, 0x27f7a975, 0xddafe543, 0x05f0648e,
- 0x0b3cb3b7, 0x7c03df21, 0x70d837ff, 0xd7f4013e, 0x13c10dbf, 0x8db20f97,
- 0x8ff483e7, 0xe6f20f9e, 0xe8104b0e, 0x09af7ce1, 0x8f3292fd, 0x45b59d7b,
- 0x7524001f, 0x01cf0e38, 0x72581b79, 0xca1ae7e6, 0x8b0f727f, 0x8f12c923,
- 0x4b4afd33, 0x6bcc5c58, 0x808bff07, 0x774c765b, 0x3e408b7b, 0x713779b2,
- 0xb39351bf, 0x2ef16140, 0x94d43796, 0x7b002e10, 0x87ae55ea, 0x5e2ccc9a,
- 0x87d0e835, 0x26a35d61, 0x185d1fff, 0x93df62d7, 0xd8941a5f, 0x884f56b8,
- 0x0a2775d9, 0x9d3d6135, 0x07d80f67, 0x59ab6eb0, 0x9f286b7c, 0xc7a1bf60,
- 0x5890e2c0, 0x41ccec1e, 0xe22f5939, 0x3f99fb56, 0xa7c79eae, 0xf45acc4e,
- 0x745ca40c, 0xb035ad48, 0xaab0bb3f, 0x0fe8fd12, 0x9f13393c, 0x7ed52bf5,
- 0xa7e045ff, 0x238e1bcf, 0x1d7bff0b, 0xbd99e8f1, 0xd447ec3c, 0x5945fb50,
- 0xbe815729, 0x15f621cc, 0x2095ff20, 0xe9abad5d, 0xc13e83b3, 0x12349768,
- 0xa77239d8, 0xfbeb0ccb, 0xf5068768, 0xe343b054, 0xcf027685, 0x8fccc939,
- 0xf3324d74, 0x0aa5d06b, 0xd9e238c1, 0x0771e3a1, 0xa272dfde, 0x2353c309,
- 0x76a3e7b1, 0x7d3466b9, 0xd0ebfa2d, 0x4fc11ab5, 0xa0d4cd17, 0xde82fbdf,
- 0xc6fd173b, 0x790202ce, 0xd6b61d54, 0x1eac3595, 0x2982e779, 0xebfac3ea,
- 0x12486664, 0x33f209c5, 0xcbe79935, 0x616de1c5, 0x1f1cba97, 0xa90c698f,
- 0x3fc4f5cb, 0xc58f2d21, 0xa7df620f, 0x75f93326, 0xc70e5561, 0xe3f307b7,
- 0x6797fcc4, 0x3269bc30, 0xb33733d9, 0x41d02e6a, 0x7397c42e, 0xabfcc9e0,
- 0x7f082674, 0x092e75ee, 0xde0e23e9, 0x80da300e, 0x3c593abe, 0x3f856ff4,
- 0xe4caee1e, 0xbc1fae14, 0xd65f886e, 0x8f18f5db, 0x493f5cbe, 0x0e5ab25d,
- 0xfebf950d, 0x27db2cfd, 0x9e796a75, 0x50e51d8d, 0xe5cd9d9d, 0x11d9e484,
- 0x6a56f786, 0x3a3cc02f, 0x3f6025b5, 0x8ad5bb4c, 0x6fd968f3, 0xf3703f42,
- 0xd02c81b2, 0x03552de3, 0x89b71005, 0x2b402fc7, 0xdb45f90b, 0xfee8b9d5,
- 0xd884ec03, 0x4b5f3c76, 0xfef5671d, 0xf60cb920, 0xbf762739, 0xb76afa01,
- 0xfd15f509, 0xf00603bf, 0x839cbcb3, 0x3687ccf6, 0x0bb41b7f, 0x9e5bc398,
- 0x85bb01cd, 0xfdcd4dd9, 0x0bb01e86, 0xe2623aeb, 0xd59ff07c, 0x591fb8ea,
- 0x3bff44e9, 0x6fbf56e9, 0xddf714d8, 0x17603888, 0xbd3af3ae, 0x3bf0227f,
- 0x7f983bd5, 0x8351b670, 0x5af50379, 0xb79022cf, 0x7b6a4d67, 0xad8dacfc,
- 0x75a196d7, 0xb5bda0f6, 0xf675cc65, 0xd73ac014, 0xb63f886b, 0x6758669f,
- 0x7c4dbeba, 0x78becf9d, 0xf3ac0175, 0x2eafbbc7, 0xa75e7580, 0xdf02f2eb,
- 0x5bfc39b4, 0x27bf6993, 0x3da1f06f, 0x2f58f225, 0x24f71e97, 0x432bfdab,
- 0xff21ffe5, 0x30fa58ca, 0x5a87043c, 0x4af4ba1f, 0x3a83c806, 0xd5bfe1a3,
- 0xaa37f08b, 0x4068cf1f, 0x3ffec77f, 0x0766ba7f, 0x2d7e81c8, 0xbfa223da,
- 0x0f3fb2fd, 0xeffda1ec, 0x69413db8, 0xb91bfeec, 0x246dd85f, 0x88abf041,
- 0x27b0807d, 0x5bf1e5e3, 0x251f3e7c, 0xbb006f7b, 0x8dfacbe6, 0x633bf81b,
- 0xe76653e8, 0xcc3c936e, 0x7e8bdc6f, 0xf37d96e4, 0x3e27e0ed, 0xe37e621d,
- 0xd18b1796, 0x7a18dc6f, 0x65790c2d, 0xc3b25fa4, 0xdb71a3fe, 0x07c804b1,
- 0xba5cfb10, 0x8c933daf, 0xefdea8f4, 0x489d0e9e, 0x0a01fc80, 0x71e82577,
- 0x07aa2b8b, 0xfba16fba, 0x6c23c83d, 0xa187a391, 0xc11716df, 0x3ed2973c,
- 0xc44ffef5, 0xf4fa3779, 0xf6377728, 0xd790214b, 0x4e7f7a29, 0x9235e806,
- 0x2078c761, 0xc98bb3e7, 0xb294d4de, 0xf7baf8d8, 0xe1e4e4f3, 0x0d81b07c,
- 0x03bf4889, 0x83b5e23a, 0xe360db3c, 0xf9464cf2, 0x8e4dc7f6, 0x630fcb10,
- 0x6218ffed, 0xc8a34276, 0x5849930b, 0x68b5eba6, 0x585df7b6, 0xe1f7906f,
- 0x5b1f7938, 0xbbfb7116, 0x52f51849, 0xca181933, 0x176d8b0f, 0x7887d71f,
- 0xd21faab8, 0x1f80ac5a, 0x07ab4eec, 0xb8f881e0, 0xf6c83eba, 0x961f94eb,
- 0xafd30c96, 0xbf410758, 0x1d0fdc2d, 0x08fe3868, 0x4fa06fd0, 0xd77d83b2,
- 0xdbf461e4, 0x905bf744, 0xefcf1b47, 0x379d57a4, 0x97ff163a, 0xd1f5a8a6,
- 0xe4eff950, 0x453ebd5f, 0xfe62f7cd, 0x343f6fc2, 0xf1897ecf, 0xe2bcdc65,
- 0xfef1a9f7, 0xbccfb176, 0x2738795c, 0x870f2d45, 0x79677fca, 0x2eb43758,
- 0x1d50f2f1, 0xe59bf8cf, 0x5c70ffe1, 0x4f7d99e3, 0x03bec027, 0xa7d878ec,
- 0x63aedcac, 0xfd1413f9, 0xe9e2f1b1, 0xc597ab5a, 0x5ea2b54f, 0xa657871d,
- 0xe33c38f3, 0xd45ed7eb, 0xf335bae2, 0x3ef37138, 0x369a079b, 0x9c631758,
- 0xba7e3e36, 0x0e9eec84, 0x471f154b, 0xce7e026d, 0x753c74bb, 0x8f8b0a75,
- 0x20725852, 0x6f3e216f, 0xa7eb35eb, 0x7598fe49, 0x1ba22aaf, 0xdbe85182,
- 0x33890728, 0x14c6fde6, 0xc6bf5766, 0x7adc8bf3, 0xad608e76, 0xfd85e2cd,
- 0xf2c35b8c, 0xf2e07e9f, 0x18bc826d, 0xfaf1c2a3, 0x4344edf2, 0xae8cf2f1,
- 0xb04ae517, 0x3901ead9, 0xa237fc28, 0x5e3c8bff, 0x3ffad971, 0xfcf7de8e,
- 0x3c7bd30f, 0xf18bf67e, 0xddb8d6fe, 0x151b8a7a, 0xe3a4105f, 0xca5f1023,
- 0x63bf4919, 0x1d1633f5, 0x1df14d1f, 0xfe766149, 0xb857cc14, 0x2963394c,
- 0x3f009e8d, 0x5063d911, 0x7e09afc0, 0xab8fd412, 0xaa3e78d3, 0xe6267ca7,
- 0x2573b369, 0x58ce1ce2, 0x4307e476, 0xc8ecc3eb, 0x9f5cc60f, 0xde47672f,
- 0x087df0ee, 0xd2b27674, 0x1e01e78b, 0x61f851b5, 0x619cf87f, 0xe22e73d4,
- 0xfca5c63c, 0xd1c45f2d, 0x4bff17d5, 0x3a92d472, 0x75f95d96, 0x13cfd1cb,
- 0x763a7fc0, 0xff9e413f, 0x45bc4119, 0x6b6449f7, 0x103b5f8c, 0x197bf961,
- 0xfef15e1c, 0xa1bef83f, 0x999bd521, 0xfc7fdf4a, 0x1248d1ae, 0x652e9ea9,
- 0x67c5b172, 0x4b42b8c5, 0x697fcb2f, 0x8e504659, 0xb4df80b7, 0x3389fc08,
- 0x4f7dd809, 0x2013fd3a, 0xf7d1ee8f, 0x226d41ac, 0x1167dbf8, 0xbdcef3b0,
- 0x9c33cacb, 0x6798c9fe, 0xe3006cb7, 0xceb3dd18, 0xf9561e60, 0x523e9f17,
- 0xa2f08a53, 0x5065c13f, 0x3db9679f, 0xf133c995, 0x6f843d9c, 0x3ff3fa2f,
- 0xdaf9606e, 0x0ed79701, 0x0fe1097e, 0x8c1128b7, 0x61ecb42b, 0x96b95bc6,
- 0x30fc87cd, 0x65a9e903, 0xf831654f, 0xa9af494d, 0xf2ddec18, 0xdf715bdf,
- 0xe983f1f7, 0xcfb12798, 0x7c02afe5, 0x37434ad8, 0x4d9a7d81, 0xf7bb01c7,
- 0x1537dde3, 0xfe42dc03, 0x39bf03ad, 0x4d9d7f1d, 0x462717ed, 0x64bf7796,
- 0x33ee2647, 0x5afeac9b, 0x133aff98, 0x9db82383, 0xfee14f9f, 0x17fe78f2,
- 0xd5aa9f7c, 0xdfa938e0, 0x5c9c6235, 0x3a7585c8, 0x0de637e2, 0x9e1293cb,
- 0xf1701867, 0x99fec73c, 0x97854f2c, 0xbe752ead, 0x37c947e7, 0x253c0094,
- 0x8b57f2a9, 0xe4475967, 0xb2a4940b, 0x5cea9678, 0xb322e5a2, 0x7aed73a7,
- 0x4adb27a4, 0x9454e2c2, 0xbfaec09e, 0x06991a36, 0xbbf2bce7, 0x9e02d7c3,
- 0x20d45ff7, 0x4799e49e, 0x28933e30, 0x56f2f1b1, 0x004e740f, 0xadfd8c7f,
- 0x954960eb, 0xa0157b2e, 0xefa749f4, 0xffe45481, 0xaf1842d6, 0x2c745fea,
- 0x059f72bf, 0x59dd0cfd, 0x795f984d, 0xea833dee, 0x33fc4e7c, 0x3e605648,
- 0x6fdf6e65, 0xdb604e31, 0x279a8d23, 0x15aa44fb, 0x1825a6f9, 0x36398e99,
- 0xce50bad7, 0x1f7efbca, 0xee43bb04, 0x91024194, 0x03579d0e, 0xcb82d3e7,
- 0xc7f5fa09, 0xb035db77, 0x3f3cd95e, 0x7fff7066, 0xbee3f14e, 0x4205c445,
- 0x3749bf2c, 0xc7ec08f0, 0xdf03e5e4, 0xec7ac20c, 0xc05a6871, 0xb68baa7f,
- 0x9f65dfa0, 0xd9acfd05, 0xbe2b797d, 0x2bd9cb41, 0x1b0718ed, 0x6ceee57c,
- 0xf3a7e7cc, 0x3cca3f1c, 0xf9654a1f, 0x8b3ef248, 0xfc99f406, 0xa8c0f104,
- 0x0aa523b2, 0x968a7ee1, 0x07df3f69, 0x8e1e4a7a, 0x0a3f829b, 0xaa4354f4,
- 0xcdd0077f, 0xa5a4b9d0, 0x892e7666, 0x2db5a79f, 0x9c176f7d, 0xfdc2d9f7,
- 0x4ff707b9, 0xbffe859e, 0x7582594e, 0xf960e0b8, 0xb2a42f95, 0xfc48e278,
- 0xd63cc41f, 0x65bf7ddc, 0x02e28d7a, 0x8c7597fa, 0x574ee45e, 0x5f19f80f,
- 0xde63f049, 0x611d75ee, 0xeccdc62d, 0xa35c7f27, 0xd677ecc4, 0xb2d33d33,
- 0xe3cfed93, 0xd29737f7, 0x921ebf2f, 0x0cbf4c33, 0x764eff95, 0xf4e2efcb,
- 0x6fbcdfca, 0x5efdea21, 0xbf12fdbc, 0x8f611bbf, 0x9637f5c7, 0x50f2231d,
- 0x61c786aa, 0xd84db4f6, 0x9e554149, 0x9f95954e, 0xfbaa343b, 0x47649f5f,
- 0x3b79107a, 0x72caed29, 0xfe8fdbc8, 0x4edfa088, 0x3c8915e4, 0xcb1560a2,
- 0x8c6a09f7, 0x4dd12e78, 0x687f30ba, 0x124b091c, 0xf006d7fa, 0xe42a6dfc,
- 0x4fefd111, 0xff62e6a4, 0xa567899b, 0x22a6e516, 0xc826fc01, 0xb802493f,
- 0xc1161b43, 0x7159b778, 0x9fe4133c, 0x033ee124, 0xc7dd39f9, 0x35a756f2,
- 0x3a43b8b0, 0x4e50cfd5, 0x697467cf, 0x3cc7ab9a, 0x22579156, 0x5e044ff2,
- 0xd3be38aa, 0x01ca2c27, 0x54f228b9, 0xe53d99d6, 0x39c11760, 0x1cbf3868,
- 0xbcf3346c, 0x776fd613, 0x4f9e2e63, 0x2979b2fe, 0xf91678f1, 0x7f44fa29,
- 0xe46cbba6, 0x37416739, 0x7089eb31, 0xecc7dc6d, 0x3d06aafc, 0x71b063ce,
- 0x072bfa06, 0xec04351b, 0x037eaa81, 0xf1b8c3a3, 0x93d5ce36, 0x872bf430,
- 0x054f204c, 0xceca5c3d, 0x085beba5, 0x6d83e0fe, 0x524ef33b, 0xd6d43fde,
- 0x9341cf8b, 0x12bdabd4, 0x03cea1cf, 0xb48df5c9, 0x1af95afc, 0x6689b7c8,
- 0x6a849449, 0x96faafd3, 0x60c4f54c, 0x287df472, 0x7be1bedf, 0xba3e3cac,
- 0x9beda245, 0xed623ed3, 0xa9d33681, 0xefff5ed8, 0x57eb41b5, 0x267f7fd0,
- 0x351cf9f1, 0xebf464ee, 0x3f41123c, 0xa57fd712, 0xadba3e4c, 0xdc9fb47a,
- 0x54951f3c, 0x8854fcf3, 0x7b72d0f8, 0xefc6315a, 0x13d944ad, 0x030cfa81,
- 0xe30827b3, 0xccf1f687, 0xf4e46d6f, 0xbf843240, 0xf208206a, 0x81c73dae,
- 0xe7c90fdf, 0xf310863d, 0x8ff1b19b, 0x9e0578be, 0xb679124b, 0x6733d884,
- 0x36f9815f, 0x135af2aa, 0xdb29a73f, 0x7bbce133, 0xc1db8ebb, 0xe6c47cbc,
- 0x04f3885f, 0xddf6a4be, 0x507e1bd1, 0x7674fc04, 0x41f30fef, 0xa7a8ddce,
- 0xe45184fb, 0x933a595a, 0xeb3a836b, 0xb77e894a, 0x016fe6c6, 0x32c77c3a,
- 0x311c3a6f, 0xa9549b9a, 0xc1bc0077, 0xd780b4e7, 0x8e274e64, 0x473e0cd9,
- 0x3c824fb5, 0x1b1376d4, 0x7b2fd937, 0x7f845cf1, 0x851b74b6, 0xf2625dbb,
- 0x88947e9b, 0x92a15576, 0x26c87108, 0xcb55ee7e, 0xcb9688e5, 0x1b6e7f91,
- 0xc1a997c8, 0x13ef4d78, 0x7fe7b05a, 0xbfe2e3cb, 0x9f9f51cd, 0xb83371e8,
- 0x569673c5, 0xcfe802b9, 0x523aaba5, 0xab40e94b, 0xfd7084f7, 0x37186d32,
- 0x772b603e, 0xa5efd00f, 0x42951fec, 0xe67b773e, 0xbe214a8f, 0xdc7a75a7,
- 0x8f7298be, 0x357fd19b, 0x59bc03b4, 0xefc14b5a, 0x97f5b5fb, 0xfa2bfb48,
- 0xf50dfdf2, 0x35706063, 0x7059a319, 0x9359fe6e, 0xffac3b7f, 0x30c7f985,
- 0xfa40fc2e, 0xaf21f7d1, 0xd18ea8e3, 0xe793305d, 0x69ee93e3, 0x0eee9409,
- 0x5e7839e7, 0x1ebf8b0a, 0xa8fcc09e, 0xfcb17e54, 0xe61289d1, 0x66ced621,
- 0x266f62e7, 0xfa018e91, 0x68593a3d, 0x1c8af4fd, 0x796b7fb4, 0x77f4c89e,
- 0x7eb0097c, 0xca8f6fd3, 0xb2c7f720, 0xeb746ee7, 0x3e188194, 0x975149be,
- 0x97542e6f, 0x9751e5bf, 0x97f15dbf, 0x9365b109, 0xe8107bd9, 0xdf8955f5,
- 0xb10d7147, 0xa4ba7f23, 0x935dd820, 0xe7e74a5f, 0xe53e5989, 0xf17ef94f,
- 0xf5820aa5, 0x5b8d3b29, 0xfdcf508d, 0x3f5e5aef, 0xd98c4dd9, 0xea07c44e,
- 0xf3c4a8e9, 0x93185d32, 0xb1ef7b22, 0x6d343f33, 0xecfda7ab, 0x1f20af9d,
- 0xe43558a7, 0xa5ebc09b, 0x04c3b446, 0x289bb45f, 0x963c537d, 0x819a338f,
- 0x9e75dbde, 0xd697d0f5, 0x2f40506c, 0xb1182657, 0xc83fed6f, 0x9b96d7a8,
- 0xcb4ec40c, 0x63371f07, 0x3e265cb9, 0x20a123c8, 0x51e786ce, 0x0ad4279d,
- 0x60eda5f3, 0x160eedbe, 0xeb96d757, 0x7ed3cf51, 0x3e0f5d71, 0x9c1109a1,
- 0xf98ca57f, 0xc1661ca6, 0x7c247477, 0x6be734ff, 0x518486ad, 0x7bb3a58e,
- 0xfed10e39, 0xbf83dfa1, 0xdfa0f6d2, 0x13b950ae, 0x271bcfea, 0xc0a8b9e0,
- 0x592f79d0, 0xda15c003, 0x67e87cb9, 0x3f04f2e7, 0xa542f90b, 0x852bbe5e,
- 0xf8149030, 0x053b050f, 0xfb8204ec, 0xccb71100, 0xd97a8a34, 0x0da6fd0b,
- 0xe0e767b5, 0x56997852, 0x60253585, 0x27f1bca7, 0xe4b1c3a0, 0x931a6145,
- 0xe429e213, 0xc3c316c5, 0x19af6a47, 0xef0a3d6d, 0x9b0cf2c7, 0x84c7ad9d,
- 0xad4be00c, 0xe8064279, 0x478776cd, 0x0b94c5f1, 0xae6a76e9, 0xdb45f013,
- 0x35adf2d1, 0x18e5f2c7, 0xc69854fd, 0xe76d00e4, 0x1ef0a24d, 0xc0192934,
- 0xdb8ca3bf, 0x7cb5c6cc, 0xe9bae3bd, 0x41ddb4b8, 0xb6971d1b, 0x843266db,
- 0x8da30935, 0x78c0a15f, 0xa2971a97, 0x833f911d, 0x93a503af, 0x0ec1f820,
- 0xaf4834da, 0xf2be7833, 0x1e3664c1, 0xffe75429, 0xf8e99be4, 0xcea65f98,
- 0xda51b9f7, 0xfa7a01d4, 0x56c25369, 0x3837cfa0, 0xfcb61cdd, 0x69d83e43,
- 0x382bcc6f, 0x71267284, 0xd1100779, 0xf28bd20c, 0x0bc1c846, 0xa1cac769,
- 0x8de1e54c, 0x0fde7469, 0x079d1ee4, 0x3c721f9d, 0xa5f68f9d, 0x56935bd9,
- 0x417e1236, 0xa06e029f, 0x218be053, 0x5f838d3a, 0xa5b91bd0, 0x37251317,
- 0x9e173b53, 0xa425eec2, 0x2bc5e595, 0xa3f3c399, 0xd8dd3e44, 0x18d1e6ca,
- 0x746fb844, 0xe6f318fc, 0xffe718ee, 0xf735c01e, 0xbef04fca, 0x3f9ee222,
- 0x1477f601, 0xc96979de, 0xc6f07bff, 0xca97f9db, 0xcf8b1f0f, 0xacd2f8c5,
- 0x1e1f989d, 0x7cc56d98, 0x3f3c69f1, 0xc1a0d036, 0x0fdd00b8, 0x85a23ee2,
- 0x97204318, 0x5cbb72a7, 0x45785b9c, 0xe0d6fe62, 0x7d45068b, 0xde7c513f,
- 0xe97982b8, 0xbf2c65c1, 0x6f7ec87c, 0x1f7ed056, 0x9cfc73d2, 0x93317744,
- 0x28f7dded, 0xe689fbea, 0x44fdf513, 0x7121ed0b, 0x32948a6f, 0xdddfbf9c,
- 0xbbfe9043, 0x9f58b96d, 0x88fa65ae, 0xa3e9837c, 0xbaa21cee, 0x399d691f,
- 0x94f31134, 0x46c15e78, 0x6ff83fc8, 0x9a7e0bf2, 0xc2fca926, 0xc9afe543,
- 0xf0e6dc2f, 0x5b3a02ef, 0x92cde458, 0xebd63d28, 0xd2987f99, 0x8108a6eb,
- 0x7cd6c574, 0x44dda7d8, 0xe4d2df5a, 0x02febd21, 0xa53275e9, 0xbd153cd7,
- 0x15fc61ee, 0xe82d2144, 0x0b4e8875, 0xfd00f3e3, 0x6edc60fb, 0x5befef47,
- 0x6fd35f60, 0x683cb0f0, 0x2f19d796, 0x59e0621f, 0x5c783320, 0xf3c22d5a,
- 0x0f13f43a, 0x4df0e5cf, 0x12a69d2c, 0xf1631fc6, 0x824caa4f, 0xfe6192b6,
- 0x6ffd9931, 0x7c43b8c1, 0xcfdb08f4, 0x6b5b808e, 0x739a7a45, 0x057f8b07,
- 0x802ecc2c, 0x1d1a5838, 0x7f1f267f, 0xdaafa74e, 0x4a66ed01, 0xfa610f0c,
- 0x167f850f, 0xdfd99faf, 0xb370798c, 0x63c775aa, 0x2f2120ed, 0x2e6ddc45,
- 0x7dab7f6f, 0xd2f20ea6, 0xe3aad767, 0x64ef735d, 0xb339b6f1, 0x25ccfdd5,
- 0x7cc13fab, 0x03aad24d, 0x53bdcdfc, 0xda49ff5d, 0x026c9c50, 0x710ec9c4,
- 0xe520d03f, 0xd7a3e013, 0xba6f1793, 0x84f9d287, 0x8095149f, 0x9486f0df,
- 0xd04f6dc6, 0x271bb3f2, 0x94f5f961, 0x28ff7eef, 0xc0296fd4, 0xe25c3572,
- 0xe056fb04, 0x8567ca43, 0xc8cc77e5, 0xc27d0049, 0xe087bdfb, 0xdfd9b77b,
- 0x73b6933d, 0x3cc5c94f, 0xd7ee6ad6, 0xeac85c18, 0xc6d2be6f, 0x52ef9552,
- 0x6d5c5fd0, 0x1d35f766, 0x04bb7e29, 0x73abaaf2, 0xd5e4b979, 0x243e5049,
- 0x3af7827d, 0xcab66b9c, 0xe92d0eb0, 0xb93ecfcc, 0xa44f0a50, 0xf276a978,
- 0xbcd99bfe, 0x4b9e4b6a, 0xaea93e07, 0xf64cfd62, 0x41e67654, 0x2c79cd3b,
- 0x26374b9f, 0xbf05fe00, 0x957df0e5, 0x5c7d2bb0, 0x3de4bc4e, 0xfb4491d6,
- 0x0f2519f5, 0x7157d14c, 0x664bdd8c, 0x7d03e765, 0xfc191cde, 0x2cbcd3f4,
- 0xb8cab6ef, 0xe1e40d3c, 0x297d7e2d, 0x2c6ecbcc, 0x1179043e, 0x65951589,
- 0x246da798, 0xfe94beb8, 0x3f03a7c7, 0x5649fd5e, 0x559d1002, 0xbe82ff4d,
- 0xafba0a66, 0xe537d356, 0x65e9c9db, 0x2adf9697, 0xd30d36fa, 0x3ef658f7,
- 0xe102ab85, 0xaf5a86fa, 0xc7138d0d, 0x8ee3f19f, 0x2fe03725, 0xc30efe56,
- 0x987c8bd7, 0x798dd901, 0x825da7c0, 0x38026f4f, 0x9e089af4, 0x3c96ca8f,
- 0x7180f093, 0x7a88c785, 0x055f8e2f, 0x33e0997c, 0x1709192f, 0x6ec2c9fc,
- 0xf02e7f65, 0x7af064a3, 0x38979dfa, 0xe3a2e187, 0x7a0e91df, 0xcf0611fc,
- 0xc995a966, 0x112fbe19, 0x311697fe, 0x7cf53edf, 0x1eeccdcb, 0xcbf83703,
- 0x3c527630, 0xcbee0869, 0x9f310758, 0xb3e7d700, 0x9e9b3e8d, 0x4736edce,
- 0xedcfd23d, 0x283aa354, 0xff74c25e, 0xd41e700f, 0x7ec1f704, 0x62f1216f,
- 0x47d29cfc, 0x6ec63d20, 0xe3c6f012, 0xb90c65a9, 0x789f3f1a, 0x5baf0cfc,
- 0xe29e0d24, 0x7cd0e1fc, 0xf19e732f, 0xaf4b8af6, 0xb93a5bf6, 0xec39d17f,
- 0xfa842c4f, 0xa0f6625a, 0xe123d13f, 0xda96af7e, 0x6ba7201f, 0x71fa086b,
- 0xfa0d569c, 0x321d8513, 0xff5c9f16, 0x6ab7264d, 0xf73f089b, 0x4f17e6c8,
- 0xe064a98f, 0x1ad6787e, 0x800b0d95, 0xaaac1bff, 0x56b50673, 0x4e788f16,
- 0x503211c8, 0xa87f7a06, 0x0fef423c, 0x8a1c8194, 0xf6ae7fbf, 0x3b7bf322,
- 0xacf84a2f, 0x032b1cf5, 0x19acefbd, 0x56790328, 0x14fef767, 0x13dc55d6,
- 0xbdcf8f19, 0x97911ae9, 0x1a745972, 0x0e2247cf, 0x7fe6c47a, 0x3fc63d39,
- 0xa08a5675, 0xcbb5759f, 0xcfe7e7ce, 0xd8767a01, 0xefc12a73, 0xaad8db34,
- 0xd138bb03, 0xce903fe1, 0x5f17e8e4, 0x9a17e6c0, 0x56de3c52, 0x66587fed,
- 0xee1e22c3, 0x81b878e5, 0x9bf3d9eb, 0xa90fb8b4, 0x0d3e16f6, 0x9bc0a0a1,
- 0xbe42123a, 0x147ea2f5, 0xa79dc6f7, 0xda185506, 0x7d436f3f, 0xf557f8bb,
- 0xb09b2718, 0x1894435e, 0x6431397d, 0x327fdd56, 0x5553a779, 0x5d37a2be,
- 0xbecafed5, 0x717d555c, 0xfeaa9278, 0x544b37aa, 0x54c8b2e5, 0xdfabfb55,
- 0xaf9552a9, 0x6aa19819, 0x3df403bf, 0x4e37e3c5, 0xffbd52cf, 0x37f4e368,
- 0x5d7d3e21, 0xefaa3bf4, 0x043f704f, 0x85237a09, 0x040bfe74, 0x53ac5ebd,
- 0x9acd4f7d, 0x7c0e54b0, 0xac16fecf, 0x95f77966, 0xfdb16314, 0xdb52ec2d,
- 0x28903713, 0x84b62be6, 0x40984f24, 0xbeba9dde, 0xf107afb1, 0x0f7ba97a,
- 0x6be6b826, 0xc69754c0, 0x22633b51, 0x0d5c8220, 0xf1638379, 0xbfd6a5fb,
- 0xa97fe480, 0xd5b837f5, 0xd4526feb, 0x54296feb, 0xa3cdbfaf, 0x0ac4ff5e,
- 0xbc3bfaf5, 0xaa4ff5ea, 0xb27faf51, 0xa9febd4f, 0x9febd573, 0xffaf57e6,
- 0xbaf506b8, 0xd7aab667, 0x7aa97b3b, 0x4b82735d, 0x74f1f554, 0xc849e820,
- 0xf795bccf, 0xa453dbaa, 0x42e86268, 0x5f02d9d0, 0x8d63e603, 0x35487aef,
- 0x4c7d3c5e, 0xf48f3c20, 0xe547d22b, 0x727f6e38, 0xa97aa0ba, 0xda325c6a,
- 0x73c03719, 0xff6e04ee, 0x33b746fb, 0xd58afc84, 0xe6fbb1eb, 0x08dae4b1,
- 0xd1f7c57d, 0xd82bea63, 0xf7869b47, 0xefd163d1, 0x59ea84bb, 0xfa357c1c,
- 0x33b0eecf, 0x999a0e38, 0x5429ff3d, 0xd1db435d, 0xde141536, 0x743e6177,
- 0x93cd77fc, 0x1df20fd1, 0x7183abd2, 0x7c1124ef, 0x7c5123ce, 0x755d89fa,
- 0xf10165be, 0x645fb9e9, 0xc9a9e009, 0x7a0e5038, 0xa3fcc2ff, 0xee7c63ef,
- 0xdd65d248, 0xe21c7207, 0x3909e33f, 0x49c9e5c5, 0xf2d10388, 0x27f71339,
- 0x8ae2897a, 0xee29e7c1, 0x269bacf7, 0x5a259ea1, 0xd5b1e633, 0x9ea12edd,
- 0xf60ffbaa, 0xf4c71f6c, 0x52e788da, 0x6e2ed781, 0xa13b301f, 0x62dd0e0f,
- 0xadf890fc, 0xec7a8f68, 0x3fb4deb0, 0x47f98716, 0xdbb17f76, 0x25dce0c8,
- 0x89c2b911, 0xdd7106c7, 0x7ce1fd61, 0xe0c8db9b, 0x4623a5db, 0xe264efc0,
- 0x31f0fb47, 0xd63c8a99, 0xefd624ef, 0x17f05cd1, 0x7e6fcd9a, 0xa9f21aab,
- 0xf472e0e5, 0xa88f7fdf, 0xb677f7fd, 0xffbfe84a, 0x3e9b851e, 0x1b8f76dd,
- 0xef28b2f4, 0x1e21b802, 0xfbe8ed00, 0x04ab7754, 0xadafb1fe, 0xb10f3dbf,
- 0xbfb25f76, 0x83087ea1, 0x3d60fe0b, 0x83367f85, 0xd281b7d2, 0x11efb6cb,
- 0xfbc61ff4, 0xa969c76b, 0x31fc8106, 0xc097bb1d, 0xfb67af2d, 0xbb1ec3e2,
- 0x7444cfca, 0x7a47380e, 0xf20e7b29, 0x9cc54fbe, 0x3474a0d3, 0x1fbafdea,
- 0xa47cb065, 0x44c8b6f6, 0xe39e4b88, 0xdb87d771, 0x56b2c4de, 0x265e60f6,
- 0x88e5f7dc, 0xa2ef5ef9, 0x4e7231f5, 0x63efd2b6, 0xeace8de4, 0x1e6bcbc3,
- 0xbc608b69, 0x25efc753, 0x5ee3347b, 0xbfc63fbb, 0x6e38cef2, 0xc4831927,
- 0x69b8429e, 0x4f4eff4f, 0x5a3f4023, 0x762a7cbb, 0xd3706d1f, 0xeef562fe,
- 0x1b1264c5, 0xf6d9587f, 0x88fdc20e, 0x6743f7e4, 0x36127c86, 0x641b7c51,
- 0xdf4d0338, 0xe511b86f, 0xaf76deaf, 0x1aa1ee07, 0xb7067f0b, 0x7e56217c,
- 0xdf8e387e, 0xe7e5c5cf, 0xc9d16d93, 0xdb7b4e30, 0x5d6f0a80, 0xfdf1176d,
- 0xc452369a, 0x7ac43fea, 0xf4828d4d, 0x42d28a73, 0xf27ae204, 0xc1fc0d80,
- 0x10263ed4, 0x8db9d67f, 0xb8306f18, 0xa2e4bc18, 0x9e63e90b, 0x3e00c19d,
- 0x1f4a4cbf, 0xe1d52fef, 0x4cbefafe, 0xefbfb62b, 0x780fe337, 0x29eadf29,
- 0xc37fb41a, 0x61c7867c, 0xf973d3f8, 0x0fbf6449, 0x5d3e80e4, 0xd38538c6,
- 0xf1d70b3e, 0xf027f6cb, 0xcc1137ae, 0x5a67d647, 0x5cb85ed1, 0x6a19dd38,
- 0x8fe3c7bc, 0xffe509e2, 0xf74f1c7d, 0x93fcc83d, 0xf04fddf7, 0x4a59053c,
- 0xe987caff, 0x87971c6a, 0xcf87c4a9, 0x082a36ae, 0x465eb00d, 0xed409fe2,
- 0x8d8bd211, 0x82a7e04d, 0x80ecaf7a, 0xaa2788d4, 0xb9e1335d, 0x1764e2a6,
- 0x6bdae3b0, 0x13c08b3f, 0x2f801162, 0xc109037b, 0xab98bc55, 0xf877c740,
- 0xd7813959, 0xe565cc27, 0xe89f5e44, 0xef4ce563, 0x0035520b, 0xcb471716,
- 0xca6f3ab4, 0x80bc7907, 0xfcf173b0, 0x84cd8d7e, 0x73ab0bcb, 0xdfd43566,
- 0x8b9cf049, 0xaf09ffa8, 0x5f1eb34f, 0x637a0799, 0x0dfbfab6, 0xd6a90f1c,
- 0x30d35de3, 0x17aea6de, 0xeb64acf1, 0xfbf137f9, 0x53fd7522, 0xf59b7bfc,
- 0xd41a647c, 0x7fc7abe7, 0xac5bd79c, 0xca8def2c, 0x037f767e, 0xd78c7faf,
- 0xc61ea09b, 0x5af5642f, 0x6f09df71, 0x18e1c9d7, 0x431e33e2, 0xbf33260c,
- 0x233696f2, 0xbf3c57f2, 0x73f707dd, 0x9bf30d95, 0xf519297d, 0x32fb86de,
- 0x5049dc98, 0x51debc06, 0x77a8a2e4, 0x37cc65da, 0x48f5bad0, 0x972b064f,
- 0x871f9c27, 0xead489e4, 0xe4c64461, 0x9ae8a5f4, 0x9005f012, 0x0ff4596b,
- 0xfbe33ae8, 0x918fe21a, 0x664de973, 0x83e58fe2, 0x39554e05, 0x5574cee5,
- 0x5cecd77b, 0x74b5bd55, 0xcc9eaa92, 0xdc9f2276, 0x5ccbe9cb, 0x17aaa254,
- 0x6d9065f7, 0xb59d9dbc, 0x554fe5d3, 0xa85f3bb5, 0x9f8d0224, 0xa3dc49ba,
- 0x7c8231e6, 0x9b96d7b8, 0xb3f8fc0a, 0x4e440ab6, 0xf627e53b, 0x1ba7f3b4,
- 0x54fa598c, 0xcb10b978, 0x7e583bcf, 0x879b7b7f, 0x9e087395, 0xab6f6faf,
- 0xca2ef2c1, 0x69fcf09f, 0xdb9f179b, 0xcfa15969, 0x2bfda47f, 0xda1e9fb4,
- 0xa19f943f, 0x3373c3fd, 0x3f9e1fed, 0xfd43fda1, 0x942fda06, 0xc170a69f,
- 0x0fda29f3, 0xed31ffbc, 0xb44fca1f, 0xb6bcb0f9, 0x1f962e6d, 0xf3e3f36f,
- 0x7c06b6b1, 0x8ad6d9df, 0x96db47e5, 0xb6e1f3e2, 0xdbdb3e20, 0x2f7d6256,
- 0xf9e793a7, 0x2be7dc79, 0xf103bdd9, 0x219fdfeb, 0x9d2fbb61, 0x154a539f,
- 0x3f2ab97a, 0xfc033fa7, 0xfceabd02, 0xc21fc054, 0x8c786261, 0x0668e387,
- 0x91270fb3, 0x930b72c8, 0x1f07181f, 0x6159e7df, 0xae35fca1, 0x4e7bad95,
- 0xd3eb145f, 0x4778d81a, 0x5c409db9, 0xce519241, 0xbb439b8e, 0xcaa45273,
- 0xd007f2c2, 0x14dc430f, 0x5aece53f, 0x21e64672, 0x5725c00d, 0x331e3d50,
- 0x397c21af, 0xb7809c18, 0x57fde0d1, 0x696d378e, 0xa75fbb2f, 0x6c0c2ba6,
- 0xe2b6f666, 0xb9c63afd, 0x9f4cb0be, 0xef1f9f2e, 0x717498e9, 0x5224dd3a,
- 0x9bf176f9, 0x8ccfa144, 0x31fef526, 0x6a89417d, 0xb8bda67f, 0xd1572886,
- 0xfbd48b7e, 0xbdfe733c, 0x198cefaa, 0xf5eaa90f, 0xfaaa15ae, 0x1e73bbba,
- 0xc73e0371, 0x6199b8b1, 0x210272f5, 0x4fdd85e4, 0x4ce65c20, 0x92738f36,
- 0x605f7ec2, 0x133dff37, 0xd6797fbe, 0x5c65f1ce, 0x09f2fb8d, 0x482c560e,
- 0x0f406a0c, 0x448bfc7d, 0x9e3b7f94, 0x7e9fa0d1, 0x40690922, 0xe6a64cde,
- 0x015fd424, 0xf16b8c37, 0x942d26aa, 0x85a2898b, 0x8a2455f2, 0x7fba3afb,
- 0xf5d264d1, 0x9ffad16b, 0xd9f2d131, 0x2cb3ff4c, 0xfa8c30bf, 0x67af80ba,
- 0xadc7d881, 0xdcfde397, 0x37f44cc6, 0x7625cfa9, 0x874bfdf0, 0x970df989,
- 0xc153ca3b, 0x46373e0e, 0x7dcda83e, 0x14058de2, 0x63b4b6df, 0x1fef14f8,
- 0x9ea33457, 0x94cbcfd7, 0xf75e5abe, 0xd44faa7a, 0xf307937c, 0xcffa5b38,
- 0x6b76e029, 0xff228fc9, 0x3c84e874, 0x9e411253, 0x893d970d, 0x3b1e6624,
- 0x93c9deda, 0x11fa2151, 0x375f326f, 0x4ff95f31, 0x4bc87695, 0xd179e02c,
- 0xf2d2db3b, 0x7f0fc7ab, 0x5074e3ef, 0xa0352248, 0x348b0b5f, 0xe074109e,
- 0x31fcabb5, 0x2f2efca6, 0x4b930b9c, 0xf2c40788, 0xf785d244, 0xd57fc829,
- 0x7c9a3e62, 0x50a21af0, 0x0d6ad8fb, 0x70d16093, 0x75fb84bf, 0xfce5cfbe,
- 0x9c6af667, 0xec259c8f, 0x74e80f26, 0x1bd599f2, 0xacfc3a01, 0xf4d8c75b,
- 0xd0bebab8, 0x2def504a, 0x1487d42a, 0xebcbee09, 0xe5407bc2, 0xc8c9122d,
- 0xb9a63801, 0xdf7e83e7, 0xb63a416b, 0x9fc72fac, 0xe359b830, 0x0efc40af,
- 0xc2357b28, 0x9aeda2e8, 0x82b7eb27, 0xf001393d, 0xdcbc0562, 0x430d5f91,
- 0x1e2217e7, 0x2f79f217, 0xc8e8f3e4, 0x833fc21c, 0x70bc7887, 0x6ea2ef1f,
- 0xcf528fe1, 0xaad2f1f3, 0xa2bdc36f, 0xff2d11ed, 0x3e352299, 0x5322e957,
- 0x70c34be6, 0x66173851, 0xb8015c82, 0xd80f82af, 0x919f9afc, 0x941cc6c8,
- 0x6f68356b, 0x3f306994, 0x9b2e9e3d, 0x8fdc9932, 0x7dd9d866, 0x4853eee4,
- 0x93e5c3cf, 0xc2482c6f, 0x5bb333fd, 0x8fcb326c, 0x58957af4, 0xe12af7bf,
- 0x72e7e45f, 0xa1de1ccc, 0xb127057b, 0x892b60bc, 0xb4bc87ac, 0x2bf5f6b1,
- 0xdc707332, 0xb53d7de1, 0xa53f205d, 0x5c7988cc, 0xa13e44ab, 0x69995472,
- 0x57384f63, 0xfa74e465, 0xf79d4da8, 0x6fcf9db3, 0x418f5f3b, 0xf27bc8a3,
- 0x9cc716d6, 0xafeba9f3, 0x88963f47, 0xff720ed3, 0x1d59a0e1, 0xa4e46d57,
- 0xaba87830, 0xc1f10cca, 0x6da7162e, 0xdd99bfec, 0xc7efbb6b, 0xed302f78,
- 0xa87a0153, 0x57ebede7, 0x0b58fdaa, 0x5f91fa77, 0xf164fde3, 0x398a317e,
- 0xe31fec3d, 0x335b62fd, 0x43c27ef9, 0x7b0e218a, 0x61de7562, 0x7277ec33,
- 0x1f0f9e08, 0xef017da7, 0x81bba6dd, 0x974fb82e, 0xa3fbb114, 0x54ffd7e2,
- 0xb2f11e96, 0x78efac53, 0x3ba5da2b, 0xd81c98cb, 0x2dfce079, 0x2b3f69e3,
- 0xf9d52473, 0x3a399580, 0x29b7a75c, 0x97b3c37d, 0xeed19a90, 0xa9943b29,
- 0xef726af9, 0xc1eff55a, 0x1c0df734, 0xff2828b6, 0x1fba035e, 0x4279fc3c,
- 0x1451f211, 0x08c4bf7f, 0xc19930c2, 0x76b3e70d, 0x17993e6b, 0x676f0f4b,
- 0x36ff58ca, 0x0d2f8ba7, 0xae1ab557, 0xa56f45b3, 0xfd7060cc, 0xb9c6e40e,
- 0x5894f1f0, 0xb5c0467b, 0x03df8c7b, 0xe2abf0f8, 0x1fad42a9, 0xfa74f062,
- 0x6ed3c3bf, 0xfcf0e8fd, 0xb3f3c395, 0x9b5eec43, 0x515ff591, 0xe1ab759f,
- 0x647cfb3d, 0x0a49880e, 0x7f115fef, 0x182993ee, 0xebf8e613, 0x59f4e52d,
- 0x078fe5ca, 0xc09150cf, 0x1e63577b, 0x924caf66, 0xbe5ca16a, 0x2cf77f00,
- 0x02c3ef93, 0xbf9e3f1a, 0x4619ef21, 0x64d77f95, 0x9ddeba31, 0x878a8d2e,
- 0xcf362cd2, 0xb2ea4703, 0xd8f1bfc1, 0x7202063b, 0xbfcf3361, 0x6bdecc7e,
- 0x05a67b84, 0x425ca11e, 0x747d019f, 0xc7bc2811, 0x2a333f4a, 0xd3c651d6,
- 0xc6d6f1b0, 0x4f188df1, 0x1564a73c, 0x3a557b32, 0x387385a4, 0x0b7daf6b,
- 0x5b5b7fef, 0xfdeca32a, 0x1d5ff8d2, 0x5bf0ff87, 0x7a30b729, 0xe1459299,
- 0x90fe916b, 0x0e5a6df0, 0x2a7fd148, 0xbd157c82, 0xa01fe71f, 0x4691ec78,
- 0x8b2d29e2, 0x9f988bd1, 0xdb80bf98, 0x5c02dd76, 0x06bbdb07, 0xbca51a54,
- 0x8917d0bd, 0xbcc1ff5c, 0x2b5c5f50, 0x654c73b3, 0xdafbae32, 0xee78a98a,
- 0x17cf376c, 0x1fa35e89, 0x164477f5, 0x763dbc70, 0xb811b7f1, 0xafd83947,
- 0x883ffbc3, 0x15bee03c, 0x8dff1fee, 0x5389f78c, 0xfb81aa7a, 0x391c0ecc,
- 0xebfb009f, 0x843a59f9, 0x87973e7b, 0x35b51783, 0xc8ec1e78, 0x0c6d7667,
- 0x6965d7fd, 0x89127db9, 0x35af39c0, 0x8b3cec25, 0xd603db95, 0x001b2723,
- 0x43c56b7e, 0xde862906, 0x10196566, 0x68fa35ae, 0x17f6878a, 0x6125a7d8,
- 0x7bc1ffe6, 0xb3ce8719, 0x5a1e19da, 0xbda10f4a, 0xf767ed60, 0x2965d635,
- 0xb852ce4c, 0xe6f7d2f7, 0xebd99f89, 0x8e94bea1, 0xbdfc3b97, 0xd3d6cecd,
- 0x4beec65c, 0x3fed7b5a, 0xc83ee1db, 0x471df844, 0x79f2efd8, 0x7292b80a,
- 0x48dfbc35, 0xcbf81724, 0x5abe632e, 0x235ef86f, 0x2f82fbd8, 0x62d5cade,
- 0x39f947bb, 0x0a2b4789, 0x4cae7043, 0xdb35b1d0, 0xcc1640ff, 0x0bc5f28f,
- 0x7c44ef68, 0xf63f10d3, 0xdf33c862, 0x32e64525, 0x076f443b, 0x68d42c3e,
- 0xe116fc54, 0x549e26eb, 0x73dda3fd, 0xa15da73f, 0x46423bf7, 0xfe4de702,
- 0x22667178, 0x191da7d8, 0x1af3dec2, 0x259b5f01, 0x8c0e625f, 0xdc5a2ff3,
- 0x72381e0f, 0xedc601bc, 0xbe02f3a0, 0xeb75f87d, 0x3a53b06a, 0x53e45eec,
- 0xd0ecbe31, 0xfd60f5f0, 0xdf7bd6ec, 0xd4647f04, 0x3acdeec1, 0x11867538,
- 0xd3b69fe8, 0xa07f3f40, 0x04f0f7fb, 0xfd1aa7e8, 0xb3ed0b06, 0x8b77c3a6,
- 0xb011ff88, 0x6b75176f, 0x3c83f755, 0xc2c5e5cc, 0x8e12168b, 0xac2c2fd9,
- 0x6b9e0ef8, 0x0131785c, 0xcfcc3fdf, 0xcfcc3fed, 0xf8e2edbd, 0x5f3f9978,
- 0xfb8afacf, 0xde9c4f6f, 0x8eddfe4a, 0xbbf7c63a, 0xa59afd60, 0xfaa83d01,
- 0xc73f5335, 0x687f64f3, 0x21b093b3, 0xf311de06, 0x98e1224c, 0x5dda8771,
- 0x52709134, 0xfa32faec, 0x15af9e1d, 0xe6d0ffeb, 0xdd8e3c46, 0x1e1538ff,
- 0x53cffb87, 0xff6471e1, 0x87ff5805, 0xf44bc2b6, 0xfe8c793f, 0x0ff05473,
- 0xef8f9bf7, 0x7bac1dcf, 0xeef942d6, 0xc6c57860, 0xf7e14b57, 0x7bf80cf7,
- 0xb7afa41b, 0xeeb9cf0a, 0xfa0e7822, 0x7a7ffd81, 0x1f52f21f, 0xc0f7aad8,
- 0xe8ba8318, 0x7a28cf3c, 0x83d89f26, 0x789cef70, 0x87959dbe, 0xdeff1ceb,
- 0x90ec8728, 0x942c6a67, 0x8ce7a0ed, 0x015a1224, 0x235297fb, 0xdf1139ca,
- 0x34fefd12, 0xb392ab53, 0x46a17ee2, 0x68d87f9e, 0x26aff161, 0xac2cffab,
- 0x574d12ff, 0x1f68cfcb, 0xf03b0ba7, 0x0e213b7c, 0xf888d7dc, 0xc5fb0c8e,
- 0xf97d703c, 0x9b0b9c08, 0x0cffe397, 0x1509fbbe, 0xd1ef102b, 0x0fcdb15e,
- 0xf38f79f9, 0xa6e3e47d, 0x2313db88, 0xf2d9753f, 0xba1bb357, 0xecb7e8e2,
- 0x8cc23b77, 0x40d9757e, 0xcfc8dabf, 0x7ce072eb, 0x67bf00e3, 0xb9fb414e,
- 0xde30f4ae, 0xfc275947, 0xf3e32b02, 0x601d3256, 0x54788b4f, 0x8217e402,
- 0xdd86b0dd, 0x616f5853, 0x275ffae5, 0xba17b9e1, 0x8114b21f, 0x65add99c,
- 0x071e22fe, 0x1e61cf3b, 0x02c9ae34, 0x7cf20efc, 0xaffdf397, 0xe7a7bde1,
- 0x3a478e57, 0x0fe5ffa8, 0xddc31ef1, 0x0d9f4ce9, 0x3ea1b3ee, 0xca7837ab,
- 0xddcd5ee1, 0xed6ecce9, 0x2509c395, 0xa3ec7631, 0xa7285519, 0x5e395e3f,
- 0x19271b13, 0xc2e4cd9f, 0x94ffe11a, 0xce70e5a3, 0xf0d2e3ea, 0xdd3ea13f,
- 0x1bdfc263, 0x53fdecd3, 0xbabfde39, 0x63bf80c6, 0xe277b551, 0x5fb0b9ba,
- 0x1f31904c, 0x84d7b35b, 0xc55d9cf0, 0x6f8383ee, 0xef35ee41, 0xcbbf871d,
- 0x62896f56, 0xd9b364de, 0xc1f10053, 0xc0dfbdfa, 0xf1389fdf, 0x902cc4f8,
- 0x9593c783, 0xfb6fbc2c, 0x3a748a71, 0x26fbe3ef, 0x579df7b0, 0xdb6ab9e3,
- 0x347f8b1a, 0x4bd088ff, 0xedcdf7f1, 0xd73e2f4e, 0x6899f807, 0x5e1c80f4,
- 0x675fe438, 0xbfd607f7, 0x24a59d19, 0xf306ffa0, 0xa7edea17, 0xeb1df7f0,
- 0x49dd8fbb, 0x42e93e30, 0xbcfb15fa, 0xb9eb71f8, 0x8faddafe, 0xd5df83ce,
- 0xf8e76fab, 0x59f7bfe7, 0xdfc629af, 0x5ff8149b, 0xf31f7713, 0xc5de38f7,
- 0x1911c4f3, 0x76a4b9ef, 0x8ff81645, 0x2037ec4e, 0x33589dbd, 0x1057ef19,
- 0x5853d5e3, 0x8f4f94ed, 0xb029953b, 0x15b20bbe, 0xb676ff36, 0xe9ef157f,
- 0xbdf811f8, 0x2d3ee8ce, 0xda0dafe6, 0xc71009a3, 0x7944ed14, 0x5afd3e68,
- 0xddb7bdfc, 0xdd7007e9, 0xa0115d29, 0x6d2fcd2b, 0xbf03b7a8, 0xf71bbf64,
- 0x82092971, 0x8ef8349f, 0x077bf701, 0x9ed019f7, 0x9d977c1e, 0xef711fcf,
- 0x059a359f, 0x7e06dcf7, 0xdae50e39, 0x0b746660, 0x784dbfb3, 0x51e0e4cf,
- 0x5e3cd5ff, 0xd1efc69c, 0xefbb034c, 0x18533ec2, 0xc4fa3eec, 0x6c9043b8,
- 0xfdfbe373, 0x882fbc16, 0x24f9d93e, 0x7f1b8f69, 0xf1748937, 0xfdf823ef,
- 0x09fe5903, 0xc81fa720, 0xe15bfda3, 0xeed893fb, 0x4affae42, 0x9211598c,
- 0xc74bc7ce, 0xd9fd337e, 0xccfa5ef8, 0xa80f7ecd, 0xb047d78b, 0x5ff0603e,
- 0xbdf8f38d, 0x328cf48d, 0x5f7aafcf, 0x49d97de4, 0x6e028eb8, 0x23b4678a,
- 0x93d2f1e3, 0x029ff6cd, 0x3974f11f, 0x80979eb4, 0x7832fc0f, 0xb63ec0bf,
- 0xea26ab8e, 0x9ce93c99, 0xde32f68c, 0x27931430, 0x07df7cb8, 0x3a839748,
- 0x97a0d3ef, 0x847547a2, 0x2d48c3dd, 0x5457f003, 0x16f576b0, 0x7010f7e6,
- 0x07e7e19c, 0x1e593b1a, 0x3ee799e1, 0x856f9ac8, 0xa81ff3f3, 0xff0bcfce,
- 0x0124ed21, 0x8f5633fc, 0xc4575092, 0xc22d76ec, 0x6e8f7ec5, 0xdfc14e8d,
- 0x3e3e0c0b, 0x2712fd11, 0xbc5ecaf4, 0x15d57607, 0x6d27a01a, 0x4fbf9731,
- 0xfb8979b0, 0x6d3dc4dd, 0xc81978f1, 0x99b2fa66, 0x3b82eff8, 0x25138ffe,
- 0xf14b0785, 0xff744abe, 0x52cd206b, 0x7e589af6, 0x9185ea3b, 0x2fea42f7,
- 0xff827bf1, 0xb053e5bb, 0x9f806556, 0xd5e80260, 0x7fb676d3, 0x40225bc4,
- 0x3cd96bbf, 0xb803e03b, 0x4ef882ff, 0x5bc45e83, 0x4e1e2825, 0x9e3eac4b,
- 0x1bbc84ce, 0x1ba00f81, 0xa3be17e8, 0x9d9e7f7d, 0x763ff6c3, 0x17943f27,
- 0xaa5e43d4, 0x490157d0, 0x0f7dc0d6, 0x024a1d27, 0xcec9e5d0, 0xc872e73c,
- 0x292871f7, 0xe076f6b1, 0x0e7bc110, 0x73ff3814, 0x922efc35, 0x05f80a77,
- 0xfed53b77, 0x5e787888, 0xfd401ca8, 0xc6985ff3, 0x800053c5, 0x00008000,
- 0x00088b1f, 0x00000000, 0x7db5ff00, 0xd554780b, 0x733effb5, 0x79332666,
- 0x84841e4e, 0xe4249840, 0x09308401, 0x0741410f, 0x68151048, 0x85280978,
- 0x42100793, 0x17b6881e, 0x240cdb5b, 0x41b45a20, 0x768bd151, 0xb4544140,
- 0x03414141, 0x58a50077, 0x56d56351, 0x880dcb6d, 0xa8311fbc, 0xadadff97,
- 0xfb5bf5ff, 0x90ce649c, 0xf9b7b5a8, 0x67d9d83e, 0x7b5ad7bf, 0x3bdaf5ed,
- 0x3f437cdf, 0x756109d7, 0x10f4422b, 0x116dce22, 0xa3109862, 0x42f382dc,
- 0x11c885d8, 0xca8df3fc, 0x5c3adb89, 0x8df88588, 0xdaf9aaaa, 0x2bc89eb5,
- 0x1f5c2deb, 0x774675e3, 0xb5f1bdf1, 0x28f250ff, 0x084c21b3, 0x5d3dfe87,
- 0x1e310f88, 0x90ea7b8d, 0x460ca7dd, 0x09ac2e1a, 0x75ac5442, 0xa51a45fa,
- 0xbacc4e6f, 0x4285e653, 0x5c6cc775, 0xe34ad899, 0xca2a6f96, 0x1fb29112,
- 0xd0aaf341, 0xea9e55e7, 0x0a8752cd, 0xeaa8f6d1, 0xebf684da, 0x6a8f9e55,
- 0xa51eb8f3, 0xdbd627ef, 0x9fa9cb5c, 0x273e7d0a, 0xc5d16b7a, 0x0ab794b9,
- 0xf280bdab, 0x45da2d56, 0x54782efd, 0xb177f62d, 0x81f7aa3e, 0xf80ba0b5,
- 0x3a894d60, 0x1ea8327c, 0xe39469d6, 0x7268f7bf, 0xc2fcd157, 0x63cc77e9,
- 0xd1f7e2a3, 0xd1f44efc, 0xfc7f21e6, 0x82b13093, 0x45daeaf2, 0x2bdceed1,
- 0xa1c27de1, 0x01727b45, 0x031eb95f, 0x18e3a19e, 0x7808bcf0, 0xbabd20c6,
- 0xabf04bc5, 0xa0f5487d, 0x4be6bece, 0x98df80d1, 0xae47453d, 0x61b5f7c1,
- 0xecda8c22, 0xcefe9c3b, 0x8b8f34ad, 0x3d4155ab, 0x193dd28a, 0xdbc68289,
- 0x2e7cf96e, 0x4dbf73e0, 0xd2917acc, 0x47a7b7d2, 0x46fd285b, 0x21f51fa7,
- 0x6a352709, 0xae7cf47a, 0x98b93edf, 0x9edcc7f2, 0x7aa082c4, 0x2ce9d63f,
- 0x6b655f14, 0x718d16ff, 0x78d8d62a, 0x2e5e065d, 0xbf341d62, 0xfe118d8b,
- 0x8b9704e5, 0x5fb8dbbd, 0xbf464f03, 0x4183c015, 0xa56f544f, 0xe38fa5db,
- 0x114717b3, 0xe1b4d35c, 0x64e82e9e, 0x2e3483c1, 0xe51f5bfa, 0xff7de675,
- 0x74780d71, 0x25969be0, 0x8f03fc0c, 0xbc6da44f, 0xde59be97, 0x93d10ab3,
- 0x7d78d0e0, 0xcbdf42aa, 0x850984f6, 0xda532bfa, 0x9c09288e, 0xac14fb77,
- 0x8c3cf17f, 0x9871f657, 0xf7c7e505, 0xf3c79f5e, 0xc12bc10a, 0x7a2bb529,
- 0x96d698bf, 0xdf8209ea, 0x736d3ec5, 0x7d06be79, 0xe79bce74, 0x4c37bb51,
- 0x4c5c5f60, 0x76467c23, 0xf801b1c2, 0x5df5c619, 0x6f6fa676, 0xb1d7e01e,
- 0x7ac8575e, 0xfdeb215d, 0x0b7d3040, 0x29ebc68f, 0x82cc24ff, 0xdc0fe5ef,
- 0x71a6e594, 0x8e3bdf8e, 0xce3c75d7, 0x75fd879b, 0xcffa953c, 0xe59d72bd,
- 0x733ad00f, 0x8d9d65bf, 0xb757c64e, 0x7b6b8ceb, 0x3acb7c42, 0x6874ea37,
- 0xab33f3ac, 0xfa8ada3b, 0x9cb155bb, 0x14fb6a8a, 0xcc8d7fdf, 0xd0d056bb,
- 0x0f4936b5, 0xfc236bb5, 0x6685d7c0, 0x6e7f04db, 0xf1a01f27, 0x583d27be,
- 0x8f8e1e98, 0x023c3f75, 0xea9f75f4, 0x9701b9f2, 0x9cfcef21, 0x57efc7f2,
- 0xb1f9025d, 0x0fc47e12, 0xc70fe02c, 0x73278b53, 0xb5cdaf7e, 0xb4f9fa82,
- 0x047f6ff1, 0x63dc5cfd, 0x5f5e0b73, 0x90b3fdf1, 0xaf82f9a7, 0xc66e5c11,
- 0xebce54b8, 0xd619ef57, 0xe8f17288, 0xbba65760, 0x0214be0b, 0xaa358ae7,
- 0x01d21f69, 0x3ed5e3c1, 0x3ac6e290, 0x8713380c, 0xa83a9acd, 0x4fc81e13,
- 0x9709d41f, 0x9ad0bb5a, 0xfb12fbf8, 0xfc414194, 0x9749f00c, 0x3cff44e7,
- 0xa2d2c7c9, 0xc873f683, 0x8ff942fc, 0xff48cf51, 0xcc57c1d2, 0x705178fc,
- 0x1950e09e, 0xc21c5f92, 0xca42aa37, 0xb7ca43ab, 0xf99cfaf7, 0x13f8e840,
- 0x31bee4d3, 0xc3aa58e0, 0x9145bb71, 0xc53ee47c, 0x2d7e89bf, 0x4bedbab5,
- 0x8e2ffe69, 0x4fd0f311, 0xae385599, 0xced97de5, 0x8ab52beb, 0x7c02b086,
- 0x633d70f7, 0x435fd4dd, 0xc3e51c58, 0x7aa21f25, 0x7941ec13, 0xf31adf83,
- 0xf0934f09, 0x5bc5d230, 0x83c78d9d, 0x14dd59e0, 0xeed7ca6b, 0xee3c6e4a,
- 0xc62fcce8, 0x6ff4c92f, 0x387ead22, 0xaa7f22e0, 0x8c1eb577, 0xb249fa20,
- 0xd469e168, 0xff83c5ef, 0x66eb9d1b, 0x262f0fbc, 0xe9a816fc, 0xf5a61d2f,
- 0x3d56edb6, 0x9befd09b, 0x5f11fcf2, 0x1b787a5f, 0x9bd9af7d, 0x7775ee21,
- 0x8e143fae, 0x8a5d7717, 0x17efa74e, 0x05c3d90e, 0xcda501c9, 0xd1ed63f1,
- 0x84babfbc, 0xbb875bbb, 0x6b05dfd1, 0xa094f46b, 0x6b44177a, 0x7a20d4f4,
- 0xa975dd29, 0xfc31e44e, 0x1f106a7c, 0x8f4f74ff, 0x2f7d2ab1, 0xb1af7dfb,
- 0xe9c74a16, 0x736fdefd, 0xe686b93f, 0xe61ddbed, 0xbef34cd9, 0x0b2ce6f0,
- 0xb3785fda, 0xea7f4f42, 0x4fb3f4e5, 0xb47e3153, 0x31bbd245, 0x293488de,
- 0x8e59954f, 0xfc1a313e, 0x699ed5ff, 0xe59d69f5, 0x2c829665, 0xad9b79e0,
- 0x7de62e6d, 0x95ab1141, 0xc67eceb8, 0xfdb9b9a5, 0x9f27dd85, 0xf4f87f00,
- 0x60053efe, 0x6776172b, 0x7e5469e7, 0x5921e3e1, 0xc2f7ea2e, 0xf01ec97d,
- 0xf7366d85, 0xeede994f, 0xdf60f289, 0x9c61fd1b, 0xf77fe825, 0xa435c355,
- 0x52f9cb1f, 0xe3934f3e, 0xce8294fa, 0xee2da37e, 0xbf028f5f, 0xb3cdbdf8,
- 0x7fa59299, 0x8b19e8cf, 0x773f61f5, 0xd5b28781, 0xe26dc261, 0xde782b27,
- 0x8763c2a5, 0x1172841c, 0xa2e55f44, 0x6fcfbf98, 0x405f7f34, 0x17df027c,
- 0xaf7f37ae, 0x5aab8d10, 0xfc8b7d69, 0xf682efe6, 0xfb112f8f, 0xe269f8da,
- 0xd6f17ef3, 0xf54cc26f, 0x0fe74f84, 0xa5c7e60e, 0xc7c11fb4, 0xfefc579e,
- 0x3defc015, 0x7433af2a, 0xd2d3cb5d, 0x448f1d78, 0x6b6e63fc, 0x598f5e10,
- 0xe0893584, 0x1c2ecc7a, 0x47e80549, 0xbeab9c08, 0xcdfe613d, 0xfedee4d4,
- 0x3296a55f, 0xe0b24bdf, 0x05c3b83c, 0xedfd47ce, 0x7e8a9939, 0x791756ca,
- 0x77e6835b, 0xe47de6d1, 0xdf5790e7, 0xf54d7e23, 0x37f58d8e, 0x1d79a58e,
- 0xd4f557bb, 0x33af3177, 0xe3f99f24, 0x28f71e09, 0xf2843fc2, 0x2d4c9ccf,
- 0xde9cbc21, 0x34b5327c, 0x3115fe98, 0x8d1e982b, 0xebc26694, 0xf489ac82,
- 0xeb05ad18, 0x89d7ad09, 0x0d7cf35f, 0xb1553a78, 0x787a2ba4, 0xe54f7414,
- 0x05577f39, 0x3d9acee4, 0x33e83f36, 0x0f17e362, 0x6cfa0adf, 0xda40b9b6,
- 0x2f547bb5, 0x5bb174e4, 0x1ce267f5, 0xba34fe6b, 0xeecce712, 0x68352e21,
- 0x170e74dd, 0xb0b97ce3, 0x596252eb, 0x1933f72e, 0x9eed44f2, 0xdfa03c87,
- 0x5cf1e6ee, 0xf1affa9a, 0xff99af3f, 0x20fdcf9d, 0x81f046f1, 0xc0b2278d,
- 0x3e0f89df, 0x99fd8697, 0x791db5f5, 0x83875a21, 0x2c7e68fe, 0x7ff45fbf,
- 0xa3a5f2c5, 0xbbfaf559, 0x349ec3c0, 0x07ffc33b, 0xcd026fcf, 0x7e73b12f,
- 0xe03d9f34, 0x6b3cc6cb, 0x9c766ddc, 0xd11d17b3, 0xb4a7e079, 0x89f989a0,
- 0x06e4f9fa, 0x289b2d7f, 0xee16bf88, 0x09c2bf9e, 0xf151a179, 0x6f280f40,
- 0x2adcf956, 0xddfaa0df, 0xecc29784, 0x213bf6bb, 0xe5443e9f, 0x3abc74d4,
- 0xa8b38fea, 0x54fbc2fe, 0xf8dbefce, 0x80da3fd3, 0x11360dd7, 0x47863c06,
- 0x63c7d26f, 0x3e916879, 0x37cd45bf, 0xb7a0569d, 0x013d51ec, 0xe51cdfb4,
- 0xd5b2f7c1, 0xf4c163b6, 0x50bf1f35, 0x2bd7f37f, 0xf81a40fe, 0xc2fcb984,
- 0x27ce9f30, 0x5c6fbe42, 0x027f7535, 0x89eb2b52, 0x72e6fc8b, 0xf34ebcfc,
- 0xdf7fd5a9, 0x17a6b99a, 0x29c173f0, 0xabf60b44, 0x1df595b5, 0x054d6811,
- 0xfeec2f1e, 0xac78152c, 0xb27ff57d, 0xebf81744, 0x51cd4fd8, 0x84222709,
- 0xc6e74b38, 0xfdd01637, 0x5dc5c9a5, 0x8fb17fd4, 0x6d5b17dc, 0x63905ebe,
- 0x8afc6ff7, 0xddc5c1f9, 0x17575f5a, 0x5fb9dbf4, 0x124b4e7d, 0x205380d2,
- 0xbae4da1d, 0xe484fb11, 0x1f417bc1, 0xdd4d569b, 0x6be77944, 0xa2424836,
- 0xf7923336, 0xfcc7f60b, 0x7d8d7ea0, 0x017c15b2, 0x1fc930e9, 0xe523ec5e,
- 0xbcbad584, 0xfb5f75b0, 0xe62ecce4, 0x26cd3ab3, 0x923edbcf, 0x2b4dcc6f,
- 0x9c874f0e, 0x0345f161, 0x75ebc21f, 0x157c1027, 0x97eabe9d, 0x3df0512d,
- 0xda723449, 0xfa71345b, 0x245a10b8, 0x0b8f0bea, 0x4fa21670, 0x7bc7e02c,
- 0x31abd79e, 0x8e89fcdf, 0xd06af03b, 0xf8562f83, 0xeaefd337, 0x63508746,
- 0x46b5ed20, 0xa0d451a3, 0x4beebfa9, 0x540fb6e5, 0x3ed49fd6, 0x2e3d3e06,
- 0xc8cbf7e0, 0xf8c131e9, 0x74b877db, 0xdeabfa02, 0xf52e7a49, 0x4d877e77,
- 0x5957a004, 0x3d50bf69, 0xec2fe1db, 0xcd4be069, 0x5cbc808a, 0xaf7c794b,
- 0xfaf5651d, 0x9792e083, 0x9a91e12e, 0xbb70c59e, 0x9a1ef560, 0x9573fa08,
- 0xdbd721da, 0xc04f970e, 0x2a4b6379, 0xfb5e63b5, 0xa4758f0e, 0x56b16f01,
- 0x9aab37de, 0x5c5b718d, 0xf62a3fe8, 0x436f9e03, 0x534445ae, 0xc28f86bb,
- 0x874c0cfc, 0x3a6143e4, 0x85021b5c, 0xf817770e, 0x14c289f1, 0x77ca8231,
- 0xcf3013a8, 0x1752aef3, 0x958b68f0, 0x9b308776, 0x9af40277, 0x78b8d8b0,
- 0x7a446fcc, 0xabffcf06, 0xcf3c25d8, 0x80bc48af, 0x7af241be, 0xbd0df231,
- 0x7d8655cb, 0x8fbc23e3, 0xfc721d6b, 0x9f2a3da8, 0x43a462a3, 0xbbefdbe7,
- 0xc89c68ca, 0xd024dabe, 0xa89f3183, 0xf00baf61, 0x858b1ce7, 0x3786b3e5,
- 0x2f80d722, 0xd21be518, 0xf819bd25, 0x75609958, 0xae3c7f81, 0x574ae7d3,
- 0x6820a3b1, 0x161eb69d, 0x0ec55e1d, 0xbdbb69c0, 0x97ce10f8, 0x738efa36,
- 0x54d27f73, 0xaa14f407, 0x273f4167, 0x64c768ea, 0x0ee9dfa3, 0x424177c0,
- 0x5bb478e9, 0xc2ac9628, 0x5eb85b7e, 0x3e208115, 0xe39360db, 0x211cb82e,
- 0xc73a4302, 0xe3f8405d, 0xf9a397f6, 0xd653837b, 0xfb92886b, 0x2974cee7,
- 0xd3d4ae2f, 0x83fa7ab5, 0xccc7baf9, 0xfec7cfd7, 0xe4a94b71, 0x53a677ef,
- 0xeb4ad5bf, 0xab268878, 0x80edda92, 0x973a89ef, 0xcd058408, 0xc6758af7,
- 0x38d0408b, 0x3b2ef51d, 0x183e2045, 0x47c66e1f, 0xb9237ae7, 0x125d44fc,
- 0xfefbb1c3, 0xec704c53, 0x04c33fec, 0xcffb2bc7, 0x7513f2e2, 0xffd1df39,
- 0x4ffa6ec0, 0xb3bfcd33, 0x5dfc7edf, 0x82fad2ec, 0x22eddcbf, 0xd374c07e,
- 0xbb2676ca, 0x7606fda2, 0x9871f12f, 0x95f7dc80, 0x0576cb53, 0xe96d87f1,
- 0x0b9f5d76, 0xfadf80a4, 0x6b4e3ac4, 0x8f1a5d77, 0x0be26ef6, 0xcbd0e76c,
- 0xcf1b456b, 0xfa02fc13, 0xbab648bd, 0x96977cb9, 0x98c8bd0d, 0xf33c8747,
- 0x859f48bb, 0x9ed841f6, 0x1f6347bf, 0x4db6b45f, 0xa9aa7d86, 0xde088d59,
- 0xfdf407d7, 0x17cfb631, 0xd5d7b079, 0xbdf11da0, 0x9c5dee9f, 0x84d4f80d,
- 0xde61e5b5, 0x2dfef7fb, 0x57c8e70f, 0xc5f7167b, 0x9f54adf7, 0x5b7b0fe5,
- 0xbfa8278d, 0xb3e5c27e, 0x9b4ce88c, 0xfa1ffdf5, 0xfa9eeb7d, 0x36c7985e,
- 0x2e483dd8, 0x56f659ac, 0xb078f1c6, 0xe083ef21, 0x16f8825f, 0xa6bb43eb,
- 0xdf2063a9, 0x0f32487d, 0x96ee87e5, 0x3ed0c372, 0x83496fc2, 0x2ce1f7dc,
- 0x619a89f0, 0xe1541776, 0x9616fcf0, 0x3987c3b7, 0x9f9f385c, 0xebc193ed,
- 0xc84e43b3, 0x78a2fb40, 0xf154e7a6, 0x1b6dc9af, 0xe04ff642, 0x68db350f,
- 0x75b56abc, 0xf78538f2, 0xa9f031d1, 0x78bfb79a, 0x135fd747, 0x8c5a9f81,
- 0x5f78f04b, 0x432127ef, 0x9a7a893b, 0xabbef5a3, 0x9b8cdea8, 0x1fa15393,
- 0x99fae895, 0x19404898, 0x1068fcc9, 0x9e5720ec, 0x7a0f52db, 0xc034d14d,
- 0xf0ec97c1, 0x981afce0, 0x71c91c22, 0xf4fed0d8, 0x57ee34a9, 0x2ec316e9,
- 0x03de60aa, 0xdf3d35f4, 0x2c6969ab, 0x38fe939f, 0x3b3fd1d0, 0xfbc325ae,
- 0xa30bf077, 0xdf3787fe, 0xe2eb483a, 0x79e430dc, 0x36e9bdbb, 0x3aadb3cc,
- 0x9847f592, 0xc9eed0f3, 0x2a02c39b, 0xc8b68aec, 0x3fe7d0d5, 0xb07b988a,
- 0xfee3c107, 0x83222d28, 0x799acdda, 0x95e42ac3, 0xa5eef1fd, 0xd692e7a0,
- 0xd3e7c0e1, 0x83262d4e, 0x6872afc6, 0x8969137d, 0xd968fbe7, 0x8be43831,
- 0x449e25e3, 0x2ee2a0f1, 0x53e72fe7, 0x0ff1c8a2, 0xe8496947, 0xf2d2c4a7,
- 0x66f855c4, 0x837b616d, 0xfdc1e868, 0x8a8bb79c, 0x037fe4ae, 0x75f4470e,
- 0x6b89b3ec, 0xf6fad32f, 0xd4f18dad, 0xefcb7cd3, 0x96b7399e, 0xe296f9d2,
- 0x9a6a80c4, 0x55d61677, 0x9be92be5, 0x79f3f24c, 0x65ef3e9b, 0xaeadbcfa,
- 0x1cfde0ac, 0x437aef3a, 0xc285f95e, 0x50ff20fa, 0xac5f15fe, 0x87ca5eff,
- 0x307d2e59, 0x20d6e70d, 0x3649db0b, 0x22ded384, 0x7d5df23d, 0xbed38f9e,
- 0xf7f1c473, 0x149ef8d5, 0x3d27db2e, 0x7ec3f16c, 0x37763c50, 0x9ac9e9e3,
- 0x634a8f48, 0x1db70895, 0xf0995072, 0xd9fc5cb2, 0x69edbf98, 0x661575a5,
- 0x6e01d768, 0xa92de2f3, 0xb43cf01f, 0x6f205381, 0xf8eb928d, 0xd7937916,
- 0x6cb85531, 0x3589942c, 0x531fc816, 0xf329725d, 0xa63fb915, 0xe30daf09,
- 0xd71a10cd, 0xbb05c3fb, 0x1fc4fa17, 0xbcd10ba0, 0x7f1f0a67, 0x9cfc2d9f,
- 0x5c022ade, 0x95a2c7ff, 0x89bc06f3, 0x4825e63e, 0x53d938fa, 0x8cdff865,
- 0x9117bf79, 0xad1967d7, 0xd923ca63, 0xad5fac99, 0xf9f0c1eb, 0xd14f79ae,
- 0xeff686e9, 0xfd83f43c, 0x99fa9d3b, 0xfec8637a, 0xe061ec2d, 0xf6dbf333,
- 0x877b4b51, 0x4c9914fe, 0x475eb870, 0xc5def5e9, 0xa9153fac, 0xf847c291,
- 0xfaa51969, 0xf21c7721, 0xa0484f2e, 0xb9fddc75, 0xb77e83d4, 0x843dbc5c,
- 0x46377fca, 0xd2dcf515, 0x64d4f2cb, 0xbdc99fbd, 0x9d869fc7, 0x2408b0f5,
- 0x17b9a50c, 0x8f5ed65d, 0x564ef9a1, 0x52c435b7, 0xa4de84f9, 0xbdf104c7,
- 0x5bb6121b, 0xd8ddd7a1, 0x627dfccf, 0x99df59ae, 0xc0551a24, 0x7350f279,
- 0x0f807dbd, 0x0c8ad7d1, 0x0188b7a9, 0xdfee8062, 0x47fbb963, 0x13ed1f7a,
- 0x0be1d92f, 0xbb433579, 0x3a5c7007, 0x18b9b3e9, 0x7ae55857, 0xd951de6a,
- 0xe48c779e, 0xdf9d2f2c, 0x84e8ebc7, 0x08f29308, 0x6e48a7f2, 0xcea67a40,
- 0x3a39e9cd, 0xa17e51e7, 0x67eb23ce, 0x7d803f14, 0x73faba56, 0xb772f02b,
- 0x6ef9c253, 0x761faa67, 0xc6a68ab5, 0xe55e98f1, 0x4883a6ae, 0xe3c503cb,
- 0x382ecc71, 0xd220e4b4, 0xb6f43bbb, 0x5fdd0e25, 0x5dbff3c0, 0xa3dbd3a7,
- 0x8834dea6, 0xbbedc9f6, 0xf6ebdfa5, 0x4da7533e, 0xc6de404a, 0xa8e8eef9,
- 0x3422b2fa, 0xa8cf22da, 0xb758cdde, 0xc1e8f9b7, 0xc9e75a78, 0xff3c11ba,
- 0x9e5e75d3, 0x09bad9ff, 0xa33dfe9c, 0x27ae39f8, 0x6c79673e, 0xd6a3b6d2,
- 0xe45faa14, 0xb7d8bc55, 0xdf857ad7, 0xdeb1744f, 0xf581cf26, 0x1f600e74,
- 0xf534198f, 0xe9303bf1, 0xda276d0c, 0x5171b8cf, 0x3c99c611, 0x7a8ac4a2,
- 0x2216bf33, 0x4e93ad3e, 0x8dee8bbf, 0xf8eb57f5, 0x6157bf3b, 0x1bdf9e78,
- 0xdf6cf0cb, 0xf9031191, 0x8ccee960, 0x6f89489e, 0x046f7a1a, 0xd97ed7e0,
- 0xff6df3c2, 0x8ef59c28, 0x774bf6d0, 0x7a89ec0e, 0x22df0967, 0xfb3cde48,
- 0x83b87ffc, 0x71b395cf, 0x027d5f4d, 0xc957f6fe, 0x39b248df, 0x5ff818f1,
- 0xd01e5eef, 0xce5d05cb, 0x02233d26, 0x6e8d5fe7, 0x427f0457, 0xb4b86cfe,
- 0x217f0ee7, 0x17f62c65, 0x9c1373c6, 0xb9191cc3, 0x7f7087c7, 0xfd467e47,
- 0x9258fcbd, 0xb9effa07, 0x63a48fed, 0xf34dadfc, 0xfa8c793f, 0xf8b7ef3f,
- 0x9d4e746c, 0x5e174d17, 0x2a7e1f05, 0x777bed92, 0x9c2f342b, 0x717b9bc3,
- 0x86b1473e, 0x2c39c32f, 0x73cfbcfc, 0x1975b714, 0x17aaadf1, 0x7a05ed1f,
- 0x30608d7c, 0x5b5fca82, 0xed7cc11b, 0xc8e79b35, 0xb8f7f432, 0xfbe9efec,
- 0x0bb63cef, 0x05d57de9, 0x65fa5277, 0xa1e31c46, 0x034581fc, 0x79ce9ed0,
- 0x3dfd4c91, 0x80128af7, 0xbad06abf, 0x69922b7d, 0x1c37837e, 0x34a2f4b5,
- 0x1ea529ff, 0x373ec0e9, 0xf9fd821e, 0x6e6e196f, 0x9a5b643f, 0xd96d829a,
- 0x75c9ffcb, 0xe59bfe7c, 0x9f75dc82, 0x3a25ed8f, 0x4a0183e5, 0x348d99d3,
- 0x8fd4b0d7, 0x6386340a, 0x6767af23, 0x6ff7b4f3, 0x49075815, 0x8977981e,
- 0x91e7c3dd, 0x7811b7df, 0x78e5af3e, 0xf62bbf58, 0x3b7a0a3d, 0x707a25af,
- 0xfa4cbd3e, 0x7fa8d5fc, 0x7cebcac4, 0xa2f7a9e5, 0x2189df61, 0xbf09d93d,
- 0x78db7e48, 0xe3eeafd4, 0xf587f016, 0x09fae279, 0x8ecd4f80, 0x9fb91b9d,
- 0xfa07872a, 0x4bcec56e, 0x2f205307, 0x993c20de, 0x321dc7a0, 0xaf42abff,
- 0x56a5a547, 0xe652fc6c, 0x5f398a5b, 0xfc27da4c, 0xca4ca2fe, 0xe7e88f49,
- 0x63cd68a0, 0xee24c97e, 0xafd7c4ee, 0xebe518a8, 0xb0c97cd3, 0x27e71b6f,
- 0xfda97b9d, 0xb2ec65b0, 0x5bd8cb7d, 0xdf2e1953, 0xebb3dcf3, 0xdfd197e7,
- 0x73e17623, 0xdf303f52, 0xc1be9ec0, 0xcdebcf2e, 0x2f4067c4, 0xe34d79c6,
- 0xed93f5e6, 0x29afe0bd, 0x076832aa, 0x91e523c1, 0xbe379630, 0x62b3f8ef,
- 0x6df9f156, 0xe1b55bc8, 0xd9f22f92, 0x885fed41, 0x37eeaed2, 0x7932760c,
- 0x3bab0bde, 0xe3c8f217, 0xfa6bde51, 0x96d5bcb1, 0x39d0358a, 0x53e61d7a,
- 0x95fc92a3, 0x457f2411, 0x73af7dc6, 0x2de51034, 0x5beffb42, 0xcd046c7f,
- 0xf1290633, 0x86a468ef, 0x485a45de, 0x7d39fc97, 0xf3f8135b, 0x3f926143,
- 0xbe610d47, 0x7433ac64, 0x07c4039c, 0x6f3be234, 0x11a339d0, 0x3917183f,
- 0x7d78cac6, 0x907552dd, 0x3922e5ce, 0x1ada0802, 0xdef3943b, 0x61638228,
- 0x2eb42aa4, 0x252347f4, 0x3ac7cdbc, 0x984427c7, 0xc42515ea, 0xbf8fb1da,
- 0x1d55faef, 0x3cb86a4f, 0x8370d4bf, 0x7413babf, 0xfac87dbf, 0x776f7ae5,
- 0x3abe630e, 0xeb7ef956, 0xdf15b22e, 0x8b8f3c09, 0x7373e7cc, 0x2394e45c,
- 0xd475e09a, 0x7ae87be1, 0x1c25d743, 0xfa8e4fdf, 0x167c2289, 0xedcfc7ec,
- 0xb66b776c, 0x5bf73eb5, 0xa2f36b82, 0x47ec0f5c, 0x70bed32f, 0xb54e9f80,
- 0x0cdb9cb3, 0x37ea92d9, 0x5c7170f7, 0xdfba6bcb, 0x6f5b37dc, 0xbe7c14ef,
- 0xc5eecf34, 0x615ef47e, 0x48ec1034, 0xd26fd2f5, 0x16f25b6c, 0xe5e6ebce,
- 0x819a1e29, 0x69efc150, 0x97e47ccb, 0x095ebcfc, 0x817f0adc, 0x40bb73ef,
- 0xfeb175fd, 0x5f94e9d5, 0x9e0c8bf7, 0x8fa447cf, 0x8abc62d7, 0xeb5be670,
- 0x71c9bd62, 0xff979f04, 0xb279f2a1, 0x91f29f2e, 0x6ed9d7cc, 0x378a6eb3,
- 0x04ad7e19, 0x36eb6f1d, 0xb05ef2ca, 0x4d3ca293, 0x26c4ffb6, 0xd7a2dfeb,
- 0xfbf1d04b, 0xb4a74eb1, 0x683f99ff, 0xa0ac2393, 0x95fb77ff, 0x46fbc6be,
- 0x17e19378, 0x933cac7a, 0x54b7986d, 0xf4c690de, 0x66d3dba4, 0xe8dcfce9,
- 0xc31c0d17, 0x9fcb4f21, 0x3b37f3d9, 0x2a33df41, 0x1f21479c, 0x22b1547e,
- 0x0cfd7a0a, 0x21840d4d, 0x917a6abe, 0x4bae43b7, 0x395eb8c7, 0x1fa1b96e,
- 0xdf00ca06, 0x710e6dbd, 0x81ffcb2f, 0x96fac121, 0xfa45e781, 0x1a6eadbe,
- 0x7eb060f3, 0xfe27695d, 0x72e51833, 0x6a45573f, 0xd57d07bf, 0xc1e1baee,
- 0x54fbbd60, 0xbc7943f9, 0xcf71f4ef, 0x3c1f79d5, 0x6f39099e, 0xb8c6a702,
- 0xf011fa1d, 0xd5f6fd49, 0xefda73cf, 0xdaf00b3e, 0x92fa94e4, 0x85e3edb5,
- 0x359faf94, 0x09f7cf80, 0xd85e1d53, 0x8477daf5, 0xadaf61f9, 0xc5ee159f,
- 0x44f7eaba, 0x985761f9, 0xd21befa7, 0x6fbbf8bb, 0xade98dbb, 0x667feeca,
- 0xdaabb50b, 0x89e99fdb, 0x96ed95e8, 0x642357be, 0x6d37b479, 0xf79450e5,
- 0xcd79fa64, 0xf2e18ee6, 0xe5c15537, 0x58ac81e1, 0x539b7782, 0x1375853b,
- 0xbcfdb2bd, 0x1fbf2eca, 0xfa12e9d1, 0x96fffb25, 0x42bf7144, 0x8f3f6bcf,
- 0x584f7d67, 0x91f3c9bd, 0xaf207dbf, 0x7dcbb347, 0x7ea46a21, 0xe725c478,
- 0x9e39a475, 0x8f4185f7, 0xdcb78a47, 0xef809593, 0xfcd2af24, 0x0d4cb2fe,
- 0xd06e1fc0, 0xf2f5329f, 0xbb5157db, 0xd9555f4f, 0xd7e7336f, 0xfbe30f8b,
- 0x13d5159c, 0x6bbcad39, 0xf5cb9f32, 0xa2eea71f, 0xa7a984f2, 0xe06bbfd8,
- 0xd9954e7f, 0xe9989a9f, 0xdf813355, 0x83f6ff5c, 0xd9e1ff54, 0xaf001627,
- 0x473533c3, 0xf6dbec26, 0x4cff97d6, 0xfe5d6df3, 0x36a3d627, 0xf8116b44,
- 0xd3f7717e, 0xc566bf5c, 0x7e802cff, 0x74956350, 0xb5db9c63, 0x91bf3d3a,
- 0xffa2c5a9, 0x63bf15aa, 0xb722223d, 0xbbd7f245, 0x3a3f1fbe, 0x65f9bcd3,
- 0x0e2dda85, 0x54e1ae6f, 0xfce1e7f5, 0xa204ab3b, 0x2b860c95, 0x5ce775eb,
- 0x47e06881, 0x72b948b3, 0xbf10d6f1, 0xa8925031, 0xdda88bdb, 0x8f5526e2,
- 0x41dbf457, 0x17f5a1a7, 0xf7ae77d3, 0x8a57bf3d, 0x763df926, 0x30d7fdd7,
- 0xfe0045fe, 0x64cf33ae, 0x9c3d026e, 0x5674f9df, 0x34369fb0, 0x72be72bd,
- 0x7df4e7fd, 0xd8be8e73, 0xc2db6f40, 0x0b85f64c, 0xf4eb24cf, 0xc2e9e926,
- 0xe7ecd933, 0xd9f7d44e, 0x0967c505, 0x085fbb47, 0x9e10678e, 0x971ce1a6,
- 0x0e1a6de3, 0x9d61fbb9, 0x6f8e2e2f, 0x67be0e1a, 0x68e141f0, 0x41bb63ca,
- 0xf41e534e, 0x8a7f8364, 0xfe2ca6e2, 0x42ca6fee, 0xd22d97fb, 0xa7cc630e,
- 0x8e14b9f2, 0xf0b5a27b, 0x6e7caefe, 0x8de426e0, 0x929dea71, 0x253bd4ef,
- 0xb75d097f, 0xe8ed2996, 0x1ee64fa4, 0x3ea4b3a7, 0x5c82f496, 0xde6593e4,
- 0x370bf329, 0x6fe1d894, 0xbcc9b7af, 0xfd897d6b, 0x35f7e618, 0x4fc4b569,
- 0xc5bf7473, 0xdda97f02, 0xfafefb0b, 0x3f1ce1e5, 0xcf3edb31, 0x7af6694b,
- 0x035c69bb, 0xe6fdfd0f, 0xf9f48bef, 0x0b890df4, 0xedb6a5ea, 0xf639c30b,
- 0x8e32e8a4, 0xb4a64960, 0x6cfb3ee3, 0xaa917c47, 0x6dc2dbeb, 0xea5ba1d0,
- 0x8fd78c1b, 0xef5e06ed, 0x2ff9a148, 0x5ea5e3d6, 0xfab848b6, 0xe37c959e,
- 0x052d7ce5, 0xc005d5e7, 0x2c5ce71d, 0xef2173e5, 0x7919bc49, 0xf0a15f03,
- 0x82f1f15d, 0x9f95d814, 0xc7f694c8, 0x8f2c7c50, 0xe513de1a, 0xd4cf5c06,
- 0xdc00ca1d, 0xa89d758d, 0x68e97af3, 0xafbfb4eb, 0x8c6877cf, 0x30477c8f,
- 0x1d6fd77d, 0x20248872, 0xd5ab6e71, 0x5bd42583, 0xbf43f7fd, 0x36aadfa8,
- 0x3b9704f9, 0x91739780, 0xbd41dffb, 0x0b621b05, 0xed180fa0, 0xf22fae17,
- 0x7bcd0796, 0x5e3356e0, 0xf3993506, 0xf3997783, 0x0d06715b, 0xe5dbe7fb,
- 0x21f9cc07, 0x93f9cc87, 0x3371dc1f, 0xea854fb6, 0xbe855fbb, 0x87f1e7f3,
- 0x7a9f4e70, 0xe06895f9, 0xcb5ff16b, 0x0b8f420f, 0x3c21678d, 0x7c73d02a,
- 0x97a6145b, 0xba5ae22b, 0xdc4643e1, 0x30627606, 0xdf0a54dd, 0x95da6b41,
- 0xa68acff5, 0x6744bd9b, 0xcfdecb55, 0xecb37a90, 0x5ad36477, 0xd0cee43b,
- 0x3be3bb71, 0xc6ebd222, 0x21192a3e, 0x365eaecb, 0xfe8a7c4e, 0x1e37bcd6,
- 0x2bf258f4, 0x929be585, 0x075fb297, 0x3edd1cdd, 0x6f4e46fb, 0x30f0c09e,
- 0x9b0b92ec, 0xe5144095, 0x8744235d, 0x8bf11f7f, 0xf1210da5, 0xe2426b9f,
- 0xcb99d682, 0xf7daee17, 0x504710ff, 0xe38278e1, 0x678cae2e, 0x5e801ff4,
- 0xb04a7959, 0xa9f2aa7d, 0xe5ccc26f, 0xf5f35d72, 0xade71875, 0xf1cb5df0,
- 0xaacb577b, 0xa3fe38e2, 0x4ba8e973, 0xcb73853b, 0x5eaf7738, 0xf29551b7,
- 0xfd84b7bc, 0x8e7691c8, 0x8876ac8b, 0xebcd0440, 0xebdd9450, 0xd697efa2,
- 0xb2bcb147, 0xe85ce480, 0x270a948b, 0x627a4dc7, 0xbbc4eed0, 0xd565cb2a,
- 0xd51e12f1, 0xb0fc51bf, 0xa8c3571d, 0x3293fc8b, 0xd80448bf, 0xf23a0bbe,
- 0xf803ad06, 0x468bce0b, 0x59565fa9, 0x9f00fb03, 0xab68738e, 0xad155eb9,
- 0xc838a3f3, 0x35efe67b, 0xd7eb8da2, 0x2c26faee, 0x3d907bf8, 0x435ef59a,
- 0xf97556ff, 0x3865fd4a, 0x20744fcb, 0x6cbe8384, 0xeebedcba, 0x6823921e,
- 0x7b0d2b7d, 0xdf295af8, 0x9e51b2dd, 0x679f2463, 0xd6eb4e01, 0xef867c92,
- 0xce206fa4, 0xf70a2c44, 0xea5ef94b, 0x6766eb0b, 0xf2f45cb1, 0x400a5e3f,
- 0x487b691f, 0xbad2bb61, 0xbaefd97c, 0x3973fafb, 0xe3c2a7f8, 0xb61cb184,
- 0xde518a6e, 0x4f91f587, 0xc864c530, 0x1ef7faf9, 0x4bdefe6e, 0x3ec166f5,
- 0xb2741e22, 0xfb90c47d, 0x2ebeb90d, 0x1ac9cb56, 0x75feb9d6, 0xf0516db1,
- 0xf88a89bb, 0x6cb725ef, 0x36e3cfd6, 0x2afc3f5a, 0x83e295c7, 0xf5198ff0,
- 0x73c96646, 0xef58f865, 0xfb1ebd16, 0x532dca5f, 0xe68ebdee, 0xc5b0fe55,
- 0x81a17b0d, 0x66f5e107, 0xd7c70e01, 0x77400b3a, 0x7b4ac7c3, 0xc97c91d9,
- 0x0a8623e7, 0xab1a378e, 0xcb363bf7, 0xc2934a62, 0x9fa91e89, 0x1ed245e3,
- 0x98b4351f, 0x132496ed, 0x6e2aebcc, 0x4fdeb265, 0xf7f8bdb9, 0x4f98bba3,
- 0x4a145d07, 0x6df8fbf9, 0x2f3926ca, 0x0e27c72f, 0xf6c9c07f, 0x39fae3ce,
- 0xe881e064, 0x0fcb1868, 0x0d8b5f3a, 0xa0b59ba1, 0xa0879c07, 0x6e982507,
- 0x8b7174cc, 0xee2be122, 0xbaf7f293, 0xe8379958, 0xf13ff482, 0x229ba0bf,
- 0x4eeff0c1, 0xdbd6340f, 0x74481e9d, 0xd07408b0, 0x0e842f51, 0xec3fd584,
- 0xa542fcdb, 0x2b876223, 0xab148284, 0x17ce21f0, 0xebc32467, 0xb11fab1e,
- 0x12adbd78, 0x92ac7d2f, 0xf1b4e8ee, 0x7d701785, 0x4b7de22f, 0xbc285c1e,
- 0x4524bf54, 0x1fad7db0, 0x713155c9, 0x45204edc, 0xbb0a8e58, 0x5f68a513,
- 0x2ffb2312, 0xfe3829e9, 0x5af3fa8e, 0x36e674e2, 0xc15efe1c, 0x47da0572,
- 0x9f7b7017, 0x5af7b645, 0x219bed29, 0x95b698f5, 0x5cbf1c61, 0x2c9f7772,
- 0xb1c4c9d0, 0xa2393a66, 0xde9195d3, 0x8dd6ed94, 0xf0249e75, 0xfe86d283,
- 0x3bd4de7c, 0x0277ab8b, 0xb047cf9f, 0xeab259fc, 0x618693c7, 0x7bc42f7e,
- 0x9333c280, 0xa83fb3b7, 0x4ff661b4, 0xb4be843e, 0x2bdfc9d5, 0x59f5b5b2,
- 0xf715ff90, 0xa1f49ddc, 0x7b01c674, 0x9ad7b512, 0x957f9ca6, 0xedbec9d2,
- 0x989e40ef, 0xfae55d3c, 0x3fb48593, 0xce39068b, 0xd6e7df24, 0xd26fea24,
- 0x69c38528, 0xa95d3a8e, 0xa40fc1b7, 0x2ca9f7e3, 0xe47f9745, 0x5592813d,
- 0x73d2b27d, 0xc9213fe1, 0xfd390bb8, 0x18fea353, 0xa5e40365, 0xfee4e3be,
- 0x1fa3ea33, 0x4b3a7bf4, 0xd5bf55ca, 0x09e462e1, 0x7cbf5cae, 0x8cd1d875,
- 0x40b6a468, 0xfde9a536, 0x7584bec7, 0xe3174c4e, 0x77ee03d7, 0xcf1362aa,
- 0xf984adb7, 0x1b965442, 0x4291abf4, 0xd6e3facd, 0x8f27ccfe, 0x7a3b698e,
- 0x6e8fe537, 0x8ced241e, 0xbe617dba, 0x707cb04b, 0x77e48c74, 0x98239b6d,
- 0x5ab88ffe, 0x3da4e2a3, 0x650ded8e, 0xb67c493a, 0xf87efeac, 0xed22cbb9,
- 0xcc7e7147, 0xc71a687f, 0x53ad9427, 0x07b86103, 0x6f6cc6b0, 0xded48aa8,
- 0xb5087ec6, 0x07da841b, 0xa3a03340, 0xd30a35f2, 0x8f7adf61, 0x9cf9993d,
- 0xcafac2e2, 0x70fd0323, 0x9c7b940e, 0x857cc71c, 0x826be0fd, 0xb9d870fb,
- 0xb5890705, 0x009f6b67, 0x258d254e, 0xe446efac, 0xfabfcc6a, 0xec1704aa,
- 0x26fe9d17, 0xbe0b5ec2, 0xc64d6d64, 0x9655fcbe, 0x3130f19b, 0xc91595ce,
- 0xfbe4ed74, 0xae6d4711, 0xe8efcc2c, 0xe705a74a, 0x9215c4ed, 0x39df69be,
- 0x1ee18f70, 0x3f0708ab, 0xfb259ad8, 0x5adcb39d, 0xbdf291bc, 0x151ac21d,
- 0x67cafa07, 0x5fd85efa, 0x75e62dfb, 0x046217ea, 0x35b289e4, 0x74bce56b,
- 0x96d610fa, 0xe71a78c2, 0x02b4e6d4, 0xe43a01d8, 0xdb63fedb, 0xba0ec701,
- 0x3d30ae98, 0xc10e7ad0, 0xbfde9c8e, 0xe9ca32f4, 0xcbd03efb, 0x7e81b1c4,
- 0x522f1b88, 0xb6be38ab, 0xe078493d, 0x6d176c77, 0x93b48f2c, 0x67be023c,
- 0x9f8319f0, 0x1d785d10, 0xdef89d89, 0x22534752, 0xceb5be1e, 0x75b3e9c1,
- 0x7825612e, 0xe24bab6f, 0x6e750bfc, 0x72ea9b4e, 0x758bfbf8, 0xa8efce1e,
- 0x97f9c11b, 0xdf9cbceb, 0xd3813755, 0xf98aeb57, 0x08afc1bb, 0x0c97cc3e,
- 0x27f063be, 0x3e0cbe83, 0x73574a15, 0x17b8cc09, 0x1f99ed41, 0xeb107c1a,
- 0xf27414b0, 0xe9cf0327, 0x092fb14a, 0xceb450fc, 0x5228ff06, 0x0aff3dcf,
- 0x22bdb9c1, 0xed22ed92, 0xf6c1f242, 0x079f0748, 0x0bb176a9, 0xdbfa89f6,
- 0x0eef47bc, 0xad6f873a, 0x88358450, 0xc4bc7f8e, 0x7441ac29, 0xac596f3c,
- 0xd9673f29, 0xa4f46ffb, 0xd18ddffe, 0x1e69b372, 0xe2797e47, 0xf7d13ff1,
- 0x4cf2fcdf, 0xf34ef026, 0xc608fcd8, 0x9f5c2bbd, 0xd79cab47, 0x9796765d,
- 0x7d4b86fa, 0xd4b86fab, 0x08e3f0b7, 0xa23dcf8a, 0x2d24a3e3, 0xb1a79df6,
- 0x9baeec6f, 0xb44ec047, 0xfa4bde52, 0xf2a3f804, 0x2bf8e8bf, 0x70c6165d,
- 0xf7d06d2d, 0x36dc706b, 0xb258f5c1, 0xf14ef960, 0xd7bf010a, 0x03d85fb1,
- 0x63882b24, 0x40afc38a, 0x6be52276, 0xab98ec0e, 0xe411f77f, 0x21d96576,
- 0x4735b396, 0x087fc724, 0x705ced9f, 0x83b2ca7f, 0xf6b44f5c, 0x466fc536,
- 0xc1daf50c, 0xc0e34037, 0x7ece695f, 0x1a2efd81, 0x547fbe15, 0x5f2f7fae,
- 0xa2e298ad, 0xf2ab6467, 0x959645de, 0x4259f3d3, 0xf91a473f, 0x96e832bc,
- 0x61c708f8, 0xdbe63796, 0xe7f10417, 0x597bfd52, 0xa714c58e, 0x9d967f79,
- 0xcd8f39fb, 0x9bdefd49, 0xcf9f6e93, 0xf7cdcffc, 0xa5fa8c05, 0x60ab0539,
- 0x835d2e4f, 0xf6cea6a8, 0x7d56d925, 0x7fa92e5e, 0x8b5ce839, 0x2ea2f8e2,
- 0x9e4307cf, 0x475f8539, 0xef59fcf2, 0xb9e17caa, 0xac8fe017, 0x9f1873fc,
- 0x75839553, 0x7fae4afb, 0x839634f8, 0x70ca91bc, 0xff12e1c8, 0x35fdcf85,
- 0xb55d711a, 0x97bda43b, 0x6b48a3d2, 0xfb60aaee, 0xf6878d5e, 0xadf81c49,
- 0xfaffefd9, 0xfbe67f0b, 0x14b0849d, 0xe3986e3d, 0x7c766ad4, 0xb06bf1ca,
- 0x7286f9c7, 0x1d5f1c7f, 0xf956beda, 0x4257f59a, 0x68a7c32c, 0x3c8997cf,
- 0x12979d8f, 0xf76ae7c1, 0x2aec4cac, 0x1fb4288e, 0xb0c1ce23, 0x358ad5ff,
- 0x59cfc39f, 0x9384d77b, 0xff65de92, 0xca1eeda1, 0x31384a8e, 0xeec62050,
- 0x5893b62a, 0x2c9fc705, 0xed38edd5, 0x63f64cfe, 0xd7772777, 0x2446a7ae,
- 0xdd5bb592, 0xbeb38831, 0xae84c428, 0xb649f4f0, 0xd3cf6b94, 0xfb3f823e,
- 0xe59536e2, 0xa2db8bca, 0x6cd43f78, 0xe220f07b, 0x529e6b04, 0x2d58edd8,
- 0xafce385a, 0x1c2a8766, 0xec1de7c1, 0xcfddf147, 0x5173f173, 0x8b5f404b,
- 0x66ef149a, 0xc3bb4f9a, 0x6823d31d, 0xbe80af3e, 0x87173488, 0xff470d35,
- 0x079ffcc6, 0x37920b7f, 0xc83f3517, 0xef548df1, 0xbf37cb02, 0x3c38e08d,
- 0xc1dec93a, 0x186ecf3c, 0x45f5fec2, 0x586bdb4d, 0xe116d83e, 0x8ce9e982,
- 0xe40f7ccd, 0x81de3e80, 0x9c8f296c, 0x67d1edd5, 0x1f59505f, 0x2fb13cc2,
- 0xb871e8cf, 0xf537bb46, 0x4b666f76, 0x5b26a7f9, 0xfea34fee, 0xd1a3a6a2,
- 0xc9fea8fd, 0xfa73ef5d, 0x166fbebe, 0x3df0b645, 0x223b93cf, 0xc9e09ef8,
- 0xfe39ff1d, 0x7cef1a35, 0x250498d3, 0xc89d9f68, 0xba7dc9b6, 0xf32fc641,
- 0x13d61725, 0x673d789a, 0xac28a5b7, 0xa4de032f, 0xf1dd9fb7, 0x3643df12,
- 0x1c1febe4, 0xb14b382f, 0x18a3dc86, 0x8d72083d, 0xd7bf55a3, 0x63dba6d1,
- 0xaffa6ffe, 0x5927bfd1, 0xe471f58a, 0xc4610d3d, 0xbd64b86f, 0x27b73522,
- 0xc1dcddf6, 0x97b899ee, 0x7192de2d, 0xfbb7a297, 0x737fe811, 0xbb678ddf,
- 0xbb9b52cb, 0x1c5ff227, 0xe0958526, 0xce887733, 0x875a9257, 0x347bbec1,
- 0x8615ca4d, 0xb56aad3f, 0xbf04bc22, 0x3e67445e, 0xd0aafde4, 0x49c90760,
- 0x563d7c67, 0x71daf161, 0x99d9463e, 0x3bb7ea2e, 0x75bec137, 0xec7c2ec4,
- 0x29d17b7f, 0xd2e927fd, 0xf618f20f, 0x7155a517, 0xd878ac81, 0xa9ba74f1,
- 0x41e54a9a, 0x29b553f4, 0xea390590, 0x2bda5d9c, 0xa9fd0e51, 0xabd640aa,
- 0xfd14e9d7, 0x69a3dfa0, 0xf72c0bae, 0xd0128cee, 0x44af2c3f, 0xd3c8bb49,
- 0x41614dce, 0x1cbf76e7, 0xc777118b, 0x66df4afe, 0x0bcc3f39, 0x7b22fcf2,
- 0x5de41663, 0xd145dc63, 0x39de3c8d, 0xe145bc7d, 0xa39fd28d, 0x3ea211c7,
- 0xec136f8f, 0x267b6a77, 0x33e6e58c, 0x632f2dc9, 0xf4cf33fc, 0xa387b8e7,
- 0xbb05fe69, 0xf1c9dcb8, 0x86cf95e7, 0xd3df3005, 0x5db144cf, 0xca4db4eb,
- 0x12a3a763, 0x143b1e59, 0xf65cf0f5, 0xa6153d63, 0x5a742ec0, 0x9424f611,
- 0xf2c1ee6f, 0x32dd6540, 0x1254d7f6, 0x4b1c817b, 0x7fc804e9, 0x67f737a7,
- 0x37e9d17b, 0x415cbe55, 0xbbe357df, 0xfee71a26, 0x0880f58c, 0x799e23b6,
- 0x83fd6ff6, 0x5a463bfd, 0x3ed994f9, 0x5183d066, 0xf923945e, 0xd48e5160,
- 0x71c86e53, 0xd11d5a71, 0xaf3a70f4, 0xc207f253, 0xb481eb03, 0xef61131f,
- 0x3bb4d23f, 0x9c048951, 0x09ff5903, 0xfa956fb8, 0x366d99d6, 0xbe5553f6,
- 0x3b65e512, 0xf157ddd4, 0x554ac97d, 0x1695e3ca, 0xf950df79, 0xffb656e5,
- 0x2ce33fd4, 0xde083c00, 0x6db6dfac, 0xe471f556, 0xf4b7a7b8, 0x808d7e91,
- 0x10797f9e, 0xc62635fb, 0x59537989, 0x0790dace, 0x2a7a5eb8, 0x69fee382,
- 0x34e22f1c, 0x73f67f2a, 0x0598cf09, 0xc1d027ac, 0x4ab9fccd, 0x77d5cfe7,
- 0xfb83135f, 0x955de210, 0xb25c79ef, 0xff827a7a, 0xd1ebc286, 0xbf3f9d1c,
- 0x83f338fc, 0x8837da2a, 0xfbac5b0f, 0xab3f1713, 0x78b95cb0, 0x308f35d5,
- 0x26c77ddf, 0x5ce22f70, 0xc1d183d3, 0x91cfa8f8, 0xbdb3b0fc, 0xa62feb87,
- 0x5bfdb2fa, 0x2d9f3cd1, 0x13e60f36, 0xddefc78a, 0x07f559fe, 0x226cafb5,
- 0xcaef22f9, 0x2d125ff5, 0xf833fd3f, 0xfb2736cb, 0x7cff0951, 0xadacea3f,
- 0x7fd60169, 0xf32779f6, 0x72b1b39d, 0xf3a49fdf, 0xf98d97d4, 0xb66bf4dc,
- 0x9a61fccb, 0xd0b439c0, 0x98d7ee6f, 0x9b1cead7, 0x4f78b7a4, 0xd544fc0c,
- 0x47f40f84, 0xb711f9f8, 0xedc6d77f, 0x40b3d743, 0x4fb1d76f, 0xba608f9f,
- 0xe24bdb39, 0xd90bece5, 0x8d1d9e7c, 0xf34ef495, 0x74de854d, 0xb8a65636,
- 0xa87a0499, 0x387a4974, 0xed89a63b, 0xed956702, 0xc9b51e9c, 0x74cb9576,
- 0x5fd13b7f, 0xb407e812, 0x63aabb09, 0x19e40b4d, 0x05e1f9f0, 0x4f70069c,
- 0x0e8ed43b, 0xd7f9c53a, 0xe333efaa, 0xebf6051d, 0x89a79fb0, 0xba6bc7ef,
- 0xedb5593c, 0xf0257f4a, 0x614db554, 0x197fda7f, 0x13acd0fd, 0xd1003f0c,
- 0xc29f62e5, 0x6e2c22ef, 0xfb116db8, 0xbdac96d3, 0xac6f7415, 0x6f7eb163,
- 0xf2a2a8fc, 0x693a8e7c, 0x395ee4ff, 0xdfdf019e, 0xef1d28e7, 0xf38cb875,
- 0x3bf0f68b, 0x47496e39, 0xfea46d94, 0x35941aaa, 0xa19a4e3c, 0x19f5cae7,
- 0xd8b02270, 0xaa3be761, 0x6eeed3df, 0xbb3cc6fd, 0x9d31cf9b, 0x934d1fcf,
- 0xdedb93f7, 0x2fccf796, 0x26243d7d, 0x41e45bee, 0xf46061be, 0xd063b887,
- 0x22f3f520, 0x35f61cf8, 0xcf34ebec, 0xff660dac, 0xe653ce4e, 0xe66d80fc,
- 0x730eee7c, 0x9cd9af3e, 0xce6ebcf7, 0x0ee309ff, 0xf41384eb, 0x4235c46f,
- 0xfd0a46ff, 0xf5261ddb, 0x7fa1e46f, 0x8dfe8523, 0x91bfd0ef, 0x3c8dfe87,
- 0xa1e46ff4, 0xfe85237f, 0xfeeeef8d, 0xba554e12, 0xe07814bd, 0x4eddbab8,
- 0xf7813e23, 0x89d9c5cb, 0x558547cc, 0x1717a5ea, 0xd8fcb2e5, 0xe29a6f61,
- 0x11937b60, 0xad18958f, 0x1c47f785, 0x2ab2d280, 0xb1db8d39, 0x55f6ba1d,
- 0x2aae8769, 0xeec24670, 0xe4f2bad1, 0xa73d882a, 0xd418b4a3, 0xdb6b68bf,
- 0x2f56f802, 0xff7ec03b, 0x77eee5d6, 0x63f893af, 0x5f118bfb, 0x0f738255,
- 0x25f49b7c, 0x71ee7719, 0x4353db04, 0x4d6244fd, 0xd3f21e50, 0xd43e733a,
- 0xe6be042f, 0x46abed35, 0x6c6fc7c6, 0xfbe0c96d, 0xe0e33e9f, 0xea9f69fb,
- 0xcb313bf6, 0x2198f2c1, 0x1bce23cf, 0x9f7a5970, 0x95e709b2, 0xc31c7fa7,
- 0xa650fdb9, 0x68617ee9, 0x0879765a, 0xf91df3cb, 0xe3058a35, 0xbe5f4f94,
- 0xcd6af58f, 0xedd2e7cb, 0xd7b2dcfa, 0xeef34c5b, 0xd1370fef, 0x71adc0d1,
- 0x5ecc7e21, 0x7783faa6, 0x31f887a5, 0xa7ca9807, 0xbe6219ad, 0x8d7c5f8f,
- 0xbdafbca9, 0xa1cf6e23, 0xfce4b9fb, 0xa5ceb25c, 0x6f5e02c8, 0xc554bd68,
- 0x6ff827f3, 0x4e52dbc5, 0xc673a72d, 0x2bbfaf1b, 0x9d7f0052, 0x57e03277,
- 0x858b64d1, 0x3f4cad9d, 0xf332c487, 0x15615cb9, 0x275c573e, 0x84b855dd,
- 0x7fda9637, 0x654c6d69, 0x47e5fa3a, 0x68812aa9, 0x3c9680d1, 0xde8bafe8,
- 0xe838727c, 0x98dd5aaa, 0x3bf2a2ea, 0x5c16ff14, 0xb7133f20, 0x9524713d,
- 0x495aa927, 0xaa73c27f, 0x1cff702d, 0x19edd1f0, 0x7ca4ef02, 0x68a5e6ba,
- 0xe9d41f8e, 0x0ae6d52f, 0x6c6c1d07, 0x814f5954, 0xeb8d4cfd, 0x8d8d93a4,
- 0x6bd0e1f1, 0x3e28c62a, 0x5c06c7c8, 0x8508fa0c, 0xefefc907, 0x97bd69ba,
- 0x94f7c90e, 0x752e758c, 0x41a2fac9, 0x07de37b6, 0x5c7bd630, 0x372b47d7,
- 0x3b7591be, 0x7fd73f7d, 0x7e1b9e5f, 0xbc5dbadc, 0x6d96c5ee, 0x7d29925b,
- 0x85dda1c7, 0x7b7d2d75, 0x1a48f45c, 0x326dcbe7, 0x75b3fdae, 0x23e13e4f,
- 0xe3777a7e, 0x0fe87693, 0x9dbf5695, 0x6679cddf, 0x0ef11da3, 0xc8dd6fd7,
- 0x2d6c17df, 0x71807b61, 0x1194eecf, 0xa3c3ad97, 0xc1b2ac62, 0xde3ceb45,
- 0x1585ca5f, 0xa69e32e1, 0x46f51d48, 0x55b5d602, 0xa6bac7c9, 0xe3b76f17,
- 0xf58781fd, 0xa6fba17a, 0xa2b4f0fd, 0x357bb01e, 0xd4c71c29, 0x11993edd,
- 0x64fbcfe8, 0x4e34e5da, 0xc81e5fa7, 0x8287de7a, 0x239c2fb4, 0xf5fa21b9,
- 0xf5da5561, 0x4ef9559a, 0x30903d98, 0x5ec2f20d, 0x35456ef9, 0x0a23439d,
- 0x710bb7a0, 0xa3c5a535, 0xd79d1354, 0xf6984616, 0xb4112cc1, 0x9bbfa8af,
- 0x7e532f45, 0x530cc4fa, 0x07d399fd, 0x0b9df886, 0x7f99cb3a, 0x8f7a6d5d,
- 0x9f2efaa6, 0xc7bb615b, 0x4a77f358, 0xbb3a62ef, 0x5abed4d1, 0x47bd354c,
- 0xf7a9e8b3, 0x6544ce18, 0x54e1c476, 0x6658f7e8, 0xeff54769, 0x169dfcad,
- 0x7dafda62, 0x927f3c33, 0xfd8da5e7, 0x7d3d8609, 0xe8cf7e16, 0xef0cbcea,
- 0xbc451788, 0x9a1dec30, 0x61691e59, 0x3c48553d, 0xa8f6eb54, 0x8f691cea,
- 0xd8b5f6aa, 0xf04d8f11, 0x4810a6b7, 0xb6151a6a, 0x477d5237, 0xdfcc9c4a,
- 0xcc3bef85, 0xdfd052f7, 0x521f9465, 0x42bfb04b, 0xdd686bcb, 0x606a1738,
- 0xd83b6247, 0x076c9384, 0xfbd1c633, 0xf434e837, 0xfed0807d, 0x33700c06,
- 0xbadcaeff, 0x822f60fd, 0xd8e2b4cf, 0x549dc47c, 0x95b14d35, 0x6f495ee4,
- 0x54bfff06, 0x7ebf6161, 0x4c03e1fb, 0x5615ed6f, 0xff4b8c8f, 0x78d4b876,
- 0x9435dda5, 0xbad0170e, 0xb05e7fe0, 0x15f8f143, 0xe9f00f59, 0x810cfa05,
- 0x70174a4f, 0x01d5e033, 0x7e7290bf, 0xe2286e3f, 0x0a7be426, 0x1425c057,
- 0x0b38fa9e, 0x2772c134, 0xf3cfcbcd, 0x8c57e90a, 0xb78fdd08, 0xb0ffd9db,
- 0xe52e1141, 0xf531e1bb, 0xf4e3b4b2, 0x6feb90cd, 0x2078a9db, 0xd97cdfbf,
- 0xe83bdfca, 0xd9c658a7, 0xde689f4f, 0x54f41daf, 0x8ccff72c, 0xeedc89cb,
- 0xdf5745df, 0xff864f45, 0xdd7e3426, 0x19e647b8, 0x1ab7dfa0, 0xf37d8626,
- 0x1be1c44f, 0xe77741f2, 0xe439c74c, 0x9910f1d2, 0xbcf9e5de, 0xe39d2a34,
- 0xbedd35cc, 0x4d69f068, 0x5b8c676f, 0x78eee542, 0x7e6f7bd0, 0x43557167,
- 0xfbf06a46, 0x1b4ada37, 0x975381db, 0xe25a73c7, 0x7ce22574, 0xdf2e5929,
- 0x4f763969, 0x29f844cf, 0x25b4ad8e, 0x8faea44c, 0x553439dd, 0x88be420c,
- 0x86d74fd3, 0xcfb60acd, 0x032de91b, 0x9c61f9e4, 0x872de7ef, 0x3f6167a3,
- 0x8d19dcae, 0x2bc5a190, 0xa2ee1fdf, 0xa2d9be73, 0xfec01a2d, 0xce7c8de0,
- 0x3cc6d70b, 0x390ce7d8, 0x516572a3, 0x5503c84f, 0x04f038ff, 0xb96d01e4,
- 0xea72112d, 0x81540fe9, 0xe73a1ad0, 0xe538be58, 0x6a7df494, 0xabdf0473,
- 0x2f08a53c, 0xd48b51fc, 0xd32e797d, 0x337cdb79, 0xd2708fc6, 0xae30c3b8,
- 0xc6124b7f, 0x30b2f8f5, 0x333cb6ae, 0x8bbb2ba6, 0x97aed691, 0xc316dff2,
- 0xa3dbacce, 0x0f23f721, 0x4b645fb9, 0xc8791fb9, 0xf72148fd, 0xfc0d7be3,
- 0xd71bf00e, 0x6f43e5b7, 0x39158df5, 0x8e1cf84b, 0x7f5c81cc, 0x01ee12bb,
- 0xf15dba3f, 0x8478e4f4, 0xf9e5620f, 0x2357821b, 0xb246dd1d, 0x5edd1059,
- 0x8221d977, 0x88c6ebe3, 0x9c7e5358, 0xbf54d923, 0x2a6695c8, 0xbfa93ebf,
- 0x7706fca9, 0x537f29be, 0xfd5348ce, 0xa6319e49, 0xdc468ffc, 0xc53faa60,
- 0x9f94c53b, 0xa9b66136, 0x12e28cfe, 0x59ccf953, 0xb3e54c8b, 0xf94cdbb5,
- 0x34ee2b5b, 0x92f1ffd5, 0xaf72a6e5, 0x0e715970, 0x231f4336, 0x3e85efb8,
- 0x6fede946, 0xe3064667, 0x4b38d475, 0x350cef97, 0x56fa900d, 0x39f7ae74,
- 0x09ee25d0, 0xe8fb0e81, 0xe2f680f7, 0xbf06199c, 0xfa914065, 0xe8324b70,
- 0x685eb426, 0xfd88a8f9, 0x6594f097, 0x9f6ee7ff, 0x313e2561, 0x43fdaaea,
- 0xfb7f2832, 0x5619e6c0, 0xaea32fe2, 0x3a52ffd9, 0xdcf17fe5, 0xf07cb237,
- 0x57284bfe, 0xfccbf772, 0xc822c134, 0x9bce06af, 0x8c75a3e1, 0x8d7d2eba,
- 0xba53da47, 0x5235538c, 0x9d7101c0, 0x00d20380, 0xfdd227d1, 0x5f489f44,
- 0xb72cfa27, 0xe8907109, 0xd221e913, 0xf7fdf14b, 0x3d2297a4, 0xd2297a4c,
- 0x452f4877, 0x297a42da, 0xcdd43fd2, 0x3a83f4e2, 0xb1fddb8d, 0x8fd382ae,
- 0xf7f096ea, 0x7196ea4f, 0x1f3a97fa, 0x8064ff7f, 0xb0087f61, 0x8bf0c69d,
- 0x091fc0d5, 0xdb2ede7b, 0xb1bf60b9, 0xabe795e2, 0x5facc7e1, 0xb0235a22,
- 0xb1ad5b4f, 0xfe9d1c27, 0xadf9eec9, 0x92089c55, 0xdee19ccb, 0xf8f006cf,
- 0xb7cc5dbd, 0xc447eff5, 0x84053eb4, 0xb5d34fa7, 0x3307e0b3, 0xc656ca0a,
- 0xeeb8ff10, 0xd03625eb, 0xae9687cb, 0xd5efa3ef, 0x03a7dbf9, 0xf7e86dbd,
- 0xa65dfd5a, 0xae321d6b, 0x6b6b5af0, 0xbfdbdb3d, 0x03c46e14, 0xefec33ed,
- 0x5ef958f7, 0xe085f2b1, 0xc104e8fc, 0x5b2ffaf9, 0x5af10e38, 0xcf892797,
- 0xc46f3d1d, 0xfdf87505, 0xef1413f1, 0x8de1f863, 0x2fc29f78, 0x3e41c75a,
- 0x77691d18, 0x0dc48587, 0x2fbedfc0, 0xbcc68fea, 0xc3277df8, 0x97d4ffbf,
- 0xf2f78022, 0xb5fe3f0c, 0xd834968e, 0xe1df4615, 0x33c704f0, 0xe57afe19,
- 0xe715168b, 0x64af1189, 0x3bcc638c, 0x15fd4aca, 0x5d23c674, 0x47ca6aeb,
- 0x757d465c, 0x93d7f724, 0x49dde3be, 0xb955e7aa, 0xec3e535d, 0x22aba3c7,
- 0x8ce9423d, 0xafa9e813, 0x3af1ea9b, 0x38d0bf0b, 0x1eb4624e, 0x1c7e8127,
- 0x01df9cb2, 0x48109d1c, 0xa39ffbc6, 0xb03dd897, 0xb88e3e83, 0xb8ce82b3,
- 0x088fd405, 0x2798c7da, 0x15f7edfa, 0xbcf217cd, 0x9df0cbd7, 0x29f492e6,
- 0x3f5e7adc, 0x2c6385af, 0x3d54bbdb, 0xfae61c5f, 0xcfd1046b, 0x90da19ad,
- 0x1fdfd481, 0x7ccc8c94, 0x7a3217d6, 0x094fdf60, 0x0bb04779, 0xf03119fa,
- 0xbc7e84ff, 0x05bdef12, 0xe942e1db, 0x418fc0c8, 0xbbde064f, 0x0e832ba3,
- 0x18d0e282, 0x65711def, 0xf4a17f7a, 0x199d1dd6, 0x43ad75f4, 0x8cf001d2,
- 0xae8320f8, 0xf89a2f94, 0x2ae8eb1e, 0x067f9f07, 0xc5d2855d, 0xe9257495,
- 0x0e27feb4, 0xba4aefee, 0xc007a4ea, 0x55d387e5, 0xf8f38a8b, 0x79a7a59f,
- 0xee3c626d, 0x765c97ff, 0xabda441f, 0x7c17b69f, 0x198c4ca6, 0x2e13120f,
- 0x62ec1075, 0xba32f5a1, 0x7f4a17a9, 0xbc6eeda1, 0x6e465da2, 0xfa71bb70,
- 0xaeda1959, 0x047aed12, 0x71c21bb7, 0xf7e96f11, 0x1a72de08, 0x999e2d71,
- 0xb90e5390, 0x2f2df26d, 0x27cc8de1, 0xf3a719ba, 0x096243f3, 0xee24bf9f,
- 0x854f40fa, 0xcb8d693a, 0x42fac85d, 0x71d76461, 0xedea3705, 0xdc5d7fc7,
- 0x4f8cf980, 0x37e3cb30, 0xf5fcf2ea, 0x0ffb91a2, 0xc6e1477d, 0xce59ebdc,
- 0x61477d0f, 0xfe3d40f3, 0x81a44d20, 0x8f0a17df, 0x0efe9f9c, 0xcfbea146,
- 0xc9ba7453, 0x5462ab70, 0x6a9bee1c, 0xaf321c56, 0x3c8c1de3, 0xfce3eb8c,
- 0xe9cfc20d, 0xfdc0224d, 0x0903a24c, 0x61091ff9, 0xc85fef93, 0xaa35bafb,
- 0x5790dff6, 0x4fba7b8d, 0xb057b53b, 0x4c440fcf, 0x4a77839e, 0xd7190dc6,
- 0x17f6ed0f, 0xdbce59ba, 0xb960c8ef, 0x16d2fb13, 0xde27c9d7, 0x5fba73a4,
- 0x8a37bca6, 0xfb46f714, 0x3bfa79d1, 0xbf91c73a, 0x40b96731, 0x736ef1bb,
- 0xfed193bc, 0x6138d726, 0x9cfeef8d, 0x776f29bc, 0xdecdd86f, 0x042ecd8a,
- 0xbd8adf7e, 0x7deb10aa, 0x45a7b62b, 0x4e7661a6, 0xafd2bd07, 0xa0d8b92b,
- 0xc6f1cefb, 0xc1dd78f3, 0x286b80d9, 0xff380d3c, 0xeb1eb800, 0x077bae0a,
- 0xaa379608, 0xad5f2423, 0xd57c908e, 0x58757380, 0x9ede7dc7, 0x5527f1c1,
- 0xf9af090e, 0x5611aecb, 0x2c17f512, 0x93f9c91b, 0xb807c275, 0x6092c69f,
- 0xf7b10f10, 0xce58eb09, 0x9ddcef1b, 0xe8bdf87d, 0x2ae79a24, 0x983ff687,
- 0x4082b9df, 0xe2844916, 0xbe7a86e4, 0x05fe7f8f, 0xaa7d03d5, 0xf1af754a,
- 0x96facec0, 0x7d71ef2a, 0xfe15207d, 0xd754f158, 0x0e55e8f1, 0x9f435f09,
- 0x98afd21c, 0x5fb1adf7, 0x80befe85, 0x0ef55f21, 0xc6dcf193, 0xe4eef73d,
- 0x92e1e1ad, 0x930ef5af, 0xebc0d8fc, 0xee7ebb06, 0x89c33f53, 0x3afca68f,
- 0x98abf59c, 0x2e4c6f58, 0xc28583ec, 0x76189fa4, 0xf904f695, 0x22b5ca7e,
- 0x945191eb, 0x13643c2f, 0x076f2a7e, 0x92794043, 0x1fb6b3f4, 0xef82a4ba,
- 0xfc294517, 0x6f71863e, 0x22c92c29, 0xc27c41dc, 0xbd370ee9, 0x13911b4b,
- 0x7947ca67, 0xc7ea997a, 0x9537488c, 0x98077ac7, 0x1427e3ca, 0x8a3df298,
- 0xefd536af, 0x29ac6b39, 0x68ddac9f, 0x31529faa, 0xf83794d5, 0x24fc8a58,
- 0xc5b92cfa, 0xb2efbed4, 0x34fd5352, 0x5ca9a55f, 0x319b3bc5, 0x25b7ab40,
- 0x81cf1127, 0xd58c9fca, 0xe3de434b, 0xf0cb08b5, 0xfe6b77ce, 0xcbde5a33,
- 0x80b91099, 0x6cc9afdf, 0x9e7999fc, 0x2c6b44ea, 0xcdbbd7a5, 0xc928b17c,
- 0xb9171f9c, 0x71df814f, 0x9fcccb9c, 0x4d589653, 0xeae51ff9, 0xe44f34fc,
- 0xbbe3ddb1, 0x300daff0, 0x4e143fe1, 0x7efc0f44, 0xef9d3b68, 0xcdebcc3e,
- 0x070f7e32, 0x75e0937e, 0x0c126fc0, 0x824df807, 0x049bf0f3, 0x24df87d7,
- 0x937e1cb8, 0x8721f2e0, 0xd61ff8cc, 0x55ffc662, 0x6ff1991f, 0x787765d0,
- 0xa66ad91a, 0x9a29a10f, 0xba782df2, 0x7e9994e6, 0x1d73f142, 0x09b15b89,
- 0x09e287c0, 0xbe387fb8, 0x8be08656, 0x37f7c3f0, 0x31477bdb, 0xd7d71e7e,
- 0x20606d75, 0x3a2e97df, 0x6fbc0aa4, 0x71f3ac63, 0x6d3fdcfd, 0x89731ad5,
- 0x5dcefccf, 0x763e0490, 0xdb7e909d, 0x4f1655f1, 0x207fba80, 0x29d99c64,
- 0x3fa843da, 0xaa52fe2b, 0x26d2741d, 0x0e7bcfdf, 0x95d8797c, 0x123eb2f1,
- 0xf6bef84f, 0x27be54cf, 0xa8d2c475, 0x8eaf8f80, 0x9f009ed1, 0x84bb9799,
- 0x8a249bd7, 0x5c402fb7, 0xa5857fd4, 0xafb73f22, 0x722dc7bc, 0x89fef95b,
- 0xa6e727c1, 0x2da9b8c8, 0xdd7fbab9, 0x9ea7e323, 0x777295c9, 0x71c5c794,
- 0xf2b925de, 0x8ba90d7e, 0x010773a9, 0xd99d873e, 0x0b3acf80, 0x8ad9ebbf,
- 0x9d09e47b, 0x0f21c8f7, 0xa3ecfe43, 0x1ff57fcb, 0x47581c3b, 0x3a617af6,
- 0x1dfbfb7f, 0x81e2f8a6, 0xfca65d5b, 0x5324a6a0, 0xdcbbc1fd, 0x40fcf2a6,
- 0xc87ca98e, 0x3f298f21, 0xa98465ac, 0x791f55fe, 0xad91f94d, 0xaff54c13,
- 0xca6c5539, 0x47b688a7, 0x8abedf01, 0xcd1c53b4, 0xb9fa974d, 0xe4dc705b,
- 0xe563bbdc, 0x7edd5f7d, 0x46fbc861, 0xd3a6b9dc, 0xd11ea875, 0xe8e52ed7,
- 0xf52164fa, 0x1fae8746, 0xa13eb30a, 0x1de371e9, 0xe67c58f7, 0x5e2371b8,
- 0xd0ef43bc, 0x7b8e8af5, 0xe2f19d34, 0xf178e0de, 0xbf5d61b9, 0xc75e7d1f,
- 0xfbfce87b, 0xeb7ae5da, 0xbdf3b4ef, 0xa15e631d, 0x96c949f3, 0xd1d9bb74,
- 0xbfaabdf5, 0x46fb4ae5, 0x25f1666b, 0x3613fdd0, 0x6dff2b4f, 0xf3c62b84,
- 0xb75e22b4, 0xcf7617fe, 0x8f77f70a, 0x5cb07737, 0x658b1ccf, 0x8e5c94de,
- 0xddfd338b, 0x92418884, 0x7583adbe, 0x78c84afb, 0xdc646373, 0xbbb1889a,
- 0x8fddbf41, 0x6499e127, 0xff7c0d17, 0xf167bf4b, 0xf74d35e3, 0xbd8e68a1,
- 0xce3f7f51, 0x4c3d036f, 0x59f24b1c, 0x5b13c93e, 0x49143d7a, 0xcb13ca72,
- 0x8a9f6cac, 0x3757fe7b, 0xde75fafb, 0xfa4be99f, 0xb203e810, 0x07a8f40e,
- 0xb72954f2, 0x2beb920c, 0xb8eebf52, 0x187ec0e7, 0x43f3f421, 0x174fbc70,
- 0x6874c6f4, 0x75dfe3ac, 0xdba0c1ef, 0xfa193850, 0x3be3d0af, 0xd2f319fb,
- 0x07ec67e1, 0xfdc67e03, 0xb66df713, 0x7c914de2, 0xe202658f, 0x6dfc0ce5,
- 0xc6f693c9, 0x503c3a05, 0xbba8fc0f, 0x6e6a457a, 0xedf7ec0c, 0xeae31dc2,
- 0xea3b0e82, 0x62e09bff, 0xfbbbbfc0, 0x87f1dd6d, 0x5df0be50, 0xa3baddf7,
- 0xdef67fd3, 0x909f105b, 0x5e3a4bf1, 0x1c2cfdfc, 0x94777017, 0x323f3f79,
- 0x9189f248, 0xe4fdf483, 0xccd6fd23, 0x0ffc042f, 0x9d552bf5, 0xbcf3c85f,
- 0xdf98ad24, 0x8af9c6af, 0x37f35bfb, 0x8847f94a, 0x87abc4e2, 0xe36f8fc2,
- 0x7ad7cbfb, 0x4a6ddb05, 0xde3f151b, 0x75f12af9, 0x9fb30fad, 0x0772cdcf,
- 0x26c83bbf, 0x46576a4d, 0x5da5f6ed, 0xc2facef9, 0x60eef948, 0x0beafbe8,
- 0x2f19bd75, 0x86df606a, 0x19eebdfa, 0x3cb1fba4, 0x9cf2c3c2, 0xa150d71e,
- 0x37a0e9d7, 0x0e6f7cbf, 0x31f6327a, 0x671f1ca5, 0x3f0dcdc0, 0x3cce90d4,
- 0x073c37c1, 0xb58379e7, 0x0ec5f8cb, 0xab7e1af8, 0x61ecbf0e, 0x1a1127be,
- 0x77ce718f, 0x3f2bba20, 0xeb1fe198, 0xf8741f6e, 0xefc3bec7, 0x89691ed6,
- 0x69f1dfc6, 0x67df26df, 0xfd5bf4e9, 0x22cbb865, 0xf03153fd, 0xfdeab53f,
- 0x5d798d89, 0x96d50fdd, 0x9438e4ef, 0x73b68b66, 0x2cefad10, 0x7b778ff5,
- 0x9fdc89ef, 0x26117788, 0x2ba976ea, 0xcdcbadd7, 0x8fe914a3, 0xef8ca9f6,
- 0x5ef209f6, 0x8151f13d, 0x4fc4677d, 0x0481114c, 0x4a1f86a4, 0xe1923d5b,
- 0x4aa1f86f, 0x9e792302, 0xda17ea33, 0xeb68e4f0, 0x851577a3, 0x53fd3bbb,
- 0x5c647dad, 0xaa7e7754, 0xb9f39769, 0xaf97e9bf, 0x183e7ee1, 0xb6e52694,
- 0x036efb86, 0x2ad80d9d, 0xab67586c, 0x4bbfebad, 0xabf3a851, 0x3d9ae812,
- 0x96ade282, 0x962fbc2b, 0xbf88c22a, 0xe46f3e62, 0xf9ea352f, 0x7dbf9922,
- 0xeab7cca5, 0xd16da7ef, 0x275820ed, 0x7a07ac52, 0x4edd36f9, 0xc5207582,
- 0x7c1df03a, 0x35f0790d, 0x90d7c1e4, 0x0a435f07, 0xa5ef86be, 0x761538a2,
- 0x0ad3f85b, 0xfc07f683, 0x72418569, 0xc169fc13, 0x82d3f879, 0x169fc3eb,
- 0x5a7f0e5c, 0x69fc3970, 0xd3f879c1, 0x9fc3eb82, 0x3f879c16, 0xfc3eb82d,
- 0xf879c169, 0xc3eb82d3, 0x0e5c169f, 0x39705a7f, 0x79c169fc, 0xeb82d3f8,
- 0x5c169fc3, 0x62996f3e, 0xd3cdb7f2, 0x5b287fdf, 0x51f4cf1f, 0x9b1c5198,
- 0xeffdf847, 0xc4fc7f88, 0x373c0e96, 0x2edd022f, 0x48f70ead, 0x904e373c,
- 0x8908b778, 0x8cd9b6e7, 0x32ecbbe7, 0xb4e3245f, 0x7e07e943, 0xf49b42ab,
- 0xdf85215b, 0x56fc290a, 0x2ab7e148, 0x2b7e94cc, 0xe15bf0a4, 0x4856fc3b,
- 0x0a42b7e1, 0xf85215bf, 0x6fc290ad, 0x2b7e1485, 0x0adf83b4, 0xf856fc29,
- 0x5215bf0e, 0xfdf0adf8, 0xfe03cd08, 0x905e632b, 0xf499fbf3, 0x9343a252,
- 0xe532ea5e, 0xd707e721, 0x5c1f9c87, 0xb83f390e, 0x707e721c, 0x707e721e,
- 0xc1f9c87d, 0xdc8349f9, 0xef20bfbc, 0xbc83b707, 0xd41f9c1f, 0xb6037be8,
- 0x2e1b49ab, 0x35b48ebc, 0x7142794a, 0x2f353109, 0x8bfc2673, 0x35254ead,
- 0x6d8423d6, 0x859980f9, 0x38f4d794, 0x66d13cc7, 0xae39be01, 0x05a6f080,
- 0x0f65c704, 0x5cc97ffa, 0xf9b3f86e, 0xbf9ef087, 0x50deb043, 0x35afdfa3,
- 0x4b847bda, 0xefd46a45, 0x2f5d77cc, 0x1ea37c74, 0x79a0cbf3, 0x8f996290,
- 0xbbfc9378, 0xaf700b22, 0x91458b60, 0x642bb8f1, 0x5d28743c, 0xe793caad,
- 0xf6cb16fb, 0x5388e1fd, 0xb83c5129, 0x156591ef, 0x80056c87, 0x7e0292d3,
- 0x562f2af7, 0xab92d75f, 0xcc658711, 0x124bb0db, 0x867be09f, 0xbd84daa3,
- 0xfd19c69c, 0xefe3b085, 0x4bb44c73, 0xa0ed0279, 0x29f40e6f, 0xf4414dde,
- 0x9e4f2cbd, 0xb6ef9a7b, 0xfbe9cbab, 0xae4b6dc0, 0x89c5fdc6, 0xd3ddb2e1,
- 0x386689bf, 0xf8506e4e, 0x6da8ce9e, 0xc9fb8bc2, 0x3a7e75cb, 0x5ecb9b70,
- 0xf8bae3ce, 0x6fd1a3de, 0xbe5486c9, 0x5a2259a7, 0x450f710b, 0x3df8550c,
- 0xb46e037c, 0xbeb1d7be, 0xb02ada2c, 0xfbe0ff2f, 0x7e2e244f, 0xa34ffb9f,
- 0x2116c687, 0xcb3450ae, 0x0d2742f7, 0x83d9592d, 0xe5f9a5e6, 0xbfa3a17b,
- 0xe706f258, 0x85ef929f, 0xe70cf932, 0x9879f1f9, 0xfdf853ed, 0x8dbec995,
- 0xee370496, 0x25b72f65, 0xe136fea2, 0xf5055881, 0x8d8af708, 0x168ae575,
- 0xbd01538b, 0x41f10388, 0x639c47f4, 0xdf25e83a, 0x59f7e363, 0x365d58a6,
- 0xce431bf0, 0xb1c97129, 0x3151d48b, 0x4432cf7c, 0xd0d4b84e, 0x7e62e383,
- 0x3b4e9c78, 0xba5fe7df, 0x8572c9d3, 0xbe615eb6, 0xc65f3e79, 0xf6dd56bb,
- 0x7a4b70e1, 0x99ce9c67, 0xbc16ff34, 0x7d267b03, 0x8508f47b, 0x79bd88e5,
- 0x0da3d704, 0xcd3df12f, 0xf06f9592, 0x0d4b943d, 0xfbcb450f, 0x52ffd26c,
- 0xb0cdc3ae, 0xf1d7cd3b, 0x69c7ae53, 0xef93ab1d, 0xcc39d33a, 0x6a5caeef,
- 0x119cb1b0, 0xf21a2f2a, 0x911ef1a7, 0xc23fae10, 0x60d153ce, 0x0bc03be3,
- 0x4aac94d7, 0x91ca5712, 0x7339758b, 0xe38d8351, 0xf7f42ab2, 0x6eff42d4,
- 0x1e3d62cf, 0xf356f16b, 0x42f24ff7, 0x7de350e4, 0xc94ebd4d, 0xb06607db,
- 0xc6c4b43c, 0xcb39cdfe, 0xb6247ca5, 0x93ee3f0b, 0xce3e59cc, 0xe666f782,
- 0x947af4ec, 0x5de9e82e, 0xd89a4e5d, 0x4ff864ea, 0xfcc11cb9, 0x14e5ea65,
- 0x397cdfce, 0x9799d399, 0xee2adc65, 0x5a6e8122, 0x073be48b, 0xd1f2ebef,
- 0xc6b1c40c, 0xc9eb3e43, 0xf44eddf4, 0x74f2218d, 0xabc035be, 0x3878801c,
- 0x44ada6d1, 0x8dc4ec9c, 0x4d83ef82, 0xfd451c82, 0x155c82cf, 0x5691fd8f,
- 0x2661f7c4, 0x68bf7c28, 0xf4dbd0d2, 0x43fb40fd, 0xf7e13f30, 0x29c2b457,
- 0xcd39c47e, 0x805bb6d2, 0x685f637f, 0x5efca3be, 0x629f24ea, 0x9a923bc7,
- 0x741b6fae, 0xe63fba1f, 0xb276e846, 0xeb076948, 0xb26193b0, 0xb7c92478,
- 0xd3e4266a, 0xf66db0b9, 0x608109d2, 0xcb2b951f, 0xd576fc7b, 0x419206cc,
- 0xc9fb55ff, 0xde458b1c, 0x9039233f, 0x96880bef, 0x2f949ea2, 0x4014a359,
- 0xf5e6323f, 0x38ec67b9, 0x3a4eb0cf, 0xa7d8ed28, 0xd2e51ef2, 0x7e4d327b,
- 0x8cb4d09b, 0x34fd8de0, 0x27f5a637, 0xf468610a, 0x1c2de160, 0x85ebf781,
- 0x005428f1, 0xe8b798f1, 0x3bc1eaf9, 0x973ab4ff, 0x91f9c4e1, 0xa6687dbf,
- 0xe05ff22f, 0x6b147393, 0x4b1bdff0, 0x0d5768b2, 0x50f7c1ee, 0x11bf03c7,
- 0x9efc6db9, 0x4bb64a44, 0x7b10a9f2, 0x8960f54b, 0x4bbb50c7, 0x773cae59,
- 0x7a9dd584, 0xdc7bfb2b, 0xd634b76c, 0xbe66cc7d, 0xf3a46be7, 0x5ee7eb07,
- 0x9ee7bfdd, 0xf916c3ca, 0x1663c2fe, 0x8857f6ff, 0xd0f72f5e, 0x8fbd6066,
- 0xe79ede21, 0x8cfaf1af, 0xf83a4cf7, 0x896efe95, 0x96474f41, 0x2afbe25d,
- 0xb77691a5, 0xe54f441a, 0x0fbe15ab, 0xde4cba5a, 0x2b56d6e7, 0x6e845df2,
- 0x99bf58ec, 0x9efcbffd, 0x117e6fd5, 0xf8750b2e, 0xbcb7b1ce, 0x84eb48e1,
- 0x3d979fef, 0x347c9360, 0x0efb8990, 0xf2712cb7, 0x7b9fd9bb, 0x0f06ab8a,
- 0x8c3c9e03, 0xe5d871a7, 0x8c4b7f54, 0x4bdf04b6, 0xd841cb45, 0xfcfee71d,
- 0xba8f7e6d, 0xdf8d39b6, 0x95d92cbf, 0xd9ef0abf, 0x7ed1ee7c, 0x4497f582,
- 0x4790ecba, 0xf9621a6a, 0x53db9e7c, 0xda2bcfbf, 0xe067cfd8, 0xd2c1bee7,
- 0xbe7d778e, 0xaea2e71c, 0x6cc01157, 0xbaf54c53, 0xf61a63b6, 0x4b3b50d1,
- 0xdf21bbe8, 0xdd815765, 0x5f641ec4, 0xb632ec35, 0x71b3639c, 0x77b1cfae,
- 0xf73ef7fd, 0xf437f3ea, 0x7a1df9da, 0x9ef8ee6d, 0x2ad7ff90, 0xcbd3d82e,
- 0x7133dd23, 0x90fca1bf, 0x62b4910d, 0xbe5b9c62, 0x7c8f731f, 0x8ef4a63f,
- 0x7367e67c, 0xdc029380, 0xfbc9193b, 0xe94fdcb8, 0xfbf7ee90, 0xf40f6bad,
- 0x0a7a0dd9, 0x821df978, 0x1ed79772, 0x951f2417, 0x77a62a35, 0x0bfc8c24,
- 0x97c95583, 0xfc00dd48, 0x9a477c7e, 0xcd396f1d, 0xf1093121, 0x27417b99,
- 0x51db3ac3, 0x993f8e3d, 0xca0e2e98, 0xfe14bdf7, 0x2f18e4bb, 0x955beff8,
- 0xc3df9a36, 0xdf2cfaa0, 0xc51c1aed, 0x68b895fd, 0x5d4869dd, 0x03824f3c,
- 0x3eeda9c3, 0xe3cdcfea, 0x02ca3e30, 0x07ec1b7e, 0x42f71073, 0x7e5c5bf9,
- 0x6d29c61b, 0x68d4ef90, 0xda38e46b, 0x20fb58ea, 0x975607c8, 0x5cb04fbd,
- 0xbddf20d8, 0xddffa39e, 0xcb2f9a11, 0x2704e5cd, 0xee33b3dc, 0xabc286dd,
- 0x797f9f44, 0xce59ac63, 0x036b5c6c, 0xf377667e, 0xdd39c65e, 0x30da5d0e,
- 0x2837df86, 0xbef97ab7, 0xfbc3a68a, 0xf79cdbb3, 0x7b325fc2, 0x34b623dd,
- 0xb065ffca, 0xe9cf6b94, 0x7a6271fb, 0xa9df9320, 0xf1c9cdba, 0x8d5db3e3,
- 0x780edebc, 0x81f0443f, 0x662ae2dc, 0xf89d1378, 0xbe596f10, 0xcedf8cce,
- 0x77c944f9, 0xf095d7fc, 0xd5605bfe, 0x79e0aeec, 0x8997dfac, 0xb4d9a1f8,
- 0x970ef1ef, 0x1f7c6970, 0x3343c4f6, 0x6205eff9, 0xe6cf1c9e, 0xbbc78f71,
- 0x4c374453, 0x18fd06d7, 0xf18df3f7, 0xb4ab1eac, 0x6bbe7bc7, 0x420f7a9f,
- 0x7c27af4e, 0xddd00fc3, 0x02e3b53e, 0x2f6b8d26, 0x5e07ef97, 0xfdf4efc1,
- 0x6a01fffa, 0x00d36c91, 0x0000d36c, 0x00088b1f, 0x00000000, 0x7dedff00,
- 0x65555c7b, 0xd6bbf0ba, 0xc0d857da, 0x51b08b66, 0x62020dc0, 0x10106d11,
- 0x80a17515, 0x636a735b, 0x8dc42937, 0x910150b7, 0xf39fa8ac, 0xa96f0db1,
- 0x962a2695, 0x8da6b675, 0xb2707595, 0xd99b1b46, 0x0f5d9a6a, 0x39d38d3a,
- 0x32cdb653, 0x34d209bb, 0x99d37d9f, 0xde79e7be, 0x0daf60b5, 0xf9a675a4,
- 0x3efcefce, 0x7df5e3fc, 0xee7d7bd7, 0x765ef3cf, 0xb24c6322, 0x98783631,
- 0x8c81b183, 0x45931819, 0x77a13fc8, 0x6302edfb, 0xbeac7195, 0x28d2132d,
- 0x0b6bff56, 0xdfe3df63, 0xa2749ef8, 0x8f2c6453, 0x5da0dbb1, 0x10af7c1b,
- 0xd6ccabd9, 0x29d33df3, 0x148af7d0, 0xd41dd336, 0x7ec3fb1e, 0x13efd5e3,
- 0x338b69fc, 0xe3abea7b, 0xbb78d856, 0x9a7ed0a9, 0xdd8beb05, 0x3ea81bf5,
- 0x26e9b3cf, 0x3632c591, 0x87ff04db, 0x7b4894a5, 0x32e6c456, 0x7057b0d6,
- 0xe1a8a11a, 0x18b18941, 0xf08b9f48, 0xbec664b1, 0x3bcdf868, 0xcfbd40b7,
- 0x64af6f37, 0x35e67b43, 0x398a3fc7, 0xf7363046, 0x0c733652, 0xa5de6c60,
- 0x0f569431, 0x073864f3, 0xf8dbd506, 0xc607ba5c, 0xfb2dadbf, 0x5a307fdc,
- 0x30e59fb7, 0xbf73fef6, 0xe868e3fd, 0xde9f3197, 0x3acf4d7d, 0xa13ead66,
- 0xc304b2af, 0x4d73af8d, 0x83155746, 0x18b6ce79, 0xcd14121c, 0x64c55e5e,
- 0x33b32798, 0x13e41a67, 0x422bcc75, 0x16fd6cbf, 0xf3eb04d9, 0xb557fe30,
- 0x5da9905c, 0x824fbe63, 0x7a860cf5, 0xdf5e1cc6, 0x58f7f00c, 0x4884670c,
- 0x912de8a8, 0xcdbc1903, 0xf83d29f7, 0x21a90c1d, 0x89ef07a7, 0x5ecc1d0a,
- 0x7b6d0657, 0x330305f0, 0x65eb0f96, 0xfceaae1c, 0xbff32aa7, 0xfb20bd6d,
- 0x4e0ddea0, 0x2757cf07, 0x7ac1e61b, 0x364face7, 0x5cb486cc, 0x473e5ef9,
- 0x2f8dde5b, 0xccaf8aab, 0x4f587695, 0x57c71b57, 0xe13d3ad7, 0x2f4f6bab,
- 0xa931257c, 0x00771e67, 0x8e00d8be, 0xe382362f, 0x57c0530b, 0xa82f33a5,
- 0x7c70bfde, 0xedfe7ecd, 0xd0765e0f, 0xceffa8fa, 0x1dbe8d07, 0xb6acffd0,
- 0xf2b784bd, 0xc9f41bd5, 0x99ceaf50, 0xdb51704c, 0xb6cfaecf, 0x6de78032,
- 0x1debb7ab, 0xe8eefc16, 0x9521ee93, 0x413f1059, 0x6790099e, 0x3bbc40ba,
- 0x397ea7a2, 0x9c617ba4, 0x91cd8b25, 0x719edaec, 0x3cf428b6, 0x86da3ebb,
- 0xafaecde3, 0x7165887a, 0xf66777fa, 0x66b3bfe6, 0xa0b317ce, 0xb3cfe43f,
- 0xe424ce45, 0xd4510a8b, 0x3e9a9bf0, 0x79837884, 0x35e0063d, 0xdbc3fe23,
- 0x0c38469e, 0x6ce6145e, 0xa9a94f86, 0x8b8e1f01, 0x36f38cf4, 0x826bcc88,
- 0x8135a97a, 0x548f388b, 0x876c28a0, 0x528d8469, 0x1df90b16, 0x4802ed30,
- 0xee9e2453, 0xc3f5f273, 0x677e3f77, 0x5c3c8131, 0xa1cf4abf, 0x3b606af4,
- 0xfe00a757, 0xd9cc310d, 0x4fa1e8ec, 0x3e951fb5, 0x6fedfa55, 0x70ae7b7d,
- 0x3993677d, 0x3386593c, 0x56e304c9, 0xb9cc3c3e, 0x3afcb846, 0x0f00610d,
- 0x817ad05b, 0x7d6c0b58, 0x903537ac, 0x0fcd7657, 0x24a5b7ad, 0x86f58fb6,
- 0x93e553ae, 0xc3ce2639, 0x015127c0, 0xfad77798, 0xf10c51a1, 0xca2f302d,
- 0xcd8bb39d, 0x5d5bce22, 0x504d53d7, 0xbbb6e619, 0x33e944c9, 0xc368c04d,
- 0x764d3e00, 0xe4df3fca, 0x29adb4a0, 0x9ddbca83, 0x633f9a36, 0x80698881,
- 0x85308aa7, 0x8f3cfdff, 0xe54165e5, 0xee9c6d53, 0x11035b4e, 0xfd3920b6,
- 0x0d79bd71, 0x0efa428b, 0xccfc883c, 0x5db2871a, 0xf5e9d430, 0x4cc42367,
- 0x3f3e4fa4, 0x7d12ddb5, 0x163fc927, 0x02ec7061, 0x24b19b96, 0xe02374fb,
- 0x38f2ee6b, 0x9b129027, 0xe49438d1, 0xb46f0cc2, 0x7eb00093, 0xcc78430b,
- 0xf860e453, 0x2395aa92, 0xb26b7eb1, 0xe6718055, 0x5ae79c5a, 0xced5fda9,
- 0x4b7bf1fb, 0x93252199, 0x9026caaa, 0x72287763, 0xdcc0896c, 0xa07787c8,
- 0x12fe449c, 0xfea2a50f, 0xf055a3b9, 0x56cf291b, 0x21d7000b, 0x78d2eecd,
- 0x055b1394, 0xbb6c0ee7, 0xa9a9e40d, 0x0d769e47, 0x7a817f73, 0xf4077d81,
- 0x255ffd07, 0x5d710220, 0xca1c726d, 0x75824df1, 0xb979c317, 0x059f080d,
- 0x6e9c9d0a, 0xc8e11339, 0xa3eb81ec, 0x65105ff8, 0x288b23cc, 0x3d141b6f,
- 0x79406486, 0x310e4e45, 0xca41f870, 0x3a3f11da, 0xa0e909a7, 0xc51292cb,
- 0x886f28fa, 0xf2c38948, 0xc912ad39, 0xaa9e9545, 0x7c2835d5, 0xa3be1733,
- 0x2a912bde, 0x56be9162, 0x74a44cb6, 0xcd9286ce, 0x24e3a05e, 0x9a3b1dc1,
- 0xb867a3d6, 0x13b5399e, 0x55bc47af, 0x9b4630ef, 0x7a496f00, 0x104e526f,
- 0xbed9ce3f, 0xbb41892a, 0xd3cddbf3, 0x5b17fe51, 0xa1a38acb, 0xd16dbcfd,
- 0x1e9052d9, 0x7ae6ca49, 0xc4ed4164, 0xacf00638, 0x2791fbf9, 0xe78fa0ac,
- 0xe8569f42, 0x70b69bff, 0xd4aa179f, 0x924fed34, 0x31dee780, 0xa1b3e279,
- 0xe0f142fe, 0x1f50a32d, 0xe2a7be08, 0xce23bea9, 0x503c87da, 0x0fc073d3,
- 0xdaf7a00e, 0xf51ef5ff, 0xd6f895f3, 0xbed0e5f5, 0x4885f6a6, 0xa6e167ec,
- 0xa15be43f, 0x49e8a0fc, 0x173ffec3, 0x45653fb6, 0x9edd6c02, 0xee7c7a85,
- 0x4f28b4a6, 0xf917f21f, 0xbd51f100, 0xaaf8205f, 0x517c33e5, 0xc7bb8406,
- 0x4c560ccf, 0xf480ccad, 0x8d625e7e, 0xf6a80f68, 0x323e5a8c, 0xf3adcb9b,
- 0x9093eb51, 0xb53fe64e, 0xccf50925, 0x5f3c1167, 0x6fadd4f1, 0xecf2dca0,
- 0xaf101a34, 0x38331d1e, 0x41799f51, 0x551d22bf, 0x93c6ff03, 0x04ae61dd,
- 0x0eca2a7a, 0x6fceb827, 0x51fa411d, 0xa77c179d, 0xcc74cff2, 0xd218f385,
- 0x748d99dc, 0x7f9d67ff, 0xcff3e22e, 0x17a766f5, 0xf5cd99f1, 0x4bd79fdb,
- 0x05ee58a5, 0xe47b4186, 0x885febcf, 0xd8f4b548, 0xfbd2256f, 0xd67684b2,
- 0xea36428b, 0x76ccf0ed, 0x1bb22cc3, 0x9d59d118, 0xc359d395, 0xe0e97d01,
- 0xa8c7b218, 0x37e746a4, 0x05af85f4, 0x9dd5bd8a, 0x80d7b7df, 0x87b3527c,
- 0x6d3511db, 0x508ec867, 0x855a92ed, 0x39ee179f, 0xda857643, 0x871f6eae,
- 0x5e3eed4b, 0xc801955e, 0x80e5cd1d, 0x0aba4200, 0xfbf905f1, 0xd3d7f5fe,
- 0x7bf26997, 0xb5df7f29, 0x750f2e56, 0xb7a8499d, 0x349c64d6, 0x976bfe20,
- 0x5e42fd2b, 0xbcde341f, 0x2f0481ec, 0xc16a1f2c, 0xfd8d0ef6, 0x9a2fbb50,
- 0xc36bfbda, 0x97bea356, 0x4c3a2ceb, 0xa42d6b9b, 0x8bd5b7ff, 0x9c5cba19,
- 0xed13985c, 0x916183b9, 0x07472859, 0x06653c2e, 0x3b6a0248, 0xbe50888f,
- 0x2f73ca3a, 0x031c67d2, 0x6f5090ae, 0x5fb405f8, 0x74f95e3b, 0x6e3ff604,
- 0x066be048, 0xbf0bd753, 0xf20c5e9b, 0x2d981964, 0x06671f64, 0x0f1d2046,
- 0xf4e5cc3c, 0x1ab67ae3, 0xb9d31bf5, 0xf72834d9, 0x3c42dca3, 0xdbe61b7f,
- 0x1dffff05, 0xfec60ff3, 0x143fc999, 0xd0a4bddb, 0x5968dba7, 0xaebcc02d,
- 0x8359ea1e, 0xd041be4b, 0x222d935f, 0xac34a40e, 0xdfe7a1d7, 0x82757b55,
- 0xc113a722, 0xc8bb408e, 0x416ec830, 0xf3366e3a, 0xccb209f5, 0xf71e611a,
- 0x8d9e1e67, 0xa76d7a7a, 0x9d611989, 0xc8c33a13, 0xe41c4d7e, 0x6cd6bd22,
- 0x2dbd224e, 0x02ac7438, 0x14ce1fea, 0xcfac3afd, 0xcfac3e4c, 0xae76214c,
- 0x9db19668, 0x6fb5f070, 0x960fbe51, 0x82891e2e, 0x47be0df5, 0x9d433670,
- 0x8f73aeca, 0x15a41bff, 0xfdec7697, 0x2dff4857, 0xe113b3ca, 0x75cbba7a,
- 0x5ba803c6, 0x39336d6b, 0xc160deb9, 0xef7838eb, 0xb13691b7, 0x9d1d7e67,
- 0x4dfb9ee7, 0x2726a62e, 0x07099fea, 0xa11fd225, 0xc3b0e9f3, 0x3d5287c4,
- 0x2c3b3bb2, 0xb0104fa2, 0x70f791fe, 0x164c137e, 0xbaf684bf, 0xb065ff49,
- 0xc48e617e, 0x935773e8, 0x83df614a, 0x938b1091, 0xd1747d47, 0x38eb7642,
- 0x3a550f85, 0xdb9b2b7b, 0x72296f8f, 0x73338555, 0xaf582cc8, 0xd66cf0a8,
- 0x1022faab, 0xf87b32ce, 0xaf529176, 0x932892eb, 0xf46d5e1d, 0xebb2e831,
- 0x33d250e0, 0x3fd9c9fd, 0xf601dda0, 0xf954f2c4, 0x5327845d, 0x0acdeef4,
- 0x2dfd54fc, 0xacdffd29, 0x8b66f1c0, 0x5376e1c8, 0x7a14dc08, 0x1e97a50a,
- 0xdb41887a, 0xeccf1ba3, 0x51a3f6be, 0x6bdf84c9, 0xfd78e61e, 0xedfaf090,
- 0xcd802b5b, 0x4dbfa0d8, 0x0cfefc21, 0xb98bf578, 0xedaf023f, 0x9bf578a1,
- 0x375e2187, 0xa0676489, 0xa376881d, 0xb5c0e507, 0x60f6e794, 0x51392306,
- 0xd7398529, 0x8077e324, 0x87c91643, 0x541f28a3, 0x15c430b9, 0xe9f506b8,
- 0x71e57069, 0x8db1017e, 0x10a4e797, 0xf6b0245d, 0xbc072c78, 0x277da1e7,
- 0x7e668699, 0xe5b7720c, 0xdfdedf01, 0x82cd3f40, 0x983ceb6f, 0x8b66f78f,
- 0x0eb7ed13, 0xc3d5e89f, 0x59a25a3c, 0xbf187ed6, 0x4e55fe65, 0x4533962f,
- 0xf8374c6e, 0xef837ed0, 0xbdf88d49, 0xe97f7f9c, 0x441f67ef, 0x8d33acfb,
- 0xb25abad1, 0x67da3a59, 0xf419652d, 0xdcaab7fd, 0xb7823079, 0xddf4e32f,
- 0x43e6df32, 0xa3e8f43d, 0x27a8e1be, 0xf1cbb65a, 0x510d4836, 0x981cf89e,
- 0xd38920ff, 0x94324b7d, 0x7059ba43, 0x7ec5cf97, 0x0df3e1ae, 0xff3d8794,
- 0x4e657414, 0xe506d105, 0x76231ba7, 0xe9555ca0, 0x2e30f074, 0xcf7887df,
- 0x7938456c, 0x7a8cb027, 0x8543ffe8, 0x0bf854de, 0x008d36c0, 0x3c1098f7,
- 0xa31774a8, 0xca585fc0, 0x413bcfe9, 0xf31d4f59, 0x0091bfa1, 0x38070953,
- 0xf0c11a57, 0xd5967483, 0x6ff38d93, 0x91f80c5e, 0x0f1c1d70, 0xdd5645a7,
- 0x155f07d6, 0x0df128e6, 0xa6f90218, 0xa9be7192, 0x7a42ba44, 0x0aba046c,
- 0x481647a2, 0xae173e88, 0x83ca15d0, 0x1cb8f708, 0xc257e758, 0xf0b1f21f,
- 0xa694ffad, 0xa4ce35f7, 0x1e2f2e1c, 0x734a7b33, 0xd04def48, 0x656f9dd8,
- 0xfa889a7f, 0xafbdf4e5, 0x149a6025, 0xeb8c9ee5, 0xd7fe5cd8, 0x1fff1452,
- 0xb8f407c6, 0xffcb0f8e, 0x2dda224f, 0x235f4b95, 0x79d2bffa, 0x37989996,
- 0x5d1ee01c, 0x00fd382c, 0x462d79bf, 0x16f824e7, 0x0c755c57, 0x6ad659e1,
- 0x56911874, 0x1c8d62d8, 0x408f2b3b, 0xda1d8a37, 0x39ba246a, 0xf4894bf7,
- 0x8b92b9c1, 0x0f800eaf, 0x4e0856e7, 0x32d657ac, 0x3790256c, 0xa816292b,
- 0xa057995e, 0x1ca9657a, 0x051a275f, 0xaf4037a2, 0xde283b25, 0x8ef5a731,
- 0x13df88a9, 0xa40f5fc5, 0x187ac1f8, 0x2e63e547, 0x959e48de, 0x56abf529,
- 0xbb47911b, 0xacb597bf, 0x3ffc88ba, 0xde521bd3, 0xec53e93a, 0x5b51acb7,
- 0x8235c6ee, 0x4e57771d, 0x07ca0c44, 0xefce64e6, 0x40f24811, 0x93fa0ff2,
- 0x447140bb, 0xc20f30cf, 0x61bc89c3, 0x99eba47a, 0xdba05708, 0xdd7ca5e8,
- 0xbe0aa733, 0x99ceb049, 0x1f67ce16, 0xfbbe0996, 0x09ff3e05, 0x5065ef40,
- 0x5d740b1e, 0x38e4c316, 0xe626dd48, 0x2e79c70f, 0xca09f61d, 0xd438d3db,
- 0x8fefaa28, 0xf75ca1b4, 0xb78911e8, 0xe5a52f32, 0xede947cc, 0x98f34fcc,
- 0x74933ac1, 0xfc93af90, 0xf38e312b, 0x0367b32b, 0x8b5fd7d2, 0xe0169c4e,
- 0x4239ddfb, 0x439428de, 0xdd68038d, 0x701f5b97, 0x067680a5, 0x5fac41aa,
- 0x147ee396, 0x4ccab3fb, 0x74ab718f, 0x995a8e95, 0x17d61537, 0x9be2debb,
- 0x6b8beb04, 0xf5c21cf5, 0x38374fa6, 0x1383ef10, 0x74133af8, 0x543f9fdc,
- 0x81a3606e, 0x183f360e, 0xdb3a43e6, 0xda2035bc, 0x03e6fea1, 0x97cc0180,
- 0xf0bc14af, 0x4e61eadd, 0x7559d38c, 0xfeed111e, 0x188f56a2, 0xe1a7e208,
- 0x394441b2, 0x23d3be91, 0x5ab49ea2, 0x353d53d7, 0x4fd4ac5f, 0x59067937,
- 0x4e9e4ec9, 0xa15c33f4, 0xd49fb51f, 0x045f8356, 0x4ac917b8, 0x57b7997d,
- 0x9e8a61fb, 0x3961db56, 0xab7a67d2, 0x453f4fa3, 0x3f505b4d, 0x08f88f83,
- 0x7bd205c6, 0xfd711fca, 0x1bf084da, 0x36abf378, 0x2103374c, 0x9d1c71f8,
- 0x79e34cc7, 0x15d33cf8, 0xbfbf87da, 0x63e38f7f, 0xb9bbf01e, 0xe422fef5,
- 0x1f00cda3, 0x9de6f3c4, 0xcfd4ccb3, 0x799a59f4, 0xf286a931, 0x4b070825,
- 0xa23c75ef, 0xd53d2fcc, 0xbd695a23, 0xe76843ce, 0xe28ccba5, 0x763f6a01,
- 0xf405741d, 0x857a776a, 0x90cbcc7a, 0x47b8945a, 0x4eb38e3a, 0x5d31ff40,
- 0x6b4957c1, 0xf63361fd, 0x5f1466e3, 0xfe85cf4c, 0x8426fea1, 0xfc37a183,
- 0x5e99e742, 0x4273e7cc, 0xf18edfa9, 0xe76c7494, 0x74431158, 0xd5d7e7c5,
- 0x1c6214ea, 0xa08fb197, 0x7e90c9fd, 0x0cb8c29e, 0x7e4ecfa4, 0xb42e4a6d,
- 0x97d1fe7f, 0x52d0b476, 0x0fb33e0e, 0xf5ab56e5, 0x9c709be6, 0xff9f2283,
- 0x5de2724d, 0x206ddf98, 0x53be9a3d, 0x7944db4e, 0xebfd1393, 0x55df56ae,
- 0x2cbd422f, 0xeb64c618, 0x0a138f3d, 0x3a15da9c, 0xcb793938, 0x53ef5c20,
- 0x582c7745, 0x5f87ed02, 0x3b8d38f7, 0x94fcca7c, 0x9b0fc816, 0x30abcbf8,
- 0xc78e5f7f, 0xfee4023c, 0xde5fd2b0, 0x6ae50fb6, 0x821cfce9, 0x4576c597,
- 0xda39a9f2, 0xbf02f5e3, 0x52dc4737, 0xd2b8fc8e, 0x24487066, 0xfa19eb77,
- 0x7711cd59, 0xe5bfb1db, 0x4c26f9d1, 0x36bfd60d, 0x6e3c9ca1, 0x1e2131c9,
- 0x18132d9a, 0x0aaceb96, 0x4f1bbe9e, 0x885240fa, 0x73847772, 0xe5744cba,
- 0x0c272864, 0xbcad0609, 0x2f7971d6, 0xb43e1dd9, 0xf5acba9f, 0x60cc8148,
- 0x7ca05409, 0x69795493, 0x3c717a71, 0xa3b4e2c9, 0x9142b4bf, 0xaf862c37,
- 0xf73960d3, 0x5eaf389f, 0x962e63fd, 0x867f4b50, 0x4128ccb0, 0x9bda3ff9,
- 0x573e10c6, 0xbbc58353, 0x6844f518, 0x70205d7f, 0x4fa38e50, 0x7e337647,
- 0x5eddee48, 0x7a341bb2, 0x7a5e5ba4, 0xf221f5a2, 0x7a811e52, 0x792058a2,
- 0x0ceb61e9, 0x0c12feb8, 0x3c5c00b2, 0x545eb8db, 0xce267bf9, 0x49e5f005,
- 0x5e5c9165, 0x2673e4e9, 0xd1efc60e, 0x452a5cae, 0x5e021e22, 0xc3e9e0c9,
- 0x9378f79f, 0x9d1e507f, 0xa987fa41, 0x21fe9007, 0x0fe144fd, 0x6f078a8f,
- 0x50a3f5d9, 0xd912cb5f, 0x85cb9503, 0xe2cfb436, 0x6947d1bc, 0x2edcc5be,
- 0xa6bf9768, 0x892a1cf5, 0x7979444b, 0xc799d962, 0xbebd41ef, 0xfff49c29,
- 0x5667a5a4, 0xa66e3c60, 0x211a7057, 0x7d1a59ef, 0x6f987bf7, 0x905d3a34,
- 0x81f0ab3f, 0x914597fb, 0xb8084f68, 0x759e8cce, 0x83321656, 0xf139e29b,
- 0x3b409633, 0x34e0a34f, 0xa1e07a3b, 0xef527ac7, 0x37bc05f5, 0xfad0fe46,
- 0xa8d7bc3f, 0x3e7759c8, 0xc6a2d9ca, 0x700a87e4, 0x7cf5eb5d, 0xd7d18d9e,
- 0x3927de53, 0x1cb97639, 0x3fd8a99e, 0x57b3a59e, 0xc0f7c3c6, 0xcef9416a,
- 0xc8a956f1, 0x88e340e5, 0x0d3f1863, 0x3e48172c, 0xa252bc79, 0x5ccdda1f,
- 0xef784d9e, 0x5d900a28, 0xb43de5d8, 0x722b5a92, 0x3674a3de, 0x94588c17,
- 0xe3dfa76f, 0xfe479ffe, 0x9bb62563, 0x83b5a2d3, 0x0cfd0226, 0x67bcb840,
- 0xf1e9fd26, 0xefbad196, 0xea6945f0, 0xd38ead55, 0x8bab3de4, 0xe7b0c7ae,
- 0x52277bac, 0x3992af3c, 0x2ade9122, 0xc1376e65, 0xe61b259f, 0x4f9d5733,
- 0x2ac7b731, 0xa27ec18b, 0xb07b5aef, 0x3389fec7, 0x78a8df20, 0x3a13f154,
- 0x19765eef, 0xacd076e3, 0xdd7ada75, 0x16301076, 0xe5caba8a, 0x32bf76da,
- 0xb9459fbb, 0xe038dee8, 0xaeabf21b, 0x80821e50, 0x266e7f21, 0xa61f71e3,
- 0xced543e8, 0x517a592f, 0x6668728f, 0xc23d45e3, 0x1fd2e673, 0x385fa7e6,
- 0xa1bef3b5, 0x3ebb4a20, 0xbf934e39, 0x534435d1, 0x30f766ff, 0xa75bf7cd,
- 0x5ef9ab5f, 0xc9a919ee, 0x5e3d5edf, 0xfd467f53, 0x7a1cad24, 0xa3d69a37,
- 0x79bfa7e2, 0xa3e8a5bf, 0x12ec4277, 0xe23a9d35, 0xbf91133f, 0xe4672c3f,
- 0x33787cbf, 0x1d31f8d3, 0xe7822423, 0xf93d5c80, 0xc8e5f731, 0xbf208fef,
- 0xa1f44fc9, 0x7343f3c2, 0xa228c9a1, 0x7ee4627f, 0x725fa879, 0x5e503990,
- 0xfdb1d4ce, 0xff8f5442, 0x9cf30e67, 0xe3bafec7, 0xf10f4b0d, 0x1f884378,
- 0xff78a573, 0xbfcc0670, 0x4d79790f, 0x16c3f72e, 0xffaf36ee, 0xb58e0838,
- 0xfc9ad16d, 0xebf1fda2, 0x3bd60e3f, 0xae1d044b, 0x93e146b3, 0x7da0165a,
- 0xa0e8bb52, 0x40c4eafe, 0x583be62c, 0xf4b46c67, 0x0a8b838f, 0x258f800f,
- 0xa9de2837, 0x193fc3fa, 0x9e0a453e, 0x1a70b4cb, 0x90e3cb93, 0x29108f5f,
- 0xc7239cdd, 0xf103fee7, 0xf49eb41c, 0xdc7fbcdc, 0xc847227a, 0x9f9f0859,
- 0xe3dfaf1b, 0x17940f1e, 0x7f0b908e, 0xfe4cb826, 0x47a5c247, 0xd82f47cf,
- 0x72a3fa0d, 0xfdfb819d, 0xbf5c33de, 0xfefd7237, 0xf68fb47c, 0x44f39b87,
- 0xed070ee7, 0xe93ed297, 0x618d7ba1, 0x59df1819, 0x797d23a1, 0x8190997a,
- 0x2126c2fe, 0x0f36fc8c, 0xc81648ab, 0xc878b9be, 0xaa31fd48, 0x3afded07,
- 0x0551f390, 0xe4096b3e, 0x71e5ccdf, 0x716e35b1, 0xf5038a4a, 0x1eac1ff6,
- 0xe27a8b8a, 0xfd9e1e11, 0x696be130, 0x2bee45df, 0x6bd0127e, 0x8512d1e5,
- 0xd5cc5f8f, 0x2e1f3ad1, 0x949db914, 0x1f70ba2a, 0xa9d81563, 0x96065768,
- 0x915f28eb, 0x6d59e9c7, 0x9d0a1ff7, 0x14dd94c7, 0xda88f386, 0x7d7dba24,
- 0x2e51fb8c, 0x793d0f8f, 0xb3ed1857, 0x68742a01, 0xd6bddbef, 0xaf582e69,
- 0x8d96d0bd, 0xdcdadfb6, 0x4d6fea68, 0xcf159746, 0x748cfca1, 0xfe8eca78,
- 0x8cfac0a0, 0xe655cd33, 0x580feeab, 0xe936fe94, 0x9da2bf41, 0x1e289822,
- 0xf91af161, 0xb16715f9, 0x1ccade26, 0xa76e0b02, 0xf428f3d6, 0x1b42c76a,
- 0xeff697e1, 0x5db178d5, 0x1ba417a1, 0xcf4abbc4, 0x8983fda1, 0xe9cc8dec,
- 0x15d9f389, 0xe51a8e52, 0x8f748dd9, 0x1f90eafd, 0x07fe5cbc, 0xe3c4be6e,
- 0xded7de2c, 0xe18879c3, 0x0c9c525f, 0x5fce4aec, 0xbee2434b, 0x024f913f,
- 0x40cf0e66, 0xde1e5684, 0xdac9d0ab, 0x48de827f, 0x3ebc02ba, 0x8fe5cb9c,
- 0x36fdc0ab, 0xb2c73bca, 0xfba230d4, 0x96270b1f, 0x51384560, 0x3872ba5e,
- 0x1f3df379, 0xcc749e10, 0x7f71b46f, 0x72e1f90b, 0x31c2a47c, 0xbe9e6449,
- 0x3c88f2f4, 0xca1bfbe5, 0x6ab7ae7e, 0x61d90fc8, 0x02c57728, 0xcc2cd2c6,
- 0xffb6bc61, 0x8f9c0e7a, 0x396ae885, 0x96aee5d2, 0xcfe43094, 0xcabc6564,
- 0x0ca7d29b, 0x205fa077, 0x040ed018, 0xe3c0c3bf, 0x574edc3f, 0xb94f7ae5,
- 0x72c47ed6, 0x1f8f664f, 0xeaf7daa6, 0x82973c77, 0x59f3aae3, 0xfd61d8a5,
- 0x125577cd, 0xdca2724b, 0x808f765a, 0x5ab1dcf0, 0x717df8d4, 0x0325615e,
- 0x7fce3e3f, 0x8efd13af, 0xcdafb038, 0xf575cf28, 0x5e083382, 0x0a817b81,
- 0xf8871338, 0xe24fe02b, 0x8967bd3a, 0x57c7425e, 0x85abb1d7, 0x5de71b8f,
- 0x9f90c82c, 0xa02f5154, 0x9956b7df, 0xa3055c7f, 0x3e9969ef, 0x9e21e301,
- 0xe38a5616, 0x03335655, 0x332af5c6, 0xf2865399, 0x7443c6ca, 0x02b9edde,
- 0x206f2539, 0x4f3a4fc9, 0xa4f02ae3, 0x4d1d01e7, 0x7643284d, 0x864bb867,
- 0x167f89f1, 0x4cb5a71d, 0x59efa2f0, 0x843ce2d4, 0x11d001fe, 0x2d3c7dc5,
- 0xe75f1a01, 0x5d7271e5, 0x80e9c18b, 0x658d4875, 0x5521ffb4, 0xd4329c1b,
- 0xdf29b63b, 0x2d95f18f, 0x0ddfdc8d, 0xd67493f5, 0xd1c3d7fa, 0x9910ab5f,
- 0x790a0144, 0x5659fa2a, 0x30562e85, 0xf7ee3b77, 0x41fe1933, 0xdca548bb,
- 0x2a6f3d5a, 0xd0e52266, 0x13dc8378, 0x6b9e409f, 0xd3b240dc, 0x678daa94,
- 0xc92b2d48, 0x7d6233af, 0x890faca8, 0xa5d54877, 0xac971714, 0xf35bf2da,
- 0x8e086222, 0x9e1e3c59, 0x8d88ef73, 0x727cc2b7, 0x1fe3797f, 0x41873d30,
- 0xfe5b8033, 0x4c073bb2, 0xac16ff87, 0xa62378d8, 0xe8cebc4f, 0xe08fc19c,
- 0xfa8c6657, 0xe8fafcf1, 0xb2abf295, 0xb9d00f26, 0xd27dafc2, 0x094f1abf,
- 0xfe954fe5, 0x4d4ef943, 0x7f865ed7, 0x120526d7, 0xdf4f0f91, 0xdb03323b,
- 0x73de3657, 0x5f88c7c8, 0x77d00705, 0x117177a5, 0x5660ba23, 0x5e5bd097,
- 0x490b3784, 0x1f37bfec, 0x3b7c863f, 0x13e7effe, 0x95df087f, 0x63ce8c09,
- 0xf649fd81, 0xdfaa9a9c, 0x3eb9f223, 0x246790bd, 0xc1464ebc, 0x053bac0a,
- 0xc7bee0da, 0x2b4e6078, 0xf02e7fa4, 0x4de38b3c, 0xef9e3c81, 0x6b40fd7b,
- 0x4b37ae0c, 0xa78ef5c7, 0x76e68edb, 0xa8ffb748, 0x06590fd8, 0xdced0536,
- 0x771126c0, 0xc0e0596e, 0xe2d63be7, 0xc9b96bbe, 0xcaeb0699, 0xf448dfba,
- 0xf68a0484, 0xa7689651, 0xb6aee5b8, 0x9f69cb8f, 0xd2c0d1b1, 0x0ee06e28,
- 0x006473c3, 0x4caab0cf, 0xacc357b2, 0x857aaf68, 0x1e88aaa4, 0x22f5087b,
- 0xef2cb40a, 0x30ac53ad, 0xb042aefe, 0xec7b3347, 0x59fed51c, 0xeb4c9f9c,
- 0x6820ed57, 0x8fddb0c7, 0x0b4aa7e5, 0x19bb224b, 0xf7fb83e6, 0x90264cb6,
- 0xff5213ed, 0xd92332f4, 0x7baf76af, 0x5bb470ca, 0xa0e6a797, 0x9ae30add,
- 0xfd7f6e24, 0xbb67ca3b, 0x285ef94e, 0x49b9e0e6, 0x05801f75, 0x8718d174,
- 0xfeaaed53, 0xe763a5e7, 0x9505b954, 0x9f2f9b7f, 0x59ff7ec1, 0x5563dd72,
- 0x634d4de8, 0xe9e079f8, 0xcf8dbd0a, 0x9e9a5337, 0x73dbb3ff, 0xfe93aea7,
- 0x39feeb79, 0x9ffae1d7, 0xffd88eb1, 0x3cd8f821, 0x3ac67ff9, 0x4ff2996e,
- 0x5f37875c, 0x43cfc86e, 0xe746d679, 0x7e2eec88, 0xdee41c2e, 0xcb9cbc3d,
- 0x09938b39, 0x74ffc764, 0xfd84d779, 0x1c1f419d, 0x7778a1cf, 0x67183a08,
- 0x88a1a588, 0x8ca5cdec, 0x2c8681f6, 0x4340fbe5, 0x224d3a96, 0x6e1603da,
- 0xec520e27, 0xb94b41ce, 0x9ca719dd, 0x118b882b, 0x3fd4327d, 0xca5bcbf6,
- 0xbee0c6e7, 0xd5ec9190, 0xf5dd36e6, 0x5e53d416, 0x868fce89, 0xd2d289da,
- 0x5f9c4a95, 0xf6aa9f6b, 0x79e31a68, 0xb4b3b2fd, 0xa3daa74f, 0xb4f29443,
- 0x603f7ca5, 0x1ed68b48, 0xdad6ab8d, 0x1082fa8f, 0xbaa9733b, 0xeb49d07f,
- 0xe9d72dd3, 0xa87ffcf1, 0xb07b89dd, 0xab0714a8, 0xfeb4067a, 0xf630d74d,
- 0xf9f77e74, 0x1fdc1c8c, 0xd05ab99a, 0xcf5539e8, 0x7e282402, 0x43e3e2a4,
- 0x3f8873d4, 0x5fb534f7, 0xaf3e6fd2, 0x2e4c7048, 0x539cd74f, 0x1e7eec62,
- 0x3a73712f, 0x11eaf5fa, 0xddaed16b, 0x37c6eeb7, 0xfd697d31, 0x04e5e19d,
- 0x6f54f5af, 0xebc6cb7f, 0x7650ff30, 0xe6123dbb, 0x53a8d0f5, 0xefd009ef,
- 0x85e33c6a, 0x2978b3eb, 0x9e14b68f, 0x7ab3d08b, 0xa4dbdfda, 0x0d9f4c0f,
- 0x45122be5, 0x23be911c, 0x1832981d, 0x59309f9d, 0x35f57e78, 0x30e3ee8c,
- 0x1a9f5ce5, 0xd73d0987, 0xc7c3cab7, 0xc4f00559, 0x18963573, 0x39a91f7e,
- 0x08e9fee1, 0x818766ef, 0x8b3939e1, 0x624fee72, 0xa82aaed5, 0xbf7edc77,
- 0x0bee167d, 0x7e881867, 0x26ce98a4, 0x9ed993c4, 0x71c2af63, 0xcd35e242,
- 0x2037e929, 0xfbb5bc59, 0x20679ef0, 0xc9cf7b7d, 0x2a9d312f, 0xf3c3efb5,
- 0x88465225, 0xbf6bd29f, 0x9bdc1198, 0x4a5f3387, 0x6e3b9632, 0x754e9110,
- 0x869a6feb, 0x50c154fe, 0x4f581ae7, 0x1bf30258, 0xbd611e60, 0x7b7989f6,
- 0xce9c20a9, 0xf59648d5, 0xdfd80d15, 0x7fba08a8, 0xae03bec0, 0x4df3a7cb,
- 0x80f657f4, 0x0e3a47a8, 0xc38ff653, 0x1fed7b32, 0x30c2fcd3, 0x3b59e14d,
- 0x7a15c3e4, 0xca7b635f, 0x6b77fb87, 0x106e5213, 0x69f53d1d, 0xbbd6195f,
- 0xab1bbbf2, 0x26fd5f68, 0x9fcf1593, 0xcafb2985, 0xa574e3a1, 0x43675b3a,
- 0x6418b46a, 0x55f11673, 0xe0725f0f, 0xe68353d8, 0x9cfaf501, 0x736e3aa7,
- 0xda83c71e, 0x64c2d19f, 0xf74323b4, 0x81fb43ad, 0x56be7079, 0x31fda9ea,
- 0x01e746d6, 0x518b8874, 0xa7abb57d, 0xe9df0db9, 0xff1fbb24, 0xcc82e382,
- 0x35fc431a, 0xcedb55ac, 0x0dcfca9c, 0x2a18f4a8, 0xfdd0a52f, 0x6f7ad4f7,
- 0x9f81e138, 0x1fad0827, 0xf6d0d70a, 0x5833b7f0, 0xe160ddde, 0xa95d88fb,
- 0xac22b99d, 0x473da57b, 0xbf5a7f33, 0xef7fd3d0, 0xbe6d3cfd, 0xb9f6364c,
- 0x7d07943e, 0x4e8277cd, 0x6c596fbb, 0x8d2fb6d1, 0x25777ed1, 0x4592f368,
- 0x6d91dfe9, 0x8e1af3a2, 0xf79e137c, 0x18d8f953, 0x8af7efe2, 0x2efa2adf,
- 0x1e74c991, 0x79de9375, 0xe3c4e50e, 0x01d24033, 0xf82c3c7d, 0x552e58cc,
- 0x0f515bb4, 0x93d3adc6, 0xaefc7a9c, 0xbde0ce5b, 0x6ba016a0, 0xf771e584,
- 0xc56e9b47, 0xf148b17c, 0x70fb9b0d, 0xcb51d239, 0x37bf5f77, 0x3a9fcf1b,
- 0x5bce740d, 0x75b1b73d, 0x1e2b61ac, 0x94cb8a0b, 0xfdf069cd, 0x84e62aa1,
- 0x6323b099, 0xfc712363, 0x15a2d12d, 0xd1f3ddf5, 0x718efff5, 0x8c19e694,
- 0xe14219f6, 0x46d23757, 0x756e3672, 0x5bf780b6, 0x5f9b1e1e, 0x06317289,
- 0xaf9465fc, 0xc57dca90, 0xf015c717, 0xc5b6c0f8, 0xbe23c52f, 0xdb0f5837,
- 0xa2159e69, 0x52d8a713, 0x8b7fe5c1, 0x7b3ed185, 0x3752a8f3, 0x72ec4d1e,
- 0x8b3c0ec9, 0x41dee2d8, 0x2d595ef3, 0x9cacd972, 0xc8580197, 0xbe9c3951,
- 0xfd4a360c, 0xb3346e98, 0x972839f8, 0x7ce8c292, 0x81f67f50, 0x57cb84b4,
- 0xe9cc6f6c, 0x1143debf, 0x5cc8f18d, 0x9fe467cb, 0x6dfd0b9f, 0xf299b19d,
- 0x538d3caa, 0xdfbbbbe8, 0x1bba3d10, 0x36724bf0, 0x9e2ce41a, 0x878e63c7,
- 0xf575b789, 0x3a20b4c2, 0x7c8055d5, 0x2ee7e2cd, 0xbebb7e30, 0x87e334a8,
- 0x9b9d4cfc, 0x5518e5cb, 0x97ebbb1e, 0xda05dc61, 0x635f51fb, 0x0fce783f,
- 0xb7d71952, 0x443fa851, 0x830cf37e, 0xe839ef03, 0x430e402a, 0x56825d7b,
- 0xc9181c4f, 0xc1fb35f1, 0xa09eccbb, 0x728c4d38, 0xbea3661e, 0xeb069cde,
- 0x744338d9, 0x6c78076e, 0xfa1068a9, 0x55c4c78a, 0x0d997e70, 0xde6fd1f5,
- 0x1b139152, 0x8c669ebc, 0x36d0c073, 0xdb9f0fd7, 0xbfc885d3, 0xbc79235d,
- 0x1cdd67bd, 0x3f4071be, 0x479a87a8, 0x6ae6ae97, 0x557241da, 0x6d6de567,
- 0x073a7aae, 0xcfc155d9, 0xf813ad5d, 0xc4a4827e, 0xf28b9bcb, 0x4bf4bf49,
- 0x492b152f, 0x57e2849f, 0xe5fd3f9d, 0x9911e907, 0x8719f1f1, 0x4cceb49b,
- 0xda07e1fa, 0x4af9743b, 0x1e0bd47d, 0x62ba7f6d, 0xf8e33651, 0xaf105fa8,
- 0x7bc5e63a, 0x95fda193, 0x3a16fc2a, 0xe069c91f, 0x8d9db1ed, 0xdbf48bf8,
- 0xc8e00169, 0xa1ce82e9, 0x3c38f7b3, 0x7c3a24b7, 0x2e01f86b, 0xae7487d2,
- 0x78f7a52b, 0x658e098f, 0x7de8efb8, 0xe7f3a25d, 0xcd4f7aa1, 0xb13070ab,
- 0x3e9ce736, 0x0f9c4dec, 0xa76935ea, 0x01fa89d7, 0xed8a97d0, 0x094b2a36,
- 0x5cd4b3bb, 0xd7ade8e0, 0xab6d5cba, 0x937282af, 0x03f69983, 0x99534c3c,
- 0x79c0307f, 0x1ccf33ed, 0x3df58abf, 0xf803ae0e, 0xe6bce099, 0xe63347f9,
- 0xedf37b40, 0xb9b426ad, 0xf5a1cf43, 0x76a4ef6e, 0x4cab4b71, 0x23c519d3,
- 0x86b95465, 0xafd90b08, 0xe48674cc, 0xc6c934b3, 0x3d10a7ed, 0x50f80eb9,
- 0x644af08f, 0x38d0af04, 0x49f8e871, 0xdefcc905, 0x1a52e2e4, 0xa7454377,
- 0x5d90e31e, 0x4ec57aae, 0xefa9f4f2, 0x7bb1fb42, 0xff23a73a, 0xc81a1577,
- 0xc1f87e1e, 0xcf119349, 0xc51265de, 0x7bd17ad1, 0x233dbac8, 0x1cae9cf5,
- 0x7f28cd8b, 0xdbb9ccb7, 0xfec3e8ec, 0x8b3152d8, 0x965a2fce, 0xa5633b70,
- 0x88e481bd, 0xe7b942a5, 0x71cbd8a2, 0xa213bfaa, 0x3754b727, 0x9bdef198,
- 0x8590de7a, 0xed97dbd8, 0xbbbd1fbf, 0xf18bf961, 0x2aee4fa8, 0x79c78869,
- 0x4ff0896f, 0xd5df1377, 0xf2029f93, 0xf1e51e38, 0x920e91a2, 0x7ff2dd2f,
- 0x0e3b39c6, 0x5569181e, 0x43db8af8, 0x417fe25f, 0x928d66bf, 0x1c6014a7,
- 0x8e44b52d, 0x74bc6076, 0x00d3bbdf, 0x7abd93ae, 0xfb8d63f2, 0x2fc1f481,
- 0x49382632, 0x681e9e5f, 0xac9d22b0, 0x8f46fc6a, 0xe2ce6bf7, 0x7fe855e9,
- 0x87b70255, 0x9818c556, 0xa1f342df, 0x2e754f45, 0xf5a7a866, 0x0137dc09,
- 0x798fc5bf, 0xfd102316, 0xbaf18e4c, 0x298700ad, 0x30bbbe31, 0xd7ac4aad,
- 0x129c60d9, 0xf080b447, 0xc563a29d, 0x9daf1e06, 0x115cf385, 0x59c511f3,
- 0xd1c5a727, 0xc5a3547d, 0xc9fbc3ad, 0xf6d5677a, 0x8bce8cb5, 0xb015bc51,
- 0x8ce1f74a, 0xb6bdc718, 0xeeab8e27, 0xdcf1a913, 0x04290575, 0xffc1212f,
- 0xcb23e22d, 0x1ef1101a, 0x403e987e, 0x46aaf8f6, 0xcd41f913, 0x91da3b09,
- 0xf823323d, 0x3e7aa43e, 0xb163e017, 0x0c567c02, 0x95d69bbc, 0x17bb1494,
- 0x91faa5e7, 0x50af20f1, 0xcc2565de, 0x4beb8a9b, 0x4aedc37a, 0x0cc67a86,
- 0x1660365d, 0xa2b9eae0, 0xc61eac78, 0xd8583c21, 0xabfb4c38, 0x40d122bf,
- 0xf2d0d8f1, 0x5c780b27, 0x21050b32, 0x135eebae, 0x755dcfdd, 0xaaf7bee0,
- 0x301e7e50, 0x6767c939, 0xffbc1481, 0x66771dde, 0xaeddff7c, 0xdbb5bf9c,
- 0xa63f740d, 0xf8ccbe3b, 0xe71abcbe, 0xd9e51a88, 0x31f2788c, 0xc7f421c7,
- 0x8f71abfe, 0x4fca461b, 0x6dac7f60, 0x63c515c0, 0x68eac6c2, 0x8529279f,
- 0x05f78279, 0x5feb2956, 0x7a870dd5, 0x75f5ea3b, 0xf6079428, 0x378d870f,
- 0x2226bbe7, 0x88ec46dd, 0x47dafd47, 0x171343bc, 0x79287bc1, 0xfa6204b1,
- 0x9c79aa93, 0x3cea6624, 0x5348778a, 0x0ad93ef9, 0xdcfc6016, 0x7c84c0a0,
- 0xfd4beaba, 0xe887700d, 0x927accd7, 0x90ae9193, 0x7f2f48b8, 0x6576e645,
- 0xa2dbdc88, 0x02f1f9f0, 0xcf91ee25, 0x93e7bff2, 0x5228bb25, 0x1889f7d9,
- 0xe8724295, 0xd90a5711, 0x411cc443, 0x9d9cbef0, 0x87b15073, 0x8f9ca77e,
- 0x83e72bf7, 0x83e72b0f, 0x0b77c55f, 0x863f90c0, 0x7a4016ef, 0xe549c9bc,
- 0x2815346f, 0x6fe399ca, 0x4892ee45, 0xf9941fb2, 0xadf994e9, 0x25734eb0,
- 0x6d567e03, 0x5879d3d3, 0xe984c263, 0xaf32cf68, 0xdb119edc, 0x7587ef73,
- 0x9efcbfc2, 0x095da773, 0x3a4f3a1e, 0x3ff7cac7, 0x542d7c55, 0xb612afea,
- 0xc75f9019, 0x36e16a76, 0xc6a452fe, 0xda622cae, 0x4d1397f3, 0x4bf53443,
- 0x97f3daac, 0x6ad7ec93, 0x68764fbe, 0x975e5fcf, 0x1f643e31, 0x0b574b56,
- 0x806e8013, 0x7d33aa4e, 0xd685ff34, 0xcd7b8a52, 0x74c7b90d, 0x3f36ab47,
- 0x2fcda7df, 0xabcdaddc, 0x46c3c9e7, 0x9230f429, 0xf131fc8d, 0x0cf7e44e,
- 0x0107ef85, 0x3ab36fbf, 0xcfda1199, 0xf8bf7816, 0x1b00c61e, 0x76c94bed,
- 0xe3ac238c, 0x5cb09ff7, 0xc3bdcbc7, 0xbe7af695, 0xdb8ec56f, 0x4b1dbee8,
- 0x06ede1cc, 0xfc7eeff0, 0x72f1a48e, 0xfe87af0e, 0xa21bd612, 0xe5c353f4,
- 0xfe459c93, 0x33ec9b82, 0x62b36b23, 0xc2fe016a, 0xe9399a34, 0xab0c759e,
- 0x9075bf27, 0x51327f72, 0x43bca4e8, 0x3e6186b0, 0xf0a67045, 0xe48f85f8,
- 0xfe4950c3, 0x89f12a75, 0xf447745b, 0xb90d97e6, 0xaaf007ba, 0x910286f8,
- 0x5623e2e4, 0xd8f9ef46, 0xbf13f75c, 0xb016c36e, 0x8f6b336e, 0xf87a1549,
- 0x61bcede7, 0x5c135fc4, 0xb52fda0e, 0x780b2415, 0x8588a52e, 0x4536cb9c,
- 0xc4a3e869, 0x5f42171a, 0x4be84243, 0x9d7f7f4b, 0x3945d5ec, 0xe842ce90,
- 0xe5be2ff0, 0xaf182c51, 0x05fa8f4c, 0x7689d58f, 0xca9e054a, 0x754f9602,
- 0xee319b46, 0x73d18b67, 0x3fd8a579, 0xab9f4aa5, 0xb2eb59e4, 0x566bfbe1,
- 0xf6e649d1, 0xf13d2dba, 0x96df1825, 0xea35f600, 0x5c919963, 0x1fd3b07d,
- 0x7fd43576, 0x65fffc04, 0xeb1bfd0c, 0x65efbc64, 0x5f10e4b5, 0x7949623f,
- 0xd05ef300, 0x437f58e8, 0xe5aff731, 0xef826ce8, 0x05bea151, 0xc23da5ef,
- 0xc1a94cf2, 0xfebc2df5, 0x5164597a, 0x31189f90, 0x9dbfea82, 0xcef86667,
- 0xd9a07781, 0x63ec7187, 0xdd77acf2, 0x7b7feb41, 0xaf07d714, 0xa8f11c19,
- 0x7c991e0f, 0xd287a677, 0x685f8d74, 0xbee4104b, 0x8f8517ce, 0x92bd7236,
- 0x78c7e25b, 0x34c2747c, 0xfd039957, 0xe90bb71d, 0xf112e742, 0xfd375be8,
- 0xa87e2b44, 0x0fc106e4, 0x5d749b4b, 0xe3ff430e, 0x35770b11, 0xd59e291e,
- 0x02f98652, 0xd903ee91, 0xd9ebe25c, 0x7e02aeb8, 0xe54af0fe, 0x181ea871,
- 0xbfdb9a32, 0x3c448693, 0xdffa1430, 0xb15a2450, 0x2b7a0dff, 0x4ef1e7dd,
- 0x1757e466, 0xe097eabb, 0x11096dbc, 0xda6fcf0c, 0xbe781a0a, 0x00ccc0d8,
- 0xbd6b934f, 0x4a69f117, 0xf6c08cf5, 0x7a7e0747, 0x5b19ed1c, 0x703a4882,
- 0xaef9cba2, 0x2817eb1b, 0x79e29df1, 0x9b3c70eb, 0x599ab445, 0xb9541c0f,
- 0xcbc99ebe, 0x0ab2ffc9, 0x0accdef4, 0xce0d436b, 0x708491e7, 0xae6df3b2,
- 0x79e20b06, 0xd13d40c3, 0x7f224941, 0xc2556a57, 0xffcc0ab4, 0x7191a062,
- 0x1f2ff3be, 0x5381fe8a, 0x5b3575a0, 0xc75e681a, 0xc139892e, 0xa9a896ef,
- 0xcf85a1d9, 0xf8f146ef, 0xf1e30990, 0xf5b79f80, 0x8b9a9ccc, 0x78a7a3f4,
- 0x6b7c7f53, 0x7ece5d73, 0x2afe61fb, 0x110b0394, 0xc29785be, 0xfa404f98,
- 0xfe61293d, 0x5b017f77, 0x60d9d680, 0x6e41fec1, 0xbfa2fabb, 0x7e9cd188,
- 0x4b0e0b9b, 0xd7824ef8, 0x341f1021, 0x444e4e5b, 0xb528783e, 0xa1e8e88c,
- 0x899a8f82, 0xfcf3862f, 0xeef779db, 0x137a3c41, 0xe77f69c3, 0x315982a1,
- 0x60bef4c1, 0x32f44894, 0x4e616fee, 0x9463e23f, 0x91fbf881, 0x8c56c708,
- 0xccf3794f, 0x824bbf64, 0x986cd975, 0x2862c4e7, 0x5da2fe87, 0x7ef13e62,
- 0x0b8f0575, 0xd57e302b, 0xf8843b65, 0x31664a90, 0x3949ae7e, 0xef9114f7,
- 0xb435435c, 0x25956ffa, 0xd8cfde97, 0x4270d092, 0xbb20b6d9, 0x5722906a,
- 0x45889406, 0x5906df28, 0xeb655db8, 0xbb940594, 0xaa47fba1, 0xed29d7be,
- 0xa65b328c, 0x371b54a3, 0x7d7015d2, 0xe97f6a1b, 0xc35edc2c, 0xae8fbc3f,
- 0x893f35cf, 0x317438e7, 0x197f7ada, 0x0a739ca5, 0x3a54afb1, 0x7ae560df,
- 0xd1ae4362, 0xa1bd7487, 0x2a59db98, 0x47f2ab1f, 0x872abf85, 0xef7e7bd4,
- 0x5195f628, 0x87365e4e, 0xe599eae4, 0xd4076f78, 0xc317739e, 0xfa56897b,
- 0x1f72aefe, 0x6f6294f1, 0x5bd8a7bd, 0x5bd8a1ff, 0x05bda3ef, 0x835186f9,
- 0x1437bf08, 0x08dd762e, 0x20901af3, 0x3a14df11, 0xedc44c4e, 0x271971af,
- 0x61d97d2c, 0x0ea2d111, 0x348f05e3, 0x36497bf2, 0x1598ed97, 0x95cf59f1,
- 0x766b2cf9, 0xbcbb3469, 0x7ae3f27c, 0xe43ed1d2, 0xb9557beb, 0x994c794f,
- 0xfe6571ff, 0x57f3286f, 0x43498fed, 0xbca132be, 0xefaf10df, 0xfc297e47,
- 0xb9d0a729, 0xb57950a8, 0xe908c401, 0xfc9122eb, 0xe778209f, 0x25bde46a,
- 0x4ef5f720, 0x1e68c959, 0x7660dbbf, 0x7c462c57, 0xa714664e, 0x27aae89d,
- 0xb90365b9, 0xf8b37245, 0xca6ceb5c, 0xe5833847, 0x6381519e, 0x8e5acbb1,
- 0x4638be72, 0x24571f4f, 0x5bbdd0a4, 0x1d0efed5, 0x0cf072f7, 0x82a66795,
- 0xf3e25ef5, 0x6c7247ff, 0x8ee3e32c, 0xfd3a24bd, 0x4f1cde5c, 0x91237926,
- 0x5fed0a7c, 0x636f3795, 0xbe2064cc, 0xfba1644f, 0x610a7700, 0x9de7844e,
- 0x3f307c28, 0xff7dd197, 0x673d8ac1, 0x01d1de57, 0xceb8a14e, 0xf5b04ed8,
- 0xfc7af883, 0x1bf75325, 0x8f8edc6c, 0x9a27e4d6, 0x4bf535e2, 0xef9ac9ac,
- 0x35c3ec93, 0xb23b27df, 0x32ebf935, 0xffea6946, 0xc9a459c2, 0x593050df,
- 0x2e4cbf53, 0x6665e4d3, 0x0e4877a5, 0xfa1eed36, 0xa7fd1eb1, 0xa71fa1b6,
- 0xa14f86f5, 0x0e0bf0f1, 0xa3b5e160, 0x00e8678b, 0x87518546, 0xfc864cef,
- 0x6793d1c6, 0x0aef80e8, 0x3afe1f07, 0xd3685819, 0x7f3c29e8, 0x53afe1f5,
- 0xf465bf20, 0x863f3c75, 0x3adcf091, 0x2f0cea7a, 0xea1c59e0, 0xd0347479,
- 0xea972df1, 0xf83da28f, 0xe6d365c7, 0x4ef84b26, 0x06625940, 0x8a6ce7cc,
- 0x7efc61e7, 0x15acec73, 0xfc761178, 0x8f74f577, 0x79a337ed, 0xfc8b8ebb,
- 0x8b8e8d5d, 0xbb0d1dfc, 0x53f6f1c8, 0xcbbef553, 0x7e9a0e04, 0x64115fdf,
- 0xfd05af7e, 0xdc6939cd, 0xfd14c4df, 0xdfd14c4d, 0xcdfd14c4, 0x6fee7a39,
- 0x26fe8a62, 0x89bfa396, 0x324d5be9, 0xb934efa5, 0x726f6d28, 0xbf7dda53,
- 0x6ae729e0, 0xef380a3d, 0x985b8b4f, 0x1117e4c3, 0x4ae7a14e, 0x4f9df43a,
- 0x45ca7ed0, 0x12fbc0e6, 0x394e2287, 0x39acbf70, 0x2e7444cf, 0x4c3bb674,
- 0x9730bdf0, 0xb62f9be7, 0x617e503b, 0x8e9eed1e, 0x946cb6e8, 0x16b5cdbf,
- 0x35bbee27, 0x23c7f45f, 0x1bd6149f, 0x714cdee8, 0xe9c52767, 0xbdfc2d0a,
- 0xc7114384, 0x91e3288e, 0x9179da5c, 0x277c45f9, 0xb0eedcc7, 0x3f60e32a,
- 0xea326e30, 0x3025c2b7, 0xbf5bf52e, 0xb0a9fa98, 0x842b8f74, 0xe1fa6b8c,
- 0x410a2771, 0x3176a6e3, 0xc701177a, 0xf5c66875, 0xfc3f744b, 0x78c25fa2,
- 0xd3b44761, 0x354d718e, 0x21df8c5f, 0xdfcf45bf, 0xf8742c5f, 0xb893d425,
- 0x5bef89bd, 0x33d881c6, 0x1f0d79d3, 0x47a865c9, 0x5d9db971, 0x9a179d7c,
- 0x9f900bfc, 0x6077958a, 0x7ba58cc0, 0x730c4c9b, 0x9128bea2, 0x38363bbe,
- 0xe339df17, 0x1b15a0ef, 0x1f90dbdd, 0xde5c74eb, 0xdf3318b0, 0xcfb5d057,
- 0x3bd415ff, 0xec983b19, 0x4bfb0495, 0xb404752c, 0x44cae45f, 0x5b24e3bb,
- 0x7568724f, 0x8f7fe794, 0x31be7a06, 0xf4505eb3, 0x7763f527, 0xfdc0ef85,
- 0x86578e88, 0x4d1f21e5, 0x645e3a33, 0x1f7fbfc0, 0x3cfc44dd, 0x8791ca2d,
- 0x7dfdac2f, 0x8f9e0af4, 0x3788bc73, 0x69acad83, 0x8ffc7146, 0xf1452f3f,
- 0xa79a740d, 0x7fb43a0a, 0x765373d4, 0x063613d1, 0xfaeb54e0, 0xd7e7c0ca,
- 0x7078c069, 0xc10718d4, 0x4661e06f, 0x273a98e7, 0xe076f847, 0xfa80df7e,
- 0xb2878c6c, 0xd61e474c, 0xd277d24b, 0xef8ef27d, 0xa827fdf8, 0x50537919,
- 0x8389fefc, 0xf8afab92, 0xdc31c9e3, 0x6a945d4e, 0xa8788759, 0x944c9bb3,
- 0xe748bc1e, 0x9dce9982, 0xd96bf18a, 0xa97bf7d0, 0xfae18eaf, 0x41a57921,
- 0x74410231, 0x30e594c2, 0x0cbde6a6, 0xbbf6d0f4, 0x8bdfbac3, 0x43327003,
- 0xdef3c89a, 0xeb178f1d, 0xac65f534, 0xe31dfddf, 0xbda7acf4, 0x8fcddbfc,
- 0xc6554f2f, 0xc7997a43, 0xd50c7fc8, 0x6d0b6b3b, 0x843f3bea, 0xcc63c7e7,
- 0x523de9db, 0x14877949, 0x4e315aea, 0x3de8ce11, 0x37bfc1ae, 0x9e819afb,
- 0x3d399a76, 0xdd3c8aa7, 0xeafaf229, 0xbbeaa53b, 0x7a14cf6b, 0xa3cc2b6e,
- 0x8fd4fc7e, 0xdf1b37b4, 0x6d6788cb, 0x6efabe34, 0x012f5a94, 0x2b0920f4,
- 0xe23a675d, 0xfb1250ab, 0x63e7e784, 0x1d20e68a, 0xb2f2685c, 0xcdf4824f,
- 0xc6c8f085, 0x49d5fc60, 0x3f5af7da, 0xda81331f, 0x1b6beda9, 0x284fb227,
- 0x3a27e978, 0x69154daa, 0x624ebd1f, 0x9c3be2af, 0xa80d5920, 0xa776d597,
- 0x78e2de40, 0xc5fc82ef, 0xbb903df4, 0x3ed1e89f, 0xfbe94e9d, 0x3f2a1e4d,
- 0x694d54dd, 0xca9ea9a0, 0xa46a6a3f, 0x23db96f4, 0x167f9172, 0x3ec65fed,
- 0xdaf7a209, 0x1027bd36, 0xd4553f94, 0x51ad1d37, 0x7254e8e8, 0x1c9fdfdf,
- 0x53bbedc3, 0x3b3e38e3, 0xf7c0dec0, 0x972e80da, 0xdbfd6d5b, 0xfdca1d1d,
- 0xf9e3a3ae, 0x3c4765fe, 0xc31f2fcf, 0x64596efd, 0xe8fed8ad, 0x3fef0378,
- 0xefc6ac45, 0x7bf78db2, 0x77a45d2a, 0xb1357ea4, 0x5831fee8, 0x73ca163f,
- 0xaea7f27a, 0x41e5dfe2, 0xaf9d5cbc, 0x42b6fdfa, 0x61eefaab, 0x8fcf7f3a,
- 0x7a02f7df, 0xfad5fea7, 0x3e702663, 0x4befad0c, 0x43c9e7e5, 0xc2a9f1e1,
- 0x6817c4b7, 0x241f2367, 0x9d45f107, 0xa542f883, 0xd6fe9543, 0xa7387216,
- 0x0f3a151a, 0x07eee7e7, 0x76842ea3, 0xb4cce383, 0xbbe3208f, 0x9d9eb0cb,
- 0xa12fc282, 0x63bca0fc, 0xca83f2ac, 0x0fbd2a07, 0xefe33e06, 0x8c75f334,
- 0x5f79fa95, 0x7b475958, 0x845dc46c, 0x2b7a83d7, 0x12b1adea, 0xb0792f7f,
- 0xedcef5d8, 0x11b19fc8, 0x96918c0e, 0xf7d4b2ac, 0xfe3ec725, 0x9543c2af,
- 0xa3c0fd0b, 0xca0c1c17, 0x123fc3bb, 0x50e7240e, 0xf6fd238e, 0x8c4eb721,
- 0x177629b1, 0xc7cfdfa7, 0x1d226fc8, 0x1d660875, 0x30e87bde, 0xf05f7df7,
- 0x0ebe78e8, 0x16d68e95, 0xe3074a32, 0x96f6873a, 0xba7aea7b, 0x230779d7,
- 0xc61a97f9, 0xacf143cb, 0xfe482bae, 0xa979c19d, 0xec0c64f0, 0xa127e81f,
- 0xe8ef42c6, 0xe0e856dd, 0xd3f036fc, 0x67ac0dca, 0x3e8a35fd, 0xf8944c7b,
- 0x7e8ac87b, 0xa4172ee9, 0x1a996599, 0xcf4743bd, 0xefe15f3a, 0x5645fb8a,
- 0xa372ef8d, 0x171c1d6f, 0xe5c8521f, 0x3cf4d743, 0x2f13f711, 0xf742d5fc,
- 0xea0c2f8b, 0xcef68d3c, 0x533d5685, 0x2a9b23de, 0x8b9dde80, 0xf90c133e,
- 0xf39ef2a5, 0x0ef7e8e7, 0x176d7a83, 0xb5bda34f, 0x4cc4ab68, 0xeb609e78,
- 0x3d20b737, 0x4f457bcd, 0x5b9a99e7, 0x7a471e37, 0xc04fb73c, 0x85d96fe7,
- 0x31c5027d, 0x7c225b6b, 0x0a5fa866, 0xc77fac79, 0xe3c7c96e, 0x39c5328b,
- 0x3ef1946a, 0xa0a5d731, 0xeb713e5d, 0xfb843a5d, 0x8b02edbc, 0xb48f7e83,
- 0xdf0c79de, 0x8db7391d, 0x366b2fdf, 0xf9c0ee47, 0x0ceb4a97, 0xc17ca083,
- 0x635e5e76, 0xf70cfd29, 0xcd3c1743, 0x60b3fe28, 0x8ff9046f, 0x1ff45af3,
- 0x8eec8205, 0xfcda6dea, 0x4066d67c, 0x53b0583a, 0x07b35e5b, 0x79f241f2,
- 0x2f12a150, 0x29b2ce19, 0xe3c2d25e, 0xef7caa07, 0xb97b5f6d, 0xde506d1c,
- 0x897f66ff, 0x5f0ff7a5, 0x23e926f9, 0x2997cf0b, 0xff9033f9, 0x178e1bea,
- 0xca752e15, 0xb3c55fd8, 0x675836dc, 0x2b662bdd, 0x0775edfa, 0x79e246ce,
- 0x016145b0, 0xbd99177a, 0xded1592c, 0xe4bf607b, 0x1ed6f845, 0xfb893f34,
- 0x9e2f7598, 0xa13c6030, 0xb262df74, 0xef312657, 0xfd9bf44a, 0x89dac8a2,
- 0x7de9da8e, 0xce77265f, 0x1c2e7ec3, 0x0ed15b30, 0x4ff97ba8, 0xfcc76ec7,
- 0xa7dd028b, 0x201890bc, 0x55b7993a, 0x0c437ba2, 0x1efcb42d, 0xaf10913a,
- 0x28b6e788, 0x0ee58f7a, 0x19e23bc4, 0x4648eef0, 0xd071e13a, 0xf44b4f79,
- 0xd9b5b9bd, 0xf9cff580, 0xbc557e38, 0x094b4a97, 0xe71e0bcf, 0x75b89cf8,
- 0xa430e6d7, 0x64f5a783, 0x76811f8f, 0x0d3b7883, 0xe15e181d, 0xc5d85ffd,
- 0xd37791cf, 0x376301c1, 0x2f3ce01d, 0xa7c00747, 0x472ff7a4, 0x97e89d07,
- 0xddffbf92, 0x0ed0c7b9, 0x87e7e08f, 0xd51b77d5, 0x2e071a77, 0xdf14753c,
- 0xbfb34ae7, 0xa5777640, 0xc5da8bed, 0x9d09de8c, 0x4be78853, 0x02bdbf26,
- 0xca7277d1, 0x2f14d9b3, 0x6d7607d5, 0x744378c1, 0x3ac7c538, 0xe1b6cb92,
- 0xb6c598fb, 0xc2f6936f, 0xcefd163a, 0xeb11e748, 0x3fc67e15, 0xbea2073c,
- 0xa7780c4b, 0x07b519f3, 0xc65cfc8d, 0xe1fbed3e, 0xce9cf11d, 0x959d0c4b,
- 0x804fd18b, 0x411c70fe, 0xc2e9fee6, 0x451dfc83, 0xa85c9fd5, 0x47b8a7be,
- 0x60836efb, 0x3dea9b7d, 0x70429850, 0xd6371a18, 0x73797681, 0x0d84f339,
- 0xc17d21fd, 0x5c7ca9df, 0xb5fa8bf1, 0x1bd1fb27, 0xbcc91daa, 0x15daf721,
- 0x014775b9, 0xbbd1e39f, 0x7be1d0df, 0xf93b1d8c, 0x3fcc3bef, 0x062af208,
- 0x1af519f7, 0xd4a753b9, 0x0fe914ff, 0x5bde76e0, 0x052892ff, 0x8bf797cb,
- 0xa79a9fb1, 0x48753f79, 0xf5571457, 0xfe830e6f, 0x33d36cbe, 0x4c0597e4,
- 0x23fb3791, 0x4bd46e28, 0xbedcecbe, 0x50f7cd12, 0x76085aba, 0x94222e26,
- 0x69f6eabe, 0xa85d3deb, 0x670e7bec, 0xfff9e0d7, 0x90e031af, 0xba5f23d7,
- 0x8e67e9df, 0x6eefe428, 0xef68287d, 0x056b0fef, 0x77ea0f96, 0x63c4cfb8,
- 0xeafe4aa4, 0xfe4d56dd, 0xa6bb369a, 0x1dfbb5fe, 0xfed9ef9a, 0x11f7cd0c,
- 0x7c9a9dc7, 0xa6817b5e, 0x64f7c8fe, 0xc0547e4d, 0xe63fa9a5, 0xef935bbc,
- 0xf4f584ca, 0xe9a8cf61, 0xa9a0bb24, 0xd661d93f, 0x465d7ff4, 0x65df26b4,
- 0xd8a3e051, 0xfbfdaa99, 0xff6e42a7, 0x7c2aa686, 0x8ed4e17f, 0x37edfaa3,
- 0x2bc76814, 0x5de3b593, 0x1df05e29, 0xff9e9d41, 0xf8a6027e, 0x34ba09fb,
- 0x9809fbfe, 0xc04fdfc7, 0x013f7f14, 0xe4dd7fcb, 0xa6befca4, 0x04bfca02,
- 0xf7e6097e, 0xe9829f83, 0x609fe0cb, 0x77e0e5f9, 0xb8f7194c, 0xca1bee32,
- 0x4e153fb8, 0xbdfd296f, 0xef87f4a3, 0x3df4ea0d, 0x795d6bdf, 0xe3e025e2,
- 0x7467db22, 0x086e595f, 0xa31c6294, 0xe18975f3, 0xf1e667f9, 0x418a6f1d,
- 0xa18036fd, 0x9ddcc49d, 0x6e3ee26f, 0xad438bdd, 0x81efae78, 0x07787ffd,
- 0x27d85fbf, 0xf0e6bc51, 0xd891b3fe, 0xc29797cf, 0xe90a30e9, 0x7cd7c845,
- 0x0d7e502b, 0x6773c77c, 0xca4af793, 0xa46d67bb, 0x554cbeef, 0x2fba3ef3,
- 0xd7b3deed, 0xb85a7880, 0x7f7d2f7b, 0xf35af81d, 0xcd76f77d, 0x87d62b77,
- 0x47cea174, 0xf7cf8571, 0xa9f9fdab, 0x7f2a4d7e, 0xddf3fe3f, 0x418e5647,
- 0x6ab7bc7d, 0x17b5c600, 0x3b1139ee, 0xf1f007fb, 0x66cf4bd5, 0x3da81ea2,
- 0xd1e72920, 0x07b57f78, 0xcf9e4af4, 0x6f7526bf, 0x63379e29, 0xb3ba047b,
- 0x4f5b25f4, 0xee16c4e7, 0x728355df, 0xedc66176, 0xb57f8a7a, 0x83bc4a49,
- 0x6350d3bf, 0x6baedc65, 0xdf123afb, 0xdb7dffa9, 0x1ef1ebd1, 0x23c1c774,
- 0xc74c5ef4, 0x4fe3493e, 0xf1cb1d8d, 0xf72c763b, 0x77dcbeff, 0x09cf1224,
- 0x8476d03e, 0xa7e75dc3, 0xf2561ff5, 0xbc12901d, 0xfeb44bf7, 0xcd2497f9,
- 0xc0b801ef, 0xcdfba171, 0x7022d3fb, 0xf8db275d, 0x7d40d378, 0xd56a7950,
- 0x1bff9c1c, 0xe53cf2f6, 0xddfa327d, 0xaeab8ea1, 0x767285db, 0xe7d49b61,
- 0xd839f779, 0x98efcc2f, 0xebe9d39e, 0x1b1c2fa9, 0xc37f7004, 0x749b2035,
- 0x62af5284, 0xa59bd72c, 0xea2a4f06, 0x47169391, 0xfdf9d204, 0x8811a1ae,
- 0x6298c3df, 0xba49ebb9, 0x1f60be07, 0xb5a4ef1f, 0xeee9123d, 0x5211bee4,
- 0x2dcbfef0, 0xe9ba7aca, 0x5e6f1bbb, 0x6fb553c2, 0xe9fb05bb, 0x9f2f1fc1,
- 0xf54ad636, 0xb89df0df, 0x93aced05, 0xc0ddfc19, 0xfe460663, 0xdc3dc2f5,
- 0x70793e4e, 0xfbe0f6f0, 0x7c14d359, 0x7df06474, 0xf5fb0bf5, 0x77dbbd4a,
- 0x3d3d4d31, 0xed4ed7c7, 0x33beac7c, 0x5e7da10f, 0x6744b8f3, 0xf5f46a1d,
- 0x4ffeb8b1, 0x57e769b7, 0x46b9c0ad, 0x0d8d8fef, 0x039ad7a2, 0x21637cdd,
- 0xf2a03f3a, 0xa9f08389, 0x8664f1e2, 0xe765e7c4, 0xecd5f8ef, 0xdd7445dd,
- 0xe3c4be3b, 0x31ef83b7, 0x74be2939, 0xb55a7f19, 0x2dfc821b, 0xbd23bdfa,
- 0x989e686b, 0x9c1f63d2, 0x1a1f942e, 0x987e879b, 0x93ccfc9b, 0x185bec0c,
- 0xebed16b3, 0x891dfa28, 0xd76e38cd, 0xffbd3d3e, 0xb03a6b5f, 0xef23df00,
- 0xc0a30272, 0xe9b6bbbc, 0x4667dfbb, 0x629e773b, 0xf0ea7ee7, 0x7fa04be4,
- 0xb489976b, 0x923d9abe, 0x5c17cf0f, 0x57dee450, 0x406f937b, 0x2e39ad7a,
- 0x9a3fd159, 0x70fc96d8, 0x77e92e61, 0xdaeb57b2, 0xb75c9db8, 0x58bb205b,
- 0x156a43b5, 0x629ce43b, 0xd65b9f07, 0x57e3edc9, 0xea11b604, 0x7b030dad,
- 0x9b5de604, 0xdaec8539, 0xcadd695a, 0x473c0ec1, 0xe61bb5a5, 0xe7443c1f,
- 0xd1cec0ae, 0xaddc2f94, 0x69b6d7cd, 0xf8bfaaf3, 0x3b6ed8d2, 0x37fa3863,
- 0x1c615225, 0x0a9bc3f2, 0xe77f555e, 0xf49c6bce, 0xe80f27fb, 0xb8d4531c,
- 0xd16bc204, 0xc7cc2f2b, 0xc26afb79, 0x347fe49c, 0xdae096fe, 0xd7ee17f1,
- 0x1bdee074, 0xf0e333f2, 0xe9cfd8ed, 0xf05e917c, 0x2cbaefe1, 0xfd815d42,
- 0x32df0499, 0xbb7b3b8c, 0x293e4922, 0xca1a08e7, 0x632affb9, 0xb2a6180c,
- 0xe7f72c7e, 0x38eaf543, 0x0e8a405d, 0xb1811392, 0xd8af5429, 0xde57cfc0,
- 0xfd24e119, 0xedc4c436, 0x6e2621f5, 0x75d10faf, 0x85dfa32e, 0x7df02418,
- 0x6997ac8e, 0x9d6d60ff, 0x0417f685, 0xe10e957b, 0x955076b1, 0x887de90e,
- 0xfd032db5, 0x8c5f353a, 0xec7b33df, 0x478b5283, 0x8cece387, 0x047d9417,
- 0x74cb4fae, 0x90747d56, 0x996c657e, 0x3dea7e66, 0x7e7d9fcc, 0xa59f9856,
- 0xef807e67, 0x75ff6c28, 0x86ec93ae, 0xf7f532a4, 0x2e49ea1a, 0x12fcf0a8,
- 0x7018bde8, 0x816c7745, 0x1db66a6e, 0x96b2ff22, 0x76c4afb5, 0x1d7c91a5,
- 0xbefe06a5, 0x4f186951, 0xfcb8e375, 0xa5d2512a, 0xc3f6b4e3, 0x7eb27191,
- 0xc63ba41c, 0xf2e34db9, 0x79953f68, 0x6f0d7d61, 0x43d677f3, 0x13943ee5,
- 0x7c0d7d3d, 0x466ff288, 0xd54d60bd, 0xbf9c69d8, 0x6ea2f116, 0xf6f85a3e,
- 0xea27c493, 0xc66acc39, 0xa3667bf9, 0xc41a9ad9, 0xdf908b17, 0xc377ded0,
- 0x138c7cbf, 0xeb6abff0, 0xe9973a7c, 0xa2b58c69, 0xfa48b75f, 0x7e25f692,
- 0xda2ddf2c, 0xcdfbcdaf, 0x11fdfe9c, 0x1949f902, 0x0de3bae3, 0x0a498fc4,
- 0x08f76c7f, 0xfb600e74, 0xcf1e3a77, 0x7e2810ab, 0x36143377, 0x624994da,
- 0xba22eabd, 0xe333724f, 0x4b596347, 0x3dbbf28c, 0x796fb431, 0x9beeb293,
- 0x2843fe75, 0xdbea8e57, 0x749e3192, 0xc4e4d6b4, 0x1b59cbfe, 0xc15a6fbd,
- 0x153d29da, 0x9fa2f75e, 0x2226f73a, 0x63c9fddd, 0xf6d678a4, 0x50223be5,
- 0xe5b167be, 0x044fdc56, 0xb7c6ec50, 0x73b3fb01, 0xd51df742, 0x2f60c4fb,
- 0x027d21c7, 0x1d2127fe, 0xd8dc079c, 0x5fb77a73, 0x2317c7f8, 0x2c5f7f11,
- 0x5b96e179, 0x9d5ffa19, 0xa82d47e4, 0x5df7465f, 0x33da9c81, 0xaaf07bf2,
- 0x5bc55de2, 0xf01d5e37, 0xb0af182f, 0x938404a6, 0xc91965f4, 0xe8917fa5,
- 0xf0e5d69c, 0xbc7dc2aa, 0x0e3b9f82, 0x8a15f970, 0xb70f156f, 0x43f5bbe2,
- 0x236eef49, 0xc923313c, 0xb87a50cb, 0x3080be1c, 0xc4d93ce9, 0xa1f92318,
- 0x4f2e4583, 0x2813cf07, 0xf33b795e, 0xf48012bc, 0xf5f7f096, 0xc70adefc,
- 0xb782855b, 0x2fdf313f, 0x71ff9232, 0xce323b78, 0x606e34dd, 0xe50dbe6f,
- 0xb2f8fed3, 0x37fce1c6, 0x18fa5f55, 0x3f0863f2, 0x376bf087, 0x2ff09d1e,
- 0xc69e8f08, 0x6ecbe248, 0xae7b4b7c, 0x7fe22f4c, 0x5fb58e30, 0xaf93f9f0,
- 0x46055f80, 0xf8f8bfbf, 0x54dead38, 0xa5c2a6f1, 0x07e0b8bf, 0x2ad47fcc,
- 0xe70abed0, 0x748dbbe3, 0x57dd43ff, 0x5e4ff751, 0x5cf5c719, 0xd801fa68,
- 0xb55fb84b, 0x40e4e326, 0x194f33b4, 0xfef87ed4, 0xdacb07ef, 0xb6f7f113,
- 0xe9e2283e, 0xddff0329, 0x872f350f, 0x07e4b8f1, 0xc22f46f1, 0xf86103e9,
- 0x1f33d404, 0xcf5cf708, 0x070671f3, 0x26e3cbe6, 0x53903de0, 0x798e357a,
- 0xf07f12bf, 0x8f9479f1, 0x027aa62c, 0x074a5dff, 0xf61ddefe, 0x1736082b,
- 0xbb83e7cc, 0x9d7de8d2, 0x718d7dee, 0x467f0edc, 0xdc774759, 0xe2815eff,
- 0x355133fe, 0x84c4fee1, 0x877c2e2d, 0x437df4f3, 0xb4df69b3, 0xea3e3b41,
- 0x978a64fd, 0xfee7e06e, 0xabea752e, 0xb75bf482, 0xc8be2dbe, 0xd1e4e7cb,
- 0xbfa88cef, 0x86db2747, 0xc7dcff73, 0xd550df7f, 0x5fc75d67, 0x73c704b0,
- 0xdfe2533f, 0x0fe1f9dd, 0xc3eb0526, 0x4dad4f43, 0x0daa7ec7, 0x05a72cde,
- 0xb1ee877f, 0xaa5bb424, 0x4e955a9f, 0x0f53f4f6, 0x545fa3a4, 0xba6d63bd,
- 0x0f70f94c, 0xbe3a65f9, 0x1b9e2fee, 0xd4f3e745, 0xdccaf6fe, 0x1d30a8af,
- 0x3dbd412a, 0x56afeae5, 0xda41fee0, 0xffc5027d, 0x15f6b066, 0x332b67a8,
- 0x16b15f38, 0xe87fc913, 0x776bf68f, 0x4ec5ff0d, 0x646f0794, 0x81cfd59c,
- 0x203e127a, 0xd5df1035, 0xdfa3adf2, 0x7fcd5c09, 0x7ea7b027, 0x56ffed22,
- 0x9de8172d, 0xfcf519ab, 0xf1a4f377, 0x59c704d1, 0xd18fb3ab, 0x794b57fb,
- 0x6fa314f9, 0x67ec49df, 0x3fdf818b, 0xe094ee64, 0xb29270fb, 0x9d73385f,
- 0xca717bf2, 0x639b6938, 0x53af07b7, 0x591df652, 0xdf2477ea, 0x32f0506e,
- 0x5789e975, 0x54efd0ed, 0x1e3cc7bd, 0xe9b3bfbe, 0x619faa5c, 0x3a33f41c,
- 0xf066985f, 0xd71f3a3c, 0x7148c3bd, 0xc1acdcd2, 0xcfd41c52, 0x11b45259,
- 0xab4b99d3, 0x728f9d1e, 0xcd94d5b8, 0xf9f2358f, 0x114e0835, 0xed91f4e5,
- 0xb842ceb7, 0x7fc4df9d, 0xfb61abff, 0xc2ddfa30, 0xafdee4fe, 0xf9eff89a,
- 0xa264dd3d, 0x2b26d9f4, 0xcfeba3c3, 0xff29d935, 0x4a0e4daf, 0xcd3cf4d9,
- 0xd7f4d8ef, 0xe14b88df, 0xb973bbf4, 0x3bf4cdab, 0x39460d88, 0x2bc03c75,
- 0x1ddaaaed, 0xc2eb280f, 0xbdb2b8f7, 0x0e1113c9, 0x3e2c0fb9, 0x75b3a686,
- 0x7d97df3c, 0x24eae4f3, 0x2c77d614, 0x7cc4f33d, 0x78fb7ef8, 0x270835f7,
- 0x148bb6d3, 0x607238a7, 0xbbc22555, 0xaf91877a, 0xf9f7594f, 0x8f71e94d,
- 0x75f97c62, 0x160dc53d, 0xc4f33b6d, 0x877f0c03, 0x9821b177, 0xbd74afde,
- 0x7ee78f57, 0xaaf8e5e6, 0x78fc383f, 0x449b5abe, 0xf803b3fc, 0xf3a7f32a,
- 0xcba5a2d5, 0xc6cb7e08, 0xb8426fbb, 0x937bd79d, 0x0fce9f90, 0xee744b1f,
- 0xf820457d, 0xdbbc72ab, 0xbfe056af, 0x575b6c50, 0xc723dc98, 0x04b961bf,
- 0x3e0743df, 0xf9fb474d, 0x3fe5fd9b, 0x6097eeb8, 0x1861fedd, 0x1a5133af,
- 0xe0df3dfa, 0xf584ea19, 0x3ef3f7e5, 0x6af1d2e8, 0x539f9ffc, 0x36213fc0,
- 0xe6219df8, 0xd4f9828d, 0x61fc141c, 0x26cfa859, 0xbf43a67d, 0x8fcffc11,
- 0x198ce734, 0x9f4828fb, 0xcbdf37f7, 0x4fd875a5, 0x1ddc8f5a, 0xfcc89ef9,
- 0x547b7a41, 0x83f98c20, 0x73f6edc6, 0xfb40cca0, 0x1724f14e, 0x2e786f10,
- 0xe181c2ec, 0x99ff303b, 0xc2f1e381, 0xf14f604b, 0xf2931078, 0xd9f9d67b,
- 0x50b22f81, 0xb7ae86ce, 0x882fe5ee, 0xaff66a3e, 0xfad028ba, 0xcba67f27,
- 0x0ffafcba, 0x1645f53d, 0x7d33efe2, 0xb6fd1f20, 0x1640860b, 0xb7eea1e2,
- 0x58ff9e5c, 0xf3e5a838, 0xf7e81b57, 0x1304eb3a, 0xf48949d1, 0x2e1fc525,
- 0x87f1e71c, 0x924f03ba, 0xc83aed3c, 0xc48b40e3, 0x8c38d2f6, 0x399fd49b,
- 0xcbacf286, 0xe831fdce, 0x2b71de9f, 0x41e8aa1c, 0xde12675d, 0x4dd83bf7,
- 0x3c8fdc0f, 0x0c3bfc8f, 0xf3a369fb, 0x9c2b2cbd, 0x39f15da1, 0x7c30f3f2,
- 0x257930bf, 0xdf79f9d2, 0x8f941cc0, 0xadfd666f, 0xbf86e28e, 0xb27ba70f,
- 0xe6926db5, 0x3af7799c, 0x703f127c, 0x29fb54c4, 0xe7c1c99c, 0x1b8e0cb9,
- 0x837e6ec8, 0xba2e13ef, 0x7b13f38a, 0xed53f399, 0x7b0643f2, 0x15bb7f50,
- 0xc8ed527e, 0x1bffbf29, 0x85b3e5f1, 0xd504fd32, 0xffc7a54f, 0x4cf7fe9f,
- 0x33412fff, 0x800063ec, 0x00008000, 0x00088b1f, 0x00000000, 0x5aa5ff00,
- 0x5554700d, 0xbdef3e96, 0xdd2749fe, 0x12421349, 0x42068408, 0x03621a88,
- 0xc4d67281, 0x206efce9, 0x6b01bb33, 0x8d08c42d, 0x749d2422, 0x6aece882,
- 0x021a6eb9, 0x367564ac, 0x1d47598c, 0x809f9b47, 0x9476ec28, 0x0da0c040,
- 0x6ba2cb0a, 0x3a26aa45, 0xab545b55, 0xa6e00eac, 0xd63b8223, 0x3be7b8e2,
- 0x1dddb5ef, 0xa6ed4fe2, 0xee7dba8a, 0x9ee7b9cf, 0xce77ce7b, 0x52b48f3d,
- 0x6a22ca22, 0x2a08cdcf, 0x6ea6ff0a, 0x6d4445a2, 0xf67f2429, 0xaf1f4541,
- 0x7dbc64d3, 0x58c9a340, 0xce08eb93, 0x4754419e, 0x459a26dd, 0x654284b4,
- 0x29bf71a4, 0x795bcbf2, 0x6d0dfebc, 0x61931741, 0xb06aad1b, 0x7aa6d513,
- 0x1314360b, 0xaacaab0d, 0x0bcc6286, 0x4b9d2e95, 0x7efe0df4, 0x879b744a,
- 0x2a224f99, 0xf60f14d3, 0x169c9d1b, 0x8b5dc9dc, 0x491bfb97, 0xeaa7984d,
- 0x534f98f3, 0xa3827c08, 0xd81d4b25, 0x9964b468, 0x8eef3e23, 0x07d6d237,
- 0xd2a14e31, 0xf9f6123b, 0x68858f4b, 0xcb17d121, 0x650faa17, 0xdaae79f2,
- 0x51337403, 0x29ed768d, 0x70ddf785, 0x05564ccc, 0xafbc67fc, 0x670239f2,
- 0xfa65ea34, 0x790a4752, 0x4bceccac, 0x1bcf0f1e, 0xd8293b99, 0x3f6fe7c5,
- 0xe78990a0, 0xeeb11db5, 0x6d79e14c, 0x9bb648e6, 0xf036ddf7, 0xdb878b3b,
- 0x2cf7fef6, 0xcf58b9ae, 0x9e433647, 0x6dfa1514, 0x174ff277, 0xce607f91,
- 0x3f3177fb, 0xf44d69ff, 0x67bd37ed, 0x05d7d621, 0x5afd8f9e, 0x82d5f60e,
- 0x56f0a56e, 0x3cfdda27, 0x9bbf48af, 0xe5dff86f, 0xb386575c, 0xf8be7e38,
- 0xa7a25d39, 0x69f8bd18, 0xd602f73e, 0x43eb468b, 0x21ee5976, 0x6e717b96,
- 0x252e8ece, 0x5fae9d71, 0x4b69768f, 0x9d15cb0e, 0x6615b8a9, 0x6c0d4d15,
- 0x851f4276, 0x1797b38a, 0xb97f5f47, 0x9bf42d74, 0x9dbd2c12, 0x90b517cf,
- 0xc7e2c7dc, 0x04b49bb6, 0x6a0f1679, 0x3443dc1e, 0xc90e9a95, 0xe2a77bbd,
- 0x61bca83e, 0xd61267a9, 0x2b7bbe8d, 0x7955196f, 0x73fafdbd, 0x7975ca04,
- 0xc9a9b0ce, 0xd7721b7d, 0x80ede5e7, 0xc400d9fe, 0xfaa94e8e, 0xc7951efe,
- 0xbfd7c7e7, 0x46a79c68, 0xf089ce2b, 0x9dc506f8, 0x9f671ce3, 0xf587bb58,
- 0xe9ef86be, 0xb46fbe45, 0x6938752f, 0xfda26ccd, 0xff42b91d, 0xda4b8773,
- 0xf4914750, 0x16e1d2bf, 0x2dc760fa, 0xf0ea1f42, 0x51d03d08, 0x8ed1ed27,
- 0x033fe906, 0x708cff51, 0xe2ec20a0, 0x4a6d7c14, 0x1cce1e9c, 0x9e494f43,
- 0x24a99c3f, 0x991453d3, 0x3cb870ff, 0xa5fa6018, 0x939ca732, 0xc0d1ca8d,
- 0x4b4e68fa, 0xb40ca12f, 0x674a41f9, 0x037bb1bb, 0x3ffbb61e, 0x43daedd4,
- 0x4bcfc533, 0xf33aaf30, 0xdbf846ce, 0x692b2ce5, 0x1ec3cfac, 0xde63dfef,
- 0x0555d3e9, 0x683fd1db, 0xfef95b73, 0x94dc5787, 0xff47bd01, 0xb78d234d,
- 0xb05a28ae, 0x0ae994b9, 0xcc7622bb, 0xc86e6efc, 0x4fc6bb66, 0xb83553e6,
- 0xe3a4d4ba, 0x02b67384, 0xc1aeb7fd, 0xdb261b3e, 0xfc795816, 0x57f7b94a,
- 0xf7a627d8, 0x0aeb29da, 0xd98bd0bc, 0xf3cabef5, 0xa66eff02, 0x80f79e5e,
- 0xdf649dc3, 0x822bcb47, 0x45c59bb0, 0x07cf36b3, 0xd9ba767f, 0xf5bb3fbc,
- 0x51e7c87e, 0xc14e94d3, 0xb8099731, 0xf3fdc410, 0x452e953e, 0x716c30ec,
- 0x7f993299, 0x2b22b538, 0x194eebc0, 0xb8da7df7, 0x7dc633ef, 0xd5fdc3bf,
- 0xfdcbbedc, 0x1fb88768, 0x9e988aed, 0xd085a34d, 0x0da7f05f, 0xef44792f,
- 0xa3a0f9a3, 0x3b0e5a66, 0xd33f025c, 0x81bf27f1, 0x5ca278e5, 0x036ee397,
- 0x6b6e867f, 0x85d7d3e8, 0x858b4f84, 0x4bffb0bc, 0x9f609f58, 0xf5f175b1,
- 0x9bb2ed24, 0xe7c29029, 0x20b6c3a0, 0x895344f4, 0x0ecb5f80, 0x692e08e7,
- 0xcf8ab329, 0x017a644f, 0xabd29e09, 0xae5e7d56, 0x85fc216b, 0x8cfb2475,
- 0x9980d504, 0x399fc4ed, 0xf2c99854, 0x167e188e, 0x49fd0fa3, 0xcff6fc13,
- 0xd7db9a67, 0xfe7cfd14, 0x13854365, 0xa9b15eb0, 0x4eff33b0, 0xe1acfc7d,
- 0x0699fe87, 0x943ce33f, 0x7dc7ca12, 0xce1d8f44, 0x2ee987bf, 0x1ead787b,
- 0x8285c207, 0x5c2e14df, 0x42549c06, 0xd44dc8e7, 0xaf7dfc77, 0x47d027e9,
- 0xfdd079e8, 0xd3af7fc7, 0x6739df4a, 0x50a4f8e2, 0xfd04e2be, 0x3df74181,
- 0x409dc13f, 0x87395f9b, 0xdfa6cb71, 0x3327ab7b, 0xa783586e, 0xff37603b,
- 0xed97dba2, 0xd027ff40, 0x2b11cb5b, 0x0f2b2ec1, 0x0af67ff4, 0x3bf4b78f,
- 0xa8fb80dc, 0xbbe88667, 0xc7dec8f3, 0x7d236f61, 0xae87f166, 0xfe7bbffd,
- 0x25679911, 0x35bd5b98, 0xcfbc4a54, 0xe37fe3d1, 0xb49f6135, 0x6fd015d0,
- 0x39179c57, 0xfeea27ea, 0xa9f1543d, 0xf5bd0037, 0xc46bf81f, 0x0a0cfab5,
- 0x65e96ec0, 0xe46647be, 0x6a86f57b, 0xc771e12a, 0x6ff04ad0, 0x86eac97b,
- 0xcd5efa9d, 0x5f1f84a9, 0xfb14ccf3, 0x3bb1be6b, 0x3d57711f, 0x23cf6fba,
- 0x23679859, 0xc99edbc8, 0xf57ac476, 0xdd163b69, 0x6bb7f72f, 0xf7206fcf,
- 0x64ed1b3e, 0x03cccd3e, 0x99ef35fb, 0xd1f00c1d, 0xe3fafb5e, 0x1a87b895,
- 0xe83db9ed, 0xa6dbb2bf, 0x2d670f42, 0xf8728c9e, 0xbbb359e1, 0xba0ceb17,
- 0x2ea27879, 0x56a45a4f, 0x3bab2fee, 0x37d7711f, 0x80bfe1f1, 0xf75af5dc,
- 0x3ce2cff3, 0x3884ad7b, 0xeb1f6171, 0xe85dd78d, 0x2dc7cf35, 0x9873ec8f,
- 0x94972f60, 0x82cf95ee, 0xef3eaf7f, 0xf45bad92, 0x439de819, 0x11e78fd8,
- 0x6525f2e2, 0x85ff527b, 0x5e25bdde, 0x97c5dfd6, 0x09bd8bea, 0x17f31bf6,
- 0x526b6edf, 0x6024147c, 0xbf19f25c, 0x3b2019c9, 0x8366dfc7, 0x99e878bc,
- 0xbe296791, 0x737ee2fe, 0x6a3ac2d8, 0x94e6d2b6, 0xf83fb8cc, 0x0ebcfef2,
- 0x3ba9f3e7, 0x34c7910a, 0x84ac882f, 0x51b05c5f, 0x7bcf2e4a, 0xbe5f88db,
- 0x2a971b83, 0x4f2ddf25, 0xc7ee854d, 0x38f57357, 0x16c07576, 0x1ddf280c,
- 0x83a3fe8f, 0x8eccef9c, 0x67af77d3, 0x7e71297e, 0xad425b6f, 0x2db7de6e,
- 0x738fc753, 0xe33f7f3c, 0xcfb19558, 0xe79287aa, 0x299152df, 0x8966d3f6,
- 0xc60e2214, 0x88ac2ff8, 0x10a45ae1, 0x5d763578, 0xe013d23d, 0xe08acbc8,
- 0xf2a0ef88, 0xa86e96a1, 0x4fae3b34, 0xa8204a5f, 0x0f7f8c95, 0x7b8c8bb9,
- 0x55ef5e60, 0xdbe57ee8, 0x98d8f36f, 0x246a4b4f, 0xab53791d, 0x7c8e9223,
- 0x46a8e468, 0xcbeb8d3b, 0x199ff18a, 0x4649afdf, 0xf6643fb8, 0x8fdbc6d8,
- 0x6f3c438f, 0x2ab37e1d, 0xfdd0a93e, 0x4d2069a6, 0x646723f6, 0xe9b6ec11,
- 0x3875e4b9, 0x1fc133a7, 0x65760647, 0x8fe2137b, 0xaa3b90cf, 0x137e287c,
- 0x7ca3fafd, 0xa54f81d8, 0xf6ab0acd, 0x65b1af22, 0x3a294d0a, 0xe5b1b01d,
- 0xa7b4befb, 0x5e2e7ec2, 0x1e3f156d, 0x73822251, 0x0aae27b9, 0x23988c3e,
- 0xca8e7382, 0x18fc11ff, 0x09591099, 0xb4adcadc, 0xc9f196af, 0x1e2e9591,
- 0xa0c2b2ff, 0x03e491a7, 0x57322785, 0xb5ea4f03, 0x3711b7d1, 0x09d99769,
- 0x7be9893f, 0xa227a19d, 0x783b86c7, 0xb3410ffc, 0x4e61f10b, 0x0be462a5,
- 0xb5f9f896, 0x908d3fb8, 0xf841c0eb, 0xdddd9367, 0xfdc1a32b, 0xbc1f20af,
- 0xe5dddb33, 0x326f5eba, 0xcacae587, 0xee2d6afc, 0xfbdd3b29, 0xdfcc158f,
- 0x07c91c5f, 0x4bb5b1ce, 0xdd7b6a1c, 0x47fb13ba, 0x807ba3cd, 0xde1c175f,
- 0x9f582b27, 0xada196ad, 0x67d22ca5, 0xa429c8e6, 0x6f604bf8, 0xbdba2382,
- 0xb2ef148d, 0x561e9f08, 0x9767eb2a, 0x4b940f71, 0xa1f603b4, 0xe6fcf7e8,
- 0x00efabc0, 0x6686466f, 0xf58f4e09, 0x4f030ba7, 0x3e3703a6, 0x981ef8e0,
- 0x60ffef13, 0xfa0b5ef5, 0xc3b8bf97, 0x9ef6e112, 0xbbe7c9cd, 0x0cf6ed7c,
- 0x9e3d0bf8, 0xec7b0fd0, 0xeac7a649, 0x4e197605, 0xe88083f2, 0x29c79cfd,
- 0x0e54b7f2, 0xdf0f41b5, 0xd698cbd2, 0x6313e812, 0xa9f331e8, 0xce1fcf41,
- 0xb6f84879, 0x430f0b4e, 0xcc07236f, 0xe4ef7c04, 0x7f7426b8, 0x1aef105a,
- 0xadc700f5, 0x216e3d2c, 0x0fa4b45e, 0x8cbdc4ad, 0x989d5bf4, 0xa7c8e9bf,
- 0xdb3f38f9, 0xdbce3e63, 0x3670e472, 0xf78dcec1, 0x6cc7c704, 0x1ff4b78c,
- 0x24bbc6c9, 0x86aadfd6, 0x4717210a, 0x47e012b8, 0x85afdfac, 0x8b7f210b,
- 0xf1825432, 0xf996e428, 0x49a06b4c, 0xe8aad1ce, 0x34474f7e, 0xf7b1f9c1,
- 0x6e8551f6, 0x250f8caf, 0x1d3707c8, 0xb11254bd, 0xd9a0f1c7, 0xe81395c0,
- 0xdffdd62f, 0x09c0c8b9, 0xbf0cda5e, 0xbc27071f, 0xf5a3dc31, 0xae7dc816,
- 0xb63b9742, 0x3bcaf85e, 0x6de32023, 0x992a5daf, 0xc6758c59, 0xa3c04a3c,
- 0x017c7159, 0x0e0ae40e, 0xf367326c, 0x2bcf7cb9, 0xd25e4eee, 0x96b1b8dc,
- 0xd33ad3a7, 0x6bd0b5fd, 0x5de40513, 0xb1ae5637, 0x8570f476, 0x553ebf7e,
- 0xf6fb8f7f, 0x964ec128, 0x7d6322eb, 0x9bc17cee, 0x5d67f030, 0xf85ac6f5,
- 0x7e597ddf, 0xf9bbe24b, 0xedaff887, 0xadd7a649, 0x339b58df, 0x1efb9f8e,
- 0x126a7eda, 0xd9afcf5d, 0xdb36a3bb, 0x4c7f7d75, 0x98b68bee, 0x49e6959c,
- 0xbe58fa89, 0xb71276b1, 0xaffe52eb, 0x7dcfd0fa, 0x8c3588f1, 0xb5facbb8,
- 0xfdb7fce0, 0x0925bd71, 0x5f807fb7, 0x9d6b0533, 0xfe5bbe33, 0x12ab6db1,
- 0x4f80561e, 0xe2bd5fec, 0x0937ec67, 0x18aa6dfb, 0x5a68a753, 0x37791d3d,
- 0x4f4f5779, 0x6d8c53ac, 0xa8a72819, 0x49bd88b7, 0xd2b87ecb, 0x623e8e3d,
- 0xd4ae6ff3, 0x864d9f64, 0x6fa94f1d, 0x1e15e679, 0x53ccb97f, 0x557ec956,
- 0xbf92a9ae, 0xa6a7dd8f, 0x860fcf52, 0x80bf1db2, 0xcd07453d, 0xb949f84e,
- 0x4f33eba6, 0xfc2efcbd, 0xe1db2f31, 0x357e64ea, 0xbcfa6955, 0xea273663,
- 0x5f63d140, 0xffe07be5, 0xa5cbec5b, 0xd3b262ce, 0x953f1e64, 0x3df0573b,
- 0xc6c7cfb6, 0x7aa5693e, 0x645ed3be, 0x533afefe, 0x3adbe3b1, 0xc51be493,
- 0x12d9c169, 0xf890bf87, 0xe85c1d16, 0xf7c05cd4, 0xd6fe1da0, 0x677ff5fe,
- 0x0c8f0e23, 0x0bba67fe, 0xd3ed75b8, 0xb6cfd874, 0x81d38f81, 0x6606270f,
- 0x1d9ed039, 0x1fd03972, 0x16b8fbad, 0x368cbaf3, 0x8b30675e, 0xf636b19c,
- 0x13d58e7e, 0xcdd1de12, 0x73af6bd0, 0x614b2fdb, 0x82dda9ef, 0xce8efc63,
- 0xd788fc44, 0xe3395c19, 0xeb1265d5, 0xf5b3050c, 0xd45a033a, 0x7acc0a19,
- 0xea34019d, 0x6751680c, 0x0cea3f40, 0x006751a0, 0x68033a8d, 0xa2d019d4,
- 0x2bfe80ce, 0xbcb16ba8, 0x50de4e51, 0xecd1aadf, 0xf40fff82, 0xf5e4416a,
- 0x74d31c0f, 0xc412877a, 0xfbc67f7d, 0xaf460e23, 0x28b075e8, 0xe77953c7,
- 0xfbcb341f, 0x5eda1a20, 0xd6f71337, 0x5571b9af, 0xd9371117, 0xa3cddb14,
- 0x6a1f5127, 0x1bdc53ef, 0x2e5fe85d, 0x5c1b6c72, 0xfa237ef8, 0xd56ecd7b,
- 0x9abafb85, 0x6f97fa8d, 0x58ea57b0, 0x2cc739d5, 0x15fbcf72, 0xeffde1ca,
- 0x64efeab0, 0x2cbdc6bf, 0x9545b0f7, 0x1d6fda3c, 0xcb4bf792, 0x4d738a8b,
- 0x7eda1e42, 0x1382e7cb, 0x9df4b69d, 0xb21fd790, 0xc524d739, 0x7de48f57,
- 0xc174fc7e, 0x45433c8d, 0xa7d5af4c, 0x7b5edf90, 0xf9213801, 0xb47e4248,
- 0x33fcd9d6, 0x5da467e4, 0x7efce133, 0x644ee87e, 0x6d3dd6f9, 0xb09228fe,
- 0x9930737f, 0x6df60df6, 0x99c823cd, 0x034a8fdc, 0x943fb2e2, 0x74aa1fdc,
- 0xc6927d64, 0x3cd1e63f, 0xff755be4, 0x3f40e6b4, 0xdbb977ef, 0x61caf92a,
- 0x2570f78f, 0xb349f1fb, 0x272fea47, 0xbde4d98f, 0x9cfb7e75, 0x8d4bfaa4,
- 0x1fea5536, 0xc48acc1b, 0xdee52bf1, 0xaacbb063, 0xeea57bba, 0x10eb9552,
- 0xe1d98e7f, 0x3786f2d1, 0x5cc377c0, 0x6abfd497, 0xe10bf4ac, 0xf72f7ec7,
- 0x7f16683c, 0x8254e9ab, 0xc9abd32a, 0xad7f816d, 0x3d8a7562, 0x298fed99,
- 0x78ab0fec, 0xbb04c6af, 0x915db0da, 0x100a42bc, 0x8695e7ac, 0xfe0d573e,
- 0xfb0a57eb, 0x3d56bdcb, 0x5553ce0f, 0xc5d79fe1, 0xdfe78b71, 0xfc0b5e47,
- 0x55c71d66, 0x5f671cb4, 0x37bf708f, 0x9ebe6a6d, 0xc072bbe7, 0x3319f57f,
- 0x726a4f01, 0x95e85e7e, 0xfced5f78, 0x095bef84, 0x737da5df, 0xa8e1f7d3,
- 0xc8493e89, 0x759a4f6b, 0xca7d61fc, 0xec14eb7b, 0x5e3eea55, 0x3474cf69,
- 0x8ca2bb49, 0x340bffc4, 0xe02f6f3d, 0x4a6672bb, 0xeb0fa2dd, 0x6eedda6b,
- 0x0b863fe8, 0xbefc8dbb, 0xe796e540, 0x5bd54eed, 0xdc29d30b, 0xca5b8d3f,
- 0xe7617e14, 0x5c71d47c, 0x3d4f3fc2, 0x7d05c0bb, 0x4377697c, 0xc739351f,
- 0x31dde1e6, 0x72ffe0cb, 0xdc55c359, 0x029d2797, 0x438f9fd8, 0x5adfacdd,
- 0x5d41481c, 0x50d1e43d, 0x38a63f27, 0x1ebfaef1, 0x716fb74f, 0x140acfc2,
- 0xb5b7ea27, 0xd935dda9, 0xe676bfcc, 0x9cf0370c, 0x61ea55f1, 0x76eadc23,
- 0x53506b70, 0x6ca6b5f4, 0xff0df3d4, 0x54a6f729, 0xd7f78a4d, 0x1d147e1b,
- 0xf11d22fc, 0x6dd447f5, 0x807f8377, 0x835eee6c, 0xfea0ec3f, 0xbf5269a6,
- 0xe5d1d98d, 0x613b39fd, 0xf4ab5347, 0xef8d8d75, 0x0c4f9199, 0xc1cde6dd,
- 0x7cd72bfe, 0xce5b25be, 0x8cbd7e39, 0xb8033771, 0x165eb63b, 0x463df1c3,
- 0x6b781dfd, 0x26baea32, 0x326baea3, 0xa326baea, 0xea326bae, 0xaea326ba,
- 0xbaea326b, 0x6baea326, 0x26baea32, 0x97ae13a9, 0x878eddf6, 0x08ea1da4,
- 0xbc4278c8, 0xc7eab9b8, 0x55175dd5, 0xa577538d, 0xc4865714, 0xbd7bf65d,
- 0xcea63dde, 0x26aefeca, 0xe0d57bf8, 0x431e7b84, 0x7163d25e, 0x6b5438b3,
- 0x603c16f1, 0x54f07c17, 0x8d6f5b8d, 0xf52ecfe9, 0x9b64cbd9, 0x2ca87b8f,
- 0x5152659a, 0x23ee34c7, 0xdf84ef56, 0x1bf09ce0, 0xd31bf0b4, 0xfcdfb8ec,
- 0x5daec2d6, 0x0109e7aa, 0x726c13c9, 0x32375bbf, 0x2f7d30ae, 0xe5709339,
- 0xc2b831b3, 0x90159a0f, 0x95a0ed63, 0x233f74ba, 0x37254ff8, 0x0e3f9c7f,
- 0x9c7484ce, 0xda1a9699, 0xb5a67d87, 0x1791baa5, 0x9d8bbfb3, 0x88a6dc9d,
- 0x06a1afbf, 0xbc1c77d9, 0x7c9e4749, 0x73d1c4ef, 0xf7f9e1bf, 0xf25d83fe,
- 0xd793ad9d, 0xe0fffa2e, 0xae954d4d, 0x84775f8f, 0x9659e77d, 0x43b654ea,
- 0x16d5578e, 0xb8ba922a, 0x50fe2a9a, 0x58ae3da3, 0xd377a380, 0xb577dc3c,
- 0xc839e1b5, 0x2efec399, 0xa32cdfef, 0x6a1a6bbe, 0xd9f4cbde, 0xbe373cec,
- 0x3dcd4dab, 0x800b0544, 0xb0c57547, 0xadd4b3ab, 0x1963dd60, 0xbf83bfde,
- 0xa7cc5edc, 0x96fee356, 0xb3b69753, 0xce63ee4b, 0x32fbdc42, 0xf51fabab,
- 0x9e6f2d86, 0xb2c27a90, 0xd442d70c, 0x79bcb61b, 0x5c73a75a, 0xe51b8afd,
- 0xabab13b2, 0x66f8827f, 0x109f3eeb, 0x09a1fd67, 0xc0fb7449, 0x09f3eee4,
- 0x3f05ae71, 0x3f4e9df8, 0xafb84c53, 0x5c944356, 0xf21dbbd5, 0x4bfeebf9,
- 0xa8d3cf7f, 0xaaa7c9c4, 0x749c5c74, 0xe7b0c282, 0xf90ec5d1, 0x713397fe,
- 0xdbd43cfd, 0x10b5d8a8, 0xfdaf38f3, 0xe2f8ec35, 0xc1a79ead, 0x7738cf27,
- 0x3579f10e, 0x0d90c758, 0xbbe319ed, 0xdbd529e4, 0x3d36b688, 0x357e9260,
- 0x6df68a58, 0xfa20f435, 0x81762fd9, 0xf393ed4f, 0x3a622c6e, 0xb79a1acf,
- 0xe9788ede, 0x73fe8dd9, 0xec5e9e65, 0xdfeeb637, 0xe58f9c69, 0xc37987d9,
- 0xf9e4aa85, 0x6dea37c3, 0x55c22ecc, 0x371d0e3a, 0x93aca8fc, 0x58e7fbe4,
- 0xa55e39fb, 0xfdf9781a, 0x47bcb372, 0x7e4c4f20, 0x0a5d5eea, 0xa3de5879,
- 0x61afbc86, 0x5299ec9c, 0x7b6ef98f, 0xc77ec80d, 0x7c653b0d, 0xe3af396c,
- 0xa685b4a3, 0x0de404e0, 0x4e0d1e53, 0x7653bc80, 0xdc5cda8c, 0xb51810be,
- 0xe1787f21, 0xe86d476f, 0x7543c17f, 0x56bfe1e3, 0xc2df09ad, 0x3f5951b2,
- 0x921af79d, 0x04e8c277, 0x4d856fe4, 0x6c02596f, 0xe69e73b7, 0xb7f2937d,
- 0xd3638922, 0xfe9a5b0d, 0x87b04aa8, 0xe490cfe9, 0x259d54ab, 0xdd14bee3,
- 0x3e8f7dff, 0x6e8ec2a8, 0x09dcb208, 0x69e737f6, 0x1248e5d3, 0x6bacb0df,
- 0xf3837031, 0x3f71a4b5, 0x3cbe4733, 0xe423c0c5, 0x378c8d8f, 0xbeb7a6fe,
- 0x79c8be42, 0x8c7e18dc, 0x261c314d, 0xebef5dc4, 0x20fc1711, 0xbbdade79,
- 0xf78ad91e, 0x76e3536d, 0xd78fbc8b, 0xdb456df4, 0x259efada, 0x4cbf2487,
- 0x65f9cf9a, 0x9c9d7d12, 0x7b68e463, 0x39adf3f0, 0x76cbece3, 0x0ed12d70,
- 0x37439a4e, 0xd27abde0, 0x480eea9f, 0x0fdd091c, 0x6ad9d97c, 0xecae2377,
- 0xd8a555fa, 0xa9f5b7d7, 0xfaa98f32, 0xa751d947, 0x52540fcc, 0x87e6fc11,
- 0xe1e011da, 0x0c3c24ec, 0x8972dd48, 0xddae7043, 0xadb60778, 0x123e4a71,
- 0x5336ebf3, 0x98adc3e8, 0xef90e597, 0x45b70c11, 0x6f7c2ca6, 0x4aeee29a,
- 0x2ece2bc8, 0x9d041599, 0x830a19dd, 0x15cfe8ef, 0xd5c8ea37, 0xd6ae3a69,
- 0x7bad0da8, 0x352dfc79, 0x5bf1b82c, 0x6ff307e0, 0x7697acb7, 0xb14cd945,
- 0x290a5cdb, 0x7067fffa, 0x3d7bc42d, 0x67ad3df6, 0x20efb05b, 0xf04afbde,
- 0x8fa8b599, 0xe45d95fe, 0x80d50689, 0x33d3cf99, 0x7bb70481, 0xb8942cee,
- 0xc686a513, 0x2cff91fb, 0x6a3a954f, 0x13d704cf, 0xd3da6ef8, 0xf5e4a37c,
- 0xc7a4fe87, 0x29a5d1fb, 0x3d71e46e, 0x711b5cf3, 0x5d479eae, 0xa29afe32,
- 0xa13c0bf3, 0xa967a7eb, 0xe69ece7e, 0xc59f794c, 0x8767a1ee, 0xbfbe3267,
- 0xe5bc3259, 0x1803a8d5, 0x667b1fdf, 0x4fb73f70, 0xde770d29, 0x75733e07,
- 0xb9945779, 0xde4edee4, 0x7b13e379, 0xf1867d74, 0x897dac1d, 0xfefde923,
- 0xcb80febf, 0x002220b3, 0x00000000
-};
-
-#endif /*__BNX2X_INIT_VALUES_H__*/
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index ad5ef25add3e..e01539c33b8a 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -53,12 +53,19 @@
#include "bnx2x.h"
#include "bnx2x_init.h"
+#include "bnx2x_init_ops.h"
#include "bnx2x_dump.h"
-#define DRV_MODULE_VERSION "1.48.105"
-#define DRV_MODULE_RELDATE "2009/03/02"
+#define DRV_MODULE_VERSION "1.48.105-1"
+#define DRV_MODULE_RELDATE "2009/04/22"
#define BNX2X_BC_VER 0x040200
+#include <linux/firmware.h>
+#include "bnx2x_fw_file_hdr.h"
+/* FW files */
+#define FW_FILE_PREFIX_E1 "bnx2x-e1-"
+#define FW_FILE_PREFIX_E1H "bnx2x-e1h-"
+
/* Time in jiffies before concluding the transmitter is hung */
#define TX_TIMEOUT (5*HZ)
@@ -1539,7 +1546,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
len, cqe, comp_ring_cons);
#ifdef BNX2X_STOP_ON_ERROR
if (bp->panic)
- return -EINVAL;
+ return 0;
#endif
bnx2x_update_sge_prod(fp,
@@ -5232,13 +5239,15 @@ static void bnx2x_gunzip_end(struct bnx2x *bp)
}
}
-static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
+static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len)
{
int n, rc;
/* check gzip header */
- if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED))
+ if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) {
+ BNX2X_ERR("Bad gzip header\n");
return -EINVAL;
+ }
n = 10;
@@ -5247,7 +5256,7 @@ static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
if (zbuf[3] & FNAME)
while ((zbuf[n++] != 0) && (n < len));
- bp->strm->next_in = zbuf + n;
+ bp->strm->next_in = (typeof(bp->strm->next_in))zbuf + n;
bp->strm->avail_in = len - n;
bp->strm->next_out = bp->gunzip_buf;
bp->strm->avail_out = FW_BUF_SIZE;
@@ -5369,8 +5378,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
msleep(50);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
msleep(50);
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+ bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
DP(NETIF_MSG_HW, "part2\n");
@@ -5434,8 +5443,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
msleep(50);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
msleep(50);
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+ bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
#ifndef BCM_ISCSI
/* set NIC mode */
REG_WR(bp, PRS_REG_NIC_MODE, 1);
@@ -5510,7 +5519,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
- bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
+ bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE);
if (CHIP_IS_E1H(bp))
REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp));
@@ -5518,14 +5527,14 @@ static int bnx2x_init_common(struct bnx2x *bp)
msleep(30);
REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0);
- bnx2x_init_block(bp, PXP_COMMON_START, PXP_COMMON_END);
+ bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE);
if (CHIP_IS_E1(bp)) {
/* enable HW interrupt from PXP on USDM overflow
bit 16 on INT_MASK_0 */
REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
}
- bnx2x_init_block(bp, PXP2_COMMON_START, PXP2_COMMON_END);
+ bnx2x_init_block(bp, PXP2_BLOCK, COMMON_STAGE);
bnx2x_init_pxp(bp);
#ifdef __BIG_ENDIAN
@@ -5571,60 +5580,60 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0);
REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0);
- bnx2x_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END);
+ bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE);
/* clean the DMAE memory */
bp->dmae_ready = 1;
bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8);
- bnx2x_init_block(bp, TCM_COMMON_START, TCM_COMMON_END);
- bnx2x_init_block(bp, UCM_COMMON_START, UCM_COMMON_END);
- bnx2x_init_block(bp, CCM_COMMON_START, CCM_COMMON_END);
- bnx2x_init_block(bp, XCM_COMMON_START, XCM_COMMON_END);
+ bnx2x_init_block(bp, TCM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, UCM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, CCM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, XCM_BLOCK, COMMON_STAGE);
bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3);
bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3);
bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3);
bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3);
- bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
+ bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE);
/* soft reset pulse */
REG_WR(bp, QM_REG_SOFT_RESET, 1);
REG_WR(bp, QM_REG_SOFT_RESET, 0);
#ifdef BCM_ISCSI
- bnx2x_init_block(bp, TIMERS_COMMON_START, TIMERS_COMMON_END);
+ bnx2x_init_block(bp, TIMERS_BLOCK, COMMON_STAGE);
#endif
- bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END);
+ bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE);
REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT);
if (!CHIP_REV_IS_SLOW(bp)) {
/* enable hw interrupt from doorbell Q */
REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
}
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+ bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
/* set NIC mode */
REG_WR(bp, PRS_REG_NIC_MODE, 1);
if (CHIP_IS_E1H(bp))
REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp));
- bnx2x_init_block(bp, TSDM_COMMON_START, TSDM_COMMON_END);
- bnx2x_init_block(bp, CSDM_COMMON_START, CSDM_COMMON_END);
- bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
- bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
+ bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, USDM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, XSDM_BLOCK, COMMON_STAGE);
bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
- bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
- bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
- bnx2x_init_block(bp, CSEM_COMMON_START, CSEM_COMMON_END);
- bnx2x_init_block(bp, XSEM_COMMON_START, XSEM_COMMON_END);
+ bnx2x_init_block(bp, TSEM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, USEM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE);
/* sync semi rtc */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
@@ -5632,16 +5641,16 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
0x80000000);
- bnx2x_init_block(bp, UPB_COMMON_START, UPB_COMMON_END);
- bnx2x_init_block(bp, XPB_COMMON_START, XPB_COMMON_END);
- bnx2x_init_block(bp, PBF_COMMON_START, PBF_COMMON_END);
+ bnx2x_init_block(bp, UPB_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE);
REG_WR(bp, SRC_REG_SOFT_RST, 1);
for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
REG_WR(bp, i, 0xc0cac01a);
/* TODO: replace with something meaningful */
}
- bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
+ bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE);
REG_WR(bp, SRC_REG_SOFT_RST, 0);
if (sizeof(union cdu_context) != 1024)
@@ -5649,7 +5658,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
printk(KERN_ALERT PFX "please adjust the size of"
" cdu_context(%ld)\n", (long)sizeof(union cdu_context));
- bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END);
+ bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE);
val = (4 << 24) + (0 << 12) + 1024;
REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val);
if (CHIP_IS_E1(bp)) {
@@ -5658,7 +5667,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, CDU_REG_CDU_DEBUG, 0);
}
- bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
+ bnx2x_init_block(bp, CFC_BLOCK, COMMON_STAGE);
REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
/* enable context validation interrupt from CFC */
REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
@@ -5666,20 +5675,25 @@ static int bnx2x_init_common(struct bnx2x *bp)
/* set the thresholds to prevent CFC/CDU race */
REG_WR(bp, CFC_REG_DEBUG0, 0x20020000);
- bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END);
- bnx2x_init_block(bp, MISC_AEU_COMMON_START, MISC_AEU_COMMON_END);
+ bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE);
/* PXPCS COMMON comes here */
+ bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE);
/* Reset PCIE errors for debug */
REG_WR(bp, 0x2814, 0xffffffff);
REG_WR(bp, 0x3820, 0xffffffff);
/* EMAC0 COMMON comes here */
+ bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE);
/* EMAC1 COMMON comes here */
+ bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE);
/* DBU COMMON comes here */
+ bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE);
/* DBG COMMON comes here */
+ bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE);
- bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END);
+ bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE);
if (CHIP_IS_E1H(bp)) {
REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp));
REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp));
@@ -5763,6 +5777,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
static int bnx2x_init_port(struct bnx2x *bp)
{
int port = BP_PORT(bp);
+ int init_stage = port ? PORT1_STAGE : PORT0_STAGE;
u32 low, high;
u32 val;
@@ -5771,7 +5786,9 @@ static int bnx2x_init_port(struct bnx2x *bp)
REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
/* Port PXP comes here */
+ bnx2x_init_block(bp, PXP_BLOCK, init_stage);
/* Port PXP2 comes here */
+ bnx2x_init_block(bp, PXP2_BLOCK, init_stage);
#ifdef BCM_ISCSI
/* Port0 1
* Port1 385 */
@@ -5798,21 +5815,19 @@ static int bnx2x_init_port(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
#endif
/* Port CMs come here */
- bnx2x_init_block(bp, (port ? XCM_PORT1_START : XCM_PORT0_START),
- (port ? XCM_PORT1_END : XCM_PORT0_END));
+ bnx2x_init_block(bp, XCM_BLOCK, init_stage);
/* Port QM comes here */
#ifdef BCM_ISCSI
REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20);
REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31);
- bnx2x_init_block(bp, func ? TIMERS_PORT1_START : TIMERS_PORT0_START,
- func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
+ bnx2x_init_block(bp, TIMERS_BLOCK, init_stage);
#endif
/* Port DQ comes here */
+ bnx2x_init_block(bp, DQ_BLOCK, init_stage);
- bnx2x_init_block(bp, (port ? BRB1_PORT1_START : BRB1_PORT0_START),
- (port ? BRB1_PORT1_END : BRB1_PORT0_END));
+ bnx2x_init_block(bp, BRB1_BLOCK, init_stage);
if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) {
/* no pause for emulation and FPGA */
low = 0;
@@ -5837,25 +5852,27 @@ static int bnx2x_init_port(struct bnx2x *bp)
/* Port PRS comes here */
+ bnx2x_init_block(bp, PRS_BLOCK, init_stage);
/* Port TSDM comes here */
+ bnx2x_init_block(bp, TSDM_BLOCK, init_stage);
/* Port CSDM comes here */
+ bnx2x_init_block(bp, CSDM_BLOCK, init_stage);
/* Port USDM comes here */
+ bnx2x_init_block(bp, USDM_BLOCK, init_stage);
/* Port XSDM comes here */
+ bnx2x_init_block(bp, XSDM_BLOCK, init_stage);
- bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START,
- port ? TSEM_PORT1_END : TSEM_PORT0_END);
- bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START,
- port ? USEM_PORT1_END : USEM_PORT0_END);
- bnx2x_init_block(bp, port ? CSEM_PORT1_START : CSEM_PORT0_START,
- port ? CSEM_PORT1_END : CSEM_PORT0_END);
- bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START,
- port ? XSEM_PORT1_END : XSEM_PORT0_END);
+ bnx2x_init_block(bp, TSEM_BLOCK, init_stage);
+ bnx2x_init_block(bp, USEM_BLOCK, init_stage);
+ bnx2x_init_block(bp, CSEM_BLOCK, init_stage);
+ bnx2x_init_block(bp, XSEM_BLOCK, init_stage);
/* Port UPB comes here */
+ bnx2x_init_block(bp, UPB_BLOCK, init_stage);
/* Port XPB comes here */
+ bnx2x_init_block(bp, XPB_BLOCK, init_stage);
- bnx2x_init_block(bp, port ? PBF_PORT1_START : PBF_PORT0_START,
- port ? PBF_PORT1_END : PBF_PORT0_END);
+ bnx2x_init_block(bp, PBF_BLOCK, init_stage);
/* configure PBF to work without PAUSE mtu 9000 */
REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
@@ -5885,18 +5902,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
/* Port SRCH comes here */
#endif
/* Port CDU comes here */
+ bnx2x_init_block(bp, CDU_BLOCK, init_stage);
/* Port CFC comes here */
+ bnx2x_init_block(bp, CFC_BLOCK, init_stage);
if (CHIP_IS_E1(bp)) {
REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
}
- bnx2x_init_block(bp, port ? HC_PORT1_START : HC_PORT0_START,
- port ? HC_PORT1_END : HC_PORT0_END);
+ bnx2x_init_block(bp, HC_BLOCK, init_stage);
- bnx2x_init_block(bp, port ? MISC_AEU_PORT1_START :
- MISC_AEU_PORT0_START,
- port ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END);
+ bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage);
/* init aeu_mask_attn_func_0/1:
* - SF mode: bits 3-7 are masked. only bits 0-2 are in use
* - MF mode: bit 3 is masked. bits 0-2 are in use as in SF
@@ -5905,13 +5921,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
(IS_E1HMF(bp) ? 0xF7 : 0x7));
/* Port PXPCS comes here */
+ bnx2x_init_block(bp, PXPCS_BLOCK, init_stage);
/* Port EMAC0 comes here */
+ bnx2x_init_block(bp, EMAC0_BLOCK, init_stage);
/* Port EMAC1 comes here */
+ bnx2x_init_block(bp, EMAC1_BLOCK, init_stage);
/* Port DBU comes here */
+ bnx2x_init_block(bp, DBU_BLOCK, init_stage);
/* Port DBG comes here */
+ bnx2x_init_block(bp, DBG_BLOCK, init_stage);
- bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START,
- port ? NIG_PORT1_END : NIG_PORT0_END);
+ bnx2x_init_block(bp, NIG_BLOCK, init_stage);
REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
@@ -5931,7 +5951,9 @@ static int bnx2x_init_port(struct bnx2x *bp)
}
/* Port MCP comes here */
+ bnx2x_init_block(bp, MCP_BLOCK, init_stage);
/* Port DMAE comes here */
+ bnx2x_init_block(bp, DMAE_BLOCK, init_stage);
switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
@@ -6036,7 +6058,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
if (CHIP_IS_E1H(bp)) {
for (i = 0; i < 9; i++)
bnx2x_init_block(bp,
- cm_start[func][i], cm_end[func][i]);
+ cm_blocks[i], FUNC0_STAGE + func);
REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
@@ -6049,7 +6071,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
}
- bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]);
+ bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func);
/* Reset PCIE errors for debug */
REG_WR(bp, 0x2114, 0xffffffff);
@@ -11082,6 +11104,190 @@ static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
return val;
}
+static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
+{
+ struct bnx2x_fw_file_hdr *fw_hdr;
+ struct bnx2x_fw_file_section *sections;
+ u16 *ops_offsets;
+ u32 offset, len, num_ops;
+ int i;
+ const struct firmware *firmware = bp->firmware;
+ const u8 * fw_ver;
+
+ if (firmware->size < sizeof(struct bnx2x_fw_file_hdr))
+ return -EINVAL;
+
+ fw_hdr = (struct bnx2x_fw_file_hdr *)firmware->data;
+ sections = (struct bnx2x_fw_file_section *)fw_hdr;
+
+ /* Make sure none of the offsets and sizes make us read beyond
+ * the end of the firmware data */
+ for (i = 0; i < sizeof(*fw_hdr) / sizeof(*sections); i++) {
+ offset = be32_to_cpu(sections[i].offset);
+ len = be32_to_cpu(sections[i].len);
+ if (offset + len > firmware->size) {
+ printk(KERN_ERR PFX "Section %d length is out of bounds\n", i);
+ return -EINVAL;
+ }
+ }
+
+ /* Likewise for the init_ops offsets */
+ offset = be32_to_cpu(fw_hdr->init_ops_offsets.offset);
+ ops_offsets = (u16 *)(firmware->data + offset);
+ num_ops = be32_to_cpu(fw_hdr->init_ops.len) / sizeof(struct raw_op);
+
+ for (i = 0; i < be32_to_cpu(fw_hdr->init_ops_offsets.len) / 2; i++) {
+ if (be16_to_cpu(ops_offsets[i]) > num_ops) {
+ printk(KERN_ERR PFX "Section offset %d is out of bounds\n", i);
+ return -EINVAL;
+ }
+ }
+
+ /* Check FW version */
+ offset = be32_to_cpu(fw_hdr->fw_version.offset);
+ fw_ver = firmware->data + offset;
+ if ((fw_ver[0] != BCM_5710_FW_MAJOR_VERSION) ||
+ (fw_ver[1] != BCM_5710_FW_MINOR_VERSION) ||
+ (fw_ver[2] != BCM_5710_FW_REVISION_VERSION) ||
+ (fw_ver[3] != BCM_5710_FW_ENGINEERING_VERSION)) {
+ printk(KERN_ERR PFX "Bad FW version:%d.%d.%d.%d."
+ " Should be %d.%d.%d.%d\n",
+ fw_ver[0], fw_ver[1], fw_ver[2],
+ fw_ver[3], BCM_5710_FW_MAJOR_VERSION,
+ BCM_5710_FW_MINOR_VERSION,
+ BCM_5710_FW_REVISION_VERSION,
+ BCM_5710_FW_ENGINEERING_VERSION);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void inline be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
+{
+ u32 i;
+ const __be32 *source = (const __be32*)_source;
+ u32 *target = (u32*)_target;
+
+ for (i = 0; i < n/4; i++)
+ target[i] = be32_to_cpu(source[i]);
+}
+
+/*
+ Ops array is stored in the following format:
+ {op(8bit), offset(24bit, big endian), data(32bit, big endian)}
+ */
+static void inline bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n)
+{
+ u32 i, j, tmp;
+ const __be32 *source = (const __be32*)_source;
+ struct raw_op *target = (struct raw_op*)_target;
+
+ for (i = 0, j = 0; i < n/8; i++, j+=2) {
+ tmp = be32_to_cpu(source[j]);
+ target[i].op = (tmp >> 24) & 0xff;
+ target[i].offset = tmp & 0xffffff;
+ target[i].raw_data = be32_to_cpu(source[j+1]);
+ }
+}
+static void inline be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
+{
+ u32 i;
+ u16 *target = (u16*)_target;
+ const __be16 *source = (const __be16*)_source;
+
+ for (i = 0; i < n/2; i++)
+ target[i] = be16_to_cpu(source[i]);
+}
+
+#define BNX2X_ALLOC_AND_SET(arr, lbl, func) \
+ do { \
+ u32 len = be32_to_cpu(fw_hdr->arr.len); \
+ bp->arr = kmalloc(len, GFP_KERNEL); \
+ if (!bp->arr) { \
+ printk(KERN_ERR PFX "Failed to allocate %d bytes for "#arr"\n", len); \
+ goto lbl; \
+ } \
+ func(bp->firmware->data + \
+ be32_to_cpu(fw_hdr->arr.offset), \
+ (u8*)bp->arr, len); \
+ } while (0)
+
+
+static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
+{
+ char fw_file_name[40] = {0};
+ int rc, offset;
+ struct bnx2x_fw_file_hdr *fw_hdr;
+
+ /* Create a FW file name */
+ if (CHIP_IS_E1(bp))
+ offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1);
+ else
+ offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1H);
+
+ sprintf(fw_file_name + offset, "%d.%d.%d.%d.fw",
+ BCM_5710_FW_MAJOR_VERSION,
+ BCM_5710_FW_MINOR_VERSION,
+ BCM_5710_FW_REVISION_VERSION,
+ BCM_5710_FW_ENGINEERING_VERSION);
+
+ printk(KERN_INFO PFX "Loading %s\n", fw_file_name);
+
+ rc = request_firmware(&bp->firmware, fw_file_name, dev);
+ if (rc) {
+ printk(KERN_ERR PFX "Can't load firmware file %s\n", fw_file_name);
+ goto request_firmware_exit;
+ }
+
+ rc = bnx2x_check_firmware(bp);
+ if (rc) {
+ printk(KERN_ERR PFX "Corrupt firmware file %s\n", fw_file_name);
+ goto request_firmware_exit;
+ }
+
+ fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data;
+
+ /* Initialize the pointers to the init arrays */
+ /* Blob */
+ BNX2X_ALLOC_AND_SET(init_data, request_firmware_exit, be32_to_cpu_n);
+
+ /* Opcodes */
+ BNX2X_ALLOC_AND_SET(init_ops, init_ops_alloc_err, bnx2x_prep_ops);
+
+ /* Offsets */
+ BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err, be16_to_cpu_n);
+
+ /* STORMs firmware */
+ bp->tsem_int_table_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->tsem_int_table_data.offset);
+ bp->tsem_pram_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->tsem_pram_data.offset);
+ bp->usem_int_table_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->usem_int_table_data.offset);
+ bp->usem_pram_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->usem_pram_data.offset);
+ bp->xsem_int_table_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->xsem_int_table_data.offset);
+ bp->xsem_pram_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->xsem_pram_data.offset);
+ bp->csem_int_table_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->csem_int_table_data.offset);
+ bp->csem_pram_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->csem_pram_data.offset);
+
+ return 0;
+init_offsets_alloc_err:
+ kfree(bp->init_ops);
+init_ops_alloc_err:
+ kfree(bp->init_data);
+request_firmware_exit:
+ release_firmware(bp->firmware);
+
+ return rc;
+}
+
+
static int __devinit bnx2x_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -11116,6 +11322,13 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
if (rc)
goto init_one_exit;
+ /* Set init arrays */
+ rc = bnx2x_init_firmware(bp, &pdev->dev);
+ if (rc) {
+ printk(KERN_ERR PFX "Error loading firmware\n");
+ goto init_one_exit;
+ }
+
rc = register_netdev(dev);
if (rc) {
dev_err(&pdev->dev, "Cannot register net device\n");
@@ -11163,6 +11376,11 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
unregister_netdev(dev);
+ kfree(bp->init_ops_offsets);
+ kfree(bp->init_ops);
+ kfree(bp->init_data);
+ release_firmware(bp->firmware);
+
if (bp->regview)
iounmap(bp->regview);
@@ -11412,13 +11630,20 @@ static struct pci_driver bnx2x_pci_driver = {
static int __init bnx2x_init(void)
{
+ int ret;
+
bnx2x_wq = create_singlethread_workqueue("bnx2x");
if (bnx2x_wq == NULL) {
printk(KERN_ERR PFX "Cannot create workqueue\n");
return -ENOMEM;
}
- return pci_register_driver(&bnx2x_pci_driver);
+ ret = pci_register_driver(&bnx2x_pci_driver);
+ if (ret) {
+ printk(KERN_ERR PFX "Cannot register driver\n");
+ destroy_workqueue(bnx2x_wq);
+ }
+ return ret;
}
static void __exit bnx2x_cleanup(void)
@@ -11431,3 +11656,4 @@ static void __exit bnx2x_cleanup(void)
module_init(bnx2x_init);
module_exit(bnx2x_cleanup);
+
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 8c2e5ab51f08..06009dc50b19 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1845,9 +1845,10 @@ static u16 aggregator_identifier;
* Can be called only after the mac address of the bond is set.
*/
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
-{
+{
// check that the bond is not initialized yet
- if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->dev->dev_addr))) {
+ if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr),
+ bond->dev->dev_addr)) {
aggregator_identifier = 0;
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index a306230381c8..2c46a154f2c6 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -26,10 +26,10 @@
#include <asm/byteorder.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <linux/if_ether.h>
// General definitions
-#define BOND_ETH_P_LACPDU 0x8809
-#define PKT_TYPE_LACPDU cpu_to_be16(BOND_ETH_P_LACPDU)
+#define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW)
#define AD_TIMER_INTERVAL 100 /*msec*/
#define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2188a96fc090..56830a456c59 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -695,6 +695,18 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
if (bond->params.use_carrier)
return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
+ /* Try to get link status using Ethtool first. */
+ if (slave_dev->ethtool_ops) {
+ if (slave_dev->ethtool_ops->get_link) {
+ u32 link;
+
+ link = slave_dev->ethtool_ops->get_link(slave_dev);
+
+ return link ? BMSR_LSTATUS : 0;
+ }
+ }
+
+ /* Ethtool can't be used, fallback to MII ioclts. */
ioctl = slave_ops->ndo_do_ioctl;
if (ioctl) {
/* TODO: set pointer to correct ioctl on a per team member */
@@ -721,20 +733,6 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
}
/*
- * Some drivers cache ETHTOOL_GLINK for a period of time so we only
- * attempt to get link status from it if the above MII ioctls fail.
- */
- if (slave_dev->ethtool_ops) {
- if (slave_dev->ethtool_ops->get_link) {
- u32 link;
-
- link = slave_dev->ethtool_ops->get_link(slave_dev);
-
- return link ? BMSR_LSTATUS : 0;
- }
- }
-
- /*
* If reporting, report that either there's no dev->do_ioctl,
* or both SIOCGMIIREG and get_link failed (meaning that we
* cannot report link status). If not reporting, pretend
@@ -2240,6 +2238,9 @@ static int bond_miimon_inspect(struct bonding *bond)
{
struct slave *slave;
int i, link_state, commit = 0;
+ bool ignore_updelay;
+
+ ignore_updelay = !bond->curr_active_slave ? true : false;
bond_for_each_slave(bond, slave, i) {
slave->new_link = BOND_LINK_NOCHANGE;
@@ -2304,6 +2305,7 @@ static int bond_miimon_inspect(struct bonding *bond)
": %s: link status up for "
"interface %s, enabling it in %d ms.\n",
bond->dev->name, slave->dev->name,
+ ignore_updelay ? 0 :
bond->params.updelay *
bond->params.miimon);
}
@@ -2322,9 +2324,13 @@ static int bond_miimon_inspect(struct bonding *bond)
continue;
}
+ if (ignore_updelay)
+ slave->delay = 0;
+
if (slave->delay <= 0) {
slave->new_link = BOND_LINK_UP;
commit++;
+ ignore_updelay = false;
continue;
}
@@ -3453,8 +3459,28 @@ static void bond_destroy_proc_dir(void)
bond_proc_dir = NULL;
}
}
+
+#else /* !CONFIG_PROC_FS */
+
+static int bond_create_proc_entry(struct bonding *bond)
+{
+}
+
+static void bond_remove_proc_entry(struct bonding *bond)
+{
+}
+
+static void bond_create_proc_dir(void)
+{
+}
+
+static void bond_destroy_proc_dir(void)
+{
+}
+
#endif /* CONFIG_PROC_FS */
+
/*-------------------------- netdev event handling --------------------------*/
/*
@@ -3462,10 +3488,8 @@ static void bond_destroy_proc_dir(void)
*/
static int bond_event_changename(struct bonding *bond)
{
-#ifdef CONFIG_PROC_FS
bond_remove_proc_entry(bond);
bond_create_proc_entry(bond);
-#endif
down_write(&(bonding_rwsem));
bond_destroy_sysfs_entry(bond);
bond_create_sysfs_entry(bond);
@@ -4631,9 +4655,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER);
-#ifdef CONFIG_PROC_FS
bond_create_proc_entry(bond);
-#endif
list_add_tail(&bond->bond_list, &bond_dev_list);
return 0;
@@ -4671,9 +4693,7 @@ static void bond_deinit(struct net_device *bond_dev)
bond_work_cancel_all(bond);
-#ifdef CONFIG_PROC_FS
bond_remove_proc_entry(bond);
-#endif
}
/* Unregister and free all bond devices.
@@ -4692,9 +4712,7 @@ static void bond_free_all(void)
bond_destroy(bond);
}
-#ifdef CONFIG_PROC_FS
bond_destroy_proc_dir();
-#endif
}
/*------------------------- Module initialization ---------------------------*/
@@ -5181,7 +5199,6 @@ static int __init bonding_init(void)
{
int i;
int res;
- struct bonding *bond;
printk(KERN_INFO "%s", version);
@@ -5190,9 +5207,7 @@ static int __init bonding_init(void)
goto out;
}
-#ifdef CONFIG_PROC_FS
bond_create_proc_dir();
-#endif
init_rwsem(&bonding_rwsem);
@@ -5212,13 +5227,6 @@ static int __init bonding_init(void)
goto out;
err:
- list_for_each_entry(bond, &bond_dev_list, bond_list) {
- bond_work_cancel_all(bond);
- destroy_workqueue(bond->wq);
- }
-
- bond_destroy_sysfs();
-
rtnl_lock();
bond_free_all();
rtnl_unlock();
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index 4bd2455b0fe3..699d22c5fe09 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -46,7 +46,7 @@
#include <linux/pci.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
#include <linux/crc32.h>
#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h
index 79d855e267e0..8b5165a5af3f 100644
--- a/drivers/net/chelsio/cphy.h
+++ b/drivers/net/chelsio/cphy.h
@@ -43,10 +43,11 @@
struct mdio_ops {
void (*init)(adapter_t *adapter, const struct board_info *bi);
- int (*read)(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *val);
- int (*write)(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val);
+ int (*read)(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr);
+ int (*write)(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr, u16 val);
+ unsigned mode_support;
};
/* PHY interrupt types */
@@ -83,11 +84,12 @@ struct cphy_ops {
int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex);
int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
int *duplex, int *fc);
+
+ u32 mmds;
};
/* A PHY instance */
struct cphy {
- int addr; /* PHY address */
int state; /* Link status state machine */
adapter_t *adapter; /* associated adapter */
@@ -101,36 +103,37 @@ struct cphy {
u32 elmer_gpo;
const struct cphy_ops *ops; /* PHY operations */
- int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *val);
- int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val);
+ struct mdio_if_info mdio;
struct cphy_instance *instance;
};
/* Convenience MDIO read/write wrappers */
-static inline int mdio_read(struct cphy *cphy, int mmd, int reg,
- unsigned int *valp)
+static inline int cphy_mdio_read(struct cphy *cphy, int mmd, int reg,
+ unsigned int *valp)
{
- return cphy->mdio_read(cphy->adapter, cphy->addr, mmd, reg, valp);
+ int rc = cphy->mdio.mdio_read(cphy->mdio.dev, cphy->mdio.prtad, mmd,
+ reg);
+ *valp = (rc >= 0) ? rc : -1;
+ return (rc >= 0) ? 0 : rc;
}
-static inline int mdio_write(struct cphy *cphy, int mmd, int reg,
- unsigned int val)
+static inline int cphy_mdio_write(struct cphy *cphy, int mmd, int reg,
+ unsigned int val)
{
- return cphy->mdio_write(cphy->adapter, cphy->addr, mmd, reg, val);
+ return cphy->mdio.mdio_write(cphy->mdio.dev, cphy->mdio.prtad, mmd,
+ reg, val);
}
static inline int simple_mdio_read(struct cphy *cphy, int reg,
unsigned int *valp)
{
- return mdio_read(cphy, 0, reg, valp);
+ return cphy_mdio_read(cphy, MDIO_DEVAD_NONE, reg, valp);
}
static inline int simple_mdio_write(struct cphy *cphy, int reg,
unsigned int val)
{
- return mdio_write(cphy, 0, reg, val);
+ return cphy_mdio_write(cphy, MDIO_DEVAD_NONE, reg, val);
}
/* Convenience initializer */
@@ -139,11 +142,13 @@ static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
const struct mdio_ops *mdio_ops)
{
phy->adapter = adapter;
- phy->addr = phy_addr;
phy->ops = phy_ops;
if (mdio_ops) {
- phy->mdio_read = mdio_ops->read;
- phy->mdio_write = mdio_ops->write;
+ phy->mdio.prtad = phy_addr;
+ phy->mdio.mmds = phy_ops->mmds;
+ phy->mdio.mode_support = mdio_ops->mode_support;
+ phy->mdio.mdio_read = mdio_ops->read;
+ phy->mdio.mdio_write = mdio_ops->write;
}
}
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index fa06994f9737..082cdb28b510 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -589,7 +589,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
}
cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
- cmd->phy_address = p->phy->addr;
+ cmd->phy_address = p->phy->mdio.prtad;
cmd->transceiver = XCVR_EXTERNAL;
cmd->autoneg = p->link_config.autoneg;
cmd->maxtxpkt = 0;
@@ -849,39 +849,9 @@ static const struct ethtool_ops t1_ethtool_ops = {
static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
{
struct adapter *adapter = dev->ml_priv;
- struct mii_ioctl_data *data = if_mii(req);
-
- switch (cmd) {
- case SIOCGMIIPHY:
- data->phy_id = adapter->port[dev->if_port].phy->addr;
- /* FALLTHRU */
- case SIOCGMIIREG: {
- struct cphy *phy = adapter->port[dev->if_port].phy;
- u32 val;
-
- if (!phy->mdio_read)
- return -EOPNOTSUPP;
- phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
- &val);
- data->val_out = val;
- break;
- }
- case SIOCSMIIREG: {
- struct cphy *phy = adapter->port[dev->if_port].phy;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- if (!phy->mdio_write)
- return -EOPNOTSUPP;
- phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
- data->val_in);
- break;
- }
+ struct mdio_if_info *mdio = &adapter->port[dev->if_port].phy->mdio;
- default:
- return -EOPNOTSUPP;
- }
- return 0;
+ return mdio_mii_ioctl(mdio, if_mii(req), cmd);
}
static int t1_change_mtu(struct net_device *dev, int new_mtu)
diff --git a/drivers/net/chelsio/mv88x201x.c b/drivers/net/chelsio/mv88x201x.c
index cd856041af34..29e0cba48d53 100644
--- a/drivers/net/chelsio/mv88x201x.c
+++ b/drivers/net/chelsio/mv88x201x.c
@@ -53,7 +53,7 @@ static int led_init(struct cphy *cphy)
* Writing these bits maps control to another
* register. mmd(0x1) addr(0x7)
*/
- mdio_write(cphy, 0x3, 0x8304, 0xdddd);
+ cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8304, 0xdddd);
return 0;
}
@@ -62,14 +62,14 @@ static int led_link(struct cphy *cphy, u32 do_enable)
u32 led = 0;
#define LINK_ENABLE_BIT 0x1
- mdio_read(cphy, 0x1, 0x7, &led);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, &led);
if (do_enable & LINK_ENABLE_BIT) {
led |= LINK_ENABLE_BIT;
- mdio_write(cphy, 0x1, 0x7, led);
+ cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led);
} else {
led &= ~LINK_ENABLE_BIT;
- mdio_write(cphy, 0x1, 0x7, led);
+ cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led);
}
return 0;
}
@@ -86,7 +86,7 @@ static int mv88x201x_reset(struct cphy *cphy, int wait)
static int mv88x201x_interrupt_enable(struct cphy *cphy)
{
/* Enable PHY LASI interrupts. */
- mdio_write(cphy, 0x1, 0x9002, 0x1);
+ cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, 0x9002, 0x1);
/* Enable Marvell interrupts through Elmer0. */
if (t1_is_asic(cphy->adapter)) {
@@ -102,7 +102,7 @@ static int mv88x201x_interrupt_enable(struct cphy *cphy)
static int mv88x201x_interrupt_disable(struct cphy *cphy)
{
/* Disable PHY LASI interrupts. */
- mdio_write(cphy, 0x1, 0x9002, 0x0);
+ cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, 0x9002, 0x0);
/* Disable Marvell interrupts through Elmer0. */
if (t1_is_asic(cphy->adapter)) {
@@ -122,25 +122,25 @@ static int mv88x201x_interrupt_clear(struct cphy *cphy)
#ifdef MV88x2010_LINK_STATUS_BUGS
/* Required to read twice before clear takes affect. */
- mdio_read(cphy, 0x1, 0x9003, &val);
- mdio_read(cphy, 0x1, 0x9004, &val);
- mdio_read(cphy, 0x1, 0x9005, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9003, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9004, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9005, &val);
/* Read this register after the others above it else
* the register doesn't clear correctly.
*/
- mdio_read(cphy, 0x1, 0x1, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
#endif
/* Clear link status. */
- mdio_read(cphy, 0x1, 0x1, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
/* Clear PHY LASI interrupts. */
- mdio_read(cphy, 0x1, 0x9005, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9005, &val);
#ifdef MV88x2010_LINK_STATUS_BUGS
/* Do it again. */
- mdio_read(cphy, 0x1, 0x9003, &val);
- mdio_read(cphy, 0x1, 0x9004, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9003, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9004, &val);
#endif
/* Clear Marvell interrupts through Elmer0. */
@@ -172,13 +172,12 @@ static int mv88x201x_get_link_status(struct cphy *cphy, int *link_ok,
int *speed, int *duplex, int *fc)
{
u32 val = 0;
-#define LINK_STATUS_BIT 0x4
if (link_ok) {
/* Read link status. */
- mdio_read(cphy, 0x1, 0x1, &val);
- val &= LINK_STATUS_BIT;
- *link_ok = (val == LINK_STATUS_BIT);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
+ val &= MDIO_STAT1_LSTATUS;
+ *link_ok = (val == MDIO_STAT1_LSTATUS);
/* Turn on/off Link LED */
led_link(cphy, *link_ok);
}
@@ -205,6 +204,8 @@ static struct cphy_ops mv88x201x_ops = {
.interrupt_handler = mv88x201x_interrupt_handler,
.get_link_status = mv88x201x_get_link_status,
.set_loopback = mv88x201x_set_loopback,
+ .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
+ MDIO_DEVS_PHYXS | MDIO_DEVS_WIS),
};
static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
@@ -219,12 +220,12 @@ static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
cphy_init(cphy, adapter, phy_addr, &mv88x201x_ops, mdio_ops);
/* Commands the PHY to enable XFP's clock. */
- mdio_read(cphy, 0x3, 0x8300, &val);
- mdio_write(cphy, 0x3, 0x8300, val | 1);
+ cphy_mdio_read(cphy, MDIO_MMD_PCS, 0x8300, &val);
+ cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8300, val | 1);
/* Clear link status. Required because of a bug in the PHY. */
- mdio_read(cphy, 0x1, 0x8, &val);
- mdio_read(cphy, 0x3, 0x8, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT2, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PCS, MDIO_STAT2, &val);
/* Allows for Link,Ack LED turn on/off */
led_init(cphy);
diff --git a/drivers/net/chelsio/my3126.c b/drivers/net/chelsio/my3126.c
index 040acd29995a..977c7e08b0e0 100644
--- a/drivers/net/chelsio/my3126.c
+++ b/drivers/net/chelsio/my3126.c
@@ -43,11 +43,11 @@ static int my3126_interrupt_handler(struct cphy *cphy)
adapter = cphy->adapter;
if (cphy->count == 50) {
- mdio_read(cphy, 0x1, 0x1, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
val16 = (u16) val;
status = cphy->bmsr ^ val16;
- if (status & BMSR_LSTATUS)
+ if (status & MDIO_STAT1_LSTATUS)
t1_link_changed(adapter, 0);
cphy->bmsr = val16;
@@ -114,14 +114,14 @@ static int my3126_get_link_status(struct cphy *cphy,
adapter_t *adapter;
adapter = cphy->adapter;
- mdio_read(cphy, 0x1, 0x1, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
val16 = (u16) val;
/* Populate elmer_gpo with the register value */
t1_tpi_read(adapter, A_ELMER0_GPO, &val);
cphy->elmer_gpo = val;
- *link_ok = (val16 & BMSR_LSTATUS);
+ *link_ok = (val16 & MDIO_STAT1_LSTATUS);
if (*link_ok) {
/* Turn on the LED. */
@@ -163,6 +163,8 @@ static struct cphy_ops my3126_ops = {
.interrupt_handler = my3126_interrupt_handler,
.get_link_status = my3126_get_link_status,
.set_loopback = my3126_set_loopback,
+ .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
+ MDIO_DEVS_PHYXS),
};
static struct cphy *my3126_phy_create(adapter_t *adapter,
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 58f6fc055f6a..5e97a1a71d88 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1149,8 +1149,8 @@ static inline void write_tx_desc(struct cmdQ_e *e, dma_addr_t mapping,
unsigned int len, unsigned int gen,
unsigned int eop)
{
- if (unlikely(len > SGE_TX_DESC_MAX_PLEN))
- BUG();
+ BUG_ON(len > SGE_TX_DESC_MAX_PLEN);
+
e->addr_lo = (u32)mapping;
e->addr_hi = (u64)mapping >> 32;
e->len_gen = V_CMD_LEN(len) | V_CMD_GEN1(gen);
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c
index 7adf30230c4f..2564312b3056 100644
--- a/drivers/net/chelsio/subr.c
+++ b/drivers/net/chelsio/subr.c
@@ -284,32 +284,29 @@ static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi)
/*
* Elmer MI1 MDIO read/write operations.
*/
-static int mi1_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *valp)
+static int mi1_mdio_read(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr)
{
+ struct adapter *adapter = dev->ml_priv;
u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
-
- if (mmd_addr)
- return -EINVAL;
+ unsigned int val;
spin_lock(&adapter->tpi_lock);
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
__t1_tpi_write(adapter,
A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ);
mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
- __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
+ __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
spin_unlock(&adapter->tpi_lock);
- return 0;
+ return val;
}
-static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val)
+static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr, u16 val)
{
+ struct adapter *adapter = dev->ml_priv;
u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
- if (mmd_addr)
- return -EINVAL;
-
spin_lock(&adapter->tpi_lock);
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
@@ -324,16 +321,19 @@ static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
static const struct mdio_ops mi1_mdio_ops = {
.init = mi1_mdio_init,
.read = mi1_mdio_read,
- .write = mi1_mdio_write
+ .write = mi1_mdio_write,
+ .mode_support = MDIO_SUPPORTS_C22
};
#endif
#endif
-static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *valp)
+static int mi1_mdio_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr)
{
+ struct adapter *adapter = dev->ml_priv;
u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
+ unsigned int val;
spin_lock(&adapter->tpi_lock);
@@ -350,14 +350,15 @@ static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
/* Read the data. */
- __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
+ __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
spin_unlock(&adapter->tpi_lock);
- return 0;
+ return val;
}
-static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val)
+static int mi1_mdio_ext_write(struct net_device *dev, int phy_addr,
+ int mmd_addr, u16 reg_addr, u16 val)
{
+ struct adapter *adapter = dev->ml_priv;
u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
spin_lock(&adapter->tpi_lock);
@@ -380,7 +381,8 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
static const struct mdio_ops mi1_mdio_ext_ops = {
.init = mi1_mdio_init,
.read = mi1_mdio_ext_read,
- .write = mi1_mdio_ext_write
+ .write = mi1_mdio_ext_write,
+ .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
};
enum {
@@ -1140,6 +1142,7 @@ int __devinit t1_init_sw_modules(adapter_t *adapter,
adapter->name, i);
goto error;
}
+ adapter->port[i].phy->mdio.dev = adapter->port[i].dev;
adapter->port[i].mac = mac = bi->gmac->create(adapter, i);
if (!mac) {
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 3f476c7c0736..af305c0b34d1 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -1093,6 +1093,19 @@ static int cpmac_stop(struct net_device *dev)
return 0;
}
+static const struct net_device_ops cpmac_netdev_ops = {
+ .ndo_open = cpmac_open,
+ .ndo_stop = cpmac_stop,
+ .ndo_start_xmit = cpmac_start_xmit,
+ .ndo_tx_timeout = cpmac_tx_timeout,
+ .ndo_set_multicast_list = cpmac_set_multicast_list,
+ .ndo_so_ioctl = cpmac_ioctl,
+ .ndo_set_config = cpmac_config,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int external_switch;
static int __devinit cpmac_probe(struct platform_device *pdev)
@@ -1143,14 +1156,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
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->netdev_ops = &cpmac_netdev_ops;
+ dev->ethtool_ops = &cpmac_ethtool_ops;
netif_napi_add(dev, &priv->napi, cpmac_poll, 64);
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 714df2b675e6..322434ac42fc 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -195,7 +195,7 @@ struct sge_qset { /* an SGE queue set */
struct sge_rspq rspq;
struct sge_fl fl[SGE_RXQ_PER_SET];
struct sge_txq txq[SGE_TXQ_PER_SET];
- struct napi_gro_fraginfo lro_frag_tbl;
+ int nomem;
int lro_enabled;
void *lro_va;
struct net_device *netdev;
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index e1b22490ff59..bebc00d2424d 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -33,14 +33,6 @@
#include "regs.h"
enum {
- PMD_RSD = 10, /* PMA/PMD receive signal detect register */
- PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */
- PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */
- XS_LN_STAT = 24 /* XS lane status register */
-};
-
-enum {
- AEL100X_TX_DISABLE = 9,
AEL100X_TX_CONFIG1 = 0xc002,
AEL1002_PWR_DOWN_HI = 0xc011,
AEL1002_PWR_DOWN_LO = 0xc012,
@@ -74,8 +66,8 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
for (err = 0; rv->mmd_addr && !err; rv++) {
if (rv->clear_bits == 0xffff)
- err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
- rv->set_bits);
+ err = t3_mdio_write(phy, rv->mmd_addr, rv->reg_addr,
+ rv->set_bits);
else
err = t3_mdio_change_bits(phy, rv->mmd_addr,
rv->reg_addr, rv->clear_bits,
@@ -86,7 +78,8 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
static void ael100x_txon(struct cphy *phy)
{
- int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
+ int tx_on_gpio =
+ phy->mdio.prtad == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
msleep(100);
t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
@@ -97,10 +90,11 @@ static int ael1002_power_down(struct cphy *phy, int enable)
{
int err;
- err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, !!enable);
if (!err)
- err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
- BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
+ err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+ MDIO_MMD_PMAPMD, MDIO_CTRL1,
+ MDIO_CTRL1_LPOWER, enable);
return err;
}
@@ -109,11 +103,11 @@ static int ael1002_reset(struct cphy *phy, int wait)
int err;
if ((err = ael1002_power_down(phy, 0)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
- (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
+ (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL100X_TX_CONFIG1, 1)) ||
+ (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_HI, 0)) ||
+ (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_LO, 0)) ||
+ (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_XFI_EQL, 0x18)) ||
+ (err = t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL1002_LB_EN,
0, 1 << 5)))
return err;
return 0;
@@ -132,12 +126,15 @@ static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
{
if (link_ok) {
unsigned int stat0, stat1, stat2;
- int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
+ int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD,
+ MDIO_PMA_RXDET, &stat0);
if (!err)
- err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
+ err = t3_mdio_read(phy, MDIO_MMD_PCS,
+ MDIO_PCS_10GBRT_STAT1, &stat1);
if (!err)
- err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
+ err = t3_mdio_read(phy, MDIO_MMD_PHYXS,
+ MDIO_PHYXS_LNSTAT, &stat2);
if (err)
return err;
*link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
@@ -157,6 +154,7 @@ static struct cphy_ops ael1002_ops = {
.intr_handler = ael1002_intr_noop,
.get_link_status = get_link_status_r,
.power_down = ael1002_power_down,
+ .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
};
int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -171,13 +169,13 @@ int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
static int ael1006_reset(struct cphy *phy, int wait)
{
- return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
+ return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait);
}
static int ael1006_power_down(struct cphy *phy, int enable)
{
- return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
- BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
+ return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD,
+ MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable);
}
static struct cphy_ops ael1006_ops = {
@@ -188,6 +186,7 @@ static struct cphy_ops ael1006_ops = {
.intr_handler = t3_phy_lasi_intr_handler,
.get_link_status = get_link_status_r,
.power_down = ael1006_power_down,
+ .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
};
int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -203,9 +202,9 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
static int ael2005_setup_sr_edc(struct cphy *phy)
{
static struct reg_val regs[] = {
- { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
- { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
- { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
+ { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 },
+ { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a },
+ { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 },
{ 0, 0, 0, 0 }
};
static u16 sr_edc[] = {
@@ -490,8 +489,8 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
msleep(50);
for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
- err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
- sr_edc[i + 1]);
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i],
+ sr_edc[i + 1]);
if (!err)
phy->priv = edc_sr;
return err;
@@ -500,12 +499,12 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
{
static struct reg_val regs[] = {
- { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
+ { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 },
{ 0, 0, 0, 0 }
};
static struct reg_val preemphasis[] = {
- { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
- { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
+ { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 },
+ { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 },
{ 0, 0, 0, 0 }
};
static u16 twinax_edc[] = {
@@ -887,8 +886,8 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
msleep(50);
for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
- err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
- twinax_edc[i + 1]);
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i],
+ twinax_edc[i + 1]);
if (!err)
phy->priv = edc_twinax;
return err;
@@ -899,26 +898,26 @@ static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
int i, err;
unsigned int stat, data;
- err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
- (dev_addr << 8) | (1 << 8) | word_addr);
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL,
+ (dev_addr << 8) | (1 << 8) | word_addr);
if (err)
return err;
for (i = 0; i < 5; i++) {
msleep(1);
- err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
+ err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat);
if (err)
return err;
if ((stat & 3) == 1) {
- err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
- &data);
+ err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA,
+ &data);
if (err)
return err;
return data >> 8;
}
}
CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
- phy->addr, word_addr);
+ phy->mdio.prtad, word_addr);
return -ETIMEDOUT;
}
@@ -927,7 +926,7 @@ static int get_module_type(struct cphy *phy, int delay_ms)
int v;
unsigned int stat;
- v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
+ v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, &stat);
if (v)
return v;
@@ -971,48 +970,48 @@ unknown:
static int ael2005_intr_enable(struct cphy *phy)
{
- int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
+ int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x200);
return err ? err : t3_phy_lasi_intr_enable(phy);
}
static int ael2005_intr_disable(struct cphy *phy)
{
- int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
+ int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x100);
return err ? err : t3_phy_lasi_intr_disable(phy);
}
static int ael2005_intr_clear(struct cphy *phy)
{
- int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
+ int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00);
return err ? err : t3_phy_lasi_intr_clear(phy);
}
static int ael2005_reset(struct cphy *phy, int wait)
{
static struct reg_val regs0[] = {
- { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
- { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
- { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
- { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
- { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
- { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
- { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
+ { MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 },
+ { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 },
+ { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 },
+ { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 },
+ { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8100 },
+ { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 },
+ { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 },
{ 0, 0, 0, 0 }
};
static struct reg_val regs1[] = {
- { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
- { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
+ { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 },
+ { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 },
{ 0, 0, 0, 0 }
};
int err;
unsigned int lasi_ctrl;
- err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
+ err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_CTRL, &lasi_ctrl);
if (err)
return err;
- err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
+ err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 0);
if (err)
return err;
@@ -1051,13 +1050,13 @@ static int ael2005_intr_handler(struct cphy *phy)
unsigned int stat;
int ret, edc_needed, cause = 0;
- ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
+ ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_STAT, &stat);
if (ret)
return ret;
if (stat & AEL2005_MODDET_IRQ) {
- ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
- 0xd00);
+ ret = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL,
+ 0xd00);
if (ret)
return ret;
@@ -1098,6 +1097,7 @@ static struct cphy_ops ael2005_ops = {
.intr_handler = ael2005_intr_handler,
.get_link_status = get_link_status_r,
.power_down = ael1002_power_down,
+ .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
};
int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -1107,7 +1107,7 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
SUPPORTED_IRQ, "10GBASE-R");
msleep(125);
- return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
+ return t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, 0,
1 << 5);
}
@@ -1119,12 +1119,15 @@ static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
{
if (link_ok) {
unsigned int stat0, stat1, stat2;
- int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
+ int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD,
+ MDIO_PMA_RXDET, &stat0);
if (!err)
- err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
+ err = t3_mdio_read(phy, MDIO_MMD_PCS,
+ MDIO_PCS_10GBX_STAT1, &stat1);
if (!err)
- err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
+ err = t3_mdio_read(phy, MDIO_MMD_PHYXS,
+ MDIO_PHYXS_LNSTAT, &stat2);
if (err)
return err;
*link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
@@ -1144,6 +1147,7 @@ static struct cphy_ops qt2045_ops = {
.intr_handler = t3_phy_lasi_intr_handler,
.get_link_status = get_link_status_x,
.power_down = ael1006_power_down,
+ .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
};
int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -1159,9 +1163,10 @@ int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
* Some cards where the PHY is supposed to be at address 0 actually
* have it at 1.
*/
- if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
+ if (!phy_addr &&
+ !t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &stat) &&
stat == 0xffff)
- phy->addr = 1;
+ phy->mdio.prtad = 1;
return 0;
}
@@ -1175,15 +1180,16 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
{
if (link_ok) {
unsigned int status;
+ int prtad = phy->mdio.prtad;
status = t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
+ XGM_REG(A_XGM_SERDES_STAT0, prtad)) |
t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
+ XGM_REG(A_XGM_SERDES_STAT1, prtad)) |
t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
+ XGM_REG(A_XGM_SERDES_STAT2, prtad)) |
t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
+ XGM_REG(A_XGM_SERDES_STAT3, prtad));
*link_ok = !(status & F_LOWSIG0);
}
if (speed)
@@ -1211,7 +1217,7 @@ static struct cphy_ops xaui_direct_ops = {
int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
int phy_addr, const struct mdio_ops *mdio_ops)
{
- cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
+ cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops,
SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
"10GBASE-CX4");
return 0;
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index e508dc32f3ec..3147789aecec 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -39,7 +39,7 @@
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
#include "version.h"
#define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__)
@@ -184,10 +184,11 @@ struct cphy;
struct adapter;
struct mdio_ops {
- int (*read)(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *val);
- int (*write)(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val);
+ int (*read)(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr);
+ int (*write)(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr, u16 val);
+ unsigned mode_support;
};
struct adapter_info {
@@ -520,17 +521,6 @@ enum {
MAC_RXFIFO_SIZE = 32768
};
-/* IEEE 802.3 specified MDIO devices */
-enum {
- MDIO_DEV_PMA_PMD = 1,
- MDIO_DEV_WIS = 2,
- MDIO_DEV_PCS = 3,
- MDIO_DEV_XGXS = 4,
- MDIO_DEV_ANEG = 7,
- MDIO_DEV_VEND1 = 30,
- MDIO_DEV_VEND2 = 31
-};
-
/* LASI control and status registers */
enum {
RX_ALARM_CTRL = 0x9000,
@@ -583,11 +573,12 @@ struct cphy_ops {
int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
int *duplex, int *fc);
int (*power_down)(struct cphy *phy, int enable);
+
+ u32 mmds;
};
/* A PHY instance */
struct cphy {
- u8 addr; /* PHY address */
u8 modtype; /* PHY module type */
short priv; /* scratch pad */
unsigned int caps; /* PHY capabilities */
@@ -595,23 +586,23 @@ struct cphy {
const char *desc; /* PHY description */
unsigned long fifo_errors; /* FIFO over/under-flows */
const struct cphy_ops *ops; /* PHY operations */
- int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *val);
- int (*mdio_write)(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val);
+ struct mdio_if_info mdio;
};
/* Convenience MDIO read/write wrappers */
-static inline int mdio_read(struct cphy *phy, int mmd, int reg,
- unsigned int *valp)
+static inline int t3_mdio_read(struct cphy *phy, int mmd, int reg,
+ unsigned int *valp)
{
- return phy->mdio_read(phy->adapter, phy->addr, mmd, reg, valp);
+ int rc = phy->mdio.mdio_read(phy->mdio.dev, phy->mdio.prtad, mmd, reg);
+ *valp = (rc >= 0) ? rc : -1;
+ return (rc >= 0) ? 0 : rc;
}
-static inline int mdio_write(struct cphy *phy, int mmd, int reg,
- unsigned int val)
+static inline int t3_mdio_write(struct cphy *phy, int mmd, int reg,
+ unsigned int val)
{
- return phy->mdio_write(phy->adapter, phy->addr, mmd, reg, val);
+ return phy->mdio.mdio_write(phy->mdio.dev, phy->mdio.prtad, mmd,
+ reg, val);
}
/* Convenience initializer */
@@ -620,14 +611,16 @@ static inline void cphy_init(struct cphy *phy, struct adapter *adapter,
const struct mdio_ops *mdio_ops,
unsigned int caps, const char *desc)
{
- phy->addr = phy_addr;
phy->caps = caps;
phy->adapter = adapter;
phy->desc = desc;
phy->ops = phy_ops;
if (mdio_ops) {
- phy->mdio_read = mdio_ops->read;
- phy->mdio_write = mdio_ops->write;
+ phy->mdio.prtad = phy_addr;
+ phy->mdio.mmds = phy_ops->mmds;
+ phy->mdio.mode_support = mdio_ops->mode_support;
+ phy->mdio.mdio_read = mdio_ops->read;
+ phy->mdio.mdio_write = mdio_ops->write;
}
}
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 7ea48414c6cb..0b87fee023f5 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -37,7 +37,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
#include <linux/sockios.h>
#include <linux/workqueue.h>
#include <linux/proc_fs.h>
@@ -1593,7 +1593,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
}
cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
- cmd->phy_address = p->phy.addr;
+ cmd->phy_address = p->phy.mdio.prtad;
cmd->transceiver = XCVR_EXTERNAL;
cmd->autoneg = p->link_config.autoneg;
cmd->maxtxpkt = 0;
@@ -2308,70 +2308,25 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
struct mii_ioctl_data *data = if_mii(req);
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
- int ret, mmd;
switch (cmd) {
- case SIOCGMIIPHY:
- data->phy_id = pi->phy.addr;
+ case SIOCGMIIREG:
+ case SIOCSMIIREG:
+ /* Convert phy_id from older PRTAD/DEVAD format */
+ if (is_10G(adapter) &&
+ !mdio_phy_id_is_c45(data->phy_id) &&
+ (data->phy_id & 0x1f00) &&
+ !(data->phy_id & 0xe0e0))
+ data->phy_id = mdio_phy_id_c45(data->phy_id >> 8,
+ data->phy_id & 0x1f);
/* FALLTHRU */
- case SIOCGMIIREG:{
- u32 val;
- struct cphy *phy = &pi->phy;
-
- if (!phy->mdio_read)
- return -EOPNOTSUPP;
- if (is_10G(adapter)) {
- mmd = data->phy_id >> 8;
- if (!mmd)
- mmd = MDIO_DEV_PCS;
- else if (mmd > MDIO_DEV_VEND2)
- return -EINVAL;
-
- ret =
- phy->mdio_read(adapter, data->phy_id & 0x1f,
- mmd, data->reg_num, &val);
- } else
- ret =
- phy->mdio_read(adapter, data->phy_id & 0x1f,
- 0, data->reg_num & 0x1f,
- &val);
- if (!ret)
- data->val_out = val;
- break;
- }
- case SIOCSMIIREG:{
- struct cphy *phy = &pi->phy;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- if (!phy->mdio_write)
- return -EOPNOTSUPP;
- if (is_10G(adapter)) {
- mmd = data->phy_id >> 8;
- if (!mmd)
- mmd = MDIO_DEV_PCS;
- else if (mmd > MDIO_DEV_VEND2)
- return -EINVAL;
-
- ret =
- phy->mdio_write(adapter,
- data->phy_id & 0x1f, mmd,
- data->reg_num,
- data->val_in);
- } else
- ret =
- phy->mdio_write(adapter,
- data->phy_id & 0x1f, 0,
- data->reg_num & 0x1f,
- data->val_in);
- break;
- }
+ case SIOCGMIIPHY:
+ return mdio_mii_ioctl(&pi->phy.mdio, data, cmd);
case SIOCCHIOCTL:
return cxgb_extension_ioctl(dev, req->ifr_data);
default:
return -EOPNOTSUPP;
}
- return ret;
}
static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 26d3587f3399..73d569e758ec 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -654,7 +654,8 @@ static void t3_reset_qset(struct sge_qset *q)
q->txq_stopped = 0;
q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
q->rx_reclaim_timer.function = NULL;
- q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0;
+ q->nomem = 0;
+ napi_free_frags(&q->napi);
}
@@ -2074,20 +2075,19 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
struct sge_fl *fl, int len, int complete)
{
struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
+ struct sk_buff *skb = NULL;
struct cpl_rx_pkt *cpl;
- struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags;
- int nr_frags = qs->lro_frag_tbl.nr_frags;
- int frag_len = qs->lro_frag_tbl.len;
+ struct skb_frag_struct *rx_frag;
+ int nr_frags;
int offset = 0;
- if (!nr_frags) {
- offset = 2 + sizeof(struct cpl_rx_pkt);
- qs->lro_va = cpl = sd->pg_chunk.va + 2;
+ if (!qs->nomem) {
+ skb = napi_get_frags(&qs->napi);
+ qs->nomem = !skb;
}
fl->credits--;
- len -= offset;
pci_dma_sync_single_for_cpu(adap->pdev,
pci_unmap_addr(sd, dma_addr),
fl->buf_size - SGE_PG_RSVD,
@@ -2100,21 +2100,38 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
fl->alloc_size,
PCI_DMA_FROMDEVICE);
+ if (!skb) {
+ put_page(sd->pg_chunk.page);
+ if (complete)
+ qs->nomem = 0;
+ return;
+ }
+
+ rx_frag = skb_shinfo(skb)->frags;
+ nr_frags = skb_shinfo(skb)->nr_frags;
+
+ if (!nr_frags) {
+ offset = 2 + sizeof(struct cpl_rx_pkt);
+ qs->lro_va = sd->pg_chunk.va + 2;
+ }
+ len -= offset;
+
prefetch(qs->lro_va);
rx_frag += nr_frags;
rx_frag->page = sd->pg_chunk.page;
rx_frag->page_offset = sd->pg_chunk.offset + offset;
rx_frag->size = len;
- frag_len += len;
- qs->lro_frag_tbl.nr_frags++;
- qs->lro_frag_tbl.len = frag_len;
+ skb->len += len;
+ skb->data_len += len;
+ skb->truesize += len;
+ skb_shinfo(skb)->nr_frags++;
if (!complete)
return;
- qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
cpl = qs->lro_va;
if (unlikely(cpl->vlan_valid)) {
@@ -2123,15 +2140,11 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
struct vlan_group *grp = pi->vlan_grp;
if (likely(grp != NULL)) {
- vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan),
- &qs->lro_frag_tbl);
- goto out;
+ vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan));
+ return;
}
}
- napi_gro_frags(&qs->napi, &qs->lro_frag_tbl);
-
-out:
- qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0;
+ napi_gro_frags(&qs->napi);
}
/**
@@ -2300,8 +2313,6 @@ no_mem:
if (fl->use_pages) {
void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
- prefetch(&qs->lro_frag_tbl);
-
prefetch(addr);
#if L1_CACHE_BYTES < 128
prefetch(addr + L1_CACHE_BYTES);
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 4f68aeb2679a..c8a865a7e26c 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -204,35 +204,33 @@ static void mi1_init(struct adapter *adap, const struct adapter_info *ai)
/*
* MI1 read/write operations for clause 22 PHYs.
*/
-static int t3_mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *valp)
+static int t3_mi1_read(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr)
{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
int ret;
u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
- if (mmd_addr)
- return -EINVAL;
-
mutex_lock(&adapter->mdio_lock);
t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
t3_write_reg(adapter, A_MI1_ADDR, addr);
t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2));
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
if (!ret)
- *valp = t3_read_reg(adapter, A_MI1_DATA);
+ ret = t3_read_reg(adapter, A_MI1_DATA);
mutex_unlock(&adapter->mdio_lock);
return ret;
}
-static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val)
+static int t3_mi1_write(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr, u16 val)
{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
int ret;
u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
- if (mmd_addr)
- return -EINVAL;
-
mutex_lock(&adapter->mdio_lock);
t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
t3_write_reg(adapter, A_MI1_ADDR, addr);
@@ -244,8 +242,9 @@ static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
}
static const struct mdio_ops mi1_mdio_ops = {
- t3_mi1_read,
- t3_mi1_write
+ .read = t3_mi1_read,
+ .write = t3_mi1_write,
+ .mode_support = MDIO_SUPPORTS_C22
};
/*
@@ -268,9 +267,11 @@ static int mi1_wr_addr(struct adapter *adapter, int phy_addr, int mmd_addr,
/*
* MI1 read/write operations for indirect-addressed PHYs.
*/
-static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *valp)
+static int mi1_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr)
{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
int ret;
mutex_lock(&adapter->mdio_lock);
@@ -280,15 +281,17 @@ static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr,
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
MDIO_ATTEMPTS, 10);
if (!ret)
- *valp = t3_read_reg(adapter, A_MI1_DATA);
+ ret = t3_read_reg(adapter, A_MI1_DATA);
}
mutex_unlock(&adapter->mdio_lock);
return ret;
}
-static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val)
+static int mi1_ext_write(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr, u16 val)
{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
int ret;
mutex_lock(&adapter->mdio_lock);
@@ -304,8 +307,9 @@ static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr,
}
static const struct mdio_ops mi1_mdio_ext_ops = {
- mi1_ext_read,
- mi1_ext_write
+ .read = mi1_ext_read,
+ .write = mi1_ext_write,
+ .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
};
/**
@@ -325,10 +329,10 @@ int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear,
int ret;
unsigned int val;
- ret = mdio_read(phy, mmd, reg, &val);
+ ret = t3_mdio_read(phy, mmd, reg, &val);
if (!ret) {
val &= ~clear;
- ret = mdio_write(phy, mmd, reg, val | set);
+ ret = t3_mdio_write(phy, mmd, reg, val | set);
}
return ret;
}
@@ -348,15 +352,16 @@ int t3_phy_reset(struct cphy *phy, int mmd, int wait)
int err;
unsigned int ctl;
- err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET);
+ err = t3_mdio_change_bits(phy, mmd, MDIO_CTRL1, MDIO_CTRL1_LPOWER,
+ MDIO_CTRL1_RESET);
if (err || !wait)
return err;
do {
- err = mdio_read(phy, mmd, MII_BMCR, &ctl);
+ err = t3_mdio_read(phy, mmd, MDIO_CTRL1, &ctl);
if (err)
return err;
- ctl &= BMCR_RESET;
+ ctl &= MDIO_CTRL1_RESET;
if (ctl)
msleep(1);
} while (ctl && --wait);
@@ -377,7 +382,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
int err;
unsigned int val = 0;
- err = mdio_read(phy, 0, MII_CTRL1000, &val);
+ err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_CTRL1000, &val);
if (err)
return err;
@@ -387,7 +392,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
if (advert & ADVERTISED_1000baseT_Full)
val |= ADVERTISE_1000FULL;
- err = mdio_write(phy, 0, MII_CTRL1000, val);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_CTRL1000, val);
if (err)
return err;
@@ -404,7 +409,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
val |= ADVERTISE_PAUSE_CAP;
if (advert & ADVERTISED_Asym_Pause)
val |= ADVERTISE_PAUSE_ASYM;
- return mdio_write(phy, 0, MII_ADVERTISE, val);
+ return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val);
}
/**
@@ -427,7 +432,7 @@ int t3_phy_advertise_fiber(struct cphy *phy, unsigned int advert)
val |= ADVERTISE_1000XPAUSE;
if (advert & ADVERTISED_Asym_Pause)
val |= ADVERTISE_1000XPSE_ASYM;
- return mdio_write(phy, 0, MII_ADVERTISE, val);
+ return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val);
}
/**
@@ -444,7 +449,7 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
int err;
unsigned int ctl;
- err = mdio_read(phy, 0, MII_BMCR, &ctl);
+ err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_BMCR, &ctl);
if (err)
return err;
@@ -462,30 +467,30 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
}
if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */
ctl |= BMCR_ANENABLE;
- return mdio_write(phy, 0, MII_BMCR, ctl);
+ return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_BMCR, ctl);
}
int t3_phy_lasi_intr_enable(struct cphy *phy)
{
- return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1);
+ return t3_mdio_write(phy, MDIO_MMD_PMAPMD, LASI_CTRL, 1);
}
int t3_phy_lasi_intr_disable(struct cphy *phy)
{
- return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0);
+ return t3_mdio_write(phy, MDIO_MMD_PMAPMD, LASI_CTRL, 0);
}
int t3_phy_lasi_intr_clear(struct cphy *phy)
{
u32 val;
- return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val);
+ return t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_STAT, &val);
}
int t3_phy_lasi_intr_handler(struct cphy *phy)
{
unsigned int status;
- int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status);
+ int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_STAT, &status);
if (err)
return err;
@@ -3863,6 +3868,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
ai->mdio_ops);
if (ret)
return ret;
+ p->phy.mdio.dev = adapter->port[i];
mac_prep(&p->mac, adapter, j);
/*
@@ -3918,7 +3924,7 @@ int t3_replay_prep_adapter(struct adapter *adapter)
;
pti = &port_types[adapter->params.vpd.port_type[j]];
- ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL);
+ ret = pti->phy_prep(&p->phy, adapter, p->phy.mdio.prtad, NULL);
if (ret)
return ret;
p->phy.ops->power_down(&p->phy, 1);
diff --git a/drivers/net/cxgb3/vsc8211.c b/drivers/net/cxgb3/vsc8211.c
index d07130971b8f..4f9a1c2724f4 100644
--- a/drivers/net/cxgb3/vsc8211.c
+++ b/drivers/net/cxgb3/vsc8211.c
@@ -91,17 +91,18 @@ enum {
*/
static int vsc8211_reset(struct cphy *cphy, int wait)
{
- return t3_phy_reset(cphy, 0, 0);
+ return t3_phy_reset(cphy, MDIO_DEVAD_NONE, 0);
}
static int vsc8211_intr_enable(struct cphy *cphy)
{
- return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, INTR_MASK);
+ return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE,
+ INTR_MASK);
}
static int vsc8211_intr_disable(struct cphy *cphy)
{
- return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, 0);
+ return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE, 0);
}
static int vsc8211_intr_clear(struct cphy *cphy)
@@ -109,18 +110,20 @@ static int vsc8211_intr_clear(struct cphy *cphy)
u32 val;
/* Clear PHY interrupts by reading the register. */
- return mdio_read(cphy, 0, VSC8211_INTR_STATUS, &val);
+ return t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &val);
}
static int vsc8211_autoneg_enable(struct cphy *cphy)
{
- return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
+ return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR,
+ BMCR_PDOWN | BMCR_ISOLATE,
BMCR_ANENABLE | BMCR_ANRESTART);
}
static int vsc8211_autoneg_restart(struct cphy *cphy)
{
- return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
+ return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR,
+ BMCR_PDOWN | BMCR_ISOLATE,
BMCR_ANRESTART);
}
@@ -130,9 +133,9 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
unsigned int bmcr, status, lpa, adv;
int err, sp = -1, dplx = -1, pause = 0;
- err = mdio_read(cphy, 0, MII_BMCR, &bmcr);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr);
if (!err)
- err = mdio_read(cphy, 0, MII_BMSR, &status);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status);
if (err)
return err;
@@ -142,7 +145,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
* once more to get the current link state.
*/
if (!(status & BMSR_LSTATUS))
- err = mdio_read(cphy, 0, MII_BMSR, &status);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR,
+ &status);
if (err)
return err;
*link_ok = (status & BMSR_LSTATUS) != 0;
@@ -156,7 +160,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
else
sp = SPEED_10;
} else if (status & BMSR_ANEGCOMPLETE) {
- err = mdio_read(cphy, 0, VSC8211_AUX_CTRL_STAT, &status);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_AUX_CTRL_STAT,
+ &status);
if (err)
return err;
@@ -170,9 +175,11 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
sp = SPEED_1000;
if (fc && dplx == DUPLEX_FULL) {
- err = mdio_read(cphy, 0, MII_LPA, &lpa);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA,
+ &lpa);
if (!err)
- err = mdio_read(cphy, 0, MII_ADVERTISE, &adv);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE,
+ MII_ADVERTISE, &adv);
if (err)
return err;
@@ -202,9 +209,9 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
unsigned int bmcr, status, lpa, adv;
int err, sp = -1, dplx = -1, pause = 0;
- err = mdio_read(cphy, 0, MII_BMCR, &bmcr);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr);
if (!err)
- err = mdio_read(cphy, 0, MII_BMSR, &status);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status);
if (err)
return err;
@@ -214,7 +221,8 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
* once more to get the current link state.
*/
if (!(status & BMSR_LSTATUS))
- err = mdio_read(cphy, 0, MII_BMSR, &status);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR,
+ &status);
if (err)
return err;
*link_ok = (status & BMSR_LSTATUS) != 0;
@@ -228,9 +236,10 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
else
sp = SPEED_10;
} else if (status & BMSR_ANEGCOMPLETE) {
- err = mdio_read(cphy, 0, MII_LPA, &lpa);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA, &lpa);
if (!err)
- err = mdio_read(cphy, 0, MII_ADVERTISE, &adv);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_ADVERTISE,
+ &adv);
if (err)
return err;
@@ -270,23 +279,23 @@ static int vsc8211_set_automdi(struct cphy *phy, int enable)
{
int err;
- err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0x52b5);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0x52b5);
if (err)
return err;
- err = mdio_write(phy, 0, 18, 0x12);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 18, 0x12);
if (err)
return err;
- err = mdio_write(phy, 0, 17, enable ? 0x2803 : 0x3003);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 17, enable ? 0x2803 : 0x3003);
if (err)
return err;
- err = mdio_write(phy, 0, 16, 0x87fa);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 16, 0x87fa);
if (err)
return err;
- err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0);
if (err)
return err;
@@ -315,7 +324,7 @@ static int vsc8211_intr_handler(struct cphy *cphy)
unsigned int cause;
int err, cphy_cause = 0;
- err = mdio_read(cphy, 0, VSC8211_INTR_STATUS, &cause);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &cause);
if (err)
return err;
@@ -367,12 +376,13 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T");
msleep(20); /* PHY needs ~10ms to start responding to MDIO */
- err = mdio_read(phy, 0, VSC8211_EXT_CTRL, &val);
+ err = t3_mdio_read(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL, &val);
if (err)
return err;
if (val & VSC_CTRL_MEDIA_MODE_HI) {
/* copper interface, just need to configure the LEDs */
- return mdio_write(phy, 0, VSC8211_LED_CTRL, 0x100);
+ return t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_LED_CTRL,
+ 0x100);
}
phy->caps = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
@@ -380,20 +390,20 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
phy->desc = "1000BASE-X";
phy->ops = &vsc8211_fiber_ops;
- err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 1);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 1);
if (err)
return err;
- err = mdio_write(phy, 0, VSC8211_SIGDET_CTRL, 1);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_SIGDET_CTRL, 1);
if (err)
return err;
- err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0);
if (err)
return err;
- err = mdio_write(phy, 0, VSC8211_EXT_CTRL,
- val | VSC_CTRL_CLAUSE37_VIEW);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL,
+ val | VSC_CTRL_CLAUSE37_VIEW);
if (err)
return err;
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 357f565851ed..9301eb28d9e2 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -810,7 +810,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
dev->mem_start = 0;
- device->driver_data = dev;
+ dev_set_drvdata(device, dev);
SET_NETDEV_DEV (dev, device);
status = register_netdev(dev);
@@ -1614,7 +1614,7 @@ static int __devexit depca_device_remove (struct device *device)
struct depca_private *lp;
int bus;
- dev = device->driver_data;
+ dev = dev_get_drvdata(device);
lp = netdev_priv(dev);
unregister_netdev (dev);
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index d8350860c0f8..e402e91bf188 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1170,6 +1170,21 @@ dm9000_stop(struct net_device *ndev)
return 0;
}
+static const struct net_device_ops dm9000_netdev_ops = {
+ .ndo_open = dm9000_open,
+ .ndo_stop = dm9000_stop,
+ .ndo_start_xmit = dm9000_start_xmit,
+ .ndo_tx_timeout = dm9000_timeout,
+ .ndo_set_multicast_list = dm9000_hash_table,
+ .ndo_do_ioctl = dm9000_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = dm9000_poll_controller,
+#endif
+};
+
#define res_size(_r) (((_r)->end - (_r)->start) + 1)
/*
@@ -1339,18 +1354,9 @@ dm9000_probe(struct platform_device *pdev)
/* driver system function */
ether_setup(ndev);
- ndev->open = &dm9000_open;
- ndev->hard_start_xmit = &dm9000_start_xmit;
- ndev->tx_timeout = &dm9000_timeout;
- ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
- ndev->stop = &dm9000_stop;
- ndev->set_multicast_list = &dm9000_hash_table;
- ndev->ethtool_ops = &dm9000_ethtool_ops;
- ndev->do_ioctl = &dm9000_ioctl;
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
- ndev->poll_controller = &dm9000_poll_controller;
-#endif
+ ndev->netdev_ops = &dm9000_netdev_ops;
+ ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
+ ndev->ethtool_ops = &dm9000_ethtool_ops;
db->msg_enable = NETIF_MSG_LINK;
db->mii.phy_id_mask = 0x1f;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index b1419e21b46b..9a32d0c73cb3 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -498,6 +498,8 @@ int e1000_up(struct e1000_adapter *adapter)
e1000_irq_enable(adapter);
+ netif_wake_queue(adapter->netdev);
+
/* fire a link change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
return 0;
@@ -1234,15 +1236,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
!e1000_check_mng_mode(hw))
e1000_get_hw_control(adapter);
- /* tell the stack to leave us alone until e1000_open() is called */
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
+ /* carrier off reporting is important to ethtool even BEFORE open */
+ netif_carrier_off(netdev);
+
DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
cards_found++;
@@ -1441,6 +1442,8 @@ static int e1000_open(struct net_device *netdev)
if (test_bit(__E1000_TESTING, &adapter->flags))
return -EBUSY;
+ netif_carrier_off(netdev);
+
/* allocate transmit descriptors */
err = e1000_setup_all_tx_resources(adapter);
if (err)
@@ -2590,7 +2593,6 @@ static void e1000_watchdog(unsigned long data)
ew32(TCTL, tctl);
netif_carrier_on(netdev);
- netif_wake_queue(netdev);
mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
adapter->smartspeed = 0;
} else {
@@ -2607,7 +2609,6 @@ static void e1000_watchdog(unsigned long data)
printk(KERN_INFO "e1000: %s NIC Link is Down\n",
netdev->name);
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
/* 80003ES2LAN workaround--
@@ -2645,6 +2646,8 @@ static void e1000_watchdog(unsigned long data)
* (Do the reset outside of interrupt context). */
adapter->tx_timeout_count++;
schedule_work(&adapter->reset_task);
+ /* return immediately since reset is imminent */
+ return;
}
}
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index ca82f19a7ed1..ccaaee0951cf 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2826,6 +2826,8 @@ int e1000e_up(struct e1000_adapter *adapter)
e1000_configure_msix(adapter);
e1000_irq_enable(adapter);
+ netif_wake_queue(adapter->netdev);
+
/* fire a link change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
return 0;
@@ -2848,7 +2850,7 @@ void e1000e_down(struct e1000_adapter *adapter)
ew32(RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */
- netif_tx_stop_all_queues(netdev);
+ netif_stop_queue(netdev);
/* disable transmits in the hardware */
tctl = er32(TCTL);
@@ -3072,6 +3074,8 @@ static int e1000_open(struct net_device *netdev)
if (test_bit(__E1000_TESTING, &adapter->state))
return -EBUSY;
+ netif_carrier_off(netdev);
+
/* allocate transmit descriptors */
err = e1000e_setup_tx_resources(adapter);
if (err)
@@ -3128,7 +3132,7 @@ static int e1000_open(struct net_device *netdev)
e1000_irq_enable(adapter);
- netif_tx_start_all_queues(netdev);
+ netif_start_queue(netdev);
/* fire a link status change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
@@ -3598,7 +3602,6 @@ static void e1000_watchdog_task(struct work_struct *work)
phy->ops.cfg_on_link_up(hw);
netif_carrier_on(netdev);
- netif_tx_wake_all_queues(netdev);
if (!test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
@@ -3612,7 +3615,6 @@ static void e1000_watchdog_task(struct work_struct *work)
printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
adapter->netdev->name);
netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
if (!test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
@@ -3649,6 +3651,8 @@ link_up:
*/
adapter->tx_timeout_count++;
schedule_work(&adapter->reset_task);
+ /* return immediately since reset is imminent */
+ return;
}
}
@@ -5037,15 +5041,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (!(adapter->flags & FLAG_HAS_AMT))
e1000_get_hw_control(adapter);
- /* tell the stack to leave us alone until e1000_open() is called */
- netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
-
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
+ /* carrier off reporting is important to ethtool even BEFORE open */
+ netif_carrier_off(netdev);
+
e1000_print_device_info(adapter);
return 0;
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index b22dab9153f6..147c4b088fb3 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -3261,7 +3261,7 @@ static ssize_t ehea_probe_port(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ehea_adapter *adapter = dev->driver_data;
+ struct ehea_adapter *adapter = dev_get_drvdata(dev);
struct ehea_port *port;
struct device_node *eth_dn = NULL;
int i;
@@ -3316,7 +3316,7 @@ static ssize_t ehea_remove_port(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ehea_adapter *adapter = dev->driver_data;
+ struct ehea_adapter *adapter = dev_get_drvdata(dev);
struct ehea_port *port;
int i;
u32 logical_port_id;
@@ -3404,7 +3404,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
adapter->pd = EHEA_PD_ID;
- dev->dev.driver_data = adapter;
+ dev_set_drvdata(&dev->dev, adapter);
/* initialize adapter and ports */
@@ -3468,7 +3468,7 @@ out:
static int __devexit ehea_remove(struct of_device *dev)
{
- struct ehea_adapter *adapter = dev->dev.driver_data;
+ struct ehea_adapter *adapter = dev_get_drvdata(&dev->dev);
int i;
for (i = 0; i < EHEA_MAX_PORTS; i++)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 682e7f0b5581..28db6919c526 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -86,8 +86,7 @@ static unsigned char fec_mac_default[] = {
#endif
#endif /* CONFIG_M5272 */
-/* Forward declarations of some structures to support different PHYs
-*/
+/* Forward declarations of some structures to support different PHYs */
typedef struct {
uint mii_data;
@@ -123,8 +122,7 @@ typedef struct {
#error "FEC: descriptor ring size constants too large"
#endif
-/* Interrupt events/masks.
-*/
+/* Interrupt events/masks. */
#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
@@ -165,7 +163,7 @@ typedef struct {
*/
struct fec_enet_private {
/* Hardware registers of the FEC device */
- volatile fec_t *hwp;
+ void __iomem *hwp;
struct net_device *netdev;
@@ -174,16 +172,20 @@ struct fec_enet_private {
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
unsigned char *tx_bounce[TX_RING_SIZE];
struct sk_buff* tx_skbuff[TX_RING_SIZE];
+ struct sk_buff* rx_skbuff[RX_RING_SIZE];
ushort skb_cur;
ushort skb_dirty;
- /* CPM dual port RAM relative addresses.
- */
+ /* CPM dual port RAM relative addresses */
dma_addr_t bd_dma;
- cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
- cbd_t *tx_bd_base;
- cbd_t *cur_rx, *cur_tx; /* The next free ring entry */
- cbd_t *dirty_tx; /* The ring entries to be free()ed. */
+ /* Address of Rx and Tx buffers */
+ struct bufdesc *rx_bd_base;
+ struct bufdesc *tx_bd_base;
+ /* The next free ring entry */
+ struct bufdesc *cur_rx, *cur_tx;
+ /* The ring entries to be free()ed */
+ struct bufdesc *dirty_tx;
+
uint tx_full;
/* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
spinlock_t hw_lock;
@@ -209,17 +211,13 @@ struct fec_enet_private {
int full_duplex;
};
-static int fec_enet_open(struct net_device *dev);
-static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void fec_enet_mii(struct net_device *dev);
static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
static void fec_enet_tx(struct net_device *dev);
static void fec_enet_rx(struct net_device *dev);
static int fec_enet_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
static void fec_restart(struct net_device *dev, int duplex);
static void fec_stop(struct net_device *dev);
-static void fec_set_mac_address(struct net_device *dev);
/* MII processing. We keep this as simple as possible. Requests are
@@ -241,19 +239,16 @@ static mii_list_t *mii_tail;
static int mii_queue(struct net_device *dev, int request,
void (*func)(uint, struct net_device *));
-/* Make MII read/write commands for the FEC.
-*/
+/* Make MII read/write commands for the FEC */
#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18))
#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \
(VAL & 0xffff))
#define mk_mii_end 0
-/* Transmitter timeout.
-*/
-#define TX_TIMEOUT (2*HZ)
+/* Transmitter timeout */
+#define TX_TIMEOUT (2 * HZ)
-/* Register definitions for the PHY.
-*/
+/* Register definitions for the PHY */
#define MII_REG_CR 0 /* Control Register */
#define MII_REG_SR 1 /* Status Register */
@@ -288,15 +283,11 @@ static int mii_queue(struct net_device *dev, int request,
static int
fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct fec_enet_private *fep;
- volatile fec_t *fecp;
- volatile cbd_t *bdp;
+ struct fec_enet_private *fep = netdev_priv(dev);
+ struct bufdesc *bdp;
unsigned short status;
unsigned long flags;
- fep = netdev_priv(dev);
- fecp = (volatile fec_t*)dev->base_addr;
-
if (!fep->link) {
/* Link is down or autonegotiation is in progress. */
return 1;
@@ -307,7 +298,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
bdp = fep->cur_tx;
status = bdp->cbd_sc;
-#ifndef final_version
+
if (status & BD_ENET_TX_READY) {
/* Ooops. All transmit buffers are full. Bail out.
* This should not happen, since dev->tbusy should be set.
@@ -316,21 +307,18 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&fep->hw_lock, flags);
return 1;
}
-#endif
- /* Clear all of the status flags.
- */
+ /* Clear all of the status flags */
status &= ~BD_ENET_TX_STATS;
- /* Set buffer length and buffer pointer.
- */
+ /* Set buffer length and buffer pointer */
bdp->cbd_bufaddr = __pa(skb->data);
bdp->cbd_datlen = skb->len;
/*
- * On some FEC implementations data must be aligned on
- * 4-byte boundaries. Use bounce buffers to copy data
- * and get it aligned. Ugh.
+ * On some FEC implementations data must be aligned on
+ * 4-byte boundaries. Use bounce buffers to copy data
+ * and get it aligned. Ugh.
*/
if (bdp->cbd_bufaddr & FEC_ALIGNMENT) {
unsigned int index;
@@ -339,8 +327,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
}
- /* Save skb pointer.
- */
+ /* Save skb pointer */
fep->tx_skbuff[fep->skb_cur] = skb;
dev->stats.tx_bytes += skb->len;
@@ -349,13 +336,12 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Push the data cache so the CPM does not get stale memory
* data.
*/
- dma_sync_single(NULL, bdp->cbd_bufaddr,
- bdp->cbd_datlen, DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+ FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
/* Send it on its way. Tell FEC it's ready, interrupt when done,
* it's the last BD of the frame, and to put the CRC on the end.
*/
-
status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
| BD_ENET_TX_LAST | BD_ENET_TX_TC);
bdp->cbd_sc = status;
@@ -363,22 +349,20 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
/* Trigger transmission start */
- fecp->fec_x_des_active = 0;
+ writel(0, fep->hwp + FEC_X_DES_ACTIVE);
- /* If this was the last BD in the ring, start at the beginning again.
- */
- if (status & BD_ENET_TX_WRAP) {
+ /* If this was the last BD in the ring, start at the beginning again. */
+ if (status & BD_ENET_TX_WRAP)
bdp = fep->tx_bd_base;
- } else {
+ else
bdp++;
- }
if (bdp == fep->dirty_tx) {
fep->tx_full = 1;
netif_stop_queue(dev);
}
- fep->cur_tx = (cbd_t *)bdp;
+ fep->cur_tx = bdp;
spin_unlock_irqrestore(&fep->hw_lock, flags);
@@ -390,75 +374,33 @@ fec_timeout(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- printk("%s: transmit timed out.\n", dev->name);
dev->stats.tx_errors++;
-#ifndef final_version
- {
- int i;
- cbd_t *bdp;
-
- printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
- (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
- (unsigned long)fep->dirty_tx,
- (unsigned long)fep->cur_rx);
-
- bdp = fep->tx_bd_base;
- printk(" tx: %u buffers\n", TX_RING_SIZE);
- for (i = 0 ; i < TX_RING_SIZE; i++) {
- printk(" %08x: %04x %04x %08x\n",
- (uint) bdp,
- bdp->cbd_sc,
- bdp->cbd_datlen,
- (int) bdp->cbd_bufaddr);
- bdp++;
- }
- bdp = fep->rx_bd_base;
- printk(" rx: %lu buffers\n", (unsigned long) RX_RING_SIZE);
- for (i = 0 ; i < RX_RING_SIZE; i++) {
- printk(" %08x: %04x %04x %08x\n",
- (uint) bdp,
- bdp->cbd_sc,
- bdp->cbd_datlen,
- (int) bdp->cbd_bufaddr);
- bdp++;
- }
- }
-#endif
fec_restart(dev, fep->full_duplex);
netif_wake_queue(dev);
}
-/* The interrupt handler.
- * This is called from the MPC core interrupt.
- */
static irqreturn_t
fec_enet_interrupt(int irq, void * dev_id)
{
struct net_device *dev = dev_id;
- volatile fec_t *fecp;
+ struct fec_enet_private *fep = netdev_priv(dev);
uint int_events;
irqreturn_t ret = IRQ_NONE;
- fecp = (volatile fec_t*)dev->base_addr;
-
- /* Get the interrupt events that caused us to be here.
- */
do {
- int_events = fecp->fec_ievent;
- fecp->fec_ievent = int_events;
+ int_events = readl(fep->hwp + FEC_IEVENT);
+ writel(int_events, fep->hwp + FEC_IEVENT);
- /* Handle receive event in its own function.
- */
if (int_events & FEC_ENET_RXF) {
ret = IRQ_HANDLED;
fec_enet_rx(dev);
}
/* Transmit OK, or non-fatal error. Update the buffer
- descriptors. FEC handles all errors, we just discover
- them as part of the transmit process.
- */
+ * descriptors. FEC handles all errors, we just discover
+ * them as part of the transmit process.
+ */
if (int_events & FEC_ENET_TXF) {
ret = IRQ_HANDLED;
fec_enet_tx(dev);
@@ -479,7 +421,7 @@ static void
fec_enet_tx(struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile cbd_t *bdp;
+ struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
@@ -488,7 +430,11 @@ fec_enet_tx(struct net_device *dev)
bdp = fep->dirty_tx;
while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
- if (bdp == fep->cur_tx && fep->tx_full == 0) break;
+ if (bdp == fep->cur_tx && fep->tx_full == 0)
+ break;
+
+ dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = 0;
skb = fep->tx_skbuff[fep->skb_dirty];
/* Check for errors. */
@@ -510,31 +456,27 @@ fec_enet_tx(struct net_device *dev)
dev->stats.tx_packets++;
}
-#ifndef final_version
if (status & BD_ENET_TX_READY)
printk("HEY! Enet xmit interrupt and TX_READY.\n");
-#endif
+
/* Deferred means some collisions occurred during transmit,
* but we eventually sent the packet OK.
*/
if (status & BD_ENET_TX_DEF)
dev->stats.collisions++;
- /* Free the sk buffer associated with this last transmit.
- */
+ /* Free the sk buffer associated with this last transmit */
dev_kfree_skb_any(skb);
fep->tx_skbuff[fep->skb_dirty] = NULL;
fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
- /* Update pointer to next buffer descriptor to be transmitted.
- */
+ /* Update pointer to next buffer descriptor to be transmitted */
if (status & BD_ENET_TX_WRAP)
bdp = fep->tx_bd_base;
else
bdp++;
- /* Since we have freed up a buffer, the ring is no longer
- * full.
+ /* Since we have freed up a buffer, the ring is no longer full
*/
if (fep->tx_full) {
fep->tx_full = 0;
@@ -542,7 +484,7 @@ fec_enet_tx(struct net_device *dev)
netif_wake_queue(dev);
}
}
- fep->dirty_tx = (cbd_t *)bdp;
+ fep->dirty_tx = bdp;
spin_unlock_irq(&fep->hw_lock);
}
@@ -555,9 +497,8 @@ fec_enet_tx(struct net_device *dev)
static void
fec_enet_rx(struct net_device *dev)
{
- struct fec_enet_private *fep;
- volatile fec_t *fecp;
- volatile cbd_t *bdp;
+ struct fec_enet_private *fep = netdev_priv(dev);
+ struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
ushort pkt_len;
@@ -567,9 +508,6 @@ fec_enet_rx(struct net_device *dev)
flush_cache_all();
#endif
- fep = netdev_priv(dev);
- fecp = (volatile fec_t*)dev->base_addr;
-
spin_lock_irq(&fep->hw_lock);
/* First, grab all of the stats for the incoming packet.
@@ -577,143 +515,121 @@ fec_enet_rx(struct net_device *dev)
*/
bdp = fep->cur_rx;
-while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
+ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
-#ifndef final_version
- /* Since we have allocated space to hold a complete frame,
- * the last indicator should be set.
- */
- if ((status & BD_ENET_RX_LAST) == 0)
- printk("FEC ENET: rcv is not +last\n");
-#endif
+ /* Since we have allocated space to hold a complete frame,
+ * the last indicator should be set.
+ */
+ if ((status & BD_ENET_RX_LAST) == 0)
+ printk("FEC ENET: rcv is not +last\n");
- if (!fep->opened)
- goto rx_processing_done;
+ if (!fep->opened)
+ goto rx_processing_done;
- /* Check for errors. */
- if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
+ /* Check for errors. */
+ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
BD_ENET_RX_CR | BD_ENET_RX_OV)) {
- dev->stats.rx_errors++;
- if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
- /* Frame too long or too short. */
- dev->stats.rx_length_errors++;
+ dev->stats.rx_errors++;
+ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
+ /* Frame too long or too short. */
+ dev->stats.rx_length_errors++;
+ }
+ if (status & BD_ENET_RX_NO) /* Frame alignment */
+ dev->stats.rx_frame_errors++;
+ if (status & BD_ENET_RX_CR) /* CRC Error */
+ dev->stats.rx_crc_errors++;
+ if (status & BD_ENET_RX_OV) /* FIFO overrun */
+ dev->stats.rx_fifo_errors++;
}
- if (status & BD_ENET_RX_NO) /* Frame alignment */
+
+ /* Report late collisions as a frame error.
+ * On this error, the BD is closed, but we don't know what we
+ * have in the buffer. So, just drop this frame on the floor.
+ */
+ if (status & BD_ENET_RX_CL) {
+ dev->stats.rx_errors++;
dev->stats.rx_frame_errors++;
- if (status & BD_ENET_RX_CR) /* CRC Error */
- dev->stats.rx_crc_errors++;
- if (status & BD_ENET_RX_OV) /* FIFO overrun */
- dev->stats.rx_fifo_errors++;
- }
+ goto rx_processing_done;
+ }
- /* Report late collisions as a frame error.
- * On this error, the BD is closed, but we don't know what we
- * have in the buffer. So, just drop this frame on the floor.
- */
- if (status & BD_ENET_RX_CL) {
- dev->stats.rx_errors++;
- dev->stats.rx_frame_errors++;
- goto rx_processing_done;
- }
+ /* Process the incoming frame. */
+ dev->stats.rx_packets++;
+ pkt_len = bdp->cbd_datlen;
+ dev->stats.rx_bytes += pkt_len;
+ data = (__u8*)__va(bdp->cbd_bufaddr);
- /* Process the incoming frame.
- */
- dev->stats.rx_packets++;
- pkt_len = bdp->cbd_datlen;
- dev->stats.rx_bytes += pkt_len;
- data = (__u8*)__va(bdp->cbd_bufaddr);
-
- dma_sync_single(NULL, (unsigned long)__pa(data),
- pkt_len - 4, DMA_FROM_DEVICE);
-
- /* This does 16 byte alignment, exactly what we need.
- * The packet length includes FCS, but we don't want to
- * include that when passing upstream as it messes up
- * bridging applications.
- */
- skb = dev_alloc_skb(pkt_len-4);
+ dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
+ DMA_FROM_DEVICE);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- dev->stats.rx_dropped++;
- } else {
- skb_put(skb,pkt_len-4); /* Make room */
- skb_copy_to_linear_data(skb, data, pkt_len-4);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- }
- rx_processing_done:
+ /* This does 16 byte alignment, exactly what we need.
+ * The packet length includes FCS, but we don't want to
+ * include that when passing upstream as it messes up
+ * bridging applications.
+ */
+ skb = dev_alloc_skb(pkt_len - 4 + NET_IP_ALIGN);
- /* Clear the status flags for this buffer.
- */
- status &= ~BD_ENET_RX_STATS;
+ if (unlikely(!skb)) {
+ printk("%s: Memory squeeze, dropping packet.\n",
+ dev->name);
+ dev->stats.rx_dropped++;
+ } else {
+ skb_reserve(skb, NET_IP_ALIGN);
+ skb_put(skb, pkt_len - 4); /* Make room */
+ skb_copy_to_linear_data(skb, data, pkt_len - 4);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ }
- /* Mark the buffer empty.
- */
- status |= BD_ENET_RX_EMPTY;
- bdp->cbd_sc = status;
+ bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen,
+ DMA_FROM_DEVICE);
+rx_processing_done:
+ /* Clear the status flags for this buffer */
+ status &= ~BD_ENET_RX_STATS;
- /* Update BD pointer to next entry.
- */
- if (status & BD_ENET_RX_WRAP)
- bdp = fep->rx_bd_base;
- else
- bdp++;
+ /* Mark the buffer empty */
+ status |= BD_ENET_RX_EMPTY;
+ bdp->cbd_sc = status;
-#if 1
- /* Doing this here will keep the FEC running while we process
- * incoming frames. On a heavily loaded network, we should be
- * able to keep up at the expense of system resources.
- */
- fecp->fec_r_des_active = 0;
-#endif
- } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */
- fep->cur_rx = (cbd_t *)bdp;
-
-#if 0
- /* Doing this here will allow us to process all frames in the
- * ring before the FEC is allowed to put more there. On a heavily
- * loaded network, some frames may be lost. Unfortunately, this
- * increases the interrupt overhead since we can potentially work
- * our way back to the interrupt return only to come right back
- * here.
- */
- fecp->fec_r_des_active = 0;
-#endif
+ /* Update BD pointer to next entry */
+ if (status & BD_ENET_RX_WRAP)
+ bdp = fep->rx_bd_base;
+ else
+ bdp++;
+ /* Doing this here will keep the FEC running while we process
+ * incoming frames. On a heavily loaded network, we should be
+ * able to keep up at the expense of system resources.
+ */
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE);
+ }
+ fep->cur_rx = bdp;
spin_unlock_irq(&fep->hw_lock);
}
-
/* called from interrupt context */
static void
fec_enet_mii(struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile fec_t *ep;
mii_list_t *mip;
- uint mii_reg;
fep = netdev_priv(dev);
spin_lock_irq(&fep->mii_lock);
- ep = fep->hwp;
- mii_reg = ep->fec_mii_data;
-
if ((mip = mii_head) == NULL) {
printk("MII and no head!\n");
goto unlock;
}
if (mip->mii_func != NULL)
- (*(mip->mii_func))(mii_reg, dev);
+ (*(mip->mii_func))(readl(fep->hwp + FEC_MII_DATA), dev);
mii_head = mip->mii_next;
mip->mii_next = mii_free;
mii_free = mip;
if ((mip = mii_head) != NULL)
- ep->fec_mii_data = mip->mii_regval;
+ writel(mip->mii_regval, fep->hwp + FEC_MII_DATA);
unlock:
spin_unlock_irq(&fep->mii_lock);
@@ -727,8 +643,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
mii_list_t *mip;
int retval;
- /* Add PHY address to register command.
- */
+ /* Add PHY address to register command */
fep = netdev_priv(dev);
spin_lock_irqsave(&fep->mii_lock, flags);
@@ -745,7 +660,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
mii_tail = mip;
} else {
mii_head = mii_tail = mip;
- fep->hwp->fec_mii_data = regval;
+ writel(regval, fep->hwp + FEC_MII_DATA);
}
} else {
retval = 1;
@@ -1246,11 +1161,8 @@ static void __inline__ fec_phy_ack_intr(void)
static void __inline__ fec_get_mac(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- volatile fec_t *fecp;
unsigned char *iap, tmpaddr[ETH_ALEN];
- fecp = fep->hwp;
-
if (FEC_FLASHMAC) {
/*
* Get MAC address from FLASH.
@@ -1264,8 +1176,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
(iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
iap = fec_mac_default;
} else {
- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+ *((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
+ *((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
iap = &tmpaddr[0];
}
@@ -1375,11 +1287,6 @@ static void mii_relink(struct work_struct *work)
fec_restart(dev, duplex);
} else
fec_stop(dev);
-
-#if 0
- enable_irq(fep->mii_irq);
-#endif
-
}
/* mii_queue_relink is called in interrupt context from mii_link_interrupt */
@@ -1388,12 +1295,12 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev)
struct fec_enet_private *fep = netdev_priv(dev);
/*
- ** We cannot queue phy_task twice in the workqueue. It
- ** would cause an endless loop in the workqueue.
- ** Fortunately, if the last mii_relink entry has not yet been
- ** executed now, it will do the job for the current interrupt,
- ** which is just what we want.
- */
+ * We cannot queue phy_task twice in the workqueue. It
+ * would cause an endless loop in the workqueue.
+ * Fortunately, if the last mii_relink entry has not yet been
+ * executed now, it will do the job for the current interrupt,
+ * which is just what we want.
+ */
if (fep->mii_phy_task_queued)
return;
@@ -1424,8 +1331,7 @@ phy_cmd_t const phy_cmd_config[] = {
{ mk_mii_end, }
};
-/* Read remainder of PHY ID.
-*/
+/* Read remainder of PHY ID. */
static void
mii_discover_phy3(uint mii_reg, struct net_device *dev)
{
@@ -1457,17 +1363,14 @@ static void
mii_discover_phy(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile fec_t *fecp;
uint phytype;
fep = netdev_priv(dev);
- fecp = fep->hwp;
if (fep->phy_addr < 32) {
if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {
- /* Got first part of ID, now get remainder.
- */
+ /* Got first part of ID, now get remainder */
fep->phy_id = phytype << 16;
mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
mii_discover_phy3);
@@ -1479,15 +1382,15 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
} else {
printk("FEC: No PHY device found.\n");
/* Disable external MII interface */
- fecp->fec_mii_speed = fep->phy_speed = 0;
+ writel(0, fep->hwp + FEC_MII_SPEED);
+ fep->phy_speed = 0;
#ifdef HAVE_mii_link_interrupt
fec_disable_phy_intr();
#endif
}
}
-/* This interrupt occurs when the PHY detects a link change.
-*/
+/* This interrupt occurs when the PHY detects a link change */
#ifdef HAVE_mii_link_interrupt
static irqreturn_t
mii_link_interrupt(int irq, void * dev_id)
@@ -1497,10 +1400,6 @@ mii_link_interrupt(int irq, void * dev_id)
fec_phy_ack_intr();
-#if 0
- disable_irq(fep->mii_irq); /* disable now, enable later */
-#endif
-
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */
@@ -1508,19 +1407,91 @@ mii_link_interrupt(int irq, void * dev_id)
}
#endif
+static void fec_enet_free_buffers(struct net_device *dev)
+{
+ struct fec_enet_private *fep = netdev_priv(dev);
+ int i;
+ struct sk_buff *skb;
+ struct bufdesc *bdp;
+
+ bdp = fep->rx_bd_base;
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ skb = fep->rx_skbuff[i];
+
+ if (bdp->cbd_bufaddr)
+ dma_unmap_single(&dev->dev, bdp->cbd_bufaddr,
+ FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+ if (skb)
+ dev_kfree_skb(skb);
+ bdp++;
+ }
+
+ bdp = fep->tx_bd_base;
+ for (i = 0; i < TX_RING_SIZE; i++)
+ kfree(fep->tx_bounce[i]);
+}
+
+static int fec_enet_alloc_buffers(struct net_device *dev)
+{
+ struct fec_enet_private *fep = netdev_priv(dev);
+ int i;
+ struct sk_buff *skb;
+ struct bufdesc *bdp;
+
+ bdp = fep->rx_bd_base;
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE);
+ if (!skb) {
+ fec_enet_free_buffers(dev);
+ return -ENOMEM;
+ }
+ fep->rx_skbuff[i] = skb;
+
+ bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+ FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+ bdp->cbd_sc = BD_ENET_RX_EMPTY;
+ bdp++;
+ }
+
+ /* Set the last buffer to wrap. */
+ bdp--;
+ bdp->cbd_sc |= BD_SC_WRAP;
+
+ bdp = fep->tx_bd_base;
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
+
+ bdp->cbd_sc = 0;
+ bdp->cbd_bufaddr = 0;
+ bdp++;
+ }
+
+ /* Set the last buffer to wrap. */
+ bdp--;
+ bdp->cbd_sc |= BD_SC_WRAP;
+
+ return 0;
+}
+
static int
fec_enet_open(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
+ int ret;
/* I should reset the ring buffers here, but I don't yet know
* a simple way to do that.
*/
- fec_set_mac_address(dev);
+
+ ret = fec_enet_alloc_buffers(dev);
+ if (ret)
+ return ret;
fep->sequence_done = 0;
fep->link = 0;
+ fec_restart(dev, 1);
+
if (fep->phy) {
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, fep->phy->config);
@@ -1537,21 +1508,17 @@ fec_enet_open(struct net_device *dev)
schedule();
mii_do_cmd(dev, fep->phy->startup);
-
- /* Set the initial link state to true. A lot of hardware
- * based on this device does not implement a PHY interrupt,
- * so we are never notified of link change.
- */
- fep->link = 1;
- } else {
- fep->link = 1; /* lets just try it and see */
- /* no phy, go full duplex, it's most likely a hub chip */
- fec_restart(dev, 1);
}
+ /* Set the initial link state to true. A lot of hardware
+ * based on this device does not implement a PHY interrupt,
+ * so we are never notified of link change.
+ */
+ fep->link = 1;
+
netif_start_queue(dev);
fep->opened = 1;
- return 0; /* Success */
+ return 0;
}
static int
@@ -1559,12 +1526,13 @@ fec_enet_close(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- /* Don't know what to do yet.
- */
+ /* Don't know what to do yet. */
fep->opened = 0;
netif_stop_queue(dev);
fec_stop(dev);
+ fec_enet_free_buffers(dev);
+
return 0;
}
@@ -1583,87 +1551,102 @@ fec_enet_close(struct net_device *dev)
static void set_multicast_list(struct net_device *dev)
{
- struct fec_enet_private *fep;
- volatile fec_t *ep;
+ struct fec_enet_private *fep = netdev_priv(dev);
struct dev_mc_list *dmi;
- unsigned int i, j, bit, data, crc;
+ unsigned int i, j, bit, data, crc, tmp;
unsigned char hash;
- fep = netdev_priv(dev);
- ep = fep->hwp;
+ if (dev->flags & IFF_PROMISC) {
+ tmp = readl(fep->hwp + FEC_R_CNTRL);
+ tmp |= 0x8;
+ writel(tmp, fep->hwp + FEC_R_CNTRL);
+ return;
+ }
- if (dev->flags&IFF_PROMISC) {
- ep->fec_r_cntrl |= 0x0008;
- } else {
+ tmp = readl(fep->hwp + FEC_R_CNTRL);
+ tmp &= ~0x8;
+ writel(tmp, fep->hwp + FEC_R_CNTRL);
+
+ if (dev->flags & IFF_ALLMULTI) {
+ /* Catch all multicast addresses, so set the
+ * filter to all 1's
+ */
+ writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
- ep->fec_r_cntrl &= ~0x0008;
+ return;
+ }
- if (dev->flags & IFF_ALLMULTI) {
- /* Catch all multicast addresses, so set the
- * filter to all 1's.
- */
- ep->fec_grp_hash_table_high = 0xffffffff;
- ep->fec_grp_hash_table_low = 0xffffffff;
- } else {
- /* Clear filter and add the addresses in hash register.
- */
- ep->fec_grp_hash_table_high = 0;
- ep->fec_grp_hash_table_low = 0;
-
- dmi = dev->mc_list;
-
- for (j = 0; j < dev->mc_count; j++, dmi = dmi->next)
- {
- /* Only support group multicast for now.
- */
- if (!(dmi->dmi_addr[0] & 1))
- continue;
-
- /* calculate crc32 value of mac address
- */
- crc = 0xffffffff;
-
- for (i = 0; i < dmi->dmi_addrlen; i++)
- {
- data = dmi->dmi_addr[i];
- for (bit = 0; bit < 8; bit++, data >>= 1)
- {
- crc = (crc >> 1) ^
- (((crc ^ data) & 1) ? CRC32_POLY : 0);
- }
- }
-
- /* only upper 6 bits (HASH_BITS) are used
- which point to specific bit in he hash registers
- */
- hash = (crc >> (32 - HASH_BITS)) & 0x3f;
-
- if (hash > 31)
- ep->fec_grp_hash_table_high |= 1 << (hash - 32);
- else
- ep->fec_grp_hash_table_low |= 1 << hash;
+ /* Clear filter and add the addresses in hash register
+ */
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+
+ dmi = dev->mc_list;
+
+ for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) {
+ /* Only support group multicast for now */
+ if (!(dmi->dmi_addr[0] & 1))
+ continue;
+
+ /* calculate crc32 value of mac address */
+ crc = 0xffffffff;
+
+ for (i = 0; i < dmi->dmi_addrlen; i++) {
+ data = dmi->dmi_addr[i];
+ for (bit = 0; bit < 8; bit++, data >>= 1) {
+ crc = (crc >> 1) ^
+ (((crc ^ data) & 1) ? CRC32_POLY : 0);
}
}
+
+ /* only upper 6 bits (HASH_BITS) are used
+ * which point to specific bit in he hash registers
+ */
+ hash = (crc >> (32 - HASH_BITS)) & 0x3f;
+
+ if (hash > 31) {
+ tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ tmp |= 1 << (hash - 32);
+ writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ } else {
+ tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+ tmp |= 1 << hash;
+ writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+ }
}
}
-/* Set a MAC change in hardware.
- */
-static void
-fec_set_mac_address(struct net_device *dev)
+/* Set a MAC change in hardware. */
+static int
+fec_set_mac_address(struct net_device *dev, void *p)
{
- volatile fec_t *fecp;
+ struct fec_enet_private *fep = netdev_priv(dev);
+ struct sockaddr *addr = p;
- fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp;
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
- /* Set station address. */
- fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
- (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24);
- fecp->fec_addr_high = (dev->dev_addr[5] << 16) |
- (dev->dev_addr[4] << 24);
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ writel(dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
+ (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24),
+ fep->hwp + FEC_ADDR_LOW);
+ writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24),
+ fep + FEC_ADDR_HIGH);
+ return 0;
}
+static const struct net_device_ops fec_netdev_ops = {
+ .ndo_open = fec_enet_open,
+ .ndo_stop = fec_enet_close,
+ .ndo_start_xmit = fec_enet_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_tx_timeout = fec_timeout,
+ .ndo_set_mac_address = fec_set_mac_address,
+};
+
/*
* XXX: We need to clean up on failure exits here.
*
@@ -1672,17 +1655,13 @@ fec_set_mac_address(struct net_device *dev)
int __init fec_enet_init(struct net_device *dev, int index)
{
struct fec_enet_private *fep = netdev_priv(dev);
- unsigned long mem_addr;
- volatile cbd_t *bdp;
- cbd_t *cbd_base;
- volatile fec_t *fecp;
- int i, j;
+ struct bufdesc *cbd_base;
+ int i;
- /* Allocate memory for buffer descriptors.
- */
- mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE,
- &fep->bd_dma, GFP_KERNEL);
- if (mem_addr == 0) {
+ /* Allocate memory for buffer descriptors. */
+ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
+ GFP_KERNEL);
+ if (!cbd_base) {
printk("FEC: allocate descriptor memory failed?\n");
return -ENOMEM;
}
@@ -1690,146 +1669,47 @@ int __init fec_enet_init(struct net_device *dev, int index)
spin_lock_init(&fep->hw_lock);
spin_lock_init(&fep->mii_lock);
- /* Create an Ethernet device instance.
- */
- fecp = (volatile fec_t *)dev->base_addr;
-
fep->index = index;
- fep->hwp = fecp;
+ fep->hwp = (void __iomem *)dev->base_addr;
fep->netdev = dev;
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
- udelay(10);
-
/* Set the Ethernet address */
#ifdef CONFIG_M5272
fec_get_mac(dev);
#else
{
unsigned long l;
- l = fecp->fec_addr_low;
+ l = readl(fep->hwp + FEC_ADDR_LOW);
dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
- l = fecp->fec_addr_high;
+ l = readl(fep->hwp + FEC_ADDR_HIGH);
dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
}
#endif
- cbd_base = (cbd_t *)mem_addr;
-
- /* Set receive and transmit descriptor base.
- */
+ /* Set receive and transmit descriptor base. */
fep->rx_bd_base = cbd_base;
fep->tx_bd_base = cbd_base + RX_RING_SIZE;
- fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
- fep->cur_rx = fep->rx_bd_base;
-
- fep->skb_cur = fep->skb_dirty = 0;
-
- /* Initialize the receive buffer descriptors.
- */
- bdp = fep->rx_bd_base;
- for (i=0; i<FEC_ENET_RX_PAGES; i++) {
-
- /* Allocate a page.
- */
- mem_addr = __get_free_page(GFP_KERNEL);
- /* XXX: missing check for allocation failure */
-
- /* Initialize the BD for every fragment in the page.
- */
- for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
- bdp->cbd_sc = BD_ENET_RX_EMPTY;
- bdp->cbd_bufaddr = __pa(mem_addr);
- mem_addr += FEC_ENET_RX_FRSIZE;
- bdp++;
- }
- }
-
- /* Set the last buffer to wrap.
- */
- bdp--;
- bdp->cbd_sc |= BD_SC_WRAP;
-
- /* ...and the same for transmmit.
- */
- bdp = fep->tx_bd_base;
- for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {
- if (j >= FEC_ENET_TX_FRPPG) {
- mem_addr = __get_free_page(GFP_KERNEL);
- j = 1;
- } else {
- mem_addr += FEC_ENET_TX_FRSIZE;
- j++;
- }
- fep->tx_bounce[i] = (unsigned char *) mem_addr;
-
- /* Initialize the BD for every fragment in the page.
- */
- bdp->cbd_sc = 0;
- bdp->cbd_bufaddr = 0;
- bdp++;
- }
-
- /* Set the last buffer to wrap.
- */
- bdp--;
- bdp->cbd_sc |= BD_SC_WRAP;
-
- /* Set receive and transmit descriptor base.
- */
- fecp->fec_r_des_start = fep->bd_dma;
- fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
- * RX_RING_SIZE;
-
#ifdef HAVE_mii_link_interrupt
fec_request_mii_intr(dev);
#endif
-
- fecp->fec_grp_hash_table_high = 0;
- fecp->fec_grp_hash_table_low = 0;
- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
- fecp->fec_ecntrl = 2;
- fecp->fec_r_des_active = 0;
-#ifndef CONFIG_M5272
- fecp->fec_hash_table_high = 0;
- fecp->fec_hash_table_low = 0;
-#endif
-
- /* The FEC Ethernet specific entries in the device structure. */
- dev->open = fec_enet_open;
- dev->hard_start_xmit = fec_enet_start_xmit;
- dev->tx_timeout = fec_timeout;
+ /* The FEC Ethernet specific entries in the device structure */
dev->watchdog_timeo = TX_TIMEOUT;
- dev->stop = fec_enet_close;
- dev->set_multicast_list = set_multicast_list;
+ dev->netdev_ops = &fec_netdev_ops;
for (i=0; i<NMII-1; i++)
mii_cmds[i].mii_next = &mii_cmds[i+1];
mii_free = mii_cmds;
- /* setup MII interface */
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
-
- /*
- * Set MII speed to 2.5 MHz
- */
+ /* Set MII speed to 2.5 MHz */
fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
/ 2500000) / 2) & 0x3F) << 1;
- fecp->fec_mii_speed = fep->phy_speed;
fec_restart(dev, 0);
- /* Clear and enable interrupts */
- fecp->fec_ievent = 0xffc00000;
- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
-
/* Queue up command to detect the PHY and initialize the
* remainder of the interface.
*/
@@ -1847,145 +1727,118 @@ int __init fec_enet_init(struct net_device *dev, int index)
static void
fec_restart(struct net_device *dev, int duplex)
{
- struct fec_enet_private *fep;
- volatile cbd_t *bdp;
- volatile fec_t *fecp;
+ struct fec_enet_private *fep = netdev_priv(dev);
+ struct bufdesc *bdp;
int i;
- fep = netdev_priv(dev);
- fecp = fep->hwp;
-
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
+ /* Whack a reset. We should wait for this. */
+ writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
- /* Clear any outstanding interrupt.
- */
- fecp->fec_ievent = 0xffc00000;
+ /* Clear any outstanding interrupt. */
+ writel(0xffc00000, fep->hwp + FEC_IEVENT);
- /* Set station address.
- */
- fec_set_mac_address(dev);
+ /* Reset all multicast. */
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+#ifndef CONFIG_M5272
+ writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
+#endif
- /* Reset all multicast.
- */
- fecp->fec_grp_hash_table_high = 0;
- fecp->fec_grp_hash_table_low = 0;
+ /* Set maximum receive buffer size. */
+ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
- /* Set maximum receive buffer size.
- */
- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-
- /* Set receive and transmit descriptor base.
- */
- fecp->fec_r_des_start = fep->bd_dma;
- fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
- * RX_RING_SIZE;
+ /* Set receive and transmit descriptor base. */
+ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
+ writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE,
+ fep->hwp + FEC_X_DES_START);
fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
fep->cur_rx = fep->rx_bd_base;
- /* Reset SKB transmit buffers.
- */
+ /* Reset SKB transmit buffers. */
fep->skb_cur = fep->skb_dirty = 0;
- for (i=0; i<=TX_RING_MOD_MASK; i++) {
- if (fep->tx_skbuff[i] != NULL) {
+ for (i = 0; i <= TX_RING_MOD_MASK; i++) {
+ if (fep->tx_skbuff[i]) {
dev_kfree_skb_any(fep->tx_skbuff[i]);
fep->tx_skbuff[i] = NULL;
}
}
- /* Initialize the receive buffer descriptors.
- */
+ /* Initialize the receive buffer descriptors. */
bdp = fep->rx_bd_base;
- for (i=0; i<RX_RING_SIZE; i++) {
+ for (i = 0; i < RX_RING_SIZE; i++) {
- /* Initialize the BD for every fragment in the page.
- */
+ /* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = BD_ENET_RX_EMPTY;
bdp++;
}
- /* Set the last buffer to wrap.
- */
+ /* Set the last buffer to wrap */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* ...and the same for transmmit.
- */
+ /* ...and the same for transmit */
bdp = fep->tx_bd_base;
- for (i=0; i<TX_RING_SIZE; i++) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
- /* Initialize the BD for every fragment in the page.
- */
+ /* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = 0;
bdp->cbd_bufaddr = 0;
bdp++;
}
- /* Set the last buffer to wrap.
- */
+ /* Set the last buffer to wrap */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* Enable MII mode.
- */
+ /* Enable MII mode */
if (duplex) {
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */
- fecp->fec_x_cntrl = 0x04; /* FD enable */
+ /* MII enable / FD enable */
+ writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
+ writel(0x04, fep->hwp + FEC_X_CNTRL);
} else {
- /* MII enable|No Rcv on Xmit */
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
- fecp->fec_x_cntrl = 0x00;
+ /* MII enable / No Rcv on Xmit */
+ writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL);
+ writel(0x0, fep->hwp + FEC_X_CNTRL);
}
fep->full_duplex = duplex;
- /* Set MII speed.
- */
- fecp->fec_mii_speed = fep->phy_speed;
+ /* Set MII speed */
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
- /* And last, enable the transmit and receive processing.
- */
- fecp->fec_ecntrl = 2;
- fecp->fec_r_des_active = 0;
+ /* And last, enable the transmit and receive processing */
+ writel(2, fep->hwp + FEC_ECNTRL);
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE);
- /* Enable interrupts we wish to service.
- */
- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
+ /* Enable interrupts we wish to service */
+ writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
+ fep->hwp + FEC_IMASK);
}
static void
fec_stop(struct net_device *dev)
{
- volatile fec_t *fecp;
- struct fec_enet_private *fep;
-
- fep = netdev_priv(dev);
- fecp = fep->hwp;
+ struct fec_enet_private *fep = netdev_priv(dev);
- /*
- ** We cannot expect a graceful transmit stop without link !!!
- */
- if (fep->link)
- {
- fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */
+ /* We cannot expect a graceful transmit stop without link !!! */
+ if (fep->link) {
+ writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
udelay(10);
- if (!(fecp->fec_ievent & FEC_ENET_GRA))
+ if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA))
printk("fec_stop : Graceful transmit stop did not complete !\n");
- }
+ }
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
+ /* Whack a reset. We should wait for this. */
+ writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
- /* Clear outstanding MII command interrupts.
- */
- fecp->fec_ievent = FEC_ENET_MII;
+ /* Clear outstanding MII command interrupts. */
+ writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
- fecp->fec_imask = FEC_ENET_MII;
- fecp->fec_mii_speed = fep->phy_speed;
+ writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
}
static int __devinit
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 76c64c92e190..30b7dd671336 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -20,82 +20,55 @@
* registers in the same peripheral device on different models
* of the ColdFire!
*/
-typedef struct fec {
- unsigned long fec_reserved0;
- unsigned long fec_ievent; /* Interrupt event reg */
- unsigned long fec_imask; /* Interrupt mask reg */
- unsigned long fec_reserved1;
- unsigned long fec_r_des_active; /* Receive descriptor reg */
- unsigned long fec_x_des_active; /* Transmit descriptor reg */
- unsigned long fec_reserved2[3];
- unsigned long fec_ecntrl; /* Ethernet control reg */
- unsigned long fec_reserved3[6];
- unsigned long fec_mii_data; /* MII manage frame reg */
- unsigned long fec_mii_speed; /* MII speed control reg */
- unsigned long fec_reserved4[7];
- unsigned long fec_mib_ctrlstat; /* MIB control/status reg */
- unsigned long fec_reserved5[7];
- unsigned long fec_r_cntrl; /* Receive control reg */
- unsigned long fec_reserved6[15];
- unsigned long fec_x_cntrl; /* Transmit Control reg */
- unsigned long fec_reserved7[7];
- unsigned long fec_addr_low; /* Low 32bits MAC address */
- unsigned long fec_addr_high; /* High 16bits MAC address */
- unsigned long fec_opd; /* Opcode + Pause duration */
- unsigned long fec_reserved8[10];
- unsigned long fec_hash_table_high; /* High 32bits hash table */
- unsigned long fec_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_grp_hash_table_high;/* High 32bits hash table */
- unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_reserved9[7];
- unsigned long fec_x_wmrk; /* FIFO transmit water mark */
- unsigned long fec_reserved10;
- unsigned long fec_r_bound; /* FIFO receive bound reg */
- unsigned long fec_r_fstart; /* FIFO receive start reg */
- unsigned long fec_reserved11[11];
- unsigned long fec_r_des_start; /* Receive descriptor ring */
- unsigned long fec_x_des_start; /* Transmit descriptor ring */
- unsigned long fec_r_buff_size; /* Maximum receive buff size */
-} fec_t;
+#define FEC_IEVENT 0x004 /* Interrupt event reg */
+#define FEC_IMASK 0x008 /* Interrupt mask reg */
+#define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */
+#define FEC_ECNTRL 0x024 /* Ethernet control reg */
+#define FEC_MII_DATA 0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED 0x044 /* MII speed control reg */
+#define FEC_MIB_CTRLSTAT 0x064 /* MIB control/status reg */
+#define FEC_R_CNTRL 0x084 /* Receive control reg */
+#define FEC_X_CNTRL 0x0c4 /* Transmit Control reg */
+#define FEC_ADDR_LOW 0x0e4 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH 0x0e8 /* High 16bits MAC address */
+#define FEC_OPD 0x0ec /* Opcode + Pause duration */
+#define FEC_HASH_TABLE_HIGH 0x118 /* High 32bits hash table */
+#define FEC_HASH_TABLE_LOW 0x11c /* Low 32bits hash table */
+#define FEC_GRP_HASH_TABLE_HIGH 0x120 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x124 /* Low 32bits hash table */
+#define FEC_X_WMRK 0x144 /* FIFO transmit water mark */
+#define FEC_R_BOUND 0x14c /* FIFO receive bound reg */
+#define FEC_R_FSTART 0x150 /* FIFO receive start reg */
+#define FEC_R_DES_START 0x180 /* Receive descriptor ring */
+#define FEC_X_DES_START 0x184 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */
#else
-/*
- * Define device register set address map.
- */
-typedef struct fec {
- unsigned long fec_ecntrl; /* Ethernet control reg */
- unsigned long fec_ievent; /* Interrupt even reg */
- unsigned long fec_imask; /* Interrupt mask reg */
- unsigned long fec_ivec; /* Interrupt vec status reg */
- unsigned long fec_r_des_active; /* Receive descriptor reg */
- unsigned long fec_x_des_active; /* Transmit descriptor reg */
- unsigned long fec_reserved1[10];
- unsigned long fec_mii_data; /* MII manage frame reg */
- unsigned long fec_mii_speed; /* MII speed control reg */
- unsigned long fec_reserved2[17];
- unsigned long fec_r_bound; /* FIFO receive bound reg */
- unsigned long fec_r_fstart; /* FIFO receive start reg */
- unsigned long fec_reserved3[4];
- unsigned long fec_x_wmrk; /* FIFO transmit water mark */
- unsigned long fec_reserved4;
- unsigned long fec_x_fstart; /* FIFO transmit start reg */
- unsigned long fec_reserved5[21];
- unsigned long fec_r_cntrl; /* Receive control reg */
- unsigned long fec_max_frm_len; /* Maximum frame length reg */
- unsigned long fec_reserved6[14];
- unsigned long fec_x_cntrl; /* Transmit Control reg */
- unsigned long fec_reserved7[158];
- unsigned long fec_addr_low; /* Low 32bits MAC address */
- unsigned long fec_addr_high; /* High 16bits MAC address */
- unsigned long fec_grp_hash_table_high;/* High 32bits hash table */
- unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_r_des_start; /* Receive descriptor ring */
- unsigned long fec_x_des_start; /* Transmit descriptor ring */
- unsigned long fec_r_buff_size; /* Maximum receive buff size */
- unsigned long reserved8[9];
- unsigned long fec_fifo_ram[112]; /* FIFO RAM buffer */
-} fec_t;
+#define FEC_ECNTRL; 0x000 /* Ethernet control reg */
+#define FEC_IEVENT; 0x004 /* Interrupt even reg */
+#define FEC_IMASK; 0x008 /* Interrupt mask reg */
+#define FEC_IVEC; 0x00c /* Interrupt vec status reg */
+#define FEC_R_DES_ACTIVE; 0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE; 0x01c /* Transmit descriptor reg */
+#define FEC_MII_DATA 0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED 0x044 /* MII speed control reg */
+#define FEC_R_BOUND 0x08c /* FIFO receive bound reg */
+#define FEC_R_FSTART 0x090 /* FIFO receive start reg */
+#define FEC_X_WMRK 0x0a4 /* FIFO transmit water mark */
+#define FEC_X_FSTART 0x0ac /* FIFO transmit start reg */
+#define FEC_R_CNTRL 0x104 /* Receive control reg */
+#define FEC_MAX_FRM_LEN 0x108 /* Maximum frame length reg */
+#define FEC_X_CNTRL 0x144 /* Transmit Control reg */
+#define FEC_ADDR_LOW 0x3c0 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH 0x3c4 /* High 16bits MAC address */
+#define FEC_GRP_HASH_TABLE_HIGH 0x3c8 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x3cc /* Low 32bits hash table */
+#define FEC_R_DES_START 0x3d0 /* Receive descriptor ring */
+#define FEC_X_DES_START 0x3d4 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE 0x3d8 /* Maximum receive buff size */
+#define FEC_FIFO_RAM 0x400 /* FIFO RAM buffer */
#endif /* CONFIG_M5272 */
@@ -104,17 +77,17 @@ typedef struct fec {
* Define the buffer descriptor structure.
*/
#ifdef CONFIG_ARCH_MXC
-typedef struct bufdesc {
+struct bufdesc {
unsigned short cbd_datlen; /* Data length */
unsigned short cbd_sc; /* Control and status info */
unsigned long cbd_bufaddr; /* Buffer address */
-} cbd_t;
+};
#else
-typedef struct bufdesc {
+struct bufdesc {
unsigned short cbd_sc; /* Control and status info */
unsigned short cbd_datlen; /* Data length */
unsigned long cbd_bufaddr; /* Buffer address */
-} cbd_t;
+};
#endif
/*
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index 8bbe7f617994..7d443405bbe2 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -25,6 +25,7 @@
#include <linux/hardirq.h>
#include <linux/delay.h>
#include <linux/of_device.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/netdevice.h>
@@ -43,11 +44,9 @@
#define DRIVER_NAME "mpc52xx-fec"
-#define FEC5200_PHYADDR_NONE (-1)
-#define FEC5200_PHYADDR_7WIRE (-2)
-
/* Private driver data structure */
struct mpc52xx_fec_priv {
+ struct net_device *ndev;
int duplex;
int speed;
int r_irq;
@@ -59,10 +58,11 @@ struct mpc52xx_fec_priv {
int msg_enable;
/* MDIO link details */
- int phy_addr;
- unsigned int phy_speed;
+ unsigned int mdio_speed;
+ struct device_node *phy_node;
struct phy_device *phydev;
enum phy_state link;
+ int seven_wire_mode;
};
@@ -211,85 +211,25 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
phy_print_status(phydev);
}
-static int mpc52xx_fec_init_phy(struct net_device *dev)
-{
- struct mpc52xx_fec_priv *priv = netdev_priv(dev);
- struct phy_device *phydev;
- char phy_id[BUS_ID_SIZE];
-
- snprintf(phy_id, sizeof(phy_id), "%x:%02x",
- (unsigned int)dev->base_addr, priv->phy_addr);
-
- priv->link = PHY_DOWN;
- priv->speed = 0;
- priv->duplex = -1;
-
- phydev = phy_connect(dev, phy_id, &mpc52xx_fec_adjust_link, 0, PHY_INTERFACE_MODE_MII);
- if (IS_ERR(phydev)) {
- dev_err(&dev->dev, "phy_connect failed\n");
- return PTR_ERR(phydev);
- }
- dev_info(&dev->dev, "attached phy %i to driver %s\n",
- phydev->addr, phydev->drv->name);
-
- priv->phydev = phydev;
-
- return 0;
-}
-
-static int mpc52xx_fec_phy_start(struct net_device *dev)
-{
- struct mpc52xx_fec_priv *priv = netdev_priv(dev);
- int err;
-
- if (priv->phy_addr < 0)
- return 0;
-
- err = mpc52xx_fec_init_phy(dev);
- if (err) {
- dev_err(&dev->dev, "mpc52xx_fec_init_phy failed\n");
- return err;
- }
-
- /* reset phy - this also wakes it from PDOWN */
- phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
- phy_start(priv->phydev);
-
- return 0;
-}
-
-static void mpc52xx_fec_phy_stop(struct net_device *dev)
-{
- struct mpc52xx_fec_priv *priv = netdev_priv(dev);
-
- if (!priv->phydev)
- return;
-
- phy_disconnect(priv->phydev);
- /* power down phy */
- phy_stop(priv->phydev);
- phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN);
-}
-
-static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv)
-{
- struct mpc52xx_fec __iomem *fec = priv->fec;
-
- if (priv->phydev)
- return;
-
- out_be32(&fec->mii_speed, priv->phy_speed);
-}
-
static int mpc52xx_fec_open(struct net_device *dev)
{
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
int err = -EBUSY;
+ if (priv->phy_node) {
+ priv->phydev = of_phy_connect(priv->ndev, priv->phy_node,
+ mpc52xx_fec_adjust_link, 0, 0);
+ if (!priv->phydev) {
+ dev_err(&dev->dev, "of_phy_connect failed\n");
+ return -ENODEV;
+ }
+ phy_start(priv->phydev);
+ }
+
if (request_irq(dev->irq, &mpc52xx_fec_interrupt, IRQF_SHARED,
DRIVER_NAME "_ctrl", dev)) {
dev_err(&dev->dev, "ctrl interrupt request failed\n");
- goto out;
+ goto free_phy;
}
if (request_irq(priv->r_irq, &mpc52xx_fec_rx_interrupt, 0,
DRIVER_NAME "_rx", dev)) {
@@ -311,10 +251,6 @@ static int mpc52xx_fec_open(struct net_device *dev)
goto free_irqs;
}
- err = mpc52xx_fec_phy_start(dev);
- if (err)
- goto free_skbs;
-
bcom_enable(priv->rx_dmatsk);
bcom_enable(priv->tx_dmatsk);
@@ -324,16 +260,18 @@ static int mpc52xx_fec_open(struct net_device *dev)
return 0;
- free_skbs:
- mpc52xx_fec_free_rx_buffers(dev, priv->rx_dmatsk);
-
free_irqs:
free_irq(priv->t_irq, dev);
free_2irqs:
free_irq(priv->r_irq, dev);
free_ctrl_irq:
free_irq(dev->irq, dev);
- out:
+ free_phy:
+ if (priv->phydev) {
+ phy_stop(priv->phydev);
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+ }
return err;
}
@@ -352,7 +290,12 @@ static int mpc52xx_fec_close(struct net_device *dev)
free_irq(priv->r_irq, dev);
free_irq(priv->t_irq, dev);
- mpc52xx_fec_phy_stop(dev);
+ if (priv->phydev) {
+ /* power down phy */
+ phy_stop(priv->phydev);
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+ }
return 0;
}
@@ -696,7 +639,7 @@ static void mpc52xx_fec_hw_init(struct net_device *dev)
/* set phy speed.
* this can't be done in phy driver, since it needs to be called
* before fec stuff (even on resume) */
- mpc52xx_fec_phy_hw_init(priv);
+ out_be32(&fec->mii_speed, priv->mdio_speed);
}
/**
@@ -732,7 +675,7 @@ static void mpc52xx_fec_start(struct net_device *dev)
rcntrl = FEC_RX_BUFFER_SIZE << 16; /* max frame length */
rcntrl |= FEC_RCNTRL_FCE;
- if (priv->phy_addr != FEC5200_PHYADDR_7WIRE)
+ if (!priv->seven_wire_mode)
rcntrl |= FEC_RCNTRL_MII_MODE;
if (priv->duplex == DUPLEX_FULL)
@@ -798,8 +741,6 @@ static void mpc52xx_fec_stop(struct net_device *dev)
/* Stop FEC */
out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) & ~FEC_ECNTRL_ETHER_EN);
-
- return;
}
/* reset fec and bestcomm tasks */
@@ -817,9 +758,11 @@ static void mpc52xx_fec_reset(struct net_device *dev)
mpc52xx_fec_hw_init(dev);
- phy_stop(priv->phydev);
- phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
- phy_start(priv->phydev);
+ if (priv->phydev) {
+ phy_stop(priv->phydev);
+ phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
+ phy_start(priv->phydev);
+ }
bcom_fec_rx_reset(priv->rx_dmatsk);
bcom_fec_tx_reset(priv->tx_dmatsk);
@@ -919,8 +862,6 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
struct net_device *ndev;
struct mpc52xx_fec_priv *priv = NULL;
struct resource mem;
- struct device_node *phy_node;
- const phandle *phy_handle;
const u32 *prop;
int prop_size;
@@ -933,6 +874,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
return -ENOMEM;
priv = netdev_priv(ndev);
+ priv->ndev = ndev;
/* Reserve FEC control zone */
rv = of_address_to_resource(op->node, 0, &mem);
@@ -956,6 +898,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
ndev->ethtool_ops = &mpc52xx_fec_ethtool_ops;
ndev->watchdog_timeo = FEC_WATCHDOG_TIMEOUT;
ndev->base_addr = mem.start;
+ SET_NETDEV_DEV(ndev, &op->dev);
spin_lock_init(&priv->lock);
@@ -1003,14 +946,9 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
*/
/* Start with safe defaults for link connection */
- priv->phy_addr = FEC5200_PHYADDR_NONE;
priv->speed = 100;
priv->duplex = DUPLEX_HALF;
- priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
-
- /* the 7-wire property means don't use MII mode */
- if (of_find_property(op->node, "fsl,7-wire-mode", NULL))
- priv->phy_addr = FEC5200_PHYADDR_7WIRE;
+ priv->mdio_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
/* The current speed preconfigures the speed of the MII link */
prop = of_get_property(op->node, "current-speed", &prop_size);
@@ -1019,43 +957,23 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF;
}
- /* If there is a phy handle, setup link to that phy */
- phy_handle = of_get_property(op->node, "phy-handle", &prop_size);
- if (phy_handle && (prop_size >= sizeof(phandle))) {
- phy_node = of_find_node_by_phandle(*phy_handle);
- prop = of_get_property(phy_node, "reg", &prop_size);
- if (prop && (prop_size >= sizeof(u32)))
- if ((*prop >= 0) && (*prop < PHY_MAX_ADDR))
- priv->phy_addr = *prop;
- of_node_put(phy_node);
+ /* If there is a phy handle, then get the PHY node */
+ priv->phy_node = of_parse_phandle(op->node, "phy-handle", 0);
+
+ /* the 7-wire property means don't use MII mode */
+ if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) {
+ priv->seven_wire_mode = 1;
+ dev_info(&ndev->dev, "using 7-wire PHY mode\n");
}
/* Hardware init */
mpc52xx_fec_hw_init(ndev);
-
mpc52xx_fec_reset_stats(ndev);
- SET_NETDEV_DEV(ndev, &op->dev);
-
- /* Register the new network device */
rv = register_netdev(ndev);
if (rv < 0)
goto probe_error;
- /* Now report the link setup */
- switch (priv->phy_addr) {
- case FEC5200_PHYADDR_NONE:
- dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n",
- priv->speed, priv->duplex ? 'F' : 'H');
- break;
- case FEC5200_PHYADDR_7WIRE:
- dev_info(&ndev->dev, "using 7-wire PHY mode\n");
- break;
- default:
- dev_info(&ndev->dev, "Using PHY at MDIO address %i\n",
- priv->phy_addr);
- }
-
/* We're done ! */
dev_set_drvdata(&op->dev, ndev);
@@ -1065,6 +983,10 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
/* Error handling - free everything that might be allocated */
probe_error:
+ if (priv->phy_node)
+ of_node_put(priv->phy_node);
+ priv->phy_node = NULL;
+
irq_dispose_mapping(ndev->irq);
if (priv->rx_dmatsk)
@@ -1093,6 +1015,10 @@ mpc52xx_fec_remove(struct of_device *op)
unregister_netdev(ndev);
+ if (priv->phy_node)
+ of_node_put(priv->phy_node);
+ priv->phy_node = NULL;
+
irq_dispose_mapping(ndev->irq);
bcom_fec_rx_release(priv->rx_dmatsk);
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index dd9bfa42ac34..fec9f245116b 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -14,12 +14,14 @@
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/of_platform.h>
+#include <linux/of_mdio.h>
#include <asm/io.h>
#include <asm/mpc52xx.h>
#include "fec_mpc52xx.h"
struct mpc52xx_fec_mdio_priv {
struct mpc52xx_fec __iomem *regs;
+ int mdio_irqs[PHY_MAX_ADDR];
};
static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
@@ -27,7 +29,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
{
struct mpc52xx_fec_mdio_priv *priv = bus->priv;
struct mpc52xx_fec __iomem *fec;
- int tries = 100;
+ int tries = 3;
value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
@@ -38,7 +40,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
/* wait for it to finish, this takes about 23 us on lite5200b */
while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
- udelay(5);
+ msleep(1);
if (!tries)
return -ETIMEDOUT;
@@ -64,7 +66,6 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
{
struct device *dev = &of->dev;
struct device_node *np = of->node;
- struct device_node *child = NULL;
struct mii_bus *bus;
struct mpc52xx_fec_mdio_priv *priv;
struct resource res = {};
@@ -85,22 +86,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
bus->write = mpc52xx_fec_mdio_write;
/* setup irqs */
- bus->irq = kmalloc(sizeof(bus->irq[0]) * PHY_MAX_ADDR, GFP_KERNEL);
- if (bus->irq == NULL) {
- err = -ENOMEM;
- goto out_free;
- }
- for (i=0; i<PHY_MAX_ADDR; i++)
- bus->irq[i] = PHY_POLL;
-
- while ((child = of_get_next_child(np, child)) != NULL) {
- int irq = irq_of_parse_and_map(child, 0);
- if (irq != NO_IRQ) {
- const u32 *id = of_get_property(child, "reg", NULL);
- if (id)
- bus->irq[*id] = irq;
- }
- }
+ bus->irq = priv->mdio_irqs;
/* setup registers */
err = of_address_to_resource(np, 0, &res);
@@ -122,7 +108,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
out_be32(&priv->regs->mii_speed,
((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
- err = mdiobus_register(bus);
+ err = of_mdiobus_register(bus, np);
if (err)
goto out_unmap;
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index f9a846b1b92f..d0b1d9f17a5d 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -343,6 +343,7 @@ enum {
#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F15
#define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001
#define NVREG_POWERSTATE2_PHY_RESET 0x0004
+#define NVREG_POWERSTATE2_GATE_CLOCKS 0x0F00
};
/* Big endian: should work, but is untested */
@@ -1017,6 +1018,23 @@ static int using_multi_irqs(struct net_device *dev)
return 1;
}
+static void nv_txrx_gate(struct net_device *dev, bool gate)
+{
+ struct fe_priv *np = get_nvpriv(dev);
+ u8 __iomem *base = get_hwbase(dev);
+ u32 powerstate;
+
+ if (!np->mac_in_use &&
+ (np->driver_data & DEV_HAS_POWER_CNTRL)) {
+ powerstate = readl(base + NvRegPowerState2);
+ if (gate)
+ powerstate |= NVREG_POWERSTATE2_GATE_CLOCKS;
+ else
+ powerstate &= ~NVREG_POWERSTATE2_GATE_CLOCKS;
+ writel(powerstate, base + NvRegPowerState2);
+ }
+}
+
static void nv_enable_irq(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
@@ -3394,12 +3412,14 @@ static void nv_linkchange(struct net_device *dev)
if (!netif_carrier_ok(dev)) {
netif_carrier_on(dev);
printk(KERN_INFO "%s: link up.\n", dev->name);
+ nv_txrx_gate(dev, false);
nv_start_rx(dev);
}
} else {
if (netif_carrier_ok(dev)) {
netif_carrier_off(dev);
printk(KERN_INFO "%s: link down.\n", dev->name);
+ nv_txrx_gate(dev, true);
nv_stop_rx(dev);
}
}
@@ -5327,6 +5347,7 @@ static int nv_open(struct net_device *dev)
mii_rw(dev, np->phyaddr, MII_BMCR,
mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ) & ~BMCR_PDOWN);
+ nv_txrx_gate(dev, false);
/* erase previous misconfiguration */
if (np->driver_data & DEV_HAS_POWER_CNTRL)
nv_mac_reset(dev);
@@ -5514,12 +5535,14 @@ static int nv_close(struct net_device *dev)
nv_drain_rxtx(dev);
if (np->wolenabled) {
+ nv_txrx_gate(dev, false);
writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags);
nv_start_rx(dev);
} else {
/* power down phy */
mii_rw(dev, np->phyaddr, MII_BMCR,
mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ)|BMCR_PDOWN);
+ nv_txrx_gate(dev, true);
}
/* FIXME: power down nic */
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index a9cbc3191a2a..b892c3ad9a74 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -36,6 +36,8 @@
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
@@ -752,9 +754,10 @@ static int fs_init_phy(struct net_device *dev)
fep->oldlink = 0;
fep->oldspeed = 0;
fep->oldduplex = -1;
- if(fep->fpi->bus_id)
- phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ if(fep->fpi->phy_node)
+ phydev = of_phy_connect(dev, fep->fpi->phy_node,
+ &fs_adjust_link, 0,
+ PHY_INTERFACE_MODE_MII);
else {
printk("No phy bus ID specified in BSP code\n");
return -EINVAL;
@@ -938,81 +941,6 @@ extern void fs_mii_disconnect(struct net_device *dev);
/**************************************************************************************/
-/* handy pointer to the immap */
-void __iomem *fs_enet_immap = NULL;
-
-static int setup_immap(void)
-{
-#ifdef CONFIG_CPM1
- fs_enet_immap = ioremap(IMAP_ADDR, 0x4000);
- WARN_ON(!fs_enet_immap);
-#elif defined(CONFIG_CPM2)
- fs_enet_immap = cpm2_immr;
-#endif
-
- return 0;
-}
-
-static void cleanup_immap(void)
-{
-#if defined(CONFIG_CPM1)
- iounmap(fs_enet_immap);
-#endif
-}
-
-/**************************************************************************************/
-
-static int __devinit find_phy(struct device_node *np,
- struct fs_platform_info *fpi)
-{
- struct device_node *phynode, *mdionode;
- int ret = 0, len, bus_id;
- const u32 *data;
-
- data = of_get_property(np, "fixed-link", NULL);
- if (data) {
- snprintf(fpi->bus_id, 16, "%x:%02x", 0, *data);
- return 0;
- }
-
- data = of_get_property(np, "phy-handle", &len);
- if (!data || len != 4)
- return -EINVAL;
-
- phynode = of_find_node_by_phandle(*data);
- if (!phynode)
- return -EINVAL;
-
- data = of_get_property(phynode, "reg", &len);
- if (!data || len != 4) {
- ret = -EINVAL;
- goto out_put_phy;
- }
-
- mdionode = of_get_parent(phynode);
- if (!mdionode) {
- ret = -EINVAL;
- goto out_put_phy;
- }
-
- bus_id = of_get_gpio(mdionode, 0);
- if (bus_id < 0) {
- struct resource res;
- ret = of_address_to_resource(mdionode, 0, &res);
- if (ret)
- goto out_put_mdio;
- bus_id = res.start;
- }
-
- snprintf(fpi->bus_id, 16, "%x:%02x", bus_id, *data);
-
-out_put_mdio:
- of_node_put(mdionode);
-out_put_phy:
- of_node_put(phynode);
- return ret;
-}
-
#ifdef CONFIG_FS_ENET_HAS_FEC
#define IS_FEC(match) ((match)->data == &fs_fec_ops)
#else
@@ -1062,9 +990,9 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
fpi->rx_copybreak = 240;
fpi->use_napi = 1;
fpi->napi_weight = 17;
-
- ret = find_phy(ofdev->node, fpi);
- if (ret)
+ fpi->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0);
+ if ((!fpi->phy_node) && (!of_get_property(ofdev->node, "fixed-link",
+ NULL)))
goto out_free_fpi;
privsize = sizeof(*fep) +
@@ -1136,6 +1064,7 @@ out_cleanup_data:
out_free_dev:
free_netdev(ndev);
dev_set_drvdata(&ofdev->dev, NULL);
+ of_node_put(fpi->phy_node);
out_free_fpi:
kfree(fpi);
return ret;
@@ -1151,7 +1080,7 @@ static int fs_enet_remove(struct of_device *ofdev)
fep->ops->free_bd(ndev);
fep->ops->cleanup_data(ndev);
dev_set_drvdata(fep->dev, NULL);
-
+ of_node_put(fep->fpi->phy_node);
free_netdev(ndev);
return 0;
}
@@ -1191,25 +1120,12 @@ static struct of_platform_driver fs_enet_driver = {
static int __init fs_init(void)
{
- int r = setup_immap();
- if (r != 0)
- return r;
-
- r = of_register_platform_driver(&fs_enet_driver);
- if (r != 0)
- goto out;
-
- return 0;
-
-out:
- cleanup_immap();
- return r;
+ return of_register_platform_driver(&fs_enet_driver);
}
static void __exit fs_cleanup(void)
{
of_unregister_platform_driver(&fs_enet_driver);
- cleanup_immap();
}
#ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 85a4bab7f630..ef01e09781a5 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -194,9 +194,4 @@ extern const struct fs_ops fs_scc_ops;
/*******************************************************************/
-/* handy pointer to the immap */
-extern void __iomem *fs_enet_immap;
-
-/*******************************************************************/
-
#endif
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 14e575313c89..ca7bcb8ab3a1 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -245,10 +245,6 @@ static void set_multicast_list(struct net_device *dev)
static void restart(struct net_device *dev)
{
-#ifdef CONFIG_DUET
- immap_t *immap = fs_enet_immap;
- u32 cptr;
-#endif
struct fs_enet_private *fep = netdev_priv(dev);
fec_t __iomem *fecp = fep->fec.fecp;
const struct fs_platform_info *fpi = fep->fpi;
@@ -315,36 +311,6 @@ static void restart(struct net_device *dev)
FW(fecp, ievent, 0xffc0);
FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29);
- /*
- * adjust to speed (only for DUET & RMII)
- */
-#ifdef CONFIG_DUET
- if (fpi->use_rmii) {
- cptr = in_be32(&immap->im_cpm.cp_cptr);
- switch (fs_get_fec_index(fpi->fs_no)) {
- case 0:
- cptr |= 0x100;
- if (fep->speed == 10)
- cptr |= 0x0000010;
- else if (fep->speed == 100)
- cptr &= ~0x0000010;
- break;
- case 1:
- cptr |= 0x80;
- if (fep->speed == 10)
- cptr |= 0x0000008;
- else if (fep->speed == 100)
- cptr &= ~0x0000008;
- break;
- default:
- BUG(); /* should never happen */
- break;
- }
- out_be32(&immap->im_cpm.cp_cptr, cptr);
- }
-#endif
-
-
FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
/*
* adjust to duplex mode
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
index 49b6645d7e0c..93b481b0e3c7 100644
--- a/drivers/net/fs_enet/mii-bitbang.c
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -22,6 +22,7 @@
#include <linux/mii.h>
#include <linux/platform_device.h>
#include <linux/mdio-bitbang.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include "fs_enet.h"
@@ -149,31 +150,12 @@ static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
return 0;
}
-static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
-{
- const u32 *data;
- int len, id, irq;
-
- data = of_get_property(np, "reg", &len);
- if (!data || len != 4)
- return;
-
- id = *data;
- bus->phy_mask &= ~(1 << id);
-
- irq = of_irq_to_resource(np, 0, NULL);
- if (irq != NO_IRQ)
- bus->irq[id] = irq;
-}
-
static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
- struct device_node *np = NULL;
struct mii_bus *new_bus;
struct bb_info *bitbang;
int ret = -ENOMEM;
- int i;
bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
if (!bitbang)
@@ -196,17 +178,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
if (!new_bus->irq)
goto out_unmap_regs;
- for (i = 0; i < PHY_MAX_ADDR; i++)
- new_bus->irq[i] = -1;
-
- while ((np = of_get_next_child(ofdev->node, np)))
- if (!strcmp(np->type, "ethernet-phy"))
- add_phy(new_bus, np);
-
new_bus->parent = &ofdev->dev;
dev_set_drvdata(&ofdev->dev, new_bus);
- ret = mdiobus_register(new_bus);
+ ret = of_mdiobus_register(new_bus, ofdev->node);
if (ret)
goto out_free_irqs;
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 28077cc1b949..75a09994d665 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -54,8 +54,7 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
fec_t __iomem *fecp = fec->fecp;
int i, ret = -1;
- if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
- BUG();
+ BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
/* Add PHY address to register command. */
out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_read(location));
@@ -79,8 +78,7 @@ static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location,
int i;
/* this must never happen */
- if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
- BUG();
+ BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
/* Add PHY address to register command. */
out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_write(location, val));
@@ -102,23 +100,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
return 0;
}
-static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
-{
- const u32 *data;
- int len, id, irq;
-
- data = of_get_property(np, "reg", &len);
- if (!data || len != 4)
- return;
-
- id = *data;
- bus->phy_mask &= ~(1 << id);
-
- irq = of_irq_to_resource(np, 0, NULL);
- if (irq != NO_IRQ)
- bus->irq[id] = irq;
-}
-
static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
@@ -165,17 +146,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
if (!new_bus->irq)
goto out_unmap_regs;
- for (i = 0; i < PHY_MAX_ADDR; i++)
- new_bus->irq[i] = -1;
-
- while ((np = of_get_next_child(ofdev->node, np)))
- if (!strcmp(np->type, "ethernet-phy"))
- add_phy(new_bus, np);
-
new_bus->parent = &ofdev->dev;
dev_set_drvdata(&ofdev->dev, new_bus);
- ret = mdiobus_register(new_bus);
+ ret = of_mdiobus_register(new_bus, ofdev->node);
if (ret)
goto out_free_irqs;
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c
index aa1eb88c21fc..d12e0e0336f4 100644
--- a/drivers/net/fsl_pq_mdio.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -34,6 +34,7 @@
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/of.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <asm/io.h>
@@ -154,44 +155,6 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus)
return 0;
}
-/* Allocate an array which provides irq #s for each PHY on the given bus */
-static int *create_irq_map(struct device_node *np)
-{
- int *irqs;
- int i;
- struct device_node *child = NULL;
-
- irqs = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
-
- if (!irqs)
- return NULL;
-
- for (i = 0; i < PHY_MAX_ADDR; i++)
- irqs[i] = PHY_POLL;
-
- while ((child = of_get_next_child(np, child)) != NULL) {
- int irq = irq_of_parse_and_map(child, 0);
- const u32 *id;
-
- if (irq == NO_IRQ)
- continue;
-
- id = of_get_property(child, "reg", NULL);
-
- if (!id)
- continue;
-
- if (*id < PHY_MAX_ADDR && *id >= 0)
- irqs[*id] = irq;
- else
- printk(KERN_WARNING "%s: "
- "%d is not a valid PHY address\n",
- np->full_name, *id);
- }
-
- return irqs;
-}
-
void fsl_pq_mdio_bus_name(char *name, struct device_node *np)
{
const u32 *addr;
@@ -315,7 +278,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
new_bus->priv = (void __force *)regs;
- new_bus->irq = create_irq_map(np);
+ new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
if (NULL == new_bus->irq) {
err = -ENOMEM;
@@ -384,15 +347,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
out_be32(tbipa, tbiaddr);
- /*
- * The TBIPHY-only buses will find PHYs at every address,
- * so we mask them all but the TBI
- */
- if (of_device_is_compatible(np, "fsl,gianfar-tbi"))
- new_bus->phy_mask = ~(1 << tbiaddr);
-
- err = mdiobus_register(new_bus);
-
+ err = of_mdiobus_register(new_bus, np);
if (err) {
printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
new_bus->name);
@@ -460,10 +415,10 @@ int __init fsl_pq_mdio_init(void)
{
return of_register_platform_driver(&fsl_pq_mdio_driver);
}
+module_init(fsl_pq_mdio_init);
void fsl_pq_mdio_exit(void)
{
of_unregister_platform_driver(&fsl_pq_mdio_driver);
}
-subsys_initcall_sync(fsl_pq_mdio_init);
module_exit(fsl_pq_mdio_exit);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index b2c49679bba7..2bb038b98cc4 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -75,6 +75,7 @@
#include <linux/if_vlan.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/ip.h>
#include <linux/tcp.h>
@@ -168,17 +169,13 @@ static inline int gfar_uses_fcb(struct gfar_private *priv)
static int gfar_of_init(struct net_device *dev)
{
- struct device_node *phy, *mdio;
- const unsigned int *id;
const char *model;
const char *ctype;
const void *mac_addr;
- const phandle *ph;
u64 addr, size;
int err = 0;
struct gfar_private *priv = netdev_priv(dev);
struct device_node *np = priv->node;
- char bus_name[MII_BUS_ID_SIZE];
const u32 *stash;
const u32 *stash_len;
const u32 *stash_idx;
@@ -264,8 +261,8 @@ static int gfar_of_init(struct net_device *dev)
if (of_get_property(np, "fsl,magic-packet", NULL))
priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
- ph = of_get_property(np, "phy-handle", NULL);
- if (ph == NULL) {
+ priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
+ if (!priv->phy_node) {
u32 *fixed_link;
fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL);
@@ -273,57 +270,10 @@ static int gfar_of_init(struct net_device *dev)
err = -ENODEV;
goto err_out;
}
-
- snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id),
- PHY_ID_FMT, "0", fixed_link[0]);
- } else {
- phy = of_find_node_by_phandle(*ph);
-
- if (phy == NULL) {
- err = -ENODEV;
- goto err_out;
- }
-
- mdio = of_get_parent(phy);
-
- id = of_get_property(phy, "reg", NULL);
-
- of_node_put(phy);
-
- fsl_pq_mdio_bus_name(bus_name, mdio);
- of_node_put(mdio);
- snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
- bus_name, *id);
}
/* Find the TBI PHY. If it's not there, we don't support SGMII */
- ph = of_get_property(np, "tbi-handle", NULL);
- if (ph) {
- struct device_node *tbi = of_find_node_by_phandle(*ph);
- struct of_device *ofdev;
- struct mii_bus *bus;
-
- if (!tbi)
- return 0;
-
- mdio = of_get_parent(tbi);
- if (!mdio)
- return 0;
-
- ofdev = of_find_device_by_node(mdio);
-
- of_node_put(mdio);
-
- id = of_get_property(tbi, "reg", NULL);
- if (!id)
- return 0;
-
- of_node_put(tbi);
-
- bus = dev_get_drvdata(&ofdev->dev);
-
- priv->tbiphy = bus->phy_map[*id];
- }
+ priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
return 0;
@@ -529,6 +479,10 @@ static int gfar_probe(struct of_device *ofdev,
register_fail:
iounmap(priv->regs);
regs_fail:
+ if (priv->phy_node)
+ of_node_put(priv->phy_node);
+ if (priv->tbi_node)
+ of_node_put(priv->tbi_node);
free_netdev(dev);
return err;
}
@@ -537,6 +491,11 @@ static int gfar_remove(struct of_device *ofdev)
{
struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
+ if (priv->phy_node)
+ of_node_put(priv->phy_node);
+ if (priv->tbi_node)
+ of_node_put(priv->tbi_node);
+
dev_set_drvdata(&ofdev->dev, NULL);
iounmap(priv->regs);
@@ -690,7 +649,6 @@ static int init_phy(struct net_device *dev)
uint gigabit_support =
priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
SUPPORTED_1000baseT_Full : 0;
- struct phy_device *phydev;
phy_interface_t interface;
priv->oldlink = 0;
@@ -699,21 +657,21 @@ static int init_phy(struct net_device *dev)
interface = gfar_get_interface(dev);
- phydev = phy_connect(dev, priv->phy_bus_id, &adjust_link, 0, interface);
+ if (priv->phy_node) {
+ priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link,
+ 0, interface);
+ if (!priv->phydev) {
+ dev_err(&dev->dev, "error: Could not attach to PHY\n");
+ return -ENODEV;
+ }
+ }
if (interface == PHY_INTERFACE_MODE_SGMII)
gfar_configure_serdes(dev);
- if (IS_ERR(phydev)) {
- printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
- return PTR_ERR(phydev);
- }
-
/* Remove any features not supported by the controller */
- phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
- phydev->advertising = phydev->supported;
-
- priv->phydev = phydev;
+ priv->phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
+ priv->phydev->advertising = priv->phydev->supported;
return 0;
}
@@ -730,10 +688,17 @@ static int init_phy(struct net_device *dev)
static void gfar_configure_serdes(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
+ struct phy_device *tbiphy;
- if (!priv->tbiphy) {
- printk(KERN_WARNING "SGMII mode requires that the device "
- "tree specify a tbi-handle\n");
+ if (!priv->tbi_node) {
+ dev_warn(&dev->dev, "error: SGMII mode requires that the "
+ "device tree specify a tbi-handle\n");
+ return;
+ }
+
+ tbiphy = of_phy_find_device(priv->tbi_node);
+ if (!tbiphy) {
+ dev_err(&dev->dev, "error: Could not get TBI device\n");
return;
}
@@ -743,17 +708,17 @@ static void gfar_configure_serdes(struct net_device *dev)
* everything for us? Resetting it takes the link down and requires
* several seconds for it to come back.
*/
- if (phy_read(priv->tbiphy, MII_BMSR) & BMSR_LSTATUS)
+ if (phy_read(tbiphy, MII_BMSR) & BMSR_LSTATUS)
return;
/* Single clk mode, mii mode off(for serdes communication) */
- phy_write(priv->tbiphy, MII_TBICON, TBICON_CLK_SELECT);
+ phy_write(tbiphy, MII_TBICON, TBICON_CLK_SELECT);
- phy_write(priv->tbiphy, MII_ADVERTISE,
+ phy_write(tbiphy, MII_ADVERTISE,
ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE |
ADVERTISE_1000XPSE_ASYM);
- phy_write(priv->tbiphy, MII_BMCR, BMCR_ANENABLE |
+ phy_write(tbiphy, MII_BMCR, BMCR_ANENABLE |
BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000);
}
@@ -1242,7 +1207,8 @@ static int gfar_enet_open(struct net_device *dev)
static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb)
{
struct txfcb *fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN);
- cacheable_memzero(fcb, GMAC_FCB_LEN);
+
+ memset(fcb, 0, GMAC_FCB_LEN);
return fcb;
}
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 0642d52aef5c..91317bc11154 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -779,7 +779,8 @@ struct gfar_private {
spinlock_t bflock;
phy_interface_t interface;
- char phy_bus_id[BUS_ID_SIZE];
+ struct device_node *phy_node;
+ struct device_node *tbi_node;
u32 device_flags;
unsigned char rx_csum_enable:1,
extended_hash:1,
@@ -793,7 +794,6 @@ struct gfar_private {
/* PHY stuff */
struct phy_device *phydev;
- struct phy_device *tbiphy;
struct mii_bus *mii_bus;
int oldspeed;
int oldduplex;
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index de3f49f991a3..8feda9fe8297 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -2864,7 +2864,7 @@ static int __init hp100_eisa_probe (struct device *gendev)
printk("hp100: %s: EISA adapter found at 0x%x\n", dev->name,
dev->base_addr);
#endif
- gendev->driver_data = dev;
+ dev_set_drvdata(gendev, dev);
return 0;
out1:
free_netdev(dev);
@@ -2873,7 +2873,7 @@ static int __init hp100_eisa_probe (struct device *gendev)
static int __devexit hp100_eisa_remove (struct device *gendev)
{
- struct net_device *dev = gendev->driver_data;
+ struct net_device *dev = dev_get_drvdata(gendev);
cleanup_dev(dev);
return 0;
}
diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c
index 2e802634d366..3e3528ade259 100644
--- a/drivers/net/hplance.c
+++ b/drivers/net/hplance.c
@@ -71,6 +71,19 @@ static struct dio_driver hplance_driver = {
.remove = __devexit_p(hplance_remove_one),
};
+static const struct net_device_ops hplance_netdev_ops = {
+ .ndo_open = hplance_open,
+ .ndo_stop = hplance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_multicast_list = lance_set_multicast,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = lance_poll,
+#endif
+};
+
/* Find all the HP Lance boards and initialise them... */
static int __devinit hplance_init_one(struct dio_dev *d,
const struct dio_device_id *ent)
@@ -135,13 +148,7 @@ static void __init hplance_init(struct net_device *dev, struct dio_dev *d)
/* Fill the dev fields */
dev->base_addr = va;
- dev->open = &hplance_open;
- dev->stop = &hplance_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = lance_poll;
-#endif
- dev->hard_start_xmit = &lance_start_xmit;
- dev->set_multicast_list = &lance_set_multicast;
+ dev->netdev_ops = &hplance_netdev_ops;
dev->dma = 0;
for (i=0; i<6; i++) {
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 5c6315df86b9..0995c438f286 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1203,6 +1203,20 @@ static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev)
return ret;
}
+static const struct net_device_ops ibmveth_netdev_ops = {
+ .ndo_open = ibmveth_open,
+ .ndo_stop = ibmveth_close,
+ .ndo_start_xmit = ibmveth_start_xmit,
+ .ndo_set_multicast_list = ibmveth_set_multicast_list,
+ .ndo_do_ioctl = ibmveth_ioctl,
+ .ndo_change_mtu = ibmveth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ibmveth_poll_controller,
+#endif
+};
+
static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
{
int rc, i;
@@ -1241,7 +1255,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
return -ENOMEM;
adapter = netdev_priv(netdev);
- dev->dev.driver_data = netdev;
+ dev_set_drvdata(&dev->dev, netdev);
adapter->vdev = dev;
adapter->netdev = netdev;
@@ -1265,21 +1279,13 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
memcpy(&adapter->mac_addr, mac_addr_p, 6);
netdev->irq = dev->irq;
- netdev->open = ibmveth_open;
- netdev->stop = ibmveth_close;
- netdev->hard_start_xmit = ibmveth_start_xmit;
- netdev->set_multicast_list = ibmveth_set_multicast_list;
- netdev->do_ioctl = ibmveth_ioctl;
- netdev->ethtool_ops = &netdev_ethtool_ops;
- netdev->change_mtu = ibmveth_change_mtu;
+ netdev->netdev_ops = &ibmveth_netdev_ops;
+ netdev->ethtool_ops = &netdev_ethtool_ops;
SET_NETDEV_DEV(netdev, &dev->dev);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = ibmveth_poll_controller;
-#endif
netdev->features |= NETIF_F_LLTX;
spin_lock_init(&adapter->stats_lock);
- memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
+ memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
for(i = 0; i<IbmVethNumBufferPools; i++) {
struct kobject *kobj = &adapter->rx_buff_pool[i].kobj;
@@ -1335,7 +1341,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
static int __devexit ibmveth_remove(struct vio_dev *dev)
{
- struct net_device *netdev = dev->dev.driver_data;
+ struct net_device *netdev = dev_get_drvdata(&dev->dev);
struct ibmveth_adapter *adapter = netdev_priv(netdev);
int i;
@@ -1368,8 +1374,8 @@ static void ibmveth_proc_unregister_driver(void)
static int ibmveth_show(struct seq_file *seq, void *v)
{
struct ibmveth_adapter *adapter = seq->private;
- char *current_mac = ((char*) &adapter->netdev->dev_addr);
- char *firmware_mac = ((char*) &adapter->mac_addr) ;
+ char *current_mac = (char *) adapter->netdev->dev_addr;
+ char *firmware_mac = (char *) &adapter->mac_addr;
seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
@@ -1468,8 +1474,8 @@ const char * buf, size_t count)
struct ibmveth_buff_pool *pool = container_of(kobj,
struct ibmveth_buff_pool,
kobj);
- struct net_device *netdev =
- container_of(kobj->parent, struct device, kobj)->driver_data;
+ struct net_device *netdev = dev_get_drvdata(
+ container_of(kobj->parent, struct device, kobj));
struct ibmveth_adapter *adapter = netdev_priv(netdev);
long value = simple_strtol(buf, NULL, 10);
long rc;
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index eaf977050368..0f16abab2565 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -130,6 +130,7 @@ struct e1000_adv_tx_context_desc {
#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
+#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 packet TYPE of SCTP */
/* IPSec Encrypt Enable for ESP */
#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index ad2d319d0f8b..3bda3db73f1f 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -289,8 +289,9 @@
#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
/* Receive Checksum Control */
+#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */
#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
-#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
+#define E1000_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
/* Header split receive */
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c
index 840782fb5736..ed9058eca45c 100644
--- a/drivers/net/igb/e1000_mbx.c
+++ b/drivers/net/igb/e1000_mbx.c
@@ -140,13 +140,13 @@ static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
struct e1000_mbx_info *mbx = &hw->mbx;
int countdown = mbx->timeout;
- if (!mbx->ops.check_for_msg)
+ if (!countdown || !mbx->ops.check_for_msg)
goto out;
while (mbx->ops.check_for_msg(hw, mbx_id)) {
+ countdown--;
if (!countdown)
break;
- countdown--;
udelay(mbx->usec_delay);
}
out:
@@ -165,13 +165,13 @@ static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
struct e1000_mbx_info *mbx = &hw->mbx;
int countdown = mbx->timeout;
- if (!mbx->ops.check_for_ack)
+ if (!countdown || !mbx->ops.check_for_ack)
goto out;
while (mbx->ops.check_for_ack(hw, mbx_id)) {
+ countdown--;
if (!countdown)
break;
- countdown--;
udelay(mbx->usec_delay);
}
out:
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 4e8464b9df2e..154c5acc6fce 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -238,7 +238,6 @@ struct igb_adapter {
u64 hw_csum_err;
u64 hw_csum_good;
u32 alloc_rx_buff_failed;
- bool rx_csum;
u32 gorc;
u64 gorc_old;
u16 rx_ps_hdr_size;
@@ -286,6 +285,7 @@ struct igb_adapter {
#define IGB_FLAG_DCA_ENABLED (1 << 1)
#define IGB_FLAG_QUAD_PORT_A (1 << 2)
#define IGB_FLAG_NEED_CTX_IDX (1 << 3)
+#define IGB_FLAG_RX_CSUM_DISABLED (1 << 4)
enum e1000_state_t {
__IGB_TESTING,
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 27eae49e79c2..b8551a57dd3f 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -275,13 +275,17 @@ static int igb_set_pauseparam(struct net_device *netdev,
static u32 igb_get_rx_csum(struct net_device *netdev)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- return adapter->rx_csum;
+ return !(adapter->flags & IGB_FLAG_RX_CSUM_DISABLED);
}
static int igb_set_rx_csum(struct net_device *netdev, u32 data)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- adapter->rx_csum = data;
+
+ if (data)
+ adapter->flags &= ~IGB_FLAG_RX_CSUM_DISABLED;
+ else
+ adapter->flags |= IGB_FLAG_RX_CSUM_DISABLED;
return 0;
}
@@ -293,10 +297,16 @@ static u32 igb_get_tx_csum(struct net_device *netdev)
static int igb_set_tx_csum(struct net_device *netdev, u32 data)
{
- if (data)
+ struct igb_adapter *adapter = netdev_priv(netdev);
+
+ if (data) {
netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
- else
- netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+ if (adapter->hw.mac.type == e1000_82576)
+ netdev->features |= NETIF_F_SCTP_CSUM;
+ } else {
+ netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_SCTP_CSUM);
+ }
return 0;
}
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 08c801490c72..ffd731539997 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -942,6 +942,8 @@ int igb_up(struct igb_adapter *adapter)
rd32(E1000_ICR);
igb_irq_enable(adapter);
+ netif_tx_start_all_queues(adapter->netdev);
+
/* Fire a link change interrupt to start the watchdog. */
wr32(E1000_ICS, E1000_ICS_LSC);
return 0;
@@ -1343,6 +1345,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
+ if (adapter->hw.mac.type == e1000_82576)
+ netdev->features |= NETIF_F_SCTP_CSUM;
+
adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw);
/* before reading the NVM, reset the controller to put the device in a
@@ -1390,8 +1395,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
igb_validate_mdi_setting(hw);
- adapter->rx_csum = 1;
-
/* Initial Wake on LAN setting If APM wake is enabled in the EEPROM,
* enable the ACPI Magic Packet filter
*/
@@ -1442,15 +1445,14 @@ static int __devinit igb_probe(struct pci_dev *pdev,
* driver. */
igb_get_hw_control(adapter);
- /* tell the stack to leave us alone until igb_open() is called */
- netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
-
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
+ /* carrier off reporting is important to ethtool even BEFORE open */
+ netif_carrier_off(netdev);
+
#ifdef CONFIG_IGB_DCA
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IGB_FLAG_DCA_ENABLED;
@@ -1699,6 +1701,8 @@ static int igb_open(struct net_device *netdev)
if (test_bit(__IGB_TESTING, &adapter->state))
return -EBUSY;
+ netif_carrier_off(netdev);
+
/* allocate transmit descriptors */
err = igb_setup_all_tx_resources(adapter);
if (err)
@@ -2006,7 +2010,7 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
u32 rctl;
u32 srrctl = 0;
- int i, j;
+ int i;
rctl = rd32(E1000_RCTL);
@@ -2071,8 +2075,6 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
if (adapter->vfs_allocated_count) {
u32 vmolr;
- j = adapter->rx_ring[0].reg_idx;
-
/* set all queue drop enable bits */
wr32(E1000_QDE, ALL_QUEUES);
srrctl |= E1000_SRRCTL_DROP_EN;
@@ -2080,16 +2082,16 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
/* disable queue 0 to prevent tail write w/o re-config */
wr32(E1000_RXDCTL(0), 0);
- vmolr = rd32(E1000_VMOLR(j));
+ vmolr = rd32(E1000_VMOLR(adapter->vfs_allocated_count));
if (rctl & E1000_RCTL_LPE)
vmolr |= E1000_VMOLR_LPE;
- if (adapter->num_rx_queues > 0)
+ if (adapter->num_rx_queues > 1)
vmolr |= E1000_VMOLR_RSSE;
- wr32(E1000_VMOLR(j), vmolr);
+ wr32(E1000_VMOLR(adapter->vfs_allocated_count), vmolr);
}
for (i = 0; i < adapter->num_rx_queues; i++) {
- j = adapter->rx_ring[i].reg_idx;
+ int j = adapter->rx_ring[i].reg_idx;
wr32(E1000_SRRCTL(j), srrctl);
}
@@ -2233,29 +2235,24 @@ static void igb_configure_rx(struct igb_adapter *adapter)
mrqc |= (E1000_MRQC_RSS_FIELD_IPV6_UDP_EX |
E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
-
wr32(E1000_MRQC, mrqc);
-
- /* Multiqueue and raw packet checksumming are mutually
- * exclusive. Note that this not the same as TCP/IP
- * checksumming, which works fine. */
- rxcsum = rd32(E1000_RXCSUM);
- rxcsum |= E1000_RXCSUM_PCSD;
- wr32(E1000_RXCSUM, rxcsum);
- } else {
+ } else if (adapter->vfs_allocated_count) {
/* Enable multi-queue for sr-iov */
- if (adapter->vfs_allocated_count)
- wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ);
- /* Enable Receive Checksum Offload for TCP and UDP */
- rxcsum = rd32(E1000_RXCSUM);
- if (adapter->rx_csum)
- rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE;
- else
- rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE);
-
- wr32(E1000_RXCSUM, rxcsum);
+ wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ);
}
+ /* Enable Receive Checksum Offload for TCP and UDP */
+ rxcsum = rd32(E1000_RXCSUM);
+ /* Disable raw packet checksumming */
+ rxcsum |= E1000_RXCSUM_PCSD;
+
+ if (adapter->hw.mac.type == e1000_82576)
+ /* Enable Receive Checksum Offload for SCTP */
+ rxcsum |= E1000_RXCSUM_CRCOFL;
+
+ /* Don't need to set TUOFL or IPOFL, they default to 1 */
+ wr32(E1000_RXCSUM, rxcsum);
+
/* Set the default pool for the PF's first queue */
igb_configure_vt_default_pool(adapter);
@@ -2663,7 +2660,6 @@ static void igb_watchdog_task(struct work_struct *work)
}
netif_carrier_on(netdev);
- netif_tx_wake_all_queues(netdev);
igb_ping_all_vfs(adapter);
@@ -2680,7 +2676,6 @@ static void igb_watchdog_task(struct work_struct *work)
printk(KERN_INFO "igb: %s NIC Link is Down\n",
netdev->name);
netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
igb_ping_all_vfs(adapter);
@@ -2714,6 +2709,8 @@ link_up:
* (Do the reset outside of interrupt context). */
adapter->tx_timeout_count++;
schedule_work(&adapter->reset_task);
+ /* return immediately since reset is imminent */
+ return;
}
}
@@ -2897,13 +2894,13 @@ static void igb_set_itr(struct igb_adapter *adapter)
switch (current_itr) {
/* counts and packets in update_itr are dependent on these numbers */
case lowest_latency:
- new_itr = 70000;
+ new_itr = 56; /* aka 70,000 ints/sec */
break;
case low_latency:
- new_itr = 20000; /* aka hwitr = ~200 */
+ new_itr = 196; /* aka 20,000 ints/sec */
break;
case bulk_latency:
- new_itr = 4000;
+ new_itr = 980; /* aka 4,000 ints/sec */
break;
default:
break;
@@ -2922,7 +2919,8 @@ set_itr_now:
* by adding intermediate steps when interrupt rate is
* increasing */
new_itr = new_itr > adapter->itr ?
- min(adapter->itr + (new_itr >> 2), new_itr) :
+ max((new_itr * adapter->itr) /
+ (new_itr + (adapter->itr >> 2)), new_itr) :
new_itr;
/* Don't write the value here; it resets the adapter's
* internal timer, and causes us to delay far longer than
@@ -2931,7 +2929,7 @@ set_itr_now:
* ends up being correct.
*/
adapter->itr = new_itr;
- adapter->rx_ring->itr_val = 1000000000 / (new_itr * 256);
+ adapter->rx_ring->itr_val = new_itr;
adapter->rx_ring->set_itr = 1;
}
@@ -3070,11 +3068,15 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+ else if (ip_hdr(skb)->protocol == IPPROTO_SCTP)
+ tu_cmd |= E1000_ADVTXD_TUCMD_L4T_SCTP;
break;
case cpu_to_be16(ETH_P_IPV6):
/* XXX what about other V6 headers?? */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+ else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP)
+ tu_cmd |= E1000_ADVTXD_TUCMD_L4T_SCTP;
break;
default:
if (unlikely(net_ratelimit()))
@@ -4436,20 +4438,12 @@ static void igb_receive_skb(struct igb_ring *ring, u8 status,
bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP));
skb_record_rx_queue(skb, ring->queue_index);
- if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
- if (vlan_extracted)
- vlan_gro_receive(&ring->napi, adapter->vlgrp,
- le16_to_cpu(rx_desc->wb.upper.vlan),
- skb);
- else
- napi_gro_receive(&ring->napi, skb);
- } else {
- if (vlan_extracted)
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(rx_desc->wb.upper.vlan));
- else
- netif_receive_skb(skb);
- }
+ if (vlan_extracted)
+ vlan_gro_receive(&ring->napi, adapter->vlgrp,
+ le16_to_cpu(rx_desc->wb.upper.vlan),
+ skb);
+ else
+ napi_gro_receive(&ring->napi, skb);
}
static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
@@ -4458,19 +4452,28 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
skb->ip_summed = CHECKSUM_NONE;
/* Ignore Checksum bit is set or checksum is disabled through ethtool */
- if ((status_err & E1000_RXD_STAT_IXSM) || !adapter->rx_csum)
+ if ((status_err & E1000_RXD_STAT_IXSM) ||
+ (adapter->flags & IGB_FLAG_RX_CSUM_DISABLED))
return;
/* TCP/UDP checksum error bit is set */
if (status_err &
(E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
+ /*
+ * work around errata with sctp packets where the TCPE aka
+ * L4E bit is set incorrectly on 64 byte (60 byte w/o crc)
+ * packets, (aka let the stack check the crc32c)
+ */
+ if (!((adapter->hw.mac.type == e1000_82576) &&
+ (skb->len == 60)))
+ adapter->hw_csum_err++;
/* let the stack verify checksum errors */
- adapter->hw_csum_err++;
return;
}
/* It must be a TCP or UDP packet with a valid checksum */
if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
skb->ip_summed = CHECKSUM_UNNECESSARY;
+ dev_dbg(&adapter->pdev->dev, "cksum success: bits %08X\n", status_err);
adapter->hw_csum_good++;
}
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c
index 1dcaa6905312..ee17a097d1ca 100644
--- a/drivers/net/igbvf/ethtool.c
+++ b/drivers/net/igbvf/ethtool.c
@@ -133,6 +133,24 @@ static int igbvf_set_pauseparam(struct net_device *netdev,
return -EOPNOTSUPP;
}
+static u32 igbvf_get_rx_csum(struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ return !(adapter->flags & IGBVF_FLAG_RX_CSUM_DISABLED);
+}
+
+static int igbvf_set_rx_csum(struct net_device *netdev, u32 data)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ if (data)
+ adapter->flags &= ~IGBVF_FLAG_RX_CSUM_DISABLED;
+ else
+ adapter->flags |= IGBVF_FLAG_RX_CSUM_DISABLED;
+
+ return 0;
+}
+
static u32 igbvf_get_tx_csum(struct net_device *netdev)
{
return ((netdev->features & NETIF_F_IP_CSUM) != 0);
@@ -150,8 +168,6 @@ static int igbvf_set_tx_csum(struct net_device *netdev, u32 data)
static int igbvf_set_tso(struct net_device *netdev, u32 data)
{
struct igbvf_adapter *adapter = netdev_priv(netdev);
- int i;
- struct net_device *v_netdev;
if (data) {
netdev->features |= NETIF_F_TSO;
@@ -159,24 +175,10 @@ static int igbvf_set_tso(struct net_device *netdev, u32 data)
} else {
netdev->features &= ~NETIF_F_TSO;
netdev->features &= ~NETIF_F_TSO6;
- /* disable TSO on all VLANs if they're present */
- if (!adapter->vlgrp)
- goto tso_out;
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
- v_netdev = vlan_group_get_device(adapter->vlgrp, i);
- if (!v_netdev)
- continue;
-
- v_netdev->features &= ~NETIF_F_TSO;
- v_netdev->features &= ~NETIF_F_TSO6;
- vlan_group_set_device(adapter->vlgrp, i, v_netdev);
- }
}
-tso_out:
dev_info(&adapter->pdev->dev, "TSO is %s\n",
data ? "Enabled" : "Disabled");
- adapter->flags |= FLAG_TSO_FORCE;
return 0;
}
@@ -517,6 +519,8 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
.set_ringparam = igbvf_set_ringparam,
.get_pauseparam = igbvf_get_pauseparam,
.set_pauseparam = igbvf_set_pauseparam,
+ .get_rx_csum = igbvf_get_rx_csum,
+ .set_rx_csum = igbvf_set_rx_csum,
.get_tx_csum = igbvf_get_tx_csum,
.set_tx_csum = igbvf_set_tx_csum,
.get_sg = ethtool_op_get_sg,
diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h
index d488733893a6..8e9b67ebbf8b 100644
--- a/drivers/net/igbvf/igbvf.h
+++ b/drivers/net/igbvf/igbvf.h
@@ -286,11 +286,7 @@ struct igbvf_info {
};
/* hardware capability, feature, and workaround flags */
-#define FLAG_HAS_HW_VLAN_FILTER (1 << 0)
-#define FLAG_HAS_JUMBO_FRAMES (1 << 1)
-#define FLAG_MSI_ENABLED (1 << 2)
-#define FLAG_RX_CSUM_ENABLED (1 << 3)
-#define FLAG_TSO_FORCE (1 << 4)
+#define IGBVF_FLAG_RX_CSUM_DISABLED (1 << 0)
#define IGBVF_RX_DESC_ADV(R, i) \
(&((((R).desc))[i].rx_desc))
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index b774666ad3cf..44a8eef03a74 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -58,8 +58,7 @@ static void igbvf_reset_interrupt_capability(struct igbvf_adapter *);
static struct igbvf_info igbvf_vf_info = {
.mac = e1000_vfadapt,
- .flags = FLAG_HAS_JUMBO_FRAMES
- | FLAG_RX_CSUM_ENABLED,
+ .flags = 0,
.pba = 10,
.init_ops = e1000_init_function_pointers_vf,
};
@@ -107,8 +106,10 @@ static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
skb->ip_summed = CHECKSUM_NONE;
/* Ignore Checksum bit is set or checksum is disabled through ethtool */
- if ((status_err & E1000_RXD_STAT_IXSM))
+ if ((status_err & E1000_RXD_STAT_IXSM) ||
+ (adapter->flags & IGBVF_FLAG_RX_CSUM_DISABLED))
return;
+
/* TCP/UDP checksum error bit is set */
if (status_err &
(E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
@@ -116,6 +117,7 @@ static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
adapter->hw_csum_err++;
return;
}
+
/* It must be a TCP or UDP packet with a valid checksum */
if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2351,15 +2353,6 @@ static int igbvf_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL;
}
- /* Jumbo frame size limits */
- if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
- if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
- dev_err(&adapter->pdev->dev,
- "Jumbo Frames not supported.\n");
- return -EINVAL;
- }
- }
-
#define MAX_STD_JUMBO_FRAME_SIZE 9234
if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
dev_err(&adapter->pdev->dev, "MTU > 9216 not supported.\n");
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index 941164076a2b..269153eedd26 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/slab.h>
#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
@@ -198,6 +199,17 @@ static int au1k_irda_init_iobuf(iobuff_t *io, int size)
return io->head ? 0 : -ENOMEM;
}
+static const struct net_device_ops au1k_irda_netdev_ops = {
+ .ndo_open = au1k_irda_start,
+ .ndo_stop = au1k_irda_stop,
+ .ndo_start_xmit = au1k_irda_hard_xmit,
+ .ndo_tx_timeout = au1k_tx_timeout,
+ .ndo_do_ioctl = au1k_irda_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int au1k_irda_net_init(struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
@@ -209,11 +221,7 @@ static int au1k_irda_net_init(struct net_device *dev)
if (err)
goto out1;
- dev->open = au1k_irda_start;
- dev->hard_start_xmit = au1k_irda_hard_xmit;
- dev->stop = au1k_irda_stop;
- dev->do_ioctl = au1k_irda_ioctl;
- dev->tx_timeout = au1k_tx_timeout;
+ dev->netdev_ops = &au1k_irda_netdev_ops;
irda_init_max_qos_capabilies(&aup->qos);
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index e775338b525f..3376a4f39e0a 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -14,6 +14,7 @@
*/
#include <linux/module.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
@@ -797,6 +798,16 @@ static int pxa_irda_init_iobuf(iobuff_t *io, int size)
return io->head ? 0 : -ENOMEM;
}
+static const struct net_device_ops pxa_irda_netdev_ops = {
+ .ndo_open = pxa_irda_start,
+ .ndo_stop = pxa_irda_stop,
+ .ndo_start_xmit = pxa_irda_hard_xmit,
+ .ndo_do_ioctl = pxa_irda_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int pxa_irda_probe(struct platform_device *pdev)
{
struct net_device *dev;
@@ -845,10 +856,7 @@ static int pxa_irda_probe(struct platform_device *pdev)
if (err)
goto err_startup;
- dev->hard_start_xmit = pxa_irda_hard_xmit;
- dev->open = pxa_irda_start;
- dev->stop = pxa_irda_stop;
- dev->do_ioctl = pxa_irda_ioctl;
+ dev->netdev_ops = &pxa_irda_netdev_ops;
irda_init_max_qos_capabilies(&si->qos);
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 7a2b003954ca..2aeb2e6aec1b 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/slab.h>
#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
@@ -875,6 +876,16 @@ static int sa1100_irda_init_iobuf(iobuff_t *io, int size)
return io->head ? 0 : -ENOMEM;
}
+static const struct net_device_ops sa1100_irda_netdev_ops = {
+ .ndo_open = sa1100_irda_start,
+ .ndo_stop = sa1100_irda_stop,
+ .ndo_start_xmit = sa1100_irda_hard_xmit,
+ .ndo_do_ioctl = sa1100_irda_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int sa1100_irda_probe(struct platform_device *pdev)
{
struct net_device *dev;
@@ -913,11 +924,8 @@ static int sa1100_irda_probe(struct platform_device *pdev)
if (err)
goto err_mem_5;
- dev->hard_start_xmit = sa1100_irda_hard_xmit;
- dev->open = sa1100_irda_start;
- dev->stop = sa1100_irda_stop;
- dev->do_ioctl = sa1100_irda_ioctl;
- dev->irq = IRQ_Ser2ICP;
+ dev->netdev_ops = &sa1100_irda_netdev_ops;
+ dev->irq = IRQ_Ser2ICP;
irda_init_max_qos_capabilies(&si->qos);
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index cb793c2bade2..e44215cb1882 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -1021,6 +1021,16 @@ static const struct ethtool_ops ops = {
.get_link = veth_get_link,
};
+static const struct net_device_ops veth_netdev_ops = {
+ .ndo_open = veth_open,
+ .ndo_stop = veth_close,
+ .ndo_start_xmit = veth_start_xmit,
+ .ndo_change_mtu = veth_change_mtu,
+ .ndo_set_multicast_list = veth_set_multicast_list,
+ .ndo_set_mac_address = NULL,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static struct net_device *veth_probe_one(int vlan,
struct vio_dev *vio_dev)
{
@@ -1067,12 +1077,7 @@ static struct net_device *veth_probe_one(int vlan,
memcpy(&port->mac_addr, mac_addr, ETH_ALEN);
- dev->open = veth_open;
- dev->hard_start_xmit = veth_start_xmit;
- dev->stop = veth_close;
- dev->change_mtu = veth_change_mtu;
- dev->set_mac_address = NULL;
- dev->set_multicast_list = veth_set_multicast_list;
+ dev->netdev_ops = &veth_netdev_ops;
SET_ETHTOOL_OPS(dev, &ops);
SET_NETDEV_DEV(dev, vdev);
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index 11dcda0f453e..ff67a84e6802 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -192,7 +192,7 @@ ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
vendor_name[i] = ixgb_read_phy_reg(hw,
MDIO_PMA_PMD_XPAK_VENDOR_NAME
+ i, IXGB_PHY_ADDRESS,
- MDIO_PMA_PMD_DID);
+ MDIO_MMD_PMAPMD);
}
/* Determine the actual vendor */
@@ -1225,15 +1225,15 @@ ixgb_optics_reset(struct ixgb_hw *hw)
u16 mdio_reg;
ixgb_write_phy_reg(hw,
- MDIO_PMA_PMD_CR1,
- IXGB_PHY_ADDRESS,
- MDIO_PMA_PMD_DID,
- MDIO_PMA_PMD_CR1_RESET);
-
- mdio_reg = ixgb_read_phy_reg( hw,
- MDIO_PMA_PMD_CR1,
- IXGB_PHY_ADDRESS,
- MDIO_PMA_PMD_DID);
+ MDIO_CTRL1,
+ IXGB_PHY_ADDRESS,
+ MDIO_MMD_PMAPMD,
+ MDIO_CTRL1_RESET);
+
+ mdio_reg = ixgb_read_phy_reg(hw,
+ MDIO_CTRL1,
+ IXGB_PHY_ADDRESS,
+ MDIO_MMD_PMAPMD);
}
return;
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
index 831fe0c58b2b..af6ca3aab5ad 100644
--- a/drivers/net/ixgb/ixgb_hw.h
+++ b/drivers/net/ixgb/ixgb_hw.h
@@ -29,6 +29,8 @@
#ifndef _IXGB_HW_H_
#define _IXGB_HW_H_
+#include <linux/mdio.h>
+
#include "ixgb_osdep.h"
/* Enums */
@@ -507,18 +509,6 @@ typedef enum {
/* Definitions for the optics devices on the MDIO bus. */
#define IXGB_PHY_ADDRESS 0x0 /* Single PHY, multiple "Devices" */
-/* Standard five-bit Device IDs. See IEEE 802.3ae, clause 45 */
-#define MDIO_PMA_PMD_DID 0x01
-#define MDIO_WIS_DID 0x02
-#define MDIO_PCS_DID 0x03
-#define MDIO_XGXS_DID 0x04
-
-/* Standard PMA/PMD registers and bit definitions. */
-/* Note: This is a very limited set of definitions, */
-/* only implemented features are defined. */
-#define MDIO_PMA_PMD_CR1 0x0000
-#define MDIO_PMA_PMD_CR1_RESET 0x8000
-
#define MDIO_PMA_PMD_XPAK_VENDOR_NAME 0x803A /* XPAK/XENPAK devices only */
/* Vendor-specific MDIO registers */
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 4a0826b8f6f2..04cb81a739c2 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -266,6 +266,8 @@ ixgb_up(struct ixgb_adapter *adapter)
napi_enable(&adapter->napi);
ixgb_irq_enable(adapter);
+ netif_wake_queue(netdev);
+
mod_timer(&adapter->watchdog_timer, jiffies);
return 0;
@@ -471,10 +473,8 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto err_register;
- /* we're going to reset, so assume we have no link for now */
-
+ /* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
DPRINTK(PROBE, INFO, "Intel(R) PRO/10GbE Network Connection\n");
ixgb_check_options(adapter);
@@ -592,6 +592,8 @@ ixgb_open(struct net_device *netdev)
if (err)
goto err_setup_tx;
+ netif_carrier_off(netdev);
+
/* allocate receive descriptors */
err = ixgb_setup_rx_resources(adapter);
@@ -602,6 +604,8 @@ ixgb_open(struct net_device *netdev)
if (err)
goto err_up;
+ netif_start_queue(netdev);
+
return 0;
err_up:
@@ -1116,7 +1120,6 @@ ixgb_watchdog(unsigned long data)
adapter->link_speed = 10000;
adapter->link_duplex = FULL_DUPLEX;
netif_carrier_on(netdev);
- netif_wake_queue(netdev);
}
} else {
if (netif_carrier_ok(netdev)) {
@@ -1125,8 +1128,6 @@ ixgb_watchdog(unsigned long data)
printk(KERN_INFO "ixgb: %s NIC Link is Down\n",
netdev->name);
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
}
}
@@ -1139,6 +1140,8 @@ ixgb_watchdog(unsigned long data)
* to get done, so reset controller to flush Tx.
* (Do the reset outside of interrupt context). */
schedule_work(&adapter->tx_timeout_task);
+ /* return immediately since reset is imminent */
+ return;
}
}
diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h
index d92e72bd627a..371a6be4d965 100644
--- a/drivers/net/ixgb/ixgb_osdep.h
+++ b/drivers/net/ixgb/ixgb_osdep.h
@@ -40,7 +40,7 @@
#include <linux/sched.h>
#undef ASSERT
-#define ASSERT(x) if (!(x)) BUG()
+#define ASSERT(x) BUG_ON(!(x))
#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B)
#ifdef DBG
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index c26433d14605..d743d0ed5c2e 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -147,6 +147,7 @@ struct ixgbe_ring {
u16 work_limit; /* max work per interrupt */
u16 rx_buf_len;
+ u64 rsc_count; /* stat for coalesced packets */
};
enum ixgbe_ring_f_enum {
@@ -186,6 +187,7 @@ struct ixgbe_q_vector {
u8 tx_itr;
u8 rx_itr;
u32 eitr;
+ u32 v_idx; /* vector index in list */
};
/* Helper macros to switch between ints/sec and what the register uses.
@@ -229,7 +231,7 @@ struct ixgbe_adapter {
struct vlan_group *vlgrp;
u16 bd_number;
struct work_struct reset_task;
- struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS];
+ struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
struct ixgbe_dcb_config dcb_cfg;
struct ixgbe_dcb_config temp_dcb_cfg;
@@ -294,6 +296,8 @@ struct ixgbe_adapter {
#define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 23)
#define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 24)
#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25)
+#define IXGBE_FLAG_RSC_CAPABLE (u32)(1 << 26)
+#define IXGBE_FLAG_RSC_ENABLED (u32)(1 << 27)
/* default to trying for four seconds */
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
@@ -325,6 +329,7 @@ struct ixgbe_adapter {
struct timer_list sfp_timer;
struct work_struct multispeed_fiber_task;
struct work_struct sfp_config_module_task;
+ u64 rsc_count;
u32 wol;
u16 eeprom_version;
};
@@ -363,10 +368,8 @@ extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *)
extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
-extern void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter);
extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
-void ixgbe_napi_add_all(struct ixgbe_adapter *adapter);
-void ixgbe_napi_del_all(struct ixgbe_adapter *adapter);
+extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32);
#endif /* _IXGBE_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 4791238c3f6e..e051964347e4 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -75,18 +75,49 @@ static u16 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
+
+ /* Call PHY identify routine to get the phy type */
+ ixgbe_identify_phy_generic(hw);
+
+ mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
+ mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
+ mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
+ mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
+ mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
+ mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_init_phy_ops_82598 - PHY/SFP specific init
+ * @hw: pointer to hardware structure
+ *
+ * Initialize any function pointers that were not able to be
+ * set during get_invariants because the PHY/SFP type was
+ * not known. Perform the SFP init if necessary.
+ *
+ **/
+s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
struct ixgbe_phy_info *phy = &hw->phy;
s32 ret_val = 0;
u16 list_offset, data_offset;
- /* Set the bus information prior to PHY identification */
- mac->ops.get_bus_info(hw);
+ /* Identify the PHY */
+ phy->ops.identify(hw);
- /* Call PHY identify routine to get the phy type */
- ixgbe_identify_phy_generic(hw);
+ /* Overwrite the link function pointers if copper PHY */
+ if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+ mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
+ mac->ops.setup_link_speed =
+ &ixgbe_setup_copper_link_speed_82598;
+ mac->ops.get_link_capabilities =
+ &ixgbe_get_copper_link_capabilities_82598;
+ }
- /* PHY Init */
- switch (phy->type) {
+ switch (hw->phy.type) {
case ixgbe_phy_tn:
phy->ops.check_link = &ixgbe_check_phy_link_tnx;
phy->ops.get_firmware_version =
@@ -106,8 +137,8 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
/* Check to see if SFP+ module is supported */
ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
- &list_offset,
- &data_offset);
+ &list_offset,
+ &data_offset);
if (ret_val != 0) {
ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
goto out;
@@ -117,21 +148,6 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
break;
}
- if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
- mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
- mac->ops.setup_link_speed =
- &ixgbe_setup_copper_link_speed_82598;
- mac->ops.get_link_capabilities =
- &ixgbe_get_copper_link_capabilities_82598;
- }
-
- mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
- mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
- mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
- mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
- mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
- mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
-
out:
return ret_val;
}
@@ -149,12 +165,19 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
bool *autoneg)
{
s32 status = 0;
+ u32 autoc = 0;
/*
* Determine link capabilities based on the stored value of AUTOC,
- * which represents EEPROM defaults.
+ * which represents EEPROM defaults. If AUTOC value has not been
+ * stored, use the current register value.
*/
- switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+ if (hw->mac.orig_link_settings_stored)
+ autoc = hw->mac.orig_autoc;
+ else
+ autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+
+ switch (autoc & IXGBE_AUTOC_LMS_MASK) {
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
*speed = IXGBE_LINK_SPEED_1GB_FULL;
*autoneg = false;
@@ -173,9 +196,9 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
case IXGBE_AUTOC_LMS_KX4_AN:
case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
*speed = IXGBE_LINK_SPEED_UNKNOWN;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ if (autoc & IXGBE_AUTOC_KX4_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+ if (autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
*autoneg = true;
break;
@@ -206,14 +229,13 @@ static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
*speed = 0;
*autoneg = true;
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
&speed_ability);
if (status == 0) {
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+ if (speed_ability & MDIO_SPEED_10G)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+ if (speed_ability & MDIO_PMA_SPEED_1000)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
}
@@ -322,6 +344,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
}
/* Enable 802.3x based flow control settings. */
+ fctrl_reg |= IXGBE_FCTRL_DPF;
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
@@ -380,9 +403,11 @@ static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
* because it causes the controller to just blast out fc packets.
*/
if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
- hw_dbg(hw, "Invalid water mark configuration\n");
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
+ if (hw->fc.requested_mode != ixgbe_fc_none) {
+ hw_dbg(hw, "Invalid water mark configuration\n");
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
}
/*
@@ -500,9 +525,9 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
* clear indicates active; set indicates inactive.
*/
if (hw->phy.type == ixgbe_phy_nl) {
- hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
- hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
- hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV,
+ hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg);
+ hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg);
+ hw->phy.ops.read_reg(hw, 0xC00C, MDIO_MMD_PMAPMD,
&adapt_comp_reg);
if (link_up_wait_to_complete) {
for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
@@ -515,10 +540,10 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
}
msleep(100);
hw->phy.ops.read_reg(hw, 0xC79F,
- IXGBE_TWINAX_DEV,
+ MDIO_MMD_PMAPMD,
&link_reg);
hw->phy.ops.read_reg(hw, 0xC00C,
- IXGBE_TWINAX_DEV,
+ MDIO_MMD_PMAPMD,
&adapt_comp_reg);
}
} else {
@@ -716,14 +741,23 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
}
/* Reset PHY */
- if (hw->phy.reset_disable == false)
+ if (hw->phy.reset_disable == false) {
+ /* PHY ops must be identified and initialized prior to reset */
+
+ /* Init PHY and function pointers, perform SFP setup */
+ status = hw->phy.ops.init(hw);
+ if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto reset_hw_out;
+
hw->phy.ops.reset(hw);
+ }
/*
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
* access and verify no pending requests before reset
*/
- if (ixgbe_disable_pcie_master(hw) != 0) {
+ status = ixgbe_disable_pcie_master(hw);
+ if (status != 0) {
status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
}
@@ -770,6 +804,7 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
/* Store the permanent mac address */
hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+reset_hw_out:
return status;
}
@@ -954,14 +989,14 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
hw->phy.ops.write_reg(hw,
IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ MDIO_MMD_PMAPMD,
sfp_addr);
/* Poll status */
for (i = 0; i < 100; i++) {
hw->phy.ops.read_reg(hw,
IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ MDIO_MMD_PMAPMD,
&sfp_stat);
sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
@@ -977,7 +1012,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
/* Read data */
hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
+ MDIO_MMD_PMAPMD, &sfp_data);
*eeprom_data = (u8)(sfp_data >> 8);
} else {
@@ -998,35 +1033,56 @@ out:
static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
{
u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
+ u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+ u16 ext_ability = 0;
+
+ hw->phy.ops.identify(hw);
+
+ /* Copper PHY must be checked before AUTOC LMS to determine correct
+ * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
+ if (hw->phy.type == ixgbe_phy_tn ||
+ hw->phy.type == ixgbe_phy_cu_unknown) {
+ hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
+ &ext_ability);
+ if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+ if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+ if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+ goto out;
+ }
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82598:
- /* Default device ID is mezzanine card KX/KX4 */
- physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
- IXGBE_PHYSICAL_LAYER_1000BASE_KX);
- break;
- case IXGBE_DEV_ID_82598_BX:
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
- case IXGBE_DEV_ID_82598EB_CX4:
- case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
- break;
- case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+ switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+ case IXGBE_AUTOC_LMS_1G_AN:
+ case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+ if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
+ physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+ else
+ physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
break;
- case IXGBE_DEV_ID_82598AF_DUAL_PORT:
- case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
- case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+ case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+ if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+ else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+ else /* XAUI */
+ physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
break;
- case IXGBE_DEV_ID_82598EB_XF_LR:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+ case IXGBE_AUTOC_LMS_KX4_AN:
+ case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
+ if (autoc & IXGBE_AUTOC_KX_SUPP)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+ if (autoc & IXGBE_AUTOC_KX4_SUPP)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
break;
- case IXGBE_DEV_ID_82598AT:
- physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T |
- IXGBE_PHYSICAL_LAYER_1000BASE_T);
+ default:
break;
- case IXGBE_DEV_ID_82598EB_SFP_LOM:
+ }
+
+ if (hw->phy.type == ixgbe_phy_nl) {
hw->phy.ops.identify_sfp(hw);
switch (hw->phy.sfp_type) {
@@ -1043,13 +1099,25 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
break;
}
- break;
+ }
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
+ physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+ break;
+ case IXGBE_DEV_ID_82598AF_DUAL_PORT:
+ case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
+ case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+ break;
+ case IXGBE_DEV_ID_82598EB_XF_LR:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+ break;
default:
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
break;
}
+out:
return physical_layer;
}
@@ -1099,6 +1167,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
static struct ixgbe_phy_operations phy_ops_82598 = {
.identify = &ixgbe_identify_phy_generic,
.identify_sfp = &ixgbe_identify_sfp_module_generic,
+ .init = &ixgbe_init_phy_ops_82598,
.reset = &ixgbe_reset_phy_generic,
.read_reg = &ixgbe_read_phy_reg_generic,
.write_reg = &ixgbe_write_phy_reg_generic,
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 29771fbaa42d..6038ed14c9f9 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -100,6 +100,9 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
ixgbe_init_mac_link_ops_82599(hw);
+
+ hw->phy.ops.reset = NULL;
+
ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
&data_offset);
@@ -146,51 +149,60 @@ u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw)
static s32 ixgbe_get_invariants_82599(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
- struct ixgbe_phy_info *phy = &hw->phy;
- s32 ret_val;
- /* Set the bus information prior to PHY identification */
- mac->ops.get_bus_info(hw);
+ ixgbe_init_mac_link_ops_82599(hw);
- /* Call PHY identify routine to get the Cu or SFI phy type */
- ret_val = phy->ops.identify(hw);
+ mac->mcft_size = IXGBE_82599_MC_TBL_SIZE;
+ mac->vft_size = IXGBE_82599_VFT_TBL_SIZE;
+ mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES;
+ mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES;
+ mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES;
+ mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
- if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto get_invariants_out;
+ return 0;
+}
- ixgbe_init_mac_link_ops_82599(hw);
+/**
+ * ixgbe_init_phy_ops_82599 - PHY/SFP specific init
+ * @hw: pointer to hardware structure
+ *
+ * Initialize any function pointers that were not able to be
+ * set during get_invariants because the PHY/SFP type was
+ * not known. Perform the SFP init if necessary.
+ *
+ **/
+s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
+ struct ixgbe_phy_info *phy = &hw->phy;
+ s32 ret_val = 0;
- /* Setup SFP module if there is one present. */
- ret_val = mac->ops.setup_sfp(hw);
+ /* Identify the PHY or SFP module */
+ ret_val = phy->ops.identify(hw);
+
+ /* Setup function pointers based on detected SFP module and speeds */
+ ixgbe_init_mac_link_ops_82599(hw);
/* If copper media, overwrite with copper function pointers */
if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
mac->ops.setup_link_speed =
- &ixgbe_setup_copper_link_speed_82599;
+ &ixgbe_setup_copper_link_speed_82599;
mac->ops.get_link_capabilities =
&ixgbe_get_copper_link_capabilities_82599;
}
- /* PHY Init */
+ /* Set necessary function pointers based on phy type */
switch (hw->phy.type) {
case ixgbe_phy_tn:
phy->ops.check_link = &ixgbe_check_phy_link_tnx;
phy->ops.get_firmware_version =
- &ixgbe_get_phy_firmware_version_tnx;
+ &ixgbe_get_phy_firmware_version_tnx;
break;
default:
break;
}
- mac->mcft_size = IXGBE_82599_MC_TBL_SIZE;
- mac->vft_size = IXGBE_82599_VFT_TBL_SIZE;
- mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES;
- mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES;
- mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES;
- mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
-
-get_invariants_out:
return ret_val;
}
@@ -207,8 +219,19 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
bool *negotiation)
{
s32 status = 0;
+ u32 autoc = 0;
+
+ /*
+ * Determine link capabilities based on the stored value of AUTOC,
+ * which represents EEPROM defaults. If AUTOC value has not been
+ * stored, use the current register value.
+ */
+ if (hw->mac.orig_link_settings_stored)
+ autoc = hw->mac.orig_autoc;
+ else
+ autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+ switch (autoc & IXGBE_AUTOC_LMS_MASK) {
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
*speed = IXGBE_LINK_SPEED_1GB_FULL;
*negotiation = false;
@@ -232,22 +255,22 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
case IXGBE_AUTOC_LMS_KX4_KX_KR:
case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
*speed = IXGBE_LINK_SPEED_UNKNOWN;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+ if (autoc & IXGBE_AUTOC_KR_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ if (autoc & IXGBE_AUTOC_KX4_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+ if (autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
*negotiation = true;
break;
case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
*speed = IXGBE_LINK_SPEED_100_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+ if (autoc & IXGBE_AUTOC_KR_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ if (autoc & IXGBE_AUTOC_KX4_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+ if (autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
*negotiation = true;
break;
@@ -291,14 +314,13 @@ static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
*speed = 0;
*autoneg = true;
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
&speed_ability);
if (status == 0) {
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+ if (speed_ability & MDIO_SPEED_10G)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+ if (speed_ability & MDIO_PMA_SPEED_1000)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
}
@@ -558,6 +580,7 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
s32 status = 0;
u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ u32 orig_autoc = 0;
u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
@@ -569,6 +592,13 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg);
speed &= link_capabilities;
+ /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
+ if (hw->mac.orig_link_settings_stored)
+ orig_autoc = hw->mac.orig_autoc;
+ else
+ orig_autoc = autoc;
+
+
if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
status = IXGBE_ERR_LINK_SETUP;
} else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
@@ -577,9 +607,9 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
/* Set KX4/KX/KR support according to speed requested */
autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
if (speed & IXGBE_LINK_SPEED_10GB_FULL)
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ if (orig_autoc & IXGBE_AUTOC_KX4_SUPP)
autoc |= IXGBE_AUTOC_KX4_SUPP;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+ if (orig_autoc & IXGBE_AUTOC_KR_SUPP)
autoc |= IXGBE_AUTOC_KR_SUPP;
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
autoc |= IXGBE_AUTOC_KX_SUPP;
@@ -705,14 +735,30 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
/* Call adapter stop to disable tx/rx and clear interrupts */
hw->mac.ops.stop_adapter(hw);
+ /* PHY ops must be identified and initialized prior to reset */
+
+ /* Init PHY and function pointers, perform SFP setup */
+ status = hw->phy.ops.init(hw);
+
+ if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto reset_hw_out;
+
+ /* Setup SFP module if there is one present. */
+ if (hw->phy.sfp_setup_needed) {
+ status = hw->mac.ops.setup_sfp(hw);
+ hw->phy.sfp_setup_needed = false;
+ }
+
/* Reset PHY */
- hw->phy.ops.reset(hw);
+ if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
+ hw->phy.ops.reset(hw);
/*
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
* access and verify no pending requests before reset
*/
- if (ixgbe_disable_pcie_master(hw) != 0) {
+ status = ixgbe_disable_pcie_master(hw);
+ if (status != 0) {
status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
}
@@ -773,6 +819,7 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
/* Store the permanent mac address */
hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+reset_hw_out:
return status;
}
@@ -1093,53 +1140,98 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
{
u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
+ u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
+ u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+ u16 ext_ability = 0;
u8 comp_codes_10g = 0;
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82599:
- case IXGBE_DEV_ID_82599_KX4:
- /* Default device ID is mezzanine card KX/KX4 */
- physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
- IXGBE_PHYSICAL_LAYER_1000BASE_KX);
+ hw->phy.ops.identify(hw);
+
+ if (hw->phy.type == ixgbe_phy_tn ||
+ hw->phy.type == ixgbe_phy_cu_unknown) {
+ hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
+ &ext_ability);
+ if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+ if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+ if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+ goto out;
+ }
+
+ switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+ case IXGBE_AUTOC_LMS_1G_AN:
+ case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+ if (pma_pmd_1g == IXGBE_AUTOC_1G_KX_BX) {
+ physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX |
+ IXGBE_PHYSICAL_LAYER_1000BASE_BX;
+ goto out;
+ } else
+ /* SFI mode so read SFP module */
+ goto sfp_check;
break;
- case IXGBE_DEV_ID_82599_SFP:
- hw->phy.ops.identify_sfp(hw);
+ case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+ if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_CX4)
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+ else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_KX4)
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+ goto out;
+ break;
+ case IXGBE_AUTOC_LMS_10G_SERIAL:
+ if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_KR) {
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR;
+ goto out;
+ } else if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)
+ goto sfp_check;
+ break;
+ case IXGBE_AUTOC_LMS_KX4_KX_KR:
+ case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
+ if (autoc & IXGBE_AUTOC_KX_SUPP)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+ if (autoc & IXGBE_AUTOC_KX4_SUPP)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+ if (autoc & IXGBE_AUTOC_KR_SUPP)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR;
+ goto out;
+ break;
+ default:
+ goto out;
+ break;
+ }
- switch (hw->phy.sfp_type) {
- case ixgbe_sfp_type_da_cu:
- case ixgbe_sfp_type_da_cu_core0:
- case ixgbe_sfp_type_da_cu_core1:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
- break;
- case ixgbe_sfp_type_sr:
+sfp_check:
+ /* SFP check must be done last since DA modules are sometimes used to
+ * test KR mode - we need to id KR mode correctly before SFP module.
+ * Call identify_sfp because the pluggable module may have changed */
+ hw->phy.ops.identify_sfp(hw);
+ if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
+ goto out;
+
+ switch (hw->phy.type) {
+ case ixgbe_phy_tw_tyco:
+ case ixgbe_phy_tw_unknown:
+ physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+ break;
+ case ixgbe_phy_sfp_avago:
+ case ixgbe_phy_sfp_ftl:
+ case ixgbe_phy_sfp_intel:
+ case ixgbe_phy_sfp_unknown:
+ hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
+ if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- break;
- case ixgbe_sfp_type_lr:
+ else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- break;
- case ixgbe_sfp_type_srlr_core0:
- case ixgbe_sfp_type_srlr_core1:
- hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_10GBE_COMP_CODES,
- &comp_codes_10g);
- if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
- physical_layer =
- IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
- physical_layer =
- IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- else
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- default:
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- break;
- }
break;
default:
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
break;
}
+out:
return physical_layer;
}
@@ -1187,6 +1279,22 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
return 0;
}
+/**
+ * ixgbe_get_device_caps_82599 - Get additional device capabilities
+ * @hw: pointer to hardware structure
+ * @device_caps: the EEPROM word with the extra device capabilities
+ *
+ * This function will read the EEPROM location for the device capabilities,
+ * and return the word through device_caps.
+ **/
+s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
+{
+ hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
+
+ return 0;
+}
+
+
static struct ixgbe_mac_operations mac_ops_82599 = {
.init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_82599,
@@ -1196,6 +1304,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82599,
.enable_rx_dma = &ixgbe_enable_rx_dma_82599,
.get_mac_addr = &ixgbe_get_mac_addr_generic,
+ .get_device_caps = &ixgbe_get_device_caps_82599,
.stop_adapter = &ixgbe_stop_adapter_generic,
.get_bus_info = &ixgbe_get_bus_info_generic,
.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie,
@@ -1236,6 +1345,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
static struct ixgbe_phy_operations phy_ops_82599 = {
.identify = &ixgbe_identify_phy_82599,
.identify_sfp = &ixgbe_identify_sfp_module_generic,
+ .init = &ixgbe_init_phy_ops_82599,
.reset = &ixgbe_reset_phy_generic,
.read_reg = &ixgbe_read_phy_reg_generic,
.write_reg = &ixgbe_write_phy_reg_generic,
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 186a65069b33..60638e267c61 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1653,6 +1653,7 @@ s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
}
/* Enable 802.3x based flow control settings. */
+ mflcn_reg |= IXGBE_MFLCN_DPF;
IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
@@ -1859,9 +1860,11 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
* because it causes the controller to just blast out fc packets.
*/
if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
- hw_dbg(hw, "Invalid water mark configuration\n");
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
+ if (hw->fc.requested_mode != ixgbe_fc_none) {
+ hw_dbg(hw, "Invalid water mark configuration\n");
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
}
/*
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index bd0a0c276952..99e0c106e671 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -124,13 +124,7 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
- ixgbe_reset_interrupt_capability(adapter);
- ixgbe_napi_del_all(adapter);
- INIT_LIST_HEAD(&netdev->napi_list);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
- adapter->tx_ring = NULL;
- adapter->rx_ring = NULL;
+ ixgbe_clear_interrupt_scheme(adapter);
adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
@@ -144,13 +138,7 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
adapter->hw.fc.requested_mode = ixgbe_fc_default;
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
- ixgbe_reset_interrupt_capability(adapter);
- ixgbe_napi_del_all(adapter);
- INIT_LIST_HEAD(&netdev->napi_list);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
- adapter->tx_ring = NULL;
- adapter->rx_ring = NULL;
+ ixgbe_clear_interrupt_scheme(adapter);
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index f0a20facc650..c0167d617b1e 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -67,6 +67,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"rx_over_errors", IXGBE_STAT(net_stats.rx_over_errors)},
{"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)},
{"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)},
+ {"hw_rsc_count", IXGBE_STAT(rsc_count)},
{"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)},
{"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)},
{"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)},
@@ -311,10 +312,17 @@ static u32 ixgbe_get_tx_csum(struct net_device *netdev)
static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
{
- if (data)
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ if (data) {
netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
- else
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ netdev->features |= NETIF_F_SCTP_CSUM;
+ } else {
netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ netdev->features &= ~NETIF_F_SCTP_CSUM;
+ }
return 0;
}
@@ -1106,7 +1114,7 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
}
for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
- struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
if (q_vector->txr_count && !q_vector->rxr_count)
/* tx vector gets half the rate */
q_vector->eitr = (adapter->eitr_param >> 1);
@@ -1120,6 +1128,27 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
return 0;
}
+static int ixgbe_set_flags(struct net_device *netdev, u32 data)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ ethtool_op_set_flags(netdev, data);
+
+ if (!(adapter->flags & IXGBE_FLAG_RSC_CAPABLE))
+ return 0;
+
+ /* if state changes we need to update adapter->flags and reset */
+ if ((!!(data & ETH_FLAG_LRO)) !=
+ (!!(adapter->flags & IXGBE_FLAG_RSC_ENABLED))) {
+ adapter->flags ^= IXGBE_FLAG_RSC_ENABLED;
+ if (netif_running(netdev))
+ ixgbe_reinit_locked(adapter);
+ else
+ ixgbe_reset(adapter);
+ }
+ return 0;
+
+}
static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_settings = ixgbe_get_settings,
@@ -1154,7 +1183,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_coalesce = ixgbe_get_coalesce,
.set_coalesce = ixgbe_set_coalesce,
.get_flags = ethtool_op_get_flags,
- .set_flags = ethtool_op_set_flags,
+ .set_flags = ixgbe_set_flags,
};
void ixgbe_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 07e778d3e5d2..efb175b1e438 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -47,7 +47,7 @@ char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Network Driver";
-#define DRV_VERSION "2.0.8-k2"
+#define DRV_VERSION "2.0.16-k2"
const char ixgbe_driver_version[] = DRV_VERSION;
static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
@@ -326,8 +326,18 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
}
/* re-arm the interrupt */
- if (count >= tx_ring->work_limit)
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->v_idx);
+ if (count >= tx_ring->work_limit) {
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
+ tx_ring->v_idx);
+ else if (tx_ring->v_idx & 0xFFFFFFFF)
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0),
+ tx_ring->v_idx);
+ else
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1),
+ (tx_ring->v_idx >> 32));
+ }
+
tx_ring->total_bytes += total_bytes;
tx_ring->total_packets += total_packets;
@@ -451,6 +461,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
**/
static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
struct sk_buff *skb, u8 status,
+ struct ixgbe_ring *ring,
union ixgbe_adv_rx_desc *rx_desc)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
@@ -458,24 +469,17 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
bool is_vlan = (status & IXGBE_RXD_STAT_VP);
u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
- skb_record_rx_queue(skb, q_vector - &adapter->q_vector[0]);
- if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ skb_record_rx_queue(skb, ring->queue_index);
+ if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
if (adapter->vlgrp && is_vlan && (tag != 0))
vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
else
napi_gro_receive(napi, skb);
} else {
- if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
- if (adapter->vlgrp && is_vlan && (tag != 0))
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp, tag);
- else
- netif_receive_skb(skb);
- } else {
- if (adapter->vlgrp && is_vlan && (tag != 0))
- vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
- else
- netif_rx(skb);
- }
+ if (adapter->vlgrp && is_vlan && (tag != 0))
+ vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
+ else
+ netif_rx(skb);
}
}
@@ -622,6 +626,40 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
}
+static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc)
+{
+ return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) &
+ IXGBE_RXDADV_RSCCNT_MASK) >>
+ IXGBE_RXDADV_RSCCNT_SHIFT;
+}
+
+/**
+ * ixgbe_transform_rsc_queue - change rsc queue into a full packet
+ * @skb: pointer to the last skb in the rsc queue
+ *
+ * This function changes a queue full of hw rsc buffers into a completed
+ * packet. It uses the ->prev pointers to find the first packet and then
+ * turns it into the frag list owner.
+ **/
+static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb)
+{
+ unsigned int frag_list_size = 0;
+
+ while (skb->prev) {
+ struct sk_buff *prev = skb->prev;
+ frag_list_size += skb->len;
+ skb->prev = NULL;
+ skb = prev;
+ }
+
+ skb_shinfo(skb)->frag_list = skb->next;
+ skb->next = NULL;
+ skb->len += frag_list_size;
+ skb->data_len += frag_list_size;
+ skb->truesize += frag_list_size;
+ return skb;
+}
+
static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *rx_ring,
int *work_done, int work_to_do)
@@ -631,7 +669,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
struct sk_buff *skb;
- unsigned int i;
+ unsigned int i, rsc_count = 0;
u32 len, staterr;
u16 hdr_info;
bool cleaned = false;
@@ -697,20 +735,38 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
i++;
if (i == rx_ring->count)
i = 0;
- next_buffer = &rx_ring->rx_buffer_info[i];
next_rxd = IXGBE_RX_DESC_ADV(*rx_ring, i);
prefetch(next_rxd);
-
cleaned_count++;
+
+ if (adapter->flags & IXGBE_FLAG_RSC_CAPABLE)
+ rsc_count = ixgbe_get_rsc_count(rx_desc);
+
+ if (rsc_count) {
+ u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >>
+ IXGBE_RXDADV_NEXTP_SHIFT;
+ next_buffer = &rx_ring->rx_buffer_info[nextp];
+ rx_ring->rsc_count += (rsc_count - 1);
+ } else {
+ next_buffer = &rx_ring->rx_buffer_info[i];
+ }
+
if (staterr & IXGBE_RXD_STAT_EOP) {
+ if (skb->prev)
+ skb = ixgbe_transform_rsc_queue(skb);
rx_ring->stats.packets++;
rx_ring->stats.bytes += skb->len;
} else {
- rx_buffer_info->skb = next_buffer->skb;
- rx_buffer_info->dma = next_buffer->dma;
- next_buffer->skb = skb;
- next_buffer->dma = 0;
+ if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+ rx_buffer_info->skb = next_buffer->skb;
+ rx_buffer_info->dma = next_buffer->dma;
+ next_buffer->skb = skb;
+ next_buffer->dma = 0;
+ } else {
+ skb->next = next_buffer->skb;
+ skb->next->prev = skb;
+ }
adapter->non_eop_descs++;
goto next_desc;
}
@@ -727,7 +783,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
total_rx_packets++;
skb->protocol = eth_type_trans(skb, adapter->netdev);
- ixgbe_receive_skb(q_vector, skb, staterr, rx_desc);
+ ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc);
next_desc:
rx_desc->wb.upper.status_error = 0;
@@ -740,7 +796,7 @@ next_desc:
/* use prefetched values */
rx_desc = next_rxd;
- rx_buffer_info = next_buffer;
+ rx_buffer_info = &rx_ring->rx_buffer_info[i];
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
@@ -780,7 +836,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
* corresponding register.
*/
for (v_idx = 0; v_idx < q_vectors; v_idx++) {
- q_vector = &adapter->q_vector[v_idx];
+ q_vector = adapter->q_vector[v_idx];
/* XXX for_each_bit(...) */
r_idx = find_first_bit(q_vector->rxr_idx,
adapter->num_rx_queues);
@@ -929,8 +985,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
struct ixgbe_adapter *adapter = q_vector->adapter;
u32 new_itr;
u8 current_itr, ret_itr;
- int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
- sizeof(struct ixgbe_q_vector);
+ int i, r_idx, v_idx = q_vector->v_idx;
struct ixgbe_ring *rx_ring, *tx_ring;
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
@@ -1121,7 +1176,13 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
rx_ring = &(adapter->rx_ring[r_idx]);
/* disable interrupts on this vector only */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
+ else if (rx_ring->v_idx & 0xFFFFFFFF)
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), rx_ring->v_idx);
+ else
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1),
+ (rx_ring->v_idx >> 32));
napi_schedule(&q_vector->napi);
return IRQ_HANDLED;
@@ -1135,6 +1196,23 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
return IRQ_HANDLED;
}
+static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter,
+ u64 qmask)
+{
+ u32 mask;
+
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
+ } else {
+ mask = (qmask & 0xFFFFFFFF);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(0), mask);
+ mask = (qmask >> 32);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask);
+ }
+ /* skip the flush */
+}
+
/**
* ixgbe_clean_rxonly - msix (aka one shot) rx clean routine
* @napi: napi struct with our devices info in it
@@ -1167,7 +1245,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
if (adapter->itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx);
+ ixgbe_irq_enable_queues(adapter, rx_ring->v_idx);
}
return work_done;
@@ -1189,7 +1267,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
struct ixgbe_ring *rx_ring = NULL;
int work_done = 0, i;
long r_idx;
- u16 enable_mask = 0;
+ u64 enable_mask = 0;
/* attempt to distribute budget to each queue fairly, but don't allow
* the budget to go below 1 because we'll exit polling */
@@ -1216,7 +1294,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
if (adapter->itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, enable_mask);
+ ixgbe_irq_enable_queues(adapter, enable_mask);
return 0;
}
@@ -1225,19 +1303,21 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
int r_idx)
{
- a->q_vector[v_idx].adapter = a;
- set_bit(r_idx, a->q_vector[v_idx].rxr_idx);
- a->q_vector[v_idx].rxr_count++;
- a->rx_ring[r_idx].v_idx = 1 << v_idx;
+ struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
+
+ set_bit(r_idx, q_vector->rxr_idx);
+ q_vector->rxr_count++;
+ a->rx_ring[r_idx].v_idx = (u64)1 << v_idx;
}
static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
- int r_idx)
+ int t_idx)
{
- a->q_vector[v_idx].adapter = a;
- set_bit(r_idx, a->q_vector[v_idx].txr_idx);
- a->q_vector[v_idx].txr_count++;
- a->tx_ring[r_idx].v_idx = 1 << v_idx;
+ struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
+
+ set_bit(t_idx, q_vector->txr_idx);
+ q_vector->txr_count++;
+ a->tx_ring[t_idx].v_idx = (u64)1 << v_idx;
}
/**
@@ -1333,7 +1413,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
(!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
&ixgbe_msix_clean_many)
for (vector = 0; vector < q_vectors; vector++) {
- handler = SET_HANDLER(&adapter->q_vector[vector]);
+ handler = SET_HANDLER(adapter->q_vector[vector]);
if(handler == &ixgbe_msix_clean_rx) {
sprintf(adapter->name[vector], "%s-%s-%d",
@@ -1349,7 +1429,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
err = request_irq(adapter->msix_entries[vector].vector,
handler, 0, adapter->name[vector],
- &(adapter->q_vector[vector]));
+ adapter->q_vector[vector]);
if (err) {
DPRINTK(PROBE, ERR,
"request_irq failed for MSIX interrupt "
@@ -1372,7 +1452,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
free_queue_irqs:
for (i = vector - 1; i >= 0; i--)
free_irq(adapter->msix_entries[--vector].vector,
- &(adapter->q_vector[i]));
+ adapter->q_vector[i]);
adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
pci_disable_msix(adapter->pdev);
kfree(adapter->msix_entries);
@@ -1383,7 +1463,7 @@ out:
static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
{
- struct ixgbe_q_vector *q_vector = adapter->q_vector;
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
u8 current_itr;
u32 new_itr = q_vector->eitr;
struct ixgbe_ring *rx_ring = &adapter->rx_ring[0];
@@ -1436,7 +1516,8 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
{
u32 mask;
- mask = IXGBE_EIMS_ENABLE_MASK;
+
+ mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
mask |= IXGBE_EIMS_GPI_SDP1;
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
@@ -1446,14 +1527,7 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
}
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- /* enable the rest of the queue vectors */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1),
- (IXGBE_EIMS_RTX_QUEUE << 16));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
- ((IXGBE_EIMS_RTX_QUEUE << 16) |
- IXGBE_EIMS_RTX_QUEUE));
- }
+ ixgbe_irq_enable_queues(adapter, ~0);
IXGBE_WRITE_FLUSH(&adapter->hw);
}
@@ -1467,6 +1541,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
struct net_device *netdev = data;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
u32 eicr;
/*
@@ -1494,13 +1569,13 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
ixgbe_check_fan_failure(adapter, eicr);
- if (napi_schedule_prep(&adapter->q_vector[0].napi)) {
+ if (napi_schedule_prep(&(q_vector->napi))) {
adapter->tx_ring[0].total_packets = 0;
adapter->tx_ring[0].total_bytes = 0;
adapter->rx_ring[0].total_packets = 0;
adapter->rx_ring[0].total_bytes = 0;
/* would disable interrupts here but EIAM disabled it */
- __napi_schedule(&adapter->q_vector[0].napi);
+ __napi_schedule(&(q_vector->napi));
}
return IRQ_HANDLED;
@@ -1511,7 +1586,7 @@ static inline void ixgbe_reset_q_vectors(struct ixgbe_adapter *adapter)
int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
for (i = 0; i < q_vectors; i++) {
- struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES);
bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES);
q_vector->rxr_count = 0;
@@ -1562,7 +1637,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
i--;
for (; i >= 0; i--) {
free_irq(adapter->msix_entries[i].vector,
- &(adapter->q_vector[i]));
+ adapter->q_vector[i]);
}
ixgbe_reset_q_vectors(adapter);
@@ -1577,10 +1652,12 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
**/
static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
{
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
+ } else {
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(2), ~0);
}
IXGBE_WRITE_FLUSH(&adapter->hw);
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
@@ -1592,18 +1669,6 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
}
}
-static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter)
-{
- u32 mask = IXGBE_EIMS_RTX_QUEUE;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask << 16);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
- (mask << 16 | mask));
- }
- /* skip the flush */
-}
-
/**
* ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts
*
@@ -1675,7 +1740,18 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
unsigned long mask;
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- queue0 = index;
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
+ if (dcb_i == 8)
+ queue0 = index >> 4;
+ else if (dcb_i == 4)
+ queue0 = index >> 5;
+ else
+ dev_err(&adapter->pdev->dev, "Invalid DCB "
+ "configuration\n");
+ } else {
+ queue0 = index;
+ }
} else {
mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
queue0 = index & mask;
@@ -1689,28 +1765,20 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
+ srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
+ IXGBE_SRRCTL_BSIZEHDR_MASK;
+
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
- u16 bufsz = IXGBE_RXBUFFER_2048;
- /* grow the amount we can receive on large page machines */
- if (bufsz < (PAGE_SIZE / 2))
- bufsz = (PAGE_SIZE / 2);
- /* cap the bufsz at our largest descriptor size */
- bufsz = min((u16)IXGBE_MAX_RXBUFFER, bufsz);
-
- srrctl |= bufsz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#if (PAGE_SIZE / 2) > IXGBE_MAX_RXBUFFER
+ srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#else
+ srrctl |= (PAGE_SIZE / 2) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#endif
srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
- srrctl |= ((IXGBE_RX_HDR_SIZE <<
- IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
- IXGBE_SRRCTL_BSIZEHDR_MASK);
} else {
+ srrctl |= ALIGN(rx_ring->rx_buf_len, 1024) >>
+ IXGBE_SRRCTL_BSIZEPKT_SHIFT;
srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
-
- if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE)
- srrctl |= IXGBE_RXBUFFER_2048 >>
- IXGBE_SRRCTL_BSIZEPKT_SHIFT;
- else
- srrctl |= rx_ring->rx_buf_len >>
- IXGBE_SRRCTL_BSIZEPKT_SHIFT;
}
IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
@@ -1736,6 +1804,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
u32 fctrl, hlreg0;
u32 reta = 0, mrqc = 0;
u32 rdrxctl;
+ u32 rscctrl;
int rx_buf_len;
/* Decide whether to use packet split mode or not */
@@ -1749,11 +1818,13 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
IXGBE_PSRTYPE_UDPHDR |
IXGBE_PSRTYPE_IPV4HDR |
- IXGBE_PSRTYPE_IPV6HDR;
+ IXGBE_PSRTYPE_IPV6HDR |
+ IXGBE_PSRTYPE_L2HDR;
IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype);
}
} else {
- if (netdev->mtu <= ETH_DATA_LEN)
+ if (!(adapter->flags & IXGBE_FLAG_RSC_ENABLED) &&
+ (netdev->mtu <= ETH_DATA_LEN))
rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
else
rx_buf_len = ALIGN(max_frame, 1024);
@@ -1875,8 +1946,38 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
if (hw->mac.type == ixgbe_mac_82599EB) {
rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
+ rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE;
IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
}
+
+ if (adapter->flags & IXGBE_FLAG_RSC_ENABLED) {
+ /* Enable 82599 HW-RSC */
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ j = adapter->rx_ring[i].reg_idx;
+ rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j));
+ rscctrl |= IXGBE_RSCCTL_RSCEN;
+ /*
+ * if packet split is enabled we can only support up
+ * to max frags + 1 descriptors.
+ */
+ if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)
+#if (MAX_SKB_FRAGS < 3)
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_1;
+#elif (MAX_SKB_FRAGS < 7)
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
+#elif (MAX_SKB_FRAGS < 15)
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
+#else
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
+#endif
+ else
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
+ IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl);
+ }
+ /* Disable RSC for ACK packets */
+ IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
+ (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU)));
+ }
}
static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
@@ -2041,7 +2142,7 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
for (q_idx = 0; q_idx < q_vectors; q_idx++) {
struct napi_struct *napi;
- q_vector = &adapter->q_vector[q_idx];
+ q_vector = adapter->q_vector[q_idx];
if (!q_vector->rxr_count)
continue;
napi = &q_vector->napi;
@@ -2064,7 +2165,7 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
q_vectors = 1;
for (q_idx = 0; q_idx < q_vectors; q_idx++) {
- q_vector = &adapter->q_vector[q_idx];
+ q_vector = adapter->q_vector[q_idx];
if (!q_vector->rxr_count)
continue;
napi_disable(&q_vector->napi);
@@ -2357,6 +2458,17 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
ixgbe_irq_enable(adapter);
/*
+ * If this adapter has a fan, check to see if we had a failure
+ * before we enabled the interrupt.
+ */
+ if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
+ u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+ if (esdp & IXGBE_ESDP_SDP1)
+ DPRINTK(DRV, CRIT,
+ "Fan has stopped, replace the adapter\n");
+ }
+
+ /*
* For hot-pluggable SFP+ devices, a new SFP+ module may have
* arrived before interrupts were enabled. We need to kick off
* the SFP+ module setup first, then try to bring up link.
@@ -2404,8 +2516,6 @@ int ixgbe_up(struct ixgbe_adapter *adapter)
/* hardware has been reset, we need to reload some things */
ixgbe_configure(adapter);
- ixgbe_napi_add_all(adapter);
-
return ixgbe_up_complete(adapter);
}
@@ -2445,8 +2555,13 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_buffer_info->dma = 0;
}
if (rx_buffer_info->skb) {
- dev_kfree_skb(rx_buffer_info->skb);
+ struct sk_buff *skb = rx_buffer_info->skb;
rx_buffer_info->skb = NULL;
+ do {
+ struct sk_buff *this = skb;
+ skb = skb->prev;
+ dev_kfree_skb(this);
+ } while (skb);
}
if (!rx_buffer_info->page)
continue;
@@ -2632,7 +2747,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
if (adapter->itr_setting & 1)
ixgbe_set_itr(adapter);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable_queues(adapter);
+ ixgbe_irq_enable_queues(adapter, IXGBE_EIMS_RTX_QUEUE);
}
return work_done;
}
@@ -2778,9 +2893,6 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
kfree(adapter->msix_entries);
adapter->msix_entries = NULL;
- adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
- adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
- ixgbe_set_num_queues(adapter);
} else {
adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
/*
@@ -3004,31 +3116,20 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
* mean we disable MSI-X capabilities of the adapter. */
adapter->msix_entries = kcalloc(v_budget,
sizeof(struct msix_entry), GFP_KERNEL);
- if (!adapter->msix_entries) {
- adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
- adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
- ixgbe_set_num_queues(adapter);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
- err = ixgbe_alloc_queues(adapter);
- if (err) {
- DPRINTK(PROBE, ERR, "Unable to allocate memory "
- "for queues\n");
- goto out;
- }
+ if (adapter->msix_entries) {
+ for (vector = 0; vector < v_budget; vector++)
+ adapter->msix_entries[vector].entry = vector;
- goto try_msi;
- }
+ ixgbe_acquire_msix_vectors(adapter, v_budget);
- for (vector = 0; vector < v_budget; vector++)
- adapter->msix_entries[vector].entry = vector;
-
- ixgbe_acquire_msix_vectors(adapter, v_budget);
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
+ goto out;
+ }
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
- goto out;
+ adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
+ adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
+ ixgbe_set_num_queues(adapter);
-try_msi:
err = pci_enable_msi(adapter->pdev);
if (!err) {
adapter->flags |= IXGBE_FLAG_MSI_ENABLED;
@@ -3043,6 +3144,87 @@ out:
return err;
}
+/**
+ * ixgbe_alloc_q_vectors - Allocate memory for interrupt vectors
+ * @adapter: board private structure to initialize
+ *
+ * We allocate one q_vector per queue interrupt. If allocation fails we
+ * return -ENOMEM.
+ **/
+static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter)
+{
+ int q_idx, num_q_vectors;
+ struct ixgbe_q_vector *q_vector;
+ int napi_vectors;
+ int (*poll)(struct napi_struct *, int);
+
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+ napi_vectors = adapter->num_rx_queues;
+ poll = &ixgbe_clean_rxonly;
+ } else {
+ num_q_vectors = 1;
+ napi_vectors = 1;
+ poll = &ixgbe_poll;
+ }
+
+ for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
+ q_vector = kzalloc(sizeof(struct ixgbe_q_vector), GFP_KERNEL);
+ if (!q_vector)
+ goto err_out;
+ q_vector->adapter = adapter;
+ q_vector->v_idx = q_idx;
+ q_vector->eitr = adapter->eitr_param;
+ if (q_idx < napi_vectors)
+ netif_napi_add(adapter->netdev, &q_vector->napi,
+ (*poll), 64);
+ adapter->q_vector[q_idx] = q_vector;
+ }
+
+ return 0;
+
+err_out:
+ while (q_idx) {
+ q_idx--;
+ q_vector = adapter->q_vector[q_idx];
+ netif_napi_del(&q_vector->napi);
+ kfree(q_vector);
+ adapter->q_vector[q_idx] = NULL;
+ }
+ return -ENOMEM;
+}
+
+/**
+ * ixgbe_free_q_vectors - Free memory allocated for interrupt vectors
+ * @adapter: board private structure to initialize
+ *
+ * This function frees the memory allocated to the q_vectors. In addition if
+ * NAPI is enabled it will delete any references to the NAPI struct prior
+ * to freeing the q_vector.
+ **/
+static void ixgbe_free_q_vectors(struct ixgbe_adapter *adapter)
+{
+ int q_idx, num_q_vectors;
+ int napi_vectors;
+
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+ napi_vectors = adapter->num_rx_queues;
+ } else {
+ num_q_vectors = 1;
+ napi_vectors = 1;
+ }
+
+ for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[q_idx];
+
+ adapter->q_vector[q_idx] = NULL;
+ if (q_idx < napi_vectors)
+ netif_napi_del(&q_vector->napi);
+ kfree(q_vector);
+ }
+}
+
void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter)
{
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
@@ -3074,18 +3256,25 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
/* Number of supported queues */
ixgbe_set_num_queues(adapter);
- err = ixgbe_alloc_queues(adapter);
- if (err) {
- DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
- goto err_alloc_queues;
- }
-
err = ixgbe_set_interrupt_capability(adapter);
if (err) {
DPRINTK(PROBE, ERR, "Unable to setup interrupt capabilities\n");
goto err_set_interrupt;
}
+ err = ixgbe_alloc_q_vectors(adapter);
+ if (err) {
+ DPRINTK(PROBE, ERR, "Unable to allocate memory for queue "
+ "vectors\n");
+ goto err_alloc_q_vectors;
+ }
+
+ err = ixgbe_alloc_queues(adapter);
+ if (err) {
+ DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
+ goto err_alloc_queues;
+ }
+
DPRINTK(DRV, INFO, "Multiqueue %s: Rx Queue count = %u, "
"Tx Queue count = %u\n",
(adapter->num_rx_queues > 1) ? "Enabled" :
@@ -3095,11 +3284,30 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
return 0;
+err_alloc_queues:
+ ixgbe_free_q_vectors(adapter);
+err_alloc_q_vectors:
+ ixgbe_reset_interrupt_capability(adapter);
err_set_interrupt:
+ return err;
+}
+
+/**
+ * ixgbe_clear_interrupt_scheme - Clear the current interrupt scheme settings
+ * @adapter: board private structure to clear interrupt scheme on
+ *
+ * We go through and clear interrupt specific resources and reset the structure
+ * to pre-load conditions
+ **/
+void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
+{
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
-err_alloc_queues:
- return err;
+ adapter->tx_ring = NULL;
+ adapter->rx_ring = NULL;
+
+ ixgbe_free_q_vectors(adapter);
+ ixgbe_reset_interrupt_capability(adapter);
}
/**
@@ -3185,10 +3393,15 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->ring_feature[RING_F_RSS].indices = rss;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES;
- if (hw->mac.type == ixgbe_mac_82598EB)
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ if (hw->device_id == IXGBE_DEV_ID_82598AT)
+ adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598;
- else if (hw->mac.type == ixgbe_mac_82599EB)
+ } else if (hw->mac.type == ixgbe_mac_82599EB) {
adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
+ adapter->flags |= IXGBE_FLAG_RSC_CAPABLE;
+ adapter->flags |= IXGBE_FLAG_RSC_ENABLED;
+ }
#ifdef CONFIG_IXGBE_DCB
/* Configure DCB traffic classes */
@@ -3503,6 +3716,8 @@ static int ixgbe_open(struct net_device *netdev)
if (test_bit(__IXGBE_TESTING, &adapter->state))
return -EBUSY;
+ netif_carrier_off(netdev);
+
/* allocate transmit descriptors */
err = ixgbe_setup_all_tx_resources(adapter);
if (err)
@@ -3515,8 +3730,6 @@ static int ixgbe_open(struct net_device *netdev)
ixgbe_configure(adapter);
- ixgbe_napi_add_all(adapter);
-
err = ixgbe_request_irq(adapter);
if (err)
goto err_req_irq;
@@ -3568,55 +3781,6 @@ static int ixgbe_close(struct net_device *netdev)
return 0;
}
-/**
- * ixgbe_napi_add_all - prep napi structs for use
- * @adapter: private struct
- *
- * helper function to napi_add each possible q_vector->napi
- */
-void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
-{
- int q_idx, q_vectors;
- struct net_device *netdev = adapter->netdev;
- int (*poll)(struct napi_struct *, int);
-
- /* check if we already have our netdev->napi_list populated */
- if (&netdev->napi_list != netdev->napi_list.next)
- return;
-
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- poll = &ixgbe_clean_rxonly;
- /* Only enable as many vectors as we have rx queues. */
- q_vectors = adapter->num_rx_queues;
- } else {
- poll = &ixgbe_poll;
- /* only one q_vector for legacy modes */
- q_vectors = 1;
- }
-
- for (q_idx = 0; q_idx < q_vectors; q_idx++) {
- struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
- netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
- }
-}
-
-void ixgbe_napi_del_all(struct ixgbe_adapter *adapter)
-{
- int q_idx;
- int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
-
- /* legacy and MSI only use one vector */
- if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
- q_vectors = 1;
-
- for (q_idx = 0; q_idx < q_vectors; q_idx++) {
- struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
- if (!q_vector->rxr_count)
- continue;
- netif_napi_del(&q_vector->napi);
- }
-}
-
#ifdef CONFIG_PM
static int ixgbe_resume(struct pci_dev *pdev)
{
@@ -3626,7 +3790,8 @@ static int ixgbe_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- err = pci_enable_device(pdev);
+
+ err = pci_enable_device_mem(pdev);
if (err) {
printk(KERN_ERR "ixgbe: Cannot enable PCI device from "
"suspend\n");
@@ -3634,8 +3799,7 @@ static int ixgbe_resume(struct pci_dev *pdev)
}
pci_set_master(pdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
+ pci_wake_from_d3(pdev, false);
err = ixgbe_init_interrupt_scheme(adapter);
if (err) {
@@ -3679,11 +3843,7 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
ixgbe_free_all_tx_resources(adapter);
ixgbe_free_all_rx_resources(adapter);
}
- ixgbe_reset_interrupt_capability(adapter);
- ixgbe_napi_del_all(adapter);
- INIT_LIST_HEAD(&netdev->napi_list);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
+ ixgbe_clear_interrupt_scheme(adapter);
#ifdef CONFIG_PM
retval = pci_save_state(pdev);
@@ -3711,13 +3871,10 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0);
}
- if (wufc && hw->mac.type == ixgbe_mac_82599EB) {
- pci_enable_wake(pdev, PCI_D3hot, 1);
- pci_enable_wake(pdev, PCI_D3cold, 1);
- } else {
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
- }
+ if (wufc && hw->mac.type == ixgbe_mac_82599EB)
+ pci_wake_from_d3(pdev, true);
+ else
+ pci_wake_from_d3(pdev, false);
*enable_wake = !!wufc;
@@ -3772,9 +3929,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
if (hw->mac.type == ixgbe_mac_82599EB) {
+ u64 rsc_count = 0;
for (i = 0; i < 16; i++)
adapter->hw_rx_no_dma_resources +=
IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ rsc_count += adapter->rx_ring[i].rsc_count;
+ adapter->rsc_count = rsc_count;
}
adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
@@ -3896,7 +4057,7 @@ static void ixgbe_watchdog(unsigned long data)
int i;
for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++)
- eics |= (1 << i);
+ eics |= ((u64)1 << i);
/* Cause software interrupt to ensure rx rings are cleaned */
switch (hw->mac.type) {
@@ -3916,16 +4077,9 @@ static void ixgbe_watchdog(unsigned long data)
break;
case ixgbe_mac_82599EB:
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- /*
- * EICS(0..15) first 0-15 q vectors
- * EICS[1] (16..31) q vectors 16-31
- * EICS[2] (0..31) q vectors 32-63
- */
- IXGBE_WRITE_REG(hw, IXGBE_EICS,
- (u32)(eics & 0xFFFF));
+ IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(0),
+ (u32)(eics & 0xFFFFFFFF));
IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(1),
- (u32)(eics & 0xFFFF0000));
- IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(2),
(u32)(eics >> 32));
} else {
/*
@@ -4011,6 +4165,9 @@ static void ixgbe_watchdog_task(struct work_struct *work)
struct ixgbe_hw *hw = &adapter->hw;
u32 link_speed = adapter->link_speed;
bool link_up = adapter->link_up;
+ int i;
+ struct ixgbe_ring *tx_ring;
+ int some_tx_pending = 0;
adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK;
@@ -4068,6 +4225,25 @@ static void ixgbe_watchdog_task(struct work_struct *work)
}
}
+ if (!netif_carrier_ok(netdev)) {
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ tx_ring = &adapter->tx_ring[i];
+ if (tx_ring->next_to_use != tx_ring->next_to_clean) {
+ some_tx_pending = 1;
+ break;
+ }
+ }
+
+ if (some_tx_pending) {
+ /* We've lost link, so the controller stops DMA,
+ * but we've got queued Tx work that's never going
+ * to get done, so reset controller to flush Tx.
+ * (Do the reset outside of interrupt context).
+ */
+ schedule_work(&adapter->reset_task);
+ }
+ }
+
ixgbe_update_stats(adapter);
adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK;
}
@@ -4196,12 +4372,18 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
type_tucmd_mlhl |=
IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ else if (ip_hdr(skb)->protocol == IPPROTO_SCTP)
+ type_tucmd_mlhl |=
+ IXGBE_ADVTXD_TUCMD_L4T_SCTP;
break;
case cpu_to_be16(ETH_P_IPV6):
/* XXX what about other V6 headers?? */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
type_tucmd_mlhl |=
IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP)
+ type_tucmd_mlhl |=
+ IXGBE_ADVTXD_TUCMD_L4T_SCTP;
break;
default:
if (unlikely(net_ratelimit())) {
@@ -4519,6 +4701,40 @@ static int ixgbe_set_mac(struct net_device *netdev, void *p)
return 0;
}
+static int
+ixgbe_mdio_read(struct net_device *netdev, int prtad, int devad, u16 addr)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u16 value;
+ int rc;
+
+ if (prtad != hw->phy.mdio.prtad)
+ return -EINVAL;
+ rc = hw->phy.ops.read_reg(hw, addr, devad, &value);
+ if (!rc)
+ rc = value;
+ return rc;
+}
+
+static int ixgbe_mdio_write(struct net_device *netdev, int prtad, int devad,
+ u16 addr, u16 value)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ if (prtad != hw->phy.mdio.prtad)
+ return -EINVAL;
+ return hw->phy.ops.write_reg(hw, addr, devad, value);
+}
+
+static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd);
+}
+
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
* Polling 'interrupt' - used by things like netconsole to send skbs
@@ -4552,6 +4768,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_vlan_rx_register = ixgbe_vlan_rx_register,
.ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid,
+ .ndo_do_ioctl = ixgbe_ioctl,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ixgbe_netpoll,
#endif
@@ -4579,7 +4796,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
int i, err, pci_using_dac;
u32 part_num, eec;
- err = pci_enable_device(pdev);
+ err = pci_enable_device_mem(pdev);
if (err)
return err;
@@ -4599,9 +4816,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
pci_using_dac = 0;
}
- err = pci_request_regions(pdev, ixgbe_driver_name);
+ err = pci_request_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM), ixgbe_driver_name);
if (err) {
- dev_err(&pdev->dev, "pci_request_regions failed 0x%x\n", err);
+ dev_err(&pdev->dev,
+ "pci_request_selected_regions failed 0x%x\n", err);
goto err_pci_reg;
}
@@ -4665,6 +4884,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* PHY */
memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops));
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+ /* ixgbe_identify_phy_generic will set prtad and mmds properly */
+ hw->phy.mdio.prtad = MDIO_PRTAD_NONE;
+ hw->phy.mdio.mmds = 0;
+ hw->phy.mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+ hw->phy.mdio.dev = netdev;
+ hw->phy.mdio.mdio_read = ixgbe_mdio_read;
+ hw->phy.mdio.mdio_write = ixgbe_mdio_write;
/* set up this timer and work struct before calling get_invariants
* which might start the timer
@@ -4702,9 +4928,24 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
goto err_sw_init;
+ /*
+ * If there is a fan on this device and it has failed log the
+ * failure.
+ */
+ if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
+ u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+ if (esdp & IXGBE_ESDP_SDP1)
+ DPRINTK(PROBE, CRIT,
+ "Fan has stopped, replace the adapter\n");
+ }
+
/* reset_hw fills in the perm_addr as well */
err = hw->mac.ops.reset_hw(hw);
- if (err) {
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+ dev_err(&adapter->pdev->dev, "failed to load because an "
+ "unsupported SFP+ module type was detected.\n");
+ goto err_sw_init;
+ } else if (err) {
dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err);
goto err_sw_init;
}
@@ -4720,6 +4961,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_TSO6;
netdev->features |= NETIF_F_GRO;
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ netdev->features |= NETIF_F_SCTP_CSUM;
+
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
netdev->vlan_features |= NETIF_F_IP_CSUM;
@@ -4735,6 +4979,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
+ if (adapter->flags & IXGBE_FLAG_RSC_ENABLED)
+ netdev->features |= NETIF_F_LRO;
+
/* make sure the EEPROM is good */
if (hw->eeprom.ops.validate_checksum(hw, NULL) < 0) {
dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n");
@@ -4774,6 +5021,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
device_init_wakeup(&adapter->pdev->dev, true);
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+ /* pick up the PCI bus settings for reporting later */
+ hw->mac.ops.get_bus_info(hw);
+
/* print bus type/speed/width info */
dev_info(&pdev->dev, "(PCI Express:%s:%s) %pM\n",
((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s":
@@ -4807,13 +5057,14 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* reset the hardware with the new settings */
hw->mac.ops.start_hw(hw);
- netif_carrier_off(netdev);
-
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
+ /* carrier off reporting is important to ethtool even BEFORE open */
+ netif_carrier_off(netdev);
+
#ifdef CONFIG_IXGBE_DCA
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
@@ -4831,8 +5082,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
err_register:
ixgbe_release_hw_control(adapter);
err_hw_init:
+ ixgbe_clear_interrupt_scheme(adapter);
err_sw_init:
- ixgbe_reset_interrupt_capability(adapter);
err_eeprom:
clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
del_timer_sync(&adapter->sfp_timer);
@@ -4843,7 +5094,8 @@ err_eeprom:
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM));
err_pci_reg:
err_dma:
pci_disable_device(pdev);
@@ -4890,16 +5142,15 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
if (netdev->reg_state == NETREG_REGISTERED)
unregister_netdev(netdev);
- ixgbe_reset_interrupt_capability(adapter);
+ ixgbe_clear_interrupt_scheme(adapter);
ixgbe_release_hw_control(adapter);
iounmap(adapter->hw.hw_addr);
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM));
DPRINTK(PROBE, INFO, "complete\n");
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
free_netdev(netdev);
@@ -4927,6 +5178,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
netif_device_detach(netdev);
+ if (state == pci_channel_io_perm_failure)
+ return PCI_ERS_RESULT_DISCONNECT;
+
if (netif_running(netdev))
ixgbe_down(adapter);
pci_disable_device(pdev);
@@ -4948,7 +5202,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
pci_ers_result_t result;
int err;
- if (pci_enable_device(pdev)) {
+ if (pci_enable_device_mem(pdev)) {
DPRINTK(PROBE, ERR,
"Cannot re-enable PCI device after reset.\n");
result = PCI_ERS_RESULT_DISCONNECT;
@@ -4956,8 +5210,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
pci_set_master(pdev);
pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
+ pci_wake_from_d3(pdev, false);
ixgbe_reset(adapter);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 14e9606aa3b3..6d385ea3c2a1 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -44,7 +44,6 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
static bool ixgbe_get_i2c_data(u32 *i2cctl);
static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
-static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
@@ -61,8 +60,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
if (hw->phy.type == ixgbe_phy_unknown) {
for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
- if (ixgbe_validate_phy_addr(hw, phy_addr)) {
- hw->phy.addr = phy_addr;
+ if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) {
ixgbe_get_phy_id(hw);
hw->phy.type =
ixgbe_get_phy_type_from_id(hw->phy.id);
@@ -78,26 +76,6 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
}
/**
- * ixgbe_validate_phy_addr - Determines phy address is valid
- * @hw: pointer to hardware structure
- *
- **/
-static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
-{
- u16 phy_id = 0;
- bool valid = false;
-
- hw->phy.addr = phy_addr;
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id);
-
- if (phy_id != 0xFFFF && phy_id != 0x0)
- valid = true;
-
- return valid;
-}
-
-/**
* ixgbe_get_phy_id - Get the phy type
* @hw: pointer to hardware structure
*
@@ -108,14 +86,12 @@ static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
u16 phy_id_high = 0;
u16 phy_id_low = 0;
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, MDIO_DEVID1, MDIO_MMD_PMAPMD,
&phy_id_high);
if (status == 0) {
hw->phy.id = (u32)(phy_id_high << 16);
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, MDIO_DEVID2, MDIO_MMD_PMAPMD,
&phy_id_low);
hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
@@ -160,9 +136,8 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
* Perform soft PHY reset to the PHY_XS.
* This will cause a soft reset to the PHY
*/
- return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE,
- IXGBE_MDIO_PHY_XS_RESET);
+ return hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
+ MDIO_CTRL1_RESET);
}
/**
@@ -192,7 +167,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
/* Setup and write the address cycle command */
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
(device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
(IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -223,7 +198,8 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
*/
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
(device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (hw->phy.mdio.prtad <<
+ IXGBE_MSCA_PHY_ADDR_SHIFT) |
(IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -292,7 +268,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
/* Setup and write the address cycle command */
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
(device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
(IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -323,7 +299,8 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
*/
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
(device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (hw->phy.mdio.prtad <<
+ IXGBE_MSCA_PHY_ADDR_SHIFT) |
(IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -365,7 +342,7 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
s32 status = IXGBE_NOT_IMPLEMENTED;
u32 time_out;
u32 max_time_out = 10;
- u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
+ u16 autoneg_reg;
/*
* Set advertisement settings in PHY based on autoneg_advertised
@@ -373,36 +350,31 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
* tnx devices cannot be "forced" to a autoneg 10G and fail. But can
* for a 1G.
*/
- hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
+ hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg);
if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL)
- autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */
+ autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
else
- autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */
+ autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
- hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
+ hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg);
/* Restart PHY autonegotiation and wait for completion */
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
+ hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, &autoneg_reg);
- autoneg_reg |= IXGBE_MII_RESTART;
+ autoneg_reg |= MDIO_AN_CTRL1_RESTART;
- hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
+ hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, autoneg_reg);
/* Wait for autonegotiation to finish */
for (time_out = 0; time_out < max_time_out; time_out++) {
udelay(10);
/* Restart PHY autonegotiation and wait for completion */
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN,
&autoneg_reg);
- autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
- if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) {
+ autoneg_reg &= MDIO_AN_STAT1_COMPLETE;
+ if (autoneg_reg == MDIO_AN_STAT1_COMPLETE) {
status = 0;
break;
}
@@ -457,23 +429,21 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
s32 ret_val = 0;
u32 i;
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
+ hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data);
/* reset the PHY and poll for completion */
- hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE,
- (phy_data | IXGBE_MDIO_PHY_XS_RESET));
+ hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
+ (phy_data | MDIO_CTRL1_RESET));
for (i = 0; i < 100; i++) {
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
- if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0)
+ hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
+ &phy_data);
+ if ((phy_data & MDIO_CTRL1_RESET) == 0)
break;
msleep(10);
}
- if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) {
+ if ((phy_data & MDIO_CTRL1_RESET) != 0) {
hw_dbg(hw, "PHY reset did not complete.\n");
ret_val = IXGBE_ERR_PHY;
goto out;
@@ -509,7 +479,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
for (i = 0; i < edata; i++) {
hw->eeprom.ops.read(hw, data_offset, &eword);
hw->phy.ops.write_reg(hw, phy_offset,
- IXGBE_TWINAX_DEV, eword);
+ MDIO_MMD_PMAPMD, eword);
hw_dbg(hw, "Wrote %4.4x to %4.4x\n", eword,
phy_offset);
data_offset++;
@@ -552,6 +522,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
{
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
u32 vendor_oui = 0;
+ enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
u8 identifier = 0;
u8 comp_codes_1g = 0;
u8 comp_codes_10g = 0;
@@ -620,8 +591,18 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
}
+ if (hw->phy.sfp_type != stored_sfp_type)
+ hw->phy.sfp_setup_needed = true;
+
+ /* Determine if the SFP+ PHY is dual speed or not. */
+ if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
+ (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
+ ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
+ (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
+ hw->phy.multispeed_fiber = true;
+
/* Determine PHY vendor */
- if (hw->phy.type == ixgbe_phy_unknown) {
+ if (hw->phy.type != ixgbe_phy_nl) {
hw->phy.id = identifier;
hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_VENDOR_OUI_BYTE0,
@@ -662,23 +643,35 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
break;
}
}
- if (hw->mac.type == ixgbe_mac_82598EB ||
- (hw->phy.sfp_type != ixgbe_sfp_type_sr &&
- hw->phy.sfp_type != ixgbe_sfp_type_lr &&
- hw->phy.sfp_type != ixgbe_sfp_type_srlr_core0 &&
- hw->phy.sfp_type != ixgbe_sfp_type_srlr_core1)) {
+
+ /* All DA cables are supported */
+ if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE) {
+ status = 0;
+ goto out;
+ }
+
+ /* 1G SFP modules are not supported */
+ if (comp_codes_10g == 0) {
+ hw->phy.type = ixgbe_phy_sfp_unsupported;
+ status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+ goto out;
+ }
+
+ /* Anything else 82598-based is supported */
+ if (hw->mac.type == ixgbe_mac_82598EB) {
status = 0;
goto out;
}
- hw->eeprom.ops.read(hw, IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET,
- &enforce_sfp);
- if (!(enforce_sfp & IXGBE_PHY_ALLOW_ANY_SFP)) {
+ /* This is guaranteed to be 82599, no need to check for NULL */
+ hw->mac.ops.get_device_caps(hw, &enforce_sfp);
+ if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
/* Make sure we're a supported PHY type */
if (hw->phy.type == ixgbe_phy_sfp_intel) {
status = 0;
} else {
hw_dbg(hw, "SFP+ module not supported\n");
+ hw->phy.type = ixgbe_phy_sfp_unsupported;
status = IXGBE_ERR_SFP_NOT_SUPPORTED;
}
} else {
@@ -1279,7 +1272,7 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
udelay(10);
status = hw->phy.ops.read_reg(hw,
IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ MDIO_MMD_VEND1,
&phy_data);
phy_link = phy_data &
IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
@@ -1307,8 +1300,7 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
{
s32 status = 0;
- status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, TNX_FW_REV, MDIO_MMD_VEND1,
firmware_version);
return status;
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index cc5f1b3287e1..c9964b7ce1b9 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -44,6 +44,7 @@
/* Bitmasks */
#define IXGBE_SFF_TWIN_AX_CAPABLE 0x80
#define IXGBE_SFF_1GBASESX_CAPABLE 0x1
+#define IXGBE_SFF_1GBASELX_CAPABLE 0x2
#define IXGBE_SFF_10GBASESR_CAPABLE 0x10
#define IXGBE_SFF_10GBASELR_CAPABLE 0x20
#define IXGBE_I2C_EEPROM_READ_MASK 0x100
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 030ff0a9ea67..9fd79a05ff0f 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -29,6 +29,7 @@
#define _IXGBE_TYPE_H_
#include <linux/types.h>
+#include <linux/mdio.h>
/* Vendor ID */
#define IXGBE_INTEL_VENDOR_ID 0x8086
@@ -443,6 +444,21 @@
#define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE 0x4
+/* HW RSC registers */
+#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \
+ (0x0D02C + ((_i - 64) * 0x40)))
+#define IXGBE_RSCDBU 0x03028
+#define IXGBE_RSCCTL_RSCEN 0x01
+#define IXGBE_RSCCTL_MAXDESC_1 0x00
+#define IXGBE_RSCCTL_MAXDESC_4 0x04
+#define IXGBE_RSCCTL_MAXDESC_8 0x08
+#define IXGBE_RSCCTL_MAXDESC_16 0x0C
+#define IXGBE_RXDADV_RSCCNT_SHIFT 17
+#define IXGBE_GPIE_RSC_DELAY_SHIFT 11
+#define IXGBE_RXDADV_RSCCNT_MASK 0x001E0000
+#define IXGBE_RSCDBU_RSCACKDIS 0x00000080
+#define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000
+
/* DCB registers */
#define IXGBE_RTRPCS 0x02430
#define IXGBE_RTTDCS 0x04900
@@ -833,13 +849,7 @@
/* Omer bit masks */
#define IXGBE_CORECTL_WRITE_CMD 0x00010000
-/* Device Type definitions for new protocol MDIO commands */
-#define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1
-#define IXGBE_MDIO_PCS_DEV_TYPE 0x3
-#define IXGBE_MDIO_PHY_XS_DEV_TYPE 0x4
-#define IXGBE_MDIO_AUTO_NEG_DEV_TYPE 0x7
-#define IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE 0x1E /* Device 30 */
-#define IXGBE_TWINAX_DEV 1
+/* MDIO definitions */
#define IXGBE_MDIO_COMMAND_TIMEOUT 100 /* PHY Timeout for 1 GB mode */
@@ -850,31 +860,10 @@
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_10G_SPEED 0x0018
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_1G_SPEED 0x0010
-#define IXGBE_MDIO_AUTO_NEG_CONTROL 0x0 /* AUTO_NEG Control Reg */
-#define IXGBE_MDIO_AUTO_NEG_STATUS 0x1 /* AUTO_NEG Status Reg */
-#define IXGBE_MDIO_PHY_XS_CONTROL 0x0 /* PHY_XS Control Reg */
-#define IXGBE_MDIO_PHY_XS_RESET 0x8000 /* PHY_XS Reset */
-#define IXGBE_MDIO_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/
-#define IXGBE_MDIO_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/
-#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Ability Reg */
-#define IXGBE_MDIO_PHY_SPEED_10G 0x0001 /* 10G capable */
-#define IXGBE_MDIO_PHY_SPEED_1G 0x0010 /* 1G capable */
-#define IXGBE_MDIO_PHY_EXT_ABILITY 0xB /* Ext Ability Reg */
-#define IXGBE_MDIO_PHY_10GBASET_ABILITY 0x0004 /* 10GBaseT capable */
-#define IXGBE_MDIO_PHY_1000BASET_ABILITY 0x0020 /* 1000BaseT capable */
-
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */
-/* MII clause 22/28 definitions */
-#define IXGBE_MDIO_PHY_LOW_POWER_MODE 0x0800
-
-#define IXGBE_MII_SPEED_SELECTION_REG 0x10
-#define IXGBE_MII_RESTART 0x200
-#define IXGBE_MII_AUTONEG_COMPLETE 0x20
-#define IXGBE_MII_AUTONEG_REG 0x0
-
#define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0
#define IXGBE_MAX_PHY_ADDR 32
@@ -898,8 +887,6 @@
#define IXGBE_CONTROL_NL 0x000F
#define IXGBE_CONTROL_EOL_NL 0x0FFF
#define IXGBE_CONTROL_SOL_NL 0x0000
-#define IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET 0x002C
-#define IXGBE_PHY_ALLOW_ANY_SFP 0x1
/* General purpose Interrupt Enable */
#define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */
@@ -958,6 +945,8 @@
#define IXGBE_VT_CTL_DIS_DEFPL 0x20000000 /* disable default pool */
#define IXGBE_VT_CTL_REPLEN 0x40000000 /* replication enabled */
#define IXGBE_VT_CTL_VT_ENABLE 0x00000001 /* Enable VT Mode */
+#define IXGBE_VT_CTL_POOL_SHIFT 7
+#define IXGBE_VT_CTL_POOL_MASK (0x3F << IXGBE_VT_CTL_POOL_SHIFT)
/* VMOLR bitmasks */
#define IXGBE_VMOLR_AUPE 0x01000000 /* accept untagged packets */
@@ -1148,6 +1137,7 @@
/* Interrupt Vector Allocation Registers */
#define IXGBE_IVAR_REG_NUM 25
+#define IXGBE_IVAR_REG_NUM_82599 64
#define IXGBE_IVAR_TXRX_ENTRY 96
#define IXGBE_IVAR_RX_ENTRY 64
#define IXGBE_IVAR_RX_QUEUE(_i) (0 + (_i))
@@ -1382,6 +1372,7 @@
#define IXGBE_FW_PTR 0x0F
#define IXGBE_PBANUM0_PTR 0x15
#define IXGBE_PBANUM1_PTR 0x16
+#define IXGBE_DEVICE_CAPS 0x2C
#define IXGBE_PCIE_MSIX_82599_CAPS 0x72
#define IXGBE_PCIE_MSIX_82598_CAPS 0x62
@@ -1425,6 +1416,8 @@
#define IXGBE_EERD_ATTEMPTS 100000
#endif
+#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1
+
/* PCI Bus Info */
#define IXGBE_PCI_LINK_STATUS 0xB2
#define IXGBE_PCI_LINK_WIDTH 0x3F0
@@ -1553,7 +1546,8 @@
#define IXGBE_MTQC_RT_ENA 0x1 /* DCB Enable */
#define IXGBE_MTQC_VT_ENA 0x2 /* VMDQ2 Enable */
#define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */
-#define IXGBE_MTQC_64VF 0x8 /* 2 TX Queues per pool w/64VF's */
+#define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */
+#define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */
#define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */
/* Receive Descriptor bit definitions */
@@ -1610,6 +1604,7 @@
#define IXGBE_PSRTYPE_UDPHDR 0x00000020
#define IXGBE_PSRTYPE_IPV4HDR 0x00000100
#define IXGBE_PSRTYPE_IPV6HDR 0x00000200
+#define IXGBE_PSRTYPE_L2HDR 0x00001000
/* SRRCTL bit definitions */
#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */
@@ -1861,7 +1856,7 @@ typedef u32 ixgbe_physical_layer;
#define IXGBE_PHYSICAL_LAYER_UNKNOWN 0
#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x0001
#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x0002
-#define IXGBE_PHYSICAL_LAYER_100BASE_T 0x0004
+#define IXGBE_PHYSICAL_LAYER_100BASE_TX 0x0004
#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x0008
#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x0010
#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x0020
@@ -1870,6 +1865,7 @@ typedef u32 ixgbe_physical_layer;
#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x0100
#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200
#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400
+#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800
enum ixgbe_eeprom_type {
ixgbe_eeprom_uninitialized = 0,
@@ -1897,6 +1893,7 @@ enum ixgbe_phy_type {
ixgbe_phy_sfp_ftl,
ixgbe_phy_sfp_unknown,
ixgbe_phy_sfp_intel,
+ ixgbe_phy_sfp_unsupported,
ixgbe_phy_generic
};
@@ -2101,6 +2098,7 @@ struct ixgbe_mac_operations {
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
+ s32 (*get_device_caps)(struct ixgbe_hw *, u16 *);
s32 (*stop_adapter)(struct ixgbe_hw *);
s32 (*get_bus_info)(struct ixgbe_hw *);
void (*set_lan_id)(struct ixgbe_hw *);
@@ -2146,6 +2144,7 @@ struct ixgbe_mac_operations {
struct ixgbe_phy_operations {
s32 (*identify)(struct ixgbe_hw *);
s32 (*identify_sfp)(struct ixgbe_hw *);
+ s32 (*init)(struct ixgbe_hw *);
s32 (*reset)(struct ixgbe_hw *);
s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
@@ -2189,10 +2188,11 @@ struct ixgbe_mac_info {
struct ixgbe_phy_info {
struct ixgbe_phy_operations ops;
+ struct mdio_if_info mdio;
enum ixgbe_phy_type type;
- u32 addr;
u32 id;
enum ixgbe_sfp_type sfp_type;
+ bool sfp_setup_needed;
u32 revision;
enum ixgbe_media_type media_type;
bool reset_disable;
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index d3bf2f017cc2..2a0174b62e96 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -270,6 +270,18 @@ static int ixpdev_close(struct net_device *dev)
return 0;
}
+static const struct net_device_ops ixpdev_netdev_ops = {
+ .ndo_open = ixpdev_open,
+ .ndo_stop = ixpdev_close,
+ .ndo_start_xmit = ixpdev_xmit,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ixpdev_poll_controller,
+#endif
+};
+
struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
{
struct net_device *dev;
@@ -279,12 +291,7 @@ struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
if (dev == NULL)
return NULL;
- dev->hard_start_xmit = ixpdev_xmit;
- dev->open = ixpdev_open;
- dev->stop = ixpdev_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ixpdev_poll_controller;
-#endif
+ dev->netdev_ops = &ixpdev_netdev_ops;
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 14248cfc3dfd..d12106b47bf2 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -96,6 +96,18 @@ static int jazzsonic_close(struct net_device* dev)
return err;
}
+static const struct net_device_ops sonic_netdev_ops = {
+ .ndo_open = jazzsonic_open,
+ .ndo_stop = jazzsonic_close,
+ .ndo_start_xmit = sonic_send_packet,
+ .ndo_get_stats = sonic_get_stats,
+ .ndo_set_multicast_list = sonic_multicast_list,
+ .ndo_tx_timeout = sonic_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int __init sonic_probe1(struct net_device *dev)
{
static unsigned version_printed;
@@ -179,12 +191,7 @@ static int __init sonic_probe1(struct net_device *dev)
lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
* SONIC_BUS_SCALE(lp->dma_bitmode));
- dev->open = jazzsonic_open;
- dev->stop = jazzsonic_close;
- dev->hard_start_xmit = sonic_send_packet;
- dev->get_stats = sonic_get_stats;
- dev->set_multicast_list = &sonic_multicast_list;
- dev->tx_timeout = sonic_tx_timeout;
+ dev->netdev_ops = &sonic_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
/*
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 38d6649a29c4..dc238567cae1 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -1081,6 +1081,21 @@ static int korina_close(struct net_device *dev)
return 0;
}
+static const struct net_device_ops korina_netdev_ops = {
+ .ndo_open = korina_open,
+ .ndo_stop = korina_close,
+ .ndo_start_xmit = korina_send_packet,
+ .ndo_set_multicast_list = korina_multicast_list,
+ .ndo_tx_timeout = korina_tx_timeout,
+ .ndo_do_ioctl = korina_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = korina_poll_controller,
+#endif
+};
+
static int korina_probe(struct platform_device *pdev)
{
struct korina_device *bif = platform_get_drvdata(pdev);
@@ -1149,17 +1164,9 @@ static int korina_probe(struct platform_device *pdev)
dev->irq = lp->rx_irq;
lp->dev = dev;
- dev->open = korina_open;
- dev->stop = korina_close;
- dev->hard_start_xmit = korina_send_packet;
- dev->set_multicast_list = &korina_multicast_list;
+ dev->netdev_ops = &korina_netdev_ops;
dev->ethtool_ops = &netdev_ethtool_ops;
- dev->tx_timeout = korina_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->do_ioctl = &korina_ioctl;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = korina_poll_controller;
-#endif
netif_napi_add(dev, &lp->napi, korina_poll, 64);
lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index efbae4b8398e..a0c578585a50 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -161,12 +161,12 @@ lan_init_chip(struct parisc_device *dev)
if (!dev->irq) {
printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
- __FILE__, dev->hpa.start);
+ __FILE__, (unsigned long)dev->hpa.start);
return -ENODEV;
}
- printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start,
- dev->irq);
+ printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n",
+ (unsigned long)dev->hpa.start, dev->irq);
netdevice = alloc_etherdev(sizeof(struct i596_private));
if (!netdevice)
diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c
index 7415f517491d..070fa4500871 100644
--- a/drivers/net/lib82596.c
+++ b/drivers/net/lib82596.c
@@ -1036,6 +1036,19 @@ static void print_eth(unsigned char *add, char *str)
printk(KERN_DEBUG "i596 0x%p, %pM --> %pM %02X%02X, %s\n",
add, add + 6, add, add[12], add[13], str);
}
+static const struct net_device_ops i596_netdev_ops = {
+ .ndo_open = i596_open,
+ .ndo_stop = i596_close,
+ .ndo_start_xmit = i596_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_tx_timeout = i596_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = i596_poll_controller,
+#endif
+};
static int __devinit i82596_probe(struct net_device *dev)
{
@@ -1062,16 +1075,8 @@ static int __devinit i82596_probe(struct net_device *dev)
return -ENOMEM;
}
- /* The 82596-specific entries in the device structure. */
- dev->open = i596_open;
- dev->stop = i596_close;
- dev->hard_start_xmit = i596_start_xmit;
- dev->set_multicast_list = set_multicast_list;
- dev->tx_timeout = i596_tx_timeout;
+ dev->netdev_ops = &i596_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = i596_poll_controller;
-#endif
memset(dma, 0, sizeof(struct i596_dma));
lp->dma = dma;
diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h
new file mode 100644
index 000000000000..1af66a1e6911
--- /dev/null
+++ b/drivers/net/ll_temac.h
@@ -0,0 +1,374 @@
+
+#ifndef XILINX_LL_TEMAC_H
+#define XILINX_LL_TEMAC_H
+
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+#include <asm/dcr.h>
+#include <asm/dcr-regs.h>
+
+/* packet size info */
+#define XTE_HDR_SIZE 14 /* size of Ethernet header */
+#define XTE_TRL_SIZE 4 /* size of Ethernet trailer (FCS) */
+#define XTE_JUMBO_MTU 9000
+#define XTE_MAX_JUMBO_FRAME_SIZE (XTE_JUMBO_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE)
+
+/* Configuration options */
+
+/* Accept all incoming packets.
+ * This option defaults to disabled (cleared) */
+#define XTE_OPTION_PROMISC (1 << 0)
+/* Jumbo frame support for Tx & Rx.
+ * This option defaults to disabled (cleared) */
+#define XTE_OPTION_JUMBO (1 << 1)
+/* VLAN Rx & Tx frame support.
+ * This option defaults to disabled (cleared) */
+#define XTE_OPTION_VLAN (1 << 2)
+/* Enable recognition of flow control frames on Rx
+ * This option defaults to enabled (set) */
+#define XTE_OPTION_FLOW_CONTROL (1 << 4)
+/* Strip FCS and PAD from incoming frames.
+ * Note: PAD from VLAN frames is not stripped.
+ * This option defaults to disabled (set) */
+#define XTE_OPTION_FCS_STRIP (1 << 5)
+/* Generate FCS field and add PAD automatically for outgoing frames.
+ * This option defaults to enabled (set) */
+#define XTE_OPTION_FCS_INSERT (1 << 6)
+/* Enable Length/Type error checking for incoming frames. When this option is
+set, the MAC will filter frames that have a mismatched type/length field
+and if XTE_OPTION_REPORT_RXERR is set, the user is notified when these
+types of frames are encountered. When this option is cleared, the MAC will
+allow these types of frames to be received.
+This option defaults to enabled (set) */
+#define XTE_OPTION_LENTYPE_ERR (1 << 7)
+/* Enable the transmitter.
+ * This option defaults to enabled (set) */
+#define XTE_OPTION_TXEN (1 << 11)
+/* Enable the receiver
+* This option defaults to enabled (set) */
+#define XTE_OPTION_RXEN (1 << 12)
+
+/* Default options set when device is initialized or reset */
+#define XTE_OPTION_DEFAULTS \
+ (XTE_OPTION_TXEN | \
+ XTE_OPTION_FLOW_CONTROL | \
+ XTE_OPTION_RXEN)
+
+/* XPS_LL_TEMAC SDMA registers definition */
+
+#define TX_NXTDESC_PTR 0x00 /* r */
+#define TX_CURBUF_ADDR 0x01 /* r */
+#define TX_CURBUF_LENGTH 0x02 /* r */
+#define TX_CURDESC_PTR 0x03 /* rw */
+#define TX_TAILDESC_PTR 0x04 /* rw */
+#define TX_CHNL_CTRL 0x05 /* rw */
+/*
+ 0:7 24:31 IRQTimeout
+ 8:15 16:23 IRQCount
+ 16:20 11:15 Reserved
+ 21 10 0
+ 22 9 UseIntOnEnd
+ 23 8 LdIRQCnt
+ 24 7 IRQEn
+ 25:28 3:6 Reserved
+ 29 2 IrqErrEn
+ 30 1 IrqDlyEn
+ 31 0 IrqCoalEn
+*/
+#define CHNL_CTRL_IRQ_IOE (1 << 9)
+#define CHNL_CTRL_IRQ_EN (1 << 7)
+#define CHNL_CTRL_IRQ_ERR_EN (1 << 2)
+#define CHNL_CTRL_IRQ_DLY_EN (1 << 1)
+#define CHNL_CTRL_IRQ_COAL_EN (1 << 0)
+#define TX_IRQ_REG 0x06 /* rw */
+/*
+ 0:7 24:31 DltTmrValue
+ 8:15 16:23 ClscCntrValue
+ 16:17 14:15 Reserved
+ 18:21 10:13 ClscCnt
+ 22:23 8:9 DlyCnt
+ 24:28 3::7 Reserved
+ 29 2 ErrIrq
+ 30 1 DlyIrq
+ 31 0 CoalIrq
+ */
+#define TX_CHNL_STS 0x07 /* r */
+/*
+ 0:9 22:31 Reserved
+ 10 21 TailPErr
+ 11 20 CmpErr
+ 12 19 AddrErr
+ 13 18 NxtPErr
+ 14 17 CurPErr
+ 15 16 BsyWr
+ 16:23 8:15 Reserved
+ 24 7 Error
+ 25 6 IOE
+ 26 5 SOE
+ 27 4 Cmplt
+ 28 3 SOP
+ 29 2 EOP
+ 30 1 EngBusy
+ 31 0 Reserved
+*/
+
+#define RX_NXTDESC_PTR 0x08 /* r */
+#define RX_CURBUF_ADDR 0x09 /* r */
+#define RX_CURBUF_LENGTH 0x0a /* r */
+#define RX_CURDESC_PTR 0x0b /* rw */
+#define RX_TAILDESC_PTR 0x0c /* rw */
+#define RX_CHNL_CTRL 0x0d /* rw */
+/*
+ 0:7 24:31 IRQTimeout
+ 8:15 16:23 IRQCount
+ 16:20 11:15 Reserved
+ 21 10 0
+ 22 9 UseIntOnEnd
+ 23 8 LdIRQCnt
+ 24 7 IRQEn
+ 25:28 3:6 Reserved
+ 29 2 IrqErrEn
+ 30 1 IrqDlyEn
+ 31 0 IrqCoalEn
+ */
+#define RX_IRQ_REG 0x0e /* rw */
+#define IRQ_COAL (1 << 0)
+#define IRQ_DLY (1 << 1)
+#define IRQ_ERR (1 << 2)
+#define IRQ_DMAERR (1 << 7) /* this is not documented ??? */
+/*
+ 0:7 24:31 DltTmrValue
+ 8:15 16:23 ClscCntrValue
+ 16:17 14:15 Reserved
+ 18:21 10:13 ClscCnt
+ 22:23 8:9 DlyCnt
+ 24:28 3::7 Reserved
+*/
+#define RX_CHNL_STS 0x0f /* r */
+#define CHNL_STS_ENGBUSY (1 << 1)
+#define CHNL_STS_EOP (1 << 2)
+#define CHNL_STS_SOP (1 << 3)
+#define CHNL_STS_CMPLT (1 << 4)
+#define CHNL_STS_SOE (1 << 5)
+#define CHNL_STS_IOE (1 << 6)
+#define CHNL_STS_ERR (1 << 7)
+
+#define CHNL_STS_BSYWR (1 << 16)
+#define CHNL_STS_CURPERR (1 << 17)
+#define CHNL_STS_NXTPERR (1 << 18)
+#define CHNL_STS_ADDRERR (1 << 19)
+#define CHNL_STS_CMPERR (1 << 20)
+#define CHNL_STS_TAILERR (1 << 21)
+/*
+ 0:9 22:31 Reserved
+ 10 21 TailPErr
+ 11 20 CmpErr
+ 12 19 AddrErr
+ 13 18 NxtPErr
+ 14 17 CurPErr
+ 15 16 BsyWr
+ 16:23 8:15 Reserved
+ 24 7 Error
+ 25 6 IOE
+ 26 5 SOE
+ 27 4 Cmplt
+ 28 3 SOP
+ 29 2 EOP
+ 30 1 EngBusy
+ 31 0 Reserved
+*/
+
+#define DMA_CONTROL_REG 0x10 /* rw */
+#define DMA_CONTROL_RST (1 << 0)
+#define DMA_TAIL_ENABLE (1 << 2)
+
+/* XPS_LL_TEMAC direct registers definition */
+
+#define XTE_RAF0_OFFSET 0x00
+#define RAF0_RST (1 << 0)
+#define RAF0_MCSTREJ (1 << 1)
+#define RAF0_BCSTREJ (1 << 2)
+#define XTE_TPF0_OFFSET 0x04
+#define XTE_IFGP0_OFFSET 0x08
+#define XTE_ISR0_OFFSET 0x0c
+#define ISR0_HARDACSCMPLT (1 << 0)
+#define ISR0_AUTONEG (1 << 1)
+#define ISR0_RXCMPLT (1 << 2)
+#define ISR0_RXREJ (1 << 3)
+#define ISR0_RXFIFOOVR (1 << 4)
+#define ISR0_TXCMPLT (1 << 5)
+#define ISR0_RXDCMLCK (1 << 6)
+
+#define XTE_IPR0_OFFSET 0x10
+#define XTE_IER0_OFFSET 0x14
+
+#define XTE_MSW0_OFFSET 0x20
+#define XTE_LSW0_OFFSET 0x24
+#define XTE_CTL0_OFFSET 0x28
+#define XTE_RDY0_OFFSET 0x2c
+
+#define XTE_RSE_MIIM_RR_MASK 0x0002
+#define XTE_RSE_MIIM_WR_MASK 0x0004
+#define XTE_RSE_CFG_RR_MASK 0x0020
+#define XTE_RSE_CFG_WR_MASK 0x0040
+#define XTE_RDY0_HARD_ACS_RDY_MASK (0x10000)
+
+/* XPS_LL_TEMAC indirect registers offset definition */
+
+#define XTE_RXC0_OFFSET 0x00000200 /* Rx configuration word 0 */
+#define XTE_RXC1_OFFSET 0x00000240 /* Rx configuration word 1 */
+#define XTE_RXC1_RXRST_MASK (1 << 31) /* Receiver reset */
+#define XTE_RXC1_RXJMBO_MASK (1 << 30) /* Jumbo frame enable */
+#define XTE_RXC1_RXFCS_MASK (1 << 29) /* FCS not stripped */
+#define XTE_RXC1_RXEN_MASK (1 << 28) /* Receiver enable */
+#define XTE_RXC1_RXVLAN_MASK (1 << 27) /* VLAN enable */
+#define XTE_RXC1_RXHD_MASK (1 << 26) /* Half duplex */
+#define XTE_RXC1_RXLT_MASK (1 << 25) /* Length/type check disable */
+
+#define XTE_TXC_OFFSET 0x00000280 /* Tx configuration */
+#define XTE_TXC_TXRST_MASK (1 << 31) /* Transmitter reset */
+#define XTE_TXC_TXJMBO_MASK (1 << 30) /* Jumbo frame enable */
+#define XTE_TXC_TXFCS_MASK (1 << 29) /* Generate FCS */
+#define XTE_TXC_TXEN_MASK (1 << 28) /* Transmitter enable */
+#define XTE_TXC_TXVLAN_MASK (1 << 27) /* VLAN enable */
+#define XTE_TXC_TXHD_MASK (1 << 26) /* Half duplex */
+
+#define XTE_FCC_OFFSET 0x000002C0 /* Flow control config */
+#define XTE_FCC_RXFLO_MASK (1 << 29) /* Rx flow control enable */
+#define XTE_FCC_TXFLO_MASK (1 << 30) /* Tx flow control enable */
+
+#define XTE_EMCFG_OFFSET 0x00000300 /* EMAC configuration */
+#define XTE_EMCFG_LINKSPD_MASK 0xC0000000 /* Link speed */
+#define XTE_EMCFG_HOSTEN_MASK (1 << 26) /* Host interface enable */
+#define XTE_EMCFG_LINKSPD_10 0x00000000 /* 10 Mbit LINKSPD_MASK */
+#define XTE_EMCFG_LINKSPD_100 (1 << 30) /* 100 Mbit LINKSPD_MASK */
+#define XTE_EMCFG_LINKSPD_1000 (1 << 31) /* 1000 Mbit LINKSPD_MASK */
+
+#define XTE_GMIC_OFFSET 0x00000320 /* RGMII/SGMII config */
+#define XTE_MC_OFFSET 0x00000340 /* MDIO configuration */
+#define XTE_UAW0_OFFSET 0x00000380 /* Unicast address word 0 */
+#define XTE_UAW1_OFFSET 0x00000384 /* Unicast address word 1 */
+
+#define XTE_MAW0_OFFSET 0x00000388 /* Multicast addr word 0 */
+#define XTE_MAW1_OFFSET 0x0000038C /* Multicast addr word 1 */
+#define XTE_AFM_OFFSET 0x00000390 /* Promiscuous mode */
+#define XTE_AFM_EPPRM_MASK (1 << 31) /* Promiscuous mode enable */
+
+/* Interrupt Request status */
+#define XTE_TIS_OFFSET 0x000003A0
+#define TIS_FRIS (1 << 0)
+#define TIS_MRIS (1 << 1)
+#define TIS_MWIS (1 << 2)
+#define TIS_ARIS (1 << 3)
+#define TIS_AWIS (1 << 4)
+#define TIS_CRIS (1 << 5)
+#define TIS_CWIS (1 << 6)
+
+#define XTE_TIE_OFFSET 0x000003A4 /* Interrupt enable */
+
+/** MII Mamagement Control register (MGTCR) */
+#define XTE_MGTDR_OFFSET 0x000003B0 /* MII data */
+#define XTE_MIIMAI_OFFSET 0x000003B4 /* MII control */
+
+#define CNTLREG_WRITE_ENABLE_MASK 0x8000
+#define CNTLREG_EMAC1SEL_MASK 0x0400
+#define CNTLREG_ADDRESSCODE_MASK 0x03ff
+
+/* CDMAC descriptor status bit definitions */
+
+#define STS_CTRL_APP0_ERR (1 << 31)
+#define STS_CTRL_APP0_IRQONEND (1 << 30)
+/* undoccumented */
+#define STS_CTRL_APP0_STOPONEND (1 << 29)
+#define STS_CTRL_APP0_CMPLT (1 << 28)
+#define STS_CTRL_APP0_SOP (1 << 27)
+#define STS_CTRL_APP0_EOP (1 << 26)
+#define STS_CTRL_APP0_ENGBUSY (1 << 25)
+/* undocumented */
+#define STS_CTRL_APP0_ENGRST (1 << 24)
+
+#define TX_CONTROL_CALC_CSUM_MASK 1
+
+#define XTE_ALIGN 32
+#define BUFFER_ALIGN(adr) ((XTE_ALIGN - ((u32) adr)) % XTE_ALIGN)
+
+#define MULTICAST_CAM_TABLE_NUM 4
+
+/* TX/RX CURDESC_PTR points to first descriptor */
+/* TX/RX TAILDESC_PTR points to last descriptor in linked list */
+
+/**
+ * struct cdmac_bd - LocalLink buffer descriptor format
+ *
+ * app0 bits:
+ * 0 Error
+ * 1 IrqOnEnd generate an interrupt at completion of DMA op
+ * 2 reserved
+ * 3 completed Current descriptor completed
+ * 4 SOP TX - marks first desc/ RX marks first desct
+ * 5 EOP TX marks last desc/RX marks last desc
+ * 6 EngBusy DMA is processing
+ * 7 reserved
+ * 8:31 application specific
+ */
+struct cdmac_bd {
+ u32 next; /* Physical address of next buffer descriptor */
+ u32 phys;
+ u32 len;
+ u32 app0;
+ u32 app1; /* TX start << 16 | insert */
+ u32 app2; /* TX csum */
+ u32 app3;
+ u32 app4; /* skb for TX length for RX */
+};
+
+struct temac_local {
+ struct net_device *ndev;
+ struct device *dev;
+
+ /* Connection to PHY device */
+ struct phy_device *phy_dev; /* Pointer to PHY device */
+ struct device_node *phy_node;
+
+ /* MDIO bus data */
+ struct mii_bus *mii_bus; /* MII bus reference */
+ int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */
+
+ /* IO registers and IRQs */
+ void __iomem *regs;
+ dcr_host_t sdma_dcrs;
+ int tx_irq;
+ int rx_irq;
+ int emac_num;
+
+ struct sk_buff **rx_skb;
+ spinlock_t rx_lock;
+ struct mutex indirect_mutex;
+ u32 options; /* Current options word */
+ int last_link;
+
+ /* Buffer descriptors */
+ struct cdmac_bd *tx_bd_v;
+ dma_addr_t tx_bd_p;
+ struct cdmac_bd *rx_bd_v;
+ dma_addr_t rx_bd_p;
+ int tx_bd_ci;
+ int tx_bd_next;
+ int tx_bd_tail;
+ int rx_bd_ci;
+};
+
+/* xilinx_temac.c */
+u32 temac_ior(struct temac_local *lp, int offset);
+void temac_iow(struct temac_local *lp, int offset, u32 value);
+int temac_indirect_busywait(struct temac_local *lp);
+u32 temac_indirect_in32(struct temac_local *lp, int reg);
+void temac_indirect_out32(struct temac_local *lp, int reg, u32 value);
+
+
+/* xilinx_temac_mdio.c */
+int temac_mdio_setup(struct temac_local *lp, struct device_node *np);
+void temac_mdio_teardown(struct temac_local *lp);
+
+#endif /* XILINX_LL_TEMAC_H */
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
new file mode 100644
index 000000000000..96e7248876c1
--- /dev/null
+++ b/drivers/net/ll_temac_main.c
@@ -0,0 +1,969 @@
+/*
+ * Driver for Xilinx TEMAC Ethernet device
+ *
+ * Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi
+ * Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. <dhlii@dlasys.net>
+ * Copyright (c) 2008-2009 Secret Lab Technologies Ltd.
+ *
+ * This is a driver for the Xilinx ll_temac ipcore which is often used
+ * in the Virtex and Spartan series of chips.
+ *
+ * Notes:
+ * - The ll_temac hardware uses indirect access for many of the TEMAC
+ * registers, include the MDIO bus. However, indirect access to MDIO
+ * registers take considerably more clock cycles than to TEMAC registers.
+ * MDIO accesses are long, so threads doing them should probably sleep
+ * rather than busywait. However, since only one indirect access can be
+ * in progress at any given time, that means that *all* indirect accesses
+ * could end up sleeping (to wait for an MDIO access to complete).
+ * Fortunately none of the indirect accesses are on the 'hot' path for tx
+ * or rx, so this should be okay.
+ *
+ * TODO:
+ * - Fix driver to work on more than just Virtex5. Right now the driver
+ * assumes that the locallink DMA registers are accessed via DCR
+ * instructions.
+ * - Factor out locallink DMA code into separate driver
+ * - Fix multicast assignment.
+ * - Fix support for hardware checksumming.
+ * - Testing. Lots and lots of testing.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/tcp.h> /* needed for sizeof(tcphdr) */
+#include <linux/udp.h> /* needed for sizeof(udphdr) */
+#include <linux/phy.h>
+#include <linux/in.h>
+#include <linux/io.h>
+#include <linux/ip.h>
+
+#include "ll_temac.h"
+
+#define TX_BD_NUM 64
+#define RX_BD_NUM 128
+
+/* ---------------------------------------------------------------------
+ * Low level register access functions
+ */
+
+u32 temac_ior(struct temac_local *lp, int offset)
+{
+ return in_be32((u32 *)(lp->regs + offset));
+}
+
+void temac_iow(struct temac_local *lp, int offset, u32 value)
+{
+ out_be32((u32 *) (lp->regs + offset), value);
+}
+
+int temac_indirect_busywait(struct temac_local *lp)
+{
+ long end = jiffies + 2;
+
+ while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) {
+ if (end - jiffies <= 0) {
+ WARN_ON(1);
+ return -ETIMEDOUT;
+ }
+ msleep(1);
+ }
+ return 0;
+}
+
+/**
+ * temac_indirect_in32
+ *
+ * lp->indirect_mutex must be held when calling this function
+ */
+u32 temac_indirect_in32(struct temac_local *lp, int reg)
+{
+ u32 val;
+
+ if (temac_indirect_busywait(lp))
+ return -ETIMEDOUT;
+ temac_iow(lp, XTE_CTL0_OFFSET, reg);
+ if (temac_indirect_busywait(lp))
+ return -ETIMEDOUT;
+ val = temac_ior(lp, XTE_LSW0_OFFSET);
+
+ return val;
+}
+
+/**
+ * temac_indirect_out32
+ *
+ * lp->indirect_mutex must be held when calling this function
+ */
+void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
+{
+ if (temac_indirect_busywait(lp))
+ return;
+ temac_iow(lp, XTE_LSW0_OFFSET, value);
+ temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
+}
+
+static u32 temac_dma_in32(struct temac_local *lp, int reg)
+{
+ return dcr_read(lp->sdma_dcrs, reg);
+}
+
+static void temac_dma_out32(struct temac_local *lp, int reg, u32 value)
+{
+ dcr_write(lp->sdma_dcrs, reg, value);
+}
+
+/**
+ * temac_dma_bd_init - Setup buffer descriptor rings
+ */
+static int temac_dma_bd_init(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct sk_buff *skb;
+ int i;
+
+ lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM, GFP_KERNEL);
+ /* allocate the tx and rx ring buffer descriptors. */
+ /* returns a virtual addres and a physical address. */
+ lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent,
+ sizeof(*lp->tx_bd_v) * TX_BD_NUM,
+ &lp->tx_bd_p, GFP_KERNEL);
+ lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent,
+ sizeof(*lp->rx_bd_v) * RX_BD_NUM,
+ &lp->rx_bd_p, GFP_KERNEL);
+
+ memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM);
+ for (i = 0; i < TX_BD_NUM; i++) {
+ lp->tx_bd_v[i].next = lp->tx_bd_p +
+ sizeof(*lp->tx_bd_v) * ((i + 1) % TX_BD_NUM);
+ }
+
+ memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM);
+ for (i = 0; i < RX_BD_NUM; i++) {
+ lp->rx_bd_v[i].next = lp->rx_bd_p +
+ sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM);
+
+ skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE
+ + XTE_ALIGN, GFP_ATOMIC);
+ if (skb == 0) {
+ dev_err(&ndev->dev, "alloc_skb error %d\n", i);
+ return -1;
+ }
+ lp->rx_skb[i] = skb;
+ skb_reserve(skb, BUFFER_ALIGN(skb->data));
+ /* returns physical address of skb->data */
+ lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent,
+ skb->data,
+ XTE_MAX_JUMBO_FRAME_SIZE,
+ DMA_FROM_DEVICE);
+ lp->rx_bd_v[i].len = XTE_MAX_JUMBO_FRAME_SIZE;
+ lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND;
+ }
+
+ temac_dma_out32(lp, TX_CHNL_CTRL, 0x10220400 |
+ CHNL_CTRL_IRQ_EN |
+ CHNL_CTRL_IRQ_DLY_EN |
+ CHNL_CTRL_IRQ_COAL_EN);
+ /* 0x10220483 */
+ /* 0x00100483 */
+ temac_dma_out32(lp, RX_CHNL_CTRL, 0xff010000 |
+ CHNL_CTRL_IRQ_EN |
+ CHNL_CTRL_IRQ_DLY_EN |
+ CHNL_CTRL_IRQ_COAL_EN |
+ CHNL_CTRL_IRQ_IOE);
+ /* 0xff010283 */
+
+ temac_dma_out32(lp, RX_CURDESC_PTR, lp->rx_bd_p);
+ temac_dma_out32(lp, RX_TAILDESC_PTR,
+ lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1)));
+ temac_dma_out32(lp, TX_CURDESC_PTR, lp->tx_bd_p);
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------
+ * net_device_ops
+ */
+
+static int temac_set_mac_address(struct net_device *ndev, void *address)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+
+ if (address)
+ memcpy(ndev->dev_addr, address, ETH_ALEN);
+
+ if (!is_valid_ether_addr(ndev->dev_addr))
+ random_ether_addr(ndev->dev_addr);
+
+ /* set up unicast MAC address filter set its mac address */
+ mutex_lock(&lp->indirect_mutex);
+ temac_indirect_out32(lp, XTE_UAW0_OFFSET,
+ (ndev->dev_addr[0]) |
+ (ndev->dev_addr[1] << 8) |
+ (ndev->dev_addr[2] << 16) |
+ (ndev->dev_addr[3] << 24));
+ /* There are reserved bits in EUAW1
+ * so don't affect them Set MAC bits [47:32] in EUAW1 */
+ temac_indirect_out32(lp, XTE_UAW1_OFFSET,
+ (ndev->dev_addr[4] & 0x000000ff) |
+ (ndev->dev_addr[5] << 8));
+ mutex_unlock(&lp->indirect_mutex);
+
+ return 0;
+}
+
+static void temac_set_multicast_list(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ u32 multi_addr_msw, multi_addr_lsw, val;
+ int i;
+
+ mutex_lock(&lp->indirect_mutex);
+ if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)
+ || ndev->mc_count > MULTICAST_CAM_TABLE_NUM) {
+ /*
+ * We must make the kernel realise we had to move
+ * into promisc mode or we start all out war on
+ * the cable. If it was a promisc request the
+ * flag is already set. If not we assert it.
+ */
+ ndev->flags |= IFF_PROMISC;
+ temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK);
+ dev_info(&ndev->dev, "Promiscuous mode enabled.\n");
+ } else if (ndev->mc_count) {
+ struct dev_mc_list *mclist = ndev->mc_list;
+ for (i = 0; mclist && i < ndev->mc_count; i++) {
+
+ if (i >= MULTICAST_CAM_TABLE_NUM)
+ break;
+ multi_addr_msw = ((mclist->dmi_addr[3] << 24) |
+ (mclist->dmi_addr[2] << 16) |
+ (mclist->dmi_addr[1] << 8) |
+ (mclist->dmi_addr[0]));
+ temac_indirect_out32(lp, XTE_MAW0_OFFSET,
+ multi_addr_msw);
+ multi_addr_lsw = ((mclist->dmi_addr[5] << 8) |
+ (mclist->dmi_addr[4]) | (i << 16));
+ temac_indirect_out32(lp, XTE_MAW1_OFFSET,
+ multi_addr_lsw);
+ mclist = mclist->next;
+ }
+ } else {
+ val = temac_indirect_in32(lp, XTE_AFM_OFFSET);
+ temac_indirect_out32(lp, XTE_AFM_OFFSET,
+ val & ~XTE_AFM_EPPRM_MASK);
+ temac_indirect_out32(lp, XTE_MAW0_OFFSET, 0);
+ temac_indirect_out32(lp, XTE_MAW1_OFFSET, 0);
+ dev_info(&ndev->dev, "Promiscuous mode disabled.\n");
+ }
+ mutex_unlock(&lp->indirect_mutex);
+}
+
+struct temac_option {
+ int flg;
+ u32 opt;
+ u32 reg;
+ u32 m_or;
+ u32 m_and;
+} temac_options[] = {
+ /* Turn on jumbo packet support for both Rx and Tx */
+ {
+ .opt = XTE_OPTION_JUMBO,
+ .reg = XTE_TXC_OFFSET,
+ .m_or = XTE_TXC_TXJMBO_MASK,
+ },
+ {
+ .opt = XTE_OPTION_JUMBO,
+ .reg = XTE_RXC1_OFFSET,
+ .m_or =XTE_RXC1_RXJMBO_MASK,
+ },
+ /* Turn on VLAN packet support for both Rx and Tx */
+ {
+ .opt = XTE_OPTION_VLAN,
+ .reg = XTE_TXC_OFFSET,
+ .m_or =XTE_TXC_TXVLAN_MASK,
+ },
+ {
+ .opt = XTE_OPTION_VLAN,
+ .reg = XTE_RXC1_OFFSET,
+ .m_or =XTE_RXC1_RXVLAN_MASK,
+ },
+ /* Turn on FCS stripping on receive packets */
+ {
+ .opt = XTE_OPTION_FCS_STRIP,
+ .reg = XTE_RXC1_OFFSET,
+ .m_or =XTE_RXC1_RXFCS_MASK,
+ },
+ /* Turn on FCS insertion on transmit packets */
+ {
+ .opt = XTE_OPTION_FCS_INSERT,
+ .reg = XTE_TXC_OFFSET,
+ .m_or =XTE_TXC_TXFCS_MASK,
+ },
+ /* Turn on length/type field checking on receive packets */
+ {
+ .opt = XTE_OPTION_LENTYPE_ERR,
+ .reg = XTE_RXC1_OFFSET,
+ .m_or =XTE_RXC1_RXLT_MASK,
+ },
+ /* Turn on flow control */
+ {
+ .opt = XTE_OPTION_FLOW_CONTROL,
+ .reg = XTE_FCC_OFFSET,
+ .m_or =XTE_FCC_RXFLO_MASK,
+ },
+ /* Turn on flow control */
+ {
+ .opt = XTE_OPTION_FLOW_CONTROL,
+ .reg = XTE_FCC_OFFSET,
+ .m_or =XTE_FCC_TXFLO_MASK,
+ },
+ /* Turn on promiscuous frame filtering (all frames are received ) */
+ {
+ .opt = XTE_OPTION_PROMISC,
+ .reg = XTE_AFM_OFFSET,
+ .m_or =XTE_AFM_EPPRM_MASK,
+ },
+ /* Enable transmitter if not already enabled */
+ {
+ .opt = XTE_OPTION_TXEN,
+ .reg = XTE_TXC_OFFSET,
+ .m_or =XTE_TXC_TXEN_MASK,
+ },
+ /* Enable receiver? */
+ {
+ .opt = XTE_OPTION_RXEN,
+ .reg = XTE_RXC1_OFFSET,
+ .m_or =XTE_RXC1_RXEN_MASK,
+ },
+ {}
+};
+
+/**
+ * temac_setoptions
+ */
+static u32 temac_setoptions(struct net_device *ndev, u32 options)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct temac_option *tp = &temac_options[0];
+ int reg;
+
+ mutex_lock(&lp->indirect_mutex);
+ while (tp->opt) {
+ reg = temac_indirect_in32(lp, tp->reg) & ~tp->m_or;
+ if (options & tp->opt)
+ reg |= tp->m_or;
+ temac_indirect_out32(lp, tp->reg, reg);
+ tp++;
+ }
+ lp->options |= options;
+ mutex_unlock(&lp->indirect_mutex);
+
+ return (0);
+}
+
+/* Initilize temac */
+static void temac_device_reset(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ u32 timeout;
+ u32 val;
+
+ /* Perform a software reset */
+
+ /* 0x300 host enable bit ? */
+ /* reset PHY through control register ?:1 */
+
+ dev_dbg(&ndev->dev, "%s()\n", __func__);
+
+ mutex_lock(&lp->indirect_mutex);
+ /* Reset the receiver and wait for it to finish reset */
+ temac_indirect_out32(lp, XTE_RXC1_OFFSET, XTE_RXC1_RXRST_MASK);
+ timeout = 1000;
+ while (temac_indirect_in32(lp, XTE_RXC1_OFFSET) & XTE_RXC1_RXRST_MASK) {
+ udelay(1);
+ if (--timeout == 0) {
+ dev_err(&ndev->dev,
+ "temac_device_reset RX reset timeout!!\n");
+ break;
+ }
+ }
+
+ /* Reset the transmitter and wait for it to finish reset */
+ temac_indirect_out32(lp, XTE_TXC_OFFSET, XTE_TXC_TXRST_MASK);
+ timeout = 1000;
+ while (temac_indirect_in32(lp, XTE_TXC_OFFSET) & XTE_TXC_TXRST_MASK) {
+ udelay(1);
+ if (--timeout == 0) {
+ dev_err(&ndev->dev,
+ "temac_device_reset TX reset timeout!!\n");
+ break;
+ }
+ }
+
+ /* Disable the receiver */
+ val = temac_indirect_in32(lp, XTE_RXC1_OFFSET);
+ temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK);
+
+ /* Reset Local Link (DMA) */
+ temac_dma_out32(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
+ timeout = 1000;
+ while (temac_dma_in32(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) {
+ udelay(1);
+ if (--timeout == 0) {
+ dev_err(&ndev->dev,
+ "temac_device_reset DMA reset timeout!!\n");
+ break;
+ }
+ }
+ temac_dma_out32(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE);
+
+ temac_dma_bd_init(ndev);
+
+ temac_indirect_out32(lp, XTE_RXC0_OFFSET, 0);
+ temac_indirect_out32(lp, XTE_RXC1_OFFSET, 0);
+ temac_indirect_out32(lp, XTE_TXC_OFFSET, 0);
+ temac_indirect_out32(lp, XTE_FCC_OFFSET, XTE_FCC_RXFLO_MASK);
+
+ mutex_unlock(&lp->indirect_mutex);
+
+ /* Sync default options with HW
+ * but leave receiver and transmitter disabled. */
+ temac_setoptions(ndev,
+ lp->options & ~(XTE_OPTION_TXEN | XTE_OPTION_RXEN));
+
+ temac_set_mac_address(ndev, NULL);
+
+ /* Set address filter table */
+ temac_set_multicast_list(ndev);
+ if (temac_setoptions(ndev, lp->options))
+ dev_err(&ndev->dev, "Error setting TEMAC options\n");
+
+ /* Init Driver variable */
+ ndev->trans_start = 0;
+}
+
+void temac_adjust_link(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct phy_device *phy = lp->phy_dev;
+ u32 mii_speed;
+ int link_state;
+
+ /* hash together the state values to decide if something has changed */
+ link_state = phy->speed | (phy->duplex << 1) | phy->link;
+
+ mutex_lock(&lp->indirect_mutex);
+ if (lp->last_link != link_state) {
+ mii_speed = temac_indirect_in32(lp, XTE_EMCFG_OFFSET);
+ mii_speed &= ~XTE_EMCFG_LINKSPD_MASK;
+
+ switch (phy->speed) {
+ case SPEED_1000: mii_speed |= XTE_EMCFG_LINKSPD_1000; break;
+ case SPEED_100: mii_speed |= XTE_EMCFG_LINKSPD_100; break;
+ case SPEED_10: mii_speed |= XTE_EMCFG_LINKSPD_10; break;
+ }
+
+ /* Write new speed setting out to TEMAC */
+ temac_indirect_out32(lp, XTE_EMCFG_OFFSET, mii_speed);
+ lp->last_link = link_state;
+ phy_print_status(phy);
+ }
+ mutex_unlock(&lp->indirect_mutex);
+}
+
+static void temac_start_xmit_done(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct cdmac_bd *cur_p;
+ unsigned int stat = 0;
+
+ cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
+ stat = cur_p->app0;
+
+ while (stat & STS_CTRL_APP0_CMPLT) {
+ dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len,
+ DMA_TO_DEVICE);
+ if (cur_p->app4)
+ dev_kfree_skb_irq((struct sk_buff *)cur_p->app4);
+ cur_p->app0 = 0;
+
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += cur_p->len;
+
+ lp->tx_bd_ci++;
+ if (lp->tx_bd_ci >= TX_BD_NUM)
+ lp->tx_bd_ci = 0;
+
+ cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
+ stat = cur_p->app0;
+ }
+
+ netif_wake_queue(ndev);
+}
+
+static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct cdmac_bd *cur_p;
+ dma_addr_t start_p, tail_p;
+ int ii;
+ unsigned long num_frag;
+ skb_frag_t *frag;
+
+ num_frag = skb_shinfo(skb)->nr_frags;
+ frag = &skb_shinfo(skb)->frags[0];
+ start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
+ cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+
+ if (cur_p->app0 & STS_CTRL_APP0_CMPLT) {
+ if (!netif_queue_stopped(ndev)) {
+ netif_stop_queue(ndev);
+ return NETDEV_TX_BUSY;
+ }
+ return NETDEV_TX_BUSY;
+ }
+
+ cur_p->app0 = 0;
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ const struct iphdr *ip = ip_hdr(skb);
+ int length = 0, start = 0, insert = 0;
+
+ switch (ip->protocol) {
+ case IPPROTO_TCP:
+ start = sizeof(struct iphdr) + ETH_HLEN;
+ insert = sizeof(struct iphdr) + ETH_HLEN + 16;
+ length = ip->tot_len - sizeof(struct iphdr);
+ break;
+ case IPPROTO_UDP:
+ start = sizeof(struct iphdr) + ETH_HLEN;
+ insert = sizeof(struct iphdr) + ETH_HLEN + 6;
+ length = ip->tot_len - sizeof(struct iphdr);
+ break;
+ default:
+ break;
+ }
+ cur_p->app1 = ((start << 16) | insert);
+ cur_p->app2 = csum_tcpudp_magic(ip->saddr, ip->daddr,
+ length, ip->protocol, 0);
+ skb->data[insert] = 0;
+ skb->data[insert + 1] = 0;
+ }
+ cur_p->app0 |= STS_CTRL_APP0_SOP;
+ cur_p->len = skb_headlen(skb);
+ cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ cur_p->app4 = (unsigned long)skb;
+
+ for (ii = 0; ii < num_frag; ii++) {
+ lp->tx_bd_tail++;
+ if (lp->tx_bd_tail >= TX_BD_NUM)
+ lp->tx_bd_tail = 0;
+
+ cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+ cur_p->phys = dma_map_single(ndev->dev.parent,
+ (void *)page_address(frag->page) +
+ frag->page_offset,
+ frag->size, DMA_TO_DEVICE);
+ cur_p->len = frag->size;
+ cur_p->app0 = 0;
+ frag++;
+ }
+ cur_p->app0 |= STS_CTRL_APP0_EOP;
+
+ tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
+ lp->tx_bd_tail++;
+ if (lp->tx_bd_tail >= TX_BD_NUM)
+ lp->tx_bd_tail = 0;
+
+ /* Kick off the transfer */
+ temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
+
+ return 0;
+}
+
+
+static void ll_temac_recv(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct sk_buff *skb, *new_skb;
+ unsigned int bdstat;
+ struct cdmac_bd *cur_p;
+ dma_addr_t tail_p;
+ int length;
+ unsigned long skb_vaddr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lp->rx_lock, flags);
+
+ tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
+ cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+
+ bdstat = cur_p->app0;
+ while ((bdstat & STS_CTRL_APP0_CMPLT)) {
+
+ skb = lp->rx_skb[lp->rx_bd_ci];
+ length = cur_p->app4;
+
+ skb_vaddr = virt_to_bus(skb->data);
+ dma_unmap_single(ndev->dev.parent, skb_vaddr, length,
+ DMA_FROM_DEVICE);
+
+ skb_put(skb, length);
+ skb->dev = ndev;
+ skb->protocol = eth_type_trans(skb, ndev);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ netif_rx(skb);
+
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += length;
+
+ new_skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN,
+ GFP_ATOMIC);
+ if (new_skb == 0) {
+ dev_err(&ndev->dev, "no memory for new sk_buff\n");
+ spin_unlock_irqrestore(&lp->rx_lock, flags);
+ return;
+ }
+
+ skb_reserve(new_skb, BUFFER_ALIGN(new_skb->data));
+
+ cur_p->app0 = STS_CTRL_APP0_IRQONEND;
+ cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data,
+ XTE_MAX_JUMBO_FRAME_SIZE,
+ DMA_FROM_DEVICE);
+ cur_p->len = XTE_MAX_JUMBO_FRAME_SIZE;
+ lp->rx_skb[lp->rx_bd_ci] = new_skb;
+
+ lp->rx_bd_ci++;
+ if (lp->rx_bd_ci >= RX_BD_NUM)
+ lp->rx_bd_ci = 0;
+
+ cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+ bdstat = cur_p->app0;
+ }
+ temac_dma_out32(lp, RX_TAILDESC_PTR, tail_p);
+
+ spin_unlock_irqrestore(&lp->rx_lock, flags);
+}
+
+static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev)
+{
+ struct net_device *ndev = _ndev;
+ struct temac_local *lp = netdev_priv(ndev);
+ unsigned int status;
+
+ status = temac_dma_in32(lp, TX_IRQ_REG);
+ temac_dma_out32(lp, TX_IRQ_REG, status);
+
+ if (status & (IRQ_COAL | IRQ_DLY))
+ temac_start_xmit_done(lp->ndev);
+ if (status & 0x080)
+ dev_err(&ndev->dev, "DMA error 0x%x\n", status);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev)
+{
+ struct net_device *ndev = _ndev;
+ struct temac_local *lp = netdev_priv(ndev);
+ unsigned int status;
+
+ /* Read and clear the status registers */
+ status = temac_dma_in32(lp, RX_IRQ_REG);
+ temac_dma_out32(lp, RX_IRQ_REG, status);
+
+ if (status & (IRQ_COAL | IRQ_DLY))
+ ll_temac_recv(lp->ndev);
+
+ return IRQ_HANDLED;
+}
+
+static int temac_open(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ int rc;
+
+ dev_dbg(&ndev->dev, "temac_open()\n");
+
+ if (lp->phy_node) {
+ lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node,
+ temac_adjust_link, 0, 0);
+ if (!lp->phy_dev) {
+ dev_err(lp->dev, "of_phy_connect() failed\n");
+ return -ENODEV;
+ }
+
+ phy_start(lp->phy_dev);
+ }
+
+ rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);
+ if (rc)
+ goto err_tx_irq;
+ rc = request_irq(lp->rx_irq, ll_temac_rx_irq, 0, ndev->name, ndev);
+ if (rc)
+ goto err_rx_irq;
+
+ temac_device_reset(ndev);
+ return 0;
+
+ err_rx_irq:
+ free_irq(lp->tx_irq, ndev);
+ err_tx_irq:
+ if (lp->phy_dev)
+ phy_disconnect(lp->phy_dev);
+ lp->phy_dev = NULL;
+ dev_err(lp->dev, "request_irq() failed\n");
+ return rc;
+}
+
+static int temac_stop(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+
+ dev_dbg(&ndev->dev, "temac_close()\n");
+
+ free_irq(lp->tx_irq, ndev);
+ free_irq(lp->rx_irq, ndev);
+
+ if (lp->phy_dev)
+ phy_disconnect(lp->phy_dev);
+ lp->phy_dev = NULL;
+
+ return 0;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void
+temac_poll_controller(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+
+ disable_irq(lp->tx_irq);
+ disable_irq(lp->rx_irq);
+
+ ll_temac_rx_irq(lp->tx_irq, lp);
+ ll_temac_tx_irq(lp->rx_irq, lp);
+
+ enable_irq(lp->tx_irq);
+ enable_irq(lp->rx_irq);
+}
+#endif
+
+static const struct net_device_ops temac_netdev_ops = {
+ .ndo_open = temac_open,
+ .ndo_stop = temac_stop,
+ .ndo_start_xmit = temac_start_xmit,
+ .ndo_set_mac_address = temac_set_mac_address,
+ //.ndo_set_multicast_list = temac_set_multicast_list,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = temac_poll_controller,
+#endif
+};
+
+/* ---------------------------------------------------------------------
+ * SYSFS device attributes
+ */
+static ssize_t temac_show_llink_regs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct temac_local *lp = netdev_priv(ndev);
+ int i, len = 0;
+
+ for (i = 0; i < 0x11; i++)
+ len += sprintf(buf + len, "%.8x%s", temac_dma_in32(lp, i),
+ (i % 8) == 7 ? "\n" : " ");
+ len += sprintf(buf + len, "\n");
+
+ return len;
+}
+
+static DEVICE_ATTR(llink_regs, 0440, temac_show_llink_regs, NULL);
+
+static struct attribute *temac_device_attrs[] = {
+ &dev_attr_llink_regs.attr,
+ NULL,
+};
+
+static const struct attribute_group temac_attr_group = {
+ .attrs = temac_device_attrs,
+};
+
+static int __init
+temac_of_probe(struct of_device *op, const struct of_device_id *match)
+{
+ struct device_node *np;
+ struct temac_local *lp;
+ struct net_device *ndev;
+ const void *addr;
+ int size, rc = 0;
+ unsigned int dcrs;
+
+ /* Init network device structure */
+ ndev = alloc_etherdev(sizeof(*lp));
+ if (!ndev) {
+ dev_err(&op->dev, "could not allocate device.\n");
+ return -ENOMEM;
+ }
+ ether_setup(ndev);
+ dev_set_drvdata(&op->dev, ndev);
+ SET_NETDEV_DEV(ndev, &op->dev);
+ ndev->flags &= ~IFF_MULTICAST; /* clear multicast */
+ ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
+ ndev->netdev_ops = &temac_netdev_ops;
+#if 0
+ ndev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4. */
+ ndev->features |= NETIF_F_HW_CSUM; /* Can checksum all the packets. */
+ ndev->features |= NETIF_F_IPV6_CSUM; /* Can checksum IPV6 TCP/UDP */
+ ndev->features |= NETIF_F_HIGHDMA; /* Can DMA to high memory. */
+ ndev->features |= NETIF_F_HW_VLAN_TX; /* Transmit VLAN hw accel */
+ ndev->features |= NETIF_F_HW_VLAN_RX; /* Receive VLAN hw acceleration */
+ ndev->features |= NETIF_F_HW_VLAN_FILTER; /* Receive VLAN filtering */
+ ndev->features |= NETIF_F_VLAN_CHALLENGED; /* cannot handle VLAN pkts */
+ ndev->features |= NETIF_F_GSO; /* Enable software GSO. */
+ ndev->features |= NETIF_F_MULTI_QUEUE; /* Has multiple TX/RX queues */
+ ndev->features |= NETIF_F_LRO; /* large receive offload */
+#endif
+
+ /* setup temac private info structure */
+ lp = netdev_priv(ndev);
+ lp->ndev = ndev;
+ lp->dev = &op->dev;
+ lp->options = XTE_OPTION_DEFAULTS;
+ spin_lock_init(&lp->rx_lock);
+ mutex_init(&lp->indirect_mutex);
+
+ /* map device registers */
+ lp->regs = of_iomap(op->node, 0);
+ if (!lp->regs) {
+ dev_err(&op->dev, "could not map temac regs.\n");
+ goto nodev;
+ }
+
+ /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
+ np = of_parse_phandle(op->node, "llink-connected", 0);
+ if (!np) {
+ dev_err(&op->dev, "could not find DMA node\n");
+ goto nodev;
+ }
+
+ dcrs = dcr_resource_start(np, 0);
+ if (dcrs == 0) {
+ dev_err(&op->dev, "could not get DMA register address\n");
+ goto nodev;;
+ }
+ lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
+ dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
+
+ lp->rx_irq = irq_of_parse_and_map(np, 0);
+ lp->tx_irq = irq_of_parse_and_map(np, 1);
+ if (!lp->rx_irq || !lp->tx_irq) {
+ dev_err(&op->dev, "could not determine irqs\n");
+ rc = -ENOMEM;
+ goto nodev;
+ }
+
+ of_node_put(np); /* Finished with the DMA node; drop the reference */
+
+ /* Retrieve the MAC address */
+ addr = of_get_property(op->node, "local-mac-address", &size);
+ if ((!addr) || (size != 6)) {
+ dev_err(&op->dev, "could not find MAC address\n");
+ rc = -ENODEV;
+ goto nodev;
+ }
+ temac_set_mac_address(ndev, (void *)addr);
+
+ rc = temac_mdio_setup(lp, op->node);
+ if (rc)
+ dev_warn(&op->dev, "error registering MDIO bus\n");
+
+ lp->phy_node = of_parse_phandle(op->node, "phy-handle", 0);
+ if (lp->phy_node)
+ dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np);
+
+ /* Add the device attributes */
+ rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group);
+ if (rc) {
+ dev_err(lp->dev, "Error creating sysfs files\n");
+ goto nodev;
+ }
+
+ rc = register_netdev(lp->ndev);
+ if (rc) {
+ dev_err(lp->dev, "register_netdev() error (%i)\n", rc);
+ goto err_register_ndev;
+ }
+
+ return 0;
+
+ err_register_ndev:
+ sysfs_remove_group(&lp->dev->kobj, &temac_attr_group);
+ nodev:
+ free_netdev(ndev);
+ ndev = NULL;
+ return rc;
+}
+
+static int __devexit temac_of_remove(struct of_device *op)
+{
+ struct net_device *ndev = dev_get_drvdata(&op->dev);
+ struct temac_local *lp = netdev_priv(ndev);
+
+ temac_mdio_teardown(lp);
+ unregister_netdev(ndev);
+ sysfs_remove_group(&lp->dev->kobj, &temac_attr_group);
+ if (lp->phy_node)
+ of_node_put(lp->phy_node);
+ lp->phy_node = NULL;
+ dev_set_drvdata(&op->dev, NULL);
+ free_netdev(ndev);
+ return 0;
+}
+
+static struct of_device_id temac_of_match[] __devinitdata = {
+ { .compatible = "xlnx,xps-ll-temac-1.01.b", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, temac_of_match);
+
+static struct of_platform_driver temac_of_driver = {
+ .match_table = temac_of_match,
+ .probe = temac_of_probe,
+ .remove = __devexit_p(temac_of_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "xilinx_temac",
+ },
+};
+
+static int __init temac_init(void)
+{
+ return of_register_platform_driver(&temac_of_driver);
+}
+module_init(temac_init);
+
+static void __exit temac_exit(void)
+{
+ of_unregister_platform_driver(&temac_of_driver);
+}
+module_exit(temac_exit);
+
+MODULE_DESCRIPTION("Xilinx LL_TEMAC Ethernet driver");
+MODULE_AUTHOR("Yoshio Kashiwagi");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ll_temac_mdio.c b/drivers/net/ll_temac_mdio.c
new file mode 100644
index 000000000000..da0e462308d5
--- /dev/null
+++ b/drivers/net/ll_temac_mdio.c
@@ -0,0 +1,120 @@
+/*
+ * MDIO bus driver for the Xilinx TEMAC device
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ */
+
+#include <linux/io.h>
+#include <linux/netdevice.h>
+#include <linux/mutex.h>
+#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_mdio.h>
+
+#include "ll_temac.h"
+
+/* ---------------------------------------------------------------------
+ * MDIO Bus functions
+ */
+static int temac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+{
+ struct temac_local *lp = bus->priv;
+ u32 rc;
+
+ /* Write the PHY address to the MIIM Access Initiator register.
+ * When the transfer completes, the PHY register value will appear
+ * in the LSW0 register */
+ mutex_lock(&lp->indirect_mutex);
+ temac_iow(lp, XTE_LSW0_OFFSET, (phy_id << 5) | reg);
+ rc = temac_indirect_in32(lp, XTE_MIIMAI_OFFSET);
+ mutex_unlock(&lp->indirect_mutex);
+
+ dev_dbg(lp->dev, "temac_mdio_read(phy_id=%i, reg=%x) == %x\n",
+ phy_id, reg, rc);
+
+ return rc;
+}
+
+static int temac_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
+{
+ struct temac_local *lp = bus->priv;
+
+ dev_dbg(lp->dev, "temac_mdio_write(phy_id=%i, reg=%x, val=%x)\n",
+ phy_id, reg, val);
+
+ /* First write the desired value into the write data register
+ * and then write the address into the access initiator register
+ */
+ mutex_lock(&lp->indirect_mutex);
+ temac_indirect_out32(lp, XTE_MGTDR_OFFSET, val);
+ temac_indirect_out32(lp, XTE_MIIMAI_OFFSET, (phy_id << 5) | reg);
+ mutex_unlock(&lp->indirect_mutex);
+
+ return 0;
+}
+
+int temac_mdio_setup(struct temac_local *lp, struct device_node *np)
+{
+ struct mii_bus *bus;
+ const u32 *bus_hz;
+ int clk_div;
+ int rc, size;
+ struct resource res;
+
+ /* Calculate a reasonable divisor for the clock rate */
+ clk_div = 0x3f; /* worst-case default setting */
+ bus_hz = of_get_property(np, "clock-frequency", &size);
+ if (bus_hz && size >= sizeof(*bus_hz)) {
+ clk_div = (*bus_hz) / (2500 * 1000 * 2) - 1;
+ if (clk_div < 1)
+ clk_div = 1;
+ if (clk_div > 0x3f)
+ clk_div = 0x3f;
+ }
+
+ /* Enable the MDIO bus by asserting the enable bit and writing
+ * in the clock config */
+ mutex_lock(&lp->indirect_mutex);
+ temac_indirect_out32(lp, XTE_MC_OFFSET, 1 << 6 | clk_div);
+ mutex_unlock(&lp->indirect_mutex);
+
+ bus = mdiobus_alloc();
+ if (!bus)
+ return -ENOMEM;
+
+ of_address_to_resource(np, 0, &res);
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
+ (unsigned long long)res.start);
+ bus->priv = lp;
+ bus->name = "Xilinx TEMAC MDIO";
+ bus->read = temac_mdio_read;
+ bus->write = temac_mdio_write;
+ bus->parent = lp->dev;
+ bus->irq = lp->mdio_irqs; /* preallocated IRQ table */
+
+ lp->mii_bus = bus;
+
+ rc = of_mdiobus_register(bus, np);
+ if (rc)
+ goto err_register;
+
+ mutex_lock(&lp->indirect_mutex);
+ dev_dbg(lp->dev, "MDIO bus registered; MC:%x\n",
+ temac_indirect_in32(lp, XTE_MC_OFFSET));
+ mutex_unlock(&lp->indirect_mutex);
+ return 0;
+
+ err_register:
+ mdiobus_free(bus);
+ return rc;
+}
+
+void temac_mdio_teardown(struct temac_local *lp)
+{
+ mdiobus_unregister(lp->mii_bus);
+ kfree(lp->mii_bus->irq);
+ mdiobus_free(lp->mii_bus);
+ lp->mii_bus = NULL;
+}
+
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index b7d438a367f3..6f71157bea8e 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -62,6 +62,7 @@
struct pcpu_lstats {
unsigned long packets;
unsigned long bytes;
+ unsigned long drops;
};
/*
@@ -71,18 +72,22 @@ struct pcpu_lstats {
static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct pcpu_lstats *pcpu_lstats, *lb_stats;
+ int len;
skb_orphan(skb);
- skb->protocol = eth_type_trans(skb,dev);
+ skb->protocol = eth_type_trans(skb, dev);
/* it's OK to use per_cpu_ptr() because BHs are off */
pcpu_lstats = dev->ml_priv;
lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());
- lb_stats->bytes += skb->len;
- lb_stats->packets++;
- netif_rx(skb);
+ len = skb->len;
+ if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {
+ lb_stats->bytes += len;
+ lb_stats->packets++;
+ } else
+ lb_stats->drops++;
return 0;
}
@@ -93,6 +98,7 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
struct net_device_stats *stats = &dev->stats;
unsigned long bytes = 0;
unsigned long packets = 0;
+ unsigned long drops = 0;
int i;
pcpu_lstats = dev->ml_priv;
@@ -102,11 +108,14 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
lb_stats = per_cpu_ptr(pcpu_lstats, i);
bytes += lb_stats->bytes;
packets += lb_stats->packets;
+ drops += lb_stats->drops;
}
stats->rx_packets = packets;
stats->tx_packets = packets;
- stats->rx_bytes = bytes;
- stats->tx_bytes = bytes;
+ stats->rx_dropped = drops;
+ stats->rx_errors = drops;
+ stats->rx_bytes = bytes;
+ stats->tx_bytes = bytes;
return stats;
}
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index e82aee41d77e..722265920da8 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -599,6 +599,21 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void macb_poll_controller(struct net_device *dev)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ macb_interrupt(dev->irq, dev);
+ local_irq_restore(flags);
+}
+#endif
+
static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct macb *bp = netdev_priv(dev);
@@ -1094,6 +1109,9 @@ static const struct net_device_ops macb_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = eth_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = macb_poll_controller,
+#endif
};
static int __init macb_probe(struct platform_device *pdev)
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index feebbd92aff2..1ad740bc8878 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -94,6 +94,16 @@ static void __mace_set_address(struct net_device *dev, void *addr);
*/
static unsigned char *dummy_buf;
+static const struct net_device_ops mace_netdev_ops = {
+ .ndo_open = mace_open,
+ .ndo_stop = mace_close,
+ .ndo_start_xmit = mace_xmit_start,
+ .ndo_set_multicast_list = mace_set_multicast,
+ .ndo_set_mac_address = mace_set_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
struct device_node *mace = macio_get_of_node(mdev);
@@ -207,11 +217,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
}
}
- dev->open = mace_open;
- dev->stop = mace_close;
- dev->hard_start_xmit = mace_xmit_start;
- dev->set_multicast_list = mace_set_multicast;
- dev->set_mac_address = mace_set_address;
+ dev->netdev_ops = &mace_netdev_ops;
/*
* Most of what is below could be moved to mace_open()
diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c
index 274e99bb63ac..44f3c2896f20 100644
--- a/drivers/net/macmace.c
+++ b/drivers/net/macmace.c
@@ -180,6 +180,17 @@ static void mace_dma_off(struct net_device *dev)
psc_write_word(PSC_ENETWR_CMD + PSC_SET1, 0x1100);
}
+static const struct net_device_ops mace_netdev_ops = {
+ .ndo_open = mace_open,
+ .ndo_stop = mace_close,
+ .ndo_start_xmit = mace_xmit_start,
+ .ndo_tx_timeout = mace_tx_timeout,
+ .ndo_set_multicast_list = mace_set_multicast,
+ .ndo_set_mac_address = mace_set_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* Not really much of a probe. The hardware table tells us if this
* model of Macintrash has a MACE (AV macintoshes)
@@ -240,13 +251,8 @@ static int __devinit mace_probe(struct platform_device *pdev)
return -ENODEV;
}
- dev->open = mace_open;
- dev->stop = mace_close;
- dev->hard_start_xmit = mace_xmit_start;
- dev->tx_timeout = mace_tx_timeout;
+ dev->netdev_ops = &mace_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->set_multicast_list = mace_set_multicast;
- dev->set_mac_address = mace_set_address;
printk(KERN_INFO "%s: 68K MACE, hardware address %pM\n",
dev->name, dev->dev_addr);
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 214a8cf2b708..329cd50d0e29 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -374,36 +374,20 @@ static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
{
const struct macvlan_dev *vlan = netdev_priv(dev);
- struct net_device *lowerdev = vlan->lowerdev;
-
- if (lowerdev->ethtool_ops == NULL ||
- lowerdev->ethtool_ops->get_rx_csum == NULL)
- return 0;
- return lowerdev->ethtool_ops->get_rx_csum(lowerdev);
+ return dev_ethtool_get_rx_csum(vlan->lowerdev);
}
static int macvlan_ethtool_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
const struct macvlan_dev *vlan = netdev_priv(dev);
- struct net_device *lowerdev = vlan->lowerdev;
-
- if (!lowerdev->ethtool_ops ||
- !lowerdev->ethtool_ops->get_settings)
- return -EOPNOTSUPP;
-
- return lowerdev->ethtool_ops->get_settings(lowerdev, cmd);
+ return dev_ethtool_get_settings(vlan->lowerdev, cmd);
}
static u32 macvlan_ethtool_get_flags(struct net_device *dev)
{
const struct macvlan_dev *vlan = netdev_priv(dev);
- struct net_device *lowerdev = vlan->lowerdev;
-
- if (!lowerdev->ethtool_ops ||
- !lowerdev->ethtool_ops->get_flags)
- return 0;
- return lowerdev->ethtool_ops->get_flags(lowerdev);
+ return dev_ethtool_get_flags(vlan->lowerdev);
}
static const struct ethtool_ops macvlan_ethtool_ops = {
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c
new file mode 100644
index 000000000000..66483035f683
--- /dev/null
+++ b/drivers/net/mdio.c
@@ -0,0 +1,414 @@
+/*
+ * mdio.c: Generic support for MDIO-compatible transceivers
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#include <linux/kernel.h>
+#include <linux/capability.h>
+#include <linux/errno.h>
+#include <linux/ethtool.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+
+/**
+ * mdio45_probe - probe for an MDIO (clause 45) device
+ * @mdio: MDIO interface
+ * @prtad: Expected PHY address
+ *
+ * This sets @prtad and @mmds in the MDIO interface if successful.
+ * Returns 0 on success, negative on error.
+ */
+int mdio45_probe(struct mdio_if_info *mdio, int prtad)
+{
+ int mmd, stat2, devs1, devs2;
+
+ /* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY
+ * XS or DTE XS; give up if none is present. */
+ for (mmd = 1; mmd <= 5; mmd++) {
+ /* Is this MMD present? */
+ stat2 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_STAT2);
+ if (stat2 < 0 ||
+ (stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL)
+ continue;
+
+ /* It should tell us about all the other MMDs */
+ devs1 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_DEVS1);
+ devs2 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_DEVS2);
+ if (devs1 < 0 || devs2 < 0)
+ continue;
+
+ mdio->prtad = prtad;
+ mdio->mmds = devs1 | (devs2 << 16);
+ return 0;
+ }
+
+ return -ENODEV;
+}
+EXPORT_SYMBOL(mdio45_probe);
+
+/**
+ * mdio_set_flag - set or clear flag in an MDIO register
+ * @mdio: MDIO interface
+ * @prtad: PHY address
+ * @devad: MMD address
+ * @addr: Register address
+ * @mask: Mask for flag (single bit set)
+ * @sense: New value of flag
+ *
+ * This debounces changes: it does not write the register if the flag
+ * already has the proper value. Returns 0 on success, negative on error.
+ */
+int mdio_set_flag(const struct mdio_if_info *mdio,
+ int prtad, int devad, u16 addr, int mask,
+ bool sense)
+{
+ int old_val = mdio->mdio_read(mdio->dev, prtad, devad, addr);
+ int new_val;
+
+ if (old_val < 0)
+ return old_val;
+ if (sense)
+ new_val = old_val | mask;
+ else
+ new_val = old_val & ~mask;
+ if (old_val == new_val)
+ return 0;
+ return mdio->mdio_write(mdio->dev, prtad, devad, addr, new_val);
+}
+EXPORT_SYMBOL(mdio_set_flag);
+
+/**
+ * mdio_link_ok - is link status up/OK
+ * @mdio: MDIO interface
+ * @mmd_mask: Mask for MMDs to check
+ *
+ * Returns 1 if the PHY reports link status up/OK, 0 otherwise.
+ * @mmd_mask is normally @mdio->mmds, but if loopback is enabled
+ * the MMDs being bypassed should be excluded from the mask.
+ */
+int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmd_mask)
+{
+ int devad, reg;
+
+ if (!mmd_mask) {
+ /* Use absence of XGMII faults in lieu of link state */
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad,
+ MDIO_MMD_PHYXS, MDIO_STAT2);
+ return reg >= 0 && !(reg & MDIO_STAT2_RXFAULT);
+ }
+
+ for (devad = 0; mmd_mask; devad++) {
+ if (mmd_mask & (1 << devad)) {
+ mmd_mask &= ~(1 << devad);
+
+ /* Read twice because link state is latched and a
+ * read moves the current state into the register */
+ mdio->mdio_read(mdio->dev, mdio->prtad,
+ devad, MDIO_STAT1);
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad,
+ devad, MDIO_STAT1);
+ if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
+ return false;
+ }
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(mdio45_links_ok);
+
+/**
+ * mdio45_nway_restart - restart auto-negotiation for this interface
+ * @mdio: MDIO interface
+ *
+ * Returns 0 on success, negative on error.
+ */
+int mdio45_nway_restart(const struct mdio_if_info *mdio)
+{
+ if (!(mdio->mmds & MDIO_DEVS_AN))
+ return -EOPNOTSUPP;
+
+ mdio_set_flag(mdio, mdio->prtad, MDIO_MMD_AN, MDIO_CTRL1,
+ MDIO_AN_CTRL1_RESTART, true);
+ return 0;
+}
+EXPORT_SYMBOL(mdio45_nway_restart);
+
+static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr)
+{
+ u32 result = 0;
+ int reg;
+
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, addr);
+ if (reg & ADVERTISE_10HALF)
+ result |= ADVERTISED_10baseT_Half;
+ if (reg & ADVERTISE_10FULL)
+ result |= ADVERTISED_10baseT_Full;
+ if (reg & ADVERTISE_100HALF)
+ result |= ADVERTISED_100baseT_Half;
+ if (reg & ADVERTISE_100FULL)
+ result |= ADVERTISED_100baseT_Full;
+ return result;
+}
+
+/**
+ * mdio45_ethtool_gset_npage - get settings for ETHTOOL_GSET
+ * @mdio: MDIO interface
+ * @ecmd: Ethtool request structure
+ * @npage_adv: Modes currently advertised on next pages
+ * @npage_lpa: Modes advertised by link partner on next pages
+ *
+ * Since the CSRs for auto-negotiation using next pages are not fully
+ * standardised, this function does not attempt to decode them. The
+ * caller must pass them in.
+ */
+void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
+ struct ethtool_cmd *ecmd,
+ u32 npage_adv, u32 npage_lpa)
+{
+ int reg;
+
+ ecmd->transceiver = XCVR_INTERNAL;
+ ecmd->phy_address = mdio->prtad;
+ ecmd->mdio_support =
+ mdio->mode_support & (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22);
+
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_CTRL2);
+ switch (reg & MDIO_PMA_CTRL2_TYPE) {
+ case MDIO_PMA_CTRL2_10GBT:
+ case MDIO_PMA_CTRL2_1000BT:
+ case MDIO_PMA_CTRL2_100BTX:
+ case MDIO_PMA_CTRL2_10BT:
+ ecmd->port = PORT_TP;
+ ecmd->supported = SUPPORTED_TP;
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_SPEED);
+ if (reg & MDIO_SPEED_10G)
+ ecmd->supported |= SUPPORTED_10000baseT_Full;
+ if (reg & MDIO_PMA_SPEED_1000)
+ ecmd->supported |= (SUPPORTED_1000baseT_Full |
+ SUPPORTED_1000baseT_Half);
+ if (reg & MDIO_PMA_SPEED_100)
+ ecmd->supported |= (SUPPORTED_100baseT_Full |
+ SUPPORTED_100baseT_Half);
+ if (reg & MDIO_PMA_SPEED_10)
+ ecmd->supported |= (SUPPORTED_10baseT_Full |
+ SUPPORTED_10baseT_Half);
+ ecmd->advertising = ADVERTISED_TP;
+ break;
+
+ case MDIO_PMA_CTRL2_10GBCX4:
+ ecmd->port = PORT_OTHER;
+ ecmd->supported = 0;
+ ecmd->advertising = 0;
+ break;
+
+ case MDIO_PMA_CTRL2_10GBKX4:
+ case MDIO_PMA_CTRL2_10GBKR:
+ case MDIO_PMA_CTRL2_1000BKX:
+ ecmd->port = PORT_OTHER;
+ ecmd->supported = SUPPORTED_Backplane;
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_PMA_EXTABLE);
+ if (reg & MDIO_PMA_EXTABLE_10GBKX4)
+ ecmd->supported |= SUPPORTED_10000baseKX4_Full;
+ if (reg & MDIO_PMA_EXTABLE_10GBKR)
+ ecmd->supported |= SUPPORTED_10000baseKR_Full;
+ if (reg & MDIO_PMA_EXTABLE_1000BKX)
+ ecmd->supported |= SUPPORTED_1000baseKX_Full;
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_PMA_10GBR_FECABLE);
+ if (reg & MDIO_PMA_10GBR_FECABLE_ABLE)
+ ecmd->supported |= SUPPORTED_10000baseR_FEC;
+ ecmd->advertising = ADVERTISED_Backplane;
+ break;
+
+ /* All the other defined modes are flavours of optical */
+ default:
+ ecmd->port = PORT_FIBRE;
+ ecmd->supported = SUPPORTED_FIBRE;
+ ecmd->advertising = ADVERTISED_FIBRE;
+ break;
+ }
+
+ if (mdio->mmds & MDIO_DEVS_AN) {
+ ecmd->supported |= SUPPORTED_Autoneg;
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN,
+ MDIO_CTRL1);
+ if (reg & MDIO_AN_CTRL1_ENABLE) {
+ ecmd->autoneg = AUTONEG_ENABLE;
+ ecmd->advertising |=
+ ADVERTISED_Autoneg |
+ mdio45_get_an(mdio, MDIO_AN_ADVERTISE) |
+ npage_adv;
+ } else {
+ ecmd->autoneg = AUTONEG_DISABLE;
+ }
+ } else {
+ ecmd->autoneg = AUTONEG_DISABLE;
+ }
+
+ if (ecmd->autoneg) {
+ u32 modes = 0;
+ int an_stat = mdio->mdio_read(mdio->dev, mdio->prtad,
+ MDIO_MMD_AN, MDIO_STAT1);
+
+ /* If AN is complete and successful, report best common
+ * mode, otherwise report best advertised mode. */
+ if (an_stat & MDIO_AN_STAT1_COMPLETE) {
+ ecmd->lp_advertising =
+ mdio45_get_an(mdio, MDIO_AN_LPA) | npage_lpa;
+ if (an_stat & MDIO_AN_STAT1_LPABLE)
+ ecmd->lp_advertising |= ADVERTISED_Autoneg;
+ modes = ecmd->advertising & ecmd->lp_advertising;
+ }
+ if ((modes & ~ADVERTISED_Autoneg) == 0)
+ modes = ecmd->advertising;
+
+ if (modes & (ADVERTISED_10000baseT_Full |
+ ADVERTISED_10000baseKX4_Full |
+ ADVERTISED_10000baseKR_Full)) {
+ ecmd->speed = SPEED_10000;
+ ecmd->duplex = DUPLEX_FULL;
+ } else if (modes & (ADVERTISED_1000baseT_Full |
+ ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseKX_Full)) {
+ ecmd->speed = SPEED_1000;
+ ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half);
+ } else if (modes & (ADVERTISED_100baseT_Full |
+ ADVERTISED_100baseT_Half)) {
+ ecmd->speed = SPEED_100;
+ ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
+ } else {
+ ecmd->speed = SPEED_10;
+ ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
+ }
+ } else {
+ /* Report forced settings */
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_CTRL1);
+ ecmd->speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) *
+ ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10));
+ ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX ||
+ ecmd->speed == SPEED_10000);
+ }
+}
+EXPORT_SYMBOL(mdio45_ethtool_gset_npage);
+
+/**
+ * mdio45_ethtool_spauseparam_an - set auto-negotiated pause parameters
+ * @mdio: MDIO interface
+ * @ecmd: Ethtool request structure
+ *
+ * This function assumes that the PHY has an auto-negotiation MMD. It
+ * will enable and disable advertising of flow control as appropriate.
+ */
+void mdio45_ethtool_spauseparam_an(const struct mdio_if_info *mdio,
+ const struct ethtool_pauseparam *ecmd)
+{
+ int adv, old_adv;
+
+ WARN_ON(!(mdio->mmds & MDIO_DEVS_AN));
+
+ old_adv = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN,
+ MDIO_AN_ADVERTISE);
+ adv = old_adv & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
+ if (ecmd->autoneg)
+ adv |= mii_advertise_flowctrl(
+ (ecmd->rx_pause ? FLOW_CTRL_RX : 0) |
+ (ecmd->tx_pause ? FLOW_CTRL_TX : 0));
+ if (adv != old_adv) {
+ mdio->mdio_write(mdio->dev, mdio->prtad, MDIO_MMD_AN,
+ MDIO_AN_ADVERTISE, adv);
+ mdio45_nway_restart(mdio);
+ }
+}
+EXPORT_SYMBOL(mdio45_ethtool_spauseparam_an);
+
+/**
+ * mdio_mii_ioctl - MII ioctl interface for MDIO (clause 22 or 45) PHYs
+ * @mdio: MDIO interface
+ * @mii_data: MII ioctl data structure
+ * @cmd: MII ioctl command
+ *
+ * Returns 0 on success, negative on error.
+ */
+int mdio_mii_ioctl(const struct mdio_if_info *mdio,
+ struct mii_ioctl_data *mii_data, int cmd)
+{
+ int prtad, devad;
+ u16 addr = mii_data->reg_num;
+
+ /* Validate/convert cmd to one of SIOC{G,S}MIIREG */
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ if (mdio->prtad == MDIO_PRTAD_NONE)
+ return -EOPNOTSUPP;
+ mii_data->phy_id = mdio->prtad;
+ cmd = SIOCGMIIREG;
+ break;
+ case SIOCGMIIREG:
+ break;
+ case SIOCSMIIREG:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ /* Validate/convert phy_id */
+ if ((mdio->mode_support & MDIO_SUPPORTS_C45) &&
+ mdio_phy_id_is_c45(mii_data->phy_id)) {
+ prtad = mdio_phy_id_prtad(mii_data->phy_id);
+ devad = mdio_phy_id_devad(mii_data->phy_id);
+ } else if ((mdio->mode_support & MDIO_SUPPORTS_C22) &&
+ mii_data->phy_id < 0x20) {
+ prtad = mii_data->phy_id;
+ devad = MDIO_DEVAD_NONE;
+ addr &= 0x1f;
+ } else if ((mdio->mode_support & MDIO_EMULATE_C22) &&
+ mdio->prtad != MDIO_PRTAD_NONE &&
+ mii_data->phy_id == mdio->prtad) {
+ /* Remap commonly-used MII registers. */
+ prtad = mdio->prtad;
+ switch (addr) {
+ case MII_BMCR:
+ case MII_BMSR:
+ case MII_PHYSID1:
+ case MII_PHYSID2:
+ devad = __ffs(mdio->mmds);
+ break;
+ case MII_ADVERTISE:
+ case MII_LPA:
+ if (!(mdio->mmds & MDIO_DEVS_AN))
+ return -EINVAL;
+ devad = MDIO_MMD_AN;
+ if (addr == MII_ADVERTISE)
+ addr = MDIO_AN_ADVERTISE;
+ else
+ addr = MDIO_AN_LPA;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ return -EINVAL;
+ }
+
+ if (cmd == SIOCGMIIREG) {
+ int rc = mdio->mdio_read(mdio->dev, prtad, devad, addr);
+ if (rc < 0)
+ return rc;
+ mii_data->val_out = rc;
+ return 0;
+ } else {
+ return mdio->mdio_write(mdio->dev, prtad, devad, addr,
+ mii_data->val_in);
+ }
+}
+EXPORT_SYMBOL(mdio_mii_ioctl);
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index aa08987f6e81..46ffdb464ac4 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -769,9 +769,17 @@ static int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
}
}
-/*
- * Return statistics to the caller
- */
+static const struct net_device_ops meth_netdev_ops = {
+ .ndo_open = meth_open,
+ .ndo_stop = meth_release,
+ .ndo_start_xmit = meth_tx,
+ .ndo_do_ioctl = meth_ioctl,
+ .ndo_tx_timeout = meth_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
/*
* The init function.
*/
@@ -785,16 +793,10 @@ static int __init meth_probe(struct platform_device *pdev)
if (!dev)
return -ENOMEM;
- dev->open = meth_open;
- dev->stop = meth_release;
- dev->hard_start_xmit = meth_tx;
- dev->do_ioctl = meth_ioctl;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = meth_tx_timeout;
- dev->watchdog_timeo = timeout;
-#endif
- dev->irq = MACE_ETHERNET_IRQ;
- dev->base_addr = (unsigned long)&mace->eth;
+ dev->netdev_ops = &meth_netdev_ops;
+ dev->watchdog_timeo = timeout;
+ dev->irq = MACE_ETHERNET_IRQ;
+ dev->base_addr = (unsigned long)&mace->eth;
memcpy(dev->dev_addr, o2meth_eaddr, 6);
priv = netdev_priv(dev);
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index 92056051f269..d81a5d22a3a9 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -31,7 +31,27 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
+
+static u32 mii_get_an(struct mii_if_info *mii, u16 addr)
+{
+ u32 result = 0;
+ int advert;
+
+ advert = mii->mdio_read(mii->dev, mii->phy_id, addr);
+ if (advert & LPA_LPACK)
+ result |= ADVERTISED_Autoneg;
+ if (advert & ADVERTISE_10HALF)
+ result |= ADVERTISED_10baseT_Half;
+ if (advert & ADVERTISE_10FULL)
+ result |= ADVERTISED_10baseT_Full;
+ if (advert & ADVERTISE_100HALF)
+ result |= ADVERTISED_100baseT_Half;
+ if (advert & ADVERTISE_100FULL)
+ result |= ADVERTISED_100baseT_Full;
+
+ return result;
+}
/**
* mii_ethtool_gset - get settings that are specified in @ecmd
@@ -43,8 +63,8 @@
int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
{
struct net_device *dev = mii->dev;
- u32 advert, bmcr, lpa, nego;
- u32 advert2 = 0, bmcr2 = 0, lpa2 = 0;
+ u16 bmcr, bmsr, ctrl1000 = 0, stat1000 = 0;
+ u32 nego;
ecmd->supported =
(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
@@ -62,50 +82,51 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
/* this isn't fully supported at higher layers */
ecmd->phy_address = mii->phy_id;
+ ecmd->mdio_support = MDIO_SUPPORTS_C22;
ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
- advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
- if (mii->supports_gmii)
- advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
-
- if (advert & ADVERTISE_10HALF)
- ecmd->advertising |= ADVERTISED_10baseT_Half;
- if (advert & ADVERTISE_10FULL)
- ecmd->advertising |= ADVERTISED_10baseT_Full;
- if (advert & ADVERTISE_100HALF)
- ecmd->advertising |= ADVERTISED_100baseT_Half;
- if (advert & ADVERTISE_100FULL)
- ecmd->advertising |= ADVERTISED_100baseT_Full;
- if (advert2 & ADVERTISE_1000HALF)
- ecmd->advertising |= ADVERTISED_1000baseT_Half;
- if (advert2 & ADVERTISE_1000FULL)
- ecmd->advertising |= ADVERTISED_1000baseT_Full;
bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
- lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA);
+ bmsr = mii->mdio_read(dev, mii->phy_id, MII_BMSR);
if (mii->supports_gmii) {
- bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
- lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
+ ctrl1000 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
+ stat1000 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
}
if (bmcr & BMCR_ANENABLE) {
ecmd->advertising |= ADVERTISED_Autoneg;
ecmd->autoneg = AUTONEG_ENABLE;
- nego = mii_nway_result(advert & lpa);
- if ((bmcr2 & (ADVERTISE_1000HALF | ADVERTISE_1000FULL)) &
- (lpa2 >> 2))
+ ecmd->advertising |= mii_get_an(mii, MII_ADVERTISE);
+ if (ctrl1000 & ADVERTISE_1000HALF)
+ ecmd->advertising |= ADVERTISED_1000baseT_Half;
+ if (ctrl1000 & ADVERTISE_1000FULL)
+ ecmd->advertising |= ADVERTISED_1000baseT_Full;
+
+ if (bmsr & BMSR_ANEGCOMPLETE) {
+ ecmd->lp_advertising = mii_get_an(mii, MII_LPA);
+ if (stat1000 & LPA_1000HALF)
+ ecmd->lp_advertising |=
+ ADVERTISED_1000baseT_Half;
+ if (stat1000 & LPA_1000FULL)
+ ecmd->lp_advertising |=
+ ADVERTISED_1000baseT_Full;
+ } else {
+ ecmd->lp_advertising = 0;
+ }
+
+ nego = ecmd->advertising & ecmd->lp_advertising;
+
+ if (nego & (ADVERTISED_1000baseT_Full |
+ ADVERTISED_1000baseT_Half)) {
ecmd->speed = SPEED_1000;
- else if (nego == LPA_100FULL || nego == LPA_100HALF)
+ ecmd->duplex = !!(nego & ADVERTISED_1000baseT_Full);
+ } else if (nego & (ADVERTISED_100baseT_Full |
+ ADVERTISED_100baseT_Half)) {
ecmd->speed = SPEED_100;
- else
- ecmd->speed = SPEED_10;
- if ((lpa2 & LPA_1000FULL) || nego == LPA_100FULL ||
- nego == LPA_10FULL) {
- ecmd->duplex = DUPLEX_FULL;
- mii->full_duplex = 1;
+ ecmd->duplex = !!(nego & ADVERTISED_100baseT_Full);
} else {
- ecmd->duplex = DUPLEX_HALF;
- mii->full_duplex = 0;
+ ecmd->speed = SPEED_10;
+ ecmd->duplex = !!(nego & ADVERTISED_10baseT_Full);
}
} else {
ecmd->autoneg = AUTONEG_DISABLE;
@@ -116,6 +137,8 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
}
+ mii->full_duplex = ecmd->duplex;
+
/* ignore maxtxpkt, maxrxpkt for now */
return 0;
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 664835b822fb..b3b9a147d09a 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -237,6 +237,16 @@ static void mipsnet_set_mclist(struct net_device *dev)
{
}
+static const struct net_device_ops mipsnet_netdev_ops = {
+ .ndo_open = mipsnet_open,
+ .ndo_stop = mipsnet_close,
+ .ndo_start_xmit = mipsnet_xmit,
+ .ndo_set_multicast_list = mipsnet_set_mclist,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int __init mipsnet_probe(struct platform_device *dev)
{
struct net_device *netdev;
@@ -250,10 +260,7 @@ static int __init mipsnet_probe(struct platform_device *dev)
platform_set_drvdata(dev, netdev);
- netdev->open = mipsnet_open;
- netdev->stop = mipsnet_close;
- netdev->hard_start_xmit = mipsnet_xmit;
- netdev->set_multicast_list = mipsnet_set_mclist;
+ netdev->netdev_ops = &mipsnet_netdev_ops;
/*
* TODO: probe for these or load them from PARAM
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 7942c4d3cd88..9ee873e872b3 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -951,7 +951,6 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv,
if (err) {
mlx4_err(mdev, "Failed to allocate qp #%d\n", qpn);
goto out;
- return err;
}
qp->event = mlx4_en_sqp_event;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index a400d7115f78..d5838528791f 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -88,7 +88,24 @@ static char mv643xx_eth_driver_version[] = "1.4";
#define MAC_ADDR_LOW 0x0014
#define MAC_ADDR_HIGH 0x0018
#define SDMA_CONFIG 0x001c
+#define TX_BURST_SIZE_16_64BIT 0x01000000
+#define TX_BURST_SIZE_4_64BIT 0x00800000
+#define BLM_TX_NO_SWAP 0x00000020
+#define BLM_RX_NO_SWAP 0x00000010
+#define RX_BURST_SIZE_16_64BIT 0x00000008
+#define RX_BURST_SIZE_4_64BIT 0x00000004
#define PORT_SERIAL_CONTROL 0x003c
+#define SET_MII_SPEED_TO_100 0x01000000
+#define SET_GMII_SPEED_TO_1000 0x00800000
+#define SET_FULL_DUPLEX_MODE 0x00200000
+#define MAX_RX_PACKET_9700BYTE 0x000a0000
+#define DISABLE_AUTO_NEG_SPEED_GMII 0x00002000
+#define DO_NOT_FORCE_LINK_FAIL 0x00000400
+#define SERIAL_PORT_CONTROL_RESERVED 0x00000200
+#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL 0x00000008
+#define DISABLE_AUTO_NEG_FOR_DUPLEX 0x00000004
+#define FORCE_LINK_PASS 0x00000002
+#define SERIAL_PORT_ENABLE 0x00000001
#define PORT_STATUS 0x0044
#define TX_FIFO_EMPTY 0x00000400
#define TX_IN_PROGRESS 0x00000080
@@ -106,7 +123,9 @@ static char mv643xx_eth_driver_version[] = "1.4";
#define TX_BW_BURST 0x005c
#define INT_CAUSE 0x0060
#define INT_TX_END 0x07f80000
+#define INT_TX_END_0 0x00080000
#define INT_RX 0x000003fc
+#define INT_RX_0 0x00000004
#define INT_EXT 0x00000002
#define INT_CAUSE_EXT 0x0064
#define INT_EXT_LINK_PHY 0x00110000
@@ -135,15 +154,8 @@ static char mv643xx_eth_driver_version[] = "1.4";
/*
- * SDMA configuration register.
+ * SDMA configuration register default value.
*/
-#define RX_BURST_SIZE_4_64BIT (2 << 1)
-#define RX_BURST_SIZE_16_64BIT (4 << 1)
-#define BLM_RX_NO_SWAP (1 << 4)
-#define BLM_TX_NO_SWAP (1 << 5)
-#define TX_BURST_SIZE_4_64BIT (2 << 22)
-#define TX_BURST_SIZE_16_64BIT (4 << 22)
-
#if defined(__BIG_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
(RX_BURST_SIZE_4_64BIT | \
@@ -160,22 +172,11 @@ static char mv643xx_eth_driver_version[] = "1.4";
/*
- * Port serial control register.
+ * Misc definitions.
*/
-#define SET_MII_SPEED_TO_100 (1 << 24)
-#define SET_GMII_SPEED_TO_1000 (1 << 23)
-#define SET_FULL_DUPLEX_MODE (1 << 21)
-#define MAX_RX_PACKET_9700BYTE (5 << 17)
-#define DISABLE_AUTO_NEG_SPEED_GMII (1 << 13)
-#define DO_NOT_FORCE_LINK_FAIL (1 << 10)
-#define SERIAL_PORT_CONTROL_RESERVED (1 << 9)
-#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL (1 << 3)
-#define DISABLE_AUTO_NEG_FOR_DUPLEX (1 << 2)
-#define FORCE_LINK_PASS (1 << 1)
-#define SERIAL_PORT_ENABLE (1 << 0)
-
-#define DEFAULT_RX_QUEUE_SIZE 128
-#define DEFAULT_TX_QUEUE_SIZE 256
+#define DEFAULT_RX_QUEUE_SIZE 128
+#define DEFAULT_TX_QUEUE_SIZE 256
+#define SKB_DMA_REALIGN ((PAGE_SIZE - NET_SKB_PAD) % SMP_CACHE_BYTES)
/*
@@ -393,6 +394,7 @@ struct mv643xx_eth_private {
struct work_struct tx_timeout_task;
struct napi_struct napi;
+ u32 int_mask;
u8 oom;
u8 work_link;
u8 work_tx;
@@ -651,23 +653,20 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
refilled = 0;
while (refilled < budget && rxq->rx_desc_count < rxq->rx_ring_size) {
struct sk_buff *skb;
- int unaligned;
int rx;
struct rx_desc *rx_desc;
skb = __skb_dequeue(&mp->rx_recycle);
if (skb == NULL)
- skb = dev_alloc_skb(mp->skb_size +
- dma_get_cache_alignment() - 1);
+ skb = dev_alloc_skb(mp->skb_size);
if (skb == NULL) {
mp->oom = 1;
goto oom;
}
- unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);
- if (unaligned)
- skb_reserve(skb, dma_get_cache_alignment() - unaligned);
+ if (SKB_DMA_REALIGN)
+ skb_reserve(skb, SKB_DMA_REALIGN);
refilled++;
rxq->rx_desc_count++;
@@ -966,8 +965,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
if (skb != NULL) {
if (skb_queue_len(&mp->rx_recycle) <
mp->rx_ring_size &&
- skb_recycle_check(skb, mp->skb_size +
- dma_get_cache_alignment() - 1))
+ skb_recycle_check(skb, mp->skb_size))
__skb_queue_head(&mp->rx_recycle, skb);
else
dev_kfree_skb(skb);
@@ -1807,7 +1805,6 @@ static void mv643xx_eth_program_multicast_filter(struct net_device *dev)
if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
int port_num;
u32 accept;
- int i;
oom:
port_num = mp->port_num;
@@ -2064,15 +2061,16 @@ static int mv643xx_eth_collect_events(struct mv643xx_eth_private *mp)
u32 int_cause;
u32 int_cause_ext;
- int_cause = rdlp(mp, INT_CAUSE) & (INT_TX_END | INT_RX | INT_EXT);
+ int_cause = rdlp(mp, INT_CAUSE) & mp->int_mask;
if (int_cause == 0)
return 0;
int_cause_ext = 0;
- if (int_cause & INT_EXT)
+ if (int_cause & INT_EXT) {
+ int_cause &= ~INT_EXT;
int_cause_ext = rdlp(mp, INT_CAUSE_EXT);
+ }
- int_cause &= INT_TX_END | INT_RX;
if (int_cause) {
wrlp(mp, INT_CAUSE, ~int_cause);
mp->work_tx_end |= ((int_cause & INT_TX_END) >> 19) &
@@ -2179,6 +2177,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
if (mp->work_link) {
mp->work_link = 0;
handle_link_event(mp);
+ work_done++;
continue;
}
@@ -2217,7 +2216,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
if (mp->oom)
mod_timer(&mp->rx_oom, jiffies + (HZ / 10));
napi_complete(napi);
- wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+ wrlp(mp, INT_MASK, mp->int_mask);
}
return work_done;
@@ -2338,6 +2337,14 @@ static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp)
* size field are ignored by the hardware.
*/
mp->skb_size = (skb_size + 7) & ~7;
+
+ /*
+ * If NET_SKB_PAD is smaller than a cache line,
+ * netdev_alloc_skb() will cause skb->data to be misaligned
+ * to a cache line boundary. If this is the case, include
+ * some extra space to allow re-aligning the data area.
+ */
+ mp->skb_size += SKB_DMA_REALIGN;
}
static int mv643xx_eth_open(struct net_device *dev)
@@ -2363,6 +2370,8 @@ static int mv643xx_eth_open(struct net_device *dev)
skb_queue_head_init(&mp->rx_recycle);
+ mp->int_mask = INT_EXT;
+
for (i = 0; i < mp->rxq_count; i++) {
err = rxq_init(mp, i);
if (err) {
@@ -2372,6 +2381,7 @@ static int mv643xx_eth_open(struct net_device *dev)
}
rxq_refill(mp->rxq + i, INT_MAX);
+ mp->int_mask |= INT_RX_0 << i;
}
if (mp->oom) {
@@ -2386,12 +2396,13 @@ static int mv643xx_eth_open(struct net_device *dev)
txq_deinit(mp->txq + i);
goto out_free;
}
+ mp->int_mask |= INT_TX_END_0 << i;
}
port_start(mp);
wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX);
- wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+ wrlp(mp, INT_MASK, mp->int_mask);
return 0;
@@ -2535,7 +2546,7 @@ static void mv643xx_eth_netpoll(struct net_device *dev)
mv643xx_eth_irq(dev->irq, dev);
- wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+ wrlp(mp, INT_MASK, mp->int_mask);
}
#endif
diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c
index 435e5a847c43..93c709d63e2f 100644
--- a/drivers/net/mvme147.c
+++ b/drivers/net/mvme147.c
@@ -57,6 +57,17 @@ typedef void (*writerap_t)(void *, unsigned short);
typedef void (*writerdp_t)(void *, unsigned short);
typedef unsigned short (*readrdp_t)(void *);
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = m147lance_open,
+ .ndo_stop = m147lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_multicast_list = lance_set_multicast,
+ .ndo_tx_timeout = lance_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
/* Initialise the one and only on-board 7990 */
struct net_device * __init mvme147lance_probe(int unit)
{
@@ -81,11 +92,7 @@ struct net_device * __init mvme147lance_probe(int unit)
/* Fill the dev fields */
dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
- dev->open = &m147lance_open;
- dev->stop = &m147lance_close;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->set_multicast_list = &lance_set_multicast;
- dev->tx_timeout = &lance_tx_timeout;
+ dev->netdev_ops = &lance_netdev_ops;
dev->dma = 0;
addr=(u_long *)ETHERNET_ADDRESS;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index f2c4a665e93f..140794a8d56a 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.4.4-1.401"
+#define MYRI10GE_VERSION_STR "1.4.4-1.412"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -255,6 +255,7 @@ struct myri10ge_priv {
u32 read_write_dma;
u32 link_changes;
u32 msg_enable;
+ unsigned int board_number;
};
static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat";
@@ -266,6 +267,13 @@ static char *myri10ge_fw_name = NULL;
module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name");
+#define MYRI10GE_MAX_BOARDS 8
+static char *myri10ge_fw_names[MYRI10GE_MAX_BOARDS] =
+ {[0 ... (MYRI10GE_MAX_BOARDS - 1)] = NULL };
+module_param_array_named(myri10ge_fw_names, myri10ge_fw_names, charp, NULL,
+ 0444);
+MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image names per board");
+
static int myri10ge_ecrc_enable = 1;
module_param(myri10ge_ecrc_enable, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E");
@@ -361,6 +369,8 @@ static inline void put_be32(__be32 val, __be32 __iomem * p)
__raw_writel((__force __u32) val, (__force void __iomem *)p);
}
+static struct net_device_stats *myri10ge_get_stats(struct net_device *dev);
+
static int
myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
struct myri10ge_cmd *data, int atomic)
@@ -1686,7 +1696,7 @@ myri10ge_get_ringparam(struct net_device *netdev,
ring->rx_mini_max_pending = mgp->ss[0].rx_small.mask + 1;
ring->rx_max_pending = mgp->ss[0].rx_big.mask + 1;
ring->rx_jumbo_max_pending = 0;
- ring->tx_max_pending = mgp->ss[0].rx_small.mask + 1;
+ ring->tx_max_pending = mgp->ss[0].tx.mask + 1;
ring->rx_mini_pending = ring->rx_mini_max_pending;
ring->rx_pending = ring->rx_max_pending;
ring->rx_jumbo_pending = ring->rx_jumbo_max_pending;
@@ -1803,6 +1813,8 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
int slice;
int i;
+ /* force stats update */
+ (void)myri10ge_get_stats(netdev);
for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++)
data[i] = ((unsigned long *)&mgp->stats)[i];
@@ -2969,6 +2981,7 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
struct net_device_stats *stats = &mgp->stats;
int i;
+ spin_lock(&mgp->stats_lock);
memset(stats, 0, sizeof(*stats));
for (i = 0; i < mgp->num_slices; i++) {
slice_stats = &mgp->ss[i].stats;
@@ -2979,6 +2992,7 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
stats->rx_dropped += slice_stats->rx_dropped;
stats->tx_dropped += slice_stats->tx_dropped;
}
+ spin_unlock(&mgp->stats_lock);
return stats;
}
@@ -3253,6 +3267,8 @@ abort:
static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
{
+ int overridden = 0;
+
if (myri10ge_force_firmware == 0) {
int link_width, exp_cap;
u16 lnk;
@@ -3286,10 +3302,18 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
}
}
if (myri10ge_fw_name != NULL) {
- dev_info(&mgp->pdev->dev, "overriding firmware to %s\n",
- myri10ge_fw_name);
+ overridden = 1;
mgp->fw_name = myri10ge_fw_name;
}
+ if (mgp->board_number < MYRI10GE_MAX_BOARDS &&
+ myri10ge_fw_names[mgp->board_number] != NULL &&
+ strlen(myri10ge_fw_names[mgp->board_number])) {
+ mgp->fw_name = myri10ge_fw_names[mgp->board_number];
+ overridden = 1;
+ }
+ if (overridden)
+ dev_info(&mgp->pdev->dev, "overriding firmware to %s\n",
+ mgp->fw_name);
}
#ifdef CONFIG_PM
@@ -3754,6 +3778,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int status = -ENXIO;
int dac_enabled;
unsigned hdr_offset, ss_offset;
+ static int board_number;
netdev = alloc_etherdev_mq(sizeof(*mgp), MYRI10GE_MAX_SLICES);
if (netdev == NULL) {
@@ -3770,6 +3795,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mgp->pause = myri10ge_flow_control;
mgp->intr_coal_delay = myri10ge_intr_coal_delay;
mgp->msg_enable = netif_msg_init(myri10ge_debug, MYRI10GE_MSG_DEFAULT);
+ mgp->board_number = board_number;
init_waitqueue_head(&mgp->down_wq);
if (pci_enable_device(pdev)) {
@@ -3902,6 +3928,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer,
(unsigned long)mgp);
+ spin_lock_init(&mgp->stats_lock);
SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops);
INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog);
status = register_netdev(netdev);
@@ -3919,6 +3946,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->irq, mgp->tx_boundary, mgp->fw_name,
(mgp->wc_enabled ? "Enabled" : "Disabled"));
+ board_number++;
return 0;
abort_with_state:
@@ -4008,6 +4036,8 @@ static struct pci_device_id myri10ge_pci_tbl[] = {
{0},
};
+MODULE_DEVICE_TABLE(pci, myri10ge_pci_tbl);
+
static struct pci_driver myri10ge_driver = {
.name = "myri10ge",
.probe = myri10ge_probe,
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index 7d83896b8c26..3fcebb70151c 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -374,7 +374,7 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
dev->ethtool_ops = &ne2k_pci_ethtool_ops;
NS8390_init(dev, 0);
- memcpy(dev->dev_addr, SA_prom, 6);
+ memcpy(dev->dev_addr, SA_prom, dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
i = register_netdev(dev);
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
index 6a843f7350ab..a00bbfb9aed0 100644
--- a/drivers/net/ne3210.c
+++ b/drivers/net/ne3210.c
@@ -104,7 +104,7 @@ static int __init ne3210_eisa_probe (struct device *device)
}
SET_NETDEV_DEV(dev, device);
- device->driver_data = dev;
+ dev_set_drvdata(device, dev);
ioaddr = edev->base_addr;
if (!request_region(ioaddr, NE3210_IO_EXTENT, DRV_NAME)) {
@@ -225,7 +225,7 @@ static int __init ne3210_eisa_probe (struct device *device)
static int __devexit ne3210_eisa_remove (struct device *device)
{
- struct net_device *dev = device->driver_data;
+ struct net_device *dev = dev_get_drvdata(device);
unsigned long ioaddr = to_eisa_device (device)->base_addr;
unregister_netdev (dev);
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c
index 1861d5bbd96b..946366dcc992 100644
--- a/drivers/net/netx-eth.c
+++ b/drivers/net/netx-eth.c
@@ -301,6 +301,17 @@ netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value)
while (readl(NETX_MIIMU) & MIIMU_SNRDY);
}
+static const struct net_device_ops netx_eth_netdev_ops = {
+ .ndo_open = netx_eth_open,
+ .ndo_stop = netx_eth_close,
+ .ndo_start_xmit = netx_eth_hard_start_xmit,
+ .ndo_tx_timeout = netx_eth_timeout,
+ .ndo_set_multicast_list = netx_eth_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int netx_eth_enable(struct net_device *ndev)
{
struct netx_eth_priv *priv = netdev_priv(ndev);
@@ -309,12 +320,8 @@ static int netx_eth_enable(struct net_device *ndev)
ether_setup(ndev);
- ndev->open = netx_eth_open;
- ndev->stop = netx_eth_close;
- ndev->hard_start_xmit = netx_eth_hard_start_xmit;
- ndev->tx_timeout = netx_eth_timeout;
+ ndev->netdev_ops = &netx_eth_netdev_ops;
ndev->watchdog_timeo = msecs_to_jiffies(5000);
- ndev->set_multicast_list = netx_eth_set_multicast_list;
priv->msg_enable = NETIF_MSG_LINK;
priv->mii.phy_id_mask = 0x1f;
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index c40815169f35..ab11c2b3f0fe 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -34,10 +34,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
@@ -46,21 +42,16 @@
#include <linux/in.h>
#include <linux/tcp.h>
#include <linux/skbuff.h>
+#include <linux/firmware.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
-#include <linux/interrupt.h>
#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
#include <linux/vmalloc.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/byteorder.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
#include "netxen_nic_hw.h"
@@ -84,10 +75,10 @@
(sizeof(struct netxen_rx_buffer) * rds_ring->num_desc)
#define STATUS_DESC_RINGSIZE(sds_ring) \
(sizeof(struct status_desc) * (sds_ring)->num_desc)
-#define TX_BUFF_RINGSIZE(adapter) \
- (sizeof(struct netxen_cmd_buffer) * adapter->num_txd)
-#define TX_DESC_RINGSIZE(adapter) \
- (sizeof(struct cmd_desc_type0) * adapter->num_txd)
+#define TX_BUFF_RINGSIZE(tx_ring) \
+ (sizeof(struct netxen_cmd_buffer) * tx_ring->num_desc)
+#define TX_DESC_RINGSIZE(tx_ring) \
+ (sizeof(struct cmd_desc_type0) * tx_ring->num_desc)
#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
@@ -118,6 +109,7 @@
#define NX_P3_A2 0x30
#define NX_P3_B0 0x40
#define NX_P3_B1 0x41
+#define NX_P3_B2 0x42
#define NX_IS_REVISION_P2(REVISION) (REVISION <= NX_P2_C1)
#define NX_IS_REVISION_P3(REVISION) (REVISION >= NX_P3_A0)
@@ -203,18 +195,10 @@
#define MAX_RCV_DESCRIPTORS_10G 4096
#define MAX_JUMBO_RCV_DESCRIPTORS 1024
#define MAX_LRO_RCV_DESCRIPTORS 8
-#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS
-#define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS
-#define MAX_RCV_DESC MAX_RCV_DESCRIPTORS
-#define MAX_RCVSTATUS_DESC MAX_RCV_DESCRIPTORS
-#define MAX_EPG_DESCRIPTORS (MAX_CMD_DESCRIPTORS * 8)
-#define NUM_RCV_DESC (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS + \
- MAX_LRO_RCV_DESCRIPTORS)
-#define MIN_TX_COUNT 4096
-#define MIN_RX_COUNT 4096
#define NETXEN_CTX_SIGNATURE 0xdee0
+#define NETXEN_CTX_SIGNATURE_V2 0x0002dee0
+#define NETXEN_CTX_RESET 0xbad0
#define NETXEN_RCV_PRODUCER(ringid) (ringid)
-#define MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */
#define PHAN_PEG_RCV_INITIALIZED 0xff01
#define PHAN_PEG_RCV_START_INITIALIZE 0xff00
@@ -253,12 +237,19 @@ typedef u32 netxen_ctx_msg;
#define netxen_set_msg_opcode(config_word, val) \
((config_word) &= ~(0xf<<28), (config_word) |= (val & 0xf) << 28)
-struct netxen_rcv_context {
- __le64 rcv_ring_addr;
- __le32 rcv_ring_size;
+struct netxen_rcv_ring {
+ __le64 addr;
+ __le32 size;
__le32 rsrvd;
};
+struct netxen_sts_ring {
+ __le64 addr;
+ __le32 size;
+ __le16 msi_index;
+ __le16 rsvd;
+} ;
+
struct netxen_ring_ctx {
/* one command ring */
@@ -268,13 +259,18 @@ struct netxen_ring_ctx {
__le32 rsrvd;
/* three receive rings */
- struct netxen_rcv_context rcv_ctx[3];
+ struct netxen_rcv_ring rcv_rings[NUM_RCV_DESC_RINGS];
- /* one status ring */
__le64 sts_ring_addr;
__le32 sts_ring_size;
__le32 ctx_id;
+
+ __le64 rsrvd_2[3];
+ __le32 sts_ring_count;
+ __le32 rsrvd_3;
+ struct netxen_sts_ring sts_rings[NUM_STS_DESC_RINGS];
+
} __attribute__ ((aligned(64)));
/*
@@ -373,6 +369,7 @@ struct rcv_desc {
/* opcode field in status_desc */
#define NETXEN_NIC_RXPKT_DESC 0x04
#define NETXEN_OLD_RXPKT_DESC 0x3f
+#define NETXEN_NIC_RESPONSE_DESC 0x05
/* for status field in status_desc */
#define STATUS_NEED_CKSUM (1)
@@ -382,13 +379,11 @@ struct rcv_desc {
#define STATUS_OWNER_HOST (0x1ULL << 56)
#define STATUS_OWNER_PHANTOM (0x2ULL << 56)
-/* Note: sizeof(status_desc) should always be a mutliple of 2 */
-
-#define netxen_get_sts_desc_lro_cnt(status_desc) \
- ((status_desc)->lro & 0x7F)
-#define netxen_get_sts_desc_lro_last_frag(status_desc) \
- (((status_desc)->lro & 0x80) >> 7)
-
+/* Status descriptor:
+ 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
+ 28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
+ 53-55 desc_cnt, 56-57 owner, 58-63 opcode
+ */
#define netxen_get_sts_port(sts_data) \
((sts_data) & 0x0F)
#define netxen_get_sts_status(sts_data) \
@@ -403,41 +398,15 @@ struct rcv_desc {
(((sts_data) >> 44) & 0x0F)
#define netxen_get_sts_pkt_offset(sts_data) \
(((sts_data) >> 48) & 0x1F)
+#define netxen_get_sts_desc_cnt(sts_data) \
+ (((sts_data) >> 53) & 0x7)
#define netxen_get_sts_opcode(sts_data) \
(((sts_data) >> 58) & 0x03F)
struct status_desc {
- /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
- 28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
- 53-55 desc_cnt, 56-57 owner, 58-63 opcode
- */
- __le64 status_desc_data;
- union {
- struct {
- __le32 hash_value;
- u8 hash_type;
- u8 msg_type;
- u8 unused;
- union {
- /* Bit pattern: 0-6 lro_count indicates frag
- * sequence, 7 last_frag indicates last frag
- */
- u8 lro;
-
- /* chained buffers */
- u8 nr_frags;
- };
- };
- struct {
- __le16 frag_handles[4];
- };
- };
+ __le64 status_desc_data[2];
} __attribute__ ((aligned(16)));
-enum {
- NETXEN_RCV_PEG_0 = 0,
- NETXEN_RCV_PEG_1
-};
/* The version of the main data structure */
#define NETXEN_BDINFO_VERSION 1
@@ -447,85 +416,35 @@ enum {
/* Max number of Gig ports on a Phantom board */
#define NETXEN_MAX_PORTS 4
-typedef enum {
- NETXEN_BRDTYPE_P1_BD = 0x0000,
- NETXEN_BRDTYPE_P1_SB = 0x0001,
- NETXEN_BRDTYPE_P1_SMAX = 0x0002,
- NETXEN_BRDTYPE_P1_SOCK = 0x0003,
-
- NETXEN_BRDTYPE_P2_SOCK_31 = 0x0008,
- NETXEN_BRDTYPE_P2_SOCK_35 = 0x0009,
- NETXEN_BRDTYPE_P2_SB35_4G = 0x000a,
- NETXEN_BRDTYPE_P2_SB31_10G = 0x000b,
- NETXEN_BRDTYPE_P2_SB31_2G = 0x000c,
-
- NETXEN_BRDTYPE_P2_SB31_10G_IMEZ = 0x000d,
- NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e,
- NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f,
-
- NETXEN_BRDTYPE_P3_REF_QG = 0x0021,
- NETXEN_BRDTYPE_P3_HMEZ = 0x0022,
- NETXEN_BRDTYPE_P3_10G_CX4_LP = 0x0023,
- NETXEN_BRDTYPE_P3_4_GB = 0x0024,
- NETXEN_BRDTYPE_P3_IMEZ = 0x0025,
- NETXEN_BRDTYPE_P3_10G_SFP_PLUS = 0x0026,
- NETXEN_BRDTYPE_P3_10000_BASE_T = 0x0027,
- NETXEN_BRDTYPE_P3_XG_LOM = 0x0028,
- NETXEN_BRDTYPE_P3_4_GB_MM = 0x0029,
- NETXEN_BRDTYPE_P3_10G_SFP_CT = 0x002a,
- NETXEN_BRDTYPE_P3_10G_SFP_QT = 0x002b,
- NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031,
- NETXEN_BRDTYPE_P3_10G_XFP = 0x0032,
- NETXEN_BRDTYPE_P3_10G_TP = 0x0080
-
-} netxen_brdtype_t;
-
-typedef enum {
- NETXEN_BRDMFG_INVENTEC = 1
-} netxen_brdmfg;
-
-typedef enum {
- MEM_ORG_128Mbx4 = 0x0, /* DDR1 only */
- MEM_ORG_128Mbx8 = 0x1, /* DDR1 only */
- MEM_ORG_128Mbx16 = 0x2, /* DDR1 only */
- MEM_ORG_256Mbx4 = 0x3,
- MEM_ORG_256Mbx8 = 0x4,
- MEM_ORG_256Mbx16 = 0x5,
- MEM_ORG_512Mbx4 = 0x6,
- MEM_ORG_512Mbx8 = 0x7,
- MEM_ORG_512Mbx16 = 0x8,
- MEM_ORG_1Gbx4 = 0x9,
- MEM_ORG_1Gbx8 = 0xa,
- MEM_ORG_1Gbx16 = 0xb,
- MEM_ORG_2Gbx4 = 0xc,
- MEM_ORG_2Gbx8 = 0xd,
- MEM_ORG_2Gbx16 = 0xe,
- MEM_ORG_128Mbx32 = 0x10002, /* GDDR only */
- MEM_ORG_256Mbx32 = 0x10005 /* GDDR only */
-} netxen_mn_mem_org_t;
-
-typedef enum {
- MEM_ORG_512Kx36 = 0x0,
- MEM_ORG_1Mx36 = 0x1,
- MEM_ORG_2Mx36 = 0x2
-} netxen_sn_mem_org_t;
-
-typedef enum {
- MEM_DEPTH_4MB = 0x1,
- MEM_DEPTH_8MB = 0x2,
- MEM_DEPTH_16MB = 0x3,
- MEM_DEPTH_32MB = 0x4,
- MEM_DEPTH_64MB = 0x5,
- MEM_DEPTH_128MB = 0x6,
- MEM_DEPTH_256MB = 0x7,
- MEM_DEPTH_512MB = 0x8,
- MEM_DEPTH_1GB = 0x9,
- MEM_DEPTH_2GB = 0xa,
- MEM_DEPTH_4GB = 0xb,
- MEM_DEPTH_8GB = 0xc,
- MEM_DEPTH_16GB = 0xd,
- MEM_DEPTH_32GB = 0xe
-} netxen_mem_depth_t;
+#define NETXEN_BRDTYPE_P1_BD 0x0000
+#define NETXEN_BRDTYPE_P1_SB 0x0001
+#define NETXEN_BRDTYPE_P1_SMAX 0x0002
+#define NETXEN_BRDTYPE_P1_SOCK 0x0003
+
+#define NETXEN_BRDTYPE_P2_SOCK_31 0x0008
+#define NETXEN_BRDTYPE_P2_SOCK_35 0x0009
+#define NETXEN_BRDTYPE_P2_SB35_4G 0x000a
+#define NETXEN_BRDTYPE_P2_SB31_10G 0x000b
+#define NETXEN_BRDTYPE_P2_SB31_2G 0x000c
+
+#define NETXEN_BRDTYPE_P2_SB31_10G_IMEZ 0x000d
+#define NETXEN_BRDTYPE_P2_SB31_10G_HMEZ 0x000e
+#define NETXEN_BRDTYPE_P2_SB31_10G_CX4 0x000f
+
+#define NETXEN_BRDTYPE_P3_REF_QG 0x0021
+#define NETXEN_BRDTYPE_P3_HMEZ 0x0022
+#define NETXEN_BRDTYPE_P3_10G_CX4_LP 0x0023
+#define NETXEN_BRDTYPE_P3_4_GB 0x0024
+#define NETXEN_BRDTYPE_P3_IMEZ 0x0025
+#define NETXEN_BRDTYPE_P3_10G_SFP_PLUS 0x0026
+#define NETXEN_BRDTYPE_P3_10000_BASE_T 0x0027
+#define NETXEN_BRDTYPE_P3_XG_LOM 0x0028
+#define NETXEN_BRDTYPE_P3_4_GB_MM 0x0029
+#define NETXEN_BRDTYPE_P3_10G_SFP_CT 0x002a
+#define NETXEN_BRDTYPE_P3_10G_SFP_QT 0x002b
+#define NETXEN_BRDTYPE_P3_10G_CX4 0x0031
+#define NETXEN_BRDTYPE_P3_10G_XFP 0x0032
+#define NETXEN_BRDTYPE_P3_10G_TP 0x0080
struct netxen_board_info {
u32 header_version;
@@ -676,17 +595,15 @@ struct netxen_new_user_info {
#define PRIMARY_IMAGE_BAD 0xffffffff
/* Flash memory map */
-typedef enum {
- NETXEN_CRBINIT_START = 0, /* Crbinit section */
- NETXEN_BRDCFG_START = 0x4000, /* board config */
- NETXEN_INITCODE_START = 0x6000, /* pegtune code */
- NETXEN_BOOTLD_START = 0x10000, /* bootld */
- NETXEN_IMAGE_START = 0x43000, /* compressed image */
- NETXEN_SECONDARY_START = 0x200000, /* backup images */
- NETXEN_PXE_START = 0x3E0000, /* user defined region */
- NETXEN_USER_START = 0x3E8000, /* User defined region for new boards */
- NETXEN_FIXED_START = 0x3F0000 /* backup of crbinit */
-} netxen_flash_map_t;
+#define NETXEN_CRBINIT_START 0 /* crbinit section */
+#define NETXEN_BRDCFG_START 0x4000 /* board config */
+#define NETXEN_INITCODE_START 0x6000 /* pegtune code */
+#define NETXEN_BOOTLD_START 0x10000 /* bootld */
+#define NETXEN_IMAGE_START 0x43000 /* compressed image */
+#define NETXEN_SECONDARY_START 0x200000 /* backup images */
+#define NETXEN_PXE_START 0x3E0000 /* PXE boot rom */
+#define NETXEN_USER_START 0x3E8000 /* Firmare info */
+#define NETXEN_FIXED_START 0x3F0000 /* backup of crbinit */
#define NX_FW_VERSION_OFFSET (NETXEN_USER_START+0x408)
#define NX_FW_SIZE_OFFSET (NETXEN_USER_START+0x40c)
@@ -708,21 +625,8 @@ typedef enum {
#define NETXEN_FLASH_SECONDARY_SIZE (NETXEN_USER_START-NETXEN_SECONDARY_START)
#define NETXEN_NUM_PRIMARY_SECTORS (0x20)
#define NETXEN_NUM_CONFIG_SECTORS (1)
-#define PFX "NetXen: "
extern char netxen_nic_driver_name[];
-/* Note: Make sure to not call this before adapter->port is valid */
-#if !defined(NETXEN_DEBUG)
-#define DPRINTK(klevel, fmt, args...) do { \
- } while (0)
-#else
-#define DPRINTK(klevel, fmt, args...) do { \
- printk(KERN_##klevel PFX "%s: %s: " fmt, __func__,\
- (adapter != NULL && adapter->netdev != NULL) ? \
- adapter->netdev->name : NULL, \
- ## args); } while(0)
-#endif
-
/* Number of status descriptors to handle per interrupt */
#define MAX_STATUS_HANDLE (64)
@@ -732,7 +636,7 @@ extern char netxen_nic_driver_name[];
*/
struct netxen_skb_frag {
u64 dma;
- ulong length;
+ u64 length;
};
#define _netxen_set_bits(config_word, start, bits, val) {\
@@ -793,34 +697,24 @@ struct netxen_hardware_context {
u8 cut_through;
u8 revision_id;
+ u8 pci_func;
+ u8 linkup;
u16 port_type;
- int board_type;
- u32 linkup;
- /* Address of cmd ring in Phantom */
- struct cmd_desc_type0 *cmd_desc_head;
- dma_addr_t cmd_desc_phys_addr;
- struct netxen_adapter *adapter;
- int pci_func;
+ u16 board_type;
};
#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
#define ETHERNET_FCS_SIZE 4
struct netxen_adapter_stats {
- u64 rcvdbadskb;
u64 xmitcalled;
- u64 xmitedframes;
u64 xmitfinished;
- u64 badskblen;
- u64 nocmddescriptor;
- u64 polled;
u64 rxdropped;
u64 txdropped;
u64 csummed;
u64 no_rcv;
u64 rxbytes;
u64 txbytes;
- u64 ints;
};
/*
@@ -852,14 +746,25 @@ struct nx_host_sds_ring {
struct napi_struct napi;
struct list_head free_list[NUM_RCV_DESC_RINGS];
- u16 clean_tx;
- u16 post_rxd;
int irq;
dma_addr_t phys_addr;
char name[IFNAMSIZ+4];
};
+struct nx_host_tx_ring {
+ u32 producer;
+ __le32 *hw_consumer;
+ u32 sw_consumer;
+ u32 crb_cmd_producer;
+ u32 crb_cmd_consumer;
+ u32 num_desc;
+
+ struct netxen_cmd_buffer *cmd_buf_arr;
+ struct cmd_desc_type0 *desc_head;
+ dma_addr_t phys_addr;
+};
+
/*
* Receive context. There is one such structure per instance of the
* receive processing. Any state information that is relevant to
@@ -871,8 +776,11 @@ struct netxen_recv_context {
u16 context_id;
u16 virt_port;
- struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS];
- struct nx_host_sds_ring sds_rings[NUM_STS_DESC_RINGS];
+ struct nx_host_rds_ring *rds_rings;
+ struct nx_host_sds_ring *sds_rings;
+
+ struct netxen_ring_ctx *hwctx;
+ dma_addr_t phys_addr;
};
/* New HW context creation */
@@ -1111,8 +1019,8 @@ typedef struct {
#define NETXEN_MAC_DEL 2
typedef struct nx_mac_list_s {
- struct nx_mac_list_s *next;
- uint8_t mac_addr[MAX_ADDR_LEN];
+ struct list_head list;
+ uint8_t mac_addr[ETH_ALEN+2];
} nx_mac_list_t;
/*
@@ -1154,31 +1062,118 @@ typedef struct {
#define NX_MAC_EVENT 0x1
-enum {
- NX_NIC_H2C_OPCODE_START = 0,
- NX_NIC_H2C_OPCODE_CONFIG_RSS,
- NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL,
- NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE,
- NX_NIC_H2C_OPCODE_CONFIG_LED,
- NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS,
- NX_NIC_H2C_OPCODE_CONFIG_L2_MAC,
- NX_NIC_H2C_OPCODE_LRO_REQUEST,
- NX_NIC_H2C_OPCODE_GET_SNMP_STATS,
- NX_NIC_H2C_OPCODE_PROXY_START_REQUEST,
- NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST,
- NX_NIC_H2C_OPCODE_PROXY_SET_MTU,
- NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE,
- NX_H2P_OPCODE_GET_FINGER_PRINT_REQUEST,
- NX_H2P_OPCODE_INSTALL_LICENSE_REQUEST,
- NX_H2P_OPCODE_GET_LICENSE_CAPABILITY_REQUEST,
- NX_NIC_H2C_OPCODE_GET_NET_STATS,
- NX_NIC_H2C_OPCODE_LAST
-};
+/*
+ * Driver --> Firmware
+ */
+#define NX_NIC_H2C_OPCODE_START 0
+#define NX_NIC_H2C_OPCODE_CONFIG_RSS 1
+#define NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL 2
+#define NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE 3
+#define NX_NIC_H2C_OPCODE_CONFIG_LED 4
+#define NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS 5
+#define NX_NIC_H2C_OPCODE_CONFIG_L2_MAC 6
+#define NX_NIC_H2C_OPCODE_LRO_REQUEST 7
+#define NX_NIC_H2C_OPCODE_GET_SNMP_STATS 8
+#define NX_NIC_H2C_OPCODE_PROXY_START_REQUEST 9
+#define NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST 10
+#define NX_NIC_H2C_OPCODE_PROXY_SET_MTU 11
+#define NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE 12
+#define NX_NIC_H2C_OPCODE_GET_FINGER_PRINT_REQUEST 13
+#define NX_NIC_H2C_OPCODE_INSTALL_LICENSE_REQUEST 14
+#define NX_NIC_H2C_OPCODE_GET_LICENSE_CAPABILITY_REQUEST 15
+#define NX_NIC_H2C_OPCODE_GET_NET_STATS 16
+#define NX_NIC_H2C_OPCODE_PROXY_UPDATE_P2V 17
+#define NX_NIC_H2C_OPCODE_CONFIG_IPADDR 18
+#define NX_NIC_H2C_OPCODE_CONFIG_LOOPBACK 19
+#define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE 20
+#define NX_NIC_H2C_OPCODE_GET_LINKEVENT 21
+#define NX_NIC_C2C_OPCODE 22
+#define NX_NIC_H2C_OPCODE_LAST 23
+
+/*
+ * Firmware --> Driver
+ */
+
+#define NX_NIC_C2H_OPCODE_START 128
+#define NX_NIC_C2H_OPCODE_CONFIG_RSS_RESPONSE 129
+#define NX_NIC_C2H_OPCODE_CONFIG_RSS_TBL_RESPONSE 130
+#define NX_NIC_C2H_OPCODE_CONFIG_MAC_RESPONSE 131
+#define NX_NIC_C2H_OPCODE_CONFIG_PROMISCUOUS_RESPONSE 132
+#define NX_NIC_C2H_OPCODE_CONFIG_L2_MAC_RESPONSE 133
+#define NX_NIC_C2H_OPCODE_LRO_DELETE_RESPONSE 134
+#define NX_NIC_C2H_OPCODE_LRO_ADD_FAILURE_RESPONSE 135
+#define NX_NIC_C2H_OPCODE_GET_SNMP_STATS 136
+#define NX_NIC_C2H_OPCODE_GET_FINGER_PRINT_REPLY 137
+#define NX_NIC_C2H_OPCODE_INSTALL_LICENSE_REPLY 138
+#define NX_NIC_C2H_OPCODE_GET_LICENSE_CAPABILITIES_REPLY 139
+#define NX_NIC_C2H_OPCODE_GET_NET_STATS_RESPONSE 140
+#define NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE 141
+#define NX_NIC_C2H_OPCODE_LAST 142
#define VPORT_MISS_MODE_DROP 0 /* drop all unmatched */
#define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */
#define VPORT_MISS_MODE_ACCEPT_MULTI 2 /* accept unmatched multicast */
+#define NX_FW_CAPABILITY_LINK_NOTIFICATION (1 << 5)
+#define NX_FW_CAPABILITY_SWITCHING (1 << 6)
+
+/* module types */
+#define LINKEVENT_MODULE_NOT_PRESENT 1
+#define LINKEVENT_MODULE_OPTICAL_UNKNOWN 2
+#define LINKEVENT_MODULE_OPTICAL_SRLR 3
+#define LINKEVENT_MODULE_OPTICAL_LRM 4
+#define LINKEVENT_MODULE_OPTICAL_SFP_1G 5
+#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE 6
+#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN 7
+#define LINKEVENT_MODULE_TWINAX 8
+
+#define LINKSPEED_10GBPS 10000
+#define LINKSPEED_1GBPS 1000
+#define LINKSPEED_100MBPS 100
+#define LINKSPEED_10MBPS 10
+
+#define LINKSPEED_ENCODED_10MBPS 0
+#define LINKSPEED_ENCODED_100MBPS 1
+#define LINKSPEED_ENCODED_1GBPS 2
+
+#define LINKEVENT_AUTONEG_DISABLED 0
+#define LINKEVENT_AUTONEG_ENABLED 1
+
+#define LINKEVENT_HALF_DUPLEX 0
+#define LINKEVENT_FULL_DUPLEX 1
+
+#define LINKEVENT_LINKSPEED_MBPS 0
+#define LINKEVENT_LINKSPEED_ENCODED 1
+
+/* firmware response header:
+ * 63:58 - message type
+ * 57:56 - owner
+ * 55:53 - desc count
+ * 52:48 - reserved
+ * 47:40 - completion id
+ * 39:32 - opcode
+ * 31:16 - error code
+ * 15:00 - reserved
+ */
+#define netxen_get_nic_msgtype(msg_hdr) \
+ ((msg_hdr >> 58) & 0x3F)
+#define netxen_get_nic_msg_compid(msg_hdr) \
+ ((msg_hdr >> 40) & 0xFF)
+#define netxen_get_nic_msg_opcode(msg_hdr) \
+ ((msg_hdr >> 32) & 0xFF)
+#define netxen_get_nic_msg_errcode(msg_hdr) \
+ ((msg_hdr >> 16) & 0xFFFF)
+
+typedef struct {
+ union {
+ struct {
+ u64 hdr;
+ u64 body[7];
+ };
+ u64 words[8];
+ };
+} nx_fw_msg_t;
+
typedef struct {
__le64 qhdr;
__le64 req_hdr;
@@ -1218,99 +1213,96 @@ struct netxen_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
- int pci_using_dac;
- struct net_device_stats net_stats;
- int mtu;
- int portnum;
- u8 physical_port;
- u16 tx_context_id;
-
- uint8_t mc_enabled;
- uint8_t max_mc_count;
- nx_mac_list_t *mac_list;
-
- struct netxen_legacy_intr_set legacy_intr;
-
- struct work_struct watchdog_task;
- struct timer_list watchdog_timer;
- struct work_struct tx_timeout_task;
+ struct list_head mac_list;
u32 curr_window;
u32 crb_win;
rwlock_t adapter_lock;
- u32 cmd_producer;
- __le32 *cmd_consumer;
- u32 last_cmd_consumer;
- u32 crb_addr_cmd_producer;
- u32 crb_addr_cmd_consumer;
spinlock_t tx_clean_lock;
- u32 num_txd;
- u32 num_rxd;
- u32 num_jumbo_rxd;
- u32 num_lro_rxd;
+ u16 num_txd;
+ u16 num_rxd;
+ u16 num_jumbo_rxd;
+ u16 num_lro_rxd;
+
+ u8 max_rds_rings;
+ u8 max_sds_rings;
+ u8 driver_mismatch;
+ u8 msix_supported;
+ u8 rx_csum;
+ u8 pci_using_dac;
+ u8 portnum;
+ u8 physical_port;
+
+ u8 mc_enabled;
+ u8 max_mc_count;
+ u8 rss_supported;
+ u8 resv2;
+ u32 resv3;
+
+ u8 has_link_events;
+ u8 resv1;
+ u16 tx_context_id;
+ u16 mtu;
+ u16 is_up;
- int max_rds_rings;
- int max_sds_rings;
+ u16 link_speed;
+ u16 link_duplex;
+ u16 link_autoneg;
+ u16 module_type;
+ u32 capabilities;
u32 flags;
u32 irq;
- int driver_mismatch;
u32 temp;
- u32 fw_major;
- u32 fw_version;
-
- int msix_supported;
- struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
+ u32 msi_tgt_status;
+ u32 resv4;
struct netxen_adapter_stats stats;
- u16 link_speed;
- u16 link_duplex;
- u16 state;
- u16 link_autoneg;
- int rx_csum;
-
- struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */
-
- /*
- * Receive instances. These can be either one per port,
- * or one per peg, etc.
- */
struct netxen_recv_context recv_ctx;
+ struct nx_host_tx_ring *tx_ring;
- int is_up;
- struct netxen_dummy_dma dummy_dma;
- nx_nic_intr_coalesce_t coal;
-
- /* Context interface shared between card and host */
- struct netxen_ring_ctx *ctx_desc;
- dma_addr_t ctx_desc_phys_addr;
- int intr_scheme;
- int msi_mode;
int (*enable_phy_interrupts) (struct netxen_adapter *);
int (*disable_phy_interrupts) (struct netxen_adapter *);
- int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t);
+ int (*macaddr_set) (struct netxen_adapter *, u8 *);
int (*set_mtu) (struct netxen_adapter *, int);
int (*set_promisc) (struct netxen_adapter *, u32);
+ void (*set_multi) (struct net_device *);
int (*phy_read) (struct netxen_adapter *, long reg, u32 *);
int (*phy_write) (struct netxen_adapter *, long reg, u32 val);
int (*init_port) (struct netxen_adapter *, int);
int (*stop_port) (struct netxen_adapter *);
- int (*hw_read_wx)(struct netxen_adapter *, ulong, void *, int);
- int (*hw_write_wx)(struct netxen_adapter *, ulong, void *, int);
+ u32 (*hw_read_wx)(struct netxen_adapter *, ulong);
+ int (*hw_write_wx)(struct netxen_adapter *, ulong, u32);
int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int);
int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int);
int (*pci_write_immediate)(struct netxen_adapter *, u64, u32);
u32 (*pci_read_immediate)(struct netxen_adapter *, u64);
- void (*pci_write_normalize)(struct netxen_adapter *, u64, u32);
- u32 (*pci_read_normalize)(struct netxen_adapter *, u64);
unsigned long (*pci_set_window)(struct netxen_adapter *,
unsigned long long);
-}; /* netxen_adapter structure */
+
+ struct netxen_legacy_intr_set legacy_intr;
+
+ struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
+
+ struct netxen_dummy_dma dummy_dma;
+
+ struct work_struct watchdog_task;
+ struct timer_list watchdog_timer;
+ struct work_struct tx_timeout_task;
+
+ struct net_device_stats net_stats;
+
+ nx_nic_intr_coalesce_t coal;
+
+ u32 fw_major;
+ u32 fw_version;
+ const struct firmware *fw;
+};
/*
* NetXen dma watchdog control structure
@@ -1330,46 +1322,6 @@ struct netxen_adapter {
#define netxen_get_dma_watchdog_disabled(config_word) \
(((config_word) >> 1) & 0x1)
-/* Max number of xmit producer threads that can run simultaneously */
-#define MAX_XMIT_PRODUCERS 16
-
-#define PCI_OFFSET_FIRST_RANGE(adapter, off) \
- ((adapter)->ahw.pci_base0 + (off))
-#define PCI_OFFSET_SECOND_RANGE(adapter, off) \
- ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
-#define PCI_OFFSET_THIRD_RANGE(adapter, off) \
- ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)
-
-static inline void __iomem *pci_base_offset(struct netxen_adapter *adapter,
- unsigned long off)
-{
- if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) {
- return (adapter->ahw.pci_base0 + off);
- } else if ((off < SECOND_PAGE_GROUP_END) &&
- (off >= SECOND_PAGE_GROUP_START)) {
- return (adapter->ahw.pci_base1 + off - SECOND_PAGE_GROUP_START);
- } else if ((off < THIRD_PAGE_GROUP_END) &&
- (off >= THIRD_PAGE_GROUP_START)) {
- return (adapter->ahw.pci_base2 + off - THIRD_PAGE_GROUP_START);
- }
- return NULL;
-}
-
-static inline void __iomem *pci_base(struct netxen_adapter *adapter,
- unsigned long off)
-{
- if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) {
- return adapter->ahw.pci_base0;
- } else if ((off < SECOND_PAGE_GROUP_END) &&
- (off >= SECOND_PAGE_GROUP_START)) {
- return adapter->ahw.pci_base1;
- } else if ((off < THIRD_PAGE_GROUP_END) &&
- (off >= THIRD_PAGE_GROUP_START)) {
- return adapter->ahw.pci_base2;
- }
- return NULL;
-}
-
int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter);
int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter);
int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter);
@@ -1382,21 +1334,22 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
/* Functions available from netxen_nic_hw.c */
int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu);
-void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val);
-int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off);
-void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value);
-void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value);
-void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value);
-void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value);
+
+int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
+int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
+
+#define NXRD32(adapter, off) \
+ (adapter->hw_read_wx(adapter, off))
+#define NXWR32(adapter, off, val) \
+ (adapter->hw_write_wx(adapter, off, val))
int netxen_nic_get_board_info(struct netxen_adapter *adapter);
void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
int netxen_nic_wol_supported(struct netxen_adapter *adapter);
-int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
- ulong off, void *data, int len);
+u32 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off);
int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
- ulong off, void *data, int len);
+ ulong off, u32 data);
int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
u64 off, void *data, int size);
int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
@@ -1412,16 +1365,13 @@ unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter,
u32 wndw);
-int netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
- ulong off, void *data, int len);
+u32 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off);
int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
- ulong off, void *data, int len);
+ ulong off, u32 data);
int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
u64 off, void *data, int size);
int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
u64 off, void *data, int size);
-void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
- unsigned long off, int data);
int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
u64 off, u32 data);
u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off);
@@ -1435,8 +1385,9 @@ unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
void netxen_free_adapter_offload(struct netxen_adapter *adapter);
int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
-int netxen_receive_peg_ready(struct netxen_adapter *adapter);
int netxen_load_firmware(struct netxen_adapter *adapter);
+void netxen_request_firmware(struct netxen_adapter *adapter);
+void netxen_release_firmware(struct netxen_adapter *adapter);
int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp);
@@ -1475,6 +1426,8 @@ void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
int netxen_config_rss(struct netxen_adapter *adapter, int enable);
+int netxen_linkevent_request(struct netxen_adapter *adapter, int enable);
+void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup);
int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
@@ -1483,7 +1436,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p);
struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
- uint32_t crb_producer);
+ struct nx_host_tx_ring *tx_ring, uint32_t crb_producer);
/*
* NetXen Board information
@@ -1491,7 +1444,7 @@ void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
#define NETXEN_MAX_SHORT_NAME 32
struct netxen_brdinfo {
- netxen_brdtype_t brdtype; /* type of board */
+ int brdtype; /* type of board */
long ports; /* max no of physical ports */
char short_name[NETXEN_MAX_SHORT_NAME];
};
@@ -1541,17 +1494,15 @@ dma_watchdog_shutdown_request(struct netxen_adapter *adapter)
u32 ctrl;
/* check if already inactive */
- if (adapter->hw_read_wx(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
- printk(KERN_ERR "failed to read dma watchdog status\n");
+ ctrl = adapter->hw_read_wx(adapter,
+ NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
if (netxen_get_dma_watchdog_enabled(ctrl) == 0)
return 1;
/* Send the disable request */
netxen_set_dma_watchdog_disable_req(ctrl);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
+ NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
return 0;
}
@@ -1561,9 +1512,8 @@ dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter)
{
u32 ctrl;
- if (adapter->hw_read_wx(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
- printk(KERN_ERR "failed to read dma watchdog status\n");
+ ctrl = adapter->hw_read_wx(adapter,
+ NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
return (netxen_get_dma_watchdog_enabled(ctrl) == 0);
}
@@ -1573,9 +1523,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
{
u32 ctrl;
- if (adapter->hw_read_wx(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
- printk(KERN_ERR "failed to read dma watchdog status\n");
+ ctrl = adapter->hw_read_wx(adapter,
+ NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
if (netxen_get_dma_watchdog_enabled(ctrl))
return 1;
@@ -1583,8 +1532,7 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
/* send the wakeup request */
netxen_set_dma_watchdog_enable_req(ctrl);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
+ NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
return 0;
}
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 9234473bc08a..4754f5cffad0 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -41,8 +41,7 @@ netxen_api_lock(struct netxen_adapter *adapter)
for (;;) {
/* Acquire PCIE HW semaphore5 */
- netxen_nic_read_w0(adapter,
- NETXEN_PCIE_REG(PCIE_SEM5_LOCK), &done);
+ done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_LOCK));
if (done == 1)
break;
@@ -56,7 +55,7 @@ netxen_api_lock(struct netxen_adapter *adapter)
}
#if 0
- netxen_nic_write_w1(adapter,
+ NXWR32(adapter,
NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
#endif
return 0;
@@ -65,11 +64,8 @@ netxen_api_lock(struct netxen_adapter *adapter)
static int
netxen_api_unlock(struct netxen_adapter *adapter)
{
- u32 val;
-
/* Release PCIE HW semaphore5 */
- netxen_nic_read_w0(adapter,
- NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK), &val);
+ NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK));
return 0;
}
@@ -86,7 +82,7 @@ netxen_poll_rsp(struct netxen_adapter *adapter)
if (++timeout > NX_OS_CRB_RETRY_COUNT)
return NX_CDRP_RSP_TIMEOUT;
- netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, &rsp);
+ rsp = NXRD32(adapter, NX_CDRP_CRB_OFFSET);
} while (!NX_CDRP_IS_RSP(rsp));
return rsp;
@@ -106,16 +102,15 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
if (netxen_api_lock(adapter))
return NX_RCODE_TIMEOUT;
- netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, signature);
+ NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature);
- netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, arg1);
+ NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1);
- netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, arg2);
+ NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2);
- netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, arg3);
+ NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3);
- netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET,
- NX_CDRP_FORM_CMD(cmd));
+ NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd));
rsp = netxen_poll_rsp(adapter);
@@ -125,7 +120,7 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
rcode = NX_RCODE_TIMEOUT;
} else if (rsp == NX_CDRP_RSP_FAIL) {
- netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode);
+ rcode = NXRD32(adapter, NX_ARG1_CRB_OFFSET);
printk(KERN_ERR "%s: failed card response code:0x%x\n",
netxen_nic_driver_name, rcode);
@@ -328,6 +323,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
int err = 0;
u64 offset, phys_addr;
dma_addr_t rq_phys_addr, rsp_phys_addr;
+ struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
rq_addr = pci_alloc_consistent(adapter->pdev,
@@ -362,15 +359,13 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
prq->dummy_dma_addr = cpu_to_le64(adapter->dummy_dma.phys_addr);
- offset = adapter->ctx_desc_phys_addr+sizeof(struct netxen_ring_ctx);
+ offset = recv_ctx->phys_addr + sizeof(struct netxen_ring_ctx);
prq->cmd_cons_dma_addr = cpu_to_le64(offset);
prq_cds = &prq->cds_ring;
- prq_cds->host_phys_addr =
- cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
-
- prq_cds->ring_size = cpu_to_le32(adapter->num_txd);
+ prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr);
+ prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
phys_addr = rq_phys_addr;
err = netxen_issue_cmd(adapter,
@@ -383,8 +378,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
if (err == NX_RCODE_SUCCESS) {
temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
- adapter->crb_addr_cmd_producer =
- NETXEN_NIC_REG(temp - 0x200);
+ tx_ring->crb_cmd_producer = NETXEN_NIC_REG(temp - 0x200);
#if 0
adapter->tx_state =
le32_to_cpu(prsp->host_ctx_state);
@@ -448,7 +442,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
NETXEN_NIC_REG(0x120)
},
/* crb_sts_consumer: */
- NETXEN_NIC_REG(0x138),
+ {
+ NETXEN_NIC_REG(0x138),
+ NETXEN_NIC_REG_2(0x000),
+ NETXEN_NIC_REG_2(0x004),
+ NETXEN_NIC_REG_2(0x008),
+ },
+ /* sw_int_mask */
+ {
+ CRB_SW_INT_MASK_0,
+ NETXEN_NIC_REG_2(0x044),
+ NETXEN_NIC_REG_2(0x048),
+ NETXEN_NIC_REG_2(0x04c),
+ },
},
/* Instance 1 */
{
@@ -461,7 +467,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
NETXEN_NIC_REG(0x164)
},
/* crb_sts_consumer: */
- NETXEN_NIC_REG(0x17c),
+ {
+ NETXEN_NIC_REG(0x17c),
+ NETXEN_NIC_REG_2(0x020),
+ NETXEN_NIC_REG_2(0x024),
+ NETXEN_NIC_REG_2(0x028),
+ },
+ /* sw_int_mask */
+ {
+ CRB_SW_INT_MASK_1,
+ NETXEN_NIC_REG_2(0x064),
+ NETXEN_NIC_REG_2(0x068),
+ NETXEN_NIC_REG_2(0x06c),
+ },
},
/* Instance 2 */
{
@@ -474,7 +492,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
NETXEN_NIC_REG(0x208)
},
/* crb_sts_consumer: */
- NETXEN_NIC_REG(0x220),
+ {
+ NETXEN_NIC_REG(0x220),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ },
+ /* sw_int_mask */
+ {
+ CRB_SW_INT_MASK_2,
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ },
},
/* Instance 3 */
{
@@ -487,7 +517,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
NETXEN_NIC_REG(0x24c)
},
/* crb_sts_consumer: */
- NETXEN_NIC_REG(0x264),
+ {
+ NETXEN_NIC_REG(0x264),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ },
+ /* sw_int_mask */
+ {
+ CRB_SW_INT_MASK_3,
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ },
},
};
@@ -497,84 +539,91 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring;
+ struct nx_host_tx_ring *tx_ring;
int ring;
- int func_id = adapter->portnum;
-
- adapter->ctx_desc->cmd_ring_addr =
- cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
- adapter->ctx_desc->cmd_ring_size =
- cpu_to_le32(adapter->num_txd);
+ int port = adapter->portnum;
+ struct netxen_ring_ctx *hwctx;
+ u32 signature;
+ tx_ring = adapter->tx_ring;
recv_ctx = &adapter->recv_ctx;
+ hwctx = recv_ctx->hwctx;
+
+ hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr);
+ hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc);
+
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
- adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
+ hwctx->rcv_rings[ring].addr =
cpu_to_le64(rds_ring->phys_addr);
- adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+ hwctx->rcv_rings[ring].size =
cpu_to_le32(rds_ring->num_desc);
}
- sds_ring = &recv_ctx->sds_rings[0];
- adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
- adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
-
- adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
- lower32(adapter->ctx_desc_phys_addr));
- adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_HI(func_id),
- upper32(adapter->ctx_desc_phys_addr));
- adapter->pci_write_normalize(adapter, CRB_CTX_SIGNATURE_REG(func_id),
- NETXEN_CTX_SIGNATURE | func_id);
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+
+ if (ring == 0) {
+ hwctx->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
+ hwctx->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
+ }
+ hwctx->sts_rings[ring].addr = cpu_to_le64(sds_ring->phys_addr);
+ hwctx->sts_rings[ring].size = cpu_to_le32(sds_ring->num_desc);
+ hwctx->sts_rings[ring].msi_index = cpu_to_le16(ring);
+ }
+ hwctx->sts_ring_count = cpu_to_le32(adapter->max_sds_rings);
+
+ signature = (adapter->max_sds_rings > 1) ?
+ NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE;
+
+ NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port),
+ lower32(recv_ctx->phys_addr));
+ NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port),
+ upper32(recv_ctx->phys_addr));
+ NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port),
+ signature | port);
return 0;
}
-static uint32_t sw_int_mask[4] = {
- CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
- CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
-};
-
int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
{
- struct netxen_hardware_context *hw = &adapter->ahw;
- u32 state = 0;
void *addr;
int err = 0;
int ring;
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring;
+ struct nx_host_tx_ring *tx_ring;
struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
+ int port = adapter->portnum;
- err = netxen_receive_peg_ready(adapter);
- if (err) {
- printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n",
- state);
- return err;
- }
+ recv_ctx = &adapter->recv_ctx;
+ tx_ring = adapter->tx_ring;
addr = pci_alloc_consistent(pdev,
sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
- &adapter->ctx_desc_phys_addr);
-
+ &recv_ctx->phys_addr);
if (addr == NULL) {
dev_err(&pdev->dev, "failed to allocate hw context\n");
return -ENOMEM;
}
+
memset(addr, 0, sizeof(struct netxen_ring_ctx));
- adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
- adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum);
- adapter->ctx_desc->cmd_consumer_offset =
- cpu_to_le64(adapter->ctx_desc_phys_addr +
+ recv_ctx->hwctx = (struct netxen_ring_ctx *)addr;
+ recv_ctx->hwctx->ctx_id = cpu_to_le32(port);
+ recv_ctx->hwctx->cmd_consumer_offset =
+ cpu_to_le64(recv_ctx->phys_addr +
sizeof(struct netxen_ring_ctx));
- adapter->cmd_consumer =
+ tx_ring->hw_consumer =
(__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
/* cmd desc ring */
- addr = pci_alloc_consistent(pdev,
- TX_DESC_RINGSIZE(adapter),
- &hw->cmd_desc_phys_addr);
+ addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring),
+ &tx_ring->phys_addr);
if (addr == NULL) {
dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
@@ -582,9 +631,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
return -ENOMEM;
}
- hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
-
- recv_ctx = &adapter->recv_ctx;
+ tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
@@ -602,8 +649,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
if (adapter->fw_major < 4)
rds_ring->crb_rcv_producer =
- recv_crb_registers[adapter->portnum].
- crb_rcv_producer[ring];
+ recv_crb_registers[port].crb_rcv_producer[ring];
}
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
@@ -620,13 +666,16 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
goto err_out_free;
}
sds_ring->desc_head = (struct status_desc *)addr;
+
+ sds_ring->crb_sts_consumer =
+ recv_crb_registers[port].crb_sts_consumer[ring];
+
+ sds_ring->crb_intr_mask =
+ recv_crb_registers[port].sw_int_mask[ring];
}
if (adapter->fw_major >= 4) {
- adapter->intr_scheme = INTR_SCHEME_PERPORT;
- adapter->msi_mode = MSI_MODE_MULTIFUNC;
-
err = nx_fw_cmd_create_rx_ctx(adapter);
if (err)
goto err_out_free;
@@ -634,23 +683,11 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
if (err)
goto err_out_free;
} else {
- sds_ring = &recv_ctx->sds_rings[0];
- sds_ring->crb_sts_consumer =
- recv_crb_registers[adapter->portnum].crb_sts_consumer;
-
- adapter->intr_scheme = adapter->pci_read_normalize(adapter,
- CRB_NIC_CAPABILITIES_FW);
- adapter->msi_mode = adapter->pci_read_normalize(adapter,
- CRB_NIC_MSI_MODE_FW);
- recv_ctx->sds_rings[0].crb_intr_mask =
- sw_int_mask[adapter->portnum];
-
err = netxen_init_old_ctx(adapter);
if (err) {
netxen_free_hw_resources(adapter);
return err;
}
-
}
return 0;
@@ -665,32 +702,40 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring;
+ struct nx_host_tx_ring *tx_ring;
int ring;
+ int port = adapter->portnum;
+
if (adapter->fw_major >= 4) {
nx_fw_cmd_destroy_tx_ctx(adapter);
nx_fw_cmd_destroy_rx_ctx(adapter);
+ } else {
+ netxen_api_lock(adapter);
+ NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port),
+ NETXEN_CTX_RESET | port);
+ netxen_api_unlock(adapter);
}
- if (adapter->ctx_desc != NULL) {
+ recv_ctx = &adapter->recv_ctx;
+
+ if (recv_ctx->hwctx != NULL) {
pci_free_consistent(adapter->pdev,
sizeof(struct netxen_ring_ctx) +
sizeof(uint32_t),
- adapter->ctx_desc,
- adapter->ctx_desc_phys_addr);
- adapter->ctx_desc = NULL;
+ recv_ctx->hwctx,
+ recv_ctx->phys_addr);
+ recv_ctx->hwctx = NULL;
}
- if (adapter->ahw.cmd_desc_head != NULL) {
+ tx_ring = adapter->tx_ring;
+ if (tx_ring->desc_head != NULL) {
pci_free_consistent(adapter->pdev,
- sizeof(struct cmd_desc_type0) *
- adapter->num_txd,
- adapter->ahw.cmd_desc_head,
- adapter->ahw.cmd_desc_phys_addr);
- adapter->ahw.cmd_desc_head = NULL;
+ TX_DESC_RINGSIZE(tx_ring),
+ tx_ring->desc_head, tx_ring->phys_addr);
+ tx_ring->desc_head = NULL;
}
- recv_ctx = &adapter->recv_ctx;
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index a677ff895184..e16ea46c24b8 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -30,7 +30,6 @@
#include <linux/types.h>
#include <linux/delay.h>
-#include <asm/uaccess.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <linux/netdevice.h>
@@ -53,13 +52,9 @@ struct netxen_nic_stats {
#define NETXEN_NIC_INVALID_DATA 0xDEADBEEF
static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
- {"rcvd_bad_skb", NETXEN_NIC_STAT(stats.rcvdbadskb)},
{"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)},
- {"xmited_frames", NETXEN_NIC_STAT(stats.xmitedframes)},
{"xmit_finished", NETXEN_NIC_STAT(stats.xmitfinished)},
- {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)},
- {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)},
- {"polled", NETXEN_NIC_STAT(stats.polled)},
+ {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
{"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
{"csummed", NETXEN_NIC_STAT(stats.csummed)},
{"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)},
@@ -97,12 +92,9 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
write_lock_irqsave(&adapter->adapter_lock, flags);
- fw_major = adapter->pci_read_normalize(adapter,
- NETXEN_FW_VERSION_MAJOR);
- fw_minor = adapter->pci_read_normalize(adapter,
- NETXEN_FW_VERSION_MINOR);
- fw_build = adapter->pci_read_normalize(adapter,
- NETXEN_FW_VERSION_SUB);
+ fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+ fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+ fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
write_unlock_irqrestore(&adapter->adapter_lock, flags);
sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
@@ -115,6 +107,7 @@ static int
netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct netxen_adapter *adapter = netdev_priv(dev);
+ int check_sfp_module = 0;
/* read which mode */
if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
@@ -139,7 +132,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
u32 val;
- adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4);
+ val = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
if (val == NETXEN_PORT_MODE_802_3_AP) {
ecmd->supported = SUPPORTED_1000baseT_Full;
ecmd->advertising = ADVERTISED_1000baseT_Full;
@@ -148,13 +141,19 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->advertising = ADVERTISED_10000baseT_Full;
}
+ if (netif_running(dev) && adapter->has_link_events) {
+ ecmd->speed = adapter->link_speed;
+ ecmd->autoneg = adapter->link_autoneg;
+ ecmd->duplex = adapter->link_duplex;
+ goto skip;
+ }
+
ecmd->port = PORT_TP;
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
u16 pcifn = adapter->ahw.pci_func;
- adapter->hw_read_wx(adapter,
- P3_LINK_SPEED_REG(pcifn), &val, 4);
+ val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
ecmd->speed = P3_LINK_SPEED_MHZ *
P3_LINK_SPEED_VAL(pcifn, val);
} else
@@ -165,10 +164,11 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
} else
return -EIO;
+skip:
ecmd->phy_address = adapter->physical_port;
ecmd->transceiver = XCVR_EXTERNAL;
- switch ((netxen_brdtype_t)adapter->ahw.board_type) {
+ switch (adapter->ahw.board_type) {
case NETXEN_BRDTYPE_P2_SB35_4G:
case NETXEN_BRDTYPE_P2_SB31_2G:
case NETXEN_BRDTYPE_P3_REF_QG:
@@ -195,7 +195,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
case NETXEN_BRDTYPE_P3_HMEZ:
ecmd->supported |= SUPPORTED_MII;
ecmd->advertising |= ADVERTISED_MII;
- ecmd->port = PORT_FIBRE;
+ ecmd->port = PORT_MII;
ecmd->autoneg = AUTONEG_DISABLE;
break;
case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
@@ -203,6 +203,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
case NETXEN_BRDTYPE_P3_10G_SFP_QT:
ecmd->advertising |= ADVERTISED_TP;
ecmd->supported |= SUPPORTED_TP;
+ check_sfp_module = netif_running(dev) &&
+ adapter->has_link_events;
case NETXEN_BRDTYPE_P2_SB31_10G:
case NETXEN_BRDTYPE_P3_10G_XFP:
ecmd->supported |= SUPPORTED_FIBRE;
@@ -217,6 +219,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->advertising |=
(ADVERTISED_FIBRE | ADVERTISED_TP);
ecmd->port = PORT_FIBRE;
+ check_sfp_module = netif_running(dev) &&
+ adapter->has_link_events;
} else {
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg);
@@ -227,10 +231,28 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
break;
default:
printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
- (netxen_brdtype_t)adapter->ahw.board_type);
+ adapter->ahw.board_type);
return -EIO;
}
+ if (check_sfp_module) {
+ switch (adapter->module_type) {
+ case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
+ case LINKEVENT_MODULE_OPTICAL_SRLR:
+ case LINKEVENT_MODULE_OPTICAL_LRM:
+ case LINKEVENT_MODULE_OPTICAL_SFP_1G:
+ ecmd->port = PORT_FIBRE;
+ break;
+ case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
+ case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
+ case LINKEVENT_MODULE_TWINAX:
+ ecmd->port = PORT_TP;
+ break;
+ default:
+ ecmd->port = -1;
+ }
+ }
+
return 0;
}
@@ -398,12 +420,11 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
(adapter->pdev)->device;
/* which mode */
- adapter->hw_read_wx(adapter, NETXEN_NIU_MODE, &regs_buff[0], 4);
+ regs_buff[0] = NXRD32(adapter, NETXEN_NIU_MODE);
mode = regs_buff[0];
/* Common registers to all the modes */
- adapter->hw_read_wx(adapter,
- NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER, &regs_buff[2], 4);
+ regs_buff[2] = NXRD32(adapter, NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER);
/* GB/XGB Mode */
mode = (mode / 2) - 1;
window = 0;
@@ -414,9 +435,8 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
window = adapter->physical_port *
NETXEN_NIC_PORT_WINDOW;
- adapter->hw_read_wx(adapter,
- niu_registers[mode].reg[i - 3] + window,
- &regs_buff[i], 4);
+ regs_buff[i] = NXRD32(adapter,
+ niu_registers[mode].reg[i - 3] + window);
}
}
@@ -440,7 +460,7 @@ static u32 netxen_nic_test_link(struct net_device *dev)
return !val;
}
} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
- val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
+ val = NXRD32(adapter, CRB_XG_STATE);
return (val == XG_LINK_UP) ? 0 : 1;
}
return -EIO;
@@ -504,10 +524,9 @@ netxen_nic_get_pauseparam(struct net_device *dev,
if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
return;
/* get flow control settings */
- netxen_nic_read_w0(adapter,NETXEN_NIU_GB_MAC_CONFIG_0(port),
- &val);
+ val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
pause->rx_pause = netxen_gb_get_rx_flowctl(val);
- netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
+ val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
switch (port) {
case 0:
pause->tx_pause = !(netxen_gb_get_gb0_mask(val));
@@ -527,7 +546,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
return;
pause->rx_pause = 1;
- netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
+ val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
if (port == 0)
pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
else
@@ -550,18 +569,17 @@ netxen_nic_set_pauseparam(struct net_device *dev,
if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
return -EIO;
/* set flow control */
- netxen_nic_read_w0(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(port), &val);
+ val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
if (pause->rx_pause)
netxen_gb_rx_flowctl(val);
else
netxen_gb_unset_rx_flowctl(val);
- netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
val);
/* set autoneg */
- netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
+ val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
switch (port) {
case 0:
if (pause->tx_pause)
@@ -589,11 +607,11 @@ netxen_nic_set_pauseparam(struct net_device *dev,
netxen_gb_set_gb3_mask(val);
break;
}
- netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
+ NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
return -EIO;
- netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
+ val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
if (port == 0) {
if (pause->tx_pause)
netxen_xg_unset_xg0_mask(val);
@@ -605,7 +623,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
else
netxen_xg_set_xg1_mask(val);
}
- netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
+ NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
} else {
printk(KERN_ERR "%s: Unknown board type: %x\n",
netxen_nic_driver_name,
@@ -619,14 +637,14 @@ static int netxen_nic_reg_test(struct net_device *dev)
struct netxen_adapter *adapter = netdev_priv(dev);
u32 data_read, data_written;
- netxen_nic_read_w0(adapter, NETXEN_PCIX_PH_REG(0), &data_read);
+ data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0));
if ((data_read & 0xffff) != PHAN_VENDOR_ID)
return 1;
data_written = (u32)0xa5a5a5a5;
- netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written);
- data_read = adapter->pci_read_normalize(adapter, CRB_SCRATCHPAD_TEST);
+ NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
+ data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST);
if (data_written != data_read)
return 1;
@@ -743,11 +761,11 @@ netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
return;
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
if (wol_cfg & (1UL << adapter->portnum))
wol->supported |= WAKE_MAGIC;
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
if (wol_cfg & (1UL << adapter->portnum))
wol->wolopts |= WAKE_MAGIC;
}
@@ -764,16 +782,16 @@ netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (wol->wolopts & ~WAKE_MAGIC)
return -EOPNOTSUPP;
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
if (!(wol_cfg & (1 << adapter->portnum)))
return -EOPNOTSUPP;
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
if (wol->wolopts & WAKE_MAGIC)
wol_cfg |= 1UL << adapter->portnum;
else
wol_cfg &= ~(1UL << adapter->portnum);
- netxen_nic_reg_write(adapter, NETXEN_WOL_CONFIG, wol_cfg);
+ NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg);
return 0;
}
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 016c62129c76..7f0ddbfa7b28 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -31,16 +31,8 @@
#ifndef __NETXEN_NIC_HDR_H_
#define __NETXEN_NIC_HDR_H_
-#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <asm/irq.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
#include <linux/types.h>
-#include <asm/uaccess.h>
-#include <asm/string.h> /* for memset */
/*
* The basic unit of access when reading/writing control registers.
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 5026811c04ce..42ffb825ebf1 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -32,7 +32,6 @@
#include "netxen_nic_hw.h"
#include "netxen_nic_phan_reg.h"
-#include <linux/firmware.h>
#include <net/ip.h>
#define MASK(n) ((1ULL<<(n))-1)
@@ -48,8 +47,49 @@
#define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
#define CRB_INDIRECT_2M (0x1e0000UL)
+#ifndef readq
+static inline u64 readq(void __iomem *addr)
+{
+ return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 val, void __iomem *addr)
+{
+ writel(((u32) (val)), (addr));
+ writel(((u32) (val >> 32)), (addr + 4));
+}
+#endif
+
+#define ADDR_IN_RANGE(addr, low, high) \
+ (((addr) < (high)) && ((addr) >= (low)))
+
+#define PCI_OFFSET_FIRST_RANGE(adapter, off) \
+ ((adapter)->ahw.pci_base0 + (off))
+#define PCI_OFFSET_SECOND_RANGE(adapter, off) \
+ ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
+#define PCI_OFFSET_THIRD_RANGE(adapter, off) \
+ ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)
+
+static void __iomem *pci_base_offset(struct netxen_adapter *adapter,
+ unsigned long off)
+{
+ if (ADDR_IN_RANGE(off, FIRST_PAGE_GROUP_START, FIRST_PAGE_GROUP_END))
+ return PCI_OFFSET_FIRST_RANGE(adapter, off);
+
+ if (ADDR_IN_RANGE(off, SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_END))
+ return PCI_OFFSET_SECOND_RANGE(adapter, off);
+
+ if (ADDR_IN_RANGE(off, THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_END))
+ return PCI_OFFSET_THIRD_RANGE(adapter, off);
+
+ return NULL;
+}
+
#define CRB_WIN_LOCK_TIMEOUT 100000000
-static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
+static crb_128M_2M_block_map_t
+crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
{{{0, 0, 0, 0} } }, /* 0: PCI */
{{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */
{1, 0x0110000, 0x0120000, 0x130000},
@@ -279,39 +319,8 @@ static unsigned crb_hub_agt[64] =
/* PCI Windowing for DDR regions. */
-#define ADDR_IN_RANGE(addr, low, high) \
- (((addr) <= (high)) && ((addr) >= (low)))
-
#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */
-#define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL
-#define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL
-#define NETXEN_NIC_EPG_PAUSE_ADDR1 0x2200010000c28001ULL
-#define NETXEN_NIC_EPG_PAUSE_ADDR2 0x0100088866554433ULL
-
-#define NETXEN_NIC_WINDOW_MARGIN 0x100000
-
-int netxen_nic_set_mac(struct net_device *netdev, void *p)
-{
- struct netxen_adapter *adapter = netdev_priv(netdev);
- struct sockaddr *addr = p;
-
- if (netif_running(netdev))
- return -EBUSY;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-
- /* For P3, MAC addr is not set in NIU */
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
- if (adapter->macaddr_set)
- adapter->macaddr_set(adapter, addr->sa_data);
-
- return 0;
-}
-
#define NETXEN_UNICAST_ADDR(port, index) \
(NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
#define NETXEN_MCAST_ADDR(port, index) \
@@ -331,22 +340,20 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
if (adapter->mc_enabled)
return 0;
- adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+ val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
val |= (1UL << (28+port));
- adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+ NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
/* add broadcast addr to filter */
val = 0xffffff;
- netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_UNICAST_ADDR(port, 0)+4, val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
/* add station addr to filter */
val = MAC_HI(addr);
- netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
val = MAC_LO(addr);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_UNICAST_ADDR(port, 1)+4, val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, val);
adapter->mc_enabled = 1;
return 0;
@@ -362,18 +369,17 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
if (!adapter->mc_enabled)
return 0;
- adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+ val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
val &= ~(1UL << (28+port));
- adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+ NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
val = MAC_HI(addr);
- netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
val = MAC_LO(addr);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_UNICAST_ADDR(port, 0)+4, val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
- netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
adapter->mc_enabled = 0;
return 0;
@@ -389,10 +395,8 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
lo = MAC_LO(addr);
hi = MAC_HI(addr);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_MCAST_ADDR(port, index), hi);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_MCAST_ADDR(port, index)+4, lo);
+ NXWR32(adapter, NETXEN_MCAST_ADDR(port, index), hi);
+ NXWR32(adapter, NETXEN_MCAST_ADDR(port, index)+4, lo);
return 0;
}
@@ -445,100 +449,58 @@ void netxen_p2_nic_set_multi(struct net_device *netdev)
netxen_nic_set_mcast_addr(adapter, index, null_addr);
}
-static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
- u8 *addr, nx_mac_list_t **add_list, nx_mac_list_t **del_list)
-{
- nx_mac_list_t *cur, *prev;
-
- /* if in del_list, move it to adapter->mac_list */
- for (cur = *del_list, prev = NULL; cur;) {
- if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
- if (prev == NULL)
- *del_list = cur->next;
- else
- prev->next = cur->next;
- cur->next = adapter->mac_list;
- adapter->mac_list = cur;
- return 0;
- }
- prev = cur;
- cur = cur->next;
- }
-
- /* make sure to add each mac address only once */
- for (cur = adapter->mac_list; cur; cur = cur->next) {
- if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
- return 0;
- }
- /* not in del_list, create new entry and add to add_list */
- cur = kmalloc(sizeof(*cur), in_atomic()? GFP_ATOMIC : GFP_KERNEL);
- if (cur == NULL) {
- printk(KERN_ERR "%s: cannot allocate memory. MAC filtering may"
- "not work properly from now.\n", __func__);
- return -1;
- }
-
- memcpy(cur->mac_addr, addr, ETH_ALEN);
- cur->next = *add_list;
- *add_list = cur;
- return 0;
-}
-
static int
netxen_send_cmd_descs(struct netxen_adapter *adapter,
- struct cmd_desc_type0 *cmd_desc_arr, int nr_elements)
+ struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
{
- uint32_t i, producer;
+ u32 i, producer, consumer;
struct netxen_cmd_buffer *pbuf;
struct cmd_desc_type0 *cmd_desc;
-
- if (nr_elements > MAX_PENDING_DESC_BLOCK_SIZE || nr_elements == 0) {
- printk(KERN_WARNING "%s: Too many command descriptors in a "
- "request\n", __func__);
- return -EINVAL;
- }
+ struct nx_host_tx_ring *tx_ring;
i = 0;
+ tx_ring = adapter->tx_ring;
netif_tx_lock_bh(adapter->netdev);
- producer = adapter->cmd_producer;
+ producer = tx_ring->producer;
+ consumer = tx_ring->sw_consumer;
+
+ if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) {
+ netif_tx_unlock_bh(adapter->netdev);
+ return -EBUSY;
+ }
+
do {
cmd_desc = &cmd_desc_arr[i];
- pbuf = &adapter->cmd_buf_arr[producer];
+ pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL;
pbuf->frag_count = 0;
- /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */
- memcpy(&adapter->ahw.cmd_desc_head[producer],
+ memcpy(&tx_ring->desc_head[producer],
&cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
- producer = get_next_index(producer,
- adapter->num_txd);
+ producer = get_next_index(producer, tx_ring->num_desc);
i++;
- } while (i != nr_elements);
-
- adapter->cmd_producer = producer;
+ } while (i != nr_desc);
- /* write producer index to start the xmit */
+ tx_ring->producer = producer;
- netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
+ netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
netif_tx_unlock_bh(adapter->netdev);
return 0;
}
-static int nx_p3_sre_macaddr_change(struct net_device *dev,
- u8 *addr, unsigned op)
+static int
+nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op)
{
- struct netxen_adapter *adapter = netdev_priv(dev);
nx_nic_req_t req;
nx_mac_req_t *mac_req;
u64 word;
- int rv;
memset(&req, 0, sizeof(nx_nic_req_t));
req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
@@ -550,28 +512,51 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev,
mac_req->op = op;
memcpy(mac_req->mac_addr, addr, 6);
- rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
- if (rv != 0) {
- printk(KERN_ERR "ERROR. Could not send mac update\n");
- return rv;
+ return netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+}
+
+static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
+ u8 *addr, struct list_head *del_list)
+{
+ struct list_head *head;
+ nx_mac_list_t *cur;
+
+ /* look up if already exists */
+ list_for_each(head, del_list) {
+ cur = list_entry(head, nx_mac_list_t, list);
+
+ if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
+ list_move_tail(head, &adapter->mac_list);
+ return 0;
+ }
}
- return 0;
+ cur = kzalloc(sizeof(nx_mac_list_t), GFP_ATOMIC);
+ if (cur == NULL) {
+ printk(KERN_ERR "%s: failed to add mac address filter\n",
+ adapter->netdev->name);
+ return -ENOMEM;
+ }
+ memcpy(cur->mac_addr, addr, ETH_ALEN);
+ list_add_tail(&cur->list, &adapter->mac_list);
+ return nx_p3_sre_macaddr_change(adapter,
+ cur->mac_addr, NETXEN_MAC_ADD);
}
void netxen_p3_nic_set_multi(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
- nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
struct dev_mc_list *mc_ptr;
u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
u32 mode = VPORT_MISS_MODE_DROP;
+ LIST_HEAD(del_list);
+ struct list_head *head;
+ nx_mac_list_t *cur;
- del_list = adapter->mac_list;
- adapter->mac_list = NULL;
+ list_splice_tail_init(&adapter->mac_list, &del_list);
- nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list);
- nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
+ nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list);
+ nx_p3_nic_add_mac(adapter, bcast_addr, &del_list);
if (netdev->flags & IFF_PROMISC) {
mode = VPORT_MISS_MODE_ACCEPT_ALL;
@@ -587,25 +572,20 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
if (netdev->mc_count > 0) {
for (mc_ptr = netdev->mc_list; mc_ptr;
mc_ptr = mc_ptr->next) {
- nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr,
- &add_list, &del_list);
+ nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list);
}
}
send_fw_cmd:
adapter->set_promisc(adapter, mode);
- for (cur = del_list; cur;) {
- nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL);
- next = cur->next;
+ head = &del_list;
+ while (!list_empty(head)) {
+ cur = list_entry(head->next, nx_mac_list_t, list);
+
+ nx_p3_sre_macaddr_change(adapter,
+ cur->mac_addr, NETXEN_MAC_DEL);
+ list_del(&cur->list);
kfree(cur);
- cur = next;
- }
- for (cur = add_list; cur;) {
- nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_ADD);
- next = cur->next;
- cur->next = adapter->mac_list;
- adapter->mac_list = cur;
- cur = next;
}
}
@@ -630,17 +610,25 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
{
- nx_mac_list_t *cur, *next;
-
- cur = adapter->mac_list;
-
- while (cur) {
- next = cur->next;
+ nx_mac_list_t *cur;
+ struct list_head *head = &adapter->mac_list;
+
+ while (!list_empty(head)) {
+ cur = list_entry(head->next, nx_mac_list_t, list);
+ nx_p3_sre_macaddr_change(adapter,
+ cur->mac_addr, NETXEN_MAC_DEL);
+ list_del(&cur->list);
kfree(cur);
- cur = next;
}
}
+int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
+{
+ /* assuming caller has already copied new addr to netdev */
+ netxen_p3_nic_set_multi(adapter->netdev);
+ return 0;
+}
+
#define NETXEN_CONFIG_INTR_COALESCE 3
/*
@@ -717,6 +705,28 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable)
return rv;
}
+int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
+{
+ nx_nic_req_t req;
+ u64 word;
+ int rv;
+
+ memset(&req, 0, sizeof(nx_nic_req_t));
+ req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+ word = NX_NIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16);
+ req.req_hdr = cpu_to_le64(word);
+ req.words[0] = cpu_to_le64(enable | (enable << 8));
+
+ rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+ if (rv != 0) {
+ printk(KERN_ERR "%s: could not configure link notification\n",
+ adapter->netdev->name);
+ }
+
+ return rv;
+}
+
/*
* netxen_nic_change_mtu - Change the Maximum Transfer Unit
* @returns 0 on success, negative on failure
@@ -812,8 +822,8 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
crbaddr = CRB_MAC_BLOCK_START +
(4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
- adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4);
- adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4);
+ mac_lo = NXRD32(adapter, crbaddr);
+ mac_hi = NXRD32(adapter, crbaddr+4);
if (pci_func & 1)
*mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16));
@@ -831,8 +841,7 @@ static int crb_win_lock(struct netxen_adapter *adapter)
while (!done) {
/* acquire semaphore3 from PCI HW block */
- adapter->hw_read_wx(adapter,
- NETXEN_PCIE_REG(PCIE_SEM7_LOCK), &done, 4);
+ done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK));
if (done == 1)
break;
if (timeout >= CRB_WIN_LOCK_TIMEOUT)
@@ -840,8 +849,7 @@ static int crb_win_lock(struct netxen_adapter *adapter)
timeout++;
udelay(1);
}
- netxen_crb_writelit_adapter(adapter,
- NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
+ NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
return 0;
}
@@ -849,8 +857,7 @@ static void crb_win_unlock(struct netxen_adapter *adapter)
{
int val;
- adapter->hw_read_wx(adapter,
- NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK), &val, 4);
+ val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK));
}
/*
@@ -907,17 +914,15 @@ netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw)
* In: 'off' is offset from base in 128M pci map
*/
static int
-netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
- ulong *off, int len)
+netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off)
{
- unsigned long end = *off + len;
crb_128M_2M_sub_block_map_t *m;
if (*off >= NETXEN_CRB_MAX)
return -1;
- if (*off >= NETXEN_PCI_CAMQM && (end <= NETXEN_PCI_CAMQM_2M_END)) {
+ if (*off >= NETXEN_PCI_CAMQM && (*off < NETXEN_PCI_CAMQM_2M_END)) {
*off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE +
(ulong)adapter->ahw.pci_base0;
return 0;
@@ -927,14 +932,13 @@ netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
return -1;
*off -= NETXEN_PCI_CRBSPACE;
- end = *off + len;
/*
* Try direct map
*/
m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
- if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) {
+ if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) {
*off = *off + m->start_2M - m->start_128M +
(ulong)adapter->ahw.pci_base0;
return 0;
@@ -972,214 +976,11 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
(ulong)adapter->ahw.pci_base0;
}
-static int
-netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname,
- const struct firmware *fw)
-{
- u64 *ptr64;
- u32 i, flashaddr, size;
- struct pci_dev *pdev = adapter->pdev;
-
- if (fw)
- dev_info(&pdev->dev, "loading firmware from file %s\n", fwname);
- else
- dev_info(&pdev->dev, "loading firmware from flash\n");
-
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
- adapter->pci_write_normalize(adapter,
- NETXEN_ROMUSB_GLB_CAS_RST, 1);
-
- if (fw) {
- __le64 data;
-
- size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
-
- ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START];
- flashaddr = NETXEN_BOOTLD_START;
-
- for (i = 0; i < size; i++) {
- data = cpu_to_le64(ptr64[i]);
- adapter->pci_mem_write(adapter, flashaddr, &data, 8);
- flashaddr += 8;
- }
-
- size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET];
- size = (__force u32)cpu_to_le32(size) / 8;
-
- ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START];
- flashaddr = NETXEN_IMAGE_START;
-
- for (i = 0; i < size; i++) {
- data = cpu_to_le64(ptr64[i]);
-
- if (adapter->pci_mem_write(adapter,
- flashaddr, &data, 8))
- return -EIO;
-
- flashaddr += 8;
- }
- } else {
- u32 data;
-
- size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
- flashaddr = NETXEN_BOOTLD_START;
-
- for (i = 0; i < size; i++) {
- if (netxen_rom_fast_read(adapter,
- flashaddr, (int *)&data) != 0)
- return -EIO;
-
- if (adapter->pci_mem_write(adapter,
- flashaddr, &data, 4))
- return -EIO;
-
- flashaddr += 4;
- }
- }
- msleep(1);
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- adapter->pci_write_normalize(adapter,
- NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
- else {
- adapter->pci_write_normalize(adapter,
- NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
- adapter->pci_write_normalize(adapter,
- NETXEN_ROMUSB_GLB_CAS_RST, 0);
- }
-
- return 0;
-}
-
-static int
-netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname,
- const struct firmware *fw)
-{
- __le32 val;
- u32 major, minor, build, ver, min_ver, bios;
- struct pci_dev *pdev = adapter->pdev;
-
- if (fw->size < NX_FW_MIN_SIZE)
- return -EINVAL;
-
- val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
- if ((__force u32)val != NETXEN_BDINFO_MAGIC)
- return -EINVAL;
-
- val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
- major = (__force u32)val & 0xff;
- minor = ((__force u32)val >> 8) & 0xff;
- build = (__force u32)val >> 16;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- min_ver = NETXEN_VERSION_CODE(4, 0, 216);
- else
- min_ver = NETXEN_VERSION_CODE(3, 4, 216);
-
- ver = NETXEN_VERSION_CODE(major, minor, build);
-
- if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
- dev_err(&pdev->dev,
- "%s: firmware version %d.%d.%d unsupported\n",
- fwname, major, minor, build);
- return -EINVAL;
- }
-
- val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
- netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
- if ((__force u32)val != bios) {
- dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
- fwname);
- return -EINVAL;
- }
-
- /* check if flashed firmware is newer */
- if (netxen_rom_fast_read(adapter,
- NX_FW_VERSION_OFFSET, (int *)&val))
- return -EIO;
- major = (__force u32)val & 0xff;
- minor = ((__force u32)val >> 8) & 0xff;
- build = (__force u32)val >> 16;
- if (NETXEN_VERSION_CODE(major, minor, build) > ver)
- return -EINVAL;
-
- netxen_nic_reg_write(adapter, NETXEN_CAM_RAM(0x1fc),
- NETXEN_BDINFO_MAGIC);
- return 0;
-}
-
-static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
-
-int netxen_load_firmware(struct netxen_adapter *adapter)
-{
- u32 capability, flashed_ver;
- const struct firmware *fw;
- int fw_type;
- struct pci_dev *pdev = adapter->pdev;
- int rc = 0;
-
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
- fw_type = NX_P2_MN_ROMIMAGE;
- goto request_fw;
- } else {
- fw_type = NX_P3_CT_ROMIMAGE;
- goto request_fw;
- }
-
-request_mn:
- capability = 0;
-
- netxen_rom_fast_read(adapter,
- NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
- if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
- adapter->hw_read_wx(adapter,
- NX_PEG_TUNE_CAPABILITY, &capability, 4);
- if (capability & NX_PEG_TUNE_MN_PRESENT) {
- fw_type = NX_P3_MN_ROMIMAGE;
- goto request_fw;
- }
- }
-
-request_fw:
- rc = request_firmware(&fw, fw_name[fw_type], &pdev->dev);
- if (rc != 0) {
- if (fw_type == NX_P3_CT_ROMIMAGE) {
- msleep(1);
- goto request_mn;
- }
-
- fw = NULL;
- goto load_fw;
- }
-
- rc = netxen_validate_firmware(adapter, fw_name[fw_type], fw);
- if (rc != 0) {
- release_firmware(fw);
-
- if (fw_type == NX_P3_CT_ROMIMAGE) {
- msleep(1);
- goto request_mn;
- }
-
- fw = NULL;
- }
-
-load_fw:
- rc = netxen_do_load_firmware(adapter, fw_name[fw_type], fw);
-
- if (fw)
- release_firmware(fw);
- return rc;
-}
-
int
-netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
- ulong off, void *data, int len)
+netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
{
void __iomem *addr;
- BUG_ON(len != 4);
-
if (ADDR_IN_WINDOW1(off)) {
addr = NETXEN_CRB_NORMALIZE(adapter, off);
} else { /* Window 0 */
@@ -1192,7 +993,7 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
return 1;
}
- writel(*(u32 *) data, addr);
+ writel(data, addr);
if (!ADDR_IN_WINDOW1(off))
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
@@ -1200,13 +1001,11 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
return 0;
}
-int
-netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
- ulong off, void *data, int len)
+u32
+netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
{
void __iomem *addr;
-
- BUG_ON(len != 4);
+ u32 data;
if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
addr = NETXEN_CRB_NORMALIZE(adapter, off);
@@ -1220,24 +1019,21 @@ netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
return 1;
}
- *(u32 *)data = readl(addr);
+ data = readl(addr);
if (!ADDR_IN_WINDOW1(off))
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
- return 0;
+ return data;
}
int
-netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
- ulong off, void *data, int len)
+netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
{
unsigned long flags = 0;
int rv;
- BUG_ON(len != 4);
-
- rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
+ rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
if (rv == -1) {
printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
@@ -1250,26 +1046,24 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
write_lock_irqsave(&adapter->adapter_lock, flags);
crb_win_lock(adapter);
netxen_nic_pci_set_crbwindow_2M(adapter, &off);
- writel(*(uint32_t *)data, (void __iomem *)off);
+ writel(data, (void __iomem *)off);
crb_win_unlock(adapter);
write_unlock_irqrestore(&adapter->adapter_lock, flags);
} else
- writel(*(uint32_t *)data, (void __iomem *)off);
+ writel(data, (void __iomem *)off);
return 0;
}
-int
-netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
- ulong off, void *data, int len)
+u32
+netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
{
unsigned long flags = 0;
int rv;
+ u32 data;
- BUG_ON(len != 4);
-
- rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
+ rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
if (rv == -1) {
printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
@@ -1282,47 +1076,13 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
write_lock_irqsave(&adapter->adapter_lock, flags);
crb_win_lock(adapter);
netxen_nic_pci_set_crbwindow_2M(adapter, &off);
- *(uint32_t *)data = readl((void __iomem *)off);
+ data = readl((void __iomem *)off);
crb_win_unlock(adapter);
write_unlock_irqrestore(&adapter->adapter_lock, flags);
} else
- *(uint32_t *)data = readl((void __iomem *)off);
-
- return 0;
-}
+ data = readl((void __iomem *)off);
-void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
-{
- adapter->hw_write_wx(adapter, off, &val, 4);
-}
-
-int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
-{
- int val;
- adapter->hw_read_wx(adapter, off, &val, 4);
- return val;
-}
-
-/* Change the window to 0, write and change back to window 1. */
-void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value)
-{
- adapter->hw_write_wx(adapter, index, &value, 4);
-}
-
-/* Change the window to 0, read and change back to window 1. */
-void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value)
-{
- adapter->hw_read_wx(adapter, index, value, 4);
-}
-
-void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value)
-{
- adapter->hw_write_wx(adapter, index, &value, 4);
-}
-
-void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value)
-{
- adapter->hw_read_wx(adapter, index, value, 4);
+ return data;
}
/*
@@ -1425,17 +1185,6 @@ u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off)
return readl((void __iomem *)(pci_base_offset(adapter, off)));
}
-void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter,
- u64 off, u32 data)
-{
- writel(data, NETXEN_CRB_NORMALIZE(adapter, off));
-}
-
-u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off)
-{
- return readl(NETXEN_CRB_NORMALIZE(adapter, off));
-}
-
unsigned long
netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
unsigned long long addr)
@@ -1447,12 +1196,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
/* DDR network side */
window = MN_WIN(addr);
adapter->ahw.ddr_mn_window = window;
- adapter->hw_write_wx(adapter,
- adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
- &window, 4);
- adapter->hw_read_wx(adapter,
- adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
- &win_read, 4);
+ NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+ window);
+ win_read = NXRD32(adapter,
+ adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
if ((win_read << 17) != window) {
printk(KERN_INFO "Written MNwin (0x%x) != "
"Read MNwin (0x%x)\n", window, win_read);
@@ -1467,12 +1214,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
window = OCM_WIN(addr);
adapter->ahw.ddr_mn_window = window;
- adapter->hw_write_wx(adapter,
- adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
- &window, 4);
- adapter->hw_read_wx(adapter,
- adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
- &win_read, 4);
+ NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+ window);
+ win_read = NXRD32(adapter,
+ adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
if ((win_read >> 7) != window) {
printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
"Read OCMwin (0x%x)\n",
@@ -1485,12 +1230,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
/* QDR network side */
window = MS_WIN(addr);
adapter->ahw.qdr_sn_window = window;
- adapter->hw_write_wx(adapter,
- adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
- &window, 4);
- adapter->hw_read_wx(adapter,
- adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
- &win_read, 4);
+ NXWR32(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
+ window);
+ win_read = NXRD32(adapter,
+ adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE);
if (win_read != window) {
printk(KERN_INFO "%s: Written MSwin (0x%x) != "
"Read MSwin (0x%x)\n",
@@ -1936,27 +1679,20 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
for (i = 0; i < loop; i++) {
temp = off8 + (i << 3);
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
temp = 0;
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
temp = word[i] & 0xffffffff;
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
temp = (word[i] >> 32) & 0xffffffff;
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
for (j = 0; j < MAX_CTL_CHECK; j++) {
- adapter->hw_read_wx(adapter,
- mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+ temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
@@ -2013,21 +1749,16 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
for (i = 0; i < loop; i++) {
temp = off8 + (i << 3);
- adapter->hw_write_wx(adapter,
- mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
+ NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
temp = 0;
- adapter->hw_write_wx(adapter,
- mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
+ NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
temp = MIU_TA_CTL_ENABLE;
- adapter->hw_write_wx(adapter,
- mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+ NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
- adapter->hw_write_wx(adapter,
- mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+ NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
for (j = 0; j < MAX_CTL_CHECK; j++) {
- adapter->hw_read_wx(adapter,
- mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+ temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
@@ -2042,8 +1773,8 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
start = off0[i] >> 2;
end = (off0[i] + sz[i] - 1) >> 2;
for (k = start; k <= end; k++) {
- adapter->hw_read_wx(adapter,
- mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
+ temp = NXRD32(adapter,
+ mem_crb + MIU_TEST_AGT_RDDATA(k));
word[i] |= ((uint64_t)temp << (32 * k));
}
}
@@ -2086,29 +1817,14 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
u64 off, u32 data)
{
- adapter->hw_write_wx(adapter, off, &data, 4);
+ NXWR32(adapter, off, data);
return 0;
}
u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off)
{
- u32 temp;
- adapter->hw_read_wx(adapter, off, &temp, 4);
- return temp;
-}
-
-void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter,
- u64 off, u32 data)
-{
- adapter->hw_write_wx(adapter, off, &data, 4);
-}
-
-u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off)
-{
- u32 temp;
- adapter->hw_read_wx(adapter, off, &temp, 4);
- return temp;
+ return NXRD32(adapter, off);
}
int netxen_nic_get_board_info(struct netxen_adapter *adapter)
@@ -2142,13 +1858,12 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
adapter->ahw.board_type = board_type;
if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
- u32 gpio = netxen_nic_reg_read(adapter,
- NETXEN_ROMUSB_GLB_PAD_GPIO_I);
+ u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I);
if ((gpio & 0x8000) == 0)
board_type = NETXEN_BRDTYPE_P3_10G_TP;
}
- switch ((netxen_brdtype_t)board_type) {
+ switch (board_type) {
case NETXEN_BRDTYPE_P2_SB35_4G:
adapter->ahw.port_type = NETXEN_NIC_GBE;
break;
@@ -2195,8 +1910,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
{
new_mtu += MTU_FUDGE_FACTOR;
- netxen_nic_write_w0(adapter,
- NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
+ NXWR32(adapter, NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
new_mtu);
return 0;
}
@@ -2205,21 +1919,12 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
{
new_mtu += MTU_FUDGE_FACTOR;
if (adapter->physical_port == 0)
- netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
- new_mtu);
+ NXWR32(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
else
- netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE,
- new_mtu);
+ NXWR32(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu);
return 0;
}
-void
-netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
- unsigned long off, int data)
-{
- adapter->hw_write_wx(adapter, off, &data, 4);
-}
-
void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
{
__u32 status;
@@ -2234,8 +1939,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
}
if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
- adapter->hw_read_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &port_mode, 4);
+ port_mode = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
adapter->link_speed = SPEED_1000;
adapter->link_duplex = DUPLEX_FULL;
@@ -2312,9 +2016,9 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
addr += sizeof(u32);
}
- adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MAJOR, &fw_major, 4);
- adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR, &fw_minor, 4);
- adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4);
+ fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+ fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+ fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
adapter->fw_major = fw_major;
adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
@@ -2337,8 +2041,7 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
fw_major, fw_minor, fw_build);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- adapter->hw_read_wx(adapter,
- NETXEN_MIU_MN_CONTROL, &i, 4);
+ i = NXRD32(adapter, NETXEN_MIU_MN_CONTROL);
adapter->ahw.cut_through = (i & 0x4) ? 1 : 0;
dev_info(&pdev->dev, "firmware running in %s mode\n",
adapter->ahw.cut_through ? "cut-through" : "legacy");
@@ -2353,9 +2056,9 @@ netxen_nic_wol_supported(struct netxen_adapter *adapter)
if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
return 0;
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
if (wol_cfg & (1UL << adapter->portnum)) {
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
if (wol_cfg & (1 << adapter->portnum))
return 1;
}
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index 04b47a7993cd..d4e833339781 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -36,35 +36,13 @@
/* Hardware memory size of 128 meg */
#define NETXEN_MEMADDR_MAX (128 * 1024 * 1024)
-#ifndef readq
-static inline u64 readq(void __iomem * addr)
-{
- return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
-}
-#endif
-
-#ifndef writeq
-static inline void writeq(u64 val, void __iomem * addr)
-{
- writel(((u32) (val)), (addr));
- writel(((u32) (val >> 32)), (addr + 4));
-}
-#endif
-
struct netxen_adapter;
#define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20)
-struct netxen_port;
void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
-typedef u8 netxen_ethernet_macaddr_t[6];
-
/* Nibble or Byte mode for phy interface (GbE mode only) */
-typedef enum {
- NETXEN_NIU_10_100_MB = 0,
- NETXEN_NIU_1000_MB
-} netxen_niu_gbe_ifmode_t;
#define _netxen_crb_get_bit(var, bit) ((var >> bit) & 0x1)
@@ -222,30 +200,28 @@ typedef enum {
/*
* PHY-Specific MII control/status registers.
*/
-typedef enum {
- NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL = 0,
- NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS = 1,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0 = 2,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1 = 3,
- NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG = 4,
- NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART = 5,
- NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE = 6,
- NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT = 7,
- NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE = 8,
- NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL = 9,
- NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS = 10,
- NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS = 15,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL = 16,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS = 17,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE = 18,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS = 19,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE = 20,
- NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT = 21,
- NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL = 24,
- NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE = 25,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET = 26,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE = 27
-} netxen_niu_phy_register_t;
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL 0
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS 1
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0 2
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1 3
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG 4
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART 5
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE 6
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT 7
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE 8
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL 9
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS 10
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS 15
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL 16
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS 17
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE 18
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS 19
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE 20
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT 21
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL 24
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE 25
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET 26
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE 27
/*
* PHY-Specific Status Register (reg 17).
@@ -417,14 +393,6 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
u32 mode);
-/* set the MAC address for a given MAC */
-int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t addr);
-
-/* XG version */
-int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t addr);
-
/* Generic enable for GbE ports. Will detect the speed of the link. */
int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port);
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 0759c35f16ac..4a51c31330da 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -108,42 +108,6 @@ static void crb_addr_transform_setup(void)
crb_addr_transform(I2C0);
}
-int netxen_init_firmware(struct netxen_adapter *adapter)
-{
- u32 state = 0, loops = 0, err = 0;
-
- /* Window 1 call */
- state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
-
- if (state == PHAN_INITIALIZE_ACK)
- return 0;
-
- while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) {
- msleep(1);
- /* Window 1 call */
- state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
-
- loops++;
- }
- if (loops >= 2000) {
- printk(KERN_ERR "Cmd Peg initialization not complete:%x.\n",
- state);
- err = -EIO;
- return err;
- }
- /* Window 1 call */
- adapter->pci_write_normalize(adapter,
- CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
- adapter->pci_write_normalize(adapter,
- CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
- adapter->pci_write_normalize(adapter,
- CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
- adapter->pci_write_normalize(adapter,
- CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
-
- return err;
-}
-
void netxen_release_rx_buffers(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
@@ -173,9 +137,10 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
struct netxen_cmd_buffer *cmd_buf;
struct netxen_skb_frag *buffrag;
int i, j;
+ struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
- cmd_buf = adapter->cmd_buf_arr;
- for (i = 0; i < adapter->num_txd; i++) {
+ cmd_buf = tx_ring->cmd_buf_arr;
+ for (i = 0; i < tx_ring->num_desc; i++) {
buffrag = cmd_buf->frag_array;
if (buffrag->dma) {
pci_unmap_single(adapter->pdev, buffrag->dma,
@@ -203,9 +168,14 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_tx_ring *tx_ring;
int ring;
recv_ctx = &adapter->recv_ctx;
+
+ if (recv_ctx->rds_rings == NULL)
+ goto skip_rds;
+
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
if (rds_ring->rx_buf_arr) {
@@ -213,10 +183,15 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
rds_ring->rx_buf_arr = NULL;
}
}
+ kfree(recv_ctx->rds_rings);
- if (adapter->cmd_buf_arr)
- vfree(adapter->cmd_buf_arr);
- return;
+skip_rds:
+ if (adapter->tx_ring == NULL)
+ return;
+
+ tx_ring = adapter->tx_ring;
+ if (tx_ring->cmd_buf_arr)
+ vfree(tx_ring->cmd_buf_arr);
}
int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
@@ -224,23 +199,45 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring;
+ struct nx_host_tx_ring *tx_ring;
struct netxen_rx_buffer *rx_buf;
- int ring, i, num_rx_bufs;
+ int ring, i, size;
struct netxen_cmd_buffer *cmd_buf_arr;
struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
- cmd_buf_arr =
- (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(adapter));
+ size = sizeof(struct nx_host_tx_ring);
+ tx_ring = kzalloc(size, GFP_KERNEL);
+ if (tx_ring == NULL) {
+ dev_err(&pdev->dev, "%s: failed to allocate tx ring struct\n",
+ netdev->name);
+ return -ENOMEM;
+ }
+ adapter->tx_ring = tx_ring;
+
+ tx_ring->num_desc = adapter->num_txd;
+
+ cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring));
if (cmd_buf_arr == NULL) {
- printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
+ dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n",
netdev->name);
return -ENOMEM;
}
- memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(adapter));
- adapter->cmd_buf_arr = cmd_buf_arr;
+ memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
+ tx_ring->cmd_buf_arr = cmd_buf_arr;
recv_ctx = &adapter->recv_ctx;
+
+ size = adapter->max_rds_rings * sizeof (struct nx_host_rds_ring);
+ rds_ring = kzalloc(size, GFP_KERNEL);
+ if (rds_ring == NULL) {
+ dev_err(&pdev->dev, "%s: failed to allocate rds ring struct\n",
+ netdev->name);
+ return -ENOMEM;
+ }
+ recv_ctx->rds_rings = rds_ring;
+
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
switch (ring) {
@@ -292,9 +289,8 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
* Now go through all of them, set reference handles
* and put them in the queues.
*/
- num_rx_bufs = rds_ring->num_desc;
rx_buf = rds_ring->rx_buf_arr;
- for (i = 0; i < num_rx_bufs; i++) {
+ for (i = 0; i < rds_ring->num_desc; i++) {
list_add_tail(&rx_buf->list,
&rds_ring->free_list);
rx_buf->ref_handle = i;
@@ -307,8 +303,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
sds_ring->irq = adapter->msix_entries[ring].vector;
- sds_ring->clean_tx = (ring == 0);
- sds_ring->post_rxd = (ring == 0);
sds_ring->adapter = adapter;
sds_ring->num_desc = adapter->num_rxd;
@@ -325,13 +319,15 @@ err_out:
void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
{
+ adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
+ adapter->set_multi = netxen_p2_nic_set_multi;
+
switch (adapter->ahw.port_type) {
case NETXEN_NIC_GBE:
adapter->enable_phy_interrupts =
netxen_niu_gbe_enable_phy_interrupts;
adapter->disable_phy_interrupts =
netxen_niu_gbe_disable_phy_interrupts;
- adapter->macaddr_set = netxen_niu_macaddr_set;
adapter->set_mtu = netxen_nic_set_mtu_gb;
adapter->set_promisc = netxen_niu_set_promiscuous_mode;
adapter->phy_read = netxen_niu_gbe_phy_read;
@@ -345,7 +341,6 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
netxen_niu_xgbe_enable_phy_interrupts;
adapter->disable_phy_interrupts =
netxen_niu_xgbe_disable_phy_interrupts;
- adapter->macaddr_set = netxen_niu_xg_macaddr_set;
adapter->set_mtu = netxen_nic_set_mtu_xgb;
adapter->init_port = netxen_niu_xg_init_port;
adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
@@ -359,6 +354,8 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
adapter->set_mtu = nx_fw_cmd_set_mtu;
adapter->set_promisc = netxen_p3_nic_set_promisc;
+ adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
+ adapter->set_multi = netxen_p3_nic_set_multi;
}
}
@@ -400,8 +397,7 @@ static int rom_lock(struct netxen_adapter *adapter)
while (!done) {
/* acquire semaphore2 from PCI HW block */
- netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK),
- &done);
+ done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK));
if (done == 1)
break;
if (timeout >= rom_lock_timeout)
@@ -418,7 +414,7 @@ static int rom_lock(struct netxen_adapter *adapter)
cpu_relax(); /*This a nop instr on i386 */
}
}
- netxen_nic_reg_write(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
+ NXWR32(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
return 0;
}
@@ -430,7 +426,7 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
cond_resched();
while (done == 0) {
- done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS);
+ done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS);
done &= 2;
timeout++;
if (timeout >= rom_max_timeout) {
@@ -443,30 +439,28 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
static void netxen_rom_unlock(struct netxen_adapter *adapter)
{
- u32 val;
-
/* release semaphore2 */
- netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val);
+ NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK));
}
static int do_rom_fast_read(struct netxen_adapter *adapter,
int addr, int *valp)
{
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
if (netxen_wait_rom_done(adapter)) {
printk("Error waiting for rom done\n");
return -EIO;
}
/* reset abyte_cnt and dummy_byte_cnt */
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
udelay(10);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
- *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
+ *valp = NXRD32(adapter, NETXEN_ROMUSB_ROM_RDATA);
return 0;
}
@@ -530,8 +524,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
/* resetall */
rom_lock(adapter);
- netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
- 0xffffffff);
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff);
netxen_rom_unlock(adapter);
if (verbose) {
@@ -655,7 +648,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
}
}
- adapter->hw_write_wx(adapter, off, &buf[i].data, 4);
+ NXWR32(adapter, off, buf[i].data);
msleep(init_delay);
}
@@ -665,36 +658,230 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
/* unreset_net_cache */
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
- adapter->hw_read_wx(adapter,
- NETXEN_ROMUSB_GLB_SW_RESET, &val, 4);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
+ val = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET);
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
}
/* p2dn replyCount */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
/* disable_peg_cache 0 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
/* disable_peg_cache 1 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);
/* peg_clr_all */
/* peg_clr 0 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
/* peg_clr 1 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
/* peg_clr 2 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
/* peg_clr 3 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
+ return 0;
+}
+
+int
+netxen_load_firmware(struct netxen_adapter *adapter)
+{
+ u64 *ptr64;
+ u32 i, flashaddr, size;
+ const struct firmware *fw = adapter->fw;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1);
+
+ if (fw) {
+ __le64 data;
+
+ size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
+
+ ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START];
+ flashaddr = NETXEN_BOOTLD_START;
+
+ for (i = 0; i < size; i++) {
+ data = cpu_to_le64(ptr64[i]);
+ adapter->pci_mem_write(adapter, flashaddr, &data, 8);
+ flashaddr += 8;
+ }
+
+ size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET];
+ size = (__force u32)cpu_to_le32(size) / 8;
+
+ ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START];
+ flashaddr = NETXEN_IMAGE_START;
+
+ for (i = 0; i < size; i++) {
+ data = cpu_to_le64(ptr64[i]);
+
+ if (adapter->pci_mem_write(adapter,
+ flashaddr, &data, 8))
+ return -EIO;
+
+ flashaddr += 8;
+ }
+ } else {
+ u32 data;
+
+ size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
+ flashaddr = NETXEN_BOOTLD_START;
+
+ for (i = 0; i < size; i++) {
+ if (netxen_rom_fast_read(adapter,
+ flashaddr, (int *)&data) != 0)
+ return -EIO;
+
+ if (adapter->pci_mem_write(adapter,
+ flashaddr, &data, 4))
+ return -EIO;
+
+ flashaddr += 4;
+ }
+ }
+ msleep(1);
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
+ else {
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0);
+ }
+
+ return 0;
+}
+
+static int
+netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
+{
+ __le32 val;
+ u32 major, minor, build, ver, min_ver, bios;
+ struct pci_dev *pdev = adapter->pdev;
+ const struct firmware *fw = adapter->fw;
+
+ if (fw->size < NX_FW_MIN_SIZE)
+ return -EINVAL;
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
+ if ((__force u32)val != NETXEN_BDINFO_MAGIC)
+ return -EINVAL;
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
+ major = (__force u32)val & 0xff;
+ minor = ((__force u32)val >> 8) & 0xff;
+ build = (__force u32)val >> 16;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ min_ver = NETXEN_VERSION_CODE(4, 0, 216);
+ else
+ min_ver = NETXEN_VERSION_CODE(3, 4, 216);
+
+ ver = NETXEN_VERSION_CODE(major, minor, build);
+
+ if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
+ dev_err(&pdev->dev,
+ "%s: firmware version %d.%d.%d unsupported\n",
+ fwname, major, minor, build);
+ return -EINVAL;
+ }
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
+ netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
+ if ((__force u32)val != bios) {
+ dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
+ fwname);
+ return -EINVAL;
+ }
+
+ /* check if flashed firmware is newer */
+ if (netxen_rom_fast_read(adapter,
+ NX_FW_VERSION_OFFSET, (int *)&val))
+ return -EIO;
+ major = (__force u32)val & 0xff;
+ minor = ((__force u32)val >> 8) & 0xff;
+ build = (__force u32)val >> 16;
+ if (NETXEN_VERSION_CODE(major, minor, build) > ver)
+ return -EINVAL;
+
+ NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
return 0;
}
+static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
+
+void netxen_request_firmware(struct netxen_adapter *adapter)
+{
+ u32 capability, flashed_ver;
+ int fw_type;
+ struct pci_dev *pdev = adapter->pdev;
+ int rc = 0;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ fw_type = NX_P2_MN_ROMIMAGE;
+ goto request_fw;
+ } else {
+ fw_type = NX_P3_CT_ROMIMAGE;
+ goto request_fw;
+ }
+
+request_mn:
+ capability = 0;
+
+ netxen_rom_fast_read(adapter,
+ NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
+ if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
+ capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY);
+ if (capability & NX_PEG_TUNE_MN_PRESENT) {
+ fw_type = NX_P3_MN_ROMIMAGE;
+ goto request_fw;
+ }
+ }
+
+request_fw:
+ rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev);
+ if (rc != 0) {
+ if (fw_type == NX_P3_CT_ROMIMAGE) {
+ msleep(1);
+ goto request_mn;
+ }
+
+ adapter->fw = NULL;
+ goto done;
+ }
+
+ rc = netxen_validate_firmware(adapter, fw_name[fw_type]);
+ if (rc != 0) {
+ release_firmware(adapter->fw);
+
+ if (fw_type == NX_P3_CT_ROMIMAGE) {
+ msleep(1);
+ goto request_mn;
+ }
+
+ adapter->fw = NULL;
+ goto done;
+ }
+
+done:
+ if (adapter->fw)
+ dev_info(&pdev->dev, "loading firmware from file %s\n",
+ fw_name[fw_type]);
+ else
+ dev_info(&pdev->dev, "loading firmware from flash\n");
+}
+
+
+void
+netxen_release_firmware(struct netxen_adapter *adapter)
+{
+ if (adapter->fw)
+ release_firmware(adapter->fw);
+}
+
int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
{
uint64_t addr;
@@ -715,12 +902,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
hi = (addr >> 32) & 0xffffffff;
lo = addr & 0xffffffff;
- adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
- adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
+ NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
+ NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
uint32_t temp = 0;
- adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, &temp, 4);
+ NXWR32(adapter, CRB_HOST_DUMMY_BUF, temp);
}
return 0;
@@ -762,8 +949,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
if (!pegtune_val) {
do {
- val = adapter->pci_read_normalize(adapter,
- CRB_CMDPEG_STATE);
+ val = NXRD32(adapter, CRB_CMDPEG_STATE);
if (val == PHAN_INITIALIZE_COMPLETE ||
val == PHAN_INITIALIZE_ACK)
@@ -774,7 +960,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
} while (--retries);
if (!retries) {
- pegtune_val = adapter->pci_read_normalize(adapter,
+ pegtune_val = NXRD32(adapter,
NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
printk(KERN_WARNING "netxen_phantom_init: init failed, "
"pegtune_val=%x\n", pegtune_val);
@@ -785,13 +971,14 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
return 0;
}
-int netxen_receive_peg_ready(struct netxen_adapter *adapter)
+static int
+netxen_receive_peg_ready(struct netxen_adapter *adapter)
{
u32 val = 0;
int retries = 2000;
do {
- val = adapter->pci_read_normalize(adapter, CRB_RCVPEG_STATE);
+ val = NXRD32(adapter, CRB_RCVPEG_STATE);
if (val == PHAN_PEG_RCV_INITIALIZED)
return 0;
@@ -809,6 +996,93 @@ int netxen_receive_peg_ready(struct netxen_adapter *adapter)
return 0;
}
+int netxen_init_firmware(struct netxen_adapter *adapter)
+{
+ int err;
+
+ err = netxen_receive_peg_ready(adapter);
+ if (err)
+ return err;
+
+ NXWR32(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
+ NXWR32(adapter, CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
+ NXWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
+ NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
+
+ if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) {
+ adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
+ }
+
+ return err;
+}
+
+static void
+netxen_handle_linkevent(struct netxen_adapter *adapter, nx_fw_msg_t *msg)
+{
+ u32 cable_OUI;
+ u16 cable_len;
+ u16 link_speed;
+ u8 link_status, module, duplex, autoneg;
+ struct net_device *netdev = adapter->netdev;
+
+ adapter->has_link_events = 1;
+
+ cable_OUI = msg->body[1] & 0xffffffff;
+ cable_len = (msg->body[1] >> 32) & 0xffff;
+ link_speed = (msg->body[1] >> 48) & 0xffff;
+
+ link_status = msg->body[2] & 0xff;
+ duplex = (msg->body[2] >> 16) & 0xff;
+ autoneg = (msg->body[2] >> 24) & 0xff;
+
+ module = (msg->body[2] >> 8) & 0xff;
+ if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE) {
+ printk(KERN_INFO "%s: unsupported cable: OUI 0x%x, length %d\n",
+ netdev->name, cable_OUI, cable_len);
+ } else if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN) {
+ printk(KERN_INFO "%s: unsupported cable length %d\n",
+ netdev->name, cable_len);
+ }
+
+ netxen_advert_link_change(adapter, link_status);
+
+ /* update link parameters */
+ if (duplex == LINKEVENT_FULL_DUPLEX)
+ adapter->link_duplex = DUPLEX_FULL;
+ else
+ adapter->link_duplex = DUPLEX_HALF;
+ adapter->module_type = module;
+ adapter->link_autoneg = autoneg;
+ adapter->link_speed = link_speed;
+}
+
+static void
+netxen_handle_fw_message(int desc_cnt, int index,
+ struct nx_host_sds_ring *sds_ring)
+{
+ nx_fw_msg_t msg;
+ struct status_desc *desc;
+ int i = 0, opcode;
+
+ while (desc_cnt > 0 && i < 8) {
+ desc = &sds_ring->desc_head[index];
+ msg.words[i++] = le64_to_cpu(desc->status_desc_data[0]);
+ msg.words[i++] = le64_to_cpu(desc->status_desc_data[1]);
+
+ index = get_next_index(index, sds_ring->num_desc);
+ desc_cnt--;
+ }
+
+ opcode = netxen_get_nic_msg_opcode(msg.body[0]);
+ switch (opcode) {
+ case NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE:
+ netxen_handle_linkevent(sds_ring->adapter, &msg);
+ break;
+ default:
+ break;
+ }
+}
+
static int
netxen_alloc_rx_skb(struct netxen_adapter *adapter,
struct nx_host_rds_ring *rds_ring,
@@ -874,7 +1148,8 @@ no_skb:
static struct netxen_rx_buffer *
netxen_process_rcv(struct netxen_adapter *adapter,
- int ring, int index, int length, int cksum, int pkt_offset)
+ int ring, int index, int length, int cksum, int pkt_offset,
+ struct nx_host_sds_ring *sds_ring)
{
struct net_device *netdev = adapter->netdev;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
@@ -902,7 +1177,7 @@ netxen_process_rcv(struct netxen_adapter *adapter,
skb->protocol = eth_type_trans(skb, netdev);
- netif_receive_skb(skb);
+ napi_gro_receive(&sds_ring->napi, skb);
adapter->stats.no_rcv++;
adapter->stats.rxbytes += length;
@@ -927,35 +1202,53 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
int count = 0;
u64 sts_data;
- int opcode, ring, index, length, cksum, pkt_offset;
+ int opcode, ring, index, length, cksum, pkt_offset, desc_cnt;
while (count < max) {
desc = &sds_ring->desc_head[consumer];
- sts_data = le64_to_cpu(desc->status_desc_data);
+ sts_data = le64_to_cpu(desc->status_desc_data[0]);
if (!(sts_data & STATUS_OWNER_HOST))
break;
+ desc_cnt = netxen_get_sts_desc_cnt(sts_data);
ring = netxen_get_sts_type(sts_data);
+
if (ring > RCV_RING_JUMBO)
- continue;
+ goto skip;
opcode = netxen_get_sts_opcode(sts_data);
+ switch (opcode) {
+ case NETXEN_NIC_RXPKT_DESC:
+ case NETXEN_OLD_RXPKT_DESC:
+ break;
+ case NETXEN_NIC_RESPONSE_DESC:
+ netxen_handle_fw_message(desc_cnt, consumer, sds_ring);
+ default:
+ goto skip;
+ }
+
+ WARN_ON(desc_cnt > 1);
+
index = netxen_get_sts_refhandle(sts_data);
length = netxen_get_sts_totallength(sts_data);
cksum = netxen_get_sts_status(sts_data);
pkt_offset = netxen_get_sts_pkt_offset(sts_data);
rxbuf = netxen_process_rcv(adapter, ring, index,
- length, cksum, pkt_offset);
+ length, cksum, pkt_offset, sds_ring);
if (rxbuf)
list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
- desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
-
- consumer = get_next_index(consumer, sds_ring->num_desc);
+skip:
+ for (; desc_cnt > 0; desc_cnt--) {
+ desc = &sds_ring->desc_head[consumer];
+ desc->status_desc_data[0] =
+ cpu_to_le64(STATUS_OWNER_PHANTOM);
+ consumer = get_next_index(consumer, sds_ring->num_desc);
+ }
count++;
}
@@ -980,8 +1273,7 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
if (count) {
sds_ring->consumer = consumer;
- adapter->pci_write_normalize(adapter,
- sds_ring->crb_sts_consumer, consumer);
+ NXWR32(adapter, sds_ring->crb_sts_consumer, consumer);
}
return count;
@@ -990,23 +1282,24 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
/* Process Command status ring */
int netxen_process_cmd_ring(struct netxen_adapter *adapter)
{
- u32 last_consumer, consumer;
+ u32 sw_consumer, hw_consumer;
int count = 0, i;
struct netxen_cmd_buffer *buffer;
struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
struct netxen_skb_frag *frag;
int done = 0;
+ struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
if (!spin_trylock(&adapter->tx_clean_lock))
return 1;
- last_consumer = adapter->last_cmd_consumer;
- barrier(); /* cmd_consumer can change underneath */
- consumer = le32_to_cpu(*(adapter->cmd_consumer));
+ sw_consumer = tx_ring->sw_consumer;
+ barrier(); /* hw_consumer can change underneath */
+ hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
- while (last_consumer != consumer) {
- buffer = &adapter->cmd_buf_arr[last_consumer];
+ while (sw_consumer != hw_consumer) {
+ buffer = &tx_ring->cmd_buf_arr[sw_consumer];
if (buffer->skb) {
frag = &buffer->frag_array[0];
pci_unmap_single(pdev, frag->dma, frag->length,
@@ -1024,16 +1317,16 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
buffer->skb = NULL;
}
- last_consumer = get_next_index(last_consumer,
- adapter->num_txd);
+ sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc);
if (++count >= MAX_STATUS_HANDLE)
break;
}
- if (count) {
- adapter->last_cmd_consumer = last_consumer;
+ tx_ring->sw_consumer = sw_consumer;
+
+ if (count && netif_running(netdev)) {
smp_mb();
- if (netif_queue_stopped(netdev) && netif_running(netdev)) {
+ if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
netif_tx_lock(netdev);
netif_wake_queue(netdev);
smp_mb();
@@ -1053,9 +1346,9 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
* There is still a possible race condition and the host could miss an
* interrupt. The card has to take care of this.
*/
- barrier(); /* cmd_consumer can change underneath */
- consumer = le32_to_cpu(*(adapter->cmd_consumer));
- done = (last_consumer == consumer);
+ barrier(); /* hw_consumer can change underneath */
+ hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
+ done = (sw_consumer == hw_consumer);
spin_unlock(&adapter->tx_clean_lock);
return (done);
@@ -1099,8 +1392,7 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
if (count) {
rds_ring->producer = producer;
- adapter->pci_write_normalize(adapter,
- rds_ring->crb_rcv_producer,
+ NXWR32(adapter, rds_ring->crb_rcv_producer,
(producer-1) & (rds_ring->num_desc-1));
if (adapter->fw_major < 4) {
@@ -1160,10 +1452,8 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
if (count) {
rds_ring->producer = producer;
- adapter->pci_write_normalize(adapter,
- rds_ring->crb_rcv_producer,
+ NXWR32(adapter, rds_ring->crb_rcv_producer,
(producer - 1) & (rds_ring->num_desc - 1));
- wmb();
}
spin_unlock(&rds_ring->lock);
}
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index aef77289bd34..86ca0812dd48 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -29,7 +29,7 @@
*/
#include <linux/vmalloc.h>
-#include <linux/highmem.h>
+#include <linux/interrupt.h>
#include "netxen_nic_hw.h"
#include "netxen_nic.h"
@@ -107,10 +107,9 @@ static uint32_t crb_cmd_producer[4] = {
void
netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
- uint32_t crb_producer)
+ struct nx_host_tx_ring *tx_ring, u32 producer)
{
- adapter->pci_write_normalize(adapter,
- adapter->crb_addr_cmd_producer, crb_producer);
+ NXWR32(adapter, tx_ring->crb_cmd_producer, producer);
}
static uint32_t crb_cmd_consumer[4] = {
@@ -120,10 +119,9 @@ static uint32_t crb_cmd_consumer[4] = {
static inline void
netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
- u32 crb_consumer)
+ struct nx_host_tx_ring *tx_ring, u32 consumer)
{
- adapter->pci_write_normalize(adapter,
- adapter->crb_addr_cmd_consumer, crb_consumer);
+ NXWR32(adapter, tx_ring->crb_cmd_consumer, consumer);
}
static uint32_t msi_tgt_status[8] = {
@@ -139,37 +137,54 @@ static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
{
struct netxen_adapter *adapter = sds_ring->adapter;
- adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0);
+ NXWR32(adapter, sds_ring->crb_intr_mask, 0);
}
static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
{
struct netxen_adapter *adapter = sds_ring->adapter;
- adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0x1);
+ NXWR32(adapter, sds_ring->crb_intr_mask, 0x1);
if (!NETXEN_IS_MSI_FAMILY(adapter))
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_mask_reg, 0xfbff);
}
+static int
+netxen_alloc_sds_rings(struct netxen_recv_context *recv_ctx, int count)
+{
+ int size = sizeof(struct nx_host_sds_ring) * count;
+
+ recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL);
+
+ return (recv_ctx->sds_rings == NULL);
+}
+
static void
+netxen_free_sds_rings(struct netxen_recv_context *recv_ctx)
+{
+ if (recv_ctx->sds_rings != NULL)
+ kfree(recv_ctx->sds_rings);
+}
+
+static int
netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
{
int ring;
struct nx_host_sds_ring *sds_ring;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
- adapter->max_sds_rings = (num_online_cpus() >= 4) ? 4 : 2;
- else
- adapter->max_sds_rings = 1;
+ if (netxen_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
+ return 1;
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
netif_napi_add(netdev, &sds_ring->napi,
netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
}
+
+ return 0;
}
static void
@@ -195,8 +210,9 @@ netxen_napi_disable(struct netxen_adapter *adapter)
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
- netxen_nic_disable_int(sds_ring);
napi_disable(&sds_ring->napi);
+ netxen_nic_disable_int(sds_ring);
+ synchronize_irq(sds_ring->irq);
}
}
@@ -240,7 +256,7 @@ nx_update_dma_mask(struct netxen_adapter *adapter)
change = 0;
- shift = netxen_nic_reg_read(adapter, CRB_DMA_SHIFT);
+ shift = NXRD32(adapter, CRB_DMA_SHIFT);
if (shift >= 32)
return 0;
@@ -268,10 +284,21 @@ static void netxen_check_options(struct netxen_adapter *adapter)
else if (adapter->ahw.port_type == NETXEN_NIC_GBE)
adapter->num_rxd = MAX_RCV_DESCRIPTORS_1G;
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ adapter->msix_supported = 0;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
adapter->msix_supported = !!use_msi_x;
- else
- adapter->msix_supported = 0;
+ adapter->rss_supported = !!use_msi_x;
+ } else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) {
+ switch (adapter->ahw.board_type) {
+ case NETXEN_BRDTYPE_P2_SB31_10G:
+ case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
+ adapter->msix_supported = !!use_msi_x;
+ adapter->rss_supported = !!use_msi_x;
+ break;
+ default:
+ break;
+ }
+ }
adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST;
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
@@ -287,43 +314,34 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
if (first_boot == 0x55555555) {
/* This is the first boot after power up */
- adapter->pci_write_normalize(adapter,
- NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
+ NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
if (!NX_IS_REVISION_P2(adapter->ahw.revision_id))
return 0;
/* PCI bus master workaround */
- adapter->hw_read_wx(adapter,
- NETXEN_PCIE_REG(0x4), &first_boot, 4);
+ first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4));
if (!(first_boot & 0x4)) {
first_boot |= 0x4;
- adapter->hw_write_wx(adapter,
- NETXEN_PCIE_REG(0x4), &first_boot, 4);
- adapter->hw_read_wx(adapter,
- NETXEN_PCIE_REG(0x4), &first_boot, 4);
+ NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot);
+ first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4));
}
/* This is the first boot after power up */
- adapter->hw_read_wx(adapter,
- NETXEN_ROMUSB_GLB_SW_RESET, &first_boot, 4);
+ first_boot = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET);
if (first_boot != 0x80000f) {
/* clear the register for future unloads/loads */
- adapter->pci_write_normalize(adapter,
- NETXEN_CAM_RAM(0x1fc), 0);
+ NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), 0);
return -EIO;
}
/* Start P2 boot loader */
- val = adapter->pci_read_normalize(adapter,
- NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
- adapter->pci_write_normalize(adapter,
- NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1);
+ val = NXRD32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1);
timeout = 0;
do {
msleep(1);
- val = adapter->pci_read_normalize(adapter,
- NETXEN_CAM_RAM(0x1fc));
+ val = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
if (++timeout > 5000)
return -EIO;
@@ -342,24 +360,19 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter)
(val == NETXEN_BRDTYPE_P3_XG_LOM)) {
if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
data = NETXEN_PORT_MODE_802_3_AP;
- adapter->hw_write_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &data, 4);
+ NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
} else if (port_mode == NETXEN_PORT_MODE_XG) {
data = NETXEN_PORT_MODE_XG;
- adapter->hw_write_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &data, 4);
+ NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
} else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) {
data = NETXEN_PORT_MODE_AUTO_NEG_1G;
- adapter->hw_write_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &data, 4);
+ NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
} else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) {
data = NETXEN_PORT_MODE_AUTO_NEG_XG;
- adapter->hw_write_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &data, 4);
+ NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
} else {
data = NETXEN_PORT_MODE_AUTO_NEG;
- adapter->hw_write_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &data, 4);
+ NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
}
if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) &&
@@ -368,8 +381,7 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter)
(wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_XG)) {
wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG;
}
- adapter->hw_write_wx(adapter, NETXEN_WOL_PORT_MODE,
- &wol_port_mode, 4);
+ NXWR32(adapter, NETXEN_WOL_PORT_MODE, wol_port_mode);
}
}
@@ -389,11 +401,11 @@ static void netxen_set_msix_bit(struct pci_dev *pdev, int enable)
}
}
-static void netxen_init_msix_entries(struct netxen_adapter *adapter)
+static void netxen_init_msix_entries(struct netxen_adapter *adapter, int count)
{
int i;
- for (i = 0; i < MSIX_ENTRIES_PER_ADAPTER; i++)
+ for (i = 0; i < count; i++)
adapter->msix_entries[i].entry = i;
}
@@ -424,20 +436,38 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
if (!is_valid_ether_addr(netdev->perm_addr))
dev_warn(&pdev->dev, "Bad MAC address %pM.\n", netdev->dev_addr);
- else
- adapter->macaddr_set(adapter, netdev->dev_addr);
return 0;
}
+int netxen_nic_set_mac(struct net_device *netdev, void *p)
+{
+ struct netxen_adapter *adapter = netdev_priv(netdev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EINVAL;
+
+ if (netif_running(netdev)) {
+ netif_device_detach(netdev);
+ netxen_napi_disable(adapter);
+ }
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+ adapter->macaddr_set(adapter, addr->sa_data);
+
+ if (netif_running(netdev)) {
+ netif_device_attach(netdev);
+ netxen_napi_enable(adapter);
+ }
+ return 0;
+}
+
static void netxen_set_multicast_list(struct net_device *dev)
{
struct netxen_adapter *adapter = netdev_priv(dev);
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- netxen_p3_nic_set_multi(dev);
- else
- netxen_p2_nic_set_multi(dev);
+ adapter->set_multi(dev);
}
static const struct net_device_ops netxen_netdev_ops = {
@@ -460,10 +490,17 @@ netxen_setup_intr(struct netxen_adapter *adapter)
{
struct netxen_legacy_intr_set *legacy_intrp;
struct pci_dev *pdev = adapter->pdev;
+ int err, num_msix;
+
+ if (adapter->rss_supported) {
+ num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ?
+ MSIX_ENTRIES_PER_ADAPTER : 2;
+ } else
+ num_msix = 1;
+
+ adapter->max_sds_rings = 1;
adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
- adapter->intr_scheme = -1;
- adapter->msi_mode = -1;
if (adapter->ahw.revision_id >= NX_P3_B0)
legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
@@ -478,24 +515,35 @@ netxen_setup_intr(struct netxen_adapter *adapter)
if (adapter->msix_supported) {
- netxen_init_msix_entries(adapter);
- if (pci_enable_msix(pdev, adapter->msix_entries,
- MSIX_ENTRIES_PER_ADAPTER))
- goto request_msi;
+ netxen_init_msix_entries(adapter, num_msix);
+ err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
+ if (err == 0) {
+ adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
+ netxen_set_msix_bit(pdev, 1);
- adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
- netxen_set_msix_bit(pdev, 1);
- dev_info(&pdev->dev, "using msi-x interrupts\n");
+ if (adapter->rss_supported)
+ adapter->max_sds_rings = num_msix;
- } else {
-request_msi:
- if (use_msi && !pci_enable_msi(pdev)) {
- adapter->flags |= NETXEN_NIC_MSI_ENABLED;
- dev_info(&pdev->dev, "using msi interrupts\n");
- } else
- dev_info(&pdev->dev, "using legacy interrupts\n");
- adapter->msix_entries[0].vector = pdev->irq;
+ dev_info(&pdev->dev, "using msi-x interrupts\n");
+ return;
+ }
+
+ if (err > 0)
+ pci_disable_msix(pdev);
+
+ /* fall through for msi */
+ }
+
+ if (use_msi && !pci_enable_msi(pdev)) {
+ adapter->flags |= NETXEN_NIC_MSI_ENABLED;
+ adapter->msi_tgt_status =
+ msi_tgt_status[adapter->ahw.pci_func];
+ dev_info(&pdev->dev, "using msi interrupts\n");
+ return;
}
+
+ dev_info(&pdev->dev, "using legacy interrupts\n");
+ adapter->msix_entries[0].vector = pdev->irq;
}
static void
@@ -552,8 +600,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
adapter->hw_read_wx = netxen_nic_hw_read_wx_128M;
adapter->pci_read_immediate = netxen_nic_pci_read_immediate_128M;
adapter->pci_write_immediate = netxen_nic_pci_write_immediate_128M;
- adapter->pci_read_normalize = netxen_nic_pci_read_normalize_128M;
- adapter->pci_write_normalize = netxen_nic_pci_write_normalize_128M;
adapter->pci_set_window = netxen_nic_pci_set_window_128M;
adapter->pci_mem_read = netxen_nic_pci_mem_read_128M;
adapter->pci_mem_write = netxen_nic_pci_mem_write_128M;
@@ -575,9 +621,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
adapter->pci_read_immediate = netxen_nic_pci_read_immediate_2M;
adapter->pci_write_immediate =
netxen_nic_pci_write_immediate_2M;
- adapter->pci_read_normalize = netxen_nic_pci_read_normalize_2M;
- adapter->pci_write_normalize =
- netxen_nic_pci_write_normalize_2M;
adapter->pci_set_window = netxen_nic_pci_set_window_2M;
adapter->pci_mem_read = netxen_nic_pci_mem_read_2M;
adapter->pci_mem_write = netxen_nic_pci_mem_write_2M;
@@ -643,25 +686,22 @@ err_out:
}
static int
-netxen_start_firmware(struct netxen_adapter *adapter)
+netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
{
int val, err, first_boot;
struct pci_dev *pdev = adapter->pdev;
int first_driver = 0;
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- if (adapter->ahw.pci_func == 0)
- first_driver = 1;
- } else {
- if (adapter->portnum == 0)
- first_driver = 1;
- }
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ first_driver = (adapter->portnum == 0);
+ else
+ first_driver = (adapter->ahw.pci_func == 0);
if (!first_driver)
return 0;
- first_boot = adapter->pci_read_normalize(adapter,
- NETXEN_CAM_RAM(0x1fc));
+ first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
err = netxen_check_hw_init(adapter, first_boot);
if (err) {
@@ -669,14 +709,16 @@ netxen_start_firmware(struct netxen_adapter *adapter)
return err;
}
+ if (request_fw)
+ netxen_request_firmware(adapter);
+
if (first_boot != 0x55555555) {
- adapter->pci_write_normalize(adapter,
- CRB_CMDPEG_STATE, 0);
+ NXWR32(adapter, CRB_CMDPEG_STATE, 0);
netxen_pinit_from_rom(adapter, 0);
msleep(1);
}
- netxen_nic_reg_write(adapter, CRB_DMA_SHIFT, 0x55555555);
+ NXWR32(adapter, CRB_DMA_SHIFT, 0x55555555);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_set_port_mode(adapter);
@@ -688,8 +730,7 @@ netxen_start_firmware(struct netxen_adapter *adapter)
val = 0x7654;
if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
val |= 0x0f000000;
- netxen_crb_writelit_adapter(adapter,
- NETXEN_MAC_ADDR_CNTL_REG, val);
+ NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
}
@@ -703,7 +744,7 @@ netxen_start_firmware(struct netxen_adapter *adapter)
val = (_NETXEN_NIC_LINUX_MAJOR << 16)
| ((_NETXEN_NIC_LINUX_MINOR << 8))
| (_NETXEN_NIC_LINUX_SUBVERSION);
- adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, val);
+ NXWR32(adapter, CRB_DRIVER_VERSION, val);
/* Handshake with the card before we register the devices. */
err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
@@ -726,15 +767,6 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
struct net_device *netdev = adapter->netdev;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
- if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
- (adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
- printk(KERN_ERR "%s: Firmware interrupt scheme is "
- "incompatible with driver\n",
- netdev->name);
- adapter->driver_mismatch = 1;
- return -EINVAL;
- }
-
if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
handler = netxen_msix_intr;
else if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
@@ -747,7 +779,7 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
- sprintf(sds_ring->name, "%16s[%d]", netdev->name, ring);
+ sprintf(sds_ring->name, "%s[%d]", netdev->name, ring);
err = request_irq(sds_ring->irq, handler,
flags, sds_ring->name, sds_ring);
if (err)
@@ -782,22 +814,26 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
netxen_nic_driver_name, adapter->portnum);
return err;
}
- adapter->macaddr_set(adapter, netdev->dev_addr);
-
- netxen_nic_set_link_parameters(adapter);
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ adapter->macaddr_set(adapter, netdev->dev_addr);
- netxen_set_multicast_list(netdev);
- if (adapter->set_mtu)
- adapter->set_mtu(adapter, netdev->mtu);
+ adapter->set_multi(netdev);
+ adapter->set_mtu(adapter, netdev->mtu);
adapter->ahw.linkup = 0;
- mod_timer(&adapter->watchdog_timer, jiffies);
netxen_napi_enable(adapter);
if (adapter->max_sds_rings > 1)
netxen_config_rss(adapter, 1);
+ if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION)
+ netxen_linkevent_request(adapter, 1);
+ else
+ netxen_nic_set_link_parameters(adapter);
+
+ mod_timer(&adapter->watchdog_timer, jiffies);
+
return 0;
}
@@ -806,11 +842,15 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
{
netif_carrier_off(netdev);
netif_stop_queue(netdev);
- netxen_napi_disable(adapter);
if (adapter->stop_port)
adapter->stop_port(adapter);
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ netxen_p3_free_mac_list(adapter);
+
+ netxen_napi_disable(adapter);
+
netxen_release_tx_buffers(adapter);
FLUSH_SCHEDULED_WORK();
@@ -825,6 +865,7 @@ netxen_nic_attach(struct netxen_adapter *adapter)
struct pci_dev *pdev = adapter->pdev;
int err, ring;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_tx_ring *tx_ring;
err = netxen_init_firmware(adapter);
if (err != 0) {
@@ -854,13 +895,12 @@ netxen_nic_attach(struct netxen_adapter *adapter)
}
if (adapter->fw_major < 4) {
- adapter->crb_addr_cmd_producer =
- crb_cmd_producer[adapter->portnum];
- adapter->crb_addr_cmd_consumer =
- crb_cmd_consumer[adapter->portnum];
+ tx_ring = adapter->tx_ring;
+ tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum];
+ tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum];
- netxen_nic_update_cmd_producer(adapter, 0);
- netxen_nic_update_cmd_consumer(adapter, 0);
+ netxen_nic_update_cmd_producer(adapter, tx_ring, 0);
+ netxen_nic_update_cmd_consumer(adapter, tx_ring, 0);
}
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
@@ -889,10 +929,9 @@ err_out_free_sw:
static void
netxen_nic_detach(struct netxen_adapter *adapter)
{
- netxen_nic_free_irq(adapter);
-
netxen_release_rx_buffers(adapter);
netxen_free_hw_resources(adapter);
+ netxen_nic_free_irq(adapter);
netxen_free_sw_resources(adapter);
adapter->is_up = 0;
@@ -957,6 +996,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rwlock_init(&adapter->adapter_lock);
spin_lock_init(&adapter->tx_clean_lock);
+ INIT_LIST_HEAD(&adapter->mac_list);
err = netxen_setup_pci_map(adapter);
if (err)
@@ -979,6 +1019,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+ netdev->features |= (NETIF_F_GRO);
netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
if (NX_IS_REVISION_P3(revision_id)) {
@@ -1011,7 +1052,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- err = netxen_start_firmware(adapter);
+ err = netxen_start_firmware(adapter, 1);
if (err)
goto err_out_iounmap;
@@ -1024,8 +1065,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
adapter->physical_port = adapter->portnum;
if (adapter->fw_major < 4) {
- i = adapter->pci_read_normalize(adapter,
- CRB_V2P(adapter->portnum));
+ i = NXRD32(adapter, CRB_V2P(adapter->portnum));
if (i != 0x55555555)
adapter->physical_port = i;
}
@@ -1036,10 +1076,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->irq = adapter->msix_entries[0].vector;
- netxen_napi_add(adapter, netdev);
-
- err = netxen_receive_peg_ready(adapter);
- if (err)
+ if (netxen_napi_add(adapter, netdev))
goto err_out_disable_msi;
init_timer(&adapter->watchdog_timer);
@@ -1113,18 +1150,18 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
netxen_nic_detach(adapter);
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- netxen_p3_free_mac_list(adapter);
}
if (adapter->portnum == 0)
netxen_free_adapter_offload(adapter);
netxen_teardown_intr(adapter);
+ netxen_free_sds_rings(&adapter->recv_ctx);
netxen_cleanup_pci_map(adapter);
+ netxen_release_firmware(adapter);
+
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
@@ -1176,7 +1213,7 @@ netxen_nic_resume(struct pci_dev *pdev)
adapter->curr_window = 255;
- err = netxen_start_firmware(adapter);
+ err = netxen_start_firmware(adapter, 0);
if (err) {
dev_err(&pdev->dev, "failed to start firmware\n");
return err;
@@ -1315,7 +1352,7 @@ static int
netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
- struct netxen_hardware_context *hw = &adapter->ahw;
+ struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
unsigned int first_seg_len = skb->len - skb->data_len;
struct netxen_cmd_buffer *pbuf;
struct netxen_skb_frag *buffrag;
@@ -1326,28 +1363,26 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
u32 producer, consumer;
int frag_count, no_of_desc;
- u32 num_txd = adapter->num_txd;
+ u32 num_txd = tx_ring->num_desc;
bool is_tso = false;
frag_count = skb_shinfo(skb)->nr_frags + 1;
- /* There 4 fragments per descriptor */
+ /* 4 fragments per cmd des */
no_of_desc = (frag_count + 3) >> 2;
- producer = adapter->cmd_producer;
+ producer = tx_ring->producer;
smp_mb();
- consumer = adapter->last_cmd_consumer;
- if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) {
+ consumer = tx_ring->sw_consumer;
+ if ((no_of_desc+2) >= find_diff_among(producer, consumer, num_txd)) {
netif_stop_queue(netdev);
smp_mb();
return NETDEV_TX_BUSY;
}
- /* Copy the descriptors into the hardware */
- hwdesc = &hw->cmd_desc_head[producer];
+ hwdesc = &tx_ring->desc_head[producer];
netxen_clear_cmddesc((u64 *)hwdesc);
- /* Take skb->data itself */
- pbuf = &adapter->cmd_buf_arr[producer];
+ pbuf = &tx_ring->cmd_buf_arr[producer];
is_tso = netxen_tso_check(netdev, hwdesc, skb);
@@ -1376,9 +1411,9 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if ((i & 0x3) == 0) {
k = 0;
producer = get_next_index(producer, num_txd);
- hwdesc = &hw->cmd_desc_head[producer];
+ hwdesc = &tx_ring->desc_head[producer];
netxen_clear_cmddesc((u64 *)hwdesc);
- pbuf = &adapter->cmd_buf_arr[producer];
+ pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL;
}
frag = &skb_shinfo(skb)->frags[i - 1];
@@ -1430,8 +1465,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
more_hdr = 0;
}
/* copy the MAC/IP/TCP headers to the cmd descriptor list */
- hwdesc = &hw->cmd_desc_head[producer];
- pbuf = &adapter->cmd_buf_arr[producer];
+ hwdesc = &tx_ring->desc_head[producer];
+ pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL;
/* copy the first 64 bytes */
@@ -1440,8 +1475,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
producer = get_next_index(producer, num_txd);
if (more_hdr) {
- hwdesc = &hw->cmd_desc_head[producer];
- pbuf = &adapter->cmd_buf_arr[producer];
+ hwdesc = &tx_ring->desc_head[producer];
+ pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL;
/* copy the next 64 bytes - should be enough except
* for pathological case
@@ -1454,10 +1489,10 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
}
- adapter->cmd_producer = producer;
+ tx_ring->producer = producer;
adapter->stats.txbytes += skb->len;
- netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
+ netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
adapter->stats.xmitcalled++;
netdev->trans_start = jiffies;
@@ -1476,7 +1511,7 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
uint32_t temp, temp_state, temp_val;
int rv = 0;
- temp = adapter->pci_read_normalize(adapter, CRB_TEMP_STATE);
+ temp = NXRD32(adapter, CRB_TEMP_STATE);
temp_state = nx_get_temp_state(temp);
temp_val = nx_get_temp_val(temp);
@@ -1510,26 +1545,9 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
return rv;
}
-static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
+void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
{
struct net_device *netdev = adapter->netdev;
- u32 val, port, linkup;
-
- port = adapter->physical_port;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- val = adapter->pci_read_normalize(adapter, CRB_XG_STATE_P3);
- val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
- linkup = (val == XG_LINK_UP_P3);
- } else {
- val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
- if (adapter->ahw.port_type == NETXEN_NIC_GBE)
- linkup = (val >> port) & 1;
- else {
- val = (val >> port*8) & 0xff;
- linkup = (val == XG_LINK_UP);
- }
- }
if (adapter->ahw.linkup && !linkup) {
printk(KERN_INFO "%s: %s NIC Link is down\n",
@@ -1540,7 +1558,9 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
netif_stop_queue(netdev);
}
- netxen_nic_set_link_parameters(adapter);
+ if (!adapter->has_link_events)
+ netxen_nic_set_link_parameters(adapter);
+
} else if (!adapter->ahw.linkup && linkup) {
printk(KERN_INFO "%s: %s NIC Link is up\n",
netxen_nic_driver_name, netdev->name);
@@ -1550,8 +1570,32 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
netif_wake_queue(netdev);
}
- netxen_nic_set_link_parameters(adapter);
+ if (!adapter->has_link_events)
+ netxen_nic_set_link_parameters(adapter);
+ }
+}
+
+static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
+{
+ u32 val, port, linkup;
+
+ port = adapter->physical_port;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ val = NXRD32(adapter, CRB_XG_STATE_P3);
+ val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
+ linkup = (val == XG_LINK_UP_P3);
+ } else {
+ val = NXRD32(adapter, CRB_XG_STATE);
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE)
+ linkup = (val >> port) & 1;
+ else {
+ val = (val >> port*8) & 0xff;
+ linkup = (val == XG_LINK_UP);
+ }
}
+
+ netxen_advert_link_change(adapter, linkup);
}
static void netxen_watchdog(unsigned long v)
@@ -1569,7 +1613,8 @@ void netxen_watchdog_task(struct work_struct *work)
if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter))
return;
- netxen_nic_handle_phy_intr(adapter);
+ if (!adapter->has_link_events)
+ netxen_nic_handle_phy_intr(adapter);
if (netif_running(adapter->netdev))
mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
@@ -1598,10 +1643,6 @@ static void netxen_tx_timeout_task(struct work_struct *work)
netif_wake_queue(adapter->netdev);
}
-/*
- * netxen_nic_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- */
struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -1609,22 +1650,11 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
memset(stats, 0, sizeof(*stats));
- /* total packets received */
stats->rx_packets = adapter->stats.no_rcv;
- /* total packets transmitted */
- stats->tx_packets = adapter->stats.xmitedframes +
- adapter->stats.xmitfinished;
- /* total bytes received */
+ stats->tx_packets = adapter->stats.xmitfinished;
stats->rx_bytes = adapter->stats.rxbytes;
- /* total bytes transmitted */
stats->tx_bytes = adapter->stats.txbytes;
- /* bad packets received */
- stats->rx_errors = adapter->stats.rcvdbadskb;
- /* packet transmit problems */
- stats->tx_errors = adapter->stats.nocmddescriptor;
- /* no space in linux buffers */
stats->rx_dropped = adapter->stats.rxdropped;
- /* no space available in linux */
stats->tx_dropped = adapter->stats.txdropped;
return stats;
@@ -1651,15 +1681,14 @@ static irqreturn_t netxen_intr(int irq, void *data)
} else {
unsigned long our_int = 0;
- our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
+ our_int = NXRD32(adapter, CRB_INT_VECTOR);
/* not our interrupt */
if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
return IRQ_NONE;
/* claim interrupt */
- adapter->pci_write_normalize(adapter,
- CRB_INT_VECTOR, (our_int & 0xffffffff));
+ NXWR32(adapter, CRB_INT_VECTOR, (our_int & 0xffffffff));
}
/* clear interrupt */
@@ -1685,7 +1714,7 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
/* clear interrupt */
adapter->pci_write_immediate(adapter,
- msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
+ adapter->msi_tgt_status, 0xffffffff);
napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index d85203203d4d..5941c79be723 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -43,8 +43,7 @@ static int phy_lock(struct netxen_adapter *adapter)
int done = 0, timeout = 0;
while (!done) {
- done = netxen_nic_reg_read(adapter,
- NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
+ done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
if (done == 1)
break;
if (timeout >= phy_lock_timeout) {
@@ -59,8 +58,7 @@ static int phy_lock(struct netxen_adapter *adapter)
}
}
- netxen_crb_writelit_adapter(adapter,
- NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
+ NXWR32(adapter, NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
return 0;
}
@@ -105,9 +103,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
* so it cannot be in reset
*/
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &mac_cfg0, 4))
- return -EIO;
+ mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
if (netxen_gb_get_soft_reset(mac_cfg0)) {
__u32 temp;
temp = 0;
@@ -115,9 +111,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
netxen_gb_rx_reset_pb(temp);
netxen_gb_tx_reset_mac(temp);
netxen_gb_rx_reset_mac(temp);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &temp, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
return -EIO;
restore = 1;
}
@@ -125,43 +119,32 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
address = 0;
netxen_gb_mii_mgmt_reg_addr(address, reg);
netxen_gb_mii_mgmt_phy_addr(address, phy);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
- &address, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
return -EIO;
command = 0; /* turn off any prior activity */
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
- &command, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
return -EIO;
/* send read command */
netxen_gb_mii_mgmt_set_read_cycle(command);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
- &command, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
return -EIO;
status = 0;
do {
- if (adapter->hw_read_wx(adapter,
- NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
- &status, 4))
- return -EIO;
+ status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
timeout++;
} while ((netxen_get_gb_mii_mgmt_busy(status)
|| netxen_get_gb_mii_mgmt_notvalid(status))
&& (timeout++ < NETXEN_NIU_PHY_WAITMAX));
if (timeout < NETXEN_NIU_PHY_WAITMAX) {
- if (adapter->hw_read_wx(adapter,
- NETXEN_NIU_GB_MII_MGMT_STATUS(0),
- readval, 4))
- return -EIO;
+ *readval = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(0));
result = 0;
} else
result = -1;
if (restore)
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &mac_cfg0, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
return -EIO;
phy_unlock(adapter);
return result;
@@ -197,9 +180,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
* cannot be in reset
*/
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &mac_cfg0, 4))
- return -EIO;
+ mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
if (netxen_gb_get_soft_reset(mac_cfg0)) {
__u32 temp;
temp = 0;
@@ -208,35 +189,27 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
netxen_gb_tx_reset_mac(temp);
netxen_gb_rx_reset_mac(temp);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &temp, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
return -EIO;
restore = 1;
}
command = 0; /* turn off any prior activity */
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
- &command, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
return -EIO;
address = 0;
netxen_gb_mii_mgmt_reg_addr(address, reg);
netxen_gb_mii_mgmt_phy_addr(address, phy);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
- &address, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
return -EIO;
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0),
- &val, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), val))
return -EIO;
status = 0;
do {
- if (adapter->hw_read_wx(adapter,
- NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
- &status, 4))
- return -EIO;
+ status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
timeout++;
} while ((netxen_get_gb_mii_mgmt_busy(status))
&& (timeout++ < NETXEN_NIU_PHY_WAITMAX));
@@ -248,9 +221,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
/* restore the state of port 0 MAC in case we tampered with it */
if (restore)
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &mac_cfg0, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
return -EIO;
return result;
@@ -258,7 +229,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter)
{
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f);
+ NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x3f);
return 0;
}
@@ -281,7 +252,7 @@ int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter)
int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter)
{
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f);
+ NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x7f);
return 0;
}
@@ -315,36 +286,27 @@ static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
int port, long enable)
{
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x80000000);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x0000f0025);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
- 0xf1ff);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
- netxen_crb_writelit_adapter(adapter,
- (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
+ NXWR32(adapter, NETXEN_NIU_MODE, 0x2);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf1ff);
+ NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
+ NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
+ NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
+ NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
if (enable) {
/*
* Do NOT enable flow control until a suitable solution for
* shutting down pause frames is found.
*/
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x5);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5);
}
if (netxen_niu_gbe_enable_phy_interrupts(adapter))
- printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
+ printk(KERN_ERR "ERROR enabling PHY interrupts\n");
if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
+ printk(KERN_ERR "ERROR clearing PHY interrupts\n");
}
/*
@@ -353,36 +315,27 @@ static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
int port, long enable)
{
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x80000000);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x0000f0025);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
- 0xf2ff);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
- netxen_crb_writelit_adapter(adapter,
- (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
+ NXWR32(adapter, NETXEN_NIU_MODE, 0x2);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf2ff);
+ NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
+ NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
+ NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
+ NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
if (enable) {
/*
* Do NOT enable flow control until a suitable solution for
* shutting down pause frames is found.
*/
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x5);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5);
}
if (netxen_niu_gbe_enable_phy_interrupts(adapter))
- printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
+ printk(KERN_ERR "ERROR enabling PHY interrupts\n");
if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
+ printk(KERN_ERR "ERROR clearing PHY interrupts\n");
}
int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
@@ -416,25 +369,20 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
* plugged in.
*/
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0
- (port),
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
NETXEN_GB_MAC_SOFT_RESET);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0
- (port),
- NETXEN_GB_MAC_RESET_PROT_BLK
- | NETXEN_GB_MAC_ENABLE_TX_RX
- |
- NETXEN_GB_MAC_PAUSED_FRMS);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+ NETXEN_GB_MAC_RESET_PROT_BLK |
+ NETXEN_GB_MAC_ENABLE_TX_RX |
+ NETXEN_GB_MAC_PAUSED_FRMS);
if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR PFX
+ printk(KERN_ERR
"ERROR clearing PHY interrupts\n");
if (netxen_niu_gbe_enable_phy_interrupts(adapter))
- printk(KERN_ERR PFX
+ printk(KERN_ERR
"ERROR enabling PHY interrupts\n");
if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR PFX
+ printk(KERN_ERR
"ERROR clearing PHY interrupts\n");
result = -1;
}
@@ -447,88 +395,10 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
{
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
- }
-
- return 0;
-}
-
-/*
- * Return the current station MAC address.
- * Note that the passed-in value must already be in network byte order.
- */
-static int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t * addr)
-{
- u32 stationhigh;
- u32 stationlow;
- int phy = adapter->physical_port;
- u8 val[8];
-
- if (addr == NULL)
- return -EINVAL;
- if ((phy < 0) || (phy > 3))
- return -EINVAL;
-
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
- &stationhigh, 4))
- return -EIO;
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
- &stationlow, 4))
- return -EIO;
- ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
- ((__le32 *)val)[0] = cpu_to_le32(stationlow);
-
- memcpy(addr, val + 2, 6);
-
- return 0;
-}
-
-/*
- * Set the station MAC address.
- * Note that the passed-in value must already be in network byte order.
- */
-int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t addr)
-{
- u8 temp[4];
- u32 val;
- int phy = adapter->physical_port;
- unsigned char mac_addr[6];
- int i;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- return 0;
-
- for (i = 0; i < 10; i++) {
- temp[0] = temp[1] = 0;
- memcpy(temp + 2, addr, 2);
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4))
- return -EIO;
-
- memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32));
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4))
- return -2;
-
- netxen_niu_macaddr_get(adapter,
- (netxen_ethernet_macaddr_t *) mac_addr);
- if (memcmp(mac_addr, addr, 6) == 0)
- break;
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
}
- if (i == 10) {
- printk(KERN_ERR "%s: cannot set Mac addr for %s\n",
- netxen_nic_driver_name, adapter->netdev->name);
- printk(KERN_ERR "MAC address set: %pM.\n", addr);
- printk(KERN_ERR "MAC address get: %pM.\n", mac_addr);
- }
return 0;
}
@@ -545,8 +415,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
return -EINVAL;
mac_cfg0 = 0;
netxen_gb_soft_reset(mac_cfg0);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- &mac_cfg0, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), mac_cfg0))
return -EIO;
return 0;
}
@@ -564,8 +433,8 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
return -EINVAL;
mac_cfg = 0;
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4))
+ if (NXWR32(adapter,
+ NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
return -EIO;
return 0;
}
@@ -581,9 +450,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
return -EINVAL;
/* save previous contents */
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
- &reg, 4))
- return -EIO;
+ reg = NXRD32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR);
if (mode == NETXEN_NIU_PROMISC_MODE) {
switch (port) {
case 0:
@@ -619,67 +486,11 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
return -EIO;
}
}
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
- &reg, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, reg))
return -EIO;
return 0;
}
-/*
- * Set the MAC address for an XG port
- * Note that the passed-in value must already be in network byte order.
- */
-int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t addr)
-{
- int phy = adapter->physical_port;
- u8 temp[4];
- u32 val;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- return 0;
-
- if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
- return -EIO;
-
- temp[0] = temp[1] = 0;
- switch (phy) {
- case 0:
- memcpy(temp + 2, addr, 2);
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
- &val, 4))
- return -EIO;
-
- memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
- &val, 4))
- return -EIO;
- break;
-
- case 1:
- memcpy(temp + 2, addr, 2);
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1,
- &val, 4))
- return -EIO;
-
- memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI,
- &val, 4))
- return -EIO;
- break;
-
- default:
- printk(KERN_ERR "Unknown port %d\n", phy);
- break;
- }
-
- return 0;
-}
-
int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
u32 mode)
{
@@ -689,9 +500,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
if (port > NETXEN_NIU_MAX_XG_PORTS)
return -EINVAL;
- if (adapter->hw_read_wx(adapter,
- NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4))
- return -EIO;
+ reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
if (mode == NETXEN_NIU_PROMISC_MODE)
reg = (reg | 0x2000UL);
else
@@ -702,8 +511,40 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
else
reg = (reg & ~0x1000UL);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+
+ return 0;
+}
+
+int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
+{
+ u32 mac_hi, mac_lo;
+ u32 reg_hi, reg_lo;
+
+ u8 phy = adapter->physical_port;
+ u8 phy_count = (adapter->ahw.port_type == NETXEN_NIC_XGBE) ?
+ NETXEN_NIU_MAX_XG_PORTS : NETXEN_NIU_MAX_GBE_PORTS;
+
+ if (phy >= phy_count)
+ return -EINVAL;
+
+ mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
+ mac_hi = addr[2] | ((u32)addr[3] << 8) |
+ ((u32)addr[4] << 16) | ((u32)addr[5] << 24);
+
+ if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
+ reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
+ reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
+ } else {
+ reg_lo = NETXEN_NIU_GB_STATION_ADDR_1(phy);
+ reg_hi = NETXEN_NIU_GB_STATION_ADDR_0(phy);
+ }
+
+ /* write twice to flush */
+ if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
+ return -EIO;
+ if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
+ return -EIO;
return 0;
}
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
index 50183335e43a..b73a62ca74f8 100644
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ b/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -36,23 +36,25 @@
*/
#define NIC_CRB_BASE NETXEN_CAM_RAM(0x200)
#define NETXEN_NIC_REG(X) (NIC_CRB_BASE+(X))
+#define NIC_CRB_BASE_2 NETXEN_CAM_RAM(0x700)
+#define NETXEN_NIC_REG_2(X) (NIC_CRB_BASE_2+(X))
#define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00)
#define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04)
#define CRB_CMD_PRODUCER_OFFSET NETXEN_NIC_REG(0x08)
#define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c)
-#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10) /* C0 EPG BUG */
+#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10)
#define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14)
#define NX_CDRP_CRB_OFFSET NETXEN_NIC_REG(0x18)
#define NX_ARG1_CRB_OFFSET NETXEN_NIC_REG(0x1c)
#define NX_ARG2_CRB_OFFSET NETXEN_NIC_REG(0x20)
#define NX_ARG3_CRB_OFFSET NETXEN_NIC_REG(0x24)
#define NX_SIGN_CRB_OFFSET NETXEN_NIC_REG(0x28)
-#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20) /* 4 regs for perf */
+#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20)
#define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x24)
#define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x28)
#define CRB_RCV_DMA_LOOP NETXEN_NIC_REG(0x2c)
-#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x30) /* phantom init status */
+#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x30)
#define CRB_MMAP_ADDR_3 NETXEN_NIC_REG(0x34)
#define CRB_CMDPEG_CMDRING NETXEN_NIC_REG(0x38)
#define CRB_HOST_DUMMY_BUF_ADDR_HI NETXEN_NIC_REG(0x3c)
@@ -65,7 +67,7 @@
#define CRB_MMAP_SIZE_1 NETXEN_NIC_REG(0x58)
#define CRB_MMAP_SIZE_2 NETXEN_NIC_REG(0x5c)
#define CRB_MMAP_SIZE_3 NETXEN_NIC_REG(0x60)
-#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x64) /* interrupt coalescing */
+#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x64)
#define CRB_INT_COAL_MODE NETXEN_NIC_REG(0x68)
#define CRB_MAX_RCV_BUFS NETXEN_NIC_REG(0x6c)
#define CRB_TX_INT_THRESHOLD NETXEN_NIC_REG(0x70)
@@ -83,13 +85,13 @@
#define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xa0)
#define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xa4)
#define CRB_AGENT_TX_MSS NETXEN_NIC_REG(0xa8)
-#define CRB_TX_STATE NETXEN_NIC_REG(0xac) /* Debug -performance */
+#define CRB_TX_STATE NETXEN_NIC_REG(0xac)
#define CRB_TX_COUNT NETXEN_NIC_REG(0xb0)
#define CRB_RX_STATE NETXEN_NIC_REG(0xb4)
#define CRB_RX_PERF_DEBUG_1 NETXEN_NIC_REG(0xb8)
-#define CRB_RX_LRO_CONTROL NETXEN_NIC_REG(0xbc) /* LRO On/OFF */
+#define CRB_RX_LRO_CONTROL NETXEN_NIC_REG(0xbc)
#define CRB_RX_LRO_START_NUM NETXEN_NIC_REG(0xc0)
-#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4) /* Multiport Mode */
+#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4)
#define CRB_CMD_RING_SIZE NETXEN_NIC_REG(0xc8)
#define CRB_DMA_SHIFT NETXEN_NIC_REG(0xcc)
#define CRB_INT_VECTOR NETXEN_NIC_REG(0xd4)
@@ -109,8 +111,6 @@
#define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0)
#define CRB_CMD_PRODUCER_OFFSET_2 NETXEN_NIC_REG(0x1b8)
#define CRB_CMD_CONSUMER_OFFSET_2 NETXEN_NIC_REG(0x1bc)
-
-// 1c0 to 1cc used for signature reg
#define CRB_CMD_PRODUCER_OFFSET_3 NETXEN_NIC_REG(0x1d0)
#define CRB_CMD_CONSUMER_OFFSET_3 NETXEN_NIC_REG(0x1d4)
#define CRB_TEMP_STATE NETXEN_NIC_REG(0x1b4)
@@ -120,13 +120,13 @@
#define CRB_V2P_2 NETXEN_NIC_REG(0x298)
#define CRB_V2P_3 NETXEN_NIC_REG(0x29c)
#define CRB_V2P(port) (CRB_V2P_0+((port)*4))
-#define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0)
-/* sw int status/mask registers */
+#define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0)
#define CRB_SW_INT_MASK_0 NETXEN_NIC_REG(0x1d8)
#define CRB_SW_INT_MASK_1 NETXEN_NIC_REG(0x1e0)
#define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4)
#define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8)
+#define CRB_FW_CAPABILITIES_1 NETXEN_CAM_RAM(0x128)
#define CRB_MAC_BLOCK_START NETXEN_CAM_RAM(0x1c0)
/*
@@ -136,7 +136,7 @@
#define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8)
#define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc)
#define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270)
-#define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274)
+#define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274)
#define INTR_SCHEME_PERPORT 0x1
#define MSI_MODE_MULTIFUNC 0x1
@@ -162,7 +162,8 @@
struct netxen_recv_crb {
u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
- u32 crb_sts_consumer;
+ u32 crb_sts_consumer[NUM_STS_DESC_RINGS];
+ u32 sw_int_mask[NUM_STS_DESC_RINGS];
};
/*
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 5eeb5a87b738..c254a7f5b9f5 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -24,6 +24,7 @@
#include <linux/dmaengine.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
+#include <linux/of_mdio.h>
#include <linux/etherdevice.h>
#include <asm/dma-mapping.h>
#include <linux/in.h>
@@ -1086,34 +1087,17 @@ static int pasemi_mac_phy_init(struct net_device *dev)
struct pasemi_mac *mac = netdev_priv(dev);
struct device_node *dn, *phy_dn;
struct phy_device *phydev;
- unsigned int phy_id;
- const phandle *ph;
- const unsigned int *prop;
- struct resource r;
- int ret;
dn = pci_device_to_OF_node(mac->pdev);
- ph = of_get_property(dn, "phy-handle", NULL);
- if (!ph)
- return -ENODEV;
- phy_dn = of_find_node_by_phandle(*ph);
-
- prop = of_get_property(phy_dn, "reg", NULL);
- ret = of_address_to_resource(phy_dn->parent, 0, &r);
- if (ret)
- goto err;
-
- phy_id = *prop;
- snprintf(mac->phy_id, sizeof(mac->phy_id), "%x:%02x",
- (int)r.start, phy_id);
-
+ phy_dn = of_parse_phandle(dn, "phy-handle", 0);
of_node_put(phy_dn);
mac->link = 0;
mac->speed = 0;
mac->duplex = -1;
- phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII);
+ phydev = of_phy_connect(dev, phy_dn, &pasemi_adjust_link, 0,
+ PHY_INTERFACE_MODE_SGMII);
if (IS_ERR(phydev)) {
printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
@@ -1123,10 +1107,6 @@ static int pasemi_mac_phy_init(struct net_device *dev)
mac->phydev = phydev;
return 0;
-
-err:
- of_node_put(phy_dn);
- return -ENODEV;
}
@@ -1735,12 +1715,25 @@ out:
return ret;
}
+static const struct net_device_ops pasemi_netdev_ops = {
+ .ndo_open = pasemi_mac_open,
+ .ndo_stop = pasemi_mac_close,
+ .ndo_start_xmit = pasemi_mac_start_tx,
+ .ndo_set_multicast_list = pasemi_mac_set_rx_mode,
+ .ndo_set_mac_address = pasemi_mac_set_mac_addr,
+ .ndo_change_mtu = pasemi_mac_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = pasemi_mac_netpoll,
+#endif
+};
+
static int __devinit
pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *dev;
struct pasemi_mac *mac;
- int err;
+ int err, ret;
err = pci_enable_device(pdev);
if (err)
@@ -1798,12 +1791,13 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
memcpy(dev->dev_addr, mac->mac_addr, sizeof(mac->mac_addr));
- mac->dma_if = mac_to_intf(mac);
- if (mac->dma_if < 0) {
+ ret = mac_to_intf(mac);
+ if (ret < 0) {
dev_err(&mac->pdev->dev, "Can't map DMA interface\n");
err = -ENODEV;
goto out;
}
+ mac->dma_if = ret;
switch (pdev->device) {
case 0xa005:
@@ -1817,19 +1811,11 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out;
}
- dev->open = pasemi_mac_open;
- dev->stop = pasemi_mac_close;
- dev->hard_start_xmit = pasemi_mac_start_tx;
- dev->set_multicast_list = pasemi_mac_set_rx_mode;
- dev->set_mac_address = pasemi_mac_set_mac_addr;
+ dev->netdev_ops = &pasemi_netdev_ops;
dev->mtu = PE_DEF_MTU;
/* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = pasemi_mac_netpoll;
-#endif
- dev->change_mtu = pasemi_mac_change_mtu;
dev->ethtool_ops = &pasemi_mac_ethtool_ops;
if (err)
diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
index 1a115ec60b53..e2f4efa8ad46 100644
--- a/drivers/net/pasemi_mac.h
+++ b/drivers/net/pasemi_mac.h
@@ -100,7 +100,6 @@ struct pasemi_mac {
int duplex;
unsigned int msg_enable;
- char phy_id[BUS_ID_SIZE];
};
/* Software status descriptor (ring_info) */
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index c95fd72c3bb9..8c1f6988f398 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -728,6 +728,17 @@ err_out:
return rc;
}
+static const struct net_device_ops netdrv_netdev_ops = {
+ .ndo_open = netdrv_open,
+ .ndo_stop = netdrv_close,
+ .ndo_start_xmit = netdrv_start_xmit,
+ .ndo_set_multicast_list = netdrv_set_rx_mode,
+ .ndo_do_ioctl = netdrv_ioctl,
+ .ndo_tx_timeout = netdrv_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
static int __devinit netdrv_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -769,13 +780,7 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev,
((u16 *) (dev->dev_addr))[i] =
le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
- /* The Rtl8139-specific entries in the device structure. */
- dev->open = netdrv_open;
- dev->hard_start_xmit = netdrv_start_xmit;
- dev->stop = netdrv_close;
- dev->set_multicast_list = netdrv_set_rx_mode;
- dev->do_ioctl = netdrv_ioctl;
- dev->tx_timeout = netdrv_tx_timeout;
+ dev->netdev_ops = &netdrv_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
dev->irq = pdev->irq;
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 8f3872b8985d..f35c609ba020 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -1195,7 +1195,7 @@ static int el3_close(struct net_device *dev)
static struct pcmcia_device_id tc574_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0574),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "3CCFEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, tc574_ids);
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index cdf661a6092c..ec7cf5ac4f05 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -967,8 +967,8 @@ static struct pcmcia_device_id tc589_ids[] = {
PCMCIA_MFC_DEVICE_PROD_ID1(0, "Motorola MARQUIS", 0xf03e4e77),
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0589),
PCMCIA_DEVICE_PROD_ID12("Farallon", "ENet", 0x58d93fc4, 0x992c2202),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0035, "3CXEM556.cis"),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x003d, "3CXEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0035, "cis/3CXEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x003d, "cis/3CXEM556.cis"),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, tc589_ids);
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 80124fac65fa..1c35e1d637a0 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1227,7 +1227,6 @@ static void pcnet32_rx_entry(struct net_device *dev,
dev->stats.rx_dropped++;
return;
}
- skb->dev = dev;
if (!rx_in_place) {
skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pkt_len); /* Make room */
@@ -1406,7 +1405,7 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
/* Set interrupt enable. */
lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN);
- mmiowb();
+
spin_unlock_irqrestore(&lp->lock, flags);
}
return work_done;
@@ -2598,7 +2597,7 @@ pcnet32_interrupt(int irq, void *dev_id)
val = lp->a.read_csr(ioaddr, CSR3);
val |= 0x5f00;
lp->a.write_csr(ioaddr, CSR3, val);
- mmiowb();
+
__napi_schedule(&lp->napi);
break;
}
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index b754020cbe75..bd4e8d72dc08 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -113,7 +113,6 @@ int mdiobus_register(struct mii_bus *bus)
bus->reset(bus);
for (i = 0; i < PHY_MAX_ADDR; i++) {
- bus->phy_map[i] = NULL;
if ((bus->phy_mask & (1 << i)) == 0) {
struct phy_device *phydev;
@@ -150,6 +149,7 @@ void mdiobus_unregister(struct mii_bus *bus)
for (i = 0; i < PHY_MAX_ADDR; i++) {
if (bus->phy_map[i])
device_unregister(&bus->phy_map[i]->dev);
+ bus->phy_map[i] = NULL;
}
}
EXPORT_SYMBOL(mdiobus_unregister);
@@ -188,35 +188,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
if (IS_ERR(phydev) || phydev == NULL)
return phydev;
- /* There's a PHY at this address
- * We need to set:
- * 1) IRQ
- * 2) bus_id
- * 3) parent
- * 4) bus
- * 5) mii_bus
- * And, we need to register it */
-
- phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
-
- phydev->dev.parent = bus->parent;
- phydev->dev.bus = &mdio_bus_type;
- dev_set_name(&phydev->dev, PHY_ID_FMT, bus->id, addr);
-
- phydev->bus = bus;
-
- /* Run all of the fixups for this PHY */
- phy_scan_fixups(phydev);
-
- err = device_register(&phydev->dev);
+ err = phy_device_register(phydev);
if (err) {
- printk(KERN_ERR "phy %d failed to register\n", addr);
phy_device_free(phydev);
- phydev = NULL;
+ return NULL;
}
- bus->phy_map[addr] = phydev;
-
return phydev;
}
EXPORT_SYMBOL(mdiobus_scan);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 0a06e4fd37d9..a2ece89622d6 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -39,20 +39,21 @@ MODULE_DESCRIPTION("PHY library");
MODULE_AUTHOR("Andy Fleming");
MODULE_LICENSE("GPL");
-static struct phy_driver genphy_driver;
-extern int mdio_bus_init(void);
-extern void mdio_bus_exit(void);
-
void phy_device_free(struct phy_device *phydev)
{
kfree(phydev);
}
+EXPORT_SYMBOL(phy_device_free);
static void phy_device_release(struct device *dev)
{
phy_device_free(to_phy_device(dev));
}
+static struct phy_driver genphy_driver;
+extern int mdio_bus_init(void);
+extern void mdio_bus_exit(void);
+
static LIST_HEAD(phy_fixup_list);
static DEFINE_MUTEX(phy_fixup_lock);
@@ -166,6 +167,10 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
dev->addr = addr;
dev->phy_id = phy_id;
dev->bus = bus;
+ dev->dev.parent = bus->parent;
+ dev->dev.bus = &mdio_bus_type;
+ dev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
+ dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
dev->state = PHY_DOWN;
@@ -235,6 +240,38 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
return dev;
}
+EXPORT_SYMBOL(get_phy_device);
+
+/**
+ * phy_device_register - Register the phy device on the MDIO bus
+ * @phy_device: phy_device structure to be added to the MDIO bus
+ */
+int phy_device_register(struct phy_device *phydev)
+{
+ int err;
+
+ /* Don't register a phy if one is already registered at this
+ * address */
+ if (phydev->bus->phy_map[phydev->addr])
+ return -EINVAL;
+ phydev->bus->phy_map[phydev->addr] = phydev;
+
+ /* Run all of the fixups for this PHY */
+ phy_scan_fixups(phydev);
+
+ err = device_register(&phydev->dev);
+ if (err) {
+ pr_err("phy %d failed to register\n", phydev->addr);
+ goto out;
+ }
+
+ return 0;
+
+ out:
+ phydev->bus->phy_map[phydev->addr] = NULL;
+ return err;
+}
+EXPORT_SYMBOL(phy_device_register);
/**
* phy_prepare_link - prepares the PHY layer to monitor link status
@@ -255,6 +292,33 @@ void phy_prepare_link(struct phy_device *phydev,
}
/**
+ * phy_connect_direct - connect an ethernet device to a specific phy_device
+ * @dev: the network device to connect
+ * @phydev: the pointer to the phy device
+ * @handler: callback function for state change notifications
+ * @flags: PHY device's dev_flags
+ * @interface: PHY device's interface
+ */
+int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
+ void (*handler)(struct net_device *), u32 flags,
+ phy_interface_t interface)
+{
+ int rc;
+
+ rc = phy_attach_direct(dev, phydev, flags, interface);
+ if (rc)
+ return rc;
+
+ phy_prepare_link(phydev, handler);
+ phy_start_machine(phydev, NULL);
+ if (phydev->irq > 0)
+ phy_start_interrupts(phydev);
+
+ return 0;
+}
+EXPORT_SYMBOL(phy_connect_direct);
+
+/**
* phy_connect - connect an ethernet device to a PHY device
* @dev: the network device to connect
* @bus_id: the id string of the PHY device to connect
@@ -275,18 +339,21 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
phy_interface_t interface)
{
struct phy_device *phydev;
+ struct device *d;
+ int rc;
- phydev = phy_attach(dev, bus_id, flags, interface);
-
- if (IS_ERR(phydev))
- return phydev;
-
- phy_prepare_link(phydev, handler);
-
- phy_start_machine(phydev, NULL);
+ /* Search the list of PHY devices on the mdio bus for the
+ * PHY with the requested name */
+ d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id);
+ if (!d) {
+ pr_err("PHY %s not found\n", bus_id);
+ return ERR_PTR(-ENODEV);
+ }
+ phydev = to_phy_device(d);
- if (phydev->irq > 0)
- phy_start_interrupts(phydev);
+ rc = phy_connect_direct(dev, phydev, handler, flags, interface);
+ if (rc)
+ return ERR_PTR(rc);
return phydev;
}
@@ -310,9 +377,9 @@ void phy_disconnect(struct phy_device *phydev)
EXPORT_SYMBOL(phy_disconnect);
/**
- * phy_attach - attach a network device to a particular PHY device
+ * phy_attach_direct - attach a network device to a given PHY device pointer
* @dev: network device to attach
- * @bus_id: PHY device to attach
+ * @phydev: Pointer to phy_device to attach
* @flags: PHY device's dev_flags
* @interface: PHY device's interface
*
@@ -323,22 +390,10 @@ EXPORT_SYMBOL(phy_disconnect);
* the attaching device, and given a callback for link status
* change. The phy_device is returned to the attaching driver.
*/
-struct phy_device *phy_attach(struct net_device *dev,
- const char *bus_id, u32 flags, phy_interface_t interface)
+int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
+ u32 flags, phy_interface_t interface)
{
- struct bus_type *bus = &mdio_bus_type;
- struct phy_device *phydev;
- struct device *d;
-
- /* Search the list of PHY devices on the mdio bus for the
- * PHY with the requested name */
- d = bus_find_device_by_name(bus, NULL, bus_id);
- if (d) {
- phydev = to_phy_device(d);
- } else {
- printk(KERN_ERR "%s not found\n", bus_id);
- return ERR_PTR(-ENODEV);
- }
+ struct device *d = &phydev->dev;
/* Assume that if there is no driver, that it doesn't
* exist, and we should use the genphy driver. */
@@ -351,13 +406,12 @@ struct phy_device *phy_attach(struct net_device *dev,
err = device_bind_driver(d);
if (err)
- return ERR_PTR(err);
+ return err;
}
if (phydev->attached_dev) {
- printk(KERN_ERR "%s: %s already attached\n",
- dev->name, bus_id);
- return ERR_PTR(-EBUSY);
+ dev_err(&dev->dev, "PHY already attached\n");
+ return -EBUSY;
}
phydev->attached_dev = dev;
@@ -375,14 +429,49 @@ struct phy_device *phy_attach(struct net_device *dev,
err = phy_scan_fixups(phydev);
if (err < 0)
- return ERR_PTR(err);
+ return err;
err = phydev->drv->config_init(phydev);
if (err < 0)
- return ERR_PTR(err);
+ return err;
}
+ return 0;
+}
+EXPORT_SYMBOL(phy_attach_direct);
+
+/**
+ * phy_attach - attach a network device to a particular PHY device
+ * @dev: network device to attach
+ * @bus_id: Bus ID of PHY device to attach
+ * @flags: PHY device's dev_flags
+ * @interface: PHY device's interface
+ *
+ * Description: Same as phy_attach_direct() except that a PHY bus_id
+ * string is passed instead of a pointer to a struct phy_device.
+ */
+struct phy_device *phy_attach(struct net_device *dev,
+ const char *bus_id, u32 flags, phy_interface_t interface)
+{
+ struct bus_type *bus = &mdio_bus_type;
+ struct phy_device *phydev;
+ struct device *d;
+ int rc;
+
+ /* Search the list of PHY devices on the mdio bus for the
+ * PHY with the requested name */
+ d = bus_find_device_by_name(bus, NULL, bus_id);
+ if (!d) {
+ pr_err("PHY %s not found\n", bus_id);
+ return ERR_PTR(-ENODEV);
+ }
+ phydev = to_phy_device(d);
+
+ rc = phy_attach_direct(dev, phydev, flags, interface);
+ if (rc)
+ return ERR_PTR(rc);
+
return phydev;
}
EXPORT_SYMBOL(phy_attach);
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 5b07dd8e5c04..5981debcde5e 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -1238,8 +1238,7 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
struct pppol2tp_session *session;
struct sock *sk;
- if (tunnel == NULL)
- BUG();
+ BUG_ON(tunnel == NULL);
PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
"%s: closing all sessions...\n", tunnel->name);
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 6f97b47d74a6..1508b124e3d8 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -49,8 +49,8 @@
#include <asm/processor.h>
#define DRV_NAME "r6040"
-#define DRV_VERSION "0.22"
-#define DRV_RELDATE "25Mar2009"
+#define DRV_VERSION "0.23"
+#define DRV_RELDATE "05May2009"
/* PHY CHIP Address */
#define PHY1_ADDR 1 /* For MAC1 */
@@ -742,6 +742,14 @@ static int r6040_up(struct net_device *dev)
struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
int ret;
+ u16 val;
+
+ /* Check presence of a second PHY */
+ val = r6040_phy_read(ioaddr, lp->phy_addr, 2);
+ if (val == 0xFFFF) {
+ printk(KERN_ERR DRV_NAME " no second PHY attached\n");
+ return -EIO;
+ }
/* Initialise and alloc RX/TX buffers */
r6040_init_txbufs(dev);
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 0b6e8c896835..c812e16b7ab4 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -3791,16 +3791,13 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
return &dev->stats;
}
-#ifdef CONFIG_PM
-
-static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
+static void rtl8169_net_suspend(struct net_device *dev)
{
- struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
if (!netif_running(dev))
- goto out_pci_suspend;
+ return;
netif_device_detach(dev);
netif_stop_queue(dev);
@@ -3812,24 +3809,25 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
rtl8169_rx_missed(dev, ioaddr);
spin_unlock_irq(&tp->lock);
+}
+
+#ifdef CONFIG_PM
+
+static int rtl8169_suspend(struct device *device)
+{
+ struct pci_dev *pdev = to_pci_dev(device);
+ struct net_device *dev = pci_get_drvdata(pdev);
-out_pci_suspend:
- pci_save_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, state),
- (tp->features & RTL_FEATURE_WOL) ? 1 : 0);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ rtl8169_net_suspend(dev);
return 0;
}
-static int rtl8169_resume(struct pci_dev *pdev)
+static int rtl8169_resume(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D0, 0);
-
if (!netif_running(dev))
goto out;
@@ -3840,23 +3838,42 @@ out:
return 0;
}
+static struct dev_pm_ops rtl8169_pm_ops = {
+ .suspend = rtl8169_suspend,
+ .resume = rtl8169_resume,
+ .freeze = rtl8169_suspend,
+ .thaw = rtl8169_resume,
+ .poweroff = rtl8169_suspend,
+ .restore = rtl8169_resume,
+};
+
+#define RTL8169_PM_OPS (&rtl8169_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define RTL8169_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
+
static void rtl_shutdown(struct pci_dev *pdev)
{
- rtl8169_suspend(pdev, PMSG_SUSPEND);
-}
+ struct net_device *dev = pci_get_drvdata(pdev);
+
+ rtl8169_net_suspend(dev);
-#endif /* CONFIG_PM */
+ if (system_state == SYSTEM_POWER_OFF) {
+ pci_wake_from_d3(pdev, true);
+ pci_set_power_state(pdev, PCI_D3hot);
+ }
+}
static struct pci_driver rtl8169_pci_driver = {
.name = MODULENAME,
.id_table = rtl8169_pci_tbl,
.probe = rtl8169_init_one,
.remove = __devexit_p(rtl8169_remove_one),
-#ifdef CONFIG_PM
- .suspend = rtl8169_suspend,
- .resume = rtl8169_resume,
.shutdown = rtl_shutdown,
-#endif
+ .driver.pm = RTL8169_PM_OPS,
};
static int __init rtl8169_init_module(void)
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index ec59e29807a6..8702e7acdee6 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -428,6 +428,15 @@ static const struct ethtool_ops rionet_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
+static const struct net_device_ops rionet_netdev_ops = {
+ .ndo_open = rionet_open,
+ .ndo_stop = rionet_close,
+ .ndo_start_xmit = rionet_start_xmit,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int rionet_setup_netdev(struct rio_mport *mport)
{
int rc = 0;
@@ -466,10 +475,7 @@ static int rionet_setup_netdev(struct rio_mport *mport)
ndev->dev_addr[4] = device_id >> 8;
ndev->dev_addr[5] = device_id & 0xff;
- /* Fill in the driver function table */
- ndev->open = &rionet_open;
- ndev->hard_start_xmit = &rionet_start_xmit;
- ndev->stop = &rionet_close;
+ ndev->netdev_ops = &rionet_netdev_ops;
ndev->mtu = RIO_MAX_MSG_SIZE - 14;
ndev->features = NETIF_F_LLTX;
SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index f8274f8941ea..416669fd68c6 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -271,11 +271,6 @@ struct XENA_dev_config {
u64 mdio_control;
#define MDIO_MMD_INDX_ADDR(val) vBIT(val, 0, 16)
#define MDIO_MMD_DEV_ADDR(val) vBIT(val, 19, 5)
-#define MDIO_MMD_PMA_DEV_ADDR 0x1
-#define MDIO_MMD_PMD_DEV_ADDR 0x1
-#define MDIO_MMD_WIS_DEV_ADDR 0x2
-#define MDIO_MMD_PCS_DEV_ADDR 0x3
-#define MDIO_MMD_PHYXS_DEV_ADDR 0x4
#define MDIO_MMS_PRT_ADDR(val) vBIT(val, 27, 5)
#define MDIO_CTRL_START_TRANS(val) vBIT(val, 56, 4)
#define MDIO_OP(val) vBIT(val, 60, 2)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 1a4979f27fb5..80562ea77de3 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -63,6 +63,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/mdio.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -3328,9 +3329,9 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
struct stat_block *stat_info = sp->mac_control.stats_info;
/* Check the communication with the MDIO slave */
- addr = 0x0000;
+ addr = MDIO_CTRL1;
val64 = 0x0;
- val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+ val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
if((val64 == 0xFFFF) || (val64 == 0x0000))
{
DBG_PRINT(ERR_DBG, "ERR: MDIO slave access failed - "
@@ -3338,24 +3339,24 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
return;
}
- /* Check for the expecte value of 2040 at PMA address 0x0000 */
- if(val64 != 0x2040)
+ /* Check for the expected value of control reg 1 */
+ if(val64 != MDIO_CTRL1_SPEED10G)
{
DBG_PRINT(ERR_DBG, "Incorrect value at PMA address 0x0000 - ");
- DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x2040\n",
- (unsigned long long)val64);
+ DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x%x\n",
+ (unsigned long long)val64, MDIO_CTRL1_SPEED10G);
return;
}
/* Loading the DOM register to MDIO register */
addr = 0xA100;
- s2io_mdio_write(MDIO_MMD_PMA_DEV_ADDR, addr, val16, dev);
- val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+ s2io_mdio_write(MDIO_MMD_PMAPMD, addr, val16, dev);
+ val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
/* Reading the Alarm flags */
addr = 0xA070;
val64 = 0x0;
- val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+ val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
flag = CHECKBIT(val64, 0x7);
type = 1;
@@ -3387,7 +3388,7 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
/* Reading the Warning flags */
addr = 0xA074;
val64 = 0x0;
- val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+ val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
if(CHECKBIT(val64, 0x7))
stat_info->xpak_stat.warn_transceiver_temp_high++;
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index ce7551e17ba7..7a4b9fbddbaf 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2271,6 +2271,21 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
return 0;
}
+static const struct net_device_ops sbmac_netdev_ops = {
+ .ndo_open = sbmac_open,
+ .ndo_stop = sbmac_close,
+ .ndo_start_xmit = sbmac_start_tx,
+ .ndo_set_multicast_list = sbmac_set_rx_mode,
+ .ndo_tx_timeout = sbmac_tx_timeout,
+ .ndo_do_ioctl = sbmac_mii_ioctl,
+ .ndo_change_mtu = sb1250_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = sbmac_netpoll,
+#endif
+};
+
/**********************************************************************
* SBMAC_INIT(dev)
*
@@ -2285,7 +2300,7 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
static int sbmac_init(struct platform_device *pldev, long long base)
{
- struct net_device *dev = pldev->dev.driver_data;
+ struct net_device *dev = dev_get_drvdata(&pldev->dev);
int idx = pldev->id;
struct sbmac_softc *sc = netdev_priv(dev);
unsigned char *eaddr;
@@ -2327,21 +2342,11 @@ static int sbmac_init(struct platform_device *pldev, long long base)
spin_lock_init(&(sc->sbm_lock));
- dev->open = sbmac_open;
- dev->hard_start_xmit = sbmac_start_tx;
- dev->stop = sbmac_close;
- dev->set_multicast_list = sbmac_set_rx_mode;
- dev->do_ioctl = sbmac_mii_ioctl;
- dev->tx_timeout = sbmac_tx_timeout;
- dev->watchdog_timeo = TX_TIMEOUT;
+ dev->netdev_ops = &sbmac_netdev_ops;
+ dev->watchdog_timeo = TX_TIMEOUT;
netif_napi_add(dev, &sc->napi, sbmac_poll, 16);
- dev->change_mtu = sb1250_change_mtu;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = sbmac_netpoll;
-#endif
-
dev->irq = UNIT_INT(idx);
/* This is needed for PASS2 for Rx H/W checksum feature */
@@ -2726,7 +2731,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
goto out_unmap;
}
- pldev->dev.driver_data = dev;
+ dev_set_drvdata(&pldev->dev, dev);
SET_NETDEV_DEV(dev, &pldev->dev);
sc = netdev_priv(dev);
@@ -2751,7 +2756,7 @@ out_out:
static int __exit sbmac_remove(struct platform_device *pldev)
{
- struct net_device *dev = pldev->dev.driver_data;
+ struct net_device *dev = dev_get_drvdata(&pldev->dev);
struct sbmac_softc *sc = netdev_priv(dev);
unregister_netdev(dev);
diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig
index 12a82966b577..260aafaac235 100644
--- a/drivers/net/sfc/Kconfig
+++ b/drivers/net/sfc/Kconfig
@@ -1,7 +1,7 @@
config SFC
tristate "Solarflare Solarstorm SFC4000 support"
depends on PCI && INET
- select MII
+ select MDIO
select CRC32
select I2C
select I2C_ALGOBIT
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index 5182ac5a1034..4a4c74c891b7 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -172,7 +172,6 @@ static const u8 sfe4002_lm87_regs[] = {
static struct i2c_board_info sfe4002_hwmon_info = {
I2C_BOARD_INFO("lm87", 0x2e),
.platform_data = &sfe4002_lm87_channel,
- .irq = -1,
};
/****************************************************************************/
@@ -247,7 +246,6 @@ static const u8 sfn4112f_lm87_regs[] = {
static struct i2c_board_info sfn4112f_hwmon_info = {
I2C_BOARD_INFO("lm87", 0x2e),
.platform_data = &sfn4112f_lm87_channel,
- .irq = -1,
};
#define SFN4112F_ACT_LED 0
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7269a426051c..d3e240b736c7 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1300,10 +1300,16 @@ out_requeue:
static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
{
struct efx_nic *efx = netdev_priv(net_dev);
+ struct mii_ioctl_data *data = if_mii(ifr);
EFX_ASSERT_RESET_SERIALISED(efx);
- return generic_mii_ioctl(&efx->mii, if_mii(ifr), cmd, NULL);
+ /* Convert phy_id from older PRTAD/DEVAD format */
+ if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) &&
+ (data->phy_id & 0xfc00) == 0x0400)
+ data->phy_id ^= MDIO_PHY_ID_C45 | 0x0400;
+
+ return mdio_mii_ioctl(&efx->mdio, data, cmd);
}
/**************************************************************************
@@ -1945,7 +1951,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
mutex_init(&efx->mac_lock);
efx->mac_op = &efx_dummy_mac_operations;
efx->phy_op = &efx_dummy_phy_operations;
- efx->mii.dev = net_dev;
+ efx->mdio.dev = net_dev;
INIT_WORK(&efx->phy_work, efx_phy_work);
INIT_WORK(&efx->mac_work, efx_mac_work);
atomic_set(&efx->netif_stop_count, 1);
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 64309f4e8b19..997ea2a3d53f 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -10,6 +10,7 @@
#include <linux/netdevice.h>
#include <linux/ethtool.h>
+#include <linux/mdio.h>
#include <linux/rtnetlink.h>
#include "net_driver.h"
#include "workarounds.h"
@@ -345,8 +346,8 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
unsigned int n = 0, i;
enum efx_loopback_mode mode;
- efx_fill_test(n++, strings, data, &tests->mii,
- "core", 0, "mii", NULL);
+ efx_fill_test(n++, strings, data, &tests->mdio,
+ "core", 0, "mdio", NULL);
efx_fill_test(n++, strings, data, &tests->nvram,
"core", 0, "nvram", NULL);
efx_fill_test(n++, strings, data, &tests->interrupt,
@@ -529,14 +530,7 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
- if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
- mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1,
- __ffs(BMCR_ANRESTART), true);
- return 0;
- }
-
- return -EOPNOTSUPP;
+ return mdio45_nway_restart(&efx->mdio);
}
static u32 efx_ethtool_get_link(struct net_device *net_dev)
@@ -689,7 +683,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
return -EINVAL;
}
- if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) &&
+ if (!(efx->phy_op->mmds & MDIO_DEVS_AN) &&
(wanted_fc & EFX_FC_AUTO)) {
EFX_LOG(efx, "PHY does not support flow control "
"autonegotiation\n");
@@ -717,7 +711,8 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
mutex_lock(&efx->mac_lock);
efx->wanted_fc = wanted_fc;
- mdio_clause45_set_pause(efx);
+ if (efx->phy_op->mmds & MDIO_DEVS_AN)
+ mdio45_ethtool_spauseparam_an(&efx->mdio, pause);
__efx_reconfigure_port(efx);
mutex_unlock(&efx->mac_lock);
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 466a8abb0053..c049364aec46 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2063,26 +2063,6 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset)
**************************************************************************
*/
-/* Use the top bit of the MII PHY id to indicate the PHY type
- * (1G/10G), with the remaining bits as the actual PHY id.
- *
- * This allows us to avoid leaking information from the mii_if_info
- * structure into other data structures.
- */
-#define FALCON_PHY_ID_ID_WIDTH EFX_WIDTH(MD_PRT_DEV_ADR)
-#define FALCON_PHY_ID_ID_MASK ((1 << FALCON_PHY_ID_ID_WIDTH) - 1)
-#define FALCON_PHY_ID_WIDTH (FALCON_PHY_ID_ID_WIDTH + 1)
-#define FALCON_PHY_ID_MASK ((1 << FALCON_PHY_ID_WIDTH) - 1)
-#define FALCON_PHY_ID_10G (1 << (FALCON_PHY_ID_WIDTH - 1))
-
-
-/* Packing the clause 45 port and device fields into a single value */
-#define MD_PRT_ADR_COMP_LBN (MD_PRT_ADR_LBN - MD_DEV_ADR_LBN)
-#define MD_PRT_ADR_COMP_WIDTH MD_PRT_ADR_WIDTH
-#define MD_DEV_ADR_COMP_LBN 0
-#define MD_DEV_ADR_COMP_WIDTH MD_DEV_ADR_WIDTH
-
-
/* Wait for GMII access to complete */
static int falcon_gmii_wait(struct efx_nic *efx)
{
@@ -2108,49 +2088,29 @@ static int falcon_gmii_wait(struct efx_nic *efx)
return -ETIMEDOUT;
}
-/* Writes a GMII register of a PHY connected to Falcon using MDIO. */
-static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
- int addr, int value)
+/* Write an MDIO register of a PHY connected to Falcon. */
+static int falcon_mdio_write(struct net_device *net_dev,
+ int prtad, int devad, u16 addr, u16 value)
{
struct efx_nic *efx = netdev_priv(net_dev);
- unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK;
efx_oword_t reg;
+ int rc;
- /* The 'generic' prt/dev packing in mdio_10g.h is conveniently
- * chosen so that the only current user, Falcon, can take the
- * packed value and use them directly.
- * Fail to build if this assumption is broken.
- */
- BUILD_BUG_ON(FALCON_PHY_ID_10G != MDIO45_XPRT_ID_IS10G);
- BUILD_BUG_ON(FALCON_PHY_ID_ID_WIDTH != MDIO45_PRT_DEV_WIDTH);
- BUILD_BUG_ON(MD_PRT_ADR_COMP_LBN != MDIO45_PRT_ID_COMP_LBN);
- BUILD_BUG_ON(MD_DEV_ADR_COMP_LBN != MDIO45_DEV_ID_COMP_LBN);
-
- if (phy_id2 == PHY_ADDR_INVALID)
- return;
-
- /* See falcon_mdio_read for an explanation. */
- if (!(phy_id & FALCON_PHY_ID_10G)) {
- int mmd = ffs(efx->phy_op->mmds) - 1;
- EFX_TRACE(efx, "Fixing erroneous clause22 write\n");
- phy_id2 = mdio_clause45_pack(phy_id2, mmd)
- & FALCON_PHY_ID_ID_MASK;
- }
-
- EFX_REGDUMP(efx, "writing GMII %d register %02x with %04x\n", phy_id,
- addr, value);
+ EFX_REGDUMP(efx, "writing MDIO %d register %d.%d with 0x%04x\n",
+ prtad, devad, addr, value);
spin_lock_bh(&efx->phy_lock);
- /* Check MII not currently being accessed */
- if (falcon_gmii_wait(efx) != 0)
+ /* Check MDIO not currently being accessed */
+ rc = falcon_gmii_wait(efx);
+ if (rc)
goto out;
/* Write the address/ID register */
EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
- EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_id2);
+ EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
falcon_write(efx, &reg, MD_ID_REG_KER);
/* Write data */
@@ -2163,7 +2123,8 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
falcon_write(efx, &reg, MD_CS_REG_KER);
/* Wait for data to be written */
- if (falcon_gmii_wait(efx) != 0) {
+ rc = falcon_gmii_wait(efx);
+ if (rc) {
/* Abort the write operation */
EFX_POPULATE_OWORD_2(reg,
MD_WRC, 0,
@@ -2174,45 +2135,28 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
out:
spin_unlock_bh(&efx->phy_lock);
+ return rc;
}
-/* Reads a GMII register from a PHY connected to Falcon. If no value
- * could be read, -1 will be returned. */
-static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
+/* Read an MDIO register of a PHY connected to Falcon. */
+static int falcon_mdio_read(struct net_device *net_dev,
+ int prtad, int devad, u16 addr)
{
struct efx_nic *efx = netdev_priv(net_dev);
- unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK;
efx_oword_t reg;
- int value = -1;
-
- if (phy_addr == PHY_ADDR_INVALID)
- return -1;
-
- /* Our PHY code knows whether it needs to talk clause 22(1G) or 45(10G)
- * but the generic Linux code does not make any distinction or have
- * any state for this.
- * We spot the case where someone tried to talk 22 to a 45 PHY and
- * redirect the request to the lowest numbered MMD as a clause45
- * request. This is enough to allow simple queries like id and link
- * state to succeed. TODO: We may need to do more in future.
- */
- if (!(phy_id & FALCON_PHY_ID_10G)) {
- int mmd = ffs(efx->phy_op->mmds) - 1;
- EFX_TRACE(efx, "Fixing erroneous clause22 read\n");
- phy_addr = mdio_clause45_pack(phy_addr, mmd)
- & FALCON_PHY_ID_ID_MASK;
- }
+ int rc;
spin_lock_bh(&efx->phy_lock);
- /* Check MII not currently being accessed */
- if (falcon_gmii_wait(efx) != 0)
+ /* Check MDIO not currently being accessed */
+ rc = falcon_gmii_wait(efx);
+ if (rc)
goto out;
EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
- EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_addr);
+ EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
falcon_write(efx, &reg, MD_ID_REG_KER);
/* Request data to be read */
@@ -2220,12 +2164,12 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
falcon_write(efx, &reg, MD_CS_REG_KER);
/* Wait for data to become available */
- value = falcon_gmii_wait(efx);
- if (value == 0) {
+ rc = falcon_gmii_wait(efx);
+ if (rc == 0) {
falcon_read(efx, &reg, MD_RXD_REG_KER);
- value = EFX_OWORD_FIELD(reg, MD_RXD);
- EFX_REGDUMP(efx, "read from GMII %d register %02x, got %04x\n",
- phy_id, addr, value);
+ rc = EFX_OWORD_FIELD(reg, MD_RXD);
+ EFX_REGDUMP(efx, "read from MDIO %d register %d.%d, got %04x\n",
+ prtad, devad, addr, rc);
} else {
/* Abort the read operation */
EFX_POPULATE_OWORD_2(reg,
@@ -2233,22 +2177,13 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
MD_GC, 1);
falcon_write(efx, &reg, MD_CS_REG_KER);
- EFX_LOG(efx, "read from GMII 0x%x register %02x, got "
- "error %d\n", phy_id, addr, value);
+ EFX_LOG(efx, "read from MDIO %d register %d.%d, got error %d\n",
+ prtad, devad, addr, rc);
}
out:
spin_unlock_bh(&efx->phy_lock);
-
- return value;
-}
-
-static void falcon_init_mdio(struct mii_if_info *gmii)
-{
- gmii->mdio_read = falcon_mdio_read;
- gmii->mdio_write = falcon_mdio_write;
- gmii->phy_id_mask = FALCON_PHY_ID_MASK;
- gmii->reg_num_mask = ((1 << EFX_WIDTH(MD_PHY_ADR)) - 1);
+ return rc;
}
static int falcon_probe_phy(struct efx_nic *efx)
@@ -2342,9 +2277,11 @@ int falcon_probe_port(struct efx_nic *efx)
if (rc)
return rc;
- /* Set up GMII structure for PHY */
- efx->mii.supports_gmii = true;
- falcon_init_mdio(&efx->mii);
+ /* Set up MDIO structure for PHY */
+ efx->mdio.mmds = efx->phy_op->mmds;
+ efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+ efx->mdio.mdio_read = falcon_mdio_read;
+ efx->mdio.mdio_write = falcon_mdio_write;
/* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */
if (falcon_rev(efx) >= FALCON_REV_B0)
@@ -2761,7 +2698,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
if (rc == -EINVAL) {
EFX_ERR(efx, "NVRAM is invalid therefore using defaults\n");
efx->phy_type = PHY_TYPE_NONE;
- efx->mii.phy_id = PHY_ADDR_INVALID;
+ efx->mdio.prtad = MDIO_PRTAD_NONE;
board_rev = 0;
rc = 0;
} else if (rc) {
@@ -2771,7 +2708,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3;
efx->phy_type = v2->port0_phy_type;
- efx->mii.phy_id = v2->port0_phy_addr;
+ efx->mdio.prtad = v2->port0_phy_addr;
board_rev = le16_to_cpu(v2->board_revision);
if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) {
@@ -2793,7 +2730,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
/* Read the MAC addresses */
memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN);
- EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mii.phy_id);
+ EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad);
efx_set_board_info(efx, board_rev);
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index bda8d5bb72e4..375e2a5961ec 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -456,9 +456,6 @@
#define MD_PRT_ADR_WIDTH 5
#define MD_DEV_ADR_LBN 6
#define MD_DEV_ADR_WIDTH 5
-/* Used for writing both at once */
-#define MD_PRT_DEV_ADR_LBN 6
-#define MD_PRT_DEV_ADR_WIDTH 10
/* PHY management status & mask register (DWORD read only) */
#define MD_STAT_REG_KER 0xc50
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 5a03713685ac..2b3269c03263 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -133,7 +133,7 @@ bool falcon_xaui_link_ok(struct efx_nic *efx)
/* If the link is up, then check the phy side of the xaui link */
if (efx->link_up && link_ok)
if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS))
- link_ok = mdio_clause45_phyxgxs_lane_sync(efx);
+ link_ok = efx_mdio_phyxgxs_lane_sync(efx);
return link_ok;
}
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 9f5ec3eb3418..6c33459f9ea9 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -17,7 +17,7 @@
#include "boards.h"
#include "workarounds.h"
-unsigned mdio_id_oui(u32 id)
+unsigned efx_mdio_id_oui(u32 id)
{
unsigned oui = 0;
int i;
@@ -32,52 +32,45 @@ unsigned mdio_id_oui(u32 id)
return oui;
}
-int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
+int efx_mdio_reset_mmd(struct efx_nic *port, int mmd,
int spins, int spintime)
{
u32 ctrl;
- int phy_id = port->mii.phy_id;
/* Catch callers passing values in the wrong units (or just silly) */
EFX_BUG_ON_PARANOID(spins * spintime >= 5000);
- mdio_clause45_write(port, phy_id, mmd, MDIO_MMDREG_CTRL1,
- (1 << MDIO_MMDREG_CTRL1_RESET_LBN));
+ efx_mdio_write(port, mmd, MDIO_CTRL1, MDIO_CTRL1_RESET);
/* Wait for the reset bit to clear. */
do {
msleep(spintime);
- ctrl = mdio_clause45_read(port, phy_id, mmd, MDIO_MMDREG_CTRL1);
+ ctrl = efx_mdio_read(port, mmd, MDIO_CTRL1);
spins--;
- } while (spins && (ctrl & (1 << MDIO_MMDREG_CTRL1_RESET_LBN)));
+ } while (spins && (ctrl & MDIO_CTRL1_RESET));
return spins ? spins : -ETIMEDOUT;
}
-static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
- int fault_fatal)
+static int efx_mdio_check_mmd(struct efx_nic *efx, int mmd, int fault_fatal)
{
int status;
- int phy_id = efx->mii.phy_id;
if (LOOPBACK_INTERNAL(efx))
return 0;
if (mmd != MDIO_MMD_AN) {
/* Read MMD STATUS2 to check it is responding. */
- status = mdio_clause45_read(efx, phy_id, mmd,
- MDIO_MMDREG_STAT2);
- if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
- ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) !=
- MDIO_MMDREG_STAT2_PRESENT_VAL) {
+ status = efx_mdio_read(efx, mmd, MDIO_STAT2);
+ if ((status & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) {
EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd);
return -EIO;
}
}
/* Read MMD STATUS 1 to check for fault. */
- status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT1);
- if ((status & (1 << MDIO_MMDREG_STAT1_FAULT_LBN)) != 0) {
+ status = efx_mdio_read(efx, mmd, MDIO_STAT1);
+ if (status & MDIO_STAT1_FAULT) {
if (fault_fatal) {
EFX_ERR(efx, "PHY MMD %d reporting fatal"
" fault: status %x\n", mmd, status);
@@ -94,8 +87,7 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
#define MDIO45_RESET_TIME 1000 /* ms */
#define MDIO45_RESET_ITERS 100
-int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
- unsigned int mmd_mask)
+int efx_mdio_wait_reset_mmds(struct efx_nic *efx, unsigned int mmd_mask)
{
const int spintime = MDIO45_RESET_TIME / MDIO45_RESET_ITERS;
int tries = MDIO45_RESET_ITERS;
@@ -109,16 +101,13 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
in_reset = 0;
while (mask) {
if (mask & 1) {
- stat = mdio_clause45_read(efx,
- efx->mii.phy_id,
- mmd,
- MDIO_MMDREG_CTRL1);
+ stat = efx_mdio_read(efx, mmd, MDIO_CTRL1);
if (stat < 0) {
EFX_ERR(efx, "failed to read status of"
" MMD %d\n", mmd);
return -EIO;
}
- if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN))
+ if (stat & MDIO_CTRL1_RESET)
in_reset |= (1 << mmd);
}
mask = mask >> 1;
@@ -137,28 +126,26 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
return rc;
}
-int mdio_clause45_check_mmds(struct efx_nic *efx,
- unsigned int mmd_mask, unsigned int fatal_mask)
+int efx_mdio_check_mmds(struct efx_nic *efx,
+ unsigned int mmd_mask, unsigned int fatal_mask)
{
- int mmd = 0, probe_mmd, devs0, devs1;
+ int mmd = 0, probe_mmd, devs1, devs2;
u32 devices;
/* Historically we have probed the PHYXS to find out what devices are
* present,but that doesn't work so well if the PHYXS isn't expected
* to exist, if so just find the first item in the list supplied. */
- probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
+ probe_mmd = (mmd_mask & MDIO_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
__ffs(mmd_mask);
/* Check all the expected MMDs are present */
- devs0 = mdio_clause45_read(efx, efx->mii.phy_id,
- probe_mmd, MDIO_MMDREG_DEVS0);
- devs1 = mdio_clause45_read(efx, efx->mii.phy_id,
- probe_mmd, MDIO_MMDREG_DEVS1);
- if (devs0 < 0 || devs1 < 0) {
+ devs1 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS1);
+ devs2 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS2);
+ if (devs1 < 0 || devs2 < 0) {
EFX_ERR(efx, "failed to read devices present\n");
return -EIO;
}
- devices = devs0 | (devs1 << 16);
+ devices = devs1 | (devs2 << 16);
if ((devices & mmd_mask) != mmd_mask) {
EFX_ERR(efx, "required MMDs not present: got %x, "
"wanted %x\n", devices, mmd_mask);
@@ -170,7 +157,7 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
while (mmd_mask) {
if (mmd_mask & 1) {
int fault_fatal = fatal_mask & 1;
- if (mdio_clause45_check_mmd(efx, mmd, fault_fatal))
+ if (efx_mdio_check_mmd(efx, mmd, fault_fatal))
return -EIO;
}
mmd_mask = mmd_mask >> 1;
@@ -181,13 +168,8 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
return 0;
}
-bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
+bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
{
- int phy_id = efx->mii.phy_id;
- u32 reg;
- bool ok = true;
- int mmd = 0;
-
/* If the port is in loopback, then we should only consider a subset
* of mmd's */
if (LOOPBACK_INTERNAL(efx))
@@ -197,241 +179,75 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
else if (efx_phy_mode_disabled(efx->phy_mode))
return false;
else if (efx->loopback_mode == LOOPBACK_PHYXS)
- mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
- MDIO_MMDREG_DEVS_PCS |
- MDIO_MMDREG_DEVS_PMAPMD |
- MDIO_MMDREG_DEVS_AN);
+ mmd_mask &= ~(MDIO_DEVS_PHYXS |
+ MDIO_DEVS_PCS |
+ MDIO_DEVS_PMAPMD |
+ MDIO_DEVS_AN);
else if (efx->loopback_mode == LOOPBACK_PCS)
- mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
- MDIO_MMDREG_DEVS_PMAPMD |
- MDIO_MMDREG_DEVS_AN);
+ mmd_mask &= ~(MDIO_DEVS_PCS |
+ MDIO_DEVS_PMAPMD |
+ MDIO_DEVS_AN);
else if (efx->loopback_mode == LOOPBACK_PMAPMD)
- mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
- MDIO_MMDREG_DEVS_AN);
-
- if (!mmd_mask) {
- /* Use presence of XGMII faults in leui of link state */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
- MDIO_PHYXS_STATUS2);
- return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
- }
+ mmd_mask &= ~(MDIO_DEVS_PMAPMD |
+ MDIO_DEVS_AN);
- while (mmd_mask) {
- if (mmd_mask & 1) {
- /* Double reads because link state is latched, and a
- * read moves the current state into the register */
- reg = mdio_clause45_read(efx, phy_id,
- mmd, MDIO_MMDREG_STAT1);
- reg = mdio_clause45_read(efx, phy_id,
- mmd, MDIO_MMDREG_STAT1);
- ok = ok && (reg & (1 << MDIO_MMDREG_STAT1_LINK_LBN));
- }
- mmd_mask = (mmd_mask >> 1);
- mmd++;
- }
- return ok;
+ return mdio45_links_ok(&efx->mdio, mmd_mask);
}
-void mdio_clause45_transmit_disable(struct efx_nic *efx)
+void efx_mdio_transmit_disable(struct efx_nic *efx)
{
- mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_TXDIS, MDIO_MMDREG_TXDIS_GLOBAL_LBN,
- efx->phy_mode & PHY_MODE_TX_DISABLED);
+ efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD,
+ MDIO_PMA_TXDIS, MDIO_PMD_TXDIS_GLOBAL,
+ efx->phy_mode & PHY_MODE_TX_DISABLED);
}
-void mdio_clause45_phy_reconfigure(struct efx_nic *efx)
+void efx_mdio_phy_reconfigure(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
-
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1, MDIO_PMAPMD_CTRL1_LBACK_LBN,
- efx->loopback_mode == LOOPBACK_PMAPMD);
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PCS,
- MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
- efx->loopback_mode == LOOPBACK_PCS);
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
- MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
- efx->loopback_mode == LOOPBACK_NETWORK);
+ efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD,
+ MDIO_CTRL1, MDIO_PMA_CTRL1_LOOPBACK,
+ efx->loopback_mode == LOOPBACK_PMAPMD);
+ efx_mdio_set_flag(efx, MDIO_MMD_PCS,
+ MDIO_CTRL1, MDIO_PCS_CTRL1_LOOPBACK,
+ efx->loopback_mode == LOOPBACK_PCS);
+ efx_mdio_set_flag(efx, MDIO_MMD_PHYXS,
+ MDIO_CTRL1, MDIO_PHYXS_CTRL1_LOOPBACK,
+ efx->loopback_mode == LOOPBACK_NETWORK);
}
-static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx,
- int lpower, int mmd)
+static void efx_mdio_set_mmd_lpower(struct efx_nic *efx,
+ int lpower, int mmd)
{
- int phy = efx->mii.phy_id;
- int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1);
+ int stat = efx_mdio_read(efx, mmd, MDIO_STAT1);
EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n",
mmd, lpower);
- if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) {
- mdio_clause45_set_flag(efx, phy, mmd, MDIO_MMDREG_CTRL1,
- MDIO_MMDREG_CTRL1_LPOWER_LBN, lpower);
+ if (stat & MDIO_STAT1_LPOWERABLE) {
+ efx_mdio_set_flag(efx, mmd, MDIO_CTRL1,
+ MDIO_CTRL1_LPOWER, lpower);
}
}
-void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
- int low_power, unsigned int mmd_mask)
+void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
+ int low_power, unsigned int mmd_mask)
{
int mmd = 0;
- mmd_mask &= ~MDIO_MMDREG_DEVS_AN;
+ mmd_mask &= ~MDIO_DEVS_AN;
while (mmd_mask) {
if (mmd_mask & 1)
- mdio_clause45_set_mmd_lpower(efx, low_power, mmd);
+ efx_mdio_set_mmd_lpower(efx, low_power, mmd);
mmd_mask = (mmd_mask >> 1);
mmd++;
}
}
-static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
-{
- int phy_id = efx->mii.phy_id;
- u32 result = 0;
- int reg;
-
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, addr);
- if (reg & ADVERTISE_10HALF)
- result |= ADVERTISED_10baseT_Half;
- if (reg & ADVERTISE_10FULL)
- result |= ADVERTISED_10baseT_Full;
- if (reg & ADVERTISE_100HALF)
- result |= ADVERTISED_100baseT_Half;
- if (reg & ADVERTISE_100FULL)
- result |= ADVERTISED_100baseT_Full;
- return result;
-}
-
-/**
- * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
- * @efx: Efx NIC
- * @ecmd: Buffer for settings
- *
- * On return the 'port', 'speed', 'supported' and 'advertising' fields of
- * ecmd have been filled out.
- */
-void mdio_clause45_get_settings(struct efx_nic *efx,
- struct ethtool_cmd *ecmd)
-{
- mdio_clause45_get_settings_ext(efx, ecmd, 0, 0);
-}
-
-/**
- * mdio_clause45_get_settings_ext - Read (some of) the PHY settings over MDIO.
- * @efx: Efx NIC
- * @ecmd: Buffer for settings
- * @xnp: Advertised Extended Next Page state
- * @xnp_lpa: Link Partner's advertised XNP state
- *
- * On return the 'port', 'speed', 'supported' and 'advertising' fields of
- * ecmd have been filled out.
- */
-void mdio_clause45_get_settings_ext(struct efx_nic *efx,
- struct ethtool_cmd *ecmd,
- u32 npage_adv, u32 npage_lpa)
-{
- int phy_id = efx->mii.phy_id;
- int reg;
-
- ecmd->transceiver = XCVR_INTERNAL;
- ecmd->phy_address = phy_id;
-
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL2);
- switch (reg & MDIO_PMAPMD_CTRL2_TYPE_MASK) {
- case MDIO_PMAPMD_CTRL2_10G_BT:
- case MDIO_PMAPMD_CTRL2_1G_BT:
- case MDIO_PMAPMD_CTRL2_100_BT:
- case MDIO_PMAPMD_CTRL2_10_BT:
- ecmd->port = PORT_TP;
- ecmd->supported = SUPPORTED_TP;
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_SPEED);
- if (reg & (1 << MDIO_MMDREG_SPEED_10G_LBN))
- ecmd->supported |= SUPPORTED_10000baseT_Full;
- if (reg & (1 << MDIO_MMDREG_SPEED_1000M_LBN))
- ecmd->supported |= (SUPPORTED_1000baseT_Full |
- SUPPORTED_1000baseT_Half);
- if (reg & (1 << MDIO_MMDREG_SPEED_100M_LBN))
- ecmd->supported |= (SUPPORTED_100baseT_Full |
- SUPPORTED_100baseT_Half);
- if (reg & (1 << MDIO_MMDREG_SPEED_10M_LBN))
- ecmd->supported |= (SUPPORTED_10baseT_Full |
- SUPPORTED_10baseT_Half);
- ecmd->advertising = ADVERTISED_TP;
- break;
-
- /* We represent CX4 as fibre in the absence of anything better */
- case MDIO_PMAPMD_CTRL2_10G_CX4:
- /* All the other defined modes are flavours of optical */
- default:
- ecmd->port = PORT_FIBRE;
- ecmd->supported = SUPPORTED_FIBRE;
- ecmd->advertising = ADVERTISED_FIBRE;
- break;
- }
-
- if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
- ecmd->supported |= SUPPORTED_Autoneg;
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1);
- if (reg & BMCR_ANENABLE) {
- ecmd->autoneg = AUTONEG_ENABLE;
- ecmd->advertising |=
- ADVERTISED_Autoneg |
- mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
- npage_adv;
- } else
- ecmd->autoneg = AUTONEG_DISABLE;
- } else
- ecmd->autoneg = AUTONEG_DISABLE;
-
- if (ecmd->autoneg) {
- /* If AN is complete, report best common mode,
- * otherwise report best advertised mode. */
- u32 modes = 0;
- if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_STAT1) &
- (1 << MDIO_AN_STATUS_AN_DONE_LBN))
- modes = (ecmd->advertising &
- (mdio_clause45_get_an(efx, MDIO_AN_LPA) |
- npage_lpa));
- if (modes == 0)
- modes = ecmd->advertising;
-
- if (modes & ADVERTISED_10000baseT_Full) {
- ecmd->speed = SPEED_10000;
- ecmd->duplex = DUPLEX_FULL;
- } else if (modes & (ADVERTISED_1000baseT_Full |
- ADVERTISED_1000baseT_Half)) {
- ecmd->speed = SPEED_1000;
- ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
- } else if (modes & (ADVERTISED_100baseT_Full |
- ADVERTISED_100baseT_Half)) {
- ecmd->speed = SPEED_100;
- ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
- } else {
- ecmd->speed = SPEED_10;
- ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
- }
- } else {
- /* Report forced settings */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1);
- ecmd->speed = (((reg & BMCR_SPEED1000) ? 100 : 1) *
- ((reg & BMCR_SPEED100) ? 100 : 10));
- ecmd->duplex = (reg & BMCR_FULLDPLX ||
- ecmd->speed == SPEED_10000);
- }
-}
-
/**
- * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO.
+ * efx_mdio_set_settings - Set (some of) the PHY settings over MDIO.
* @efx: Efx NIC
* @ecmd: New settings
*/
-int mdio_clause45_set_settings(struct efx_nic *efx,
- struct ethtool_cmd *ecmd)
+int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy_id = efx->mii.phy_id;
struct ethtool_cmd prev;
u32 required;
int reg;
@@ -488,95 +304,48 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
else if (ecmd->advertising & (ADVERTISED_1000baseT_Half |
ADVERTISED_1000baseT_Full))
reg |= ADVERTISE_NPAGE;
- reg |= efx_fc_advertise(efx->wanted_fc);
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_ADVERTISE, reg);
+ reg |= mii_advertise_flowctrl(efx->wanted_fc);
+ efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
/* Set up the (extended) next page if necessary */
if (efx->phy_op->set_npage_adv)
efx->phy_op->set_npage_adv(efx, ecmd->advertising);
/* Enable and restart AN */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1);
- reg |= BMCR_ANENABLE;
+ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
+ reg |= MDIO_AN_CTRL1_ENABLE;
if (!(EFX_WORKAROUND_15195(efx) &&
LOOPBACK_MASK(efx) & efx->phy_op->loopbacks))
- reg |= BMCR_ANRESTART;
+ reg |= MDIO_AN_CTRL1_RESTART;
if (xnp)
- reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
+ reg |= MDIO_AN_CTRL1_XNP;
else
- reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1, reg);
+ reg &= ~MDIO_AN_CTRL1_XNP;
+ efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
} else {
/* Disable AN */
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1,
- __ffs(BMCR_ANENABLE), false);
+ efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_CTRL1,
+ MDIO_AN_CTRL1_ENABLE, false);
/* Set the basic control bits */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1);
- reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX |
- 0x003c);
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1);
+ reg &= ~(MDIO_CTRL1_SPEEDSEL | MDIO_CTRL1_FULLDPLX);
if (ecmd->speed == SPEED_100)
- reg |= BMCR_SPEED100;
+ reg |= MDIO_PMA_CTRL1_SPEED100;
if (ecmd->duplex)
- reg |= BMCR_FULLDPLX;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1, reg);
+ reg |= MDIO_CTRL1_FULLDPLX;
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, reg);
}
return 0;
}
-void mdio_clause45_set_pause(struct efx_nic *efx)
-{
- int phy_id = efx->mii.phy_id;
- int reg;
-
- if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
- /* Set pause capability advertising */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_ADVERTISE);
- reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
- reg |= efx_fc_advertise(efx->wanted_fc);
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_ADVERTISE, reg);
-
- /* Restart auto-negotiation */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1);
- if (reg & BMCR_ANENABLE) {
- reg |= BMCR_ANRESTART;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1, reg);
- }
- }
-}
-
-enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx)
+enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
int lpa;
- if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)))
+ if (!(efx->phy_op->mmds & MDIO_DEVS_AN))
return efx->wanted_fc;
- lpa = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_AN_LPA);
+ lpa = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_LPA);
return efx_fc_resolve(efx->wanted_fc, lpa);
}
-
-void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
- u16 addr, int bit, bool sense)
-{
- int old_val = mdio_clause45_read(efx, prt, dev, addr);
- int new_val;
-
- if (sense)
- new_val = old_val | (1 << bit);
- else
- new_val = old_val & ~(1 << bit);
- if (old_val != new_val)
- mdio_clause45_write(efx, prt, dev, addr, new_val);
-}
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 7014d2279c20..6b14421a7444 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -10,247 +10,53 @@
#ifndef EFX_MDIO_10G_H
#define EFX_MDIO_10G_H
+#include <linux/mdio.h>
+
/*
- * Definitions needed for doing 10G MDIO as specified in clause 45
- * MDIO, which do not appear in Linux yet. Also some helper functions.
+ * Helper functions for doing 10G MDIO as specified in IEEE 802.3 clause 45.
*/
#include "efx.h"
#include "boards.h"
-/* Numbering of the MDIO Manageable Devices (MMDs) */
-/* Physical Medium Attachment/ Physical Medium Dependent sublayer */
-#define MDIO_MMD_PMAPMD (1)
-/* WAN Interface Sublayer */
-#define MDIO_MMD_WIS (2)
-/* Physical Coding Sublayer */
-#define MDIO_MMD_PCS (3)
-/* PHY Extender Sublayer */
-#define MDIO_MMD_PHYXS (4)
-/* Extender Sublayer */
-#define MDIO_MMD_DTEXS (5)
-/* Transmission convergence */
-#define MDIO_MMD_TC (6)
-/* Auto negotiation */
-#define MDIO_MMD_AN (7)
-/* Clause 22 extension */
-#define MDIO_MMD_C22EXT 29
-
-/* Generic register locations */
-#define MDIO_MMDREG_CTRL1 (0)
-#define MDIO_MMDREG_STAT1 (1)
-#define MDIO_MMDREG_IDHI (2)
-#define MDIO_MMDREG_IDLOW (3)
-#define MDIO_MMDREG_SPEED (4)
-#define MDIO_MMDREG_DEVS0 (5)
-#define MDIO_MMDREG_DEVS1 (6)
-#define MDIO_MMDREG_CTRL2 (7)
-#define MDIO_MMDREG_STAT2 (8)
-#define MDIO_MMDREG_TXDIS (9)
-
-/* Bits in MMDREG_CTRL1 */
-/* Reset */
-#define MDIO_MMDREG_CTRL1_RESET_LBN (15)
-#define MDIO_MMDREG_CTRL1_RESET_WIDTH (1)
-/* Loopback */
-/* Loopback bit for WIS, PCS, PHYSX and DTEXS */
-#define MDIO_MMDREG_CTRL1_LBACK_LBN (14)
-#define MDIO_MMDREG_CTRL1_LBACK_WIDTH (1)
-/* Low power */
-#define MDIO_MMDREG_CTRL1_LPOWER_LBN (11)
-#define MDIO_MMDREG_CTRL1_LPOWER_WIDTH (1)
-
-/* Bits in MMDREG_STAT1 */
-#define MDIO_MMDREG_STAT1_FAULT_LBN (7)
-#define MDIO_MMDREG_STAT1_FAULT_WIDTH (1)
-/* Link state */
-#define MDIO_MMDREG_STAT1_LINK_LBN (2)
-#define MDIO_MMDREG_STAT1_LINK_WIDTH (1)
-/* Low power ability */
-#define MDIO_MMDREG_STAT1_LPABLE_LBN (1)
-#define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1)
-
-/* Bits in combined ID regs */
-static inline unsigned mdio_id_rev(u32 id) { return id & 0xf; }
-static inline unsigned mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
-extern unsigned mdio_id_oui(u32 id);
-
-/* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out
- * so the 'bit present' bit number of an MMD is the number of
- * that MMD */
-#define DEV_PRESENT_BIT(_b) (1 << _b)
-
-#define MDIO_MMDREG_DEVS_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS)
-#define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS)
-#define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)
-#define MDIO_MMDREG_DEVS_AN DEV_PRESENT_BIT(MDIO_MMD_AN)
-#define MDIO_MMDREG_DEVS_C22EXT DEV_PRESENT_BIT(MDIO_MMD_C22EXT)
-
-/* Bits in MMDREG_SPEED */
-#define MDIO_MMDREG_SPEED_10G_LBN 0
-#define MDIO_MMDREG_SPEED_10G_WIDTH 1
-#define MDIO_MMDREG_SPEED_1000M_LBN 4
-#define MDIO_MMDREG_SPEED_1000M_WIDTH 1
-#define MDIO_MMDREG_SPEED_100M_LBN 5
-#define MDIO_MMDREG_SPEED_100M_WIDTH 1
-#define MDIO_MMDREG_SPEED_10M_LBN 6
-#define MDIO_MMDREG_SPEED_10M_WIDTH 1
-
-/* Bits in MMDREG_STAT2 */
-#define MDIO_MMDREG_STAT2_PRESENT_VAL (2)
-#define MDIO_MMDREG_STAT2_PRESENT_LBN (14)
-#define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2)
-
-/* Bits in MMDREG_TXDIS */
-#define MDIO_MMDREG_TXDIS_GLOBAL_LBN (0)
-#define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH (1)
-
-/* MMD-specific bits, ordered by MMD, then register */
-#define MDIO_PMAPMD_CTRL1_LBACK_LBN (0)
-#define MDIO_PMAPMD_CTRL1_LBACK_WIDTH (1)
-
-/* PMA type (4 bits) */
-#define MDIO_PMAPMD_CTRL2_10G_CX4 (0x0)
-#define MDIO_PMAPMD_CTRL2_10G_EW (0x1)
-#define MDIO_PMAPMD_CTRL2_10G_LW (0x2)
-#define MDIO_PMAPMD_CTRL2_10G_SW (0x3)
-#define MDIO_PMAPMD_CTRL2_10G_LX4 (0x4)
-#define MDIO_PMAPMD_CTRL2_10G_ER (0x5)
-#define MDIO_PMAPMD_CTRL2_10G_LR (0x6)
-#define MDIO_PMAPMD_CTRL2_10G_SR (0x7)
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_10G_BT (0x9)
-/* Reserved */
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_1G_BT (0xc)
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_100_BT (0xe)
-#define MDIO_PMAPMD_CTRL2_10_BT (0xf)
-#define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf)
-
-/* PMA 10GBT registers */
-#define MDIO_PMAPMD_10GBT_TXPWR (131)
-#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0)
-#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1)
-
-/* PHY XGXS Status 2 */
-#define MDIO_PHYXS_STATUS2 (8)
-#define MDIO_PHYXS_STATUS2_RX_FAULT_LBN 10
-
-/* PHY XGXS lane state */
-#define MDIO_PHYXS_LANE_STATE (0x18)
-#define MDIO_PHYXS_LANE_ALIGNED_LBN (12)
-
-/* AN registers */
-#define MDIO_AN_CTRL_XNP_LBN 13
-#define MDIO_AN_STATUS (1)
-#define MDIO_AN_STATUS_XNP_LBN (7)
-#define MDIO_AN_STATUS_PAGE_LBN (6)
-#define MDIO_AN_STATUS_AN_DONE_LBN (5)
-#define MDIO_AN_STATUS_LP_AN_CAP_LBN (0)
-
-#define MDIO_AN_ADVERTISE 16
-#define MDIO_AN_ADVERTISE_XNP_LBN 12
-#define MDIO_AN_LPA 19
-#define MDIO_AN_XNP 22
-#define MDIO_AN_LPA_XNP 25
-
-#define MDIO_AN_10GBT_CTRL 32
-#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12
-#define MDIO_AN_10GBT_STATUS (33)
-#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */
-#define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */
-#define MDIO_AN_10GBT_STATUS_LOC_OK_LBN (13) /* Local OK */
-#define MDIO_AN_10GBT_STATUS_REM_OK_LBN (12) /* Remote OK */
-#define MDIO_AN_10GBT_STATUS_LP_10G_LBN (11) /* Link partner is 10GBT capable */
-#define MDIO_AN_10GBT_STATUS_LP_LTA_LBN (10) /* LP loop timing ability */
-#define MDIO_AN_10GBT_STATUS_LP_TRR_LBN (9) /* LP Training Reset Request */
-
+static inline unsigned efx_mdio_id_rev(u32 id) { return id & 0xf; }
+static inline unsigned efx_mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
+extern unsigned efx_mdio_id_oui(u32 id);
-/* Packing of the prt and dev arguments of clause 45 style MDIO into a
- * single int so they can be passed into the mdio_read/write functions
- * that currently exist. Note that as Falcon is the only current user,
- * the packed form is chosen to match what Falcon needs to write into
- * a register. This is checked at compile-time so do not change it. If
- * your target chip needs things layed out differently you will need
- * to unpack the arguments in your chip-specific mdio functions.
- */
- /* These are defined by the standard. */
-#define MDIO45_PRT_ID_WIDTH (5)
-#define MDIO45_DEV_ID_WIDTH (5)
-
-/* The prt ID is just packed in immediately to the left of the dev ID */
-#define MDIO45_PRT_DEV_WIDTH (MDIO45_PRT_ID_WIDTH + MDIO45_DEV_ID_WIDTH)
-
-#define MDIO45_PRT_ID_MASK ((1 << MDIO45_PRT_DEV_WIDTH) - 1)
-/* This is the prt + dev extended by 1 bit to hold the 'is clause 45' flag. */
-#define MDIO45_XPRT_ID_WIDTH (MDIO45_PRT_DEV_WIDTH + 1)
-#define MDIO45_XPRT_ID_MASK ((1 << MDIO45_XPRT_ID_WIDTH) - 1)
-#define MDIO45_XPRT_ID_IS10G (1 << (MDIO45_XPRT_ID_WIDTH - 1))
-
-
-#define MDIO45_PRT_ID_COMP_LBN MDIO45_DEV_ID_WIDTH
-#define MDIO45_PRT_ID_COMP_WIDTH MDIO45_PRT_ID_WIDTH
-#define MDIO45_DEV_ID_COMP_LBN 0
-#define MDIO45_DEV_ID_COMP_WIDTH MDIO45_DEV_ID_WIDTH
-
-/* Compose port and device into a phy_id */
-static inline int mdio_clause45_pack(u8 prt, u8 dev)
-{
- efx_dword_t phy_id;
- EFX_POPULATE_DWORD_2(phy_id, MDIO45_PRT_ID_COMP, prt,
- MDIO45_DEV_ID_COMP, dev);
- return MDIO45_XPRT_ID_IS10G | EFX_DWORD_VAL(phy_id);
-}
-
-static inline void mdio_clause45_unpack(u32 val, u8 *prt, u8 *dev)
+static inline int efx_mdio_read(struct efx_nic *efx, int devad, int addr)
{
- efx_dword_t phy_id;
- EFX_POPULATE_DWORD_1(phy_id, EFX_DWORD_0, val);
- *prt = EFX_DWORD_FIELD(phy_id, MDIO45_PRT_ID_COMP);
- *dev = EFX_DWORD_FIELD(phy_id, MDIO45_DEV_ID_COMP);
+ return efx->mdio.mdio_read(efx->net_dev, efx->mdio.prtad, devad, addr);
}
-static inline int mdio_clause45_read(struct efx_nic *efx,
- u8 prt, u8 dev, u16 addr)
+static inline void
+efx_mdio_write(struct efx_nic *efx, int devad, int addr, int value)
{
- return efx->mii.mdio_read(efx->net_dev,
- mdio_clause45_pack(prt, dev), addr);
+ efx->mdio.mdio_write(efx->net_dev, efx->mdio.prtad, devad, addr, value);
}
-static inline void mdio_clause45_write(struct efx_nic *efx,
- u8 prt, u8 dev, u16 addr, int value)
+static inline u32 efx_mdio_read_id(struct efx_nic *efx, int mmd)
{
- efx->mii.mdio_write(efx->net_dev,
- mdio_clause45_pack(prt, dev), addr, value);
-}
-
-
-static inline u32 mdio_clause45_read_id(struct efx_nic *efx, int mmd)
-{
- int phy_id = efx->mii.phy_id;
- u16 id_low = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDLOW);
- u16 id_hi = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDHI);
+ u16 id_low = efx_mdio_read(efx, mmd, MDIO_DEVID2);
+ u16 id_hi = efx_mdio_read(efx, mmd, MDIO_DEVID1);
return (id_hi << 16) | (id_low);
}
-static inline bool mdio_clause45_phyxgxs_lane_sync(struct efx_nic *efx)
+static inline bool efx_mdio_phyxgxs_lane_sync(struct efx_nic *efx)
{
int i, lane_status;
bool sync;
for (i = 0; i < 2; ++i)
- lane_status = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PHYXS,
- MDIO_PHYXS_LANE_STATE);
+ lane_status = efx_mdio_read(efx, MDIO_MMD_PHYXS,
+ MDIO_PHYXS_LNSTAT);
- sync = !!(lane_status & (1 << MDIO_PHYXS_LANE_ALIGNED_LBN));
+ sync = !!(lane_status & MDIO_PHYXS_LNSTAT_ALIGN);
if (!sync)
EFX_LOG(efx, "XGXS lane status: %x\n", lane_status);
return sync;
}
-extern const char *mdio_clause45_mmd_name(int mmd);
+extern const char *efx_mdio_mmd_name(int mmd);
/*
* Reset a specific MMD and wait for reset to clear.
@@ -258,54 +64,44 @@ extern const char *mdio_clause45_mmd_name(int mmd);
*
* This function will sleep
*/
-extern int mdio_clause45_reset_mmd(struct efx_nic *efx, int mmd,
- int spins, int spintime);
+extern int efx_mdio_reset_mmd(struct efx_nic *efx, int mmd,
+ int spins, int spintime);
-/* As mdio_clause45_check_mmd but for multiple MMDs */
-int mdio_clause45_check_mmds(struct efx_nic *efx,
- unsigned int mmd_mask, unsigned int fatal_mask);
+/* As efx_mdio_check_mmd but for multiple MMDs */
+int efx_mdio_check_mmds(struct efx_nic *efx,
+ unsigned int mmd_mask, unsigned int fatal_mask);
/* Check the link status of specified mmds in bit mask */
-extern bool mdio_clause45_links_ok(struct efx_nic *efx,
- unsigned int mmd_mask);
+extern bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask);
/* Generic transmit disable support though PMAPMD */
-extern void mdio_clause45_transmit_disable(struct efx_nic *efx);
+extern void efx_mdio_transmit_disable(struct efx_nic *efx);
/* Generic part of reconfigure: set/clear loopback bits */
-extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx);
+extern void efx_mdio_phy_reconfigure(struct efx_nic *efx);
/* Set the power state of the specified MMDs */
-extern void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
- int low_power, unsigned int mmd_mask);
-
-/* Read (some of) the PHY settings over MDIO */
-extern void mdio_clause45_get_settings(struct efx_nic *efx,
- struct ethtool_cmd *ecmd);
-
-/* Read (some of) the PHY settings over MDIO */
-extern void
-mdio_clause45_get_settings_ext(struct efx_nic *efx, struct ethtool_cmd *ecmd,
- u32 xnp, u32 xnp_lpa);
+extern void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
+ int low_power, unsigned int mmd_mask);
/* Set (some of) the PHY settings over MDIO */
-extern int mdio_clause45_set_settings(struct efx_nic *efx,
- struct ethtool_cmd *ecmd);
-
-/* Set pause parameters to be advertised through AN (if available) */
-extern void mdio_clause45_set_pause(struct efx_nic *efx);
+extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
/* Get pause parameters from AN if available (otherwise return
* requested pause parameters)
*/
-enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx);
+enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx);
/* Wait for specified MMDs to exit reset within a timeout */
-extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
- unsigned int mmd_mask);
+extern int efx_mdio_wait_reset_mmds(struct efx_nic *efx,
+ unsigned int mmd_mask);
/* Set or clear flag, debouncing */
-extern void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
- u16 addr, int bit, bool sense);
+static inline void
+efx_mdio_set_flag(struct efx_nic *efx, int devad, int addr,
+ int mask, bool state)
+{
+ mdio_set_flag(&efx->mdio, efx->mdio.prtad, devad, addr, mask, state);
+}
#endif /* EFX_MDIO_10G_H */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index e169e5dcd1e6..5eabede9ac18 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -19,7 +19,7 @@
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/timer.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -458,8 +458,6 @@ enum phy_type {
PHY_TYPE_MAX /* Insert any new items before this */
};
-#define PHY_ADDR_INVALID 0xff
-
#define EFX_IS10G(efx) ((efx)->link_speed == 10000)
enum nic_state {
@@ -497,8 +495,8 @@ struct efx_nic;
/* Pseudo bit-mask flow control field */
enum efx_fc_type {
- EFX_FC_RX = 1,
- EFX_FC_TX = 2,
+ EFX_FC_RX = FLOW_CTRL_RX,
+ EFX_FC_TX = FLOW_CTRL_TX,
EFX_FC_AUTO = 4,
};
@@ -508,33 +506,15 @@ enum efx_mac_type {
EFX_XMAC = 2,
};
-static inline unsigned int efx_fc_advertise(enum efx_fc_type wanted_fc)
-{
- unsigned int adv = 0;
- if (wanted_fc & EFX_FC_RX)
- adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
- if (wanted_fc & EFX_FC_TX)
- adv ^= ADVERTISE_PAUSE_ASYM;
- return adv;
-}
-
static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc,
unsigned int lpa)
{
- unsigned int adv = efx_fc_advertise(wanted_fc);
+ BUILD_BUG_ON(EFX_FC_AUTO & (EFX_FC_RX | EFX_FC_TX));
if (!(wanted_fc & EFX_FC_AUTO))
return wanted_fc;
- if (adv & lpa & ADVERTISE_PAUSE_CAP)
- return EFX_FC_RX | EFX_FC_TX;
- if (adv & lpa & ADVERTISE_PAUSE_ASYM) {
- if (adv & ADVERTISE_PAUSE_CAP)
- return EFX_FC_RX;
- if (lpa & ADVERTISE_PAUSE_CAP)
- return EFX_FC_TX;
- }
- return 0;
+ return mii_resolve_flowctrl_fdx(mii_advertise_flowctrl(wanted_fc), lpa);
}
/**
@@ -758,7 +738,7 @@ union efx_multicast_hash {
* @phy_lock: PHY access lock
* @phy_op: PHY interface
* @phy_data: PHY private data (including PHY-specific stats)
- * @mii: PHY interface
+ * @mdio: PHY MDIO interface
* @phy_mode: PHY operating mode. Serialised by @mac_lock.
* @mac_up: MAC link state
* @link_up: Link status
@@ -845,7 +825,7 @@ struct efx_nic {
struct work_struct phy_work;
struct efx_phy_operations *phy_op;
void *phy_data;
- struct mii_if_info mii;
+ struct mdio_if_info mdio;
enum efx_phy_mode phy_mode;
bool mac_up;
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 66d7fe3db3e6..01f9432c31ef 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -450,17 +450,27 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
/* Pass the skb/page into the LRO engine */
if (rx_buf->page) {
- struct napi_gro_fraginfo info;
+ struct sk_buff *skb = napi_get_frags(napi);
- info.frags[0].page = rx_buf->page;
- info.frags[0].page_offset = efx_rx_buf_offset(rx_buf);
- info.frags[0].size = rx_buf->len;
- info.nr_frags = 1;
- info.ip_summed = CHECKSUM_UNNECESSARY;
- info.len = rx_buf->len;
+ if (!skb) {
+ put_page(rx_buf->page);
+ goto out;
+ }
+
+ skb_shinfo(skb)->frags[0].page = rx_buf->page;
+ skb_shinfo(skb)->frags[0].page_offset =
+ efx_rx_buf_offset(rx_buf);
+ skb_shinfo(skb)->frags[0].size = rx_buf->len;
+ skb_shinfo(skb)->nr_frags = 1;
+
+ skb->len = rx_buf->len;
+ skb->data_len = rx_buf->len;
+ skb->truesize += rx_buf->len;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
- napi_gro_frags(napi, &info);
+ napi_gro_frags(napi);
+out:
EFX_BUG_ON_PARANOID(rx_buf->skb);
rx_buf->page = NULL;
} else {
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 0a598084c513..043795715955 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -80,39 +80,38 @@ struct efx_loopback_state {
*
**************************************************************************/
-static int efx_test_mii(struct efx_nic *efx, struct efx_self_tests *tests)
+static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests)
{
int rc = 0;
+ int devad = __ffs(efx->mdio.mmds);
u16 physid1, physid2;
- struct mii_if_info *mii = &efx->mii;
- struct net_device *net_dev = efx->net_dev;
if (efx->phy_type == PHY_TYPE_NONE)
return 0;
mutex_lock(&efx->mac_lock);
- tests->mii = -1;
+ tests->mdio = -1;
- physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1);
- physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2);
+ physid1 = efx_mdio_read(efx, devad, MDIO_DEVID1);
+ physid2 = efx_mdio_read(efx, devad, MDIO_DEVID2);
if ((physid1 == 0x0000) || (physid1 == 0xffff) ||
(physid2 == 0x0000) || (physid2 == 0xffff)) {
- EFX_ERR(efx, "no MII PHY present with ID %d\n",
- mii->phy_id);
+ EFX_ERR(efx, "no MDIO PHY present with ID %d\n",
+ efx->mdio.prtad);
rc = -EINVAL;
goto out;
}
if (EFX_IS10G(efx)) {
- rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0);
+ rc = efx_mdio_check_mmds(efx, efx->phy_op->mmds, 0);
if (rc)
goto out;
}
out:
mutex_unlock(&efx->mac_lock);
- tests->mii = rc ? -1 : 1;
+ tests->mdio = rc ? -1 : 1;
return rc;
}
@@ -673,7 +672,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
/* Online (i.e. non-disruptive) testing
* This checks interrupt generation, event delivery and PHY presence. */
- rc = efx_test_mii(efx, tests);
+ rc = efx_test_mdio(efx, tests);
if (rc && !rc_test)
rc_test = rc;
diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h
index 39451cf938cf..f6feee04c96b 100644
--- a/drivers/net/sfc/selftest.h
+++ b/drivers/net/sfc/selftest.h
@@ -32,7 +32,7 @@ struct efx_loopback_self_tests {
*/
struct efx_self_tests {
/* online tests */
- int mii;
+ int mdio;
int nvram;
int interrupt;
int eventq_dma[EFX_MAX_CHANNELS];
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 4eac5da81e5a..cee00ad49b57 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -296,7 +296,6 @@ static int sfe4001_check_hw(struct efx_nic *efx)
static struct i2c_board_info sfe4001_hwmon_info = {
I2C_BOARD_INFO("max6647", 0x4e),
- .irq = -1,
};
/* This board uses an I2C expander to provider power to the PHY, which needs to
@@ -389,12 +388,10 @@ static void sfn4111t_fini(struct efx_nic *efx)
static struct i2c_board_info sfn4111t_a0_hwmon_info = {
I2C_BOARD_INFO("max6647", 0x4e),
- .irq = -1,
};
static struct i2c_board_info sfn4111t_r5_hwmon_info = {
I2C_BOARD_INFO("max6646", 0x4d),
- .irq = -1,
};
int sfn4111t_init(struct efx_nic *efx)
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index e61dc4d4741c..0421190db7de 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -23,10 +23,10 @@
* clause 22 extension MMD, but since it doesn't have all the generic
* MMD registers it is pointless to include it here.
*/
-#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD | \
- MDIO_MMDREG_DEVS_PCS | \
- MDIO_MMDREG_DEVS_PHYXS | \
- MDIO_MMDREG_DEVS_AN)
+#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \
+ MDIO_DEVS_PCS | \
+ MDIO_DEVS_PHYXS | \
+ MDIO_DEVS_AN)
#define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \
(1 << LOOPBACK_PCS) | \
@@ -153,10 +153,6 @@
#define LOOPBACK_NEAR_LBN (8)
#define LOOPBACK_NEAR_WIDTH (1)
-#define PCS_10GBASET_STAT1 32
-#define PCS_10GBASET_BLKLK_LBN 0
-#define PCS_10GBASET_BLKLK_WIDTH 1
-
/* Boot status register */
#define PCS_BOOT_STATUS_REG 53248
#define PCS_BOOT_FATAL_ERROR_LBN 0
@@ -206,10 +202,8 @@ static ssize_t show_phy_short_reach(struct device *dev,
struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
int reg;
- reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- MDIO_PMAPMD_10GBT_TXPWR);
- return sprintf(buf, "%d\n",
- !!(reg & (1 << MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN)));
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR);
+ return sprintf(buf, "%d\n", !!(reg & MDIO_PMA_10GBT_TXPWR_SHORT));
}
static ssize_t set_phy_short_reach(struct device *dev,
@@ -219,10 +213,9 @@ static ssize_t set_phy_short_reach(struct device *dev,
struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
rtnl_lock();
- mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- MDIO_PMAPMD_10GBT_TXPWR,
- MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN,
- count != 0 && *buf != '0');
+ efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR,
+ MDIO_PMA_10GBT_TXPWR_SHORT,
+ count != 0 && *buf != '0');
efx_reconfigure_port(efx);
rtnl_unlock();
@@ -238,9 +231,8 @@ int sft9001_wait_boot(struct efx_nic *efx)
int boot_stat;
for (;;) {
- boot_stat = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PCS,
- PCS_BOOT_STATUS_REG);
+ boot_stat = efx_mdio_read(efx, MDIO_MMD_PCS,
+ PCS_BOOT_STATUS_REG);
if (boot_stat >= 0) {
EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat);
switch (boot_stat &
@@ -286,38 +278,32 @@ int sft9001_wait_boot(struct efx_nic *efx)
static int tenxpress_init(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
int reg;
if (efx->phy_type == PHY_TYPE_SFX7101) {
/* Enable 312.5 MHz clock */
- mdio_clause45_write(efx, phy_id,
- MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
- 1 << CLK312_EN_LBN);
+ efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
+ 1 << CLK312_EN_LBN);
} else {
/* Enable 312.5 MHz clock and GMII */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
(1 << PMA_PMD_EXT_CLK_OUT_LBN) |
(1 << PMA_PMD_EXT_CLK312_LBN) |
(1 << PMA_PMD_EXT_ROBUST_LBN));
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, reg);
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG, GPHY_ISOLATE_LBN,
- false);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
+ efx_mdio_set_flag(efx, MDIO_MMD_C22EXT,
+ GPHY_XCONTROL_REG, 1 << GPHY_ISOLATE_LBN,
+ false);
}
/* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
if (efx->phy_type == PHY_TYPE_SFX7101) {
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_LED_CTRL_REG,
- PMA_PMA_LED_ACTIVITY_LBN,
- true);
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT);
+ efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
+ 1 << PMA_PMA_LED_ACTIVITY_LBN, true);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
+ PMA_PMD_LED_DEFAULT);
}
return 0;
@@ -337,22 +323,19 @@ static int tenxpress_phy_init(struct efx_nic *efx)
if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
if (efx->phy_type == PHY_TYPE_SFT9001A) {
int reg;
- reg = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_XCONTROL_REG);
reg |= (1 << PMA_PMD_EXT_SSR_LBN);
- mdio_clause45_write(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_XCONTROL_REG, reg);
mdelay(200);
}
- rc = mdio_clause45_wait_reset_mmds(efx,
- TENXPRESS_REQUIRED_DEVS);
+ rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
goto fail;
- rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
+ rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
if (rc < 0)
goto fail;
}
@@ -360,7 +343,6 @@ static int tenxpress_phy_init(struct efx_nic *efx)
rc = tenxpress_init(efx);
if (rc < 0)
goto fail;
- mdio_clause45_set_pause(efx);
if (efx->phy_type == PHY_TYPE_SFT9001B) {
rc = device_create_file(&efx->pci_dev->dev,
@@ -395,17 +377,14 @@ static int tenxpress_special_reset(struct efx_nic *efx)
efx_stats_disable(efx);
/* Initiate reset */
- reg = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
reg |= (1 << PMA_PMD_EXT_SSR_LBN);
- mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
mdelay(200);
/* Wait for the blocks to come out of reset */
- rc = mdio_clause45_wait_reset_mmds(efx,
- TENXPRESS_REQUIRED_DEVS);
+ rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
goto out;
@@ -424,7 +403,6 @@ out:
static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
{
struct tenxpress_phy_data *pd = efx->phy_data;
- int phy_id = efx->mii.phy_id;
bool bad_lp;
int reg;
@@ -432,11 +410,10 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
bad_lp = false;
} else {
/* Check that AN has started but not completed. */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_STATUS);
- if (!(reg & (1 << MDIO_AN_STATUS_LP_AN_CAP_LBN)))
+ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_STAT1);
+ if (!(reg & MDIO_AN_STAT1_LPABLE))
return; /* LP status is unknown */
- bad_lp = !(reg & (1 << MDIO_AN_STATUS_AN_DONE_LBN));
+ bad_lp = !(reg & MDIO_AN_STAT1_COMPLETE);
if (bad_lp)
pd->bad_lp_tries++;
}
@@ -448,8 +425,8 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
/* Use the RX (red) LED as an error indicator once we've seen AN
* failure several times in a row, and also log a message. */
if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_LED_OVERR_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_LED_OVERR_REG);
reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN);
if (!bad_lp) {
reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN;
@@ -460,23 +437,22 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
" supports 10GBASE-T ONLY, so no link can"
" be established\n");
}
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_LED_OVERR_REG, reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_LED_OVERR_REG, reg);
pd->bad_lp_tries = bad_lp;
}
}
static bool sfx7101_link_ok(struct efx_nic *efx)
{
- return mdio_clause45_links_ok(efx,
- MDIO_MMDREG_DEVS_PMAPMD |
- MDIO_MMDREG_DEVS_PCS |
- MDIO_MMDREG_DEVS_PHYXS);
+ return efx_mdio_links_ok(efx,
+ MDIO_DEVS_PMAPMD |
+ MDIO_DEVS_PCS |
+ MDIO_DEVS_PHYXS);
}
static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy_id = efx->mii.phy_id;
u32 reg;
if (efx_phy_mode_disabled(efx->phy_mode))
@@ -484,50 +460,43 @@ static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
else if (efx->loopback_mode == LOOPBACK_GPHY)
return true;
else if (efx->loopback_mode)
- return mdio_clause45_links_ok(efx,
- MDIO_MMDREG_DEVS_PMAPMD |
- MDIO_MMDREG_DEVS_PHYXS);
+ return efx_mdio_links_ok(efx,
+ MDIO_DEVS_PMAPMD |
+ MDIO_DEVS_PHYXS);
/* We must use the same definition of link state as LASI,
* otherwise we can miss a link state transition
*/
if (ecmd->speed == 10000) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
- PCS_10GBASET_STAT1);
- return reg & (1 << PCS_10GBASET_BLKLK_LBN);
+ reg = efx_mdio_read(efx, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
+ return reg & MDIO_PCS_10GBRT_STAT1_BLKLK;
} else {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
- C22EXT_STATUS_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_STATUS_REG);
return reg & (1 << C22EXT_STATUS_LINK_LBN);
}
}
static void tenxpress_ext_loopback(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
-
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
- PHYXS_TEST1, LOOPBACK_NEAR_LBN,
- efx->loopback_mode == LOOPBACK_PHYXS);
+ efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1,
+ 1 << LOOPBACK_NEAR_LBN,
+ efx->loopback_mode == LOOPBACK_PHYXS);
if (efx->phy_type != PHY_TYPE_SFX7101)
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG,
- GPHY_LOOPBACK_NEAR_LBN,
- efx->loopback_mode == LOOPBACK_GPHY);
+ efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, GPHY_XCONTROL_REG,
+ 1 << GPHY_LOOPBACK_NEAR_LBN,
+ efx->loopback_mode == LOOPBACK_GPHY);
}
static void tenxpress_low_power(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
-
if (efx->phy_type == PHY_TYPE_SFX7101)
- mdio_clause45_set_mmds_lpower(
+ efx_mdio_set_mmds_lpower(
efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
TENXPRESS_REQUIRED_DEVS);
else
- mdio_clause45_set_flag(
- efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, PMA_PMD_EXT_LPOWER_LBN,
+ efx_mdio_set_flag(
+ efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG,
+ 1 << PMA_PMD_EXT_LPOWER_LBN,
!!(efx->phy_mode & PHY_MODE_LOW_POWER));
}
@@ -568,8 +537,8 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
WARN_ON(rc);
}
- mdio_clause45_transmit_disable(efx);
- mdio_clause45_phy_reconfigure(efx);
+ efx_mdio_transmit_disable(efx);
+ efx_mdio_phy_reconfigure(efx);
tenxpress_ext_loopback(efx);
phy_data->loopback_mode = efx->loopback_mode;
@@ -585,7 +554,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
efx->link_fd = ecmd.duplex == DUPLEX_FULL;
efx->link_up = sft9001_link_ok(efx, &ecmd);
}
- efx->link_fc = mdio_clause45_get_pause(efx);
+ efx->link_fc = efx_mdio_get_pause(efx);
}
/* Poll PHY for interrupt */
@@ -599,7 +568,7 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
if (link_ok != efx->link_up) {
change = true;
} else {
- unsigned int link_fc = mdio_clause45_get_pause(efx);
+ unsigned int link_fc = efx_mdio_get_pause(efx);
if (link_fc != efx->link_fc)
change = true;
}
@@ -609,9 +578,8 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
if (link_ok != efx->link_up)
change = true;
} else {
- u32 status = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD,
- PMA_PMD_LASI_STATUS);
+ int status = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_LASI_STATUS);
if (status & (1 << PMA_PMD_LS_ALARM_LBN))
change = true;
}
@@ -634,8 +602,7 @@ static void tenxpress_phy_fini(struct efx_nic *efx)
if (efx->phy_type == PHY_TYPE_SFX7101) {
/* Power down the LNPGA */
reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
- mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
/* Waiting here ensures that the board fini, which can turn
* off the power to the PHY, won't get run until the LNPGA
@@ -661,8 +628,7 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
else
reg = PMA_PMD_LED_DEFAULT;
- mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_LED_OVERR_REG, reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
}
static const char *const sfx7101_test_names[] = {
@@ -698,7 +664,6 @@ static const char *const sft9001_test_names[] = {
static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
{
struct ethtool_cmd ecmd;
- int phy_id = efx->mii.phy_id;
int rc = 0, rc2, i, ctrl_reg, res_reg;
if (flags & ETH_TEST_FL_OFFLINE)
@@ -717,11 +682,10 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
* must reset the PHY to resume normal service. */
ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
}
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_CTRL_REG, ctrl_reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG,
+ ctrl_reg);
i = 0;
- while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_CTRL_REG) &
+ while (efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG) &
(1 << CDIAG_CTRL_IN_PROG_LBN)) {
if (++i == 50) {
rc = -ETIMEDOUT;
@@ -729,15 +693,13 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
}
msleep(100);
}
- res_reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_RES_REG);
+ res_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_RES_REG);
for (i = 0; i < 4; i++) {
int pair_res =
(res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH))
& ((1 << CDIAG_RES_WIDTH) - 1);
- int len_reg = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_LEN_REG + i);
+ int len_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_CDIAG_LEN_REG + i);
if (pair_res == CDIAG_RES_OK)
results[1 + i] = 1;
else if (pair_res == CDIAG_RES_INVALID)
@@ -769,32 +731,27 @@ out:
static void
tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy_id = efx->mii.phy_id;
u32 adv = 0, lpa = 0;
int reg;
if (efx->phy_type != PHY_TYPE_SFX7101) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
- C22EXT_MSTSLV_CTRL);
+ reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL);
if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
adv |= ADVERTISED_1000baseT_Full;
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
- C22EXT_MSTSLV_STATUS);
+ reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_STATUS);
if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
lpa |= ADVERTISED_1000baseT_Half;
if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
lpa |= ADVERTISED_1000baseT_Full;
}
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_10GBT_CTRL);
- if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
+ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
+ if (reg & MDIO_AN_10GBT_CTRL_ADV10G)
adv |= ADVERTISED_10000baseT_Full;
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_10GBT_STATUS);
- if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
+ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
+ if (reg & MDIO_AN_10GBT_STAT_LP10G)
lpa |= ADVERTISED_10000baseT_Full;
- mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
+ mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa);
if (efx->phy_type != PHY_TYPE_SFX7101)
ecmd->supported |= (SUPPORTED_100baseT_Full |
@@ -813,29 +770,24 @@ static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
if (!ecmd->autoneg)
return -EINVAL;
- return mdio_clause45_set_settings(efx, ecmd);
+ return efx_mdio_set_settings(efx, ecmd);
}
static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
{
- mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
- MDIO_AN_10GBT_CTRL,
- MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
- advertising & ADVERTISED_10000baseT_Full);
+ efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+ MDIO_AN_10GBT_CTRL_ADV10G,
+ advertising & ADVERTISED_10000baseT_Full);
}
static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
{
- int phy_id = efx->mii.phy_id;
-
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
- C22EXT_MSTSLV_CTRL,
- C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
- advertising & ADVERTISED_1000baseT_Full);
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_10GBT_CTRL,
- MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
- advertising & ADVERTISED_10000baseT_Full);
+ efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL,
+ 1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
+ advertising & ADVERTISED_1000baseT_Full);
+ efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+ MDIO_AN_10GBT_CTRL_ADV10G,
+ advertising & ADVERTISED_10000baseT_Full);
}
struct efx_phy_operations falcon_sfx7101_phy_ops = {
diff --git a/drivers/net/sfc/xenpack.h b/drivers/net/sfc/xenpack.h
index b0d1f225b70a..4e52286e542d 100644
--- a/drivers/net/sfc/xenpack.h
+++ b/drivers/net/sfc/xenpack.h
@@ -34,29 +34,24 @@
/* Enable LASI interrupts for PHY */
static inline void xenpack_enable_lasi_irqs(struct efx_nic *efx)
{
- int reg;
- int phy_id = efx->mii.phy_id;
/* Read to clear LASI status register */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_XP_LASI_STAT);
+ efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT);
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_XP_LASI_CTRL, XP_LASI_LS_ALARM);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_CTRL,
+ XP_LASI_LS_ALARM);
}
/* Read the LASI interrupt status to clear the interrupt. */
static inline int xenpack_clear_lasi_irqs(struct efx_nic *efx)
{
/* Read to clear link status alarm */
- return mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT);
+ return efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT);
}
/* Turn off LASI interrupts */
static inline void xenpack_disable_lasi_irqs(struct efx_nic *efx)
{
- mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- MDIO_XP_LASI_CTRL, 0);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_CTRL, 0);
}
#endif /* EFX_XENPACK_H */
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index bb1ef77d5f56..aad2dca19772 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -19,9 +19,9 @@
#include "phy.h"
#include "falcon.h"
-#define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS | \
- MDIO_MMDREG_DEVS_PMAPMD | \
- MDIO_MMDREG_DEVS_PHYXS)
+#define XFP_REQUIRED_DEVS (MDIO_DEVS_PCS | \
+ MDIO_DEVS_PMAPMD | \
+ MDIO_DEVS_PHYXS)
#define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) | \
(1 << LOOPBACK_PMAPMD) | \
@@ -49,8 +49,7 @@
void xfp_set_led(struct efx_nic *p, int led, int mode)
{
int addr = MDIO_QUAKE_LED0_REG + led;
- mdio_clause45_write(p, p->mii.phy_id, MDIO_MMD_PMAPMD, addr,
- mode);
+ efx_mdio_write(p, MDIO_MMD_PMAPMD, addr, mode);
}
struct xfp_phy_data {
@@ -63,14 +62,12 @@ struct xfp_phy_data {
static int qt2025c_wait_reset(struct efx_nic *efx)
{
unsigned long timeout = jiffies + 10 * HZ;
- int phy_id = efx->mii.phy_id;
int reg, old_counter = 0;
/* Wait for firmware heartbeat to start */
for (;;) {
int counter;
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
- PCS_FW_HEARTBEAT_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_FW_HEARTBEAT_REG);
if (reg < 0)
return reg;
counter = ((reg >> PCS_FW_HEARTB_LBN) &
@@ -86,8 +83,7 @@ static int qt2025c_wait_reset(struct efx_nic *efx)
/* Wait for firmware status to look good */
for (;;) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
- PCS_UC8051_STATUS_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG);
if (reg < 0)
return reg;
if ((reg &
@@ -109,9 +105,9 @@ static int xfp_reset_phy(struct efx_nic *efx)
{
int rc;
- rc = mdio_clause45_reset_mmd(efx, MDIO_MMD_PHYXS,
- XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
- XFP_RESET_WAIT);
+ rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PHYXS,
+ XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
+ XFP_RESET_WAIT);
if (rc < 0)
goto fail;
@@ -126,8 +122,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
/* Check that all the MMDs we expect are present and responding. We
* expect faults on some if the link is down, but not on the PHY XS */
- rc = mdio_clause45_check_mmds(efx, XFP_REQUIRED_DEVS,
- MDIO_MMDREG_DEVS_PHYXS);
+ rc = efx_mdio_check_mmds(efx, XFP_REQUIRED_DEVS, MDIO_DEVS_PHYXS);
if (rc < 0)
goto fail;
@@ -143,7 +138,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
static int xfp_phy_init(struct efx_nic *efx)
{
struct xfp_phy_data *phy_data;
- u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS);
+ u32 devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS);
int rc;
phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL);
@@ -152,8 +147,8 @@ static int xfp_phy_init(struct efx_nic *efx)
efx->phy_data = phy_data;
EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
- devid, mdio_id_oui(devid), mdio_id_model(devid),
- mdio_id_rev(devid));
+ devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid),
+ efx_mdio_id_rev(devid));
phy_data->phy_mode = efx->phy_mode;
@@ -179,7 +174,7 @@ static void xfp_phy_clear_interrupt(struct efx_nic *efx)
static int xfp_link_ok(struct efx_nic *efx)
{
- return mdio_clause45_links_ok(efx, XFP_REQUIRED_DEVS);
+ return efx_mdio_links_ok(efx, XFP_REQUIRED_DEVS);
}
static void xfp_phy_poll(struct efx_nic *efx)
@@ -200,9 +195,9 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
* or optical transceivers, varying somewhat between
* firmware versions. Only 'static mode' appears to
* cover everything. */
- mdio_clause45_set_flag(
- efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_FTX_CTRL2_REG, PMA_PMD_FTX_STATIC_LBN,
+ mdio_set_flag(
+ &efx->mdio, efx->mdio.prtad, MDIO_MMD_PMAPMD,
+ PMA_PMD_FTX_CTRL2_REG, 1 << PMA_PMD_FTX_STATIC_LBN,
efx->phy_mode & PHY_MODE_TX_DISABLED ||
efx->phy_mode & PHY_MODE_LOW_POWER ||
efx->loopback_mode == LOOPBACK_PCS ||
@@ -213,10 +208,10 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
(phy_data->phy_mode & PHY_MODE_TX_DISABLED))
xfp_reset_phy(efx);
- mdio_clause45_transmit_disable(efx);
+ efx_mdio_transmit_disable(efx);
}
- mdio_clause45_phy_reconfigure(efx);
+ efx_mdio_phy_reconfigure(efx);
phy_data->phy_mode = efx->phy_mode;
efx->link_up = xfp_link_ok(efx);
@@ -225,6 +220,10 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
efx->link_fc = efx->wanted_fc;
}
+static void xfp_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+{
+ mdio45_ethtool_gset(&efx->mdio, ecmd);
+}
static void xfp_phy_fini(struct efx_nic *efx)
{
@@ -243,8 +242,8 @@ struct efx_phy_operations falcon_xfp_phy_ops = {
.poll = xfp_phy_poll,
.fini = xfp_phy_fini,
.clear_interrupt = xfp_phy_clear_interrupt,
- .get_settings = mdio_clause45_get_settings,
- .set_settings = mdio_clause45_set_settings,
+ .get_settings = xfp_phy_get_settings,
+ .set_settings = efx_mdio_set_settings,
.mmds = XFP_REQUIRED_DEVS,
.loopbacks = XFP_LOOPBACKS,
};
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 97d68560067d..5fb88ca6dd7f 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -709,6 +709,17 @@ static inline void setup_rx_ring(struct net_device *dev,
dma_sync_desc_dev(dev, &buf[i]);
}
+static const struct net_device_ops sgiseeq_netdev_ops = {
+ .ndo_open = sgiseeq_open,
+ .ndo_stop = sgiseeq_close,
+ .ndo_start_xmit = sgiseeq_start_xmit,
+ .ndo_tx_timeout = timeout,
+ .ndo_set_multicast_list = sgiseeq_set_multicast,
+ .ndo_set_mac_address = sgiseeq_set_mac_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init sgiseeq_probe(struct platform_device *pdev)
{
struct sgiseeq_platform_data *pd = pdev->dev.platform_data;
@@ -775,13 +786,8 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT |
SEEQ_CTRL_ENCARR;
- dev->open = sgiseeq_open;
- dev->stop = sgiseeq_close;
- dev->hard_start_xmit = sgiseeq_start_xmit;
- dev->tx_timeout = timeout;
+ dev->netdev_ops = &sgiseeq_netdev_ops;
dev->watchdog_timeo = (200 * HZ) / 1000;
- dev->set_multicast_list = sgiseeq_set_multicast;
- dev->set_mac_address = sgiseeq_set_mac_address;
dev->irq = irq;
if (register_netdev(dev)) {
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 5c61d5fad908..527c2ce59150 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -616,6 +616,14 @@ static void sl_uninit(struct net_device *dev)
sl_free_bufs(sl);
}
+/* Hook the destructor so we can free slip devices at the right point in time */
+static void sl_free_netdev(struct net_device *dev)
+{
+ int i = dev->base_addr;
+ free_netdev(dev);
+ slip_devs[i] = NULL;
+}
+
static const struct net_device_ops sl_netdev_ops = {
.ndo_init = sl_init,
.ndo_uninit = sl_uninit,
@@ -634,7 +642,7 @@ static const struct net_device_ops sl_netdev_ops = {
static void sl_setup(struct net_device *dev)
{
dev->netdev_ops = &sl_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = sl_free_netdev;
dev->hard_header_len = 0;
dev->addr_len = 0;
@@ -712,8 +720,6 @@ static void sl_sync(void)
static struct slip *sl_alloc(dev_t line)
{
int i;
- int sel = -1;
- int score = -1;
struct net_device *dev = NULL;
struct slip *sl;
@@ -724,55 +730,7 @@ static struct slip *sl_alloc(dev_t line)
dev = slip_devs[i];
if (dev == NULL)
break;
-
- sl = netdev_priv(dev);
- if (sl->leased) {
- if (sl->line != line)
- continue;
- if (sl->tty)
- return NULL;
-
- /* Clear ESCAPE & ERROR flags */
- sl->flags &= (1 << SLF_INUSE);
- return sl;
- }
-
- if (sl->tty)
- continue;
-
- if (current->pid == sl->pid) {
- if (sl->line == line && score < 3) {
- sel = i;
- score = 3;
- continue;
- }
- if (score < 2) {
- sel = i;
- score = 2;
- }
- continue;
- }
- if (sl->line == line && score < 1) {
- sel = i;
- score = 1;
- continue;
- }
- if (score < 0) {
- sel = i;
- score = 0;
- }
- }
-
- if (sel >= 0) {
- i = sel;
- dev = slip_devs[i];
- if (score > 1) {
- sl = netdev_priv(dev);
- sl->flags &= (1 << SLF_INUSE);
- return sl;
- }
}
-
/* Sorry, too many, all slots in use */
if (i >= slip_maxdev)
return NULL;
@@ -909,30 +867,13 @@ err_exit:
}
/*
-
- FIXME: 1,2 are fixed 3 was never true anyway.
-
- Let me to blame a bit.
- 1. TTY module calls this funstion on soft interrupt.
- 2. TTY module calls this function WITH MASKED INTERRUPTS!
- 3. TTY module does not notify us about line discipline
- shutdown,
-
- Seems, now it is clean. The solution is to consider netdevice and
- line discipline sides as two independent threads.
-
- By-product (not desired): sl? does not feel hangups and remains open.
- It is supposed, that user level program (dip, diald, slattach...)
- will catch SIGHUP and make the rest of work.
-
- I see no way to make more with current tty code. --ANK
- */
-
-/*
* Close down a SLIP channel.
* This means flushing out any pending queues, and then returning. This
* call is serialized against other ldisc functions.
+ *
+ * We also use this method fo a hangup event
*/
+
static void slip_close(struct tty_struct *tty)
{
struct slip *sl = tty->disc_data;
@@ -951,10 +892,16 @@ static void slip_close(struct tty_struct *tty)
del_timer_sync(&sl->keepalive_timer);
del_timer_sync(&sl->outfill_timer);
#endif
-
- /* Count references from TTY module */
+ /* Flush network side */
+ unregister_netdev(sl->dev);
+ /* This will complete via sl_free_netdev */
}
+static int slip_hangup(struct tty_struct *tty)
+{
+ slip_close(tty);
+ return 0;
+}
/************************************************************************
* STANDARD SLIP ENCAPSULATION *
************************************************************************/
@@ -1311,6 +1258,7 @@ static struct tty_ldisc_ops sl_ldisc = {
.name = "slip",
.open = slip_open,
.close = slip_close,
+ .hangup = slip_hangup,
.ioctl = slip_ioctl,
.receive_buf = slip_receive_buf,
.write_wakeup = slip_write_wakeup,
@@ -1384,6 +1332,8 @@ static void __exit slip_exit(void)
}
} while (busy && time_before(jiffies, timeout));
+ /* FIXME: hangup is async so we should wait when doing this second
+ phase */
for (i = 0; i < slip_maxdev; i++) {
dev = slip_devs[i];
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
index 8d36d40649ef..c791ef76c1d6 100644
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -370,7 +370,7 @@ static int __init ultramca_probe(struct device *gen_dev)
outb(reg4, ioaddr + 4);
- gen_dev->driver_data = dev;
+ dev_set_drvdata(gen_dev, dev);
/* The 8390 isn't at the base address, so fake the offset
*/
@@ -531,7 +531,7 @@ static int ultramca_close_card(struct net_device *dev)
static int ultramca_remove(struct device *gen_dev)
{
struct mca_device *mca_dev = to_mca_device(gen_dev);
- struct net_device *dev = (struct net_device *)gen_dev->driver_data;
+ struct net_device *dev = dev_get_drvdata(gen_dev);
if (dev) {
/* NB: ultra_close_card() does free_irq */
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 293610334a77..bc4976ac8712 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -1774,6 +1774,20 @@ static int __devinit smc911x_findirq(struct net_device *dev)
return probe_irq_off(cookie);
}
+static const struct net_device_ops smc911x_netdev_ops = {
+ .ndo_open = smc911x_open,
+ .ndo_stop = smc911x_close,
+ .ndo_start_xmit = smc911x_hard_start_xmit,
+ .ndo_tx_timeout = smc911x_timeout,
+ .ndo_set_multicast_list = smc911x_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = smc911x_poll_controller,
+#endif
+};
+
/*
* Function: smc911x_probe(unsigned long ioaddr)
*
@@ -1940,16 +1954,9 @@ static int __devinit smc911x_probe(struct net_device *dev)
/* Fill in the fields of the device structure with ethernet values. */
ether_setup(dev);
- dev->open = smc911x_open;
- dev->stop = smc911x_close;
- dev->hard_start_xmit = smc911x_hard_start_xmit;
- dev->tx_timeout = smc911x_timeout;
+ dev->netdev_ops = &smc911x_netdev_ops;
dev->watchdog_timeo = msecs_to_jiffies(watchdog);
- dev->set_multicast_list = smc911x_set_multicast_list;
dev->ethtool_ops = &smc911x_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = smc911x_poll_controller;
-#endif
INIT_WORK(&lp->phy_configure, smc911x_phy_configure);
lp->mii.phy_id_mask = 0x1f;
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index eb7db032a780..3cff84078a9e 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -47,6 +47,7 @@
#include <linux/bitops.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/swab.h>
#include <linux/phy.h>
#include <linux/smsc911x.h>
#include "smsc911x.h"
@@ -175,6 +176,12 @@ static inline void
smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf,
unsigned int wordcount)
{
+ if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
+ while (wordcount--)
+ smsc911x_reg_write(pdata, TX_DATA_FIFO, swab32(*buf++));
+ return;
+ }
+
if (pdata->config.flags & SMSC911X_USE_32BIT) {
writesl(pdata->ioaddr + TX_DATA_FIFO, buf, wordcount);
return;
@@ -194,6 +201,12 @@ static inline void
smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf,
unsigned int wordcount)
{
+ if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
+ while (wordcount--)
+ *buf++ = swab32(smsc911x_reg_read(pdata, RX_DATA_FIFO));
+ return;
+ }
+
if (pdata->config.flags & SMSC911X_USE_32BIT) {
readsl(pdata->ioaddr + RX_DATA_FIFO, buf, wordcount);
return;
@@ -1963,7 +1976,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
retval = -ENODEV;
goto out_0;
}
- res_size = res->end - res->start;
+ res_size = res->end - res->start + 1;
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq_res) {
@@ -2096,12 +2109,58 @@ out_0:
return retval;
}
+#ifdef CONFIG_PM
+/* This implementation assumes the devices remains powered on its VDDVARIO
+ * pins during suspend. */
+
+static int smsc911x_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct smsc911x_data *pdata = netdev_priv(dev);
+
+ /* enable wake on LAN, energy detection and the external PME
+ * signal. */
+ smsc911x_reg_write(pdata, PMT_CTRL,
+ PMT_CTRL_PM_MODE_D1_ | PMT_CTRL_WOL_EN_ |
+ PMT_CTRL_ED_EN_ | PMT_CTRL_PME_EN_);
+
+ return 0;
+}
+
+static int smsc911x_resume(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct smsc911x_data *pdata = netdev_priv(dev);
+ unsigned int to = 100;
+
+ /* Note 3.11 from the datasheet:
+ * "When the LAN9220 is in a power saving state, a write of any
+ * data to the BYTE_TEST register will wake-up the device."
+ */
+ smsc911x_reg_write(pdata, BYTE_TEST, 0);
+
+ /* poll the READY bit in PMT_CTRL. Any other access to the device is
+ * forbidden while this bit isn't set. Try for 100ms and return -EIO
+ * if it failed. */
+ while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
+ udelay(1000);
+
+ return (to == 0) ? -EIO : 0;
+}
+
+#else
+#define smsc911x_suspend NULL
+#define smsc911x_resume NULL
+#endif
+
static struct platform_driver smsc911x_driver = {
.probe = smsc911x_drv_probe,
.remove = smsc911x_drv_remove,
.driver = {
.name = SMSC_CHIPNAME,
},
+ .suspend = smsc911x_suspend,
+ .resume = smsc911x_resume,
};
/* Entry point for loading the module */
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index e5beb299cbd0..9bd9dadb8534 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -294,6 +294,16 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = lance_open,
+ .ndo_stop = lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_set_mac_address = NULL,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init lance_probe( struct net_device *dev)
{
unsigned long ioaddr;
@@ -397,12 +407,7 @@ static int __init lance_probe( struct net_device *dev)
if (did_version++ == 0)
printk( version );
- /* The LANCE-specific entries in the device structure. */
- dev->open = &lance_open;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->stop = &lance_close;
- dev->set_multicast_list = &set_multicast_list;
- dev->set_mac_address = NULL;
+ dev->netdev_ops = &lance_netdev_ops;
// KLUDGE -- REMOVE ME
set_bit(__LINK_STATE_PRESENT, &dev->state);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 201be425643a..eb65e25989f3 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.98"
-#define DRV_MODULE_RELDATE "February 25, 2009"
+#define DRV_MODULE_VERSION "3.99"
+#define DRV_MODULE_RELDATE "April 20, 2009"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -1950,7 +1950,8 @@ static void tg3_frob_aux_power(struct tg3 *tp)
GRC_LCLCTRL_GPIO_OUTPUT0 |
GRC_LCLCTRL_GPIO_OUTPUT1),
100);
- } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+ } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
/* The 5761 non-e device swaps GPIO 0 and GPIO 2. */
u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
GRC_LCLCTRL_GPIO_OE1 |
@@ -2455,8 +2456,6 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
}
}
- __tg3_set_mac_addr(tp, 0);
-
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
u32 val;
@@ -4656,6 +4655,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
* so we must read it before checking for more work.
*/
tp->last_tag = sblk->status_tag;
+ tp->last_irq_tag = tp->last_tag;
rmb();
} else
sblk->status &= ~SD_STATUS_UPDATED;
@@ -4811,7 +4811,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* Reading the PCI State register will confirm whether the
* interrupt is ours and will flush the status block.
*/
- if (unlikely(sblk->status_tag == tp->last_tag)) {
+ if (unlikely(sblk->status_tag == tp->last_irq_tag)) {
if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
handled = 0;
@@ -4831,18 +4831,22 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* excessive spurious interrupts can be worse in some cases.
*/
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+
+ /*
+ * In a shared interrupt configuration, sometimes other devices'
+ * interrupts will scream. We record the current status tag here
+ * so that the above check can report that the screaming interrupts
+ * are unhandled. Eventually they will be silenced.
+ */
+ tp->last_irq_tag = sblk->status_tag;
+
if (tg3_irq_sync(tp))
goto out;
- if (napi_schedule_prep(&tp->napi)) {
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- /* Update last_tag to mark that this status has been
- * seen. Because interrupt may be shared, we may be
- * racing with tg3_poll(), so only update last_tag
- * if tg3_poll() is not scheduled.
- */
- tp->last_tag = sblk->status_tag;
- __napi_schedule(&tp->napi);
- }
+
+ prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+
+ napi_schedule(&tp->napi);
+
out:
return IRQ_RETVAL(handled);
}
@@ -6156,6 +6160,7 @@ static int tg3_chip_reset(struct tg3 *tp)
tp->hw_status->status_tag = 0;
}
tp->last_tag = 0;
+ tp->last_irq_tag = 0;
smp_mb();
synchronize_irq(tp->pdev->irq);
@@ -6350,6 +6355,8 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent)
tg3_abort_hw(tp, silent);
err = tg3_chip_reset(tp);
+ __tg3_set_mac_addr(tp, 0);
+
tg3_write_sig_legacy(tp, kind);
tg3_write_sig_post_reset(tp, kind);
@@ -6711,6 +6718,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(TG3_CPMU_HST_ACC, val);
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+ val = tr32(PCIE_PWR_MGMT_THRESH) & ~PCIE_PWR_MGMT_L1_THRESH_MSK;
+ val |= PCIE_PWR_MGMT_EXT_ASPM_TMR_EN |
+ PCIE_PWR_MGMT_L1_THRESH_4MS;
+ tw32(PCIE_PWR_MGMT_THRESH, val);
+ }
+
/* This works around an issue with Athlon chipsets on
* B3 tigon3 silicon. This bit has no effect on any
* other revision. But do not set this on PCI Express
@@ -7138,7 +7152,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
udelay(100);
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
- tp->last_tag = 0;
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
@@ -8539,6 +8552,9 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
u32 i, offset, len, b_offset, b_count;
__be32 val;
+ if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+ return -EINVAL;
+
if (tp->link_config.phy_is_low_power)
return -EAGAIN;
@@ -8604,7 +8620,8 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
if (tp->link_config.phy_is_low_power)
return -EAGAIN;
- if (eeprom->magic != TG3_EEPROM_MAGIC)
+ if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+ eeprom->magic != TG3_EEPROM_MAGIC)
return -EINVAL;
offset = eeprom->offset;
@@ -9201,6 +9218,9 @@ static int tg3_test_nvram(struct tg3 *tp)
__be32 *buf;
int i, j, k, err = 0, size;
+ if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+ return 0;
+
if (tg3_nvram_read(tp, 0, &magic) != 0)
return -EIO;
@@ -10183,7 +10203,8 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
{
u32 val;
- if (tg3_nvram_read(tp, 0, &val) != 0)
+ if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+ tg3_nvram_read(tp, 0, &val) != 0)
return;
/* Selfboot format */
@@ -10565,6 +10586,7 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
}
break;
default:
+ tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
return;
}
@@ -11365,7 +11387,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
unsigned int i;
u32 magic;
- if (tg3_nvram_read(tp, 0x0, &magic))
+ if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+ tg3_nvram_read(tp, 0x0, &magic))
goto out_not_found;
if (magic == TG3_EEPROM_MAGIC) {
@@ -11457,6 +11480,15 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
out_not_found:
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
strcpy(tp->board_part_number, "BCM95906");
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780)
+ strcpy(tp->board_part_number, "BCM57780");
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760)
+ strcpy(tp->board_part_number, "BCM57760");
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790)
+ strcpy(tp->board_part_number, "BCM57790");
else
strcpy(tp->board_part_number, "none");
}
@@ -11667,6 +11699,14 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
{
u32 val;
+ if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) {
+ tp->fw_ver[0] = 's';
+ tp->fw_ver[1] = 'b';
+ tp->fw_ver[2] = '\0';
+
+ return;
+ }
+
if (tg3_nvram_read(tp, 0, &val))
return;
@@ -11952,7 +11992,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+ tp->pci_chip_rev_id == CHIPREV_ID_57780_A0 ||
+ tp->pci_chip_rev_id == CHIPREV_ID_57780_A1)
tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
}
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
@@ -12144,7 +12185,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
- if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+ if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
/* Turn off the debug UART. */
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
@@ -12454,7 +12496,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
}
if (!addr_ok) {
/* Next, try NVRAM. */
- if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
+ if (!(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) &&
+ !tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
!tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo));
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index cb4c62abdd21..b3347c41a1a3 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -95,6 +95,8 @@
#define CHIPREV_ID_5752_A1 0x6001
#define CHIPREV_ID_5714_A2 0x9002
#define CHIPREV_ID_5906_A1 0xc001
+#define CHIPREV_ID_57780_A0 0x57780000
+#define CHIPREV_ID_57780_A1 0x57780001
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07
#define ASIC_REV_5701 0x00
@@ -1697,6 +1699,8 @@
#define PCIE_PWR_MGMT_THRESH 0x00007d28
#define PCIE_PWR_MGMT_L1_THRESH_MSK 0x0000ff00
+#define PCIE_PWR_MGMT_L1_THRESH_4MS 0x0000ff00
+#define PCIE_PWR_MGMT_EXT_ASPM_TMR_EN 0x01000000
/* OTP bit definitions */
@@ -2501,6 +2505,7 @@ struct tg3 {
struct tg3_hw_status *hw_status;
dma_addr_t status_mapping;
u32 last_tag;
+ u32 last_irq_tag;
u32 msg_enable;
@@ -2635,6 +2640,7 @@ struct tg3 {
#define TG3_FLG3_CLKREQ_BUG 0x00000800
#define TG3_FLG3_PHY_ENABLE_APD 0x00001000
#define TG3_FLG3_5755_PLUS 0x00002000
+#define TG3_FLG3_NO_NVRAM 0x00004000
struct timer_list timer;
u16 timer_counter;
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index f9491bd787d1..32256179a205 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -1099,7 +1099,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
struct pci_dev *pdev = NULL;
int i, status=0;
- gendev->driver_data = dev;
+ dev_set_drvdata(gendev, dev);
/* Ensure we're not sleeping */
if (lp->bus == EISA) {
@@ -2094,7 +2094,7 @@ static int __devexit de4x5_eisa_remove (struct device *device)
struct net_device *dev;
u_long iobase;
- dev = device->driver_data;
+ dev = dev_get_drvdata(device);
iobase = dev->base_addr;
unregister_netdev (dev);
@@ -2338,7 +2338,7 @@ static void __devexit de4x5_pci_remove (struct pci_dev *pdev)
struct net_device *dev;
u_long iobase;
- dev = pdev->dev.driver_data;
+ dev = dev_get_drvdata(&pdev->dev);
iobase = dev->base_addr;
unregister_netdev (dev);
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 264e61404f34..842b1a2c40d4 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -1601,8 +1601,7 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state)
/* no more hardware accesses behind this line. */
- BUG_ON(np->csr6);
- if (ioread32(ioaddr + IntrEnable)) BUG();
+ BUG_ON(np->csr6 || ioread32(ioaddr + IntrEnable));
/* pci_power_off(pdev, -1); */
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 735bf41c654a..94622e5fb936 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -540,31 +540,34 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
/* Get packet from user space buffer */
static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
- struct iovec *iv, size_t count,
+ const struct iovec *iv, size_t count,
int noblock)
{
struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
struct sk_buff *skb;
size_t len = count, align = 0;
struct virtio_net_hdr gso = { 0 };
+ int offset = 0;
if (!(tun->flags & TUN_NO_PI)) {
if ((len -= sizeof(pi)) > count)
return -EINVAL;
- if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
+ if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
return -EFAULT;
+ offset += sizeof(pi);
}
if (tun->flags & TUN_VNET_HDR) {
if ((len -= sizeof(gso)) > count)
return -EINVAL;
- if (memcpy_fromiovec((void *)&gso, iv, sizeof(gso)))
+ if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
return -EFAULT;
if (gso.hdr_len > len)
return -EINVAL;
+ offset += sizeof(pi);
}
if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
@@ -581,7 +584,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
return PTR_ERR(skb);
}
- if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
+ if (skb_copy_datagram_from_iovec(skb, 0, iv, offset, len)) {
tun->dev->stats.rx_dropped++;
kfree_skb(skb);
return -EFAULT;
@@ -673,7 +676,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
- result = tun_get_user(tun, (struct iovec *)iv, iov_length(iv, count),
+ result = tun_get_user(tun, iv, iov_length(iv, count),
file->f_flags & O_NONBLOCK);
tun_put(tun);
@@ -683,7 +686,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
/* Put packet to the user space buffer */
static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
struct sk_buff *skb,
- struct iovec *iv, int len)
+ const struct iovec *iv, int len)
{
struct tun_pi pi = { 0, skb->protocol };
ssize_t total = 0;
@@ -697,7 +700,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
pi.flags |= TUN_PKT_STRIP;
}
- if (memcpy_toiovec(iv, (void *) &pi, sizeof(pi)))
+ if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi)))
return -EFAULT;
total += sizeof(pi);
}
@@ -730,14 +733,15 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
gso.csum_offset = skb->csum_offset;
} /* else everything is zero */
- if (unlikely(memcpy_toiovec(iv, (void *)&gso, sizeof(gso))))
+ if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
+ sizeof(gso))))
return -EFAULT;
total += sizeof(gso);
}
len = min_t(int, skb->len, len);
- skb_copy_datagram_iovec(skb, 0, iv, len);
+ skb_copy_datagram_const_iovec(skb, 0, iv, total, len);
total += len;
tun->dev->stats.tx_packets++;
@@ -792,7 +796,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
}
netif_wake_queue(tun->dev);
- ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
+ ret = tun_put_user(tun, skb, iv, len);
kfree_skb(skb);
break;
}
@@ -870,6 +874,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
dev = __dev_get_by_name(net, ifr->ifr_name);
if (dev) {
+ if (ifr->ifr_flags & IFF_TUN_EXCL)
+ return -EBUSY;
if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops)
tun = netdev_priv(dev);
else if ((ifr->ifr_flags & IFF_TAP) && dev->netdev_ops == &tap_netdev_ops)
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 44f8392da117..33d4e4c0e8f2 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -27,6 +27,7 @@
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/workqueue.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <asm/uaccess.h>
@@ -270,7 +271,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
u8 num_entries,
u32 thread_size,
u32 thread_alignment,
- enum qe_risc_allocation risc,
+ unsigned int risc,
int skip_page_for_first_entry)
{
u32 init_enet_offset;
@@ -307,7 +308,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
static int return_init_enet_entries(struct ucc_geth_private *ugeth,
u32 *p_start,
u8 num_entries,
- enum qe_risc_allocation risc,
+ unsigned int risc,
int skip_page_for_first_entry)
{
u32 init_enet_offset;
@@ -342,7 +343,7 @@ static int dump_init_enet_entries(struct ucc_geth_private *ugeth,
u32 __iomem *p_start,
u8 num_entries,
u32 thread_size,
- enum qe_risc_allocation risc,
+ unsigned int risc,
int skip_page_for_first_entry)
{
u32 init_enet_offset;
@@ -1543,12 +1544,14 @@ static int init_phy(struct net_device *dev)
priv->oldspeed = 0;
priv->oldduplex = -1;
- phydev = phy_connect(dev, ug_info->phy_bus_id, &adjust_link, 0,
- priv->phy_interface);
+ if (!ug_info->phy_node)
+ return 0;
- if (IS_ERR(phydev)) {
+ phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0,
+ priv->phy_interface);
+ if (!phydev) {
printk("%s: Could not attach to PHY\n", dev->name);
- return PTR_ERR(phydev);
+ return -ENODEV;
}
phydev->supported &= (ADVERTISED_10baseT_Half |
@@ -2135,6 +2138,14 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
return -ENOMEM;
}
+ /* read the number of risc engines, update the riscTx and riscRx
+ * if there are 4 riscs in QE
+ */
+ if (qe_get_num_of_risc() == 4) {
+ ug_info->riscTx = QE_RISC_ALLOCATION_FOUR_RISCS;
+ ug_info->riscRx = QE_RISC_ALLOCATION_FOUR_RISCS;
+ }
+
ugeth->ug_regs = ioremap(uf_info->regs, sizeof(*ugeth->ug_regs));
if (!ugeth->ug_regs) {
if (netif_msg_probe(ugeth))
@@ -3217,7 +3228,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
dev->stats.tx_packets++;
/* Free the sk buffer associated with this TxBD */
- dev_kfree_skb_irq(ugeth->
+ dev_kfree_skb(ugeth->
tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]);
ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
ugeth->skb_dirtytx[txQ] =
@@ -3251,9 +3262,15 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
for (i = 0; i < ug_info->numQueuesRx; i++)
howmany += ucc_geth_rx(ugeth, i, budget - howmany);
+ /* Tx event processing */
+ spin_lock(&ugeth->lock);
+ for (i = 0; i < ug_info->numQueuesTx; i++)
+ ucc_geth_tx(ugeth->ndev, i);
+ spin_unlock(&ugeth->lock);
+
if (howmany < budget) {
napi_complete(napi);
- setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS);
+ setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS);
}
return howmany;
@@ -3267,8 +3284,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
struct ucc_geth_info *ug_info;
register u32 ucce;
register u32 uccm;
- register u32 tx_mask;
- u8 i;
ugeth_vdbg("%s: IN", __func__);
@@ -3282,27 +3297,14 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
out_be32(uccf->p_ucce, ucce);
/* check for receive events that require processing */
- if (ucce & UCCE_RX_EVENTS) {
+ if (ucce & (UCCE_RX_EVENTS | UCCE_TX_EVENTS)) {
if (napi_schedule_prep(&ugeth->napi)) {
- uccm &= ~UCCE_RX_EVENTS;
+ uccm &= ~(UCCE_RX_EVENTS | UCCE_TX_EVENTS);
out_be32(uccf->p_uccm, uccm);
__napi_schedule(&ugeth->napi);
}
}
- /* Tx event processing */
- if (ucce & UCCE_TX_EVENTS) {
- spin_lock(&ugeth->lock);
- tx_mask = UCC_GETH_UCCE_TXB0;
- for (i = 0; i < ug_info->numQueuesTx; i++) {
- if (ucce & tx_mask)
- ucc_geth_tx(dev, i);
- ucce &= ~tx_mask;
- tx_mask <<= 1;
- }
- spin_unlock(&ugeth->lock);
- }
-
/* Errors and other events */
if (ucce & UCCE_OTHER) {
if (ucce & UCC_GETH_UCCE_BSY)
@@ -3520,14 +3522,12 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
{
struct device *device = &ofdev->dev;
struct device_node *np = ofdev->node;
- struct device_node *mdio;
struct net_device *dev = NULL;
struct ucc_geth_private *ugeth = NULL;
struct ucc_geth_info *ug_info;
struct resource res;
struct device_node *phy;
int err, ucc_num, max_speed = 0;
- const phandle *ph;
const u32 *fixed_link;
const unsigned int *prop;
const char *sprop;
@@ -3627,40 +3627,13 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
fixed_link = of_get_property(np, "fixed-link", NULL);
if (fixed_link) {
- snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
- PHY_ID_FMT, "0", fixed_link[0]);
phy = NULL;
} else {
- char bus_name[MII_BUS_ID_SIZE];
-
- ph = of_get_property(np, "phy-handle", NULL);
- phy = of_find_node_by_phandle(*ph);
-
+ phy = of_parse_phandle(np, "phy-handle", 0);
if (phy == NULL)
return -ENODEV;
-
- /* set the PHY address */
- prop = of_get_property(phy, "reg", NULL);
- if (prop == NULL)
- return -1;
-
- /* Set the bus id */
- mdio = of_get_parent(phy);
-
- if (mdio == NULL)
- return -ENODEV;
-
- err = of_address_to_resource(mdio, 0, &res);
-
- if (err) {
- of_node_put(mdio);
- return err;
- }
- fsl_pq_mdio_bus_name(bus_name, mdio);
- of_node_put(mdio);
- snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
- "%s:%02x", bus_name, *prop);
}
+ ug_info->phy_node = phy;
/* get the phy interface type, or default to MII */
prop = of_get_property(np, "phy-connection-type", NULL);
@@ -3702,7 +3675,15 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT;
ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT;
ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4;
- ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
+
+ /* If QE's snum number is 46 which means we need to support
+ * 4 UECs at 1000Base-T simultaneously, we need to allocate
+ * more Threads to Rx.
+ */
+ if (qe_get_num_of_snums() == 46)
+ ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_6;
+ else
+ ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
}
if (netif_msg_probe(&debug))
@@ -3735,7 +3716,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
dev->netdev_ops = &ucc_geth_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work);
- netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
+ netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64);
dev->mtu = 1500;
ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 2f8ee7c87efe..816027656c06 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -852,7 +852,6 @@ struct ucc_geth_hardware_statistics {
/* Driver definitions */
#define TX_BD_RING_LEN 0x10
#define RX_BD_RING_LEN 0x10
-#define UCC_GETH_DEV_WEIGHT TX_BD_RING_LEN
#define TX_RING_MOD_MASK(size) (size-1)
#define RX_RING_MOD_MASK(size) (size-1)
@@ -1100,7 +1099,7 @@ struct ucc_geth_info {
u32 eventRegMask;
u16 pausePeriod;
u16 extensionField;
- char phy_bus_id[BUS_ID_SIZE];
+ struct device_node *phy_node;
u8 weightfactor[NUM_TX_QUEUES];
u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES];
u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX];
@@ -1120,8 +1119,8 @@ struct ucc_geth_info {
enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc;
enum ucc_geth_num_of_threads numThreadsTx;
enum ucc_geth_num_of_threads numThreadsRx;
- enum qe_risc_allocation riscTx;
- enum qe_risc_allocation riscRx;
+ unsigned int riscTx;
+ unsigned int riscRx;
};
/* structure representing UCC GETH */
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index dfc6cf765fbd..3717569828bf 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -359,4 +359,12 @@ config USB_HSO
To compile this driver as a module, choose M here: the
module will be called hso.
+config USB_NET_INT51X1
+ tristate "Intellon PLC based usb adapter"
+ depends on USB_USBNET
+ help
+ Choose this option if you're using a 14Mb USB-based PLC
+ (Powerline Communications) solution with an Intellon
+ INT51x1/INT5200 chip, like the "devolo dLan duo".
+
endmenu
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index c8aef62cf2b7..b870b0b1cbe0 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -20,4 +20,5 @@ obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o
obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
obj-$(CONFIG_USB_USBNET) += usbnet.o
+obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 55e8ecc3a9e5..01fd528306ec 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <linux/ctype.h>
#include <linux/ethtool.h>
#include <linux/workqueue.h>
#include <linux/mii.h>
@@ -389,36 +388,6 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
}
}
-static u8 nibble(unsigned char c)
-{
- if (likely(isdigit(c)))
- return c - '0';
- c = toupper(c);
- if (likely(isxdigit(c)))
- return 10 + c - 'A';
- return 0;
-}
-
-static inline int
-get_ethernet_addr(struct usbnet *dev, struct usb_cdc_ether_desc *e)
-{
- int tmp, i;
- unsigned char buf [13];
-
- tmp = usb_string(dev->udev, e->iMACAddress, buf, sizeof buf);
- if (tmp != 12) {
- dev_dbg(&dev->udev->dev,
- "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
- if (tmp >= 0)
- tmp = -EINVAL;
- return tmp;
- }
- for (i = tmp = 0; i < 6; i++, tmp += 2)
- dev->net->dev_addr [i] =
- (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
- return 0;
-}
-
static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
{
int status;
@@ -428,7 +397,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
if (status < 0)
return status;
- status = get_ethernet_addr(dev, info->ether);
+ status = usbnet_get_ethernet_addr(dev, info->ether->iMACAddress);
if (status < 0) {
usb_set_intfdata(info->data, NULL);
usb_driver_release_interface(driver_of(intf), info->data);
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index f84b78d94c40..837135f0390a 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -482,7 +482,7 @@ static ssize_t hso_sysfs_show_porttype(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct hso_device *hso_dev = dev->driver_data;
+ struct hso_device *hso_dev = dev_get_drvdata(dev);
char *port_name;
if (!hso_dev)
@@ -2313,7 +2313,7 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
serial->parent->dev = tty_register_device(tty_drv, minor,
&serial->parent->interface->dev);
dev = serial->parent->dev;
- dev->driver_data = serial->parent;
+ dev_set_drvdata(dev, serial->parent);
i = device_create_file(dev, &dev_attr_hsotype);
/* fill in specific data for later use */
@@ -2484,7 +2484,7 @@ static int add_net_device(struct hso_device *hso_dev)
static int hso_radio_toggle(void *data, enum rfkill_state state)
{
struct hso_device *hso_dev = data;
- int enabled = (state == RFKILL_STATE_ON);
+ int enabled = (state == RFKILL_STATE_UNBLOCKED);
int rv;
mutex_lock(&hso_dev->mutex);
@@ -2522,7 +2522,7 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
snprintf(rfkn, 20, "hso-%d",
interface->altsetting->desc.bInterfaceNumber);
hso_net->rfkill->name = rfkn;
- hso_net->rfkill->state = RFKILL_STATE_ON;
+ hso_net->rfkill->state = RFKILL_STATE_UNBLOCKED;
hso_net->rfkill->data = hso_dev;
hso_net->rfkill->toggle_radio = hso_radio_toggle;
if (rfkill_register(hso_net->rfkill) < 0) {
diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c
new file mode 100644
index 000000000000..55cf7081de10
--- /dev/null
+++ b/drivers/net/usb/int51x1.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2009 Peter Holik
+ *
+ * Intellon usb PLC (Powerline Communications) usb net driver
+ *
+ * http://www.tandel.be/downloads/INT51X1_Datasheet.pdf
+ *
+ * Based on the work of Jan 'RedBully' Seiffert
+ */
+
+/*
+ * 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/ctype.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/usbnet.h>
+
+#define INT51X1_VENDOR_ID 0x09e1
+#define INT51X1_PRODUCT_ID 0x5121
+
+#define INT51X1_HEADER_SIZE 2 /* 2 byte header */
+
+#define PACKET_TYPE_PROMISCUOUS (1 << 0)
+#define PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */
+#define PACKET_TYPE_DIRECTED (1 << 2)
+#define PACKET_TYPE_BROADCAST (1 << 3)
+#define PACKET_TYPE_MULTICAST (1 << 4) /* filtered */
+
+#define SET_ETHERNET_PACKET_FILTER 0x43
+
+static int int51x1_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ int len;
+
+ if (!(pskb_may_pull(skb, INT51X1_HEADER_SIZE))) {
+ deverr(dev, "unexpected tiny rx frame");
+ return 0;
+ }
+
+ len = le16_to_cpu(*(__le16 *)&skb->data[skb->len - 2]);
+
+ skb_trim(skb, len);
+
+ return 1;
+}
+
+static struct sk_buff *int51x1_tx_fixup(struct usbnet *dev,
+ struct sk_buff *skb, gfp_t flags)
+{
+ int pack_len = skb->len;
+ int pack_with_header_len = pack_len + INT51X1_HEADER_SIZE;
+ int headroom = skb_headroom(skb);
+ int tailroom = skb_tailroom(skb);
+ int need_tail = 0;
+ __le16 *len;
+
+ /* if packet and our header is smaler than 64 pad to 64 (+ ZLP) */
+ if ((pack_with_header_len) < dev->maxpacket)
+ need_tail = dev->maxpacket - pack_with_header_len + 1;
+ /*
+ * usbnet would send a ZLP if packetlength mod urbsize == 0 for us,
+ * but we need to know ourself, because this would add to the length
+ * we send down to the device...
+ */
+ else if (!(pack_with_header_len % dev->maxpacket))
+ need_tail = 1;
+
+ if (!skb_cloned(skb) &&
+ (headroom + tailroom >= need_tail + INT51X1_HEADER_SIZE)) {
+ if (headroom < INT51X1_HEADER_SIZE || tailroom < need_tail) {
+ skb->data = memmove(skb->head + INT51X1_HEADER_SIZE,
+ skb->data, skb->len);
+ skb_set_tail_pointer(skb, skb->len);
+ }
+ } else {
+ struct sk_buff *skb2;
+
+ skb2 = skb_copy_expand(skb,
+ INT51X1_HEADER_SIZE,
+ need_tail,
+ flags);
+ dev_kfree_skb_any(skb);
+ if (!skb2)
+ return NULL;
+ skb = skb2;
+ }
+
+ pack_len += need_tail;
+ pack_len &= 0x07ff;
+
+ len = (__le16 *) __skb_push(skb, INT51X1_HEADER_SIZE);
+ *len = cpu_to_le16(pack_len);
+
+ if(need_tail)
+ memset(__skb_put(skb, need_tail), 0, need_tail);
+
+ return skb;
+}
+
+static void int51x1_async_cmd_callback(struct urb *urb)
+{
+ struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+ int status = urb->status;
+
+ if (status < 0)
+ dev_warn(&urb->dev->dev, "async callback failed with %d\n", status);
+
+ kfree(req);
+ usb_free_urb(urb);
+}
+
+static void int51x1_set_multicast(struct net_device *netdev)
+{
+ struct usb_ctrlrequest *req;
+ int status;
+ struct urb *urb;
+ struct usbnet *dev = netdev_priv(netdev);
+ u16 filter = PACKET_TYPE_DIRECTED | PACKET_TYPE_BROADCAST;
+
+ if (netdev->flags & IFF_PROMISC) {
+ /* do not expect to see traffic of other PLCs */
+ filter |= PACKET_TYPE_PROMISCUOUS;
+ devinfo(dev, "promiscuous mode enabled");
+ } else if (netdev->mc_count ||
+ (netdev->flags & IFF_ALLMULTI)) {
+ filter |= PACKET_TYPE_ALL_MULTICAST;
+ devdbg(dev, "receive all multicast enabled");
+ } else {
+ /* ~PROMISCUOUS, ~MULTICAST */
+ devdbg(dev, "receive own packets only");
+ }
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ devwarn(dev, "Error allocating URB");
+ return;
+ }
+
+ req = kmalloc(sizeof(*req), GFP_ATOMIC);
+ if (!req) {
+ devwarn(dev, "Error allocating control msg");
+ goto out;
+ }
+
+ req->bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+ req->bRequest = SET_ETHERNET_PACKET_FILTER;
+ req->wValue = cpu_to_le16(filter);
+ req->wIndex = 0;
+ req->wLength = 0;
+
+ usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0),
+ (void *)req, NULL, 0,
+ int51x1_async_cmd_callback,
+ (void *)req);
+
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status < 0) {
+ devwarn(dev, "Error submitting control msg, sts=%d", status);
+ goto out1;
+ }
+ return;
+out1:
+ kfree(req);
+out:
+ usb_free_urb(urb);
+}
+
+static const struct net_device_ops int51x1_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = usbnet_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = int51x1_set_multicast,
+};
+
+static int int51x1_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int status = usbnet_get_ethernet_addr(dev, 3);
+
+ if (status)
+ return status;
+
+ dev->net->hard_header_len += INT51X1_HEADER_SIZE;
+ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+ dev->net->netdev_ops = &int51x1_netdev_ops;
+
+ return usbnet_get_endpoints(dev, intf);
+}
+
+static const struct driver_info int51x1_info = {
+ .description = "Intellon usb powerline adapter",
+ .bind = int51x1_bind,
+ .rx_fixup = int51x1_rx_fixup,
+ .tx_fixup = int51x1_tx_fixup,
+ .in = 1,
+ .out = 2,
+ .flags = FLAG_ETHER,
+};
+
+static const struct usb_device_id products[] = {
+ {
+ USB_DEVICE(INT51X1_VENDOR_ID, INT51X1_PRODUCT_ID),
+ .driver_info = (unsigned long) &int51x1_info,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver int51x1_driver = {
+ .name = "int51x1",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init int51x1_init(void)
+{
+ return usb_register(&int51x1_driver);
+}
+module_init(int51x1_init);
+
+static void __exit int51x1_exit(void)
+{
+ usb_deregister(&int51x1_driver);
+}
+module_exit(int51x1_exit);
+
+MODULE_AUTHOR("Peter Holik");
+MODULE_DESCRIPTION("Intellon usb powerline adapter");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index 3d0d0b0b37c5..e01314789718 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -31,7 +31,6 @@
****************************************************************/
/* TODO:
- * Fix in_interrupt() problem
* Develop test procedures for USB net interfaces
* Run test procedures
* Fix bugs from previous two steps
@@ -606,14 +605,30 @@ static void kaweth_usb_receive(struct urb *urb)
struct sk_buff *skb;
- if(unlikely(status == -ECONNRESET || status == -ESHUTDOWN))
- /* we are killed - set a flag and wake the disconnect handler */
- {
+ if (unlikely(status == -EPIPE)) {
+ kaweth->stats.rx_errors++;
kaweth->end = 1;
wake_up(&kaweth->term_wait);
+ dbg("Status was -EPIPE.");
return;
}
-
+ if (unlikely(status == -ECONNRESET || status == -ESHUTDOWN)) {
+ /* we are killed - set a flag and wake the disconnect handler */
+ kaweth->end = 1;
+ wake_up(&kaweth->term_wait);
+ dbg("Status was -ECONNRESET or -ESHUTDOWN.");
+ return;
+ }
+ if (unlikely(status == -EPROTO || status == -ETIME ||
+ status == -EILSEQ)) {
+ kaweth->stats.rx_errors++;
+ dbg("Status was -EPROTO, -ETIME, or -EILSEQ.");
+ return;
+ }
+ if (unlikely(status == -EOVERFLOW)) {
+ kaweth->stats.rx_errors++;
+ dbg("Status was -EOVERFLOW.");
+ }
spin_lock(&kaweth->device_lock);
if (IS_BLOCKED(kaweth->status)) {
spin_unlock(&kaweth->device_lock);
@@ -883,13 +898,16 @@ static void kaweth_set_rx_mode(struct net_device *net)
****************************************************************/
static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth)
{
+ int result;
__u16 packet_filter_bitmap = kaweth->packet_filter_bitmap;
+
kaweth->packet_filter_bitmap = 0;
if (packet_filter_bitmap == 0)
return;
- {
- int result;
+ if (in_interrupt())
+ return;
+
result = kaweth_control(kaweth,
usb_sndctrlpipe(kaweth->dev, 0),
KAWETH_COMMAND_SET_PACKET_FILTER,
@@ -906,7 +924,6 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth)
else {
dbg("Set Rx mode to %d", packet_filter_bitmap);
}
- }
}
/****************************************************************
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index f3a2fce6166c..c94de6243140 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -37,6 +37,7 @@
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/ctype.h>
#include <linux/ethtool.h>
#include <linux/workqueue.h>
#include <linux/mii.h>
@@ -156,6 +157,36 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
}
EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
+static u8 nibble(unsigned char c)
+{
+ if (likely(isdigit(c)))
+ return c - '0';
+ c = toupper(c);
+ if (likely(isxdigit(c)))
+ return 10 + c - 'A';
+ return 0;
+}
+
+int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress)
+{
+ int tmp, i;
+ unsigned char buf [13];
+
+ tmp = usb_string(dev->udev, iMACAddress, buf, sizeof buf);
+ if (tmp != 12) {
+ dev_dbg(&dev->udev->dev,
+ "bad MAC string %d fetch, %d\n", iMACAddress, tmp);
+ if (tmp >= 0)
+ tmp = -EINVAL;
+ return tmp;
+ }
+ for (i = tmp = 0; i < 6; i++, tmp += 2)
+ dev->net->dev_addr [i] =
+ (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr);
+
static void intr_complete (struct urb *urb);
static int init_status (struct usbnet *dev, struct usb_interface *intf)
@@ -1185,12 +1216,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
#endif
net->netdev_ops = &usbnet_netdev_ops;
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
- net->hard_start_xmit = usbnet_start_xmit;
- net->open = usbnet_open;
- net->stop = usbnet_stop;
- net->tx_timeout = usbnet_tx_timeout;
-#endif
net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
net->ethtool_ops = &usbnet_ethtool_ops;
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 4d1d47953fc6..6cc5bcd34fb0 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -622,12 +622,9 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
unsigned int tmp;
int i;
- if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
- BUG(); /* Caller should know better */
- return false;
- }
-
- BUG_ON(out + in > VIRTNET_SEND_COMMAND_SG_MAX);
+ /* Caller should know better */
+ BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ||
+ (out + in > VIRTNET_SEND_COMMAND_SG_MAX));
out++; /* Add header */
in++; /* Add return status */
@@ -642,8 +639,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
sg_set_buf(&sg[i + 1], sg_virt(s), s->length);
sg_set_buf(&sg[out + in - 1], &status, sizeof(status));
- if (vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) != 0)
- BUG();
+ BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi));
vi->cvq->vq_ops->kick(vi->cvq);
diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c
index 7be0ae10d69b..506625b180ac 100644
--- a/drivers/net/vxge/vxge-traffic.c
+++ b/drivers/net/vxge/vxge-traffic.c
@@ -1923,7 +1923,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process(
if (vpath == NULL) {
alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
alarm_event);
- goto out;
+ goto out2;
}
hldev = vpath->hldev;
@@ -2161,7 +2161,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process(
}
out:
hldev->stats.sw_dev_err_stats.vpath_alarms++;
-
+out2:
if ((alarm_event == VXGE_HW_EVENT_ALARM_CLEARED) ||
(alarm_event == VXGE_HW_EVENT_UNKNOWN))
return VXGE_HW_OK;
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index 3bf7d3f447db..765a7f5d6aa4 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -1249,7 +1249,7 @@ static int __devinit hss_init_one(struct platform_device *pdev)
return -ENOMEM;
if ((port->npe = npe_request(0)) == NULL) {
- err = -ENOSYS;
+ err = -ENODEV;
goto err_free;
}
@@ -1311,7 +1311,7 @@ static int __init hss_init_module(void)
if ((ixp4xx_read_feature_bits() &
(IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) !=
(IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS))
- return -ENOSYS;
+ return -ENODEV;
spin_lock_init(&npe_lock);
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index c23fde0c0344..79dabc557bd3 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -225,6 +225,7 @@ static char rcsid[] =
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/spinlock.h>
#include <linux/if.h>
#include <net/arp.h>
@@ -3246,6 +3247,16 @@ static inline void show_version(void)
rcsvers, rcsdate, __DATE__, __TIME__);
} /* show_version */
+static const struct net_device_ops cpc_netdev_ops = {
+ .ndo_open = cpc_open,
+ .ndo_stop = cpc_close,
+ .ndo_tx_timeout = cpc_tx_timeout,
+ .ndo_set_mac_address = NULL,
+ .ndo_change_mtu = cpc_change_mtu,
+ .ndo_do_ioctl = cpc_ioctl,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static void cpc_init_card(pc300_t * card)
{
int i, devcount = 0;
@@ -3357,18 +3368,11 @@ static void cpc_init_card(pc300_t * card)
dev->mem_start = card->hw.ramphys;
dev->mem_end = card->hw.ramphys + card->hw.ramsize - 1;
dev->irq = card->hw.irq;
- dev->init = NULL;
dev->tx_queue_len = PC300_TX_QUEUE_LEN;
dev->mtu = PC300_DEF_MTU;
- dev->open = cpc_open;
- dev->stop = cpc_close;
- dev->tx_timeout = cpc_tx_timeout;
+ dev->netdev_ops = &cpc_netdev_ops;
dev->watchdog_timeo = PC300_TX_TIMEOUT;
- dev->set_multicast_list = NULL;
- dev->set_mac_address = NULL;
- dev->change_mtu = cpc_change_mtu;
- dev->do_ioctl = cpc_ioctl;
if (register_hdlc_device(dev) == 0) {
printk("%s: Cyclades-PC300/", dev->name);
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 8a0823588c51..91be3e7bf133 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -146,10 +146,10 @@ config LIBERTAS_CS
A driver for Marvell Libertas 8385 CompactFlash devices.
config LIBERTAS_SDIO
- tristate "Marvell Libertas 8385 and 8686 SDIO 802.11b/g cards"
+ tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
depends on LIBERTAS && MMC
---help---
- A driver for Marvell Libertas 8385 and 8686 SDIO devices.
+ A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
config LIBERTAS_SPI
tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
@@ -337,6 +337,7 @@ config USB_NET_RNDIS_WLAN
select USB_NET_CDCETHER
select USB_NET_RNDIS_HOST
select WIRELESS_EXT
+ select CFG80211
---help---
This is a driver for wireless RNDIS devices.
These are USB based adapters found in devices such as:
@@ -433,6 +434,13 @@ config RTL8187
Thanks to Realtek for their support!
+# If possible, automatically enable LEDs for RTL8187.
+
+config RTL8187_LEDS
+ bool
+ depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
+ default y
+
config ADM8211
tristate "ADMtek ADM8211 support"
depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
@@ -483,9 +491,7 @@ config MWL8K
will be called mwl8k. If unsure, say N.
source "drivers/net/wireless/p54/Kconfig"
-source "drivers/net/wireless/ath5k/Kconfig"
-source "drivers/net/wireless/ath9k/Kconfig"
-source "drivers/net/wireless/ar9170/Kconfig"
+source "drivers/net/wireless/ath/Kconfig"
source "drivers/net/wireless/ipw2x00/Kconfig"
source "drivers/net/wireless/iwlwifi/Kconfig"
source "drivers/net/wireless/hostap/Kconfig"
@@ -494,5 +500,6 @@ source "drivers/net/wireless/b43legacy/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
source "drivers/net/wireless/rt2x00/Kconfig"
source "drivers/net/wireless/orinoco/Kconfig"
+source "drivers/net/wireless/wl12xx/Kconfig"
endmenu
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 50e7fba7f0ea..f2b1861e6bcb 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -55,8 +55,8 @@ obj-$(CONFIG_RT2X00) += rt2x00/
obj-$(CONFIG_P54_COMMON) += p54/
-obj-$(CONFIG_ATH5K) += ath5k/
-obj-$(CONFIG_ATH9K) += ath9k/
-obj-$(CONFIG_AR9170_USB) += ar9170/
+obj-$(CONFIG_ATH_COMMON) += ath/
obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
+
+obj-$(CONFIG_WL12XX) += wl12xx/
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index f71821795018..2b9e379994a1 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1311,18 +1311,20 @@ static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
return 0;
}
-static int adm8211_config_interface(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
+static void adm8211_bss_info_changed(struct ieee80211_hw *dev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf,
+ u32 changes)
{
struct adm8211_priv *priv = dev->priv;
+ if (!(changes & BSS_CHANGED_BSSID))
+ return;
+
if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
adm8211_set_bssid(dev, conf->bssid);
memcpy(priv->bssid, conf->bssid, ETH_ALEN);
}
-
- return 0;
}
static void adm8211_configure_filter(struct ieee80211_hw *dev,
@@ -1753,7 +1755,7 @@ static const struct ieee80211_ops adm8211_ops = {
.add_interface = adm8211_add_interface,
.remove_interface = adm8211_remove_interface,
.config = adm8211_config,
- .config_interface = adm8211_config_interface,
+ .bss_info_changed = adm8211_bss_info_changed,
.configure_filter = adm8211_configure_filter,
.get_stats = adm8211_get_stats,
.get_tx_stats = adm8211_get_tx_stats,
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index c36d3a3d655f..d73475739127 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -6501,7 +6501,10 @@ static int airo_get_encode(struct net_device *dev,
/* Copy the key to the user buffer */
dwrq->length = get_wep_key(local, index, &buf[0], sizeof(buf));
- memcpy(extra, buf, dwrq->length);
+ if (dwrq->length != -1)
+ memcpy(extra, buf, dwrq->length);
+ else
+ dwrq->length = 0;
return 0;
}
@@ -6659,7 +6662,10 @@ static int airo_get_encodeext(struct net_device *dev,
/* Copy the key to the user buffer */
ext->key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
- memcpy(extra, buf, ext->key_len);
+ if (ext->key_len != -1)
+ memcpy(extra, buf, ext->key_len);
+ else
+ ext->key_len = 0;
return 0;
}
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 744f4f4dd3d1..cea7f1466c54 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1965,13 +1965,18 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed)
return 0;
}
-static int at76_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
+static void at76_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf,
+ u32 changed)
{
struct at76_priv *priv = hw->priv;
at76_dbg(DBG_MAC80211, "%s():", __func__);
+
+ if (!(changed & BSS_CHANGED_BSSID))
+ return;
+
at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
mutex_lock(&priv->mtx);
@@ -1983,8 +1988,6 @@ static int at76_config_interface(struct ieee80211_hw *hw,
at76_join(priv);
mutex_unlock(&priv->mtx);
-
- return 0;
}
/* must be atomic */
@@ -2076,7 +2079,7 @@ static const struct ieee80211_ops at76_ops = {
.add_interface = at76_add_interface,
.remove_interface = at76_remove_interface,
.config = at76_config,
- .config_interface = at76_config_interface,
+ .bss_info_changed = at76_bss_info_changed,
.configure_filter = at76_configure_filter,
.start = at76_mac80211_start,
.stop = at76_mac80211_stop,
@@ -2250,6 +2253,7 @@ static int at76_init_new_device(struct at76_priv *priv,
/* mac80211 initialisation */
priv->hw->wiphy->max_scan_ssids = 1;
+ priv->hw->wiphy->max_scan_ie_len = 0;
priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band;
priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
@@ -2311,8 +2315,7 @@ static void at76_delete_device(struct at76_priv *priv)
del_timer_sync(&ledtrig_tx_timer);
- if (priv->rx_skb)
- kfree_skb(priv->rx_skb);
+ kfree_skb(priv->rx_skb);
usb_put_dev(priv->udev);
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
new file mode 100644
index 000000000000..d26e7b485315
--- /dev/null
+++ b/drivers/net/wireless/ath/Kconfig
@@ -0,0 +1,8 @@
+config ATH_COMMON
+ tristate "Atheros Wireless Cards"
+ depends on ATH5K || ATH9K || AR9170_USB
+
+source "drivers/net/wireless/ath/ath5k/Kconfig"
+source "drivers/net/wireless/ath/ath9k/Kconfig"
+source "drivers/net/wireless/ath/ar9170/Kconfig"
+
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
new file mode 100644
index 000000000000..4bb0132ada37
--- /dev/null
+++ b/drivers/net/wireless/ath/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_ATH5K) += ath5k/
+obj-$(CONFIG_ATH9K) += ath9k/
+obj-$(CONFIG_AR9170_USB) += ar9170/
+
+obj-$(CONFIG_ATH_COMMON) += ath.o
+ath-objs := main.o regd.o
diff --git a/drivers/net/wireless/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig
index de4281fda129..b99e3263ee6d 100644
--- a/drivers/net/wireless/ar9170/Kconfig
+++ b/drivers/net/wireless/ath/ar9170/Kconfig
@@ -2,6 +2,7 @@ config AR9170_USB
tristate "Atheros AR9170 802.11n USB support"
depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
select FW_LOADER
+ select ATH_COMMON
help
This is a driver for the Atheros "otus" 802.11n USB devices.
diff --git a/drivers/net/wireless/ar9170/Makefile b/drivers/net/wireless/ath/ar9170/Makefile
index 8d91c7ee3215..8d91c7ee3215 100644
--- a/drivers/net/wireless/ar9170/Makefile
+++ b/drivers/net/wireless/ath/ar9170/Makefile
diff --git a/drivers/net/wireless/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index f4fb2e94aea0..17bd3eaf3e03 100644
--- a/drivers/net/wireless/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -40,7 +40,7 @@
#include <linux/completion.h>
#include <linux/spinlock.h>
-#include <net/wireless.h>
+#include <net/cfg80211.h>
#include <net/mac80211.h>
#ifdef CONFIG_AR9170_LEDS
#include <linux/leds.h>
@@ -48,6 +48,8 @@
#include "eeprom.h"
#include "hw.h"
+#include "../regd.h"
+
#define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1)
enum ar9170_bw {
@@ -58,6 +60,21 @@ enum ar9170_bw {
__AR9170_NUM_BW,
};
+static inline enum ar9170_bw nl80211_to_ar9170(enum nl80211_channel_type type)
+{
+ switch (type) {
+ case NL80211_CHAN_NO_HT:
+ case NL80211_CHAN_HT20:
+ return AR9170_BW_20;
+ case NL80211_CHAN_HT40MINUS:
+ return AR9170_BW_40_BELOW;
+ case NL80211_CHAN_HT40PLUS:
+ return AR9170_BW_40_ABOVE;
+ default:
+ BUG();
+ }
+}
+
enum ar9170_rf_init_mode {
AR9170_RFI_NONE,
AR9170_RFI_WARM,
@@ -87,10 +104,16 @@ enum ar9170_device_state {
AR9170_ASSOCIATED,
};
+struct ar9170_rxstream_mpdu_merge {
+ struct ar9170_rx_head plcp;
+ bool has_plcp;
+};
+
struct ar9170 {
struct ieee80211_hw *hw;
struct mutex mutex;
enum ar9170_device_state state;
+ unsigned long bad_hw_nagger;
int (*open)(struct ar9170 *);
void (*stop)(struct ar9170 *);
@@ -118,6 +141,7 @@ struct ar9170 {
u64 cur_mc_hash, want_mc_hash;
u32 cur_filter, want_filter;
unsigned int filter_changed;
+ unsigned int filter_state;
bool sniffer_enabled;
/* PHY */
@@ -151,11 +175,17 @@ struct ar9170 {
/* EEPROM */
struct ar9170_eeprom eeprom;
+ struct ath_regulatory regulatory;
/* global tx status for unregistered Stations. */
struct sk_buff_head global_tx_status;
struct sk_buff_head global_tx_status_waste;
struct delayed_work tx_status_janitor;
+
+ /* rxstream mpdu merge */
+ struct ar9170_rxstream_mpdu_merge rx_mpdu;
+ struct sk_buff *rx_failover;
+ int rx_failover_missing;
};
struct ar9170_sta_info {
diff --git a/drivers/net/wireless/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c
index f57a6200167b..f57a6200167b 100644
--- a/drivers/net/wireless/ar9170/cmd.c
+++ b/drivers/net/wireless/ath/ar9170/cmd.c
diff --git a/drivers/net/wireless/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h
index a4f0e50e52b4..a4f0e50e52b4 100644
--- a/drivers/net/wireless/ar9170/cmd.h
+++ b/drivers/net/wireless/ath/ar9170/cmd.h
diff --git a/drivers/net/wireless/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h
index d2c8cc83f1dd..d2c8cc83f1dd 100644
--- a/drivers/net/wireless/ar9170/eeprom.h
+++ b/drivers/net/wireless/ath/ar9170/eeprom.h
diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
index 53e250a4278f..3293e0fb24fb 100644
--- a/drivers/net/wireless/ar9170/hw.h
+++ b/drivers/net/wireless/ath/ar9170/hw.h
@@ -207,6 +207,8 @@ enum ar9170_cmd {
#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44)
#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48)
+#define AR9170_MAC_REG_AMPDU_SET (AR9170_MAC_REG_BASE + 0xba0)
+
#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00)
#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50)
@@ -312,7 +314,7 @@ struct ar9170_rx_head {
u8 plcp[12];
} __packed;
-struct ar9170_rx_tail {
+struct ar9170_rx_phystatus {
union {
struct {
u8 rssi_ant0, rssi_ant1, rssi_ant2,
@@ -324,6 +326,9 @@ struct ar9170_rx_tail {
u8 evm_stream0[6], evm_stream1[6];
u8 phy_err;
+} __packed;
+
+struct ar9170_rx_macstatus {
u8 SAidx, DAidx;
u8 error;
u8 status;
@@ -339,7 +344,7 @@ struct ar9170_rx_tail {
#define AR9170_RX_ENC_SOFTWARE 0x8
-static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
+static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
{
return (t->SAidx & 0xc0) >> 4 |
(t->DAidx & 0xc0) >> 6;
@@ -357,10 +362,9 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
#define AR9170_RX_STATUS_MPDU_MASK 0x30
#define AR9170_RX_STATUS_MPDU_SINGLE 0x00
-#define AR9170_RX_STATUS_MPDU_FIRST 0x10
-#define AR9170_RX_STATUS_MPDU_MIDDLE 0x20
-#define AR9170_RX_STATUS_MPDU_LAST 0x30
-
+#define AR9170_RX_STATUS_MPDU_FIRST 0x20
+#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30
+#define AR9170_RX_STATUS_MPDU_LAST 0x10
#define AR9170_RX_ERROR_RXTO 0x01
#define AR9170_RX_ERROR_OVERRUN 0x02
@@ -369,6 +373,7 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
#define AR9170_RX_ERROR_WRONG_RA 0x10
#define AR9170_RX_ERROR_PLCP 0x20
#define AR9170_RX_ERROR_MMIC 0x40
+#define AR9170_RX_ERROR_FATAL 0x80
struct ar9170_cmd_tx_status {
__le16 unkn;
diff --git a/drivers/net/wireless/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
index 341cead7f606..341cead7f606 100644
--- a/drivers/net/wireless/ar9170/led.c
+++ b/drivers/net/wireless/ath/ar9170/led.c
diff --git a/drivers/net/wireless/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
index c8fa3073169f..43aeb69685d3 100644
--- a/drivers/net/wireless/ar9170/mac.c
+++ b/drivers/net/wireless/ath/ar9170/mac.c
@@ -72,6 +72,24 @@ int ar9170_set_qos(struct ar9170 *ar)
return ar9170_regwrite_result();
}
+static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity)
+{
+ u32 val;
+
+ /* don't allow AMPDU density > 8us */
+ if (mpdudensity > 6)
+ return -EINVAL;
+
+ /* Watch out! Otus uses slightly different density values. */
+ val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0);
+
+ ar9170_regwrite_begin(ar);
+ ar9170_regwrite(AR9170_MAC_REG_AMPDU_SET, val);
+ ar9170_regwrite_finish();
+
+ return ar9170_regwrite_result();
+}
+
int ar9170_init_mac(struct ar9170 *ar)
{
ar9170_regwrite_begin(ar);
@@ -265,9 +283,9 @@ int ar9170_set_operating_mode(struct ar9170 *ar)
case NL80211_IFTYPE_ADHOC:
pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
break;
-/* case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_AP:
pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
- break;*/
+ break;
case NL80211_IFTYPE_WDS:
pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
break;
@@ -296,6 +314,11 @@ int ar9170_set_operating_mode(struct ar9170 *ar)
if (err)
return err;
+ /* set AMPDU density to 8us. */
+ err = ar9170_set_ampdu_density(ar, 6);
+ if (err)
+ return err;
+
ar9170_regwrite_begin(ar);
ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
@@ -316,9 +339,9 @@ int ar9170_set_beacon_timers(struct ar9170 *ar)
u32 v = 0;
u32 pretbtt = 0;
- v |= ar->hw->conf.beacon_int;
-
if (ar->vif) {
+ v |= ar->vif->bss_conf.beacon_int;
+
switch (ar->vif->type) {
case NL80211_IFTYPE_MESH_POINT:
case NL80211_IFTYPE_ADHOC:
@@ -326,7 +349,7 @@ int ar9170_set_beacon_timers(struct ar9170 *ar)
break;
case NL80211_IFTYPE_AP:
v |= BIT(24);
- pretbtt = (ar->hw->conf.beacon_int - 6) << 16;
+ pretbtt = (ar->vif->bss_conf.beacon_int - 6) << 16;
break;
default:
break;
diff --git a/drivers/net/wireless/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 5996ff9f7f47..4ef1d2fc859c 100644
--- a/drivers/net/wireless/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -142,11 +142,36 @@ static struct ieee80211_channel ar9170_5ghz_chantable[] = {
};
#undef CHAN
+#define AR9170_HT_CAP \
+{ \
+ .ht_supported = true, \
+ .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
+ IEEE80211_HT_CAP_SM_PS | \
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
+ IEEE80211_HT_CAP_SGI_40 | \
+ IEEE80211_HT_CAP_DSSSCCK40 | \
+ IEEE80211_HT_CAP_SM_PS, \
+ .ampdu_factor = 3, \
+ .ampdu_density = 6, \
+ .mcs = { \
+ .rx_mask = { 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, }, \
+ }, \
+}
+
static struct ieee80211_supported_band ar9170_band_2GHz = {
.channels = ar9170_2ghz_chantable,
.n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
.bitrates = ar9170_g_ratetable,
.n_bitrates = ar9170_g_ratetable_size,
+ .ht_cap = AR9170_HT_CAP,
+};
+
+static struct ieee80211_supported_band ar9170_band_5GHz = {
+ .channels = ar9170_5ghz_chantable,
+ .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
+ .bitrates = ar9170_a_ratetable,
+ .n_bitrates = ar9170_a_ratetable_size,
+ .ht_cap = AR9170_HT_CAP,
};
#ifdef AR9170_QUEUE_DEBUG
@@ -190,13 +215,6 @@ static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar,
}
#endif /* AR9170_QUEUE_DEBUG */
-static struct ieee80211_supported_band ar9170_band_5GHz = {
- .channels = ar9170_5ghz_chantable,
- .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
- .bitrates = ar9170_a_ratetable,
- .n_bitrates = ar9170_a_ratetable_size,
-};
-
void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
bool valid_status, u16 tx_status)
{
@@ -436,214 +454,430 @@ static void ar9170_handle_command_response(struct ar9170 *ar,
}
}
-/*
- * If the frame alignment is right (or the kernel has
- * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
- * is only a single MPDU in the USB frame, then we can
- * submit to mac80211 the SKB directly. However, since
- * there may be multiple packets in one SKB in stream
- * mode, and we need to observe the proper ordering,
- * this is non-trivial.
- */
-static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
+static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
{
- struct sk_buff *skb;
- struct ar9170_rx_head *head = (void *)buf;
- struct ar9170_rx_tail *tail;
- struct ieee80211_rx_status status;
- int mpdu_len, i;
- u8 error, antennas = 0, decrypt;
- __le16 fc;
- int reserved;
+ memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
+ ar->rx_mpdu.has_plcp = false;
+}
- if (unlikely(!IS_STARTED(ar)))
- return ;
+static int ar9170_nag_limiter(struct ar9170 *ar)
+{
+ bool print_message;
+
+ /*
+ * we expect all sorts of errors in promiscuous mode.
+ * don't bother with it, it's OK!
+ */
+ if (ar->sniffer_enabled)
+ return false;
+
+ /*
+ * only go for frequent errors! The hardware tends to
+ * do some stupid thing once in a while under load, in
+ * noisy environments or just for fun!
+ */
+ if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
+ print_message = true;
+ else
+ print_message = false;
+
+ /* reset threshold for "once in a while" */
+ ar->bad_hw_nagger = jiffies + HZ / 4;
+ return print_message;
+}
+
+static int ar9170_rx_mac_status(struct ar9170 *ar,
+ struct ar9170_rx_head *head,
+ struct ar9170_rx_macstatus *mac,
+ struct ieee80211_rx_status *status)
+{
+ u8 error, decrypt;
- /* Received MPDU */
- mpdu_len = len;
- mpdu_len -= sizeof(struct ar9170_rx_head);
- mpdu_len -= sizeof(struct ar9170_rx_tail);
BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
- BUILD_BUG_ON(sizeof(struct ar9170_rx_tail) != 24);
+ BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
- if (mpdu_len <= FCS_LEN)
- return;
+ error = mac->error;
+ if (error & AR9170_RX_ERROR_MMIC) {
+ status->flag |= RX_FLAG_MMIC_ERROR;
+ error &= ~AR9170_RX_ERROR_MMIC;
+ }
- tail = (void *)(buf + sizeof(struct ar9170_rx_head) + mpdu_len);
+ if (error & AR9170_RX_ERROR_PLCP) {
+ status->flag |= RX_FLAG_FAILED_PLCP_CRC;
+ error &= ~AR9170_RX_ERROR_PLCP;
- for (i = 0; i < 3; i++)
- if (tail->rssi[i] != 0x80)
- antennas |= BIT(i);
+ if (!(ar->filter_state & FIF_PLCPFAIL))
+ return -EINVAL;
+ }
- /* post-process RSSI */
- for (i = 0; i < 7; i++)
- if (tail->rssi[i] & 0x80)
- tail->rssi[i] = ((tail->rssi[i] & 0x7f) + 1) & 0x7f;
+ if (error & AR9170_RX_ERROR_FCS) {
+ status->flag |= RX_FLAG_FAILED_FCS_CRC;
+ error &= ~AR9170_RX_ERROR_FCS;
- memset(&status, 0, sizeof(status));
+ if (!(ar->filter_state & FIF_FCSFAIL))
+ return -EINVAL;
+ }
+
+ decrypt = ar9170_get_decrypt_type(mac);
+ if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
+ decrypt != AR9170_ENC_ALG_NONE)
+ status->flag |= RX_FLAG_DECRYPTED;
+
+ /* ignore wrong RA errors */
+ error &= ~AR9170_RX_ERROR_WRONG_RA;
+
+ if (error & AR9170_RX_ERROR_DECRYPT) {
+ error &= ~AR9170_RX_ERROR_DECRYPT;
+ /*
+ * Rx decryption is done in place,
+ * the original data is lost anyway.
+ */
+
+ return -EINVAL;
+ }
- status.band = ar->channel->band;
- status.freq = ar->channel->center_freq;
- status.signal = ar->noise[0] + tail->rssi_combined;
- status.noise = ar->noise[0];
- status.antenna = antennas;
+ /* drop any other error frames */
+ if (unlikely(error)) {
+ /* TODO: update netdevice's RX dropped/errors statistics */
+
+ if (ar9170_nag_limiter(ar))
+ printk(KERN_DEBUG "%s: received frame with "
+ "suspicious error code (%#x).\n",
+ wiphy_name(ar->hw->wiphy), error);
+
+ return -EINVAL;
+ }
- switch (tail->status & AR9170_RX_STATUS_MODULATION_MASK) {
+ status->band = ar->channel->band;
+ status->freq = ar->channel->center_freq;
+
+ switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
case AR9170_RX_STATUS_MODULATION_CCK:
- if (tail->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
- status.flag |= RX_FLAG_SHORTPRE;
+ if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
+ status->flag |= RX_FLAG_SHORTPRE;
switch (head->plcp[0]) {
case 0x0a:
- status.rate_idx = 0;
+ status->rate_idx = 0;
break;
case 0x14:
- status.rate_idx = 1;
+ status->rate_idx = 1;
break;
case 0x37:
- status.rate_idx = 2;
+ status->rate_idx = 2;
break;
case 0x6e:
- status.rate_idx = 3;
+ status->rate_idx = 3;
break;
default:
- if ((!ar->sniffer_enabled) && (net_ratelimit()))
+ if (ar9170_nag_limiter(ar))
printk(KERN_ERR "%s: invalid plcp cck rate "
"(%x).\n", wiphy_name(ar->hw->wiphy),
head->plcp[0]);
- return;
+ return -EINVAL;
}
break;
+
case AR9170_RX_STATUS_MODULATION_OFDM:
- switch (head->plcp[0] & 0xF) {
- case 0xB:
- status.rate_idx = 0;
+ switch (head->plcp[0] & 0xf) {
+ case 0xb:
+ status->rate_idx = 0;
break;
- case 0xF:
- status.rate_idx = 1;
+ case 0xf:
+ status->rate_idx = 1;
break;
- case 0xA:
- status.rate_idx = 2;
+ case 0xa:
+ status->rate_idx = 2;
break;
- case 0xE:
- status.rate_idx = 3;
+ case 0xe:
+ status->rate_idx = 3;
break;
case 0x9:
- status.rate_idx = 4;
+ status->rate_idx = 4;
break;
- case 0xD:
- status.rate_idx = 5;
+ case 0xd:
+ status->rate_idx = 5;
break;
case 0x8:
- status.rate_idx = 6;
+ status->rate_idx = 6;
break;
- case 0xC:
- status.rate_idx = 7;
+ case 0xc:
+ status->rate_idx = 7;
break;
default:
- if ((!ar->sniffer_enabled) && (net_ratelimit()))
+ if (ar9170_nag_limiter(ar))
printk(KERN_ERR "%s: invalid plcp ofdm rate "
"(%x).\n", wiphy_name(ar->hw->wiphy),
head->plcp[0]);
- return;
+ return -EINVAL;
}
- if (status.band == IEEE80211_BAND_2GHZ)
- status.rate_idx += 4;
+ if (status->band == IEEE80211_BAND_2GHZ)
+ status->rate_idx += 4;
break;
+
case AR9170_RX_STATUS_MODULATION_HT:
+ if (head->plcp[3] & 0x80)
+ status->flag |= RX_FLAG_40MHZ;
+ if (head->plcp[6] & 0x80)
+ status->flag |= RX_FLAG_SHORT_GI;
+
+ status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
+ status->flag |= RX_FLAG_HT;
+ break;
+
case AR9170_RX_STATUS_MODULATION_DUPOFDM:
/* XXX */
-
- if (net_ratelimit())
+ if (ar9170_nag_limiter(ar))
printk(KERN_ERR "%s: invalid modulation\n",
wiphy_name(ar->hw->wiphy));
- return;
+ return -EINVAL;
}
- error = tail->error;
+ return 0;
+}
- if (error & AR9170_RX_ERROR_MMIC) {
- status.flag |= RX_FLAG_MMIC_ERROR;
- error &= ~AR9170_RX_ERROR_MMIC;
- }
+static void ar9170_rx_phy_status(struct ar9170 *ar,
+ struct ar9170_rx_phystatus *phy,
+ struct ieee80211_rx_status *status)
+{
+ int i;
- if (error & AR9170_RX_ERROR_PLCP) {
- status.flag |= RX_FLAG_FAILED_PLCP_CRC;
- error &= ~AR9170_RX_ERROR_PLCP;
+ BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
+
+ for (i = 0; i < 3; i++)
+ if (phy->rssi[i] != 0x80)
+ status->antenna |= BIT(i);
+
+ /* post-process RSSI */
+ for (i = 0; i < 7; i++)
+ if (phy->rssi[i] & 0x80)
+ phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
+
+ /* TODO: we could do something with phy_errors */
+ status->signal = ar->noise[0] + phy->rssi_combined;
+ status->noise = ar->noise[0];
+}
+
+static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
+{
+ struct sk_buff *skb;
+ int reserved = 0;
+ struct ieee80211_hdr *hdr = (void *) buf;
+
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
+ reserved += NET_IP_ALIGN;
+
+ if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
+ reserved += NET_IP_ALIGN;
}
- if (error & AR9170_RX_ERROR_FCS) {
- status.flag |= RX_FLAG_FAILED_FCS_CRC;
- error &= ~AR9170_RX_ERROR_FCS;
+ if (ieee80211_has_a4(hdr->frame_control))
+ reserved += NET_IP_ALIGN;
+
+ reserved = 32 + (reserved & NET_IP_ALIGN);
+
+ skb = dev_alloc_skb(len + reserved);
+ if (likely(skb)) {
+ skb_reserve(skb, reserved);
+ memcpy(skb_put(skb, len), buf, len);
}
- decrypt = ar9170_get_decrypt_type(tail);
- if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
- decrypt != AR9170_ENC_ALG_NONE)
- status.flag |= RX_FLAG_DECRYPTED;
+ return skb;
+}
- /* ignore wrong RA errors */
- error &= ~AR9170_RX_ERROR_WRONG_RA;
+/*
+ * If the frame alignment is right (or the kernel has
+ * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
+ * is only a single MPDU in the USB frame, then we could
+ * submit to mac80211 the SKB directly. However, since
+ * there may be multiple packets in one SKB in stream
+ * mode, and we need to observe the proper ordering,
+ * this is non-trivial.
+ */
- if (error & AR9170_RX_ERROR_DECRYPT) {
- error &= ~AR9170_RX_ERROR_DECRYPT;
+static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
+{
+ struct ar9170_rx_head *head;
+ struct ar9170_rx_macstatus *mac;
+ struct ar9170_rx_phystatus *phy = NULL;
+ struct ieee80211_rx_status status;
+ struct sk_buff *skb;
+ int mpdu_len;
+
+ if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
+ return ;
+
+ /* Received MPDU */
+ mpdu_len = len - sizeof(*mac);
+
+ mac = (void *)(buf + mpdu_len);
+ if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
+ /* this frame is too damaged and can't be used - drop it */
- /*
- * Rx decryption is done in place,
- * the original data is lost anyway.
- */
return ;
}
- /* drop any other error frames */
- if ((error) && (net_ratelimit())) {
- printk(KERN_DEBUG "%s: errors: %#x\n",
- wiphy_name(ar->hw->wiphy), error);
- return;
+ switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
+ case AR9170_RX_STATUS_MPDU_FIRST:
+ /* first mpdu packet has the plcp header */
+ if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
+ head = (void *) buf;
+ memcpy(&ar->rx_mpdu.plcp, (void *) buf,
+ sizeof(struct ar9170_rx_head));
+
+ mpdu_len -= sizeof(struct ar9170_rx_head);
+ buf += sizeof(struct ar9170_rx_head);
+ ar->rx_mpdu.has_plcp = true;
+ } else {
+ if (ar9170_nag_limiter(ar))
+ printk(KERN_ERR "%s: plcp info is clipped.\n",
+ wiphy_name(ar->hw->wiphy));
+ return ;
+ }
+ break;
+
+ case AR9170_RX_STATUS_MPDU_LAST:
+ /* last mpdu has a extra tail with phy status information */
+
+ if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
+ mpdu_len -= sizeof(struct ar9170_rx_phystatus);
+ phy = (void *)(buf + mpdu_len);
+ } else {
+ if (ar9170_nag_limiter(ar))
+ printk(KERN_ERR "%s: frame tail is clipped.\n",
+ wiphy_name(ar->hw->wiphy));
+ return ;
+ }
+
+ case AR9170_RX_STATUS_MPDU_MIDDLE:
+ /* middle mpdus are just data */
+ if (unlikely(!ar->rx_mpdu.has_plcp)) {
+ if (!ar9170_nag_limiter(ar))
+ return ;
+
+ printk(KERN_ERR "%s: rx stream did not start "
+ "with a first_mpdu frame tag.\n",
+ wiphy_name(ar->hw->wiphy));
+
+ return ;
+ }
+
+ head = &ar->rx_mpdu.plcp;
+ break;
+
+ case AR9170_RX_STATUS_MPDU_SINGLE:
+ /* single mpdu - has plcp (head) and phy status (tail) */
+ head = (void *) buf;
+
+ mpdu_len -= sizeof(struct ar9170_rx_head);
+ mpdu_len -= sizeof(struct ar9170_rx_phystatus);
+
+ buf += sizeof(struct ar9170_rx_head);
+ phy = (void *)(buf + mpdu_len);
+ break;
+
+ default:
+ BUG_ON(1);
+ break;
}
- buf += sizeof(struct ar9170_rx_head);
- fc = *(__le16 *)buf;
+ if (unlikely(mpdu_len < FCS_LEN))
+ return ;
- if (ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc))
- reserved = 32 + 2;
- else
- reserved = 32;
+ memset(&status, 0, sizeof(status));
+ if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
+ return ;
- skb = dev_alloc_skb(mpdu_len + reserved);
- if (!skb)
- return;
+ if (phy)
+ ar9170_rx_phy_status(ar, phy, &status);
- skb_reserve(skb, reserved);
- memcpy(skb_put(skb, mpdu_len), buf, mpdu_len);
- ieee80211_rx_irqsafe(ar->hw, skb, &status);
+ skb = ar9170_rx_copy_data(buf, mpdu_len);
+ if (likely(skb))
+ ieee80211_rx_irqsafe(ar->hw, skb, &status);
}
void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
{
- unsigned int i, tlen, resplen;
+ unsigned int i, tlen, resplen, wlen = 0, clen = 0;
u8 *tbuf, *respbuf;
tbuf = skb->data;
tlen = skb->len;
while (tlen >= 4) {
- int clen = tbuf[1] << 8 | tbuf[0];
- int wlen = (clen + 3) & ~3;
+ clen = tbuf[1] << 8 | tbuf[0];
+ wlen = ALIGN(clen, 4);
- /*
- * parse stream (if any)
- */
+ /* check if this is stream has a valid tag.*/
if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
- printk(KERN_ERR "%s: missing tag!\n",
- wiphy_name(ar->hw->wiphy));
+ /*
+ * TODO: handle the highly unlikely event that the
+ * corrupted stream has the TAG at the right position.
+ */
+
+ /* check if the frame can be repaired. */
+ if (!ar->rx_failover_missing) {
+ /* this is no "short read". */
+ if (ar9170_nag_limiter(ar)) {
+ printk(KERN_ERR "%s: missing tag!\n",
+ wiphy_name(ar->hw->wiphy));
+ goto err_telluser;
+ } else
+ goto err_silent;
+ }
+
+ if (ar->rx_failover_missing > tlen) {
+ if (ar9170_nag_limiter(ar)) {
+ printk(KERN_ERR "%s: possible multi "
+ "stream corruption!\n",
+ wiphy_name(ar->hw->wiphy));
+ goto err_telluser;
+ } else
+ goto err_silent;
+ }
+
+ memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
+ ar->rx_failover_missing -= tlen;
+
+ if (ar->rx_failover_missing <= 0) {
+ /*
+ * nested ar9170_rx call!
+ * termination is guranteed, even when the
+ * combined frame also have a element with
+ * a bad tag.
+ */
+
+ ar->rx_failover_missing = 0;
+ ar9170_rx(ar, ar->rx_failover);
+
+ skb_reset_tail_pointer(ar->rx_failover);
+ skb_trim(ar->rx_failover, 0);
+ }
+
return ;
}
+
+ /* check if stream is clipped */
if (wlen > tlen - 4) {
- printk(KERN_ERR "%s: invalid RX (%d, %d, %d)\n",
- wiphy_name(ar->hw->wiphy), clen, wlen, tlen);
- print_hex_dump(KERN_DEBUG, "data: ",
- DUMP_PREFIX_OFFSET,
- 16, 1, tbuf, tlen, true);
+ if (ar->rx_failover_missing) {
+ /* TODO: handle double stream corruption. */
+ if (ar9170_nag_limiter(ar)) {
+ printk(KERN_ERR "%s: double rx stream "
+ "corruption!\n",
+ wiphy_name(ar->hw->wiphy));
+ goto err_telluser;
+ } else
+ goto err_silent;
+ }
+
+ /*
+ * save incomplete data set.
+ * the firmware will resend the missing bits when
+ * the rx - descriptor comes round again.
+ */
+
+ memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
+ ar->rx_failover_missing = clen - tlen;
return ;
}
resplen = clen;
@@ -668,12 +902,44 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
if (i == 12)
ar9170_handle_command_response(ar, respbuf, resplen);
else
- ar9170_handle_mpdu(ar, respbuf, resplen);
+ ar9170_handle_mpdu(ar, respbuf, clen);
}
- if (tlen)
- printk(KERN_ERR "%s: buffer remains!\n",
- wiphy_name(ar->hw->wiphy));
+ if (tlen) {
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: %d bytes of unprocessed "
+ "data left in rx stream!\n",
+ wiphy_name(ar->hw->wiphy), tlen);
+
+ goto err_telluser;
+ }
+
+ return ;
+
+err_telluser:
+ printk(KERN_ERR "%s: damaged RX stream data [want:%d, "
+ "data:%d, rx:%d, pending:%d ]\n",
+ wiphy_name(ar->hw->wiphy), clen, wlen, tlen,
+ ar->rx_failover_missing);
+
+ if (ar->rx_failover_missing)
+ print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
+ ar->rx_failover->data,
+ ar->rx_failover->len);
+
+ print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
+ skb->data, skb->len);
+
+ printk(KERN_ERR "%s: please check your hardware and cables, if "
+ "you see this message frequently.\n",
+ wiphy_name(ar->hw->wiphy));
+
+err_silent:
+ if (ar->rx_failover_missing) {
+ skb_reset_tail_pointer(ar->rx_failover);
+ skb_trim(ar->rx_failover, 0);
+ ar->rx_failover_missing = 0;
+ }
}
#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
@@ -703,6 +969,8 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
+ ar->bad_hw_nagger = jiffies;
+
err = ar->open(ar);
if (err)
goto out;
@@ -742,8 +1010,9 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
if (IS_STARTED(ar))
ar->state = AR9170_IDLE;
- mutex_lock(&ar->mutex);
+ flush_workqueue(ar->hw->workqueue);
+ mutex_lock(&ar->mutex);
cancel_delayed_work_sync(&ar->tx_status_janitor);
cancel_work_sync(&ar->filter_config_work);
cancel_work_sync(&ar->beacon_work);
@@ -1068,7 +1337,7 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
goto out;
}
- if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) {
+ if (changed & BSS_CHANGED_BEACON_INT) {
err = ar9170_set_beacon_timers(ar);
if (err)
goto out;
@@ -1076,7 +1345,8 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
err = ar9170_set_channel(ar, hw->conf.channel,
- AR9170_RFI_NONE, AR9170_BW_20);
+ AR9170_RFI_NONE,
+ nl80211_to_ar9170(hw->conf.channel_type));
if (err)
goto out;
/* adjust slot time for 5 GHz */
@@ -1090,43 +1360,16 @@ out:
return err;
}
-static int ar9170_op_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct ar9170 *ar = hw->priv;
- int err = 0;
-
- mutex_lock(&ar->mutex);
-
- if (conf->changed & IEEE80211_IFCC_BSSID) {
- memcpy(ar->bssid, conf->bssid, ETH_ALEN);
- err = ar9170_set_operating_mode(ar);
- }
-
- if (conf->changed & IEEE80211_IFCC_BEACON) {
- err = ar9170_update_beacon(ar);
-
- if (err)
- goto out;
- err = ar9170_set_beacon_timers(ar);
- }
-
-out:
- mutex_unlock(&ar->mutex);
- return err;
-}
-
static void ar9170_set_filters(struct work_struct *work)
{
struct ar9170 *ar = container_of(work, struct ar9170,
filter_config_work);
int err;
- mutex_lock(&ar->mutex);
if (unlikely(!IS_STARTED(ar)))
- goto unlock;
+ return ;
+ mutex_lock(&ar->mutex);
if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) {
err = ar9170_set_operating_mode(ar);
if (err)
@@ -1155,8 +1398,8 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
/* mask supported flags */
*new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
- FIF_PROMISC_IN_BSS;
-
+ FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
+ ar->filter_state = *new_flags;
/*
* We can support more by setting the sniffer bit and
* then checking the error flags, later.
@@ -1218,6 +1461,17 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
mutex_lock(&ar->mutex);
+ if (changed & BSS_CHANGED_BSSID) {
+ memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
+ err = ar9170_set_operating_mode(ar);
+ }
+
+ if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
+ err = ar9170_update_beacon(ar);
+ if (!err)
+ ar9170_set_beacon_timers(ar);
+ }
+
ar9170_regwrite_begin(ar);
if (changed & BSS_CHANGED_ASSOC) {
@@ -1229,6 +1483,9 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
#endif /* CONFIG_AR9170_LEDS */
}
+ if (changed & BSS_CHANGED_BEACON_INT)
+ err = ar9170_set_beacon_timers(ar);
+
if (changed & BSS_CHANGED_HT) {
/* TODO */
err = 0;
@@ -1498,6 +1755,24 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
return ret;
}
+static int ar9170_ampdu_action(struct ieee80211_hw *hw,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+{
+ switch (action) {
+ case IEEE80211_AMPDU_RX_START:
+ case IEEE80211_AMPDU_RX_STOP:
+ /*
+ * Something goes wrong -- RX locks up
+ * after a while of receiving aggregated
+ * frames -- not enabling for now.
+ */
+ return -EOPNOTSUPP;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static const struct ieee80211_ops ar9170_ops = {
.start = ar9170_op_start,
.stop = ar9170_op_stop,
@@ -1505,7 +1780,6 @@ static const struct ieee80211_ops ar9170_ops = {
.add_interface = ar9170_op_add_interface,
.remove_interface = ar9170_op_remove_interface,
.config = ar9170_op_config,
- .config_interface = ar9170_op_config_interface,
.configure_filter = ar9170_op_configure_filter,
.conf_tx = ar9170_conf_tx,
.bss_info_changed = ar9170_op_bss_info_changed,
@@ -1514,26 +1788,40 @@ static const struct ieee80211_ops ar9170_ops = {
.sta_notify = ar9170_sta_notify,
.get_stats = ar9170_get_stats,
.get_tx_stats = ar9170_get_tx_stats,
+ .ampdu_action = ar9170_ampdu_action,
};
void *ar9170_alloc(size_t priv_size)
{
struct ieee80211_hw *hw;
struct ar9170 *ar;
+ struct sk_buff *skb;
int i;
+ /*
+ * this buffer is used for rx stream reconstruction.
+ * Under heavy load this device (or the transport layer?)
+ * tends to split the streams into seperate rx descriptors.
+ */
+
+ skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
+ if (!skb)
+ goto err_nomem;
+
hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
if (!hw)
- return ERR_PTR(-ENOMEM);
+ goto err_nomem;
ar = hw->priv;
ar->hw = hw;
+ ar->rx_failover = skb;
mutex_init(&ar->mutex);
spin_lock_init(&ar->cmdlock);
spin_lock_init(&ar->tx_stats_lock);
skb_queue_head_init(&ar->global_tx_status);
skb_queue_head_init(&ar->global_tx_status_waste);
+ ar9170_rx_reset_rx_mpdu(ar);
INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor);
@@ -1561,6 +1849,10 @@ void *ar9170_alloc(size_t priv_size)
ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
return ar;
+
+err_nomem:
+ kfree_skb(skb);
+ return ERR_PTR(-ENOMEM);
}
static int ar9170_read_eeprom(struct ar9170 *ar)
@@ -1619,12 +1911,24 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
else
ar->hw->channel_change_time = 80 * 1000;
+ ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
+ ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
+
/* second part of wiphy init */
SET_IEEE80211_PERM_ADDR(ar->hw, addr);
return bands ? 0 : -EINVAL;
}
+static int ar9170_reg_notifier(struct wiphy *wiphy,
+ struct regulatory_request *request)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ar9170 *ar = hw->priv;
+
+ return ath_reg_notifier_apply(wiphy, request, &ar->regulatory);
+}
+
int ar9170_register(struct ar9170 *ar, struct device *pdev)
{
int err;
@@ -1634,10 +1938,18 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
if (err)
goto err_out;
+ err = ath_regd_init(&ar->regulatory, ar->hw->wiphy,
+ ar9170_reg_notifier);
+ if (err)
+ goto err_out;
+
err = ieee80211_register_hw(ar->hw);
if (err)
goto err_out;
+ if (!ath_is_world_regd(&ar->regulatory))
+ regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2);
+
err = ar9170_init_leds(ar);
if (err)
goto err_unreg;
@@ -1666,6 +1978,7 @@ void ar9170_unregister(struct ar9170 *ar)
ar9170_unregister_leds(ar);
#endif /* CONFIG_AR9170_LEDS */
+ kfree_skb(ar->rx_failover);
ieee80211_unregister_hw(ar->hw);
mutex_destroy(&ar->mutex);
}
diff --git a/drivers/net/wireless/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
index 6ce20754b8e7..6ce20754b8e7 100644
--- a/drivers/net/wireless/ar9170/phy.c
+++ b/drivers/net/wireless/ath/ar9170/phy.c
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index fddda477095c..d7c13c0177ca 100644
--- a/drivers/net/wireless/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -350,7 +350,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
goto err_unbuf;
}
- if (outlen >= 0 && aru->readlen != outlen) {
+ if (aru->readlen != outlen) {
err = -EMSGSIZE;
goto err_unbuf;
}
@@ -689,6 +689,9 @@ static int ar9170_usb_probe(struct usb_interface *intf,
aru->common.exec_cmd = ar9170_usb_exec_cmd;
aru->common.callback_cmd = ar9170_usb_callback_cmd;
+#ifdef CONFIG_PM
+ udev->reset_resume = 1;
+#endif
err = ar9170_usb_reset(aru);
if (err)
goto err_freehw;
@@ -805,6 +808,7 @@ static struct usb_driver ar9170_driver = {
#ifdef CONFIG_PM
.suspend = ar9170_suspend,
.resume = ar9170_resume,
+ .reset_resume = ar9170_resume,
#endif /* CONFIG_PM */
};
diff --git a/drivers/net/wireless/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h
index f5852924cd64..ac42586495d8 100644
--- a/drivers/net/wireless/ar9170/usb.h
+++ b/drivers/net/wireless/ath/ar9170/usb.h
@@ -43,7 +43,7 @@
#include <linux/completion.h>
#include <linux/spinlock.h>
#include <linux/leds.h>
-#include <net/wireless.h>
+#include <net/cfg80211.h>
#include <net/mac80211.h>
#include <linux/firmware.h>
#include "eeprom.h"
diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index 75383a5df992..509b6f94f73b 100644
--- a/drivers/net/wireless/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,6 +1,7 @@
config ATH5K
tristate "Atheros 5xxx wireless cards support"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+ select ATH_COMMON
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index 84a74c5248e5..84a74c5248e5 100644
--- a/drivers/net/wireless/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 0b616e72fe05..813718210338 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -27,6 +27,8 @@
#include <linux/types.h>
#include <net/mac80211.h>
+#include "../regd.h"
+
/* RX/TX descriptor hw structs
* TODO: Driver part should only see sw structs */
#include "desc.h"
@@ -207,7 +209,6 @@
#define AR5K_TUNE_MAX_TXPOWER 63
#define AR5K_TUNE_DEFAULT_TXPOWER 25
#define AR5K_TUNE_TPC_TXPOWER false
-#define AR5K_TUNE_ANT_DIVERSITY true
#define AR5K_TUNE_HWTXTRIES 4
#define AR5K_INIT_CARR_SENSE_EN 1
@@ -418,6 +419,17 @@ enum ath5k_driver_mode {
AR5K_MODE_MAX = 5
};
+enum ath5k_ant_mode {
+ AR5K_ANTMODE_DEFAULT = 0, /* default antenna setup */
+ AR5K_ANTMODE_FIXED_A = 1, /* only antenna A is present */
+ AR5K_ANTMODE_FIXED_B = 2, /* only antenna B is present */
+ AR5K_ANTMODE_SINGLE_AP = 3, /* sta locked on a single ap */
+ AR5K_ANTMODE_SECTOR_AP = 4, /* AP with tx antenna set on tx desc */
+ AR5K_ANTMODE_SECTOR_STA = 5, /* STA with tx antenna set on tx desc */
+ AR5K_ANTMODE_DEBUG = 6, /* Debug mode -A -> Rx, B-> Tx- */
+ AR5K_ANTMODE_MAX,
+};
+
/****************\
TX DEFINITIONS
@@ -1039,8 +1051,6 @@ struct ath5k_hw {
bool ah_5ghz;
bool ah_2ghz;
-#define ah_regdomain ah_capabilities.cap_regdomain.reg_current
-#define ah_regdomain_hw ah_capabilities.cap_regdomain.reg_hw
#define ah_modes ah_capabilities.cap_mode
#define ah_ee_version ah_capabilities.cap_eeprom.ee_version
@@ -1051,8 +1061,11 @@ struct ath5k_hw {
bool ah_software_retry;
u32 ah_limit_tx_retries;
- u32 ah_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
- bool ah_ant_diversity;
+ /* Antenna Control */
+ u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
+ u8 ah_ant_mode;
+ u8 ah_tx_ant;
+ u8 ah_def_ant;
u8 ah_sta_id[ETH_ALEN];
@@ -1065,6 +1078,7 @@ struct ath5k_hw {
u32 ah_gpio[AR5K_MAX_GPIO];
int ah_gpio_npins;
+ struct ath_regulatory ah_regulatory;
struct ath5k_capabilities ah_capabilities;
struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES];
@@ -1099,11 +1113,12 @@ struct ath5k_hw {
/* Values in 0.25dB units */
s16 txp_min_pwr;
s16 txp_max_pwr;
+ /* Values in 0.5dB units */
s16 txp_offset;
s16 txp_ofdm;
- /* Values in dB units */
- s16 txp_cck_ofdm_pwr_delta;
s16 txp_cck_ofdm_gainf_delta;
+ /* Value in dB units */
+ s16 txp_cck_ofdm_pwr_delta;
} ah_txpower;
struct {
@@ -1263,14 +1278,21 @@ extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *chann
/* PHY calibration */
extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
+/* Spur mitigation */
+bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel);
+void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel);
/* Misc PHY functions */
extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
-extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
-extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
+/* Antenna control */
+extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
+extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant);
+extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
/* TX power setup */
extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
-extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower);
+extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
/*
* Functions used internaly
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 70d376c63aac..c41ef58393e7 100644
--- a/drivers/net/wireless/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -133,7 +133,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
ah->ah_cw_min = AR5K_TUNE_CWMIN;
ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
ah->ah_software_retry = false;
- ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
/*
* Set the mac version based on the pci id
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index a08bc8a4fb69..dbfe9f45050e 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -61,9 +61,13 @@
static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+static int modparam_all_channels;
+module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
+MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
+
/******************\
* Internal defines *
@@ -214,7 +218,7 @@ static struct pci_driver ath5k_pci_driver = {
* Prototypes - MAC 802.11 stack related functions
*/
static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel);
+static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
static int ath5k_reset_wake(struct ath5k_softc *sc);
static int ath5k_start(struct ieee80211_hw *hw);
static void ath5k_stop(struct ieee80211_hw *hw);
@@ -223,9 +227,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
static void ath5k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf);
static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
-static int ath5k_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf);
static void ath5k_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *new_flags,
@@ -255,7 +256,6 @@ static const struct ieee80211_ops ath5k_hw_ops = {
.add_interface = ath5k_add_interface,
.remove_interface = ath5k_remove_interface,
.config = ath5k_config,
- .config_interface = ath5k_config_interface,
.configure_filter = ath5k_configure_filter,
.set_key = ath5k_set_key,
.get_stats = ath5k_get_stats,
@@ -516,6 +516,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
IEEE80211_HW_NOISE_DBM;
hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
@@ -705,6 +706,15 @@ err_no_irq:
* Driver Initialization *
\***********************/
+static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ath5k_softc *sc = hw->priv;
+ struct ath_regulatory *reg = &sc->ah->ah_regulatory;
+
+ return ath_reg_notifier_apply(wiphy, request, reg);
+}
+
static int
ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
{
@@ -793,12 +803,23 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
memset(sc->bssidmask, 0xff, ETH_ALEN);
ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
+ ah->ah_regulatory.current_rd =
+ ah->ah_capabilities.cap_eeprom.ee_regdomain;
+ ret = ath_regd_init(&ah->ah_regulatory, hw->wiphy, ath5k_reg_notifier);
+ if (ret) {
+ ATH5K_ERR(sc, "can't initialize regulatory system\n");
+ goto err_queues;
+ }
+
ret = ieee80211_register_hw(hw);
if (ret) {
ATH5K_ERR(sc, "can't register ieee80211 hw\n");
goto err_queues;
}
+ if (!ath_is_world_regd(&sc->ah->ah_regulatory))
+ regulatory_hint(hw->wiphy, sc->ah->ah_regulatory.alpha2);
+
ath5k_init_leds(sc);
return 0;
@@ -862,6 +883,20 @@ ath5k_ieee2mhz(short chan)
return 2212 + chan * 20;
}
+/*
+ * Returns true for the channel numbers used without all_channels modparam.
+ */
+static bool ath5k_is_standard_channel(short chan)
+{
+ return ((chan <= 14) ||
+ /* UNII 1,2 */
+ ((chan & 3) == 0 && chan >= 36 && chan <= 64) ||
+ /* midband */
+ ((chan & 3) == 0 && chan >= 100 && chan <= 140) ||
+ /* UNII-3 */
+ ((chan & 3) == 1 && chan >= 149 && chan <= 165));
+}
+
static unsigned int
ath5k_copy_channels(struct ath5k_hw *ah,
struct ieee80211_channel *channels,
@@ -899,6 +934,9 @@ ath5k_copy_channels(struct ath5k_hw *ah,
if (!ath5k_channel_ok(ah, freq, chfreq))
continue;
+ if (!modparam_all_channels && !ath5k_is_standard_channel(ch))
+ continue;
+
/* Write channel info and increment counter */
channels[count].center_freq = freq;
channels[count].band = (chfreq == CHANNEL_2GHZ) ?
@@ -1038,16 +1076,13 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
if (chan->center_freq != sc->curchan->center_freq ||
chan->hw_value != sc->curchan->hw_value) {
- sc->curchan = chan;
- sc->curband = &sc->sbands[chan->band];
-
/*
* To switch channels clear any pending DMA operations;
* wait long enough for the RX fifo to drain, reset the
* hardware at the new frequency, and then re-enable
* the relevant bits of the h/w.
*/
- return ath5k_reset(sc, true, true);
+ return ath5k_reset(sc, chan);
}
return 0;
@@ -1241,7 +1276,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
(sc->power_level * 2),
hw_rate,
- info->control.rates[0].count, keyidx, 0, flags,
+ info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
cts_rate, duration);
if (ret)
goto err_unmap;
@@ -1577,9 +1612,8 @@ ath5k_rx_start(struct ath5k_softc *sc)
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
sc->cachelsz, sc->rxbufsize);
- sc->rxlink = NULL;
-
spin_lock_bh(&sc->rxbuflock);
+ sc->rxlink = NULL;
list_for_each_entry(bf, &sc->rxbuf, list) {
ret = ath5k_rxbuf_setup(sc, bf);
if (ret != 0) {
@@ -1588,9 +1622,9 @@ ath5k_rx_start(struct ath5k_softc *sc)
}
}
bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
+ ath5k_hw_set_rxdp(ah, bf->daddr);
spin_unlock_bh(&sc->rxbuflock);
- ath5k_hw_set_rxdp(ah, bf->daddr);
ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */
ath5k_mode_setup(sc); /* set filters, etc. */
ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
@@ -1702,35 +1736,6 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
}
}
-static void ath5k_tasklet_beacon(unsigned long data)
-{
- struct ath5k_softc *sc = (struct ath5k_softc *) data;
-
- /*
- * Software beacon alert--time to send a beacon.
- *
- * In IBSS mode we use this interrupt just to
- * keep track of the next TBTT (target beacon
- * transmission time) in order to detect wether
- * automatic TSF updates happened.
- */
- if (sc->opmode == NL80211_IFTYPE_ADHOC) {
- /* XXX: only if VEOL suppported */
- u64 tsf = ath5k_hw_get_tsf64(sc->ah);
- sc->nexttbtt += sc->bintval;
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
- "SWBA nexttbtt: %x hw_tu: %x "
- "TSF: %llx\n",
- sc->nexttbtt,
- TSF_TO_TU(tsf),
- (unsigned long long) tsf);
- } else {
- spin_lock(&sc->block);
- ath5k_beacon_send(sc);
- spin_unlock(&sc->block);
- }
-}
-
static void
ath5k_tasklet_rx(unsigned long data)
{
@@ -1739,7 +1744,7 @@ ath5k_tasklet_rx(unsigned long data)
struct sk_buff *skb, *next_skb;
dma_addr_t next_skb_addr;
struct ath5k_softc *sc = (void *)data;
- struct ath5k_buf *bf, *bf_last;
+ struct ath5k_buf *bf;
struct ath5k_desc *ds;
int ret;
int hdrlen;
@@ -1750,7 +1755,6 @@ ath5k_tasklet_rx(unsigned long data)
ATH5K_WARN(sc, "empty rx buf pool\n");
goto unlock;
}
- bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list);
do {
rxs.flag = 0;
@@ -1759,24 +1763,9 @@ ath5k_tasklet_rx(unsigned long data)
skb = bf->skb;
ds = bf->desc;
- /*
- * last buffer must not be freed to ensure proper hardware
- * function. When the hardware finishes also a packet next to
- * it, we are sure, it doesn't use it anymore and we can go on.
- */
- if (bf_last == bf)
- bf->flags |= 1;
- if (bf->flags) {
- struct ath5k_buf *bf_next = list_entry(bf->list.next,
- struct ath5k_buf, list);
- ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc,
- &rs);
- if (ret)
- break;
- bf->flags &= ~1;
- /* skip the overwritten one (even status is martian) */
- goto next;
- }
+ /* bail if HW is still using self-linked descriptor */
+ if (ath5k_hw_get_rxdp(sc->ah) == bf->daddr)
+ break;
ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
if (unlikely(ret == -EINPROGRESS))
@@ -2017,7 +2006,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ath5k_hw *ah = sc->ah;
struct ath5k_desc *ds;
- int ret, antenna = 0;
+ int ret = 0;
+ u8 antenna;
u32 flags;
bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
@@ -2031,23 +2021,35 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
}
ds = bf->desc;
+ antenna = ah->ah_tx_ant;
flags = AR5K_TXDESC_NOACK;
if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
ds->ds_link = bf->daddr; /* self-linked */
flags |= AR5K_TXDESC_VEOL;
- /*
- * Let hardware handle antenna switching if txantenna is not set
- */
- } else {
+ } else
ds->ds_link = 0;
- /*
- * Switch antenna every 4 beacons if txantenna is not set
- * XXX assumes two antennas
- */
- if (antenna == 0)
- antenna = sc->bsent & 4 ? 2 : 1;
- }
+
+ /*
+ * If we use multiple antennas on AP and use
+ * the Sectored AP scenario, switch antenna every
+ * 4 beacons to make sure everybody hears our AP.
+ * When a client tries to associate, hw will keep
+ * track of the tx antenna to be used for this client
+ * automaticaly, based on ACKed packets.
+ *
+ * Note: AP still listens and transmits RTS on the
+ * default antenna which is supposed to be an omni.
+ *
+ * Note2: On sectored scenarios it's possible to have
+ * multiple antennas (1omni -the default- and 14 sectors)
+ * so if we choose to actually support this mode we need
+ * to allow user to set how many antennas we have and tweak
+ * the code below to send beacons on all of them.
+ */
+ if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
+ antenna = sc->bsent & 4 ? 2 : 1;
+
/* FIXME: If we are in g mode and rate is a CCK rate
* subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
@@ -2100,7 +2102,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
sc->bmisscount++;
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"missed %u consecutive beacons\n", sc->bmisscount);
- if (sc->bmisscount > 3) { /* NB: 3 is a guess */
+ if (sc->bmisscount > 10) { /* NB: 10 is a guess */
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"stuck beacon time (%u missed)\n",
sc->bmisscount);
@@ -2121,10 +2123,12 @@ ath5k_beacon_send(struct ath5k_softc *sc)
* are still pending on the queue.
*/
if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
- ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq);
+ ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq);
/* NB: hw still stops DMA, so proceed */
}
+ /* Note: Beacon buffer is updated on beacon_update when mac80211
+ * calls config_interface */
ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
ath5k_hw_start_tx_dma(ah, sc->bhalq);
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
@@ -2281,6 +2285,35 @@ ath5k_beacon_config(struct ath5k_softc *sc)
ath5k_hw_set_imr(ah, sc->imask);
}
+static void ath5k_tasklet_beacon(unsigned long data)
+{
+ struct ath5k_softc *sc = (struct ath5k_softc *) data;
+
+ /*
+ * Software beacon alert--time to send a beacon.
+ *
+ * In IBSS mode we use this interrupt just to
+ * keep track of the next TBTT (target beacon
+ * transmission time) in order to detect wether
+ * automatic TSF updates happened.
+ */
+ if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+ /* XXX: only if VEOL suppported */
+ u64 tsf = ath5k_hw_get_tsf64(sc->ah);
+ sc->nexttbtt += sc->bintval;
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+ "SWBA nexttbtt: %x hw_tu: %x "
+ "TSF: %llx\n",
+ sc->nexttbtt,
+ TSF_TO_TU(tsf),
+ (unsigned long long) tsf);
+ } else {
+ spin_lock(&sc->block);
+ ath5k_beacon_send(sc);
+ spin_unlock(&sc->block);
+ }
+}
+
/********************\
* Interrupt handling *
@@ -2314,7 +2347,7 @@ ath5k_init(struct ath5k_softc *sc)
sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
AR5K_INT_FATAL | AR5K_INT_GLOBAL;
- ret = ath5k_reset(sc, false, false);
+ ret = ath5k_reset(sc, NULL);
if (ret)
goto done;
@@ -2455,7 +2488,7 @@ ath5k_intr(int irq, void *dev_id)
tasklet_schedule(&sc->restq);
} else {
if (status & AR5K_INT_SWBA) {
- tasklet_schedule(&sc->beacontq);
+ tasklet_hi_schedule(&sc->beacontq);
}
if (status & AR5K_INT_RXEOL) {
/*
@@ -2485,7 +2518,7 @@ ath5k_intr(int irq, void *dev_id)
ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
}
}
- } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0);
+ } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
if (unlikely(!counter))
ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
@@ -2599,18 +2632,25 @@ drop_packet:
return NETDEV_TX_OK;
}
+/*
+ * Reset the hardware. If chan is not NULL, then also pause rx/tx
+ * and change to the given channel.
+ */
static int
-ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
+ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
{
struct ath5k_hw *ah = sc->ah;
int ret;
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
- if (stop) {
+ if (chan) {
ath5k_hw_set_imr(ah, 0);
ath5k_txq_cleanup(sc);
ath5k_rx_stop(sc);
+
+ sc->curchan = chan;
+ sc->curband = &sc->sbands[chan->band];
}
ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
if (ret) {
@@ -2648,7 +2688,7 @@ ath5k_reset_wake(struct ath5k_softc *sc)
{
int ret;
- ret = ath5k_reset(sc, true, true);
+ ret = ath5k_reset(sc, sc->curchan);
if (!ret)
ieee80211_wake_queues(sc->hw);
@@ -2727,56 +2767,47 @@ static int
ath5k_config(struct ieee80211_hw *hw, u32 changed)
{
struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
struct ieee80211_conf *conf = &hw->conf;
- int ret;
+ int ret = 0;
mutex_lock(&sc->lock);
sc->bintval = conf->beacon_int;
- sc->power_level = conf->power_level;
ret = ath5k_chan_set(sc, conf->channel);
+ if (ret < 0)
+ return ret;
- mutex_unlock(&sc->lock);
- return ret;
-}
-
-static int
-ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct ath5k_softc *sc = hw->priv;
- struct ath5k_hw *ah = sc->ah;
- int ret = 0;
+ if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
+ (sc->power_level != conf->power_level)) {
+ sc->power_level = conf->power_level;
- mutex_lock(&sc->lock);
- if (sc->vif != vif) {
- ret = -EIO;
- goto unlock;
- }
- if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
- /* Cache for later use during resets */
- memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
- /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
- * a clean way of letting us retrieve this yet. */
- ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
- mmiowb();
- }
- if (conf->changed & IEEE80211_IFCC_BEACON &&
- (vif->type == NL80211_IFTYPE_ADHOC ||
- vif->type == NL80211_IFTYPE_MESH_POINT ||
- vif->type == NL80211_IFTYPE_AP)) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
- if (!beacon) {
- ret = -ENOMEM;
- goto unlock;
- }
- ath5k_beacon_update(sc, beacon);
+ /* Half dB steps */
+ ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
}
-unlock:
+ /* TODO:
+ * 1) Move this on config_interface and handle each case
+ * separately eg. when we have only one STA vif, use
+ * AR5K_ANTMODE_SINGLE_AP
+ *
+ * 2) Allow the user to change antenna mode eg. when only
+ * one antenna is present
+ *
+ * 3) Allow the user to set default/tx antenna when possible
+ *
+ * 4) Default mode should handle 90% of the cases, together
+ * with fixed a/b and single AP modes we should be able to
+ * handle 99%. Sectored modes are extreme cases and i still
+ * haven't found a usage for them. If we decide to support them,
+ * then we must allow the user to set how many tx antennas we
+ * have available
+ */
+ ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
+
mutex_unlock(&sc->lock);
- return ret;
+ return 0;
}
#define SUPPORTED_FIF_FLAGS \
@@ -3059,11 +3090,40 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
u32 changes)
{
struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+
+ mutex_lock(&sc->lock);
+ if (WARN_ON(sc->vif != vif))
+ goto unlock;
+
+ if (changes & BSS_CHANGED_BSSID) {
+ /* Cache for later use during resets */
+ memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN);
+ /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
+ * a clean way of letting us retrieve this yet. */
+ ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+ mmiowb();
+ }
+
+ if (changes & BSS_CHANGED_BEACON_INT)
+ sc->bintval = bss_conf->beacon_int;
+
if (changes & BSS_CHANGED_ASSOC) {
- mutex_lock(&sc->lock);
sc->assoc = bss_conf->assoc;
if (sc->opmode == NL80211_IFTYPE_STATION)
set_beacon_filter(hw, sc->assoc);
- mutex_unlock(&sc->lock);
}
+
+ if (changes & BSS_CHANGED_BEACON &&
+ (vif->type == NL80211_IFTYPE_ADHOC ||
+ vif->type == NL80211_IFTYPE_MESH_POINT ||
+ vif->type == NL80211_IFTYPE_AP)) {
+ struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+
+ if (beacon)
+ ath5k_beacon_update(sc, beacon);
+ }
+
+ unlock:
+ mutex_unlock(&sc->lock);
}
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 822956114cd7..852b2c189fd8 100644
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -56,7 +56,6 @@
struct ath5k_buf {
struct list_head list;
- unsigned int flags; /* rx descriptor flags */
struct ath5k_desc *desc; /* virtual addr of desc */
dma_addr_t daddr; /* physical addr of desc */
struct sk_buff *skb; /* skbuff for buf */
diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index 367a6c7d3cc7..367a6c7d3cc7 100644
--- a/drivers/net/wireless/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 4904a07e4b59..4904a07e4b59 100644
--- a/drivers/net/wireless/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 66f69f04e55e..66f69f04e55e 100644
--- a/drivers/net/wireless/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index dc30a2b70a6b..dc30a2b70a6b 100644
--- a/drivers/net/wireless/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
diff --git a/drivers/net/wireless/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
index 56158c804e3e..56158c804e3e 100644
--- a/drivers/net/wireless/ath5k/desc.h
+++ b/drivers/net/wireless/ath/ath5k/desc.h
diff --git a/drivers/net/wireless/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index b65b4feb2d28..941b51130a6f 100644
--- a/drivers/net/wireless/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -80,8 +80,6 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
* ath5k_hw_get_rxdp - Get RX Descriptor's address
*
* @ah: The &struct ath5k_hw
- *
- * XXX: Is RXDP read and clear ?
*/
u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
{
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index c0fb3b09ba45..c56b494d417a 100644
--- a/drivers/net/wireless/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -156,6 +156,17 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
}
+ AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val);
+
+ if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val)
+ ee->ee_is_hb63 = true;
+ else
+ ee->ee_is_hb63 = false;
+
+ AR5K_EEPROM_READ(AR5K_EEPROM_RFKILL, val);
+ ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL);
+ ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false;
+
return 0;
}
@@ -197,16 +208,16 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
ee->ee_ant_control[mode][i++] = val & 0x3f;
- /* Get antenna modes */
- ah->ah_antenna[mode][0] =
+ /* Get antenna switch tables */
+ ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
(ee->ee_ant_control[mode][0] << 4);
- ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
+ ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
ee->ee_ant_control[mode][1] |
(ee->ee_ant_control[mode][2] << 6) |
(ee->ee_ant_control[mode][3] << 12) |
(ee->ee_ant_control[mode][4] << 18) |
(ee->ee_ant_control[mode][5] << 24);
- ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
+ ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
ee->ee_ant_control[mode][6] |
(ee->ee_ant_control[mode][7] << 6) |
(ee->ee_ant_control[mode][8] << 12) |
@@ -640,9 +651,9 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
static inline void
ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
{
- const static u16 intercepts3[] =
+ static const u16 intercepts3[] =
{ 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
- const static u16 intercepts3_2[] =
+ static const u16 intercepts3_2[] =
{ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
const u16 *ip;
int i;
@@ -1694,9 +1705,40 @@ ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
return 0;
}
+static int
+ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ u32 offset;
+ u16 val;
+ int ret = 0, i;
+
+ offset = AR5K_EEPROM_CTL(ee->ee_version) +
+ AR5K_EEPROM_N_CTLS(ee->ee_version);
+
+ if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) {
+ /* No spur info for 5GHz */
+ ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR;
+ /* 2 channels for 2GHz (2464/2420) */
+ ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1;
+ ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2;
+ ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR;
+ } else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) {
+ for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
+ AR5K_EEPROM_READ(offset, val);
+ ee->ee_spur_chans[i][0] = val;
+ AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS,
+ val);
+ ee->ee_spur_chans[i][1] = val;
+ offset++;
+ }
+ }
+
+ return ret;
+}
/*
- * Initialize eeprom power tables
+ * Initialize eeprom data structure
*/
int
ath5k_eeprom_init(struct ath5k_hw *ah)
@@ -1719,6 +1761,10 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
if (err < 0)
return err;
+ err = ath5k_eeprom_read_spur_chans(ah);
+ if (err < 0)
+ return err;
+
return 0;
}
@@ -1754,16 +1800,3 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
return 0;
}
-
-bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
-{
- u16 data;
-
- ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data);
-
- if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
- return true;
- else
- return false;
-}
-
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index b0c0606dea0b..64be73a5edae 100644
--- a/drivers/net/wireless/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -26,6 +26,13 @@
#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */
+
+#define AR5K_EEPROM_RFKILL 0x0f
+#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
+#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
+#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
+#define AR5K_EEPROM_RFKILL_POLARITY_S 1
+
#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */
#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
@@ -66,11 +73,6 @@
#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */
-#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
-#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
-#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
-#define AR5K_EEPROM_RFKILL_POLARITY_S 1
-
/* Newer EEPROMs are using a different offset */
#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
(((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
@@ -211,6 +213,23 @@
#define AR5K_EEPROM_I_GAIN 10
#define AR5K_EEPROM_CCK_OFDM_DELTA 15
#define AR5K_EEPROM_N_IQ_CAL 2
+/* 5GHz/2GHz */
+enum ath5k_eeprom_freq_bands{
+ AR5K_EEPROM_BAND_5GHZ = 0,
+ AR5K_EEPROM_BAND_2GHZ = 1,
+ AR5K_EEPROM_N_FREQ_BANDS,
+};
+/* Spur chans per freq band */
+#define AR5K_EEPROM_N_SPUR_CHANS 5
+/* fbin value for chan 2464 x2 */
+#define AR5K_EEPROM_5413_SPUR_CHAN_1 1640
+/* fbin value for chan 2420 x2 */
+#define AR5K_EEPROM_5413_SPUR_CHAN_2 1200
+#define AR5K_EEPROM_SPUR_CHAN_MASK 0x3FFF
+#define AR5K_EEPROM_NO_SPUR 0x8000
+#define AR5K_SPUR_CHAN_WIDTH 87
+#define AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz 3125
+#define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250
#define AR5K_EEPROM_READ(_o, _v) do { \
ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \
@@ -221,11 +240,11 @@
#define AR5K_EEPROM_READ_HDR(_o, _v) \
AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \
-enum ath5k_ant_setting {
- AR5K_ANT_VARIABLE = 0, /* variable by programming */
- AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */
- AR5K_ANT_FIXED_B = 2, /* fixed to 11b frequencies */
- AR5K_ANT_MAX = 3,
+enum ath5k_ant_table {
+ AR5K_ANT_CTL = 0, /* Idle switch table settings */
+ AR5K_ANT_SWTABLE_A = 1, /* Switch table for antenna A */
+ AR5K_ANT_SWTABLE_B = 2, /* Switch table for antenna B */
+ AR5K_ANT_MAX,
};
enum ath5k_ctl_mode {
@@ -369,6 +388,9 @@ struct ath5k_eeprom_info {
u16 ee_version;
u16 ee_header;
u16 ee_ant_gain;
+ u8 ee_rfkill_pin;
+ bool ee_rfkill_pol;
+ bool ee_is_hb63;
u16 ee_misc0;
u16 ee_misc1;
u16 ee_misc2;
@@ -436,6 +458,10 @@ struct ath5k_eeprom_info {
s8 ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES];
s8 ee_pd_gain_overlap;
+ /* Spur mitigation data (fbin values for spur channels) */
+ u16 ee_spur_chans[AR5K_EEPROM_N_SPUR_CHANS][AR5K_EEPROM_N_FREQ_BANDS];
+
+ /* Antenna raw switch tables */
u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
};
diff --git a/drivers/net/wireless/ath5k/gpio.c b/drivers/net/wireless/ath/ath5k/gpio.c
index 64a27e73d02e..64a27e73d02e 100644
--- a/drivers/net/wireless/ath5k/gpio.c
+++ b/drivers/net/wireless/ath/ath5k/gpio.c
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
index 61fb621ed20d..18eb5190ce4b 100644
--- a/drivers/net/wireless/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -537,8 +537,6 @@ static const struct ath5k_ini ar5212_ini_common_start[] = {
{ AR5K_DCU_TX_FILTER_1(15), 0x00000000 },
{ AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
{ AR5K_DCU_TX_FILTER_SET, 0x00000000 },
- { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
- { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
{ AR5K_STA_ID1, 0x00000000 },
{ AR5K_BSS_ID0, 0x00000000 },
{ AR5K_BSS_ID1, 0x00000000 },
@@ -669,7 +667,7 @@ static const struct ath5k_ini ar5212_ini_common_start[] = {
/*{ AR5K_PHY(650), 0x000001b5 },*/
{ AR5K_PHY(651), 0x00000000 },
{ AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
- { AR5K_PHY_TXPOWER_RATE2, 0x20202020 },
+ { AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
/*{ AR5K_PHY(655), 0x13c889af },*/
{ AR5K_PHY(656), 0x38490a20 },
{ AR5K_PHY(657), 0x00007bb6 },
@@ -718,7 +716,7 @@ static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
{ AR5K_PHY_SETTLING,
{ 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
{ AR5K_PHY_AGCCTL,
- { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
+ { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d10 } },
{ AR5K_PHY_NF,
{ 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
{ AR5K_PHY_WEAK_OFDM_HIGH_THR,
@@ -799,7 +797,7 @@ static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
{ AR5K_PHY_DESIRED_SIZE,
{ 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
+ { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7e800d2e } },
{ AR5K_PHY_AGCCOARSE,
{ 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
diff --git a/drivers/net/wireless/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index 19555fb79c9b..876725f08b6c 100644
--- a/drivers/net/wireless/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -53,8 +53,6 @@
/* Devices we match on for LED config info (typically laptops) */
static const struct pci_device_id ath5k_led_devices[] = {
- /* IBM-specific AR5212 */
- { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
/* AR5211 */
{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
/* HP Compaq nc6xx, nc4000, nx6000 */
@@ -67,6 +65,12 @@ static const struct pci_device_id ath5k_led_devices[] = {
{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
/* Acer Extensa 5620z (nekoreeve@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
+ /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) },
+ /* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) },
+ /* IBM-specific AR5212 (all others) */
+ { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
{ }
};
@@ -78,7 +82,7 @@ void ath5k_led_enable(struct ath5k_softc *sc)
}
}
-void ath5k_led_on(struct ath5k_softc *sc)
+static void ath5k_led_on(struct ath5k_softc *sc)
{
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
return;
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 55122f1e1986..579aa0a96ab8 100644
--- a/drivers/net/wireless/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -736,8 +736,8 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
/* When in AP mode zero timer0 to start TSF */
if (ah->ah_op_mode == NL80211_IFTYPE_AP)
ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
- else
- ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
+
+ ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
@@ -1003,7 +1003,7 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
* Note2: Windows driver (ndiswrapper) sets this to
* 0x00000714 instead of 0x00000007
*/
- if (ah->ah_version > AR5K_AR5211) {
+ if (ah->ah_version >= AR5K_AR5211) {
ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
AR5K_KEYTABLE_TYPE(entry));
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 9e2faae5ae94..d0d1c350025a 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -168,9 +168,6 @@ int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
* tx power and a Peak to Average Power Detector (PAPD) will try
* to measure the gain.
*
- * TODO: Use propper tx power setting for the probe packet so
- * that we don't observe a serious power drop on the receiver
- *
* XXX: How about forcing a tx packet (bypassing PCU arbitrator etc)
* just after we enable the probe so that we don't mess with
* standard traffic ? Maybe it's time to use sw interrupts and
@@ -186,7 +183,7 @@ static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
/* Send the packet with 2dB below max power as
* patent doc suggest */
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4,
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_ofdm - 4,
AR5K_PHY_PAPD_PROBE_TXPOWER) |
AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
@@ -1356,6 +1353,257 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
return ret;
}
+/***************************\
+* Spur mitigation functions *
+\***************************/
+
+bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ u8 refclk_freq;
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ refclk_freq = 40;
+ else
+ refclk_freq = 32;
+
+ if ((channel->center_freq % refclk_freq != 0) &&
+ ((channel->center_freq % refclk_freq < 10) ||
+ (channel->center_freq % refclk_freq > 22)))
+ return true;
+ else
+ return false;
+}
+
+void
+ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ u32 mag_mask[4] = {0, 0, 0, 0};
+ u32 pilot_mask[2] = {0, 0};
+ /* Note: fbin values are scaled up by 2 */
+ u16 spur_chan_fbin, chan_fbin, symbol_width, spur_detection_window;
+ s32 spur_delta_phase, spur_freq_sigma_delta;
+ s32 spur_offset, num_symbols_x16;
+ u8 num_symbol_offsets, i, freq_band;
+
+ /* Convert current frequency to fbin value (the same way channels
+ * are stored on EEPROM, check out ath5k_eeprom_bin2freq) and scale
+ * up by 2 so we can compare it later */
+ if (channel->hw_value & CHANNEL_2GHZ) {
+ chan_fbin = (channel->center_freq - 2300) * 10;
+ freq_band = AR5K_EEPROM_BAND_2GHZ;
+ } else {
+ chan_fbin = (channel->center_freq - 4900) * 10;
+ freq_band = AR5K_EEPROM_BAND_5GHZ;
+ }
+
+ /* Check if any spur_chan_fbin from EEPROM is
+ * within our current channel's spur detection range */
+ spur_chan_fbin = AR5K_EEPROM_NO_SPUR;
+ spur_detection_window = AR5K_SPUR_CHAN_WIDTH;
+ /* XXX: Half/Quarter channels ?*/
+ if (channel->hw_value & CHANNEL_TURBO)
+ spur_detection_window *= 2;
+
+ for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
+ spur_chan_fbin = ee->ee_spur_chans[i][freq_band];
+
+ /* Note: mask cleans AR5K_EEPROM_NO_SPUR flag
+ * so it's zero if we got nothing from EEPROM */
+ if (spur_chan_fbin == AR5K_EEPROM_NO_SPUR) {
+ spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
+ break;
+ }
+
+ if ((chan_fbin - spur_detection_window <=
+ (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK)) &&
+ (chan_fbin + spur_detection_window >=
+ (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK))) {
+ spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
+ break;
+ }
+ }
+
+ /* We need to enable spur filter for this channel */
+ if (spur_chan_fbin) {
+ spur_offset = spur_chan_fbin - chan_fbin;
+ /*
+ * Calculate deltas:
+ * spur_freq_sigma_delta -> spur_offset / sample_freq << 21
+ * spur_delta_phase -> spur_offset / chip_freq << 11
+ * Note: Both values have 100KHz resolution
+ */
+ /* XXX: Half/Quarter rate channels ? */
+ switch (channel->hw_value) {
+ case CHANNEL_A:
+ /* Both sample_freq and chip_freq are 40MHz */
+ spur_delta_phase = (spur_offset << 17) / 25;
+ spur_freq_sigma_delta = (spur_delta_phase >> 10);
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
+ break;
+ case CHANNEL_G:
+ /* sample_freq -> 40MHz chip_freq -> 44MHz
+ * (for b compatibility) */
+ spur_freq_sigma_delta = (spur_offset << 8) / 55;
+ spur_delta_phase = (spur_offset << 17) / 25;
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
+ break;
+ case CHANNEL_T:
+ case CHANNEL_TG:
+ /* Both sample_freq and chip_freq are 80MHz */
+ spur_delta_phase = (spur_offset << 16) / 25;
+ spur_freq_sigma_delta = (spur_delta_phase >> 10);
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz;
+ break;
+ default:
+ return;
+ }
+
+ /* Calculate pilot and magnitude masks */
+
+ /* Scale up spur_offset by 1000 to switch to 100HZ resolution
+ * and divide by symbol_width to find how many symbols we have
+ * Note: number of symbols is scaled up by 16 */
+ num_symbols_x16 = ((spur_offset * 1000) << 4) / symbol_width;
+
+ /* Spur is on a symbol if num_symbols_x16 % 16 is zero */
+ if (!(num_symbols_x16 & 0xF))
+ /* _X_ */
+ num_symbol_offsets = 3;
+ else
+ /* _xx_ */
+ num_symbol_offsets = 4;
+
+ for (i = 0; i < num_symbol_offsets; i++) {
+
+ /* Calculate pilot mask */
+ s32 curr_sym_off =
+ (num_symbols_x16 / 16) + i + 25;
+
+ /* Pilot magnitude mask seems to be a way to
+ * declare the boundaries for our detection
+ * window or something, it's 2 for the middle
+ * value(s) where the symbol is expected to be
+ * and 1 on the boundary values */
+ u8 plt_mag_map =
+ (i == 0 || i == (num_symbol_offsets - 1))
+ ? 1 : 2;
+
+ if (curr_sym_off >= 0 && curr_sym_off <= 32) {
+ if (curr_sym_off <= 25)
+ pilot_mask[0] |= 1 << curr_sym_off;
+ else if (curr_sym_off >= 27)
+ pilot_mask[0] |= 1 << (curr_sym_off - 1);
+ } else if (curr_sym_off >= 33 && curr_sym_off <= 52)
+ pilot_mask[1] |= 1 << (curr_sym_off - 33);
+
+ /* Calculate magnitude mask (for viterbi decoder) */
+ if (curr_sym_off >= -1 && curr_sym_off <= 14)
+ mag_mask[0] |=
+ plt_mag_map << (curr_sym_off + 1) * 2;
+ else if (curr_sym_off >= 15 && curr_sym_off <= 30)
+ mag_mask[1] |=
+ plt_mag_map << (curr_sym_off - 15) * 2;
+ else if (curr_sym_off >= 31 && curr_sym_off <= 46)
+ mag_mask[2] |=
+ plt_mag_map << (curr_sym_off - 31) * 2;
+ else if (curr_sym_off >= 46 && curr_sym_off <= 53)
+ mag_mask[3] |=
+ plt_mag_map << (curr_sym_off - 47) * 2;
+
+ }
+
+ /* Write settings on hw to enable spur filter */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+ AR5K_PHY_BIN_MASK_CTL_RATE, 0xff);
+ /* XXX: Self correlator also ? */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+ AR5K_PHY_IQ_PILOT_MASK_EN |
+ AR5K_PHY_IQ_CHAN_MASK_EN |
+ AR5K_PHY_IQ_SPUR_FILT_EN);
+
+ /* Set delta phase and freq sigma delta */
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM(spur_delta_phase,
+ AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE) |
+ AR5K_REG_SM(spur_freq_sigma_delta,
+ AR5K_PHY_TIMING_11_SPUR_FREQ_SD) |
+ AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC,
+ AR5K_PHY_TIMING_11);
+
+ /* Write pilot masks */
+ ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_7);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
+ AR5K_PHY_TIMING_8_PILOT_MASK_2,
+ pilot_mask[1]);
+
+ ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_9);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
+ AR5K_PHY_TIMING_10_PILOT_MASK_2,
+ pilot_mask[1]);
+
+ /* Write magnitude masks */
+ ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK_1);
+ ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK_2);
+ ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK_3);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+ AR5K_PHY_BIN_MASK_CTL_MASK_4,
+ mag_mask[3]);
+
+ ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK2_1);
+ ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK2_2);
+ ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK2_3);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
+ AR5K_PHY_BIN_MASK2_4_MASK_4,
+ mag_mask[3]);
+
+ } else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) &
+ AR5K_PHY_IQ_SPUR_FILT_EN) {
+ /* Clean up spur mitigation settings and disable fliter */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+ AR5K_PHY_BIN_MASK_CTL_RATE, 0);
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_IQ,
+ AR5K_PHY_IQ_PILOT_MASK_EN |
+ AR5K_PHY_IQ_CHAN_MASK_EN |
+ AR5K_PHY_IQ_SPUR_FILT_EN);
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_11);
+
+ /* Clear pilot masks */
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_7);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
+ AR5K_PHY_TIMING_8_PILOT_MASK_2,
+ 0);
+
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_9);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
+ AR5K_PHY_TIMING_10_PILOT_MASK_2,
+ 0);
+
+ /* Clear magnitude masks */
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_1);
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_2);
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_3);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+ AR5K_PHY_BIN_MASK_CTL_MASK_4,
+ 0);
+
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_1);
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_2);
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_3);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
+ AR5K_PHY_BIN_MASK2_4_MASK_4,
+ 0);
+ }
+}
+
+/********************\
+ Misc PHY functions
+\********************/
+
int ath5k_hw_phy_disable(struct ath5k_hw *ah)
{
ATH5K_TRACE(ah->ah_sc);
@@ -1365,10 +1613,6 @@ int ath5k_hw_phy_disable(struct ath5k_hw *ah)
return 0;
}
-/********************\
- Misc PHY functions
-\********************/
-
/*
* Get the PHY Chip revision
*/
@@ -1417,25 +1661,189 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
return ret;
}
+/*****************\
+* Antenna control *
+\*****************/
+
void /*TODO:Boundary check*/
-ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant)
+ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
{
ATH5K_TRACE(ah->ah_sc);
- /*Just a try M.F.*/
+
if (ah->ah_version != AR5K_AR5210)
- ath5k_hw_reg_write(ah, ant, AR5K_DEFAULT_ANTENNA);
+ ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
}
unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
{
ATH5K_TRACE(ah->ah_sc);
- /*Just a try M.F.*/
+
if (ah->ah_version != AR5K_AR5210)
- return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
+ return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7;
return false; /*XXX: What do we return for 5210 ?*/
}
+/*
+ * Enable/disable fast rx antenna diversity
+ */
+static void
+ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
+{
+ switch (ee_mode) {
+ case AR5K_EEPROM_MODE_11G:
+ /* XXX: This is set to
+ * disabled on initvals !!! */
+ case AR5K_EEPROM_MODE_11A:
+ if (enable)
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGCCTL,
+ AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
+ else
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+ AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
+ break;
+ case AR5K_EEPROM_MODE_11B:
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+ AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
+ break;
+ default:
+ return;
+ }
+
+ if (enable) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
+ AR5K_PHY_RESTART_DIV_GC, 0xc);
+
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
+ AR5K_PHY_FAST_ANT_DIV_EN);
+ } else {
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
+ AR5K_PHY_RESTART_DIV_GC, 0x8);
+
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
+ AR5K_PHY_FAST_ANT_DIV_EN);
+ }
+}
+
+/*
+ * Set antenna operating mode
+ */
+void
+ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
+{
+ struct ieee80211_channel *channel = &ah->ah_current_channel;
+ bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
+ bool use_def_for_sg;
+ u8 def_ant, tx_ant, ee_mode;
+ u32 sta_id1 = 0;
+
+ def_ant = ah->ah_def_ant;
+
+ ATH5K_TRACE(ah->ah_sc);
+
+ switch (channel->hw_value & CHANNEL_MODES) {
+ case CHANNEL_A:
+ case CHANNEL_T:
+ case CHANNEL_XR:
+ ee_mode = AR5K_EEPROM_MODE_11A;
+ break;
+ case CHANNEL_G:
+ case CHANNEL_TG:
+ ee_mode = AR5K_EEPROM_MODE_11G;
+ break;
+ case CHANNEL_B:
+ ee_mode = AR5K_EEPROM_MODE_11B;
+ break;
+ default:
+ ATH5K_ERR(ah->ah_sc,
+ "invalid channel: %d\n", channel->center_freq);
+ return;
+ }
+
+ switch (ant_mode) {
+ case AR5K_ANTMODE_DEFAULT:
+ tx_ant = 0;
+ use_def_for_tx = false;
+ update_def_on_tx = false;
+ use_def_for_rts = false;
+ use_def_for_sg = false;
+ fast_div = true;
+ break;
+ case AR5K_ANTMODE_FIXED_A:
+ def_ant = 1;
+ tx_ant = 0;
+ use_def_for_tx = true;
+ update_def_on_tx = false;
+ use_def_for_rts = true;
+ use_def_for_sg = true;
+ fast_div = false;
+ break;
+ case AR5K_ANTMODE_FIXED_B:
+ def_ant = 2;
+ tx_ant = 0;
+ use_def_for_tx = true;
+ update_def_on_tx = false;
+ use_def_for_rts = true;
+ use_def_for_sg = true;
+ fast_div = false;
+ break;
+ case AR5K_ANTMODE_SINGLE_AP:
+ def_ant = 1; /* updated on tx */
+ tx_ant = 0;
+ use_def_for_tx = true;
+ update_def_on_tx = true;
+ use_def_for_rts = true;
+ use_def_for_sg = true;
+ fast_div = true;
+ break;
+ case AR5K_ANTMODE_SECTOR_AP:
+ tx_ant = 1; /* variable */
+ use_def_for_tx = false;
+ update_def_on_tx = false;
+ use_def_for_rts = true;
+ use_def_for_sg = false;
+ fast_div = false;
+ break;
+ case AR5K_ANTMODE_SECTOR_STA:
+ tx_ant = 1; /* variable */
+ use_def_for_tx = true;
+ update_def_on_tx = false;
+ use_def_for_rts = true;
+ use_def_for_sg = false;
+ fast_div = true;
+ break;
+ case AR5K_ANTMODE_DEBUG:
+ def_ant = 1;
+ tx_ant = 2;
+ use_def_for_tx = false;
+ update_def_on_tx = false;
+ use_def_for_rts = false;
+ use_def_for_sg = false;
+ fast_div = false;
+ break;
+ default:
+ return;
+ }
+
+ ah->ah_tx_ant = tx_ant;
+ ah->ah_ant_mode = ant_mode;
+
+ sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
+ sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
+ sta_id1 |= use_def_for_rts ? AR5K_STA_ID1_RTS_DEF_ANTENNA : 0;
+ sta_id1 |= use_def_for_sg ? AR5K_STA_ID1_SELFGEN_DEF_ANT : 0;
+
+ AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_ANTENNA_SETTINGS);
+
+ if (sta_id1)
+ AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1);
+
+ /* Note: set diversity before default antenna
+ * because it won't work correctly */
+ ath5k_hw_set_fast_div(ah, ee_mode, fast_div);
+ ath5k_hw_set_def_antenna(ah, def_ant);
+}
+
/****************\
* TX power setup *
@@ -1487,28 +1895,35 @@ ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
{
s8 tmp;
s16 min_pwrL, min_pwrR;
- s16 pwr_i = pwrL[0];
-
- do {
- pwr_i--;
- tmp = (s8) ath5k_get_interpolated_value(pwr_i,
- pwrL[0], pwrL[1],
- stepL[0], stepL[1]);
-
- } while (tmp > 1);
-
- min_pwrL = pwr_i;
-
- pwr_i = pwrR[0];
- do {
- pwr_i--;
- tmp = (s8) ath5k_get_interpolated_value(pwr_i,
- pwrR[0], pwrR[1],
- stepR[0], stepR[1]);
-
- } while (tmp > 1);
+ s16 pwr_i;
+
+ if (pwrL[0] == pwrL[1])
+ min_pwrL = pwrL[0];
+ else {
+ pwr_i = pwrL[0];
+ do {
+ pwr_i--;
+ tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+ pwrL[0], pwrL[1],
+ stepL[0], stepL[1]);
+ } while (tmp > 1);
+
+ min_pwrL = pwr_i;
+ }
- min_pwrR = pwr_i;
+ if (pwrR[0] == pwrR[1])
+ min_pwrR = pwrR[0];
+ else {
+ pwr_i = pwrR[0];
+ do {
+ pwr_i--;
+ tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+ pwrR[0], pwrR[1],
+ stepR[0], stepR[1]);
+ } while (tmp > 1);
+
+ min_pwrR = pwr_i;
+ }
/* Keep the right boundary so that it works for both curves */
return max(min_pwrL, min_pwrR);
@@ -1743,8 +2158,6 @@ done:
* Get the max edge power for this channel if
* we have such data from EEPROM's Conformance Test
* Limits (CTL), and limit max power if needed.
- *
- * FIXME: Only works for world regulatory domains
*/
static void
ath5k_get_max_ctl_power(struct ath5k_hw *ah,
@@ -1760,26 +2173,23 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
u8 ctl_idx = 0xFF;
u32 target = channel->center_freq;
- /* Find out a CTL for our mode that's not mapped
- * on a specific reg domain.
- *
- * TODO: Map our current reg domain to one of the 3 available
- * reg domain ids so that we can support more CTLs. */
+ ctl_mode = ath_regd_get_band_ctl(&ah->ah_regulatory, channel->band);
+
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
- ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN;
+ ctl_mode |= AR5K_CTL_11A;
break;
case CHANNEL_G:
- ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN;
+ ctl_mode |= AR5K_CTL_11G;
break;
case CHANNEL_B:
- ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN;
+ ctl_mode |= AR5K_CTL_11B;
break;
case CHANNEL_T:
- ctl_mode = AR5K_CTL_TURBO | AR5K_CTL_NO_REGDOMAIN;
+ ctl_mode |= AR5K_CTL_TURBO;
break;
case CHANNEL_TG:
- ctl_mode = AR5K_CTL_TURBOG | AR5K_CTL_NO_REGDOMAIN;
+ ctl_mode |= AR5K_CTL_TURBOG;
break;
case CHANNEL_XR:
/* Fall through */
@@ -2475,8 +2885,19 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
for (i = 8; i <= 15; i++)
rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
- ah->ah_txpower.txp_min_pwr = rates[7];
- ah->ah_txpower.txp_max_pwr = rates[0];
+ /* Now that we have all rates setup use table offset to
+ * match the power range set by user with the power indices
+ * on PCDAC/PDADC table */
+ for (i = 0; i < 16; i++) {
+ rates[i] += ah->ah_txpower.txp_offset;
+ /* Don't get out of bounds */
+ if (rates[i] > 63)
+ rates[i] = 63;
+ }
+
+ /* Min/max in 0.25dB units */
+ ah->ah_txpower.txp_min_pwr = 2 * rates[7];
+ ah->ah_txpower.txp_max_pwr = 2 * rates[0];
ah->ah_txpower.txp_ofdm = rates[7];
}
@@ -2584,16 +3005,37 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
return 0;
}
-int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower)
+int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
{
/*Just a try M.F.*/
struct ieee80211_channel *channel = &ah->ah_current_channel;
+ u8 ee_mode;
ATH5K_TRACE(ah->ah_sc);
+
+ switch (channel->hw_value & CHANNEL_MODES) {
+ case CHANNEL_A:
+ case CHANNEL_T:
+ case CHANNEL_XR:
+ ee_mode = AR5K_EEPROM_MODE_11A;
+ break;
+ case CHANNEL_G:
+ case CHANNEL_TG:
+ ee_mode = AR5K_EEPROM_MODE_11G;
+ break;
+ case CHANNEL_B:
+ ee_mode = AR5K_EEPROM_MODE_11B;
+ break;
+ default:
+ ATH5K_ERR(ah->ah_sc,
+ "invalid channel: %d\n", channel->center_freq);
+ return -EINVAL;
+ }
+
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
"changing txpower to %d\n", txpower);
- return ath5k_hw_txpower(ah, channel, mode, txpower);
+ return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
}
#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 5094c394a4b2..73407b3f53ef 100644
--- a/drivers/net/wireless/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -160,7 +160,8 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
if (ah->ah_version == AR5K_AR5210)
return false;
- pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT);
+ pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
+ pending &= AR5K_QCU_STS_FRMPENDCNT;
/* It's possible to have no frames pending even if TXE
* is set. To indicate that q has not stopped return
@@ -401,14 +402,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
AR5K_DCU_MISC_ARBLOCK_CTL_S) |
+ AR5K_DCU_MISC_ARBLOCK_IGNORE |
AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
AR5K_DCU_MISC_BCN_ENABLE);
break;
case AR5K_TX_QUEUE_CAB:
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
- AR5K_QCU_MISC_FRSHED_DBA_GT |
+ AR5K_QCU_MISC_FRSHED_BCN_SENT_GT |
AR5K_QCU_MISC_CBREXP_DIS |
+ AR5K_QCU_MISC_RDY_VEOL_POLICY |
AR5K_QCU_MISC_CBREXP_BCN_DIS);
ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 7070d1543cdc..6809b54a2ad7 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -1148,6 +1148,11 @@
#define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */
#define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */
+#define AR5K_STA_ID1_ANTENNA_SETTINGS (AR5K_STA_ID1_DEFAULT_ANTENNA | \
+ AR5K_STA_ID1_DESC_ANTENNA | \
+ AR5K_STA_ID1_RTS_DEF_ANTENNA | \
+ AR5K_STA_ID1_SELFGEN_DEF_ANT)
+
/*
* First BSSID register (MAC address, lower 32bits)
*/
@@ -2028,7 +2033,9 @@
#define AR5K_PHY_AGCCTL 0x9860 /* Register address */
#define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */
#define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */
+#define AR5K_PHY_AGCCTL_OFDM_DIV_DIS 0x00000008 /* Disable antenna diversity on OFDM modes */
#define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */
+#define AR5K_PHY_AGCTL_FLTR_CAL 0x00010000 /* Allow filter calibration (?) */
#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */
/*
@@ -2528,7 +2535,7 @@
* PHY CCK Cross-correlator Barker RSSI threshold register [5212+]
*/
#define AR5K_PHY_CCK_CROSSCORR 0xa208
-#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000000f
+#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000003f
#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0
/* Same address is used for antenna diversity activation */
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 7a17d31b2fd9..c1862f8a2e7b 100644
--- a/drivers/net/wireless/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -54,9 +54,8 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
u32 coef_scaled, coef_exp, coef_man,
ds_coef_exp, ds_coef_man, clock;
- if (!(ah->ah_version == AR5K_AR5212) ||
- !(channel->hw_value & CHANNEL_OFDM))
- BUG();
+ BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
+ !(channel->hw_value & CHANNEL_OFDM));
/* Get coefficient
* ALGO: coef = (5 * clock * carrier_freq) / 2)
@@ -359,7 +358,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
mode |= AR5K_PHY_MODE_FREQ_5GHZ;
if (ah->ah_radio == AR5K_RF5413)
- clock |= AR5K_PHY_PLL_40MHZ_5413;
+ clock = AR5K_PHY_PLL_40MHZ_5413;
else
clock |= AR5K_PHY_PLL_40MHZ;
@@ -508,7 +507,7 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
scal = AR5K_PHY_SCAL_32MHZ_2417;
- else if (ath5k_eeprom_is_hb63(ah))
+ else if (ee->ee_is_hb63)
scal = AR5K_PHY_SCAL_32MHZ_HB63;
else
scal = AR5K_PHY_SCAL_32MHZ;
@@ -537,26 +536,6 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
return;
}
-static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
- struct ieee80211_channel *channel)
-{
- u8 refclk_freq;
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
- refclk_freq = 40;
- else
- refclk_freq = 32;
-
- if ((channel->center_freq % refclk_freq != 0) &&
- ((channel->center_freq % refclk_freq < 10) ||
- (channel->center_freq % refclk_freq > 22)))
- return true;
- else
- return false;
-}
-
/* TODO: Half/Quarter rate */
static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
struct ieee80211_channel *channel)
@@ -599,9 +578,10 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
/* Set DAC/ADC delays */
if (ah->ah_version == AR5K_AR5212) {
u32 scal;
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
scal = AR5K_PHY_SCAL_32MHZ_2417;
- else if (ath5k_eeprom_is_hb63(ah))
+ else if (ee->ee_is_hb63)
scal = AR5K_PHY_SCAL_32MHZ_HB63;
else
scal = AR5K_PHY_SCAL_32MHZ;
@@ -698,13 +678,13 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
/* Set antenna idle switch table */
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
- (ah->ah_antenna[ee_mode][0] |
+ (ah->ah_ant_ctl[ee_mode][0] |
AR5K_PHY_ANT_CTL_TXRX_EN));
- /* Set antenna switch table */
- ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
+ /* Set antenna switch tables */
+ ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[0]],
AR5K_PHY_ANT_SWITCH_TABLE_0);
- ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
+ ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[1]],
AR5K_PHY_ANT_SWITCH_TABLE_1);
/* Noise floor threshold */
@@ -998,10 +978,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_tweak_initval_settings(ah, channel);
/*
- * Set TX power (FIXME)
+ * Set TX power
*/
ret = ath5k_hw_txpower(ah, channel, ee_mode,
- AR5K_TUNE_DEFAULT_TXPOWER);
+ ah->ah_txpower.txp_max_pwr / 2);
if (ret)
return ret;
@@ -1024,9 +1004,22 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/* Write OFDM timings on 5212*/
if (ah->ah_version == AR5K_AR5212 &&
channel->hw_value & CHANNEL_OFDM) {
+ struct ath5k_eeprom_info *ee =
+ &ah->ah_capabilities.cap_eeprom;
+
ret = ath5k_hw_write_ofdm_timings(ah, channel);
if (ret)
return ret;
+
+ /* Note: According to docs we can have a newer
+ * EEPROM on old hardware, so we need to verify
+ * that our hardware is new enough to have spur
+ * mitigation registers (delta phase etc) */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR5424 ||
+ (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
+ ee->ee_version >= AR5K_EEPROM_VERSION_5_3))
+ ath5k_hw_set_spur_mitigation_filter(ah,
+ channel);
}
/*Enable/disable 802.11b mode on 5111
@@ -1042,17 +1035,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/*
* In case a fixed antenna was set as default
- * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
- * registers.
+ * use the same switch table twice.
*/
- if (s_ant != 0) {
- if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
- ant[0] = ant[1] = AR5K_ANT_FIXED_A;
- else /* 2 - Aux */
- ant[0] = ant[1] = AR5K_ANT_FIXED_B;
- } else {
- ant[0] = AR5K_ANT_FIXED_A;
- ant[1] = AR5K_ANT_FIXED_B;
+ if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
+ ant[0] = ant[1] = AR5K_ANT_SWTABLE_A;
+ else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
+ ant[0] = ant[1] = AR5K_ANT_SWTABLE_B;
+ else {
+ ant[0] = AR5K_ANT_SWTABLE_A;
+ ant[1] = AR5K_ANT_SWTABLE_B;
}
/* Commit values from EEPROM */
@@ -1260,6 +1251,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
*/
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+ /* Restore antenna mode */
+ ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
/*
* Configure QCUs/DCUs
diff --git a/drivers/net/wireless/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h
index e50baff66175..e50baff66175 100644
--- a/drivers/net/wireless/ath5k/rfbuffer.h
+++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h
diff --git a/drivers/net/wireless/ath5k/rfgain.h b/drivers/net/wireless/ath/ath5k/rfgain.h
index 1354d8c392c8..1354d8c392c8 100644
--- a/drivers/net/wireless/ath5k/rfgain.h
+++ b/drivers/net/wireless/ath/ath5k/rfgain.h
diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 90a8dd873786..0ed1ac312aa6 100644
--- a/drivers/net/wireless/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -2,6 +2,7 @@ config ATH9K
tristate "Atheros 802.11n wireless cards support"
depends on PCI && MAC80211 && WLAN_80211
depends on RFKILL || RFKILL=n
+ select ATH_COMMON
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 1a4d4eab6fe8..783bc39eb2ff 100644
--- a/drivers/net/wireless/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -4,7 +4,6 @@ ath9k-y += hw.o \
calib.o \
ani.o \
phy.o \
- regd.o \
beacon.o \
main.o \
recv.o \
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 0e65c51ba176..0e65c51ba176 100644
--- a/drivers/net/wireless/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 6c5e887d50d7..1aeafb511ddd 100644
--- a/drivers/net/wireless/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -569,8 +569,7 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"phyCnt1 0x%x, resetting "
"counter value to 0x%x\n",
- phyCnt1,
- aniState->ofdmPhyErrBase);
+ phyCnt1, aniState->ofdmPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_1,
aniState->ofdmPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_MASK_1,
@@ -580,8 +579,7 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"phyCnt2 0x%x, resetting "
"counter value to 0x%x\n",
- phyCnt2,
- aniState->cckPhyErrBase);
+ phyCnt2, aniState->cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_2,
aniState->cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_MASK_2,
@@ -667,7 +665,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
u32 cc = REG_READ(ah, AR_CCCNT);
if (cycles == 0 || cycles > cc) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+ DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"cycle counter wrap. ExtBusy = 0\n");
good = 0;
} else {
diff --git a/drivers/net/wireless/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 08b4e7ed5ff0..08b4e7ed5ff0 100644
--- a/drivers/net/wireless/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 2689a08a2844..10ffc9442859 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -53,11 +53,7 @@ struct ath_node;
#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
-#define ASSERT(exp) do { \
- if (unlikely(!(exp))) { \
- BUG(); \
- } \
- } while (0)
+#define ASSERT(exp) BUG_ON(!(exp))
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
@@ -70,7 +66,6 @@ struct ath_config {
u32 ath_aggr_prot;
u16 txpowlimit;
u8 cabqReadytime;
- u8 swBeaconProcess;
};
/*************************/
@@ -78,13 +73,17 @@ struct ath_config {
/*************************/
#define ATH_TXBUF_RESET(_bf) do { \
- (_bf)->bf_status = 0; \
+ (_bf)->bf_stale = false; \
(_bf)->bf_lastbf = NULL; \
(_bf)->bf_next = NULL; \
memset(&((_bf)->bf_state), 0, \
sizeof(struct ath_buf_state)); \
} while (0)
+#define ATH_RXBUF_RESET(_bf) do { \
+ (_bf)->bf_stale = false; \
+ } while (0)
+
/**
* enum buffer_type - Buffer type flags
*
@@ -110,7 +109,7 @@ struct ath_buf_state {
int bfs_seqno;
int bfs_tidno;
int bfs_retries;
- u32 bf_type;
+ u8 bf_type;
u32 bfs_keyix;
enum ath9k_key_type bfs_keytype;
};
@@ -134,26 +133,21 @@ struct ath_buf {
struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
an aggregate) */
struct ath_buf *bf_next; /* next subframe in the aggregate */
- void *bf_mpdu; /* enclosing frame structure */
+ struct sk_buff *bf_mpdu; /* enclosing frame structure */
struct ath_desc *bf_desc; /* virtual addr of desc */
dma_addr_t bf_daddr; /* physical addr of desc */
dma_addr_t bf_buf_addr; /* physical addr of data buffer */
- u32 bf_status;
+ bool bf_stale;
u16 bf_flags;
struct ath_buf_state bf_state;
dma_addr_t bf_dmacontext;
};
-#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
-#define ATH_BUFSTATUS_STALE 0x00000002
-
struct ath_descdma {
- const char *dd_name;
struct ath_desc *dd_desc;
dma_addr_t dd_desc_paddr;
u32 dd_desc_len;
struct ath_buf *dd_bufptr;
- dma_addr_t dd_dmacontext;
};
int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
@@ -299,26 +293,6 @@ struct ath_tx_control {
#define ATH_TX_XRETRY 0x02
#define ATH_TX_BAR 0x04
-/* All RSSI values are noise floor adjusted */
-struct ath_tx_stat {
- int rssi;
- int rssictl[ATH_MAX_ANTENNA];
- int rssiextn[ATH_MAX_ANTENNA];
- int rateieee;
- int rateKbps;
- int ratecode;
- int flags;
- u32 airtime; /* time on air per final tx rate */
-};
-
-struct aggr_rifs_param {
- int param_max_frames;
- int param_max_len;
- int param_rl;
- int param_al;
- struct ath_rc_series *param_rcs;
-};
-
struct ath_node {
struct ath_softc *an_sc;
struct ath_atx_tid tid[WME_NUM_TID];
@@ -366,7 +340,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
int ath_tx_init(struct ath_softc *sc, int nbufs);
-int ath_tx_cleanup(struct ath_softc *sc);
+void ath_tx_cleanup(struct ath_softc *sc);
struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
int ath_txq_update(struct ath_softc *sc, int qnum,
struct ath9k_tx_queue_info *q);
@@ -529,19 +503,18 @@ struct ath_rfkill {
#define SC_OP_BEACONS BIT(1)
#define SC_OP_RXAGGR BIT(2)
#define SC_OP_TXAGGR BIT(3)
-#define SC_OP_CHAINMASK_UPDATE BIT(4)
-#define SC_OP_FULL_RESET BIT(5)
-#define SC_OP_PREAMBLE_SHORT BIT(6)
-#define SC_OP_PROTECT_ENABLE BIT(7)
-#define SC_OP_RXFLUSH BIT(8)
-#define SC_OP_LED_ASSOCIATED BIT(9)
-#define SC_OP_RFKILL_REGISTERED BIT(10)
-#define SC_OP_RFKILL_SW_BLOCKED BIT(11)
-#define SC_OP_RFKILL_HW_BLOCKED BIT(12)
-#define SC_OP_WAIT_FOR_BEACON BIT(13)
-#define SC_OP_LED_ON BIT(14)
-#define SC_OP_SCANNING BIT(15)
-#define SC_OP_TSF_RESET BIT(16)
+#define SC_OP_FULL_RESET BIT(4)
+#define SC_OP_PREAMBLE_SHORT BIT(5)
+#define SC_OP_PROTECT_ENABLE BIT(6)
+#define SC_OP_RXFLUSH BIT(7)
+#define SC_OP_LED_ASSOCIATED BIT(8)
+#define SC_OP_RFKILL_REGISTERED BIT(9)
+#define SC_OP_RFKILL_SW_BLOCKED BIT(10)
+#define SC_OP_RFKILL_HW_BLOCKED BIT(11)
+#define SC_OP_WAIT_FOR_BEACON BIT(12)
+#define SC_OP_LED_ON BIT(13)
+#define SC_OP_SCANNING BIT(14)
+#define SC_OP_TSF_RESET BIT(15)
struct ath_bus_ops {
void (*read_cachesize)(struct ath_softc *sc, int *csz);
@@ -603,8 +576,8 @@ struct ath_softc {
struct ath_tx tx;
struct ath_beacon beacon;
struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
- struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
- struct ath_rate_table *cur_rate_table;
+ const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
+ const struct ath_rate_table *cur_rate_table;
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ath_led radio_led;
@@ -617,6 +590,8 @@ struct ath_softc {
int led_on_cnt;
int led_off_cnt;
+ int beacon_interval;
+
struct ath_rfkill rf_kill;
struct ath_ani ani;
struct ath9k_node_stats nodestats;
@@ -722,36 +697,7 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
bool ath9k_wiphy_scanning(struct ath_softc *sc);
void ath9k_wiphy_work(struct work_struct *work);
-/*
- * Read and write, they both share the same lock. We do this to serialize
- * reads and writes on Atheros 802.11n PCI devices only. This is required
- * as the FIFO on these devices can only accept sanely 2 requests. After
- * that the device goes bananas. Serializing the reads/writes prevents this
- * from happening.
- */
-
-static inline void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
-{
- if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
- unsigned long flags;
- spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
- iowrite32(val, ah->ah_sc->mem + reg_offset);
- spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
- } else
- iowrite32(val, ah->ah_sc->mem + reg_offset);
-}
-
-static inline unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
-{
- u32 val;
- if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
- unsigned long flags;
- spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
- val = ioread32(ah->ah_sc->mem + reg_offset);
- spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
- } else
- val = ioread32(ah->ah_sc->mem + reg_offset);
- return val;
-}
+void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val);
+unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset);
#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index ec995730632d..3a7154beeae1 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -43,7 +43,7 @@ static int ath_beaconq_config(struct ath_softc *sc)
if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
DPRINTF(sc, ATH_DBG_FATAL,
- "unable to update h/w beacon queue parameters\n");
+ "Unable to update h/w beacon queue parameters\n");
return 0;
} else {
ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
@@ -59,11 +59,11 @@ static int ath_beaconq_config(struct ath_softc *sc)
static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
struct ath_buf *bf)
{
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct sk_buff *skb = bf->bf_mpdu;
struct ath_hw *ah = sc->sc_ah;
struct ath_desc *ds;
struct ath9k_11n_rate_series series[4];
- struct ath_rate_table *rt;
+ const struct ath_rate_table *rt;
int flags, antenna, ctsrate = 0, ctsduration = 0;
u8 rate;
@@ -132,16 +132,13 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
avp = (void *)vif->drv_priv;
cabq = sc->beacon.cabq;
- if (avp->av_bcbuf == NULL) {
- DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
- avp, avp->av_bcbuf);
+ if (avp->av_bcbuf == NULL)
return NULL;
- }
/* Release the old beacon first */
bf = avp->av_bcbuf;
- skb = (struct sk_buff *)bf->bf_mpdu;
+ skb = bf->bf_mpdu;
if (skb) {
dma_unmap_single(sc->dev, bf->bf_dmacontext,
skb->len, DMA_TO_DEVICE);
@@ -229,7 +226,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc,
return;
bf = avp->av_bcbuf;
- skb = (struct sk_buff *) bf->bf_mpdu;
+ skb = bf->bf_mpdu;
ath_beacon_setup(sc, avp, bf);
@@ -302,7 +299,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
/* release the previous beacon frame, if it already exists. */
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
- skb = (struct sk_buff *)bf->bf_mpdu;
+ skb = bf->bf_mpdu;
dma_unmap_single(sc->dev, bf->bf_dmacontext,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
@@ -323,8 +320,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
u64 tsfadjust;
int intval;
- intval = sc->hw->conf.beacon_int ?
- sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
+ intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
/*
* Calculate the TSF offset for this beacon slot, i.e., the
@@ -374,7 +370,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct sk_buff *skb = bf->bf_mpdu;
dma_unmap_single(sc->dev, bf->bf_dmacontext,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
@@ -434,8 +430,7 @@ void ath_beacon_tasklet(unsigned long data)
* on the tsf to safeguard against missing an swba.
*/
- intval = sc->hw->conf.beacon_int ?
- sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
+ intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf);
@@ -714,8 +709,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
/* Setup the beacon configuration parameters */
memset(&conf, 0, sizeof(struct ath_beacon_config));
- conf.beacon_interval = sc->hw->conf.beacon_int ?
- sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
+ conf.beacon_interval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
conf.listen_interval = 1;
conf.dtim_period = conf.beacon_interval;
conf.dtim_count = 1;
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index e2d62e97131c..a32d7e7fecbe 100644
--- a/drivers/net/wireless/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -186,7 +186,7 @@ static bool getNoiseFloorThresh(struct ath_hw *ah,
}
static void ath9k_hw_setup_calibration(struct ath_hw *ah,
- struct hal_cal_list *currCal)
+ struct ath9k_cal_list *currCal)
{
REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
@@ -220,7 +220,7 @@ static void ath9k_hw_setup_calibration(struct ath_hw *ah,
}
static void ath9k_hw_reset_calibration(struct ath_hw *ah,
- struct hal_cal_list *currCal)
+ struct ath9k_cal_list *currCal)
{
int i;
@@ -238,13 +238,12 @@ static void ath9k_hw_reset_calibration(struct ath_hw *ah,
ah->cal_samples = 0;
}
-static void ath9k_hw_per_calibration(struct ath_hw *ah,
+static bool ath9k_hw_per_calibration(struct ath_hw *ah,
struct ath9k_channel *ichan,
u8 rxchainmask,
- struct hal_cal_list *currCal,
- bool *isCalDone)
+ struct ath9k_cal_list *currCal)
{
- *isCalDone = false;
+ bool iscaldone = false;
if (currCal->calState == CAL_RUNNING) {
if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
@@ -263,7 +262,7 @@ static void ath9k_hw_per_calibration(struct ath_hw *ah,
currCal->calData->calPostProc(ah, numChains);
ichan->CalValid |= currCal->calData->calType;
currCal->calState = CAL_DONE;
- *isCalDone = true;
+ iscaldone = true;
} else {
ath9k_hw_setup_calibration(ah, currCal);
}
@@ -271,11 +270,13 @@ static void ath9k_hw_per_calibration(struct ath_hw *ah,
} else if (!(ichan->CalValid & currCal->calData->calType)) {
ath9k_hw_reset_calibration(ah, currCal);
}
+
+ return iscaldone;
}
/* Assumes you are talking about the currently configured channel */
static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
- enum hal_cal_types calType)
+ enum ath9k_cal_types calType)
{
struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
@@ -284,8 +285,8 @@ static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
return true;
case ADC_GAIN_CAL:
case ADC_DC_CAL:
- if (conf->channel->band == IEEE80211_BAND_5GHZ &&
- conf_is_ht20(conf))
+ if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
+ conf_is_ht20(conf)))
return true;
break;
}
@@ -498,7 +499,7 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
{
u32 iOddMeasOffset, iEvenMeasOffset, val, i;
int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
- const struct hal_percal_data *calData =
+ const struct ath9k_percal_data *calData =
ah->cal_list_curr->calData;
u32 numSamples =
(1 << (calData->calCountMax + 5)) * calData->calNumSamples;
@@ -555,7 +556,7 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
{
struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
- struct hal_cal_list *currCal = ah->cal_list_curr;
+ struct ath9k_cal_list *currCal = ah->cal_list_curr;
if (!ah->curchan)
return true;
@@ -841,30 +842,28 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
}
bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
- u8 rxchainmask, bool longcal,
- bool *isCalDone)
+ u8 rxchainmask, bool longcal)
{
- struct hal_cal_list *currCal = ah->cal_list_curr;
-
- *isCalDone = true;
+ bool iscaldone = true;
+ struct ath9k_cal_list *currCal = ah->cal_list_curr;
if (currCal &&
(currCal->calState == CAL_RUNNING ||
currCal->calState == CAL_WAITING)) {
- ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
- isCalDone);
- if (*isCalDone) {
+ iscaldone = ath9k_hw_per_calibration(ah, chan,
+ rxchainmask, currCal);
+ if (iscaldone) {
ah->cal_list_curr = currCal = currCal->calNext;
if (currCal->calState == CAL_WAITING) {
- *isCalDone = false;
+ iscaldone = false;
ath9k_hw_reset_calibration(ah, currCal);
}
}
}
if (longcal) {
- if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+ if (AR_SREV_9285_11_OR_LATER(ah))
ath9k_hw_9285_pa_cal(ah);
if (OLC_FOR_AR9280_20_LATER)
@@ -872,18 +871,15 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_getnf(ah, chan);
ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah);
-
- if (chan->channelFlags & CHANNEL_CW_INT)
- chan->channelFlags &= ~CHANNEL_CW_INT;
}
- return true;
+ return iscaldone;
}
static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
{
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
- if (chan->channelFlags & CHANNEL_HT20) {
+ if (IS_CHAN_HT20(chan)) {
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
@@ -919,83 +915,66 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
return true;
}
-bool ath9k_hw_init_cal(struct ath_hw *ah,
- struct ath9k_channel *chan)
+bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
{
- if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
+ if (AR_SREV_9285_12_OR_LATER(ah)) {
if (!ar9285_clc(ah, chan))
return false;
- } else if (AR_SREV_9280_10_OR_LATER(ah)) {
- REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
- REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
- REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ } else {
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ }
- /* Kick off the cal */
+ /* Calibrate the AGC */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) |
- AR_PHY_AGC_CONTROL_CAL);
+ REG_READ(ah, AR_PHY_AGC_CONTROL) |
+ AR_PHY_AGC_CONTROL_CAL);
- if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
- AR_PHY_AGC_CONTROL_CAL, 0,
- AH_WAIT_TIMEOUT)) {
+ /* Poll for offset calibration complete */
+ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+ 0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"offset calibration failed to complete in 1ms; "
"noisy environment?\n");
return false;
}
- REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
- REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
- REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
- }
-
- /* Calibrate the AGC */
- REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) |
- AR_PHY_AGC_CONTROL_CAL);
-
- if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
- 0, AH_WAIT_TIMEOUT)) {
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "offset calibration failed to complete in 1ms; "
- "noisy environment?\n");
- return false;
- }
-
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
- REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ }
}
/* Do PA Calibration */
- if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+ if (AR_SREV_9285_11_OR_LATER(ah))
ath9k_hw_9285_pa_cal(ah);
- /* Do NF Calibration */
+ /* Do NF Calibration after DC offset and other calibrations */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) |
- AR_PHY_AGC_CONTROL_NF);
+ REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+ /* Enable IQ, ADC Gain and ADC DC offset CALs */
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
INIT_CAL(&ah->adcgain_caldata);
INSERT_CAL(ah, &ah->adcgain_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "enabling ADC Gain Calibration.\n");
+ "enabling ADC Gain Calibration.\n");
}
if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
INIT_CAL(&ah->adcdc_caldata);
INSERT_CAL(ah, &ah->adcdc_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "enabling ADC DC Calibration.\n");
+ "enabling ADC DC Calibration.\n");
}
if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "enabling IQ Calibration.\n");
+ "enabling IQ Calibration.\n");
}
ah->cal_list_curr = ah->cal_list;
@@ -1009,49 +988,49 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
return true;
}
-const struct hal_percal_data iq_cal_multi_sample = {
+const struct ath9k_percal_data iq_cal_multi_sample = {
IQ_MISMATCH_CAL,
MAX_CAL_SAMPLES,
PER_MIN_LOG_COUNT,
ath9k_hw_iqcal_collect,
ath9k_hw_iqcalibrate
};
-const struct hal_percal_data iq_cal_single_sample = {
+const struct ath9k_percal_data iq_cal_single_sample = {
IQ_MISMATCH_CAL,
MIN_CAL_SAMPLES,
PER_MAX_LOG_COUNT,
ath9k_hw_iqcal_collect,
ath9k_hw_iqcalibrate
};
-const struct hal_percal_data adc_gain_cal_multi_sample = {
+const struct ath9k_percal_data adc_gain_cal_multi_sample = {
ADC_GAIN_CAL,
MAX_CAL_SAMPLES,
PER_MIN_LOG_COUNT,
ath9k_hw_adc_gaincal_collect,
ath9k_hw_adc_gaincal_calibrate
};
-const struct hal_percal_data adc_gain_cal_single_sample = {
+const struct ath9k_percal_data adc_gain_cal_single_sample = {
ADC_GAIN_CAL,
MIN_CAL_SAMPLES,
PER_MAX_LOG_COUNT,
ath9k_hw_adc_gaincal_collect,
ath9k_hw_adc_gaincal_calibrate
};
-const struct hal_percal_data adc_dc_cal_multi_sample = {
+const struct ath9k_percal_data adc_dc_cal_multi_sample = {
ADC_DC_CAL,
MAX_CAL_SAMPLES,
PER_MIN_LOG_COUNT,
ath9k_hw_adc_dccal_collect,
ath9k_hw_adc_dccal_calibrate
};
-const struct hal_percal_data adc_dc_cal_single_sample = {
+const struct ath9k_percal_data adc_dc_cal_single_sample = {
ADC_DC_CAL,
MIN_CAL_SAMPLES,
PER_MAX_LOG_COUNT,
ath9k_hw_adc_dccal_collect,
ath9k_hw_adc_dccal_calibrate
};
-const struct hal_percal_data adc_init_dc_cal = {
+const struct ath9k_percal_data adc_init_dc_cal = {
ADC_DC_INIT_CAL,
MIN_CAL_SAMPLES,
INIT_LOG_COUNT,
diff --git a/drivers/net/wireless/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 1c74bd50700d..fe5367f14148 100644
--- a/drivers/net/wireless/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -17,13 +17,13 @@
#ifndef CALIB_H
#define CALIB_H
-extern const struct hal_percal_data iq_cal_multi_sample;
-extern const struct hal_percal_data iq_cal_single_sample;
-extern const struct hal_percal_data adc_gain_cal_multi_sample;
-extern const struct hal_percal_data adc_gain_cal_single_sample;
-extern const struct hal_percal_data adc_dc_cal_multi_sample;
-extern const struct hal_percal_data adc_dc_cal_single_sample;
-extern const struct hal_percal_data adc_init_dc_cal;
+extern const struct ath9k_percal_data iq_cal_multi_sample;
+extern const struct ath9k_percal_data iq_cal_single_sample;
+extern const struct ath9k_percal_data adc_gain_cal_multi_sample;
+extern const struct ath9k_percal_data adc_gain_cal_single_sample;
+extern const struct ath9k_percal_data adc_dc_cal_multi_sample;
+extern const struct ath9k_percal_data adc_dc_cal_single_sample;
+extern const struct ath9k_percal_data adc_init_dc_cal;
#define AR_PHY_CCA_MAX_GOOD_VALUE -85
#define AR_PHY_CCA_MAX_HIGH_VALUE -62
@@ -67,14 +67,14 @@ struct ar5416IniArray {
} \
} while (0)
-enum hal_cal_types {
+enum ath9k_cal_types {
ADC_DC_INIT_CAL = 0x1,
ADC_GAIN_CAL = 0x2,
ADC_DC_CAL = 0x4,
IQ_MISMATCH_CAL = 0x8
};
-enum hal_cal_state {
+enum ath9k_cal_state {
CAL_INACTIVE,
CAL_WAITING,
CAL_RUNNING,
@@ -87,18 +87,18 @@ enum hal_cal_state {
#define PER_MIN_LOG_COUNT 2
#define PER_MAX_LOG_COUNT 10
-struct hal_percal_data {
- enum hal_cal_types calType;
+struct ath9k_percal_data {
+ enum ath9k_cal_types calType;
u32 calNumSamples;
u32 calCountMax;
void (*calCollect) (struct ath_hw *);
void (*calPostProc) (struct ath_hw *, u8);
};
-struct hal_cal_list {
- const struct hal_percal_data *calData;
- enum hal_cal_state calState;
- struct hal_cal_list *calNext;
+struct ath9k_cal_list {
+ const struct ath9k_percal_data *calData;
+ enum ath9k_cal_state calState;
+ struct ath9k_cal_list *calNext;
};
struct ath9k_nfcal_hist {
@@ -116,8 +116,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
- u8 rxchainmask, bool longcal,
- bool *isCalDone);
+ u8 rxchainmask, bool longcal);
bool ath9k_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan);
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index fdf9528fa49b..97df20cbf528 100644
--- a/drivers/net/wireless/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -498,6 +498,9 @@ int ath9k_init_debug(struct ath_softc *sc)
{
sc->debug.debug_mask = ath9k_debug;
+ if (!ath9k_debugfs_root)
+ return -ENOENT;
+
sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
ath9k_debugfs_root);
if (!sc->debug.debugfs_phy)
diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 7b0e5419d2bc..23298b90b52b 100644
--- a/drivers/net/wireless/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -19,20 +19,16 @@
enum ATH_DEBUG {
ATH_DBG_RESET = 0x00000001,
- ATH_DBG_REG_IO = 0x00000002,
- ATH_DBG_QUEUE = 0x00000004,
- ATH_DBG_EEPROM = 0x00000008,
- ATH_DBG_CALIBRATE = 0x00000010,
- ATH_DBG_CHANNEL = 0x00000020,
- ATH_DBG_INTERRUPT = 0x00000040,
- ATH_DBG_REGULATORY = 0x00000080,
- ATH_DBG_ANI = 0x00000100,
- ATH_DBG_POWER_MGMT = 0x00000200,
- ATH_DBG_XMIT = 0x00000400,
- ATH_DBG_BEACON = 0x00001000,
- ATH_DBG_CONFIG = 0x00002000,
- ATH_DBG_KEYCACHE = 0x00004000,
- ATH_DBG_FATAL = 0x00008000,
+ ATH_DBG_QUEUE = 0x00000002,
+ ATH_DBG_EEPROM = 0x00000004,
+ ATH_DBG_CALIBRATE = 0x00000008,
+ ATH_DBG_INTERRUPT = 0x00000010,
+ ATH_DBG_REGULATORY = 0x00000020,
+ ATH_DBG_ANI = 0x00000040,
+ ATH_DBG_XMIT = 0x00000080,
+ ATH_DBG_BEACON = 0x00000100,
+ ATH_DBG_CONFIG = 0x00000200,
+ ATH_DBG_FATAL = 0x00000400,
ATH_DBG_ANY = 0xffffffff
};
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index ffc36b0361c7..a2fda702b620 100644
--- a/drivers/net/wireless/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -694,7 +694,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
#undef TMP_VAL_VPD_TABLE
}
-static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
+static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *pTxPowerIndexOffset)
{
@@ -783,11 +783,11 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
((pdadcValues[4 * j + 3] & 0xFF) << 24);
REG_WRITE(ah, regOffset, reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PDADC (%d,%4x): %4.4x %8.8x\n",
i, regChainOffset, regOffset,
reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PDADC: Chain %d | "
"PDADC %3d Value %3d | "
"PDADC %3d Value %3d | "
@@ -805,11 +805,9 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
}
*pTxPowerIndexOffset = 0;
-
- return true;
}
-static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
+static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *ratesArray,
u16 cfgCtl,
@@ -910,7 +908,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
ah->eep_ops->get_eeprom_rev(ah) <= 2)
twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
"EXT_ADDITIVE %d\n",
ctlMode, numCtlModes, isHt40CtlMode,
@@ -918,7 +916,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
for (i = 0; (i < AR5416_NUM_CTLS) &&
pEepData->ctlIndex[i]; i++) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
"pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
"chan %d\n",
@@ -941,7 +939,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
IS_CHAN_2GHZ(chan),
AR5416_EEP4K_NUM_BAND_EDGES);
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" MATCH-EE_IDX %d: ch %d is2 %d "
"2xMinEdge %d chainmask %d chains %d\n",
i, freq, IS_CHAN_2GHZ(chan),
@@ -961,7 +959,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" SEL-Min ctlMode %d pCtlMode %d "
"2xMaxEdge %d sP %d minCtlPwr %d\n",
ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
@@ -1041,10 +1039,9 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
}
- return true;
}
-static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
+static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan,
u16 cfgCtl,
u8 twiceAntennaReduction,
@@ -1065,22 +1062,13 @@ static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
}
- if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
+ ath9k_hw_set_4k_power_per_rate_table(ah, chan,
&ratesArray[0], cfgCtl,
twiceAntennaReduction,
twiceMaxRegulatoryPower,
- powerLimit)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set "
- "tx power per rate table\n");
- return -EIO;
- }
+ powerLimit);
- if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set power table\n");
- return -EIO;
- }
+ ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
@@ -1168,7 +1156,6 @@ static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
else
ah->regulatory.max_power_level = ratesArray[i];
- return 0;
}
static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
@@ -2103,7 +2090,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
return;
}
-static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
+static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *pTxPowerIndexOffset)
{
@@ -2234,11 +2221,11 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
((pdadcValues[4 * j + 3] & 0xFF) << 24);
REG_WRITE(ah, regOffset, reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PDADC (%d,%4x): %4.4x %8.8x\n",
i, regChainOffset, regOffset,
reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PDADC: Chain %d | PDADC %3d "
"Value %3d | PDADC %3d Value %3d | "
"PDADC %3d Value %3d | PDADC %3d "
@@ -2255,13 +2242,11 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
}
*pTxPowerIndexOffset = 0;
-
- return true;
#undef SM_PD_GAIN
#undef SM_PDGAIN_B
}
-static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
+static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *ratesArray,
u16 cfgCtl,
@@ -2415,14 +2400,14 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
ah->eep_ops->get_eeprom_rev(ah) <= 2)
twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
"EXT_ADDITIVE %d\n",
ctlMode, numCtlModes, isHt40CtlMode,
(pCtlMode[ctlMode] & EXT_ADDITIVE));
for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
"pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
"chan %d\n",
@@ -2441,7 +2426,7 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" MATCH-EE_IDX %d: ch %d is2 %d "
"2xMinEdge %d chainmask %d chains %d\n",
i, freq, IS_CHAN_2GHZ(chan),
@@ -2460,7 +2445,7 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
minCtlPower = min(twiceMaxEdgePower, scaledPower);
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" SEL-Min ctlMode %d pCtlMode %d "
"2xMaxEdge %d sP %d minCtlPwr %d\n",
ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
@@ -2549,10 +2534,9 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
targetPowerCckExt.tPow2x[0];
}
}
- return true;
}
-static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
+static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan,
u16 cfgCtl,
u8 twiceAntennaReduction,
@@ -2575,22 +2559,13 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
}
- if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
+ ath9k_hw_set_def_power_per_rate_table(ah, chan,
&ratesArray[0], cfgCtl,
twiceAntennaReduction,
twiceMaxRegulatoryPower,
- powerLimit)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set "
- "tx power per rate table\n");
- return -EIO;
- }
+ powerLimit);
- if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set power table\n");
- return -EIO;
- }
+ ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
@@ -2717,8 +2692,6 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
"Invalid chainmask configuration\n");
break;
}
-
- return 0;
}
static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 25b68c881ff1..67b8bd12941a 100644
--- a/drivers/net/wireless/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -17,6 +17,8 @@
#ifndef EEPROM_H
#define EEPROM_H
+#include <net/cfg80211.h>
+
#define AH_USE_EEPROM 0x1
#ifdef __BIG_ENDIAN
@@ -492,7 +494,7 @@ struct eeprom_ops {
struct ath9k_channel *chan);
void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
- int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
+ void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
u16 cfgCtl, u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower, u8 powerLimit);
u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index b15eaf8417ff..4acfab514916 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -84,6 +84,38 @@ static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
return ath9k_hw_mac_clks(ah, usecs);
}
+/*
+ * Read and write, they both share the same lock. We do this to serialize
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
+ * as the FIFO on these devices can only accept sanely 2 requests. After
+ * that the device goes bananas. Serializing the reads/writes prevents this
+ * from happening.
+ */
+
+void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
+{
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+ unsigned long flags;
+ spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+ iowrite32(val, ah->ah_sc->mem + reg_offset);
+ spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+ } else
+ iowrite32(val, ah->ah_sc->mem + reg_offset);
+}
+
+unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
+{
+ u32 val;
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+ unsigned long flags;
+ spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+ val = ioread32(ah->ah_sc->mem + reg_offset);
+ spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+ } else
+ val = ioread32(ah->ah_sc->mem + reg_offset);
+ return val;
+}
+
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
{
int i;
@@ -97,7 +129,7 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
udelay(AH_TIME_QUANTUM);
}
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
timeout, reg, REG_READ(ah, reg), mask, val);
@@ -136,7 +168,7 @@ bool ath9k_get_channel_edges(struct ath_hw *ah,
}
u16 ath9k_hw_computetxtime(struct ath_hw *ah,
- struct ath_rate_table *rates,
+ const struct ath_rate_table *rates,
u32 frameLen, u16 rateix,
bool shortPreamble)
{
@@ -181,7 +213,7 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
}
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Unknown phy %u (rate ix %u)\n",
rates->info[rateix].phy, rateix);
txTime = 0;
@@ -306,7 +338,7 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
REG_WRITE(ah, addr, wrData);
rdData = REG_READ(ah, addr);
if (rdData != wrData) {
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"address test failed "
"addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
addr, wrData, rdData);
@@ -318,7 +350,7 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
REG_WRITE(ah, addr, wrData);
rdData = REG_READ(ah, addr);
if (wrData != rdData) {
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"address test failed "
"addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
addr, wrData, rdData);
@@ -363,10 +395,7 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah)
ah->config.ack_6mb = 0x0;
ah->config.cwm_ignore_extcca = 0;
ah->config.pcie_powersave_enable = 0;
- ah->config.pcie_l1skp_enable = 0;
ah->config.pcie_clock_req = 0;
- ah->config.pcie_power_reset = 0x100;
- ah->config.pcie_restore = 0;
ah->config.pcie_waen = 0;
ah->config.analog_shiftreg = 1;
ah->config.ht_enable = 1;
@@ -375,13 +404,6 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah)
ah->config.cck_trig_high = 200;
ah->config.cck_trig_low = 100;
ah->config.enable_ani = 1;
- ah->config.noise_immunity_level = 4;
- ah->config.ofdm_weaksignal_det = 1;
- ah->config.cck_weaksignal_thr = 0;
- ah->config.spur_immunity_level = 2;
- ah->config.firstep_level = 0;
- ah->config.rssi_thr_high = 40;
- ah->config.rssi_thr_low = 7;
ah->config.diversity_control = 0;
ah->config.antenna_switch_swap = 0;
@@ -390,7 +412,7 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah)
ah->config.spurchans[i][1] = AR_NO_SPUR;
}
- ah->config.intr_mitigation = 1;
+ ah->config.intr_mitigation = true;
/*
* We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -463,8 +485,8 @@ static int ath9k_hw_rfattach(struct ath_hw *ah)
rfStatus = ath9k_hw_init_rf(ah, &ecode);
if (!rfStatus) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
- "RF setup failed, status %u\n", ecode);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "RF setup failed, status: %u\n", ecode);
return ecode;
}
@@ -488,10 +510,9 @@ static int ath9k_hw_rf_claim(struct ath_hw *ah)
case AR_RAD2122_SREV_MAJOR:
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "5G Radio Chip Rev 0x%02X is not "
- "supported by this driver\n",
- ah->hw_version.analog5GhzRev);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "Radio Chip Rev 0x%02X not supported\n",
+ val & AR_RADIO_SREV_MAJOR);
return -EOPNOTSUPP;
}
@@ -513,12 +534,8 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
ah->macaddr[2 * i] = eeval >> 8;
ah->macaddr[2 * i + 1] = eeval & 0xff;
}
- if (sum == 0 || sum == 0xffff * 3) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "mac address read failed: %pM\n",
- ah->macaddr);
+ if (sum == 0 || sum == 0xffff * 3)
return -EADDRNOTAVAIL;
- }
return 0;
}
@@ -575,11 +592,8 @@ static int ath9k_hw_post_attach(struct ath_hw *ah)
{
int ecode;
- if (!ath9k_hw_chip_test(ah)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
- "hardware self-test failed\n");
+ if (!ath9k_hw_chip_test(ah))
return -ENODEV;
- }
ecode = ath9k_hw_rf_claim(ah);
if (ecode != 0)
@@ -617,17 +631,14 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
ath9k_hw_set_defaults(ah);
- if (ah->config.intr_mitigation != 0)
- ah->intr_mitigation = true;
-
if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
- DPRINTF(sc, ATH_DBG_RESET, "Couldn't reset chip\n");
+ DPRINTF(sc, ATH_DBG_FATAL, "Couldn't reset chip\n");
ecode = -EIO;
goto bad;
}
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
- DPRINTF(sc, ATH_DBG_RESET, "Couldn't wakeup chip\n");
+ DPRINTF(sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
ecode = -EIO;
goto bad;
}
@@ -650,7 +661,7 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
(ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
(ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
(!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
- DPRINTF(sc, ATH_DBG_RESET,
+ DPRINTF(sc, ATH_DBG_FATAL,
"Mac Chip Rev 0x%02x.%x is not supported by "
"this driver\n", ah->hw_version.macVersion,
ah->hw_version.macRev);
@@ -690,10 +701,6 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if (AR_SREV_9280_10_OR_LATER(ah))
ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
- DPRINTF(sc, ATH_DBG_RESET,
- "This Mac Chip Rev 0x%02x.%x is \n",
- ah->hw_version.macVersion, ah->hw_version.macRev);
-
if (AR_SREV_9285_12_OR_LATER(ah)) {
INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
@@ -859,11 +866,7 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if (AR_SREV_9280_20(ah))
ath9k_hw_init_txgain_ini(ah);
- if (!ath9k_hw_fill_cap_info(ah)) {
- DPRINTF(sc, ATH_DBG_RESET, "failed ath9k_hw_fill_cap_info\n");
- ecode = -EINVAL;
- goto bad;
- }
+ ath9k_hw_fill_cap_info(ah);
if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
@@ -885,8 +888,8 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
ecode = ath9k_hw_init_macaddr(ah);
if (ecode != 0) {
- DPRINTF(sc, ATH_DBG_RESET,
- "failed initializing mac address\n");
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Failed to initialize MAC address\n");
goto bad;
}
@@ -1054,7 +1057,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
AR_IMR_RXORN |
AR_IMR_BCNMISC;
- if (ah->intr_mitigation)
+ if (ah->config.intr_mitigation)
ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
else
ah->mask_reg |= AR_IMR_RXOK;
@@ -1203,23 +1206,23 @@ static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
switch (ah->hw_version.devid) {
case AR9280_DEVID_PCI:
if (reg == 0x7894) {
- DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"ini VAL: %x EEPROM: %x\n", value,
(pBase->version & 0xff));
if ((pBase->version & 0xff) > 0x0a) {
- DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PWDCLKIND: %d\n",
pBase->pwdclkind);
value &= ~AR_AN_TOP2_PWDCLKIND;
value |= AR_AN_TOP2_PWDCLKIND &
(pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
} else {
- DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PWDCLKIND Earlier Rev\n");
}
- DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"final ini VAL: %x\n", value);
}
break;
@@ -1249,6 +1252,21 @@ static void ath9k_olc_init(struct ath_hw *ah)
ah->PDADCdelta = 0;
}
+static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
+ struct ath9k_channel *chan)
+{
+ u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
+
+ if (IS_CHAN_B(chan))
+ ctl |= CTL_11B;
+ else if (IS_CHAN_G(chan))
+ ctl |= CTL_11G;
+ else
+ ctl |= CTL_11A;
+
+ return ctl;
+}
+
static int ath9k_hw_process_ini(struct ath_hw *ah,
struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
@@ -1256,7 +1274,6 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
int i, regWrites = 0;
struct ieee80211_channel *channel = chan->chan;
u32 modesIndex, freqIndex;
- int status;
switch (chan->chanmode) {
case CHANNEL_A:
@@ -1327,8 +1344,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
if (AR_SREV_9280(ah))
REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
- if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) &&
- AR_SREV_9285_12_OR_LATER(ah)))
+ if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah))
REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
for (i = 0; i < ah->iniCommon.ia_rows; i++) {
@@ -1359,20 +1375,15 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
if (OLC_FOR_AR9280_20_LATER)
ath9k_olc_init(ah);
- status = ah->eep_ops->set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
- channel->max_antenna_gain * 2,
- channel->max_power * 2,
- min((u32) MAX_RATE_POWER,
- (u32) ah->regulatory.power_limit));
- if (status != 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- "error init'ing transmit power\n");
- return -EIO;
- }
+ ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(&ah->regulatory, chan),
+ channel->max_antenna_gain * 2,
+ channel->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) ah->regulatory.power_limit));
if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"ar5416SetRfRegs failed\n");
return -EIO;
}
@@ -1600,11 +1611,9 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
switch (type) {
case ATH9K_RESET_POWER_ON:
return ath9k_hw_set_reset_power_on(ah);
- break;
case ATH9K_RESET_WARM:
case ATH9K_RESET_COLD:
return ath9k_hw_set_reset(ah, type);
- break;
default:
return false;
}
@@ -1678,7 +1687,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Could not kill baseband RX\n");
return false;
}
@@ -1686,29 +1695,21 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
ath9k_hw_set_regs(ah, chan, macmode);
if (AR_SREV_9280_10_OR_LATER(ah)) {
- if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "failed to set channel\n");
- return false;
- }
+ ath9k_hw_ar9280_set_channel(ah, chan);
} else {
if (!(ath9k_hw_set_channel(ah, chan))) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "failed to set channel\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "Failed to set channel\n");
return false;
}
}
- if (ah->eep_ops->set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
+ ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(&ah->regulatory, chan),
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
- (u32) ah->regulatory.power_limit)) != 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "error init'ing transmit power\n");
- return false;
- }
+ (u32) ah->regulatory.power_limit));
synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
if (IS_CHAN_B(chan))
@@ -2199,14 +2200,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ah->txchainmask = sc->tx_chainmask;
ah->rxchainmask = sc->rx_chainmask;
- if (AR_SREV_9285(ah)) {
- ah->txchainmask &= 0x1;
- ah->rxchainmask &= 0x1;
- } else if (AR_SREV_9280(ah)) {
- ah->txchainmask &= 0x3;
- ah->rxchainmask &= 0x3;
- }
-
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return -EIO;
@@ -2242,7 +2235,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_mark_phy_inactive(ah);
if (!ath9k_hw_chip_reset(ah, chan)) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n");
return -EINVAL;
}
@@ -2304,13 +2297,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
- return -EIO;
- } else {
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ath9k_hw_ar9280_set_channel(ah, chan);
+ else
if (!(ath9k_hw_set_channel(ah, chan)))
return -EIO;
- }
for (i = 0; i < AR_NUM_DCU; i++)
REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
@@ -2335,8 +2326,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_OBS, 8);
- if (ah->intr_mitigation) {
-
+ if (ah->config.intr_mitigation) {
REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
}
@@ -2385,8 +2375,8 @@ bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
u32 keyType;
if (entry >= ah->caps.keycache_size) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
- "entry %u out of range\n", entry);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "keychache entry %u out of range\n", entry);
return false;
}
@@ -2422,8 +2412,8 @@ bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
u32 macHi, macLo;
if (entry >= ah->caps.keycache_size) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
- "entry %u out of range\n", entry);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "keychache entry %u out of range\n", entry);
return false;
}
@@ -2454,8 +2444,8 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
u32 keyType;
if (entry >= pCap->keycache_size) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
- "entry %u out of range\n", entry);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "keycache entry %u out of range\n", entry);
return false;
}
@@ -2465,7 +2455,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
break;
case ATH9K_CIPHER_AES_CCM:
if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+ DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"AES-CCM not supported by mac rev 0x%x\n",
ah->hw_version.macRev);
return false;
@@ -2476,14 +2466,14 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
keyType = AR_KEYTABLE_TYPE_TKIP;
if (ATH9K_IS_MIC_ENABLED(ah)
&& entry + 64 >= pCap->keycache_size) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+ DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"entry %u inappropriate for TKIP\n", entry);
return false;
}
break;
case ATH9K_CIPHER_WEP:
if (k->kv_len < LEN_WEP40) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+ DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"WEP key length %u too small\n", k->kv_len);
return false;
}
@@ -2498,7 +2488,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
keyType = AR_KEYTABLE_TYPE_CLR;
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"cipher %u not supported\n", k->kv_type);
return false;
}
@@ -2716,7 +2706,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
AR_RTC_FORCE_WAKE_EN);
}
if (i == 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Failed to wakeup in %uus\n", POWER_UP_TIME / 20);
return false;
}
@@ -2737,9 +2727,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
"UNDEFINED"
};
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n",
- modes[ah->power_mode], modes[mode],
- setChip ? "set chip " : "");
+ DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n",
+ modes[ah->power_mode], modes[mode]);
switch (mode) {
case ATH9K_PM_AWAKE:
@@ -2753,7 +2742,7 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
ath9k_set_power_network_sleep(ah, setChip);
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Unknown power mode %u\n", mode);
return false;
}
@@ -2943,7 +2932,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
*masked = isr & ATH9K_INT_COMMON;
- if (ah->intr_mitigation) {
+ if (ah->config.intr_mitigation) {
if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
*masked |= ATH9K_INT_RX;
}
@@ -3000,6 +2989,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"received PCI PERR interrupt\n");
}
+ *masked |= ATH9K_INT_FATAL;
}
if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
@@ -3061,7 +3051,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
}
if (ints & ATH9K_INT_RX) {
mask |= AR_IMR_RXERR;
- if (ah->intr_mitigation)
+ if (ah->config.intr_mitigation)
mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
else
mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
@@ -3259,7 +3249,7 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
/* HW Capabilities */
/*******************/
-bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
+void ath9k_hw_fill_cap_info(struct ath_hw *ah)
{
struct ath9k_hw_capabilities *pCap = &ah->caps;
u16 capField = 0, eeval;
@@ -3343,8 +3333,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
- pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
-
if (ah->config.ht_enable)
pCap->hw_caps |= ATH9K_HW_CAP_HT;
else
@@ -3368,7 +3356,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->keycache_size = AR_KEYTABLE_SIZE;
pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
- pCap->num_mr_retries = 4;
pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
if (AR_SREV_9285_10_OR_LATER(ah))
@@ -3378,14 +3365,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
else
pCap->num_gpio_pins = AR_NUM_GPIO;
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- pCap->hw_caps |= ATH9K_HW_CAP_WOW;
- pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
- } else {
- pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
- pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
- }
-
if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
pCap->hw_caps |= ATH9K_HW_CAP_CST;
pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
@@ -3411,7 +3390,8 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
(ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
(ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
(ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
- (ah->hw_version.macVersion == AR_SREV_VERSION_9280))
+ (ah->hw_version.macVersion == AR_SREV_VERSION_9280) ||
+ (ah->hw_version.macVersion == AR_SREV_VERSION_9285))
pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
else
pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
@@ -3445,8 +3425,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
ah->btactive_gpio = 6;
ah->wlanactive_gpio = 5;
}
-
- return true;
}
bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
@@ -3754,22 +3732,19 @@ bool ath9k_hw_disable(struct ath_hw *ah)
return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
}
-bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
{
struct ath9k_channel *chan = ah->curchan;
struct ieee80211_channel *channel = chan->chan;
ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
- if (ah->eep_ops->set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
- channel->max_antenna_gain * 2,
- channel->max_power * 2,
- min((u32) MAX_RATE_POWER,
- (u32) ah->regulatory.power_limit)) != 0)
- return false;
-
- return true;
+ ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(&ah->regulatory, chan),
+ channel->max_antenna_gain * 2,
+ channel->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) ah->regulatory.power_limit));
}
void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 0b594e0ee260..dd8508ef6e05 100644
--- a/drivers/net/wireless/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -25,10 +25,11 @@
#include "ani.h"
#include "eeprom.h"
#include "calib.h"
-#include "regd.h"
#include "reg.h"
#include "phy.h"
+#include "../regd.h"
+
#define ATHEROS_VENDOR_ID 0x168c
#define AR5416_DEVID_PCI 0x0023
#define AR5416_DEVID_PCIE 0x0024
@@ -124,29 +125,24 @@ enum wireless_mode {
};
enum ath9k_hw_caps {
- ATH9K_HW_CAP_CHAN_SPREAD = BIT(0),
- ATH9K_HW_CAP_MIC_AESCCM = BIT(1),
- ATH9K_HW_CAP_MIC_CKIP = BIT(2),
- ATH9K_HW_CAP_MIC_TKIP = BIT(3),
- ATH9K_HW_CAP_CIPHER_AESCCM = BIT(4),
- ATH9K_HW_CAP_CIPHER_CKIP = BIT(5),
- ATH9K_HW_CAP_CIPHER_TKIP = BIT(6),
- ATH9K_HW_CAP_VEOL = BIT(7),
- ATH9K_HW_CAP_BSSIDMASK = BIT(8),
- ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(9),
- ATH9K_HW_CAP_CHAN_HALFRATE = BIT(10),
- ATH9K_HW_CAP_CHAN_QUARTERRATE = BIT(11),
- ATH9K_HW_CAP_HT = BIT(12),
- ATH9K_HW_CAP_GTT = BIT(13),
- ATH9K_HW_CAP_FASTCC = BIT(14),
- ATH9K_HW_CAP_RFSILENT = BIT(15),
- ATH9K_HW_CAP_WOW = BIT(16),
- ATH9K_HW_CAP_CST = BIT(17),
- ATH9K_HW_CAP_ENHANCEDPM = BIT(18),
- ATH9K_HW_CAP_AUTOSLEEP = BIT(19),
- ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20),
- ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21),
- ATH9K_HW_CAP_BT_COEX = BIT(22)
+ ATH9K_HW_CAP_MIC_AESCCM = BIT(0),
+ ATH9K_HW_CAP_MIC_CKIP = BIT(1),
+ ATH9K_HW_CAP_MIC_TKIP = BIT(2),
+ ATH9K_HW_CAP_CIPHER_AESCCM = BIT(3),
+ ATH9K_HW_CAP_CIPHER_CKIP = BIT(4),
+ ATH9K_HW_CAP_CIPHER_TKIP = BIT(5),
+ ATH9K_HW_CAP_VEOL = BIT(6),
+ ATH9K_HW_CAP_BSSIDMASK = BIT(7),
+ ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(8),
+ ATH9K_HW_CAP_HT = BIT(9),
+ ATH9K_HW_CAP_GTT = BIT(10),
+ ATH9K_HW_CAP_FASTCC = BIT(11),
+ ATH9K_HW_CAP_RFSILENT = BIT(12),
+ ATH9K_HW_CAP_CST = BIT(13),
+ ATH9K_HW_CAP_ENHANCEDPM = BIT(14),
+ ATH9K_HW_CAP_AUTOSLEEP = BIT(15),
+ ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16),
+ ATH9K_HW_CAP_BT_COEX = BIT(17)
};
enum ath9k_capability_type {
@@ -166,7 +162,6 @@ struct ath9k_hw_capabilities {
u16 keycache_size;
u16 low_5ghz_chan, high_5ghz_chan;
u16 low_2ghz_chan, high_2ghz_chan;
- u16 num_mr_retries;
u16 rts_aggr_limit;
u8 tx_chainmask;
u8 rx_chainmask;
@@ -184,11 +179,8 @@ struct ath9k_ops_config {
int ack_6mb;
int cwm_ignore_extcca;
u8 pcie_powersave_enable;
- u8 pcie_l1skp_enable;
u8 pcie_clock_req;
u32 pcie_waen;
- int pcie_power_reset;
- u8 pcie_restore;
u8 analog_shiftreg;
u8 ht_enable;
u32 ofdm_trig_low;
@@ -196,17 +188,10 @@ struct ath9k_ops_config {
u32 cck_trig_high;
u32 cck_trig_low;
u32 enable_ani;
- u8 noise_immunity_level;
- u32 ofdm_weaksignal_det;
- u32 cck_weaksignal_thr;
- u8 spur_immunity_level;
- u8 firstep_level;
- int8_t rssi_thr_high;
- int8_t rssi_thr_low;
u16 diversity_control;
u16 antenna_switch_swap;
int serialize_regmode;
- int intr_mitigation;
+ bool intr_mitigation;
#define SPUR_DISABLE 0
#define SPUR_ENABLE_IOCTL 1
#define SPUR_ENABLE_EEPROM 2
@@ -281,13 +266,6 @@ enum ath9k_int {
#define CHANNEL_HT40PLUS 0x20000
#define CHANNEL_HT40MINUS 0x40000
-#define CHANNEL_INTERFERENCE 0x01
-#define CHANNEL_DFS 0x02
-#define CHANNEL_4MS_LIMIT 0x04
-#define CHANNEL_DFS_CLEAR 0x08
-#define CHANNEL_DISALLOW_ADHOC 0x10
-#define CHANNEL_PER_11D_ADHOC 0x20
-
#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
@@ -318,10 +296,6 @@ struct ath9k_channel {
int16_t rawNoiseFloor;
};
-#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
- (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
- (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
- (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
(((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
(((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
@@ -329,7 +303,6 @@ struct ath9k_channel {
#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
-#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
#define IS_CHAN_A_5MHZ_SPACED(_c) \
@@ -420,7 +393,7 @@ struct ath_hw {
struct ath9k_hw_version hw_version;
struct ath9k_ops_config config;
struct ath9k_hw_capabilities caps;
- struct ath9k_regulatory regulatory;
+ struct ath_regulatory regulatory;
struct ath9k_channel channels[38];
struct ath9k_channel *curchan;
@@ -463,14 +436,14 @@ struct ath_hw {
enum ath9k_ant_setting diversity_control;
/* Calibration */
- enum hal_cal_types supp_cals;
- struct hal_cal_list iq_caldata;
- struct hal_cal_list adcgain_caldata;
- struct hal_cal_list adcdc_calinitdata;
- struct hal_cal_list adcdc_caldata;
- struct hal_cal_list *cal_list;
- struct hal_cal_list *cal_list_last;
- struct hal_cal_list *cal_list_curr;
+ enum ath9k_cal_types supp_cals;
+ struct ath9k_cal_list iq_caldata;
+ struct ath9k_cal_list adcgain_caldata;
+ struct ath9k_cal_list adcdc_calinitdata;
+ struct ath9k_cal_list adcdc_caldata;
+ struct ath9k_cal_list *cal_list;
+ struct ath9k_cal_list *cal_list_last;
+ struct ath9k_cal_list *cal_list_curr;
#define totalPowerMeasI meas0.unsign
#define totalPowerMeasQ meas1.unsign
#define totalIqCorrMeas meas2.sign
@@ -540,7 +513,6 @@ struct ath_hw {
enum ath9k_ani_cmd ani_function;
u32 intr_txqs;
- bool intr_mitigation;
enum ath9k_ht_extprotspacing extprotspacing;
u8 txchainmask;
u8 rxchainmask;
@@ -573,7 +545,7 @@ struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
void ath9k_hw_rfdetach(struct ath_hw *ah);
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
bool bChannelChange);
-bool ath9k_hw_fill_cap_info(struct ath_hw *ah);
+void ath9k_hw_fill_cap_info(struct ath_hw *ah);
bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
u32 capability, u32 *result);
bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
@@ -608,7 +580,8 @@ bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
u32 ath9k_hw_reverse_bits(u32 val, u32 n);
bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
-u16 ath9k_hw_computetxtime(struct ath_hw *ah, struct ath_rate_table *rates,
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
+ const struct ath_rate_table *rates,
u32 frameLen, u16 rateix, bool shortPreamble);
void ath9k_hw_get_channel_centers(struct ath_hw *ah,
struct ath9k_channel *chan,
@@ -617,7 +590,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
bool ath9k_hw_phy_disable(struct ath_hw *ah);
bool ath9k_hw_disable(struct ath_hw *ah);
-bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
void ath9k_hw_setopmode(struct ath_hw *ah);
void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
index e2f0a34b79a1..e2f0a34b79a1 100644
--- a/drivers/net/wireless/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/initvals.h
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index e0a6dee45839..8ae4ec21667b 100644
--- a/drivers/net/wireless/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -49,7 +49,7 @@ bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
{
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q);
REG_WRITE(ah, AR_Q_TXE, 1 << q);
@@ -110,13 +110,15 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
+ "invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
+ "inactive queue: %u\n", q);
return false;
}
@@ -146,7 +148,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
break;
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
- "TSF have moved while trying to set "
+ "TSF has moved while trying to set "
"quiet time TSF: 0x%08x\n", tsfLow);
}
@@ -158,8 +160,8 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
wait = wait_time;
while (ath9k_hw_numtxpending(ah, q)) {
if ((--wait) == 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
- "Failed to stop Tx DMA in 100 "
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+ "Failed to stop TX DMA in 100 "
"msec after killing last frame\n");
break;
}
@@ -454,17 +456,19 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
+ "invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
+ "inactive queue: %u\n", q);
return false;
}
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %p\n", qi);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
qi->tqi_ver = qinfo->tqi_ver;
qi->tqi_subtype = qinfo->tqi_subtype;
@@ -521,13 +525,15 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
+ "invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
+ "inactive queue: %u\n", q);
return false;
}
@@ -575,22 +581,23 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
ATH9K_TX_QUEUE_INACTIVE)
break;
if (q == pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
- "no available tx queue\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "No available TX queue\n");
return -1;
}
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "bad tx queue type %u\n", type);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid TX queue type: %u\n",
+ type);
return -1;
}
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
qi = &ah->txq[q];
if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
- "tx queue %u already active\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "TX queue: %u already active\n", q);
return -1;
}
memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
@@ -620,16 +627,18 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
+ "invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
+ "inactive queue: %u\n", q);
return false;
}
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
ah->txok_interrupt_mask &= ~(1 << q);
@@ -650,17 +659,19 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
u32 cwMin, chanCwMin, value;
if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
+ "invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
+ "inactive queue: %u\n", q);
return true;
}
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "reset queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
if (chan && IS_CHAN_B(chan))
@@ -894,7 +905,7 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
reg = REG_READ(ah, AR_OBS_BUS_1);
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
- "rx failed to go idle in 10 ms RXSM=0x%x\n", reg);
+ "RX failed to go idle in 10 ms RXSM=0x%x\n", reg);
return false;
}
@@ -949,8 +960,8 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
}
if (i == 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
- "dma failed to stop in %d ms "
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "DMA failed to stop in %d ms "
"AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
AH_RX_STOP_DMA_TIMEOUT / 1000,
REG_READ(ah, AR_CR),
diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 1176bce8b76c..1176bce8b76c 100644
--- a/drivers/net/wireless/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 13d4e6756c99..175ed5358baf 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -189,7 +189,7 @@ static u8 parse_mpdudensity(u8 mpdudensity)
static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
{
- struct ath_rate_table *rate_table = NULL;
+ const struct ath_rate_table *rate_table = NULL;
struct ieee80211_supported_band *sband;
struct ieee80211_rate *rate;
int i, maxrates;
@@ -287,7 +287,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
}
spin_unlock_bh(&sc->sc_resetlock);
- sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
sc->sc_flags &= ~SC_OP_FULL_RESET;
if (ath_startrecv(sc) != 0) {
@@ -368,28 +367,16 @@ static void ath_ani_calibrate(unsigned long data)
/* Perform calibration if necessary */
if (longcal || shortcal) {
- bool iscaldone = false;
-
- if (ath9k_hw_calibrate(ah, ah->curchan,
- sc->rx_chainmask, longcal,
- &iscaldone)) {
- if (longcal)
- sc->ani.noise_floor =
- ath9k_hw_getchan_noise(ah,
- ah->curchan);
-
- DPRINTF(sc, ATH_DBG_ANI,
- "calibrate chan %u/%x nf: %d\n",
- ah->curchan->channel,
- ah->curchan->channelFlags,
- sc->ani.noise_floor);
- } else {
- DPRINTF(sc, ATH_DBG_ANY,
- "calibrate chan %u/%x failed\n",
- ah->curchan->channel,
- ah->curchan->channelFlags);
- }
- sc->ani.caldone = iscaldone;
+ sc->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan,
+ sc->rx_chainmask, longcal);
+
+ if (longcal)
+ sc->ani.noise_floor = ath9k_hw_getchan_noise(ah,
+ ah->curchan);
+
+ DPRINTF(sc, ATH_DBG_ANI," calibrate chan %u/%x nf: %d\n",
+ ah->curchan->channel, ah->curchan->channelFlags,
+ sc->ani.noise_floor);
}
}
@@ -408,6 +395,18 @@ set_timer:
mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
}
+static void ath_start_ani(struct ath_softc *sc)
+{
+ unsigned long timestamp = jiffies_to_msecs(jiffies);
+
+ sc->ani.longcal_timer = timestamp;
+ sc->ani.shortcal_timer = timestamp;
+ sc->ani.checkani_timer = timestamp;
+
+ mod_timer(&sc->ani.timer,
+ jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+}
+
/*
* Update tx/rx chainmask. For legacy association,
* hard code chainmask to 1x1, for 11n association, use
@@ -416,7 +415,6 @@ set_timer:
*/
void ath_update_chainmask(struct ath_softc *sc, int is_ht)
{
- sc->sc_flags |= SC_OP_CHAINMASK_UPDATE;
if (is_ht ||
(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
@@ -436,12 +434,12 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
an = (struct ath_node *)sta->drv_priv;
- if (sc->sc_flags & SC_OP_TXAGGR)
+ if (sc->sc_flags & SC_OP_TXAGGR) {
ath_tx_node_init(sc, an);
-
- an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
- sta->ht_cap.ampdu_factor);
- an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
+ an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
+ sta->ht_cap.ampdu_factor);
+ an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
+ }
}
static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
@@ -458,133 +456,124 @@ static void ath9k_tasklet(unsigned long data)
u32 status = sc->intrstatus;
if (status & ATH9K_INT_FATAL) {
- /* need a chip reset */
ath_reset(sc, false);
return;
- } else {
+ }
- if (status &
- (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
- spin_lock_bh(&sc->rx.rxflushlock);
- ath_rx_tasklet(sc, 0);
- spin_unlock_bh(&sc->rx.rxflushlock);
- }
- /* XXX: optimize this */
- if (status & ATH9K_INT_TX)
- ath_tx_tasklet(sc);
+ if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
+ spin_lock_bh(&sc->rx.rxflushlock);
+ ath_rx_tasklet(sc, 0);
+ spin_unlock_bh(&sc->rx.rxflushlock);
}
+ if (status & ATH9K_INT_TX)
+ ath_tx_tasklet(sc);
+
/* re-enable hardware interrupt */
ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
}
irqreturn_t ath_isr(int irq, void *dev)
{
+#define SCHED_INTR ( \
+ ATH9K_INT_FATAL | \
+ ATH9K_INT_RXORN | \
+ ATH9K_INT_RXEOL | \
+ ATH9K_INT_RX | \
+ ATH9K_INT_TX | \
+ ATH9K_INT_BMISS | \
+ ATH9K_INT_CST | \
+ ATH9K_INT_TSFOOR)
+
struct ath_softc *sc = dev;
struct ath_hw *ah = sc->sc_ah;
enum ath9k_int status;
bool sched = false;
- do {
- if (sc->sc_flags & SC_OP_INVALID) {
- /*
- * The hardware is not ready/present, don't
- * touch anything. Note this can happen early
- * on if the IRQ is shared.
- */
- return IRQ_NONE;
- }
- if (!ath9k_hw_intrpend(ah)) { /* shared irq, not for us */
- return IRQ_NONE;
- }
+ /*
+ * The hardware is not ready/present, don't
+ * touch anything. Note this can happen early
+ * on if the IRQ is shared.
+ */
+ if (sc->sc_flags & SC_OP_INVALID)
+ return IRQ_NONE;
- /*
- * Figure out the reason(s) for the interrupt. Note
- * that the hal returns a pseudo-ISR that may include
- * bits we haven't explicitly enabled so we mask the
- * value to insure we only process bits we requested.
- */
- ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
+ ath9k_ps_wakeup(sc);
+
+ /* shared irq, not for us */
+
+ if (!ath9k_hw_intrpend(ah)) {
+ ath9k_ps_restore(sc);
+ return IRQ_NONE;
+ }
+
+ /*
+ * Figure out the reason(s) for the interrupt. Note
+ * that the hal returns a pseudo-ISR that may include
+ * bits we haven't explicitly enabled so we mask the
+ * value to insure we only process bits we requested.
+ */
+ ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
+ status &= sc->imask; /* discard unasked-for bits */
- status &= sc->imask; /* discard unasked-for bits */
+ /*
+ * If there are no status bits set, then this interrupt was not
+ * for me (should have been caught above).
+ */
+ if (!status) {
+ ath9k_ps_restore(sc);
+ return IRQ_NONE;
+ }
+
+ /* Cache the status */
+ sc->intrstatus = status;
+
+ if (status & SCHED_INTR)
+ sched = true;
+
+ /*
+ * If a FATAL or RXORN interrupt is received, we have to reset the
+ * chip immediately.
+ */
+ if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN))
+ goto chip_reset;
+ if (status & ATH9K_INT_SWBA)
+ tasklet_schedule(&sc->bcon_tasklet);
+
+ if (status & ATH9K_INT_TXURN)
+ ath9k_hw_updatetxtriglevel(ah, true);
+
+ if (status & ATH9K_INT_MIB) {
/*
- * If there are no status bits set, then this interrupt was not
- * for me (should have been caught above).
+ * Disable interrupts until we service the MIB
+ * interrupt; otherwise it will continue to
+ * fire.
*/
- if (!status)
- return IRQ_NONE;
-
- sc->intrstatus = status;
- ath9k_ps_wakeup(sc);
+ ath9k_hw_set_interrupts(ah, 0);
+ /*
+ * Let the hal handle the event. We assume
+ * it will clear whatever condition caused
+ * the interrupt.
+ */
+ ath9k_hw_procmibevent(ah, &sc->nodestats);
+ ath9k_hw_set_interrupts(ah, sc->imask);
+ }
- if (status & ATH9K_INT_FATAL) {
- /* need a chip reset */
+ if (status & ATH9K_INT_TIM_TIMER) {
+ if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+ /* Clear RxAbort bit so that we can
+ * receive frames */
+ ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
+ ath9k_hw_setrxabort(ah, 0);
sched = true;
- } else if (status & ATH9K_INT_RXORN) {
- /* need a chip reset */
- sched = true;
- } else {
- if (status & ATH9K_INT_SWBA) {
- /* schedule a tasklet for beacon handling */
- tasklet_schedule(&sc->bcon_tasklet);
- }
- if (status & ATH9K_INT_RXEOL) {
- /*
- * NB: the hardware should re-read the link when
- * RXE bit is written, but it doesn't work
- * at least on older hardware revs.
- */
- sched = true;
- }
-
- if (status & ATH9K_INT_TXURN)
- /* bump tx trigger level */
- ath9k_hw_updatetxtriglevel(ah, true);
- /* XXX: optimize this */
- if (status & ATH9K_INT_RX)
- sched = true;
- if (status & ATH9K_INT_TX)
- sched = true;
- if (status & ATH9K_INT_BMISS)
- sched = true;
- /* carrier sense timeout */
- if (status & ATH9K_INT_CST)
- sched = true;
- if (status & ATH9K_INT_MIB) {
- /*
- * Disable interrupts until we service the MIB
- * interrupt; otherwise it will continue to
- * fire.
- */
- ath9k_hw_set_interrupts(ah, 0);
- /*
- * Let the hal handle the event. We assume
- * it will clear whatever condition caused
- * the interrupt.
- */
- ath9k_hw_procmibevent(ah, &sc->nodestats);
- ath9k_hw_set_interrupts(ah, sc->imask);
- }
- if (status & ATH9K_INT_TIM_TIMER) {
- if (!(ah->caps.hw_caps &
- ATH9K_HW_CAP_AUTOSLEEP)) {
- /* Clear RxAbort bit so that we can
- * receive frames */
- ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
- ath9k_hw_setrxabort(ah, 0);
- sched = true;
- sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
- }
- }
- if (status & ATH9K_INT_TSFOOR) {
- /* FIXME: Handle this interrupt for power save */
- sched = true;
- }
+ sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
}
- ath9k_ps_restore(sc);
- } while (0);
+ }
+
+chip_reset:
+ ath9k_ps_restore(sc);
ath_debug_stat_interrupt(sc, status);
if (sched) {
@@ -594,6 +583,8 @@ irqreturn_t ath_isr(int irq, void *dev)
}
return IRQ_HANDLED;
+
+#undef SCHED_INTR
}
static u32 ath_get_extchanmode(struct ath_softc *sc,
@@ -676,7 +667,7 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
/* TX MIC entry failed. No need to proceed further */
- DPRINTF(sc, ATH_DBG_KEYCACHE,
+ DPRINTF(sc, ATH_DBG_FATAL,
"Setting TX MIC Key Failed\n");
return 0;
}
@@ -920,11 +911,9 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
- /* Start ANI */
- mod_timer(&sc->ani.timer,
- jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+ ath_start_ani(sc);
} else {
- DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n");
+ DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
sc->curaid = 0;
}
}
@@ -1098,10 +1087,10 @@ void ath_radio_enable(struct ath_softc *sc)
int r;
ath9k_ps_wakeup(sc);
- spin_lock_bh(&sc->sc_resetlock);
+ ath9k_hw_configpcipowersave(ah, 0);
+ spin_lock_bh(&sc->sc_resetlock);
r = ath9k_hw_reset(ah, ah->curchan, false);
-
if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) ",
@@ -1163,6 +1152,7 @@ void ath_radio_disable(struct ath_softc *sc)
spin_unlock_bh(&sc->sc_resetlock);
ath9k_hw_phy_disable(ah);
+ ath9k_hw_configpcipowersave(ah, 1);
ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
ath9k_ps_restore(sc);
}
@@ -1362,6 +1352,17 @@ void ath_detach(struct ath_softc *sc)
ath9k_ps_restore(sc);
}
+static int ath9k_reg_notifier(struct wiphy *wiphy,
+ struct regulatory_request *request)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_regulatory *reg = &sc->sc_ah->regulatory;
+
+ return ath_reg_notifier_apply(wiphy, request, reg);
+}
+
static int ath_init(u16 devid, struct ath_softc *sc)
{
struct ath_hw *ah = NULL;
@@ -1403,7 +1404,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
/* Get the hardware key cache size. */
sc->keymax = ah->caps.keycache_size;
if (sc->keymax > ATH_KEYMAX) {
- DPRINTF(sc, ATH_DBG_KEYCACHE,
+ DPRINTF(sc, ATH_DBG_ANY,
"Warning, using only %u entries in %u key cache\n",
ATH_KEYMAX, sc->keymax);
sc->keymax = ATH_KEYMAX;
@@ -1416,7 +1417,9 @@ static int ath_init(u16 devid, struct ath_softc *sc)
for (i = 0; i < sc->keymax; i++)
ath9k_hw_keyreset(ah, (u16) i);
- if (ath9k_regd_init(sc->sc_ah))
+ error = ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy,
+ ath9k_reg_notifier);
+ if (error)
goto bad;
/* default to MONITOR mode */
@@ -1545,9 +1548,6 @@ static int ath_init(u16 devid, struct ath_softc *sc)
sc->beacon.bslot_aphy[i] = NULL;
}
- /* save MISC configurations */
- sc->config.swBeaconProcess = 1;
-
/* setup channels and rates */
sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
@@ -1602,9 +1602,6 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
- hw->wiphy->reg_notifier = ath9k_reg_notifier;
- hw->wiphy->strict_regulatory = true;
-
hw->queues = 4;
hw->max_rates = 4;
hw->channel_change_time = 5000;
@@ -1625,8 +1622,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
int ath_attach(u16 devid, struct ath_softc *sc)
{
struct ieee80211_hw *hw = sc->hw;
- const struct ieee80211_regdomain *regd;
int error = 0, i;
+ struct ath_regulatory *reg;
DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
@@ -1634,6 +1631,8 @@ int ath_attach(u16 devid, struct ath_softc *sc)
if (error != 0)
return error;
+ reg = &sc->sc_ah->regulatory;
+
/* get mac address from hardware and set in mac80211 */
SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr);
@@ -1666,31 +1665,14 @@ int ath_attach(u16 devid, struct ath_softc *sc)
goto error_attach;
#endif
- if (ath9k_is_world_regd(sc->sc_ah)) {
- /* Anything applied here (prior to wiphy registration) gets
- * saved on the wiphy orig_* parameters */
- regd = ath9k_world_regdomain(sc->sc_ah);
- hw->wiphy->custom_regulatory = true;
- hw->wiphy->strict_regulatory = false;
- } else {
- /* This gets applied in the case of the absense of CRDA,
- * it's our own custom world regulatory domain, similar to
- * cfg80211's but we enable passive scanning */
- regd = ath9k_default_world_regdomain();
- }
- wiphy_apply_custom_regulatory(hw->wiphy, regd);
- ath9k_reg_apply_radar_flags(hw->wiphy);
- ath9k_reg_apply_world_flags(hw->wiphy, NL80211_REGDOM_SET_BY_DRIVER);
-
INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
sc->wiphy_scheduler_int = msecs_to_jiffies(500);
error = ieee80211_register_hw(hw);
- if (!ath9k_is_world_regd(sc->sc_ah)) {
- error = regulatory_hint(hw->wiphy,
- sc->sc_ah->regulatory.alpha2);
+ if (!ath_is_world_regd(reg)) {
+ error = regulatory_hint(hw->wiphy, reg->alpha2);
if (error)
goto error_attach;
}
@@ -1792,7 +1774,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
goto fail;
}
- dd->dd_name = name;
dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
/*
@@ -1822,7 +1803,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
}
ds = dd->dd_desc;
DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
- dd->dd_name, ds, (u32) dd->dd_desc_len,
+ name, ds, (u32) dd->dd_desc_len,
ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
/* allocate buffers */
@@ -2043,8 +2024,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
* here except setup the interrupt mask.
*/
if (ath_startrecv(sc) != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to start recv logic\n");
+ DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n");
r = -EIO;
goto mutex_unlock;
}
@@ -2257,25 +2237,10 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
sc->imask |= ATH9K_INT_TSFOOR;
}
- /*
- * Some hardware processes the TIM IE and fires an
- * interrupt when the TIM bit is set. For hardware
- * that does, if not overridden by configuration,
- * enable the TIM interrupt when operating as station.
- */
- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
- (conf->type == NL80211_IFTYPE_STATION) &&
- !sc->config.swBeaconProcess)
- sc->imask |= ATH9K_INT_TIM;
-
ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
- if (conf->type == NL80211_IFTYPE_AP) {
- /* TODO: is this a suitable place to start ANI for AP mode? */
- /* Start ANI */
- mod_timer(&sc->ani.timer,
- jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
- }
+ if (conf->type == NL80211_IFTYPE_AP)
+ ath_start_ani(sc);
out:
mutex_unlock(&sc->mutex);
@@ -2326,26 +2291,33 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ieee80211_conf *conf = &hw->conf;
+ struct ath_hw *ah = sc->sc_ah;
mutex_lock(&sc->mutex);
if (changed & IEEE80211_CONF_CHANGE_PS) {
if (conf->flags & IEEE80211_CONF_PS) {
- if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
- sc->imask |= ATH9K_INT_TIM_TIMER;
- ath9k_hw_set_interrupts(sc->sc_ah,
- sc->imask);
+ if (!(ah->caps.hw_caps &
+ ATH9K_HW_CAP_AUTOSLEEP)) {
+ if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
+ sc->imask |= ATH9K_INT_TIM_TIMER;
+ ath9k_hw_set_interrupts(sc->sc_ah,
+ sc->imask);
+ }
+ ath9k_hw_setrxabort(sc->sc_ah, 1);
}
- ath9k_hw_setrxabort(sc->sc_ah, 1);
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
} else {
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
- ath9k_hw_setrxabort(sc->sc_ah, 0);
- sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
- if (sc->imask & ATH9K_INT_TIM_TIMER) {
- sc->imask &= ~ATH9K_INT_TIM_TIMER;
- ath9k_hw_set_interrupts(sc->sc_ah,
- sc->imask);
+ if (!(ah->caps.hw_caps &
+ ATH9K_HW_CAP_AUTOSLEEP)) {
+ ath9k_hw_setrxabort(sc->sc_ah, 0);
+ sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+ if (sc->imask & ATH9K_INT_TIM_TIMER) {
+ sc->imask &= ~ATH9K_INT_TIM_TIMER;
+ ath9k_hw_set_interrupts(sc->sc_ah,
+ sc->imask);
+ }
}
}
}
@@ -2387,114 +2359,6 @@ skip_chan_change:
if (changed & IEEE80211_CONF_CHANGE_POWER)
sc->config.txpowlimit = 2 * conf->power_level;
- /*
- * The HW TSF has to be reset when the beacon interval changes.
- * We set the flag here, and ath_beacon_config_ap() would take this
- * into account when it gets called through the subsequent
- * config_interface() call - with IFCC_BEACON in the changed field.
- */
-
- if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
- sc->sc_flags |= SC_OP_TSF_RESET;
-
- mutex_unlock(&sc->mutex);
-
- return 0;
-}
-
-static int ath9k_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct ath_wiphy *aphy = hw->priv;
- struct ath_softc *sc = aphy->sc;
- struct ath_hw *ah = sc->sc_ah;
- struct ath_vif *avp = (void *)vif->drv_priv;
- u32 rfilt = 0;
- int error, i;
-
- mutex_lock(&sc->mutex);
-
- /* TODO: Need to decide which hw opmode to use for multi-interface
- * cases */
- if (vif->type == NL80211_IFTYPE_AP &&
- ah->opmode != NL80211_IFTYPE_AP) {
- ah->opmode = NL80211_IFTYPE_STATION;
- ath9k_hw_setopmode(ah);
- memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
- sc->curaid = 0;
- ath9k_hw_write_associd(sc);
- /* Request full reset to get hw opmode changed properly */
- sc->sc_flags |= SC_OP_FULL_RESET;
- }
-
- if ((conf->changed & IEEE80211_IFCC_BSSID) &&
- !is_zero_ether_addr(conf->bssid)) {
- switch (vif->type) {
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_MESH_POINT:
- /* Set BSSID */
- memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
- memcpy(avp->bssid, conf->bssid, ETH_ALEN);
- sc->curaid = 0;
- ath9k_hw_write_associd(sc);
-
- /* Set aggregation protection mode parameters */
- sc->config.ath_aggr_prot = 0;
-
- DPRINTF(sc, ATH_DBG_CONFIG,
- "RX filter 0x%x bssid %pM aid 0x%x\n",
- rfilt, sc->curbssid, sc->curaid);
-
- /* need to reconfigure the beacon */
- sc->sc_flags &= ~SC_OP_BEACONS ;
-
- break;
- default:
- break;
- }
- }
-
- if ((vif->type == NL80211_IFTYPE_ADHOC) ||
- (vif->type == NL80211_IFTYPE_AP) ||
- (vif->type == NL80211_IFTYPE_MESH_POINT)) {
- if ((conf->changed & IEEE80211_IFCC_BEACON) ||
- (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
- conf->enable_beacon)) {
- /*
- * Allocate and setup the beacon frame.
- *
- * Stop any previous beacon DMA. This may be
- * necessary, for example, when an ibss merge
- * causes reconfiguration; we may be called
- * with beacon transmission active.
- */
- ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-
- error = ath_beacon_alloc(aphy, vif);
- if (error != 0) {
- mutex_unlock(&sc->mutex);
- return error;
- }
-
- ath_beacon_config(sc, vif);
- }
- }
-
- /* Check for WLAN_CAPABILITY_PRIVACY ? */
- if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
- for (i = 0; i < IEEE80211_WEP_NKID; i++)
- if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
- ath9k_hw_keysetmac(sc->sc_ah,
- (u16)i,
- sc->curbssid);
- }
-
- /* Only legacy IBSS for now */
- if (vif->type == NL80211_IFTYPE_ADHOC)
- ath_update_chainmask(sc, 0);
-
mutex_unlock(&sc->mutex);
return 0;
@@ -2562,6 +2426,8 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
mutex_lock(&sc->mutex);
+ memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
+
qi.tqi_aifs = params->aifs;
qi.tqi_cwmin = params->cw_min;
qi.tqi_cwmax = params->cw_max;
@@ -2598,7 +2464,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);
ath9k_ps_wakeup(sc);
- DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n");
+ DPRINTF(sc, ATH_DBG_CONFIG, "Set HW Key\n");
switch (cmd) {
case SET_KEY:
@@ -2634,9 +2500,92 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_vif *avp = (void *)vif->drv_priv;
+ u32 rfilt = 0;
+ int error, i;
mutex_lock(&sc->mutex);
+ /*
+ * TODO: Need to decide which hw opmode to use for
+ * multi-interface cases
+ * XXX: This belongs into add_interface!
+ */
+ if (vif->type == NL80211_IFTYPE_AP &&
+ ah->opmode != NL80211_IFTYPE_AP) {
+ ah->opmode = NL80211_IFTYPE_STATION;
+ ath9k_hw_setopmode(ah);
+ memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
+ sc->curaid = 0;
+ ath9k_hw_write_associd(sc);
+ /* Request full reset to get hw opmode changed properly */
+ sc->sc_flags |= SC_OP_FULL_RESET;
+ }
+
+ if ((changed & BSS_CHANGED_BSSID) &&
+ !is_zero_ether_addr(bss_conf->bssid)) {
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
+ /* Set BSSID */
+ memcpy(sc->curbssid, bss_conf->bssid, ETH_ALEN);
+ memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
+ sc->curaid = 0;
+ ath9k_hw_write_associd(sc);
+
+ /* Set aggregation protection mode parameters */
+ sc->config.ath_aggr_prot = 0;
+
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "RX filter 0x%x bssid %pM aid 0x%x\n",
+ rfilt, sc->curbssid, sc->curaid);
+
+ /* need to reconfigure the beacon */
+ sc->sc_flags &= ~SC_OP_BEACONS ;
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ((vif->type == NL80211_IFTYPE_ADHOC) ||
+ (vif->type == NL80211_IFTYPE_AP) ||
+ (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+ if ((changed & BSS_CHANGED_BEACON) ||
+ (changed & BSS_CHANGED_BEACON_ENABLED &&
+ bss_conf->enable_beacon)) {
+ /*
+ * Allocate and setup the beacon frame.
+ *
+ * Stop any previous beacon DMA. This may be
+ * necessary, for example, when an ibss merge
+ * causes reconfiguration; we may be called
+ * with beacon transmission active.
+ */
+ ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+
+ error = ath_beacon_alloc(aphy, vif);
+ if (!error)
+ ath_beacon_config(sc, vif);
+ }
+ }
+
+ /* Check for WLAN_CAPABILITY_PRIVACY ? */
+ if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
+ for (i = 0; i < IEEE80211_WEP_NKID; i++)
+ if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
+ ath9k_hw_keysetmac(sc->sc_ah,
+ (u16)i,
+ sc->curbssid);
+ }
+
+ /* Only legacy IBSS for now */
+ if (vif->type == NL80211_IFTYPE_ADHOC)
+ ath_update_chainmask(sc, 0);
+
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
bss_conf->use_short_preamble);
@@ -2662,6 +2611,18 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
ath9k_bss_assoc_info(sc, vif, bss_conf);
}
+ /*
+ * The HW TSF has to be reset when the beacon interval changes.
+ * We set the flag here, and ath_beacon_config_ap() would take this
+ * into account when it gets called through the subsequent
+ * config_interface() call - with IFCC_BEACON in the changed field.
+ */
+
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ sc->sc_flags |= SC_OP_TSF_RESET;
+ sc->beacon_interval = bss_conf->beacon_int;
+ }
+
mutex_unlock(&sc->mutex);
}
@@ -2771,6 +2732,7 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
mutex_lock(&sc->mutex);
aphy->state = ATH_WIPHY_ACTIVE;
sc->sc_flags &= ~SC_OP_SCANNING;
+ sc->sc_flags |= SC_OP_FULL_RESET;
mutex_unlock(&sc->mutex);
}
@@ -2781,7 +2743,6 @@ struct ieee80211_ops ath9k_ops = {
.add_interface = ath9k_add_interface,
.remove_interface = ath9k_remove_interface,
.config = ath9k_config,
- .config_interface = ath9k_config_interface,
.configure_filter = ath9k_configure_filter,
.sta_notify = ath9k_sta_notify,
.conf_tx = ath9k_conf_tx,
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 168411d322a2..168411d322a2 100644
--- a/drivers/net/wireless/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index 8bcba906929a..aaa941561c36 100644
--- a/drivers/net/wireless/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -46,7 +46,7 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Invalid channel %u MHz\n", freq);
return false;
}
@@ -79,7 +79,7 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
aModeRefSel = ath9k_hw_reverse_bits(1, 2);
} else {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Invalid channel %u MHz\n", freq);
return false;
}
@@ -96,9 +96,8 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
return true;
}
-bool
-ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
- struct ath9k_channel *chan)
+void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
u16 bMode, fracMode, aModeRefSel = 0;
u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
@@ -169,8 +168,6 @@ ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
ah->curchan = chan;
ah->curchan_rad_index = -1;
-
- return true;
}
static void
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 0f7f8e0c9c95..c70f530642f6 100644
--- a/drivers/net/wireless/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -17,7 +17,7 @@
#ifndef PHY_H
#define PHY_H
-bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
+void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
struct ath9k_channel
*chan);
bool ath9k_hw_set_channel(struct ath_hw *ah,
@@ -556,9 +556,6 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
int r; \
for (r = 0; r < ((iniarray)->ia_rows); r++) { \
REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, \
- "RF 0x%x V 0x%x\n", \
- INI_RA((iniarray), r, 0), (regData)[r]); \
DO_DELAY(regWr); \
} \
} while (0)
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 824ccbb8b7b8..ba06e78b2f50 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -17,7 +17,7 @@
#include "ath9k.h"
-static struct ath_rate_table ar5416_11na_ratetable = {
+static const struct ath_rate_table ar5416_11na_ratetable = {
42,
{
{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
@@ -155,7 +155,7 @@ static struct ath_rate_table ar5416_11na_ratetable = {
/* 4ms frame limit not used for NG mode. The values filled
* for HT are the 64K max aggregate limit */
-static struct ath_rate_table ar5416_11ng_ratetable = {
+static const struct ath_rate_table ar5416_11ng_ratetable = {
46,
{
{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
@@ -302,7 +302,7 @@ static struct ath_rate_table ar5416_11ng_ratetable = {
WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
};
-static struct ath_rate_table ar5416_11a_ratetable = {
+static const struct ath_rate_table ar5416_11a_ratetable = {
8,
{
{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
@@ -335,7 +335,7 @@ static struct ath_rate_table ar5416_11a_ratetable = {
0, /* Phy rates allowed initially */
};
-static struct ath_rate_table ar5416_11g_ratetable = {
+static const struct ath_rate_table ar5416_11g_ratetable = {
12,
{
{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
@@ -380,7 +380,7 @@ static struct ath_rate_table ar5416_11g_ratetable = {
0, /* Phy rates allowed initially */
};
-static struct ath_rate_table ar5416_11b_ratetable = {
+static const struct ath_rate_table ar5416_11b_ratetable = {
4,
{
{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
@@ -420,7 +420,7 @@ static inline int8_t median(int8_t a, int8_t b, int8_t c)
}
}
-static void ath_rc_sort_validrates(struct ath_rate_table *rate_table,
+static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv)
{
u8 i, j, idx, idx_next;
@@ -461,10 +461,11 @@ static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
return ath_rc_priv->valid_rate_index[index];
}
-static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
- struct ath_rate_priv *ath_rc_priv,
- u8 cur_valid_txrate,
- u8 *next_idx)
+static inline
+int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
+ struct ath_rate_priv *ath_rc_priv,
+ u8 cur_valid_txrate,
+ u8 *next_idx)
{
u8 i;
@@ -500,7 +501,7 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
}
static inline int
-ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
+ath_rc_get_nextlowervalid_txrate(const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv,
u8 cur_valid_txrate, u8 *next_idx)
{
@@ -517,14 +518,14 @@ ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
}
static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
u32 capflag)
{
u8 i, hi = 0;
u32 valid;
for (i = 0; i < rate_table->rate_cnt; i++) {
- valid = (ath_rc_priv->single_stream ?
+ valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
rate_table->info[i].valid_single_stream :
rate_table->info[i].valid);
if (valid == 1) {
@@ -547,7 +548,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
}
static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
struct ath_rateset *rateset,
u32 capflag)
{
@@ -557,9 +558,9 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
for (i = 0; i < rateset->rs_nrates; i++) {
for (j = 0; j < rate_table->rate_cnt; j++) {
u32 phy = rate_table->info[j].phy;
- u32 valid = (ath_rc_priv->single_stream ?
- rate_table->info[j].valid_single_stream :
- rate_table->info[j].valid);
+ u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
+ rate_table->info[j].valid_single_stream :
+ rate_table->info[j].valid);
u8 rate = rateset->rs_rates[i];
u8 dot11rate = rate_table->info[j].dot11rate;
@@ -592,7 +593,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
}
static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
u8 *mcs_set, u32 capflag)
{
struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
@@ -603,7 +604,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
for (i = 0; i < rateset->rs_nrates; i++) {
for (j = 0; j < rate_table->rate_cnt; j++) {
u32 phy = rate_table->info[j].phy;
- u32 valid = (ath_rc_priv->single_stream ?
+ u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
rate_table->info[j].valid_single_stream :
rate_table->info[j].valid);
u8 rate = rateset->rs_rates[i];
@@ -630,7 +631,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
int *is_probing)
{
u32 dt, best_thruput, this_thruput, now_msec;
@@ -740,14 +741,15 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
if (rate > (ath_rc_priv->rate_table_size - 1))
rate = ath_rc_priv->rate_table_size - 1;
- ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) ||
+ ASSERT((rate_table->info[rate].valid &&
+ (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) ||
(rate_table->info[rate].valid_single_stream &&
- ath_rc_priv->single_stream));
+ !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)));
return rate;
}
-static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
+static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate,
struct ieee80211_tx_rate_control *txrc,
u8 tries, u8 rix, int rtsctsenable)
@@ -768,7 +770,7 @@ static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
}
static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
struct ieee80211_tx_info *tx_info)
{
struct ieee80211_tx_rate *rates = tx_info->control.rates;
@@ -806,12 +808,12 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
static u8 ath_rc_rate_getidx(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
u8 rix, u16 stepdown,
u16 min_rate)
{
u32 j;
- u8 nextindex;
+ u8 nextindex = 0;
if (min_rate) {
for (j = RATE_TABLE_SIZE; j > 0; j--) {
@@ -837,7 +839,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
struct ieee80211_tx_rate_control *txrc)
{
- struct ath_rate_table *rate_table;
+ const struct ath_rate_table *rate_table;
struct sk_buff *skb = txrc->skb;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->control.rates;
@@ -936,7 +938,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
}
static bool ath_rc_update_per(struct ath_softc *sc,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv,
struct ath_tx_info_priv *tx_info_priv,
int tx_rate, int xretries, int retries,
@@ -1141,7 +1143,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
int rate;
u8 last_per;
bool state_change = false;
- struct ath_rate_table *rate_table = sc->cur_rate_table;
+ const struct ath_rate_table *rate_table = sc->cur_rate_table;
int size = ath_rc_priv->rate_table_size;
if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
@@ -1275,7 +1277,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
#undef CHK_RSSI
}
-static int ath_rc_get_rateindex(struct ath_rate_table *rate_table,
+static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate)
{
int rix;
@@ -1299,7 +1301,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
int final_ts_idx, int xretries, int long_retry)
{
struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
- struct ath_rate_table *rate_table;
+ const struct ath_rate_table *rate_table;
struct ieee80211_tx_rate *rates = tx_info->status.rates;
u8 flags;
u32 i = 0, rix;
@@ -1320,7 +1322,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
* 40 to 20 => don't update */
if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
- (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG))
+ !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
return;
rix = ath_rc_get_rateindex(rate_table, &rates[i]);
@@ -1345,18 +1347,19 @@ static void ath_rc_tx_status(struct ath_softc *sc,
/* If HT40 and we have switched mode from 40 to 20 => don't update */
if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
- (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) {
+ !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
return;
- }
rix = ath_rc_get_rateindex(rate_table, &rates[i]);
ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
xretries, long_retry);
}
-static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
- enum ieee80211_band band,
- bool is_ht, bool is_cw_40)
+static const
+struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
+ enum ieee80211_band band,
+ bool is_ht,
+ bool is_cw_40)
{
int mode = 0;
@@ -1390,7 +1393,7 @@ static void ath_rc_init(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta,
- struct ath_rate_table *rate_table)
+ const struct ath_rate_table *rate_table)
{
struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
@@ -1420,10 +1423,6 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_priv->valid_phy_rateidx[i][j] = 0;
ath_rc_priv->valid_phy_ratecnt[i] = 0;
}
- ath_rc_priv->rc_phy_mode = ath_rc_priv->ht_cap & WLAN_RC_40_FLAG;
-
- /* Set stream capability */
- ath_rc_priv->single_stream = (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1;
if (!rateset->rs_nrates) {
/* No working rate, just initialize valid rates */
@@ -1572,12 +1571,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
struct ath_rate_priv *ath_rc_priv = priv_sta;
__le16 fc = hdr->frame_control;
- /* lowest rate for management and multicast/broadcast frames */
- if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
- !sta) {
+ /* lowest rate for management and NO_ACK frames */
+ if (!ieee80211_is_data(fc) ||
+ tx_info->flags & IEEE80211_TX_CTL_NO_ACK || !sta) {
tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
tx_info->control.rates[0].count =
- is_multicast_ether_addr(hdr->addr1) ? 1 : ATH_MGT_TXMAXTRY;
+ (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) ?
+ 1 : ATH_MGT_TXMAXTRY;
return;
}
@@ -1590,7 +1590,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
{
struct ath_softc *sc = priv;
struct ath_rate_priv *ath_rc_priv = priv_sta;
- struct ath_rate_table *rate_table = NULL;
+ const struct ath_rate_table *rate_table = NULL;
bool is_cw40, is_sgi40;
int i, j = 0;
@@ -1639,7 +1639,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
{
struct ath_softc *sc = priv;
struct ath_rate_priv *ath_rc_priv = priv_sta;
- struct ath_rate_table *rate_table = NULL;
+ const struct ath_rate_table *rate_table = NULL;
bool oper_cw40 = false, oper_sgi40;
bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
true : false;
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 199a3ce57d64..e3abd76103fd 100644
--- a/drivers/net/wireless/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -24,7 +24,6 @@ struct ath_softc;
#define ATH_RATE_MAX 30
#define RATE_TABLE_SIZE 64
#define MAX_TX_RATE_PHY 48
-#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
/* VALID_ALL - valid for 20/40/Legacy,
* VALID - Legacy only,
@@ -158,7 +157,6 @@ struct ath_rateset {
* @probe_interval: interval for ratectrl to probe for other rates
* @prev_data_rix: rate idx of last data frame
* @ht_cap: HT capabilities
- * @single_stream: When TRUE, only single TX stream possible
* @neg_rates: Negotatied rates
* @neg_ht_rates: Negotiated HT rates
*/
@@ -176,10 +174,8 @@ struct ath_rate_priv {
u8 max_valid_rate;
u8 valid_rate_index[RATE_TABLE_SIZE];
u8 ht_cap;
- u8 single_stream;
u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
- u8 rc_phy_mode;
u8 rate_max_phy;
u32 rssi_time;
u32 rssi_down_time;
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index dd1f30156740..b46badd21f73 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -283,54 +283,51 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
struct ath_buf *bf;
int error = 0;
- do {
- spin_lock_init(&sc->rx.rxflushlock);
- sc->sc_flags &= ~SC_OP_RXFLUSH;
- spin_lock_init(&sc->rx.rxbuflock);
-
- sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
- min(sc->cachelsz,
- (u16)64));
+ spin_lock_init(&sc->rx.rxflushlock);
+ sc->sc_flags &= ~SC_OP_RXFLUSH;
+ spin_lock_init(&sc->rx.rxbuflock);
- DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
- sc->cachelsz, sc->rx.bufsize);
+ sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
+ min(sc->cachelsz, (u16)64));
- /* Initialize rx descriptors */
+ DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
+ sc->cachelsz, sc->rx.bufsize);
- error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
- "rx", nbufs, 1);
- if (error != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "failed to allocate rx descriptors: %d\n", error);
- break;
- }
+ /* Initialize rx descriptors */
- list_for_each_entry(bf, &sc->rx.rxbuf, list) {
- skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
- if (skb == NULL) {
- error = -ENOMEM;
- break;
- }
+ error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
+ "rx", nbufs, 1);
+ if (error != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "failed to allocate rx descriptors: %d\n", error);
+ goto err;
+ }
- bf->bf_mpdu = skb;
- bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
- sc->rx.bufsize,
- DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(sc->dev,
- bf->bf_buf_addr))) {
- dev_kfree_skb_any(skb);
- bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
- "dma_mapping_error() on RX init\n");
- error = -ENOMEM;
- break;
- }
- bf->bf_dmacontext = bf->bf_buf_addr;
+ list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+ skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
+ if (skb == NULL) {
+ error = -ENOMEM;
+ goto err;
}
- sc->rx.rxlink = NULL;
- } while (0);
+ bf->bf_mpdu = skb;
+ bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+ sc->rx.bufsize,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev,
+ bf->bf_buf_addr))) {
+ dev_kfree_skb_any(skb);
+ bf->bf_mpdu = NULL;
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "dma_mapping_error() on RX init\n");
+ error = -ENOMEM;
+ goto err;
+ }
+ bf->bf_dmacontext = bf->bf_buf_addr;
+ }
+ sc->rx.rxlink = NULL;
+err:
if (error)
ath_rx_cleanup(sc);
@@ -345,10 +342,8 @@ void ath_rx_cleanup(struct ath_softc *sc)
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
skb = bf->bf_mpdu;
if (skb) {
- dma_unmap_single(sc->dev,
- bf->bf_buf_addr,
- sc->rx.bufsize,
- DMA_FROM_DEVICE);
+ dma_unmap_single(sc->dev, bf->bf_buf_addr,
+ sc->rx.bufsize, DMA_FROM_DEVICE);
dev_kfree_skb(skb);
}
}
@@ -675,7 +670,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
bf->bf_buf_addr))) {
dev_kfree_skb_any(requeue_skb);
bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
+ DPRINTF(sc, ATH_DBG_FATAL,
"dma_mapping_error() on RX\n");
break;
}
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 52605246679f..52605246679f 100644
--- a/drivers/net/wireless/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
diff --git a/drivers/net/wireless/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 1ff429b027d7..1ff429b027d7 100644
--- a/drivers/net/wireless/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 689bdbf78808..41c42824a5ca 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -283,7 +283,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
bool rc_update = true;
- skb = (struct sk_buff *)bf->bf_mpdu;
+ skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
rcu_read_lock();
@@ -380,8 +380,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
} else {
/* retry the un-acked ones */
- if (bf->bf_next == NULL &&
- bf_last->bf_status & ATH_BUFSTATUS_STALE) {
+ if (bf->bf_next == NULL && bf_last->bf_stale) {
struct ath_buf *tbf;
tbf = ath_clone_txbuf(sc, bf_last);
@@ -435,7 +434,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
struct ath_atx_tid *tid)
{
- struct ath_rate_table *rate_table = sc->cur_rate_table;
+ const struct ath_rate_table *rate_table = sc->cur_rate_table;
struct sk_buff *skb;
struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rates;
@@ -444,7 +443,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
u16 aggr_limit, legacy = 0, maxampdu;
int i;
- skb = (struct sk_buff *)bf->bf_mpdu;
+ skb = bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
rates = tx_info->control.rates;
tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
@@ -498,7 +497,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
struct ath_buf *bf, u16 frmlen)
{
- struct ath_rate_table *rt = sc->cur_rate_table;
+ const struct ath_rate_table *rt = sc->cur_rate_table;
struct sk_buff *skb = bf->bf_mpdu;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
u32 nsymbits, nsymbols, mpdudensity;
@@ -972,7 +971,7 @@ int ath_cabq_update(struct ath_softc *sc)
else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
- qi.tqi_readyTime = (sc->hw->conf.beacon_int *
+ qi.tqi_readyTime = (sc->beacon_interval *
sc->config.cabqReadytime) / 100;
ath_txq_update(sc, qnum, &qi);
@@ -1004,7 +1003,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
- if (bf->bf_status & ATH_BUFSTATUS_STALE) {
+ if (bf->bf_stale) {
list_del(&bf->list);
spin_unlock_bh(&txq->axq_lock);
@@ -1408,7 +1407,7 @@ static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
int width, int half_gi, bool shortPreamble)
{
- struct ath_rate_table *rate_table = sc->cur_rate_table;
+ const struct ath_rate_table *rate_table = sc->cur_rate_table;
u32 nbits, nsymbits, duration, nsymbols;
u8 rc;
int streams, pktlen;
@@ -1440,7 +1439,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_rate_table *rt = sc->cur_rate_table;
+ const struct ath_rate_table *rt = sc->cur_rate_table;
struct ath9k_11n_rate_series series[4];
struct sk_buff *skb;
struct ieee80211_tx_info *tx_info;
@@ -1452,7 +1451,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
- skb = (struct sk_buff *)bf->bf_mpdu;
+ skb = bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
rates = tx_info->control.rates;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -1573,8 +1572,9 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
skb->len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
- "dma_mapping_error() on TX\n");
+ kfree(tx_info_priv);
+ tx_info->rate_driver_data[0] = NULL;
+ DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error() on TX\n");
return -ENOMEM;
}
@@ -1586,7 +1586,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
struct ath_tx_control *txctl)
{
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct sk_buff *skb = bf->bf_mpdu;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ath_node *an = NULL;
@@ -1860,7 +1860,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
int nbad, int txok, bool update_rc)
{
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct sk_buff *skb = bf->bf_mpdu;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
@@ -1941,7 +1941,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
* it with the STALE flag.
*/
bf_held = NULL;
- if (bf->bf_status & ATH_BUFSTATUS_STALE) {
+ if (bf->bf_stale) {
bf_held = bf;
if (list_is_last(&bf_held->list, &txq->axq_q)) {
txq->axq_link = NULL;
@@ -1982,7 +1982,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
* however leave the last descriptor back as the holding
* descriptor for hw.
*/
- lastbf->bf_status |= ATH_BUFSTATUS_STALE;
+ lastbf->bf_stale = true;
INIT_LIST_HEAD(&bf_head);
if (!list_is_singular(&lastbf->list))
list_cut_position(&bf_head,
@@ -2048,44 +2048,38 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
{
int error = 0;
- do {
- spin_lock_init(&sc->tx.txbuflock);
+ spin_lock_init(&sc->tx.txbuflock);
- error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
- "tx", nbufs, 1);
- if (error != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Failed to allocate tx descriptors: %d\n",
- error);
- break;
- }
-
- error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
- "beacon", ATH_BCBUF, 1);
- if (error != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Failed to allocate beacon descriptors: %d\n",
- error);
- break;
- }
+ error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
+ "tx", nbufs, 1);
+ if (error != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Failed to allocate tx descriptors: %d\n", error);
+ goto err;
+ }
- } while (0);
+ error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
+ "beacon", ATH_BCBUF, 1);
+ if (error != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Failed to allocate beacon descriptors: %d\n", error);
+ goto err;
+ }
+err:
if (error != 0)
ath_tx_cleanup(sc);
return error;
}
-int ath_tx_cleanup(struct ath_softc *sc)
+void ath_tx_cleanup(struct ath_softc *sc)
{
if (sc->beacon.bdma.dd_desc_len != 0)
ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
if (sc->tx.txdma.dd_desc_len != 0)
ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
-
- return 0;
}
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c
new file mode 100644
index 000000000000..9949b11cb151
--- /dev/null
+++ b/drivers/net/wireless/ath/main.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Atheros Communications");
+MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards.");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath/regd.c
index 4ca625102291..fdf07c822081 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -16,7 +16,9 @@
#include <linux/kernel.h>
#include <linux/slab.h>
-#include "ath9k.h"
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include "regd.h"
#include "regd_common.h"
/*
@@ -55,7 +57,7 @@
/* Can be used for:
* 0x60, 0x61, 0x62 */
-static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = {
+static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
.n_reg_rules = 5,
.alpha2 = "99",
.reg_rules = {
@@ -65,7 +67,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = {
};
/* Can be used by 0x63 and 0x65 */
-static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = {
+static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
.n_reg_rules = 4,
.alpha2 = "99",
.reg_rules = {
@@ -76,7 +78,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = {
};
/* Can be used by 0x64 only */
-static const struct ieee80211_regdomain ath9k_world_regdom_64 = {
+static const struct ieee80211_regdomain ath_world_regdom_64 = {
.n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
@@ -86,7 +88,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_64 = {
};
/* Can be used by 0x66 and 0x69 */
-static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = {
+static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
.n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
@@ -96,7 +98,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = {
};
/* Can be used by 0x67, 0x6A and 0x68 */
-static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = {
+static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = {
.n_reg_rules = 4,
.alpha2 = "99",
.reg_rules = {
@@ -112,49 +114,51 @@ static inline bool is_wwr_sku(u16 regd)
(regd == WORLD);
}
-static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah)
+static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
{
- return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG;
+ return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
}
-bool ath9k_is_world_regd(struct ath_hw *ah)
+bool ath_is_world_regd(struct ath_regulatory *reg)
{
- return is_wwr_sku(ath9k_regd_get_eepromRD(ah));
+ return is_wwr_sku(ath_regd_get_eepromRD(reg));
}
+EXPORT_SYMBOL(ath_is_world_regd);
-const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
+static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
{
/* this is the most restrictive */
- return &ath9k_world_regdom_64;
+ return &ath_world_regdom_64;
}
-const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah)
+static const struct
+ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
{
- switch (ah->regulatory.regpair->regDmnEnum) {
+ switch (reg->regpair->regDmnEnum) {
case 0x60:
case 0x61:
case 0x62:
- return &ath9k_world_regdom_60_61_62;
+ return &ath_world_regdom_60_61_62;
case 0x63:
case 0x65:
- return &ath9k_world_regdom_63_65;
+ return &ath_world_regdom_63_65;
case 0x64:
- return &ath9k_world_regdom_64;
+ return &ath_world_regdom_64;
case 0x66:
case 0x69:
- return &ath9k_world_regdom_66_69;
+ return &ath_world_regdom_66_69;
case 0x67:
case 0x68:
case 0x6A:
- return &ath9k_world_regdom_67_68_6A;
+ return &ath_world_regdom_67_68_6A;
default:
WARN_ON(1);
- return ath9k_default_world_regdomain();
+ return ath_default_world_regdomain();
}
}
/* Frequency is one where radar detection is required */
-static bool ath9k_is_radar_freq(u16 center_freq)
+static bool ath_is_radar_freq(u16 center_freq)
{
return (center_freq >= 5260 && center_freq <= 5700);
}
@@ -168,9 +172,9 @@ static bool ath9k_is_radar_freq(u16 center_freq)
* received a beacon on a channel we can enable active scan and
* adhoc (or beaconing).
*/
-static void ath9k_reg_apply_beaconing_flags(
- struct wiphy *wiphy,
- enum nl80211_reg_initiator initiator)
+static void
+ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
{
enum ieee80211_band band;
struct ieee80211_supported_band *sband;
@@ -191,7 +195,7 @@ static void ath9k_reg_apply_beaconing_flags(
ch = &sband->channels[i];
- if (ath9k_is_radar_freq(ch->center_freq) ||
+ if (ath_is_radar_freq(ch->center_freq) ||
(ch->flags & IEEE80211_CHAN_RADAR))
continue;
@@ -227,9 +231,9 @@ static void ath9k_reg_apply_beaconing_flags(
}
/* Allows active scan scan on Ch 12 and 13 */
-static void ath9k_reg_apply_active_scan_flags(
- struct wiphy *wiphy,
- enum nl80211_reg_initiator initiator)
+static void
+ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
{
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
@@ -278,7 +282,7 @@ static void ath9k_reg_apply_active_scan_flags(
}
/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
-void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
+static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
{
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
@@ -291,7 +295,7 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
for (i = 0; i < sband->n_channels; i++) {
ch = &sband->channels[i];
- if (!ath9k_is_radar_freq(ch->center_freq))
+ if (!ath_is_radar_freq(ch->center_freq))
continue;
/* We always enable radar detection/DFS on this
* frequency range. Additionally we also apply on
@@ -310,37 +314,31 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
}
}
-void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
- enum nl80211_reg_initiator initiator)
+static void ath_reg_apply_world_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator,
+ struct ath_regulatory *reg)
{
- struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
- struct ath_wiphy *aphy = hw->priv;
- struct ath_softc *sc = aphy->sc;
- struct ath_hw *ah = sc->sc_ah;
-
- switch (ah->regulatory.regpair->regDmnEnum) {
+ switch (reg->regpair->regDmnEnum) {
case 0x60:
case 0x63:
case 0x66:
case 0x67:
- ath9k_reg_apply_beaconing_flags(wiphy, initiator);
+ ath_reg_apply_beaconing_flags(wiphy, initiator);
break;
case 0x68:
- ath9k_reg_apply_beaconing_flags(wiphy, initiator);
- ath9k_reg_apply_active_scan_flags(wiphy, initiator);
+ ath_reg_apply_beaconing_flags(wiphy, initiator);
+ ath_reg_apply_active_scan_flags(wiphy, initiator);
break;
}
return;
}
-int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+int ath_reg_notifier_apply(struct wiphy *wiphy,
+ struct regulatory_request *request,
+ struct ath_regulatory *reg)
{
- struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
- struct ath_wiphy *aphy = hw->priv;
- struct ath_softc *sc = aphy->sc;
-
/* We always apply this */
- ath9k_reg_apply_radar_flags(wiphy);
+ ath_reg_apply_radar_flags(wiphy);
switch (request->initiator) {
case NL80211_REGDOM_SET_BY_DRIVER:
@@ -348,17 +346,19 @@ int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
case NL80211_REGDOM_SET_BY_USER:
break;
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
- if (ath9k_is_world_regd(sc->sc_ah))
- ath9k_reg_apply_world_flags(wiphy, request->initiator);
+ if (ath_is_world_regd(reg))
+ ath_reg_apply_world_flags(wiphy, request->initiator,
+ reg);
break;
}
return 0;
}
+EXPORT_SYMBOL(ath_reg_notifier_apply);
-bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
+static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
{
- u16 rd = ath9k_regd_get_eepromRD(ah);
+ u16 rd = ath_regd_get_eepromRD(reg);
int i;
if (rd & COUNTRY_ERD_FLAG) {
@@ -373,14 +373,14 @@ bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
if (regDomainPairs[i].regDmnEnum == rd)
return true;
}
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "invalid regulatory domain/country code 0x%x\n", rd);
+ printk(KERN_DEBUG
+ "ath: invalid regulatory domain/country code 0x%x\n", rd);
return false;
}
/* EEPROM country code to regpair mapping */
static struct country_code_to_enum_rd*
-ath9k_regd_find_country(u16 countryCode)
+ath_regd_find_country(u16 countryCode)
{
int i;
@@ -393,7 +393,7 @@ ath9k_regd_find_country(u16 countryCode)
/* EEPROM rd code to regpair mapping */
static struct country_code_to_enum_rd*
-ath9k_regd_find_country_by_rd(int regdmn)
+ath_regd_find_country_by_rd(int regdmn)
{
int i;
@@ -405,13 +405,13 @@ ath9k_regd_find_country_by_rd(int regdmn)
}
/* Returns the map of the EEPROM set RD to a country code */
-static u16 ath9k_regd_get_default_country(u16 rd)
+static u16 ath_regd_get_default_country(u16 rd)
{
if (rd & COUNTRY_ERD_FLAG) {
struct country_code_to_enum_rd *country = NULL;
u16 cc = rd & ~COUNTRY_ERD_FLAG;
- country = ath9k_regd_find_country(cc);
+ country = ath_regd_find_country(cc);
if (country != NULL)
return cc;
}
@@ -420,7 +420,7 @@ static u16 ath9k_regd_get_default_country(u16 rd)
}
static struct reg_dmn_pair_mapping*
-ath9k_get_regpair(int regdmn)
+ath_get_regpair(int regdmn)
{
int i;
@@ -433,87 +433,120 @@ ath9k_get_regpair(int regdmn)
return NULL;
}
-int ath9k_regd_init(struct ath_hw *ah)
+static int
+ath_regd_init_wiphy(struct ath_regulatory *reg,
+ struct wiphy *wiphy,
+ int (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *request))
+{
+ const struct ieee80211_regdomain *regd;
+
+ wiphy->reg_notifier = reg_notifier;
+ wiphy->strict_regulatory = true;
+
+ if (ath_is_world_regd(reg)) {
+ /*
+ * Anything applied here (prior to wiphy registration) gets
+ * saved on the wiphy orig_* parameters
+ */
+ regd = ath_world_regdomain(reg);
+ wiphy->custom_regulatory = true;
+ wiphy->strict_regulatory = false;
+ } else {
+ /*
+ * This gets applied in the case of the absense of CRDA,
+ * it's our own custom world regulatory domain, similar to
+ * cfg80211's but we enable passive scanning.
+ */
+ regd = ath_default_world_regdomain();
+ }
+ wiphy_apply_custom_regulatory(wiphy, regd);
+ ath_reg_apply_radar_flags(wiphy);
+ ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
+ return 0;
+}
+
+int
+ath_regd_init(struct ath_regulatory *reg,
+ struct wiphy *wiphy,
+ int (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *request))
{
struct country_code_to_enum_rd *country = NULL;
u16 regdmn;
- if (!ath9k_regd_is_eeprom_valid(ah)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Invalid EEPROM contents\n");
+ if (!ath_regd_is_eeprom_valid(reg)) {
+ printk(KERN_ERR "ath: Invalid EEPROM contents\n");
return -EINVAL;
}
- regdmn = ath9k_regd_get_eepromRD(ah);
- ah->regulatory.country_code = ath9k_regd_get_default_country(regdmn);
+ regdmn = ath_regd_get_eepromRD(reg);
+ reg->country_code = ath_regd_get_default_country(regdmn);
- if (ah->regulatory.country_code == CTRY_DEFAULT &&
+ if (reg->country_code == CTRY_DEFAULT &&
regdmn == CTRY_DEFAULT)
- ah->regulatory.country_code = CTRY_UNITED_STATES;
+ reg->country_code = CTRY_UNITED_STATES;
- if (ah->regulatory.country_code == CTRY_DEFAULT) {
+ if (reg->country_code == CTRY_DEFAULT) {
country = NULL;
} else {
- country = ath9k_regd_find_country(ah->regulatory.country_code);
+ country = ath_regd_find_country(reg->country_code);
if (country == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Country is NULL!!!!, cc= %d\n",
- ah->regulatory.country_code);
+ printk(KERN_DEBUG
+ "ath: Country is NULL!!!!, cc= %d\n",
+ reg->country_code);
return -EINVAL;
} else
regdmn = country->regDmnEnum;
}
- ah->regulatory.regpair = ath9k_get_regpair(regdmn);
+ reg->regpair = ath_get_regpair(regdmn);
- if (!ah->regulatory.regpair) {
- DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ if (!reg->regpair) {
+ printk(KERN_DEBUG "ath: "
"No regulatory domain pair found, cannot continue\n");
return -EINVAL;
}
if (!country)
- country = ath9k_regd_find_country_by_rd(regdmn);
+ country = ath_regd_find_country_by_rd(regdmn);
if (country) {
- ah->regulatory.alpha2[0] = country->isoName[0];
- ah->regulatory.alpha2[1] = country->isoName[1];
+ reg->alpha2[0] = country->isoName[0];
+ reg->alpha2[1] = country->isoName[1];
} else {
- ah->regulatory.alpha2[0] = '0';
- ah->regulatory.alpha2[1] = '0';
+ reg->alpha2[0] = '0';
+ reg->alpha2[1] = '0';
}
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Country alpha2 being used: %c%c\n"
- "Regulatory.Regpair detected: 0x%0x\n",
- ah->regulatory.alpha2[0], ah->regulatory.alpha2[1],
- ah->regulatory.regpair->regDmnEnum);
+ printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n",
+ reg->alpha2[0], reg->alpha2[1]);
+ printk(KERN_DEBUG "ath: Regpair detected: 0x%0x\n",
+ reg->regpair->regDmnEnum);
+ ath_regd_init_wiphy(reg, wiphy, reg_notifier);
return 0;
}
+EXPORT_SYMBOL(ath_regd_init);
-u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan)
+u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
+ enum ieee80211_band band)
{
- u32 ctl = NO_CTL;
-
- if (!ah->regulatory.regpair ||
- (ah->regulatory.country_code == CTRY_DEFAULT &&
- is_wwr_sku(ath9k_regd_get_eepromRD(ah)))) {
- if (IS_CHAN_B(chan))
- ctl = SD_NO_CTL | CTL_11B;
- else if (IS_CHAN_G(chan))
- ctl = SD_NO_CTL | CTL_11G;
- else
- ctl = SD_NO_CTL | CTL_11A;
- return ctl;
+ if (!reg->regpair ||
+ (reg->country_code == CTRY_DEFAULT &&
+ is_wwr_sku(ath_regd_get_eepromRD(reg)))) {
+ return SD_NO_CTL;
}
- if (IS_CHAN_B(chan))
- ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11B;
- else if (IS_CHAN_G(chan))
- ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11G;
- else
- ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A;
+ switch (band) {
+ case IEEE80211_BAND_2GHZ:
+ return reg->regpair->reg_2ghz_ctl;
+ case IEEE80211_BAND_5GHZ:
+ return reg->regpair->reg_5ghz_ctl;
+ default:
+ return NO_CTL;
+ }
- return ctl;
+ return NO_CTL;
}
+EXPORT_SYMBOL(ath_regd_get_band_ctl);
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath/regd.h
index 9f5fbd4eea7a..07291ccb23f2 100644
--- a/drivers/net/wireless/ath9k/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -17,6 +17,25 @@
#ifndef REGD_H
#define REGD_H
+#include <linux/nl80211.h>
+
+#include <net/cfg80211.h>
+
+#define NO_CTL 0xff
+#define SD_NO_CTL 0xE0
+#define NO_CTL 0xff
+#define CTL_MODE_M 7
+#define CTL_11A 0
+#define CTL_11B 1
+#define CTL_11G 2
+#define CTL_2GHT20 5
+#define CTL_5GHT20 6
+#define CTL_2GHT40 7
+#define CTL_5GHT40 8
+
+#define CTRY_DEBUG 0x1ff
+#define CTRY_DEFAULT 0
+
#define COUNTRY_ERD_FLAG 0x8000
#define WORLDWIDE_ROAMING_FLAG 0x4000
@@ -40,7 +59,7 @@ struct country_code_to_enum_rd {
const char *isoName;
};
-struct ath9k_regulatory {
+struct ath_regulatory {
char alpha2[2];
u16 country_code;
u16 max_power_level;
@@ -233,15 +252,14 @@ enum CountryCode {
CTRY_BELGIUM2 = 5002
};
-bool ath9k_is_world_regd(struct ath_hw *ah);
-const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah);
-const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
-void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
- enum nl80211_reg_initiator initiator);
-void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
-int ath9k_regd_init(struct ath_hw *ah);
-bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah);
-u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan);
-int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+bool ath_is_world_regd(struct ath_regulatory *reg);
+int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy,
+ int (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *request));
+u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
+ enum ieee80211_band band);
+int ath_reg_notifier_apply(struct wiphy *wiphy,
+ struct regulatory_request *request,
+ struct ath_regulatory *reg);
#endif
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index 4d0e298cd1c7..4d0e298cd1c7 100644
--- a/drivers/net/wireless/ath9k/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 77406245dc7b..ddaa859c3491 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -279,7 +279,7 @@ static int atmel_config(struct pcmcia_device *link)
struct pcmcia_device_id *did;
dev = link->priv;
- did = handle_to_dev(link).driver_data;
+ did = dev_get_drvdata(&handle_to_dev(link));
DEBUG(0, "atmel_config(0x%p)\n", link);
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index aab71a70ba78..21572e40b79d 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -3,7 +3,6 @@ config B43
depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA
select SSB
select FW_LOADER
- select HW_RANDOM
---help---
b43 is a driver for the Broadcom 43xx series wireless devices.
@@ -106,6 +105,13 @@ config B43_RFKILL
depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43)
default y
+# This config option automatically enables b43 HW-RNG support,
+# if the HW-RNG core is enabled.
+config B43_HWRNG
+ bool
+ depends on B43 && (HW_RANDOM = y || HW_RANDOM = B43)
+ default y
+
config B43_DEBUG
bool "Broadcom 43xx debugging"
depends on B43
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index beaf18d6e8a7..4e8ad841c3c5 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -625,9 +625,11 @@ struct b43_wl {
/* Stats about the wireless interface */
struct ieee80211_low_level_stats ieee_stats;
+#ifdef CONFIG_B43_HWRNG
struct hwrng rng;
- u8 rng_initialized;
+ bool rng_initialized;
char rng_name[30 + 1];
+#endif /* CONFIG_B43_HWRNG */
/* The RF-kill button */
struct b43_rfkill rfkill;
@@ -776,8 +778,8 @@ struct b43_wldev {
/* Reason code of the last interrupt. */
u32 irq_reason;
u32 dma_reason[6];
- /* saved irq enable/disable state bitfield. */
- u32 irq_savedstate;
+ /* The currently active generic-interrupt mask. */
+ u32 irq_mask;
/* Link Quality calculation context. */
struct b43_noise_calculation noisecalc;
/* if > 0 MAC is suspended. if == 0 MAC is enabled. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 79b685e300c7..2615aaf7df6a 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -673,32 +673,6 @@ static void b43_short_slot_timing_disable(struct b43_wldev *dev)
b43_set_slot_time(dev, 20);
}
-/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43_interrupt_enable(struct b43_wldev *dev, u32 mask)
-{
- u32 old_mask;
-
- old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
- b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask | mask);
-
- return old_mask;
-}
-
-/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43_interrupt_disable(struct b43_wldev *dev, u32 mask)
-{
- u32 old_mask;
-
- old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
- b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
-
- return old_mask;
-}
-
/* Synchronize IRQ top- and bottom-half.
* IRQs must be masked before calling this.
* This must not be called with the irq_lock held.
@@ -1593,7 +1567,7 @@ static void handle_irq_beacon(struct b43_wldev *dev)
/* This is the bottom half of the asynchronous beacon update. */
/* Ignore interrupt in the future. */
- dev->irq_savedstate &= ~B43_IRQ_BEACON;
+ dev->irq_mask &= ~B43_IRQ_BEACON;
cmd = b43_read32(dev, B43_MMIO_MACCMD);
beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID);
@@ -1602,7 +1576,7 @@ static void handle_irq_beacon(struct b43_wldev *dev)
/* Schedule interrupt manually, if busy. */
if (beacon0_valid && beacon1_valid) {
b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON);
- dev->irq_savedstate |= B43_IRQ_BEACON;
+ dev->irq_mask |= B43_IRQ_BEACON;
return;
}
@@ -1641,11 +1615,9 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
spin_lock_irq(&wl->irq_lock);
/* update beacon right away or defer to irq */
- dev->irq_savedstate = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
handle_irq_beacon(dev);
/* The handler might have updated the IRQ mask. */
- b43_write32(dev, B43_MMIO_GEN_IRQ_MASK,
- dev->irq_savedstate);
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
mmiowb();
spin_unlock_irq(&wl->irq_lock);
}
@@ -1879,7 +1851,7 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
if (reason & B43_IRQ_TX_OK)
handle_irq_transmit_status(dev);
- b43_interrupt_enable(dev, dev->irq_savedstate);
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
mmiowb();
spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
}
@@ -1893,7 +1865,9 @@ static void b43_interrupt_ack(struct b43_wldev *dev, u32 reason)
b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
+/* Unused ring
b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
+*/
}
/* Interrupt handler top-half */
@@ -1903,18 +1877,19 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
struct b43_wldev *dev = dev_id;
u32 reason;
- if (!dev)
- return IRQ_NONE;
+ B43_WARN_ON(!dev);
spin_lock(&dev->wl->irq_lock);
- if (b43_status(dev) < B43_STAT_STARTED)
+ if (unlikely(b43_status(dev) < B43_STAT_STARTED)) {
+ /* This can only happen on shared IRQ lines. */
goto out;
+ }
reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
if (reason == 0xffffffff) /* shared IRQ */
goto out;
ret = IRQ_HANDLED;
- reason &= b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
+ reason &= dev->irq_mask;
if (!reason)
goto out;
@@ -1928,16 +1903,18 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
& 0x0001DC00;
dev->dma_reason[4] = b43_read32(dev, B43_MMIO_DMA4_REASON)
& 0x0000DC00;
+/* Unused ring
dev->dma_reason[5] = b43_read32(dev, B43_MMIO_DMA5_REASON)
& 0x0000DC00;
+*/
b43_interrupt_ack(dev, reason);
/* disable all IRQs. They are enabled again in the bottom half. */
- dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
/* save the reason code and call our bottom half. */
dev->irq_reason = reason;
tasklet_schedule(&dev->isr_tasklet);
- out:
+out:
mmiowb();
spin_unlock(&dev->wl->irq_lock);
@@ -2980,6 +2957,7 @@ static void b43_security_init(struct b43_wldev *dev)
b43_clear_keys(dev);
}
+#ifdef CONFIG_B43_HWRNG
static int b43_rng_read(struct hwrng *rng, u32 *data)
{
struct b43_wl *wl = (struct b43_wl *)rng->priv;
@@ -2995,17 +2973,21 @@ static int b43_rng_read(struct hwrng *rng, u32 *data)
return (sizeof(u16));
}
+#endif /* CONFIG_B43_HWRNG */
static void b43_rng_exit(struct b43_wl *wl)
{
+#ifdef CONFIG_B43_HWRNG
if (wl->rng_initialized)
hwrng_unregister(&wl->rng);
+#endif /* CONFIG_B43_HWRNG */
}
static int b43_rng_init(struct b43_wl *wl)
{
- int err;
+ int err = 0;
+#ifdef CONFIG_B43_HWRNG
snprintf(wl->rng_name, ARRAY_SIZE(wl->rng_name),
"%s_%s", KBUILD_MODNAME, wiphy_name(wl->hw->wiphy));
wl->rng.name = wl->rng_name;
@@ -3018,6 +3000,7 @@ static int b43_rng_init(struct b43_wl *wl)
b43err(wl, "Failed to register the random "
"number generator (%d)\n", err);
}
+#endif /* CONFIG_B43_HWRNG */
return err;
}
@@ -3485,11 +3468,6 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
if (phy->ops->set_rx_antenna)
phy->ops->set_rx_antenna(dev, antenna);
- /* Update templates for AP/mesh mode. */
- if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
- b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT))
- b43_set_beacon_int(dev, conf->beacon_int);
-
if (!!conf->radio_enabled != phy->radio_on) {
if (conf->radio_enabled) {
b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED);
@@ -3565,14 +3543,47 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
+ unsigned long flags;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (!dev || b43_status(dev) < B43_STAT_STARTED)
goto out_unlock_mutex;
+
+ B43_WARN_ON(wl->vif != vif);
+
+ if (changed & BSS_CHANGED_BSSID) {
+ spin_lock_irqsave(&wl->irq_lock, flags);
+ if (conf->bssid)
+ memcpy(wl->bssid, conf->bssid, ETH_ALEN);
+ else
+ memset(wl->bssid, 0, ETH_ALEN);
+
+ if (b43_status(dev) >= B43_STAT_INITIALIZED) {
+ if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
+ b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) {
+ B43_WARN_ON(vif->type != wl->if_type);
+ if (changed & BSS_CHANGED_BEACON)
+ b43_update_templates(wl);
+ } else if (b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
+ if (changed & BSS_CHANGED_BEACON)
+ b43_update_templates(wl);
+ }
+ b43_write_mac_bssid_templates(dev);
+ }
+ spin_unlock_irqrestore(&wl->irq_lock, flags);
+ }
+
b43_mac_suspend(dev);
+ /* Update templates for AP/mesh mode. */
+ if (changed & BSS_CHANGED_BEACON_INT &&
+ (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
+ b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
+ b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+ b43_set_beacon_int(dev, conf->beacon_int);
+
if (changed & BSS_CHANGED_BASIC_RATES)
b43_update_basic_rates(dev, conf->basic_rates);
@@ -3586,8 +3597,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
b43_mac_enable(dev);
out_unlock_mutex:
mutex_unlock(&wl->mutex);
-
- return;
}
static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -3745,41 +3754,6 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw,
spin_unlock_irqrestore(&wl->irq_lock, flags);
}
-static int b43_op_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct b43_wl *wl = hw_to_b43_wl(hw);
- struct b43_wldev *dev = wl->current_dev;
- unsigned long flags;
-
- if (!dev)
- return -ENODEV;
- mutex_lock(&wl->mutex);
- spin_lock_irqsave(&wl->irq_lock, flags);
- B43_WARN_ON(wl->vif != vif);
- if (conf->bssid)
- memcpy(wl->bssid, conf->bssid, ETH_ALEN);
- else
- memset(wl->bssid, 0, ETH_ALEN);
- if (b43_status(dev) >= B43_STAT_INITIALIZED) {
- if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
- b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) {
- B43_WARN_ON(vif->type != wl->if_type);
- if (conf->changed & IEEE80211_IFCC_BEACON)
- b43_update_templates(wl);
- } else if (b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
- if (conf->changed & IEEE80211_IFCC_BEACON)
- b43_update_templates(wl);
- }
- b43_write_mac_bssid_templates(dev);
- }
- spin_unlock_irqrestore(&wl->irq_lock, flags);
- mutex_unlock(&wl->mutex);
-
- return 0;
-}
-
/* Locking: wl->mutex */
static void b43_wireless_core_stop(struct b43_wldev *dev)
{
@@ -3793,7 +3767,7 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
* setting the status to INITIALIZED, as the interrupt handler
* won't care about IRQs then. */
spin_lock_irqsave(&wl->irq_lock, flags);
- dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
spin_unlock_irqrestore(&wl->irq_lock, flags);
b43_synchronize_irq(dev);
@@ -3834,7 +3808,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
/* Start data flow (TX/RX). */
b43_mac_enable(dev);
- b43_interrupt_enable(dev, dev->irq_savedstate);
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
/* Start maintainance work */
b43_periodic_tasks_setup(dev);
@@ -3997,9 +3971,9 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)
/* IRQ related flags */
dev->irq_reason = 0;
memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
- dev->irq_savedstate = B43_IRQ_MASKTEMPLATE;
+ dev->irq_mask = B43_IRQ_MASKTEMPLATE;
if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
- dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR;
+ dev->irq_mask &= ~B43_IRQ_PHY_TXERR;
dev->mac_suspended = 1;
@@ -4449,7 +4423,6 @@ static const struct ieee80211_ops b43_hw_ops = {
.remove_interface = b43_op_remove_interface,
.config = b43_op_config,
.bss_info_changed = b43_op_bss_info_changed,
- .config_interface = b43_op_config_interface,
.configure_filter = b43_op_configure_filter,
.set_key = b43_op_set_key,
.get_stats = b43_op_get_stats,
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig
index aef2298d37ac..d4f628a74bbd 100644
--- a/drivers/net/wireless/b43legacy/Kconfig
+++ b/drivers/net/wireless/b43legacy/Kconfig
@@ -3,7 +3,6 @@ config B43LEGACY
depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA
select SSB
select FW_LOADER
- select HW_RANDOM
---help---
b43legacy is a driver for 802.11b devices from Broadcom (BCM4301 and
BCM4303) and early model 802.11g chips (BCM4306 Ver. 2) used in the
@@ -51,6 +50,13 @@ config B43LEGACY_RFKILL
depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY)
default y
+# This config option automatically enables b43 HW-RNG support,
+# if the HW-RNG core is enabled.
+config B43LEGACY_HWRNG
+ bool
+ depends on B43LEGACY && (HW_RANDOM = y || HW_RANDOM = B43LEGACY)
+ default y
+
config B43LEGACY_DEBUG
bool "Broadcom 43xx-legacy debugging"
depends on B43LEGACY
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index 97b0e06dfe21..da59ef02b6ef 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -59,7 +59,8 @@
#define B43legacy_MMIO_XMITSTAT_1 0x174
#define B43legacy_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */
#define B43legacy_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
-
+#define B43legacy_MMIO_TSF_CFP_REP 0x188
+#define B43legacy_MMIO_TSF_CFP_START 0x18C
/* 32-bit DMA */
#define B43legacy_MMIO_DMA32_BASE0 0x200
#define B43legacy_MMIO_DMA32_BASE1 0x220
@@ -258,7 +259,6 @@
#define B43legacy_IRQ_ALL 0xFFFFFFFF
#define B43legacy_IRQ_MASKTEMPLATE (B43legacy_IRQ_MAC_SUSPENDED | \
- B43legacy_IRQ_BEACON | \
B43legacy_IRQ_TBTT_INDI | \
B43legacy_IRQ_ATIM_END | \
B43legacy_IRQ_PMQ | \
@@ -596,9 +596,11 @@ struct b43legacy_wl {
/* Stats about the wireless interface */
struct ieee80211_low_level_stats ieee_stats;
+#ifdef CONFIG_B43LEGACY_HWRNG
struct hwrng rng;
u8 rng_initialized;
char rng_name[30 + 1];
+#endif
/* The RF-kill button */
struct b43legacy_rfkill rfkill;
@@ -614,6 +616,8 @@ struct b43legacy_wl {
struct sk_buff *current_beacon;
bool beacon0_uploaded;
bool beacon1_uploaded;
+ bool beacon_templates_virgin; /* Never wrote the templates? */
+ struct work_struct beacon_update_trigger;
};
/* Pointers to the firmware data and meta information about it. */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 879edc786713..07c7898c87ac 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -955,23 +955,54 @@ static void b43legacy_write_template_common(struct b43legacy_wldev *dev,
size + sizeof(struct b43legacy_plcp_hdr6));
}
+/* Convert a b43legacy antenna number value to the PHY TX control value. */
+static u16 b43legacy_antenna_to_phyctl(int antenna)
+{
+ switch (antenna) {
+ case B43legacy_ANTENNA0:
+ return B43legacy_TX4_PHY_ANT0;
+ case B43legacy_ANTENNA1:
+ return B43legacy_TX4_PHY_ANT1;
+ }
+ return B43legacy_TX4_PHY_ANTLAST;
+}
+
static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev,
u16 ram_offset,
- u16 shm_size_offset, u8 rate)
+ u16 shm_size_offset)
{
unsigned int i, len, variable_len;
const struct ieee80211_mgmt *bcn;
const u8 *ie;
bool tim_found = 0;
+ unsigned int rate;
+ u16 ctl;
+ int antenna;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon);
bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
len = min((size_t)dev->wl->current_beacon->len,
0x200 - sizeof(struct b43legacy_plcp_hdr6));
+ rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
b43legacy_write_template_common(dev, (const u8 *)bcn, len, ram_offset,
shm_size_offset, rate);
+ /* Write the PHY TX control parameters. */
+ antenna = B43legacy_ANTENNA_DEFAULT;
+ antenna = b43legacy_antenna_to_phyctl(antenna);
+ ctl = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
+ B43legacy_SHM_SH_BEACPHYCTL);
+ /* We can't send beacons with short preamble. Would get PHY errors. */
+ ctl &= ~B43legacy_TX4_PHY_SHORTPRMBL;
+ ctl &= ~B43legacy_TX4_PHY_ANT;
+ ctl &= ~B43legacy_TX4_PHY_ENC;
+ ctl |= antenna;
+ ctl |= B43legacy_TX4_PHY_ENC_CCK;
+ b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
+ B43legacy_SHM_SH_BEACPHYCTL, ctl);
+
/* Find the position of the TIM and the DTIM_period value
* and write them to SHM. */
ie = bcn->u.beacon.variable;
@@ -1013,7 +1044,8 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev,
b43legacywarn(dev->wl, "Did not find a valid TIM IE in the "
"beacon template packet. AP or IBSS operation "
"may be broken.\n");
- }
+ } else
+ b43legacydbg(dev->wl, "Updated beacon template\n");
}
static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
@@ -1025,7 +1057,7 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
__le16 dur;
plcp.data = 0;
- b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->bitrate);
+ b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value);
dur = ieee80211_generic_frame_duration(dev->wl->hw,
dev->wl->vif,
size,
@@ -1129,10 +1161,104 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
0x200 - sizeof(struct b43legacy_plcp_hdr6));
b43legacy_write_template_common(dev, probe_resp_data,
size, ram_offset,
- shm_size_offset, rate->bitrate);
+ shm_size_offset, rate->hw_value);
kfree(probe_resp_data);
}
+static void b43legacy_upload_beacon0(struct b43legacy_wldev *dev)
+{
+ struct b43legacy_wl *wl = dev->wl;
+
+ if (wl->beacon0_uploaded)
+ return;
+ b43legacy_write_beacon_template(dev, 0x68, 0x18);
+ /* FIXME: Probe resp upload doesn't really belong here,
+ * but we don't use that feature anyway. */
+ b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
+ &__b43legacy_ratetable[3]);
+ wl->beacon0_uploaded = 1;
+}
+
+static void b43legacy_upload_beacon1(struct b43legacy_wldev *dev)
+{
+ struct b43legacy_wl *wl = dev->wl;
+
+ if (wl->beacon1_uploaded)
+ return;
+ b43legacy_write_beacon_template(dev, 0x468, 0x1A);
+ wl->beacon1_uploaded = 1;
+}
+
+static void handle_irq_beacon(struct b43legacy_wldev *dev)
+{
+ struct b43legacy_wl *wl = dev->wl;
+ u32 cmd, beacon0_valid, beacon1_valid;
+
+ if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
+ return;
+
+ /* This is the bottom half of the asynchronous beacon update. */
+
+ /* Ignore interrupt in the future. */
+ dev->irq_savedstate &= ~B43legacy_IRQ_BEACON;
+
+ cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+ beacon0_valid = (cmd & B43legacy_MACCMD_BEACON0_VALID);
+ beacon1_valid = (cmd & B43legacy_MACCMD_BEACON1_VALID);
+
+ /* Schedule interrupt manually, if busy. */
+ if (beacon0_valid && beacon1_valid) {
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, B43legacy_IRQ_BEACON);
+ dev->irq_savedstate |= B43legacy_IRQ_BEACON;
+ return;
+ }
+
+ if (unlikely(wl->beacon_templates_virgin)) {
+ /* We never uploaded a beacon before.
+ * Upload both templates now, but only mark one valid. */
+ wl->beacon_templates_virgin = 0;
+ b43legacy_upload_beacon0(dev);
+ b43legacy_upload_beacon1(dev);
+ cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+ cmd |= B43legacy_MACCMD_BEACON0_VALID;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+ } else {
+ if (!beacon0_valid) {
+ b43legacy_upload_beacon0(dev);
+ cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+ cmd |= B43legacy_MACCMD_BEACON0_VALID;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+ } else if (!beacon1_valid) {
+ b43legacy_upload_beacon1(dev);
+ cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+ cmd |= B43legacy_MACCMD_BEACON1_VALID;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+ }
+ }
+}
+
+static void b43legacy_beacon_update_trigger_work(struct work_struct *work)
+{
+ struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl,
+ beacon_update_trigger);
+ struct b43legacy_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+ if (likely(dev && (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED))) {
+ spin_lock_irq(&wl->irq_lock);
+ /* update beacon right away or defer to irq */
+ dev->irq_savedstate = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK);
+ handle_irq_beacon(dev);
+ /* The handler might have updated the IRQ mask. */
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK,
+ dev->irq_savedstate);
+ mmiowb();
+ spin_unlock_irq(&wl->irq_lock);
+ }
+ mutex_unlock(&wl->mutex);
+}
+
/* Asynchronously update the packet templates in template RAM.
* Locking: Requires wl->irq_lock to be locked. */
static void b43legacy_update_templates(struct b43legacy_wl *wl)
@@ -1156,54 +1282,24 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl)
wl->current_beacon = beacon;
wl->beacon0_uploaded = 0;
wl->beacon1_uploaded = 0;
+ queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
}
static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev,
u16 beacon_int)
{
b43legacy_time_lock(dev);
- if (dev->dev->id.revision >= 3)
- b43legacy_write32(dev, 0x188, (beacon_int << 16));
- else {
+ if (dev->dev->id.revision >= 3) {
+ b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_REP,
+ (beacon_int << 16));
+ b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_START,
+ (beacon_int << 10));
+ } else {
b43legacy_write16(dev, 0x606, (beacon_int >> 6));
b43legacy_write16(dev, 0x610, beacon_int);
}
b43legacy_time_unlock(dev);
-}
-
-static void handle_irq_beacon(struct b43legacy_wldev *dev)
-{
- struct b43legacy_wl *wl = dev->wl;
- u32 cmd;
-
- if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
- return;
-
- /* This is the bottom half of the asynchronous beacon update. */
-
- cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
- if (!(cmd & B43legacy_MACCMD_BEACON0_VALID)) {
- if (!wl->beacon0_uploaded) {
- b43legacy_write_beacon_template(dev, 0x68,
- B43legacy_SHM_SH_BTL0,
- B43legacy_CCK_RATE_1MB);
- b43legacy_write_probe_resp_template(dev, 0x268,
- B43legacy_SHM_SH_PRTLEN,
- &__b43legacy_ratetable[3]);
- wl->beacon0_uploaded = 1;
- }
- cmd |= B43legacy_MACCMD_BEACON0_VALID;
- }
- if (!(cmd & B43legacy_MACCMD_BEACON1_VALID)) {
- if (!wl->beacon1_uploaded) {
- b43legacy_write_beacon_template(dev, 0x468,
- B43legacy_SHM_SH_BTL1,
- B43legacy_CCK_RATE_1MB);
- wl->beacon1_uploaded = 1;
- }
- cmd |= B43legacy_MACCMD_BEACON1_VALID;
- }
- b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+ b43legacydbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
}
static void handle_irq_ucode_debug(struct b43legacy_wldev *dev)
@@ -2297,6 +2393,7 @@ static void b43legacy_security_init(struct b43legacy_wldev *dev)
dev->max_nr_keys - 8);
}
+#ifdef CONFIG_B43LEGACY_HWRNG
static int b43legacy_rng_read(struct hwrng *rng, u32 *data)
{
struct b43legacy_wl *wl = (struct b43legacy_wl *)rng->priv;
@@ -2312,17 +2409,21 @@ static int b43legacy_rng_read(struct hwrng *rng, u32 *data)
return (sizeof(u16));
}
+#endif
static void b43legacy_rng_exit(struct b43legacy_wl *wl)
{
+#ifdef CONFIG_B43LEGACY_HWRNG
if (wl->rng_initialized)
hwrng_unregister(&wl->rng);
+#endif
}
static int b43legacy_rng_init(struct b43legacy_wl *wl)
{
- int err;
+ int err = 0;
+#ifdef CONFIG_B43LEGACY_HWRNG
snprintf(wl->rng_name, ARRAY_SIZE(wl->rng_name),
"%s_%s", KBUILD_MODNAME, wiphy_name(wl->hw->wiphy));
wl->rng.name = wl->rng_name;
@@ -2336,6 +2437,7 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl)
"number generator (%d)\n", err);
}
+#endif
return err;
}
@@ -2619,11 +2721,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
/* Antennas for RX and management frame TX. */
b43legacy_mgmtframe_txantenna(dev, antenna_tx);
- /* Update templates for AP mode. */
- if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
- b43legacy_set_beacon_int(dev, conf->beacon_int);
-
-
if (!!conf->radio_enabled != phy->radio_on) {
if (conf->radio_enabled) {
b43legacy_radio_turn_on(dev);
@@ -2707,6 +2804,7 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
u32 savedirqs;
mutex_lock(&wl->mutex);
+ B43legacy_WARN_ON(wl->vif != vif);
dev = wl->current_dev;
phy = &dev->phy;
@@ -2720,11 +2818,37 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
goto out_unlock_mutex;
}
savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
- spin_unlock_irqrestore(&wl->irq_lock, flags);
- b43legacy_synchronize_irq(dev);
+
+ if (changed & BSS_CHANGED_BSSID) {
+ spin_unlock_irqrestore(&wl->irq_lock, flags);
+ b43legacy_synchronize_irq(dev);
+
+ if (conf->bssid)
+ memcpy(wl->bssid, conf->bssid, ETH_ALEN);
+ else
+ memset(wl->bssid, 0, ETH_ALEN);
+
+ if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
+ if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) {
+ B43legacy_WARN_ON(vif->type != NL80211_IFTYPE_AP);
+ if (changed & BSS_CHANGED_BEACON)
+ b43legacy_update_templates(wl);
+ } else if (b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
+ if (changed & BSS_CHANGED_BEACON)
+ b43legacy_update_templates(wl);
+ }
+ b43legacy_write_mac_bssid_templates(dev);
+ }
+ spin_unlock_irqrestore(&wl->irq_lock, flags);
+ }
b43legacy_mac_suspend(dev);
+ if (changed & BSS_CHANGED_BEACON_INT &&
+ (b43legacy_is_mode(wl, NL80211_IFTYPE_AP) ||
+ b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+ b43legacy_set_beacon_int(dev, conf->beacon_int);
+
if (changed & BSS_CHANGED_BASIC_RATES)
b43legacy_update_basic_rates(dev, conf->basic_rates);
@@ -2744,8 +2868,6 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
spin_unlock_irqrestore(&wl->irq_lock, flags);
out_unlock_mutex:
mutex_unlock(&wl->mutex);
-
- return;
}
static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
@@ -2787,40 +2909,6 @@ static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
spin_unlock_irqrestore(&wl->irq_lock, flags);
}
-static int b43legacy_op_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
- struct b43legacy_wldev *dev = wl->current_dev;
- unsigned long flags;
-
- if (!dev)
- return -ENODEV;
- mutex_lock(&wl->mutex);
- spin_lock_irqsave(&wl->irq_lock, flags);
- B43legacy_WARN_ON(wl->vif != vif);
- if (conf->bssid)
- memcpy(wl->bssid, conf->bssid, ETH_ALEN);
- else
- memset(wl->bssid, 0, ETH_ALEN);
- if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
- if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) {
- B43legacy_WARN_ON(vif->type != NL80211_IFTYPE_AP);
- if (conf->changed & IEEE80211_IFCC_BEACON)
- b43legacy_update_templates(wl);
- } else if (b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
- if (conf->changed & IEEE80211_IFCC_BEACON)
- b43legacy_update_templates(wl);
- }
- b43legacy_write_mac_bssid_templates(dev);
- }
- spin_unlock_irqrestore(&wl->irq_lock, flags);
- mutex_unlock(&wl->mutex);
-
- return 0;
-}
-
/* Locking: wl->mutex */
static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
{
@@ -3392,6 +3480,9 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
memset(wl->bssid, 0, ETH_ALEN);
memset(wl->mac_addr, 0, ETH_ALEN);
wl->filter_flags = 0;
+ wl->beacon0_uploaded = 0;
+ wl->beacon1_uploaded = 0;
+ wl->beacon_templates_virgin = 1;
mutex_lock(&wl->mutex);
@@ -3429,6 +3520,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw)
struct b43legacy_wldev *dev = wl->current_dev;
b43legacy_rfkill_exit(dev);
+ cancel_work_sync(&(wl->beacon_update_trigger));
mutex_lock(&wl->mutex);
if (b43legacy_status(dev) >= B43legacy_STAT_STARTED)
@@ -3457,7 +3549,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
.remove_interface = b43legacy_op_remove_interface,
.config = b43legacy_op_dev_config,
.bss_info_changed = b43legacy_op_bss_info_changed,
- .config_interface = b43legacy_op_config_interface,
.configure_filter = b43legacy_op_configure_filter,
.get_stats = b43legacy_op_get_stats,
.get_tx_stats = b43legacy_op_get_tx_stats,
@@ -3760,6 +3851,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
spin_lock_init(&wl->leds_lock);
mutex_init(&wl->mutex);
INIT_LIST_HEAD(&wl->devlist);
+ INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work);
ssb_set_devtypedata(dev, wl);
b43legacyinfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index 12fca99f7578..b8e39dd06e99 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -274,7 +274,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
/* PHY TX Control word */
if (rate_ofdm)
- phy_ctl |= B43legacy_TX4_PHY_OFDM;
+ phy_ctl |= B43legacy_TX4_PHY_ENC_OFDM;
if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL;
switch (info->antenna_sel_tx) {
diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h
index 62e09d02788f..91633087a20b 100644
--- a/drivers/net/wireless/b43legacy/xmit.h
+++ b/drivers/net/wireless/b43legacy/xmit.h
@@ -67,7 +67,9 @@ struct b43legacy_txhdr_fw3 {
#define B43legacy_TX4_EFT_RTSFBOFDM 0x0010 /* RTS/CTS fallback rate type */
/* PHY TX control word */
-#define B43legacy_TX4_PHY_OFDM 0x0001 /* Data frame rate type */
+#define B43legacy_TX4_PHY_ENC 0x0003 /* Data frame encoding */
+#define B43legacy_TX4_PHY_ENC_CCK 0x0000 /* CCK */
+#define B43legacy_TX4_PHY_ENC_OFDM 0x0001 /* Data frame rate type */
#define B43legacy_TX4_PHY_SHORTPRMBL 0x0010 /* Use short preamble */
#define B43legacy_TX4_PHY_ANT 0x03C0 /* Antenna selection */
#define B43legacy_TX4_PHY_ANT0 0x0000 /* Use antenna 0 */
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 3dad1cf8f241..ff9b5c882184 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -1423,7 +1423,7 @@ static int prism2_hw_init2(struct net_device *dev, int initial)
prism2_check_sta_fw_version(local);
if (hfa384x_get_rid(dev, HFA384X_RID_CNFOWNMACADDR,
- &dev->dev_addr, 6, 1) < 0) {
+ dev->dev_addr, 6, 1) < 0) {
printk("%s: could not get own MAC address\n",
dev->name);
}
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index cbf15d703201..0e5d51086a44 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -435,7 +435,7 @@ static int prism2_plx_probe(struct pci_dev *pdev,
unsigned long pccard_attr_mem;
unsigned int pccard_attr_len;
void __iomem *attr_mem = NULL;
- unsigned int cor_offset, cor_index;
+ unsigned int cor_offset = 0, cor_index = 0;
u32 reg;
local_info_t *local = NULL;
struct net_device *dev = NULL;
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 97e5647ff050..742432388ca3 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -3488,7 +3488,7 @@ static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw2100_priv *p = d->driver_data;
+ struct ipw2100_priv *p = dev_get_drvdata(d);
return sprintf(buf, "0x%08x\n", (int)p->config);
}
@@ -3497,7 +3497,7 @@ static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
static ssize_t show_status(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw2100_priv *p = d->driver_data;
+ struct ipw2100_priv *p = dev_get_drvdata(d);
return sprintf(buf, "0x%08x\n", (int)p->status);
}
@@ -3506,7 +3506,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
static ssize_t show_capability(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw2100_priv *p = d->driver_data;
+ struct ipw2100_priv *p = dev_get_drvdata(d);
return sprintf(buf, "0x%08x\n", (int)p->capability);
}
@@ -4224,7 +4224,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
1 - SW based RF kill active (sysfs)
2 - HW based RF kill active
3 - Both HW and SW baed RF kill active */
- struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
+ struct ipw2100_priv *priv = dev_get_drvdata(d);
int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
(rf_kill_active(priv) ? 0x2 : 0x0);
return sprintf(buf, "%i\n", val);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index bd4dbcfe1bbe..c3b3dfe43d1a 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -1527,7 +1527,7 @@ static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
static ssize_t show_status(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
return sprintf(buf, "0x%08x\n", (int)p->status);
}
@@ -1536,7 +1536,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
return sprintf(buf, "0x%08x\n", (int)p->config);
}
@@ -1545,7 +1545,7 @@ static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
static ssize_t show_nic_type(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "TYPE: %d\n", priv->nic_type);
}
@@ -1555,7 +1555,7 @@ static ssize_t show_ucode_version(struct device *d,
struct device_attribute *attr, char *buf)
{
u32 len = sizeof(u32), tmp = 0;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len))
return 0;
@@ -1569,7 +1569,7 @@ static ssize_t show_rtc(struct device *d, struct device_attribute *attr,
char *buf)
{
u32 len = sizeof(u32), tmp = 0;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len))
return 0;
@@ -1586,14 +1586,15 @@ static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL);
static ssize_t show_eeprom_delay(struct device *d,
struct device_attribute *attr, char *buf)
{
- int n = ((struct ipw_priv *)d->driver_data)->eeprom_delay;
+ struct ipw_priv *p = dev_get_drvdata(d);
+ int n = p->eeprom_delay;
return sprintf(buf, "%i\n", n);
}
static ssize_t store_eeprom_delay(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
sscanf(buf, "%i", &p->eeprom_delay);
return strnlen(buf, count);
}
@@ -1605,7 +1606,7 @@ static ssize_t show_command_event_reg(struct device *d,
struct device_attribute *attr, char *buf)
{
u32 reg = 0;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
return sprintf(buf, "0x%08x\n", reg);
@@ -1615,7 +1616,7 @@ static ssize_t store_command_event_reg(struct device *d,
const char *buf, size_t count)
{
u32 reg;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
sscanf(buf, "%x", &reg);
ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
@@ -1629,7 +1630,7 @@ static ssize_t show_mem_gpio_reg(struct device *d,
struct device_attribute *attr, char *buf)
{
u32 reg = 0;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
reg = ipw_read_reg32(p, 0x301100);
return sprintf(buf, "0x%08x\n", reg);
@@ -1639,7 +1640,7 @@ static ssize_t store_mem_gpio_reg(struct device *d,
const char *buf, size_t count)
{
u32 reg;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
sscanf(buf, "%x", &reg);
ipw_write_reg32(p, 0x301100, reg);
@@ -1653,7 +1654,7 @@ static ssize_t show_indirect_dword(struct device *d,
struct device_attribute *attr, char *buf)
{
u32 reg = 0;
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
if (priv->status & STATUS_INDIRECT_DWORD)
reg = ipw_read_reg32(priv, priv->indirect_dword);
@@ -1666,7 +1667,7 @@ static ssize_t store_indirect_dword(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
sscanf(buf, "%x", &priv->indirect_dword);
priv->status |= STATUS_INDIRECT_DWORD;
@@ -1680,7 +1681,7 @@ static ssize_t show_indirect_byte(struct device *d,
struct device_attribute *attr, char *buf)
{
u8 reg = 0;
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
if (priv->status & STATUS_INDIRECT_BYTE)
reg = ipw_read_reg8(priv, priv->indirect_byte);
@@ -1693,7 +1694,7 @@ static ssize_t store_indirect_byte(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
sscanf(buf, "%x", &priv->indirect_byte);
priv->status |= STATUS_INDIRECT_BYTE;
@@ -1707,7 +1708,7 @@ static ssize_t show_direct_dword(struct device *d,
struct device_attribute *attr, char *buf)
{
u32 reg = 0;
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
if (priv->status & STATUS_DIRECT_DWORD)
reg = ipw_read32(priv, priv->direct_dword);
@@ -1720,7 +1721,7 @@ static ssize_t store_direct_dword(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
sscanf(buf, "%x", &priv->direct_dword);
priv->status |= STATUS_DIRECT_DWORD;
@@ -1747,7 +1748,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
1 - SW based RF kill active (sysfs)
2 - HW based RF kill active
3 - Both HW and SW baed RF kill active */
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
(rf_kill_active(priv) ? 0x2 : 0x0);
return sprintf(buf, "%i\n", val);
@@ -1791,7 +1792,7 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
ipw_radio_kill_sw(priv, buf[0] == '1');
@@ -1803,7 +1804,7 @@ static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
int pos = 0, len = 0;
if (priv->config & CFG_SPEED_SCAN) {
while (priv->speed_scan[pos] != 0)
@@ -1818,7 +1819,7 @@ static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
int channel, pos = 0;
const char *p = buf;
@@ -1857,14 +1858,14 @@ static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
}
static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
if (buf[0] == '1')
priv->config |= CFG_NET_STATS;
else
@@ -3176,11 +3177,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
/* Start the Dma */
rc = ipw_fw_dma_enable(priv);
- if (priv->sram_desc.last_cb_index > 0) {
- /* the DMA is already ready this would be a bug. */
- BUG();
- goto out;
- }
+ /* the DMA is already ready this would be a bug. */
+ BUG_ON(priv->sram_desc.last_cb_index > 0);
do {
chunk = (struct fw_chunk *)(data + offset);
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 92a26922e792..8ce6e961c5da 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -154,10 +154,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
goto failed;
}
ieee = netdev_priv(dev);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
- dev->hard_start_xmit = ieee80211_xmit;
- dev->change_mtu = ieee80211_change_mtu;
-#endif
ieee->dev = dev;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index af6b9d444778..814afaf6d10b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -683,11 +683,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
if (sta)
rate_mask = sta->supp_rates[sband->band];
- /* Send management frames and broadcast/multicast data using lowest
- * rate. */
+ /* Send management frames and NO_ACK data using lowest rate. */
fc = le16_to_cpu(hdr->frame_control);
if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
- is_multicast_ether_addr(hdr->addr1) ||
+ info->flags & IEEE80211_TX_CTL_NO_ACK ||
!sta || !priv_sta) {
IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
if (!rate_mask)
@@ -696,6 +695,8 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
else
info->control.rates[0].idx =
rate_lowest_index(sband, sta);
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ info->control.rates[0].count = 1;
return;
}
@@ -719,7 +720,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n",
hdr->addr1);
sta_id = iwl3945_add_station(priv,
- hdr->addr1, 0, CMD_ASYNC);
+ hdr->addr1, 0, CMD_ASYNC, NULL);
}
if (sta_id != IWL_INVALID_STATION)
rs_sta->ibss_sta_added = 1;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 527525cc0919..5b0c6e5bda92 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1110,6 +1110,11 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
spin_lock_irqsave(&priv->lock, flags);
+ /* Determine HW type */
+ pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
+
+ IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
+
if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
IWL_DEBUG_INFO(priv, "RTP type \n");
else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
@@ -1163,7 +1168,6 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
int iwl3945_hw_nic_init(struct iwl_priv *priv)
{
- u8 rev_id;
int rc;
unsigned long flags;
struct iwl_rx_queue *rxq = &priv->rxq;
@@ -1172,12 +1176,6 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
priv->cfg->ops->lib->apm_ops.init(priv);
spin_unlock_irqrestore(&priv->lock, flags);
- /* Determine HW type */
- rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
- if (rc)
- return rc;
- IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
-
rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
if (rc)
return rc;
@@ -1964,6 +1962,194 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
return 0;
}
+static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
+{
+ int rc = 0;
+ struct iwl_rx_packet *res = NULL;
+ struct iwl3945_rxon_assoc_cmd rxon_assoc;
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_RXON_ASSOC,
+ .len = sizeof(rxon_assoc),
+ .meta.flags = CMD_WANT_SKB,
+ .data = &rxon_assoc,
+ };
+ const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
+ const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
+
+ if ((rxon1->flags == rxon2->flags) &&
+ (rxon1->filter_flags == rxon2->filter_flags) &&
+ (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
+ (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
+ return 0;
+ }
+
+ rxon_assoc.flags = priv->staging_rxon.flags;
+ rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
+ rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+ rxon_assoc.reserved = 0;
+
+ rc = iwl_send_cmd_sync(priv, &cmd);
+ if (rc)
+ return rc;
+
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+ if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+ IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
+ rc = -EIO;
+ }
+
+ priv->alloc_rxb_skb--;
+ dev_kfree_skb_any(cmd.meta.u.skb);
+
+ return rc;
+}
+
+/**
+ * iwl3945_commit_rxon - commit staging_rxon to hardware
+ *
+ * The RXON command in staging_rxon is committed to the hardware and
+ * the active_rxon structure is updated with the new data. This
+ * function correctly transitions out of the RXON_ASSOC_MSK state if
+ * a HW tune is required based on the RXON structure changes.
+ */
+static int iwl3945_commit_rxon(struct iwl_priv *priv)
+{
+ /* cast away the const for active_rxon in this function */
+ struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+ struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
+ int rc = 0;
+ bool new_assoc =
+ !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
+
+ if (!iwl_is_alive(priv))
+ return -1;
+
+ /* always get timestamp with Rx frame */
+ staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
+
+ /* select antenna */
+ staging_rxon->flags &=
+ ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
+ staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
+
+ rc = iwl_check_rxon_cmd(priv);
+ if (rc) {
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
+ return -EINVAL;
+ }
+
+ /* If we don't need to send a full RXON, we can use
+ * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
+ * and other flags for the current radio configuration. */
+ if (!iwl_full_rxon_required(priv)) {
+ rc = iwl_send_rxon_assoc(priv);
+ if (rc) {
+ IWL_ERR(priv, "Error setting RXON_ASSOC "
+ "configuration (%d).\n", rc);
+ return rc;
+ }
+
+ memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
+
+ return 0;
+ }
+
+ /* If we are currently associated and the new config requires
+ * an RXON_ASSOC and the new config wants the associated mask enabled,
+ * we must clear the associated from the active configuration
+ * before we apply the new config */
+ if (iwl_is_associated(priv) && new_assoc) {
+ IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
+ active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+
+ /*
+ * reserved4 and 5 could have been filled by the iwlcore code.
+ * Let's clear them before pushing to the 3945.
+ */
+ active_rxon->reserved4 = 0;
+ active_rxon->reserved5 = 0;
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+ sizeof(struct iwl3945_rxon_cmd),
+ &priv->active_rxon);
+
+ /* If the mask clearing failed then we set
+ * active_rxon back to what it was previously */
+ if (rc) {
+ active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
+ IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
+ "configuration (%d).\n", rc);
+ return rc;
+ }
+ }
+
+ IWL_DEBUG_INFO(priv, "Sending RXON\n"
+ "* with%s RXON_FILTER_ASSOC_MSK\n"
+ "* channel = %d\n"
+ "* bssid = %pM\n",
+ (new_assoc ? "" : "out"),
+ le16_to_cpu(staging_rxon->channel),
+ staging_rxon->bssid_addr);
+
+ /*
+ * reserved4 and 5 could have been filled by the iwlcore code.
+ * Let's clear them before pushing to the 3945.
+ */
+ staging_rxon->reserved4 = 0;
+ staging_rxon->reserved5 = 0;
+
+ iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
+
+ /* Apply the new configuration */
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+ sizeof(struct iwl3945_rxon_cmd),
+ staging_rxon);
+ if (rc) {
+ IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
+ return rc;
+ }
+
+ memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
+
+ priv->cfg->ops->smgmt->clear_station_table(priv);
+
+ /* If we issue a new RXON command which required a tune then we must
+ * send a new TXPOWER command or we won't be able to Tx any frames */
+ rc = priv->cfg->ops->lib->send_tx_power(priv);
+ if (rc) {
+ IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
+ return rc;
+ }
+
+ /* Add the broadcast address so we can send broadcast frames */
+ if (priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL) ==
+ IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
+ return -EIO;
+ }
+
+ /* If we have set the ASSOC_MSK and we are in BSS mode then
+ * add the IWL_AP_ID to the station rate table */
+ if (iwl_is_associated(priv) &&
+ (priv->iw_mode == NL80211_IFTYPE_STATION))
+ if (priv->cfg->ops->smgmt->add_station(priv,
+ priv->active_rxon.bssid_addr, 1, 0, NULL)
+ == IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Error adding AP address for transmit\n");
+ return -EIO;
+ }
+
+ /* Init the hardware's rate fallback order based on the band */
+ rc = iwl3945_init_hw_rate_table(priv);
+ if (rc) {
+ IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
+ return -EIO;
+ }
+
+ return 0;
+}
+
/* will add 3945 channel switch cmd handling later */
int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
{
@@ -2729,6 +2915,11 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
return 0;
}
+static struct iwl_hcmd_ops iwl3945_hcmd = {
+ .rxon_assoc = iwl3945_send_rxon_assoc,
+ .commit_rxon = iwl3945_commit_rxon,
+};
+
static struct iwl_lib_ops iwl3945_lib = {
.txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl3945_hw_txq_free_tfd,
@@ -2758,6 +2949,17 @@ static struct iwl_lib_ops iwl3945_lib = {
},
.send_tx_power = iwl3945_send_tx_power,
.is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
+ .post_associate = iwl3945_post_associate,
+ .config_ap = iwl3945_config_ap,
+};
+
+static struct iwl_station_mgmt_ops iwl3945_station_mgmt = {
+ .add_station = iwl3945_add_station,
+#if 0
+ .remove_station = iwl3945_remove_station,
+#endif
+ .find_station = iwl3945_hw_find_station,
+ .clear_station_table = iwl3945_clear_stations_table,
};
static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
@@ -2767,7 +2969,9 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
static struct iwl_ops iwl3945_ops = {
.lib = &iwl3945_lib,
+ .hcmd = &iwl3945_hcmd,
.utils = &iwl3945_hcmd_utils,
+ .smgmt = &iwl3945_station_mgmt,
};
static struct iwl_cfg iwl3945_bg_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 55188844657b..da87528f355f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -162,7 +162,6 @@ struct iwl3945_frame {
#define STATUS_TEMPERATURE 8
#define STATUS_GEO_CONFIGURED 9
#define STATUS_EXIT_PENDING 10
-#define STATUS_IN_SUSPEND 11
#define STATUS_STATISTICS 12
#define STATUS_SCANNING 13
#define STATUS_SCAN_ABORTING 14
@@ -207,7 +206,8 @@ struct iwl3945_addsta_cmd;
extern int iwl3945_send_add_station(struct iwl_priv *priv,
struct iwl3945_addsta_cmd *sta, u8 flags);
extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid,
- int is_ap, u8 flags);
+ int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info);
+extern void iwl3945_clear_stations_table(struct iwl_priv *priv);
extern int iwl3945_power_init_handle(struct iwl_priv *priv);
extern int iwl3945_eeprom_init(struct iwl_priv *priv);
extern int iwl3945_calc_db_from_ratio(int sig_ratio);
@@ -278,6 +278,8 @@ extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
extern void iwl3945_disable_events(struct iwl_priv *priv);
extern int iwl4965_get_temperature(const struct iwl_priv *priv);
+extern void iwl3945_post_associate(struct iwl_priv *priv);
+extern void iwl3945_config_ap(struct iwl_priv *priv);
/**
* iwl3945_hw_find_station - Find station id for a given BSSID
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 847a6220c5e6..a98ff4ead720 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2268,9 +2268,17 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
cancel_work_sync(&priv->txpower_work);
}
+static struct iwl_station_mgmt_ops iwl4965_station_mgmt = {
+ .add_station = iwl_add_station_flags,
+ .remove_station = iwl_remove_station,
+ .find_station = iwl_find_station,
+ .clear_station_table = iwl_clear_stations_table,
+};
static struct iwl_hcmd_ops iwl4965_hcmd = {
.rxon_assoc = iwl4965_send_rxon_assoc,
+ .commit_rxon = iwl_commit_rxon,
+ .set_rxon_chain = iwl_set_rxon_chain,
};
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
@@ -2324,12 +2332,15 @@ static struct iwl_lib_ops iwl4965_lib = {
.send_tx_power = iwl4965_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.temperature = iwl4965_temperature_calib,
+ .post_associate = iwl_post_associate,
+ .config_ap = iwl_config_ap,
};
static struct iwl_ops iwl4965_ops = {
.lib = &iwl4965_lib,
.hcmd = &iwl4965_hcmd,
.utils = &iwl4965_hcmd_utils,
+ .smgmt = &iwl4965_station_mgmt,
};
struct iwl_cfg iwl4965_agn_cfg = {
@@ -2350,8 +2361,6 @@ MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX));
module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl4965_mod_params.disable, int, 0444);
-MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444);
MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
module_param_named(debug, iwl4965_mod_params.debug, uint, 0444);
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index e5ca2511a81a..d731a836e6c8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -678,7 +678,7 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv)
goto restart;
}
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
IWL_WARN(priv,
@@ -1472,8 +1472,17 @@ int iwl5000_calc_rssi(struct iwl_priv *priv,
return max_rssi - agc - IWL49_RSSI_OFFSET;
}
+struct iwl_station_mgmt_ops iwl5000_station_mgmt = {
+ .add_station = iwl_add_station_flags,
+ .remove_station = iwl_remove_station,
+ .find_station = iwl_find_station,
+ .clear_station_table = iwl_clear_stations_table,
+};
+
struct iwl_hcmd_ops iwl5000_hcmd = {
.rxon_assoc = iwl5000_send_rxon_assoc,
+ .commit_rxon = iwl_commit_rxon,
+ .set_rxon_chain = iwl_set_rxon_chain,
};
struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
@@ -1527,12 +1536,15 @@ struct iwl_lib_ops iwl5000_lib = {
.calib_version = iwl5000_eeprom_calib_version,
.query_addr = iwl5000_eeprom_query_addr,
},
+ .post_associate = iwl_post_associate,
+ .config_ap = iwl_config_ap,
};
struct iwl_ops iwl5000_ops = {
.lib = &iwl5000_lib,
.hcmd = &iwl5000_hcmd,
.utils = &iwl5000_hcmd_utils,
+ .smgmt = &iwl5000_station_mgmt,
};
struct iwl_mod_params iwl50_mod_params = {
@@ -1643,9 +1655,6 @@ struct iwl_cfg iwl5150_agn_cfg = {
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
-module_param_named(disable50, iwl50_mod_params.disable, int, 0444);
-MODULE_PARM_DESC(disable50,
- "manually disable the 50XX radio (default 0 [radio on])");
module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444);
MODULE_PARM_DESC(swcrypto50,
"using software crypto engine (default 0 [hardware])\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index edfa5e149f71..7236382aeaa6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -72,6 +72,7 @@ static struct iwl_ops iwl6000_ops = {
.lib = &iwl5000_lib,
.hcmd = &iwl5000_hcmd,
.utils = &iwl6000_hcmd_utils,
+ .smgmt = &iwl5000_station_mgmt,
};
struct iwl_cfg iwl6000_2ag_cfg = {
@@ -101,8 +102,8 @@ struct iwl_cfg iwl6000_2agn_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
.need_pll_cfg = false,
};
@@ -117,8 +118,8 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
.need_pll_cfg = false,
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index cab7842a73aa..4c88e8715df2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -52,7 +52,7 @@
/* max allowed rate miss before sync LQ cmd */
#define IWL_MISSED_RATE_MAX 15
/* max time to accum history 2 seconds */
-#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ)
+#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ)
static u8 rs_ht_to_legacy[] = {
IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
@@ -100,6 +100,7 @@ struct iwl_scale_tbl_info {
u8 is_fat; /* 1 = 40 MHz channel width */
u8 is_dup; /* 1 = duplicated data streams */
u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
+ u8 max_search; /* maximun number of tables we can search */
s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
u32 current_rate; /* rate_n_flags, uCode API format */
struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
@@ -135,7 +136,7 @@ struct iwl_lq_sta {
u32 table_count;
u32 total_failed; /* total failed frames, any/all rates */
u32 total_success; /* total successful frames, any/all rates */
- u32 flush_timer; /* time staying in mode before new search */
+ u64 flush_timer; /* time staying in mode before new search */
u8 action_counter; /* # mode-switch actions tried */
u8 is_green;
@@ -160,6 +161,7 @@ struct iwl_lq_sta {
#ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_scale_table_file;
struct dentry *rs_sta_dbgfs_stats_table_file;
+ struct dentry *rs_sta_dbgfs_rate_scale_data_file;
struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
u32 dbg_fixed_rate;
#endif
@@ -167,10 +169,12 @@ struct iwl_lq_sta {
/* used to be in sta_info */
int last_txrate_idx;
+ /* last tx rate_n_flags */
+ u32 last_rate_n_flags;
};
static void rs_rate_scale_perform(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr,
+ struct sk_buff *skb,
struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta);
static void rs_fill_link_cmd(const struct iwl_priv *priv,
@@ -191,7 +195,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
* "G" is the only table that supports CCK (the first 4 rates).
*/
-/*FIXME:RS:need to separate tables for MIMO2/MIMO3*/
+
static s32 expected_tpt_A[IWL_RATE_COUNT] = {
0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
};
@@ -208,11 +212,11 @@ static s32 expected_tpt_siso20MHzSGI[IWL_RATE_COUNT] = {
0, 0, 0, 0, 46, 46, 82, 110, 132, 168, 192, 202, 211
};
-static s32 expected_tpt_mimo20MHz[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_20MHz[IWL_RATE_COUNT] = {
0, 0, 0, 0, 74, 74, 123, 155, 179, 214, 236, 244, 251
};
-static s32 expected_tpt_mimo20MHzSGI[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_20MHzSGI[IWL_RATE_COUNT] = {
0, 0, 0, 0, 81, 81, 131, 164, 188, 222, 243, 251, 257
};
@@ -224,14 +228,48 @@ static s32 expected_tpt_siso40MHzSGI[IWL_RATE_COUNT] = {
0, 0, 0, 0, 83, 83, 135, 169, 193, 229, 250, 257, 264
};
-static s32 expected_tpt_mimo40MHz[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_40MHz[IWL_RATE_COUNT] = {
0, 0, 0, 0, 123, 123, 182, 214, 235, 264, 279, 285, 289
};
-static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_40MHzSGI[IWL_RATE_COUNT] = {
0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293
};
+/* Expected throughput metric MIMO3 */
+static s32 expected_tpt_mimo3_20MHz[IWL_RATE_COUNT] = {
+ 0, 0, 0, 0, 99, 99, 153, 186, 208, 239, 256, 263, 268
+};
+
+static s32 expected_tpt_mimo3_20MHzSGI[IWL_RATE_COUNT] = {
+ 0, 0, 0, 0, 106, 106, 162, 194, 215, 246, 262, 268, 273
+};
+
+static s32 expected_tpt_mimo3_40MHz[IWL_RATE_COUNT] = {
+ 0, 0, 0, 0, 152, 152, 211, 239, 255, 279, 290, 294, 297
+};
+
+static s32 expected_tpt_mimo3_40MHzSGI[IWL_RATE_COUNT] = {
+ 0, 0, 0, 0, 160, 160, 219, 245, 261, 284, 294, 297, 300
+};
+
+/* mbps, mcs */
+const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
+ {"1", ""},
+ {"2", ""},
+ {"5.5", ""},
+ {"11", ""},
+ {"6", "BPSK 1/2"},
+ {"9", "BPSK 1/2"},
+ {"12", "QPSK 1/2"},
+ {"18", "QPSK 3/4"},
+ {"24", "16QAM 1/2"},
+ {"36", "16QAM 3/4"},
+ {"48", "64QAM 2/3"},
+ {"54", "64QAM 3/4"},
+ {"60", "64QAM 5/6"}
+};
+
static inline u8 rs_extract_rate(u32 rate_n_flags)
{
return (u8)(rate_n_flags & 0xFF);
@@ -543,6 +581,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
tbl->is_dup = 0;
tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
tbl->lq_type = LQ_NONE;
+ tbl->max_search = IWL_MAX_SEARCH;
/* legacy rate format */
if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
@@ -576,8 +615,10 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
tbl->lq_type = LQ_MIMO2;
/* MIMO3 */
} else {
- if (num_of_ant == 3)
+ if (num_of_ant == 3) {
+ tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
tbl->lq_type = LQ_MIMO3;
+ }
}
}
return 0;
@@ -735,6 +776,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
tbl->is_fat = 0;
tbl->is_SGI = 0;
+ tbl->max_search = IWL_MAX_SEARCH;
}
rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type);
@@ -793,7 +835,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
if (!ieee80211_is_data(hdr->frame_control) ||
- is_multicast_ether_addr(hdr->addr1))
+ info->flags & IEEE80211_TX_CTL_NO_ACK)
return;
/* This packet was aggregated but doesn't carry rate scale info */
@@ -902,6 +944,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
* else look up the rate that was, finally, successful.
*/
tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags);
+ lq_sta->last_rate_n_flags = tx_rate;
rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
/* Update frame history window with "success" if Tx got ACKed ... */
@@ -958,7 +1001,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
/* See if there's a better rate or modulation mode to try. */
if (sta && sta->supp_rates[sband->band])
- rs_rate_scale_perform(priv, hdr, sta, lq_sta);
+ rs_rate_scale_perform(priv, skb, sta, lq_sta);
out:
return;
}
@@ -988,6 +1031,8 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
lq_sta->table_count = 0;
lq_sta->total_failed = 0;
lq_sta->total_success = 0;
+ lq_sta->flush_timer = jiffies;
+ lq_sta->action_counter = 0;
}
/*
@@ -1011,17 +1056,26 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
tbl->expected_tpt = expected_tpt_siso20MHzSGI;
else
tbl->expected_tpt = expected_tpt_siso20MHz;
-
- } else if (is_mimo(tbl->lq_type)) { /* FIXME:need to separate mimo2/3 */
+ } else if (is_mimo2(tbl->lq_type)) {
+ if (tbl->is_fat && !lq_sta->is_dup)
+ if (tbl->is_SGI)
+ tbl->expected_tpt = expected_tpt_mimo2_40MHzSGI;
+ else
+ tbl->expected_tpt = expected_tpt_mimo2_40MHz;
+ else if (tbl->is_SGI)
+ tbl->expected_tpt = expected_tpt_mimo2_20MHzSGI;
+ else
+ tbl->expected_tpt = expected_tpt_mimo2_20MHz;
+ } else if (is_mimo3(tbl->lq_type)) {
if (tbl->is_fat && !lq_sta->is_dup)
if (tbl->is_SGI)
- tbl->expected_tpt = expected_tpt_mimo40MHzSGI;
+ tbl->expected_tpt = expected_tpt_mimo3_40MHzSGI;
else
- tbl->expected_tpt = expected_tpt_mimo40MHz;
+ tbl->expected_tpt = expected_tpt_mimo3_40MHz;
else if (tbl->is_SGI)
- tbl->expected_tpt = expected_tpt_mimo20MHzSGI;
+ tbl->expected_tpt = expected_tpt_mimo3_20MHzSGI;
else
- tbl->expected_tpt = expected_tpt_mimo20MHz;
+ tbl->expected_tpt = expected_tpt_mimo3_20MHz;
} else
tbl->expected_tpt = expected_tpt_G;
}
@@ -1130,7 +1184,7 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
}
/*
- * Set up search table for MIMO
+ * Set up search table for MIMO2
*/
static int rs_switch_to_mimo2(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta,
@@ -1158,10 +1212,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
tbl->lq_type = LQ_MIMO2;
tbl->is_dup = lq_sta->is_dup;
tbl->action = 0;
+ tbl->max_search = IWL_MAX_SEARCH;
rate_mask = lq_sta->active_mimo2_rate;
- if (priv->current_ht_config.supported_chan_width
- == IWL_CHANNEL_WIDTH_40MHZ)
+ if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
tbl->is_fat = 1;
else
tbl->is_fat = 0;
@@ -1183,7 +1237,73 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
IWL_DEBUG_RATE(priv, "LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
+ if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
+ IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",
+ rate, rate_mask);
+ return -1;
+ }
+ tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
+
+ IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
+ tbl->current_rate, is_green);
+ return 0;
+}
+
+/*
+ * Set up search table for MIMO3
+ */
+static int rs_switch_to_mimo3(struct iwl_priv *priv,
+ struct iwl_lq_sta *lq_sta,
+ struct ieee80211_conf *conf,
+ struct ieee80211_sta *sta,
+ struct iwl_scale_tbl_info *tbl, int index)
+{
+ u16 rate_mask;
+ s32 rate;
+ s8 is_green = lq_sta->is_green;
+
+ if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
+ return -1;
+
+ if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
+ == WLAN_HT_CAP_SM_PS_STATIC)
+ return -1;
+
+ /* Need both Tx chains/antennas to support MIMO */
+ if (priv->hw_params.tx_chains_num < 3)
+ return -1;
+
+ IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO3\n");
+
+ tbl->lq_type = LQ_MIMO3;
+ tbl->is_dup = lq_sta->is_dup;
+ tbl->action = 0;
+ tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
+ rate_mask = lq_sta->active_mimo3_rate;
+
+ if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
+ tbl->is_fat = 1;
+ else
+ tbl->is_fat = 0;
+
+ /* FIXME: - don't toggle SGI here
+ if (tbl->is_fat) {
+ if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
+ tbl->is_SGI = 1;
+ else
+ tbl->is_SGI = 0;
+ } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
+ tbl->is_SGI = 1;
+ else
+ tbl->is_SGI = 0;
+ */
+ rs_set_expected_tpt_table(lq_sta, tbl);
+
+ rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
+
+ IWL_DEBUG_RATE(priv, "LQ: MIMO3 best rate %d mask %X\n",
+ rate, rate_mask);
if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",
rate, rate_mask);
@@ -1217,10 +1337,10 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
tbl->is_dup = lq_sta->is_dup;
tbl->lq_type = LQ_SISO;
tbl->action = 0;
+ tbl->max_search = IWL_MAX_SEARCH;
rate_mask = lq_sta->active_siso_rate;
- if (priv->current_ht_config.supported_chan_width
- == IWL_CHANNEL_WIDTH_40MHZ)
+ if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
tbl->is_fat = 1;
else
tbl->is_fat = 0;
@@ -1274,15 +1394,15 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret = 0;
+ u8 update_search_tbl_counter = 0;
for (; ;) {
+ lq_sta->action_counter++;
switch (tbl->action) {
case IWL_LEGACY_SWITCH_ANTENNA1:
case IWL_LEGACY_SWITCH_ANTENNA2:
IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n");
- lq_sta->action_counter++;
-
if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
tx_chains_num <= 1) ||
(tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
@@ -1298,6 +1418,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
if (rs_toggle_antenna(valid_tx_ant,
&search_tbl->current_rate, search_tbl)) {
+ update_search_tbl_counter = 1;
rs_set_expected_tpt_table(lq_sta, search_tbl);
goto out;
}
@@ -1342,9 +1463,29 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
goto out;
}
break;
+
+ case IWL_LEGACY_SWITCH_MIMO3_ABC:
+ IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO3\n");
+
+ /* Set up search table to try MIMO3 */
+ memcpy(search_tbl, tbl, sz);
+ search_tbl->is_SGI = 0;
+
+ search_tbl->ant_type = ANT_ABC;
+
+ if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+ break;
+
+ ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
+ search_tbl, index);
+ if (!ret) {
+ lq_sta->action_counter = 0;
+ goto out;
+ }
+ break;
}
tbl->action++;
- if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
+ if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
if (tbl->action == start_action)
@@ -1357,8 +1498,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
out:
lq_sta->search_better_tbl = 1;
tbl->action++;
- if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
+ if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
+ if (update_search_tbl_counter)
+ search_tbl->action = tbl->action;
return 0;
}
@@ -1381,6 +1524,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
u8 start_action = tbl->action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
+ u8 update_search_tbl_counter = 0;
int ret;
for (;;) {
@@ -1401,8 +1545,10 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
memcpy(search_tbl, tbl, sz);
if (rs_toggle_antenna(valid_tx_ant,
- &search_tbl->current_rate, search_tbl))
+ &search_tbl->current_rate, search_tbl)) {
+ update_search_tbl_counter = 1;
goto out;
+ }
break;
case IWL_SISO_SWITCH_MIMO2_AB:
case IWL_SISO_SWITCH_MIMO2_AC:
@@ -1456,10 +1602,25 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
search_tbl->current_rate =
rate_n_flags_from_tbl(priv, search_tbl,
index, is_green);
+ update_search_tbl_counter = 1;
goto out;
+ case IWL_SISO_SWITCH_MIMO3_ABC:
+ IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n");
+ memcpy(search_tbl, tbl, sz);
+ search_tbl->is_SGI = 0;
+ search_tbl->ant_type = ANT_ABC;
+
+ if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+ break;
+
+ ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
+ search_tbl, index);
+ if (!ret)
+ goto out;
+ break;
}
tbl->action++;
- if (tbl->action > IWL_SISO_SWITCH_GI)
+ if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
tbl->action = IWL_SISO_SWITCH_ANTENNA1;
if (tbl->action == start_action)
@@ -1471,15 +1632,18 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
out:
lq_sta->search_better_tbl = 1;
tbl->action++;
- if (tbl->action > IWL_SISO_SWITCH_GI)
+ if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC)
tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+ if (update_search_tbl_counter)
+ search_tbl->action = tbl->action;
+
return 0;
}
/*
- * Try to switch to new modulation mode from MIMO
+ * Try to switch to new modulation mode from MIMO2
*/
-static int rs_move_mimo_to_other(struct iwl_priv *priv,
+static int rs_move_mimo2_to_other(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf,
struct ieee80211_sta *sta, int index)
@@ -1494,6 +1658,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
u8 start_action = tbl->action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
+ u8 update_search_tbl_counter = 0;
int ret;
for (;;) {
@@ -1501,7 +1666,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
switch (tbl->action) {
case IWL_MIMO2_SWITCH_ANTENNA1:
case IWL_MIMO2_SWITCH_ANTENNA2:
- IWL_DEBUG_RATE(priv, "LQ: MIMO toggle Antennas\n");
+ IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle Antennas\n");
if (tx_chains_num <= 2)
break;
@@ -1511,8 +1676,10 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
memcpy(search_tbl, tbl, sz);
if (rs_toggle_antenna(valid_tx_ant,
- &search_tbl->current_rate, search_tbl))
+ &search_tbl->current_rate, search_tbl)) {
+ update_search_tbl_counter = 1;
goto out;
+ }
break;
case IWL_MIMO2_SWITCH_SISO_A:
case IWL_MIMO2_SWITCH_SISO_B:
@@ -1549,9 +1716,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
HT_SHORT_GI_40MHZ))
break;
- IWL_DEBUG_RATE(priv, "LQ: MIMO toggle SGI/NGI\n");
+ IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle SGI/NGI\n");
- /* Set up new search table for MIMO */
+ /* Set up new search table for MIMO2 */
memcpy(search_tbl, tbl, sz);
search_tbl->is_SGI = !tbl->is_SGI;
rs_set_expected_tpt_table(lq_sta, search_tbl);
@@ -1569,11 +1736,27 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
search_tbl->current_rate =
rate_n_flags_from_tbl(priv, search_tbl,
index, is_green);
+ update_search_tbl_counter = 1;
goto out;
+ case IWL_MIMO2_SWITCH_MIMO3_ABC:
+ IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to MIMO3\n");
+ memcpy(search_tbl, tbl, sz);
+ search_tbl->is_SGI = 0;
+ search_tbl->ant_type = ANT_ABC;
+
+ if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+ break;
+
+ ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
+ search_tbl, index);
+ if (!ret)
+ goto out;
+
+ break;
}
tbl->action++;
- if (tbl->action > IWL_MIMO2_SWITCH_GI)
+ if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
if (tbl->action == start_action)
@@ -1584,8 +1767,153 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
out:
lq_sta->search_better_tbl = 1;
tbl->action++;
- if (tbl->action > IWL_MIMO2_SWITCH_GI)
+ if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
+ if (update_search_tbl_counter)
+ search_tbl->action = tbl->action;
+
+ return 0;
+
+}
+
+/*
+ * Try to switch to new modulation mode from MIMO3
+ */
+static int rs_move_mimo3_to_other(struct iwl_priv *priv,
+ struct iwl_lq_sta *lq_sta,
+ struct ieee80211_conf *conf,
+ struct ieee80211_sta *sta, int index)
+{
+ s8 is_green = lq_sta->is_green;
+ struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+ struct iwl_scale_tbl_info *search_tbl =
+ &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
+ struct iwl_rate_scale_data *window = &(tbl->win[index]);
+ u32 sz = (sizeof(struct iwl_scale_tbl_info) -
+ (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
+ u8 start_action = tbl->action;
+ u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
+ u8 tx_chains_num = priv->hw_params.tx_chains_num;
+ int ret;
+ u8 update_search_tbl_counter = 0;
+
+ for (;;) {
+ lq_sta->action_counter++;
+ switch (tbl->action) {
+ case IWL_MIMO3_SWITCH_ANTENNA1:
+ case IWL_MIMO3_SWITCH_ANTENNA2:
+ IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle Antennas\n");
+
+ if (tx_chains_num <= 3)
+ break;
+
+ if (window->success_ratio >= IWL_RS_GOOD_RATIO)
+ break;
+
+ memcpy(search_tbl, tbl, sz);
+ if (rs_toggle_antenna(valid_tx_ant,
+ &search_tbl->current_rate, search_tbl))
+ goto out;
+ break;
+ case IWL_MIMO3_SWITCH_SISO_A:
+ case IWL_MIMO3_SWITCH_SISO_B:
+ case IWL_MIMO3_SWITCH_SISO_C:
+ IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to SISO\n");
+
+ /* Set up new search table for SISO */
+ memcpy(search_tbl, tbl, sz);
+
+ if (tbl->action == IWL_MIMO3_SWITCH_SISO_A)
+ search_tbl->ant_type = ANT_A;
+ else if (tbl->action == IWL_MIMO3_SWITCH_SISO_B)
+ search_tbl->ant_type = ANT_B;
+ else
+ search_tbl->ant_type = ANT_C;
+
+ if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+ break;
+
+ ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
+ search_tbl, index);
+ if (!ret)
+ goto out;
+
+ break;
+
+ case IWL_MIMO3_SWITCH_MIMO2_AB:
+ case IWL_MIMO3_SWITCH_MIMO2_AC:
+ case IWL_MIMO3_SWITCH_MIMO2_BC:
+ IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to MIMO2\n");
+
+ memcpy(search_tbl, tbl, sz);
+ search_tbl->is_SGI = 0;
+ if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB)
+ search_tbl->ant_type = ANT_AB;
+ else if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC)
+ search_tbl->ant_type = ANT_AC;
+ else
+ search_tbl->ant_type = ANT_BC;
+
+ if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+ break;
+
+ ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
+ search_tbl, index);
+ if (!ret)
+ goto out;
+
+ break;
+
+ case IWL_MIMO3_SWITCH_GI:
+ if (!tbl->is_fat &&
+ !(priv->current_ht_config.sgf &
+ HT_SHORT_GI_20MHZ))
+ break;
+ if (tbl->is_fat &&
+ !(priv->current_ht_config.sgf &
+ HT_SHORT_GI_40MHZ))
+ break;
+
+ IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle SGI/NGI\n");
+
+ /* Set up new search table for MIMO */
+ memcpy(search_tbl, tbl, sz);
+ search_tbl->is_SGI = !tbl->is_SGI;
+ rs_set_expected_tpt_table(lq_sta, search_tbl);
+ /*
+ * If active table already uses the fastest possible
+ * modulation (dual stream with short guard interval),
+ * and it's working well, there's no need to look
+ * for a better type of modulation!
+ */
+ if (tbl->is_SGI) {
+ s32 tpt = lq_sta->last_tpt / 100;
+ if (tpt >= search_tbl->expected_tpt[index])
+ break;
+ }
+ search_tbl->current_rate =
+ rate_n_flags_from_tbl(priv, search_tbl,
+ index, is_green);
+ update_search_tbl_counter = 1;
+ goto out;
+ }
+ tbl->action++;
+ if (tbl->action > IWL_MIMO3_SWITCH_GI)
+ tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
+
+ if (tbl->action == start_action)
+ break;
+ }
+ search_tbl->lq_type = LQ_NONE;
+ return 0;
+ out:
+ lq_sta->search_better_tbl = 1;
+ tbl->action++;
+ if (tbl->action > IWL_MIMO3_SWITCH_GI)
+ tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
+ if (update_search_tbl_counter)
+ search_tbl->action = tbl->action;
+
return 0;
}
@@ -1616,8 +1944,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
/* Elapsed time using current modulation mode */
if (lq_sta->flush_timer)
flush_interval_passed =
- time_after(jiffies,
- (unsigned long)(lq_sta->flush_timer +
+ time_after(jiffies,
+ (unsigned long)(lq_sta->flush_timer +
IWL_RATE_SCALE_FLUSH_INTVL));
/*
@@ -1676,12 +2004,14 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
* Do rate scaling and search for new modulation mode.
*/
static void rs_rate_scale_perform(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr,
+ struct sk_buff *skb,
struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta)
{
struct ieee80211_hw *hw = priv->hw;
struct ieee80211_conf *conf = &hw->conf;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
int low = IWL_RATE_INVALID;
int high = IWL_RATE_INVALID;
int index;
@@ -1707,11 +2037,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
- /* Send management frames and broadcast/multicast data using
- * lowest rate. */
+ /* Send management frames and NO_ACK data using lowest rate. */
/* TODO: this could probably be improved.. */
if (!ieee80211_is_data(hdr->frame_control) ||
- is_multicast_ether_addr(hdr->addr1))
+ info->flags & IEEE80211_TX_CTL_NO_ACK)
return;
if (!sta || !lq_sta)
@@ -1951,6 +2280,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
update_lq = 1;
index = low;
}
+
break;
case 1:
/* Increase starting rate, update uCode's rate table */
@@ -1997,8 +2327,10 @@ lq_update:
rs_move_legacy_other(priv, lq_sta, conf, sta, index);
else if (is_siso(tbl->lq_type))
rs_move_siso_to_other(priv, lq_sta, conf, sta, index);
+ else if (is_mimo2(tbl->lq_type))
+ rs_move_mimo2_to_other(priv, lq_sta, conf, sta, index);
else
- rs_move_mimo_to_other(priv, lq_sta, conf, sta, index);
+ rs_move_mimo3_to_other(priv, lq_sta, conf, sta, index);
/* If new "search" mode was selected, set up in uCode table */
if (lq_sta->search_better_tbl) {
@@ -2014,8 +2346,11 @@ lq_update:
tbl->current_rate, index);
rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
- }
+ } else
+ done_search = 1;
+ }
+ if (done_search && !lq_sta->stay_in_tbl) {
/* If the "active" (non-search) mode was legacy,
* and we've tried switching antennas,
* but we haven't been able to try HT modes (not available),
@@ -2023,8 +2358,7 @@ lq_update:
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
- lq_sta->action_counter >= 1) {
- lq_sta->action_counter = 0;
+ lq_sta->action_counter > tbl1->max_search) {
IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n");
rs_set_stay_in_table(priv, 1, lq_sta);
}
@@ -2033,7 +2367,7 @@ lq_update:
* have been tried and compared, stay in this best modulation
* mode for a while before next round of mode comparisons. */
if (lq_sta->enable_counter &&
- (lq_sta->action_counter >= IWL_ACTION_LIMIT)) {
+ (lq_sta->action_counter >= tbl1->max_search)) {
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != MAX_TID_COUNT)) {
@@ -2047,20 +2381,8 @@ lq_update:
lq_sta, sta);
}
}
- lq_sta->action_counter = 0;
rs_set_stay_in_table(priv, 0, lq_sta);
}
-
- /*
- * Else, don't search for a new modulation mode.
- * Put new timestamp in stay-in-modulation-mode flush timer if:
- * 1) Not changing rates right now
- * 2) Not just finishing up a search
- * 3) flush timer is empty
- */
- } else {
- if ((!update_lq) && (!done_search) && (!lq_sta->flush_timer))
- lq_sta->flush_timer = jiffies;
}
out:
@@ -2156,16 +2478,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
if (sta)
mask_bit = sta->supp_rates[sband->band];
- /* Send management frames and broadcast/multicast data using lowest
- * rate. */
+ /* Send management frames and NO_ACK data using lowest rate. */
if (!ieee80211_is_data(hdr->frame_control) ||
- is_multicast_ether_addr(hdr->addr1) || !sta || !lq_sta) {
+ info->flags & IEEE80211_TX_CTL_NO_ACK || !sta || !lq_sta) {
if (!mask_bit)
info->control.rates[0].idx =
rate_lowest_index(sband, NULL);
else
info->control.rates[0].idx =
rate_lowest_index(sband, sta);
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ info->control.rates[0].count = 1;
return;
}
@@ -2173,13 +2496,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
!lq_sta->ibss_sta_added) {
- u8 sta_id = iwl_find_station(priv, hdr->addr1);
+ u8 sta_id = priv->cfg->ops->smgmt->find_station(priv,
+ hdr->addr1);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
hdr->addr1);
- sta_id = iwl_add_station_flags(priv, hdr->addr1,
- 0, CMD_ASYNC, NULL);
+ sta_id = priv->cfg->ops->smgmt->add_station(priv,
+ hdr->addr1, 0,
+ CMD_ASYNC, NULL);
}
if ((sta_id != IWL_INVALID_STATION)) {
lq_sta->lq.sta_id = sta_id;
@@ -2246,15 +2571,17 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->ibss_sta_added = 0;
if (priv->iw_mode == NL80211_IFTYPE_AP) {
- u8 sta_id = iwl_find_station(priv, sta->addr);
+ u8 sta_id = priv->cfg->ops->smgmt->find_station(priv,
+ sta->addr);
/* for IBSS the call are from tasklet */
IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
- sta_id = iwl_add_station_flags(priv, sta->addr,
- 0, CMD_ASYNC, NULL);
+ sta_id = priv->cfg->ops->smgmt->add_station(priv,
+ sta->addr, 0,
+ CMD_ASYNC, NULL);
}
if ((sta_id != IWL_INVALID_STATION)) {
lq_sta->lq.sta_id = sta_id;
@@ -2539,6 +2866,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
char *buff;
int desc = 0;
int i = 0;
+ int index = 0;
ssize_t ret;
struct iwl_lq_sta *lq_sta = file->private_data;
@@ -2570,6 +2898,8 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
(tbl->is_fat) ? "40MHz" : "20MHz");
desc += sprintf(buff+desc, " %s\n", (tbl->is_SGI) ? "SGI" : "");
}
+ desc += sprintf(buff+desc, "last tx rate=0x%X\n",
+ lq_sta->last_rate_n_flags);
desc += sprintf(buff+desc, "general:"
"flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
lq_sta->lq.general_params.flags,
@@ -2590,10 +2920,19 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
lq_sta->lq.general_params.start_rate_index[2],
lq_sta->lq.general_params.start_rate_index[3]);
-
- for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
- desc += sprintf(buff+desc, " rate[%d] 0x%X\n",
- i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
+ for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
+ index = iwl_hwrate_to_plcp_idx(
+ le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
+ if (is_legacy(tbl->lq_type)) {
+ desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n",
+ i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),
+ iwl_rate_mcs[index].mbps);
+ } else {
+ desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps (%s)\n",
+ i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),
+ iwl_rate_mcs[index].mbps, iwl_rate_mcs[index].mcs);
+ }
+ }
ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
kfree(buff);
@@ -2646,6 +2985,43 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
.open = open_file_generic,
};
+static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
+ char __user *user_buf, size_t count, loff_t *ppos)
+{
+ char buff[120];
+ int desc = 0;
+ ssize_t ret;
+
+ struct iwl_lq_sta *lq_sta = file->private_data;
+ struct iwl_priv *priv;
+ struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
+
+ priv = lq_sta->drv;
+
+ if (is_Ht(tbl->lq_type))
+ desc += sprintf(buff+desc,
+ "Bit Rate= %d Mb/s\n",
+ tbl->expected_tpt[lq_sta->last_txrate_idx]);
+ else
+ desc += sprintf(buff+desc,
+ "Bit Rate= %d Mb/s\n",
+ iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
+ desc += sprintf(buff+desc,
+ "Signal Level= %d dBm\tNoise Level= %d dBm\n",
+ priv->last_rx_rssi, priv->last_rx_noise);
+ desc += sprintf(buff+desc,
+ "Tsf= 0x%llx\tBeacon time= 0x%08X\n",
+ priv->last_tsf, priv->last_beacon_time);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ return ret;
+}
+
+static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
+ .read = rs_sta_dbgfs_rate_scale_data_read,
+ .open = open_file_generic,
+};
+
static void rs_add_debugfs(void *priv, void *priv_sta,
struct dentry *dir)
{
@@ -2656,6 +3032,9 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
lq_sta->rs_sta_dbgfs_stats_table_file =
debugfs_create_file("rate_stats_table", 0600, dir,
lq_sta, &rs_sta_dbgfs_stats_table_ops);
+ lq_sta->rs_sta_dbgfs_rate_scale_data_file =
+ debugfs_create_file("rate_scale_data", 0600, dir,
+ lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
debugfs_create_u8("tx_agg_tid_enable", 0600, dir,
&lq_sta->tx_agg_tid_en);
@@ -2667,6 +3046,7 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
struct iwl_lq_sta *lq_sta = priv_sta;
debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
+ debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
}
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index ab59acc405d9..25050bf315a2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -241,6 +241,7 @@ enum {
#define IWL_LEGACY_SWITCH_MIMO2_AB 3
#define IWL_LEGACY_SWITCH_MIMO2_AC 4
#define IWL_LEGACY_SWITCH_MIMO2_BC 5
+#define IWL_LEGACY_SWITCH_MIMO3_ABC 6
/* possible actions when in siso mode */
#define IWL_SISO_SWITCH_ANTENNA1 0
@@ -249,6 +250,8 @@ enum {
#define IWL_SISO_SWITCH_MIMO2_AC 3
#define IWL_SISO_SWITCH_MIMO2_BC 4
#define IWL_SISO_SWITCH_GI 5
+#define IWL_SISO_SWITCH_MIMO3_ABC 6
+
/* possible actions when in mimo mode */
#define IWL_MIMO2_SWITCH_ANTENNA1 0
@@ -257,6 +260,23 @@ enum {
#define IWL_MIMO2_SWITCH_SISO_B 3
#define IWL_MIMO2_SWITCH_SISO_C 4
#define IWL_MIMO2_SWITCH_GI 5
+#define IWL_MIMO2_SWITCH_MIMO3_ABC 6
+
+
+/* possible actions when in mimo3 mode */
+#define IWL_MIMO3_SWITCH_ANTENNA1 0
+#define IWL_MIMO3_SWITCH_ANTENNA2 1
+#define IWL_MIMO3_SWITCH_SISO_A 2
+#define IWL_MIMO3_SWITCH_SISO_B 3
+#define IWL_MIMO3_SWITCH_SISO_C 4
+#define IWL_MIMO3_SWITCH_MIMO2_AB 5
+#define IWL_MIMO3_SWITCH_MIMO2_AC 6
+#define IWL_MIMO3_SWITCH_MIMO2_BC 7
+#define IWL_MIMO3_SWITCH_GI 8
+
+
+#define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI
+#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC
/*FIXME:RS:add possible actions for MIMO3*/
@@ -307,6 +327,13 @@ enum iwl_table_type {
#define ANT_BC (ANT_B | ANT_C)
#define ANT_ABC (ANT_AB | ANT_C)
+#define IWL_MAX_MCS_DISPLAY_SIZE 12
+
+struct iwl_rate_mcs_info {
+ char mbps[IWL_MAX_MCS_DISPLAY_SIZE];
+ char mcs[IWL_MAX_MCS_DISPLAY_SIZE];
+};
+
static inline u8 num_of_ant(u8 mask)
{
return !!((mask) & ANT_A) +
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1ef4192207a5..596977d71c94 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -102,7 +102,7 @@ MODULE_ALIAS("iwl4965");
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
-static int iwl_commit_rxon(struct iwl_priv *priv)
+int iwl_commit_rxon(struct iwl_priv *priv)
{
/* cast away the const for active_rxon in this function */
struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
@@ -188,10 +188,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
}
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
- if (!priv->error_recovering)
- priv->start_calib = 0;
+ priv->start_calib = 0;
/* Add the broadcast address so we can send broadcast frames */
if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
@@ -246,8 +245,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
void iwl_update_chain_flags(struct iwl_priv *priv)
{
- iwl_set_rxon_chain(priv);
- iwl_commit_rxon(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ iwlcore_commit_rxon(priv);
}
static void iwl_clear_free_frames(struct iwl_priv *priv)
@@ -531,76 +531,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv,
*
******************************************************************************/
-static void iwl_ht_conf(struct iwl_priv *priv,
- struct ieee80211_bss_conf *bss_conf)
-{
- struct ieee80211_sta_ht_cap *ht_conf;
- struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
- struct ieee80211_sta *sta;
-
- IWL_DEBUG_MAC80211(priv, "enter: \n");
-
- if (!iwl_conf->is_ht)
- return;
-
-
- /*
- * It is totally wrong to base global information on something
- * that is valid only when associated, alas, this driver works
- * that way and I don't know how to fix it.
- */
-
- rcu_read_lock();
- sta = ieee80211_find_sta(priv->hw, priv->bssid);
- if (!sta) {
- rcu_read_unlock();
- return;
- }
- ht_conf = &sta->ht_cap;
-
- if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
- iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
- if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
- iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
-
- iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
- iwl_conf->max_amsdu_size =
- !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
-
- iwl_conf->supported_chan_width =
- !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
-
- /*
- * XXX: The HT configuration needs to be moved into iwl_mac_config()
- * to be done there correctly.
- */
-
- iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
- if (conf_is_ht40_minus(&priv->hw->conf))
- iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- else if (conf_is_ht40_plus(&priv->hw->conf))
- iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-
- /* If no above or below channel supplied disable FAT channel */
- if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
- iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
- iwl_conf->supported_chan_width = 0;
-
- iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
-
- memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
-
- iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
- iwl_conf->ht_protection =
- bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
- iwl_conf->non_GF_STA_present =
- !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
-
- rcu_read_unlock();
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
#define MAX_UCODE_BEACON_INTERVAL 4096
static u16 iwl_adjust_beacon_interval(u16 beacon_val)
@@ -636,7 +566,8 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
beacon_int = iwl_adjust_beacon_interval(priv->beacon_int);
priv->rxon_timing.atim_window = 0;
} else {
- beacon_int = iwl_adjust_beacon_interval(conf->beacon_int);
+ beacon_int = iwl_adjust_beacon_interval(
+ priv->vif->bss_conf.beacon_int);
/* TODO: we need to get atim_window from upper stack
* for now we set to 0 */
@@ -657,30 +588,6 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static int iwl_set_mode(struct iwl_priv *priv, int mode)
-{
- iwl_connection_init_rx_config(priv, mode);
- iwl_set_rxon_chain(priv);
- memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
-
- iwl_clear_stations_table(priv);
-
- /* dont commit rxon if rf-kill is on*/
- if (!iwl_is_ready_rf(priv))
- return -EAGAIN;
-
- cancel_delayed_work(&priv->scan_check);
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
- return -EAGAIN;
- }
-
- iwl_commit_rxon(priv);
-
- return 0;
-}
-
/******************************************************************************
*
* Generic RX handler implementations
@@ -1002,6 +909,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+ priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
} else {
/* No handling needed */
IWL_DEBUG_RX(priv,
@@ -1058,23 +966,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
tasklet_kill(&priv->irq_tasklet);
}
-static void iwl_error_recovery(struct iwl_priv *priv)
-{
- unsigned long flags;
-
- memcpy(&priv->staging_rxon, &priv->recovery_rxon,
- sizeof(priv->staging_rxon));
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
-
- iwl_rxon_add_station(priv, priv->bssid, 1);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
- priv->error_recovering = 0;
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
static void iwl_irq_tasklet(struct iwl_priv *priv)
{
u32 inta, handled = 0;
@@ -1123,6 +1014,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Tell the device to stop sending interrupts */
iwl_disable_interrupts(priv);
+ priv->isr_stats.hw++;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_HW_ERR;
@@ -1135,13 +1027,17 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
#ifdef CONFIG_IWLWIFI_DEBUG
if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_SCD)
+ if (inta & CSR_INT_BIT_SCD) {
IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
"the frame/frames.\n");
+ priv->isr_stats.sch++;
+ }
/* Alive notification via Rx interrupt will do the real work */
- if (inta & CSR_INT_BIT_ALIVE)
+ if (inta & CSR_INT_BIT_ALIVE) {
IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+ priv->isr_stats.alive++;
+ }
}
#endif
/* Safely ignore these bits for debug checks below */
@@ -1157,6 +1053,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
hw_rf_kill ? "disable radio" : "enable radio");
+ priv->isr_stats.rfkill++;
+
/* driver only loads ucode once setting the interface up.
* the driver allows loading the ucode even if the radio
* is killed. Hence update the killswitch state here. The
@@ -1176,6 +1074,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Chip got too hot and stopped itself */
if (inta & CSR_INT_BIT_CT_KILL) {
IWL_ERR(priv, "Microcode CT kill error detected.\n");
+ priv->isr_stats.ctkill++;
handled |= CSR_INT_BIT_CT_KILL;
}
@@ -1183,6 +1082,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
if (inta & CSR_INT_BIT_SW_ERR) {
IWL_ERR(priv, "Microcode SW error detected. "
" Restarting 0x%X.\n", inta);
+ priv->isr_stats.sw++;
+ priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -1198,6 +1099,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
iwl_txq_update_write_ptr(priv, &priv->txq[4]);
iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+ priv->isr_stats.wakeup++;
+
handled |= CSR_INT_BIT_WAKEUP;
}
@@ -1206,19 +1109,23 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
* notifications from uCode come through here*/
if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
iwl_rx_handle(priv);
+ priv->isr_stats.rx++;
handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
}
if (inta & CSR_INT_BIT_FH_TX) {
IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+ priv->isr_stats.tx++;
handled |= CSR_INT_BIT_FH_TX;
/* FH finished to write, send event */
priv->ucode_write_complete = 1;
wake_up_interruptible(&priv->wait_command_queue);
}
- if (inta & ~handled)
+ if (inta & ~handled) {
IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ priv->isr_stats.unhandled++;
+ }
if (inta & ~CSR_INI_SET_MASK) {
IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
@@ -1243,6 +1150,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
+
/******************************************************************************
*
* uCode download functions
@@ -1508,10 +1416,6 @@ static int iwl_read_ucode(struct iwl_priv *priv)
return ret;
}
-/* temporary */
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw,
- struct sk_buff *skb);
-
/**
* iwl_alive_start - called after REPLY_ALIVE notification received
* from protocol/runtime uCode (initialization uCode's
@@ -1540,7 +1444,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
goto restart;
}
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
IWL_WARN(priv,
@@ -1568,7 +1472,10 @@ static void iwl_alive_start(struct iwl_priv *priv)
} else {
/* Initialize our rx_config data */
iwl_connection_init_rx_config(priv, priv->iw_mode);
- iwl_set_rxon_chain(priv);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
}
@@ -1578,7 +1485,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_reset_run_time_calib(priv);
/* Configure the adapter for unassociated operation */
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
/* At this point, the NIC is initialized and operational */
iwl_rf_kill_ct_config(priv);
@@ -1589,9 +1496,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
- if (priv->error_recovering)
- iwl_error_recovery(priv);
-
iwl_power_update_mode(priv, 1);
/* reassociate for ADHOC mode */
@@ -1626,7 +1530,7 @@ static void __iwl_down(struct iwl_priv *priv)
iwl_leds_unregister(priv);
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
@@ -1649,7 +1553,7 @@ static void __iwl_down(struct iwl_priv *priv)
ieee80211_stop_queues(priv->hw);
/* If we have not previously called iwl_init() then
- * clear all bits but the RF Kill and SUSPEND bits and return */
+ * clear all bits but the RF Kill bits and return */
if (!iwl_is_init(priv)) {
priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
@@ -1657,23 +1561,19 @@ static void __iwl_down(struct iwl_priv *priv)
STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
goto exit;
}
- /* ...otherwise clear out all the status bits but the RF Kill and
- * SUSPEND bits and continue taking the NIC down. */
+ /* ...otherwise clear out all the status bits but the RF Kill
+ * bits and continue taking the NIC down. */
priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_FW_ERROR, &priv->status) <<
STATUS_FW_ERROR |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
@@ -1698,7 +1598,7 @@ static void __iwl_down(struct iwl_priv *priv)
udelay(5);
/* FIXME: apm_ops.suspend(priv) */
- if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+ if (exit_pending)
priv->cfg->ops->lib->apm_ops.stop(priv);
else
priv->cfg->ops->lib->apm_ops.reset(priv);
@@ -1781,7 +1681,7 @@ static int __iwl_up(struct iwl_priv *priv)
for (i = 0; i < MAX_HW_RESTARTS; i++) {
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
@@ -1794,9 +1694,6 @@ static int __iwl_up(struct iwl_priv *priv)
continue;
}
- /* Clear out the uCode error bit if it is set */
- clear_bit(STATUS_FW_ERROR, &priv->status);
-
/* start card; "initialize" will load runtime ucode */
iwl_nic_start(priv);
@@ -1891,8 +1788,17 @@ static void iwl_bg_restart(struct work_struct *data)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- iwl_down(priv);
- queue_work(priv->workqueue, &priv->up);
+ if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+ mutex_lock(&priv->mutex);
+ priv->vif = NULL;
+ priv->is_open = 0;
+ mutex_unlock(&priv->mutex);
+ iwl_down(priv);
+ ieee80211_restart_hw(priv->hw);
+ } else {
+ iwl_down(priv);
+ queue_work(priv->workqueue, &priv->up);
+ }
}
static void iwl_bg_rx_replenish(struct work_struct *data)
@@ -1910,7 +1816,7 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static void iwl_post_associate(struct iwl_priv *priv)
+void iwl_post_associate(struct iwl_priv *priv)
{
struct ieee80211_conf *conf = NULL;
int ret = 0;
@@ -1932,13 +1838,12 @@ static void iwl_post_associate(struct iwl_priv *priv)
if (!priv->vif || !priv->is_open)
return;
- iwl_power_cancel_timeout(priv);
iwl_scan_cancel_timeout(priv, 200);
conf = ieee80211_get_hw_conf(priv->hw);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
iwl_setup_rxon_timing(priv);
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
@@ -1951,7 +1856,9 @@ static void iwl_post_associate(struct iwl_priv *priv)
iwl_set_rxon_ht(priv, &priv->current_ht_config);
- iwl_set_rxon_chain(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
@@ -1973,7 +1880,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
}
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
switch (priv->iw_mode) {
case NL80211_IFTYPE_STATION:
@@ -2006,7 +1913,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
* If chain noise has already been run, then we need to enable
* power management here */
if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
- iwl_power_enable_management(priv);
+ iwl_power_update_mode(priv, 0);
/* Enable Rx differential gain and sensitivity calibrations */
iwl_chain_noise_reset(priv);
@@ -2059,9 +1966,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
IWL_DEBUG_INFO(priv, "Start UP work done.\n");
- if (test_bit(STATUS_IN_SUSPEND, &priv->status))
- return 0;
-
/* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
* mac80211 will not be run successfully. */
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -2087,10 +1991,8 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211(priv, "enter\n");
- if (!priv->is_open) {
- IWL_DEBUG_MAC80211(priv, "leave - skip\n");
+ if (!priv->is_open)
return;
- }
priv->is_open = 0;
@@ -2130,175 +2032,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
-static int iwl_mac_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
-
- if (priv->vif) {
- IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
- return -EOPNOTSUPP;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->vif = conf->vif;
- priv->iw_mode = conf->type;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
-
- if (conf->mac_addr) {
- IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
- memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
- }
-
- if (iwl_set_mode(priv, conf->type) == -EAGAIN)
- /* we are not ready, will run again when ready */
- set_bit(STATUS_MODE_PENDING, &priv->status);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
-/**
- * iwl_mac_config - mac80211 config callback
- *
- * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
- * be set inappropriately and the driver currently sets the hardware up to
- * use it whenever needed.
- */
-static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct iwl_priv *priv = hw->priv;
- const struct iwl_channel_info *ch_info;
- struct ieee80211_conf *conf = &hw->conf;
- unsigned long flags = 0;
- int ret = 0;
- u16 ch;
- int scan_active = 0;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
- conf->channel->hw_value, changed);
-
- if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
- test_bit(STATUS_SCANNING, &priv->status))) {
- scan_active = 1;
- IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
- }
-
-
- /* during scanning mac80211 will delay channel setting until
- * scan finish with changed = 0
- */
- if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
- if (scan_active)
- goto set_ch_out;
-
- ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
- ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
- ret = -EINVAL;
- goto set_ch_out;
- }
-
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- !is_channel_ibss(ch_info)) {
- IWL_ERR(priv, "channel %d in band %d not "
- "IBSS channel\n",
- conf->channel->hw_value, conf->channel->band);
- ret = -EINVAL;
- goto set_ch_out;
- }
-
- priv->current_ht_config.is_ht = conf_is_ht(conf);
-
- spin_lock_irqsave(&priv->lock, flags);
-
-
- /* if we are switching from ht to 2.4 clear flags
- * from any ht related info since 2.4 does not
- * support ht */
- if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
- priv->staging_rxon.flags = 0;
-
- iwl_set_rxon_channel(priv, conf->channel);
-
- iwl_set_flags_for_band(priv, conf->channel->band);
- spin_unlock_irqrestore(&priv->lock, flags);
- set_ch_out:
- /* The list of supported rates and rate mask can be different
- * for each band; since the band may have changed, reset
- * the rate mask to what mac80211 lists */
- iwl_set_rate(priv);
- }
-
- if (changed & IEEE80211_CONF_CHANGE_PS) {
- if (conf->flags & IEEE80211_CONF_PS)
- ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
- else
- ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
- if (ret)
- IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
-
- }
-
- if (changed & IEEE80211_CONF_CHANGE_POWER) {
- IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
- priv->tx_power_user_lmt, conf->power_level);
-
- iwl_set_tx_power(priv, conf->power_level, false);
- }
-
- /* call to ensure that 4965 rx_chain is set properly in monitor mode */
- iwl_set_rxon_chain(priv);
-
- if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
- if (conf->radio_enabled &&
- iwl_radio_kill_sw_enable_radio(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
- "waiting for uCode\n");
- goto out;
- }
-
- if (!conf->radio_enabled)
- iwl_radio_kill_sw_disable_radio(priv);
- }
-
- if (!conf->radio_enabled) {
- IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
- goto out;
- }
-
- if (!iwl_is_ready(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- goto out;
- }
-
- if (scan_active)
- goto out;
-
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
- iwl_commit_rxon(priv);
- else
- IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n");
-
-
-out:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
- return ret;
-}
-
-static void iwl_config_ap(struct iwl_priv *priv)
+void iwl_config_ap(struct iwl_priv *priv)
{
int ret = 0;
unsigned long flags;
@@ -2311,7 +2045,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
/* RXON Timing */
iwl_setup_rxon_timing(priv);
@@ -2321,7 +2055,8 @@ static void iwl_config_ap(struct iwl_priv *priv)
IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
- iwl_set_rxon_chain(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
/* FIXME: what should be the assoc_id for AP? */
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
@@ -2347,7 +2082,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
}
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
spin_lock_irqsave(&priv->lock, flags);
iwl_activate_qos(priv, 1);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -2360,194 +2095,6 @@ static void iwl_config_ap(struct iwl_priv *priv)
* clear sta table, add BCAST sta... */
}
-
-static int iwl_mac_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- int rc;
-
- if (conf == NULL)
- return -EIO;
-
- if (priv->vif != vif) {
- IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
- return 0;
- }
-
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- conf->changed & IEEE80211_IFCC_BEACON) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
- if (!beacon)
- return -ENOMEM;
- mutex_lock(&priv->mutex);
- rc = iwl_mac_beacon_update(hw, beacon);
- mutex_unlock(&priv->mutex);
- if (rc)
- return rc;
- }
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- mutex_lock(&priv->mutex);
-
- if (conf->bssid)
- IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
-
-/*
- * very dubious code was here; the probe filtering flag is never set:
- *
- if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
- !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
- */
-
- if (priv->iw_mode == NL80211_IFTYPE_AP) {
- if (!conf->bssid) {
- conf->bssid = priv->mac_addr;
- memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
- IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
- conf->bssid);
- }
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
- }
-
- if (iwl_is_rfkill(priv))
- goto done;
-
- if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
- !is_multicast_ether_addr(conf->bssid)) {
- /* If there is currently a HW scan going on in the background
- * then we need to cancel it else the RXON below will fail. */
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress "
- "after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
- mutex_unlock(&priv->mutex);
- return -EAGAIN;
- }
- memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);
-
- /* TODO: Audit driver for usage of these members and see
- * if mac80211 deprecates them (priv->bssid looks like it
- * shouldn't be there, but I haven't scanned the IBSS code
- * to verify) - jpk */
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl_config_ap(priv);
- else {
- rc = iwl_commit_rxon(priv);
- if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
- iwl_rxon_add_station(
- priv, priv->active_rxon.bssid_addr, 1);
- }
-
- } else {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
- }
-
- done:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
-
- return 0;
-}
-
-static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- mutex_lock(&priv->mutex);
-
- if (iwl_is_ready_rf(priv)) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
- }
- if (priv->vif == conf->vif) {
- priv->vif = NULL;
- memset(priv->bssid, 0, ETH_ALEN);
- }
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-}
-
-#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-static void iwl_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
-
- if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
- bss_conf->use_short_preamble);
- if (bss_conf->use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- }
-
- if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
- if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
- priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
- }
-
- if (changes & BSS_CHANGED_HT) {
- iwl_ht_conf(priv, bss_conf);
- iwl_set_rxon_chain(priv);
- }
-
- if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
- /* This should never happen as this function should
- * never be called from interrupt context. */
- if (WARN_ON_ONCE(in_interrupt()))
- return;
- if (bss_conf->assoc) {
- priv->assoc_id = bss_conf->aid;
- priv->beacon_int = bss_conf->beacon_int;
- priv->power_data.dtim_period = bss_conf->dtim_period;
- priv->timestamp = bss_conf->timestamp;
- priv->assoc_capability = bss_conf->assoc_capability;
-
- /* we have just associated, don't start scan too early
- * leave time for EAPOL exchange to complete
- */
- priv->next_scan_jiffies = jiffies +
- IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
- mutex_lock(&priv->mutex);
- iwl_post_associate(priv);
- mutex_unlock(&priv->mutex);
- } else {
- priv->assoc_id = 0;
- IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
- }
- } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
- IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
- iwl_send_rxon_assoc(priv);
- }
-
-}
-
static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
struct ieee80211_key_conf *keyconf, const u8 *addr,
u32 iv32, u16 *phase1key)
@@ -2579,7 +2126,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return -EOPNOTSUPP;
}
addr = sta ? sta->addr : iwl_bcast_addr;
- sta_id = iwl_find_station(priv, addr);
+ sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
@@ -2630,49 +2177,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
- const struct ieee80211_tx_queue_params *params)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- int q;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (queue >= AC_NUM) {
- IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
- return 0;
- }
-
- q = AC_NUM - 1 - queue;
-
- spin_lock_irqsave(&priv->lock, flags);
-
- priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
- priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
- priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
- priv->qos_data.def_qos_parm.ac[q].edca_txop =
- cpu_to_le16((params->txop * 32));
-
- priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
- priv->qos_data.qos_active = 1;
-
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl_activate_qos(priv, 1);
- else if (priv->assoc_id && iwl_is_associated(priv))
- iwl_activate_qos(priv, 0);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
struct ieee80211_sta *sta, u16 tid, u16 *ssn)
@@ -2715,41 +2219,6 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
return 0;
}
-static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
- struct ieee80211_tx_queue_stats *stats)
-{
- struct iwl_priv *priv = hw->priv;
- int i, avail;
- struct iwl_tx_queue *txq;
- struct iwl_queue *q;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- for (i = 0; i < AC_NUM; i++) {
- txq = &priv->txq[i];
- q = &txq->q;
- avail = iwl_queue_space(q);
-
- stats[i].len = q->n_window - avail;
- stats[i].limit = q->n_window - q->high_mark;
- stats[i].count = q->n_window;
-
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
- return 0;
-}
-
static int iwl_mac_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
{
@@ -2762,120 +2231,6 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
return 0;
}
-static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- spin_lock_irqsave(&priv->lock, flags);
- memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_reset_qos(priv);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = 0;
- priv->assoc_capability = 0;
- priv->assoc_station_added = 0;
-
- /* new association get rid of ibss beacon skb */
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = NULL;
-
- priv->beacon_int = priv->hw->conf.beacon_int;
- priv->timestamp = 0;
- if ((priv->iw_mode == NL80211_IFTYPE_STATION))
- priv->beacon_int = 0;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- /* we are restarting association process
- * clear RXON_FILTER_ASSOC_MSK bit
- */
- if (priv->iw_mode != NL80211_IFTYPE_AP) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
- }
-
- iwl_power_update_mode(priv, 0);
-
- /* Per mac80211.h: This is only used in IBSS mode... */
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-
- /* switch to CAM during association period.
- * the ucode will block any association/authentication
- * frome during assiciation period if it can not hear
- * the AP because of PM. the timer enable PM back is
- * association do not complete
- */
- if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
- IEEE80211_CHAN_RADAR))
- iwl_power_disable_management(priv, 3000);
-
- IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- iwl_set_rate(priv);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- __le64 timestamp;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = skb;
-
- priv->assoc_id = 0;
- timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
- priv->timestamp = le64_to_cpu(timestamp);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_reset_qos(priv);
-
- iwl_post_associate(priv);
-
-
- return 0;
-}
-
/*****************************************************************************
*
* sysfs attributes
@@ -2895,7 +2250,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
static ssize_t show_debug_level(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%08X\n", priv->debug_level);
}
@@ -2903,7 +2258,7 @@ static ssize_t store_debug_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
int ret;
@@ -2926,7 +2281,7 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
static ssize_t show_version(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
struct iwl_alive_resp *palive = &priv->card_alive;
ssize_t pos = 0;
u16 eeprom_ver;
@@ -2957,7 +2312,7 @@ static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL);
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (!iwl_is_alive(priv))
return -EAGAIN;
@@ -2970,7 +2325,7 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (!iwl_is_ready_rf(priv))
return sprintf(buf, "off\n");
@@ -2982,7 +2337,7 @@ static ssize_t store_tx_power(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
int ret;
@@ -3000,7 +2355,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
static ssize_t show_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
}
@@ -3009,7 +2364,7 @@ static ssize_t store_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
u32 flags;
int ret = strict_strtoul(buf, 0, &val);
@@ -3025,7 +2380,7 @@ static ssize_t store_flags(struct device *d,
else {
IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -3038,7 +2393,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
static ssize_t show_filter_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%04X\n",
le32_to_cpu(priv->active_rxon.filter_flags));
@@ -3048,7 +2403,7 @@ static ssize_t store_filter_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
u32 filter_flags;
int ret = strict_strtoul(buf, 0, &val);
@@ -3066,7 +2421,7 @@ static ssize_t store_filter_flags(struct device *d,
"0x%04X\n", filter_flags);
priv->staging_rxon.filter_flags =
cpu_to_le32(filter_flags);
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -3109,32 +2464,37 @@ static ssize_t show_power_level(struct device *d,
{
struct iwl_priv *priv = dev_get_drvdata(d);
int mode = priv->power_data.user_power_setting;
- int system = priv->power_data.system_power_setting;
int level = priv->power_data.power_mode;
char *p = buf;
- switch (system) {
- case IWL_POWER_SYS_AUTO:
- p += sprintf(p, "SYSTEM:auto");
- break;
- case IWL_POWER_SYS_AC:
- p += sprintf(p, "SYSTEM:ac");
- break;
- case IWL_POWER_SYS_BATTERY:
- p += sprintf(p, "SYSTEM:battery");
- break;
- }
-
- p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
- "fixed" : "auto");
- p += sprintf(p, "\tINDEX:%d", level);
- p += sprintf(p, "\n");
+ p += sprintf(p, "INDEX:%d\t", level);
+ p += sprintf(p, "USER:%d\n", mode);
return p - buf + 1;
}
static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
store_power_level);
+static ssize_t show_qos(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ char *p = buf;
+ int q;
+
+ for (q = 0; q < AC_NUM; q++) {
+ p += sprintf(p, "\tcw_min\tcw_max\taifsn\ttxop\n");
+ p += sprintf(p, "AC[%d]\t%u\t%u\t%u\t%u\n", q,
+ priv->qos_data.def_qos_parm.ac[q].cw_min,
+ priv->qos_data.def_qos_parm.ac[q].cw_max,
+ priv->qos_data.def_qos_parm.ac[q].aifsn,
+ priv->qos_data.def_qos_parm.ac[q].edca_txop);
+ }
+
+ return p - buf + 1;
+}
+
+static DEVICE_ATTR(qos, S_IRUGO, show_qos, NULL);
static ssize_t show_statistics(struct device *d,
struct device_attribute *attr, char *buf)
@@ -3197,7 +2557,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
iwl_setup_scan_deferred_work(priv);
- iwl_setup_power_deferred_work(priv);
if (priv->cfg->ops->lib->setup_deferred_work)
priv->cfg->ops->lib->setup_deferred_work(priv);
@@ -3217,7 +2576,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
cancel_delayed_work_sync(&priv->init_alive_start);
cancel_delayed_work(&priv->scan_check);
- cancel_delayed_work_sync(&priv->set_power_save);
cancel_delayed_work(&priv->alive_start);
cancel_work_sync(&priv->beacon_update);
del_timer_sync(&priv->statistics_periodic);
@@ -3234,7 +2592,7 @@ static struct attribute *iwl_sysfs_entries[] = {
&dev_attr_debug_level.attr,
#endif
&dev_attr_version.attr,
-
+ &dev_attr_qos.attr,
NULL
};
@@ -3250,7 +2608,6 @@ static struct ieee80211_ops iwl_hw_ops = {
.add_interface = iwl_mac_add_interface,
.remove_interface = iwl_mac_remove_interface,
.config = iwl_mac_config,
- .config_interface = iwl_mac_config_interface,
.configure_filter = iwl_configure_filter,
.set_key = iwl_mac_set_key,
.update_tkip_key = iwl_mac_update_tkip_key,
@@ -3397,18 +2754,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_free_eeprom;
/* At this point both hw and priv are initialized. */
- /**********************************
- * 7. Initialize module parameters
- **********************************/
-
- /* Disable radio (SW RF KILL) via parameter when loading driver */
- if (priv->cfg->mod_params->disable) {
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- IWL_DEBUG_INFO(priv, "Radio disabled.\n");
- }
-
/********************
- * 8. Setup services
+ * 7. Setup services
********************/
spin_lock_irqsave(&priv->lock, flags);
iwl_disable_interrupts(priv);
@@ -3432,7 +2779,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_setup_rx_handlers(priv);
/**********************************
- * 9. Setup and register mac80211
+ * 8. Setup and register mac80211
**********************************/
/* enable interrupts if needed: hw bug w/a */
@@ -3450,7 +2797,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
- IWL_ERR(priv, "failed to create debugfs files\n");
+ IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
/* If platform's RF_KILL switch is NOT set to KILL */
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
@@ -3533,7 +2880,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
iwl_rx_queue_free(priv, &priv->rxq);
iwl_hw_txq_ctx_free(priv);
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
iwl_eeprom_free(priv);
@@ -3561,45 +2908,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
ieee80211_free_hw(priv->hw);
}
-#ifdef CONFIG_PM
-
-static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
-
- if (priv->is_open) {
- set_bit(STATUS_IN_SUSPEND, &priv->status);
- iwl_mac_stop(priv->hw);
- priv->is_open = 1;
- }
-
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- return 0;
-}
-
-static int iwl_pci_resume(struct pci_dev *pdev)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
- int ret;
-
- pci_set_power_state(pdev, PCI_D0);
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
- pci_restore_state(pdev);
- iwl_enable_interrupts(priv);
-
- if (priv->is_open)
- iwl_mac_start(priv->hw);
-
- clear_bit(STATUS_IN_SUSPEND, &priv->status);
- return 0;
-}
-
-#endif /* CONFIG_PM */
/*****************************************************************************
*
@@ -3636,7 +2944,9 @@ static struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
{IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000_2agn_cfg)},
{IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000_2agn_cfg)},
{IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
{IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)},
{IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 735f3f19928c..a5d63672ad39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -857,7 +857,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
priv->cfg->ops->lib->update_chain_flags(priv);
data->state = IWL_CHAIN_NOISE_DONE;
- iwl_power_enable_management(priv);
+ iwl_power_update_mode(priv, 0);
}
EXPORT_SYMBOL(iwl_chain_noise_calibration);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 29d40746da6a..7b84d5246b36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2469,11 +2469,12 @@ struct iwl_ssid_ie {
u8 ssid[32];
} __attribute__ ((packed));
-#define PROBE_OPTION_MAX_API1 0x4
-#define PROBE_OPTION_MAX 0x14
+#define PROBE_OPTION_MAX_3945 4
+#define PROBE_OPTION_MAX 20
#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
#define IWL_GOOD_CRC_TH cpu_to_le16(1)
#define IWL_MAX_SCAN_SIZE 1024
+#define IWL_MAX_PROBE_REQUEST 200
/*
* REPLY_SCAN_CMD = 0x80 (command)
@@ -2552,7 +2553,7 @@ struct iwl3945_scan_cmd {
struct iwl3945_tx_cmd tx_cmd;
/* For directed active scans (set to all-0s otherwise) */
- struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_API1];
+ struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_3945];
/*
* Probe request frame, followed by channel list.
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index c54fb93e9d72..5393fb3f452c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -273,6 +273,14 @@ void iwl_activate_qos(struct iwl_priv *priv, u8 force)
}
EXPORT_SYMBOL(iwl_activate_qos);
+/*
+ * AC CWmin CW max AIFSN TXOP Limit TXOP Limit
+ * (802.11b) (802.11a/g)
+ * AC_BK 15 1023 7 0 0
+ * AC_BE 15 1023 3 0 0
+ * AC_VI 7 15 2 6.016ms 3.008ms
+ * AC_VO 3 7 2 3.264ms 1.504ms
+ */
void iwl_reset_qos(struct iwl_priv *priv)
{
u16 cw_min = 15;
@@ -304,6 +312,7 @@ void iwl_reset_qos(struct iwl_priv *priv)
if (priv->qos_data.qos_active)
aifs = 3;
+ /* AC_BE */
priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
@@ -311,6 +320,7 @@ void iwl_reset_qos(struct iwl_priv *priv)
priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
if (priv->qos_data.qos_active) {
+ /* AC_BK */
i = 1;
priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
@@ -318,11 +328,12 @@ void iwl_reset_qos(struct iwl_priv *priv)
priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
+ /* AC_VI */
i = 2;
priv->qos_data.def_qos_parm.ac[i].cw_min =
cpu_to_le16((cw_min + 1) / 2 - 1);
priv->qos_data.def_qos_parm.ac[i].cw_max =
- cpu_to_le16(cw_max);
+ cpu_to_le16(cw_min);
priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
if (is_legacy)
priv->qos_data.def_qos_parm.ac[i].edca_txop =
@@ -332,11 +343,12 @@ void iwl_reset_qos(struct iwl_priv *priv)
cpu_to_le16(3008);
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
+ /* AC_VO */
i = 3;
priv->qos_data.def_qos_parm.ac[i].cw_min =
cpu_to_le16((cw_min + 1) / 4 - 1);
priv->qos_data.def_qos_parm.ac[i].cw_max =
- cpu_to_le16((cw_max + 1) / 2 - 1);
+ cpu_to_le16((cw_min + 1) / 2 - 1);
priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
if (is_legacy)
@@ -735,6 +747,8 @@ int iwl_full_rxon_required(struct iwl_priv *priv)
priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
(priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
+ (priv->staging_rxon.ofdm_ht_triple_stream_basic_rates !=
+ priv->active_rxon.ofdm_ht_triple_stream_basic_rates) ||
(priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
return 1;
@@ -821,7 +835,8 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS);
- iwl_set_rxon_chain(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
IWL_DEBUG_ASSOC(priv, "supported HT rate 0x%X 0x%X 0x%X "
"rxon flags 0x%X operation mode :0x%X "
@@ -901,10 +916,11 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
* never called for monitor mode. The only way mac80211 informs us about
* monitor mode is through configuring filters (call to configure_filter).
*/
-static bool iwl_is_monitor_mode(struct iwl_priv *priv)
+bool iwl_is_monitor_mode(struct iwl_priv *priv)
{
return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
}
+EXPORT_SYMBOL(iwl_is_monitor_mode);
/**
* iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
@@ -956,10 +972,10 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
if (iwl_is_monitor_mode(priv) &&
!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) {
- rx_chain = 0x07 << RXON_RX_CHAIN_VALID_POS;
- rx_chain |= 0x06 << RXON_RX_CHAIN_FORCE_SEL_POS;
- rx_chain |= 0x07 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
- rx_chain |= 0x01 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+ rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS;
+ rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS;
+ rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+ rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
}
priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
@@ -1068,11 +1084,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
RXON_FILTER_ACCEPT_GRP_MSK;
break;
- case NL80211_IFTYPE_MONITOR:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
- priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
- RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
- break;
default:
IWL_ERR(priv, "Unsupported interface type %d\n", mode);
break;
@@ -1117,10 +1128,11 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN);
priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
+ priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff;
}
EXPORT_SYMBOL(iwl_connection_init_rx_config);
-void iwl_set_rate(struct iwl_priv *priv)
+static void iwl_set_rate(struct iwl_priv *priv)
{
const struct ieee80211_supported_band *hw = NULL;
struct ieee80211_rate *rate;
@@ -1166,7 +1178,6 @@ void iwl_set_rate(struct iwl_priv *priv)
priv->staging_rxon.ofdm_basic_rates =
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
}
-EXPORT_SYMBOL(iwl_set_rate);
void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
@@ -1230,11 +1241,6 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
"Restarting adapter due to uCode error.\n");
- if (iwl_is_associated(priv)) {
- memcpy(&priv->recovery_rxon, &priv->active_rxon,
- sizeof(priv->recovery_rxon));
- priv->error_recovering = 1;
- }
if (priv->cfg->mod_params->restart_fw)
queue_work(priv->workqueue, &priv->restart);
}
@@ -1298,19 +1304,20 @@ int iwl_setup_mac(struct iwl_priv *priv)
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM |
IEEE80211_HW_AMPDU_AGGREGATION |
- IEEE80211_HW_SPECTRUM_MGMT |
- IEEE80211_HW_SUPPORTS_PS;
+ IEEE80211_HW_SPECTRUM_MGMT;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->custom_regulatory = true;
- hw->wiphy->max_scan_ssids = 1;
+
+ hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
+ /* we create the 802.11 header and a zero-length SSID element */
+ hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
- hw->conf.beacon_int = 100;
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
@@ -1357,7 +1364,6 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->ibss_beacon = NULL;
spin_lock_init(&priv->lock);
- spin_lock_init(&priv->power_data.lock);
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
@@ -1366,7 +1372,7 @@ int iwl_init_drv(struct iwl_priv *priv)
mutex_init(&priv->mutex);
/* Clear the driver's (not device's) station table */
- iwl_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
priv->data_retry_limit = -1;
priv->ieee_channels = NULL;
@@ -1378,7 +1384,9 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
/* Choose which receivers/antennas to use */
- iwl_set_rxon_chain(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
iwl_init_scan_params(priv);
iwl_reset_qos(priv);
@@ -2054,7 +2062,7 @@ void iwl_bg_rf_kill(struct work_struct *work)
"HW and/or SW RF Kill no longer active, restarting "
"device\n");
if (!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
- test_bit(STATUS_ALIVE, &priv->status))
+ priv->is_open)
queue_work(priv->workqueue, &priv->restart);
} else {
/* make sure mac80211 stop sending Tx frame */
@@ -2112,3 +2120,666 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_rx_reply_error);
+void iwl_clear_isr_stats(struct iwl_priv *priv)
+{
+ memset(&priv->isr_stats, 0, sizeof(priv->isr_stats));
+}
+EXPORT_SYMBOL(iwl_clear_isr_stats);
+
+int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+ int q;
+
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+ return -EIO;
+ }
+
+ if (queue >= AC_NUM) {
+ IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
+ return 0;
+ }
+
+ q = AC_NUM - 1 - queue;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
+ priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
+ priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
+ priv->qos_data.def_qos_parm.ac[q].edca_txop =
+ cpu_to_le16((params->txop * 32));
+
+ priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
+ priv->qos_data.qos_active = 1;
+
+ if (priv->iw_mode == NL80211_IFTYPE_AP)
+ iwl_activate_qos(priv, 1);
+ else if (priv->assoc_id && iwl_is_associated(priv))
+ iwl_activate_qos(priv, 0);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ return 0;
+}
+EXPORT_SYMBOL(iwl_mac_conf_tx);
+
+static void iwl_ht_conf(struct iwl_priv *priv,
+ struct ieee80211_bss_conf *bss_conf)
+{
+ struct ieee80211_sta_ht_cap *ht_conf;
+ struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
+ struct ieee80211_sta *sta;
+
+ IWL_DEBUG_MAC80211(priv, "enter: \n");
+
+ if (!iwl_conf->is_ht)
+ return;
+
+
+ /*
+ * It is totally wrong to base global information on something
+ * that is valid only when associated, alas, this driver works
+ * that way and I don't know how to fix it.
+ */
+
+ rcu_read_lock();
+ sta = ieee80211_find_sta(priv->hw, priv->bssid);
+ if (!sta) {
+ rcu_read_unlock();
+ return;
+ }
+ ht_conf = &sta->ht_cap;
+
+ if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
+ iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
+ if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
+ iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
+
+ iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
+ iwl_conf->max_amsdu_size =
+ !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
+
+ iwl_conf->supported_chan_width =
+ !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
+
+ /*
+ * XXX: The HT configuration needs to be moved into iwl_mac_config()
+ * to be done there correctly.
+ */
+
+ iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ if (conf_is_ht40_minus(&priv->hw->conf))
+ iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ else if (conf_is_ht40_plus(&priv->hw->conf))
+ iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+
+ /* If no above or below channel supplied disable FAT channel */
+ if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
+ iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
+ iwl_conf->supported_chan_width = 0;
+
+ iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
+
+ memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
+
+ iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
+ iwl_conf->ht_protection =
+ bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
+ iwl_conf->non_GF_STA_present =
+ !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+
+ rcu_read_unlock();
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+
+#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
+void iwl_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes)
+{
+ struct iwl_priv *priv = hw->priv;
+ int ret;
+
+ IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
+
+ if (!iwl_is_alive(priv))
+ return;
+
+ mutex_lock(&priv->mutex);
+
+ if (changes & BSS_CHANGED_BEACON &&
+ priv->iw_mode == NL80211_IFTYPE_AP) {
+ dev_kfree_skb(priv->ibss_beacon);
+ priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
+ }
+
+ if ((changes & BSS_CHANGED_BSSID) && !iwl_is_rfkill(priv)) {
+ /* If there is currently a HW scan going on in the background
+ * then we need to cancel it else the RXON below will fail. */
+ if (iwl_scan_cancel_timeout(priv, 100)) {
+ IWL_WARN(priv, "Aborted scan still in progress "
+ "after 100ms\n");
+ IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+ memcpy(priv->staging_rxon.bssid_addr,
+ bss_conf->bssid, ETH_ALEN);
+
+ /* TODO: Audit driver for usage of these members and see
+ * if mac80211 deprecates them (priv->bssid looks like it
+ * shouldn't be there, but I haven't scanned the IBSS code
+ * to verify) - jpk */
+ memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+
+ if (priv->iw_mode == NL80211_IFTYPE_AP)
+ iwlcore_config_ap(priv);
+ else {
+ int rc = iwlcore_commit_rxon(priv);
+ if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
+ iwl_rxon_add_station(
+ priv, priv->active_rxon.bssid_addr, 1);
+ }
+ } else if (!iwl_is_rfkill(priv)) {
+ iwl_scan_cancel_timeout(priv, 100);
+ priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv);
+ }
+
+ if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+ changes & BSS_CHANGED_BEACON) {
+ struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+
+ if (beacon)
+ iwl_mac_beacon_update(hw, beacon);
+ }
+
+ mutex_unlock(&priv->mutex);
+
+ if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+ IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
+ bss_conf->use_short_preamble);
+ if (bss_conf->use_short_preamble)
+ priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ }
+
+ if (changes & BSS_CHANGED_ERP_CTS_PROT) {
+ IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
+ if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
+ priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ else
+ priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+ }
+
+ if (changes & BSS_CHANGED_HT) {
+ iwl_ht_conf(priv, bss_conf);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ }
+
+ if (changes & BSS_CHANGED_ASSOC) {
+ IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
+ /* This should never happen as this function should
+ * never be called from interrupt context. */
+ if (WARN_ON_ONCE(in_interrupt()))
+ return;
+ if (bss_conf->assoc) {
+ priv->assoc_id = bss_conf->aid;
+ priv->beacon_int = bss_conf->beacon_int;
+ priv->power_data.dtim_period = bss_conf->dtim_period;
+ priv->timestamp = bss_conf->timestamp;
+ priv->assoc_capability = bss_conf->assoc_capability;
+
+ /* we have just associated, don't start scan too early
+ * leave time for EAPOL exchange to complete
+ */
+ priv->next_scan_jiffies = jiffies +
+ IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
+ mutex_lock(&priv->mutex);
+ priv->cfg->ops->lib->post_associate(priv);
+ mutex_unlock(&priv->mutex);
+ } else {
+ priv->assoc_id = 0;
+ IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
+ }
+ } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
+ IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
+ ret = iwl_send_rxon_assoc(priv);
+ if (!ret)
+ /* Sync active_rxon with latest change. */
+ memcpy((void *)&priv->active_rxon,
+ &priv->staging_rxon,
+ sizeof(struct iwl_rxon_cmd));
+ }
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+EXPORT_SYMBOL(iwl_bss_info_changed);
+
+int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+ __le64 timestamp;
+
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+ return -EIO;
+ }
+
+ if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
+ IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
+ return -EIO;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (priv->ibss_beacon)
+ dev_kfree_skb(priv->ibss_beacon);
+
+ priv->ibss_beacon = skb;
+
+ priv->assoc_id = 0;
+ timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+ priv->timestamp = le64_to_cpu(timestamp);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ iwl_reset_qos(priv);
+
+ priv->cfg->ops->lib->post_associate(priv);
+
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_mac_beacon_update);
+
+int iwl_set_mode(struct iwl_priv *priv, int mode)
+{
+ if (mode == NL80211_IFTYPE_ADHOC) {
+ const struct iwl_channel_info *ch_info;
+
+ ch_info = iwl_get_channel_info(priv,
+ priv->band,
+ le16_to_cpu(priv->staging_rxon.channel));
+
+ if (!ch_info || !is_channel_ibss(ch_info)) {
+ IWL_ERR(priv, "channel %d not IBSS channel\n",
+ le16_to_cpu(priv->staging_rxon.channel));
+ return -EINVAL;
+ }
+ }
+
+ iwl_connection_init_rx_config(priv, mode);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
+ memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+
+ priv->cfg->ops->smgmt->clear_station_table(priv);
+
+ /* dont commit rxon if rf-kill is on*/
+ if (!iwl_is_ready_rf(priv))
+ return -EAGAIN;
+
+ cancel_delayed_work(&priv->scan_check);
+ if (iwl_scan_cancel_timeout(priv, 100)) {
+ IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
+ IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
+ return -EAGAIN;
+ }
+
+ iwlcore_commit_rxon(priv);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_set_mode);
+
+int iwl_mac_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+
+ IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
+
+ if (priv->vif) {
+ IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
+ return -EOPNOTSUPP;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->vif = conf->vif;
+ priv->iw_mode = conf->type;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ mutex_lock(&priv->mutex);
+
+ if (conf->mac_addr) {
+ IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
+ memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
+ }
+
+ if (iwl_set_mode(priv, conf->type) == -EAGAIN)
+ /* we are not ready, will run again when ready */
+ set_bit(STATUS_MODE_PENDING, &priv->status);
+
+ mutex_unlock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ return 0;
+}
+EXPORT_SYMBOL(iwl_mac_add_interface);
+
+void iwl_mac_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct iwl_priv *priv = hw->priv;
+
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ mutex_lock(&priv->mutex);
+
+ if (iwl_is_ready_rf(priv)) {
+ iwl_scan_cancel_timeout(priv, 100);
+ priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv);
+ }
+ if (priv->vif == conf->vif) {
+ priv->vif = NULL;
+ memset(priv->bssid, 0, ETH_ALEN);
+ }
+ mutex_unlock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+
+}
+EXPORT_SYMBOL(iwl_mac_remove_interface);
+
+/**
+ * iwl_mac_config - mac80211 config callback
+ *
+ * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
+ * be set inappropriately and the driver currently sets the hardware up to
+ * use it whenever needed.
+ */
+int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct iwl_priv *priv = hw->priv;
+ const struct iwl_channel_info *ch_info;
+ struct ieee80211_conf *conf = &hw->conf;
+ unsigned long flags = 0;
+ int ret = 0;
+ u16 ch;
+ int scan_active = 0;
+
+ mutex_lock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
+ conf->channel->hw_value, changed);
+
+ if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
+ test_bit(STATUS_SCANNING, &priv->status))) {
+ scan_active = 1;
+ IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
+ }
+
+
+ /* during scanning mac80211 will delay channel setting until
+ * scan finish with changed = 0
+ */
+ if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
+ if (scan_active)
+ goto set_ch_out;
+
+ ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
+ if (!is_channel_valid(ch_info)) {
+ IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
+ ret = -EINVAL;
+ goto set_ch_out;
+ }
+
+ if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+ !is_channel_ibss(ch_info)) {
+ IWL_ERR(priv, "channel %d in band %d not "
+ "IBSS channel\n",
+ conf->channel->hw_value, conf->channel->band);
+ ret = -EINVAL;
+ goto set_ch_out;
+ }
+
+ priv->current_ht_config.is_ht = conf_is_ht(conf);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+
+ /* if we are switching from ht to 2.4 clear flags
+ * from any ht related info since 2.4 does not
+ * support ht */
+ if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
+ priv->staging_rxon.flags = 0;
+
+ iwl_set_rxon_channel(priv, conf->channel);
+
+ iwl_set_flags_for_band(priv, conf->channel->band);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ set_ch_out:
+ /* The list of supported rates and rate mask can be different
+ * for each band; since the band may have changed, reset
+ * the rate mask to what mac80211 lists */
+ iwl_set_rate(priv);
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_PS &&
+ priv->iw_mode == NL80211_IFTYPE_STATION) {
+ priv->power_data.power_disabled =
+ !(conf->flags & IEEE80211_CONF_PS);
+ ret = iwl_power_update_mode(priv, 0);
+ if (ret)
+ IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
+ priv->tx_power_user_lmt, conf->power_level);
+
+ iwl_set_tx_power(priv, conf->power_level, false);
+ }
+
+ /* call to ensure that 4965 rx_chain is set properly in monitor mode */
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
+ if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
+ if (conf->radio_enabled &&
+ iwl_radio_kill_sw_enable_radio(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
+ "waiting for uCode\n");
+ goto out;
+ }
+
+ if (!conf->radio_enabled)
+ iwl_radio_kill_sw_disable_radio(priv);
+ }
+
+ if (!conf->radio_enabled) {
+ IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
+ goto out;
+ }
+
+ if (!iwl_is_ready(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ goto out;
+ }
+
+ if (scan_active)
+ goto out;
+
+ if (memcmp(&priv->active_rxon,
+ &priv->staging_rxon, sizeof(priv->staging_rxon)))
+ iwlcore_commit_rxon(priv);
+ else
+ IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration.\n");
+
+
+out:
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ mutex_unlock(&priv->mutex);
+ return ret;
+}
+EXPORT_SYMBOL(iwl_mac_config);
+
+int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
+ struct ieee80211_tx_queue_stats *stats)
+{
+ struct iwl_priv *priv = hw->priv;
+ int i, avail;
+ struct iwl_tx_queue *txq;
+ struct iwl_queue *q;
+ unsigned long flags;
+
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+ return -EIO;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ for (i = 0; i < AC_NUM; i++) {
+ txq = &priv->txq[i];
+ q = &txq->q;
+ avail = iwl_queue_space(q);
+
+ stats[i].len = q->n_window - avail;
+ stats[i].limit = q->n_window - q->high_mark;
+ stats[i].count = q->n_window;
+
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_mac_get_tx_stats);
+
+void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+
+ mutex_lock(&priv->mutex);
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ spin_lock_irqsave(&priv->lock, flags);
+ memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ iwl_reset_qos(priv);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->assoc_id = 0;
+ priv->assoc_capability = 0;
+ priv->assoc_station_added = 0;
+
+ /* new association get rid of ibss beacon skb */
+ if (priv->ibss_beacon)
+ dev_kfree_skb(priv->ibss_beacon);
+
+ priv->ibss_beacon = NULL;
+
+ priv->beacon_int = priv->vif->bss_conf.beacon_int;
+ priv->timestamp = 0;
+ if ((priv->iw_mode == NL80211_IFTYPE_STATION))
+ priv->beacon_int = 0;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ /* we are restarting association process
+ * clear RXON_FILTER_ASSOC_MSK bit
+ */
+ if (priv->iw_mode != NL80211_IFTYPE_AP) {
+ iwl_scan_cancel_timeout(priv, 100);
+ priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv);
+ }
+
+ if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
+ IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ iwl_set_rate(priv);
+
+ mutex_unlock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+EXPORT_SYMBOL(iwl_mac_reset_tsf);
+
+#ifdef CONFIG_PM
+
+int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
+
+ /*
+ * This function is called when system goes into suspend state
+ * mac80211 will call iwl_mac_stop() from the mac80211 suspend function
+ * first but since iwl_mac_stop() has no knowledge of who the caller is,
+ * it will not call apm_ops.stop() to stop the DMA operation.
+ * Calling apm_ops.stop here to make sure we stop the DMA.
+ */
+ priv->cfg->ops->lib->apm_ops.stop(priv);
+
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_pci_suspend);
+
+int iwl_pci_resume(struct pci_dev *pdev)
+{
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
+ int ret;
+
+ pci_set_power_state(pdev, PCI_D0);
+ ret = pci_enable_device(pdev);
+ if (ret)
+ return ret;
+ pci_restore_state(pdev);
+ iwl_enable_interrupts(priv);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_pci_resume);
+
+#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index a8eac8c3c1fa..f3544ea559a2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -83,9 +83,21 @@ struct iwl_cmd;
#define IWL_SKU_A 0x2
#define IWL_SKU_N 0x8
+struct iwl_station_mgmt_ops {
+ u8 (*add_station)(struct iwl_priv *priv, const u8 *addr,
+ int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info);
+ int (*remove_station)(struct iwl_priv *priv, const u8 *addr,
+ int is_ap);
+ u8 (*find_station)(struct iwl_priv *priv, const u8 *addr);
+ void (*clear_station_table)(struct iwl_priv *priv);
+};
+
struct iwl_hcmd_ops {
int (*rxon_assoc)(struct iwl_priv *priv);
+ int (*commit_rxon)(struct iwl_priv *priv);
+ void (*set_rxon_chain)(struct iwl_priv *priv);
};
+
struct iwl_hcmd_utils_ops {
u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
@@ -149,6 +161,9 @@ struct iwl_lib_ops {
int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv);
void (*temperature) (struct iwl_priv *priv);
+ void (*post_associate) (struct iwl_priv *priv);
+ void (*config_ap) (struct iwl_priv *priv);
+
/* eeprom operations (as defined in iwl-eeprom.h) */
struct iwl_eeprom_ops eeprom_ops;
};
@@ -157,10 +172,10 @@ struct iwl_ops {
const struct iwl_lib_ops *lib;
const struct iwl_hcmd_ops *hcmd;
const struct iwl_hcmd_utils_ops *utils;
+ const struct iwl_station_mgmt_ops *smgmt;
};
struct iwl_mod_params {
- int disable; /* def: 0 = enable radio */
int sw_crypto; /* def: 0 = using hardware encryption */
u32 debug; /* def: 0 = minimal debug log messages */
int disable_hw_scan; /* def: 0 = use h/w scan */
@@ -225,6 +240,8 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
void iwl_hw_detect(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
void iwl_activate_qos(struct iwl_priv *priv, u8 force);
+int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params);
void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
int iwl_check_rxon_cmd(struct iwl_priv *priv);
int iwl_full_rxon_required(struct iwl_priv *priv);
@@ -249,6 +266,24 @@ int iwl_setup_mac(struct iwl_priv *priv);
int iwl_set_hw_params(struct iwl_priv *priv);
int iwl_init_drv(struct iwl_priv *priv);
void iwl_uninit_drv(struct iwl_priv *priv);
+bool iwl_is_monitor_mode(struct iwl_priv *priv);
+void iwl_post_associate(struct iwl_priv *priv);
+void iwl_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes);
+int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
+int iwl_commit_rxon(struct iwl_priv *priv);
+int iwl_set_mode(struct iwl_priv *priv, int mode);
+int iwl_mac_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf);
+void iwl_mac_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf);
+int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
+void iwl_config_ap(struct iwl_priv *priv);
+int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
+ struct ieee80211_tx_queue_stats *stats);
+void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
/*****************************************************
* RX handlers.
@@ -328,8 +363,6 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
-void iwl_set_rate(struct iwl_priv *priv);
-
u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx);
static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
@@ -358,8 +391,8 @@ int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
int iwl_scan_initiate(struct iwl_priv *priv);
int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
-u16 iwl_fill_probe_req(struct iwl_priv *priv, enum ieee80211_band band,
- struct ieee80211_mgmt *frame, int left);
+u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
+ const u8 *ie, int ie_len, int left);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
enum ieee80211_band band,
@@ -432,12 +465,17 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
return pci_lnk_ctl;
}
+#ifdef CONFIG_PM
+int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
+int iwl_pci_resume(struct pci_dev *pdev);
+#endif /* CONFIG_PM */
/*****************************************************
* Error Handling Debugging
******************************************************/
void iwl_dump_nic_error_log(struct iwl_priv *priv);
void iwl_dump_nic_event_log(struct iwl_priv *priv);
+void iwl_clear_isr_stats(struct iwl_priv *priv);
/*****************************************************
* GEOS
@@ -458,7 +496,6 @@ void iwlcore_free_geos(struct iwl_priv *priv);
#define STATUS_TEMPERATURE 8
#define STATUS_GEO_CONFIGURED 9
#define STATUS_EXIT_PENDING 10
-#define STATUS_IN_SUSPEND 11
#define STATUS_STATISTICS 12
#define STATUS_SCANNING 13
#define STATUS_SCAN_ABORTING 14
@@ -528,7 +565,14 @@ static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
{
return priv->cfg->ops->hcmd->rxon_assoc(priv);
}
-
+static inline int iwlcore_commit_rxon(struct iwl_priv *priv)
+{
+ return priv->cfg->ops->hcmd->commit_rxon(priv);
+}
+static inline void iwlcore_config_ap(struct iwl_priv *priv)
+{
+ priv->cfg->ops->lib->config_ap(priv);
+}
static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
struct iwl_priv *priv, enum ieee80211_band band)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 65d1a7f2db9e..db069801bc41 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -75,6 +75,7 @@ struct iwl_debugfs {
struct dentry *file_log_event;
struct dentry *file_channels;
struct dentry *file_status;
+ struct dentry *file_interrupt;
} dbgfs_data_files;
struct dir_rf_files {
struct dentry *file_disable_sensitivity;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 64eb585f1578..ffc4be3842b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -389,7 +389,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
channels[i].max_power,
channels[i].flags & IEEE80211_CHAN_RADAR ?
" (IEEE 802.11h required)" : "",
- (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS)
+ ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
|| (channels[i].flags &
IEEE80211_CHAN_RADAR)) ? "" :
", IBSS",
@@ -456,8 +456,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
test_bit(STATUS_GEO_CONFIGURED, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
test_bit(STATUS_EXIT_PENDING, &priv->status));
- pos += scnprintf(buf + pos, bufsz - pos, "STATUS_IN_SUSPEND:\t %d\n",
- test_bit(STATUS_IN_SUSPEND, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
test_bit(STATUS_STATISTICS, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
@@ -475,6 +473,95 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
+static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos) {
+
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ int pos = 0;
+ int cnt = 0;
+ char *buf;
+ int bufsz = 24 * 64; /* 24 items * 64 char per item */
+ ssize_t ret;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "Interrupt Statistics Report:\n");
+
+ pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
+ priv->isr_stats.hw);
+ pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
+ priv->isr_stats.sw);
+ if (priv->isr_stats.sw > 0) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\tLast Restarting Code: 0x%X\n",
+ priv->isr_stats.sw_err);
+ }
+#ifdef CONFIG_IWLWIFI_DEBUG
+ pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
+ priv->isr_stats.sch);
+ pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
+ priv->isr_stats.alive);
+#endif
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "HW RF KILL switch toggled:\t %u\n",
+ priv->isr_stats.rfkill);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
+ priv->isr_stats.ctkill);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
+ priv->isr_stats.wakeup);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "Rx command responses:\t\t %u\n",
+ priv->isr_stats.rx);
+ for (cnt = 0; cnt < REPLY_MAX; cnt++) {
+ if (priv->isr_stats.rx_handlers[cnt] > 0)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\tRx handler[%36s]:\t\t %u\n",
+ get_cmd_string(cnt),
+ priv->isr_stats.rx_handlers[cnt]);
+ }
+
+ pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
+ priv->isr_stats.tx);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
+ priv->isr_stats.unhandled);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = file->private_data;
+ char buf[8];
+ int buf_size;
+ u32 reset_flag;
+
+ memset(buf, 0, sizeof(buf));
+ buf_size = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ if (sscanf(buf, "%x", &reset_flag) != 1)
+ return -EFAULT;
+ if (reset_flag == 0)
+ iwl_clear_isr_stats(priv);
+
+ return count;
+}
+
+
DEBUGFS_READ_WRITE_FILE_OPS(sram);
DEBUGFS_WRITE_FILE_OPS(log_event);
DEBUGFS_READ_FILE_OPS(eeprom);
@@ -483,6 +570,7 @@ DEBUGFS_READ_FILE_OPS(rx_statistics);
DEBUGFS_READ_FILE_OPS(tx_statistics);
DEBUGFS_READ_FILE_OPS(channels);
DEBUGFS_READ_FILE_OPS(status);
+DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
/*
* Create the debugfs files and directories
@@ -518,6 +606,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(tx_statistics, data);
DEBUGFS_ADD_FILE(channels, data);
DEBUGFS_ADD_FILE(status, data);
+ DEBUGFS_ADD_FILE(interrupt, data);
DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
&priv->disable_chain_noise_cal);
@@ -548,6 +637,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
DEBUGFS_REMOVE(priv->dbgfs->dir_data);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index cf7f0db58fcf..3049ba25c3fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -70,6 +70,7 @@ extern struct iwl_ops iwl5000_ops;
extern struct iwl_lib_ops iwl5000_lib;
extern struct iwl_hcmd_ops iwl5000_hcmd;
extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
+extern struct iwl_station_mgmt_ops iwl5000_station_mgmt;
/* shared functions from iwl-5000.c */
extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len);
@@ -822,6 +823,21 @@ enum {
MEASUREMENT_ACTIVE = (1 << 1),
};
+/* interrupt statistics */
+struct isr_statistics {
+ u32 hw;
+ u32 sw;
+ u32 sw_err;
+ u32 sch;
+ u32 alive;
+ u32 rfkill;
+ u32 ctkill;
+ u32 wakeup;
+ u32 rx;
+ u32 rx_handlers[REPLY_MAX];
+ u32 tx;
+ u32 unhandled;
+};
#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
@@ -877,9 +893,7 @@ struct iwl_priv {
unsigned long scan_start_tsf;
void *scan;
int scan_bands;
- int one_direct_scan;
- u8 direct_ssid_len;
- u8 direct_ssid[IW_ESSID_MAX_SIZE];
+ struct cfg80211_scan_request *scan_request;
u8 scan_tx_ant[IEEE80211_NUM_BANDS];
u8 mgmt_tx_ant;
@@ -919,7 +933,6 @@ struct iwl_priv {
const struct iwl_rxon_cmd active_rxon;
struct iwl_rxon_cmd staging_rxon;
- int error_recovering;
struct iwl_rxon_cmd recovery_rxon;
/* 1st responses from initialize and runtime uCode images.
@@ -978,6 +991,9 @@ struct iwl_priv {
u64 bytes;
} tx_stats[3], rx_stats[3];
+ /* counts interrupts */
+ struct isr_statistics isr_stats;
+
struct iwl_power_mgr power_data;
struct iwl_notif_statistics statistics;
@@ -1059,7 +1075,6 @@ struct iwl_priv {
struct tasklet_struct irq_tasklet;
- struct delayed_work set_power_save;
struct delayed_work init_alive_start;
struct delayed_work alive_start;
struct delayed_work scan_check;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 75517d05df08..401438aec19c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -285,7 +285,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
return 0;
err:
- IWL_ERR(priv, "Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
+ IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
eeprom_ver, priv->cfg->eeprom_ver,
calib_ver, priv->cfg->eeprom_calib_ver);
return -EINVAL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 47c894530eb5..f2ea3f05f6e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -41,38 +41,33 @@
#include "iwl-power.h"
/*
- * Setting power level allow the card to go to sleep when not busy
- * there are three factor that decide the power level to go to, they
- * are list here with its priority
- * 1- critical_power_setting this will be set according to card temperature.
- * 2- system_power_setting this will be set by system PM manager.
- * 3- user_power_setting this will be set by user either by writing to sys or
- * mac80211
+ * Setting power level allow the card to go to sleep when not busy.
*
- * if system_power_setting and user_power_setting is set to auto
- * the power level will be decided according to association status and battery
- * status.
+ * The power level is set to INDEX_1 (the least deep state) by
+ * default, and will, in the future, be the deepest state unless
+ * otherwise required by pm_qos network latency requirements.
*
+ * Using INDEX_1 without pm_qos is ok because mac80211 will disable
+ * PS when even checking every beacon for the TIM bit would exceed
+ * the required latency.
*/
-#define MSEC_TO_USEC 1024
#define IWL_POWER_RANGE_0_MAX (2)
#define IWL_POWER_RANGE_1_MAX (10)
-
-#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5
-#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM
-#define IWL_POWER_ON_AC_ASSOC IWL_POWER_MODE_CAM
-
-
-#define IWL_CT_KILL_TEMPERATURE 110
-#define IWL_MIN_POWER_TEMPERATURE 100
-#define IWL_REDUCED_POWER_TEMPERATURE 95
-
+#define NOSLP cpu_to_le16(0), 0, 0
+#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
+#define TU_TO_USEC 1024
+#define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC)
+#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
+ cpu_to_le32(X1), \
+ cpu_to_le32(X2), \
+ cpu_to_le32(X3), \
+ cpu_to_le32(X4)}
/* default power management (not Tx power) table values */
-/* for TIM 0-10 */
-static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
+/* for DTIM period 0 through IWL_POWER_RANGE_0_MAX */
+static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
@@ -82,8 +77,8 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
};
-/* for TIM = 3-10 */
-static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
+/* for DTIM period IWL_POWER_RANGE_0_MAX + 1 through IWL_POWER_RANGE_1_MAX */
+static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
@@ -92,8 +87,8 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}
};
-/* for TIM > 11 */
-static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
+/* for DTIM period > IWL_POWER_RANGE_1_MAX */
+static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
@@ -106,39 +101,15 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
/* set card power command */
static int iwl_set_power(struct iwl_priv *priv, void *cmd)
{
- return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
- sizeof(struct iwl_powertable_cmd),
- cmd, NULL);
-}
-/* decide the right power level according to association status
- * and battery status
- */
-static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
-{
- u16 mode;
-
- switch (priv->power_data.user_power_setting) {
- case IWL_POWER_AUTO:
- /* if running on battery */
- if (priv->power_data.is_battery_active)
- mode = IWL_POWER_ON_BATTERY;
- else if (iwl_is_associated(priv))
- mode = IWL_POWER_ON_AC_ASSOC;
- else
- mode = IWL_POWER_ON_AC_DISASSOC;
- break;
- default:
- mode = priv->power_data.user_power_setting;
- break;
- }
- return mode;
+ return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
+ sizeof(struct iwl_powertable_cmd), cmd);
}
/* initialize to default */
static void iwl_power_init_handle(struct iwl_priv *priv)
{
struct iwl_power_mgr *pow_data;
- int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
+ int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_NUM;
struct iwl_powertable_cmd *cmd;
int i;
u16 lctl;
@@ -157,7 +128,7 @@ static void iwl_power_init_handle(struct iwl_priv *priv)
IWL_DEBUG_POWER(priv, "adjust power command flags\n");
- for (i = 0; i < IWL_POWER_MAX; i++) {
+ for (i = 0; i < IWL_POWER_NUM; i++) {
cmd = &pow_data->pwr_range_0[i].cmd;
if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
@@ -247,33 +218,12 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
- /* If on battery, set to 3,
- * if plugged into AC power, set to CAM ("continuously aware mode"),
- * else user level */
-
- switch (setting->system_power_setting) {
- case IWL_POWER_SYS_AUTO:
- final_mode = iwl_get_auto_power_mode(priv);
- break;
- case IWL_POWER_SYS_BATTERY:
- final_mode = IWL_POWER_INDEX_3;
- break;
- case IWL_POWER_SYS_AC:
- final_mode = IWL_POWER_MODE_CAM;
- break;
- default:
- final_mode = IWL_POWER_INDEX_3;
- WARN_ON(1);
- }
-
- if (setting->critical_power_setting > final_mode)
- final_mode = setting->critical_power_setting;
+ final_mode = priv->power_data.user_power_setting;
- /* driver only support CAM for non STA network */
- if (priv->iw_mode != NL80211_IFTYPE_STATION)
+ if (setting->power_disabled)
final_mode = IWL_POWER_MODE_CAM;
- if (iwl_is_ready_rf(priv) && !setting->power_disabled &&
+ if (iwl_is_ready_rf(priv) &&
((setting->power_mode != final_mode) || force)) {
struct iwl_powertable_cmd cmd;
@@ -290,8 +240,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
if (final_mode == IWL_POWER_MODE_CAM)
clear_bit(STATUS_POWER_PMI, &priv->status);
- else
- set_bit(STATUS_POWER_PMI, &priv->status);
if (priv->cfg->ops->lib->update_chain_flags && update_chains)
priv->cfg->ops->lib->update_chain_flags(priv);
@@ -307,51 +255,10 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
}
EXPORT_SYMBOL(iwl_power_update_mode);
-/* Allow other iwl code to disable/enable power management active
- * this will be useful for rate scale to disable PM during heavy
- * Tx/Rx activities
- */
-int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
-{
- u16 prev_mode;
- int ret = 0;
-
- if (priv->power_data.power_disabled)
- return -EBUSY;
-
- prev_mode = priv->power_data.user_power_setting;
- priv->power_data.user_power_setting = IWL_POWER_MODE_CAM;
- ret = iwl_power_update_mode(priv, 0);
- priv->power_data.power_disabled = 1;
- priv->power_data.user_power_setting = prev_mode;
- cancel_delayed_work(&priv->set_power_save);
- if (ms)
- queue_delayed_work(priv->workqueue, &priv->set_power_save,
- msecs_to_jiffies(ms));
-
-
- return ret;
-}
-EXPORT_SYMBOL(iwl_power_disable_management);
-
-/* Allow other iwl code to disable/enable power management active
- * this will be useful for rate scale to disable PM during high
- * volume activities
- */
-int iwl_power_enable_management(struct iwl_priv *priv)
-{
- int ret = 0;
-
- priv->power_data.power_disabled = 0;
- ret = iwl_power_update_mode(priv, 0);
- return ret;
-}
-EXPORT_SYMBOL(iwl_power_enable_management);
-
/* set user_power_setting */
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
{
- if (mode > IWL_POWER_MAX)
+ if (mode >= IWL_POWER_NUM)
return -EINVAL;
priv->power_data.user_power_setting = mode;
@@ -360,86 +267,12 @@ int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
}
EXPORT_SYMBOL(iwl_power_set_user_mode);
-/* set system_power_setting. This should be set by over all
- * PM application.
- */
-int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
-{
- if (mode < IWL_POWER_SYS_MAX)
- priv->power_data.system_power_setting = mode;
- else
- return -EINVAL;
- return iwl_power_update_mode(priv, 0);
-}
-EXPORT_SYMBOL(iwl_power_set_system_mode);
-
/* initialize to default */
void iwl_power_initialize(struct iwl_priv *priv)
{
iwl_power_init_handle(priv);
- priv->power_data.user_power_setting = IWL_POWER_AUTO;
- priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
- priv->power_data.power_disabled = 0;
- priv->power_data.is_battery_active = 0;
- priv->power_data.critical_power_setting = 0;
+ priv->power_data.user_power_setting = IWL_POWER_INDEX_1;
+ /* default to disabled until mac80211 says otherwise */
+ priv->power_data.power_disabled = 1;
}
EXPORT_SYMBOL(iwl_power_initialize);
-
-/* set critical_power_setting according to temperature value */
-int iwl_power_temperature_change(struct iwl_priv *priv)
-{
- int ret = 0;
- s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature);
- u16 new_critical = priv->power_data.critical_power_setting;
-
- if (temperature > IWL_CT_KILL_TEMPERATURE)
- return 0;
- else if (temperature > IWL_MIN_POWER_TEMPERATURE)
- new_critical = IWL_POWER_INDEX_5;
- else if (temperature > IWL_REDUCED_POWER_TEMPERATURE)
- new_critical = IWL_POWER_INDEX_3;
- else
- new_critical = IWL_POWER_MODE_CAM;
-
- if (new_critical != priv->power_data.critical_power_setting)
- priv->power_data.critical_power_setting = new_critical;
-
- if (priv->power_data.critical_power_setting >
- priv->power_data.power_mode)
- ret = iwl_power_update_mode(priv, 0);
-
- return ret;
-}
-EXPORT_SYMBOL(iwl_power_temperature_change);
-
-static void iwl_bg_set_power_save(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work,
- struct iwl_priv, set_power_save.work);
- IWL_DEBUG_POWER(priv, "update power\n");
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
-
- /* on starting association we disable power management
- * until association, if association failed then this
- * timer will expire and enable PM again.
- */
- if (!iwl_is_associated(priv))
- iwl_power_enable_management(priv);
-
- mutex_unlock(&priv->mutex);
-}
-void iwl_setup_power_deferred_work(struct iwl_priv *priv)
-{
- INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save);
-}
-EXPORT_SYMBOL(iwl_setup_power_deferred_work);
-
-void iwl_power_cancel_timeout(struct iwl_priv *priv)
-{
- cancel_delayed_work(&priv->set_power_save);
-}
-EXPORT_SYMBOL(iwl_power_cancel_timeout);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 18963392121e..37ba3bb7a25a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -40,56 +40,29 @@ enum {
IWL_POWER_INDEX_3,
IWL_POWER_INDEX_4,
IWL_POWER_INDEX_5,
- IWL_POWER_AUTO,
- IWL_POWER_MAX = IWL_POWER_AUTO,
+ IWL_POWER_NUM
};
-enum {
- IWL_POWER_SYS_AUTO,
- IWL_POWER_SYS_AC,
- IWL_POWER_SYS_BATTERY,
- IWL_POWER_SYS_MAX,
-};
-
-
/* Power management (not Tx power) structures */
-#define NOSLP cpu_to_le16(0), 0, 0
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
-#define SLP_TOUT(T) cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
- cpu_to_le32(X1), \
- cpu_to_le32(X2), \
- cpu_to_le32(X3), \
- cpu_to_le32(X4)}
struct iwl_power_vec_entry {
struct iwl_powertable_cmd cmd;
u8 no_dtim;
};
struct iwl_power_mgr {
- spinlock_t lock;
- struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX];
- struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX];
- struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX];
+ struct iwl_power_vec_entry pwr_range_0[IWL_POWER_NUM];
+ struct iwl_power_vec_entry pwr_range_1[IWL_POWER_NUM];
+ struct iwl_power_vec_entry pwr_range_2[IWL_POWER_NUM];
u32 dtim_period;
/* final power level that used to calculate final power command */
u8 power_mode;
- u8 user_power_setting; /* set by user through mac80211 or sysfs */
- u8 system_power_setting; /* set by kernel system tools */
- u8 critical_power_setting; /* set if driver over heated */
- u8 is_battery_active; /* DC/AC power */
- u8 power_disabled; /* flag to disable using power saving level */
+ u8 user_power_setting; /* set by user through sysfs */
+ u8 power_disabled; /* set by mac80211's CONF_PS */
};
-void iwl_setup_power_deferred_work(struct iwl_priv *priv);
-void iwl_power_cancel_timeout(struct iwl_priv *priv);
int iwl_power_update_mode(struct iwl_priv *priv, bool force);
-int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
-int iwl_power_enable_management(struct iwl_priv *priv);
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
-int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);
void iwl_power_initialize(struct iwl_priv *priv);
-int iwl_power_temperature_change(struct iwl_priv *priv);
#endif /* __iwl_power_setting_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 8f65908f66f1..fae84262efb6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1102,13 +1102,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
if (rx_start->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
rx_status.flag |= RX_FLAG_SHORTPRE;
- /* Take shortcut when only in monitor mode */
- if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
- iwl_pass_packet_to_mac80211(priv, include_phy,
- rxb, &rx_status);
- return;
- }
-
network_packet = iwl_is_network_packet(priv, header);
if (network_packet) {
priv->last_rx_rssi = rx_status.signal;
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index e7c65c4f741b..065214b55895 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -448,13 +448,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
unsigned long flags;
struct iwl_priv *priv = hw->priv;
int ret;
- u8 *ssid = NULL;
- size_t ssid_len = 0;
-
- if (req->n_ssids) {
- ssid = req->ssids[0].ssid;
- ssid_len = req->ssids[0].ssid_len;
- }
IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -488,13 +481,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
goto out_unlock;
}
- if (ssid_len) {
- priv->one_direct_scan = 1;
- priv->direct_ssid_len = ssid_len;
- memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
- } else {
- priv->one_direct_scan = 0;
- }
+ priv->scan_request = req;
ret = iwl_scan_initiate(priv);
@@ -533,73 +520,14 @@ void iwl_bg_scan_check(struct work_struct *data)
EXPORT_SYMBOL(iwl_bg_scan_check);
/**
- * iwl_supported_rate_to_ie - fill in the supported rate in IE field
- *
- * return : set the bit for each supported rate insert in ie
- */
-static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
- u16 basic_rate, int *left)
-{
- u16 ret_rates = 0, bit;
- int i;
- u8 *cnt = ie;
- u8 *rates = ie + 1;
-
- for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
- if (bit & supported_rate) {
- ret_rates |= bit;
- rates[*cnt] = iwl_rates[i].ieee |
- ((bit & basic_rate) ? 0x80 : 0x00);
- (*cnt)++;
- (*left)--;
- if ((*left <= 0) ||
- (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
- break;
- }
- }
-
- return ret_rates;
-}
-
-
-static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
- u8 *pos, int *left)
-{
- struct ieee80211_ht_cap *ht_cap;
-
- if (!sband || !sband->ht_cap.ht_supported)
- return;
-
- if (*left < sizeof(struct ieee80211_ht_cap))
- return;
-
- *pos++ = sizeof(struct ieee80211_ht_cap);
- ht_cap = (struct ieee80211_ht_cap *) pos;
-
- ht_cap->cap_info = cpu_to_le16(sband->ht_cap.cap);
- memcpy(&ht_cap->mcs, &sband->ht_cap.mcs, 16);
- ht_cap->ampdu_params_info =
- (sband->ht_cap.ampdu_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) |
- ((sband->ht_cap.ampdu_density << 2) &
- IEEE80211_HT_AMPDU_PARM_DENSITY);
- *left -= sizeof(struct ieee80211_ht_cap);
-}
-
-/**
* iwl_fill_probe_req - fill in all required fields and IE for probe request
*/
-u16 iwl_fill_probe_req(struct iwl_priv *priv,
- enum ieee80211_band band,
- struct ieee80211_mgmt *frame,
- int left)
+u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
+ const u8 *ies, int ie_len, int left)
{
int len = 0;
u8 *pos = NULL;
- u16 active_rates, ret_rates, cck_rates, active_rate_basic;
- const struct ieee80211_supported_band *sband =
- iwl_get_hw_mode(priv, band);
-
/* Make sure there is enough space for the probe request,
* two mandatory IEs and the data */
@@ -627,62 +555,12 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv,
len += 2;
- /* fill in supported rate */
- left -= 2;
- if (left < 0)
- return 0;
-
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos = 0;
-
- /* exclude 60M rate */
- active_rates = priv->rates_mask;
- active_rates &= ~IWL_RATE_60M_MASK;
-
- active_rate_basic = active_rates & IWL_BASIC_RATES_MASK;
-
- cck_rates = IWL_CCK_RATES_MASK & active_rates;
- ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
- active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
- active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- len += 2 + *pos;
- pos += (*pos) + 1;
+ if (WARN_ON(left < ie_len))
+ return len;
- if (active_rates == 0)
- goto fill_end;
-
- /* fill in supported extended rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
- /* ... fill it in... */
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos = 0;
- iwl_supported_rate_to_ie(pos, active_rates, active_rate_basic, &left);
- if (*pos > 0) {
- len += 2 + *pos;
- pos += (*pos) + 1;
- } else {
- pos--;
- }
-
- fill_end:
-
- left -= 2;
- if (left < 0)
- return 0;
-
- *pos++ = WLAN_EID_HT_CAPABILITY;
- *pos = 0;
- iwl_ht_cap_to_ie(sband, pos, &left);
- if (*pos > 0)
- len += 2 + *pos;
+ memcpy(pos, ies, ie_len);
+ len += ie_len;
+ left -= ie_len;
return (u16)len;
}
@@ -702,11 +580,12 @@ static void iwl_bg_request_scan(struct work_struct *data)
int ret = 0;
u32 rate_flags = 0;
u16 cmd_len;
+ u16 rx_chain = 0;
enum ieee80211_band band;
- u8 n_probes = 2;
- u8 rx_chain = priv->hw_params.valid_rx_ant;
+ u8 n_probes = 0;
+ u8 rx_ant = priv->hw_params.valid_rx_ant;
u8 rate;
- DECLARE_SSID_BUF(ssid);
+ bool is_active = false;
conf = ieee80211_get_hw_conf(priv->hw);
@@ -796,19 +675,25 @@ static void iwl_bg_request_scan(struct work_struct *data)
scan_suspend_time, interval);
}
- /* We should add the ability for user to lock to PASSIVE ONLY */
- if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN(priv, "Start direct scan for '%s'\n",
- print_ssid(ssid, priv->direct_ssid,
- priv->direct_ssid_len));
- scan->direct_scan[0].id = WLAN_EID_SSID;
- scan->direct_scan[0].len = priv->direct_ssid_len;
- memcpy(scan->direct_scan[0].ssid,
- priv->direct_ssid, priv->direct_ssid_len);
- n_probes++;
- } else {
- IWL_DEBUG_SCAN(priv, "Start indirect scan.\n");
- }
+ if (priv->scan_request->n_ssids) {
+ int i, p = 0;
+ IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
+ for (i = 0; i < priv->scan_request->n_ssids; i++) {
+ /* always does wildcard anyway */
+ if (!priv->scan_request->ssids[i].ssid_len)
+ continue;
+ scan->direct_scan[p].id = WLAN_EID_SSID;
+ scan->direct_scan[p].len =
+ priv->scan_request->ssids[i].ssid_len;
+ memcpy(scan->direct_scan[p].ssid,
+ priv->scan_request->ssids[i].ssid,
+ priv->scan_request->ssids[i].ssid_len);
+ n_probes++;
+ p++;
+ }
+ is_active = true;
+ } else
+ IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
@@ -828,13 +713,18 @@ static void iwl_bg_request_scan(struct work_struct *data)
} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
band = IEEE80211_BAND_5GHZ;
rate = IWL_RATE_6M_PLCP;
- scan->good_CRC_th = IWL_GOOD_CRC_TH;
+ /*
+ * If active scaning is requested but a certain channel
+ * is marked passive, we can do active scanning if we
+ * detect transmissions.
+ */
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
/* Force use of chains B and C (0x6) for scan Rx for 4965
* Avoid A (0x1) because of its off-channel reception on A-band.
*/
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
- rx_chain = 0x6;
+ rx_ant = ANT_BC;
} else {
IWL_WARN(priv, "Invalid scan band count\n");
goto done;
@@ -846,26 +736,27 @@ static void iwl_bg_request_scan(struct work_struct *data)
scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
/* MIMO is not used here, but value is required */
- scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
- cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
- (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) |
- (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));
-
- cmd_len = iwl_fill_probe_req(priv, band,
- (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan));
+ rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS;
+ rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+ rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
+ rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+ scan->rx_chain = cpu_to_le16(rx_chain);
+ cmd_len = iwl_fill_probe_req(priv,
+ (struct ieee80211_mgmt *)scan->data,
+ priv->scan_request->ie,
+ priv->scan_request->ie_len,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan));
scan->tx_cmd.len = cpu_to_le16(cmd_len);
- if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
+ if (iwl_is_monitor_mode(priv))
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
RXON_FILTER_BCON_AWARE_MSK);
scan->channel_count =
- iwl_get_channels_for_scan(priv, band, 1, /* active */
- n_probes,
+ iwl_get_channels_for_scan(priv, band, is_active, n_probes,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
if (scan->channel_count == 0) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 5798fe49c771..0eb939c40ac1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -75,7 +75,7 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
return IWL_AP_ID;
} else {
u8 *da = ieee80211_get_DA(hdr);
- return iwl_find_station(priv, da);
+ return priv->cfg->ops->smgmt->find_station(priv, da);
}
}
EXPORT_SYMBOL(iwl_get_ra_sta_id);
@@ -300,7 +300,7 @@ EXPORT_SYMBOL(iwl_add_station_flags);
static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
{
unsigned long flags;
- u8 sta_id = iwl_find_station(priv, addr);
+ u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);
BUG_ON(sta_id == IWL_INVALID_STATION);
@@ -490,7 +490,7 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
/* keep track of static keys */
for (i = 0; i < WEP_KEYS_MAX ; i++) {
if (priv->wep_keys[i].key_size)
- test_and_set_bit(i, &priv->ucode_key_table);
+ set_bit(i, &priv->ucode_key_table);
}
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -719,6 +719,14 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
{
unsigned long flags;
int ret = 0;
+ __le16 key_flags = 0;
+
+ key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
+ key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+ key_flags &= ~STA_KEY_FLG_INVALID;
+
+ if (sta_id == priv->hw_params.bcast_sta_id)
+ key_flags |= STA_KEY_MULTICAST_MSK;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
@@ -738,6 +746,9 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
"no space for a new key");
+ priv->stations[sta_id].sta.key.key_flags = key_flags;
+
+
/* This copy is acutally not needed: we get the key with each TX */
memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
@@ -754,11 +765,9 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
{
u8 sta_id = IWL_INVALID_STATION;
unsigned long flags;
- __le16 key_flags = 0;
int i;
- DECLARE_MAC_BUF(mac);
- sta_id = iwl_find_station(priv, addr);
+ sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
@@ -771,16 +780,8 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
return;
}
- key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
- key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
- key_flags &= ~STA_KEY_FLG_INVALID;
-
- if (sta_id == priv->hw_params.bcast_sta_id)
- key_flags |= STA_KEY_MULTICAST_MSK;
-
spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
for (i = 0; i < 5; i++)
@@ -1019,7 +1020,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
rcu_read_unlock();
}
- sta_id = iwl_add_station_flags(priv, addr, is_ap,
+ sta_id = priv->cfg->ops->smgmt->add_station(priv, addr, is_ap,
0, cur_ht_config);
/* Set up default rate scaling table in device's station table */
@@ -1053,7 +1054,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
/* If we are an AP, then find the station, or use BCAST */
case NL80211_IFTYPE_AP:
- sta_id = iwl_find_station(priv, hdr->addr1);
+ sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1);
if (sta_id != IWL_INVALID_STATION)
return sta_id;
return priv->hw_params.bcast_sta_id;
@@ -1061,12 +1062,12 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
/* If this frame is going out to an IBSS network, find the station,
* or create a new station table entry */
case NL80211_IFTYPE_ADHOC:
- sta_id = iwl_find_station(priv, hdr->addr1);
+ sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1);
if (sta_id != IWL_INVALID_STATION)
return sta_id;
/* Create new station table entry */
- sta_id = iwl_add_station_flags(priv, hdr->addr1,
+ sta_id = priv->cfg->ops->smgmt->add_station(priv, hdr->addr1,
0, CMD_ASYNC, NULL);
if (sta_id != IWL_INVALID_STATION)
@@ -1078,11 +1079,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
return priv->hw_params.bcast_sta_id;
- /* If we are in monitor mode, use BCAST. This is required for
- * packet injection. */
- case NL80211_IFTYPE_MONITOR:
- return priv->hw_params.bcast_sta_id;
-
default:
IWL_WARN(priv, "Unknown mode of operation: %d\n",
priv->iw_mode);
@@ -1115,7 +1111,7 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv,
unsigned long flags;
int sta_id;
- sta_id = iwl_find_station(priv, addr);
+ sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION)
return -ENXIO;
@@ -1137,7 +1133,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid)
unsigned long flags;
int sta_id;
- sta_id = iwl_find_station(priv, addr);
+ sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
return -ENXIO;
@@ -1172,7 +1168,7 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
{
/* FIXME: need locking over ps_status ??? */
- u8 sta_id = iwl_find_station(priv, addr);
+ u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);
if (sta_id != IWL_INVALID_STATION) {
u8 sta_awake = priv->stations[sta_id].
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 71d5b8a1a73e..a82cca0a30c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -728,7 +728,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* drop all data frame if we are not associated */
if (ieee80211_is_data(fc) &&
- (priv->iw_mode != NL80211_IFTYPE_MONITOR ||
+ (!iwl_is_monitor_mode(priv) ||
!(info->flags & IEEE80211_TX_CTL_INJECTED)) && /* packet injection */
(!iwl_is_associated(priv) ||
((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) ||
@@ -1183,8 +1183,10 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
__func__, ra, tid);
sta_id = iwl_find_station(priv, ra);
- if (sta_id == IWL_INVALID_STATION)
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Start AGG on invalid station\n");
return -ENXIO;
+ }
if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
@@ -1192,8 +1194,10 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
}
txq_id = iwl_txq_ctx_activate_free(priv);
- if (txq_id == -1)
+ if (txq_id == -1) {
+ IWL_ERR(priv, "No free aggregation queue available\n");
return -ENXIO;
+ }
spin_lock_irqsave(&priv->sta_lock, flags);
tid_data = &priv->stations[sta_id].tid[tid];
@@ -1207,7 +1211,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
return ret;
if (tid_data->tfds_in_queue == 0) {
- IWL_ERR(priv, "HW queue is empty\n");
+ IWL_DEBUG_HT(priv, "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON;
ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid);
} else {
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 70a00c8ee42e..c32ec809053f 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -149,7 +149,7 @@ out:
*
* NOTE: This does not clear or otherwise alter the device's station table.
*/
-static void iwl3945_clear_stations_table(struct iwl_priv *priv)
+void iwl3945_clear_stations_table(struct iwl_priv *priv)
{
unsigned long flags;
@@ -164,7 +164,7 @@ static void iwl3945_clear_stations_table(struct iwl_priv *priv)
/**
* iwl3945_add_station - Add station to station tables in driver and device
*/
-u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
+u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info)
{
int i;
int index = IWL_INVALID_STATION;
@@ -233,50 +233,6 @@ u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flag
}
-static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
-{
- int rc = 0;
- struct iwl_rx_packet *res = NULL;
- struct iwl3945_rxon_assoc_cmd rxon_assoc;
- struct iwl_host_cmd cmd = {
- .id = REPLY_RXON_ASSOC,
- .len = sizeof(rxon_assoc),
- .meta.flags = CMD_WANT_SKB,
- .data = &rxon_assoc,
- };
- const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
-
- if ((rxon1->flags == rxon2->flags) &&
- (rxon1->filter_flags == rxon2->filter_flags) &&
- (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
- (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
- return 0;
- }
-
- rxon_assoc.flags = priv->staging_rxon.flags;
- rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
- rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
- rxon_assoc.reserved = 0;
-
- rc = iwl_send_cmd_sync(priv, &cmd);
- if (rc)
- return rc;
-
- res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
- rc = -EIO;
- }
-
- priv->alloc_rxb_skb--;
- dev_kfree_skb_any(cmd.meta.u.skb);
-
- return rc;
-}
-
/**
* iwl3945_get_antenna_flags - Get antenna flags for RXON command
* @priv: eeprom and antenna fields are used to determine antenna flags
@@ -314,150 +270,6 @@ __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
return 0; /* "diversity" is default if error */
}
-/**
- * iwl3945_commit_rxon - commit staging_rxon to hardware
- *
- * The RXON command in staging_rxon is committed to the hardware and
- * the active_rxon structure is updated with the new data. This
- * function correctly transitions out of the RXON_ASSOC_MSK state if
- * a HW tune is required based on the RXON structure changes.
- */
-static int iwl3945_commit_rxon(struct iwl_priv *priv)
-{
- /* cast away the const for active_rxon in this function */
- struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
- struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
- int rc = 0;
- bool new_assoc =
- !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
-
- if (!iwl_is_alive(priv))
- return -1;
-
- /* always get timestamp with Rx frame */
- staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
-
- /* select antenna */
- staging_rxon->flags &=
- ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
- staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
-
- rc = iwl_check_rxon_cmd(priv);
- if (rc) {
- IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
- return -EINVAL;
- }
-
- /* If we don't need to send a full RXON, we can use
- * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
- * and other flags for the current radio configuration. */
- if (!iwl_full_rxon_required(priv)) {
- rc = iwl3945_send_rxon_assoc(priv);
- if (rc) {
- IWL_ERR(priv, "Error setting RXON_ASSOC "
- "configuration (%d).\n", rc);
- return rc;
- }
-
- memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
-
- return 0;
- }
-
- /* If we are currently associated and the new config requires
- * an RXON_ASSOC and the new config wants the associated mask enabled,
- * we must clear the associated from the active configuration
- * before we apply the new config */
- if (iwl_is_associated(priv) && new_assoc) {
- IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
- active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-
- /*
- * reserved4 and 5 could have been filled by the iwlcore code.
- * Let's clear them before pushing to the 3945.
- */
- active_rxon->reserved4 = 0;
- active_rxon->reserved5 = 0;
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl3945_rxon_cmd),
- &priv->active_rxon);
-
- /* If the mask clearing failed then we set
- * active_rxon back to what it was previously */
- if (rc) {
- active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
- "configuration (%d).\n", rc);
- return rc;
- }
- }
-
- IWL_DEBUG_INFO(priv, "Sending RXON\n"
- "* with%s RXON_FILTER_ASSOC_MSK\n"
- "* channel = %d\n"
- "* bssid = %pM\n",
- (new_assoc ? "" : "out"),
- le16_to_cpu(staging_rxon->channel),
- staging_rxon->bssid_addr);
-
- /*
- * reserved4 and 5 could have been filled by the iwlcore code.
- * Let's clear them before pushing to the 3945.
- */
- staging_rxon->reserved4 = 0;
- staging_rxon->reserved5 = 0;
-
- iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
-
- /* Apply the new configuration */
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl3945_rxon_cmd),
- staging_rxon);
- if (rc) {
- IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
- return rc;
- }
-
- memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
-
- iwl3945_clear_stations_table(priv);
-
- /* If we issue a new RXON command which required a tune then we must
- * send a new TXPOWER command or we won't be able to Tx any frames */
- rc = priv->cfg->ops->lib->send_tx_power(priv);
- if (rc) {
- IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
- return rc;
- }
-
- /* Add the broadcast address so we can send broadcast frames */
- if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) ==
- IWL_INVALID_STATION) {
- IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
- return -EIO;
- }
-
- /* If we have set the ASSOC_MSK and we are in BSS mode then
- * add the IWL_AP_ID to the station rate table */
- if (iwl_is_associated(priv) &&
- (priv->iw_mode == NL80211_IFTYPE_STATION))
- if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr,
- 1, 0)
- == IWL_INVALID_STATION) {
- IWL_ERR(priv, "Error adding AP address for transmit\n");
- return -EIO;
- }
-
- /* Init the hardware's rate fallback order based on the band */
- rc = iwl3945_init_hw_rate_table(priv);
- if (rc) {
- IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
- return -EIO;
- }
-
- return 0;
-}
-
static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
u8 sta_id)
@@ -739,7 +551,8 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
priv->rxon_timing.atim_window = 0;
} else {
priv->rxon_timing.beacon_interval =
- iwl3945_adjust_beacon_interval(conf->beacon_int);
+ iwl3945_adjust_beacon_interval(
+ priv->vif->bss_conf.beacon_int);
/* TODO: we need to get atim_window from upper stack
* for now we set to 0 */
priv->rxon_timing.atim_window = 0;
@@ -758,42 +571,6 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
-{
- if (mode == NL80211_IFTYPE_ADHOC) {
- const struct iwl_channel_info *ch_info;
-
- ch_info = iwl_get_channel_info(priv,
- priv->band,
- le16_to_cpu(priv->staging_rxon.channel));
-
- if (!ch_info || !is_channel_ibss(ch_info)) {
- IWL_ERR(priv, "channel %d not IBSS channel\n",
- le16_to_cpu(priv->staging_rxon.channel));
- return -EINVAL;
- }
- }
-
- iwl_connection_init_rx_config(priv, mode);
-
- iwl3945_clear_stations_table(priv);
-
- /* don't commit rxon if rf-kill is on*/
- if (!iwl_is_ready_rf(priv))
- return -EAGAIN;
-
- cancel_delayed_work(&priv->scan_check);
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
- return -EAGAIN;
- }
-
- iwl3945_commit_rxon(priv);
-
- return 0;
-}
-
static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
struct iwl_cmd *cmd,
@@ -900,64 +677,6 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
tx->next_frame_len = 0;
}
-/**
- * iwl3945_get_sta_id - Find station's index within station table
- */
-static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
-{
- int sta_id;
- u16 fc = le16_to_cpu(hdr->frame_control);
-
- /* If this frame is broadcast or management, use broadcast station id */
- if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
- is_multicast_ether_addr(hdr->addr1))
- return priv->hw_params.bcast_sta_id;
-
- switch (priv->iw_mode) {
-
- /* If we are a client station in a BSS network, use the special
- * AP station entry (that's the only station we communicate with) */
- case NL80211_IFTYPE_STATION:
- return IWL_AP_ID;
-
- /* If we are an AP, then find the station, or use BCAST */
- case NL80211_IFTYPE_AP:
- sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
- return priv->hw_params.bcast_sta_id;
-
- /* If this frame is going out to an IBSS network, find the station,
- * or create a new station table entry */
- case NL80211_IFTYPE_ADHOC: {
- /* Create new station table entry */
- sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
-
- sta_id = iwl3945_add_station(priv, hdr->addr1, 0, CMD_ASYNC);
-
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
-
- IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
- "Defaulting to broadcast...\n",
- hdr->addr1);
- iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
- return priv->hw_params.bcast_sta_id;
- }
- /* If we are in monitor mode, use BCAST. This is required for
- * packet injection. */
- case NL80211_IFTYPE_MONITOR:
- return priv->hw_params.bcast_sta_id;
-
- default:
- IWL_WARN(priv, "Unknown mode of operation: %d\n",
- priv->iw_mode);
- return priv->hw_params.bcast_sta_id;
- }
-}
-
/*
* start REPLY_TX command process
*/
@@ -1011,7 +730,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* drop all data frame if we are not associated */
if (ieee80211_is_data(fc) &&
- (priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */
+ (!iwl_is_monitor_mode(priv)) && /* packet injection */
(!iwl_is_associated(priv) ||
((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
@@ -1023,7 +742,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find (or create) index into station table for destination station */
- sta_id = iwl3945_get_sta_id(priv, hdr);
+ sta_id = iwl_get_sta_id(priv, hdr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
@@ -1625,15 +1344,24 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
struct list_head *element;
struct iwl_rx_mem_buffer *rxb;
unsigned long flags;
- spin_lock_irqsave(&rxq->lock, flags);
- while (!list_empty(&rxq->rx_used)) {
+
+ while (1) {
+ spin_lock_irqsave(&rxq->lock, flags);
+
+ if (list_empty(&rxq->rx_used)) {
+ spin_unlock_irqrestore(&rxq->lock, flags);
+ return;
+ }
+
element = rxq->rx_used.next;
rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+ list_del(element);
+ spin_unlock_irqrestore(&rxq->lock, flags);
/* Alloc a new receive buffer */
rxb->skb =
alloc_skb(priv->hw_params.rx_buf_size,
- __GFP_NOWARN | GFP_ATOMIC);
+ GFP_KERNEL);
if (!rxb->skb) {
if (net_ratelimit())
IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
@@ -1651,18 +1379,18 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
*/
skb_reserve(rxb->skb, 4);
- priv->alloc_rxb_skb++;
- list_del(element);
-
/* Get physical address of RB/SKB */
rxb->real_dma_addr = pci_map_single(priv->pci_dev,
rxb->skb->data,
priv->hw_params.rx_buf_size,
PCI_DMA_FROMDEVICE);
+
+ spin_lock_irqsave(&rxq->lock, flags);
list_add_tail(&rxb->list, &rxq->rx_free);
+ priv->alloc_rxb_skb++;
rxq->free_count++;
+ spin_unlock_irqrestore(&rxq->lock, flags);
}
- spin_unlock_irqrestore(&rxq->lock, flags);
}
void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
@@ -1695,18 +1423,6 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
spin_unlock_irqrestore(&rxq->lock, flags);
}
-/*
- * this should be called while priv->lock is locked
- */
-static void __iwl3945_rx_replenish(void *data)
-{
- struct iwl_priv *priv = data;
-
- iwl3945_rx_allocate(priv);
- iwl3945_rx_queue_restock(priv);
-}
-
-
void iwl3945_rx_replenish(void *data)
{
struct iwl_priv *priv = data;
@@ -1744,7 +1460,6 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx
rxq->bd = NULL;
rxq->rb_stts = NULL;
}
-EXPORT_SYMBOL(iwl3945_rx_queue_free);
/* Convert linear signal-to-noise ratio into dB */
@@ -1887,6 +1602,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
"r = %d, i = %d, %s, 0x%02x\n", r, i,
get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+ priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
} else {
/* No handling needed */
IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
@@ -1924,7 +1640,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
count++;
if (count >= 8) {
priv->rxq.read = i;
- __iwl3945_rx_replenish(priv);
+ iwl3945_rx_queue_restock(priv);
count = 0;
}
}
@@ -2121,23 +1837,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
iwl_release_nic_access(priv);
}
-static void iwl3945_error_recovery(struct iwl_priv *priv)
-{
- unsigned long flags;
-
- memcpy(&priv->staging_rxon, &priv->recovery_rxon,
- sizeof(priv->staging_rxon));
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
-
- iwl3945_add_station(priv, priv->bssid, 1, 0);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
- priv->error_recovering = 0;
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
static void iwl3945_irq_tasklet(struct iwl_priv *priv)
{
u32 inta, handled = 0;
@@ -2186,6 +1885,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
/* Tell the device to stop sending interrupts */
iwl_disable_interrupts(priv);
+ priv->isr_stats.hw++;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_HW_ERR;
@@ -2198,13 +1898,17 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
#ifdef CONFIG_IWLWIFI_DEBUG
if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_SCD)
+ if (inta & CSR_INT_BIT_SCD) {
IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
"the frame/frames.\n");
+ priv->isr_stats.sch++;
+ }
/* Alive notification via Rx interrupt will do the real work */
- if (inta & CSR_INT_BIT_ALIVE)
+ if (inta & CSR_INT_BIT_ALIVE) {
IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+ priv->isr_stats.alive++;
+ }
}
#endif
/* Safely ignore these bits for debug checks below */
@@ -2214,6 +1918,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
if (inta & CSR_INT_BIT_SW_ERR) {
IWL_ERR(priv, "Microcode SW error detected. "
"Restarting 0x%X.\n", inta);
+ priv->isr_stats.sw++;
+ priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -2229,6 +1935,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
iwl_txq_update_write_ptr(priv, &priv->txq[4]);
iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+ priv->isr_stats.wakeup++;
handled |= CSR_INT_BIT_WAKEUP;
}
@@ -2237,11 +1944,13 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
* notifications from uCode come through here*/
if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
iwl3945_rx_handle(priv);
+ priv->isr_stats.rx++;
handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
}
if (inta & CSR_INT_BIT_FH_TX) {
IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+ priv->isr_stats.tx++;
iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
if (!iwl_grab_nic_access(priv)) {
@@ -2252,8 +1961,10 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
handled |= CSR_INT_BIT_FH_TX;
}
- if (inta & ~handled)
+ if (inta & ~handled) {
IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ priv->isr_stats.unhandled++;
+ }
if (inta & ~CSR_INI_SET_MASK) {
IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
@@ -2895,11 +2606,6 @@ static void iwl3945_init_alive_start(struct iwl_priv *priv)
queue_work(priv->workqueue, &priv->restart);
}
-
-/* temporary */
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
- struct sk_buff *skb);
-
/**
* iwl3945_alive_start - called after REPLY_ALIVE notification received
* from protocol/runtime uCode (initialization uCode's
@@ -2930,7 +2636,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
goto restart;
}
- iwl3945_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
rc = iwl_grab_nic_access(priv);
if (rc) {
@@ -2960,9 +2666,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
/* After the ALIVE response, we can send commands to 3945 uCode */
set_bit(STATUS_ALIVE, &priv->status);
- /* Clear out the uCode error bit if it is set */
- clear_bit(STATUS_FW_ERROR, &priv->status);
-
if (iwl_is_rfkill(priv))
return;
@@ -2989,7 +2692,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
iwl_send_bt_config(priv);
/* Configure the adapter for unassociated operation */
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
iwl3945_reg_txpower_periodic(priv);
@@ -2999,17 +2702,17 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
- if (priv->error_recovering)
- iwl3945_error_recovery(priv);
-
/* reassociate for ADHOC mode */
if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
priv->vif);
if (beacon)
- iwl3945_mac_beacon_update(priv->hw, beacon);
+ iwl_mac_beacon_update(priv->hw, beacon);
}
+ if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
+ iwl_set_mode(priv, priv->iw_mode);
+
return;
restart:
@@ -3032,7 +2735,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
set_bit(STATUS_EXIT_PENDING, &priv->status);
iwl3945_led_unregister(priv);
- iwl3945_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
@@ -3055,7 +2758,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
ieee80211_stop_queues(priv->hw);
/* If we have not previously called iwl3945_init() then
- * clear all bits but the RF Kill and SUSPEND bits and return */
+ * clear all bits but the RF Kill bits and return */
if (!iwl_is_init(priv)) {
priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
@@ -3063,23 +2766,19 @@ static void __iwl3945_down(struct iwl_priv *priv)
STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
goto exit;
}
- /* ...otherwise clear out all the status bits but the RF Kill and
- * SUSPEND bits and continue taking the NIC down. */
+ /* ...otherwise clear out all the status bits but the RF Kill
+ * bits and continue taking the NIC down. */
priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_FW_ERROR, &priv->status) <<
STATUS_FW_ERROR |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
@@ -3103,7 +2802,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
udelay(5);
- if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+ if (exit_pending)
priv->cfg->ops->lib->apm_ops.stop(priv);
else
priv->cfg->ops->lib->apm_ops.reset(priv);
@@ -3156,10 +2855,8 @@ static int __iwl3945_up(struct iwl_priv *priv)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
else {
set_bit(STATUS_RF_KILL_HW, &priv->status);
- if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
- IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
- return -ENODEV;
- }
+ IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
+ return -ENODEV;
}
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
@@ -3195,7 +2892,7 @@ static int __iwl3945_up(struct iwl_priv *priv)
for (i = 0; i < MAX_HW_RESTARTS; i++) {
- iwl3945_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
@@ -3291,9 +2988,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
int rc = 0;
struct iwl3945_scan_cmd *scan;
struct ieee80211_conf *conf = NULL;
- u8 n_probes = 2;
+ u8 n_probes = 0;
enum ieee80211_band band;
- DECLARE_SSID_BUF(ssid);
+ bool is_active = false;
conf = ieee80211_get_hw_conf(priv->hw);
@@ -3392,18 +3089,25 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan_suspend_time, interval);
}
- /* We should add the ability for user to lock to PASSIVE ONLY */
- if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN(priv, "Kicking off one direct scan for '%s'\n",
- print_ssid(ssid, priv->direct_ssid,
- priv->direct_ssid_len));
- scan->direct_scan[0].id = WLAN_EID_SSID;
- scan->direct_scan[0].len = priv->direct_ssid_len;
- memcpy(scan->direct_scan[0].ssid,
- priv->direct_ssid, priv->direct_ssid_len);
- n_probes++;
+ if (priv->scan_request->n_ssids) {
+ int i, p = 0;
+ IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
+ for (i = 0; i < priv->scan_request->n_ssids; i++) {
+ /* always does wildcard anyway */
+ if (!priv->scan_request->ssids[i].ssid_len)
+ continue;
+ scan->direct_scan[p].id = WLAN_EID_SSID;
+ scan->direct_scan[p].len =
+ priv->scan_request->ssids[i].ssid_len;
+ memcpy(scan->direct_scan[p].ssid,
+ priv->scan_request->ssids[i].ssid,
+ priv->scan_request->ssids[i].ssid_len);
+ n_probes++;
+ p++;
+ }
+ is_active = true;
} else
- IWL_DEBUG_SCAN(priv, "Kicking off one indirect scan.\n");
+ IWL_DEBUG_SCAN(priv, "Kicking off passive scan.\n");
/* We don't build a direct scan probe request; the uCode will do
* that based on the direct_mask added to each channel entry */
@@ -3420,7 +3124,12 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
band = IEEE80211_BAND_2GHZ;
} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
- scan->good_CRC_th = IWL_GOOD_CRC_TH;
+ /*
+ * If active scaning is requested but a certain channel
+ * is marked passive, we can do active scanning if we
+ * detect transmissions.
+ */
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
band = IEEE80211_BAND_5GHZ;
} else {
IWL_WARN(priv, "Invalid scan band count\n");
@@ -3428,19 +3137,20 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
}
scan->tx_cmd.len = cpu_to_le16(
- iwl_fill_probe_req(priv, band,
- (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan)));
+ iwl_fill_probe_req(priv,
+ (struct ieee80211_mgmt *)scan->data,
+ priv->scan_request->ie,
+ priv->scan_request->ie_len,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan)));
/* select Rx antennas */
scan->flags |= iwl3945_get_antenna_flags(priv);
- if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
+ if (iwl_is_monitor_mode(priv))
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
scan->channel_count =
- iwl3945_get_channels_for_scan(priv, band, 1, /* active */
- n_probes,
+ iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
if (scan->channel_count == 0) {
@@ -3498,8 +3208,17 @@ static void iwl3945_bg_restart(struct work_struct *data)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- iwl3945_down(priv);
- queue_work(priv->workqueue, &priv->up);
+ if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+ mutex_lock(&priv->mutex);
+ priv->vif = NULL;
+ priv->is_open = 0;
+ mutex_unlock(&priv->mutex);
+ iwl3945_down(priv);
+ ieee80211_restart_hw(priv->hw);
+ } else {
+ iwl3945_down(priv);
+ queue_work(priv->workqueue, &priv->up);
+ }
}
static void iwl3945_bg_rx_replenish(struct work_struct *data)
@@ -3517,7 +3236,7 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static void iwl3945_post_associate(struct iwl_priv *priv)
+void iwl3945_post_associate(struct iwl_priv *priv)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
@@ -3542,7 +3261,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
conf = ieee80211_get_hw_conf(priv->hw);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
iwl3945_setup_rxon_timing(priv);
@@ -3575,7 +3294,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
}
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
switch (priv->iw_mode) {
case NL80211_IFTYPE_STATION:
@@ -3585,7 +3304,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
case NL80211_IFTYPE_ADHOC:
priv->assoc_id = 1;
- iwl3945_add_station(priv, priv->bssid, 0, 0);
+ priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 0, 0, NULL);
iwl3945_sync_sta(priv, IWL_STA_ID,
(priv->band == IEEE80211_BAND_5GHZ) ?
IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
@@ -3607,8 +3326,6 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}
-static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
-
/*****************************************************************************
*
* mac80211 entry point functions
@@ -3651,9 +3368,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
IWL_DEBUG_INFO(priv, "Start UP work.\n");
- if (test_bit(STATUS_IN_SUSPEND, &priv->status))
- return 0;
-
/* Wait for START_ALIVE from ucode. Otherwise callbacks from
* mac80211 will not be run successfully. */
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -3732,144 +3446,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
-static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
-
- if (priv->vif) {
- IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
- return -EOPNOTSUPP;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->vif = conf->vif;
- priv->iw_mode = conf->type;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
-
- if (conf->mac_addr) {
- IWL_DEBUG_MAC80211(priv, "Set: %pM\n", conf->mac_addr);
- memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
- }
-
- if (iwl_is_ready(priv))
- iwl3945_set_mode(priv, conf->type);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
-/**
- * iwl3945_mac_config - mac80211 config callback
- *
- * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
- * be set inappropriately and the driver currently sets the hardware up to
- * use it whenever needed.
- */
-static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct iwl_priv *priv = hw->priv;
- const struct iwl_channel_info *ch_info;
- struct ieee80211_conf *conf = &hw->conf;
- unsigned long flags;
- int ret = 0;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter to channel %d\n",
- conf->channel->hw_value);
-
- if (!iwl_is_ready(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- ret = -EIO;
- goto out;
- }
-
- if (unlikely(!iwl3945_mod_params.disable_hw_scan &&
- test_bit(STATUS_SCANNING, &priv->status))) {
- IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
- set_bit(STATUS_CONF_PENDING, &priv->status);
- mutex_unlock(&priv->mutex);
- return 0;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- ch_info = iwl_get_channel_info(priv, conf->channel->band,
- conf->channel->hw_value);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN(priv,
- "Channel %d [%d] is INVALID for this band.\n",
- conf->channel->hw_value, conf->channel->band);
- IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
- spin_unlock_irqrestore(&priv->lock, flags);
- ret = -EINVAL;
- goto out;
- }
-
- iwl_set_rxon_channel(priv, conf->channel);
-
- iwl_set_flags_for_band(priv, conf->channel->band);
-
- /* The list of supported rates and rate mask can be different
- * for each phymode; since the phymode may have changed, reset
- * the rate mask to what mac80211 lists */
- iwl_set_rate(priv);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
-#ifdef IEEE80211_CONF_CHANNEL_SWITCH
- if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
- iwl3945_hw_channel_switch(priv, conf->channel);
- goto out;
- }
-#endif
-
- if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
- if (conf->radio_enabled &&
- iwl_radio_kill_sw_enable_radio(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
- "waiting for uCode\n");
- goto out;
- }
-
- if (!conf->radio_enabled) {
- iwl_radio_kill_sw_disable_radio(priv);
- IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
- goto out;
- }
- }
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF kill\n");
- ret = -EIO;
- goto out;
- }
-
- iwl_set_rate(priv);
-
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
- iwl3945_commit_rxon(priv);
- else
- IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n");
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-out:
- clear_bit(STATUS_CONF_PENDING, &priv->status);
- mutex_unlock(&priv->mutex);
- return ret;
-}
-
-static void iwl3945_config_ap(struct iwl_priv *priv)
+void iwl3945_config_ap(struct iwl_priv *priv)
{
int rc = 0;
@@ -3881,7 +3458,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
/* RXON Timing */
memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
@@ -3917,8 +3494,8 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
}
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- iwl3945_add_station(priv, iwl_bcast_addr, 0, 0);
+ iwlcore_commit_rxon(priv);
+ priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL);
}
iwl3945_send_beacon_cmd(priv);
@@ -3927,189 +3504,6 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
* clear sta table, add BCAST sta... */
}
-static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- int rc;
-
- if (conf == NULL)
- return -EIO;
-
- if (priv->vif != vif) {
- IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
- return 0;
- }
-
- /* handle this temporarily here */
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- conf->changed & IEEE80211_IFCC_BEACON) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
- if (!beacon)
- return -ENOMEM;
- mutex_lock(&priv->mutex);
- rc = iwl3945_mac_beacon_update(hw, beacon);
- mutex_unlock(&priv->mutex);
- if (rc)
- return rc;
- }
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- mutex_lock(&priv->mutex);
-
- if (conf->bssid)
- IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
-
-/*
- * very dubious code was here; the probe filtering flag is never set:
- *
- if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
- !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
- */
-
- if (priv->iw_mode == NL80211_IFTYPE_AP) {
- if (!conf->bssid) {
- conf->bssid = priv->mac_addr;
- memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
- IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
- conf->bssid);
- }
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
- }
-
- if (iwl_is_rfkill(priv))
- goto done;
-
- if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
- !is_multicast_ether_addr(conf->bssid)) {
- /* If there is currently a HW scan going on in the background
- * then we need to cancel it else the RXON below will fail. */
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress "
- "after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving:scan abort failed\n");
- mutex_unlock(&priv->mutex);
- return -EAGAIN;
- }
- memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);
-
- /* TODO: Audit driver for usage of these members and see
- * if mac80211 deprecates them (priv->bssid looks like it
- * shouldn't be there, but I haven't scanned the IBSS code
- * to verify) - jpk */
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl3945_config_ap(priv);
- else {
- rc = iwl3945_commit_rxon(priv);
- if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
- iwl3945_add_station(priv,
- priv->active_rxon.bssid_addr, 1, 0);
- }
-
- } else {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- }
-
- done:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
-
- return 0;
-}
-
-static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- mutex_lock(&priv->mutex);
-
- if (iwl_is_ready_rf(priv)) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- }
- if (priv->vif == conf->vif) {
- priv->vif = NULL;
- memset(priv->bssid, 0, ETH_ALEN);
- }
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
-#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-
-static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
-
- if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
- bss_conf->use_short_preamble);
- if (bss_conf->use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- priv->staging_rxon.flags &=
- ~RXON_FLG_SHORT_PREAMBLE_MSK;
- }
-
- if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n",
- bss_conf->use_cts_prot);
- if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
- priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
- }
-
- if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
- /* This should never happen as this function should
- * never be called from interrupt context. */
- if (WARN_ON_ONCE(in_interrupt()))
- return;
- if (bss_conf->assoc) {
- priv->assoc_id = bss_conf->aid;
- priv->beacon_int = bss_conf->beacon_int;
- priv->timestamp = bss_conf->timestamp;
- priv->assoc_capability = bss_conf->assoc_capability;
- priv->power_data.dtim_period = bss_conf->dtim_period;
- priv->next_scan_jiffies = jiffies +
- IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
- mutex_lock(&priv->mutex);
- iwl3945_post_associate(priv);
- mutex_unlock(&priv->mutex);
- } else {
- priv->assoc_id = 0;
- IWL_DEBUG_MAC80211(priv,
- "DISASSOC %d\n", bss_conf->assoc);
- }
- } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
- IWL_DEBUG_MAC80211(priv,
- "Associated Changes %d\n", changes);
- iwl3945_send_rxon_assoc(priv);
- }
-
-}
-
static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -4132,7 +3526,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
static_key = !iwl_is_associated(priv);
if (!static_key) {
- sta_id = iwl3945_hw_find_station(priv, addr);
+ sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
@@ -4168,185 +3562,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
- const struct ieee80211_tx_queue_params *params)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- int q;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (queue >= AC_NUM) {
- IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
- return 0;
- }
-
- q = AC_NUM - 1 - queue;
-
- spin_lock_irqsave(&priv->lock, flags);
-
- priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
- priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
- priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
- priv->qos_data.def_qos_parm.ac[q].edca_txop =
- cpu_to_le16((params->txop * 32));
-
- priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
- priv->qos_data.qos_active = 1;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl_activate_qos(priv, 1);
- else if (priv->assoc_id && iwl_is_associated(priv))
- iwl_activate_qos(priv, 0);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
-static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
- struct ieee80211_tx_queue_stats *stats)
-{
- struct iwl_priv *priv = hw->priv;
- int i, avail;
- struct iwl_tx_queue *txq;
- struct iwl_queue *q;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- for (i = 0; i < AC_NUM; i++) {
- txq = &priv->txq[i];
- q = &txq->q;
- avail = iwl_queue_space(q);
-
- stats[i].len = q->n_window - avail;
- stats[i].limit = q->n_window - q->high_mark;
- stats[i].count = q->n_window;
-
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
- return 0;
-}
-
-static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- iwl_reset_qos(priv);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = 0;
- priv->assoc_capability = 0;
-
- /* new association get rid of ibss beacon skb */
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = NULL;
-
- priv->beacon_int = priv->hw->conf.beacon_int;
- priv->timestamp = 0;
- if ((priv->iw_mode == NL80211_IFTYPE_STATION))
- priv->beacon_int = 0;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- /* we are restarting association process
- * clear RXON_FILTER_ASSOC_MSK bit
- */
- if (priv->iw_mode != NL80211_IFTYPE_AP) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- }
-
- /* Per mac80211.h: This is only used in IBSS mode... */
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-
- IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- iwl_set_rate(priv);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-}
-
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- __le64 timestamp;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = skb;
-
- priv->assoc_id = 0;
- timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
- priv->timestamp = le64_to_cpu(timestamp);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_reset_qos(priv);
-
- iwl3945_post_associate(priv);
-
-
- return 0;
-}
-
/*****************************************************************************
*
* sysfs attributes
@@ -4365,7 +3580,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
static ssize_t show_debug_level(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%08X\n", priv->debug_level);
}
@@ -4373,7 +3588,7 @@ static ssize_t store_debug_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
int ret;
@@ -4394,7 +3609,7 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (!iwl_is_alive(priv))
return -EAGAIN;
@@ -4407,7 +3622,7 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
}
@@ -4415,7 +3630,7 @@ static ssize_t store_tx_power(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
char *p = (char *)buf;
u32 val;
@@ -4433,7 +3648,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
static ssize_t show_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
}
@@ -4442,7 +3657,7 @@ static ssize_t store_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
u32 flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
@@ -4454,7 +3669,7 @@ static ssize_t store_flags(struct device *d,
IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -4467,7 +3682,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
static ssize_t show_filter_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%04X\n",
le32_to_cpu(priv->active_rxon.filter_flags));
@@ -4477,7 +3692,7 @@ static ssize_t store_filter_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
u32 filter_flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
@@ -4490,7 +3705,7 @@ static ssize_t store_filter_flags(struct device *d,
"0x%04X\n", filter_flags);
priv->staging_rxon.filter_flags =
cpu_to_le32(filter_flags);
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -4630,26 +3845,11 @@ static ssize_t show_power_level(struct device *d,
{
struct iwl_priv *priv = dev_get_drvdata(d);
int mode = priv->power_data.user_power_setting;
- int system = priv->power_data.system_power_setting;
int level = priv->power_data.power_mode;
char *p = buf;
- switch (system) {
- case IWL_POWER_SYS_AUTO:
- p += sprintf(p, "SYSTEM:auto");
- break;
- case IWL_POWER_SYS_AC:
- p += sprintf(p, "SYSTEM:ac");
- break;
- case IWL_POWER_SYS_BATTERY:
- p += sprintf(p, "SYSTEM:battery");
- break;
- }
-
- p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
- "fixed" : "auto");
- p += sprintf(p, "\tINDEX:%d", level);
- p += sprintf(p, "\n");
+ p += sprintf(p, "INDEX:%d\t", level);
+ p += sprintf(p, "USER:%d\n", mode);
return p - buf + 1;
}
@@ -4762,7 +3962,7 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna);
static ssize_t show_status(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "0x%08x\n", (int)priv->status);
@@ -4774,10 +3974,11 @@ static ssize_t dump_error_log(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct iwl_priv *priv = dev_get_drvdata(d);
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_error_log((struct iwl_priv *)d->driver_data);
+ iwl3945_dump_nic_error_log(priv);
return strnlen(buf, count);
}
@@ -4788,10 +3989,11 @@ static ssize_t dump_event_log(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct iwl_priv *priv = dev_get_drvdata(d);
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_event_log((struct iwl_priv *)d->driver_data);
+ iwl3945_dump_nic_event_log(priv);
return strnlen(buf, count);
}
@@ -4870,16 +4072,15 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.tx = iwl3945_mac_tx,
.start = iwl3945_mac_start,
.stop = iwl3945_mac_stop,
- .add_interface = iwl3945_mac_add_interface,
- .remove_interface = iwl3945_mac_remove_interface,
- .config = iwl3945_mac_config,
- .config_interface = iwl3945_mac_config_interface,
+ .add_interface = iwl_mac_add_interface,
+ .remove_interface = iwl_mac_remove_interface,
+ .config = iwl_mac_config,
.configure_filter = iwl_configure_filter,
.set_key = iwl3945_mac_set_key,
- .get_tx_stats = iwl3945_mac_get_tx_stats,
- .conf_tx = iwl3945_mac_conf_tx,
- .reset_tsf = iwl3945_mac_reset_tsf,
- .bss_info_changed = iwl3945_bss_info_changed,
+ .get_tx_stats = iwl_mac_get_tx_stats,
+ .conf_tx = iwl_mac_conf_tx,
+ .reset_tsf = iwl_mac_reset_tsf,
+ .bss_info_changed = iwl_bss_info_changed,
.hw_scan = iwl_mac_hw_scan
};
@@ -4892,7 +4093,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
priv->ibss_beacon = NULL;
spin_lock_init(&priv->lock);
- spin_lock_init(&priv->power_data.lock);
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
@@ -4901,7 +4101,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
mutex_init(&priv->mutex);
/* Clear the driver's (not device's) station table */
- iwl3945_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
priv->data_retry_limit = -1;
priv->ieee_channels = NULL;
@@ -4972,13 +4172,13 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
hw->wiphy->custom_regulatory = true;
- hw->wiphy->max_scan_ssids = 1; /* WILL FIX */
+ hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
+ /* we create the 802.11 header and a zero-length SSID element */
+ hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
- hw->conf.beacon_int = 100;
-
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&priv->bands[IEEE80211_BAND_2GHZ];
@@ -5134,20 +4334,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n",
priv->cfg->name);
- /***********************************
- * 7. Initialize Module Parameters
- * **********************************/
-
- /* Initialize module parameter values here */
- /* Disable radio (SW RF KILL) via parameter when loading driver */
- if (iwl3945_mod_params.disable) {
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- IWL_DEBUG_INFO(priv, "Radio disabled.\n");
- }
-
-
/***********************
- * 8. Setup Services
+ * 7. Setup Services
* ********************/
spin_lock_irqsave(&priv->lock, flags);
@@ -5175,7 +4363,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
iwl3945_setup_rx_handlers(priv);
/*********************************
- * 9. Setup and Register mac80211
+ * 8. Setup and Register mac80211
* *******************************/
iwl_enable_interrupts(priv);
@@ -5184,6 +4372,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if (err)
goto out_remove_sysfs;
+ err = iwl_dbgfs_register(priv, DRV_NAME);
+ if (err)
+ IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
+
err = iwl_rfkill_init(priv);
if (err)
IWL_ERR(priv, "Unable to initialize RFKILL system. "
@@ -5234,6 +4426,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
+ iwl_dbgfs_unregister(priv);
+
set_bit(STATUS_EXIT_PENDING, &priv->status);
if (priv->mac80211_registered) {
@@ -5264,7 +4458,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
iwl3945_hw_txq_ctx_free(priv);
iwl3945_unset_hw_params(priv);
- iwl3945_clear_stations_table(priv);
+ priv->cfg->ops->smgmt->clear_station_table(priv);
/*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue);
@@ -5292,43 +4486,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
ieee80211_free_hw(priv->hw);
}
-#ifdef CONFIG_PM
-
-static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
-
- if (priv->is_open) {
- set_bit(STATUS_IN_SUSPEND, &priv->status);
- iwl3945_mac_stop(priv->hw);
- priv->is_open = 1;
- }
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- return 0;
-}
-
-static int iwl3945_pci_resume(struct pci_dev *pdev)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
- int ret;
-
- pci_set_power_state(pdev, PCI_D0);
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
- pci_restore_state(pdev);
-
- if (priv->is_open)
- iwl3945_mac_start(priv->hw);
-
- clear_bit(STATUS_IN_SUSPEND, &priv->status);
- return 0;
-}
-
-#endif /* CONFIG_PM */
/*****************************************************************************
*
@@ -5342,8 +4499,8 @@ static struct pci_driver iwl3945_driver = {
.probe = iwl3945_pci_probe,
.remove = __devexit_p(iwl3945_pci_remove),
#ifdef CONFIG_PM
- .suspend = iwl3945_pci_suspend,
- .resume = iwl3945_pci_resume,
+ .suspend = iwl_pci_suspend,
+ .resume = iwl_pci_resume,
#endif
};
@@ -5384,8 +4541,6 @@ MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444);
MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl3945_mod_params.disable, int, 0444);
-MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
MODULE_PARM_DESC(swcrypto,
"using software crypto (default 1 [software])\n");
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 8c3605cdc64c..c455b9abbfc0 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -119,6 +119,19 @@ int lbs_update_hw_spec(struct lbs_private *priv)
lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
cmd.hwifversion, cmd.version);
+ /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
+ /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
+ /* 5.110.22 have mesh command with 0xa3 command id */
+ /* 10.0.0.p0 FW brings in mesh config command with different id */
+ /* Check FW version MSB and initialize mesh_fw_ver */
+ if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
+ priv->mesh_fw_ver = MESH_FW_OLD;
+ else if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
+ (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK))
+ priv->mesh_fw_ver = MESH_FW_NEW;
+ else
+ priv->mesh_fw_ver = MESH_NONE;
+
/* Clamp region code to 8-bit since FW spec indicates that it should
* only ever be 8-bit, even though the field size is 16-bit. Some firmware
* returns non-zero high 8 bits here.
@@ -1036,17 +1049,26 @@ static int __lbs_mesh_config_send(struct lbs_private *priv,
uint16_t action, uint16_t type)
{
int ret;
+ u16 command = CMD_MESH_CONFIG_OLD;
lbs_deb_enter(LBS_DEB_CMD);
- cmd->hdr.command = cpu_to_le16(CMD_MESH_CONFIG);
+ /*
+ * Command id is 0xac for v10 FW along with mesh interface
+ * id in bits 14-13-12.
+ */
+ if (priv->mesh_fw_ver == MESH_FW_NEW)
+ command = CMD_MESH_CONFIG |
+ (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
+
+ cmd->hdr.command = cpu_to_le16(command);
cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
cmd->hdr.result = 0;
cmd->type = cpu_to_le16(type);
cmd->action = cpu_to_le16(action);
- ret = lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);
+ ret = lbs_cmd_with_response(priv, command, cmd);
lbs_deb_leave(LBS_DEB_CMD);
return ret;
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index e8dfde39abfc..48da157d6cda 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -227,6 +227,20 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
#define TxPD_CONTROL_WDS_FRAME (1<<17)
#define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME
+/** Mesh interface ID */
+#define MESH_IFACE_ID 0x0001
+/** Mesh id should be in bits 14-13-12 */
+#define MESH_IFACE_BIT_OFFSET 0x000c
+/** Mesh enable bit in FW capability */
+#define MESH_CAPINFO_ENABLE_MASK (1<<16)
+
+/** FW definition from Marvell v5 */
+#define MRVL_FW_V5 (0x05)
+/** FW definition from Marvell v10 */
+#define MRVL_FW_V10 (0x0a)
+/** FW major revision definition */
+#define MRVL_FW_MAJOR_REV(x) ((x)>>24)
+
/** RxPD status */
#define MRVDRV_RXPD_STATUS_OK 0x0001
@@ -380,6 +394,13 @@ enum KEY_INFO_WPA {
KEY_INFO_WPA_ENABLED = 0x04
};
+/** mesh_fw_ver */
+enum _mesh_fw_ver {
+ MESH_NONE = 0, /* MESH is not supported */
+ MESH_FW_OLD, /* MESH is supported in FW V5 */
+ MESH_FW_NEW, /* MESH is supported in FW V10 and newer */
+};
+
/* Default values for fwt commands. */
#define FWT_DEFAULT_METRIC 0
#define FWT_DEFAULT_DIR 1
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 27e81fd97c94..cbaafa653b6a 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -101,6 +101,7 @@ struct lbs_mesh_stats {
/** Private structure for the MV device */
struct lbs_private {
int mesh_open;
+ int mesh_fw_ver;
int infra_open;
int mesh_autostart_enabled;
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index d4457ef808a6..8ff8ac9d817e 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -83,7 +83,8 @@
#define CMD_FWT_ACCESS 0x0095
#define CMD_802_11_MONITOR_MODE 0x0098
#define CMD_MESH_ACCESS 0x009b
-#define CMD_MESH_CONFIG 0x00a3
+#define CMD_MESH_CONFIG_OLD 0x00a3
+#define CMD_MESH_CONFIG 0x00ac
#define CMD_SET_BOOT2_VER 0x00a5
#define CMD_802_11_BEACON_CTRL 0x00b0
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index a899aeb676bb..391c54ab2b09 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -13,8 +13,19 @@
/* TxPD descriptor */
struct txpd {
- /* Current Tx packet status */
- __le32 tx_status;
+ /* union to cope up with later FW revisions */
+ union {
+ /* Current Tx packet status */
+ __le32 tx_status;
+ struct {
+ /* BSS type: client, AP, etc. */
+ u8 bss_type;
+ /* BSS number */
+ u8 bss_num;
+ /* Reserved */
+ __le16 reserved;
+ } bss;
+ } u;
/* Tx control */
__le32 tx_control;
__le32 tx_packet_location;
@@ -36,8 +47,17 @@ struct txpd {
/* RxPD Descriptor */
struct rxpd {
- /* Current Rx packet status */
- __le16 status;
+ /* union to cope up with later FW revisions */
+ union {
+ /* Current Rx packet status */
+ __le16 status;
+ struct {
+ /* BSS type: client, AP, etc. */
+ u8 bss_type;
+ /* BSS number */
+ u8 bss_num;
+ } bss;
+ } u;
/* SNR */
u8 snr;
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index cedeac6322fe..2a5b083bf9bd 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -273,7 +273,28 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
*/
#define IF_CS_PRODUCT_ID 0x0000001C
#define IF_CS_CF8385_B1_REV 0x12
+#define IF_CS_CF8381_B3_REV 0x04
+/*
+ * Used to detect other cards than CF8385 since their revisions of silicon
+ * doesn't match those from CF8385, eg. CF8381 B3 works with this driver.
+ */
+#define CF8381_MANFID 0x02db
+#define CF8381_CARDID 0x6064
+#define CF8385_MANFID 0x02df
+#define CF8385_CARDID 0x8103
+
+static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev)
+{
+ return (p_dev->manf_id == CF8381_MANFID &&
+ p_dev->card_id == CF8381_CARDID);
+}
+
+static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev)
+{
+ return (p_dev->manf_id == CF8385_MANFID &&
+ p_dev->card_id == CF8385_CARDID);
+}
/********************************************************************/
/* I/O and interrupt handling */
@@ -757,6 +778,7 @@ static void if_cs_release(struct pcmcia_device *p_dev)
static int if_cs_probe(struct pcmcia_device *p_dev)
{
int ret = -ENOMEM;
+ unsigned int prod_id;
struct lbs_private *priv;
struct if_cs_card *card;
/* CIS parsing */
@@ -859,7 +881,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
/* Check if we have a current silicon */
- if (if_cs_read8(card, IF_CS_PRODUCT_ID) < IF_CS_CF8385_B1_REV) {
+ prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
+ if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) {
+ lbs_pr_err("old chips like 8381 rev B3 aren't supported\n");
+ ret = -ENODEV;
+ goto out2;
+ }
+
+ if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) {
lbs_pr_err("old chips like 8385 rev B1 aren't supported\n");
ret = -ENODEV;
goto out2;
@@ -950,7 +979,8 @@ static void if_cs_detach(struct pcmcia_device *p_dev)
/********************************************************************/
static struct pcmcia_device_id if_cs_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x02df, 0x8103),
+ PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
+ PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 76f4c653d641..55864c10f9f1 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -48,8 +48,11 @@ static char *lbs_fw_name = NULL;
module_param_named(fw_name, lbs_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 */ },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
+ SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
+ SDIO_DEVICE_ID_MARVELL_8688WLAN) },
+ { /* end: all zeroes */ },
};
MODULE_DEVICE_TABLE(sdio, if_sdio_ids);
@@ -73,6 +76,12 @@ static struct if_sdio_model if_sdio_models[] = {
.helper = "sd8686_helper.bin",
.firmware = "sd8686.bin",
},
+ {
+ /* 8688 */
+ .model = 0x10,
+ .helper = "sd8688_helper.bin",
+ .firmware = "sd8688.bin",
+ },
};
struct if_sdio_packet {
@@ -488,7 +497,7 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
ret = 0;
release:
- sdio_set_block_size(card->func, 0);
+ sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
sdio_release_host(card->func);
kfree(chunk_buffer);
release_fw:
@@ -624,7 +633,7 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
ret = 0;
release:
- sdio_set_block_size(card->func, 0);
+ sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
sdio_release_host(card->func);
kfree(chunk_buffer);
release_fw:
diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h
index 533bdfbf5d2a..37ada2c29aa9 100644
--- a/drivers/net/wireless/libertas/if_sdio.h
+++ b/drivers/net/wireless/libertas/if_sdio.h
@@ -42,4 +42,6 @@
#define IF_SDIO_EVENT 0x80fc
+#define IF_SDIO_BLOCK_SIZE 256
+
#endif
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 07311e71af92..dccd01fd1f10 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -731,7 +731,7 @@ static int if_spi_c2h_data(struct if_spi_card *card)
goto out;
} else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
lbs_pr_err("%s: error: card has %d bytes of data, but "
- "our maximum skb size is %u\n",
+ "our maximum skb size is %lu\n",
__func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
err = -EINVAL;
goto out;
@@ -1020,6 +1020,7 @@ static int __devinit if_spi_probe(struct spi_device *spi)
struct libertas_spi_platform_data *pdata = spi->dev.platform_data;
int err = 0;
u32 scratch;
+ struct sched_param param = { .sched_priority = 1 };
lbs_deb_enter(LBS_DEB_SPI);
@@ -1123,6 +1124,9 @@ static int __devinit if_spi_probe(struct spi_device *spi)
lbs_pr_err("error creating SPI thread: err=%d\n", err);
goto remove_card;
}
+ if (sched_setscheduler(card->spi_thread, SCHED_FIFO, &param))
+ lbs_pr_err("Error setting scheduler, using default.\n");
+
err = request_irq(spi->irq, if_spi_host_interrupt,
IRQF_TRIGGER_FALLING, "libertas_spi", card);
if (err) {
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index ea3dc038be76..d649caebf08a 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -686,8 +686,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
return;
}
- if (!in_interrupt())
- BUG();
+ BUG_ON(!in_interrupt());
spin_lock(&priv->driver_lock);
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 8ae935ac32f1..89575e448015 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1307,8 +1307,10 @@ int lbs_start_card(struct lbs_private *priv)
lbs_update_channel(priv);
- /* 5.0.16p0 is known to NOT support any mesh */
- if (priv->fwrelease > 0x05001000) {
+ /* Check mesh FW version and appropriately send the mesh start
+ * command
+ */
+ if (priv->mesh_fw_ver == MESH_FW_OLD) {
/* Enable mesh, if supported, and work out which TLV it uses.
0x100 + 291 is an unofficial value used in 5.110.20.pXX
0x100 + 37 is the official value used in 5.110.21.pXX
@@ -1322,27 +1324,35 @@ int lbs_start_card(struct lbs_private *priv)
It's just that 5.110.20.pXX will not have done anything
useful */
- priv->mesh_tlv = 0x100 + 291;
+ priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
priv->curbssparams.channel)) {
- priv->mesh_tlv = 0x100 + 37;
+ priv->mesh_tlv = TLV_TYPE_MESH_ID;
if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
priv->curbssparams.channel))
priv->mesh_tlv = 0;
}
- if (priv->mesh_tlv) {
- lbs_add_mesh(priv);
-
- if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
- lbs_pr_err("cannot register lbs_mesh attribute\n");
-
- /* While rtap isn't related to mesh, only mesh-enabled
- * firmware implements the rtap functionality via
- * CMD_802_11_MONITOR_MODE.
- */
- if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
- lbs_pr_err("cannot register lbs_rtap attribute\n");
- }
+ } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+ /* 10.0.0.pXX new firmwares should succeed with TLV
+ * 0x100+37; Do not invoke command with old TLV.
+ */
+ priv->mesh_tlv = TLV_TYPE_MESH_ID;
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->curbssparams.channel))
+ priv->mesh_tlv = 0;
+ }
+ if (priv->mesh_tlv) {
+ lbs_add_mesh(priv);
+
+ if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
+ lbs_pr_err("cannot register lbs_mesh attribute\n");
+
+ /* While rtap isn't related to mesh, only mesh-enabled
+ * firmware implements the rtap functionality via
+ * CMD_802_11_MONITOR_MODE.
+ */
+ if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
+ lbs_pr_err("cannot register lbs_rtap attribute\n");
}
lbs_debugfs_init_one(priv, dev);
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 8e669775cb5d..65f02cc6752f 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -25,7 +25,6 @@ struct rfc1042hdr {
} __attribute__ ((packed));
struct rxpackethdr {
- struct rxpd rx_pd;
struct eth803hdr eth803_hdr;
struct rfc1042hdr rfc1042_hdr;
} __attribute__ ((packed));
@@ -158,10 +157,18 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
if (priv->monitormode)
return process_rxed_802_11_packet(priv, skb);
- p_rx_pkt = (struct rxpackethdr *) skb->data;
- p_rx_pd = &p_rx_pkt->rx_pd;
- if (priv->mesh_dev && (p_rx_pd->rx_control & RxPD_MESH_FRAME))
- dev = priv->mesh_dev;
+ p_rx_pd = (struct rxpd *) skb->data;
+ p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd +
+ le32_to_cpu(p_rx_pd->pkt_ptr));
+ if (priv->mesh_dev) {
+ if (priv->mesh_fw_ver == MESH_FW_OLD) {
+ if (p_rx_pd->rx_control & RxPD_MESH_FRAME)
+ dev = priv->mesh_dev;
+ } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+ if (p_rx_pd->u.bss.bss_num == MESH_IFACE_ID)
+ dev = priv->mesh_dev;
+ }
+ }
lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
min_t(unsigned int, skb->len, 100));
@@ -174,20 +181,9 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
goto done;
}
- /*
- * Check rxpd status and update 802.3 stat,
- */
- if (!(p_rx_pd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
- lbs_deb_rx("rx err: frame received with bad status\n");
- lbs_pr_alert("rxpd not ok\n");
- dev->stats.rx_errors++;
- ret = 0;
- dev_kfree_skb(skb);
- goto done;
- }
-
- lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
- skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
+ lbs_deb_rx("rx data: skb->len - pkt_ptr = %d-%zd = %zd\n",
+ skb->len, (size_t)le32_to_cpu(p_rx_pd->pkt_ptr),
+ skb->len - (size_t)le32_to_cpu(p_rx_pd->pkt_ptr));
lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
sizeof(p_rx_pkt->eth803_hdr.dest_addr));
@@ -221,14 +217,14 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
/* Chop off the rxpd + the excess memory from the 802.2/llc/snap header
* that was removed
*/
- hdrchop = (u8 *) p_ethhdr - (u8 *) p_rx_pkt;
+ hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd;
} else {
lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP",
(u8 *) & p_rx_pkt->rfc1042_hdr,
sizeof(p_rx_pkt->rfc1042_hdr));
/* Chop off the rxpd */
- hdrchop = (u8 *) & p_rx_pkt->eth803_hdr - (u8 *) p_rx_pkt;
+ hdrchop = (u8 *)&p_rx_pkt->eth803_hdr - (u8 *)p_rx_pd;
}
/* Chop off the leading header bytes so the skb points to the start of
@@ -334,14 +330,6 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
goto done;
}
- /*
- * Check rxpd status and update 802.3 stat,
- */
- if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
- //lbs_deb_rx("rx err: frame received with bad status\n");
- dev->stats.rx_errors++;
- }
-
lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
@@ -353,8 +341,6 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
radiotap_hdr.hdr.it_pad = 0;
radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
- if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
- radiotap_hdr.flags |= IEEE80211_RADIOTAP_F_BADFCS;
radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
/* XXX must check no carryout */
radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index f10aa39a6b68..160cfd8311c0 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -132,8 +132,12 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
txpd->tx_packet_length = cpu_to_le16(pkt_len);
txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
- if (dev == priv->mesh_dev)
- txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
+ if (dev == priv->mesh_dev) {
+ if (priv->mesh_fw_ver == MESH_FW_OLD)
+ txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
+ else if (priv->mesh_fw_ver == MESH_FW_NEW)
+ txpd->u.bss.bss_num = MESH_IFACE_ID;
+ }
lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd));
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index fb7a2d1a2525..de03b9c9c204 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -94,6 +94,8 @@ struct ieeetypes_assocrsp {
#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23)
+#define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37)
+#define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291)
/** TLV related data structures*/
struct mrvlietypesheader {
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index 59634c33b1f9..392337b37b1d 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -461,8 +461,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
return;
}
- if (!in_interrupt())
- BUG();
+ BUG_ON(!in_interrupt());
spin_lock(&priv->driver_lock);
memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN,
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index e7289e2e7f16..10a99e26d392 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -366,36 +366,6 @@ static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
return 0;
}
-static int lbtf_op_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct lbtf_private *priv = hw->priv;
- struct sk_buff *beacon;
-
- switch (priv->vif->type) {
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_MESH_POINT:
- beacon = ieee80211_beacon_get(hw, vif);
- if (beacon) {
- lbtf_beacon_set(priv, beacon);
- kfree_skb(beacon);
- lbtf_beacon_ctrl(priv, 1, hw->conf.beacon_int);
- }
- break;
- default:
- break;
- }
-
- if (conf->bssid) {
- u8 null_bssid[ETH_ALEN] = {0};
- bool activate = compare_ether_addr(conf->bssid, null_bssid);
- lbtf_set_bssid(priv, activate, conf->bssid);
- }
-
- return 0;
-}
-
#define SUPPORTED_FIF_FLAGS (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)
static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
@@ -451,6 +421,29 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
u32 changes)
{
struct lbtf_private *priv = hw->priv;
+ struct sk_buff *beacon;
+
+ if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) {
+ switch (priv->vif->type) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_MESH_POINT:
+ beacon = ieee80211_beacon_get(hw, vif);
+ if (beacon) {
+ lbtf_beacon_set(priv, beacon);
+ kfree_skb(beacon);
+ lbtf_beacon_ctrl(priv, 1,
+ bss_conf->beacon_int);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (changes & BSS_CHANGED_BSSID) {
+ bool activate = !is_zero_ether_addr(bss_conf->bssid);
+ lbtf_set_bssid(priv, activate, bss_conf->bssid);
+ }
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
if (bss_conf->use_short_preamble)
@@ -459,8 +452,6 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
priv->preamble = CMD_TYPE_LONG_PREAMBLE;
lbtf_set_radio_control(priv);
}
-
- return;
}
static const struct ieee80211_ops lbtf_ops = {
@@ -470,7 +461,6 @@ static const struct ieee80211_ops lbtf_ops = {
.add_interface = lbtf_op_add_interface,
.remove_interface = lbtf_op_remove_interface,
.config = lbtf_op_config,
- .config_interface = lbtf_op_config_interface,
.configure_filter = lbtf_op_configure_filter,
.bss_info_changed = lbtf_op_bss_info_changed,
};
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index d4fdc8b7d7d8..61a4ad7cc1c2 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -553,18 +553,15 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
struct mac80211_hwsim_data *data = hw->priv;
struct ieee80211_conf *conf = &hw->conf;
- printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n",
+ printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d idle=%d ps=%d)\n",
wiphy_name(hw->wiphy), __func__,
conf->channel->center_freq, conf->radio_enabled,
- conf->beacon_int);
+ !!(conf->flags & IEEE80211_CONF_IDLE),
+ !!(conf->flags & IEEE80211_CONF_PS));
data->channel = conf->channel;
data->radio_enabled = conf->radio_enabled;
- data->beacon_int = 1024 * conf->beacon_int / 1000 * HZ / 1000;
- if (data->beacon_int < 1)
- data->beacon_int = 1;
-
- if (!data->started || !data->radio_enabled)
+ if (!data->started || !data->radio_enabled || !data->beacon_int)
del_timer(&data->beacon_timer);
else
mod_timer(&data->beacon_timer, jiffies + data->beacon_int);
@@ -592,35 +589,26 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
*total_flags = data->rx_filter;
}
-static int mac80211_hwsim_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
-
- hwsim_check_magic(vif);
- if (conf->changed & IEEE80211_IFCC_BSSID) {
- DECLARE_MAC_BUF(mac);
- printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n",
- wiphy_name(hw->wiphy), __func__,
- conf->bssid);
- memcpy(vp->bssid, conf->bssid, ETH_ALEN);
- }
- return 0;
-}
-
static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
u32 changed)
{
struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
+ struct mac80211_hwsim_data *data = hw->priv;
hwsim_check_magic(vif);
printk(KERN_DEBUG "%s:%s(changed=0x%x)\n",
wiphy_name(hw->wiphy), __func__, changed);
+ if (changed & BSS_CHANGED_BSSID) {
+ printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n",
+ wiphy_name(hw->wiphy), __func__,
+ info->bssid);
+ memcpy(vp->bssid, info->bssid, ETH_ALEN);
+ }
+
if (changed & BSS_CHANGED_ASSOC) {
printk(KERN_DEBUG " %s: ASSOC: assoc=%d aid=%d\n",
wiphy_name(hw->wiphy), info->assoc, info->aid);
@@ -628,6 +616,14 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
vp->aid = info->aid;
}
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ printk(KERN_DEBUG " %s: BCNINT: %d\n",
+ wiphy_name(hw->wiphy), info->beacon_int);
+ data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000;
+ if (WARN_ON(!data->beacon_int))
+ data->beacon_int = 1;
+ }
+
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
printk(KERN_DEBUG " %s: ERP_CTS_PROT: %d\n",
wiphy_name(hw->wiphy), info->use_cts_prot);
@@ -646,7 +642,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_HT) {
printk(KERN_DEBUG " %s: HT: op_mode=0x%x\n",
wiphy_name(hw->wiphy),
- info->ht.operation_mode);
+ info->ht_operation_mode);
}
if (changed & BSS_CHANGED_BASIC_RATES) {
@@ -704,7 +700,6 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
.remove_interface = mac80211_hwsim_remove_interface,
.config = mac80211_hwsim_config,
.configure_filter = mac80211_hwsim_configure_filter,
- .config_interface = mac80211_hwsim_config_interface,
.bss_info_changed = mac80211_hwsim_bss_info_changed,
.sta_notify = mac80211_hwsim_sta_notify,
.set_tim = mac80211_hwsim_set_tim,
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index a9a970469c2a..a263d5c84c08 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2369,7 +2369,7 @@ static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
if (info->use_cts_prot) {
prot_mode = MWL8K_FRAME_PROT_11G;
} else {
- switch (info->ht.operation_mode &
+ switch (info->ht_operation_mode &
IEEE80211_HT_OP_MODE_PROTECTION) {
case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
@@ -3089,19 +3089,6 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
return rc ? -EINVAL : 0;
}
-static int mwl8k_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
- u32 changed = conf->changed;
-
- if (changed & IEEE80211_IFCC_BSSID)
- memcpy(mv_vif->bssid, conf->bssid, IEEE80211_ADDR_LEN);
-
- return 0;
-}
-
struct mwl8k_bss_info_changed_worker {
struct mwl8k_work_struct header;
struct ieee80211_vif *vif;
@@ -3183,8 +3170,12 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
{
struct mwl8k_bss_info_changed_worker *worker;
struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
int rc;
+ if (changed & BSS_CHANGED_BSSID)
+ memcpy(mv_vif->bssid, info->bssid, IEEE80211_ADDR_LEN);
+
if ((changed & BSS_CHANGED_ASSOC) == 0)
return;
@@ -3442,7 +3433,6 @@ static const struct ieee80211_ops mwl8k_ops = {
.add_interface = mwl8k_add_interface,
.remove_interface = mwl8k_remove_interface,
.config = mwl8k_config,
- .config_interface = mwl8k_config_interface,
.bss_info_changed = mwl8k_bss_info_changed,
.configure_filter = mwl8k_configure_filter,
.set_rts_threshold = mwl8k_set_rts_threshold,
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index ecf8b6ed5a47..db3df947d8ed 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -125,6 +125,7 @@ struct p54_led_dev {
struct led_classdev led_dev;
char name[P54_LED_MAX_NAME_LEN + 1];
+ unsigned int toggled;
unsigned int index;
unsigned int registered;
};
@@ -133,55 +134,74 @@ struct p54_led_dev {
struct p54_common {
struct ieee80211_hw *hw;
- u32 rx_start;
- u32 rx_end;
- struct sk_buff_head tx_queue;
+ struct ieee80211_vif *vif;
void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb);
int (*open)(struct ieee80211_hw *dev);
void (*stop)(struct ieee80211_hw *dev);
- int mode;
+ struct sk_buff_head tx_queue;
+ struct mutex conf_mutex;
+
+ /* memory management (as seen by the firmware) */
+ u32 rx_start;
+ u32 rx_end;
u16 rx_mtu;
u8 headroom;
u8 tailroom;
- struct mutex conf_mutex;
- u8 mac_addr[ETH_ALEN];
- u8 bssid[ETH_ALEN];
+
+ /* firmware/hardware info */
+ unsigned int tx_hdr_len;
+ unsigned int fw_var;
+ unsigned int fw_interface;
+ u8 version;
+
+ /* (e)DCF / QOS state */
+ bool use_short_slot;
+ struct ieee80211_tx_queue_stats tx_stats[8];
+ struct p54_edcf_queue_param qos_params[8];
+
+ /* Radio data */
+ u16 rxhw;
u8 rx_diversity_mask;
u8 tx_diversity_mask;
+ unsigned int output_power;
+ int noise;
+ /* calibration, output power limit and rssi<->dBm conversation data */
struct pda_iq_autocal_entry *iq_autocal;
unsigned int iq_autocal_len;
- struct p54_cal_database *output_limit;
struct p54_cal_database *curve_data;
+ struct p54_cal_database *output_limit;
struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
+
+ /* BBP/MAC state */
+ u8 mac_addr[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+ u16 wakeup_timer;
unsigned int filter_flags;
- bool use_short_slot;
- u16 rxhw;
- u8 version;
- unsigned int tx_hdr_len;
- unsigned int fw_var;
- unsigned int fw_interface;
- unsigned int output_power;
- u32 tsf_low32;
- u32 tsf_high32;
+ int mode;
+ u32 tsf_low32, tsf_high32;
u32 basic_rate_mask;
- u16 wakeup_timer;
u16 aid;
- struct ieee80211_tx_queue_stats tx_stats[8];
- struct p54_edcf_queue_param qos_params[8];
- struct ieee80211_low_level_stats stats;
- struct delayed_work work;
struct sk_buff *cached_beacon;
- int noise;
- void *eeprom;
- struct completion eeprom_comp;
+
+ /* cryptographic engine information */
u8 privacy_caps;
u8 rx_keycache_size;
+ unsigned long *used_rxkeys;
+
/* LED management */
#ifdef CONFIG_P54_LEDS
- struct p54_led_dev assoc_led;
- struct p54_led_dev tx_led;
+ struct p54_led_dev leds[4];
+ struct delayed_work led_work;
#endif /* CONFIG_P54_LEDS */
u16 softled_state; /* bit field of glowing LEDs */
+
+ /* statistics */
+ struct ieee80211_low_level_stats stats;
+ struct delayed_work work;
+
+ /* eeprom handling */
+ void *eeprom;
+ struct completion eeprom_comp;
};
int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index c8f0232ee5e0..48d81d98e12d 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -249,7 +249,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
dev->queues = P54_QUEUE_AC_NUM;
}
- if (!modparam_nohwcrypt)
+ if (!modparam_nohwcrypt) {
printk(KERN_INFO "%s: cryptographic accelerator "
"WEP:%s, TKIP:%s, CCMP:%s\n",
wiphy_name(dev->wiphy),
@@ -259,6 +259,26 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ?
"YES" : "no");
+ if (priv->rx_keycache_size) {
+ /*
+ * NOTE:
+ *
+ * The firmware provides at most 255 (0 - 254) slots
+ * for keys which are then used to offload decryption.
+ * As a result the 255 entry (aka 0xff) can be used
+ * safely by the driver to mark keys that didn't fit
+ * into the full cache. This trick saves us from
+ * keeping a extra list for uploaded keys.
+ */
+
+ priv->used_rxkeys = kzalloc(BITS_TO_LONGS(
+ priv->rx_keycache_size), GFP_KERNEL);
+
+ if (!priv->used_rxkeys)
+ return -ENOMEM;
+ }
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(p54_parse_firmware);
@@ -749,8 +769,6 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
rx_status.signal = p54_rssi_to_dbm(dev, hdr->rssi);
rx_status.noise = priv->noise;
- /* XX correct? */
- rx_status.qual = (100 * hdr->rssi) / 127;
if (hdr->rate & 0x10)
rx_status.flag |= RX_FLAG_SHORTPRE;
if (dev->conf.channel->band == IEEE80211_BAND_5GHZ)
@@ -804,7 +822,6 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
struct ieee80211_tx_info *info;
struct p54_tx_info *range;
unsigned long flags;
- u32 freed = 0, last_addr = priv->rx_start;
if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue)))
return;
@@ -824,7 +841,6 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
ni = IEEE80211_SKB_CB(skb->prev);
mr = (struct p54_tx_info *)ni->rate_driver_data;
- last_addr = mr->end_addr;
}
if (skb->next != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *ni;
@@ -832,16 +848,11 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
ni = IEEE80211_SKB_CB(skb->next);
mr = (struct p54_tx_info *)ni->rate_driver_data;
- freed = mr->start_addr - last_addr;
- } else
- freed = priv->rx_end - last_addr;
+ }
__skb_unlink(skb, &priv->tx_queue);
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
dev_kfree_skb_any(skb);
-
- if (freed >= priv->headroom + sizeof(struct p54_hdr) + 48 +
- IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
- p54_wake_free_queues(dev);
+ p54_wake_free_queues(dev);
}
EXPORT_SYMBOL_GPL(p54_free_skb);
@@ -875,8 +886,6 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
struct sk_buff *entry;
u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom;
struct p54_tx_info *range = NULL;
- u32 freed = 0;
- u32 last_addr = priv->rx_start;
unsigned long flags;
int count, idx;
@@ -890,7 +899,6 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
range = (void *)info->rate_driver_data;
if (range->start_addr != addr) {
- last_addr = range->end_addr;
entry = entry->next;
continue;
}
@@ -901,11 +909,8 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
ni = IEEE80211_SKB_CB(entry->next);
mr = (struct p54_tx_info *)ni->rate_driver_data;
- freed = mr->start_addr - last_addr;
- } else
- freed = priv->rx_end - last_addr;
+ }
- last_addr = range->end_addr;
__skb_unlink(entry, &priv->tx_queue);
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
@@ -992,9 +997,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
out:
- if (freed >= priv->headroom + sizeof(struct p54_hdr) + 48 +
- IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
- p54_wake_free_queues(dev);
+ p54_wake_free_queues(dev);
}
static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
@@ -1044,6 +1047,7 @@ static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb)
static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb)
{
+ struct p54_common *priv = dev->priv;
struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
struct p54_trap *trap = (struct p54_trap *) hdr->data;
u16 event = le16_to_cpu(trap->event);
@@ -1057,6 +1061,8 @@ static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb)
wiphy_name(dev->wiphy), freq);
break;
case P54_TRAP_NO_BEACON:
+ if (priv->vif)
+ ieee80211_beacon_loss(priv->vif);
break;
case P54_TRAP_SCAN:
break;
@@ -1452,7 +1458,8 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
if (info->control.sta)
*aid = info->control.sta->aid;
- else
+
+ if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
break;
}
@@ -1939,7 +1946,8 @@ static int p54_set_ps(struct ieee80211_hw *dev)
int i;
if (dev->conf.flags & IEEE80211_CONF_PS)
- mode = P54_PSM | P54_PSM_DTIM | P54_PSM_MCBC;
+ mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM |
+ P54_PSM_CHECKSUM | P54_PSM_MCBC;
else
mode = P54_PSM_CAM;
@@ -1957,9 +1965,10 @@ static int p54_set_ps(struct ieee80211_hw *dev)
psm->intervals[i].periods = cpu_to_le16(1);
}
- psm->beacon_rssi_skip_max = 60;
+ psm->beacon_rssi_skip_max = 200;
psm->rssi_delta_threshold = 0;
- psm->nr = 0;
+ psm->nr = 10;
+ psm->exclude[0] = 0;
priv->tx(dev, skb);
@@ -2088,6 +2097,9 @@ static void p54_stop(struct ieee80211_hw *dev)
priv->softled_state = 0;
p54_set_leds(dev);
+#ifdef CONFIG_P54_LEDS
+ cancel_delayed_work_sync(&priv->led_work);
+#endif /* CONFIG_P54_LEDS */
cancel_delayed_work_sync(&priv->work);
if (priv->cached_beacon)
p54_tx_cancel(dev, priv->cached_beacon);
@@ -2111,6 +2123,8 @@ static int p54_add_interface(struct ieee80211_hw *dev,
return -EOPNOTSUPP;
}
+ priv->vif = conf->vif;
+
switch (conf->type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
@@ -2135,6 +2149,7 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
struct p54_common *priv = dev->priv;
mutex_lock(&priv->conf_mutex);
+ priv->vif = NULL;
if (priv->cached_beacon)
p54_tx_cancel(dev, priv->cached_beacon);
priv->mode = NL80211_IFTYPE_MONITOR;
@@ -2174,41 +2189,6 @@ out:
return ret;
}
-static int p54_config_interface(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct p54_common *priv = dev->priv;
- int ret = 0;
-
- mutex_lock(&priv->conf_mutex);
- if (conf->changed & IEEE80211_IFCC_BSSID) {
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
- ret = p54_setup_mac(dev);
- if (ret)
- goto out;
- }
-
- if (conf->changed & IEEE80211_IFCC_BEACON) {
- ret = p54_scan(dev, P54_SCAN_EXIT, 0);
- if (ret)
- goto out;
- ret = p54_setup_mac(dev);
- if (ret)
- goto out;
- ret = p54_beacon_update(dev, vif);
- if (ret)
- goto out;
- ret = p54_set_edcf(dev);
- if (ret)
- goto out;
- }
-
-out:
- mutex_unlock(&priv->conf_mutex);
- return ret;
-}
-
static void p54_configure_filter(struct ieee80211_hw *dev,
unsigned int changed_flags,
unsigned int *total_flags,
@@ -2312,8 +2292,32 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
u32 changed)
{
struct p54_common *priv = dev->priv;
+ int ret;
- if (changed & BSS_CHANGED_ERP_SLOT) {
+ mutex_lock(&priv->conf_mutex);
+ if (changed & BSS_CHANGED_BSSID) {
+ memcpy(priv->bssid, info->bssid, ETH_ALEN);
+ ret = p54_setup_mac(dev);
+ if (ret)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_BEACON) {
+ ret = p54_scan(dev, P54_SCAN_EXIT, 0);
+ if (ret)
+ goto out;
+ ret = p54_setup_mac(dev);
+ if (ret)
+ goto out;
+ ret = p54_beacon_update(dev, vif);
+ if (ret)
+ goto out;
+ }
+ /* XXX: this mimics having two callbacks... clean up */
+ out:
+ mutex_unlock(&priv->conf_mutex);
+
+ if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BEACON)) {
priv->use_short_slot = info->use_short_slot;
p54_set_edcf(dev);
}
@@ -2334,7 +2338,6 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
p54_setup_mac(dev);
}
}
-
}
static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
@@ -2344,61 +2347,84 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
struct p54_common *priv = dev->priv;
struct sk_buff *skb;
struct p54_keycache *rxkey;
+ int slot, ret = 0;
u8 algo = 0;
if (modparam_nohwcrypt)
return -EOPNOTSUPP;
- if (cmd == DISABLE_KEY)
- algo = 0;
- else {
+ mutex_lock(&priv->conf_mutex);
+ if (cmd == SET_KEY) {
switch (key->alg) {
case ALG_TKIP:
if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL |
- BR_DESC_PRIV_CAP_TKIP)))
- return -EOPNOTSUPP;
+ BR_DESC_PRIV_CAP_TKIP))) {
+ ret = -EOPNOTSUPP;
+ goto out_unlock;
+ }
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
algo = P54_CRYPTO_TKIPMICHAEL;
break;
case ALG_WEP:
- if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP))
- return -EOPNOTSUPP;
+ if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) {
+ ret = -EOPNOTSUPP;
+ goto out_unlock;
+ }
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
algo = P54_CRYPTO_WEP;
break;
case ALG_CCMP:
- if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP))
- return -EOPNOTSUPP;
+ if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) {
+ ret = -EOPNOTSUPP;
+ goto out_unlock;
+ }
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
algo = P54_CRYPTO_AESCCMP;
break;
default:
- return -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
+ goto out_unlock;
}
- }
+ slot = bitmap_find_free_region(priv->used_rxkeys,
+ priv->rx_keycache_size, 0);
- if (key->keyidx > priv->rx_keycache_size) {
- /*
- * The device supports the choosen algorithm, but the firmware
- * does not provide enough key slots to store all of them.
- * So, incoming frames have to be decoded by the mac80211 stack,
- * but we can still offload encryption for outgoing frames.
- */
+ if (slot < 0) {
+ /*
+ * The device supports the choosen algorithm, but the
+ * firmware does not provide enough key slots to store
+ * all of them.
+ * But encryption offload for outgoing frames is always
+ * possible, so we just pretend that the upload was
+ * successful and do the decryption in software.
+ */
- return 0;
+ /* mark the key as invalid. */
+ key->hw_key_idx = 0xff;
+ goto out_unlock;
+ }
+ } else {
+ slot = key->hw_key_idx;
+
+ if (slot == 0xff) {
+ /* This key was not uploaded into the rx key cache. */
+
+ goto out_unlock;
+ }
+
+ bitmap_release_region(priv->used_rxkeys, slot, 0);
+ algo = 0;
}
- mutex_lock(&priv->conf_mutex);
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
- P54_CONTROL_TYPE_RX_KEYCACHE, GFP_ATOMIC);
+ P54_CONTROL_TYPE_RX_KEYCACHE, GFP_KERNEL);
if (!skb) {
- mutex_unlock(&priv->conf_mutex);
- return -ENOMEM;
+ bitmap_release_region(priv->used_rxkeys, slot, 0);
+ ret = -ENOSPC;
+ goto out_unlock;
}
- /* TODO: some devices have 4 more free slots for rx keys */
rxkey = (struct p54_keycache *)skb_put(skb, sizeof(*rxkey));
- rxkey->entry = key->keyidx;
+ rxkey->entry = slot;
rxkey->key_id = key->keyidx;
rxkey->key_type = algo;
if (sta)
@@ -2416,11 +2442,51 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
}
priv->tx(dev, skb);
+ key->hw_key_idx = slot;
+
+out_unlock:
mutex_unlock(&priv->conf_mutex);
- return 0;
+ return ret;
}
#ifdef CONFIG_P54_LEDS
+static void p54_update_leds(struct work_struct *work)
+{
+ struct p54_common *priv = container_of(work, struct p54_common,
+ led_work.work);
+ int err, i, tmp, blink_delay = 400;
+ bool rerun = false;
+
+ /* Don't toggle the LED, when the device is down. */
+ if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+ return ;
+
+ for (i = 0; i < ARRAY_SIZE(priv->leds); i++)
+ if (priv->leds[i].toggled) {
+ priv->softled_state |= BIT(i);
+
+ tmp = 70 + 200 / (priv->leds[i].toggled);
+ if (tmp < blink_delay)
+ blink_delay = tmp;
+
+ if (priv->leds[i].led_dev.brightness == LED_OFF)
+ rerun = true;
+
+ priv->leds[i].toggled =
+ !!priv->leds[i].led_dev.brightness;
+ } else
+ priv->softled_state &= ~BIT(i);
+
+ err = p54_set_leds(priv->hw);
+ if (err && net_ratelimit())
+ printk(KERN_ERR "%s: failed to update LEDs.\n",
+ wiphy_name(priv->hw->wiphy));
+
+ if (rerun)
+ queue_delayed_work(priv->hw->workqueue, &priv->led_work,
+ msecs_to_jiffies(blink_delay));
+}
+
static void p54_led_brightness_set(struct led_classdev *led_dev,
enum led_brightness brightness)
{
@@ -2428,28 +2494,23 @@ static void p54_led_brightness_set(struct led_classdev *led_dev,
led_dev);
struct ieee80211_hw *dev = led->hw_dev;
struct p54_common *priv = dev->priv;
- int err;
- /* Don't toggle the LED, when the device is down. */
if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
return ;
- if (brightness != LED_OFF)
- priv->softled_state |= BIT(led->index);
- else
- priv->softled_state &= ~BIT(led->index);
-
- err = p54_set_leds(dev);
- if (err && net_ratelimit())
- printk(KERN_ERR "%s: failed to update %s LED.\n",
- wiphy_name(dev->wiphy), led_dev->name);
+ if (brightness) {
+ led->toggled++;
+ queue_delayed_work(priv->hw->workqueue, &priv->led_work,
+ HZ/10);
+ }
}
static int p54_register_led(struct ieee80211_hw *dev,
- struct p54_led_dev *led,
unsigned int led_index,
char *name, char *trigger)
{
+ struct p54_common *priv = dev->priv;
+ struct p54_led_dev *led = &priv->leds[led_index];
int err;
if (led->registered)
@@ -2482,19 +2543,30 @@ static int p54_init_leds(struct ieee80211_hw *dev)
* TODO:
* Figure out if the EEPROM contains some hints about the number
* of available/programmable LEDs of the device.
- * But for now, we can assume that we have two programmable LEDs.
*/
- err = p54_register_led(dev, &priv->assoc_led, 0, "assoc",
+ INIT_DELAYED_WORK(&priv->led_work, p54_update_leds);
+
+ err = p54_register_led(dev, 0, "assoc",
ieee80211_get_assoc_led_name(dev));
if (err)
return err;
- err = p54_register_led(dev, &priv->tx_led, 1, "tx",
+ err = p54_register_led(dev, 1, "tx",
ieee80211_get_tx_led_name(dev));
if (err)
return err;
+ err = p54_register_led(dev, 2, "rx",
+ ieee80211_get_rx_led_name(dev));
+ if (err)
+ return err;
+
+ err = p54_register_led(dev, 3, "radio",
+ ieee80211_get_radio_led_name(dev));
+ if (err)
+ return err;
+
err = p54_set_leds(dev);
return err;
}
@@ -2502,11 +2574,11 @@ static int p54_init_leds(struct ieee80211_hw *dev)
static void p54_unregister_leds(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
+ int i;
- if (priv->tx_led.registered)
- led_classdev_unregister(&priv->tx_led.led_dev);
- if (priv->assoc_led.registered)
- led_classdev_unregister(&priv->assoc_led.led_dev);
+ for (i = 0; i < ARRAY_SIZE(priv->leds); i++)
+ if (priv->leds[i].registered)
+ led_classdev_unregister(&priv->leds[i].led_dev);
}
#endif /* CONFIG_P54_LEDS */
@@ -2520,7 +2592,6 @@ static const struct ieee80211_ops p54_ops = {
.sta_notify = p54_sta_notify,
.set_key = p54_set_key,
.config = p54_config,
- .config_interface = p54_config_interface,
.bss_info_changed = p54_bss_info_changed,
.configure_filter = p54_configure_filter,
.conf_tx = p54_conf_tx,
@@ -2607,21 +2678,10 @@ void p54_free_common(struct ieee80211_hw *dev)
kfree(priv->iq_autocal);
kfree(priv->output_limit);
kfree(priv->curve_data);
+ kfree(priv->used_rxkeys);
#ifdef CONFIG_P54_LEDS
p54_unregister_leds(dev);
#endif /* CONFIG_P54_LEDS */
}
EXPORT_SYMBOL_GPL(p54_free_common);
-
-static int __init p54_init(void)
-{
- return 0;
-}
-
-static void __exit p54_exit(void)
-{
-}
-
-module_init(p54_init);
-module_exit(p54_exit);
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index d1fe577de3d4..59a5e778bb08 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -167,18 +167,36 @@ static const struct p54spi_spi_reg p54spi_registers_array[] =
static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits)
{
int i;
- __le32 buffer;
for (i = 0; i < 2000; i++) {
- p54spi_spi_read(priv, reg, &buffer, sizeof(buffer));
- if (buffer == bits)
+ __le32 buffer = p54spi_read32(priv, reg);
+ if ((buffer & bits) == bits)
return 1;
- msleep(1);
+ msleep(0);
}
return 0;
}
+static int p54spi_spi_write_dma(struct p54s_priv *priv, __le32 base,
+ const void *buf, size_t len)
+{
+ p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL,
+ cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE));
+
+ if (!p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL,
+ cpu_to_le32(HOST_ALLOWED))) {
+ dev_err(&priv->spi->dev, "spi_write_dma not allowed "
+ "to DMA write.\n");
+ return -EAGAIN;
+ }
+
+ p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN, cpu_to_le16(len));
+ p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE, base);
+ p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, buf, len);
+ return 0;
+}
+
static int p54spi_request_firmware(struct ieee80211_hw *dev)
{
struct p54s_priv *priv = dev->priv;
@@ -228,8 +246,15 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev)
static int p54spi_upload_firmware(struct ieee80211_hw *dev)
{
struct p54s_priv *priv = dev->priv;
- unsigned long fw_len, fw_addr;
- long _fw_len;
+ unsigned long fw_len, _fw_len;
+ unsigned int offset = 0;
+ int err = 0;
+ u8 *fw;
+
+ fw_len = priv->firmware->size;
+ fw = kmemdup(priv->firmware->data, fw_len, GFP_KERNEL);
+ if (!fw)
+ return -ENOMEM;
/* stop the device */
p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
@@ -244,36 +269,17 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev)
msleep(TARGET_BOOT_SLEEP);
- fw_addr = ISL38XX_DEV_FIRMWARE_ADDR;
- fw_len = priv->firmware->size;
-
while (fw_len > 0) {
_fw_len = min_t(long, fw_len, SPI_MAX_PACKET_SIZE);
- p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL,
- cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE));
-
- if (p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL,
- cpu_to_le32(HOST_ALLOWED)) == 0) {
- dev_err(&priv->spi->dev, "fw_upload not allowed "
- "to DMA write.");
- return -EAGAIN;
- }
-
- p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN,
- cpu_to_le16(_fw_len));
- p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE,
- cpu_to_le32(fw_addr));
-
- p54spi_spi_write(priv, SPI_ADRS_DMA_DATA,
- &priv->firmware->data, _fw_len);
+ err = p54spi_spi_write_dma(priv, cpu_to_le32(
+ ISL38XX_DEV_FIRMWARE_ADDR + offset),
+ (fw + offset), _fw_len);
+ if (err < 0)
+ goto out;
fw_len -= _fw_len;
- fw_addr += _fw_len;
-
- /* FIXME: I think this doesn't work if firmware is large,
- * this loop goes to second round. fw->data is not
- * increased at all! */
+ offset += _fw_len;
}
BUG_ON(fw_len != 0);
@@ -292,7 +298,10 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev)
p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT));
msleep(TARGET_BOOT_SLEEP);
- return 0;
+
+out:
+ kfree(fw);
+ return err;
}
static void p54spi_power_off(struct p54s_priv *priv)
@@ -320,21 +329,15 @@ static inline void p54spi_int_ack(struct p54s_priv *priv, u32 val)
static void p54spi_wakeup(struct p54s_priv *priv)
{
- unsigned long timeout;
- u32 ints;
-
/* wake the chip */
p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS,
cpu_to_le32(SPI_TARGET_INT_WAKEUP));
/* And wait for the READY interrupt */
- timeout = jiffies + HZ;
-
- ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
- while (!(ints & SPI_HOST_INT_READY)) {
- if (time_after(jiffies, timeout))
- goto out;
- ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+ if (!p54spi_wait_bit(priv, SPI_ADRS_HOST_INTERRUPTS,
+ cpu_to_le32(SPI_HOST_INT_READY))) {
+ dev_err(&priv->spi->dev, "INT_READY timeout\n");
+ goto out;
}
p54spi_int_ack(priv, SPI_HOST_INT_READY);
@@ -385,7 +388,12 @@ static int p54spi_rx(struct p54s_priv *priv)
return 0;
}
- skb = dev_alloc_skb(len);
+
+ /* Firmware may insert up to 4 padding bytes after the lmac header,
+ * but it does not amend the size of SPI data transfer.
+ * Such packets has correct data size in header, thus referencing
+ * past the end of allocated skb. Reserve extra 4 bytes for this case */
+ skb = dev_alloc_skb(len + 4);
if (!skb) {
dev_err(&priv->spi->dev, "could not alloc skb");
return 0;
@@ -393,6 +401,9 @@ static int p54spi_rx(struct p54s_priv *priv)
p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
p54spi_sleep(priv);
+ /* Put additional bytes to compensate for the possible
+ * alignment-caused truncation */
+ skb_put(skb, 4);
if (p54_rx(priv->hw, skb) == 0)
dev_kfree_skb(skb);
@@ -414,39 +425,27 @@ static irqreturn_t p54spi_interrupt(int irq, void *config)
static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb)
{
struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
- struct p54s_dma_regs dma_regs;
- unsigned long timeout;
int ret = 0;
- u32 ints;
p54spi_wakeup(priv);
- dma_regs.cmd = cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE);
- dma_regs.len = cpu_to_le16(skb->len);
- dma_regs.addr = hdr->req_id;
-
- p54spi_spi_write(priv, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
- sizeof(dma_regs));
-
- p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, skb->data, skb->len);
+ ret = p54spi_spi_write_dma(priv, hdr->req_id, skb->data, skb->len);
+ if (ret < 0)
+ goto out;
- timeout = jiffies + 2 * HZ;
- ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
- while (!(ints & SPI_HOST_INT_WR_READY)) {
- if (time_after(jiffies, timeout)) {
- dev_err(&priv->spi->dev, "WR_READY timeout");
- ret = -1;
- goto out;
- }
- ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+ if (!p54spi_wait_bit(priv, SPI_ADRS_HOST_INTERRUPTS,
+ cpu_to_le32(SPI_HOST_INT_WR_READY))) {
+ dev_err(&priv->spi->dev, "WR_READY timeout\n");
+ ret = -1;
+ goto out;
}
p54spi_int_ack(priv, SPI_HOST_INT_WR_READY);
p54spi_sleep(priv);
-out:
if (FREE_AFTER_TX(skb))
p54_free_skb(priv->hw, skb);
+out:
return ret;
}
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 6cc6cbc9234f..f40c0f468b27 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -81,6 +81,29 @@ static struct usb_device_id p54u_table[] __devinitdata = {
MODULE_DEVICE_TABLE(usb, p54u_table);
+static const struct {
+ u32 intf;
+ enum p54u_hw_type type;
+ char fw[FIRMWARE_NAME_MAX];
+ char fw_legacy[FIRMWARE_NAME_MAX];
+ char hw[20];
+} p54u_fwlist[__NUM_P54U_HWTYPES] = {
+ {
+ .type = P54U_NET2280,
+ .intf = FW_LM86,
+ .fw = "isl3886usb",
+ .fw_legacy = "isl3890usb",
+ .hw = "ISL3886 + net2280",
+ },
+ {
+ .type = P54U_3887,
+ .intf = FW_LM87,
+ .fw = "isl3887usb",
+ .fw_legacy = "isl3887usb_bare",
+ .hw = "ISL3887",
+ },
+};
+
static void p54u_rx_cb(struct urb *urb)
{
struct sk_buff *skb = (struct sk_buff *) urb->context;
@@ -125,11 +148,7 @@ static void p54u_rx_cb(struct urb *urb)
}
skb_reset_tail_pointer(skb);
skb_trim(skb, 0);
- if (urb->transfer_buffer != skb_tail_pointer(skb)) {
- /* this should not happen */
- WARN_ON(1);
- urb->transfer_buffer = skb_tail_pointer(skb);
- }
+ urb->transfer_buffer = skb_tail_pointer(skb);
}
skb_queue_tail(&priv->rx_queue, skb);
usb_anchor_urb(urb, &priv->submitted);
@@ -206,53 +225,6 @@ static int p54u_init_urbs(struct ieee80211_hw *dev)
return ret;
}
-static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
- struct p54u_priv *priv = dev->priv;
- struct urb *addr_urb, *data_urb;
- int err = 0;
-
- addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!addr_urb)
- return;
-
- data_urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!data_urb) {
- usb_free_urb(addr_urb);
- return;
- }
-
- usb_fill_bulk_urb(addr_urb, priv->udev,
- usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- &((struct p54_hdr *)skb->data)->req_id, 4,
- p54u_tx_dummy_cb, dev);
- usb_fill_bulk_urb(data_urb, priv->udev,
- usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, FREE_AFTER_TX(skb) ?
- p54u_tx_cb : p54u_tx_dummy_cb, skb);
- addr_urb->transfer_flags |= URB_ZERO_PACKET;
- data_urb->transfer_flags |= URB_ZERO_PACKET;
-
- usb_anchor_urb(addr_urb, &priv->submitted);
- err = usb_submit_urb(addr_urb, GFP_ATOMIC);
- if (err) {
- usb_unanchor_urb(addr_urb);
- goto out;
- }
-
- usb_anchor_urb(data_urb, &priv->submitted);
- err = usb_submit_urb(data_urb, GFP_ATOMIC);
- if (err)
- usb_unanchor_urb(data_urb);
-
- out:
- usb_free_urb(addr_urb);
- usb_free_urb(data_urb);
-
- if (err)
- p54_free_skb(dev, skb);
-}
-
static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
{
u32 chk = 0;
@@ -425,20 +397,16 @@ static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
data, len, &alen, 2000);
}
-static const char p54u_romboot_3887[] = "~~~~";
-static const char p54u_firmware_upload_3887[] = "<\r";
-
-static int p54u_device_reset_3887(struct ieee80211_hw *dev)
+static int p54u_device_reset(struct ieee80211_hw *dev)
{
struct p54u_priv *priv = dev->priv;
int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING);
- u8 buf[4];
if (lock) {
ret = usb_lock_device_for_reset(priv->udev, priv->intf);
if (ret < 0) {
dev_err(&priv->udev->dev, "(p54usb) unable to lock "
- " device for reset: %d\n", ret);
+ "device for reset (%d)!\n", ret);
return ret;
}
}
@@ -447,26 +415,34 @@ static int p54u_device_reset_3887(struct ieee80211_hw *dev)
if (lock)
usb_unlock_device(priv->udev);
- if (ret) {
+ if (ret)
dev_err(&priv->udev->dev, "(p54usb) unable to reset "
- "device: %d\n", ret);
- return ret;
- }
+ "device (%d)!\n", ret);
+
+ return ret;
+}
+
+static const char p54u_romboot_3887[] = "~~~~";
+static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
+{
+ struct p54u_priv *priv = dev->priv;
+ u8 buf[4];
+ int ret;
memcpy(&buf, p54u_romboot_3887, sizeof(buf));
ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
buf, sizeof(buf));
if (ret)
dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
- "boot ROM: %d\n", ret);
+ "boot ROM (%d)!\n", ret);
return ret;
}
+static const char p54u_firmware_upload_3887[] = "<\r";
static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
{
struct p54u_priv *priv = dev->priv;
- const struct firmware *fw_entry = NULL;
int err, alen;
u8 carry = 0;
u8 *buf, *tmp;
@@ -475,51 +451,29 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
struct x2_header *hdr;
unsigned long timeout;
+ err = p54u_firmware_reset_3887(dev);
+ if (err)
+ return err;
+
tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
if (!buf) {
dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware"
"upload buffer!\n");
- err = -ENOMEM;
- goto err_bufalloc;
- }
-
- err = p54u_device_reset_3887(dev);
- if (err)
- goto err_reset;
-
- err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev);
- if (err) {
- dev_err(&priv->udev->dev, "p54usb: cannot find firmware "
- "(isl3887usb)\n");
- err = request_firmware(&fw_entry, "isl3887usb_bare",
- &priv->udev->dev);
- if (err)
- goto err_req_fw_failed;
- }
-
- err = p54_parse_firmware(dev, fw_entry);
- if (err)
- goto err_upload_failed;
-
- if (priv->common.fw_interface != FW_LM87) {
- dev_err(&priv->udev->dev, "wrong firmware, "
- "please get a LM87 firmware and try again.\n");
- err = -EINVAL;
- goto err_upload_failed;
+ return -ENOMEM;
}
- left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
+ left = block_size = min((size_t)P54U_FW_BLOCK, priv->fw->size);
strcpy(buf, p54u_firmware_upload_3887);
left -= strlen(p54u_firmware_upload_3887);
tmp += strlen(p54u_firmware_upload_3887);
- data = fw_entry->data;
- remains = fw_entry->size;
+ data = priv->fw->data;
+ remains = priv->fw->size;
hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887));
memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
- hdr->fw_length = cpu_to_le32(fw_entry->size);
+ hdr->fw_length = cpu_to_le32(priv->fw->size);
hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
sizeof(u32)*2));
left -= sizeof(*hdr);
@@ -561,7 +515,8 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
}
- *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
+ *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, priv->fw->data,
+ priv->fw->size));
err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
if (err) {
dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
@@ -612,19 +567,14 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
if (err)
goto err_upload_failed;
- err_upload_failed:
- release_firmware(fw_entry);
- err_req_fw_failed:
- err_reset:
+err_upload_failed:
kfree(buf);
- err_bufalloc:
return err;
}
static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
{
struct p54u_priv *priv = dev->priv;
- const struct firmware *fw_entry = NULL;
const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
int err, alen;
void *buf;
@@ -639,33 +589,6 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
return -ENOMEM;
}
- err = request_firmware(&fw_entry, "isl3886usb", &priv->udev->dev);
- if (err) {
- dev_err(&priv->udev->dev, "(p54usb) cannot find firmware "
- "(isl3886usb)\n");
- err = request_firmware(&fw_entry, "isl3890usb",
- &priv->udev->dev);
- if (err) {
- kfree(buf);
- return err;
- }
- }
-
- err = p54_parse_firmware(dev, fw_entry);
- if (err) {
- kfree(buf);
- release_firmware(fw_entry);
- return err;
- }
-
- if (priv->common.fw_interface != FW_LM86) {
- dev_err(&priv->udev->dev, "wrong firmware, "
- "please get a LM86(USB) firmware and try again.\n");
- kfree(buf);
- release_firmware(fw_entry);
- return -EINVAL;
- }
-
#define P54U_WRITE(type, addr, data) \
do {\
err = p54u_write(priv, buf, type,\
@@ -765,8 +688,8 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
/* finally, we can upload firmware now! */
- remains = fw_entry->size;
- data = fw_entry->data;
+ remains = priv->fw->size;
+ data = priv->fw->data;
offset = ISL38XX_DEV_FIRMWARE_ADDR;
while (remains) {
@@ -875,12 +798,54 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
#undef P54U_WRITE
#undef P54U_READ
- fail:
- release_firmware(fw_entry);
+fail:
kfree(buf);
return err;
}
+static int p54u_load_firmware(struct ieee80211_hw *dev)
+{
+ struct p54u_priv *priv = dev->priv;
+ int err, i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(p54u_fwlist) != __NUM_P54U_HWTYPES);
+
+ for (i = 0; i < __NUM_P54U_HWTYPES; i++)
+ if (p54u_fwlist[i].type == priv->hw_type)
+ break;
+
+ if (i == __NUM_P54U_HWTYPES)
+ return -EOPNOTSUPP;
+
+ err = request_firmware(&priv->fw, p54u_fwlist[i].fw, &priv->udev->dev);
+ if (err) {
+ dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s "
+ "(%d)!\n", p54u_fwlist[i].fw, err);
+
+ err = request_firmware(&priv->fw, p54u_fwlist[i].fw_legacy,
+ &priv->udev->dev);
+ if (err)
+ return err;
+ }
+
+ err = p54_parse_firmware(dev, priv->fw);
+ if (err)
+ goto out;
+
+ if (priv->common.fw_interface != p54u_fwlist[i].intf) {
+ dev_err(&priv->udev->dev, "wrong firmware, please get "
+ "a firmware for \"%s\" and try again.\n",
+ p54u_fwlist[i].hw);
+ err = -EINVAL;
+ }
+
+out:
+ if (err)
+ release_firmware(priv->fw);
+
+ return err;
+}
+
static int p54u_open(struct ieee80211_hw *dev)
{
struct p54u_priv *priv = dev->priv;
@@ -922,6 +887,7 @@ static int __devinit p54u_probe(struct usb_interface *intf,
}
priv = dev->priv;
+ priv->hw_type = P54U_INVALID_HW;
SET_IEEE80211_DEV(dev, &intf->dev);
usb_set_intfdata(intf, dev);
@@ -953,37 +919,48 @@ static int __devinit p54u_probe(struct usb_interface *intf,
priv->common.open = p54u_open;
priv->common.stop = p54u_stop;
if (recognized_pipes < P54U_PIPE_NUMBER) {
+#ifdef CONFIG_PM
+ /* ISL3887 needs a full reset on resume */
+ udev->reset_resume = 1;
+ err = p54u_device_reset(dev);
+#endif
+
priv->hw_type = P54U_3887;
- err = p54u_upload_firmware_3887(dev);
- if (priv->common.fw_interface == FW_LM87) {
- dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
- priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
- priv->common.tx = p54u_tx_lm87;
- } else
- priv->common.tx = p54u_tx_3887;
+ dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
+ priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
+ priv->common.tx = p54u_tx_lm87;
+ priv->upload_fw = p54u_upload_firmware_3887;
} else {
priv->hw_type = P54U_NET2280;
dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
priv->common.tx = p54u_tx_net2280;
- err = p54u_upload_firmware_net2280(dev);
+ priv->upload_fw = p54u_upload_firmware_net2280;
}
+ err = p54u_load_firmware(dev);
if (err)
goto err_free_dev;
+ err = priv->upload_fw(dev);
+ if (err)
+ goto err_free_fw;
+
p54u_open(dev);
err = p54_read_eeprom(dev);
p54u_stop(dev);
if (err)
- goto err_free_dev;
+ goto err_free_fw;
err = p54_register_common(dev, &udev->dev);
if (err)
- goto err_free_dev;
+ goto err_free_fw;
return 0;
- err_free_dev:
+err_free_fw:
+ release_firmware(priv->fw);
+
+err_free_dev:
ieee80211_free_hw(dev);
usb_set_intfdata(intf, NULL);
usb_put_dev(udev);
@@ -1002,20 +979,64 @@ static void __devexit p54u_disconnect(struct usb_interface *intf)
priv = dev->priv;
usb_put_dev(interface_to_usbdev(intf));
+ release_firmware(priv->fw);
p54_free_common(dev);
ieee80211_free_hw(dev);
}
static int p54u_pre_reset(struct usb_interface *intf)
{
+ struct ieee80211_hw *dev = usb_get_intfdata(intf);
+
+ if (!dev)
+ return -ENODEV;
+
+ p54u_stop(dev);
return 0;
}
+static int p54u_resume(struct usb_interface *intf)
+{
+ struct ieee80211_hw *dev = usb_get_intfdata(intf);
+ struct p54u_priv *priv;
+
+ if (!dev)
+ return -ENODEV;
+
+ priv = dev->priv;
+ if (unlikely(!(priv->upload_fw && priv->fw)))
+ return 0;
+
+ return priv->upload_fw(dev);
+}
+
static int p54u_post_reset(struct usb_interface *intf)
{
+ struct ieee80211_hw *dev = usb_get_intfdata(intf);
+ struct p54u_priv *priv;
+ int err;
+
+ err = p54u_resume(intf);
+ if (err)
+ return err;
+
+ /* reinitialize old device state */
+ priv = dev->priv;
+ if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED)
+ ieee80211_restart_hw(dev);
+
return 0;
}
+#ifdef CONFIG_PM
+
+static int p54u_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ return p54u_pre_reset(intf);
+}
+
+#endif /* CONFIG_PM */
+
static struct usb_driver p54u_driver = {
.name = "p54usb",
.id_table = p54u_table,
@@ -1023,6 +1044,11 @@ static struct usb_driver p54u_driver = {
.disconnect = p54u_disconnect,
.pre_reset = p54u_pre_reset,
.post_reset = p54u_post_reset,
+#ifdef CONFIG_PM
+ .suspend = p54u_suspend,
+ .resume = p54u_resume,
+ .reset_resume = p54u_resume,
+#endif /* CONFIG_PM */
.soft_unbind = 1,
};
diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h
index 8bc58982d8dd..e935b79f7f75 100644
--- a/drivers/net/wireless/p54/p54usb.h
+++ b/drivers/net/wireless/p54/p54usb.h
@@ -123,18 +123,26 @@ struct p54u_rx_info {
struct ieee80211_hw *dev;
};
+enum p54u_hw_type {
+ P54U_INVALID_HW,
+ P54U_NET2280,
+ P54U_3887,
+
+ /* keep last */
+ __NUM_P54U_HWTYPES,
+};
+
struct p54u_priv {
struct p54_common common;
struct usb_device *udev;
struct usb_interface *intf;
- enum {
- P54U_NET2280 = 0,
- P54U_3887
- } hw_type;
+ int (*upload_fw)(struct ieee80211_hw *dev);
+ enum p54u_hw_type hw_type;
spinlock_t lock;
struct sk_buff_head rx_queue;
struct usb_anchor submitted;
+ const struct firmware *fw;
};
#endif /* P54USB_H */
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index fa90d1d8d82e..22e71856aa24 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -892,7 +892,7 @@ static int ray_dev_init(struct net_device *dev)
#endif /* RAY_IMMEDIATE_INIT */
/* copy mac and broadcast addresses to linux device */
- memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
+ memcpy(dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
memset(dev->broadcast, 0xff, ETH_ALEN);
DEBUG(2, "ray_dev_init ending\n");
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index ff0042ffe3e9..ab7fe02230ca 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -42,6 +42,7 @@
#include <linux/ctype.h>
#include <linux/spinlock.h>
#include <net/iw_handler.h>
+#include <net/cfg80211.h>
#include <linux/usb/usbnet.h>
#include <linux/usb/rndis_host.h>
@@ -316,25 +317,61 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
#define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set))
+static const struct ieee80211_channel rndis_channels[] = {
+ { .center_freq = 2412 },
+ { .center_freq = 2417 },
+ { .center_freq = 2422 },
+ { .center_freq = 2427 },
+ { .center_freq = 2432 },
+ { .center_freq = 2437 },
+ { .center_freq = 2442 },
+ { .center_freq = 2447 },
+ { .center_freq = 2452 },
+ { .center_freq = 2457 },
+ { .center_freq = 2462 },
+ { .center_freq = 2467 },
+ { .center_freq = 2472 },
+ { .center_freq = 2484 },
+};
+
+static const struct ieee80211_rate rndis_rates[] = {
+ { .bitrate = 10 },
+ { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 60 },
+ { .bitrate = 90 },
+ { .bitrate = 120 },
+ { .bitrate = 180 },
+ { .bitrate = 240 },
+ { .bitrate = 360 },
+ { .bitrate = 480 },
+ { .bitrate = 540 }
+};
+
/* RNDIS device private data */
struct rndis_wext_private {
- char name[32];
-
struct usbnet *usbdev;
+ struct wireless_dev wdev;
+
+ struct cfg80211_scan_request *scan_request;
+
struct workqueue_struct *workqueue;
struct delayed_work stats_work;
+ struct delayed_work scan_work;
struct work_struct work;
struct mutex command_lock;
spinlock_t stats_lock;
unsigned long work_pending;
+ struct ieee80211_supported_band band;
+ struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)];
+ struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)];
+
struct iw_statistics iwstats;
struct iw_statistics privstats;
- int nick_len;
- char nick[32];
-
int caps;
int multicast_size;
@@ -368,8 +405,22 @@ struct rndis_wext_private {
u8 command_buffer[COMMAND_BUFFER_SIZE];
};
+/*
+ * cfg80211 ops
+ */
+static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params);
+
+static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_scan_request *request);
+
+static struct cfg80211_ops rndis_config_ops = {
+ .change_virtual_intf = rndis_change_virtual_intf,
+ .scan = rndis_scan,
+};
-static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
+static void *rndis_wiphy_privid = &rndis_wiphy_privid;
static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
@@ -1086,131 +1137,180 @@ static void set_multicast_list(struct usbnet *usbdev)
/*
- * wireless extension handlers
+ * cfg80211 ops
*/
-
-static int rndis_iw_commit(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
{
- /* dummy op */
- return 0;
+ struct net_device *dev;
+ struct usbnet *usbdev;
+ int mode;
+
+ /* we're under RTNL */
+ dev = __dev_get_by_index(&init_net, ifindex);
+ if (!dev)
+ return -ENODEV;
+ usbdev = netdev_priv(dev);
+
+ switch (type) {
+ case NL80211_IFTYPE_ADHOC:
+ mode = ndis_80211_infra_adhoc;
+ break;
+ case NL80211_IFTYPE_STATION:
+ mode = ndis_80211_infra_infra;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return set_infra_mode(usbdev, mode);
}
-static int rndis_iw_get_range(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+#define SCAN_DELAY_JIFFIES (HZ)
+static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_scan_request *request)
{
- struct iw_range *range = (struct iw_range *)extra;
struct usbnet *usbdev = netdev_priv(dev);
struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
- int len, ret, i, j, num, has_80211g_rates;
- u8 rates[8];
- __le32 tx_power;
+ int ret;
+ __le32 tmp;
- devdbg(usbdev, "SIOCGIWRANGE");
+ devdbg(usbdev, "cfg80211.scan");
- /* clear iw_range struct */
- memset(range, 0, sizeof(*range));
- wrqu->data.length = sizeof(*range);
+ if (!request)
+ return -EINVAL;
- range->txpower_capa = IW_TXPOW_MWATT;
- range->num_txpower = 1;
- if (priv->caps & CAP_SUPPORT_TXPOWER) {
- len = sizeof(tx_power);
- ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
- &tx_power, &len);
- if (ret == 0 && le32_to_cpu(tx_power) != 0xFF)
- range->txpower[0] = le32_to_cpu(tx_power);
- else
- range->txpower[0] = get_bcm4320_power(priv);
- } else
- range->txpower[0] = get_bcm4320_power(priv);
+ if (priv->scan_request && priv->scan_request != request)
+ return -EBUSY;
- len = sizeof(rates);
- ret = rndis_query_oid(usbdev, OID_802_11_SUPPORTED_RATES, &rates,
- &len);
- has_80211g_rates = 0;
+ priv->scan_request = request;
+
+ tmp = cpu_to_le32(1);
+ ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
+ sizeof(tmp));
if (ret == 0) {
- j = 0;
- for (i = 0; i < len; i++) {
- if (rates[i] == 0)
- break;
- range->bitrate[j] = (rates[i] & 0x7f) * 500000;
- /* check for non 802.11b rates */
- if (range->bitrate[j] == 6000000 ||
- range->bitrate[j] == 9000000 ||
- (range->bitrate[j] >= 12000000 &&
- range->bitrate[j] != 22000000))
- has_80211g_rates = 1;
- j++;
- }
- range->num_bitrates = j;
- } else
- range->num_bitrates = 0;
-
- /* fill in 802.11g rates */
- if (has_80211g_rates) {
- num = range->num_bitrates;
- for (i = 0; i < ARRAY_SIZE(rates_80211g); i++) {
- for (j = 0; j < num; j++) {
- if (range->bitrate[j] ==
- rates_80211g[i] * 1000000)
- break;
- }
- if (j == num)
- range->bitrate[range->num_bitrates++] =
- rates_80211g[i] * 1000000;
- if (range->num_bitrates == IW_MAX_BITRATES)
- break;
- }
+ /* Wait before retrieving scan results from device */
+ queue_delayed_work(priv->workqueue, &priv->scan_work,
+ SCAN_DELAY_JIFFIES);
+ }
- /* estimated max real througput in bps */
- range->throughput = 54 * 1000 * 1000 / 2;
+ return ret;
+}
- /* ~35% more with afterburner */
- if (priv->param_afterburner)
- range->throughput = range->throughput / 100 * 135;
- } else {
- /* estimated max real througput in bps */
- range->throughput = 11 * 1000 * 1000 / 2;
+
+static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
+ struct ndis_80211_bssid_ex *bssid)
+{
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct ieee80211_channel *channel;
+ s32 signal;
+ u64 timestamp;
+ u16 capability;
+ u16 beacon_interval;
+ struct ndis_80211_fixed_ies *fixed;
+ int ie_len, bssid_len;
+ u8 *ie;
+
+ /* parse bssid structure */
+ bssid_len = le32_to_cpu(bssid->length);
+
+ if (bssid_len < sizeof(struct ndis_80211_bssid_ex) +
+ sizeof(struct ndis_80211_fixed_ies))
+ return NULL;
+
+ fixed = (struct ndis_80211_fixed_ies *)bssid->ies;
+
+ ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
+ ie_len = min(bssid_len - (int)sizeof(*bssid),
+ (int)le32_to_cpu(bssid->ie_length));
+ ie_len -= sizeof(struct ndis_80211_fixed_ies);
+ if (ie_len < 0)
+ return NULL;
+
+ /* extract data for cfg80211_inform_bss */
+ channel = ieee80211_get_channel(priv->wdev.wiphy,
+ KHZ_TO_MHZ(le32_to_cpu(bssid->config.ds_config)));
+ if (!channel)
+ return NULL;
+
+ signal = level_to_qual(le32_to_cpu(bssid->rssi));
+ timestamp = le64_to_cpu(*(__le64 *)fixed->timestamp);
+ capability = le16_to_cpu(fixed->capabilities);
+ beacon_interval = le16_to_cpu(fixed->beacon_interval);
+
+ return cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac,
+ timestamp, capability, beacon_interval, ie, ie_len, signal,
+ GFP_KERNEL);
+}
+
+
+static int rndis_check_bssid_list(struct usbnet *usbdev)
+{
+ void *buf = NULL;
+ struct ndis_80211_bssid_list_ex *bssid_list;
+ struct ndis_80211_bssid_ex *bssid;
+ int ret = -EINVAL, len, count, bssid_len;
+
+ devdbg(usbdev, "check_bssid_list");
+
+ len = CONTROL_BUFFER_SIZE;
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto out;
}
- range->num_channels = 14;
+ ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
+ if (ret != 0)
+ goto out;
+
+ bssid_list = buf;
+ bssid = bssid_list->bssid;
+ bssid_len = le32_to_cpu(bssid->length);
+ count = le32_to_cpu(bssid_list->num_items);
+ devdbg(usbdev, "check_bssid_list: %d BSSIDs found", count);
+
+ while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
+ rndis_bss_info_update(usbdev, bssid);
- for (i = 0; (i < 14) && (i < IW_MAX_FREQUENCIES); i++) {
- range->freq[i].i = i + 1;
- range->freq[i].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
- range->freq[i].e = 1;
+ bssid = (void *)bssid + bssid_len;
+ bssid_len = le32_to_cpu(bssid->length);
+ count--;
}
- range->num_frequency = i;
- range->min_rts = 0;
- range->max_rts = 2347;
- range->min_frag = 256;
- range->max_frag = 2346;
+out:
+ kfree(buf);
+ return ret;
+}
+
- range->max_qual.qual = 100;
- range->max_qual.level = 154;
- range->max_qual.updated = IW_QUAL_QUAL_UPDATED
- | IW_QUAL_LEVEL_UPDATED
- | IW_QUAL_NOISE_INVALID;
+static void rndis_get_scan_results(struct work_struct *work)
+{
+ struct rndis_wext_private *priv =
+ container_of(work, struct rndis_wext_private, scan_work.work);
+ struct usbnet *usbdev = priv->usbdev;
+ int ret;
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = WIRELESS_EXT;
+ devdbg(usbdev, "get_scan_results");
- range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
- IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
- return 0;
+ ret = rndis_check_bssid_list(usbdev);
+
+ cfg80211_scan_done(priv->scan_request, ret < 0);
+
+ priv->scan_request = NULL;
}
-static int rndis_iw_get_name(struct net_device *dev,
+/*
+ * wireless extension handlers
+ */
+
+static int rndis_iw_commit(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
- struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
- strcpy(wrqu->name, priv->name);
+ /* dummy op */
return 0;
}
@@ -1422,55 +1522,6 @@ static int rndis_iw_get_auth(struct net_device *dev,
}
-static int rndis_iw_get_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
- switch (priv->infra_mode) {
- case ndis_80211_infra_adhoc:
- wrqu->mode = IW_MODE_ADHOC;
- break;
- case ndis_80211_infra_infra:
- wrqu->mode = IW_MODE_INFRA;
- break;
- /*case ndis_80211_infra_auto_unknown:*/
- default:
- wrqu->mode = IW_MODE_AUTO;
- break;
- }
- devdbg(usbdev, "SIOCGIWMODE: %08x", wrqu->mode);
- return 0;
-}
-
-
-static int rndis_iw_set_mode(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- int mode;
-
- devdbg(usbdev, "SIOCSIWMODE: %08x", wrqu->mode);
-
- switch (wrqu->mode) {
- case IW_MODE_ADHOC:
- mode = ndis_80211_infra_adhoc;
- break;
- case IW_MODE_INFRA:
- mode = ndis_80211_infra_infra;
- break;
- /*case IW_MODE_AUTO:*/
- default:
- mode = ndis_80211_infra_auto_unknown;
- break;
- }
-
- return set_infra_mode(usbdev, mode);
-}
-
-
static int rndis_iw_set_encode(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
@@ -1619,198 +1670,6 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
}
-static int rndis_iw_set_scan(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- union iwreq_data evt;
- int ret = -EINVAL;
- __le32 tmp;
-
- devdbg(usbdev, "SIOCSIWSCAN");
-
- if (wrqu->data.flags == 0) {
- tmp = cpu_to_le32(1);
- ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
- sizeof(tmp));
- evt.data.flags = 0;
- evt.data.length = 0;
- wireless_send_event(dev, SIOCGIWSCAN, &evt, NULL);
- }
- return ret;
-}
-
-
-static char *rndis_translate_scan(struct net_device *dev,
- struct iw_request_info *info, char *cev,
- char *end_buf,
- struct ndis_80211_bssid_ex *bssid)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- u8 *ie;
- char *current_val;
- int bssid_len, ie_len, i;
- u32 beacon, atim;
- struct iw_event iwe;
- unsigned char sbuf[32];
-
- bssid_len = le32_to_cpu(bssid->length);
-
- devdbg(usbdev, "BSSID %pM", bssid->mac);
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
- cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN);
-
- devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
- bssid->ssid.essid);
- iwe.cmd = SIOCGIWESSID;
- iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
- iwe.u.essid.flags = 1;
- cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid);
-
- devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
- iwe.cmd = SIOCGIWMODE;
- switch (le32_to_cpu(bssid->net_infra)) {
- case ndis_80211_infra_adhoc:
- iwe.u.mode = IW_MODE_ADHOC;
- break;
- case ndis_80211_infra_infra:
- iwe.u.mode = IW_MODE_INFRA;
- break;
- /*case ndis_80211_infra_auto_unknown:*/
- default:
- iwe.u.mode = IW_MODE_AUTO;
- break;
- }
- cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN);
-
- devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
- iwe.cmd = SIOCGIWFREQ;
- dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
- cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN);
-
- devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = level_to_qual(le32_to_cpu(bssid->rssi));
- iwe.u.qual.level = le32_to_cpu(bssid->rssi);
- iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
- | IW_QUAL_LEVEL_UPDATED
- | IW_QUAL_NOISE_INVALID;
- cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN);
-
- devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
- iwe.cmd = SIOCGIWENCODE;
- iwe.u.data.length = 0;
- if (le32_to_cpu(bssid->privacy) == ndis_80211_priv_accept_all)
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- else
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-
- cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
-
- devdbg(usbdev, "RATES:");
- current_val = cev + iwe_stream_lcp_len(info);
- iwe.cmd = SIOCGIWRATE;
- for (i = 0; i < sizeof(bssid->rates); i++) {
- if (bssid->rates[i] & 0x7f) {
- iwe.u.bitrate.value =
- ((bssid->rates[i] & 0x7f) *
- 500000);
- devdbg(usbdev, " %d", iwe.u.bitrate.value);
- current_val = iwe_stream_add_value(info, cev,
- current_val, end_buf, &iwe,
- IW_EV_PARAM_LEN);
- }
- }
-
- if ((current_val - cev) > iwe_stream_lcp_len(info))
- cev = current_val;
-
- beacon = le32_to_cpu(bssid->config.beacon_period);
- devdbg(usbdev, "BCN_INT %d", beacon);
- iwe.cmd = IWEVCUSTOM;
- snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
- iwe.u.data.length = strlen(sbuf);
- cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
-
- atim = le32_to_cpu(bssid->config.atim_window);
- devdbg(usbdev, "ATIM %d", atim);
- iwe.cmd = IWEVCUSTOM;
- snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
- iwe.u.data.length = strlen(sbuf);
- cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
-
- ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
- ie_len = min(bssid_len - (int)sizeof(*bssid),
- (int)le32_to_cpu(bssid->ie_length));
- ie_len -= sizeof(struct ndis_80211_fixed_ies);
- while (ie_len >= 2 && 2 + ie[1] <= ie_len) {
- if ((ie[0] == WLAN_EID_GENERIC && ie[1] >= 4 &&
- memcmp(ie + 2, "\x00\x50\xf2\x01", 4) == 0) ||
- ie[0] == WLAN_EID_RSN) {
- devdbg(usbdev, "IE: WPA%d",
- (ie[0] == WLAN_EID_RSN) ? 2 : 1);
- iwe.cmd = IWEVGENIE;
- /* arbitrary cut-off at 64 */
- iwe.u.data.length = min(ie[1] + 2, 64);
- cev = iwe_stream_add_point(info, cev, end_buf, &iwe, ie);
- }
-
- ie_len -= 2 + ie[1];
- ie += 2 + ie[1];
- }
-
- return cev;
-}
-
-
-static int rndis_iw_get_scan(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- void *buf = NULL;
- char *cev = extra;
- struct ndis_80211_bssid_list_ex *bssid_list;
- struct ndis_80211_bssid_ex *bssid;
- int ret = -EINVAL, len, count, bssid_len;
-
- devdbg(usbdev, "SIOCGIWSCAN");
-
- len = CONTROL_BUFFER_SIZE;
- buf = kmalloc(len, GFP_KERNEL);
- if (!buf) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
-
- if (ret != 0)
- goto out;
-
- bssid_list = buf;
- bssid = bssid_list->bssid;
- bssid_len = le32_to_cpu(bssid->length);
- count = le32_to_cpu(bssid_list->num_items);
- devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
-
- while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
- cev = rndis_translate_scan(dev, info, cev,
- extra + IW_SCAN_MAX_DATA, bssid);
- bssid = (void *)bssid + bssid_len;
- bssid_len = le32_to_cpu(bssid->length);
- count--;
- }
-
-out:
- wrqu->data.length = cev - extra;
- wrqu->data.flags = 0;
- kfree(buf);
- return ret;
-}
-
-
static int rndis_iw_set_genie(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
@@ -1936,39 +1795,6 @@ static int rndis_iw_get_frag(struct net_device *dev,
}
-static int rndis_iw_set_nick(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
- devdbg(usbdev, "SIOCSIWNICK");
-
- priv->nick_len = wrqu->data.length;
- if (priv->nick_len > 32)
- priv->nick_len = 32;
-
- memcpy(priv->nick, extra, priv->nick_len);
- return 0;
-}
-
-
-static int rndis_iw_get_nick(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
- wrqu->data.flags = 1;
- wrqu->data.length = priv->nick_len;
- memcpy(extra, priv->nick, priv->nick_len);
-
- devdbg(usbdev, "SIOCGIWNICK: '%s'", priv->nick);
-
- return 0;
-}
-
-
static int rndis_iw_set_freq(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
@@ -2165,20 +1991,18 @@ static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
static const iw_handler rndis_iw_handler[] =
{
IW_IOCTL(SIOCSIWCOMMIT) = rndis_iw_commit,
- IW_IOCTL(SIOCGIWNAME) = rndis_iw_get_name,
+ IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
IW_IOCTL(SIOCSIWFREQ) = rndis_iw_set_freq,
IW_IOCTL(SIOCGIWFREQ) = rndis_iw_get_freq,
- IW_IOCTL(SIOCSIWMODE) = rndis_iw_set_mode,
- IW_IOCTL(SIOCGIWMODE) = rndis_iw_get_mode,
- IW_IOCTL(SIOCGIWRANGE) = rndis_iw_get_range,
+ IW_IOCTL(SIOCSIWMODE) = (iw_handler) cfg80211_wext_siwmode,
+ IW_IOCTL(SIOCGIWMODE) = (iw_handler) cfg80211_wext_giwmode,
+ IW_IOCTL(SIOCGIWRANGE) = (iw_handler) cfg80211_wext_giwrange,
IW_IOCTL(SIOCSIWAP) = rndis_iw_set_bssid,
IW_IOCTL(SIOCGIWAP) = rndis_iw_get_bssid,
- IW_IOCTL(SIOCSIWSCAN) = rndis_iw_set_scan,
- IW_IOCTL(SIOCGIWSCAN) = rndis_iw_get_scan,
+ IW_IOCTL(SIOCSIWSCAN) = (iw_handler) cfg80211_wext_siwscan,
+ IW_IOCTL(SIOCGIWSCAN) = (iw_handler) cfg80211_wext_giwscan,
IW_IOCTL(SIOCSIWESSID) = rndis_iw_set_essid,
IW_IOCTL(SIOCGIWESSID) = rndis_iw_get_essid,
- IW_IOCTL(SIOCSIWNICKN) = rndis_iw_set_nick,
- IW_IOCTL(SIOCGIWNICKN) = rndis_iw_get_nick,
IW_IOCTL(SIOCGIWRATE) = rndis_iw_get_rate,
IW_IOCTL(SIOCSIWRTS) = rndis_iw_set_rts,
IW_IOCTL(SIOCGIWRTS) = rndis_iw_get_rts,
@@ -2338,12 +2162,6 @@ static int rndis_wext_get_caps(struct usbnet *usbdev)
break;
}
}
- if (priv->caps & CAP_MODE_80211A)
- strcat(priv->name, "a");
- if (priv->caps & CAP_MODE_80211B)
- strcat(priv->name, "b");
- if (priv->caps & CAP_MODE_80211G)
- strcat(priv->name, "g");
}
return retval;
@@ -2387,7 +2205,7 @@ static void rndis_update_wireless_stats(struct work_struct *work)
if (ret == 0) {
memset(&iwstats.qual, 0, sizeof(iwstats.qual));
iwstats.qual.qual = level_to_qual(le32_to_cpu(rssi));
- iwstats.qual.level = le32_to_cpu(rssi);
+ iwstats.qual.level = level_to_qual(le32_to_cpu(rssi));
iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
| IW_QUAL_LEVEL_UPDATED
| IW_QUAL_NOISE_INVALID;
@@ -2538,20 +2356,28 @@ static const struct net_device_ops rndis_wext_netdev_ops = {
static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
{
+ struct wiphy *wiphy;
struct rndis_wext_private *priv;
int retval, len;
__le32 tmp;
- /* allocate rndis private data */
- priv = kzalloc(sizeof(struct rndis_wext_private), GFP_KERNEL);
- if (!priv)
+ /* allocate wiphy and rndis private data
+ * NOTE: We only support a single virtual interface, so wiphy
+ * and wireless_dev are somewhat synonymous for this device.
+ */
+ wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wext_private));
+ if (!wiphy)
return -ENOMEM;
+ priv = wiphy_priv(wiphy);
+ usbdev->net->ieee80211_ptr = &priv->wdev;
+ priv->wdev.wiphy = wiphy;
+ priv->wdev.iftype = NL80211_IFTYPE_STATION;
+
/* These have to be initialized before calling generic_rndis_bind().
* Otherwise we'll be in big trouble in rndis_wext_early_init().
*/
usbdev->driver_priv = priv;
- strcpy(priv->name, "IEEE802.11");
usbdev->net->wireless_handlers = &rndis_iw_handlers;
priv->usbdev = usbdev;
@@ -2562,6 +2388,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
priv->workqueue = create_singlethread_workqueue("rndis_wlan");
INIT_WORK(&priv->work, rndis_wext_worker);
INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
+ INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results);
/* try bind rndis_host */
retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS);
@@ -2600,7 +2427,32 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
| IW_QUAL_QUAL_INVALID
| IW_QUAL_LEVEL_INVALID;
+ /* fill-out wiphy structure and register w/ cfg80211 */
+ memcpy(wiphy->perm_addr, usbdev->net->dev_addr, ETH_ALEN);
+ wiphy->privid = rndis_wiphy_privid;
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+ | BIT(NL80211_IFTYPE_ADHOC);
+ wiphy->max_scan_ssids = 1;
+
+ /* TODO: fill-out band information based on priv->caps */
rndis_wext_get_caps(usbdev);
+
+ memcpy(priv->channels, rndis_channels, sizeof(rndis_channels));
+ memcpy(priv->rates, rndis_rates, sizeof(rndis_rates));
+ priv->band.channels = priv->channels;
+ priv->band.n_channels = ARRAY_SIZE(rndis_channels);
+ priv->band.bitrates = priv->rates;
+ priv->band.n_bitrates = ARRAY_SIZE(rndis_rates);
+ wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
+
+ set_wiphy_dev(wiphy, &usbdev->udev->dev);
+
+ if (wiphy_register(wiphy)) {
+ retval = -ENODEV;
+ goto fail;
+ }
+
set_default_iw_params(usbdev);
/* turn radio on */
@@ -2615,11 +2467,12 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
fail:
cancel_delayed_work_sync(&priv->stats_work);
+ cancel_delayed_work_sync(&priv->scan_work);
cancel_work_sync(&priv->work);
flush_workqueue(priv->workqueue);
destroy_workqueue(priv->workqueue);
- kfree(priv);
+ wiphy_free(wiphy);
return retval;
}
@@ -2632,15 +2485,18 @@ static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf)
disassociate(usbdev, 0);
cancel_delayed_work_sync(&priv->stats_work);
+ cancel_delayed_work_sync(&priv->scan_work);
cancel_work_sync(&priv->work);
flush_workqueue(priv->workqueue);
destroy_workqueue(priv->workqueue);
if (priv && priv->wpa_ie_len)
kfree(priv->wpa_ie);
- kfree(priv);
rndis_unbind(usbdev, intf);
+
+ wiphy_unregister(priv->wdev.wiphy);
+ wiphy_free(priv->wdev.wiphy);
}
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index bfc5d9cf716e..18ee7d6c4028 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -77,6 +77,20 @@ config RT73USB
When compiled as a module, this driver will be called "rt73usb.ko".
+config RT2800USB
+ tristate "Ralink rt2800 (USB) support"
+ depends on USB
+ select RT2X00_LIB_USB
+ select RT2X00_LIB_HT
+ select RT2X00_LIB_FIRMWARE
+ select RT2X00_LIB_CRYPTO
+ select CRC_CCITT
+ ---help---
+ This adds support for rt2800 wireless chipset family.
+ Supported chips: RT2770, RT2870 & RT3070.
+
+ When compiled as a module, this driver will be called "rt2800usb.ko".
+
config RT2X00_LIB_PCI
tristate
select RT2X00_LIB
@@ -88,6 +102,9 @@ config RT2X00_LIB_USB
config RT2X00_LIB
tristate
+config RT2X00_LIB_HT
+ boolean
+
config RT2X00_LIB_FIRMWARE
boolean
select FW_LOADER
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index f22d808d8c51..bfc7226f0afe 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -8,6 +8,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o
rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o
+rt2x00lib-$(CONFIG_RT2X00_LIB_HT) += rt2x00ht.o
obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o
obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
@@ -17,3 +18,4 @@ obj-$(CONFIG_RT2500PCI) += rt2500pci.o
obj-$(CONFIG_RT61PCI) += rt61pci.o
obj-$(CONFIG_RT2500USB) += rt2500usb.o
obj-$(CONFIG_RT73USB) += rt73usb.o
+obj-$(CONFIG_RT2800USB) += rt2800usb.o
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 0f08773328c6..6f39ba662188 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1361,7 +1361,7 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
*/
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
- rt2x00_set_chip(rt2x00dev, RT2460, value, reg);
+ rt2x00_set_chip_rf(rt2x00dev, value, reg);
if (!rt2x00_rf(&rt2x00dev->chip, RF2420) &&
!rt2x00_rf(&rt2x00dev->chip, RF2421)) {
@@ -1580,7 +1580,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
- .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats,
.bss_info_changed = rt2x00mac_bss_info_changed,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 276a8232aaa0..906960f67b6c 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1525,7 +1525,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
*/
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
- rt2x00_set_chip(rt2x00dev, RT2560, value, reg);
+ rt2x00_set_chip_rf(rt2x00dev, value, reg);
if (!rt2x00_rf(&rt2x00dev->chip, RF2522) &&
!rt2x00_rf(&rt2x00dev->chip, RF2523) &&
@@ -1879,7 +1879,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
- .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats,
.bss_info_changed = rt2x00mac_bss_info_changed,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 9e630e70fc97..1debb88bc60e 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1559,7 +1559,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
rt2x00_set_chip(rt2x00dev, RT2570, value, reg);
- if (!rt2x00_check_rev(&rt2x00dev->chip, 0)) {
+ if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0)) {
ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
return -ENODEV;
}
@@ -1908,7 +1908,6 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
- .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.set_key = rt2x00mac_set_key,
.get_stats = rt2x00mac_get_stats,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
new file mode 100644
index 000000000000..257bfb5483c9
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -0,0 +1,3071 @@
+/*
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.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.
+ */
+
+/*
+ Module: rt2800usb
+ Abstract: rt2800usb device specific routines.
+ Supported chipsets: RT2800U.
+ */
+
+#include <linux/crc-ccitt.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "rt2x00.h"
+#include "rt2x00usb.h"
+#include "rt2800usb.h"
+
+/*
+ * Allow hardware encryption to be disabled.
+ */
+static int modparam_nohwcrypt = 1;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+/*
+ * Register access.
+ * All access to the CSR registers will go through the methods
+ * rt2x00usb_register_read and rt2x00usb_register_write.
+ * BBP and RF register require indirect register access,
+ * and use the CSR registers BBPCSR and RFCSR to achieve this.
+ * These indirect registers work with busy bits,
+ * and we will try maximal REGISTER_BUSY_COUNT times to access
+ * the register while taking a REGISTER_BUSY_DELAY us delay
+ * between each attampt. When the busy bit is still set at that time,
+ * the access attempt is considered to have failed,
+ * and we will print an error.
+ * The _lock versions must be used if you already hold the csr_mutex
+ */
+#define WAIT_FOR_BBP(__dev, __reg) \
+ rt2x00usb_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
+#define WAIT_FOR_RFCSR(__dev, __reg) \
+ rt2x00usb_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg))
+#define WAIT_FOR_RF(__dev, __reg) \
+ rt2x00usb_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg))
+#define WAIT_FOR_MCU(__dev, __reg) \
+ rt2x00usb_regbusy_read((__dev), H2M_MAILBOX_CSR, \
+ H2M_MAILBOX_CSR_OWNER, (__reg))
+
+static void rt2800usb_bbp_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u8 value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the BBP becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_VALUE, value);
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 0);
+
+ rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_bbp_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, u8 *value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the BBP becomes available, afterwards we
+ * can safely write the read request into the register.
+ * After the data has been written, we wait until hardware
+ * returns the correct value, if at any time the register
+ * doesn't become available in time, reg will be 0xffffffff
+ * which means we return 0xff to the caller.
+ */
+ if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 1);
+
+ rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+
+ WAIT_FOR_BBP(rt2x00dev, &reg);
+ }
+
+ *value = rt2x00_get_field32(reg, BBP_CSR_CFG_VALUE);
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_rfcsr_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u8 value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the RFCSR becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, RF_CSR_CFG_DATA, value);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 1);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+ rt2x00usb_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_rfcsr_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, u8 *value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the RFCSR becomes available, afterwards we
+ * can safely write the read request into the register.
+ * After the data has been written, we wait until hardware
+ * returns the correct value, if at any time the register
+ * doesn't become available in time, reg will be 0xffffffff
+ * which means we return 0xff to the caller.
+ */
+ if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 0);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+ rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+
+ WAIT_FOR_RFCSR(rt2x00dev, &reg);
+ }
+
+ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_rf_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u32 value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the RF becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_RF(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, RF_CSR_CFG0_REG_VALUE_BW, value);
+ rt2x00_set_field32(&reg, RF_CSR_CFG0_STANDBYMODE, 0);
+ rt2x00_set_field32(&reg, RF_CSR_CFG0_SEL, 0);
+ rt2x00_set_field32(&reg, RF_CSR_CFG0_BUSY, 1);
+
+ rt2x00usb_register_write_lock(rt2x00dev, RF_CSR_CFG0, reg);
+ rt2x00_rf_write(rt2x00dev, word, value);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_mcu_request(struct rt2x00_dev *rt2x00dev,
+ const u8 command, const u8 token,
+ const u8 arg0, const u8 arg1)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the MCU becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_MCU(rt2x00dev, &reg)) {
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_OWNER, 1);
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
+ rt2x00usb_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
+
+ reg = 0;
+ rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
+ rt2x00usb_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+static const struct rt2x00debug rt2800usb_rt2x00debug = {
+ .owner = THIS_MODULE,
+ .csr = {
+ .read = rt2x00usb_register_read,
+ .write = rt2x00usb_register_write,
+ .flags = RT2X00DEBUGFS_OFFSET,
+ .word_base = CSR_REG_BASE,
+ .word_size = sizeof(u32),
+ .word_count = CSR_REG_SIZE / sizeof(u32),
+ },
+ .eeprom = {
+ .read = rt2x00_eeprom_read,
+ .write = rt2x00_eeprom_write,
+ .word_base = EEPROM_BASE,
+ .word_size = sizeof(u16),
+ .word_count = EEPROM_SIZE / sizeof(u16),
+ },
+ .bbp = {
+ .read = rt2800usb_bbp_read,
+ .write = rt2800usb_bbp_write,
+ .word_base = BBP_BASE,
+ .word_size = sizeof(u8),
+ .word_count = BBP_SIZE / sizeof(u8),
+ },
+ .rf = {
+ .read = rt2x00_rf_read,
+ .write = rt2800usb_rf_write,
+ .word_base = RF_BASE,
+ .word_size = sizeof(u32),
+ .word_count = RF_SIZE / sizeof(u32),
+ },
+};
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt2800usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
+ return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
+}
+#else
+#define rt2800usb_rfkill_poll NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+#ifdef CONFIG_RT2X00_LIB_LEDS
+static void rt2800usb_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct rt2x00_led *led =
+ container_of(led_cdev, struct rt2x00_led, led_dev);
+ unsigned int enabled = brightness != LED_OFF;
+ unsigned int bg_mode =
+ (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
+ unsigned int polarity =
+ rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
+ EEPROM_FREQ_LED_POLARITY);
+ unsigned int ledmode =
+ rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
+ EEPROM_FREQ_LED_MODE);
+
+ if (led->type == LED_TYPE_RADIO) {
+ rt2800usb_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+ enabled ? 0x20 : 0);
+ } else if (led->type == LED_TYPE_ASSOC) {
+ rt2800usb_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+ enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20);
+ } else if (led->type == LED_TYPE_QUALITY) {
+ /*
+ * The brightness is divided into 6 levels (0 - 5),
+ * The specs tell us the following levels:
+ * 0, 1 ,3, 7, 15, 31
+ * to determine the level in a simple way we can simply
+ * work with bitshifting:
+ * (1 << level) - 1
+ */
+ rt2800usb_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
+ (1 << brightness / (LED_FULL / 6)) - 1,
+ polarity);
+ }
+}
+
+static int rt2800usb_blink_set(struct led_classdev *led_cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct rt2x00_led *led =
+ container_of(led_cdev, struct rt2x00_led, led_dev);
+ u32 reg;
+
+ rt2x00usb_register_read(led->rt2x00dev, LED_CFG, &reg);
+ rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, *delay_on);
+ rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, *delay_off);
+ rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
+ rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
+ rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 12);
+ rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
+ rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
+ rt2x00usb_register_write(led->rt2x00dev, LED_CFG, reg);
+
+ return 0;
+}
+
+static void rt2800usb_init_led(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_led *led,
+ enum led_type type)
+{
+ led->rt2x00dev = rt2x00dev;
+ led->type = type;
+ led->led_dev.brightness_set = rt2800usb_brightness_set;
+ led->led_dev.blink_set = rt2800usb_blink_set;
+ led->flags = LED_INITIALIZED;
+}
+#endif /* CONFIG_RT2X00_LIB_LEDS */
+
+/*
+ * Configuration handlers.
+ */
+static void rt2800usb_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_crypto *crypto,
+ struct ieee80211_key_conf *key)
+{
+ struct mac_wcid_entry wcid_entry;
+ struct mac_iveiv_entry iveiv_entry;
+ u32 offset;
+ u32 reg;
+
+ offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
+
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
+ !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
+ (crypto->cmd == SET_KEY) * crypto->cipher);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
+ (crypto->cmd == SET_KEY) * crypto->bssidx);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
+ rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+ offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
+
+ memset(&iveiv_entry, 0, sizeof(iveiv_entry));
+ if ((crypto->cipher == CIPHER_TKIP) ||
+ (crypto->cipher == CIPHER_TKIP_NO_MIC) ||
+ (crypto->cipher == CIPHER_AES))
+ iveiv_entry.iv[3] |= 0x20;
+ iveiv_entry.iv[3] |= key->keyidx << 6;
+ rt2x00usb_register_multiwrite(rt2x00dev, offset,
+ &iveiv_entry, sizeof(iveiv_entry));
+
+ offset = MAC_WCID_ENTRY(key->hw_key_idx);
+
+ memset(&wcid_entry, 0, sizeof(wcid_entry));
+ if (crypto->cmd == SET_KEY)
+ memcpy(&wcid_entry, crypto->address, ETH_ALEN);
+ rt2x00usb_register_multiwrite(rt2x00dev, offset,
+ &wcid_entry, sizeof(wcid_entry));
+}
+
+static int rt2800usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_crypto *crypto,
+ struct ieee80211_key_conf *key)
+{
+ struct hw_key_entry key_entry;
+ struct rt2x00_field32 field;
+ int timeout;
+ u32 offset;
+ u32 reg;
+
+ if (crypto->cmd == SET_KEY) {
+ key->hw_key_idx = (4 * crypto->bssidx) + key->keyidx;
+
+ memcpy(key_entry.key, crypto->key,
+ sizeof(key_entry.key));
+ memcpy(key_entry.tx_mic, crypto->tx_mic,
+ sizeof(key_entry.tx_mic));
+ memcpy(key_entry.rx_mic, crypto->rx_mic,
+ sizeof(key_entry.rx_mic));
+
+ offset = SHARED_KEY_ENTRY(key->hw_key_idx);
+ timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
+ rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT,
+ offset, &key_entry,
+ sizeof(key_entry),
+ timeout);
+ }
+
+ /*
+ * The cipher types are stored over multiple registers
+ * starting with SHARED_KEY_MODE_BASE each word will have
+ * 32 bits and contains the cipher types for 2 bssidx each.
+ * Using the correct defines correctly will cause overhead,
+ * so just calculate the correct offset.
+ */
+ field.bit_offset = 4 * (key->hw_key_idx % 8);
+ field.bit_mask = 0x7 << field.bit_offset;
+
+ offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
+
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, field,
+ (crypto->cmd == SET_KEY) * crypto->cipher);
+ rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+ /*
+ * Update WCID information
+ */
+ rt2800usb_config_wcid_attr(rt2x00dev, crypto, key);
+
+ return 0;
+}
+
+static int rt2800usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_crypto *crypto,
+ struct ieee80211_key_conf *key)
+{
+ struct hw_key_entry key_entry;
+ int timeout;
+ u32 offset;
+
+ if (crypto->cmd == SET_KEY) {
+ /*
+ * 1 pairwise key is possible per AID, this means that the AID
+ * equals our hw_key_idx. Make sure the WCID starts _after_ the
+ * last possible shared key entry.
+ */
+ if (crypto->aid > (256 - 32))
+ return -ENOSPC;
+
+ key->hw_key_idx = 32 + crypto->aid;
+
+ memcpy(key_entry.key, crypto->key,
+ sizeof(key_entry.key));
+ memcpy(key_entry.tx_mic, crypto->tx_mic,
+ sizeof(key_entry.tx_mic));
+ memcpy(key_entry.rx_mic, crypto->rx_mic,
+ sizeof(key_entry.rx_mic));
+
+ offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
+ timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
+ rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT,
+ offset, &key_entry,
+ sizeof(key_entry),
+ timeout);
+ }
+
+ /*
+ * Update WCID information
+ */
+ rt2800usb_config_wcid_attr(rt2x00dev, crypto, key);
+
+ return 0;
+}
+
+static void rt2800usb_config_filter(struct rt2x00_dev *rt2x00dev,
+ const unsigned int filter_flags)
+{
+ u32 reg;
+
+ /*
+ * Start configuration steps.
+ * Note that the version error will always be dropped
+ * and broadcast frames will always be accepted since
+ * there is no filter for it at this time.
+ */
+ rt2x00usb_register_read(rt2x00dev, RX_FILTER_CFG, &reg);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CRC_ERROR,
+ !(filter_flags & FIF_FCSFAIL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PHY_ERROR,
+ !(filter_flags & FIF_PLCPFAIL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_TO_ME,
+ !(filter_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_VER_ERROR, 1);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_MULTICAST,
+ !(filter_flags & FIF_ALLMULTI));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BROADCAST, 0);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_DUPLICATE, 1);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END_ACK,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_ACK,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CTS,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_RTS,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PSPOLL,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BA, 1);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BAR, 0);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CNTL,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00usb_register_write(rt2x00dev, RX_FILTER_CFG, reg);
+}
+
+static void rt2800usb_config_intf(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_intf *intf,
+ struct rt2x00intf_conf *conf,
+ const unsigned int flags)
+{
+ unsigned int beacon_base;
+ u32 reg;
+
+ if (flags & CONFIG_UPDATE_TYPE) {
+ /*
+ * Clear current synchronisation setup.
+ * For the Beacon base registers we only need to clear
+ * the first byte since that byte contains the VALID and OWNER
+ * bits which (when set to 0) will invalidate the entire beacon.
+ */
+ beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
+ rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
+
+ /*
+ * Enable synchronisation.
+ */
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ }
+
+ if (flags & CONFIG_UPDATE_MAC) {
+ reg = le32_to_cpu(conf->mac[1]);
+ rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
+ conf->mac[1] = cpu_to_le32(reg);
+
+ rt2x00usb_register_multiwrite(rt2x00dev, MAC_ADDR_DW0,
+ conf->mac, sizeof(conf->mac));
+ }
+
+ if (flags & CONFIG_UPDATE_BSSID) {
+ reg = le32_to_cpu(conf->bssid[1]);
+ rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 0);
+ rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
+ conf->bssid[1] = cpu_to_le32(reg);
+
+ rt2x00usb_register_multiwrite(rt2x00dev, MAC_BSSID_DW0,
+ conf->bssid, sizeof(conf->bssid));
+ }
+}
+
+static void rt2800usb_config_erp(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_erp *erp)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT,
+ DIV_ROUND_UP(erp->ack_timeout, erp->slot_time));
+ rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
+ !!erp->short_preamble);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE,
+ !!erp->short_preamble);
+ rt2x00usb_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL,
+ erp->cts_protection ? 2 : 0);
+ rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, LEGACY_BASIC_RATE,
+ erp->basic_rates);
+ rt2x00usb_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+
+ rt2x00usb_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
+ rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time);
+ rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
+ rt2x00usb_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, erp->sifs);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, erp->sifs);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
+ rt2x00usb_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
+}
+
+static void rt2800usb_config_ant(struct rt2x00_dev *rt2x00dev,
+ struct antenna_setup *ant)
+{
+ u8 r1;
+ u8 r3;
+
+ rt2800usb_bbp_read(rt2x00dev, 1, &r1);
+ rt2800usb_bbp_read(rt2x00dev, 3, &r3);
+
+ /*
+ * Configure the TX antenna.
+ */
+ switch ((int)ant->tx) {
+ case 1:
+ rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
+ break;
+ case 2:
+ rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
+ break;
+ case 3:
+ /* Do nothing */
+ break;
+ }
+
+ /*
+ * Configure the RX antenna.
+ */
+ switch ((int)ant->rx) {
+ case 1:
+ rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
+ break;
+ case 2:
+ rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
+ break;
+ case 3:
+ rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2);
+ break;
+ }
+
+ rt2800usb_bbp_write(rt2x00dev, 3, r3);
+ rt2800usb_bbp_write(rt2x00dev, 1, r1);
+}
+
+static void rt2800usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ u16 eeprom;
+ short lna_gain;
+
+ if (libconf->rf.channel <= 14) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG);
+ } else if (libconf->rf.channel <= 64) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
+ } else if (libconf->rf.channel <= 128) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1);
+ } else {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2);
+ }
+
+ rt2x00dev->lna_gain = lna_gain;
+}
+
+static void rt2800usb_config_channel_rt2x(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
+{
+ rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
+
+ if (rt2x00dev->default_ant.tx == 1)
+ rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1);
+
+ if (rt2x00dev->default_ant.rx == 1) {
+ rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1);
+ rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
+ } else if (rt2x00dev->default_ant.rx == 2)
+ rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
+
+ if (rf->channel > 14) {
+ /*
+ * When TX power is below 0, we should increase it by 7 to
+ * make it a positive value (Minumum value is -7).
+ * However this means that values between 0 and 7 have
+ * double meaning, and we should set a 7DBm boost flag.
+ */
+ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST,
+ (info->tx_power1 >= 0));
+
+ if (info->tx_power1 < 0)
+ info->tx_power1 += 7;
+
+ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A,
+ TXPOWER_A_TO_DEV(info->tx_power1));
+
+ rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST,
+ (info->tx_power2 >= 0));
+
+ if (info->tx_power2 < 0)
+ info->tx_power2 += 7;
+
+ rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A,
+ TXPOWER_A_TO_DEV(info->tx_power2));
+ } else {
+ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G,
+ TXPOWER_G_TO_DEV(info->tx_power1));
+ rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G,
+ TXPOWER_G_TO_DEV(info->tx_power2));
+ }
+
+ rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf));
+
+ rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
+ rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
+ rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+ rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+ udelay(200);
+
+ rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
+ rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
+ rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
+ rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+ udelay(200);
+
+ rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
+ rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
+ rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+ rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
+}
+
+static void rt2800usb_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
+{
+ u8 rfcsr;
+
+ rt2800usb_rfcsr_write(rt2x00dev, 2, rf->rf1);
+ rt2800usb_rfcsr_write(rt2x00dev, 2, rf->rf3);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 6, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2);
+ rt2800usb_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 12, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+ TXPOWER_G_TO_DEV(info->tx_power1));
+ rt2800usb_rfcsr_write(rt2x00dev, 12, rfcsr);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 23, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
+ rt2800usb_rfcsr_write(rt2x00dev, 23, rfcsr);
+
+ rt2800usb_rfcsr_write(rt2x00dev, 24,
+ rt2x00dev->calibration[conf_is_ht40(conf)]);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 23, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
+ rt2800usb_rfcsr_write(rt2x00dev, 23, rfcsr);
+}
+
+static void rt2800usb_config_channel(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
+{
+ u32 reg;
+ unsigned int tx_pin;
+ u8 bbp;
+
+ if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
+ rt2800usb_config_channel_rt2x(rt2x00dev, conf, rf, info);
+ else
+ rt2800usb_config_channel_rt3x(rt2x00dev, conf, rf, info);
+
+ /*
+ * Change BBP settings
+ */
+ rt2800usb_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+ rt2800usb_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+ rt2800usb_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+ rt2800usb_bbp_write(rt2x00dev, 86, 0);
+
+ if (rf->channel <= 14) {
+ if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
+ rt2800usb_bbp_write(rt2x00dev, 82, 0x62);
+ rt2800usb_bbp_write(rt2x00dev, 75, 0x46);
+ } else {
+ rt2800usb_bbp_write(rt2x00dev, 82, 0x84);
+ rt2800usb_bbp_write(rt2x00dev, 75, 0x50);
+ }
+ } else {
+ rt2800usb_bbp_write(rt2x00dev, 82, 0xf2);
+
+ if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
+ rt2800usb_bbp_write(rt2x00dev, 75, 0x46);
+ else
+ rt2800usb_bbp_write(rt2x00dev, 75, 0x50);
+ }
+
+ rt2x00usb_register_read(rt2x00dev, TX_BAND_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_BAND_CFG_HT40_PLUS, conf_is_ht40_plus(conf));
+ rt2x00_set_field32(&reg, TX_BAND_CFG_A, rf->channel > 14);
+ rt2x00_set_field32(&reg, TX_BAND_CFG_BG, rf->channel <= 14);
+ rt2x00usb_register_write(rt2x00dev, TX_BAND_CFG, reg);
+
+ tx_pin = 0;
+
+ /* Turn on unused PA or LNA when not using 1T or 1R */
+ if (rt2x00dev->default_ant.tx != 1) {
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
+ }
+
+ /* Turn on unused PA or LNA when not using 1T or 1R */
+ if (rt2x00dev->default_ant.rx != 1) {
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
+ }
+
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
+
+ rt2x00usb_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+
+ rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
+ rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
+ rt2800usb_bbp_write(rt2x00dev, 4, bbp);
+
+ rt2800usb_bbp_read(rt2x00dev, 3, &bbp);
+ rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
+ rt2800usb_bbp_write(rt2x00dev, 3, bbp);
+
+ if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+ if (conf_is_ht40(conf)) {
+ rt2800usb_bbp_write(rt2x00dev, 69, 0x1a);
+ rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
+ rt2800usb_bbp_write(rt2x00dev, 73, 0x16);
+ } else {
+ rt2800usb_bbp_write(rt2x00dev, 69, 0x16);
+ rt2800usb_bbp_write(rt2x00dev, 70, 0x08);
+ rt2800usb_bbp_write(rt2x00dev, 73, 0x11);
+ }
+ }
+
+ msleep(1);
+}
+
+static void rt2800usb_config_txpower(struct rt2x00_dev *rt2x00dev,
+ const int txpower)
+{
+ u32 reg;
+ u32 value = TXPOWER_G_TO_DEV(txpower);
+ u8 r1;
+
+ rt2800usb_bbp_read(rt2x00dev, 1, &r1);
+ rt2x00_set_field8(&reg, BBP1_TX_POWER, 0);
+ rt2800usb_bbp_write(rt2x00dev, 1, r1);
+
+ rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_0, &reg);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_1MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_2MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_55MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_11MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_6MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_9MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_12MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_18MBS, value);
+ rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_0, reg);
+
+ rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_1, &reg);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_24MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_36MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_48MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_54MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS0, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS1, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS2, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS3, value);
+ rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_1, reg);
+
+ rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_2, &reg);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS4, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS5, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS6, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS7, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS8, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS9, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS10, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS11, value);
+ rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_2, reg);
+
+ rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_3, &reg);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS12, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS13, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS14, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS15, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN1, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN2, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN3, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN4, value);
+ rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_3, reg);
+
+ rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_4, &reg);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN5, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN6, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN7, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN8, value);
+ rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_4, reg);
+}
+
+static void rt2800usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, TX_RTY_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT,
+ libconf->conf->short_frame_max_tx_count);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT,
+ libconf->conf->long_frame_max_tx_count);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
+ rt2x00usb_register_write(rt2x00dev, TX_RTY_CFG, reg);
+}
+
+static void rt2800usb_config_duration(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
+ libconf->conf->beacon_int * 16);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+}
+
+static void rt2800usb_config_ps(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ enum dev_state state =
+ (libconf->conf->flags & IEEE80211_CONF_PS) ?
+ STATE_SLEEP : STATE_AWAKE;
+ u32 reg;
+
+ if (state == STATE_SLEEP) {
+ rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0);
+
+ rt2x00usb_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 5);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE,
+ libconf->conf->listen_interval - 1);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 1);
+ rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
+
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+ } else {
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+
+ rt2x00usb_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 0);
+ rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
+ }
+}
+
+static void rt2800usb_config(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf,
+ const unsigned int flags)
+{
+ /* Always recalculate LNA gain before changing configuration */
+ rt2800usb_config_lna_gain(rt2x00dev, libconf);
+
+ if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
+ rt2800usb_config_channel(rt2x00dev, libconf->conf,
+ &libconf->rf, &libconf->channel);
+ if (flags & IEEE80211_CONF_CHANGE_POWER)
+ rt2800usb_config_txpower(rt2x00dev, libconf->conf->power_level);
+ if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+ rt2800usb_config_retry_limit(rt2x00dev, libconf);
+ if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
+ rt2800usb_config_duration(rt2x00dev, libconf);
+ if (flags & IEEE80211_CONF_CHANGE_PS)
+ rt2800usb_config_ps(rt2x00dev, libconf);
+}
+
+/*
+ * Link tuning
+ */
+static void rt2800usb_link_stats(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
+{
+ u32 reg;
+
+ /*
+ * Update FCS error count from register.
+ */
+ rt2x00usb_register_read(rt2x00dev, RX_STA_CNT0, &reg);
+ qual->rx_failed = rt2x00_get_field32(reg, RX_STA_CNT0_CRC_ERR);
+}
+
+static u8 rt2800usb_get_default_vgc(struct rt2x00_dev *rt2x00dev)
+{
+ if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
+ if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION)
+ return 0x1c + (2 * rt2x00dev->lna_gain);
+ else
+ return 0x2e + rt2x00dev->lna_gain;
+ }
+
+ if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
+ return 0x32 + (rt2x00dev->lna_gain * 5) / 3;
+ else
+ return 0x3a + (rt2x00dev->lna_gain * 5) / 3;
+}
+
+static inline void rt2800usb_set_vgc(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, u8 vgc_level)
+{
+ if (qual->vgc_level != vgc_level) {
+ rt2800usb_bbp_write(rt2x00dev, 66, vgc_level);
+ qual->vgc_level = vgc_level;
+ qual->vgc_level_reg = vgc_level;
+ }
+}
+
+static void rt2800usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
+{
+ rt2800usb_set_vgc(rt2x00dev, qual,
+ rt2800usb_get_default_vgc(rt2x00dev));
+}
+
+static void rt2800usb_link_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count)
+{
+ if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION)
+ return;
+
+ /*
+ * When RSSI is better then -80 increase VGC level with 0x10
+ */
+ rt2800usb_set_vgc(rt2x00dev, qual,
+ rt2800usb_get_default_vgc(rt2x00dev) +
+ ((qual->rssi > -80) * 0x10));
+}
+
+/*
+ * Firmware functions
+ */
+static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
+{
+ return FIRMWARE_RT2870;
+}
+
+static bool rt2800usb_check_crc(const u8 *data, const size_t len)
+{
+ u16 fw_crc;
+ u16 crc;
+
+ /*
+ * The last 2 bytes in the firmware array are the crc checksum itself,
+ * this means that we should never pass those 2 bytes to the crc
+ * algorithm.
+ */
+ fw_crc = (data[len - 2] << 8 | data[len - 1]);
+
+ /*
+ * Use the crc ccitt algorithm.
+ * This will return the same value as the legacy driver which
+ * used bit ordering reversion on the both the firmware bytes
+ * before input input as well as on the final output.
+ * Obviously using crc ccitt directly is much more efficient.
+ */
+ crc = crc_ccitt(~0, data, len - 2);
+
+ /*
+ * There is a small difference between the crc-itu-t + bitrev and
+ * the crc-ccitt crc calculation. In the latter method the 2 bytes
+ * will be swapped, use swab16 to convert the crc to the correct
+ * value.
+ */
+ crc = swab16(crc);
+
+ return fw_crc == crc;
+}
+
+static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
+{
+ u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
+ size_t offset = 0;
+
+ /*
+ * Firmware files:
+ * There are 2 variations of the rt2870 firmware.
+ * a) size: 4kb
+ * b) size: 8kb
+ * Note that (b) contains 2 seperate firmware blobs of 4k
+ * within the file. The first blob is the same firmware as (a),
+ * but the second blob is for the additional chipsets.
+ */
+ if (len != 4096 && len != 8192)
+ return FW_BAD_LENGTH;
+
+ /*
+ * Check if we need the upper 4kb firmware data or not.
+ */
+ if ((len == 4096) &&
+ (chipset != 0x2860) &&
+ (chipset != 0x2872) &&
+ (chipset != 0x3070))
+ return FW_BAD_VERSION;
+
+ /*
+ * 8kb firmware files must be checked as if it were
+ * 2 seperate firmware files.
+ */
+ while (offset < len) {
+ if (!rt2800usb_check_crc(data + offset, 4096))
+ return FW_BAD_CRC;
+
+ offset += 4096;
+ }
+
+ return FW_OK;
+}
+
+static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
+{
+ unsigned int i;
+ int status;
+ u32 reg;
+ u32 offset;
+ u32 length;
+ u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
+
+ /*
+ * Check which section of the firmware we need.
+ */
+ if ((chipset == 0x2860) ||
+ (chipset == 0x2872) ||
+ (chipset == 0x3070)) {
+ offset = 0;
+ length = 4096;
+ } else {
+ offset = 4096;
+ length = 4096;
+ }
+
+ /*
+ * Wait for stable hardware.
+ */
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+ if (reg && reg != ~0)
+ break;
+ msleep(1);
+ }
+
+ if (i == REGISTER_BUSY_COUNT) {
+ ERROR(rt2x00dev, "Unstable hardware.\n");
+ return -EBUSY;
+ }
+
+ /*
+ * Write firmware to device.
+ */
+ rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT,
+ FIRMWARE_IMAGE_BASE,
+ data + offset, length,
+ REGISTER_TIMEOUT32(length));
+
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+
+ /*
+ * Send firmware request to device to load firmware,
+ * we need to specify a long timeout time.
+ */
+ status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE,
+ 0, USB_MODE_FIRMWARE,
+ REGISTER_TIMEOUT_FIRMWARE);
+ if (status < 0) {
+ ERROR(rt2x00dev, "Failed to write Firmware to device.\n");
+ return status;
+ }
+
+ msleep(10);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+
+ /*
+ * Send signal to firmware during boot time.
+ */
+ rt2800usb_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
+
+ if ((chipset == 0x3070) ||
+ (chipset == 0x3071) ||
+ (chipset == 0x3572)) {
+ udelay(200);
+ rt2800usb_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
+ udelay(10);
+ }
+
+ /*
+ * Wait for device to stabilize.
+ */
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+ if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
+ break;
+ msleep(1);
+ }
+
+ if (i == REGISTER_BUSY_COUNT) {
+ ERROR(rt2x00dev, "PBF system register not ready.\n");
+ return -EBUSY;
+ }
+
+ /*
+ * Initialize firmware.
+ */
+ rt2x00usb_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+ msleep(1);
+
+ return 0;
+}
+
+/*
+ * Initialization functions.
+ */
+static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+ unsigned int i;
+
+ /*
+ * Wait untill BBP and RF are ready.
+ */
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+ if (reg && reg != ~0)
+ break;
+ msleep(1);
+ }
+
+ if (i == REGISTER_BUSY_COUNT) {
+ ERROR(rt2x00dev, "Unstable hardware.\n");
+ return -EBUSY;
+ }
+
+ rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+ rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
+
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
+
+ rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+ USB_MODE_RESET, REGISTER_TIMEOUT);
+
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+ rt2x00usb_register_read(rt2x00dev, BCN_OFFSET0, &reg);
+ rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
+ rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1, 0xe8); /* 0x3a00 */
+ rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2, 0xf0); /* 0x3c00 */
+ rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3, 0xf8); /* 0x3e00 */
+ rt2x00usb_register_write(rt2x00dev, BCN_OFFSET0, reg);
+
+ rt2x00usb_register_read(rt2x00dev, BCN_OFFSET1, &reg);
+ rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4, 0xc8); /* 0x3200 */
+ rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5, 0xd0); /* 0x3400 */
+ rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6, 0x77); /* 0x1dc0 */
+ rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7, 0x6f); /* 0x1bc0 */
+ rt2x00usb_register_write(rt2x00dev, BCN_OFFSET1, reg);
+
+ rt2x00usb_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
+ rt2x00usb_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+ if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
+ rt2x00usb_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+ rt2x00usb_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
+ rt2x00usb_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+ } else {
+ rt2x00usb_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
+ rt2x00usb_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+ }
+
+ rt2x00usb_register_read(rt2x00dev, TX_LINK_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB_LIFETIME, 32);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_MFB_ENABLE, 0);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_UMFS_ENABLE, 0);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_TX_MRQ_EN, 0);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_TX_RDG_EN, 0);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_TX_CF_ACK_EN, 1);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB, 0);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFS, 0);
+ rt2x00usb_register_write(rt2x00dev, TX_LINK_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
+ rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
+ rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
+ if (rt2x00_rev(&rt2x00dev->chip) >= RT2880E_VERSION &&
+ rt2x00_rev(&rt2x00dev->chip) < RT3070_VERSION)
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
+ else
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_PSDU, 0);
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
+ rt2x00usb_register_write(rt2x00dev, MAX_LEN_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
+
+ rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_AUTORESPONDER, 1);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MMODE, 0);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MREF, 0);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
+ rt2x00usb_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 8);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00usb_register_write(rt2x00dev, CCK_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 8);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+ rt2x00usb_register_write(rt2x00dev, MM20_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00usb_register_write(rt2x00dev, MM40_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+ rt2x00usb_register_write(rt2x00dev, GF20_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00usb_register_write(rt2x00dev, GF40_PROT_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+
+ rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 3);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_BIG_ENDIAN, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_HDR_SCATTER, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_HDR_SEG_LEN, 0);
+ rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f);
+ rt2x00usb_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
+
+ rt2x00usb_register_read(rt2x00dev, TX_RTS_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
+ rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
+ IEEE80211_MAX_RTS_THRESHOLD);
+ rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_FBK_EN, 0);
+ rt2x00usb_register_write(rt2x00dev, TX_RTS_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
+ rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+
+ /*
+ * ASIC will keep garbage value after boot, clear encryption keys.
+ */
+ for (i = 0; i < 256; i++) {
+ u32 wcid[2] = { 0xffffffff, 0x00ffffff };
+ rt2x00usb_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
+ wcid, sizeof(wcid));
+
+ rt2x00usb_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1);
+ rt2x00usb_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
+ }
+
+ for (i = 0; i < 16; i++)
+ rt2x00usb_register_write(rt2x00dev,
+ SHARED_KEY_MODE_ENTRY(i), 0);
+
+ /*
+ * Clear all beacons
+ * For the Beacon base registers we only need to clear
+ * the first byte since that byte contains the VALID and OWNER
+ * bits which (when set to 0) will invalidate the entire beacon.
+ */
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE4, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE5, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE6, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
+
+ rt2x00usb_register_read(rt2x00dev, USB_CYC_CFG, &reg);
+ rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30);
+ rt2x00usb_register_write(rt2x00dev, USB_CYC_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, HT_FBK_CFG0, &reg);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS0FBK, 0);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS1FBK, 0);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS2FBK, 1);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS3FBK, 2);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS4FBK, 3);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS5FBK, 4);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS6FBK, 5);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS7FBK, 6);
+ rt2x00usb_register_write(rt2x00dev, HT_FBK_CFG0, reg);
+
+ rt2x00usb_register_read(rt2x00dev, HT_FBK_CFG1, &reg);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS8FBK, 8);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS9FBK, 8);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS10FBK, 9);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS11FBK, 10);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS12FBK, 11);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS13FBK, 12);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS14FBK, 13);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS15FBK, 14);
+ rt2x00usb_register_write(rt2x00dev, HT_FBK_CFG1, reg);
+
+ rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG0, &reg);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS0FBK, 8);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS1FBK, 8);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS2FBK, 3);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS3FBK, 10);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS4FBK, 11);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS5FBK, 12);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS6FBK, 13);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS7FBK, 14);
+ rt2x00usb_register_write(rt2x00dev, LG_FBK_CFG0, reg);
+
+ rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG1, &reg);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS0FBK, 0);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS1FBK, 0);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS2FBK, 1);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS3FBK, 2);
+ rt2x00usb_register_write(rt2x00dev, LG_FBK_CFG1, reg);
+
+ /*
+ * We must clear the error counters.
+ * These registers are cleared on read,
+ * so we may pass a useless variable to store the value.
+ */
+ rt2x00usb_register_read(rt2x00dev, RX_STA_CNT0, &reg);
+ rt2x00usb_register_read(rt2x00dev, RX_STA_CNT1, &reg);
+ rt2x00usb_register_read(rt2x00dev, RX_STA_CNT2, &reg);
+ rt2x00usb_register_read(rt2x00dev, TX_STA_CNT0, &reg);
+ rt2x00usb_register_read(rt2x00dev, TX_STA_CNT1, &reg);
+ rt2x00usb_register_read(rt2x00dev, TX_STA_CNT2, &reg);
+
+ return 0;
+}
+
+static int rt2800usb_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u32 reg;
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00usb_register_read(rt2x00dev, MAC_STATUS_CFG, &reg);
+ if (!rt2x00_get_field32(reg, MAC_STATUS_CFG_BBP_RF_BUSY))
+ return 0;
+
+ udelay(REGISTER_BUSY_DELAY);
+ }
+
+ ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n");
+ return -EACCES;
+}
+
+static int rt2800usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u8 value;
+
+ /*
+ * BBP was enabled after firmware was loaded,
+ * but we need to reactivate it now.
+ */
+ rt2x00usb_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+ msleep(1);
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2800usb_bbp_read(rt2x00dev, 0, &value);
+ if ((value != 0xff) && (value != 0x00))
+ return 0;
+ udelay(REGISTER_BUSY_DELAY);
+ }
+
+ ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
+ return -EACCES;
+}
+
+static int rt2800usb_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u16 eeprom;
+ u8 reg_id;
+ u8 value;
+
+ if (unlikely(rt2800usb_wait_bbp_rf_ready(rt2x00dev) ||
+ rt2800usb_wait_bbp_ready(rt2x00dev)))
+ return -EACCES;
+
+ rt2800usb_bbp_write(rt2x00dev, 65, 0x2c);
+ rt2800usb_bbp_write(rt2x00dev, 66, 0x38);
+ rt2800usb_bbp_write(rt2x00dev, 69, 0x12);
+ rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
+ rt2800usb_bbp_write(rt2x00dev, 73, 0x10);
+ rt2800usb_bbp_write(rt2x00dev, 81, 0x37);
+ rt2800usb_bbp_write(rt2x00dev, 82, 0x62);
+ rt2800usb_bbp_write(rt2x00dev, 83, 0x6a);
+ rt2800usb_bbp_write(rt2x00dev, 84, 0x99);
+ rt2800usb_bbp_write(rt2x00dev, 86, 0x00);
+ rt2800usb_bbp_write(rt2x00dev, 91, 0x04);
+ rt2800usb_bbp_write(rt2x00dev, 92, 0x00);
+ rt2800usb_bbp_write(rt2x00dev, 103, 0x00);
+ rt2800usb_bbp_write(rt2x00dev, 105, 0x05);
+
+ if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+ rt2800usb_bbp_write(rt2x00dev, 69, 0x16);
+ rt2800usb_bbp_write(rt2x00dev, 73, 0x12);
+ }
+
+ if (rt2x00_rev(&rt2x00dev->chip) > RT2860D_VERSION) {
+ rt2800usb_bbp_write(rt2x00dev, 84, 0x19);
+ }
+
+ if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
+ rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
+ rt2800usb_bbp_write(rt2x00dev, 84, 0x99);
+ rt2800usb_bbp_write(rt2x00dev, 105, 0x05);
+ }
+
+ for (i = 0; i < EEPROM_BBP_SIZE; i++) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
+
+ if (eeprom != 0xffff && eeprom != 0x0000) {
+ reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
+ value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
+ rt2800usb_bbp_write(rt2x00dev, reg_id, value);
+ }
+ }
+
+ return 0;
+}
+
+static u8 rt2800usb_init_rx_filter(struct rt2x00_dev *rt2x00dev,
+ bool bw40, u8 rfcsr24, u8 filter_target)
+{
+ unsigned int i;
+ u8 bbp;
+ u8 rfcsr;
+ u8 passband;
+ u8 stopband;
+ u8 overtuned = 0;
+
+ rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
+
+ rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
+ rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40);
+ rt2800usb_bbp_write(rt2x00dev, 4, bbp);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 22, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1);
+ rt2800usb_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+ /*
+ * Set power & frequency of passband test tone
+ */
+ rt2800usb_bbp_write(rt2x00dev, 24, 0);
+
+ for (i = 0; i < 100; i++) {
+ rt2800usb_bbp_write(rt2x00dev, 25, 0x90);
+ msleep(1);
+
+ rt2800usb_bbp_read(rt2x00dev, 55, &passband);
+ if (passband)
+ break;
+ }
+
+ /*
+ * Set power & frequency of stopband test tone
+ */
+ rt2800usb_bbp_write(rt2x00dev, 24, 0x06);
+
+ for (i = 0; i < 100; i++) {
+ rt2800usb_bbp_write(rt2x00dev, 25, 0x90);
+ msleep(1);
+
+ rt2800usb_bbp_read(rt2x00dev, 55, &stopband);
+
+ if ((passband - stopband) <= filter_target) {
+ rfcsr24++;
+ overtuned += ((passband - stopband) == filter_target);
+ } else
+ break;
+
+ rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
+ }
+
+ rfcsr24 -= !!overtuned;
+
+ rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
+ return rfcsr24;
+}
+
+static int rt2800usb_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+{
+ u8 rfcsr;
+ u8 bbp;
+
+ if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
+ return 0;
+
+ /*
+ * Init RF calibration.
+ */
+ rt2800usb_rfcsr_read(rt2x00dev, 30, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+ rt2800usb_rfcsr_write(rt2x00dev, 30, rfcsr);
+ msleep(1);
+ rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
+ rt2800usb_rfcsr_write(rt2x00dev, 30, rfcsr);
+
+ rt2800usb_rfcsr_write(rt2x00dev, 4, 0x40);
+ rt2800usb_rfcsr_write(rt2x00dev, 5, 0x03);
+ rt2800usb_rfcsr_write(rt2x00dev, 6, 0x02);
+ rt2800usb_rfcsr_write(rt2x00dev, 7, 0x70);
+ rt2800usb_rfcsr_write(rt2x00dev, 9, 0x0f);
+ rt2800usb_rfcsr_write(rt2x00dev, 10, 0x71);
+ rt2800usb_rfcsr_write(rt2x00dev, 11, 0x21);
+ rt2800usb_rfcsr_write(rt2x00dev, 12, 0x7b);
+ rt2800usb_rfcsr_write(rt2x00dev, 14, 0x90);
+ rt2800usb_rfcsr_write(rt2x00dev, 15, 0x58);
+ rt2800usb_rfcsr_write(rt2x00dev, 16, 0xb3);
+ rt2800usb_rfcsr_write(rt2x00dev, 17, 0x92);
+ rt2800usb_rfcsr_write(rt2x00dev, 18, 0x2c);
+ rt2800usb_rfcsr_write(rt2x00dev, 19, 0x02);
+ rt2800usb_rfcsr_write(rt2x00dev, 20, 0xba);
+ rt2800usb_rfcsr_write(rt2x00dev, 21, 0xdb);
+ rt2800usb_rfcsr_write(rt2x00dev, 24, 0x16);
+ rt2800usb_rfcsr_write(rt2x00dev, 25, 0x01);
+ rt2800usb_rfcsr_write(rt2x00dev, 27, 0x03);
+ rt2800usb_rfcsr_write(rt2x00dev, 29, 0x1f);
+
+ /*
+ * Set RX Filter calibration for 20MHz and 40MHz
+ */
+ rt2x00dev->calibration[0] =
+ rt2800usb_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
+ rt2x00dev->calibration[1] =
+ rt2800usb_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
+
+ /*
+ * Set back to initial state
+ */
+ rt2800usb_bbp_write(rt2x00dev, 24, 0);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 22, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0);
+ rt2800usb_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+ /*
+ * set BBP back to BW20
+ */
+ rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
+ rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
+ rt2800usb_bbp_write(rt2x00dev, 4, bbp);
+
+ return 0;
+}
+
+/*
+ * Device state switch handlers.
+ */
+static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
+ enum dev_state state)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
+ (state == STATE_RADIO_RX_ON) ||
+ (state == STATE_RADIO_RX_ON_LINK));
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+}
+
+static int rt2800usb_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u32 reg;
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
+ !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
+ return 0;
+
+ msleep(1);
+ }
+
+ ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
+ return -EACCES;
+}
+
+static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+ u16 word;
+
+ /*
+ * Initialize all registers.
+ */
+ if (unlikely(rt2800usb_wait_wpdma_ready(rt2x00dev) ||
+ rt2800usb_init_registers(rt2x00dev) ||
+ rt2800usb_init_bbp(rt2x00dev) ||
+ rt2800usb_init_rfcsr(rt2x00dev)))
+ return -EIO;
+
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ udelay(50);
+
+ rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
+ rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+
+ rt2x00usb_register_read(rt2x00dev, USB_DMA_CFG, &reg);
+ rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
+ /* Don't use bulk in aggregation when working with USB 1.1 */
+ rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN,
+ (rt2x00dev->rx->usb_maxpacket == 512));
+ rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
+ /*
+ * Total room for RX frames in kilobytes, PBF might still exceed
+ * this limit so reduce the number to prevent errors.
+ */
+ rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
+ ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3);
+ rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
+ rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
+ rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ /*
+ * Initialize LED control
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
+ rt2800usb_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
+ rt2800usb_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
+ rt2800usb_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ return 0;
+}
+
+static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+ rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
+ rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+ rt2x00usb_register_write(rt2x00dev, TX_PIN_CFG, 0);
+
+ /* Wait for DMA, ignore error */
+ rt2800usb_wait_wpdma_ready(rt2x00dev);
+
+ rt2x00usb_disable_radio(rt2x00dev);
+}
+
+static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev,
+ enum dev_state state)
+{
+ if (state == STATE_AWAKE)
+ rt2800usb_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+ else
+ rt2800usb_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
+
+ return 0;
+}
+
+static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
+ enum dev_state state)
+{
+ int retval = 0;
+
+ switch (state) {
+ case STATE_RADIO_ON:
+ /*
+ * Before the radio can be enabled, the device first has
+ * to be woken up. After that it needs a bit of time
+ * to be fully awake and the radio can be enabled.
+ */
+ rt2800usb_set_state(rt2x00dev, STATE_AWAKE);
+ msleep(1);
+ retval = rt2800usb_enable_radio(rt2x00dev);
+ break;
+ case STATE_RADIO_OFF:
+ /*
+ * After the radio has been disablee, the device should
+ * be put to sleep for powersaving.
+ */
+ rt2800usb_disable_radio(rt2x00dev);
+ rt2800usb_set_state(rt2x00dev, STATE_SLEEP);
+ break;
+ case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ case STATE_RADIO_RX_OFF:
+ case STATE_RADIO_RX_OFF_LINK:
+ rt2800usb_toggle_rx(rt2x00dev, state);
+ break;
+ case STATE_RADIO_IRQ_ON:
+ case STATE_RADIO_IRQ_OFF:
+ /* No support, but no error either */
+ break;
+ case STATE_DEEP_SLEEP:
+ case STATE_SLEEP:
+ case STATE_STANDBY:
+ case STATE_AWAKE:
+ retval = rt2800usb_set_state(rt2x00dev, state);
+ break;
+ default:
+ retval = -ENOTSUPP;
+ break;
+ }
+
+ if (unlikely(retval))
+ ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
+ state, retval);
+
+ return retval;
+}
+
+/*
+ * TX descriptor initialization
+ */
+static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb,
+ struct txentry_desc *txdesc)
+{
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+ __le32 *txi = skbdesc->desc;
+ __le32 *txwi = &txi[TXINFO_DESC_SIZE / sizeof(__le32)];
+ u32 word;
+
+ /*
+ * Initialize TX Info descriptor
+ */
+ rt2x00_desc_read(txwi, 0, &word);
+ rt2x00_set_field32(&word, TXWI_W0_FRAG,
+ test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
+ rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
+ rt2x00_set_field32(&word, TXWI_W0_TS,
+ test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W0_AMPDU,
+ test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
+ rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->ifs);
+ rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
+ rt2x00_set_field32(&word, TXWI_W0_BW,
+ test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
+ test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
+ rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
+ rt2x00_desc_write(txwi, 0, word);
+
+ rt2x00_desc_read(txwi, 1, &word);
+ rt2x00_set_field32(&word, TXWI_W1_ACK,
+ test_bit(ENTRY_TXD_ACK, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W1_NSEQ,
+ test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
+ rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
+ test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
+ txdesc->key_idx : 0xff);
+ rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
+ skb->len - txdesc->l2pad);
+ rt2x00_set_field32(&word, TXWI_W1_PACKETID,
+ skbdesc->entry->entry_idx);
+ rt2x00_desc_write(txwi, 1, word);
+
+ /*
+ * Always write 0 to IV/EIV fields, hardware will insert the IV
+ * from the IVEIV register when TXINFO_W0_WIV is set to 0.
+ * When TXINFO_W0_WIV is set to 1 it will use the IV data
+ * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
+ * crypto entry in the registers should be used to encrypt the frame.
+ */
+ _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
+ _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
+
+ /*
+ * Initialize TX descriptor
+ */
+ rt2x00_desc_read(txi, 0, &word);
+ rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
+ skb->len + TXWI_DESC_SIZE);
+ rt2x00_set_field32(&word, TXINFO_W0_WIV,
+ !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
+ rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
+ rt2x00_set_field32(&word, TXINFO_W0_SW_USE_LAST_ROUND, 0);
+ rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_NEXT_VALID, 0);
+ rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_BURST,
+ test_bit(ENTRY_TXD_BURST, &txdesc->flags));
+ rt2x00_desc_write(txi, 0, word);
+}
+
+/*
+ * TX data initialization
+ */
+static void rt2800usb_write_beacon(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ unsigned int beacon_base;
+ u32 reg;
+
+ /*
+ * Add the descriptor in front of the skb.
+ */
+ skb_push(entry->skb, entry->queue->desc_size);
+ memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
+ skbdesc->desc = entry->skb->data;
+
+ /*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+ /*
+ * Write entire beacon with descriptor to register.
+ */
+ beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
+ rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT, beacon_base,
+ entry->skb->data, entry->skb->len,
+ REGISTER_TIMEOUT32(entry->skb->len));
+
+ /*
+ * Clean up the beacon skb.
+ */
+ dev_kfree_skb(entry->skb);
+ entry->skb = NULL;
+}
+
+static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
+{
+ int length;
+
+ /*
+ * The length _must_ include 4 bytes padding,
+ * it should always be multiple of 4,
+ * but it must _not_ be a multiple of the USB packet size.
+ */
+ length = roundup(entry->skb->len + 4, 4);
+ length += (4 * !(length % entry->queue->usb_maxpacket));
+
+ return length;
+}
+
+static void rt2800usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid queue)
+{
+ u32 reg;
+
+ if (queue != QID_BEACON) {
+ rt2x00usb_kick_tx_queue(rt2x00dev, queue);
+ return;
+ }
+
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ }
+}
+
+/*
+ * RX control handlers
+ */
+static void rt2800usb_fill_rxdone(struct queue_entry *entry,
+ struct rxdone_entry_desc *rxdesc)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ __le32 *rxd = (__le32 *)entry->skb->data;
+ __le32 *rxwi;
+ u32 rxd0;
+ u32 rxwi0;
+ u32 rxwi1;
+ u32 rxwi2;
+ u32 rxwi3;
+
+ /*
+ * Copy descriptor to the skbdesc->desc buffer, making it safe from
+ * moving of frame data in rt2x00usb.
+ */
+ memcpy(skbdesc->desc, rxd, skbdesc->desc_len);
+ rxd = (__le32 *)skbdesc->desc;
+ rxwi = &rxd[RXD_DESC_SIZE / sizeof(__le32)];
+
+ /*
+ * It is now safe to read the descriptor on all architectures.
+ */
+ rt2x00_desc_read(rxd, 0, &rxd0);
+ rt2x00_desc_read(rxwi, 0, &rxwi0);
+ rt2x00_desc_read(rxwi, 1, &rxwi1);
+ rt2x00_desc_read(rxwi, 2, &rxwi2);
+ rt2x00_desc_read(rxwi, 3, &rxwi3);
+
+ if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR))
+ rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
+
+ if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
+ rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
+ rxdesc->cipher_status =
+ rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
+ }
+
+ if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) {
+ /*
+ * Hardware has stripped IV/EIV data from 802.11 frame during
+ * decryption. Unfortunately the descriptor doesn't contain
+ * any fields with the EIV/IV data either, so they can't
+ * be restored by rt2x00lib.
+ */
+ rxdesc->flags |= RX_FLAG_IV_STRIPPED;
+
+ if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS)
+ rxdesc->flags |= RX_FLAG_DECRYPTED;
+ else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC)
+ rxdesc->flags |= RX_FLAG_MMIC_ERROR;
+ }
+
+ if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
+ rxdesc->dev_flags |= RXDONE_MY_BSS;
+
+ if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD))
+ rxdesc->dev_flags |= RXDONE_L2PAD;
+
+ if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
+ rxdesc->flags |= RX_FLAG_SHORT_GI;
+
+ if (rt2x00_get_field32(rxwi1, RXWI_W1_BW))
+ rxdesc->flags |= RX_FLAG_40MHZ;
+
+ /*
+ * Detect RX rate, always use MCS as signal type.
+ */
+ rxdesc->dev_flags |= RXDONE_SIGNAL_MCS;
+ rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE);
+ rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS);
+
+ /*
+ * Mask of 0x8 bit to remove the short preamble flag.
+ */
+ if (rxdesc->rate_mode == RATE_MODE_CCK)
+ rxdesc->signal &= ~0x8;
+
+ rxdesc->rssi =
+ (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) +
+ rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2;
+
+ rxdesc->noise =
+ (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) +
+ rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2;
+
+ rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
+
+ /*
+ * Remove RXWI descriptor from start of buffer.
+ */
+ skb_pull(entry->skb, skbdesc->desc_len);
+ skb_trim(entry->skb, rxdesc->size);
+}
+
+/*
+ * Device probe functions.
+ */
+static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+ u16 word;
+ u8 *mac;
+ u8 default_lna_gain;
+
+ rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE);
+
+ /*
+ * Start validation of the data that has been read.
+ */
+ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+ if (!is_valid_ether_addr(mac)) {
+ DECLARE_MAC_BUF(macbuf);
+
+ random_ether_addr(mac);
+ EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));
+ }
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+ if (word == 0xffff) {
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+ EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
+ } else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) {
+ /*
+ * There is a max of 2 RX streams for RT2870 series
+ */
+ if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2)
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+ }
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);
+ if (word == 0xffff) {
+ rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
+ EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
+ }
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
+ if ((word & 0x00ff) == 0x00ff) {
+ rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);
+ rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE,
+ LED_MODE_TXRX_ACTIVITY);
+ rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8);
+ EEPROM(rt2x00dev, "Freq: 0x%04x\n", word);
+ }
+
+ /*
+ * During the LNA validation we are going to use
+ * lna0 as correct value. Note that EEPROM_LNA
+ * is never validated.
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
+ default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
+ if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
+ default_lna_gain);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
+ if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
+ default_lna_gain);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
+
+ return 0;
+}
+
+static int rt2800usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+ u16 value;
+ u16 eeprom;
+
+ /*
+ * Read EEPROM word for configuration.
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+
+ /*
+ * Identify RF chipset.
+ */
+ value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+ rt2x00_set_chip(rt2x00dev, RT2870, value, reg);
+
+ /*
+ * The check for rt2860 is not a typo, some rt2870 hardware
+ * identifies itself as rt2860 in the CSR register.
+ */
+ if (!rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28600000) &&
+ !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28700000) &&
+ !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28800000) &&
+ !rt2x00_check_rev(&rt2x00dev->chip, 0xffff0000, 0x30700000)) {
+ ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
+ return -ENODEV;
+ }
+
+ if (!rt2x00_rf(&rt2x00dev->chip, RF2820) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2850) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2720) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2750) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF3020) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2020)) {
+ ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Identify default antenna configuration.
+ */
+ rt2x00dev->default_ant.tx =
+ rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH);
+ rt2x00dev->default_ant.rx =
+ rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH);
+
+ /*
+ * Read frequency offset and RF programming sequence.
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+ rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
+
+ /*
+ * Read external LNA informations.
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
+ __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
+ __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+
+ /*
+ * Detect if this device has an hardware controlled radio.
+ */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO))
+ __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+ /*
+ * Store led settings, for correct led behaviour.
+ */
+#ifdef CONFIG_RT2X00_LIB_LEDS
+ rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
+ rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
+ rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ,
+ &rt2x00dev->led_mcu_reg);
+#endif /* CONFIG_RT2X00_LIB_LEDS */
+
+ return 0;
+}
+
+/*
+ * RF value list for rt2870
+ * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750)
+ */
+static const struct rf_channel rf_vals[] = {
+ { 1, 0x18402ecc, 0x184c0786, 0x1816b455, 0x1800510b },
+ { 2, 0x18402ecc, 0x184c0786, 0x18168a55, 0x1800519f },
+ { 3, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800518b },
+ { 4, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800519f },
+ { 5, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800518b },
+ { 6, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800519f },
+ { 7, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800518b },
+ { 8, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800519f },
+ { 9, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800518b },
+ { 10, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800519f },
+ { 11, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800518b },
+ { 12, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800519f },
+ { 13, 0x18402ecc, 0x184c079e, 0x18168a55, 0x1800518b },
+ { 14, 0x18402ecc, 0x184c07a2, 0x18168a55, 0x18005193 },
+
+ /* 802.11 UNI / HyperLan 2 */
+ { 36, 0x18402ecc, 0x184c099a, 0x18158a55, 0x180ed1a3 },
+ { 38, 0x18402ecc, 0x184c099e, 0x18158a55, 0x180ed193 },
+ { 40, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed183 },
+ { 44, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed1a3 },
+ { 46, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed18b },
+ { 48, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed19b },
+ { 52, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed193 },
+ { 54, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed1a3 },
+ { 56, 0x18402ec8, 0x184c068e, 0x18158a55, 0x180ed18b },
+ { 60, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed183 },
+ { 62, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed193 },
+ { 64, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed1a3 },
+
+ /* 802.11 HyperLan 2 */
+ { 100, 0x18402ec8, 0x184c06b2, 0x18178a55, 0x180ed783 },
+ { 102, 0x18402ec8, 0x184c06b2, 0x18578a55, 0x180ed793 },
+ { 104, 0x18402ec8, 0x185c06b2, 0x18578a55, 0x180ed1a3 },
+ { 108, 0x18402ecc, 0x185c0a32, 0x18578a55, 0x180ed193 },
+ { 110, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed183 },
+ { 112, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed19b },
+ { 116, 0x18402ecc, 0x184c0a3a, 0x18178a55, 0x180ed1a3 },
+ { 118, 0x18402ecc, 0x184c0a3e, 0x18178a55, 0x180ed193 },
+ { 120, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed183 },
+ { 124, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed193 },
+ { 126, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed15b },
+ { 128, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed1a3 },
+ { 132, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed18b },
+ { 134, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed193 },
+ { 136, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed19b },
+ { 140, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed183 },
+
+ /* 802.11 UNII */
+ { 149, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed1a7 },
+ { 151, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed187 },
+ { 153, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed18f },
+ { 157, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed19f },
+ { 159, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed1a7 },
+ { 161, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed187 },
+ { 165, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed197 },
+ { 167, 0x18402ec4, 0x184c03d2, 0x18179855, 0x1815531f },
+ { 169, 0x18402ec4, 0x184c03d2, 0x18179855, 0x18155327 },
+ { 171, 0x18402ec4, 0x184c03d6, 0x18179855, 0x18155307 },
+ { 173, 0x18402ec4, 0x184c03d6, 0x18179855, 0x1815530f },
+
+ /* 802.11 Japan */
+ { 184, 0x15002ccc, 0x1500491e, 0x1509be55, 0x150c0a0b },
+ { 188, 0x15002ccc, 0x15004922, 0x1509be55, 0x150c0a13 },
+ { 192, 0x15002ccc, 0x15004926, 0x1509be55, 0x150c0a1b },
+ { 196, 0x15002ccc, 0x1500492a, 0x1509be55, 0x150c0a23 },
+ { 208, 0x15002ccc, 0x1500493a, 0x1509be55, 0x150c0a13 },
+ { 212, 0x15002ccc, 0x1500493e, 0x1509be55, 0x150c0a1b },
+ { 216, 0x15002ccc, 0x15004982, 0x1509be55, 0x150c0a23 },
+};
+
+/*
+ * RF value list for rt3070
+ * Supports: 2.4 GHz
+ */
+static const struct rf_channel rf_vals_3070[] = {
+ {1, 241, 2, 2 },
+ {2, 241, 2, 7 },
+ {3, 242, 2, 2 },
+ {4, 242, 2, 7 },
+ {5, 243, 2, 2 },
+ {6, 243, 2, 7 },
+ {7, 244, 2, 2 },
+ {8, 244, 2, 7 },
+ {9, 245, 2, 2 },
+ {10, 245, 2, 7 },
+ {11, 246, 2, 2 },
+ {12, 246, 2, 7 },
+ {13, 247, 2, 2 },
+ {14, 248, 2, 4 },
+};
+
+static int rt2800usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+{
+ struct hw_mode_spec *spec = &rt2x00dev->spec;
+ struct channel_info *info;
+ char *tx_power1;
+ char *tx_power2;
+ unsigned int i;
+ u16 eeprom;
+
+ /*
+ * Initialize all hw fields.
+ */
+ rt2x00dev->hw->flags =
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
+ rt2x00dev->hw->extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
+
+ SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
+ SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
+ rt2x00_eeprom_addr(rt2x00dev,
+ EEPROM_MAC_ADDR_0));
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+
+ /*
+ * Initialize HT information.
+ */
+ spec->ht.ht_supported = true;
+ spec->ht.cap =
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+ IEEE80211_HT_CAP_GRN_FLD |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_TX_STBC |
+ IEEE80211_HT_CAP_RX_STBC |
+ IEEE80211_HT_CAP_PSMP_SUPPORT;
+ spec->ht.ampdu_factor = 3;
+ spec->ht.ampdu_density = 4;
+ spec->ht.mcs.tx_params =
+ IEEE80211_HT_MCS_TX_DEFINED |
+ IEEE80211_HT_MCS_TX_RX_DIFF |
+ ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
+ IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
+
+ switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
+ case 3:
+ spec->ht.mcs.rx_mask[2] = 0xff;
+ case 2:
+ spec->ht.mcs.rx_mask[1] = 0xff;
+ case 1:
+ spec->ht.mcs.rx_mask[0] = 0xff;
+ spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
+ break;
+ }
+
+ /*
+ * Initialize hw_mode information.
+ */
+ spec->supported_bands = SUPPORT_BAND_2GHZ;
+ spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
+
+ if (rt2x00_rf(&rt2x00dev->chip, RF2820) ||
+ rt2x00_rf(&rt2x00dev->chip, RF2720)) {
+ spec->num_channels = 14;
+ spec->channels = rf_vals;
+ } else if (rt2x00_rf(&rt2x00dev->chip, RF2850) ||
+ rt2x00_rf(&rt2x00dev->chip, RF2750)) {
+ spec->supported_bands |= SUPPORT_BAND_5GHZ;
+ spec->num_channels = ARRAY_SIZE(rf_vals);
+ spec->channels = rf_vals;
+ } else if (rt2x00_rf(&rt2x00dev->chip, RF3020) ||
+ rt2x00_rf(&rt2x00dev->chip, RF2020)) {
+ spec->num_channels = ARRAY_SIZE(rf_vals_3070);
+ spec->channels = rf_vals_3070;
+ }
+
+ /*
+ * Create channel information array
+ */
+ info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ spec->channels_info = info;
+
+ tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
+ tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
+
+ for (i = 0; i < 14; i++) {
+ info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]);
+ info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]);
+ }
+
+ if (spec->num_channels > 14) {
+ tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
+ tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
+
+ for (i = 14; i < spec->num_channels; i++) {
+ info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]);
+ info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]);
+ }
+ }
+
+ return 0;
+}
+
+static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
+{
+ int retval;
+
+ /*
+ * Allocate eeprom data.
+ */
+ retval = rt2800usb_validate_eeprom(rt2x00dev);
+ if (retval)
+ return retval;
+
+ retval = rt2800usb_init_eeprom(rt2x00dev);
+ if (retval)
+ return retval;
+
+ /*
+ * Initialize hw specifications.
+ */
+ retval = rt2800usb_probe_hw_mode(rt2x00dev);
+ if (retval)
+ return retval;
+
+ /*
+ * This device requires firmware.
+ */
+ __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
+ if (!modparam_nohwcrypt)
+ __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
+
+ /*
+ * Set the rssi offset.
+ */
+ rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
+
+ return 0;
+}
+
+/*
+ * IEEE80211 stack callback functions.
+ */
+static void rt2800usb_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx,
+ u32 *iv32, u16 *iv16)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct mac_iveiv_entry iveiv_entry;
+ u32 offset;
+
+ offset = MAC_IVEIV_ENTRY(hw_key_idx);
+ rt2x00usb_register_multiread(rt2x00dev, offset,
+ &iveiv_entry, sizeof(iveiv_entry));
+
+ memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16));
+ memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32));
+}
+
+static int rt2800usb_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ u32 reg;
+ bool enabled = (value < IEEE80211_MAX_RTS_THRESHOLD);
+
+ rt2x00usb_register_read(rt2x00dev, TX_RTS_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES, value);
+ rt2x00usb_register_write(rt2x00dev, TX_RTS_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, CCK_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, MM20_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, MM40_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, GF20_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, GF40_PROT_CFG, reg);
+
+ return 0;
+}
+
+static int rt2800usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
+ const struct ieee80211_tx_queue_params *params)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct data_queue *queue;
+ struct rt2x00_field32 field;
+ int retval;
+ u32 reg;
+ u32 offset;
+
+ /*
+ * First pass the configuration through rt2x00lib, that will
+ * update the queue settings and validate the input. After that
+ * we are free to update the registers based on the value
+ * in the queue parameter.
+ */
+ retval = rt2x00mac_conf_tx(hw, queue_idx, params);
+ if (retval)
+ return retval;
+
+ /*
+ * We only need to perform additional register initialization
+ * for WMM queues/
+ */
+ if (queue_idx >= 4)
+ return 0;
+
+ queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
+
+ /* Update WMM TXOP register */
+ offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2)));
+ field.bit_offset = (queue_idx & 1) * 16;
+ field.bit_mask = 0xffff << field.bit_offset;
+
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, field, queue->txop);
+ rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+ /* Update WMM registers */
+ field.bit_offset = queue_idx * 4;
+ field.bit_mask = 0xf << field.bit_offset;
+
+ rt2x00usb_register_read(rt2x00dev, WMM_AIFSN_CFG, &reg);
+ rt2x00_set_field32(&reg, field, queue->aifs);
+ rt2x00usb_register_write(rt2x00dev, WMM_AIFSN_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, WMM_CWMIN_CFG, &reg);
+ rt2x00_set_field32(&reg, field, queue->cw_min);
+ rt2x00usb_register_write(rt2x00dev, WMM_CWMIN_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, WMM_CWMAX_CFG, &reg);
+ rt2x00_set_field32(&reg, field, queue->cw_max);
+ rt2x00usb_register_write(rt2x00dev, WMM_CWMAX_CFG, reg);
+
+ /* Update EDCA registers */
+ offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx);
+
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, EDCA_AC0_CFG_TX_OP, queue->txop);
+ rt2x00_set_field32(&reg, EDCA_AC0_CFG_AIFSN, queue->aifs);
+ rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMIN, queue->cw_min);
+ rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMAX, queue->cw_max);
+ rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+ return 0;
+}
+
+static u64 rt2800usb_get_tsf(struct ieee80211_hw *hw)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ u64 tsf;
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, TSF_TIMER_DW1, &reg);
+ tsf = (u64) rt2x00_get_field32(reg, TSF_TIMER_DW1_HIGH_WORD) << 32;
+ rt2x00usb_register_read(rt2x00dev, TSF_TIMER_DW0, &reg);
+ tsf |= rt2x00_get_field32(reg, TSF_TIMER_DW0_LOW_WORD);
+
+ return tsf;
+}
+
+static const struct ieee80211_ops rt2800usb_mac80211_ops = {
+ .tx = rt2x00mac_tx,
+ .start = rt2x00mac_start,
+ .stop = rt2x00mac_stop,
+ .add_interface = rt2x00mac_add_interface,
+ .remove_interface = rt2x00mac_remove_interface,
+ .config = rt2x00mac_config,
+ .configure_filter = rt2x00mac_configure_filter,
+ .set_key = rt2x00mac_set_key,
+ .get_stats = rt2x00mac_get_stats,
+ .get_tkip_seq = rt2800usb_get_tkip_seq,
+ .set_rts_threshold = rt2800usb_set_rts_threshold,
+ .bss_info_changed = rt2x00mac_bss_info_changed,
+ .conf_tx = rt2800usb_conf_tx,
+ .get_tx_stats = rt2x00mac_get_tx_stats,
+ .get_tsf = rt2800usb_get_tsf,
+};
+
+static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
+ .probe_hw = rt2800usb_probe_hw,
+ .get_firmware_name = rt2800usb_get_firmware_name,
+ .check_firmware = rt2800usb_check_firmware,
+ .load_firmware = rt2800usb_load_firmware,
+ .initialize = rt2x00usb_initialize,
+ .uninitialize = rt2x00usb_uninitialize,
+ .clear_entry = rt2x00usb_clear_entry,
+ .set_device_state = rt2800usb_set_device_state,
+ .rfkill_poll = rt2800usb_rfkill_poll,
+ .link_stats = rt2800usb_link_stats,
+ .reset_tuner = rt2800usb_reset_tuner,
+ .link_tuner = rt2800usb_link_tuner,
+ .write_tx_desc = rt2800usb_write_tx_desc,
+ .write_tx_data = rt2x00usb_write_tx_data,
+ .write_beacon = rt2800usb_write_beacon,
+ .get_tx_data_len = rt2800usb_get_tx_data_len,
+ .kick_tx_queue = rt2800usb_kick_tx_queue,
+ .kill_tx_queue = rt2x00usb_kill_tx_queue,
+ .fill_rxdone = rt2800usb_fill_rxdone,
+ .config_shared_key = rt2800usb_config_shared_key,
+ .config_pairwise_key = rt2800usb_config_pairwise_key,
+ .config_filter = rt2800usb_config_filter,
+ .config_intf = rt2800usb_config_intf,
+ .config_erp = rt2800usb_config_erp,
+ .config_ant = rt2800usb_config_ant,
+ .config = rt2800usb_config,
+};
+
+static const struct data_queue_desc rt2800usb_queue_rx = {
+ .entry_num = RX_ENTRIES,
+ .data_size = AGGREGATION_SIZE,
+ .desc_size = RXD_DESC_SIZE + RXWI_DESC_SIZE,
+ .priv_size = sizeof(struct queue_entry_priv_usb),
+};
+
+static const struct data_queue_desc rt2800usb_queue_tx = {
+ .entry_num = TX_ENTRIES,
+ .data_size = AGGREGATION_SIZE,
+ .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
+ .priv_size = sizeof(struct queue_entry_priv_usb),
+};
+
+static const struct data_queue_desc rt2800usb_queue_bcn = {
+ .entry_num = 8 * BEACON_ENTRIES,
+ .data_size = MGMT_FRAME_SIZE,
+ .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
+ .priv_size = sizeof(struct queue_entry_priv_usb),
+};
+
+static const struct rt2x00_ops rt2800usb_ops = {
+ .name = KBUILD_MODNAME,
+ .max_sta_intf = 1,
+ .max_ap_intf = 8,
+ .eeprom_size = EEPROM_SIZE,
+ .rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
+ .rx = &rt2800usb_queue_rx,
+ .tx = &rt2800usb_queue_tx,
+ .bcn = &rt2800usb_queue_bcn,
+ .lib = &rt2800usb_rt2x00_ops,
+ .hw = &rt2800usb_mac80211_ops,
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+ .debugfs = &rt2800usb_rt2x00debug,
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+};
+
+/*
+ * rt2800usb module information.
+ */
+static struct usb_device_id rt2800usb_device_table[] = {
+ /* ??? */
+ { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Abocom */
+ { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* AirTies */
+ { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Amigo */
+ { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Amit */
+ { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* ASUS */
+ { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* AzureWave */
+ { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Belkin */
+ { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Buffalo */
+ { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Conceptronic */
+ { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Corega */
+ { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* D-Link */
+ { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Edimax */
+ { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* EnGenius */
+ { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Gemtek */
+ { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Gigabyte */
+ { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Hawking */
+ { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* LevelOne */
+ { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Linksys */
+ { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Logitec */
+ { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Motorola */
+ { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Ovislink */
+ { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Pegatron */
+ { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Philips */
+ { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Planex */
+ { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Qcom */
+ { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Quanta */
+ { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Ralink */
+ { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Samsung */
+ { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Siemens */
+ { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Sitecom */
+ { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* SMC */
+ { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Sparklan */
+ { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* U-Media*/
+ { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* ZCOM */
+ { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Zinwell */
+ { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Zyxel */
+ { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { 0, }
+};
+
+MODULE_AUTHOR(DRV_PROJECT);
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION("Ralink RT2800 USB Wireless LAN driver.");
+MODULE_SUPPORTED_DEVICE("Ralink RT2870 USB chipset based cards");
+MODULE_DEVICE_TABLE(usb, rt2800usb_device_table);
+MODULE_FIRMWARE(FIRMWARE_RT2870);
+MODULE_LICENSE("GPL");
+
+static struct usb_driver rt2800usb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = rt2800usb_device_table,
+ .probe = rt2x00usb_probe,
+ .disconnect = rt2x00usb_disconnect,
+ .suspend = rt2x00usb_suspend,
+ .resume = rt2x00usb_resume,
+};
+
+static int __init rt2800usb_init(void)
+{
+ return usb_register(&rt2800usb_driver);
+}
+
+static void __exit rt2800usb_exit(void)
+{
+ usb_deregister(&rt2800usb_driver);
+}
+
+module_init(rt2800usb_init);
+module_exit(rt2800usb_exit);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
new file mode 100644
index 000000000000..61a8be61d3f5
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -0,0 +1,1945 @@
+/*
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.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.
+ */
+
+/*
+ Module: rt2800usb
+ Abstract: Data structures and registers for the rt2800usb module.
+ Supported chipsets: RT2800U.
+ */
+
+#ifndef RT2800USB_H
+#define RT2800USB_H
+
+/*
+ * RF chip defines.
+ *
+ * RF2820 2.4G 2T3R
+ * RF2850 2.4G/5G 2T3R
+ * RF2720 2.4G 1T2R
+ * RF2750 2.4G/5G 1T2R
+ * RF3020 2.4G 1T1R
+ * RF2020 2.4G B/G
+ */
+#define RF2820 0x0001
+#define RF2850 0x0002
+#define RF2720 0x0003
+#define RF2750 0x0004
+#define RF3020 0x0005
+#define RF2020 0x0006
+
+/*
+ * RT2870 version
+ */
+#define RT2860C_VERSION 0x28600100
+#define RT2860D_VERSION 0x28600101
+#define RT2880E_VERSION 0x28720200
+#define RT2883_VERSION 0x28830300
+#define RT3070_VERSION 0x30700200
+
+/*
+ * Signal information.
+ * Defaul offset is required for RSSI <-> dBm conversion.
+ */
+#define DEFAULT_RSSI_OFFSET 120 /* FIXME */
+
+/*
+ * Register layout information.
+ */
+#define CSR_REG_BASE 0x1000
+#define CSR_REG_SIZE 0x0800
+#define EEPROM_BASE 0x0000
+#define EEPROM_SIZE 0x0110
+#define BBP_BASE 0x0000
+#define BBP_SIZE 0x0080
+#define RF_BASE 0x0004
+#define RF_SIZE 0x0010
+
+/*
+ * Number of TX queues.
+ */
+#define NUM_TX_QUEUES 4
+
+/*
+ * USB registers.
+ */
+
+/*
+ * HOST-MCU shared memory
+ */
+#define HOST_CMD_CSR 0x0404
+#define HOST_CMD_CSR_HOST_COMMAND FIELD32(0x000000ff)
+
+/*
+ * INT_SOURCE_CSR: Interrupt source register.
+ * Write one to clear corresponding bit.
+ * TX_FIFO_STATUS: FIFO Statistics is full, sw should read 0x171c
+ */
+#define INT_SOURCE_CSR 0x0200
+#define INT_SOURCE_CSR_RXDELAYINT FIELD32(0x00000001)
+#define INT_SOURCE_CSR_TXDELAYINT FIELD32(0x00000002)
+#define INT_SOURCE_CSR_RX_DONE FIELD32(0x00000004)
+#define INT_SOURCE_CSR_AC0_DMA_DONE FIELD32(0x00000008)
+#define INT_SOURCE_CSR_AC1_DMA_DONE FIELD32(0x00000010)
+#define INT_SOURCE_CSR_AC2_DMA_DONE FIELD32(0x00000020)
+#define INT_SOURCE_CSR_AC3_DMA_DONE FIELD32(0x00000040)
+#define INT_SOURCE_CSR_HCCA_DMA_DONE FIELD32(0x00000080)
+#define INT_SOURCE_CSR_MGMT_DMA_DONE FIELD32(0x00000100)
+#define INT_SOURCE_CSR_MCU_COMMAND FIELD32(0x00000200)
+#define INT_SOURCE_CSR_RXTX_COHERENT FIELD32(0x00000400)
+#define INT_SOURCE_CSR_TBTT FIELD32(0x00000800)
+#define INT_SOURCE_CSR_PRE_TBTT FIELD32(0x00001000)
+#define INT_SOURCE_CSR_TX_FIFO_STATUS FIELD32(0x00002000)
+#define INT_SOURCE_CSR_AUTO_WAKEUP FIELD32(0x00004000)
+#define INT_SOURCE_CSR_GPTIMER FIELD32(0x00008000)
+#define INT_SOURCE_CSR_RX_COHERENT FIELD32(0x00010000)
+#define INT_SOURCE_CSR_TX_COHERENT FIELD32(0x00020000)
+
+/*
+ * INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF.
+ */
+#define INT_MASK_CSR 0x0204
+#define INT_MASK_CSR_RXDELAYINT FIELD32(0x00000001)
+#define INT_MASK_CSR_TXDELAYINT FIELD32(0x00000002)
+#define INT_MASK_CSR_RX_DONE FIELD32(0x00000004)
+#define INT_MASK_CSR_AC0_DMA_DONE FIELD32(0x00000008)
+#define INT_MASK_CSR_AC1_DMA_DONE FIELD32(0x00000010)
+#define INT_MASK_CSR_AC2_DMA_DONE FIELD32(0x00000020)
+#define INT_MASK_CSR_AC3_DMA_DONE FIELD32(0x00000040)
+#define INT_MASK_CSR_HCCA_DMA_DONE FIELD32(0x00000080)
+#define INT_MASK_CSR_MGMT_DMA_DONE FIELD32(0x00000100)
+#define INT_MASK_CSR_MCU_COMMAND FIELD32(0x00000200)
+#define INT_MASK_CSR_RXTX_COHERENT FIELD32(0x00000400)
+#define INT_MASK_CSR_TBTT FIELD32(0x00000800)
+#define INT_MASK_CSR_PRE_TBTT FIELD32(0x00001000)
+#define INT_MASK_CSR_TX_FIFO_STATUS FIELD32(0x00002000)
+#define INT_MASK_CSR_AUTO_WAKEUP FIELD32(0x00004000)
+#define INT_MASK_CSR_GPTIMER FIELD32(0x00008000)
+#define INT_MASK_CSR_RX_COHERENT FIELD32(0x00010000)
+#define INT_MASK_CSR_TX_COHERENT FIELD32(0x00020000)
+
+/*
+ * WPDMA_GLO_CFG
+ */
+#define WPDMA_GLO_CFG 0x0208
+#define WPDMA_GLO_CFG_ENABLE_TX_DMA FIELD32(0x00000001)
+#define WPDMA_GLO_CFG_TX_DMA_BUSY FIELD32(0x00000002)
+#define WPDMA_GLO_CFG_ENABLE_RX_DMA FIELD32(0x00000004)
+#define WPDMA_GLO_CFG_RX_DMA_BUSY FIELD32(0x00000008)
+#define WPDMA_GLO_CFG_WP_DMA_BURST_SIZE FIELD32(0x00000030)
+#define WPDMA_GLO_CFG_TX_WRITEBACK_DONE FIELD32(0x00000040)
+#define WPDMA_GLO_CFG_BIG_ENDIAN FIELD32(0x00000080)
+#define WPDMA_GLO_CFG_RX_HDR_SCATTER FIELD32(0x0000ff00)
+#define WPDMA_GLO_CFG_HDR_SEG_LEN FIELD32(0xffff0000)
+
+/*
+ * WPDMA_RST_IDX
+ */
+#define WPDMA_RST_IDX 0x020c
+#define WPDMA_RST_IDX_DTX_IDX0 FIELD32(0x00000001)
+#define WPDMA_RST_IDX_DTX_IDX1 FIELD32(0x00000002)
+#define WPDMA_RST_IDX_DTX_IDX2 FIELD32(0x00000004)
+#define WPDMA_RST_IDX_DTX_IDX3 FIELD32(0x00000008)
+#define WPDMA_RST_IDX_DTX_IDX4 FIELD32(0x00000010)
+#define WPDMA_RST_IDX_DTX_IDX5 FIELD32(0x00000020)
+#define WPDMA_RST_IDX_DRX_IDX0 FIELD32(0x00010000)
+
+/*
+ * DELAY_INT_CFG
+ */
+#define DELAY_INT_CFG 0x0210
+#define DELAY_INT_CFG_RXMAX_PTIME FIELD32(0x000000ff)
+#define DELAY_INT_CFG_RXMAX_PINT FIELD32(0x00007f00)
+#define DELAY_INT_CFG_RXDLY_INT_EN FIELD32(0x00008000)
+#define DELAY_INT_CFG_TXMAX_PTIME FIELD32(0x00ff0000)
+#define DELAY_INT_CFG_TXMAX_PINT FIELD32(0x7f000000)
+#define DELAY_INT_CFG_TXDLY_INT_EN FIELD32(0x80000000)
+
+/*
+ * WMM_AIFSN_CFG: Aifsn for each EDCA AC
+ * AIFSN0: AC_BE
+ * AIFSN1: AC_BK
+ * AIFSN1: AC_VI
+ * AIFSN1: AC_VO
+ */
+#define WMM_AIFSN_CFG 0x0214
+#define WMM_AIFSN_CFG_AIFSN0 FIELD32(0x0000000f)
+#define WMM_AIFSN_CFG_AIFSN1 FIELD32(0x000000f0)
+#define WMM_AIFSN_CFG_AIFSN2 FIELD32(0x00000f00)
+#define WMM_AIFSN_CFG_AIFSN3 FIELD32(0x0000f000)
+
+/*
+ * WMM_CWMIN_CSR: CWmin for each EDCA AC
+ * CWMIN0: AC_BE
+ * CWMIN1: AC_BK
+ * CWMIN1: AC_VI
+ * CWMIN1: AC_VO
+ */
+#define WMM_CWMIN_CFG 0x0218
+#define WMM_CWMIN_CFG_CWMIN0 FIELD32(0x0000000f)
+#define WMM_CWMIN_CFG_CWMIN1 FIELD32(0x000000f0)
+#define WMM_CWMIN_CFG_CWMIN2 FIELD32(0x00000f00)
+#define WMM_CWMIN_CFG_CWMIN3 FIELD32(0x0000f000)
+
+/*
+ * WMM_CWMAX_CSR: CWmax for each EDCA AC
+ * CWMAX0: AC_BE
+ * CWMAX1: AC_BK
+ * CWMAX1: AC_VI
+ * CWMAX1: AC_VO
+ */
+#define WMM_CWMAX_CFG 0x021c
+#define WMM_CWMAX_CFG_CWMAX0 FIELD32(0x0000000f)
+#define WMM_CWMAX_CFG_CWMAX1 FIELD32(0x000000f0)
+#define WMM_CWMAX_CFG_CWMAX2 FIELD32(0x00000f00)
+#define WMM_CWMAX_CFG_CWMAX3 FIELD32(0x0000f000)
+
+/*
+ * AC_TXOP0: AC_BK/AC_BE TXOP register
+ * AC0TXOP: AC_BK in unit of 32us
+ * AC1TXOP: AC_BE in unit of 32us
+ */
+#define WMM_TXOP0_CFG 0x0220
+#define WMM_TXOP0_CFG_AC0TXOP FIELD32(0x0000ffff)
+#define WMM_TXOP0_CFG_AC1TXOP FIELD32(0xffff0000)
+
+/*
+ * AC_TXOP1: AC_VO/AC_VI TXOP register
+ * AC2TXOP: AC_VI in unit of 32us
+ * AC3TXOP: AC_VO in unit of 32us
+ */
+#define WMM_TXOP1_CFG 0x0224
+#define WMM_TXOP1_CFG_AC2TXOP FIELD32(0x0000ffff)
+#define WMM_TXOP1_CFG_AC3TXOP FIELD32(0xffff0000)
+
+/*
+ * GPIO_CTRL_CFG:
+ */
+#define GPIO_CTRL_CFG 0x0228
+#define GPIO_CTRL_CFG_BIT0 FIELD32(0x00000001)
+#define GPIO_CTRL_CFG_BIT1 FIELD32(0x00000002)
+#define GPIO_CTRL_CFG_BIT2 FIELD32(0x00000004)
+#define GPIO_CTRL_CFG_BIT3 FIELD32(0x00000008)
+#define GPIO_CTRL_CFG_BIT4 FIELD32(0x00000010)
+#define GPIO_CTRL_CFG_BIT5 FIELD32(0x00000020)
+#define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040)
+#define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080)
+#define GPIO_CTRL_CFG_BIT8 FIELD32(0x00000100)
+
+/*
+ * MCU_CMD_CFG
+ */
+#define MCU_CMD_CFG 0x022c
+
+/*
+ * AC_BK register offsets
+ */
+#define TX_BASE_PTR0 0x0230
+#define TX_MAX_CNT0 0x0234
+#define TX_CTX_IDX0 0x0238
+#define TX_DTX_IDX0 0x023c
+
+/*
+ * AC_BE register offsets
+ */
+#define TX_BASE_PTR1 0x0240
+#define TX_MAX_CNT1 0x0244
+#define TX_CTX_IDX1 0x0248
+#define TX_DTX_IDX1 0x024c
+
+/*
+ * AC_VI register offsets
+ */
+#define TX_BASE_PTR2 0x0250
+#define TX_MAX_CNT2 0x0254
+#define TX_CTX_IDX2 0x0258
+#define TX_DTX_IDX2 0x025c
+
+/*
+ * AC_VO register offsets
+ */
+#define TX_BASE_PTR3 0x0260
+#define TX_MAX_CNT3 0x0264
+#define TX_CTX_IDX3 0x0268
+#define TX_DTX_IDX3 0x026c
+
+/*
+ * HCCA register offsets
+ */
+#define TX_BASE_PTR4 0x0270
+#define TX_MAX_CNT4 0x0274
+#define TX_CTX_IDX4 0x0278
+#define TX_DTX_IDX4 0x027c
+
+/*
+ * MGMT register offsets
+ */
+#define TX_BASE_PTR5 0x0280
+#define TX_MAX_CNT5 0x0284
+#define TX_CTX_IDX5 0x0288
+#define TX_DTX_IDX5 0x028c
+
+/*
+ * RX register offsets
+ */
+#define RX_BASE_PTR 0x0290
+#define RX_MAX_CNT 0x0294
+#define RX_CRX_IDX 0x0298
+#define RX_DRX_IDX 0x029c
+
+/*
+ * USB_DMA_CFG
+ * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns.
+ * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes.
+ * PHY_CLEAR: phy watch dog enable.
+ * TX_CLEAR: Clear USB DMA TX path.
+ * TXOP_HALT: Halt TXOP count down when TX buffer is full.
+ * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation.
+ * RX_BULK_EN: Enable USB DMA Rx.
+ * TX_BULK_EN: Enable USB DMA Tx.
+ * EP_OUT_VALID: OUT endpoint data valid.
+ * RX_BUSY: USB DMA RX FSM busy.
+ * TX_BUSY: USB DMA TX FSM busy.
+ */
+#define USB_DMA_CFG 0x02a0
+#define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT FIELD32(0x000000ff)
+#define USB_DMA_CFG_RX_BULK_AGG_LIMIT FIELD32(0x0000ff00)
+#define USB_DMA_CFG_PHY_CLEAR FIELD32(0x00010000)
+#define USB_DMA_CFG_TX_CLEAR FIELD32(0x00080000)
+#define USB_DMA_CFG_TXOP_HALT FIELD32(0x00100000)
+#define USB_DMA_CFG_RX_BULK_AGG_EN FIELD32(0x00200000)
+#define USB_DMA_CFG_RX_BULK_EN FIELD32(0x00400000)
+#define USB_DMA_CFG_TX_BULK_EN FIELD32(0x00800000)
+#define USB_DMA_CFG_EP_OUT_VALID FIELD32(0x3f000000)
+#define USB_DMA_CFG_RX_BUSY FIELD32(0x40000000)
+#define USB_DMA_CFG_TX_BUSY FIELD32(0x80000000)
+
+/*
+ * USB_CYC_CFG
+ */
+#define USB_CYC_CFG 0x02a4
+#define USB_CYC_CFG_CLOCK_CYCLE FIELD32(0x000000ff)
+
+/*
+ * PBF_SYS_CTRL
+ * HOST_RAM_WRITE: enable Host program ram write selection
+ */
+#define PBF_SYS_CTRL 0x0400
+#define PBF_SYS_CTRL_READY FIELD32(0x00000080)
+#define PBF_SYS_CTRL_HOST_RAM_WRITE FIELD32(0x00010000)
+
+/*
+ * PBF registers
+ * Most are for debug. Driver doesn't touch PBF register.
+ */
+#define PBF_CFG 0x0408
+#define PBF_MAX_PCNT 0x040c
+#define PBF_CTRL 0x0410
+#define PBF_INT_STA 0x0414
+#define PBF_INT_ENA 0x0418
+
+/*
+ * BCN_OFFSET0:
+ */
+#define BCN_OFFSET0 0x042c
+#define BCN_OFFSET0_BCN0 FIELD32(0x000000ff)
+#define BCN_OFFSET0_BCN1 FIELD32(0x0000ff00)
+#define BCN_OFFSET0_BCN2 FIELD32(0x00ff0000)
+#define BCN_OFFSET0_BCN3 FIELD32(0xff000000)
+
+/*
+ * BCN_OFFSET1:
+ */
+#define BCN_OFFSET1 0x0430
+#define BCN_OFFSET1_BCN4 FIELD32(0x000000ff)
+#define BCN_OFFSET1_BCN5 FIELD32(0x0000ff00)
+#define BCN_OFFSET1_BCN6 FIELD32(0x00ff0000)
+#define BCN_OFFSET1_BCN7 FIELD32(0xff000000)
+
+/*
+ * PBF registers
+ * Most are for debug. Driver doesn't touch PBF register.
+ */
+#define TXRXQ_PCNT 0x0438
+#define PBF_DBG 0x043c
+
+/*
+ * RF registers
+ */
+#define RF_CSR_CFG 0x0500
+#define RF_CSR_CFG_DATA FIELD32(0x000000ff)
+#define RF_CSR_CFG_REGNUM FIELD32(0x00001f00)
+#define RF_CSR_CFG_WRITE FIELD32(0x00010000)
+#define RF_CSR_CFG_BUSY FIELD32(0x00020000)
+
+/*
+ * MAC Control/Status Registers(CSR).
+ * Some values are set in TU, whereas 1 TU == 1024 us.
+ */
+
+/*
+ * MAC_CSR0: ASIC revision number.
+ * ASIC_REV: 0
+ * ASIC_VER: 2870
+ */
+#define MAC_CSR0 0x1000
+#define MAC_CSR0_ASIC_REV FIELD32(0x0000ffff)
+#define MAC_CSR0_ASIC_VER FIELD32(0xffff0000)
+
+/*
+ * MAC_SYS_CTRL:
+ */
+#define MAC_SYS_CTRL 0x1004
+#define MAC_SYS_CTRL_RESET_CSR FIELD32(0x00000001)
+#define MAC_SYS_CTRL_RESET_BBP FIELD32(0x00000002)
+#define MAC_SYS_CTRL_ENABLE_TX FIELD32(0x00000004)
+#define MAC_SYS_CTRL_ENABLE_RX FIELD32(0x00000008)
+#define MAC_SYS_CTRL_CONTINUOUS_TX FIELD32(0x00000010)
+#define MAC_SYS_CTRL_LOOPBACK FIELD32(0x00000020)
+#define MAC_SYS_CTRL_WLAN_HALT FIELD32(0x00000040)
+#define MAC_SYS_CTRL_RX_TIMESTAMP FIELD32(0x00000080)
+
+/*
+ * MAC_ADDR_DW0: STA MAC register 0
+ */
+#define MAC_ADDR_DW0 0x1008
+#define MAC_ADDR_DW0_BYTE0 FIELD32(0x000000ff)
+#define MAC_ADDR_DW0_BYTE1 FIELD32(0x0000ff00)
+#define MAC_ADDR_DW0_BYTE2 FIELD32(0x00ff0000)
+#define MAC_ADDR_DW0_BYTE3 FIELD32(0xff000000)
+
+/*
+ * MAC_ADDR_DW1: STA MAC register 1
+ * UNICAST_TO_ME_MASK:
+ * Used to mask off bits from byte 5 of the MAC address
+ * to determine the UNICAST_TO_ME bit for RX frames.
+ * The full mask is complemented by BSS_ID_MASK:
+ * MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK
+ */
+#define MAC_ADDR_DW1 0x100c
+#define MAC_ADDR_DW1_BYTE4 FIELD32(0x000000ff)
+#define MAC_ADDR_DW1_BYTE5 FIELD32(0x0000ff00)
+#define MAC_ADDR_DW1_UNICAST_TO_ME_MASK FIELD32(0x00ff0000)
+
+/*
+ * MAC_BSSID_DW0: BSSID register 0
+ */
+#define MAC_BSSID_DW0 0x1010
+#define MAC_BSSID_DW0_BYTE0 FIELD32(0x000000ff)
+#define MAC_BSSID_DW0_BYTE1 FIELD32(0x0000ff00)
+#define MAC_BSSID_DW0_BYTE2 FIELD32(0x00ff0000)
+#define MAC_BSSID_DW0_BYTE3 FIELD32(0xff000000)
+
+/*
+ * MAC_BSSID_DW1: BSSID register 1
+ * BSS_ID_MASK:
+ * 0: 1-BSSID mode (BSS index = 0)
+ * 1: 2-BSSID mode (BSS index: Byte5, bit 0)
+ * 2: 4-BSSID mode (BSS index: byte5, bit 0 - 1)
+ * 3: 8-BSSID mode (BSS index: byte5, bit 0 - 2)
+ * This mask is used to mask off bits 0, 1 and 2 of byte 5 of the
+ * BSSID. This will make sure that those bits will be ignored
+ * when determining the MY_BSS of RX frames.
+ */
+#define MAC_BSSID_DW1 0x1014
+#define MAC_BSSID_DW1_BYTE4 FIELD32(0x000000ff)
+#define MAC_BSSID_DW1_BYTE5 FIELD32(0x0000ff00)
+#define MAC_BSSID_DW1_BSS_ID_MASK FIELD32(0x00030000)
+#define MAC_BSSID_DW1_BSS_BCN_NUM FIELD32(0x001c0000)
+
+/*
+ * MAX_LEN_CFG: Maximum frame length register.
+ * MAX_MPDU: rt2860b max 16k bytes
+ * MAX_PSDU: Maximum PSDU length
+ * (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
+ */
+#define MAX_LEN_CFG 0x1018
+#define MAX_LEN_CFG_MAX_MPDU FIELD32(0x00000fff)
+#define MAX_LEN_CFG_MAX_PSDU FIELD32(0x00003000)
+#define MAX_LEN_CFG_MIN_PSDU FIELD32(0x0000c000)
+#define MAX_LEN_CFG_MIN_MPDU FIELD32(0x000f0000)
+
+/*
+ * BBP_CSR_CFG: BBP serial control register
+ * VALUE: Register value to program into BBP
+ * REG_NUM: Selected BBP register
+ * READ_CONTROL: 0 write BBP, 1 read BBP
+ * BUSY: ASIC is busy executing BBP commands
+ * BBP_PAR_DUR: 0 4 MAC clocks, 1 8 MAC clocks
+ * BBP_RW_MODE: 0 serial, 1 paralell
+ */
+#define BBP_CSR_CFG 0x101c
+#define BBP_CSR_CFG_VALUE FIELD32(0x000000ff)
+#define BBP_CSR_CFG_REGNUM FIELD32(0x0000ff00)
+#define BBP_CSR_CFG_READ_CONTROL FIELD32(0x00010000)
+#define BBP_CSR_CFG_BUSY FIELD32(0x00020000)
+#define BBP_CSR_CFG_BBP_PAR_DUR FIELD32(0x00040000)
+#define BBP_CSR_CFG_BBP_RW_MODE FIELD32(0x00080000)
+
+/*
+ * RF_CSR_CFG0: RF control register
+ * REGID_AND_VALUE: Register value to program into RF
+ * BITWIDTH: Selected RF register
+ * STANDBYMODE: 0 high when standby, 1 low when standby
+ * SEL: 0 RF_LE0 activate, 1 RF_LE1 activate
+ * BUSY: ASIC is busy executing RF commands
+ */
+#define RF_CSR_CFG0 0x1020
+#define RF_CSR_CFG0_REGID_AND_VALUE FIELD32(0x00ffffff)
+#define RF_CSR_CFG0_BITWIDTH FIELD32(0x1f000000)
+#define RF_CSR_CFG0_REG_VALUE_BW FIELD32(0x1fffffff)
+#define RF_CSR_CFG0_STANDBYMODE FIELD32(0x20000000)
+#define RF_CSR_CFG0_SEL FIELD32(0x40000000)
+#define RF_CSR_CFG0_BUSY FIELD32(0x80000000)
+
+/*
+ * RF_CSR_CFG1: RF control register
+ * REGID_AND_VALUE: Register value to program into RF
+ * RFGAP: Gap between BB_CONTROL_RF and RF_LE
+ * 0: 3 system clock cycle (37.5usec)
+ * 1: 5 system clock cycle (62.5usec)
+ */
+#define RF_CSR_CFG1 0x1024
+#define RF_CSR_CFG1_REGID_AND_VALUE FIELD32(0x00ffffff)
+#define RF_CSR_CFG1_RFGAP FIELD32(0x1f000000)
+
+/*
+ * RF_CSR_CFG2: RF control register
+ * VALUE: Register value to program into RF
+ * RFGAP: Gap between BB_CONTROL_RF and RF_LE
+ * 0: 3 system clock cycle (37.5usec)
+ * 1: 5 system clock cycle (62.5usec)
+ */
+#define RF_CSR_CFG2 0x1028
+#define RF_CSR_CFG2_VALUE FIELD32(0x00ffffff)
+
+/*
+ * LED_CFG: LED control
+ * color LED's:
+ * 0: off
+ * 1: blinking upon TX2
+ * 2: periodic slow blinking
+ * 3: always on
+ * LED polarity:
+ * 0: active low
+ * 1: active high
+ */
+#define LED_CFG 0x102c
+#define LED_CFG_ON_PERIOD FIELD32(0x000000ff)
+#define LED_CFG_OFF_PERIOD FIELD32(0x0000ff00)
+#define LED_CFG_SLOW_BLINK_PERIOD FIELD32(0x003f0000)
+#define LED_CFG_R_LED_MODE FIELD32(0x03000000)
+#define LED_CFG_G_LED_MODE FIELD32(0x0c000000)
+#define LED_CFG_Y_LED_MODE FIELD32(0x30000000)
+#define LED_CFG_LED_POLAR FIELD32(0x40000000)
+
+/*
+ * XIFS_TIME_CFG: MAC timing
+ * CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX
+ * OFDM_SIFS_TIME: unit 1us. Applied after OFDM RX/TX
+ * OFDM_XIFS_TIME: unit 1us. Applied after OFDM RX
+ * when MAC doesn't reference BBP signal BBRXEND
+ * EIFS: unit 1us
+ * BB_RXEND_ENABLE: reference RXEND signal to begin XIFS defer
+ *
+ */
+#define XIFS_TIME_CFG 0x1100
+#define XIFS_TIME_CFG_CCKM_SIFS_TIME FIELD32(0x000000ff)
+#define XIFS_TIME_CFG_OFDM_SIFS_TIME FIELD32(0x0000ff00)
+#define XIFS_TIME_CFG_OFDM_XIFS_TIME FIELD32(0x000f0000)
+#define XIFS_TIME_CFG_EIFS FIELD32(0x1ff00000)
+#define XIFS_TIME_CFG_BB_RXEND_ENABLE FIELD32(0x20000000)
+
+/*
+ * BKOFF_SLOT_CFG:
+ */
+#define BKOFF_SLOT_CFG 0x1104
+#define BKOFF_SLOT_CFG_SLOT_TIME FIELD32(0x000000ff)
+#define BKOFF_SLOT_CFG_CC_DELAY_TIME FIELD32(0x0000ff00)
+
+/*
+ * NAV_TIME_CFG:
+ */
+#define NAV_TIME_CFG 0x1108
+#define NAV_TIME_CFG_SIFS FIELD32(0x000000ff)
+#define NAV_TIME_CFG_SLOT_TIME FIELD32(0x0000ff00)
+#define NAV_TIME_CFG_EIFS FIELD32(0x01ff0000)
+#define NAV_TIME_ZERO_SIFS FIELD32(0x02000000)
+
+/*
+ * CH_TIME_CFG: count as channel busy
+ */
+#define CH_TIME_CFG 0x110c
+
+/*
+ * PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us
+ */
+#define PBF_LIFE_TIMER 0x1110
+
+/*
+ * BCN_TIME_CFG:
+ * BEACON_INTERVAL: in unit of 1/16 TU
+ * TSF_TICKING: Enable TSF auto counting
+ * TSF_SYNC: Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+ * BEACON_GEN: Enable beacon generator
+ */
+#define BCN_TIME_CFG 0x1114
+#define BCN_TIME_CFG_BEACON_INTERVAL FIELD32(0x0000ffff)
+#define BCN_TIME_CFG_TSF_TICKING FIELD32(0x00010000)
+#define BCN_TIME_CFG_TSF_SYNC FIELD32(0x00060000)
+#define BCN_TIME_CFG_TBTT_ENABLE FIELD32(0x00080000)
+#define BCN_TIME_CFG_BEACON_GEN FIELD32(0x00100000)
+#define BCN_TIME_CFG_TX_TIME_COMPENSATE FIELD32(0xf0000000)
+
+/*
+ * TBTT_SYNC_CFG:
+ */
+#define TBTT_SYNC_CFG 0x1118
+
+/*
+ * TSF_TIMER_DW0: Local lsb TSF timer, read-only
+ */
+#define TSF_TIMER_DW0 0x111c
+#define TSF_TIMER_DW0_LOW_WORD FIELD32(0xffffffff)
+
+/*
+ * TSF_TIMER_DW1: Local msb TSF timer, read-only
+ */
+#define TSF_TIMER_DW1 0x1120
+#define TSF_TIMER_DW1_HIGH_WORD FIELD32(0xffffffff)
+
+/*
+ * TBTT_TIMER: TImer remains till next TBTT, read-only
+ */
+#define TBTT_TIMER 0x1124
+
+/*
+ * INT_TIMER_CFG:
+ */
+#define INT_TIMER_CFG 0x1128
+
+/*
+ * INT_TIMER_EN: GP-timer and pre-tbtt Int enable
+ */
+#define INT_TIMER_EN 0x112c
+
+/*
+ * CH_IDLE_STA: channel idle time
+ */
+#define CH_IDLE_STA 0x1130
+
+/*
+ * CH_BUSY_STA: channel busy time
+ */
+#define CH_BUSY_STA 0x1134
+
+/*
+ * MAC_STATUS_CFG:
+ * BBP_RF_BUSY: When set to 0, BBP and RF are stable.
+ * if 1 or higher one of the 2 registers is busy.
+ */
+#define MAC_STATUS_CFG 0x1200
+#define MAC_STATUS_CFG_BBP_RF_BUSY FIELD32(0x00000003)
+
+/*
+ * PWR_PIN_CFG:
+ */
+#define PWR_PIN_CFG 0x1204
+
+/*
+ * AUTOWAKEUP_CFG: Manual power control / status register
+ * TBCN_BEFORE_WAKE: ForceWake has high privilege than PutToSleep when both set
+ * AUTOWAKE: 0:sleep, 1:awake
+ */
+#define AUTOWAKEUP_CFG 0x1208
+#define AUTOWAKEUP_CFG_AUTO_LEAD_TIME FIELD32(0x000000ff)
+#define AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE FIELD32(0x00007f00)
+#define AUTOWAKEUP_CFG_AUTOWAKE FIELD32(0x00008000)
+
+/*
+ * EDCA_AC0_CFG:
+ */
+#define EDCA_AC0_CFG 0x1300
+#define EDCA_AC0_CFG_TX_OP FIELD32(0x000000ff)
+#define EDCA_AC0_CFG_AIFSN FIELD32(0x00000f00)
+#define EDCA_AC0_CFG_CWMIN FIELD32(0x0000f000)
+#define EDCA_AC0_CFG_CWMAX FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC1_CFG:
+ */
+#define EDCA_AC1_CFG 0x1304
+#define EDCA_AC1_CFG_TX_OP FIELD32(0x000000ff)
+#define EDCA_AC1_CFG_AIFSN FIELD32(0x00000f00)
+#define EDCA_AC1_CFG_CWMIN FIELD32(0x0000f000)
+#define EDCA_AC1_CFG_CWMAX FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC2_CFG:
+ */
+#define EDCA_AC2_CFG 0x1308
+#define EDCA_AC2_CFG_TX_OP FIELD32(0x000000ff)
+#define EDCA_AC2_CFG_AIFSN FIELD32(0x00000f00)
+#define EDCA_AC2_CFG_CWMIN FIELD32(0x0000f000)
+#define EDCA_AC2_CFG_CWMAX FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC3_CFG:
+ */
+#define EDCA_AC3_CFG 0x130c
+#define EDCA_AC3_CFG_TX_OP FIELD32(0x000000ff)
+#define EDCA_AC3_CFG_AIFSN FIELD32(0x00000f00)
+#define EDCA_AC3_CFG_CWMIN FIELD32(0x0000f000)
+#define EDCA_AC3_CFG_CWMAX FIELD32(0x000f0000)
+
+/*
+ * EDCA_TID_AC_MAP:
+ */
+#define EDCA_TID_AC_MAP 0x1310
+
+/*
+ * TX_PWR_CFG_0:
+ */
+#define TX_PWR_CFG_0 0x1314
+#define TX_PWR_CFG_0_1MBS FIELD32(0x0000000f)
+#define TX_PWR_CFG_0_2MBS FIELD32(0x000000f0)
+#define TX_PWR_CFG_0_55MBS FIELD32(0x00000f00)
+#define TX_PWR_CFG_0_11MBS FIELD32(0x0000f000)
+#define TX_PWR_CFG_0_6MBS FIELD32(0x000f0000)
+#define TX_PWR_CFG_0_9MBS FIELD32(0x00f00000)
+#define TX_PWR_CFG_0_12MBS FIELD32(0x0f000000)
+#define TX_PWR_CFG_0_18MBS FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_1:
+ */
+#define TX_PWR_CFG_1 0x1318
+#define TX_PWR_CFG_1_24MBS FIELD32(0x0000000f)
+#define TX_PWR_CFG_1_36MBS FIELD32(0x000000f0)
+#define TX_PWR_CFG_1_48MBS FIELD32(0x00000f00)
+#define TX_PWR_CFG_1_54MBS FIELD32(0x0000f000)
+#define TX_PWR_CFG_1_MCS0 FIELD32(0x000f0000)
+#define TX_PWR_CFG_1_MCS1 FIELD32(0x00f00000)
+#define TX_PWR_CFG_1_MCS2 FIELD32(0x0f000000)
+#define TX_PWR_CFG_1_MCS3 FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_2:
+ */
+#define TX_PWR_CFG_2 0x131c
+#define TX_PWR_CFG_2_MCS4 FIELD32(0x0000000f)
+#define TX_PWR_CFG_2_MCS5 FIELD32(0x000000f0)
+#define TX_PWR_CFG_2_MCS6 FIELD32(0x00000f00)
+#define TX_PWR_CFG_2_MCS7 FIELD32(0x0000f000)
+#define TX_PWR_CFG_2_MCS8 FIELD32(0x000f0000)
+#define TX_PWR_CFG_2_MCS9 FIELD32(0x00f00000)
+#define TX_PWR_CFG_2_MCS10 FIELD32(0x0f000000)
+#define TX_PWR_CFG_2_MCS11 FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_3:
+ */
+#define TX_PWR_CFG_3 0x1320
+#define TX_PWR_CFG_3_MCS12 FIELD32(0x0000000f)
+#define TX_PWR_CFG_3_MCS13 FIELD32(0x000000f0)
+#define TX_PWR_CFG_3_MCS14 FIELD32(0x00000f00)
+#define TX_PWR_CFG_3_MCS15 FIELD32(0x0000f000)
+#define TX_PWR_CFG_3_UKNOWN1 FIELD32(0x000f0000)
+#define TX_PWR_CFG_3_UKNOWN2 FIELD32(0x00f00000)
+#define TX_PWR_CFG_3_UKNOWN3 FIELD32(0x0f000000)
+#define TX_PWR_CFG_3_UKNOWN4 FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_4:
+ */
+#define TX_PWR_CFG_4 0x1324
+#define TX_PWR_CFG_4_UKNOWN5 FIELD32(0x0000000f)
+#define TX_PWR_CFG_4_UKNOWN6 FIELD32(0x000000f0)
+#define TX_PWR_CFG_4_UKNOWN7 FIELD32(0x00000f00)
+#define TX_PWR_CFG_4_UKNOWN8 FIELD32(0x0000f000)
+
+/*
+ * TX_PIN_CFG:
+ */
+#define TX_PIN_CFG 0x1328
+#define TX_PIN_CFG_PA_PE_A0_EN FIELD32(0x00000001)
+#define TX_PIN_CFG_PA_PE_G0_EN FIELD32(0x00000002)
+#define TX_PIN_CFG_PA_PE_A1_EN FIELD32(0x00000004)
+#define TX_PIN_CFG_PA_PE_G1_EN FIELD32(0x00000008)
+#define TX_PIN_CFG_PA_PE_A0_POL FIELD32(0x00000010)
+#define TX_PIN_CFG_PA_PE_G0_POL FIELD32(0x00000020)
+#define TX_PIN_CFG_PA_PE_A1_POL FIELD32(0x00000040)
+#define TX_PIN_CFG_PA_PE_G1_POL FIELD32(0x00000080)
+#define TX_PIN_CFG_LNA_PE_A0_EN FIELD32(0x00000100)
+#define TX_PIN_CFG_LNA_PE_G0_EN FIELD32(0x00000200)
+#define TX_PIN_CFG_LNA_PE_A1_EN FIELD32(0x00000400)
+#define TX_PIN_CFG_LNA_PE_G1_EN FIELD32(0x00000800)
+#define TX_PIN_CFG_LNA_PE_A0_POL FIELD32(0x00001000)
+#define TX_PIN_CFG_LNA_PE_G0_POL FIELD32(0x00002000)
+#define TX_PIN_CFG_LNA_PE_A1_POL FIELD32(0x00004000)
+#define TX_PIN_CFG_LNA_PE_G1_POL FIELD32(0x00008000)
+#define TX_PIN_CFG_RFTR_EN FIELD32(0x00010000)
+#define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000)
+#define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000)
+#define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000)
+
+/*
+ * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz
+ */
+#define TX_BAND_CFG 0x132c
+#define TX_BAND_CFG_HT40_PLUS FIELD32(0x00000001)
+#define TX_BAND_CFG_A FIELD32(0x00000002)
+#define TX_BAND_CFG_BG FIELD32(0x00000004)
+
+/*
+ * TX_SW_CFG0:
+ */
+#define TX_SW_CFG0 0x1330
+
+/*
+ * TX_SW_CFG1:
+ */
+#define TX_SW_CFG1 0x1334
+
+/*
+ * TX_SW_CFG2:
+ */
+#define TX_SW_CFG2 0x1338
+
+/*
+ * TXOP_THRES_CFG:
+ */
+#define TXOP_THRES_CFG 0x133c
+
+/*
+ * TXOP_CTRL_CFG:
+ */
+#define TXOP_CTRL_CFG 0x1340
+
+/*
+ * TX_RTS_CFG:
+ * RTS_THRES: unit:byte
+ * RTS_FBK_EN: enable rts rate fallback
+ */
+#define TX_RTS_CFG 0x1344
+#define TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT FIELD32(0x000000ff)
+#define TX_RTS_CFG_RTS_THRES FIELD32(0x00ffff00)
+#define TX_RTS_CFG_RTS_FBK_EN FIELD32(0x01000000)
+
+/*
+ * TX_TIMEOUT_CFG:
+ * MPDU_LIFETIME: expiration time = 2^(9+MPDU LIFE TIME) us
+ * RX_ACK_TIMEOUT: unit:slot. Used for TX procedure
+ * TX_OP_TIMEOUT: TXOP timeout value for TXOP truncation.
+ * it is recommended that:
+ * (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+ */
+#define TX_TIMEOUT_CFG 0x1348
+#define TX_TIMEOUT_CFG_MPDU_LIFETIME FIELD32(0x000000f0)
+#define TX_TIMEOUT_CFG_RX_ACK_TIMEOUT FIELD32(0x0000ff00)
+#define TX_TIMEOUT_CFG_TX_OP_TIMEOUT FIELD32(0x00ff0000)
+
+/*
+ * TX_RTY_CFG:
+ * SHORT_RTY_LIMIT: short retry limit
+ * LONG_RTY_LIMIT: long retry limit
+ * LONG_RTY_THRE: Long retry threshoold
+ * NON_AGG_RTY_MODE: Non-Aggregate MPDU retry mode
+ * 0:expired by retry limit, 1: expired by mpdu life timer
+ * AGG_RTY_MODE: Aggregate MPDU retry mode
+ * 0:expired by retry limit, 1: expired by mpdu life timer
+ * TX_AUTO_FB_ENABLE: Tx retry PHY rate auto fallback enable
+ */
+#define TX_RTY_CFG 0x134c
+#define TX_RTY_CFG_SHORT_RTY_LIMIT FIELD32(0x000000ff)
+#define TX_RTY_CFG_LONG_RTY_LIMIT FIELD32(0x0000ff00)
+#define TX_RTY_CFG_LONG_RTY_THRE FIELD32(0x0fff0000)
+#define TX_RTY_CFG_NON_AGG_RTY_MODE FIELD32(0x10000000)
+#define TX_RTY_CFG_AGG_RTY_MODE FIELD32(0x20000000)
+#define TX_RTY_CFG_TX_AUTO_FB_ENABLE FIELD32(0x40000000)
+
+/*
+ * TX_LINK_CFG:
+ * REMOTE_MFB_LIFETIME: remote MFB life time. unit: 32us
+ * MFB_ENABLE: TX apply remote MFB 1:enable
+ * REMOTE_UMFS_ENABLE: remote unsolicit MFB enable
+ * 0: not apply remote remote unsolicit (MFS=7)
+ * TX_MRQ_EN: MCS request TX enable
+ * TX_RDG_EN: RDG TX enable
+ * TX_CF_ACK_EN: Piggyback CF-ACK enable
+ * REMOTE_MFB: remote MCS feedback
+ * REMOTE_MFS: remote MCS feedback sequence number
+ */
+#define TX_LINK_CFG 0x1350
+#define TX_LINK_CFG_REMOTE_MFB_LIFETIME FIELD32(0x000000ff)
+#define TX_LINK_CFG_MFB_ENABLE FIELD32(0x00000100)
+#define TX_LINK_CFG_REMOTE_UMFS_ENABLE FIELD32(0x00000200)
+#define TX_LINK_CFG_TX_MRQ_EN FIELD32(0x00000400)
+#define TX_LINK_CFG_TX_RDG_EN FIELD32(0x00000800)
+#define TX_LINK_CFG_TX_CF_ACK_EN FIELD32(0x00001000)
+#define TX_LINK_CFG_REMOTE_MFB FIELD32(0x00ff0000)
+#define TX_LINK_CFG_REMOTE_MFS FIELD32(0xff000000)
+
+/*
+ * HT_FBK_CFG0:
+ */
+#define HT_FBK_CFG0 0x1354
+#define HT_FBK_CFG0_HTMCS0FBK FIELD32(0x0000000f)
+#define HT_FBK_CFG0_HTMCS1FBK FIELD32(0x000000f0)
+#define HT_FBK_CFG0_HTMCS2FBK FIELD32(0x00000f00)
+#define HT_FBK_CFG0_HTMCS3FBK FIELD32(0x0000f000)
+#define HT_FBK_CFG0_HTMCS4FBK FIELD32(0x000f0000)
+#define HT_FBK_CFG0_HTMCS5FBK FIELD32(0x00f00000)
+#define HT_FBK_CFG0_HTMCS6FBK FIELD32(0x0f000000)
+#define HT_FBK_CFG0_HTMCS7FBK FIELD32(0xf0000000)
+
+/*
+ * HT_FBK_CFG1:
+ */
+#define HT_FBK_CFG1 0x1358
+#define HT_FBK_CFG1_HTMCS8FBK FIELD32(0x0000000f)
+#define HT_FBK_CFG1_HTMCS9FBK FIELD32(0x000000f0)
+#define HT_FBK_CFG1_HTMCS10FBK FIELD32(0x00000f00)
+#define HT_FBK_CFG1_HTMCS11FBK FIELD32(0x0000f000)
+#define HT_FBK_CFG1_HTMCS12FBK FIELD32(0x000f0000)
+#define HT_FBK_CFG1_HTMCS13FBK FIELD32(0x00f00000)
+#define HT_FBK_CFG1_HTMCS14FBK FIELD32(0x0f000000)
+#define HT_FBK_CFG1_HTMCS15FBK FIELD32(0xf0000000)
+
+/*
+ * LG_FBK_CFG0:
+ */
+#define LG_FBK_CFG0 0x135c
+#define LG_FBK_CFG0_OFDMMCS0FBK FIELD32(0x0000000f)
+#define LG_FBK_CFG0_OFDMMCS1FBK FIELD32(0x000000f0)
+#define LG_FBK_CFG0_OFDMMCS2FBK FIELD32(0x00000f00)
+#define LG_FBK_CFG0_OFDMMCS3FBK FIELD32(0x0000f000)
+#define LG_FBK_CFG0_OFDMMCS4FBK FIELD32(0x000f0000)
+#define LG_FBK_CFG0_OFDMMCS5FBK FIELD32(0x00f00000)
+#define LG_FBK_CFG0_OFDMMCS6FBK FIELD32(0x0f000000)
+#define LG_FBK_CFG0_OFDMMCS7FBK FIELD32(0xf0000000)
+
+/*
+ * LG_FBK_CFG1:
+ */
+#define LG_FBK_CFG1 0x1360
+#define LG_FBK_CFG0_CCKMCS0FBK FIELD32(0x0000000f)
+#define LG_FBK_CFG0_CCKMCS1FBK FIELD32(0x000000f0)
+#define LG_FBK_CFG0_CCKMCS2FBK FIELD32(0x00000f00)
+#define LG_FBK_CFG0_CCKMCS3FBK FIELD32(0x0000f000)
+
+/*
+ * CCK_PROT_CFG: CCK Protection
+ * PROTECT_RATE: Protection control frame rate for CCK TX(RTS/CTS/CFEnd)
+ * PROTECT_CTRL: Protection control frame type for CCK TX
+ * 0:none, 1:RTS/CTS, 2:CTS-to-self
+ * PROTECT_NAV: TXOP protection type for CCK TX
+ * 0:none, 1:ShortNAVprotect, 2:LongNAVProtect
+ * TX_OP_ALLOW_CCK: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_OFDM: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_MM20: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_MM40: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_GF20: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_GF40: CCK TXOP allowance, 0:disallow
+ * RTS_TH_EN: RTS threshold enable on CCK TX
+ */
+#define CCK_PROT_CFG 0x1364
+#define CCK_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define CCK_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define CCK_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define CCK_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * OFDM_PROT_CFG: OFDM Protection
+ */
+#define OFDM_PROT_CFG 0x1368
+#define OFDM_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define OFDM_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define OFDM_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define OFDM_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * MM20_PROT_CFG: MM20 Protection
+ */
+#define MM20_PROT_CFG 0x136c
+#define MM20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define MM20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define MM20_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define MM20_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * MM40_PROT_CFG: MM40 Protection
+ */
+#define MM40_PROT_CFG 0x1370
+#define MM40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define MM40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define MM40_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define MM40_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * GF20_PROT_CFG: GF20 Protection
+ */
+#define GF20_PROT_CFG 0x1374
+#define GF20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define GF20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define GF20_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define GF20_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * GF40_PROT_CFG: GF40 Protection
+ */
+#define GF40_PROT_CFG 0x1378
+#define GF40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define GF40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define GF40_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define GF40_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * EXP_CTS_TIME:
+ */
+#define EXP_CTS_TIME 0x137c
+
+/*
+ * EXP_ACK_TIME:
+ */
+#define EXP_ACK_TIME 0x1380
+
+/*
+ * RX_FILTER_CFG: RX configuration register.
+ */
+#define RX_FILTER_CFG 0x1400
+#define RX_FILTER_CFG_DROP_CRC_ERROR FIELD32(0x00000001)
+#define RX_FILTER_CFG_DROP_PHY_ERROR FIELD32(0x00000002)
+#define RX_FILTER_CFG_DROP_NOT_TO_ME FIELD32(0x00000004)
+#define RX_FILTER_CFG_DROP_NOT_MY_BSSD FIELD32(0x00000008)
+#define RX_FILTER_CFG_DROP_VER_ERROR FIELD32(0x00000010)
+#define RX_FILTER_CFG_DROP_MULTICAST FIELD32(0x00000020)
+#define RX_FILTER_CFG_DROP_BROADCAST FIELD32(0x00000040)
+#define RX_FILTER_CFG_DROP_DUPLICATE FIELD32(0x00000080)
+#define RX_FILTER_CFG_DROP_CF_END_ACK FIELD32(0x00000100)
+#define RX_FILTER_CFG_DROP_CF_END FIELD32(0x00000200)
+#define RX_FILTER_CFG_DROP_ACK FIELD32(0x00000400)
+#define RX_FILTER_CFG_DROP_CTS FIELD32(0x00000800)
+#define RX_FILTER_CFG_DROP_RTS FIELD32(0x00001000)
+#define RX_FILTER_CFG_DROP_PSPOLL FIELD32(0x00002000)
+#define RX_FILTER_CFG_DROP_BA FIELD32(0x00004000)
+#define RX_FILTER_CFG_DROP_BAR FIELD32(0x00008000)
+#define RX_FILTER_CFG_DROP_CNTL FIELD32(0x00010000)
+
+/*
+ * AUTO_RSP_CFG:
+ * AUTORESPONDER: 0: disable, 1: enable
+ * BAC_ACK_POLICY: 0:long, 1:short preamble
+ * CTS_40_MMODE: Response CTS 40MHz duplicate mode
+ * CTS_40_MREF: Response CTS 40MHz duplicate mode
+ * AR_PREAMBLE: Auto responder preamble 0:long, 1:short preamble
+ * DUAL_CTS_EN: Power bit value in control frame
+ * ACK_CTS_PSM_BIT:Power bit value in control frame
+ */
+#define AUTO_RSP_CFG 0x1404
+#define AUTO_RSP_CFG_AUTORESPONDER FIELD32(0x00000001)
+#define AUTO_RSP_CFG_BAC_ACK_POLICY FIELD32(0x00000002)
+#define AUTO_RSP_CFG_CTS_40_MMODE FIELD32(0x00000004)
+#define AUTO_RSP_CFG_CTS_40_MREF FIELD32(0x00000008)
+#define AUTO_RSP_CFG_AR_PREAMBLE FIELD32(0x00000010)
+#define AUTO_RSP_CFG_DUAL_CTS_EN FIELD32(0x00000040)
+#define AUTO_RSP_CFG_ACK_CTS_PSM_BIT FIELD32(0x00000080)
+
+/*
+ * LEGACY_BASIC_RATE:
+ */
+#define LEGACY_BASIC_RATE 0x1408
+
+/*
+ * HT_BASIC_RATE:
+ */
+#define HT_BASIC_RATE 0x140c
+
+/*
+ * HT_CTRL_CFG:
+ */
+#define HT_CTRL_CFG 0x1410
+
+/*
+ * SIFS_COST_CFG:
+ */
+#define SIFS_COST_CFG 0x1414
+
+/*
+ * RX_PARSER_CFG:
+ * Set NAV for all received frames
+ */
+#define RX_PARSER_CFG 0x1418
+
+/*
+ * TX_SEC_CNT0:
+ */
+#define TX_SEC_CNT0 0x1500
+
+/*
+ * RX_SEC_CNT0:
+ */
+#define RX_SEC_CNT0 0x1504
+
+/*
+ * CCMP_FC_MUTE:
+ */
+#define CCMP_FC_MUTE 0x1508
+
+/*
+ * TXOP_HLDR_ADDR0:
+ */
+#define TXOP_HLDR_ADDR0 0x1600
+
+/*
+ * TXOP_HLDR_ADDR1:
+ */
+#define TXOP_HLDR_ADDR1 0x1604
+
+/*
+ * TXOP_HLDR_ET:
+ */
+#define TXOP_HLDR_ET 0x1608
+
+/*
+ * QOS_CFPOLL_RA_DW0:
+ */
+#define QOS_CFPOLL_RA_DW0 0x160c
+
+/*
+ * QOS_CFPOLL_RA_DW1:
+ */
+#define QOS_CFPOLL_RA_DW1 0x1610
+
+/*
+ * QOS_CFPOLL_QC:
+ */
+#define QOS_CFPOLL_QC 0x1614
+
+/*
+ * RX_STA_CNT0: RX PLCP error count & RX CRC error count
+ */
+#define RX_STA_CNT0 0x1700
+#define RX_STA_CNT0_CRC_ERR FIELD32(0x0000ffff)
+#define RX_STA_CNT0_PHY_ERR FIELD32(0xffff0000)
+
+/*
+ * RX_STA_CNT1: RX False CCA count & RX LONG frame count
+ */
+#define RX_STA_CNT1 0x1704
+#define RX_STA_CNT1_FALSE_CCA FIELD32(0x0000ffff)
+#define RX_STA_CNT1_PLCP_ERR FIELD32(0xffff0000)
+
+/*
+ * RX_STA_CNT2:
+ */
+#define RX_STA_CNT2 0x1708
+#define RX_STA_CNT2_RX_DUPLI_COUNT FIELD32(0x0000ffff)
+#define RX_STA_CNT2_RX_FIFO_OVERFLOW FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT0: TX Beacon count
+ */
+#define TX_STA_CNT0 0x170c
+#define TX_STA_CNT0_TX_FAIL_COUNT FIELD32(0x0000ffff)
+#define TX_STA_CNT0_TX_BEACON_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT1: TX tx count
+ */
+#define TX_STA_CNT1 0x1710
+#define TX_STA_CNT1_TX_SUCCESS FIELD32(0x0000ffff)
+#define TX_STA_CNT1_TX_RETRANSMIT FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT2: TX tx count
+ */
+#define TX_STA_CNT2 0x1714
+#define TX_STA_CNT2_TX_ZERO_LEN_COUNT FIELD32(0x0000ffff)
+#define TX_STA_CNT2_TX_UNDER_FLOW_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_STA_FIFO: TX Result for specific PID status fifo register
+ */
+#define TX_STA_FIFO 0x1718
+#define TX_STA_FIFO_VALID FIELD32(0x00000001)
+#define TX_STA_FIFO_PID_TYPE FIELD32(0x0000001e)
+#define TX_STA_FIFO_TX_SUCCESS FIELD32(0x00000020)
+#define TX_STA_FIFO_TX_AGGRE FIELD32(0x00000040)
+#define TX_STA_FIFO_TX_ACK_REQUIRED FIELD32(0x00000080)
+#define TX_STA_FIFO_WCID FIELD32(0x0000ff00)
+#define TX_STA_FIFO_SUCCESS_RATE FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT: Debug counter
+ */
+#define TX_AGG_CNT 0x171c
+#define TX_AGG_CNT_NON_AGG_TX_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT_AGG_TX_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT0:
+ */
+#define TX_AGG_CNT0 0x1720
+#define TX_AGG_CNT0_AGG_SIZE_1_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT0_AGG_SIZE_2_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT1:
+ */
+#define TX_AGG_CNT1 0x1724
+#define TX_AGG_CNT1_AGG_SIZE_3_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT1_AGG_SIZE_4_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT2:
+ */
+#define TX_AGG_CNT2 0x1728
+#define TX_AGG_CNT2_AGG_SIZE_5_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT2_AGG_SIZE_6_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT3:
+ */
+#define TX_AGG_CNT3 0x172c
+#define TX_AGG_CNT3_AGG_SIZE_7_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT3_AGG_SIZE_8_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT4:
+ */
+#define TX_AGG_CNT4 0x1730
+#define TX_AGG_CNT4_AGG_SIZE_9_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT4_AGG_SIZE_10_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT5:
+ */
+#define TX_AGG_CNT5 0x1734
+#define TX_AGG_CNT5_AGG_SIZE_11_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT5_AGG_SIZE_12_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT6:
+ */
+#define TX_AGG_CNT6 0x1738
+#define TX_AGG_CNT6_AGG_SIZE_13_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT6_AGG_SIZE_14_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT7:
+ */
+#define TX_AGG_CNT7 0x173c
+#define TX_AGG_CNT7_AGG_SIZE_15_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT7_AGG_SIZE_16_COUNT FIELD32(0xffff0000)
+
+/*
+ * MPDU_DENSITY_CNT:
+ * TX_ZERO_DEL: TX zero length delimiter count
+ * RX_ZERO_DEL: RX zero length delimiter count
+ */
+#define MPDU_DENSITY_CNT 0x1740
+#define MPDU_DENSITY_CNT_TX_ZERO_DEL FIELD32(0x0000ffff)
+#define MPDU_DENSITY_CNT_RX_ZERO_DEL FIELD32(0xffff0000)
+
+/*
+ * Security key table memory.
+ * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry
+ * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry
+ * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry
+ * MAC_WCID_ATTRIBUTE_BASE: 4-byte * 256-entry
+ * SHARED_KEY_TABLE_BASE: 32-byte * 16-entry
+ * SHARED_KEY_MODE_BASE: 4-byte * 16-entry
+ */
+#define MAC_WCID_BASE 0x1800
+#define PAIRWISE_KEY_TABLE_BASE 0x4000
+#define MAC_IVEIV_TABLE_BASE 0x6000
+#define MAC_WCID_ATTRIBUTE_BASE 0x6800
+#define SHARED_KEY_TABLE_BASE 0x6c00
+#define SHARED_KEY_MODE_BASE 0x7000
+
+#define MAC_WCID_ENTRY(__idx) \
+ ( MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)) )
+#define PAIRWISE_KEY_ENTRY(__idx) \
+ ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+#define MAC_IVEIV_ENTRY(__idx) \
+ ( MAC_IVEIV_TABLE_BASE + ((__idx) & sizeof(struct mac_iveiv_entry)) )
+#define MAC_WCID_ATTR_ENTRY(__idx) \
+ ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) )
+#define SHARED_KEY_ENTRY(__idx) \
+ ( SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+#define SHARED_KEY_MODE_ENTRY(__idx) \
+ ( SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)) )
+
+struct mac_wcid_entry {
+ u8 mac[6];
+ u8 reserved[2];
+} __attribute__ ((packed));
+
+struct hw_key_entry {
+ u8 key[16];
+ u8 tx_mic[8];
+ u8 rx_mic[8];
+} __attribute__ ((packed));
+
+struct mac_iveiv_entry {
+ u8 iv[8];
+} __attribute__ ((packed));
+
+/*
+ * MAC_WCID_ATTRIBUTE:
+ */
+#define MAC_WCID_ATTRIBUTE_KEYTAB FIELD32(0x00000001)
+#define MAC_WCID_ATTRIBUTE_CIPHER FIELD32(0x0000000e)
+#define MAC_WCID_ATTRIBUTE_BSS_IDX FIELD32(0x00000070)
+#define MAC_WCID_ATTRIBUTE_RX_WIUDF FIELD32(0x00000380)
+
+/*
+ * SHARED_KEY_MODE:
+ */
+#define SHARED_KEY_MODE_BSS0_KEY0 FIELD32(0x00000007)
+#define SHARED_KEY_MODE_BSS0_KEY1 FIELD32(0x00000070)
+#define SHARED_KEY_MODE_BSS0_KEY2 FIELD32(0x00000700)
+#define SHARED_KEY_MODE_BSS0_KEY3 FIELD32(0x00007000)
+#define SHARED_KEY_MODE_BSS1_KEY0 FIELD32(0x00070000)
+#define SHARED_KEY_MODE_BSS1_KEY1 FIELD32(0x00700000)
+#define SHARED_KEY_MODE_BSS1_KEY2 FIELD32(0x07000000)
+#define SHARED_KEY_MODE_BSS1_KEY3 FIELD32(0x70000000)
+
+/*
+ * HOST-MCU communication
+ */
+
+/*
+ * H2M_MAILBOX_CSR: Host-to-MCU Mailbox.
+ */
+#define H2M_MAILBOX_CSR 0x7010
+#define H2M_MAILBOX_CSR_ARG0 FIELD32(0x000000ff)
+#define H2M_MAILBOX_CSR_ARG1 FIELD32(0x0000ff00)
+#define H2M_MAILBOX_CSR_CMD_TOKEN FIELD32(0x00ff0000)
+#define H2M_MAILBOX_CSR_OWNER FIELD32(0xff000000)
+
+/*
+ * H2M_MAILBOX_CID:
+ */
+#define H2M_MAILBOX_CID 0x7014
+#define H2M_MAILBOX_CID_CMD0 FIELD32(0x000000ff)
+#define H2M_MAILBOX_CID_CMD1 FIELD32(0x0000ff00)
+#define H2M_MAILBOX_CID_CMD2 FIELD32(0x00ff0000)
+#define H2M_MAILBOX_CID_CMD3 FIELD32(0xff000000)
+
+/*
+ * H2M_MAILBOX_STATUS:
+ */
+#define H2M_MAILBOX_STATUS 0x701c
+
+/*
+ * H2M_INT_SRC:
+ */
+#define H2M_INT_SRC 0x7024
+
+/*
+ * H2M_BBP_AGENT:
+ */
+#define H2M_BBP_AGENT 0x7028
+
+/*
+ * MCU_LEDCS: LED control for MCU Mailbox.
+ */
+#define MCU_LEDCS_LED_MODE FIELD8(0x1f)
+#define MCU_LEDCS_POLARITY FIELD8(0x01)
+
+/*
+ * HW_CS_CTS_BASE:
+ * Carrier-sense CTS frame base address.
+ * It's where mac stores carrier-sense frame for carrier-sense function.
+ */
+#define HW_CS_CTS_BASE 0x7700
+
+/*
+ * HW_DFS_CTS_BASE:
+ * FS CTS frame base address. It's where mac stores CTS frame for DFS.
+ */
+#define HW_DFS_CTS_BASE 0x7780
+
+/*
+ * TXRX control registers - base address 0x3000
+ */
+
+/*
+ * TXRX_CSR1:
+ * rt2860b UNKNOWN reg use R/O Reg Addr 0x77d0 first..
+ */
+#define TXRX_CSR1 0x77d0
+
+/*
+ * HW_DEBUG_SETTING_BASE:
+ * since NULL frame won't be that long (256 byte)
+ * We steal 16 tail bytes to save debugging settings
+ */
+#define HW_DEBUG_SETTING_BASE 0x77f0
+#define HW_DEBUG_SETTING_BASE2 0x7770
+
+/*
+ * HW_BEACON_BASE
+ * In order to support maximum 8 MBSS and its maximum length
+ * is 512 bytes for each beacon
+ * Three section discontinue memory segments will be used.
+ * 1. The original region for BCN 0~3
+ * 2. Extract memory from FCE table for BCN 4~5
+ * 3. Extract memory from Pair-wise key table for BCN 6~7
+ * It occupied those memory of wcid 238~253 for BCN 6
+ * and wcid 222~237 for BCN 7
+ *
+ * IMPORTANT NOTE: Not sure why legacy driver does this,
+ * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6.
+ */
+#define HW_BEACON_BASE0 0x7800
+#define HW_BEACON_BASE1 0x7a00
+#define HW_BEACON_BASE2 0x7c00
+#define HW_BEACON_BASE3 0x7e00
+#define HW_BEACON_BASE4 0x7200
+#define HW_BEACON_BASE5 0x7400
+#define HW_BEACON_BASE6 0x5dc0
+#define HW_BEACON_BASE7 0x5bc0
+
+#define HW_BEACON_OFFSET(__index) \
+ ( ((__index) < 4) ? ( HW_BEACON_BASE0 + (__index * 0x0200) ) : \
+ (((__index) < 6) ? ( HW_BEACON_BASE4 + ((__index - 4) * 0x0200) ) : \
+ (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))) )
+
+/*
+ * 8051 firmware image.
+ */
+#define FIRMWARE_RT2870 "rt2870.bin"
+#define FIRMWARE_IMAGE_BASE 0x3000
+
+/*
+ * BBP registers.
+ * The wordsize of the BBP is 8 bits.
+ */
+
+/*
+ * BBP 1: TX Antenna
+ */
+#define BBP1_TX_POWER FIELD8(0x07)
+#define BBP1_TX_ANTENNA FIELD8(0x18)
+
+/*
+ * BBP 3: RX Antenna
+ */
+#define BBP3_RX_ANTENNA FIELD8(0x18)
+#define BBP3_HT40_PLUS FIELD8(0x20)
+
+/*
+ * BBP 4: Bandwidth
+ */
+#define BBP4_TX_BF FIELD8(0x01)
+#define BBP4_BANDWIDTH FIELD8(0x18)
+
+/*
+ * RFCSR registers
+ * The wordsize of the RFCSR is 8 bits.
+ */
+
+/*
+ * RFCSR 6:
+ */
+#define RFCSR6_R FIELD8(0x03)
+
+/*
+ * RFCSR 7:
+ */
+#define RFCSR7_RF_TUNING FIELD8(0x01)
+
+/*
+ * RFCSR 12:
+ */
+#define RFCSR12_TX_POWER FIELD8(0x1f)
+
+/*
+ * RFCSR 22:
+ */
+#define RFCSR22_BASEBAND_LOOPBACK FIELD8(0x01)
+
+/*
+ * RFCSR 23:
+ */
+#define RFCSR23_FREQ_OFFSET FIELD8(0x7f)
+
+/*
+ * RFCSR 30:
+ */
+#define RFCSR30_RF_CALIBRATION FIELD8(0x80)
+
+/*
+ * RF registers
+ */
+
+/*
+ * RF 2
+ */
+#define RF2_ANTENNA_RX2 FIELD32(0x00000040)
+#define RF2_ANTENNA_TX1 FIELD32(0x00004000)
+#define RF2_ANTENNA_RX1 FIELD32(0x00020000)
+
+/*
+ * RF 3
+ */
+#define RF3_TXPOWER_G FIELD32(0x00003e00)
+#define RF3_TXPOWER_A_7DBM_BOOST FIELD32(0x00000200)
+#define RF3_TXPOWER_A FIELD32(0x00003c00)
+
+/*
+ * RF 4
+ */
+#define RF4_TXPOWER_G FIELD32(0x000007c0)
+#define RF4_TXPOWER_A_7DBM_BOOST FIELD32(0x00000040)
+#define RF4_TXPOWER_A FIELD32(0x00000780)
+#define RF4_FREQ_OFFSET FIELD32(0x001f8000)
+#define RF4_HT40 FIELD32(0x00200000)
+
+/*
+ * EEPROM content.
+ * The wordsize of the EEPROM is 16 bits.
+ */
+
+/*
+ * EEPROM Version
+ */
+#define EEPROM_VERSION 0x0001
+#define EEPROM_VERSION_FAE FIELD16(0x00ff)
+#define EEPROM_VERSION_VERSION FIELD16(0xff00)
+
+/*
+ * HW MAC address.
+ */
+#define EEPROM_MAC_ADDR_0 0x0002
+#define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00)
+#define EEPROM_MAC_ADDR_1 0x0003
+#define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00)
+#define EEPROM_MAC_ADDR_2 0x0004
+#define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00)
+
+/*
+ * EEPROM ANTENNA config
+ * RXPATH: 1: 1R, 2: 2R, 3: 3R
+ * TXPATH: 1: 1T, 2: 2T
+ */
+#define EEPROM_ANTENNA 0x001a
+#define EEPROM_ANTENNA_RXPATH FIELD16(0x000f)
+#define EEPROM_ANTENNA_TXPATH FIELD16(0x00f0)
+#define EEPROM_ANTENNA_RF_TYPE FIELD16(0x0f00)
+
+/*
+ * EEPROM NIC config
+ * CARDBUS_ACCEL: 0 - enable, 1 - disable
+ */
+#define EEPROM_NIC 0x001b
+#define EEPROM_NIC_HW_RADIO FIELD16(0x0001)
+#define EEPROM_NIC_DYNAMIC_TX_AGC FIELD16(0x0002)
+#define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0004)
+#define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0008)
+#define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0010)
+#define EEPROM_NIC_BW40M_SB_BG FIELD16(0x0020)
+#define EEPROM_NIC_BW40M_SB_A FIELD16(0x0040)
+#define EEPROM_NIC_WPS_PBC FIELD16(0x0080)
+#define EEPROM_NIC_BW40M_BG FIELD16(0x0100)
+#define EEPROM_NIC_BW40M_A FIELD16(0x0200)
+
+/*
+ * EEPROM frequency
+ */
+#define EEPROM_FREQ 0x001d
+#define EEPROM_FREQ_OFFSET FIELD16(0x00ff)
+#define EEPROM_FREQ_LED_MODE FIELD16(0x7f00)
+#define EEPROM_FREQ_LED_POLARITY FIELD16(0x1000)
+
+/*
+ * EEPROM LED
+ * POLARITY_RDY_G: Polarity RDY_G setting.
+ * POLARITY_RDY_A: Polarity RDY_A setting.
+ * POLARITY_ACT: Polarity ACT setting.
+ * POLARITY_GPIO_0: Polarity GPIO0 setting.
+ * POLARITY_GPIO_1: Polarity GPIO1 setting.
+ * POLARITY_GPIO_2: Polarity GPIO2 setting.
+ * POLARITY_GPIO_3: Polarity GPIO3 setting.
+ * POLARITY_GPIO_4: Polarity GPIO4 setting.
+ * LED_MODE: Led mode.
+ */
+#define EEPROM_LED1 0x001e
+#define EEPROM_LED2 0x001f
+#define EEPROM_LED3 0x0020
+#define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001)
+#define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002)
+#define EEPROM_LED_POLARITY_ACT FIELD16(0x0004)
+#define EEPROM_LED_POLARITY_GPIO_0 FIELD16(0x0008)
+#define EEPROM_LED_POLARITY_GPIO_1 FIELD16(0x0010)
+#define EEPROM_LED_POLARITY_GPIO_2 FIELD16(0x0020)
+#define EEPROM_LED_POLARITY_GPIO_3 FIELD16(0x0040)
+#define EEPROM_LED_POLARITY_GPIO_4 FIELD16(0x0080)
+#define EEPROM_LED_LED_MODE FIELD16(0x1f00)
+
+/*
+ * EEPROM LNA
+ */
+#define EEPROM_LNA 0x0022
+#define EEPROM_LNA_BG FIELD16(0x00ff)
+#define EEPROM_LNA_A0 FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI BG offset
+ */
+#define EEPROM_RSSI_BG 0x0023
+#define EEPROM_RSSI_BG_OFFSET0 FIELD16(0x00ff)
+#define EEPROM_RSSI_BG_OFFSET1 FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI BG2 offset
+ */
+#define EEPROM_RSSI_BG2 0x0024
+#define EEPROM_RSSI_BG2_OFFSET2 FIELD16(0x00ff)
+#define EEPROM_RSSI_BG2_LNA_A1 FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI A offset
+ */
+#define EEPROM_RSSI_A 0x0025
+#define EEPROM_RSSI_A_OFFSET0 FIELD16(0x00ff)
+#define EEPROM_RSSI_A_OFFSET1 FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI A2 offset
+ */
+#define EEPROM_RSSI_A2 0x0026
+#define EEPROM_RSSI_A2_OFFSET2 FIELD16(0x00ff)
+#define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00)
+
+/*
+ * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
+ * This is delta in 40MHZ.
+ * VALUE: Tx Power dalta value (MAX=4)
+ * TYPE: 1: Plus the delta value, 0: minus the delta value
+ * TXPOWER: Enable:
+ */
+#define EEPROM_TXPOWER_DELTA 0x0028
+#define EEPROM_TXPOWER_DELTA_VALUE FIELD16(0x003f)
+#define EEPROM_TXPOWER_DELTA_TYPE FIELD16(0x0040)
+#define EEPROM_TXPOWER_DELTA_TXPOWER FIELD16(0x0080)
+
+/*
+ * EEPROM TXPOWER 802.11BG
+ */
+#define EEPROM_TXPOWER_BG1 0x0029
+#define EEPROM_TXPOWER_BG2 0x0030
+#define EEPROM_TXPOWER_BG_SIZE 7
+#define EEPROM_TXPOWER_BG_1 FIELD16(0x00ff)
+#define EEPROM_TXPOWER_BG_2 FIELD16(0xff00)
+
+/*
+ * EEPROM TXPOWER 802.11A
+ */
+#define EEPROM_TXPOWER_A1 0x003c
+#define EEPROM_TXPOWER_A2 0x0053
+#define EEPROM_TXPOWER_A_SIZE 6
+#define EEPROM_TXPOWER_A_1 FIELD16(0x00ff)
+#define EEPROM_TXPOWER_A_2 FIELD16(0xff00)
+
+/*
+ * EEPROM TXpower byrate: 20MHZ power
+ */
+#define EEPROM_TXPOWER_BYRATE 0x006f
+
+/*
+ * EEPROM BBP.
+ */
+#define EEPROM_BBP_START 0x0078
+#define EEPROM_BBP_SIZE 16
+#define EEPROM_BBP_VALUE FIELD16(0x00ff)
+#define EEPROM_BBP_REG_ID FIELD16(0xff00)
+
+/*
+ * MCU mailbox commands.
+ */
+#define MCU_SLEEP 0x30
+#define MCU_WAKEUP 0x31
+#define MCU_RADIO_OFF 0x35
+#define MCU_CURRENT 0x36
+#define MCU_LED 0x50
+#define MCU_LED_STRENGTH 0x51
+#define MCU_LED_1 0x52
+#define MCU_LED_2 0x53
+#define MCU_LED_3 0x54
+#define MCU_RADAR 0x60
+#define MCU_BOOT_SIGNAL 0x72
+#define MCU_BBP_SIGNAL 0x80
+#define MCU_POWER_SAVE 0x83
+
+/*
+ * MCU mailbox tokens
+ */
+#define TOKEN_WAKUP 3
+
+/*
+ * DMA descriptor defines.
+ */
+#define TXD_DESC_SIZE ( 4 * sizeof(__le32) )
+#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
+#define TXWI_DESC_SIZE ( 4 * sizeof(__le32) )
+#define RXD_DESC_SIZE ( 1 * sizeof(__le32) )
+#define RXWI_DESC_SIZE ( 4 * sizeof(__le32) )
+
+/*
+ * TX descriptor format for TX, PRIO and Beacon Ring.
+ */
+
+/*
+ * Word0
+ */
+#define TXD_W0_SD_PTR0 FIELD32(0xffffffff)
+
+/*
+ * Word1
+ */
+#define TXD_W1_SD_LEN1 FIELD32(0x00003fff)
+#define TXD_W1_LAST_SEC1 FIELD32(0x00004000)
+#define TXD_W1_BURST FIELD32(0x00008000)
+#define TXD_W1_SD_LEN0 FIELD32(0x3fff0000)
+#define TXD_W1_LAST_SEC0 FIELD32(0x40000000)
+#define TXD_W1_DMA_DONE FIELD32(0x80000000)
+
+/*
+ * Word2
+ */
+#define TXD_W2_SD_PTR1 FIELD32(0xffffffff)
+
+/*
+ * Word3
+ * WIV: Wireless Info Valid. 1: Driver filled WI, 0: DMA needs to copy WI
+ * QSEL: Select on-chip FIFO ID for 2nd-stage output scheduler.
+ * 0:MGMT, 1:HCCA 2:EDCA
+ */
+#define TXD_W3_WIV FIELD32(0x01000000)
+#define TXD_W3_QSEL FIELD32(0x06000000)
+#define TXD_W3_TCO FIELD32(0x20000000)
+#define TXD_W3_UCO FIELD32(0x40000000)
+#define TXD_W3_ICO FIELD32(0x80000000)
+
+/*
+ * TX Info structure
+ */
+
+/*
+ * Word0
+ * WIV: Wireless Info Valid. 1: Driver filled WI, 0: DMA needs to copy WI
+ * QSEL: Select on-chip FIFO ID for 2nd-stage output scheduler.
+ * 0:MGMT, 1:HCCA 2:EDCA
+ * USB_DMA_NEXT_VALID: Used ONLY in USB bulk Aggregation, NextValid
+ * DMA_TX_BURST: used ONLY in USB bulk Aggregation.
+ * Force USB DMA transmit frame from current selected endpoint
+ */
+#define TXINFO_W0_USB_DMA_TX_PKT_LEN FIELD32(0x0000ffff)
+#define TXINFO_W0_WIV FIELD32(0x01000000)
+#define TXINFO_W0_QSEL FIELD32(0x06000000)
+#define TXINFO_W0_SW_USE_LAST_ROUND FIELD32(0x08000000)
+#define TXINFO_W0_USB_DMA_NEXT_VALID FIELD32(0x40000000)
+#define TXINFO_W0_USB_DMA_TX_BURST FIELD32(0x80000000)
+
+/*
+ * TX WI structure
+ */
+
+/*
+ * Word0
+ * FRAG: 1 To inform TKIP engine this is a fragment.
+ * MIMO_PS: The remote peer is in dynamic MIMO-PS mode
+ * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs
+ * BW: Channel bandwidth 20MHz or 40 MHz
+ * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED
+ */
+#define TXWI_W0_FRAG FIELD32(0x00000001)
+#define TXWI_W0_MIMO_PS FIELD32(0x00000002)
+#define TXWI_W0_CF_ACK FIELD32(0x00000004)
+#define TXWI_W0_TS FIELD32(0x00000008)
+#define TXWI_W0_AMPDU FIELD32(0x00000010)
+#define TXWI_W0_MPDU_DENSITY FIELD32(0x000000e0)
+#define TXWI_W0_TX_OP FIELD32(0x00000300)
+#define TXWI_W0_MCS FIELD32(0x007f0000)
+#define TXWI_W0_BW FIELD32(0x00800000)
+#define TXWI_W0_SHORT_GI FIELD32(0x01000000)
+#define TXWI_W0_STBC FIELD32(0x06000000)
+#define TXWI_W0_IFS FIELD32(0x08000000)
+#define TXWI_W0_PHYMODE FIELD32(0xc0000000)
+
+/*
+ * Word1
+ */
+#define TXWI_W1_ACK FIELD32(0x00000001)
+#define TXWI_W1_NSEQ FIELD32(0x00000002)
+#define TXWI_W1_BW_WIN_SIZE FIELD32(0x000000fc)
+#define TXWI_W1_WIRELESS_CLI_ID FIELD32(0x0000ff00)
+#define TXWI_W1_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000)
+#define TXWI_W1_PACKETID FIELD32(0xf0000000)
+
+/*
+ * Word2
+ */
+#define TXWI_W2_IV FIELD32(0xffffffff)
+
+/*
+ * Word3
+ */
+#define TXWI_W3_EIV FIELD32(0xffffffff)
+
+/*
+ * RX descriptor format for RX Ring.
+ */
+
+/*
+ * Word0
+ * UNICAST_TO_ME: This RX frame is unicast to me.
+ * MULTICAST: This is a multicast frame.
+ * BROADCAST: This is a broadcast frame.
+ * MY_BSS: this frame belongs to the same BSSID.
+ * CRC_ERROR: CRC error.
+ * CIPHER_ERROR: 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid.
+ * AMSDU: rx with 802.3 header, not 802.11 header.
+ */
+
+#define RXD_W0_BA FIELD32(0x00000001)
+#define RXD_W0_DATA FIELD32(0x00000002)
+#define RXD_W0_NULLDATA FIELD32(0x00000004)
+#define RXD_W0_FRAG FIELD32(0x00000008)
+#define RXD_W0_UNICAST_TO_ME FIELD32(0x00000010)
+#define RXD_W0_MULTICAST FIELD32(0x00000020)
+#define RXD_W0_BROADCAST FIELD32(0x00000040)
+#define RXD_W0_MY_BSS FIELD32(0x00000080)
+#define RXD_W0_CRC_ERROR FIELD32(0x00000100)
+#define RXD_W0_CIPHER_ERROR FIELD32(0x00000600)
+#define RXD_W0_AMSDU FIELD32(0x00000800)
+#define RXD_W0_HTC FIELD32(0x00001000)
+#define RXD_W0_RSSI FIELD32(0x00002000)
+#define RXD_W0_L2PAD FIELD32(0x00004000)
+#define RXD_W0_AMPDU FIELD32(0x00008000)
+#define RXD_W0_DECRYPTED FIELD32(0x00010000)
+#define RXD_W0_PLCP_RSSI FIELD32(0x00020000)
+#define RXD_W0_CIPHER_ALG FIELD32(0x00040000)
+#define RXD_W0_LAST_AMSDU FIELD32(0x00080000)
+#define RXD_W0_PLCP_SIGNAL FIELD32(0xfff00000)
+
+/*
+ * RX WI structure
+ */
+
+/*
+ * Word0
+ */
+#define RXWI_W0_WIRELESS_CLI_ID FIELD32(0x000000ff)
+#define RXWI_W0_KEY_INDEX FIELD32(0x00000300)
+#define RXWI_W0_BSSID FIELD32(0x00001c00)
+#define RXWI_W0_UDF FIELD32(0x0000e000)
+#define RXWI_W0_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000)
+#define RXWI_W0_TID FIELD32(0xf0000000)
+
+/*
+ * Word1
+ */
+#define RXWI_W1_FRAG FIELD32(0x0000000f)
+#define RXWI_W1_SEQUENCE FIELD32(0x0000fff0)
+#define RXWI_W1_MCS FIELD32(0x007f0000)
+#define RXWI_W1_BW FIELD32(0x00800000)
+#define RXWI_W1_SHORT_GI FIELD32(0x01000000)
+#define RXWI_W1_STBC FIELD32(0x06000000)
+#define RXWI_W1_PHYMODE FIELD32(0xc0000000)
+
+/*
+ * Word2
+ */
+#define RXWI_W2_RSSI0 FIELD32(0x000000ff)
+#define RXWI_W2_RSSI1 FIELD32(0x0000ff00)
+#define RXWI_W2_RSSI2 FIELD32(0x00ff0000)
+
+/*
+ * Word3
+ */
+#define RXWI_W3_SNR0 FIELD32(0x000000ff)
+#define RXWI_W3_SNR1 FIELD32(0x0000ff00)
+
+/*
+ * Macro's for converting txpower from EEPROM to mac80211 value
+ * and from mac80211 value to register value.
+ */
+#define MIN_G_TXPOWER 0
+#define MIN_A_TXPOWER -7
+#define MAX_G_TXPOWER 31
+#define MAX_A_TXPOWER 15
+#define DEFAULT_TXPOWER 5
+
+#define TXPOWER_G_FROM_DEV(__txpower) \
+ ((__txpower) > MAX_G_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_G_TO_DEV(__txpower) \
+ clamp_t(char, __txpower, MIN_G_TXPOWER, MAX_G_TXPOWER)
+
+#define TXPOWER_A_FROM_DEV(__txpower) \
+ ((__txpower) > MAX_A_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_A_TO_DEV(__txpower) \
+ clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER)
+
+#endif /* RT2800USB_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 84bd6f19acb0..419b1b9f998e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -103,6 +103,15 @@
#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
/*
+ * Determine the alignment requirement,
+ * to make sure the 802.11 payload is padded to a 4-byte boundrary
+ * we must determine the address of the payload and calculate the
+ * amount of bytes needed to move the data.
+ */
+#define ALIGN_SIZE(__skb, __header) \
+ ( ((unsigned long)((__skb)->data + (__header))) & 3 )
+
+/*
* Standard timing and size defines.
* These values should follow the ieee80211 specifications.
*/
@@ -138,6 +147,7 @@ struct rt2x00_chip {
#define RT2561 0x0302
#define RT2661 0x0401
#define RT2571 0x1300
+#define RT2870 0x1600
u16 rf;
u32 rev;
@@ -357,6 +367,7 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
* for @tx_power_a, @tx_power_bg and @channels.
* @channels: Device/chipset specific channel values (See &struct rf_channel).
* @channels_info: Additional information for channels (See &struct channel_info).
+ * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
*/
struct hw_mode_spec {
unsigned int supported_bands;
@@ -370,6 +381,8 @@ struct hw_mode_spec {
unsigned int num_channels;
const struct rf_channel *channels;
const struct channel_info *channels_info;
+
+ struct ieee80211_sta_ht_cap ht;
};
/*
@@ -590,6 +603,7 @@ enum rt2x00_flags {
DRIVER_REQUIRE_SCHEDULED,
DRIVER_REQUIRE_DMA,
DRIVER_REQUIRE_COPY_IV,
+ DRIVER_REQUIRE_L2PAD,
/*
* Driver features
@@ -606,6 +620,7 @@ enum rt2x00_flags {
CONFIG_EXTERNAL_LNA_BG,
CONFIG_DOUBLE_ANTENNA,
CONFIG_DISABLE_LINK_TUNING,
+ CONFIG_CHANNEL_HT40,
};
/*
@@ -672,6 +687,12 @@ struct rt2x00_dev {
unsigned long flags;
/*
+ * Device information, Bus IRQ and name (PCI, SoC)
+ */
+ int irq;
+ const char *name;
+
+ /*
* Chipset identification.
*/
struct rt2x00_chip chip;
@@ -772,6 +793,13 @@ struct rt2x00_dev {
u8 freq_offset;
/*
+ * Calibration information (for rt2800usb & rt2800pci).
+ * [0] -> BW20
+ * [1] -> BW40
+ */
+ u8 calibration[2];
+
+ /*
* Low level statistics which will have
* to be kept up to date while device is running.
*/
@@ -860,6 +888,18 @@ static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev,
rt2x00dev->chip.rev = rev;
}
+static inline void rt2x00_set_chip_rt(struct rt2x00_dev *rt2x00dev,
+ const u16 rt)
+{
+ rt2x00dev->chip.rt = rt;
+}
+
+static inline void rt2x00_set_chip_rf(struct rt2x00_dev *rt2x00dev,
+ const u16 rf, const u32 rev)
+{
+ rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev);
+}
+
static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip)
{
return (chipset->rt == chip);
@@ -875,11 +915,10 @@ static inline u32 rt2x00_rev(const struct rt2x00_chip *chipset)
return chipset->rev;
}
-static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
- const u32 rev)
+static inline bool rt2x00_check_rev(const struct rt2x00_chip *chipset,
+ const u32 mask, const u32 rev)
{
- return (((chipset->rev & 0xffff0) == rev) &&
- !!(chipset->rev & 0x0000f));
+ return ((chipset->rev & mask) == rev);
}
/**
@@ -925,9 +964,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf);
int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
-int rt2x00mac_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf);
void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags,
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 9c2f5517af2a..863e399d4fa6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -173,6 +173,11 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
libconf.conf = conf;
if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
+ if (conf_is_ht40(conf))
+ __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+ else
+ __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+
memcpy(&libconf.rf,
&rt2x00dev->spec.channels[conf->channel->hw_value],
sizeof(libconf.rf));
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index 0b41845d9543..57ab42cfed34 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -65,7 +65,8 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
__set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags);
txdesc->key_idx = hw_key->hw_key_idx;
- txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb);
+ txdesc->iv_offset = txdesc->header_length;
+ txdesc->iv_len = hw_key->iv_len;
if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
__set_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags);
@@ -103,47 +104,44 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
return overhead;
}
-void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len)
+void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
- if (unlikely(!iv_len))
+ if (unlikely(!txdesc->iv_len))
return;
/* Copy IV/EIV data */
- memcpy(skbdesc->iv, skb->data + header_length, iv_len);
+ memcpy(skbdesc->iv, skb->data + txdesc->iv_offset, txdesc->iv_len);
}
-void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len)
+void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
- if (unlikely(!iv_len))
+ if (unlikely(!txdesc->iv_len))
return;
/* Copy IV/EIV data */
- memcpy(skbdesc->iv, skb->data + header_length, iv_len);
+ memcpy(skbdesc->iv, skb->data + txdesc->iv_offset, txdesc->iv_len);
/* Move ieee80211 header */
- memmove(skb->data + iv_len, skb->data, header_length);
+ memmove(skb->data + txdesc->iv_len, skb->data, txdesc->iv_offset);
/* Pull buffer to correct size */
- skb_pull(skb, iv_len);
+ skb_pull(skb, txdesc->iv_len);
/* IV/EIV data has officially be stripped */
- skbdesc->flags |= FRAME_DESC_IV_STRIPPED;
+ skbdesc->flags |= SKBDESC_IV_STRIPPED;
}
-void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
+void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
const unsigned int iv_len =
((!!(skbdesc->iv[0])) * 4) + ((!!(skbdesc->iv[1])) * 4);
- if (!(skbdesc->flags & FRAME_DESC_IV_STRIPPED))
+ if (!(skbdesc->flags & SKBDESC_IV_STRIPPED))
return;
skb_push(skb, iv_len);
@@ -155,14 +153,15 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
memcpy(skb->data + header_length, skbdesc->iv, iv_len);
/* IV/EIV data has returned into the frame */
- skbdesc->flags &= ~FRAME_DESC_IV_STRIPPED;
+ skbdesc->flags &= ~SKBDESC_IV_STRIPPED;
}
-void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
+void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
unsigned int header_length,
struct rxdone_entry_desc *rxdesc)
{
unsigned int payload_len = rxdesc->size - header_length;
+ unsigned int align = ALIGN_SIZE(skb, header_length);
unsigned int iv_len;
unsigned int icv_len;
unsigned int transfer = 0;
@@ -192,32 +191,48 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
}
/*
- * Make room for new data, note that we increase both
- * headsize and tailsize when required. The tailsize is
- * only needed when ICV data needs to be inserted and
- * the padding is smaller than the ICV data.
- * When alignment requirements is greater than the
- * ICV data we must trim the skb to the correct size
- * because we need to remove the extra bytes.
+ * Make room for new data. There are 2 possibilities
+ * either the alignment is already present between
+ * the 802.11 header and payload. In that case we
+ * we have to move the header less then the iv_len
+ * since we can use the already available l2pad bytes
+ * for the iv data.
+ * When the alignment must be added manually we must
+ * move the header more then iv_len since we must
+ * make room for the payload move as well.
*/
- skb_push(skb, iv_len + align);
- if (align < icv_len)
- skb_put(skb, icv_len - align);
- else if (align > icv_len)
- skb_trim(skb, rxdesc->size + iv_len + icv_len);
+ if (l2pad) {
+ skb_push(skb, iv_len - align);
+ skb_put(skb, icv_len);
- /* Move ieee80211 header */
- memmove(skb->data + transfer,
- skb->data + transfer + iv_len + align,
- header_length);
- transfer += header_length;
+ /* Move ieee80211 header */
+ memmove(skb->data + transfer,
+ skb->data + transfer + (iv_len - align),
+ header_length);
+ transfer += header_length;
+ } else {
+ skb_push(skb, iv_len + align);
+ if (align < icv_len)
+ skb_put(skb, icv_len - align);
+ else if (align > icv_len)
+ skb_trim(skb, rxdesc->size + iv_len + icv_len);
+
+ /* Move ieee80211 header */
+ memmove(skb->data + transfer,
+ skb->data + transfer + iv_len + align,
+ header_length);
+ transfer += header_length;
+ }
/* Copy IV/EIV data */
memcpy(skb->data + transfer, rxdesc->iv, iv_len);
transfer += iv_len;
- /* Move payload */
- if (align) {
+ /*
+ * Move payload for alignment purposes. Note that
+ * this is only needed when no l2 padding is present.
+ */
+ if (!l2pad) {
memmove(skb->data + transfer,
skb->data + transfer + align,
payload_len);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 5752aaae906b..f2270845072a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -227,6 +227,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
+ unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
u8 rate_idx, rate_flags;
/*
@@ -235,13 +236,19 @@ void rt2x00lib_txdone(struct queue_entry *entry,
rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
/*
+ * Remove L2 padding which was added during
+ */
+ if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
+ rt2x00queue_payload_align(entry->skb, true, header_length);
+
+ /*
* If the IV/EIV data was stripped from the frame before it was
* passed to the hardware, we should now reinsert it again because
* mac80211 will expect the the same data to be present it the
* frame as it was passed to us.
*/
if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
- rt2x00crypto_tx_insert_iv(entry->skb);
+ rt2x00crypto_tx_insert_iv(entry->skb, header_length);
/*
* Send frame to debugfs immediately, after this call is completed
@@ -316,19 +323,54 @@ void rt2x00lib_txdone(struct queue_entry *entry,
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
+static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
+ struct rxdone_entry_desc *rxdesc)
+{
+ struct ieee80211_supported_band *sband;
+ const struct rt2x00_rate *rate;
+ unsigned int i;
+ int signal;
+ int type;
+
+ /*
+ * For non-HT rates the MCS value needs to contain the
+ * actually used rate modulation (CCK or OFDM).
+ */
+ if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
+ signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal);
+ else
+ signal = rxdesc->signal;
+
+ type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
+
+ sband = &rt2x00dev->bands[rt2x00dev->curr_band];
+ for (i = 0; i < sband->n_bitrates; i++) {
+ rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
+
+ if (((type == RXDONE_SIGNAL_PLCP) &&
+ (rate->plcp == signal)) ||
+ ((type == RXDONE_SIGNAL_BITRATE) &&
+ (rate->bitrate == signal)) ||
+ ((type == RXDONE_SIGNAL_MCS) &&
+ (rate->mcs == signal))) {
+ return i;
+ }
+ }
+
+ WARNING(rt2x00dev, "Frame received with unrecognized signal, "
+ "signal=0x%.4x, type=%d.\n", signal, type);
+ return 0;
+}
+
void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
struct rxdone_entry_desc rxdesc;
struct sk_buff *skb;
struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
- struct ieee80211_supported_band *sband;
- const struct rt2x00_rate *rate;
unsigned int header_length;
- unsigned int align;
- unsigned int i;
- int idx = -1;
-
+ bool l2pad;
+ int rate_idx;
/*
* Allocate a new sk_buffer. If no new buffer available, drop the
* received frame and reuse the existing buffer.
@@ -348,12 +390,15 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
memset(&rxdesc, 0, sizeof(rxdesc));
rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
+ /* Trim buffer to correct size */
+ skb_trim(entry->skb, rxdesc.size);
+
/*
* The data behind the ieee80211 header must be
* aligned on a 4 byte boundary.
*/
header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
- align = ((unsigned long)(entry->skb->data + header_length)) & 3;
+ l2pad = !!(rxdesc.dev_flags & RXDONE_L2PAD);
/*
* Hardware might have stripped the IV/EIV/ICV data,
@@ -362,40 +407,24 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
* in which case we should reinsert the data into the frame.
*/
if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) &&
- (rxdesc.flags & RX_FLAG_IV_STRIPPED)) {
- rt2x00crypto_rx_insert_iv(entry->skb, align,
- header_length, &rxdesc);
- } else if (align) {
- skb_push(entry->skb, align);
- /* Move entire frame in 1 command */
- memmove(entry->skb->data, entry->skb->data + align,
- rxdesc.size);
- }
-
- /* Update data pointers, trim buffer to correct size */
- skb_trim(entry->skb, rxdesc.size);
+ (rxdesc.flags & RX_FLAG_IV_STRIPPED))
+ rt2x00crypto_rx_insert_iv(entry->skb, l2pad, header_length,
+ &rxdesc);
+ else
+ rt2x00queue_payload_align(entry->skb, l2pad, header_length);
/*
- * Update RX statistics.
+ * Check if the frame was received using HT. In that case,
+ * the rate is the MCS index and should be passed to mac80211
+ * directly. Otherwise we need to translate the signal to
+ * the correct bitrate index.
*/
- sband = &rt2x00dev->bands[rt2x00dev->curr_band];
- for (i = 0; i < sband->n_bitrates; i++) {
- rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
-
- if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
- (rate->plcp == rxdesc.signal)) ||
- ((rxdesc.dev_flags & RXDONE_SIGNAL_BITRATE) &&
- (rate->bitrate == rxdesc.signal))) {
- idx = i;
- break;
- }
- }
-
- if (idx < 0) {
- WARNING(rt2x00dev, "Frame received with unrecognized signal,"
- "signal=0x%.2x, type=%d.\n", rxdesc.signal,
- (rxdesc.dev_flags & RXDONE_SIGNAL_MASK));
- idx = 0;
+ if (rxdesc.rate_mode == RATE_MODE_CCK ||
+ rxdesc.rate_mode == RATE_MODE_OFDM) {
+ rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
+ } else {
+ rxdesc.flags |= RX_FLAG_HT;
+ rate_idx = rxdesc.signal;
}
/*
@@ -405,7 +434,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
rx_status->mactime = rxdesc.timestamp;
- rx_status->rate_idx = idx;
+ rx_status->rate_idx = rate_idx;
rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
rx_status->signal = rxdesc.rssi;
rx_status->noise = rxdesc.noise;
@@ -440,72 +469,84 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
.bitrate = 10,
.ratemask = BIT(0),
.plcp = 0x00,
+ .mcs = RATE_MCS(RATE_MODE_CCK, 0),
},
{
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
.bitrate = 20,
.ratemask = BIT(1),
.plcp = 0x01,
+ .mcs = RATE_MCS(RATE_MODE_CCK, 1),
},
{
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
.bitrate = 55,
.ratemask = BIT(2),
.plcp = 0x02,
+ .mcs = RATE_MCS(RATE_MODE_CCK, 2),
},
{
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
.bitrate = 110,
.ratemask = BIT(3),
.plcp = 0x03,
+ .mcs = RATE_MCS(RATE_MODE_CCK, 3),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 60,
.ratemask = BIT(4),
.plcp = 0x0b,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 0),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 90,
.ratemask = BIT(5),
.plcp = 0x0f,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 1),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 120,
.ratemask = BIT(6),
.plcp = 0x0a,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 2),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 180,
.ratemask = BIT(7),
.plcp = 0x0e,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 3),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 240,
.ratemask = BIT(8),
.plcp = 0x09,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 4),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 360,
.ratemask = BIT(9),
.plcp = 0x0d,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 5),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 480,
.ratemask = BIT(10),
.plcp = 0x08,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 6),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 540,
.ratemask = BIT(11),
.plcp = 0x0c,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 7),
},
};
@@ -581,6 +622,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates;
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&rt2x00dev->bands[IEEE80211_BAND_2GHZ];
+ memcpy(&rt2x00dev->bands[IEEE80211_BAND_2GHZ].ht_cap,
+ &spec->ht, sizeof(spec->ht));
}
/*
@@ -597,6 +640,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4];
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&rt2x00dev->bands[IEEE80211_BAND_5GHZ];
+ memcpy(&rt2x00dev->bands[IEEE80211_BAND_5GHZ].ht_cap,
+ &spec->ht, sizeof(spec->ht));
}
return 0;
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
new file mode 100644
index 000000000000..e3cec839e540
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -0,0 +1,69 @@
+/*
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.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.
+ */
+
+/*
+ Module: rt2x00lib
+ Abstract: rt2x00 HT specific routines.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "rt2x00.h"
+#include "rt2x00lib.h"
+
+void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
+ struct txentry_desc *txdesc,
+ const struct rt2x00_rate *hwrate)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+ struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
+
+ if (tx_info->control.sta)
+ txdesc->mpdu_density =
+ tx_info->control.sta->ht_cap.ampdu_density;
+ else
+ txdesc->mpdu_density = 0;
+
+ txdesc->ba_size = 7; /* FIXME: What value is needed? */
+ txdesc->stbc = 0; /* FIXME: What value is needed? */
+
+ txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
+ if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ txdesc->mcs |= 0x08;
+
+ /*
+ * Convert flags
+ */
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
+ __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
+
+ /*
+ * Determine HT Mix/Greenfield rate mode
+ */
+ if (txrate->flags & IEEE80211_TX_RC_MCS)
+ txdesc->rate_mode = RATE_MODE_HT_MIX;
+ if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+ txdesc->rate_mode = RATE_MODE_HT_GREENFIELD;
+ if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
+ if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+ __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
+}
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index d83e3794d340..0bf2715fa93a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -32,8 +32,8 @@
* Interval defines
* Both the link tuner as the rfkill will be called once per second.
*/
-#define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) )
-#define RFKILL_POLL_INTERVAL ( 1000 )
+#define LINK_TUNE_INTERVAL round_jiffies_relative(HZ)
+#define RFKILL_POLL_INTERVAL 1000
/*
* rt2x00_rate: Per rate device information
@@ -48,6 +48,7 @@ struct rt2x00_rate {
unsigned short ratemask;
unsigned short plcp;
+ unsigned short mcs;
};
extern const struct rt2x00_rate rt2x00_supported_rates[12];
@@ -57,6 +58,14 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value)
return &rt2x00_supported_rates[hw_value & 0xff];
}
+#define RATE_MCS(__mode, __mcs) \
+ ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) )
+
+static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
+{
+ return (mcs_value & 0x00ff);
+}
+
/*
* Radio control handlers.
*/
@@ -113,6 +122,23 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
/**
+ * rt2x00queue_payload_align - Align 802.11 payload to 4-byte boundary
+ * @skb: The skb to align
+ * @l2pad: Should L2 padding be used
+ * @header_length: Length of 802.11 header
+ *
+ * This function prepares the @skb to be send to the device or mac80211.
+ * If @l2pad is set to true padding will occur between the 802.11 header
+ * and payload. Otherwise the padding will be done in front of the 802.11
+ * header.
+ * When @l2pad is set the function will check for the &SKBDESC_L2_PADDED
+ * flag in &skb_frame_desc. If that flag is set, the padding is removed
+ * and the flag cleared. Otherwise the padding is added and the flag is set.
+ */
+void rt2x00queue_payload_align(struct sk_buff *skb,
+ bool l2pad, unsigned int header_length);
+
+/**
* rt2x00queue_write_tx_frame - Write TX frame to hardware
* @queue: Queue over which the frame should be send
* @skb: The skb to send
@@ -295,10 +321,12 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc);
unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb);
-void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len);
-void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len);
-void rt2x00crypto_tx_insert_iv(struct sk_buff *skb);
-void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
+void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
+ struct txentry_desc *txdesc);
+void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
+ struct txentry_desc *txdesc);
+void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length);
+void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
unsigned int header_length,
struct rxdone_entry_desc *rxdesc);
#else
@@ -319,21 +347,21 @@ static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev
}
static inline void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
- unsigned int iv_len)
+ struct txentry_desc *txdesc)
{
}
static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
- unsigned int iv_len)
+ struct txentry_desc *txdesc)
{
}
-static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
+static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb,
+ unsigned int header_length)
{
}
-static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
- unsigned int align,
+static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
unsigned int header_length,
struct rxdone_entry_desc *rxdesc)
{
@@ -341,6 +369,21 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
#endif /* CONFIG_RT2X00_LIB_CRYPTO */
/*
+ * HT handlers.
+ */
+#ifdef CONFIG_RT2X00_LIB_HT
+void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
+ struct txentry_desc *txdesc,
+ const struct rt2x00_rate *hwrate);
+#else
+static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
+ struct txentry_desc *txdesc,
+ const struct rt2x00_rate *hwrate)
+{
+}
+#endif /* CONFIG_RT2X00_LIB_HT */
+
+/*
* RFkill handlers.
*/
#ifdef CONFIG_RT2X00_LIB_RFKILL
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 7eb5cd7e5f32..eb9b981b9139 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -387,7 +387,7 @@ void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna)
rt2x00link_antenna_reset(rt2x00dev);
}
-void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev)
+static void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev)
{
struct link_qual *qual = &rt2x00dev->link.qual;
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index c41a0b9e473d..c4c06b4e1f08 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -390,56 +390,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
}
EXPORT_SYMBOL_GPL(rt2x00mac_config);
-int rt2x00mac_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct rt2x00_dev *rt2x00dev = hw->priv;
- struct rt2x00_intf *intf = vif_to_intf(vif);
- int update_bssid = 0;
- int status = 0;
-
- /*
- * Mac80211 might be calling this function while we are trying
- * to remove the device or perhaps suspending it.
- */
- if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
- return 0;
-
- spin_lock(&intf->lock);
-
- /*
- * conf->bssid can be NULL if coming from the internal
- * beacon update routine.
- */
- if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
- update_bssid = 1;
- memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
- }
-
- spin_unlock(&intf->lock);
-
- /*
- * Call rt2x00_config_intf() outside of the spinlock context since
- * the call will sleep for USB drivers. By using the ieee80211_if_conf
- * values as arguments we make keep access to rt2x00_intf thread safe
- * even without the lock.
- */
- rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
- update_bssid ? conf->bssid : NULL);
-
- /*
- * Update the beacon.
- */
- if (conf->changed & (IEEE80211_IFCC_BEACON |
- IEEE80211_IFCC_BEACON_ENABLED))
- status = rt2x00queue_update_beacon(rt2x00dev, vif,
- conf->enable_beacon);
-
- return status;
-}
-EXPORT_SYMBOL_GPL(rt2x00mac_config_interface);
-
void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags,
@@ -623,6 +573,44 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
struct rt2x00_dev *rt2x00dev = hw->priv;
struct rt2x00_intf *intf = vif_to_intf(vif);
unsigned int delayed = 0;
+ int update_bssid = 0;
+
+ /*
+ * Mac80211 might be calling this function while we are trying
+ * to remove the device or perhaps suspending it.
+ */
+ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+ return;
+
+ spin_lock(&intf->lock);
+
+ /*
+ * conf->bssid can be NULL if coming from the internal
+ * beacon update routine.
+ */
+ if (changes & BSS_CHANGED_BSSID) {
+ update_bssid = 1;
+ memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN);
+ }
+
+ spin_unlock(&intf->lock);
+
+ /*
+ * Call rt2x00_config_intf() outside of the spinlock context since
+ * the call will sleep for USB drivers. By using the ieee80211_if_conf
+ * values as arguments we make keep access to rt2x00_intf thread safe
+ * even without the lock.
+ */
+ if (changes & BSS_CHANGED_BSSID)
+ rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
+ update_bssid ? bss_conf->bssid : NULL);
+
+ /*
+ * Update the beacon.
+ */
+ if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED))
+ rt2x00queue_update_beacon(rt2x00dev, vif,
+ bss_conf->enable_beacon);
/*
* When the association status has changed we must reset the link
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 9730b4f8fd26..cdd5154bd4c0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -170,7 +170,6 @@ static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
{
- struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
struct data_queue *queue;
int status;
@@ -186,11 +185,11 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
/*
* Register interrupt handler.
*/
- status = request_irq(pci_dev->irq, rt2x00dev->ops->lib->irq_handler,
- IRQF_SHARED, pci_name(pci_dev), rt2x00dev);
+ status = request_irq(rt2x00dev->irq, rt2x00dev->ops->lib->irq_handler,
+ IRQF_SHARED, rt2x00dev->name, rt2x00dev);
if (status) {
ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
- pci_dev->irq, status);
+ rt2x00dev->irq, status);
goto exit;
}
@@ -270,6 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
struct ieee80211_hw *hw;
struct rt2x00_dev *rt2x00dev;
int retval;
+ u16 chip;
retval = pci_request_regions(pci_dev, pci_name(pci_dev));
if (retval) {
@@ -307,6 +307,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
rt2x00dev->dev = &pci_dev->dev;
rt2x00dev->ops = ops;
rt2x00dev->hw = hw;
+ rt2x00dev->irq = pci_dev->irq;
+ rt2x00dev->name = pci_name(pci_dev);
+
+ /*
+ * Determine RT chipset by reading PCI header.
+ */
+ pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
+ rt2x00_set_chip_rt(rt2x00dev, chip);
retval = rt2x00pci_alloc_reg(rt2x00dev);
if (retval)
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index a5664bd8493e..44e5b3279ca7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -148,6 +148,35 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
dev_kfree_skb_any(skb);
}
+void rt2x00queue_payload_align(struct sk_buff *skb,
+ bool l2pad, unsigned int header_length)
+{
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+ unsigned int frame_length = skb->len;
+ unsigned int align = ALIGN_SIZE(skb, header_length);
+
+ if (!align)
+ return;
+
+ if (l2pad) {
+ if (skbdesc->flags & SKBDESC_L2_PADDED) {
+ /* Remove L2 padding */
+ memmove(skb->data + align, skb->data, header_length);
+ skb_pull(skb, align);
+ skbdesc->flags &= ~SKBDESC_L2_PADDED;
+ } else {
+ /* Add L2 padding */
+ skb_push(skb, align);
+ memmove(skb->data, skb->data + align, header_length);
+ skbdesc->flags |= SKBDESC_L2_PADDED;
+ }
+ } else {
+ /* Generic payload alignment to 4-byte boundary */
+ skb_push(skb, align);
+ memmove(skb->data, skb->data + align, frame_length);
+ }
+}
+
static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
@@ -259,6 +288,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
txdesc->aifs = entry->queue->aifs;
/*
+ * Header and alignment information.
+ */
+ txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
+ txdesc->l2pad = ALIGN_SIZE(entry->skb, txdesc->header_length);
+
+ /*
* Check whether this frame is to be acked.
*/
if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
@@ -326,6 +361,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
* Apply TX descriptor handling by components
*/
rt2x00crypto_create_tx_descriptor(entry, txdesc);
+ rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate);
rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
}
@@ -368,7 +404,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
struct txentry_desc txdesc;
struct skb_frame_desc *skbdesc;
- unsigned int iv_len = 0;
u8 rate_idx, rate_flags;
if (unlikely(rt2x00queue_full(queue)))
@@ -390,9 +425,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
entry->skb = skb;
rt2x00queue_create_tx_descriptor(entry, &txdesc);
- if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
- iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
-
/*
* All information is retrieved from the skb->cb array,
* now we should claim ownership of the driver part of that
@@ -415,11 +447,15 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags))
- rt2x00crypto_tx_copy_iv(skb, iv_len);
+ rt2x00crypto_tx_copy_iv(skb, &txdesc);
else
- rt2x00crypto_tx_remove_iv(skb, iv_len);
+ rt2x00crypto_tx_remove_iv(skb, &txdesc);
}
+ if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags))
+ rt2x00queue_payload_align(entry->skb, true,
+ txdesc.header_length);
+
/*
* It could be possible that the queue was corrupted and this
* call failed. Since we always return NETDEV_TX_OK to mac80211,
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 97e2ab08f080..b5e06347c8a7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -35,9 +35,12 @@
* for USB devices this restriction does not apply, but the value of
* 2432 makes sense since it is big enough to contain the maximum fragment
* size according to the ieee802.11 specs.
+ * The aggregation size depends on support from the driver, but should
+ * be something around 3840 bytes.
*/
-#define DATA_FRAME_SIZE 2432
-#define MGMT_FRAME_SIZE 256
+#define DATA_FRAME_SIZE 2432
+#define MGMT_FRAME_SIZE 256
+#define AGGREGATION_SIZE 3840
/**
* DOC: Number of entries per queue
@@ -87,13 +90,16 @@ enum data_queue_qid {
*
* @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX
* @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
- * @FRAME_DESC_IV_STRIPPED: Frame contained a IV/EIV provided by
+ * @SKBDESC_IV_STRIPPED: Frame contained a IV/EIV provided by
* mac80211 but was stripped for processing by the driver.
+ * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment,
+ * the padded bytes are located between header and payload.
*/
enum skb_frame_desc_flags {
SKBDESC_DMA_MAPPED_RX = 1 << 0,
SKBDESC_DMA_MAPPED_TX = 1 << 1,
- FRAME_DESC_IV_STRIPPED = 1 << 2,
+ SKBDESC_IV_STRIPPED = 1 << 2,
+ SKBDESC_L2_PADDED = 1 << 3
};
/**
@@ -145,16 +151,20 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
*
* @RXDONE_SIGNAL_PLCP: Signal field contains the plcp value.
* @RXDONE_SIGNAL_BITRATE: Signal field contains the bitrate value.
+ * @RXDONE_SIGNAL_MCS: Signal field contains the mcs value.
* @RXDONE_MY_BSS: Does this frame originate from device's BSS.
* @RXDONE_CRYPTO_IV: Driver provided IV/EIV data.
* @RXDONE_CRYPTO_ICV: Driver provided ICV data.
+ * @RXDONE_L2PAD: 802.11 payload has been padded to 4-byte boundary.
*/
enum rxdone_entry_desc_flags {
- RXDONE_SIGNAL_PLCP = 1 << 0,
- RXDONE_SIGNAL_BITRATE = 1 << 1,
- RXDONE_MY_BSS = 1 << 2,
- RXDONE_CRYPTO_IV = 1 << 3,
- RXDONE_CRYPTO_ICV = 1 << 4,
+ RXDONE_SIGNAL_PLCP = BIT(0),
+ RXDONE_SIGNAL_BITRATE = BIT(1),
+ RXDONE_SIGNAL_MCS = BIT(2),
+ RXDONE_MY_BSS = BIT(3),
+ RXDONE_CRYPTO_IV = BIT(4),
+ RXDONE_CRYPTO_ICV = BIT(5),
+ RXDONE_L2PAD = BIT(6),
};
/**
@@ -163,7 +173,7 @@ enum rxdone_entry_desc_flags {
* from &rxdone_entry_desc to a signal value type.
*/
#define RXDONE_SIGNAL_MASK \
- ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE )
+ ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE | RXDONE_SIGNAL_MCS )
/**
* struct rxdone_entry_desc: RX Entry descriptor
@@ -177,6 +187,7 @@ enum rxdone_entry_desc_flags {
* @size: Data size of the received frame.
* @flags: MAC80211 receive flags (See &enum mac80211_rx_flags).
* @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags).
+ * @rate_mode: Rate mode (See @enum rate_modulation).
* @cipher: Cipher type used during decryption.
* @cipher_status: Decryption status.
* @iv: IV/EIV data used during decryption.
@@ -190,6 +201,7 @@ struct rxdone_entry_desc {
int size;
int flags;
int dev_flags;
+ u16 rate_mode;
u8 cipher;
u8 cipher_status;
@@ -243,6 +255,9 @@ struct txdone_entry_desc {
* @ENTRY_TXD_ENCRYPT_PAIRWISE: Use pairwise key table (instead of shared).
* @ENTRY_TXD_ENCRYPT_IV: Generate IV/EIV in hardware.
* @ENTRY_TXD_ENCRYPT_MMIC: Generate MIC in hardware.
+ * @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU.
+ * @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth.
+ * @ENTRY_TXD_HT_SHORT_GI: Use short GI.
*/
enum txentry_desc_flags {
ENTRY_TXD_RTS_FRAME,
@@ -258,6 +273,9 @@ enum txentry_desc_flags {
ENTRY_TXD_ENCRYPT_PAIRWISE,
ENTRY_TXD_ENCRYPT_IV,
ENTRY_TXD_ENCRYPT_MMIC,
+ ENTRY_TXD_HT_AMPDU,
+ ENTRY_TXD_HT_BW_40,
+ ENTRY_TXD_HT_SHORT_GI,
};
/**
@@ -267,11 +285,17 @@ enum txentry_desc_flags {
*
* @flags: Descriptor flags (See &enum queue_entry_flags).
* @queue: Queue identification (See &enum data_queue_qid).
+ * @header_length: Length of 802.11 header.
+ * @l2pad: Amount of padding to align 802.11 payload to 4-byte boundrary.
* @length_high: PLCP length high word.
* @length_low: PLCP length low word.
* @signal: PLCP signal.
* @service: PLCP service.
+ * @msc: MCS.
+ * @stbc: STBC.
+ * @ba_size: BA size.
* @rate_mode: Rate mode (See @enum rate_modulation).
+ * @mpdu_density: MDPU density.
* @retry_limit: Max number of retries.
* @aifs: AIFS value.
* @ifs: IFS value.
@@ -280,18 +304,26 @@ enum txentry_desc_flags {
* @cipher: Cipher type used for encryption.
* @key_idx: Key index used for encryption.
* @iv_offset: Position where IV should be inserted by hardware.
+ * @iv_len: Length of IV data.
*/
struct txentry_desc {
unsigned long flags;
enum data_queue_qid queue;
+ u16 header_length;
+ u16 l2pad;
+
u16 length_high;
u16 length_low;
u16 signal;
u16 service;
+ u16 mcs;
+ u16 stbc;
+ u16 ba_size;
u16 rate_mode;
+ u16 mpdu_density;
short retry_limit;
short aifs;
@@ -302,6 +334,7 @@ struct txentry_desc {
enum cipher cipher;
u16 key_idx;
u16 iv_offset;
+ u16 iv_len;
};
/**
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 2ca8b7a9722c..cb521ee7a8f0 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2308,7 +2308,6 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
u32 reg;
u16 value;
u16 eeprom;
- u16 device;
/*
* Read EEPROM word for configuration.
@@ -2317,14 +2316,10 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Identify RF chipset.
- * To determine the RT chip we have to read the
- * PCI header of the device.
*/
- pci_read_config_word(to_pci_dev(rt2x00dev->dev),
- PCI_CONFIG_HEADER_DEVICE, &device);
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg);
- rt2x00_set_chip(rt2x00dev, device, value, reg);
+ rt2x00_set_chip_rf(rt2x00dev, value, reg);
if (!rt2x00_rf(&rt2x00dev->chip, RF5225) &&
!rt2x00_rf(&rt2x00dev->chip, RF5325) &&
@@ -2740,7 +2735,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
- .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.set_key = rt2x00mac_set_key,
.get_stats = rt2x00mac_get_stats,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 41e8959919f6..6c71f77c8165 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -63,12 +63,6 @@
*/
/*
- * PCI Configuration Header
- */
-#define PCI_CONFIG_HEADER_VENDOR 0x0000
-#define PCI_CONFIG_HEADER_DEVICE 0x0002
-
-/*
* HOST_CMD_CSR: For HOST to interrupt embedded processor
*/
#define HOST_CMD_CSR 0x0008
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 853b2b279b64..270dd4e59f7f 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1846,7 +1846,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
- if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
+ if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) ||
+ rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
return -ENODEV;
}
@@ -2259,7 +2260,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
- .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.set_key = rt2x00mac_set_key,
.get_stats = rt2x00mac_get_stats,
diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/rtl818x/Makefile
index c113b3e69046..37e3d4db0c40 100644
--- a/drivers/net/wireless/rtl818x/Makefile
+++ b/drivers/net/wireless/rtl818x/Makefile
@@ -1,5 +1,5 @@
rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
-rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
+rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o
obj-$(CONFIG_RTL8180) += rtl8180.o
obj-$(CONFIG_RTL8187) += rtl8187.o
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 387c133ec0f2..7e65d7c31802 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -702,30 +702,26 @@ static int rtl8180_config(struct ieee80211_hw *dev, u32 changed)
return 0;
}
-static int rtl8180_config_interface(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct rtl8180_priv *priv = dev->priv;
- int i;
-
- for (i = 0; i < ETH_ALEN; i++)
- rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
-
- if (is_valid_ether_addr(conf->bssid))
- rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA);
- else
- rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK);
-
- return 0;
-}
-
static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
u32 changed)
{
struct rtl8180_priv *priv = dev->priv;
+ int i;
+
+ if (changed & BSS_CHANGED_BSSID) {
+ for (i = 0; i < ETH_ALEN; i++)
+ rtl818x_iowrite8(priv, &priv->map->BSSID[i],
+ info->bssid[i]);
+
+ if (is_valid_ether_addr(info->bssid))
+ rtl818x_iowrite8(priv, &priv->map->MSR,
+ RTL818X_MSR_INFRA);
+ else
+ rtl818x_iowrite8(priv, &priv->map->MSR,
+ RTL818X_MSR_NO_LINK);
+ }
if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
priv->rf->conf_erp(dev, info);
@@ -770,7 +766,6 @@ static const struct ieee80211_ops rtl8180_ops = {
.add_interface = rtl8180_add_interface,
.remove_interface = rtl8180_remove_interface,
.config = rtl8180_config,
- .config_interface = rtl8180_config_interface,
.bss_info_changed = rtl8180_bss_info_changed,
.configure_filter = rtl8180_configure_filter,
};
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index 9718f61809cf..c09bfefc70f3 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -16,6 +16,7 @@
#define RTL8187_H
#include "rtl818x.h"
+#include "rtl8187_leds.h"
#define RTL8187_EEPROM_TXPWR_BASE 0x05
#define RTL8187_EEPROM_MAC_ADDR 0x07
@@ -102,6 +103,12 @@ struct rtl8187_priv {
struct usb_anchor anchored;
struct delayed_work work;
struct ieee80211_hw *dev;
+#ifdef CONFIG_RTL8187_LEDS
+ struct rtl8187_led led_tx;
+ struct rtl8187_led led_rx;
+ struct delayed_work led_on;
+ struct delayed_work led_off;
+#endif
u16 txpwr_base;
u8 asic_rev;
u8 is_rtl8187b;
@@ -120,6 +127,12 @@ struct rtl8187_priv {
__le64 buf;
struct sk_buff_head queue;
} b_tx_status; /* This queue is used by both -b and non-b devices */
+ struct mutex io_mutex;
+ union {
+ u8 bits8;
+ __le16 bits16;
+ __le32 bits32;
+ } *io_dmabuf;
};
void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
@@ -129,10 +142,14 @@ static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv,
{
u8 val;
+ mutex_lock(&priv->io_mutex);
usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
- (unsigned long)addr, idx & 0x03, &val,
- sizeof(val), HZ / 2);
+ (unsigned long)addr, idx & 0x03,
+ &priv->io_dmabuf->bits8, sizeof(val), HZ / 2);
+
+ val = priv->io_dmabuf->bits8;
+ mutex_unlock(&priv->io_mutex);
return val;
}
@@ -147,10 +164,14 @@ static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv,
{
__le16 val;
+ mutex_lock(&priv->io_mutex);
usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
- (unsigned long)addr, idx & 0x03, &val,
- sizeof(val), HZ / 2);
+ (unsigned long)addr, idx & 0x03,
+ &priv->io_dmabuf->bits16, sizeof(val), HZ / 2);
+
+ val = priv->io_dmabuf->bits16;
+ mutex_unlock(&priv->io_mutex);
return le16_to_cpu(val);
}
@@ -165,10 +186,14 @@ static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv,
{
__le32 val;
+ mutex_lock(&priv->io_mutex);
usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
- (unsigned long)addr, idx & 0x03, &val,
- sizeof(val), HZ / 2);
+ (unsigned long)addr, idx & 0x03,
+ &priv->io_dmabuf->bits32, sizeof(val), HZ / 2);
+
+ val = priv->io_dmabuf->bits32;
+ mutex_unlock(&priv->io_mutex);
return le32_to_cpu(val);
}
@@ -181,10 +206,15 @@ static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr)
static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv,
u8 *addr, u8 val, u8 idx)
{
+ mutex_lock(&priv->io_mutex);
+
+ priv->io_dmabuf->bits8 = val;
usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
- (unsigned long)addr, idx & 0x03, &val,
- sizeof(val), HZ / 2);
+ (unsigned long)addr, idx & 0x03,
+ &priv->io_dmabuf->bits8, sizeof(val), HZ / 2);
+
+ mutex_unlock(&priv->io_mutex);
}
static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val)
@@ -195,12 +225,15 @@ static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val)
static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv,
__le16 *addr, u16 val, u8 idx)
{
- __le16 buf = cpu_to_le16(val);
+ mutex_lock(&priv->io_mutex);
+ priv->io_dmabuf->bits16 = cpu_to_le16(val);
usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
- (unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
- HZ / 2);
+ (unsigned long)addr, idx & 0x03,
+ &priv->io_dmabuf->bits16, sizeof(val), HZ / 2);
+
+ mutex_unlock(&priv->io_mutex);
}
static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr,
@@ -212,12 +245,15 @@ static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr,
static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv,
__le32 *addr, u32 val, u8 idx)
{
- __le32 buf = cpu_to_le32(val);
+ mutex_lock(&priv->io_mutex);
+ priv->io_dmabuf->bits32 = cpu_to_le32(val);
usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
- (unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
- HZ / 2);
+ (unsigned long)addr, idx & 0x03,
+ &priv->io_dmabuf->bits32, sizeof(val), HZ / 2);
+
+ mutex_unlock(&priv->io_mutex);
}
static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr,
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index fd81884b9c7d..6499ccc34c94 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -29,6 +29,9 @@
#include "rtl8187.h"
#include "rtl8187_rtl8225.h"
+#ifdef CONFIG_RTL8187_LEDS
+#include "rtl8187_leds.h"
+#endif
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
@@ -734,10 +737,10 @@ static const u8 rtl8187b_reg_table[][3] = {
{0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0},
{0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0},
{0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0},
- {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x91, 0x03, 0},
+ {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x4C, 0x00, 2},
- {0x4C, 0x00, 2}, {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0},
- {0x8E, 0x08, 0}, {0x8F, 0x00, 0}
+ {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0},
+ {0x8F, 0x00, 0}
};
static int rtl8187b_init_hw(struct ieee80211_hw *dev)
@@ -1087,32 +1090,6 @@ static int rtl8187_config(struct ieee80211_hw *dev, u32 changed)
return 0;
}
-static int rtl8187_config_interface(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct rtl8187_priv *priv = dev->priv;
- int i;
- u8 reg;
-
- mutex_lock(&priv->conf_mutex);
- for (i = 0; i < ETH_ALEN; i++)
- rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
-
- if (is_valid_ether_addr(conf->bssid)) {
- reg = RTL818X_MSR_INFRA;
- if (priv->is_rtl8187b)
- reg |= RTL818X_MSR_ENEDCA;
- rtl818x_iowrite8(priv, &priv->map->MSR, reg);
- } else {
- reg = RTL818X_MSR_NO_LINK;
- rtl818x_iowrite8(priv, &priv->map->MSR, reg);
- }
-
- mutex_unlock(&priv->conf_mutex);
- return 0;
-}
-
/*
* With 8187B, AC_*_PARAM clashes with FEMR definition in struct rtl818x_csr for
* example. Thus we have to use raw values for AC_*_PARAM register addresses.
@@ -1190,6 +1167,27 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
u32 changed)
{
struct rtl8187_priv *priv = dev->priv;
+ int i;
+ u8 reg;
+
+ if (changed & BSS_CHANGED_BSSID) {
+ mutex_lock(&priv->conf_mutex);
+ for (i = 0; i < ETH_ALEN; i++)
+ rtl818x_iowrite8(priv, &priv->map->BSSID[i],
+ info->bssid[i]);
+
+ if (is_valid_ether_addr(info->bssid)) {
+ reg = RTL818X_MSR_INFRA;
+ if (priv->is_rtl8187b)
+ reg |= RTL818X_MSR_ENEDCA;
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
+ } else {
+ reg = RTL818X_MSR_NO_LINK;
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
+ }
+
+ mutex_unlock(&priv->conf_mutex);
+ }
if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE))
rtl8187_conf_erp(priv, info->use_short_slot,
@@ -1271,7 +1269,6 @@ static const struct ieee80211_ops rtl8187_ops = {
.add_interface = rtl8187_add_interface,
.remove_interface = rtl8187_remove_interface,
.config = rtl8187_config,
- .config_interface = rtl8187_config_interface,
.bss_info_changed = rtl8187_bss_info_changed,
.configure_filter = rtl8187_configure_filter,
.conf_tx = rtl8187_conf_tx
@@ -1329,6 +1326,14 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
priv = dev->priv;
priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B);
+ /* allocate "DMA aware" buffer for register accesses */
+ priv->io_dmabuf = kmalloc(sizeof(*priv->io_dmabuf), GFP_KERNEL);
+ if (!priv->io_dmabuf) {
+ err = -ENOMEM;
+ goto err_free_dev;
+ }
+ mutex_init(&priv->io_mutex);
+
SET_IEEE80211_DEV(dev, &intf->dev);
usb_set_intfdata(intf, dev);
priv->udev = udev;
@@ -1470,9 +1475,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
(*channel++).hw_value = txpwr >> 8;
}
- if (priv->is_rtl8187b)
- printk(KERN_WARNING "rtl8187: 8187B chip detected.\n");
-
/*
* XXX: Once this driver supports anything that requires
* beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ.
@@ -1495,7 +1497,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
err = ieee80211_register_hw(dev);
if (err) {
printk(KERN_ERR "rtl8187: Cannot register device\n");
- goto err_free_dev;
+ goto err_free_dmabuf;
}
mutex_init(&priv->conf_mutex);
skb_queue_head_init(&priv->b_tx_status.queue);
@@ -1504,8 +1506,16 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
chip_name, priv->asic_rev, priv->rf->name);
+#ifdef CONFIG_RTL8187_LEDS
+ eeprom_93cx6_read(&eeprom, 0x3F, &reg);
+ reg &= 0xFF;
+ rtl8187_leds_init(dev, reg);
+#endif
+
return 0;
+ err_free_dmabuf:
+ kfree(priv->io_dmabuf);
err_free_dev:
ieee80211_free_hw(dev);
usb_set_intfdata(intf, NULL);
@@ -1521,11 +1531,15 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf)
if (!dev)
return;
+#ifdef CONFIG_RTL8187_LEDS
+ rtl8187_leds_exit(dev);
+#endif
ieee80211_unregister_hw(dev);
priv = dev->priv;
usb_reset_device(priv->udev);
usb_put_dev(interface_to_usbdev(intf));
+ kfree(priv->io_dmabuf);
ieee80211_free_hw(dev);
}
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c
new file mode 100644
index 000000000000..b44253592243
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c
@@ -0,0 +1,218 @@
+/*
+ * Linux LED driver for RTL8187
+ *
+ * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ * Based on the LED handling in the r8187 driver, which is:
+ * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+ *
+ * Thanks to Realtek for their support!
+ *
+ * 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.
+ */
+
+#ifdef CONFIG_RTL8187_LEDS
+
+#include <net/mac80211.h>
+#include <linux/usb.h>
+#include <linux/eeprom_93cx6.h>
+
+#include "rtl8187.h"
+#include "rtl8187_leds.h"
+
+static void led_turn_on(struct work_struct *work)
+{
+ /* As this routine does read/write operations on the hardware, it must
+ * be run from a work queue.
+ */
+ u8 reg;
+ struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
+ led_on.work);
+ struct rtl8187_led *led = &priv->led_tx;
+
+ /* Don't change the LED, when the device is down. */
+ if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+ return ;
+
+ /* Skip if the LED is not registered. */
+ if (!led->dev)
+ return;
+ mutex_lock(&priv->conf_mutex);
+ switch (led->ledpin) {
+ case LED_PIN_GPIO0:
+ rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01);
+ rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00);
+ break;
+ case LED_PIN_LED0:
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 4);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+ break;
+ case LED_PIN_LED1:
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 5);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+ break;
+ case LED_PIN_HW:
+ default:
+ break;
+ }
+ mutex_unlock(&priv->conf_mutex);
+}
+
+static void led_turn_off(struct work_struct *work)
+{
+ /* As this routine does read/write operations on the hardware, it must
+ * be run from a work queue.
+ */
+ u8 reg;
+ struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
+ led_off.work);
+ struct rtl8187_led *led = &priv->led_tx;
+
+ /* Don't change the LED, when the device is down. */
+ if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+ return ;
+
+ /* Skip if the LED is not registered. */
+ if (!led->dev)
+ return;
+ mutex_lock(&priv->conf_mutex);
+ switch (led->ledpin) {
+ case LED_PIN_GPIO0:
+ rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01);
+ rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01);
+ break;
+ case LED_PIN_LED0:
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 4);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+ break;
+ case LED_PIN_LED1:
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 5);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+ break;
+ case LED_PIN_HW:
+ default:
+ break;
+ }
+ mutex_unlock(&priv->conf_mutex);
+}
+
+/* Callback from the LED subsystem. */
+static void rtl8187_led_brightness_set(struct led_classdev *led_dev,
+ enum led_brightness brightness)
+{
+ struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led,
+ led_dev);
+ struct ieee80211_hw *hw = led->dev;
+ struct rtl8187_priv *priv = hw->priv;
+
+ if (brightness == LED_OFF) {
+ queue_delayed_work(hw->workqueue, &priv->led_off, 0);
+ /* The LED is off for 1/20 sec so that it just blinks. */
+ queue_delayed_work(hw->workqueue, &priv->led_on, HZ / 20);
+ } else
+ queue_delayed_work(hw->workqueue, &priv->led_on, 0);
+}
+
+static int rtl8187_register_led(struct ieee80211_hw *dev,
+ struct rtl8187_led *led, const char *name,
+ const char *default_trigger, u8 ledpin)
+{
+ int err;
+ struct rtl8187_priv *priv = dev->priv;
+
+ if (led->dev)
+ return -EEXIST;
+ if (!default_trigger)
+ return -EINVAL;
+ led->dev = dev;
+ led->ledpin = ledpin;
+ strncpy(led->name, name, sizeof(led->name));
+
+ led->led_dev.name = led->name;
+ led->led_dev.default_trigger = default_trigger;
+ led->led_dev.brightness_set = rtl8187_led_brightness_set;
+
+ err = led_classdev_register(&priv->udev->dev, &led->led_dev);
+ if (err) {
+ printk(KERN_INFO "LEDs: Failed to register %s\n", name);
+ led->dev = NULL;
+ return err;
+ }
+ return 0;
+}
+
+static void rtl8187_unregister_led(struct rtl8187_led *led)
+{
+ led_classdev_unregister(&led->led_dev);
+ led->dev = NULL;
+}
+
+void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid)
+{
+ struct rtl8187_priv *priv = dev->priv;
+ char name[RTL8187_LED_MAX_NAME_LEN + 1];
+ u8 ledpin;
+ int err;
+
+ /* According to the vendor driver, the LED operation depends on the
+ * customer ID encoded in the EEPROM
+ */
+ printk(KERN_INFO "rtl8187: Customer ID is 0x%02X\n", custid);
+ switch (custid) {
+ case EEPROM_CID_RSVD0:
+ case EEPROM_CID_RSVD1:
+ case EEPROM_CID_SERCOMM_PS:
+ case EEPROM_CID_QMI:
+ case EEPROM_CID_DELL:
+ case EEPROM_CID_TOSHIBA:
+ ledpin = LED_PIN_GPIO0;
+ break;
+ case EEPROM_CID_ALPHA0:
+ ledpin = LED_PIN_LED0;
+ break;
+ case EEPROM_CID_HW:
+ ledpin = LED_PIN_HW;
+ break;
+ default:
+ ledpin = LED_PIN_GPIO0;
+ }
+
+ INIT_DELAYED_WORK(&priv->led_on, led_turn_on);
+ INIT_DELAYED_WORK(&priv->led_off, led_turn_off);
+
+ snprintf(name, sizeof(name),
+ "rtl8187-%s::tx", wiphy_name(dev->wiphy));
+ err = rtl8187_register_led(dev, &priv->led_tx, name,
+ ieee80211_get_tx_led_name(dev), ledpin);
+ if (err)
+ goto error;
+ snprintf(name, sizeof(name),
+ "rtl8187-%s::rx", wiphy_name(dev->wiphy));
+ err = rtl8187_register_led(dev, &priv->led_rx, name,
+ ieee80211_get_rx_led_name(dev), ledpin);
+ if (!err) {
+ queue_delayed_work(dev->workqueue, &priv->led_on, 0);
+ return;
+ }
+ /* registration of RX LED failed - unregister TX */
+ rtl8187_unregister_led(&priv->led_tx);
+error:
+ /* If registration of either failed, cancel delayed work */
+ cancel_delayed_work_sync(&priv->led_off);
+ cancel_delayed_work_sync(&priv->led_on);
+}
+
+void rtl8187_leds_exit(struct ieee80211_hw *dev)
+{
+ struct rtl8187_priv *priv = dev->priv;
+
+ rtl8187_unregister_led(&priv->led_tx);
+ /* turn the LED off before exiting */
+ queue_delayed_work(dev->workqueue, &priv->led_off, 0);
+ cancel_delayed_work_sync(&priv->led_off);
+ rtl8187_unregister_led(&priv->led_rx);
+}
+#endif /* def CONFIG_RTL8187_LED */
+
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187_leds.h
new file mode 100644
index 000000000000..a0332027aead
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.h
@@ -0,0 +1,57 @@
+/*
+ * Definitions for RTL8187 leds
+ *
+ * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ * Based on the LED handling in the r8187 driver, which is:
+ * Copyright (c) Realtek Semiconductor Corp. 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 RTL8187_LED_H
+#define RTL8187_LED_H
+
+#ifdef CONFIG_RTL8187_LEDS
+
+#define RTL8187_LED_MAX_NAME_LEN 21
+
+#include <linux/leds.h>
+#include <linux/types.h>
+
+enum {
+ LED_PIN_LED0,
+ LED_PIN_LED1,
+ LED_PIN_GPIO0,
+ LED_PIN_HW
+};
+
+enum {
+ EEPROM_CID_RSVD0 = 0x00,
+ EEPROM_CID_RSVD1 = 0xFF,
+ EEPROM_CID_ALPHA0 = 0x01,
+ EEPROM_CID_SERCOMM_PS = 0x02,
+ EEPROM_CID_HW = 0x03,
+ EEPROM_CID_TOSHIBA = 0x04,
+ EEPROM_CID_QMI = 0x07,
+ EEPROM_CID_DELL = 0x08
+};
+
+struct rtl8187_led {
+ struct ieee80211_hw *dev;
+ /* The LED class device */
+ struct led_classdev led_dev;
+ /* The pin/method used to control the led */
+ u8 ledpin;
+ /* The unique name string for this LED device. */
+ char name[RTL8187_LED_MAX_NAME_LEN + 1];
+};
+
+void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code);
+void rtl8187_leds_exit(struct ieee80211_hw *dev);
+
+#endif /* def CONFIG_RTL8187_LED */
+
+#endif /* RTL8187_LED_H */
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
index 78df281b297a..a09819386a1e 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
@@ -88,9 +88,15 @@ static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
udelay(10);
+ mutex_lock(&priv->io_mutex);
+
+ priv->io_dmabuf->bits16 = data;
usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
- addr, 0x8225, &data, sizeof(data), HZ / 2);
+ addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data),
+ HZ / 2);
+
+ mutex_unlock(&priv->io_mutex);
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
udelay(10);
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
new file mode 100644
index 000000000000..a82c4cd436d8
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -0,0 +1,11 @@
+config WL12XX
+ tristate "TI wl1251/wl1271 support"
+ depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS && EXPERIMENTAL
+ select FW_LOADER
+ select CRC7
+ ---help---
+ This module adds support for wireless adapters based on
+ TI wl1251/wl1271 chipsets.
+
+ If you choose to build a module, it'll be called wl12xx. Say N if
+ unsure.
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
new file mode 100644
index 000000000000..d43de27dc54c
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -0,0 +1,4 @@
+wl12xx-objs = main.o spi.o event.o tx.o rx.o \
+ ps.o cmd.o acx.o boot.o init.o wl1251.o \
+ debugfs.o
+obj-$(CONFIG_WL12XX) += wl12xx.o
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
new file mode 100644
index 000000000000..1cfd458ad5ab
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -0,0 +1,689 @@
+#include "acx.h"
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "spi.h"
+#include "ps.h"
+
+int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
+ u8 mgt_rate, u8 mgt_mod)
+{
+ int ret;
+ struct acx_fw_gen_frame_rates rates;
+
+ wl12xx_debug(DEBUG_ACX, "acx frame rates");
+
+ rates.header.id = ACX_FW_GEN_FRAME_RATES;
+ rates.header.len = sizeof(struct acx_fw_gen_frame_rates) -
+ sizeof(struct acx_header);
+
+ rates.tx_ctrl_frame_rate = ctrl_rate;
+ rates.tx_ctrl_frame_mod = ctrl_mod;
+ rates.tx_mgt_frame_rate = mgt_rate;
+ rates.tx_mgt_frame_mod = mgt_mod;
+
+ ret = wl12xx_cmd_configure(wl, &rates, sizeof(rates));
+ if (ret < 0) {
+ wl12xx_error("Failed to set FW rates and modulation");
+ return ret;
+ }
+
+ return 0;
+}
+
+
+int wl12xx_acx_station_id(struct wl12xx *wl)
+{
+ int ret, i;
+ struct dot11_station_id mac;
+
+ wl12xx_debug(DEBUG_ACX, "acx dot11_station_id");
+
+ mac.header.id = DOT11_STATION_ID;
+ mac.header.len = sizeof(mac) - sizeof(struct acx_header);
+
+ for (i = 0; i < ETH_ALEN; i++)
+ mac.mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
+
+ ret = wl12xx_cmd_configure(wl, &mac, sizeof(mac));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id)
+{
+ struct acx_dot11_default_key default_key;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
+
+ default_key.header.id = DOT11_DEFAULT_KEY;
+ default_key.header.len = sizeof(default_key) -
+ sizeof(struct acx_header);
+
+ default_key.id = key_id;
+
+ ret = wl12xx_cmd_configure(wl, &default_key, sizeof(default_key));
+ if (ret < 0) {
+ wl12xx_error("Couldnt set default key");
+ return ret;
+ }
+
+ wl->default_key = key_id;
+
+ return 0;
+}
+
+int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval)
+{
+ struct acx_wake_up_condition wake_up;
+
+ wl12xx_debug(DEBUG_ACX, "acx wake up conditions");
+
+ wake_up.header.id = ACX_WAKE_UP_CONDITIONS;
+ wake_up.header.len = sizeof(wake_up) - sizeof(struct acx_header);
+
+ wake_up.wake_up_event = WAKE_UP_EVENT_DTIM_BITMAP;
+ wake_up.listen_interval = listen_interval;
+
+ return wl12xx_cmd_configure(wl, &wake_up, sizeof(wake_up));
+}
+
+int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth)
+{
+ int ret;
+ struct acx_sleep_auth auth;
+
+ wl12xx_debug(DEBUG_ACX, "acx sleep auth");
+
+ auth.header.id = ACX_SLEEP_AUTH;
+ auth.header.len = sizeof(auth) - sizeof(struct acx_header);
+
+ auth.sleep_auth = sleep_auth;
+
+ ret = wl12xx_cmd_configure(wl, &auth, sizeof(auth));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len)
+{
+ struct wl12xx_command cmd;
+ struct acx_revision *rev;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx fw rev");
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ ret = wl12xx_cmd_interrogate(wl, ACX_FW_REV, sizeof(*rev), &cmd);
+ if (ret < 0) {
+ wl12xx_warning("ACX_FW_REV interrogate failed");
+ return ret;
+ }
+
+ rev = (struct acx_revision *) &cmd.parameters;
+
+ /* be careful with the buffer sizes */
+ strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
+
+ /*
+ * if the firmware version string is exactly
+ * sizeof(rev->fw_version) long or fw_len is less than
+ * sizeof(rev->fw_version) it won't be null terminated
+ */
+ buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
+
+ return 0;
+}
+
+int wl12xx_acx_tx_power(struct wl12xx *wl, int power)
+{
+ struct acx_current_tx_power ie;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
+
+ if (power < 0 || power > 25)
+ return -EINVAL;
+
+ memset(&ie, 0, sizeof(ie));
+
+ ie.header.id = DOT11_CUR_TX_PWR;
+ ie.header.len = sizeof(ie) - sizeof(struct acx_header);
+ ie.current_tx_power = power * 10;
+
+ ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
+ if (ret < 0) {
+ wl12xx_warning("configure of tx power failed: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_feature_cfg(struct wl12xx *wl)
+{
+ struct acx_feature_config feature;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx feature cfg");
+
+ memset(&feature, 0, sizeof(feature));
+
+ feature.header.id = ACX_FEATURE_CFG;
+ feature.header.len = sizeof(feature) - sizeof(struct acx_header);
+
+ /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
+ feature.data_flow_options = 0;
+ feature.options = 0;
+
+ ret = wl12xx_cmd_configure(wl, &feature, sizeof(feature));
+ if (ret < 0)
+ wl12xx_error("Couldnt set HW encryption");
+
+ return ret;
+}
+
+int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len)
+{
+ struct wl12xx_command cmd;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx mem map");
+
+ ret = wl12xx_cmd_interrogate(wl, ACX_MEM_MAP, len, &cmd);
+ if (ret < 0)
+ return ret;
+ else if (cmd.status != CMD_STATUS_SUCCESS)
+ return -EIO;
+
+ memcpy(mem_map, &cmd.parameters, len);
+
+ return 0;
+}
+
+int wl12xx_acx_data_path_params(struct wl12xx *wl,
+ struct acx_data_path_params_resp *data_path)
+{
+ struct acx_data_path_params params;
+ struct wl12xx_command cmd;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx data path params");
+
+ params.rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
+ params.tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
+
+ params.rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
+ params.tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
+
+ params.tx_complete_threshold = 1;
+
+ params.tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
+
+ params.tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
+
+ params.header.id = ACX_DATA_PATH_PARAMS;
+ params.header.len = sizeof(params) - sizeof(struct acx_header);
+
+ ret = wl12xx_cmd_configure(wl, &params, sizeof(params));
+ if (ret < 0)
+ return ret;
+
+
+ ret = wl12xx_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
+ sizeof(struct acx_data_path_params_resp),
+ &cmd);
+
+ if (ret < 0) {
+ wl12xx_warning("failed to read data path parameters: %d", ret);
+ return ret;
+ } else if (cmd.status != CMD_STATUS_SUCCESS) {
+ wl12xx_warning("data path parameter acx status failed");
+ return -EIO;
+ }
+
+ memcpy(data_path, &cmd.parameters, sizeof(*data_path));
+
+ return 0;
+}
+
+int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time)
+{
+ struct rx_msdu_lifetime msdu_lifetime;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx rx msdu life time");
+
+ msdu_lifetime.header.id = DOT11_RX_MSDU_LIFE_TIME;
+ msdu_lifetime.header.len = sizeof(msdu_lifetime) -
+ sizeof(struct acx_header);
+ msdu_lifetime.lifetime = life_time;
+
+ ret = wl12xx_cmd_configure(wl, &msdu_lifetime, sizeof(msdu_lifetime));
+ if (ret < 0) {
+ wl12xx_warning("failed to set rx msdu life time: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter)
+{
+ struct acx_rx_config rx_config;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx rx config");
+
+ rx_config.header.id = ACX_RX_CFG;
+ rx_config.header.len = sizeof(rx_config) - sizeof(struct acx_header);
+ rx_config.config_options = config;
+ rx_config.filter_options = filter;
+
+ ret = wl12xx_cmd_configure(wl, &rx_config, sizeof(rx_config));
+ if (ret < 0) {
+ wl12xx_warning("failed to set rx config: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_pd_threshold(struct wl12xx *wl)
+{
+ struct acx_packet_detection packet_detection;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx data pd threshold");
+
+ /* FIXME: threshold value not set */
+ packet_detection.header.id = ACX_PD_THRESHOLD;
+ packet_detection.header.len = sizeof(packet_detection) -
+ sizeof(struct acx_header);
+
+ ret = wl12xx_cmd_configure(wl, &packet_detection,
+ sizeof(packet_detection));
+ if (ret < 0) {
+ wl12xx_warning("failed to set pd threshold: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time)
+{
+ struct acx_slot slot;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx slot");
+
+ slot.header.id = ACX_SLOT;
+ slot.header.len = sizeof(slot) - sizeof(struct acx_header);
+
+ slot.wone_index = STATION_WONE_INDEX;
+ slot.slot_time = slot_time;
+
+ ret = wl12xx_cmd_configure(wl, &slot, sizeof(slot));
+ if (ret < 0) {
+ wl12xx_warning("failed to set slot time: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_group_address_tbl(struct wl12xx *wl)
+{
+ struct multicast_grp_addr_start multicast;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx group address tbl");
+
+ /* MAC filtering */
+ multicast.header.id = DOT11_GROUP_ADDRESS_TBL;
+ multicast.header.len = sizeof(multicast) - sizeof(struct acx_header);
+
+ multicast.enabled = 0;
+ multicast.num_groups = 0;
+ memset(multicast.mac_table, 0, ADDRESS_GROUP_MAX_LEN);
+
+ ret = wl12xx_cmd_configure(wl, &multicast, sizeof(multicast));
+ if (ret < 0) {
+ wl12xx_warning("failed to set group addr table: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_service_period_timeout(struct wl12xx *wl)
+{
+ struct acx_rx_timeout rx_timeout;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx service period timeout");
+
+ /* RX timeout */
+ rx_timeout.header.id = ACX_SERVICE_PERIOD_TIMEOUT;
+ rx_timeout.header.len = sizeof(rx_timeout) - sizeof(struct acx_header);
+
+ rx_timeout.ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
+ rx_timeout.upsd_timeout = RX_TIMEOUT_UPSD_DEF;
+
+ ret = wl12xx_cmd_configure(wl, &rx_timeout, sizeof(rx_timeout));
+ if (ret < 0) {
+ wl12xx_warning("failed to set service period timeout: %d",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold)
+{
+ struct acx_rts_threshold rts;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx rts threshold");
+
+ rts.header.id = DOT11_RTS_THRESHOLD;
+ rts.header.len = sizeof(rts) - sizeof(struct acx_header);
+
+ rts.threshold = rts_threshold;
+
+ ret = wl12xx_cmd_configure(wl, &rts, sizeof(rts));
+ if (ret < 0) {
+ wl12xx_warning("failed to set rts threshold: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl)
+{
+ struct acx_beacon_filter_option beacon_filter;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx beacon filter opt");
+
+ beacon_filter.header.id = ACX_BEACON_FILTER_OPT;
+ beacon_filter.header.len = sizeof(beacon_filter) -
+ sizeof(struct acx_header);
+
+ beacon_filter.enable = 0;
+ beacon_filter.max_num_beacons = 0;
+
+ ret = wl12xx_cmd_configure(wl, &beacon_filter, sizeof(beacon_filter));
+ if (ret < 0) {
+ wl12xx_warning("failed to set beacon filter opt: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_beacon_filter_table(struct wl12xx *wl)
+{
+ struct acx_beacon_filter_ie_table ie_table;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx beacon filter table");
+
+ ie_table.header.id = ACX_BEACON_FILTER_TABLE;
+ ie_table.header.len = sizeof(ie_table) - sizeof(struct acx_header);
+
+ ie_table.num_ie = 0;
+ memset(ie_table.table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
+
+ ret = wl12xx_cmd_configure(wl, &ie_table, sizeof(ie_table));
+ if (ret < 0) {
+ wl12xx_warning("failed to set beacon filter table: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_sg_enable(struct wl12xx *wl)
+{
+ struct acx_bt_wlan_coex pta;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx sg enable");
+
+ pta.header.id = ACX_SG_ENABLE;
+ pta.header.len = sizeof(pta) - sizeof(struct acx_header);
+
+ pta.enable = SG_ENABLE;
+
+ ret = wl12xx_cmd_configure(wl, &pta, sizeof(pta));
+ if (ret < 0) {
+ wl12xx_warning("failed to set softgemini enable: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_sg_cfg(struct wl12xx *wl)
+{
+ struct acx_bt_wlan_coex_param param;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx sg cfg");
+
+ /* BT-WLAN coext parameters */
+ param.header.id = ACX_SG_CFG;
+ param.header.len = sizeof(param) - sizeof(struct acx_header);
+
+ param.min_rate = RATE_INDEX_24MBPS;
+ param.bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
+ param.wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
+ param.sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
+ param.rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
+ param.tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
+ param.rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
+ param.tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
+ param.wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
+ param.bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
+ param.next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
+ param.wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
+ param.hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
+ param.next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
+ param.antenna_type = PTA_ANTENNA_TYPE_DEF;
+ param.signal_type = PTA_SIGNALING_TYPE_DEF;
+ param.afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
+ param.quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
+ param.max_cts = PTA_MAX_NUM_CTS_DEF;
+ param.wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
+ param.bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
+ param.missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
+ param.wlan_elp_hp = PTA_ELP_HP_DEF;
+ param.bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
+ param.ack_mode_dual_ant = PTA_ACK_MODE_DEF;
+ param.pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
+ param.pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
+ param.bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
+
+ ret = wl12xx_cmd_configure(wl, &param, sizeof(param));
+ if (ret < 0) {
+ wl12xx_warning("failed to set sg config: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_cca_threshold(struct wl12xx *wl)
+{
+ struct acx_energy_detection detection;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx cca threshold");
+
+ detection.header.id = ACX_CCA_THRESHOLD;
+ detection.header.len = sizeof(detection) - sizeof(struct acx_header);
+
+ detection.rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
+ detection.tx_energy_detection = 0;
+
+ ret = wl12xx_cmd_configure(wl, &detection, sizeof(detection));
+ if (ret < 0) {
+ wl12xx_warning("failed to set cca threshold: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl)
+{
+ struct acx_beacon_broadcast bb;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx bcn dtim options");
+
+ bb.header.id = ACX_BCN_DTIM_OPTIONS;
+ bb.header.len = sizeof(bb) - sizeof(struct acx_header);
+
+ bb.beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
+ bb.broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
+ bb.rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
+ bb.ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
+
+ ret = wl12xx_cmd_configure(wl, &bb, sizeof(bb));
+ if (ret < 0) {
+ wl12xx_warning("failed to set rx config: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_aid(struct wl12xx *wl, u16 aid)
+{
+ struct acx_aid acx_aid;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx aid");
+
+ acx_aid.header.id = ACX_AID;
+ acx_aid.header.len = sizeof(acx_aid) - sizeof(struct acx_header);
+
+ acx_aid.aid = aid;
+
+ ret = wl12xx_cmd_configure(wl, &acx_aid, sizeof(acx_aid));
+ if (ret < 0) {
+ wl12xx_warning("failed to set aid: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask)
+{
+ struct acx_event_mask mask;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx event mbox mask");
+
+ mask.header.id = ACX_EVENT_MBOX_MASK;
+ mask.header.len = sizeof(mask) - sizeof(struct acx_header);
+
+ /* high event mask is unused */
+ mask.high_event_mask = 0xffffffff;
+
+ mask.event_mask = event_mask;
+
+ ret = wl12xx_cmd_configure(wl, &mask, sizeof(mask));
+ if (ret < 0) {
+ wl12xx_warning("failed to set aid: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble)
+{
+ struct acx_preamble ie;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx_set_preamble");
+
+ memset(&ie, 0, sizeof(ie));
+
+ ie.header.id = ACX_PREAMBLE_TYPE;
+ ie.header.len = sizeof(ie) - sizeof(struct acx_header);
+ ie.preamble = preamble;
+ ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
+ if (ret < 0) {
+ wl12xx_warning("Setting of preamble failed: %d", ret);
+ return ret;
+ }
+ return 0;
+}
+
+int wl12xx_acx_cts_protect(struct wl12xx *wl,
+ enum acx_ctsprotect_type ctsprotect)
+{
+ struct acx_ctsprotect ie;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx_set_ctsprotect");
+
+ memset(&ie, 0, sizeof(ie));
+
+ ie.header.id = ACX_CTS_PROTECTION;
+ ie.header.len = sizeof(ie) - sizeof(struct acx_header);
+ ie.ctsprotect = ctsprotect;
+ ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
+ if (ret < 0) {
+ wl12xx_warning("Setting of ctsprotect failed: %d", ret);
+ return ret;
+ }
+ return 0;
+}
+
+int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats)
+{
+ struct wl12xx_command *answer;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx statistics");
+
+ answer = kmalloc(sizeof(*answer), GFP_KERNEL);
+ if (!answer) {
+ wl12xx_warning("could not allocate memory for acx statistics");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = wl12xx_cmd_interrogate(wl, ACX_STATISTICS, sizeof(*answer),
+ answer);
+ if (ret < 0) {
+ wl12xx_warning("acx statistics failed: %d", ret);
+ goto out;
+ }
+
+ memcpy(stats, answer->parameters, sizeof(*stats));
+
+out:
+ kfree(answer);
+ return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
new file mode 100644
index 000000000000..fb2d2340993c
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -0,0 +1,1245 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __WL12XX_ACX_H__
+#define __WL12XX_ACX_H__
+
+#include "wl12xx.h"
+
+/* Target's information element */
+struct acx_header {
+ u16 id;
+ u16 len;
+};
+
+struct acx_error_counter {
+ struct acx_header header;
+
+ /* The number of PLCP errors since the last time this */
+ /* information element was interrogated. This field is */
+ /* automatically cleared when it is interrogated.*/
+ u32 PLCP_error;
+
+ /* The number of FCS errors since the last time this */
+ /* information element was interrogated. This field is */
+ /* automatically cleared when it is interrogated.*/
+ u32 FCS_error;
+
+ /* The number of MPDUs without PLCP header errors received*/
+ /* since the last time this information element was interrogated. */
+ /* This field is automatically cleared when it is interrogated.*/
+ u32 valid_frame;
+
+ /* the number of missed sequence numbers in the squentially */
+ /* values of frames seq numbers */
+ u32 seq_num_miss;
+} __attribute__ ((packed));
+
+struct acx_revision {
+ struct acx_header header;
+
+ /*
+ * The WiLink firmware version, an ASCII string x.x.x.x,
+ * that uniquely identifies the current firmware.
+ * The left most digit is incremented each time a
+ * significant change is made to the firmware, such as
+ * code redesign or new platform support.
+ * The second digit is incremented when major enhancements
+ * are added or major fixes are made.
+ * The third digit is incremented for each GA release.
+ * The fourth digit is incremented for each build.
+ * The first two digits identify a firmware release version,
+ * in other words, a unique set of features.
+ * The first three digits identify a GA release.
+ */
+ char fw_version[20];
+
+ /*
+ * This 4 byte field specifies the WiLink hardware version.
+ * bits 0 - 15: Reserved.
+ * bits 16 - 23: Version ID - The WiLink version ID
+ * (1 = first spin, 2 = second spin, and so on).
+ * bits 24 - 31: Chip ID - The WiLink chip ID.
+ */
+ u32 hw_version;
+} __attribute__ ((packed));
+
+enum wl12xx_psm_mode {
+ /* Active mode */
+ WL12XX_PSM_CAM = 0,
+
+ /* Power save mode */
+ WL12XX_PSM_PS = 1,
+
+ /* Extreme low power */
+ WL12XX_PSM_ELP = 2,
+};
+
+struct acx_sleep_auth {
+ struct acx_header header;
+
+ /* The sleep level authorization of the device. */
+ /* 0 - Always active*/
+ /* 1 - Power down mode: light / fast sleep*/
+ /* 2 - ELP mode: Deep / Max sleep*/
+ u8 sleep_auth;
+ u8 padding[3];
+} __attribute__ ((packed));
+
+#define TIM_ELE_ID 5
+#define PARTIAL_VBM_MAX 251
+
+struct tim {
+ u8 identity;
+ u8 length;
+ u8 dtim_count;
+ u8 dtim_period;
+ u8 bitmap_ctrl;
+ u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
+} __attribute__ ((packed));
+
+/* Virtual Bit Map update */
+struct vbm_update_request {
+ __le16 len;
+ u8 padding[2];
+ struct tim tim;
+} __attribute__ ((packed));
+
+enum {
+ HOSTIF_PCI_MASTER_HOST_INDIRECT,
+ HOSTIF_PCI_MASTER_HOST_DIRECT,
+ HOSTIF_SLAVE,
+ HOSTIF_PKT_RING,
+ HOSTIF_DONTCARE = 0xFF
+};
+
+#define DEFAULT_UCAST_PRIORITY 0
+#define DEFAULT_RX_Q_PRIORITY 0
+#define DEFAULT_NUM_STATIONS 1
+#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */
+#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */
+#define TRACE_BUFFER_MAX_SIZE 256
+
+#define DP_RX_PACKET_RING_CHUNK_SIZE 1600
+#define DP_TX_PACKET_RING_CHUNK_SIZE 1600
+#define DP_RX_PACKET_RING_CHUNK_NUM 2
+#define DP_TX_PACKET_RING_CHUNK_NUM 2
+#define DP_TX_COMPLETE_TIME_OUT 20
+#define FW_TX_CMPLT_BLOCK_SIZE 16
+
+struct acx_data_path_params {
+ struct acx_header header;
+
+ u16 rx_packet_ring_chunk_size;
+ u16 tx_packet_ring_chunk_size;
+
+ u8 rx_packet_ring_chunk_num;
+ u8 tx_packet_ring_chunk_num;
+
+ /*
+ * Maximum number of packets that can be gathered
+ * in the TX complete ring before an interrupt
+ * is generated.
+ */
+ u8 tx_complete_threshold;
+
+ /* Number of pending TX complete entries in cyclic ring.*/
+ u8 tx_complete_ring_depth;
+
+ /*
+ * Max num microseconds since a packet enters the TX
+ * complete ring until an interrupt is generated.
+ */
+ u32 tx_complete_timeout;
+} __attribute__ ((packed));
+
+
+struct acx_data_path_params_resp {
+ struct acx_header header;
+
+ u16 rx_packet_ring_chunk_size;
+ u16 tx_packet_ring_chunk_size;
+
+ u8 rx_packet_ring_chunk_num;
+ u8 tx_packet_ring_chunk_num;
+
+ u8 pad[2];
+
+ u32 rx_packet_ring_addr;
+ u32 tx_packet_ring_addr;
+
+ u32 rx_control_addr;
+ u32 tx_control_addr;
+
+ u32 tx_complete_addr;
+} __attribute__ ((packed));
+
+#define TX_MSDU_LIFETIME_MIN 0
+#define TX_MSDU_LIFETIME_MAX 3000
+#define TX_MSDU_LIFETIME_DEF 512
+#define RX_MSDU_LIFETIME_MIN 0
+#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF
+#define RX_MSDU_LIFETIME_DEF 512000
+
+struct rx_msdu_lifetime {
+ struct acx_header header;
+
+ /*
+ * The maximum amount of time, in TU, before the
+ * firmware discards the MSDU.
+ */
+ u32 lifetime;
+} __attribute__ ((packed));
+
+/*
+ * RX Config Options Table
+ * Bit Definition
+ * === ==========
+ * 31:14 Reserved
+ * 13 Copy RX Status - when set, write three receive status words
+ * to top of rx'd MPDUs.
+ * When cleared, do not write three status words (added rev 1.5)
+ * 12 Reserved
+ * 11 RX Complete upon FCS error - when set, give rx complete
+ * interrupt for FCS errors, after the rx filtering, e.g. unicast
+ * frames not to us with FCS error will not generate an interrupt.
+ * 10 SSID Filter Enable - When set, the WiLink discards all beacon,
+ * probe request, and probe response frames with an SSID that does
+ * not match the SSID specified by the host in the START/JOIN
+ * command.
+ * When clear, the WiLink receives frames with any SSID.
+ * 9 Broadcast Filter Enable - When set, the WiLink discards all
+ * broadcast frames. When clear, the WiLink receives all received
+ * broadcast frames.
+ * 8:6 Reserved
+ * 5 BSSID Filter Enable - When set, the WiLink discards any frames
+ * with a BSSID that does not match the BSSID specified by the
+ * host.
+ * When clear, the WiLink receives frames from any BSSID.
+ * 4 MAC Addr Filter - When set, the WiLink discards any frames
+ * with a destination address that does not match the MAC address
+ * of the adaptor.
+ * When clear, the WiLink receives frames destined to any MAC
+ * address.
+ * 3 Promiscuous - When set, the WiLink receives all valid frames
+ * (i.e., all frames that pass the FCS check).
+ * When clear, only frames that pass the other filters specified
+ * are received.
+ * 2 FCS - When set, the WiLink includes the FCS with the received
+ * frame.
+ * When cleared, the FCS is discarded.
+ * 1 PLCP header - When set, write all data from baseband to frame
+ * buffer including PHY header.
+ * 0 Reserved - Always equal to 0.
+ *
+ * RX Filter Options Table
+ * Bit Definition
+ * === ==========
+ * 31:12 Reserved - Always equal to 0.
+ * 11 Association - When set, the WiLink receives all association
+ * related frames (association request/response, reassocation
+ * request/response, and disassociation). When clear, these frames
+ * are discarded.
+ * 10 Auth/De auth - When set, the WiLink receives all authentication
+ * and de-authentication frames. When clear, these frames are
+ * discarded.
+ * 9 Beacon - When set, the WiLink receives all beacon frames.
+ * When clear, these frames are discarded.
+ * 8 Contention Free - When set, the WiLink receives all contention
+ * free frames.
+ * When clear, these frames are discarded.
+ * 7 Control - When set, the WiLink receives all control frames.
+ * When clear, these frames are discarded.
+ * 6 Data - When set, the WiLink receives all data frames.
+ * When clear, these frames are discarded.
+ * 5 FCS Error - When set, the WiLink receives frames that have FCS
+ * errors.
+ * When clear, these frames are discarded.
+ * 4 Management - When set, the WiLink receives all management
+ * frames.
+ * When clear, these frames are discarded.
+ * 3 Probe Request - When set, the WiLink receives all probe request
+ * frames.
+ * When clear, these frames are discarded.
+ * 2 Probe Response - When set, the WiLink receives all probe
+ * response frames.
+ * When clear, these frames are discarded.
+ * 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
+ * frames.
+ * When clear, these frames are discarded.
+ * 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames
+ * that have reserved frame types and sub types as defined by the
+ * 802.11 specification.
+ * When clear, these frames are discarded.
+ */
+struct acx_rx_config {
+ struct acx_header header;
+
+ u32 config_options;
+ u32 filter_options;
+} __attribute__ ((packed));
+
+enum {
+ QOS_AC_BE = 0,
+ QOS_AC_BK,
+ QOS_AC_VI,
+ QOS_AC_VO,
+ QOS_HIGHEST_AC_INDEX = QOS_AC_VO,
+};
+
+#define MAX_NUM_OF_AC (QOS_HIGHEST_AC_INDEX+1)
+#define FIRST_AC_INDEX QOS_AC_BE
+#define MAX_NUM_OF_802_1d_TAGS 8
+#define AC_PARAMS_MAX_TSID 15
+#define MAX_APSD_CONF 0xffff
+
+#define QOS_TX_HIGH_MIN (0)
+#define QOS_TX_HIGH_MAX (100)
+
+#define QOS_TX_HIGH_BK_DEF (25)
+#define QOS_TX_HIGH_BE_DEF (35)
+#define QOS_TX_HIGH_VI_DEF (35)
+#define QOS_TX_HIGH_VO_DEF (35)
+
+#define QOS_TX_LOW_BK_DEF (15)
+#define QOS_TX_LOW_BE_DEF (25)
+#define QOS_TX_LOW_VI_DEF (25)
+#define QOS_TX_LOW_VO_DEF (25)
+
+struct acx_tx_queue_qos_config {
+ struct acx_header header;
+
+ u8 qid;
+ u8 pad[3];
+
+ /* Max number of blocks allowd in the queue */
+ u16 high_threshold;
+
+ /* Lowest memory blocks guaranteed for this queue */
+ u16 low_threshold;
+} __attribute__ ((packed));
+
+struct acx_packet_detection {
+ struct acx_header header;
+
+ u32 threshold;
+} __attribute__ ((packed));
+
+
+enum acx_slot_type {
+ SLOT_TIME_LONG = 0,
+ SLOT_TIME_SHORT = 1,
+ DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
+ MAX_SLOT_TIMES = 0xFF
+};
+
+#define STATION_WONE_INDEX 0
+
+struct acx_slot {
+ struct acx_header header;
+
+ u8 wone_index; /* Reserved */
+ u8 slot_time;
+ u8 reserved[6];
+} __attribute__ ((packed));
+
+
+#define ADDRESS_GROUP_MAX (8)
+#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX)
+
+struct multicast_grp_addr_start {
+ struct acx_header header;
+
+ u8 enabled;
+ u8 num_groups;
+ u8 pad[2];
+ u8 mac_table[ADDRESS_GROUP_MAX_LEN];
+} __attribute__ ((packed));
+
+
+#define RX_TIMEOUT_PS_POLL_MIN 0
+#define RX_TIMEOUT_PS_POLL_MAX (200000)
+#define RX_TIMEOUT_PS_POLL_DEF (15)
+#define RX_TIMEOUT_UPSD_MIN 0
+#define RX_TIMEOUT_UPSD_MAX (200000)
+#define RX_TIMEOUT_UPSD_DEF (15)
+
+struct acx_rx_timeout {
+ struct acx_header header;
+
+ /*
+ * The longest time the STA will wait to receive
+ * traffic from the AP after a PS-poll has been
+ * transmitted.
+ */
+ u16 ps_poll_timeout;
+
+ /*
+ * The longest time the STA will wait to receive
+ * traffic from the AP after a frame has been sent
+ * from an UPSD enabled queue.
+ */
+ u16 upsd_timeout;
+} __attribute__ ((packed));
+
+#define RTS_THRESHOLD_MIN 0
+#define RTS_THRESHOLD_MAX 4096
+#define RTS_THRESHOLD_DEF 2347
+
+struct acx_rts_threshold {
+ struct acx_header header;
+
+ u16 threshold;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_beacon_filter_option {
+ struct acx_header header;
+
+ u8 enable;
+
+ /*
+ * The number of beacons without the unicast TIM
+ * bit set that the firmware buffers before
+ * signaling the host about ready frames.
+ * When set to 0 and the filter is enabled, beacons
+ * without the unicast TIM bit set are dropped.
+ */
+ u8 max_num_beacons;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+/*
+ * ACXBeaconFilterEntry (not 221)
+ * Byte Offset Size (Bytes) Definition
+ * =========== ============ ==========
+ * 0 1 IE identifier
+ * 1 1 Treatment bit mask
+ *
+ * ACXBeaconFilterEntry (221)
+ * Byte Offset Size (Bytes) Definition
+ * =========== ============ ==========
+ * 0 1 IE identifier
+ * 1 1 Treatment bit mask
+ * 2 3 OUI
+ * 5 1 Type
+ * 6 2 Version
+ *
+ *
+ * Treatment bit mask - The information element handling:
+ * bit 0 - The information element is compared and transferred
+ * in case of change.
+ * bit 1 - The information element is transferred to the host
+ * with each appearance or disappearance.
+ * Note that both bits can be set at the same time.
+ */
+#define BEACON_FILTER_TABLE_MAX_IE_NUM (32)
+#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
+#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE (2)
+#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
+#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
+ BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
+ (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
+ BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
+
+struct acx_beacon_filter_ie_table {
+ struct acx_header header;
+
+ u8 num_ie;
+ u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
+ u8 pad[3];
+} __attribute__ ((packed));
+
+enum {
+ SG_ENABLE = 0,
+ SG_DISABLE,
+ SG_SENSE_NO_ACTIVITY,
+ SG_SENSE_ACTIVE
+};
+
+struct acx_bt_wlan_coex {
+ struct acx_header header;
+
+ /*
+ * 0 -> PTA enabled
+ * 1 -> PTA disabled
+ * 2 -> sense no active mode, i.e.
+ * an interrupt is sent upon
+ * BT activity.
+ * 3 -> PTA is switched on in response
+ * to the interrupt sending.
+ */
+ u8 enable;
+ u8 pad[3];
+} __attribute__ ((packed));
+
+#define PTA_ANTENNA_TYPE_DEF (0)
+#define PTA_BT_HP_MAXTIME_DEF (2000)
+#define PTA_WLAN_HP_MAX_TIME_DEF (5000)
+#define PTA_SENSE_DISABLE_TIMER_DEF (1350)
+#define PTA_PROTECTIVE_RX_TIME_DEF (1500)
+#define PTA_PROTECTIVE_TX_TIME_DEF (1500)
+#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
+#define PTA_SIGNALING_TYPE_DEF (1)
+#define PTA_AFH_LEVERAGE_ON_DEF (0)
+#define PTA_NUMBER_QUIET_CYCLE_DEF (0)
+#define PTA_MAX_NUM_CTS_DEF (3)
+#define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2)
+#define PTA_NUMBER_OF_BT_PACKETS_DEF (2)
+#define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500)
+#define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000)
+#define PTA_CYCLE_TIME_FAST_DEF (8700)
+#define PTA_RX_FOR_AVALANCHE_DEF (5)
+#define PTA_ELP_HP_DEF (0)
+#define PTA_ANTI_STARVE_PERIOD_DEF (500)
+#define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4)
+#define PTA_ALLOW_PA_SD_DEF (1)
+#define PTA_TIME_BEFORE_BEACON_DEF (6300)
+#define PTA_HPDM_MAX_TIME_DEF (1600)
+#define PTA_TIME_OUT_NEXT_WLAN_DEF (2550)
+#define PTA_AUTO_MODE_NO_CTS_DEF (0)
+#define PTA_BT_HP_RESPECTED_DEF (3)
+#define PTA_WLAN_RX_MIN_RATE_DEF (24)
+#define PTA_ACK_MODE_DEF (1)
+
+struct acx_bt_wlan_coex_param {
+ struct acx_header header;
+
+ /*
+ * The minimum rate of a received WLAN packet in the STA,
+ * during protective mode, of which a new BT-HP request
+ * during this Rx will always be respected and gain the antenna.
+ */
+ u32 min_rate;
+
+ /* Max time the BT HP will be respected. */
+ u16 bt_hp_max_time;
+
+ /* Max time the WLAN HP will be respected. */
+ u16 wlan_hp_max_time;
+
+ /*
+ * The time between the last BT activity
+ * and the moment when the sense mode returns
+ * to SENSE_INACTIVE.
+ */
+ u16 sense_disable_timer;
+
+ /* Time before the next BT HP instance */
+ u16 rx_time_bt_hp;
+ u16 tx_time_bt_hp;
+
+ /* range: 10-20000 default: 1500 */
+ u16 rx_time_bt_hp_fast;
+ u16 tx_time_bt_hp_fast;
+
+ /* range: 2000-65535 default: 8700 */
+ u16 wlan_cycle_fast;
+
+ /* range: 0 - 15000 (Msec) default: 1000 */
+ u16 bt_anti_starvation_period;
+
+ /* range 400-10000(Usec) default: 3000 */
+ u16 next_bt_lp_packet;
+
+ /* Deafult: worst case for BT DH5 traffic */
+ u16 wake_up_beacon;
+
+ /* range: 0-50000(Usec) default: 1050 */
+ u16 hp_dm_max_guard_time;
+
+ /*
+ * This is to prevent both BT & WLAN antenna
+ * starvation.
+ * Range: 100-50000(Usec) default:2550
+ */
+ u16 next_wlan_packet;
+
+ /* 0 -> shared antenna */
+ u8 antenna_type;
+
+ /*
+ * 0 -> TI legacy
+ * 1 -> Palau
+ */
+ u8 signal_type;
+
+ /*
+ * BT AFH status
+ * 0 -> no AFH
+ * 1 -> from dedicated GPIO
+ * 2 -> AFH on (from host)
+ */
+ u8 afh_leverage_on;
+
+ /*
+ * The number of cycles during which no
+ * TX will be sent after 1 cycle of RX
+ * transaction in protective mode
+ */
+ u8 quiet_cycle_num;
+
+ /*
+ * The maximum number of CTSs that will
+ * be sent for receiving RX packet in
+ * protective mode
+ */
+ u8 max_cts;
+
+ /*
+ * The number of WLAN packets
+ * transferred in common mode before
+ * switching to BT.
+ */
+ u8 wlan_packets_num;
+
+ /*
+ * The number of BT packets
+ * transferred in common mode before
+ * switching to WLAN.
+ */
+ u8 bt_packets_num;
+
+ /* range: 1-255 default: 5 */
+ u8 missed_rx_avalanche;
+
+ /* range: 0-1 default: 1 */
+ u8 wlan_elp_hp;
+
+ /* range: 0 - 15 default: 4 */
+ u8 bt_anti_starvation_cycles;
+
+ u8 ack_mode_dual_ant;
+
+ /*
+ * Allow PA_SD assertion/de-assertion
+ * during enabled BT activity.
+ */
+ u8 pa_sd_enable;
+
+ /*
+ * Enable/Disable PTA in auto mode:
+ * Support Both Active & P.S modes
+ */
+ u8 pta_auto_mode_enable;
+
+ /* range: 0 - 20 default: 1 */
+ u8 bt_hp_respected_num;
+} __attribute__ ((packed));
+
+#define CCA_THRSH_ENABLE_ENERGY_D 0x140A
+#define CCA_THRSH_DISABLE_ENERGY_D 0xFFEF
+
+struct acx_energy_detection {
+ struct acx_header header;
+
+ /* The RX Clear Channel Assessment threshold in the PHY */
+ u16 rx_cca_threshold;
+ u8 tx_energy_detection;
+ u8 pad;
+} __attribute__ ((packed));
+
+#define BCN_RX_TIMEOUT_DEF_VALUE 10000
+#define BROADCAST_RX_TIMEOUT_DEF_VALUE 20000
+#define RX_BROADCAST_IN_PS_DEF_VALUE 1
+#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
+
+struct acx_beacon_broadcast {
+ struct acx_header header;
+
+ u16 beacon_rx_timeout;
+ u16 broadcast_timeout;
+
+ /* Enables receiving of broadcast packets in PS mode */
+ u8 rx_broadcast_in_ps;
+
+ /* Consecutive PS Poll failures before updating the host */
+ u8 ps_poll_threshold;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_event_mask {
+ struct acx_header header;
+
+ u32 event_mask;
+ u32 high_event_mask; /* Unused */
+} __attribute__ ((packed));
+
+#define CFG_RX_FCS BIT(2)
+#define CFG_RX_ALL_GOOD BIT(3)
+#define CFG_UNI_FILTER_EN BIT(4)
+#define CFG_BSSID_FILTER_EN BIT(5)
+#define CFG_MC_FILTER_EN BIT(6)
+#define CFG_MC_ADDR0_EN BIT(7)
+#define CFG_MC_ADDR1_EN BIT(8)
+#define CFG_BC_REJECT_EN BIT(9)
+#define CFG_SSID_FILTER_EN BIT(10)
+#define CFG_RX_INT_FCS_ERROR BIT(11)
+#define CFG_RX_INT_ENCRYPTED BIT(12)
+#define CFG_RX_WR_RX_STATUS BIT(13)
+#define CFG_RX_FILTER_NULTI BIT(14)
+#define CFG_RX_RESERVE BIT(15)
+#define CFG_RX_TIMESTAMP_TSF BIT(16)
+
+#define CFG_RX_RSV_EN BIT(0)
+#define CFG_RX_RCTS_ACK BIT(1)
+#define CFG_RX_PRSP_EN BIT(2)
+#define CFG_RX_PREQ_EN BIT(3)
+#define CFG_RX_MGMT_EN BIT(4)
+#define CFG_RX_FCS_ERROR BIT(5)
+#define CFG_RX_DATA_EN BIT(6)
+#define CFG_RX_CTL_EN BIT(7)
+#define CFG_RX_CF_EN BIT(8)
+#define CFG_RX_BCN_EN BIT(9)
+#define CFG_RX_AUTH_EN BIT(10)
+#define CFG_RX_ASSOC_EN BIT(11)
+
+#define SCAN_PASSIVE BIT(0)
+#define SCAN_5GHZ_BAND BIT(1)
+#define SCAN_TRIGGERED BIT(2)
+#define SCAN_PRIORITY_HIGH BIT(3)
+
+struct acx_fw_gen_frame_rates {
+ struct acx_header header;
+
+ u8 tx_ctrl_frame_rate; /* RATE_* */
+ u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */
+ u8 tx_mgt_frame_rate;
+ u8 tx_mgt_frame_mod;
+} __attribute__ ((packed));
+
+/* STA MAC */
+struct dot11_station_id {
+ struct acx_header header;
+
+ u8 mac[ETH_ALEN];
+ u8 pad[2];
+} __attribute__ ((packed));
+
+/* HW encryption keys */
+#define NUM_ACCESS_CATEGORIES_COPY 4
+#define MAX_KEY_SIZE 32
+
+/* When set, disable HW encryption */
+#define DF_ENCRYPTION_DISABLE 0x01
+/* When set, disable HW decryption */
+#define DF_SNIFF_MODE_ENABLE 0x80
+
+struct acx_feature_config {
+ struct acx_header header;
+
+ u32 options;
+ u32 data_flow_options;
+} __attribute__ ((packed));
+
+enum acx_key_action {
+ KEY_ADD_OR_REPLACE = 1,
+ KEY_REMOVE = 2,
+ KEY_SET_ID = 3,
+ MAX_KEY_ACTION = 0xffff,
+};
+
+enum acx_key_type {
+ KEY_WEP_DEFAULT = 0,
+ KEY_WEP_ADDR = 1,
+ KEY_AES_GROUP = 4,
+ KEY_AES_PAIRWISE = 5,
+ KEY_WEP_GROUP = 6,
+ KEY_TKIP_MIC_GROUP = 10,
+ KEY_TKIP_MIC_PAIRWISE = 11,
+};
+
+/*
+ *
+ * key_type_e key size key format
+ * ---------- --------- ----------
+ * 0x00 5, 13, 29 Key data
+ * 0x01 5, 13, 29 Key data
+ * 0x04 16 16 bytes of key data
+ * 0x05 16 16 bytes of key data
+ * 0x0a 32 16 bytes of TKIP key data
+ * 8 bytes of RX MIC key data
+ * 8 bytes of TX MIC key data
+ * 0x0b 32 16 bytes of TKIP key data
+ * 8 bytes of RX MIC key data
+ * 8 bytes of TX MIC key data
+ *
+ */
+
+struct acx_set_key {
+ /* Ignored for default WEP key */
+ u8 addr[ETH_ALEN];
+
+ /* key_action_e */
+ u16 key_action;
+
+ u16 reserved_1;
+
+ /* key size in bytes */
+ u8 key_size;
+
+ /* key_type_e */
+ u8 key_type;
+ u8 ssid_profile;
+
+ /*
+ * TKIP, AES: frame's key id field.
+ * For WEP default key: key id;
+ */
+ u8 id;
+ u8 reserved_2[6];
+ u8 key[MAX_KEY_SIZE];
+ u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
+ u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
+} __attribute__ ((packed));
+
+struct acx_current_tx_power {
+ struct acx_header header;
+
+ u8 current_tx_power;
+ u8 padding[3];
+} __attribute__ ((packed));
+
+struct acx_dot11_default_key {
+ struct acx_header header;
+
+ u8 id;
+ u8 pad[3];
+} __attribute__ ((packed));
+
+struct acx_tsf_info {
+ struct acx_header header;
+
+ u32 current_tsf_msb;
+ u32 current_tsf_lsb;
+ u32 last_TBTT_msb;
+ u32 last_TBTT_lsb;
+ u8 last_dtim_count;
+ u8 pad[3];
+} __attribute__ ((packed));
+
+/* 802.11 PS */
+enum acx_ps_mode {
+ STATION_ACTIVE_MODE,
+ STATION_POWER_SAVE_MODE
+};
+
+struct acx_ps_params {
+ u8 ps_mode; /* STATION_* */
+ u8 send_null_data; /* Do we have to send NULL data packet ? */
+ u8 retries; /* Number of retires for the initial NULL data packet */
+
+ /*
+ * TUs during which the target stays awake after switching
+ * to power save mode.
+ */
+ u8 hang_over_period;
+ u16 null_data_rate;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+enum acx_wake_up_event {
+ WAKE_UP_EVENT_BEACON_BITMAP = 0x01, /* Wake on every Beacon*/
+ WAKE_UP_EVENT_DTIM_BITMAP = 0x02, /* Wake on every DTIM*/
+ WAKE_UP_EVENT_N_DTIM_BITMAP = 0x04, /* Wake on every Nth DTIM */
+ WAKE_UP_EVENT_N_BEACONS_BITMAP = 0x08, /* Wake on every Nth Beacon */
+ WAKE_UP_EVENT_BITS_MASK = 0x0F
+};
+
+struct acx_wake_up_condition {
+ struct acx_header header;
+
+ u8 wake_up_event; /* Only one bit can be set */
+ u8 listen_interval;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_aid {
+ struct acx_header header;
+
+ /*
+ * To be set when associated with an AP.
+ */
+ u16 aid;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+enum acx_preamble_type {
+ ACX_PREAMBLE_LONG = 0,
+ ACX_PREAMBLE_SHORT = 1
+};
+
+struct acx_preamble {
+ struct acx_header header;
+ /*
+ * When set, the WiLink transmits the frames with a short preamble and
+ * when cleared, the WiLink transmits the frames with a long preamble.
+ */
+ u8 preamble;
+ u8 padding[3];
+} __attribute__ ((packed));
+
+enum acx_ctsprotect_type {
+ CTSPROTECT_DISABLE = 0,
+ CTSPROTECT_ENABLE = 1
+};
+
+struct acx_ctsprotect {
+ struct acx_header header;
+ u8 ctsprotect;
+ u8 padding[3];
+} __attribute__ ((packed));
+
+struct acx_tx_statistics {
+ u32 internal_desc_overflow;
+} __attribute__ ((packed));
+
+struct acx_rx_statistics {
+ u32 out_of_mem;
+ u32 hdr_overflow;
+ u32 hw_stuck;
+ u32 dropped;
+ u32 fcs_err;
+ u32 xfr_hint_trig;
+ u32 path_reset;
+ u32 reset_counter;
+} __attribute__ ((packed));
+
+struct acx_dma_statistics {
+ u32 rx_requested;
+ u32 rx_errors;
+ u32 tx_requested;
+ u32 tx_errors;
+} __attribute__ ((packed));
+
+struct acx_isr_statistics {
+ /* host command complete */
+ u32 cmd_cmplt;
+
+ /* fiqisr() */
+ u32 fiqs;
+
+ /* (INT_STS_ND & INT_TRIG_RX_HEADER) */
+ u32 rx_headers;
+
+ /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
+ u32 rx_completes;
+
+ /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
+ u32 rx_mem_overflow;
+
+ /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
+ u32 rx_rdys;
+
+ /* irqisr() */
+ u32 irqs;
+
+ /* (INT_STS_ND & INT_TRIG_TX_PROC) */
+ u32 tx_procs;
+
+ /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
+ u32 decrypt_done;
+
+ /* (INT_STS_ND & INT_TRIG_DMA0) */
+ u32 dma0_done;
+
+ /* (INT_STS_ND & INT_TRIG_DMA1) */
+ u32 dma1_done;
+
+ /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
+ u32 tx_exch_complete;
+
+ /* (INT_STS_ND & INT_TRIG_COMMAND) */
+ u32 commands;
+
+ /* (INT_STS_ND & INT_TRIG_RX_PROC) */
+ u32 rx_procs;
+
+ /* (INT_STS_ND & INT_TRIG_PM_802) */
+ u32 hw_pm_mode_changes;
+
+ /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
+ u32 host_acknowledges;
+
+ /* (INT_STS_ND & INT_TRIG_PM_PCI) */
+ u32 pci_pm;
+
+ /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
+ u32 wakeups;
+
+ /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
+ u32 low_rssi;
+} __attribute__ ((packed));
+
+struct acx_wep_statistics {
+ /* WEP address keys configured */
+ u32 addr_key_count;
+
+ /* default keys configured */
+ u32 default_key_count;
+
+ u32 reserved;
+
+ /* number of times that WEP key not found on lookup */
+ u32 key_not_found;
+
+ /* number of times that WEP key decryption failed */
+ u32 decrypt_fail;
+
+ /* WEP packets decrypted */
+ u32 packets;
+
+ /* WEP decrypt interrupts */
+ u32 interrupt;
+} __attribute__ ((packed));
+
+#define ACX_MISSED_BEACONS_SPREAD 10
+
+struct acx_pwr_statistics {
+ /* the amount of enters into power save mode (both PD & ELP) */
+ u32 ps_enter;
+
+ /* the amount of enters into ELP mode */
+ u32 elp_enter;
+
+ /* the amount of missing beacon interrupts to the host */
+ u32 missing_bcns;
+
+ /* the amount of wake on host-access times */
+ u32 wake_on_host;
+
+ /* the amount of wake on timer-expire */
+ u32 wake_on_timer_exp;
+
+ /* the number of packets that were transmitted with PS bit set */
+ u32 tx_with_ps;
+
+ /* the number of packets that were transmitted with PS bit clear */
+ u32 tx_without_ps;
+
+ /* the number of received beacons */
+ u32 rcvd_beacons;
+
+ /* the number of entering into PowerOn (power save off) */
+ u32 power_save_off;
+
+ /* the number of entries into power save mode */
+ u16 enable_ps;
+
+ /*
+ * the number of exits from power save, not including failed PS
+ * transitions
+ */
+ u16 disable_ps;
+
+ /*
+ * the number of times the TSF counter was adjusted because
+ * of drift
+ */
+ u32 fix_tsf_ps;
+
+ /* Gives statistics about the spread continuous missed beacons.
+ * The 16 LSB are dedicated for the PS mode.
+ * The 16 MSB are dedicated for the PS mode.
+ * cont_miss_bcns_spread[0] - single missed beacon.
+ * cont_miss_bcns_spread[1] - two continuous missed beacons.
+ * cont_miss_bcns_spread[2] - three continuous missed beacons.
+ * ...
+ * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
+ */
+ u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
+
+ /* the number of beacons in awake mode */
+ u32 rcvd_awake_beacons;
+} __attribute__ ((packed));
+
+struct acx_mic_statistics {
+ u32 rx_pkts;
+ u32 calc_failure;
+} __attribute__ ((packed));
+
+struct acx_aes_statistics {
+ u32 encrypt_fail;
+ u32 decrypt_fail;
+ u32 encrypt_packets;
+ u32 decrypt_packets;
+ u32 encrypt_interrupt;
+ u32 decrypt_interrupt;
+} __attribute__ ((packed));
+
+struct acx_event_statistics {
+ u32 heart_beat;
+ u32 calibration;
+ u32 rx_mismatch;
+ u32 rx_mem_empty;
+ u32 rx_pool;
+ u32 oom_late;
+ u32 phy_transmit_error;
+ u32 tx_stuck;
+} __attribute__ ((packed));
+
+struct acx_ps_statistics {
+ u32 pspoll_timeouts;
+ u32 upsd_timeouts;
+ u32 upsd_max_sptime;
+ u32 upsd_max_apturn;
+ u32 pspoll_max_apturn;
+ u32 pspoll_utilization;
+ u32 upsd_utilization;
+} __attribute__ ((packed));
+
+struct acx_rxpipe_statistics {
+ u32 rx_prep_beacon_drop;
+ u32 descr_host_int_trig_rx_data;
+ u32 beacon_buffer_thres_host_int_trig_rx_data;
+ u32 missed_beacon_host_int_trig_rx_data;
+ u32 tx_xfr_host_int_trig_rx_data;
+} __attribute__ ((packed));
+
+struct acx_statistics {
+ struct acx_header header;
+
+ struct acx_tx_statistics tx;
+ struct acx_rx_statistics rx;
+ struct acx_dma_statistics dma;
+ struct acx_isr_statistics isr;
+ struct acx_wep_statistics wep;
+ struct acx_pwr_statistics pwr;
+ struct acx_aes_statistics aes;
+ struct acx_mic_statistics mic;
+ struct acx_event_statistics event;
+ struct acx_ps_statistics ps;
+ struct acx_rxpipe_statistics rxpipe;
+} __attribute__ ((packed));
+
+enum {
+ ACX_WAKE_UP_CONDITIONS = 0x0002,
+ ACX_MEM_CFG = 0x0003,
+ ACX_SLOT = 0x0004,
+ ACX_QUEUE_HEAD = 0x0005, /* for MASTER mode only */
+ ACX_AC_CFG = 0x0007,
+ ACX_MEM_MAP = 0x0008,
+ ACX_AID = 0x000A,
+ ACX_RADIO_PARAM = 0x000B, /* Not used */
+ ACX_CFG = 0x000C, /* Not used */
+ ACX_FW_REV = 0x000D,
+ ACX_MEDIUM_USAGE = 0x000F,
+ ACX_RX_CFG = 0x0010,
+ ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */
+ ACX_BSS_IN_PS = 0x0012, /* for AP only */
+ ACX_STATISTICS = 0x0013, /* Debug API */
+ ACX_FEATURE_CFG = 0x0015,
+ ACX_MISC_CFG = 0x0017, /* Not used */
+ ACX_TID_CFG = 0x001A,
+ ACX_BEACON_FILTER_OPT = 0x001F,
+ ACX_LOW_RSSI = 0x0020,
+ ACX_NOISE_HIST = 0x0021,
+ ACX_HDK_VERSION = 0x0022, /* ??? */
+ ACX_PD_THRESHOLD = 0x0023,
+ ACX_DATA_PATH_PARAMS = 0x0024, /* WO */
+ ACX_DATA_PATH_RESP_PARAMS = 0x0024, /* RO */
+ ACX_CCA_THRESHOLD = 0x0025,
+ ACX_EVENT_MBOX_MASK = 0x0026,
+#ifdef FW_RUNNING_AS_AP
+ ACX_DTIM_PERIOD = 0x0027, /* for AP only */
+#else
+ ACX_WR_TBTT_AND_DTIM = 0x0027, /* STA only */
+#endif
+ ACX_ACI_OPTION_CFG = 0x0029, /* OBSOLETE (for 1251)*/
+ ACX_GPIO_CFG = 0x002A, /* Not used */
+ ACX_GPIO_SET = 0x002B, /* Not used */
+ ACX_PM_CFG = 0x002C, /* To Be Documented */
+ ACX_CONN_MONIT_PARAMS = 0x002D,
+ ACX_AVERAGE_RSSI = 0x002E, /* Not used */
+ ACX_CONS_TX_FAILURE = 0x002F,
+ ACX_BCN_DTIM_OPTIONS = 0x0031,
+ ACX_SG_ENABLE = 0x0032,
+ ACX_SG_CFG = 0x0033,
+ ACX_ANTENNA_DIVERSITY_CFG = 0x0035, /* To Be Documented */
+ ACX_LOW_SNR = 0x0037, /* To Be Documented */
+ ACX_BEACON_FILTER_TABLE = 0x0038,
+ ACX_ARP_IP_FILTER = 0x0039,
+ ACX_ROAMING_STATISTICS_TBL = 0x003B,
+ ACX_RATE_POLICY = 0x003D,
+ ACX_CTS_PROTECTION = 0x003E,
+ ACX_SLEEP_AUTH = 0x003F,
+ ACX_PREAMBLE_TYPE = 0x0040,
+ ACX_ERROR_CNT = 0x0041,
+ ACX_FW_GEN_FRAME_RATES = 0x0042,
+ ACX_IBSS_FILTER = 0x0044,
+ ACX_SERVICE_PERIOD_TIMEOUT = 0x0045,
+ ACX_TSF_INFO = 0x0046,
+ ACX_CONFIG_PS_WMM = 0x0049,
+ ACX_ENABLE_RX_DATA_FILTER = 0x004A,
+ ACX_SET_RX_DATA_FILTER = 0x004B,
+ ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
+ ACX_POWER_LEVEL_TABLE = 0x004D,
+ ACX_BET_ENABLE = 0x0050,
+ DOT11_STATION_ID = 0x1001,
+ DOT11_RX_MSDU_LIFE_TIME = 0x1004,
+ DOT11_CUR_TX_PWR = 0x100D,
+ DOT11_DEFAULT_KEY = 0x1010,
+ DOT11_RX_DOT11_MODE = 0x1012,
+ DOT11_RTS_THRESHOLD = 0x1013,
+ DOT11_GROUP_ADDRESS_TBL = 0x1014,
+
+ MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
+
+ MAX_IE = 0xFFFF
+};
+
+
+int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
+ u8 mgt_rate, u8 mgt_mod);
+int wl12xx_acx_station_id(struct wl12xx *wl);
+int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id);
+int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval);
+int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth);
+int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len);
+int wl12xx_acx_tx_power(struct wl12xx *wl, int power);
+int wl12xx_acx_feature_cfg(struct wl12xx *wl);
+int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len);
+int wl12xx_acx_data_path_params(struct wl12xx *wl,
+ struct acx_data_path_params_resp *data_path);
+int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time);
+int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter);
+int wl12xx_acx_pd_threshold(struct wl12xx *wl);
+int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time);
+int wl12xx_acx_group_address_tbl(struct wl12xx *wl);
+int wl12xx_acx_service_period_timeout(struct wl12xx *wl);
+int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold);
+int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl);
+int wl12xx_acx_beacon_filter_table(struct wl12xx *wl);
+int wl12xx_acx_sg_enable(struct wl12xx *wl);
+int wl12xx_acx_sg_cfg(struct wl12xx *wl);
+int wl12xx_acx_cca_threshold(struct wl12xx *wl);
+int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl);
+int wl12xx_acx_aid(struct wl12xx *wl, u16 aid);
+int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask);
+int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble);
+int wl12xx_acx_cts_protect(struct wl12xx *wl,
+ enum acx_ctsprotect_type ctsprotect);
+int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats);
+
+#endif /* __WL12XX_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
new file mode 100644
index 000000000000..48ac08c429bd
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -0,0 +1,295 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include <linux/gpio.h>
+
+#include "reg.h"
+#include "boot.h"
+#include "spi.h"
+#include "event.h"
+
+static void wl12xx_boot_enable_interrupts(struct wl12xx *wl)
+{
+ enable_irq(wl->irq);
+}
+
+void wl12xx_boot_target_enable_interrupts(struct wl12xx *wl)
+{
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+ wl12xx_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
+}
+
+int wl12xx_boot_soft_reset(struct wl12xx *wl)
+{
+ unsigned long timeout;
+ u32 boot_data;
+
+ /* perform soft reset */
+ wl12xx_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
+
+ /* SOFT_RESET is self clearing */
+ timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
+ while (1) {
+ boot_data = wl12xx_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
+ wl12xx_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
+ if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
+ break;
+
+ if (time_after(jiffies, timeout)) {
+ /* 1.2 check pWhalBus->uSelfClearTime if the
+ * timeout was reached */
+ wl12xx_error("soft reset timeout");
+ return -1;
+ }
+
+ udelay(SOFT_RESET_STALL_TIME);
+ }
+
+ /* disable Rx/Tx */
+ wl12xx_reg_write32(wl, ENABLE, 0x0);
+
+ /* disable auto calibration on start*/
+ wl12xx_reg_write32(wl, SPARE_A2, 0xffff);
+
+ return 0;
+}
+
+int wl12xx_boot_init_seq(struct wl12xx *wl)
+{
+ u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq;
+
+ /*
+ * col #1: INTEGER_DIVIDER
+ * col #2: FRACTIONAL_DIVIDER
+ * col #3: ATTN_BB
+ * col #4: ALPHA_BB
+ * col #5: STOP_TIME_BB
+ * col #6: BB_PLL_LOOP_FILTER
+ */
+ static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = {
+
+ { 83, 87381, 0xB, 5, 0xF00, 3}, /* REF_FREQ_19_2*/
+ { 61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/
+ { 41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/
+ { 40, 0, 0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/
+ { 47, 162280, 0xC, 6, 0x2760, 1} /* REF_FREQ_33_6 */
+ };
+
+ /* read NVS params */
+ scr_pad6 = wl12xx_reg_read32(wl, SCR_PAD6);
+ wl12xx_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6);
+
+ /* read ELP_CMD */
+ elp_cmd = wl12xx_reg_read32(wl, ELP_CMD);
+ wl12xx_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd);
+
+ /* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */
+ ref_freq = scr_pad6 & 0x000000FF;
+ wl12xx_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq);
+
+ wl12xx_reg_write32(wl, PLL_CAL_TIME, 0x9);
+
+ /*
+ * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME)
+ */
+ wl12xx_reg_write32(wl, CLK_BUF_TIME, 0x6);
+
+ /*
+ * set the clock detect feature to work in the restart wu procedure
+ * (ELP_CFG_MODE[14]) and Select the clock source type
+ * (ELP_CFG_MODE[13:12])
+ */
+ tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000;
+ wl12xx_reg_write32(wl, ELP_CFG_MODE, tmp);
+
+ /* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */
+ elp_cmd |= 0x00000040;
+ wl12xx_reg_write32(wl, ELP_CMD, elp_cmd);
+
+ /* PG 1.2: Set the BB PLL stable time to be 1000usec
+ * (PLL_STABLE_TIME) */
+ wl12xx_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20);
+
+ /* PG 1.2: read clock request time */
+ init_data = wl12xx_reg_read32(wl, CLK_REQ_TIME);
+
+ /*
+ * PG 1.2: set the clock request time to be ref_clk_settling_time -
+ * 1ms = 4ms
+ */
+ if (init_data > 0x21)
+ tmp = init_data - 0x21;
+ else
+ tmp = 0;
+ wl12xx_reg_write32(wl, CLK_REQ_TIME, tmp);
+
+ /* set BB PLL configurations in RF AFE */
+ wl12xx_reg_write32(wl, 0x003058cc, 0x4B5);
+
+ /* set RF_AFE_REG_5 */
+ wl12xx_reg_write32(wl, 0x003058d4, 0x50);
+
+ /* set RF_AFE_CTRL_REG_2 */
+ wl12xx_reg_write32(wl, 0x00305948, 0x11c001);
+
+ /*
+ * change RF PLL and BB PLL divider for VCO clock and adjust VCO
+ * bais current(RF_AFE_REG_13)
+ */
+ wl12xx_reg_write32(wl, 0x003058f4, 0x1e);
+
+ /* set BB PLL configurations */
+ tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000;
+ wl12xx_reg_write32(wl, 0x00305840, tmp);
+
+ /* set fractional divider according to Appendix C-BB PLL
+ * Calculations
+ */
+ tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER];
+ wl12xx_reg_write32(wl, 0x00305844, tmp);
+
+ /* set the initial data for the sigma delta */
+ wl12xx_reg_write32(wl, 0x00305848, 0x3039);
+
+ /*
+ * set the accumulator attenuation value, calibration loop1
+ * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and
+ * the VCO gain
+ */
+ tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) |
+ (LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1;
+ wl12xx_reg_write32(wl, 0x00305854, tmp);
+
+ /*
+ * set the calibration stop time after holdoff time expires and set
+ * settling time HOLD_OFF_TIME_BB
+ */
+ tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000;
+ wl12xx_reg_write32(wl, 0x00305858, tmp);
+
+ /*
+ * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL
+ * constant leakage current to linearize PFD to 0uA -
+ * BB_ILOOPF[7:3]
+ */
+ tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030;
+ wl12xx_reg_write32(wl, 0x003058f8, tmp);
+
+ /*
+ * set regulator output voltage for n divider to
+ * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2],
+ * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB
+ * PLL auto-call to normal mode- BB_CALGAIN_3DB[8]
+ */
+ wl12xx_reg_write32(wl, 0x003058f0, 0x29);
+
+ /* enable restart wakeup sequence (ELP_CMD[0]) */
+ wl12xx_reg_write32(wl, ELP_CMD, elp_cmd | 0x1);
+
+ /* restart sequence completed */
+ udelay(2000);
+
+ return 0;
+}
+
+int wl12xx_boot_run_firmware(struct wl12xx *wl)
+{
+ int loop, ret;
+ u32 chip_id, interrupt;
+
+ wl->chip.op_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
+
+ chip_id = wl12xx_reg_read32(wl, CHIP_ID_B);
+
+ wl12xx_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
+
+ if (chip_id != wl->chip.id) {
+ wl12xx_error("chip id doesn't match after firmware boot");
+ return -EIO;
+ }
+
+ /* wait for init to complete */
+ loop = 0;
+ while (loop++ < INIT_LOOP) {
+ udelay(INIT_LOOP_DELAY);
+ interrupt = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+
+ if (interrupt == 0xffffffff) {
+ wl12xx_error("error reading hardware complete "
+ "init indication");
+ return -EIO;
+ }
+ /* check that ACX_INTR_INIT_COMPLETE is enabled */
+ else if (interrupt & wl->chip.intr_init_complete) {
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+ wl->chip.intr_init_complete);
+ break;
+ }
+ }
+
+ if (loop >= INIT_LOOP) {
+ wl12xx_error("timeout waiting for the hardware to "
+ "complete initialization");
+ return -EIO;
+ }
+
+ /* get hardware config command mail box */
+ wl->cmd_box_addr = wl12xx_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
+
+ /* get hardware config event mail box */
+ wl->event_box_addr = wl12xx_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+
+ /* set the working partition to its "running" mode offset */
+ wl12xx_set_partition(wl,
+ wl->chip.p_table[PART_WORK].mem.start,
+ wl->chip.p_table[PART_WORK].mem.size,
+ wl->chip.p_table[PART_WORK].reg.start,
+ wl->chip.p_table[PART_WORK].reg.size);
+
+ wl12xx_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
+ wl->cmd_box_addr, wl->event_box_addr);
+
+ /*
+ * in case of full asynchronous mode the firmware event must be
+ * ready to receive event from the command mailbox
+ */
+
+ /* enable gpio interrupts */
+ wl12xx_boot_enable_interrupts(wl);
+
+ wl->chip.op_target_enable_interrupts(wl);
+
+ /* unmask all mbox events */
+ wl->event_mask = 0xffffffff;
+
+ ret = wl12xx_event_unmask(wl);
+ if (ret < 0) {
+ wl12xx_error("EVENT mask setting failed");
+ return ret;
+ }
+
+ wl12xx_event_mbox_config(wl);
+
+ /* firmware startup completed */
+ return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h
new file mode 100644
index 000000000000..4fa73132baae
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/boot.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __BOOT_H__
+#define __BOOT_H__
+
+#include "wl12xx.h"
+
+int wl12xx_boot_soft_reset(struct wl12xx *wl);
+int wl12xx_boot_init_seq(struct wl12xx *wl);
+int wl12xx_boot_run_firmware(struct wl12xx *wl);
+void wl12xx_boot_target_enable_interrupts(struct wl12xx *wl);
+
+/* number of times we try to read the INIT interrupt */
+#define INIT_LOOP 20000
+
+/* delay between retries */
+#define INIT_LOOP_DELAY 50
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
new file mode 100644
index 000000000000..f73ab602b7ae
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -0,0 +1,353 @@
+#include "cmd.h"
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "spi.h"
+#include "ps.h"
+
+int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len)
+{
+ struct wl12xx_command cmd;
+ unsigned long timeout;
+ size_t cmd_len;
+ u32 intr;
+ int ret = 0;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.id = type;
+ cmd.status = 0;
+ memcpy(cmd.parameters, buf, buf_len);
+ cmd_len = ALIGN(buf_len, 4) + CMDMBOX_HEADER_LEN;
+
+ wl12xx_ps_elp_wakeup(wl);
+
+ wl12xx_spi_mem_write(wl, wl->cmd_box_addr, &cmd, cmd_len);
+
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
+
+ timeout = jiffies + msecs_to_jiffies(WL12XX_COMMAND_TIMEOUT);
+
+ intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+ while (!(intr & wl->chip.intr_cmd_complete)) {
+ if (time_after(jiffies, timeout)) {
+ wl12xx_error("command complete timeout");
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+
+ msleep(1);
+
+ intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+ }
+
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+ wl->chip.intr_cmd_complete);
+
+out:
+ wl12xx_ps_elp_sleep(wl);
+
+ return ret;
+}
+
+int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer)
+{
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd test");
+
+ ret = wl12xx_cmd_send(wl, CMD_TEST, buf, buf_len);
+ if (ret < 0) {
+ wl12xx_warning("TEST command failed");
+ return ret;
+ }
+
+ if (answer) {
+ struct wl12xx_command *cmd_answer;
+
+ /*
+ * The test command got in, we can read the answer.
+ * The answer would be a wl12xx_command, where the
+ * parameter array contains the actual answer.
+ */
+
+ wl12xx_ps_elp_wakeup(wl);
+
+ wl12xx_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
+
+ wl12xx_ps_elp_sleep(wl);
+
+ cmd_answer = buf;
+ if (cmd_answer->status != CMD_STATUS_SUCCESS)
+ wl12xx_error("TEST command answer error: %d",
+ cmd_answer->status);
+ }
+
+ return 0;
+}
+
+
+int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len,
+ void *answer)
+{
+ struct wl12xx_command *cmd;
+ struct acx_header header;
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd interrogate");
+
+ header.id = ie_id;
+ header.len = ie_len - sizeof(header);
+
+ ret = wl12xx_cmd_send(wl, CMD_INTERROGATE, &header, sizeof(header));
+ if (ret < 0) {
+ wl12xx_error("INTERROGATE command failed");
+ return ret;
+ }
+
+ wl12xx_ps_elp_wakeup(wl);
+
+ /* the interrogate command got in, we can read the answer */
+ wl12xx_spi_mem_read(wl, wl->cmd_box_addr, answer,
+ CMDMBOX_HEADER_LEN + ie_len);
+
+ wl12xx_ps_elp_sleep(wl);
+
+ cmd = answer;
+ if (cmd->status != CMD_STATUS_SUCCESS)
+ wl12xx_error("INTERROGATE command error: %d",
+ cmd->status);
+
+ return 0;
+
+}
+
+int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len)
+{
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd configure");
+
+ ret = wl12xx_cmd_send(wl, CMD_CONFIGURE, ie,
+ ie_len);
+ if (ret < 0) {
+ wl12xx_warning("CONFIGURE command NOK");
+ return ret;
+ }
+
+ return 0;
+
+}
+
+int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
+ void *bitmap, u16 bitmap_len, u8 bitmap_control)
+{
+ struct vbm_update_request vbm;
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd vbm");
+
+ /* Count and period will be filled by the target */
+ vbm.tim.bitmap_ctrl = bitmap_control;
+ if (bitmap_len > PARTIAL_VBM_MAX) {
+ wl12xx_warning("cmd vbm len is %d B, truncating to %d",
+ bitmap_len, PARTIAL_VBM_MAX);
+ bitmap_len = PARTIAL_VBM_MAX;
+ }
+ memcpy(vbm.tim.pvb_field, bitmap, bitmap_len);
+ vbm.tim.identity = identity;
+ vbm.tim.length = bitmap_len + 3;
+
+ vbm.len = cpu_to_le16(bitmap_len + 5);
+
+ ret = wl12xx_cmd_send(wl, CMD_VBM, &vbm, sizeof(vbm));
+ if (ret < 0) {
+ wl12xx_error("VBM command failed");
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable)
+{
+ int ret;
+ u16 cmd_rx, cmd_tx;
+
+ wl12xx_debug(DEBUG_CMD, "cmd data path");
+
+ if (enable) {
+ cmd_rx = CMD_ENABLE_RX;
+ cmd_tx = CMD_ENABLE_TX;
+ } else {
+ cmd_rx = CMD_DISABLE_RX;
+ cmd_tx = CMD_DISABLE_TX;
+ }
+
+ ret = wl12xx_cmd_send(wl, cmd_rx, &channel, sizeof(channel));
+ if (ret < 0) {
+ wl12xx_error("rx %s cmd for channel %d failed",
+ enable ? "start" : "stop", channel);
+ return ret;
+ }
+
+ wl12xx_debug(DEBUG_BOOT, "rx %s cmd channel %d",
+ enable ? "start" : "stop", channel);
+
+ ret = wl12xx_cmd_send(wl, cmd_tx, &channel, sizeof(channel));
+ if (ret < 0) {
+ wl12xx_error("tx %s cmd for channel %d failed",
+ enable ? "start" : "stop", channel);
+ return ret;
+ }
+
+ wl12xx_debug(DEBUG_BOOT, "tx %s cmd channel %d",
+ enable ? "start" : "stop", channel);
+
+ return 0;
+}
+
+int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
+ u16 beacon_interval, u8 wait)
+{
+ unsigned long timeout;
+ struct cmd_join join = {};
+ int ret, i;
+ u8 *bssid;
+
+ /* FIXME: this should be in main.c */
+ ret = wl12xx_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
+ DEFAULT_HW_GEN_MODULATION_TYPE,
+ wl->tx_mgmt_frm_rate,
+ wl->tx_mgmt_frm_mod);
+ if (ret < 0)
+ return ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd join");
+
+ /* Reverse order BSSID */
+ bssid = (u8 *)&join.bssid_lsb;
+ for (i = 0; i < ETH_ALEN; i++)
+ bssid[i] = wl->bssid[ETH_ALEN - i - 1];
+
+ join.rx_config_options = wl->rx_config;
+ join.rx_filter_options = wl->rx_filter;
+
+ join.basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
+ RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
+
+ join.beacon_interval = beacon_interval;
+ join.dtim_interval = dtim_interval;
+ join.bss_type = bss_type;
+ join.channel = wl->channel;
+ join.ctrl = JOIN_CMD_CTRL_TX_FLUSH;
+
+ ret = wl12xx_cmd_send(wl, CMD_START_JOIN, &join, sizeof(join));
+ if (ret < 0) {
+ wl12xx_error("failed to initiate cmd join");
+ return ret;
+ }
+
+ timeout = msecs_to_jiffies(JOIN_TIMEOUT);
+
+ /*
+ * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
+ * simplify locking we just sleep instead, for now
+ */
+ if (wait)
+ msleep(10);
+
+ return 0;
+}
+
+int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode)
+{
+ int ret;
+ struct acx_ps_params ps_params;
+
+ /* FIXME: this should be in ps.c */
+ ret = wl12xx_acx_wake_up_conditions(wl, wl->listen_int);
+ if (ret < 0) {
+ wl12xx_error("Couldnt set wake up conditions");
+ return ret;
+ }
+
+ wl12xx_debug(DEBUG_CMD, "cmd set ps mode");
+
+ ps_params.ps_mode = ps_mode;
+ ps_params.send_null_data = 1;
+ ps_params.retries = 5;
+ ps_params.hang_over_period = 128;
+ ps_params.null_data_rate = 1; /* 1 Mbps */
+
+ ret = wl12xx_cmd_send(wl, CMD_SET_PS_MODE, &ps_params,
+ sizeof(ps_params));
+ if (ret < 0) {
+ wl12xx_error("cmd set_ps_mode failed");
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer)
+{
+ struct cmd_read_write_memory mem_cmd, *mem_answer;
+ struct wl12xx_command cmd;
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd read memory");
+
+ memset(&mem_cmd, 0, sizeof(mem_cmd));
+ mem_cmd.addr = addr;
+ mem_cmd.size = len;
+
+ ret = wl12xx_cmd_send(wl, CMD_READ_MEMORY, &mem_cmd, sizeof(mem_cmd));
+ if (ret < 0) {
+ wl12xx_error("read memory command failed: %d", ret);
+ return ret;
+ }
+
+ /* the read command got in, we can now read the answer */
+ wl12xx_spi_mem_read(wl, wl->cmd_box_addr, &cmd,
+ CMDMBOX_HEADER_LEN + sizeof(mem_cmd));
+
+ if (cmd.status != CMD_STATUS_SUCCESS)
+ wl12xx_error("error in read command result: %d", cmd.status);
+
+ mem_answer = (struct cmd_read_write_memory *) cmd.parameters;
+ memcpy(answer, mem_answer->value, len);
+
+ return 0;
+}
+
+int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
+ void *buf, size_t buf_len)
+{
+ struct wl12xx_cmd_packet_template template;
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd template %d", cmd_id);
+
+ memset(&template, 0, sizeof(template));
+
+ WARN_ON(buf_len > WL12XX_MAX_TEMPLATE_SIZE);
+ buf_len = min_t(size_t, buf_len, WL12XX_MAX_TEMPLATE_SIZE);
+ template.size = cpu_to_le16(buf_len);
+
+ if (buf)
+ memcpy(template.template, buf, buf_len);
+
+ ret = wl12xx_cmd_send(wl, cmd_id, &template,
+ sizeof(template.size) + buf_len);
+ if (ret < 0) {
+ wl12xx_warning("cmd set_template failed: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
new file mode 100644
index 000000000000..aa307dcd081f
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -0,0 +1,265 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __WL12XX_CMD_H__
+#define __WL12XX_CMD_H__
+
+#include "wl12xx.h"
+
+int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len);
+int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer);
+int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len,
+ void *answer);
+int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len);
+int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
+ void *bitmap, u16 bitmap_len, u8 bitmap_control);
+int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable);
+int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
+ u16 beacon_interval, u8 wait);
+int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode);
+int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer);
+int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
+ void *buf, size_t buf_len);
+
+/* unit ms */
+#define WL12XX_COMMAND_TIMEOUT 2000
+
+#define WL12XX_MAX_TEMPLATE_SIZE 300
+
+struct wl12xx_cmd_packet_template {
+ __le16 size;
+ u8 template[WL12XX_MAX_TEMPLATE_SIZE];
+} __attribute__ ((packed));
+
+enum wl12xx_commands {
+ CMD_RESET = 0,
+ CMD_INTERROGATE = 1, /*use this to read information elements*/
+ CMD_CONFIGURE = 2, /*use this to write information elements*/
+ CMD_ENABLE_RX = 3,
+ CMD_ENABLE_TX = 4,
+ CMD_DISABLE_RX = 5,
+ CMD_DISABLE_TX = 6,
+ CMD_SCAN = 8,
+ CMD_STOP_SCAN = 9,
+ CMD_VBM = 10,
+ CMD_START_JOIN = 11,
+ CMD_SET_KEYS = 12,
+ CMD_READ_MEMORY = 13,
+ CMD_WRITE_MEMORY = 14,
+ CMD_BEACON = 19,
+ CMD_PROBE_RESP = 20,
+ CMD_NULL_DATA = 21,
+ CMD_PROBE_REQ = 22,
+ CMD_TEST = 23,
+ CMD_RADIO_CALIBRATE = 25, /* OBSOLETE */
+ CMD_ENABLE_RX_PATH = 27, /* OBSOLETE */
+ CMD_NOISE_HIST = 28,
+ CMD_RX_RESET = 29,
+ CMD_PS_POLL = 30,
+ CMD_QOS_NULL_DATA = 31,
+ CMD_LNA_CONTROL = 32,
+ CMD_SET_BCN_MODE = 33,
+ CMD_MEASUREMENT = 34,
+ CMD_STOP_MEASUREMENT = 35,
+ CMD_DISCONNECT = 36,
+ CMD_SET_PS_MODE = 37,
+ CMD_CHANNEL_SWITCH = 38,
+ CMD_STOP_CHANNEL_SWICTH = 39,
+ CMD_AP_DISCOVERY = 40,
+ CMD_STOP_AP_DISCOVERY = 41,
+ CMD_SPS_SCAN = 42,
+ CMD_STOP_SPS_SCAN = 43,
+ CMD_HEALTH_CHECK = 45,
+ CMD_DEBUG = 46,
+ CMD_TRIGGER_SCAN_TO = 47,
+
+ NUM_COMMANDS,
+ MAX_COMMAND_ID = 0xFFFF,
+};
+
+#define MAX_CMD_PARAMS 572
+
+struct wl12xx_command {
+ u16 id;
+ u16 status;
+ u8 parameters[MAX_CMD_PARAMS];
+};
+
+enum {
+ CMD_MAILBOX_IDLE = 0,
+ CMD_STATUS_SUCCESS = 1,
+ CMD_STATUS_UNKNOWN_CMD = 2,
+ CMD_STATUS_UNKNOWN_IE = 3,
+ CMD_STATUS_REJECT_MEAS_SG_ACTIVE = 11,
+ CMD_STATUS_RX_BUSY = 13,
+ CMD_STATUS_INVALID_PARAM = 14,
+ CMD_STATUS_TEMPLATE_TOO_LARGE = 15,
+ CMD_STATUS_OUT_OF_MEMORY = 16,
+ CMD_STATUS_STA_TABLE_FULL = 17,
+ CMD_STATUS_RADIO_ERROR = 18,
+ CMD_STATUS_WRONG_NESTING = 19,
+ CMD_STATUS_TIMEOUT = 21, /* Driver internal use.*/
+ CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/
+ MAX_COMMAND_STATUS = 0xff
+};
+
+
+/*
+ * CMD_READ_MEMORY
+ *
+ * The host issues this command to read the WiLink device memory/registers.
+ *
+ * Note: The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+/*
+ * CMD_WRITE_MEMORY
+ *
+ * The host issues this command to write the WiLink device memory/registers.
+ *
+ * The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+#define MAX_READ_SIZE 256
+
+struct cmd_read_write_memory {
+ /* The address of the memory to read from or write to.*/
+ u32 addr;
+
+ /* The amount of data in bytes to read from or write to the WiLink
+ * device.*/
+ u32 size;
+
+ /* The actual value read from or written to the Wilink. The source
+ of this field is the Host in WRITE command or the Wilink in READ
+ command. */
+ u8 value[MAX_READ_SIZE];
+};
+
+#define CMDMBOX_HEADER_LEN 4
+#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
+
+
+struct basic_scan_parameters {
+ u32 rx_config_options;
+ u32 rx_filter_options;
+
+ /*
+ * Scan options:
+ * bit 0: When this bit is set, passive scan.
+ * bit 1: Band, when this bit is set we scan
+ * in the 5Ghz band.
+ * bit 2: voice mode, 0 for normal scan.
+ * bit 3: scan priority, 1 for high priority.
+ */
+ u16 scan_options;
+
+ /* Number of channels to scan */
+ u8 num_channels;
+
+ /* Number opf probe requests to send, per channel */
+ u8 num_probe_requests;
+
+ /* Rate and modulation for probe requests */
+ u16 tx_rate;
+
+ u8 tid_trigger;
+ u8 ssid_len;
+ u32 ssid[8];
+
+} __attribute__ ((packed));
+
+struct basic_scan_channel_parameters {
+ u32 min_duration; /* in TU */
+ u32 max_duration; /* in TU */
+ u32 bssid_lsb;
+ u16 bssid_msb;
+
+ /*
+ * bits 0-3: Early termination count.
+ * bits 4-5: Early termination condition.
+ */
+ u8 early_termination;
+
+ u8 tx_power_att;
+ u8 channel;
+ u8 pad[3];
+} __attribute__ ((packed));
+
+/* SCAN parameters */
+#define SCAN_MAX_NUM_OF_CHANNELS 16
+
+struct cmd_scan {
+ struct basic_scan_parameters params;
+ struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
+} __attribute__ ((packed));
+
+enum {
+ BSS_TYPE_IBSS = 0,
+ BSS_TYPE_STA_BSS = 2,
+ BSS_TYPE_AP_BSS = 3,
+ MAX_BSS_TYPE = 0xFF
+};
+
+#define JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */
+#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE 0x01 /* Early wakeup time */
+
+
+struct cmd_join {
+ u32 bssid_lsb;
+ u16 bssid_msb;
+ u16 beacon_interval; /* in TBTTs */
+ u32 rx_config_options;
+ u32 rx_filter_options;
+
+ /*
+ * The target uses this field to determine the rate at
+ * which to transmit control frame responses (such as
+ * ACK or CTS frames).
+ */
+ u16 basic_rate_set;
+ u8 dtim_interval;
+ u8 tx_ctrl_frame_rate; /* OBSOLETE */
+ u8 tx_ctrl_frame_mod; /* OBSOLETE */
+ /*
+ * bits 0-2: This bitwise field specifies the type
+ * of BSS to start or join (BSS_TYPE_*).
+ * bit 4: Band - The radio band in which to join
+ * or start.
+ * 0 - 2.4GHz band
+ * 1 - 5GHz band
+ * bits 3, 5-7: Reserved
+ */
+ u8 bss_type;
+ u8 channel;
+ u8 ssid_len;
+ u8 ssid[IW_ESSID_MAX_SIZE];
+ u8 ctrl; /* JOIN_CMD_CTRL_* */
+ u8 tx_mgt_frame_rate; /* OBSOLETE */
+ u8 tx_mgt_frame_mod; /* OBSOLETE */
+ u8 reserved;
+} __attribute__ ((packed));
+
+
+#endif /* __WL12XX_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
new file mode 100644
index 000000000000..cdb368ce4dae
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -0,0 +1,508 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include "debugfs.h"
+
+#include <linux/skbuff.h>
+
+#include "wl12xx.h"
+#include "acx.h"
+
+/* ms */
+#define WL12XX_DEBUGFS_STATS_LIFETIME 1000
+
+/* debugfs macros idea from mac80211 */
+
+#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
+static ssize_t name## _read(struct file *file, char __user *userbuf, \
+ size_t count, loff_t *ppos) \
+{ \
+ struct wl12xx *wl = file->private_data; \
+ char buf[buflen]; \
+ int res; \
+ \
+ res = scnprintf(buf, buflen, fmt "\n", ##value); \
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+} \
+ \
+static const struct file_operations name## _ops = { \
+ .read = name## _read, \
+ .open = wl12xx_open_file_generic, \
+};
+
+#define DEBUGFS_ADD(name, parent) \
+ wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \
+ wl, &name## _ops); \
+ if (IS_ERR(wl->debugfs.name)) { \
+ ret = PTR_ERR(wl->debugfs.name); \
+ wl->debugfs.name = NULL; \
+ goto out; \
+ }
+
+#define DEBUGFS_DEL(name) \
+ do { \
+ debugfs_remove(wl->debugfs.name); \
+ wl->debugfs.name = NULL; \
+ } while (0)
+
+#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \
+static ssize_t sub## _ ##name## _read(struct file *file, \
+ char __user *userbuf, \
+ size_t count, loff_t *ppos) \
+{ \
+ struct wl12xx *wl = file->private_data; \
+ char buf[buflen]; \
+ int res; \
+ \
+ wl12xx_debugfs_update_stats(wl); \
+ \
+ res = scnprintf(buf, buflen, fmt "\n", \
+ wl->stats.fw_stats->sub.name); \
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+} \
+ \
+static const struct file_operations sub## _ ##name## _ops = { \
+ .read = sub## _ ##name## _read, \
+ .open = wl12xx_open_file_generic, \
+};
+
+#define DEBUGFS_FWSTATS_ADD(sub, name) \
+ DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
+
+#define DEBUGFS_FWSTATS_DEL(sub, name) \
+ DEBUGFS_DEL(sub## _ ##name)
+
+static void wl12xx_debugfs_update_stats(struct wl12xx *wl)
+{
+ mutex_lock(&wl->mutex);
+
+ if (wl->state == WL12XX_STATE_ON &&
+ time_after(jiffies, wl->stats.fw_stats_update +
+ msecs_to_jiffies(WL12XX_DEBUGFS_STATS_LIFETIME))) {
+ wl12xx_acx_statistics(wl, wl->stats.fw_stats);
+ wl->stats.fw_stats_update = jiffies;
+ }
+
+ mutex_unlock(&wl->mutex);
+}
+
+static int wl12xx_open_file_generic(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
+/* skipping wep.reserved */
+DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
+/* skipping cont_miss_bcns_spread for now */
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
+ 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
+
+DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
+DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
+ wl->stats.excessive_retries);
+
+static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct wl12xx *wl = file->private_data;
+ u32 queue_len;
+ char buf[20];
+ int res;
+
+ queue_len = skb_queue_len(&wl->tx_queue);
+
+ res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+
+static const struct file_operations tx_queue_len_ops = {
+ .read = tx_queue_len_read,
+ .open = wl12xx_open_file_generic,
+};
+
+static void wl12xx_debugfs_delete_files(struct wl12xx *wl)
+{
+ DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
+
+ DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
+ DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
+ DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
+ DEBUGFS_FWSTATS_DEL(rx, dropped);
+ DEBUGFS_FWSTATS_DEL(rx, fcs_err);
+ DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
+ DEBUGFS_FWSTATS_DEL(rx, path_reset);
+ DEBUGFS_FWSTATS_DEL(rx, reset_counter);
+
+ DEBUGFS_FWSTATS_DEL(dma, rx_requested);
+ DEBUGFS_FWSTATS_DEL(dma, rx_errors);
+ DEBUGFS_FWSTATS_DEL(dma, tx_requested);
+ DEBUGFS_FWSTATS_DEL(dma, tx_errors);
+
+ DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
+ DEBUGFS_FWSTATS_DEL(isr, fiqs);
+ DEBUGFS_FWSTATS_DEL(isr, rx_headers);
+ DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
+ DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
+ DEBUGFS_FWSTATS_DEL(isr, irqs);
+ DEBUGFS_FWSTATS_DEL(isr, tx_procs);
+ DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
+ DEBUGFS_FWSTATS_DEL(isr, dma0_done);
+ DEBUGFS_FWSTATS_DEL(isr, dma1_done);
+ DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
+ DEBUGFS_FWSTATS_DEL(isr, commands);
+ DEBUGFS_FWSTATS_DEL(isr, rx_procs);
+ DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
+ DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
+ DEBUGFS_FWSTATS_DEL(isr, pci_pm);
+ DEBUGFS_FWSTATS_DEL(isr, wakeups);
+ DEBUGFS_FWSTATS_DEL(isr, low_rssi);
+
+ DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
+ DEBUGFS_FWSTATS_DEL(wep, default_key_count);
+ /* skipping wep.reserved */
+ DEBUGFS_FWSTATS_DEL(wep, key_not_found);
+ DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
+ DEBUGFS_FWSTATS_DEL(wep, packets);
+ DEBUGFS_FWSTATS_DEL(wep, interrupt);
+
+ DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
+ DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
+ DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
+ DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
+ DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
+ DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
+ DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
+ DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
+ DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
+ DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
+ DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
+ DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
+ /* skipping cont_miss_bcns_spread for now */
+ DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
+
+ DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
+ DEBUGFS_FWSTATS_DEL(mic, calc_failure);
+
+ DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
+ DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
+ DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
+ DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
+ DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
+ DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
+
+ DEBUGFS_FWSTATS_DEL(event, heart_beat);
+ DEBUGFS_FWSTATS_DEL(event, calibration);
+ DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
+ DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
+ DEBUGFS_FWSTATS_DEL(event, rx_pool);
+ DEBUGFS_FWSTATS_DEL(event, oom_late);
+ DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
+ DEBUGFS_FWSTATS_DEL(event, tx_stuck);
+
+ DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
+ DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
+ DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
+ DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
+ DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
+ DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
+ DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
+
+ DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
+ DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+ DEBUGFS_DEL(tx_queue_len);
+ DEBUGFS_DEL(retry_count);
+ DEBUGFS_DEL(excessive_retries);
+}
+
+static int wl12xx_debugfs_add_files(struct wl12xx *wl)
+{
+ int ret = 0;
+
+ DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
+
+ DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
+ DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
+ DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
+ DEBUGFS_FWSTATS_ADD(rx, dropped);
+ DEBUGFS_FWSTATS_ADD(rx, fcs_err);
+ DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
+ DEBUGFS_FWSTATS_ADD(rx, path_reset);
+ DEBUGFS_FWSTATS_ADD(rx, reset_counter);
+
+ DEBUGFS_FWSTATS_ADD(dma, rx_requested);
+ DEBUGFS_FWSTATS_ADD(dma, rx_errors);
+ DEBUGFS_FWSTATS_ADD(dma, tx_requested);
+ DEBUGFS_FWSTATS_ADD(dma, tx_errors);
+
+ DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
+ DEBUGFS_FWSTATS_ADD(isr, fiqs);
+ DEBUGFS_FWSTATS_ADD(isr, rx_headers);
+ DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
+ DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
+ DEBUGFS_FWSTATS_ADD(isr, irqs);
+ DEBUGFS_FWSTATS_ADD(isr, tx_procs);
+ DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
+ DEBUGFS_FWSTATS_ADD(isr, dma0_done);
+ DEBUGFS_FWSTATS_ADD(isr, dma1_done);
+ DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
+ DEBUGFS_FWSTATS_ADD(isr, commands);
+ DEBUGFS_FWSTATS_ADD(isr, rx_procs);
+ DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
+ DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
+ DEBUGFS_FWSTATS_ADD(isr, pci_pm);
+ DEBUGFS_FWSTATS_ADD(isr, wakeups);
+ DEBUGFS_FWSTATS_ADD(isr, low_rssi);
+
+ DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
+ DEBUGFS_FWSTATS_ADD(wep, default_key_count);
+ /* skipping wep.reserved */
+ DEBUGFS_FWSTATS_ADD(wep, key_not_found);
+ DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
+ DEBUGFS_FWSTATS_ADD(wep, packets);
+ DEBUGFS_FWSTATS_ADD(wep, interrupt);
+
+ DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
+ DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
+ DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
+ DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
+ DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
+ DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
+ DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
+ DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
+ /* skipping cont_miss_bcns_spread for now */
+ DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
+
+ DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
+ DEBUGFS_FWSTATS_ADD(mic, calc_failure);
+
+ DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
+ DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
+ DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
+ DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
+ DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
+ DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
+
+ DEBUGFS_FWSTATS_ADD(event, heart_beat);
+ DEBUGFS_FWSTATS_ADD(event, calibration);
+ DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
+ DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
+ DEBUGFS_FWSTATS_ADD(event, rx_pool);
+ DEBUGFS_FWSTATS_ADD(event, oom_late);
+ DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
+ DEBUGFS_FWSTATS_ADD(event, tx_stuck);
+
+ DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
+ DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
+ DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
+
+ DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
+ DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+ DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
+ DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
+ DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
+
+out:
+ if (ret < 0)
+ wl12xx_debugfs_delete_files(wl);
+
+ return ret;
+}
+
+void wl12xx_debugfs_reset(struct wl12xx *wl)
+{
+ memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+ wl->stats.retry_count = 0;
+ wl->stats.excessive_retries = 0;
+}
+
+int wl12xx_debugfs_init(struct wl12xx *wl)
+{
+ int ret;
+
+ wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+
+ if (IS_ERR(wl->debugfs.rootdir)) {
+ ret = PTR_ERR(wl->debugfs.rootdir);
+ wl->debugfs.rootdir = NULL;
+ goto err;
+ }
+
+ wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
+ wl->debugfs.rootdir);
+
+ if (IS_ERR(wl->debugfs.fw_statistics)) {
+ ret = PTR_ERR(wl->debugfs.fw_statistics);
+ wl->debugfs.fw_statistics = NULL;
+ goto err_root;
+ }
+
+ wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
+ GFP_KERNEL);
+
+ if (!wl->stats.fw_stats) {
+ ret = -ENOMEM;
+ goto err_fw;
+ }
+
+ wl->stats.fw_stats_update = jiffies;
+
+ ret = wl12xx_debugfs_add_files(wl);
+
+ if (ret < 0)
+ goto err_file;
+
+ return 0;
+
+err_file:
+ kfree(wl->stats.fw_stats);
+ wl->stats.fw_stats = NULL;
+
+err_fw:
+ debugfs_remove(wl->debugfs.fw_statistics);
+ wl->debugfs.fw_statistics = NULL;
+
+err_root:
+ debugfs_remove(wl->debugfs.rootdir);
+ wl->debugfs.rootdir = NULL;
+
+err:
+ return ret;
+}
+
+void wl12xx_debugfs_exit(struct wl12xx *wl)
+{
+ wl12xx_debugfs_delete_files(wl);
+
+ kfree(wl->stats.fw_stats);
+ wl->stats.fw_stats = NULL;
+
+ debugfs_remove(wl->debugfs.fw_statistics);
+ wl->debugfs.fw_statistics = NULL;
+
+ debugfs_remove(wl->debugfs.rootdir);
+ wl->debugfs.rootdir = NULL;
+
+}
diff --git a/drivers/net/wireless/wl12xx/debugfs.h b/drivers/net/wireless/wl12xx/debugfs.h
new file mode 100644
index 000000000000..562cdcbcc874
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/debugfs.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 WL12XX_DEBUGFS_H
+#define WL12XX_DEBUGFS_H
+
+#include "wl12xx.h"
+
+int wl12xx_debugfs_init(struct wl12xx *wl);
+void wl12xx_debugfs_exit(struct wl12xx *wl);
+void wl12xx_debugfs_reset(struct wl12xx *wl);
+
+#endif /* WL12XX_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
new file mode 100644
index 000000000000..99529ca89a7e
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -0,0 +1,127 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include "wl12xx.h"
+#include "reg.h"
+#include "spi.h"
+#include "event.h"
+#include "ps.h"
+
+static int wl12xx_event_scan_complete(struct wl12xx *wl,
+ struct event_mailbox *mbox)
+{
+ wl12xx_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
+ mbox->scheduled_scan_status,
+ mbox->scheduled_scan_channels);
+
+ if (wl->scanning) {
+ mutex_unlock(&wl->mutex);
+ ieee80211_scan_completed(wl->hw, false);
+ mutex_lock(&wl->mutex);
+ wl->scanning = false;
+ }
+
+ return 0;
+}
+
+static void wl12xx_event_mbox_dump(struct event_mailbox *mbox)
+{
+ wl12xx_debug(DEBUG_EVENT, "MBOX DUMP:");
+ wl12xx_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
+ wl12xx_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
+}
+
+static int wl12xx_event_process(struct wl12xx *wl, struct event_mailbox *mbox)
+{
+ int ret;
+ u32 vector;
+
+ wl12xx_event_mbox_dump(mbox);
+
+ vector = mbox->events_vector & ~(mbox->events_mask);
+ wl12xx_debug(DEBUG_EVENT, "vector: 0x%x", vector);
+
+ if (vector & SCAN_COMPLETE_EVENT_ID) {
+ ret = wl12xx_event_scan_complete(wl, mbox);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (vector & BSS_LOSE_EVENT_ID) {
+ wl12xx_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
+
+ if (wl->psm_requested && wl->psm) {
+ ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int wl12xx_event_unmask(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_event_mbox_mask(wl, ~(wl->event_mask));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+void wl12xx_event_mbox_config(struct wl12xx *wl)
+{
+ wl->mbox_ptr[0] = wl12xx_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+ wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
+
+ wl12xx_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
+ wl->mbox_ptr[0], wl->mbox_ptr[1]);
+}
+
+int wl12xx_event_handle(struct wl12xx *wl, u8 mbox_num)
+{
+ struct event_mailbox mbox;
+ int ret;
+
+ wl12xx_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
+
+ if (mbox_num > 1)
+ return -EINVAL;
+
+ /* first we read the mbox descriptor */
+ wl12xx_spi_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
+ sizeof(struct event_mailbox));
+
+ /* process the descriptor */
+ ret = wl12xx_event_process(wl, &mbox);
+ if (ret < 0)
+ return ret;
+
+ /* then we let the firmware know it can go on...*/
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
+
+ return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
new file mode 100644
index 000000000000..1f4c2f7438a7
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/event.h
@@ -0,0 +1,121 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __WL12XX_EVENT_H__
+#define __WL12XX_EVENT_H__
+
+/*
+ * Mbox events
+ *
+ * The event mechanism is based on a pair of event buffers (buffers A and
+ * B) at fixed locations in the target's memory. The host processes one
+ * buffer while the other buffer continues to collect events. If the host
+ * is not processing events, an interrupt is issued to signal that a buffer
+ * is ready. Once the host is done with processing events from one buffer,
+ * it signals the target (with an ACK interrupt) that the event buffer is
+ * free.
+ */
+
+enum {
+ RESERVED1_EVENT_ID = BIT(0),
+ RESERVED2_EVENT_ID = BIT(1),
+ MEASUREMENT_START_EVENT_ID = BIT(2),
+ SCAN_COMPLETE_EVENT_ID = BIT(3),
+ CALIBRATION_COMPLETE_EVENT_ID = BIT(4),
+ ROAMING_TRIGGER_LOW_RSSI_EVENT_ID = BIT(5),
+ PS_REPORT_EVENT_ID = BIT(6),
+ SYNCHRONIZATION_TIMEOUT_EVENT_ID = BIT(7),
+ HEALTH_REPORT_EVENT_ID = BIT(8),
+ ACI_DETECTION_EVENT_ID = BIT(9),
+ DEBUG_REPORT_EVENT_ID = BIT(10),
+ MAC_STATUS_EVENT_ID = BIT(11),
+ DISCONNECT_EVENT_COMPLETE_ID = BIT(12),
+ JOIN_EVENT_COMPLETE_ID = BIT(13),
+ CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(14),
+ BSS_LOSE_EVENT_ID = BIT(15),
+ ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(16),
+ MEASUREMENT_COMPLETE_EVENT_ID = BIT(17),
+ AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(18),
+ SCHEDULED_SCAN_COMPLETE_EVENT_ID = BIT(19),
+ PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(20),
+ RESET_BSS_EVENT_ID = BIT(21),
+ REGAINED_BSS_EVENT_ID = BIT(22),
+ ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID = BIT(23),
+ ROAMING_TRIGGER_LOW_SNR_EVENT_ID = BIT(24),
+ ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID = BIT(25),
+
+ DBG_EVENT_ID = BIT(26),
+ BT_PTA_SENSE_EVENT_ID = BIT(27),
+ BT_PTA_PREDICTION_EVENT_ID = BIT(28),
+ BT_PTA_AVALANCHE_EVENT_ID = BIT(29),
+
+ PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(30),
+
+ EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff,
+};
+
+struct event_debug_report {
+ u8 debug_event_id;
+ u8 num_params;
+ u16 pad;
+ u32 report_1;
+ u32 report_2;
+ u32 report_3;
+} __attribute__ ((packed));
+
+struct event_mailbox {
+ u32 events_vector;
+ u32 events_mask;
+ u32 reserved_1;
+ u32 reserved_2;
+
+ char average_rssi_level;
+ u8 ps_status;
+ u8 channel_switch_status;
+ u8 scheduled_scan_status;
+
+ /* Channels scanned by the scheduled scan */
+ u16 scheduled_scan_channels;
+
+ /* If bit 0 is set -> target's fatal error */
+ u16 health_report;
+ u16 bad_fft_counter;
+ u8 bt_pta_sense_info;
+ u8 bt_pta_protective_info;
+ u32 reserved;
+ u32 debug_report[2];
+
+ /* Number of FCS errors since last event */
+ u32 fcs_err_counter;
+
+ struct event_debug_report report;
+ u8 average_snr_level;
+ u8 padding[19];
+} __attribute__ ((packed));
+
+int wl12xx_event_unmask(struct wl12xx *wl);
+void wl12xx_event_mbox_config(struct wl12xx *wl);
+int wl12xx_event_handle(struct wl12xx *wl, u8 mbox);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
new file mode 100644
index 000000000000..2a573a6010bd
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -0,0 +1,200 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "init.h"
+#include "wl12xx_80211.h"
+#include "acx.h"
+#include "cmd.h"
+
+int wl12xx_hw_init_hwenc_config(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_feature_cfg(wl);
+ if (ret < 0) {
+ wl12xx_warning("couldn't set feature config");
+ return ret;
+ }
+
+ ret = wl12xx_acx_default_key(wl, wl->default_key);
+ if (ret < 0) {
+ wl12xx_warning("couldn't set default key");
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_hw_init_templates_config(struct wl12xx *wl)
+{
+ int ret;
+ u8 partial_vbm[PARTIAL_VBM_MAX];
+
+ /* send empty templates for fw memory reservation */
+ ret = wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
+ sizeof(struct wl12xx_probe_req_template));
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_template_set(wl, CMD_NULL_DATA, NULL,
+ sizeof(struct wl12xx_null_data_template));
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_template_set(wl, CMD_PS_POLL, NULL,
+ sizeof(struct wl12xx_ps_poll_template));
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
+ sizeof
+ (struct wl12xx_qos_null_data_template));
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
+ sizeof
+ (struct wl12xx_probe_resp_template));
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_template_set(wl, CMD_BEACON, NULL,
+ sizeof
+ (struct wl12xx_beacon_template));
+ if (ret < 0)
+ return ret;
+
+ /* tim templates, first reserve space then allocate an empty one */
+ memset(partial_vbm, 0, PARTIAL_VBM_MAX);
+ ret = wl12xx_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_rx_config(struct wl12xx *wl, u32 config, u32 filter)
+{
+ int ret;
+
+ ret = wl12xx_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_rx_config(wl, config, filter);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_phy_config(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_pd_threshold(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_slot(wl, DEFAULT_SLOT_TIME);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_group_address_tbl(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_service_period_timeout(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_beacon_filter(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_beacon_filter_opt(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_beacon_filter_table(wl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_pta(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_sg_enable(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_sg_cfg(wl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_energy_detection(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_cca_threshold(wl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_beacon_broadcast(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_bcn_dtim_options(wl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_power_auth(struct wl12xx *wl)
+{
+ return wl12xx_acx_sleep_auth(wl, WL12XX_PSM_CAM);
+}
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h
new file mode 100644
index 000000000000..c8b6cd0b7c3e
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/init.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __WL12XX_INIT_H__
+#define __WL12XX_INIT_H__
+
+#include "wl12xx.h"
+
+int wl12xx_hw_init_hwenc_config(struct wl12xx *wl);
+int wl12xx_hw_init_templates_config(struct wl12xx *wl);
+int wl12xx_hw_init_mem_config(struct wl12xx *wl);
+int wl12xx_hw_init_rx_config(struct wl12xx *wl, u32 config, u32 filter);
+int wl12xx_hw_init_phy_config(struct wl12xx *wl);
+int wl12xx_hw_init_beacon_filter(struct wl12xx *wl);
+int wl12xx_hw_init_pta(struct wl12xx *wl);
+int wl12xx_hw_init_energy_detection(struct wl12xx *wl);
+int wl12xx_hw_init_beacon_broadcast(struct wl12xx *wl);
+int wl12xx_hw_init_power_auth(struct wl12xx *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
new file mode 100644
index 000000000000..603d6114882e
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -0,0 +1,1358 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/crc32.h>
+#include <linux/etherdevice.h>
+#include <linux/spi/wl12xx.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "wl1251.h"
+#include "spi.h"
+#include "event.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+#include "debugfs.h"
+
+static void wl12xx_disable_interrupts(struct wl12xx *wl)
+{
+ disable_irq(wl->irq);
+}
+
+static void wl12xx_power_off(struct wl12xx *wl)
+{
+ wl->set_power(false);
+}
+
+static void wl12xx_power_on(struct wl12xx *wl)
+{
+ wl->set_power(true);
+}
+
+static irqreturn_t wl12xx_irq(int irq, void *cookie)
+{
+ struct wl12xx *wl;
+
+ wl12xx_debug(DEBUG_IRQ, "IRQ");
+
+ wl = cookie;
+
+ schedule_work(&wl->irq_work);
+
+ return IRQ_HANDLED;
+}
+
+static int wl12xx_fetch_firmware(struct wl12xx *wl)
+{
+ const struct firmware *fw;
+ int ret;
+
+ ret = request_firmware(&fw, wl->chip.fw_filename, &wl->spi->dev);
+
+ if (ret < 0) {
+ wl12xx_error("could not get firmware: %d", ret);
+ return ret;
+ }
+
+ if (fw->size % 4) {
+ wl12xx_error("firmware size is not multiple of 32 bits: %zu",
+ fw->size);
+ ret = -EILSEQ;
+ goto out;
+ }
+
+ wl->fw_len = fw->size;
+ wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
+
+ if (!wl->fw) {
+ wl12xx_error("could not allocate memory for the firmware");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(wl->fw, fw->data, wl->fw_len);
+
+ ret = 0;
+
+out:
+ release_firmware(fw);
+
+ return ret;
+}
+
+static int wl12xx_fetch_nvs(struct wl12xx *wl)
+{
+ const struct firmware *fw;
+ int ret;
+
+ ret = request_firmware(&fw, wl->chip.nvs_filename, &wl->spi->dev);
+
+ if (ret < 0) {
+ wl12xx_error("could not get nvs file: %d", ret);
+ return ret;
+ }
+
+ if (fw->size % 4) {
+ wl12xx_error("nvs size is not multiple of 32 bits: %zu",
+ fw->size);
+ ret = -EILSEQ;
+ goto out;
+ }
+
+ wl->nvs_len = fw->size;
+ wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
+
+ if (!wl->nvs) {
+ wl12xx_error("could not allocate memory for the nvs file");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(wl->nvs, fw->data, wl->nvs_len);
+
+ ret = 0;
+
+out:
+ release_firmware(fw);
+
+ return ret;
+}
+
+static void wl12xx_fw_wakeup(struct wl12xx *wl)
+{
+ u32 elp_reg;
+
+ elp_reg = ELPCTRL_WAKE_UP;
+ wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+ elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+
+ if (!(elp_reg & ELPCTRL_WLAN_READY)) {
+ wl12xx_warning("WLAN not ready");
+ elp_reg = ELPCTRL_WAKE_UP_WLAN_READY;
+ wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+ }
+}
+
+static int wl12xx_chip_wakeup(struct wl12xx *wl)
+{
+ int ret = 0;
+
+ wl12xx_power_on(wl);
+ msleep(wl->chip.power_on_sleep);
+ wl12xx_spi_reset(wl);
+ wl12xx_spi_init(wl);
+
+ /* We don't need a real memory partition here, because we only want
+ * to use the registers at this point. */
+ wl12xx_set_partition(wl,
+ 0x00000000,
+ 0x00000000,
+ REGISTERS_BASE,
+ REGISTERS_DOWN_SIZE);
+
+ /* ELP module wake up */
+ wl12xx_fw_wakeup(wl);
+
+ /* whal_FwCtrl_BootSm() */
+
+ /* 0. read chip id from CHIP_ID */
+ wl->chip.id = wl12xx_reg_read32(wl, CHIP_ID_B);
+
+ /* 1. check if chip id is valid */
+
+ switch (wl->chip.id) {
+ case CHIP_ID_1251_PG12:
+ wl12xx_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
+ wl->chip.id);
+
+ wl1251_setup(wl);
+
+ break;
+ case CHIP_ID_1271_PG10:
+ case CHIP_ID_1251_PG10:
+ case CHIP_ID_1251_PG11:
+ default:
+ wl12xx_error("unsupported chip id: 0x%x", wl->chip.id);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (wl->fw == NULL) {
+ ret = wl12xx_fetch_firmware(wl);
+ if (ret < 0)
+ goto out;
+ }
+
+ /* No NVS from netlink, try to get it from the filesystem */
+ if (wl->nvs == NULL) {
+ ret = wl12xx_fetch_nvs(wl);
+ if (ret < 0)
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void wl12xx_filter_work(struct work_struct *work)
+{
+ struct wl12xx *wl =
+ container_of(work, struct wl12xx, filter_work);
+ int ret;
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->state == WL12XX_STATE_OFF)
+ goto out;
+
+ ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
+ if (ret < 0)
+ goto out;
+
+out:
+ mutex_unlock(&wl->mutex);
+}
+
+int wl12xx_plt_start(struct wl12xx *wl)
+{
+ int ret;
+
+ wl12xx_notice("power up");
+
+ if (wl->state != WL12XX_STATE_OFF) {
+ wl12xx_error("cannot go into PLT state because not "
+ "in off state: %d", wl->state);
+ return -EBUSY;
+ }
+
+ wl->state = WL12XX_STATE_PLT;
+
+ ret = wl12xx_chip_wakeup(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl->chip.op_boot(wl);
+ if (ret < 0)
+ return ret;
+
+ wl12xx_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
+
+ ret = wl->chip.op_plt_init(wl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_plt_stop(struct wl12xx *wl)
+{
+ wl12xx_notice("power down");
+
+ if (wl->state != WL12XX_STATE_PLT) {
+ wl12xx_error("cannot power down because not in PLT "
+ "state: %d", wl->state);
+ return -EBUSY;
+ }
+
+ wl12xx_disable_interrupts(wl);
+ wl12xx_power_off(wl);
+
+ wl->state = WL12XX_STATE_OFF;
+
+ return 0;
+}
+
+
+static int wl12xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct wl12xx *wl = hw->priv;
+
+ skb_queue_tail(&wl->tx_queue, skb);
+
+ schedule_work(&wl->tx_work);
+
+ /*
+ * The workqueue is slow to process the tx_queue and we need stop
+ * the queue here, otherwise the queue will get too long.
+ */
+ if (skb_queue_len(&wl->tx_queue) >= WL12XX_TX_QUEUE_MAX_LENGTH) {
+ ieee80211_stop_queues(wl->hw);
+
+ /*
+ * FIXME: this is racy, the variable is not properly
+ * protected. Maybe fix this by removing the stupid
+ * variable altogether and checking the real queue state?
+ */
+ wl->tx_queue_stopped = true;
+ }
+
+ return NETDEV_TX_OK;
+}
+
+static int wl12xx_op_start(struct ieee80211_hw *hw)
+{
+ struct wl12xx *wl = hw->priv;
+ int ret = 0;
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 start");
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->state != WL12XX_STATE_OFF) {
+ wl12xx_error("cannot start because not in off state: %d",
+ wl->state);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ret = wl12xx_chip_wakeup(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl->chip.op_boot(wl);
+ if (ret < 0)
+ goto out;
+
+ ret = wl->chip.op_hw_init(wl);
+ if (ret < 0)
+ goto out;
+
+ ret = wl12xx_acx_station_id(wl);
+ if (ret < 0)
+ goto out;
+
+ wl->state = WL12XX_STATE_ON;
+
+ wl12xx_info("firmware booted (%s)", wl->chip.fw_ver);
+
+out:
+ if (ret < 0)
+ wl12xx_power_off(wl);
+
+ mutex_unlock(&wl->mutex);
+
+ return ret;
+}
+
+static void wl12xx_op_stop(struct ieee80211_hw *hw)
+{
+ struct wl12xx *wl = hw->priv;
+
+ wl12xx_info("down");
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 stop");
+
+ mutex_lock(&wl->mutex);
+
+ WARN_ON(wl->state != WL12XX_STATE_ON);
+
+ if (wl->scanning) {
+ mutex_unlock(&wl->mutex);
+ ieee80211_scan_completed(wl->hw, true);
+ mutex_lock(&wl->mutex);
+ wl->scanning = false;
+ }
+
+ wl->state = WL12XX_STATE_OFF;
+
+ wl12xx_disable_interrupts(wl);
+
+ mutex_unlock(&wl->mutex);
+
+ cancel_work_sync(&wl->irq_work);
+ cancel_work_sync(&wl->tx_work);
+ cancel_work_sync(&wl->filter_work);
+
+ mutex_lock(&wl->mutex);
+
+ /* let's notify MAC80211 about the remaining pending TX frames */
+ wl12xx_tx_flush(wl);
+
+ wl12xx_power_off(wl);
+
+ memset(wl->bssid, 0, ETH_ALEN);
+ wl->listen_int = 1;
+ wl->bss_type = MAX_BSS_TYPE;
+
+ wl->data_in_count = 0;
+ wl->rx_counter = 0;
+ wl->rx_handled = 0;
+ wl->rx_current_buffer = 0;
+ wl->rx_last_id = 0;
+ wl->next_tx_complete = 0;
+ wl->elp = false;
+ wl->psm = 0;
+ wl->tx_queue_stopped = false;
+ wl->power_level = WL12XX_DEFAULT_POWER_LEVEL;
+
+ wl12xx_debugfs_reset(wl);
+
+ mutex_unlock(&wl->mutex);
+}
+
+static int wl12xx_op_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct wl12xx *wl = hw->priv;
+ DECLARE_MAC_BUF(mac);
+ int ret = 0;
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %s",
+ conf->type, print_mac(mac, conf->mac_addr));
+
+ mutex_lock(&wl->mutex);
+
+ switch (conf->type) {
+ case NL80211_IFTYPE_STATION:
+ wl->bss_type = BSS_TYPE_STA_BSS;
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ wl->bss_type = BSS_TYPE_IBSS;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) {
+ memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
+ SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+ ret = wl12xx_acx_station_id(wl);
+ if (ret < 0)
+ goto out;
+ }
+
+out:
+ mutex_unlock(&wl->mutex);
+ return ret;
+}
+
+static void wl12xx_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 remove interface");
+}
+
+static int wl12xx_build_null_data(struct wl12xx *wl)
+{
+ struct wl12xx_null_data_template template;
+
+ if (!is_zero_ether_addr(wl->bssid)) {
+ memcpy(template.header.da, wl->bssid, ETH_ALEN);
+ memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
+ } else {
+ memset(template.header.da, 0xff, ETH_ALEN);
+ memset(template.header.bssid, 0xff, ETH_ALEN);
+ }
+
+ memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
+ template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_NULLFUNC);
+
+ return wl12xx_cmd_template_set(wl, CMD_NULL_DATA, &template,
+ sizeof(template));
+
+}
+
+static int wl12xx_build_ps_poll(struct wl12xx *wl, u16 aid)
+{
+ struct wl12xx_ps_poll_template template;
+
+ memcpy(template.bssid, wl->bssid, ETH_ALEN);
+ memcpy(template.ta, wl->mac_addr, ETH_ALEN);
+ template.aid = aid;
+ template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
+
+ return wl12xx_cmd_template_set(wl, CMD_PS_POLL, &template,
+ sizeof(template));
+
+}
+
+static int wl12xx_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct wl12xx *wl = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
+ int channel, ret = 0;
+
+ channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
+ channel,
+ conf->flags & IEEE80211_CONF_PS ? "on" : "off",
+ conf->power_level);
+
+ mutex_lock(&wl->mutex);
+
+ if (channel != wl->channel) {
+ /* FIXME: use beacon interval provided by mac80211 */
+ ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
+ if (ret < 0)
+ goto out;
+
+ wl->channel = channel;
+ }
+
+ ret = wl12xx_build_null_data(wl);
+ if (ret < 0)
+ goto out;
+
+ if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
+ wl12xx_info("psm enabled");
+
+ wl->psm_requested = true;
+
+ /*
+ * We enter PSM only if we're already associated.
+ * If we're not, we'll enter it when joining an SSID,
+ * through the bss_info_changed() hook.
+ */
+ ret = wl12xx_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+ } else if (!(conf->flags & IEEE80211_CONF_PS) &&
+ wl->psm_requested) {
+ wl12xx_info("psm disabled");
+
+ wl->psm_requested = false;
+
+ if (wl->psm)
+ ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE);
+ }
+
+ if (conf->power_level != wl->power_level) {
+ ret = wl12xx_acx_tx_power(wl, conf->power_level);
+ if (ret < 0)
+ goto out;
+
+ wl->power_level = conf->power_level;
+ }
+
+out:
+ mutex_unlock(&wl->mutex);
+ return ret;
+}
+
+#define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
+ FIF_ALLMULTI | \
+ FIF_FCSFAIL | \
+ FIF_BCN_PRBRESP_PROMISC | \
+ FIF_CONTROL | \
+ FIF_OTHER_BSS)
+
+static void wl12xx_op_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed,
+ unsigned int *total,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ struct wl12xx *wl = hw->priv;
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 configure filter");
+
+ *total &= WL12XX_SUPPORTED_FILTERS;
+ changed &= WL12XX_SUPPORTED_FILTERS;
+
+ if (changed == 0)
+ /* no filters which we support changed */
+ return;
+
+ /* FIXME: wl->rx_config and wl->rx_filter are not protected */
+
+ wl->rx_config = WL12XX_DEFAULT_RX_CONFIG;
+ wl->rx_filter = WL12XX_DEFAULT_RX_FILTER;
+
+ if (*total & FIF_PROMISC_IN_BSS) {
+ wl->rx_config |= CFG_BSSID_FILTER_EN;
+ wl->rx_config |= CFG_RX_ALL_GOOD;
+ }
+ if (*total & FIF_ALLMULTI)
+ /*
+ * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive
+ * all multicast frames
+ */
+ wl->rx_config &= ~CFG_MC_FILTER_EN;
+ if (*total & FIF_FCSFAIL)
+ wl->rx_filter |= CFG_RX_FCS_ERROR;
+ if (*total & FIF_BCN_PRBRESP_PROMISC) {
+ wl->rx_config &= ~CFG_BSSID_FILTER_EN;
+ wl->rx_config &= ~CFG_SSID_FILTER_EN;
+ }
+ if (*total & FIF_CONTROL)
+ wl->rx_filter |= CFG_RX_CTL_EN;
+ if (*total & FIF_OTHER_BSS)
+ wl->rx_filter &= ~CFG_BSSID_FILTER_EN;
+
+ /*
+ * FIXME: workqueues need to be properly cancelled on stop(), for
+ * now let's just disable changing the filter settings. They will
+ * be updated any on config().
+ */
+ /* schedule_work(&wl->filter_work); */
+}
+
+/* HW encryption */
+static int wl12xx_set_key_type(struct wl12xx *wl, struct acx_set_key *key,
+ enum set_key_cmd cmd,
+ struct ieee80211_key_conf *mac80211_key,
+ const u8 *addr)
+{
+ switch (mac80211_key->alg) {
+ case ALG_WEP:
+ if (is_broadcast_ether_addr(addr))
+ key->key_type = KEY_WEP_DEFAULT;
+ else
+ key->key_type = KEY_WEP_ADDR;
+
+ mac80211_key->hw_key_idx = mac80211_key->keyidx;
+ break;
+ case ALG_TKIP:
+ if (is_broadcast_ether_addr(addr))
+ key->key_type = KEY_TKIP_MIC_GROUP;
+ else
+ key->key_type = KEY_TKIP_MIC_PAIRWISE;
+
+ mac80211_key->hw_key_idx = mac80211_key->keyidx;
+ break;
+ case ALG_CCMP:
+ if (is_broadcast_ether_addr(addr))
+ key->key_type = KEY_AES_GROUP;
+ else
+ key->key_type = KEY_AES_PAIRWISE;
+ mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ break;
+ default:
+ wl12xx_error("Unknown key algo 0x%x", mac80211_key->alg);
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct wl12xx *wl = hw->priv;
+ struct acx_set_key wl_key;
+ const u8 *addr;
+ int ret;
+
+ static const u8 bcast_addr[ETH_ALEN] =
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 set key");
+
+ memset(&wl_key, 0, sizeof(wl_key));
+
+ addr = sta ? sta->addr : bcast_addr;
+
+ wl12xx_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
+ wl12xx_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
+ wl12xx_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
+ key->alg, key->keyidx, key->keylen, key->flags);
+ wl12xx_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
+
+ mutex_lock(&wl->mutex);
+
+ switch (cmd) {
+ case SET_KEY:
+ wl_key.key_action = KEY_ADD_OR_REPLACE;
+ break;
+ case DISABLE_KEY:
+ wl_key.key_action = KEY_REMOVE;
+ break;
+ default:
+ wl12xx_error("Unsupported key cmd 0x%x", cmd);
+ break;
+ }
+
+ ret = wl12xx_set_key_type(wl, &wl_key, cmd, key, addr);
+ if (ret < 0) {
+ wl12xx_error("Set KEY type failed");
+ goto out;
+ }
+
+ if (wl_key.key_type != KEY_WEP_DEFAULT)
+ memcpy(wl_key.addr, addr, ETH_ALEN);
+
+ if ((wl_key.key_type == KEY_TKIP_MIC_GROUP) ||
+ (wl_key.key_type == KEY_TKIP_MIC_PAIRWISE)) {
+ /*
+ * We get the key in the following form:
+ * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
+ * but the target is expecting:
+ * TKIP - RX MIC - TX MIC
+ */
+ memcpy(wl_key.key, key->key, 16);
+ memcpy(wl_key.key + 16, key->key + 24, 8);
+ memcpy(wl_key.key + 24, key->key + 16, 8);
+
+ } else {
+ memcpy(wl_key.key, key->key, key->keylen);
+ }
+ wl_key.key_size = key->keylen;
+
+ wl_key.id = key->keyidx;
+ wl_key.ssid_profile = 0;
+
+ wl12xx_dump(DEBUG_CRYPT, "TARGET KEY: ", &wl_key, sizeof(wl_key));
+
+ if (wl12xx_cmd_send(wl, CMD_SET_KEYS, &wl_key, sizeof(wl_key)) < 0) {
+ wl12xx_error("Set KEY failed");
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+out:
+ mutex_unlock(&wl->mutex);
+ return ret;
+}
+
+static int wl12xx_build_basic_rates(char *rates)
+{
+ u8 index = 0;
+
+ rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
+ rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
+ rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
+ rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
+
+ return index;
+}
+
+static int wl12xx_build_extended_rates(char *rates)
+{
+ u8 index = 0;
+
+ rates[index++] = IEEE80211_OFDM_RATE_6MB;
+ rates[index++] = IEEE80211_OFDM_RATE_9MB;
+ rates[index++] = IEEE80211_OFDM_RATE_12MB;
+ rates[index++] = IEEE80211_OFDM_RATE_18MB;
+ rates[index++] = IEEE80211_OFDM_RATE_24MB;
+ rates[index++] = IEEE80211_OFDM_RATE_36MB;
+ rates[index++] = IEEE80211_OFDM_RATE_48MB;
+ rates[index++] = IEEE80211_OFDM_RATE_54MB;
+
+ return index;
+}
+
+
+static int wl12xx_build_probe_req(struct wl12xx *wl, u8 *ssid, size_t ssid_len)
+{
+ struct wl12xx_probe_req_template template;
+ struct wl12xx_ie_rates *rates;
+ char *ptr;
+ u16 size;
+
+ ptr = (char *)&template;
+ size = sizeof(struct ieee80211_header);
+
+ memset(template.header.da, 0xff, ETH_ALEN);
+ memset(template.header.bssid, 0xff, ETH_ALEN);
+ memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
+ template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+
+ /* IEs */
+ /* SSID */
+ template.ssid.header.id = WLAN_EID_SSID;
+ template.ssid.header.len = ssid_len;
+ if (ssid_len && ssid)
+ memcpy(template.ssid.ssid, ssid, ssid_len);
+ size += sizeof(struct wl12xx_ie_header) + ssid_len;
+ ptr += size;
+
+ /* Basic Rates */
+ rates = (struct wl12xx_ie_rates *)ptr;
+ rates->header.id = WLAN_EID_SUPP_RATES;
+ rates->header.len = wl12xx_build_basic_rates(rates->rates);
+ size += sizeof(struct wl12xx_ie_header) + rates->header.len;
+ ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
+
+ /* Extended rates */
+ rates = (struct wl12xx_ie_rates *)ptr;
+ rates->header.id = WLAN_EID_EXT_SUPP_RATES;
+ rates->header.len = wl12xx_build_extended_rates(rates->rates);
+ size += sizeof(struct wl12xx_ie_header) + rates->header.len;
+
+ wl12xx_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
+
+ return wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, &template,
+ size);
+}
+
+static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
+ u8 active_scan, u8 high_prio, u8 num_channels,
+ u8 probe_requests)
+{
+ int i, ret;
+ u32 split_scan = 0;
+ u16 scan_options = 0;
+ struct cmd_scan *params;
+ struct wl12xx_command *cmd_answer;
+
+ if (wl->scanning)
+ return -EINVAL;
+
+ params = kzalloc(sizeof(*params), GFP_KERNEL);
+ if (!params)
+ return -ENOMEM;
+
+ params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
+ params->params.rx_filter_options =
+ cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
+
+ /* High priority scan */
+ if (!active_scan)
+ scan_options |= SCAN_PASSIVE;
+ if (high_prio)
+ scan_options |= SCAN_PRIORITY_HIGH;
+ params->params.scan_options = scan_options;
+
+ params->params.num_channels = num_channels;
+ params->params.num_probe_requests = probe_requests;
+ params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
+ params->params.tid_trigger = 0;
+
+ for (i = 0; i < num_channels; i++) {
+ params->channels[i].min_duration = cpu_to_le32(30000);
+ params->channels[i].max_duration = cpu_to_le32(60000);
+ memset(&params->channels[i].bssid_lsb, 0xff, 4);
+ memset(&params->channels[i].bssid_msb, 0xff, 2);
+ params->channels[i].early_termination = 0;
+ params->channels[i].tx_power_att = 0;
+ params->channels[i].channel = i + 1;
+ memset(params->channels[i].pad, 0, 3);
+ }
+
+ for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++)
+ memset(&params->channels[i], 0,
+ sizeof(struct basic_scan_channel_parameters));
+
+ if (len && ssid) {
+ params->params.ssid_len = len;
+ memcpy(params->params.ssid, ssid, len);
+ } else {
+ params->params.ssid_len = 0;
+ memset(params->params.ssid, 0, 32);
+ }
+
+ ret = wl12xx_build_probe_req(wl, ssid, len);
+ if (ret < 0) {
+ wl12xx_error("PROBE request template failed");
+ goto out;
+ }
+
+ ret = wl12xx_cmd_send(wl, CMD_TRIGGER_SCAN_TO, &split_scan,
+ sizeof(u32));
+ if (ret < 0) {
+ wl12xx_error("Split SCAN failed");
+ goto out;
+ }
+
+ wl12xx_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
+
+ wl->scanning = true;
+
+ ret = wl12xx_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
+ if (ret < 0)
+ wl12xx_error("SCAN failed");
+
+ wl12xx_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
+
+ cmd_answer = (struct wl12xx_command *) params;
+ if (cmd_answer->status != CMD_STATUS_SUCCESS) {
+ wl12xx_error("TEST command answer error: %d",
+ cmd_answer->status);
+ wl->scanning = false;
+ ret = -EIO;
+ goto out;
+ }
+
+out:
+ kfree(params);
+ return ret;
+
+}
+
+static int wl12xx_op_hw_scan(struct ieee80211_hw *hw,
+ struct cfg80211_scan_request *req)
+{
+ struct wl12xx *wl = hw->priv;
+ int ret;
+ u8 *ssid = NULL;
+ size_t ssid_len = 0;
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 hw scan");
+
+ if (req->n_ssids) {
+ ssid = req->ssids[0].ssid;
+ ssid_len = req->ssids[0].ssid_len;
+ }
+
+ mutex_lock(&wl->mutex);
+ ret = wl12xx_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
+ mutex_unlock(&wl->mutex);
+
+ return ret;
+}
+
+static int wl12xx_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+ struct wl12xx *wl = hw->priv;
+ int ret;
+
+ ret = wl12xx_acx_rts_threshold(wl, (u16) value);
+
+ if (ret < 0)
+ wl12xx_warning("wl12xx_op_set_rts_threshold failed: %d", ret);
+
+ return ret;
+}
+
+static void wl12xx_op_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changed)
+{
+ enum acx_ps_mode mode;
+ struct wl12xx *wl = hw->priv;
+ struct sk_buff *beacon;
+ int ret;
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 bss info changed");
+
+ mutex_lock(&wl->mutex);
+
+ if (changed & BSS_CHANGED_ASSOC) {
+ if (bss_conf->assoc) {
+ wl->aid = bss_conf->aid;
+
+ ret = wl12xx_build_ps_poll(wl, wl->aid);
+ if (ret < 0)
+ goto out;
+
+ ret = wl12xx_acx_aid(wl, wl->aid);
+ if (ret < 0)
+ goto out;
+
+ /* If we want to go in PSM but we're not there yet */
+ if (wl->psm_requested && !wl->psm) {
+ mode = STATION_POWER_SAVE_MODE;
+ ret = wl12xx_ps_set_mode(wl, mode);
+ if (ret < 0)
+ goto out;
+ }
+ }
+ }
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ if (bss_conf->use_short_slot)
+ ret = wl12xx_acx_slot(wl, SLOT_TIME_SHORT);
+ else
+ ret = wl12xx_acx_slot(wl, SLOT_TIME_LONG);
+ if (ret < 0) {
+ wl12xx_warning("Set slot time failed %d", ret);
+ goto out;
+ }
+ }
+
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ if (bss_conf->use_short_preamble)
+ wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
+ else
+ wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
+ }
+
+ if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+ if (bss_conf->use_cts_prot)
+ ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_ENABLE);
+ else
+ ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_DISABLE);
+ if (ret < 0) {
+ wl12xx_warning("Set ctsprotect failed %d", ret);
+ goto out;
+ }
+ }
+
+ if (changed & BSS_CHANGED_BSSID) {
+ memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
+
+ ret = wl12xx_build_null_data(wl);
+ if (ret < 0)
+ goto out;
+
+ if (wl->bss_type != BSS_TYPE_IBSS) {
+ ret = wl12xx_cmd_join(wl, wl->bss_type, 5, 100, 1);
+ if (ret < 0)
+ goto out;
+ }
+ }
+
+ if (changed & BSS_CHANGED_BEACON) {
+ beacon = ieee80211_beacon_get(hw, vif);
+ ret = wl12xx_cmd_template_set(wl, CMD_BEACON, beacon->data,
+ beacon->len);
+
+ if (ret < 0) {
+ dev_kfree_skb(beacon);
+ goto out;
+ }
+
+ ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
+ beacon->len);
+
+ dev_kfree_skb(beacon);
+
+ if (ret < 0)
+ goto out;
+
+ ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
+
+ if (ret < 0)
+ goto out;
+ }
+
+out:
+ mutex_unlock(&wl->mutex);
+}
+
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_rate wl12xx_rates[] = {
+ { .bitrate = 10,
+ .hw_value = 0x1,
+ .hw_value_short = 0x1, },
+ { .bitrate = 20,
+ .hw_value = 0x2,
+ .hw_value_short = 0x2,
+ .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 55,
+ .hw_value = 0x4,
+ .hw_value_short = 0x4,
+ .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 110,
+ .hw_value = 0x20,
+ .hw_value_short = 0x20,
+ .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 60,
+ .hw_value = 0x8,
+ .hw_value_short = 0x8, },
+ { .bitrate = 90,
+ .hw_value = 0x10,
+ .hw_value_short = 0x10, },
+ { .bitrate = 120,
+ .hw_value = 0x40,
+ .hw_value_short = 0x40, },
+ { .bitrate = 180,
+ .hw_value = 0x80,
+ .hw_value_short = 0x80, },
+ { .bitrate = 240,
+ .hw_value = 0x200,
+ .hw_value_short = 0x200, },
+ { .bitrate = 360,
+ .hw_value = 0x400,
+ .hw_value_short = 0x400, },
+ { .bitrate = 480,
+ .hw_value = 0x800,
+ .hw_value_short = 0x800, },
+ { .bitrate = 540,
+ .hw_value = 0x1000,
+ .hw_value_short = 0x1000, },
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_channel wl12xx_channels[] = {
+ { .hw_value = 1, .center_freq = 2412},
+ { .hw_value = 2, .center_freq = 2417},
+ { .hw_value = 3, .center_freq = 2422},
+ { .hw_value = 4, .center_freq = 2427},
+ { .hw_value = 5, .center_freq = 2432},
+ { .hw_value = 6, .center_freq = 2437},
+ { .hw_value = 7, .center_freq = 2442},
+ { .hw_value = 8, .center_freq = 2447},
+ { .hw_value = 9, .center_freq = 2452},
+ { .hw_value = 10, .center_freq = 2457},
+ { .hw_value = 11, .center_freq = 2462},
+ { .hw_value = 12, .center_freq = 2467},
+ { .hw_value = 13, .center_freq = 2472},
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_supported_band wl12xx_band_2ghz = {
+ .channels = wl12xx_channels,
+ .n_channels = ARRAY_SIZE(wl12xx_channels),
+ .bitrates = wl12xx_rates,
+ .n_bitrates = ARRAY_SIZE(wl12xx_rates),
+};
+
+static const struct ieee80211_ops wl12xx_ops = {
+ .start = wl12xx_op_start,
+ .stop = wl12xx_op_stop,
+ .add_interface = wl12xx_op_add_interface,
+ .remove_interface = wl12xx_op_remove_interface,
+ .config = wl12xx_op_config,
+ .configure_filter = wl12xx_op_configure_filter,
+ .tx = wl12xx_op_tx,
+ .set_key = wl12xx_op_set_key,
+ .hw_scan = wl12xx_op_hw_scan,
+ .bss_info_changed = wl12xx_op_bss_info_changed,
+ .set_rts_threshold = wl12xx_op_set_rts_threshold,
+};
+
+static int wl12xx_register_hw(struct wl12xx *wl)
+{
+ int ret;
+
+ if (wl->mac80211_registered)
+ return 0;
+
+ SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+
+ ret = ieee80211_register_hw(wl->hw);
+ if (ret < 0) {
+ wl12xx_error("unable to register mac80211 hw: %d", ret);
+ return ret;
+ }
+
+ wl->mac80211_registered = true;
+
+ wl12xx_notice("loaded");
+
+ return 0;
+}
+
+static int wl12xx_init_ieee80211(struct wl12xx *wl)
+{
+ /* The tx descriptor buffer and the TKIP space */
+ wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
+ + WL12XX_TKIP_IV_SPACE;
+
+ /* unit us */
+ /* FIXME: find a proper value */
+ wl->hw->channel_change_time = 10000;
+
+ wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
+
+ wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ wl->hw->wiphy->max_scan_ssids = 1;
+ wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl12xx_band_2ghz;
+
+ SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
+
+ return 0;
+}
+
+#define WL12XX_DEFAULT_CHANNEL 1
+static int __devinit wl12xx_probe(struct spi_device *spi)
+{
+ struct wl12xx_platform_data *pdata;
+ struct ieee80211_hw *hw;
+ struct wl12xx *wl;
+ int ret, i;
+ static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
+
+ pdata = spi->dev.platform_data;
+ if (!pdata) {
+ wl12xx_error("no platform data");
+ return -ENODEV;
+ }
+
+ hw = ieee80211_alloc_hw(sizeof(*wl), &wl12xx_ops);
+ if (!hw) {
+ wl12xx_error("could not alloc ieee80211_hw");
+ return -ENOMEM;
+ }
+
+ wl = hw->priv;
+ memset(wl, 0, sizeof(*wl));
+
+ wl->hw = hw;
+ dev_set_drvdata(&spi->dev, wl);
+ wl->spi = spi;
+
+ wl->data_in_count = 0;
+
+ skb_queue_head_init(&wl->tx_queue);
+
+ INIT_WORK(&wl->tx_work, wl12xx_tx_work);
+ INIT_WORK(&wl->filter_work, wl12xx_filter_work);
+ wl->channel = WL12XX_DEFAULT_CHANNEL;
+ wl->scanning = false;
+ wl->default_key = 0;
+ wl->listen_int = 1;
+ wl->rx_counter = 0;
+ wl->rx_handled = 0;
+ wl->rx_current_buffer = 0;
+ wl->rx_last_id = 0;
+ wl->rx_config = WL12XX_DEFAULT_RX_CONFIG;
+ wl->rx_filter = WL12XX_DEFAULT_RX_FILTER;
+ wl->elp = false;
+ wl->psm = 0;
+ wl->psm_requested = false;
+ wl->tx_queue_stopped = false;
+ wl->power_level = WL12XX_DEFAULT_POWER_LEVEL;
+
+ /* We use the default power on sleep time until we know which chip
+ * we're using */
+ wl->chip.power_on_sleep = WL12XX_DEFAULT_POWER_ON_SLEEP;
+
+ for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+ wl->tx_frames[i] = NULL;
+
+ wl->next_tx_complete = 0;
+
+ /*
+ * In case our MAC address is not correctly set,
+ * we use a random but Nokia MAC.
+ */
+ memcpy(wl->mac_addr, nokia_oui, 3);
+ get_random_bytes(wl->mac_addr + 3, 3);
+
+ wl->state = WL12XX_STATE_OFF;
+ mutex_init(&wl->mutex);
+
+ wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
+ wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
+
+ /* This is the only SPI value that we need to set here, the rest
+ * comes from the board-peripherals file */
+ spi->bits_per_word = 32;
+
+ ret = spi_setup(spi);
+ if (ret < 0) {
+ wl12xx_error("spi_setup failed");
+ goto out_free;
+ }
+
+ wl->set_power = pdata->set_power;
+ if (!wl->set_power) {
+ wl12xx_error("set power function missing in platform data");
+ return -ENODEV;
+ }
+
+ wl->irq = spi->irq;
+ if (wl->irq < 0) {
+ wl12xx_error("irq missing in platform data");
+ return -ENODEV;
+ }
+
+ ret = request_irq(wl->irq, wl12xx_irq, 0, DRIVER_NAME, wl);
+ if (ret < 0) {
+ wl12xx_error("request_irq() failed: %d", ret);
+ goto out_free;
+ }
+
+ set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+
+ disable_irq(wl->irq);
+
+ ret = wl12xx_init_ieee80211(wl);
+ if (ret)
+ goto out_irq;
+
+ ret = wl12xx_register_hw(wl);
+ if (ret)
+ goto out_irq;
+
+ wl12xx_debugfs_init(wl);
+
+ wl12xx_notice("initialized");
+
+ return 0;
+
+ out_irq:
+ free_irq(wl->irq, wl);
+
+ out_free:
+ ieee80211_free_hw(hw);
+
+ return ret;
+}
+
+static int __devexit wl12xx_remove(struct spi_device *spi)
+{
+ struct wl12xx *wl = dev_get_drvdata(&spi->dev);
+
+ ieee80211_unregister_hw(wl->hw);
+
+ wl12xx_debugfs_exit(wl);
+
+ free_irq(wl->irq, wl);
+ kfree(wl->target_mem_map);
+ kfree(wl->data_path);
+ kfree(wl->fw);
+ wl->fw = NULL;
+ kfree(wl->nvs);
+ wl->nvs = NULL;
+ ieee80211_free_hw(wl->hw);
+
+ return 0;
+}
+
+
+static struct spi_driver wl12xx_spi_driver = {
+ .driver = {
+ .name = "wl12xx",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = wl12xx_probe,
+ .remove = __devexit_p(wl12xx_remove),
+};
+
+static int __init wl12xx_init(void)
+{
+ int ret;
+
+ ret = spi_register_driver(&wl12xx_spi_driver);
+ if (ret < 0) {
+ wl12xx_error("failed to register spi driver: %d", ret);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void __exit wl12xx_exit(void)
+{
+ spi_unregister_driver(&wl12xx_spi_driver);
+
+ wl12xx_notice("unloaded");
+}
+
+module_init(wl12xx_init);
+module_exit(wl12xx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>, "
+ "Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
new file mode 100644
index 000000000000..83a10117330b
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -0,0 +1,151 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include "reg.h"
+#include "ps.h"
+#include "spi.h"
+
+#define WL12XX_WAKEUP_TIMEOUT 2000
+
+/* Routines to toggle sleep mode while in ELP */
+void wl12xx_ps_elp_sleep(struct wl12xx *wl)
+{
+ if (wl->elp || !wl->psm)
+ return;
+
+ wl12xx_debug(DEBUG_PSM, "chip to elp");
+
+ wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
+
+ wl->elp = true;
+}
+
+int wl12xx_ps_elp_wakeup(struct wl12xx *wl)
+{
+ unsigned long timeout;
+ u32 elp_reg;
+
+ if (!wl->elp)
+ return 0;
+
+ wl12xx_debug(DEBUG_PSM, "waking up chip from elp");
+
+ timeout = jiffies + msecs_to_jiffies(WL12XX_WAKEUP_TIMEOUT);
+
+ wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
+
+ elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+
+ /*
+ * FIXME: we should wait for irq from chip but, as a temporary
+ * solution to simplify locking, let's poll instead
+ */
+ while (!(elp_reg & ELPCTRL_WLAN_READY)) {
+ if (time_after(jiffies, timeout)) {
+ wl12xx_error("elp wakeup timeout");
+ return -ETIMEDOUT;
+ }
+ msleep(1);
+ elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+ }
+
+ wl12xx_debug(DEBUG_PSM, "wakeup time: %u ms",
+ jiffies_to_msecs(jiffies) -
+ (jiffies_to_msecs(timeout) - WL12XX_WAKEUP_TIMEOUT));
+
+ wl->elp = false;
+
+ return 0;
+}
+
+static int wl12xx_ps_set_elp(struct wl12xx *wl, bool enable)
+{
+ int ret;
+
+ if (enable) {
+ wl12xx_debug(DEBUG_PSM, "sleep auth psm/elp");
+
+ /*
+ * FIXME: we should PSM_ELP, but because of firmware wakeup
+ * problems let's use only PSM_PS
+ */
+ ret = wl12xx_acx_sleep_auth(wl, WL12XX_PSM_PS);
+ if (ret < 0)
+ return ret;
+
+ wl12xx_ps_elp_sleep(wl);
+ } else {
+ wl12xx_debug(DEBUG_PSM, "sleep auth cam");
+
+ /*
+ * When the target is in ELP, we can only
+ * access the ELP control register. Thus,
+ * we have to wake the target up before
+ * changing the power authorization.
+ */
+
+ wl12xx_ps_elp_wakeup(wl);
+
+ ret = wl12xx_acx_sleep_auth(wl, WL12XX_PSM_CAM);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode)
+{
+ int ret;
+
+ switch (mode) {
+ case STATION_POWER_SAVE_MODE:
+ wl12xx_debug(DEBUG_PSM, "entering psm");
+ ret = wl12xx_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_ps_set_elp(wl, true);
+ if (ret < 0)
+ return ret;
+
+ wl->psm = 1;
+ break;
+ case STATION_ACTIVE_MODE:
+ default:
+ wl12xx_debug(DEBUG_PSM, "leaving psm");
+ ret = wl12xx_ps_set_elp(wl, false);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
+ if (ret < 0)
+ return ret;
+
+ wl->psm = 0;
+ break;
+ }
+
+ return ret;
+}
+
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
new file mode 100644
index 000000000000..5d7c52553830
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -0,0 +1,36 @@
+#ifndef __WL12XX_PS_H__
+#define __WL12XX_PS_H__
+
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include "wl12xx.h"
+#include "acx.h"
+
+int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode);
+void wl12xx_ps_elp_sleep(struct wl12xx *wl);
+int wl12xx_ps_elp_wakeup(struct wl12xx *wl);
+
+
+#endif /* __WL12XX_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/wl12xx/reg.h
new file mode 100644
index 000000000000..e421643215cd
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/reg.h
@@ -0,0 +1,745 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __REG_H__
+#define __REG_H__
+
+#include <linux/bitops.h>
+#include "wl12xx.h"
+
+#define REGISTERS_BASE 0x00300000
+#define DRPW_BASE 0x00310000
+
+#define REGISTERS_DOWN_SIZE 0x00008800
+#define REGISTERS_WORK_SIZE 0x0000b000
+
+#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC
+
+/* ELP register commands */
+#define ELPCTRL_WAKE_UP 0x1
+#define ELPCTRL_WAKE_UP_WLAN_READY 0x5
+#define ELPCTRL_SLEEP 0x0
+/* ELP WLAN_READY bit */
+#define ELPCTRL_WLAN_READY 0x2
+
+/*
+ * Interrupt registers.
+ * 64 bit interrupt sources registers ws ced.
+ * sme interupts were removed and new ones were added.
+ * Order was changed.
+ */
+#define FIQ_MASK (REGISTERS_BASE + 0x0400)
+#define FIQ_MASK_L (REGISTERS_BASE + 0x0400)
+#define FIQ_MASK_H (REGISTERS_BASE + 0x0404)
+#define FIQ_MASK_SET (REGISTERS_BASE + 0x0408)
+#define FIQ_MASK_SET_L (REGISTERS_BASE + 0x0408)
+#define FIQ_MASK_SET_H (REGISTERS_BASE + 0x040C)
+#define FIQ_MASK_CLR (REGISTERS_BASE + 0x0410)
+#define FIQ_MASK_CLR_L (REGISTERS_BASE + 0x0410)
+#define FIQ_MASK_CLR_H (REGISTERS_BASE + 0x0414)
+#define IRQ_MASK (REGISTERS_BASE + 0x0418)
+#define IRQ_MASK_L (REGISTERS_BASE + 0x0418)
+#define IRQ_MASK_H (REGISTERS_BASE + 0x041C)
+#define IRQ_MASK_SET (REGISTERS_BASE + 0x0420)
+#define IRQ_MASK_SET_L (REGISTERS_BASE + 0x0420)
+#define IRQ_MASK_SET_H (REGISTERS_BASE + 0x0424)
+#define IRQ_MASK_CLR (REGISTERS_BASE + 0x0428)
+#define IRQ_MASK_CLR_L (REGISTERS_BASE + 0x0428)
+#define IRQ_MASK_CLR_H (REGISTERS_BASE + 0x042C)
+#define ECPU_MASK (REGISTERS_BASE + 0x0448)
+#define FIQ_STS_L (REGISTERS_BASE + 0x044C)
+#define FIQ_STS_H (REGISTERS_BASE + 0x0450)
+#define IRQ_STS_L (REGISTERS_BASE + 0x0454)
+#define IRQ_STS_H (REGISTERS_BASE + 0x0458)
+#define INT_STS_ND (REGISTERS_BASE + 0x0464)
+#define INT_STS_RAW_L (REGISTERS_BASE + 0x0464)
+#define INT_STS_RAW_H (REGISTERS_BASE + 0x0468)
+#define INT_STS_CLR (REGISTERS_BASE + 0x04B4)
+#define INT_STS_CLR_L (REGISTERS_BASE + 0x04B4)
+#define INT_STS_CLR_H (REGISTERS_BASE + 0x04B8)
+#define INT_ACK (REGISTERS_BASE + 0x046C)
+#define INT_ACK_L (REGISTERS_BASE + 0x046C)
+#define INT_ACK_H (REGISTERS_BASE + 0x0470)
+#define INT_TRIG (REGISTERS_BASE + 0x0474)
+#define INT_TRIG_L (REGISTERS_BASE + 0x0474)
+#define INT_TRIG_H (REGISTERS_BASE + 0x0478)
+#define HOST_STS_L (REGISTERS_BASE + 0x045C)
+#define HOST_STS_H (REGISTERS_BASE + 0x0460)
+#define HOST_MASK (REGISTERS_BASE + 0x0430)
+#define HOST_MASK_L (REGISTERS_BASE + 0x0430)
+#define HOST_MASK_H (REGISTERS_BASE + 0x0434)
+#define HOST_MASK_SET (REGISTERS_BASE + 0x0438)
+#define HOST_MASK_SET_L (REGISTERS_BASE + 0x0438)
+#define HOST_MASK_SET_H (REGISTERS_BASE + 0x043C)
+#define HOST_MASK_CLR (REGISTERS_BASE + 0x0440)
+#define HOST_MASK_CLR_L (REGISTERS_BASE + 0x0440)
+#define HOST_MASK_CLR_H (REGISTERS_BASE + 0x0444)
+
+/* Host Interrupts*/
+#define HINT_MASK (REGISTERS_BASE + 0x0494)
+#define HINT_MASK_SET (REGISTERS_BASE + 0x0498)
+#define HINT_MASK_CLR (REGISTERS_BASE + 0x049C)
+#define HINT_STS_ND_MASKED (REGISTERS_BASE + 0x04A0)
+/*1150 spec calls this HINT_STS_RAW*/
+#define HINT_STS_ND (REGISTERS_BASE + 0x04B0)
+#define HINT_STS_CLR (REGISTERS_BASE + 0x04A4)
+#define HINT_ACK (REGISTERS_BASE + 0x04A8)
+#define HINT_TRIG (REGISTERS_BASE + 0x04AC)
+
+/* Device Configuration registers*/
+#define SOR_CFG (REGISTERS_BASE + 0x0800)
+#define ECPU_CTRL (REGISTERS_BASE + 0x0804)
+#define HI_CFG (REGISTERS_BASE + 0x0808)
+#define EE_START (REGISTERS_BASE + 0x080C)
+
+#define CHIP_ID_B (REGISTERS_BASE + 0x5674)
+
+#define CHIP_ID_1251_PG10 (0x7010101)
+#define CHIP_ID_1251_PG11 (0x7020101)
+#define CHIP_ID_1251_PG12 (0x7030101)
+
+#define ENABLE (REGISTERS_BASE + 0x5450)
+
+/* Power Management registers */
+#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804)
+#define ELP_CMD (REGISTERS_BASE + 0x5808)
+#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810)
+#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814)
+#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818)
+
+#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820)
+
+/* Scratch Pad registers*/
+#define SCR_PAD0 (REGISTERS_BASE + 0x5608)
+#define SCR_PAD1 (REGISTERS_BASE + 0x560C)
+#define SCR_PAD2 (REGISTERS_BASE + 0x5610)
+#define SCR_PAD3 (REGISTERS_BASE + 0x5614)
+#define SCR_PAD4 (REGISTERS_BASE + 0x5618)
+#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C)
+#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620)
+#define SCR_PAD5 (REGISTERS_BASE + 0x5624)
+#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628)
+#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C)
+#define SCR_PAD6 (REGISTERS_BASE + 0x5630)
+#define SCR_PAD7 (REGISTERS_BASE + 0x5634)
+#define SCR_PAD8 (REGISTERS_BASE + 0x5638)
+#define SCR_PAD9 (REGISTERS_BASE + 0x563C)
+
+/* Spare registers*/
+#define SPARE_A1 (REGISTERS_BASE + 0x0994)
+#define SPARE_A2 (REGISTERS_BASE + 0x0998)
+#define SPARE_A3 (REGISTERS_BASE + 0x099C)
+#define SPARE_A4 (REGISTERS_BASE + 0x09A0)
+#define SPARE_A5 (REGISTERS_BASE + 0x09A4)
+#define SPARE_A6 (REGISTERS_BASE + 0x09A8)
+#define SPARE_A7 (REGISTERS_BASE + 0x09AC)
+#define SPARE_A8 (REGISTERS_BASE + 0x09B0)
+#define SPARE_B1 (REGISTERS_BASE + 0x5420)
+#define SPARE_B2 (REGISTERS_BASE + 0x5424)
+#define SPARE_B3 (REGISTERS_BASE + 0x5428)
+#define SPARE_B4 (REGISTERS_BASE + 0x542C)
+#define SPARE_B5 (REGISTERS_BASE + 0x5430)
+#define SPARE_B6 (REGISTERS_BASE + 0x5434)
+#define SPARE_B7 (REGISTERS_BASE + 0x5438)
+#define SPARE_B8 (REGISTERS_BASE + 0x543C)
+
+enum wl12xx_acx_int_reg {
+ ACX_REG_INTERRUPT_TRIG,
+ ACX_REG_INTERRUPT_TRIG_H,
+
+/*=============================================
+ Host Interrupt Mask Register - 32bit (RW)
+ ------------------------------------------
+ Setting a bit in this register masks the
+ corresponding interrupt to the host.
+ 0 - RX0 - Rx first dubble buffer Data Interrupt
+ 1 - TXD - Tx Data Interrupt
+ 2 - TXXFR - Tx Transfer Interrupt
+ 3 - RX1 - Rx second dubble buffer Data Interrupt
+ 4 - RXXFR - Rx Transfer Interrupt
+ 5 - EVENT_A - Event Mailbox interrupt
+ 6 - EVENT_B - Event Mailbox interrupt
+ 7 - WNONHST - Wake On Host Interrupt
+ 8 - TRACE_A - Debug Trace interrupt
+ 9 - TRACE_B - Debug Trace interrupt
+ 10 - CDCMP - Command Complete Interrupt
+ 11 -
+ 12 -
+ 13 -
+ 14 - ICOMP - Initialization Complete Interrupt
+ 16 - SG SE - Soft Gemini - Sense enable interrupt
+ 17 - SG SD - Soft Gemini - Sense disable interrupt
+ 18 - -
+ 19 - -
+ 20 - -
+ 21- -
+ Default: 0x0001
+*==============================================*/
+ ACX_REG_INTERRUPT_MASK,
+
+/*=============================================
+ Host Interrupt Mask Set 16bit, (Write only)
+ ------------------------------------------
+ Setting a bit in this register sets
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+==============================================*/
+ ACX_REG_HINT_MASK_SET,
+
+/*=============================================
+ Host Interrupt Mask Clear 16bit,(Write only)
+ ------------------------------------------
+ Setting a bit in this register clears
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+=============================================*/
+ ACX_REG_HINT_MASK_CLR,
+
+/*=============================================
+ Host Interrupt Status Nondestructive Read
+ 16bit,(Read only)
+ ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register doesn't
+ effect its content.
+=============================================*/
+ ACX_REG_INTERRUPT_NO_CLEAR,
+
+/*=============================================
+ Host Interrupt Status Clear on Read Register
+ 16bit,(Read only)
+ ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register clears it,
+ thus making all interrupts inactive.
+==============================================*/
+ ACX_REG_INTERRUPT_CLEAR,
+
+/*=============================================
+ Host Interrupt Acknowledge Register
+ 16bit,(Write only)
+ ------------------------------------------
+ The host can set individual bits in this
+ register to clear (acknowledge) the corresp.
+ interrupt status bits in the HINT_STS_CLR and
+ HINT_STS_ND registers, thus making the
+ assotiated interrupt inactive. (0-no effect)
+==============================================*/
+ ACX_REG_INTERRUPT_ACK,
+
+/*===============================================
+ Host Software Reset - 32bit RW
+ ------------------------------------------
+ [31:1] Reserved
+ 0 SOFT_RESET Soft Reset - When this bit is set,
+ it holds the Wlan hardware in a soft reset state.
+ This reset disables all MAC and baseband processor
+ clocks except the CardBus/PCI interface clock.
+ It also initializes all MAC state machines except
+ the host interface. It does not reload the
+ contents of the EEPROM. When this bit is cleared
+ (not self-clearing), the Wlan hardware
+ exits the software reset state.
+===============================================*/
+ ACX_REG_SLV_SOFT_RESET,
+
+/*===============================================
+ EEPROM Burst Read Start - 32bit RW
+ ------------------------------------------
+ [31:1] Reserved
+ 0 ACX_EE_START - EEPROM Burst Read Start 0
+ Setting this bit starts a burst read from
+ the external EEPROM.
+ If this bit is set (after reset) before an EEPROM read/write,
+ the burst read starts at EEPROM address 0.
+ Otherwise, it starts at the address
+ following the address of the previous access.
+ TheWlan hardware hardware clears this bit automatically.
+
+ Default: 0x00000000
+*================================================*/
+ ACX_REG_EE_START,
+
+/* Embedded ARM CPU Control */
+
+/*===============================================
+ Halt eCPU - 32bit RW
+ ------------------------------------------
+ 0 HALT_ECPU Halt Embedded CPU - This bit is the
+ compliment of bit 1 (MDATA2) in the SOR_CFG register.
+ During a hardware reset, this bit holds
+ the inverse of MDATA2.
+ When downloading firmware from the host,
+ set this bit (pull down MDATA2).
+ The host clears this bit after downloading the firmware into
+ zero-wait-state SSRAM.
+ When loading firmware from Flash, clear this bit (pull up MDATA2)
+ so that the eCPU can run the bootloader code in Flash
+ HALT_ECPU eCPU State
+ --------------------
+ 1 halt eCPU
+ 0 enable eCPU
+ ===============================================*/
+ ACX_REG_ECPU_CONTROL,
+
+ ACX_REG_TABLE_LEN
+};
+
+#define ACX_SLV_SOFT_RESET_BIT BIT(1)
+#define ACX_REG_EEPROM_START_BIT BIT(1)
+
+/* Command/Information Mailbox Pointers */
+
+/*===============================================
+ Command Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the command mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to
+ find the location of the command mailbox.
+ The Wlan hardware initializes the command mailbox
+ pointer with the default address of the command mailbox.
+ The command mailbox pointer is not valid until after
+ the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0)
+
+/*===============================================
+ Information Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the information mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to find
+ the location of the information mailbox.
+ The Wlan hardware initializes the information mailbox pointer
+ with the default address of the information mailbox.
+ The information mailbox pointer is not valid
+ until after the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_EVENT_MAILBOX_PTR (SCR_PAD1)
+
+
+/* Misc */
+
+#define REG_ENABLE_TX_RX (ENABLE)
+/*
+ * Rx configuration (filter) information element
+ * ---------------------------------------------
+ */
+#define REG_RX_CONFIG (RX_CFG)
+#define REG_RX_FILTER (RX_FILTER_CFG)
+
+
+#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002
+
+/* promiscuous - receives all valid frames */
+#define RX_CFG_PROMISCUOUS 0x0008
+
+/* receives frames from any BSSID */
+#define RX_CFG_BSSID 0x0020
+
+/* receives frames destined to any MAC address */
+#define RX_CFG_MAC 0x0010
+
+#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010
+#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000
+#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020
+#define RX_CFG_ENABLE_ANY_BSSID 0x0000
+
+/* discards all broadcast frames */
+#define RX_CFG_DISABLE_BCAST 0x0200
+
+#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400
+#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
+#define RX_CFG_COPY_RX_STATUS 0x2000
+#define RX_CFG_TSF 0x10000
+
+#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
+ RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+ | RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
+ RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+ | RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \
+ | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
+ | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
+
+#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \
+ RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \
+ RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_FILTER_OPTION_DEF (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+ | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
+ | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
+
+#define RX_FILTER_OPTION_FILTER_ALL 0
+
+#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
+ | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
+
+#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+ | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
+ | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
+ | CFG_RX_PRSP_EN)
+
+
+/*===============================================
+ Phy regs
+ ===============================================*/
+#define ACX_PHY_ADDR_REG SBB_ADDR
+#define ACX_PHY_DATA_REG SBB_DATA
+#define ACX_PHY_CTRL_REG SBB_CTL
+#define ACX_PHY_REG_WR_MASK 0x00000001ul
+#define ACX_PHY_REG_RD_MASK 0x00000002ul
+
+
+/*===============================================
+ EEPROM Read/Write Request 32bit RW
+ ------------------------------------------
+ 1 EE_READ - EEPROM Read Request 1 - Setting this bit
+ loads a single byte of data into the EE_DATA
+ register from the EEPROM location specified in
+ the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+ EE_DATA is valid when this bit is cleared.
+
+ 0 EE_WRITE - EEPROM Write Request - Setting this bit
+ writes a single byte of data from the EE_DATA register into the
+ EEPROM location specified in the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+*===============================================*/
+#define ACX_EE_CTL_REG EE_CTL
+#define EE_WRITE 0x00000001ul
+#define EE_READ 0x00000002ul
+
+/*===============================================
+ EEPROM Address - 32bit RW
+ ------------------------------------------
+ This register specifies the address
+ within the EEPROM from/to which to read/write data.
+ ===============================================*/
+#define ACX_EE_ADDR_REG EE_ADDR
+
+/*===============================================
+ EEPROM Data - 32bit RW
+ ------------------------------------------
+ This register either holds the read 8 bits of
+ data from the EEPROM or the write data
+ to be written to the EEPROM.
+ ===============================================*/
+#define ACX_EE_DATA_REG EE_DATA
+
+/*===============================================
+ EEPROM Base Address - 32bit RW
+ ------------------------------------------
+ This register holds the upper nine bits
+ [23:15] of the 24-bit Wlan hardware memory
+ address for burst reads from EEPROM accesses.
+ The EEPROM provides the lower 15 bits of this address.
+ The MSB of the address from the EEPROM is ignored.
+ ===============================================*/
+#define ACX_EE_CFG EE_CFG
+
+/*===============================================
+ GPIO Output Values -32bit, RW
+ ------------------------------------------
+ [31:16] Reserved
+ [15: 0] Specify the output values (at the output driver inputs) for
+ GPIO[15:0], respectively.
+ ===============================================*/
+#define ACX_GPIO_OUT_REG GPIO_OUT
+#define ACX_MAX_GPIO_LINES 15
+
+/*===============================================
+ Contention window -32bit, RW
+ ------------------------------------------
+ [31:26] Reserved
+ [25:16] Max (0x3ff)
+ [15:07] Reserved
+ [06:00] Current contention window value - default is 0x1F
+ ===============================================*/
+#define ACX_CONT_WIND_CFG_REG CONT_WIND_CFG
+#define ACX_CONT_WIND_MIN_MASK 0x0000007f
+#define ACX_CONT_WIND_MAX 0x03ff0000
+
+/*
+ * Indirect slave register/memory registers
+ * ----------------------------------------
+ */
+#define HW_SLAVE_REG_ADDR_REG 0x00000004
+#define HW_SLAVE_REG_DATA_REG 0x00000008
+#define HW_SLAVE_REG_CTRL_REG 0x0000000c
+
+#define SLAVE_AUTO_INC 0x00010000
+#define SLAVE_NO_AUTO_INC 0x00000000
+#define SLAVE_HOST_LITTLE_ENDIAN 0x00000000
+
+#define HW_SLAVE_MEM_ADDR_REG SLV_MEM_ADDR
+#define HW_SLAVE_MEM_DATA_REG SLV_MEM_DATA
+#define HW_SLAVE_MEM_CTRL_REG SLV_MEM_CTL
+#define HW_SLAVE_MEM_ENDIAN_REG SLV_END_CTL
+
+#define HW_FUNC_EVENT_INT_EN 0x8000
+#define HW_FUNC_EVENT_MASK_REG 0x00000034
+
+#define ACX_MAC_TIMESTAMP_REG (MAC_TIMESTAMP)
+
+/*===============================================
+ HI_CFG Interface Configuration Register Values
+ ------------------------------------------
+ ===============================================*/
+#define HI_CFG_UART_ENABLE 0x00000004
+#define HI_CFG_RST232_ENABLE 0x00000008
+#define HI_CFG_CLOCK_REQ_SELECT 0x00000010
+#define HI_CFG_HOST_INT_ENABLE 0x00000020
+#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040
+#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080
+#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100
+#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
+#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
+
+/*
+ * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
+ * for platforms using active high interrupt level
+ */
+#ifdef USE_ACTIVE_HIGH
+#define HI_CFG_DEF_VAL \
+ (HI_CFG_UART_ENABLE | \
+ HI_CFG_RST232_ENABLE | \
+ HI_CFG_CLOCK_REQ_SELECT | \
+ HI_CFG_HOST_INT_ENABLE)
+#else
+#define HI_CFG_DEF_VAL \
+ (HI_CFG_UART_ENABLE | \
+ HI_CFG_RST232_ENABLE | \
+ HI_CFG_CLOCK_REQ_SELECT | \
+ HI_CFG_HOST_INT_ENABLE)
+
+#endif
+
+#define REF_FREQ_19_2 0
+#define REF_FREQ_26_0 1
+#define REF_FREQ_38_4 2
+#define REF_FREQ_40_0 3
+#define REF_FREQ_33_6 4
+#define REF_FREQ_NUM 5
+
+#define LUT_PARAM_INTEGER_DIVIDER 0
+#define LUT_PARAM_FRACTIONAL_DIVIDER 1
+#define LUT_PARAM_ATTN_BB 2
+#define LUT_PARAM_ALPHA_BB 3
+#define LUT_PARAM_STOP_TIME_BB 4
+#define LUT_PARAM_BB_PLL_LOOP_FILTER 5
+#define LUT_PARAM_NUM 6
+
+#define ACX_EEPROMLESS_IND_REG (SCR_PAD4)
+#define USE_EEPROM 0
+#define SOFT_RESET_MAX_TIME 1000000
+#define SOFT_RESET_STALL_TIME 1000
+#define NVS_DATA_BUNDARY_ALIGNMENT 4
+
+
+/* Firmware image load chunk size */
+#define CHUNK_SIZE 512
+
+/* Firmware image header size */
+#define FW_HDR_SIZE 8
+
+#define ECPU_CONTROL_HALT 0x00000101
+
+
+/******************************************************************************
+
+ CHANNELS, BAND & REG DOMAINS definitions
+
+******************************************************************************/
+
+
+enum {
+ RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */
+ RADIO_BAND_5GHZ = 1, /* 5 Ghz band */
+ RADIO_BAND_JAPAN_4_9_GHZ = 2,
+ DEFAULT_BAND = RADIO_BAND_2_4GHZ,
+ INVALID_BAND = 0xFE,
+ MAX_RADIO_BANDS = 0xFF
+};
+
+enum {
+ NO_RATE = 0,
+ RATE_1MBPS = 0x0A,
+ RATE_2MBPS = 0x14,
+ RATE_5_5MBPS = 0x37,
+ RATE_6MBPS = 0x0B,
+ RATE_9MBPS = 0x0F,
+ RATE_11MBPS = 0x6E,
+ RATE_12MBPS = 0x0A,
+ RATE_18MBPS = 0x0E,
+ RATE_22MBPS = 0xDC,
+ RATE_24MBPS = 0x09,
+ RATE_36MBPS = 0x0D,
+ RATE_48MBPS = 0x08,
+ RATE_54MBPS = 0x0C
+};
+
+enum {
+ RATE_INDEX_1MBPS = 0,
+ RATE_INDEX_2MBPS = 1,
+ RATE_INDEX_5_5MBPS = 2,
+ RATE_INDEX_6MBPS = 3,
+ RATE_INDEX_9MBPS = 4,
+ RATE_INDEX_11MBPS = 5,
+ RATE_INDEX_12MBPS = 6,
+ RATE_INDEX_18MBPS = 7,
+ RATE_INDEX_22MBPS = 8,
+ RATE_INDEX_24MBPS = 9,
+ RATE_INDEX_36MBPS = 10,
+ RATE_INDEX_48MBPS = 11,
+ RATE_INDEX_54MBPS = 12,
+ RATE_INDEX_MAX = RATE_INDEX_54MBPS,
+ MAX_RATE_INDEX,
+ INVALID_RATE_INDEX = MAX_RATE_INDEX,
+ RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
+};
+
+enum {
+ RATE_MASK_1MBPS = 0x1,
+ RATE_MASK_2MBPS = 0x2,
+ RATE_MASK_5_5MBPS = 0x4,
+ RATE_MASK_11MBPS = 0x20,
+};
+
+#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */
+#define OFDM_RATE_BIT BIT(6)
+#define PBCC_RATE_BIT BIT(7)
+
+enum {
+ CCK_LONG = 0,
+ CCK_SHORT = SHORT_PREAMBLE_BIT,
+ PBCC_LONG = PBCC_RATE_BIT,
+ PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
+ OFDM = OFDM_RATE_BIT
+};
+
+/******************************************************************************
+
+Transmit-Descriptor RATE-SET field definitions...
+
+Define a new "Rate-Set" for TX path that incorporates the
+Rate & Modulation info into a single 16-bit field.
+
+TxdRateSet_t:
+b15 - Indicates Preamble type (1=SHORT, 0=LONG).
+ Notes:
+ Must be LONG (0) for 1Mbps rate.
+ Does not apply (set to 0) for RevG-OFDM rates.
+b14 - Indicates PBCC encoding (1=PBCC, 0=not).
+ Notes:
+ Does not apply (set to 0) for rates 1 and 2 Mbps.
+ Does not apply (set to 0) for RevG-OFDM rates.
+b13 - Unused (set to 0).
+b12-b0 - Supported Rate indicator bits as defined below.
+
+******************************************************************************/
+
+
+#define TNETW1251_CHIP_ID_PG1_0 0x07010101
+#define TNETW1251_CHIP_ID_PG1_1 0x07020101
+#define TNETW1251_CHIP_ID_PG1_2 0x07030101
+
+/*************************************************************************
+
+ Interrupt Trigger Register (Host -> WiLink)
+
+**************************************************************************/
+
+/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
+
+/*
+ * Host Command Interrupt. Setting this bit masks
+ * the interrupt that the host issues to inform
+ * the FW that it has sent a command
+ * to the Wlan hardware Command Mailbox.
+ */
+#define INTR_TRIG_CMD BIT(0)
+
+/*
+ * Host Event Acknowlegde Interrupt. The host
+ * sets this bit to acknowledge that it received
+ * the unsolicited information from the event
+ * mailbox.
+ */
+#define INTR_TRIG_EVENT_ACK BIT(1)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * FW that a TX packet is in the XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_TX_PROC0 BIT(2)
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_RX_PROC0 BIT(3)
+
+#define INTR_TRIG_DEBUG_ACK BIT(4)
+
+#define INTR_TRIG_STATE_CHANGED BIT(5)
+
+
+/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_RX_PROC1 BIT(17)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * hardware that a TX packet is in the XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_TX_PROC1 BIT(18)
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
new file mode 100644
index 000000000000..981ea259eb89
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -0,0 +1,208 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include <linux/skbuff.h>
+#include <net/mac80211.h>
+
+#include "wl12xx.h"
+#include "reg.h"
+#include "spi.h"
+#include "rx.h"
+
+static void wl12xx_rx_header(struct wl12xx *wl,
+ struct wl12xx_rx_descriptor *desc)
+{
+ u32 rx_packet_ring_addr;
+
+ rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
+ if (wl->rx_current_buffer)
+ rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
+
+ wl12xx_spi_mem_read(wl, rx_packet_ring_addr, desc,
+ sizeof(struct wl12xx_rx_descriptor));
+}
+
+static void wl12xx_rx_status(struct wl12xx *wl,
+ struct wl12xx_rx_descriptor *desc,
+ struct ieee80211_rx_status *status,
+ u8 beacon)
+{
+ memset(status, 0, sizeof(struct ieee80211_rx_status));
+
+ status->band = IEEE80211_BAND_2GHZ;
+ status->mactime = desc->timestamp;
+
+ /*
+ * The rx status timestamp is a 32 bits value while the TSF is a
+ * 64 bits one.
+ * For IBSS merging, TSF is mandatory, so we have to get it
+ * somehow, so we ask for ACX_TSF_INFO.
+ * That could be moved to the get_tsf() hook, but unfortunately,
+ * this one must be atomic, while our SPI routines can sleep.
+ */
+ if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
+ u64 mactime;
+ int ret;
+ struct wl12xx_command cmd;
+ struct acx_tsf_info *tsf_info;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ ret = wl12xx_cmd_interrogate(wl, ACX_TSF_INFO,
+ sizeof(struct acx_tsf_info),
+ &cmd);
+ if (ret < 0) {
+ wl12xx_warning("ACX_FW_REV interrogate failed");
+ return;
+ }
+
+ tsf_info = (struct acx_tsf_info *)&(cmd.parameters);
+
+ mactime = tsf_info->current_tsf_lsb |
+ (tsf_info->current_tsf_msb << 31);
+
+ status->mactime = mactime;
+ }
+
+ status->signal = desc->rssi;
+ status->qual = (desc->rssi - WL12XX_RX_MIN_RSSI) * 100 /
+ (WL12XX_RX_MAX_RSSI - WL12XX_RX_MIN_RSSI);
+ status->qual = min(status->qual, 100);
+ status->qual = max(status->qual, 0);
+
+ /*
+ * FIXME: guessing that snr needs to be divided by two, otherwise
+ * the values don't make any sense
+ */
+ status->noise = desc->rssi - desc->snr / 2;
+
+ status->freq = ieee80211_channel_to_frequency(desc->channel);
+
+ status->flag |= RX_FLAG_TSFT;
+
+ if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
+ status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
+
+ if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
+ status->flag |= RX_FLAG_DECRYPTED;
+
+ if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
+ status->flag |= RX_FLAG_MMIC_ERROR;
+ }
+
+ if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
+ status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+
+ /* FIXME: set status->rate_idx */
+}
+
+static void wl12xx_rx_body(struct wl12xx *wl,
+ struct wl12xx_rx_descriptor *desc)
+{
+ struct sk_buff *skb;
+ struct ieee80211_rx_status status;
+ u8 *rx_buffer, beacon = 0;
+ u16 length, *fc;
+ u32 curr_id, last_id_inc, rx_packet_ring_addr;
+
+ length = WL12XX_RX_ALIGN(desc->length - PLCP_HEADER_LENGTH);
+ curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
+ last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
+
+ if (last_id_inc != curr_id) {
+ wl12xx_warning("curr ID:%d, last ID inc:%d",
+ curr_id, last_id_inc);
+ wl->rx_last_id = curr_id;
+ } else {
+ wl->rx_last_id = last_id_inc;
+ }
+
+ rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
+ sizeof(struct wl12xx_rx_descriptor) + 20;
+ if (wl->rx_current_buffer)
+ rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
+
+ skb = dev_alloc_skb(length);
+ if (!skb) {
+ wl12xx_error("Couldn't allocate RX frame");
+ return;
+ }
+
+ rx_buffer = skb_put(skb, length);
+ wl12xx_spi_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
+
+ /* The actual lenght doesn't include the target's alignment */
+ skb->len = desc->length - PLCP_HEADER_LENGTH;
+
+ fc = (u16 *)skb->data;
+
+ if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
+ beacon = 1;
+
+ wl12xx_rx_status(wl, desc, &status, beacon);
+
+ wl12xx_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
+ beacon ? "beacon" : "");
+
+ ieee80211_rx(wl->hw, skb, &status);
+}
+
+static void wl12xx_rx_ack(struct wl12xx *wl)
+{
+ u32 data, addr;
+
+ if (wl->rx_current_buffer) {
+ addr = ACX_REG_INTERRUPT_TRIG_H;
+ data = INTR_TRIG_RX_PROC1;
+ } else {
+ addr = ACX_REG_INTERRUPT_TRIG;
+ data = INTR_TRIG_RX_PROC0;
+ }
+
+ wl12xx_reg_write32(wl, addr, data);
+
+ /* Toggle buffer ring */
+ wl->rx_current_buffer = !wl->rx_current_buffer;
+}
+
+
+void wl12xx_rx(struct wl12xx *wl)
+{
+ struct wl12xx_rx_descriptor rx_desc;
+
+ if (wl->state != WL12XX_STATE_ON)
+ return;
+
+ /* We first read the frame's header */
+ wl12xx_rx_header(wl, &rx_desc);
+
+ /* Now we can read the body */
+ wl12xx_rx_body(wl, &rx_desc);
+
+ /* Finally, we need to ACK the RX */
+ wl12xx_rx_ack(wl);
+
+ return;
+}
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h
new file mode 100644
index 000000000000..8a23fdea5016
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/rx.h
@@ -0,0 +1,122 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __WL12XX_RX_H__
+#define __WL12XX_RX_H__
+
+#include <linux/bitops.h>
+
+/*
+ * RX PATH
+ *
+ * The Rx path uses a double buffer and an rx_contro structure, each located
+ * at a fixed address in the device memory. The host keeps track of which
+ * buffer is available and alternates between them on a per packet basis.
+ * The size of each of the two buffers is large enough to hold the longest
+ * 802.3 packet.
+ * The RX path goes like that:
+ * 1) The target generates an interrupt each time a new packet is received.
+ * There are 2 RX interrupts, one for each buffer.
+ * 2) The host reads the received packet from one of the double buffers.
+ * 3) The host triggers a target interrupt.
+ * 4) The target prepares the next RX packet.
+ */
+
+#define WL12XX_RX_MAX_RSSI -30
+#define WL12XX_RX_MIN_RSSI -95
+
+#define WL12XX_RX_ALIGN_TO 4
+#define WL12XX_RX_ALIGN(len) (((len) + WL12XX_RX_ALIGN_TO - 1) & \
+ ~(WL12XX_RX_ALIGN_TO - 1))
+
+#define SHORT_PREAMBLE_BIT BIT(0)
+#define OFDM_RATE_BIT BIT(6)
+#define PBCC_RATE_BIT BIT(7)
+
+#define PLCP_HEADER_LENGTH 8
+#define RX_DESC_PACKETID_SHIFT 11
+#define RX_MAX_PACKET_ID 3
+
+#define RX_DESC_VALID_FCS 0x0001
+#define RX_DESC_MATCH_RXADDR1 0x0002
+#define RX_DESC_MCAST 0x0004
+#define RX_DESC_STAINTIM 0x0008
+#define RX_DESC_VIRTUAL_BM 0x0010
+#define RX_DESC_BCAST 0x0020
+#define RX_DESC_MATCH_SSID 0x0040
+#define RX_DESC_MATCH_BSSID 0x0080
+#define RX_DESC_ENCRYPTION_MASK 0x0300
+#define RX_DESC_MEASURMENT 0x0400
+#define RX_DESC_SEQNUM_MASK 0x1800
+#define RX_DESC_MIC_FAIL 0x2000
+#define RX_DESC_DECRYPT_FAIL 0x4000
+
+struct wl12xx_rx_descriptor {
+ u32 timestamp; /* In microseconds */
+ u16 length; /* Paylod length, including headers */
+ u16 flags;
+
+ /*
+ * 0 - 802.11
+ * 1 - 802.3
+ * 2 - IP
+ * 3 - Raw Codec
+ */
+ u8 type;
+
+ /*
+ * Recevied Rate:
+ * 0x0A - 1MBPS
+ * 0x14 - 2MBPS
+ * 0x37 - 5_5MBPS
+ * 0x0B - 6MBPS
+ * 0x0F - 9MBPS
+ * 0x6E - 11MBPS
+ * 0x0A - 12MBPS
+ * 0x0E - 18MBPS
+ * 0xDC - 22MBPS
+ * 0x09 - 24MBPS
+ * 0x0D - 36MBPS
+ * 0x08 - 48MBPS
+ * 0x0C - 54MBPS
+ */
+ u8 rate;
+
+ u8 mod_pre; /* Modulation and preamble */
+ u8 channel;
+
+ /*
+ * 0 - 2.4 Ghz
+ * 1 - 5 Ghz
+ */
+ u8 band;
+
+ s8 rssi; /* in dB */
+ u8 rcpi; /* in dB */
+ u8 snr; /* in dB */
+} __attribute__ ((packed));
+
+void wl12xx_rx(struct wl12xx *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c
new file mode 100644
index 000000000000..abdf171a47e7
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/spi.c
@@ -0,0 +1,358 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "spi.h"
+#include "ps.h"
+
+static int wl12xx_translate_reg_addr(struct wl12xx *wl, int addr)
+{
+ /* If the address is lower than REGISTERS_BASE, it means that this is
+ * a chip-specific register address, so look it up in the registers
+ * table */
+ if (addr < REGISTERS_BASE) {
+ /* Make sure we don't go over the table */
+ if (addr >= ACX_REG_TABLE_LEN) {
+ wl12xx_error("address out of range (%d)", addr);
+ return -EINVAL;
+ }
+ addr = wl->chip.acx_reg_table[addr];
+ }
+
+ return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
+}
+
+static int wl12xx_translate_mem_addr(struct wl12xx *wl, int addr)
+{
+ return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
+}
+
+
+void wl12xx_spi_reset(struct wl12xx *wl)
+{
+ u8 *cmd;
+ struct spi_transfer t;
+ struct spi_message m;
+
+ cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+ if (!cmd) {
+ wl12xx_error("could not allocate cmd for spi reset");
+ return;
+ }
+
+ memset(&t, 0, sizeof(t));
+ spi_message_init(&m);
+
+ memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
+
+ t.tx_buf = cmd;
+ t.len = WSPI_INIT_CMD_LEN;
+ spi_message_add_tail(&t, &m);
+
+ spi_sync(wl->spi, &m);
+
+ wl12xx_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+void wl12xx_spi_init(struct wl12xx *wl)
+{
+ u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
+ struct spi_transfer t;
+ struct spi_message m;
+
+ cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+ if (!cmd) {
+ wl12xx_error("could not allocate cmd for spi init");
+ return;
+ }
+
+ memset(crc, 0, sizeof(crc));
+ memset(&t, 0, sizeof(t));
+ spi_message_init(&m);
+
+ /*
+ * Set WSPI_INIT_COMMAND
+ * the data is being send from the MSB to LSB
+ */
+ cmd[2] = 0xff;
+ cmd[3] = 0xff;
+ cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
+ cmd[0] = 0;
+ cmd[7] = 0;
+ cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
+ cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
+
+ if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
+ cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
+ else
+ cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
+
+ cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
+ | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
+
+ crc[0] = cmd[1];
+ crc[1] = cmd[0];
+ crc[2] = cmd[7];
+ crc[3] = cmd[6];
+ crc[4] = cmd[5];
+
+ cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
+ cmd[4] |= WSPI_INIT_CMD_END;
+
+ t.tx_buf = cmd;
+ t.len = WSPI_INIT_CMD_LEN;
+ spi_message_add_tail(&t, &m);
+
+ spi_sync(wl->spi, &m);
+
+ wl12xx_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+/* Set the SPI partitions to access the chip addresses
+ *
+ * There are two VIRTUAL (SPI) partitions (the memory partition and the
+ * registers partition), which are mapped to two different areas of the
+ * PHYSICAL (hardware) memory. This function also makes other checks to
+ * ensure that the partitions are not overlapping. In the diagram below, the
+ * memory partition comes before the register partition, but the opposite is
+ * also supported.
+ *
+ * PHYSICAL address
+ * space
+ *
+ * | |
+ * ...+----+--> mem_start
+ * VIRTUAL address ... | |
+ * space ... | | [PART_0]
+ * ... | |
+ * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size
+ * | | ... | |
+ * |MEM | ... | |
+ * | | ... | |
+ * part_size <--+----+... | | {unused area)
+ * | | ... | |
+ * |REG | ... | |
+ * part_size | | ... | |
+ * + <--+----+... ...+----+--> reg_start
+ * reg_size ... | |
+ * ... | | [PART_1]
+ * ... | |
+ * ...+----+--> reg_start + reg_size
+ * | |
+ *
+ */
+void wl12xx_set_partition(struct wl12xx *wl,
+ u32 mem_start, u32 mem_size,
+ u32 reg_start, u32 reg_size)
+{
+ u8 tx_buf[sizeof(u32) + 2 * sizeof(struct wl12xx_partition)];
+ struct wl12xx_partition *partition;
+ struct spi_transfer t;
+ struct spi_message m;
+ u32 *cmd;
+ size_t len;
+ int addr;
+
+ spi_message_init(&m);
+ memset(&t, 0, sizeof(t));
+ memset(tx_buf, 0, sizeof(tx_buf));
+
+ cmd = (u32 *) tx_buf;
+ partition = (struct wl12xx_partition *) (tx_buf + sizeof(u32));
+ addr = HW_ACCESS_PART0_SIZE_ADDR;
+ len = 2 * sizeof(struct wl12xx_partition);
+
+ *cmd |= WSPI_CMD_WRITE;
+ *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+ *cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+ wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+ mem_start, mem_size);
+ wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+ reg_start, reg_size);
+
+ /* Make sure that the two partitions together don't exceed the
+ * address range */
+ if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
+ wl12xx_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
+ " address range. Truncating partition[0].");
+ mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
+ wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+ mem_start, mem_size);
+ wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+ reg_start, reg_size);
+ }
+
+ if ((mem_start < reg_start) &&
+ ((mem_start + mem_size) > reg_start)) {
+ /* Guarantee that the memory partition doesn't overlap the
+ * registers partition */
+ wl12xx_debug(DEBUG_SPI, "End of partition[0] is "
+ "overlapping partition[1]. Adjusted.");
+ mem_size = reg_start - mem_start;
+ wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+ mem_start, mem_size);
+ wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+ reg_start, reg_size);
+ } else if ((reg_start < mem_start) &&
+ ((reg_start + reg_size) > mem_start)) {
+ /* Guarantee that the register partition doesn't overlap the
+ * memory partition */
+ wl12xx_debug(DEBUG_SPI, "End of partition[1] is"
+ " overlapping partition[0]. Adjusted.");
+ reg_size = mem_start - reg_start;
+ wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+ mem_start, mem_size);
+ wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+ reg_start, reg_size);
+ }
+
+ partition[0].start = mem_start;
+ partition[0].size = mem_size;
+ partition[1].start = reg_start;
+ partition[1].size = reg_size;
+
+ wl->physical_mem_addr = mem_start;
+ wl->physical_reg_addr = reg_start;
+
+ wl->virtual_mem_addr = 0;
+ wl->virtual_reg_addr = mem_size;
+
+ t.tx_buf = tx_buf;
+ t.len = sizeof(tx_buf);
+ spi_message_add_tail(&t, &m);
+
+ spi_sync(wl->spi, &m);
+}
+
+void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf,
+ size_t len)
+{
+ struct spi_transfer t[3];
+ struct spi_message m;
+ char busy_buf[TNETWIF_READ_OFFSET_BYTES];
+ u32 cmd;
+
+ cmd = 0;
+ cmd |= WSPI_CMD_READ;
+ cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+ cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &cmd;
+ t[0].len = 4;
+ spi_message_add_tail(&t[0], &m);
+
+ /* Busy and non busy words read */
+ t[1].rx_buf = busy_buf;
+ t[1].len = TNETWIF_READ_OFFSET_BYTES;
+ spi_message_add_tail(&t[1], &m);
+
+ t[2].rx_buf = buf;
+ t[2].len = len;
+ spi_message_add_tail(&t[2], &m);
+
+ spi_sync(wl->spi, &m);
+
+ /* FIXME: check busy words */
+
+ wl12xx_dump(DEBUG_SPI, "spi_read cmd -> ", &cmd, sizeof(cmd));
+ wl12xx_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
+}
+
+void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf,
+ size_t len)
+{
+ struct spi_transfer t[2];
+ struct spi_message m;
+ u32 cmd;
+
+ cmd = 0;
+ cmd |= WSPI_CMD_WRITE;
+ cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+ cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &cmd;
+ t[0].len = sizeof(cmd);
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].tx_buf = buf;
+ t[1].len = len;
+ spi_message_add_tail(&t[1], &m);
+
+ spi_sync(wl->spi, &m);
+
+ wl12xx_dump(DEBUG_SPI, "spi_write cmd -> ", &cmd, sizeof(cmd));
+ wl12xx_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
+}
+
+void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf,
+ size_t len)
+{
+ int physical;
+
+ physical = wl12xx_translate_mem_addr(wl, addr);
+
+ wl12xx_spi_read(wl, physical, buf, len);
+}
+
+void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf,
+ size_t len)
+{
+ int physical;
+
+ physical = wl12xx_translate_mem_addr(wl, addr);
+
+ wl12xx_spi_write(wl, physical, buf, len);
+}
+
+u32 wl12xx_mem_read32(struct wl12xx *wl, int addr)
+{
+ return wl12xx_read32(wl, wl12xx_translate_mem_addr(wl, addr));
+}
+
+void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val)
+{
+ wl12xx_write32(wl, wl12xx_translate_mem_addr(wl, addr), val);
+}
+
+u32 wl12xx_reg_read32(struct wl12xx *wl, int addr)
+{
+ return wl12xx_read32(wl, wl12xx_translate_reg_addr(wl, addr));
+}
+
+void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val)
+{
+ wl12xx_write32(wl, wl12xx_translate_reg_addr(wl, addr), val);
+}
diff --git a/drivers/net/wireless/wl12xx/spi.h b/drivers/net/wireless/wl12xx/spi.h
new file mode 100644
index 000000000000..fd3227e904a8
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/spi.h
@@ -0,0 +1,109 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __WL12XX_SPI_H__
+#define __WL12XX_SPI_H__
+
+#include "cmd.h"
+#include "acx.h"
+#include "reg.h"
+
+#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
+
+#define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0
+#define HW_ACCESS_PART0_START_ADDR 0x1FFC4
+#define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8
+#define HW_ACCESS_PART1_START_ADDR 0x1FFCC
+
+#define HW_ACCESS_REGISTER_SIZE 4
+
+#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
+
+#define WSPI_CMD_READ 0x40000000
+#define WSPI_CMD_WRITE 0x00000000
+#define WSPI_CMD_FIXED 0x20000000
+#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
+#define WSPI_CMD_BYTE_LENGTH_OFFSET 17
+#define WSPI_CMD_BYTE_ADDR 0x0001FFFF
+
+#define WSPI_INIT_CMD_CRC_LEN 5
+
+#define WSPI_INIT_CMD_START 0x00
+#define WSPI_INIT_CMD_TX 0x40
+/* the extra bypass bit is sampled by the TNET as '1' */
+#define WSPI_INIT_CMD_BYPASS_BIT 0x80
+#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
+#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
+#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
+#define WSPI_INIT_CMD_IOD 0x40
+#define WSPI_INIT_CMD_IP 0x20
+#define WSPI_INIT_CMD_CS 0x10
+#define WSPI_INIT_CMD_WS 0x08
+#define WSPI_INIT_CMD_WSPI 0x01
+#define WSPI_INIT_CMD_END 0x01
+
+#define WSPI_INIT_CMD_LEN 8
+
+#define TNETWIF_READ_OFFSET_BYTES 8
+#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
+ ((TNETWIF_READ_OFFSET_BYTES - 4) / sizeof(u32))
+#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
+
+
+/* Raw target IO, address is not translated */
+void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf, size_t len);
+void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf, size_t len);
+
+/* Memory target IO, address is tranlated to partition 0 */
+void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf, size_t len);
+void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf, size_t len);
+u32 wl12xx_mem_read32(struct wl12xx *wl, int addr);
+void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val);
+
+/* Registers IO */
+u32 wl12xx_reg_read32(struct wl12xx *wl, int addr);
+void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val);
+
+/* INIT and RESET words */
+void wl12xx_spi_reset(struct wl12xx *wl);
+void wl12xx_spi_init(struct wl12xx *wl);
+void wl12xx_set_partition(struct wl12xx *wl,
+ u32 part_start, u32 part_size,
+ u32 reg_start, u32 reg_size);
+
+static inline u32 wl12xx_read32(struct wl12xx *wl, int addr)
+{
+ u32 response;
+
+ wl12xx_spi_read(wl, addr, &response, sizeof(u32));
+
+ return response;
+}
+
+static inline void wl12xx_write32(struct wl12xx *wl, int addr, u32 val)
+{
+ wl12xx_spi_write(wl, addr, &val, sizeof(u32));
+}
+
+#endif /* __WL12XX_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
new file mode 100644
index 000000000000..62145e205a8c
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -0,0 +1,557 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "wl12xx.h"
+#include "reg.h"
+#include "spi.h"
+#include "tx.h"
+#include "ps.h"
+
+static bool wl12xx_tx_double_buffer_busy(struct wl12xx *wl, u32 data_out_count)
+{
+ int used, data_in_count;
+
+ data_in_count = wl->data_in_count;
+
+ if (data_in_count < data_out_count)
+ /* data_in_count has wrapped */
+ data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1;
+
+ used = data_in_count - data_out_count;
+
+ WARN_ON(used < 0);
+ WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM);
+
+ if (used >= DP_TX_PACKET_RING_CHUNK_NUM)
+ return true;
+ else
+ return false;
+}
+
+static int wl12xx_tx_path_status(struct wl12xx *wl)
+{
+ u32 status, addr, data_out_count;
+ bool busy;
+
+ addr = wl->data_path->tx_control_addr;
+ status = wl12xx_mem_read32(wl, addr);
+ data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK;
+ busy = wl12xx_tx_double_buffer_busy(wl, data_out_count);
+
+ if (busy)
+ return -EBUSY;
+
+ return 0;
+}
+
+static int wl12xx_tx_id(struct wl12xx *wl, struct sk_buff *skb)
+{
+ int i;
+
+ for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+ if (wl->tx_frames[i] == NULL) {
+ wl->tx_frames[i] = skb;
+ return i;
+ }
+
+ return -EBUSY;
+}
+
+static void wl12xx_tx_control(struct tx_double_buffer_desc *tx_hdr,
+ struct ieee80211_tx_info *control, u16 fc)
+{
+ *(u16 *)&tx_hdr->control = 0;
+
+ tx_hdr->control.rate_policy = 0;
+
+ /* 802.11 packets */
+ tx_hdr->control.packet_type = 0;
+
+ if (control->flags & IEEE80211_TX_CTL_NO_ACK)
+ tx_hdr->control.ack_policy = 1;
+
+ tx_hdr->control.tx_complete = 1;
+
+ if ((fc & IEEE80211_FTYPE_DATA) &&
+ ((fc & IEEE80211_STYPE_QOS_DATA) ||
+ (fc & IEEE80211_STYPE_QOS_NULLFUNC)))
+ tx_hdr->control.qos = 1;
+}
+
+/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */
+#define MAX_MSDU_SECURITY_LENGTH 16
+#define MAX_MPDU_SECURITY_LENGTH 16
+#define WLAN_QOS_HDR_LEN 26
+#define MAX_MPDU_HEADER_AND_SECURITY (MAX_MPDU_SECURITY_LENGTH + \
+ WLAN_QOS_HDR_LEN)
+#define HW_BLOCK_SIZE 252
+static void wl12xx_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
+{
+ u16 payload_len, frag_threshold, mem_blocks;
+ u16 num_mpdus, mem_blocks_per_frag;
+
+ frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
+ tx_hdr->frag_threshold = cpu_to_le16(frag_threshold);
+
+ payload_len = tx_hdr->length + MAX_MSDU_SECURITY_LENGTH;
+
+ if (payload_len > frag_threshold) {
+ mem_blocks_per_frag =
+ ((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) /
+ HW_BLOCK_SIZE) + 1;
+ num_mpdus = payload_len / frag_threshold;
+ mem_blocks = num_mpdus * mem_blocks_per_frag;
+ payload_len -= num_mpdus * frag_threshold;
+ num_mpdus++;
+
+ } else {
+ mem_blocks_per_frag = 0;
+ mem_blocks = 0;
+ num_mpdus = 1;
+ }
+
+ mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1;
+
+ if (num_mpdus > 1)
+ mem_blocks += min(num_mpdus, mem_blocks_per_frag);
+
+ tx_hdr->num_mem_blocks = mem_blocks;
+}
+
+static int wl12xx_tx_fill_hdr(struct wl12xx *wl, struct sk_buff *skb,
+ struct ieee80211_tx_info *control)
+{
+ struct tx_double_buffer_desc *tx_hdr;
+ struct ieee80211_rate *rate;
+ int id;
+ u16 fc;
+
+ if (!skb)
+ return -EINVAL;
+
+ id = wl12xx_tx_id(wl, skb);
+ if (id < 0)
+ return id;
+
+ fc = *(u16 *)skb->data;
+ tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb,
+ sizeof(*tx_hdr));
+
+ tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr));
+ rate = ieee80211_get_tx_rate(wl->hw, control);
+ tx_hdr->rate = cpu_to_le16(rate->hw_value);
+ tx_hdr->expiry_time = cpu_to_le32(1 << 16);
+ tx_hdr->id = id;
+
+ /* FIXME: how to get the correct queue id? */
+ tx_hdr->xmit_queue = 0;
+
+ wl12xx_tx_control(tx_hdr, control, fc);
+ wl12xx_tx_frag_block_num(tx_hdr);
+
+ return 0;
+}
+
+/* We copy the packet to the target */
+static int wl12xx_tx_send_packet(struct wl12xx *wl, struct sk_buff *skb,
+ struct ieee80211_tx_info *control)
+{
+ struct tx_double_buffer_desc *tx_hdr;
+ int len;
+ u32 addr;
+
+ if (!skb)
+ return -EINVAL;
+
+ tx_hdr = (struct tx_double_buffer_desc *) skb->data;
+
+ if (control->control.hw_key &&
+ control->control.hw_key->alg == ALG_TKIP) {
+ int hdrlen;
+ u16 fc;
+ u8 *pos;
+
+ fc = *(u16 *)(skb->data + sizeof(*tx_hdr));
+ tx_hdr->length += WL12XX_TKIP_IV_SPACE;
+
+ hdrlen = ieee80211_hdrlen(fc);
+
+ pos = skb_push(skb, WL12XX_TKIP_IV_SPACE);
+ memmove(pos, pos + WL12XX_TKIP_IV_SPACE,
+ sizeof(*tx_hdr) + hdrlen);
+ }
+
+ /* Revisit. This is a workaround for getting non-aligned packets.
+ This happens at least with EAPOL packets from the user space.
+ Our DMA requires packets to be aligned on a 4-byte boundary.
+ */
+ if (unlikely((long)skb->data & 0x03)) {
+ int offset = (4 - (long)skb->data) & 0x03;
+ wl12xx_debug(DEBUG_TX, "skb offset %d", offset);
+
+ /* check whether the current skb can be used */
+ if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
+ unsigned char *src = skb->data;
+
+ /* align the buffer on a 4-byte boundary */
+ skb_reserve(skb, offset);
+ memmove(skb->data, src, skb->len);
+ } else {
+ wl12xx_info("No handler, fixme!");
+ return -EINVAL;
+ }
+ }
+
+ /* Our skb->data at this point includes the HW header */
+ len = WL12XX_TX_ALIGN(skb->len);
+
+ if (wl->data_in_count & 0x1)
+ addr = wl->data_path->tx_packet_ring_addr +
+ wl->data_path->tx_packet_ring_chunk_size;
+ else
+ addr = wl->data_path->tx_packet_ring_addr;
+
+ wl12xx_spi_mem_write(wl, addr, skb->data, len);
+
+ wl12xx_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x",
+ tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate);
+
+ return 0;
+}
+
+static void wl12xx_tx_trigger(struct wl12xx *wl)
+{
+ u32 data, addr;
+
+ if (wl->data_in_count & 0x1) {
+ addr = ACX_REG_INTERRUPT_TRIG_H;
+ data = INTR_TRIG_TX_PROC1;
+ } else {
+ addr = ACX_REG_INTERRUPT_TRIG;
+ data = INTR_TRIG_TX_PROC0;
+ }
+
+ wl12xx_reg_write32(wl, addr, data);
+
+ /* Bumping data in */
+ wl->data_in_count = (wl->data_in_count + 1) &
+ TX_STATUS_DATA_OUT_COUNT_MASK;
+}
+
+/* caller must hold wl->mutex */
+static int wl12xx_tx_frame(struct wl12xx *wl, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info;
+ int ret = 0;
+ u8 idx;
+
+ info = IEEE80211_SKB_CB(skb);
+
+ if (info->control.hw_key) {
+ idx = info->control.hw_key->hw_key_idx;
+ if (unlikely(wl->default_key != idx)) {
+ ret = wl12xx_acx_default_key(wl, idx);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ ret = wl12xx_tx_path_status(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_tx_fill_hdr(wl, skb, info);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_tx_send_packet(wl, skb, info);
+ if (ret < 0)
+ return ret;
+
+ wl12xx_tx_trigger(wl);
+
+ return ret;
+}
+
+void wl12xx_tx_work(struct work_struct *work)
+{
+ struct wl12xx *wl = container_of(work, struct wl12xx, tx_work);
+ struct sk_buff *skb;
+ bool woken_up = false;
+ int ret;
+
+ mutex_lock(&wl->mutex);
+
+ if (unlikely(wl->state == WL12XX_STATE_OFF))
+ goto out;
+
+ while ((skb = skb_dequeue(&wl->tx_queue))) {
+ if (!woken_up) {
+ wl12xx_ps_elp_wakeup(wl);
+ woken_up = true;
+ }
+
+ ret = wl12xx_tx_frame(wl, skb);
+ if (ret == -EBUSY) {
+ /* firmware buffer is full, stop queues */
+ wl12xx_debug(DEBUG_TX, "tx_work: fw buffer full, "
+ "stop queues");
+ ieee80211_stop_queues(wl->hw);
+ wl->tx_queue_stopped = true;
+ skb_queue_head(&wl->tx_queue, skb);
+ goto out;
+ } else if (ret < 0) {
+ dev_kfree_skb(skb);
+ goto out;
+ }
+ }
+
+out:
+ if (woken_up)
+ wl12xx_ps_elp_sleep(wl);
+
+ mutex_unlock(&wl->mutex);
+}
+
+static const char *wl12xx_tx_parse_status(u8 status)
+{
+ /* 8 bit status field, one character per bit plus null */
+ static char buf[9];
+ int i = 0;
+
+ memset(buf, 0, sizeof(buf));
+
+ if (status & TX_DMA_ERROR)
+ buf[i++] = 'm';
+ if (status & TX_DISABLED)
+ buf[i++] = 'd';
+ if (status & TX_RETRY_EXCEEDED)
+ buf[i++] = 'r';
+ if (status & TX_TIMEOUT)
+ buf[i++] = 't';
+ if (status & TX_KEY_NOT_FOUND)
+ buf[i++] = 'k';
+ if (status & TX_ENCRYPT_FAIL)
+ buf[i++] = 'e';
+ if (status & TX_UNAVAILABLE_PRIORITY)
+ buf[i++] = 'p';
+
+ /* bit 0 is unused apparently */
+
+ return buf;
+}
+
+static void wl12xx_tx_packet_cb(struct wl12xx *wl,
+ struct tx_result *result)
+{
+ struct ieee80211_tx_info *info;
+ struct sk_buff *skb;
+ int hdrlen, ret;
+ u8 *frame;
+
+ skb = wl->tx_frames[result->id];
+ if (skb == NULL) {
+ wl12xx_error("SKB for packet %d is NULL", result->id);
+ return;
+ }
+
+ info = IEEE80211_SKB_CB(skb);
+
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ (result->status == TX_SUCCESS))
+ info->flags |= IEEE80211_TX_STAT_ACK;
+
+ info->status.rates[0].count = result->ack_failures + 1;
+ wl->stats.retry_count += result->ack_failures;
+
+ /*
+ * We have to remove our private TX header before pushing
+ * the skb back to mac80211.
+ */
+ frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
+ if (info->control.hw_key &&
+ info->control.hw_key->alg == ALG_TKIP) {
+ hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ memmove(frame + WL12XX_TKIP_IV_SPACE, frame, hdrlen);
+ skb_pull(skb, WL12XX_TKIP_IV_SPACE);
+ }
+
+ wl12xx_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
+ " status 0x%x (%s)",
+ result->id, skb, result->ack_failures, result->rate,
+ result->status, wl12xx_tx_parse_status(result->status));
+
+
+ ieee80211_tx_status(wl->hw, skb);
+
+ wl->tx_frames[result->id] = NULL;
+
+ if (wl->tx_queue_stopped) {
+ wl12xx_debug(DEBUG_TX, "cb: queue was stopped");
+
+ skb = skb_dequeue(&wl->tx_queue);
+
+ /* The skb can be NULL because tx_work might have been
+ scheduled before the queue was stopped making the
+ queue empty */
+
+ if (skb) {
+ ret = wl12xx_tx_frame(wl, skb);
+ if (ret == -EBUSY) {
+ /* firmware buffer is still full */
+ wl12xx_debug(DEBUG_TX, "cb: fw buffer "
+ "still full");
+ skb_queue_head(&wl->tx_queue, skb);
+ return;
+ } else if (ret < 0) {
+ dev_kfree_skb(skb);
+ return;
+ }
+ }
+
+ wl12xx_debug(DEBUG_TX, "cb: waking queues");
+ ieee80211_wake_queues(wl->hw);
+ wl->tx_queue_stopped = false;
+ }
+}
+
+/* Called upon reception of a TX complete interrupt */
+void wl12xx_tx_complete(struct wl12xx *wl)
+{
+ int i, result_index, num_complete = 0;
+ struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
+
+ if (unlikely(wl->state != WL12XX_STATE_ON))
+ return;
+
+ /* First we read the result */
+ wl12xx_spi_mem_read(wl, wl->data_path->tx_complete_addr,
+ result, sizeof(result));
+
+ result_index = wl->next_tx_complete;
+
+ for (i = 0; i < ARRAY_SIZE(result); i++) {
+ result_ptr = &result[result_index];
+
+ if (result_ptr->done_1 == 1 &&
+ result_ptr->done_2 == 1) {
+ wl12xx_tx_packet_cb(wl, result_ptr);
+
+ result_ptr->done_1 = 0;
+ result_ptr->done_2 = 0;
+
+ result_index = (result_index + 1) &
+ (FW_TX_CMPLT_BLOCK_SIZE - 1);
+ num_complete++;
+ } else {
+ break;
+ }
+ }
+
+ /* Every completed frame needs to be acknowledged */
+ if (num_complete) {
+ /*
+ * If we've wrapped, we have to clear
+ * the results in 2 steps.
+ */
+ if (result_index > wl->next_tx_complete) {
+ /* Only 1 write is needed */
+ wl12xx_spi_mem_write(wl,
+ wl->data_path->tx_complete_addr +
+ (wl->next_tx_complete *
+ sizeof(struct tx_result)),
+ &result[wl->next_tx_complete],
+ num_complete *
+ sizeof(struct tx_result));
+
+
+ } else if (result_index < wl->next_tx_complete) {
+ /* 2 writes are needed */
+ wl12xx_spi_mem_write(wl,
+ wl->data_path->tx_complete_addr +
+ (wl->next_tx_complete *
+ sizeof(struct tx_result)),
+ &result[wl->next_tx_complete],
+ (FW_TX_CMPLT_BLOCK_SIZE -
+ wl->next_tx_complete) *
+ sizeof(struct tx_result));
+
+ wl12xx_spi_mem_write(wl,
+ wl->data_path->tx_complete_addr,
+ result,
+ (num_complete -
+ FW_TX_CMPLT_BLOCK_SIZE +
+ wl->next_tx_complete) *
+ sizeof(struct tx_result));
+
+ } else {
+ /* We have to write the whole array */
+ wl12xx_spi_mem_write(wl,
+ wl->data_path->tx_complete_addr,
+ result,
+ FW_TX_CMPLT_BLOCK_SIZE *
+ sizeof(struct tx_result));
+ }
+
+ }
+
+ wl->next_tx_complete = result_index;
+}
+
+/* caller must hold wl->mutex */
+void wl12xx_tx_flush(struct wl12xx *wl)
+{
+ int i;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+
+ /* TX failure */
+/* control->flags = 0; FIXME */
+
+ while ((skb = skb_dequeue(&wl->tx_queue))) {
+ info = IEEE80211_SKB_CB(skb);
+
+ wl12xx_debug(DEBUG_TX, "flushing skb 0x%p", skb);
+
+ if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+ continue;
+
+ ieee80211_tx_status(wl->hw, skb);
+ }
+
+ for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+ if (wl->tx_frames[i] != NULL) {
+ skb = wl->tx_frames[i];
+ info = IEEE80211_SKB_CB(skb);
+
+ if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+ continue;
+
+ ieee80211_tx_status(wl->hw, skb);
+ wl->tx_frames[i] = NULL;
+ }
+}
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
new file mode 100644
index 000000000000..dc82691f4c14
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -0,0 +1,215 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __WL12XX_TX_H__
+#define __WL12XX_TX_H__
+
+#include <linux/bitops.h>
+
+/*
+ *
+ * TX PATH
+ *
+ * The Tx path uses a double buffer and a tx_control structure, each located
+ * at a fixed address in the device's memory. On startup, the host retrieves
+ * the pointers to these addresses. A double buffer allows for continuous data
+ * flow towards the device. The host keeps track of which buffer is available
+ * and alternates between these two buffers on a per packet basis.
+ *
+ * The size of each of the two buffers is large enough to hold the longest
+ * 802.3 packet - maximum size Ethernet packet + header + descriptor.
+ * TX complete indication will be received a-synchronously in a TX done cyclic
+ * buffer which is composed of 16 tx_result descriptors structures and is used
+ * in a cyclic manner.
+ *
+ * The TX (HOST) procedure is as follows:
+ * 1. Read the Tx path status, that will give the data_out_count.
+ * 2. goto 1, if not possible.
+ * i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double
+ * buffer).
+ * 3. Copy the packet (preceded by double_buffer_desc), if possible.
+ * i.e. if data_in_count - data_out_count < HwBuffer size (2 for double
+ * buffer).
+ * 4. increment data_in_count.
+ * 5. Inform the firmware by generating a firmware internal interrupt.
+ * 6. FW will increment data_out_count after it reads the buffer.
+ *
+ * The TX Complete procedure:
+ * 1. To get a TX complete indication the host enables the tx_complete flag in
+ * the TX descriptor Structure.
+ * 2. For each packet with a Tx Complete field set, the firmware adds the
+ * transmit results to the cyclic buffer (txDoneRing) and sets both done_1
+ * and done_2 to 1 to indicate driver ownership.
+ * 3. The firmware sends a Tx Complete interrupt to the host to trigger the
+ * host to process the new data. Note: interrupt will be send per packet if
+ * TX complete indication was requested in tx_control or per crossing
+ * aggregation threshold.
+ * 4. After receiving the Tx Complete interrupt, the host reads the
+ * TxDescriptorDone information in a cyclic manner and clears both done_1
+ * and done_2 fields.
+ *
+ */
+
+#define TX_COMPLETE_REQUIRED_BIT 0x80
+#define TX_STATUS_DATA_OUT_COUNT_MASK 0xf
+#define WL12XX_TX_ALIGN_TO 4
+#define WL12XX_TX_ALIGN(len) (((len) + WL12XX_TX_ALIGN_TO - 1) & \
+ ~(WL12XX_TX_ALIGN_TO - 1))
+#define WL12XX_TKIP_IV_SPACE 4
+
+struct tx_control {
+ /* Rate Policy (class) index */
+ unsigned rate_policy:3;
+
+ /* When set, no ack policy is expected */
+ unsigned ack_policy:1;
+
+ /*
+ * Packet type:
+ * 0 -> 802.11
+ * 1 -> 802.3
+ * 2 -> IP
+ * 3 -> raw codec
+ */
+ unsigned packet_type:2;
+
+ /* If set, this is a QoS-Null or QoS-Data frame */
+ unsigned qos:1;
+
+ /*
+ * If set, the target triggers the tx complete INT
+ * upon frame sending completion.
+ */
+ unsigned tx_complete:1;
+
+ /* 2 bytes padding before packet header */
+ unsigned xfer_pad:1;
+
+ unsigned reserved:7;
+} __attribute__ ((packed));
+
+
+struct tx_double_buffer_desc {
+ /* Length of payload, including headers. */
+ u16 length;
+
+ /*
+ * A bit mask that specifies the initial rate to be used
+ * Possible values are:
+ * 0x0001 - 1Mbits
+ * 0x0002 - 2Mbits
+ * 0x0004 - 5.5Mbits
+ * 0x0008 - 6Mbits
+ * 0x0010 - 9Mbits
+ * 0x0020 - 11Mbits
+ * 0x0040 - 12Mbits
+ * 0x0080 - 18Mbits
+ * 0x0100 - 22Mbits
+ * 0x0200 - 24Mbits
+ * 0x0400 - 36Mbits
+ * 0x0800 - 48Mbits
+ * 0x1000 - 54Mbits
+ */
+ u16 rate;
+
+ /* Time in us that a packet can spend in the target */
+ u32 expiry_time;
+
+ /* index of the TX queue used for this packet */
+ u8 xmit_queue;
+
+ /* Used to identify a packet */
+ u8 id;
+
+ struct tx_control control;
+
+ /*
+ * The FW should cut the packet into fragments
+ * of this size.
+ */
+ u16 frag_threshold;
+
+ /* Numbers of HW queue blocks to be allocated */
+ u8 num_mem_blocks;
+
+ u8 reserved;
+} __attribute__ ((packed));
+
+enum {
+ TX_SUCCESS = 0,
+ TX_DMA_ERROR = BIT(7),
+ TX_DISABLED = BIT(6),
+ TX_RETRY_EXCEEDED = BIT(5),
+ TX_TIMEOUT = BIT(4),
+ TX_KEY_NOT_FOUND = BIT(3),
+ TX_ENCRYPT_FAIL = BIT(2),
+ TX_UNAVAILABLE_PRIORITY = BIT(1),
+};
+
+struct tx_result {
+ /*
+ * Ownership synchronization between the host and
+ * the firmware. If done_1 and done_2 are cleared,
+ * owned by the FW (no info ready).
+ */
+ u8 done_1;
+
+ /* same as double_buffer_desc->id */
+ u8 id;
+
+ /*
+ * Total air access duration consumed by this
+ * packet, including all retries and overheads.
+ */
+ u16 medium_usage;
+
+ /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */
+ u32 medium_delay;
+
+ /* Time between host xfer and tx complete */
+ u32 fw_hnadling_time;
+
+ /* The LS-byte of the last TKIP sequence number. */
+ u8 lsb_seq_num;
+
+ /* Retry count */
+ u8 ack_failures;
+
+ /* At which rate we got a ACK */
+ u16 rate;
+
+ u16 reserved;
+
+ /* TX_* */
+ u8 status;
+
+ /* See done_1 */
+ u8 done_2;
+} __attribute__ ((packed));
+
+void wl12xx_tx_work(struct work_struct *work);
+void wl12xx_tx_complete(struct wl12xx *wl);
+void wl12xx_tx_flush(struct wl12xx *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251.c b/drivers/net/wireless/wl12xx/wl1251.c
new file mode 100644
index 000000000000..ce1561a41fa4
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251.c
@@ -0,0 +1,709 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "wl1251.h"
+#include "reg.h"
+#include "spi.h"
+#include "boot.h"
+#include "event.h"
+#include "acx.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+
+static struct wl12xx_partition_set wl1251_part_table[PART_TABLE_LEN] = {
+ [PART_DOWN] = {
+ .mem = {
+ .start = 0x00000000,
+ .size = 0x00016800
+ },
+ .reg = {
+ .start = REGISTERS_BASE,
+ .size = REGISTERS_DOWN_SIZE
+ },
+ },
+
+ [PART_WORK] = {
+ .mem = {
+ .start = 0x00028000,
+ .size = 0x00014000
+ },
+ .reg = {
+ .start = REGISTERS_BASE,
+ .size = REGISTERS_WORK_SIZE
+ },
+ },
+
+ /* WL1251 doesn't use the DRPW partition, so we don't set it here */
+};
+
+static enum wl12xx_acx_int_reg wl1251_acx_reg_table[ACX_REG_TABLE_LEN] = {
+ [ACX_REG_INTERRUPT_TRIG] = (REGISTERS_BASE + 0x0474),
+ [ACX_REG_INTERRUPT_TRIG_H] = (REGISTERS_BASE + 0x0478),
+ [ACX_REG_INTERRUPT_MASK] = (REGISTERS_BASE + 0x0494),
+ [ACX_REG_HINT_MASK_SET] = (REGISTERS_BASE + 0x0498),
+ [ACX_REG_HINT_MASK_CLR] = (REGISTERS_BASE + 0x049C),
+ [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
+ [ACX_REG_INTERRUPT_CLEAR] = (REGISTERS_BASE + 0x04A4),
+ [ACX_REG_INTERRUPT_ACK] = (REGISTERS_BASE + 0x04A8),
+ [ACX_REG_SLV_SOFT_RESET] = (REGISTERS_BASE + 0x0000),
+ [ACX_REG_EE_START] = (REGISTERS_BASE + 0x080C),
+ [ACX_REG_ECPU_CONTROL] = (REGISTERS_BASE + 0x0804)
+};
+
+static int wl1251_upload_firmware(struct wl12xx *wl)
+{
+ struct wl12xx_partition_set *p_table = wl->chip.p_table;
+ int addr, chunk_num, partition_limit;
+ size_t fw_data_len;
+ u8 *p;
+
+ /* whal_FwCtrl_LoadFwImageSm() */
+
+ wl12xx_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x",
+ wl12xx_reg_read32(wl, CHIP_ID_B));
+
+ /* 10.0 check firmware length and set partition */
+ fw_data_len = (wl->fw[4] << 24) | (wl->fw[5] << 16) |
+ (wl->fw[6] << 8) | (wl->fw[7]);
+
+ wl12xx_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len,
+ CHUNK_SIZE);
+
+ if ((fw_data_len % 4) != 0) {
+ wl12xx_error("firmware length not multiple of four");
+ return -EIO;
+ }
+
+ wl12xx_set_partition(wl,
+ p_table[PART_DOWN].mem.start,
+ p_table[PART_DOWN].mem.size,
+ p_table[PART_DOWN].reg.start,
+ p_table[PART_DOWN].reg.size);
+
+ /* 10.1 set partition limit and chunk num */
+ chunk_num = 0;
+ partition_limit = p_table[PART_DOWN].mem.size;
+
+ while (chunk_num < fw_data_len / CHUNK_SIZE) {
+ /* 10.2 update partition, if needed */
+ addr = p_table[PART_DOWN].mem.start +
+ (chunk_num + 2) * CHUNK_SIZE;
+ if (addr > partition_limit) {
+ addr = p_table[PART_DOWN].mem.start +
+ chunk_num * CHUNK_SIZE;
+ partition_limit = chunk_num * CHUNK_SIZE +
+ p_table[PART_DOWN].mem.size;
+ wl12xx_set_partition(wl,
+ addr,
+ p_table[PART_DOWN].mem.size,
+ p_table[PART_DOWN].reg.start,
+ p_table[PART_DOWN].reg.size);
+ }
+
+ /* 10.3 upload the chunk */
+ addr = p_table[PART_DOWN].mem.start + chunk_num * CHUNK_SIZE;
+ p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+ wl12xx_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
+ p, addr);
+ wl12xx_spi_mem_write(wl, addr, p, CHUNK_SIZE);
+
+ chunk_num++;
+ }
+
+ /* 10.4 upload the last chunk */
+ addr = p_table[PART_DOWN].mem.start + chunk_num * CHUNK_SIZE;
+ p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+ wl12xx_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
+ fw_data_len % CHUNK_SIZE, p, addr);
+ wl12xx_spi_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
+
+ return 0;
+}
+
+static int wl1251_upload_nvs(struct wl12xx *wl)
+{
+ size_t nvs_len, nvs_bytes_written, burst_len;
+ int nvs_start, i;
+ u32 dest_addr, val;
+ u8 *nvs_ptr, *nvs;
+
+ nvs = wl->nvs;
+ if (nvs == NULL)
+ return -ENODEV;
+
+ nvs_ptr = nvs;
+
+ nvs_len = wl->nvs_len;
+ nvs_start = wl->fw_len;
+
+ /*
+ * Layout before the actual NVS tables:
+ * 1 byte : burst length.
+ * 2 bytes: destination address.
+ * n bytes: data to burst copy.
+ *
+ * This is ended by a 0 length, then the NVS tables.
+ */
+
+ while (nvs_ptr[0]) {
+ burst_len = nvs_ptr[0];
+ dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
+
+ /* We move our pointer to the data */
+ nvs_ptr += 3;
+
+ for (i = 0; i < burst_len; i++) {
+ val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+ | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+ wl12xx_debug(DEBUG_BOOT,
+ "nvs burst write 0x%x: 0x%x",
+ dest_addr, val);
+ wl12xx_mem_write32(wl, dest_addr, val);
+
+ nvs_ptr += 4;
+ dest_addr += 4;
+ }
+ }
+
+ /*
+ * We've reached the first zero length, the first NVS table
+ * is 7 bytes further.
+ */
+ nvs_ptr += 7;
+ nvs_len -= nvs_ptr - nvs;
+ nvs_len = ALIGN(nvs_len, 4);
+
+ /* Now we must set the partition correctly */
+ wl12xx_set_partition(wl, nvs_start,
+ wl->chip.p_table[PART_DOWN].mem.size,
+ wl->chip.p_table[PART_DOWN].reg.start,
+ wl->chip.p_table[PART_DOWN].reg.size);
+
+ /* And finally we upload the NVS tables */
+ nvs_bytes_written = 0;
+ while (nvs_bytes_written < nvs_len) {
+ val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+ | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+ val = cpu_to_le32(val);
+
+ wl12xx_debug(DEBUG_BOOT,
+ "nvs write table 0x%x: 0x%x",
+ nvs_start, val);
+ wl12xx_mem_write32(wl, nvs_start, val);
+
+ nvs_ptr += 4;
+ nvs_bytes_written += 4;
+ nvs_start += 4;
+ }
+
+ return 0;
+}
+
+static int wl1251_boot(struct wl12xx *wl)
+{
+ int ret = 0, minor_minor_e2_ver;
+ u32 tmp, boot_data;
+
+ ret = wl12xx_boot_soft_reset(wl);
+ if (ret < 0)
+ goto out;
+
+ /* 2. start processing NVS file */
+ ret = wl->chip.op_upload_nvs(wl);
+ if (ret < 0)
+ goto out;
+
+ /* write firmware's last address (ie. it's length) to
+ * ACX_EEPROMLESS_IND_REG */
+ wl12xx_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
+
+ /* 6. read the EEPROM parameters */
+ tmp = wl12xx_reg_read32(wl, SCR_PAD2);
+
+ /* 7. read bootdata */
+ wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8;
+ wl->boot_attr.major = (tmp & 0x00FF0000) >> 16;
+ tmp = wl12xx_reg_read32(wl, SCR_PAD3);
+
+ /* 8. check bootdata and call restart sequence */
+ wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16;
+ minor_minor_e2_ver = (tmp & 0xFF000000) >> 24;
+
+ wl12xx_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x "
+ "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
+ wl->boot_attr.radio_type, wl->boot_attr.major,
+ wl->boot_attr.minor, minor_minor_e2_ver);
+
+ ret = wl12xx_boot_init_seq(wl);
+ if (ret < 0)
+ goto out;
+
+ /* 9. NVS processing done */
+ boot_data = wl12xx_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+ wl12xx_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data);
+
+ /* 10. check that ECPU_CONTROL_HALT bits are set in
+ * pWhalBus->uBootData and start uploading firmware
+ */
+ if ((boot_data & ECPU_CONTROL_HALT) == 0) {
+ wl12xx_error("boot failed, ECPU_CONTROL_HALT not set");
+ ret = -EIO;
+ goto out;
+ }
+
+ ret = wl->chip.op_upload_fw(wl);
+ if (ret < 0)
+ goto out;
+
+ /* 10.5 start firmware */
+ ret = wl12xx_boot_run_firmware(wl);
+ if (ret < 0)
+ goto out;
+
+ /* Get and save the firmware version */
+ wl12xx_acx_fw_version(wl, wl->chip.fw_ver, sizeof(wl->chip.fw_ver));
+
+out:
+ return ret;
+}
+
+static int wl1251_mem_cfg(struct wl12xx *wl)
+{
+ struct wl1251_acx_config_memory mem_conf;
+ int ret, i;
+
+ wl12xx_debug(DEBUG_ACX, "wl1251 mem cfg");
+
+ /* memory config */
+ mem_conf.mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
+ mem_conf.mem_config.rx_mem_block_num = 35;
+ mem_conf.mem_config.tx_min_mem_block_num = 64;
+ mem_conf.mem_config.num_tx_queues = MAX_TX_QUEUES;
+ mem_conf.mem_config.host_if_options = HOSTIF_PKT_RING;
+ mem_conf.mem_config.num_ssid_profiles = 1;
+ mem_conf.mem_config.debug_buffer_size =
+ cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
+
+ /* RX queue config */
+ mem_conf.rx_queue_config.dma_address = 0;
+ mem_conf.rx_queue_config.num_descs = ACX_RX_DESC_DEF;
+ mem_conf.rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
+ mem_conf.rx_queue_config.type = DEFAULT_RXQ_TYPE;
+
+ /* TX queue config */
+ for (i = 0; i < MAX_TX_QUEUES; i++) {
+ mem_conf.tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
+ mem_conf.tx_queue_config[i].attributes = i;
+ }
+
+ mem_conf.header.id = ACX_MEM_CFG;
+ mem_conf.header.len = sizeof(struct wl1251_acx_config_memory) -
+ sizeof(struct acx_header);
+ mem_conf.header.len -=
+ (MAX_TX_QUEUE_CONFIGS - mem_conf.mem_config.num_tx_queues) *
+ sizeof(struct wl1251_acx_tx_queue_config);
+
+ ret = wl12xx_cmd_configure(wl, &mem_conf,
+ sizeof(struct wl1251_acx_config_memory));
+ if (ret < 0)
+ wl12xx_warning("wl1251 mem config failed: %d", ret);
+
+ return ret;
+}
+
+static int wl1251_hw_init_mem_config(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl1251_mem_cfg(wl);
+ if (ret < 0)
+ return ret;
+
+ wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
+ GFP_KERNEL);
+ if (!wl->target_mem_map) {
+ wl12xx_error("couldn't allocate target memory map");
+ return -ENOMEM;
+ }
+
+ /* we now ask for the firmware built memory map */
+ ret = wl12xx_acx_mem_map(wl, wl->target_mem_map,
+ sizeof(struct wl1251_acx_mem_map));
+ if (ret < 0) {
+ wl12xx_error("couldn't retrieve firmware memory map");
+ kfree(wl->target_mem_map);
+ wl->target_mem_map = NULL;
+ return ret;
+ }
+
+ return 0;
+}
+
+static void wl1251_set_ecpu_ctrl(struct wl12xx *wl, u32 flag)
+{
+ u32 cpu_ctrl;
+
+ /* 10.5.0 run the firmware (I) */
+ cpu_ctrl = wl12xx_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+ /* 10.5.1 run the firmware (II) */
+ cpu_ctrl &= ~flag;
+ wl12xx_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
+}
+
+static void wl1251_target_enable_interrupts(struct wl12xx *wl)
+{
+ /* Enable target's interrupts */
+ wl->intr_mask = WL1251_ACX_INTR_RX0_DATA |
+ WL1251_ACX_INTR_RX1_DATA |
+ WL1251_ACX_INTR_TX_RESULT |
+ WL1251_ACX_INTR_EVENT_A |
+ WL1251_ACX_INTR_EVENT_B |
+ WL1251_ACX_INTR_INIT_COMPLETE;
+ wl12xx_boot_target_enable_interrupts(wl);
+}
+
+static void wl1251_irq_work(struct work_struct *work)
+{
+ u32 intr;
+ struct wl12xx *wl =
+ container_of(work, struct wl12xx, irq_work);
+
+ mutex_lock(&wl->mutex);
+
+ wl12xx_debug(DEBUG_IRQ, "IRQ work");
+
+ if (wl->state == WL12XX_STATE_OFF)
+ goto out;
+
+ wl12xx_ps_elp_wakeup(wl);
+
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL);
+
+ intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
+ wl12xx_debug(DEBUG_IRQ, "intr: 0x%x", intr);
+
+ if (wl->data_path) {
+ wl12xx_spi_mem_read(wl, wl->data_path->rx_control_addr,
+ &wl->rx_counter, sizeof(u32));
+
+ /* We handle a frmware bug here */
+ switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
+ case 0:
+ wl12xx_debug(DEBUG_IRQ, "RX: FW and host in sync");
+ intr &= ~WL1251_ACX_INTR_RX0_DATA;
+ intr &= ~WL1251_ACX_INTR_RX1_DATA;
+ break;
+ case 1:
+ wl12xx_debug(DEBUG_IRQ, "RX: FW +1");
+ intr |= WL1251_ACX_INTR_RX0_DATA;
+ intr &= ~WL1251_ACX_INTR_RX1_DATA;
+ break;
+ case 2:
+ wl12xx_debug(DEBUG_IRQ, "RX: FW +2");
+ intr |= WL1251_ACX_INTR_RX0_DATA;
+ intr |= WL1251_ACX_INTR_RX1_DATA;
+ break;
+ default:
+ wl12xx_warning("RX: FW and host out of sync: %d",
+ wl->rx_counter - wl->rx_handled);
+ break;
+ }
+
+ wl->rx_handled = wl->rx_counter;
+
+
+ wl12xx_debug(DEBUG_IRQ, "RX counter: %d", wl->rx_counter);
+ }
+
+ intr &= wl->intr_mask;
+
+ if (intr == 0) {
+ wl12xx_debug(DEBUG_IRQ, "INTR is 0");
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
+ ~(wl->intr_mask));
+
+ goto out_sleep;
+ }
+
+ if (intr & WL1251_ACX_INTR_RX0_DATA) {
+ wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
+ wl12xx_rx(wl);
+ }
+
+ if (intr & WL1251_ACX_INTR_RX1_DATA) {
+ wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
+ wl12xx_rx(wl);
+ }
+
+ if (intr & WL1251_ACX_INTR_TX_RESULT) {
+ wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
+ wl12xx_tx_complete(wl);
+ }
+
+ if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) {
+ wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr);
+ if (intr & WL1251_ACX_INTR_EVENT_A)
+ wl12xx_event_handle(wl, 0);
+ else
+ wl12xx_event_handle(wl, 1);
+ }
+
+ if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
+ wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE");
+
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+
+out_sleep:
+ wl12xx_ps_elp_sleep(wl);
+out:
+ mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_hw_init_txq_fill(u8 qid,
+ struct acx_tx_queue_qos_config *config,
+ u32 num_blocks)
+{
+ config->qid = qid;
+
+ switch (qid) {
+ case QOS_AC_BE:
+ config->high_threshold =
+ (QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
+ config->low_threshold =
+ (QOS_TX_LOW_BE_DEF * num_blocks) / 100;
+ break;
+ case QOS_AC_BK:
+ config->high_threshold =
+ (QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
+ config->low_threshold =
+ (QOS_TX_LOW_BK_DEF * num_blocks) / 100;
+ break;
+ case QOS_AC_VI:
+ config->high_threshold =
+ (QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
+ config->low_threshold =
+ (QOS_TX_LOW_VI_DEF * num_blocks) / 100;
+ break;
+ case QOS_AC_VO:
+ config->high_threshold =
+ (QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
+ config->low_threshold =
+ (QOS_TX_LOW_VO_DEF * num_blocks) / 100;
+ break;
+ default:
+ wl12xx_error("Invalid TX queue id: %d", qid);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int wl1251_hw_init_tx_queue_config(struct wl12xx *wl)
+{
+ struct acx_tx_queue_qos_config config;
+ struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
+ int ret, i;
+
+ wl12xx_debug(DEBUG_ACX, "acx tx queue config");
+
+ config.header.id = ACX_TX_QUEUE_CFG;
+ config.header.len = sizeof(struct acx_tx_queue_qos_config) -
+ sizeof(struct acx_header);
+
+ for (i = 0; i < MAX_NUM_OF_AC; i++) {
+ ret = wl1251_hw_init_txq_fill(i, &config,
+ wl_mem_map->num_tx_mem_blocks);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_configure(wl, &config, sizeof(config));
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int wl1251_hw_init_data_path_config(struct wl12xx *wl)
+{
+ int ret;
+
+ /* asking for the data path parameters */
+ wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
+ GFP_KERNEL);
+ if (!wl->data_path) {
+ wl12xx_error("Couldnt allocate data path parameters");
+ return -ENOMEM;
+ }
+
+ ret = wl12xx_acx_data_path_params(wl, wl->data_path);
+ if (ret < 0) {
+ kfree(wl->data_path);
+ wl->data_path = NULL;
+ return ret;
+ }
+
+ return 0;
+}
+
+static int wl1251_hw_init(struct wl12xx *wl)
+{
+ struct wl1251_acx_mem_map *wl_mem_map;
+ int ret;
+
+ ret = wl12xx_hw_init_hwenc_config(wl);
+ if (ret < 0)
+ return ret;
+
+ /* Template settings */
+ ret = wl12xx_hw_init_templates_config(wl);
+ if (ret < 0)
+ return ret;
+
+ /* Default memory configuration */
+ ret = wl1251_hw_init_mem_config(wl);
+ if (ret < 0)
+ return ret;
+
+ /* Default data path configuration */
+ ret = wl1251_hw_init_data_path_config(wl);
+ if (ret < 0)
+ goto out_free_memmap;
+
+ /* RX config */
+ ret = wl12xx_hw_init_rx_config(wl,
+ RX_CFG_PROMISCUOUS | RX_CFG_TSF,
+ RX_FILTER_OPTION_DEF);
+ /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
+ RX_FILTER_OPTION_FILTER_ALL); */
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* TX queues config */
+ ret = wl1251_hw_init_tx_queue_config(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* PHY layer config */
+ ret = wl12xx_hw_init_phy_config(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Beacon filtering */
+ ret = wl12xx_hw_init_beacon_filter(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Bluetooth WLAN coexistence */
+ ret = wl12xx_hw_init_pta(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Energy detection */
+ ret = wl12xx_hw_init_energy_detection(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Beacons and boradcast settings */
+ ret = wl12xx_hw_init_beacon_broadcast(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Enable data path */
+ ret = wl12xx_cmd_data_path(wl, wl->channel, 1);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Default power state */
+ ret = wl12xx_hw_init_power_auth(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ wl_mem_map = wl->target_mem_map;
+ wl12xx_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
+ wl_mem_map->num_tx_mem_blocks,
+ wl->data_path->tx_control_addr,
+ wl_mem_map->num_rx_mem_blocks,
+ wl->data_path->rx_control_addr);
+
+ return 0;
+
+ out_free_data_path:
+ kfree(wl->data_path);
+
+ out_free_memmap:
+ kfree(wl->target_mem_map);
+
+ return ret;
+}
+
+static int wl1251_plt_init(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl1251_hw_init_mem_config(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_data_path(wl, wl->channel, 1);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+void wl1251_setup(struct wl12xx *wl)
+{
+ /* FIXME: Is it better to use strncpy here or is this ok? */
+ wl->chip.fw_filename = WL1251_FW_NAME;
+ wl->chip.nvs_filename = WL1251_NVS_NAME;
+
+ /* Now we know what chip we're using, so adjust the power on sleep
+ * time accordingly */
+ wl->chip.power_on_sleep = WL1251_POWER_ON_SLEEP;
+
+ wl->chip.intr_cmd_complete = WL1251_ACX_INTR_CMD_COMPLETE;
+ wl->chip.intr_init_complete = WL1251_ACX_INTR_INIT_COMPLETE;
+
+ wl->chip.op_upload_nvs = wl1251_upload_nvs;
+ wl->chip.op_upload_fw = wl1251_upload_firmware;
+ wl->chip.op_boot = wl1251_boot;
+ wl->chip.op_set_ecpu_ctrl = wl1251_set_ecpu_ctrl;
+ wl->chip.op_target_enable_interrupts = wl1251_target_enable_interrupts;
+ wl->chip.op_hw_init = wl1251_hw_init;
+ wl->chip.op_plt_init = wl1251_plt_init;
+
+ wl->chip.p_table = wl1251_part_table;
+ wl->chip.acx_reg_table = wl1251_acx_reg_table;
+
+ INIT_WORK(&wl->irq_work, wl1251_irq_work);
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
new file mode 100644
index 000000000000..1f4a44330394
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -0,0 +1,165 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __WL1251_H__
+#define __WL1251_H__
+
+#include <linux/bitops.h>
+
+#include "wl12xx.h"
+#include "acx.h"
+
+#define WL1251_FW_NAME "wl1251-fw.bin"
+#define WL1251_NVS_NAME "wl1251-nvs.bin"
+
+#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */
+
+void wl1251_setup(struct wl12xx *wl);
+
+
+struct wl1251_acx_memory {
+ __le16 num_stations; /* number of STAs to be supported. */
+ u16 reserved_1;
+
+ /*
+ * Nmber of memory buffers for the RX mem pool.
+ * The actual number may be less if there are
+ * not enough blocks left for the minimum num
+ * of TX ones.
+ */
+ u8 rx_mem_block_num;
+ u8 reserved_2;
+ u8 num_tx_queues; /* From 1 to 16 */
+ u8 host_if_options; /* HOST_IF* */
+ u8 tx_min_mem_block_num;
+ u8 num_ssid_profiles;
+ __le16 debug_buffer_size;
+} __attribute__ ((packed));
+
+
+#define ACX_RX_DESC_MIN 1
+#define ACX_RX_DESC_MAX 127
+#define ACX_RX_DESC_DEF 32
+struct wl1251_acx_rx_queue_config {
+ u8 num_descs;
+ u8 pad;
+ u8 type;
+ u8 priority;
+ __le32 dma_address;
+} __attribute__ ((packed));
+
+#define ACX_TX_DESC_MIN 1
+#define ACX_TX_DESC_MAX 127
+#define ACX_TX_DESC_DEF 16
+struct wl1251_acx_tx_queue_config {
+ u8 num_descs;
+ u8 pad[2];
+ u8 attributes;
+} __attribute__ ((packed));
+
+#define MAX_TX_QUEUE_CONFIGS 5
+#define MAX_TX_QUEUES 4
+struct wl1251_acx_config_memory {
+ struct acx_header header;
+
+ struct wl1251_acx_memory mem_config;
+ struct wl1251_acx_rx_queue_config rx_queue_config;
+ struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS];
+} __attribute__ ((packed));
+
+struct wl1251_acx_mem_map {
+ struct acx_header header;
+
+ void *code_start;
+ void *code_end;
+
+ void *wep_defkey_start;
+ void *wep_defkey_end;
+
+ void *sta_table_start;
+ void *sta_table_end;
+
+ void *packet_template_start;
+ void *packet_template_end;
+
+ void *queue_memory_start;
+ void *queue_memory_end;
+
+ void *packet_memory_pool_start;
+ void *packet_memory_pool_end;
+
+ void *debug_buffer1_start;
+ void *debug_buffer1_end;
+
+ void *debug_buffer2_start;
+ void *debug_buffer2_end;
+
+ /* Number of blocks FW allocated for TX packets */
+ u32 num_tx_mem_blocks;
+
+ /* Number of blocks FW allocated for RX packets */
+ u32 num_rx_mem_blocks;
+} __attribute__ ((packed));
+
+/*************************************************************************
+
+ Host Interrupt Register (WiLink -> Host)
+
+**************************************************************************/
+
+/* RX packet is ready in Xfer buffer #0 */
+#define WL1251_ACX_INTR_RX0_DATA BIT(0)
+
+/* TX result(s) are in the TX complete buffer */
+#define WL1251_ACX_INTR_TX_RESULT BIT(1)
+
+/* OBSOLETE */
+#define WL1251_ACX_INTR_TX_XFR BIT(2)
+
+/* RX packet is ready in Xfer buffer #1 */
+#define WL1251_ACX_INTR_RX1_DATA BIT(3)
+
+/* Event was entered to Event MBOX #A */
+#define WL1251_ACX_INTR_EVENT_A BIT(4)
+
+/* Event was entered to Event MBOX #B */
+#define WL1251_ACX_INTR_EVENT_B BIT(5)
+
+/* OBSOLETE */
+#define WL1251_ACX_INTR_WAKE_ON_HOST BIT(6)
+
+/* Trace meassge on MBOX #A */
+#define WL1251_ACX_INTR_TRACE_A BIT(7)
+
+/* Trace meassge on MBOX #B */
+#define WL1251_ACX_INTR_TRACE_B BIT(8)
+
+/* Command processing completion */
+#define WL1251_ACX_INTR_CMD_COMPLETE BIT(9)
+
+/* Init sequence is done */
+#define WL1251_ACX_INTR_INIT_COMPLETE BIT(14)
+
+#define WL1251_ACX_INTR_ALL 0xFFFFFFFF
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
new file mode 100644
index 000000000000..48641437414b
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -0,0 +1,409 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 __WL12XX_H__
+#define __WL12XX_H__
+
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/bitops.h>
+#include <net/mac80211.h>
+
+#define DRIVER_NAME "wl12xx"
+#define DRIVER_PREFIX DRIVER_NAME ": "
+
+enum {
+ DEBUG_NONE = 0,
+ DEBUG_IRQ = BIT(0),
+ DEBUG_SPI = BIT(1),
+ DEBUG_BOOT = BIT(2),
+ DEBUG_MAILBOX = BIT(3),
+ DEBUG_NETLINK = BIT(4),
+ DEBUG_EVENT = BIT(5),
+ DEBUG_TX = BIT(6),
+ DEBUG_RX = BIT(7),
+ DEBUG_SCAN = BIT(8),
+ DEBUG_CRYPT = BIT(9),
+ DEBUG_PSM = BIT(10),
+ DEBUG_MAC80211 = BIT(11),
+ DEBUG_CMD = BIT(12),
+ DEBUG_ACX = BIT(13),
+ DEBUG_ALL = ~0,
+};
+
+#define DEBUG_LEVEL (DEBUG_NONE)
+
+#define DEBUG_DUMP_LIMIT 1024
+
+#define wl12xx_error(fmt, arg...) \
+ printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+
+#define wl12xx_warning(fmt, arg...) \
+ printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+
+#define wl12xx_notice(fmt, arg...) \
+ printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl12xx_info(fmt, arg...) \
+ printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl12xx_debug(level, fmt, arg...) \
+ do { \
+ if (level & DEBUG_LEVEL) \
+ printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
+ } while (0)
+
+#define wl12xx_dump(level, prefix, buf, len) \
+ do { \
+ if (level & DEBUG_LEVEL) \
+ print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+ DUMP_PREFIX_OFFSET, 16, 1, \
+ buf, \
+ min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+ 0); \
+ } while (0)
+
+#define wl12xx_dump_ascii(level, prefix, buf, len) \
+ do { \
+ if (level & DEBUG_LEVEL) \
+ print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+ DUMP_PREFIX_OFFSET, 16, 1, \
+ buf, \
+ min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+ true); \
+ } while (0)
+
+#define WL12XX_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \
+ CFG_BSSID_FILTER_EN)
+
+#define WL12XX_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \
+ CFG_RX_MGMT_EN | \
+ CFG_RX_DATA_EN | \
+ CFG_RX_CTL_EN | \
+ CFG_RX_BCN_EN | \
+ CFG_RX_AUTH_EN | \
+ CFG_RX_ASSOC_EN)
+
+
+struct boot_attr {
+ u32 radio_type;
+ u8 mac_clock;
+ u8 arm_clock;
+ int firmware_debug;
+ u32 minor;
+ u32 major;
+ u32 bugfix;
+};
+
+enum wl12xx_state {
+ WL12XX_STATE_OFF,
+ WL12XX_STATE_ON,
+ WL12XX_STATE_PLT,
+};
+
+enum wl12xx_partition_type {
+ PART_DOWN,
+ PART_WORK,
+ PART_DRPW,
+
+ PART_TABLE_LEN
+};
+
+struct wl12xx_partition {
+ u32 size;
+ u32 start;
+};
+
+struct wl12xx_partition_set {
+ struct wl12xx_partition mem;
+ struct wl12xx_partition reg;
+};
+
+struct wl12xx;
+
+/* FIXME: I'm not sure about this structure name */
+struct wl12xx_chip {
+ u32 id;
+
+ const char *fw_filename;
+ const char *nvs_filename;
+
+ char fw_ver[21];
+
+ unsigned int power_on_sleep;
+ int intr_cmd_complete;
+ int intr_init_complete;
+
+ int (*op_upload_fw)(struct wl12xx *wl);
+ int (*op_upload_nvs)(struct wl12xx *wl);
+ int (*op_boot)(struct wl12xx *wl);
+ void (*op_set_ecpu_ctrl)(struct wl12xx *wl, u32 flag);
+ void (*op_target_enable_interrupts)(struct wl12xx *wl);
+ int (*op_hw_init)(struct wl12xx *wl);
+ int (*op_plt_init)(struct wl12xx *wl);
+
+ struct wl12xx_partition_set *p_table;
+ enum wl12xx_acx_int_reg *acx_reg_table;
+};
+
+struct wl12xx_stats {
+ struct acx_statistics *fw_stats;
+ unsigned long fw_stats_update;
+
+ unsigned int retry_count;
+ unsigned int excessive_retries;
+};
+
+struct wl12xx_debugfs {
+ struct dentry *rootdir;
+ struct dentry *fw_statistics;
+
+ struct dentry *tx_internal_desc_overflow;
+
+ struct dentry *rx_out_of_mem;
+ struct dentry *rx_hdr_overflow;
+ struct dentry *rx_hw_stuck;
+ struct dentry *rx_dropped;
+ struct dentry *rx_fcs_err;
+ struct dentry *rx_xfr_hint_trig;
+ struct dentry *rx_path_reset;
+ struct dentry *rx_reset_counter;
+
+ struct dentry *dma_rx_requested;
+ struct dentry *dma_rx_errors;
+ struct dentry *dma_tx_requested;
+ struct dentry *dma_tx_errors;
+
+ struct dentry *isr_cmd_cmplt;
+ struct dentry *isr_fiqs;
+ struct dentry *isr_rx_headers;
+ struct dentry *isr_rx_mem_overflow;
+ struct dentry *isr_rx_rdys;
+ struct dentry *isr_irqs;
+ struct dentry *isr_tx_procs;
+ struct dentry *isr_decrypt_done;
+ struct dentry *isr_dma0_done;
+ struct dentry *isr_dma1_done;
+ struct dentry *isr_tx_exch_complete;
+ struct dentry *isr_commands;
+ struct dentry *isr_rx_procs;
+ struct dentry *isr_hw_pm_mode_changes;
+ struct dentry *isr_host_acknowledges;
+ struct dentry *isr_pci_pm;
+ struct dentry *isr_wakeups;
+ struct dentry *isr_low_rssi;
+
+ struct dentry *wep_addr_key_count;
+ struct dentry *wep_default_key_count;
+ /* skipping wep.reserved */
+ struct dentry *wep_key_not_found;
+ struct dentry *wep_decrypt_fail;
+ struct dentry *wep_packets;
+ struct dentry *wep_interrupt;
+
+ struct dentry *pwr_ps_enter;
+ struct dentry *pwr_elp_enter;
+ struct dentry *pwr_missing_bcns;
+ struct dentry *pwr_wake_on_host;
+ struct dentry *pwr_wake_on_timer_exp;
+ struct dentry *pwr_tx_with_ps;
+ struct dentry *pwr_tx_without_ps;
+ struct dentry *pwr_rcvd_beacons;
+ struct dentry *pwr_power_save_off;
+ struct dentry *pwr_enable_ps;
+ struct dentry *pwr_disable_ps;
+ struct dentry *pwr_fix_tsf_ps;
+ /* skipping cont_miss_bcns_spread for now */
+ struct dentry *pwr_rcvd_awake_beacons;
+
+ struct dentry *mic_rx_pkts;
+ struct dentry *mic_calc_failure;
+
+ struct dentry *aes_encrypt_fail;
+ struct dentry *aes_decrypt_fail;
+ struct dentry *aes_encrypt_packets;
+ struct dentry *aes_decrypt_packets;
+ struct dentry *aes_encrypt_interrupt;
+ struct dentry *aes_decrypt_interrupt;
+
+ struct dentry *event_heart_beat;
+ struct dentry *event_calibration;
+ struct dentry *event_rx_mismatch;
+ struct dentry *event_rx_mem_empty;
+ struct dentry *event_rx_pool;
+ struct dentry *event_oom_late;
+ struct dentry *event_phy_transmit_error;
+ struct dentry *event_tx_stuck;
+
+ struct dentry *ps_pspoll_timeouts;
+ struct dentry *ps_upsd_timeouts;
+ struct dentry *ps_upsd_max_sptime;
+ struct dentry *ps_upsd_max_apturn;
+ struct dentry *ps_pspoll_max_apturn;
+ struct dentry *ps_pspoll_utilization;
+ struct dentry *ps_upsd_utilization;
+
+ struct dentry *rxpipe_rx_prep_beacon_drop;
+ struct dentry *rxpipe_descr_host_int_trig_rx_data;
+ struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
+ struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
+ struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
+
+ struct dentry *tx_queue_len;
+
+ struct dentry *retry_count;
+ struct dentry *excessive_retries;
+};
+
+struct wl12xx {
+ struct ieee80211_hw *hw;
+ bool mac80211_registered;
+
+ struct spi_device *spi;
+
+ void (*set_power)(bool enable);
+ int irq;
+
+ enum wl12xx_state state;
+ struct mutex mutex;
+
+ int physical_mem_addr;
+ int physical_reg_addr;
+ int virtual_mem_addr;
+ int virtual_reg_addr;
+
+ struct wl12xx_chip chip;
+
+ int cmd_box_addr;
+ int event_box_addr;
+ struct boot_attr boot_attr;
+
+ u8 *fw;
+ size_t fw_len;
+ u8 *nvs;
+ size_t nvs_len;
+
+ u8 bssid[ETH_ALEN];
+ u8 mac_addr[ETH_ALEN];
+ u8 bss_type;
+ u8 listen_int;
+ int channel;
+
+ void *target_mem_map;
+ struct acx_data_path_params_resp *data_path;
+
+ /* Number of TX packets transferred to the FW, modulo 16 */
+ u32 data_in_count;
+
+ /* Frames scheduled for transmission, not handled yet */
+ struct sk_buff_head tx_queue;
+ bool tx_queue_stopped;
+
+ struct work_struct tx_work;
+ struct work_struct filter_work;
+
+ /* Pending TX frames */
+ struct sk_buff *tx_frames[16];
+
+ /*
+ * Index pointing to the next TX complete entry
+ * in the cyclic XT complete array we get from
+ * the FW.
+ */
+ u32 next_tx_complete;
+
+ /* FW Rx counter */
+ u32 rx_counter;
+
+ /* Rx frames handled */
+ u32 rx_handled;
+
+ /* Current double buffer */
+ u32 rx_current_buffer;
+ u32 rx_last_id;
+
+ /* The target interrupt mask */
+ u32 intr_mask;
+ struct work_struct irq_work;
+
+ /* The mbox event mask */
+ u32 event_mask;
+
+ /* Mailbox pointers */
+ u32 mbox_ptr[2];
+
+ /* Are we currently scanning */
+ bool scanning;
+
+ /* Our association ID */
+ u16 aid;
+
+ /* Default key (for WEP) */
+ u32 default_key;
+
+ unsigned int tx_mgmt_frm_rate;
+ unsigned int tx_mgmt_frm_mod;
+
+ unsigned int rx_config;
+ unsigned int rx_filter;
+
+ /* is firmware in elp mode */
+ bool elp;
+
+ /* we can be in psm, but not in elp, we have to differentiate */
+ bool psm;
+
+ /* PSM mode requested */
+ bool psm_requested;
+
+ /* in dBm */
+ int power_level;
+
+ struct wl12xx_stats stats;
+ struct wl12xx_debugfs debugfs;
+};
+
+int wl12xx_plt_start(struct wl12xx *wl);
+int wl12xx_plt_stop(struct wl12xx *wl);
+
+#define DEFAULT_HW_GEN_MODULATION_TYPE CCK_LONG /* Long Preamble */
+#define DEFAULT_HW_GEN_TX_RATE RATE_2MBPS
+#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
+
+#define WL12XX_DEFAULT_POWER_LEVEL 20
+
+#define WL12XX_TX_QUEUE_MAX_LENGTH 20
+
+/* Different chips need different sleep times after power on. WL1271 needs
+ * 200ms, WL1251 needs only 10ms. By default we use 200ms, but as soon as we
+ * know the chip ID, we change the sleep value in the wl12xx chip structure,
+ * so in subsequent power ons, we don't waste more time then needed. */
+#define WL12XX_DEFAULT_POWER_ON_SLEEP 200
+
+#define CHIP_ID_1251_PG10 (0x7010101)
+#define CHIP_ID_1251_PG11 (0x7020101)
+#define CHIP_ID_1251_PG12 (0x7030101)
+#define CHIP_ID_1271_PG10 (0x4030101)
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h
new file mode 100644
index 000000000000..657c2dbcb7d3
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h
@@ -0,0 +1,156 @@
+#ifndef __WL12XX_80211_H__
+#define __WL12XX_80211_H__
+
+#include <linux/if_ether.h> /* ETH_ALEN */
+
+/* RATES */
+#define IEEE80211_CCK_RATE_1MB 0x02
+#define IEEE80211_CCK_RATE_2MB 0x04
+#define IEEE80211_CCK_RATE_5MB 0x0B
+#define IEEE80211_CCK_RATE_11MB 0x16
+#define IEEE80211_OFDM_RATE_6MB 0x0C
+#define IEEE80211_OFDM_RATE_9MB 0x12
+#define IEEE80211_OFDM_RATE_12MB 0x18
+#define IEEE80211_OFDM_RATE_18MB 0x24
+#define IEEE80211_OFDM_RATE_24MB 0x30
+#define IEEE80211_OFDM_RATE_36MB 0x48
+#define IEEE80211_OFDM_RATE_48MB 0x60
+#define IEEE80211_OFDM_RATE_54MB 0x6C
+#define IEEE80211_BASIC_RATE_MASK 0x80
+
+#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
+#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
+#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
+#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
+#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
+#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
+#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
+#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
+#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
+#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
+#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
+#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
+
+#define IEEE80211_CCK_RATES_MASK 0x0000000F
+#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
+ IEEE80211_CCK_RATE_2MB_MASK)
+#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
+ IEEE80211_CCK_RATE_5MB_MASK | \
+ IEEE80211_CCK_RATE_11MB_MASK)
+
+#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
+#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
+ IEEE80211_OFDM_RATE_12MB_MASK | \
+ IEEE80211_OFDM_RATE_24MB_MASK)
+#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
+ IEEE80211_OFDM_RATE_9MB_MASK | \
+ IEEE80211_OFDM_RATE_18MB_MASK | \
+ IEEE80211_OFDM_RATE_36MB_MASK | \
+ IEEE80211_OFDM_RATE_48MB_MASK | \
+ IEEE80211_OFDM_RATE_54MB_MASK)
+#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
+ IEEE80211_CCK_DEFAULT_RATES_MASK)
+
+
+/* This really should be 8, but not for our firmware */
+#define MAX_SUPPORTED_RATES 32
+#define COUNTRY_STRING_LEN 3
+#define MAX_COUNTRY_TRIPLETS 32
+
+/* Headers */
+struct ieee80211_header {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 da[ETH_ALEN];
+ u8 sa[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct wl12xx_ie_header {
+ u8 id;
+ u8 len;
+} __attribute__ ((packed));
+
+/* IEs */
+
+struct wl12xx_ie_ssid {
+ struct wl12xx_ie_header header;
+ char ssid[IW_ESSID_MAX_SIZE];
+} __attribute__ ((packed));
+
+struct wl12xx_ie_rates {
+ struct wl12xx_ie_header header;
+ u8 rates[MAX_SUPPORTED_RATES];
+} __attribute__ ((packed));
+
+struct wl12xx_ie_ds_params {
+ struct wl12xx_ie_header header;
+ u8 channel;
+} __attribute__ ((packed));
+
+struct country_triplet {
+ u8 channel;
+ u8 num_channels;
+ u8 max_tx_power;
+} __attribute__ ((packed));
+
+struct wl12xx_ie_country {
+ struct wl12xx_ie_header header;
+ u8 country_string[COUNTRY_STRING_LEN];
+ struct country_triplet triplets[MAX_COUNTRY_TRIPLETS];
+} __attribute__ ((packed));
+
+
+/* Templates */
+
+struct wl12xx_beacon_template {
+ struct ieee80211_header header;
+ __le32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ struct wl12xx_ie_ssid ssid;
+ struct wl12xx_ie_rates rates;
+ struct wl12xx_ie_rates ext_rates;
+ struct wl12xx_ie_ds_params ds_params;
+ struct wl12xx_ie_country country;
+} __attribute__ ((packed));
+
+struct wl12xx_null_data_template {
+ struct ieee80211_header header;
+} __attribute__ ((packed));
+
+struct wl12xx_ps_poll_template {
+ u16 fc;
+ u16 aid;
+ u8 bssid[ETH_ALEN];
+ u8 ta[ETH_ALEN];
+} __attribute__ ((packed));
+
+struct wl12xx_qos_null_data_template {
+ struct ieee80211_header header;
+ __le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct wl12xx_probe_req_template {
+ struct ieee80211_header header;
+ struct wl12xx_ie_ssid ssid;
+ struct wl12xx_ie_rates rates;
+ struct wl12xx_ie_rates ext_rates;
+} __attribute__ ((packed));
+
+
+struct wl12xx_probe_resp_template {
+ struct ieee80211_header header;
+ __le32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ struct wl12xx_ie_ssid ssid;
+ struct wl12xx_ie_rates rates;
+ struct wl12xx_ie_rates ext_rates;
+ struct wl12xx_ie_ds_params ds_params;
+ struct wl12xx_ie_country country;
+} __attribute__ ((packed));
+
+#endif
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index c3a51266de20..6bdb1704083b 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -755,52 +755,6 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
}
-static int zd_op_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct zd_mac *mac = zd_hw_mac(hw);
- int associated;
- int r;
-
- if (mac->type == NL80211_IFTYPE_MESH_POINT ||
- mac->type == NL80211_IFTYPE_ADHOC) {
- associated = true;
- if (conf->changed & IEEE80211_IFCC_BEACON) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
-
- if (!beacon)
- return -ENOMEM;
- r = zd_mac_config_beacon(hw, beacon);
- kfree_skb(beacon);
-
- if (r < 0)
- return r;
- }
-
- if (conf->changed & IEEE80211_IFCC_BEACON_ENABLED) {
- u32 interval;
-
- if (conf->enable_beacon)
- interval = BCN_MODE_IBSS | hw->conf.beacon_int;
- else
- interval = 0;
-
- r = zd_set_beacon_interval(&mac->chip, interval);
- if (r < 0)
- return r;
- }
- } else
- associated = is_valid_ether_addr(conf->bssid);
-
- spin_lock_irq(&mac->lock);
- mac->associated = associated;
- spin_unlock_irq(&mac->lock);
-
- /* TODO: do hardware bssid filtering */
- return 0;
-}
-
static void zd_process_intr(struct work_struct *work)
{
u16 int_status;
@@ -923,9 +877,42 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
{
struct zd_mac *mac = zd_hw_mac(hw);
unsigned long flags;
+ int associated;
dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
+ if (mac->type == NL80211_IFTYPE_MESH_POINT ||
+ mac->type == NL80211_IFTYPE_ADHOC) {
+ associated = true;
+ if (changes & BSS_CHANGED_BEACON) {
+ struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+
+ if (beacon) {
+ zd_mac_config_beacon(hw, beacon);
+ kfree_skb(beacon);
+ }
+ }
+
+ if (changes & BSS_CHANGED_BEACON_ENABLED) {
+ u32 interval;
+
+ if (bss_conf->enable_beacon)
+ interval = BCN_MODE_IBSS |
+ bss_conf->beacon_int;
+ else
+ interval = 0;
+
+ zd_set_beacon_interval(&mac->chip, interval);
+ }
+ } else
+ associated = is_valid_ether_addr(bss_conf->bssid);
+
+ spin_lock_irq(&mac->lock);
+ mac->associated = associated;
+ spin_unlock_irq(&mac->lock);
+
+ /* TODO: do hardware bssid filtering */
+
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
spin_lock_irqsave(&mac->lock, flags);
mac->short_preamble = bss_conf->use_short_preamble;
@@ -952,7 +939,6 @@ static const struct ieee80211_ops zd_ops = {
.add_interface = zd_op_add_interface,
.remove_interface = zd_op_remove_interface,
.config = zd_op_config,
- .config_interface = zd_op_config_interface,
.configure_filter = zd_op_configure_filter,
.bss_info_changed = zd_op_bss_info_changed,
.get_tsf = zd_op_get_tsf,
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index f821dbc952a4..6fe043bd3770 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -19,3 +19,9 @@ config OF_SPI
depends on OF && PPC_OF && SPI
help
OpenFirmware SPI accessors
+
+config OF_MDIO
+ def_tristate PHYLIB
+ depends on OF && PHYLIB
+ help
+ OpenFirmware MDIO bus (Ethernet PHY) accessors
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 4c3c6f8e36f5..bdfb5f5d4b06 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_OF_DEVICE) += device.o platform.o
obj-$(CONFIG_OF_GPIO) += gpio.o
obj-$(CONFIG_OF_I2C) += of_i2c.o
obj-$(CONFIG_OF_SPI) += of_spi.o
+obj-$(CONFIG_OF_MDIO) += of_mdio.o
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 41c5dfd85358..69f85c07d17f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -447,6 +447,7 @@ struct of_modalias_table {
static struct of_modalias_table of_modalias_table[] = {
{ "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
{ "mmc-spi-slot", "mmc_spi" },
+ { "stm,m25p40", "m25p80" },
};
/**
@@ -495,6 +496,30 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
EXPORT_SYMBOL_GPL(of_modalias_node);
/**
+ * of_parse_phandle - Resolve a phandle property to a device_node pointer
+ * @np: Pointer to device node holding phandle property
+ * @phandle_name: Name of property holding a phandle value
+ * @index: For properties holding a table of phandles, this is the index into
+ * the table
+ *
+ * Returns the device_node pointer with refcount incremented. Use
+ * of_node_put() on it when done.
+ */
+struct device_node *
+of_parse_phandle(struct device_node *np, const char *phandle_name, int index)
+{
+ const phandle *phandle;
+ int size;
+
+ phandle = of_get_property(np, phandle_name, &size);
+ if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
+ return NULL;
+
+ return of_find_node_by_phandle(phandle[index]);
+}
+EXPORT_SYMBOL(of_parse_phandle);
+
+/**
* of_parse_phandles_with_args - Find a node pointed by phandle in a list
* @np: pointer to a device tree node containing a list
* @list_name: property name that contains a list
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
new file mode 100644
index 000000000000..aee967d7f760
--- /dev/null
+++ b/drivers/of/of_mdio.c
@@ -0,0 +1,139 @@
+/*
+ * OF helpers for the MDIO (Ethernet PHY) API
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ *
+ * This file is released under the GPLv2
+ *
+ * This file provides helper functions for extracting PHY device information
+ * out of the OpenFirmware device tree and using it to populate an mii_bus.
+ */
+
+#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
+MODULE_LICENSE("GPL");
+
+/**
+ * of_mdiobus_register - Register mii_bus and create PHYs from the device tree
+ * @mdio: pointer to mii_bus structure
+ * @np: pointer to device_node of MDIO bus.
+ *
+ * This function registers the mii_bus structure and registers a phy_device
+ * for each child node of @np.
+ */
+int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
+{
+ struct phy_device *phy;
+ struct device_node *child;
+ int rc, i;
+
+ /* Mask out all PHYs from auto probing. Instead the PHYs listed in
+ * the device tree are populated after the bus has been registered */
+ mdio->phy_mask = ~0;
+
+ /* Clear all the IRQ properties */
+ if (mdio->irq)
+ for (i=0; i<PHY_MAX_ADDR; i++)
+ mdio->irq[i] = PHY_POLL;
+
+ /* Register the MDIO bus */
+ rc = mdiobus_register(mdio);
+ if (rc)
+ return rc;
+
+ /* Loop over the child nodes and register a phy_device for each one */
+ for_each_child_of_node(np, child) {
+ const u32 *addr;
+ int len;
+
+ /* A PHY must have a reg property in the range [0-31] */
+ addr = of_get_property(child, "reg", &len);
+ if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) {
+ dev_err(&mdio->dev, "%s has invalid PHY address\n",
+ child->full_name);
+ continue;
+ }
+
+ if (mdio->irq) {
+ mdio->irq[*addr] = irq_of_parse_and_map(child, 0);
+ if (!mdio->irq[*addr])
+ mdio->irq[*addr] = PHY_POLL;
+ }
+
+ phy = get_phy_device(mdio, *addr);
+ if (!phy) {
+ dev_err(&mdio->dev, "error probing PHY at address %i\n",
+ *addr);
+ continue;
+ }
+ phy_scan_fixups(phy);
+
+ /* Associate the OF node with the device structure so it
+ * can be looked up later */
+ of_node_get(child);
+ dev_archdata_set_node(&phy->dev.archdata, child);
+
+ /* All data is now stored in the phy struct; register it */
+ rc = phy_device_register(phy);
+ if (rc) {
+ phy_device_free(phy);
+ of_node_put(child);
+ continue;
+ }
+
+ dev_dbg(&mdio->dev, "registered phy %s at address %i\n",
+ child->name, *addr);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(of_mdiobus_register);
+
+/**
+ * of_phy_find_device - Give a PHY node, find the phy_device
+ * @phy_np: Pointer to the phy's device tree node
+ *
+ * Returns a pointer to the phy_device.
+ */
+struct phy_device *of_phy_find_device(struct device_node *phy_np)
+{
+ struct device *d;
+ int match(struct device *dev, void *phy_np)
+ {
+ return dev_archdata_get_node(&dev->archdata) == phy_np;
+ }
+
+ if (!phy_np)
+ return NULL;
+
+ d = bus_find_device(&mdio_bus_type, NULL, phy_np, match);
+ return d ? to_phy_device(d) : NULL;
+}
+EXPORT_SYMBOL(of_phy_find_device);
+
+/**
+ * of_phy_connect - Connect to the phy described in the device tree
+ * @dev: pointer to net_device claiming the phy
+ * @phy_np: Pointer to device tree node for the PHY
+ * @hndlr: Link state callback for the network device
+ * @iface: PHY data interface type
+ *
+ * Returns a pointer to the phy_device if successfull. NULL otherwise
+ */
+struct phy_device *of_phy_connect(struct net_device *dev,
+ struct device_node *phy_np,
+ void (*hndlr)(struct net_device *), u32 flags,
+ phy_interface_t iface)
+{
+ struct phy_device *phy = of_phy_find_device(phy_np);
+
+ if (!phy)
+ return NULL;
+
+ return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy;
+}
+EXPORT_SYMBOL(of_phy_connect);
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index f0e99d4c066b..242257b19441 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -78,16 +78,20 @@ void free_cpu_buffers(void)
op_ring_buffer_write = NULL;
}
+#define RB_EVENT_HDR_SIZE 4
+
int alloc_cpu_buffers(void)
{
int i;
unsigned long buffer_size = oprofile_cpu_buffer_size;
+ unsigned long byte_size = buffer_size * (sizeof(struct op_sample) +
+ RB_EVENT_HDR_SIZE);
- op_ring_buffer_read = ring_buffer_alloc(buffer_size, OP_BUFFER_FLAGS);
+ op_ring_buffer_read = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
if (!op_ring_buffer_read)
goto fail;
- op_ring_buffer_write = ring_buffer_alloc(buffer_size, OP_BUFFER_FLAGS);
+ op_ring_buffer_write = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
if (!op_ring_buffer_write)
goto fail;
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 73348c4047e9..4a9cc92d4d18 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -702,7 +702,7 @@ static unsigned int iosapic_startup_irq(unsigned int irq)
}
#ifdef CONFIG_SMP
-static void iosapic_set_affinity_irq(unsigned int irq,
+static int iosapic_set_affinity_irq(unsigned int irq,
const struct cpumask *dest)
{
struct vector_info *vi = iosapic_get_vector(irq);
@@ -712,7 +712,7 @@ static void iosapic_set_affinity_irq(unsigned int irq,
dest_cpu = cpu_check_affinity(irq, dest);
if (dest_cpu < 0)
- return;
+ return -1;
cpumask_copy(irq_desc[irq].affinity, cpumask_of(dest_cpu));
vi->txn_addr = txn_affinity_addr(irq, dest_cpu);
@@ -724,6 +724,8 @@ static void iosapic_set_affinity_irq(unsigned int irq,
iosapic_set_irt_data(vi, &dummy_d0, &d1);
iosapic_wr_irt_entry(vi, d0, d1);
spin_unlock_irqrestore(&iosapic_lock, flags);
+
+ return 0;
}
#endif
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 97a8194063b5..40af27f31043 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -41,9 +41,14 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
void *alignf_data)
{
int i, ret = -ENOMEM;
+ resource_size_t max = -1;
type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
+ /* don't allocate too high if the pref mem doesn't support 64bit*/
+ if (!(res->flags & IORESOURCE_MEM_64))
+ max = PCIBIOS_MAX_MEM_32;
+
for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
struct resource *r = bus->resource[i];
if (!r)
@@ -62,7 +67,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
/* Ok, try it out.. */
ret = allocate_resource(r, res, size,
r->start ? : min,
- -1, align,
+ max, align,
alignf, alignf_data);
if (ret == 0)
break;
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index fa3a11365ec3..faf77a00cafe 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -515,6 +515,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
u32 ver;
static int iommu_allocated = 0;
int agaw = 0;
+ int msagaw = 0;
iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
if (!iommu)
@@ -535,12 +536,20 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
agaw = iommu_calculate_agaw(iommu);
if (agaw < 0) {
printk(KERN_ERR
- "Cannot get a valid agaw for iommu (seq_id = %d)\n",
+ "Cannot get a valid agaw for iommu (seq_id = %d)\n",
+ iommu->seq_id);
+ goto error;
+ }
+ msagaw = iommu_calculate_max_sagaw(iommu);
+ if (msagaw < 0) {
+ printk(KERN_ERR
+ "Cannot get a valid max agaw for iommu (seq_id = %d)\n",
iommu->seq_id);
goto error;
}
#endif
iommu->agaw = agaw;
+ iommu->msagaw = msagaw;
/* the registers might be more than one page */
map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
@@ -714,41 +723,26 @@ void qi_global_iec(struct intel_iommu *iommu)
qi_submit_sync(&desc, iommu);
}
-int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
- u64 type, int non_present_entry_flush)
+void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
+ u64 type)
{
struct qi_desc desc;
- if (non_present_entry_flush) {
- if (!cap_caching_mode(iommu->cap))
- return 1;
- else
- did = 0;
- }
-
desc.low = QI_CC_FM(fm) | QI_CC_SID(sid) | QI_CC_DID(did)
| QI_CC_GRAN(type) | QI_CC_TYPE;
desc.high = 0;
- return qi_submit_sync(&desc, iommu);
+ qi_submit_sync(&desc, iommu);
}
-int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
- unsigned int size_order, u64 type,
- int non_present_entry_flush)
+void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
+ unsigned int size_order, u64 type)
{
u8 dw = 0, dr = 0;
struct qi_desc desc;
int ih = 0;
- if (non_present_entry_flush) {
- if (!cap_caching_mode(iommu->cap))
- return 1;
- else
- did = 0;
- }
-
if (cap_write_drain(iommu->cap))
dw = 1;
@@ -760,7 +754,7 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih)
| QI_IOTLB_AM(size_order);
- return qi_submit_sync(&desc, iommu);
+ qi_submit_sync(&desc, iommu);
}
/*
@@ -790,7 +784,6 @@ void dmar_disable_qi(struct intel_iommu *iommu)
cpu_relax();
iommu->gcmd &= ~DMA_GCMD_QIE;
-
writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl,
@@ -804,7 +797,7 @@ end:
*/
static void __dmar_enable_qi(struct intel_iommu *iommu)
{
- u32 cmd, sts;
+ u32 sts;
unsigned long flags;
struct q_inval *qi = iommu->qi;
@@ -818,9 +811,8 @@ static void __dmar_enable_qi(struct intel_iommu *iommu)
dmar_writeq(iommu->reg + DMAR_IQA_REG, virt_to_phys(qi->desc));
- cmd = iommu->gcmd | DMA_GCMD_QIE;
iommu->gcmd |= DMA_GCMD_QIE;
- writel(cmd, iommu->reg + DMAR_GCMD_REG);
+ writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
/* Make sure hardware complete it */
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts);
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index 9aa4fe100a0d..ac888ccfa161 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -41,7 +41,7 @@ config HOTPLUG_PCI_FAKE
config HOTPLUG_PCI_COMPAQ
tristate "Compaq PCI Hotplug driver"
- depends on X86 && PCI_BIOS && PCI_LEGACY
+ depends on X86 && PCI_BIOS
help
Say Y here if you have a motherboard with a Compaq PCI Hotplug
controller.
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
index afaf8f69f73e..53836001d511 100644
--- a/drivers/pci/hotplug/cpqphp.h
+++ b/drivers/pci/hotplug/cpqphp.h
@@ -150,25 +150,25 @@ struct ctrl_reg { /* offset */
/* offsets to the controller registers based on the above structure layout */
enum ctrl_offsets {
- SLOT_RST = offsetof(struct ctrl_reg, slot_RST),
+ SLOT_RST = offsetof(struct ctrl_reg, slot_RST),
SLOT_ENABLE = offsetof(struct ctrl_reg, slot_enable),
MISC = offsetof(struct ctrl_reg, misc),
LED_CONTROL = offsetof(struct ctrl_reg, led_control),
INT_INPUT_CLEAR = offsetof(struct ctrl_reg, int_input_clear),
- INT_MASK = offsetof(struct ctrl_reg, int_mask),
- CTRL_RESERVED0 = offsetof(struct ctrl_reg, reserved0),
+ INT_MASK = offsetof(struct ctrl_reg, int_mask),
+ CTRL_RESERVED0 = offsetof(struct ctrl_reg, reserved0),
CTRL_RESERVED1 = offsetof(struct ctrl_reg, reserved1),
CTRL_RESERVED2 = offsetof(struct ctrl_reg, reserved1),
- GEN_OUTPUT_AB = offsetof(struct ctrl_reg, gen_output_AB),
- NON_INT_INPUT = offsetof(struct ctrl_reg, non_int_input),
+ GEN_OUTPUT_AB = offsetof(struct ctrl_reg, gen_output_AB),
+ NON_INT_INPUT = offsetof(struct ctrl_reg, non_int_input),
CTRL_RESERVED3 = offsetof(struct ctrl_reg, reserved3),
CTRL_RESERVED4 = offsetof(struct ctrl_reg, reserved4),
CTRL_RESERVED5 = offsetof(struct ctrl_reg, reserved5),
CTRL_RESERVED6 = offsetof(struct ctrl_reg, reserved6),
CTRL_RESERVED7 = offsetof(struct ctrl_reg, reserved7),
CTRL_RESERVED8 = offsetof(struct ctrl_reg, reserved8),
- SLOT_MASK = offsetof(struct ctrl_reg, slot_mask),
- CTRL_RESERVED9 = offsetof(struct ctrl_reg, reserved9),
+ SLOT_MASK = offsetof(struct ctrl_reg, slot_mask),
+ CTRL_RESERVED9 = offsetof(struct ctrl_reg, reserved9),
CTRL_RESERVED10 = offsetof(struct ctrl_reg, reserved10),
CTRL_RESERVED11 = offsetof(struct ctrl_reg, reserved11),
SLOT_SERR = offsetof(struct ctrl_reg, slot_SERR),
@@ -190,7 +190,9 @@ struct hrt {
u32 reserved2;
} __attribute__ ((packed));
-/* offsets to the hotplug resource table registers based on the above structure layout */
+/* offsets to the hotplug resource table registers based on the above
+ * structure layout
+ */
enum hrt_offsets {
SIG0 = offsetof(struct hrt, sig0),
SIG1 = offsetof(struct hrt, sig1),
@@ -217,18 +219,20 @@ struct slot_rt {
u16 pre_mem_length;
} __attribute__ ((packed));
-/* offsets to the hotplug slot resource table registers based on the above structure layout */
+/* offsets to the hotplug slot resource table registers based on the above
+ * structure layout
+ */
enum slot_rt_offsets {
DEV_FUNC = offsetof(struct slot_rt, dev_func),
- PRIMARY_BUS = offsetof(struct slot_rt, primary_bus),
- SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus),
- MAX_BUS = offsetof(struct slot_rt, max_bus),
- IO_BASE = offsetof(struct slot_rt, io_base),
- IO_LENGTH = offsetof(struct slot_rt, io_length),
- MEM_BASE = offsetof(struct slot_rt, mem_base),
- MEM_LENGTH = offsetof(struct slot_rt, mem_length),
- PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base),
- PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length),
+ PRIMARY_BUS = offsetof(struct slot_rt, primary_bus),
+ SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus),
+ MAX_BUS = offsetof(struct slot_rt, max_bus),
+ IO_BASE = offsetof(struct slot_rt, io_base),
+ IO_LENGTH = offsetof(struct slot_rt, io_length),
+ MEM_BASE = offsetof(struct slot_rt, mem_base),
+ MEM_LENGTH = offsetof(struct slot_rt, mem_length),
+ PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base),
+ PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length),
};
struct pci_func {
@@ -286,8 +290,8 @@ struct event_info {
struct controller {
struct controller *next;
u32 ctrl_int_comp;
- struct mutex crit_sect; /* critical section mutex */
- void __iomem *hpc_reg; /* cookie for our pci controller location */
+ struct mutex crit_sect; /* critical section mutex */
+ void __iomem *hpc_reg; /* cookie for our pci controller location */
struct pci_resource *mem_head;
struct pci_resource *p_mem_head;
struct pci_resource *io_head;
@@ -299,7 +303,7 @@ struct controller {
u8 next_event;
u8 interrupt;
u8 cfgspc_irq;
- u8 bus; /* bus number for the pci hotplug controller */
+ u8 bus; /* bus number for the pci hotplug controller */
u8 rev;
u8 slot_device_offset;
u8 first_slot;
@@ -401,46 +405,57 @@ struct resource_lists {
/* debugfs functions for the hotplug controller info */
-extern void cpqhp_initialize_debugfs (void);
-extern void cpqhp_shutdown_debugfs (void);
-extern void cpqhp_create_debugfs_files (struct controller *ctrl);
-extern void cpqhp_remove_debugfs_files (struct controller *ctrl);
+extern void cpqhp_initialize_debugfs(void);
+extern void cpqhp_shutdown_debugfs(void);
+extern void cpqhp_create_debugfs_files(struct controller *ctrl);
+extern void cpqhp_remove_debugfs_files(struct controller *ctrl);
/* controller functions */
-extern void cpqhp_pushbutton_thread (unsigned long event_pointer);
-extern irqreturn_t cpqhp_ctrl_intr (int IRQ, void *data);
-extern int cpqhp_find_available_resources (struct controller *ctrl, void __iomem *rom_start);
-extern int cpqhp_event_start_thread (void);
-extern void cpqhp_event_stop_thread (void);
-extern struct pci_func *cpqhp_slot_create (unsigned char busnumber);
-extern struct pci_func *cpqhp_slot_find (unsigned char bus, unsigned char device, unsigned char index);
-extern int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func);
-extern int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func);
-extern int cpqhp_hardware_test (struct controller *ctrl, int test_num);
+extern void cpqhp_pushbutton_thread(unsigned long event_pointer);
+extern irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data);
+extern int cpqhp_find_available_resources(struct controller *ctrl,
+ void __iomem *rom_start);
+extern int cpqhp_event_start_thread(void);
+extern void cpqhp_event_stop_thread(void);
+extern struct pci_func *cpqhp_slot_create(unsigned char busnumber);
+extern struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device,
+ unsigned char index);
+extern int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func);
+extern int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func);
+extern int cpqhp_hardware_test(struct controller *ctrl, int test_num);
/* resource functions */
extern int cpqhp_resource_sort_and_combine (struct pci_resource **head);
/* pci functions */
-extern int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
-extern int cpqhp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot);
-extern int cpqhp_save_config (struct controller *ctrl, int busnumber, int is_hot_plug);
-extern int cpqhp_save_base_addr_length (struct controller *ctrl, struct pci_func * func);
-extern int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func);
-extern int cpqhp_configure_board (struct controller *ctrl, struct pci_func * func);
-extern int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot);
-extern int cpqhp_valid_replace (struct controller *ctrl, struct pci_func * func);
-extern void cpqhp_destroy_board_resources (struct pci_func * func);
-extern int cpqhp_return_board_resources (struct pci_func * func, struct resource_lists * resources);
-extern void cpqhp_destroy_resource_list (struct resource_lists * resources);
-extern int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func);
-extern int cpqhp_unconfigure_device (struct pci_func* func);
+extern int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
+extern int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num,
+ u8 slot);
+extern int cpqhp_save_config(struct controller *ctrl, int busnumber,
+ int is_hot_plug);
+extern int cpqhp_save_base_addr_length(struct controller *ctrl,
+ struct pci_func *func);
+extern int cpqhp_save_used_resources(struct controller *ctrl,
+ struct pci_func *func);
+extern int cpqhp_configure_board(struct controller *ctrl,
+ struct pci_func *func);
+extern int cpqhp_save_slot_config(struct controller *ctrl,
+ struct pci_func *new_slot);
+extern int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func);
+extern void cpqhp_destroy_board_resources(struct pci_func *func);
+extern int cpqhp_return_board_resources (struct pci_func *func,
+ struct resource_lists *resources);
+extern void cpqhp_destroy_resource_list(struct resource_lists *resources);
+extern int cpqhp_configure_device(struct controller *ctrl,
+ struct pci_func *func);
+extern int cpqhp_unconfigure_device(struct pci_func *func);
/* Global variables */
extern int cpqhp_debug;
extern int cpqhp_legacy_mode;
extern struct controller *cpqhp_ctrl_list;
extern struct pci_func *cpqhp_slot_list[256];
+extern struct irq_routing_table *cpqhp_routing_table;
/* these can be gotten rid of, but for debugging they are purty */
extern u8 cpqhp_nic_irq;
@@ -449,7 +464,7 @@ extern u8 cpqhp_disk_irq;
/* inline functions */
-static inline char *slot_name(struct slot *slot)
+static inline const char *slot_name(struct slot *slot)
{
return hotplug_slot_name(slot->hotplug_slot);
}
@@ -458,9 +473,9 @@ static inline char *slot_name(struct slot *slot)
* return_resource
*
* Puts node back in the resource list pointed to by head
- *
*/
-static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
+static inline void return_resource(struct pci_resource **head,
+ struct pci_resource *node)
{
if (!node || !head)
return;
@@ -471,7 +486,7 @@ static inline void return_resource(struct pci_resource **head, struct pci_resour
static inline void set_SOGO(struct controller *ctrl)
{
u16 misc;
-
+
misc = readw(ctrl->hpc_reg + MISC);
misc = (misc | 0x0001) & 0xFFFB;
writew(misc, ctrl->hpc_reg + MISC);
@@ -481,7 +496,7 @@ static inline void set_SOGO(struct controller *ctrl)
static inline void amber_LED_on(struct controller *ctrl, u8 slot)
{
u32 led_control;
-
+
led_control = readl(ctrl->hpc_reg + LED_CONTROL);
led_control |= (0x01010000L << slot);
writel(led_control, ctrl->hpc_reg + LED_CONTROL);
@@ -491,7 +506,7 @@ static inline void amber_LED_on(struct controller *ctrl, u8 slot)
static inline void amber_LED_off(struct controller *ctrl, u8 slot)
{
u32 led_control;
-
+
led_control = readl(ctrl->hpc_reg + LED_CONTROL);
led_control &= ~(0x01010000L << slot);
writel(led_control, ctrl->hpc_reg + LED_CONTROL);
@@ -504,7 +519,7 @@ static inline int read_amber_LED(struct controller *ctrl, u8 slot)
led_control = readl(ctrl->hpc_reg + LED_CONTROL);
led_control &= (0x01010000L << slot);
-
+
return led_control ? 1 : 0;
}
@@ -512,7 +527,7 @@ static inline int read_amber_LED(struct controller *ctrl, u8 slot)
static inline void green_LED_on(struct controller *ctrl, u8 slot)
{
u32 led_control;
-
+
led_control = readl(ctrl->hpc_reg + LED_CONTROL);
led_control |= 0x0101L << slot;
writel(led_control, ctrl->hpc_reg + LED_CONTROL);
@@ -521,7 +536,7 @@ static inline void green_LED_on(struct controller *ctrl, u8 slot)
static inline void green_LED_off(struct controller *ctrl, u8 slot)
{
u32 led_control;
-
+
led_control = readl(ctrl->hpc_reg + LED_CONTROL);
led_control &= ~(0x0101L << slot);
writel(led_control, ctrl->hpc_reg + LED_CONTROL);
@@ -531,7 +546,7 @@ static inline void green_LED_off(struct controller *ctrl, u8 slot)
static inline void green_LED_blink(struct controller *ctrl, u8 slot)
{
u32 led_control;
-
+
led_control = readl(ctrl->hpc_reg + LED_CONTROL);
led_control &= ~(0x0101L << slot);
led_control |= (0x0001L << slot);
@@ -575,22 +590,21 @@ static inline u8 read_slot_enable(struct controller *ctrl)
}
-/*
+/**
* get_controller_speed - find the current frequency/mode of controller.
*
* @ctrl: controller to get frequency/mode for.
*
* Returns controller speed.
- *
*/
static inline u8 get_controller_speed(struct controller *ctrl)
{
u8 curr_freq;
- u16 misc;
-
+ u16 misc;
+
if (ctrl->pcix_support) {
curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);
- if ((curr_freq & 0xB0) == 0xB0)
+ if ((curr_freq & 0xB0) == 0xB0)
return PCI_SPEED_133MHz_PCIX;
if ((curr_freq & 0xA0) == 0xA0)
return PCI_SPEED_100MHz_PCIX;
@@ -602,19 +616,18 @@ static inline u8 get_controller_speed(struct controller *ctrl)
return PCI_SPEED_33MHz;
}
- misc = readw(ctrl->hpc_reg + MISC);
- return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
+ misc = readw(ctrl->hpc_reg + MISC);
+ return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
}
-
-/*
+
+/**
* get_adapter_speed - find the max supported frequency/mode of adapter.
*
* @ctrl: hotplug controller.
* @hp_slot: hotplug slot where adapter is installed.
*
* Returns adapter speed.
- *
*/
static inline u8 get_adapter_speed(struct controller *ctrl, u8 hp_slot)
{
@@ -672,7 +685,8 @@ static inline int get_slot_enabled(struct controller *ctrl, struct slot *slot)
}
-static inline int cpq_get_latch_status(struct controller *ctrl, struct slot *slot)
+static inline int cpq_get_latch_status(struct controller *ctrl,
+ struct slot *slot)
{
u32 status;
u8 hp_slot;
@@ -687,7 +701,8 @@ static inline int cpq_get_latch_status(struct controller *ctrl, struct slot *slo
}
-static inline int get_presence_status(struct controller *ctrl, struct slot *slot)
+static inline int get_presence_status(struct controller *ctrl,
+ struct slot *slot)
{
int presence_save = 0;
u8 hp_slot;
@@ -696,7 +711,8 @@ static inline int get_presence_status(struct controller *ctrl, struct slot *slot
hp_slot = slot->device - ctrl->slot_device_offset;
tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
- presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> hp_slot) & 0x02;
+ presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15))
+ >> hp_slot) & 0x02;
return presence_save;
}
@@ -718,5 +734,12 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
return retval;
}
-#endif
+#include <asm/pci_x86.h>
+static inline int cpqhp_routing_table_length(void)
+{
+ BUG_ON(cpqhp_routing_table == NULL);
+ return ((cpqhp_routing_table->size - sizeof(struct irq_routing_table)) /
+ sizeof(struct irq_info));
+}
+#endif
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index c2e1bcbb28a7..7888b37c6c8e 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -25,8 +25,7 @@
* Send feedback to <greg@kroah.com>
*
* Jan 12, 2003 - Added 66/100/133MHz PCI-X support,
- * Torben Mathiasen <torben.mathiasen@hp.com>
- *
+ * Torben Mathiasen <torben.mathiasen@hp.com>
*/
#include <linux/module.h>
@@ -45,7 +44,6 @@
#include "cpqphp.h"
#include "cpqphp_nvram.h"
-#include <asm/pci_x86.h>
/* Global variables */
@@ -53,6 +51,7 @@ int cpqhp_debug;
int cpqhp_legacy_mode;
struct controller *cpqhp_ctrl_list; /* = NULL */
struct pci_func *cpqhp_slot_list[256];
+struct irq_routing_table *cpqhp_routing_table;
/* local variables */
static void __iomem *smbios_table;
@@ -78,33 +77,6 @@ MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
#define CPQHPC_MODULE_MINOR 208
-static int one_time_init (void);
-static int set_attention_status (struct hotplug_slot *slot, u8 value);
-static int process_SI (struct hotplug_slot *slot);
-static int process_SS (struct hotplug_slot *slot);
-static int hardware_test (struct hotplug_slot *slot, u32 value);
-static int get_power_status (struct hotplug_slot *slot, u8 *value);
-static int get_attention_status (struct hotplug_slot *slot, u8 *value);
-static int get_latch_status (struct hotplug_slot *slot, u8 *value);
-static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
-static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
-static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
-
-static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
- .owner = THIS_MODULE,
- .set_attention_status = set_attention_status,
- .enable_slot = process_SI,
- .disable_slot = process_SS,
- .hardware_test = hardware_test,
- .get_power_status = get_power_status,
- .get_attention_status = get_attention_status,
- .get_latch_status = get_latch_status,
- .get_adapter_status = get_adapter_status,
- .get_max_bus_speed = get_max_bus_speed,
- .get_cur_bus_speed = get_cur_bus_speed,
-};
-
-
static inline int is_slot64bit(struct slot *slot)
{
return (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06) ? 1 : 0;
@@ -144,7 +116,7 @@ static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *e
break;
}
}
-
+
if (!status)
fp = NULL;
@@ -171,7 +143,7 @@ static int init_SERR(struct controller * ctrl)
tempdword = ctrl->first_slot;
number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
- // Loop through slots
+ /* Loop through slots */
while (number_of_slots) {
physical_slot = tempdword;
writeb(0, ctrl->hpc_reg + SLOT_SERR);
@@ -182,41 +154,42 @@ static int init_SERR(struct controller * ctrl)
return 0;
}
-
-/* nice debugging output */
-static int pci_print_IRQ_route (void)
+static int init_cpqhp_routing_table(void)
{
- struct irq_routing_table *routing_table;
int len;
- int loop;
- u8 tbus, tdevice, tslot;
-
- routing_table = pcibios_get_irq_routing_table();
- if (routing_table == NULL) {
- err("No BIOS Routing Table??? Not good\n");
+ cpqhp_routing_table = pcibios_get_irq_routing_table();
+ if (cpqhp_routing_table == NULL)
return -ENOMEM;
- }
- len = (routing_table->size - sizeof(struct irq_routing_table)) /
- sizeof(struct irq_info);
- // Make sure I got at least one entry
+ len = cpqhp_routing_table_length();
if (len == 0) {
- kfree(routing_table);
+ kfree(cpqhp_routing_table);
+ cpqhp_routing_table = NULL;
return -1;
}
- dbg("bus dev func slot\n");
+ return 0;
+}
+/* nice debugging output */
+static void pci_print_IRQ_route(void)
+{
+ int len;
+ int loop;
+ u8 tbus, tdevice, tslot;
+
+ len = cpqhp_routing_table_length();
+
+ dbg("bus dev func slot\n");
for (loop = 0; loop < len; ++loop) {
- tbus = routing_table->slots[loop].bus;
- tdevice = routing_table->slots[loop].devfn;
- tslot = routing_table->slots[loop].slot;
+ tbus = cpqhp_routing_table->slots[loop].bus;
+ tdevice = cpqhp_routing_table->slots[loop].devfn;
+ tslot = cpqhp_routing_table->slots[loop].slot;
dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
}
- kfree(routing_table);
- return 0;
+ return;
}
@@ -242,9 +215,9 @@ static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
void __iomem *p_max;
if (!smbios_table || !curr)
- return(NULL);
+ return NULL;
- // set p_max to the end of the table
+ /* set p_max to the end of the table */
p_max = smbios_start + readw(smbios_table + ST_LENGTH);
p_temp = curr;
@@ -253,20 +226,19 @@ static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
while ((p_temp < p_max) && !bail) {
/* Look for the double NULL terminator
* The first condition is the previous byte
- * and the second is the curr */
- if (!previous_byte && !(readb(p_temp))) {
+ * and the second is the curr
+ */
+ if (!previous_byte && !(readb(p_temp)))
bail = 1;
- }
previous_byte = readb(p_temp);
p_temp++;
}
- if (p_temp < p_max) {
+ if (p_temp < p_max)
return p_temp;
- } else {
+ else
return NULL;
- }
}
@@ -292,21 +264,18 @@ static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start,
if (!smbios_table)
return NULL;
- if (!previous) {
+ if (!previous)
previous = smbios_start;
- } else {
+ else
previous = get_subsequent_smbios_entry(smbios_start,
smbios_table, previous);
- }
- while (previous) {
- if (readb(previous + SMBIOS_GENERIC_TYPE) != type) {
+ while (previous)
+ if (readb(previous + SMBIOS_GENERIC_TYPE) != type)
previous = get_subsequent_smbios_entry(smbios_start,
smbios_table, previous);
- } else {
+ else
break;
- }
- }
return previous;
}
@@ -322,144 +291,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
kfree(slot);
}
-#define SLOT_NAME_SIZE 10
-
-static int ctrl_slot_setup(struct controller *ctrl,
- void __iomem *smbios_start,
- void __iomem *smbios_table)
-{
- struct slot *slot;
- struct hotplug_slot *hotplug_slot;
- struct hotplug_slot_info *hotplug_slot_info;
- u8 number_of_slots;
- u8 slot_device;
- u8 slot_number;
- u8 ctrl_slot;
- u32 tempdword;
- char name[SLOT_NAME_SIZE];
- void __iomem *slot_entry= NULL;
- int result = -ENOMEM;
-
- dbg("%s\n", __func__);
-
- tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-
- number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
- slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
- slot_number = ctrl->first_slot;
-
- while (number_of_slots) {
- slot = kzalloc(sizeof(*slot), GFP_KERNEL);
- if (!slot)
- goto error;
-
- slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)),
- GFP_KERNEL);
- if (!slot->hotplug_slot)
- goto error_slot;
- hotplug_slot = slot->hotplug_slot;
-
- hotplug_slot->info =
- kzalloc(sizeof(*(hotplug_slot->info)),
- GFP_KERNEL);
- if (!hotplug_slot->info)
- goto error_hpslot;
- hotplug_slot_info = hotplug_slot->info;
-
- slot->ctrl = ctrl;
- slot->bus = ctrl->bus;
- slot->device = slot_device;
- slot->number = slot_number;
- dbg("slot->number = %u\n", slot->number);
-
- slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
- slot_entry);
-
- while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) !=
- slot->number)) {
- slot_entry = get_SMBIOS_entry(smbios_start,
- smbios_table, 9, slot_entry);
- }
-
- slot->p_sm_slot = slot_entry;
-
- init_timer(&slot->task_event);
- slot->task_event.expires = jiffies + 5 * HZ;
- slot->task_event.function = cpqhp_pushbutton_thread;
-
- //FIXME: these capabilities aren't used but if they are
- // they need to be correctly implemented
- slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
- slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
-
- if (is_slot64bit(slot))
- slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
- if (is_slot66mhz(slot))
- slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
- if (ctrl->speed == PCI_SPEED_66MHz)
- slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
-
- ctrl_slot =
- slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
-
- // Check presence
- slot->capabilities |=
- ((((~tempdword) >> 23) |
- ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
- // Check the switch state
- slot->capabilities |=
- ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
- // Check the slot enable
- slot->capabilities |=
- ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
-
- /* register this slot with the hotplug pci core */
- hotplug_slot->release = &release_slot;
- hotplug_slot->private = slot;
- snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
- hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
-
- hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot);
- hotplug_slot_info->attention_status =
- cpq_get_attention_status(ctrl, slot);
- hotplug_slot_info->latch_status =
- cpq_get_latch_status(ctrl, slot);
- hotplug_slot_info->adapter_status =
- get_presence_status(ctrl, slot);
-
- dbg("registering bus %d, dev %d, number %d, "
- "ctrl->slot_device_offset %d, slot %d\n",
- slot->bus, slot->device,
- slot->number, ctrl->slot_device_offset,
- slot_number);
- result = pci_hp_register(hotplug_slot,
- ctrl->pci_dev->bus,
- slot->device,
- name);
- if (result) {
- err("pci_hp_register failed with error %d\n", result);
- goto error_info;
- }
-
- slot->next = ctrl->slot;
- ctrl->slot = slot;
-
- number_of_slots--;
- slot_device++;
- slot_number++;
- }
-
- return 0;
-error_info:
- kfree(hotplug_slot_info);
-error_hpslot:
- kfree(hotplug_slot);
-error_slot:
- kfree(slot);
-error:
- return result;
-}
-
static int ctrl_slot_cleanup (struct controller * ctrl)
{
struct slot *old_slot, *next_slot;
@@ -476,36 +307,32 @@ static int ctrl_slot_cleanup (struct controller * ctrl)
cpqhp_remove_debugfs_files(ctrl);
- //Free IRQ associated with hot plug device
+ /* Free IRQ associated with hot plug device */
free_irq(ctrl->interrupt, ctrl);
- //Unmap the memory
+ /* Unmap the memory */
iounmap(ctrl->hpc_reg);
- //Finally reclaim PCI mem
+ /* Finally reclaim PCI mem */
release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
pci_resource_len(ctrl->pci_dev, 0));
- return(0);
+ return 0;
}
-//============================================================================
-// function: get_slot_mapping
-//
-// Description: Attempts to determine a logical slot mapping for a PCI
-// device. Won't work for more than one PCI-PCI bridge
-// in a slot.
-//
-// Input: u8 bus_num - bus number of PCI device
-// u8 dev_num - device number of PCI device
-// u8 *slot - Pointer to u8 where slot number will
-// be returned
-//
-// Output: SUCCESS or FAILURE
-//=============================================================================
+/**
+ * get_slot_mapping - determine logical slot mapping for PCI device
+ *
+ * Won't work for more than one PCI-PCI bridge in a slot.
+ *
+ * @bus_num - bus number of PCI device
+ * @dev_num - device number of PCI device
+ * @slot - Pointer to u8 where slot number will be returned
+ *
+ * Output: SUCCESS or FAILURE
+ */
static int
get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
{
- struct irq_routing_table *PCIIRQRoutingInfoLength;
u32 work;
long len;
long loop;
@@ -516,36 +343,25 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
bridgeSlot = 0xFF;
- PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
- if (!PCIIRQRoutingInfoLength)
- return -1;
-
- len = (PCIIRQRoutingInfoLength->size -
- sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
- // Make sure I got at least one entry
- if (len == 0) {
- kfree(PCIIRQRoutingInfoLength);
- return -1;
- }
-
+ len = cpqhp_routing_table_length();
for (loop = 0; loop < len; ++loop) {
- tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
- tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
- tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
+ tbus = cpqhp_routing_table->slots[loop].bus;
+ tdevice = cpqhp_routing_table->slots[loop].devfn >> 3;
+ tslot = cpqhp_routing_table->slots[loop].slot;
if ((tbus == bus_num) && (tdevice == dev_num)) {
*slot = tslot;
- kfree(PCIIRQRoutingInfoLength);
return 0;
} else {
/* Did not get a match on the target PCI device. Check
- * if the current IRQ table entry is a PCI-to-PCI bridge
- * device. If so, and it's secondary bus matches the
- * bus number for the target device, I need to save the
- * bridge's slot number. If I can not find an entry for
- * the target device, I will have to assume it's on the
- * other side of the bridge, and assign it the bridge's
- * slot. */
+ * if the current IRQ table entry is a PCI-to-PCI
+ * bridge device. If so, and it's secondary bus
+ * matches the bus number for the target device, I need
+ * to save the bridge's slot number. If I can not find
+ * an entry for the target device, I will have to
+ * assume it's on the other side of the bridge, and
+ * assign it the bridge's slot.
+ */
bus->number = tbus;
pci_bus_read_config_dword(bus, PCI_DEVFN(tdevice, 0),
PCI_CLASS_REVISION, &work);
@@ -555,25 +371,23 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
PCI_DEVFN(tdevice, 0),
PCI_PRIMARY_BUS, &work);
// See if bridge's secondary bus matches target bus.
- if (((work >> 8) & 0x000000FF) == (long) bus_num) {
+ if (((work >> 8) & 0x000000FF) == (long) bus_num)
bridgeSlot = tslot;
- }
}
}
}
- // If we got here, we didn't find an entry in the IRQ mapping table
- // for the target PCI device. If we did determine that the target
- // device is on the other side of a PCI-to-PCI bridge, return the
- // slot number for the bridge.
+ /* If we got here, we didn't find an entry in the IRQ mapping table for
+ * the target PCI device. If we did determine that the target device
+ * is on the other side of a PCI-to-PCI bridge, return the slot number
+ * for the bridge.
+ */
if (bridgeSlot != 0xFF) {
*slot = bridgeSlot;
- kfree(PCIIRQRoutingInfoLength);
return 0;
}
- kfree(PCIIRQRoutingInfoLength);
- // Couldn't find an entry in the routing table for this PCI device
+ /* Couldn't find an entry in the routing table for this PCI device */
return -1;
}
@@ -591,32 +405,32 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
u8 hp_slot;
if (func == NULL)
- return(1);
+ return 1;
hp_slot = func->device - ctrl->slot_device_offset;
- // Wait for exclusive access to hardware
+ /* Wait for exclusive access to hardware */
mutex_lock(&ctrl->crit_sect);
- if (status == 1) {
+ if (status == 1)
amber_LED_on (ctrl, hp_slot);
- } else if (status == 0) {
+ else if (status == 0)
amber_LED_off (ctrl, hp_slot);
- } else {
- // Done with exclusive hardware access
+ else {
+ /* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
- return(1);
+ return 1;
}
set_SOGO(ctrl);
- // Wait for SOBS to be unset
+ /* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
- // Done with exclusive hardware access
+ /* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
- return(0);
+ return 0;
}
@@ -719,7 +533,7 @@ static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
- return cpqhp_hardware_test(ctrl, value);
+ return cpqhp_hardware_test(ctrl, value);
}
@@ -738,7 +552,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
{
struct slot *slot = hotplug_slot->private;
struct controller *ctrl = slot->ctrl;
-
+
dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
*value = cpq_get_attention_status(ctrl, slot);
@@ -793,6 +607,231 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
return 0;
}
+static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
+ .owner = THIS_MODULE,
+ .set_attention_status = set_attention_status,
+ .enable_slot = process_SI,
+ .disable_slot = process_SS,
+ .hardware_test = hardware_test,
+ .get_power_status = get_power_status,
+ .get_attention_status = get_attention_status,
+ .get_latch_status = get_latch_status,
+ .get_adapter_status = get_adapter_status,
+ .get_max_bus_speed = get_max_bus_speed,
+ .get_cur_bus_speed = get_cur_bus_speed,
+};
+
+#define SLOT_NAME_SIZE 10
+
+static int ctrl_slot_setup(struct controller *ctrl,
+ void __iomem *smbios_start,
+ void __iomem *smbios_table)
+{
+ struct slot *slot;
+ struct hotplug_slot *hotplug_slot;
+ struct hotplug_slot_info *hotplug_slot_info;
+ u8 number_of_slots;
+ u8 slot_device;
+ u8 slot_number;
+ u8 ctrl_slot;
+ u32 tempdword;
+ char name[SLOT_NAME_SIZE];
+ void __iomem *slot_entry= NULL;
+ int result = -ENOMEM;
+
+ dbg("%s\n", __func__);
+
+ tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
+
+ number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
+ slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
+ slot_number = ctrl->first_slot;
+
+ while (number_of_slots) {
+ slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+ if (!slot)
+ goto error;
+
+ slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)),
+ GFP_KERNEL);
+ if (!slot->hotplug_slot)
+ goto error_slot;
+ hotplug_slot = slot->hotplug_slot;
+
+ hotplug_slot->info = kzalloc(sizeof(*(hotplug_slot->info)),
+ GFP_KERNEL);
+ if (!hotplug_slot->info)
+ goto error_hpslot;
+ hotplug_slot_info = hotplug_slot->info;
+
+ slot->ctrl = ctrl;
+ slot->bus = ctrl->bus;
+ slot->device = slot_device;
+ slot->number = slot_number;
+ dbg("slot->number = %u\n", slot->number);
+
+ slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
+ slot_entry);
+
+ while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) !=
+ slot->number)) {
+ slot_entry = get_SMBIOS_entry(smbios_start,
+ smbios_table, 9, slot_entry);
+ }
+
+ slot->p_sm_slot = slot_entry;
+
+ init_timer(&slot->task_event);
+ slot->task_event.expires = jiffies + 5 * HZ;
+ slot->task_event.function = cpqhp_pushbutton_thread;
+
+ /*FIXME: these capabilities aren't used but if they are
+ * they need to be correctly implemented
+ */
+ slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
+ slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
+
+ if (is_slot64bit(slot))
+ slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
+ if (is_slot66mhz(slot))
+ slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
+ if (ctrl->speed == PCI_SPEED_66MHz)
+ slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
+
+ ctrl_slot =
+ slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
+
+ /* Check presence */
+ slot->capabilities |=
+ ((((~tempdword) >> 23) |
+ ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
+ /* Check the switch state */
+ slot->capabilities |=
+ ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
+ /* Check the slot enable */
+ slot->capabilities |=
+ ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
+
+ /* register this slot with the hotplug pci core */
+ hotplug_slot->release = &release_slot;
+ hotplug_slot->private = slot;
+ snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
+ hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
+
+ hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot);
+ hotplug_slot_info->attention_status =
+ cpq_get_attention_status(ctrl, slot);
+ hotplug_slot_info->latch_status =
+ cpq_get_latch_status(ctrl, slot);
+ hotplug_slot_info->adapter_status =
+ get_presence_status(ctrl, slot);
+
+ dbg("registering bus %d, dev %d, number %d, "
+ "ctrl->slot_device_offset %d, slot %d\n",
+ slot->bus, slot->device,
+ slot->number, ctrl->slot_device_offset,
+ slot_number);
+ result = pci_hp_register(hotplug_slot,
+ ctrl->pci_dev->bus,
+ slot->device,
+ name);
+ if (result) {
+ err("pci_hp_register failed with error %d\n", result);
+ goto error_info;
+ }
+
+ slot->next = ctrl->slot;
+ ctrl->slot = slot;
+
+ number_of_slots--;
+ slot_device++;
+ slot_number++;
+ }
+
+ return 0;
+error_info:
+ kfree(hotplug_slot_info);
+error_hpslot:
+ kfree(hotplug_slot);
+error_slot:
+ kfree(slot);
+error:
+ return result;
+}
+
+static int one_time_init(void)
+{
+ int loop;
+ int retval = 0;
+
+ if (initialized)
+ return 0;
+
+ power_mode = 0;
+
+ retval = init_cpqhp_routing_table();
+ if (retval)
+ goto error;
+
+ if (cpqhp_debug)
+ pci_print_IRQ_route();
+
+ dbg("Initialize + Start the notification mechanism \n");
+
+ retval = cpqhp_event_start_thread();
+ if (retval)
+ goto error;
+
+ dbg("Initialize slot lists\n");
+ for (loop = 0; loop < 256; loop++)
+ cpqhp_slot_list[loop] = NULL;
+
+ /* FIXME: We also need to hook the NMI handler eventually.
+ * this also needs to be worked with Christoph
+ * register_NMI_handler();
+ */
+ /* Map rom address */
+ cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
+ if (!cpqhp_rom_start) {
+ err ("Could not ioremap memory region for ROM\n");
+ retval = -EIO;
+ goto error;
+ }
+
+ /* Now, map the int15 entry point if we are on compaq specific
+ * hardware
+ */
+ compaq_nvram_init(cpqhp_rom_start);
+
+ /* Map smbios table entry point structure */
+ smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start,
+ cpqhp_rom_start + ROM_PHY_LEN);
+ if (!smbios_table) {
+ err ("Could not find the SMBIOS pointer in memory\n");
+ retval = -EIO;
+ goto error_rom_start;
+ }
+
+ smbios_start = ioremap(readl(smbios_table + ST_ADDRESS),
+ readw(smbios_table + ST_LENGTH));
+ if (!smbios_start) {
+ err ("Could not ioremap memory region taken from SMBIOS values\n");
+ retval = -EIO;
+ goto error_smbios_start;
+ }
+
+ initialized = 1;
+
+ return retval;
+
+error_smbios_start:
+ iounmap(smbios_start);
+error_rom_start:
+ iounmap(cpqhp_rom_start);
+error:
+ return retval;
+}
+
static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
u8 num_of_slots = 0;
@@ -815,7 +854,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return err;
}
- // Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
+ /* Need to read VID early b/c it's used to differentiate CPQ and INTC
+ * discovery
+ */
rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
err(msg_HPC_non_compaq_or_intel);
@@ -832,217 +873,209 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
/* Check for the proper subsytem ID's
- * Intel uses a different SSID programming model than Compaq.
+ * Intel uses a different SSID programming model than Compaq.
* For Intel, each SSID bit identifies a PHP capability.
* Also Intel HPC's may have RID=0.
*/
- if ((pdev->revision > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
- // TODO: This code can be made to support non-Compaq or Intel subsystem IDs
- rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
- if (rc) {
- err("%s : pci_read_config_word failed\n", __func__);
- goto err_disable_device;
- }
- dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
- if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
- err(msg_HPC_non_compaq_or_intel);
- rc = -ENODEV;
- goto err_disable_device;
- }
+ if ((pdev->revision <= 2) && (vendor_id != PCI_VENDOR_ID_INTEL)) {
+ err(msg_HPC_not_supported);
+ return -ENODEV;
+ }
- ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL);
- if (!ctrl) {
- err("%s : out of memory\n", __func__);
- rc = -ENOMEM;
- goto err_disable_device;
- }
+ /* TODO: This code can be made to support non-Compaq or Intel
+ * subsystem IDs
+ */
+ rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
+ if (rc) {
+ err("%s : pci_read_config_word failed\n", __func__);
+ goto err_disable_device;
+ }
+ dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
+ if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
+ err(msg_HPC_non_compaq_or_intel);
+ rc = -ENODEV;
+ goto err_disable_device;
+ }
- rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
- if (rc) {
- err("%s : pci_read_config_word failed\n", __func__);
- goto err_free_ctrl;
- }
+ ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL);
+ if (!ctrl) {
+ err("%s : out of memory\n", __func__);
+ rc = -ENOMEM;
+ goto err_disable_device;
+ }
- info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
-
- /* Set Vendor ID, so it can be accessed later from other functions */
- ctrl->vendor_id = vendor_id;
-
- switch (subsystem_vid) {
- case PCI_VENDOR_ID_COMPAQ:
- if (pdev->revision >= 0x13) { /* CIOBX */
- ctrl->push_flag = 1;
- ctrl->slot_switch_type = 1;
- ctrl->push_button = 1;
- ctrl->pci_config_space = 1;
- ctrl->defeature_PHP = 1;
- ctrl->pcix_support = 1;
- ctrl->pcix_speed_capability = 1;
- pci_read_config_byte(pdev, 0x41, &bus_cap);
- if (bus_cap & 0x80) {
- dbg("bus max supports 133MHz PCI-X\n");
- ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
- break;
- }
- if (bus_cap & 0x40) {
- dbg("bus max supports 100MHz PCI-X\n");
- ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
- break;
- }
- if (bus_cap & 20) {
- dbg("bus max supports 66MHz PCI-X\n");
- ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
- break;
- }
- if (bus_cap & 10) {
- dbg("bus max supports 66MHz PCI\n");
- ctrl->speed_capability = PCI_SPEED_66MHz;
- break;
- }
-
- break;
- }
-
- switch (subsystem_deviceid) {
- case PCI_SUB_HPC_ID:
- /* Original 6500/7000 implementation */
- ctrl->slot_switch_type = 1;
- ctrl->speed_capability = PCI_SPEED_33MHz;
- ctrl->push_button = 0;
- ctrl->pci_config_space = 1;
- ctrl->defeature_PHP = 1;
- ctrl->pcix_support = 0;
- ctrl->pcix_speed_capability = 0;
- break;
- case PCI_SUB_HPC_ID2:
- /* First Pushbutton implementation */
- ctrl->push_flag = 1;
- ctrl->slot_switch_type = 1;
- ctrl->speed_capability = PCI_SPEED_33MHz;
- ctrl->push_button = 1;
- ctrl->pci_config_space = 1;
- ctrl->defeature_PHP = 1;
- ctrl->pcix_support = 0;
- ctrl->pcix_speed_capability = 0;
- break;
- case PCI_SUB_HPC_ID_INTC:
- /* Third party (6500/7000) */
- ctrl->slot_switch_type = 1;
- ctrl->speed_capability = PCI_SPEED_33MHz;
- ctrl->push_button = 0;
- ctrl->pci_config_space = 1;
- ctrl->defeature_PHP = 1;
- ctrl->pcix_support = 0;
- ctrl->pcix_speed_capability = 0;
- break;
- case PCI_SUB_HPC_ID3:
- /* First 66 Mhz implementation */
- ctrl->push_flag = 1;
- ctrl->slot_switch_type = 1;
- ctrl->speed_capability = PCI_SPEED_66MHz;
- ctrl->push_button = 1;
- ctrl->pci_config_space = 1;
- ctrl->defeature_PHP = 1;
- ctrl->pcix_support = 0;
- ctrl->pcix_speed_capability = 0;
- break;
- case PCI_SUB_HPC_ID4:
- /* First PCI-X implementation, 100MHz */
- ctrl->push_flag = 1;
- ctrl->slot_switch_type = 1;
- ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
- ctrl->push_button = 1;
- ctrl->pci_config_space = 1;
- ctrl->defeature_PHP = 1;
- ctrl->pcix_support = 1;
- ctrl->pcix_speed_capability = 0;
- break;
- default:
- err(msg_HPC_not_supported);
- rc = -ENODEV;
- goto err_free_ctrl;
- }
- break;
+ rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
+ if (rc) {
+ err("%s : pci_read_config_word failed\n", __func__);
+ goto err_free_ctrl;
+ }
- case PCI_VENDOR_ID_INTEL:
- /* Check for speed capability (0=33, 1=66) */
- if (subsystem_deviceid & 0x0001) {
- ctrl->speed_capability = PCI_SPEED_66MHz;
- } else {
- ctrl->speed_capability = PCI_SPEED_33MHz;
- }
-
- /* Check for push button */
- if (subsystem_deviceid & 0x0002) {
- /* no push button */
- ctrl->push_button = 0;
- } else {
- /* push button supported */
- ctrl->push_button = 1;
- }
-
- /* Check for slot switch type (0=mechanical, 1=not mechanical) */
- if (subsystem_deviceid & 0x0004) {
- /* no switch */
- ctrl->slot_switch_type = 0;
- } else {
- /* switch */
- ctrl->slot_switch_type = 1;
- }
-
- /* PHP Status (0=De-feature PHP, 1=Normal operation) */
- if (subsystem_deviceid & 0x0008) {
- ctrl->defeature_PHP = 1; // PHP supported
- } else {
- ctrl->defeature_PHP = 0; // PHP not supported
- }
-
- /* Alternate Base Address Register Interface (0=not supported, 1=supported) */
- if (subsystem_deviceid & 0x0010) {
- ctrl->alternate_base_address = 1; // supported
- } else {
- ctrl->alternate_base_address = 0; // not supported
- }
-
- /* PCI Config Space Index (0=not supported, 1=supported) */
- if (subsystem_deviceid & 0x0020) {
- ctrl->pci_config_space = 1; // supported
- } else {
- ctrl->pci_config_space = 0; // not supported
- }
-
- /* PCI-X support */
- if (subsystem_deviceid & 0x0080) {
- /* PCI-X capable */
- ctrl->pcix_support = 1;
- /* Frequency of operation in PCI-X mode */
- if (subsystem_deviceid & 0x0040) {
- /* 133MHz PCI-X if bit 7 is 1 */
- ctrl->pcix_speed_capability = 1;
- } else {
- /* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
- /* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
- ctrl->pcix_speed_capability = 0;
- }
- } else {
- /* Conventional PCI */
- ctrl->pcix_support = 0;
- ctrl->pcix_speed_capability = 0;
- }
+ info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
+
+ /* Set Vendor ID, so it can be accessed later from other
+ * functions
+ */
+ ctrl->vendor_id = vendor_id;
+
+ switch (subsystem_vid) {
+ case PCI_VENDOR_ID_COMPAQ:
+ if (pdev->revision >= 0x13) { /* CIOBX */
+ ctrl->push_flag = 1;
+ ctrl->slot_switch_type = 1;
+ ctrl->push_button = 1;
+ ctrl->pci_config_space = 1;
+ ctrl->defeature_PHP = 1;
+ ctrl->pcix_support = 1;
+ ctrl->pcix_speed_capability = 1;
+ pci_read_config_byte(pdev, 0x41, &bus_cap);
+ if (bus_cap & 0x80) {
+ dbg("bus max supports 133MHz PCI-X\n");
+ ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
break;
+ }
+ if (bus_cap & 0x40) {
+ dbg("bus max supports 100MHz PCI-X\n");
+ ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
+ break;
+ }
+ if (bus_cap & 20) {
+ dbg("bus max supports 66MHz PCI-X\n");
+ ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
+ break;
+ }
+ if (bus_cap & 10) {
+ dbg("bus max supports 66MHz PCI\n");
+ ctrl->speed_capability = PCI_SPEED_66MHz;
+ break;
+ }
+
+ break;
+ }
- default:
- err(msg_HPC_not_supported);
- rc = -ENODEV;
- goto err_free_ctrl;
+ switch (subsystem_deviceid) {
+ case PCI_SUB_HPC_ID:
+ /* Original 6500/7000 implementation */
+ ctrl->slot_switch_type = 1;
+ ctrl->speed_capability = PCI_SPEED_33MHz;
+ ctrl->push_button = 0;
+ ctrl->pci_config_space = 1;
+ ctrl->defeature_PHP = 1;
+ ctrl->pcix_support = 0;
+ ctrl->pcix_speed_capability = 0;
+ break;
+ case PCI_SUB_HPC_ID2:
+ /* First Pushbutton implementation */
+ ctrl->push_flag = 1;
+ ctrl->slot_switch_type = 1;
+ ctrl->speed_capability = PCI_SPEED_33MHz;
+ ctrl->push_button = 1;
+ ctrl->pci_config_space = 1;
+ ctrl->defeature_PHP = 1;
+ ctrl->pcix_support = 0;
+ ctrl->pcix_speed_capability = 0;
+ break;
+ case PCI_SUB_HPC_ID_INTC:
+ /* Third party (6500/7000) */
+ ctrl->slot_switch_type = 1;
+ ctrl->speed_capability = PCI_SPEED_33MHz;
+ ctrl->push_button = 0;
+ ctrl->pci_config_space = 1;
+ ctrl->defeature_PHP = 1;
+ ctrl->pcix_support = 0;
+ ctrl->pcix_speed_capability = 0;
+ break;
+ case PCI_SUB_HPC_ID3:
+ /* First 66 Mhz implementation */
+ ctrl->push_flag = 1;
+ ctrl->slot_switch_type = 1;
+ ctrl->speed_capability = PCI_SPEED_66MHz;
+ ctrl->push_button = 1;
+ ctrl->pci_config_space = 1;
+ ctrl->defeature_PHP = 1;
+ ctrl->pcix_support = 0;
+ ctrl->pcix_speed_capability = 0;
+ break;
+ case PCI_SUB_HPC_ID4:
+ /* First PCI-X implementation, 100MHz */
+ ctrl->push_flag = 1;
+ ctrl->slot_switch_type = 1;
+ ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
+ ctrl->push_button = 1;
+ ctrl->pci_config_space = 1;
+ ctrl->defeature_PHP = 1;
+ ctrl->pcix_support = 1;
+ ctrl->pcix_speed_capability = 0;
+ break;
+ default:
+ err(msg_HPC_not_supported);
+ rc = -ENODEV;
+ goto err_free_ctrl;
}
+ break;
+
+ case PCI_VENDOR_ID_INTEL:
+ /* Check for speed capability (0=33, 1=66) */
+ if (subsystem_deviceid & 0x0001)
+ ctrl->speed_capability = PCI_SPEED_66MHz;
+ else
+ ctrl->speed_capability = PCI_SPEED_33MHz;
+
+ /* Check for push button */
+ if (subsystem_deviceid & 0x0002)
+ ctrl->push_button = 0;
+ else
+ ctrl->push_button = 1;
+
+ /* Check for slot switch type (0=mechanical, 1=not mechanical) */
+ if (subsystem_deviceid & 0x0004)
+ ctrl->slot_switch_type = 0;
+ else
+ ctrl->slot_switch_type = 1;
+
+ /* PHP Status (0=De-feature PHP, 1=Normal operation) */
+ if (subsystem_deviceid & 0x0008)
+ ctrl->defeature_PHP = 1; /* PHP supported */
+ else
+ ctrl->defeature_PHP = 0; /* PHP not supported */
+
+ /* Alternate Base Address Register Interface
+ * (0=not supported, 1=supported)
+ */
+ if (subsystem_deviceid & 0x0010)
+ ctrl->alternate_base_address = 1;
+ else
+ ctrl->alternate_base_address = 0;
+
+ /* PCI Config Space Index (0=not supported, 1=supported) */
+ if (subsystem_deviceid & 0x0020)
+ ctrl->pci_config_space = 1;
+ else
+ ctrl->pci_config_space = 0;
+
+ /* PCI-X support */
+ if (subsystem_deviceid & 0x0080) {
+ ctrl->pcix_support = 1;
+ if (subsystem_deviceid & 0x0040)
+ /* 133MHz PCI-X if bit 7 is 1 */
+ ctrl->pcix_speed_capability = 1;
+ else
+ /* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
+ /* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
+ ctrl->pcix_speed_capability = 0;
+ } else {
+ /* Conventional PCI */
+ ctrl->pcix_support = 0;
+ ctrl->pcix_speed_capability = 0;
+ }
+ break;
- } else {
+ default:
err(msg_HPC_not_supported);
- return -ENODEV;
+ rc = -ENODEV;
+ goto err_free_ctrl;
}
- // Tell the user that we found one.
+ /* Tell the user that we found one. */
info("Initializing the PCI hot plug controller residing on PCI bus %d\n",
pdev->bus->number);
@@ -1087,7 +1120,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) {
goto err_free_bus;
}
-
+
dbg("pdev = %p\n", pdev);
dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0));
dbg("pci resource len %llx\n", (unsigned long long)pci_resource_len(pdev, 0));
@@ -1109,7 +1142,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_free_mem_region;
}
- // Check for 66Mhz operation
+ /* Check for 66Mhz operation */
ctrl->speed = get_controller_speed(ctrl);
@@ -1120,7 +1153,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
*
********************************************************/
- // find the physical slot number of the first hot plug slot
+ /* find the physical slot number of the first hot plug slot */
/* Get slot won't work for devices behind bridges, but
* in this case it will always be called for the "base"
@@ -1137,7 +1170,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_iounmap;
}
- // Store PCI Config Space for all devices on this bus
+ /* Store PCI Config Space for all devices on this bus */
rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
if (rc) {
err("%s: unable to save PCI configuration data, error %d\n",
@@ -1148,7 +1181,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/*
* Get IO, memory, and IRQ resources for new devices
*/
- // The next line is required for cpqhp_find_available_resources
+ /* The next line is required for cpqhp_find_available_resources */
ctrl->interrupt = pdev->irq;
if (ctrl->interrupt < 0x10) {
cpqhp_legacy_mode = 1;
@@ -1182,7 +1215,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
__func__, rc);
goto err_iounmap;
}
-
+
/* Mask all general input interrupts */
writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
@@ -1196,12 +1229,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_iounmap;
}
- /* Enable Shift Out interrupt and clear it, also enable SERR on power fault */
+ /* Enable Shift Out interrupt and clear it, also enable SERR on power
+ * fault
+ */
temp_word = readw(ctrl->hpc_reg + MISC);
temp_word |= 0x4006;
writew(temp_word, ctrl->hpc_reg + MISC);
- // Changed 05/05/97 to clear all interrupts at start
+ /* Changed 05/05/97 to clear all interrupts at start */
writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
@@ -1216,13 +1251,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
cpqhp_ctrl_list = ctrl;
}
- // turn off empty slots here unless command line option "ON" set
- // Wait for exclusive access to hardware
+ /* turn off empty slots here unless command line option "ON" set
+ * Wait for exclusive access to hardware
+ */
mutex_lock(&ctrl->crit_sect);
num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
- // find first device number for the ctrl
+ /* find first device number for the ctrl */
device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
while (num_of_slots) {
@@ -1234,23 +1270,21 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hp_slot = func->device - ctrl->slot_device_offset;
dbg("hp_slot: %d\n", hp_slot);
- // We have to save the presence info for these slots
+ /* We have to save the presence info for these slots */
temp_word = ctrl->ctrl_int_comp >> 16;
func->presence_save = (temp_word >> hp_slot) & 0x01;
func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
- if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
+ if (ctrl->ctrl_int_comp & (0x1L << hp_slot))
func->switch_save = 0;
- } else {
+ else
func->switch_save = 0x10;
- }
- if (!power_mode) {
+ if (!power_mode)
if (!func->is_a_board) {
green_LED_off(ctrl, hp_slot);
slot_disable(ctrl, hp_slot);
}
- }
device++;
num_of_slots--;
@@ -1258,7 +1292,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!power_mode) {
set_SOGO(ctrl);
- // Wait for SOBS to be unset
+ /* Wait for SOBS to be unset */
wait_for_ctrl_irq(ctrl);
}
@@ -1269,7 +1303,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_free_irq;
}
- // Done with exclusive hardware access
+ /* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
cpqhp_create_debugfs_files(ctrl);
@@ -1291,77 +1325,6 @@ err_disable_device:
return rc;
}
-
-static int one_time_init(void)
-{
- int loop;
- int retval = 0;
-
- if (initialized)
- return 0;
-
- power_mode = 0;
-
- retval = pci_print_IRQ_route();
- if (retval)
- goto error;
-
- dbg("Initialize + Start the notification mechanism \n");
-
- retval = cpqhp_event_start_thread();
- if (retval)
- goto error;
-
- dbg("Initialize slot lists\n");
- for (loop = 0; loop < 256; loop++) {
- cpqhp_slot_list[loop] = NULL;
- }
-
- // FIXME: We also need to hook the NMI handler eventually.
- // this also needs to be worked with Christoph
- // register_NMI_handler();
-
- // Map rom address
- cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
- if (!cpqhp_rom_start) {
- err ("Could not ioremap memory region for ROM\n");
- retval = -EIO;
- goto error;
- }
-
- /* Now, map the int15 entry point if we are on compaq specific hardware */
- compaq_nvram_init(cpqhp_rom_start);
-
- /* Map smbios table entry point structure */
- smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start,
- cpqhp_rom_start + ROM_PHY_LEN);
- if (!smbios_table) {
- err ("Could not find the SMBIOS pointer in memory\n");
- retval = -EIO;
- goto error_rom_start;
- }
-
- smbios_start = ioremap(readl(smbios_table + ST_ADDRESS),
- readw(smbios_table + ST_LENGTH));
- if (!smbios_start) {
- err ("Could not ioremap memory region taken from SMBIOS values\n");
- retval = -EIO;
- goto error_smbios_start;
- }
-
- initialized = 1;
-
- return retval;
-
-error_smbios_start:
- iounmap(smbios_start);
-error_rom_start:
- iounmap(cpqhp_rom_start);
-error:
- return retval;
-}
-
-
static void __exit unload_cpqphpd(void)
{
struct pci_func *next;
@@ -1381,10 +1344,10 @@ static void __exit unload_cpqphpd(void)
if (ctrl->hpc_reg) {
u16 misc;
rc = read_slot_enable (ctrl);
-
+
writeb(0, ctrl->hpc_reg + SLOT_SERR);
writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
-
+
misc = readw(ctrl->hpc_reg + MISC);
misc &= 0xFFFD;
writew(misc, ctrl->hpc_reg + MISC);
@@ -1464,38 +1427,34 @@ static void __exit unload_cpqphpd(void)
}
}
- // Stop the notification mechanism
+ /* Stop the notification mechanism */
if (initialized)
cpqhp_event_stop_thread();
- //unmap the rom address
+ /* unmap the rom address */
if (cpqhp_rom_start)
iounmap(cpqhp_rom_start);
if (smbios_start)
iounmap(smbios_start);
}
-
-
static struct pci_device_id hpcd_pci_tbl[] = {
{
/* handle any PCI Hotplug controller */
.class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
.class_mask = ~0,
-
+
/* no matter who makes it */
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
-
+
}, { /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
-
-
static struct pci_driver cpqhpc_driver = {
.name = "compaq_pci_hotplug",
.id_table = hpcd_pci_tbl,
@@ -1503,8 +1462,6 @@ static struct pci_driver cpqhpc_driver = {
/* remove: cpqhpc_remove_one, */
};
-
-
static int __init cpqhpc_init(void)
{
int result;
@@ -1518,7 +1475,6 @@ static int __init cpqhpc_init(void)
return result;
}
-
static void __exit cpqhpc_cleanup(void)
{
dbg("unload_cpqphpd()\n");
@@ -1529,8 +1485,5 @@ static void __exit cpqhpc_cleanup(void)
cpqhp_shutdown_debugfs();
}
-
module_init(cpqhpc_init);
module_exit(cpqhpc_cleanup);
-
-
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index cc227a8c4b11..2fa47af992a8 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -81,14 +81,15 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl)
for (hp_slot = 0; hp_slot < 6; hp_slot++) {
if (change & (0x1L << hp_slot)) {
- /**********************************
+ /*
* this one changed.
- **********************************/
+ */
func = cpqhp_slot_find(ctrl->bus,
(hp_slot + ctrl->slot_device_offset), 0);
/* this is the structure that tells the worker thread
- *what to do */
+ * what to do
+ */
taskInfo = &(ctrl->event_queue[ctrl->next_event]);
ctrl->next_event = (ctrl->next_event + 1) % 10;
taskInfo->hp_slot = hp_slot;
@@ -100,17 +101,17 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl)
func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
- /**********************************
+ /*
* Switch opened
- **********************************/
+ */
func->switch_save = 0;
taskInfo->event_type = INT_SWITCH_OPEN;
} else {
- /**********************************
+ /*
* Switch closed
- **********************************/
+ */
func->switch_save = 0x10;
@@ -131,9 +132,8 @@ static struct slot *cpqhp_find_slot(struct controller *ctrl, u8 device)
{
struct slot *slot = ctrl->slot;
- while (slot && (slot->device != device)) {
+ while (slot && (slot->device != device))
slot = slot->next;
- }
return slot;
}
@@ -152,17 +152,17 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl)
if (!change)
return 0;
- /**********************************
+ /*
* Presence Change
- **********************************/
+ */
dbg("cpqsbd: Presence/Notify input change.\n");
dbg(" Changed bits are 0x%4.4x\n", change );
for (hp_slot = 0; hp_slot < 6; hp_slot++) {
if (change & (0x0101 << hp_slot)) {
- /**********************************
+ /*
* this one changed.
- **********************************/
+ */
func = cpqhp_slot_find(ctrl->bus,
(hp_slot + ctrl->slot_device_offset), 0);
@@ -177,22 +177,23 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl)
return 0;
/* If the switch closed, must be a button
- * If not in button mode, nevermind */
+ * If not in button mode, nevermind
+ */
if (func->switch_save && (ctrl->push_button == 1)) {
temp_word = ctrl->ctrl_int_comp >> 16;
temp_byte = (temp_word >> hp_slot) & 0x01;
temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02;
if (temp_byte != func->presence_save) {
- /**************************************
+ /*
* button Pressed (doesn't do anything)
- **************************************/
+ */
dbg("hp_slot %d button pressed\n", hp_slot);
taskInfo->event_type = INT_BUTTON_PRESS;
} else {
- /**********************************
+ /*
* button Released - TAKE ACTION!!!!
- **********************************/
+ */
dbg("hp_slot %d button released\n", hp_slot);
taskInfo->event_type = INT_BUTTON_RELEASE;
@@ -210,7 +211,8 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl)
}
} else {
/* Switch is open, assume a presence change
- * Save the presence state */
+ * Save the presence state
+ */
temp_word = ctrl->ctrl_int_comp >> 16;
func->presence_save = (temp_word >> hp_slot) & 0x01;
func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
@@ -241,17 +243,17 @@ static u8 handle_power_fault(u8 change, struct controller * ctrl)
if (!change)
return 0;
- /**********************************
+ /*
* power fault
- **********************************/
+ */
info("power fault interrupt\n");
for (hp_slot = 0; hp_slot < 6; hp_slot++) {
if (change & (0x01 << hp_slot)) {
- /**********************************
+ /*
* this one changed.
- **********************************/
+ */
func = cpqhp_slot_find(ctrl->bus,
(hp_slot + ctrl->slot_device_offset), 0);
@@ -262,16 +264,16 @@ static u8 handle_power_fault(u8 change, struct controller * ctrl)
rc++;
if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) {
- /**********************************
+ /*
* power fault Cleared
- **********************************/
+ */
func->status = 0x00;
taskInfo->event_type = INT_POWER_FAULT_CLEAR;
} else {
- /**********************************
+ /*
* power fault
- **********************************/
+ */
taskInfo->event_type = INT_POWER_FAULT;
if (ctrl->rev < 4) {
@@ -432,13 +434,15 @@ static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **h
/* If we got here, there the bridge requires some of the resource, but
- * we may be able to split some off of the front */
+ * we may be able to split some off of the front
+ */
node = *head;
if (node->length & (alignment -1)) {
/* this one isn't an aligned length, so we'll make a new entry
- * and split it up. */
+ * and split it up.
+ */
split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
@@ -544,10 +548,10 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size
if (!(*head))
return NULL;
- if ( cpqhp_resource_sort_and_combine(head) )
+ if (cpqhp_resource_sort_and_combine(head))
return NULL;
- if ( sort_by_size(head) )
+ if (sort_by_size(head))
return NULL;
for (node = *head; node; node = node->next) {
@@ -556,7 +560,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size
if (node->base & (size - 1)) {
/* this one isn't base aligned properly
- * so we'll make a new entry and split it up */
+ * so we'll make a new entry and split it up
+ */
temp_dword = (node->base | (size-1)) + 1;
/* Short circuit if adjusted size is too small */
@@ -581,7 +586,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size
/* Don't need to check if too small since we already did */
if (node->length > size) {
/* this one is longer than we need
- * so we'll make a new entry and split it up */
+ * so we'll make a new entry and split it up
+ */
split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
@@ -601,7 +607,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size
continue;
/* If we got here, then it is the right size
- * Now take it out of the list and break */
+ * Now take it out of the list and break
+ */
if (*head == node) {
*head = node->next;
} else {
@@ -642,14 +649,16 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz
return NULL;
for (max = *head; max; max = max->next) {
- /* If not big enough we could probably just bail,
- * instead we'll continue to the next. */
+ /* If not big enough we could probably just bail,
+ * instead we'll continue to the next.
+ */
if (max->length < size)
continue;
if (max->base & (size - 1)) {
/* this one isn't base aligned properly
- * so we'll make a new entry and split it up */
+ * so we'll make a new entry and split it up
+ */
temp_dword = (max->base | (size-1)) + 1;
/* Short circuit if adjusted size is too small */
@@ -672,7 +681,8 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz
if ((max->base + max->length) & (size - 1)) {
/* this one isn't end aligned properly at the top
- * so we'll make a new entry and split it up */
+ * so we'll make a new entry and split it up
+ */
split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
@@ -744,7 +754,8 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
if (node->base & (size - 1)) {
dbg("%s: not aligned\n", __func__);
/* this one isn't base aligned properly
- * so we'll make a new entry and split it up */
+ * so we'll make a new entry and split it up
+ */
temp_dword = (node->base | (size-1)) + 1;
/* Short circuit if adjusted size is too small */
@@ -769,7 +780,8 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
if (node->length > size) {
dbg("%s: too big\n", __func__);
/* this one is longer than we need
- * so we'll make a new entry and split it up */
+ * so we'll make a new entry and split it up
+ */
split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
@@ -886,19 +898,19 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data)
u32 Diff;
u32 temp_dword;
-
+
misc = readw(ctrl->hpc_reg + MISC);
- /***************************************
+ /*
* Check to see if it was our interrupt
- ***************************************/
+ */
if (!(misc & 0x000C)) {
return IRQ_NONE;
}
if (misc & 0x0004) {
- /**********************************
+ /*
* Serial Output interrupt Pending
- **********************************/
+ */
/* Clear the interrupt */
misc |= 0x0004;
@@ -961,11 +973,8 @@ struct pci_func *cpqhp_slot_create(u8 busnumber)
struct pci_func *next;
new_slot = kzalloc(sizeof(*new_slot), GFP_KERNEL);
- if (new_slot == NULL) {
- /* I'm not dead yet!
- * You will be. */
+ if (new_slot == NULL)
return new_slot;
- }
new_slot->next = NULL;
new_slot->configured = 1;
@@ -996,10 +1005,8 @@ static int slot_remove(struct pci_func * old_slot)
return 1;
next = cpqhp_slot_list[old_slot->bus];
-
- if (next == NULL) {
+ if (next == NULL)
return 1;
- }
if (next == old_slot) {
cpqhp_slot_list[old_slot->bus] = old_slot->next;
@@ -1008,9 +1015,8 @@ static int slot_remove(struct pci_func * old_slot)
return 0;
}
- while ((next->next != old_slot) && (next->next != NULL)) {
+ while ((next->next != old_slot) && (next->next != NULL))
next = next->next;
- }
if (next->next == old_slot) {
next->next = old_slot->next;
@@ -1040,9 +1046,8 @@ static int bridge_slot_remove(struct pci_func *bridge)
for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
next = cpqhp_slot_list[tempBus];
- while (!slot_remove(next)) {
+ while (!slot_remove(next))
next = cpqhp_slot_list[tempBus];
- }
}
next = cpqhp_slot_list[bridge->bus];
@@ -1130,39 +1135,43 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_
u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
u16 reg16;
u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);
-
+
if (ctrl->speed == adapter_speed)
return 0;
-
+
/* We don't allow freq/mode changes if we find another adapter running
- * in another slot on this controller */
+ * in another slot on this controller
+ */
for(slot = ctrl->slot; slot; slot = slot->next) {
- if (slot->device == (hp_slot + ctrl->slot_device_offset))
+ if (slot->device == (hp_slot + ctrl->slot_device_offset))
continue;
if (!slot->hotplug_slot || !slot->hotplug_slot->info)
continue;
- if (slot->hotplug_slot->info->adapter_status == 0)
+ if (slot->hotplug_slot->info->adapter_status == 0)
continue;
/* If another adapter is running on the same segment but at a
* lower speed/mode, we allow the new adapter to function at
- * this rate if supported */
- if (ctrl->speed < adapter_speed)
+ * this rate if supported
+ */
+ if (ctrl->speed < adapter_speed)
return 0;
return 1;
}
-
+
/* If the controller doesn't support freq/mode changes and the
- * controller is running at a higher mode, we bail */
+ * controller is running at a higher mode, we bail
+ */
if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability))
return 1;
-
+
/* But we allow the adapter to run at a lower rate if possible */
if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability))
return 0;
/* We try to set the max speed supported by both the adapter and
- * controller */
+ * controller
+ */
if (ctrl->speed_capability < adapter_speed) {
if (ctrl->speed == ctrl->speed_capability)
return 0;
@@ -1171,22 +1180,22 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_
writel(0x0L, ctrl->hpc_reg + LED_CONTROL);
writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE);
-
- set_SOGO(ctrl);
+
+ set_SOGO(ctrl);
wait_for_ctrl_irq(ctrl);
-
+
if (adapter_speed != PCI_SPEED_133MHz_PCIX)
reg = 0xF5;
else
- reg = 0xF4;
+ reg = 0xF4;
pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
-
+
reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ);
reg16 &= ~0x000F;
switch(adapter_speed) {
- case(PCI_SPEED_133MHz_PCIX):
+ case(PCI_SPEED_133MHz_PCIX):
reg = 0x75;
- reg16 |= 0xB;
+ reg16 |= 0xB;
break;
case(PCI_SPEED_100MHz_PCIX):
reg = 0x74;
@@ -1203,48 +1212,48 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_
default: /* 33MHz PCI 2.2 */
reg = 0x71;
break;
-
+
}
reg16 |= 0xB << 12;
writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ);
-
- mdelay(5);
-
+
+ mdelay(5);
+
/* Reenable interrupts */
writel(0, ctrl->hpc_reg + INT_MASK);
- pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
-
+ pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
+
/* Restart state machine */
reg = ~0xF;
pci_read_config_byte(ctrl->pci_dev, 0x43, &reg);
pci_write_config_byte(ctrl->pci_dev, 0x43, reg);
-
+
/* Only if mode change...*/
if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz)))
set_SOGO(ctrl);
-
+
wait_for_ctrl_irq(ctrl);
mdelay(1100);
-
+
/* Restore LED/Slot state */
writel(leds, ctrl->hpc_reg + LED_CONTROL);
writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE);
-
+
set_SOGO(ctrl);
wait_for_ctrl_irq(ctrl);
ctrl->speed = adapter_speed;
slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
- info("Successfully changed frequency/mode for adapter in slot %d\n",
+ info("Successfully changed frequency/mode for adapter in slot %d\n",
slot->number);
return 0;
}
-/* the following routines constitute the bulk of the
- hotplug controller logic
+/* the following routines constitute the bulk of the
+ * hotplug controller logic
*/
@@ -1268,17 +1277,17 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
hp_slot = func->device - ctrl->slot_device_offset;
- if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) {
- /**********************************
- * The switch is open.
- **********************************/
+ /*
+ * The switch is open.
+ */
+ if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot))
rc = INTERLOCK_OPEN;
- } else if (is_slot_enabled (ctrl, hp_slot)) {
- /**********************************
- * The board is already on
- **********************************/
+ /*
+ * The board is already on
+ */
+ else if (is_slot_enabled (ctrl, hp_slot))
rc = CARD_FUNCTIONING;
- } else {
+ else {
mutex_lock(&ctrl->crit_sect);
/* turn on board without attaching to the bus */
@@ -1299,7 +1308,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
-
+
adapter_speed = get_adapter_speed(ctrl, hp_slot);
if (ctrl->speed != adapter_speed)
if (set_controller_speed(ctrl, adapter_speed, hp_slot))
@@ -1352,7 +1361,8 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
* Get slot won't work for devices behind
* bridges, but in this case it will always be
* called for the "base" bus/dev/func of an
- * adapter. */
+ * adapter.
+ */
mutex_lock(&ctrl->crit_sect);
@@ -1377,7 +1387,8 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
* Get slot won't work for devices behind bridges, but
* in this case it will always be called for the "base"
- * bus/dev/func of an adapter. */
+ * bus/dev/func of an adapter.
+ */
mutex_lock(&ctrl->crit_sect);
@@ -1434,7 +1445,8 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
wait_for_ctrl_irq (ctrl);
/* Change bits in slot power register to force another shift out
- * NOTE: this is to work around the timer bug */
+ * NOTE: this is to work around the timer bug
+ */
temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
@@ -1443,12 +1455,12 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
/* Wait for SOBS to be unset */
wait_for_ctrl_irq (ctrl);
-
+
adapter_speed = get_adapter_speed(ctrl, hp_slot);
if (ctrl->speed != adapter_speed)
if (set_controller_speed(ctrl, adapter_speed, hp_slot))
rc = WRONG_BUS_FREQUENCY;
-
+
/* turn off board without attaching to the bus */
disable_slot_power (ctrl, hp_slot);
@@ -1461,7 +1473,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
if (rc)
return rc;
-
+
p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
/* turn on board and blink green LED */
@@ -1521,7 +1533,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
}
/* All F's is an empty slot or an invalid board */
- if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */
+ if (temp_register != 0xFFFFFFFF) {
res_lists.io_head = ctrl->io_head;
res_lists.mem_head = ctrl->mem_head;
res_lists.p_mem_head = ctrl->p_mem_head;
@@ -1570,9 +1582,8 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
index = 0;
do {
new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
- if (new_slot && !new_slot->pci_dev) {
+ if (new_slot && !new_slot->pci_dev)
cpqhp_configure_device(ctrl, new_slot);
- }
} while (new_slot);
mutex_lock(&ctrl->crit_sect);
@@ -1859,12 +1870,12 @@ static void interrupt_event_handler(struct controller *ctrl)
info(msg_button_on, p_slot->number);
}
mutex_lock(&ctrl->crit_sect);
-
+
dbg("blink green LED and turn off amber\n");
-
+
amber_LED_off (ctrl, hp_slot);
green_LED_blink (ctrl, hp_slot);
-
+
set_SOGO(ctrl);
/* Wait for SOBS to be unset */
@@ -1958,7 +1969,7 @@ void cpqhp_pushbutton_thread(unsigned long slot)
if (cpqhp_process_SI(ctrl, func) != 0) {
amber_LED_on(ctrl, hp_slot);
green_LED_off(ctrl, hp_slot);
-
+
set_SOGO(ctrl);
/* Wait for SOBS to be unset */
@@ -2079,7 +2090,7 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
struct pci_bus *pci_bus = ctrl->pci_bus;
int physical_slot=0;
- device = func->device;
+ device = func->device;
func = cpqhp_slot_find(ctrl->bus, device, index++);
p_slot = cpqhp_find_slot(ctrl, device);
if (p_slot) {
@@ -2113,9 +2124,8 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
/* If the VGA Enable bit is set, remove isn't
* supported */
- if (BCR & PCI_BRIDGE_CTL_VGA) {
+ if (BCR & PCI_BRIDGE_CTL_VGA)
rc = REMOVE_NOT_SUPPORTED;
- }
}
}
@@ -2183,67 +2193,67 @@ int cpqhp_hardware_test(struct controller *ctrl, int test_num)
num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;
switch (test_num) {
- case 1:
- /* Do stuff here! */
-
- /* Do that funky LED thing */
- /* so we can restore them later */
- save_LED = readl(ctrl->hpc_reg + LED_CONTROL);
- work_LED = 0x01010101;
- switch_leds(ctrl, num_of_slots, &work_LED, 0);
- switch_leds(ctrl, num_of_slots, &work_LED, 1);
- switch_leds(ctrl, num_of_slots, &work_LED, 0);
- switch_leds(ctrl, num_of_slots, &work_LED, 1);
-
- work_LED = 0x01010000;
- writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
- switch_leds(ctrl, num_of_slots, &work_LED, 0);
- switch_leds(ctrl, num_of_slots, &work_LED, 1);
- work_LED = 0x00000101;
- writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
- switch_leds(ctrl, num_of_slots, &work_LED, 0);
- switch_leds(ctrl, num_of_slots, &work_LED, 1);
+ case 1:
+ /* Do stuff here! */
+
+ /* Do that funky LED thing */
+ /* so we can restore them later */
+ save_LED = readl(ctrl->hpc_reg + LED_CONTROL);
+ work_LED = 0x01010101;
+ switch_leds(ctrl, num_of_slots, &work_LED, 0);
+ switch_leds(ctrl, num_of_slots, &work_LED, 1);
+ switch_leds(ctrl, num_of_slots, &work_LED, 0);
+ switch_leds(ctrl, num_of_slots, &work_LED, 1);
+
+ work_LED = 0x01010000;
+ writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+ switch_leds(ctrl, num_of_slots, &work_LED, 0);
+ switch_leds(ctrl, num_of_slots, &work_LED, 1);
+ work_LED = 0x00000101;
+ writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+ switch_leds(ctrl, num_of_slots, &work_LED, 0);
+ switch_leds(ctrl, num_of_slots, &work_LED, 1);
+
+ work_LED = 0x01010000;
+ writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+ for (loop = 0; loop < num_of_slots; loop++) {
+ set_SOGO(ctrl);
- work_LED = 0x01010000;
- writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
- for (loop = 0; loop < num_of_slots; loop++) {
- set_SOGO(ctrl);
+ /* Wait for SOGO interrupt */
+ wait_for_ctrl_irq (ctrl);
- /* Wait for SOGO interrupt */
- wait_for_ctrl_irq (ctrl);
+ /* Get ready for next iteration */
+ long_delay((3*HZ)/10);
+ work_LED = work_LED >> 16;
+ writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
- /* Get ready for next iteration */
- long_delay((3*HZ)/10);
- work_LED = work_LED >> 16;
- writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-
- set_SOGO(ctrl);
+ set_SOGO(ctrl);
- /* Wait for SOGO interrupt */
- wait_for_ctrl_irq (ctrl);
+ /* Wait for SOGO interrupt */
+ wait_for_ctrl_irq (ctrl);
- /* Get ready for next iteration */
- long_delay((3*HZ)/10);
- work_LED = work_LED << 16;
- writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
- work_LED = work_LED << 1;
- writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
- }
+ /* Get ready for next iteration */
+ long_delay((3*HZ)/10);
+ work_LED = work_LED << 16;
+ writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+ work_LED = work_LED << 1;
+ writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+ }
- /* put it back the way it was */
- writel(save_LED, ctrl->hpc_reg + LED_CONTROL);
+ /* put it back the way it was */
+ writel(save_LED, ctrl->hpc_reg + LED_CONTROL);
- set_SOGO(ctrl);
+ set_SOGO(ctrl);
- /* Wait for SOBS to be unset */
- wait_for_ctrl_irq (ctrl);
- break;
- case 2:
- /* Do other stuff here! */
- break;
- case 3:
- /* and more... */
- break;
+ /* Wait for SOBS to be unset */
+ wait_for_ctrl_irq (ctrl);
+ break;
+ case 2:
+ /* Do other stuff here! */
+ break;
+ case 3:
+ /* and more... */
+ break;
}
return 0;
}
@@ -2312,9 +2322,9 @@ static u32 configure_new_device(struct controller * ctrl, struct pci_func * func
while ((function < max_functions) && (!stop_it)) {
pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
- if (ID == 0xFFFFFFFF) { /* There's nothing there. */
+ if (ID == 0xFFFFFFFF) {
function++;
- } else { /* There's something there */
+ } else {
/* Setup slot structure. */
new_slot = cpqhp_slot_create(func->bus);
@@ -2339,8 +2349,8 @@ static u32 configure_new_device(struct controller * ctrl, struct pci_func * func
/*
- Configuration logic that involves the hotplug data structures and
- their bookkeeping
+ * Configuration logic that involves the hotplug data structures and
+ * their bookkeeping
*/
@@ -2393,7 +2403,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
if (rc)
return rc;
- if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
+ if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
/* set Primary bus */
dbg("set Primary bus = %d\n", func->bus);
rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
@@ -2484,7 +2494,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
temp_resources.irqs = &irqs;
/* Make copies of the nodes we are going to pass down so that
- * if there is a problem,we can just use these to free resources */
+ * if there is a problem,we can just use these to free resources
+ */
hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL);
hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL);
hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL);
@@ -2556,7 +2567,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
- /* Adjust this to compensate for extra adjustment in first loop */
+ /* Adjust this to compensate for extra adjustment in first loop
+ */
irqs.barber_pole--;
rc = 0;
@@ -2917,27 +2929,26 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
} /* End of base register loop */
if (cpqhp_legacy_mode) {
/* Figure out which interrupt pin this function uses */
- rc = pci_bus_read_config_byte (pci_bus, devfn,
+ rc = pci_bus_read_config_byte (pci_bus, devfn,
PCI_INTERRUPT_PIN, &temp_byte);
/* If this function needs an interrupt and we are behind
* a bridge and the pin is tied to something that's
* alread mapped, set this one the same */
- if (temp_byte && resources->irqs &&
- (resources->irqs->valid_INT &
+ if (temp_byte && resources->irqs &&
+ (resources->irqs->valid_INT &
(0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
/* We have to share with something already set up */
- IRQ = resources->irqs->interrupt[(temp_byte +
+ IRQ = resources->irqs->interrupt[(temp_byte +
resources->irqs->barber_pole - 1) & 0x03];
} else {
/* Program IRQ based on card type */
rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
- if (class_code == PCI_BASE_CLASS_STORAGE) {
+ if (class_code == PCI_BASE_CLASS_STORAGE)
IRQ = cpqhp_disk_irq;
- } else {
+ else
IRQ = cpqhp_nic_irq;
- }
}
/* IRQ Line */
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
index cb174888002b..76ba8a1c774d 100644
--- a/drivers/pci/hotplug/cpqphp_nvram.c
+++ b/drivers/pci/hotplug/cpqphp_nvram.c
@@ -94,12 +94,13 @@ static u8 evbuffer[1024];
static void __iomem *compaq_int15_entry_point;
-static spinlock_t int15_lock; /* lock for ordering int15_bios_call() */
+/* lock for ordering int15_bios_call() */
+static spinlock_t int15_lock;
/* This is a series of function that deals with
- setting & getting the hotplug resource table in some environment variable.
-*/
+ * setting & getting the hotplug resource table in some environment variable.
+ */
/*
* We really shouldn't be doing this unless there is a _very_ good reason to!!!
@@ -113,7 +114,7 @@ static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail)
if ((*used + 1) > *avail)
return(1);
-
+
*((u8*)*p_buffer) = value;
tByte = (u8**)p_buffer;
(*tByte)++;
@@ -170,10 +171,10 @@ static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
unsigned long flags;
int op = operation;
int ret_val;
-
+
if (!compaq_int15_entry_point)
return -ENODEV;
-
+
spin_lock_irqsave(&int15_lock, flags);
__asm__ (
"xorl %%ebx,%%ebx\n" \
@@ -187,7 +188,7 @@ static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
"D" (buffer), "m" (compaq_int15_entry_point)
: "%ebx", "%edx");
spin_unlock_irqrestore(&int15_lock, flags);
-
+
return((ret_val & 0xFF00) >> 8);
}
@@ -210,14 +211,16 @@ static int load_HRT (void __iomem *rom_start)
available = 1024;
- // Now load the EV
+ /* Now load the EV */
temp_dword = available;
rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword);
evbuffer_length = temp_dword;
- // We're maintaining the resource lists so write FF to invalidate old info
+ /* We're maintaining the resource lists so write FF to invalidate old
+ * info
+ */
temp_dword = 1;
rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword);
@@ -263,13 +266,13 @@ static u32 store_HRT (void __iomem *rom_start)
p_EV_header = (struct ev_hrt_header *) pFill;
ctrl = cpqhp_ctrl_list;
-
- // The revision of this structure
+
+ /* The revision of this structure */
rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available);
if (rc)
return(rc);
- // The number of controllers
+ /* The number of controllers */
rc = add_byte( &pFill, 1, &usedbytes, &available);
if (rc)
return(rc);
@@ -279,27 +282,27 @@ static u32 store_HRT (void __iomem *rom_start)
numCtrl++;
- // The bus number
+ /* The bus number */
rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available);
if (rc)
return(rc);
- // The device Number
+ /* The device Number */
rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
if (rc)
return(rc);
- // The function Number
+ /* The function Number */
rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
if (rc)
return(rc);
- // Skip the number of available entries
+ /* Skip the number of available entries */
rc = add_dword( &pFill, 0, &usedbytes, &available);
if (rc)
return(rc);
- // Figure out memory Available
+ /* Figure out memory Available */
resNode = ctrl->mem_head;
@@ -308,12 +311,12 @@ static u32 store_HRT (void __iomem *rom_start)
while (resNode) {
loop ++;
- // base
+ /* base */
rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
if (rc)
return(rc);
- // length
+ /* length */
rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
if (rc)
return(rc);
@@ -321,10 +324,10 @@ static u32 store_HRT (void __iomem *rom_start)
resNode = resNode->next;
}
- // Fill in the number of entries
+ /* Fill in the number of entries */
p_ev_ctrl->mem_avail = loop;
- // Figure out prefetchable memory Available
+ /* Figure out prefetchable memory Available */
resNode = ctrl->p_mem_head;
@@ -333,12 +336,12 @@ static u32 store_HRT (void __iomem *rom_start)
while (resNode) {
loop ++;
- // base
+ /* base */
rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
if (rc)
return(rc);
- // length
+ /* length */
rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
if (rc)
return(rc);
@@ -346,10 +349,10 @@ static u32 store_HRT (void __iomem *rom_start)
resNode = resNode->next;
}
- // Fill in the number of entries
+ /* Fill in the number of entries */
p_ev_ctrl->p_mem_avail = loop;
- // Figure out IO Available
+ /* Figure out IO Available */
resNode = ctrl->io_head;
@@ -358,12 +361,12 @@ static u32 store_HRT (void __iomem *rom_start)
while (resNode) {
loop ++;
- // base
+ /* base */
rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
if (rc)
return(rc);
- // length
+ /* length */
rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
if (rc)
return(rc);
@@ -371,10 +374,10 @@ static u32 store_HRT (void __iomem *rom_start)
resNode = resNode->next;
}
- // Fill in the number of entries
+ /* Fill in the number of entries */
p_ev_ctrl->io_avail = loop;
- // Figure out bus Available
+ /* Figure out bus Available */
resNode = ctrl->bus_head;
@@ -383,12 +386,12 @@ static u32 store_HRT (void __iomem *rom_start)
while (resNode) {
loop ++;
- // base
+ /* base */
rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
if (rc)
return(rc);
- // length
+ /* length */
rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
if (rc)
return(rc);
@@ -396,15 +399,15 @@ static u32 store_HRT (void __iomem *rom_start)
resNode = resNode->next;
}
- // Fill in the number of entries
+ /* Fill in the number of entries */
p_ev_ctrl->bus_avail = loop;
ctrl = ctrl->next;
}
-
+
p_EV_header->num_of_ctrl = numCtrl;
- // Now store the EV
+ /* Now store the EV */
temp_dword = usedbytes;
@@ -449,20 +452,21 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
struct ev_hrt_header *p_EV_header;
if (!evbuffer_init) {
- // Read the resource list information in from NVRAM
+ /* Read the resource list information in from NVRAM */
if (load_HRT(rom_start))
memset (evbuffer, 0, 1024);
evbuffer_init = 1;
}
- // If we saved information in NVRAM, use it now
+ /* If we saved information in NVRAM, use it now */
p_EV_header = (struct ev_hrt_header *) evbuffer;
- // The following code is for systems where version 1.0 of this
- // driver has been loaded, but doesn't support the hardware.
- // In that case, the driver would incorrectly store something
- // in NVRAM.
+ /* The following code is for systems where version 1.0 of this
+ * driver has been loaded, but doesn't support the hardware.
+ * In that case, the driver would incorrectly store something
+ * in NVRAM.
+ */
if ((p_EV_header->Version == 2) ||
((p_EV_header->Version == 1) && !ctrl->push_flag)) {
p_byte = &(p_EV_header->next);
@@ -479,7 +483,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
function = p_ev_ctrl->function;
while ((bus != ctrl->bus) ||
- (device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
+ (device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
(function != PCI_FUNC(ctrl->pci_dev->devfn))) {
nummem = p_ev_ctrl->mem_avail;
numpmem = p_ev_ctrl->p_mem_avail;
@@ -491,7 +495,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
if (p_byte > ((u8*)p_EV_header + evbuffer_length))
return 2;
- // Skip forward to the next entry
+ /* Skip forward to the next entry */
p_byte += (nummem + numpmem + numio + numbus) * 8;
if (p_byte > ((u8*)p_EV_header + evbuffer_length))
@@ -629,8 +633,9 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
ctrl->bus_head = bus_node;
}
- // If all of the following fail, we don't have any resources for
- // hot plug add
+ /* If all of the following fail, we don't have any resources for
+ * hot plug add
+ */
rc = 1;
rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
@@ -640,14 +645,14 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
if (rc)
return(rc);
} else {
- if ((evbuffer[0] != 0) && (!ctrl->push_flag))
+ if ((evbuffer[0] != 0) && (!ctrl->push_flag))
return 1;
}
return 0;
}
-
+
int compaq_nvram_store (void __iomem *rom_start)
{
int rc = 1;
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index 6c0ed0fcb8ee..6173b9a4544e 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -37,7 +37,6 @@
#include "../pci.h"
#include "cpqphp.h"
#include "cpqphp_nvram.h"
-#include <asm/pci_x86.h>
u8 cpqhp_nic_irq;
@@ -82,14 +81,14 @@ static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iom
}
-int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
+int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
{
unsigned char bus;
struct pci_bus *child;
int num;
if (func->pci_dev == NULL)
- func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
+ func->pci_dev = pci_get_bus_and_slot(func->bus,PCI_DEVFN(func->device, func->function));
/* No pci device, we need to create it then */
if (func->pci_dev == NULL) {
@@ -99,7 +98,7 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
if (num)
pci_bus_add_devices(ctrl->pci_dev->bus);
- func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
+ func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function));
if (func->pci_dev == NULL) {
dbg("ERROR: pci_dev still null\n");
return 0;
@@ -112,20 +111,24 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
pci_do_scan_bus(child);
}
+ pci_dev_put(func->pci_dev);
+
return 0;
}
-int cpqhp_unconfigure_device(struct pci_func* func)
+int cpqhp_unconfigure_device(struct pci_func* func)
{
int j;
-
+
dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function);
for (j=0; j<8 ; j++) {
- struct pci_dev* temp = pci_find_slot(func->bus, PCI_DEVFN(func->device, j));
- if (temp)
+ struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j));
+ if (temp) {
+ pci_dev_put(temp);
pci_remove_bus_device(temp);
+ }
}
return 0;
}
@@ -178,32 +181,22 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
if (!rc)
return !rc;
- // set the Edge Level Control Register (ELCR)
+ /* set the Edge Level Control Register (ELCR) */
temp_word = inb(0x4d0);
temp_word |= inb(0x4d1) << 8;
temp_word |= 0x01 << irq_num;
- // This should only be for x86 as it sets the Edge Level Control Register
- outb((u8) (temp_word & 0xFF), 0x4d0);
- outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
- rc = 0;
- }
+ /* This should only be for x86 as it sets the Edge Level
+ * Control Register
+ */
+ outb((u8) (temp_word & 0xFF), 0x4d0); outb((u8) ((temp_word &
+ 0xFF00) >> 8), 0x4d1); rc = 0; }
return rc;
}
-/*
- * WTF??? This function isn't in the code, yet a function calls it, but the
- * compiler optimizes it away? strange. Here as a placeholder to keep the
- * compiler happy.
- */
-static int PCI_ScanBusNonBridge (u8 bus, u8 device)
-{
- return 0;
-}
-
static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num)
{
u16 tdevice;
@@ -213,11 +206,11 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
ctrl->pci_bus->number = bus_num;
for (tdevice = 0; tdevice < 0xFF; tdevice++) {
- //Scan for access first
+ /* Scan for access first */
if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
continue;
dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
- //Yep we got one. Not a bridge ?
+ /* Yep we got one. Not a bridge ? */
if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) {
*dev_num = tdevice;
dbg("found it !\n");
@@ -225,16 +218,16 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
}
}
for (tdevice = 0; tdevice < 0xFF; tdevice++) {
- //Scan for access first
+ /* Scan for access first */
if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
continue;
dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
- //Yep we got one. bridge ?
+ /* Yep we got one. bridge ? */
if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
+ /* XXX: no recursion, wtf? */
dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
- if (PCI_ScanBusNonBridge(tbus, tdevice) == 0)
- return 0;
+ return 0;
}
}
@@ -244,39 +237,23 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
{
- struct irq_routing_table *PCIIRQRoutingInfoLength;
- long len;
- long loop;
+ int loop, len;
u32 work;
-
u8 tbus, tdevice, tslot;
- PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
- if (!PCIIRQRoutingInfoLength)
- return -1;
-
- len = (PCIIRQRoutingInfoLength->size -
- sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
- // Make sure I got at least one entry
- if (len == 0) {
- kfree(PCIIRQRoutingInfoLength );
- return -1;
- }
-
+ len = cpqhp_routing_table_length();
for (loop = 0; loop < len; ++loop) {
- tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
- tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn;
- tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
+ tbus = cpqhp_routing_table->slots[loop].bus;
+ tdevice = cpqhp_routing_table->slots[loop].devfn;
+ tslot = cpqhp_routing_table->slots[loop].slot;
if (tslot == slot) {
*bus_num = tbus;
*dev_num = tdevice;
ctrl->pci_bus->number = tbus;
pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
- if (!nobridge || (work == 0xffffffff)) {
- kfree(PCIIRQRoutingInfoLength );
+ if (!nobridge || (work == 0xffffffff))
return 0;
- }
dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
@@ -287,28 +264,26 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
dbg("Scan bus for Non Bridge: bus %d\n", tbus);
if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
*bus_num = tbus;
- kfree(PCIIRQRoutingInfoLength );
return 0;
}
- } else {
- kfree(PCIIRQRoutingInfoLength );
+ } else
return 0;
- }
-
}
}
- kfree(PCIIRQRoutingInfoLength );
return -1;
}
int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot)
{
- return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0); //plain (bridges allowed)
+ /* plain (bridges allowed) */
+ return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0);
}
-/* More PCI configuration routines; this time centered around hotplug controller */
+/* More PCI configuration routines; this time centered around hotplug
+ * controller
+ */
/*
@@ -339,12 +314,12 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
int stop_it;
int index;
- // Decide which slots are supported
+ /* Decide which slots are supported */
if (is_hot_plug) {
- //*********************************
- // is_hot_plug is the slot mask
- //*********************************
+ /*
+ * is_hot_plug is the slot mask
+ */
FirstSupported = is_hot_plug >> 4;
LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1;
} else {
@@ -352,123 +327,127 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
LastSupported = 0x1F;
}
- // Save PCI configuration space for all devices in supported slots
+ /* Save PCI configuration space for all devices in supported slots */
ctrl->pci_bus->number = busnumber;
for (device = FirstSupported; device <= LastSupported; device++) {
ID = 0xFFFFFFFF;
- rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
+ rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
+
+ if (ID == 0xFFFFFFFF) {
+ if (is_hot_plug) {
+ /* Setup slot structure with entry for empty
+ * slot
+ */
+ new_slot = cpqhp_slot_create(busnumber);
+ if (new_slot == NULL)
+ return 1;
- if (ID != 0xFFFFFFFF) { // device in slot
- rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
- if (rc)
- return rc;
+ new_slot->bus = (u8) busnumber;
+ new_slot->device = (u8) device;
+ new_slot->function = 0;
+ new_slot->is_a_board = 0;
+ new_slot->presence_save = 0;
+ new_slot->switch_save = 0;
+ }
+ continue;
+ }
- rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
- if (rc)
- return rc;
+ rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
+ if (rc)
+ return rc;
- // If multi-function device, set max_functions to 8
- if (header_type & 0x80)
- max_functions = 8;
- else
- max_functions = 1;
+ rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
+ if (rc)
+ return rc;
- function = 0;
+ /* If multi-function device, set max_functions to 8 */
+ if (header_type & 0x80)
+ max_functions = 8;
+ else
+ max_functions = 1;
- do {
- DevError = 0;
+ function = 0;
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // P-P Bridge
- // Recurse the subordinate bus
- // get the subordinate bus number
- rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
- if (rc) {
+ do {
+ DevError = 0;
+ if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ /* Recurse the subordinate bus
+ * get the subordinate bus number
+ */
+ rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
+ if (rc) {
+ return rc;
+ } else {
+ sub_bus = (int) secondary_bus;
+
+ /* Save secondary bus cfg spc
+ * with this recursive call.
+ */
+ rc = cpqhp_save_config(ctrl, sub_bus, 0);
+ if (rc)
return rc;
- } else {
- sub_bus = (int) secondary_bus;
-
- // Save secondary bus cfg spc
- // with this recursive call.
- rc = cpqhp_save_config(ctrl, sub_bus, 0);
- if (rc)
- return rc;
- ctrl->pci_bus->number = busnumber;
- }
+ ctrl->pci_bus->number = busnumber;
}
+ }
- index = 0;
+ index = 0;
+ new_slot = cpqhp_slot_find(busnumber, device, index++);
+ while (new_slot &&
+ (new_slot->function != (u8) function))
new_slot = cpqhp_slot_find(busnumber, device, index++);
- while (new_slot &&
- (new_slot->function != (u8) function))
- new_slot = cpqhp_slot_find(busnumber, device, index++);
- if (!new_slot) {
- // Setup slot structure.
- new_slot = cpqhp_slot_create(busnumber);
-
- if (new_slot == NULL)
- return(1);
- }
-
- new_slot->bus = (u8) busnumber;
- new_slot->device = (u8) device;
- new_slot->function = (u8) function;
- new_slot->is_a_board = 1;
- new_slot->switch_save = 0x10;
- // In case of unsupported board
- new_slot->status = DevError;
- new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
-
- for (cloop = 0; cloop < 0x20; cloop++) {
- rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
- if (rc)
- return rc;
- }
+ if (!new_slot) {
+ /* Setup slot structure. */
+ new_slot = cpqhp_slot_create(busnumber);
+ if (new_slot == NULL)
+ return 1;
+ }
- function++;
+ new_slot->bus = (u8) busnumber;
+ new_slot->device = (u8) device;
+ new_slot->function = (u8) function;
+ new_slot->is_a_board = 1;
+ new_slot->switch_save = 0x10;
+ /* In case of unsupported board */
+ new_slot->status = DevError;
+ new_slot->pci_dev = pci_get_bus_and_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
- stop_it = 0;
+ for (cloop = 0; cloop < 0x20; cloop++) {
+ rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
+ if (rc)
+ return rc;
+ }
- // this loop skips to the next present function
- // reading in Class Code and Header type.
+ pci_dev_put(new_slot->pci_dev);
- while ((function < max_functions)&&(!stop_it)) {
- rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
- if (ID == 0xFFFFFFFF) { // nothing there.
- function++;
- } else { // Something there
- rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
- if (rc)
- return rc;
+ function++;
- rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
- if (rc)
- return rc;
+ stop_it = 0;
- stop_it++;
- }
+ /* this loop skips to the next present function
+ * reading in Class Code and Header type.
+ */
+ while ((function < max_functions) && (!stop_it)) {
+ rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
+ if (ID == 0xFFFFFFFF) {
+ function++;
+ continue;
}
+ rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
+ if (rc)
+ return rc;
- } while (function < max_functions);
- } // End of IF (device in slot?)
- else if (is_hot_plug) {
- // Setup slot structure with entry for empty slot
- new_slot = cpqhp_slot_create(busnumber);
+ rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
+ if (rc)
+ return rc;
- if (new_slot == NULL) {
- return(1);
+ stop_it++;
}
- new_slot->bus = (u8) busnumber;
- new_slot->device = (u8) device;
- new_slot->function = 0;
- new_slot->is_a_board = 0;
- new_slot->presence_save = 0;
- new_slot->switch_save = 0;
- }
- } // End of FOR loop
+ } while (function < max_functions);
+ } /* End of FOR loop */
- return(0);
+ return 0;
}
@@ -489,7 +468,7 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
u8 secondary_bus;
int sub_bus;
int max_functions;
- int function;
+ int function = 0;
int cloop = 0;
int stop_it;
@@ -498,63 +477,58 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
ctrl->pci_bus->number = new_slot->bus;
pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
- if (ID != 0xFFFFFFFF) { // device in slot
- pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
- pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
-
- if (header_type & 0x80) // Multi-function device
- max_functions = 8;
- else
- max_functions = 1;
-
- function = 0;
-
- do {
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
- // Recurse the subordinate bus
- pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
+ if (ID == 0xFFFFFFFF)
+ return 2;
- sub_bus = (int) secondary_bus;
+ pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
+ pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
- // Save the config headers for the secondary bus.
- rc = cpqhp_save_config(ctrl, sub_bus, 0);
- if (rc)
- return(rc);
- ctrl->pci_bus->number = new_slot->bus;
+ if (header_type & 0x80) /* Multi-function device */
+ max_functions = 8;
+ else
+ max_functions = 1;
- } // End of IF
+ while (function < max_functions) {
+ if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ /* Recurse the subordinate bus */
+ pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
- new_slot->status = 0;
+ sub_bus = (int) secondary_bus;
- for (cloop = 0; cloop < 0x20; cloop++) {
- pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
- }
+ /* Save the config headers for the secondary
+ * bus.
+ */
+ rc = cpqhp_save_config(ctrl, sub_bus, 0);
+ if (rc)
+ return(rc);
+ ctrl->pci_bus->number = new_slot->bus;
- function++;
+ }
- stop_it = 0;
+ new_slot->status = 0;
- // this loop skips to the next present function
- // reading in the Class Code and the Header type.
+ for (cloop = 0; cloop < 0x20; cloop++)
+ pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
- while ((function < max_functions) && (!stop_it)) {
- pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
+ function++;
- if (ID == 0xFFFFFFFF) { // nothing there.
- function++;
- } else { // Something there
- pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
+ stop_it = 0;
- pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
+ /* this loop skips to the next present function
+ * reading in the Class Code and the Header type.
+ */
+ while ((function < max_functions) && (!stop_it)) {
+ pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
- stop_it++;
- }
+ if (ID == 0xFFFFFFFF)
+ function++;
+ else {
+ pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
+ pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
+ stop_it++;
}
+ }
- } while (function < max_functions);
- } // End of IF (device in slot?)
- else {
- return 2;
}
return 0;
@@ -590,11 +564,10 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
- // Check for Bridge
+ /* Check for Bridge */
pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
- // PCI-PCI Bridge
pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
sub_bus = (int) secondary_bus;
@@ -610,23 +583,27 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
}
pci_bus->number = func->bus;
- //FIXME: this loop is duplicated in the non-bridge case. The two could be rolled together
- // Figure out IO and memory base lengths
+ /* FIXME: this loop is duplicated in the non-bridge
+ * case. The two could be rolled together Figure out
+ * IO and memory base lengths
+ */
for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
temp_register = 0xFFFFFFFF;
pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
-
- if (base) { // If this register is implemented
+ /* If this register is implemented */
+ if (base) {
if (base & 0x01L) {
- // IO base
- // set base = amount of IO space requested
+ /* IO base
+ * set base = amount of IO space
+ * requested
+ */
base = base & 0xFFFFFFFE;
base = (~base) + 1;
type = 1;
} else {
- // memory base
+ /* memory base */
base = base & 0xFFFFFFF0;
base = (~base) + 1;
@@ -637,32 +614,36 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
type = 0;
}
- // Save information in slot structure
+ /* Save information in slot structure */
func->base_length[(cloop - 0x10) >> 2] =
base;
func->base_type[(cloop - 0x10) >> 2] = type;
- } // End of base register loop
+ } /* End of base register loop */
-
- } else if ((header_type & 0x7F) == 0x00) { // PCI-PCI Bridge
- // Figure out IO and memory base lengths
+ } else if ((header_type & 0x7F) == 0x00) {
+ /* Figure out IO and memory base lengths */
for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF;
pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
- if (base) { // If this register is implemented
+ /* If this register is implemented */
+ if (base) {
if (base & 0x01L) {
- // IO base
- // base = amount of IO space requested
+ /* IO base
+ * base = amount of IO space
+ * requested
+ */
base = base & 0xFFFFFFFE;
base = (~base) + 1;
type = 1;
} else {
- // memory base
- // base = amount of memory space requested
+ /* memory base
+ * base = amount of memory
+ * space requested
+ */
base = base & 0xFFFFFFF0;
base = (~base) + 1;
@@ -673,16 +654,16 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
type = 0;
}
- // Save information in slot structure
+ /* Save information in slot structure */
func->base_length[(cloop - 0x10) >> 2] = base;
func->base_type[(cloop - 0x10) >> 2] = type;
- } // End of base register loop
+ } /* End of base register loop */
- } else { // Some other unknown header type
+ } else { /* Some other unknown header type */
}
- // find the next device in this slot
+ /* find the next device in this slot */
func = cpqhp_slot_find(func->bus, func->device, index++);
}
@@ -728,18 +709,18 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
- // Save the command register
+ /* Save the command register */
pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
- // disable card
+ /* disable card */
command = 0x00;
pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
- // Check for Bridge
+ /* Check for Bridge */
pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
- // Clear Bridge Control Register
+ if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ /* Clear Bridge Control Register */
command = 0x00;
pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
@@ -755,7 +736,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
bus_node->next = func->bus_head;
func->bus_head = bus_node;
- // Save IO base and Limit registers
+ /* Save IO base and Limit registers */
pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &b_base);
pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length);
@@ -771,7 +752,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
func->io_head = io_node;
}
- // Save memory base and Limit registers
+ /* Save memory base and Limit registers */
pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
@@ -787,7 +768,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
func->mem_head = mem_node;
}
- // Save prefetchable memory base and Limit registers
+ /* Save prefetchable memory base and Limit registers */
pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
@@ -802,7 +783,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
p_mem_node->next = func->p_mem_head;
func->p_mem_head = p_mem_node;
}
- // Figure out IO and memory base lengths
+ /* Figure out IO and memory base lengths */
for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
@@ -812,11 +793,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
temp_register = base;
- if (base) { // If this register is implemented
+ /* If this register is implemented */
+ if (base) {
if (((base & 0x03L) == 0x01)
&& (save_command & 0x01)) {
- // IO base
- // set temp_register = amount of IO space requested
+ /* IO base
+ * set temp_register = amount
+ * of IO space requested
+ */
temp_register = base & 0xFFFFFFFE;
temp_register = (~temp_register) + 1;
@@ -834,7 +818,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} else
if (((base & 0x0BL) == 0x08)
&& (save_command & 0x02)) {
- // prefetchable memory base
+ /* prefetchable memory base */
temp_register = base & 0xFFFFFFF0;
temp_register = (~temp_register) + 1;
@@ -851,7 +835,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} else
if (((base & 0x0BL) == 0x00)
&& (save_command & 0x02)) {
- // prefetchable memory base
+ /* prefetchable memory base */
temp_register = base & 0xFFFFFFF0;
temp_register = (~temp_register) + 1;
@@ -868,9 +852,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} else
return(1);
}
- } // End of base register loop
- } else if ((header_type & 0x7F) == 0x00) { // Standard header
- // Figure out IO and memory base lengths
+ } /* End of base register loop */
+ /* Standard header */
+ } else if ((header_type & 0x7F) == 0x00) {
+ /* Figure out IO and memory base lengths */
for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
@@ -880,11 +865,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
temp_register = base;
- if (base) { // If this register is implemented
+ /* If this register is implemented */
+ if (base) {
if (((base & 0x03L) == 0x01)
&& (save_command & 0x01)) {
- // IO base
- // set temp_register = amount of IO space requested
+ /* IO base
+ * set temp_register = amount
+ * of IO space requested
+ */
temp_register = base & 0xFFFFFFFE;
temp_register = (~temp_register) + 1;
@@ -901,7 +889,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} else
if (((base & 0x0BL) == 0x08)
&& (save_command & 0x02)) {
- // prefetchable memory base
+ /* prefetchable memory base */
temp_register = base & 0xFFFFFFF0;
temp_register = (~temp_register) + 1;
@@ -918,7 +906,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} else
if (((base & 0x0BL) == 0x00)
&& (save_command & 0x02)) {
- // prefetchable memory base
+ /* prefetchable memory base */
temp_register = base & 0xFFFFFFF0;
temp_register = (~temp_register) + 1;
@@ -935,15 +923,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} else
return(1);
}
- } // End of base register loop
- } else { // Some other unknown header type
+ } /* End of base register loop */
}
- // find the next device in this slot
+ /* find the next device in this slot */
func = cpqhp_slot_find(func->bus, func->device, index++);
}
- return(0);
+ return 0;
}
@@ -975,16 +962,16 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
- // Start at the top of config space so that the control
- // registers are programmed last
- for (cloop = 0x3C; cloop > 0; cloop -= 4) {
+ /* Start at the top of config space so that the control
+ * registers are programmed last
+ */
+ for (cloop = 0x3C; cloop > 0; cloop -= 4)
pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
- }
pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
- // If this is a bridge device, restore subordinate devices
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
+ /* If this is a bridge device, restore subordinate devices */
+ if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
sub_bus = (int) secondary_bus;
@@ -1000,8 +987,9 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
}
} else {
- // Check all the base Address Registers to make sure
- // they are the same. If not, the board is different.
+ /* Check all the base Address Registers to make sure
+ * they are the same. If not, the board is different.
+ */
for (cloop = 16; cloop < 40; cloop += 4) {
pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp);
@@ -1058,27 +1046,28 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
- // No adapter present
+ /* No adapter present */
if (temp_register == 0xFFFFFFFF)
return(NO_ADAPTER_PRESENT);
if (temp_register != func->config_space[0])
return(ADAPTER_NOT_SAME);
- // Check for same revision number and class code
+ /* Check for same revision number and class code */
pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
- // Adapter not the same
+ /* Adapter not the same */
if (temp_register != func->config_space[0x08 >> 2])
return(ADAPTER_NOT_SAME);
- // Check for Bridge
+ /* Check for Bridge */
pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
- // In order to continue checking, we must program the
- // bus registers in the bridge to respond to accesses
- // for it's subordinate bus(es)
+ if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ /* In order to continue checking, we must program the
+ * bus registers in the bridge to respond to accesses
+ * for its subordinate bus(es)
+ */
temp_register = func->config_space[0x18 >> 2];
pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
@@ -1096,35 +1085,39 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
}
}
- // Check to see if it is a standard config header
+ /* Check to see if it is a standard config header */
else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
- // Check subsystem vendor and ID
+ /* Check subsystem vendor and ID */
pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
if (temp_register != func->config_space[0x2C >> 2]) {
- // If it's a SMART-2 and the register isn't filled
- // in, ignore the difference because
- // they just have an old rev of the firmware
-
+ /* If it's a SMART-2 and the register isn't
+ * filled in, ignore the difference because
+ * they just have an old rev of the firmware
+ */
if (!((func->config_space[0] == 0xAE100E11)
&& (temp_register == 0x00L)))
return(ADAPTER_NOT_SAME);
}
- // Figure out IO and memory base lengths
+ /* Figure out IO and memory base lengths */
for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF;
pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
- if (base) { // If this register is implemented
+
+ /* If this register is implemented */
+ if (base) {
if (base & 0x01L) {
- // IO base
- // set base = amount of IO space requested
+ /* IO base
+ * set base = amount of IO
+ * space requested
+ */
base = base & 0xFFFFFFFE;
base = (~base) + 1;
type = 1;
} else {
- // memory base
+ /* memory base */
base = base & 0xFFFFFFF0;
base = (~base) + 1;
@@ -1135,23 +1128,24 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
type = 0;
}
- // Check information in slot structure
+ /* Check information in slot structure */
if (func->base_length[(cloop - 0x10) >> 2] != base)
return(ADAPTER_NOT_SAME);
if (func->base_type[(cloop - 0x10) >> 2] != type)
return(ADAPTER_NOT_SAME);
- } // End of base register loop
+ } /* End of base register loop */
- } // End of (type 0 config space) else
+ } /* End of (type 0 config space) else */
else {
- // this is not a type 0 or 1 config space header so
- // we don't know how to do it
+ /* this is not a type 0 or 1 config space header so
+ * we don't know how to do it
+ */
return(DEVICE_TYPE_NOT_SUPPORTED);
}
- // Get the next function
+ /* Get the next function */
func = cpqhp_slot_find(func->bus, func->device, index++);
}
@@ -1168,7 +1162,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
* this function is for hot plug ADD!
*
* returns 0 if success
- */
+ */
int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start)
{
u8 temp;
@@ -1187,10 +1181,10 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
dbg("rom_resource_table = %p\n", rom_resource_table);
- if (rom_resource_table == NULL) {
+ if (rom_resource_table == NULL)
return -ENODEV;
- }
- // Sum all resources and setup resource maps
+
+ /* Sum all resources and setup resource maps */
unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
dbg("unused_IRQ = %x\n", unused_IRQ);
@@ -1222,13 +1216,11 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
temp = 0;
- if (!cpqhp_nic_irq) {
+ if (!cpqhp_nic_irq)
cpqhp_nic_irq = ctrl->cfgspc_irq;
- }
- if (!cpqhp_disk_irq) {
+ if (!cpqhp_disk_irq)
cpqhp_disk_irq = ctrl->cfgspc_irq;
- }
dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);
@@ -1262,13 +1254,13 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
primary_bus, secondary_bus, max_bus);
- // If this entry isn't for our controller's bus, ignore it
+ /* If this entry isn't for our controller's bus, ignore it */
if (primary_bus != ctrl->bus) {
i--;
one_slot += sizeof (struct slot_rt);
continue;
}
- // find out if this entry is for an occupied slot
+ /* find out if this entry is for an occupied slot */
ctrl->pci_bus->number = primary_bus;
pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
dbg("temp_D_word = %x\n", temp_dword);
@@ -1282,13 +1274,13 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++);
}
- // If we can't find a match, skip this table entry
+ /* If we can't find a match, skip this table entry */
if (!func) {
i--;
one_slot += sizeof (struct slot_rt);
continue;
}
- // this may not work and shouldn't be used
+ /* this may not work and shouldn't be used */
if (secondary_bus != primary_bus)
bridged_slot = 1;
else
@@ -1301,7 +1293,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
}
- // If we've got a valid IO base, use it
+ /* If we've got a valid IO base, use it */
temp_dword = io_base + io_length;
@@ -1325,7 +1317,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
}
}
- // If we've got a valid memory base, use it
+ /* If we've got a valid memory base, use it */
temp_dword = mem_base + mem_length;
if ((mem_base) && (temp_dword < 0x10000)) {
mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL);
@@ -1348,8 +1340,9 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
}
}
- // If we've got a valid prefetchable memory base, and
- // the base + length isn't greater than 0xFFFF
+ /* If we've got a valid prefetchable memory base, and
+ * the base + length isn't greater than 0xFFFF
+ */
temp_dword = pre_mem_base + pre_mem_length;
if ((pre_mem_base) && (temp_dword < 0x10000)) {
p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL);
@@ -1372,9 +1365,10 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
}
}
- // If we've got a valid bus number, use it
- // The second condition is to ignore bus numbers on
- // populated slots that don't have PCI-PCI bridges
+ /* If we've got a valid bus number, use it
+ * The second condition is to ignore bus numbers on
+ * populated slots that don't have PCI-PCI bridges
+ */
if (secondary_bus && (secondary_bus != primary_bus)) {
bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL);
if (!bus_node)
@@ -1398,8 +1392,9 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
one_slot += sizeof (struct slot_rt);
}
- // If all of the following fail, we don't have any resources for
- // hot plug add
+ /* If all of the following fail, we don't have any resources for
+ * hot plug add
+ */
rc = 1;
rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index dd18f857dfb0..29ccb8a6da8a 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -1419,3 +1419,4 @@ static void __exit ibmphp_exit(void)
}
module_init(ibmphp_init);
+module_exit(ibmphp_exit);
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
index 6808d8333ecc..737a1c44b07a 100644
--- a/drivers/pci/htirq.c
+++ b/drivers/pci/htirq.c
@@ -98,6 +98,7 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
int max_irq;
int pos;
int irq;
+ int node;
pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ);
if (!pos)
@@ -125,7 +126,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
cfg->msg.address_lo = 0xffffffff;
cfg->msg.address_hi = 0xffffffff;
- irq = create_irq();
+ node = dev_to_node(&dev->dev);
+ irq = create_irq_nr(0, node);
if (irq <= 0) {
kfree(cfg);
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 001b328adf80..8cd4aacd0711 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -53,12 +53,18 @@
#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
+#define MAX_AGAW_WIDTH 64
+
#define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
#define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32))
#define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64))
+#ifndef PHYSICAL_PAGE_MASK
+#define PHYSICAL_PAGE_MASK PAGE_MASK
+#endif
+
/* global iommu list, set NULL for ignored DMAR units */
static struct intel_iommu **g_iommus;
@@ -127,8 +133,6 @@ static inline void context_set_fault_enable(struct context_entry *context)
context->lo &= (((u64)-1) << 2) | 1;
}
-#define CONTEXT_TT_MULTI_LEVEL 0
-
static inline void context_set_translation_type(struct context_entry *context,
unsigned long value)
{
@@ -397,17 +401,13 @@ void free_iova_mem(struct iova *iova)
static inline int width_to_agaw(int width);
-/* calculate agaw for each iommu.
- * "SAGAW" may be different across iommus, use a default agaw, and
- * get a supported less agaw for iommus that don't support the default agaw.
- */
-int iommu_calculate_agaw(struct intel_iommu *iommu)
+static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
{
unsigned long sagaw;
int agaw = -1;
sagaw = cap_sagaw(iommu->cap);
- for (agaw = width_to_agaw(DEFAULT_DOMAIN_ADDRESS_WIDTH);
+ for (agaw = width_to_agaw(max_gaw);
agaw >= 0; agaw--) {
if (test_bit(agaw, &sagaw))
break;
@@ -416,6 +416,24 @@ int iommu_calculate_agaw(struct intel_iommu *iommu)
return agaw;
}
+/*
+ * Calculate max SAGAW for each iommu.
+ */
+int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
+{
+ return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
+}
+
+/*
+ * calculate agaw for each iommu.
+ * "SAGAW" may be different across iommus, use a default agaw, and
+ * get a supported less agaw for iommus that don't support the default agaw.
+ */
+int iommu_calculate_agaw(struct intel_iommu *iommu)
+{
+ return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
+}
+
/* in native case, each domain is related to only one iommu */
static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
{
@@ -805,7 +823,7 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu)
static void iommu_set_root_entry(struct intel_iommu *iommu)
{
void *addr;
- u32 cmd, sts;
+ u32 sts;
unsigned long flag;
addr = iommu->root_entry;
@@ -813,12 +831,11 @@ static void iommu_set_root_entry(struct intel_iommu *iommu)
spin_lock_irqsave(&iommu->register_lock, flag);
dmar_writeq(iommu->reg + DMAR_RTADDR_REG, virt_to_phys(addr));
- cmd = iommu->gcmd | DMA_GCMD_SRTP;
- writel(cmd, iommu->reg + DMAR_GCMD_REG);
+ writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
/* Make sure hardware complete it */
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
- readl, (sts & DMA_GSTS_RTPS), sts);
+ readl, (sts & DMA_GSTS_RTPS), sts);
spin_unlock_irqrestore(&iommu->register_lock, flag);
}
@@ -830,39 +847,25 @@ static void iommu_flush_write_buffer(struct intel_iommu *iommu)
if (!rwbf_quirk && !cap_rwbf(iommu->cap))
return;
- val = iommu->gcmd | DMA_GCMD_WBF;
spin_lock_irqsave(&iommu->register_lock, flag);
- writel(val, iommu->reg + DMAR_GCMD_REG);
+ writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
/* Make sure hardware complete it */
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
- readl, (!(val & DMA_GSTS_WBFS)), val);
+ readl, (!(val & DMA_GSTS_WBFS)), val);
spin_unlock_irqrestore(&iommu->register_lock, flag);
}
/* return value determine if we need a write buffer flush */
-static int __iommu_flush_context(struct intel_iommu *iommu,
- u16 did, u16 source_id, u8 function_mask, u64 type,
- int non_present_entry_flush)
+static void __iommu_flush_context(struct intel_iommu *iommu,
+ u16 did, u16 source_id, u8 function_mask,
+ u64 type)
{
u64 val = 0;
unsigned long flag;
- /*
- * In the non-present entry flush case, if hardware doesn't cache
- * non-present entry we do nothing and if hardware cache non-present
- * entry, we flush entries of domain 0 (the domain id is used to cache
- * any non-present entries)
- */
- if (non_present_entry_flush) {
- if (!cap_caching_mode(iommu->cap))
- return 1;
- else
- did = 0;
- }
-
switch (type) {
case DMA_CCMD_GLOBAL_INVL:
val = DMA_CCMD_GLOBAL_INVL;
@@ -887,33 +890,16 @@ static int __iommu_flush_context(struct intel_iommu *iommu,
dmar_readq, (!(val & DMA_CCMD_ICC)), val);
spin_unlock_irqrestore(&iommu->register_lock, flag);
-
- /* flush context entry will implicitly flush write buffer */
- return 0;
}
/* return value determine if we need a write buffer flush */
-static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
- u64 addr, unsigned int size_order, u64 type,
- int non_present_entry_flush)
+static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
+ u64 addr, unsigned int size_order, u64 type)
{
int tlb_offset = ecap_iotlb_offset(iommu->ecap);
u64 val = 0, val_iva = 0;
unsigned long flag;
- /*
- * In the non-present entry flush case, if hardware doesn't cache
- * non-present entry we do nothing and if hardware cache non-present
- * entry, we flush entries of domain 0 (the domain id is used to cache
- * any non-present entries)
- */
- if (non_present_entry_flush) {
- if (!cap_caching_mode(iommu->cap))
- return 1;
- else
- did = 0;
- }
-
switch (type) {
case DMA_TLB_GLOBAL_FLUSH:
/* global flush doesn't need set IVA_REG */
@@ -961,12 +947,10 @@ static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n",
(unsigned long long)DMA_TLB_IIRG(type),
(unsigned long long)DMA_TLB_IAIG(val));
- /* flush iotlb entry will implicitly flush write buffer */
- return 0;
}
-static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
- u64 addr, unsigned int pages, int non_present_entry_flush)
+static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
+ u64 addr, unsigned int pages)
{
unsigned int mask;
@@ -976,8 +960,7 @@ static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
/* Fallback to domain selective flush if no PSI support */
if (!cap_pgsel_inv(iommu->cap))
return iommu->flush.flush_iotlb(iommu, did, 0, 0,
- DMA_TLB_DSI_FLUSH,
- non_present_entry_flush);
+ DMA_TLB_DSI_FLUSH);
/*
* PSI requires page size to be 2 ^ x, and the base address is naturally
@@ -987,11 +970,10 @@ static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
/* Fallback to domain selective flush if size is too big */
if (mask > cap_max_amask_val(iommu->cap))
return iommu->flush.flush_iotlb(iommu, did, 0, 0,
- DMA_TLB_DSI_FLUSH, non_present_entry_flush);
+ DMA_TLB_DSI_FLUSH);
return iommu->flush.flush_iotlb(iommu, did, addr, mask,
- DMA_TLB_PSI_FLUSH,
- non_present_entry_flush);
+ DMA_TLB_PSI_FLUSH);
}
static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
@@ -1017,13 +999,13 @@ static int iommu_enable_translation(struct intel_iommu *iommu)
unsigned long flags;
spin_lock_irqsave(&iommu->register_lock, flags);
- writel(iommu->gcmd|DMA_GCMD_TE, iommu->reg + DMAR_GCMD_REG);
+ iommu->gcmd |= DMA_GCMD_TE;
+ writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
/* Make sure hardware complete it */
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
- readl, (sts & DMA_GSTS_TES), sts);
+ readl, (sts & DMA_GSTS_TES), sts);
- iommu->gcmd |= DMA_GCMD_TE;
spin_unlock_irqrestore(&iommu->register_lock, flags);
return 0;
}
@@ -1039,7 +1021,7 @@ static int iommu_disable_translation(struct intel_iommu *iommu)
/* Make sure hardware complete it */
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
- readl, (!(sts & DMA_GSTS_TES)), sts);
+ readl, (!(sts & DMA_GSTS_TES)), sts);
spin_unlock_irqrestore(&iommu->register_lock, flag);
return 0;
@@ -1216,7 +1198,7 @@ static void dmar_init_reserved_ranges(void)
if (!r->flags || !(r->flags & IORESOURCE_MEM))
continue;
addr = r->start;
- addr &= PAGE_MASK;
+ addr &= PHYSICAL_PAGE_MASK;
size = r->end - addr;
size = PAGE_ALIGN(size);
iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr),
@@ -1321,8 +1303,8 @@ static void domain_exit(struct dmar_domain *domain)
free_domain_mem(domain);
}
-static int domain_context_mapping_one(struct dmar_domain *domain,
- int segment, u8 bus, u8 devfn)
+static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
+ u8 bus, u8 devfn, int translation)
{
struct context_entry *context;
unsigned long flags;
@@ -1335,7 +1317,10 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
pr_debug("Set context mapping for %02x:%02x.%d\n",
bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+
BUG_ON(!domain->pgd);
+ BUG_ON(translation != CONTEXT_TT_PASS_THROUGH &&
+ translation != CONTEXT_TT_MULTI_LEVEL);
iommu = device_to_iommu(segment, bus, devfn);
if (!iommu)
@@ -1395,21 +1380,37 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
}
context_set_domain_id(context, id);
- context_set_address_width(context, iommu->agaw);
- context_set_address_root(context, virt_to_phys(pgd));
- context_set_translation_type(context, CONTEXT_TT_MULTI_LEVEL);
+
+ /*
+ * In pass through mode, AW must be programmed to indicate the largest
+ * AGAW value supported by hardware. And ASR is ignored by hardware.
+ */
+ if (likely(translation == CONTEXT_TT_MULTI_LEVEL)) {
+ context_set_address_width(context, iommu->agaw);
+ context_set_address_root(context, virt_to_phys(pgd));
+ } else
+ context_set_address_width(context, iommu->msagaw);
+
+ context_set_translation_type(context, translation);
context_set_fault_enable(context);
context_set_present(context);
domain_flush_cache(domain, context, sizeof(*context));
- /* it's a non-present to present mapping */
- if (iommu->flush.flush_context(iommu, domain->id,
- (((u16)bus) << 8) | devfn, DMA_CCMD_MASK_NOBIT,
- DMA_CCMD_DEVICE_INVL, 1))
+ /*
+ * It's a non-present to present mapping. If hardware doesn't cache
+ * non-present entry we only need to flush the write-buffer. If the
+ * _does_ cache non-present entries, then it does so in the special
+ * domain #0, which we have to flush:
+ */
+ if (cap_caching_mode(iommu->cap)) {
+ iommu->flush.flush_context(iommu, 0,
+ (((u16)bus) << 8) | devfn,
+ DMA_CCMD_MASK_NOBIT,
+ DMA_CCMD_DEVICE_INVL);
+ iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_DSI_FLUSH);
+ } else {
iommu_flush_write_buffer(iommu);
- else
- iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_DSI_FLUSH, 0);
-
+ }
spin_unlock_irqrestore(&iommu->lock, flags);
spin_lock_irqsave(&domain->iommu_lock, flags);
@@ -1422,13 +1423,15 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
}
static int
-domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
+domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev,
+ int translation)
{
int ret;
struct pci_dev *tmp, *parent;
ret = domain_context_mapping_one(domain, pci_domain_nr(pdev->bus),
- pdev->bus->number, pdev->devfn);
+ pdev->bus->number, pdev->devfn,
+ translation);
if (ret)
return ret;
@@ -1442,7 +1445,7 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
ret = domain_context_mapping_one(domain,
pci_domain_nr(parent->bus),
parent->bus->number,
- parent->devfn);
+ parent->devfn, translation);
if (ret)
return ret;
parent = parent->bus->self;
@@ -1450,12 +1453,14 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
return domain_context_mapping_one(domain,
pci_domain_nr(tmp->subordinate),
- tmp->subordinate->number, 0);
+ tmp->subordinate->number, 0,
+ translation);
else /* this is a legacy PCI bridge */
return domain_context_mapping_one(domain,
pci_domain_nr(tmp->bus),
tmp->bus->number,
- tmp->devfn);
+ tmp->devfn,
+ translation);
}
static int domain_context_mapped(struct pci_dev *pdev)
@@ -1536,9 +1541,8 @@ static void iommu_detach_dev(struct intel_iommu *iommu, u8 bus, u8 devfn)
clear_context_table(iommu, bus, devfn);
iommu->flush.flush_context(iommu, 0, 0, 0,
- DMA_CCMD_GLOBAL_INVL, 0);
- iommu->flush.flush_iotlb(iommu, 0, 0, 0,
- DMA_TLB_GLOBAL_FLUSH, 0);
+ DMA_CCMD_GLOBAL_INVL);
+ iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
}
static void domain_remove_dev_info(struct dmar_domain *domain)
@@ -1752,7 +1756,7 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
goto error;
/* context entry init */
- ret = domain_context_mapping(domain, pdev);
+ ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL);
if (!ret)
return 0;
error:
@@ -1853,6 +1857,23 @@ static inline void iommu_prepare_isa(void)
}
#endif /* !CONFIG_DMAR_FLPY_WA */
+/* Initialize each context entry as pass through.*/
+static int __init init_context_pass_through(void)
+{
+ struct pci_dev *pdev = NULL;
+ struct dmar_domain *domain;
+ int ret;
+
+ for_each_pci_dev(pdev) {
+ domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
+ ret = domain_context_mapping(domain, pdev,
+ CONTEXT_TT_PASS_THROUGH);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
static int __init init_dmars(void)
{
struct dmar_drhd_unit *drhd;
@@ -1860,6 +1881,7 @@ static int __init init_dmars(void)
struct pci_dev *pdev;
struct intel_iommu *iommu;
int i, ret;
+ int pass_through = 1;
/*
* for each drhd
@@ -1913,7 +1935,15 @@ static int __init init_dmars(void)
printk(KERN_ERR "IOMMU: allocate root entry failed\n");
goto error;
}
+ if (!ecap_pass_through(iommu->ecap))
+ pass_through = 0;
}
+ if (iommu_pass_through)
+ if (!pass_through) {
+ printk(KERN_INFO
+ "Pass Through is not supported by hardware.\n");
+ iommu_pass_through = 0;
+ }
/*
* Start from the sane iommu hardware state.
@@ -1968,45 +1998,57 @@ static int __init init_dmars(void)
}
}
-#ifdef CONFIG_INTR_REMAP
- if (!intr_remapping_enabled) {
- ret = enable_intr_remapping(0);
- if (ret)
- printk(KERN_ERR
- "IOMMU: enable interrupt remapping failed\n");
+ /*
+ * If pass through is set and enabled, context entries of all pci
+ * devices are intialized by pass through translation type.
+ */
+ if (iommu_pass_through) {
+ ret = init_context_pass_through();
+ if (ret) {
+ printk(KERN_ERR "IOMMU: Pass through init failed.\n");
+ iommu_pass_through = 0;
+ }
}
-#endif
/*
- * For each rmrr
- * for each dev attached to rmrr
- * do
- * locate drhd for dev, alloc domain for dev
- * allocate free domain
- * allocate page table entries for rmrr
- * if context not allocated for bus
- * allocate and init context
- * set present in root table for this bus
- * init context with domain, translation etc
- * endfor
- * endfor
+ * If pass through is not set or not enabled, setup context entries for
+ * identity mappings for rmrr, gfx, and isa.
*/
- for_each_rmrr_units(rmrr) {
- for (i = 0; i < rmrr->devices_cnt; i++) {
- pdev = rmrr->devices[i];
- /* some BIOS lists non-exist devices in DMAR table */
- if (!pdev)
- continue;
- ret = iommu_prepare_rmrr_dev(rmrr, pdev);
- if (ret)
- printk(KERN_ERR
+ if (!iommu_pass_through) {
+ /*
+ * For each rmrr
+ * for each dev attached to rmrr
+ * do
+ * locate drhd for dev, alloc domain for dev
+ * allocate free domain
+ * allocate page table entries for rmrr
+ * if context not allocated for bus
+ * allocate and init context
+ * set present in root table for this bus
+ * init context with domain, translation etc
+ * endfor
+ * endfor
+ */
+ for_each_rmrr_units(rmrr) {
+ for (i = 0; i < rmrr->devices_cnt; i++) {
+ pdev = rmrr->devices[i];
+ /*
+ * some BIOS lists non-exist devices in DMAR
+ * table.
+ */
+ if (!pdev)
+ continue;
+ ret = iommu_prepare_rmrr_dev(rmrr, pdev);
+ if (ret)
+ printk(KERN_ERR
"IOMMU: mapping reserved region failed\n");
+ }
}
- }
- iommu_prepare_gfx_mapping();
+ iommu_prepare_gfx_mapping();
- iommu_prepare_isa();
+ iommu_prepare_isa();
+ }
/*
* for each drhd
@@ -2028,10 +2070,8 @@ static int __init init_dmars(void)
iommu_set_root_entry(iommu);
- iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL,
- 0);
- iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH,
- 0);
+ iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
+ iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
iommu_disable_protect_mem_regions(iommu);
ret = iommu_enable_translation(iommu);
@@ -2117,7 +2157,8 @@ get_valid_domain_for_dev(struct pci_dev *pdev)
/* make sure context mapping is ok */
if (unlikely(!domain_context_mapped(pdev))) {
- ret = domain_context_mapping(domain, pdev);
+ ret = domain_context_mapping(domain, pdev,
+ CONTEXT_TT_MULTI_LEVEL);
if (ret) {
printk(KERN_ERR
"Domain context map for %s failed",
@@ -2173,14 +2214,16 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
* is not a big problem
*/
ret = domain_page_mapping(domain, start_paddr,
- ((u64)paddr) & PAGE_MASK, size, prot);
+ ((u64)paddr) & PHYSICAL_PAGE_MASK,
+ size, prot);
if (ret)
goto error;
- /* it's a non-present to present mapping */
- ret = iommu_flush_iotlb_psi(iommu, domain->id,
- start_paddr, size >> VTD_PAGE_SHIFT, 1);
- if (ret)
+ /* it's a non-present to present mapping. Only flush if caching mode */
+ if (cap_caching_mode(iommu->cap))
+ iommu_flush_iotlb_psi(iommu, 0, start_paddr,
+ size >> VTD_PAGE_SHIFT);
+ else
iommu_flush_write_buffer(iommu);
return start_paddr + ((u64)paddr & (~PAGE_MASK));
@@ -2216,7 +2259,7 @@ static void flush_unmaps(void)
if (deferred_flush[i].next) {
iommu->flush.flush_iotlb(iommu, 0, 0, 0,
- DMA_TLB_GLOBAL_FLUSH, 0);
+ DMA_TLB_GLOBAL_FLUSH);
for (j = 0; j < deferred_flush[i].next; j++) {
__free_iova(&deferred_flush[i].domain[j]->iovad,
deferred_flush[i].iova[j]);
@@ -2295,9 +2338,8 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
/* free page tables */
dma_pte_free_pagetable(domain, start_addr, start_addr + size);
if (intel_iommu_strict) {
- if (iommu_flush_iotlb_psi(iommu,
- domain->id, start_addr, size >> VTD_PAGE_SHIFT, 0))
- iommu_flush_write_buffer(iommu);
+ iommu_flush_iotlb_psi(iommu, domain->id, start_addr,
+ size >> VTD_PAGE_SHIFT);
/* free iova */
__free_iova(&domain->iovad, iova);
} else {
@@ -2388,9 +2430,8 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
/* free page tables */
dma_pte_free_pagetable(domain, start_addr, start_addr + size);
- if (iommu_flush_iotlb_psi(iommu, domain->id, start_addr,
- size >> VTD_PAGE_SHIFT, 0))
- iommu_flush_write_buffer(iommu);
+ iommu_flush_iotlb_psi(iommu, domain->id, start_addr,
+ size >> VTD_PAGE_SHIFT);
/* free iova */
__free_iova(&domain->iovad, iova);
@@ -2463,8 +2504,8 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne
addr = page_to_phys(sg_page(sg)) + sg->offset;
size = aligned_size((u64)addr, sg->length);
ret = domain_page_mapping(domain, start_addr + offset,
- ((u64)addr) & PAGE_MASK,
- size, prot);
+ ((u64)addr) & PHYSICAL_PAGE_MASK,
+ size, prot);
if (ret) {
/* clear the page */
dma_pte_clear_range(domain, start_addr,
@@ -2482,10 +2523,13 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne
offset += size;
}
- /* it's a non-present to present mapping */
- if (iommu_flush_iotlb_psi(iommu, domain->id,
- start_addr, offset >> VTD_PAGE_SHIFT, 1))
+ /* it's a non-present to present mapping. Only flush if caching mode */
+ if (cap_caching_mode(iommu->cap))
+ iommu_flush_iotlb_psi(iommu, 0, start_addr,
+ offset >> VTD_PAGE_SHIFT);
+ else
iommu_flush_write_buffer(iommu);
+
return nelems;
}
@@ -2644,9 +2688,9 @@ static int init_iommu_hw(void)
iommu_set_root_entry(iommu);
iommu->flush.flush_context(iommu, 0, 0, 0,
- DMA_CCMD_GLOBAL_INVL, 0);
+ DMA_CCMD_GLOBAL_INVL);
iommu->flush.flush_iotlb(iommu, 0, 0, 0,
- DMA_TLB_GLOBAL_FLUSH, 0);
+ DMA_TLB_GLOBAL_FLUSH);
iommu_disable_protect_mem_regions(iommu);
iommu_enable_translation(iommu);
}
@@ -2661,9 +2705,9 @@ static void iommu_flush_all(void)
for_each_active_iommu(iommu, drhd) {
iommu->flush.flush_context(iommu, 0, 0, 0,
- DMA_CCMD_GLOBAL_INVL, 0);
+ DMA_CCMD_GLOBAL_INVL);
iommu->flush.flush_iotlb(iommu, 0, 0, 0,
- DMA_TLB_GLOBAL_FLUSH, 0);
+ DMA_TLB_GLOBAL_FLUSH);
}
}
@@ -2786,7 +2830,7 @@ int __init intel_iommu_init(void)
* Check the need for DMA-remapping initialization now.
* Above initialization will also be used by Interrupt-remapping.
*/
- if (no_iommu || swiotlb || dmar_disabled)
+ if (no_iommu || (swiotlb && !iommu_pass_through) || dmar_disabled)
return -ENODEV;
iommu_init_mempool();
@@ -2806,7 +2850,15 @@ int __init intel_iommu_init(void)
init_timer(&unmap_timer);
force_iommu = 1;
- dma_ops = &intel_dma_ops;
+
+ if (!iommu_pass_through) {
+ printk(KERN_INFO
+ "Multi-level page-table translation for DMAR.\n");
+ dma_ops = &intel_dma_ops;
+ } else
+ printk(KERN_INFO
+ "DMAR: Pass through translation for DMAR.\n");
+
init_iommu_sysfs();
register_iommu(&intel_iommu_ops);
@@ -3146,7 +3198,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
return -EFAULT;
}
- ret = domain_context_mapping(dmar_domain, pdev);
+ ret = domain_context_mapping(dmar_domain, pdev, CONTEXT_TT_MULTI_LEVEL);
if (ret)
return ret;
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index f5e0ea724a6f..1e83c8c5f985 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -15,6 +15,14 @@ static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
static int ir_ioapic_num;
int intr_remapping_enabled;
+static int disable_intremap;
+static __init int setup_nointremap(char *str)
+{
+ disable_intremap = 1;
+ return 0;
+}
+early_param("nointremap", setup_nointremap);
+
struct irq_2_iommu {
struct intel_iommu *iommu;
u16 irte_index;
@@ -23,15 +31,12 @@ struct irq_2_iommu {
};
#ifdef CONFIG_GENERIC_HARDIRQS
-static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
+static struct irq_2_iommu *get_one_free_irq_2_iommu(int node)
{
struct irq_2_iommu *iommu;
- int node;
-
- node = cpu_to_node(cpu);
iommu = kzalloc_node(sizeof(*iommu), GFP_ATOMIC, node);
- printk(KERN_DEBUG "alloc irq_2_iommu on cpu %d node %d\n", cpu, node);
+ printk(KERN_DEBUG "alloc irq_2_iommu on node %d\n", node);
return iommu;
}
@@ -48,7 +53,7 @@ static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
return desc->irq_2_iommu;
}
-static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu)
+static struct irq_2_iommu *irq_2_iommu_alloc_node(unsigned int irq, int node)
{
struct irq_desc *desc;
struct irq_2_iommu *irq_iommu;
@@ -56,7 +61,7 @@ static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu)
/*
* alloc irq desc if not allocated already.
*/
- desc = irq_to_desc_alloc_cpu(irq, cpu);
+ desc = irq_to_desc_alloc_node(irq, node);
if (!desc) {
printk(KERN_INFO "can not get irq_desc for %d\n", irq);
return NULL;
@@ -65,14 +70,14 @@ static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu)
irq_iommu = desc->irq_2_iommu;
if (!irq_iommu)
- desc->irq_2_iommu = get_one_free_irq_2_iommu(cpu);
+ desc->irq_2_iommu = get_one_free_irq_2_iommu(node);
return desc->irq_2_iommu;
}
static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
{
- return irq_2_iommu_alloc_cpu(irq, boot_cpu_id);
+ return irq_2_iommu_alloc_node(irq, cpu_to_node(boot_cpu_id));
}
#else /* !CONFIG_SPARSE_IRQ */
@@ -404,7 +409,7 @@ int free_irte(int irq)
static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
{
u64 addr;
- u32 cmd, sts;
+ u32 sts;
unsigned long flags;
addr = virt_to_phys((void *)iommu->ir_table->base);
@@ -415,28 +420,13 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
(addr) | IR_X2APIC_MODE(mode) | INTR_REMAP_TABLE_REG_SIZE);
/* Set interrupt-remapping table pointer */
- cmd = iommu->gcmd | DMA_GCMD_SIRTP;
iommu->gcmd |= DMA_GCMD_SIRTP;
- writel(cmd, iommu->reg + DMAR_GCMD_REG);
+ writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
readl, (sts & DMA_GSTS_IRTPS), sts);
spin_unlock_irqrestore(&iommu->register_lock, flags);
- if (mode == 0) {
- spin_lock_irqsave(&iommu->register_lock, flags);
-
- /* enable comaptiblity format interrupt pass through */
- cmd = iommu->gcmd | DMA_GCMD_CFI;
- iommu->gcmd |= DMA_GCMD_CFI;
- writel(cmd, iommu->reg + DMAR_GCMD_REG);
-
- IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
- readl, (sts & DMA_GSTS_CFIS), sts);
-
- spin_unlock_irqrestore(&iommu->register_lock, flags);
- }
-
/*
* global invalidation of interrupt entry cache before enabling
* interrupt-remapping.
@@ -446,9 +436,8 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
spin_lock_irqsave(&iommu->register_lock, flags);
/* Enable interrupt-remapping */
- cmd = iommu->gcmd | DMA_GCMD_IRE;
iommu->gcmd |= DMA_GCMD_IRE;
- writel(cmd, iommu->reg + DMAR_GCMD_REG);
+ writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
readl, (sts & DMA_GSTS_IRES), sts);
@@ -516,6 +505,23 @@ end:
spin_unlock_irqrestore(&iommu->register_lock, flags);
}
+int __init intr_remapping_supported(void)
+{
+ struct dmar_drhd_unit *drhd;
+
+ if (disable_intremap)
+ return 0;
+
+ for_each_drhd_unit(drhd) {
+ struct intel_iommu *iommu = drhd->iommu;
+
+ if (!ecap_ir_support(iommu->ecap))
+ return 0;
+ }
+
+ return 1;
+}
+
int __init enable_intr_remapping(int eim)
{
struct dmar_drhd_unit *drhd;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 6f2e6295e773..7ffac27d5d4a 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -381,7 +381,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
entry->msi_attrib.pos = pos;
- entry->mask_pos = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
+ entry->mask_pos = msi_mask_reg(pos, entry->msi_attrib.is_64);
/* All MSIs are unmasked by default, Mask them all */
if (entry->msi_attrib.maskbit)
pci_read_config_dword(dev, entry->mask_pos, &entry->masked);
@@ -455,8 +455,6 @@ static int msix_capability_init(struct pci_dev *dev,
entry->msi_attrib.default_irq = dev->irq;
entry->msi_attrib.pos = pos;
entry->mask_base = base;
- entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE +
- PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
msix_mask_irq(entry, 1);
list_add_tail(&entry->list, &dev->msi_list);
@@ -493,6 +491,12 @@ static int msix_capability_init(struct pci_dev *dev,
msix_set_enable(dev, 1);
dev->msix_enabled = 1;
+ list_for_each_entry(entry, &dev->msi_list, list) {
+ int vector = entry->msi_attrib.entry_nr;
+ entry->masked = readl(base + vector * PCI_MSIX_ENTRY_SIZE +
+ PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+ }
+
return 0;
}
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index 71f4df2ef654..a0662842550b 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -16,21 +16,15 @@
#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO)
#define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI)
#define msi_data_reg(base, is64bit) \
- ( (is64bit == 1) ? base+PCI_MSI_DATA_64 : base+PCI_MSI_DATA_32 )
-#define msi_mask_bits_reg(base, is64bit) \
- ( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4)
-#define msi_disable(control) control &= ~PCI_MSI_FLAGS_ENABLE
+ (base + ((is64bit == 1) ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32))
+#define msi_mask_reg(base, is64bit) \
+ (base + ((is64bit == 1) ? PCI_MSI_MASK_64 : PCI_MSI_MASK_32))
#define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT))
#define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT))
#define msix_table_offset_reg(base) (base + 0x04)
#define msix_pba_offset_reg(base) (base + 0x08)
-#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE
-#define msix_disable(control) control &= ~PCI_MSIX_FLAGS_ENABLE
#define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1)
-#define multi_msix_capable msix_table_size
-#define msix_unmask(address) (address & ~PCI_MSIX_FLAGS_BITMASK)
-#define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK)
-#define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK)
+#define multi_msix_capable(control) msix_table_size((control))
#endif /* MSI_H */
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index c7ad68b6c6d6..aa14482a4779 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -95,6 +95,9 @@ struct aer_broadcast_data {
static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
enum pci_ers_result new)
{
+ if (new == PCI_ERS_RESULT_NONE)
+ return orig;
+
switch (orig) {
case PCI_ERS_RESULT_CAN_RECOVER:
case PCI_ERS_RESULT_RECOVERED:
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index e39982503863..13ffdc35ea0e 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -275,7 +275,7 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
memset(device, 0, sizeof(struct device));
device->bus = &pcie_port_bus_type;
device->driver = NULL;
- device->driver_data = NULL;
+ dev_set_drvdata(device, NULL);
device->release = release_pcie_device; /* callback to free pcie dev */
dev_set_name(device, "%s:pcie%02x",
pci_name(parent), get_descriptor_id(port_type, service_type));
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index b924e2463f85..091ce70051e0 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -200,7 +200,7 @@ static int slot_reset_iter(struct device *device, void *data)
static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)
{
- pci_ers_result_t status = PCI_ERS_RESULT_NONE;
+ pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
int retval;
/* If fatal, restore cfg space for possible link reset at upstream */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e3c3e081b834..3daa7f824da1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -193,7 +193,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN;
if (type == pci_bar_io) {
l &= PCI_BASE_ADDRESS_IO_MASK;
- mask = PCI_BASE_ADDRESS_IO_MASK & 0xffff;
+ mask = PCI_BASE_ADDRESS_IO_MASK & IO_SPACE_LIMIT;
} else {
l &= PCI_BASE_ADDRESS_MEM_MASK;
mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
@@ -237,6 +237,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
dev_printk(KERN_DEBUG, &dev->dev,
"reg %x 64bit mmio: %pR\n", pos, res);
}
+
+ res->flags |= IORESOURCE_MEM_64;
} else {
sz = pci_size(l, sz, mask);
@@ -362,7 +364,10 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
}
}
if (base <= limit) {
- res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
+ IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ if (res->flags & PCI_PREF_RANGE_TYPE_64)
+ res->flags |= IORESOURCE_MEM_64;
res->start = base;
res->end = limit + 0xfffff;
dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n",
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 3067673d54f6..bd4253f93d5a 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2461,6 +2461,8 @@ static void __devinit quirk_i82576_sriov(struct pci_dev *dev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c9, quirk_i82576_sriov);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e6, quirk_i82576_sriov);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov);
#endif /* CONFIG_PCI_IOV */
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 710d4ea69568..650bc0a538dc 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -115,36 +115,6 @@ pci_find_next_bus(const struct pci_bus *from)
#ifdef CONFIG_PCI_LEGACY
/**
- * pci_find_slot - locate PCI device from a given PCI slot
- * @bus: number of PCI bus on which desired PCI device resides
- * @devfn: encodes number of PCI slot in which the desired PCI
- * device resides and the logical device number within that slot
- * in case of multi-function devices.
- *
- * Given a PCI bus and slot/function number, the desired PCI device
- * is located in system global list of PCI devices. If the device
- * is found, a pointer to its data structure is returned. If no
- * device is found, %NULL is returned.
- *
- * NOTE: Do not use this function any more; use pci_get_slot() instead, as
- * the PCI device returned by this function can disappear at any moment in
- * time.
- */
-struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
-{
- struct pci_dev *dev = NULL;
-
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- if (dev->bus->number == bus && dev->devfn == devfn) {
- pci_dev_put(dev);
- return dev;
- }
- }
- return NULL;
-}
-EXPORT_SYMBOL(pci_find_slot);
-
-/**
* pci_find_device - begin or continue searching for a PCI device by vendor/device id
* @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
* @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index a00f85471b6e..b636e245445d 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -58,7 +58,6 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus)
res = list->res;
idx = res - &list->dev->resource[0];
if (pci_assign_resource(list->dev, idx)) {
- /* FIXME: get rid of this */
res->start = 0;
res->end = 0;
res->flags = 0;
@@ -143,6 +142,7 @@ static void pci_setup_bridge(struct pci_bus *bus)
struct pci_dev *bridge = bus->self;
struct pci_bus_region region;
u32 l, bu, lu, io_upper16;
+ int pref_mem64;
if (pci_is_enabled(bridge))
return;
@@ -198,16 +198,22 @@ static void pci_setup_bridge(struct pci_bus *bus)
pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
/* Set up PREF base/limit. */
+ pref_mem64 = 0;
bu = lu = 0;
pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
+ int width = 8;
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
- bu = upper_32_bits(region.start);
- lu = upper_32_bits(region.end);
- dev_info(&bridge->dev, " PREFETCH window: %#016llx-%#016llx\n",
- (unsigned long long)region.start,
- (unsigned long long)region.end);
+ if (bus->resource[2]->flags & IORESOURCE_MEM_64) {
+ pref_mem64 = 1;
+ bu = upper_32_bits(region.start);
+ lu = upper_32_bits(region.end);
+ width = 16;
+ }
+ dev_info(&bridge->dev, " PREFETCH window: %#0*llx-%#0*llx\n",
+ width, (unsigned long long)region.start,
+ width, (unsigned long long)region.end);
}
else {
l = 0x0000fff0;
@@ -215,9 +221,11 @@ static void pci_setup_bridge(struct pci_bus *bus)
}
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
- /* Set the upper 32 bits of PREF base & limit. */
- pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
- pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
+ if (pref_mem64) {
+ /* Set the upper 32 bits of PREF base & limit. */
+ pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
+ pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
+ }
pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
}
@@ -255,8 +263,25 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
}
- if (pmem)
+ if (pmem) {
b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64)
+ b_res[2].flags |= IORESOURCE_MEM_64;
+ }
+
+ /* double check if bridge does support 64 bit pref */
+ if (b_res[2].flags & IORESOURCE_MEM_64) {
+ u32 mem_base_hi, tmp;
+ pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32,
+ &mem_base_hi);
+ pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
+ 0xffffffff);
+ pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
+ if (!tmp)
+ b_res[2].flags &= ~IORESOURCE_MEM_64;
+ pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
+ mem_base_hi);
+ }
}
/* Helper function for sizing routines: find first available
@@ -336,6 +361,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
int order, max_order;
struct resource *b_res = find_free_bus_resource(bus, type);
+ unsigned int mem64_mask = 0;
if (!b_res)
return 0;
@@ -344,9 +370,12 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
max_order = 0;
size = 0;
+ mem64_mask = b_res->flags & IORESOURCE_MEM_64;
+ b_res->flags &= ~IORESOURCE_MEM_64;
+
list_for_each_entry(dev, &bus->devices, bus_list) {
int i;
-
+
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
struct resource *r = &dev->resource[i];
resource_size_t r_size;
@@ -372,6 +401,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
aligns[order] += align;
if (order > max_order)
max_order = order;
+ mem64_mask &= r->flags & IORESOURCE_MEM_64;
}
}
@@ -396,6 +426,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
b_res->start = min_align;
b_res->end = size + min_align - 1;
b_res->flags |= IORESOURCE_STARTALIGN;
+ b_res->flags |= mem64_mask;
return 1;
}
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 3039fcb86afc..0b6908b48935 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -135,23 +135,16 @@ void pci_disable_bridge_window(struct pci_dev *dev)
}
#endif /* CONFIG_PCI_QUIRKS */
-int pci_assign_resource(struct pci_dev *dev, int resno)
+static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
+ int resno)
{
- struct pci_bus *bus = dev->bus;
struct resource *res = dev->resource + resno;
resource_size_t size, min, align;
int ret;
size = resource_size(res);
min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
-
align = resource_alignment(res);
- if (!align) {
- dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
- "alignment) %pR flags %#lx\n",
- resno, res, res->flags);
- return -EINVAL;
- }
/* First, try exact prefetching match.. */
ret = pci_bus_alloc_resource(bus, res, size, align, min,
@@ -169,10 +162,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
pcibios_align_resource, dev);
}
- if (ret) {
- dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
- resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
- } else {
+ if (!ret) {
res->flags &= ~IORESOURCE_STARTALIGN;
if (resno < PCI_BRIDGE_RESOURCES)
pci_update_resource(dev, resno);
@@ -181,6 +171,39 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
return ret;
}
+int pci_assign_resource(struct pci_dev *dev, int resno)
+{
+ struct resource *res = dev->resource + resno;
+ resource_size_t align;
+ struct pci_bus *bus;
+ int ret;
+
+ align = resource_alignment(res);
+ if (!align) {
+ dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
+ "alignment) %pR flags %#lx\n",
+ resno, res, res->flags);
+ return -EINVAL;
+ }
+
+ bus = dev->bus;
+ while ((ret = __pci_assign_resource(bus, dev, resno))) {
+ if (bus->parent && bus->self->transparent)
+ bus = bus->parent;
+ else
+ bus = NULL;
+ if (bus)
+ continue;
+ break;
+ }
+
+ if (ret)
+ dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
+ resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
+
+ return ret;
+}
+
#if 0
int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
{
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 284ebaca6e45..075791fe663c 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -143,6 +143,19 @@ config MSI_LAPTOP
If you have an MSI S270 laptop, say Y or M here.
+config OQO_WMI
+ tristate "OQO WMI extras"
+ depends on ACPI_WMI
+ depends on INPUT && INPUT_POLLDEV
+ depends on RFKILL
+ depends on BACKLIGHT_CLASS_DEVICE
+ help
+ Say Y here if you want to support rfkill and backlight control on
+ series 2 OQO handheld devices.
+
+ To compile this driver as a module, choose M here: the module will
+ be called oqo-wmi.
+
config PANASONIC_LAPTOP
tristate "Panasonic Laptop Extras"
depends on INPUT && ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index e40c7bd1b87e..1637378ad3f4 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o
+obj-$(CONFIG_OQO_WMI) += oqo-wmi.o
obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o
obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o
obj-$(CONFIG_ACPI_WMI) += wmi.o
diff --git a/drivers/platform/x86/oqo-wmi.c b/drivers/platform/x86/oqo-wmi.c
new file mode 100644
index 000000000000..0a88af82f127
--- /dev/null
+++ b/drivers/platform/x86/oqo-wmi.c
@@ -0,0 +1,941 @@
+/*
+ * OQO WMI UPMC Extras
+ *
+ * Copyright (C) 2008 Brian S. Julin <bri@abrij.org>
+ *
+ * Based on acer-wmi:
+ * Copyright (C) 2007-2008 Carlos Corbacho <cathectic@gmail.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
+ */
+
+/*
+ * NOTE: You need to turn SMI on in BIOS (if dmidecode works, you already have)
+ * NOTE: acpi-wmi support mandatory
+ * NOTE: backlight and inputdev support a must, ifdefs will come later
+ */
+
+/*
+ *
+ * 0.3: added WLAN enable switch, restore settings on unload,
+ * resume/suspend handling
+ * 0.2: Still not production-ready, but added ambient light sensor,
+ * backlight, and it prints the unit serial number to dmesg (do
+ * not know where to make that available to userspace yet.)
+ * 0.1: This is a first cut. Plan to reboot after playing with this.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/dmi.h>
+#include <linux/backlight.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
+#include <linux/i8042.h>
+#include <linux/input-polldev.h>
+#include <linux/rfkill.h>
+
+#include <acpi/acpi_drivers.h>
+
+MODULE_AUTHOR("Brian Julin");
+MODULE_DESCRIPTION("OQO UPMC WMI Extras Driver");
+MODULE_LICENSE("GPL");
+
+#define OQO_LOGPREFIX "oqo-wmi: "
+#define OQO_ERR KERN_ERR OQO_LOGPREFIX
+#define OQO_NOTICE KERN_NOTICE OQO_LOGPREFIX
+#define OQO_INFO KERN_INFO OQO_LOGPREFIX
+
+#define OQO_KINE_MAXTRY 3
+
+/* Store defined devices globally since we only have one instance. */
+static struct platform_device *oqo_platform_device;
+static struct backlight_device *oqo_backlight_device;
+static struct rfkill *oqo_rfkill;
+static struct input_dev *oqo_kine;
+static struct input_polled_dev *oqo_kine_polled;
+
+/* Likewise store current and original settings globally. */
+struct oqo_settings {
+ int lid_wakes; /* not sure if ACPI handles/needs help here */
+ int kine_itvl;
+ int bl_bright;
+};
+
+static struct oqo_settings orig, curr;
+
+/* Some of this code is left like in acer-wmi so we can add the older
+ Model 01 and any future models more easily, but we should not expect
+ it to be as complicated as Acer given each model is a leap rather than
+ a subtle variant on the last, so we aren't using "quirks" perse. Not
+ sure if there is any real difference for our purposes between the o2
+ and e2.
+*/
+struct oqo_model {
+ const char *model;
+ u16 model_subs;
+};
+#define MODEL_SUB_OQO_O2_SMB0 3
+
+static struct oqo_model oqo_models[] = {
+ {
+ .model = "Model 2",
+ .model_subs = MODEL_SUB_OQO_O2_SMB0,
+ },
+ {}
+};
+
+static struct oqo_model *model;
+
+static int force;
+module_param(force, bool, 0644);
+MODULE_PARM_DESC(force, "Force WMI detection even if DMI detection failed");
+
+/*
+ * OQO Model 2 SMBUS registers
+ * We are just using WMI to read the Cx700 smbus, to share the
+ * ACPI mutex (what may also eventually work in VMs/win32)
+ * Using i2c-viapro directly could interfere with PM.
+ */
+
+#define OQO_O2_SMB0_WWAN_DSBL_ADDR 0x19
+#define OQO_O2_SMB0_WWAN_DSBL_MASK 0x02
+#define OQO_O2_SMB0_LUMIN_LO 0x20
+#define OQO_O2_SMB0_LUMIN_HI 0x21
+#define OQO_O2_SMB0_BL_LO 0x26
+#define OQO_O2_SMB0_BL_HI 0x27
+#define OQO_O2_SMB0_ACCEL_POLL_ITVL 0x45
+#define OQO_O2_SMB0_ACCEL_XLO 0x50
+#define OQO_O2_SMB0_ACCEL_XHI 0x51
+#define OQO_O2_SMB0_ACCEL_YLO 0x52
+#define OQO_O2_SMB0_ACCEL_YHI 0x53
+#define OQO_O2_SMB0_ACCEL_ZLO 0x54
+#define OQO_O2_SMB0_ACCEL_ZHI 0x55
+/* These may be handled by ACPI not sure yet. */
+#define OQO_O2_SMB0_LID_WAKES_ADDR 0x58
+#define OQO_O2_SMB0_LID_WAKES_MASK 0x08
+
+#define OQO_O2_SMB0_SERIAL_START 0x70
+#define OQO_O2_SMB0_SERIAL_LEN 11
+
+static char oqo_sn[OQO_O2_SMB0_SERIAL_LEN + 1];
+
+/* Other addresses I have noticed used on the 02 SMBUS (from DSDT and whatnot)
+ *
+ * These are not used because the linux ACPI drivers work fine on them
+ *
+ * 0x0A -- processor sleep mode?
+ * 0x0C -- ACPI events, probably clears when read.
+ * 0x30 -- thermal zone
+ * There is something going on at 0x31 through 0x34 which is likely
+ * also thermal. The values change over time. Have not figured that
+ * out yet.
+ * 0x41 -- AC detect
+ * 0x42 -- LID button ACTUALLY THIS DOES NOT WORK AND NEEDS TO BE FIXED
+ * 0xa0 and 0xa1 -- battery something (presence? state?)
+ * 0xa4 to 0xcf -- battery info (0xc8-0xca contains "OQO")
+ * 0xd4 to 0xef -- other battery stats
+ */
+
+/*
+ * OQO method GUIDs
+ */
+#define OQO_O2_AMW0_GUID "ABBC0F6D-8EA1-11D1-00A0-C90629100000"
+MODULE_ALIAS("wmi:ABBC0F6D-8EA1-11D1-00A0-C90629100000");
+
+/*
+ * Interface type flags
+ */
+enum interface_type {
+ OQO_O2_AMW0,
+};
+
+/* Each low-level interface must define at least some of the following */
+struct wmi_interface {
+ /* The WMI device type */
+ u32 type;
+};
+
+static struct wmi_interface AMW0_interface = {
+ .type = OQO_O2_AMW0,
+};
+
+/* The detected/chosen interface */
+static struct wmi_interface *interface;
+
+static int dmi_matched(const struct dmi_system_id *dmi)
+{
+ model = dmi->driver_data;
+ /*
+ * Detect which ACPI-WMI interface we're using.
+ */
+ if (wmi_has_guid(OQO_O2_AMW0_GUID))
+ interface = &AMW0_interface;
+
+ return 0;
+}
+
+static struct dmi_system_id oqo_dmis[] = {
+ {
+ .callback = dmi_matched,
+ .ident = "OQO 02",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "OQO Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OQO Model 2"),
+ },
+ .driver_data = oqo_models + 0,
+ },
+ {}
+};
+
+/*
+ * AMW0 (V1) interface on OQO Model 2
+ *
+ * wmba: has four functions selected by int arg 1. arg2 is 3 byte buffer.
+ * 1: performs GETB method on the SMBUS using bytes 0, 1 of Arg2
+ * returns a buffer object containing a single byte
+ * 2: performs SETB on SMBUS using bytes 0, 1, 2 of Arg2
+ * returns 0 as int.
+ * 3: dumps 256 values into a given SMBUS register (not used here)
+ * returns 0 as int.
+ * 4: puts byte 0 of arg2 into some sort of busy flag. Some ACPI
+ * funcs check this (==0) to decide if SMBUS operations are safe.
+ * returns 0 as int.
+ * wmbb: simply returns the busy flag set by wmba #4
+ */
+static acpi_status oqo_smbus_getb(u8 addr, u8 *result)
+{
+ struct acpi_buffer input, res;
+ acpi_status status;
+ union acpi_object *obj;
+ u32 arg2;
+
+ input.length = 4;
+ input.pointer = &arg2;
+ res.length = ACPI_ALLOCATE_BUFFER;
+ res.pointer = NULL;
+
+ arg2 = addr;
+ arg2 <<= 8;
+ arg2 |= 0x12; /* HOSTCMD */
+
+ status = wmi_evaluate_method(OQO_O2_AMW0_GUID, 1, 1, &input, &res);
+
+ if (status != AE_OK)
+ return status;
+
+ obj = (union acpi_object *)res.pointer;
+ if (!obj)
+ return AE_NULL_OBJECT;
+
+ if (obj->type != ACPI_TYPE_BUFFER
+ || obj->buffer.length != 1 || obj->buffer.pointer == NULL) {
+ kfree(obj);
+ return AE_TYPE;
+ }
+ *result = ((u8 *) (obj->buffer.pointer))[0];
+ kfree(obj);
+ return status;
+}
+
+static acpi_status oqo_smbus_setb(u8 addr, u8 val)
+{
+ struct acpi_buffer input, res;
+ acpi_status status;
+ union acpi_object *obj;
+ u32 arg2;
+
+ input.length = 4;
+ input.pointer = &arg2;
+ res.length = ACPI_ALLOCATE_BUFFER;
+ res.pointer = NULL;
+
+ arg2 = val;
+ arg2 <<= 8;
+ arg2 |= addr;
+ arg2 <<= 8;
+ arg2 |= 0x12; /* HOSTCMD */
+
+ status = wmi_evaluate_method(OQO_O2_AMW0_GUID, 1, 2, &input, &res);
+
+ if (status != AE_OK)
+ return status;
+
+ obj = (union acpi_object *)res.pointer;
+ if (!obj)
+ return AE_NULL_OBJECT;
+
+ if (obj->type != ACPI_TYPE_INTEGER) {
+ kfree(obj);
+ return AE_TYPE;
+ }
+ kfree(obj);
+ return status;
+}
+
+/*
+ * We assume we are the only one using this ...ahem... "lock" on
+ * the SMBUS because it would be pathetically noneffective otherwise.
+ *
+ * Nonzero silly_lock will keep certain ACPI routines away from the
+ * SMBUS (if they aren't already on it when you call it.) Zero
+ * silly_lock will let them back on
+ *
+ * This is probably useful before sleeping the system, and one
+ * waits until any ACPI funcs would have long finished before
+ * proceeding. It seems harmless enough and will work to wrap
+ * more accesses with it.
+ */
+static acpi_status oqo_lock_smbus(int silly_lock)
+{
+ struct acpi_buffer input, res;
+ acpi_status status;
+ union acpi_object *obj;
+ u32 arg2;
+
+ input.length = 4;
+ input.pointer = &arg2;
+ res.length = ACPI_ALLOCATE_BUFFER;
+ res.pointer = NULL;
+
+ arg2 = !!silly_lock;
+
+ status = wmi_evaluate_method(OQO_O2_AMW0_GUID, 1, 4, &input, &res);
+
+ if (status != AE_OK)
+ return status;
+
+ obj = (union acpi_object *)res.pointer;
+ if (!obj)
+ return AE_NULL_OBJECT;
+
+ if (obj->type != ACPI_TYPE_INTEGER) {
+ kfree(obj);
+ return AE_TYPE;
+ }
+ kfree(obj);
+ return status;
+}
+
+static int smread_s16(u8 hi_addr, u8 lo_addr)
+{
+ s16 ret = -1;
+ acpi_status status;
+ u8 r;
+
+ /* Keep some ACPI routines off the SMBUS */
+ status = oqo_lock_smbus(1);
+ if (ACPI_FAILURE(status))
+ goto skip;
+
+ status = oqo_smbus_getb(hi_addr, &r);
+ if (ACPI_FAILURE(status))
+ goto skip;
+
+ ret = r;
+ ret <<= 8;
+
+ status = oqo_smbus_getb(lo_addr, &r);
+ if (ACPI_FAILURE(status)) {
+ ret = -1;
+ goto skip;
+ }
+
+ ret |= r;
+ ret &= 0x7fff;
+skip:
+ /* Let ACPI routines back on the SMBUS */
+ status = oqo_lock_smbus(0);
+ if (ACPI_FAILURE(status))
+ return -1;
+ return (int)ret;
+}
+
+static int smwrite_s16(u8 hi_addr, u8 lo_addr, s16 val)
+{
+ acpi_status status;
+ u8 r;
+ int ret = -1;
+
+ status = oqo_lock_smbus(1);
+ if (ACPI_FAILURE(status))
+ goto skip;
+
+ r = (val >> 8) & 0x7f;
+ status = oqo_smbus_setb(hi_addr, r);
+ if (ACPI_FAILURE(status))
+ goto skip;
+
+ r = val & 0xff;
+ status = oqo_smbus_setb(lo_addr, r);
+ if (ACPI_FAILURE(status))
+ goto skip;
+
+ ret = 0;
+skip:
+ status = oqo_lock_smbus(0);
+ if (ACPI_FAILURE(status))
+ return -1;
+ return ret;
+}
+
+static int smread_u8(u8 addr)
+{
+ int ret = -1;
+ acpi_status status;
+ u8 r;
+
+ status = oqo_lock_smbus(1);
+ if (ACPI_FAILURE(status))
+ goto skip;
+
+ status = oqo_smbus_getb(addr, &r);
+ if (ACPI_FAILURE(status))
+ goto skip;
+
+ ret = r;
+skip:
+ status = oqo_lock_smbus(0);
+ if (ACPI_FAILURE(status))
+ return -1;
+ return (int)ret;
+}
+
+static int smwrite_u8(u8 addr, u8 val)
+{
+ acpi_status status;
+ int ret = -1;
+
+ status = oqo_lock_smbus(1);
+ if (ACPI_FAILURE(status))
+ goto skip;
+
+ status = oqo_smbus_setb(addr, val);
+ if (ACPI_FAILURE(status))
+ goto skip;
+
+ ret = 0;
+skip:
+ status = oqo_lock_smbus(0);
+ if (ACPI_FAILURE(status))
+ return -1;
+ return ret;
+}
+
+/*
+ * Accelerometer inputdev
+ */
+
+/*
+ * Get a reading of the accelerometer from the firwmware and push
+ * it to an inputdev.
+ *
+ * Also the ambient light detector hitch-hikes on the inputdev, since
+ * it could be useful in some of the same applications for accelerometers.
+ *
+ * Available information and a bit of poking have not found a
+ * way to freeze a snapshot of the accelerometer data, so we have
+ * to do consistency checks to reduce the odds that we mix low
+ * and high bytes from different updates.
+ *
+ * Unfortunately SMBUS access is very slow (11ms) and the firmware API
+ * does not provide 2-byte transfers, so mixed readings happen and
+ * have to be corrected a lot. (Do not know why; it should be a
+ * multi-kHz.. bus and the reads take only a hundred-ish cycles/byte.
+ * It is not the ACPI function -- it is slow on i2c-viapro as well.)
+ *
+ * Since there is such a big time lag between readings, the axis
+ * are decoupled and reported separately on different timelines as
+ * different events rather than as a set.
+ */
+static acpi_status oqo_read_kine(int *good, s16 *x, s16 *y, s16 *z,
+ u16 *lumin)
+{
+ u8 hiregs[4] = { OQO_O2_SMB0_ACCEL_XHI,
+ OQO_O2_SMB0_ACCEL_YHI,
+ OQO_O2_SMB0_ACCEL_ZHI,
+ OQO_O2_SMB0_LUMIN_HI
+ };
+ u8 loregs[4] = { OQO_O2_SMB0_ACCEL_XLO,
+ OQO_O2_SMB0_ACCEL_YLO,
+ OQO_O2_SMB0_ACCEL_ZLO,
+ OQO_O2_SMB0_LUMIN_LO
+ };
+
+ short ax[4] = { ABS_X, ABS_Y, ABS_Z, ABS_MISC };
+ u8 realgood = 0;
+ u16 res[4];
+ acpi_status status;
+ int i;
+
+ *good = 0;
+
+ /* Routine: Starting with the lo byte, read lo/hi bytes
+ alternately until two lo byte readings, match. Then
+ take that reading and combine it with the hi reading
+ sandwiched between. Errors can still happen when
+ jittering at wrap boundaries, but should be rare.
+
+ Don't use this for missile guidance.
+
+ Userspace post-processing error detection encouraged.
+ */
+ for (i = 0; i < 4; i++) {
+ int maxtry;
+ u32 log;
+ u8 r, lo, hi;
+
+ lo = loregs[i];
+ hi = hiregs[i];
+ log = 0;
+
+#define LOGRES(reg) do { \
+ status = oqo_smbus_getb(reg, &r); \
+ log <<= 8; log |= r; log &= 0xffffff; \
+ if (ACPI_FAILURE(status)) \
+ goto leave; \
+ } while (0)
+
+ maxtry = OQO_KINE_MAXTRY + 1;
+ while (maxtry) {
+ LOGRES(lo);
+ if (maxtry <= OQO_KINE_MAXTRY &&
+ (log >> 16) == (log & 0xff)) {
+ *(res + i) = log & 0xffff;
+ break;
+ }
+ LOGRES(hi);
+ maxtry--;
+ }
+
+ if (maxtry == OQO_KINE_MAXTRY)
+ realgood |= 1 << i;
+
+ if (maxtry) {
+ *good |= 1 << i;
+ /* JIC CYA: this bit may be reserved */
+ res[3] &= 0x7fff;
+ input_report_abs(oqo_kine, ax[i], (s16) res[i]);
+ }
+ /* else we had trouble getting the reading to lock
+ and we skip reporting this axis.
+ */
+ }
+
+ *x = (u16) res[0];
+ *y = (u16) res[1];
+ *z = (u16) res[2];
+ *lumin = (u16) res[3];
+ return status;
+leave:
+ return status;
+}
+
+/*
+ * Generic Device (interface-independent)
+ */
+
+static void oqo_kine_poll(struct input_polled_dev *dev)
+{
+ s16 x, y, z;
+ u16 lumin;
+ int good;
+ /* struct timeval tv1, tv2; */
+
+ if (dev != oqo_kine_polled)
+ return;
+ if (orig.kine_itvl < 0)
+ return;
+
+ x = y = z = 0;
+ oqo_read_kine(&good, &x, &y, &z, &lumin);
+}
+
+static int __devinit oqo_kine_init(void)
+{
+ int err;
+
+ oqo_kine = input_allocate_device();
+ if (!oqo_kine)
+ return -ENOMEM;
+
+ oqo_kine->name = "OQO embedded accelerometer";
+ oqo_kine->phys = "platform:oqo-wmi:kine";
+ oqo_kine->id.bustype = 0;
+ oqo_kine->id.vendor = 0;
+ oqo_kine->id.product = 2;
+ oqo_kine->id.version = 0;
+ oqo_kine->evbit[0] = BIT_MASK(EV_ABS);
+ set_bit(ABS_X, oqo_kine->absbit);
+ set_bit(ABS_Y, oqo_kine->absbit);
+ set_bit(ABS_Z, oqo_kine->absbit);
+ set_bit(ABS_MISC, oqo_kine->absbit);
+ oqo_kine->absmin[ABS_X] =
+ oqo_kine->absmin[ABS_Y] =
+ oqo_kine->absmin[ABS_Z] = oqo_kine->absmin[ABS_MISC] = -32768;
+ oqo_kine->absmax[ABS_X] =
+ oqo_kine->absmax[ABS_Y] =
+ oqo_kine->absmax[ABS_Z] = oqo_kine->absmax[ABS_MISC] = 32767;
+
+ dev_set_name(&oqo_kine->dev, "kine");
+
+ oqo_kine_polled = input_allocate_polled_device();
+ if (!oqo_kine_polled) {
+ err = -ENOMEM;
+ goto bail0;
+ }
+
+ oqo_kine_polled->poll = oqo_kine_poll;
+ oqo_kine_polled->poll_interval = 250;
+ oqo_kine_polled->input = oqo_kine;
+
+ orig.kine_itvl = -1; /* prevent callback from running */
+ err = input_register_polled_device(oqo_kine_polled);
+ if (err) {
+ printk(OQO_ERR "Failed to register OQO kine input\n");
+ goto bail1;
+ }
+
+ /* This will allow the callback to run now if successful. */
+ orig.kine_itvl = smread_u8(OQO_O2_SMB0_ACCEL_POLL_ITVL);
+ smwrite_u8(OQO_O2_SMB0_ACCEL_POLL_ITVL, 250);
+ curr.kine_itvl = smread_u8(OQO_O2_SMB0_ACCEL_POLL_ITVL);
+ if (orig.kine_itvl < 0 || curr.kine_itvl != 250) {
+ printk(OQO_ERR "Test communication with kine sensor failed\n");
+ err = -ENODEV;
+ goto bail2;
+ }
+
+ printk(OQO_INFO "Created OQO kine input.\n");
+ printk(OQO_INFO "Firmware interval %ims, driver interval %ims\n",
+ curr.kine_itvl, oqo_kine_polled->poll_interval);
+ return 0;
+bail2:
+ input_unregister_polled_device(oqo_kine_polled);
+bail1:
+ input_free_polled_device(oqo_kine_polled); /* frees oqo_kine */
+ return err;
+bail0:
+ input_free_device(oqo_kine);
+ return err;
+}
+
+static void __devexit oqo_kine_fini(void)
+{
+ smwrite_u8(OQO_O2_SMB0_ACCEL_POLL_ITVL, orig.kine_itvl);
+ input_unregister_polled_device(oqo_kine_polled);
+ input_free_polled_device(oqo_kine_polled);
+}
+
+/*
+ * Backlight device
+ */
+static int read_brightness(struct backlight_device *bd)
+{
+ return (int)smread_s16(OQO_O2_SMB0_BL_HI, OQO_O2_SMB0_BL_LO);
+}
+
+static int update_bl_status(struct backlight_device *bd)
+{
+ return smwrite_s16(OQO_O2_SMB0_BL_HI,
+ OQO_O2_SMB0_BL_LO, (s16) bd->props.brightness);
+}
+
+static struct backlight_ops oqo_bl_ops = {
+ .get_brightness = read_brightness,
+ .update_status = update_bl_status,
+};
+
+static int __devinit oqo_backlight_init(struct device *dev)
+{
+ struct backlight_device *bd;
+
+ /*
+ * It would be nice if someone would figure out how backlights
+ * like these, which are not driven through the video hardware,
+ * are supposed to find their associated fb and bind to it (and
+ * rebind when fb drivers change.
+ *
+ * Most extras backlights just shove a junk name in like we do here,
+ * and don't end up integrated with fbcon sysfs as a result.
+ */
+ bd = backlight_device_register("oqo-bl", dev, NULL, &oqo_bl_ops);
+
+ if (IS_ERR(bd)) {
+ printk(OQO_ERR "Could not register OQO backlight device\n");
+ oqo_backlight_device = NULL;
+ return PTR_ERR(bd);
+ }
+
+ oqo_backlight_device = bd;
+ bd->props.max_brightness = 0x7fff;
+ curr.bl_bright = orig.bl_bright = bd->props.brightness =
+ read_brightness(NULL);
+
+ if (bd->props.brightness < 0)
+ goto fail;
+
+ backlight_update_status(bd);
+ printk(OQO_INFO "Found backlight set at %i\n", bd->props.brightness);
+ return 0;
+
+fail:
+ backlight_device_unregister(oqo_backlight_device);
+ oqo_backlight_device = NULL;
+ return -ENODEV;
+}
+
+static void __devexit oqo_backlight_fini(void)
+{
+ if (!oqo_backlight_device)
+ return;
+ oqo_backlight_device->props.brightness = orig.bl_bright;
+ backlight_update_status(oqo_backlight_device);
+ backlight_device_unregister(oqo_backlight_device);
+}
+
+/*
+ * RFKill device
+ */
+
+static int oqo_rfkill_get(void *data, enum rfkill_state *state)
+{
+ int res;
+
+ res = smread_u8(OQO_O2_SMB0_WWAN_DSBL_ADDR);
+ if (res < 0)
+ return res;
+
+ res &= OQO_O2_SMB0_WWAN_DSBL_MASK;
+
+ if (res)
+ *state = RFKILL_STATE_SOFT_BLOCKED;
+ else
+ *state = RFKILL_STATE_UNBLOCKED;
+
+ return 0;
+}
+
+static int oqo_rfkill_toggle(void *data, enum rfkill_state state)
+{
+ int res;
+
+ res = smread_u8(OQO_O2_SMB0_WWAN_DSBL_ADDR);
+
+ if (state == RFKILL_STATE_UNBLOCKED)
+ res &= ~OQO_O2_SMB0_WWAN_DSBL_MASK;
+ else
+ res |= OQO_O2_SMB0_WWAN_DSBL_MASK;
+
+ return smwrite_u8(OQO_O2_SMB0_WWAN_DSBL_ADDR, res);
+}
+
+static int __devinit oqo_rfkill_init(struct device *dev)
+{
+ int res;
+
+ oqo_rfkill = rfkill_allocate(dev, RFKILL_TYPE_WWAN);
+ if (!oqo_rfkill)
+ return -ENODEV;
+
+ res = smread_u8(OQO_O2_SMB0_WWAN_DSBL_ADDR);
+ res &= OQO_O2_SMB0_WWAN_DSBL_MASK;
+
+ oqo_rfkill->name = "oqo-wwan";
+ if (res)
+ oqo_rfkill->state = RFKILL_STATE_SOFT_BLOCKED;
+ else
+ oqo_rfkill->state = RFKILL_STATE_UNBLOCKED;
+
+ oqo_rfkill->get_state = oqo_rfkill_get;
+ oqo_rfkill->toggle_radio = oqo_rfkill_toggle;
+ oqo_rfkill->user_claim_unsupported = 1;
+
+ res = rfkill_register(oqo_rfkill);
+
+ if (res)
+ rfkill_free(oqo_rfkill);
+
+ return res;
+}
+
+static void __devexit oqo_rfkill_fini(void)
+{
+ if (!oqo_rfkill)
+ return;
+ rfkill_unregister(oqo_rfkill);
+}
+
+/*
+ * Platform device
+ */
+
+static int __devinit oqo_platform_probe(struct platform_device *device)
+{
+ int err;
+ int i;
+ char *troubleok = "trouble, but continuing.\n";
+
+ memset(oqo_sn, 0, OQO_O2_SMB0_SERIAL_LEN + 1);
+ for (i = 0; i < OQO_O2_SMB0_SERIAL_LEN; i++) {
+ err = oqo_smbus_getb(OQO_O2_SMB0_SERIAL_START + i, oqo_sn + i);
+ if (err) {
+ printk(OQO_ERR "Serial number check failed.\n");
+ return err;
+ }
+ }
+ printk(OQO_INFO "Found OQO with serial number %s.\n", oqo_sn);
+
+ err = oqo_backlight_init(&device->dev);
+ if (err)
+ printk(OQO_ERR "Backlight init %s", troubleok);
+
+ err = oqo_rfkill_init(&device->dev);
+ if (err)
+ printk(OQO_ERR "RFKill init %s", troubleok);
+
+ /* LID does not work at all yet, and this may be taken
+ care of by ACPI.
+ */
+ orig.lid_wakes = smread_u8(OQO_O2_SMB0_LID_WAKES_ADDR);
+ orig.lid_wakes &= OQO_O2_SMB0_LID_WAKES_MASK;
+ orig.lid_wakes = curr.lid_wakes = !!orig.lid_wakes;
+ if (orig.lid_wakes < 0) {
+ printk(OQO_ERR "Wake on LID event %s", troubleok);
+ } else {
+ printk(OQO_INFO "Wake on LID is %s.\n",
+ (orig.lid_wakes ? "on" : "off"));
+ }
+
+ err = oqo_kine_init();
+ return err;
+}
+
+static int oqo_platform_remove(struct platform_device *device)
+{
+ oqo_backlight_fini();
+ oqo_rfkill_fini();
+ oqo_kine_fini();
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int oqo_platform_suspend(struct platform_device *dev, pm_message_t state)
+{
+ if (!interface)
+ return -ENOMEM;
+
+ /* This sticks during boot so do not turn it entirely off */
+ if (oqo_backlight_device) {
+ curr.bl_bright = read_brightness(oqo_backlight_device);
+ smwrite_s16(OQO_O2_SMB0_BL_HI, OQO_O2_SMB0_BL_LO, 256);
+ }
+ return 0;
+}
+
+static int oqo_platform_resume(struct platform_device *device)
+{
+ if (!interface)
+ return -ENOMEM;
+
+ if (oqo_backlight_device) {
+ smwrite_s16(OQO_O2_SMB0_BL_HI,
+ OQO_O2_SMB0_BL_LO, curr.bl_bright);
+ }
+
+ return 0;
+}
+
+#else
+#define oqo_platform_suspend NULL
+#define oqo_platform_resume NULL
+#endif
+
+static struct platform_driver oqo_platform_driver = {
+ .driver = {
+ .name = "oqo-wmi",
+ .owner = THIS_MODULE,
+ },
+ .probe = oqo_platform_probe,
+ .remove = oqo_platform_remove,
+ .suspend = oqo_platform_suspend,
+ .resume = oqo_platform_resume,
+};
+
+static int __init oqo_wmi_init(void)
+{
+ int err;
+
+ dmi_check_system(oqo_dmis);
+
+ if (!interface && force) {
+ model = oqo_models;
+ if (wmi_has_guid(OQO_O2_AMW0_GUID))
+ interface = &AMW0_interface;
+ }
+
+ if (!interface) {
+ printk(OQO_ERR "No or unsupported WMI interface. Aborting.\n");
+ printk(OQO_ERR "Hint: Get dmidecode working and try again.\n");
+ printk(OQO_ERR "(Check \"System Management BIOS\" in BIOS)\n");
+ if (!force)
+ printk(OQO_ERR "Use the force option to skip DMI"
+ " checking\n");
+ return -ENODEV;
+ }
+
+ err = platform_driver_register(&oqo_platform_driver);
+ if (err) {
+ printk(OQO_ERR "platform_driver_register gave %d.\n", err);
+ goto bail0;
+ }
+
+ oqo_platform_device = platform_device_alloc("oqo-wmi", -1);
+ if (!oqo_platform_device) {
+ printk(OQO_ERR "Could not allocate platform device.\n");
+ err = -ENOMEM;
+ goto bail1;
+ }
+
+ err = platform_device_add(oqo_platform_device);
+ if (err) {
+ printk(OQO_ERR "platform_device_add gave %d.\n", err);
+ platform_device_put(oqo_platform_device);
+ goto bail1;
+ }
+
+ return 0;
+
+bail1:
+ platform_driver_unregister(&oqo_platform_driver);
+bail0:
+ return err;
+}
+
+static void __exit oqo_wmi_fini(void)
+{
+ platform_device_del(oqo_platform_device);
+ platform_driver_unregister(&oqo_platform_driver);
+
+ return;
+}
+
+module_init(oqo_wmi_init);
+module_exit(oqo_wmi_fini);
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 9f187265db8e..0c6cd7c654da 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -46,6 +46,7 @@
#include <linux/platform_device.h>
#include <linux/rfkill.h>
#include <linux/input-polldev.h>
+#include <linux/input.h>
#include <asm/uaccess.h>
@@ -62,9 +63,10 @@ MODULE_LICENSE("GPL");
/* Toshiba ACPI method paths */
#define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM"
-#define METHOD_HCI_1 "\\_SB_.VALD.GHCI"
-#define METHOD_HCI_2 "\\_SB_.VALZ.GHCI"
+#define TOSH_INTERFACE_1 "\\_SB_.VALD"
+#define TOSH_INTERFACE_2 "\\_SB_.VALZ"
#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX"
+#define GHCI_METHOD ".GHCI"
/* Toshiba HCI interface definitions
*
@@ -116,6 +118,36 @@ static const struct acpi_device_id toshiba_device_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);
+struct key_entry {
+ char type;
+ u16 code;
+ u16 keycode;
+};
+
+enum {KE_KEY, KE_END};
+
+static struct key_entry toshiba_acpi_keymap[] = {
+ {KE_KEY, 0x101, KEY_MUTE},
+ {KE_KEY, 0x13b, KEY_COFFEE},
+ {KE_KEY, 0x13c, KEY_BATTERY},
+ {KE_KEY, 0x13d, KEY_SLEEP},
+ {KE_KEY, 0x13e, KEY_SUSPEND},
+ {KE_KEY, 0x13f, KEY_SWITCHVIDEOMODE},
+ {KE_KEY, 0x140, KEY_BRIGHTNESSDOWN},
+ {KE_KEY, 0x141, KEY_BRIGHTNESSUP},
+ {KE_KEY, 0x142, KEY_WLAN},
+ {KE_KEY, 0x143, KEY_PROG1},
+ {KE_KEY, 0xb05, KEY_PROG2},
+ {KE_KEY, 0xb06, KEY_WWW},
+ {KE_KEY, 0xb07, KEY_MAIL},
+ {KE_KEY, 0xb30, KEY_STOP},
+ {KE_KEY, 0xb31, KEY_PREVIOUSSONG},
+ {KE_KEY, 0xb32, KEY_NEXTSONG},
+ {KE_KEY, 0xb33, KEY_PLAYPAUSE},
+ {KE_KEY, 0xb5a, KEY_MEDIA},
+ {KE_END, 0, 0},
+};
+
/* utility
*/
@@ -252,6 +284,8 @@ struct toshiba_acpi_dev {
struct platform_device *p_dev;
struct rfkill *rfk_dev;
struct input_polled_dev *poll_dev;
+ struct input_dev *hotkey_dev;
+ acpi_handle handle;
const char *bt_name;
const char *rfk_name;
@@ -700,6 +734,154 @@ static struct backlight_ops toshiba_backlight_data = {
.update_status = set_lcd_status,
};
+static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code)
+{
+ struct key_entry *key;
+
+ for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
+ if (code == key->code)
+ return key;
+
+ return NULL;
+}
+
+static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code)
+{
+ struct key_entry *key;
+
+ for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
+ if (code == key->keycode && key->type == KE_KEY)
+ return key;
+
+ return NULL;
+}
+
+static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode,
+ int *keycode)
+{
+ struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode);
+
+ if (key && key->type == KE_KEY) {
+ *keycode = key->keycode;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int toshiba_acpi_setkeycode(struct input_dev *dev, int scancode,
+ int keycode)
+{
+ struct key_entry *key;
+ int old_keycode;
+
+ if (keycode < 0 || keycode > KEY_MAX)
+ return -EINVAL;
+
+ key = toshiba_acpi_get_entry_by_scancode(scancode);
+ if (key && key->type == KE_KEY) {
+ old_keycode = key->keycode;
+ key->keycode = keycode;
+ set_bit(keycode, dev->keybit);
+ if (!toshiba_acpi_get_entry_by_keycode(old_keycode))
+ clear_bit(old_keycode, dev->keybit);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
+{
+ u32 hci_result, value;
+ struct key_entry *key;
+
+ if (event != 0x80)
+ return;
+ do {
+ hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result);
+ if (hci_result == HCI_SUCCESS) {
+ if (value == 0x100)
+ continue;
+ else if (value & 0x80) {
+ key = toshiba_acpi_get_entry_by_scancode
+ (value & ~0x80);
+ if (!key) {
+ printk(MY_INFO "Unknown key %x\n",
+ value & ~0x80);
+ continue;
+ }
+ input_report_key(toshiba_acpi.hotkey_dev,
+ key->keycode, 1);
+ input_sync(toshiba_acpi.hotkey_dev);
+ input_report_key(toshiba_acpi.hotkey_dev,
+ key->keycode, 0);
+ input_sync(toshiba_acpi.hotkey_dev);
+ }
+ } else if (hci_result == HCI_NOT_SUPPORTED) {
+ /* This is a workaround for an unresolved issue on
+ * some machines where system events sporadically
+ * become disabled. */
+ hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
+ printk(MY_NOTICE "Re-enabled hotkeys\n");
+ }
+ } while (hci_result != HCI_EMPTY);
+}
+
+static int toshiba_acpi_setup_keyboard(char *device)
+{
+ acpi_status status;
+ acpi_handle handle;
+ int result;
+ const struct key_entry *key;
+
+ status = acpi_get_handle(NULL, device, &handle);
+ if (ACPI_FAILURE(status)) {
+ printk(MY_INFO "Unable to get notification device\n");
+ return -ENODEV;
+ }
+
+ toshiba_acpi.handle = handle;
+
+ status = acpi_evaluate_object(handle, "ENAB", NULL, NULL);
+ if (ACPI_FAILURE(status)) {
+ printk(MY_INFO "Unable to enable hotkeys\n");
+ return -ENODEV;
+ }
+
+ status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY,
+ toshiba_acpi_notify, NULL);
+ if (ACPI_FAILURE(status)) {
+ printk(MY_INFO "Unable to install hotkey notification\n");
+ return -ENODEV;
+ }
+
+ toshiba_acpi.hotkey_dev = input_allocate_device();
+ if (!toshiba_acpi.hotkey_dev) {
+ printk(MY_INFO "Unable to register input device\n");
+ return -ENOMEM;
+ }
+
+ toshiba_acpi.hotkey_dev->name = "Toshiba input device";
+ toshiba_acpi.hotkey_dev->phys = device;
+ toshiba_acpi.hotkey_dev->id.bustype = BUS_HOST;
+ toshiba_acpi.hotkey_dev->getkeycode = toshiba_acpi_getkeycode;
+ toshiba_acpi.hotkey_dev->setkeycode = toshiba_acpi_setkeycode;
+
+ for (key = toshiba_acpi_keymap; key->type != KE_END; key++) {
+ set_bit(EV_KEY, toshiba_acpi.hotkey_dev->evbit);
+ set_bit(key->keycode, toshiba_acpi.hotkey_dev->keybit);
+ }
+
+ result = input_register_device(toshiba_acpi.hotkey_dev);
+ if (result) {
+ printk(MY_INFO "Unable to register input device\n");
+ return result;
+ }
+
+ return 0;
+}
+
static void toshiba_acpi_exit(void)
{
if (toshiba_acpi.poll_dev) {
@@ -707,12 +889,18 @@ static void toshiba_acpi_exit(void)
input_free_polled_device(toshiba_acpi.poll_dev);
}
+ if (toshiba_acpi.hotkey_dev)
+ input_unregister_device(toshiba_acpi.hotkey_dev);
+
if (toshiba_acpi.rfk_dev)
rfkill_unregister(toshiba_acpi.rfk_dev);
if (toshiba_backlight_device)
backlight_device_unregister(toshiba_backlight_device);
+ acpi_remove_notify_handler(toshiba_acpi.handle, ACPI_DEVICE_NOTIFY,
+ toshiba_acpi_notify);
+
remove_device();
if (toshiba_proc_dir)
@@ -736,11 +924,15 @@ static int __init toshiba_acpi_init(void)
return -ENODEV;
/* simple device detection: look for HCI method */
- if (is_valid_acpi_path(METHOD_HCI_1))
- method_hci = METHOD_HCI_1;
- else if (is_valid_acpi_path(METHOD_HCI_2))
- method_hci = METHOD_HCI_2;
- else
+ if (is_valid_acpi_path(TOSH_INTERFACE_1 GHCI_METHOD)) {
+ method_hci = TOSH_INTERFACE_1 GHCI_METHOD;
+ if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_1))
+ printk(MY_INFO "Unable to activate hotkeys\n");
+ } else if (is_valid_acpi_path(TOSH_INTERFACE_2 GHCI_METHOD)) {
+ method_hci = TOSH_INTERFACE_2 GHCI_METHOD;
+ if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_2))
+ printk(MY_INFO "Unable to activate hotkeys\n");
+ } else
return -ENODEV;
printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n",
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 9a3a682c6981..9496494f340e 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -110,11 +110,9 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
ret = 0;
- if (acpi_bus_power_manageable(handle)) {
- ret = acpi_bus_set_power(handle, ACPI_STATE_D3);
- if (ret)
- return ret;
- }
+ if (acpi_bus_power_manageable(handle))
+ acpi_bus_set_power(handle, ACPI_STATE_D3);
+ /* continue even if acpi_bus_set_power() fails */
if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
ret = -ENODEV;
return ret;
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index adf17856bacc..7f207f335bec 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -123,7 +123,7 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
}
flags = irq_flags(triggering, polarity, shareable);
- irq = acpi_register_gsi(gsi, triggering, polarity);
+ irq = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
if (irq >= 0)
pcibios_penalize_isa_irq(irq, 1);
else
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 74d0bfa3f310..3b78540288c7 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -290,7 +290,7 @@ static void __devinit rio_add_device(struct rio_dev *rdev)
* to a RIO device on success or NULL on failure.
*
*/
-static struct rio_dev *rio_setup_device(struct rio_net *net,
+static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
struct rio_mport *port, u16 destid,
u8 hopcount, int do_enum)
{
@@ -559,7 +559,7 @@ static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
* Recursively enumerates a RIO network. Transactions are sent via the
* master port passed in @port.
*/
-static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
+static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
u8 hopcount)
{
int port_num;
@@ -718,7 +718,7 @@ static int rio_enum_complete(struct rio_mport *port)
* Recursively discovers a RIO network. Transactions are sent via the
* master port passed in @port.
*/
-static int
+static int __devinit
rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
u8 hopcount)
{
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e58c0ce65aa6..5bec17cf1d5c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -47,6 +47,16 @@ config REGULATOR_VIRTUAL_CONSUMER
If unsure, say no.
+config REGULATOR_USERSPACE_CONSUMER
+ tristate "Userspace regulator consumer support"
+ default n
+ help
+ There are some classes of devices that are controlled entirely
+ from user space. Usersapce consumer driver provides ability to
+ control power supplies for such devices.
+
+ If unsure, say no.
+
config REGULATOR_BQ24022
tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
default n
@@ -56,6 +66,15 @@ config REGULATOR_BQ24022
charging select between 100 mA and 500 mA charging current
limit.
+config REGULATOR_MAX1586
+ tristate "Maxim 1586/1587 voltage regulator"
+ depends on I2C
+ default n
+ help
+ This driver controls a Maxim 1586 or 1587 voltage output
+ regulator via I2C bus. The provided regulator is suitable
+ for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
+
config REGULATOR_TWL4030
bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
depends on TWL4030_CORE
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index bac133afc061..faf7bcc1af98 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -6,8 +6,10 @@
obj-$(CONFIG_REGULATOR) += core.o
obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
+obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
index 72b15495183c..2a491bf15865 100644
--- a/drivers/regulator/da903x.c
+++ b/drivers/regulator/da903x.c
@@ -504,7 +504,7 @@ static int __init da903x_regulator_init(void)
{
return platform_driver_register(&da903x_regulator_driver);
}
-module_init(da903x_regulator_init);
+subsys_initcall(da903x_regulator_init);
static void __exit da903x_regulator_exit(void)
{
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 23d554628a76..cdc674fb46c3 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -44,10 +44,22 @@ static int fixed_voltage_get_voltage(struct regulator_dev *dev)
return data->microvolts;
}
+static int fixed_voltage_list_voltage(struct regulator_dev *dev,
+ unsigned selector)
+{
+ struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+ if (selector != 0)
+ return -EINVAL;
+
+ return data->microvolts;
+}
+
static struct regulator_ops fixed_voltage_ops = {
.is_enabled = fixed_voltage_is_enabled,
.enable = fixed_voltage_enable,
.get_voltage = fixed_voltage_get_voltage,
+ .list_voltage = fixed_voltage_list_voltage,
};
static int regulator_fixed_voltage_probe(struct platform_device *pdev)
@@ -69,7 +81,8 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
}
drvdata->desc.type = REGULATOR_VOLTAGE;
drvdata->desc.owner = THIS_MODULE;
- drvdata->desc.ops = &fixed_voltage_ops,
+ drvdata->desc.ops = &fixed_voltage_ops;
+ drvdata->desc.n_voltages = 1;
drvdata->microvolts = config->microvolts;
@@ -117,7 +130,7 @@ static int __init regulator_fixed_voltage_init(void)
{
return platform_driver_register(&regulator_fixed_voltage_driver);
}
-module_init(regulator_fixed_voltage_init);
+subsys_initcall(regulator_fixed_voltage_init);
static void __exit regulator_fixed_voltage_exit(void)
{
@@ -128,3 +141,4 @@ module_exit(regulator_fixed_voltage_exit);
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_DESCRIPTION("Fixed voltage regulator");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:reg-fixed-voltage");
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
new file mode 100644
index 000000000000..bbbb55fcfe8c
--- /dev/null
+++ b/drivers/regulator/max1586.c
@@ -0,0 +1,249 @@
+/*
+ * max1586.c -- Voltage and current regulation for the Maxim 1586
+ *
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * 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/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/max1586.h>
+
+#define MAX1586_V3_MAX_VSEL 31
+#define MAX1586_V6_MAX_VSEL 3
+
+#define MAX1586_V3_MIN_UV 700000
+#define MAX1586_V3_MAX_UV 1475000
+#define MAX1586_V3_STEP_UV 25000
+
+#define MAX1586_V6_MIN_UV 0
+#define MAX1586_V6_MAX_UV 3000000
+
+#define I2C_V3_SELECT (0 << 5)
+#define I2C_V6_SELECT (1 << 5)
+
+/*
+ * V3 voltage
+ * On I2C bus, sending a "x" byte to the max1586 means :
+ * set V3 to 0.700V + (x & 0x1f) * 0.025V
+ */
+static int max1586_v3_calc_voltage(unsigned selector)
+{
+ return MAX1586_V3_MIN_UV + (MAX1586_V3_STEP_UV * selector);
+}
+
+static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+ struct i2c_client *client = rdev_get_drvdata(rdev);
+ unsigned selector;
+ u8 v3_prog;
+
+ if (min_uV < MAX1586_V3_MIN_UV || min_uV > MAX1586_V3_MAX_UV)
+ return -EINVAL;
+ if (max_uV < MAX1586_V3_MIN_UV || max_uV > MAX1586_V3_MAX_UV)
+ return -EINVAL;
+
+ selector = (min_uV - MAX1586_V3_MIN_UV) / MAX1586_V3_STEP_UV;
+ if (max1586_v3_calc_voltage(selector) > max_uV)
+ return -EINVAL;
+
+ dev_dbg(&client->dev, "changing voltage v3 to %dmv\n",
+ max1586_v3_calc_voltage(selector) / 1000);
+
+ v3_prog = I2C_V3_SELECT | (u8) selector;
+ return i2c_smbus_write_byte(client, v3_prog);
+}
+
+static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector)
+{
+ if (selector > MAX1586_V3_MAX_VSEL)
+ return -EINVAL;
+ return max1586_v3_calc_voltage(selector);
+}
+
+/*
+ * V6 voltage
+ * On I2C bus, sending a "x" byte to the max1586 means :
+ * set V6 to either 0V, 1.8V, 2.5V, 3V depending on (x & 0x3)
+ * As regulator framework doesn't accept voltages to be 0V, we use 1uV.
+ */
+static int max1586_v6_calc_voltage(unsigned selector)
+{
+ static int voltages_uv[] = { 1, 1800000, 2500000, 3000000 };
+
+ return voltages_uv[selector];
+}
+
+static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+ struct i2c_client *client = rdev_get_drvdata(rdev);
+ unsigned selector;
+ u8 v6_prog;
+
+ if (min_uV < MAX1586_V6_MIN_UV || min_uV > MAX1586_V6_MAX_UV)
+ return -EINVAL;
+ if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV)
+ return -EINVAL;
+
+ if (min_uV >= 3000000)
+ selector = 3;
+ if (min_uV < 3000000)
+ selector = 2;
+ if (min_uV < 2500000)
+ selector = 1;
+ if (min_uV < 1800000)
+ selector = 0;
+
+ if (max1586_v6_calc_voltage(selector) > max_uV)
+ return -EINVAL;
+
+ dev_dbg(&client->dev, "changing voltage v6 to %dmv\n",
+ max1586_v6_calc_voltage(selector) / 1000);
+
+ v6_prog = I2C_V6_SELECT | (u8) selector;
+ return i2c_smbus_write_byte(client, v6_prog);
+}
+
+static int max1586_v6_list(struct regulator_dev *rdev, unsigned selector)
+{
+ if (selector > MAX1586_V6_MAX_VSEL)
+ return -EINVAL;
+ return max1586_v6_calc_voltage(selector);
+}
+
+/*
+ * The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back
+ * the set up value.
+ */
+static struct regulator_ops max1586_v3_ops = {
+ .set_voltage = max1586_v3_set,
+ .list_voltage = max1586_v3_list,
+};
+
+static struct regulator_ops max1586_v6_ops = {
+ .set_voltage = max1586_v6_set,
+ .list_voltage = max1586_v6_list,
+};
+
+static struct regulator_desc max1586_reg[] = {
+ {
+ .name = "Output_V3",
+ .id = MAX1586_V3,
+ .ops = &max1586_v3_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = MAX1586_V3_MAX_VSEL + 1,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "Output_V6",
+ .id = MAX1586_V6,
+ .ops = &max1586_v6_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = MAX1586_V6_MAX_VSEL + 1,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int max1586_pmic_probe(struct i2c_client *client,
+ const struct i2c_device_id *i2c_id)
+{
+ struct regulator_dev **rdev;
+ struct max1586_platform_data *pdata = client->dev.platform_data;
+ int i, id, ret = 0;
+
+ rdev = kzalloc(sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
+ GFP_KERNEL);
+ if (!rdev)
+ return -ENOMEM;
+
+ ret = -EINVAL;
+ for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) {
+ id = pdata->subdevs[i].id;
+ if (!pdata->subdevs[i].platform_data)
+ continue;
+ if (id < MAX1586_V3 || id > MAX1586_V6) {
+ dev_err(&client->dev, "invalid regulator id %d\n", id);
+ goto err;
+ }
+ rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
+ pdata->subdevs[i].platform_data,
+ client);
+ if (IS_ERR(rdev[i])) {
+ ret = PTR_ERR(rdev[i]);
+ dev_err(&client->dev, "failed to register %s\n",
+ max1586_reg[id].name);
+ goto err;
+ }
+ }
+
+ i2c_set_clientdata(client, rdev);
+ dev_info(&client->dev, "Maxim 1586 regulator driver loaded\n");
+ return 0;
+
+err:
+ while (--i >= 0)
+ regulator_unregister(rdev[i]);
+ kfree(rdev);
+ return ret;
+}
+
+static int max1586_pmic_remove(struct i2c_client *client)
+{
+ struct regulator_dev **rdev = i2c_get_clientdata(client);
+ int i;
+
+ for (i = 0; i <= MAX1586_V6; i++)
+ if (rdev[i])
+ regulator_unregister(rdev[i]);
+ kfree(rdev);
+ i2c_set_clientdata(client, NULL);
+
+ return 0;
+}
+
+static const struct i2c_device_id max1586_id[] = {
+ { "max1586", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max1586_id);
+
+static struct i2c_driver max1586_pmic_driver = {
+ .probe = max1586_pmic_probe,
+ .remove = max1586_pmic_remove,
+ .driver = {
+ .name = "max1586",
+ },
+ .id_table = max1586_id,
+};
+
+static int __init max1586_pmic_init(void)
+{
+ return i2c_add_driver(&max1586_pmic_driver);
+}
+subsys_initcall(max1586_pmic_init);
+
+static void __exit max1586_pmic_exit(void)
+{
+ i2c_del_driver(&max1586_pmic_driver);
+}
+module_exit(max1586_pmic_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("MAXIM 1586 voltage regulator driver");
+MODULE_AUTHOR("Robert Jarzmik");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index cd761d85c8fd..8e14900eb686 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -316,7 +316,7 @@ static int __init pcf50633_regulator_init(void)
{
return platform_driver_register(&pcf50633_regulator_driver);
}
-module_init(pcf50633_regulator_init);
+subsys_initcall(pcf50633_regulator_init);
static void __exit pcf50633_regulator_exit(void)
{
diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c
new file mode 100644
index 000000000000..06d2fa96a8b4
--- /dev/null
+++ b/drivers/regulator/userspace-consumer.c
@@ -0,0 +1,200 @@
+/*
+ * userspace-consumer.c
+ *
+ * Copyright 2009 CompuLab, Ltd.
+ *
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * Based of virtual consumer driver:
+ * Copyright 2008 Wolfson Microelectronics PLC.
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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.
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/userspace-consumer.h>
+
+struct userspace_consumer_data {
+ const char *name;
+
+ struct mutex lock;
+ bool enabled;
+
+ int num_supplies;
+ struct regulator_bulk_data *supplies;
+};
+
+static ssize_t reg_show_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct userspace_consumer_data *data = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%s\n", data->name);
+}
+
+static ssize_t reg_show_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct userspace_consumer_data *data = dev_get_drvdata(dev);
+
+ if (data->enabled)
+ return sprintf(buf, "enabled\n");
+
+ return sprintf(buf, "disabled\n");
+}
+
+static ssize_t reg_set_state(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct userspace_consumer_data *data = dev_get_drvdata(dev);
+ bool enabled;
+ int ret;
+
+ /*
+ * sysfs_streq() doesn't need the \n's, but we add them so the strings
+ * will be shared with show_state(), above.
+ */
+ if (sysfs_streq(buf, "enabled\n") || sysfs_streq(buf, "1"))
+ enabled = true;
+ else if (sysfs_streq(buf, "disabled\n") || sysfs_streq(buf, "0"))
+ enabled = false;
+ else {
+ dev_err(dev, "Configuring invalid mode\n");
+ return count;
+ }
+
+ mutex_lock(&data->lock);
+ if (enabled != data->enabled) {
+ if (enabled)
+ ret = regulator_bulk_enable(data->num_supplies,
+ data->supplies);
+ else
+ ret = regulator_bulk_disable(data->num_supplies,
+ data->supplies);
+
+ if (ret == 0)
+ data->enabled = enabled;
+ else
+ dev_err(dev, "Failed to configure state: %d\n", ret);
+ }
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(name, 0444, reg_show_name, NULL);
+static DEVICE_ATTR(state, 0644, reg_show_state, reg_set_state);
+
+static struct device_attribute *attributes[] = {
+ &dev_attr_name,
+ &dev_attr_state,
+};
+
+static int regulator_userspace_consumer_probe(struct platform_device *pdev)
+{
+ struct regulator_userspace_consumer_data *pdata;
+ struct userspace_consumer_data *drvdata;
+ int ret, i;
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata)
+ return -EINVAL;
+
+ drvdata = kzalloc(sizeof(struct userspace_consumer_data), GFP_KERNEL);
+ if (drvdata == NULL)
+ return -ENOMEM;
+
+ drvdata->name = pdata->name;
+ drvdata->num_supplies = pdata->num_supplies;
+ drvdata->supplies = pdata->supplies;
+
+ mutex_init(&drvdata->lock);
+
+ ret = regulator_bulk_get(&pdev->dev, drvdata->num_supplies,
+ drvdata->supplies);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to get supplies: %d\n", ret);
+ goto err_alloc_supplies;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(attributes); i++) {
+ ret = device_create_file(&pdev->dev, attributes[i]);
+ if (ret != 0)
+ goto err_create_attrs;
+ }
+
+ if (pdata->init_on)
+ ret = regulator_bulk_enable(drvdata->num_supplies,
+ drvdata->supplies);
+
+ drvdata->enabled = pdata->init_on;
+
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to set initial state: %d\n", ret);
+ goto err_create_attrs;
+ }
+
+ platform_set_drvdata(pdev, drvdata);
+
+ return 0;
+
+err_create_attrs:
+ for (i = 0; i < ARRAY_SIZE(attributes); i++)
+ device_remove_file(&pdev->dev, attributes[i]);
+
+ regulator_bulk_free(drvdata->num_supplies, drvdata->supplies);
+
+err_alloc_supplies:
+ kfree(drvdata);
+ return ret;
+}
+
+static int regulator_userspace_consumer_remove(struct platform_device *pdev)
+{
+ struct userspace_consumer_data *data = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(attributes); i++)
+ device_remove_file(&pdev->dev, attributes[i]);
+
+ if (data->enabled)
+ regulator_bulk_disable(data->num_supplies, data->supplies);
+
+ regulator_bulk_free(data->num_supplies, data->supplies);
+ kfree(data);
+
+ return 0;
+}
+
+static struct platform_driver regulator_userspace_consumer_driver = {
+ .probe = regulator_userspace_consumer_probe,
+ .remove = regulator_userspace_consumer_remove,
+ .driver = {
+ .name = "reg-userspace-consumer",
+ },
+};
+
+
+static int __init regulator_userspace_consumer_init(void)
+{
+ return platform_driver_register(&regulator_userspace_consumer_driver);
+}
+module_init(regulator_userspace_consumer_init);
+
+static void __exit regulator_userspace_consumer_exit(void)
+{
+ platform_driver_unregister(&regulator_userspace_consumer_driver);
+}
+module_exit(regulator_userspace_consumer_exit);
+
+MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
+MODULE_DESCRIPTION("Userspace consumer for voltage and current regulators");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index 71403fa3ffa1..e7db5664722e 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -347,3 +347,4 @@ module_exit(regulator_virtual_consumer_exit);
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_DESCRIPTION("Virtual regulator consumer");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:reg-virt-consumer");
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 771eca1066b5..17a00b0fafd1 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1570,3 +1570,4 @@ module_exit(wm8350_regulator_exit);
MODULE_AUTHOR("Liam Girdwood");
MODULE_DESCRIPTION("WM8350 voltage and current regulator driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8350-regulator");
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
index 157426029071..d9a2c988c6e7 100644
--- a/drivers/regulator/wm8400-regulator.c
+++ b/drivers/regulator/wm8400-regulator.c
@@ -320,7 +320,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
- pdev->dev.platform_data, pdev->dev.driver_data);
+ pdev->dev.platform_data, dev_get_drvdata(&pdev->dev));
if (IS_ERR(rdev))
return PTR_ERR(rdev);
@@ -359,7 +359,7 @@ static struct platform_driver wm8400_regulator_driver = {
int wm8400_register_regulator(struct device *dev, int reg,
struct regulator_init_data *initdata)
{
- struct wm8400 *wm8400 = dev->driver_data;
+ struct wm8400 *wm8400 = dev_get_drvdata(dev);
if (wm8400->regulators[reg].name)
return -EBUSY;
@@ -369,8 +369,8 @@ int wm8400_register_regulator(struct device *dev, int reg,
wm8400->regulators[reg].name = "wm8400-regulator";
wm8400->regulators[reg].id = reg;
wm8400->regulators[reg].dev.parent = dev;
- wm8400->regulators[reg].dev.driver_data = wm8400;
wm8400->regulators[reg].dev.platform_data = initdata;
+ dev_set_drvdata(&wm8400->regulators[reg].dev, wm8400);
return platform_device_register(&wm8400->regulators[reg]);
}
@@ -380,7 +380,7 @@ static int __init wm8400_regulator_init(void)
{
return platform_driver_register(&wm8400_regulator_driver);
}
-module_init(wm8400_regulator_init);
+subsys_initcall(wm8400_regulator_init);
static void __exit wm8400_regulator_exit(void)
{
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 4e9851fc1746..1f27cedc452c 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -491,6 +491,15 @@ config RTC_DRV_M48T59
This driver can also be built as a module, if so, the module
will be called "rtc-m48t59".
+config RTC_DRV_MSM6242
+ tristate "Oki MSM6242"
+ help
+ If you say yes here you get support for the Oki MSM6242
+ timekeeping chip. It is used in some Amiga models (e.g. A2000).
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-msm6242.
+
config RTC_DRV_BQ4802
tristate "TI BQ4802"
help
@@ -500,6 +509,16 @@ config RTC_DRV_BQ4802
This driver can also be built as a module. If so, the module
will be called rtc-bq4802.
+config RTC_DRV_RP5C01
+ tristate "Ricoh RP5C01"
+ help
+ If you say yes here you get support for the Ricoh RP5C01
+ timekeeping chip. It is used in some Amiga models (e.g. A3000
+ and A4000).
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-rp5c01.
+
config RTC_DRV_V3020
tristate "EM Microelectronic V3020"
help
@@ -692,7 +711,7 @@ config RTC_DRV_GENERIC
tristate "Generic RTC support"
# Please consider writing a new RTC driver instead of using the generic
# RTC abstraction
- depends on PARISC || M68K || PPC
+ depends on PARISC || M68K || PPC || SUPERH32
help
Say Y or M here to enable RTC support on systems using the generic
RTC abstraction. If you do not know what you are doing, you should
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 6c0639a14f09..ab0275cae87f 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
+obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
@@ -59,6 +60,7 @@ obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
+obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index f7a3283dd029..551332e4ed02 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -12,32 +12,56 @@
#include <linux/module.h>
#include <linux/rtc.h>
#include <linux/platform_device.h>
-#include <mach/hardware.h>
+#include <linux/io.h>
+
+#define EP93XX_RTC_DATA 0x000
+#define EP93XX_RTC_MATCH 0x004
+#define EP93XX_RTC_STATUS 0x008
+#define EP93XX_RTC_STATUS_INTR (1<<0)
+#define EP93XX_RTC_LOAD 0x00C
+#define EP93XX_RTC_CONTROL 0x010
+#define EP93XX_RTC_CONTROL_MIE (1<<0)
+#define EP93XX_RTC_SWCOMP 0x108
+#define EP93XX_RTC_SWCOMP_DEL_MASK 0x001f0000
+#define EP93XX_RTC_SWCOMP_DEL_SHIFT 16
+#define EP93XX_RTC_SWCOMP_INT_MASK 0x0000ffff
+#define EP93XX_RTC_SWCOMP_INT_SHIFT 0
+
+#define DRV_VERSION "0.3"
-#define EP93XX_RTC_REG(x) (EP93XX_RTC_BASE + (x))
-#define EP93XX_RTC_DATA EP93XX_RTC_REG(0x0000)
-#define EP93XX_RTC_LOAD EP93XX_RTC_REG(0x000C)
-#define EP93XX_RTC_SWCOMP EP93XX_RTC_REG(0x0108)
-
-#define DRV_VERSION "0.2"
+/*
+ * struct device dev.platform_data is used to store our private data
+ * because struct rtc_device does not have a variable to hold it.
+ */
+struct ep93xx_rtc {
+ void __iomem *mmio_base;
+};
-static int ep93xx_get_swcomp(struct device *dev, unsigned short *preload,
+static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
unsigned short *delete)
{
- unsigned short comp = __raw_readl(EP93XX_RTC_SWCOMP);
+ struct ep93xx_rtc *ep93xx_rtc = dev->platform_data;
+ unsigned long comp;
+
+ comp = __raw_readl(ep93xx_rtc->mmio_base + EP93XX_RTC_SWCOMP);
if (preload)
- *preload = comp & 0xffff;
+ *preload = (comp & EP93XX_RTC_SWCOMP_INT_MASK)
+ >> EP93XX_RTC_SWCOMP_INT_SHIFT;
if (delete)
- *delete = (comp >> 16) & 0x1f;
+ *delete = (comp & EP93XX_RTC_SWCOMP_DEL_MASK)
+ >> EP93XX_RTC_SWCOMP_DEL_SHIFT;
return 0;
}
static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
- unsigned long time = __raw_readl(EP93XX_RTC_DATA);
+ struct ep93xx_rtc *ep93xx_rtc = dev->platform_data;
+ unsigned long time;
+
+ time = __raw_readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA);
rtc_time_to_tm(time, tm);
return 0;
@@ -45,7 +69,9 @@ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs)
{
- __raw_writel(secs + 1, EP93XX_RTC_LOAD);
+ struct ep93xx_rtc *ep93xx_rtc = dev->platform_data;
+
+ __raw_writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD);
return 0;
}
@@ -53,7 +79,7 @@ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq)
{
unsigned short preload, delete;
- ep93xx_get_swcomp(dev, &preload, &delete);
+ ep93xx_rtc_get_swcomp(dev, &preload, &delete);
seq_printf(seq, "preload\t\t: %d\n", preload);
seq_printf(seq, "delete\t\t: %d\n", delete);
@@ -67,54 +93,104 @@ static const struct rtc_class_ops ep93xx_rtc_ops = {
.proc = ep93xx_rtc_proc,
};
-static ssize_t ep93xx_sysfs_show_comp_preload(struct device *dev,
+static ssize_t ep93xx_rtc_show_comp_preload(struct device *dev,
struct device_attribute *attr, char *buf)
{
unsigned short preload;
- ep93xx_get_swcomp(dev, &preload, NULL);
+ ep93xx_rtc_get_swcomp(dev, &preload, NULL);
return sprintf(buf, "%d\n", preload);
}
-static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_sysfs_show_comp_preload, NULL);
+static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_rtc_show_comp_preload, NULL);
-static ssize_t ep93xx_sysfs_show_comp_delete(struct device *dev,
+static ssize_t ep93xx_rtc_show_comp_delete(struct device *dev,
struct device_attribute *attr, char *buf)
{
unsigned short delete;
- ep93xx_get_swcomp(dev, NULL, &delete);
+ ep93xx_rtc_get_swcomp(dev, NULL, &delete);
return sprintf(buf, "%d\n", delete);
}
-static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_sysfs_show_comp_delete, NULL);
+static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_rtc_show_comp_delete, NULL);
-static int __devinit ep93xx_rtc_probe(struct platform_device *dev)
+static int __init ep93xx_rtc_probe(struct platform_device *pdev)
{
- struct rtc_device *rtc = rtc_device_register("ep93xx",
- &dev->dev, &ep93xx_rtc_ops, THIS_MODULE);
+ struct ep93xx_rtc *ep93xx_rtc;
+ struct resource *res;
+ struct rtc_device *rtc;
+ int err;
+
+ ep93xx_rtc = kzalloc(sizeof(struct ep93xx_rtc), GFP_KERNEL);
+ if (ep93xx_rtc == NULL)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL)
+ return -ENXIO;
+
+ res = request_mem_region(res->start, resource_size(res), pdev->name);
+ if (res == NULL)
+ return -EBUSY;
+
+ ep93xx_rtc->mmio_base = ioremap(res->start, resource_size(res));
+ if (ep93xx_rtc->mmio_base == NULL) {
+ err = -ENXIO;
+ goto fail;
+ }
+ pdev->dev.platform_data = ep93xx_rtc;
+
+ rtc = rtc_device_register(pdev->name,
+ &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
- return PTR_ERR(rtc);
+ err = PTR_ERR(rtc);
+ goto fail;
}
- platform_set_drvdata(dev, rtc);
+ platform_set_drvdata(pdev, rtc);
- device_create_file(&dev->dev, &dev_attr_comp_preload);
- device_create_file(&dev->dev, &dev_attr_comp_delete);
+ err = device_create_file(&pdev->dev, &dev_attr_comp_preload);
+ if (err)
+ goto fail;
+ err = device_create_file(&pdev->dev, &dev_attr_comp_delete);
+ if (err) {
+ device_remove_file(&pdev->dev, &dev_attr_comp_preload);
+ goto fail;
+ }
return 0;
+
+fail:
+ if (ep93xx_rtc->mmio_base) {
+ iounmap(ep93xx_rtc->mmio_base);
+ pdev->dev.platform_data = NULL;
+ }
+ release_mem_region(res->start, resource_size(res));
+ return err;
}
-static int __devexit ep93xx_rtc_remove(struct platform_device *dev)
+static int __exit ep93xx_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtc = platform_get_drvdata(dev);
+ struct rtc_device *rtc = platform_get_drvdata(pdev);
+ struct ep93xx_rtc *ep93xx_rtc = pdev->dev.platform_data;
+ struct resource *res;
+
+ /* cleanup sysfs */
+ device_remove_file(&pdev->dev, &dev_attr_comp_delete);
+ device_remove_file(&pdev->dev, &dev_attr_comp_preload);
+
+ rtc_device_unregister(rtc);
+
+ iounmap(ep93xx_rtc->mmio_base);
+ pdev->dev.platform_data = NULL;
- if (rtc)
- rtc_device_unregister(rtc);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
- platform_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
return 0;
}
@@ -122,23 +198,22 @@ static int __devexit ep93xx_rtc_remove(struct platform_device *dev)
/* work with hotplug and coldplug */
MODULE_ALIAS("platform:ep93xx-rtc");
-static struct platform_driver ep93xx_rtc_platform_driver = {
+static struct platform_driver ep93xx_rtc_driver = {
.driver = {
.name = "ep93xx-rtc",
.owner = THIS_MODULE,
},
- .probe = ep93xx_rtc_probe,
- .remove = __devexit_p(ep93xx_rtc_remove),
+ .remove = __exit_p(ep93xx_rtc_remove),
};
static int __init ep93xx_rtc_init(void)
{
- return platform_driver_register(&ep93xx_rtc_platform_driver);
+ return platform_driver_probe(&ep93xx_rtc_driver, ep93xx_rtc_probe);
}
static void __exit ep93xx_rtc_exit(void)
{
- platform_driver_unregister(&ep93xx_rtc_platform_driver);
+ platform_driver_unregister(&ep93xx_rtc_driver);
}
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c
new file mode 100644
index 000000000000..10b9b7fb4700
--- /dev/null
+++ b/drivers/rtc/rtc-msm6242.c
@@ -0,0 +1,268 @@
+/*
+ * Oki MSM6242 RTC Driver
+ *
+ * Copyright 2009 Geert Uytterhoeven
+ *
+ * Based on the A2000 TOD code in arch/m68k/amiga/config.c
+ * Copyright (C) 1993 Hamish Macdonald
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+
+enum {
+ MSM6242_SECOND1 = 0x0, /* 1-second digit register */
+ MSM6242_SECOND10 = 0x1, /* 10-second digit register */
+ MSM6242_MINUTE1 = 0x2, /* 1-minute digit register */
+ MSM6242_MINUTE10 = 0x3, /* 10-minute digit register */
+ MSM6242_HOUR1 = 0x4, /* 1-hour digit register */
+ MSM6242_HOUR10 = 0x5, /* PM/AM, 10-hour digit register */
+ MSM6242_DAY1 = 0x6, /* 1-day digit register */
+ MSM6242_DAY10 = 0x7, /* 10-day digit register */
+ MSM6242_MONTH1 = 0x8, /* 1-month digit register */
+ MSM6242_MONTH10 = 0x9, /* 10-month digit register */
+ MSM6242_YEAR1 = 0xa, /* 1-year digit register */
+ MSM6242_YEAR10 = 0xb, /* 10-year digit register */
+ MSM6242_WEEK = 0xc, /* Week register */
+ MSM6242_CD = 0xd, /* Control Register D */
+ MSM6242_CE = 0xe, /* Control Register E */
+ MSM6242_CF = 0xf, /* Control Register F */
+};
+
+#define MSM6242_HOUR10_AM (0 << 2)
+#define MSM6242_HOUR10_PM (1 << 2)
+#define MSM6242_HOUR10_HR_MASK (3 << 0)
+
+#define MSM6242_WEEK_SUNDAY 0
+#define MSM6242_WEEK_MONDAY 1
+#define MSM6242_WEEK_TUESDAY 2
+#define MSM6242_WEEK_WEDNESDAY 3
+#define MSM6242_WEEK_THURSDAY 4
+#define MSM6242_WEEK_FRIDAY 5
+#define MSM6242_WEEK_SATURDAY 6
+
+#define MSM6242_CD_30_S_ADJ (1 << 3) /* 30-second adjustment */
+#define MSM6242_CD_IRQ_FLAG (1 << 2)
+#define MSM6242_CD_BUSY (1 << 1)
+#define MSM6242_CD_HOLD (1 << 0)
+
+#define MSM6242_CE_T_MASK (3 << 2)
+#define MSM6242_CE_T_64HZ (0 << 2) /* period 1/64 second */
+#define MSM6242_CE_T_1HZ (1 << 2) /* period 1 second */
+#define MSM6242_CE_T_1MINUTE (2 << 2) /* period 1 minute */
+#define MSM6242_CE_T_1HOUR (3 << 2) /* period 1 hour */
+
+#define MSM6242_CE_ITRPT_STND (1 << 1)
+#define MSM6242_CE_MASK (1 << 0) /* STD.P output control */
+
+#define MSM6242_CF_TEST (1 << 3)
+#define MSM6242_CF_12H (0 << 2)
+#define MSM6242_CF_24H (1 << 2)
+#define MSM6242_CF_STOP (1 << 1)
+#define MSM6242_CF_REST (1 << 0) /* reset */
+
+
+struct msm6242_priv {
+ u32 __iomem *regs;
+ struct rtc_device *rtc;
+};
+
+static inline unsigned int msm6242_read(struct msm6242_priv *priv,
+ unsigned int reg)
+{
+ return __raw_readl(&priv->regs[reg]) & 0xf;
+}
+
+static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val,
+ unsigned int reg)
+{
+ return __raw_writel(val, &priv->regs[reg]);
+}
+
+static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val,
+ unsigned int reg)
+{
+ msm6242_write(priv, msm6242_read(priv, reg) | val, reg);
+}
+
+static inline void msm6242_clear(struct msm6242_priv *priv, unsigned int val,
+ unsigned int reg)
+{
+ msm6242_write(priv, msm6242_read(priv, reg) & ~val, reg);
+}
+
+static void msm6242_lock(struct msm6242_priv *priv)
+{
+ int cnt = 5;
+
+ msm6242_set(priv, MSM6242_CD_HOLD, MSM6242_CD);
+
+ while ((msm6242_read(priv, MSM6242_CD) & MSM6242_CD_BUSY) && cnt--) {
+ msm6242_clear(priv, MSM6242_CD_HOLD, MSM6242_CD);
+ udelay(70);
+ msm6242_set(priv, MSM6242_CD_HOLD, MSM6242_CD);
+ }
+
+ if (!cnt)
+ pr_warning("msm6242: timed out waiting for RTC (0x%x)\n",
+ msm6242_read(priv, MSM6242_CD));
+}
+
+static void msm6242_unlock(struct msm6242_priv *priv)
+{
+ msm6242_clear(priv, MSM6242_CD_HOLD, MSM6242_CD);
+}
+
+static int msm6242_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct msm6242_priv *priv = dev_get_drvdata(dev);
+
+ msm6242_lock(priv);
+
+ tm->tm_sec = msm6242_read(priv, MSM6242_SECOND10) * 10 +
+ msm6242_read(priv, MSM6242_SECOND1);
+ tm->tm_min = msm6242_read(priv, MSM6242_MINUTE10) * 10 +
+ msm6242_read(priv, MSM6242_MINUTE1);
+ tm->tm_hour = (msm6242_read(priv, MSM6242_HOUR10 & 3)) * 10 +
+ msm6242_read(priv, MSM6242_HOUR1);
+ tm->tm_mday = msm6242_read(priv, MSM6242_DAY10) * 10 +
+ msm6242_read(priv, MSM6242_DAY1);
+ tm->tm_wday = msm6242_read(priv, MSM6242_WEEK);
+ tm->tm_mon = msm6242_read(priv, MSM6242_MONTH10) * 10 +
+ msm6242_read(priv, MSM6242_MONTH1) - 1;
+ tm->tm_year = msm6242_read(priv, MSM6242_YEAR10) * 10 +
+ msm6242_read(priv, MSM6242_YEAR1);
+ if (tm->tm_year <= 69)
+ tm->tm_year += 100;
+
+ if (!(msm6242_read(priv, MSM6242_CF) & MSM6242_CF_24H)) {
+ unsigned int pm = msm6242_read(priv, MSM6242_HOUR10) &
+ MSM6242_HOUR10_PM;
+ if (!pm && tm->tm_hour == 12)
+ tm->tm_hour = 0;
+ else if (pm && tm->tm_hour != 12)
+ tm->tm_hour += 12;
+ }
+
+ msm6242_unlock(priv);
+
+ return rtc_valid_tm(tm);
+}
+
+static int msm6242_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct msm6242_priv *priv = dev_get_drvdata(dev);
+
+ msm6242_lock(priv);
+
+ msm6242_write(priv, tm->tm_sec / 10, MSM6242_SECOND10);
+ msm6242_write(priv, tm->tm_sec % 10, MSM6242_SECOND1);
+ msm6242_write(priv, tm->tm_min / 10, MSM6242_MINUTE10);
+ msm6242_write(priv, tm->tm_min % 10, MSM6242_MINUTE1);
+ if (msm6242_read(priv, MSM6242_CF) & MSM6242_CF_24H)
+ msm6242_write(priv, tm->tm_hour / 10, MSM6242_HOUR10);
+ else if (tm->tm_hour >= 12)
+ msm6242_write(priv, MSM6242_HOUR10_PM + (tm->tm_hour - 12) / 10,
+ MSM6242_HOUR10);
+ else
+ msm6242_write(priv, tm->tm_hour / 10, MSM6242_HOUR10);
+ msm6242_write(priv, tm->tm_hour % 10, MSM6242_HOUR1);
+ msm6242_write(priv, tm->tm_mday / 10, MSM6242_DAY10);
+ msm6242_write(priv, tm->tm_mday % 10, MSM6242_DAY1);
+ if (tm->tm_wday != -1)
+ msm6242_write(priv, tm->tm_wday, MSM6242_WEEK);
+ msm6242_write(priv, (tm->tm_mon + 1) / 10, MSM6242_MONTH10);
+ msm6242_write(priv, (tm->tm_mon + 1) % 10, MSM6242_MONTH1);
+ if (tm->tm_year >= 100)
+ tm->tm_year -= 100;
+ msm6242_write(priv, tm->tm_year / 10, MSM6242_YEAR10);
+ msm6242_write(priv, tm->tm_year % 10, MSM6242_YEAR1);
+
+ msm6242_unlock(priv);
+ return 0;
+}
+
+static const struct rtc_class_ops msm6242_rtc_ops = {
+ .read_time = msm6242_read_time,
+ .set_time = msm6242_set_time,
+};
+
+static int __init msm6242_rtc_probe(struct platform_device *dev)
+{
+ struct resource *res;
+ struct msm6242_priv *priv;
+ struct rtc_device *rtc;
+ int error;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->regs = ioremap(res->start, resource_size(res));
+ if (!priv->regs) {
+ error = -ENOMEM;
+ goto out_free_priv;
+ }
+
+ rtc = rtc_device_register("rtc-msm6242", &dev->dev, &msm6242_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc)) {
+ error = PTR_ERR(rtc);
+ goto out_unmap;
+ }
+
+ priv->rtc = rtc;
+ platform_set_drvdata(dev, priv);
+ return 0;
+
+out_unmap:
+ iounmap(priv->regs);
+out_free_priv:
+ kfree(priv);
+ return error;
+}
+
+static int __exit msm6242_rtc_remove(struct platform_device *dev)
+{
+ struct msm6242_priv *priv = platform_get_drvdata(dev);
+
+ rtc_device_unregister(priv->rtc);
+ iounmap(priv->regs);
+ kfree(priv);
+ return 0;
+}
+
+static struct platform_driver msm6242_rtc_driver = {
+ .driver = {
+ .name = "rtc-msm6242",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(msm6242_rtc_remove),
+};
+
+static int __init msm6242_rtc_init(void)
+{
+ return platform_driver_probe(&msm6242_rtc_driver, msm6242_rtc_probe);
+}
+
+static void __exit msm6242_rtc_fini(void)
+{
+ platform_driver_unregister(&msm6242_rtc_driver);
+}
+
+module_init(msm6242_rtc_init);
+module_exit(msm6242_rtc_fini);
+
+MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Oki MSM6242 RTC driver");
+MODULE_ALIAS("platform:rtc-msm6242");
diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c
new file mode 100644
index 000000000000..e1313feb060f
--- /dev/null
+++ b/drivers/rtc/rtc-rp5c01.c
@@ -0,0 +1,222 @@
+/*
+ * Ricoh RP5C01 RTC Driver
+ *
+ * Copyright 2009 Geert Uytterhoeven
+ *
+ * Based on the A3000 TOD code in arch/m68k/amiga/config.c
+ * Copyright (C) 1993 Hamish Macdonald
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+
+enum {
+ RP5C01_1_SECOND = 0x0, /* MODE 00 */
+ RP5C01_10_SECOND = 0x1, /* MODE 00 */
+ RP5C01_1_MINUTE = 0x2, /* MODE 00 and MODE 01 */
+ RP5C01_10_MINUTE = 0x3, /* MODE 00 and MODE 01 */
+ RP5C01_1_HOUR = 0x4, /* MODE 00 and MODE 01 */
+ RP5C01_10_HOUR = 0x5, /* MODE 00 and MODE 01 */
+ RP5C01_DAY_OF_WEEK = 0x6, /* MODE 00 and MODE 01 */
+ RP5C01_1_DAY = 0x7, /* MODE 00 and MODE 01 */
+ RP5C01_10_DAY = 0x8, /* MODE 00 and MODE 01 */
+ RP5C01_1_MONTH = 0x9, /* MODE 00 */
+ RP5C01_10_MONTH = 0xa, /* MODE 00 */
+ RP5C01_1_YEAR = 0xb, /* MODE 00 */
+ RP5C01_10_YEAR = 0xc, /* MODE 00 */
+
+ RP5C01_12_24_SELECT = 0xa, /* MODE 01 */
+ RP5C01_LEAP_YEAR = 0xb, /* MODE 01 */
+
+ RP5C01_MODE = 0xd, /* all modes */
+ RP5C01_TEST = 0xe, /* all modes */
+ RP5C01_RESET = 0xf, /* all modes */
+};
+
+#define RP5C01_12_24_SELECT_12 (0 << 0)
+#define RP5C01_12_24_SELECT_24 (1 << 0)
+
+#define RP5C01_10_HOUR_AM (0 << 1)
+#define RP5C01_10_HOUR_PM (1 << 1)
+
+#define RP5C01_MODE_TIMER_EN (1 << 3) /* timer enable */
+#define RP5C01_MODE_ALARM_EN (1 << 2) /* alarm enable */
+
+#define RP5C01_MODE_MODE_MASK (3 << 0)
+#define RP5C01_MODE_MODE00 (0 << 0) /* time */
+#define RP5C01_MODE_MODE01 (1 << 0) /* alarm, 12h/24h, leap year */
+#define RP5C01_MODE_RAM_BLOCK10 (2 << 0) /* RAM 4 bits x 13 */
+#define RP5C01_MODE_RAM_BLOCK11 (3 << 0) /* RAM 4 bits x 13 */
+
+#define RP5C01_RESET_1HZ_PULSE (1 << 3)
+#define RP5C01_RESET_16HZ_PULSE (1 << 2)
+#define RP5C01_RESET_SECOND (1 << 1) /* reset divider stages for */
+ /* seconds or smaller units */
+#define RP5C01_RESET_ALARM (1 << 0) /* reset all alarm registers */
+
+
+struct rp5c01_priv {
+ u32 __iomem *regs;
+ struct rtc_device *rtc;
+};
+
+static inline unsigned int rp5c01_read(struct rp5c01_priv *priv,
+ unsigned int reg)
+{
+ return __raw_readl(&priv->regs[reg]) & 0xf;
+}
+
+static inline void rp5c01_write(struct rp5c01_priv *priv, unsigned int val,
+ unsigned int reg)
+{
+ return __raw_writel(val, &priv->regs[reg]);
+}
+
+static void rp5c01_lock(struct rp5c01_priv *priv)
+{
+ rp5c01_write(priv, RP5C01_MODE_MODE00, RP5C01_MODE);
+}
+
+static void rp5c01_unlock(struct rp5c01_priv *priv)
+{
+ rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_MODE01,
+ RP5C01_MODE);
+}
+
+static int rp5c01_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct rp5c01_priv *priv = dev_get_drvdata(dev);
+
+ rp5c01_lock(priv);
+
+ tm->tm_sec = rp5c01_read(priv, RP5C01_10_SECOND) * 10 +
+ rp5c01_read(priv, RP5C01_1_SECOND);
+ tm->tm_min = rp5c01_read(priv, RP5C01_10_MINUTE) * 10 +
+ rp5c01_read(priv, RP5C01_1_MINUTE);
+ tm->tm_hour = rp5c01_read(priv, RP5C01_10_HOUR) * 10 +
+ rp5c01_read(priv, RP5C01_1_HOUR);
+ tm->tm_mday = rp5c01_read(priv, RP5C01_10_DAY) * 10 +
+ rp5c01_read(priv, RP5C01_1_DAY);
+ tm->tm_wday = rp5c01_read(priv, RP5C01_DAY_OF_WEEK);
+ tm->tm_mon = rp5c01_read(priv, RP5C01_10_MONTH) * 10 +
+ rp5c01_read(priv, RP5C01_1_MONTH) - 1;
+ tm->tm_year = rp5c01_read(priv, RP5C01_10_YEAR) * 10 +
+ rp5c01_read(priv, RP5C01_1_YEAR);
+ if (tm->tm_year <= 69)
+ tm->tm_year += 100;
+
+ rp5c01_unlock(priv);
+
+ return rtc_valid_tm(tm);
+}
+
+static int rp5c01_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct rp5c01_priv *priv = dev_get_drvdata(dev);
+
+ rp5c01_lock(priv);
+
+ rp5c01_write(priv, tm->tm_sec / 10, RP5C01_10_SECOND);
+ rp5c01_write(priv, tm->tm_sec % 10, RP5C01_1_SECOND);
+ rp5c01_write(priv, tm->tm_min / 10, RP5C01_10_MINUTE);
+ rp5c01_write(priv, tm->tm_min % 10, RP5C01_1_MINUTE);
+ rp5c01_write(priv, tm->tm_hour / 10, RP5C01_10_HOUR);
+ rp5c01_write(priv, tm->tm_hour % 10, RP5C01_1_HOUR);
+ rp5c01_write(priv, tm->tm_mday / 10, RP5C01_10_DAY);
+ rp5c01_write(priv, tm->tm_mday % 10, RP5C01_1_DAY);
+ if (tm->tm_wday != -1)
+ rp5c01_write(priv, tm->tm_wday, RP5C01_DAY_OF_WEEK);
+ rp5c01_write(priv, (tm->tm_mon + 1) / 10, RP5C01_10_MONTH);
+ rp5c01_write(priv, (tm->tm_mon + 1) % 10, RP5C01_1_MONTH);
+ if (tm->tm_year >= 100)
+ tm->tm_year -= 100;
+ rp5c01_write(priv, tm->tm_year / 10, RP5C01_10_YEAR);
+ rp5c01_write(priv, tm->tm_year % 10, RP5C01_1_YEAR);
+
+ rp5c01_unlock(priv);
+ return 0;
+}
+
+static const struct rtc_class_ops rp5c01_rtc_ops = {
+ .read_time = rp5c01_read_time,
+ .set_time = rp5c01_set_time,
+};
+
+static int __init rp5c01_rtc_probe(struct platform_device *dev)
+{
+ struct resource *res;
+ struct rp5c01_priv *priv;
+ struct rtc_device *rtc;
+ int error;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->regs = ioremap(res->start, resource_size(res));
+ if (!priv->regs) {
+ error = -ENOMEM;
+ goto out_free_priv;
+ }
+
+ rtc = rtc_device_register("rtc-rp5c01", &dev->dev, &rp5c01_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc)) {
+ error = PTR_ERR(rtc);
+ goto out_unmap;
+ }
+
+ priv->rtc = rtc;
+ platform_set_drvdata(dev, priv);
+ return 0;
+
+out_unmap:
+ iounmap(priv->regs);
+out_free_priv:
+ kfree(priv);
+ return error;
+}
+
+static int __exit rp5c01_rtc_remove(struct platform_device *dev)
+{
+ struct rp5c01_priv *priv = platform_get_drvdata(dev);
+
+ rtc_device_unregister(priv->rtc);
+ iounmap(priv->regs);
+ kfree(priv);
+ return 0;
+}
+
+static struct platform_driver rp5c01_rtc_driver = {
+ .driver = {
+ .name = "rtc-rp5c01",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(rp5c01_rtc_remove),
+};
+
+static int __init rp5c01_rtc_init(void)
+{
+ return platform_driver_probe(&rp5c01_rtc_driver, rp5c01_rtc_probe);
+}
+
+static void __exit rp5c01_rtc_fini(void)
+{
+ platform_driver_unregister(&rp5c01_rtc_driver);
+}
+
+module_init(rp5c01_rtc_init);
+module_exit(rp5c01_rtc_fini);
+
+MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Ricoh RP5C01 RTC driver");
+MODULE_ALIAS("platform:rtc-rp5c01");
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c
index a6341e4f9a0f..9c8c70c497dc 100644
--- a/drivers/rtc/rtc-twl4030.c
+++ b/drivers/rtc/rtc-twl4030.c
@@ -495,9 +495,7 @@ static int twl4030_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
irqstat = rtc_irq_bits;
- /* REVISIT alarm may need to wake us from sleep */
- mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M |
- BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+ mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
return 0;
}
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index d1815272c435..e64f62d5e0fc 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -603,7 +603,7 @@ static void dasd_profile_end(struct dasd_block *block,
if (dasd_profile_level != DASD_PROFILE_ON)
return;
- sectors = req->nr_sectors;
+ sectors = blk_rq_sectors(req);
if (!cqr->buildclk || !cqr->startclk ||
!cqr->stopclk || !cqr->endclk ||
!sectors)
@@ -1614,15 +1614,6 @@ void dasd_block_clear_timer(struct dasd_block *block)
}
/*
- * posts the buffer_cache about a finalized request
- */
-static inline void dasd_end_request(struct request *req, int error)
-{
- if (__blk_end_request(req, error, blk_rq_bytes(req)))
- BUG();
-}
-
-/*
* Process finished error recovery ccw.
*/
static inline void __dasd_block_process_erp(struct dasd_block *block,
@@ -1665,18 +1656,14 @@ static void __dasd_process_request_queue(struct dasd_block *block)
if (basedev->state < DASD_STATE_READY)
return;
/* Now we try to fetch requests from the request queue */
- while (!blk_queue_plugged(queue) &&
- elv_next_request(queue)) {
-
- req = elv_next_request(queue);
-
+ while (!blk_queue_plugged(queue) && (req = blk_peek_request(queue))) {
if (basedev->features & DASD_FEATURE_READONLY &&
rq_data_dir(req) == WRITE) {
DBF_DEV_EVENT(DBF_ERR, basedev,
"Rejecting write request %p",
req);
- blkdev_dequeue_request(req);
- dasd_end_request(req, -EIO);
+ blk_start_request(req);
+ __blk_end_request_all(req, -EIO);
continue;
}
cqr = basedev->discipline->build_cp(basedev, block, req);
@@ -1704,8 +1691,8 @@ static void __dasd_process_request_queue(struct dasd_block *block)
"CCW creation failed (rc=%ld) "
"on request %p",
PTR_ERR(cqr), req);
- blkdev_dequeue_request(req);
- dasd_end_request(req, -EIO);
+ blk_start_request(req);
+ __blk_end_request_all(req, -EIO);
continue;
}
/*
@@ -1714,7 +1701,7 @@ static void __dasd_process_request_queue(struct dasd_block *block)
*/
cqr->callback_data = (void *) req;
cqr->status = DASD_CQR_FILLED;
- blkdev_dequeue_request(req);
+ blk_start_request(req);
list_add_tail(&cqr->blocklist, &block->ccw_queue);
dasd_profile_start(block, cqr, req);
}
@@ -1731,7 +1718,7 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr)
status = cqr->block->base->discipline->free_cp(cqr, req);
if (status <= 0)
error = status ? status : -EIO;
- dasd_end_request(req, error);
+ __blk_end_request_all(req, error);
}
/*
@@ -2038,10 +2025,8 @@ static void dasd_flush_request_queue(struct dasd_block *block)
return;
spin_lock_irq(&block->request_queue_lock);
- while ((req = elv_next_request(block->request_queue))) {
- blkdev_dequeue_request(req);
- dasd_end_request(req, -EIO);
- }
+ while ((req = blk_fetch_request(block->request_queue)))
+ __blk_end_request_all(req, -EIO);
spin_unlock_irq(&block->request_queue_lock);
}
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index b9a7f7733446..2efaddfae560 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -505,8 +505,9 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev,
return ERR_PTR(-EINVAL);
blksize = block->bp_block;
/* Calculate record id of first and last block. */
- first_rec = req->sector >> block->s2b_shift;
- last_rec = (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
+ first_rec = blk_rq_pos(req) >> block->s2b_shift;
+ last_rec =
+ (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;
/* Check struct bio and count the number of blocks for the request. */
count = 0;
rq_for_each_segment(bv, req, iter) {
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index cb52da033f06..a41c94053e64 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2354,10 +2354,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
blksize = block->bp_block;
blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
/* Calculate record id of first and last block. */
- first_rec = first_trk = req->sector >> block->s2b_shift;
+ first_rec = first_trk = blk_rq_pos(req) >> block->s2b_shift;
first_offs = sector_div(first_trk, blk_per_trk);
last_rec = last_trk =
- (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
+ (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;
last_offs = sector_div(last_trk, blk_per_trk);
cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
@@ -2420,7 +2420,7 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
private = (struct dasd_eckd_private *) cqr->block->base->private;
blksize = cqr->block->bp_block;
blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
- recid = req->sector >> cqr->block->s2b_shift;
+ recid = blk_rq_pos(req) >> cqr->block->s2b_shift;
ccw = cqr->cpaddr;
/* Skip over define extent & locate record. */
ccw++;
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index a3eb6fd14673..8912358daa2f 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -270,8 +270,9 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
return ERR_PTR(-EINVAL);
blksize = block->bp_block;
/* Calculate record id of first and last block. */
- first_rec = req->sector >> block->s2b_shift;
- last_rec = (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
+ first_rec = blk_rq_pos(req) >> block->s2b_shift;
+ last_rec =
+ (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;
/* Check struct bio and count the number of blocks for the request. */
count = 0;
cidaw = 0;
@@ -309,7 +310,7 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
ccw = cqr->cpaddr;
/* First ccw is define extent. */
define_extent(ccw++, cqr->data, rq_data_dir(req),
- block->bp_block, req->sector, req->nr_sectors);
+ block->bp_block, blk_rq_pos(req), blk_rq_sectors(req));
/* Build locate_record + read/write ccws. */
idaws = (unsigned long *) (cqr->data + sizeof(struct DE_fba_data));
LO_data = (struct LO_fba_data *) (idaws + cidaw);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 5f8e8ef43dd3..2d00a383a475 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -1134,7 +1134,7 @@ tape_34xx_bread(struct tape_device *device, struct request *req)
/* Setup ccws. */
request->op = TO_BLOCK;
start_block = (struct tape_34xx_block_id *) request->cpdata;
- start_block->block = req->sector >> TAPEBLOCK_HSEC_S2B;
+ start_block->block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B;
DBF_EVENT(6, "start_block = %i\n", start_block->block);
ccw = request->cpaddr;
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index 823b05bd0dd7..c453b2f3e9f4 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -633,7 +633,7 @@ tape_3590_bread(struct tape_device *device, struct request *req)
struct req_iterator iter;
DBF_EVENT(6, "xBREDid:");
- start_block = req->sector >> TAPEBLOCK_HSEC_S2B;
+ start_block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B;
DBF_EVENT(6, "start_block = %i\n", start_block);
rq_for_each_segment(bv, req, iter)
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index f32e89e7c4f2..1e7967675980 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -74,13 +74,6 @@ tapeblock_trigger_requeue(struct tape_device *device)
* Post finished request.
*/
static void
-tapeblock_end_request(struct request *req, int error)
-{
- if (blk_end_request(req, error, blk_rq_bytes(req)))
- BUG();
-}
-
-static void
__tapeblock_end_request(struct tape_request *ccw_req, void *data)
{
struct tape_device *device;
@@ -90,17 +83,17 @@ __tapeblock_end_request(struct tape_request *ccw_req, void *data)
device = ccw_req->device;
req = (struct request *) data;
- tapeblock_end_request(req, (ccw_req->rc == 0) ? 0 : -EIO);
+ blk_end_request_all(req, (ccw_req->rc == 0) ? 0 : -EIO);
if (ccw_req->rc == 0)
/* Update position. */
device->blk_data.block_position =
- (req->sector + req->nr_sectors) >> TAPEBLOCK_HSEC_S2B;
+ (blk_rq_pos(req) + blk_rq_sectors(req)) >> TAPEBLOCK_HSEC_S2B;
else
/* We lost the position information due to an error. */
device->blk_data.block_position = -1;
device->discipline->free_bread(ccw_req);
if (!list_empty(&device->req_queue) ||
- elv_next_request(device->blk_data.request_queue))
+ blk_peek_request(device->blk_data.request_queue))
tapeblock_trigger_requeue(device);
}
@@ -118,7 +111,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req)
ccw_req = device->discipline->bread(device, req);
if (IS_ERR(ccw_req)) {
DBF_EVENT(1, "TBLOCK: bread failed\n");
- tapeblock_end_request(req, -EIO);
+ blk_end_request_all(req, -EIO);
return PTR_ERR(ccw_req);
}
ccw_req->callback = __tapeblock_end_request;
@@ -131,7 +124,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req)
* Start/enqueueing failed. No retries in
* this case.
*/
- tapeblock_end_request(req, -EIO);
+ blk_end_request_all(req, -EIO);
device->discipline->free_bread(ccw_req);
}
@@ -169,19 +162,16 @@ tapeblock_requeue(struct work_struct *work) {
spin_lock_irq(&device->blk_data.request_queue_lock);
while (
!blk_queue_plugged(queue) &&
- elv_next_request(queue) &&
+ (req = blk_fetch_request(queue)) &&
nr_queued < TAPEBLOCK_MIN_REQUEUE
) {
- req = elv_next_request(queue);
if (rq_data_dir(req) == WRITE) {
DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
- blkdev_dequeue_request(req);
spin_unlock_irq(&device->blk_data.request_queue_lock);
- tapeblock_end_request(req, -EIO);
+ blk_end_request_all(req, -EIO);
spin_lock_irq(&device->blk_data.request_queue_lock);
continue;
}
- blkdev_dequeue_request(req);
nr_queued++;
spin_unlock_irq(&device->blk_data.request_queue_lock);
rc = tapeblock_start_request(device, req);
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 2aebb9823044..9889f188c7c5 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -28,7 +28,7 @@
#include <asm/chpid.h>
#include <asm/airq.h>
#include <asm/isc.h>
-#include <asm/cpu.h>
+#include <asm/cputime.h>
#include <asm/fcx.h>
#include <asm/nmi.h>
#include <asm/crw.h>
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 151754d54745..bf0a24af39a0 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -114,7 +114,7 @@ int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
struct subchannel *sch;
int ret;
- if (!cdev)
+ if (!cdev || !cdev->dev.parent)
return -ENODEV;
if (cdev->private->state == DEV_STATE_NOT_OPER)
return -ENODEV;
@@ -122,8 +122,6 @@ int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
cdev->private->state != DEV_STATE_W4SENSE)
return -EINVAL;
sch = to_subchannel(cdev->dev.parent);
- if (!sch)
- return -ENODEV;
ret = cio_clear(sch);
if (ret == 0)
cdev->private->intparm = intparm;
@@ -161,11 +159,9 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
struct subchannel *sch;
int ret;
- if (!cdev)
+ if (!cdev || !cdev->dev.parent)
return -ENODEV;
sch = to_subchannel(cdev->dev.parent);
- if (!sch)
- return -ENODEV;
if (cdev->private->state == DEV_STATE_NOT_OPER)
return -ENODEV;
if (cdev->private->state == DEV_STATE_VERIFY ||
@@ -339,7 +335,7 @@ int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
struct subchannel *sch;
int ret;
- if (!cdev)
+ if (!cdev || !cdev->dev.parent)
return -ENODEV;
if (cdev->private->state == DEV_STATE_NOT_OPER)
return -ENODEV;
@@ -347,8 +343,6 @@ int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
cdev->private->state != DEV_STATE_W4SENSE)
return -EINVAL;
sch = to_subchannel(cdev->dev.parent);
- if (!sch)
- return -ENODEV;
ret = cio_halt(sch);
if (ret == 0)
cdev->private->intparm = intparm;
@@ -372,11 +366,9 @@ int ccw_device_resume(struct ccw_device *cdev)
{
struct subchannel *sch;
- if (!cdev)
+ if (!cdev || !cdev->dev.parent)
return -ENODEV;
sch = to_subchannel(cdev->dev.parent);
- if (!sch)
- return -ENODEV;
if (cdev->private->state == DEV_STATE_NOT_OPER)
return -ENODEV;
if (cdev->private->state != DEV_STATE_ONLINE ||
@@ -471,11 +463,11 @@ __u8 ccw_device_get_path_mask(struct ccw_device *cdev)
{
struct subchannel *sch;
- sch = to_subchannel(cdev->dev.parent);
- if (!sch)
+ if (!cdev->dev.parent)
return 0;
- else
- return sch->lpm;
+
+ sch = to_subchannel(cdev->dev.parent);
+ return sch->lpm;
}
/*
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index accd957454e7..ba4facc37011 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -881,42 +881,26 @@ no_handler:
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
}
-static int qdio_establish_check_errors(struct ccw_device *cdev, int cstat,
- int dstat)
+static void qdio_establish_handle_irq(struct ccw_device *cdev, int cstat,
+ int dstat)
{
struct qdio_irq *irq_ptr = cdev->private->qdio_data;
- if (cstat || (dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
- DBF_ERROR("EQ:ck con");
- goto error;
- }
+ DBF_DEV_EVENT(DBF_INFO, irq_ptr, "qest irq");
- if (!(dstat & DEV_STAT_DEV_END)) {
- DBF_ERROR("EQ:no dev");
+ if (cstat)
goto error;
- }
-
- if (dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) {
- DBF_ERROR("EQ: bad io");
+ if (dstat & ~(DEV_STAT_DEV_END | DEV_STAT_CHN_END))
goto error;
- }
- return 0;
+ if (!(dstat & DEV_STAT_DEV_END))
+ goto error;
+ qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ESTABLISHED);
+ return;
+
error:
DBF_ERROR("%4x EQ:error", irq_ptr->schid.sch_no);
DBF_ERROR("ds: %2x cs:%2x", dstat, cstat);
-
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
- return 1;
-}
-
-static void qdio_establish_handle_irq(struct ccw_device *cdev, int cstat,
- int dstat)
-{
- struct qdio_irq *irq_ptr = cdev->private->qdio_data;
-
- DBF_DEV_EVENT(DBF_INFO, irq_ptr, "qest irq");
- if (!qdio_establish_check_errors(cdev, cstat, dstat))
- qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ESTABLISHED);
}
/* qdio interrupt handler */
@@ -946,7 +930,6 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
}
}
qdio_irq_check_sense(irq_ptr, irb);
-
cstat = irb->scsw.cmd.cstat;
dstat = irb->scsw.cmd.dstat;
@@ -954,22 +937,19 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
case QDIO_IRQ_STATE_INACTIVE:
qdio_establish_handle_irq(cdev, cstat, dstat);
break;
-
case QDIO_IRQ_STATE_CLEANUP:
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
break;
-
case QDIO_IRQ_STATE_ESTABLISHED:
case QDIO_IRQ_STATE_ACTIVE:
if (cstat & SCHN_STAT_PCI) {
qdio_int_handler_pci(irq_ptr);
return;
}
- if ((cstat & ~SCHN_STAT_PCI) || dstat) {
+ if (cstat || dstat)
qdio_handle_activate_check(cdev, intparm, cstat,
dstat);
- break;
- }
+ break;
default:
WARN_ON(1);
}
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index a85ad05e8548..6d4651684688 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -186,31 +186,31 @@ static void jsfd_do_request(struct request_queue *q)
{
struct request *req;
- while ((req = elv_next_request(q)) != NULL) {
+ req = blk_fetch_request(q);
+ while (req) {
struct jsfd_part *jdp = req->rq_disk->private_data;
- unsigned long offset = req->sector << 9;
- size_t len = req->current_nr_sectors << 9;
+ unsigned long offset = blk_rq_pos(req) << 9;
+ size_t len = blk_rq_cur_bytes(req);
+ int err = -EIO;
- if ((offset + len) > jdp->dsize) {
- end_request(req, 0);
- continue;
- }
+ if ((offset + len) > jdp->dsize)
+ goto end;
if (rq_data_dir(req) != READ) {
printk(KERN_ERR "jsfd: write\n");
- end_request(req, 0);
- continue;
+ goto end;
}
if ((jdp->dbase & 0xff000000) != 0x20000000) {
printk(KERN_ERR "jsfd: bad base %x\n", (int)jdp->dbase);
- end_request(req, 0);
- continue;
+ goto end;
}
jsfd_read(req->buffer, jdp->dbase + offset, len);
-
- end_request(req, 1);
+ err = 0;
+ end:
+ if (!__blk_end_request_cur(req, err))
+ req = blk_fetch_request(q);
}
}
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index be5099dd94b5..c7076ce25e21 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -1825,7 +1825,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
if (linked_comm && SCpnt->device->queue_depth > 2
&& TLDEV(SCpnt->device->type)) {
ha->cp_stat[i] = READY;
- flush_dev(SCpnt->device, SCpnt->request->sector, ha, 0);
+ flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 0);
return 0;
}
@@ -2144,13 +2144,13 @@ static int reorder(struct hostdata *ha, unsigned long cursec,
if (!cpp->din)
input_only = 0;
- if (SCpnt->request->sector < minsec)
- minsec = SCpnt->request->sector;
- if (SCpnt->request->sector > maxsec)
- maxsec = SCpnt->request->sector;
+ if (blk_rq_pos(SCpnt->request) < minsec)
+ minsec = blk_rq_pos(SCpnt->request);
+ if (blk_rq_pos(SCpnt->request) > maxsec)
+ maxsec = blk_rq_pos(SCpnt->request);
- sl[n] = SCpnt->request->sector;
- ioseek += SCpnt->request->nr_sectors;
+ sl[n] = blk_rq_pos(SCpnt->request);
+ ioseek += blk_rq_sectors(SCpnt->request);
if (!n)
continue;
@@ -2190,7 +2190,7 @@ static int reorder(struct hostdata *ha, unsigned long cursec,
k = il[n];
cpp = &ha->cp[k];
SCpnt = cpp->SCpnt;
- ll[n] = SCpnt->request->nr_sectors;
+ ll[n] = blk_rq_sectors(SCpnt->request);
pl[n] = SCpnt->serial_number;
if (!n)
@@ -2236,12 +2236,12 @@ static int reorder(struct hostdata *ha, unsigned long cursec,
cpp = &ha->cp[k];
SCpnt = cpp->SCpnt;
scmd_printk(KERN_INFO, SCpnt,
- "%s pid %ld mb %d fc %d nr %d sec %ld ns %ld"
+ "%s pid %ld mb %d fc %d nr %d sec %ld ns %u"
" cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
(ihdlr ? "ihdlr" : "qcomm"),
SCpnt->serial_number, k, flushcount,
- n_ready, SCpnt->request->sector,
- SCpnt->request->nr_sectors, cursec, YESNO(s),
+ n_ready, blk_rq_pos(SCpnt->request),
+ blk_rq_sectors(SCpnt->request), cursec, YESNO(s),
YESNO(r), YESNO(rev), YESNO(input_only),
YESNO(overlap), cpp->din);
}
@@ -2408,7 +2408,7 @@ static irqreturn_t ihdlr(struct Scsi_Host *shost)
if (linked_comm && SCpnt->device->queue_depth > 2
&& TLDEV(SCpnt->device->type))
- flush_dev(SCpnt->device, SCpnt->request->sector, ha, 1);
+ flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 1);
tstatus = status_byte(spp->target_status);
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 3da02e436788..531af9ed7199 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -1927,21 +1927,17 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
/* do we need to support multiple segments? */
if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
printk("%s: multiple segments req %u %u, rsp %u %u\n",
- __func__, req->bio->bi_vcnt, req->data_len,
- rsp->bio->bi_vcnt, rsp->data_len);
+ __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
+ rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
return -EINVAL;
}
- ret = smp_execute_task(dev, bio_data(req->bio), req->data_len,
- bio_data(rsp->bio), rsp->data_len);
+ ret = smp_execute_task(dev, bio_data(req->bio), blk_rq_bytes(req),
+ bio_data(rsp->bio), blk_rq_bytes(rsp));
if (ret > 0) {
/* positive number is the untransferred residual */
- rsp->data_len = ret;
- req->data_len = 0;
+ rsp->resid_len = ret;
ret = 0;
- } else if (ret == 0) {
- rsp->data_len = 0;
- req->data_len = 0;
}
return ret;
diff --git a/drivers/scsi/libsas/sas_host_smp.c b/drivers/scsi/libsas/sas_host_smp.c
index d110a366c48a..be9a951b977d 100644
--- a/drivers/scsi/libsas/sas_host_smp.c
+++ b/drivers/scsi/libsas/sas_host_smp.c
@@ -134,24 +134,24 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
{
u8 *req_data = NULL, *resp_data = NULL, *buf;
struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
- int error = -EINVAL, resp_data_len = rsp->data_len;
+ int error = -EINVAL;
/* eight is the minimum size for request and response frames */
- if (req->data_len < 8 || rsp->data_len < 8)
+ if (blk_rq_bytes(req) < 8 || blk_rq_bytes(rsp) < 8)
goto out;
- if (bio_offset(req->bio) + req->data_len > PAGE_SIZE ||
- bio_offset(rsp->bio) + rsp->data_len > PAGE_SIZE) {
+ if (bio_offset(req->bio) + blk_rq_bytes(req) > PAGE_SIZE ||
+ bio_offset(rsp->bio) + blk_rq_bytes(rsp) > PAGE_SIZE) {
shost_printk(KERN_ERR, shost,
"SMP request/response frame crosses page boundary");
goto out;
}
- req_data = kzalloc(req->data_len, GFP_KERNEL);
+ req_data = kzalloc(blk_rq_bytes(req), GFP_KERNEL);
/* make sure frame can always be built ... we copy
* back only the requested length */
- resp_data = kzalloc(max(rsp->data_len, 128U), GFP_KERNEL);
+ resp_data = kzalloc(max(blk_rq_bytes(rsp), 128U), GFP_KERNEL);
if (!req_data || !resp_data) {
error = -ENOMEM;
@@ -160,7 +160,7 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
local_irq_disable();
buf = kmap_atomic(bio_page(req->bio), KM_USER0) + bio_offset(req->bio);
- memcpy(req_data, buf, req->data_len);
+ memcpy(req_data, buf, blk_rq_bytes(req));
kunmap_atomic(buf - bio_offset(req->bio), KM_USER0);
local_irq_enable();
@@ -176,17 +176,20 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
resp_data[1] = req_data[1];
resp_data[2] = SMP_RESP_FUNC_UNK;
+ req->resid_len = blk_rq_bytes(req);
+ rsp->resid_len = blk_rq_bytes(rsp);
+
switch (req_data[1]) {
case SMP_REPORT_GENERAL:
- req->data_len -= 8;
- resp_data_len -= 32;
+ req->resid_len -= 8;
+ rsp->resid_len -= 32;
resp_data[2] = SMP_RESP_FUNC_ACC;
resp_data[9] = sas_ha->num_phys;
break;
case SMP_REPORT_MANUF_INFO:
- req->data_len -= 8;
- resp_data_len -= 64;
+ req->resid_len -= 8;
+ rsp->resid_len -= 64;
resp_data[2] = SMP_RESP_FUNC_ACC;
memcpy(resp_data + 12, shost->hostt->name,
SAS_EXPANDER_VENDOR_ID_LEN);
@@ -199,13 +202,13 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
break;
case SMP_DISCOVER:
- req->data_len -= 16;
- if ((int)req->data_len < 0) {
- req->data_len = 0;
+ req->resid_len -= 16;
+ if ((int)req->resid_len < 0) {
+ req->resid_len = 0;
error = -EINVAL;
goto out;
}
- resp_data_len -= 56;
+ rsp->resid_len -= 56;
sas_host_smp_discover(sas_ha, resp_data, req_data[9]);
break;
@@ -215,13 +218,13 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
break;
case SMP_REPORT_PHY_SATA:
- req->data_len -= 16;
- if ((int)req->data_len < 0) {
- req->data_len = 0;
+ req->resid_len -= 16;
+ if ((int)req->resid_len < 0) {
+ req->resid_len = 0;
error = -EINVAL;
goto out;
}
- resp_data_len -= 60;
+ rsp->resid_len -= 60;
sas_report_phy_sata(sas_ha, resp_data, req_data[9]);
break;
@@ -238,13 +241,13 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
break;
case SMP_PHY_CONTROL:
- req->data_len -= 44;
- if ((int)req->data_len < 0) {
- req->data_len = 0;
+ req->resid_len -= 44;
+ if ((int)req->resid_len < 0) {
+ req->resid_len = 0;
error = -EINVAL;
goto out;
}
- resp_data_len -= 8;
+ rsp->resid_len -= 8;
sas_phy_control(sas_ha, req_data[9], req_data[10],
req_data[32] >> 4, req_data[33] >> 4,
resp_data);
@@ -261,11 +264,10 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
local_irq_disable();
buf = kmap_atomic(bio_page(rsp->bio), KM_USER0) + bio_offset(rsp->bio);
- memcpy(buf, resp_data, rsp->data_len);
+ memcpy(buf, resp_data, blk_rq_bytes(rsp));
flush_kernel_dcache_page(bio_page(rsp->bio));
kunmap_atomic(buf - bio_offset(rsp->bio), KM_USER0);
local_irq_enable();
- rsp->data_len = resp_data_len;
out:
kfree(req_data);
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 6ce8880fa9aa..679adfff0bf8 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1312,10 +1312,10 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,
uint32_t bgstat = bgf->bgstat;
uint64_t failing_sector = 0;
- printk(KERN_ERR "BG ERROR in cmd 0x%x lba 0x%llx blk cnt 0x%lx "
+ printk(KERN_ERR "BG ERROR in cmd 0x%x lba 0x%llx blk cnt 0x%x "
"bgstat=0x%x bghm=0x%x\n",
cmd->cmnd[0], (unsigned long long)scsi_get_lba(cmd),
- cmd->request->nr_sectors, bgstat, bghm);
+ blk_rq_sectors(cmd->request), bgstat, bghm);
spin_lock(&_dump_buf_lock);
if (!_dump_buf_done) {
@@ -2378,15 +2378,15 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
if (cmnd->cmnd[0] == READ_10)
lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
"9035 BLKGRD: READ @ sector %llu, "
- "count %lu\n",
- (unsigned long long)scsi_get_lba(cmnd),
- cmnd->request->nr_sectors);
+ "count %u\n",
+ (unsigned long long)scsi_get_lba(cmnd),
+ blk_rq_sectors(cmnd->request));
else if (cmnd->cmnd[0] == WRITE_10)
lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
"9036 BLKGRD: WRITE @ sector %llu, "
- "count %lu cmd=%p\n",
+ "count %u cmd=%p\n",
(unsigned long long)scsi_get_lba(cmnd),
- cmnd->request->nr_sectors,
+ blk_rq_sectors(cmnd->request),
cmnd);
err = lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd);
@@ -2406,15 +2406,15 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
if (cmnd->cmnd[0] == READ_10)
lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
"9040 dbg: READ @ sector %llu, "
- "count %lu\n",
+ "count %u\n",
(unsigned long long)scsi_get_lba(cmnd),
- cmnd->request->nr_sectors);
+ blk_rq_sectors(cmnd->request));
else if (cmnd->cmnd[0] == WRITE_10)
lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
"9041 dbg: WRITE @ sector %llu, "
- "count %lu cmd=%p\n",
+ "count %u cmd=%p\n",
(unsigned long long)scsi_get_lba(cmnd),
- cmnd->request->nr_sectors, cmnd);
+ blk_rq_sectors(cmnd->request), cmnd);
else
lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
"9042 dbg: parser not implemented\n");
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index e03dc0b1e1a0..af95a449930e 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -1041,7 +1041,7 @@ transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
printk(MPT2SAS_ERR_FMT "%s: multiple segments req %u %u, "
"rsp %u %u\n", ioc->name, __func__, req->bio->bi_vcnt,
- req->data_len, rsp->bio->bi_vcnt, rsp->data_len);
+ blk_rq_bytes(req), rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
return -EINVAL;
}
@@ -1104,7 +1104,7 @@ transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
*((u64 *)&mpi_request->SASAddress) = (rphy) ?
cpu_to_le64(rphy->identify.sas_address) :
cpu_to_le64(ioc->sas_hba.sas_address);
- mpi_request->RequestDataLength = cpu_to_le16(req->data_len - 4);
+ mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
psge = &mpi_request->SGL;
/* WRITE sgel first */
@@ -1112,13 +1112,13 @@ transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
- req->data_len, PCI_DMA_BIDIRECTIONAL);
+ blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
if (!dma_addr_out) {
mpt2sas_base_free_smid(ioc, le16_to_cpu(smid));
goto unmap;
}
- ioc->base_add_sg_single(psge, sgl_flags | (req->data_len - 4),
+ ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(req) - 4),
dma_addr_out);
/* incr sgel */
@@ -1129,14 +1129,14 @@ transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
MPI2_SGE_FLAGS_END_OF_LIST);
sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
- dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio),
- rsp->data_len, PCI_DMA_BIDIRECTIONAL);
+ dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio),
+ blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
if (!dma_addr_in) {
mpt2sas_base_free_smid(ioc, le16_to_cpu(smid));
goto unmap;
}
- ioc->base_add_sg_single(psge, sgl_flags | (rsp->data_len + 4),
+ ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(rsp) + 4),
dma_addr_in);
dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s - "
@@ -1170,9 +1170,8 @@ transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
req->sense_len = sizeof(*mpi_reply);
- req->data_len = 0;
- rsp->data_len -= mpi_reply->ResponseDataLength;
-
+ rsp->resid_len = blk_rq_bytes(rsp) -
+ mpi_reply->ResponseDataLength;
} else {
dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
"%s - no reply\n", ioc->name, __func__));
@@ -1188,10 +1187,10 @@ transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
unmap:
if (dma_addr_out)
- pci_unmap_single(ioc->pdev, dma_addr_out, req->data_len,
+ pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req),
PCI_DMA_BIDIRECTIONAL);
if (dma_addr_in)
- pci_unmap_single(ioc->pdev, dma_addr_in, rsp->data_len,
+ pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp),
PCI_DMA_BIDIRECTIONAL);
out:
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 1ce6b24abab2..0c9dfd390ec0 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -1372,7 +1372,7 @@ int osd_finalize_request(struct osd_request *or,
return ret;
}
OSD_DEBUG("out bytes=%llu (bytes_req=%u)\n",
- _LLU(or->out.total_bytes), or->out.req->data_len);
+ _LLU(or->out.total_bytes), blk_rq_bytes(or->out.req));
}
if (or->in.bio) {
ret = blk_rq_append_bio(or->request->q, or->in.req, or->in.bio);
@@ -1381,7 +1381,7 @@ int osd_finalize_request(struct osd_request *or,
return ret;
}
OSD_DEBUG("in bytes=%llu (bytes_req=%u)\n",
- _LLU(or->in.total_bytes), or->in.req->data_len);
+ _LLU(or->in.total_bytes), blk_rq_bytes(or->in.req));
}
or->out.pad_buff = sg_out_pad_buffer;
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index f644c9571eab..22b59e13ba83 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -173,26 +173,26 @@ static const struct file_operations osd_fops = {
.unlocked_ioctl = osd_uld_ioctl,
};
-struct osd_dev *osduld_path_lookup(const char *path)
+struct osd_dev *osduld_path_lookup(const char *name)
{
- struct nameidata nd;
+ struct path path;
struct inode *inode;
struct cdev *cdev;
struct osd_uld_device *uninitialized_var(oud);
int error;
- if (!path || !*path) {
+ if (!name || !*name) {
OSD_ERR("Mount with !path || !*path\n");
return ERR_PTR(-EINVAL);
}
- error = path_lookup(path, LOOKUP_FOLLOW, &nd);
+ error = kern_path(name, LOOKUP_FOLLOW, &path);
if (error) {
- OSD_ERR("path_lookup of %s faild=>%d\n", path, error);
+ OSD_ERR("path_lookup of %s failed=>%d\n", name, error);
return ERR_PTR(error);
}
- inode = nd.path.dentry->d_inode;
+ inode = path.dentry->d_inode;
error = -EINVAL; /* Not the right device e.g osd_uld_device */
if (!S_ISCHR(inode->i_mode)) {
OSD_DEBUG("!S_ISCHR()\n");
@@ -202,15 +202,15 @@ struct osd_dev *osduld_path_lookup(const char *path)
cdev = inode->i_cdev;
if (!cdev) {
OSD_ERR("Before mounting an OSD Based filesystem\n");
- OSD_ERR(" user-mode must open+close the %s device\n", path);
- OSD_ERR(" Example: bash: echo < %s\n", path);
+ OSD_ERR(" user-mode must open+close the %s device\n", name);
+ OSD_ERR(" Example: bash: echo < %s\n", name);
goto out;
}
/* The Magic wand. Is it our char-dev */
/* TODO: Support sg devices */
if (cdev->owner != THIS_MODULE) {
- OSD_ERR("Error mounting %s - is not an OSD device\n", path);
+ OSD_ERR("Error mounting %s - is not an OSD device\n", name);
goto out;
}
@@ -220,7 +220,7 @@ struct osd_dev *osduld_path_lookup(const char *path)
error = 0;
out:
- path_put(&nd.path);
+ path_put(&path);
return error ? ERR_PTR(error) : &oud->od;
}
EXPORT_SYMBOL(osduld_path_lookup);
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index b09993a06576..fc30f8e2f467 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -97,7 +97,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj,
return 0;
if (IS_NOCACHE_VPD_TYPE(ha))
- ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_nvram << 2,
+ ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2,
ha->nvram_size);
return memory_read_from_buffer(buf, count, &off, ha->nvram,
ha->nvram_size);
@@ -1088,6 +1088,33 @@ qla2x00_flash_block_size_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "0x%x\n", ha->fdt_block_size);
}
+static ssize_t
+qla2x00_vlan_id_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+
+ if (!IS_QLA81XX(vha->hw))
+ return snprintf(buf, PAGE_SIZE, "\n");
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", vha->fcoe_vlan_id);
+}
+
+static ssize_t
+qla2x00_vn_port_mac_address_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+
+ if (!IS_QLA81XX(vha->hw))
+ return snprintf(buf, PAGE_SIZE, "\n");
+
+ return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ vha->fcoe_vn_port_mac[5], vha->fcoe_vn_port_mac[4],
+ vha->fcoe_vn_port_mac[3], vha->fcoe_vn_port_mac[2],
+ vha->fcoe_vn_port_mac[1], vha->fcoe_vn_port_mac[0]);
+}
+
static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
@@ -1116,6 +1143,9 @@ static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL);
static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL);
static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show,
NULL);
+static DEVICE_ATTR(vlan_id, S_IRUGO, qla2x00_vlan_id_show, NULL);
+static DEVICE_ATTR(vn_port_mac_address, S_IRUGO,
+ qla2x00_vn_port_mac_address_show, NULL);
struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_driver_version,
@@ -1138,6 +1168,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_mpi_version,
&dev_attr_phy_version,
&dev_attr_flash_block_size,
+ &dev_attr_vlan_id,
+ &dev_attr_vn_port_mac_address,
NULL,
};
@@ -1437,11 +1469,12 @@ static int
qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
{
int ret = 0;
- int cnt = 0;
- uint8_t qos = QLA_DEFAULT_QUE_QOS;
+ uint8_t qos = 0;
scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
scsi_qla_host_t *vha = NULL;
struct qla_hw_data *ha = base_vha->hw;
+ uint16_t options = 0;
+ int cnt;
ret = qla24xx_vport_create_req_sanity_check(fc_vport);
if (ret) {
@@ -1497,23 +1530,35 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
qla24xx_vport_disable(fc_vport, disable);
- /* Create a queue pair for the vport */
- if (ha->mqenable) {
- if (ha->npiv_info) {
- for (; cnt < ha->nvram_npiv_size; cnt++) {
- if (ha->npiv_info[cnt].port_name ==
- vha->port_name &&
- ha->npiv_info[cnt].node_name ==
- vha->node_name) {
- qos = ha->npiv_info[cnt].q_qos;
- break;
- }
- }
+ ret = 0;
+ if (ha->cur_vport_count <= ha->flex_port_count || ql2xmultique_tag
+ || ha->max_req_queues == 1 || !ha->npiv_info)
+ goto vport_queue;
+ /* Create a request queue in QoS mode for the vport */
+ for (cnt = ha->flex_port_count; cnt < ha->nvram_npiv_size; cnt++) {
+ if (ha->npiv_info[cnt].port_name == vha->port_name &&
+ ha->npiv_info[cnt].node_name == vha->node_name) {
+ qos = ha->npiv_info[cnt].q_qos;
+ break;
}
- qla25xx_create_queues(vha, qos);
+ }
+ if (qos) {
+ ret = qla25xx_create_req_que(ha, options, vha->vp_idx, 0, 0,
+ qos);
+ if (!ret)
+ qla_printk(KERN_WARNING, ha,
+ "Can't create request queue for vp_idx:%d\n",
+ vha->vp_idx);
+ else
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "Request Que:%d created for vp_idx:%d\n",
+ ret, vha->vp_idx));
}
+vport_queue:
+ vha->req = ha->req_q_map[ret];
return 0;
+
vport_create_failed_2:
qla24xx_disable_vp(vha);
qla24xx_deallocate_vp_id(vha);
@@ -1554,8 +1599,8 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
vha->host_no, vha->vp_idx, vha));
}
- if (ha->mqenable) {
- if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS)
+ if (vha->req->id && !ql2xmultique_tag) {
+ if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS)
qla_printk(KERN_WARNING, ha,
"Queue delete failed.\n");
}
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 34760f8d4f17..68671a2b8b7f 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -351,7 +351,7 @@ static inline void *
qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
{
uint32_t cnt, que_idx;
- uint8_t req_cnt, rsp_cnt, que_cnt;
+ uint8_t que_cnt;
struct qla2xxx_mq_chain *mq = ptr;
struct device_reg_25xxmq __iomem *reg;
@@ -363,9 +363,8 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
mq->type = __constant_htonl(DUMP_CHAIN_MQ);
mq->chain_size = __constant_htonl(sizeof(struct qla2xxx_mq_chain));
- req_cnt = find_first_zero_bit(ha->req_qid_map, ha->max_queues);
- rsp_cnt = find_first_zero_bit(ha->rsp_qid_map, ha->max_queues);
- que_cnt = req_cnt > rsp_cnt ? req_cnt : rsp_cnt;
+ que_cnt = ha->max_req_queues > ha->max_rsp_queues ?
+ ha->max_req_queues : ha->max_rsp_queues;
mq->count = htonl(que_cnt);
for (cnt = 0; cnt < que_cnt; cnt++) {
reg = (struct device_reg_25xxmq *) ((void *)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 714ee67567e1..721bae94e437 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -93,6 +93,7 @@
#define LSD(x) ((uint32_t)((uint64_t)(x)))
#define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16))
+#define MAKE_HANDLE(x, y) ((uint32_t)((((uint32_t)(x)) << 16) | (uint32_t)(y)))
/*
* I/O register
@@ -179,6 +180,7 @@
#define REQUEST_ENTRY_CNT_24XX 2048 /* Number of request entries. */
#define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/
#define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/
+#define RESPONSE_ENTRY_CNT_MQ 128 /* Number of response entries.*/
struct req_que;
@@ -186,7 +188,6 @@ struct req_que;
* SCSI Request Block
*/
typedef struct srb {
- struct req_que *que;
struct fc_port *fcport;
struct scsi_cmnd *cmd; /* Linux SCSI command pkt */
@@ -2008,7 +2009,7 @@ typedef struct vport_params {
#define VP_RET_CODE_NOT_FOUND 6
struct qla_hw_data;
-
+struct rsp_que;
/*
* ISP operations
*/
@@ -2030,10 +2031,9 @@ struct isp_operations {
void (*enable_intrs) (struct qla_hw_data *);
void (*disable_intrs) (struct qla_hw_data *);
- int (*abort_command) (struct scsi_qla_host *, srb_t *,
- struct req_que *);
- int (*target_reset) (struct fc_port *, unsigned int);
- int (*lun_reset) (struct fc_port *, unsigned int);
+ int (*abort_command) (srb_t *);
+ int (*target_reset) (struct fc_port *, unsigned int, int);
+ int (*lun_reset) (struct fc_port *, unsigned int, int);
int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t,
uint8_t, uint8_t, uint16_t *, uint8_t);
int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t,
@@ -2079,7 +2079,6 @@ struct isp_operations {
#define QLA_PCI_MSIX_CONTROL 0xa2
struct scsi_qla_host;
-struct rsp_que;
struct qla_msix_entry {
int have_irq;
@@ -2140,7 +2139,6 @@ struct qla_statistics {
#define MBC_INITIALIZE_MULTIQ 0x1f
#define QLA_QUE_PAGE 0X1000
#define QLA_MQ_SIZE 32
-#define QLA_MAX_HOST_QUES 16
#define QLA_MAX_QUEUES 256
#define ISP_QUE_REG(ha, id) \
((ha->mqenable) ? \
@@ -2170,6 +2168,8 @@ struct rsp_que {
struct qla_hw_data *hw;
struct qla_msix_entry *msix;
struct req_que *req;
+ srb_t *status_srb; /* status continuation entry */
+ struct work_struct q_work;
};
/* Request queue data structure */
@@ -2222,6 +2222,7 @@ struct qla_hw_data {
uint32_t fce_enabled :1;
uint32_t fac_supported :1;
uint32_t chip_reset_done :1;
+ uint32_t port0 :1;
} flags;
/* This spinlock is used to protect "io transactions", you must
@@ -2246,7 +2247,8 @@ struct qla_hw_data {
struct rsp_que **rsp_q_map;
unsigned long req_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)];
unsigned long rsp_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)];
- uint16_t max_queues;
+ uint8_t max_req_queues;
+ uint8_t max_rsp_queues;
struct qla_npiv_entry *npiv_info;
uint16_t nvram_npiv_size;
@@ -2255,6 +2257,9 @@ struct qla_hw_data {
#define FLOGI_MID_SUPPORT BIT_10
#define FLOGI_VSAN_SUPPORT BIT_12
#define FLOGI_SP_SUPPORT BIT_13
+
+ uint8_t port_no; /* Physical port of adapter */
+
/* Timeout timers. */
uint8_t loop_down_abort_time; /* port down timer */
atomic_t loop_down_timer; /* loop down timer */
@@ -2532,10 +2537,12 @@ struct qla_hw_data {
uint16_t num_vsans; /* number of vsan created */
uint16_t max_npiv_vports; /* 63 or 125 per topoloty */
int cur_vport_count;
+ uint16_t flex_port_count;
struct qla_chip_state_84xx *cs84xx;
struct qla_statistics qla_stats;
struct isp_operations *isp_ops;
+ struct workqueue_struct *wq;
};
/*
@@ -2591,8 +2598,6 @@ typedef struct scsi_qla_host {
#define SWITCH_FOUND BIT_0
#define DFLG_NO_CABLE BIT_1
- srb_t *status_srb; /* Status continuation entry. */
-
/* ISP configuration data. */
uint16_t loop_id; /* Host adapter loop id */
@@ -2618,6 +2623,11 @@ typedef struct scsi_qla_host {
uint8_t node_name[WWN_SIZE];
uint8_t port_name[WWN_SIZE];
uint8_t fabric_node_name[WWN_SIZE];
+
+ uint16_t fcoe_vlan_id;
+ uint16_t fcoe_fcf_idx;
+ uint8_t fcoe_vn_port_mac[6];
+
uint32_t vp_abort_cnt;
struct fc_vport *fc_vport; /* holds fc_vport * for each vport */
@@ -2643,7 +2653,7 @@ typedef struct scsi_qla_host {
#define VP_ERR_FAB_LOGOUT 4
#define VP_ERR_ADAP_NORESOURCES 5
struct qla_hw_data *hw;
- int req_ques[QLA_MAX_HOST_QUES];
+ struct req_que *req;
} scsi_qla_host_t;
/*
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index 96ccb9642ba0..f389f3da0bab 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1711,7 +1711,7 @@ struct ex_init_cb_81xx {
#define FA_VPD0_ADDR_81 0xD0000
#define FA_VPD1_ADDR_81 0xD0400
#define FA_NVRAM0_ADDR_81 0xD0080
-#define FA_NVRAM1_ADDR_81 0xD0480
+#define FA_NVRAM1_ADDR_81 0xD0180
#define FA_FEATURE_ADDR_81 0xD4000
#define FA_FLASH_DESCR_ADDR_81 0xD8000
#define FA_FLASH_LAYOUT_ADDR_81 0xD8400
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 528913f6bed9..f17d525897a0 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -65,8 +65,11 @@ extern int ql2xfdmienable;
extern int ql2xallocfwdump;
extern int ql2xextended_error_logging;
extern int ql2xqfullrampup;
+extern int ql2xqfulltracking;
extern int ql2xiidmaenable;
extern int ql2xmaxqueues;
+extern int ql2xmultique_tag;
+extern int ql2xfwloadbin;
extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
@@ -165,13 +168,13 @@ extern int
qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t);
extern int
-qla2x00_abort_command(scsi_qla_host_t *, srb_t *, struct req_que *);
+qla2x00_abort_command(srb_t *);
extern int
-qla2x00_abort_target(struct fc_port *, unsigned int);
+qla2x00_abort_target(struct fc_port *, unsigned int, int);
extern int
-qla2x00_lun_reset(struct fc_port *, unsigned int);
+qla2x00_lun_reset(struct fc_port *, unsigned int, int);
extern int
qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
@@ -236,9 +239,11 @@ extern int
qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
dma_addr_t);
-extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *, struct req_que *);
-extern int qla24xx_abort_target(struct fc_port *, unsigned int);
-extern int qla24xx_lun_reset(struct fc_port *, unsigned int);
+extern int qla24xx_abort_command(srb_t *);
+extern int
+qla24xx_abort_target(struct fc_port *, unsigned int, int);
+extern int
+qla24xx_lun_reset(struct fc_port *, unsigned int, int);
extern int
qla2x00_system_error(scsi_qla_host_t *);
@@ -295,8 +300,8 @@ extern irqreturn_t qla2100_intr_handler(int, void *);
extern irqreturn_t qla2300_intr_handler(int, void *);
extern irqreturn_t qla24xx_intr_handler(int, void *);
extern void qla2x00_process_response_queue(struct rsp_que *);
-extern void qla24xx_process_response_queue(struct rsp_que *);
-
+extern void
+qla24xx_process_response_queue(struct scsi_qla_host *, struct rsp_que *);
extern int qla2x00_request_irqs(struct qla_hw_data *, struct rsp_que *);
extern void qla2x00_free_irqs(scsi_qla_host_t *);
@@ -401,19 +406,21 @@ extern int qla25xx_request_irq(struct rsp_que *);
extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *);
extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *);
extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t,
- uint16_t, uint8_t, uint8_t);
+ uint16_t, int, uint8_t);
extern int qla25xx_create_rsp_que(struct qla_hw_data *, uint16_t, uint8_t,
- uint16_t);
+ uint16_t, int);
extern int qla25xx_update_req_que(struct scsi_qla_host *, uint8_t, uint8_t);
extern void qla2x00_init_response_q_entries(struct rsp_que *);
extern int qla25xx_delete_req_que(struct scsi_qla_host *, struct req_que *);
extern int qla25xx_delete_rsp_que(struct scsi_qla_host *, struct rsp_que *);
extern int qla25xx_create_queues(struct scsi_qla_host *, uint8_t);
-extern int qla25xx_delete_queues(struct scsi_qla_host *, uint8_t);
+extern int qla25xx_delete_queues(struct scsi_qla_host *);
extern uint16_t qla24xx_rd_req_reg(struct qla_hw_data *, uint16_t);
extern uint16_t qla25xx_rd_req_reg(struct qla_hw_data *, uint16_t);
extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
+extern struct scsi_qla_host * qla25xx_get_host(struct rsp_que *);
+
#endif /* _QLA_GBL_H */
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 557f58d5bf88..3dbb9e73e80a 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -1107,7 +1107,7 @@ qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
return ret;
ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa,
- mb, BIT_1);
+ mb, BIT_1|BIT_0);
if (mb[0] != MBS_COMMAND_COMPLETE) {
DEBUG2_13(printk("%s(%ld): Failed MANAGEMENT_SERVER login: "
"loop_id=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x\n",
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index bd7dd84c0648..33e924810666 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -634,7 +634,7 @@ qla2x00_chip_diag(scsi_qla_host_t *vha)
goto chip_diag_failed;
DEBUG3(printk("scsi(%ld): Reset register cleared by chip reset\n",
- ha->host_no));
+ vha->host_no));
/* Reset RISC processor. */
WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
@@ -655,7 +655,7 @@ qla2x00_chip_diag(scsi_qla_host_t *vha)
goto chip_diag_failed;
/* Check product ID of chip */
- DEBUG3(printk("scsi(%ld): Checking product ID of chip\n", ha->host_no));
+ DEBUG3(printk("scsi(%ld): Checking product ID of chip\n", vha->host_no));
mb[1] = RD_MAILBOX_REG(ha, reg, 1);
mb[2] = RD_MAILBOX_REG(ha, reg, 2);
@@ -786,7 +786,6 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
sizeof(uint32_t);
if (ha->mqenable)
mq_size = sizeof(struct qla2xxx_mq_chain);
-
/* Allocate memory for Fibre Channel Event Buffer. */
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))
goto try_eft;
@@ -850,8 +849,7 @@ cont_alloc:
rsp_q_size = rsp->length * sizeof(response_t);
dump_size = offsetof(struct qla2xxx_fw_dump, isp);
- dump_size += fixed_size + mem_size + req_q_size + rsp_q_size +
- eft_size;
+ dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + eft_size;
ha->chain_offset = dump_size;
dump_size += mq_size + fce_size;
@@ -1013,12 +1011,14 @@ qla2x00_init_response_q_entries(struct rsp_que *rsp)
uint16_t cnt;
response_t *pkt;
+ rsp->ring_ptr = rsp->ring;
+ rsp->ring_index = 0;
+ rsp->status_srb = NULL;
pkt = rsp->ring_ptr;
for (cnt = 0; cnt < rsp->length; cnt++) {
pkt->signature = RESPONSE_PROCESSED;
pkt++;
}
-
}
/**
@@ -1176,7 +1176,7 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
if (ha->flags.msix_enabled) {
msix = &ha->msix_entries[1];
DEBUG2_17(printk(KERN_INFO
- "Reistering vector 0x%x for base que\n", msix->entry));
+ "Registering vector 0x%x for base que\n", msix->entry));
icb->msix = cpu_to_le16(msix->entry);
}
/* Use alternate PCI bus number */
@@ -1230,14 +1230,14 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Clear outstanding commands array. */
- for (que = 0; que < ha->max_queues; que++) {
+ for (que = 0; que < ha->max_req_queues; que++) {
req = ha->req_q_map[que];
if (!req)
continue;
- for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
+ for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
req->outstanding_cmds[cnt] = NULL;
- req->current_outstanding_cmd = 0;
+ req->current_outstanding_cmd = 1;
/* Initialize firmware. */
req->ring_ptr = req->ring;
@@ -1245,13 +1245,10 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
req->cnt = req->length;
}
- for (que = 0; que < ha->max_queues; que++) {
+ for (que = 0; que < ha->max_rsp_queues; que++) {
rsp = ha->rsp_q_map[que];
if (!rsp)
continue;
- rsp->ring_ptr = rsp->ring;
- rsp->ring_index = 0;
-
/* Initialize response queue entries */
qla2x00_init_response_q_entries(rsp);
}
@@ -1541,6 +1538,7 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
char *st, *en;
uint16_t index;
struct qla_hw_data *ha = vha->hw;
+ int use_tbl = !IS_QLA25XX(ha) && IS_QLA81XX(ha);
if (memcmp(model, BINZERO, len) != 0) {
strncpy(ha->model_number, model, len);
@@ -1553,14 +1551,16 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
}
index = (ha->pdev->subsystem_device & 0xff);
- if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
+ if (use_tbl &&
+ ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
index < QLA_MODEL_NAMES)
strncpy(ha->model_desc,
qla2x00_model_name[index * 2 + 1],
sizeof(ha->model_desc) - 1);
} else {
index = (ha->pdev->subsystem_device & 0xff);
- if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
+ if (use_tbl &&
+ ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
index < QLA_MODEL_NAMES) {
strcpy(ha->model_number,
qla2x00_model_name[index * 2]);
@@ -2110,7 +2110,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
goto cleanup_allocation;
DEBUG3(printk("scsi(%ld): Entries in ID list (%d)\n",
- ha->host_no, entries));
+ vha->host_no, entries));
DEBUG3(qla2x00_dump_buffer((uint8_t *)ha->gid_list,
entries * sizeof(struct gid_list_info)));
@@ -3180,9 +3180,14 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
{
int rval = QLA_SUCCESS;
uint32_t wait_time;
- struct qla_hw_data *ha = vha->hw;
- struct req_que *req = ha->req_q_map[vha->req_ques[0]];
- struct rsp_que *rsp = req->rsp;
+ struct req_que *req;
+ struct rsp_que *rsp;
+
+ if (ql2xmultique_tag)
+ req = vha->hw->req_q_map[0];
+ else
+ req = vha->req;
+ rsp = req->rsp;
atomic_set(&vha->loop_state, LOOP_UPDATE);
clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
@@ -3448,7 +3453,7 @@ qla25xx_init_queues(struct qla_hw_data *ha)
int ret = -1;
int i;
- for (i = 1; i < ha->max_queues; i++) {
+ for (i = 1; i < ha->max_rsp_queues; i++) {
rsp = ha->rsp_q_map[i];
if (rsp) {
rsp->options &= ~BIT_0;
@@ -3462,6 +3467,8 @@ qla25xx_init_queues(struct qla_hw_data *ha)
"%s Rsp que:%d inited\n", __func__,
rsp->id));
}
+ }
+ for (i = 1; i < ha->max_req_queues; i++) {
req = ha->req_q_map[i];
if (req) {
/* Clear outstanding commands array. */
@@ -3566,14 +3573,15 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
nv = ha->nvram;
/* Determine NVRAM starting address. */
- ha->nvram_size = sizeof(struct nvram_24xx);
- ha->nvram_base = FA_NVRAM_FUNC0_ADDR;
- ha->vpd_size = FA_NVRAM_VPD_SIZE;
- ha->vpd_base = FA_NVRAM_VPD0_ADDR;
- if (PCI_FUNC(ha->pdev->devfn)) {
+ if (ha->flags.port0) {
+ ha->nvram_base = FA_NVRAM_FUNC0_ADDR;
+ ha->vpd_base = FA_NVRAM_VPD0_ADDR;
+ } else {
ha->nvram_base = FA_NVRAM_FUNC1_ADDR;
ha->vpd_base = FA_NVRAM_VPD1_ADDR;
}
+ ha->nvram_size = sizeof(struct nvram_24xx);
+ ha->vpd_size = FA_NVRAM_VPD_SIZE;
/* Get VPD data into cache */
ha->vpd = ha->nvram + VPD_OFFSET;
@@ -3587,7 +3595,7 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++)
chksum += le32_to_cpu(*dptr++);
- DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
+ DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", vha->host_no));
DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size));
/* Bad NVRAM data, set defaults parameters. */
@@ -3612,7 +3620,7 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
nv->exchange_count = __constant_cpu_to_le16(0);
nv->hard_address = __constant_cpu_to_le16(124);
nv->port_name[0] = 0x21;
- nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn);
+ nv->port_name[1] = 0x00 + ha->port_no;
nv->port_name[2] = 0x00;
nv->port_name[3] = 0xe0;
nv->port_name[4] = 0x8b;
@@ -4104,6 +4112,9 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
{
int rval;
+ if (ql2xfwloadbin == 1)
+ return qla81xx_load_risc(vha, srisc_addr);
+
/*
* FW Load priority:
* 1) Firmware via request-firmware interface (.bin file).
@@ -4121,6 +4132,9 @@ qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
{
int rval;
+ if (ql2xfwloadbin == 2)
+ return qla24xx_load_risc(vha, srisc_addr);
+
/*
* FW Load priority:
* 1) Firmware residing in flash.
@@ -4146,7 +4160,7 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha)
ret = qla2x00_stop_firmware(vha);
for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT &&
- retries ; retries--) {
+ ret != QLA_INVALID_COMMAND && retries ; retries--) {
ha->isp_ops->reset_chip(vha);
if (ha->isp_ops->chip_diag(vha) != QLA_SUCCESS)
continue;
@@ -4165,13 +4179,19 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha)
uint16_t mb[MAILBOX_REGISTER_COUNT];
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
- struct req_que *req = ha->req_q_map[vha->req_ques[0]];
- struct rsp_que *rsp = req->rsp;
+ struct req_que *req;
+ struct rsp_que *rsp;
if (!vha->vp_idx)
return -EINVAL;
rval = qla2x00_fw_ready(base_vha);
+ if (ql2xmultique_tag)
+ req = ha->req_q_map[0];
+ else
+ req = vha->req;
+ rsp = req->rsp;
+
if (rval == QLA_SUCCESS) {
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
@@ -4305,7 +4325,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++)
chksum += le32_to_cpu(*dptr++);
- DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
+ DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", vha->host_no));
DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size));
/* Bad NVRAM data, set defaults parameters. */
@@ -4329,7 +4349,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
nv->execution_throttle = __constant_cpu_to_le16(0xFFFF);
nv->exchange_count = __constant_cpu_to_le16(0);
nv->port_name[0] = 0x21;
- nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn);
+ nv->port_name[1] = 0x00 + ha->port_no;
nv->port_name[2] = 0x00;
nv->port_name[3] = 0xe0;
nv->port_name[4] = 0x8b;
@@ -4363,7 +4383,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
nv->enode_mac[2] = 0x03;
nv->enode_mac[3] = 0x04;
nv->enode_mac[4] = 0x05;
- nv->enode_mac[5] = 0x06 + PCI_FUNC(ha->pdev->devfn);
+ nv->enode_mac[5] = 0x06 + ha->port_no;
rval = 1;
}
@@ -4396,7 +4416,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
icb->enode_mac[2] = 0x03;
icb->enode_mac[3] = 0x04;
icb->enode_mac[4] = 0x05;
- icb->enode_mac[5] = 0x06 + PCI_FUNC(ha->pdev->devfn);
+ icb->enode_mac[5] = 0x06 + ha->port_no;
}
/* Use extended-initialization control block. */
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index a8abbb95730d..b4c6010ee5fa 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -15,6 +15,7 @@ static request_t *qla2x00_req_pkt(struct scsi_qla_host *, struct req_que *,
struct rsp_que *rsp);
static void qla2x00_isp_cmd(struct scsi_qla_host *, struct req_que *);
+static void qla25xx_set_que(srb_t *, struct req_que **, struct rsp_que **);
/**
* qla2x00_get_cmd_direction() - Determine control_flag data direction.
* @cmd: SCSI command
@@ -92,9 +93,10 @@ qla2x00_calc_iocbs_64(uint16_t dsds)
* Returns a pointer to the Continuation Type 0 IOCB packet.
*/
static inline cont_entry_t *
-qla2x00_prep_cont_type0_iocb(struct req_que *req, struct scsi_qla_host *vha)
+qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha)
{
cont_entry_t *cont_pkt;
+ struct req_que *req = vha->req;
/* Adjust ring index. */
req->ring_index++;
if (req->ring_index == req->length) {
@@ -120,10 +122,11 @@ qla2x00_prep_cont_type0_iocb(struct req_que *req, struct scsi_qla_host *vha)
* Returns a pointer to the continuation type 1 IOCB packet.
*/
static inline cont_a64_entry_t *
-qla2x00_prep_cont_type1_iocb(struct req_que *req, scsi_qla_host_t *vha)
+qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha)
{
cont_a64_entry_t *cont_pkt;
+ struct req_que *req = vha->req;
/* Adjust ring index. */
req->ring_index++;
if (req->ring_index == req->length) {
@@ -159,7 +162,6 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
struct scsi_cmnd *cmd;
struct scatterlist *sg;
int i;
- struct req_que *req;
cmd = sp->cmd;
@@ -174,8 +176,6 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
}
vha = sp->fcport->vha;
- req = sp->que;
-
cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));
/* Three DSDs are available in the Command Type 2 IOCB */
@@ -192,7 +192,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
* Seven DSDs are available in the Continuation
* Type 0 IOCB.
*/
- cont_pkt = qla2x00_prep_cont_type0_iocb(req, vha);
+ cont_pkt = qla2x00_prep_cont_type0_iocb(vha);
cur_dsd = (uint32_t *)&cont_pkt->dseg_0_address;
avail_dsds = 7;
}
@@ -220,7 +220,6 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
struct scsi_cmnd *cmd;
struct scatterlist *sg;
int i;
- struct req_que *req;
cmd = sp->cmd;
@@ -235,8 +234,6 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
}
vha = sp->fcport->vha;
- req = sp->que;
-
cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));
/* Two DSDs are available in the Command Type 3 IOCB */
@@ -254,7 +251,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
* Five DSDs are available in the Continuation
* Type 1 IOCB.
*/
- cont_pkt = qla2x00_prep_cont_type1_iocb(req, vha);
+ cont_pkt = qla2x00_prep_cont_type1_iocb(vha);
cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
avail_dsds = 5;
}
@@ -353,7 +350,6 @@ qla2x00_start_scsi(srb_t *sp)
/* Build command packet */
req->current_outstanding_cmd = handle;
req->outstanding_cmds[handle] = sp;
- sp->que = req;
sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
req->cnt -= req_cnt;
@@ -453,6 +449,7 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
mrk24->lun[2] = MSB(lun);
host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun));
mrk24->vp_index = vha->vp_idx;
+ mrk24->handle = MAKE_HANDLE(req->id, mrk24->handle);
} else {
SET_TARGET_ID(ha, mrk->target, loop_id);
mrk->lun = cpu_to_le16(lun);
@@ -531,9 +528,6 @@ qla2x00_req_pkt(struct scsi_qla_host *vha, struct req_que *req,
for (cnt = 0; cnt < REQUEST_ENTRY_SIZE / 4; cnt++)
*dword_ptr++ = 0;
- /* Set system defined field. */
- pkt->sys_define = (uint8_t)req->ring_index;
-
/* Set entry count. */
pkt->entry_count = 1;
@@ -656,7 +650,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
}
vha = sp->fcport->vha;
- req = sp->que;
+ req = vha->req;
/* Set transfer direction */
if (cmd->sc_data_direction == DMA_TO_DEVICE) {
@@ -687,7 +681,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
* Five DSDs are available in the Continuation
* Type 1 IOCB.
*/
- cont_pkt = qla2x00_prep_cont_type1_iocb(req, vha);
+ cont_pkt = qla2x00_prep_cont_type1_iocb(vha);
cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
avail_dsds = 5;
}
@@ -724,19 +718,12 @@ qla24xx_start_scsi(srb_t *sp)
struct scsi_cmnd *cmd = sp->cmd;
struct scsi_qla_host *vha = sp->fcport->vha;
struct qla_hw_data *ha = vha->hw;
- uint16_t que_id;
/* Setup device pointers. */
ret = 0;
- que_id = vha->req_ques[0];
- req = ha->req_q_map[que_id];
- sp->que = req;
+ qla25xx_set_que(sp, &req, &rsp);
- if (req->rsp)
- rsp = req->rsp;
- else
- rsp = ha->rsp_q_map[que_id];
/* So we know we haven't pci_map'ed anything yet */
tot_dsds = 0;
@@ -794,7 +781,7 @@ qla24xx_start_scsi(srb_t *sp)
req->cnt -= req_cnt;
cmd_pkt = (struct cmd_type_7 *)req->ring_ptr;
- cmd_pkt->handle = handle;
+ cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
/* Zero out remaining portion of packet. */
/* tagged queuing modifier -- default is TSK_SIMPLE (0). */
@@ -823,6 +810,8 @@ qla24xx_start_scsi(srb_t *sp)
/* Set total data segment count. */
cmd_pkt->entry_count = (uint8_t)req_cnt;
+ /* Specify response queue number where completion should happen */
+ cmd_pkt->entry_status = (uint8_t) rsp->id;
wmb();
/* Adjust ring index. */
@@ -842,7 +831,7 @@ qla24xx_start_scsi(srb_t *sp)
/* Manage unprocessed RIO/ZIO commands in response queue. */
if (vha->flags.process_response_queue &&
rsp->ring_ptr->signature != RESPONSE_PROCESSED)
- qla24xx_process_response_queue(rsp);
+ qla24xx_process_response_queue(vha, rsp);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return QLA_SUCCESS;
@@ -855,3 +844,21 @@ queuing_error:
return QLA_FUNCTION_FAILED;
}
+
+static void qla25xx_set_que(srb_t *sp, struct req_que **req,
+ struct rsp_que **rsp)
+{
+ struct scsi_cmnd *cmd = sp->cmd;
+ struct scsi_qla_host *vha = sp->fcport->vha;
+ struct qla_hw_data *ha = sp->fcport->vha->hw;
+ int affinity = cmd->request->cpu;
+
+ if (ql2xmultique_tag && affinity >= 0 &&
+ affinity < ha->max_rsp_queues - 1) {
+ *rsp = ha->rsp_q_map[affinity + 1];
+ *req = ha->req_q_map[1];
+ } else {
+ *req = vha->req;
+ *rsp = ha->rsp_q_map[0];
+ }
+}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index d04981848e56..eb35d2050f7a 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -13,10 +13,9 @@ static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
static void qla2x00_process_completed_request(struct scsi_qla_host *,
struct req_que *, uint32_t);
static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
-static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
+static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
sts_entry_t *);
-static struct scsi_qla_host *qla2x00_get_rsp_host(struct rsp_que *);
/**
* qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
@@ -51,7 +50,7 @@ qla2100_intr_handler(int irq, void *dev_id)
status = 0;
spin_lock(&ha->hardware_lock);
- vha = qla2x00_get_rsp_host(rsp);
+ vha = pci_get_drvdata(ha->pdev);
for (iter = 50; iter--; ) {
hccr = RD_REG_WORD(&reg->hccr);
if (hccr & HCCR_RISC_PAUSE) {
@@ -147,7 +146,7 @@ qla2300_intr_handler(int irq, void *dev_id)
status = 0;
spin_lock(&ha->hardware_lock);
- vha = qla2x00_get_rsp_host(rsp);
+ vha = pci_get_drvdata(ha->pdev);
for (iter = 50; iter--; ) {
stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
if (stat & HSR_RISC_PAUSED) {
@@ -685,7 +684,7 @@ skip_rio:
vha->host_no));
if (IS_FWI2_CAPABLE(ha))
- qla24xx_process_response_queue(rsp);
+ qla24xx_process_response_queue(vha, rsp);
else
qla2x00_process_response_queue(rsp);
break;
@@ -766,7 +765,10 @@ qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data)
struct qla_hw_data *ha = vha->hw;
struct req_que *req = NULL;
- req = ha->req_q_map[vha->req_ques[0]];
+ if (!ql2xqfulltracking)
+ return;
+
+ req = vha->req;
if (!req)
return;
if (req->max_q_depth <= sdev->queue_depth)
@@ -808,6 +810,9 @@ qla2x00_ramp_up_queue_depth(scsi_qla_host_t *vha, struct req_que *req,
fc_port_t *fcport;
struct scsi_device *sdev;
+ if (!ql2xqfulltracking)
+ return;
+
sdev = sp->cmd->device;
if (sdev->queue_depth >= req->max_q_depth)
return;
@@ -858,8 +863,8 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
qla2x00_ramp_up_queue_depth(vha, req, sp);
qla2x00_sp_compl(ha, sp);
} else {
- DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
- vha->host_no));
+ DEBUG2(printk("scsi(%ld) Req:%d: Invalid ISP SCSI completion"
+ " handle(%d)\n", vha->host_no, req->id, index));
qla_printk(KERN_WARNING, ha,
"Invalid ISP SCSI completion handle\n");
@@ -881,7 +886,7 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
uint16_t handle_cnt;
uint16_t cnt;
- vha = qla2x00_get_rsp_host(rsp);
+ vha = pci_get_drvdata(ha->pdev);
if (!vha->flags.online)
return;
@@ -926,7 +931,7 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
}
break;
case STATUS_CONT_TYPE:
- qla2x00_status_cont_entry(vha, (sts_cont_entry_t *)pkt);
+ qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
break;
default:
/* Type Not Supported. */
@@ -945,7 +950,8 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
}
static inline void
-qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
+qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len,
+ struct rsp_que *rsp)
{
struct scsi_cmnd *cp = sp->cmd;
@@ -962,7 +968,7 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
sp->request_sense_ptr += sense_len;
sp->request_sense_length -= sense_len;
if (sp->request_sense_length != 0)
- sp->fcport->vha->status_srb = sp;
+ rsp->status_srb = sp;
DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) "
"cmd=%p pid=%ld\n", __func__, sp->fcport->vha->host_no,
@@ -992,7 +998,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
uint32_t sense_len, rsp_info_len, resid_len, fw_resid_len;
uint8_t *rsp_info, *sense_data;
struct qla_hw_data *ha = vha->hw;
- struct req_que *req = rsp->req;
+ uint32_t handle;
+ uint16_t que;
+ struct req_que *req;
sts = (sts_entry_t *) pkt;
sts24 = (struct sts_entry_24xx *) pkt;
@@ -1003,18 +1011,20 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
comp_status = le16_to_cpu(sts->comp_status);
scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
}
-
+ handle = (uint32_t) LSW(sts->handle);
+ que = MSW(sts->handle);
+ req = ha->req_q_map[que];
/* Fast path completion. */
if (comp_status == CS_COMPLETE && scsi_status == 0) {
- qla2x00_process_completed_request(vha, req, sts->handle);
+ qla2x00_process_completed_request(vha, req, handle);
return;
}
/* Validate handle. */
- if (sts->handle < MAX_OUTSTANDING_COMMANDS) {
- sp = req->outstanding_cmds[sts->handle];
- req->outstanding_cmds[sts->handle] = NULL;
+ if (handle < MAX_OUTSTANDING_COMMANDS) {
+ sp = req->outstanding_cmds[handle];
+ req->outstanding_cmds[handle] = NULL;
} else
sp = NULL;
@@ -1030,7 +1040,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
cp = sp->cmd;
if (cp == NULL) {
DEBUG2(printk("scsi(%ld): Command already returned back to OS "
- "pkt->handle=%d sp=%p.\n", vha->host_no, sts->handle, sp));
+ "pkt->handle=%d sp=%p.\n", vha->host_no, handle, sp));
qla_printk(KERN_WARNING, ha,
"Command is NULL: already returned to OS (sp=%p)\n", sp);
@@ -1121,6 +1131,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
scsi_status));
/* Adjust queue depth for all luns on the port. */
+ if (!ql2xqfulltracking)
+ break;
fcport->last_queue_full = jiffies;
starget_for_each_device(cp->device->sdev_target,
fcport, qla2x00_adjust_sdev_qdepth_down);
@@ -1133,7 +1145,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
if (!(scsi_status & SS_SENSE_LEN_VALID))
break;
- qla2x00_handle_sense(sp, sense_data, sense_len);
+ qla2x00_handle_sense(sp, sense_data, sense_len, rsp);
break;
case CS_DATA_UNDERRUN:
@@ -1179,6 +1191,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
* Adjust queue depth for all luns on the
* port.
*/
+ if (!ql2xqfulltracking)
+ break;
fcport->last_queue_full = jiffies;
starget_for_each_device(
cp->device->sdev_target, fcport,
@@ -1192,7 +1206,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
if (!(scsi_status & SS_SENSE_LEN_VALID))
break;
- qla2x00_handle_sense(sp, sense_data, sense_len);
+ qla2x00_handle_sense(sp, sense_data, sense_len, rsp);
} else {
/*
* If RISC reports underrun and target does not report
@@ -1334,7 +1348,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
}
/* Place command on done queue. */
- if (vha->status_srb == NULL)
+ if (rsp->status_srb == NULL)
qla2x00_sp_compl(ha, sp);
}
@@ -1346,11 +1360,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
* Extended sense data.
*/
static void
-qla2x00_status_cont_entry(scsi_qla_host_t *vha, sts_cont_entry_t *pkt)
+qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
{
uint8_t sense_sz = 0;
- struct qla_hw_data *ha = vha->hw;
- srb_t *sp = vha->status_srb;
+ struct qla_hw_data *ha = rsp->hw;
+ srb_t *sp = rsp->status_srb;
struct scsi_cmnd *cp;
if (sp != NULL && sp->request_sense_length != 0) {
@@ -1362,7 +1376,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *vha, sts_cont_entry_t *pkt)
"cmd is NULL: already returned to OS (sp=%p)\n",
sp);
- vha->status_srb = NULL;
+ rsp->status_srb = NULL;
return;
}
@@ -1383,7 +1397,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *vha, sts_cont_entry_t *pkt)
/* Place command on done queue. */
if (sp->request_sense_length == 0) {
- vha->status_srb = NULL;
+ rsp->status_srb = NULL;
qla2x00_sp_compl(ha, sp);
}
}
@@ -1399,7 +1413,9 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
{
srb_t *sp;
struct qla_hw_data *ha = vha->hw;
- struct req_que *req = rsp->req;
+ uint32_t handle = LSW(pkt->handle);
+ uint16_t que = MSW(pkt->handle);
+ struct req_que *req = ha->req_q_map[que];
#if defined(QL_DEBUG_LEVEL_2)
if (pkt->entry_status & RF_INV_E_ORDER)
qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__);
@@ -1417,14 +1433,14 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
#endif
/* Validate handle. */
- if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
- sp = req->outstanding_cmds[pkt->handle];
+ if (handle < MAX_OUTSTANDING_COMMANDS)
+ sp = req->outstanding_cmds[handle];
else
sp = NULL;
if (sp) {
/* Free outstanding command slot. */
- req->outstanding_cmds[pkt->handle] = NULL;
+ req->outstanding_cmds[handle] = NULL;
/* Bad payload or header */
if (pkt->entry_status &
@@ -1486,13 +1502,10 @@ qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
* qla24xx_process_response_queue() - Process response queue entries.
* @ha: SCSI driver HA context
*/
-void
-qla24xx_process_response_queue(struct rsp_que *rsp)
+void qla24xx_process_response_queue(struct scsi_qla_host *vha,
+ struct rsp_que *rsp)
{
struct sts_entry_24xx *pkt;
- struct scsi_qla_host *vha;
-
- vha = qla2x00_get_rsp_host(rsp);
if (!vha->flags.online)
return;
@@ -1523,7 +1536,7 @@ qla24xx_process_response_queue(struct rsp_que *rsp)
qla2x00_status_entry(vha, rsp, pkt);
break;
case STATUS_CONT_TYPE:
- qla2x00_status_cont_entry(vha, (sts_cont_entry_t *)pkt);
+ qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
break;
case VP_RPT_ID_IOCB_TYPE:
qla24xx_report_id_acquisition(vha,
@@ -1626,7 +1639,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
status = 0;
spin_lock(&ha->hardware_lock);
- vha = qla2x00_get_rsp_host(rsp);
+ vha = pci_get_drvdata(ha->pdev);
for (iter = 50; iter--; ) {
stat = RD_REG_DWORD(&reg->host_status);
if (stat & HSRX_RISC_PAUSED) {
@@ -1664,7 +1677,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
break;
case 0x13:
case 0x14:
- qla24xx_process_response_queue(rsp);
+ qla24xx_process_response_queue(vha, rsp);
break;
default:
DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
@@ -1692,6 +1705,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
struct qla_hw_data *ha;
struct rsp_que *rsp;
struct device_reg_24xx __iomem *reg;
+ struct scsi_qla_host *vha;
rsp = (struct rsp_que *) dev_id;
if (!rsp) {
@@ -1704,7 +1718,8 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
spin_lock_irq(&ha->hardware_lock);
- qla24xx_process_response_queue(rsp);
+ vha = qla25xx_get_host(rsp);
+ qla24xx_process_response_queue(vha, rsp);
WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
spin_unlock_irq(&ha->hardware_lock);
@@ -1717,7 +1732,6 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
{
struct qla_hw_data *ha;
struct rsp_que *rsp;
- struct device_reg_24xx __iomem *reg;
rsp = (struct rsp_que *) dev_id;
if (!rsp) {
@@ -1726,13 +1740,8 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
return IRQ_NONE;
}
ha = rsp->hw;
- reg = &ha->iobase->isp24;
- spin_lock_irq(&ha->hardware_lock);
-
- qla24xx_process_response_queue(rsp);
-
- spin_unlock_irq(&ha->hardware_lock);
+ queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work);
return IRQ_HANDLED;
}
@@ -1760,7 +1769,7 @@ qla24xx_msix_default(int irq, void *dev_id)
status = 0;
spin_lock_irq(&ha->hardware_lock);
- vha = qla2x00_get_rsp_host(rsp);
+ vha = pci_get_drvdata(ha->pdev);
do {
stat = RD_REG_DWORD(&reg->host_status);
if (stat & HSRX_RISC_PAUSED) {
@@ -1798,7 +1807,7 @@ qla24xx_msix_default(int irq, void *dev_id)
break;
case 0x13:
case 0x14:
- qla24xx_process_response_queue(rsp);
+ qla24xx_process_response_queue(vha, rsp);
break;
default:
DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
@@ -1822,31 +1831,14 @@ qla24xx_msix_default(int irq, void *dev_id)
/* Interrupt handling helpers. */
struct qla_init_msix_entry {
- uint16_t entry;
- uint16_t index;
const char *name;
irq_handler_t handler;
};
-static struct qla_init_msix_entry base_queue = {
- .entry = 0,
- .index = 0,
- .name = "qla2xxx (default)",
- .handler = qla24xx_msix_default,
-};
-
-static struct qla_init_msix_entry base_rsp_queue = {
- .entry = 1,
- .index = 1,
- .name = "qla2xxx (rsp_q)",
- .handler = qla24xx_msix_rsp_q,
-};
-
-static struct qla_init_msix_entry multi_rsp_queue = {
- .entry = 1,
- .index = 1,
- .name = "qla2xxx (multi_q)",
- .handler = qla25xx_msix_rsp_q,
+static struct qla_init_msix_entry msix_entries[3] = {
+ { "qla2xxx (default)", qla24xx_msix_default },
+ { "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
+ { "qla2xxx (multiq)", qla25xx_msix_rsp_q },
};
static void
@@ -1873,7 +1865,6 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
int i, ret;
struct msix_entry *entries;
struct qla_msix_entry *qentry;
- struct qla_init_msix_entry *msix_queue;
entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count,
GFP_KERNEL);
@@ -1900,7 +1891,7 @@ msix_failed:
ha->msix_count, ret);
goto msix_out;
}
- ha->max_queues = ha->msix_count - 1;
+ ha->max_rsp_queues = ha->msix_count - 1;
}
ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) *
ha->msix_count, GFP_KERNEL);
@@ -1918,45 +1909,27 @@ msix_failed:
qentry->rsp = NULL;
}
- /* Enable MSI-X for AENs for queue 0 */
- qentry = &ha->msix_entries[0];
- ret = request_irq(qentry->vector, base_queue.handler, 0,
- base_queue.name, rsp);
- if (ret) {
- qla_printk(KERN_WARNING, ha,
+ /* Enable MSI-X vectors for the base queue */
+ for (i = 0; i < 2; i++) {
+ qentry = &ha->msix_entries[i];
+ ret = request_irq(qentry->vector, msix_entries[i].handler,
+ 0, msix_entries[i].name, rsp);
+ if (ret) {
+ qla_printk(KERN_WARNING, ha,
"MSI-X: Unable to register handler -- %x/%d.\n",
qentry->vector, ret);
- qla24xx_disable_msix(ha);
- goto msix_out;
+ qla24xx_disable_msix(ha);
+ ha->mqenable = 0;
+ goto msix_out;
+ }
+ qentry->have_irq = 1;
+ qentry->rsp = rsp;
+ rsp->msix = qentry;
}
- qentry->have_irq = 1;
- qentry->rsp = rsp;
/* Enable MSI-X vector for response queue update for queue 0 */
- if (ha->max_queues > 1 && ha->mqiobase) {
+ if (ha->mqiobase && (ha->max_rsp_queues > 1 || ha->max_req_queues > 1))
ha->mqenable = 1;
- msix_queue = &multi_rsp_queue;
- qla_printk(KERN_INFO, ha,
- "MQ enabled, Number of Queue Resources: %d \n",
- ha->max_queues);
- } else {
- ha->mqenable = 0;
- msix_queue = &base_rsp_queue;
- }
-
- qentry = &ha->msix_entries[1];
- ret = request_irq(qentry->vector, msix_queue->handler, 0,
- msix_queue->name, rsp);
- if (ret) {
- qla_printk(KERN_WARNING, ha,
- "MSI-X: Unable to register handler -- %x/%d.\n",
- qentry->vector, ret);
- qla24xx_disable_msix(ha);
- ha->mqenable = 0;
- goto msix_out;
- }
- qentry->have_irq = 1;
- qentry->rsp = rsp;
msix_out:
kfree(entries);
@@ -2063,35 +2036,11 @@ qla2x00_free_irqs(scsi_qla_host_t *vha)
}
}
-static struct scsi_qla_host *
-qla2x00_get_rsp_host(struct rsp_que *rsp)
-{
- srb_t *sp;
- struct qla_hw_data *ha = rsp->hw;
- struct scsi_qla_host *vha = NULL;
- struct sts_entry_24xx *pkt;
- struct req_que *req;
-
- if (rsp->id) {
- pkt = (struct sts_entry_24xx *) rsp->ring_ptr;
- req = rsp->req;
- if (pkt && pkt->handle < MAX_OUTSTANDING_COMMANDS) {
- sp = req->outstanding_cmds[pkt->handle];
- if (sp)
- vha = sp->fcport->vha;
- }
- }
- if (!vha)
- /* handle it in base queue */
- vha = pci_get_drvdata(ha->pdev);
-
- return vha;
-}
int qla25xx_request_irq(struct rsp_que *rsp)
{
struct qla_hw_data *ha = rsp->hw;
- struct qla_init_msix_entry *intr = &multi_rsp_queue;
+ struct qla_init_msix_entry *intr = &msix_entries[2];
struct qla_msix_entry *msix = rsp->msix;
int ret;
@@ -2106,3 +2055,30 @@ int qla25xx_request_irq(struct rsp_que *rsp)
msix->rsp = rsp;
return ret;
}
+
+struct scsi_qla_host *
+qla25xx_get_host(struct rsp_que *rsp)
+{
+ srb_t *sp;
+ struct qla_hw_data *ha = rsp->hw;
+ struct scsi_qla_host *vha = NULL;
+ struct sts_entry_24xx *pkt;
+ struct req_que *req;
+ uint16_t que;
+ uint32_t handle;
+
+ pkt = (struct sts_entry_24xx *) rsp->ring_ptr;
+ que = MSW(pkt->handle);
+ handle = (uint32_t) LSW(pkt->handle);
+ req = ha->req_q_map[que];
+ if (handle < MAX_OUTSTANDING_COMMANDS) {
+ sp = req->outstanding_cmds[handle];
+ if (sp)
+ return sp->fcport->vha;
+ else
+ goto base_que;
+ }
+base_que:
+ vha = pci_get_drvdata(ha->pdev);
+ return vha;
+}
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index e67c1660bf46..7d0eeec9ba57 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -748,20 +748,20 @@ qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
* Kernel context.
*/
int
-qla2x00_abort_command(scsi_qla_host_t *vha, srb_t *sp, struct req_que *req)
+qla2x00_abort_command(srb_t *sp)
{
unsigned long flags = 0;
- fc_port_t *fcport;
int rval;
uint32_t handle = 0;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
+ fc_port_t *fcport = sp->fcport;
+ scsi_qla_host_t *vha = fcport->vha;
struct qla_hw_data *ha = vha->hw;
+ struct req_que *req = vha->req;
DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", vha->host_no));
- fcport = sp->fcport;
-
spin_lock_irqsave(&ha->hardware_lock, flags);
for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
if (req->outstanding_cmds[handle] == sp)
@@ -800,7 +800,7 @@ qla2x00_abort_command(scsi_qla_host_t *vha, srb_t *sp, struct req_que *req)
}
int
-qla2x00_abort_target(struct fc_port *fcport, unsigned int l)
+qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
{
int rval, rval2;
mbx_cmd_t mc;
@@ -813,8 +813,8 @@ qla2x00_abort_target(struct fc_port *fcport, unsigned int l)
l = l;
vha = fcport->vha;
- req = vha->hw->req_q_map[0];
- rsp = vha->hw->rsp_q_map[0];
+ req = vha->hw->req_q_map[tag];
+ rsp = vha->hw->rsp_q_map[tag];
mcp->mb[0] = MBC_ABORT_TARGET;
mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
if (HAS_EXTENDED_IDS(vha->hw)) {
@@ -850,7 +850,7 @@ qla2x00_abort_target(struct fc_port *fcport, unsigned int l)
}
int
-qla2x00_lun_reset(struct fc_port *fcport, unsigned int l)
+qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
{
int rval, rval2;
mbx_cmd_t mc;
@@ -862,8 +862,8 @@ qla2x00_lun_reset(struct fc_port *fcport, unsigned int l)
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no));
vha = fcport->vha;
- req = vha->hw->req_q_map[0];
- rsp = vha->hw->rsp_q_map[0];
+ req = vha->hw->req_q_map[tag];
+ rsp = vha->hw->rsp_q_map[tag];
mcp->mb[0] = MBC_LUN_RESET;
mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
if (HAS_EXTENDED_IDS(vha->hw))
@@ -931,6 +931,8 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
mcp->mb[9] = vha->vp_idx;
mcp->out_mb = MBX_9|MBX_0;
mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+ if (IS_QLA81XX(vha->hw))
+ mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp);
@@ -952,9 +954,19 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n",
vha->host_no, rval));
} else {
- /*EMPTY*/
DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n",
vha->host_no));
+
+ if (IS_QLA81XX(vha->hw)) {
+ vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
+ vha->fcoe_fcf_idx = mcp->mb[10];
+ vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
+ vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
+ vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
+ vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
+ vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
+ vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
+ }
}
return rval;
@@ -1480,9 +1492,17 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
dma_addr_t lg_dma;
uint32_t iop[2];
struct qla_hw_data *ha = vha->hw;
+ struct req_que *req;
+ struct rsp_que *rsp;
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+ if (ql2xmultique_tag)
+ req = ha->req_q_map[0];
+ else
+ req = vha->req;
+ rsp = req->rsp;
+
lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
if (lg == NULL) {
DEBUG2_3(printk("%s(%ld): failed to allocate Login IOCB.\n",
@@ -1493,6 +1513,7 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
lg->entry_count = 1;
+ lg->handle = MAKE_HANDLE(req->id, lg->handle);
lg->nport_handle = cpu_to_le16(loop_id);
lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
if (opt & BIT_0)
@@ -1741,6 +1762,8 @@ qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
struct logio_entry_24xx *lg;
dma_addr_t lg_dma;
struct qla_hw_data *ha = vha->hw;
+ struct req_que *req;
+ struct rsp_que *rsp;
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
@@ -1752,8 +1775,14 @@ qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
}
memset(lg, 0, sizeof(struct logio_entry_24xx));
+ if (ql2xmaxqueues > 1)
+ req = ha->req_q_map[0];
+ else
+ req = vha->req;
+ rsp = req->rsp;
lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
lg->entry_count = 1;
+ lg->handle = MAKE_HANDLE(req->id, lg->handle);
lg->nport_handle = cpu_to_le16(loop_id);
lg->control_flags =
__constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
@@ -1864,9 +1893,6 @@ qla2x00_full_login_lip(scsi_qla_host_t *vha)
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
- if (IS_QLA81XX(vha->hw))
- return QLA_SUCCESS;
-
DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n",
vha->host_no));
@@ -2195,21 +2221,21 @@ qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
}
int
-qla24xx_abort_command(scsi_qla_host_t *vha, srb_t *sp, struct req_que *req)
+qla24xx_abort_command(srb_t *sp)
{
int rval;
- fc_port_t *fcport;
unsigned long flags = 0;
struct abort_entry_24xx *abt;
dma_addr_t abt_dma;
uint32_t handle;
+ fc_port_t *fcport = sp->fcport;
+ struct scsi_qla_host *vha = fcport->vha;
struct qla_hw_data *ha = vha->hw;
+ struct req_que *req = vha->req;
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
- fcport = sp->fcport;
-
spin_lock_irqsave(&ha->hardware_lock, flags);
for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
if (req->outstanding_cmds[handle] == sp)
@@ -2231,6 +2257,7 @@ qla24xx_abort_command(scsi_qla_host_t *vha, srb_t *sp, struct req_que *req)
abt->entry_type = ABORT_IOCB_TYPE;
abt->entry_count = 1;
+ abt->handle = MAKE_HANDLE(req->id, abt->handle);
abt->nport_handle = cpu_to_le16(fcport->loop_id);
abt->handle_to_abort = handle;
abt->port_id[0] = fcport->d_id.b.al_pa;
@@ -2272,7 +2299,7 @@ struct tsk_mgmt_cmd {
static int
__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
- unsigned int l)
+ unsigned int l, int tag)
{
int rval, rval2;
struct tsk_mgmt_cmd *tsk;
@@ -2286,8 +2313,11 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
vha = fcport->vha;
ha = vha->hw;
- req = ha->req_q_map[0];
- rsp = ha->rsp_q_map[0];
+ req = vha->req;
+ if (ql2xmultique_tag)
+ rsp = ha->rsp_q_map[tag + 1];
+ else
+ rsp = req->rsp;
tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
if (tsk == NULL) {
DEBUG2_3(printk("%s(%ld): failed to allocate Task Management "
@@ -2298,6 +2328,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
tsk->p.tsk.entry_count = 1;
+ tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
tsk->p.tsk.control_flags = cpu_to_le32(type);
@@ -2344,15 +2375,15 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
}
int
-qla24xx_abort_target(struct fc_port *fcport, unsigned int l)
+qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
{
- return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l);
+ return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
}
int
-qla24xx_lun_reset(struct fc_port *fcport, unsigned int l)
+qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
{
- return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l);
+ return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
}
int
@@ -2446,6 +2477,8 @@ qla2x00_stop_firmware(scsi_qla_host_t *vha)
if (rval != QLA_SUCCESS) {
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
vha->host_no, rval));
+ if (mcp->mb[0] == MBS_INVALID_COMMAND)
+ rval = QLA_INVALID_COMMAND;
} else {
DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
}
@@ -3141,6 +3174,8 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
WRT_REG_DWORD(&reg->req_q_in, 0);
WRT_REG_DWORD(&reg->req_q_out, 0);
}
+ req->req_q_in = &reg->req_q_in;
+ req->req_q_out = &reg->req_q_out;
spin_unlock_irqrestore(&ha->hardware_lock, flags);
rval = qla2x00_mailbox_command(vha, mcp);
@@ -3167,7 +3202,6 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
mcp->mb[6] = MSW(MSD(rsp->dma));
mcp->mb[7] = LSW(MSD(rsp->dma));
mcp->mb[5] = rsp->length;
- mcp->mb[11] = rsp->vp_idx;
mcp->mb[14] = rsp->msix->entry;
mcp->mb[13] = rsp->rid;
@@ -3179,7 +3213,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
mcp->mb[8] = 0;
/* que out ptr index */
mcp->mb[9] = 0;
- mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7
+ mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_0;
mcp->flags = MBX_DMA_OUT;
@@ -3384,7 +3418,7 @@ qla2x00_read_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
vha->host_no, rval, mcp->mb[0]));
} else {
- DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
}
return rval;
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 51716c7e3008..650bcef08f2a 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -398,9 +398,8 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL);
- memset(vha->req_ques, 0, sizeof(vha->req_ques));
- vha->req_ques[0] = ha->req_q_map[0]->id;
- host->can_queue = ha->req_q_map[0]->length + 128;
+ vha->req = base_vha->req;
+ host->can_queue = base_vha->req->length + 128;
host->this_id = 255;
host->cmd_per_lun = 3;
host->max_cmd_len = MAX_CMDSZ;
@@ -515,76 +514,53 @@ int qla25xx_update_req_que(struct scsi_qla_host *vha, uint8_t que, uint8_t qos)
/* Delete all queues for a given vhost */
int
-qla25xx_delete_queues(struct scsi_qla_host *vha, uint8_t que_no)
+qla25xx_delete_queues(struct scsi_qla_host *vha)
{
int cnt, ret = 0;
struct req_que *req = NULL;
struct rsp_que *rsp = NULL;
struct qla_hw_data *ha = vha->hw;
- if (que_no) {
- /* Delete request queue */
- req = ha->req_q_map[que_no];
+ /* Delete request queues */
+ for (cnt = 1; cnt < ha->max_req_queues; cnt++) {
+ req = ha->req_q_map[cnt];
if (req) {
- rsp = req->rsp;
ret = qla25xx_delete_req_que(vha, req);
if (ret != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha,
- "Couldn't delete req que %d\n", req->id);
+ "Couldn't delete req que %d\n",
+ req->id);
return ret;
}
- /* Delete associated response queue */
- if (rsp) {
- ret = qla25xx_delete_rsp_que(vha, rsp);
- if (ret != QLA_SUCCESS) {
- qla_printk(KERN_WARNING, ha,
- "Couldn't delete rsp que %d\n",
- rsp->id);
- return ret;
- }
- }
}
- } else { /* delete all queues of this host */
- for (cnt = 0; cnt < QLA_MAX_HOST_QUES; cnt++) {
- /* Delete request queues */
- req = ha->req_q_map[vha->req_ques[cnt]];
- if (req && req->id) {
- rsp = req->rsp;
- ret = qla25xx_delete_req_que(vha, req);
- if (ret != QLA_SUCCESS) {
- qla_printk(KERN_WARNING, ha,
- "Couldn't delete req que %d\n",
- vha->req_ques[cnt]);
- return ret;
- }
- vha->req_ques[cnt] = ha->req_q_map[0]->id;
- /* Delete associated response queue */
- if (rsp && rsp->id) {
- ret = qla25xx_delete_rsp_que(vha, rsp);
- if (ret != QLA_SUCCESS) {
- qla_printk(KERN_WARNING, ha,
- "Couldn't delete rsp que %d\n",
- rsp->id);
- return ret;
- }
- }
+ }
+
+ /* Delete response queues */
+ for (cnt = 1; cnt < ha->max_rsp_queues; cnt++) {
+ rsp = ha->rsp_q_map[cnt];
+ if (rsp) {
+ ret = qla25xx_delete_rsp_que(vha, rsp);
+ if (ret != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "Couldn't delete rsp que %d\n",
+ rsp->id);
+ return ret;
}
}
}
- qla_printk(KERN_INFO, ha, "Queues deleted for vport:%d\n",
- vha->vp_idx);
return ret;
}
int
qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
- uint8_t vp_idx, uint16_t rid, uint8_t rsp_que, uint8_t qos)
+ uint8_t vp_idx, uint16_t rid, int rsp_que, uint8_t qos)
{
int ret = 0;
struct req_que *req = NULL;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
uint16_t que_id = 0;
device_reg_t __iomem *reg;
+ uint32_t cnt;
req = kzalloc(sizeof(struct req_que), GFP_KERNEL);
if (req == NULL) {
@@ -604,8 +580,8 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
}
mutex_lock(&ha->vport_lock);
- que_id = find_first_zero_bit(ha->req_qid_map, ha->max_queues);
- if (que_id >= ha->max_queues) {
+ que_id = find_first_zero_bit(ha->req_qid_map, ha->max_req_queues);
+ if (que_id >= ha->max_req_queues) {
mutex_unlock(&ha->vport_lock);
qla_printk(KERN_INFO, ha, "No resources to create "
"additional request queue\n");
@@ -617,10 +593,10 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
req->vp_idx = vp_idx;
req->qos = qos;
- if (ha->rsp_q_map[rsp_que]) {
+ if (rsp_que < 0)
+ req->rsp = NULL;
+ else
req->rsp = ha->rsp_q_map[rsp_que];
- req->rsp->req = req;
- }
/* Use alternate PCI bus number */
if (MSB(req->rid))
options |= BIT_4;
@@ -628,13 +604,16 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
if (LSB(req->rid))
options |= BIT_5;
req->options = options;
+
+ for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
+ req->outstanding_cmds[cnt] = NULL;
+ req->current_outstanding_cmd = 1;
+
req->ring_ptr = req->ring;
req->ring_index = 0;
req->cnt = req->length;
req->id = que_id;
reg = ISP_QUE_REG(ha, que_id);
- req->req_q_in = &reg->isp25mq.req_q_in;
- req->req_q_out = &reg->isp25mq.req_q_out;
req->max_q_depth = ha->req_q_map[0]->max_q_depth;
mutex_unlock(&ha->vport_lock);
@@ -654,10 +633,19 @@ que_failed:
return 0;
}
+static void qla_do_work(struct work_struct *work)
+{
+ struct rsp_que *rsp = container_of(work, struct rsp_que, q_work);
+ struct scsi_qla_host *vha;
+
+ vha = qla25xx_get_host(rsp);
+ qla24xx_process_response_queue(vha, rsp);
+}
+
/* create response queue */
int
qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
- uint8_t vp_idx, uint16_t rid)
+ uint8_t vp_idx, uint16_t rid, int req)
{
int ret = 0;
struct rsp_que *rsp = NULL;
@@ -672,7 +660,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
goto que_failed;
}
- rsp->length = RESPONSE_ENTRY_CNT_2300;
+ rsp->length = RESPONSE_ENTRY_CNT_MQ;
rsp->ring = dma_alloc_coherent(&ha->pdev->dev,
(rsp->length + 1) * sizeof(response_t),
&rsp->dma, GFP_KERNEL);
@@ -683,8 +671,8 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
}
mutex_lock(&ha->vport_lock);
- que_id = find_first_zero_bit(ha->rsp_qid_map, ha->max_queues);
- if (que_id >= ha->max_queues) {
+ que_id = find_first_zero_bit(ha->rsp_qid_map, ha->max_rsp_queues);
+ if (que_id >= ha->max_rsp_queues) {
mutex_unlock(&ha->vport_lock);
qla_printk(KERN_INFO, ha, "No resources to create "
"additional response queue\n");
@@ -708,8 +696,6 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
if (LSB(rsp->rid))
options |= BIT_5;
rsp->options = options;
- rsp->ring_ptr = rsp->ring;
- rsp->ring_index = 0;
rsp->id = que_id;
reg = ISP_QUE_REG(ha, que_id);
rsp->rsp_q_in = &reg->isp25mq.rsp_q_in;
@@ -728,9 +714,14 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
mutex_unlock(&ha->vport_lock);
goto que_failed;
}
+ if (req >= 0)
+ rsp->req = ha->req_q_map[req];
+ else
+ rsp->req = NULL;
qla2x00_init_response_q_entries(rsp);
-
+ if (rsp->hw->wq)
+ INIT_WORK(&rsp->q_work, qla_do_work);
return rsp->id;
que_failed:
@@ -744,14 +735,16 @@ qla25xx_create_queues(struct scsi_qla_host *vha, uint8_t qos)
uint16_t options = 0;
uint8_t ret = 0;
struct qla_hw_data *ha = vha->hw;
+ struct rsp_que *rsp;
options |= BIT_1;
- ret = qla25xx_create_rsp_que(ha, options, vha->vp_idx, 0);
+ ret = qla25xx_create_rsp_que(ha, options, vha->vp_idx, 0, -1);
if (!ret) {
qla_printk(KERN_WARNING, ha, "Response Que create failed\n");
return ret;
} else
qla_printk(KERN_INFO, ha, "Response Que:%d created.\n", ret);
+ rsp = ha->rsp_q_map[ret];
options = 0;
if (qos & BIT_7)
@@ -759,10 +752,11 @@ qla25xx_create_queues(struct scsi_qla_host *vha, uint8_t qos)
ret = qla25xx_create_req_que(ha, options, vha->vp_idx, 0, ret,
qos & ~BIT_7);
if (ret) {
- vha->req_ques[0] = ret;
+ vha->req = ha->req_q_map[ret];
qla_printk(KERN_INFO, ha, "Request Que:%d created.\n", ret);
} else
qla_printk(KERN_WARNING, ha, "Request Que create failed\n");
+ rsp->req = ha->req_q_map[ret];
return ret;
}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index e4fdcdad80d0..f4f535536952 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -77,6 +77,14 @@ module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xmaxqdepth,
"Maximum queue depth to report for target devices.");
+int ql2xqfulltracking = 1;
+module_param(ql2xqfulltracking, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(ql2xqfulltracking,
+ "Controls whether the driver tracks queue full status "
+ "returns and dynamically adjusts a scsi device's queue "
+ "depth. Default is 1, perform tracking. Set to 0 to "
+ "disable dynamic tracking and adjustment of queue depth.");
+
int ql2xqfullrampup = 120;
module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xqfullrampup,
@@ -96,6 +104,23 @@ MODULE_PARM_DESC(ql2xmaxqueues,
"Enables MQ settings "
"Default is 1 for single queue. Set it to number \
of queues in MQ mode.");
+
+int ql2xmultique_tag;
+module_param(ql2xmultique_tag, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xmultique_tag,
+ "Enables CPU affinity settings for the driver "
+ "Default is 0 for no affinity of request and response IO. "
+ "Set it to 1 to turn on the cpu affinity.");
+
+int ql2xfwloadbin;
+module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xfwloadbin,
+ "Option to specify location from which to load ISP firmware:\n"
+ " 2 -- load firmware via the request_firmware() (hotplug)\n"
+ " interface.\n"
+ " 1 -- load firmware from flash.\n"
+ " 0 -- use default semantics.\n");
+
/*
* SCSI host template entry points
*/
@@ -187,7 +212,7 @@ static void qla2x00_sp_free_dma(srb_t *);
/* -------------------------------------------------------------------------- */
static int qla2x00_alloc_queues(struct qla_hw_data *ha)
{
- ha->req_q_map = kzalloc(sizeof(struct req_que *) * ha->max_queues,
+ ha->req_q_map = kzalloc(sizeof(struct req_que *) * ha->max_req_queues,
GFP_KERNEL);
if (!ha->req_q_map) {
qla_printk(KERN_WARNING, ha,
@@ -195,7 +220,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha)
goto fail_req_map;
}
- ha->rsp_q_map = kzalloc(sizeof(struct rsp_que *) * ha->max_queues,
+ ha->rsp_q_map = kzalloc(sizeof(struct rsp_que *) * ha->max_rsp_queues,
GFP_KERNEL);
if (!ha->rsp_q_map) {
qla_printk(KERN_WARNING, ha,
@@ -213,16 +238,8 @@ fail_req_map:
return -ENOMEM;
}
-static void qla2x00_free_que(struct qla_hw_data *ha, struct req_que *req,
- struct rsp_que *rsp)
+static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req)
{
- if (rsp && rsp->ring)
- dma_free_coherent(&ha->pdev->dev,
- (rsp->length + 1) * sizeof(response_t),
- rsp->ring, rsp->dma);
-
- kfree(rsp);
- rsp = NULL;
if (req && req->ring)
dma_free_coherent(&ha->pdev->dev,
(req->length + 1) * sizeof(request_t),
@@ -232,22 +249,77 @@ static void qla2x00_free_que(struct qla_hw_data *ha, struct req_que *req,
req = NULL;
}
+static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp)
+{
+ if (rsp && rsp->ring)
+ dma_free_coherent(&ha->pdev->dev,
+ (rsp->length + 1) * sizeof(response_t),
+ rsp->ring, rsp->dma);
+
+ kfree(rsp);
+ rsp = NULL;
+}
+
static void qla2x00_free_queues(struct qla_hw_data *ha)
{
struct req_que *req;
struct rsp_que *rsp;
int cnt;
- for (cnt = 0; cnt < ha->max_queues; cnt++) {
- rsp = ha->rsp_q_map[cnt];
+ for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
req = ha->req_q_map[cnt];
- qla2x00_free_que(ha, req, rsp);
+ qla2x00_free_req_que(ha, req);
+ }
+ kfree(ha->req_q_map);
+ ha->req_q_map = NULL;
+
+ for (cnt = 0; cnt < ha->max_rsp_queues; cnt++) {
+ rsp = ha->rsp_q_map[cnt];
+ qla2x00_free_rsp_que(ha, rsp);
}
kfree(ha->rsp_q_map);
ha->rsp_q_map = NULL;
+}
- kfree(ha->req_q_map);
- ha->req_q_map = NULL;
+static int qla25xx_setup_mode(struct scsi_qla_host *vha)
+{
+ uint16_t options = 0;
+ int ques, req, ret;
+ struct qla_hw_data *ha = vha->hw;
+
+ if (ql2xmultique_tag) {
+ /* CPU affinity mode */
+ ha->wq = create_workqueue("qla2xxx_wq");
+ /* create a request queue for IO */
+ options |= BIT_7;
+ req = qla25xx_create_req_que(ha, options, 0, 0, -1,
+ QLA_DEFAULT_QUE_QOS);
+ if (!req) {
+ qla_printk(KERN_WARNING, ha,
+ "Can't create request queue\n");
+ goto fail;
+ }
+ vha->req = ha->req_q_map[req];
+ options |= BIT_1;
+ for (ques = 1; ques < ha->max_rsp_queues; ques++) {
+ ret = qla25xx_create_rsp_que(ha, options, 0, 0, req);
+ if (!ret) {
+ qla_printk(KERN_WARNING, ha,
+ "Response Queue create failed\n");
+ goto fail2;
+ }
+ }
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "CPU affinity mode enabled, no. of response"
+ " queues:%d, no. of request queues:%d\n",
+ ha->max_rsp_queues, ha->max_req_queues));
+ }
+ return 0;
+fail2:
+ qla25xx_delete_queues(vha);
+fail:
+ ha->mqenable = 0;
+ return 1;
}
static char *
@@ -387,7 +459,6 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
sp->fcport = fcport;
sp->cmd = cmd;
- sp->que = ha->req_q_map[0];
sp->flags = 0;
CMD_SP(cmd) = (void *)sp;
cmd->scsi_done = done;
@@ -612,7 +683,7 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *vha)
void
qla2x00_abort_fcport_cmds(fc_port_t *fcport)
{
- int cnt, que, id;
+ int cnt;
unsigned long flags;
srb_t *sp;
scsi_qla_host_t *vha = fcport->vha;
@@ -620,32 +691,27 @@ qla2x00_abort_fcport_cmds(fc_port_t *fcport)
struct req_que *req;
spin_lock_irqsave(&ha->hardware_lock, flags);
- for (que = 0; que < QLA_MAX_HOST_QUES; que++) {
- id = vha->req_ques[que];
- req = ha->req_q_map[id];
- if (!req)
+ req = vha->req;
+ for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
+ sp = req->outstanding_cmds[cnt];
+ if (!sp)
+ continue;
+ if (sp->fcport != fcport)
continue;
- for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
- sp = req->outstanding_cmds[cnt];
- if (!sp)
- continue;
- if (sp->fcport != fcport)
- continue;
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
- if (ha->isp_ops->abort_command(vha, sp, req)) {
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ if (ha->isp_ops->abort_command(sp)) {
+ DEBUG2(qla_printk(KERN_WARNING, ha,
+ "Abort failed -- %lx\n",
+ sp->cmd->serial_number));
+ } else {
+ if (qla2x00_eh_wait_on_command(sp->cmd) !=
+ QLA_SUCCESS)
DEBUG2(qla_printk(KERN_WARNING, ha,
- "Abort failed -- %lx\n",
+ "Abort failed while waiting -- %lx\n",
sp->cmd->serial_number));
- } else {
- if (qla2x00_eh_wait_on_command(sp->cmd) !=
- QLA_SUCCESS)
- DEBUG2(qla_printk(KERN_WARNING, ha,
- "Abort failed while waiting -- %lx\n",
- sp->cmd->serial_number));
- }
- spin_lock_irqsave(&ha->hardware_lock, flags);
}
+ spin_lock_irqsave(&ha->hardware_lock, flags);
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
@@ -693,7 +759,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
unsigned long flags;
int wait = 0;
struct qla_hw_data *ha = vha->hw;
- struct req_que *req;
+ struct req_que *req = vha->req;
srb_t *spt;
qla2x00_block_error_handler(cmd);
@@ -709,7 +775,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
spt = (srb_t *) CMD_SP(cmd);
if (!spt)
return SUCCESS;
- req = spt->que;
/* Check active list for command command. */
spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -726,7 +791,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
" pid=%ld.\n", __func__, vha->host_no, sp, serial));
spin_unlock_irqrestore(&ha->hardware_lock, flags);
- if (ha->isp_ops->abort_command(vha, sp, req)) {
+ if (ha->isp_ops->abort_command(sp)) {
DEBUG2(printk("%s(%ld): abort_command "
"mbx failed.\n", __func__, vha->host_no));
ret = FAILED;
@@ -777,7 +842,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
return status;
spin_lock_irqsave(&ha->hardware_lock, flags);
- req = sp->que;
+ req = vha->req;
for (cnt = 1; status == QLA_SUCCESS &&
cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
sp = req->outstanding_cmds[cnt];
@@ -820,7 +885,7 @@ static char *reset_errors[] = {
static int
__qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
- struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int))
+ struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int, int))
{
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
@@ -841,7 +906,8 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
if (qla2x00_wait_for_loop_ready(vha) != QLA_SUCCESS)
goto eh_reset_failed;
err = 2;
- if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS)
+ if (do_reset(fcport, cmd->device->lun, cmd->request->cpu + 1)
+ != QLA_SUCCESS)
goto eh_reset_failed;
err = 3;
if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id,
@@ -996,6 +1062,9 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
if (qla2x00_vp_abort_isp(vha))
goto eh_host_reset_lock;
} else {
+ if (ha->wq)
+ flush_workqueue(ha->wq);
+
set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
if (qla2x00_abort_isp(base_vha)) {
clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
@@ -1037,7 +1106,8 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
struct fc_port *fcport;
struct qla_hw_data *ha = vha->hw;
- if (ha->flags.enable_lip_full_login && !vha->vp_idx) {
+ if (ha->flags.enable_lip_full_login && !vha->vp_idx &&
+ !IS_QLA81XX(ha)) {
ret = qla2x00_full_login_lip(vha);
if (ret != QLA_SUCCESS) {
DEBUG2_3(printk("%s(%ld): failed: "
@@ -1064,7 +1134,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
if (fcport->port_type != FCT_TARGET)
continue;
- ret = ha->isp_ops->target_reset(fcport, 0);
+ ret = ha->isp_ops->target_reset(fcport, 0, 0);
if (ret != QLA_SUCCESS) {
DEBUG2_3(printk("%s(%ld): bus_reset failed: "
"target_reset=%d d_id=%x.\n", __func__,
@@ -1088,7 +1158,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
struct req_que *req;
spin_lock_irqsave(&ha->hardware_lock, flags);
- for (que = 0; que < ha->max_queues; que++) {
+ for (que = 0; que < ha->max_req_queues; que++) {
req = ha->req_q_map[que];
if (!req)
continue;
@@ -1123,7 +1193,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
scsi_qla_host_t *vha = shost_priv(sdev->host);
struct qla_hw_data *ha = vha->hw;
struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
- struct req_que *req = ha->req_q_map[vha->req_ques[0]];
+ struct req_que *req = vha->req;
if (sdev->tagged_supported)
scsi_activate_tcq(sdev, req->max_q_depth);
@@ -1511,6 +1581,13 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha)
ha->fw_srisc_address = RISC_START_ADDRESS_2400;
break;
}
+
+ /* Get adapter physical port no from interrupt pin register. */
+ pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &ha->port_no);
+ if (ha->port_no & 1)
+ ha->flags.port0 = 1;
+ else
+ ha->flags.port0 = 0;
}
static int
@@ -1518,6 +1595,7 @@ qla2x00_iospace_config(struct qla_hw_data *ha)
{
resource_size_t pio;
uint16_t msix;
+ int cpus;
if (pci_request_selected_regions(ha->pdev, ha->bars,
QLA2XXX_DRIVER_NAME)) {
@@ -1571,8 +1649,9 @@ skip_pio:
}
/* Determine queue resources */
- ha->max_queues = 1;
- if (ql2xmaxqueues <= 1 || (!IS_QLA25XX(ha) && !IS_QLA81XX(ha)))
+ ha->max_req_queues = ha->max_rsp_queues = 1;
+ if ((ql2xmaxqueues <= 1 || ql2xmultique_tag < 1) &&
+ (!IS_QLA25XX(ha) && !IS_QLA81XX(ha)))
goto mqiobase_exit;
ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
pci_resource_len(ha->pdev, 3));
@@ -1582,18 +1661,24 @@ skip_pio:
ha->msix_count = msix;
/* Max queues are bounded by available msix vectors */
/* queue 0 uses two msix vectors */
- if (ha->msix_count - 1 < ql2xmaxqueues)
- ha->max_queues = ha->msix_count - 1;
- else if (ql2xmaxqueues > QLA_MQ_SIZE)
- ha->max_queues = QLA_MQ_SIZE;
- else
- ha->max_queues = ql2xmaxqueues;
+ if (ql2xmultique_tag) {
+ cpus = num_online_cpus();
+ ha->max_rsp_queues = (ha->msix_count - 1 - cpus) ?
+ (cpus + 1) : (ha->msix_count - 1);
+ ha->max_req_queues = 2;
+ } else if (ql2xmaxqueues > 1) {
+ ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ?
+ QLA_MQ_SIZE : ql2xmaxqueues;
+ DEBUG2(qla_printk(KERN_INFO, ha, "QoS mode set, max no"
+ " of request queues:%d\n", ha->max_req_queues));
+ }
qla_printk(KERN_INFO, ha,
"MSI-X vector count: %d\n", msix);
- }
+ } else
+ qla_printk(KERN_INFO, ha, "BAR 3 not enabled\n");
mqiobase_exit:
- ha->msix_count = ha->max_queues + 1;
+ ha->msix_count = ha->max_rsp_queues + 1;
return (0);
iospace_error_exit:
@@ -1803,14 +1888,15 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ret = -ENOMEM;
qla2x00_mem_free(ha);
- qla2x00_free_que(ha, req, rsp);
+ qla2x00_free_req_que(ha, req);
+ qla2x00_free_rsp_que(ha, rsp);
goto probe_hw_failed;
}
pci_set_drvdata(pdev, base_vha);
host = base_vha->host;
- base_vha->req_ques[0] = req->id;
+ base_vha->req = req;
host->can_queue = req->length + 128;
if (IS_QLA2XXX_MIDTYPE(ha))
base_vha->mgmt_svr_loop_id = 10 + base_vha->vp_idx;
@@ -1841,7 +1927,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
}
ha->rsp_q_map[0] = rsp;
ha->req_q_map[0] = req;
-
+ rsp->req = req;
+ req->rsp = rsp;
+ set_bit(0, ha->req_qid_map);
+ set_bit(0, ha->rsp_qid_map);
/* FWI2-capable only. */
req->req_q_in = &ha->iobase->isp24.req_q_in;
req->req_q_out = &ha->iobase->isp24.req_q_out;
@@ -1866,6 +1955,12 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
goto probe_failed;
}
+ if (ha->mqenable)
+ if (qla25xx_setup_mode(base_vha))
+ qla_printk(KERN_WARNING, ha,
+ "Can't create queues, falling back to single"
+ " queue mode\n");
+
/*
* Startup the kernel thread for this host adapter
*/
@@ -1917,8 +2012,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
probe_init_failed:
- qla2x00_free_que(ha, req, rsp);
- ha->max_queues = 0;
+ qla2x00_free_req_que(ha, req);
+ qla2x00_free_rsp_que(ha, rsp);
+ ha->max_req_queues = ha->max_rsp_queues = 0;
probe_failed:
if (base_vha->timer_active)
@@ -1976,6 +2072,13 @@ qla2x00_remove_one(struct pci_dev *pdev)
base_vha->flags.online = 0;
+ /* Flush the work queue and remove it */
+ if (ha->wq) {
+ flush_workqueue(ha->wq);
+ destroy_workqueue(ha->wq);
+ ha->wq = NULL;
+ }
+
/* Kill the kernel thread for this host */
if (ha->dpc_thread) {
struct task_struct *t = ha->dpc_thread;
@@ -2017,6 +2120,8 @@ qla2x00_free_device(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
+ qla25xx_delete_queues(vha);
+
if (ha->flags.fce_enabled)
qla2x00_disable_fce_trace(vha, NULL, NULL);
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 152ecfc26cd2..22f97eb50cf9 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -219,8 +219,8 @@ qla2x00_write_nvram_word(struct qla_hw_data *ha, uint32_t addr, uint16_t data)
wait_cnt = NVR_WAIT_CNT;
do {
if (!--wait_cnt) {
- DEBUG9_10(printk("%s(%ld): NVRAM didn't go ready...\n",
- __func__, vha->host_no));
+ DEBUG9_10(qla_printk(KERN_WARNING, ha,
+ "NVRAM didn't go ready...\n"));
break;
}
NVRAM_DELAY();
@@ -349,7 +349,7 @@ qla2x00_clear_nvram_protection(struct qla_hw_data *ha)
wait_cnt = NVR_WAIT_CNT;
do {
if (!--wait_cnt) {
- DEBUG9_10(qla_printk(
+ DEBUG9_10(qla_printk(KERN_WARNING, ha,
"NVRAM didn't go ready...\n"));
break;
}
@@ -408,7 +408,8 @@ qla2x00_set_nvram_protection(struct qla_hw_data *ha, int stat)
wait_cnt = NVR_WAIT_CNT;
do {
if (!--wait_cnt) {
- DEBUG9_10(qla_printk("NVRAM didn't go ready...\n"));
+ DEBUG9_10(qla_printk(KERN_WARNING, ha,
+ "NVRAM didn't go ready...\n"));
break;
}
NVRAM_DELAY();
@@ -701,30 +702,30 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
break;
case FLT_REG_VPD_0:
ha->flt_region_vpd_nvram = start;
- if (!(PCI_FUNC(ha->pdev->devfn) & 1))
+ if (ha->flags.port0)
ha->flt_region_vpd = start;
break;
case FLT_REG_VPD_1:
- if (PCI_FUNC(ha->pdev->devfn) & 1)
+ if (!ha->flags.port0)
ha->flt_region_vpd = start;
break;
case FLT_REG_NVRAM_0:
- if (!(PCI_FUNC(ha->pdev->devfn) & 1))
+ if (ha->flags.port0)
ha->flt_region_nvram = start;
break;
case FLT_REG_NVRAM_1:
- if (PCI_FUNC(ha->pdev->devfn) & 1)
+ if (!ha->flags.port0)
ha->flt_region_nvram = start;
break;
case FLT_REG_FDT:
ha->flt_region_fdt = start;
break;
case FLT_REG_NPIV_CONF_0:
- if (!(PCI_FUNC(ha->pdev->devfn) & 1))
+ if (ha->flags.port0)
ha->flt_region_npiv_conf = start;
break;
case FLT_REG_NPIV_CONF_1:
- if (PCI_FUNC(ha->pdev->devfn) & 1)
+ if (!ha->flags.port0)
ha->flt_region_npiv_conf = start;
break;
}
@@ -744,12 +745,12 @@ no_flash_data:
ha->flt_region_fw = def_fw[def];
ha->flt_region_boot = def_boot[def];
ha->flt_region_vpd_nvram = def_vpd_nvram[def];
- ha->flt_region_vpd = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
+ ha->flt_region_vpd = ha->flags.port0 ?
def_vpd0[def]: def_vpd1[def];
- ha->flt_region_nvram = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
+ ha->flt_region_nvram = ha->flags.port0 ?
def_nvram0[def]: def_nvram1[def];
ha->flt_region_fdt = def_fdt[def];
- ha->flt_region_npiv_conf = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
+ ha->flt_region_npiv_conf = ha->flags.port0 ?
def_npiv_conf0[def]: def_npiv_conf1[def];
done:
DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x "
@@ -919,6 +920,7 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha)
entry = data + sizeof(struct qla_npiv_header);
cnt = le16_to_cpu(hdr.entries);
+ ha->flex_port_count = cnt;
for (i = 0; cnt; cnt--, entry++, i++) {
uint16_t flags;
struct fc_vport_identifiers vid;
@@ -1079,8 +1081,9 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
0xff0000) | ((fdata >> 16) & 0xff));
ret = qla24xx_erase_sector(vha, fdata);
if (ret != QLA_SUCCESS) {
- DEBUG9(qla_printk("Unable to erase sector: "
- "address=%x.\n", faddr));
+ DEBUG9(qla_printk(KERN_WARNING, ha,
+ "Unable to erase sector: address=%x.\n",
+ faddr));
break;
}
}
@@ -1240,8 +1243,9 @@ qla24xx_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr,
ret = qla24xx_write_flash_dword(ha,
nvram_data_addr(ha, naddr), cpu_to_le32(*dwptr));
if (ret != QLA_SUCCESS) {
- DEBUG9(qla_printk("Unable to program nvram address=%x "
- "data=%x.\n", naddr, *dwptr));
+ DEBUG9(qla_printk(KERN_WARNING, ha,
+ "Unable to program nvram address=%x data=%x.\n",
+ naddr, *dwptr));
break;
}
}
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 19d1afc3a343..a1094e7d2b44 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.01-k1"
+#define QLA2XXX_VERSION "8.03.01-k2"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index bb218c8b6e98..00968a5aaebc 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -240,11 +240,11 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
* is invalid. Prevent the garbage from being misinterpreted
* and prevent security leaks by zeroing out the excess data.
*/
- if (unlikely(req->data_len > 0 && req->data_len <= bufflen))
- memset(buffer + (bufflen - req->data_len), 0, req->data_len);
+ if (unlikely(req->resid_len > 0 && req->resid_len <= bufflen))
+ memset(buffer + (bufflen - req->resid_len), 0, req->resid_len);
if (resid)
- *resid = req->data_len;
+ *resid = req->resid_len;
ret = req->errors;
out:
blk_put_request(req);
@@ -546,14 +546,9 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
* to queue the remainder of them.
*/
if (blk_end_request(req, error, bytes)) {
- int leftover = (req->hard_nr_sectors << 9);
-
- if (blk_pc_request(req))
- leftover = req->data_len;
-
/* kill remainder if no retrys */
if (error && scsi_noretry_cmd(cmd))
- blk_end_request(req, error, leftover);
+ blk_end_request_all(req, error);
else {
if (requeue) {
/*
@@ -673,34 +668,6 @@ void scsi_release_buffers(struct scsi_cmnd *cmd)
EXPORT_SYMBOL(scsi_release_buffers);
/*
- * Bidi commands Must be complete as a whole, both sides at once.
- * If part of the bytes were written and lld returned
- * scsi_in()->resid and/or scsi_out()->resid this information will be left
- * in req->data_len and req->next_rq->data_len. The upper-layer driver can
- * decide what to do with this information.
- */
-static void scsi_end_bidi_request(struct scsi_cmnd *cmd)
-{
- struct request *req = cmd->request;
- unsigned int dlen = req->data_len;
- unsigned int next_dlen = req->next_rq->data_len;
-
- req->data_len = scsi_out(cmd)->resid;
- req->next_rq->data_len = scsi_in(cmd)->resid;
-
- /* The req and req->next_rq have not been completed */
- BUG_ON(blk_end_bidi_request(req, 0, dlen, next_dlen));
-
- scsi_release_buffers(cmd);
-
- /*
- * This will goose the queue request function at the end, so we don't
- * need to worry about launching another command.
- */
- scsi_next_command(cmd);
-}
-
-/*
* Function: scsi_io_completion()
*
* Purpose: Completion processing for block device I/O requests.
@@ -773,12 +740,22 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
if (!sense_deferred)
error = -EIO;
}
+
+ req->resid_len = scsi_get_resid(cmd);
+
if (scsi_bidi_cmnd(cmd)) {
- /* will also release_buffers */
- scsi_end_bidi_request(cmd);
+ /*
+ * Bidi commands Must be complete as a whole,
+ * both sides at once.
+ */
+ req->next_rq->resid_len = scsi_in(cmd)->resid;
+
+ blk_end_request_all(req, 0);
+
+ scsi_release_buffers(cmd);
+ scsi_next_command(cmd);
return;
}
- req->data_len = scsi_get_resid(cmd);
}
BUG_ON(blk_bidi_rq(req)); /* bidi not support for !blk_pc_request yet */
@@ -787,9 +764,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
* Next deal with any sectors which we were able to correctly
* handle.
*/
- SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, "
+ SCSI_LOG_HLCOMPLETE(1, printk("%u sectors total, "
"%d bytes done.\n",
- req->nr_sectors, good_bytes));
+ blk_rq_sectors(req), good_bytes));
/*
* Recovered errors need reporting, but they're always treated
@@ -922,7 +899,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
if (driver_byte(result) & DRIVER_SENSE)
scsi_print_sense("", cmd);
}
- blk_end_request(req, -EIO, blk_rq_bytes(req));
+ blk_end_request_all(req, -EIO);
scsi_next_command(cmd);
break;
case ACTION_REPREP:
@@ -965,10 +942,7 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
count = blk_rq_map_sg(req->q, req, sdb->table.sgl);
BUG_ON(count > sdb->table.nents);
sdb->table.nents = count;
- if (blk_pc_request(req))
- sdb->length = req->data_len;
- else
- sdb->length = req->nr_sectors << 9;
+ sdb->length = blk_rq_bytes(req);
return BLKPREP_OK;
}
@@ -1087,22 +1061,21 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
if (unlikely(ret))
return ret;
} else {
- BUG_ON(req->data_len);
- BUG_ON(req->data);
+ BUG_ON(blk_rq_bytes(req));
memset(&cmd->sdb, 0, sizeof(cmd->sdb));
req->buffer = NULL;
}
cmd->cmd_len = req->cmd_len;
- if (!req->data_len)
+ if (!blk_rq_bytes(req))
cmd->sc_data_direction = DMA_NONE;
else if (rq_data_dir(req) == WRITE)
cmd->sc_data_direction = DMA_TO_DEVICE;
else
cmd->sc_data_direction = DMA_FROM_DEVICE;
- cmd->transfersize = req->data_len;
+ cmd->transfersize = blk_rq_bytes(req);
cmd->allowed = req->retries;
return BLKPREP_OK;
}
@@ -1212,7 +1185,7 @@ int scsi_prep_return(struct request_queue *q, struct request *req, int ret)
break;
case BLKPREP_DEFER:
/*
- * If we defer, the elv_next_request() returns NULL, but the
+ * If we defer, the blk_peek_request() returns NULL, but the
* queue must be restarted, so we plug here if no returning
* command will automatically do that.
*/
@@ -1388,7 +1361,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
struct scsi_target *starget = scsi_target(sdev);
struct Scsi_Host *shost = sdev->host;
- blkdev_dequeue_request(req);
+ blk_start_request(req);
if (unlikely(cmd == NULL)) {
printk(KERN_CRIT "impossible request in %s.\n",
@@ -1480,7 +1453,7 @@ static void scsi_request_fn(struct request_queue *q)
if (!sdev) {
printk("scsi: killing requests for dead queue\n");
- while ((req = elv_next_request(q)) != NULL)
+ while ((req = blk_peek_request(q)) != NULL)
scsi_kill_request(req, q);
return;
}
@@ -1501,7 +1474,7 @@ static void scsi_request_fn(struct request_queue *q)
* that the request is fully prepared even if we cannot
* accept it.
*/
- req = elv_next_request(q);
+ req = blk_peek_request(q);
if (!req || !scsi_dev_queue_ready(q, sdev))
break;
@@ -1517,7 +1490,7 @@ static void scsi_request_fn(struct request_queue *q)
* Remove the request from the request list.
*/
if (!(blk_queue_tagged(q) && !blk_queue_start_tag(q, req)))
- blkdev_dequeue_request(req);
+ blk_start_request(req);
sdev->device_busy++;
spin_unlock(q->queue_lock);
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 48ba413f7f6a..10303272ba45 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -387,7 +387,7 @@ static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd,
* we use REQ_TYPE_BLOCK_PC so scsi_init_io doesn't set the
* length for us.
*/
- cmd->sdb.length = rq->data_len;
+ cmd->sdb.length = blk_rq_bytes(rq);
return 0;
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index a152f89ae51c..c8b8fb7ba3ed 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -35,6 +35,7 @@
#include <linux/netlink.h>
#include <net/netlink.h>
#include <scsi/scsi_netlink_fc.h>
+#include <scsi/scsi_bsg_fc.h>
#include "scsi_priv.h"
#include "scsi_transport_fc_internal.h"
@@ -43,6 +44,10 @@ static void fc_vport_sched_delete(struct work_struct *work);
static int fc_vport_setup(struct Scsi_Host *shost, int channel,
struct device *pdev, struct fc_vport_identifiers *ids,
struct fc_vport **vport);
+static int fc_bsg_hostadd(struct Scsi_Host *, struct fc_host_attrs *);
+static int fc_bsg_rportadd(struct Scsi_Host *, struct fc_rport *);
+static void fc_bsg_remove(struct request_queue *);
+static void fc_bsg_goose_queue(struct fc_rport *);
/*
* Redefine so that we can have same named attributes in the
@@ -411,13 +416,26 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
return -ENOMEM;
}
+ fc_bsg_hostadd(shost, fc_host);
+ /* ignore any bsg add error - we just can't do sgio */
+
+ return 0;
+}
+
+static int fc_host_remove(struct transport_container *tc, struct device *dev,
+ struct device *cdev)
+{
+ struct Scsi_Host *shost = dev_to_shost(dev);
+ struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+
+ fc_bsg_remove(fc_host->rqst_q);
return 0;
}
static DECLARE_TRANSPORT_CLASS(fc_host_class,
"fc_host",
fc_host_setup,
- NULL,
+ fc_host_remove,
NULL);
/*
@@ -2375,6 +2393,7 @@ fc_rport_final_delete(struct work_struct *work)
scsi_flush_work(shost);
fc_terminate_rport_io(rport);
+
/*
* Cancel any outstanding timers. These should really exist
* only when rmmod'ing the LLDD and we're asking for
@@ -2407,6 +2426,8 @@ fc_rport_final_delete(struct work_struct *work)
(i->f->dev_loss_tmo_callbk))
i->f->dev_loss_tmo_callbk(rport);
+ fc_bsg_remove(rport->rqst_q);
+
transport_remove_device(dev);
device_del(dev);
transport_destroy_device(dev);
@@ -2494,6 +2515,9 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
transport_add_device(dev);
transport_configure_device(dev);
+ fc_bsg_rportadd(shost, rport);
+ /* ignore any bsg add error - we just can't do sgio */
+
if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
/* initiate a scan of the target */
rport->flags |= FC_RPORT_SCAN_PENDING;
@@ -2658,6 +2682,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
spin_unlock_irqrestore(shost->host_lock,
flags);
+ fc_bsg_goose_queue(rport);
+
return rport;
}
}
@@ -3343,6 +3369,594 @@ fc_vport_sched_delete(struct work_struct *work)
}
+/*
+ * BSG support
+ */
+
+
+/**
+ * fc_destroy_bsgjob - routine to teardown/delete a fc bsg job
+ * @job: fc_bsg_job that is to be torn down
+ */
+static void
+fc_destroy_bsgjob(struct fc_bsg_job *job)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&job->job_lock, flags);
+ if (job->ref_cnt) {
+ spin_unlock_irqrestore(&job->job_lock, flags);
+ return;
+ }
+ spin_unlock_irqrestore(&job->job_lock, flags);
+
+ put_device(job->dev); /* release reference for the request */
+
+ kfree(job->request_payload.sg_list);
+ kfree(job->reply_payload.sg_list);
+ kfree(job);
+}
+
+
+/**
+ * fc_bsg_jobdone - completion routine for bsg requests that the LLD has
+ * completed
+ * @job: fc_bsg_job that is complete
+ */
+static void
+fc_bsg_jobdone(struct fc_bsg_job *job)
+{
+ struct request *req = job->req;
+ struct request *rsp = req->next_rq;
+ unsigned long flags;
+ unsigned rsp_len = 0, req_len = blk_rq_bytes(req);
+ int err;
+
+ spin_lock_irqsave(&job->job_lock, flags);
+ job->state_flags |= FC_RQST_STATE_DONE;
+ job->ref_cnt--;
+ spin_unlock_irqrestore(&job->job_lock, flags);
+
+ err = job->req->errors = job->reply->result;
+ if (err < 0)
+ /* we're only returning the result field in the reply */
+ job->req->sense_len = sizeof(uint32_t);
+ else
+ job->req->sense_len = job->reply_len;
+
+ /* we assume all request payload was transferred, residual == 0 */
+ req->__data_len = 0;
+
+ if (rsp) {
+ rsp_len = blk_rq_bytes(rsp);
+ BUG_ON(job->reply->reply_payload_rcv_len > rsp_len);
+ /* set reply (bidi) residual */
+ rsp->__data_len = (rsp_len - job->reply->reply_payload_rcv_len);
+ }
+
+ blk_end_bidi_request(req, err, req_len, rsp_len);
+
+ fc_destroy_bsgjob(job);
+}
+
+
+/**
+ * fc_bsg_job_timeout - handler for when a bsg request timesout
+ * @req: request that timed out
+ */
+static enum blk_eh_timer_return
+fc_bsg_job_timeout(struct request *req)
+{
+ struct fc_bsg_job *job = (void *) req->special;
+ struct Scsi_Host *shost = job->shost;
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ unsigned long flags;
+ int err = 0, done = 0;
+
+ if (job->rport && job->rport->port_state == FC_PORTSTATE_BLOCKED)
+ return BLK_EH_RESET_TIMER;
+
+ spin_lock_irqsave(&job->job_lock, flags);
+ if (job->state_flags & FC_RQST_STATE_DONE)
+ done = 1;
+ else
+ job->ref_cnt++;
+ spin_unlock_irqrestore(&job->job_lock, flags);
+
+ if (!done && i->f->bsg_timeout) {
+ /* call LLDD to abort the i/o as it has timed out */
+ err = i->f->bsg_timeout(job);
+ if (err)
+ printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
+ "abort failed with status %d\n", err);
+ }
+
+ if (!done) {
+ spin_lock_irqsave(&job->job_lock, flags);
+ job->ref_cnt--;
+ spin_unlock_irqrestore(&job->job_lock, flags);
+ fc_destroy_bsgjob(job);
+ }
+
+ /* the blk_end_sync_io() doesn't check the error */
+ return BLK_EH_HANDLED;
+}
+
+
+
+static int
+fc_bsg_map_buffer(struct fc_bsg_buffer *buf, struct request *req)
+{
+ size_t sz = (sizeof(struct scatterlist) * req->nr_phys_segments);
+
+ BUG_ON(!req->nr_phys_segments);
+
+ buf->sg_list = kzalloc(sz, GFP_KERNEL);
+ if (!buf->sg_list)
+ return -ENOMEM;
+ sg_init_table(buf->sg_list, req->nr_phys_segments);
+ buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list);
+ buf->payload_len = blk_rq_bytes(req);
+ return 0;
+}
+
+
+/**
+ * fc_req_to_bsgjob - Allocate/create the fc_bsg_job structure for the
+ * bsg request
+ * @shost: SCSI Host corresponding to the bsg object
+ * @rport: (optional) FC Remote Port corresponding to the bsg object
+ * @req: BSG request that needs a job structure
+ */
+static int
+fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
+ struct request *req)
+{
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ struct request *rsp = req->next_rq;
+ struct fc_bsg_job *job;
+ int ret;
+
+ BUG_ON(req->special);
+
+ job = kzalloc(sizeof(struct fc_bsg_job) + i->f->dd_bsg_size,
+ GFP_KERNEL);
+ if (!job)
+ return -ENOMEM;
+
+ /*
+ * Note: this is a bit silly.
+ * The request gets formatted as a SGIO v4 ioctl request, which
+ * then gets reformatted as a blk request, which then gets
+ * reformatted as a fc bsg request. And on completion, we have
+ * to wrap return results such that SGIO v4 thinks it was a scsi
+ * status. I hope this was all worth it.
+ */
+
+ req->special = job;
+ job->shost = shost;
+ job->rport = rport;
+ job->req = req;
+ if (i->f->dd_bsg_size)
+ job->dd_data = (void *)&job[1];
+ spin_lock_init(&job->job_lock);
+ job->request = (struct fc_bsg_request *)req->cmd;
+ job->request_len = req->cmd_len;
+ job->reply = req->sense;
+ job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
+ * allocated */
+ if (req->bio) {
+ ret = fc_bsg_map_buffer(&job->request_payload, req);
+ if (ret)
+ goto failjob_rls_job;
+ }
+ if (rsp && rsp->bio) {
+ ret = fc_bsg_map_buffer(&job->reply_payload, rsp);
+ if (ret)
+ goto failjob_rls_rqst_payload;
+ }
+ job->job_done = fc_bsg_jobdone;
+ if (rport)
+ job->dev = &rport->dev;
+ else
+ job->dev = &shost->shost_gendev;
+ get_device(job->dev); /* take a reference for the request */
+
+ job->ref_cnt = 1;
+
+ return 0;
+
+
+failjob_rls_rqst_payload:
+ kfree(job->request_payload.sg_list);
+failjob_rls_job:
+ kfree(job);
+ return -ENOMEM;
+}
+
+
+enum fc_dispatch_result {
+ FC_DISPATCH_BREAK, /* on return, q is locked, break from q loop */
+ FC_DISPATCH_LOCKED, /* on return, q is locked, continue on */
+ FC_DISPATCH_UNLOCKED, /* on return, q is unlocked, continue on */
+};
+
+
+/**
+ * fc_bsg_host_dispatch - process fc host bsg requests and dispatch to LLDD
+ * @shost: scsi host rport attached to
+ * @job: bsg job to be processed
+ */
+static enum fc_dispatch_result
+fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
+ struct fc_bsg_job *job)
+{
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ int cmdlen = sizeof(uint32_t); /* start with length of msgcode */
+ int ret;
+
+ /* Validate the host command */
+ switch (job->request->msgcode) {
+ case FC_BSG_HST_ADD_RPORT:
+ cmdlen += sizeof(struct fc_bsg_host_add_rport);
+ break;
+
+ case FC_BSG_HST_DEL_RPORT:
+ cmdlen += sizeof(struct fc_bsg_host_del_rport);
+ break;
+
+ case FC_BSG_HST_ELS_NOLOGIN:
+ cmdlen += sizeof(struct fc_bsg_host_els);
+ /* there better be a xmt and rcv payloads */
+ if ((!job->request_payload.payload_len) ||
+ (!job->reply_payload.payload_len)) {
+ ret = -EINVAL;
+ goto fail_host_msg;
+ }
+ break;
+
+ case FC_BSG_HST_CT:
+ cmdlen += sizeof(struct fc_bsg_host_ct);
+ /* there better be xmt and rcv payloads */
+ if ((!job->request_payload.payload_len) ||
+ (!job->reply_payload.payload_len)) {
+ ret = -EINVAL;
+ goto fail_host_msg;
+ }
+ break;
+
+ case FC_BSG_HST_VENDOR:
+ cmdlen += sizeof(struct fc_bsg_host_vendor);
+ if ((shost->hostt->vendor_id == 0L) ||
+ (job->request->rqst_data.h_vendor.vendor_id !=
+ shost->hostt->vendor_id)) {
+ ret = -ESRCH;
+ goto fail_host_msg;
+ }
+ break;
+
+ default:
+ ret = -EBADR;
+ goto fail_host_msg;
+ }
+
+ /* check if we really have all the request data needed */
+ if (job->request_len < cmdlen) {
+ ret = -ENOMSG;
+ goto fail_host_msg;
+ }
+
+ ret = i->f->bsg_request(job);
+ if (!ret)
+ return FC_DISPATCH_UNLOCKED;
+
+fail_host_msg:
+ /* return the errno failure code as the only status */
+ BUG_ON(job->reply_len < sizeof(uint32_t));
+ job->reply->result = ret;
+ job->reply_len = sizeof(uint32_t);
+ fc_bsg_jobdone(job);
+ return FC_DISPATCH_UNLOCKED;
+}
+
+
+/*
+ * fc_bsg_goose_queue - restart rport queue in case it was stopped
+ * @rport: rport to be restarted
+ */
+static void
+fc_bsg_goose_queue(struct fc_rport *rport)
+{
+ int flagset;
+
+ if (!rport->rqst_q)
+ return;
+
+ get_device(&rport->dev);
+
+ spin_lock(rport->rqst_q->queue_lock);
+ flagset = test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags) &&
+ !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags);
+ if (flagset)
+ queue_flag_set(QUEUE_FLAG_REENTER, rport->rqst_q);
+ __blk_run_queue(rport->rqst_q);
+ if (flagset)
+ queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q);
+ spin_unlock(rport->rqst_q->queue_lock);
+
+ put_device(&rport->dev);
+}
+
+
+/**
+ * fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD
+ * @shost: scsi host rport attached to
+ * @rport: rport request destined to
+ * @job: bsg job to be processed
+ */
+static enum fc_dispatch_result
+fc_bsg_rport_dispatch(struct request_queue *q, struct Scsi_Host *shost,
+ struct fc_rport *rport, struct fc_bsg_job *job)
+{
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ int cmdlen = sizeof(uint32_t); /* start with length of msgcode */
+ int ret;
+
+ /* Validate the rport command */
+ switch (job->request->msgcode) {
+ case FC_BSG_RPT_ELS:
+ cmdlen += sizeof(struct fc_bsg_rport_els);
+ goto check_bidi;
+
+ case FC_BSG_RPT_CT:
+ cmdlen += sizeof(struct fc_bsg_rport_ct);
+check_bidi:
+ /* there better be xmt and rcv payloads */
+ if ((!job->request_payload.payload_len) ||
+ (!job->reply_payload.payload_len)) {
+ ret = -EINVAL;
+ goto fail_rport_msg;
+ }
+ break;
+ default:
+ ret = -EBADR;
+ goto fail_rport_msg;
+ }
+
+ /* check if we really have all the request data needed */
+ if (job->request_len < cmdlen) {
+ ret = -ENOMSG;
+ goto fail_rport_msg;
+ }
+
+ ret = i->f->bsg_request(job);
+ if (!ret)
+ return FC_DISPATCH_UNLOCKED;
+
+fail_rport_msg:
+ /* return the errno failure code as the only status */
+ BUG_ON(job->reply_len < sizeof(uint32_t));
+ job->reply->result = ret;
+ job->reply_len = sizeof(uint32_t);
+ fc_bsg_jobdone(job);
+ return FC_DISPATCH_UNLOCKED;
+}
+
+
+/**
+ * fc_bsg_request_handler - generic handler for bsg requests
+ * @q: request queue to manage
+ * @shost: Scsi_Host related to the bsg object
+ * @rport: FC remote port related to the bsg object (optional)
+ * @dev: device structure for bsg object
+ */
+static void
+fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
+ struct fc_rport *rport, struct device *dev)
+{
+ struct request *req;
+ struct fc_bsg_job *job;
+ enum fc_dispatch_result ret;
+
+ if (!get_device(dev))
+ return;
+
+ while (!blk_queue_plugged(q)) {
+ req = blk_peek_request(q);
+ if (!req)
+ break;
+
+ if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED))
+ break;
+
+ blk_start_request(req);
+
+ if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) {
+ req->errors = -ENXIO;
+ spin_unlock_irq(q->queue_lock);
+ blk_end_request(req, -ENXIO, blk_rq_bytes(req));
+ spin_lock_irq(q->queue_lock);
+ continue;
+ }
+
+ spin_unlock_irq(q->queue_lock);
+
+ ret = fc_req_to_bsgjob(shost, rport, req);
+ if (ret) {
+ req->errors = ret;
+ blk_end_request(req, ret, blk_rq_bytes(req));
+ spin_lock_irq(q->queue_lock);
+ continue;
+ }
+
+ job = req->special;
+
+ /* check if we have the msgcode value at least */
+ if (job->request_len < sizeof(uint32_t)) {
+ BUG_ON(job->reply_len < sizeof(uint32_t));
+ job->reply->result = -ENOMSG;
+ job->reply_len = sizeof(uint32_t);
+ fc_bsg_jobdone(job);
+ spin_lock_irq(q->queue_lock);
+ continue;
+ }
+
+ /* the dispatch routines will unlock the queue_lock */
+ if (rport)
+ ret = fc_bsg_rport_dispatch(q, shost, rport, job);
+ else
+ ret = fc_bsg_host_dispatch(q, shost, job);
+
+ /* did dispatcher hit state that can't process any more */
+ if (ret == FC_DISPATCH_BREAK)
+ break;
+
+ /* did dispatcher had released the lock */
+ if (ret == FC_DISPATCH_UNLOCKED)
+ spin_lock_irq(q->queue_lock);
+ }
+
+ spin_unlock_irq(q->queue_lock);
+ put_device(dev);
+ spin_lock_irq(q->queue_lock);
+}
+
+
+/**
+ * fc_bsg_host_handler - handler for bsg requests for a fc host
+ * @q: fc host request queue
+ */
+static void
+fc_bsg_host_handler(struct request_queue *q)
+{
+ struct Scsi_Host *shost = q->queuedata;
+
+ fc_bsg_request_handler(q, shost, NULL, &shost->shost_gendev);
+}
+
+
+/**
+ * fc_bsg_rport_handler - handler for bsg requests for a fc rport
+ * @q: rport request queue
+ */
+static void
+fc_bsg_rport_handler(struct request_queue *q)
+{
+ struct fc_rport *rport = q->queuedata;
+ struct Scsi_Host *shost = rport_to_shost(rport);
+
+ fc_bsg_request_handler(q, shost, rport, &rport->dev);
+}
+
+
+/**
+ * fc_bsg_hostadd - Create and add the bsg hooks so we can receive requests
+ * @shost: shost for fc_host
+ * @fc_host: fc_host adding the structures to
+ */
+static int
+fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host)
+{
+ struct device *dev = &shost->shost_gendev;
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ struct request_queue *q;
+ int err;
+ char bsg_name[BUS_ID_SIZE]; /*20*/
+
+ fc_host->rqst_q = NULL;
+
+ if (!i->f->bsg_request)
+ return -ENOTSUPP;
+
+ snprintf(bsg_name, sizeof(bsg_name),
+ "fc_host%d", shost->host_no);
+
+ q = __scsi_alloc_queue(shost, fc_bsg_host_handler);
+ if (!q) {
+ printk(KERN_ERR "fc_host%d: bsg interface failed to "
+ "initialize - no request queue\n",
+ shost->host_no);
+ return -ENOMEM;
+ }
+
+ q->queuedata = shost;
+ queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
+ blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
+ blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);
+
+ err = bsg_register_queue(q, dev, bsg_name, NULL);
+ if (err) {
+ printk(KERN_ERR "fc_host%d: bsg interface failed to "
+ "initialize - register queue\n",
+ shost->host_no);
+ blk_cleanup_queue(q);
+ return err;
+ }
+
+ fc_host->rqst_q = q;
+ return 0;
+}
+
+
+/**
+ * fc_bsg_rportadd - Create and add the bsg hooks so we can receive requests
+ * @shost: shost that rport is attached to
+ * @rport: rport that the bsg hooks are being attached to
+ */
+static int
+fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
+{
+ struct device *dev = &rport->dev;
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ struct request_queue *q;
+ int err;
+
+ rport->rqst_q = NULL;
+
+ if (!i->f->bsg_request)
+ return -ENOTSUPP;
+
+ q = __scsi_alloc_queue(shost, fc_bsg_rport_handler);
+ if (!q) {
+ printk(KERN_ERR "%s: bsg interface failed to "
+ "initialize - no request queue\n",
+ dev->kobj.name);
+ return -ENOMEM;
+ }
+
+ q->queuedata = rport;
+ queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
+ blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
+ blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
+
+ err = bsg_register_queue(q, dev, NULL, NULL);
+ if (err) {
+ printk(KERN_ERR "%s: bsg interface failed to "
+ "initialize - register queue\n",
+ dev->kobj.name);
+ blk_cleanup_queue(q);
+ return err;
+ }
+
+ rport->rqst_q = q;
+ return 0;
+}
+
+
+/**
+ * fc_bsg_remove - Deletes the bsg hooks on fchosts/rports
+ * @q: the request_queue that is to be torn down.
+ */
+static void
+fc_bsg_remove(struct request_queue *q)
+{
+ if (q) {
+ bsg_unregister_queue(q);
+ blk_cleanup_queue(q);
+ }
+}
+
+
/* Original Author: Martin Hicks */
MODULE_AUTHOR("James Smart");
MODULE_DESCRIPTION("FC Transport Attributes");
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 50988cbf7b2d..d606452297cf 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -163,12 +163,10 @@ static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost,
int (*handler)(struct Scsi_Host *, struct sas_rphy *, struct request *);
while (!blk_queue_plugged(q)) {
- req = elv_next_request(q);
+ req = blk_fetch_request(q);
if (!req)
break;
- blkdev_dequeue_request(req);
-
spin_unlock_irq(q->queue_lock);
handler = to_sas_internal(shost->transportt)->f->smp_handler;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 84044233b637..40d2860f235a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -384,9 +384,9 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
struct scsi_device *sdp = q->queuedata;
struct gendisk *disk = rq->rq_disk;
struct scsi_disk *sdkp;
- sector_t block = rq->sector;
+ sector_t block = blk_rq_pos(rq);
sector_t threshold;
- unsigned int this_count = rq->nr_sectors;
+ unsigned int this_count = blk_rq_sectors(rq);
int ret, host_dif;
if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
@@ -413,10 +413,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
this_count));
if (!sdp || !scsi_device_online(sdp) ||
- block + rq->nr_sectors > get_capacity(disk)) {
+ block + blk_rq_sectors(rq) > get_capacity(disk)) {
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
- "Finishing %ld sectors\n",
- rq->nr_sectors));
+ "Finishing %u sectors\n",
+ blk_rq_sectors(rq)));
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
"Retry with 0x%p\n", SCpnt));
goto out;
@@ -463,7 +463,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
* for this.
*/
if (sdp->sector_size == 1024) {
- if ((block & 1) || (rq->nr_sectors & 1)) {
+ if ((block & 1) || (blk_rq_sectors(rq) & 1)) {
scmd_printk(KERN_ERR, SCpnt,
"Bad block number requested\n");
goto out;
@@ -473,7 +473,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
}
}
if (sdp->sector_size == 2048) {
- if ((block & 3) || (rq->nr_sectors & 3)) {
+ if ((block & 3) || (blk_rq_sectors(rq) & 3)) {
scmd_printk(KERN_ERR, SCpnt,
"Bad block number requested\n");
goto out;
@@ -483,7 +483,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
}
}
if (sdp->sector_size == 4096) {
- if ((block & 7) || (rq->nr_sectors & 7)) {
+ if ((block & 7) || (blk_rq_sectors(rq) & 7)) {
scmd_printk(KERN_ERR, SCpnt,
"Bad block number requested\n");
goto out;
@@ -512,10 +512,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
}
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
- "%s %d/%ld 512 byte blocks.\n",
+ "%s %d/%u 512 byte blocks.\n",
(rq_data_dir(rq) == WRITE) ?
"writing" : "reading", this_count,
- rq->nr_sectors));
+ blk_rq_sectors(rq)));
/* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */
host_dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type);
@@ -971,8 +971,8 @@ static struct block_device_operations sd_fops = {
static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
{
- u64 start_lba = scmd->request->sector;
- u64 end_lba = scmd->request->sector + (scsi_bufflen(scmd) / 512);
+ u64 start_lba = blk_rq_pos(scmd->request);
+ u64 end_lba = blk_rq_pos(scmd->request) + (scsi_bufflen(scmd) / 512);
u64 bad_lba;
int info_valid;
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index 184dff492797..82f14a9482d0 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -507,7 +507,7 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
sector_sz = scmd->device->sector_size;
sectors = good_bytes / sector_sz;
- phys = scmd->request->sector & 0xffffffff;
+ phys = blk_rq_pos(scmd->request) & 0xffffffff;
if (sector_sz == 4096)
phys >>= 3;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index e1716f14cd47..1bf6e00f4c44 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1065,6 +1065,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
return blk_trace_setup(sdp->device->request_queue,
sdp->disk->disk_name,
MKDEV(SCSI_GENERIC_MAJOR, sdp->index),
+ NULL,
(char *)arg);
case BLKTRACESTART:
return blk_trace_startstop(sdp->device->request_queue, 1);
@@ -1260,7 +1261,7 @@ static void sg_rq_end_io(struct request *rq, int uptodate)
sense = rq->sense;
result = rq->errors;
- resid = rq->data_len;
+ resid = rq->resid_len;
SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n",
sdp->disk->disk_name, srp->header.pack_id, result));
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 0e1a0f2d2ad5..fddba53c7fe5 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -292,7 +292,8 @@ static int sr_done(struct scsi_cmnd *SCpnt)
if (cd->device->sector_size == 2048)
error_sector <<= 2;
error_sector &= ~(block_sectors - 1);
- good_bytes = (error_sector - SCpnt->request->sector) << 9;
+ good_bytes = (error_sector -
+ blk_rq_pos(SCpnt->request)) << 9;
if (good_bytes < 0 || good_bytes >= this_count)
good_bytes = 0;
/*
@@ -349,8 +350,8 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
cd->disk->disk_name, block));
if (!cd->device || !scsi_device_online(cd->device)) {
- SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n",
- rq->nr_sectors));
+ SCSI_LOG_HLQUEUE(2, printk("Finishing %u sectors\n",
+ blk_rq_sectors(rq)));
SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
goto out;
}
@@ -413,7 +414,7 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
/*
* request doesn't start on hw block boundary, add scatter pads
*/
- if (((unsigned int)rq->sector % (s_size >> 9)) ||
+ if (((unsigned int)blk_rq_pos(rq) % (s_size >> 9)) ||
(scsi_bufflen(SCpnt) % s_size)) {
scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n");
goto out;
@@ -422,14 +423,14 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
this_count = (scsi_bufflen(SCpnt) >> 9) / (s_size >> 9);
- SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n",
+ SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%u 512 byte blocks.\n",
cd->cdi.name,
(rq_data_dir(rq) == WRITE) ?
"writing" : "reading",
- this_count, rq->nr_sectors));
+ this_count, blk_rq_sectors(rq)));
SCpnt->cmnd[1] = 0;
- block = (unsigned int)rq->sector / (s_size >> 9);
+ block = (unsigned int)blk_rq_pos(rq) / (s_size >> 9);
if (this_count > 0xffff) {
this_count = 0xffff;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index eb24efea8f14..8681b708344f 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -463,7 +463,7 @@ static void st_scsi_execute_end(struct request *req, int uptodate)
struct scsi_tape *STp = SRpnt->stp;
STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
- STp->buffer->cmdstat.residual = req->data_len;
+ STp->buffer->cmdstat.residual = req->resid_len;
if (SRpnt->waiting)
complete(SRpnt->waiting);
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index 601e95141cbe..54023d41fd15 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -1306,7 +1306,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs
if (linked_comm && SCpnt->device->queue_depth > 2
&& TLDEV(SCpnt->device->type)) {
HD(j)->cp_stat[i] = READY;
- flush_dev(SCpnt->device, SCpnt->request->sector, j, FALSE);
+ flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), j, FALSE);
return 0;
}
@@ -1610,11 +1610,13 @@ static int reorder(unsigned int j, unsigned long cursec,
if (!(cpp->xdir == DTD_IN)) input_only = FALSE;
- if (SCpnt->request->sector < minsec) minsec = SCpnt->request->sector;
- if (SCpnt->request->sector > maxsec) maxsec = SCpnt->request->sector;
+ if (blk_rq_pos(SCpnt->request) < minsec)
+ minsec = blk_rq_pos(SCpnt->request);
+ if (blk_rq_pos(SCpnt->request) > maxsec)
+ maxsec = blk_rq_pos(SCpnt->request);
- sl[n] = SCpnt->request->sector;
- ioseek += SCpnt->request->nr_sectors;
+ sl[n] = blk_rq_pos(SCpnt->request);
+ ioseek += blk_rq_sectors(SCpnt->request);
if (!n) continue;
@@ -1642,7 +1644,7 @@ static int reorder(unsigned int j, unsigned long cursec,
if (!input_only) for (n = 0; n < n_ready; n++) {
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
- ll[n] = SCpnt->request->nr_sectors; pl[n] = SCpnt->serial_number;
+ ll[n] = blk_rq_sectors(SCpnt->request); pl[n] = SCpnt->serial_number;
if (!n) continue;
@@ -1666,12 +1668,12 @@ static int reorder(unsigned int j, unsigned long cursec,
if (link_statistics && (overlap || !(flushcount % link_statistics)))
for (n = 0; n < n_ready; n++) {
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
- printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\
+ printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %u"\
" cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
(ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target,
SCpnt->lun, SCpnt->serial_number, k, flushcount, n_ready,
- SCpnt->request->sector, SCpnt->request->nr_sectors, cursec,
- YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only),
+ blk_rq_pos(SCpnt->request), blk_rq_sectors(SCpnt->request),
+ cursec, YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only),
YESNO(overlap), cpp->xdir);
}
#endif
@@ -1799,7 +1801,7 @@ static irqreturn_t ihdlr(unsigned int j)
if (linked_comm && SCpnt->device->queue_depth > 2
&& TLDEV(SCpnt->device->type))
- flush_dev(SCpnt->device, SCpnt->request->sector, j, TRUE);
+ flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), j, TRUE);
tstatus = status_byte(spp->target_status);
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 938bc1b6c3fa..e371a9c15341 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -2776,6 +2776,9 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_OXSEMI, 0x950a,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_2_1130000 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_C950,
+ PCI_VENDOR_ID_OXSEMI, PCI_SUBDEVICE_ID_OXSEMI_C950, 0, 0,
+ pbn_b0_1_921600 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_4_115200 },
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index 8871aaa3dba6..c0a3e2734e24 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -130,8 +130,6 @@ struct jsm_board
struct pci_dev *pci_dev;
u32 maxports; /* MAX ports this board can handle */
- spinlock_t bd_lock; /* Used to protect board */
-
spinlock_t bd_intr_lock; /* Used to protect the poller tasklet and
* the interrupt routine from each other.
*/
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index d2d32a198629..b3604aa322a4 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -88,7 +88,6 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device
else
brd->maxports = 2;
- spin_lock_init(&brd->bd_lock);
spin_lock_init(&brd->bd_intr_lock);
/* store which revision we have */
diff --git a/drivers/serial/s3c6400.c b/drivers/serial/s3c6400.c
index 06936d13393f..3e3785233682 100644
--- a/drivers/serial/s3c6400.c
+++ b/drivers/serial/s3c6400.c
@@ -102,6 +102,7 @@ static struct s3c24xx_uart_info s3c6400_uart_inf = {
.name = "Samsung S3C6400 UART",
.type = PORT_S3C6400,
.fifosize = 64,
+ .has_divslot = 1,
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index e06686ae858b..93b5d75db126 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -508,6 +508,7 @@ s3c24xx_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
struct baud_calc {
struct s3c24xx_uart_clksrc *clksrc;
unsigned int calc;
+ unsigned int divslot;
unsigned int quot;
struct clk *src;
};
@@ -517,6 +518,7 @@ static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
struct s3c24xx_uart_clksrc *clksrc,
unsigned int baud)
{
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
unsigned long rate;
calc->src = clk_get(port->dev, clksrc->name);
@@ -527,8 +529,24 @@ static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
rate /= clksrc->divisor;
calc->clksrc = clksrc;
- calc->quot = (rate + (8 * baud)) / (16 * baud);
- calc->calc = (rate / (calc->quot * 16));
+
+ if (ourport->info->has_divslot) {
+ unsigned long div = rate / baud;
+
+ /* The UDIVSLOT register on the newer UARTs allows us to
+ * get a divisor adjustment of 1/16th on the baud clock.
+ *
+ * We don't keep the UDIVSLOT value (the 16ths we calculated
+ * by not multiplying the baud by 16) as it is easy enough
+ * to recalculate.
+ */
+
+ calc->quot = div / 16;
+ calc->calc = rate / div;
+ } else {
+ calc->quot = (rate + (8 * baud)) / (16 * baud);
+ calc->calc = (rate / (calc->quot * 16));
+ }
calc->quot--;
return 1;
@@ -611,6 +629,30 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
return best->quot;
}
+/* udivslot_table[]
+ *
+ * This table takes the fractional value of the baud divisor and gives
+ * the recommended setting for the UDIVSLOT register.
+ */
+static u16 udivslot_table[16] = {
+ [0] = 0x0000,
+ [1] = 0x0080,
+ [2] = 0x0808,
+ [3] = 0x0888,
+ [4] = 0x2222,
+ [5] = 0x4924,
+ [6] = 0x4A52,
+ [7] = 0x54AA,
+ [8] = 0x5555,
+ [9] = 0xD555,
+ [10] = 0xD5D5,
+ [11] = 0xDDD5,
+ [12] = 0xDDDD,
+ [13] = 0xDFDD,
+ [14] = 0xDFDF,
+ [15] = 0xFFDF,
+};
+
static void s3c24xx_serial_set_termios(struct uart_port *port,
struct ktermios *termios,
struct ktermios *old)
@@ -623,6 +665,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
unsigned int baud, quot;
unsigned int ulcon;
unsigned int umcon;
+ unsigned int udivslot = 0;
/*
* We don't support modem control lines.
@@ -644,6 +687,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
/* check to see if we need to change clock source */
if (ourport->clksrc != clksrc || ourport->baudclk != clk) {
+ dbg("selecting clock %p\n", clk);
s3c24xx_serial_setsource(port, clksrc);
if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
@@ -658,6 +702,13 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
}
+ if (ourport->info->has_divslot) {
+ unsigned int div = ourport->baudclk_rate / baud;
+
+ udivslot = udivslot_table[div & 15];
+ dbg("udivslot = %04x (div %d)\n", udivslot, div & 15);
+ }
+
switch (termios->c_cflag & CSIZE) {
case CS5:
dbg("config: 5bits/char\n");
@@ -697,12 +748,16 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
spin_lock_irqsave(&port->lock, flags);
- dbg("setting ulcon to %08x, brddiv to %d\n", ulcon, quot);
+ dbg("setting ulcon to %08x, brddiv to %d, udivslot %08x\n",
+ ulcon, quot, udivslot);
wr_regl(port, S3C2410_ULCON, ulcon);
wr_regl(port, S3C2410_UBRDIV, quot);
wr_regl(port, S3C2410_UMCON, umcon);
+ if (ourport->info->has_divslot)
+ wr_regl(port, S3C2443_DIVSLOT, udivslot);
+
dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
rd_regl(port, S3C2410_ULCON),
rd_regl(port, S3C2410_UCON),
diff --git a/drivers/serial/samsung.h b/drivers/serial/samsung.h
index 571d6b90d206..7afb94843a08 100644
--- a/drivers/serial/samsung.h
+++ b/drivers/serial/samsung.h
@@ -21,6 +21,10 @@ struct s3c24xx_uart_info {
unsigned long tx_fifoshift;
unsigned long tx_fifofull;
+ /* uart port features */
+
+ unsigned int has_divslot:1;
+
/* clock source control */
int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 7546aa887fa7..79c9c5f5cdba 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -681,7 +681,7 @@ static int serial_config(struct pcmcia_device * link)
u_char *buf;
cisparse_t *parse;
cistpl_cftable_entry_t *cf;
- int i;
+ int i, last_ret, last_fn;
DEBUG(0, "serial_config(0x%p)\n", link);
@@ -699,6 +699,16 @@ static int serial_config(struct pcmcia_device * link)
tuple->TupleDataMax = 255;
tuple->Attributes = 0;
+ /* Get configuration register information */
+ tuple->DesiredTuple = CISTPL_CONFIG;
+ last_ret = first_tuple(link, tuple, parse);
+ if (last_ret != 0) {
+ last_fn = ParseTuple;
+ goto cs_failed;
+ }
+ link->conf.ConfigBase = parse->config.base;
+ link->conf.Present = parse->config.rmask[0];
+
/* Is this a compliant multifunction card? */
tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
@@ -761,7 +771,9 @@ static int serial_config(struct pcmcia_device * link)
kfree(cfg_mem);
return 0;
- failed:
+cs_failed:
+ cs_error(link, last_fn, last_ret);
+failed:
serial_remove(link);
kfree(cfg_mem);
return -ENODEV;
@@ -863,10 +875,10 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "3CCFEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
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_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/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 */
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index dbf5357a77b3..4e3248d58602 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -47,12 +47,17 @@
#include <linux/clk.h>
#include <linux/ctype.h>
#include <linux/err.h>
+#include <linux/list.h>
#ifdef CONFIG_SUPERH
#include <asm/clock.h>
#include <asm/sh_bios.h>
#endif
+#ifdef CONFIG_H8300
+#include <asm/gpio.h>
+#endif
+
#include "sh-sci.h"
struct sci_port {
@@ -75,14 +80,22 @@ struct sci_port {
int break_flag;
#ifdef CONFIG_HAVE_CLK
- /* Port clock */
- struct clk *clk;
+ /* Interface clock */
+ struct clk *iclk;
+ /* Data clock */
+ struct clk *dclk;
#endif
+ struct list_head node;
};
-#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
-static struct sci_port *serial_console_port;
+struct sh_sci_priv {
+ spinlock_t lock;
+ struct list_head ports;
+
+#ifdef CONFIG_HAVE_CLK
+ struct notifier_block clk_nb;
#endif
+};
/* Function prototypes */
static void sci_stop_tx(struct uart_port *port);
@@ -159,12 +172,12 @@ static void h8300_sci_config(struct uart_port *port, unsigned int ctrl)
*mstpcrl &= ~mask;
}
-static inline void h8300_sci_enable(struct uart_port *port)
+static void h8300_sci_enable(struct uart_port *port)
{
h8300_sci_config(port, sci_enable);
}
-static inline void h8300_sci_disable(struct uart_port *port)
+static void h8300_sci_disable(struct uart_port *port)
{
h8300_sci_config(port, sci_disable);
}
@@ -611,7 +624,7 @@ static inline int sci_handle_breaks(struct uart_port *port)
int copied = 0;
unsigned short status = sci_in(port, SCxSR);
struct tty_struct *tty = port->info->port.tty;
- struct sci_port *s = &sci_ports[port->line];
+ struct sci_port *s = to_sci_port(port);
if (uart_handle_break(port))
return 0;
@@ -726,19 +739,43 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
static int sci_notifier(struct notifier_block *self,
unsigned long phase, void *p)
{
- int i;
+ struct sh_sci_priv *priv = container_of(self,
+ struct sh_sci_priv, clk_nb);
+ struct sci_port *sci_port;
+ unsigned long flags;
if ((phase == CPUFREQ_POSTCHANGE) ||
- (phase == CPUFREQ_RESUMECHANGE))
- for (i = 0; i < SCI_NPORTS; i++) {
- struct sci_port *s = &sci_ports[i];
- s->port.uartclk = clk_get_rate(s->clk);
- }
+ (phase == CPUFREQ_RESUMECHANGE)) {
+ spin_lock_irqsave(&priv->lock, flags);
+ list_for_each_entry(sci_port, &priv->ports, node)
+ sci_port->port.uartclk = clk_get_rate(sci_port->dclk);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
return NOTIFY_OK;
}
-static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 };
+static void sci_clk_enable(struct uart_port *port)
+{
+ struct sci_port *sci_port = to_sci_port(port);
+
+ clk_enable(sci_port->dclk);
+ sci_port->port.uartclk = clk_get_rate(sci_port->dclk);
+
+ if (sci_port->iclk)
+ clk_enable(sci_port->iclk);
+}
+
+static void sci_clk_disable(struct uart_port *port)
+{
+ struct sci_port *sci_port = to_sci_port(port);
+
+ if (sci_port->iclk)
+ clk_disable(sci_port->iclk);
+
+ clk_disable(sci_port->dclk);
+}
#endif
static int sci_request_irq(struct sci_port *port)
@@ -865,15 +902,11 @@ static void sci_break_ctl(struct uart_port *port, int break_state)
static int sci_startup(struct uart_port *port)
{
- struct sci_port *s = &sci_ports[port->line];
+ struct sci_port *s = to_sci_port(port);
if (s->enable)
s->enable(port);
-#ifdef CONFIG_HAVE_CLK
- s->clk = clk_get(NULL, "module_clk");
-#endif
-
sci_request_irq(s);
sci_start_tx(port);
sci_start_rx(port, 1);
@@ -883,7 +916,7 @@ static int sci_startup(struct uart_port *port)
static void sci_shutdown(struct uart_port *port)
{
- struct sci_port *s = &sci_ports[port->line];
+ struct sci_port *s = to_sci_port(port);
sci_stop_rx(port);
sci_stop_tx(port);
@@ -891,11 +924,6 @@ static void sci_shutdown(struct uart_port *port)
if (s->disable)
s->disable(port);
-
-#ifdef CONFIG_HAVE_CLK
- clk_put(s->clk);
- s->clk = NULL;
-#endif
}
static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
@@ -980,25 +1008,31 @@ static int sci_request_port(struct uart_port *port)
static void sci_config_port(struct uart_port *port, int flags)
{
- struct sci_port *s = &sci_ports[port->line];
+ struct sci_port *s = to_sci_port(port);
port->type = s->type;
- if (port->flags & UPF_IOREMAP && !port->membase) {
-#if defined(CONFIG_SUPERH64)
- port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
- port->membase = (void __iomem *)port->mapbase;
-#else
+ if (port->membase)
+ return;
+
+ if (port->flags & UPF_IOREMAP) {
port->membase = ioremap_nocache(port->mapbase, 0x40);
-#endif
- dev_err(port->dev, "can't remap port#%d\n", port->line);
+ if (IS_ERR(port->membase))
+ dev_err(port->dev, "can't remap port#%d\n", port->line);
+ } else {
+ /*
+ * For the simple (and majority of) cases where we don't
+ * need to do any remapping, just cast the cookie
+ * directly.
+ */
+ port->membase = (void __iomem *)port->mapbase;
}
}
static int sci_verify_port(struct uart_port *port, struct serial_struct *ser)
{
- struct sci_port *s = &sci_ports[port->line];
+ struct sci_port *s = to_sci_port(port);
if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs)
return -EINVAL;
@@ -1032,63 +1066,60 @@ static struct uart_ops sci_uart_ops = {
#endif
};
-static void __init sci_init_ports(void)
+static void __devinit sci_init_single(struct platform_device *dev,
+ struct sci_port *sci_port,
+ unsigned int index,
+ struct plat_sci_port *p)
{
- static int first = 1;
- int i;
-
- if (!first)
- return;
-
- first = 0;
-
- for (i = 0; i < SCI_NPORTS; i++) {
- sci_ports[i].port.ops = &sci_uart_ops;
- sci_ports[i].port.iotype = UPIO_MEM;
- sci_ports[i].port.line = i;
- sci_ports[i].port.fifosize = 1;
+ sci_port->port.ops = &sci_uart_ops;
+ sci_port->port.iotype = UPIO_MEM;
+ sci_port->port.line = index;
+ sci_port->port.fifosize = 1;
#if defined(__H8300H__) || defined(__H8300S__)
#ifdef __H8300S__
- sci_ports[i].enable = h8300_sci_enable;
- sci_ports[i].disable = h8300_sci_disable;
+ sci_port->enable = h8300_sci_enable;
+ sci_port->disable = h8300_sci_disable;
#endif
- sci_ports[i].port.uartclk = CONFIG_CPU_CLOCK;
+ sci_port->port.uartclk = CONFIG_CPU_CLOCK;
#elif defined(CONFIG_HAVE_CLK)
- /*
- * XXX: We should use a proper SCI/SCIF clock
- */
- {
- struct clk *clk = clk_get(NULL, "module_clk");
- sci_ports[i].port.uartclk = clk_get_rate(clk);
- clk_put(clk);
- }
+ sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL;
+ sci_port->dclk = clk_get(&dev->dev, "module_clk");
+ sci_port->enable = sci_clk_enable;
+ sci_port->disable = sci_clk_disable;
#else
#error "Need a valid uartclk"
#endif
- sci_ports[i].break_timer.data = (unsigned long)&sci_ports[i];
- sci_ports[i].break_timer.function = sci_break_timer;
-
- init_timer(&sci_ports[i].break_timer);
- }
-}
+ sci_port->break_timer.data = (unsigned long)sci_port;
+ sci_port->break_timer.function = sci_break_timer;
+ init_timer(&sci_port->break_timer);
-int __init early_sci_setup(struct uart_port *port)
-{
- if (unlikely(port->line > SCI_NPORTS))
- return -ENODEV;
+ sci_port->port.mapbase = p->mapbase;
+ sci_port->port.membase = p->membase;
- sci_init_ports();
+ sci_port->port.irq = p->irqs[SCIx_TXI_IRQ];
+ sci_port->port.flags = p->flags;
+ sci_port->port.dev = &dev->dev;
+ sci_port->type = sci_port->port.type = p->type;
- sci_ports[port->line].port.membase = port->membase;
- sci_ports[port->line].port.mapbase = port->mapbase;
- sci_ports[port->line].port.type = port->type;
+ memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs));
- return 0;
}
#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
+static struct tty_driver *serial_console_device(struct console *co, int *index)
+{
+ struct uart_driver *p = &sci_uart_driver;
+ *index = co->index;
+ return p->tty_driver;
+}
+
+static void serial_console_putchar(struct uart_port *port, int ch)
+{
+ sci_poll_put_char(port, ch);
+}
+
/*
* Print a string to the serial port trying not to disturb
* any possible real use of the port...
@@ -1096,25 +1127,27 @@ int __init early_sci_setup(struct uart_port *port)
static void serial_console_write(struct console *co, const char *s,
unsigned count)
{
- struct uart_port *port = &serial_console_port->port;
+ struct uart_port *port = co->data;
+ struct sci_port *sci_port = to_sci_port(port);
unsigned short bits;
- int i;
- for (i = 0; i < count; i++) {
- if (*s == 10)
- sci_poll_put_char(port, '\r');
+ if (sci_port->enable)
+ sci_port->enable(port);
- sci_poll_put_char(port, *s++);
- }
+ uart_console_write(port, s, count, serial_console_putchar);
/* wait until fifo is empty and last bit has been transmitted */
bits = SCxSR_TDxE(port) | SCxSR_TEND(port);
while ((sci_in(port, SCxSR) & bits) != bits)
cpu_relax();
+
+ if (sci_port->disable);
+ sci_port->disable(port);
}
static int __init serial_console_setup(struct console *co, char *options)
{
+ struct sci_port *sci_port;
struct uart_port *port;
int baud = 115200;
int bits = 8;
@@ -1130,8 +1163,9 @@ static int __init serial_console_setup(struct console *co, char *options)
if (co->index >= SCI_NPORTS)
co->index = 0;
- serial_console_port = &sci_ports[co->index];
- port = &serial_console_port->port;
+ sci_port = &sci_ports[co->index];
+ port = &sci_port->port;
+ co->data = port;
/*
* Also need to check port->type, we don't actually have any
@@ -1141,21 +1175,11 @@ static int __init serial_console_setup(struct console *co, char *options)
*/
if (!port->type)
return -ENODEV;
- if (!port->membase || !port->mapbase)
- return -ENODEV;
-
- port->type = serial_console_port->type;
-
-#ifdef CONFIG_HAVE_CLK
- if (!serial_console_port->clk)
- serial_console_port->clk = clk_get(NULL, "module_clk");
-#endif
- if (port->flags & UPF_IOREMAP)
- sci_config_port(port, 0);
+ sci_config_port(port, 0);
- if (serial_console_port->enable)
- serial_console_port->enable(port);
+ if (sci_port->enable)
+ sci_port->enable(port);
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -1166,22 +1190,21 @@ static int __init serial_console_setup(struct console *co, char *options)
if (ret == 0)
sci_stop_rx(port);
#endif
+ /* TODO: disable clock */
return ret;
}
static struct console serial_console = {
.name = "ttySC",
- .device = uart_console_device,
+ .device = serial_console_device,
.write = serial_console_write,
.setup = serial_console_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
- .data = &sci_uart_driver,
};
static int __init sci_console_init(void)
{
- sci_init_ports();
register_console(&serial_console);
return 0;
}
@@ -1207,6 +1230,61 @@ static struct uart_driver sci_uart_driver = {
.cons = SCI_CONSOLE,
};
+
+static int sci_remove(struct platform_device *dev)
+{
+ struct sh_sci_priv *priv = platform_get_drvdata(dev);
+ struct sci_port *p;
+ unsigned long flags;
+
+#ifdef CONFIG_HAVE_CLK
+ cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+
+ spin_lock_irqsave(&priv->lock, flags);
+ list_for_each_entry(p, &priv->ports, node)
+ uart_remove_one_port(&sci_uart_driver, &p->port);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ kfree(priv);
+ return 0;
+}
+
+static int __devinit sci_probe_single(struct platform_device *dev,
+ unsigned int index,
+ struct plat_sci_port *p,
+ struct sci_port *sciport)
+{
+ struct sh_sci_priv *priv = platform_get_drvdata(dev);
+ unsigned long flags;
+ int ret;
+
+ /* Sanity check */
+ if (unlikely(index >= SCI_NPORTS)) {
+ dev_notice(&dev->dev, "Attempting to register port "
+ "%d when only %d are available.\n",
+ index+1, SCI_NPORTS);
+ dev_notice(&dev->dev, "Consider bumping "
+ "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n");
+ return 0;
+ }
+
+ sci_init_single(dev, sciport, index, p);
+
+ ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
+ if (ret)
+ return ret;
+
+ INIT_LIST_HEAD(&sciport->node);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ list_add(&sciport->node, &priv->ports);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
/*
* Register a set of serial devices attached to a platform device. The
* list is terminated with a zero flags entry, which means we expect
@@ -1216,57 +1294,34 @@ static struct uart_driver sci_uart_driver = {
static int __devinit sci_probe(struct platform_device *dev)
{
struct plat_sci_port *p = dev->dev.platform_data;
+ struct sh_sci_priv *priv;
int i, ret = -EINVAL;
- for (i = 0; p && p->flags != 0; p++, i++) {
- struct sci_port *sciport = &sci_ports[i];
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
- /* Sanity check */
- if (unlikely(i == SCI_NPORTS)) {
- dev_notice(&dev->dev, "Attempting to register port "
- "%d when only %d are available.\n",
- i+1, SCI_NPORTS);
- dev_notice(&dev->dev, "Consider bumping "
- "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n");
- break;
- }
+ INIT_LIST_HEAD(&priv->ports);
+ spin_lock_init(&priv->lock);
+ platform_set_drvdata(dev, priv);
- sciport->port.mapbase = p->mapbase;
+#ifdef CONFIG_HAVE_CLK
+ priv->clk_nb.notifier_call = sci_notifier;
+ cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER);
+#endif
- if (p->mapbase && !p->membase) {
- if (p->flags & UPF_IOREMAP) {
- p->membase = ioremap_nocache(p->mapbase, 0x40);
- if (IS_ERR(p->membase)) {
- ret = PTR_ERR(p->membase);
- goto err_unreg;
- }
- } else {
- /*
- * For the simple (and majority of) cases
- * where we don't need to do any remapping,
- * just cast the cookie directly.
- */
- p->membase = (void __iomem *)p->mapbase;
- }
+ if (dev->id != -1) {
+ ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]);
+ if (ret)
+ goto err_unreg;
+ } else {
+ for (i = 0; p && p->flags != 0; p++, i++) {
+ ret = sci_probe_single(dev, i, p, &sci_ports[i]);
+ if (ret)
+ goto err_unreg;
}
-
- sciport->port.membase = p->membase;
-
- sciport->port.irq = p->irqs[SCIx_TXI_IRQ];
- sciport->port.flags = p->flags;
- sciport->port.dev = &dev->dev;
-
- sciport->type = sciport->port.type = p->type;
-
- memcpy(&sciport->irqs, &p->irqs, sizeof(p->irqs));
-
- uart_add_one_port(&sci_uart_driver, &sciport->port);
}
-#ifdef CONFIG_HAVE_CLK
- cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);
-#endif
-
#ifdef CONFIG_SH_STANDARD_BIOS
sh_bios_gdb_detach();
#endif
@@ -1274,50 +1329,36 @@ static int __devinit sci_probe(struct platform_device *dev)
return 0;
err_unreg:
- for (i = i - 1; i >= 0; i--)
- uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port);
-
+ sci_remove(dev);
return ret;
}
-static int __devexit sci_remove(struct platform_device *dev)
-{
- int i;
-
-#ifdef CONFIG_HAVE_CLK
- cpufreq_unregister_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);
-#endif
-
- for (i = 0; i < SCI_NPORTS; i++)
- uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port);
-
- return 0;
-}
-
static int sci_suspend(struct platform_device *dev, pm_message_t state)
{
- int i;
+ struct sh_sci_priv *priv = platform_get_drvdata(dev);
+ struct sci_port *p;
+ unsigned long flags;
- for (i = 0; i < SCI_NPORTS; i++) {
- struct sci_port *p = &sci_ports[i];
+ spin_lock_irqsave(&priv->lock, flags);
+ list_for_each_entry(p, &priv->ports, node)
+ uart_suspend_port(&sci_uart_driver, &p->port);
- if (p->type != PORT_UNKNOWN && p->port.dev == &dev->dev)
- uart_suspend_port(&sci_uart_driver, &p->port);
- }
+ spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
static int sci_resume(struct platform_device *dev)
{
- int i;
+ struct sh_sci_priv *priv = platform_get_drvdata(dev);
+ struct sci_port *p;
+ unsigned long flags;
- for (i = 0; i < SCI_NPORTS; i++) {
- struct sci_port *p = &sci_ports[i];
+ spin_lock_irqsave(&priv->lock, flags);
+ list_for_each_entry(p, &priv->ports, node)
+ uart_resume_port(&sci_uart_driver, &p->port);
- if (p->type != PORT_UNKNOWN && p->port.dev == &dev->dev)
- uart_resume_port(&sci_uart_driver, &p->port);
- }
+ spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
@@ -1339,8 +1380,6 @@ static int __init sci_init(void)
printk(banner);
- sci_init_ports();
-
ret = uart_register_driver(&sci_uart_driver);
if (likely(ret == 0)) {
ret = platform_driver_register(&sci_driver);
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index d0aa82d7fce0..38072c15b845 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -91,6 +91,9 @@
# define SCSPTR5 0xa4050128
# define SCIF_ORER 0x0001 /* overrun error bit */
# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
+# define SCIF_ORER 0x0001 /* overrun error bit */
+# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
# define SCSPTR2 0xffe80020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
@@ -314,7 +317,18 @@
} \
}
-#define CPU_SCIF_FNS(name, scif_offset, scif_size) \
+#ifdef CONFIG_H8300
+/* h8300 don't have SCIF */
+#define CPU_SCIF_FNS(name) \
+ static inline unsigned int sci_##name##_in(struct uart_port *port) \
+ { \
+ return 0; \
+ } \
+ static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
+ { \
+ }
+#else
+#define CPU_SCIF_FNS(name, scif_offset, scif_size) \
static inline unsigned int sci_##name##_in(struct uart_port *port) \
{ \
SCI_IN(scif_size, scif_offset); \
@@ -323,6 +337,7 @@
{ \
SCI_OUT(scif_size, scif_offset, value); \
}
+#endif
#define CPU_SCI_FNS(name, sci_offset, sci_size) \
static inline unsigned int sci_##name##_in(struct uart_port* port) \
@@ -360,8 +375,10 @@
sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
h8_sci_offset, h8_sci_size) \
CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size)
-#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size)
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
+ CPU_SCIF_FNS(name)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
+ defined(CONFIG_CPU_SUBTYPE_SH7724)
#define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) \
CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size)
#define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \
@@ -390,7 +407,8 @@ SCIF_FNS(SCFDR, 0x1c, 16)
SCIF_FNS(SCxTDR, 0x20, 8)
SCIF_FNS(SCxRDR, 0x24, 8)
SCIF_FNS(SCLSR, 0x24, 16)
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
+ defined(CONFIG_CPU_SUBTYPE_SH7724)
SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
SCIx_FNS(SCBRR, 0x04, 8, 0x04, 8)
SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16)
@@ -604,10 +622,21 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */
return 1;
}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
+# define SCFSR 0x0010
+# define SCASSR 0x0014
+static inline int sci_rxd_in(struct uart_port *port)
+{
+ if (port->type == PORT_SCIF)
+ return ctrl_inw((port->mapbase + SCFSR)) & SCIF_BRK ? 1 : 0;
+ if (port->type == PORT_SCIFA)
+ return ctrl_inw((port->mapbase + SCASSR)) & SCIF_BRK ? 1 : 0;
+ return 1;
+}
#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
static inline int sci_rxd_in(struct uart_port *port)
{
- return sci_in(port, SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
+ return sci_in(port, SCSPTR)&0x0001 ? 1 : 0; /* SCIF */
}
#elif defined(__H8300H__) || defined(__H8300S__)
static inline int sci_rxd_in(struct uart_port *port)
@@ -757,7 +786,8 @@ static inline int sci_rxd_in(struct uart_port *port)
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721)
#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
+ defined(CONFIG_CPU_SUBTYPE_SH7724)
static inline int scbrr_calc(struct uart_port *port, int bps, int clk)
{
if (port->type == PORT_SCIF)
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 885194a07418..3f3c08c6ba4e 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -1373,6 +1373,9 @@ static void cleanup(struct spi_device *spi)
{
struct chip_data *chip = spi_get_ctldata(spi);
+ if (!chip)
+ return;
+
if (gpio_is_valid(chip->gpio_cs))
gpio_free(chip->gpio_cs);
diff --git a/drivers/staging/comedi/TODO b/drivers/staging/comedi/TODO
index 557812958464..15c9348fb938 100644
--- a/drivers/staging/comedi/TODO
+++ b/drivers/staging/comedi/TODO
@@ -11,4 +11,3 @@ Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
copy:
Ian Abbott <abbotti@mev.co.uk>
Frank Mori Hess <fmhess@users.sourceforge.net>
- David Schleef <ds@schleef.org>
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h
index a42caa370808..a69cf338e498 100644
--- a/drivers/staging/rt2870/rt2870.h
+++ b/drivers/staging/rt2870/rt2870.h
@@ -145,6 +145,7 @@
{USB_DEVICE(0x0789,0x0162)}, /* Logitec */ \
{USB_DEVICE(0x0789,0x0163)}, /* Logitec */ \
{USB_DEVICE(0x0789,0x0164)}, /* Logitec */ \
+ {USB_DEVICE(0x7392,0x7717)}, /* Edimax */ \
{ }/* Terminating entry */ \
}
diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h
index 12215fc61ddc..db446b7e2e08 100644
--- a/drivers/staging/rtl8187se/r8180.h
+++ b/drivers/staging/rtl8187se/r8180.h
@@ -19,7 +19,7 @@
#define R8180H
-#define RTL8180_MODULE_NAME "rtl8180"
+#define RTL8180_MODULE_NAME "r8180"
#define DMESG(x,a...) printk(KERN_INFO RTL8180_MODULE_NAME ": " x "\n", ## a)
#define DMESGW(x,a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": WW:" x "\n", ## a)
#define DMESGE(x,a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": EE:" x "\n", ## a)
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 6ecd12de4296..e10413cee0df 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -640,11 +640,9 @@ void rtl8180_proc_init_one(struct net_device *dev)
{
struct proc_dir_entry *e;
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- priv->dir_dev = create_proc_entry(dev->name,
- S_IFDIR | S_IRUGO | S_IXUGO,
- rtl8180_proc);
+ priv->dir_dev = rtl8180_proc;
if (!priv->dir_dev) {
- DMESGE("Unable to initialize /proc/net/rtl8180/%s\n",
+ DMESGE("Unable to initialize /proc/net/r8180/%s\n",
dev->name);
return;
}
@@ -654,7 +652,7 @@ void rtl8180_proc_init_one(struct net_device *dev)
if (!e) {
DMESGE("Unable to initialize "
- "/proc/net/rtl8180/%s/stats-hw\n",
+ "/proc/net/r8180/%s/stats-hw\n",
dev->name);
}
@@ -663,7 +661,7 @@ void rtl8180_proc_init_one(struct net_device *dev)
if (!e) {
DMESGE("Unable to initialize "
- "/proc/net/rtl8180/%s/stats-rx\n",
+ "/proc/net/r8180/%s/stats-rx\n",
dev->name);
}
@@ -673,7 +671,7 @@ void rtl8180_proc_init_one(struct net_device *dev)
if (!e) {
DMESGE("Unable to initialize "
- "/proc/net/rtl8180/%s/stats-tx\n",
+ "/proc/net/r8180/%s/stats-tx\n",
dev->name);
}
#if 0
@@ -702,7 +700,7 @@ void rtl8180_proc_init_one(struct net_device *dev)
if (!e) {
DMESGE("Unable to initialize "
- "/proc/net/rtl8180/%s/registers\n",
+ "/proc/net/r8180/%s/registers\n",
dev->name);
}
}
@@ -977,13 +975,6 @@ void check_tx_ring(struct net_device *dev, int pri)
*tmp & (1<<15)? "ok": "err", *(tmp+4));
}
- DMESG("nic at %d",
- (nic-nicbegin) / 8 /4);
- DMESG("tail at %d", ((int)tail - (int)begin) /8 /4);
- DMESG("head at %d", ((int)head - (int)begin) /8 /4);
- DMESG("check free desc returns %d", check_nic_enought_desc(dev,pri));
- DMESG("free desc is %d\n", get_curr_tx_free_desc(dev,pri));
- //rtl8180_reset(dev);
return;
}
@@ -1736,17 +1727,7 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
* descriptor's buffer must be 256 byte aligned
* we shouldn't be here, since we set DMA mask !
*/
- DMESGW("Fixing TX alignment");
- desc = (u32*)((u8*)desc + 256);
-#if (defined(CONFIG_HIGHMEM64G) || defined(CONFIG_64BIT_PHYS_ADDR))
- desc = (u32*)((u64)desc &~ 0xff);
- dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
- dma_desc = (dma_addr_t)((u64)dma_desc &~ 0xff);
-#else
- desc = (u32*)((u32)desc &~ 0xff);
- dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
- dma_desc = (dma_addr_t)((u32)dma_desc &~ 0xff);
-#endif
+ WARN(1, "DMA buffer is not aligned\n");
}
tmp=desc;
for (i=0;i<count;i++)
@@ -1984,18 +1965,7 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
* descriptor's buffer must be 256 byte aligned
* should never happen since we specify the DMA mask
*/
-
- DMESGW("Fixing RX alignment");
- desc = (u32*)((u8*)desc + 256);
-#if (defined(CONFIG_HIGHMEM64G) || defined(CONFIG_64BIT_PHYS_ADDR))
- desc = (u32*)((u64)desc &~ 0xff);
- dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
- dma_desc = (dma_addr_t)((u64)dma_desc &~ 0xff);
-#else
- desc = (u32*)((u32)desc &~ 0xff);
- dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
- dma_desc = (dma_addr_t)((u32)dma_desc &~ 0xff);
-#endif
+ WARN(1, "DMA buffer is not aligned\n");
}
priv->rxring=desc;
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index 9c3f9439f35e..3b2d52819b4c 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -386,7 +386,7 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
if (err)
goto error_free_hw;
- usb_set_intfdata(intf, priv);
+ usb_set_intfdata(intf, dev);
return 0;
@@ -415,10 +415,15 @@ static void wb35_hw_halt(struct wbsoft_priv *adapter)
static void wb35_disconnect(struct usb_interface *intf)
{
- struct wbsoft_priv *priv = usb_get_intfdata(intf);
+ struct ieee80211_hw *hw = usb_get_intfdata(intf);
+ struct wbsoft_priv *priv = hw->priv;
wb35_hw_halt(priv);
+ ieee80211_stop_queues(hw);
+ ieee80211_unregister_hw(hw);
+ ieee80211_free_hw(hw);
+
usb_set_intfdata(intf, NULL);
usb_put_dev(interface_to_usbdev(intf));
}
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 89299a5ce168..0716cdb44cd8 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -27,6 +27,8 @@ obj-$(CONFIG_USB_WUSB) += wusbcore/
obj-$(CONFIG_USB_ACM) += class/
obj-$(CONFIG_USB_PRINTER) += class/
+obj-$(CONFIG_USB_WDM) += class/
+obj-$(CONFIG_USB_TMC) += class/
obj-$(CONFIG_USB_STORAGE) += storage/
obj-$(CONFIG_USB) += storage/
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 6789089e2461..56802d2e994b 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -227,8 +227,14 @@ static ssize_t cxacru_sysfs_showattr_s8(s8 value, char *buf)
static ssize_t cxacru_sysfs_showattr_dB(s16 value, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d.%02u\n",
- value / 100, abs(value) % 100);
+ if (likely(value >= 0)) {
+ return snprintf(buf, PAGE_SIZE, "%u.%02u\n",
+ value / 100, value % 100);
+ } else {
+ value = -value;
+ return snprintf(buf, PAGE_SIZE, "-%u.%02u\n",
+ value / 100, value % 100);
+ }
}
static ssize_t cxacru_sysfs_showattr_bool(u32 value, char *buf)
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 0a69c0977e3f..ddeb69192537 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -16,7 +16,8 @@
* v0.9 - thorough cleaning, URBification, almost a rewrite
* v0.10 - some more cleanups
* v0.11 - fixed flow control, read error doesn't stop reads
- * v0.12 - added TIOCM ioctls, added break handling, made struct acm kmalloced
+ * v0.12 - added TIOCM ioctls, added break handling, made struct acm
+ * kmalloced
* v0.13 - added termios, added hangup
* v0.14 - sized down struct acm
* v0.15 - fixed flow control again - characters could be lost
@@ -62,7 +63,7 @@
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/mutex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/cdc.h>
#include <asm/byteorder.h>
@@ -87,7 +88,10 @@ static struct acm *acm_table[ACM_TTY_MINORS];
static DEFINE_MUTEX(open_mutex);
-#define ACM_READY(acm) (acm && acm->dev && acm->used)
+#define ACM_READY(acm) (acm && acm->dev && acm->port.count)
+
+static const struct tty_port_operations acm_port_ops = {
+};
#ifdef VERBOSE_DEBUG
#define verbose 1
@@ -99,13 +103,15 @@ static DEFINE_MUTEX(open_mutex);
* Functions for ACM control messages.
*/
-static int acm_ctrl_msg(struct acm *acm, int request, int value, void *buf, int len)
+static int acm_ctrl_msg(struct acm *acm, int request, int value,
+ void *buf, int len)
{
int retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
request, USB_RT_ACM, value,
acm->control->altsetting[0].desc.bInterfaceNumber,
buf, len, 5000);
- dbg("acm_control_msg: rq: 0x%02x val: %#x len: %#x result: %d", request, value, len, retval);
+ dbg("acm_control_msg: rq: 0x%02x val: %#x len: %#x result: %d",
+ request, value, len, retval);
return retval < 0 ? retval : 0;
}
@@ -150,9 +156,8 @@ static int acm_wb_is_avail(struct acm *acm)
n = ACM_NW;
spin_lock_irqsave(&acm->write_lock, flags);
- for (i = 0; i < ACM_NW; i++) {
+ for (i = 0; i < ACM_NW; i++)
n -= acm->wb[i].use;
- }
spin_unlock_irqrestore(&acm->write_lock, flags);
return n;
}
@@ -183,7 +188,8 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb)
wb->urb->transfer_buffer_length = wb->len;
wb->urb->dev = acm->dev;
- if ((rc = usb_submit_urb(wb->urb, GFP_ATOMIC)) < 0) {
+ rc = usb_submit_urb(wb->urb, GFP_ATOMIC);
+ if (rc < 0) {
dbg("usb_submit_urb(write bulk) failed: %d", rc);
acm_write_done(acm, wb);
}
@@ -262,6 +268,7 @@ static void acm_ctrl_irq(struct urb *urb)
{
struct acm *acm = urb->context;
struct usb_cdc_notification *dr = urb->transfer_buffer;
+ struct tty_struct *tty;
unsigned char *data;
int newctrl;
int retval;
@@ -287,40 +294,45 @@ static void acm_ctrl_irq(struct urb *urb)
data = (unsigned char *)(dr + 1);
switch (dr->bNotificationType) {
+ case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+ dbg("%s network", dr->wValue ?
+ "connected to" : "disconnected from");
+ break;
- case USB_CDC_NOTIFY_NETWORK_CONNECTION:
-
- dbg("%s network", dr->wValue ? "connected to" : "disconnected from");
- break;
-
- case USB_CDC_NOTIFY_SERIAL_STATE:
-
- newctrl = get_unaligned_le16(data);
+ case USB_CDC_NOTIFY_SERIAL_STATE:
+ tty = tty_port_tty_get(&acm->port);
+ newctrl = get_unaligned_le16(data);
- if (acm->tty && !acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
+ if (tty) {
+ if (!acm->clocal &&
+ (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
dbg("calling hangup");
- tty_hangup(acm->tty);
+ tty_hangup(tty);
}
+ tty_kref_put(tty);
+ }
- acm->ctrlin = newctrl;
-
- dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c",
- acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', acm->ctrlin & ACM_CTRL_DSR ? '+' : '-',
- acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', acm->ctrlin & ACM_CTRL_RI ? '+' : '-',
- acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-', acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
- acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');
+ acm->ctrlin = newctrl;
+ dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c",
+ acm->ctrlin & ACM_CTRL_DCD ? '+' : '-',
+ acm->ctrlin & ACM_CTRL_DSR ? '+' : '-',
+ acm->ctrlin & ACM_CTRL_BRK ? '+' : '-',
+ acm->ctrlin & ACM_CTRL_RI ? '+' : '-',
+ acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-',
+ acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
+ acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');
break;
- default:
- dbg("unknown notification %d received: index %d len %d data0 %d data1 %d",
- dr->bNotificationType, dr->wIndex,
- dr->wLength, data[0], data[1]);
- break;
+ default:
+ dbg("unknown notification %d received: index %d len %d data0 %d data1 %d",
+ dr->bNotificationType, dr->wIndex,
+ dr->wLength, data[0], data[1]);
+ break;
}
exit:
usb_mark_last_busy(acm->dev);
- retval = usb_submit_urb (urb, GFP_ATOMIC);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with "
"result %d", __func__, retval);
@@ -371,15 +383,14 @@ static void acm_rx_tasklet(unsigned long _acm)
{
struct acm *acm = (void *)_acm;
struct acm_rb *buf;
- struct tty_struct *tty = acm->tty;
+ struct tty_struct *tty;
struct acm_ru *rcv;
unsigned long flags;
unsigned char throttled;
dbg("Entering acm_rx_tasklet");
- if (!ACM_READY(acm))
- {
+ if (!ACM_READY(acm)) {
dbg("acm_rx_tasklet: ACM not ready");
return;
}
@@ -387,12 +398,13 @@ static void acm_rx_tasklet(unsigned long _acm)
spin_lock_irqsave(&acm->throttle_lock, flags);
throttled = acm->throttle;
spin_unlock_irqrestore(&acm->throttle_lock, flags);
- if (throttled)
- {
+ if (throttled) {
dbg("acm_rx_tasklet: throttled");
return;
}
+ tty = tty_port_tty_get(&acm->port);
+
next_buffer:
spin_lock_irqsave(&acm->read_lock, flags);
if (list_empty(&acm->filled_read_bufs)) {
@@ -406,20 +418,22 @@ next_buffer:
dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
- tty_buffer_request_room(tty, buf->size);
- spin_lock_irqsave(&acm->throttle_lock, flags);
- throttled = acm->throttle;
- spin_unlock_irqrestore(&acm->throttle_lock, flags);
- if (!throttled)
- tty_insert_flip_string(tty, buf->base, buf->size);
- tty_flip_buffer_push(tty);
-
- if (throttled) {
- dbg("Throttling noticed");
- spin_lock_irqsave(&acm->read_lock, flags);
- list_add(&buf->list, &acm->filled_read_bufs);
- spin_unlock_irqrestore(&acm->read_lock, flags);
- return;
+ if (tty) {
+ spin_lock_irqsave(&acm->throttle_lock, flags);
+ throttled = acm->throttle;
+ spin_unlock_irqrestore(&acm->throttle_lock, flags);
+ if (!throttled) {
+ tty_buffer_request_room(tty, buf->size);
+ tty_insert_flip_string(tty, buf->base, buf->size);
+ tty_flip_buffer_push(tty);
+ } else {
+ tty_kref_put(tty);
+ dbg("Throttling noticed");
+ spin_lock_irqsave(&acm->read_lock, flags);
+ list_add(&buf->list, &acm->filled_read_bufs);
+ spin_unlock_irqrestore(&acm->read_lock, flags);
+ return;
+ }
}
spin_lock_irqsave(&acm->read_lock, flags);
@@ -428,6 +442,8 @@ next_buffer:
goto next_buffer;
urbs:
+ tty_kref_put(tty);
+
while (!list_empty(&acm->spare_read_bufs)) {
spin_lock_irqsave(&acm->read_lock, flags);
if (list_empty(&acm->spare_read_urbs)) {
@@ -454,10 +470,11 @@ urbs:
rcv->urb->transfer_dma = buf->dma;
rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- /* This shouldn't kill the driver as unsuccessful URBs are returned to the
- free-urbs-pool and resubmited ASAP */
+ /* This shouldn't kill the driver as unsuccessful URBs are
+ returned to the free-urbs-pool and resubmited ASAP */
spin_lock_irqsave(&acm->read_lock, flags);
- if (acm->susp_count || usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
+ if (acm->susp_count ||
+ usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
list_add(&buf->list, &acm->spare_read_bufs);
list_add(&rcv->list, &acm->spare_read_urbs);
acm->processing = 0;
@@ -499,11 +516,14 @@ static void acm_write_bulk(struct urb *urb)
static void acm_softint(struct work_struct *work)
{
struct acm *acm = container_of(work, struct acm, work);
+ struct tty_struct *tty;
dev_vdbg(&acm->data->dev, "tx work\n");
if (!ACM_READY(acm))
return;
- tty_wakeup(acm->tty);
+ tty = tty_port_tty_get(&acm->port);
+ tty_wakeup(tty);
+ tty_kref_put(tty);
}
static void acm_waker(struct work_struct *waker)
@@ -543,8 +563,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
rv = 0;
set_bit(TTY_NO_WRITE_SPLIT, &tty->flags);
+
tty->driver_data = acm;
- acm->tty = tty;
+ tty_port_tty_set(&acm->port, tty);
if (usb_autopm_get_interface(acm->control) < 0)
goto early_bail;
@@ -552,11 +573,10 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
acm->control->needs_remote_wakeup = 1;
mutex_lock(&acm->mutex);
- if (acm->used++) {
+ if (acm->port.count++) {
usb_autopm_put_interface(acm->control);
goto done;
- }
-
+ }
acm->ctrlurb->dev = acm->dev;
if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) {
@@ -567,22 +587,22 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) &&
(acm->ctrl_caps & USB_CDC_CAP_LINE))
goto full_bailout;
+
usb_autopm_put_interface(acm->control);
INIT_LIST_HEAD(&acm->spare_read_urbs);
INIT_LIST_HEAD(&acm->spare_read_bufs);
INIT_LIST_HEAD(&acm->filled_read_bufs);
- for (i = 0; i < acm->rx_buflimit; i++) {
+
+ for (i = 0; i < acm->rx_buflimit; i++)
list_add(&(acm->ru[i].list), &acm->spare_read_urbs);
- }
- for (i = 0; i < acm->rx_buflimit; i++) {
+ for (i = 0; i < acm->rx_buflimit; i++)
list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
- }
acm->throttle = 0;
tasklet_schedule(&acm->urb_task);
-
+ rv = tty_port_block_til_ready(&acm->port, tty, filp);
done:
mutex_unlock(&acm->mutex);
err_out:
@@ -593,16 +613,17 @@ full_bailout:
usb_kill_urb(acm->ctrlurb);
bail_out:
usb_autopm_put_interface(acm->control);
- acm->used--;
+ acm->port.count--;
mutex_unlock(&acm->mutex);
early_bail:
mutex_unlock(&open_mutex);
+ tty_port_tty_set(&acm->port, NULL);
return -EIO;
}
static void acm_tty_unregister(struct acm *acm)
{
- int i,nr;
+ int i, nr;
nr = acm->rx_buflimit;
tty_unregister_device(acm_tty_driver, acm->minor);
@@ -619,41 +640,56 @@ static void acm_tty_unregister(struct acm *acm)
static int acm_tty_chars_in_buffer(struct tty_struct *tty);
+static void acm_port_down(struct acm *acm, int drain)
+{
+ int i, nr = acm->rx_buflimit;
+ mutex_lock(&open_mutex);
+ if (acm->dev) {
+ usb_autopm_get_interface(acm->control);
+ acm_set_control(acm, acm->ctrlout = 0);
+ /* try letting the last writes drain naturally */
+ if (drain) {
+ wait_event_interruptible_timeout(acm->drain_wait,
+ (ACM_NW == acm_wb_is_avail(acm)) || !acm->dev,
+ ACM_CLOSE_TIMEOUT * HZ);
+ }
+ usb_kill_urb(acm->ctrlurb);
+ for (i = 0; i < ACM_NW; i++)
+ usb_kill_urb(acm->wb[i].urb);
+ for (i = 0; i < nr; i++)
+ usb_kill_urb(acm->ru[i].urb);
+ acm->control->needs_remote_wakeup = 0;
+ usb_autopm_put_interface(acm->control);
+ }
+ mutex_unlock(&open_mutex);
+}
+
+static void acm_tty_hangup(struct tty_struct *tty)
+{
+ struct acm *acm = tty->driver_data;
+ tty_port_hangup(&acm->port);
+ acm_port_down(acm, 0);
+}
+
static void acm_tty_close(struct tty_struct *tty, struct file *filp)
{
struct acm *acm = tty->driver_data;
- int i,nr;
- if (!acm || !acm->used)
+ /* Perform the closing process and see if we need to do the hardware
+ shutdown */
+ if (tty_port_close_start(&acm->port, tty, filp) == 0)
return;
-
- nr = acm->rx_buflimit;
+ acm_port_down(acm, 0);
+ tty_port_close_end(&acm->port, tty);
mutex_lock(&open_mutex);
- if (!--acm->used) {
- if (acm->dev) {
- usb_autopm_get_interface(acm->control);
- acm_set_control(acm, acm->ctrlout = 0);
-
- /* try letting the last writes drain naturally */
- wait_event_interruptible_timeout(acm->drain_wait,
- (ACM_NW == acm_wb_is_avail(acm))
- || !acm->dev,
- ACM_CLOSE_TIMEOUT * HZ);
-
- usb_kill_urb(acm->ctrlurb);
- for (i = 0; i < ACM_NW; i++)
- usb_kill_urb(acm->wb[i].urb);
- for (i = 0; i < nr; i++)
- usb_kill_urb(acm->ru[i].urb);
- acm->control->needs_remote_wakeup = 0;
- usb_autopm_put_interface(acm->control);
- } else
- acm_tty_unregister(acm);
- }
+ tty_port_tty_set(&acm->port, NULL);
+ if (!acm->dev)
+ acm_tty_unregister(acm);
mutex_unlock(&open_mutex);
}
-static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
+static int acm_tty_write(struct tty_struct *tty,
+ const unsigned char *buf, int count)
{
struct acm *acm = tty->driver_data;
int stat;
@@ -669,7 +705,8 @@ static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int c
return 0;
spin_lock_irqsave(&acm->write_lock, flags);
- if ((wbn = acm_wb_alloc(acm)) < 0) {
+ wbn = acm_wb_alloc(acm);
+ if (wbn < 0) {
spin_unlock_irqrestore(&acm->write_lock, flags);
return 0;
}
@@ -681,7 +718,8 @@ static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int c
wb->len = count;
spin_unlock_irqrestore(&acm->write_lock, flags);
- if ((stat = acm_write_start(acm, wbn)) < 0)
+ stat = acm_write_start(acm, wbn);
+ if (stat < 0)
return stat;
return count;
}
@@ -767,8 +805,10 @@ static int acm_tty_tiocmset(struct tty_struct *tty, struct file *file,
return -EINVAL;
newctrl = acm->ctrlout;
- set = (set & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (set & TIOCM_RTS ? ACM_CTRL_RTS : 0);
- clear = (clear & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (clear & TIOCM_RTS ? ACM_CTRL_RTS : 0);
+ set = (set & TIOCM_DTR ? ACM_CTRL_DTR : 0) |
+ (set & TIOCM_RTS ? ACM_CTRL_RTS : 0);
+ clear = (clear & TIOCM_DTR ? ACM_CTRL_DTR : 0) |
+ (clear & TIOCM_RTS ? ACM_CTRL_RTS : 0);
newctrl = (newctrl & ~clear) | set;
@@ -777,7 +817,8 @@ static int acm_tty_tiocmset(struct tty_struct *tty, struct file *file,
return acm_set_control(acm, acm->ctrlout = newctrl);
}
-static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
+static int acm_tty_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
struct acm *acm = tty->driver_data;
@@ -799,7 +840,8 @@ static const __u8 acm_tty_size[] = {
5, 6, 7, 8
};
-static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old)
+static void acm_tty_set_termios(struct tty_struct *tty,
+ struct ktermios *termios_old)
{
struct acm *acm = tty->driver_data;
struct ktermios *termios = tty->termios;
@@ -809,19 +851,23 @@ static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios
if (!ACM_READY(acm))
return;
+ /* FIXME: Needs to support the tty_baud interface */
+ /* FIXME: Broken on sparc */
newline.dwDTERate = cpu_to_le32p(acm_tty_speed +
(termios->c_cflag & CBAUD & ~CBAUDEX) + (termios->c_cflag & CBAUDEX ? 15 : 0));
newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;
newline.bParityType = termios->c_cflag & PARENB ?
- (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0;
+ (termios->c_cflag & PARODD ? 1 : 2) +
+ (termios->c_cflag & CMSPAR ? 2 : 0) : 0;
newline.bDataBits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4];
-
+ /* FIXME: Needs to clear unsupported bits in the termios */
acm->clocal = ((termios->c_cflag & CLOCAL) != 0);
if (!newline.dwDTERate) {
newline.dwDTERate = acm->line.dwDTERate;
newctrl &= ~ACM_CTRL_DTR;
- } else newctrl |= ACM_CTRL_DTR;
+ } else
+ newctrl |= ACM_CTRL_DTR;
if (newctrl != acm->ctrlout)
acm_set_control(acm, acm->ctrlout = newctrl);
@@ -846,9 +892,8 @@ static void acm_write_buffers_free(struct acm *acm)
struct acm_wb *wb;
struct usb_device *usb_dev = interface_to_usbdev(acm->control);
- for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
+ for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++)
usb_buffer_free(usb_dev, acm->writesize, wb->buf, wb->dmah);
- }
}
static void acm_read_buffers_free(struct acm *acm)
@@ -857,7 +902,8 @@ static void acm_read_buffers_free(struct acm *acm)
int i, n = acm->rx_buflimit;
for (i = 0; i < n; i++)
- usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
+ usb_buffer_free(usb_dev, acm->readsize,
+ acm->rb[i].base, acm->rb[i].dma);
}
/* Little helper: write buffers allocate */
@@ -882,8 +928,8 @@ static int acm_write_buffers_alloc(struct acm *acm)
return 0;
}
-static int acm_probe (struct usb_interface *intf,
- const struct usb_device_id *id)
+static int acm_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
struct usb_cdc_union_desc *union_header = NULL;
struct usb_cdc_country_functional_desc *cfd = NULL;
@@ -897,7 +943,7 @@ static int acm_probe (struct usb_interface *intf,
struct usb_device *usb_dev = interface_to_usbdev(intf);
struct acm *acm;
int minor;
- int ctrlsize,readsize;
+ int ctrlsize, readsize;
u8 *buf;
u8 ac_management_function = 0;
u8 call_management_function = 0;
@@ -917,7 +963,7 @@ static int acm_probe (struct usb_interface *intf,
control_interface = usb_ifnum_to_if(usb_dev, 0);
goto skip_normal_probe;
}
-
+
/* normal probing*/
if (!buffer) {
dev_err(&intf->dev, "Weird descriptor references\n");
@@ -925,8 +971,10 @@ static int acm_probe (struct usb_interface *intf,
}
if (!buflen) {
- if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) {
- dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n");
+ if (intf->cur_altsetting->endpoint->extralen &&
+ intf->cur_altsetting->endpoint->extra) {
+ dev_dbg(&intf->dev,
+ "Seeking extra descriptors on endpoint\n");
buflen = intf->cur_altsetting->endpoint->extralen;
buffer = intf->cur_altsetting->endpoint->extra;
} else {
@@ -937,47 +985,43 @@ static int acm_probe (struct usb_interface *intf,
}
while (buflen > 0) {
- if (buffer [1] != USB_DT_CS_INTERFACE) {
+ if (buffer[1] != USB_DT_CS_INTERFACE) {
dev_err(&intf->dev, "skipping garbage\n");
goto next_desc;
}
- switch (buffer [2]) {
- case USB_CDC_UNION_TYPE: /* we've found it */
- if (union_header) {
- dev_err(&intf->dev, "More than one "
- "union descriptor, "
- "skipping ...\n");
- goto next_desc;
- }
- union_header = (struct usb_cdc_union_desc *)
- buffer;
- break;
- case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/
- cfd = (struct usb_cdc_country_functional_desc *)buffer;
- break;
- case USB_CDC_HEADER_TYPE: /* maybe check version */
- break; /* for now we ignore it */
- case USB_CDC_ACM_TYPE:
- ac_management_function = buffer[3];
- break;
- case USB_CDC_CALL_MANAGEMENT_TYPE:
- call_management_function = buffer[3];
- call_interface_num = buffer[4];
- if ((call_management_function & 3) != 3)
- dev_err(&intf->dev, "This device "
- "cannot do calls on its own. "
- "It is no modem.\n");
- break;
- default:
- /* there are LOTS more CDC descriptors that
- * could legitimately be found here.
- */
- dev_dbg(&intf->dev, "Ignoring descriptor: "
- "type %02x, length %d\n",
- buffer[2], buffer[0]);
- break;
+ switch (buffer[2]) {
+ case USB_CDC_UNION_TYPE: /* we've found it */
+ if (union_header) {
+ dev_err(&intf->dev, "More than one "
+ "union descriptor, skipping ...\n");
+ goto next_desc;
}
+ union_header = (struct usb_cdc_union_desc *)buffer;
+ break;
+ case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/
+ cfd = (struct usb_cdc_country_functional_desc *)buffer;
+ break;
+ case USB_CDC_HEADER_TYPE: /* maybe check version */
+ break; /* for now we ignore it */
+ case USB_CDC_ACM_TYPE:
+ ac_management_function = buffer[3];
+ break;
+ case USB_CDC_CALL_MANAGEMENT_TYPE:
+ call_management_function = buffer[3];
+ call_interface_num = buffer[4];
+ if ((call_management_function & 3) != 3)
+ dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n");
+ break;
+ default:
+ /* there are LOTS more CDC descriptors that
+ * could legitimately be found here.
+ */
+ dev_dbg(&intf->dev, "Ignoring descriptor: "
+ "type %02x, length %d\n",
+ buffer[2], buffer[0]);
+ break;
+ }
next_desc:
buflen -= buffer[0];
buffer += buffer[0];
@@ -985,33 +1029,36 @@ next_desc:
if (!union_header) {
if (call_interface_num > 0) {
- dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n");
+ 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\n");
+ 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\n");
+ dev_dbg(&intf->dev, "no interfaces\n");
return -ENODEV;
}
}
-
+
if (data_interface_num != call_interface_num)
- dev_dbg(&intf->dev,"Separate call control interface. That is not fully supported.\n");
+ dev_dbg(&intf->dev, "Separate call control interface. That is not fully supported.\n");
skip_normal_probe:
/*workaround for switched interfaces */
- if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
- if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) {
+ 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.\n");
-
+ dev_dbg(&intf->dev,
+ "Your device has switched interfaces.\n");
t = control_interface;
control_interface = data_interface;
data_interface = t;
@@ -1023,9 +1070,9 @@ skip_normal_probe:
/* Accept probe requests only for the control interface */
if (intf != control_interface)
return -ENODEV;
-
+
if (usb_interface_claimed(data_interface)) { /* valid in this context */
- dev_dbg(&intf->dev,"The data interface isn't available\n");
+ dev_dbg(&intf->dev, "The data interface isn't available\n");
return -EBUSY;
}
@@ -1042,8 +1089,8 @@ 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\n");
-
+ dev_dbg(&intf->dev,
+ "The data interface has switched endpoints\n");
t = epread;
epread = epwrite;
epwrite = t;
@@ -1056,13 +1103,15 @@ skip_normal_probe:
return -ENODEV;
}
- if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) {
+ acm = kzalloc(sizeof(struct acm), GFP_KERNEL);
+ if (acm == NULL) {
dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n");
goto alloc_fail;
}
ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
- readsize = le16_to_cpu(epread->wMaxPacketSize)* ( quirks == SINGLE_RX_URB ? 1 : 2);
+ readsize = le16_to_cpu(epread->wMaxPacketSize) *
+ (quirks == SINGLE_RX_URB ? 1 : 2);
acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize) * 20;
acm->control = control_interface;
acm->data = data_interface;
@@ -1082,6 +1131,8 @@ skip_normal_probe:
spin_lock_init(&acm->read_lock);
mutex_init(&acm->mutex);
acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);
+ tty_port_init(&acm->port);
+ acm->port.ops = &acm_port_ops;
buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
if (!buf) {
@@ -1103,8 +1154,10 @@ skip_normal_probe:
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)\n");
+ rcv->urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (rcv->urb == NULL) {
+ dev_dbg(&intf->dev,
+ "out of memory (read urbs usb_alloc_urb)\n");
goto alloc_fail7;
}
@@ -1117,26 +1170,29 @@ skip_normal_probe:
rb->base = usb_buffer_alloc(acm->dev, readsize,
GFP_KERNEL, &rb->dma);
if (!rb->base) {
- dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
+ dev_dbg(&intf->dev,
+ "out of memory (read bufs usb_buffer_alloc)\n");
goto alloc_fail7;
}
}
- for(i = 0; i < ACM_NW; i++)
- {
+ for (i = 0; i < ACM_NW; i++) {
struct acm_wb *snd = &(acm->wb[i]);
- if (!(snd->urb = usb_alloc_urb(0, GFP_KERNEL))) {
- dev_dbg(&intf->dev, "out of memory (write urbs usb_alloc_urb)");
+ snd->urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (snd->urb == NULL) {
+ dev_dbg(&intf->dev,
+ "out of memory (write urbs usb_alloc_urb)");
goto alloc_fail7;
}
- usb_fill_bulk_urb(snd->urb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
- NULL, acm->writesize, acm_write_bulk, snd);
+ usb_fill_bulk_urb(snd->urb, usb_dev,
+ usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
+ NULL, acm->writesize, acm_write_bulk, snd);
snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
snd->instance = acm;
}
- usb_set_intfdata (intf, acm);
+ usb_set_intfdata(intf, acm);
i = device_create_file(&intf->dev, &dev_attr_bmCapabilities);
if (i < 0)
@@ -1147,7 +1203,8 @@ skip_normal_probe:
if (!acm->country_codes)
goto skip_countries;
acm->country_code_size = cfd->bLength - 4;
- memcpy(acm->country_codes, (u8 *)&cfd->wCountyCode0, cfd->bLength - 4);
+ memcpy(acm->country_codes, (u8 *)&cfd->wCountyCode0,
+ cfd->bLength - 4);
acm->country_rel_date = cfd->iCountryCodeRelDate;
i = device_create_file(&intf->dev, &dev_attr_wCountryCodes);
@@ -1156,7 +1213,8 @@ skip_normal_probe:
goto skip_countries;
}
- i = device_create_file(&intf->dev, &dev_attr_iCountryCodeRelDate);
+ i = device_create_file(&intf->dev,
+ &dev_attr_iCountryCodeRelDate);
if (i < 0) {
kfree(acm->country_codes);
goto skip_countries;
@@ -1164,8 +1222,10 @@ skip_normal_probe:
}
skip_countries:
- usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress),
- acm->ctrl_buffer, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
+ usb_fill_int_urb(acm->ctrlurb, usb_dev,
+ usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress),
+ acm->ctrl_buffer, ctrlsize, acm_ctrl_irq, acm,
+ epctrl->bInterval);
acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
acm->ctrlurb->transfer_dma = acm->ctrl_dma;
@@ -1212,7 +1272,7 @@ static void stop_data_traffic(struct acm *acm)
tasklet_disable(&acm->urb_task);
usb_kill_urb(acm->ctrlurb);
- for(i = 0; i < ACM_NW; i++)
+ for (i = 0; i < ACM_NW; i++)
usb_kill_urb(acm->wb[i].urb);
for (i = 0; i < acm->rx_buflimit; i++)
usb_kill_urb(acm->ru[i].urb);
@@ -1227,13 +1287,14 @@ static void acm_disconnect(struct usb_interface *intf)
{
struct acm *acm = usb_get_intfdata(intf);
struct usb_device *usb_dev = interface_to_usbdev(intf);
+ struct tty_struct *tty;
/* sibling interface is already cleaning up */
if (!acm)
return;
mutex_lock(&open_mutex);
- if (acm->country_codes){
+ if (acm->country_codes) {
device_remove_file(&acm->control->dev,
&dev_attr_wCountryCodes);
device_remove_file(&acm->control->dev,
@@ -1247,22 +1308,25 @@ static void acm_disconnect(struct usb_interface *intf)
stop_data_traffic(acm);
acm_write_buffers_free(acm);
- usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
+ usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer,
+ acm->ctrl_dma);
acm_read_buffers_free(acm);
usb_driver_release_interface(&acm_driver, intf == acm->control ?
acm->data : acm->control);
- if (!acm->used) {
+ if (acm->port.count == 0) {
acm_tty_unregister(acm);
mutex_unlock(&open_mutex);
return;
}
mutex_unlock(&open_mutex);
-
- if (acm->tty)
- tty_hangup(acm->tty);
+ tty = tty_port_tty_get(&acm->port);
+ if (tty) {
+ tty_hangup(tty);
+ tty_kref_put(tty);
+ }
}
#ifdef CONFIG_PM
@@ -1297,7 +1361,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
*/
mutex_lock(&acm->mutex);
- if (acm->used)
+ if (acm->port.count)
stop_data_traffic(acm);
mutex_unlock(&acm->mutex);
@@ -1319,7 +1383,7 @@ static int acm_resume(struct usb_interface *intf)
return 0;
mutex_lock(&acm->mutex);
- if (acm->used) {
+ if (acm->port.count) {
rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
if (rv < 0)
goto err_out;
@@ -1375,6 +1439,9 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
+ { USB_DEVICE(0x0572, 0x1328), /* Shiro / Aztech USB MODEM UM-3100 */
+ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ },
{ USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
},
{ USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
@@ -1395,7 +1462,7 @@ static struct usb_device_id acm_ids[] = {
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
USB_CDC_ACM_PROTO_AT_GSM) },
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
- USB_CDC_ACM_PROTO_AT_3G ) },
+ USB_CDC_ACM_PROTO_AT_3G) },
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
USB_CDC_ACM_PROTO_AT_CDMA) },
@@ -1403,7 +1470,7 @@ static struct usb_device_id acm_ids[] = {
{ }
};
-MODULE_DEVICE_TABLE (usb, acm_ids);
+MODULE_DEVICE_TABLE(usb, acm_ids);
static struct usb_driver acm_driver = {
.name = "cdc_acm",
@@ -1426,6 +1493,7 @@ static struct usb_driver acm_driver = {
static const struct tty_operations acm_ops = {
.open = acm_tty_open,
.close = acm_tty_close,
+ .hangup = acm_tty_hangup,
.write = acm_tty_write,
.write_room = acm_tty_write_room,
.ioctl = acm_tty_ioctl,
@@ -1457,7 +1525,8 @@ static int __init acm_init(void)
acm_tty_driver->subtype = SERIAL_TYPE_NORMAL,
acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
acm_tty_driver->init_termios = tty_std_termios;
- acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD |
+ HUPCL | CLOCAL;
tty_set_operations(acm_tty_driver, &acm_ops);
retval = tty_register_driver(acm_tty_driver);
@@ -1489,7 +1558,7 @@ static void __exit acm_exit(void)
module_init(acm_init);
module_exit(acm_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(ACM_TTY_MAJOR);
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index 1f95e7aa1b66..4c3856420add 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -89,8 +89,8 @@ struct acm {
struct usb_device *dev; /* the corresponding usb device */
struct usb_interface *control; /* control interface */
struct usb_interface *data; /* data interface */
- struct tty_struct *tty; /* the corresponding tty */
- struct urb *ctrlurb; /* urbs */
+ struct tty_port port; /* our tty port data */
+ struct urb *ctrlurb; /* urbs */
u8 *ctrl_buffer; /* buffers of urbs */
dma_addr_t ctrl_dma; /* dma handles of buffers */
u8 *country_codes; /* country codes from device */
@@ -120,7 +120,6 @@ struct acm {
unsigned int ctrlout; /* output control lines (DTR, RTS) */
unsigned int writesize; /* max packet size for the output bulk endpoint */
unsigned int readsize,ctrlsize; /* buffer sizes for freeing */
- unsigned int used; /* someone has this acm's device open */
unsigned int minor; /* acm minor number */
unsigned char throttle; /* throttled by tty layer */
unsigned char clocal; /* termios CLOCAL */
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 563d57275448..05c913cc3658 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -794,7 +794,8 @@ usba_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
if (ep->desc) {
list_add_tail(&req->queue, &ep->queue);
- if (ep->is_in || (ep_is_control(ep)
+ if ((!ep_is_control(ep) && ep->is_in) ||
+ (ep_is_control(ep)
&& (ep->state == DATA_STAGE_IN
|| ep->state == STATUS_STAGE_IN)))
usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY);
@@ -1940,7 +1941,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
usba_writel(udc, CTRL, USBA_DISABLE_MASK);
clk_disable(pclk);
- usba_ep = kmalloc(sizeof(struct usba_ep) * pdata->num_ep,
+ usba_ep = kzalloc(sizeof(struct usba_ep) * pdata->num_ep,
GFP_KERNEL);
if (!usba_ep)
goto err_alloc_ep;
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c
index 4154be375c7a..58c4d37d312a 100644
--- a/drivers/usb/gadget/usbstring.c
+++ b/drivers/usb/gadget/usbstring.c
@@ -38,7 +38,7 @@ static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len)
uchar = (c & 0x1f) << 6;
c = (u8) *s++;
- if ((c & 0xc0) != 0xc0)
+ if ((c & 0xc0) != 0x80)
goto fail;
c &= 0x3f;
uchar |= c;
@@ -49,13 +49,13 @@ static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len)
uchar = (c & 0x0f) << 12;
c = (u8) *s++;
- if ((c & 0xc0) != 0xc0)
+ if ((c & 0xc0) != 0x80)
goto fail;
c &= 0x3f;
uchar |= c << 6;
c = (u8) *s++;
- if ((c & 0xc0) != 0xc0)
+ if ((c & 0xc0) != 0x80)
goto fail;
c &= 0x3f;
uchar |= c;
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index cd07ea3f0c63..15438469f21a 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -1658,6 +1658,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
u32 reg_base, or_reg, skip_reg;
unsigned long flags;
struct ptd ptd;
+ packet_enqueue *pe;
switch (usb_pipetype(urb->pipe)) {
case PIPE_ISOCHRONOUS:
@@ -1669,6 +1670,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
reg_base = INT_REGS_OFFSET;
or_reg = HC_INT_IRQ_MASK_OR_REG;
skip_reg = HC_INT_PTD_SKIPMAP_REG;
+ pe = enqueue_an_INT_packet;
break;
default:
@@ -1676,6 +1678,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
reg_base = ATL_REGS_OFFSET;
or_reg = HC_ATL_IRQ_MASK_OR_REG;
skip_reg = HC_ATL_PTD_SKIPMAP_REG;
+ pe = enqueue_an_ATL_packet;
break;
}
@@ -1687,6 +1690,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
u32 skip_map;
u32 or_map;
struct isp1760_qtd *qtd;
+ struct isp1760_qh *qh = ints->qh;
skip_map = isp1760_readl(hcd->regs + skip_reg);
skip_map |= 1 << i;
@@ -1699,8 +1703,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
priv_write_copy(priv, (u32 *)&ptd, hcd->regs + reg_base
+ i * sizeof(ptd), sizeof(ptd));
qtd = ints->qtd;
-
- clean_up_qtdlist(qtd);
+ qtd = clean_up_qtdlist(qtd);
free_mem(priv, ints->payload);
@@ -1711,7 +1714,24 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
ints->payload = 0;
isp1760_urb_done(priv, urb, status);
+ if (qtd)
+ pe(hcd, qh, qtd);
break;
+
+ } else if (ints->qtd) {
+ struct isp1760_qtd *qtd, *prev_qtd = ints->qtd;
+
+ for (qtd = ints->qtd->hw_next; qtd; qtd = qtd->hw_next) {
+ if (qtd->urb == urb) {
+ prev_qtd->hw_next = clean_up_qtdlist(qtd);
+ isp1760_urb_done(priv, urb, status);
+ break;
+ }
+ prev_qtd = qtd;
+ }
+ /* we found the urb before the end of the list */
+ if (qtd)
+ break;
}
ints++;
}
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index b7eacad4d48c..2bfd6dd85b5a 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -93,8 +93,7 @@ static int belkin_sa_startup(struct usb_serial *serial);
static void belkin_sa_shutdown(struct usb_serial *serial);
static int belkin_sa_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
-static void belkin_sa_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+static void belkin_sa_close(struct usb_serial_port *port);
static void belkin_sa_read_int_callback(struct urb *urb);
static void belkin_sa_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios * old);
@@ -244,8 +243,7 @@ exit:
} /* belkin_sa_open */
-static void belkin_sa_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void belkin_sa_close(struct usb_serial_port *port)
{
dbg("%s port %d", __func__, port->number);
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index ab4cc277aa65..2830766f5b39 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -262,32 +262,40 @@ error: kfree(priv);
return r;
}
-static void ch341_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp)
+static int ch341_carrier_raised(struct usb_serial_port *port)
+{
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ if (priv->line_status & CH341_BIT_DCD)
+ return 1;
+ return 0;
+}
+
+static void ch341_dtr_rts(struct usb_serial_port *port, int on)
{
struct ch341_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
- unsigned int c_cflag;
dbg("%s - port %d", __func__, port->number);
+ /* drop DTR and RTS */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (on)
+ priv->line_control |= CH341_BIT_RTS | CH341_BIT_DTR;
+ else
+ priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ch341_set_handshake(port->serial->dev, priv->line_control);
+ wake_up_interruptible(&priv->delta_msr_wait);
+}
+
+static void ch341_close(struct usb_serial_port *port)
+{
+ dbg("%s - port %d", __func__, port->number);
/* shutdown our urbs */
dbg("%s - shutting down urbs", __func__);
usb_kill_urb(port->write_urb);
usb_kill_urb(port->read_urb);
usb_kill_urb(port->interrupt_in_urb);
-
- if (tty) {
- c_cflag = tty->termios->c_cflag;
- if (c_cflag & HUPCL) {
- /* drop DTR and RTS */
- spin_lock_irqsave(&priv->lock, flags);
- priv->line_control = 0;
- spin_unlock_irqrestore(&priv->lock, flags);
- ch341_set_handshake(port->serial->dev, 0);
- }
- }
- wake_up_interruptible(&priv->delta_msr_wait);
}
@@ -302,7 +310,6 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
dbg("ch341_open()");
priv->baud_rate = DEFAULT_BAUD_RATE;
- priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
r = ch341_configure(serial->dev, priv);
if (r)
@@ -322,7 +329,7 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
if (r) {
dev_err(&port->dev, "%s - failed submitting interrupt urb,"
" error %d\n", __func__, r);
- ch341_close(tty, port, NULL);
+ ch341_close(port);
return -EPROTO;
}
@@ -343,9 +350,6 @@ static void ch341_set_termios(struct tty_struct *tty,
dbg("ch341_set_termios()");
- if (!tty || !tty->termios)
- return;
-
baud_rate = tty_get_baud_rate(tty);
priv->baud_rate = baud_rate;
@@ -568,6 +572,8 @@ static struct usb_serial_driver ch341_device = {
.usb_driver = &ch341_driver,
.num_ports = 1,
.open = ch341_open,
+ .dtr_rts = ch341_dtr_rts,
+ .carrier_raised = ch341_carrier_raised,
.close = ch341_close,
.ioctl = ch341_ioctl,
.set_termios = ch341_set_termios,
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 19e24045b137..247b61bfb7f4 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -169,7 +169,9 @@ static int usb_console_setup(struct console *co, char *options)
kfree(tty);
}
}
-
+ /* So we know not to kill the hardware on a hangup on this
+ port. We have also bumped the use count by one so it won't go
+ idle */
port->console = 1;
retval = 0;
@@ -182,7 +184,7 @@ free_tty:
kfree(tty);
reset_open_count:
port->port.count = 0;
-goto out;
+ goto out;
}
static void usb_console_write(struct console *co,
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index e8d5133ce9c8..d9f586dc6ecc 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -36,8 +36,7 @@
static int cp2101_open(struct tty_struct *, struct usb_serial_port *,
struct file *);
static void cp2101_cleanup(struct usb_serial_port *);
-static void cp2101_close(struct tty_struct *, struct usb_serial_port *,
- struct file*);
+static void cp2101_close(struct usb_serial_port *);
static void cp2101_get_termios(struct tty_struct *,
struct usb_serial_port *port);
static void cp2101_get_termios_port(struct usb_serial_port *port,
@@ -398,8 +397,7 @@ static void cp2101_cleanup(struct usb_serial_port *port)
}
}
-static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp)
+static void cp2101_close(struct usb_serial_port *port)
{
dbg("%s - port %d", __func__, port->number);
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index dd501bb63ed6..933ba913e66c 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -61,8 +61,7 @@ static int cyberjack_startup(struct usb_serial *serial);
static void cyberjack_shutdown(struct usb_serial *serial);
static int cyberjack_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
-static void cyberjack_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+static void cyberjack_close(struct usb_serial_port *port);
static int cyberjack_write(struct tty_struct *tty,
struct usb_serial_port *port, const unsigned char *buf, int count);
static int cyberjack_write_room(struct tty_struct *tty);
@@ -185,8 +184,7 @@ static int cyberjack_open(struct tty_struct *tty,
return result;
}
-static void cyberjack_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void cyberjack_close(struct usb_serial_port *port)
{
dbg("%s - port %d", __func__, port->number);
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index e568710b263f..669f93848539 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -174,8 +174,8 @@ static int cypress_ca42v2_startup(struct usb_serial *serial);
static void cypress_shutdown(struct usb_serial *serial);
static int cypress_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
-static void cypress_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+static void cypress_close(struct usb_serial_port *port);
+static void cypress_dtr_rts(struct usb_serial_port *port, int on);
static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
static void cypress_send(struct usb_serial_port *port);
@@ -218,6 +218,7 @@ static struct usb_serial_driver cypress_earthmate_device = {
.shutdown = cypress_shutdown,
.open = cypress_open,
.close = cypress_close,
+ .dtr_rts = cypress_dtr_rts,
.write = cypress_write,
.write_room = cypress_write_room,
.ioctl = cypress_ioctl,
@@ -244,6 +245,7 @@ static struct usb_serial_driver cypress_hidcom_device = {
.shutdown = cypress_shutdown,
.open = cypress_open,
.close = cypress_close,
+ .dtr_rts = cypress_dtr_rts,
.write = cypress_write,
.write_room = cypress_write_room,
.ioctl = cypress_ioctl,
@@ -270,6 +272,7 @@ static struct usb_serial_driver cypress_ca42v2_device = {
.shutdown = cypress_shutdown,
.open = cypress_open,
.close = cypress_close,
+ .dtr_rts = cypress_dtr_rts,
.write = cypress_write,
.write_room = cypress_write_room,
.ioctl = cypress_ioctl,
@@ -656,11 +659,7 @@ static int cypress_open(struct tty_struct *tty,
priv->rx_flags = 0;
spin_unlock_irqrestore(&priv->lock, flags);
- /* raise both lines and set termios */
- spin_lock_irqsave(&priv->lock, flags);
- priv->line_control = CONTROL_DTR | CONTROL_RTS;
- priv->cmd_ctrl = 1;
- spin_unlock_irqrestore(&priv->lock, flags);
+ /* Set termios */
result = cypress_write(tty, port, NULL, 0);
if (result) {
@@ -694,76 +693,42 @@ static int cypress_open(struct tty_struct *tty,
__func__, result);
cypress_set_dead(port);
}
-
+ port->port.drain_delay = 256;
return result;
} /* cypress_open */
+static void cypress_dtr_rts(struct usb_serial_port *port, int on)
+{
+ struct cypress_private *priv = usb_get_serial_port_data(port);
+ /* drop dtr and rts */
+ priv = usb_get_serial_port_data(port);
+ spin_lock_irq(&priv->lock);
+ if (on == 0)
+ priv->line_control = 0;
+ else
+ priv->line_control = CONTROL_DTR | CONTROL_RTS;
+ priv->cmd_ctrl = 1;
+ spin_unlock_irq(&priv->lock);
+ cypress_write(NULL, port, NULL, 0);
+}
-static void cypress_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void cypress_close(struct usb_serial_port *port)
{
struct cypress_private *priv = usb_get_serial_port_data(port);
- unsigned int c_cflag;
- int bps;
- long timeout;
- wait_queue_t wait;
dbg("%s - port %d", __func__, port->number);
- /* wait for data to drain from buffer */
- spin_lock_irq(&priv->lock);
- timeout = CYPRESS_CLOSING_WAIT;
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&tty->write_wait, &wait);
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (cypress_buf_data_avail(priv->buf) == 0
- || timeout == 0 || signal_pending(current)
- /* without mutex, allowed due to harmless failure mode */
- || port->serial->disconnected)
- break;
- spin_unlock_irq(&priv->lock);
- timeout = schedule_timeout(timeout);
- spin_lock_irq(&priv->lock);
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&tty->write_wait, &wait);
- /* clear out any remaining data in the buffer */
- cypress_buf_clear(priv->buf);
- spin_unlock_irq(&priv->lock);
-
/* writing is potentially harmful, lock must be taken */
mutex_lock(&port->serial->disc_mutex);
if (port->serial->disconnected) {
mutex_unlock(&port->serial->disc_mutex);
return;
}
- /* wait for characters to drain from device */
- if (tty) {
- bps = tty_get_baud_rate(tty);
- if (bps > 1200)
- timeout = max((HZ * 2560) / bps, HZ / 10);
- else
- timeout = 2 * HZ;
- schedule_timeout_interruptible(timeout);
- }
-
+ cypress_buf_clear(priv->buf);
dbg("%s - stopping urbs", __func__);
usb_kill_urb(port->interrupt_in_urb);
usb_kill_urb(port->interrupt_out_urb);
- if (tty) {
- c_cflag = tty->termios->c_cflag;
- if (c_cflag & HUPCL) {
- /* drop dtr and rts */
- priv = usb_get_serial_port_data(port);
- spin_lock_irq(&priv->lock);
- priv->line_control = 0;
- priv->cmd_ctrl = 1;
- spin_unlock_irq(&priv->lock);
- cypress_write(tty, port, NULL, 0);
- }
- }
if (stats)
dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 38ba4ea8b6bf..30f5140eff03 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -422,7 +422,6 @@ struct digi_port {
int dp_throttled;
int dp_throttle_restart;
wait_queue_head_t dp_flush_wait;
- int dp_in_close; /* close in progress */
wait_queue_head_t dp_close_wait; /* wait queue for close */
struct work_struct dp_wakeup_work;
struct usb_serial_port *dp_port;
@@ -456,8 +455,9 @@ static int digi_write_room(struct tty_struct *tty);
static int digi_chars_in_buffer(struct tty_struct *tty);
static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp);
-static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp);
+static void digi_close(struct usb_serial_port *port);
+static int digi_carrier_raised(struct usb_serial_port *port);
+static void digi_dtr_rts(struct usb_serial_port *port, int on);
static int digi_startup_device(struct usb_serial *serial);
static int digi_startup(struct usb_serial *serial);
static void digi_shutdown(struct usb_serial *serial);
@@ -510,6 +510,8 @@ static struct usb_serial_driver digi_acceleport_2_device = {
.num_ports = 3,
.open = digi_open,
.close = digi_close,
+ .dtr_rts = digi_dtr_rts,
+ .carrier_raised = digi_carrier_raised,
.write = digi_write,
.write_room = digi_write_room,
.write_bulk_callback = digi_write_bulk_callback,
@@ -1328,6 +1330,19 @@ static int digi_chars_in_buffer(struct tty_struct *tty)
}
+static void digi_dtr_rts(struct usb_serial_port *port, int on)
+{
+ /* Adjust DTR and RTS */
+ digi_set_modem_signals(port, on * (TIOCM_DTR|TIOCM_RTS), 1);
+}
+
+static int digi_carrier_raised(struct usb_serial_port *port)
+{
+ struct digi_port *priv = usb_get_serial_port_data(port);
+ if (priv->dp_modem_signals & TIOCM_CD)
+ return 1;
+ return 0;
+}
static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp)
@@ -1336,7 +1351,6 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
unsigned char buf[32];
struct digi_port *priv = usb_get_serial_port_data(port);
struct ktermios not_termios;
- unsigned long flags = 0;
dbg("digi_open: TOP: port=%d, open_count=%d",
priv->dp_port_num, port->port.count);
@@ -1345,26 +1359,6 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
if (digi_startup_device(port->serial) != 0)
return -ENXIO;
- spin_lock_irqsave(&priv->dp_port_lock, flags);
-
- /* don't wait on a close in progress for non-blocking opens */
- if (priv->dp_in_close && (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) {
- spin_unlock_irqrestore(&priv->dp_port_lock, flags);
- return -EAGAIN;
- }
-
- /* wait for a close in progress to finish */
- while (priv->dp_in_close) {
- cond_wait_interruptible_timeout_irqrestore(
- &priv->dp_close_wait, DIGI_RETRY_TIMEOUT,
- &priv->dp_port_lock, flags);
- if (signal_pending(current))
- return -EINTR;
- spin_lock_irqsave(&priv->dp_port_lock, flags);
- }
-
- spin_unlock_irqrestore(&priv->dp_port_lock, flags);
-
/* read modem signals automatically whenever they change */
buf[0] = DIGI_CMD_READ_INPUT_SIGNALS;
buf[1] = priv->dp_port_num;
@@ -1387,16 +1381,11 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
not_termios.c_iflag = ~tty->termios->c_iflag;
digi_set_termios(tty, port, &not_termios);
}
-
- /* set DTR and RTS */
- digi_set_modem_signals(port, TIOCM_DTR|TIOCM_RTS, 1);
-
return 0;
}
-static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp)
+static void digi_close(struct usb_serial_port *port)
{
DEFINE_WAIT(wait);
int ret;
@@ -1411,28 +1400,9 @@ static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,
if (port->serial->disconnected)
goto exit;
- /* do cleanup only after final close on this port */
- spin_lock_irq(&priv->dp_port_lock);
- priv->dp_in_close = 1;
- spin_unlock_irq(&priv->dp_port_lock);
-
- /* tell line discipline to process only XON/XOFF */
- tty->closing = 1;
-
- /* wait for output to drain */
- if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0)
- tty_wait_until_sent(tty, DIGI_CLOSE_TIMEOUT);
-
- /* flush driver and line discipline buffers */
- tty_driver_flush_buffer(tty);
- tty_ldisc_flush(tty);
-
if (port->serial->dev) {
- /* wait for transmit idle */
- if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0)
- digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT);
- /* drop DTR and RTS */
- digi_set_modem_signals(port, 0, 0);
+ /* FIXME: Transmit idle belongs in the wait_unti_sent path */
+ digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT);
/* disable input flow control */
buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL;
@@ -1477,11 +1447,9 @@ static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,
/* shutdown any outstanding bulk writes */
usb_kill_urb(port->write_urb);
}
- tty->closing = 0;
exit:
spin_lock_irq(&priv->dp_port_lock);
priv->dp_write_urb_in_use = 0;
- priv->dp_in_close = 0;
wake_up_interruptible(&priv->dp_close_wait);
spin_unlock_irq(&priv->dp_port_lock);
mutex_unlock(&port->serial->disc_mutex);
@@ -1560,7 +1528,6 @@ static int digi_startup(struct usb_serial *serial)
priv->dp_throttled = 0;
priv->dp_throttle_restart = 0;
init_waitqueue_head(&priv->dp_flush_wait);
- priv->dp_in_close = 0;
init_waitqueue_head(&priv->dp_close_wait);
INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock);
priv->dp_port = serial->port[i];
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index c709ec474a80..2b141ccb0cd9 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -81,8 +81,7 @@ static int debug;
/* function prototypes for an empeg-car player */
static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp);
-static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp);
+static void empeg_close(struct usb_serial_port *port);
static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf,
int count);
@@ -181,8 +180,7 @@ static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
}
-static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp)
+static void empeg_close(struct usb_serial_port *port)
{
dbg("%s - port %d", __func__, port->number);
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 8100f1d25904..7d935d1e2ab9 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -56,6 +56,7 @@ static __u16 vendor = FTDI_VID;
static __u16 product;
struct ftdi_private {
+ struct kref kref;
ftdi_chip_type_t chip_type;
/* type of device, either SIO or FT8U232AM */
int baud_base; /* baud base clock for divisor setting */
@@ -669,6 +670,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(ADI_VID, ADI_GNICE_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
+ { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -716,8 +719,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port);
static int ftdi_sio_port_remove(struct usb_serial_port *port);
static int ftdi_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
-static void ftdi_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+static void ftdi_close(struct usb_serial_port *port);
+static void ftdi_dtr_rts(struct usb_serial_port *port, int on);
static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
static int ftdi_write_room(struct tty_struct *tty);
@@ -755,6 +758,7 @@ static struct usb_serial_driver ftdi_sio_device = {
.port_remove = ftdi_sio_port_remove,
.open = ftdi_open,
.close = ftdi_close,
+ .dtr_rts = ftdi_dtr_rts,
.throttle = ftdi_throttle,
.unthrottle = ftdi_unthrottle,
.write = ftdi_write,
@@ -1352,6 +1356,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
return -ENOMEM;
}
+ kref_init(&priv->kref);
spin_lock_init(&priv->rx_lock);
spin_lock_init(&priv->tx_lock);
init_waitqueue_head(&priv->delta_msr_wait);
@@ -1468,6 +1473,13 @@ static void ftdi_shutdown(struct usb_serial *serial)
dbg("%s", __func__);
}
+static void ftdi_sio_priv_release(struct kref *k)
+{
+ struct ftdi_private *priv = container_of(k, struct ftdi_private, kref);
+
+ kfree(priv);
+}
+
static int ftdi_sio_port_remove(struct usb_serial_port *port)
{
struct ftdi_private *priv = usb_get_serial_port_data(port);
@@ -1482,7 +1494,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
if (priv) {
usb_set_serial_port_data(port, NULL);
- kfree(priv);
+ kref_put(&priv->kref, ftdi_sio_priv_release);
}
return 0;
@@ -1547,12 +1559,37 @@ static int ftdi_open(struct tty_struct *tty,
dev_err(&port->dev,
"%s - failed submitting read urb, error %d\n",
__func__, result);
-
+ else
+ kref_get(&priv->kref);
return result;
} /* ftdi_open */
+static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
+{
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ char buf[1];
+
+ mutex_lock(&port->serial->disc_mutex);
+ if (!port->serial->disconnected) {
+ /* Disable flow control */
+ if (!on && usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ FTDI_SIO_SET_FLOW_CTRL_REQUEST,
+ FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
+ 0, priv->interface, buf, 0,
+ WDR_TIMEOUT) < 0) {
+ dev_err(&port->dev, "error from flowcontrol urb\n");
+ }
+ /* drop RTS and DTR */
+ if (on)
+ set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ else
+ clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ }
+ mutex_unlock(&port->serial->disc_mutex);
+}
/*
* usbserial:__serial_close only calls ftdi_close if the point is open
@@ -1562,38 +1599,19 @@ static int ftdi_open(struct tty_struct *tty,
*
*/
-static void ftdi_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void ftdi_close(struct usb_serial_port *port)
{ /* ftdi_close */
- unsigned int c_cflag = tty->termios->c_cflag;
struct ftdi_private *priv = usb_get_serial_port_data(port);
- char buf[1];
dbg("%s", __func__);
- mutex_lock(&port->serial->disc_mutex);
- if (c_cflag & HUPCL && !port->serial->disconnected) {
- /* Disable flow control */
- if (usb_control_msg(port->serial->dev,
- usb_sndctrlpipe(port->serial->dev, 0),
- FTDI_SIO_SET_FLOW_CTRL_REQUEST,
- FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
- 0, priv->interface, buf, 0,
- WDR_TIMEOUT) < 0) {
- dev_err(&port->dev, "error from flowcontrol urb\n");
- }
-
- /* drop RTS and DTR */
- clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
- } /* Note change no line if hupcl is off */
- mutex_unlock(&port->serial->disc_mutex);
/* cancel any scheduled reading */
- cancel_delayed_work(&priv->rx_work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&priv->rx_work);
/* shutdown our bulk read */
usb_kill_urb(port->read_urb);
+ kref_put(&priv->kref, ftdi_sio_priv_release);
} /* ftdi_close */
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index c09f658a448b..12330fa1c095 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -920,6 +920,12 @@
#define JETI_SPC1201_PID 0x04b2
/*
+ * Marvell SheevaPlug
+ */
+#define MARVELL_VID 0x9e88
+#define MARVELL_SHEEVAPLUG_PID 0x9e8f
+
+/*
* BmRequestType: 1100 0000b
* bRequest: FTDI_E2_READ
* wValue: 0
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 586d30ff450b..ee25a3fe3b09 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -993,8 +993,7 @@ static int garmin_open(struct tty_struct *tty,
}
-static void garmin_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void garmin_close(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 4cec9906ccf3..be82ea956720 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -184,8 +184,7 @@ int usb_serial_generic_resume(struct usb_serial *serial)
}
EXPORT_SYMBOL_GPL(usb_serial_generic_resume);
-void usb_serial_generic_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+void usb_serial_generic_close(struct usb_serial_port *port)
{
dbg("%s - port %d", __func__, port->number);
generic_cleanup(port);
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index fb4a73d090f6..53ef5996e33d 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -207,8 +207,7 @@ static void edge_bulk_out_cmd_callback(struct urb *urb);
/* function prototypes for the usbserial callbacks */
static int edge_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp);
-static void edge_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp);
+static void edge_close(struct usb_serial_port *port);
static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
static int edge_write_room(struct tty_struct *tty);
@@ -965,7 +964,7 @@ static int edge_open(struct tty_struct *tty,
if (!edge_port->txfifo.fifo) {
dbg("%s - no memory", __func__);
- edge_close(tty, port, filp);
+ edge_close(port);
return -ENOMEM;
}
@@ -975,7 +974,7 @@ static int edge_open(struct tty_struct *tty,
if (!edge_port->write_urb) {
dbg("%s - no memory", __func__);
- edge_close(tty, port, filp);
+ edge_close(port);
return -ENOMEM;
}
@@ -1099,8 +1098,7 @@ static void block_until_tx_empty(struct edgeport_port *edge_port)
* edge_close
* this function is called by the tty driver when a port is closed
*****************************************************************************/
-static void edge_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void edge_close(struct usb_serial_port *port)
{
struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 0e138ff58879..db964db42d3c 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -2009,8 +2009,7 @@ release_es_lock:
return status;
}
-static void edge_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void edge_close(struct usb_serial_port *port)
{
struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index cd62825a9ac3..c610a99fa477 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -76,8 +76,7 @@ static int initial_wait;
/* Function prototypes for an ipaq */
static int ipaq_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
-static void ipaq_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+static void ipaq_close(struct usb_serial_port *port);
static int ipaq_calc_num_ports(struct usb_serial *serial);
static int ipaq_startup(struct usb_serial *serial);
static void ipaq_shutdown(struct usb_serial *serial);
@@ -714,8 +713,7 @@ error:
}
-static void ipaq_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void ipaq_close(struct usb_serial_port *port)
{
struct ipaq_private *priv = usb_get_serial_port_data(port);
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index da2a2b46644a..29ad038b9c8d 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -302,23 +302,17 @@ static int ipw_open(struct tty_struct *tty,
return 0;
}
-static void ipw_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void ipw_dtr_rts(struct usb_serial_port *port, int on)
{
struct usb_device *dev = port->serial->dev;
int result;
- if (tty_hung_up_p(filp)) {
- dbg("%s: tty_hung_up_p ...", __func__);
- return;
- }
-
/*--1: drop the dtr */
dbg("%s:dropping dtr", __func__);
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
IPW_SIO_SET_PIN,
USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- IPW_PIN_CLRDTR,
+ on ? IPW_PIN_SETDTR : IPW_PIN_CLRDTR,
0,
NULL,
0,
@@ -332,7 +326,7 @@ static void ipw_close(struct tty_struct *tty,
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
IPW_SIO_SET_PIN, USB_TYPE_VENDOR |
USB_RECIP_INTERFACE | USB_DIR_OUT,
- IPW_PIN_CLRRTS,
+ on ? IPW_PIN_SETRTS : IPW_PIN_CLRRTS,
0,
NULL,
0,
@@ -340,7 +334,12 @@ static void ipw_close(struct tty_struct *tty,
if (result < 0)
dev_err(&port->dev,
"dropping rts failed (error = %d)\n", result);
+}
+static void ipw_close(struct usb_serial_port *port)
+{
+ struct usb_device *dev = port->serial->dev;
+ int result;
/*--3: purge */
dbg("%s:sending purge", __func__);
@@ -461,6 +460,7 @@ static struct usb_serial_driver ipw_device = {
.num_ports = 1,
.open = ipw_open,
.close = ipw_close,
+ .dtr_rts = ipw_dtr_rts,
.port_probe = ipw_probe,
.port_remove = ipw_disconnect,
.write = ipw_write,
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 4e2cda93da59..66009b6b763a 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -88,8 +88,7 @@ static int xbof = -1;
static int ir_startup (struct usb_serial *serial);
static int ir_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filep);
-static void ir_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filep);
+static void ir_close(struct usb_serial_port *port);
static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
static void ir_write_bulk_callback (struct urb *urb);
@@ -346,8 +345,7 @@ static int ir_open(struct tty_struct *tty,
return result;
}
-static void ir_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file * filp)
+static void ir_close(struct usb_serial_port *port)
{
dbg("%s - port %d", __func__, port->number);
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 4473d442b2aa..bb572cee6ecd 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -70,7 +70,6 @@ static void read_rxcmd_callback(struct urb *urb);
struct iuu_private {
spinlock_t lock; /* store irq state */
wait_queue_head_t delta_msr_wait;
- u8 line_control;
u8 line_status;
u8 termios_initialized;
int tiostatus; /* store IUART SIGNAL for tiocmget call */
@@ -946,19 +945,10 @@ static int iuu_uart_baud(struct usb_serial_port *port, u32 baud,
return status;
}
-static int set_control_lines(struct usb_device *dev, u8 value)
-{
- return 0;
-}
-
-static void iuu_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void iuu_close(struct usb_serial_port *port)
{
/* iuu_led (port,255,0,0,0); */
struct usb_serial *serial;
- struct iuu_private *priv = usb_get_serial_port_data(port);
- unsigned long flags;
- unsigned int c_cflag;
serial = port->serial;
if (!serial)
@@ -968,17 +958,6 @@ static void iuu_close(struct tty_struct *tty,
iuu_uart_off(port);
if (serial->dev) {
- if (tty) {
- c_cflag = tty->termios->c_cflag;
- if (c_cflag & HUPCL) {
- /* drop DTR and RTS */
- priv = usb_get_serial_port_data(port);
- spin_lock_irqsave(&priv->lock, flags);
- priv->line_control = 0;
- spin_unlock_irqrestore(&priv->lock, flags);
- set_control_lines(port->serial->dev, 0);
- }
- }
/* free writebuf */
/* shutdown our urbs */
dbg("%s - shutting down urbs", __func__);
@@ -1154,7 +1133,7 @@ static int iuu_open(struct tty_struct *tty,
if (result) {
dev_err(&port->dev, "%s - failed submitting read urb,"
" error %d\n", __func__, result);
- iuu_close(tty, port, NULL);
+ iuu_close(port);
return -EPROTO;
} else {
dbg("%s - rxcmd OK", __func__);
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 00daa8f7759a..f1195a98f316 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -1298,8 +1298,16 @@ static inline void stop_urb(struct urb *urb)
usb_kill_urb(urb);
}
-static void keyspan_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void keyspan_dtr_rts(struct usb_serial_port *port, int on)
+{
+ struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);
+
+ p_priv->rts_state = on;
+ p_priv->dtr_state = on;
+ keyspan_send_setup(port, 0);
+}
+
+static void keyspan_close(struct usb_serial_port *port)
{
int i;
struct usb_serial *serial = port->serial;
@@ -1336,7 +1344,6 @@ static void keyspan_close(struct tty_struct *tty,
stop_urb(p_priv->out_urbs[i]);
}
}
- tty_port_tty_set(&port->port, NULL);
}
/* download the firmware to a pre-renumeration device */
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index 38b4582e0734..0d4569b60768 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -38,9 +38,8 @@
static int keyspan_open (struct tty_struct *tty,
struct usb_serial_port *port,
struct file *filp);
-static void keyspan_close (struct tty_struct *tty,
- struct usb_serial_port *port,
- struct file *filp);
+static void keyspan_close (struct usb_serial_port *port);
+static void keyspan_dtr_rts (struct usb_serial_port *port, int on);
static int keyspan_startup (struct usb_serial *serial);
static void keyspan_shutdown (struct usb_serial *serial);
static int keyspan_write_room (struct tty_struct *tty);
@@ -562,6 +561,7 @@ static struct usb_serial_driver keyspan_1port_device = {
.num_ports = 1,
.open = keyspan_open,
.close = keyspan_close,
+ .dtr_rts = keyspan_dtr_rts,
.write = keyspan_write,
.write_room = keyspan_write_room,
.set_termios = keyspan_set_termios,
@@ -582,6 +582,7 @@ static struct usb_serial_driver keyspan_2port_device = {
.num_ports = 2,
.open = keyspan_open,
.close = keyspan_close,
+ .dtr_rts = keyspan_dtr_rts,
.write = keyspan_write,
.write_room = keyspan_write_room,
.set_termios = keyspan_set_termios,
@@ -602,6 +603,7 @@ static struct usb_serial_driver keyspan_4port_device = {
.num_ports = 4,
.open = keyspan_open,
.close = keyspan_close,
+ .dtr_rts = keyspan_dtr_rts,
.write = keyspan_write,
.write_room = keyspan_write_room,
.set_termios = keyspan_set_termios,
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index bf1ae247da66..ab769dbea1b3 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -651,6 +651,35 @@ static int keyspan_pda_chars_in_buffer(struct tty_struct *tty)
}
+static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on)
+{
+ struct usb_serial *serial = port->serial;
+
+ if (serial->dev) {
+ if (on)
+ keyspan_pda_set_modem_info(serial, (1<<7) | (1<< 2));
+ else
+ keyspan_pda_set_modem_info(serial, 0);
+ }
+}
+
+static int keyspan_pda_carrier_raised(struct usb_serial_port *port)
+{
+ struct usb_serial *serial = port->serial;
+ unsigned char modembits;
+
+ /* If we can read the modem status and the DCD is low then
+ carrier is not raised yet */
+ if (keyspan_pda_get_modem_info(serial, &modembits) >= 0) {
+ if (!(modembits & (1>>6)))
+ return 0;
+ }
+ /* Carrier raised, or we failed (eg disconnected) so
+ progress accordingly */
+ return 1;
+}
+
+
static int keyspan_pda_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp)
{
@@ -682,13 +711,6 @@ static int keyspan_pda_open(struct tty_struct *tty,
priv->tx_room = room;
priv->tx_throttled = room ? 0 : 1;
- /* the normal serial device seems to always turn on DTR and RTS here,
- so do the same */
- if (tty && (tty->termios->c_cflag & CBAUD))
- keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2));
- else
- keyspan_pda_set_modem_info(serial, 0);
-
/*Start reading from the device*/
port->interrupt_in_urb->dev = serial->dev;
rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
@@ -700,19 +722,11 @@ static int keyspan_pda_open(struct tty_struct *tty,
error:
return rc;
}
-
-
-static void keyspan_pda_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void keyspan_pda_close(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
if (serial->dev) {
- /* the normal serial device seems to always shut
- off DTR and RTS now */
- if (tty->termios->c_cflag & HUPCL)
- keyspan_pda_set_modem_info(serial, 0);
-
/* shutdown our bulk reads and writes */
usb_kill_urb(port->write_urb);
usb_kill_urb(port->interrupt_in_urb);
@@ -839,6 +853,8 @@ static struct usb_serial_driver keyspan_pda_device = {
.usb_driver = &keyspan_pda_driver,
.id_table = id_table_std,
.num_ports = 1,
+ .dtr_rts = keyspan_pda_dtr_rts,
+ .carrier_raised = keyspan_pda_carrier_raised,
.open = keyspan_pda_open,
.close = keyspan_pda_close,
.write = keyspan_pda_write,
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index fcd9082f3e7f..fa817c66b3e8 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -76,8 +76,7 @@ static int klsi_105_startup(struct usb_serial *serial);
static void klsi_105_shutdown(struct usb_serial *serial);
static int klsi_105_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
-static void klsi_105_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+static void klsi_105_close(struct usb_serial_port *port);
static int klsi_105_write(struct tty_struct *tty,
struct usb_serial_port *port, const unsigned char *buf, int count);
static void klsi_105_write_bulk_callback(struct urb *urb);
@@ -447,8 +446,7 @@ exit:
} /* klsi_105_open */
-static void klsi_105_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void klsi_105_close(struct usb_serial_port *port)
{
struct klsi_105_private *priv = usb_get_serial_port_data(port);
int rc;
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index c148544953b3..6b570498287f 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -72,8 +72,7 @@ static int kobil_startup(struct usb_serial *serial);
static void kobil_shutdown(struct usb_serial *serial);
static int kobil_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
-static void kobil_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp);
+static void kobil_close(struct usb_serial_port *port);
static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
static int kobil_write_room(struct tty_struct *tty);
@@ -209,7 +208,7 @@ static void kobil_shutdown(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; ++i) {
while (serial->port[i]->port.count > 0)
- kobil_close(NULL, serial->port[i], NULL);
+ kobil_close(serial->port[i]);
kfree(usb_get_serial_port_data(serial->port[i]));
usb_set_serial_port_data(serial->port[i], NULL);
}
@@ -346,11 +345,11 @@ static int kobil_open(struct tty_struct *tty,
}
-static void kobil_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void kobil_close(struct usb_serial_port *port)
{
dbg("%s - port %d", __func__, port->number);
+ /* FIXME: Add rts/dtr methods */
if (port->write_urb) {
usb_kill_urb(port->write_urb);
usb_free_urb(port->write_urb);
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 82930a7d5093..873795548fc0 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -95,8 +95,8 @@ static int mct_u232_startup(struct usb_serial *serial);
static void mct_u232_shutdown(struct usb_serial *serial);
static int mct_u232_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
-static void mct_u232_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+static void mct_u232_close(struct usb_serial_port *port);
+static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
static void mct_u232_read_int_callback(struct urb *urb);
static void mct_u232_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old);
@@ -140,6 +140,7 @@ static struct usb_serial_driver mct_u232_device = {
.num_ports = 1,
.open = mct_u232_open,
.close = mct_u232_close,
+ .dtr_rts = mct_u232_dtr_rts,
.throttle = mct_u232_throttle,
.unthrottle = mct_u232_unthrottle,
.read_int_callback = mct_u232_read_int_callback,
@@ -496,29 +497,29 @@ error:
return retval;
} /* mct_u232_open */
-
-static void mct_u232_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
{
- unsigned int c_cflag;
unsigned int control_state;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
- dbg("%s port %d", __func__, port->number);
- if (tty) {
- c_cflag = tty->termios->c_cflag;
- mutex_lock(&port->serial->disc_mutex);
- if (c_cflag & HUPCL && !port->serial->disconnected) {
- /* drop DTR and RTS */
- spin_lock_irq(&priv->lock);
+ mutex_lock(&port->serial->disc_mutex);
+ if (!port->serial->disconnected) {
+ /* drop DTR and RTS */
+ spin_lock_irq(&priv->lock);
+ if (on)
+ priv->control_state |= TIOCM_DTR | TIOCM_RTS;
+ else
priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
- control_state = priv->control_state;
- spin_unlock_irq(&priv->lock);
- mct_u232_set_modem_ctrl(port->serial, control_state);
- }
- mutex_unlock(&port->serial->disc_mutex);
+ control_state = priv->control_state;
+ spin_unlock_irq(&priv->lock);
+ mct_u232_set_modem_ctrl(port->serial, control_state);
}
+ mutex_unlock(&port->serial->disc_mutex);
+}
+static void mct_u232_close(struct usb_serial_port *port)
+{
+ dbg("%s port %d", __func__, port->number);
if (port->serial->dev) {
/* shutdown our urbs */
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 24e3b5d4b4d4..9e1a013ee7f6 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -533,8 +533,7 @@ static int mos7720_chars_in_buffer(struct tty_struct *tty)
return chars;
}
-static void mos7720_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void mos7720_close(struct usb_serial_port *port)
{
struct usb_serial *serial;
struct moschip_port *mos7720_port;
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 84fb1dcd30dc..10b78a37214f 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -1135,54 +1135,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty)
}
-/************************************************************************
- *
- * mos7840_block_until_tx_empty
- *
- * This function will block the close until one of the following:
- * 1. TX count are 0
- * 2. The mos7840 has stopped
- * 3. A timeout of 3 seconds without activity has expired
- *
- ************************************************************************/
-static void mos7840_block_until_tx_empty(struct tty_struct *tty,
- struct moschip_port *mos7840_port)
-{
- int timeout = HZ / 10;
- int wait = 30;
- int count;
-
- while (1) {
-
- count = mos7840_chars_in_buffer(tty);
-
- /* Check for Buffer status */
- if (count <= 0)
- return;
-
- /* Block the thread for a while */
- interruptible_sleep_on_timeout(&mos7840_port->wait_chase,
- timeout);
-
- /* No activity.. count down section */
- wait--;
- if (wait == 0) {
- dbg("%s - TIMEOUT", __func__);
- return;
- } else {
- /* Reset timeout value back to seconds */
- wait = 30;
- }
- }
-}
-
/*****************************************************************************
* mos7840_close
* this function is called by the tty driver when a port is closed
*****************************************************************************/
-static void mos7840_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void mos7840_close(struct usb_serial_port *port)
{
struct usb_serial *serial;
struct moschip_port *mos7840_port;
@@ -1223,10 +1181,6 @@ static void mos7840_close(struct tty_struct *tty,
}
}
- if (serial->dev)
- /* flush and block until tx is empty */
- mos7840_block_until_tx_empty(tty, mos7840_port);
-
/* While closing port, shutdown all bulk read, write *
* and interrupt read if they exists */
if (serial->dev) {
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index bcdcbb822705..f5f3751a888c 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -98,8 +98,7 @@ static int navman_open(struct tty_struct *tty,
return result;
}
-static void navman_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void navman_close(struct usb_serial_port *port)
{
dbg("%s - port %d", __func__, port->number);
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index df6539712726..1104617334f5 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -66,8 +66,7 @@ static int debug;
/* function prototypes */
static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp);
-static void omninet_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp);
+static void omninet_close(struct usb_serial_port *port);
static void omninet_read_bulk_callback(struct urb *urb);
static void omninet_write_bulk_callback(struct urb *urb);
static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
@@ -189,8 +188,7 @@ static int omninet_open(struct tty_struct *tty,
return result;
}
-static void omninet_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void omninet_close(struct usb_serial_port *port)
{
dbg("%s - port %d", __func__, port->number);
usb_kill_urb(port->read_urb);
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index b500ad10b758..c20480aa9755 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -173,8 +173,7 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port,
return result;
}
-static void opticon_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp)
+static void opticon_close(struct usb_serial_port *port)
{
struct opticon_private *priv = usb_get_serial_data(port->serial);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 7817b82889ca..a16d69fadba1 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -45,8 +45,9 @@
/* Function prototypes */
static int option_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp);
-static void option_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp);
+static void option_close(struct usb_serial_port *port);
+static void option_dtr_rts(struct usb_serial_port *port, int on);
+
static int option_startup(struct usb_serial *serial);
static void option_shutdown(struct usb_serial *serial);
static int option_write_room(struct tty_struct *tty);
@@ -61,7 +62,7 @@ static void option_set_termios(struct tty_struct *tty,
static int option_tiocmget(struct tty_struct *tty, struct file *file);
static int option_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
-static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port);
+static int option_send_setup(struct usb_serial_port *port);
static int option_suspend(struct usb_serial *serial, pm_message_t message);
static int option_resume(struct usb_serial *serial);
@@ -551,6 +552,7 @@ static struct usb_serial_driver option_1port_device = {
.num_ports = 1,
.open = option_open,
.close = option_close,
+ .dtr_rts = option_dtr_rts,
.write = option_write,
.write_room = option_write_room,
.chars_in_buffer = option_chars_in_buffer,
@@ -630,7 +632,7 @@ static void option_set_termios(struct tty_struct *tty,
dbg("%s", __func__);
/* Doesn't support option setting */
tty_termios_copy_hw(tty->termios, old_termios);
- option_send_setup(tty, port);
+ option_send_setup(port);
}
static int option_tiocmget(struct tty_struct *tty, struct file *file)
@@ -669,7 +671,7 @@ static int option_tiocmset(struct tty_struct *tty, struct file *file,
portdata->rts_state = 0;
if (clear & TIOCM_DTR)
portdata->dtr_state = 0;
- return option_send_setup(tty, port);
+ return option_send_setup(port);
}
/* Write */
@@ -897,10 +899,6 @@ static int option_open(struct tty_struct *tty,
dbg("%s", __func__);
- /* Set some sane defaults */
- portdata->rts_state = 1;
- portdata->dtr_state = 1;
-
/* Reset low level data toggle and start reading from endpoints */
for (i = 0; i < N_IN_URB; i++) {
urb = portdata->in_urbs[i];
@@ -936,37 +934,43 @@ static int option_open(struct tty_struct *tty,
usb_pipeout(urb->pipe), 0); */
}
- option_send_setup(tty, port);
+ option_send_setup(port);
return 0;
}
-static void option_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void option_dtr_rts(struct usb_serial_port *port, int on)
{
- int i;
struct usb_serial *serial = port->serial;
struct option_port_private *portdata;
dbg("%s", __func__);
portdata = usb_get_serial_port_data(port);
+ mutex_lock(&serial->disc_mutex);
+ portdata->rts_state = on;
+ portdata->dtr_state = on;
+ if (serial->dev)
+ option_send_setup(port);
+ mutex_unlock(&serial->disc_mutex);
+}
- portdata->rts_state = 0;
- portdata->dtr_state = 0;
- if (serial->dev) {
- mutex_lock(&serial->disc_mutex);
- if (!serial->disconnected)
- option_send_setup(tty, port);
- mutex_unlock(&serial->disc_mutex);
+static void option_close(struct usb_serial_port *port)
+{
+ int i;
+ struct usb_serial *serial = port->serial;
+ struct option_port_private *portdata;
+
+ dbg("%s", __func__);
+ portdata = usb_get_serial_port_data(port);
+ if (serial->dev) {
/* Stop reading/writing urbs */
for (i = 0; i < N_IN_URB; i++)
usb_kill_urb(portdata->in_urbs[i]);
for (i = 0; i < N_OUT_URB; i++)
usb_kill_urb(portdata->out_urbs[i]);
}
- tty_port_tty_set(&port->port, NULL);
}
/* Helper functions used by option_setup_urbs */
@@ -1032,28 +1036,24 @@ static void option_setup_urbs(struct usb_serial *serial)
* This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN
* CDC.
*/
-static int option_send_setup(struct tty_struct *tty,
- struct usb_serial_port *port)
+static int option_send_setup(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct option_port_private *portdata;
int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
+ int val = 0;
dbg("%s", __func__);
portdata = usb_get_serial_port_data(port);
- if (tty) {
- int val = 0;
- if (portdata->dtr_state)
- val |= 0x01;
- if (portdata->rts_state)
- val |= 0x02;
+ if (portdata->dtr_state)
+ val |= 0x01;
+ if (portdata->rts_state)
+ val |= 0x02;
- return usb_control_msg(serial->dev,
- usb_rcvctrlpipe(serial->dev, 0),
- 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT);
- }
- return 0;
+ return usb_control_msg(serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
+ 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT);
}
static int option_startup(struct usb_serial *serial)
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index ba551f00f16f..7de54781fe61 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -143,8 +143,7 @@ struct oti6858_control_pkt {
/* function prototypes */
static int oti6858_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
-static void oti6858_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+static void oti6858_close(struct usb_serial_port *port);
static void oti6858_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old);
static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
@@ -622,67 +621,30 @@ static int oti6858_open(struct tty_struct *tty,
if (result != 0) {
dev_err(&port->dev, "%s(): usb_submit_urb() failed"
" with error %d\n", __func__, result);
- oti6858_close(tty, port, NULL);
+ oti6858_close(port);
return -EPROTO;
}
/* setup termios */
if (tty)
oti6858_set_termios(tty, port, &tmp_termios);
-
+ port->port.drain_delay = 256; /* FIXME: check the FIFO length */
return 0;
}
-static void oti6858_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void oti6858_close(struct usb_serial_port *port)
{
struct oti6858_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
- long timeout;
- wait_queue_t wait;
dbg("%s(port = %d)", __func__, port->number);
- /* wait for data to drain from the buffer */
spin_lock_irqsave(&priv->lock, flags);
- timeout = 30 * HZ; /* PL2303_CLOSING_WAIT */
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&tty->write_wait, &wait);
- dbg("%s(): entering wait loop", __func__);
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (oti6858_buf_data_avail(priv->buf) == 0
- || timeout == 0 || signal_pending(current)
- || port->serial->disconnected)
- break;
- spin_unlock_irqrestore(&priv->lock, flags);
- timeout = schedule_timeout(timeout);
- spin_lock_irqsave(&priv->lock, flags);
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&tty->write_wait, &wait);
- dbg("%s(): after wait loop", __func__);
-
/* clear out any remaining data in the buffer */
oti6858_buf_clear(priv->buf);
spin_unlock_irqrestore(&priv->lock, flags);
- /* wait for characters to drain from the device */
- /* (this is long enough for the entire 256 byte */
- /* pl2303 hardware buffer to drain with no flow */
- /* control for data rates of 1200 bps or more, */
- /* for lower rates we should really know how much */
- /* data is in the buffer to compute a delay */
- /* that is not unnecessarily long) */
- /* FIXME
- bps = tty_get_baud_rate(tty);
- if (bps > 1200)
- timeout = max((HZ*2560)/bps,HZ/10);
- else
- */
- timeout = 2*HZ;
- schedule_timeout_interruptible(timeout);
- dbg("%s(): after schedule_timeout_interruptible()", __func__);
+ dbg("%s(): after buf_clear()", __func__);
/* cancel scheduled setup */
cancel_delayed_work(&priv->delayed_setup_work);
@@ -694,15 +656,6 @@ static void oti6858_close(struct tty_struct *tty,
usb_kill_urb(port->write_urb);
usb_kill_urb(port->read_urb);
usb_kill_urb(port->interrupt_in_urb);
-
- /*
- if (tty && (tty->termios->c_cflag) & HUPCL) {
- // drop DTR and RTS
- spin_lock_irqsave(&priv->lock, flags);
- priv->pending_setup.control &= ~CONTROL_MASK;
- spin_unlock_irqrestore(&priv->lock, flags);
- }
- */
}
static int oti6858_tiocmset(struct tty_struct *tty, struct file *file,
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 751a533a4347..e02dc3d643c7 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -652,69 +652,41 @@ static void pl2303_set_termios(struct tty_struct *tty,
kfree(buf);
}
-static void pl2303_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void pl2303_dtr_rts(struct usb_serial_port *port, int on)
+{
+ struct pl2303_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ u8 control;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ /* Change DTR and RTS */
+ if (on)
+ priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
+ else
+ priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
+ control = priv->line_control;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ set_control_lines(port->serial->dev, control);
+}
+
+static void pl2303_close(struct usb_serial_port *port)
{
struct pl2303_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
- unsigned int c_cflag;
- int bps;
- long timeout;
- wait_queue_t wait;
dbg("%s - port %d", __func__, port->number);
- /* wait for data to drain from the buffer */
spin_lock_irqsave(&priv->lock, flags);
- timeout = PL2303_CLOSING_WAIT;
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&tty->write_wait, &wait);
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (pl2303_buf_data_avail(priv->buf) == 0 ||
- timeout == 0 || signal_pending(current) ||
- port->serial->disconnected)
- break;
- spin_unlock_irqrestore(&priv->lock, flags);
- timeout = schedule_timeout(timeout);
- spin_lock_irqsave(&priv->lock, flags);
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&tty->write_wait, &wait);
/* clear out any remaining data in the buffer */
pl2303_buf_clear(priv->buf);
spin_unlock_irqrestore(&priv->lock, flags);
- /* wait for characters to drain from the device */
- /* (this is long enough for the entire 256 byte */
- /* pl2303 hardware buffer to drain with no flow */
- /* control for data rates of 1200 bps or more, */
- /* for lower rates we should really know how much */
- /* data is in the buffer to compute a delay */
- /* that is not unnecessarily long) */
- bps = tty_get_baud_rate(tty);
- if (bps > 1200)
- timeout = max((HZ*2560)/bps, HZ/10);
- else
- timeout = 2*HZ;
- schedule_timeout_interruptible(timeout);
-
/* shutdown our urbs */
dbg("%s - shutting down urbs", __func__);
usb_kill_urb(port->write_urb);
usb_kill_urb(port->read_urb);
usb_kill_urb(port->interrupt_in_urb);
- if (tty) {
- c_cflag = tty->termios->c_cflag;
- if (c_cflag & HUPCL) {
- /* drop DTR and RTS */
- spin_lock_irqsave(&priv->lock, flags);
- priv->line_control = 0;
- spin_unlock_irqrestore(&priv->lock, flags);
- set_control_lines(port->serial->dev, 0);
- }
- }
}
static int pl2303_open(struct tty_struct *tty,
@@ -748,7 +720,7 @@ static int pl2303_open(struct tty_struct *tty,
if (result) {
dev_err(&port->dev, "%s - failed submitting read urb,"
" error %d\n", __func__, result);
- pl2303_close(tty, port, NULL);
+ pl2303_close(port);
return -EPROTO;
}
@@ -758,9 +730,10 @@ static int pl2303_open(struct tty_struct *tty,
if (result) {
dev_err(&port->dev, "%s - failed submitting interrupt urb,"
" error %d\n", __func__, result);
- pl2303_close(tty, port, NULL);
+ pl2303_close(port);
return -EPROTO;
}
+ port->port.drain_delay = 256;
return 0;
}
@@ -821,6 +794,14 @@ static int pl2303_tiocmget(struct tty_struct *tty, struct file *file)
return result;
}
+static int pl2303_carrier_raised(struct usb_serial_port *port)
+{
+ struct pl2303_private *priv = usb_get_serial_port_data(port);
+ if (priv->line_status & UART_DCD)
+ return 1;
+ return 0;
+}
+
static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
{
struct pl2303_private *priv = usb_get_serial_port_data(port);
@@ -1125,6 +1106,8 @@ static struct usb_serial_driver pl2303_device = {
.num_ports = 1,
.open = pl2303_open,
.close = pl2303_close,
+ .dtr_rts = pl2303_dtr_rts,
+ .carrier_raised = pl2303_carrier_raised,
.write = pl2303_write,
.ioctl = pl2303_ioctl,
.break_ctl = pl2303_break_ctl,
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 913225c61610..1319b8968d82 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -240,57 +240,39 @@ struct sierra_port_private {
int ri_state;
};
-static int sierra_send_setup(struct tty_struct *tty,
- struct usb_serial_port *port)
+static int sierra_send_setup(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct sierra_port_private *portdata;
__u16 interface = 0;
+ int val = 0;
dev_dbg(&port->dev, "%s", __func__);
portdata = usb_get_serial_port_data(port);
- if (tty) {
- int val = 0;
- if (portdata->dtr_state)
- val |= 0x01;
- if (portdata->rts_state)
- val |= 0x02;
-
- /* If composite device then properly report interface */
- if (serial->num_ports == 1) {
- interface = sierra_calc_interface(serial);
-
- /* Control message is sent only to interfaces with
- * interrupt_in endpoints
- */
- if (port->interrupt_in_urb) {
- /* send control message */
- return usb_control_msg(serial->dev,
- usb_rcvctrlpipe(serial->dev, 0),
- 0x22, 0x21, val, interface,
- NULL, 0, USB_CTRL_SET_TIMEOUT);
- }
- }
-
- /* Otherwise the need to do non-composite mapping */
- else {
- if (port->bulk_out_endpointAddress == 2)
- interface = 0;
- else if (port->bulk_out_endpointAddress == 4)
- interface = 1;
- else if (port->bulk_out_endpointAddress == 5)
- interface = 2;
-
- return usb_control_msg(serial->dev,
- usb_rcvctrlpipe(serial->dev, 0),
- 0x22, 0x21, val, interface,
- NULL, 0, USB_CTRL_SET_TIMEOUT);
-
- }
+ if (portdata->dtr_state)
+ val |= 0x01;
+ if (portdata->rts_state)
+ val |= 0x02;
+
+ /* If composite device then properly report interface */
+ if (serial->num_ports == 1)
+ interface = sierra_calc_interface(serial);
+
+ /* Otherwise the need to do non-composite mapping */
+ else {
+ if (port->bulk_out_endpointAddress == 2)
+ interface = 0;
+ else if (port->bulk_out_endpointAddress == 4)
+ interface = 1;
+ else if (port->bulk_out_endpointAddress == 5)
+ interface = 2;
}
-
+ return usb_control_msg(serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
+ 0x22, 0x21, val, interface,
+ NULL, 0, USB_CTRL_SET_TIMEOUT);
return 0;
}
@@ -299,7 +281,7 @@ static void sierra_set_termios(struct tty_struct *tty,
{
dev_dbg(&port->dev, "%s", __func__);
tty_termios_copy_hw(tty->termios, old_termios);
- sierra_send_setup(tty, port);
+ sierra_send_setup(port);
}
static int sierra_tiocmget(struct tty_struct *tty, struct file *file)
@@ -338,7 +320,7 @@ static int sierra_tiocmset(struct tty_struct *tty, struct file *file,
portdata->rts_state = 0;
if (clear & TIOCM_DTR)
portdata->dtr_state = 0;
- return sierra_send_setup(tty, port);
+ return sierra_send_setup(port);
}
static void sierra_outdat_callback(struct urb *urb)
@@ -598,7 +580,7 @@ static int sierra_open(struct tty_struct *tty,
}
}
- sierra_send_setup(tty, port);
+ sierra_send_setup(port);
/* start up the interrupt endpoint if we have one */
if (port->interrupt_in_urb) {
@@ -610,32 +592,38 @@ static int sierra_open(struct tty_struct *tty,
return 0;
}
-static void sierra_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void sierra_dtr_rts(struct usb_serial_port *port, int on)
{
- int i;
struct usb_serial *serial = port->serial;
struct sierra_port_private *portdata;
- dev_dbg(&port->dev, "%s", __func__);
portdata = usb_get_serial_port_data(port);
-
- portdata->rts_state = 0;
- portdata->dtr_state = 0;
+ portdata->rts_state = on;
+ portdata->dtr_state = on;
if (serial->dev) {
mutex_lock(&serial->disc_mutex);
if (!serial->disconnected)
- sierra_send_setup(tty, port);
+ sierra_send_setup(port);
mutex_unlock(&serial->disc_mutex);
+ }
+}
+
+static void sierra_close(struct usb_serial_port *port)
+{
+ int i;
+ struct usb_serial *serial = port->serial;
+ struct sierra_port_private *portdata;
+ dev_dbg(&port->dev, "%s", __func__);
+ portdata = usb_get_serial_port_data(port);
+
+ if (serial->dev) {
/* Stop reading/writing urbs */
for (i = 0; i < N_IN_URB; i++)
usb_kill_urb(portdata->in_urbs[i]);
}
-
usb_kill_urb(port->interrupt_in_urb);
- tty_port_tty_set(&port->port, NULL);
}
static int sierra_startup(struct usb_serial *serial)
@@ -737,6 +725,7 @@ static struct usb_serial_driver sierra_device = {
.probe = sierra_probe,
.open = sierra_open,
.close = sierra_close,
+ .dtr_rts = sierra_dtr_rts,
.write = sierra_write,
.write_room = sierra_write_room,
.set_termios = sierra_set_termios,
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 5e7528cc81a8..8f7ed8f13996 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -446,66 +446,47 @@ static void spcp8x5_set_workMode(struct usb_device *dev, u16 value,
"RTSCTS usb_control_msg(enable flowctrl) = %d\n", ret);
}
+static int spcp8x5_carrier_raised(struct usb_serial_port *port)
+{
+ struct spcp8x5_private *priv = usb_get_serial_port_data(port);
+ if (priv->line_status & MSR_STATUS_LINE_DCD)
+ return 1;
+ return 0;
+}
+
+static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on)
+{
+ struct spcp8x5_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ u8 control;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (on)
+ priv->line_control = MCR_CONTROL_LINE_DTR
+ | MCR_CONTROL_LINE_RTS;
+ else
+ priv->line_control &= ~ (MCR_CONTROL_LINE_DTR
+ | MCR_CONTROL_LINE_RTS);
+ control = priv->line_control;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type);
+}
+
/* close the serial port. We should wait for data sending to device 1st and
* then kill all urb. */
-static void spcp8x5_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void spcp8x5_close(struct usb_serial_port *port)
{
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
- unsigned int c_cflag;
- int bps;
- long timeout;
- wait_queue_t wait;
int result;
dbg("%s - port %d", __func__, port->number);
- /* wait for data to drain from the buffer */
spin_lock_irqsave(&priv->lock, flags);
- timeout = SPCP8x5_CLOSING_WAIT;
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&tty->write_wait, &wait);
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (ringbuf_avail_data(priv->buf) == 0 ||
- timeout == 0 || signal_pending(current))
- break;
- spin_unlock_irqrestore(&priv->lock, flags);
- timeout = schedule_timeout(timeout);
- spin_lock_irqsave(&priv->lock, flags);
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&tty->write_wait, &wait);
-
/* clear out any remaining data in the buffer */
clear_ringbuf(priv->buf);
spin_unlock_irqrestore(&priv->lock, flags);
- /* wait for characters to drain from the device (this is long enough
- * for the entire all byte spcp8x5 hardware buffer to drain with no
- * flow control for data rates of 1200 bps or more, for lower rates we
- * should really know how much data is in the buffer to compute a delay
- * that is not unnecessarily long) */
- bps = tty_get_baud_rate(tty);
- if (bps > 1200)
- timeout = max((HZ*2560) / bps, HZ/10);
- else
- timeout = 2*HZ;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(timeout);
-
- /* clear control lines */
- if (tty) {
- c_cflag = tty->termios->c_cflag;
- if (c_cflag & HUPCL) {
- spin_lock_irqsave(&priv->lock, flags);
- priv->line_control = 0;
- spin_unlock_irqrestore(&priv->lock, flags);
- spcp8x5_set_ctrlLine(port->serial->dev, 0 , priv->type);
- }
- }
-
/* kill urb */
if (port->write_urb != NULL) {
result = usb_unlink_urb(port->write_urb);
@@ -665,13 +646,6 @@ static int spcp8x5_open(struct tty_struct *tty,
if (ret)
return ret;
- spin_lock_irqsave(&priv->lock, flags);
- if (tty && (tty->termios->c_cflag & CBAUD))
- priv->line_control = MCR_DTR | MCR_RTS;
- else
- priv->line_control = 0;
- spin_unlock_irqrestore(&priv->lock, flags);
-
spcp8x5_set_ctrlLine(serial->dev, priv->line_control , priv->type);
/* Setup termios */
@@ -691,9 +665,10 @@ static int spcp8x5_open(struct tty_struct *tty,
port->read_urb->dev = serial->dev;
ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (ret) {
- spcp8x5_close(tty, port, NULL);
+ spcp8x5_close(port);
return -EPROTO;
}
+ port->port.drain_delay = 256;
return 0;
}
@@ -1033,6 +1008,8 @@ static struct usb_serial_driver spcp8x5_device = {
.num_ports = 1,
.open = spcp8x5_open,
.close = spcp8x5_close,
+ .dtr_rts = spcp8x5_dtr_rts,
+ .carrier_raised = spcp8x5_carrier_raised,
.write = spcp8x5_write,
.set_termios = spcp8x5_set_termios,
.ioctl = spcp8x5_ioctl,
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index 69879e437940..8b07ebc6baeb 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -152,8 +152,7 @@ static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port,
return result;
}
-static void symbol_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp)
+static void symbol_close(struct usb_serial_port *port)
{
struct symbol_private *priv = usb_get_serial_data(port->serial);
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 0a64bac306ee..42cb04c403be 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -100,8 +100,7 @@ static int ti_startup(struct usb_serial *serial);
static void ti_shutdown(struct usb_serial *serial);
static int ti_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *file);
-static void ti_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *file);
+static void ti_close(struct usb_serial_port *port);
static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *data, int count);
static int ti_write_room(struct tty_struct *tty);
@@ -647,8 +646,7 @@ release_lock:
}
-static void ti_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *file)
+static void ti_close(struct usb_serial_port *port)
{
struct ti_device *tdev;
struct ti_port *tport;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 0a566eea49c0..f1eb80537d8d 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -238,9 +238,11 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
goto bailout_interface_put;
mutex_unlock(&serial->disc_mutex);
}
-
mutex_unlock(&port->mutex);
- return 0;
+ /* Now do the correct tty layer semantics */
+ retval = tty_port_block_til_ready(&port->port, tty, filp);
+ if (retval == 0)
+ return 0;
bailout_interface_put:
usb_autopm_put_interface(serial->interface);
@@ -259,64 +261,89 @@ bailout_serial_put:
return retval;
}
-static void serial_close(struct tty_struct *tty, struct file *filp)
+/**
+ * serial_do_down - shut down hardware
+ * @port: port to shut down
+ *
+ * Shut down a USB port unless it is the console. We never shut down the
+ * console hardware as it will always be in use.
+ *
+ * Don't free any resources at this point
+ */
+static void serial_do_down(struct usb_serial_port *port)
{
- struct usb_serial_port *port = tty->driver_data;
+ struct usb_serial_driver *drv = port->serial->type;
struct usb_serial *serial;
struct module *owner;
- int count;
- if (!port)
+ /* The console is magical, do not hang up the console hardware
+ or there will be tears */
+ if (port->console)
return;
- dbg("%s - port %d", __func__, port->number);
-
mutex_lock(&port->mutex);
serial = port->serial;
owner = serial->type->driver.owner;
- if (port->port.count == 0) {
- mutex_unlock(&port->mutex);
- return;
- }
-
- if (port->port.count == 1)
- /* only call the device specific close if this
- * port is being closed by the last owner. Ensure we do
- * this before we drop the port count. The call is protected
- * by the port mutex
- */
- serial->type->close(tty, port, filp);
-
- if (port->port.count == (port->console ? 2 : 1)) {
- struct tty_struct *tty = tty_port_tty_get(&port->port);
- if (tty) {
- /* We must do this before we drop the port count to
- zero. */
- if (tty->driver_data)
- tty->driver_data = NULL;
- tty_port_tty_set(&port->port, NULL);
- tty_kref_put(tty);
- }
- }
+ if (drv->close)
+ drv->close(port);
- --port->port.count;
- count = port->port.count;
mutex_unlock(&port->mutex);
- put_device(&port->dev);
+}
+
+/**
+ * serial_do_free - free resources post close/hangup
+ * @port: port to free up
+ *
+ * Do the resource freeing and refcount dropping for the port. We must
+ * be careful about ordering and we must avoid freeing up the console.
+ */
+static void serial_do_free(struct usb_serial_port *port)
+{
+ struct usb_serial *serial;
+ struct module *owner;
+
+ /* The console is magical, do not hang up the console hardware
+ or there will be tears */
+ if (port->console)
+ return;
+
+ serial = port->serial;
+ owner = serial->type->driver.owner;
+ put_device(&port->dev);
/* Mustn't dereference port any more */
- if (count == 0) {
- mutex_lock(&serial->disc_mutex);
- if (!serial->disconnected)
- usb_autopm_put_interface(serial->interface);
- mutex_unlock(&serial->disc_mutex);
- }
+ mutex_lock(&serial->disc_mutex);
+ if (!serial->disconnected)
+ usb_autopm_put_interface(serial->interface);
+ mutex_unlock(&serial->disc_mutex);
usb_serial_put(serial);
-
/* Mustn't dereference serial any more */
- if (count == 0)
- module_put(owner);
+ module_put(owner);
+}
+
+static void serial_close(struct tty_struct *tty, struct file *filp)
+{
+ struct usb_serial_port *port = tty->driver_data;
+
+ dbg("%s - port %d", __func__, port->number);
+
+
+ if (tty_port_close_start(&port->port, tty, filp) == 0)
+ return;
+
+ serial_do_down(port);
+ tty_port_close_end(&port->port, tty);
+ tty_port_tty_set(&port->port, NULL);
+ serial_do_free(port);
+}
+
+static void serial_hangup(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ serial_do_down(port);
+ tty_port_hangup(&port->port);
+ serial_do_free(port);
}
static int serial_write(struct tty_struct *tty, const unsigned char *buf,
@@ -648,6 +675,29 @@ static struct usb_serial_driver *search_serial_device(
return NULL;
}
+static int serial_carrier_raised(struct tty_port *port)
+{
+ struct usb_serial_port *p = container_of(port, struct usb_serial_port, port);
+ struct usb_serial_driver *drv = p->serial->type;
+ if (drv->carrier_raised)
+ return drv->carrier_raised(p);
+ /* No carrier control - don't block */
+ return 1;
+}
+
+static void serial_dtr_rts(struct tty_port *port, int on)
+{
+ struct usb_serial_port *p = container_of(port, struct usb_serial_port, port);
+ struct usb_serial_driver *drv = p->serial->type;
+ if (drv->dtr_rts)
+ drv->dtr_rts(p, on);
+}
+
+static const struct tty_port_operations serial_port_ops = {
+ .carrier_raised = serial_carrier_raised,
+ .dtr_rts = serial_dtr_rts,
+};
+
int usb_serial_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
@@ -841,6 +891,7 @@ int usb_serial_probe(struct usb_interface *interface,
if (!port)
goto probe_error;
tty_port_init(&port->port);
+ port->port.ops = &serial_port_ops;
port->serial = serial;
spin_lock_init(&port->lock);
mutex_init(&port->mutex);
@@ -1070,6 +1121,9 @@ void usb_serial_disconnect(struct usb_interface *interface)
if (port) {
struct tty_struct *tty = tty_port_tty_get(&port->port);
if (tty) {
+ /* The hangup will occur asynchronously but
+ the object refcounts will sort out all the
+ cleanup */
tty_hangup(tty);
tty_kref_put(tty);
}
@@ -1134,6 +1188,7 @@ static const struct tty_operations serial_ops = {
.open = serial_open,
.close = serial_close,
.write = serial_write,
+ .hangup = serial_hangup,
.write_room = serial_write_room,
.ioctl = serial_ioctl,
.set_termios = serial_set_termios,
@@ -1146,6 +1201,7 @@ static const struct tty_operations serial_ops = {
.proc_fops = &serial_proc_fops,
};
+
struct tty_driver *usb_serial_tty_driver;
static int __init usb_serial_init(void)
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 5ac414bda718..b15f1c0e1d4a 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -38,8 +38,7 @@
/* function prototypes for a handspring visor */
static int visor_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp);
-static void visor_close(struct tty_struct *tty, struct usb_serial_port *port,
- struct file *filp);
+static void visor_close(struct usb_serial_port *port);
static int visor_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
static int visor_write_room(struct tty_struct *tty);
@@ -324,8 +323,7 @@ exit:
}
-static void visor_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void visor_close(struct usb_serial_port *port)
{
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned char *transfer_buffer;
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 5335d3211c07..7c7295d09f34 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -147,8 +147,7 @@ static int whiteheat_attach(struct usb_serial *serial);
static void whiteheat_shutdown(struct usb_serial *serial);
static int whiteheat_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
-static void whiteheat_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+static void whiteheat_close(struct usb_serial_port *port);
static int whiteheat_write(struct tty_struct *tty,
struct usb_serial_port *port,
const unsigned char *buf, int count);
@@ -712,8 +711,7 @@ exit:
}
-static void whiteheat_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp)
+static void whiteheat_close(struct usb_serial_port *port)
{
struct whiteheat_private *info = usb_get_serial_port_data(port);
struct whiteheat_urb_wrap *wrap;
@@ -723,31 +721,7 @@ static void whiteheat_close(struct tty_struct *tty,
dbg("%s - port %d", __func__, port->number);
- mutex_lock(&port->serial->disc_mutex);
- /* filp is NULL when called from usb_serial_disconnect */
- if ((filp && (tty_hung_up_p(filp))) || port->serial->disconnected) {
- mutex_unlock(&port->serial->disc_mutex);
- return;
- }
- mutex_unlock(&port->serial->disc_mutex);
-
- tty->closing = 1;
-
-/*
- * Not currently in use; tty_wait_until_sent() calls
- * serial_chars_in_buffer() which deadlocks on the second semaphore
- * acquisition. This should be fixed at some point. Greg's been
- * notified.
- if ((filp->f_flags & (O_NDELAY | O_NONBLOCK)) == 0) {
- tty_wait_until_sent(tty, CLOSING_DELAY);
- }
-*/
-
- tty_driver_flush_buffer(tty);
- tty_ldisc_flush(tty);
-
firm_report_tx_done(port);
-
firm_close(port);
/* shutdown our bulk reads and writes */
@@ -775,10 +749,7 @@ static void whiteheat_close(struct tty_struct *tty,
}
spin_unlock_irq(&info->lock);
mutex_unlock(&info->deathwarrant);
-
stop_command_port(port->serial);
-
- tty->closing = 0;
}
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index fa65a3b08601..4b8b69045fe6 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -160,8 +160,9 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
-/* Reported by Andrew Nayenko <relan@bk.ru> */
-UNUSUAL_DEV( 0x0421, 0x0019, 0x0592, 0x0592,
+/* Reported by Andrew Nayenko <relan@bk.ru>
+ * Updated for new firmware by Phillip Potter <phillipinda@hotmail.com> */
+UNUSUAL_DEV( 0x0421, 0x0019, 0x0592, 0x0610,
"Nokia",
"Nokia 6288",
US_SC_DEVICE, US_PR_DEVICE, NULL,
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7826bdce4bbe..0048f1185a60 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1128,13 +1128,6 @@ config FB_INTEL
830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
Say Y if you have and plan to use such a board.
- If you say Y here and want DDC/I2C support you must first say Y to
- "I2C support" and "I2C bit-banging support" in the character devices
- section.
-
- If you say M here then "I2C support" and "I2C bit-banging support"
- can be build either as modules or built-in.
-
To compile this driver as a module, choose M here: the
module will be called intelfb.
@@ -1207,11 +1200,10 @@ config FB_MATROX_G
pixel and 32 bpp packed pixel. You can also use font widths
different from 8.
- If you need support for G400 secondary head, you must first say Y to
- "I2C support" in the character devices section, and then to
- "Matrox I2C support" and "G400 second head support" here in the
- framebuffer section. G450/G550 secondary head and digital output
- are supported without additional modules.
+ If you need support for G400 secondary head, you must say Y to
+ "Matrox I2C support" and "G400 second head support" right below.
+ G450/G550 secondary head and digital output are supported without
+ additional modules.
The driver starts in monitor mode. You must use the matroxset tool
(available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to
@@ -1310,13 +1302,6 @@ config FB_RADEON
a framebuffer device. There are both PCI and AGP versions. You
don't need to choose this to run the Radeon in plain VGA mode.
- If you say Y here and want DDC/I2C support you must first say Y to
- "I2C support" and "I2C bit-banging support" in the character devices
- section.
-
- If you say M here then "I2C support" and "I2C bit-banging support"
- can be build either as modules or built-in.
-
There is a product page at
http://apps.ati.com/ATIcompare/
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 0dbd6c68d76b..d8d0be5151e3 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -56,7 +56,6 @@ obj-$(CONFIG_FB_CT65550) += chipsfb.o
obj-$(CONFIG_FB_IMSTT) += imsttfb.o
obj-$(CONFIG_FB_FM2) += fm2fb.o
obj-$(CONFIG_FB_VT8623) += vt8623fb.o
-obj-$(CONFIG_FB_CYBLA) += cyblafb.o
obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
obj-$(CONFIG_FB_LE80578) += vermilion/
obj-$(CONFIG_FB_S3) += s3fb.o
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 35e8eb02b9e9..e4e4d433b007 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -354,7 +354,7 @@ static int default_crt_on __devinitdata = 0;
static int default_lcd_on __devinitdata = 1;
#ifdef CONFIG_MTRR
-static int mtrr = 1;
+static bool mtrr = true;
#endif
#ifdef CONFIG_PMAC_BACKLIGHT
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index 64b35766b2a2..ba9f58b2a5e8 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -9,10 +9,6 @@
*
* NOTES:
*
- * The code for depths like 24 that don't have integer number of pixels per
- * long is broken and needs to be fixed. For now I turned these types of
- * mode off.
- *
* Also need to add code to deal with cards endians that are different than
* the native cpu endians. I also need to deal with MSB position in the word.
*
@@ -139,7 +135,7 @@ bitfill_unaligned(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
// Trailing bits
if (last)
- FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
+ FB_WRITEL(comp(pat, FB_READL(dst), last), dst);
}
}
@@ -281,7 +277,7 @@ bitfill_unaligned_rev(struct fb_info *p, unsigned long __iomem *dst,
void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
{
- unsigned long pat, fg;
+ unsigned long pat, pat2, fg;
unsigned long width = rect->width, height = rect->height;
int bits = BITS_PER_LONG, bytes = bits >> 3;
u32 bpp = p->var.bits_per_pixel;
@@ -297,7 +293,7 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
else
fg = rect->color;
- pat = pixel_to_pat( bpp, fg);
+ pat = pixel_to_pat(bpp, fg);
dst = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1));
dst_idx = ((unsigned long)p->screen_base & (bytes - 1))*8;
@@ -333,17 +329,16 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
dst_idx += p->fix.line_length*8;
}
} else {
- int right;
- int r;
- int rot = (left-dst_idx) % bpp;
+ int right, r;
void (*fill_op)(struct fb_info *p, unsigned long __iomem *dst,
int dst_idx, unsigned long pat, int left,
int right, unsigned n, int bits) = NULL;
-
- /* rotate pattern to correct start position */
- pat = pat << rot | pat >> (bpp-rot);
-
- right = bpp-left;
+#ifdef __LITTLE_ENDIAN
+ right = left;
+ left = bpp - right;
+#else
+ right = bpp - left;
+#endif
switch (rect->rop) {
case ROP_XOR:
fill_op = bitfill_unaligned_rev;
@@ -352,17 +347,18 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
fill_op = bitfill_unaligned;
break;
default:
- printk( KERN_ERR "cfb_fillrect(): unknown rop, defaulting to ROP_COPY\n");
+ printk(KERN_ERR "cfb_fillrect(): unknown rop, defaulting to ROP_COPY\n");
fill_op = bitfill_unaligned;
break;
}
while (height--) {
- dst += dst_idx >> (ffs(bits) - 1);
+ dst += dst_idx / bits;
dst_idx &= (bits - 1);
- fill_op(p, dst, dst_idx, pat, left, right,
+ r = dst_idx % bpp;
+ /* rotate pattern to the correct start position */
+ pat2 = le_long_to_cpu(rolx(cpu_to_le_long(pat), r, bpp));
+ fill_op(p, dst, dst_idx, pat2, left, right,
width*bpp, bits);
- r = (p->fix.line_length*8) % bpp;
- pat = pat << (bpp-r) | pat >> r;
dst_idx += p->fix.line_length*8;
}
}
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 83c5cefc266c..da7c01b39be2 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1736,10 +1736,8 @@ static int __init cyber2000fb_init(void)
#ifdef CONFIG_ARCH_SHARK
err = cyberpro_vl_probe();
- if (!err) {
+ if (!err)
ret = 0;
- __module_get(THIS_MODULE);
- }
#endif
#ifdef CONFIG_PCI
err = pci_register_driver(&cyberpro_driver);
@@ -1749,14 +1747,15 @@ static int __init cyber2000fb_init(void)
return ret ? err : 0;
}
+module_init(cyber2000fb_init);
+#ifndef CONFIG_ARCH_SHARK
static void __exit cyberpro_exit(void)
{
pci_unregister_driver(&cyberpro_driver);
}
-
-module_init(cyber2000fb_init);
module_exit(cyberpro_exit);
+#endif
MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver");
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h
index 1db622192bde..04c01faaf772 100644
--- a/drivers/video/fb_draw.h
+++ b/drivers/video/fb_draw.h
@@ -33,11 +33,11 @@ pixel_to_pat( u32 bpp, u32 pixel)
case 8:
return 0x0101010101010101ul*pixel;
case 12:
- return 0x0001001001001001ul*pixel;
+ return 0x1001001001001001ul*pixel;
case 16:
return 0x0001000100010001ul*pixel;
case 24:
- return 0x0000000001000001ul*pixel;
+ return 0x0001000001000001ul*pixel;
case 32:
return 0x0000000100000001ul*pixel;
default:
@@ -58,11 +58,11 @@ pixel_to_pat( u32 bpp, u32 pixel)
case 8:
return 0x01010101ul*pixel;
case 12:
- return 0x00001001ul*pixel;
+ return 0x01001001ul*pixel;
case 16:
return 0x00010001ul*pixel;
case 24:
- return 0x00000001ul*pixel;
+ return 0x01000001ul*pixel;
case 32:
return 0x00000001ul*pixel;
default:
@@ -167,4 +167,17 @@ static inline unsigned long fb_rev_pixels_in_long(unsigned long val,
#endif /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
+#define cpu_to_le_long _cpu_to_le_long(BITS_PER_LONG)
+#define _cpu_to_le_long(x) __cpu_to_le_long(x)
+#define __cpu_to_le_long(x) cpu_to_le##x
+
+#define le_long_to_cpu _le_long_to_cpu(BITS_PER_LONG)
+#define _le_long_to_cpu(x) __le_long_to_cpu(x)
+#define __le_long_to_cpu(x) le##x##_to_cpu
+
+static inline unsigned long rolx(unsigned long word, unsigned int shift, unsigned int x)
+{
+ return (word << shift) | (word >> (x - shift));
+}
+
#endif /* FB_DRAW_H */
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index 21b3692092f2..9894de1c9b9f 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -1152,11 +1152,11 @@ static struct fb_ops mx3fb_ops = {
*/
static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct mx3fb_data *drv_data = platform_get_drvdata(pdev);
- struct mx3fb_info *mx3_fbi = drv_data->fbi->par;
+ struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
+ struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
acquire_console_sem();
- fb_set_suspend(drv_data->fbi, 1);
+ fb_set_suspend(mx3fb->fbi, 1);
release_console_sem();
if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
@@ -1172,16 +1172,16 @@ static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
*/
static int mx3fb_resume(struct platform_device *pdev)
{
- struct mx3fb_data *drv_data = platform_get_drvdata(pdev);
- struct mx3fb_info *mx3_fbi = drv_data->fbi->par;
+ struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
+ struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
sdc_enable_channel(mx3_fbi);
- sdc_set_brightness(mx3fb, drv_data->backlight_level);
+ sdc_set_brightness(mx3fb, mx3fb->backlight_level);
}
acquire_console_sem();
- fb_set_suspend(drv_data->fbi, 0);
+ fb_set_suspend(mx3fb->fbi, 0);
release_console_sem();
return 0;
diff --git a/drivers/video/sysfillrect.c b/drivers/video/sysfillrect.c
index f94d6b6e29ee..33ee3d34f9d2 100644
--- a/drivers/video/sysfillrect.c
+++ b/drivers/video/sysfillrect.c
@@ -124,7 +124,7 @@ bitfill_unaligned(struct fb_info *p, unsigned long *dst, int dst_idx,
/* Trailing bits */
if (last)
- *dst = comp(pat, *dst, first);
+ *dst = comp(pat, *dst, last);
}
}
@@ -242,7 +242,7 @@ bitfill_unaligned_rev(struct fb_info *p, unsigned long *dst, int dst_idx,
void sys_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
{
- unsigned long pat, fg;
+ unsigned long pat, pat2, fg;
unsigned long width = rect->width, height = rect->height;
int bits = BITS_PER_LONG, bytes = bits >> 3;
u32 bpp = p->var.bits_per_pixel;
@@ -292,17 +292,16 @@ void sys_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
dst_idx += p->fix.line_length*8;
}
} else {
- int right;
- int r;
- int rot = (left-dst_idx) % bpp;
+ int right, r;
void (*fill_op)(struct fb_info *p, unsigned long *dst,
int dst_idx, unsigned long pat, int left,
int right, unsigned n, int bits) = NULL;
-
- /* rotate pattern to correct start position */
- pat = pat << rot | pat >> (bpp-rot);
-
- right = bpp-left;
+#ifdef __LITTLE_ENDIAN
+ right = left;
+ left = bpp - right;
+#else
+ right = bpp - left;
+#endif
switch (rect->rop) {
case ROP_XOR:
fill_op = bitfill_unaligned_rev;
@@ -311,18 +310,19 @@ void sys_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
fill_op = bitfill_unaligned;
break;
default:
- printk(KERN_ERR "cfb_fillrect(): unknown rop, "
+ printk(KERN_ERR "sys_fillrect(): unknown rop, "
"defaulting to ROP_COPY\n");
fill_op = bitfill_unaligned;
break;
}
while (height--) {
- dst += dst_idx >> (ffs(bits) - 1);
+ dst += dst_idx / bits;
dst_idx &= (bits - 1);
- fill_op(p, dst, dst_idx, pat, left, right,
+ r = dst_idx % bpp;
+ /* rotate pattern to the correct start position */
+ pat2 = le_long_to_cpu(rolx(cpu_to_le_long(pat), r, bpp));
+ fill_op(p, dst, dst_idx, pat2, left, right,
width*bpp, bits);
- r = (p->fix.line_length*8) % bpp;
- pat = pat << (bpp-r) | pat >> r;
dst_idx += p->fix.line_length*8;
}
}
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 89f231dc443f..ff43c8885028 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1315,7 +1315,6 @@ static int __devinit tdfxfb_setup_i2c_bus(struct tdfxfb_i2c_chan *chan,
strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name));
chan->adapter.owner = THIS_MODULE;
- chan->adapter.class = I2C_CLASS_TV_ANALOG;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = dev;
chan->algo.setsda = tdfxfb_i2c_setsda;
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 421770b5e6ab..ca5b4643a401 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -45,7 +45,7 @@ static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
static int mtrr __devinitdata = 3; /* enable mtrr by default */
static int blank = 1; /* enable blanking by default */
static int ypan = 1; /* 0: scroll, 1: ypan, 2: ywrap */
-static int pmi_setpal __devinitdata = 1; /* use PMI for palette changes */
+static bool pmi_setpal __devinitdata = true; /* 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 */
@@ -2002,11 +2002,7 @@ static void __devexit uvesafb_exit(void)
module_exit(uvesafb_exit);
-static int param_get_scroll(char *buffer, struct kernel_param *kp)
-{
- return 0;
-}
-
+#define param_get_scroll NULL
static int param_set_scroll(const char *val, struct kernel_param *kp)
{
ypan = 0;
@@ -2017,6 +2013,8 @@ static int param_set_scroll(const char *val, struct kernel_param *kp)
ypan = 1;
else if (!strcmp(val, "ywrap"))
ypan = 2;
+ else
+ return -EINVAL;
return 0;
}
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index e327b84820d2..a0fec298216e 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -2103,7 +2103,7 @@ static void viafb_remove_proc(struct proc_dir_entry *viafb_entry)
static int __devinit via_pci_probe(void)
{
- unsigned int default_xres, default_yres;
+ unsigned long default_xres, default_yres;
char *tmpc, *tmpm;
char *tmpc_sec, *tmpm_sec;
int vmode_index;
@@ -2196,8 +2196,8 @@ static int __devinit via_pci_probe(void)
viafb_FB_MM = viaparinfo->fbmem_virt;
tmpm = viafb_mode;
tmpc = strsep(&tmpm, "x");
- strict_strtoul(tmpc, 0, (unsigned long *)&default_xres);
- strict_strtoul(tmpm, 0, (unsigned long *)&default_yres);
+ strict_strtoul(tmpc, 0, &default_xres);
+ strict_strtoul(tmpm, 0, &default_yres);
vmode_index = viafb_get_mode_index(default_xres, default_yres, 0);
DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index);
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 90f98df5f106..f90afdb1b255 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -322,7 +322,8 @@ static int wdt_notify_sys(struct notifier_block *this,
* watchdog on reboot with no heartbeat
*/
wdt_change(WDT_ENABLE);
- printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n");
+ printk(KERN_INFO PFX "Watchdog timer is now enabled "
+ "with no heartbeat - should reboot in ~1 second.\n");
}
return NOTIFY_DONE;
}
@@ -374,12 +375,17 @@ static int __init alim7101_wdt_init(void)
pci_dev_put(ali1543_south);
if ((tmp & 0x1e) == 0x00) {
if (!use_gpio) {
- printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n");
+ printk(KERN_INFO PFX
+ "Detected old alim7101 revision 'a1d'. "
+ "If this is a cobalt board, set the 'use_gpio' "
+ "module parameter.\n");
goto err_out;
}
nowayout = 1;
} else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) {
- printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n");
+ printk(KERN_INFO PFX
+ "ALi 1543 South-Bridge does not have the correct "
+ "revision number (???1001?) - WDT not set\n");
goto err_out;
}
@@ -409,7 +415,8 @@ static int __init alim7101_wdt_init(void)
if (nowayout)
__module_get(THIS_MODULE);
- printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n",
+ printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. "
+ "timeout=%d sec (nowayout=%d)\n",
timeout, nowayout);
return 0;
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index 55dcbfe2bb72..3fe9742c23ca 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -246,7 +246,8 @@ static long ar7_wdt_ioctl(struct file *file,
static struct watchdog_info ident = {
.identity = LONGNAME,
.firmware_version = 1,
- .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING),
+ .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE),
};
int new_margin;
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index 29e52c237a3b..b185dafe1494 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -268,7 +268,8 @@ static int __init at91_wdt_init(void)
if not reset to the default */
if (at91_wdt_settimeout(wdt_time)) {
at91_wdt_settimeout(WDT_DEFAULT_TIME);
- pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time);
+ pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256"
+ ", using %d\n", wdt_time);
}
return platform_driver_register(&at91wdt_driver);
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 435b0573fb0a..eac26021e8da 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -156,7 +156,8 @@ static int at91_wdt_settimeout(unsigned int timeout)
static const struct watchdog_info at91_wdt_info = {
.identity = DRV_NAME,
- .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
};
/*
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index 067a57cb3f82..c7b3f9df2317 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -27,10 +27,15 @@
#include <linux/uaccess.h>
#include <asm/blackfin.h>
-#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
+#define stamp(fmt, args...) \
+ pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
#define stampit() stamp("here i am")
-#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); })
-#define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); })
+#define pr_devinit(fmt, args...) \
+ ({ static const __devinitconst char __fmt[] = fmt; \
+ printk(__fmt, ## args); })
+#define pr_init(fmt, args...) \
+ ({ static const __initconst char __fmt[] = fmt; \
+ printk(__fmt, ## args); })
#define WATCHDOG_NAME "bfin-wdt"
#define PFX WATCHDOG_NAME ": "
@@ -476,7 +481,8 @@ static int __init bfin_wdt_init(void)
return ret;
}
- bfin_wdt_device = platform_device_register_simple(WATCHDOG_NAME, -1, NULL, 0);
+ bfin_wdt_device = platform_device_register_simple(WATCHDOG_NAME,
+ -1, NULL, 0);
if (IS_ERR(bfin_wdt_device)) {
pr_init(KERN_ERR PFX "unable to register device\n");
platform_driver_unregister(&bfin_wdt_driver);
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 41070e4771a0..081f2955419e 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -154,9 +154,9 @@ static struct cpwd *cpwd_device;
static struct timer_list cpwd_timer;
-static int wd0_timeout = 0;
-static int wd1_timeout = 0;
-static int wd2_timeout = 0;
+static int wd0_timeout;
+static int wd1_timeout;
+static int wd2_timeout;
module_param(wd0_timeout, int, 0);
MODULE_PARM_DESC(wd0_timeout, "Default watchdog0 timeout in 1/10secs");
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index c51d0b0ea0c4..83e22e7ea4a2 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -193,7 +193,7 @@ static struct miscdevice davinci_wdt_miscdev = {
.fops = &davinci_wdt_fops,
};
-static int davinci_wdt_probe(struct platform_device *pdev)
+static int __devinit davinci_wdt_probe(struct platform_device *pdev)
{
int ret = 0, size;
struct resource *res;
@@ -237,7 +237,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
return ret;
}
-static int davinci_wdt_remove(struct platform_device *pdev)
+static int __devexit davinci_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&davinci_wdt_miscdev);
if (wdt_mem) {
@@ -254,7 +254,7 @@ static struct platform_driver platform_wdt_driver = {
.owner = THIS_MODULE,
},
.probe = davinci_wdt_probe,
- .remove = davinci_wdt_remove,
+ .remove = __devexit_p(davinci_wdt_remove),
};
static int __init davinci_wdt_init(void)
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
index d3c0f6de5523..843ef626bc50 100644
--- a/drivers/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -35,9 +35,9 @@
#include "iTCO_vendor.h"
/* iTCO defines */
-#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */
-#define TCOBASE acpibase + 0x60 /* TCO base address */
-#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
+#define SMI_EN (acpibase + 0x30) /* SMI Control and Enable Register */
+#define TCOBASE (acpibase + 0x60) /* TCO base address */
+#define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */
/* List of vendor support modes */
/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 648250b998c4..6284961eff5b 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -236,19 +236,19 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
/* Address definitions for the TCO */
/* TCO base address */
-#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60
+#define TCOBASE (iTCO_wdt_private.ACPIBASE + 0x60)
/* SMI Control and Enable Register */
-#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30
-
-#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */
-#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */
-#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
-#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
-#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
-#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */
-#define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */
-#define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */
-#define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */
+#define SMI_EN (iTCO_wdt_private.ACPIBASE + 0x30)
+
+#define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */
+#define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */
+#define TCO_DAT_IN (TCOBASE + 0x02) /* TCO Data In Register */
+#define TCO_DAT_OUT (TCOBASE + 0x03) /* TCO Data Out Register */
+#define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */
+#define TCO2_STS (TCOBASE + 0x06) /* TCO2 Status Register */
+#define TCO1_CNT (TCOBASE + 0x08) /* TCO1 Control Register */
+#define TCO2_CNT (TCOBASE + 0x0a) /* TCO2 Control Register */
+#define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */
/* internal variables */
static unsigned long is_active;
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c
index 0f761db9a27c..bea8a124a559 100644
--- a/drivers/watchdog/indydog.c
+++ b/drivers/watchdog/indydog.c
@@ -83,7 +83,6 @@ static int indydog_open(struct inode *inode, struct file *file)
indydog_start();
indydog_ping();
- indydog_alive = 1;
printk(KERN_INFO "Started watchdog timer.\n");
return nonseekable_open(inode, file);
@@ -113,8 +112,7 @@ static long indydog_ioctl(struct file *file, unsigned int cmd,
{
int options, retval = -EINVAL;
static struct watchdog_info ident = {
- .options = WDIOF_KEEPALIVEPING |
- WDIOF_MAGICCLOSE,
+ .options = WDIOF_KEEPALIVEPING,
.firmware_version = 0,
.identity = "Hardware Watchdog for SGI IP22",
};
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
index 2270ee07c01b..daed48ded7fe 100644
--- a/drivers/watchdog/it8712f_wdt.c
+++ b/drivers/watchdog/it8712f_wdt.c
@@ -239,7 +239,8 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
static struct watchdog_info ident = {
.identity = "IT8712F Watchdog",
.firmware_version = 1,
- .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
};
int value;
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index ae3832110acb..00b03eb43bf0 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -293,8 +293,8 @@ static int __init ks8695_wdt_init(void)
if not reset to the default */
if (ks8695_wdt_settimeout(wdt_time)) {
ks8695_wdt_settimeout(WDT_DEFAULT_TIME);
- pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n",
- wdt_time, WDT_MAX_TIME);
+ pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i"
+ ", using %d\n", wdt_time, WDT_MAX_TIME);
}
return platform_driver_register(&ks8695wdt_driver);
}
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index 2dfc27559bf7..b6b3f59ab446 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -118,7 +118,8 @@ static struct watchdog_info zf_info = {
*/
static int action;
module_param(action, int, 0);
-MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI");
+MODULE_PARM_DESC(action, "after watchdog resets, generate: "
+ "0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI");
static void zf_ping(unsigned long data);
@@ -142,7 +143,8 @@ static unsigned long next_heartbeat;
#ifndef ZF_DEBUG
# define dprintk(format, args...)
#else
-# define dprintk(format, args...) printk(KERN_DEBUG PFX ":%s:%d: " format, __func__, __LINE__ , ## args)
+# define dprintk(format, args...) printk(KERN_DEBUG PFX
+ ":%s:%d: " format, __func__, __LINE__ , ## args)
#endif
@@ -340,7 +342,8 @@ static int zf_close(struct inode *inode, struct file *file)
zf_timer_off();
else {
del_timer(&zf_timer);
- printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n");
+ printk(KERN_ERR PFX ": device file closed unexpectedly. "
+ "Will not stop the WDT!\n");
}
clear_bit(0, &zf_is_open);
zf_expect_close = 0;
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 1512ab8b175b..83fa34b214b4 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -61,7 +61,9 @@ MODULE_PARM_DESC(nowayout,
#define ONLY_TESTING 0
static int mpcore_noboot = ONLY_TESTING;
module_param(mpcore_noboot, int, 0);
-MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, set to 1 to ignore reboots, 0 to reboot (default=" __MODULE_STRING(ONLY_TESTING) ")");
+MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, "
+ "set to 1 to ignore reboots, 0 to reboot (default="
+ __MODULE_STRING(ONLY_TESTING) ")");
/*
* This is the interrupt handler. Note that we only use this
@@ -416,7 +418,8 @@ static struct platform_driver mpcore_wdt_driver = {
},
};
-static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n";
+static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. "
+ "mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n";
static int __init mpcore_wdt_init(void)
{
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index 539b6f6ba7f1..08e8a6ab74e1 100644
--- a/drivers/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
@@ -206,7 +206,7 @@ static struct miscdevice mtx1_wdt_misc = {
};
-static int mtx1_wdt_probe(struct platform_device *pdev)
+static int __devinit mtx1_wdt_probe(struct platform_device *pdev)
{
int ret;
@@ -229,7 +229,7 @@ static int mtx1_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int mtx1_wdt_remove(struct platform_device *pdev)
+static int __devexit mtx1_wdt_remove(struct platform_device *pdev)
{
/* FIXME: do we need to lock this test ? */
if (mtx1_wdt_device.queue) {
@@ -242,7 +242,7 @@ static int mtx1_wdt_remove(struct platform_device *pdev)
static struct platform_driver mtx1_wdt = {
.probe = mtx1_wdt_probe,
- .remove = mtx1_wdt_remove,
+ .remove = __devexit_p(mtx1_wdt_remove),
.driver.name = "mtx1-wdt",
.driver.owner = THIS_MODULE,
};
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 64135195f827..f24d04132eda 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -246,7 +246,7 @@ static struct miscdevice pnx4008_wdt_miscdev = {
.fops = &pnx4008_wdt_fops,
};
-static int pnx4008_wdt_probe(struct platform_device *pdev)
+static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
{
int ret = 0, size;
struct resource *res;
@@ -299,7 +299,7 @@ out:
return ret;
}
-static int pnx4008_wdt_remove(struct platform_device *pdev)
+static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&pnx4008_wdt_miscdev);
if (wdt_clk) {
@@ -321,7 +321,7 @@ static struct platform_driver platform_wdt_driver = {
.owner = THIS_MODULE,
},
.probe = pnx4008_wdt_probe,
- .remove = pnx4008_wdt_remove,
+ .remove = __devexit_p(pnx4008_wdt_remove),
};
static int __init pnx4008_wdt_init(void)
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 36e221beedcd..4976bfd1fce6 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -245,7 +245,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int rdc321x_wdt_remove(struct platform_device *pdev)
+static int __devexit rdc321x_wdt_remove(struct platform_device *pdev)
{
if (rdc321x_wdt_device.queue) {
rdc321x_wdt_device.queue = 0;
@@ -259,7 +259,7 @@ static int rdc321x_wdt_remove(struct platform_device *pdev)
static struct platform_driver rdc321x_wdt_driver = {
.probe = rdc321x_wdt_probe,
- .remove = rdc321x_wdt_remove,
+ .remove = __devexit_p(rdc321x_wdt_remove),
.driver = {
.owner = THIS_MODULE,
.name = "rdc321x-wdt",
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
index cce1982a1b58..2e4442642262 100644
--- a/drivers/watchdog/rm9k_wdt.c
+++ b/drivers/watchdog/rm9k_wdt.c
@@ -345,8 +345,8 @@ static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv,
return platform_get_resource_byname(pdv, type, buf);
}
-/* No hotplugging on the platform bus - use __init */
-static int __init wdt_gpi_probe(struct platform_device *pdv)
+/* No hotplugging on the platform bus - use __devinit */
+static int __devinit wdt_gpi_probe(struct platform_device *pdv)
{
int res;
const struct resource
@@ -373,7 +373,7 @@ static int __init wdt_gpi_probe(struct platform_device *pdv)
return res;
}
-static int __exit wdt_gpi_remove(struct platform_device *dev)
+static int __devexit wdt_gpi_remove(struct platform_device *dev)
{
int res;
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index e31925ee8346..b57ac6b49147 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -68,15 +68,10 @@ MODULE_PARM_DESC(tmr_atboot,
__MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)");
+MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, "
+ "0 to reboot (default depends on ONLY_TESTING)");
MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug, (default 0)");
-
-typedef enum close_state {
- CLOSE_STATE_NOT,
- CLOSE_STATE_ALLOW = 0x4021
-} close_state_t;
-
static unsigned long open_lock;
static struct device *wdt_dev; /* platform device attached to */
static struct resource *wdt_mem;
@@ -84,7 +79,7 @@ static struct resource *wdt_irq;
static struct clk *wdt_clock;
static void __iomem *wdt_base;
static unsigned int wdt_count;
-static close_state_t allow_close;
+static char expect_close;
static DEFINE_SPINLOCK(wdt_lock);
/* watchdog control routines */
@@ -211,7 +206,7 @@ static int s3c2410wdt_open(struct inode *inode, struct file *file)
if (nowayout)
__module_get(THIS_MODULE);
- allow_close = CLOSE_STATE_NOT;
+ expect_close = 0;
/* start the timer */
s3c2410wdt_start();
@@ -225,13 +220,13 @@ static int s3c2410wdt_release(struct inode *inode, struct file *file)
* Lock it in if it's a module and we set nowayout
*/
- if (allow_close == CLOSE_STATE_ALLOW)
+ if (expect_close == 42)
s3c2410wdt_stop();
else {
dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n");
s3c2410wdt_keepalive();
}
- allow_close = CLOSE_STATE_NOT;
+ expect_close = 0;
clear_bit(0, &open_lock);
return 0;
}
@@ -247,7 +242,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
size_t i;
/* In case it was set long ago */
- allow_close = CLOSE_STATE_NOT;
+ expect_close = 0;
for (i = 0; i != len; i++) {
char c;
@@ -255,7 +250,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
if (get_user(c, data + i))
return -EFAULT;
if (c == 'V')
- allow_close = CLOSE_STATE_ALLOW;
+ expect_close = 42;
}
}
s3c2410wdt_keepalive();
@@ -263,7 +258,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
return len;
}
-#define OPTIONS WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE
+#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
static const struct watchdog_info s3c2410_wdt_ident = {
.options = OPTIONS,
@@ -331,7 +326,7 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
}
/* device interface */
-static int s3c2410wdt_probe(struct platform_device *pdev)
+static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
{
struct resource *res;
struct device *dev;
@@ -404,7 +399,8 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
"tmr_margin value out of range, default %d used\n",
CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
else
- dev_info(dev, "default timer value is out of range, cannot start\n");
+ dev_info(dev, "default timer value is out of range, "
+ "cannot start\n");
}
ret = misc_register(&s3c2410wdt_miscdev);
@@ -453,7 +449,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
return ret;
}
-static int s3c2410wdt_remove(struct platform_device *dev)
+static int __devexit s3c2410wdt_remove(struct platform_device *dev)
{
release_resource(wdt_mem);
kfree(wdt_mem);
@@ -515,7 +511,7 @@ static int s3c2410wdt_resume(struct platform_device *dev)
static struct platform_driver s3c2410wdt_driver = {
.probe = s3c2410wdt_probe,
- .remove = s3c2410wdt_remove,
+ .remove = __devexit_p(s3c2410wdt_remove),
.shutdown = s3c2410wdt_shutdown,
.suspend = s3c2410wdt_suspend,
.resume = s3c2410wdt_resume,
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index 38f5831c9291..9748eed73196 100644
--- a/drivers/watchdog/sb_wdog.c
+++ b/drivers/watchdog/sb_wdog.c
@@ -93,7 +93,7 @@ static int expect_close;
static const struct watchdog_info ident = {
.options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
- WDIOF_KEEPALIVEPING,
+ WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.identity = "SiByte Watchdog",
};
@@ -269,9 +269,10 @@ irqreturn_t sbwdog_interrupt(int irq, void *addr)
* if it's the second watchdog timer, it's for those users
*/
if (wd_cfg_reg == user_dog)
- printk(KERN_CRIT
- "%s in danger of initiating system reset in %ld.%01ld seconds\n",
- ident.identity, wd_init / 1000000, (wd_init / 100000) % 10);
+ printk(KERN_CRIT "%s in danger of initiating system reset "
+ "in %ld.%01ld seconds\n",
+ ident.identity,
+ wd_init / 1000000, (wd_init / 100000) % 10);
else
cfg |= 1;
diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c
index d1c390c7155c..626d0e8e56c3 100644
--- a/drivers/watchdog/sbc60xxwdt.c
+++ b/drivers/watchdog/sbc60xxwdt.c
@@ -372,8 +372,9 @@ static int __init sbc60xxwdt_init(void)
wdt_miscdev.minor, rc);
goto err_out_reboot;
}
- printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n",
- timeout, nowayout);
+ printk(KERN_INFO PFX
+ "WDT driver for 60XX single board computer initialised. "
+ "timeout=%d sec (nowayout=%d)\n", timeout, nowayout);
return 0;
diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c
index b6e6799ec45d..68e2e2d6f73d 100644
--- a/drivers/watchdog/sbc8360.c
+++ b/drivers/watchdog/sbc8360.c
@@ -280,8 +280,8 @@ static int sbc8360_close(struct inode *inode, struct file *file)
if (expect_close == 42)
sbc8360_stop();
else
- printk(KERN_CRIT PFX
- "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n");
+ printk(KERN_CRIT PFX "SBC8360 device closed unexpectedly. "
+ "SBC8360 will not stop!\n");
clear_bit(0, &sbc8360_is_open);
expect_close = 0;
diff --git a/drivers/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c
index e467ddcf796a..28f1214457bd 100644
--- a/drivers/watchdog/sbc_epx_c3.c
+++ b/drivers/watchdog/sbc_epx_c3.c
@@ -107,8 +107,7 @@ static long epx_c3_ioctl(struct file *file, unsigned int cmd,
int options, retval = -EINVAL;
int __user *argp = (void __user *)arg;
static const struct watchdog_info ident = {
- .options = WDIOF_KEEPALIVEPING |
- WDIOF_MAGICCLOSE,
+ .options = WDIOF_KEEPALIVEPING,
.firmware_version = 0,
.identity = "Winsystems EPX-C3 H/W Watchdog",
};
@@ -174,8 +173,8 @@ static struct notifier_block epx_c3_notifier = {
.notifier_call = epx_c3_notify_sys,
};
-static const char banner[] __initdata =
- KERN_INFO PFX "Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n";
+static const char banner[] __initdata = KERN_INFO PFX
+ "Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n";
static int __init watchdog_init(void)
{
@@ -219,6 +218,9 @@ module_init(watchdog_init);
module_exit(watchdog_exit);
MODULE_AUTHOR("Calin A. Culianu <calin@ajvar.org>");
-MODULE_DESCRIPTION("Hardware Watchdog Device for Winsystems EPX-C3 SBC. Note that there is no way to probe for this device -- so only use it if you are *sure* you are runnning on this specific SBC system from Winsystems! It writes to IO ports 0x1ee and 0x1ef!");
+MODULE_DESCRIPTION("Hardware Watchdog Device for Winsystems EPX-C3 SBC. "
+ "Note that there is no way to probe for this device -- "
+ "so only use it if you are *sure* you are runnning on this specific "
+ "SBC system from Winsystems! It writes to IO ports 0x1ee and 0x1ef!");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/scx200_wdt.c b/drivers/watchdog/scx200_wdt.c
index 9e19a10a5bb9..e67b76c0526c 100644
--- a/drivers/watchdog/scx200_wdt.c
+++ b/drivers/watchdog/scx200_wdt.c
@@ -108,7 +108,9 @@ static int scx200_wdt_open(struct inode *inode, struct file *file)
static int scx200_wdt_release(struct inode *inode, struct file *file)
{
if (expect_close != 42)
- printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n");
+ printk(KERN_WARNING NAME
+ ": watchdog device closed unexpectedly, "
+ "will not disable the watchdog timer\n");
else if (!nowayout)
scx200_wdt_disable();
expect_close = 0;
@@ -163,7 +165,8 @@ static long scx200_wdt_ioctl(struct file *file, unsigned int cmd,
static const struct watchdog_info ident = {
.identity = "NatSemi SCx200 Watchdog",
.firmware_version = 1,
- .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
};
int new_margin;
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index cdc7138be301..a03f84e5ee1f 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -494,7 +494,9 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
module_param(clock_division_ratio, int, 0);
-MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")");
+MODULE_PARM_DESC(clock_division_ratio,
+ "Clock division ratio. Valid ranges are from 0x5 (1.31ms) "
+ "to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")");
module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat,
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c
index ebcc9cea5e99..833f49f43d43 100644
--- a/drivers/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
@@ -71,7 +71,9 @@ static int soft_noboot = 0;
#endif /* ONLY_TESTING */
module_param(soft_noboot, int, 0);
-MODULE_PARM_DESC(soft_noboot, "Softdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)");
+MODULE_PARM_DESC(soft_noboot,
+ "Softdog action, set to 1 to ignore reboots, 0 to reboot "
+ "(default depends on ONLY_TESTING)");
/*
* Our timer
@@ -264,7 +266,8 @@ static struct notifier_block softdog_notifier = {
.notifier_call = softdog_notify_sys,
};
-static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07 initialized. soft_noboot=%d soft_margin=%d sec (nowayout= %d)\n";
+static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07 "
+ "initialized. soft_noboot=%d soft_margin=%d sec (nowayout= %d)\n";
static int __init watchdog_init(void)
{
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c
index a9c7f352fcbf..af08972de506 100644
--- a/drivers/watchdog/w83697hf_wdt.c
+++ b/drivers/watchdog/w83697hf_wdt.c
@@ -413,7 +413,8 @@ static int __init wdt_init(void)
w83697hf_init();
if (early_disable) {
if (wdt_running())
- printk(KERN_WARNING PFX "Stopping previously enabled watchdog until userland kicks in\n");
+ printk(KERN_WARNING PFX "Stopping previously enabled "
+ "watchdog until userland kicks in\n");
wdt_disable();
}
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index a38fa4907c92..a4fe7a38d9b0 100644
--- a/drivers/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
@@ -49,12 +49,7 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
MODULE_ALIAS_MISCDEV(TEMP_MINOR);
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int wdrtas_nowayout = 1;
-#else
-static int wdrtas_nowayout = 0;
-#endif
-
+static int wdrtas_nowayout = WATCHDOG_NOWAYOUT;
static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
static char wdrtas_expect_close;
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 8ac9cddac575..cab100acf983 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -18,6 +18,16 @@ config XEN_SCRUB_PAGES
secure, but slightly less efficient.
If in doubt, say yes.
+config XEN_DEV_EVTCHN
+ tristate "Xen /dev/xen/evtchn device"
+ depends on XEN
+ default y
+ help
+ The evtchn driver allows a userspace process to triger event
+ channels and to receive notification of an event channel
+ firing.
+ If in doubt, say yes.
+
config XENFS
tristate "Xen filesystem"
depends on XEN
@@ -41,3 +51,13 @@ config XEN_COMPAT_XENFS
a xen platform.
If in doubt, say yes.
+config XEN_SYS_HYPERVISOR
+ bool "Create xen entries under /sys/hypervisor"
+ depends on XEN && SYSFS
+ select SYS_HYPERVISOR
+ default y
+ help
+ Create entries under /sys/hypervisor describing the Xen
+ hypervisor environment. When running native or in another
+ virtual environment, /sys/hypervisor will still be present,
+ but will have no xen contents. \ No newline at end of file
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index ff8accc9e103..ec2a39b1e26f 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -4,4 +4,6 @@ obj-y += xenbus/
obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
obj-$(CONFIG_XEN_XENCOMM) += xencomm.o
obj-$(CONFIG_XEN_BALLOON) += balloon.o
-obj-$(CONFIG_XENFS) += xenfs/ \ No newline at end of file
+obj-$(CONFIG_XEN_DEV_EVTCHN) += evtchn.o
+obj-$(CONFIG_XENFS) += xenfs/
+obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o \ No newline at end of file
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 30963af5dba0..891d2e90753a 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -151,6 +151,12 @@ static unsigned int evtchn_from_irq(unsigned irq)
return info_for_irq(irq)->evtchn;
}
+unsigned irq_from_evtchn(unsigned int evtchn)
+{
+ return evtchn_to_irq[evtchn];
+}
+EXPORT_SYMBOL_GPL(irq_from_evtchn);
+
static enum ipi_vector ipi_from_irq(unsigned irq)
{
struct irq_info *info = info_for_irq(irq);
@@ -335,7 +341,7 @@ static int find_unbound_irq(void)
if (irq == nr_irqs)
panic("No available IRQ to bind to: increase nr_irqs!\n");
- desc = irq_to_desc_alloc_cpu(irq, 0);
+ desc = irq_to_desc_alloc_node(irq, 0);
if (WARN_ON(desc == NULL))
return -1;
@@ -688,13 +694,13 @@ void rebind_evtchn_irq(int evtchn, int irq)
}
/* Rebind an evtchn so that it gets delivered to a specific cpu */
-static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
+static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
{
struct evtchn_bind_vcpu bind_vcpu;
int evtchn = evtchn_from_irq(irq);
if (!VALID_EVTCHN(evtchn))
- return;
+ return -1;
/* Send future instances of this interrupt to other vcpu. */
bind_vcpu.port = evtchn;
@@ -707,13 +713,15 @@ static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
*/
if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
bind_evtchn_to_cpu(evtchn, tcpu);
-}
+ return 0;
+}
-static void set_affinity_irq(unsigned irq, const struct cpumask *dest)
+static int set_affinity_irq(unsigned irq, const struct cpumask *dest)
{
unsigned tcpu = cpumask_first(dest);
- rebind_irq_to_cpu(irq, tcpu);
+
+ return rebind_irq_to_cpu(irq, tcpu);
}
int resend_irq_on_evtchn(unsigned int irq)
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
new file mode 100644
index 000000000000..af031950f9b1
--- /dev/null
+++ b/drivers/xen/evtchn.c
@@ -0,0 +1,507 @@
+/******************************************************************************
+ * evtchn.c
+ *
+ * Driver for receiving and demuxing event-channel signals.
+ *
+ * Copyright (c) 2004-2005, K A Fraser
+ * Multi-process extensions Copyright (c) 2004, Steven Smith
+ *
+ * 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; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/major.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/poll.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <linux/mutex.h>
+#include <linux/cpu.h>
+#include <xen/events.h>
+#include <xen/evtchn.h>
+#include <asm/xen/hypervisor.h>
+
+struct per_user_data {
+ struct mutex bind_mutex; /* serialize bind/unbind operations */
+
+ /* Notification ring, accessed via /dev/xen/evtchn. */
+#define EVTCHN_RING_SIZE (PAGE_SIZE / sizeof(evtchn_port_t))
+#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
+ evtchn_port_t *ring;
+ unsigned int ring_cons, ring_prod, ring_overflow;
+ struct mutex ring_cons_mutex; /* protect against concurrent readers */
+
+ /* Processes wait on this queue when ring is empty. */
+ wait_queue_head_t evtchn_wait;
+ struct fasync_struct *evtchn_async_queue;
+ const char *name;
+};
+
+/* Who's bound to each port? */
+static struct per_user_data *port_user[NR_EVENT_CHANNELS];
+static DEFINE_SPINLOCK(port_user_lock); /* protects port_user[] and ring_prod */
+
+irqreturn_t evtchn_interrupt(int irq, void *data)
+{
+ unsigned int port = (unsigned long)data;
+ struct per_user_data *u;
+
+ spin_lock(&port_user_lock);
+
+ u = port_user[port];
+
+ disable_irq_nosync(irq);
+
+ if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
+ u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
+ wmb(); /* Ensure ring contents visible */
+ if (u->ring_cons == u->ring_prod++) {
+ wake_up_interruptible(&u->evtchn_wait);
+ kill_fasync(&u->evtchn_async_queue,
+ SIGIO, POLL_IN);
+ }
+ } else {
+ u->ring_overflow = 1;
+ }
+
+ spin_unlock(&port_user_lock);
+
+ return IRQ_HANDLED;
+}
+
+static ssize_t evtchn_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int rc;
+ unsigned int c, p, bytes1 = 0, bytes2 = 0;
+ struct per_user_data *u = file->private_data;
+
+ /* Whole number of ports. */
+ count &= ~(sizeof(evtchn_port_t)-1);
+
+ if (count == 0)
+ return 0;
+
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
+
+ for (;;) {
+ mutex_lock(&u->ring_cons_mutex);
+
+ rc = -EFBIG;
+ if (u->ring_overflow)
+ goto unlock_out;
+
+ c = u->ring_cons;
+ p = u->ring_prod;
+ if (c != p)
+ break;
+
+ mutex_unlock(&u->ring_cons_mutex);
+
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ rc = wait_event_interruptible(u->evtchn_wait,
+ u->ring_cons != u->ring_prod);
+ if (rc)
+ return rc;
+ }
+
+ /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
+ if (((c ^ p) & EVTCHN_RING_SIZE) != 0) {
+ bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) *
+ sizeof(evtchn_port_t);
+ bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t);
+ } else {
+ bytes1 = (p - c) * sizeof(evtchn_port_t);
+ bytes2 = 0;
+ }
+
+ /* Truncate chunks according to caller's maximum byte count. */
+ if (bytes1 > count) {
+ bytes1 = count;
+ bytes2 = 0;
+ } else if ((bytes1 + bytes2) > count) {
+ bytes2 = count - bytes1;
+ }
+
+ rc = -EFAULT;
+ rmb(); /* Ensure that we see the port before we copy it. */
+ if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
+ ((bytes2 != 0) &&
+ copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
+ goto unlock_out;
+
+ u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
+ rc = bytes1 + bytes2;
+
+ unlock_out:
+ mutex_unlock(&u->ring_cons_mutex);
+ return rc;
+}
+
+static ssize_t evtchn_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int rc, i;
+ evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
+ struct per_user_data *u = file->private_data;
+
+ if (kbuf == NULL)
+ return -ENOMEM;
+
+ /* Whole number of ports. */
+ count &= ~(sizeof(evtchn_port_t)-1);
+
+ rc = 0;
+ if (count == 0)
+ goto out;
+
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
+
+ rc = -EFAULT;
+ if (copy_from_user(kbuf, buf, count) != 0)
+ goto out;
+
+ spin_lock_irq(&port_user_lock);
+ for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
+ if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
+ enable_irq(irq_from_evtchn(kbuf[i]));
+ spin_unlock_irq(&port_user_lock);
+
+ rc = count;
+
+ out:
+ free_page((unsigned long)kbuf);
+ return rc;
+}
+
+static int evtchn_bind_to_user(struct per_user_data *u, int port)
+{
+ int rc = 0;
+
+ /*
+ * Ports are never reused, so every caller should pass in a
+ * unique port.
+ *
+ * (Locking not necessary because we haven't registered the
+ * interrupt handler yet, and our caller has already
+ * serialized bind operations.)
+ */
+ BUG_ON(port_user[port] != NULL);
+ port_user[port] = u;
+
+ rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED,
+ u->name, (void *)(unsigned long)port);
+ if (rc >= 0)
+ rc = 0;
+
+ return rc;
+}
+
+static void evtchn_unbind_from_user(struct per_user_data *u, int port)
+{
+ int irq = irq_from_evtchn(port);
+
+ unbind_from_irqhandler(irq, (void *)(unsigned long)port);
+
+ /* make sure we unbind the irq handler before clearing the port */
+ barrier();
+
+ port_user[port] = NULL;
+}
+
+static long evtchn_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int rc;
+ struct per_user_data *u = file->private_data;
+ void __user *uarg = (void __user *) arg;
+
+ /* Prevent bind from racing with unbind */
+ mutex_lock(&u->bind_mutex);
+
+ switch (cmd) {
+ case IOCTL_EVTCHN_BIND_VIRQ: {
+ struct ioctl_evtchn_bind_virq bind;
+ struct evtchn_bind_virq bind_virq;
+
+ rc = -EFAULT;
+ if (copy_from_user(&bind, uarg, sizeof(bind)))
+ break;
+
+ bind_virq.virq = bind.virq;
+ bind_virq.vcpu = 0;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+ &bind_virq);
+ if (rc != 0)
+ break;
+
+ rc = evtchn_bind_to_user(u, bind_virq.port);
+ if (rc == 0)
+ rc = bind_virq.port;
+ break;
+ }
+
+ case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
+ struct ioctl_evtchn_bind_interdomain bind;
+ struct evtchn_bind_interdomain bind_interdomain;
+
+ rc = -EFAULT;
+ if (copy_from_user(&bind, uarg, sizeof(bind)))
+ break;
+
+ bind_interdomain.remote_dom = bind.remote_domain;
+ bind_interdomain.remote_port = bind.remote_port;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
+ if (rc != 0)
+ break;
+
+ rc = evtchn_bind_to_user(u, bind_interdomain.local_port);
+ if (rc == 0)
+ rc = bind_interdomain.local_port;
+ break;
+ }
+
+ case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
+ struct ioctl_evtchn_bind_unbound_port bind;
+ struct evtchn_alloc_unbound alloc_unbound;
+
+ rc = -EFAULT;
+ if (copy_from_user(&bind, uarg, sizeof(bind)))
+ break;
+
+ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = bind.remote_domain;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+ &alloc_unbound);
+ if (rc != 0)
+ break;
+
+ rc = evtchn_bind_to_user(u, alloc_unbound.port);
+ if (rc == 0)
+ rc = alloc_unbound.port;
+ break;
+ }
+
+ case IOCTL_EVTCHN_UNBIND: {
+ struct ioctl_evtchn_unbind unbind;
+
+ rc = -EFAULT;
+ if (copy_from_user(&unbind, uarg, sizeof(unbind)))
+ break;
+
+ rc = -EINVAL;
+ if (unbind.port >= NR_EVENT_CHANNELS)
+ break;
+
+ spin_lock_irq(&port_user_lock);
+
+ rc = -ENOTCONN;
+ if (port_user[unbind.port] != u) {
+ spin_unlock_irq(&port_user_lock);
+ break;
+ }
+
+ evtchn_unbind_from_user(u, unbind.port);
+
+ spin_unlock_irq(&port_user_lock);
+
+ rc = 0;
+ break;
+ }
+
+ case IOCTL_EVTCHN_NOTIFY: {
+ struct ioctl_evtchn_notify notify;
+
+ rc = -EFAULT;
+ if (copy_from_user(&notify, uarg, sizeof(notify)))
+ break;
+
+ if (notify.port >= NR_EVENT_CHANNELS) {
+ rc = -EINVAL;
+ } else if (port_user[notify.port] != u) {
+ rc = -ENOTCONN;
+ } else {
+ notify_remote_via_evtchn(notify.port);
+ rc = 0;
+ }
+ break;
+ }
+
+ case IOCTL_EVTCHN_RESET: {
+ /* Initialise the ring to empty. Clear errors. */
+ mutex_lock(&u->ring_cons_mutex);
+ spin_lock_irq(&port_user_lock);
+ u->ring_cons = u->ring_prod = u->ring_overflow = 0;
+ spin_unlock_irq(&port_user_lock);
+ mutex_unlock(&u->ring_cons_mutex);
+ rc = 0;
+ break;
+ }
+
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+ mutex_unlock(&u->bind_mutex);
+
+ return rc;
+}
+
+static unsigned int evtchn_poll(struct file *file, poll_table *wait)
+{
+ unsigned int mask = POLLOUT | POLLWRNORM;
+ struct per_user_data *u = file->private_data;
+
+ poll_wait(file, &u->evtchn_wait, wait);
+ if (u->ring_cons != u->ring_prod)
+ mask |= POLLIN | POLLRDNORM;
+ if (u->ring_overflow)
+ mask = POLLERR;
+ return mask;
+}
+
+static int evtchn_fasync(int fd, struct file *filp, int on)
+{
+ struct per_user_data *u = filp->private_data;
+ return fasync_helper(fd, filp, on, &u->evtchn_async_queue);
+}
+
+static int evtchn_open(struct inode *inode, struct file *filp)
+{
+ struct per_user_data *u;
+
+ u = kzalloc(sizeof(*u), GFP_KERNEL);
+ if (u == NULL)
+ return -ENOMEM;
+
+ u->name = kasprintf(GFP_KERNEL, "evtchn:%s", current->comm);
+ if (u->name == NULL) {
+ kfree(u);
+ return -ENOMEM;
+ }
+
+ init_waitqueue_head(&u->evtchn_wait);
+
+ u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
+ if (u->ring == NULL) {
+ kfree(u->name);
+ kfree(u);
+ return -ENOMEM;
+ }
+
+ mutex_init(&u->bind_mutex);
+ mutex_init(&u->ring_cons_mutex);
+
+ filp->private_data = u;
+
+ return 0;
+}
+
+static int evtchn_release(struct inode *inode, struct file *filp)
+{
+ int i;
+ struct per_user_data *u = filp->private_data;
+
+ spin_lock_irq(&port_user_lock);
+
+ free_page((unsigned long)u->ring);
+
+ for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+ if (port_user[i] != u)
+ continue;
+
+ evtchn_unbind_from_user(port_user[i], i);
+ }
+
+ spin_unlock_irq(&port_user_lock);
+
+ kfree(u->name);
+ kfree(u);
+
+ return 0;
+}
+
+static const struct file_operations evtchn_fops = {
+ .owner = THIS_MODULE,
+ .read = evtchn_read,
+ .write = evtchn_write,
+ .unlocked_ioctl = evtchn_ioctl,
+ .poll = evtchn_poll,
+ .fasync = evtchn_fasync,
+ .open = evtchn_open,
+ .release = evtchn_release,
+};
+
+static struct miscdevice evtchn_miscdev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "evtchn",
+ .fops = &evtchn_fops,
+};
+static int __init evtchn_init(void)
+{
+ int err;
+
+ if (!xen_domain())
+ return -ENODEV;
+
+ spin_lock_init(&port_user_lock);
+ memset(port_user, 0, sizeof(port_user));
+
+ /* Create '/dev/misc/evtchn'. */
+ err = misc_register(&evtchn_miscdev);
+ if (err != 0) {
+ printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
+ return err;
+ }
+
+ printk(KERN_INFO "Event-channel device installed.\n");
+
+ return 0;
+}
+
+static void __exit evtchn_cleanup(void)
+{
+ misc_deregister(&evtchn_miscdev);
+}
+
+module_init(evtchn_init);
+module_exit(evtchn_cleanup);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 4b5b84837ee1..fddc2025dece 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -98,9 +98,8 @@ static void do_suspend(void)
goto out;
}
- printk("suspending xenbus...\n");
- /* XXX use normal device tree? */
- xenbus_suspend();
+ printk(KERN_DEBUG "suspending xenstore...\n");
+ xs_suspend();
err = device_power_down(PMSG_SUSPEND);
if (err) {
@@ -116,9 +115,9 @@ static void do_suspend(void)
if (!cancelled) {
xen_arch_resume();
- xenbus_resume();
+ xs_resume();
} else
- xenbus_suspend_cancel();
+ xs_suspend_cancel();
device_power_up(PMSG_RESUME);
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c
new file mode 100644
index 000000000000..88a60e03ccf0
--- /dev/null
+++ b/drivers/xen/sys-hypervisor.c
@@ -0,0 +1,445 @@
+/*
+ * copyright (c) 2006 IBM Corporation
+ * Authored by: Mike D. Day <ncmike@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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kobject.h>
+
+#include <asm/xen/hypervisor.h>
+#include <asm/xen/hypercall.h>
+
+#include <xen/xenbus.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/version.h>
+
+#define HYPERVISOR_ATTR_RO(_name) \
+static struct hyp_sysfs_attr _name##_attr = __ATTR_RO(_name)
+
+#define HYPERVISOR_ATTR_RW(_name) \
+static struct hyp_sysfs_attr _name##_attr = \
+ __ATTR(_name, 0644, _name##_show, _name##_store)
+
+struct hyp_sysfs_attr {
+ struct attribute attr;
+ ssize_t (*show)(struct hyp_sysfs_attr *, char *);
+ ssize_t (*store)(struct hyp_sysfs_attr *, const char *, size_t);
+ void *hyp_attr_data;
+};
+
+static ssize_t type_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ return sprintf(buffer, "xen\n");
+}
+
+HYPERVISOR_ATTR_RO(type);
+
+static int __init xen_sysfs_type_init(void)
+{
+ return sysfs_create_file(hypervisor_kobj, &type_attr.attr);
+}
+
+static void xen_sysfs_type_destroy(void)
+{
+ sysfs_remove_file(hypervisor_kobj, &type_attr.attr);
+}
+
+/* xen version attributes */
+static ssize_t major_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int version = HYPERVISOR_xen_version(XENVER_version, NULL);
+ if (version)
+ return sprintf(buffer, "%d\n", version >> 16);
+ return -ENODEV;
+}
+
+HYPERVISOR_ATTR_RO(major);
+
+static ssize_t minor_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int version = HYPERVISOR_xen_version(XENVER_version, NULL);
+ if (version)
+ return sprintf(buffer, "%d\n", version & 0xff);
+ return -ENODEV;
+}
+
+HYPERVISOR_ATTR_RO(minor);
+
+static ssize_t extra_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int ret = -ENOMEM;
+ char *extra;
+
+ extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL);
+ if (extra) {
+ ret = HYPERVISOR_xen_version(XENVER_extraversion, extra);
+ if (!ret)
+ ret = sprintf(buffer, "%s\n", extra);
+ kfree(extra);
+ }
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(extra);
+
+static struct attribute *version_attrs[] = {
+ &major_attr.attr,
+ &minor_attr.attr,
+ &extra_attr.attr,
+ NULL
+};
+
+static struct attribute_group version_group = {
+ .name = "version",
+ .attrs = version_attrs,
+};
+
+static int __init xen_sysfs_version_init(void)
+{
+ return sysfs_create_group(hypervisor_kobj, &version_group);
+}
+
+static void xen_sysfs_version_destroy(void)
+{
+ sysfs_remove_group(hypervisor_kobj, &version_group);
+}
+
+/* UUID */
+
+static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ char *vm, *val;
+ int ret;
+ extern int xenstored_ready;
+
+ if (!xenstored_ready)
+ return -EBUSY;
+
+ vm = xenbus_read(XBT_NIL, "vm", "", NULL);
+ if (IS_ERR(vm))
+ return PTR_ERR(vm);
+ val = xenbus_read(XBT_NIL, vm, "uuid", NULL);
+ kfree(vm);
+ if (IS_ERR(val))
+ return PTR_ERR(val);
+ ret = sprintf(buffer, "%s\n", val);
+ kfree(val);
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(uuid);
+
+static int __init xen_sysfs_uuid_init(void)
+{
+ return sysfs_create_file(hypervisor_kobj, &uuid_attr.attr);
+}
+
+static void xen_sysfs_uuid_destroy(void)
+{
+ sysfs_remove_file(hypervisor_kobj, &uuid_attr.attr);
+}
+
+/* xen compilation attributes */
+
+static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int ret = -ENOMEM;
+ struct xen_compile_info *info;
+
+ info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
+ if (info) {
+ ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
+ if (!ret)
+ ret = sprintf(buffer, "%s\n", info->compiler);
+ kfree(info);
+ }
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(compiler);
+
+static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int ret = -ENOMEM;
+ struct xen_compile_info *info;
+
+ info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
+ if (info) {
+ ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
+ if (!ret)
+ ret = sprintf(buffer, "%s\n", info->compile_by);
+ kfree(info);
+ }
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(compiled_by);
+
+static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int ret = -ENOMEM;
+ struct xen_compile_info *info;
+
+ info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
+ if (info) {
+ ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
+ if (!ret)
+ ret = sprintf(buffer, "%s\n", info->compile_date);
+ kfree(info);
+ }
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(compile_date);
+
+static struct attribute *xen_compile_attrs[] = {
+ &compiler_attr.attr,
+ &compiled_by_attr.attr,
+ &compile_date_attr.attr,
+ NULL
+};
+
+static struct attribute_group xen_compilation_group = {
+ .name = "compilation",
+ .attrs = xen_compile_attrs,
+};
+
+int __init static xen_compilation_init(void)
+{
+ return sysfs_create_group(hypervisor_kobj, &xen_compilation_group);
+}
+
+static void xen_compilation_destroy(void)
+{
+ sysfs_remove_group(hypervisor_kobj, &xen_compilation_group);
+}
+
+/* xen properties info */
+
+static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int ret = -ENOMEM;
+ char *caps;
+
+ caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL);
+ if (caps) {
+ ret = HYPERVISOR_xen_version(XENVER_capabilities, caps);
+ if (!ret)
+ ret = sprintf(buffer, "%s\n", caps);
+ kfree(caps);
+ }
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(capabilities);
+
+static ssize_t changeset_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int ret = -ENOMEM;
+ char *cset;
+
+ cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL);
+ if (cset) {
+ ret = HYPERVISOR_xen_version(XENVER_changeset, cset);
+ if (!ret)
+ ret = sprintf(buffer, "%s\n", cset);
+ kfree(cset);
+ }
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(changeset);
+
+static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int ret = -ENOMEM;
+ struct xen_platform_parameters *parms;
+
+ parms = kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL);
+ if (parms) {
+ ret = HYPERVISOR_xen_version(XENVER_platform_parameters,
+ parms);
+ if (!ret)
+ ret = sprintf(buffer, "%lx\n", parms->virt_start);
+ kfree(parms);
+ }
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(virtual_start);
+
+static ssize_t pagesize_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int ret;
+
+ ret = HYPERVISOR_xen_version(XENVER_pagesize, NULL);
+ if (ret > 0)
+ ret = sprintf(buffer, "%x\n", ret);
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(pagesize);
+
+static ssize_t xen_feature_show(int index, char *buffer)
+{
+ ssize_t ret;
+ struct xen_feature_info info;
+
+ info.submap_idx = index;
+ ret = HYPERVISOR_xen_version(XENVER_get_features, &info);
+ if (!ret)
+ ret = sprintf(buffer, "%08x", info.submap);
+
+ return ret;
+}
+
+static ssize_t features_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ ssize_t len;
+ int i;
+
+ len = 0;
+ for (i = XENFEAT_NR_SUBMAPS-1; i >= 0; i--) {
+ int ret = xen_feature_show(i, buffer + len);
+ if (ret < 0) {
+ if (len == 0)
+ len = ret;
+ break;
+ }
+ len += ret;
+ }
+ if (len > 0)
+ buffer[len++] = '\n';
+
+ return len;
+}
+
+HYPERVISOR_ATTR_RO(features);
+
+static struct attribute *xen_properties_attrs[] = {
+ &capabilities_attr.attr,
+ &changeset_attr.attr,
+ &virtual_start_attr.attr,
+ &pagesize_attr.attr,
+ &features_attr.attr,
+ NULL
+};
+
+static struct attribute_group xen_properties_group = {
+ .name = "properties",
+ .attrs = xen_properties_attrs,
+};
+
+static int __init xen_properties_init(void)
+{
+ return sysfs_create_group(hypervisor_kobj, &xen_properties_group);
+}
+
+static void xen_properties_destroy(void)
+{
+ sysfs_remove_group(hypervisor_kobj, &xen_properties_group);
+}
+
+static int __init hyper_sysfs_init(void)
+{
+ int ret;
+
+ if (!xen_domain())
+ return -ENODEV;
+
+ ret = xen_sysfs_type_init();
+ if (ret)
+ goto out;
+ ret = xen_sysfs_version_init();
+ if (ret)
+ goto version_out;
+ ret = xen_compilation_init();
+ if (ret)
+ goto comp_out;
+ ret = xen_sysfs_uuid_init();
+ if (ret)
+ goto uuid_out;
+ ret = xen_properties_init();
+ if (ret)
+ goto prop_out;
+
+ goto out;
+
+prop_out:
+ xen_sysfs_uuid_destroy();
+uuid_out:
+ xen_compilation_destroy();
+comp_out:
+ xen_sysfs_version_destroy();
+version_out:
+ xen_sysfs_type_destroy();
+out:
+ return ret;
+}
+
+static void __exit hyper_sysfs_exit(void)
+{
+ xen_properties_destroy();
+ xen_compilation_destroy();
+ xen_sysfs_uuid_destroy();
+ xen_sysfs_version_destroy();
+ xen_sysfs_type_destroy();
+
+}
+module_init(hyper_sysfs_init);
+module_exit(hyper_sysfs_exit);
+
+static ssize_t hyp_sysfs_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buffer)
+{
+ struct hyp_sysfs_attr *hyp_attr;
+ hyp_attr = container_of(attr, struct hyp_sysfs_attr, attr);
+ if (hyp_attr->show)
+ return hyp_attr->show(hyp_attr, buffer);
+ return 0;
+}
+
+static ssize_t hyp_sysfs_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer,
+ size_t len)
+{
+ struct hyp_sysfs_attr *hyp_attr;
+ hyp_attr = container_of(attr, struct hyp_sysfs_attr, attr);
+ if (hyp_attr->store)
+ return hyp_attr->store(hyp_attr, buffer, len);
+ return 0;
+}
+
+static struct sysfs_ops hyp_sysfs_ops = {
+ .show = hyp_sysfs_show,
+ .store = hyp_sysfs_store,
+};
+
+static struct kobj_type hyp_sysfs_kobj_type = {
+ .sysfs_ops = &hyp_sysfs_ops,
+};
+
+static int __init hypervisor_subsys_init(void)
+{
+ if (!xen_domain())
+ return -ENODEV;
+
+ hypervisor_kobj->ktype = &hyp_sysfs_kobj_type;
+ return 0;
+}
+device_initcall(hypervisor_subsys_init);
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 773d1cf23283..d42e25d5968d 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -71,6 +71,9 @@ static int xenbus_probe_frontend(const char *type, const char *name);
static void xenbus_dev_shutdown(struct device *_dev);
+static int xenbus_dev_suspend(struct device *dev, pm_message_t state);
+static int xenbus_dev_resume(struct device *dev);
+
/* If something in array of ids matches this device, return it. */
static const struct xenbus_device_id *
match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev)
@@ -188,6 +191,9 @@ static struct xen_bus_type xenbus_frontend = {
.remove = xenbus_dev_remove,
.shutdown = xenbus_dev_shutdown,
.dev_attrs = xenbus_dev_attrs,
+
+ .suspend = xenbus_dev_suspend,
+ .resume = xenbus_dev_resume,
},
};
@@ -654,6 +660,7 @@ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus)
kfree(root);
}
+EXPORT_SYMBOL_GPL(xenbus_dev_changed);
static void frontend_changed(struct xenbus_watch *watch,
const char **vec, unsigned int len)
@@ -669,7 +676,7 @@ static struct xenbus_watch fe_watch = {
.callback = frontend_changed,
};
-static int suspend_dev(struct device *dev, void *data)
+static int xenbus_dev_suspend(struct device *dev, pm_message_t state)
{
int err = 0;
struct xenbus_driver *drv;
@@ -682,35 +689,14 @@ static int suspend_dev(struct device *dev, void *data)
drv = to_xenbus_driver(dev->driver);
xdev = container_of(dev, struct xenbus_device, dev);
if (drv->suspend)
- err = drv->suspend(xdev);
+ err = drv->suspend(xdev, state);
if (err)
printk(KERN_WARNING
"xenbus: suspend %s failed: %i\n", dev_name(dev), err);
return 0;
}
-static int suspend_cancel_dev(struct device *dev, void *data)
-{
- int err = 0;
- struct xenbus_driver *drv;
- struct xenbus_device *xdev;
-
- DPRINTK("");
-
- if (dev->driver == NULL)
- return 0;
- drv = to_xenbus_driver(dev->driver);
- xdev = container_of(dev, struct xenbus_device, dev);
- if (drv->suspend_cancel)
- err = drv->suspend_cancel(xdev);
- if (err)
- printk(KERN_WARNING
- "xenbus: suspend_cancel %s failed: %i\n",
- dev_name(dev), err);
- return 0;
-}
-
-static int resume_dev(struct device *dev, void *data)
+static int xenbus_dev_resume(struct device *dev)
{
int err;
struct xenbus_driver *drv;
@@ -755,33 +741,6 @@ static int resume_dev(struct device *dev, void *data)
return 0;
}
-void xenbus_suspend(void)
-{
- DPRINTK("");
-
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
- xenbus_backend_suspend(suspend_dev);
- xs_suspend();
-}
-EXPORT_SYMBOL_GPL(xenbus_suspend);
-
-void xenbus_resume(void)
-{
- xb_init_comms();
- xs_resume();
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
- xenbus_backend_resume(resume_dev);
-}
-EXPORT_SYMBOL_GPL(xenbus_resume);
-
-void xenbus_suspend_cancel(void)
-{
- xs_suspend_cancel();
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_cancel_dev);
- xenbus_backend_resume(suspend_cancel_dev);
-}
-EXPORT_SYMBOL_GPL(xenbus_suspend_cancel);
-
/* A flag to determine if xenstored is 'ready' (i.e. has started) */
int xenstored_ready = 0;
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index e325eab4724d..eab33f1dbdf7 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -673,6 +673,8 @@ void xs_resume(void)
struct xenbus_watch *watch;
char token[sizeof(watch) * 2 + 1];
+ xb_init_comms();
+
mutex_unlock(&xs_state.response_mutex);
mutex_unlock(&xs_state.request_mutex);
up_write(&xs_state.transaction_mutex);
diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c
index 515741a8e6b8..6559e0c752ce 100644
--- a/drivers/xen/xenfs/super.c
+++ b/drivers/xen/xenfs/super.c
@@ -20,10 +20,27 @@
MODULE_DESCRIPTION("Xen filesystem");
MODULE_LICENSE("GPL");
+static ssize_t capabilities_read(struct file *file, char __user *buf,
+ size_t size, loff_t *off)
+{
+ char *tmp = "";
+
+ if (xen_initial_domain())
+ tmp = "control_d\n";
+
+ return simple_read_from_buffer(buf, size, off, tmp, strlen(tmp));
+}
+
+static const struct file_operations capabilities_file_ops = {
+ .read = capabilities_read,
+};
+
static int xenfs_fill_super(struct super_block *sb, void *data, int silent)
{
static struct tree_descr xenfs_files[] = {
- [2] = {"xenbus", &xenbus_file_ops, S_IRUSR|S_IWUSR},
+ [1] = {},
+ { "xenbus", &xenbus_file_ops, S_IRUSR|S_IWUSR },
+ { "capabilities", &capabilities_file_ops, S_IRUGO },
{""},
};
diff --git a/firmware/Makefile b/firmware/Makefile
index 25200d106ee8..96c3dd8cc683 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -32,6 +32,7 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
adaptec/starfire_tx.bin
fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
+fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-4.8.53.0.fw bnx2x-e1h-4.8.53.0.fw
fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-4.6.17.fw \
bnx2/bnx2-rv2p-09-4.6.15.fw \
bnx2/bnx2-mips-06-4.6.16.fw \
@@ -47,6 +48,8 @@ fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
e100/d102e_ucode.bin
fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis
+fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
+fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis
fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
advansys/3550.bin advansys/38C0800.bin
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 4c52984a8319..bb8fda8f06b8 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -586,6 +586,26 @@ Originally developed by the pcmcia-cs project
--------------------------------------------------------------------------
+Driver: PCMCIA_3C589 - 3Com PCMCIA adapter
+
+File: cis/3CXEM556.cis
+
+Licence: GPL
+
+Originally developed by the pcmcia-cs project
+
+--------------------------------------------------------------------------
+
+Driver: PCMCIA_3C574 - 3Com PCMCIA adapter
+
+File: cis/3CCFEM556.cis
+
+Licence: GPL
+
+Originally developed by the pcmcia-cs project
+
+--------------------------------------------------------------------------
+
Driver: PCMCIA_SMC91C92 - SMC 91Cxx PCMCIA
File: ositech/Xilinx7OD.bin
@@ -618,6 +638,26 @@ Found in hex form in kernel source.
--------------------------------------------------------------------------
+Driver: bnx2x: Broadcom Everest
+
+File: bnx2x-e1-4.8.53.0.fw.ihex
+File: bnx2x-e1h-4.8.53.0.fw.ihex
+
+License:
+ Copyright (c) 2007-2009 Broadcom Corporation
+
+ This file contains firmware data derived from proprietary unpublished
+ source code, Copyright (c) 2007-2009 Broadcom Corporation.
+
+ Permission is hereby granted for the distribution of this firmware data
+ in hexadecimal or equivalent format, provided this copyright notice is
+ accompanying it.
+
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
+
Driver: BNX2 - Broadcom NetXtremeII
File: bnx2/bnx2-mips-06-4.6.16.fw
diff --git a/firmware/bnx2x-e1-4.8.53.0.fw.ihex b/firmware/bnx2x-e1-4.8.53.0.fw.ihex
new file mode 100644
index 000000000000..f1edb1e7ad1b
--- /dev/null
+++ b/firmware/bnx2x-e1-4.8.53.0.fw.ihex
@@ -0,0 +1,10364 @@
+:10000000000028600000006000000630000028C8E2
+:100010000000160800002F000000009400004510AA
+:10002000000073C8000045A8000000C40000B978B3
+:100030000000A4680000BA400000007400015EB037
+:100040000000559000015F28000000B80001B4C016
+:100050000000D1F80001B580000000040002878094
+:10006000020400480000000F020400540000004594
+:1000700002040058000000840204005C0000000636
+:100080000204007000000004020400780000000078
+:100090000204007C121700000204008022170000F6
+:1000A00002040084321700000604008800000005E6
+:1000B0000204009C12150000020400A0221500009A
+:1000C000020400A432150000060400A80000000489
+:1000D000020400B802100000020400BC001000007E
+:1000E000020400C010100000020400C42010000030
+:1000F000020400C830100000060400CC0000000418
+:10010000020400DC00100000020400E012140000F1
+:10011000020400E422140000020400E8321400008B
+:10012000060400EC000000040104012400000000AB
+:1001300001040128000000000104012C000000005F
+:10014000010401300000000002040004000000FF70
+:1001500002040008000000FF0204000C000000FF81
+:1001600002040010000000FF02040014000000FF61
+:1001700002040018000000FF0204001C000000FF41
+:1001800002040020000000FF020400240000003EE2
+:1001900002040028000000000204002C0000003FC0
+:1001A000020400300000003F020400340000003F61
+:1001B00002040038000000000204003C0000003F80
+:1001C000020400400000003F020400440000003F21
+:1001D00002042008000004110204200C00000400A6
+:1001E000020420100000040402042014000004197A
+:1001F0000204201C0000FFFF020420200000FFFF7B
+:10020000020420240000FFFF020420280000FFFF5A
+:1002100006042038000000020204204000000034E0
+:100220000204204400000035060420480000007C41
+:100230000204223807FFFFFF0204223C0000003FB7
+:100240000204224007FFFFFF020422440000000FC7
+:1002500001042248000000000104224C00000000BC
+:10026000010422500000000001042254000000009C
+:1002700001042258000000000104225C000000007C
+:10028000010422600000000001042264000000005C
+:1002900001042268000000000104226C000000003C
+:1002A000010422700000000001042274000000001C
+:1002B00001042278000000000104227C00000000FC
+:1002C000020424BC000000010C042000000003E82C
+:1002D0000A042000000000010B0420000000000AB6
+:1002E0000205004400000020020500480000003222
+:1002F000020500900215002002050094021500205E
+:1003000002050098000000300205009C0810000063
+:10031000020500A000000033020500A40000003028
+:10032000020500A800000031020500AC0000000238
+:10033000020500B000000005020500B40000000640
+:10034000020500B800000002020500BC0000000227
+:10035000020500C000000000020500C40000000506
+:10036000020500C800000002020500CC00000002E7
+:10037000020500D000000002020500D400000001C8
+:1003800002050114000000010205011C000000012B
+:100390000205012000000002020502040000000125
+:1003A0000205020C0000004002050210000000409F
+:1003B0000205021C000000200205022000000013BC
+:1003C0000205022400000020060502400000000A89
+:1003D0000405028000200000020500500000000714
+:1003E0000205005400000007020500580000000844
+:1003F0000205005C00000008060500600000000423
+:10040000020500D800000006020500E00000000D13
+:10041000020500E40000002D020500E800000007CE
+:10042000020500EC00000027020500F000000007B4
+:10043000020500F400000027020500F80000000794
+:10044000020500FC00000027020500040000000176
+:1004500002050008000000010205000C0000000178
+:100460000205001000000001020500140000000158
+:1004700002050018000000010205001C0000000138
+:100480000205002000000001020500240000000118
+:1004900002050028000000010205002C00000001F8
+:1004A00002050030000000010205003400000001D8
+:1004B00002050038000000010205003C00000001B8
+:1004C00002050040000000010406100002000020A8
+:1004D000020600DC00000001010600D80000000058
+:1004E0000406020000030220020600DC00000000F7
+:1004F00002060068000000B802060078000001143F
+:10050000010600B800000000010600C8000000005D
+:100510000206006C000000B80206007C0000011416
+:10052000010600BC00000000010600CC0000000035
+:100530000718040000930000081807600014022345
+:10054000071C0000324F0000071C800033250C946C
+:10055000071D00000E4D195E081D1E005C4002259F
+:100560000118000000000000011800040000000055
+:1005700001180008000000000118000C0000000035
+:100580000118001000000000011800140000000015
+:1005900002180020000000010218002400000002E0
+:1005A00002180028000000030218002C00000000C0
+:1005B000021800300000000402180034000000019E
+:1005C00002180038000000000218003C0000000182
+:1005D000021800400000000402180044000000005F
+:1005E00002180048000000010218004C000000033F
+:1005F0000218005000000000021800540000000122
+:1006000002180058000000040218005C00000000FE
+:1006100002180060000000010218006400000003DE
+:1006200002180068000000000218006C00000001C1
+:10063000021800700000000402180074000000009E
+:1006400002180078000000040218007C000000037B
+:100650000618008000000002021800A400003FFFFE
+:10066000021800A8000003FF021802240000000086
+:1006700002180234000000000218024C00000000C2
+:10068000021802E4000000FF061810000000040039
+:10069000021B8BC000000001021B80000000003420
+:1006A000021B804000000018021B80800000000C2C
+:1006B000021B80C0000000200C1B83000007A1204B
+:1006C0000A1B8300000001380B1B83000000138805
+:1006D000021B83C0000001F4061A2000000000B2D3
+:1006E000061A23C8000000C1041A26CC0001022704
+:1006F000061A1020000000C8061A100000000002B0
+:10070000061A1C1800000004061A1C100000000243
+:10071000061A080000000002061A0808000000027D
+:10072000061A081000000004041A1FB00004022872
+:10073000041A4CB00008022C061A22C8000000203F
+:10074000061A40000000016C021A4B600000000015
+:10075000061A14000000000A061A145000000006D1
+:10076000061A150000000002041A150800050234DC
+:10077000061A151C00000007061A1570000000126A
+:10078000061A09C00000004C061A0800000000020A
+:10079000061A08200000000E041A1FB000020239D9
+:1007A000061A290800000002061A2348000000204B
+:1007B000061A45B00000016C021A4B6400000000EC
+:1007C000061A14280000000A061A14680000000621
+:1007D000061A153800000002041A15400005023BF5
+:1007E000061A155400000007061A15B8000000127A
+:1007F000061A0AF00000004C061A08080000000261
+:10080000061A08580000000E041A1FB80002024021
+:10081000061A2910000000020200A2800000000158
+:100820000200A294071D29110200A29800000000F6
+:100830000200A29C009C04240200A2A00000000070
+:100840000200A2A4000002090200A4FCFF000000B4
+:10085000020100B400000001020100B80000000124
+:10086000020100DC000000010201010000000001A3
+:1008700002010104000000010201007C00300000C0
+:1008800002010084000000280201008C000000002A
+:1008900002010130000000040201025C00000001BE
+:1008A000020103280000000002010554000000308E
+:1008B000020100C400000001020100CC00000001A0
+:1008C000020100F800000001020100F00000000138
+:1008D00002010080003000000201008800000028B2
+:1008E0000201009000000000020101340000000439
+:1008F000020102DC000000010201032C00000000E4
+:100900000201056400000030020100C8000000017F
+:10091000020100D000000001020100FC0000000103
+:10092000020100F400000001020C10000000002091
+:10093000020C200800000A11020C200C00000A0022
+:10094000020C201000000A04020C201C0000FFFF13
+:10095000020C20200000FFFF020C20240000FFFFFB
+:10096000020C20280000FFFF020C2038000000C607
+:10097000020C203C00000000020C2040000000346B
+:10098000020C204400000035060C20480000001C2A
+:10099000020C20B800000001060C20BC0000005F23
+:1009A000020C223807FFFFFF020C223C0000003F30
+:1009B000020C224007FFFFFF020C22440000000F40
+:1009C000010C224800000000010C224C0000000035
+:1009D000010C225000000000010C22540000000015
+:1009E000010C225800000000010C225C00000000F5
+:1009F000010C226000000000010C226400000000D5
+:100A0000010C226800000000010C226C00000000B4
+:100A1000010C227000000000010C22740000000094
+:100A2000010C227800000000010C227C0000000074
+:100A3000020C24BC000000010C0C2000000003E8A4
+:100A40000A0C2000000000010B0C20000000000A2E
+:100A5000020C400800000A11020C400C00000A00C1
+:100A6000020C401000000A04020C401400000A218D
+:100A7000020C401C0000FFFF020C40200000FFFFA2
+:100A8000020C40240000FFFF020C40280000FFFF82
+:100A9000020C403800000046020C403C00000005FB
+:100AA000020C404000000034020C404400000035BD
+:100AB000060C40480000005C020C41B80000000138
+:100AC000060C41BC0000001F020C423807FFFFFF6C
+:100AD000020C423C0000003F020C424007FFFFFFB7
+:100AE000020C42440000000F010C424800000000CC
+:100AF000010C424C00000000010C425000000000BC
+:100B0000010C425400000000010C4258000000009B
+:100B1000010C425C00000000010C4260000000007B
+:100B2000010C426400000000010C4268000000005B
+:100B3000010C426C00000000010C4270000000003B
+:100B4000010C427400000000010C4278000000001B
+:100B5000010C427C00000000010C428000000000FB
+:100B6000020C44C0000000010C0C4000000003E82F
+:100B70000A0C4000000000010B0C40000000000ABD
+:100B8000020D004400000032020D008C021500200E
+:100B9000020D009002150020020D009408100000C4
+:100BA000020D009800000033020D009C00000002BE
+:100BB000020D00A000000000020D00A400000005CE
+:100BC000020D00A800000005060D00AC00000002A8
+:100BD000020D00B400000002020D00B80000000386
+:100BE000020D00BC00000002020D00C00000000168
+:100BF000020D00C800000002020D00CC000000023F
+:100C0000020D010800000001020D015C000000015E
+:100C1000020D016400000001020D016800000002E5
+:100C2000020D020400000001020D020C0000002071
+:100C3000020D021000000040020D021400000040EE
+:100C4000020D022000000003020D02240000001823
+:100C5000060D028000000012040D03000024024271
+:100C6000020D004C00000001020D005000000002C7
+:100C7000020D005400000008020D0058000000089A
+:100C8000060D005C00000004020D00C4000000041A
+:100C9000020D011400000009020D011800000029D6
+:100CA000020D011C0000000A020D01200000002AB4
+:100CB000020D012400000007020D0128000000279A
+:100CC000020D012C00000007020D0130000000277A
+:100CD000020D01340000000C020D01380000002C50
+:100CE000020D013C0000000C020D01400000002C30
+:100CF000020D01440000000C020D01480000002C10
+:100D0000020D000400000001020D000800000001B7
+:100D1000020D000C00000001020D00100000000197
+:100D2000020D001400000001020D00180000000177
+:100D3000020D001C00000001020D00200000000157
+:100D4000020D002400000001020D00280000000137
+:100D5000020D002C00000001020D00300000000117
+:100D6000020D003400000001020D003800000001F7
+:100D7000020D003C00000001020E004C0000003299
+:100D8000020E009402150020020E009802150020A9
+:100D9000020E009C00000030020E00A008100000AF
+:100DA000020E00A400000033020E00A80000003074
+:100DB000020E00AC00000031020E00B00000000284
+:100DC000020E00B400000004020E00B80000000093
+:100DD000020E00BC00000002020E00C00000000273
+:100DE000020E00C400000000020E00C80000000255
+:100DF000020E00CC00000007020E00D0000000022E
+:100E0000020E00D400000002020E00D80000000113
+:100E1000020E00E400000001020E01440000000187
+:100E2000020E014C00000001020E01500000000201
+:100E3000020E020400000001020E020C000000403D
+:100E4000020E021000000040020E021C000000040E
+:100E5000020E022000000020020E02240000000EFC
+:100E6000020E02280000001B060E03000000001204
+:100E7000040E0280001B0266020E005400000010E7
+:100E8000020E005800000007020E005C0000000F78
+:100E9000020E006000000010060E00640000000456
+:100EA000020E00DC00000003020E01100000000F23
+:100EB000020E01140000002F020E01180000000EA7
+:100EC000020E011C0000002E020E000400000001B2
+:100ED000020E000800000001020E000C00000001DC
+:100EE000020E001000000001020E001400000001BC
+:100EF000020E001800000001020E001C000000019C
+:100F0000020E002000000001020E0024000000017B
+:100F1000020E002800000001020E002C000000015B
+:100F2000020E003000000001020E0034000000013B
+:100F3000020E003800000001020E003C000000011B
+:100F4000020E004000000001020E004400000001FB
+:100F50000730040000C30000083007680013028156
+:100F600007340000314C00000734800035EF0C548A
+:100F700007350000361319D00735800007112755B3
+:100F800008358EE04E24028301300000000000008E
+:100F900001300004000000000130000800000000E3
+:100FA0000130000C000000000130001000000000C3
+:100FB0000130001400000000023000200000000199
+:100FC000023000240000000202300028000000036C
+:100FD0000230002C0000000002300030000000044D
+:100FE0000230003400000001023000380000000030
+:100FF0000230003C0000000102300040000000040C
+:1010000002300044000000000230004800000001EF
+:101010000230004C000000030230005000000000CD
+:1010200002300054000000010230005800000004AB
+:101030000230005C0000000002300060000000018F
+:10104000023000640000000302300068000000006D
+:101050000230006C0000000102300070000000044B
+:10106000023000740000000002300078000000042C
+:101070000230007C00000003063000800000000207
+:10108000023000A400003FFF023000A8000003FF70
+:101090000230022400000000023002340000000090
+:1010A0000230024C00000000023002E40000FFFFAA
+:1010B000063020000000080002338BC00000000151
+:1010C000023380000000001A023380400000004E0E
+:1010D0000233808000000010023380C00000002036
+:1010E0000C3383000007A1200A338300000001387D
+:1010F0000B33830000001388023383C0000001F427
+:101100000C3383801DCD65000A3383800004C4B492
+:101110000B338380004C4B4006325000000000C26D
+:1011200006321020000000C8063210000000000245
+:101130000632464000000040063257F0000000042E
+:10114000063257D800000005043257EC0001028532
+:1011500006321C60000000200432283000020286A3
+:10116000023308000100000004330C000010028864
+:10117000023308000000000004330C400010029805
+:1011800006321400000000A0063219000000001012
+:10119000063219800000003006324740000000B4DB
+:1011A00002321D900000000006321B4000000004C7
+:1011B00006321B6000000020063253180000009821
+:1011C00006321680000000A0063219400000001010
+:1011D00006321A400000003006324A10000000B407
+:1011E00002321D940000000006321B500000000473
+:1011F00006321BE0000000200632557800000098FF
+:10120000072004000071000008200780001002A8D9
+:1012100007240000322900000724800023630C8B80
+:101220000824C930654002AA012000000000000027
+:101230000120000400000000012000080000000060
+:101240000120000C00000000012000100000000040
+:101250000120001400000000022000200000000116
+:1012600002200024000000020220002800000003E9
+:101270000220002C000000000220003000000004CA
+:1012800002200034000000010220003800000000AD
+:101290000220003C00000001022000400000000489
+:1012A000022000440000000002200048000000016D
+:1012B0000220004C0000000302200050000000004B
+:1012C0000220005400000001022000580000000429
+:1012D0000220005C0000000002200060000000010D
+:1012E00002200064000000030220006800000000EB
+:1012F0000220006C000000010220007000000004C9
+:1013000002200074000000000220007800000004A9
+:101310000220007C00000003062000800000000284
+:10132000022000A400003FFF022000A8000003FFED
+:10133000022002240000000002200234000000000D
+:101340000220024C00000000022002E40000FFFF27
+:10135000062020000000080002238BC000000001CE
+:1013600002238000000000100223804000000012D1
+:101370000223808000000030022380C00000000EA5
+:10138000022383C0000001F4062250000000004246
+:1013900006221020000000C80622100000000002F3
+:1013A00006222000000000C00622307000000080ED
+:1013B0000622428000000004062225C000000240F0
+:1013C00004222EC8000802AC02230800013FFFFFE0
+:1013D00004230C00001002B40223080000000000E7
+:1013E00004230C40001002C406221400000000A0D8
+:1013F00006221900000000100622198000000030AB
+:101400000222511800000000062223000000000EF6
+:1014100006223040000000060622241000000030A2
+:1014200006221680000000A00622194000000010CD
+:1014300006221A40000000300222511C0000000069
+:10144000062223380000000E062230580000000655
+:10145000062224D0000000300216100000000020F8
+:1014600002170008000000020217002C0000000311
+:101470000217003C000000040217004400000008AE
+:1014800002170048000000020217004C0000009004
+:1014900002170050000000900217005400800090D6
+:1014A0000217005808140000021700600000008AAC
+:1014B000021700640000008002170068000000901E
+:1014C0000217006C00000080021700700000000688
+:1014D00002170078000007D00217007C0000076C9C
+:1014E00002170038007C1004021700040000000FEF
+:1014F0000616402400000002021640700000001C86
+:10150000021642080000000102164210000000010D
+:1015100002164220000000010216422800000001CD
+:10152000021642300000000102164238000000019D
+:1015300002164260000000010C16401C0003D0900F
+:101540000A16401C0000009C0B16401C000009C439
+:101550000216403000000008021640340000000C63
+:10156000021640380000001002164044000000201F
+:101570000216400000000001021640D800000001E1
+:1015800002164008000000010216400C0000000195
+:101590000216401000000001021642400000000048
+:1015A00002164248000000000616427000000002C9
+:1015B00002164250000000000216425800000000CF
+:1015C00006164280000000020216600800000614A1
+:1015D0000216600C000006000216601000000604EF
+:1015E0000216601C0000FFFF021660200000FFFFD3
+:1015F000021660240000FFFF021660280000FFFFB3
+:1016000002166038000000200216603C0000002036
+:1016100002166040000000340216604400000035ED
+:1016200002166048000000230216604C00000024EF
+:1016300002166050000000250216605400000026CB
+:1016400002166058000000270216605C00000029A6
+:10165000021660600000002A021660640000002B81
+:10166000021660680000002C0216606C0000002D5D
+:101670000616607000000052021661B800000001FA
+:10168000061661BC0000001F0216623807FFFFFF4C
+:101690000216623C0000003F0216624007FFFFFF97
+:1016A000021662440000000F0116624800000000AC
+:1016B0000116624C0000000001166250000000009C
+:1016C000011662540000000001166258000000007C
+:1016D0000116625C0000000001166260000000005C
+:1016E000011662640000000001166268000000003C
+:1016F0000116626C0000000001166270000000001C
+:1017000001166274000000000116627800000000FB
+:101710000116627C00000000021664BC000000019B
+:101720000C166000000003E80A16600000000001CB
+:101730000B1660000000000A021680400000000640
+:101740000216804400000005021680480000000ACE
+:101750000216804C000000050216805400000002B2
+:10176000021680CC00000004021680D000000004A5
+:10177000021680D400000004021680D80000000485
+:10178000021680DC00000004021680E00000000465
+:10179000021680E400000004021680E80000000445
+:1017A0000216880400000004021680300000007C4D
+:1017B000021680340000003D021680380000003F11
+:1017C0000216803C0000009C021680F0000000071A
+:1017D000061680F4000000050216880C01010101C4
+:1017E00002168108000000000216810C00000004AF
+:1017F000021681100000000402168114000000028D
+:101800000216881008012004021681180000000545
+:101810000216811C00000005021681200000000550
+:1018200002168124000000050216882C20081001F1
+:1018300002168128000000080216812C0000000614
+:1018400002168130000000070216813400000000FB
+:1018500002168830010101200616813800000004BC
+:1018600002168834010101010616814800000004B7
+:101870000216883801010101061681580000000493
+:101880000216883C01010101061681680000000370
+:101890000216817400000001021688400101010156
+:1018A00002168178000000010216817C0000000110
+:1018B00002168180000000010216818400000001F0
+:1018C000021688440101010102168188000000010E
+:1018D0000216818C000000040216819000000004B2
+:1018E00002168194000000020216884808012004B4
+:1018F00002168198000000050216819C0000000578
+:10190000021681A000000005021681A40000000557
+:101910000216881420081001021681A80000000891
+:10192000021681AC00000006021681B0000000071C
+:10193000021681B40000000102168818010101207E
+:10194000021681B800000001021681BC00000001EF
+:10195000021681C000000001021681C400000001CF
+:101960000216881C01010101021681C80000000155
+:10197000021681CC00000001021681D00000000197
+:10198000021681D400000001021688200101010125
+:10199000021681D800000001021681DC000000015F
+:1019A000021681E000000001021681E4000000013F
+:1019B0000216882401010101021681E800000001DD
+:1019C000021681EC00000001021681F00000000107
+:1019D000021688280101010102168240FFFF003F24
+:1019E00006168244000000020216824CFFFF003FF0
+:1019F000021682500000010002168254000001000D
+:101A0000061682580000000202168260000000C024
+:101A100002168264000000C00216826800001E00E8
+:101A20000216826C00001E00021682700000400048
+:101A300002168274000040000216827800008000C6
+:101A40000216827C000080000216828000002000C6
+:101A5000021682840000200006168288000000071B
+:101A6000021682A400000001061682A80000000AE7
+:101A7000021681F400000C08021681F800000040F4
+:101A8000021681FC00000100021682000000002006
+:101A9000021682040000001702168208000000806F
+:101AA0000216820C000002000216821000000000E4
+:101AB00002168218FFFF01FF02168214FFFF01FFCA
+:101AC0000216823C00000013021680900000013FC5
+:101AD0000216806000000140021680640000014090
+:101AE000061680680000000202168070000000C028
+:101AF00006168074000000070216809C0000004853
+:101B0000021680A000000048061680A40000000213
+:101B1000021680AC00000048061680B000000007E6
+:101B2000021682380000800002168234000025E48C
+:101B30000216809400007FFF02168220000000073A
+:101B40000216821C00000007021682280000000016
+:101B500002168224FFFFFFFF021682300000000001
+:101B60000216822CFFFFFFFF021680EC000000FF30
+:101B700002140000000000010214000C000000012B
+:101B800002140040000000010214004400007FFF26
+:101B90000214000C0000000002140000000000000D
+:101BA0000214006C00000000021400040000000198
+:101BB00002140030000000010214000400000000C4
+:101BC0000214005C00000000021400080000000184
+:101BD000021400340000000102140008000000009C
+:101BE00002140060000000000202005800000032F1
+:101BF000020200A003150020020200A40315002029
+:101C0000020200A801000030020200AC081000002F
+:101C1000020200B000000033020200B400000030F5
+:101C2000020200B800000031020200BC0000000304
+:101C3000020200C000000006020200C4000000030F
+:101C4000020200C800000003020200CC00000002F3
+:101C5000020200D000000000020200D400000002D6
+:101C6000020200DC00000000020200E000000006AA
+:101C7000020200E400000004020200E8000000028A
+:101C8000020200EC00000002020200F0000000016D
+:101C9000020200FC00000006020201200000000019
+:101CA0000202013400000002020201B00000000143
+:101CB0000202020C000000010202021400000001F6
+:101CC00002020218000000020202040400000001E7
+:101CD0000202040C00000040020204100000004058
+:101CE0000202041C00000004020204200000002084
+:101CF0000202042400000002020204280000001F67
+:101D0000060205000000001204020480001F02D435
+:101D1000020200600000000F0202006400000007E1
+:101D2000020200680000000B0202006C0000000EBE
+:101D30000602007000000004020200F4000000042B
+:101D4000020200040000000102020008000000017D
+:101D50000202000C0000000102020010000000015D
+:101D6000020200140000000102020018000000013D
+:101D70000202001C0000000102020020000000011D
+:101D800002020024000000010202002800000001FD
+:101D90000202002C000000010202003000000001DD
+:101DA00002020034000000010202003800000001BD
+:101DB0000202003C0000000102020040000000019D
+:101DC000020200440000000102020048000000017D
+:101DD0000202004C0000000102020050000000015D
+:101DE00002020108000000C80202011800000002FF
+:101DF000020201C400000000020201CC0000000049
+:101E0000020201D400000002020201DC0000000214
+:101E1000020201E4000000FF020201EC000000FFEA
+:101E20000202010C000000C80202011C00000002B6
+:101E3000020201C800000000020201D00000000000
+:101E4000020201D800000002020201E000000002CC
+:101E5000020201E8000000FF020201F0000000FFA2
+:101E60000728040000B5000008280768001302F3E3
+:101E7000072C000033660000072C800038B30CDA12
+:101E8000072D00003BB11B07072D80002A2629F4EF
+:101E9000082DD6C0452802F50128000000000000EA
+:101EA00001280004000000000128000800000000D4
+:101EB0000128000C000000000128001000000000B4
+:101EC000012800140000000002280020000000018A
+:101ED000022800240000000202280028000000035D
+:101EE0000228002C0000000002280030000000043E
+:101EF0000228003400000001022800380000000021
+:101F00000228003C000000010228004000000004FC
+:101F100002280044000000000228004800000001E0
+:101F20000228004C000000030228005000000000BE
+:101F3000022800540000000102280058000000049C
+:101F40000228005C00000000022800600000000180
+:101F5000022800640000000302280068000000005E
+:101F60000228006C0000000102280070000000043C
+:101F7000022800740000000002280078000000041D
+:101F80000228007C000000030628008000000002F8
+:101F9000022800A400003FFF022800A8000003FF61
+:101FA0000228022400000000022802340000000081
+:101FB0000228024C00000000022802E40000FFFF9B
+:101FC0000628200000000800022B8BC00000000142
+:101FD000022B800000000000022B8040000000184F
+:101FE000022B80800000000C022B80C000000066E5
+:101FF0000C2B83000007A1200A2B8300000001386E
+:102000000B2B830000001388022B83C0000001F417
+:102010000C2B8340000001F40A2B834000000000D9
+:102020000B2B8340000000050A2B83800004C4B4FE
+:102030000C2B83801DCD65000B2B8380004C4B4007
+:10204000062A3D6000000004042A3D70000202F7E9
+:10205000062A300000000048062A1020000000C8B0
+:10206000062A100000000002062A31280000008E17
+:10207000022A336800000000042A3370000202F9CB
+:10208000042A3B90000402FB042A3E20000202FFC7
+:10209000022A151800000001022A18300000000072
+:1020A000022A183800000000042A18200002030148
+:1020B000062A4AC000000002062A4B000000000465
+:1020C000042A1F4800020303022B0800000000003E
+:1020D000042B0C0000100305022B08000100000077
+:1020E000042B0C4000080315022B0800020000001E
+:1020F000042B0C600008031D062A3BA000000014FE
+:10210000062A3C4000000024062A14000000000AB1
+:10211000062A145000000006062A3378000000FC4E
+:10212000022A3B5800000000042A3D7800020325E3
+:10213000042A3D8800100327022A15000000000031
+:10214000022A150800000001062A502000000002A3
+:10215000062A503000000002062A5000000000024B
+:10216000062A501000000002022A50400000000021
+:10217000062A50480000000E022A50B80000000154
+:10218000042A4AC800020337062A4B100000004206
+:10219000062A4D2000000004062A3BF0000000142F
+:1021A000062A3CD000000024062A14280000000A59
+:1021B000062A146800000006062A3768000000FCA2
+:1021C000022A3B5C00000000042A3D800002033923
+:1021D000042A3DC80010033B022A15040000000039
+:1021E000022A150C00000001062A502800000002F7
+:1021F000062A503800000002062A5008000000029B
+:10220000062A501800000002022A50440000000074
+:10221000062A50800000000E022A50BC0000000177
+:10222000042A4AD00002034B062A4C180000004240
+:10223000062A4D30000000040210100800000001C2
+:10224000021010000003D000021010040000003D36
+:10225000091018000200034D091011000020054D5F
+:102260000610118000000002091011880006056D9B
+:10227000061011A00000001806102400000000E065
+:102280000210201C000000000210202000000001AD
+:10229000021020C000000001021020040000000114
+:1022A000021020080000000109103C000005057321
+:1022B00009103C2000050578091038000005057D4F
+:1022C00002104028000000100210404400003FFFB0
+:1022D0000210405800280000021040840084924AF6
+:1022E0000210405800000000061080680000000442
+:1022F00002108000000010800610802800000002FC
+:102300000210803800000010021080400000FFFF23
+:10231000021080440000FFFF021080500000000007
+:102320000210810000000000061081200000000261
+:1023300002108008000002B50210801000000000AA
+:10234000061082000000004A021081080001FFFF11
+:1023500006108140000000020210800000001A8078
+:102360000610900000000024061091200000004A92
+:10237000061093700000004A061095C00000004A45
+:10238000021080040000108006108030000000025F
+:102390000210803C00000010021080480000FFFF87
+:1023A0000210804C0000FFFF02108054000000006B
+:1023B00002108104000000000610812800000002C5
+:1023C0000210800C000002B5021080140000000012
+:1023D000061084000000004A0210810C0001FFFF7B
+:1023E00006108148000000020210800400001A80DC
+:1023F0000610909000000024061092480000004A49
+:10240000061094980000004A061096E80000004A62
+:102410000212049000E383400212051400003C10F5
+:1024200002120494FFFFFFFF02120498FFFFFFFF58
+:102430000212049CFFFFFFFF021204A0FFFFFFFF38
+:10244000021204A4FFFFFFFF021204A8FFFFFFFF18
+:10245000021204ACFFFFFFFF021204B0FFFFFFFFF8
+:10246000021204B8FFFFFFFF021204BCFFFFFFFFD0
+:10247000021204C0FFFFFFFF021204C4FFFFFFFFB0
+:10248000021204C8FFFFFFFF021204CCFFFFFFFF90
+:10249000021204D0FFFFFFFF021204DCFFFFFFFF68
+:1024A000021204E0FFFFFFFF021204E4FFFFFFFF40
+:1024B000021204E8FFFFFFFF021204ECFFFFFFFF20
+:1024C000021204F0FFFFFFFF021204F4FFFFFFFF00
+:1024D000021204F8FFFFFFFF021204FCFFFFFFFFE0
+:1024E00002120500FFFFFFFF02120504FFFFFFFFBE
+:1024F00002120508FFFFFFFF0212050CFFFFFFFF9E
+:1025000002120510FFFFFFFF021204D4FFFF333059
+:10251000021204D8FFFF3340021204B4F00030006E
+:1025200002120390000000080212039C0000000841
+:10253000021203A000000008021203A4000000021F
+:10254000021203BC00000004021203C000000005D8
+:10255000021203C400000004021203D000000000B5
+:102560000212036C00000001021203680000003F29
+:10257000021201BC00000040021201C00000180855
+:10258000021201C400000803021201C8000008037F
+:10259000021201CC00000040021201D00000000332
+:1025A000021201D400000803021201D8000008033F
+:1025B000021201DC00000803021201E00001000326
+:1025C000021201E400000803021201E800000803FF
+:1025D000021201EC00000003021201F000000003EF
+:1025E000021201F400000003021201F800000003CF
+:1025F000021201FC000000030212020000000003AE
+:10260000021202040000000302120208000000038C
+:102610000212020C0000000302120210000000036C
+:10262000021202140000000302120218000000034C
+:102630000212021C0000000302120220000000032C
+:1026400002120224000000030212022800002403E8
+:102650000212022C0000002F0212023000000009BA
+:102660000212023400000019021202380000018434
+:102670000212023C00000183021202400000030625
+:102680000212024400000019021202480000000673
+:102690000212024C00000306021202500000030660
+:1026A00002120254000003060212025800000C86B7
+:1026B0000212025C00000306021202600000030620
+:1026C0000212026400000006021202680000000606
+:1026D0000212026C000000060212027000000006E6
+:1026E00002120274000000060212027800000006C6
+:1026F0000212027C000000060212028000000006A6
+:102700000212028400000006021202880000000685
+:102710000212028C00000006021202900000000665
+:102720000212029400000006021202980000000645
+:102730000212029C00000006021202A00000030622
+:10274000021202A400000013021202A800000006F8
+:10275000021202B000001004021202B400001004C1
+:102760000212032400106440021203280010644087
+:10277000021201B0000000010600A00000000016D7
+:102780000200A06CBF5C00000200A070FFF51FEF0C
+:102790000200A0740000FFFF0200A078500003E0D8
+:1027A0000200A07C000000000200A0800000A00049
+:1027B0000600A084000000050200A0980FE00000C1
+:1027C0000600A09C000000140200A0EC555400007C
+:1027D0000200A0F0555555550200A0F400005555D3
+:1027E0000200A0F8000000000200A0FC5554000008
+:1027F0000200A100555555550200A1040000555591
+:102800000200A108000000000200A22C000000004D
+:102810000600A230000000030200A06000000007D4
+:102820000200A10CBF5C00000200A110FFF51FEF29
+:102830000200A1140000FFFF0200A118500003E0F5
+:102840000200A11C000000000200A1200000A00066
+:102850000600A124000000050200A1380FE00000DE
+:102860000600A13C000000140200A18C5554000099
+:102870000200A190555555550200A19400005555F0
+:102880000200A198000000000200A19C5554000025
+:102890000200A1A0555555550200A1A400005555B0
+:1028A0000200A1A8000000000200A23C00000000FD
+:1028B0000600A240000000030200A0640000000720
+:1028C00000000000000000000000002E00000000DA
+:1028D00000000000000000000000000000000000F8
+:1028E00000000000000000000000000000000000E8
+:1028F00000000000000000000000000000000000D8
+:1029000000000000000000000000000000000000C7
+:1029100000000000000000000000000000000000B7
+:10292000002E005000000000000000000000000029
+:102930000000000000000000000000000000000097
+:102940000000000000000000000000000050008DAA
+:102950000000000000000000000000000000000077
+:102960000000000000000000000000000000000067
+:102970000000000000000000008D00920092009610
+:102980000096009A00000000000000000000000017
+:102990000000000000000000000000000000000037
+:1029A00000000000009A00DB00DB00E900E900F70E
+:1029B0000000000000000000000000000000000017
+:1029C0000000000000000000000000000000000007
+:1029D00000000000000000000000000000000000F7
+:1029E00000000000000000000000000000000000E7
+:1029F00000000000000000000000000000000000D7
+:102A000000000000000000000000000000000000C6
+:102A100000000000000000000000000000000000B6
+:102A200000000000000000000000000000000000A6
+:102A30000000000000000000000000000000000096
+:102A40000000000000000000000000000000000086
+:102A50000000000000000000000000000000000076
+:102A60000000000000000000000000000000000066
+:102A70000000000000000000000000000000000056
+:102A800000F700FE00000000000000000000000051
+:102A90000000000000000000000000000000000036
+:102AA0000000000000000000000000000000000026
+:102AB0000000000000000000000000000000000016
+:102AC0000000000000000000000000000000000006
+:102AD000000000000000000000FE01030103010EE1
+:102AE000010E0119000000000000000000000000BD
+:102AF00000000000000000000000000000000000D6
+:102B000000000000000000000000000000000000C5
+:102B100000000000000000000000000000000000B5
+:102B200000000000000000000000000000000000A5
+:102B30000119011A00000000000000000000000060
+:102B40000000000000000000000000000000000085
+:102B5000000000000000000000000000011A013E1B
+:102B60000000000000000000000000000000000065
+:102B70000000000000000000000000000000000055
+:102B80000000000000000000013E016400000000A1
+:102B90000000000000000000000000000000000035
+:102BA0000000000000000000000000000000000025
+:102BB00000000000016401A300000000000000000C
+:102BC0000000000000000000000000000000000005
+:102BD00000000000000000000000000000000000F5
+:102BE00001A301DE00000000000000000000000062
+:102BF00000000000000000000000000000000000D5
+:102C000000000000000000000000000001DE0224BF
+:102C10000224022C022C02340000000000000000FC
+:102C200000000000000000000000000000000000A4
+:102C300000000000000000000234027102710278FE
+:102C40000278027F00000000000000000000000089
+:102C50000000000000000000000000000000000074
+:102C600000000000027F0280000000000000000061
+:102C70000000000000000000000000000000000054
+:102C80000000000000000000000000000000000044
+:102C9000028002920000000000000000000000001E
+:102CA0000000000000000000000000000000000024
+:102CB000000000000000000000000000029202A7D7
+:102CC00002A702AA02AA02AD000000000000000054
+:102CD00000000000000000000000000000000000F4
+:102CE000000000000000000002AD02DB0000000058
+:102CF00000000000000000000000000000000000D4
+:102D000000000000000000000000000000000000C3
+:102D10000000000002DB0362000000000000000071
+:102D200000000000000000000000000000000000A3
+:102D30000000000000000000000000000000000093
+:102D4000036203690369036D036D037100000000F2
+:102D50000000000000000000000000000000000073
+:102D6000000000000000000000000000037103B03C
+:102D700003B003B803B803C0000000000000000067
+:102D80000000000000000000000000000000000043
+:102D9000000000000000000003C004130413042717
+:102DA0000427043B000000000000000000000000B9
+:102DB0000000000000000000000000000000000013
+:102DC00000000000043B044300000000000000007D
+:102DD00000000000000000000000000000000000F3
+:102DE00000000000000000000000000000000000E3
+:102DF000044304490000000000000000000000003F
+:102E000000000000000000000000000000000000C2
+:102E10000000000000000000000000000449044C15
+:102E200000000000000000000000000000000000A2
+:102E30000000000000000000000000000000000092
+:102E40000000000000000000044C045100000000DD
+:102E50000000000000000000000000000000000072
+:102E60000000000000000000000000000000000062
+:102E70000000000004510452045204640464047607
+:102E80000000000000000000000000000000000042
+:102E90000000000000000000000000000000000032
+:102EA000047604E3000000000000000000000000C1
+:102EB0000000000000000000000000000000000012
+:102EC00000000000000000000000000004E304E433
+:102ED00004E404F804F8050C000000000000000001
+:102EE00000000000000000000000000000000000E2
+:102EF00000000000000000000000000000000000D2
+:102F000000010000000204C00003098000040E401C
+:102F100000051300000617C000071C8000082140B0
+:102F200000092600000A2AC0000B2F80000C344044
+:102F3000000D3900000E3DC0000F428000104740D8
+:102F400000114C00001250C00013558000145A406C
+:102F500000155F00001663C00017688000186D4000
+:102F600000197200001A76C0001B7B80001C804094
+:102F7000001D8500001E89C0001F8E800020934028
+:102F80000000200000004000000060000000800001
+:102F90000000A0000000C0000000E00000010000F0
+:102FA00000012000000140000001600000018000DD
+:102FB0000001A0000001C0000001E00000020000CC
+:102FC00000022000000240000002600000028000B9
+:102FD0000002A0000002C0000002E00000030000A8
+:102FE0000003200000034000000360000003800095
+:102FF0000003A0000003C0000003E0000004000084
+:103000000004200000044000000460000004800070
+:103010000004A0000004C0000004E000000500005F
+:10302000000520000005400000056000000580004C
+:103030000005A0000005C0000005E000000600003B
+:103040000006200000064000000660000006800028
+:103050000006A0000006C0000006E0000007000017
+:103060000007200000074000000760000007800004
+:103070000007A0000007C0000007E00000080000F3
+:1030800000082000000840000008600000088000E0
+:103090000008A0000008C0000008E00000090000CF
+:1030A00000092000000940000009600000098000BC
+:1030B0000009A0000009C0000009E000000A0000AB
+:1030C000000A2000000A4000000A6000000A800098
+:1030D000000AA000000AC000000AE000000B000087
+:1030E000000B2000000B4000000B6000000B800074
+:1030F000000BA000000BC000000BE000000C000063
+:10310000000C2000000C4000000C6000000C80004F
+:10311000000CA000000CC000000CE000000D00003E
+:10312000000D2000000D4000000D6000000D80002B
+:10313000000DA000000DC000000DE000000E00001A
+:10314000000E2000000E4000000E6000000E800007
+:10315000000EA000000EC000000EE000000F0000F6
+:10316000000F2000000F4000000F6000000F8000E3
+:10317000000FA000000FC000000FE00000100000D2
+:1031800000102000001040000010600000108000BF
+:103190000010A0000010C0000010E00000110000AE
+:1031A000001120000011400000116000001180009B
+:1031B0000011A0000011C0000011E000001200008A
+:1031C0000012200000124000001260000012800077
+:1031D0000012A0000012C0000012E0000013000066
+:1031E0000013200000134000001360000013800053
+:1031F0000013A0000013C0000013E0000014000042
+:10320000001420000014400000146000001480002E
+:103210000014A0000014C0000014E000001500001D
+:10322000001520000015400000156000001580000A
+:103230000015A0000015C0000015E00000160000F9
+:1032400000162000001640000016600000168000E6
+:103250000016A0000016C0000016E00000170000D5
+:1032600000172000001740000017600000178000C2
+:103270000017A0000017C0000017E00000180000B1
+:10328000001820000018400000186000001880009E
+:103290000018A0000018C0000018E000001900008D
+:1032A000001920000019400000196000001980007A
+:1032B0000019A0000019C0000019E000001A000069
+:1032C000001A2000001A4000001A6000001A800056
+:1032D000001AA000001AC000001AE000001B000045
+:1032E000001B2000001B4000001B6000001B800032
+:1032F000001BA000001BC000001BE000001C000021
+:10330000001C2000001C4000001C6000001C80000D
+:10331000001CA000001CC000001CE000001D0000FC
+:10332000001D2000001D4000001D6000001D8000E9
+:10333000001DA000001DC000001DE000001E0000D8
+:10334000001E2000001E4000001E6000001E8000C5
+:10335000001EA000001EC000001EE000001F0000B4
+:10336000001F2000001F4000001F6000001F8000A1
+:10337000001FA000001FC000001FE0000020000090
+:10338000002020000020400000206000002080007D
+:103390000020A0000020C0000020E000002100006C
+:1033A0000021200000214000002160000021800059
+:1033B0000021A0000021C0000021E0000022000048
+:1033C0000022200000224000002260000022800035
+:1033D0000022A0000022C0000022E0000023000024
+:1033E0000023200000234000002360000023800011
+:1033F0000023A0000023C0000023E0000024000000
+:1034000000242000002440000024600000248000EC
+:103410000024A0000024C0000024E00000250000DB
+:1034200000252000002540000025600000258000C8
+:103430000025A0000025C0000025E00000260000B7
+:1034400000262000002640000026600000268000A4
+:103450000026A0000026C0000026E0000027000093
+:103460000027200000274000002760000027800080
+:103470000027A0000027C0000027E000002800006F
+:10348000002820000028400000286000002880005C
+:103490000028A0000028C0000028E000002900004B
+:1034A0000029200000294000002960000029800038
+:1034B0000029A0000029C0000029E000002A000027
+:1034C000002A2000002A4000002A6000002A800014
+:1034D000002AA000002AC000002AE000002B000003
+:1034E000002B2000002B4000002B6000002B8000F0
+:1034F000002BA000002BC000002BE000002C0000DF
+:10350000002C2000002C4000002C6000002C8000CB
+:10351000002CA000002CC000002CE000002D0000BA
+:10352000002D2000002D4000002D6000002D8000A7
+:10353000002DA000002DC000002DE000002E000096
+:10354000002E2000002E4000002E6000002E800083
+:10355000002EA000002EC000002EE000002F000072
+:10356000002F2000002F4000002F6000002F80005F
+:10357000002FA000002FC000002FE000003000004E
+:10358000003020000030400000306000003080003B
+:103590000030A0000030C0000030E000003100002A
+:1035A0000031200000314000003160000031800017
+:1035B0000031A0000031C0000031E0000032000006
+:1035C00000322000003240000032600000328000F3
+:1035D0000032A0000032C0000032E00000330000E2
+:1035E00000332000003340000033600000338000CF
+:1035F0000033A0000033C0000033E00000340000BE
+:1036000000342000003440000034600000348000AA
+:103610000034A0000034C0000034E0000035000099
+:103620000035200000354000003560000035800086
+:103630000035A0000035C0000035E0000036000075
+:103640000036200000364000003660000036800062
+:103650000036A0000036C0000036E0000037000051
+:10366000003720000037400000376000003780003E
+:103670000037A0000037C0000037E000003800002D
+:10368000003820000038400000386000003880001A
+:103690000038A0000038C0000038E0000039000009
+:1036A00000392000003940000039600000398000F6
+:1036B0000039A0000039C0000039E000003A0000E5
+:1036C000003A2000003A4000003A6000003A8000D2
+:1036D000003AA000003AC000003AE000003B0000C1
+:1036E000003B2000003B4000003B6000003B8000AE
+:1036F000003BA000003BC000003BE000003C00009D
+:10370000003C2000003C4000003C6000003C800089
+:10371000003CA000003CC000003CE000003D000078
+:10372000003D2000003D4000003D6000003D800065
+:10373000003DA000003DC000003DE000003E000054
+:10374000003E2000003E4000003E6000003E800041
+:10375000003EA000003EC000003EE000003F000030
+:10376000003F2000003F4000003F6000003F80001D
+:10377000003FA000003FC000003FE000003FE0012C
+:1037800000000000000001FF0000020000007FF8C0
+:1037900000007FF8000002920000350000000001E8
+:1037A0000000000300BEBC200000000300BEBC20DF
+:1037B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1037D000FFFFFFFF00000000FFFFFFFF00000000F1
+:1037E000FFFFFFFF0000000300BEBC20FFFFFFFF44
+:1037F00000000000FFFFFFFF00000000FFFFFFFFD1
+:103800000000000300BEBC2000002000000040C0FB
+:1038100000006180000082400000A3000000C3C0DF
+:103820000000E4800001054000012600000146C0C0
+:1038300000016780000188400001A9000001C9C0A3
+:103840000001EA8000020B4000022C0000024CC084
+:1038500000026D8000028E400002AF000002CFC067
+:103860000002F0800003114000033200000352C048
+:1038700000037380000394400003B5000003D5C02B
+:103880000003F6800004174000043800000458C00C
+:103890000004798000049A40000080000001038049
+:1038A0000001870000020A8000028E0000031180E0
+:1038B000000395000004188000049C0000051F8090
+:1038C0000005A300000626800006AA0000072D8040
+:1038D0000007B100000834800008B80000093B80F0
+:1038E0000009BF00000A4280000AC600000B4980A0
+:1038F000000BCD00000C5080000CD400000D578050
+:10390000000DDB0000007FF800007FF8000003E5F9
+:10391000000015000000190000000000FFFFFFFF7D
+:103920004000000040000000400000004000000097
+:103930004000000040000000400000004000000087
+:103940004000000040000000400000004000000077
+:103950004000000040000000400000004000000067
+:103960004000000040000000400000004000000057
+:103970004000000040000000400000004000000047
+:103980004000000040000000400000004000000037
+:103990004000000040000000400000004000000027
+:1039A00000007FF800007FF8000003C80000150049
+:1039B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1039D00040000000400000004000000040000000E7
+:1039E00040000000400000004000000040000000D7
+:1039F00040000000400000004000000040000000C7
+:103A000040000000400000004000000040000000B6
+:103A100040000000400000004000000040000000A6
+:103A20004000000040000000400000004000000096
+:103A30004000000040000000400000004000000086
+:103A40004000000040000000400000004000000076
+:103A500000001000000020800000310000004180C4
+:103A600000005200000062800000730000008380AC
+:103A7000000094000000A4800000B5000000C58094
+:103A80000000D6000000E6800000F700000107807B
+:103A90000001180000012880000139000001498060
+:103AA00000015A0000016A8000017B0000018B8048
+:103AB00000019C000001AC800001BD000001CD8030
+:103AC0000001DE000001EE800001FF0000007FF831
+:103AD00000007FF800000207000035001000000021
+:103AE000000028AD000000000001000100350804BE
+:103AF000CCCCCCC1FFFFFFFFFFFFFFFF7058103C95
+:103B000000000000CCCC0201CCCCCCCC00000000EA
+:103B1000FFFFFFFF400000004000000040000000E9
+:103B20004000000040000000400000004000000095
+:103B30004000000040000000400000004000000085
+:103B40004000000040000000400000004000000075
+:103B50004000000040000000400000004000000065
+:103B60004000000040000000400000004000000055
+:103B70004000000040000000400000004000000045
+:103B80004000000040000000400000004000000035
+:103B900040000000000E01B7011600D60000FFFF34
+:103BA000000000000000FFFF000000000000FFFF19
+:103BB000000000000000FFFF000000000000FFFF09
+:103BC000000000000000FFFF000000000000FFFFF9
+:103BD000000000000000FFFF0000000000100000D7
+:103BE00000000000007201BB012300F30000FFFF92
+:103BF000000000000000FFFF000000000000FFFFC9
+:103C0000000000000000FFFF000000000000FFFFB8
+:103C1000000000000000FFFF000000000000FFFFA8
+:103C2000000000000000FFFF000000000010000086
+:103C300000000000FFFFFFF3320FFFFF0C30C30C4A
+:103C4000C30C30C3CF3CF300F3CF3CF30000CF3CB8
+:103C5000CDCDCDCDFFFFFFF130EFFFFF0C30C30C1A
+:103C6000C30C30C3CF3CF300F3CF3CF30001CF3C97
+:103C7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C85
+:103C8000C30C30C3CF3CF300F3CF3CF30002CF3C76
+:103C9000CDCDCDCDFFFFF4061CBFFFFF0C30C3051B
+:103CA000C30C30C3CF300014F3CF3CF30004CF3C3F
+:103CB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C59
+:103CC000C30C30C3CF3CF300F3CF3CF30008CF3C30
+:103CD000CDCDCDCDFFFFFFFA302FFFFF0C30C30C51
+:103CE000C30C30C3CF3CF300F3CF3CF30010CF3C08
+:103CF000CDCDCDCDFFFFFFF731EFFFFF0C30C30C73
+:103D0000C30C30C3CF3CF300F3CF3CF30020CF3CD7
+:103D1000CDCDCDCDFFFFFFF5302FFFFF0C30C30C15
+:103D2000C30C30C3CF3CF300F3CF3CF30040CF3C97
+:103D3000CDCDCDCDFFFFFFF3310FFFFF0C30C30C16
+:103D4000C30C30C3CF3CF300F3CF3CF30000CF3CB7
+:103D5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF8
+:103D6000C30C30C3CF3CF300F3CF3CF30001CF3C96
+:103D7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C84
+:103D8000C30C30C3CF3CF300F3CF3CF30002CF3C75
+:103D9000CDCDCDCDFFFFF4061CBFFFFF0C30C3051A
+:103DA000C30C30C3CF300014F3CF3CF30004CF3C3E
+:103DB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C58
+:103DC000C30C30C3CF3CF300F3CF3CF30008CF3C2F
+:103DD000CDCDCDCDFFFFFFFA302FFFFF0C30C30C50
+:103DE000C30C30C3CF3CF300F3CF3CF30010CF3C07
+:103DF000CDCDCDCDFFFFFFF730EFFFFF0C30C30C73
+:103E0000C30C30C3CF3CF300F3CF3CF30020CF3CD6
+:103E1000CDCDCDCDFFFFFFF5304FFFFF0C30C30CF4
+:103E2000C30C30C3CF3CF300F3CF3CF30040CF3C96
+:103E3000CDCDCDCDFFFFFFF331EFFFFF0C30C30C35
+:103E4000C30C30C3CF3CF300F3CF3CF30000CF3CB6
+:103E5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF7
+:103E6000C30C30C3CF3CF300F3CF3CF30001CF3C95
+:103E7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C83
+:103E8000C30C30C3CF3CF300F3CF3CF30002CF3C74
+:103E9000CDCDCDCDFFFFF4061CBFFFFF0C30C30519
+:103EA000C30C30C3CF300014F3CF3CF30004CF3C3D
+:103EB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C57
+:103EC000C30C30C3CF3CF300F3CF3CF30008CF3C2E
+:103ED000CDCDCDCDFFFFFFFA302FFFFF0C30C30C4F
+:103EE000C30C30C3CF3CF300F3CF3CF30010CF3C06
+:103EF000CDCDCDCDFFFFFF97056FFFFF0C30C30C7D
+:103F0000C30C30C3CF3CC000F3CF3CF30020CF3C08
+:103F1000CDCDCDCDFFFFFFF5310FFFFF0C30C30C32
+:103F2000C30C30C3CF3CF300F3CF3CF30040CF3C95
+:103F3000CDCDCDCDFFFFFFF3320FFFFF0C30C30C13
+:103F4000C30C30C3CF3CF300F3CF3CF30000CF3CB5
+:103F5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF6
+:103F6000C30C30C3CF3CF300F3CF3CF30001CF3C94
+:103F7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C82
+:103F8000C30C30C3CF3CF300F3CF3CF30002CF3C73
+:103F9000CDCDCDCDFFFFF4061CBFFFFF0C30C30518
+:103FA000C30C30C3CF300014F3CF3CF30004CF3C3C
+:103FB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C56
+:103FC000C30C30C3CF3CF300F3CF3CF30008CF3C2D
+:103FD000CDCDCDCDFFFFFF8A042FFFFF0C30C30CEA
+:103FE000C30C30C3CF3CC000F3CF3CF30010CF3C38
+:103FF000CDCDCDCDFFFFFF9705CFFFFF0C30C30C1C
+:10400000C30C30C3CF3CC000F3CF3CF30020CF3C07
+:10401000CDCDCDCDFFFFFFF5310FFFFF0C30C30C31
+:10402000C30C30C3CF3CF300F3CF3CF30040CF3C94
+:10403000CDCDCDCDFFFFFFF3300FFFFF0C30C30C14
+:10404000C30C30C3CF3CF300F3CF3CF30000CF3CB4
+:10405000CDCDCDCDFFFFFFF1300FFFFF0C30C30CF6
+:10406000C30C30C3CF3CF300F3CF3CF30001CF3C93
+:10407000CDCDCDCDFFFFFFF6305FFFFF0C30C30C81
+:10408000C30C30C3CF3CF300F3CF3CF30002CF3C72
+:10409000CDCDCDCDFFFFF4061CBFFFFF0C30C30517
+:1040A000C30C30C3CF300014F3CF3CF30004CF3C3B
+:1040B000CDCDCDCDFFFFFFF2304FFFFF0C30C30C55
+:1040C000C30C30C3CF3CF300F3CF3CF30008CF3C2C
+:1040D000CDCDCDCDFFFFFFFA302FFFFF0C30C30C4D
+:1040E000C30C30C3CF3CF300F3CF3CF30010CF3C04
+:1040F000CDCDCDCDFFFFFF97040FFFFF0C30C30CDC
+:10410000C30C30C3CF3CC000F3CF3CF30020CF3C06
+:10411000CDCDCDCDFFFFFFF5300FFFFF0C30C30C31
+:10412000C30C30C3CF3CF300F3CF3CF30040CF3C93
+:10413000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C47
+:10414000C30C30C3CF3CF3CCF3CF3CF30000CF3CE7
+:10415000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C27
+:10416000C30C30C3CF3CF3CCF3CF3CF30001CF3CC6
+:10417000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C07
+:10418000C30C30C3CF3CF3CCF3CF3CF30002CF3CA5
+:10419000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE7
+:1041A000C30C30C3CF3CF3CCF3CF3CF30004CF3C83
+:1041B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC7
+:1041C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5F
+:1041D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA7
+:1041E000C30C30C3CF3CF3CCF3CF3CF30010CF3C37
+:1041F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C87
+:10420000C30C30C3CF3CF3CCF3CF3CF30020CF3C06
+:10421000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C66
+:10422000C30C30C3CF3CF3CCF3CF3CF30040CF3CC6
+:10423000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C46
+:10424000C30C30C3CF3CF3CCF3CF3CF30000CF3CE6
+:10425000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C26
+:10426000C30C30C3CF3CF3CCF3CF3CF30001CF3CC5
+:10427000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C06
+:10428000C30C30C3CF3CF3CCF3CF3CF30002CF3CA4
+:10429000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE6
+:1042A000C30C30C3CF3CF3CCF3CF3CF30004CF3C82
+:1042B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC6
+:1042C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5E
+:1042D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA6
+:1042E000C30C30C3CF3CF3CCF3CF3CF30010CF3C36
+:1042F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C86
+:10430000C30C30C3CF3CF3CCF3CF3CF30020CF3C05
+:10431000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C65
+:10432000C30C30C3CF3CF3CCF3CF3CF30040CF3CC5
+:10433000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C45
+:10434000C30C30C3CF3CF3CCF3CF3CF30000CF3CE5
+:10435000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C25
+:10436000C30C30C3CF3CF3CCF3CF3CF30001CF3CC4
+:10437000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C05
+:10438000C30C30C3CF3CF3CCF3CF3CF30002CF3CA3
+:10439000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE5
+:1043A000C30C30C3CF3CF3CCF3CF3CF30004CF3C81
+:1043B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC5
+:1043C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5D
+:1043D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA5
+:1043E000C30C30C3CF3CF3CCF3CF3CF30010CF3C35
+:1043F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C85
+:10440000C30C30C3CF3CF3CCF3CF3CF30020CF3C04
+:10441000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C64
+:10442000C30C30C3CF3CF3CCF3CF3CF30040CF3CC4
+:10443000CDCDCDCD0010000000070100000281703D
+:10444000000B81980002025000010270000F0280F0
+:1044500000010370000800000008008000028100D5
+:10446000000B8128000201E0000102000007021099
+:1044700000020280000F0000000800F000028170BE
+:10448000000B81980002025000010270000B828034
+:1044900000080338001000000008010000028180BD
+:1044A000000B81A80002026000018280000E829849
+:1044B0000008038000028000000B8028000200E05A
+:1044C000000101000000811000000118CCCCCCCC10
+:1044D000CCCCCCCCCCCCCCCCCCCCCCCC000020002C
+:1044E000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0C
+:1044F00000002000CCCCCCCCCCCCCCCCCCCCCCCC0C
+:10450000CCCCCCCC0000200000000000000000005B
+:104510001F8B08000000000000FFFB51CFC0F0031C
+:104520008A45D91918FC3811FCA18059981918D856
+:10453000809803883D80B8819181A1919178FDDABE
+:10454000620876BF3003C36E20E611029A23821000
+:104550009F0254F306C85F0F15B312656038263A00
+:10456000F07EA706DE2A8D29364512C1DE86451E5D
+:10457000196F4793FF2289CADF4140FF40632965D5
+:1045800054BE9D22845EA604A1A5D1E4EDA1F2D77C
+:10459000A1FE9251C66EEE0DA83C00F85C49656024
+:1045A00003000000000000001F8B08000000000056
+:1045B00000FFED7D0B7854D5B5F03E73CE9C994944
+:1045C000CE4C4E4212F2224C1288A0210CAF808AAF
+:1045D0007F270122F539202858D40142087983D455
+:1045E0004BAFEDCD8424101135F447058B76885000
+:1045F000D1A20D34D260C10E20147B6D6FF0FAC0D1
+:10460000EAF50B4841312FB1207EC5CBBFD6DAE7A2
+:1046100064E64C2680D8DBAFFFFFFDB4B8D9E7ECE9
+:10462000B3F7DAEBB5D75A7BED3D92750293BFC76E
+:10463000D845FC03E54F4D8CB109C1F26766F680A1
+:104640002787B1C9BDFE3A473C63556D193BA29D12
+:104650008C25EC9921142850FED5232C5082DFBFE5
+:1046600065C397F0FFB619423E7C97D0E911E6C3C7
+:10467000FBE4D5026B873A939C310CEA8CB9194B59
+:10468000642C6B12A33F224B8D82FFE07325398F80
+:10469000B134FC2774754661AEC078C6321E535CD7
+:1046A000D4D0A93815783F847FC6D2BC25B731074E
+:1046B00063CF03BCC971F0BC5A3ADE61E5EF2EC28C
+:1046C000DFA1F33A6ACD58AE303E7732A789654113
+:1046D000BF3EE3F3AC46633D9BD9E34F46C33FEC9B
+:1046E000CC7E518C308F13B18C013CCB540E2F6398
+:1046F000BDB26754101F9B6A58A2322C580F2F85E9
+:1047000065873356035E97ED165C16F8FE396C2FFD
+:1047100031E6D7BE6BD6EA153E5962A3A10404B5B3
+:10472000E4F4EF6711CBBF11F1FE302BA0B24AEADF
+:10473000955580AFAA5A76FB95FEED673389E8540C
+:1047400029B9F65B61FCDE5AE66A86F19799D502D3
+:10475000AC2FFB91D3E5837A6663472183FAD03689
+:10476000818919C1EFAF009EDB917F001E2A2BA526
+:10477000DE420674ECDD2BB0E60C1C87F7BB6C77D1
+:1047800006F3650C0CE758662638E732413A89741F
+:10479000713007D2C1BC24F38942A8CE54DCF3B0F7
+:1047A0007F9FE29D87EDF4E7490BE638BD0057F2A5
+:1047B0005066A057B1B53A9D653256EA692944BEA4
+:1047C00038B5EC8D5558029E1324C0F77C8BA70892
+:1047D000FBA998579DCD80A7E659188D3FB42DFFB2
+:1047E0003309F80CBAF3C5C4213F31763C844FF04D
+:1047F000CFF1115A5D1C98DE972B8BB01F09F10584
+:104800007217011F3F42A026E0284D543A57FC2959
+:104810006BD8A0D0FA5B59C3C66900E511BC0C3F48
+:1048200061AC4308E54BBD1CBA3BFFB0943B303C48
+:10483000FFD3F30474127EAB00B7C81F1576D9BF3F
+:1048400012F861CAABE6C0F7803F2A360B7E0BD464
+:104850004DAFDBE87DF7265E0FD86537F24FD716F0
+:10486000A80BF0BDA5FDF11B91BF5E155933763B3A
+:1048700022CA84FAE5A4063B1B0F75C047B18D57C9
+:104880002B36EFBB1FBF2F69B3301BF457B17BF141
+:104890001D37427DF16133C326155B6BE514A82FEC
+:1048A000F10B2D58EF29E0F0F97689FEADD0BEC7A7
+:1048B000D19E381BE873BAC6CA9C326375F6F6C43B
+:1048C00059C067A5FE1D85F85DE976C185689FF230
+:1048D000EAD643C938AF17B97C976D8B664E1D7FFA
+:1048E000F0F764AB18F81EBC5F06F364D0EF62D635
+:1048F00054887AB062EB3AD9690FE2EB748D4AE3DF
+:10490000F4C9DF8B300E7C57F98AE0C229569A9899
+:1049100017E5B07BB76DCEF30ACEAF56CEB6E3BC8B
+:1049200056CBD86EB17FFE2E54CDA5FECD7221BCE4
+:104930002FDDB4592E0E91DBB26D838C706DC81AC9
+:10494000EC8D20D7417880D7B283F552D403A80FDD
+:1049500025BF3C2384CF2A8558E2CBB26D22731A3F
+:10496000F888D3DDF72EFC13F0E5DB6B27BCEA7487
+:10497000EBD3A71ADDCEA81A1DA5DEBC1911F8F8D5
+:1049800071A403C0D384788272AD069F6332CB9743
+:10499000A07F879BA902BB3C5F3699D97C0663F553
+:1049A000B007DDD2F55097D952E682F550FAB17BC7
+:1049B0002AD49304EF67389F7AC15BC2D7AB9624A1
+:1049C0000FE07995C0E6E0FC8F21D030AF55C9C02B
+:1049D0009F80F7A66979CF8B82067B3CD68B7FB10F
+:1049E0002683FA3943FD98A19FACCBF7A3164E322C
+:1049F000F4A31696E8FDFC8DFAB15D593F4D85375D
+:104A000018E1292CD5FB910468576FBFB279A937FB
+:104A10004F36C2737339F5133BD5C5BC0AAEE71ADE
+:104A20003FB076B708EF95EDB163D7B050BE2850D0
+:104A30000580DB0E5212CA173193A20C7C18EB8E44
+:104A400033D4A127F5E47541FD138895697C394578
+:104A500026BD909F62A5FA43290AE985876EF05E1C
+:104A600083EB208ECD92A12E7B47AB11F81AE01478
+:104A7000581296601724F57FBFDACCF150907A2156
+:104A8000FB187C5F65EACD8E85FA35A6FC6B116F4D
+:104A90002E81EBE528915563BB280B23FDB43A2307
+:104AA000EF795F089E1A8700FD8560BF8D666F12E3
+:104AB000F2D7F8DA677C12C0B76A08CC2705BA12B9
+:104AC0009E09F8603D5A3DA43809F1699141BE4301
+:104AD000C79761FC1C1AFF06C4A31BC74FE83FBE63
+:104AE000257392617C6B7A89617CAB0CE303BF4FC9
+:104AF000AD6DD6C607FCDDC0D834A199C6B7A49762
+:104B0000D0F8AB655662183FAA6FFC5B70FE9E81C1
+:104B1000E69F798371FEE9A5C6F9CB7CFEB36A5F97
+:104B2000D2C68FA2F9CF165EE2F34F2FE5F3B7F0AE
+:104B30007EFBC677F4E1FF5E9CBF7780F12D599331
+:104B40008DF31F5A6E9CBF858F5F54BB531B5FA1B3
+:104B5000F117093BF9FC8796D3F8B2C5EB423E92B8
+:104B600053A3AAFD684FA481400C261DE5A672043C
+:104B70001805A01F860A9904C743519CEFCE450132
+:104B8000BF29417DC7FC2051A0CF2A359E2FDB9E37
+:104B90002FA39EA5F7896837F13F456D22AD376C8D
+:104BA000BDC53F1CE0ED6E137D582F5A7F935FA467
+:104BB000F58EDBE560C605F0F95F9E1CD51C3AAFAB
+:104BC000F0725193F96487418E383CBE0236A21AC6
+:104BD000E06B47269810AC9F043D0AC62F3B0E7A27
+:104BE00014CB53666E8F9C003DCBE450B9A9E5F61B
+:104BF000888FBD9303F3BA5B83FFA4C4F17D72B9C0
+:104C0000E047FC9F5BB75446FDB4A8098CE91079D6
+:104C1000AFD2E8D4BBDBE26F16089F4EC4CF3D2471
+:104C20008A8CFD9766D72FDE30C8F0DD3CE66F48F2
+:104C300082F60BD7CE1FA2C2FC7F30C73216ED53CF
+:104C400090845413C9314B35816F31A7759D391547
+:104C50002AF7CC311BECFAB95E63FD0725C67AB79B
+:104C6000D96F36A1BDB144609BA1DFFBAA8DEFF5E2
+:104C7000713609719CAEDA7877277278EFC3722C9F
+:104C80003E5689AEF7ABFC5B1D9EAA87CD2C40EB50
+:104C9000654702433AFA12C85EF3AA7CDEE1F0DE11
+:104CA0006FB6BA3D00CFFD3F12099FE1F077BC1E01
+:104CB000ED36811DD7B1E14B33DAB7E1F30987FF58
+:104CC0008115E1F35165D4F7F37DE1CF399F84F38A
+:104CD00053555BFEA01321ED2A5ABE3FE844087FDE
+:104CE000956D9B61A82FF1CF35B45FBC61BEE1FD2E
+:104CF000A2A62586F70B1B971AEAF37D3F32B47FF5
+:104D00006045ADE1FD7DD58F18DEFFA0649DA13E1D
+:104D1000D7BBD1D0FE9E399B0DEF4DAF8FBC13E5B5
+:104D2000A8EE5D91E1BA715639F938DA836715C991
+:104D300085F4F8B42689E4E0748D93CAEEB6715612
+:104D40002FD783C50C4C9C5EE19CAF7132EA65465F
+:104D5000FAF3AFC2059F0FEA7F139C843F7183CCA7
+:104D600002C0C2028BEBE3E35E31E47DC765DE6F18
+:104D700000411FD7FFBDD811F97955F3FCA16A0492
+:104D8000FF2128B72C15D7B91E6D7D0F7F5F2E3000
+:104D90004FE873C656929CD769EB4CB9CCF541F9F4
+:104DA000CEE402F4BFCBE54076F5A5C66B01A4A224
+:104DB0009E44EB3C01F901A4C0C02F5906F9EEDC7A
+:104DC00027125C95A81340AFAE639EC126D43381F1
+:104DD00003E9778D4238DC49546F4BA075BDB3664B
+:104DE000FAA01312D2C743E5A73573A83C59E3A52F
+:104DF000F2444D0995C76BAAA9ECA85941E5C735FE
+:104E00003E2A3FAA69A4F2CF354D541EADD940E5E4
+:104E10007B357E2ABB6BDC54F6F92BBAFE8DD7ECC2
+:104E200055CDAF809587EA67B4B9D443DB769273EA
+:104E30005712CAF919E55C36DAE3678E8263993155
+:104E400030BEC2F96D603ABAC95E29F603FDC7F5F6
+:104E50007F6F8BE274B299D87470A6D923C37FE1B7
+:104E60005A9043750959061624D70C7B847E61ED50
+:104E7000437A5D8E4ECCDD9B3B13E871F299BFE522
+:104E800061BF75DAFA177540A47598059E7721BD44
+:104E900042F046EB5AEFAB9ABEBF0CFEBAFAF0D71F
+:104EA0009E8EFEFB4141A5FECFB45A988478DC1358
+:104EB000ED07E667670E3FEF40795C9664524F441A
+:104EC000C0835E56B464A84AE8FAD366AC9F691200
+:104ED000A6B7D07AEC8C99350AF94A554F0C43FAAB
+:104EE0002751A9F7B32C49564F80BC9EDE9615C3B7
+:104EF000D76F3F5F07B7C712BF825F48EDFFDEF095
+:104F00000CD48F0E0F63ADEC132BEA037897F5EDFD
+:104F1000FD7226FD95E2576C8FF91CDA0B16F87BB3
+:104F200091E20712D5F57EAB5A449F65343EDF6EA1
+:104F3000180FBE73EA3EF7C5CC4BF1ADC44E86C424
+:104F400011D669F1C6B26D36D5B8AEC41AEA556D40
+:104F5000C9AA619DC17F80FCB36A4142BE29D7B80E
+:104F6000A847521A0580AFDCE4A47EAB04DEAEC2D3
+:104F7000DA217BE151572BA7DB40F09DAE39EC9451
+:104F800040DE4BACE001027C252D23A7A29EEB6AFC
+:104F9000AD4B447BB04C3CF39027C2F73B4D028DA8
+:104FA000B7C46FEE35AEA31A7F30E8577F4E7E163A
+:104FB000534E86D43B4DDCCE0EEFF780D6EFE5F0B6
+:104FC00053B9FD48E18DCEFE78AA6CFB42F6921CE7
+:104FD000C1FFF28278D2F1576EF21C407D5ABAEDD1
+:104FE00018D9A39F9A7DD90F5F423FF59F9F9244A6
+:104FF00071527D5E3E3029619C055A7C17F8F79E00
+:105000000F613DFDECDFCD6C0DC0C72E402B786FDE
+:10501000D65F331333417DA1565BD05A4671DDCF45
+:105020004CDC8E2A621E07D18135E5A11DD9C54C05
+:10503000D3114F5DEC6DC7B8103A9C32C9A4671606
+:10504000361AED18B07F0DF5C51B8CF5623633119D
+:10505000F549F17A33F30B343FC3FBF74D2AE17F77
+:1050600031AB5E85EBAAA4F9230B5426A5027C156F
+:10507000BF79366F3EC65F4CDC0FD1E3234BE2387D
+:10508000FCA5F17ED90DEF3F691D77F78D48068BA2
+:105090007F15C689580C736D65FDF1FB6DE10F87B7
+:1050A000575FAFFBC5693438C46D82DB1F817F2F2A
+:1050B000687CA6EBEB5B44D5E017DC8DF510BF21D7
+:1050C00046D4E2B2221391EE5DAAD5678AA1F71405
+:1050D000B7F7EDB4B8EA80DE3F3779068913C84EDA
+:1050E000C86521ED7E6EF2D2F34EE1AD62B45B99FC
+:1050F00014C8453B14D618E25359E30731CA918BC3
+:10510000F1663B837514E86F41F8A09F55F692DB7A
+:10511000582EC6BB41DEA1BFC71C858705A8DB94FE
+:105120005686FD59928CF17C9BD358AFC27F201DCF
+:1051300046308A3F458F90C2F01860A80FED2EE3ED
+:10514000F351E88491DD1F203E76108B43695502B0
+:10515000228CCF26499D7DFE5626FA7B1C7E8A2F07
+:1051600040FBE52A6F5FA9C5CF977F503038EE121C
+:10517000FAA8EA3C68904121753DBE7F5E62FE71EF
+:10518000DF416F3A61550DD19B734DDE69480FD4F5
+:1051900093089F00E3780D76609A1A2AE70BC2F80D
+:1051A000E3AAE1886706FD5D6EF2DE2D26F487E353
+:1051B000AAFB4FEAD7FF8248F3BCEAFE87F5EBBFB4
+:1051C0003252FF15BF7979970FF8A9F4574F3A80FB
+:1051D00099D9675253A20BE85EBEB5C18172F9A995
+:1051E000E473205D3FF38BD323C9E71651974FB784
+:1051F00022E411FF101F9D7EE9D13BD0AE3AB7D516
+:10520000AC527C609B256001A6AC6C5DC2E5639BE3
+:10521000E518AFAFFE02F9B3AACDA82F4A5F7832E6
+:1052200011E3CD4049CD7F0E907F50B9E52F8568C1
+:105230007755B15ED27BE1DFE1F8E7E3C81E982F36
+:10524000C7F47FAFEFF3556978A96A7DF40B9184B9
+:10525000A583FCCDF0F6259ABDFFA4688FA738DFA3
+:10526000443611F94CC707F3737BBFEEC5A7738FA4
+:10527000013C9D5BFEDD21E484F227D77B675A1653
+:10528000FEFC35E7C0F2D40D7A31D4AED6D76767CD
+:105290009BE6A7ECE165B939E0403FB07CB3D9E5C6
+:1052A00043BABEFCFC2F9EC1B8CC0716D770E8BF2E
+:1052B000ECE583EFDD00F5B21DE6F8DBF8341421F0
+:1052C0003148972AF8BB626C900EA5BF3E283B4739
+:1052D000F1E73F8E0BD2A36CC73E998DEA8F8F29E1
+:1052E0002DFBE40E25025D5A8E15A23F51F7E257C1
+:1052F00032EAAFCF5E17D8E08C08F8DC7C90EC6225
+:10530000C413D151A3531FDDC2DA57015D50BFEA68
+:10531000740A7FFF2F9AFEC7FE9C39C4CFAFBC86AC
+:10532000FB287FB6B870FE25AF3CE8C0799C92AAF6
+:10533000395F3FDB90E886714BCCBE44954AFEBC9A
+:10534000E4B91F12BF2D3EF2C3448A7F3077B28981
+:105350006C055F32CE6FD1A6D934BF62E625BE2B75
+:105360007956F4E0FEE059894DDF11412E5224AE0A
+:105370008F4F355B704D65A770E1C07D85B745FFE8
+:10538000568AFF2DA5F8CA0FF5FD20B68CEA67AD49
+:105390009C4E5F88FABE1AAC3CA1FCBA65753BD244
+:1053A000E7F410F7608C1B5731C9A7E143B808FD3B
+:1053B0008A47A60DE6F4614E294FFB0EF4FD147CDE
+:1053C0008EEDDBCD6E5BAEE13B76312338FE726D48
+:1053D0007C803B0AEDD5538960FF45985FA1A4AF5F
+:1053E00037605785F057887C7379DFF208976F5DD7
+:1053F000DEFD33A6E3FBBFBEC3E507BF437B05E08D
+:105400000A0CA6F7FB6609A40F2C2C1049AEB7981E
+:1054100035B936BED7F904E09670DDEDE317EC3F01
+:105420008EF04F766CF17AF82E445F56E1788EFE5E
+:10543000FDE972BB5893FF04C928FF6C1397FB81E9
+:10544000FD091F8F4B98FDBF7806E515E413F7AFF4
+:10545000CB5F367B70DE9F6F3FF0DEBD20A79FB72E
+:10546000E8726AD49FE1725AB273028B24A79F63D9
+:105470001A42243985E711E554E9203EFE47E94FF9
+:105480001D7F3785E14FD78703E1315C1FFE5974DB
+:1054900046D487F0E71D96D79FFF74BED3F9ADF4CD
+:1054A000971543293EA6F3A5CE777D7CA9F35DBF72
+:1054B00078A3017FE1EF2D188301B83CBBCD1447E1
+:1054C00028DFC3F77FE1BB43A9E3094F6E5AC658F3
+:1054D000D3A1D4F8D0BA3FACDE12D6DE1D56F78485
+:1054E000B5F786D5AB0DEDCBDB0EC83CAF256068BC
+:1054F00027AE78867D322812BFFAB95FDAFA85ECDA
+:1055000043BE507AE97BF34AE6B3633C7CAF48F193
+:10551000911EC0F12A18A7677B861FF3241A6C3CE2
+:10552000EED4A3F63AD05E6C88E5F5DE047915EA90
+:105530003DFD79AF8DC7F57A3CBD8ED810FBEDD817
+:105540001E91F476879F4D8FE467C28A4272D4C160
+:10555000067ACFE3FDD344257D05C65F9A441786BE
+:10556000748A6AEF71609E41CF9EAC3BE7C0F34501
+:105570006F8AB48DD883767B0C92C72D2587F877F8
+:105580009F32DF5393317EBF87FB79456BC3EC11AC
+:10559000B696F8A958592EA33E05BFECB871FF8204
+:1055A000CB45A9D65FC926E37BFD7BDCC145FBBDAE
+:1055B000748BF1BD578B0734EB7232868DD1FC7141
+:1055C0001E8FD2F4F23431E7CE39408F9EC322C30E
+:1055D000FDFB337B44A2C799ED7CBF9EE2F6D72347
+:1055E0007FF7923ED4F1D489F2240FACAF3A5FFD3D
+:1055F000AFBC87916F767D98FB33283B777D90FD1C
+:105600005BACFFE6FDF40F59FFF6535EB7D13E49A0
+:10561000CFEB76E2F79EBD7F4C7F18EBBB2D149F3E
+:10562000EE79FDAB5CE49F9E959612D4773D438066
+:10563000FE681FECFD2AB783D6D77AA2DB1F259917
+:10564000DB477BFEF6B1108F25CC0AED86D7A34948
+:105650009EAA5EB3513CAD67EF5779A176FF779D67
+:105660004FA5B67FD963677376227CB17CDFA7EA4A
+:10567000B7D73F5F8BF917ADFBE485F07ECAEFBE6D
+:10568000C9453DDAB393DB43DDE68EE7707FEE6814
+:10569000FDDC9566C073370A550AAC9B0DCF14A08C
+:1056A000DCF4C7CB371427BC527CF4FC5F830FC1FA
+:1056B000CDF59DDD6F1570DE5F7FFC21EA85D72D6E
+:1056C000C497FA7C3F6FA9257BE572F37698799CA5
+:1056D000E4FF9D790B812B99F728F33F37BD7F2D90
+:1056E00039892EE172D09FCFF73E44F597ED2E8297
+:1056F000F70AF9FDF67FF2F97F6BBAEF04BA3B2E99
+:105700003FEFF27FF2790F4CF737EFD7E8AE627ECA
+:105710004BD5EFBE21F8BEAD9E5BFB4F2EEF03CD08
+:105720005FB7EBD7985C4D99189F43AF01D669C519
+:105730003EB311C3856B46CC54D1CE14C3F62BF5C2
+:1057400072AF99FB4D22EE5B629C6F088FF331CDF7
+:105750008FA22D3D185A528AC98E959455DCBE965B
+:105760005CED6EC0CB9A6B17B82877888D3DEAC583
+:105770007ADA6417C5AFC3FCC97A81B905B06FA5E1
+:105780006B6F398CFE8D79842960C9A5F21896ABB0
+:10579000B5B8A459950D7E8F9263ACDB9CC6BA4513
+:1057A000EBCFCA38FCD624E6C7F8B43872BF8A7982
+:1057B0006DE218890950B7B1261FFA179624E3F74E
+:1057C0001B31C01E12CFBD5A3CF6F6E1716CBB1BFB
+:1057D000F138D244716B4A2E25BCB8FC6B789E8D93
+:1057E000D588D755ED884F09FD5F6E7F91DFCC34AA
+:1057F0007F59D2BA904698DC36633BCD4FBE2C9D84
+:10580000385DD2CB353A2D33D045A74304FA18E89A
+:10581000A2E3F9DBD2279C2EE1F8DF6F7612FE07B8
+:10582000A2974E9734C5CD505ECD9ABF3015FD4935
+:10583000ACA77918ED336BFE8214EF663EA493EAB1
+:1058400062482FF4DB02E0B7FD7EFBF31427EA7A0F
+:10585000E9D81D084FD96F456605FC756FB7B300D1
+:105860007E2FF965F4434B5B458AFB3329907757CC
+:10587000C8BEAF6EF797FDCA4EF329DD69F1DF06AA
+:10588000DF97EEFA2497ECB095BDE4D7F85E1238B6
+:10589000DD7D1DB9B8AF5B2A71FF239C5F62659EF9
+:1058A00027D0B93B7A0EC66D846D3CDFB6B4E51ED9
+:1058B000B3C5907F66D6DB915EF0BD2850BE13C2A3
+:1058C000179AE7A9FB1D9D2F0A1CBE36B31FF3765E
+:1058D0004BB7EDE8C6F853E9518B0BC3D255DBBE8D
+:1058E000A0FD8D29BF7AD9D141FEB668883FF4F377
+:1058F000FBB789C41F95AD15E487409DF8A2B2257A
+:1059000072FCEB72FE69D9AFF6EEF2010ACB7EFDB6
+:105910008203E35BA7DBB73AC8FFDF76E9B85B3FFA
+:105920003FBFE5914BFAF9A7F11FE0BFDC2087C527
+:1059300049B60D227F04E0CB8B94EFADF35BD9CB5E
+:10594000679FC33874E7CECF9F4378CBFFFBCBE78D
+:10595000D09F60AFDBD4AD889797DEA5389EFEDD83
+:105960002C99C79DBB5F7C81E29FDD1F80DF017F9B
+:10597000BAF79E4A477FB27BC7D789182F59BE779F
+:10598000DA609CEFF257A70C6611F4885E22DFFA0A
+:10599000AF20FE1A4EAF03AD07C8EFE9027AA3DFCE
+:1059A000D917B769A9E07130A716AFD91E39CEDD76
+:1059B0002F3ED37AD79D378DC7D2EC72B22B88D3C6
+:1059C000BC03741C7D05F4DBFE88E67F46A65F17EA
+:1059D000FE03E8B42C8C7E675B17FDFC197CD73A7C
+:1059E00068C0384DE00AF0A6C7D1BF27BB7F22A30D
+:1059F0007CEDFC25C5C5906EB7C144BB5F3E9B8E58
+:105A0000FB0F9F9A7BEFE7E7322C2AC61B4AF7BEB3
+:105A10004FF2D3FDEA118A53332D9EDDCDFAFEF00D
+:105A2000F8A3965359B5C5CEE33B1AFE31FEE37495
+:105A3000D0732DCEC3F9588FFF0C14F7699579DE1A
+:105A4000881EDFAFD8F2A1164F09D24B9884743A62
+:105A500076C9FD081D0F2AE26162681C33727CADB5
+:105A60002FDEADD10BE987F1CBBE3825D4D3306E14
+:105A7000E517DE6711F441F7661EFFEC3647CEA34B
+:105A8000D2E39ABF0A9753FF95C5332F07FFB7C5D7
+:105A90008F5F7652BFE178EABC10598FBF2DF37546
+:105AA000FFAAF7C5CA0543BE41B9C97B04F9B1A233
+:105AB000F598CCCFA5F0F352FA7C3BB5BCD1CE978C
+:105AC000448A77AD6A39407A3C5C5FE8FBA6E1F036
+:105AD0009ED0E0AD6CE3EB44E74EBB5F817E3AF7CE
+:105AE000EF267EAEDC7E8CE26D87B6FD5AEE08595D
+:105AF00057719DF087C0DFF9CABE5C1EB7E579EC2F
+:105B0000E1E39CD1F461D59EC8E3546DFFC2304EF1
+:105B100099AF45E6EBFDA5C73B2DB9EFC1FE4EB7EA
+:105B20009B19E6799E6E11A7473A17F5AEB66EEA55
+:105B3000E77E70BDA47CFD23FC5CCCF8B7A3281FD6
+:105B40007EF991E91FC6C463098487FE5A6B399FA9
+:105B5000B6FEC49D8AF46E3D72AF88EBD42EC46F3E
+:105B6000889D9FF74EF5143BE885BC8F3CE3915D23
+:105B7000C3F5CDC4A32603FC30CE605C07EAA11FA9
+:105B80003CA782F96E088FE8289C8EF088AA49B558
+:105B900009FDE761563C745E40EFD7AC1ACF03B005
+:105BA0000BE39CD84FD24C1E474CBE8B973EFD3C1E
+:105BB0004E7194BF0EE659A078D32CF07D927D7D76
+:105BC000C64186E7BF2651DE7696C5786EAC4B554A
+:105BD0007C26D0DFCFE46C5937D949F907D7584232
+:105BE000F30F582017F9516FD7EF7D587E421A7E78
+:105BF00002FD881A7C595A7EC210D621A07DBDC9EB
+:105C0000CECF270E55E24DF8FDF39ABDA99F3FEC8C
+:105C1000775E31EC9CE2E5CE27C64FC95F3AD405EA
+:105C2000FCB47ACF14CC5F8FBF277F47AA8A791242
+:105C30007F9E82E757E25FC81F930CF513AB1F9C52
+:105C40004AF5FFC81F930EF56F1AFF8DD7CB04CA14
+:105C5000572D583D7A2AF2EB55CBF92CC08851CEFE
+:105C6000EF40BC75793EBA7B9113F31F7A658E5F66
+:105C7000E6C176432671BCA5291FED403C0D357564
+:105C8000D4227FFE7CEF57B1A8179C4C25FCA8AC12
+:105C90005E45FAC1A349172F9147179E4FA6EB9374
+:105CA000CD8AF70184E391F923E85CE0332533AD35
+:105CB0003C5FCF98C7C0D478A26791464F84D31A6F
+:105CC000928FBF58F4C9FC5C4C93A6AFA6AA389E2D
+:105CD000E02B172F5EF7EDE17A50E74BED5C69C8DA
+:105CE00079C687105E9FE27DC892D0FF3CE31D1607
+:105CF000CF0A7C9F5C7C3E1DF95B3F9F187ECE9156
+:105D000049BDA648F65FB376CE7120783D56EF2A9E
+:105D10001C37F377CE9D8741BE4617C92E4CCD1C4C
+:105D2000BD627C82C4CF15529E439546BF24139713
+:105D300043F610A37DD61E8BE046BFB9E74195F42C
+:105D4000775AD16DE457F54467B4603E50CFC3FC39
+:105D50005C29664CA31C0DD9131340BF0FE4E05C13
+:105D6000981C9C33AE73C6717B2E3ADB3AA83F5524
+:105D7000EB0F0CB0C4E0B9E01E91EBE59E1A27C111
+:105D80003184F9F6E1FA7EA5E36DB518CFFD02DEA8
+:105D90005F40BCE878FFE5C0F47B45A3DF2B91E8CA
+:105DA000177EFE74BEC5FB6B6C7FAAF8D02A7415F3
+:105DB000C3CF9D86D3B54A6ADA88AE78E29E2F6853
+:105DC0009DD1E9367A852B411A64A0E3EBD8EFE840
+:105DD0003D5F98105E9D7E4F0F90EFFD070B5FCFEC
+:105DE000C2C74B9CD391E28DB4FE60102E2158CFD8
+:105DF000B5E6D1F8834D3CDED3BFBD10713ED07FF8
+:105E0000E6A5F2307355DE2FE0FFFD50BEFF10F126
+:105E10003F2222FE3F46BC03FE3FC6F65780FF4F9F
+:105E20002E857FDDAE2FD3F44219EE2B01FFFCC58A
+:105E300039333113C62D1415E2FF255B456D1FD292
+:105E40007D5B7262508F2CB9BE7A9F19F870C9B30E
+:105E500002F16991765EFD73ED5C4B785E5FF11C3B
+:105E60001FE9C9CBE7F7F9490F956D333EBF10E441
+:105E7000DB74CAC7F5F1F393A22617E1F83FA368D4
+:105E8000FAA228D6D02E9C0E43AA4D863CF0E429D7
+:105E90007DFD909F976472BE4FF1B53F9819C6077C
+:105EA000DC52FCF800E263BC3015FBCDD7E456EFC2
+:105EB0006FE80AE33A9FE1339EFBCB6A349EFB1BFB
+:105EC000DE9462687FCD864CC3FB91FE6B0DEFAF15
+:105ED000DB36D6501FD57283A1FDE8B602437D4C58
+:105EE000E01643FB7187671AEA13DAEF35B49F783F
+:105EF0007481E1FDF51DA586F7377EBACC50BFA9A8
+:105F0000F75F0DED038BB85EDC5F939486E70A7450
+:105F1000BCEC5F2A9B547CBE34DBA4E6863E4F7407
+:105F20003B73B1CC73A37F3590BC4CB126A785AE33
+:105F3000CFF9CC6CD06B53ACC67A8155E39774E043
+:105F40001720FECD56A35CA556CF6B02B39BA52CA4
+:105F50001946F9D2205FB758B97EBBC57A65FAED0C
+:105F60004E6C7FAA3240E7ECC3E54B44F9CAA2D29B
+:105F700047FBA9CC45F9961B6D463E4D1A40AFCC68
+:105F8000B31ACFC38BEA619B649013FDF9F9A8D0D3
+:105F9000E7C2E2DB286F67A07EE5A405B76E017D4E
+:105FA00029277BA9D49FAF9A638A9897F790F53BEE
+:105FB000FA491BFAD94F0F217EBB92DE7E0AF3CC41
+:105FC0002AE7F592BF946C31E22558770DE67954B3
+:105FD0004E7E8E50E5FFDC54D3782BAEF7FA3C179B
+:105FE0007D303311F303D206F09F5ED5E6F15C4DB0
+:105FF000C9AD45C3B03FD5147ABF457AA0AA10FDFC
+:1060000098A15A1EF453A6C8F94A3FD5FA198C0A2A
+:1060100014ED035521FBA0ABF8238704F3F8779325
+:10602000F7A7C8170B46B7E7F173CB6ED74CB2ABE7
+:1060300054825FD743E98AE729D42BE94912736672
+:10604000F48767F03C6F6306BCAF8F33B914AAF7CF
+:106050000A389EE5C78C0D82F1EAFF5B24F8EAF767
+:106060005F4FF93C16A59AE2A7FA3C99B6DFAFC795
+:106070008BCF26CD8A413CD65FDB776E8761FDAC46
+:10608000E26DC77ECFAE37D3B8F50582E1BD3E6F76
+:1060900069C31D741E2B5DE1F32E867923DC9634D3
+:1060A0000E57FD73024B23B8FEF7D243E8BFEC8ACC
+:1060B0007661BC0DF0B189E8EDCE3867D2270FF3D9
+:1060C000AA18A434AF21FB25B21FFA9695AFDB4C7A
+:1060D0009D9588F654F23546B8C5F566F20717C5A2
+:1060E0002A94AFE0AF59A1D1D538EF554933EF9C91
+:1060F0000BF0D4BD23324CFD7176342D3D04DF15F9
+:10610000B746BBFCCEFE78EF72723801EEB7106E68
+:10611000714321CD9BDA21DC3F17D83319C877DED4
+:10612000E944FF1413C37D9770F8FFD3CAE3C4EFAB
+:1061300058559A879C547CEB9641581691DC1DB5B6
+:106140000EB8CE7F68E5EBFC87D608EBFCE5EEFDEC
+:10615000289FD37E084BD16DD2ECDAEAEC507B1944
+:10616000F4D649EC57AF8B313FCEC57E07B6CB3C5A
+:106170004DD91997B7CBD01E43FED3EDB1BF5A8D81
+:106180007664889EFD4AD3B35F5DA19EBD80ED4ECF
+:10619000DD1B8868C724C891F5DC381BC77F952AAA
+:1061A00033CAE31B209E9F6D8B6C1F0EB40E5DCE19
+:1061B000CFC88CD6F954D7EFDCDF60C532ED2F9C09
+:1061C000D9E07F241BF729E38751DEED40FDA4AE23
+:1061D000F8830DF1ABE36D88CD884FC0A3D3C6F92A
+:1061E000C4698B640F96031E4D063C0EC7F603D997
+:1061F0008357ADDF4B8CE76EBA357C839E9771BCBD
+:10620000AEBB3ECEC3B845E5EC73A4E7AF7A9C398C
+:10621000C67544F7BF611C01E7DF7DD77F6B71B79F
+:106220000E8A17D5BD7A4D0CC6A72A0AFAF48695B0
+:10623000DB8599A407BB7659DC0867571CCFE7ECD0
+:10624000DA35F110C6393EAF399C2985D82D5DAFBE
+:106250001CC933437F5D3B8FE4499420E7277ED1FF
+:10626000DF575CFCCF3C8F123C27D0C76F56BE0E69
+:10627000ADB7F1F8C9D398C7369AB1F7A363F9FA65
+:1062800091687A1C9F47BFE3F3A17E7F5470E5C7F6
+:10629000002B26DD554C66ABE58DA600968F0A6E69
+:1062A00011E355BE91FC3C4D52161B9101FD284750
+:1062B000DB03088EA3A3D78DDB29EAA7EA3E2C0BCC
+:1062C00014EF02C47B5CAF2B097DFC37878DB3A133
+:1062D0005F214DE17AB7777E941FEF294A34B98F59
+:1062E00080AA67670E2F8CC5F77F8BE6F2F258D233
+:1062F00089265C8E7039A038D49B665ADF960D7162
+:10630000272F82EF974D88E77EE905987DC839965B
+:10631000C7E367091407B9007881E714FA023EB5AC
+:106320004BCC173316F4B089B955F00BEC9342EE11
+:10633000D9C1FF6876FC604DFFF6384D3E33E0452D
+:106340007619DBD509EE0C5C4F7781FC0D03FAB4AE
+:10635000D558A97CAD464D1806F2B8A72689EAAFF4
+:10636000D738A90CD48CA0E7FB6B5C548F36B5A74B
+:10637000D37A2C55AF9B87FEF5FD120BBDB723BC1E
+:10638000C47B568E87C8F9972EE69300AE2F353D15
+:1063900052FBD638E2AFA7C600D431FDBFFFD98A81
+:1063A0003F644D053D98FAA3C35953418E9F12781F
+:1063B000FE021E188E742E552F9F32B7C4A2A9F06C
+:1063C0006B1BF34D4DC2BCC8DE3F158E61CCF6E8A9
+:1063D0009FA64E1D09F3C7FDFE14C6F6DADEABC755
+:1063E00073D8A9FB3FAB8B81F9C86DFC3E9F8982B6
+:1063F000A756407D339BF30B933CB598CFD97337A9
+:1064000073E2FEBE3ECE5E1BB71376DBB89D3951FC
+:10641000E0FCC1E6CA5A1E416F6EE8BA11DE3EEFDB
+:10642000C0D7748F0F8CB72FD5305E2FC51107FAE8
+:106430002E75FFD7B48E5CE9773D1F49FC7C84C480
+:10644000F32BBAE6266EA6FD78681FBA8FDA2347CB
+:10645000B6D7DED2D68106EDBEB79F65F07283A6B1
+:106460005724C6F5FF6BD105BF47B961DE38DA5F47
+:10647000AAD3E209933A7AE5F9767E2F5C3ED413EB
+:106480004E78043C0FD7A5D13355601ECCFF486031
+:1064900033840228DD36CFDBD84FD2C24DBE97D130
+:1064A0005ED86571A2D9A3E3ABEE03D98AFA216164
+:1064B000CF31DA8FAA133A64A4F7978F7C4D71CB52
+:1064C0003A737532D56D171BB0FEB4BD7A23D699D9
+:1064D000EFEBA96F003F0CD6CEE1E313D463BB9082
+:1064E000E829583B57EF067ED865E6F52F1F394B54
+:1064F000FCB1CB5C3D9F8DE1F57A98EFAE586FAA69
+:1065000009549052FB65FDE19BB0AEB7FF92DA777C
+:10651000DB546E3F2ADE0CA47F5F5D85BA3DA42E5E
+:10652000F13AB3F2529F5FC581AF297FB8720FE78E
+:1065300047C41BCE13EFCDC375E98C7AD451EBA4BD
+:10654000B87336D7D701039FE9E753B798BC2C2A15
+:1065500044CF5E085BFF42CED9B1A88490FEB43828
+:10656000763A03BB342B186FCD642E2A87310F95F2
+:10657000D9DB96EE47B42DBBAFD5897A2B3ED7FA3F
+:106580008097E868F41F9ED0F4E2FAE8FC1BA301B0
+:106590009EF582778D887AF165B34AE72F3A24B267
+:1065A000373BB5358CAD3053BD5C3BF76D5EE95D77
+:1065B0003312F5EE2293AB19D7B30C4FBE19BE2F91
+:1065C000DB9DE1AA65C1BCE7B2D896C4B14A30EF01
+:1065D00059AF3FAAF1D946B5C986F7D2E8FB439532
+:1065E0006DEBD2717FFBB37D1F903CBD1F95417C4D
+:1065F0005CD17A44F6DA69BF4CC6F3299FD9FAD642
+:106600003F5AF7BE6C19740BEAF52FEB4D74B8794D
+:10661000203DF406E83F3738C8876AAC54FEC25DB7
+:106620007D2D9ADE055129D36C60B4BF90E9569157
+:106630008FE6ADB9A6C10A7CF482AC8E443E9B17AE
+:10664000954B7C5B162B72BE64B907DD92B6CF0DFD
+:10665000F5D43565D3BE533CBEC8686F546D5288BF
+:106660000FC00EC8473EA8DC60F2E17EA2C9DA4E38
+:10667000E77DE74531CD8F369E4F5CAFE93BDF6C60
+:106680001EDFBDDC39C592F351741E51AFBF1FE54B
+:1066900024BE28917CB4FF5572DE41E718BFFB3859
+:1066A00056C379C8FEE32804873E4E79701CD25742
+:1066B000E51FEC273FF88D6B757BD64D71ACE53B44
+:1066C000B4FC059B7B30F6F3B4A62718FAB18077AB
+:1066D00029A3AFEE9340CF1CECD333F90D53D390E5
+:1066E000BEC1F76C92410FB925A0D3C128ADEEFB16
+:1066F0007EE4F65161ED33F5FACC86A993FBC3F342
+:10670000B42D58B7427BE91B4B5F1DE1A373F5A184
+:10671000FDC5E9E3DF4BFDE9FC971AB5F0A00FF8E2
+:10672000EF60AC271FF37C7A673327CAE166498D97
+:106730007285D021358AAF3725E7AF35E03F88F73E
+:106740005C03FD4FD5380DFB8A8B8B96D17998541D
+:106750009D5ECCC7CF776DCA32EC27FE7F38AE1670
+:106760000EF700704CFD07C331C2305E108E1C0363
+:106770007C570B87183B6B7A06DA6B8F98280F28AB
+:10678000D1E4B366A25DF66F268AA70C673C0F883A
+:1067900029E30DFBB4997B2CF331FE9E29B1C3D2C2
+:1067A000589427B7B316D7A99F48645FC173AB3914
+:1067B0000E876E72E3FD4F2095D45F66B9B7821FD6
+:1067C000F2E6FB82FA3ED37095E5E3BDA09BA3E71A
+:1067D000DF188DFB66731EAAC23C98E795F12F3532
+:1067E0003083BC921DD2202C253BE3ABA8871B70C5
+:1067F000BF767014B75B04F670C3E1E448EFB9BC30
+:106800009E5BF3F0348C1B34AF745E8BFE53B3CDC0
+:10681000DFB21FF3761E53E8DED6AC47FD8D9950EC
+:1068200017D79968BD1463FDDB9A71DFFDC96C173A
+:10683000DA11CD68BF60FB4714F26B56D538D3F040
+:106840007E923A6D1DD8B276B28A79C1F58A1487E4
+:10685000EBDD2A73F55C3C7731EED18D0DD6EB5133
+:106860008FB91A07A9BC9E948CEB9A33D33A467B16
+:106870000FC868AE75A6A8B1C1FAF06FC0FA203D86
+:10688000B3B1C19D86FD2E2BD5FA3B88718A17E2E4
+:1068900034BC68EF33FBF4D2C606CCCB126B83F565
+:1068A000A930DFADCF723D3518FA47FB0BE6E3C3E5
+:1068B0007B057B874B744ECA06633B607EB691991D
+:1068C000B4DFD70C7A11EF2BEE1DC9DFEBFB34F2EE
+:1068D0007013EDD3607B5C6F6CC9BCBD3C83DF572C
+:1068E00020DB158A37C07A3015F39E14A6FF71F3AA
+:1068F000B8A4B68F1185F70184F0A375ED323AF78D
+:10690000691D66DC9F97D38C75897916A0BF27AA6D
+:10691000C6E737466BF94183580ADA6DC34D3E131B
+:10692000B61BC9FC545EC702648F8D621D541F8D57
+:106930005E63161E5B72D241AB71CC2DF238AA4752
+:10694000443B3171AE1E47F24E41BE74476B7661D7
+:106950000AEF3F7EC62CCAF7F569EFCD33863D318D
+:106960000DE6B57EC6DDCE50FB4E5F2F75FBAD4804
+:1069700083F9CB6821A2BDA0DB7545365E4F98E553
+:106980007E7A14C611DBCD26BC9FAD588B63166F83
+:10699000C84F44BBAC68DF5CB287D74473BB6CD1D3
+:1069A000FA19B277149EF79A4F767FFEBA0931181A
+:1069B000A76FB0B962AE47FEFD23BFDFF54AEDB168
+:1069C000E6C46B0A501E9BC1AFC6FB8F0E9ADDCA90
+:1069D00018E48B75C3C8CE6C8EF2D6C742BFCDFF0C
+:1069E000EA74D541FD6736F7F823384E43147F8F9C
+:1069F000F726216FF6EDF73F2F5C8C1E78FCF0FD3B
+:106A0000FE83B191EFF1BD43C35FD0FEF090DDD9BD
+:106A100060F6C4DC87F0BDCBE779D6EA89512F1147
+:106A200067FBB486E70376D6B85840E6F7D162BD77
+:106A3000A4683FDDAF5CD22250DC7C096B223D3A7A
+:106A40004C89D5EEA731E6C59616BD4DED4B5B7969
+:106A5000FB32D642ED757AE1BDB501831D3ACEF029
+:106A6000FD1DD1DC6FDDAC781F43FBFF9119D9C44C
+:106A70004FC06711F32DE207D877B9319AAF1F37AE
+:106A800062DBC8F628F163B87DB85CE0E7B307C203
+:106A900053D57993613D0ADE9F21D37AD4ADF9496C
+:106AA00087937CEB6F84F97F9FF54A24A7DABD2397
+:106AB00075825F42F9FABE33ECDE1B2D0F68BAA671
+:106AC00025FE43CBEFF93E6B79C30DFDDCCE02F41E
+:106AD000DD61ED9E1214A4487919D0AF411FDC3A54
+:106AE000C258BFDD65ACDF3929F23D7D6B6BD4B494
+:106AF000D07BAAD60E708EF32D8D5E577FDF120BE2
+:106B0000CFEB7B0BE95E81F994B47FC1F3FA141BE0
+:106B1000F3A01ED9BFCF46FB21558ABC1943165599
+:106B2000E0EFE2BDF08A9D9F3740FF17E3058A99A9
+:106B3000B70FDE97C4F751123C495A3CC3953463F2
+:106B4000D4B7871BFD2ACA0B96D846DC770DE627FB
+:106B50001AEFEDE88AFE380FFD6398CF6C8C4FE892
+:106B6000715A7D3EFF287F2C5ABBCF399C6E6B3407
+:106B7000F9A80BA3733DD23907DF73B9F952BB876C
+:106B8000FF29C143796889261E17ACB3B98E529C80
+:106B900044F30FEAB4B806F37D5DEF56C2EC9510EE
+:106BA000FF227DEDD7F5F539E477F338882D6A15A6
+:106BB000AEC30D36BD6EA6FAD3E6A600F9FDAF5AF8
+:106BC0009C181F83EFDD1867F3CD1D417E5D5D06C8
+:106BD0004BC17B0EDEB0CBB4FED6BD6A69C6F5D81C
+:106BE0006DF376DB42F249BAECEFD1F9A608FDF974
+:106BF0000CFD0DF976FDC1F8AD8877FDFD1BF6A7FC
+:106C00000222FFCE49F91B69ED1F7BA19EB8CB4242
+:106C1000714FFDF70FCACFE7D1FD8C7A7F13144E69
+:106C200087CE1AD5908F5D8E7A3707E5A09DF467E1
+:106C300045CB2083DED4F569C5F91B68BF2C4857C6
+:106C40002D2E21B5935EAA38FFBF68BC3B909E34C1
+:106C50004E12E9F781C74935E8E3E038930C70F745
+:106C60001F6732C1A18FC3DAA20CE79FEBCC3CAE09
+:106C7000726698332636821ED14B7183C970FF60CD
+:106C80009DE4B262FF75CA4E35347F287C5F00EF09
+:106C9000C56421F0D5C17A86C1720BF3525E403DC6
+:106CA000F6132207A2D9A562BF62C2F8E9F92EC67F
+:106CB000FE45B9BD107D7233F22DD88B3F583B7E17
+:106CC000950FEC49C9EC6947BA4A769313F3686BA0
+:106CD0001513C545EB92AC64FFAD12CA559473BD54
+:106CE0005FA9432238F47D8F81E6299F77D03CC38A
+:106CF000EF3BFB9F1B4FA176FDEE573B30D7930F29
+:106D0000FD5B54930B455D4E53D82721F40FEF479D
+:106D1000DA2045EC27BC9D8EFF01E96CEE70203D2A
+:106D2000BAE3A58879101B95EF9807312F4C1F27E0
+:106D30001CCD0EE0F74287232383F4E54605F5A535
+:106D4000FDCC9FDC4ED2CBB4EFADAF7FE684A9562D
+:106D50009E4F6CBC576F20FED3F1627DF341C6F3AA
+:106D600053BD947F72393C4882CB43FB007629E2C5
+:106D7000BE36584286FC384931E64F35481EE2633C
+:106D8000F34DD556DA27495B69C57D92D592330616
+:106D9000FDD8DE37C1FE83F9353A79BE6A78FF6BDC
+:106DA000F01E66B4731553C4FB79A306B0AFBA34B2
+:106DB000FAACD97769FE01F5E1C175372A4E5271F7
+:106DC000DD359B39BC03AD4B7ABF03E1EBD17DFCD4
+:106DD000F71B2C39563FAEFFE1E3354A1E4F3EBC50
+:106DE0006F047870DFAC31CD4DF86D542515FDD5AD
+:106DF000E81151CC1AEA6F65CCA2F767E2E3F1CC57
+:106E0000226B8C8F9C97A3E369B7F21DED1D6F1861
+:106E10005F0E7F8FE2E8217CD9A94CE8CF97BB9128
+:106E2000171338FCA1F7A65A338645BC7FB21F7FE3
+:106E300086F14DDE6446E7F70643B919FA6ED5EEE2
+:106E400043AAC0B50BFCF4F27B14A6C2FAE677E4C1
+:106E50005F4039C96BDFCFCFD1B426F07B1EB5EFD1
+:106E6000C3C75D62E7FEC812BB4A65CC51F72FF17C
+:106E7000F7375ADBA39C785EB1352EB21F9363D7E8
+:106E8000F3689AB473081DB44FA1B7CF9BC7DCCD8C
+:106E90000AC53D1BADE07F25F4B5FFA9B63F0282D0
+:106EA0000BE3DCF9DBEB9AF9F9513E7F8CAB62FB2B
+:106EB000C4C48E5C41FC0E74DBC60CF7DB55583B3A
+:106EC000B251CEE79ABC997618A7EA684722D65BFA
+:106ED000DF3E9D4E7E6F1DB7377B774753DCA03F6B
+:106EE0007D6AF979F2F329CC37A83FDDCAA500AD58
+:106EF000ABE5E7D3996F1CCDDB678D0BBEBFD3C26B
+:106F0000D8A4B1C8001C4F889F48F430DB4D067AE6
+:106F1000803C5E67D7E88178EAA3B776EF4BA77627
+:106F2000BFE071CD5F612AF7D7F5FBA58E67F7E566
+:106F30005BD07D5BE536F713784F0B3B2252BEE604
+:106F4000C229FCFEC48516770CDA570BFF53146A6E
+:106F5000697F93F3FD220D7F9DCC45F70EF8D6DABD
+:106F6000F8BE4E987F96F154FEB83FC2F78BDA44D4
+:106F7000CA1B5F3045F161BF79ED05BFC4FDF9E281
+:106F8000C6683A77BEF07BAE9368D72D7CC2E6C464
+:106F9000DF7B59FE41667E32F4BBFCC90CD507DFAE
+:106FA00045AFF024595DA0271FDB53887E45833011
+:106FB0007FBE3006FCCAC70EACC2B898F4CD94CFE1
+:106FC0006D507FF4B1775661BCE9B718E7263BF600
+:106FD000DD42B4635F42D0F4FD3FC0C14B874D5AE0
+:106FE000FDC4AAA9A0F2AF4D6835292AFA65275633
+:106FF000E139D9C438F718138CF78EFDB342EC6F22
+:10700000C113A3CE6D80F7E7ED17C8BE003A69DF64
+:107010000B374F01BBBB78B25E972D588F8F6686BA
+:1070200038BE3933383EDAD9AD7A7C8B45DD8C7188
+:10703000F7E305D55324E83FC3A1AECE19C9D8C4A0
+:10704000F5F9AA1BC6CF76C4DD8CF198D6BE7D8338
+:10705000F8D5181F6B65DE0366787FD3E3436EB601
+:107060000262E30779C6A830FF41D629ABA7DFF457
+:107070001DE46344BFF3590DF60492934388D2F4A0
+:1070800015FCDEC23EF94EE37CDB571FD1C1CFC3F6
+:10709000E8F5245E6F5D19595FDC12C3F9BA352A31
+:1070A000F2FB664D3F00BE03147F6D8BF60FCF08D9
+:1070B000EA0F901FEB2492A7755C7F801CCDB493E0
+:1070C000DC46ECEFDBCA6BAB76AF79ABE48EC6F88F
+:1070D00082AEC7308286E3CCB53B0DFA39AF7D0175
+:1070E000E9D751312A87C7C9F19330C5A84798B568
+:1070F0003D3B74DFFE77DA3C33AED3E33F013974B6
+:10710000DF69F98EFC4B9E9F2DC7387F88BD1D9C83
+:10711000C7548A67F4EB17FA736AFDBB72AE045F5B
+:10712000EA65F0154FF8BADC3C83FD19E32FFDFB4F
+:1071300093B57DC126E33A224786F3A4CE27807F0C
+:107140005388FE2CD6F4A99E07D1BD6B24E54F06CB
+:10715000C7E5E73181BEBFC4DF5DF2813E453D96A4
+:1071600027B96FC5F679ED712ADAEFC06FF51ABF4E
+:1071700049C86F3A9D5BE3AAF369BEEB04B24BFAD0
+:10718000D941DA3A9AD724D0EF990D9EE715E787CF
+:10719000C0A7EB7BE8BF55EB7F3CE7E767FBF8F95F
+:1071A0003E941FCD9F67AE0EBA5F3D1CFE852873CF
+:1071B0000921EBD5AB368AEBEB78BB5AFED7ED85D0
+:1071C000F201D725077D37F868C0E184768B511E20
+:1071D000505FB57C42F764B6B6890C7FB200E78D8C
+:1071E0007A234FD793BE95870A24B25B827AD94916
+:1071F000F68BAE3703566BB0FDB9B52B0BEB51AF29
+:107200006AF7ECC78BA0C5C706E1487370BB7792DD
+:107210009745FCDDB81CBB5DD723348F8D2B0AE866
+:107220005E852A6D3D9DD4E1A3785334E27142100E
+:107230001FFA7A7DA7A5E315EDBC97811FF53AD813
+:107240002595A6AC60FFF87E6608DFE739381F8415
+:10725000D3E7BBEA27C0830FF1F0430DEF0950C716
+:107260007B2D9804EB17E6FDCC505C6B3242E05668
+:10727000B83E4E104D5C8F5D462EE20731EDF7585B
+:10728000EC24CF417C70BBE5018716E7D5EE293FA2
+:10729000680239A17D363ECFEE5DC9D4EF6CADDD1D
+:1072A000DF4B2F6FD6F296747BB1E2B5D4CD46F8A2
+:1072B000797FBB1C1C2F7947DD63D08E19EE515CA2
+:1072C000E81FE4B5CFDC8FF924D97BF00704827C7A
+:1072D0009EDDC2E514B84BC3CB9BDB43FBAD74D83A
+:1072E0007539FBBBCC23FB28E757A4CB7D21725A11
+:1072F000E35038BE607E16C4A764D4A37AF9F7833E
+:10730000C3B31FCF2595033E506DEB786B6D99BFCE
+:10731000D286727C94B9508EBB5BE69B46215D3170
+:1073200011CC19A21FD6F379E87628F0650BF2E5A7
+:107330003AC7101A6FF85177740EBC1F8E7613C6B9
+:107340007D5BEC7EF423FC0EEF2E07E27356EF1408
+:10735000DC4FAD8CAEAEB5853CEF6BDF06ED898FB3
+:10736000BD22EE1F953FC0F8BDF1DA7CA0A9CF0287
+:10737000E355C820A759540F20DE5A65DEBEF73EFC
+:10738000FAA5115629F27BF960FDBE95F8F36D530D
+:107390001CD217FD24B493CB454F1AEE7BB2C11615
+:1073A00017AE03E07710BF1FB431C906FDFF1E4AB8
+:1073B000D4D3D3C4A5748E6B5A9640FB44BA7F8F46
+:1073C0007A0BFDA43BBF174DFCC82E3C380CE3D311
+:1073D00009D19C4ED08F55EBC76A1D1B94BFFF4847
+:1073E0001F49FE8EBEBE1D1404EAE7E04DD735D717
+:1073F00085F841D81FEAFF83C28CB4A5C8FF9A1F45
+:1074000047F6617C70DD457B65AC21CEE6D3E0EBD1
+:1074100048473E0AB547D13EEDB3677DF357DF0CD1
+:107420007A76E2F496005E715FCB8A6EFE17E86FA3
+:107430001AD8B336C0C33E8D2F0E66F844DC4F3DDC
+:10744000385CA0FBDC0F457973AA95E038895A5C5B
+:107450002051CB334F8CE2E50F62B81EFC3C86AF67
+:10746000D737A8BC9EE8881C4798ADBDFFA989EB1B
+:10747000F735F991F3D14F68FAF5AAEDDE1C21FC3E
+:10748000BEEE138E09DA7DDD946FC7E3FD0B34FE8B
+:10749000063B87E814B4ABF87E9D6E879E6D9F4DCA
+:1074A000F51382F7BD7B042C3D4F909FF4AE48F15D
+:1074B000A1E2586F22E6A55544458ECB0CD2F0F4DC
+:1074C000590DA338EF29DCCFCBE6BFB785F5251BD7
+:1074D0009EA47B1D4A999FE2BD451B1A68BFAEC89A
+:1074E0002F30A780FE9987C781353A946E110D71B0
+:1074F000E7C552B51C9B13E45BFC1DAED0F7259B82
+:10750000C619EA576F971618F23B827AA790ECBF1C
+:10751000F07E753E0FB74F8FD7380DF1EE051B8605
+:1075200017F2CD78DE7E2173D17C17366619EF1104
+:107530006E4CB8B27B82C11EF545845326FDA83F30
+:107540003F0EF8F785C4F7177C3A8CE0F88BC37BC5
+:107550005D8C018E68E633C4CF26F3DF29B4F1F8E1
+:1075600023F08FEF5276407ECC77F507AE1DC01F1B
+:10757000C8FD87FA037993B9FE654D02E5E04C9C9E
+:107580006AB4CF66C7F0756E764CB4C13E2B9A676D
+:107590006C37576B37576B77B9384AA85D2664A1AB
+:1075A0003EE3FDE9BF1F9571FA6DCAFFDC10C3ED24
+:1075B000D79FAA6E6F0CF4BB563B77D06FDEDAEF25
+:1075C0004AAD35F7E585525EE0E66F1EACC3DF09D4
+:1075D000E9DD01F63FE8C1FC67DFA07BBAF4EF6E9E
+:1075E0005FD132B408F054A9C973B98BCFAFDC15A1
+:1075F0009087413F29E51CAEB4967D8214F25D5A16
+:10760000096FB722C66CF02F7FA2D5FF35C649653A
+:107610005A49401806ED52366D1124EC0F7F570B76
+:10762000E049A966FED0DF934A19CFED9ADBC76F18
+:107630001616E604F1D0689A91A3625C3531DA85BA
+:10764000EBCC47AAB70EF150FE5180CE494CFCA8B6
+:107650005D42BBBD5B75D7237FEB78708A6A0AAE4B
+:10766000A3D11F71389BFAFC62BEBE30F6A86647F4
+:1076700037EB76E961C6ED425AA712578E30FC3ED1
+:1076800061629CB64E2432EF4E85DA3732A227A3D0
+:10769000F924AECC6EE6762CA7F7B42CCF167C3E40
+:1076A0006DF0C8B178DF47D6DA8084BF3BFEDA26BA
+:1076B00053C4FB519A35FCC33C9EC5F9E9F3B89C11
+:1076C0005ED0DB9907884FE8F2103D3DB2DFC1D8AC
+:1076D000E3F43EFFD9F87BE9FECA7A997E4F4EC7A4
+:1076E0007FB7EA6941BCA6B46C160837DA787ADC51
+:1076F0000E9FA35C1E978DE73A0794FB153B8716F8
+:1077000085CA7DBD4CF4D91C96E7AFDBF77F88E1D5
+:10771000EBEA9058CF3EC44B65DB3A8AEF2CD9C2D6
+:107720007FF76740FC5C21FE8412EE0794CFE1FBFB
+:107730005EF9CF4A44FFB27AFEFBACE5DB77F0B8E6
+:10774000CE8F990BF54379CB0EA128077F0773875E
+:10775000B028049FA9E57ECA83BFC6AECB1FD75B06
+:10776000E1FC8E7162B4530ED9B87EE8CC577CB878
+:107770001FDC69F69663BBCEE46817E677E9F8FF8D
+:10778000FD8E9BE9DCB57DA7258065A3A939C98A53
+:10779000FB0ED7CA2EE4AB6ED57B12E91327795ABC
+:1077A000F1FBD878BBAB16BE755AD85855B9723CA8
+:1077B0004C0CE38F893FE67293A43AF4BC86B12463
+:1077C00037AA9DEB2D13D76787CC7C1E3B1987F713
+:1077D0000731EEB3248787E368DC94F2009D1FCA6B
+:1077E00038BDD370CE30C85FEEBF7D1B7EFF3F2C0F
+:1077F000A14B2800800000001F8B08000000000043
+:1078000000FFD57D7B7C54C5F5F8DCBDFB0AD90DA6
+:107810009BF73BDC100C28246C9E0401D924848740
+:10782000206E0228C86B7947926C02D2FED0FA6DA6
+:10783000168331E56B6BD41645A92E8896B65A830C
+:10784000A2060DB82822D64723A58A2DDAA5202224
+:1078500084641BFBC056CB6FCE9999ECDE9B0D0F59
+:107860006BFBF97CE18FC9DC799F73E69C33E79C65
+:10787000991D33B5CDA88C22A4A69A38BC342DFD11
+:10788000E90EE98485900BF06F2221836C3221F19F
+:1078900084A43CBD4D522C58BE7F5A1CD6272605C9
+:1078A000BE4BD8AE8696AFA0A95B22848C25E4A0FF
+:1078B0008178CC3184B4E82A47D968FD9684487B26
+:1078C000132D3B667345DB687F96639D07ACB4EA76
+:1078D00098633EA38BF64BDAE9C76442DE3012129E
+:1078E00041DB1D8C60EDD36D74902242261B89070D
+:1078F000BF1B3D2314DADFC1A183B0BF97B7EAA64F
+:107900007A697BC320B2D81932EF749B0EDBA56C69
+:10791000DD21E9E8F7B8485A1E323F51EF015B59C3
+:1079200026CC67CCD44E8443DD563DAEA7C2E81CBE
+:10793000B66654B0DE68E88FD67BEDE64F8C7EFAF3
+:10794000FDC72FBD6F2450BF5572B4C1FC5BDF373C
+:10795000CEC9A1A9E7E7324920643A61FF36BFF0FA
+:10796000BE51A1DFA7EFA670A2F5EA76EFD22FA352
+:107970006957A9C5238D2624F3CC6B8B4821FDDEE6
+:10798000662211746EDD3657918DCEFBCD5D530EA0
+:10799000495184589F33F92015F021C49FE1B40662
+:1079A000E725523A30CE2F722AFDB310B246EF557A
+:1079B00099F0DD955945EBB7C630F8CC1FCCE042C5
+:1079C0002CEC7B155F97800B1D7F0A8C5F91E5DCAB
+:1079D00001FD542446D89B32619EF9AF9929DCEB16
+:1079E000EC923D82568D2B67F00C9D57654EB87911
+:1079F0006DC0F1E263D9F844EFCF807109F1B2EFC5
+:107A0000326921F9C1F67338BEE9771FFB4E863A19
+:107A10007382F3D7E26F834DC2FA61E86C11ACA3B5
+:107A2000F698CFC7E8AC530F749679E630E243D0AE
+:107A3000CDCFB6EA3115FDD5D98CD85F9D4D8F706D
+:107A4000D90C781A4C53032C9AA61BCC5E0F85C711
+:107A50009BF3261F9272297E6E31FA207D43B7B4C4
+:107A600016CADF4861E3B7E8746B21DF729785348B
+:107A7000215E1D6E98CF6B3747217E6AE71ABD26BF
+:107A8000DACF8F9F9758DE63F112FA67AD6BF6720B
+:107A90006847E222EC4F02FE5C078C73ACFDE94ABA
+:107AA000796EBF51A1DFA7B7B1FD27F050DBC6E863
+:107AB0004BEC0701D7203CBDAAFD24F0317FB08DEF
+:107AC000D105A5178077CDCE08DB49331BEB02012A
+:107AD000FA8C56E5EBDB936D274704F335F007D0BE
+:107AE000C10E628179D6F279CED3B9EE83FD5567A6
+:107AF000F61F3450D4161F0DE07E1F887E6BD6FF14
+:107B00003AFB640121AB930E612AF6AD61A87A7F3E
+:107B10006FE5786F8294B67B82D34D4D611BEECBBF
+:107B20009A930DB89F2D53195FB31C238E503C13AD
+:107B3000F243BEDE7BB17D4564DB6499C2BDE27178
+:107B4000C9D644FACF4FA4AB24E26CA3FD7DB6F5B1
+:107B5000F5A82500DFAF2EC8A498AE3782AD7737E1
+:107B6000E73B5D3B29C091DE1B8C24CC7A2FB73FCD
+:107B7000E23B22013C6B38ECBB9E2E1FFB29A51774
+:107B8000CFCEC1F6ABE892CF3E3DEBF64FE9BCBBA2
+:107B9000764CB4CB40364D4EA49F407C847D3BA5B3
+:107BA0009F38994C9528DE37B4BD1E358EB6FBFC48
+:107BB00097A3F3816FBFCDF7FD99E7E5F50097BB7C
+:107BC0007EF6EC75505EE395624D30CECEC7FF95E4
+:107BD00042FBA9DE510F10264DBF7CD5E8A7F574F6
+:107BE000DE6DECFBCEC136A8F7F913F75F07F06E38
+:107BF0006A6BC2F2334F6CC3FC6B3F7B76DF3F682E
+:107C0000BD5A67941DEA9D797E3FE2A5D6A577C04F
+:107C10007A07A2EBCDBBF6337ED926E17E2373191A
+:107C20001F13742DE8F7F39F2D1E1B2A37C4F71678
+:107C300023973B83981C39CBF76F4D99A505D2B399
+:107C4000CF44CC85F5BA8DFEEC6898CF2846171F37
+:107C50007178D4B6AD31B82DD81EFBF980EE7B48D3
+:107C600073287D9EA2F44E6BEDB85000E3FD0AEB45
+:107C7000D37A251114BE372F382EC17C22473518F0
+:107C80006A709EBF64E574D5A1E5C5EB183D6AE94D
+:107C9000E00B9B05EB8B7D90B2BB324D413E60B259
+:107CA000333ECED69752ED6AB2D2EFD7AF73D965D5
+:107CB0008AC7974F1F9E9C4AF33F1B211520FE65E4
+:107CC00089C9398F05C7A95B5F464ED0F9EAA2D9A9
+:107CD0007E49B011FDB5C807B631BAD713BD05F25C
+:107CE000FA00F289BA162E0777B0791273206396DC
+:107CF00015DB59AE8D09CE83B6B358301FC8B829ED
+:107D000007E48E672ECA1DC588F33D23F801F1E410
+:107D10002ECC09EEB7041D7101FE138C34B5307EF4
+:107D20005349FB4F8F2E4D8A2E0AA6098358B91648
+:107D30004EB7F0F21F453B92A2015E3B6355F260E5
+:107D400020BEF2DACDDD4C6EBF721CE9D00D740896
+:107D5000E3BB4EAAE4F67264AE940EF71C473A5C9D
+:107D6000DECEF8ABBBBDD4B88CA69B253217E6EFB0
+:107D7000E6F4047464A7F99BA2A3717DEEEBFCD931
+:107D8000C0A7BA39DD75EF61F4F6864EE701F8BC9D
+:107D9000B17DE43690075AF928553B11DF6E8A6FA2
+:107DA00093047AD6BAC3A067D555133BEC57F76E48
+:107DB000BE1F1A08EE07777BE572E82F356E9A5DD5
+:107DC00096502F999C4AF3EE5A5204FB2D656BD9BD
+:107DD0001EA00BD22E91AB205FEDDC0DEDAF8FAB73
+:107DE000B3CB9920F7B6279969FDEB471463FBCD18
+:107DF000E94A29F4E7A920B627216F70A13CDB9C52
+:107E00003CD20EF2CEEDDA887A175106D9A19CB891
+:107E1000F46BA1BEDBB3806C92C2ECE33D9203CB6A
+:107E2000BD91DE08DA7E7A3BD37FDCED6C1F9F13B9
+:107E3000F011A9A173118CD7FD828978A4209DBD72
+:107E4000B9670A93B32F9A50CE9E6D749013543431
+:107E50008F8C5610AF028E35AD993AA05B42669971
+:107E6000601ECBF83C5A0D4C6E44733990752F9BB5
+:107E7000C772BE1F9647EB786AE4FBAF95C9059BB6
+:107E80002717E4E0393E1E924502977374E8BAE57D
+:107E90003EDC27B54FB3FEE24C8EBCDB42E855E832
+:107EA000475A7A6CE2E3A66C3D20013349D95AA5C2
+:107EB000DAE7D757135F3D5DE7F55B75BE89B9A873
+:107EC00037DD82FC7C83916C97FAF7774F34E35B64
+:107ED00015B1CE3C09E4D7CD16D43FFAF6E9208798
+:107EE0002E02F4B87CC9DE84AB7016EA68BDD309F3
+:107EF000563BE0ED471C8E5A7DABAFBD460F9CD183
+:107F0000EAC9254369E9864173019E545FB798A188
+:107F10009D8DB6A7F512B68F7B6213F2AB26ECF7F8
+:107F2000F6681BEB27D659D8002C2ECBB98EC92763
+:107F3000AB3DDC7AD2A3859EBD284F07F433DB82AC
+:107F4000FBE1C7AF484B19BD514128013DB2FD418E
+:107F5000E8FE7852417A443DCADDE0F486A747B690
+:107F60005FDC54AF023D9BD2E35AA6275B08DB4F90
+:107F70008C2E23A73279007C2B549F15FB54BBEF2A
+:107F800005FDF6EDFBCBDCEFDD06B61FBB291C8043
+:107F9000DEFBE8FC6546E79B36D0FD48CB37D1FDDC
+:107FA000D814C2FFB5E71F98279C0704BF3D66732E
+:107FB00076005F746F7FAB19C996F347F7CB3FC864
+:107FC000BE98DE6586CAB45F33DDAFA1F463A6E078
+:107FD000B6E663EA013911B95EAD4789F4836826D4
+:107FE000BFBEB1DE3842D2A3DEC3F155AB737D0014
+:107FF0007C1EF4464A1124633DD31B1340E600DE89
+:10800000B6477A413F4E4820AEE7C2CC673FDF67B4
+:10801000029FE2FC9010C5EAF7F27DFF29AFF74F0F
+:108020009E869C4B703F283AD771220F2C8F443B81
+:108030003A2F2C17F3E93BD798D97C13EECADEBE52
+:1080400029048FC17D75753EE037EB5E9F7EA925C3
+:10805000388E908B5ABA81F983FC81F5548E1AB808
+:108060005EEB7E7E3ED3D07104DF5F7BA8B882B426
+:10807000D5E0FB2BEEC7355602FA222507472C9D8B
+:1080800057FDBEE16C1F8D086443FBEA58D74D31A4
+:10809000B4DF3193F8FEA0DFABE09CA0271E530CA9
+:1080A000E0DDE0F587E0F9D318D67F8FD5EC91E9D4
+:1080B000FEB823D6150DED3D65C4EE03397307E513
+:1080C00027B06F89AF08F84D3DF147019CC7585D57
+:1080D000F13140BF726736C9A2FC57F2E7C2F763BD
+:1080E0001151B984F6F371FB6F9F7985B65AF8CABE
+:1080F000B985DF03FA7A312203E8E218D5973B51BC
+:10810000DF560683BEDD4B94C1B630FC57A40BCCC2
+:108110003AB3BE20983F66559F2F447A4D0CC36FEB
+:10812000FDF914E28985FE099EBF7B6214F65D1F8E
+:108130003082EA567F3E8378687F1FEB48755B98F4
+:108140007137C5307ADB4DC8D470E5F7F171760F21
+:1081500065FB30B04DF2027FAC5EBFE1CF32E50788
+:10816000D5EBAC3E4C6931E86FD5368F4F47F3C73E
+:108170000C8C1FD17FB3CDC541B947EBE9C7030EC6
+:108180003CF4204BF9E0522EB79635BCF925D813B4
+:10819000AAF5C43C9EF6B3DCEC3C984A8B3EB32C6B
+:1081A0008F02B6BFF23BB725805C4A5CD0CAEC3286
+:1081B00064920DF45EC93143BE1079313D4B8FFAA4
+:1081C00031E29FE2EB8B18E74CC0F782C104F580E7
+:1081D00005B7457A3D217CD0CCE1A1A59B4FB87E67
+:1081E000A5ED7F766C1981FE3AA29C73813E16DC68
+:1081F000764EC5CFBA25FF538F025DADB1DA9F64CD
+:10820000DD653843E8FE3B62BCF33AC4534F5E671A
+:10821000F6FA4CA0DF40C68760CFEA30D93C0A941A
+:108220001B11CFA2DD9F1A29E3CB0EE6979E1E36C7
+:1082300019E86B19B13703DE97B544124F083F03B5
+:108240000518E8C37D9E603F4B3BDE3C0AFCDCAD7D
+:10825000F7239D2C355B108FEEF37A9C0769317400
+:10826000F9457B8AFB23518EDB607D9E7BC6479F51
+:108270001A493F26D2EFB87ED7EDF0FDA1C828E21B
+:1082800000FA784BF60EA7F3EF352B836328BCEA90
+:108290008D940E4663374E7388FE43D2AC6AFC77EA
+:1082A000BCF525CC67B9D9650439BEC241CFA73228
+:1082B000E0C957641B158AEFF1F28591978FEF455E
+:1082C0007CBF7F6CA4F41F661FDDC7E1DF23EAA536
+:1082D000B07DF27106A97E0ED26B684ADB7D3C94BC
+:1082E000E7F3793E9BD74B60F91D7C9F7C9CCBEAE2
+:1082F00069C7F1C530FE363BD6B115E045DBF98CD8
+:108300004017FB22BCA8B716527E07FC6D6D3AEAF7
+:10831000AD94AFEDC07AD9C4178DF54C28574803FA
+:10832000E57BB0CF8B1484CFA6524A27B43CB0D79C
+:1083300064DBAE04F12AF0A9C5637B8CF4EFC9C3FA
+:1083400051923ED48E42E5617B0CB3A318617FD27B
+:108350009918999E360CF18574225F3EBE6E8C6032
+:1083600078A0FBF4B518D47B7D39A1FBE504C79751
+:10837000E0671F0F52E3B58AE3E16D5E6F518C8DAC
+:10838000C94F7B00F7DDC731AC7E5C169343420FCB
+:10839000FF0387CB4D9A54C8953153D5FAC54D1C70
+:1083A0009F37C54409BC7E08F315F288F2175F3485
+:1083B000DD0F0B5E35217F211B03D9B0FF68BD6344
+:1083C000586E0A2C8AA572E426AADF18F3B1DD22C2
+:1083D00068DFEF3C3F4AD08595809C3E25D65318F8
+:1083E000407E4FE51DAE6B29A17C43BA34FE37D0E9
+:1083F0003AC994D6870C56D8F94EA60302ED8F20C1
+:108400000AF447E1FEE750B86BC73BC6E9E09F318D
+:10841000921EF19647F2709FBDFF857521EDF29C8B
+:10842000CDECD151BEFFB8CE7501FAE9BAFD2DD41D
+:10843000CB8F197DD9AD9630E546DF630F49C1F288
+:10844000C53F973D46CA2F767776FDE466BAEEA51E
+:108450009DB21D865C7AE75FDF1D037A75A7C10EAA
+:10846000E7462ADFEFD5C3BC1B981E794CA7A6832D
+:10847000B3DF559F73D26219BEA8DE83FA9CE03B3E
+:10848000427EDF4A7C57815C5F461C4648FFB466EB
+:10849000D50C42E1B7C2B20EF9D1E76BA7A11EBC61
+:1084A0009278B07C598BE14FA1F26145AB3ABFEABB
+:1084B0006175FE56AF3ADF677F2E0F2FDFA7C732F9
+:1084C0003A3E4BD93EE03FB0C1E4053D485BAF9832
+:1084D000D7CBA43CB113F82495FB60475817E1486B
+:1084E00004BEBE6E6F69E2C5EC7CF5E7AF21DE101D
+:1084F0007D23A837E4126F6CFF7ECB63158423F4D1
+:10850000ABF071E0BC71B62CFC3A26C60A3D651092
+:10851000F627BE8B7E82E345E13CEACF9B07988F2E
+:1085200005DB9F5D197E9C1BFAC6B1A9E464B07D92
+:108530001C936BFC1C2DE8A3FE7C127E1779A1070F
+:1085400007DBA531FD8AA4D94E4506F994B0638BAB
+:10855000FD704222E664B43BDDCFCFEBF65CB05F4A
+:108560009F003D08F6E314659F9F4E71D9F7C666DC
+:10857000EB8706F78B761D94AECEF843F8EEB25833
+:108580006B1C8E6B27761857D0FBA2DB2B06BBE843
+:108590007CFF786779A26B54283FF530BF8951E89A
+:1085A0005F16959C251A39BCACFD2DD4BBA8BE9591
+:1085B0000D4CE7D3BDB723BDAF24CE04A0F39EBDC1
+:1085C000C3335CFF86FC15F399E559622098A79B9D
+:1085D00098EEBF2A3E9F591D4CEFD3991D061CC72C
+:1085E00041145B021EA5D97C29F3D4D3FC84BEF9C7
+:1085F00083918E90F17CFE12B4A7F09DC053B2D44B
+:108600009504F336C1B874BC08E24D82B469AC5D20
+:108610008174A2E4D4B379303C4F260D69505F6772
+:10862000F6CB6C9D740609D0BE0F5E98B7F2FCC6FF
+:10863000D9BD8B56C0778B15F98891CF63472CE550
+:108640008766E42F6658B7C9E2FB1CFD643CF594CD
+:1086500029B88F3D4309DA3B06913602E35A2CE7ED
+:108660003CB0581BB149908FB0F5FAE0FC70CE6673
+:10867000F1E846239FDC190B7C527A6725E085F2EE
+:108680006566FF19A85CEFC373B7E073317C7E4D5C
+:108690009CCF2513068758E2C0F11EB0AE9C414026
+:1086A0008459D649D07E4BD454F4EF2500E0697943
+:1086B000EC54BD8A6FC53BD5F9C4B9EA7CB24B9D79
+:1086C00037D3933FE88B92CF99742116CF5923C0AB
+:1086D000DE62E0FCA299CFEB08A4743DEF713EFD91
+:1086E0008DF513BBFABCEE8E3112B4E32598CDD0D4
+:1086F0003FD557DE8B65FACA271E289703C8CFF3EC
+:1087000026B6F9C0AED37C8364BF8B7E6FB62A1BBE
+:10871000F494543DD32466C7D1DB4AF5B47C5B8620
+:10872000CDBE89E6EBC17E1D0BF3B7D53C8DF64976
+:1087300013AB4702CDE08FDCB6C966837A71E58161
+:10874000C946D08B5710DB761286BEBFA2FB86CE01
+:10875000F709C853BC489C5E220F29F3710DBC7CFD
+:1087600007FC9DC5F2138BE15CCAFE6575E4753AA2
+:10877000C0EEE090512ED677E4BD6EA1E365CDCE7C
+:10878000433BBCB39CF97309DFF76334FB6A5C902D
+:10879000CEB13C8FE7877570BB6E9C89F96B6D74A9
+:1087A00088626636C0FA718CFEED44FC63FBF25AB7
+:1087B00012FC07FD9507FB473E3429581CDC677403
+:1087C000A87CB3BDA996D61BA3F7ED877D3C8EA7E9
+:1087D000793C7DA3F40694BF9D3A8B62D4B17D6D44
+:1087E000CE0213865306B814DB7ED004FD4C907C79
+:1087F00098664CBDBF09A65FC5ED47D14946EF0657
+:10880000BA8EA6128A67B477FCF920D8A5E5074985
+:1088100001E0E98841C839079ED3157A1CFB1A3A52
+:10882000986C40FDFC2F932AF03B01D58CCEBBD237
+:10883000C61621BE0F2C5F75283F6AE364E437B388
+:10884000A632BF6AFD5CB3579240CE10E677D2BB2A
+:10885000326F0AB197083FC4FB0632775798F3444A
+:108860006D1CD34FAB66303B6FFD46A3CA7F531DD3
+:10887000C7EC5E33E3268F8C4379C4FCA779715C27
+:108880006F1B4146009F0AE1234550AFABF4ED81D9
+:10889000F88CBA9CF399398E0203EAFD9CDF08BE7E
+:1088A000EE1CC4F6F33C42D281AE679306E4FF8728
+:1088B0004B6F457E7313F118006F1F95B17802312D
+:1088C000EF5953D57AD21CA73A7FF35CAD1EC5F0A1
+:1088D00021C69DE7529757093D78AA5A0F5EF0FFCF
+:1088E000BE8A46B99AF854DD8521E0E760F600C0FB
+:1088F0000BF373E8916EDC1B993FBCBE3DEF8D38E6
+:10890000D8677712BECF7649CBD1FFB24B5A1182CE
+:10891000FFD45AAF047264B855D87D98DEE4347938
+:10892000F783DFC359831291BCCEE3490E403C4923
+:108930007E90BEAD65561657411CB5309F345BA482
+:108940001DF4FE165D3EDA655BA2AC2A3BFAA60D6D
+:108950004A05D413F658C544F26D9C6EC29D77D774
+:10896000C531FEBA59627671CF3C339E2BE3B39C7E
+:108970002A3F41BC4C8E829D70649C22EAA3FD6319
+:10898000B3C1955C4053AF44971117D25E261BD1FB
+:10899000AEA8E14FF1B176B4EBC70FCE413BFD9CE1
+:1089A0008E3CB42F124B84FD2A29D8FF9CD9DBF4CE
+:1089B00010A753DFB14DBFDC12A4BB7BE2B85C8DC6
+:1089C000249140AF7D76BAE74C68A77B5CE7FC5FFB
+:1089D000A0CB5AA30FED7121F48ADF07928BAB383D
+:1089E000BD18CA9CF356D0F9F5BC6BB4C3F9191D78
+:1089F0006DB4FFE7F744A39D515F45503E6D2C6574
+:108A00007CA407EC5F741D9F4557E3F960A3D48AEB
+:108A1000F2A33B6632D2F16ACB013C07576FA574D3
+:108A200018229F56EF50E76B48279EDF6B9FEE475B
+:108A3000CFC817051F76EF56B723C3D47C378FCB2B
+:108A40008B7CA77D56054C7DAE3D8B9DC3E9418651
+:108A5000AEA3E81D23B7EF2EB09D8A0056FB947499
+:108A600031FDADC77A5A66FB9FC983223E8E566E92
+:108A70001571BDED3ACABFE0FC2AF4B022C2F2077C
+:108A8000741D72922E38DF42DE4EE87F424E087C23
+:108A90009596105242F743A7E04F43C950C037EDB7
+:108AA0001FF78904914331D8BF07CE7DE3F878944E
+:108AB0001E3C20B73D3AB317E8AB596A4039690606
+:108AC0003D9FA69B2417CA8397AA3D32C07B2C6981
+:108AD000983583D61B6FEE8C0438513A39124A3FD1
+:108AE0004DC497B14B52D111967745BF1D968E84D8
+:108AF0003CF37DC4F498E974C5D04F05387E687A9C
+:108B00004062E7C829961FEBA1FDDBBA69482753ED
+:108B100089570FF3ABB0A9F13F25499D9FA6F4A358
+:108B20000F8CC37070784E1FA12E77087E47D4FC3F
+:108B30002E937C857A18F9C1C1EF805D21723D19B1
+:108B400001FA0DD544711F6AE9E0EBB86FDD6FF2F1
+:108B5000755C18BF490FB7135F4BFC2B9F96FAD378
+:108B600059F71BEBE5A4107A14FBE265038B7F90A9
+:108B70005E65FEA9123319E503FA2A647645B13F12
+:108B8000AE05FA8C09D25D31FF9E11CFE96C081950
+:108B9000027436A13DC22753BCE4F1FEAE05BACB48
+:108BA0000FEA23E25CD154D28FBE32A52CD45F7081
+:108BB000DF097DA4406A6BD267021FB9A709E61BD3
+:108BC000424F43E38B802F517AC27DDA4FCEAACB3E
+:108BD00035F426F02EF4E552D28074365BA760EAB5
+:108BE000AB5C85F2B5DC325B0FEDDFAC62F43609CD
+:108BF000E8310BEAABE9A5DCACCE6BE9918EA80BB2
+:108C00001D574B9F03D1DB10A037215F632F4D6FA2
+:108C1000D3E3BF757A9B1E7F117AD3D299E05FBBF5
+:108C2000226CE5A03FD7574B280F0ADE1DD604F96A
+:108C3000E17599A84FEF8AB6A37E5DDFC0CA0B3BF2
+:108C40001D32C4BD64ADE3E599CE72C8D7AFA7E5C8
+:108C5000B4EBA2232C2E66D89DAC3CEFAE86D7ADEC
+:108C6000A0677858FB973F6F96A368B9B799B72F5D
+:108C70006D2D877C7D0B6BFF19F8A946437C9AB755
+:108C800009BE5F7D6FA69D1DAB99FE3E91AF7797A4
+:108C9000F4DCEBD8AE95B55B75D03C88E0F99FE984
+:108CA000E5D7F1754EDCCAD61977E2FAA90AA58B89
+:108CB00015010FEA6FA774B5C5C8DF06383F974A9C
+:108CC000AD69904EA1EC175287D9DE220F657ECC9C
+:108CD000ED74887BE299FD45F8FF20CEA032449FD9
+:108CE000B8279ED96345BD84188A01A08747ACA8E0
+:108CF0005F0BFFA4EF212281BC8735723D24ACBFFE
+:108D0000724A5603EA115386083FA55FBF948E9BB3
+:108D100077E18BC9E1EC433FE2E39EE671137D7A94
+:108D2000B237530774B10B88240580F4DEAF417F5E
+:108D3000DB057E4826A43CA404F0CAF25BE37FBDB9
+:108D4000A9653C85AFAE41EF01A1962161DCC9CC9C
+:108D50004EE21B1CD57FFE53F4C467C4382636FF91
+:108D6000954D541E23D1317E3687E38F8CBF0AE99F
+:108D70007736C7D3CF057F2A2005C09FE670BCDDBC
+:108D800064A67A34F2C35683866F3C130F726ACBA3
+:108D900080FABBBA5CC357AAF9B82BB9DE7E2B099F
+:108DA000A07E724AF2627A7A0BD3DB6B2C4750BFFB
+:108DB000E97984E9EDB5C48FFA8FD6BE59B3539DD6
+:108DC000AF6B53E7EBDBD5F99E1C0F8ED3B3A5AE8B
+:108DD00018EC8AD50FBF8B76EC6AC15FBC6AFE4285
+:108DE0001571C65F1EBA06ED51DF986F3C4D4F6F8F
+:108DF000C5AAB8D0DF029CFAEC352FB2F81437615F
+:108E000076821EEB88F9704E251A79A4E527799CA5
+:108E10009F08FB86E02F7984C9237A8E7DD7418213
+:108E20007C5CABD7F5C473BD979FD384FE9307FAE0
+:108E30000FD0D3350D48644139647FDB2487C89F48
+:108E4000798566C073BE99EE6780976CC971595475
+:108E5000F4F005CA9981CF7BEA720DBD88F3D62D57
+:108E60009C5E668127858EFF7BC981E7BAC3B732D6
+:108E70007A99635987F4FAD16A462FE2DC77E5E7FD
+:108E80003C87FC4DCE797D741241F55E9A1E4917E0
+:108E9000E77CE68FAF97181DD4557DF818E8CF8290
+:108EA0002F1C6E24F1FA103ED134CD64063B4A9358
+:108EB000819D83AAA67F5CBC3484CF38224A1313D9
+:108EC0004059EE8847FB6C5DA47A9C66A9F3BB7F92
+:108ED00080F3D24F23D14ED4FB304195A477EB7071
+:108EE0008CDB3E6B607E52319F550777EEF3C37E7D
+:108EF0005CFFEB083D959F3592F7C55A5AB6C4E41E
+:108F0000CA86716A743E23B36376A25F578C3BB006
+:108F10005DD683F2D5F81A93C3016910C6E1D2EF8A
+:108F2000D9A1FEB5D1898C4FDF11EB2A48880FCA31
+:108F30004B613FA45296A4C604FD26C1F8066637CD
+:108F4000F90B715C32BE6163887D9EB60F1B8F5634
+:108F500096C0F8F5F729CE61DE07A31DE5309FD353
+:108F6000DC8F7B9AFBFD4E47313FE0CCBEFA2C757F
+:108F7000F1F434F7139E8E51FB8744BDA509CC8EC6
+:108F800072B2D16CDEA807BF3A316F1C4649EC21A2
+:108F90005303C6932C6078EAD913BD6D5388FFA59F
+:108FA0002EA1F4FB309F7FD89C3743BABCF5B83173
+:108FB000D40EDF23B1F3770FA7979E08968A71EB43
+:108FC000122ABF0F78EC99E7473CF6E5C78ABC1335
+:108FD000FBEF99C0F86B5FFE3B2C4FB8DD43D8F533
+:108FE00007F2F769FD7B54D0B0734004B3CF6BFD3B
+:108FF000F30B053FE3FEF9059C1F2DEC607E8245D7
+:1090000066D29C4ACB177724B2736E94275BE59F98
+:10901000F7445E513C86A0CB9EF4CE3E7FF62321E2
+:10902000FEEC3AEECFAC13EBDBAD5EDF0309DFBA4B
+:109030003FFB818430FE6C6DDCC38BA0470C0BE2E0
+:1090400061AD8DC1AD42AE2D077B6FEF728271E8CD
+:109050006BDF5AD604F6E0B53F000B2AF231D4A7F5
+:10906000EB389C075A57BC534714959D7D105142CD
+:10907000E69FEC8A51E551430F89034DAD4E51B542
+:109080004F6F18AAAA3F64FD35AAF24C4FBE2A9F23
+:10909000D572ADAAFE55AD65AAFCF087AF57D5CF06
+:1090A000234307A3FDEC900CB62172B5B74A553E99
+:1090B00072E72DAAF69F9186CDE369BDDD42FE7968
+:1090C0001C9DA38A8371CE396D4B55ED9BA4B6626E
+:1090D0001FF0469FE49368BD151C5FCB3B99FF6270
+:1090E00074FB6A55FF67A3D83D18AD5F96762EA333
+:1090F0001ED62E9147A4FE7EDAEA8EFB9B21EEA8B7
+:10910000BFBF96F24DDA6E353DBF80FEA6D56F8E9D
+:1091100026703F5D0A496174ADA50B0BEA7FBD5B0C
+:1091200065B427E691EC87C623BC0CC4ABF4C75FDB
+:109130002F6176AEDEA7AD7688FF59F5D632A4470B
+:1091400053929A2E2214355D448E50D385D5AEA607
+:1091500083C1256A3AD0C23DDAA1A60BE2A7FF433C
+:10916000E02DE02AE01E3B554D375A78E79300DAB0
+:10917000D9DD5EC9EE2361FCE2EDDB705D97D21FA5
+:10918000F5896AF8161C703459106E2CBE4CE861D3
+:1091900026AEFF68FD1342AF894BE47A15EF47F81E
+:1091A000179A250FEA517DFEC2125F862F13F4A78E
+:1091B00006C2EC44CEA4C4F07646FC3E909D51C05D
+:1091C00075F620262F6B8803EDE12B880BF9DDC99E
+:1091D000CA5BD13EB4CAF263F4BB9EAD627A52352B
+:1091E000F1229FBFE2B802AA879210FBAB168E5203
+:1091F00087E4B302BFE1F22085740879E0C27813F6
+:109200004A86E662951F47ADE782DF30847F09BD5D
+:10921000578C27E029F89A18CF441AE424D8171A53
+:109220003E474668FD486A3B8DB0F3E06021FE2270
+:10923000AD5D26440F6E91E938F290CC2642F1578D
+:109240006073A0DDAF8874CE87EF25E6B626BDC279
+:10925000ED1357933EFBC480F2EA12FEE8591EC993
+:10926000FF68667F3FB4F06BD3E59FF8036D3C5E0B
+:109270005210EF552F0F8F077AEA6FA7B41F7D8525
+:10928000F623EB02B1A1F6C3BEFB06921FD7731300
+:1092900071DC4D42F41037699B3C3F13ECC4544ED3
+:1092A0004641CAEC58A45DAB07EBD18EACA32B01B1
+:1092B000BAAF21217EDACC6039E6E5FE7911377448
+:1092C000297DE242A28DC73FB07827C2F9A0385F5E
+:1092D0000E749E13711470CF16FC21224EA8399182
+:1092E0009F8373492EF44FF7DBA644B41FD0FD29AA
+:1092F00085EEC7BEB8222CEFB71F35EB177114B23D
+:10930000B510ED42CB42D77B19F0107ACB6FA83E57
+:1093100080F7341215A6D70D3AF681038A0B3B5518
+:10932000719EF5467A80017BC18B3C8EAF4DADAF0F
+:109330003F9BC8E393F839E752F01A181F3CEE4EF2
+:10934000E0E332F530117727E0F8427FB8EF51C102
+:10935000B5EFBCD807F73DE1E02EE072AEA8F329E7
+:10936000C0976C3D9200F0EE8872EE83FAE947FDFB
+:10937000A7245D705E157217C6CBF6B6CB783FCFCB
+:109380003D81C55BB9F7C8C81ABA3B4CE837AD6E2A
+:109390007F1DF5C2AE46CA68A91E76A6910EA9BF6A
+:1093A00088BD4003EF81CE47623D1F68D62FE2752E
+:1093B000E83A7F7F0938FC3E1C1C2AE45183E19E79
+:1093C000575F9C913E905115421FDA756CE6F4B0E0
+:1093D00056EF3C01FD1DEF4CDB0CFD55C81D07533E
+:1093E000003EEB24BC7F35D1C4EECB26F3FB7425C5
+:1093F000FE063BDC374E4AB3E0FDA9E1DF919DE07C
+:1094000017FE78DD6D31704F4CF43F5CD2E1FD4EBC
+:10941000429EFBE48E42F0572EB06FA2B98526160D
+:109420009791F9DD485F16E523AF1A8919F6A36114
+:109430006803DE6B0944CB68B78C93C924A03B3129
+:109440006F711F567C87FBFA70EF527C9FD81428EF
+:10945000584BD30E4E0F62DD13CB03050D9620FC47
+:10946000455CA6163E5B383CDCF1C666D017BBCD2A
+:10947000E2FCC95262D3239F596766FBE6D855E2E6
+:10948000FCEDB3C2B9D41DE1183C06F6DFFB32791E
+:1094900092267FB1390647E3FA15D4C7D7D958BB0E
+:1094A0006E1E07BFEEA3B244885F8E6F0A1F6FA6C1
+:1094B00024B1735C2DF7EF8BEFB57A1FC68DD542C3
+:1094C000BC7641F0FB95C66B8B78FC01E110AD27B3
+:1094D000FAD178EFDC79B17AAFFC4B0E7BBEBE3EA1
+:1094E0004927E20FD1EF4DCF5B61E30B4B93D8F9E6
+:1094F0002A1807E8C77BC37DF1857B4A13C945CE8F
+:10950000FBEEF30E55DC9F8837779F9F84717EFDBD
+:10951000FAA5FD2996605CE140F0DF92C8E6E58699
+:1095200078BF82D0EF0AFBDE374E1C8FDFF347C1D6
+:109530003EFD45BB8CF7EA7F714837757B9879D73C
+:109540002731B85D13AFC77D33D2471CDBC28C2FE8
+:10955000EA89FB35E29EAA767EBBCBFC8B60FE10CF
+:10956000471C6EBCA59C8EC4BC77C7307CB8F799ED
+:10957000F09E05ED17E3BD77C7F857E2BEB0A9F13D
+:109580007C3BB7D7ECBEDE9F81F7BCA6313BC34026
+:10959000F4E08D72FD04F5D89B69654A3FC5FA0673
+:1095A000C916B2FF2E450F41B8EB5478ED0F772363
+:1095B000E257F4FBF961BE4F89C302E7B7255CBEF1
+:1095C0002DD95183FAAF381F7DFEB08CF1179F1350
+:1095D000E627F9BC55C2F3CF521721EB291F5AF9E0
+:1095E00064413388B92549845C17C3BEDF09E94665
+:1095F000B59F7CF9BDFDEC872454AEAE200D2857F5
+:1096000056FE58DDAE9ADCFB67D09FB4FEFBE1DC72
+:109610002E27D6B139899E4740EF2926C5201FD66F
+:109620003EF985314A19781F9CA67C77981EF8AFC1
+:1096300019D3AE461BA6BF48723C9644F1B727C962
+:10964000B50DD29EF759FFBDB5BD4C7E6C8D43B9AB
+:10965000D564FD2EF2757908E3EBF7C03B09141EC3
+:109660002613D39712740D7214EA2D5EA487E3F1CA
+:109670006BAA6662DE9E04741FF7CB295331CEEFCE
+:1096800097910E80F7A652471ED8253655B27B9982
+:109690006613F3B37B7F31F63570830C6BBBBF0C65
+:1096A000CEC1B68EFD3EB0F7B4E8FE7C10E2575A4C
+:1096B000AE63F18B093AFFFED490F1E223BD49E09D
+:1096C000878F1F69C4388F38B934AF21245ECACD63
+:1096D00071D1DB9E8576C21E83B01BB645E0BDA866
+:1096E000DAA183818F5C43189E45DC1BCC2154DFBB
+:1096F000EDA27084A04B91BFA64DF219A2F0FD120D
+:10970000F4E3D4DEE54B980F72EAE77AF48389F943
+:10971000C5BD9A5C06FE2E219FE64B366647E3FAEE
+:10972000FC3C22FE317FD95C4E27F3B81E3F3F92AE
+:10973000C17B29B16740BB5BCC244A47B7D4FCF25C
+:10974000B6225C678D211AF405E1F71958CF086F2E
+:10975000FF723F6565F78DA54036747286C2E76279
+:10976000FB30C0F9B23B9BDDBB23C38803FC8CEE0E
+:109770007DC3B7817DC23488F9AF297F3297E4A3D6
+:109780005E6D8673D4ADAF44F0F8222FBF4FECC8A6
+:1097900083F89CFAAAB47C8C13391AC07737BA0DB7
+:1097A000FE0CDCC794EF4854360EDAF2FD197AB895
+:1097B000AF9942F5359A2FD9722FCB0FF5AFD4D18F
+:1097C000FC922D4FCDD0D3FDE1BEC67F0AF2355BB2
+:1097D00076B17CBE7FA54CF3CD5B5E65F5E160495B
+:1097E00009ECC12D07677868FF67A2B9BCB7FBF128
+:1097F0009EB5FBE5E1BA503B6B6332E35B67B89D16
+:10980000F84C26595C05F01E11BEFEB2641D0F5ABD
+:1098100069C554AC57B42749E1DB25F3716EE5F710
+:10982000A32746929608E6B7F344513C1CE8188EED
+:109830007EC7AF9362989E6EF3E3FB38A21F014F81
+:10984000D19F187735C867E0CB9A78ACEC64863F37
+:109850003ACE461C679883DD2BAE4ACB03FC51BC45
+:10986000E939DEF4ECFCBB8DCD8FF61B9D8B72A02D
+:1098700000ECF807BEA2F53383F3D6D24941329308
+:109880002FB736317F6B203A0BE96962247F67A5D9
+:1098900050BD8E660E87C6E4687E6F46C02B51C2EF
+:1098A000719A381CD3FC78CFF24AD75DF11F5A77F2
+:1098B00008BE1CF05ECA81F6ABB7B3F5C4F07BCD31
+:1098C000FE8C18D4F7EE57F5776683A67D09C1B8EC
+:1098D00036774C16B6BF278298F13BD9DED72E33A8
+:1098E00097E9ADA0CF8A772C88E73A12EA47EC7B5C
+:1098F000AFA28DC56706D739A390AFD3C6D769632A
+:10990000EBF4AAE8951C0964CCB6F6A7E33EF8F799
+:10991000F5372A9FF7A7DAE7E1FA837D3D105ED697
+:10992000733AF9D6F022E6A981671F9C35F313F04C
+:1099300084FD8DED46A9E952CCB326599C9335FBA5
+:109940003BF31B8E57CADAD5DDCEE2B989A2A6EB6E
+:10995000BADD993A882B10ED6AC127101FB4FF3D7C
+:109960009ACCED8969246D80F8C4C7938BC2DA0D57
+:10997000F1BBF69CD813CDE2D5B5F68A9E787B274D
+:10998000DCAFF49C63EF0A8CD3D86FC0CFF49C2576
+:10999000D82E285FD4F9739C3FF6B73F0532607E1E
+:1099A00085A6B2E7153BD547B61C437E5D38B8ECBB
+:1099B000B64C9A7F35F98FC8CF0B53CBBEC8A4FCE9
+:1099C0007C7FB29FE547967D3114F25BFCACFE4490
+:1099D000C7F3C0EF89C73F63527250AF782D59412A
+:1099E000B8C9E53A027464022586AEC7F4AA09E351
+:1099F000F6045C074A0B4DBA8670F76FDFEEA307DB
+:109A0000E65729813F15B0F3713B805FAFB203F495
+:109A100044B17BDF3D7BFF8EF75D3E487675021ECD
+:109A2000EA23BB1665D2FC5D919FA01F4F72D03D0B
+:109A300001F615C54616D0F94A5D9B9CA03F91D50D
+:109A400076B31EE1CAED5E748D1728FC5ED9F7F37C
+:109A5000EFA5B2619C308FB19C0FD4EFFBF26FE0A9
+:109A6000F7AD3F63B183F97A6CC796DB40FF1ADB31
+:109A7000F1F6974C0EB3FB3962DE63C1AE49BF9776
+:109A8000B49B70FE633BAE5E01F5C7FDB6230BE8E9
+:109A900064C2315F13B0859EBD2FA5AAEEE590CFBD
+:109AA0002E1AD739A0DF4DC0E353AA540D4678F4DF
+:109AB00032787C85F167DDF1879BFD68FC54DF7FA0
+:109AC000A2FA3AFA917BC9203BF833C47D7AADBD46
+:109AD000F468255D1FFD3E21406710A24F4F3C6F8B
+:109AE000A68C24982F25D1AA7CB9395955BFC29686
+:109AF000A92A9F9274B5AA7C9A92A7CA4F1F315681
+:109B000055FF067BA92A7F63C93455FD4A47A52A1C
+:109B10009FE76B53D52F38D4AE2E3F4264C043FE2F
+:109B200051FBEB90169D74A0D9B5F874C3EB908EE1
+:109B3000FD0B0387D65E7CEDF9B6D7E1BBB0176BA2
+:109B4000EF3309FBF1CDB2C56B0C6F274ED2670521
+:109B5000DF1F9075EC3ED318ABEBEA94A2E07DA634
+:109B600089602FA648A8587CEE47E3004F0B983D2C
+:109B7000ED282006E3BEAD68873C6A6878E60F2CC6
+:109B80000E201DF8DE84C05CD5BA279E77A9D65D6D
+:109B90004A6ED5E0698D2A5F61BB5D557F4AD2066A
+:109BA00055F934E5071A3CDDAFCADF60DFA2C1D347
+:109BB000360D9E7EAE2A17F4DDC1ED5AFBC01E4560
+:109BC000D3F1FECE72C0C375A703888F92CED67232
+:109BD000C0D3B547DB105F853E6739B0CBE2430D9C
+:109BE000AF43EAA3E73168F75A6312A6071A15B420
+:109BF0006B1D6C1C81E9A1463B7EFF756309A6EFD6
+:109C0000343A307DAF712AA69D8D4E4CDB1ADBB005
+:109C1000FE738DEDCC2E16DBF7DE453AD807BA750C
+:109C20007E377882173F927703F0CBEE41FE6EC805
+:109C3000DF45EC374CA2F925C044E8BEFC294F377C
+:109C4000A43A028057371CCA8A82F1186D3A471E1F
+:109C5000E8E177A44CF8A13E9D90BB3738936CD1D6
+:109C60002C6FA6794436C6B34DF8A18312D73320A2
+:109C70004AD0A933E106C8F744B07277CA841B40C2
+:109C80000FFFC6FE73473FFFF91D2961FCE7CF9C1C
+:109C900056AC60D739FCD5702BC0E330B76F39486C
+:109CA0009E61094D4BF5790690B34707B8B7F08030
+:109CB000AEB409E0D0A6B3CFC178EFEB0D04E8B79E
+:109CC0004A62E75F51CF95CAE441CF0D263C4F1D54
+:109CD000D13956605C9914780CE0BC3DA512E1DEE8
+:109CE000630D6400FCBC294E968F0F3C26D943F2CD
+:109CF00006069F07526EFCB6E1F35838F83C9162B5
+:109D000063FAB6CF910E7A80C81FA974D4C17E3E83
+:109D100052EAB80AEFCF384D6CFF3AADDEABD03E19
+:109D2000E4289A1362E719926A60F7D1E16222D8B7
+:109D30003B6F91719F6BE1392195E97B482770CE8C
+:109D40009C1789E782233AF69E81B6FE020ED7B3AE
+:109D500083C2DBE316A632BDA26C56DD332FD0FEE4
+:109D60007AD64560D73DCEE1A88FF53450E82A3445
+:109D70003DDD708E959BEC1C24E8BF9D0F7FD1F2DA
+:109D8000673A6EFBEBEF68FD4FD645DA5186D8AEE9
+:109D900041F8DDC22B2F8C35A3FEB4B02ABD0CE4F4
+:109DA000E27CEE075C64D527A03B501F6D8427172B
+:109DB000975BF29A2904C9CAB84A233C25559DB637
+:109DC000A619D2D5C3EE37C21329B5A37635831AA7
+:109DD0005B47B77011F23FFFBB8D745E8BD7CB0A28
+:109DE0003BCF89FBAE355714CF22E8F7088F3BA253
+:109DF00040C0F3EA220E6FD16E1187D78914AE3FAF
+:109E0000E6909C0B6A3FD66740EF5D0BDFCD1EC02E
+:109E1000CFA02EE7FAE3074636AEF6FD1231EEE2AA
+:109E20005476FE3A62A49409FAE42D4C0EE4CEFD79
+:109E3000E2AE22BAFEDC0E9B0EE31516D7BD00780B
+:109E4000E86DE778349076D84FB33C4B3EF91D224D
+:109E5000264E758FF752F2D2DE692B0F9597857ECD
+:109E60006779A8BC2C09B496835C14F251F84F7D35
+:109E70008DD59C2F37203F3DD0B81EF3071B3D9852
+:109E80001E6A6CE17CB915CBDF697C98F3652FE71E
+:109E9000CB3BF17B47E35C4CF735BA583ECA19958A
+:109EA0000AFBC4ECC2F8C437B69808F8E77A3B4C12
+:109EB000189F4177C4638FC641FC9109EF716AE333
+:109EC00090B47CBE8F1E76F77B372505C6E98B1FC5
+:109ED000027D71C8C0F474982856E04BF98FFEE4F7
+:109EE00006D0AF0F2B8A15F4E982D4CD2CEF50ACFD
+:109EF000069A2F7C94E75D8AD504AC22F521E45BB9
+:109F0000873D8A3582E68B1F7D88957B093AF3C7AA
+:109F10003DBAF5060FF059221D80FD516ECE9C44CE
+:109F2000C50595D7A507605F4C495A3209F6C5CEDD
+:109F30001405E9639AB2E100E4A78FD8A687ABFACB
+:109F40000E4BDE4668571657A9877693D2D66C8497
+:109F5000769387DDAF0F6D3775D4AE8D909F61DF3F
+:109F6000A607FD7427F0B1F8603F222FCA059F169F
+:109F70007172A33B9C280F72DB9D280F045CCA669C
+:109F800057DE0DF6CFFA76C926C13C664B7D410AF5
+:109F90001093E886F74929BFBE3EF597D60DB45D0C
+:109FA0003DE4AFC5FC0F377CBBFCFBA6D430FCFB0B
+:109FB00043BEDF41DE43DCFB8746F60ECC331C2E6E
+:109FC000F51D4BACF88E2A715941CF7A9ECBF39791
+:109FD00020A5E59FF1B48B7F7F40E770C138AB527D
+:109FE000B91FB23F7FA84965FB5F738F648072CE53
+:109FF0001FEA526DAAF73CEA08BBBF76A9383B6D51
+:10A000009CB836EE6435693BE8C8EC1F6F520BF71D
+:10A01000DCB2FAC77F8B786A6D1C78DFB96A10E30F
+:10A02000A77381D750BA6E491D904FDE7B0938DC8B
+:10A030001B0E0EFDD643589C7BBF38241EEFAE5D31
+:10A040001771C5B3778D79FCBB767D822EFAAFAFE1
+:10A0500095C15FCFE04FF5BBC7607E158BAD04ECBB
+:10A0600056A1FCE77717E13F5A7EF66DF1C99B17C1
+:10A07000D7E1BB6561F8D8F3E1F898B8CFAF4D856B
+:10A080009E0AF7F3201E12DE3982737E65A26B1FD3
+:10A09000F4D35316F89B0ECEA171ECDDF083D1AE54
+:10A0A000FDF05D32B2B80611977C5AE7F915E86DFC
+:10A0B000EF3DFA19F2B36E1016748FBC41F3A097FE
+:10A0C000FDC3E67C13E04746F88DA1EF8F0F147FA8
+:10A0D000FB1B2EFFFAA76CDF8938D49E6D5F66A04C
+:10A0E000FDEE12FB62207854C8E3FD703FA4B72454
+:10A0F00012E56797447CF0DE71576902EA2D5DE94D
+:10A10000463DA4DFF6B9B82B3D1BFBD79E8FBB9213
+:10A110004BCC6CDCC953217D2FF95421C8BDDFF035
+:10A12000F8CB76A3A7E03DB00F8F8D40FFFE8D9258
+:10A13000BF10E0A03D5777BDB5A04CC9ED7FBEA6CE
+:10A14000EB9B04EBAB3DAEBB1BBE5DE979BB76FD83
+:10A15000DF08C4B98F5BFF1581F7EFAEFCFCDD199A
+:10A1600093AB805EE16A021219D345F5099ABF5498
+:10A17000FCD639899ED33343CEE5256FB3382E9E66
+:10A180006ACFE7FDDE095CED51C70D96FA8A305EB5
+:10A1900045F647E1BD601D7B6F43C473BDC9CFF376
+:10A1A000F4BC3E240DED709D19AAF3FA1D1F2DFA83
+:10A1B0001EF281088CEF78A6FD443CCCF58F9DF112
+:10A1C0003F794509D277BDED6F24F49DC0DAF5BD26
+:10A1D000AA7CD786E0FB56701FABF65F32CA252AF1
+:10A1E000C75A104FE435E3DA10F94ADAFEDC07EF1C
+:10A1F000D194DF5502C050BE36CF74D07695FC3C6A
+:10A200004448E48D0EDAAE929F1F8967252B8FE7B5
+:10A21000F53D9FB07CBA28FFE34CAC7F95E86F1CFE
+:10A220002B4F1679DEDFD5229F782396678AF62595
+:10A230002C9F23C6AF64EDADACFEE4ADFF9C097A64
+:10A240008DE0F733D2B89CE0EF5251FEEF4C2BBAC1
+:10A2500068BC8EBA9CCB07F10E55C51DD322DF8595
+:10A260007DDC2661EC61ED9D06B4E79F8D69CB0D29
+:10A27000BD2F2FE27A9CE5568CF3AA7B71F8769974
+:10A28000C73B811EB39CFBE92B640BFA617AEF6537
+:10A290007C7E203D70E5FA9755F8EC57CEDFD3462B
+:10A2A00047251DEFDC0F13F17E0219D689F102EE6E
+:10A2B0003449C427E0BD6A11571797451C707E8E3C
+:10A2C0007B2982BDA77AB213F9EFCA97987DBB6E3E
+:10A2D000CBEB28EF96CA0ADA97BE1EEA5A07F0E9D6
+:10A2E000B6B2772F57AEDF87FBF431C5C6FD60816C
+:10A2F00051A1F0BCB33FFC3D69F11785BFBAFC3FEB
+:10A300000C7FAD5D5DDCD75F7D85F17FDD56E607B7
+:10A31000B6733CFD49A71473783D02F03AB7A233F7
+:10A320003B5A8620EE4E8C77AB90DF2982F3566F36
+:10A33000839500DEBBA5CEDC0FC3E05F7BAE389F0C
+:10A34000415471693BFBC3F7E94BD0F7D3FF4DFA9A
+:10A350004ED4FB8D76F01B1F65EFE51577FEC9180F
+:10A360001A1FF44E1A3B070F6E677E311117172C18
+:10A37000B7323C71FF535DD53BE3C1FF24F6C3C444
+:10A3800048D206FE044AD7764ED776A06B41BF412D
+:10A390003F146D1706BE41FA252C2E91C3E9B7FD77
+:10A3A000E1FAE125E0FAE17F13AEBBA93E8CFEDBCA
+:10A3B0001722D04EA385F33F385C05BC23D32F0E64
+:10A3C000E7C8F4FF0C9C23D315959D43C07B20F96F
+:10A3D000A4C58F9877987D5AF44DF6E923199C4FC0
+:10A3E000E9FD188FABC57B4C7A3FBC27A45F1CEFFF
+:10A3F000EAF2FF30DEB570D3A6B5DC9FABFD5E9808
+:10A400003E20BFFB56E0F87FCD4FB0B061BFAA7CC5
+:10A41000F1FAB754E54B3CEF5F965F41D8FBFF5B29
+:10A42000FE05E15798F9FC2A1DF81FB5F24137C423
+:10A43000F923A0C71B5FFE7AD48730F9EA6C8CB78A
+:10A44000BA8DAFE58BF17FFFE47B94BEBE6860F60A
+:10A45000D663FB3F372839FDE965E1791D7184D06A
+:10A46000D9C2F5EF1B40CF5A48D8FB54DAFA0FA6F1
+:10A47000337B30C64951BE30D74C0C71941FCC9DF4
+:10A48000CBEE4BCF0507630CA63E172D9FA9273EA9
+:10A49000788FBBD2A2F799D0EFA9BEFF6EE2EF751D
+:10A4A00093B858D53D78D921639CDF9C12E62FBD27
+:10A4B000C5D286F787E71DBAEBDCF7602F6FF4147F
+:10A4C000B1B87771FFF0F7BA2BF1833E087A2A9C76
+:10A4D000FB24EE5F5F6340FFBAB6DD2ABE9F66CA0B
+:10A4E000128BA3D9C3E233C5FEA4EB3B64CA67F762
+:10A4F00060E0F7482A1B0CBEE1B9A067EF473DBBFF
+:10A50000BE64432EE0AF7E9274DC941B3CEFD4AF6C
+:10A51000FF0BB6D7F2676D7AB9F6D54F1A0F21BD8A
+:10A520008873D1B1461FE6B5F6D60513FF17FD9324
+:10A5300063FFE26D8274DC578E0FC7D075FB1B3B47
+:10A54000FF2D7B82B02308BB82D64E21F88878BFCE
+:10A55000D2976EE3EFB296A2DF83E8592AF8EDC1F5
+:10A56000FEFCF9D7E917D727D5E5FF61FE7CB9F4E2
+:10A570005F9BC4E4AA96EE8F56FD0CEDCF82BEB56C
+:10A58000F4BF006252E8F80BEA25BC273E7755ABD2
+:10A59000619CF4CDE97DB5E56406839B462E5CB1F4
+:10A5A0003C50783C878CE70B93BCC60E760F8187B6
+:10A5B000AFD3D5EF0353BC48191797ABEAF2FFFAB4
+:10A5C00039E0E4A26F2617894A9F48CBE8B76EE5C9
+:10A5D00012EB56FE9BEB0EB9A7B448D605EFE3404D
+:10A5E000FC35C481F678D9FDD4EACC56FCDD0352A3
+:10A5F0001288027E77EB5E99FD9E8EDEA14F0E796A
+:10A600003FAD8BF83E007A5C359EBD3BA48D9B76BA
+:10A61000F378EAD596DD78BF51FB0E9A88CB76F3B6
+:10A62000FEB4EFA189F6E29D03ED7B685332781CFE
+:10A63000763EC967712917E7A3DD20CF43FC35DDDE
+:10A640005F35A25DE1C6C74AEEF3A405F13227A348
+:10A650001FDF99977171BEA32EFF2FD3AF6CDD81E1
+:10A66000F7D8AE947E47643ADC407F822FF7F19BA7
+:10A67000574CC86FC43BF33D6B9EC1F7877ABE242D
+:10A68000E897BDD43BE313BBD835C40927BD4D566D
+:10A690008AD771C73C68AF1B7BC485F776C7BCE31C
+:10A6A00080887F9277C029C3BC853E23F49B20FF1E
+:10A6B000E2F7D9789CD5E5F2B92BF537FEA7FC8CEB
+:10A6C000E25E5DB7C15704BFE7E0D91381BF03A1C4
+:10A6D0009DFF9319BA8BBE93DC11E57A12F0348B8F
+:10A6E000CB09F15E7285CCDE49EFED94D15EB8EE18
+:10A6F0007F7EFBAB47954BDB15EA6DBD61CF6522D5
+:10A70000ADD7B17B2DF9E50AC649C2790DEC87C2F8
+:10A710009EA8AD7F4A297B2903ED5BE3F13DDADE9C
+:10A7200087D97C06C257FDFA008E3F60391FBF7E75
+:10A730006F912DF49D95F3197DE743DB297310DFAD
+:10A74000974B17FFD7CE2D3365E291A87CCD91BCF6
+:10A750004CEF254CFF5D403A315D440298BA08BB8E
+:10A76000CFB094D8315D4E9C98AE555C5D191837CA
+:10A770001448C0F8D317FF390AE8E6DC75E35A211C
+:10A7800046F1DBF22369F5BE9E3C85BD97F4C23FDE
+:10A790007F07F4D9F33F86CBE21B47A21C6448181D
+:10A7A0003FD37BA532BBD754F25DDC17E2FD5D32AF
+:10A7B00089F9E1962766E2FE09F2CDC46D826F82C7
+:10A7C0003F39E7B88EC5C3DC2AE17BC6ED7E1D6E3E
+:10A7D000B19C15995EF8DDB9F6DDAC3CA72EDA2BFD
+:10A7E000D17CCED80856BE26DA0BF74F16123FEEB4
+:10A7F000CBC570FB4486FB4B8C2F8ADF0BA02782D6
+:10A80000A1126DBFA2C3CCEE5110FF30E0FFB970B2
+:10A810007E0A174F3384F1F1D14319BF1F5DA6B6ED
+:10A82000870CE5E5F72965DF0778B40C71640D81C5
+:10A83000FA319D9B1E2C043B908E809FE6B3B1B7EE
+:10A84000A35F53B47B51291B01F59F9558BCBF678B
+:10A850002FBF6F4C0209A1FEB1B54A792ED42B1A35
+:10A86000C2F8D3407085DF517486392F8AF8D1D170
+:10A87000706643BB3CC177D29E95587EF2E35B6F16
+:10A88000DC68415F8207F4E31715D744186FB49171
+:10A89000100BCCFFA7FC7E1B69C800BBE8AAC74C05
+:10A8A0003AD02F3EA2E218EEF7FC819EB721FD9828
+:10A8B0009E9B21FD233D37437A9C9E9B213D41CFAA
+:10A8C000CD90AE386F87C7CCC989218EB9D0BFF083
+:10A8D000F769E75B3984F1D7BEF1F71A71FCFB1415
+:10A8E00017C2B70FDF7B08FEDEEDB3D18194988BE2
+:10A8F000D05BCFDEBFA39F7420B808FFA3B67C0A4D
+:10A90000C76BEE6E3DCAFFDC767FD4CA907A2B8788
+:10A9100018B17DCE0B27A3A0FF6E5B1F7C1D125DBF
+:10A92000F24C1DCBAF7CFCB91B378E82F93BBE0FBE
+:10A930007441F7F96A4873DB7FFB00FC5E2AED1F68
+:10A94000E3247AA4C0663C2F68D6A1858358D7B388
+:10A95000D19D9BA0FDB32F0C859550BE43D8BE0161
+:10A960003A92C2AD7703AEE74653A010EE0BDD7806
+:10A97000410E1BA77D9F528A704E067A43FEDDCAA8
+:10A9800053465F026FDF747F6BFB23E2FD15E0A58A
+:10A990000AC8A5AFA2402FACE4F104EDBB87FD06C9
+:10A9A000D6E9392413F8BDDAD131EAFDB78BE34992
+:10A9B000A4397B8D4EC0D7B37B4F0D83F789297E99
+:10A9C00086C17BC5DB865C45427FEF3167EC978FA4
+:10A9D0003C1887F5F1F769E7916D15103733DFBC47
+:10A9E000FF0D58D242DBF10A889B599C241D8474C8
+:10A9F00089923919E265C47D8365234A0FC2969A0C
+:10AA000061AF447DAE14984C887C283747F247D814
+:10AA1000853C8A55E5A724A5AAEA4F53B254E5D34D
+:10AA2000478C54958B7167D80B54F546C70486C282
+:10AA3000798EAE83BD03FFA48CF186392F1CB97EBD
+:10AA400024CDCF7C6A0EBE43F92C2F9FF95CB91739
+:10AA5000F0D143E169A40AD5E9921F6C7E103AD384
+:10AA60009C176AF73E71D0A15CC679E112E7848138
+:10AA7000DE4F16EDB5E704CA371F00BE39FAC5D957
+:10AA800036F0DB3E3BF6CB148847FDCD10FEAE0C16
+:10AA90003F3F0C44377DFB435218DDBC259327C351
+:10AAA000D00D44F2323A64E9CCC3EC7EDE95F2B5C7
+:10AAB0004F81AFA1BDC043427F7F576BDF1B6DB499
+:10AAC000FFE636B047BD2BC30DA5BE7B932BE16FD0
+:10AAD0003948EF64F9B6BB93E3F0BB07F46137B7CD
+:10AAE000F70D52B83E55BBFFEEE4C2603959775CB2
+:10AAF000559FDC2935ABF21B33D5F97B4B9B43DBF0
+:10AB00000FA48FAD7C7889D19503F76EA5B0BF37C0
+:10AB10002CE6F3FF010980D5200080000000000032
+:10AB20001F8B08000000000000FFB5190B5454658E
+:10AB3000FABBF7CE0B1960782810427798440A8444
+:10AB4000895728B08DA01ED7DA1A4C8F545693E53A
+:10AB500003794DE0B6F4D8E318AD8FB6076D5B69A5
+:10AB60006B355696E7E439B144462536AE5B49EB82
+:10AB7000D654A266E499D8424C70267A6D9D5AF755
+:10AB8000FBFEFF5E672E605B9DD64EE79FEFFFFFEB
+:10AB9000FB7FEF279014CA70CE0008F6ACCC7099FA
+:10ABA0000106F7D61AE41880D3F4EFE2F0DAB8F928
+:10ABB0007A8303CF5700383ACCE3CF01D601140390
+:10ABC0005C29817BA2F3145960E760FF65F1BD2F1A
+:10ABD000010849009E178DDEED5684E35C06676E22
+:10ABE000F89E8DF04E0618D972FFEFBF2AC2F525E8
+:10ABF000B0E30E8CC4430DBD9BD7755C1471CD9F23
+:10AC000004D7D17779968098806B7055B407E200AD
+:10AC10009A6A633C623E9E67860E992E04C8F1A62E
+:10AC2000B59B52018E8A22C039440778A014EFE305
+:10AC30001B045F24A739EFA4DFB9C867CC2FC7E78F
+:10AC40004532B035BF3294E9C67BD77E87E71CBF5B
+:10AC500003A291CE3F804A8F034C5C2E04BBBD19EA
+:10AC6000FE3F233F4DBD1218909F61F01DBA5A6000
+:10AC7000D7CCA925002BE9A74CFB1D0690D86F194E
+:10AC8000707F95B2BFB27CE5A5108BF056FD4020D9
+:10AC90009BBD0FA7F1FFD57F6F3798F17CF553DA95
+:10ACA0007D420F53902FE5FB3AF0B377EB77E23D0F
+:10ACB00053F85E23DCFD9984EF367669BF5F24C7C5
+:10ACC000240DE6E08F0228382DB16D91DE6B36F150
+:10ACD000F7E64ADFBD7B09EAB1E925C96EC4ADD10B
+:10ACE000DDD3E200F98339A8E4D4F1F26BDA8C7A8F
+:10ACF0002A0CC3A7764BF3BD745F17CAA89E315EBA
+:10AD0000CE60C9E2F82C1C5F73C5D70B01F135F793
+:10AD1000E8D0D07E00CF4611E4083CCFED31AEF252
+:10AD20009AC3F4072D9CC7FC9E2F1366E7F2751D8E
+:10AD3000D101ED1C2F70BF9821803E09F141B56013
+:10AD4000DF8E4B5F4F7225C9BF4F009F5CC09E587E
+:10AD50006442FD5CC19FA37D3324E08F946C1DE1B0
+:10AD600059A8C8FD8AD27F7C23E0778B7B164F439E
+:10AD70000AE050D7B23ED40C6C906D0CDF12F0E8B4
+:10AD8000492F7DF1CEF416A4F3324960F6DF171F88
+:10AD90001A16107F5F45B4D026B0F7EFA4F755BE62
+:10ADA000FAF4CE7437E36B8E6510F526382E904E8C
+:10ADB000478F974758AE3A1854F52B7177217F9CEF
+:10ADC0002BDD3EFB12F4DBD1A5603122BD974B6831
+:10ADD0003808C3ABDC8FAB49D63351AE823F81E834
+:10ADE0006C96176E91F1BBE4D67B41971821371D05
+:10ADF000F733552FAA1CC7D3A1E22DF73B90BFD143
+:10AE00001D02B39F46BBCCECB3B1FCE4834B107F77
+:10AE1000A35FB20B48CFB2EEBD47487E1D6B3B40EF
+:10AE2000771E40E7DA6EB62E33997D521EE38BD93A
+:10AE3000AD8846417CAD5660C6A7357C1EE67B0CCE
+:10AE4000BC513F7C06CE043818EB7C9EF85BF3FBCC
+:10AE5000CFFB9610B51BCAE3991F90AD9D1BA63F73
+:10AE6000DF006046FA43DBA3BD4F303C68AF25618D
+:10AE70007B3DB127EB700B9E9F7853CFCC755FC5A0
+:10AE8000C3A76E4178CDF66826E71309E049A5F31C
+:10AE900027A67B3D7861A518EA6F21B977C6D8B798
+:10AEA000E3F9F147A73FBB13E1DA67A7D9894CF271
+:10AEB0001F19E57D3C1D01DA7F3E957D07291CEFBA
+:10AEC0000AC52FA56766DC574EE7CF24DA098FAA9B
+:10AED000BFA147A31C80F2FA127C791634BD93827D
+:10AEE0006750C487EBC49DC704B4CBDB0CAE83C4EE
+:10AEF000F7EA47FE7AA80CF9A97AE6370FCF44FAA9
+:10AF00006ADF9B0CF44E58AFE3E2406C2097FCDF05
+:10AF1000C6FD5F914FDD8E28CBC71171A6A1235EC0
+:10AF2000033775A75A3E8E883775C0650CF5828E3B
+:10AF3000F8A957FCAA5E741D25BA1A20C0E3228422
+:10AF40000C64570592E0A07810BAC7C8E43FD6CE8B
+:10AF5000466591D1512F828BE27941229852C86F78
+:10AF60005D5C7EC17BA63F7117CA66923541F5FBD9
+:10AF7000AC853322EDB3BFF115B2CFCD46669FC38A
+:10AF8000513C2F8DC5F31F399E7DBFC2F405F38759
+:10AF900033F9A4F5DF5A38171C14EF0ADAE4C29B20
+:10AFA000706D51F4722CC5295849EE1DF7EF3AC067
+:10AFB000E4B9F5E6A38477BF99E90F0E70B90705E8
+:10AFC0009E27D5F7569842A02B247AB7317AD5FD23
+:10AFD000C12D87F35CF8FEE00B397980F6BC4CF2AA
+:10AFE0000FFE05E5732AC67FEC365C3BF7BF3B8559
+:10AFF000F2E0587AEB5B47D97B2A3C2CF038544F6F
+:10B000007CE0FEF799CE64A213C3088B0F0377CDC3
+:10B0100060F29B2BE5C691FE8327B4F48DA5537D8A
+:10B020005FA54F7D5FBD37CD2A32398E18FC7994EC
+:10B03000F75FCC90357C8DC4FAF3E2CDB46FE17547
+:10B040004402C211F656433F51BF35268CDB485FA0
+:10B050004D8D606F03B6EFA1B889ABCF85E7F529B9
+:10B060002F2B7203A709ED78B162679094C8EC6E3C
+:10B070001170BB5EACC4EDABA0430FE82F47C475A5
+:10B08000BF35A0FD0D773CA07745C65DCF51F1746B
+:10B09000CE4F8FBB9E4AC8A6F83D6231B3BA669EBA
+:10B0A00055D0B17BE9904EF7F0DCEE433BF0741ADB
+:10B0B000ED6D48CFE3A2738115E5536FF0E5911F65
+:10B0C000A8DF3D2EBAD8FEB0706005E91B74BE3C07
+:10B0D00056EFC41B40C03A2338D9EE77505DF625B1
+:10B0E000B0B812D4434D27E22DAA12DD9DE6703C84
+:10B0F00054E367510EEEA35C2B685FF557B49BA237
+:10B100007CEDFD303F5AF8B895FB5D51A2E8EE9812
+:10B11000C05F6E57F4DC061D12F7679E47CB14B96B
+:10B1200063DD2245D62D8D4A9C0FC69A3C12F25300
+:10B13000B61BF5827099CEB797568C02D08AFA9DCD
+:10B14000053EFE5EB7369E530E59CAF2720ECBCB49
+:10B15000B31475AF17DC407A3551FEC2F52EC12FFE
+:10B16000D1FA2B08B1D501161DADA806B6CE012720
+:10B170005BE7819BADF3A19DAD0BA083AD97829F53
+:10B18000AD7081AF0D583EB8DD3288F9187EBD52E2
+:10B19000A4BC5CB464E27AFC71455E67970746F92B
+:10B1A000929F2F8F79E04A61749D4D2E53B399DDA4
+:10B1B000AB7231927DE27751E04DA1B50202EC9D78
+:10B1C0008BC990F19DD920EB08AE020783E7FE48BA
+:10B1D0007994065C3A57EE0472A99AD84E7628768E
+:10B1E000524C365D1CD6D787561E1754BD01D24926
+:10B1F000F960BC3E2183E82C8AAEFC5CC690F1DA93
+:10B20000B6F79D3A8CA34585952D36840F593FE5B9
+:10B210007059E5F399081FD976D2A99B49765E59F2
+:10B22000A8B76315BA6ED83907CF4D18FCA3504E96
+:10B23000924D82525C5D51B179807E6794ACEB7423
+:10B24000E857C6DB80C5195714809FD5B36865E4FD
+:10B250002735BC7E5D63E17ADB6B70BD4A7EDA60C8
+:10B26000F2C5CAC8D39A757393295F6E30F0F73F61
+:10B270009A2CE7BC827232223E5341984F3CF744ED
+:10B28000211C10E496566B18FF8FC0F7CF1FC277B2
+:10B290006B8AEB5D16CF4D5940FA4F53F2796767D1
+:10B2A000598A5D24FC16863F1093D5D28A470752EF
+:10B2B0009C1FD27BC1186E771F5AB95ECEB69A32E8
+:10B2C0001D1F5827D80FAEFB7A978FE2D02748086A
+:10B2D000BEF399D53540743489818C42D4D71DD1C1
+:10B2E000C70C6427AA1D0BA8BCA5C87F9B03BC067E
+:10B2F000E61FE59633F5982DEC07C1E5F81ECAA5C3
+:10B30000C8E9ACD2E371498D7B1FADA5AEF62A3CEE
+:10B31000213C41A2A7490AAD20BB3815FF9EE1138D
+:10B32000E6A753B93D2AF1AB674FEF6D691C744234
+:10B33000841F36EDF9E6AB0F50DF4DA3663B5D0F82
+:10B34000FBDF9616EA0BB01AD4C417D52F67751B0E
+:10B350007DD45F95ED3E7F39DDAB78AFDF4671FA86
+:10B36000E2FE401B95CBC19EC369DC2FD43AFE6B35
+:10B37000E1E7E493B9120575ACCB5E90BC46E4AB53
+:10B3800099EA0B05F6207CDC84761347F779BFA990
+:10B39000F6950DBDAF19A82FC1673CC46FAD42FF34
+:10B3A000AAAD375C4AF562AD57DB2FD6F57BD713D4
+:10B3B000DD753BB4FB6ABFD9A47C5F4FF59A8DEA7B
+:10B3C0003EEDBD26EA37F3A8FED3EE67662AFDA65A
+:10B3D00092FF40A933572A77883F33EBFF0C5E2357
+:10B3E000F2D6FC688BDD4270BAD9CEE26DFD0666FE
+:10B3F000C7EA7DD89AC86C44F5DBDA8DC0EA675598
+:10B400008EF94F1B1DA48FFCA793595D8CF53CABA7
+:10B4100047309EF0FE1E6522A0DD3D171FCA1411A5
+:10B42000CF733DD976AAB75F5EEB807F9D17A64F9D
+:10B43000ADF7E74A3BAB0CD447DD887D146E35F79A
+:10B440003ED96642B87913D00D242D3B8EEAA6E290
+:10B45000FD1278E91DF03E508E6B971A4F52B0BE28
+:10B460008F9047943C09E409FA79A3A2B7E8EC0469
+:10B47000CD798CFD1CCDF771A599DAEF3D0E7F6E6D
+:10B4800009C573FE7DBCE302CDFD36C16DF791CDDC
+:10B4900004F03FBC57AE88B1C2BF82CD1D12E71782
+:10B4A00068EE6F889DB79FECBBFC0BDD183B704BC3
+:10B4B000647765018047502FB386B5E7C507DB2168
+:10B4C00016F1471DD48D99577880EA16A3ACDD5F3D
+:10B4D000AEDAC55498AA99439C913BB7FBD1219110
+:10B4E000D945099CF7707911C9590F5E79BCDC46C2
+:10B4F00069A5FB6603F38B59BD2D768A47939D5A48
+:10B50000F927D768E59FEAD2CA3B6D9556DEE96E0A
+:10B51000ADBCCF6DD5CAD7EAD1CACFB67196E6FE1B
+:10B52000B4F64A0D3C7DF302CDFDF3BD0B3570CE74
+:10B530008EAB34F767742CD39CE777AFD69CAB7691
+:10B5400036D60E2EF4358FB13311C408FDAB7A56C2
+:10B55000EDA070FFAD1A3CFF6FFD6F1FA3FFA7C8E2
+:10B56000D731DEBD153B7437B9EB65D13CAE9D9943
+:10B570002794EB59BFF6B69C5815437795FCE654D3
+:10B58000F21B94FF91C3160EDBFDF67D14CF0A8EDD
+:10B5900038AB88AEA2807B1F85F392A1F6AA38BA99
+:10B5A000EF00D932858F9CE8FEE5A502E8347E8560
+:10B5B000F094B03CAFF0AC93E2F072D977DE36167F
+:10B5C0006EC9E94BC2F320A194E7856A4714E822CB
+:10B5D000E452A1EC0325E92961F9ABF323EC07C0A0
+:10B5E00040FD8068F2B65927AA77EC9B25568FB9A3
+:10B5F000587DF686E06273A545267F06C5F7DF25F0
+:10B60000BBDECEC4B8764AB4CBAC9E13026DC45434
+:10B610009018A3A4E5A9AF76501F87ED2CCD2BFF82
+:10B6200074476DB52797916F0994F0B699FEF56749
+:10B63000BA8E64A2FC0704CBFA42FCF6AD5927335C
+:10B64000287F1925944401CD4F1C47E9FCCCDC240C
+:10B6500019F9C3781B10650F89C273ABC0FA9093B8
+:10B66000F4D8CC08FFDDA867790B94BEEC1A455ED0
+:10B670006A5FB654C13F804FACC2787E4DF71B4C19
+:10B680002E7529C3CA1CCA6DB7E0FB374C3517505D
+:10B690005F0A8E423BEFE7D53E2D4DFA297955EDF5
+:10B6A0006BCF76BF2E6548D32FC3CEC409E7916315
+:10B6B000E75E61BEF9FB039BA2591E1AD894CEE641
+:10B6C0008BE1F74FB1F7AF71BFA3B193EB5ADFD75F
+:10B6D000D8DFF59E8F34E781A4903E0DF90FEC4A38
+:10B6E0009D7735CA6FE4056309F5ABA8B7385B7180
+:10B6F000F8FDC03DD3E710BEFFCDE7A74CBEFD6B04
+:10B70000FD6CEEA6F2796CED110607D606D83A96D6
+:10B710004FB5BF5557C3DF209BEAE59030C93ED1F6
+:10B72000BCE6311BEF83FA674FA9A47CDC9F6ED087
+:10B73000F1358BC3A9A5260ECF9B4F6B506FDE480A
+:10B74000FD6DBF000E01ED61A9E07CEC7AE4BB3A2F
+:10B75000D9956BA37A7275284F87FED0941FB8567F
+:10B76000407DBE1EEFCA27FE052C065313189D59B7
+:10B77000D4370C899E3C0163C14D4F765753FD3F32
+:10B7800034C9738A3276ADADAB9AFA832103F78F51
+:10B790005B9E7C84F9C3B716D74C7AE71341F2312C
+:10B7A0007B7E49F06E67F616302C8CF8BB823AAF80
+:10B7B000A17E9BFA9B60145F67DBF8DF5F2AC7AC52
+:10B7C0004B6D3CAEDD426B31E9E5EE2CFA7BCAE80D
+:10B7D0006623905F203E8748F87AF85C760AF2404C
+:10B7E000750D566FAC5F2878D5E8A3F8A1CE751615
+:10B7F000DBACECBD241B9FD724DD67F4B6B1FCEEB7
+:10B80000CFA8463ADBF558EF50DF7010D81C6D8496
+:10B81000E661117A596CE3FD17DC08C0CF93B7D10C
+:10B820007943EFC0318A27DF67BAAE24390C8872BA
+:10B8300009C59386D8BDACDE6BB6C9EC3BA497F1C5
+:10B840008F71E14ED2CF2F380F5C45FA6D300578FD
+:10B85000DDAACC03CF26B791E5FE8772D9FCCB9E3B
+:10B8600041F4A9F422FDCDB688B99D4A7FF89D1F09
+:10B87000F60B75AEA5C2835B3664919FA15EF8BCE2
+:10B880005112AE5B38C1F70F2AFA3E96E2F410FE71
+:10B89000D56E3EF70BDB4DFBCD4749CFBD66162776
+:10B8A000CFF6FD583E1BF6F43279209FD7127F1158
+:10B8B0007CDE1BC9E748CFE18772E59FCF5F309DF3
+:10B8C000FF1D29B8ED9B0C19BF6FD8FDC611B2BB87
+:10B8D00006751EDFA59D33182761FF9A30D11C1D08
+:10B8E000B34F445D6654BF9FAAD37E8F0539CDA95F
+:10B8F000BBC9DFA97E71F0BF8BA9F9B84BE96B8496
+:10B90000C0EB2C1F103EF287F58287E545758ED17E
+:10B910002660DE23DDBA5A589E90CE35DBC99EBB29
+:10B92000D006FDE4073A47349B5F8FE9A3BF35B8E3
+:10B930007691FCD6BC53994C7D76E79B0B947E8D1B
+:10B94000E7A962C52E8B093FD19F1BC7ECB548A163
+:10B95000AFC484F55026857C8FC4E715CAFC63D339
+:10B96000EB9A3EEFBF32596853001E000000000002
+:10B9700000000000000000001F8B08000000000015
+:10B9800000FFFB51CFC0F0038AC515191844D41924
+:10B99000184C341818566820C46989B5B829D39F43
+:10B9A000C9C2C0900DC4B9409C0FC47C4C0C0CFCA7
+:10B9B0004CC4EB171445B0F50419188480FC6F02D1
+:10B9C0000C0CD7851818BE8B30300803F92E40F1C7
+:10B9D0000420CE01626FA0580B905E04C4DD402CA1
+:10B9E000228ADF7C5102F26B8551F937D1F87B84D2
+:10B9F000F0EB5710C12FAF47401E1B16D1223F3E20
+:10BA00002229D03B10585F01955F26C7C0D0270F71
+:10BA10008C7FA8B80192FC4B20BB5C0EC2F69660EE
+:10BA2000602806F20D15B09BEB03942F01CA7D85AB
+:10BA3000CA0300CCCCBA8C680300000000000000F0
+:10BA40001F8B08000000000000FFE57D0B78144507
+:10BA5000B670F574F7CC2499994C12F2E03D490088
+:10BA600011030E2144C0709924C0A2460D021A147D
+:10BA7000750292849097887EECAEFE330189A0A86F
+:10BA8000F1B9AC17DD416137B2E8060C1835E0605A
+:10BA900000B32EBAC145C0E72680BC362443F0B9B6
+:10BAA000CB5E6F9D53D533DD9D09C4C7DE7FEFFFAD
+:10BAB0008F9F5FA5BAAAEB71DEE7D4E942328F27E8
+:10BAC000640A21DFC18F969F8B8490F850596F20B4
+:10BAD0002E924188D766F46D4CA6CF88237AE6680B
+:10BAE0005A981DD1375843EFE9CBD59EA434691835
+:10BAF000210F791C5812E223844EB55A2005F51601
+:10BB0000A83B93E07D3A3E21FDE8F80F46E2F8308D
+:10BB10002D99181A671031E07B53ADF989B01E4298
+:10BB20006A47E6C3FC163B21FD7B9F9F8E88EBA7EF
+:10BB3000EF0DC1F724FA9EB5EFEF2965570EFD13FF
+:10BB4000F6DF6DF66D1408F1EFFCC77158EF9986BA
+:10BB5000390E135D6F76B7D93F05EABE6C9F89B683
+:10BB6000E76EFBC026D1FEE5DB4409DA0D3B23F08E
+:10BB7000FDCE75820FEA95A6D647AEA4F5C03691E4
+:10BB80003C0FD3F82D069240C87133613F8715EB07
+:10BB90004511AC5ABE7ED76D305F49A38944D0F7BA
+:10BBA0008F37882EA82FD928F8089DAFFCB5078CB1
+:10BBB00003E878C53EA13EC241EB1B1F333AE83E85
+:10BBC00097EFFCD8D646E17CDA63260E23EEA3A4D9
+:10BBD0003E8D9052DF96E903E8FBA59B052780BECA
+:10BBE00074DDD94E585F69833C5CA4E32DAE8B2293
+:10BBF0008E916CEEEF08CCD77C14E7DB260F83F92F
+:10BC00004ACEDF650424E56E93912ECAE93A60DFDF
+:10BC1000CABCA73D6B713E059EE52FD2F968BF8A6D
+:10BC20009705276CB1C240DCB08ECED7220A5EB039
+:10BC3000C0FEAA8D23ACEA7D146E877D94FAD61BD4
+:10BC4000A75B607DEB8D4569A1F116D7FDA7767DD9
+:10BC50006B5313DD69BDE3F3B487827444A85E4A75
+:10BC6000880BE94FF219818E95E7E78518C4F7E252
+:10BC70003A9138CCA1F1153AF07EC0E9748795F17C
+:10BC800001C7DB123BE02C84B76E3BC7A314C8543A
+:10BC90008FAF948F003EE87A6A3D762C1FF72461BF
+:10BCA000F9A4C781707BDA3312CBB51E273E7FC65D
+:10BCB0003301CB751E1796CF796660E9F3E463BF55
+:10BCC000E73D05586EF0B8F1F96F3D2558D679AAD1
+:10BCD000F0F926CF322C377BBCF8FC65CF2A2CEB51
+:10BCE0003DB5586E057CD1B2C1E3C37EDB3D7558CE
+:10BCF000367AEAF1F9EB9E462CD77038DAB248B6BC
+:10BD000044E16073113B453B89CD7365CBB41E9B09
+:10BD1000CFEA09F3BCD9465A4F70D33A85CB80326B
+:10BD20007FB689D60754B1F621F7921C33AD0FF1D7
+:10BD3000B2F69435AE9C085A4FA965ED23D67973B7
+:10BD400022697D848FB58FDAECCF89A2F551F5ACED
+:10BD50007D4C13C9B5D0FA183FABA7EF73E55A690C
+:10BD60003DBD95D5333FF1E6DA683DB38DBD3FA9C2
+:10BD7000C3273A2C3DF1B055762C2014574DDEB92F
+:10BD80002E89CA9BAD46C75DC449C87BDEF92E89A2
+:10BD9000CA8706D985ED6DDEC5AC6E74617BB77759
+:10BDA00029F6DF2EBBB15DAABE0FDBB71BDDD89E27
+:10BDB000505D83ED8DB217DB47563F8AED8D462FE0
+:10BDC000B64FAA5E8BF5D7651FB6E755AFC7FEAF76
+:10BDD0001B7DD8FEF8FD9B5C5369FD05C1BD1DE4CC
+:10BDE000DE0AC15D4252819EEA9340EED570F9F9B8
+:10BDF0001C101D6DAFE96F443EDCFA6EE60BC0BF50
+:10BE0000F8EB07F5A2DF3E988CE3BC89E3C8741C0D
+:10BE1000F1E2E3A4BF3741334EFA7B25CA382D380F
+:10BE20004E44DFC6D9FADE24ED7ADE2B55C6D90F93
+:10BE3000FCB4C2DAB77DA5FF394BBB9E3F9729E31F
+:10BE40007C84EB89E9DB7A1A3ED0C2A7E183207CAF
+:10BE50008EE238F17D5B4FC6412D7C320E06E1D378
+:10BE600081E3F4EFDB380D07B5F069381884CF971C
+:10BE7000089FC17DDB57C6212D7C320E05E1F35FA3
+:10BE8000B89EE4BE8DB3FD532D7CB67F1A848F49D6
+:10BE900080F50CEFDBBE323FD3C227F3B3207CEC3E
+:10BEA00038CEA57D1B67FB675AF86CFF2C089FFEF8
+:10BEB00038CEE8BEED2BF3AF5AF864FE35089F1478
+:10BEC00001E033B66FEB69FC5C0B9FC6CF83F0B922
+:10BED0000CC719DFB7F54C38AE85CF84E341F86461
+:10BEE000E0BE26F66D9CC6E35AF8341E0FC26732D8
+:10BEF0008E33B96FFB9A70420B9F092782F0998E9F
+:10BF0000E364BBEB985146C7B1F63ECEEB67B4F0A5
+:10BF100079FD4C103ED7E338D3E838A9171F675294
+:10BF2000A7163E933A83F029C071AEEADB38AF77AB
+:10BF30006AE1F37A67103E8538CEB57DDBD7A42E53
+:10BF40002D7C267531F88C3B50956BA3ED54173A38
+:10BF500045FACA951D2E9740EBA29DD545BB93800F
+:10BF60005D222AF606697589F47DCBE698F4078987
+:10BF7000DAEEC8B913E8C74AAD31B5DD113D21523B
+:10BF800063E7C4B86235F5B8190334FDE3F35334FD
+:10BF9000ED8905A334EDFDDDE99AFAC092499AFED8
+:10BFA00083AB7234F5A1CBAED6F44FF6DEA0A9A7D1
+:10BFB000AEBA59D37F78ED7C4DFB256B4B35ED97B1
+:10BFC000FA9668EA97D5FD42D37F74FD724DFBE582
+:10BFD0008D0F6ADAC7FA1FD7D4C7B53CA3E93FBEB5
+:10BFE000F5794DFB15873769DA27B66DD5D4AF3CA7
+:10BFF000F9BACECEB3D88F5FC6EB22D03D61767F43
+:10C000007FE6F7F8AD46AC1B0758D08EDF652D7282
+:10C010001CA3F835BEB5C0D18FE217700A7E45F675
+:10C0200080924BDAE8F37B26B92FB1D3E7F718DD1E
+:10C0300097DBC3D8A7941E049204A5C300A5BEFD38
+:10C040000199D163CEC0F323DAE9FB9586C0881845
+:10C050005ACF12B31B817E770ACC2F8A144915F46C
+:10C060008B3411F40B1E48CE7CC1ABA2D75583296B
+:10C070001F0AA17157C9EE24B033DEAA6EF7821DE4
+:10C08000523398EE6B0021CD42BBDF4BFDB4070667
+:10C090001725B9E9782623B5D3D5F31BE9FC693810
+:10C0A0007F0BD0EB7B307F7CCFF94D291334F39B92
+:10C0B000879468E6371BE9FC7642DEAF3EC5E7A70A
+:10C0C000489844C85F845338BF694809CEFF8091BF
+:10C0D000FA2BEAF92383F31F86FD7FD6DBFE532676
+:10C0E00069F73FA454BB7F23DBFF91EAB37CFE4892
+:10C0F000DCFF51E12CDBFF9052B67F131B3738BFBA
+:10C100002D08FF93307F672FF39B52B3B4FB1F5A68
+:10C11000A6DDBF89CDDF5DFD2D9FDF82F39F13BEBE
+:10C1200065FB1F5A86F31B4D6E27D08F7160649597
+:10C130008FCE4F1D6107490472A1F340393216FDBD
+:10C14000E49784145CC73D918CDEBE8AA4F486F229
+:10C15000C6CBFC581F956C99D4EFE2B4BE7873B689
+:10C1600011E412B6537F65215FEA1D8D22D2377923
+:10C17000D2E41B4ED7DBD9287AA17EC793937D20CA
+:10C18000FF2A4DE4F67C784F227E78FEF953A39F78
+:10C1900057EF4B5F2EAC958FB7A9F82DE847E59088
+:10C1A00091551698D7AEA91FA17E10A1FEC527D420
+:10C1B000CF2094248FCA6CBECFA8BF04F536EA2FD7
+:10C1C000413B21D5B85FE2757D308CAE3F9F283F63
+:10C1D00017EEF32664293A9EC4F8F7C81AC107F887
+:10C1E000B87D5914057E683D85DE384D9DEE0FFB08
+:10C1F00007AE127CCF0B38861BE033938F4760BDB0
+:10C20000B45E6067EF1CA2E8EF4F51B060D5408A82
+:10C210008BD038B3884B4EA4EFCF595A2843E8A2AD
+:10C220005510062F01FA5920539711E0E78D276921
+:10C230009C38E87A6FB6B3F167BAE4636DAAF51477
+:10C24000C866573E5D4F41A188EB9F3543DBFED169
+:10C25000CE2897610C2D573D81F3CCC9D7B6DF545A
+:10C26000A0ADCF756BEB54EFC9A0F76E29D13FA7F6
+:10C2700060A1FB9C17842B5D285DE7AD1C0EB756B3
+:10C28000C95E0D5EC16D55DA21A0E026B82F7C5F36
+:10C29000ECD9FFF665DA7AA1575B5FB04A373EA763
+:10C2A0009BE31CFF47803E687902E883C2F318A72E
+:10C2B0008F905CD5D2C78DC16D30FA50F6715C623B
+:10C2C0002838BE8ED1C7C2DAA8F0F45018A4079758
+:10C2D0009ABE147AB88DD3C3A79C1E8AD76AE96A1E
+:10C2E0002EF1AD4CA2EFDFB26617E2E9A050C8E82C
+:10C2F000E1970A3DB469E8C1CDE9418FBFDB383D24
+:10C30000DCF673460F7A7CB6717A685B7B4E262921
+:10C310003DF14AF1A0A9533CE8F06E37023D507C54
+:10C3200084A587F9C17DD38DD3FA02DED6035F9C45
+:10C330001EB03D05C04E104EF87E6ACFFE544E68CA
+:10C34000EAC56BC3E3BFB2313BEE986A5DE5F557D2
+:10C35000C51D53F55B5C3753535FE49BABE95FBC92
+:10C36000B650D3BEB07691A67DC1AA3B35F542EF5B
+:10C37000CF35FD6F5F56AD69BFB56AB5A6FD969224
+:10C38000C734F5B9EE5F6BFADF54B05ED33E27FFDA
+:10C39000454DFBAC195B34F599AED734FD0D3B2F01
+:10C3A000BD1EE831EBA048C0FE38E67120DD1FF766
+:10C3B0008CC4F2A4C7897C71DA3301CB7D8DCD4F5B
+:10C3C0005C49BB7C192888264C7F16911842F62CB4
+:10C3D0007757AFCA027D4E50EFFE717951B5771095
+:10C3E00095530607C2396FAD91F8C711228052E20A
+:10C3F000F307C4507B561B6D8FEBBD3D6FAD14B67C
+:10C400003DAB4D0A3B6EE5E38543ED61E233217EB2
+:10C410002603C13EEAE2F6B9BEBD4C20F9EAE78444
+:10C420002C47FE8F3130FD5C666472A26C6BFF1C82
+:10C430006283BA7F44D585E6ABA7CC9508F491AA70
+:10C44000E1E3E2B59769E43C81E86D3CD0D938CDB1
+:10C45000F3C575576ADEEBD825E2BA2B4086507DCE
+:10C460003D8CE4070CA097FDCD43668D8675BACE52
+:10C470001A405E35C6A3FDD8E19911774C023CE61F
+:10C480006379D25380E5718F1BCB639E122C8F781A
+:10C49000AAB06CF32CC3F2338F17CB4F3CABB0FC7C
+:10C4A000C8538BE561CF5A2C0F7A7C581EF0D461AB
+:10C4B000F9BEA71ECB564F23969D1E17960ABF297D
+:10C4C000F0D0D3DD49AEA74F03FD5D80CEE2C407B7
+:10C4D000AA570D0AD159E28A87ABBD59A171F3D68B
+:10C4E0009A389D2468E86108F864E3815E4C9C5E9C
+:10C4F000C2B7E7AD952FD89ED526871DBFF2F97F2D
+:10C500000DBDCDF991F416A2A7813A7A4ABD183D26
+:10C510004D12C787E8698EC1CEF41FA7A787601F99
+:10C5200061FC8F6230EAC6ABEC3A57148B67F37349
+:10C53000076AD1B278369F7B051DAE15ED3FDF4807
+:10C54000C073F7C8BF8F80787DF761AA28937BDF1F
+:10C550009F9E5E7A87BB0BFDA0221F55A2E37AB691
+:10C56000474432B84618C80C924EC8EAE1BF75CEAF
+:10C570004FC3BA4462E17D9F736698F32802674F08
+:10C58000891787EB0AEB576360BCE3CFFC2313CA20
+:10C59000398614E6DF348B68DF13FF0B4E806F5053
+:10C5A0001F999C4910070F0C37DAD13EF059B4F0AF
+:10C5B000F3D27A66087EAB298C5A51DFD72621FC4C
+:10C5C000867D35A27F1FE07731397F3178CEF70D38
+:10C5D000F897C0F362F2F1627291B81C2F37D2FD66
+:10C5E00077ED1C9DFEA003E4E085E1AD9C5FE9D7FB
+:10C5F000F3BC287D2F3AEE4A50E8B87508A1F388BD
+:10C60000A21DC7EF6EB884C92FC5EEDB66F2F50533
+:10C61000AF6792B5E33DC5F94F19AFBBE5051BF810
+:10C620005B4B920CF66361F0A094E5F5C9768BDA6A
+:10C63000FE6CD4D6BB6B8519F568273AA2678F06C6
+:10C640003D61B71F1B06723B094B659C254946FBA4
+:10C65000312AF74ED7A546333FCFC7E4C1E6189439
+:10C6600017A73D66ECFF53AFA7B77194F510D24002
+:10C670008E9A411ED3B6D4DEFBF74ACFD217463C82
+:10C68000F76D92BF02FBD04CFFFF0EFC0D22615DE7
+:10C6900019B7B25EF49A2E87E79B35F3D1F71CCA1F
+:10C6A00019EB772917E21B891C57E896EA8B635C24
+:10C6B0009F2CAE8BB06BEDCF184DBDB2B1BF5D639B
+:10C6C0008FC21F54FE922A4102FA29E3E4D325596E
+:10C6D0005609747D6F429010E85660FDCACD6D46D4
+:10C6E000B703CE9519DE7A5B1FC5DF4C89927C8932
+:10C6F000B916CF614BEA2F9D0A7AE64CC38A0488AB
+:10C700001B2C16BBEFC90FF3BE2C3179BFC827070E
+:10C71000B4F63DA70F42C7559E635C94588EABEAB2
+:10C720001D06168FD18F9B00E3C65F1C3E159BF73D
+:10C730004F073B410FA78AC6B34637CA45FA5F6623
+:10C74000084E0AFCDE14F313243A7E695D3BC62DC5
+:10C750004ECADE11BFBC80BCECB93F4BD2F128D52C
+:10C76000BEBCA415E6993F814F441C377D4CE5F8CB
+:10C77000A93FC904E410394F7B65624886FB3B063C
+:10C7800062C80CF93BF31B16E701BC4F81BF47E5BC
+:10C79000E61D24DF867820B599E0DF9C218619000C
+:10C7A000A733E47DDB38151E7225238733958294E9
+:10C7B0001E4CC1F1DDFDC1EF3215D4B48A63E0B97E
+:10C7C000A4F83FC2771847720B98B750C09E7B8978
+:10C7D000B91AE897FA511A3F8DFA519A3AF5A334EB
+:10C7E000F522724302E425143D29139F8070D2B4D0
+:10C7F0008F92EC88C762525503F6D1AF79FC6DBEBB
+:10C800009D4803E93ECB5F7D36B390EEE76A89C56C
+:10C81000FD9473F545B10C0EA5253EA3CBD2737FD5
+:10C82000471BC6DD48253F8CC7CECF6F36621E053D
+:10C83000B44A99DCF449E97DFF890DA22BC206FDBB
+:10C84000E87365BDC9DF7FFFFAFD12F238EEA3B4CD
+:10C850006E2601FAEB9127C0F723D7092E5F187EC9
+:10C860002AE474AFE8A73B017EE343F1ACFB74F527
+:10C87000D51CBE4AFD295DFB0F962FFD8846BEBC28
+:10C8800029BAEF93C6337902F017A400F2D70F1E2E
+:10C890003FA9C7F8AB811F7FB2F10769F99E8EFFF0
+:10C8A000D44FBAFE613DD6BF3EDCFACB5F7D69BB9B
+:10C8B00097EA97D23F3C652394DF4E49B5094E8AEB
+:10C8C000F7B28D2B6D2E903B92D7067C71CA27CE86
+:10C8D00008470F87B87CA506884580782BFC49C798
+:10C8E0003FBDE9A1EBC09EF86AA36CC7386A9DC939
+:10C8F0006FA2F45CD1B0288F8CC17A3BAB3F70162D
+:10C90000E8BFB2513EA2A6D3D2DF3D95007935945F
+:10C9100052061A92A0F4A37F52B1E1F3E9606F547A
+:10C920009200F2ABFE3D98FF9B58D48785C6E89EE7
+:10C93000ED18984980F7D9AFB2E1A1B3A20DFE6A14
+:10C94000C33890BE7F09F7375A246B3F3C27B98222
+:10C950005C01F2548107F1317F63C58BBF1AD34E5E
+:10C96000D7D3B1E14F36410527C54FEAAE5FF09B03
+:10C97000D71DBDCBEF4ECA876ABB56D14F8E46EE50
+:10C980002735B1B24CF6DBAEA4F2A46CBDECF4D208
+:10C99000C7652FBDF0DB67207EFDA1C9399C8EBF26
+:10C9A000F8A53D0727D1FAE22D72BF3CB60D8B905A
+:10C9B00010C24B25FD7F597A080FA5AFEC313A46DE
+:10C9C000B3E7F7C686F0B178CB2E2319DD131EB975
+:10C9D000F5BB8C6D963078A96F9F0E76DF8A17BFF6
+:10C9E0003682BC3BB5532089C961E0B97E0FDA8538
+:10C9F0000027C423C753106FBAFE95142FA05F14ED
+:10CA00003CE9DB37717902E339D2909E5F7E9DCE9F
+:10CA10005FF291C909FB2F79F92E1BECE38454C511
+:10CA2000E8FAD9950920DF4A646F821D4BF6BCE411
+:10CA3000B9BB91DE8AF7DF9DC0E292AEFE06D495C7
+:10CA4000DEFEB0BF85EBE6E0FE8A881BE9AEE45966
+:10CA500031DF47CB2F2532634B18BEB8566672F2D2
+:10CA6000C4F35423D0FD9D50F4C0FB22D70377625A
+:10CA7000DCF36EBE176A3162FD4B33C3D330D9C0CD
+:10CA8000E52CD32B417ADDF000EA8BD3835D8970EE
+:10CA9000BE5619D20FA837C4FDD312197E989EC175
+:10CAA000F7A89EC985E7D0BF5576458CD1BC877A5B
+:10CAB00045997F299F9FAE3B12ECB51309E1FD8F8D
+:10CAC0009FCB0ADF53BB42455F2AFE66FCBE613541
+:10CAD000E36F85DF7D336740FB170718FFC07BA03E
+:10CAE00067E9BAFC89D8BE6BB680F2C044FCE1F8B5
+:10CAF0007A83CCF95ADBAED0095DB72444ABE805A4
+:10CB0000C68F45F8A35E2F7A92BEA7929795309F65
+:10CB1000ADE7780ADF1673FE9F216BF99FAC8BEFB0
+:10CB2000533E6599ECFBED33C0AF943FBD0EE0572B
+:10CB3000391FF6FDB7CDCD076FA67CFAB77A854FC2
+:10CB4000B5F253CFA7255BEF26409F7A3EFDDBA0D1
+:10CB50002A12964FE9F3B07C3AA8ED7F547E2AF072
+:10CB6000AB02F84585E0A7C8C3DEE0A8978756D991
+:10CB700011561ED2DF0192D993FE14BA53E8ADF4D8
+:10CB8000F7E54341EE04E952A1BB205D2A74A7DF1B
+:10CB9000AF167EFAF64932C175E5BF26A3FF5CD613
+:10CBA000C4F242E97B7B0766209C5CA8C648EDDEA8
+:10CBB00081FDD4759FAE5EAFEBEFD2D5F375FDDD91
+:10CBC000BA7A95A67F5963B39120FEFD9A7EE2B2B0
+:10CBD00067C8D1B870F4EA637E59C359A317E8C295
+:10CBE00012C0F7E5E5C40B7986811D22C605BA2877
+:10CBF0008C6B207EB139D9E7A5726365048B3F74D5
+:10CC0000D903B6585AAE8C61F540BCB106E49EF229
+:10CC10003C10C1E28A5DF9015B8CCA9F6A6F1251B8
+:10CC20006EB7F9C88C707E16D528C8476DA4B77644
+:10CC300076EE354DB40C590671A55AD10936F81D5A
+:10CC4000D537D9E0DCA9AB29F5FA02FA7CE11F451A
+:10CC50004C7BE98AB48D817511AF4BEAAFF26F4E10
+:10CC600012EFD359747F0B9A989F73C71A9D3D4258
+:10CC7000D6203D1559961A419E527FE288F6BC8611
+:10CC8000F145291FAF649DB65D799FD201FAF3A5E6
+:10CC90001BB4ED6EEE0F7FA0F0C9583296FBA32CAB
+:10CCA0000EC3E5F23431EDFA028A8FAE1691986820
+:10CCB000BDBB49447C746F167C104F23DE78E4B70B
+:10CCC0000A124079A8C0A903F8C9D8BBBCEAD8F6B3
+:10CCD00069E62F816EB67F3CE63F69D9B1FDC3118D
+:10CCE0006F40FDD543433E263DFBE7EE8CC073FF0E
+:10CCF000AE9D56A4F7AE1DEF0EF925D45F33396112
+:10CD00009D5D3BBF1E03F4D3B5DC5402F2AE6B3025
+:10CD10008BC7AED8F1F59836D4AFF733FD6164FE1A
+:10CD20006177D33F3E13FA4149770576C3CE28E4B5
+:10CD3000A7CAD72330DFBB6BC7D7996ECB4FB79F3E
+:10CD40000A9EE7D16525055B617D312C8FA1F28DAF
+:10CD5000892F54D3F9CB1B761917D0F6DC37FF395E
+:10CD600006E468D756660F75CA6DCF411E4394F12D
+:10CD7000DC7299E2AB13988A3ACDBF3366E402DFE6
+:10CD8000F484CB3F313ED65778A4FCAF8187E06274
+:10CD9000F2CEEA330BB0EF6F3FFB18E39A26A44BB9
+:10CDA00065BF7FABAF467BE562FBCEFE7F6EDF8269
+:10CDB000BF2FFB76FF9BEFFB38D7BB7A3EE849E7F6
+:10CDC0003BEEC1FA4B5627AEB78FF4EE85FDC7FF99
+:10CDD000FBEEFF7BE37D2BC5BBEDE2FBFECDFF5AF7
+:10CDE000BCFFF1368E773B7ED7F3E63F717DDF5790
+:10CDF000CEBDF96F8EF7DEF6AFD8F5AD862A7B068D
+:10CE00005D5F01A9B582613137BEDB92E1806CD7ED
+:10CE100073FD308F0ECE4BC3F84D0123F30B4D90B5
+:10CE200047077EFB1C41890BA21F751DB71FAE1B58
+:10CE3000548276C875AE8799DD2055B566D3FEADB0
+:10CE4000390B9C987349D20FBBA13E7B32AF6BFD6F
+:10CE5000C9F704E212A81D7F5DCE352D60D75EEFC5
+:10CE600012D1EEA525DABB1F0C99CE9E4FD0FA3D0C
+:10CE700073DDDAFA4D05DAFA1C3EDE8D84ADFFC6AD
+:10CE80007CC107715553F613F11067352D948990C5
+:10CE90000CF942552BC1BF9893AF7D7F1FF8C1E3BA
+:10CEA0007F3C1C534D0A1C97205C48B6E8DC48FACE
+:10CEB0000047BEEED6D9637D90CF4C242783E38D07
+:10CEC000E54E8C83737F5BE6EFCB9655ADC0CFB25A
+:10CED000CECF56FCE5DEE04DB8FF8DE3A484E02F15
+:10CEE000BB44F4BF659DFFADE0E5FBE243C1E38FCA
+:10CEF000C5CB973ABC0CB2B808F0ABCCFD85A916EF
+:10CF000027AB0FCA2778DEC8FD05A99F8B78D342CF
+:10CF100079DF8BCCE66C385F338F1430DE71FD1A0D
+:10CF200011F583394DC075E54F90318FF873437E0D
+:10CF300026E03B6FDC1515BF60CB70023C1771B863
+:10CF400017912AB45FC9F9EFBECBCA84730682F683
+:10CF5000EF221721D752BFAD284BF0475278154B1F
+:10CF6000C41B9D0E716F811CD1C4BDB575F8FD4702
+:10CF700042689C8BF5EF4DBEFCD4E55FA93C3B328B
+:10CF80008CFA411E9EBB4958DC56F1AF6F6F627040
+:10CF9000AC2C137C2948777E395F75EEF81CE7834B
+:10CFA000BFDE3B0EE564F6A3A3A3D1EF7739D06FC4
+:10CFB000A8E47E43B7D7110D71AEEEA6547E3E9B1A
+:10CFC0006B53CB55A5DCCFFDEEBF407E212DBBA61C
+:10CFD0000AB522F8712480F15CEFD408B2314CFE1E
+:10CFE000EBFF311938FD54611C007E6226E091FD93
+:10CFF0008AE9ABD1B12ABCADB9F69434A6271EE0BC
+:10D000007744750EF963E10B7E3EC0757F44DBF417
+:10D01000FC30FBAD35B13856DE5BDFE2779C373450
+:10D0200025CB00971BA68A9A73FB5526EE978D2376
+:10D03000E3605D796F5D659B087869119DF0DD6641
+:10D0400065D359A33BCC79B01E9E303EC4D58FCA60
+:10D05000CE2280E7D1872308F8D1EFF273C634F8E7
+:10D060006E220D433A2E882BFE9AC3B5D364C77245
+:10D07000565EB61C4FE74D6BB08F85A3D401BC7FC5
+:10D08000271821E3218987BDA7F41B50C6FAB51BD9
+:10D09000ED15E1F63F3C82EDBF9838EF9920FCFB9F
+:10D0A000E12DFB51AB3F07EC83A93CAED283AE0927
+:10D0B000F247F70CC107FA1BFC61ACE7B1EF84DF64
+:10D0C00055BEB3BE81E95985EEF570DECBE1ACCC3F
+:10D0D0007FDCC4E2AF7FE2FCA5C05981AF7EBD4AD0
+:10D0E0007F2AAFA6A8E351D7378E7D19EC9B8A26FD
+:10D0F000C16EA04355486D46E0C3CAC6C764386FC9
+:10D1000099EB60E312297F8C3A9FA0D3C4F23B9A3B
+:10D11000D3AFBC0DE8E4DC1A13E842E2BAE3AC0D8D
+:10D12000E4F0BB06E79FE17B6AEF7B22D9780179C7
+:10D13000F5B1A7CE3555528F9B8CEB9C55962D4360
+:10D14000F8EC96B25D72A28A9E3A4DB1D8AE3C1F01
+:10D1500050E64887E7743E5C87F7111381EF42D2AF
+:10D16000EA5BF1FBD45BAA62181D96D4EF32623DF4
+:10D1700019FB2BF329F3E8F969769E36EF78416EB7
+:10D18000DB20804B9EC9BFD419864E1F332BE78E00
+:10D19000DF534FB828DD8EF9FF484F2C55F4441B60
+:10D1A000E6B92BEFCF35333E57E989C4707A62492F
+:10D1B000B52311F0B064476A2230C9923F4E4B0844
+:10D1C000A7273EF0B073E343FCBBEEAED9544F5CEF
+:10D1D000AED213B323904EF4EFE59A95738D8BE89E
+:10D1E00009056FFFC3F2E603D01361F8FB46B3569F
+:10D1F0004FDCD854887AE2C6D9A2E6FBAA6BCD17D9
+:10D20000D313D90973B12E3BA3C2D0CF07DCBF39EA
+:10D21000C4F3FB611ED0176BCC76849B5E6FF42643
+:10D22000D7C7F655AEFF5F82B322D797CC61F743DD
+:10D23000F4A44382F4BC642E95EB02D02393EB4B11
+:10D240006EE5714E9D9CCD07399BA196B3ECFD0A0E
+:10D2500037D30B958DC9BF9A47DB6FAE959D66DAC4
+:10D26000FFE690DCCD54CBDD356609E1DC43EE967C
+:10D2700030B97BAE691CDA4FBDEDEF532E6FA93C80
+:10D280001BE60C431F05F3A234DFDF1D1DFB76DA1E
+:10D290002BC02FEF8A787EFB39B703F68D7D3B03D9
+:10D2A000ECE9537C3DDBB8FCEBF4F85C53A91CC8FB
+:10D2B000BD83D9D3E59B45845F4503E3FF8A619134
+:10D2C0003E07AD4F4FFF16CF6117EF60E7B0740711
+:10D2D00079D92AFC2F7EB7AD06CE0516AF17F01C04
+:10D2E00019BE5F0078167378163917E3394AF1DAF8
+:10D2F000F0E73FE5BCDFA2A6F5180F5FE4D3F62BFD
+:10D300001F76F529F047F24C0C0F79AF08BEF5C92E
+:10D3100090CFA0EBE75C8DE747E5F5DAE707F97E0C
+:10D32000178AFEB457E8FBE4CFCCBFD3C3FBA01EE3
+:10D330002E253F122EFB295C32FEF570E90D0ED42E
+:10D34000BEC7F3013D3C0E2B72259D64001F7E6E0F
+:10D3500070A15CF1BE43E142E7BBE3B1E19AFB405F
+:10D360008E73B8BC6B70D7F4877E1502F62B5EB750
+:10D37000654F02ADCFAB2763E178A178AD560F07BB
+:10D38000F57E8303F5FABCAA2D02E4C72EE4DFFB89
+:10D3900095F81EC37B546E5D46F53CEDBF20DDE481
+:10D3A0008673F0FD1101949B0ADDC64730FB258E84
+:10D3B000CBA1A3030253513F350A76E4477F04D340
+:10D3C00057144F70BF4BF3C4AFA773BCB0B8522310
+:10D3D000C36325C51BF0F3F4265EAF6376E02D4AE8
+:10D3E000BD5EF0390490ABBB64765F8C40E2048E86
+:10D3F00004957E84F3D5EC04159E77B433FADF28C8
+:10D4000038F1818FFEF743F0DC2BDD333BA6AFF420
+:10D41000AEC0293E428BE7FD11AD79E3FAC1F99B1D
+:10D42000E0C47B739A62F09CE8582DBBFF2595BF42
+:10D43000A7E70BF03BD4F7D1CC8485437EF38C086F
+:10D44000CC0FC57953985DA6964FFA7B80BE6FFED0
+:10D45000512569457B2C94C7E87EDE04E3CD10346A
+:10D46000F94E1009033AFF09C6BFD57C81F14992F4
+:10D470001DF396EFB22BCFEDECBB2C5E6F1E9C79AB
+:10D48000681E85EFB955A2135CA89B0C8E835920AA
+:10D490006F1E9409F0CBB97DB28BE98128D43B850E
+:10D4A000EF1EC5EFD90A590E1A29BC8FE997A37C44
+:10D4B0003D1F51BDED82580AA91F0FF7E0CC76EE53
+:10D4C0009AE680784BC6FE9570CE392BD77EF02039
+:10D4D000E07335BB07E9C8AA5CF4D3EEBA53407ECB
+:10D4E0003B4CF106EFCF999D7CF0209DF7D655F18E
+:10D4F000786E39CF157F239C63CEDB273A1DB4DFCE
+:10D5000082EBAD1638C7BC66A448DC2AF8DC4A5A60
+:10D5100031BE33AFEACE39B0EE12AA0FC56428F798
+:10D520004F4B84FA3A01DFAFF4BA8DF0BD66EBDA07
+:10D53000B3C60C3A7F11ED0760AF5CC7FA556E10A9
+:10D540009C90FA5DD4F418CACBA20D025E34D34A83
+:10D55000ED5F331BD767A6E3B6AEA3EFD37A31BC3A
+:10D560000FE36E88B911CE272BE93AF1FD09D57882
+:10D570002E5D44DFA3CDA475C39D38DEA275028164
+:10D58000EF034B26243F3201C6DB273BA1FDD0AE83
+:10D590005F1B61DDB7D1F9FAD3F117886DD3A03FD6
+:10D5A000F9A560C7FB87EA4660DCAD0B360C2F544B
+:10D5B0000DC73AE6133B100C923A1F654704FB4E29
+:10D5C000B86859750DECABCD1B9F6C40BA3A6B0433
+:10D5D0003D7E8CC2DB4D873C6A64792ECDDEA3C6CE
+:10D5E00036951CFD282215DFBFA3311BF3261692AA
+:10D5F0007CCC9B7057337BA47D65840FE26AEDB2CF
+:10D600007D083C6F5E69C2E79D2F31FDD339B80DAF
+:10D61000E3DB27D6C904BE5F5CB12EF569C0E389A0
+:10D62000CD32D29BF82CCB1B287E89C5C99AD7B1A5
+:10D63000714F2C35B27BB5A09DD68B5F54F20AB4E6
+:10D6400072ACC8518A724A2F97F4726BD193D54647
+:10D6500020D91EF26AE9749457A554EF00A1F59001
+:10D6600057836A306EAA975795C4A2C8A974885F79
+:10D6700016960FBE6D2DD0F1ADEC838156FF6B5F1A
+:10D680003E057AB7CC4AE04985647F5A6074418090
+:10D690005FE6356DF912F8A0645E04DEC7751CF014
+:10D6A000007CB3260ECFAF8B7C85086F252FB77813
+:10D6B000AD96CE95F8E35CB7485C6AFD5512455CC3
+:10D6C000AA7E87EEA3F44AE7B9BD51F081A83C7465
+:10D6D0005FFBDEBB33B06EC7752DE3F6C11A2BD2EC
+:10D6E000F3A19F9F5D09F47ADBBD02017B9D78DD8C
+:10D6F00035A00F2BD60A0E880F17DFCBDE2FA6EF33
+:10D70000C3BA0FFD9AD115A56F07D07FC5BAC7F66A
+:10D7100062FF0D8203C63FB4BE10ED8912AF48B060
+:10D720007D433BFA0F544F619E59B3574C00FAAFFB
+:10D73000B8DF64075349A123852EDBF97D08C4ECCB
+:10D740001C338BBEB70A1615DF931EC50221A84FE6
+:10D75000814E2ABD8CCEDA5F929D403617A74BF6DC
+:10D760001DFC09AE5FC567E74C87EF748AA97E048C
+:10D770003A6D5E976B043BE2844FC0FC8A9E74490D
+:10D780002C6A3B4AA1CB670526AF7BD0A38E0E7BCC
+:10D79000D01DA74B85FE2851A35F59B64F26F0FD3B
+:10D7A000BD9E1EDD72FD8D90FF51F832DD0F5D6F65
+:10D7B0006ECDCFD15E57E048EB09502F9258DE8FE7
+:10D7C000C20FE512CB0FFBDEEBD3CDBF2982E7877B
+:10D7D000013F882C7FC94FE77D7BF30B982F79663B
+:10D7E00053FB7568DFBC41E900E0BFD94AFCE87F24
+:10D7F000F8500E953688986F4D247FE62C95DFAE55
+:10D80000E4BF2CFE8315E15DBAD5E4CBA3EF976EA0
+:10D810003F3A06F311960730BFC7BB4960E71FDEEA
+:10D82000B631F0FD50A9C4F270F476C1F04816E7A5
+:10D83000EA782DAA00EC36A18EDDB3575A7F936C9F
+:10D8400052C5750745CA382FED87E7635E8A67B80A
+:10D850001F01D6A7BEDF4DC9BFE97891D15F69A38B
+:10D860008CF65C69DD964EC8C32C3D6C423FB7B266
+:10D87000EEAC11FCD8DC3FBC84F7F355368A9A3CF9
+:10D88000BC1EF96F75A2DF04F95B0DE5787E43EBF2
+:10D89000ED58AF0F9F077AB13CADC57FD8B1DD4BD6
+:10D8A00041B8F895DFD9F0BEBED68D36FCEEA9EEB4
+:10D8B000C2F9A73DF2DDEA575F30DFED34FC4109E4
+:10D8C000EBBA485DBE601D936B747D99F961E2C44B
+:10D8D000417BEBA52F9F837CEC8EAD7F7B0ED65BCF
+:10D8E000F65FE79E83BC1AB233C20EF648E5A60F78
+:10D8F000309F5579AF2492D97F9D2FFE0EF3803B48
+:10D900003F343961B4CE1D278680BDD1B9E5DB0433
+:10D91000C8EF5DBA631AC673966ECB4D2461E205FB
+:10D920004A0974EBEB431EB21E5FCD0DCD98FF7319
+:10D9300086E21BE443307FB1BE9CE5833A78DEE2A9
+:10D94000E6F0F9DE3DF2141B665D3F19E46203B3B5
+:10D950000B2E9AAF7880E2F1F23EE06FF36A2E4F21
+:10D96000C2E3EF0CFC41F15413A9CD57FCB261E1C5
+:10D970006F9E81B686B85EF315FD7D809B924F3E0B
+:10D980002BD2F55824F0CDD6DF637E28E02DCF01D1
+:10D99000F2F9CB2110173E290730FE10D861C2EFF3
+:10D9A0002C4B771C42FEE9DCB61FF3B509CFEBEE3A
+:10D9B00024C11FCBC3E5B19ECA0D5696E7C8E10F3F
+:10D9C00079900E1B3EE7F98E8C8E953CC8DEF21FD7
+:10D9D0005B2253F87D2A2C4FB37CC3C73CAF308405
+:10D9E0002F6102E0A9FD8279A50A1CEC00872BD4E7
+:10D9F000F9BCE1F34C8379DF1C5F803F90D3C17C9D
+:10DA00005D5A1F04F99B3EE11009230F3AD7B33C3E
+:10DA1000E04E39FCF7CC4A7E6FB39E4F7D7DCBEB59
+:10DA2000BDD8FABF2F7C1A221D38AE1E4E1DE7C38B
+:10DA3000CBF1E39CEF7FF0F7216582FEFB93CF8172
+:10DA40001ECB1BDA8D789F89E23FF1FD76F0785A84
+:10DA5000C72611F33E6BEA9B518EEBE545053F2748
+:10DA6000D1AFF71BBEDE8A46A6273AB65A7D163AD4
+:10DA70004EC75BAF213D576C6EC7BCD3BD75AF18A9
+:10DA8000DB54E7CBA0277CAAF577BCBC6B0CCA6D36
+:10DA90007EBF987E1E63149BA7B229FC3C959BCF4A
+:10DAA0006AE659ECAD37DA2D179FEFB4E4BA09C630
+:10DAB0003BDDCAECA5D3F5E20C5F98F94F71BD4987
+:10DAC000482D3B0FA5FA12EF59B3B27BD5445B2426
+:10DAD000DA5F4BAD130E47F783D288792F2BAA79E3
+:10DAE0009ECC7DCE24C0F70AEBD504D6BB12E0ABAA
+:10DAF000F2E365BB9B80DD2627E567A8CF5994F547
+:10DB00001BFB19884F85FFA5D61989E07F12C93BF9
+:10DB100008D6715DCAD712E8BF560F8BDF93F34763
+:10DB200087C1F356C9BE278E8EDB3A557042E8B5E1
+:10DB300027DDFB347186992EED7DB1F80D1CDD5F7C
+:10DB4000B7D380F6A0D5E0B7D32EC41AD19A840EED
+:10DB5000AC8338A404FC1402F3211EF49867C1FDC1
+:10DB6000C83642CD53E8E79434F79F444F9074F79A
+:10DB7000A19003C328BD5A38BD2A71392BFB9B8E57
+:10DB8000DB86F7ACC4A4916A20DF355637DA0D4F37
+:10DB9000F0FB69E86F24E441C49248A7FAFE263AF4
+:10DBA000AFE6FB383AAFA61EE3D2D6E36648C7C25B
+:10DBB000E99738BE8EE9A205E11033CDA0F86B7964
+:10DBC000C31342EB8E89274E3FB45F6BC1EF012830
+:10DBD0007B79D5FBB058B4EBA6EBD3C889E8B43653
+:10DBE000AF81AD53F3DC4E1C02EEDFA57D4ED7AB0B
+:10DBF000A917467179271109E49DC5DC4A38FCBB99
+:10DC000035F0BE5FDA373801F043B85FED2590CFCD
+:10DC100012CDF741E7D7F4B7437480CDAF1D870C21
+:10DC2000B2ABBF43BD9CEBBF5196FC2551949E32D5
+:10DC30008756616276561249C3EFA59BFAA17C4ACA
+:10DC40005996837927422DA3AB616B08F2CDB000C2
+:10DC5000CF9BBA3F12ED5193997823D2E17B36E204
+:10DC600095D361161FCF43702C37D0A1A45594D6FD
+:10DC7000E87B4D811CC3428A847A68A2E35746B987
+:10DC8000AAA3289FD6CC742719C6C2F6DE5EB93B7C
+:10DC90000BB9F65288081AAAF7EE69198C2204EF1C
+:10DCA000F120DEBD7B80C66B953A15ECF09D7F6D53
+:10DCB00064B0EE3253795F9BC2EA8F3EB47725DCC5
+:10DCC00037936ECF7F14F649CCF65178DEE58FD5C9
+:10DCD000DCF3DD9B7E51D63972833F17EE05BE3AE9
+:10DCE000C0EEF51D6E0D7E778F7A78A345A9FBD126
+:10DCF0008FC86FD88F72ADBC7E3FB61BA04ECBA134
+:10DD000071FEDC81749F2F471D9A9674291DAFA167
+:10DD100030093ED97F35EAD01EF8EE3004878F57A0
+:10DD2000EE1E148283B4FCC33D2D93D570F8700FA2
+:10DD3000D8217D85C3AB0F7D8870E8EBBE295D6C73
+:10DD400007BC5C936DC0FBD6AE386CC1F80AFD45CC
+:10DD5000A03EE2E3ACEFE5BB6CC51FA1E3EC54D3FE
+:10DD600097F29E4257BDD14D2AB18F62F76C6AE996
+:10DD7000A72BCAF536ACAB25CA758F351EF78FF7C2
+:10DD8000005CE3763BA78E0BD135B1B8C7C1FDEE81
+:10DD9000A32CF35BA354F2F29AEC25620AC4C98166
+:10DDA00017E243FB895FE68D1841F719EF3260DE19
+:10DDB000FC288BFB20CC632B08F82177EC0AE21EB1
+:10DDC000278821BE50E6ABD9C1FCF59A42836F3952
+:10DDD0003BEF1560BC107DB4E9E823C0E8A3B11D9A
+:10DDE000E9A3A2A99DD14763754E64063B37033F63
+:10DDF000BF9604C602DE3BA2BE9A2651FA1F1A1530
+:10DE0000A801BA91BDE7A6E55D8A703D1D163F7C6D
+:10DE10007DCABE7AC36F6D4BCA4369E04FEE33E0F3
+:10DE200079970237A55F8C85E5C5B658DD5F03FCA1
+:10DE30002A27B4ED85ED6F6D791FF3366CFB6ED834
+:10DE400005EFDB66530C3942F3D6EE5B8EF767D7EE
+:10DE500006D87DD8D124E005BDDE3B3C18FF04E1A7
+:10DE600001764F1AC0A31DF96513FF5E2CAB5170EC
+:10DE7000819E1F1AC5EE0D89B4B0F3EB211611D7A0
+:10DE800039C4C2CE59E2F7BD2582BF9575BF01FBEB
+:10DE9000C74399A6DEFFFDBCBFA489AF2BF854E8A9
+:10DEA000894AD228B87FE44C8C3BD1A2A19FD8A844
+:10DEB00014D578CA7B8F7888F30EAA47AFD83DFF78
+:10DEC0002ED0AB947EBE00FC04FB8D9623006E4AE0
+:10DED0007FA0CF70F8A1EF0D87F9601EB017B6ECE8
+:10DEE0005E22E23D1A7DC46B26DC1B49FB6746912E
+:10DEF000AAADF4FDCC685A423D8ED713797D202B14
+:10DF0000533F711A04FA7C3D8FBB4EB6F0FC31C909
+:10DF10003EEA86D15067765C565224EA05856FE169
+:10DF20000E0838B796F8F9754A20C5007853F858A6
+:10DF30000A18FC56AAB452248701F218DEF1D07DEB
+:10DF40004BBDCB9DAB2F65DF71EA9FCFE4EBF9C1F1
+:10DF5000F6F5173DBEEF9E09F02D37B73D7203ADC4
+:10DF6000575C7A0ECF079747555C79A17B2FF4EB6E
+:10DF70007FE7FCDB5140874DDF98C27E0F55C3E140
+:10DF8000D6E229C0F732F9BD2E2451C93356E5B186
+:10DF9000421BB7CB109529F81CEDACFF401108F8D7
+:10DFA000F44AB1F07E54329E1F4ED1E5ADFE879FFC
+:10DFB000C5F932C130002571C92836CF37CC4E3271
+:10DFC000D3FFE09C691A3F177B4772AFB0D2F1DEF6
+:10DFD00021EC7C3533AEAA19EAC4C4C6CF26DAFBDD
+:10DFE0000A32136BA7C6C2B8D1C918DFCA35EBDA3B
+:10DFF00053BD12C869929A8C7989D388CA3E637AD4
+:10E0000003EDEE08BA2E90E3D78C2C744EE5EDE7C5
+:10E01000E8FF434DE4F6992A7FE32AC75CE7548D75
+:10E02000FD528BF701FDE99FE2EDE1F22C3EE3FCAE
+:10E03000DFE2C977C2F9B31E9E390EE17EABA3279A
+:10E04000DCF570D4C35D81AB1E8ED99F38A7C68620
+:10E0500081931E2ED348ED48D0630ADCF57079C752
+:10E06000CCE8E29D3413DEABF88EC4E0F80E352325
+:10E07000A11EA49B6811EF01CE8CE2F53747B0BA20
+:10E0800082EFA864C4B71EAE7A3866C6F1F7E358CB
+:10E09000FFBD002F09E502E247A19BCCD4AADD31E8
+:10E0A0002A7A50ECEB691C2ED4BE46FB3937DE8A47
+:10E0B0007126B0AFA72584E0965BCED6953BDCF207
+:10E0C0003CF8A9F475BCBF720AE13FFF143C2FCAAB
+:10E0D000E45505CE53BED1DAC9D39AA69F8238C380
+:10E0E0005093FB7EA0CF801083E77514EE477470C9
+:10E0F000D7BE67D7D6F570F803FC31B127BC143A08
+:10E10000FBC0C2E34E03C820B097C7BC96110DF206
+:10E110009B34C5868D4B5C71383F380EA757A4637E
+:10E1200081B883CFEDA93F428EEDA35A5225C73661
+:10E130008BEED396F89E724CC1D3648E87C9C4BB54
+:10E140000BE24B9389F445D01F480EEDBF5BD9E736
+:10E15000403210F67983C5C1E43FDF6770DFD4BC7D
+:10E1600084F9B3F8FC59660B7E5F4302524710CE28
+:10E170002978DF91D7181B5A8792BF4F86541166B2
+:10E18000CFCDC37BAE295CC87751A17598AC828492
+:10E19000F7FDF0759CA9337B218FAD5B7447819DA2
+:10E1A000D721EC1B83FB93FC2340FFE9DBCF35EE4B
+:10E1B000AE8076DAAF08FBF1F52F1659FC21B0C31B
+:10E1C000E47B3EB9773B95B235EA09857EB3E0FB47
+:10E1D000D4CB81DEFD0361DD5340D5D172E759F622
+:10E1E0001D437663BA04F3ECE96679FF39C42581EF
+:10E1F0007DABA7DFEF4BA7A178456008F8298A5DC2
+:10E2000036D5EA1E69A5CF57F3EF669BCE8E18056B
+:10E2100078F9C1F474404B4F0A1D51BA1A0FF0EC53
+:10E22000CAF8FC6930C7DFCD3897007A51B1DF43B7
+:10E23000768A6B02ACA7373B7E89D53DC57A013B18
+:10E240005EB1672EE68790DDD441A674741BC7CB00
+:10E250003C73ABCCEECD0F60FEFDEA48E55E3B477C
+:10E2600024D891B7AD4ED95407E786D52CFE7E6BE6
+:10E2700095ACF183DD90DD86EFB3FB666F5FA66D35
+:10E28000FF4C60FE7EA157FB9C581234F7EDF69CC4
+:10E29000D7E035C0BCC323313F413FAF7E7FFA7921
+:10E2A000F5F3ADE67ED56A63ED48A7CA2E596065E1
+:10E2B000F650F7AAC7EBE0CABADEE0E7360F48939C
+:10E2C00054F7ABB5AD8E2C08776F8C329E02EF7988
+:10E2D000C4CFE20055F2DFC3DD839BE566F181DE4A
+:10E2E000E61D16988A76A0E149BF08F6FCB0004109
+:10E2F000FB3B2BE0322CD0F801CC4FEEE107C0BD48
+:10E3000026B45ED6B08BF901F5D5E84F94517F0263
+:10E31000F4CC7A389B1EC0179486FE41D0DF85FC72
+:10E32000A92CB8CF92FBC312A597D45AD67FA3F5D8
+:10E330005DE36A09FC5577924C2963E3C3EFD798F4
+:10E34000A95F55934C2208F5AB5E78F8FDE96BC0E8
+:10E350005F8E7509707F28ADD758FAF7DDBFDEF8FC
+:10E36000F0FE1AB86F94FA65EBAC2A7FB737FE78E7
+:10E37000048C910BF047BA3D7F23F0A112AF688A5D
+:10E38000E07C1F11A4BB6880974227572F9B8F7E8C
+:10E3900045C425E787409E5816C7FF162B8FC346F6
+:10E3A000B1F79F12DD5B90BFDF3A3F02E2CBEF8C0B
+:10E3B0003C8AFE5C9395C5E7F7794AD07E52F0B966
+:10E3C000CB2A703FC93F10F8EDDAF1CD71E09764C8
+:10E3D000C902DE43DA24FB9E4CCF007934DBBE82D7
+:10E3E0006E296BA211BF136B8AF00FBC5B65A7355A
+:10E3F000F1FB4C9BCEEE1DA8CE631E66CDDD6545C0
+:10E40000FAF38B307E56C6EEC3A0EF7BD32F21FDEF
+:10E41000E112407F90F3FB13F0FCA8618F0DE24204
+:10E420001DFC7E82330DCD09F36959BEE52F36F010
+:10E43000D7DEE7703823B5E23D4A65DB44BCFF8395
+:10E44000CE9B700BC4A71B1664B2EFF7D877678A10
+:10E45000FE4CFF67F3C07C1634C4EFC8147B72B265
+:10E46000D9EB83F535558B182F9EACBB376C0ABFA3
+:10E47000374C6F5F9EB42A71E904CC875A6A67F300
+:10E48000F4C64F59DFC4129F8ADFB224BF08EBCF16
+:10E49000FA2681C01597675A529EC8033F9EC8CE80
+:10E4A000E130AC4476A3FDCACF9FE86F37DC43BEB2
+:10E4B0009357DE6C3837EB4A2466FBFD970960778B
+:10E4C000B9FBB1E022D3078A7D37E51B6D7C556F20
+:10E4D000E7E6348DBD7F204178B37FA722C0EE559B
+:10E4E000EB61FF06A687B57B09790CE190BE2DF59F
+:10E4F0001AB84729FD8F063BCCDB027C110FF83C94
+:10E5000087F7FC5410FF8DD05ED120DAFDB07E92EB
+:10E510007119F09562372870693CDF6C1E43D79102
+:10E5200075D6605F4E877833F005FACFE3FEBC2FD7
+:10E530000EF4575340C27382ACB3BBA316A8E46079
+:10E54000D379033E7FF3FC5BDAE781D8CBE0BD2DC6
+:10E5500006E617EFDEFBF728904B6F9EEFC6F182C1
+:10E5600076434FBB18E1916B15837167B55D4CC461
+:10E57000AC0390B7352D9AAA31A177BB37FB137244
+:10E58000BF95F4B41F72C01E11C3D8111CCE743EC7
+:10E5900009F8486F575C6EE3F1E6C1241DEEA36CE9
+:10E5A0003C1FB718BF1F6E8AB22F477DCCECA5AEBB
+:10E5B000DDA71FBF069EEF13D9FD11E745E4A7B7FE
+:10E5C000762E1EDAA6E25B2A39114F5FF53FDBF9A2
+:10E5D00006EDFFD59E481647979C97A9BF7708F58B
+:10E5E000F77178F907B0F338EF00B8D7E907DB2FF8
+:10E5F0001D3DFCFA3C1BDAC381E9A01E46AC6B371B
+:10E6000002FE5BACF9D7D990DFEAA3002E5E92330D
+:10E61000904C80F37A92037415A82676F027B6B54D
+:10E62000180C80978C8DC998A7B3899F572EAAAFD5
+:10E630003526ABE862113FEF3A297B87C4AA9E1FBB
+:10E64000B031F972724FE96F304FE34313191EC6B0
+:10E65000DE6CB0317DFB8AD17BCD66E877C480DF8C
+:10E660000DEDDEFBFA5EB8CF78D161C75888FF3D6B
+:10E67000627360BFC67D9B6A20CFB7F113D052543E
+:10E68000AF6C28140D74DE378883C5EF0E18D01FC9
+:10E690000FC63D892B0EF6F9105FCF1B2D06CDF965
+:10E6A000D81BFCDEDD7B6D32B62FB18988C7AD2D5E
+:10E6B0003971A0375AACEEBB6DA02F8EB5D5C01204
+:10E6C00094789F62AF4D3CB0F59AD1F4CF891D0686
+:10E6D0003BA0DB71E07911F6EB3849488C407AD8E1
+:10E6E0006F743C8F7ABC373AD878741D6F01BF2A9B
+:10E6F000F0A79AFFA1345A7FA3558A85FC2E05FE08
+:10E70000CA3E94F91DF5C4B5DE82ACE4DA7A81B86C
+:10E71000B3925F3ACE4E947F2F01E9D268733D6A7F
+:10E7200063F60EDAD727F730BBE815AE474952E15A
+:10E7300050809F82A77A1B8B332AEBE96DFEDFDBCB
+:10E74000989E54CAEF4BD79B648717E9661BCB0F83
+:10E750007778FDE654C8236B4CC57FCF499567FB9E
+:10E760007BA4E793DA7B051BDB0C06F80EAC628713
+:10E770001083E66D1FEDEB209D49F5487F8D8709DD
+:10E78000F27169DD9D2CEE48E50DBF7F0DCFD18183
+:10E790007FF8797A7F8196139BD6AF1888F0F5DBE6
+:10E7A00080AF4270A27C036555AD11E875D1525619
+:10E7B00016F373E9456BDDC89F45EB587EE11E5BA0
+:10E7C00032AEE70CA75762881C00F9272E0E7F6532
+:10E7D000DD799C6E4F353CD10CF352FAFA13E0739D
+:10E7E00052E3634FC372157A3DB541C6714A22B5F3
+:10E7F000E7F6AD7CBC6D0718BD4FDC20E7C0FD5FC0
+:10E8000013BDC40E71EC37366C14417EBF01F49C0D
+:10E81000CCF81CF4EDC93D0F46FD02F45CBB814011
+:10E82000BCFC152329D9A2E28BDDEB5FD5F06F6923
+:10E830005DF53518976F8B1540CE2B7CABC0FD1561
+:10E84000A3F32AE4FFEB74FC3F95BD2F473BB0DFF9
+:10E85000139CFF9F9841F99F3E8AD91023C038AF7F
+:10E8600018C3DF07F7F50FA4BFA05C6DEB2157BFFE
+:10E870006672B5CD964AE7AFB8B61BE30CC1F57129
+:10E88000BA7962AA4237C902C0BF96627018C08BBB
+:10E89000C215E899DACDB7DF90865CD922E1390F4D
+:10E8A0003F47E2F91FCA77020ABF86E499C2B76EF2
+:10E8B0007334D8D553AB56805D1F97E745FA3C2596
+:10E8C000B887C6527D760AF8388C3C38C1E5C75700
+:10E8D000B2FB62F7EE0F007A2EA11E22EC87AC137A
+:10E8E000EC8017A5DDB18EDDC33A3C5AD09CBF2B1E
+:10E8F000F51F0CEF408FFB418747637C3A60843CF7
+:10E90000D5113EA6C7889083FC400C570F003E5B94
+:10E9100044F5D7CD2AFD754AAE453A55E0707934B5
+:10E92000935F5FC5B07DFF95D38515E285AA732FF0
+:10E93000EA904802E36751607C2EC2F8A7F64CBA11
+:10E940000AE9FDDAF0F46E07FF2A16FE3DA7F54846
+:10E950009F3133ECF81DCB1392332246631FF9B07D
+:10E96000DCBDF157E8D701FD02BFF746FF2540FFA8
+:10E97000240CDDFB28DDABF0A7D001A58B6BA255E5
+:10E98000F2414F17CA79A302975774E7954F47335F
+:10E9900079B080978E5EF26694FDFC603C9FEC81BE
+:10E9A000E7F90CCF21BE027C2BF2E16717E1AF3D06
+:10E9B000D1766CAFF97401E6A9D4F273AB7A3E9FBD
+:10E9C000B2EEA5D182E67C4B7FEE34CAE2BE2B5A72
+:10E9D000773EEA480BD1C7346ECF2ED968C273FF99
+:10E9E0002DD00278DBCDFEBD6CE53DBB440D4F0A5A
+:10E9F000EA15D14C8E2BF4E1586624C3A8FFF255DA
+:10EA000072E16EC8FFF959AB376F34DDC716A377D3
+:10EA1000F6B5E80738AF82F1AFCA33D8211F24C654
+:10EA2000651720DE81240A7CB88FCD332ED5791965
+:10EA3000FAC90EE73890070F737C29F855E0D09B90
+:10EA40009EEB0DAF7B387CE279BB5E8E1473FE9E2D
+:10EA5000C2FB5D5C8E7845E0271B712F1761FD5965
+:10EA60004CFE05E54816C173C9977572E4E59F5ED3
+:10EA70008EBCAC912313DAC2CA11FA0BCBFFF11B87
+:10EA800016A21D4B0E87B7637746333D1C0FFA93D2
+:10EA9000F68BF7B2F3DE8739DD528AC4BCC9DA0DD2
+:10EAA00026CC1357E4906D36C9817FAFD906FA168C
+:10EAB0007ACD761F9E0CE7C54946079C5F9F92035F
+:10EAC00088F753D401AF45FAC8C7FBC7C3C82302B0
+:10EAD000F112EF4783D0EF9C2636219F2C994650A8
+:10EAE0007FEEDE7805D255495E8A00745B5A1723A3
+:10EAF000407BEC54BB01E494B28F2B9619C8B071E3
+:10EB0000C80707D472E40A6F15FEBBCD43E3DC49A6
+:10EB1000720C21471F3DFB3375BCA88DD6D5F12261
+:10EB20005A7FE0FBC48B8E46071E8078D13F6CAEC7
+:10EB30007698779425FF28EAB7C42A91A8E4D6C529
+:10EB4000ECB71F4A2F953C2E455AA9344ED0C481AC
+:10EB50006FAB73601CF82B584FC580E34FC37078C0
+:10EB6000AF46587B9BADA31F970BE41382F8E89741
+:10EB70005F2542FC45913B067BACE22F0B9097A1B1
+:10EB8000F0DB7F031C7DB5D7008000000000000093
+:10EB90001F8B08000000000000FFCD7D097894D590
+:10EBA000D5F07DE79D2DCB2493C9427626ECBB039F
+:10EBB00009ABB14E086090040710448D380990B03D
+:10EBC000640391D2D6968120068A182BB554B10ED3
+:10EBD00014FA51451BB61ADBA013401A143456AD73
+:10EBE000D8AFA561911D8980FDD38AE53BE7DC7B29
+:10EBF00033F34E26026A9FE70F0FCFCD5DDE7BCF4A
+:10EC00003DFB3D77492D63793B22199B90B350ED35
+:10EC100006A9C9CC3C161B831F2F6343793E7A0893
+:10EC2000E659986B20636BF27579DE018C5DC79FA6
+:10EC30003BFD69A2153E8E676CFED630EB4933B5BD
+:10EC400067D7E17F795D8C265F599F643DD9C79F67
+:10EC50009F8FBF24C1FF334CCF12182B63E2A7E173
+:10EC6000CBDFFF7018B4C7DF55C6DE54DD89568090
+:10EC7000A7DCDC12D5DDCED833F9C713DC91D45232
+:10EC800087DF3D22C67871B9E3BDDE718C79DE5530
+:10EC9000D916C80F36193D4A34FCE264766B82E817
+:10ECA0000F7E9406C5671904F97F43552C6397FEC0
+:10ECB000ADA3F4C59FB8F232E0FB8A7A9D6339B404
+:10ECC000AB685018CB62CCD19579CD198CD58547DE
+:10ECD0000D62D05FCEBE48A701CA2F2966AF298337
+:10ECE000D100088741C23FA2357D1BD4573798D841
+:10ECF0006AC85ECA61AC19E1D53BA2D9003F7E0764
+:10ED00001D7EA60FCC00CA6B1D2E0B639BC278FF25
+:10ED10009BC2647B7B3483B4DB92D1EC04C0A7D765
+:10ED200033160DF481C48369F6926E03F499301F93
+:10ED30003DF318804ED9AD3E15F1D2ADD5AE6391FD
+:10ED4000FE71F4AD8CE6DB4D6FD73960FC3A81F78C
+:10ED50009D4D3B543DE073D898DA6A15D2D228F71E
+:10ED600058C4F3A8ECAA6A2C8FCDF7A86E689FA5AB
+:10ED700054EDB3005ED878E6D802E5CC07838F84E3
+:10ED8000FA16D61805D998232DCE28281F75C6D96E
+:10ED90003800E61DED620AF6C7D8321ABF5FA4CB71
+:10EDA00085FDB238A75200FD0CFB0723BCC87E7658
+:10EDB000368D56EC006F5CF318C51EC05F304DE217
+:10EDC000ABF5CCFE53ECD77348E740BADAEB987357
+:10EDD00023B4EFFA72BF312CCADFBED2AAD078B703
+:10EDE000BBDDB94646F379D80ADF8F9CEEDD6700BC
+:10EDF0007886CFF1EC33DA03E63397517F292D1E65
+:10EE00009A47D211770EA68B2D31D4CFA833BEC628
+:10EE100001D0AE4B15CC07CAD39A3F5410AF6955F9
+:10EE2000CD0AD27167D35E8237B5793F4F8111EA3F
+:10EE300020DD01725517308FC5161DCD63B145A178
+:10EE400074E5C599892EA87FC4EA5E6C19EA9FC74C
+:10EE5000CA1C776215F4BFBEA95BFB7C7B02BCB702
+:10EE6000C1678827D9DF72AB91FA69B2B87F84F3A2
+:10EE7000AB9CDE7200796F47D39FA3482E1AE288BD
+:10EE8000BE09878E133D129600CEA078FDA1850A9B
+:10EE900083AAF5854033A5239E27B8DD8E31998856
+:10EEA0006F809FF8C71A3109F8F2628CBB06C791D0
+:10EEB000ED2714D922505FB4E7C577CF2E658E5960
+:10EEC0003D00CFFB8B77B26E4877F712A47B7BBBFC
+:10EED000818F87213F318BB316FBBBA4B0E938CEBD
+:10EEE0004B9842F94B069E97F8FAAB95E3EB11EB82
+:10EEF000A4C596788E272BF0F14B61BC5DB01E7ACD
+:10EF0000D7CABFB30B7E61CD9C5F701EA8BF64BB28
+:10EF1000DDA2DFDB9DEE5C3DE793CD08E7C811DEA7
+:10EF20007DC8B7C3F33CFB90FFD398E0933CCE275A
+:10EF3000C1FCBECF6AA37E469D696588F72C85B962
+:10EF400002E92ED3D710AEA1C8DFA3897F401EB639
+:10EF5000E378C352AA54038012C7AC135877C6DEB5
+:10EF6000B6DAA95DE608E73EE437ABD345F27C208C
+:10EF7000C24AE52B33387FC0F77F40FC05CBD32E48
+:10EF800094A3017E398A437E8CECC88FBF13F0BCFA
+:10EF90002DE4A563FFEE3F61FF71CD3AA7029D0C02
+:10EFA0003F12E965D074F8A22A15E18F63C0FF0013
+:10EFB000A06D8E3507E52CA5CCA1205D9B225C873A
+:10EFC000ADD40F23BDB93247E7AD86EFE6463B89A6
+:10EFD0007EDFD83EEC676636CC6F1FC01EFC15E1A5
+:10EFE000037BB0B608F5F46FFF69443D6A97F2D72A
+:10EFF0003424A238803FAE48BDE0A7F771D20B4160
+:10F00000F40ED673C1F4F6EB05AD9E037C5DE0F41F
+:10F010007067229FC5352F52B97ED0EAB5CEE8D1B0
+:10F02000413F083A5C8A707E81F85C0C3288E37A52
+:10F0300046B33E58DE991D0E8B89A476FF453B1CD6
+:10F040001613DFD10EEBCCAD0715C04779836A5795
+:10F05000610AD58FD99C48FF17EB148709E5A441B5
+:10F06000257E78716538D94B09EF67BBA307B1DB03
+:10F070002015F2CFDCDDC98E56C688F1ED9087F100
+:10F080002F5979D6687527C504E893171BBE084326
+:10F090003CF74F64034EC6620BA7D60E830829F0D7
+:10F0A000BD097F5310AF836B5414AC69EE9D269558
+:10F0B000E8D61DFB1BCE5AFE9C0D70BDBC6DB4CEB8
+:10F0C0001DC837F55767EC05F82B23B85DBEB4F7BC
+:10F0D0005A2FE433597FF79262D27B3F072B1913E3
+:10F0E000A01FDFEE7382EB6156683DD51F87762A3D
+:10F0F000D723008551E63E7AF427D47087AAF527F6
+:10F100008839AA7B027E107F8DE184BFEA9E20773A
+:10F110001904E748EC7FBFC5C892A0FC0AC823B613
+:10F1200093707F03784707E2D10F6FAAF55484E00C
+:10F130000BD50F5F3B5D900ED0BF6AD1D33C2EB193
+:10F140007007D2B3CEE864487FCF51E11F08BA55AB
+:10F15000089EBBD430F4881BE6F7E29154077E7F0B
+:10F16000A9FE4A982E12FD46F7149C979AD61A8546
+:10F17000F6705FC395BE2D0348BF4DC5F22B874E79
+:10F18000D8DC03BED1FC6684A687767E95FAC89A41
+:10F1900040FF50617C7EC17CA43434FE4B1944F2A4
+:10F1A000C7501F7AD299B71AE6BD72A0E0A77B9923
+:10F1B0001DE53E98DE46ABAB2226406EFF15EDAA5C
+:10F1C00042B8709C942134CF85981F747866A6410C
+:10F1D00087F31BC3D06E4A7F0FFDEFB0217EFF4E39
+:10F1E000CEAF7DFE3DAF0D3AC468BE3FC67100F89C
+:10F1F000E53A80AF128CC1EA8CC079FB881EE562CB
+:10F200007EE5E6489F0AF361BB0C175AA41EE8D6B8
+:10F21000117EA04F0DC2E719ED38E246FAFE35D255
+:10F22000518DF8D1375BD15F85F9ACC67A36A2280B
+:10F2300011E7DF2FD2B905F5FC4BCB18F1F3A55739
+:10F240009877134C76FB7E1DF1CB46D68FF8BE9F88
+:10F25000EEF20C5724C9F33A843BABB956877AB720
+:10F26000A7D7AE437DDAB7B94EA7233E70FF2286FB
+:10F27000FCE49957F4005FFF6D55EA37E4076F68C7
+:10F280007EEF40AFCD81F49278CB167C908D7843A1
+:10F2900083D0AABFD062F6E30DE8C3526C1DFB63B6
+:10F2A000AC251DF1D4F8FAE95E2DD05FC51BA76728
+:10F2B000205E2AFE60222618F387BED1C8EF9FE5A4
+:10F2C00084F6672E2CAD72E8C19F7A25A61BD985DE
+:10F2D00032D66C443FA1BC6E81431FA0CFA5FF7600
+:10F2E000C8D09C8FFD1F1AAAB26580E72B8EE15D06
+:10F2F00058083BD1EE2FA1BF06B02F47D811CFAF92
+:10F30000674573FFD146F620B8FDA1A5731C637A4B
+:10F3100074DEDFA1C161D3BDF07D7E901F743486A1
+:10F32000DBB5B6186E8741213B11CE8BBFB7783D58
+:10F33000507471C847510CFDCC5D1F647A808F2ECC
+:10F34000B2E647FE8872763592D671F9833FCA5C81
+:10F3500066F1CBE51D23F8DCEF78ED70941DDAE75C
+:10F360006FDF17E709C0DF1D4C7FB59DAF33705CC1
+:10F3700046E3337D4B2FA407FBE3D9043BA4F9AF4D
+:10F38000BF15C7F9204187745E24F4DBEFB028C0B5
+:10F39000DFCE5F52417C24F3E56D66E68D0DC8EB50
+:10F3A0009B8DB8042E6F8B645E68B737C612477AA0
+:10F3B000269925A39EE9145F3789CFE07289CF4350
+:10F3C00083CFA6A35FF15927FE706F1B6FD7CEF7CF
+:10F3D0004BC14FD7FBF3EF7CA53EEC0AF15D848D6A
+:10F3E000D3E98A636417F4F7F28DBE1ED610EDE4FC
+:10F3F000FA32184F6F5F2B8DC07E7FDF66CA0B0518
+:10F4000097DEA6FB767ECA21802AC01FDCA6BA53EF
+:10F410006DC21F9C0CF98ABE57C6D1BA5AF28BD066
+:10F420007B77304F23CA6F307F487AF7B001DDFA1F
+:10F43000A372662948B78B3176CE37421EA47C046E
+:10F44000E331389D6064EE50EB80AF62245EC39878
+:10F4500007F4E1231B0D64DF0F5FFBF8DE4CE0F7E0
+:10F46000D31B0CD6E530E49C17F6A53E03F57306D6
+:10F470009BAC0AE44FDB7D3D50EE4B5F505DC80F07
+:10F48000A7373C923013D2F320BF650047E946030B
+:10F4900095CFD9F828959F15725DFA427C7FD49755
+:10F4A00087F7AF4E403ACEF9EA89694897ED466B47
+:10F4B000FFC190966D531C6302F03D6F739826BF99
+:10F4C0005DC7E6E03C245D99E26EAF47133FD5A6E9
+:10F4D000FB76711F9FD6DF04FF72AAA0E3C4293018
+:10F4E000EF8AA157C8AFDF77209CECC99B912AF91E
+:10F4F0008FBEC1FFEF9DDB209FFB95DE41BE9DA02F
+:10F50000F3584167B05CA4B74BCC3C9FFBBA9EFC60
+:10F51000CF5C8B4AF886F69163A1FE7BA2BD0FF407
+:10F520002CCA2153B3D78D847663A30D0CEDD0F78D
+:10F530007CF3F219D8C93BDBF4C75B02E6339AD5FA
+:10F54000F6417F38871982CA9D7A2CCF356BCBC79D
+:10F55000F6B8FB2CFA0F63ADDA72C9778FD8B4FA1C
+:10F5600062DF81733F9B00F32B39A492FF7C237DE4
+:10F57000FC2EC2AF473ABF5DB80DBE3B2CB072F84F
+:10F58000DAE91549C857231486F1ACD3D742CBE347
+:10F590001FA45E6640DF3E7EFA1638E6B6E751DC11
+:10F5A000EF19B1A03D8FF0DFBC1EFB7A3D759B8D3E
+:10F5B000C73382ED46B0DCFCB7EC46FEE0B7D23D87
+:10F5C000164A7F83E985ED5CEF06EB89603B21E11C
+:10F5D0000A86B7BC4DA7B10F5FA11E191A68278C08
+:10F5E0006427BEC3F570836D68C7F530F831842F8A
+:10F5F000CF303DADC3C1DF6AC4760322EDB139001F
+:10F60000D20A6BB708B27F16F77E5B401CAAFFB622
+:10F610005A1DEA8DF6F88C411BA791EBD577849D96
+:10F62000A813FA1CD6ABB4CEDF18EE4ED4E3B8C99B
+:10F6300046C7968C8EF8F948B4EFCCCF957EACBE19
+:10F6400086FBB18F585D9A3819EB93A889FBA25FAE
+:10F650008EF2EDD91B4EF3FC54710D4239D433E7D1
+:10F66000DF6D01F4A93670F883E1898FE576923178
+:10F6700017F907B27CF6E8D07A5C89D553FB9C6712
+:10F68000EF4F47FFEDD3C607D251BF7E1A14E7ED07
+:10F690004C1E9E16F2FAA4B02331222EF014CA1189
+:10F6A000E441DA9DDBE1FB554B5D24573F5D3A9D1C
+:10F6B000D267962EA1FA13B60C1ADF9AF367577722
+:10F6C000C0D3C9352AD989D94657AF18F8EEA459FD
+:10F6D00047F18513559179BB22B19CD17A72F6B36B
+:10F6E00013B67802E27E276C7AA24367F38C8FFD13
+:10F6F00066FABD9CB544A1BD6AE7D7231DECB52DC4
+:10F7000016E37FAC2501DB552ACDBDB6291DC7B751
+:10F7100032677C2CF29791F547B9A90BE7F628B828
+:10F720005D4A2CE7C3BFA11F0BFD7E8A762B849E0A
+:10F73000B10B3A2FB438EDB1A4EF22C95F27B881DD
+:10F740005FBE8C727647B8605DD613D3615D787CFE
+:10F750006EB1C52AF8C3A9F0758EAB5F6C88F85BF3
+:10F7600067F19E6038DE11780D8E03C954C681861C
+:10F77000C6F2F9BC6DB36AE24218FF0E15FFF979C3
+:10F780002CD7A31BC35B3C2ACAC3037C3DDE25DB0D
+:10F79000A3607C2B25BF3607E35F77C5F2B8A52DA4
+:10F7A000CF9D88EBF6E444A303E336372B8F03EABF
+:10F7B0009C7C5FC0AD2338D6377BC27A015C09CD13
+:10F7C000EE1C23A45371310DF8EDC2AA9621DDA0E1
+:10F7D0001D21236B7FB857918B6C689229F42840C8
+:10F7E0001A8672678C724F45BA0C9B55558D71FA0B
+:10F7F0009432BEFF70567177B5019F9C7D2B3CA45F
+:10F800003F5C22E8CF94D1C968FAB3361B08AEAC8E
+:10F81000CD3F9F817C9FB5F92EBD12A08796C71A58
+:10F8200068FE67DF9AD795E2169F9858CF107AEA5C
+:10F8300087825F1E1074D8690CCD7F8B45BB6FAC7F
+:10F84000CF5B405569F5F9E2D880385B45F965D260
+:10F85000E79363ED34CEF3FABA03C980CFE767319B
+:10F8600087078AE66DDD48F1D79DC6BAF1B8EFE4A7
+:10F87000A9D031A4FBFE037F38908C7EE42CFB6082
+:10F88000F423DABF3FF4D24A2C7F7E0E1B8CF84F54
+:10F89000F23EAD603CE69F61B584AF7F6E31B165ED
+:10F8A00018B77DBF6EFC0F21BFBE4CC750BF04CF41
+:10F8B0001B4632E81231F519742338FD510F4ABA4C
+:10F8C000030319911E926E88BFED90EEDFF21AC10C
+:10F8D0002FE19A2AE2DEF3B66E1F8F7C925C6653AC
+:10F8E000304E20E1BA913D7931F6DBD993EFD00E5D
+:10F8F000BF121B222E1DC20EEF880D618783ED2FD4
+:10F90000B3387763BB1BD9E1E182FF36C606ED7FD2
+:10F91000E07E5908BA0D8DED100FDF1F1B62FFE36B
+:10F9200046F1F0DEB172FF431B0F7FC9C8F56FAD22
+:10F930008D3D3C2984BC7413E3EBD6B51AD17EC649
+:10F94000352821F5D9628B51EE1F7E1C1BB05F124A
+:10F95000AC8F43E0F728B6EFBBCDB7175B0D89E955
+:10F960001181EE5BBFEBB0DE0D31CE29813FFB2272
+:10F9700046FBA6F62A46FA0AF25E1E14F42914374C
+:10F98000B0384F93DDBAC1BED59DD61CF283E43E9C
+:10F99000D554ABD64F8C8B93ED9C9F239C699DD8FF
+:10F9A000897F093CC1FCDB70DCB8454CB31F23F7F1
+:10F9B00061E2AA3C8A310BCD11A3F86AD758F7321D
+:10F9C00003B46B1DC91C9B201F5D68CD417D6A9BE4
+:10F9D000E368C4FD9A9517793C7EE502E65D4EFD2D
+:10F9E000F0F93277372FCA17D22D302E1011C7E118
+:10F9F0008888E3720676D21CC7E10A8F0BB0939217
+:10FA00001EBA753E95E8DA1ADA4E05D0D546DF778C
+:10FA100042D7EF502EED7137E71FF78CBB05BE19AB
+:10FA20001877737CF3144C4BECDF048F9789F30F3A
+:10FA30001E0FF82C2BEE26F8ECEA2DEE8F1E8850C8
+:10FA4000BE5DDCA5235E27C485D0776BF2757D484B
+:10FA50005FB3704728BB3A232EF2BF7D5E6486A059
+:10FA6000F72D9D1779F1272D46A4B3DCF790F0060A
+:10FA70009F1391E5150D4A26AE3F73F65DA375C041
+:10FA8000A5C67FD33AA0E3790F3EEE42E403806738
+:10FA9000AC3AA0CE07F277799B9156EA2AB3FF22BF
+:10FAA0001BE3F64D06E6B5537B33B6EFC778FB7E16
+:10FAB000DB563663DCAA1FD37BC47A54B9CEFDA8CB
+:10FAC0006894E37E4D2A5B8DF9ADBCBE8A9997613F
+:10FAD0005C3A7A848ED903F019E30C67F6007CC691
+:10FAE000E6D93479B94E9E2FC68D77256BBEEF329D
+:10FAF000BD9BA67D92BB9FA63E65CE104D3EAD6AD6
+:10FB000094A67D57B0CF81F90CCFDD9AF6DD6B2638
+:10FB10006BF23D6B1FD0B43FCDAA9ECDC6797A9CC7
+:10FB2000CD3D00CE5902CEDEEB8B35DFF5D7D50DBE
+:10FB3000F3A120F9141FEEFFCD166C324BC473FAFB
+:10FB40007AE769FA3DFF6A5E9302F89D5D6B3819AA
+:10FB5000189F217C007E4BEA15F61C8C5BBA5E5B1D
+:10FB60003FA7E1E9952990CEF56ACBE7E1BE9C82FB
+:10FB7000FCAD2DDFAD733D82EB9DED7122CE28E211
+:10FB80003DAC037F44D2B89737F07897EAE91DC4BB
+:10FB90001F5A3AB16FC92F76C12FA6442DBF84D901
+:10FBA000B5FC527A70E7301FEB88FF883E417CE459
+:10FBB000817F017897F895F8B738B47CF55DE19DC1
+:10FBC00031AF91DB0D6DF93FE2B4F1B57E91EEE31B
+:10FBD000A8B7AED42F5271BF8DE5F17DFB2BF55741
+:10FBE000071DB26BF6D73ADB4F3A1717185717FBBA
+:10FBF0004997703FF1367613FB89FBFE85F800D9F3
+:10FC0000771B801FD80887B97DFF30CCBF7F14AC2D
+:10FC100037650A76E3CB38B227FE7DD76AF87A5883
+:10FC2000F45F5C08AFDC8793E772E4F92116C9E75B
+:10FC300029FB013CA8F143F1FC9F2D02D7ADDBF776
+:10FC40002FA4F5963C3FC4C4B9BF107E3FE9EF3AFC
+:10FC5000FC3589FC81F0786ECF23316DF707C4F94C
+:10FC60002E69CF3BEB47EEB775962A7B55DA3F6C92
+:10FC700055C21D9B42D8935EF1DF72FD75A6431CF1
+:10FC8000BA577CE0FAEBD12B07D0AE00DEFB62B9AD
+:10FC9000C502F65AF1DBEB5F444411BFB61E54BDFA
+:10FCA000BDA1E0B2D91E6D033C368469ED884CAB32
+:10FCB000CCC903F4B158AF3DE727F71183DB676385
+:10FCC000FB80FD27F84EE38FAC1CC2FDB5EC786ECF
+:10FCD000DFBF88E4FEC11491AF0C5A1755D670BF30
+:10FCE0006C23F8E90D01FD4C89B750FBA511395380
+:10FCF000E2298EC0D7BB2B3314F227562A0AF921EA
+:10FD000067A24753FDB5B89CC9C43F629C29E8BBB4
+:10FD1000C1FFDA6E1C1EBB388F23FB37C7F3F6E634
+:10FD2000F8D1944E89B78AB8B3B51FF2476584936A
+:10FD3000FA35AAA1F7A5A6C7F379ADB530E9276AC8
+:10FD4000E2FEE384DEC438BF89FBA3F96313FC71D0
+:10FD50007EA6667F688C13F17D853E77A29EBA539E
+:10FD6000D0BDB378BFB38F753F6E27758CF7FB128C
+:10FD700043C6FB1DE328DE0F5FEA715EC1717FA4FD
+:10FD80004384CD2F3F8FC4B7DB8354D44FF54677E0
+:10FD900035AEBB5A7783FF0EC57DBC2DB41F30F046
+:10FDA000507707AEAF5666B0BD16E4B7658CA17F3D
+:10FDB0005FDFA25B1E06F56B3CCC8AF52337F0753E
+:10FDC0005BE97ABB03A7698075B065885F1FAC8B60
+:10FDD0008F21BCD7B74C6EC4FD8135F7321B9AA179
+:10FDE0005A569B1B85FED0061672DDF89490B30917
+:10FDF000397B55D417F1E8DF87A0D353824EA00F8B
+:10FE0000D6229D87B7BAAFF0FD38AE4F4825E2FA4B
+:10FE100074BFCE1B6A3D3F373A771DF2C1406FE891
+:10FE2000F5C35A0BE7B77511AEE7A8DD2E7EEEB528
+:10FE300054EADF593AA607BA4F11749DB2819FDF89
+:10FE400060D7AE5F57A59FC8A87F867AA5F45E8B62
+:10FE500017E343A50D191E82CBA5387AA2BE687898
+:10FE6000DF85F9D2AC2C2BC6239C7F65CAA93EE462
+:10FE70006232AEBFF4EC94D42764C7E368DF69B2A2
+:10FE8000E0B7B5163B3F470D288E00FC976E58B67D
+:10FE900017CFEF7CF46B46FB4B47D4D661D8D954CF
+:10FEA00040CE922198EA5921C52BF8FED5BDA21F5C
+:10FEB000CFBF615CB37FDCA90D07693E470CCC6303
+:10FEC000063EBAB4E73E3BFADB2BE3CD14C793FB07
+:10FED000B24755F7E36484F4AD1508DAFD0D115609
+:10FEE0008C7FFC43F05D46827B1FD2C7BD7C7C05C6
+:10FEF000DAC19665A674C4A37B79921A0770BAD743
+:10FF00002A34EFD1CB938C787E61E68AC1E3504FDF
+:10FF10000D61CE9518DF7928968594D3F3F17C9DF9
+:10FF2000585C6560C6689A8411E32F176B148ABF0A
+:10FF3000E0FE5B01D0678E985FF9AAF7A3883FECDB
+:10FF4000F06F181ECBE53F73AA4A491EC1CE6BE481
+:10FF5000A78CD51993A09F796B6039DB8DECFDF1EF
+:10FF60000EFE43C079EFF23A6D7D255BF3399D7F3C
+:10FF700061E0EF5BD02E68EB3F95F2E8600EA4AB3A
+:10FF80007BB1C58CE784460BBC14AD51ACA85F6651
+:10FF9000AE688CBF0FF2339B5407F2B4C40BEBE88E
+:10FFA000EFD3398FCB4D3D693D70D96EEF82EDDCDB
+:10FFB000515CFF2B7AF7702C7F28D63D1CD7F1AD12
+:10FFC0009F58189E9B39D606FE18C61ECD6C10C5CC
+:10FFD0001FAC6CD0A4003B5A64B02660BCDFC316D3
+:10FFE0002632BEB7650E9C77A5790DF98195E80795
+:10FFF000F2F9911FF8502C67D5D6D7153A9FC3EA6E
+:020000021000EC
+:100000000DE4079A851F78D65E9B00AE17733D6E90
+:1000100020392DDE16437E68F18A5C23F26FF1AE43
+:1000200018D243E0077ED863989F8EC756641E4857
+:10003000847E8BEB321CAA967E5AFFB8E698A45BAE
+:1000400047BF4F4BB793A1E806F4D294A72408FF0B
+:100050004ED08B3D164B7E47E182B77A9A019ECBFC
+:10006000556174EEA833FF83A5C6D1BE9E5C17E62A
+:1000700025B7AFDF68DFFCCA9AA144B7607AE5FD17
+:1000800067E670B427ECAF16867AECA1EEECE1C916
+:1000900050FEB0C2E5EBA1EAF17928A759095C6FDF
+:1000A000BEB714666864ECFDA566E6ECC5D8074BE0
+:1000B000AD94FF686922E53F5E6AA7F493A57D28A9
+:1000C0003D29E26852CE8001885F472570F91A9574
+:1000D00020E2DE6C5122AA8CBCFF7C305467C5A1A3
+:1000E000D2278C4D63EC1E272023C0DF997E6F043E
+:1000F00012B93DDF62B08E4B44FF719542FABED813
+:1001000075BBA63DF825463CFFCDFA64FACBE99CC9
+:1001100098DD3819F8F0FEFC584DFB6935299AFC3A
+:10012000E4043BCD7B525E774DF90385FD35F9A2A2
+:100130003640029E2F30DBF8FEAAD8B767CCC6D770
+:10014000EB56DEF66AD5F02EDF0778AF1E32507D13
+:10015000303D245D67ADD731378036733DCC0DFA25
+:100160003D593B93E4EAFC110BD9FD95DB32DF1DD1
+:1001700001F963DB0CB4BF7E6C45EC5ADC3F3EB644
+:100180002D3E8A41EA5EA9321FFAC17AAB9105E899
+:10019000B7DC15CBE8FC5691D7E440F92FDAEFF93C
+:1001A00095CCDBD11F4420513E3E54BD3E85E8E74F
+:1001B00024FCBE14E6DD02F933A0AFF1C8F8CC167A
+:1001C0000ED71985ADC0FCD9B0BFF5FA3EC071B1EC
+:1001D000A0B64487EB01F5503CE9CB1D2A43BE2D68
+:1001E0005C60A0FDBBB91FA91B31CF9421299CDE07
+:1001F0002A9D47642F99A87FD60A1C02ED16FDD6CA
+:10020000B489D6774CE4770FF4AE16FC897C74265B
+:10021000863963085885E03DF77EFC46ACF7E3D3AA
+:100220003B08E7FDA5DEB53201F8EB5C897710E904
+:10023000B5C7E249AE82F17ED2C8F59607E540F136
+:10024000EB4BBF9C2D273E9D69702438485F652588
+:10025000A1BE3AB9C640E79899DE193589D63F3B29
+:10026000888FE53827F5F67108DFC99A0C86FB966A
+:10027000C56B54F20790FF787B2FE7FFA755371B1C
+:100280000EFDD6286ED6A523DF3CB260389D639A5A
+:1002900021D641C17AE0339055772F7F7EDE1E7ED6
+:1002A000CE8665B5E8EF1D18388F157CBC44DEBFDF
+:1002B0003C0750D6ED4F47D1E5BEDCD43D1AEDF0FA
+:1002C000D90F55E2B3B3DD6A8725023D2FE8F60E5C
+:1002D000FB3EE4CF17784EE921FF54B87B6702AEAE
+:1002E00057746BD2956E783EF6C4DADBE1BB73AF20
+:1002F000181C24E64BE2497FCC7B696ED7C0F38E95
+:100300001DF5972F99EFBF389314C0E77C7BDD383C
+:10031000EB005C77BB841DE2F8B1E3E62AE0C5BAE6
+:100320004EC143C3ECC450CB6A3C773D13C4243068
+:100330004E7842EC8F1F107A45FA09115D787EA63F
+:100340008EF3377B5521BF0D7E34FABF529C4F94FC
+:100350007A5FEAEB32564BFBC14712F839C6B98ACD
+:1003600097DA55E0CE2EA8A8122B0F42976D35795B
+:10037000BD19D49735D00F48EE62E7FB43C6579EB0
+:1003800045B62D65CD7C7E41EDCE19BC25CD191D20
+:10039000ED4D8975E30A1BF56F7060FCA454C869C4
+:1003A00079ADE2F5F17990DD94F18AD9C26E06DB80
+:1003B000A70EF628C80ECD0EB2B3AC566B5701DEB1
+:1003C000481C47C21B0CA72BC24278980770A1BDDE
+:1003D0002D717B0F4C24B8150750B2033CA5CC35CA
+:1003E0002606E701F53E7B47F882E7D5015E31CF6F
+:1003F00060B84B1C9FFB70FF18CF8751BC29681E4B
+:10040000921EC1FE9AA44B8987E3B7A441217A7E4C
+:10041000DAEE07328A1B497E8105509DF67BD74470
+:10042000D467A5EB40FF66F8F947F2D33C56178531
+:10043000FC52C17C2B9350BE7C75D346A2DFBEE13B
+:100440007D23CA49A1CDD7531783285CFBD3BCB405
+:1004500080F544109E6F44D76F8A379C955EC6BD69
+:10046000004FB337ABCEB0419A76E21C9187E4607F
+:100470008EC763C4F8C61CB1EEBF119C957A7E6E20
+:10048000FC86F076E2277D5BB8F3BA68FD62BF9F19
+:10049000D5333A949E6AF7AF82ECFADF0C3C7E21AA
+:1004A000F5F155BD93E225502EFCAE2A2B8F9B070C
+:1004B000E9F1B42CD2E325C2AECB714EADDF49F1E8
+:1004C000B7D968F703CA3F5DB793E2FEC6576647E0
+:1004D000A1FF7D6AFDCCB578BEEBD4B69964E74B3D
+:1004E0009F9376DE6D0CF41F72D717BDF863E4DFBF
+:1004F000AD61149F2FD9EF16EB1ED0ABD0CEBE9EB0
+:10050000EB51B68EEBD552B48703C81EF6C6768B78
+:100510004BDCBD510E02CAC94E2E9EE9FEDD1EE81F
+:1005200077F1CB110E0FA1C2EAD391DF6EF5A13D99
+:100530002C5FF8F1513CE70EF6FFA31F48FB0FD9E3
+:100540008D7AF7922E286FC2EE97AB1BD3ADE827BA
+:10055000083BF15FC0BF3934FE8710FE8B11FF01ED
+:10056000FB20C76B389E6706E1FFC41A4E9795DBE8
+:10057000BA47E1FAF1784D77F2B38E6FEB49F89F05
+:10058000B51AF0CFE35F5A3FAB06F08FEB08C43FDC
+:10059000C05BBCDF2EF0EFE0F8AFE178676B783A34
+:1005A000AB039E3D748E61F1AF4D0EF41BCE84F90A
+:1005B000C89F3AB35D65D5017E98F483BE60B5BF30
+:1005C000427F4DE27F6EAFE641A87F0A9FFE531443
+:1005D000D261EE761EA4EF807FE6EC82FEB87FFC4F
+:1005E00076BFE9952EF1017ED34DD2A982B918D9F3
+:1005F000C5863F1DC17583E2844F6D788F46DCD779
+:10060000A8D7DED7C0331985368C2F38CC6684271F
+:1006100035F81E8A9B611CF99F3D3F9FB190E4BC59
+:100620005573BE6D22F319BAA0FF58A7D0FDC6F2CC
+:10063000453951390CE3D45504C7E92E8AE6FC78D4
+:10064000B9AA23FFB1CCC8FD48B93FF9AEF00FDE1F
+:10065000EDC2D725EF75B1D27797C218D9814B1665
+:10066000A317EF23C07A2A11C7F7EC3111DD8E22D0
+:100670004C807FD528E2366002914F1F649C4F1F4B
+:100680008C6CA23839AC545E40BBF8D0129383FC1A
+:10069000DAB8688AD73E20F4DD83912B5D681F1E8F
+:1006A0008A343A31857E3D7888CE301A8687F10DBE
+:1006B000C946BAAF53686E790597BE0F279E78D4A6
+:1006C0000CA0DE06EE37C655E0D75DD7633BD2C53A
+:1006D0004F1F6D9CA7323C74DCA355E04B713A2947
+:1006E0009E6382BEC3018E2B682FB1DC6EE5F19D47
+:1006F0000D40278B9FBEC1E5CCC3F703CAF05CE376
+:1007000028C6196404E15F932F33F2FAF0C4AF26D0
+:10071000ACCB66ECCFCC3E10E956863A04D7F74511
+:10072000D15E8C97DF83F1251BA67AE297C97AE622
+:10073000D1F1B42612CFCC8978D34481CFA92398A4
+:100740002F1AF0EE3BA88D77DDE7D3F97A037EEF21
+:10075000D1FB1A913F7566BBC10AE3B8F29421B888
+:100760002E295B7E73F0A6259AF3D7A5425EC7CFEC
+:1007700085B5FE80C7211E046145BCCDD0B3FDEA1E
+:1007800010CE0788974A9BDD43ED1628140F95710C
+:100790003649FFC1D07D201D1F14F0413F3551F86F
+:1007A000BD3134BDFA26CAF5731DADABE70BB99B5D
+:1007B0002FE56D9B56DEC627DAA9BD827E30E0EDBF
+:1007C0004191762617E344FFE312B95C64DDE278D9
+:1007D0002CB2359DCEB708792937F1FEE5F8F788B8
+:1007E000744CA28DFA95F000BF1EC77E74A00190D4
+:1007F0005F4FD656937F348705C4B533FCED245F35
+:1008000077CCB7EB11DD754C8DADB310F5CAF7C2DF
+:100810001CA8471F34D6F5AC8AECD84EEEDB14B2D8
+:100820006603233D29E261C2FE8C5523E97C40A189
+:10083000C2EF0F5ECAB17874D118A73110690B638B
+:10084000143A3FF137B17FF250F4E28928D785514D
+:10085000463DA633582BF5FB776BB7E8FB18DE3324
+:100860005631760E038FC877C2B8D5A877787E8DBB
+:10087000339BA24A227FC72127E0E1DE6B407FCA7B
+:100880007F2FDF09FD5F7A4BD4B33BE9FB4B8F0B26
+:100890003EF6E4F2FCCF657D1ECFAF92F5F93CFF4A
+:1008A000A4EC5FE49F0EAA5F1654FF4B9E5FBC3E14
+:1008B0003FDF837EEB68CED285A314D2537B84BE08
+:1008C000285CEE23FC16EAF6F27434F3E9B26EDC2F
+:1008D0006E53A26B0FDA1FD572D282F6F7D564275A
+:1008E000E59F4F702F4BC475D424C563447DFBA195
+:1008F00097ECC1C44ECE1FEDE9C2E3F89B92A0BFB6
+:10090000A17EFB05FDAC4E8CBFF57E1C491CAE8064
+:100910007E9EF926F0FCA7233C1BBE493FB392B54F
+:10092000FD487F484975BE86F36327E334E745E613
+:10093000FFC4118DF12786E74500F5F397D7A5672A
+:1009400042FFF35F7D3DBD04FD2561E72BDA74CCEA
+:1009500089F734DB18A5E71B3F31E27DB38A5D8D53
+:10096000C671D0AE12D2DC00B8CA049C60E7F49322
+:1009700003EC7383D01B8C3DCDF7375F3DAB477ADB
+:10098000CED7D59D7A0EEDF62825E43ECD66F1DD75
+:10099000D14ECE17EF157AE86A9AB311E7F96B8C4E
+:1009A00021403EB7BA93FB60491C5F85C2EECD1C67
+:1009B0006631DB01CF433FE4FB54251B3286603CAC
+:1009C000F8CD84D1EF247E6D3CB595C7531B783CA0
+:1009D000B5D0D6BC089437332695AD31DFC1D88465
+:1009E0005F48390391856FF34C325F9D3F269BC76B
+:1009F000BB307F76FD636B506E9AC2B91FFBD0F09F
+:100A000081E1A8175A3222745690E737E38B8C495C
+:100A100043B1FC8E71589E63B2F42A22FC32E28B01
+:100A200037E35DC7905FB03DC641DC465FFC7D307B
+:100A30000FF7DB2A9DA7750F8A7087DA77FA87C0D0
+:100A4000AB31C94A69139019FD1709871C1FFCF9BE
+:100A500045CDD0DFC9E5498357DB719F25C7903469
+:100A6000D43F7E4682FB72E0F82775AC172E296EC4
+:100A7000168E4B020E03EE5D03BE5DD92A7306ACE3
+:100A8000F3268F89D0E4EFCD8F65CEC038EDBD2938
+:100A90009AFCF4C2EE9AF60FCCEAAFA92F30356774
+:100AA0005505F8B19DFB491E82A7D26209477FEE2A
+:100AB000EF0D5FFCE541F4FF36AB0EF455E7EED9E0
+:100AC000F297DBA1D5653C4E45F1473BC5CBCEC97E
+:100AD000F3287AA73E705FE8226BA6F33E9DED03F4
+:100AE000C975EE7CEB7E3A77F65DEF03F54A12EBC3
+:100AF000DD216C08DAC3CB551F51BCAE2292CFEF7B
+:100B0000E2EBC78CB80F8AFB8AD781DFEFC20FD127
+:100B10003F6CF3503C3BB7FE18ED9B1D48E47ABA9E
+:100B20002275811EEF1D55428A76681CE8AB68E08D
+:100B300097E646367017EEBB6658B81FDE3699B199
+:100B400058E42B1EDF694A88A17BD7F36BF2A8BC5F
+:100B5000A22D9CFA7F4F6D1E47E7095F5368FFA1E6
+:100B600020E5A1E5787EB829DC33E01118B7E077FD
+:100B700077E521DE2A76F1F3B505EA9FB316405AF0
+:100B8000569B47DF17A8AC49017F61422EB7BF05CE
+:100B900068F321AF0EB3AC46BBAB1A7DBD9E473D9B
+:100BA00063B4909E896E7B80C6AF6C33D3F7F72415
+:100BB000717FD7D0C2E11ADBE6A272C90F5393BA94
+:100BC00069D60F86F8CD7A7C97C3D0C2A8FDDD6DBB
+:100BD000FD2895F37DBBCFAFE93EAE21FEEAB81408
+:100BE00098F7DB718A95DC90203D7CA56A78340B00
+:100BF000A1A7DAC769E3E7F44C6DFCDC5E618A7398
+:100C00007E12C031F1B1163DEE07B148B315F13592
+:100C100071C4607B49807CA97BEF37227D0CEBDEC1
+:100C200037A29D36419A1B505F2ECE3304EBE90567
+:100C300049524F2FA354DA1D767506F9A933AC82B9
+:100C40000185FCCC10FA547EDF4C6B1AA0E36E1EBB
+:100C5000C77F34C5BD02F545730E9BBE83F4667332
+:100C60003AEEC37C57F0039DCD0AF9892D741E75A9
+:100C7000E208BB0EE3FFAB045C528E6F348FC5A25B
+:100C8000FD7B2A5B82FDBE77E79DCD4EE8AFF14745
+:100C90009999680FE4B8CF25F17B29CCDA7A0DD782
+:100CA00083956F44D851DE0B703186FB9D7B4CB42D
+:100CB0004E8172DACFA87CC3B409EF895446C17A59
+:100CC00015C6CF7D33CC877CDCF866981EED46EFE9
+:100CD00074F77348CFDC377B8FC1F5A1B3C1A4672C
+:100CE000E4F7389F273DDB09BC37D25BC17C26E5A2
+:100CF000D35DC3E5A548F069B1903FB790A32B55EC
+:100D00005D480EAF3C0640E33EE963CAC05DE8279C
+:100D1000D82DF47E9394CB025C0F417941FF183AB1
+:100D2000FF2BFD8D60392C6BB352BFE56D7621EF43
+:100D300036CA4BB92B167263127EC62CC1E7BB5361
+:100D4000DCEF205E0AAA41EEA3681F3F0BE5C9CF86
+:100D500037462BF217F04D624980FC5437DECFD076
+:100D60003F31C5B9886F66411AE89FCC6EF74FAC2A
+:100D7000E31200FE892B327478DFA99D7FDBF9E650
+:100D8000E6F87F8F9097E2485F4FF4670D55610E4C
+:100D90003C877E398EEFF72C5CC5F1B8D0E0CA45B0
+:100DA000FF62E12F158A97A1DF817A69D8912A63C2
+:100DB000601CE5FEB641CC0E7898D2D683D23713AC
+:100DC000DC47110F456DD304BE067DA3FDC5A14EC2
+:100DD0001E4732784D8E8D19184772AB48E733693C
+:100DE000CCFA4CE07EDE7A1DC5C3E4BEA38C2B9901
+:100DF000F0BC7C801DFD425F9B4EEF3704C79972AB
+:100E0000B8DDBFB0D94076BFACF1CFC374507F2EF0
+:100E1000C3D905EDC9977A771BF2F5BCC9DE570D2A
+:100E2000909FFFE4CEA891763F3EEBF4BE9E6847CC
+:100E3000EB008F18EFAA5BA3E679B9BF13C1F7C91E
+:100E4000387F4B7E0EE6F3796DDD889FAE5499C8EE
+:100E50000E5D01BE65017648DA1DA9E7A5FD917C0E
+:100E60005DAEE7FAAB3C32DAEBC908B43B935C39D0
+:100E7000C8777DF8791ABFDDD9B47614CAC1A53810
+:100E80003AB728ED46B01CBCB6141CD35E1DED8EDF
+:100E9000D4EB52CF4BBB35FAE52F77FE15CD558AF3
+:100EA0007B4032E0EB6E3DB75F77EB2DC43F63E3F1
+:100EB00026E9916F6E5E8F1E137AF498468F5674F2
+:100EC00062070627DF9A1C7415EDF34CDC7F443D66
+:100ED0001FD8DFA329A3C7E03CC627733BFB5DC136
+:100EE000DD99FE1F9F7C6BFA7F58B288F7DD40FFCB
+:100EF000172673FD1FACEF9995BFA773694F5F2F3E
+:100F0000DA83A30CEC03DAC18608FB16610FC85E16
+:100F100084477BBFCE1E5C4D9B5988780A610F1EAB
+:100F20004AFE16F640F2A1941B2927522E82E5486C
+:100F3000CAC5849FC23A11E9F41EBF5750AEF76C80
+:100F4000A3FD467BC46094CF763F6E9742F2D6C134
+:100F50004E08F9F1CB8BD66E48B990F222E5A75C2A
+:100F6000C8C5EC20B9D8A7D63D330AF7CB92DD6BC4
+:100F700093E3FD7252B623D83E74CA57185964B32E
+:100F8000E3AA18F25539A4817C65EA441E9E49BE45
+:100F900035BF68D94DF2D36FFEFBFCF49B4EF8E9E8
+:100FA0007FBE0D3F75F4633FCEB2033C57B240DFC6
+:100FB00066F8F96DC23B8CFB0FDDF97A00D6970419
+:100FC0007793318DE23E13AEB32A8A2F0ABE947412
+:100FD00096FEC06C11773893E27A07E1C5F5C082BE
+:100FE0009BD37B4467535CB311D727B3210DF40324
+:100FF0003AF37F9B6F51EFBD7193743E96FC9DFB5E
+:101000008DC79243FB8DC7B1FC9BD2B5209789F861
+:10101000DE8F0B30DE38E1299167CB0A108FD34683
+:10102000C8FA9F3CE9EC81FA81C9B838C539DE536A
+:1010300045DEB3F4F018683FE119E68F9B43FDD815
+:10104000ECE8F6B888C2FCED95E71F3BBC86E8519A
+:10105000CBE5CCDDA2E7FB3F229F05794B407E44E8
+:10106000507E036F1FA56F6181E745909F94219C7F
+:10107000CEAE00FF0186DF7F05ED85556118D7A84C
+:101080008CDBF8D615D46BF50AED45B5E381D514A4
+:101090003853C5FBB9945F73D8093EC203BB78BE11
+:1010A0004F4AED931EBDE837E0DCBDA14E71D2B9C9
+:1010B00083118AB75B46477CF749D1DA27FCD16BAD
+:1010C000BF67781EEF56BE6FBFCFD68DBEF7996E45
+:1010D00061FCFBB2439F7FFE5E0AE7EF3159D121ED
+:1010E000EBC7A5A8BC1F1137A0F1A1684A5DE87B3A
+:1010F000B013C5B8CDB85F42F8DCF624E2B7D92802
+:10110000F1FDF293C8776319D3C4CF607CCADF9F27
+:10111000F272418D9E4FD71984AFAF9BEF8014A917
+:10112000BFFDF8F204D1CBF435F87684C0B75DFB8F
+:10113000BDEFEBE835ACC3F7826FE7483E766AF85F
+:101140003D5AEF22FE8C8E53ACE84757B8C2D6E02A
+:101150007AC12F9FBF27BE6C96FB031DE4EFB5023B
+:1011600094BF0A8947CFEB4FA2FCBA74EDEDB93CAE
+:10117000B6F33573F601BC52C80FBE7FE4F9FA2707
+:10118000312E097C41F594D707C01D2C8F7541F98C
+:10119000EC20F915F247FA03ED01E0A927EAB7B808
+:1011A00063467B009FFC4CD0E9A2B827DA3C9AFB4F
+:1011B00093CDDD78BA2385FB8FCF097C6E12ED9B32
+:1011C000C303F090AAE11F1FAE5B02E64D78BA3F61
+:1011D0004ECEFB93827CD063CD365EBF2DE5A32738
+:1011E0003DD9FE7C707FAFA67C528078F1F7FFF18D
+:1011F00061F423EE1778DB9172E4B02752D039C145
+:10120000FF4E21F007BD63518EFCA174E48F1F7661
+:10121000E44F4FD0F7F44E7767DF7B3A7EEF0CFA5E
+:101220009EE13DEA9BFF5ED02D3F88AE7941741D63
+:1012300013942F9479AF46FF4ABD5C5CFFF4E30939
+:101240007118DF54E838BF9F9F4F93BD996F95FC8D
+:101250007BE630F2AB9F9FCF129E27D709BA79CE9B
+:101260003D897A7812EAE151FEFC14D443943F5F41
+:1012700080FB617E7B7581EAEFAB91ED2F92FD7A69
+:101280006085ECEF33CA4B3A32CF25B277F70BBD0E
+:10129000C33CADA4F7E735F0EF3F7DFEF3C35F2B12
+:1012A0000FB54178D91094F704B55F7703FBB622E8
+:1012B000E8FBC782EAD704E5D707E56BB4DF17CDB3
+:1012C00052480E8B46F0FDC960B90CE68F2F52DAFA
+:1012D000E363EDF65C8924FF4E235713AA79FEFAE7
+:1012E000F3FF29A8890CC8A7B0891EB2EF305AC0F5
+:1012F000FD41D0B91E15F8C1D089DEBCD899DEEC0D
+:10130000136CEF79FD3FF0D724DA2FD2F825FB5488
+:101310006DBE51957047BDBB2832605F955926E27E
+:10132000BABAF3FD9B8889635203FC224FF84467E5
+:10133000C03C65FB715F5D5771BCF8D4F0899B714F
+:101340007F68B4D8D7B4F114ECA58AF6BA52C46F4A
+:10135000C6E1395D6C17EEEBB930D00F6275BD7028
+:101360009E8D3F52F9BB50D5401FC05311B3D37966
+:10137000D39978EABE3BD447472FF90D7CB7EF47A6
+:10138000EA12B4D34797C4D239A645A9DCEFDC17DB
+:10139000DD356136E41B231E267DDBF8C4584AF791
+:1013A000AACE95AD56E83A357962645FAC8F263C9B
+:1013B0003936C44F5C06FC9D996A2738DC366B428F
+:1013C0003DFADBAB0DB45F082D7E45FCF3A469301C
+:1013D000AEB78B96F5A7FDB0E29F4F1A87F7B08A9C
+:1013E0001F37D03E498BCE4A7122F7EAB1742E6A7C
+:1013F000D60A917AEEA2F4CDFFFCBA1AEF69B5BE17
+:10140000A0D0FB0E775CAD7B67109E9BACE94EF7DE
+:101410002EDE8075009EFB3EBEBEB717CF219F0813
+:10142000ABA273A4D09EEE8B955EB3BF3B310BDBBA
+:10143000ABD6E5D0FE1494A3FF7C6A95BA09EF41C0
+:10144000154559C2F1FCF6A9AF18C5754E3D6EA2FF
+:1014500077228E47BA67AC8FA3FBB8E8E9B3538A0B
+:101460003D4A013C4CDAD067626212969B047DFBD8
+:101470004415011E8A74EDFC43F6A42486E727A5D3
+:10148000F699B805E671EA97BDE97CD8C154E7E45E
+:1014900054C0D72FD29C5352E3115E6EB7DEFC0FBF
+:1014A000DF8FFCE385E204E4AF8752395FBFD1569A
+:1014B0009C10F8BE77C9453DF1C19B46FB227A27B7
+:1014C000303C4DC17536F0412CC6CD6789750BF0A7
+:1014D000F3929D21FCABE1A92AD1ABF1A7F1D94848
+:1014E0005F3F5F0F7F17F519AD37205FB121732D77
+:1014F000DAB993A625EC440FD67EFE91ED0B233C82
+:1015000019B68579C332307EEA1C87FCCD12EB7A9E
+:101510004DB604C8A168FF770F3FE7FB77688FEBF4
+:10152000BEBF7BFED712B89F21DB9746593CE85CD3
+:101530009CB658F4488FA3FAA5A7F03C5AC90B06ED
+:10154000B203252FC43FD68AFA07F806E36BC1F32E
+:10155000FA63AA81C7313A934BCF18AD5CB231130D
+:1015600071BE9DC965CD86DC899B233B97CB522BF1
+:10157000D74FE35EE0EF51960EB5E8717F73F40B41
+:101580006F6DA17B740BC286E0BD89D2174C44AF4E
+:10159000168BC563BD0DEF1358F431903E9BCAED19
+:1015A00069BD909F5C95E9CD4328A57B1272DFF061
+:1015B000EC92679EC5E397E79877DA70C0DF6527FE
+:1015C000E7D3CBBB548A3F06EF23961FDC69CC617F
+:1015D00037B18F7883FDC332D622DEDF0DFD7DF07B
+:1015E000FEE1ABA9C1FB8706BA4F5E2AF60F73373F
+:1015F000280477E9127ECF3F3796C78D4F2E05FA24
+:101600001B69DE1EEB103C0FCDED4E2953BC66F876
+:10161000F5AE0D0B288ED913F184716EF16EE2894F
+:1016200030473AAEF34B5E0823FC96FE6AEE5F7ECF
+:101630009985F7FA0AE202D7D5FB912F387E19DE99
+:101640001F94FD9C5EF6637AA731F745581FC37C53
+:101650004A63D8ABF76720BD92D2719F53B62B5D1A
+:10166000FEA35EBC1DACAF611D5DB44AE5EFC7ECE7
+:1016700036911D04594F6401F72C67AD38683472F8
+:101680003BC6128709FFDAEEBF9F761CEAF1EA6ECD
+:10169000A5B88726F127EF5115E9F8FB74853A853F
+:1016A000EE578126A37B499753B95F7B3A959F6795
+:1016B000284A77D0FD9CF2B526C7F20CDE4FFB7DA1
+:1016C0004F58DF95EB9A4B683FF3F7268AAB54AE41
+:1016D00008738645F1F3173B06D0F96ABD11F05146
+:1016E00066E7FAE2B2986FA57DD25D749F41CF8E16
+:1016F000E8A1BEDCC2F563790CE03D92338A6E1836
+:10170000BE67C7E8DC24F69B3428607C4594433FE1
+:10171000F6287FBF4D3A5683711B6CDF7710E2319C
+:1017200076DA7484EF1595E41990B47604FA7DAFF7
+:10173000A899B8DE2E5AB56F1CEADFF9DB07E38DF6
+:101740000956F4EA07643FE60BFAB7887367C59059
+:10175000C777B622D2B83CB9551E2F8A485334EF0A
+:1017600010C9FAF255061EBF073D8F8AA57CD9C75E
+:10177000D46FB9A53901F56FF96EC330D4D351696F
+:101780005C2E8B97A5651F01BE2A3644D3BB8365AB
+:101790009E0223E6CB6A15CAFBBF8B4F473E3DBF77
+:1017A000E2B528E49F1361BE9E68975A178439E812
+:1017B000DEA195C7EBCEAFE849F79566599B2DF8AA
+:1017C0009EC1AC45DD6DA8BF8F5A7D46AC3F5A9790
+:1017D000A1C3BCD36ACDC6BC537F1BE5CF8BF32D11
+:1017E000F4837CA5703A976DDB67C4BF4F3244CC5D
+:1017F000F7E22B1FF4C2F84F797A732FB42BC0078E
+:10180000BD5210CF2F2964972BB6F1F3EE920F2A19
+:10181000900F40EEE6093EA8D8F5DAF7511E2A905F
+:10182000FE433AF211F0F37E2ADFB1711CE3DFEFE1
+:10183000473E91760CF22B0C368CDFF17C661AA7B2
+:101840003F948FE1E59E01FC1C5DFB39048D1C7407
+:10185000465F571AB787C5CB4CA46F5D695C1E5AAB
+:1018600056ED8E42FA5D7C65DF01DC6729DF0156AB
+:10187000DA1E421E043E2A71FE51043FF9179538C4
+:10188000DF28FFFCDBF95EC86125E3F393F3ADD4F9
+:101890008BF9CB7AF1FD24C12F654CE06B576F2E8D
+:1018A0007742CE508EE9BD0E313FB74DFB0EE5F7C6
+:1018B000C5FCDC2265D6BA28C40FD217F50F3E103E
+:1018C0006994FA049A5CDCBE91CEF14B7A49F857E0
+:1018D000093840DF39636C7E3AB674F24E6495E0A5
+:1018E0009B638F7749AF07FC9DDF4ACF6C11BFEA3E
+:1018F00003C6937C23C7CB7D79D2DD386FE8DF87C1
+:10190000FDCB718F7A22F4D8CF51C6E543C22FE5C3
+:1019100032B7FAA1BB074761BB8B96EE0370DE9C22
+:101920008EABD2ACF4BD13FD05F8DE59AF50DCFA36
+:101930009858E71F7BFCB5A8E2017E7E7F427C279A
+:10194000F90C7F303E26E16DB2F1387030DC520F79
+:1019500049B8739FB8EF6E2C97F0E3BE51209F4AB1
+:101960003C4A7E95F7F582F996784EDA4FB573FECC
+:10197000AE4C3D46E7773A9407F727FCA213E25CAA
+:10198000796B3CE371FF1589FB35F78A188B0CB432
+:101990003FD28EC0CF1A7D80FD69BFA716E73C8B72
+:1019A00074BB90D68DFA3FC7EA8C39D06FD999E6CF
+:1019B00071F8CE9DF443EFB8EA53A3315EB58B9F27
+:1019C0007793FC5276613FC941B9B8FF54B4EA83BA
+:1019D00082E1C8EFBF35D0BE4ED1E3638DE8DFCFE3
+:1019E000DD327318A201EF41A05E3FBB796826BFCC
+:1019F00059604D9886F721363F33ED01289F55AF4A
+:101A0000D2BB0DD80FCA6FD1A399145F3D11D65226
+:101A1000300AFDF81FA856F4E36FDF32F4316C7F13
+:101A2000BBA56B0C3DB6B13996F24E7D34D907E9B2
+:101A3000F7CA7380D5E2DEC75F84DE3FDC9E2AE210
+:101A4000FC5F752FDC8F6FDD1846EFAC141AED7557
+:101A50003E1C6F4F175A67541AF1EA23DD5B25BF0E
+:101A60006C8E9199938650B93909CA0F1A9A1F45FD
+:101A70003B72F051CB607C3F92A9D78615737F9A59
+:101A8000EF3BC66ADF2D91707C24C60FEE4F7EDFE0
+:101A900084EB081BDD4FA4EFCFAEF8ED34B48367C1
+:101AA000B7F6B4E1BC4FEF09A3FB03A70DDA77CF7C
+:101AB0006EF5DE57F07D29796FF5749AD68F93FC19
+:101AC0007EC37B377FD39E83BCD1B9A50B4B19DD79
+:101AD000FB7E398DD1F76322BEDA89E7084B6A4D68
+:101AE00056BC077312F91EF7B376ABFCFEA599CB73
+:101AF000C1C9DD9974BFB7E46F3C5F52A778F13E6E
+:101B0000F2FEA79FA0F30AB3C1CFC4AB09EDFEF369
+:101B1000BAA7A7A1385C76B857E27DFECB5BF9F98E
+:101B20008A0EEF321CDC7920C9DEB9DFFC5DFBCB0D
+:101B3000320E119FAEBDCF2FF12CD74F6F023F8CCD
+:101B400018E2C7DB674BE790BF7C61A99BD24BCA09
+:101B5000B1B5B7231F5BA2E9BEC01FEB9F51F1BD1A
+:101B6000A8F25D83AFE13A78546434BD93F2D9D2E0
+:101B700025B48F7A616915A592DE320E77C7AE461D
+:101B8000FAEEB3FACC06BC9FFB4664B4B003B69041
+:101B900074EDECDEB19CD7B91F70FA4AB8CF6D9DD9
+:101BA0001985F36A7C3EB66124D23522DA8A7E5FDB
+:101BB000A93847726A3DF7ABCF98A37F930FF43DE6
+:101BC000B3614A02BE3737BBF1DE69585EB247B136
+:101BD000E27AC0B1675214AEDB3ED5B744E1FDA84E
+:101BE0004FD7CB7B555EFA3B54A3F2D8146C3FCA57
+:101BF000A767F60CBE758D7C32F2829EEEBF9E8783
+:101C0000728A935C0BA73809FCC4E2B991D9AFF38F
+:101C1000F84AFB3A57ACF36E17F37E34DD26F73102
+:101C2000A83C77042F3FBD61E744ECEFEC668315D9
+:101C3000E1FE6CB381FA9F07EB331DC07B662B5F1F
+:101C4000F7601ED7CB67B7F2F5CDBC3ABEBE295FB1
+:101C50006070F2FBA25A7ECC0D6847EFFB74F25E17
+:101C6000C83C279FDF3CB09738DF60BE8D6175743C
+:101C70008FEC9B9E170DE6DBF9925F857E68E7D7B8
+:101C8000CEF844E013E51DF955F2C3BCF57CDFDE68
+:101C900056373807F94EF247F03B59D546C6DF575D
+:101CA000D485D37BB89322ED06B40F53E25AC620F5
+:101CB0005A3E4EE77E809AAB73E2BD37566D0AF905
+:101CC000CECE8A74EE57457465C4EFDE742B3FCFD9
+:101CD00029EE7FC914269286767B5284ED0B3B3425
+:101CE000793AFDAE7BF4C0CF936EB73DDADDC1D853
+:101CF0002FD30BEED1C37C2665DA767783FCF3BF56
+:101D00009AC0F3B7D9861A20BF4C9978CF18C8D794
+:101D1000A73B9F4A0F18E7EC962E69383F28FF191A
+:101D200096D7C5BB7F8E69A5B80F7649691DB424C7
+:101D3000C3DFFEFD3D96A37FB4FBF32D0696EE18A0
+:101D40008079097FE8B425DDF9ABF4F88EE5C58C20
+:101D50003D4EE7F53CFC1E0EFCB8CC09784F8AF3EB
+:101D60005BB1BC975313742FC7C1EF9FC9FB52F2ED
+:101D70003E545FFF7DB20DB7729FEC9281FF1D2A2A
+:101D8000C5A9BD0FA634FC89DEF9A9F6B09630A22C
+:101D900083F69E4D39BE53771BDD0BA2FB874C6F3C
+:101DA000277D3357FA3B68AC87F9DF296089FCFC53
+:101DB000C1A3821F4F2F653D7A80E89F7FB739CA44
+:101DC0000E705C98E8EB85FA2032DCFD27C4D7E979
+:101DD0000DD5A90BE3F01EAAC9910FEDCF78F97DBF
+:101DE000CE32E1B7B2CDF1422FA8BE3BA15D534642
+:101DF000DF4D6887DE177C7521C397FE23D42B192E
+:101E00007C9D04EDE83C5DDEF2BBE2B1DD85ED4F8B
+:101E1000F4980D709B0006BCA7351EFA1C61A3F751
+:101E2000AA984AFBCF5EFE7E929E79A26CF8EED510
+:101E300033E9E23E11DD13947492F8EF4017181A5B
+:101E4000FD599D991910EEBE6C03FDFD2F491FF938
+:101E5000CEE2C2DD3CFE427724451EE348A7CDE238
+:101E6000EF9F75B08B6F91BF0A62E9D1E89F0D3388
+:101E700043DBC9111B8DD8F5776D2FFF9D2EFC928A
+:101E8000C16C70E03B92A5A2CD58B5D08EEF5B2D12
+:101E90008C37D37B250B5FE84EFCC196FC9005B6D2
+:101EA000631B62895F5666A884FFB9F58CDE1D2A24
+:101EB000A84FA6F394F9F5364AA3DA12A9FCEC6F01
+:101EC000DEC9E27A89D3A7E07FBA8CA6734BFFD331
+:101ED0009B52D6D97BA79166BACFBBF020B76B0BCC
+:101EE000A7CABFC7C2EFAFBB0438AEC81A8A0BB9C6
+:101EF0003ADC53E7EF57BAF0BE007EE734507D6717
+:101F0000EF574AFC9A04DD82DFB39C7A303391DECE
+:101F10007F14EF594E17ED9AC5BDB3CEDEB5BC4F59
+:101F2000B47B226A5C13F2DD746769C8772DF59E75
+:101F30003007FACF86D4487A47E13E37F8979AF5CA
+:101F40004C8B1EF1302D9BBF733975BAB6DE90FDF8
+:101F500039E97343768777920CA88F4D2E6DFBEC91
+:101F6000AEC20EF5657DBFF65DD15423D94F3DBE9F
+:101F70003B0BF969E25D51F40FD1FFBFECB410FFE8
+:101F80009BC43BB8CD2C2B11F5C2ADBE27FBFFDBAC
+:101F9000FBB1C1EFC406BF03DB7FEB424D7E60DDCA
+:101FA0000F35ED6FAB5FAEA91FEC5BADA9CF6CFA3F
+:101FB00099263FB4F9394DFBE1473669EA47B6BC8B
+:101FC000A4A9BFFDCC0E4DFE8ED63F68DADFD9B690
+:101FD0005793CF61EF68DAE79A3FD0E4C75AFF57CB
+:101FE000D3FEAEC4139AFAF1F6F39AFA097DAE68FD
+:101FF000F2058E2F35ED3F37BA577745BF22EA0CF1
+:10200000F1AD3A4361F844F9E5A62966D4076BBA05
+:102010000A7D24F86FB9B0D3AC07A37BAC63D56C51
+:102020001FF15F3DFFBBA0C1764F7FDEE5C4F81F07
+:102030007B8DDF6B8B067F521F307E8CD3CC02FFF3
+:10204000EE5D6C9E55938F77256ADA77996ED7D4BB
+:1020500027B9FB68EA53E63834F9B4AA119AF65D59
+:10206000973835F90C4F9EA67DF71A9726DFB37681
+:10207000BAA67DEFF56E4D7D5FEF1C4D7DFFAD5532
+:102080009AFCC0BA259AF6B7D57B34F5837D359A8C
+:10209000FACCA65A4D7E68F37A4DFBE147BC9AFA1A
+:1020A000912D5B35F5B79FA9D3E4EF68ADD7B4BFE9
+:1020B000B3CDA7C9E7B0839AF6B9E6F735F9B1D63B
+:1020C0004F34EDEF4A3CA6A91F6F3FABA9977ECED8
+:1020D000843E9F6BCB85DF53E0F897E6FBF6F76E07
+:1020E0007728741FEA5CD76EF27DC5963015FD2403
+:1020F00017C5996C781011F515DE27B7F1F33985FE
+:1021000014AF8A237F884C941DCF0B81DF1085ABE1
+:10211000B68C0CF4AB23FCFE5BEAF5CC9BF7DFDA64
+:1021200084FFDCD5EEBE88F231AF6EFB387A9F9823
+:102130007956221CF2FDBF7783DE6D95E978F3199D
+:10214000A60FF0170F86D5A60EF99A38C178F305B9
+:1021500086EFC1B6F72BE222F8C7BD1706F4BF160B
+:10216000D617F8F7236B979AE96FC7FF6CA995F21A
+:10217000EB962652FEFF003A29BF47008000000080
+:102180001F8B08000000000000FFED7D0B78544518
+:102190009670DDEEDB8F249DD07975779EDC3C490F
+:1021A00048089DF0D8003E3A216040C0E635044919
+:1021B000A4C1A84143BA81F84F7475BB311002B273
+:1021C000B391D11095C1860164199D092EA3D1093F
+:1021D0009AF09AE03A4C601CC5D91937A0A3E28E58
+:1021E000101EE3CFEE8FC37FCEA97B93BE9D0E382A
+:1021F000FE3AFFF73FFAFBB4385575AB4E559D7369
+:10220000EA3CAA2AAD5E898922636DDE1C4A9FF3EF
+:10221000DA9998C9D8366F31C1DBBD0E82FDDE7206
+:102220004A777A9D94BFCB5B41F01EAF8BD2BDDE67
+:102230001A4AF7793D54FE92B781E09F7A7D94B6B1
+:102240007B9B29FF156F0BC107BC6D04BFEAF553DB
+:10225000DAE1DD4BE91BDE762AEFF47610FCA6B757
+:102260008BE02E6F0FC187BCBD041FF19E26F8982E
+:10227000B78FD21EEF6794BEEDEDA7F277BC57097A
+:10228000BE8EBFDB19FC2ACD9FE431263097E67A5B
+:102290001EC2CCC92632F600FE4B82FFE24688CC35
+:1022A000C2D8FD8CFF3ED7B09A76139477FEF23FEA
+:1022B0008502C674A58C8D1F0F6962F6CEC634C622
+:1022C00026B075E64F7218D34057D76307FB094E07
+:1022D000191319D6C3DF752DFEDFC7583CFCBF9418
+:1022E000E5784C836953091442FBBE55827F771A07
+:1022F00055D7203EAB8D1CBF695A1395573E2CF81D
+:102300000D02635522F3E98B18FB7D5854011BC164
+:10231000D8258F2E47C47221DC0E8304F88F3A44EF
+:102320000E7E5D2C8EB1A59D861D9BD206F1AA84E2
+:10233000EF35F0FD2B561A0CAB643D3AC403F21D89
+:10234000DA18C69EB7B8A64B90FF608AC6A787F674
+:1023500099C99FED8C64EC2D8B6B06E65FF2DC7700
+:102360000C1B7FC06CCFC67E661BBAE21741FFFD17
+:10237000C7B5F69DD2F0F3E16E29676CDC0DCADFBC
+:102380003C97EC023CCAFFA275E1FC9FD04556F891
+:10239000F3012F49E0784A1A553ADBEA5A82F87C71
+:1023A00019E9B9470353F8E56DABF6AC812155AE99
+:1023B000CA1AE182EFEE822563198CCD65928E41B7
+:1023C000F97CE6389A064D2D642E8217311FA56FD1
+:1023D000C5BBAAB19DC5CC4FB06BB22135D4B88274
+:1023E000F172CB78B9657C94F471ABAB8EE3E520E8
+:1023F000BC4E4CBA231BC7A5E0F59655A27A73587C
+:10240000FF76C4EFCB83173F113286D2C7774017D0
+:1024100026681EEB313DAC73A38ED1F78D8F087EFD
+:10242000A46B852E2A9991B7FB18E40B817402F4F2
+:102430005184FCD29F3A3792E8E449091A7C7092A1
+:10244000D6A71F0BE3D4F8B3052DD1875E00FC1E81
+:102450008803FA481F9E0EEA9A210DE01FA0AF677D
+:10246000B0BDF3AFFF5D0ECE97FBCD4912CE57A3A3
+:1024700006D601E8D8F7B6D6BE5B92991460ED9403
+:10248000317EA46B26DAED73C7E07AB1A54EA8DFE2
+:10249000AD650DFBF387F6FB2AAE17B47FC2A62B02
+:1024A000F753BB9CCF95F29FE2FAC563CAEBAD5ED2
+:1024B000F569AD16F03F71E89C5E1A13621C0D6F52
+:1024C000E76606E0EFEE3833DD6142E4FAF2E74515
+:1024D0000EE69F94E944A11FAD3ED2B5C314881700
+:1024E000EF17E8F9E74437D140CF1944CF9FF8E020
+:1024F000D3390669C42248FB606ABA2075BD60D62C
+:1025000023DD2C67764AAB9993D20760F9917E9DC3
+:10251000BEA7F438EF0FB276CAAF2BBED782F47CD9
+:10252000BFC6958A702DEBA57C37EB2FB3C1FC2D70
+:102530006C5E7BD40658CF6F796A5A02CCEF3CFFB1
+:10254000B2A398CEDD257CE293883F7A10AF3EC1DE
+:10255000B33E11FABFFBA592F549903F47CBD78513
+:10256000FD2B5F17457E048F1BF8A1978FCB41E3AE
+:10257000D24695ABF8A1F209E610A09DFE8306FFB6
+:10258000CEB400FE287EE8DF93508E89FDF7E07A16
+:10259000BBDF34C4E07A3F08E21BC72938186B80E0
+:1025A000FE90D62A63882A88DE1F62E176ACF7B9EE
+:1025B0004CDF9FA730A2EFCF05E66040BF1774A69F
+:1025C0006601E55AAACB5604F8AC60BE2606E56E55
+:1025D000CD4B05384F2325D7A744D71FB53715A6B0
+:1025E000A1FCF7A70A28FFF719EC8D69AAFD845D05
+:1025F0008F4021E361389F3FC076C70EC54B283E10
+:10260000F69F421463063DF3198B88BFD944E4EB6F
+:10261000443DF157234E6D06F6E3943CA6A1ED9F91
+:1026200090F1EDF94A4B74EF83F1EC1642F5C3F7E4
+:102630002B43F8603F243F2C8CFAD1A7713E56FA09
+:1026400063A6BE6427D0756A844B978682C116C77D
+:10265000E58B99CB979EB44F33717DE64CDEA8C8CD
+:10266000656A8FDDC6E5D1099DE443F844499A1DAA
+:1026700024D7809CBDABF897A7118FBB8CA62E2DBD
+:10268000A4EC16DD9FFA947D307D70FFBD4BD97FA1
+:102690006FE1FBEF1C99B5EF12BBBAF17BC6EC3AC8
+:1026A000C42F97FD5E998F6DB8DF2AF271C87E0B3B
+:1026B00003EBC5F913252B8374B5C0C7BF3A25DCDE
+:1026C0008F7CC436E7D2F8F4B2FC0CFEDE5AC15857
+:1026D000A651C613FE4B70195966CE209C54635602
+:1026E000C1291E9BAAFEC80649559EE6CB51956797
+:1026F00034DB5570564BB1AAFEA836870ACEF59743
+:10270000ABEAE7ED75AAE031ED15AAFA633B5CAAE6
+:10271000F2C2AE1A55F9B81E8F0A9ED0DBA0AAFFEE
+:1027200077A77DAAF2497DCDAAF2299FB5A8E05BE3
+:10273000FBDB54F56FBFEA579597B07F56954F3541
+:10274000EE57C1D3CCAFABEABF80FB16F0CF1DB6BE
+:102750006E55FE0CE9B8EABB3B734EAAE017E47570
+:10276000F62D0E27BE682DE7FBD16CFB07AA765825
+:10277000E768BEFE613C6F7BCF1F0B514E6ED7F4F6
+:10278000A721DD4A5A7322F27166F1DC4340662CC0
+:10279000DBB1AA14C55B4EF95387301DEDDC5F8AAF
+:1027A0006C925F71F210A605AE8BA5D01CB3D74416
+:1027B0001FC6B4C85338D58AA834CC3D8CE944DF51
+:1027C000AAA928575F785C3F1AF9282A46A14F0723
+:1027D000D1677D8286F8B97EB1C98FF2C732C52430
+:1027E000329013961F5AD6B1024C8B9A316DF61A5D
+:1027F000995F0FFA809751BAC96B66FE6C2067AF7C
+:102800008DE0FA93F795A7433B23AB4433AA99E6AF
+:10281000518F2548D0BEF5E5969C5D76C6D6EDB0C5
+:10282000CFD7E542FF199EC53BA2014E638E05300E
+:102830007F1698233699B1253BDF76FAF287C29747
+:10284000339D4D2417C4F65CD4FF947637967E6E84
+:10285000D79821DFF74BE71198F7ADF1E1F41DC2EE
+:1028600025995FA75D470BB60BF99EF6107CFC4CD3
+:102870001ADF7F97A4737D0A8784EB66E5CBC6AC2D
+:10288000A0A78C80B9DC3AA9E10CEAF0A2D927A074
+:102890007C62D7E07B902B89582983E0DBC3014E13
+:1028A0004058626C7F96EBC7D8AFD5C5D8D900FA2F
+:1028B00049A851C35B619ECF660EE2A35BAAF18972
+:1028C0003006DD8F9D763BF4B3AD0AC60BF0563D66
+:1028D000D737947AA3348CF6F72FD3F87ECEAECDCB
+:1028E000B7A39EF4A53C9EE7BCFD8B3ECE447BEB9C
+:1028F0002AA589351EC105F2CD5AE9B4FBA09EAECA
+:1029000011E62384DEF28B3491BED71D7E4490A065
+:10291000DEA76912C189957E1A77520DB41B80BF5C
+:102920004DF40966C8B73DE613103F9BD96967F0BF
+:102930001D335A88FED7C83C616BF8CBA28F410F7C
+:10294000D3799D76ACA7BB13E8331F27D46366B851
+:102950004EC9E347B010EBA3A4863E0D73DC409F45
+:102960008F4A7DD443FBC5DD26290BE8FB85C5A630
+:102970008A1D21DAFB549E9F0D31EAFE2D5A3E1F1F
+:102980008ADCBE6CE6EBA8F0F19A68A692E36B5283
+:10299000C65B6F84AFB5CDC85C01F86E857ECCD0C8
+:1029A000BEE1AB55661C3FE8D04EEA4FE4F264C787
+:1029B0008F72C86E0A5EC721F408943FA208E9A38B
+:1029C000CFDF087C68A8D2DB516FB2FE4393807BD7
+:1029D00073226B1150BE5853CA7A44DCD74457AEA9
+:1029E00033843E7933BA54D64FD99F83D74B773D42
+:1029F000E3FD129CEF7FD531D4C7561F8F8F710531
+:102A0000D0534C3AA7CB62D6A245FE98CCDA29BD6A
+:102A100085F5527A1BEBA7D4C1CC22A6A5CC4E6972
+:102A20001973523A9D79282D672D94CE64ED94CE7A
+:102A300062BD94823D43A99399C9EE9A07FB37A6DC
+:102A40000B9893D2EF310FA599E99C7E2B580BC1BF
+:102A500077B3764A3B80EF243DFA018C9476829CD2
+:102A6000C3F44D9073987679252665A31F2087D2ED
+:102A7000235E3BA5C7BCC594F6781D54EF6D6F3936
+:102A8000A5EF789D949EF05650DAEB7551BD53DE5C
+:102A90001A4ADFF57A287DCFDB40E969AF8FD2DFB4
+:102AA000799B291DA5077EC6F9CDE92B447D3EF50E
+:102AB00023BD4302F9EC91E5D26187E699DCF1B8D8
+:102AC0006E1A66403A285B2320FD5973340E3FA4EA
+:102AD0009B72560BF742BAE104D7DF0CD648D20FEF
+:102AE000AD6DF58204ED76087DDA0858CBE9E9A9E9
+:102AF000738D209F4B3AD9BA083BC2194F1981EE0A
+:102B000076E83CFD3BA0BC64A734D7087BD6E4C87C
+:102B100053FFB18FC3543EE9086B34033C2B3DFB9C
+:102B2000A93881E381C2EF7B3B73E6AECD443C25FF
+:102B3000C2F3C534302C51BF7EC444FA7561DBD971
+:102B4000420DC0931A4C45681706D4EB42BA1FAE2B
+:102B50005E70B9F2DDB65596469C870D9F805A0E81
+:102B600059A9197D85ABF3D5ED6ABE5EFF4C7B8319
+:102B7000FE03EB0937686F7F96A3327DC2FF7E3A72
+:102B80000FA66FDDF58FF66BC80F648EC1FD74570D
+:102B9000349733FDA09FEE04BC77C5C8F0C64C1A2D
+:102BA00017CA435CB70D9BD2FD3E80778539571F0E
+:102BB000C7F27FD4D87742D1AE70D7A65C8233C932
+:102BC0003FB121C69313938FFA3CDF975A931F0DA1
+:102BD0009302F8BF399DCBAFADB75CE9DD81764498
+:102BE000B38665C1773B9B976FCC81767EBC19F429
+:102BF000078047DC5ABD310BCAD3376A266A65198C
+:102C00008778FC7873F59E4DA85F258F8EC98676F0
+:102C1000336479991ADB57B806E8BC55AFB6A79567
+:102C2000F49F647EA98666CE826C4D95EDF41D3AC4
+:102C30005611B8DFFD4CC6EF57593CD5DDCEFD57D8
+:102C40008691E1FE2760FC2523B9BFC3B2CE48FEC2
+:102C50000E4BF27F9DBC03CA2DDB347654E9446BE6
+:102C6000ED5A1DEAFB8B593BF2E30E817FEF4BE1FE
+:102C70007A21280AE97303ECF2ADDED38B3203FC30
+:102C800084B60A9F80F67BC9C85AA10FF79FE40754
+:102C900005B4FB2D152EC11589F68187CACF65B9FC
+:102CA0007E920EF8D92AE1FB40FD92B912705DA127
+:102CB000DF8A76D2F35851607FA7B3F83CAC073B6C
+:102CC00099F4D5757AC22B78BE4E65971EC0F695DD
+:102CD000750C2EFF7E06B7AB773D015D201F4CE2E1
+:102CE00076F389DD89A43FCE690D77A0FD74E2A952
+:102CF000D165046F99EC403DF2C4EEC9D3319DB368
+:102D00006526D53B21B01EB487E76CB95BC4FCD403
+:102D10000CC00BDB3BA3277A9CB3E541F9FB47CB07
+:102D2000B0BC58E3FB09DA91C58DFB22D04E9E1C46
+:102D3000F94A12A627347DF5DDD0FF5D66F62BDC5F
+:102D40009E9D1BE3FEB11CFE31F7A9741DEAD7BF9F
+:102D50004B4FA7F59CCF1CC4075083ECBA5BF6F62B
+:102D60001E064D8ADDD6DE3F15CC5CE6E8301FC17D
+:102D7000B4B4CB5E86D357D6E33C82E9F45E4F19F8
+:102D8000AA2FE5A75B8E60BA24D7F53B9C9F17FF5F
+:102D9000E17BAFBC08F0C8C7EBCDA807653ED137D3
+:102DA0006327F9EB740CF9216B92A7458B046C74C3
+:102DB000C6A07C78F6695183FBB921AD250C61C3AF
+:102DC0007DE91AB40B7745B7D4D0B8B3C219CEE3B6
+:102DD000DBB00F215D64453B63909F802F691D3EF2
+:102DE00093E9D310ED3147637E18CF1FA817CEE1CA
+:102DF000F303F55AC204EA274620FB13D406DCBFCE
+:102E00006DF2FEDDC63C09381FD648CF0EF4EB64E8
+:102E10009570FE67919C2EB07AD344FA849CCD962F
+:102E200016CF9DB80E5697E8EB0BA43BD80607F4D7
+:102E300091748219DAD75B050E839C21BCF0877EE2
+:102E40000C8BC9427A8D82BFB502DA0BD033701C6D
+:102E5000F34C83DF2974179BC1C73542A6BFAC650D
+:102E6000BC3D05DFB80C2E9F016F4983F868657C77
+:102E7000601C9A007C02EAD1F806F066761BD20547
+:102E8000487A81A74C1203C75FAD7184A15D647A53
+:102E9000F5FBE84F8942390278FE53F72423F269A3
+:102EA000F0387232D208DF46D087516F9FE9E2FCDA
+:102EB000DB58E911C83E4218C79F2C3AD01F68352D
+:102EC000AD167401E3B526F37D7A66A5A71BE5CAA6
+:102ED000CCE2083BD2F79DAC7D9D99F3F7914CC0B5
+:102EE0006F141BF899D8C441BDF0474FBF7B1297B0
+:102EF0003499B597E4E2FEF9F8FDB370FDB63E3AB9
+:102F0000B307F14FCC79AA3B061A745E94D77D19AA
+:102F1000F7EBA46C133F0E1C479207E040BF448DB3
+:102F2000BA1CE841052B7465131AA271BFD144E4A1
+:102F3000CF9C817A4A9486E43BC829614148FD339D
+:102F400088AEE4F957D6E7AE8C4C5A37AB89AF035D
+:102F5000EBB71B1746CA8355D609FA6D04361F0115
+:102F600074DF58A6F50B68D762FD28ACCFE29D91BF
+:102F700043D769874E9A3903E5F4C31AF36E367462
+:102F80005E81DC7E4B7AEDC371540EF9A291FC7D1B
+:102F900001F86A43C1EAF5B859FD6DAC6BEE8CB42B
+:102FA000A1F989C90B66E23E9B58CB68FD83CB47EC
+:102FB0003DA65E57B237C7A3FF88F9BBBEC17ACE24
+:102FC0004CDE5586FA7CF0BA2A74971A1B7A5F1089
+:102FD00033395FA646D84F95935E21929EE04C11FF
+:102FE000E303EDA20D197C1FBAFD3513ED43EC236D
+:102FF000A31FB75C7B57EF93B9B00EA5573468AEEB
+:10300000B0A3EF1CFAE14C48A7FDEADDD5FF0AF5B5
+:10301000A67D651A87F96FB0BE19E810F1F5809D9D
+:1030200001F0DA2FF6B4A0A3A4B192D971DF55FA5A
+:10303000D923F7F30B9DDF49F23557643B490E82E4
+:10304000651E402F0069897E78197356B690DD6839
+:10305000CDCC07598D6EBDF625B45FFE49CFD0EFBC
+:1030600038AF42D295C0F8E7554ABA65E8C7175954
+:1030700039EA11F32BEC943FBFD2CEF38D3C7F4164
+:103080008583F217543A78BE09F2613E1656F87BF2
+:10309000BDD0EE42538CA4413F78A593975F355045
+:1030A000F93B600F6402C98787F949DEB77CA6E166
+:1030B000F1124FB85F005C0D91453D12CEDF7D1AD5
+:1030C0007B162486149199017EB6C2E9D742F9F3A2
+:1030D000CC9F8013F946F56A6736E4BF912C9A714C
+:1030E0007C6F38C06EC6F9AB1569DEE907F01B3599
+:1030F000C914CFD821FBAD7D2B8CE467055D87FC1F
+:10310000AC6C45A2ACC7F0F26DCBCD7ED4C7400EFF
+:10311000D23AF6DF27921E00F2F0ED1CD48B5ECA85
+:10312000B4874948B76A7EB3542F2FA1F62A99195C
+:10313000EDF25995BCBDC697347E0DEA55A679339C
+:10314000910E1AF7323BDAAFCF569F2A8B45789B08
+:10315000DDCEE5875A2E34566F392EE1783C1A734E
+:1031600016D5E77EAD464FE92EAD30C8CFB4DED2DE
+:10317000A0FC182A6FEC3DD84E4255A97D13D4B35C
+:10318000C038D18FBD4DCFF37DF7881467B0548B15
+:103190005DE68241FE4E91A7D0827C1845F245C57E
+:1031A0005FA35F52C33F92F914F85DC471F97631A1
+:1031B0003BC9955DEA7A20273528AF52DAD4F96702
+:1031C000B204C52FA59A87E079B67AB8DC0B1EE762
+:1031D000E0B8BAC246D1B8347C5C28D7203FD77457
+:1031E00088F2732B45BB24A1BC6B3F85E31FF5928E
+:1031F000C8BA009E555D3413E969D6660DB94366B9
+:10320000B35E920B371BB7E2DF081E67F0F8366437
+:103210006869DF1CD007D71B491F6C7DC4A4C1B8E7
+:1032200022E85BE1E8573897551A9E09F33022539C
+:10323000D6D7AF6BB93C6934119DEAAC8FE504FA7F
+:103240001F84D1A523B0BEEE7AECBC728A1BE9685C
+:10325000DCC172AC58966393FA607C2AFF73389392
+:1032600002E6F7D6FE18157CFBD54455FD12102E4C
+:1032700081E5538D79AAF269E6712AF80EDB1455BF
+:10328000FD19D254157C67CE9DAAFAB3EDF355F023
+:103290005DC54B54F5E73AEE5595CF2F7F4855BEA7
+:1032A000D0B946052FAAF87B55FDC5AE4655F99213
+:1032B0009A2755E5C1F693929666723FCF569BE7E3
+:1032C000A483E48B4B70460EAD67A914FB03D73D76
+:1032D0002A82EB53C1F51AE5F57841E0FDB1FE48CD
+:1032E0000DF29DE27F63ED912AFF5CD7E4C9C63EF3
+:1032F00013FA72ECEF23DDB213DC1FC5FCFC3BC5F7
+:103300007FD5FD04D483F65647A65B71BF43BFABA0
+:103310004B0FFDF935E4BFB736D70BB40F6EAEE7F0
+:103320007E95AB7AE68A0DC08385F37EE5788E8242
+:1033300027734470FF6018CFDF26FB959E43BF5272
+:1033400036633FB0287E7817B59B50ACF7A17F4617
+:10335000A8F6087A945B2E66364828079753FF979D
+:103360002BEC2358887956D256AF8D39A07D5BBDA2
+:103370006FAD1EC656973969CBB3D0BCCDC3C81F3D
+:10338000F368E6942D6B81E7FF2153A2754910F98C
+:103390003C3F5FF7C6B93DD05F6B95A508E56A7005
+:1033A0007992BBF3E2B11B943FBFF2D50FEEBFD1D0
+:1033B000F7751D679A02CA87F58B56243247001DA0
+:1033C0004886D07EF91FC874E59EAC273FD6335A95
+:1033D000D793C8CF1726FFD7C4BDF0DD79E9CA3D22
+:1033E000A8A743FE0F301FEAD1BC9ECFBC44E729FB
+:1033F00052F340BF47FD3B2C34DD1E94DB17AD95E7
+:10340000FDE8075A1DA997D0CE4F327E467EEA0EC0
+:103410001DB7AB83EDF7E707ECED76B2BFF7CBED69
+:10342000EC9653AD997FCF8C3E265AE4F84088F94C
+:10343000D046B50928AF12ABC54F02F9A23B524F97
+:103440007E048B49F63B986A547E01C56FD01D7986
+:10345000BF80746FE95A417E7AF417607B07E57587
+:1034600009F6172419FFB4E8E3D81BB5CF06F223F9
+:103470008410FD04E1A1F82782FBF1A33E81FBCC7F
+:10348000CA70D22782C77D39B3E450663CF248FF48
+:10349000C93B507E9FD2D17E381CBD8449E1CC1FF0
+:1034A000D07E6F26B7EF23726254F991F644E60F8F
+:1034B000F45FB364F32711320C5BCC487DDFC65157
+:1034C000D8DFDBBCBF133ABB8DF441D8F6D0FE7B0E
+:1034D0004FE6E7EE5C4669AB6C97B7011F63FA9C59
+:1034E000D74CFAD936E03F84B77B254AFDDE1C4A2B
+:1034F000777AED54BECB5B4CF01EAF83E0BDDE723D
+:103500004AF7799D94FF92B782E09F7A5D94B67BEB
+:103510006B28FF15AF87E003DE06825F457D5044D0
+:103520003F7533A56F785BA8BCD3DB46F09B5E3F4D
+:10353000A55DDEBD947FC8DB4EF0116F07C1C7BC2F
+:103540005D04F7787B287DDBDB4BF9EF784F13DCEC
+:103550002B8F93B1E65E2FFA2B5CA284FADDB3AE1B
+:103560006A33EAD7B6651A338AF336976605FA39AD
+:10357000B655F2789F6D9586FC40A087FA519FB3AF
+:103580002D7BFAF8342A5F40E55BB149304AACAB99
+:10359000B8FECA56EAA99E150F02C177DB6A2BFD59
+:1035A0005A805BB2C3A9DCBA4A24BBED798D273AB5
+:1035B0009BEB5D24BFAD3AAE3F28741021FBE9229E
+:1035C000B2444A976573FCA33242EF2319594AFC6F
+:1035D000A4B907C767AB82F121BE55F5468C5F5A87
+:1035E000EF83F149A43FAE3A047824C378117FC039
+:1035F00087FCC26C19D797AD55EB08AFE465F3941F
+:10360000786734DAE96D9EFAB9846FA5487ECD36C5
+:10361000D7A1E8FB504ECAE77CACF1E14E7FFE50EB
+:103620007C3282F0DFC6B8DD900CFAD2FE10E300E7
+:103630008B47A9C7FD788F1943FAF126CB7A62B27E
+:10364000C0F98F3D2C12FF6D67A0F7C177CF817E47
+:10365000E7433950BA6F15FAAB1ECD724DCC023C20
+:103660007E248D3F24021C53CEDB4FAF17F7A01EE4
+:103670000DEB7DAE09F2373EB8D989B671EC6669BB
+:103680002DB25BDBB25713D0FF952CA8D74749CB9F
+:10369000653CB63B787BCFD58BE44FB6AE3A90769F
+:1036A00084F75B86FD268EFA7D18BA613216481AB9
+:1036B0001419C955E245EC2FECA1CDE5D85FFC66A5
+:1036C00087D25F21F6F775E769E4E365565708BCD2
+:1036D0008693273793238BB322E3488E24B1249417
+:1036E00023CFEBB8DCF29DE4FA241D869934B41F95
+:1036F000257EAEC4D383E3E835323D241942C76149
+:10370000570DE8FD3EAAB7DDB1C949E74B303E0B86
+:1037100045AB756C05AEF3EA9270F3DA10F4A0A431
+:103720005B508E01DFDF8B4623B5B3B99CB7A3E1B5
+:10373000EDDCCA56115C6232FB42C86B257D5A6EC5
+:10374000E7812C4EB7490FBEB4F118AEEFDB3A3A21
+:1037500013F49CC6BF11ED04DF092DC9D7446DFBDE
+:103760008E3D017835CBE3794EEFCFB523FF407B1B
+:10377000F92857915FF2C97FC16605CCBBF2DD5ACB
+:10378000D98FFDA36B1BA229BE5CB52E0CF5A33609
+:1037900066247AB0EA3CD18501F46045BA0C411F39
+:1037A000FBB2F44A3CD5543211E3327C5F9E8A72FC
+:1037B00009F03E581D45FBE1D465EFDE3916E05BAC
+:1037C000AE8876D4CB9EABE5E71327FD5143E726C1
+:1037D000DE7C9CDB7DB7FDB7B21EF47B27C8E9B366
+:1037E00068E7417A4B33B377C1BADC526D22FFCD23
+:1037F000AD57C5B381761AB9A4C7A37DC1FD3553B2
+:10380000FAA13C80FE267DA6AE0F33AA453D23A13A
+:103810004F9D6FAB3A70661AF4D356CB3F6EBBF632
+:10382000FE71847DF51AF29300F529F49340FE4D64
+:10383000D19780E716371A19C973EB32A319E541FE
+:10384000B7259CE45FDB6213E9A11B325787A19E79
+:103850006CA8AA8FC674A4DEB7037DA7DDBBFF7D6D
+:103860009E2D81E42D3F7F8184590CFAC0BD7AAE34
+:10387000E4F8FAB64CCB4479A9A1F2C3BBFF7D8B27
+:103880000F7D07AC85F090342C910F7E00BE9BE23B
+:10389000D402DF2F40674E44F874AEAB07E54342D5
+:1038A0009CAF1B8BB69ACE56D2F9E2CA38E2335D92
+:1038B000B587E931BFB2C818C8E70A9FFCB5FCFF5D
+:1038C000B41CE7BB991CB859BB37E3F79FA573BE7F
+:1038D00019CE9E360C234F15FB18CF9A638A6C4B7A
+:1038E000FBEA597D48FDEAF66CCE67C57A7E3E64F8
+:1038F0004EC5F4728AC3F8FA443CC79693CDF9A931
+:10390000CD124971E2B674D6857103DF720DF7F7F7
+:10391000C4F1FFDA2AD3C93FD42A78A27D19783EB0
+:10392000C29586EBD706731409FDB7A672B9CEFC13
+:103930001E33C6ABA19D9A40FCC1DEF3A9E9989164
+:103940003E4CFE0B2DF19EA40FF0B7A35F1CFD179C
+:10395000C1DFDDDAAF866FBFAA864B984E054F35C3
+:10396000AAE16966356CC9E67AFA1D3675FE0C491E
+:103970000D27A71C09D3F073EDA6017FB344F0BB5C
+:1039800099017EA00D9A7601E725A5AF96FCB2AD10
+:10399000A9DCDF935CAFF67324B296B53102F96D02
+:1039A00054F9B6FC5502FA736CD5EA7C9807158C6D
+:1039B000CB8AF4BF24D7959F8D71E9027EEE3A4BF6
+:1039C000EBE9CDC575688B233E4A93CF050DDD1F0E
+:1039D000B7D0B89576900F7C01E345FA0F842FE6B7
+:1039E000BA2667C7733EF005EE97F97D3AE403A562
+:1039F000BFE1F841E1C762396EA29CABB922B7A51D
+:103A00009CABA997CFC775049DC7B9925C46E78167
+:103A1000AEF4AE090FC577C867BE6CCE77986E94CA
+:103A2000CFD720DFF9F49CEF30DFF0D52A6728FDEF
+:103A3000F0BCBCAF3CB437CCFC71C0F856B647AB59
+:103A40006077478239F0BCD343F80F74BA37333A02
+:103A5000475A2B0FE78B33BFDBD308E95B5A970B31
+:103A6000D76765D6593D8F33F5EB51FE9E97F7DF4B
+:103A70000D82DD385AC094DBA58D66BB11FDBDCC2F
+:103A80009FA1F257287E87D52BD2AC3180FF8801C9
+:103A90003F82D34CE74DE333C98F1135D571372BB6
+:103AA000043CF7CC986F04A2DC854E5590C78F6517
+:103AB00097FDD0973C385E03FAAB02CE2319440F32
+:103AC00023B97335954901E7CA5B65FFC5001F9BA4
+:103AD0009697607F3FCC96783C8679D672FF9FDAC6
+:103AE0005F66B86A53B533D87EB2AADF56D92F7253
+:103AF000F3F6D5FE37C3D5F461DACF0E6ADF1CB218
+:103B0000FDC176D57EBCAF111F6F433E18CEFFB509
+:103B10005F96A71B6C9E5EF47FE918D89514070684
+:103B2000FA98886A23FF69C3F979535DB2DA0FA660
+:103B3000637E921FCF47D690FC48603E8ADF59983B
+:103B400087F2D7474DE7F1BB60B9711379C1988708
+:103B5000A1DE00FDA9F2573FC2F7D346C1EE423CB9
+:103B600083C7F3FF8ADDAB891CDF4BFA734AB86465
+:103B7000B881DEDBEA7525E3F71BC23D3518EBFEA5
+:103B80003CBB2E763DE83D1B30C6087C7635BB71CC
+:103B9000BECF84FB24A78FF5711AA227CBDD961D1B
+:103BA000DA007AB2E85D69A8F75A34F2392FFCA13D
+:103BB000BF6CBD65E7A610FD2BFA9B025B2B008F47
+:103BC00000BA6D95F5E681FE9624EED006B4633119
+:103BD000B80AA93FE55CA3D25FD337EB6FABECF734
+:103BE00052FAB3DEA31E9F55EFA1F159E5FD47E957
+:103BF0006F2B8E2F045FDDB43FD98E1EE86FA97A3C
+:103C00007C568387C667D572FFE1407F4DDFACBF2E
+:103C100036F91E934DE6D3E1CEFD370E9CAB761AF6
+:103C200051AEB429FE40797FBB14B4BFAD96F737CF
+:103C3000E5FB4B71E9E4DFBDD433DF186A5FC3FDF8
+:103C40008CC97A2493F54826EB9108CF997AA63E41
+:103C50001EE8B0F0C5B6F922ECE3731E3A333E1508
+:103C6000E0192FF6CF17615F9AF3E2990349F0C983
+:103C7000CB2FBECCCB7F78E64A32949B7CEFCD2F06
+:103C800003382A96EFC70ADE4ABFB78DE27AA3BB94
+:103C9000E173EEBF04F98AFB5663AA87A17FF14264
+:103CA000727FD432A8EF4EE9B72C0F312F4AEA6E5B
+:103CB000384F7E46147928FFE6E1BF40B4CF53EE7B
+:103CC0006794ABEF6744456D22FD2F8CF9CD28EF4B
+:103CD000228C0EBA4FF8D628BE1F2C64F60A6E3717
+:103CE0004859F2390DBACF31BF586ED77CCBCFB11E
+:103CF0007CA1C6B11EEDD9DF4EAA8A47F558391707
+:103D00009737787F72D7F51B9C1F0EBE3F39E7238C
+:103D100081EBC223B8BFA53B57E2F7B902FC86A8E6
+:103D2000F70E379FB5A3B87D3F389F0E3E9F310EEB
+:103D30003E9FE6FEA8B5B0FEEEE87ECB13C49F5DC5
+:103D400021E76BC8BC06CD5FFD28A6D8795AA4B779
+:103D50009BCDB732AFCAF9C14641CAA2FDEA4F793D
+:103D60002AFD8331BB142A8E83F419B8BFEA6D4E45
+:103D700086FE195D9C3D07CF9537FE451BF25CDE44
+:103D80006E793ED64685D3B9CEC6283DD9DBDD5106
+:103D90003319FA9745D3749A97B2A8723A6FA98DDE
+:103DA00065ED688F069F23D78EB89BCE0169AD68FD
+:103DB00041403A702ED961A4F889B9E886E7C8C5B0
+:103DC0009B9D238F99C9CF9147E9257459B445EA42
+:103DD000439E237F6C14DFF7BB713C71883F8C27B7
+:103DE0006D701CA299C7D1313F02F2F56617237F8F
+:103DF000BA3CDEC7E47550EA1BCC1E86F240ABB776
+:103E00004BA8A768C3F93E61B069584E08BFC8F710
+:103E100047E9E8FB4F72CD34AF1A23D7CBE7FC5A02
+:103E200008E94F7A7594E24F0A4D67C3D1C93C0D3A
+:103E30003F47A7F0E102939ECEF72D30D94AD10F2C
+:103E4000B20008EFB39880FAB72DE2F78145BB0DB9
+:103E5000E9E737536EFFF96F18BAF9B97C3E35437D
+:103E600047F7E34E09CC618F197A7ED5E98C9E869F
+:103E70006E9ABB669D5987ECF7E2F2EF15617B867F
+:103E8000E353751689EC9F7746A15CA84E5B1F0F24
+:103E9000F0A2CA421DDDDF94E344EE082EC79FD195
+:103EA000BA4E8EA278D1E751A54847627F2AE2A395
+:103EB000C48902EABD372A9EEACDE1D7C5A0DE1843
+:103EC00094D3677FEF62B41EB6507A12DA4F2C306B
+:103ED0006E23CB07B4A302F3D17E6201EB272C2F14
+:103EE000B6F68590174A9A60DB92520D7C9E90D070
+:103EF00042A992FFAC435BEE0FB1AE57E575FDC62C
+:103F0000764C1B603B71D08E01FBE52ACEDB17D5CA
+:103F1000A72CE36148756517C98EB1E9153E9388F2
+:103F2000BF06611EAF04FB4575DEB0D5EB4BA1FBB0
+:103F3000FEF2386D2BD646A31D03551C489FDBBCF3
+:103F40006D29659983E3C8CE91E9138DB689A817C9
+:103F5000F35F725CCB0CF497249B34743E012653C0
+:103F6000752F616E59F4B4383445DDCC6E92D02E85
+:103F7000EF253D3FE1BA96F820E1F0628671ABA4EF
+:103F8000B87601EF030DF423DF6FAE97E3B9575C0A
+:103F900065348E04EBC0FECEC80E8DF3CD4579742A
+:103FA000E5698E51C28FD5E5C971FCDCC2FDD5E152
+:103FB0007E09E83AA9B6574038010C38F4C5275CA9
+:103FC0006F4C6B4279F25A04F98BB56D99CC07F2BC
+:103FD00027557445E5E03CFBA5FFA6C990070BDF1C
+:103FE000AD7C209CF4B336A16506D925F769582825
+:103FF0003FCF981CEEC728C8E1FC9F606B4DA91EFF
+:1040000087E9D344375F97CF6790B31DF4D9119FE9
+:104010002DFA581CD47B9A75A1E9739BDCEFC07E06
+:1040200021CF5F187319917FB582933B39F7EEDB8F
+:10403000B7CF82CE1346E75536C97A8DD24E444E5D
+:104040003B1546D81D0CCF450A6607DF07CC3E9BC3
+:104050000FD6ABF92B6D487BEBC11C791F496BB2B6
+:1040600061FDB24CBB0DFD94C1F7551AD326DA7031
+:104070007D1A670CD0A931705FE84ECB7E1FCF53FD
+:10408000997A742CF01C5970AAC77321B1372897FC
+:10409000CF97371DE2E7429B4C45BD780EA1C9146E
+:1040A0005744C7FE4CFC9CA952DF643A46F2DE64DA
+:1040B000E7F15613EE0F02A2C7E7A13BED18CD833F
+:1040C000526F5A0E97AB267B17C3FB5BE1763FD549
+:1040D0000B139D3E0DE01F16C7E8FE4F9891F35558
+:1040E00004AC8F3180EF957E6FCBD1D1BC352517D5
+:1040F000F596107E22DE04674DB6221BEDDB38DF1D
+:10410000D06F63B442DF9CAF1F97E75B69A7513E56
+:10411000FF7A4F43CEFCB258F41339D7E460BBA604
+:10412000E546B483B491E36FD8DE8661DB6B5E282D
+:10413000B7F738F28536B2C88CEDE9505E84A0C37B
+:1041400067E476FE57E3ED30B374DF97605A309F33
+:104150002D94DEA3A4468CA38F1BFADD3796BFEB0C
+:10416000D47E2490BF7B71FC2B93CF1E2BA11CEE21
+:104170003FDA2EDB278A9D6191DBDE2EF07BE83E65
+:1041800021DC4EEF36C87687254C3D0F83F741F989
+:104190003A5CAEE0E7E62EC7318A6B04F3F3E577CD
+:1041A0003E8A0EB44F50EF736473BB0453B44B1C80
+:1041B000B29F0D61F41BA09DA2F0FD805FB742FA93
+:1041C000A75B003F03C86F0DB42B247B88BE0DC9CD
+:1041D0007D69C8E7A9F23B0543F6D75C2EA7854762
+:1041E0003F4B43FE2E8BEB4FC0EF82F9FC8547AE71
+:1041F00026E0785E983170CE86E243AB17A7F37B5A
+:10420000D9C7FF1CED0AD1FECDEE7F459DDDB486FA
+:10421000F4C0E55C0FFC5BDF07DBBE8CEB9D1D8211
+:10422000DAEFA4CDE57AE75FE47DCC7A55A4F72DEB
+:10423000CE65B92E201FB60AE6E5287F531FE1E7B9
+:10424000E6563F5EFFD90321F84118EDFA734E8020
+:104250003D5CDCAC273F5AA3297DC48DE21CC3AF73
+:10426000B387CB71797D4B1E35F2F3242EAE175BED
+:104270005CF7D33995E0F323C3D53B24CB3DA5BEF2
+:1042800001DB4779629A47FE804B6823A0BF4D96B9
+:104290007BC17876E264C8F36304B9127568451887
+:1042A000B6AB93EDB1ED8A3FA3A2C8E808F85EB7BC
+:1042B000B8C8581A402F8D8C9FDF0D6EFFCEDC01E1
+:1042C0007D5AA5AFE8709F45DF509CF8A7013943A0
+:1042D0008A65B8CA8E51FA0F3E3F16705E2C8CF379
+:1042E00029B7675AF1DC18E8B76B2B968FC4F96DC4
+:1042F000155D2F58611EFA3F30D039E70F65BEECCF
+:1043000093F972B8F5F3B143A08C31F6043B829770
+:10431000D6804EC68F40FE68CCD494FB438CB35CF1
+:104320001E6708FDFAD6DCAFA75F97E686D0AF51CF
+:104330007F7604C51F0261D49B1D21F4EB1382EC30
+:104340000F90CFED9CD0491D7D300F276E1D616F02
+:1043500094E89E91C35E04F6C38B6732516F9F232E
+:104360000CBCC723DB318C60B02316225E739967C7
+:10437000DF0302C5515AEE48A3EE045C8F9BADA744
+:1043800024FB1137C23A61DCA1F5DAB219A1E20CC3
+:10439000FF38402728BA02EF07C02A04C49586C414
+:1043A000CB82E263184E1938FFAB1D5AFFAE62751F
+:1043B000FC6AE335EEBF30AC60FE27043C1FAA2E3A
+:1043C0009F5FAE0B8ECFA9E25A0B9DBA607C7C88B2
+:1043D0006FB28C6FCAB607290E3E2D45E4FDAC6462
+:1043E00064CF07C7BD0C85BD0E2DEAC3158CF4F74D
+:1043F000603F369E1725FF5E0563CF0974DE5A7D48
+:10440000DFE4E959E7F8FB1C2DE5D88F2D53C350A5
+:104410003F0EBEAFA0C49BF0984CE07D69E5DD2265
+:10442000CB620DE1C77CB753B9E29787FAA6124B6E
+:10443000C0B9EE556CA03EDDA3F2851EF7D6D65965
+:1044400014EF4F1CEF29EC82A2243BA37948AA6603
+:104450006407C03CA8E2FA86945D34CE4B358CC527
+:10446000F238A0AA3C017670A44F18BF2ACE0FE301
+:1044700054C1C176E7CDEC4D434AE60DE5F9CDFCDC
+:104480008D06395EF8466E641CE93B63D818D47714
+:104490002C8B9FA6F5B804EB817E59348442C5036A
+:1044A0003743FB6807BA905FE2D1DFC454EFCA30EC
+:1044B0008748F7C984628EB310EBE4F1E17C46FCD7
+:1044C0006D0807950BF859986C70E0BC1B0C00C385
+:1044D00090053D332640BE56F637AF1598883033E9
+:1044E000DB8DDC4FA8BC6BE3A7776D86EB0774FF11
+:1044F000BE30ECCFC7BF53FA19F28EDB0DBE27FBDF
+:10450000CD1CFC7D19F91D95FE879BFFE1DE6DFB3F
+:10451000C3D4772770BF6732D16BE520BD12BC4C86
+:10452000A647FC1EE5C2BD4AB1AD770CDE373CFBA9
+:1045300070841DFDE003E3F0DDA9E5EFD1FD75ED2D
+:104540000DE0619348BE0F8C4B6EEFAF1D17FD025F
+:10455000E4DA06BC3484E74F2A199D27B0B84ACF65
+:1045600089740E00C6A0921301EF13407B1B0EF15D
+:1045700073AF5BF19D0B71B05FD42BD06EB0554221
+:104580007E083B4849AB19BF1FACE0D5A8073D1AD0
+:10459000E952C3F5E8D9A63E11CF35E9E2FA45E480
+:1045A0001FE7682EC707E8379ED1F90B6D927CCEC6
+:1045B00071A4C4DF4DCBE4FB9BD2CF84D11A59FE4A
+:1045C000F7D2FB47B3234ED54B76C6F2F6C52F4440
+:1045D000FFFCEC11A7EAD3002ED867E170D2A92B1B
+:1045E0006966C6ECFBAC0BD19F3F3BEFD495748062
+:1045F0008BF6D978F9144646CEF87D090BD19F3158
+:1046000061B459D5FE5B38D7F1DF3CD51A3421CFE0
+:1046100063DF365A394FC9E83EADB3F397A7312E61
+:10462000E954F647872E48DF81220BDE23937F7102
+:1046300051140F9D29D3D99DF8EE5214FA2DBB6861
+:104640007E470DFAE99FFE6BFCF482437997CACC52
+:104650002A81FF1B1B982B2C2380EE9943739D9F6F
+:1046600003A6B881828FD2FF10BC6069C59840BC98
+:10467000B6513B0A5E170A0DA48705C7872E08FDB1
+:10468000DBF19C54C4CFD62FC275BA10D99F2A0033
+:104690001C9EB79ED6ED427CFF76C11E00EBF83A19
+:1046A00056EF2BA275FCA3D6513D7A02BEDBC5DFC7
+:1046B0006F6896E3504FC6BB7C689F01DDD1B9326D
+:1046C0005F8A9EFC4865E30547A03FB06E34F7CB98
+:1046D0005C92D3698616CF49A04BF70181AD85FA6C
+:1046E000EE6B97F5A89FCCEE3CA3473DBAEEC01900
+:1046F0003DDE4BAD4318DAA9DBA67784D2FFFE324C
+:104700005AABF2972976D7D194ECF5E877ABAB1694
+:10471000E81EDEEAD7B91F6EF5321C256377DFB2DB
+:104720009FFCB855CEEEF5982E657D47F1DD88C526
+:104730002EADEADCC0929A08553CBECA13AB8297F4
+:10474000B6C0EAC03EBBB42149F51DC35DCF82EFC0
+:10475000280EFED0FEAF90D771B16D732FFABB1645
+:10476000BBD47ACCECCEB5620CE2ED11EC1ACEFEE5
+:10477000127EB7848F10D200BD0AE67D5A07D7A3F8
+:10478000EA2A8C649F54220CF35A59ABF5E39373D5
+:104790004753F454EEEE10A8DC2D97BB6B046E5714
+:1047A000CBF275A98CE3928327A7D175529FA337CB
+:1047B0003300DFA515E5E7881E657D43195785C4DD
+:1047C000F58D0D29EFE9B0DDA5DF17586C1A8D4B7B
+:1047D000A5472DA951C3551E5D909ED5A743F9BD90
+:1047E000B4419DFFF3D1F2BE9EC7F2909FDE182D1B
+:1047F000889F1807E13FA5BC7702EF815DD23A0F91
+:10480000227DD6EABB0A70DFBBA47511AC94437E4F
+:104810001DDFAFB8BEA201CEC3EF1B750E33DEA7FE
+:10482000F5AD14886E97B000BD276DB03EC1DAA11A
+:1048300070BF2277C39CF5E40F3D2898516F281371
+:104840001D22DE836F1CC68F7E51E68313AC2F1FA3
+:10485000F1CA46228575CA9E3F82F699ECB796F951
+:10486000308E943D4E20BFC49D80714311A622C955
+:104870009139B03784419AAD6DAF20F93E566FE65D
+:10488000EF62DA58A0BC70FC331370BE1075B20B27
+:10489000937BE8FDBD396D9B2FA25CCCCC70143DA1
+:1048A00005F83D19C6FB7FF275C1BF16DAA9CB3FEB
+:1048B00046F2D30AE481FDD6D96439DAA1F6CF5A9B
+:1048C00051AE21C1CCCAA77E1394F832D015EDC3E6
+:1048D0005DA5A49F58E57E9F2D94B8DDFCA07C2E9D
+:1048E0008DF9D6E2F9FABED18CF295F41BFBABCA76
+:1048F0000431285E50371AE679A5AD4F75DEE95BC5
+:104900006CBF01E92CB87D18BE2A5E394D7B2D8A1B
+:10491000EE771DCCB0DEE8FE94D6A83EB7A4338770
+:1049200007DDBB53CB9FD9F6A4A07B771941F7EEE7
+:10493000F282EEDDA9EFF92D744E09BA77A7BEE732
+:1049400067B0CD54D50F93E6A9E0889CBB55F523FD
+:10495000EDCBD5E7AE8EFFBC4248C777067D7D2EF6
+:10496000988766E08DE298C17D242F0A2A431A3E7B
+:104970002ECC846973A1A10BE9A43991DBE786E30E
+:104980000FDBBAA01DE388978CE86FFC89E02F4508
+:10499000FBC4289F5319FD1853ED33AF1570BE5259
+:1049A000D2DBF25CB3F3617DF2F74A49FC1DE0DE35
+:1049B000D1B83E467C6C03F9E6557EAF78AC6C47C7
+:1049C00028ED3C5F5832350FBECF7FCC3183E2EC0F
+:1049D0001DFC7EF04E3D8FA7F85EE5E75BF33BFAEA
+:1049E000348E00FE3E99C7F590679CA5141FA9EB75
+:1049F000845D16F9A9EDAC1EEF65D4757647E17EAE
+:104A000056E03CAB47BFC960BEBCCF89FDE168AF93
+:104A1000FFAC3D743C6D6D9E9EF8E3982CD7AB1EA9
+:104A2000D672BB913966E1B971455E57EDE7E3ABEC
+:104A30005AA8E7E760311A1D426E839C3EAB96C3CD
+:104A40000EF57E708B7F3DCA0E90DFAA7A4B174C15
+:104A500027BBB712E436F231C87375797213C917E0
+:104A600090E7AA7C77DE803CCFBF0EDF9D766A425E
+:104A70008EF3708148F378DA3595E6FF199847F49C
+:104A8000A73D3364DEF87CDE6CBE5EC6B50F58B75A
+:104A9000E07ABF2EE0EBF6F230F2FA7D795D770A2C
+:104AA000BD45284CDDCE70A2DB254663099E7B38D0
+:104AB00096F26513C6E1AA7E2ED03DFD7FEB3E6ED9
+:104AC00041FD5FBFFFA805FD61EEF6A316B04D598D
+:104AD000AD4E5A8B7A3CD0851DF59EBA8E2EC27F84
+:104AE00065FBB86ECC5FD921D0FB3DEE0317A7D391
+:104AF00038595F13C60B770E83D78FF2B8FEBE37D7
+:104B00004FE27E3017F489FBFD0183DF2F201D80EB
+:104B10005C42BC5E17F0E535B673A3B122941EF576
+:104B20006FF27C1FD9A867E8AFAF85EF711CC75241
+:104B30008EE98D4847FB05B2B5DDED27174660FBD2
+:104B4000F53A86FA8582DF1729BD1FE2F83FA8D61D
+:104B5000A1A78035566B69BE3FA8D7523BDAFB74DC
+:104B6000042F5EC1CF551CAEFEA82909DAFDA05660
+:104B7000A07B0C53EFFBF3318417AFE0FA5A303DC2
+:104B80002BF41A4C9FC1F43B844E6BBE199D1EC979
+:104B900093EFD5E4B102DCE761DDA759917E1EE118
+:104BA000F7E32BAE1DD6A17F33BDC96C7F02E03188
+:104BB0005AFF7A0BCA89C3BCBCB07687C0E58D7436
+:104BC00037F26152B39EA1BDFB7E1E974BEFE37A95
+:104BD000C5E3D0FA058CAF31B1371DE5529A1C4FB1
+:104BE0007A45C72AF6535C90CB9B31AFD954EF96E8
+:104BF00037E571BD43918340E6AEFDE4976D4FC448
+:104C00007B142FCBE74153E5F6B232FAA7CF85F4F8
+:104C1000AA4C2F67643C14F8B24CFF6CDBCF681FC2
+:104C20009F2DC759663674D179CC3C83EB5394875A
+:104C3000B352DFABC57DAE39FDED7C3A678D3725CC
+:104C400026E2FBC9FC7778D2A7DBD660DC2F379C45
+:104C5000D631ECE053741E382C6BBC35549C434960
+:104C6000DD57257A8FB0EE6A3AA50A3CF7D0397D38
+:104C70001FD90117A7139F5CB5A9DE2DFC54C67B75
+:104C80008CF23E5D27F7F3809C168B8B06EB29F3A5
+:104C9000809E651C6F58D62E5AAF35AB5821A9752A
+:104CA000EC29FECE66ED4901DFBD58A473E84C3017
+:104CB000DFEF8D60251F8BFC1D245736C64D8C748D
+:104CC0002FFB84D74C70AFD746F029AF44E9AD61D4
+:104CD000CE887C6867E1114F16CEDBE1945627DE63
+:104CE00057BCF08E4EA66B33BF2F2ED3DAE54E2D78
+:104CF00033629CEB00E8E3C220FEF75C4DA4FBDDD1
+:104D0000BFC3FEA09F950DBF217967AFB9381DEDD8
+:104D1000A2C2DA334D08BB1BFE3C1DF5890F61FFB3
+:104D200020BD1EF47B9B8072E424BDD35D79358663
+:104D3000DA7959D33F1DF9CBF7A640F76F3EECB8AF
+:104D4000A8B7F2FD89DC73782F1CFDF2B3F2A3B98A
+:104D50001CE92CD4D0FA3A24D53BEBDDA3FF2B0A77
+:104D6000D7C3D820FD7A0A7EDFA365C8BF9B4AFB64
+:104D7000A3CC21E4EF69F4DF65F371B0ECA1E51594
+:104D80007A5F169E93AC90E938B8BC3C7FC03FA1D7
+:104D900073CAEFEB0801FEA12AC6DF3F05BBA72BB4
+:104DA0001CF8B8AA732AF967AA3CC20DFD33C3D117
+:104DB000E1D74DEB18F7CF2830DA8D817E4DB41B4B
+:104DC00099AA7F1F7F072B25F386F774DC7D891452
+:104DD000CFAF6B6614EF5A797534A5E75FDF2021FA
+:104DE000FF18C3FB5BE97E6BB686EC8C953EB5FE87
+:104DF00033A580CB8529057CDE5CF9602FE5B00109
+:104E00007B09ECA27BF3B95D147588A9ECA5E07C65
+:104E1000B2978CF23D1D1013AE5742E07D474169B9
+:104E20000D7E97CA5A88CED93BFCFE72F038D7E483
+:104E3000733E55F87A31F235D26F07E7EBE076E74B
+:104E40001594AC413EDA384C7CAB5CE6FB956D8C3E
+:104E5000E6CBDD1643F3F4056B7396025D7E0178B5
+:104E6000E03DD20B4E6744347C7FC1E58CC0F33DFE
+:104E70008A1CA86B0BA7EF3666CE8BC573A3CD48F3
+:104E8000F7D0DEF98EA9469CE77BDA38FF29FD7D55
+:104E9000D8B53816F96982AE5F6F87F2E4CE335128
+:104EA000A8F74D787D7E2CF2E17078FEFD1819CFC1
+:104EB00086C4121E9787BD70A26C4F007EEE27BA83
+:104EC000E89DFA871A18D16FF7ABFF56877C7CBE36
+:104ED00033C28CFBE6170723E8BDCA0B6F1AE83D07
+:104EE0009A5AF97DD52F747D7348BF7C5D4BF722AC
+:104EF000DD6FFE472BF2A3FB55039D3B7CA873C3DC
+:104F000045DCF76A3B679CC377566B5FFADBF2C3FD
+:104F1000CA8654D28B14F83FBC4627BEF37B5EE4AE
+:104F200072E2A18E7F217DF7A16B970BF07CCA17EF
+:104F300007FFC744946BEEB72E4F4479E6FEC5E5F4
+:104F40008958EE7E2DC2134A5FB95EC0FD3ECA7E0F
+:104F500099F6AEA8F20FAD90E9236D5D0BBD073D4C
+:104F6000E1E4027BE0BB0F13B2344EAC3FE1B76526
+:104F7000B1F7057CB7AE57A438E3F8936511D501B6
+:104F800074794F814EF12F7E23BF0E93DFC719F046
+:104F9000E3F4F2777F36F68AFC7DA31A81EEA183D3
+:104FA000FE32E45E1AADFF8A587ADF8889CE3BC7AD
+:104FB0008C47388BDE05623EE3D1CC003D6971AF92
+:104FC000A6CB007454D169E822FDBE573C43B0AC77
+:104FD0003FDD73F1D3C83421847F26E7D43494E3D2
+:104FE000C17E1AF84522DE8ABE55E971A520FEC1B0
+:104FF000FE9BA51577907F28D87F93D62B6A668F66
+:10500000C7F7DFE93A2F8CF76923F28BA287E2FA20
+:105010001D08C1FF6BC67039A6F0D5BA5E1EFF5DD4
+:10502000D75B6ACC84B456E6AB03B09DFAA0FD759D
+:105030009DF377A31F61DDB545116360BED6BD3B0F
+:105040008F3D81FC6F2E3566E177D7EE302ECC1F79
+:10505000A497E0FEA68CE1F272404F1866DFCB9772
+:10506000F1FA5BED7F3963E4F36CFF87EF7F6087D4
+:105070008F1DC3EDF025DC4FC2EDF0E07D4391C7FD
+:105080004ABB2E799D87CA63FE7748C05E2679ECBD
+:105090001A2351BDE4CEB9B16447BFBB2056320DCF
+:1050A0006D3F43B46B62F287B6AFE8716E9FE3A8C1
+:1050B00011ED1C8796FB491708F4BE99A2F7B99D1C
+:1050C00002E9E3EE4A9D1FEB2978F52EE07ED585B7
+:1050D0000E9D3F4C18D40F15FD71A0DC2E50B9A2C7
+:1050E0004F2A7A63AF93FB71178CE7E5B786B91641
+:1050F000E17C7DD81546F91326F17CC69C479300C8
+:105100005EF43D8111FFCBFAA442A7C1FAE6A5CE19
+:105110008C1BBED7B34DA64F85CF5283F843D9BF62
+:105120009AF339DDD7E1FE1D8BFBF77FAAF4F2E09D
+:105130007661FF7E08F16F461D12BE1FFF5BD1191D
+:10514000CA3EFF4AD60BFE5E59BFDE232588AF72EA
+:105150004E76B87DB54ED66F862B6FCEFF7AFCBCEF
+:10516000471EDFDF8A9F778EF9BF439F1DD00BF567
+:10517000A1C7794741C94FC6C0BC866B3D749E73B9
+:10518000B8F7CD1E95F555B07355747C3445AF41D5
+:10519000BBC85DC3FD03CDD1D2AFC97E39AEA5F783
+:1051A000571E92EF733E78D54C692DEAC9902ED9DF
+:1051B0007B92DED95D52A3C6BF197DB7F8FDAA3434
+:1051C0008AEB57B132F22B5575469BF1BC7F737C4D
+:1051D000FB31E42BDF6EADB43BB0FEC6D1727D2354
+:1051E000F7B7D544D3DF8F61417A40952758DF5711
+:1051F000EB0553643FD170FAC12FBAC3B85CE9D153
+:10520000129FD739F9DF55D07772B9E06E0823BF06
+:1052100009DA6B88D7670D821FDF3D5F29D7FB4C0A
+:10522000EC25FF13C5D3A0CAB9CEA72C0EB2DFD48C
+:10523000F1A395BB7E4B7233388E1473408E0B0DE9
+:10524000C48D26D2799095604FE29FBC724BD25D9F
+:1052500038FF801FF393DC71A8FC30977A3E22FB65
+:1052600073C9EB3CFE33247ED43C93C78FF0DD95AD
+:10527000107EC8A5238F1DC5BFA374B3B8515DC7E9
+:1052800049BA473244FF08D23BAE8D51FB19478AD9
+:10529000DC8F3BB25330A37F6AA43C8F7FB7319C35
+:1052A000F4EAE97FA88E4579A0ACD3F9B97C5ECF4A
+:1052B0007F70A504BF9BF807D11C06E3FAC507F56C
+:1052C000BF49E2B06494F0BBFA08B463CEFF6175E5
+:1052D00004CEEB2F20C5BF2FF1DA6931A43FD22BCA
+:1052E000CB2DD80FA30BC8BF2CFBA545D80F230788
+:1052F000FD39C1DF6D97BF6B063385FC98AFF3F8BE
+:105300007E73826B26C1CFA633FE1EA683FCCEFF22
+:1053100002748DFEA23C182CC69F7F1ACED661BCAB
+:10532000A839DEF536F1D1B31A09F908BEA73893CA
+:105330006FBF44FB234E19C6730AF4FC5D46EA0CAA
+:10534000D66BB4BC8E0960C7623C09B05980F1E6E7
+:105350003C39AE5310CE446CFF499D6B13BE97F998
+:1053600064B7685F4B4C608FC577BF83E34B828324
+:10537000C7C5953893121F1F2ECE24603F059CEEA3
+:10538000F8B91587807173259EC4BEE7A4205763C2
+:10539000B187CEF73F53C848AE7F8B719E25F92168
+:1053A000E24835C86324CFD571C54D39AF109DFE95
+:1053B000B5F1C43D63D8B71CFFE2F3138CF7F8E8EE
+:1053C0004B16B2B7BEFAEF51B4CF765EA6FDF042EF
+:1053D000BF41BE8FD0C7FDEC9D3AF22F5C00BB2DC4
+:1053E0003E609F3D9ACFDB3DD43995E8FF406F5931
+:1053F00004D63F2FE76F7C77C1FCD94897BD22BD0B
+:10540000078BE7E3D00E3BD02B4E40BDE55B5C97AE
+:10541000EF8F09B12EC6F0D0EF4CE4CB7C945FC087
+:10542000E963EA07DCFE72D7F3388A59960BEE720D
+:105430003DC9C163291641F19F5B43C5595EEFA782
+:105440007DA36A8540F71CBE719CA5A35BDEB78275
+:10545000FCD3E5D3496E0EE7B70E889BABCAB715F0
+:105460000C9C8723FF75548199C61DE3292CC1B379
+:1054700087CAF8BFC575B8736C083AFB16DB5F695D
+:10548000FF6EDB9F92F7DDB6BFE63B6E7F6DDE778A
+:105490001BE7DEF11DE37FF53B6EFFCC773C3FAFB2
+:1054A000E5FFFF73000370709C3FF85C4070BCDF49
+:1054B00070FC3E1F966D1036F777416A8C7AB542C4
+:1054C00000512D46EFA27708664DE271B08D65461A
+:1054D000FF0E61F07C80325F4B0BB91D61CEBFE8DF
+:1054E0008B85794E75F496C5A29F6C127F87FD82DD
+:1054F000FCCE2A13CDF4CE18D44CC0FBF1CD61A163
+:10550000E3AA61727BC3ED23CF1796DC31369EFE92
+:105510006C43C8FB1D2FC8FE47730723BF2413A588
+:105520008479D4AF9480FAD088233C3FAA8B397613
+:10553000105E52DA3CB207A534C46F8B1CEF8D9914
+:10554000999D86FEE818D00B311EF814C605298EE9
+:1055500065A67A4A7F1F8CE5FD6DD13181EE5BE552
+:10556000F2F34CACF9A02A9EF78EAEEBE36502C5D0
+:10557000F39623FEBFD274E5EF4C938918E637FF0C
+:105580008099E28C2726BD487F775689EFAD31F3AD
+:105590002A87D16E063CD61C1C47F4BBE4D0A4F786
+:1055A000F1E93377A6680F754F51F1179C96FD1DF1
+:1055B0008ABF40896BFD5EF6937C88FE17BA1F2276
+:1055C00051EA1DABF9B6F727EFD810FCBF45E0FE56
+:1055D00021DFAFB87F689CDE9E11786E72B33CAF5E
+:1055E000CBBA78DC42F1F7EC93C733EE116D97013B
+:1055F000F6D2714D63F4B8CF8F6B4A09C7B4C0E1DE
+:10560000D7E07DF0C5D5FB35CAFA85A2A3D6B1B2E5
+:105610001FA3A79FE27AFF1214E7FF602C3FBF3061
+:10562000AF90E3F101D82408AFC9121B517D1C7162
+:105630008B591B2A9E54057631E2B9AC99E3ADCC67
+:105640007755973415FB3973B4BF09D3A29AB4A91F
+:10565000E46FAFBDD884FA9BFBDAE563B793BF4C28
+:105660002FA13D714F9FDAEFB60AA3A5F18427FD64
+:105670009D5ADF0C91ECE3713344A29F98AA30B29B
+:105680005F63744C6B42782ED78B8ACAE3A622CC18
+:105690001644933E58D42345DF973FE8078B995132
+:1056A0001F8FF374B3F8AAE24FBB35CCF11AAEE703
+:1056B0005F1B5F5DF9CEBB74AE541997322F4A9CC5
+:1056C00074B8F8AA72CEC15D7E45752EC32DF64F13
+:1056D00047FFE3B88367F4F2394B33FE1D6125FEC3
+:1056E0003AEEF58B147755E2AC6ECF45D2ABE13B89
+:1056F0003D7E3F0E963F2106DF17E2F1D757F19E20
+:10570000941EEFFF99E9BED41BF2FDC54E183FE68B
+:10571000BFE9CDA1B4CB6BA7F490B7985277E7451A
+:105720008AD77E38561DEF53E27997B4CE3363D5CE
+:10573000E723090E8EF769C3B9BFC6DDA3A3BF97E0
+:10574000E17EC748F2BBA47319DDEBFAF2A46B2427
+:10575000E25D87F1B600BA38EFB087E13B61E79DC3
+:10576000F6308CB38DEB3EA7C7F32F7562AF1EFDED
+:10577000618071121E4D741FB8C8CFF77696D0DFC6
+:10578000E3BA695CACE36F1317FB9FE541012100AD
+:10579000800000001F8B08000000000000FFB5170C
+:1057A0005D4C5367F47CB7B7E596DF0B2A3F227256
+:1057B000C16298A2DCC240A7311674AC135C8A4A5D
+:1057C0000201B5662E92092DD9CCC2CBD23A8901FD
+:1057D000DDC3B2B864F3A92683E8B687FA93AD6E49
+:1057E000550B0B84252EE2C39C71C9520D3333BA7D
+:1057F0008162DCD85CD839DFBDB5BDD8BD2CDAA458
+:10580000393D3FDF39DFF9FF0A003007DAE756B9E3
+:1058100006E74CF8A5CFC6FF0F3DA44F8CE3DDBDD6
+:105820004BEB2617C4F1BB3EC9356903F85D9CCE2E
+:10583000942B00F687CE5A1C041FCFAC7621FCEDCA
+:10584000C2DFB54A3A80F7D24C2D20EEFD66A6960F
+:10585000F8DEAFD27A02E94FDB7BD78E975E047019
+:1058600096416B10F9552EC17182E0B8C3FA4645D6
+:105870005C6EC02538E9FC80AD349BE8C75CA5D9D7
+:105880007B13F4F539456700E939AFDAAC89F409DF
+:10589000BB19A006E90C5CC124F66B5581DBDF7FE8
+:1058A000D22A4F4A7A1CF1DB1DCC36E0DE50813C17
+:1058B000591EC7F7D38F02FC6E6622D40274E9B971
+:1058C000B86472D7AAA8AF3B3F6A8152A24C5B5C16
+:1058D000AB305EDF4BFDAC1260F8FCBEE268051732
+:1058E000952017A04D3F37E0DC5B9CB110C07F3D99
+:1058F00005CA98461391DF4A3F148E2A22DA69A717
+:105900005F78E5B6FCF7274CAB11BACDFE68C2BD97
+:10591000DA9D82C39AC9ED2E6DCE207931CE2F212A
+:10592000A5D34BB7AD22CC5128E413F417C25A02C9
+:10593000D2A8AD366EEF06047EB0A17C9B5388A43E
+:10594000A09DD6704A04506F955304DF8B087BCD21
+:105950008112467CF126E72B6F3611BF4FAE2A0429
+:10596000F4E3E7CB16794109BFDF6434218EAAF353
+:10597000D3FE523CAF763195DC6AEF34F2F19341BD
+:105980007EEED6E3B23334FC7221F75F36019ECB54
+:105990001D03388E7677F618CFED6E75DE61743F95
+:1059A000F8A07F33CA814D900789DE6B94A33A3B00
+:1059B0008DF11F007026D64337D5410D41C6E1E772
+:1059C000E813D54515062A58113F37BF7E4674F9AE
+:1059D000F9FA62F00CF117517D560DD828BF4D022F
+:1059E0009401E1F5922D419F5F15B99E0F6501FC71
+:1059F00028D717DE3EC8307E7D8F5F915A506E4AA1
+:105A0000AE97CAD2E3B8F732D6531640F5F06C031E
+:105A1000C5FB589881154D79F3F1BE28577DB16EBD
+:105A20009CAD4EBCA7E6DF31CCF9443AD5819A0D46
+:105A30009A5F2061BCFC17586010ED55353D1C493C
+:105A4000A3F8B9B2D53285ECD80EA523EE6D126B52
+:105A500018E12E3C40F80E1690F0E7F62B9D5B0007
+:105A6000ED54B7D8AF52DC5B3ACCAA1588DEDA40E9
+:105A7000F46B5950372912FFC47BA9C42F67AA556C
+:105A800021BEB39EF88D5F4444AAE7AD14A56578A6
+:105A9000B7CB288D7DB3C1EA0E501F5537A311F443
+:105AA0006F47873540FEB5849BCD90CEEB41A0BEBD
+:105AB0007B5BCFEDB7458F32A3489F095767915F56
+:105AC0000BCCD316156135EA2EC84178E1BE05B07E
+:105AD0001FBCE2B44546B9733E4CAC05E04B9FC4D5
+:105AE00061C827836339C0D7BE7C0EC33E85D32FE0
+:105AF000FACA398CF8540E477C6B35A8CA3C9E957F
+:105B0000E1FB02DD27A75970259B6F7EBD3E62F940
+:105B1000AA0BEF29A67B3EBAEA2E9693C8C7205A55
+:105B20002C14D66AFDC930675EE7C306B2E381E88C
+:105B3000613AA760BE610D46218430EFBFEB6FAACA
+:105B4000529B6FD902B893F167F4FA048722D03CD4
+:105B50007A4BD2FA7F78C55F3C9E5248B9B21EF3A9
+:105B6000E61937410AD28FD46B737FBE9EEB184F74
+:105B7000C0B8DDC078129CCF6FB5F8CB281FAD74CC
+:105B80008F24E7A7F4FAC40A30BB32B49C32BC4F6E
+:105B9000476C0E6020B2308F1D211649C53EDF19BB
+:105BA000DE744724D8C3E096717E3CD77DD8E646A4
+:105BB000A589F3B6338D26F9135C4AD5E22C593406
+:105BC000D86FD5F65A935D8B730C6EB56B75719467
+:105BD0009A05EBFBE879163888FDE7A918BB4E73E8
+:105BE0002CCF01D08BC3C7939F1E31D13C0F99EFAF
+:105BF0003D99E3D81F798A0C1D3994370C26F6415C
+:105C0000817E0724C06D9463911C616E25CA2D1995
+:105C10009F257D9FD8156E2F77579001BA5004FEAF
+:105C200083345F462D50771AED779D637090FA3B71
+:105C3000E00205F7FDE8F11B874F21DD738EC9B443
+:105C40008EBA8357F99EEF162778FF78C2772DBC5E
+:105C50001E8337357A88390249F23A40FB1DED6ED2
+:105C6000467F686E741F300552D06EC339ADAFBD2C
+:105C70000E4B40417CACE81D91F09DE719E4D11C2E
+:105C8000532616A511FF80190225DCAFA6BA84FDA4
+:105C9000845F85FC8EEDCFD8FEF1C0F45821D56B22
+:105CA0002753230ADF3FB78CFB052F921BDF2FED15
+:105CB000A16133CD1BDC4306B9DD8E863B343F71D9
+:105CC000CF18E94B0EDFE7F98028AF53DC2F067EB3
+:105CD0008D3D63E16D2C095809157338CF3655CACF
+:105CE0003CDFAD6EC6DC181F497075919F7091C97D
+:105CF000346FE7C7ABD1AEF541A39F412FE677C81C
+:105D0000A2D5C7D03A16F0A37C23A294F7A18B7B2F
+:105D1000FC0CFD1CAA62AA40F120218CC7163D3E56
+:105D20002F801F6E4BFCA9706CAE1AE035AC612B56
+:105D3000D653A35E0F00016EA7F9E3D408BD238EEE
+:105D40009A83F92A7F97F8F97D6755E0FCD414E827
+:105D500049D6AF6BEC75B36A0DC93DF3F7D32E7B13
+:105D600092F7D347F876223B7BED4C24BF30BE2B15
+:105D7000A9BFEF155DCB1C41F481C9B58FCE755914
+:105D800022ABA9BE1F98DC1C8FF191EEA1FD828B86
+:105D9000EF16F591008CCF8723E567CC949776A218
+:105DA000C7EE5B1297E3B8E969FCA10ACFDAEFA16D
+:105DB000CA9AA7FD7E86FA17ABCF577F6EB2BC1D7D
+:105DC000A2F997A47E7ED2E71FC01299F7CB933831
+:105DD00083B68764E0753CAAEFF57EA6FC487BC8D5
+:105DE000FF9D190695F85CEDCFD0F47FA6EB8BC133
+:105DF000511DF69B35B9F9F627F439FC8BC9718A28
+:105E0000EEBDF2A4004A82DFAB82A9A024F85D199E
+:105E1000CA31E0F6C862837CF578A9815F33B1C2EC
+:105E2000C05F73BDCA80BF145D67905FFF6BBD012B
+:105E3000DF30BDC520BFF1CF6D063CD6BF7558B968
+:105E400089E73649AF1BE40A3B8D7E15F518FD2A1C
+:105E5000EE35FA15D35BE237FAB7ACDFE85F4EF602
+:105E6000835C85DEA1FFFC9149FB60203CC3F334D9
+:105E7000359D02133447C4A8B61FC266BE17A6F0EC
+:105E8000FFE2A2843C2CA7D73FDA19092FB3D2B97D
+:105E90000F9D362BBDDB2E510D603EFE05D7762EB5
+:105EA00017E00E00000000000000000000000000ED
+:105EB0001F8B08000000000000FFE3E36660F8515C
+:105EC0000FC1D3B81818367221F84301B7334368AD
+:105ED0003E16060601207EC7C8C0F09E91043338E6
+:105EE00010EC7E20BB0A88277150CF7D43112FE52F
+:105EF000A19F5D5FA0763D1518787F83B083100366
+:105F0000839B300383B40884BF5F0455DE5108C10E
+:105F10007E2E41995D9F81FA018DEBBB318003009C
+:105F200000000000000000001F8B080000000000BF
+:105F300000FFE57D0B7C54D5B5F73E731E33939976
+:105F40004C260F4242004F08202A842140088838FE
+:105F50000990068D9A080888CA000142483211A9A2
+:105F6000975E6D672214D16A1B2D6DA397DA0141EC
+:105F7000A3450D18E840031D4C41BC5A8D0A4A5BED
+:105F8000B541313C0A4978E8C5D65BEF5E6BEF332B
+:105F900099736642A2B6DFFDBEDF177FFE36FBECCB
+:105FA00073F65E7BADFF5A7BEDB51F2359C613D345
+:105FB00015847C057FD71372482484F4EB4E3B0B89
+:105FC000683A8E107F8E39B0552024B4EFEFED245F
+:105FD0008590B34DB355732621FBC79843D7D3F2B1
+:105FE000B381FC8099964FDD79C421D17CD54E5187
+:105FF0008272D33E2B7EDFB1510840DE6B6EFDF125
+:10600000B534DFB553249B69D5246437915442DA03
+:106010002D84FDA9F1985F6A65D9AA4DFBEF82F640
+:10602000CA836662A5DFB737896EC8AFDC2A040869
+:106030006DAF6AF783CA005ADFB280D06855697EB7
+:10604000EB638A1A4FC803FBFEEC68B31372DA677E
+:1060500021AA82FD286F1C494845607BE100FA7D3A
+:10606000C536C165A2F5576C3CD701F45534C9C398
+:10607000445ADF8A061B5147B0B6BF22D05ECB0719
+:10608000D8DE4E7928B457FEE53D0A11A19FB21B18
+:10609000BEABA27440BFB5764FFBEAB13D8D9F55B4
+:1060A000CFD1F6E87BD52F0A2EE862B58978808EAD
+:1060B0008EDDD6B94FDBA17FB5CAF0F8C87E2CDCE7
+:1060C00005FDA8086C520AED40DF2665E9C8EEFA26
+:1060D0005634FC879EBEFAACFE9E8872637ADA471D
+:1060E000593ABC3B5F4188BB91D64BA480523AAA37
+:1060F000FBF907422221E3A17E91A896EEFAA9E4DA
+:106100001107FE23F49F940FFEBDF181AD99DD725E
+:106110005BE9049975CBEDBC93CB51EACA8DAC5FBA
+:106120004B7F0CF2A0F4D4F99C983EEE4BC37483E1
+:106130004F45BEFDDC3702D37A9F0B9F3FE9CBC3AF
+:1061400074A3CF8DE953BE224C03BE127C6FB36F94
+:106150002EA65B7C1E7CFE8CAF1CD3065F0D3E7FA3
+:10616000DEB71AD36D3E3F3E7FD1B71ED3465F1DCB
+:10617000A63B405E346DF205F0BD5DBE064C83BEAD
+:10618000467CBEC717C4F411CE47C764922F513E58
+:1061900038DCC449C54E928ADDF932CD2795B07CF2
+:1061A000EA1DFE7C85E6533D344FF932A032946FF0
+:1061B000A6F90135AC7CF0FDA4C042F383FDAC7CB4
+:1061C000C823EE022BCD0FA963E5C337FA0BE268B3
+:1061D0007E7880955FBD2D5460A3F9AB1B5979760D
+:1061E00033996AA7F9EC10CBE7BCE19E1A4FF3395B
+:1061F000AD2C9FFB817FAA83E673DBD8F793CE0497
+:1062000044D51E2D871DB2BA9850596DF4CF704BEE
+:1062100013695E51EF212ECA1FFFAD6E299DF24317
+:10622000766379C83F1FCB9B143796BFE32FC3FC1F
+:106230002ED983E5C7FD552CAF78B0FC73FFBD9810
+:106240000FCA7E2CB7D4FA585EF163F980DAF5589C
+:10625000FF1E3980E5236B1FC3F23D4A00CB1F5F51
+:10626000FBA47B1ACDAF113C3F073CD2B49C640128
+:106270009E1AD34A289ED609642EE0F707003A8A70
+:10628000CB75E90AEAE18E3FE43E0DFA8B7F299057
+:106290005FFACCC399F8FDAFB01E99D623F65E4FD6
+:1062A000CE9B79BA7A72DE2CD7EA6980F7D658FB92
+:1062B00056CF8E3727E9E979B342AB673BD213DF7C
+:1062C000B77EE5BC35594FCF5B955A3D7B909EC458
+:1062D000BED1D37444CF9FA62361FEB4203DFDFA06
+:1062E00046CFB8F7F4FC19F75E983F6F603DE97D43
+:1062F000ABA7E93D3D7F9ADE0BF3E708F66B50DF75
+:10630000FA35EE7D3D7FC6BD1FE6CF47484F66DFBD
+:10631000EAD9F5A19E3FBB3E0CF3E704D633AC6F40
+:10632000FDCAFD48CF9FDC8FC2FCE9C27AAEEA5BB2
+:106330003DBB3ED2F367D74761FE7C81F58CEA5BBB
+:10634000BF72FFA2E74FEE5FC2FC310950CF98BE8B
+:10635000D113FC54CF9FE0A761FED8B09EF17DA37E
+:1063600027AF5DCF9FBCF6307F520490FBC4BED5F3
+:10637000136CD7F327D81EE6CF20ACE7BABEF52BB7
+:10638000EF849E3F7927C2FC198EFDCAA77A0FF4CD
+:10639000105A4F7CCFF5EC39ABE7CF9EB361FE8C42
+:1063A000C67AA6D37AB27AAF6752879E3F933AC233
+:1063B000FCC9C37A66F4AD9E3D1D7AFEECE908F394
+:1063C000271FF97353DFFA35A953CF9F499D8C3F9F
+:1063D000630FD74C75D0723A16BA44FAC9B567DC68
+:1063E0006E81E64527CB8B4E1701BF44D4FC0DD2FE
+:1063F000EA16E9F7F66D89390F9348BFA3A014FA9E
+:10640000154FBDB148BF23212F4EE7E724BA93743F
+:10641000F9E4A201BAF7FB950CD195F79F7BB5AED5
+:106420003CDD93A3CB67944FD2BD3FA8A64097BF56
+:1064300062F50DBAF733FDB7EAF259EB6FD7BD3FFE
+:10644000AC6E91AEFCCAFA0A5DF9558195BAFC357D
+:106450000DFFAE7B7F54E303BAF2D1C18775E563CC
+:10646000428FEBF2630F3DA97B7F7CEB665DF98485
+:10647000A3CFEBCA27B6EDD0E5AF3DB9C7E0E7D96A
+:106480009DEDD7F0BC08B827CCEF4F57D0DF0BC538
+:106490002B985706D8D18FDF1FBF543D4EE5ABBCBC
+:1064A000B2584DA1F20599123AAEE70F28BFB28D4E
+:1064B0003EBF7792E74A277D7EAFE219ED8CE19FE0
+:1064C000523C08240D52D504A9B1FC4199E1B120F8
+:1064D000E3CBE1C7E8F75E53D7F0449AEF2FE6D756
+:1064E000035E9E124C88D33891D4C07B716682F3D0
+:1064F000820733739FF647E075FD20AA874277BD78
+:10650000EB654F1AF8199B6BDFF6831FB26E10ED27
+:10651000D700429E16DE0EF987D2EF072D4DF3D03D
+:10652000FACC0AF5D323DB5768FB23B1FD0668FFDD
+:10653000C51EDA370FC9D3B56F195CAE6BDFA2D0B9
+:10654000F69DD41FA8FD236F9F0A6112212F0B7F98
+:10655000C4F6CD83CBB1FD07153A5F896C3F2EDCC5
+:106560007E10F4771FB43F3E46FF874CD2F77F7012
+:1065700085BEFF0AEBFF2BB5C778FB71D8FF16E18C
+:1065800018EBFFE00AD67F33AB37DCBE23CCFF43EA
+:10659000D0FF377BEA7FD6647DFFAFA8D4F7DFCC8E
+:1065A000DA7FA7F6146FDF8EEDBF2B9C62FDBFA2D2
+:1065B00012DB57CC1E17E047C988AB09D0F6C9409B
+:1065C0006A98FA035C683B908E48A2A026E4516169
+:1065D00008D2716F1CC3DBE771146F686FFCF89C05
+:1065E00004A865CBA5F32E8EF515DBF215B04B583C
+:1065F0004EE72B4B38A9654111F14D369803C3285E
+:10660000BD1D41D10FF9B20DD705C0FE79CD644152
+:10661000097C2791103CFFF467A33647F6CB982EF0
+:10662000A993DBDB22F42D3C8F2A20236A287DD31B
+:106630000104E3BBF31FD37910A1F38B0FE83C8374
+:1066400050487E22B3F63EA2F325C8B7D1F9129482
+:1066500013528BDFD1EA0EA751FA4B38FD1F4B4C7A
+:106660005F3FBE4308F8A97E7EFEBD31384F5DB066
+:10667000DA4699DE4DC7427FB22E4FFBE5073975EA
+:10668000ED3607360BC85F15F8558AAA49C8E2F5FA
+:106690001994D7DDEFBF4FC59E4E597F1B71CBFDBF
+:1066A000E9FB77AE12063969BBB3DDE61C364EB89E
+:1066B000334CA8D724C39447C8AD4D63645A03290B
+:1066C00075CB1FB745B43BB3489F9F5DA2CF77C83A
+:1066D0006ED944E9EA2815C8265AEF9CB9FA72AD7A
+:1066E0001DBB2989C999B75792CAE89B03690E3C1B
+:1066F00076A29CE73AD9B71A3DDEC5329DC2823CEC
+:10670000FDFD08C8D59F82EFDDEE64FD36D23B5714
+:10671000B6B84B683FE72E1403806F23FD7FDA671E
+:10672000739BB269BAFEA7323145F7C748FF3C8F69
+:10673000B13F8D328CC3F3CB8DCF196EDAB9FC3FEC
+:10674000067CD0F404E083D27F9CE3A3DBAE327CF2
+:1067500078CD9E9B010F5D4F8804E5CAF1721BC77F
+:10676000CB923A3D2E08F1C820C76573859C8723DC
+:10677000703087E36059BD1E377712BF9C1E432ED1
+:10678000F3366CFA619A1ADDBF0F396EE63FB21F1D
+:10679000F913DD4F26A7BBB89CEEACD197DFC6E559
+:1067A0007A2797EBDCFAC70E50F3416E570332E8B5
+:1067B000BBF73E4D9E6D3A797AB83C8D74DEC5E5E7
+:1067C00079D7F7983C8DF4B67179B6D55F90C990BA
+:1067D000687A8DF42D581DD51F05E4B9D01F5B9E36
+:1067E000DE607EF2F188E7558D33928F47E8D98AD3
+:1067F00086525D7E79609EEEFD65F50B75E54BEA90
+:1068000096EBCA17AFBF5B975FE8FF9EEEFD05AB47
+:106810006B75E577D63CA42B9F5FFE982E3FCFF398
+:1068200084EEFD397337E9CA67973CA72B9F59B4AB
+:106830005D972F75EFD6BD6FDA77D52D80CF378E68
+:106840008804FC89CF5C27302EF8994B76C13BC772
+:106850007D2AE2BADD3702D3933E17E2FEB42F0F52
+:10686000D38E608B1DC6093A2E2E2589D4CC9B6E03
+:10687000AE5D3F10C66982E3E916D3AC5AFF6442AD
+:106880007E6D5291DFC5F50A098D254480C186D3FE
+:10689000D1254694B7F5525E4F0D7F727479715BC6
+:1068A000ECE7DEC7175EE18C1177E9D65392017EE3
+:1068B0004F27F7BB8DE5950229897C4EC803A8D7E1
+:1068C000E7F8B85BA930FDAFDC915E401C900F0D7E
+:1068D000AFB95C7B8D14E4FD0127593A3D5E567FCC
+:1068E0008DCEBE1388CAF603BC8DD53D5FD170AD89
+:1068F000EEBB33FB45A4BB1A6CC54418164B5E3780
+:10690000811D0EB50C9E390AE874BF6182712AD8C8
+:106910000FFDC233BEA2E4E312C8AF04D393BEB9E5
+:1069200098B6FB3C981EF79563FAB1AF06D336DFF5
+:106930006A4C3FF2F931FDC0B71ED33FF9EA303D52
+:10694000EAABC7F43D5F00D3C3BE064CDFF135624E
+:10695000DAEA0B62DAE17363AAE95D6FB83BC9C793
+:10696000E1D380BF1838EB786055EDFAC9DD383BCC
+:106970006FBAAFD63FB09BCFC5F5668E87541D1E4C
+:10698000BE806033E2AC97F27A99E3B0A7EF6397E9
+:106990007B37FF6BF036DEC4FCCC6F8AB76E3C658C
+:1069A00018F094D51B9EFA89E3BBF134DEE4647ED3
+:1069B0000FC7D38FA01F31E61505E084F48BF0D705
+:1069C000DC3616A7E6EB09D45365716ADEF61AFACF
+:1069D0006E2BFA758111306E9C1FF1B7E110873F65
+:1069E0007FD44C277D3DF7CF88939EF9EEC6F9CD35
+:1069F000D2001DBCC646975BE3185FAD265244E843
+:106A0000B8F6D0B0675C8B46625E2249F07DC05517
+:106A10001A1FA35EEA2B037F7BE3EB9AF8CFB3A1A7
+:106A2000BEF627FF9E0BE97813F397E35A44F4DB95
+:106A300049E86917F0373C2E995D6910DFEE1AA618
+:106A400038D16F08D8F5FCF3D37C6E37FF1EA23C1B
+:106A50006AC571B72E0DF937F4F3E1E97DE05F6F98
+:106A6000F6BD377E2E0A0CF897F0B337FBD89B5D46
+:106A7000246EF5C520ED7FE7BE51390FAB60078767
+:106A8000B0795A0FFCD6D6A58CF47CFF6BE2B833F4
+:106A900055C371EB6042DBF988EBCBF9A62B1340B1
+:106AA0002EB41E9C1F74EDE47E7E2F723D9BA9AF19
+:106AB000CF6BAC2F4121C268DA6EBCA29004426A4F
+:106AC00044CFA322CE6F5C6D7E881BECB3B9D6A8F1
+:106AD000306F3CFD6648851AF5F185F3879E76C0D8
+:106AE0003C6C659AC9793C861CB5B4AA31D3698FD0
+:106AF0009CAF04F5F9F375425123CEE7D48459A332
+:106B0000609C713A8F0F05BB9F86A956CFCA34C5CA
+:106B1000799CDADDD30D59096CFE1760F6645B22AF
+:106B2000DA9BD33E0BBEFFCFA6A7A77A347A0869BB
+:106B3000229F58C09ED3B2AC9EDFEF511FA48B0A98
+:106B4000C43749B3FC39CC37ADF4FFAF8640BD1232
+:106B5000E6B57ABD8DA2DF3C1A9E6FD3B547BF5311
+:106B6000B5B557F8AE67BD9348BB867B2ABF57F9CA
+:106B7000FAF08A06AB53EFC726EAF2DE60BA53E7B3
+:106B8000D7C23FC071AF1124C05F25875FA7645F84
+:106B90000F78DA0CC14398BF08ECBD2A4B9BE25139
+:106BA000515D5A019F8BF234FCAB73FE4CEDD4A9BE
+:106BB000D765027A46BEA454E5F2A920E2CD444C42
+:106BC00034BF98BFBDA86945318C5BA74C6CFE50A3
+:106BD000464A1C303F2E2775B9104F3D4B4C45A0FF
+:106BE0009F67C93B8EB111FA784E54B0D2C5EBF510
+:106BF0007E3C9DDFEBF2CBEAF5F9A5E4D6545807CD
+:106C00005FBA41260101EC86BEFC98E8C47A9791F0
+:106C10009A75306EFF9CC7BB1639899441E9ABFA6F
+:106C2000CD2F7317523A2E896CFCD5D67197273128
+:106C3000FA2B660514377DFF93A6B1B7510B44BFFD
+:106C40000FAC83756D7F29716D25D1F2FBBAF41BF2
+:106C5000E9D5FC81A8F5644E474A83E00EC4B063D1
+:106C60008A24303DE3F6EE6AC9A98B83E4423E22D2
+:106C70000EF28DF194427478DA2C7A064BE3197E89
+:106C8000000F82D4A578BE4DFD6951F55F2DF5FB4F
+:106C900027D63F90D69FABAB3FF79F4AFFD028FA4D
+:106CA0000B62D55FF59B1776F9A93DA978E9670EC8
+:106CB00042C7C953525DAA8BCAB572EB0F1D6E9ABB
+:106CC0009E94FC0EC0EBA98058144BDEABC3F27649
+:106CD000DB0588BBC13F69FDA79FFF11C6233EDFCF
+:106CE0002A3B319ED6600E99A93E56372D2F26D9C4
+:106CF000983FC6F20F9E13211FD4E3AFE2D99FA5A0
+:106D0000C2FE0A8A141E5F0AA13F5BBDE5D3421C86
+:106D10009F4817EA91F13B68FF5212DABF854A4259
+:106D20007439A513E3045ECE176FD38FCE890EF8A6
+:106D3000571BCEDF8DEF9773FF74B9149FD26EA3EC
+:106D4000FF9E4026803DD4F84102CC3F5DF3DC2F0E
+:106D5000B28F517ACE6C79DD2144F049D3A3F38D03
+:106D60008B7FB547EDD9DE76503D8BF483B4F14A85
+:106D70000D72BFBA99A59572C8712DD5FBCA4DB2D7
+:106D8000CB4F1F57BEF0F4334F421CF38F66D73002
+:106D90005AFF8A170EBC3789E6576C97538A5937C2
+:106DA000EC426AB75CBCF4FFD539DD72A878F98093
+:106DB000A28E62CFEF4FEA96C78AEDFB15322A9A70
+:106DC0001F531BF72B6DF61872693C56087EC29A4A
+:106DD000E7FE4B81F8E2A97D02E99F19839F9B0E94
+:106DE000A01F007C4239723985E56678DF4BE502E9
+:106DF000F65A9393B1FC466E4FA03E7524E2F9C556
+:106E00003DB4FDF23F995DD0FFF217EF71403F4E68
+:106E100048350CD7BFFC612AD8AF72D99FEAC49419
+:106E20003D2F7FEABB88B7656F7F3715E349C49D67
+:106E30006EC2B1C79F0EFD5BB27136F66F29F120AD
+:106E4000EECA7F29960468FA99448AB6C7D08B0E99
+:106E5000AE17273653478CF6EF04CC1FC15EBF2315
+:106E6000E2BE2A42EE26A0FFDFE57DA11E02E63F3C
+:106E7000B330391D904C5CAFA8B71989D72D0FB628
+:106E8000827C4E0F72F78775162F91FC9C1FC2579C
+:106E9000B45EF1EDE9FD997C882AE5F2EFE8383F30
+:106EA000159EC3FBADB2DB9AADFB8E7C95D9DDFEA2
+:106EB0002ADE3EA53B0EC6E713A9B1FDD501B2A659
+:106EC000F7749C8EC057847E337DDFF210D36F4DF4
+:106ED000DF03A545507EF130D31FF80EC63F4A5759
+:106EE000A83F96EF9F25A03DA0F3E6587ABD45E662
+:106EF0007AAD2FD77042E996848408BC40FD49C81A
+:106F00007F5C5F59BA817E17612FBDD09E23BA3E48
+:106F10004D6F9771FD3F05FA7F4DB7FE938D4CEF96
+:106F20007BF69FFC2C6E23079E7912F495EAA75FEF
+:106F3000057D954BA0DF7FDDD6F2DEED544FFFDA05
+:106F4000A8E9A9DE7E1AF5B47CC778124B4FFF6A18
+:106F50007791987A4A9FC7D4537B1BE2F8FF94FD40
+:106F6000D4F89728EBF9A7D9C39EF868B4872F4ABD
+:106F70002AF2D3680FE9DF61921B8D3F0D771ADE8D
+:106F80002A7E5D7505D89D302E35DC8571A9E12EF0
+:106F90002A7EABE39FB1FCCF106BA274CDB7D44F68
+:106FA000817984A58BE0BC2B7F9688EBA6968B0419
+:106FB000F5BE80C8B86FF07D53CD78F043A7FCFDD7
+:106FC000B6B3F7527AE713BFCCD6E5EB64F4EBBF68
+:106FD000FCEAABC9B43FB773FECEA7ECBE89CA6367
+:106FE000AE2484E2289DF324E24F4882F8AC403E70
+:106FF0008EA0637EB93E0F7F5352BBEBE9EDFDAF30
+:107000003B0FF9A6E9DB3EB676F52EA443B179290C
+:10701000124FA52057CA3FEF38213004ED529B5440
+:107020001231AF7A9CDB9DB7A7CD1C0FFE4BFE9CA7
+:1070300051090CE783717EEBE5F6EBBC5F4D00BBBD
+:107040007EBE390BE7AFE70F2D8E8FB56FB285E3AC
+:10705000EC005F57E9B40B7522C57D27E942FFC5F7
+:107060006FB792AD31D6FDBE2F9BF8E483CB8DFE7A
+:1070700089546E73390EE7D14F137222E436EBA6B2
+:107080005392235A0EF0F771C43CEBDBF217700DEC
+:10709000FC6DB1B61596C488D7FD84F36FCA2B5F1B
+:1070A000E0FED569CDF912F0719A5DD4C5391ED4D0
+:1070B000F475241909744D7965F9A3E3298EBD8708
+:1070C0004417EC57F5369F533C31E6BB467E42FDF4
+:1070D000E0471E909DC8AF2372C912E0EB91D956CC
+:1070E00002EB96EF2AAEAA58744E37B378C83C52DA
+:1070F000F2D938E1FF3EFEE6CF890F15507E9CB7EE
+:10710000B3FDC0D1F8637A7FDE29046A05C0A1C847
+:10711000F2294200E26485C4F3E86401F5FDFA480F
+:10712000FB951F2C7D01F6D554370B4E132DAF96D2
+:10713000DA14C0B137B85D02FFFC4695B831DE20E5
+:10714000D58C9A1511D73A204BC8AF96BFDD7E2754
+:10715000F0F7C22C3301BADC23CF3960DCBFD03C5E
+:1071600016F5A0A77EFDC147A64C93A01E82F8305D
+:10717000E2A130C5A6CBCF9E4A06BAA8DCA698DB12
+:10718000EE71C590DF3285E1ACCFF6CDF2FF997D8F
+:107190009B4CED1BC3B51C69DF462B51F6AD7F2C14
+:1071A000FBB6B256ED0FB858B937AB3FC875E56BB3
+:1071B0004BFAC5B26FAFFAD8FCFD35BE0FBB7320DA
+:1071C000B56FA323ECDB406ADF62C46DD315CDFF3E
+:1071D000ECC5BE59FE77F4EF55B06F31FA3B52D192
+:1071E000DBB7A2E65AB46F450345DD7EA82C85CFF8
+:1071F000E77AB46F0B7F361BF3B2CB16033FC05751
+:10720000B06FAF713B07ED809D5BA438B1FDBEDA76
+:10721000B9D2BEDAB9FF253E6B766EE520769E23A5
+:107220001A87CCCEADCC64766EE55E66E7560E630B
+:1072300076CE68DF0AA2EC1BFBBE7A04FD1EE78B4C
+:1072400099BFB8839617CF955D16FA7EB1AA9D5F58
+:10725000A8191F69EF162912F239CADEB9CEE13931
+:1072600090DEECDD5B60EF86A21D1B0A7A64C4C76A
+:107270000D436DBAFD7247BE68FFF54BA02F7F101E
+:10728000719EFDBE89CD8BF67DD13E16F46E37A77B
+:10729000E75185C9B3C3E7477B3A7524D3F7AA43BF
+:1072A00071384E543709ACBFF70B0115C681BF5D6D
+:1072B000C2F9F29D7BD97C798E99F183FC9BC8CE73
+:1072C0005D50162C8CC0C3DC4B1518D79C2B110BB2
+:1072D000F8AF0B0EDD700AFCD60597D6A3BFBB0036
+:1072E0009EC3BE89ED6DEB3268BB772E1770DEA1B1
+:1072F000EDEF9817B6977A3F767E73EC7D1A533888
+:107300003D53EE1302B02FA7B77D102F72FD9B23C4
+:10731000B621BFC85B62CCF8A4F65E984F2EC69724
+:10732000AA55CC6F0EF389F24D15A2F944255DBC28
+:1073300030B59B2F77EEA4FD4DE9B9BF1ADFA2F758
+:10734000E1B8713EB380BFD7131F343E47F59FF3BA
+:107350009DFAA9B89FC7C88F46CDCE5C4346815ED3
+:10736000BE6FF23C3A1E70F49F942F94CEDBE60D74
+:10737000D39DE7D9C5F97293E7D8B45415F8486A94
+:107380000067B7976F3F904AFB778B3B330742E626
+:10739000B3FFA67820FED062ED423BA8E130CDCC11
+:1073A00070F8578EC323039CD370BC090A4ED4AF28
+:1073B00090C1CEF17D645ECA67D05F6F908F4F142D
+:1073C0009FA09F85DA780572A1FFBCA999C9C55B0A
+:1073D00023A05C6E265D0781EFD529822B44AB2A62
+:1073E0000C6EFF21ECB77AD54A9F839E970BAECDEA
+:1073F0008C1DF6F4D498389662E1183709468C9BB8
+:107400000BE0BD24D8B768C6F6EFFC1EB347463F75
+:10741000658AB9F508D033E5DF64B2091E06E87F56
+:10742000113830FA31517AF035F7FDA472FBFD2A9C
+:10743000C8C10EFCEE52C01FF286D8F8A3957B257A
+:10744000751AF24D9343908E2FE3981C60A9DFC804
+:10745000E75BB43CE01FDE6F1664F87E06954F32A2
+:107460002D9A6AFAE2A08677B31ACD2F8827A4470F
+:10747000D80DB06F91EB96D5C1B7914F37ACA2EE56
+:10748000991ACD274D3E60072FC7AF28FD09EE8F13
+:10749000B97FEA9BEA4F9A59AF3FFBAC5DAF8F864D
+:1074A00038DA5E01ED0A694ED4C50FF2CC6C5ED6B7
+:1074B00062F520CEBB5E935D9BD568FB7315970B81
+:1074C000CC5722CFEF4D850EC1BAB1D34A3ED1FA87
+:1074D0003D84E12C723C78D5EA41F9F554FF045E15
+:1074E0007F4FFE9896FF0EB407FB16557D7BC6F1C5
+:1074F000488B27F5D6AF6966663FBE69BFB476BED6
+:10750000EEBA8397B462FC4D5B7FD82C7A7E2EC393
+:10751000FCB848D0AD7350CA71FDF29F50FF58E5DA
+:1075200032F543FC2844F9FCEAB6A7315E7DF6F952
+:10753000633783FEACF8AD482C549F3AB6C5931020
+:10754000DB07A2809F50D124E27A169142B93323FF
+:10755000FC0C42D6307EBC148F76A7628739504C23
+:10756000BFAFD8F54936C4DD3A1E60F6CFFF3CC741
+:10757000A3BF2D1BD6FB2B24B68E6F94CFBD1C9FB3
+:107580006776DBE682FD161AD879D78AC639B23912
+:1075900022CE506596595C7BB70DF759FB9F13704F
+:1075A0009F32D01779CE52DBFF79E63966972B826E
+:1075B0007200CECD56346CEF803878C55133FAAFB7
+:1075C000DE86730AF8A7535F7A01FD236F50D4C596
+:1075D00041A3E28F0D62C80CF1B3A62AB403347F35
+:1075E0000CF38DB1E3F0BDC5C956BCB477979FB21B
+:1075F00070C5CBCF3AF0DC6CEB5607C6211B2E1FB3
+:10760000FF8F8A37363E74D978E3698E8F5F99F59C
+:10761000EB35A42119E39094BEDC9218718B30EE07
+:107620005FF8EC29580F3BB3E3AF4F01BD95FFB8AE
+:10763000F0D47DE08FEDB33A61BCF63E7F04D71302
+:10764000B4EF76733DEF78EE595C87E9F8A3D9057E
+:10765000B575EC3D3118D6233AB67F910A71DB55EA
+:107660007BA7E33C6DD5CEA9FD498C798096026E4F
+:10767000037D580732CAABA5A96530D07996CA1BDD
+:107680005CB670FCB8B18AC5E3551E37DE167BBD0B
+:107690002D2A4EDC34F396EB60FC6E925D2AE943B2
+:1076A000BCF83095E3E83EC86FDB439ABD8F29BF35
+:1076B000B3F00F2AA7F70DF2FBAC69C9AF9E84B2F5
+:1076C000A6E41EE3C5A13EF04D5BCFDB62767F6C86
+:1076D00006BDD9F16B8CCF83DCE85C8374BCF0D938
+:1076E0006088B39C94BBEEC2FD337BCDB82FAA62F9
+:1076F000EFFBA83F1D3BDFC6F532C2D7D53A48F8AD
+:107700008FAD83F0399C774B3C8B3373FE431C5A0F
+:1077100075E0731E6F6638D6E2D03DC59FD32D6CE1
+:107720003F91B6CE58B5E5CF0A31C4F5853C90D32C
+:10773000B1CBAE8B6A7C70021F2644AEA7C48EF319
+:1077400087D7DDB8BC407EE07F85D74B687E20C4FC
+:10775000CF03C2FB24863DE8D8C4D6613AE4D8FB07
+:107760000FB5F595148B414F037D5B57E98DFEAF47
+:10777000CB1F19269BE3A3F974E6CBD8767C824510
+:10778000F876FB612A85A8F57F0BACCF371D5360D7
+:10779000FEA18D635A7FCFF079F299E7453CEFB1B6
+:1077A000AEB105EDB8D15E5413161F34D23B83D36E
+:1077B0005B1D64E3C4991DF1013BADE7CC2BBB110C
+:1077C000CFD5DB8E297E5ADFC1869795B688FD52CC
+:1077D000304E0422E83FF3E2FE6CB67EC4E6E5C616
+:1077E00076E6F076BCCDB1DBF16E3BA76B6785BF6B
+:1077F0005161E7772EDFDE69C93D07EA3BDD2A13D9
+:10780000D8BF7FBA512C0AC4687F9245D6E2F24CA9
+:107810006FE87889E71DE3D9F946314941FF7A5588
+:107820007CDED18414481515E2146B6AD9FED2357A
+:10783000DF77A581BCD724DE86EB6D7506FE3A5353
+:107840009CF910BF704E2B19077035DA9B44B7496D
+:1078500047FFAAF8A2FE701E7F2DF7C788E4C2F387
+:1078600097A2A3B008FA233A4D4E6B8CF505D95E6A
+:10787000423C117C919DFAF392E4CBB12AD4A3ED62
+:10788000A3A9B4B41EC442A71BB70A4B79ECDDFC14
+:10789000594EEC77E7363E4F7013D599CAF683C13F
+:1078A000B8D1B923219B8CC60F899BE2D1C69F0B0F
+:1078B000DBF6EF077BB4D641DC8954CF285755312E
+:1078C0000BCE8D8EB1085980D3736FFE96D66B6D3B
+:1078D0001671FED069D7F685BA1341CF6CE411DC7E
+:1078E000FF0750FE2AB99B4EE3BE4002AFA476DFED
+:1078F0002B315DB4E3BCE7FC46160710C9D5BF9831
+:10790000CCE2702400F4F3F16405A7F33CA4F07E0C
+:107910009982E73A96BDF6726E88303944F22BB9F7
+:10792000487FBEB4DEEAC8867579E277B7C2399976
+:10793000325E5FBF12FDB953AA7E7ED0D3255C4F65
+:10794000FFBAB4F010D8BF32CF52B4EBFDE7EACFA4
+:10795000A51AF75921BDB02F8CEADD9342F4BEABD6
+:10796000F2E6C7D6C17C397AFF151901FBC92A484E
+:107970009C0BCEE7AC68D097EF03BB7915B093D8DA
+:107980002F17EFEB95BF6DC37F3179DC65F9EB0AFB
+:10799000C1FBDBE231AEB2ECB5C5689FCC697AFEC3
+:1079A0005A553D7F6D238C7CD4F339DEA5E79B3699
+:1079B000FFEC89CF0979FAF3BE463E4B84C71B0220
+:1079C0002C0E11B5BF2DB809E936F2D9C8D7760B00
+:1079D0005FF7E27CA57F25965466B281EE74298418
+:1079E0007A61D4A30C7B48807F0F4A09D4E257AE5A
+:1079F00078B4EF69BC3F4219FBCE067A2402BD2E53
+:107A0000D42338D10776DE463E70B65B41589F904E
+:107A1000AFAEE9599EF794FEFED822FAD546C0EFE4
+:107A200068D42B766E378904D664829EBA9C306EF9
+:107A300037FA2C6A9904F79F10B56C28DC7BE2C4F6
+:107A4000F4C77C1F4AE74882FB821B431753C13EA1
+:107A5000FD38A7EB66B07BDE25A404ECE0CD716CAD
+:107A60009EB298A77FB72ADCAE4E7BED7AF8BE595E
+:107A700056E15C7867F356CB30C80745BC7FC49BA2
+:107A8000587715B4DFD12C33BACA2C816110BFD816
+:107A90002B63BB1D6593F17C65D86F6B66FB403A29
+:107AA0009B3F712C8EB0E71DC19F5E05F1AC274C4A
+:107AB000B1F79F0CB79AF8FD35DF70FC6D8CDA7F5B
+:107AC00037DCCAF6C7FD7808ED4775E9793E0E3315
+:107AD0007DB896CBF9F74B6FC0FEEF6C1654184784
+:107AE0000AC53B6E1C45FB39F188C4E3302C2E39A6
+:107AF0008EBFBF9BB8D2801F13AF2302E8F3C43FF1
+:107B000012DCB735AE6629CEAB7EEBA038CF8675DA
+:107B1000528A5BB07367ECE8BF8F6F9574B84C9C6A
+:107B2000E6698179E684A304EDED84A3FAF23C12C0
+:107B300010B19D36FDF36B4FEAF305568E6F074982
+:107B4000057C6FF85244BA3ABB88EB015A6F67D98B
+:107B500000BCEFA6F3229CDAA5E9976251AC717ED6
+:107B600026E081F2EB0985E0F8F2C4523BC6EF5FF4
+:107B7000595A71058CEB9F7FCF7345AC73E011763A
+:107B80002981EDAF722750E229AED70A8CDF75E963
+:107B90002531F6EB6B38D670ADE1397D699C27D67F
+:107BA000BEC40FADCC0F29583A4250605EB64F208C
+:107BB000C0D78E073C973D37E3270F64003DDEE0DA
+:107BC00005F4B32DCD823B969FB1CAEA60F3BE07A0
+:107BD000FCB5B01FEF5EAA94601F7BAE7703CEABFF
+:107BE0006E87A02B7C67A95B88E7709758C866886A
+:107BF000674B75E9B7C603EEA7CE5847E97DB2C417
+:107C000084727E427621FDFE2A4230BEC0E3B50377
+:107C10006F269B22CF23FFC09AFFB095D6FBB0D52D
+:107C2000897249F6B804A0DFF5DFFFE500BDEEBCC0
+:107C30006446390EE0F31FEDBBAD9C4FA3E3DC6B54
+:107C400001FFA43C05F5C3E571A865C9702F01E5E6
+:107C50007B8C7554CD2F4DF250DB46E949B29BF039
+:107C60007E2EE276AB4E6DDF19E1EF45E8030909A0
+:107C700004F6A569F654681642F114FFE32CF610D9
+:107C8000CC3392CA69BF2909566261F5B54A67C209
+:107C9000E7AA719F3BC5652E1C6E22B8AF0D36D288
+:107CA00042FD9A9DD5ECF3DA4482F666ED635260AC
+:107CB0000DAD67A3D46685F849A65B2D80AD444918
+:107CC000928AE7BD0795337DB465FD3231ECAF5044
+:107CD000651FF30F7141ACF5BA8FC3FCF2BC00FC19
+:107CE000CA3ED4F50AB8352E2B6BCF75C082FE790B
+:107CF000D86E703FAC908FBB133F35B1FD02A1EB46
+:107D000071BF9DB68E66B41B540FDE1541AF3E9514
+:107D1000089ECF75D3FF72B52D7711F6838F93B977
+:107D2000C19A16F4DDC4912D80C76B5FC7BB38A222
+:107D3000ECC884373C6B80DE6F6A3F8C781813A2E6
+:107D4000FAC8E53352857B2A9CE13C94B75AF9FC8A
+:107D50008EDB9B94D271FDD1AFE53833F257D36BF4
+:107D6000A3BEE7AC76B598B1D60032C1D80E11BA31
+:107D7000E950B3C01EBD21827FDF994FF142E9BABD
+:107D800017F40EFCF38B8119809B0DCDDFB1827E41
+:107D90007CE3F1A3997E1DB1BFFA27A2A7C3CAF65F
+:107DA000873B800FD5FB2FF2F12384720ECB95EA2F
+:107DB00047643C44C3BD11E79A5EAC810B33B2F01B
+:107DC0007C1C01F98842230AD64C363A81AF9A7F4F
+:107DD000BD26ECCF26E2B99E554ED6DE1A59F3CB1E
+:107DE0005D16E8EFAAF882FE975B17F55EA2F3979F
+:107DF00088F3305EA90BE767DE4B0A09247F0B7E10
+:107E00000569EBB93A7EA5C4C5E05707E8D1F8FF8C
+:107E100027FB936DECCF836A777FAE259EDFB6514B
+:107E2000BB907B4F7D3AC305399C16890BBE5ED94A
+:107E3000937EE751FD06D72D4A9F0D7A3CB199EA12
+:107E4000B1295A8F5D7209DE5BE7DA6B437B67D439
+:107E5000EB8BBC5F5E1BE37B8DE8991107F37153DD
+:107E6000D760C05DB64A928B29B1D94191ADAFB60A
+:107E700026EBC691E8F1DD8F7652F32F35BFD2F8AD
+:107E80005ED8AFE4E38616CF148214FFB4DFF7C7E1
+:107E900079E6015FD738D9FC130E9A82BFFC03AB99
+:107EA000E70EA0CF46FB1007EB1A2342992C5E1277
+:107EB000D2E95B4FFA6533E84F6348C271CC4FC7D4
+:107EC000B16142CFF4F48B4B64F452AB027ECAC072
+:107ED0005CC21AAB26B8AF7B6036BB4766600EBB90
+:107EE000F7F1DFE3D87ACC7D716CDCD0D21F584B30
+:107EF000EE817EC912F19B73BE39DD402AC40FEFBB
+:107F00008F73DF0DFCB014B9B11F194EE21228DED9
+:107F100032A44601F6372455AA028B1B1236EE40D6
+:107F20004AEBCB2856F361DCCAA0B616E22019CD85
+:107F3000B1CFF56C8893BF5DBCAB29EA3CCA8638EB
+:107F4000E66F1F54687F938BD9799470DC86920F0B
+:107F5000FCED88BF0D3BDBF1195B0FF527323E1BB3
+:107F6000E75F2030E897C4F33F5488644DC2F9912D
+:107F7000DF04DF992C383FB2115723D8CF97E2584E
+:107F80005C759DE05A0FF99F485D16B86F47C3FFB7
+:107F90008F27DFEA92E82B8EEBCE67C39C95EAC36E
+:107FA000F320AF8EC9E787AFC51E740D6678738B5B
+:107FB000BAFDEF9ADC82B24E6E56888744DAEB78CF
+:107FC00005E7F71D429C0BE6431DCB0546A760E184
+:107FD000E703247D9C86DB436D1C78272E13E9B7CD
+:107FE00011FF18BC1FCCE2B2003D1AFDE173A4865C
+:107FF000739EC673A06959E1B84D3AEE932D51E0D6
+:108000008E2F72BED986FE97D7C1F4DF8887FE60B7
+:108010003C2E736E92F2AB15E4DB5FAE49047BDB62
+:10802000FFCEE30E90AF910F9D827FCC4158DFFAD7
+:10803000831C739F8896A6A50D28057F342D3D0DC2
+:1080400053ED79BD5D8A19073CCDF5EE1BE3B59E76
+:10805000580CF3C3D3D09FB39E77DE73A3BA776176
+:108060007CBC3E8EF1BB5ED1F8A826809E75E75D94
+:1080700009EC7E924476FF9093C97383CF522A49CC
+:1080800091EFB9D11FE947DC33E68111D82093ADD8
+:10809000886B16BFD1CE655043C7E497C8E8FAB9DC
+:1080A0006F4C29EC9F916DCC2E5DDC301DDB4B2598
+:1080B0000F588753BE2E2D31B920AE7376D19F1C39
+:1080C00070147C51466B2EE0FD88E8916DE331D44D
+:1080D0008DF3B76573954088422AA59E1A2426978A
+:1080E00019B8EEB8D01473FFB3DDC6E6DFCD714E1C
+:1080F0004CD3D20697968D8DCC0F44396978A47AEB
+:10810000985E36AEFB9C30C5470AB46FD4A74E9933
+:108110000461DD40B387299CFF9A3DD6F42105F424
+:108120000CD6014BA87DD4E43984BF9A8AF14AFC6D
+:10813000139A5FFD02E6038EEB0AD0DE51FD5F8FDE
+:10814000FA3282D96F2BD8D3883865E7DEF707C1BA
+:10815000FADF87DFBF100FEB407F91BAE2C17E9E4E
+:10816000BCFFDD783837F4E1FD2C5E7197611E3578
+:10817000C1C6ECFAA3B6926CE8D702DF7FE77A2299
+:10818000704956B3758DE501D1709E5C7F2F4F55B8
+:1081900063B2E19E1E3FD65BC5EFE732CAA192CB28
+:1081A00061F9B64D4A860AED7BDCB67E706E8FA013
+:1081B000BD3CD9148FF3118D9E45DBC6283077FA6C
+:1081C0004BB399AF7FB7CA6C5C7017C37A9687F3CD
+:1081D000CD48E7C17D36AC6FC9CFD8FE9485B4AD2C
+:1081E000D5D4BE7A9AD9790B633F967CA816F6A7A8
+:1081F000C25BF29080F36278FF7E3A4E79563F88F8
+:10820000EB5EC67E1AEFCD319E5FD5E653CBB8FC50
+:10821000CB8807F52FEA5C6B335B9F36C6FFCE1F1A
+:10822000CAB261FF6D3CFE914B26C079E81D87867E
+:10823000245CEE3EE533FC1E26B8571AD2933E82EC
+:1082400069B64D65F76434BF7D2FE0AA3AB81DEFDB
+:1082500019FBBAF6A6AAF99403F6306B7687FA9161
+:10826000AB013FA44CD0F997D59B2E286CBECBF820
+:1082700070077F7E07F4371BF659AB3F9A4CE57CBD
+:1082800047A57C31F21E32BF4D7FEEA6AFFDD5FA79
+:10829000A9F55B2BAFE2FBD18CDF69F8CFE6782C38
+:1082A000DB52BA6E0065D19ABD2706F3F368784EAB
+:1082B00047C397113FCB484961BA108193E647B154
+:1082C0005F9A3CCBEA16F2FEFBD3F8BA5E1AC48F73
+:1082D0007AC38D111F1D72DB60D067233E3A7AB8D6
+:1082E0005FE42736E62794A9EE4288675137769DEA
+:1082F00033C24F3929D51DBC0FF46C0BC379C4F8B8
+:10830000CB9CB9D7651CCF57C6ABFDE13E3D94DB96
+:1083100044D81760F6C37B5A3BED3EB76BA8047C8C
+:108320002FC2F4B4AFC435746877F9D2272E38C0A1
+:108330008FEE1C41308ED311AFA7F7773611E9F9D4
+:108340001D9743A5D4FA8F3F838DDAD28AFB1DDABD
+:10835000BFE471A02FCD45B1FAF927FE1DE1F786E4
+:10836000DDC5F54C9B972CE072BBAB99AD672FDA5E
+:10837000588AF230EED77A43701666D0AA3C8D63E5
+:108380001490BF513E4B5CDFC17D605172228FF073
+:108390007D011EDCA753562F62DCC328BF7CBB9334
+:1083A0009DA3576B701EB7428ABD0E79A5DDF4B54B
+:1083B000FA63ECC7C22601EDA491FE655B6AD70D96
+:1083C00020D07FD6BFE87E8406A25DE2FDD4FA55B8
+:1083D000465C78FF40D4FA50DBF524723FF5F2E6B4
+:1083E000C5B82FBF9AF69FB03812C68534FA357AD1
+:1083F0008DFD2814CFC81688E3AE165C609FA3EFEE
+:108400002773EBEE3F5CD8B07F20C8AF5D62FB66A0
+:10841000DBFD02CE0B3B3F206C7D60BD80EB693DF8
+:10842000CAAF99ED07EA598E350ADCE757B651888D
+:1084300029C765F5F9AEA111766A7960866BA88EB9
+:10844000DE46DC1FB2A2A154F77C809DC793B8FD25
+:10845000EE4DDF484D62CC3893A65F9ABE69FA971D
+:108460006F57D93C470A1CCCC804BBFE18CE4BA89A
+:108470005DBEDACED707E6D157AA9FB8A05B1F58DA
+:1084800092C7E4B3442CC6E73DD957CA079D7D1E69
+:1084900067D7EF7FF8B6FDD1FAA1E985D63FA35E95
+:1084A00018F9AFC5D58C7230F21FE882F9C11B7B79
+:1084B0006D810704D07746A77FAF15E9EC482B7094
+:1084C000C139C83FC00794CEEAF4DB315F239694EC
+:1084D000DA715EC7E74DE3FA163FC8E17ED64EABD0
+:1084E0007B2C3B4754920CB89852DB36D3E2A4F86D
+:1084F0007C647421DC2B3AE5B1B69910FA5EF2C8BF
+:108500009842B85F7ECAD6B6772D2EEAD7D58E2D83
+:1085100084FBE55780DD80F60796DB10573DE58943
+:10852000E7F27995BD3FCE5C329FDDCBCCCA2B29DB
+:108530008F2D743CAB3C3CFCF7A09F95ADC545101E
+:10854000B7A98488371DCFAADC8E902D9B8DE79329
+:10855000E87BDB6C9E5576F0EB2EADC5F1ADF2B04D
+:1085600084FA440EB1B8A844FB6AA5DFAD8DA37EA2
+:108570002FE5EFDA248B0BE6AFF4B91FE6B56B936A
+:10858000DCAA1AF15C931F7C0774AC35B175FBFD56
+:10859000AF0D4F68BBCC78BFDF4726C33CA4C5678F
+:1085A000C1D4589EAF38F17C44BE89C5358CE5BF37
+:1085B000D2EC2C51330017D5871416AFA67FE04FAD
+:1085C0005611A617D5849DEBAA3A4CF01C4BF5A189
+:1085D000423CC702FBFC3FD6E1F05F738EA51B5700
+:1085E0008C4F059230598AC0F534BB559717FB9BC9
+:1085F00046407F8818E78273186286A96607EDBF38
+:1086000078054D293F24A74B84FB5AEAA64E11E179
+:10861000BEA93532DF3F6262E7CCB5F69A387FB447
+:10862000F4B4BD6407C8FDEC5BADB936B67E81F32A
+:1086300061ADBF6B04371160DE7580E0F9809C147A
+:10864000D202FCB311771EE0ED3D7B12E7375B37BA
+:10865000A67F1990BACCA697558AF7571F5984FA66
+:10866000E04A30DD9349F36FD997B17C86E9422621
+:1086700085F0DBF67296BFC6746108CDBF6B5FCE26
+:10868000F2B0C04907B623F68A42FF486887E37D07
+:108690009BFB1AC0B76462F117E91505D753B47D87
+:1086A000216BE9440BF0F81ED84D88A7D416FCDAEC
+:1086B00006F1EA02B70AFB3D36F37B83BE69AAF1F5
+:1086C00055B49970FE0329F0FF43CE4F4D2EA4C937
+:1086D0007D0DEC8B258DEE6B601DEDB4DDD306F6C4
+:1086E00066EC1BAD53C07E37BDF3A75CBC9FFC0A94
+:1086F00056CFD837E89C90F6E7EC6F066D8A5C8F12
+:108700003E6DCFFF14BEA36240FF54509DE40EAAFD
+:10871000876BDC4455B260BEAC9F2F3611669FB6A6
+:10872000D94ACE825CC9C0108E5B45F6924EC86BAA
+:10873000F69CB426F5695F9B92BD5A847139292352
+:10874000787411D8FFDFB17B3D04B71BF773BE14FB
+:10875000BED78CED0FB1C1FE10D07F1749F3A7F241
+:10876000F8178B2F9394DC887930EF07FD7E1AEC95
+:10877000379F6063FB0768BF44B0AB63888AE958E2
+:1087800088676581283D98DF431A8FDE47EB7FDCE1
+:10879000CAE2499606A28B0F66C7B338CB4C078B4B
+:1087A0000FC6C98DB782FF10778E38C17FE8FCA550
+:1087B00022E1FE22C97923AE8F1D3411A0F7593969
+:1087C000E084F599AEAB247533E9AEAF93CB5BABE8
+:1087D000F77145BD0AE272731DCC3F7D369FE07E86
+:1087E000E8AE534A00D64D93322C3591F19F2BF9C8
+:1087F000770F390B32E321FEBC378E40FB13F6C5F1
+:1088000099400EBFDE9663053CBC043CA27C483216
+:108810003BEF86FA922E507A33F139DB272FA9638A
+:1088200012287F27DD6057E1BEA967AD8D37E07E56
+:10883000D0174C78BFEE4B8AAB14F22F9D579D603A
+:108840007F9FCD6C8CC3FEBC60C2FEBC14D775F597
+:108850004A4AF7C323587C4AB21109ECB2642A5041
+:10886000EFA6CF73E3D93C49B3D3CBE399FE3C2EBB
+:10887000103C0F2099F2517FB4FD3A9D5D04F7EB57
+:10888000F49BD52A028EE34AB5B851488478CFE4E8
+:1088900012827EDB64BB8CE772607F309C1B9BC2C4
+:1088A000EDEF940F2A713D814AE030DC7FD962E719
+:1088B000F768F175C5EB394EAE236D22F891D75D9F
+:1088C000222E88075D7F498AE9474EE7F53E23104F
+:1088D0002981BE977F51950077F944EFE74DAF2F7F
+:1088E0003C05E3E0548BE139F889488F1BCFF74F03
+:1088F000771AEE4F8EE7F3D6C16470E43E316D1DFA
+:1089000068BA38F209F4538B1417F065BBDDFD3EED
+:10891000AC7BFA5B6572B938E2333EB69F6FC4A593
+:10892000385CFFA1F8B4032EAEAEAFF35B69BFAF06
+:108930001ECAEA071C825DB9F29729C960E7CDF12A
+:10894000CCDE68A9863BC0973381E1CB39BA5B3F67
+:1089500057C567E27B9ABE01EEA09E3D72607EAC79
+:1089600075658AD75580D7ED7682F3B31FA55BE690
+:10897000829E69EDEC8967F837A6EB6A57EE87753A
+:108980001DFF676CBC9836E0921239DE7FE86438D0
+:10899000F3AA75336FA6FDF3DA655CBF49E5E78B93
+:1089A00022F1921E81170D771D7616EFD1F03375E7
+:1089B000F7BB223C9FFA1921CE4C129E8768F8998A
+:1089C000E267389C72888D13BDE1C7DDE59C06E641
+:1089D000310A3787186E0A283EF0F7B77AC08F1130
+:1089E000374FF58A9B2FF13CFCAABD532FBB6E1865
+:1089F000F4E9F77D1AD389B6D8FB828F727EEF56E1
+:108A0000EA6ECC067B7193899D7F9348C6AD14E7CF
+:108A1000BBE3B47BE56BB220BF5D62F6677BB31945
+:108A2000EDCF76BBC78371D7340B9ECB2692A70DB3
+:108A3000F6F5BB0658D4C8DFD1F82EC761A31C9A3F
+:108A40007802FCEFD798FCF36ECA811BEC487A19C8
+:108A500093C3B893CA2611E2428EFCFD80AF4FE06B
+:108A60004E2DC0C37105EF25AA3EAEA05DFCCDBE64
+:108A7000B70B21BEA9ED1F9EB0E7EDC28291F03E7B
+:108A8000C3D96BDCAE6A793C4A0176D2702FFDC443
+:108A9000F07926FDBDF225809FECEE72E37DEB734D
+:108AA000E084171D776E6D734D07B360BC6F7D4E0C
+:108AB000889D1F9B7DD43D1D4C65D47DEB1C0FB75D
+:108AC00091D65D7162F4FDDF747C3E160FF1FBD729
+:108AD000430AC4C11B959A6BD87CA2260BEC8FA6C7
+:108AE00077F847F9D6F8E108DD7DFFC3F8F8F38899
+:108AF0004B62F738B529B84EF82861DF35F271EBD3
+:108B00002BAEF739AB5E9C0FF6706CB91BD76D5767
+:108B100039457CFE1312B26481BC5C12AE7734CA54
+:108B2000EAD41342F77B442A1961A7E57BFAC58D85
+:108B300085F6EF70784C0EF02BA4AE43F0DD84493F
+:108B40003963C16EDBC7AC4D86714CA39BD255B463
+:108B5000D5DE4D87465727C7C91D8E8526C778F6AF
+:108B60001DD8A1E0B1760B7CAFE1A071EF3926FFF3
+:108B7000083C80FCBBF1202C80BCC6071B4FB5FC19
+:108B80003F1F0FA181209F1EF1007108C7B7C2438C
+:108B900016F055C303F5D7AE02FE68FE5AA3C2F61F
+:108BA0001D6A790D0745F67C7CCFA510DC3F44F6A5
+:108BB00059D9396D4F22AE57BCEC646D747ED83EE6
+:108BC00098BA9864B283F9EBDAEF898C0909E8570F
+:108BD0008EA106E10EF4E306A23D74717E9176410A
+:108BE000807B37716F7906F897A164D08B31E6E20C
+:108BF00010E07F876D4A06F88739B6C95980AF5DA6
+:108C00002356BD0E43D6AE01E52F6F51BBFD27CDD8
+:108C1000EEB5F06AB5F66F7430FB74BD9B9D0F0224
+:108C2000BB1D498766FF412C4087109A63FACA86AC
+:108C3000F6BAB90DEC39D041F9BA5F204DE01FE426
+:108C40009BDC2953C1CFEB179280CECEBD5F0C8643
+:108C5000386571F3AB4781DE626D3DD4A55F0F359A
+:108C6000FAD19ABFA3CD2B347F489BCF82DF04E596
+:108C7000D9FCB9D3CCD6AD26872C786EF9F1F3EABE
+:108C8000556EAEBF12ED4731EFC72DA415E9D2EEF8
+:108C90001DB999F3A3F8109D876643392137513EDA
+:108CA000DCC4EF1DB9C9A5BF57E196BCD8F78E68E3
+:108CB000F5F4F6BE717CB8D6B06EF46DD3433E7653
+:108CC000CFC87FFAD83C77D210D12FC1809A97CEE7
+:108CD000EE6970323E1C52628F57FBB9FE4E32B5C0
+:108CE00065C3B9E5FD7BFE8EE3E32B7BFEFE1EF83C
+:108CF00089134F4904F6B54E3A352E01D7E7F3D222
+:108D0000703D59ABD7FB69938DB0E7881FED77575E
+:108D10000E527ADC0AD067C1F4B7671EFF29D477F8
+:108D2000F1B84422CF4D142A9EA110C72DE4BFBF35
+:108D3000735060FE92567E90FFEEC5F31CB7B021D3
+:108D400042BB8FC41C21E79BF83D199A5C6F3A59CE
+:108D5000744ACA8E960FFCFD33E20B5A5CA199F35C
+:108D60008FB4FC11CFB77CA7E96E09FCF3EFA4899F
+:108D7000C41DD1EE0C95CEE023E21C2F3B0C7E4AA5
+:108D8000CB733FBD998E2BDE3744DC4AE86DDEFEA7
+:108D90007A36E45BC598F78F18F9FB9DE6BBF1FEC8
+:108DA0009121092AD2D35BFB93AEA638190D722705
+:108DB000CCCFCB65F77718E5FBCA9EFF486E1BD971
+:108DC00033BF7B92BF510EBF3D5380EB4EBDC9C335
+:108DD00088DB7DB49F7EDABF10EDA79FFA63AFF802
+:108DE0009C98FFBD2F0DF31A5EBD7B9F4E067F4EF4
+:108DF000C3E9F464869B89BB7F9A4CECDDF232F2C6
+:108E0000ED7307F36BE610D7EC9BE93F770AAE787A
+:108E1000B4177ED20AFBB34A388D730E17A2FF41F6
+:108E2000F87910E33836471C89E7DE7BFDDD9BA12E
+:108E3000F932985BE37805BFC702B8368E53456FA9
+:108E4000D449E0B2154AAB981DE37EBA469751CE9D
+:108E5000474809F6A3273A8D3830D2ABF9E7DAEF65
+:108E6000C0507E4C4FA2F5DDAAE663FFA2C661CEDC
+:108E7000979EC6DF9EFA959CC0E3DE1CFF174E4E00
+:108E80007B0BD8DB93BE19E5662CD7EC47213490D9
+:108E900083A91FFC912109A9A80F859714E2A6E3D5
+:108EA0000C19A83FFF4E8AAF40BCDDE364CF7AC205
+:108EB0005BF52513F12477E34E0E3E6603DCED9659
+:108EC000EA6C101FBDCE5EBA06546FDAA705B3F088
+:108ED0009E8736138190D9F4E6732D1047F01E2536
+:108EE000783EA0A079FF54C0E9EFA5569C47755E77
+:108EF00024E4B1083F33D8BCC6067E5830859D6F48
+:108F00003B984874FB90F72730BC068F9FBFD91D54
+:108F1000A3FC122F9F49DC29D9382EC763FCA3700C
+:108F2000BD09FB3F4D701D4801BF659E80F385CE96
+:108F3000BD130EA4507A3BEE4C443B333DF8E0DDCC
+:108F40004E2A88C6FF1E8BCFBB160A78CF40A1EAF7
+:108F5000C27C615926EEDF98F08FE499C5503E43FC
+:108F6000C6F9CD74B1528278D4D9342107E68B7B0F
+:108F700084B65AF81D5C7F296B8738FDC930FF7CA9
+:108F8000A738790CFE769CAAE587E1EF0312C33C73
+:108F90006DD5CE0BFBCDB47CD56C01F7EF4E77666B
+:108FA000107F047E0AD753798EA5B86CEE5F00B8A7
+:108FB0009E59A43F3738BBC4460291EB168213EF8B
+:108FC000213BC8F7697709FC5E7CAEE73770BCCF00
+:108FD000999BACFBAE94303FD3BB5364F771E4B3C1
+:108FE000DFA1D6F4EB46AE8737F0F9F13C4F868E21
+:108FF0008E6288D288403F5B47BEE5621B0ECFA5DC
+:10900000E20787E7D3F66E1C6198D78A956B111734
+:10901000696C1D6F36EC8213C16EEADFBB254F9F72
+:109020008FA1C797B5139A3D98BD57C475C3D9F999
+:1090300094CF0289F2D3BFAEBD9860721D8078D004
+:10904000AD97DC788F4E94BDF8A0E81BD98BDF502C
+:109050001DCCA37AFD64021F370791416037A68BB0
+:10906000DB7E0A38EAA4E3A639068EB471479BEF8B
+:1090700017523D06DC90336C9D65FAA534DCEFA4F5
+:10908000CDF7C37684FA25AE18FED26F12B274F70C
+:109090007A84ED4A845F22E77E7BBF643AF5479588
+:1090A0001CA06F20F18F457B8671C942D81805F14D
+:1090B000C1B47318E7F14A74FE8AE3F3D3882FB082
+:1090C0007F4252B77E18FD152DCE3CD6A9F9537AB2
+:1090D0009C84E38DB3D87DA51A4E0A819FA0FFB36F
+:1090E000448CEBF4861BADFDDEF012A2F6084C5664
+:1090F0008F78E1FAF775F1F2176D7C194A86F6055B
+:10910000271A3E34BC18C79BFF34C4837A1A6FBA3F
+:109110007A196F0E8C90D1AEF7E6D77CEAE4F3EAC9
+:109120000427A6375C351B7F97682CD811F037F9D8
+:10913000B8158E6BD5339C1C685B24C1FA9117EC73
+:109140004766B71CB478F0FF00C6C481D500800024
+:10915000000000001F8B08000000000000FFBD7C25
+:109160000B7C54D5B9EFB767EF7924334966924940
+:10917000323C841D082121090E21BC1137490811F8
+:10918000A20CA8888FD6011F6020094DADD5536F62
+:10919000332181526C3D58BDD67BF4F43758ED41F4
+:1091A0000D75080183277026A098F0D020F8C07AAA
+:1091B000DA6829451B92185A0F6ACFF57CDFB7F69B
+:1091C0004E662683A5F7DE73879F2ED65E6BAFF5BE
+:1091D000ADEFF95FDF5A9B4AC09F0A50B315209844
+:1091E0000650F9E1864A4806E83B20011403D4966C
+:1091F000C9411BFEB5B4FDB1C745DD0C5689DF5131
+:109200006126C0F5207E0B950EC5E60658E695BC96
+:10921000721680D62EDEBFE19225A862FD7AAFF9E4
+:10922000E31E9BE8FB35FF5F03C800B8517F7F1941
+:10923000FD0FFB2FD3A460185F5D363BBAFF8D97FF
+:10924000CA3F91A6022CD7629EC34F3E93A7F2223B
+:10925000CCBE24AC5744B78F7326B9CFD9F12FE3D6
+:1092600061FCD732C0C5F3656F51F7AFE977EDC840
+:10927000F2483D526601E8ACB77119DB5E6E017FC2
+:10928000C881254D50C4650052010A9DB8981958EF
+:10929000BF64010DF9086313E0F7B93A1D1386DFC7
+:1092A0003F88E30770DC308E1FC8013854EFE4FAC2
+:1092B0006BF51EAE5F93822FA4E37F87BFB0A8B883
+:1092C0009EC5EDDF51FC38DFE24B0A8F3B9BD69306
+:1092D0004F0B8371B49E3FF716FDE30D30DCBFB634
+:1092E000FD338BBFF0F2EBF95BF3E7A7A83C3FCD72
+:1092F000AB150CCFBB44011883EB5C9A1BCD5F63AD
+:109300009E58F9C6CA6FB9FE7EACFC56C4ACC79075
+:109310000FF4A2328D8AC3FF4B26D0A65F5E7E4338
+:10932000F2B1F8B3BD0523DB017EC9721A1E4F9757
+:1093300017742BBE42419719F5BA52B70BD4EF40C0
+:109340000ACAB9B213C28948D8F5E72B3E51A8F42E
+:109350004AF071943E037C6CC85B1E1E7FD125E4ED
+:109360006BDAF0BC8B146477113D1F0B8138EBA8CE
+:10937000A17114EA1F60396CD9615A15C2755C631A
+:10938000813B7D54268A32E094B87D93D3C4E3F6C2
+:10939000FFC56682AB015E3E985902489FD7EA3C02
+:1093A0000613014266E0F7BF4E52B9DFE6240824F7
+:1093B000E0FCA074DBC85E9412805CB43B65B4250D
+:1093C000D88843362B611FD961BF578106B4DB2F84
+:1093D0008DF70E056E0714C9E68F734C8D59F47E18
+:1093E000B87B1EF69B55A4A8DBB08BCBAA7E87DA90
+:1093F000FB0E589DF45EFFFEEF7798699CBF8017C7
+:109400002984D70E5881DAE73BCC41F21F8BE4E385
+:10941000B209EBFD030056EC3F7F55B814506ED7F0
+:109420004077A313CBB924C738F27B8DD69BCEFEF1
+:10943000C3310AE5B44097D302DD6F951E90D98FF2
+:109440009426C941C81AF653D7EA325A806C253A95
+:1094500016B4E17AB1FDDA4B4A5CBFB4481F77E13C
+:109460009F4121935C08D17ABBA84DF8A312D01478
+:10947000C0294B6D31EDE497909E45CEE8E773C966
+:1094800077A25EEF8EF14BF833D1BCF73BC5BC8BB6
+:10949000E4BF26F7E0FA5FB668EFCD437A074E9A4D
+:1094A000E1597C0EE7B13267245FDAD0AE83399799
+:1094B000B78BFD07133515E97999F4C741F5D19AB2
+:1094C0003AF5F2FDA7F60C94607778B97985021326
+:1094D000581D4F7B3286F93D82AF3AFF63F9D9229E
+:1094E00041931DF9BCB0DD5B46AE65041F3B918F17
+:1094F000F85EC980C6F35C291F0DFB78F95CA246B3
+:10950000FAFEF2B9D11ACDFF2AE96BFAB0FEEF3FAD
+:109510003B9848FE13F9A82AA817032E9BF759D6A3
+:109520005FA1F7A15139C16D586FD1F5FCE5C48138
+:10953000A3F9C4EFEB4DDE67691A65E3C41585E452
+:1095400037B7969CC577240DA407D17E24D509771B
+:10955000601940FB217D0BA402EB93194240F336C6
+:109560006AF034950BE6AB29C4EF411CB3DB41E351
+:10957000A929A4E7F0D78B337D8523F9DE528F0A22
+:1095800085F3B4D6DB34251B605FBD93EB6DF51E10
+:109590002E5FAD57B9DC742CF9C1208E53AB593412
+:1095A000256DF87D57AAB08F05E86788AE052005C0
+:1095B00003A8730B1ED6F55E91829B249213AE27EF
+:1095C000829F2897C19EDC08FE36294D9366B235EE
+:1095D000B0BC8BF24DFC3E06FFE0F35923FBA3DC4D
+:1095E000A3EAAA4B627EE6BAB42417963F74F852F7
+:1095F000A86C916E397C01B8EE12F55BE50B38FE74
+:10960000F4F0427810E3C374140CF1157FB713FD26
+:10961000333A2C40F2C180CA7659A4D3A37D2E4997
+:10962000E7703E329DAFC7E07BD6CA30E9D13EE855
+:109630004923BE17DB7C76B428A443C855936EF645
+:109640004838DE9C748B5726D226FAA66F44FE75E6
+:10965000A4E384D8BFA32363AC8AF6A6296FBC4FCA
+:1096600076ADD91C61812BCCBD3D11713C139E712F
+:1096700052BC229FF635F2BDF377C901F66B8873B1
+:10968000C88F759E4AF686719E6B2ED9BC56D27FC6
+:109690007A11EDF56062F254F2CFD05DC6EBB8D628
+:1096A00026D6916FF617BBD89F850F9FC0F7FE6D2A
+:1096B0001080FCE935DD1FCA80F4949AF2327B9069
+:1096C000CEC3D2E4142A9FFC5D720197A7927B89D6
+:1096D0003F074D7695E67DA75E2DCE467DD1DE72A5
+:1096E00098001DD682B71C0A9527EAA1381BF5E51C
+:1096F000AD7A1B9727EB9D5C9EAAF7707918DB4922
+:109700009F5EC776D2B737B09DEA5DD84EE5311C73
+:1097100097CAA2DB9378BC96DB922CB48E83C9D017
+:109720006CCC4FFA144E0CB78217E03F1EFB6AABAD
+:10973000ED2A8C97567FA1340DF9F4B3AF2A14ACFF
+:109740001F5B3CEEA1BF60BBF967A61FDB90DE9BF1
+:109750004E395A8F63DD9EAAFCD841FA792C119DAF
+:109760002399B5B94B433AA6936F1CCD6CD760369D
+:10977000D6D3F47AC07C5DD97C8095A53DF9E042D2
+:10978000257159AFB3217F57DAFDDFA3BA25B0ABFE
+:10979000A2EC2AAA6388247B97CC41B6F7B1927BCE
+:1097A00005C6BB950EFF7F12BF0D7BD1A43FA491D0
+:1097B0007F98A949E072B3BC8393A4E1E746BF95C3
+:1097C0008E45FF49FABADE25B37DCD982F6941C792
+:1097D00048FB35FACD38AB9691FC669E2F6FA2728E
+:1097E00059858BEBBE55B39AC8FECB1C977BBF94B3
+:1097F000DF7FD06566BD2D51B05F9C3868F49B8ECD
+:109800004A46B87BA02B31F82CE9F5697F6312D664
+:109810001779B28A64DD3703D75D3BB6517BE5EB40
+:10982000AD6C57DE242FE1F299A89069D8BED02103
+:1098300079C3642AF33F6A4AA376A7E425B62DD4F8
+:10984000A69D28A6F66CD9BB90EAA7D5320A51A7E7
+:109850009485F32E60BFC5B9295E1BBE772AFCD064
+:1098600045D2DF85B949DE04F2F34AF0E91AAA7B52
+:10987000ADDE0695D6F15869328DA34A5E13D65BEC
+:109880006E28FD1F4447892F052489DA5D0AE1D738
+:10989000277FF7C33227F66B192701D9CFA970DECE
+:1098A0009F88FE859D896A02F9698BB38CDE6BB156
+:1098B00048CE4D5CF79552FF408E597D1EC73D7EC8
+:1098C0009B9DE341E55B058C838EDF3686E342E5B5
+:1098D0005BF34BA83C6E1278BDF2ADCA0A6E3741FD
+:1098E000989C4AE5EDDFE2F7B697FEB0CC8DE31F1A
+:1098F0001BEF62DF82722A5622FC24F60789DEBF44
+:10990000BD9AFB7748990F9DC5FE170B528AAC385C
+:109910007FB93B21AA7FC55857547D49F6A86225D7
+:10992000C24F56166445D56F28968AB323FAFBE6D4
+:109930002744D55794B98AB323FADF54392AAABEEB
+:10994000F2A6ACA8FA42D31CE13FEA617E99B0F3DB
+:10995000F965D9208C89FCA953F47D03DBEF263B04
+:10996000EF12F8A9C885F809E552D655CC71B9D8D7
+:10997000AEFBAF00747B6692FF17BF2E1C8FDE8399
+:1099800020FE99497848FC1676231E207CA460DCD2
+:109990008EA0A7CC111DC72B40CD27FF5BD1B9846A
+:1099A000F154B96779199A31F231FABD0AF9618136
+:1099B0004362E82EEA32C7A5B7626CF4FB06AEAB91
+:1099C000D0E96B31F99B52098B05B46EC235C67A6A
+:1099D0000C3A2EB79E0AF98E3214FFDF5C572CFD2D
+:1099E000001B797F114BD7A04BC78188A71807763A
+:1099F000A6323EC49F3B1E3E30704F25FA3757A417
+:109A00007F7348EEE58597F76FC6B897C37BC6B8F6
+:109A1000C6FBD02CF3FCC6FB43CF5529FEF39DD8E3
+:109A20003F29CE73B714FFF973D1FD17286AA3033A
+:109A3000EDF82848DE00F1FBB8AA10242B3DAD3527
+:109A400051B9E843BF427874F1D9401395F37A8352
+:109A5000C7ADB8FEEB726595F20D061E8A5DD78C18
+:109A600054B14F3A7A49B5ABD8DE1250EDB4BF6865
+:109A70007958B5D33EAA45830ADA2F6A134D1B697C
+:109A8000BFA1E56389F59C54E1E7F352058E31CA25
+:109A900067657F5E2A96D5B69E47098BD47C316078
+:109AA00021307094705EC1489C7754093A68BEA317
+:109AB0000F071DBE083F7EA5386F14295B3AE9A742
+:109AC000A445FA91525B8216E93716395D51F5AF1C
+:109AD0009CAAD8C77B4645BD779D9A15D50FF16BDB
+:109AE0002EE1A0460BE42AE4474D895EC277B17CA3
+:109AF000FC177DFD5E8793E01398DDAAEC8F13972A
+:109B0000BCA5827FB1CF57A48A7DEA6F683D586EAD
+:109B10004F15F435C93E01E21037933EC4D6714F5C
+:109B2000BA8AC6C3913DA4775EBBE922426FF84E64
+:109B3000EAD5D729A8CFDEE9A6EF4EC4FA23A98B30
+:109B4000447D9E69CF04ACFF34B55CD4AF364D374D
+:109B50007B017E058BAF2BC37ABADBE74FC579FB60
+:109B6000CD8EAD12E219C52441917B78FFFB8805AB
+:109B7000E3290A16954C7321AD76ABD82FD724A0D4
+:109B8000FFA3FE259A4AFCAA4930E4DC9341711DEB
+:109B9000EECE3491BF30F66F760BBE87EFE7D8FC80
+:109BA000B5425FC2C92AFAA5FBF72FCA24BDD89EC9
+:109BB000EAE4F5E7EF99E7217F85747D97FAFD7F69
+:109BC000A46B533CBA9ACC629EDE96FC528ABBF9D7
+:109BD000E3511CD2B0BC70BBCFCF1342A82B8CCBAF
+:109BE000358F84F54697C54B387DFB907CAFAC6CC8
+:109BF000D4F313B25DE88D9C62DAB81BCB9FEBFA0D
+:109C0000F214CD3B83E61918B71CF5019C03E3560B
+:109C1000148A3AE9832C170D10DE1EF8569297F736
+:109C2000C763077EFB03ACBF7747BE9770F4078915
+:109C3000823FAB82131A7BB03ECD1ABC2A8C743E95
+:109C400094E67F96F4E0366B7012EB9B6363128DA3
+:109C50002F69C0FB10637F87FB38D5327124EE1F5C
+:109C6000392FD888CFB7CC117C36E6459EDA28EE5E
+:109C7000BC375B3C37E8C0F95B88FF063D4374C0E6
+:109C80005827C7031079A445B243E461FF60E2BCE2
+:109C9000492D191FD6F79C35F1BEAECFD85780E6B7
+:109CA000583D939B789E392736C94C6C00FFCCD425
+:109CB0005948AFB6ADE77DFA8CEEE87DFAAC4E7F41
+:109CC000A903DF9BF57EFC7CC83C7DDCD910942980
+:109CD0005ECFE989EE374FDFA7CF3B1FFDFCCD54A8
+:109CE0003DBE8D86D191798E3A7DFF33787C420AD4
+:109CF000E929F93A19F96E5165989D3AEC375AEB12
+:109D0000B15F0EF9471B9785A79D7711FD6DF5A8EB
+:109D1000D016F2931E2E0D7B2A3C0D77C2D4887983
+:109D200074BD37F838F8BEE0E3B49EDC9FCFC7BA05
+:109D3000B9D30C4175789D73753E0D82E0F3A0D3C5
+:109D4000C27C9ED9F5CBE9617C64F598408D585F63
+:109D5000829A086A843FB5E7A646D565433E3ACE67
+:109D600098AE8F9FE41D1D358E81370CF9BD9A5A30
+:109D7000DE493864BA631DE38E94D913A2C62D3E22
+:109D80001E2B27641CE17624F29F08D79F56A270F1
+:109D9000C62C77803800B33F546270C97699EC685E
+:109DA000EED9E8E7E6B4CBC8ED72FC84A93F9FEF9B
+:109DB000FEFBF9E9D2A2F9995611CDCF745F343F79
+:109DC000335745F36D943F9A2F63D64D896ABF6A26
+:109DD0006351547DFC8373A3FA6761008CAC4FDC44
+:109DE000BA24AAFFA4ED2BA2EA939FBA2DAA7F5E04
+:109DF000704D547BFECEAA2B927F61A82EAA1FB174
+:109E0000D7F40DF2BFBAED1FA2E6F9EF96FFA23428
+:109E10003D2FAFCB7F998E435C1AFAC7A2E138453C
+:109E2000E915F293AEF637BEA0FC4BA044E5BC5357
+:109E30006009781BB1ED09D927915F1B83AC36A16E
+:109E4000DF6832C13AF2F78F9A4C9C8734ECBC2A17
+:109E50004DE08BAA34E1F79F469BA6F866F0CFEC65
+:109E6000DE9E4478433699A09BE29AE265BF71C6B4
+:109E700001E16B713E7934705EAB3479F6B299A82A
+:109E800087F29B32EF1FE5D17E50717D8DC71F3F5A
+:109E900041F99F8B0E9B4AFA2AA7FA0314B7707DEB
+:109EA000A1E761245E79AF3E3C89F649467D95671E
+:109EB000E366EABFEA8E859368FF3AF4FC8E8E492A
+:109EC000651172885CDF8A38F8E87B69223F67C4D5
+:109ED00087DBAC6A630FCA6B9A2CFC3FC685EFA583
+:109EE000E1FA3F901E360B9C1530D3BA314E72DE2C
+:109EF000DF8580BA0ECB94E178A47E8D4AF5C184CB
+:109F000068DCF9261144FB085B2AC7FF5B0D7FBBA9
+:109F10002E8FF936E888EE3F78F744C1CF6F23D70C
+:109F200090DF672C621D06DDE7753FFCA9EE877B9D
+:109F3000C9FF46E49BD7ED783C89F0F5995C81A791
+:109F40008DE7CFE8727D264DE0E9F53B139C9179D2
+:109F5000C7EA902BAA5EDB36CA7936420FD71BEBD5
+:109F6000F04B0AAD63836E3FD59D3DC9B701E3F168
+:109F7000A7D370DC9A1D17BFBD8FDE370D648838FC
+:109F80001AE0F96E790F18D7DFF21544E1D297D2B3
+:109F9000447EE525A20BCB95583851DF56626C778D
+:109FA00051F9C6FC72B23B7C1E96B0BEAC13CC8499
+:109FB000D396FBB3CCC4F453E07D672F2E6D5F9A2C
+:109FC000CAF3DC043E33C5C577BF5D9D44FD86C63C
+:109FD00033C61943B959D42B57C09C41F99A6B2405
+:109FE000C60D389F8D9EFBEE18B399E2AF31DFBBF3
+:109FF000E0BFF00EEAC50AF0F2B8C6F800A9517E3B
+:10A00000F803CB901CED24BFBA2E5398F239756734
+:10A01000AC7CFED1DF30F0EB0790CEDF557DB15741
+:10A0200042BA7FBB7AE057FBF0F9AD4FA1DFC5B56F
+:10A0300066DBFD87D322CEC3CEDC7D91ED0CF1C86B
+:10A04000F34F92337AC9EA25FBF8A0EAA59C48BCF5
+:10A050007F226D6127BD07B3D3E29E47C4EE2BABD1
+:10A06000483FD96E55C699865EDEA7EB65DD0B933A
+:10A07000F9795DD2D07A44FD7999F3577507ACBC74
+:10A08000BF7F47D787AA17BF9819999F6B41BD54C7
+:10A0900073A8747249E79C2AF266CFF1C1A9D46F04
+:10A0A000A3ECEF213D3978E9E364AAEF79F34B5E45
+:10A0B0000FDC7465F4F723F322F95C9B34F02EF97E
+:10A0C00093EA7D5695F250A5FBF28EDD8EF59A4E01
+:10A0D000F43BB89E0BAE9E234FD37E6ABF04949789
+:10A0E000AA0927B073AF69958294C7AA6ADBBD65D8
+:10A0F0000CD6AB9A971793BAD6260B3F56D32205A8
+:10A10000693CF0A7317F8A74DB287D35EF1F0BB0E7
+:10A11000BDEFA818FF5C7D78EA59F44F7D2D9F9D17
+:10A12000233A36B459393F762E296C1983F35ED819
+:10A130002D8502EAB0DDF6B9C43E6A5DE8310BCD8B
+:10A14000BBEEB9E5D9040FFBF69DB4907F5CD7FA5E
+:10A1500058B9FEBC5884FB20DBC5FA9D1D9322F341
+:10A1600049F721FC83C8F881F40508F78290E309D8
+:10A170005D3EABDA273612BBD0AFED7D5A62BFE64B
+:10A180007493DF3BB8EBDFFF95E6DDFF2F9398FF7D
+:10A19000C557C67FF005184FD4E8F3C0F95316DA57
+:10A1A0001FD6B49ACFC53B17FABEDB77957BC6F0B6
+:10A1B000FE3616576FB18038B79900C1E7291E38AF
+:10A1C000062CAB919E1F5107A447710E58D660DD37
+:10A1D00046764671C2E308C6DB17D7B9159E0FF75E
+:10A1E000081BE39D57D6EAEDA56A8F85F270359E70
+:10A1F0005E0BE9754DF813715EDFF651B91667BF56
+:10A200005CED167ED3D003C3DEEBD2A7B05D98879A
+:10A21000E260C8C6765FB86680E253DD7ED40EDAAF
+:10A2200017B8FC034477606F824AEB2BDDF7C9CC8B
+:10A230009E8879FEA4DB8751AF79F9A3A966E2E78E
+:10A240009E8FA62A49C3CFFB321CEBE2E555AADD5F
+:10A25000224E6F4EF69D8FB683046F18E7AD69B737
+:10A26000F3F907DAC1968EE2483BB875DD0ED2F3FA
+:10A2700076D98B1601356DCBFD0DDC3FC94BE291D4
+:10A28000DB1606480F65A78FF513FE8AF3CDD4CFF2
+:10A290007D2652AEDB7F1BE991E2084F8ACC6BD45E
+:10A2A000987A7ED121915CB76B269AAF08D86FC996
+:10A2B0000E5F0FEF9F8A3354DAC71E9E510EC4A75C
+:10A2C0009F1E90385F6B4EF56FCD22F91E95B9BF7A
+:10A2D000E5F00B013A97EE9B06C5449FB1DE9F4E19
+:10A2E0000B838CE36C2E042F4DBB79FF2D1ED2DF28
+:10A2F0009FA61F617C61F78680FC4A23E206CAE7BD
+:10A30000D80B42611A2721D7572CE33C796E27F3EB
+:10A31000CB62F57B291F944D755C874DF1AD23FA17
+:10A320006CEE44B19F1E7B6579BA3EB27F85CE1B31
+:10A33000FD9C2FE9330B3DEDBB0A185FF31D9D39E2
+:10A34000D4A409BEC1762E6BDB3AA646C6DB44F028
+:10A35000DBE879DFFE5BBC44BF3951D7F78C44B6EC
+:10A360008BD8F9FF99F499E46E5AB3358BF84C7C8D
+:10A370005347F67B5AEF67F003147F2ED92B92AA2E
+:10A38000C5CB0F8D77973C4E72DD9CEACB7515F0EF
+:10A39000F1AC00C39EC4B87687FDFF5764FF1FE988
+:10A3A000FCDCA2F86DC4DF4D7ADD6CF1A94EB67FFE
+:10A3B0009F4AF30FAD6F74FCF5B5E9F6BA6582FFFD
+:10A3C0001BD7B74F5F9F3915F58DC64B06EE674E0D
+:10A3D0000E0648FF9A92A078133E3EEC2AF790DDD5
+:10A3E0006D39F4C538B2F7A624AF0728AF7560D62B
+:10A3F0002AB2FB2DA36F63FDFFF485BC2239629E58
+:10A40000136925ADE4BF7E69ACCBE2CFA575FC42F4
+:10A41000D723635DE96EDFABEE88BC118C755F916D
+:10A42000FE80BE9FF3EAF117F7739CFFEB87442F82
+:10A430009D27EED671B7023ED61B3B7855C6551AFE
+:10A440001CA37B1F8D1D26D846CBA6E454C4395DC2
+:10A45000B26C32367D9A0DB7E6746C4CED6FBAEB88
+:10A46000963421BDFB21200B7C169DAF004DD2A45C
+:10A47000C83CC56B55F1F314CFF81BC92EFF569E8F
+:10A48000624ED8B4DA92F2F7E72BCEBAA3F73D9F2B
+:10A49000BA55262A942BF431144E0C8ABC174CA7BB
+:10A4A0007D5333F112FF7B06D7CAF62DF5E5DA5C52
+:10A4B000684FEEFBB76D1D8B76972DD64FF546FA9C
+:10A4C0007BA7C03D43F98FD7A630EE463F27F3FE6A
+:10A4D000DFA9D31223B762C46BC0F78852A3F22757
+:10A4E000E1235F26937EED4A55DF22B90C74C97CC7
+:10A4F0004F2441E9B1B8E2D8D93EC203E8F78BD383
+:10A50000C53EC4D626CE176DAAC67E31C1E99C26AB
+:10A5100047D8C579B7C89F571FF9609C0531DC053E
+:10A52000D3F1E4021C7FC3DE96644AC3AD3FF3F669
+:10A530004CBA9253A2F81DE9B8FE4FA51D3936C298
+:10A54000A95B8353893FA1F08414F293850A049494
+:10A55000A238F1F1A922DE14D73CC587FF50D83EBE
+:10A560007D2DE1E5DAB0582FCD61C6A6BC36E07A84
+:10A570005F5B632A8D57FB6F074693BF7A295DE0C7
+:10A580009A172F4D11EF2BA050FFAC7497AEE741F7
+:10A5900013E50B5FD2F38C7D974CDCCF98BFB06D89
+:10A5A000A1EC443D28086F3FC479CD76AB4AF24D0B
+:10A5B000780E043FDA131877D61E5C0C14E7FA5DA8
+:10A5C000E095B07D57E2C06F491F060E58553A77A7
+:10A5D0004D706E87541C7F977E4F2B0F15B2C5317F
+:10A5E000FCDC982FA1FDE7941324BDE0F3DF0465A4
+:10A5F0003B5CE388E47712D35DA2EBD5AEC4B089AF
+:10A60000CE450626E15E87E91AA613785E83CE3C26
+:10A61000F6FBBB2C03E77EE066BA9CA4077920E832
+:10A6200084F6C92AF9D104A7C6EB4870AADE8034A3
+:10A6300092AEDAA908FCD06E1E25E73577D8AE6B4E
+:10A640001387EB36B4855D13403F8FFFD5363A8FC5
+:10A650001FAA9383993DFCFE2DE92F6C6B1ACBF951
+:10A66000BD808CA2B66399944AEB54797DE845B5D8
+:10A67000F422C107BAAF67B789F6A1FEA8E70EAA10
+:10A680003B443FAFD5695F92C5F64287D74378F028
+:10A690007E297CEE5AB4D7DEC77C2905B8AE5ED3DE
+:10A6A000A1079AB1DF9F568772E83EE97356FF1AF9
+:10A6B000D2CF573E5CF34821F9DB5D666F25F99DEB
+:10A6C0009EC0CF1887BF6856B745D81D8C1DC8E0FF
+:10A6D000FB8031F3D49ED9F433C2D7FDFB2595CE50
+:10A6E000BDFBCD03E388EE9AF63F5AE8BE64EDFE6B
+:10A6F0008F184F4B19FE1A9A6F765B03DF6B9B0323
+:10A70000DBF95E1BFA43BE9F18F2087F32783AE706
+:10A71000D98608393C912EEC0D06FCE3295EB5EB99
+:10A72000F67A90F6DD58EEEDB875228DBF57CF075B
+:10A7300018EF35C0A131C4F74DF01A97C6F3FEA04B
+:10A7400052417A96FFAEED4E2DA2FFA3E902BF3D26
+:10A750009A2E70667686BF89E85DDFF1B12599D6BD
+:10A760007936348EF6B921454D71C6F12343F61B77
+:10A77000634FB5CA8085FAD79E07F62B28EFA6143B
+:10A7800094DF4BEFB64D598DCFF7A24C5228AEE275
+:10A79000FE94E2EF5EB36F0CF56F78E7F3A9E4C7C0
+:10A7A0001E484FE7F57F7E60FD78E21BEA7F492275
+:10A7B000D9D96E60BF66D86901D929BE5F40FA5FFA
+:10A7C0004CF53CF6CBBB2CDD4BD82EF79A80EC1227
+:10A7D000F59FED01F5DF49F8AEC089F6C0EF4F6691
+:10A7E0003BDFD56DD21827A35F9FC4F5921BA9BE8E
+:10A7F000ABBBCCC9764EF7058AC85EC387789C1080
+:10A80000C024129D04BEA8FC883B99E936FCE5E70C
+:10A810006ED0E3869AE2C575D86539CA3E22E2A4B5
+:10A82000A81B71F4C933DB9E407B81EED428DC0F7A
+:10A83000EF0BBFFF5D3D56D5BD3E775933AEB3EE4E
+:10A8400084CCED07F57D5E58D793437A7E86E28609
+:10A850003A5DDCEFA5E733B04EF75D676A1B4B0945
+:10A8600063CDAED87E98CAB9BE502941C8F9ABBAFB
+:10A870000F9B8599E793FEB51EBA2E9FEECDF59FEF
+:10A88000B1420292D8FAE5C06F5FC4B53D7010F9CD
+:10A890001F274EE17258FF106F8D01CFC8F67EC999
+:10A8A000F023BD4B481FFB5AE5E13A1252838A4D13
+:10A8B000F577D23FDD16C0BA3F437B9F54E2C7997C
+:10A8C000FEF7493FFB4F7E994166B9F7B4D8C7B749
+:10A8D0005AB47CD29FD609B8B58DA3A7AFA58B3C3F
+:10A8E0004FB115E29E4B7EA5C7C19C003C22F1FEF4
+:10A8F0005C760651EE175A65CD82F8E73C0456CED9
+:10A90000237FA3E76FEF01FDA7E11F94CFBD7AF589
+:10A910001EC22B18B7EE7D62C4B9BF89F4696DBB46
+:10A9200004FF846B5FF74CFC7B09465EEBBEB61DF3
+:10A9300047C6A03CAB9E8BEEB761E89E7B88F7BD17
+:10A940001B9AA3EF1B7C95AEE396893091700BEABE
+:10A9500013FB07B3029D56D4DF5732FD9F105E7E76
+:10A96000C924F8847E95EDF213B71E674A843F1A16
+:10A97000B8007C8F286F67E830DDD799DB9CE5A5B0
+:10A9800039E62AA27D6E5B16C719508232DD3798F0
+:10A99000ADF9CB195F07B4D3742F649DEE27C1893D
+:10A9A0007F28BFA3AF6B9D8EE7EE0B46D33D07829A
+:10A9B0008D34CFDA9DE2FED1FA9DF1BF13A8D5C741
+:10A9C000D9F0D4C923940EAC0E45F7ABD5F953DBBF
+:10A9D00016FDBC057812189F117DCFFC4AEF43FC91
+:10A9E000C92CF0C5DBFA3846FBB519C27FD62079F1
+:10A9F00024DF0D4139487AB34E0A240B7C0B8ED5E7
+:10AA000048F75D86BEE8F765EFD6F97397AE2FBCC1
+:10AA10002E7CBFFA192948E78077FF249AFE7B42F3
+:10AA2000ABCB491F62F56A5DB399F16D156CB4103B
+:10AA3000BE8DD5ABAA217DD96EA13816AB4F357E20
+:10AA4000E932740B5CFE7F4BF77A7398F34CEBFFA3
+:10AA5000A7E4A53CD4BDADDFB1505E74A47D08F978
+:10AA600056197AA2AFEBEF5DCFED867CA7C01496A6
+:10AA70006F45DA15EE83A2F1F46ECB509E92F37C13
+:10AA8000839D13383F6EE851EC38E53A2E5FFC1495
+:10AA90007079A1ADD44EF8A2FFB8C92BA99C7F4C08
+:10AAA0002E443E4C3F2003E18DFEF6898F0790FE39
+:10AAB000A213C53752BE7CFA098C3FD8BEA7B3F8A3
+:10AAC00057E45F11E1A4917D2FECCA4EFBBD83C713
+:10AAD000E1F8DD7FBCE8F14AF2C3C7CB8A695C09C3
+:10AAE000DBE97E78911E871A8E17D97B22E2D1FD91
+:10AAF0001922DFBEC5F3FB47695FB078B7D94BF9C0
+:10AB00008EC566FFA604A4AFE805C9DB80B31DE9C6
+:10AB10003EF4248D8BF6A452BE66F1EEEF1DA2F634
+:10AB2000DA5D12D3DFDFBE287F17C5C7A0ECA5B85A
+:10AB3000D7DF7E57C1BD84730EDC537057C47C478A
+:10AB400052855F597C9599E371EF68FB2F2B29CFD4
+:10AB5000A9ED60FFD0FBEA1E0B7F57B04B020FAE92
+:10AB6000F388E7F0AF890FBDFB4E5A08E497B69E15
+:10AB7000B4F4C4F1CF467901B77161CEBF6EB7F0BE
+:10AB80003DCABD7FB0D07A6B9EFB88F369556D12CC
+:10AB9000FBA7AA67E4A04A799E03AF58483F6B9A87
+:10ABA00025C8CC8A6C37733BF951AAFFB159F865B7
+:10ABB00043EFD7E87A6EE8BD61076B74FF75D7D6AF
+:10ABC000683DBF17B42DA3F1FD7B9A57F33DA07BE1
+:10ABD000B6C7F75F861F5C4BFB528C2B6B9F8AEED0
+:10ABE00077DF907E07D8BFC7FAC95732F4F3D83C55
+:10ABF000C823FD1E0CAF19AFA03D7D7EB26A3CC4D8
+:10AC0000C93B1ED7F180118F07C3268E67B1FDFAAD
+:10AC1000DA2E5A288ED676FE99F16B79FB672C874F
+:10AC2000CAF60EBEAF7A3DF837101FAF6FB73B09BB
+:10AC30004757F608BB5FD26E0D06256A0F35917C2B
+:10AC4000FB0F8AEF3B02AF4A8CA340F77F6B757E08
+:10AC5000AED5F9B716F76763E8DE8ABEFFBE2F7779
+:10AC6000C711BAE251A33FDFD0753899F8B8048410
+:10AC70007F5A1212FEC99087115F46C6D1816F9329
+:10AC80003CD7B75BF9BEF852DD3F2D6D16DF93C59B
+:10AC9000FA8BFE517691FFDD2BE88D8DA735ADD176
+:10ACA000FDBB32D2D9DF0FEA78F813C3DFE8F2A890
+:10ACB0001C003BE5E797A8B237C86F752B347FE7D8
+:10ACC0005489CF633BD58929F1EE4B19E59B3ACEE8
+:10ACD00037EACB284F86FD43CEED8EC87DFC8D999B
+:10ACE00002AF54CD910324CF887DCFB2A2ACB8FB84
+:10ACF0001EC844BADF187BD74FA645EE7BB41D397A
+:10AD0000A4673FF23C5E49F78C6A9B857FE89B8D88
+:10AD1000E3A6108E07C6C5B5CDD620ED4F6A514FBC
+:10AD2000F87B30D20FB2BF766911E907EE1B1C9990
+:10AD300048CF723AAAC4F52F6FC3388EC32F2FFBAA
+:10AD40008CF5AA2B5BAC1BF996196F1F61EC1F6A7F
+:10AD50002E099C6A3CAF517A781F51D32EEE49B729
+:10AD60001EFA625C16D2DB7FE03FC6ADC67241A61A
+:10AD700088BFAD25A18FE9BECFE7BB6C71F1E8902C
+:10AD8000BF979AD80E6ACC3D198C57F6232E9C8516
+:10AD90007EF3ED4F79DFD17A28E14ECAC7F5ADF1E8
+:10ADA0008F777E839C1A6013E3DA4DD0C425E19E31
+:10ADB000481CB8D629EE0FDDABC749AA3F8C7A7D77
+:10ADC0002FF65D5014CFEE035BE64923EDDDF01B5B
+:10ADD000D5BABEAF2FD8B1858EE063F151B56E47BD
+:10ADE00088FC392EC6E2A21B33A3F5B4E1ED44C6BC
+:10ADF000B9FD5DB29372C4C8D75F8C26DC87F87E3C
+:10AE0000429C3CEBA7BA5EF6EAE7BE0DB365E69B53
+:10AE1000698E280D1C85FC637DE93FE908521CCB37
+:10AE20003FF8CA0492FFFA9DD1E745243F3FDFDF98
+:10AE30000AB2FCAA43763E4332DA5F3AF8CA14D229
+:10AE4000B386B7BFCC1172F922C7E2BE3C7D46295A
+:10AE50004962FF6B92C4FE77AFD2934CFBAEDAFD32
+:10AE6000B22FF2FEBC21E7BB75FD0145ECF3D765BF
+:10AE7000AA5C6F68177A613A204A9C7FA5C8F3984C
+:10AE800079FE11ED25A82FDF10B780E842D9D79AB7
+:10AE90000758EF6A4F9A989EDA938319D911EF05F4
+:10AEA00068DC4CF27B0D1B80FD881DC8BF2EA5EF12
+:10AEB0000FB1BEF4FD04C65947263C5229CEAD64FD
+:10AEC00020BFF5C0DB559323FDFF053DEE03F1C127
+:10AED0004328E70931BFCE874DB042CF13083DAEBE
+:10AEE000D2712CEEAF9AC88E63F757578A931B0E18
+:10AEF0005881F2C7B51F58F93ED0E707D6F2FE1DBC
+:10AF00002EF927939F01BFFF6A2A1F38B876323D7A
+:10AF1000FFFCE07D5773DE53DA1495AF08107D1EF9
+:10AF2000C2517F79F776C2975D0AE390A2AED3EF64
+:10AF3000D2F9EA9E56337F9B59BD77C6E38124C27E
+:10AF40004F454BE9BB9D3D9D0AEB1FE22A0347D9C4
+:10AF500019479D28661C85E3F8825C161FABA47117
+:10AF60004F9414533709DBC99F4D271CE518C6556C
+:10AF7000063DFF9C29F8D9DF91C0F9130926083D49
+:10AF800083EC28BA37B4BECE3864439B1CF5BD862B
+:10AF9000F1DEEE4C71AEB0D7D0B390A4B11EED1679
+:10AFA000E586B63D19B48EF5E610EB4943B359B4C6
+:10AFB000EF1225D0F9CD0CFED83840FC39468F5021
+:10AFC0002E4B2CC1B184DB770F9D07EAF73982E263
+:10AFD0005E5D63E744FE6E68B0738F3B5EFC394E86
+:10AFE000E73348DAD12CB1CF896DAFF3887CC6D175
+:10AFF00033C22F1E5DE89F1CCF3F06A044ECFB250B
+:10B000005D7EADE68A78E7861B3D22DFB4736CE097
+:10B0100028E971EFEE043E37EC7589FC6C694B97BB
+:10B0200042DF9FAC6F9566503C5A9FFB1E7F9F820C
+:10B03000F562F683E1FD7C6E5ADDBCBB5C8B43C7D9
+:10B04000B51E111F97E8DF018FD057BDFD1478D3CF
+:10B05000F57DDA23745E73AAD2EC14DF9989EF4A86
+:10B060006FD0FDF98DD79B19379D02D52CCE3FC4EB
+:10B0700039C532DD2FDFA0FBF911DF3B3F039BE930
+:10B080009C22F67B67C3AFDFAC8FBF02341E37F65E
+:10B09000BBF59B753C78B32FFAF9A54C1D07E6402C
+:10B0A0000EF9F310C617BE1F9197C0717A69E1A41B
+:10B0B000B83883BE0357F5EFC0A934E4DE90F71E1D
+:10B0C000C7BFA31D677ECDDF139C49800971CEC524
+:10B0D00086E39FE13F6E12F2D6CF2DAA9D824643B2
+:10B0E000EE17700716991F33E43E46E7FFFFF13D68
+:10B0F000A05C5022F325CFCAFE311E3A9FB0F53234
+:10B10000FEC615701CC4758DD3D735CE1A11DF2E2F
+:10B110008C5A1D577F87D7971A1071C4CD65479EEB
+:10B120009571627548E2EFFBAAC3625F5B5D26F62C
+:10B13000B539AD02A7AEBC490A6A12BBC3D3449F5E
+:10B14000A13FCB6C020F187A32C42F5D7FA89DF00F
+:10B15000C10D3A3E88D5A3C9D05D4EF9E65B34C92E
+:10B160004BF72A477C3FBF6ADAEBE4EE2FA73FA8F4
+:10B170006FFCEF22C4EAD1F73DFE120FE5D3BA0708
+:10B180005716E2B847F3FE388EF4A6E63276F32D72
+:10B190008F88133B1D81A37CDFA4453FEF6FC96BF4
+:10B1A000EB217E7402E3C75E57F7963A81ABF9BC98
+:10B1B000BF3A9CC0DF4356B7DBF9BBB0EAD686C4C2
+:10B1C00029E47FDB65AF1DEB95AD27CB889F95C547
+:10B1D000E23E4AAD5DDC8BB3B9FDB7107DD77B3B5A
+:10B1E000A2CFF92D3DBFA8FB063D8FF56B1B09A330
+:10B1F000A5FFF7F99B8D3A5FEABA2E664CC1A9FE0E
+:10B2000090E6AF267DEC7FFD450B1DD7D54E79A589
+:10B210009CAE886DF4A8DCEFFAE68E264AF31AF4A9
+:10B2200077643AF9F95173702CE3D2822BBB0FD3B8
+:10B23000B0FF8DA914A7FA3ABAA65A22F4BBB70EEA
+:10B24000FD731CF9358049B75B854B495AA1E3254D
+:10B2500061C7B5070E67503EA297ECB780CA7792D8
+:10B26000B3B1ACDE7D2A7912E196BDA21CC219ED04
+:10B2700032F703A527E7E6A448FA36337D17426282
+:10B280001C809E9C1B0B23DB1BFF5FDBFFD3A427D3
+:10B29000D5B69E28FB37F884BB7CFE3E3770D0CAFB
+:10B2A000F708E8BCC61521C757747F340B374B64C9
+:10B2B000A773E87C7A22413B05EEA0BA026125958E
+:10B2C000CE8BC3B2B87F3796FDF74C7DFE594AB896
+:10B2D00083EEE9CED1CF37E74237F75B00035C6AF4
+:10B2E000E0E4EF8B4BC0CBE56C5B7829C1F1825079
+:10B2F00088BF9F096728AE7336FD3BE638F21EE62D
+:10B300009B02E70C7EC8740E26EE1BC5AEA75BD76A
+:10B31000C7599AF03B041DE87EEE6C08F1B9FB3585
+:10B32000D0A39FBFC75FC73CDCF7D1B9DB35683B13
+:10B3300089CC8F20F79F4FEB91E3ADA767298B193D
+:10B34000CA9C449F14CE307D6DBFF275F4D36D4D11
+:10B35000CA57DF35D0F783E2E1734B6FFB1BEFD3A6
+:10B360007D6249D3F8BEB197BEC7A67D4E58E91D90
+:10B37000F2631300FEDDB3E637646FC6F71AE00729
+:10B38000BEE711FBBD062DF77CC6F03D35E3FEEDB3
+:10B39000CEE00A95EE6FAC72DBF8DFAD29B28D9B83
+:10B3A0004E79CA87D2FCBF21BDFA406A9EC4832869
+:10B3B000C1198C6375BDB283369BD62F69C6F7223F
+:10B3C000C0FA32F4EF0164007FB763B78AEF691EF9
+:10B3D000413DB4A5B2F6AB740F1A1E2E55092F6F5E
+:10B3E00071D9BCF45DAE95E8B50FD3DB6813F72FC8
+:10B3F0008CFB6BB17C6CB419794AAF8D7176CC77CC
+:10B400003E77DAFCFF9BE8BF3FA924937060FECB38
+:10B41000F33D7C3F29C15877898DEBC3F71A193763
+:10B4200036D17D6AA4AB311DF81EE2E1A49C14BAAA
+:10B430001FD5D825EE5337A607D87F9BFD12FBF307
+:10B44000C6CED24E8A07830E0BDFAB6E74F934AAD8
+:10B4500007D22144FE9FF83EDFE0BB6998EF21FD53
+:10B460005E5091EDD75751DE7F9A1B4AE9BD696165
+:10B470006D12F1C0F81E06E5E019954ECFA3EF7BE3
+:10B4800081E2E4FB17861C503158999DBA7C0DB9B6
+:10B49000388DEFF83525EA3B7E435E8F240AB99854
+:10B4A000E926CC447E57A57163E561F0FDBF008FAE
+:10B4B00040AEB13049000000000000000000000074
+:10B4C0001F8B08000000000000FF3B24C3C0F0A356
+:10B4D0001E81EF4A313030F1A28AD112EFE364606D
+:10B4E00010E062603005E2FB3C0C0C3380F44C2031
+:10B4F00016E566601003E21A20DE0DC47B80F819A1
+:10B5000050FC3910EF00E21B3C10FDBE4C0C0CFE51
+:10B51000401C08C4C140FC958181E11B03F1F67316
+:10B520000A33304C1547F02F03D99F24E9E7FFC1B8
+:10B5300086430CE96BDF71A07DF3AC107C46207B69
+:10B54000BE15AA9A0556F8CD588826BF088DBF1893
+:10B550008FFE720354FE5A4D34B3B581E90949CDCB
+:10B560003A4DFC6E41C7AA40FFA9013100ADF15F21
+:10B57000CA68030000000000000000000000000096
+:10B580001F8B08000000000000FFE57D097894D5BE
+:10B59000D5F07DE75D66269999BC816CAC4ED844A8
+:10B5A0000B7442421A10DB618B6811834B051798AC
+:10B5B00008644F2620F5C7DAEFCF40005151438B86
+:10B5C000355AB40304051B34D88041020EE0822DA5
+:10B5D000D5D86A5DDAD2A0C81A93801BFE5DFCCE76
+:10B5E00039F7BEC9FB4E2682B5FFFFF5FBFEF8F822
+:10B5F0005CEE7BF7B3DD73CE3DF78EE218C7948B1C
+:10B6000018FB12FFBEC798DDC6181BD79D32562304
+:10B61000D24A2DCFCD58D003FFCC62ACDCAD85979C
+:10B62000A7333665871AF95E12E43748613BE46D4B
+:10B630007B9D54DEBE9EE7236ECDCFA0FCA33AC80F
+:10B640004BD0DEDEF2C06550DEB943661BB1DB9144
+:10B65000713696C2D83107E37F5990CF66ACC0C926
+:10B66000B3E51BF6CDC5F6454D76E684FECA7715E3
+:10B67000CEBC0CF28507558655CA372FD3FA43BE88
+:10B68000382C3560BE63329F5F68A71CDE0CF53B2B
+:10B690003C2D2937B8183B55E5605E8DB16A774B74
+:10B6A000CAF5A3182B096FCFC57625F5920F973AE7
+:10B6B00065C7E697FBE1BAB64A3EBB97B1D22DF11A
+:10B6C000CC3B92CFE14BF8FF58A31CF91E942F8678
+:10B6D0007532E8B790D5E43219C75FAB79DDDDF09C
+:10B6E0003B55A5D33846BE7C2B8C03ED2A9E967C19
+:10B6F000B8C40A1B0B34C0F8EDBB9CB337B9707DDE
+:10B70000CBB4116E5CD7DD1AD62B0CE7EF747A71CF
+:10B710007E1BB45C282F59BF412B18D5DD5FE996FD
+:10B72000BED679D50E4D0D98CAA3D353558C794703
+:10B7300074E74B18F33740BF4C096BB346777FFF74
+:10B74000802532968CFDCBCCEBE8EE1F2049DF4301
+:10B750006FC13F015EA13D6E82AB81B7C53AFCDB94
+:10B76000DB8DB7B3BAC0A3D2996DEEDF481F403C62
+:10B77000C07C6A104E90AE11F3F34C649314E8DF72
+:10B78000E367BAC47A5F8F91D6A82C9FC1580B4249
+:10B79000A3FDCA78C86B6C11F331F69315D9FEA9D5
+:10B7A00090BF9F05E6E2BC57488122C413630D6930
+:10B7B00048BFAB24361BD7FF039C3494AFEA07F491
+:10B7C0000970AF9996BD4996C4DC93305FF0C4BD53
+:10B7D000E9D44F21F5A3423F43CFDF8F9E9B63E91E
+:10B7E00047CF2D32FAA9A47E9C17D64F4DEE04EB1D
+:10B7F0007C724B8C7EEEA47EDC17B62EFD8A89D639
+:10B80000F95C5146FD244EF5B100D4970D7A602DB8
+:10B810007E19CA5DF58963EF6566BA98BC12F9DFD7
+:10B820000D5C62A68B849C380B1D26FAFB58F2D067
+:10B83000937EEC5B220F834412351A5FEBAF915C71
+:10B8400098D4DF41F93BFABB482EDC312170B10EB0
+:10B85000F3C0B1593FC86B816FEB31E81AE629B1EB
+:10B86000344CBD364CA3CBEF56391C260FF8DB8881
+:10B8700023D03E68EB1C9108F9F5D2A45F205C361A
+:10B88000331BC1274E6695582FCECE483EDD9D9E78
+:10B89000BD296482D3EA41807FA9BBDFD56A200D30
+:10B8A000E96B2BBB2184F4B66A10ACA73F634F85CC
+:10B8B000AE8F8414683FA8200DE169D780BFCDE327
+:10B8C0006B30FE281AFF191C77078E3FAEE7F8F69B
+:10B8D000213996F11D838B2CE33B34181FE87D172B
+:10B8E000BB558C0FF09BC0D8F3A15B687CFBE022BA
+:10B8F0001AFF6E8D1559C68FEB1AFF051CF7A5DED2
+:10B90000D63F648275FD834BACEBD7F8FA5F650BCD
+:10B91000C5F871B4FE5F8716F0F50F2EE1EBB7F3B3
+:10B920007EBBC6F774C1FF751CF7ADDED63F74A2AF
+:10B9300075FD179559D76FE7E3BFCBCAC5F82E1A27
+:10B94000FFBD50195FFF456534BE660FF8908EB499
+:10B9500001719561189F0D0486482519E5A7746447
+:10B960001FC6A0FD3A3684E070471CA7BBCFE2801B
+:10B97000DE5CDDF28E8581A3409E55089A2FAD9F37
+:10B98000A4A19CA572907B0BC5541734C9B4DFB039
+:10B9900075F6F070986F7B931CC2FC827597876573
+:10B9A000DAEFD8BC3C6CA7B0087EFFF0A1D11BCD6C
+:10B9B000EB8A4E17D6A8C75A2D7CC4E7139ACC46FB
+:10B9C00056C2FCA621118CEBCE1F0339CA407EBEA5
+:10B9D0000F7214D3E32A8C07DF8F829C659A996FCC
+:10B9E00096F17D3CC4DE1C99827282FF1D5338BCE7
+:10B9F0008F2D91C208FFCFD62ED2503E2DAC890795
+:10BA0000A077CF2328F0D4B9CB1EDE28113CBD0887
+:10BA10009F1B891519FB33A0B51F80B6B0B6AFA523
+:10BA2000DD2D2CBC320DEACF5F933F4887F5DF3C1C
+:10BA3000DB3E56C6FD83F907D8888FD9005B0E63BD
+:10BA4000B31BD7AA032073E36CF5FD5653FB3901F2
+:10BA50006BFEE6226BBE5D0DAB36D4378A25B60190
+:10BA6000FABDB5D25A6E8C9328F5E17815E3FD2026
+:10BA700085CFF7564CC7E2679DF03A57E76D8DF9D1
+:10BA800004EF525984F6CBD66446F84FA67A019D4E
+:10BA9000AF3B7ABE7355873F0FE633F74E99E019F7
+:10BAA0003DFFD6BDF17EDB18486B3F569104A3D70E
+:10BAB000133DFF794BA3D7A3931E961F8AFECEE9B1
+:10BAC000249A9E824D93FA1E35D52B6FB8B2EF5152
+:10BAD000137D956E9965C91787E758EA17D6E65B17
+:10BAE000CA17D6145BCAE7AF5E64C9E787EEB4D461
+:10BAF0009FB77499A5FCD6CA7B2CE53717ADB5E482
+:10BB0000E7041EB1D4BF71F6064BB96DEF25D720FF
+:10BB10001F55BF2533DC373E751D7B00F5C14F5DDA
+:10BB20008A0FF171A22A8DF8E0549597D2F6A64CAF
+:10BB30004780CBC1025471162E6B08AD9E88729956
+:10BB400091FC2C5EB633141A08DAADE425F8C9B5B9
+:10BB50001A8B00094BAC4F171D77CAA6F2D6F39487
+:10BB6000D702A367F62C975B637F0F6ECCBF08E507
+:10BB70004E6FF200FE06E03ED721F6F7E8F232897A
+:10BB8000E599BF33B69CF8FC9C90B3651A9707659E
+:10BB9000CFF69BCC3C988F8CA8FCAAF11A00A82861
+:10BBA00027513B4F467A002EB0D0CB500B7FB7EDDC
+:10BBB00093695E152813C6A3C8C95B23A19C891C81
+:10BBC000187CDD689C87FF7E09F9AE2999F6F5B6E9
+:10BBD000AAE97D8F2A889F3C4A4F54CDA6F4585538
+:10BBE00080D2A3554594BE5F5549696BD5524A0F23
+:10BBF000578528FD53D56A4ADFABAAA1F49DAA5AFE
+:10BC00004AFF5015A6B4BDCA4FA9C10F5DF237490E
+:10BC1000E8ABC2AE809D87F267C55A5640DD16E29A
+:10BC2000735F1AF2F959D76723501F3FFB8E9DA10E
+:10BC3000BEDF1BBCA2E9AD773CFA495F290803FED1
+:10BC4000337B963BE3389E9C36369D813CBA67F841
+:10BC500013BEDB46515E4192810DC937CB1DA3DF78
+:10BC6000618CF0753E3C317FE7986B011FC71EFD6C
+:10BC70006B36F67B4EEC7F710764DA875964930F5D
+:10BC8000F165821BED6B9D3B84BC3F0FFC3EEA825D
+:10BC90005FCB6006E9044927FA3BDB68670AC2B15B
+:10BCA000393E0CC4CFCE1EDCE4417E5C9C66D38F53
+:10BCB000C68083919637A4EB2EF3FED364CD9FAD5F
+:10BCC00091A637903CF6265C3F1AE94AD78F0E437F
+:10BCD000FCA7516AF4B3384DD38F02BF9EDA3234D9
+:10BCE00081EFDF61BE0FD62712BD825D48F5FFD51B
+:10BCF000F3E9AD1F633E8C35B20F1C280FA06CE832
+:10BD0000F9ED9D1E78573ED1F2105FCDEA67A82F5E
+:10BD1000C4C1FF5F0EC17E15CA1BFD061BE490FD6A
+:10BD2000DBF8BDDE321EB4F31A3637B6EB9D6E1566
+:10BD300076CCA02B90571A1ACB64273A75EBBE929B
+:10BD400068C9079BFAE9967D06FF01FC0F82524104
+:10BD5000BA291354D4A1B8564B30BF23283F012F22
+:10BD60004189D72B77B46A012F91630BEA19B7E5A4
+:10BD70001874E7BDF18F20EF4FFE4665F762F9DFDB
+:10BD8000605650AE1AC520F76C909F2F72B735964B
+:10BD9000CE40B977D2C6F7F9052CCF83464F11AB09
+:10BDA000C9463DE723669B8EF4FF11FB9D27D364B4
+:10BDB0006FF86C1AAD73FE6AEB3E0BFA99255F586B
+:10BDC0006BCD17B06B5390DE0BD6A92C2C215F5A8C
+:10BDD000CBBD369DFA2D6495ABC8DE417B05C6BD53
+:10BDE0004D67CA00985FF9738F65E743FE3B36AE37
+:10BDF000A71BF67B711F3EFF92A4B0E687F20F1AD5
+:10BE0000337F7019C3F6E15528A7426EE6DBCC7A82
+:10BE1000E2EFEBCE3F7ABEC67ED2C38F20E6216F23
+:10BE200091FCE11876DA349B24F4AD10A537E0BA22
+:10BE30004D7A6BBE8083912F8FCADF1995FFA7E9DA
+:10BE40002D8959E8ED8814C8B72573FA427D41520F
+:10BE50003AB5C037E93FAD47FFE5FFD2FE0742FFE5
+:10BE6000D996FEEFFC97F63FACC7FC57C6EABFFC7D
+:10BE7000B96D3B43206F4A9E79C8C3601F3AA9D46D
+:10BE8000A4F800EF659B577A900E4E28210FD2F34D
+:10BE9000C9B03C3D163DEC467A203FA2DF25A15DAE
+:10BEA00085FF84FE4F3D75DF4CDC673EDBACEA640A
+:10BEB0002F6DB147ECC0AF158DC533D818CA1FE13F
+:10BEC000F9BBCFC8986FB2D267C9930FA5A0FF0D79
+:10BED0002845D81311D2972AEA3ECCC57D28C83A06
+:10BEE00089CFA2DBE1F8E7FA907CCCD7127A96C32F
+:10BEF0003C49CF0F0AB8041BEF3B23A3EF93B57265
+:10BF00003F6854FD22A1FFD4DBDC49C7C07462DF67
+:10BF100061DF417969C08385B9FE53BDF5E13147E1
+:10BF2000603E6D75BFF1482638197C76B661FE2FEC
+:10BF30009EF7F62E8FDB859DD7DD2E4CEDBC4D4256
+:10BF40006F6BE669991AF1A05E5CB641F585E07306
+:10BF5000D9B64D4F3C8A76EABB76DF70E8BF74DB1A
+:10BF60004B7F9800F9D2ED6AD20CBE0C9794D28D1B
+:10BF70009720FCBF746C371E4A7EF592E61DCDBF3C
+:10BF8000FFB84F373E4AB7EFD3D8E89EF098D2B00B
+:10BF90004F6B75C5C04BC3915CD4AFAAB77EAEA141
+:10BFA0003D7972AFC452D363C073C34BA427209CA6
+:10BFB000088F024F5D788BAA1F04BCA03C37F01499
+:10BFC0005DFE80903FD89F7714D1F3D3CFA35FF964
+:10BFD0003DBB0FD75FF4F4ED1E5CC771A592D3F59E
+:10BFE000632B53FC306E911A4AD129E5DF8B1EFF7B
+:10BFF00021D15BE11B3F4CE1F6A0BF9F8DF6A6501F
+:10C000003F5CDFC2F537D0FA0A5880E8AEE8313934
+:10C010002F0CE9A70A9BBE3D065F64C89C2F8E6F5C
+:10C0200004850BD6771CED12F4B3FE4E0E6F267FFF
+:10C03000C82286FCFF43C33FCE1653FE5307C79367
+:10C0400043B609BE026DCF4CAF7577B7207E4E0D5B
+:10C05000F2A7A21F2DC894908087F425F42BBF313E
+:10C060002D95E38779956CD10EF48029F81DEBB7F7
+:10C07000A87EE7184B3BF6657AF7F84BC4F830EF2B
+:10C0800038DCBF8FA7B0A28618EBBB5536F81EF67A
+:10C0900071137D99F89BF37BDD3D9CBF0D7E0FCF27
+:10C0A0009A8EE59FBCC9F907DBE1FE08F38AA4522A
+:10C0B000F9BEEB259207761689C5D775AAE06B6B9A
+:10C0C000B94127306F454A30D10BF6DF87E04FFE8C
+:10C0D000B38275D0CE242F83389EA7677F06DF16E4
+:10C0E0000AFE1F255BF99FADE77CDFBB7E15A27DB5
+:10C0F000AE4C0D3FF128F22BF067C88BFCAAE6E1AD
+:10C10000BA4FD71FF8C34DC0A7A71B0C3EB5CACF67
+:10C11000683E2D7A76B384F419CDA7A78B401B898E
+:10C12000C5A7F03D269F16B5FE3F959F06FCAE8F36
+:10C13000829F210F7B8363B43C3C63F3123CA3E5F5
+:10C1400021FCBDC9B27BD29F417706BD95FCB2FCF4
+:10C1500022F217187469D05D175D1A74D7C3FF6295
+:10C16000815F74F960A405A093BC5D2AD95565CDA3
+:10C17000FC3C0CDABD3C208BE0E4A76D8CD5BC3CCC
+:10C1800020C99C0F47E51BA2EAFBA3F27951F503F6
+:10C1900051F94A4BFDB2A6031A23FC472CF5EC4B90
+:10C1A0001F651FC4B0878CFD26D878460B215D0C17
+:10C1B000ECD450DEA9CB410545FFE01E99ECC50E3D
+:10C1C00080F12A18A7A33E3D1C02B9B1D2C9EDF0F7
+:10C1D0000EBDD3D307D295893CDF99ACAD42B96788
+:10C1E0007CEF74723F47475EA727D1E4A738D22C73
+:10C1F00093DC6E0DB3E9B1FC20B0A310DE5B596F88
+:10C20000E5DCFF394D760D5E8AF6688DEC431377D9
+:10C21000C1B21B3DE82AE9681E7ACD6CF8BEF05524
+:10C22000998E553AE23C63705E2CE457FA99EC899A
+:10C23000132CF4B389E8CF6CE676C5823551FA0841
+:10C240005B43F454E05AA2A13C053BE07DAB3F9731
+:10C25000F34589E8AF68BDB5DC688F275A68DF957C
+:10C26000D459CB03C23EDA65F04906CB2039838628
+:10C270000FDAE7422E4F93475D331BF0D1715066C2
+:10C28000789E79B659267C9CADE7E7972C944CFCB8
+:10C2900056C13A491E1A706A437ED27A97576D3B4F
+:10C2A000FE9C7D17D2CDCE3F8EF939A46D3BDF1DAC
+:10C2B000B11BF3CFBD3DF88FAC67FD297B9DE43703
+:10C2C000EED8EB267AEFD8F3DBC177617E979DFC41
+:10C2D000751D7B3F1F83F4D7B1DC5E84F2AE631023
+:10C2E000B787AAF77C3EA695F6D71584B7A3B2C642
+:10C2F000F5A3E6BF1E9692308555A1DEB0379EF8B5
+:10C3000029F8BC93FC0B1D7B3ECF0EB8FE75EBA944
+:10C3100010E7391D6E36FB599C5F22F78307778F34
+:10C32000DFB40CCFA31BF769F3A17CCA0B7F1F837B
+:10C3300072B4E359AE0FB5ABAD8FE3794587FCE13D
+:10C340003215E0DC8E4CD59FB1FB94119343A36270
+:10C35000C1E5EFE437B95078680AB74FFFFDE12136
+:10C36000F9B9BC73871D12AEFB8BC37F44B9B0D73C
+:10C370004E7469ACF774C332D257CEB7EEE1CA7FC0
+:10C38000173AB8D0754B910B59F7D47F737CFF5A8D
+:10C39000F6D2FCA2F9A0279DEFB983F2DBDC3E9A2E
+:10C3A000EF05D2FB82FF69787F16F0EE39FFBAAB5A
+:10C3B000FFCDD7DD3BDE5F9D2BF0AEE3797FF085CF
+:10C3C000BFD3FCBEAE9CDBF4DF94EE0DBDFE159B2F
+:10C3D000F7CD0CA83F9DD5B850B1B8B27CFFAB19D2
+:10C3E00050FACAC0038938DFC951E73746FAA6C2F6
+:10C3F000EDA6C9928DEC419628097B90DB51038410
+:10C40000FE30604901E9210306DECFF506C5BB0E0B
+:10C41000CF1F5F193CDF47B1146CEC3B01CCEB97AD
+:10C420008BBCD59EFCB9C4FC78343A60F0F70FA2FF
+:10C430005E3B70A04C7A2FA4A4EFBEE899CEBF97C4
+:10C440006916BBE74AAFD50ECA4DB2DA4B53457FEA
+:10C45000D3189FFF3497140E031C260FFA6912FAA3
+:10C4600047270F579904F95C165881F6C55497B5BC
+:10C47000BF063CC319F7CDE168570D380E599787B1
+:10C48000701C24939FF4BC70C47913DC32C2182F43
+:10C49000C3141F87639F721FF99D85BD4D474D9043
+:10C4A000575CAB5A909F15B497391CC8CE36ECE553
+:10C4B000DEE0CD84FDAD88210DF82B0365BFD3DA16
+:10C4C0001FD9DF065EBE2E3E0C3C7E53BCBC1B85D6
+:10C4D0009781AE450AF2EB74B417FA62FD0C9E1F09
+:10C4E0001852E8DC4DD80B57781729A4F70CCC501C
+:10C4F000105F858EA6ABF01CC4E193681E17B7D9F8
+:10C50000687F70644904F791B50AE5DFB0E9E3108C
+:10C51000DF332F7BEEF49D0CFDE67E8DC73DE5F10C
+:10C52000F38FBF7DF9E5448C1714782C84FFAF4658
+:10C530003FFF7A168903382D545828A10FFABD25DC
+:10C54000F6BEC5EF6DCDE3DF7753BAFB395FFDDE95
+:10C55000E4CABF3A7D0EE4D8FB00F35D980EA3E178
+:10C5600015B35DFD9D660EAFE021161EC2E32AE401
+:10C570003CD339E11D82FE9FFBD3B39968D74EEAC5
+:10C580001895C0E5EB30B21782C25E38CBBC093ECD
+:10C5900017CAD7A10974FE795076C78A2BDC2AEC1A
+:10C5A000ED5F627C09A41D75AC4646FB8D75921F3C
+:10C5B0003754E7609B63C4B7E4AB869F4AE00DFE47
+:10C5C000E46C3C8FE1E32F84A60966BCB5CD38A9A5
+:10C5D0008CE98907FC7BDF741EF54DE18BF63DC2CB
+:10C5E00077ABB335372F86FCB85DC06FE6FE2FC83A
+:10C5F000FF7969F3061BD2EFA57536CBF96AA92A34
+:10C60000ECB1B16C2CCE6BE67EA73B0BF17250F611
+:10C61000613C67B0F98C1688712E180D4FEC1FFD28
+:10C62000E95B559DF86BB7DA301FE1BAFB2307438E
+:10C630003B7A9756531A6B9E03EC7C9E0B59C3EDC5
+:10C6400063D2FFFDE03BA9C315998CF6671D137EED
+:10C650008F68FA6344C767B7B030EEAF68AFA25CCB
+:10C66000385BCF687F0790DC8F7637F0FBF7CC7EA6
+:10C670009C8B9BB6FF12F5828A6649C723860AA562
+:10C6800055433F6DB02951C67D38C36BC4BBEAA387
+:10C69000AF37F1C5565521F81E98B0FB661CF7E37D
+:10C6A000368DA19EE27FB1D383FBF8C7CD99C40735
+:10C6B000BDADEB5755ECAAA948372A9787D1F4307E
+:10C6C000AA3ECE92BF4C0EF447FE9A696F5DE28B94
+:10C6D00081BFEF6B923817BC40F916FEFF4CBEBD10
+:10C6E00069C8B7809C67E2A3BE5A0FF9961A4BBE81
+:10C6F0002D96BCA908F7C57B86A6225E17BFAA2681
+:10C70000C7926FDBAAF839E733224EB9A311E4DBF5
+:10C71000B74DF2AD11E45B8C7890BF5FA87C0BFF46
+:10C72000D7F0DF36946F31D6AB6B56F936A6F908E1
+:10C73000C9B7318D364B3CAF5D3B9F7C9392AF4781
+:10C74000FDF8A0EA8B8F413FDB843EFE8C884BC412
+:10C750007150CEE56A3A8D7FA172EEE20B9573FFC0
+:10C76000457036E4DCE21D8CE29C7BD22197738B12
+:10C7700077819C93901EB99C5BBC8771BF5C947C55
+:10C780001BD943BE31AA5F11E1ED834DE90FDF02F2
+:10C79000FD8DF5AB3E07D41FDB2DEFC699E55DAEF1
+:10C7A000A610DC7AC8BB831726EF76087907726C6F
+:10C7B00008CAD768FAF0355BE3C1778F3F5EFF2B7D
+:10C7C000E497DFCA74DEF8868D9F0FBD36FE7816BB
+:10C7D000D2D763623E8B84DC6BAF0A51FF535EE4B9
+:10C7E000EB2B77F138F18A46AE1F56D44B612FFC04
+:10C7F0003377C2171ACEBF788FC452213FCBCEEB0E
+:10C80000B3278DF3323623C3440F0B724AC9CFBF0F
+:10C8100040610EF4E397BA724FA2FE5B9AC3FDFE2D
+:10C82000A5E27BF1ABADABD0FF5DFC8844E7A5464C
+:10C830007CAB11E7DB236EA27919F977A3E32766B6
+:10C840008AB8A999BF94C21B62C47F946EB1E67F77
+:10C8500022F86F96DC4AF062AFCB31E3388C7A5D18
+:10C86000703A28E05427D37EDA0527809B37BD270E
+:10C870009C00D3333252BAE152FC5B586F56EFEB57
+:10C8800035E016BD6EC37F5D2AFAE90D0E069C7B6E
+:10C89000AC5FC01DEC029293D1F058A775F9B53387
+:10C8A000314E09E886E44CE8D70017182F6FD27094
+:10C8B000CB7D974705FD64D64C9A82E10CB330AE30
+:10C8C0001CCA0B6A17BDDC0FE031EE1DEF58DC4EC1
+:10C8D0002F9B600FE039EC566727C941830EDB358B
+:10C8E000AE071C14F0DDDDBF7232D9F94D928E7A9D
+:10C8F0004830E224B80601AE78FF28A870FC068113
+:10C900001E91FF0E3CF21987E31EC98BFE9D5C63EE
+:10C91000BF42BC40FDCC668E97605822BC64B14ECD
+:10C920003A7FA9A8957C11845FD306829F219FE15D
+:10C93000CF65C693897E9558F44B954CFB65A9A8A5
+:10C9400037D35EF307A4E7994FAA6C03811BFEFB64
+:10C950002A7A3E4F1C50349EDA04BCB6213C5D0856
+:10C96000B74EAE7745BEA0FB504679500959E03925
+:10C97000E5D1735F09AF7106BC908E51BE35E7CB30
+:10C98000982F689258DFF49EEBC5F35033BF17EF32
+:10C9900039C2FB7F4CF2B118EBBE60BAEE859E8BBC
+:10C9A000806EF1BCA437BA8E86533BD2F3B7BAE996
+:10C9B000F93567E7A14CA4E73D12F74334275ACE77
+:10C9C000353D761EF7B5D509740FEBEE7C55F56D48
+:10C9D000F4C690CB82EED17E30DF37BB041782F1F4
+:10C9E000A25B1C14EF47F318C2F553B37CDEE66478
+:10C9F000C9D767F5DEBFDB2EC58C2737F423233F6D
+:10CA00001AC7C3F8F926186F64F778D1FB83E12FB2
+:10CA100038DFBAFADBBFD9BA8C71BE6E3C5490B520
+:10CA2000105E8DB8A82352E0472AEA73D3254BFC49
+:10CA300015CC5CC8AD6FDC7FAA96DC7BFF2C4DA7C4
+:10CA4000FB74B7EBC6779DE8334F67E27C6FE2DBA0
+:10CA5000B8EF7FECE7E7985936F6D644DC3F26ABD3
+:10CA60000CE9EAE3432AF9A13F9ECAE36EAFF9ED70
+:10CA700001055D3ED7F0983876CD3889ECAC37B0FB
+:10CA8000EBF1A8873B987F04C12F13EFED65D4D558
+:10CA90004CF1025F8FDD12AEC6D437A533E935C441
+:10CAA000DB249921DE5AFC7DA7B8207FFB872C036D
+:10CAB0005DA0A01F50FBB1075932D69BE04F263333
+:10CAC000667CE3276F5E07F3187F48F679A1DEAC3A
+:10CAD000032E17037D7AE47A1B0B98E0358185AB32
+:10CAE000D1DF34FEA8FF3A9C7711E83B784FA4A829
+:10CAF0007943B507F3EB256A1F0C05723DB09E6DB7
+:10CB0000B56772BF857201EA6137C1F5BC5EB04E90
+:10CB1000F261887241F35A8A2F2AA893E842E1B65B
+:10CB2000B0C41CBCDFB003FADDB61EDA67E1FE0557
+:10CB3000EDB1DFBA336F5E877207E649EDEBF9B905
+:10CB40007C01B4F322BFD42DA2FE8AD74B0CEFB3E5
+:10CB500014D5F37DA9E890EAC3F2C67D8FD07E3B61
+:10CB600003C6EB978EFB50642ADD0BCA9474BA2F70
+:10CB7000191A4CF8EB601C7F6CFA20F20B52BCAB1C
+:10CB800097C0A098E363FE641F42F2B3C0B74CEBBA
+:10CB90000BFDBC96939C6E23BA3A43E7ED4701DE4A
+:10CBA0000180F71B225EE540CE075AAB695FFCC2ED
+:10CBB0003E949F9B344DA2388E852C8FE238668E32
+:10CBC000E7FAE6EB973BC3E8E77B5DED1C88DF0FF8
+:10CBD0005C6EA7EFEDDBB81C6E1FD44AFEF6E3EBEC
+:10CBE0005586F758AAD7CB242F8ED7AB743F567EE5
+:10CBF0008CC731146EE3FAC781F5BCDFE3A8B7E157
+:10CC0000B9079643BE70AB11E7C0E5B4617F16E883
+:10CC10003CFEC290BBE562DD3DF6A175CB3424D964
+:10CC200068795B2EE471098B90BD1C2D77CBF11CCC
+:10CC3000DD837C191D27E6EAB663900E225F105D46
+:10CC4000571C5219DA31D2076DB91497B647A2733F
+:10CC50008BF1CD921FE31A8ADEB18749FF0EE7CF31
+:10CC6000FB11EE2FEFDA19862C1F433C809CCAB1D2
+:10CC700077FEE9A7F0FDE41B0E8C0802BAC927B8BD
+:10CC80001B71BE599B793C4FD61BEB52F03E2F9B3C
+:10CC9000DA97E44061ADCC0226397152F25F771326
+:10CCA000DF1F74D4770C7C66693505B8BF7ECBC1B5
+:10CCB000F755EF66156364D8EF843D04F6811FF5E0
+:10CCC0009BE25D6B5334131D14EF599B22C3F75540
+:10CCD000221EA61AF7576857ACF1718AF74AFA066E
+:10CCE000D338463F46BFDA2EDE6EE81E9EF6D67F6C
+:10CCF00031CE8FD6F9A986F222BA9F1EE3F7D24F22
+:10CD0000CEEFCFAD93605E39AFCB14AC9EF3C18C48
+:10CD1000A1E6731D2335FCCAD96FDA98DF04BF9CE6
+:10CD20003FC531BF09DF8DE380EF017F5737496190
+:10CD3000A784F9235A7916E575E4F30AE17FAE98E2
+:10CD4000CACFEB1A33DE58817C3F234B227A60A195
+:10CD500080D63789F4352FFAFD0BB378FB42688F04
+:10CD6000FCD8F808E74F90135E942315EBD7E652F2
+:10CD7000FD3AC98BFD376EC8277DA4284766545EEF
+:10CD80007784F4A3A2A62349C8C7C0B7EB501FA855
+:10CD90009868D7518E1BFC68F0F7EBE23E2B73E8E6
+:10CDA000A3F17EC6FF46E68BC1D7F2212ED783F5CD
+:10CDB0009C1F83399C5F5FDFA6E20A2F84BF899F97
+:10CDC0008F6FE1FC2A3F76432EDE872FDCCCEFC34A
+:10CDD0001F583F45437DFA7858A2FDA6277F73BDB3
+:10CDE000359ABFAB25BEEF7D5DFDD2E06F838FE14D
+:10CDF000EF6A1CAF0CF814EF4F46F3F54CB5E10F9A
+:10CE0000B7C37CAF791AD603F39DF2DD3B3DAD2667
+:10CE10003909F914CC17283C9ECB902BE50A8FFBDF
+:10CE2000FBDAF38B1A3F6CB7FA477E674FE4F1EBFE
+:10CE3000752AD1FDF9F8B3079F5D207F5E285F9DBD
+:10CE40008F3F8DF1E53DD67E7E27E82DBABF7680F7
+:10CE50006B04E0FA4AFD268AF3FDE8A92333113F6B
+:10CE6000A5BB81CE91BEEADD2C82724E09D37E55E0
+:10CE7000D228D33D01A644B2AF739BF998C76D95F4
+:10CE80003EE3267A2A79D61E9E01ED4B767E3086C9
+:10CE9000E2689677525C5AE829A12F875AC7201F6B
+:10CEA00094283C7E2C5A2E041CDC0FD7B62B7E36E1
+:10CEB000AE4FDAC2DF8F2869B851B59BCE256E74AC
+:10CEC000A8463D3AD70D011DE3FD5D9C9FF9DD02AB
+:10CED000236EAC6D2B9713254D2AD981255BB6B7F0
+:10CEE00063FC70C93B76F27705B79CA1FB10539E9B
+:10CEF000D946FE9460936C397FEB11B7B9458ED853
+:10CF000031EEB0B19CCE1D217F84F20DB1E397CFFD
+:10CF1000175F58FACC9E9D210061E9AF9EF4A07C7A
+:10CF200039D5B2D98370877EBF326EBA479C66C34B
+:10CF30003D5F19A7790AFF018C738F43D835469C52
+:10CF4000EB96BEA447C2FCB2F3629C7374E9E5DBC6
+:10CF50003E7D1CEF11B43D7BFA719C6FD93F3E7E44
+:10CF60001CE3C1D85E27ED77C1A7DEA2386CA3DD34
+:10CF700026B1DFB56F7D92E2D7DBDFB5FBB0B7F648
+:10CF80003DC707633C60FBF62F52D06FB964CF34C6
+:10CF9000F2EB2ED9312595C5D82F8C14E9367C01BA
+:10CFA000F1F3D1F83AD07880E2D63E027CA3FCEBD4
+:10CFB0008ABB6D28E771CC5E116F5B1FFB9E428FB1
+:10CFC000F8DAC6EBAEB91CE57E23D71FCF1B67FB93
+:10CFD00026E0F1DB1780BF7AC32F101B7F1FE13FD4
+:10CFE000004FFBA2F0F769E3C25F3C8A658D7D7B51
+:10CFF0008DB38D5C00DC8C7B100F38FC871CC988DE
+:10D00000E75F525C33E26D8617F79F4F07E3FD91B0
+:10D01000136AE75CBA5FB8C7AE63BC68C99EB789DC
+:10D020007FDA77BC417E6826EE23B4B3AE3F1E3F65
+:10D030002E8975D6B9797CAE803FC6EF7A3DF45D16
+:10D04000C4E9723A36E2777B8BDB959D5CCF36EE96
+:10D050006794D7FD51C4C376E34BCA413C1DF9CA5E
+:10D060007868030EBA90C3DD71E8B1E3A3BBEE2B81
+:10D07000087C21FE701FEA8A3387FCC0B1E4377A4E
+:10D080009BC59007ED1B78FC7ABB1AFB5EB011972D
+:10D09000FE8F683E0D5F583CFAF9E6FF75E1D381DB
+:10D0A000CA4F724F38B5FD2DB61C4F774ADFEC9E44
+:10D0B0006199147D6FCAEB1C87713B4734B483BB05
+:10D0C000EC6CB1DE36E1576F7B4AA678E5550D076B
+:10D0D000488E47CB8B0A7C2F25C67C33C57C2B9A88
+:10D0E000F83ED1F6AC3BEC827EDAF6EF227AAEA8BF
+:10D0F0003F42F1D22F6FF995D66A8A8BC07D226CA0
+:10D100009A7FDBD3FBC690DC16EFB2448F33498C99
+:10D11000136C8E3D4EB0FE8C659CD25083A6BBCE68
+:10D120003FDE29C57F23F677AA85EB83A71AE4E9BA
+:10D13000E118E30F73AAD677A160BFA4F767DCFC00
+:10D14000BD19D91347FAE51277CE3B0949986A14FD
+:10D15000AF55BD4CC477FD872F0DF15DEDBE8AE163
+:10D160007C57227C4D7E1E550F30D44BD5B4BC2C41
+:10D17000F42B44CB1B2DC9C6C226FC2F714F4FF593
+:10D18000D279476420E2F370C67115FBFD4B949F82
+:10D19000EA2F0A5B950AF3FB4B48F22D837ED9DF19
+:10D1A0003E1894E7EED97F971EF163D9E257AAB0F3
+:10D1B000771E46BB84BDE0A4F80679AF93DEF9087C
+:10D1C0003EEEA4F51ED8F1F913A45FFFC2CEF8B964
+:10D1D0000F582F20AF0A75DEC7F11D9F3FFE57D4B1
+:10D1E0009FB1318C5FF838D447BBA13E9EEC9C8E3A
+:10D1F0006713C6A05FA4F085BB66A23C2B8CE7F446
+:10D2000058F84C6AB81AFA3B96CCF3C7B60DA27719
+:10D21000254A9F7553DCE8811DCF55E0BED4FE4CF6
+:10D220003CC37DA9FD05A1E7FF52BC5355AB7ACDA8
+:10D23000F1E3C54CF19AEFF39462DE12AFC4C82F4C
+:10D24000417C84FEAAA604BA0704FAAFA59F8FD436
+:10D25000CE3B7C44C7A1FEFCFE53A43FCA83E87AC0
+:10D2600046F9BDCE21E25E39B47375D70F6A9D05CC
+:10D270003C5FD39FCB9316AAFFB053F88F4579CF6D
+:10D280007E79FD8784FCEEEE87B7AF10EFD044D3F4
+:10D29000EF46D16FE996BF5F1CEB9D9518F3A7EFA2
+:10D2A0003F9458C8867ACA7627BD7F85EF28E07DEF
+:10D2B000859D1A3FD72AF344E89D9BDD421E97C502
+:10D2C00045E8DD9DFE621E581FF3CCD1FA34BD9FA8
+:10D2D000F69C93615C59F90B6E3FE2BB7CE7E7C7B4
+:10D2E0007E9E857189F114175FFEC2FF223A28B72E
+:10D2F00047E6223F746EB7B38DC8E7DB5F1D8CFC39
+:10D30000DAA64606F7F98AF3BAF206BBF5FEBF586D
+:10D31000C7A9AADACBF0BEBB71AFB6A41739F357D1
+:10D3200027D7A35F71FA5F7212BF5BDF733A55357F
+:10D330003B13DF5930EA973862CBC577515E7C13D7
+:10D3400039EEEA713FF55D9CCF47AC2505FD3E15F2
+:10D35000A077A33C2FD9923E10FD04FB9DC63B0451
+:10D36000DE04DC8FF6AB5EB2A73135EF3327AA7C43
+:10D3700099CA30F4DF8CCC54601D1D1BCE14F467A9
+:10D380001847EA9C1D4BEE9D76C6D33A4A1CF69888
+:10D39000F79DCF09BA7A0F8DFE643E1EF28731EEFB
+:10D3A0007E354C72F88E382FD52B01BB08BF976E97
+:10D3B000999369797F45A9A17AC0A704CF62B64E37
+:10D3C000CB32C96F63BCE2A559994A267E57FE4FFE
+:10D3D00017BDCADD7866A124D20B150163B6AE9FD6
+:10D3E000E57E88A2E639107E1ACBD3151949A586A9
+:10D3F000F83D8E3550EA02758BBF5356C9504E9E8C
+:10D4000010E7F6E8EFC2B41B5E7792DC0F0D626C9A
+:10D41000783ABE07E14DD04DF053F1101EE6635748
+:10D420002A1997173374B493A550807D09F4545D7D
+:10D43000353D13E911FEFC180749A607CCCFA3BF61
+:10D44000FC05EA4140A7FC3DBFEFB270358018C330
+:10D4500081C9AF3A99F177E856BFC3CCF6C6A5713A
+:10D460009278E7681FC93117EBFEEB843C8A55942C
+:10D47000B7D509FFC8C1734497CE22A817C6BB58B9
+:10D48000241E52D728E59499FF3D599037D1A93EE3
+:10D49000D15A1ECD1720D7A2C66D20F841BF9F4498
+:10D4A000F5FB4954BF9F7C55BF069C828E8D3E7C08
+:10D4B000A76265559E801B1FCF21E006F01989EFFA
+:10D4C000E8315B9C4F9C87135CE3C46CEC581FF005
+:10D4D0005A1E974E78B92F616F27C641B3A45A865A
+:10D4E00076EF0A89EFD3F097E732B563BA83F8F0A5
+:10D4F0001E314EB980F30AC33FD5A3BE93F4AF1ECD
+:10D50000F59DBDD58F8B5DDFDDDB7CE263CF27B181
+:10D5100097FE6BE263F6FF75E552C50B6FBF86E7BA
+:10D52000B65DF24907D05BF5CCF238D433138FFDEA
+:10D53000A395BE703DD331D08AEF38A46FA0B7B8A1
+:10D5400061D6EFD174D21B7DE58B7540DED50FE03F
+:10D550007093187F6A1D3FF7BE6509F7D38179E89C
+:10D56000C7FA378BFA37390AC9DF70C4C6DFBFBACA
+:10D57000A596EB91B7FC58A6F3E91EEF51E13F8069
+:10D58000DF6E5D2A8523E9B1DED76275783F6E9E36
+:10D59000183FFABDAA00F3E6AE9663BD57C5E9D2BF
+:10D5A000B85717FD4EC5029627DE21B37E3FEBD458
+:10D5B000BBE467CDA8EE7D2CB416E81EF54FA07B2A
+:10D5C0003C97C7EB621417E2D1785C48CB203A4F06
+:10D5D00033E4DFD991DE04DCAF997F30FFAEF3EFA7
+:10D5E0008BAFF4A69AEF1D2AE7E22CEFF554ABBE01
+:10D5F00034946FEA39D05FC154D6CE0D615E533991
+:10D60000E8ADC4FC18BE49722A4D09A35C54F43C31
+:10D6100056887AAF78EFC3A8AF255DD5A567BE0E53
+:10D62000FF6F8E4B26BE5CBCD64BF7B63F8BCFDB75
+:10D6300089F4247B727C01574F7A08EDE0EBAEC68B
+:10D6400075A7F75C4FB5E6F391BE7D158080FC6F42
+:10D650003E07CE4FB67BDFF6E2FC7EA332F4BBF48E
+:10D66000848FEF4418CACF8607507C889C306304AF
+:10D670008EBF46BC6FBABA6A24A52BAA984879BC5B
+:10D68000DC8A2AAF487344EA17E974AA776F551AFF
+:10D69000E55755F92835E0EBF0D5D0FB938E617C4A
+:10D6A0007C872EF0976413F00B90FEE548ABA473D3
+:10D6B00045A75E19C177DFD840D87770597A0DC178
+:10D6C00057D319F935A13EE5ED988754AD9D41F842
+:10D6D00052F44A5608E56FC5078E225C9DDE4B2D3D
+:10D6E000EF5ADAD3C646BD7F1A056F83DEB671B82E
+:10D6F000DF2F717A8B86FBFD6A8B17E322EEBFB2B8
+:10D70000EB5D29823B98431CEEBFE6E7B43DE1DECA
+:10D71000327BBE09EEEEECE904F7FB049CEF1670D9
+:10D72000AD1678A816F0AC46B8537EA4C8FB443AB0
+:10D730009DD27BC4FBB72B111F90CA087780877DD1
+:10D740005488C9301EBA79F1CFEE1274ABDBC81F12
+:10D750002ABBF2FC08777B1287BBC3057820BA0688
+:10D76000B87BB13C44F0545D1CCE509FE341E415BE
+:10D77000847B267EE7F800B8F78D1F87F27082055C
+:10D78000CE5AD2E40B83FB237C7F4B127C1E0DBF51
+:10D79000248DBFAF6BF0776FFA71B588B7AE16EF17
+:10D7A00027221C51AF7908E0C3340E4FFE7DA4C878
+:10D7B000FB284D16F67F35E001CB1F16FA10C21973
+:10D7C000D31FC573FB3CC956B94F4538F5E1EFF29D
+:10D7D000B0A4101B98CD78682FFEA5859817F3C6C6
+:10D7E000F9AFD74A3FB2AE44BD03E97D18E96DDD1C
+:10D7F000ABAA0DCF3FE4A55759EE67CBB3FD895EC9
+:10D80000827F4042BDE63EC1876B915E687EDC1E32
+:10D810005E29E8E06EF1FEEE3D827EEE17FCFCA094
+:10D8200041373E7E3F64CD741EC798946113EF204C
+:10D830004698394E30D1D7C0349817D9365E4AE968
+:10D840009D4BF68E9DF8367E14F3237D25BE7367BF
+:10D8500098BF439BD70FF5A144E3DDD989DEC439D6
+:10D8600074313DA288F720656E4FB6C47CDFB5DA0F
+:10D87000B7DF817E99DEE613EFF3A7AF84F1E26BA9
+:10D88000DD6447F50DE4CD590879572DD8550CCBFB
+:10D89000B97C70C1BC0B4DF411DF8B5F47755D59CE
+:10D8A00080F44AF638A43FA91DEA44F802ACBDE86A
+:10D8B000BF7A48CDEB87FBC14389B1FD70B3E2B9B4
+:10D8C000BFC49375A9C59FB04EF5533B7DA255DEED
+:10D8D000AC13FB439FA956FE30F683CB447F9FC514
+:10D8E000077E140F7496726E2AC9CFA46B63EF0F74
+:10D8F000D5AA16C2F739AA4773BE0EE56B5C6FEE68
+:10D900002177189D839C0D8CD888FE2F83BE96337B
+:10D910002EE7428CEB93C6BA7E86F43E02F7019D59
+:10D92000E81EF701CCCBC334A29B945B6CE47F5818
+:10D9300025F8EC5EC15F6B045F3D807C3502DF81C2
+:10D94000F651FA13C14FEB90FF20DD129FCEF57810
+:10D95000F1BE9761C72C778CA5F71CAB5D36DA0F4B
+:10D960009477ED6117DA05FBC6EBE8F791DD597A9C
+:10D97000C08DE5590E3FC0434ACCD2915E3E732F15
+:10D98000B8E8ABE25B01FDF4AEB0A2727FA49E9456
+:10D99000C7DE1F45A753F49E80AA5FCBD03FFD7022
+:10D9A00052A513E1FC703C8FD3AACDCF26B8033E1D
+:10D9B000B6C59BE2A552675FD5F51E1F76FF702F97
+:10D9C000EF12EC12F2820D0CB16126F9502BDE7BC6
+:10D9D00064DE101B699213CB87E732F4EBF5940FEA
+:10D9E000BDC8CBCD5C5EAE9062CB4B437F37E46568
+:10D9F000B45C31D295174DB7DCA7545D3E46F26654
+:10DA0000646CFFC1EFE3EDFC1D6AE6F3E5A7F72CBC
+:10DA10000778FDDE0C2FD4830C7FC5F762AC275A44
+:10DA20003E9EB8CAD85703F43ED002CDFBF0F8AF03
+:10DA3000DC57ADFB41E1B9D5A40F149CCBA1B4A830
+:10DA4000763AF111C3D318939D7C7CFD0F3D88DF9E
+:10DA5000E3B5E27C7CBD1AC6B8A47D1BEF7A600EEC
+:10DA6000C075C1E3329D8FE33D0DD914DFC2B2BC56
+:10DA7000A4A71BEF231E0FDFEE31C73114FCD4E93E
+:10DA800047FDBF377A2C581FDB7F538DFF44BB8384
+:10DA9000F946A25D01FA5D6704F5BF9F38E9DD181C
+:10DAA000231FDA18EF33C78F18E95BF1D3CE21DCDF
+:10DAB000DF8AF73317D29DAB0F9DD7F4CE177CDCEE
+:10DAC00063E833C773D247459C35C07D96C57FCA8E
+:10DAD000CF498F097F1873F4521E27CABDBD947BAE
+:10DAE000783C13D36397FFD37EA4513DECB421B8A7
+:10DAF000FEF2DAD3ABDEA52FD6F3806211C7BD608C
+:10DB0000637C78790CBE5920EE072F10E75D067D07
+:10DB1000157FDFD0B3395D46D3ADF4D42544A71FBC
+:10DB20001F54C95F5B01F4877A98F4D4787A8F69BF
+:10DB3000D913973D780BC0F993433295979D731095
+:10DB40005DB6FF878FE2FC3B7FABD2EF267C727025
+:10DB50001AC5EBB78BF79EBBF8CEC5EDDA1B5C5C44
+:10DB6000AE149CBB97E8BB8BAEC2F335E4DB82738B
+:10DB70000F905E5680EFBD4EC0758F78799222E887
+:10DB80007702B61F92BB1CEA15B6723E61134315AD
+:10DB9000E48FDE10EFBB37063FDFE0F25AE2450BC1
+:10DBA0005BD750FF0CF4C324535CC802F1FB07851C
+:10DBB00078B884E57A88A521DF08F9D64DFFD677B5
+:10DBC000B0DB9DD6751AE9C2AE754EB0D861DDEBFB
+:10DBD000FC2EE773A16F14B6E6F07975ADE7E7E3C5
+:10DBE00063ADA77B1D13A97D7B62ECF1EF17E31FEB
+:10DBF000AB2AC29B5BAC44BCB75B10BE5DC3F7D520
+:10DC00000AD627F6914CEB2AAC2DB5C42B15D4E6D9
+:10DC1000D3FB7A85EBF3B5DB4CFB53175E42FE97E3
+:10DC2000270DEBC6CBFD6B2E23BCA8AEBC3B917E73
+:10DC30008F3D557CC77B5EEC97E3E984161A534908
+:10DC4000F2EA764FACFB4DF747E3A956E009EC80CA
+:10DC50002C139E0CFC44B73FB6B9FC8EF7F01CE2C7
+:10DC600011FE9A50EFF22B0A7FE9B1E1F7A4A0D799
+:10DC700063A00F042E087EDFB2C4CBF50A3F816F8C
+:10DC8000033EC677D0E7C208B727913793B13F4E1E
+:10DC90000FE7835BF7F8821E26C55ECF6B5DEB59FD
+:10DCA000CA42A0C79CD4B83ED1FB7AEE6221C70518
+:10DCB000ACA78B4FF32D7CFADA9A5B389F0AFC9F56
+:10DCC000DC7F0FD1F5B170BC0FE3547A5BCF6B48AA
+:10DCD00007E362D0C1B0101B95FD7F8F0E4E68FE2A
+:10DCE000118FE03E02FB15EED3C54FDE3FC63CBFB1
+:10DCF000B7E227FD9EF6A59A0B3BA70E4DF61DF445
+:10DD0000D27E27FBAA6149435D813F63FB12CFA30B
+:10DD10009FA19F6E45E2CFC6C4D28B5756052EC732
+:10DD2000F38BEAAAA2CBD18FAA0A3D97A19E9BCEE4
+:10DD30007F1723D67B7DCCCDF1BBB2AA92CE3F9884
+:10DD400023C4F494EE7700D8894CF2472B2EAB7E97
+:10DD5000A6A9011DFDDF9A78A7405502ABD3B3D029
+:10DD60005F94941132C1EF1F2E7EEEB2266DBF8EEE
+:10DD7000E71A76E81FFD608E81CA598BFFEC456576
+:10DD8000415FC093F11C731C6BF04B12F913CF462B
+:10DD9000F913CF5AE69104F3FE0A3B5B7178E81C55
+:10DDA0005261C28F2CE0015F681FBB5BE7EB5C1E1A
+:10DDB000EF217D60D54536B2EBD609FFF4CFD02FE9
+:10DDC0004D7051E8BC01C3E0B0BE96C0D7E1C4734A
+:10DDD0000C19EDAD08E5DDF862974C4F1F4A984FDE
+:10DDE000645E09F37D596415DA0F1D935AEF203FE5
+:10DDF000A03390E606BC7ED6AFE5B084E712798109
+:10DE00008B11CEB57228C30BF57F21776660BDC13B
+:10DE100050F44E1F9E5E84F71202A6F3CE21B48EFC
+:10DE2000EEBCDC337FD15225EAFCEF6F179BCB5F52
+:10DE300071FA2FC679543BF9FB60491F4874BE57ED
+:10DE4000DD75EE9447FBF26437C723D105D2D54187
+:10DE5000AE379D55BC097DC89F3D32F345CB3C7C18
+:10DE600096BC22ECD13AA0533CA732E86398E2B7C3
+:10DE7000211D0DAF81EF663CC6D077FBB8E879F085
+:10DE800098FAB9313F1897E8553E97CBF7E3287ACF
+:10DE9000D82DF1F9878AEDDC6E642119F13AC7209B
+:10DEA0003C6505CF2732E38FECB5778D7327B682BB
+:10DEB000E7759E0BDEC6CFB9A3E733A7F9EE163C94
+:10DEC000EF99D3DC6F3E9E7BCE29BAF8434C77ABFB
+:10DED0009DFBE3515EFC50227DF6A6B75E54E32124
+:10DEE000DDF1E6467A9F60AE9BEFBF7359A78AF8D3
+:10DEF0000F305DE3E756615ADF6DCC27F20D2AFA49
+:10DF00001D6E89846FB81A72B7BE18BE1AD5BDB916
+:10DF1000073B5F42B4051AF45C3A1B32DA35F95E0E
+:10DF2000E679DEAE0B0E4EF1FB478A83D6D5BD6E89
+:10DF300007C1C15827D4247C74C149BCCF66C0A591
+:10DF40006BDDF1375F85FEF8DEE4DC1CC7E80F7996
+:10DF50009C3C9F57349C3EC12290930BDDFE1FB921
+:10DF6000A1FC7AB7FF2E4CCB1C9D839521C437555D
+:10DF700098AF900317A5001C3E1A14B83819E1D1C8
+:10DF8000D2F782F4FEC34E2E0F0EA71B7A6DAB1B89
+:10DF9000E99BBDC8F55AE3F73256ED387EFF8D0098
+:10DFA0009F8F5EE5EFCD95CBDE6BEE22FFB2CC62AC
+:10DFB000D921467A58F80D1E76DBC47BD17C9DF3BF
+:10DFC000140EEF798DF174CF6EDE52D9F2BEFDBC26
+:10DFD000A53C7E95292D63AEB7D8092B045DF7ECDF
+:10DFE00007FD1AD1FDCC5F3A99DE2DD9A9E993C876
+:10DFF000CFF138A7B3F953FD32C6FD4F582D911F0D
+:10E0000069FC516F532BE4E787137DC8AEF3EF5CD7
+:10E010009C89EF9754B4703F67AABC28E33F207DEA
+:10E02000683FDFEF31BF08E1E4F27B5DA6F39A368B
+:10E03000B53243477ABED5E54779907FBDFF5DC4D1
+:10E04000A7E1E730F6DDE7400FC038CEFC5BBC3916
+:10E05000481FF90D4E3FA50EA6C4815CCB5798030F
+:10E06000D3548D294E4CE39803D3ECE5427FAA9D0F
+:10E0700045FA8327274FC3F7C4F39B9FFC14DB1794
+:10E080002A917D92899EF29B5FFD82EEC3F9F3286F
+:10E090004EF75B5B348BDD39BAC19AFF7693359FBF
+:10E0A00011B1E6330F5AF303706D267D73FF1E1E08
+:10E0B0009F527A9ADFEF7D1E60A0223CB6D9493E7E
+:10E0C0004E296DCEC67887D34FBB6D58BEFBEFDCB3
+:10E0D000EEEEDCEAA47725F7BD17C7E292F01D6AE1
+:10E0E000E7462C3F1DD7908DFE45A84F714BB0BB26
+:10E0F0008E40BB71E7A506BD8629BE69E73FF8FDE6
+:10E1000094CEADF630C6519CDEF5E4D3489FA7B758
+:10E110000E207DEC792964C37E43F770FC4F88F3B1
+:10E1200058E454E916AB3D7E42E8011D27B579E875
+:10E1300017BAB8D6BAEE4BC2D67CA7A87F1B337DE0
+:10E140004FC7F810EFAA34DC6737C57EBFFD73C137
+:10E15000174F3DA519742B8BF71E9937A5FBBEE20F
+:10E16000EEEE73DB2503808E4A111643BABF974645
+:10E170008DDB850FD17F92382FEBFCAD4CF03955FC
+:10E18000556489EFE8D2FBAA7C69534DFB5141ED00
+:10E19000BE947CD257F7A5DC66DA67CAB61E48B9CA
+:10E1A00019FA6BDBA2D0EFEB95CD79E2810949F842
+:10E1B0005D6EC0F96239FAE7DA1A5EF2603DD08B23
+:10E1C000C79AE3BD0A6BC7A54D35F1E9D7A54B83C7
+:10E1D0009FCA740E9FE7725A72F11E46692DFF1D89
+:10E1E000BED2861BAEBB1AE1BE9EDF4FCF56589EF5
+:10E1F0000CFC53B6FD86EF8F86EFC1C7C6F9703EA3
+:10E20000D9F8242DDEBBAD3F43F776EEB571FF4460
+:10E21000345C467B387EEFFD81AB08E512F4F7A253
+:10E220006D2CB53F68037DE4C4E4D06B374395D3D0
+:10E23000ACE10F57535C96959E803E25D4B73A3794
+:10E240004BBE8DF47579F6B5A85AFB97513C3A94BC
+:10E25000C7B4378AC3D67EA2F17CA547327EF76861
+:10E26000A4995EA2EBF59D11A2DFB72A5B0A72CDDD
+:10E27000A4EF971DADA178D8E871C819688A3BC191
+:10E28000FDD14B7CEC147A02931CD9225E7C28CF02
+:10E29000D3BBA748974010A597B2A95E84EBB56C95
+:10E2A0003AA6CF4B91076499CB03F2336D8B277954
+:10E2B000D0A6B73EF173A4A3FAD1741ED65FDCEFEB
+:10E2C0006EF346E8BD58E37771DA749E2F69765293
+:10E2D0003CD5E98F349297CB308E13EB3FEDB4D918
+:10E2E000405F3BBDBDEF648C0B6E6BE0EF8A9F6AB5
+:10E2F000E83B59FB8AFD379AEF8D7DF108FE13DF6D
+:10E300004FF5F88B3DB8DFACE071D3A97D2B332AF4
+:10E3100063E0C96897A45566A0BDD279ABCBB7912D
+:10E32000EB53E90AF9DDD3C8AF922FFC49F7E9793D
+:10E330007778A0BE1BEAFAE1FF3E07E58DE877FC9F
+:10E3400040F6DDA10FED3E1F5F9015A0FBE3F40347
+:10E350003630FE7C854514A0B7F9B8AF8CA13CC916
+:10E36000CFF9EB258A235CB0C6BA1E7CE7DABC1F66
+:10E3700016E12F290EC5B8B0064A8BD65BCB8B7140
+:10E38000FFF050BC17C5CB94D459CB198B901FAD5F
+:10E39000ACFE4B7B2CB87DCA8CF5F96B3C16B9A34F
+:10E3A00092DCF950CEA3F595A23700D29BC4FE1C97
+:10E3B000BC33276D01A41D4B27A42DC8C47BEE7C64
+:10E3C0001F23D38EF898BF8F573A954506F1777182
+:10E3D00018EE8FA5CD526434E61D2CE419CBBFE3B3
+:10E3E000FB20B86EF33D3163DDB85EF377F626C7E8
+:10E3F000AB71CF10D76B2E2F137028ABB75BFC3AE5
+:10E4000013EAA590FBDB787FA995DA55347E69B7CE
+:10E41000F42BF65FD8B79913F035A168838C8B790C
+:10E42000A84B8E872F89750FE5B080DF433714F432
+:10E43000437E7D10F5CFFE02C039249F849F804526
+:10E440001C305E5C66579ECAB397F3FC3E4FE08A71
+:10E45000DA8160AFA9013A879A2FE7BD8CF71B4795
+:10E4600026065E42BCCCB7F9072BC4B7FE11E417F1
+:10E470005DCAE1F0F0D8CA4B2A63D9C502BF3F9309
+:10E480001AE85C3EB48BEFA3EEAC4ED5ECF7FE8BF6
+:10E49000904709FB5BE95E4FE70E89EE133F221DB3
+:10E4A000A1FBB68F5CE96568C7A7019E50EE3E22CE
+:10E4B000B115F85E5E56E3AC452F219EB3E27C7841
+:10E4C000DE5FDE38492E77D1FAB9BE155FB901CFCC
+:10E4D0008352E78D1C8B740EEB9E772D7CFFD0E36F
+:10E4E000A5F1FAB938DED39687D2178FC2F1F316A9
+:10E4F000BD847C383A8EEEA1A702ACDC7D285D8D10
+:10E500007A541ACBD887FA60DA0CEF58F4B93FE4A2
+:10E51000E1E324DBE479B350CF1BCBF37D7E2CF910
+:10E52000371211AEA57152ED6C3ACE17BFA35EE85B
+:10E53000403F82CB84EF299519387EEA509E2669A8
+:10E54000118A0F3C64E0BD99C7E92DD119C9E925AD
+:10E550005F4C4A453BEE501B18D420BF0E0D34ECE7
+:10E56000CC888BF4F06123797D61F72DC9E0F75FEA
+:10E5700092061BFA0FAFD7A1FA133251AEBEC1F506
+:10E58000F14F5C7EF2575FA6C58EBF4F48E0780A18
+:10E590009E8B636193FF3838FB33D21383E73C2CA7
+:10E5A0006CDA27F0BD4D731C7759D17EFA1D847249
+:10E5B000D642F701CA1BAC71E797C5C51ED7A0F3B9
+:10E5C000E0391B0BF525321E88F6D721A973D5C279
+:10E5D00024BA174BE73BC1731A0B99C60F9EEB6326
+:10E5E000CD77CD3385FAE9AEC7ACF59A3EA77A2C44
+:10E5F000A7D583E3B4EBADB48F04CF29D4CED86FC5
+:10E600003AC2B6900AFCDCEEE5E51DE23CCFA86F0D
+:10E61000F4D73E5B13F7DEF8BBE86D552078002E8B
+:10E620008F369F217F7459F33E828B410FDDF08935
+:10E630006721137C52AA5B2236E0ED690F6EB87B2E
+:10E6400014D890C9FB051F8736DDED9F08E5F8BBA0
+:10E650000F26BE8ECFEAE27312330FD9642E174213
+:10E6600075774F9D68CA8BFA5DED439BAF980A346E
+:10E6700095358AB7BFE6C1275E594E4E8B1A11DF1A
+:10E68000DF3938CF6DCA3BA2F22EC88F36E5F5A828
+:10E69000F2A4A8F2B4A8FC405EBFCD1D192CFB402B
+:10E6A000DE3FF8D415F8FB9E6DFD2273F1058F3522
+:10E6B000F2B62BF0F77CCBB3F8EFD356344B3EC910
+:10E6C000243F2BBACEF35BB5F9A3100E2D2FA31C5C
+:10E6D000286B9274D4EB5D0DDB2394C7765E53BB3D
+:10E6E000066E3F96351CA176BDF63FD2467C7CEF88
+:10E6F000C8F7A9DEF9CE9FD80CEBEF5BF5761E7557
+:10E70000440A2C4E48EE7E7FBD6DFBDBDDBF2F0A39
+:10E71000DFDBFBF90F901C8DBA071EC4F9B8BAF9FC
+:10E72000C480E3BD23CFD27BB47F1CDDFC16AA03DB
+:10E73000F14BCE2C53A0DD9FCB8F8F437D0BDFB4ED
+:10E74000C57DE36752F812DC8F1E65814B70DC5B80
+:10E75000CB87EFC39F4C38ACB63E86EF956F78F011
+:10E76000E52B1498DF6177EB20FC09B74D096FF0BA
+:10E770007C722B7F5145FF1DE1E7F0A0D64136C8E2
+:10E780003F99C0A6537E78EB63987F3DE104AF3F8D
+:10E79000BA7590ACA30972F28AA990DFACC7E6F70C
+:10E7A000DA04AE371BF39B36DCFF53840B2BE3FB01
+:10E7B0000D5E3376803C9D5B726ADB6680C7DC1F32
+:10E7C000C5939CDBDC76DD55790487501EC611A607
+:10E7D0000A78D37E48725D217DA21FEE817DBAF159
+:10E7E000E91EDCE2A5FDE2D2CAEDA837A4CE1D45A4
+:10E7F000FB45A1C72FE9C9DD69381952A82FE93AAD
+:10E8000097EBB28DE22352EF72931EF5A0F83D0311
+:10E81000E03BA20F97C0CB36B19E6D09DCBFF680FE
+:10E82000671AF5F39EE47FC42163CA424EF2A7C57E
+:10E8300091BE72F306902B20D7D78979AF5B7B0905
+:10E84000F9296E463FF128FCEEEFD76754B7FEBFBB
+:10E850002E03F2AE6EBB6EDD2C7F3FF3B9F6BA0D20
+:10E86000BCDC905BEBD2797B63BF4AADE6E3A43EB0
+:10E8700078C9465C47BCC2287E7BE1EC111B97D16E
+:10E88000FE7F2DAD9FF9FDFDD00E3F5A3CC4867A28
+:10E89000A9819FC2E1FE5712603D3789DFEF35F055
+:10E8A000648C4FB7E2517F90417F403B353140EB64
+:10E8B000077D620C0F6EE0FA04D21633C19729ADC2
+:10E8C000E3F0FBFF2038B5FD2BE0F44F9F7747C9FD
+:10E8D0002190370CFB2F5F7ADC72FFED3F01D123D3
+:10E8E0002A700080000000001F8B0800000000005C
+:10E8F00000FFC57D0B7854D5B5F03E73CEBC929920
+:10E9000064264C9249C8E38440081071124344F0D5
+:10E9100031848851693B50D4D87A71203C022699C1
+:10E92000A8D5624BFF0C12790918342250C181021C
+:10E93000C55BF506458C1A70448A7AAFF68EADB782
+:10E94000576C7FFF08888F4A32A2F5D297FDD75ABD
+:10E950007BEF64CE24A9B4B6BDF93EDCEEB3CFD9CB
+:10E960007BEDB5D76BAFB5F61EA6F54C0A5CC0D8EB
+:10E9700066256ACEAE642C7C48F1ED61F007CF6766
+:10E980003B19FBF7B4A0D595C9D89FF1EF0AC6E6AD
+:10E990007EBF29275806ED8D2318CB612CF5BBCF00
+:10E9A000D4DE00D5B94B3F7A7C0F7C3FF77BA98C36
+:10E9B000E903EF438F8CC1F7EFBC6D5BCF2E84D2A0
+:10E9C000D2193579A0BC86F956C07BEF98584327F9
+:10E9D000F4F70EBE7A096355DFBBE5353691B1DB3E
+:10E9E0005D2A6393185BABF873988A250BDBE0BB59
+:10E9F000F02C4B644F11637D1153D80CFD75B82377
+:10EA00005B17C1B81DD795F9C2D05F1F637E86EF33
+:10EA10002D4BA5F73ADC3D4CC3F64B741740C20EA4
+:10EA20007EA1FA19D4E3375A22BB14785ECEC2769F
+:10EA30006C5F323E1286FAF3300E7D7F634A640FBC
+:10EA4000B6CF828FA0DE71A3371286FEEC2C624710
+:10EA5000783A76FA73321C8CE5AAAC05E1EF28828D
+:10EA60003A94592BD9CD0107E2CF3F719673000F2D
+:10EA70005F7799683EA9953D4FFF37F4C7D6DB7D98
+:10EA800063A0B0E1AB586FCF2678993B5885F86604
+:10EA90001AFC03B8EA1FC889ACC3E7CC5785EBB1B1
+:10EAA000DAE99F47F0FF205547F81FB6B335B60A9D
+:10EAB0002815D666CB00FC0B7858FB43000C633757
+:10EAC000E3008097FFD770D6A9C3F32B5D0AAD078B
+:10EAD000FCF96D558CCD67BC7DFEF2D477958958D5
+:10EAE000AA516B1A3C5B73A5BFC746EFB13F8FE2DB
+:10EAF000A50DFA0B32F1B725EE44BA09E27769D8D1
+:10EB0000FFEF9DBA03EBF0FD445C76F8BE74E0FBCA
+:10EB10003A17A3F9CF5539FCAC355547FC4AFCC828
+:10EB2000B24EC2D7FE903F713C394E72BFF7BAFC6D
+:10EB30003722BE00EFD1740FE245A5754D86D7632D
+:10EB4000896FB043FBDC56D57D37E033B8CC49F351
+:10EB500095F0DE9C1DBF8C150FEEFF746A739586D1
+:10EB6000F35FC6E99D2DB702E212F16219A8035DB9
+:10EB70002C64F163266588E75AF445847F5147C2C7
+:10EB8000F7F4DF2FAC89EF497E61BA9204BFA02B66
+:10EB90005DD170DD820A5F378B253E375036186EA7
+:10EBA00089CFD582EE245D24E37B35E27BD2607C85
+:10EBB0007B2C3DF9D86F709995F094DC3F6311FA86
+:10EBC000EE213BF00FD0DD1645217ADD72576A64E5
+:10EBD00025F2A73DBE17F1193A7C15AD77EF9214D7
+:10EBE0009DC12BDB2C30419433879D9C8F4B7A4AFF
+:10EBF000909F7A61CE7E589FDED7D59D614502C138
+:10EC000058F3EBEA2EA4FFDE67AFE6FDAC48D5195A
+:10EC1000D4438861183714FE432B03BC9E34C52CA3
+:10EC2000345E17E057C209FF7AE15F43C580BCE854
+:10EC3000C3061CBF8BCB0798E1121AE7DB296C1DBA
+:10EC40008CDB6C52FC26686F5E3A3EB292C3614325
+:10EC50003E6A1420359B589B5231C0F7CDA6132530
+:10EC6000B795F1360DDEBB85F17581F78E2A005F11
+:10EC7000A36D7D4C45BA45FA87F6A5D85E3480FF72
+:10EC8000E6F5BFF913C2DF7CC048178D8F19E7B1D5
+:10EC900034919E8A06E824B592E389D5B0C81880DD
+:10ECA000D729EAA9B5B1888A785A56CD4E02E966C5
+:10ECB0001EE99981F4E3ACEC64F3A10C7DC0FC1176
+:10ECC000807B4AF7CE9746C2FBEEDA583E4E37B409
+:10ECD000ECB68B4E5D34B0BE12CE4BBA37A9CC41E8
+:10ECE000E3D177008A7FBF83DE1B37FB82C4F26EDD
+:10ECF000FA2ED3A412BDF6E023E41BCD9FA3C038A7
+:10ED00009B978C32E17AA6827C43B9BCB07DECAE95
+:10ED10001584677F09CAB707D380CE099FBE2A949E
+:10ED20002FA5EEEA5FBBA0BFA7DCD5FF8D258E1314
+:10ED300070E2F44790BE48A6E764BD23DFCB2E6E99
+:10ED4000296F710CFF1EF017E12DBE359DCB0F4DC5
+:10ED5000A1FAA2FF30EF5C47F0694437B76D2F226C
+:10ED600079DCC0DA89DE1A59C482F4BBC8C6C2692C
+:10ED700040178BE0B57428176FB1323D61FD9644A2
+:10ED80008CF546210F6E6131FAFE967D49ED352CEA
+:10ED9000EA84F6261B8BA662D9696C6F667141EF17
+:10EDA0007FB6263E671D7CBE378B7577D744D4204F
+:10EDB000CC7BAB1D745706BED04EEB3365F94E5A73
+:10EDC000CFF40A7FD13DA84F5E35FB7601DDBE272B
+:10EDD000D64BE2E75E57F5BB88F714D544F38FDFD7
+:10EDE0006325FC9C02BD8DEB7F9F9BDD3C1BCADE37
+:10EDF00056DD3B7A34A2C95530DB3918CFEB9EB3D0
+:10EE00003720DDB8DD26C2B77C7ECC65A67AD5DD9D
+:10EE100002FF2B5223BB8A08DD13919EAA46497D2F
+:10EE2000CA26CE82FABB6656D709F5E6EB1D41EC41
+:10EE3000AF07ED07A817B8B9DE28705B687EB22E61
+:10EE4000E72BE906C6A1FE522EE2A584638C5BC8BF
+:10EE500041B6897F27F4EFE625293B49FFF6D3AF7A
+:10EE60008911FD96052C88D7E7845C794ECA9536C2
+:10EE70002B972B9A6BEE32A83FF741996F1DE095C7
+:10EE80009582DE83EF1B3F4AD1919E5EF9E85FEFEA
+:10EE9000FD19B49FFDC0A25BA17D01D218ACDB734C
+:10EEA0000A9747607F30D48F8DC0F6386EE3C1B1CA
+:10EEB000647F1CB408FB46C8CFC6B4E0D685D04FEB
+:10EEC000E393993EA064F6BC39F2E85E6C3F64F7C8
+:10EED000ED817E1B53385E1B9F1B49DF3F610F4E48
+:10EEE00077C33C73AD919F3C8172E3052BD97B675F
+:10EEF000597411C27FB6D3AEE07B27705EE95042F1
+:10EF00009B82F3EA76923D047C9AB310BE3BB936FD
+:10EF10009BCF4BE0E9E48609C4179BCD7CBCF0B3E2
+:10EF20000ABD7FC21C989103F5134F97FB564053BF
+:10EF30005FC012B5003D87EEE3765EBD49DF8178A4
+:10EF4000628753095EB91EA18D8B67627B68E9F207
+:10EF5000AFA37C1C8ECF51DEB304B9D9CBE205C878
+:10EF60004FDB1A467546519F748FF3915A655E5870
+:10EF70007CA01B177FF79499E3357EC84CF47CBEC8
+:10EF8000FDE37CB52AAE7F709C10C86526F98FE43E
+:10EF900072425D1DAACEC8FE0C3D972DEC3A63FB74
+:10EFA000EBCEE01D6EA0BFE6FBFFE79D6584DF387A
+:10EFB000C945D69E497C79CAEC9F8B74EBAE895AC1
+:10EFC000E627E8F30D82AFEAADC2FE63514B221F84
+:10EFD000CAF6AA6A23DDCB72BDA07F678CCBF7C1CE
+:10EFE000ED26C11FDFB4A21E9BC2416685A8471C47
+:10EFF000D8BF4EFD4FF9206AA9877AE1F2A8659142
+:10F0000028914F00DF511BCCFBD45627E76F4003FC
+:10F01000F6B36832237DB94805FBB5029FEB5D3D31
+:10F02000B02EA79F7673FAFA236005F03D8F89F71B
+:10F03000AC60EF821C7BA64D89E27E60DE16EB2E73
+:10F040007B11F2B55F75E27A6E57488ECD6B9B5699
+:10F05000B215EA4B0F5C40EB9F3699D3E5D2889B03
+:10F06000F4E214211FEBAD110BD9DF3F5118F2016F
+:10F07000F44F7674237C945331180F28D70DF41075
+:10F0800049A8835D34A593CB5506F29C25D84B52F5
+:10F09000DEA31C6749F69F913EC2521F71B9C7F4A7
+:10F0A0006C947B522EDFEB0A74B949AE8DCEC6F557
+:10F0B00085F5E47273BF42786D622DA44FA41EE8FB
+:10F0C0001F57E891D36A98EB2BEB262A5F7717D16D
+:10F0D000784B5927E913A95786A383D7BF840E7E9F
+:10F0E000867400ED8D1FB0E865305EE372166D9A90
+:10F0F000C84BE744D28F5C4FDAB89EC432E53CF48B
+:10F1000065B27E4CD687C97A30DBC2F59D5C6769F3
+:10F11000CF644FE776C094E51195C1FC36A6F93F60
+:10F12000CE9C3460D784DEB2D9F40BB11E60A3E06C
+:10F13000BDC569D36ECA86F690C6FCC857A980972C
+:10F140009DF07CBBB07B6BB339DD7B2D9C7ECD5AB3
+:10F1500080953B705D62B4CF8D673217D2A3C4E750
+:10F1600076277C5781DF71FDD4FFBD8DB5A5247C4A
+:10F170005FFD9C9DE4EAE7CF3A2356B24782856E55
+:10F18000E82FEB5756B2537B9F73923EED15FAD0A2
+:10F1900083F628D1CB2AAE5F715D272135558F6468
+:10F1A00048FBCA352351044AFBACC9CDEDACC1F6CE
+:10F1B00090682F8A5DCFE9CA4AFBCCCFDD3D7762EC
+:10F1C0001DE061689FFF8F58E7D081E9E5DF87E7A1
+:10F1D000A180C3C7B11F2C477AB5AADFB9DE06F4F8
+:10F1E00035435D1EBF0BE6D194EF70A19EAB29FCA9
+:10F1F000F52F6F84FA8707CCCC8AEBBC677A1D1B8E
+:10F2000035BCFC5D12319FE849E0975BF619EB4D88
+:10F210009DC67AA8CB582FC8707A4E4F20D9E1FBF3
+:10F2200033D0B5D5DAF2C14E80D7FABC95F4D1A768
+:10F23000EE607106CA5B53FC18E2D95AF8F144F447
+:10F240006F84BA3F51B0B402EDC4CA38FE91AF3FEB
+:10F25000B7CF2B740D81B701FC319B89F00CD63AE6
+:10F260002F49CE85049F782CFE0F5F84F92F9A9D3D
+:10F27000E2BA9B9EF8674EAA427B926064A12D572A
+:10F280007F88FB2D786F09AEFFE959F01EC0D5B01D
+:10F2900085EBC346164B43BE6D06BBD3064B7C477E
+:10F2A000065F875BDAE25551F8DF8E8CDA7108A7CA
+:10F2B000F6272D80F4B11AFB4DB093AFCDE07AE084
+:10F2C000967D76D729031EDD867AA82BC7752A91ED
+:10F2D000FF84FC61798A96B81F7A57095E8BF86BB8
+:10F2E000B2F558A6C1F857FCE93392F78B97CDA732
+:10F2F0007DC4805D6D25F9B4F8AE203D7F692BDFBC
+:10F30000179EDE6AD711EFA7B7F3FDE3E23C47C4CF
+:10F3100006FF7B859BDBDB8BE13B45198CC764BC1F
+:10F32000BDFFF0555EA4A3F7191F2FDCC9ED8FF7C1
+:10F330005D80AF62FE0EF6F77E17D8EF0AE2F9AAFB
+:10F340000F512E2EDEAEFAD04E60879CE48F59BC52
+:10F35000FDCA710B1DD8DFA723A6A15F68C795E87A
+:10F3600089C2F70211EED7895D01CFB51D17931D34
+:10F370007774BB95C3E9B6EDC5795CF12795F84A7A
+:10F3800033B120DAC71D16FF38E467FDE13D337065
+:10F390005DDE9F956BA2F71F57980BF1E15E968596
+:10F3A000CF172B5A00F9B761CB929989F64E6A862E
+:10F3B0004AEB35AD7079568F83F8E97AD4A34DDBEB
+:10F3C000817F70FCD96FFFF2464F223FDD5EC54C56
+:10F3D00009F6CBC35F237AC2BF28E06BB1C0D75711
+:10F3E000E52B6BAAE48B961294A38BEF6E29710D1B
+:10F3F0006157F4F3C5C39C0FEFCB50B8FF202FC368
+:10F40000B0CF186E5FE62835915EB1F9987F0F9402
+:10F41000D9B02DC6FDF7810C8DDA0F64707B5FFBD0
+:10F42000DD6DFB5E87794DCD086ECF807A21F39735
+:10F43000E3BAEB71573598B18862B2BBD8C3566E48
+:10F44000C76ADC8EDE9CC9F6AE4BD88F77627F9997
+:10F450002417F6623FBDC7FF780CF1DA5CF0F14487
+:10F46000B40F42E73EB3A01FCDD1AD903C77F80278
+:10F470000CE925D43D8B2D281B90C3211FD713C920
+:10F48000F3FA5306DFEF843C71EAE7FD119C7F3B02
+:10F49000DC9C3EB72D4B213FE4364FC48E40FFB578
+:10F4A0007C2AEDA525C2EF67DBFD945F45FA8E2827
+:10F4B000AE3158D7397FF435CC8DA830CE87BB8B91
+:10F4C000C9DFD977609A4F8536C7EE1FAD198578A9
+:10F4D000EA32FBF07D87AF270DE7F7E1EE9369385D
+:10F4E000BF86DD2ACDBB21F249D6C2B201B9F033C5
+:10F4F00025F83ACA01E6521C38BE940F1FEEFE34BE
+:10F500006B8183FB0B487F560E8D97A7DCD37E8ED5
+:10F51000DF5F71395F978F1EB74650EE7D6407FD40
+:10F5200096206F3F72727D772A43EEEF3A0B50DFE1
+:10F53000F4D76F2A35A19CF88E8BCFDF63E92C407E
+:10F540007EFC8D62EC67E91A138B806C5FB206500B
+:10F5500003F2E8A3479F294079FFE19E670AE62767
+:10F56000C097FC9D2C7BE578C26F26FDA81E4B340E
+:10F570000FC79BEFB3727FE5307E54F93EDBC2FDCF
+:10F58000A17D3EAB8E7428BFEB6B48F1A37DDBC73A
+:10F590006C24FFE6770BBFACDF3FDA83FB18F97D05
+:10F5A00052FF151E4E4F4A9742FE83D4B238C9E32C
+:10F5B000BF59DE7B603D13E43DACF3BF215F34D91E
+:10F5C000E2C74632A20F0BE2CDD2ECD0503F65AD80
+:10F5D000E4F415BFC344FB2A4BAED781F2EC8A9208
+:10F5E00094361330A227256D22C601F2734BE9FD34
+:10F5F0007035A7FB7016237F5B0E6B51485EBBB85E
+:10F60000DF3E6F3273AD83EAAC11DC9EF132DF1660
+:10F61000B598D65D41FF90C487D40B483F281F3F63
+:10F62000526C443F4AB74276A76AEA9C8BFD0E476C
+:10F630004F1347C8FD3FA7A7FEFA3F899E268F18A4
+:10F640008E9E823AD193D736343D093FF179BFCFB0
+:10F65000C201DCBF660B7CDD27E44EFC0E9BF49BF5
+:10F660002B38DF99A2BF9936475445FDE1337F9C83
+:10F67000E8FF7D18EC5FDC27E5A0FD0EE5C895F3FB
+:10F68000745A3716EB417F41EAC536D28FF79A623A
+:10F690004568AF648F6FD98F74913DB7AC6225ED2B
+:10F6A000FFF2DCA80F50B7921F745975E0D488049C
+:10F6B0007BE110DFCF34DFE5A7E7D3BBB97D101ABC
+:10F6C0006D217B38D4A584719D9B039608DA416B2C
+:10F6D00015EE5F096FB0EB3CEEA3AFA0B8CF0F748F
+:10F6E0001E178A48FF6FCF8EEF23BD3538C8EF91C4
+:10F6F0001C3F3AF885CAC71FC368FC8E721EAFEA6A
+:10F70000B85AE7FE15B17E1DB3FC396EB407D618A2
+:10F71000F959C685FA9C8018186FFE7A3BAD43AE46
+:10F72000CAF1CCD26D5CFF0C960BE467CE9A2C1616
+:10F7300046C46FFAF91C2405D67345BB8C3739CB08
+:10F7400002456879BFBBE9B7AFA400BD66A19F8E33
+:10F750006FCAC268F7937F98D7C97DFCA00900C91A
+:10F76000C5D6FF5C577369425DBC3FF0FDDC6B6B37
+:10F77000F248EFF6B723D8A08F65DD6FD7311E357D
+:10F78000D0AE81BD6BEB52F8F761C7B5578E063C22
+:10F790002872FCFF5CEB477FA19D19C64B844F4B41
+:10F7A000EADF0CFD3B74F97EBCF64A78E1C10A59E8
+:10F7B000BF66AD1FE0BBCF6CEC8F502ABEC78A1C62
+:10F7C000EFD6AC6DEBD6E70DD8056027EC1A913972
+:10F7D000601FAC7E7B66FB853056AAEB530BEA5D5F
+:10F7E000A9E7431E85EC8F647E3D20E4C3DF2C57E0
+:10F7F000F54176F4811124577B66204BC2FE83E4E9
+:10F8000076687980A13D07F64817C2DB7BFCE3D31D
+:10F810002F427BEFECDF1F1BA9E37BB7CE45BB3745
+:10F82000744E23BA0DED53230AD0AD4DF00BE871A1
+:10F830008A0B487A5AEA1274EA0E338C73741C529B
+:10F84000268589BE5A0AAE83B5CCF7F85F4238E404
+:10F85000BE3279DEBF1EC1F70FA1D2EAAD25D8FFB7
+:10F860006E85A19DB0AEF444D602DA37BD9BB530AB
+:10F87000E1BB255D0F123E97EC330F89C75F8FE028
+:10F8800071DEE6679FF6A3DCF828A2904C68D022D0
+:10F890006BA740BDA1C1849620AB8CCCBB91E21C70
+:10F8A00075163606E67704ED268463DF37C353709A
+:10F8B000DEF04F8147DB028B489F6EABB339284E99
+:10F8C000543AFF56C2832BC58F7858575A9D83E30D
+:10F8D00034CF9AE1A2F808D871D8DE7CD7B7C82F08
+:10F8E00024E15AD765AE453BA70AECB9A700EEFC68
+:10F8F0008C6B6A7DC0C723D5FDE5B73B305E3EB457
+:10F900001CFF6E26A78B362510FE4625F94159A20D
+:10F910005FB3B08BDB8D9F8DB018E22B9F8DE0F62F
+:10F92000ECA5E1D874249FC35A4F2ADAD321E6FF0D
+:10F9300004F7CF2CE0D0F7D03A7179E469D5C93F0C
+:10F9400066F3F4DC7B21B65FAAD1FE85693D0FE04A
+:10F95000B8BD6B3DBE754CF001D6EF2AA37D4FBDFF
+:10F9600027A87832F9BC707D7B9FBDAA1CFD88D288
+:10F97000EE5AFBA89DF4E65AA77E7F2DCAD3DF6915
+:10F980003C1FC0168F4D877E96FE3E83C65D6B8FF3
+:10F99000ACC5F50FEF54A9BDD8117460BF4BBEB90B
+:10F9A0006522D22B73444A508F9A3DED0CE918B66C
+:10F9B0002BE42FB179020CE3C4D3C3F33405F5452E
+:10F9C000923D331DFD55B45FF190BFB65AF0C71894
+:10F9D000A082D3366285B63F8F18B06F5EF9E31C04
+:10F9E0000D1F4ABBC764E3FEF39ABA1486F62D5B7B
+:10F9F000153F66427FBD27C6D00E6EEA54689CA6AE
+:10FA0000D2272DB86FB9A593F37748EC33007F0563
+:10FA100068578CF1A40A7BA08DFB3958ECD848C4F8
+:10FA2000F3637C3D1983F712FCAB8CADE0F240F43C
+:10FA30006711718626E157024D48ED3E8FB45BEFAA
+:10FA400016FDB7F3528CBB5989F955C46BB962F0F6
+:10FA500087CBF22AF17DFA91F80CE4DF38D017FA5F
+:10FA600097B62AB36EFD29CC6FEBA4F13E34C1BC2E
+:10FA7000404E6A053E075204BC57767D3203E98644
+:10FA8000D532E2D7E6AE696A9383C76FD05EC84EBF
+:10FA90006DD989EDD93797927EC6F8C86C78FE3556
+:10FAA0000FE7B31C07F7D779EF0E1761BC33FD489A
+:10FAB000E0D69FE2F817A490BF351BD6C69941E562
+:10FAC0001AF46F7959F98BA87FBD33F50A8447C6BC
+:10FAD000F5302E38AB8CE438D5337C8A7F179437D9
+:10FAE00078DC340EECEF6A115E7C1E710CC419D107
+:10FAF0006F87E3621C0FCBDE9CA8467E7ED0E77B3F
+:10FB0000904EBBAC2EC4D7CCAE97DF427D3BD3C664
+:10FB10003A29EE9A64B7C4D3BE19443AED3B737ADE
+:10FB2000C73D08D775077D94CF92648F5C7139B754
+:10FB3000CB3FDA93AA233FEC12721BEC471E7F796E
+:10FB40009CEF2393EDC8EFF6AF2FB723FBEB7F7746
+:10FB50003B92C317DEC3F328A47C0F897D5F5FC38C
+:10FB6000D934D45F2B3DD2AE4DCAF7D82DF23DBA71
+:10FB700087CEF7D076F2F80F864149EEBA2D22AE45
+:10FB8000E5F7CE43FF87BB84E4C02B7B53C34837E4
+:10FB9000673BED6497696E4B14E16A7BDA1AC13CEE
+:10FBA000883645E0EB90885759441C2CA344478382
+:10FBB000E2A02540723FFCA499C7ABD2228FEE850C
+:10FBC0007AE3E11C11CF62D47FF8D954C277638AFB
+:10FBD0009E8EFD37FEFB088671AA3E180FD7F909E5
+:10FBE0007B70BB87E25ABC7FF68255E7F1B3688928
+:10FBF0001BF0B033C2EDBF93A5A6A805E6BD93895F
+:10FC00003C9FF532AEC5E7D9B761248FCBA03182D6
+:10FC1000FBB2B5DC5F542FE35587B91FAE5EC4A5B8
+:10FC20004ECE5EF408A658B4292DB5B84FFB7CDD46
+:10FC300034F29FDF79FF2C2AEBD718FDFD8BD03FE4
+:10FC40005F3C103F967EF7F9CC67E1F6F380FFD07A
+:10FC500004F68CBE46AB46FD59C45C77A33ED0C3C8
+:10FC6000B07A1743D906251AF10A6019DED3D67A7D
+:10FC70005270BD57B799486F85DB4C7E7C4FD2CB15
+:10FC8000AB1EAE67DFF570BD03A88EE038B26C33F3
+:10FC90008B7883E86F053345B13429BC5CEDD26ABB
+:10FCA00087D2DFB2BF36738B6D1ADACDF926F277C1
+:10FCB0007F6EF1D791BF38A384D6A9CDD9B2A696CD
+:10FCC000B7132F7D6E8F07A8FD328D1B964CCF404A
+:10FCD00079FA8287C71792F1B6B0DD584F8EC32CE0
+:10FCE0008918EBF52C3836A798C70D129FBF20F462
+:10FCF000C4E7EB8A04BE7D1694BB72FE2BF238DE9D
+:10FD00004CF9BC1C955F5D8774300AE3CA45587294
+:10FD1000BF2ACC84E01F75994721FA4882B7CDCD20
+:10FD2000E929BC96FB21FF5AF893E1FED09325F810
+:10FD3000D8EFC5B865BDCB4271E8F3F597A4641A56
+:10FD4000F7B7FDF5BFFFFE96EFE7D7AA22BFC6457E
+:10FD50007269BE8BCFE5A4E2DB1BC5E70EB01F7056
+:10FD60001E6BD50A9423D3BFE9A079341F063982CC
+:10FD700071ACE53D05A8D79BAB7B4A305E938C5FA9
+:10FD8000845693F20CDE9BEF81FD08DA0D6B8CF14B
+:10FD9000B8C1F1557F616626EE7B4EEE7F19F5D72F
+:10FDA0007E3BE92FF8BF17ADC8FFCF16915C8B38AB
+:10FDB0008363312E144A89EEF87111DA31DC8E6AD0
+:10FDC000EAB6EE443B717E5B427C0FFFB3DE18EF78
+:10FDD000636B32C8EFCE3A8CCF1B1E4EFA6E50FCCE
+:10FDE000AF9DD665B325380EF91DF410E51D9C595D
+:10FDF0006262B8BEF5AA6F112AA93376A37D7EC6CA
+:10FE0000C9D76B46A6D43F3EB2BFFAEB83D6D957CB
+:10FE100082EB5C6F62C1C47E9A709D617D1BC53AA6
+:10FE20009F79FAE2125CE78FF75F5C82EBBCD9DC6A
+:10FE3000EE47BE297507AF41FC9CBA3240F615E685
+:10FE4000EF201F9D2F3DDE94448F37FDE3E8B12E58
+:10FE5000311F32593F36F4E3CBA81F3D163D0FE565
+:10FE6000C17C9BF52FEA49FC1BD29F67B392FFE34D
+:10FE7000F01F3FDD48F918DD2AD927B2BFC35AB0B9
+:10FE800018EDA3C36F797D6165F8FED385FDE5B5F7
+:10FE9000B130FA59E4BE40DA97C9F278B998CF0385
+:10FEA00099FEDF8CF81BE23CD27FDC20DEB1453EC0
+:10FEB000E576EF6EC5C7FDC79DE44F6E3E34CF8536
+:10FEC000FEE20F22DC7FDCFC7439F98F97445E8AF6
+:10FED000623E19EB565CB81F59B2FBDD34CC03907F
+:10FEE000FB5ED8E7DE9F49F935C6FDEF07919369C0
+:10FEF00098370070BF8F70A77AE216A4FB66D8FF10
+:10FF000061DE60B3163F86FD367B18D905955DC668
+:10FF1000FDA08CEF6E0B5848EE6EEB562228AFB367
+:10FF20002CC1A23CD46B2CCF753A7580CF2299FEA0
+:10FF300017907E07E2EAFE5D5897FEA79EADE94462
+:10FF4000BF3D66E677A13CDBEA14F24C23F9F6DB11
+:10FF500087DD91750976C36F23DC4E5822F3C134D7
+:10FF600016D560BD16CDF11FC7F546791F4D92F726
+:10FF7000897519AFBF8545492F35B19EFEBCB0C408
+:10FF8000F792E3F9180737F4C35ACA75F493DDE41E
+:10FF9000F0519CABEBCF56637B98EF9B811F96553E
+:10FFA0000CD0AF5C0749BFCDC21F1D6A38B10AE94A
+:10FFB00037D4A5B8707FDDE8E3F4DB08FB2FCC9BDA
+:10FFC0004DE677D669CC131D8EFF7FDDCF779CFF82
+:10FFD0007F3DAC9CFAC7F85BDFEF973F9CEFE5FCF9
+:10FFE000A5FFBE7F9EDD0AE7CBA47925EF5B93FDDD
+:10FFF000EE72DF79BEF2F08B247C7CF10FC6C77005
+:020000022000DC
+:10000000F230256BE8FD42725CE3AF9687FFE0F8C3
+:10001000C623871E4A3381A8585214F672BBCE6F8E
+:100020008817CF501D7E1E3755793E4572DC5D9F87
+:1000300021E2EE9C9F5F7A5AA5F56A12F1E1A64390
+:100040004E1FBEDAE0584CF1D9E4F8E952B67F060B
+:100050002E51721CB511F9B8F8CBE3A91765393DDB
+:10006000249F745684790AC9795A2F393E1D114C40
+:1000700058EFEA32D8080C41D7362DCC32129E4FB9
+:10008000CBE2F6F44B229FC86BE1E705EE73A6FACC
+:10009000711FE335F17CA77C4F607AD62494EF0280
+:1000A0009FCFDEC04C809747CC9D244FC24D0E1F82
+:1000B000CA3FE9C791FDEF10718BF3A5F36F671984
+:1000C000E9BCBFFE4FE2FB8592BEFFDAB8DD16C089
+:1000D0008D811F18D1EF6B18672A1A4CB7C3F533FF
+:1000E0001CFD2ECB0ADC9E4578F14FA4FCE6F39470
+:1000F0002FA995F193E82F6207AC3AFA376DE2FC2D
+:100100000B5B9F23F6EBBEAA599497CDCF8FC87394
+:1001100036C3D98F1BFBF99FDB8FFDF5BF93FDC85D
+:10012000DC81769CE7A9697ECAFB5FED04F8715F0C
+:10013000F8A875C8F32CF2DCC597F95DF6F6C3CDC7
+:10014000E96AEFB070FF63E5E793FF34F9F9FB3438
+:10015000F4A30EDF4F58E47BC6FC229EC67625F83A
+:10016000B743319EAFF79280573E7F44E8C5F46CA9
+:10017000FF515CA78F8FDB6C2C1D4C9E4A2E179B6A
+:10018000030E8A2F3477F2BC97E6E58CE47733FAD6
+:100190004FCBD0AF388BA1BD373523F833FC7EF57C
+:1001A000DB8EB09A8E7EF7D90CEDBBDEE3BCFEA9E8
+:1001B0003BF8736C0F2DEFA17846C7EC8F28EFAAA0
+:1001C000EACF9FAEAAAD2478C98FE0B11ACFAD7C3B
+:1001D00091C5E30FB2FC43BF3CF1935FFFE3069E82
+:1001E0009F1DF2F85DE88F907EF1543D467EA6E6B5
+:1001F00003DC68AB52F97CD8F7F3889E9A0F4C2B3E
+:1002000047FF29EBB497A39D5BF52B07EDF73EBEA7
+:100210002B97F224EA3DC10F513E3A2B2357A35DA1
+:100220005A08E3A0BDFBF1FEABCB116E29FF36A34C
+:10023000FF1CC6DFEC34FAC7998DE7D92FDD9B4F41
+:10024000FBCB6247F053EC6FB39DC311DE23CEA30B
+:1002500008BF7932FF4BBECF564D344EF6B76D1402
+:100260002F977261B399056DC503F2E478962EF26B
+:100270004C445E63F72C9EA722EA0E8F31BFF381B8
+:10028000CC2B8F233CC7B3B4AF961FE618942F40F6
+:10029000FD627E18C505589CFC2DA9E7B81D3DCA16
+:1002A00065217A7202DF519C06E809EDF94BE3B152
+:1002B000E9789E6B7447F452C4F3E17326C2933617
+:1002C000EB358AD3A42B7CBCE2F53D6BC7A21FC6DD
+:1002D000F5E665B8A47ABBAB1A513A3523909F4D29
+:1002E000FB8C96521CAFFABFCC3C9FF2502AF917F8
+:1002F0003A0A1A299FB2F76DABE13C4E7219667744
+:1003000053FEE4A8AE5F50BCC0794019322F76721C
+:10031000B683F0D61C8ECDA01C9B4B3D2467B54305
+:10032000BFA238B5B6564309C4DACC7E139E430B40
+:10033000AF60E4EF1CD3E132E17A158AFC98BEC3CA
+:100340007F9818A4FD8A8C0F44787E93B96715EEC8
+:10035000C3B4153D9787713D0EB84DCD65D85FBCD0
+:1003600099FC2D875219D24F6157F1DD53A15EB828
+:10037000C645F1B0BEE76E2924FF2ACC73CC10F33A
+:100380002CCA36F3FE0FA59A509F699B980F47D54C
+:10039000DC59D504F78350877E468A3C55193F4582
+:1003A0003F14EAA9F4ECE0D7303FB6FF1CD2B214F8
+:1003B0007E0E49E3FE12E7B2B71FC7F33D3B2CFCAC
+:1003C0009CE791C3136693DF6FADA6E03A7CEEE63F
+:1003D000F99437669B0CE74206F07F84F256471D7E
+:1003E000FA05D76B3016F6AF9939BD686B3D3BD136
+:1003F000BFB8382D4879BA97B545558A9FB94E3D53
+:1004000050AB27EC73B6703DD3BC8FEFCB93F73571
+:100410005FA65F6ECB36DA2DFDF57F92DDF283FEAF
+:10042000F1FFC6FD0A33EEF392ED97E47DDD203B4C
+:100430003CA9BFE1EC18998F523D300EB7A79DD271
+:100440004E0A1BF275AA1DE27CA1CDD8FFE5235C04
+:10045000345F99BF93B5525F8179FAF11F30F2D7BB
+:10046000C93CA27035CFF7099B6C74EED0CBDA296A
+:100470007F68248B2A0AF9D37AE87C6D36E611C1AD
+:1004800077EBB24751BFDB996F8D4AF25257106E2E
+:100490003BE69F50BE6A64EB221CE73A078D63C7B8
+:1004A000FC938B3085C0BF15E5EBF4061E5FC805D5
+:1004B0007D8CF49B3B9AD3A1BD8EE7A1C83C1399D8
+:1004C0001722F1502DF09B3B765111CAC1B54AF06D
+:1004D0005171AE99CBFF0D4E715E19EC6BCFC079A7
+:1004E000E43EC6FB0F3798F8796437AF778CD1F9C3
+:1004F00079A02FF839BB8E729E7732283F2509AF3D
+:10050000323FE5C9B4E011E497E4F3CB924E12D642
+:100510008FCE476F3BC4EDFAEA060BCDA36FC9350A
+:10052000E497EC5B6262A8FFABBBAD9CEE92C6DBCE
+:1005300056676151EC578BD8517ECAF5FF32BB1616
+:10054000D6B514FDBE475A6B2F3A05383EDA1AA0CD
+:10055000B2CFAE74AA17D2F9D2B928A99ED8F2F9AF
+:10056000B55A0EE6DBC40B142099E7B77E3493EA44
+:1005700099F177B0FEEA16CFD73490C37D63E23BA2
+:100580001478FFFF797FC4DB911673197BF7A1877D
+:1005900066861D5F41DFFD9125E7719C41BDD3C497
+:1005A0007A56C5C85F24F45D2597875E8785EC255C
+:1005B000AFC83F6535221F15233B505F99534E71DD
+:1005C0007B07D30FC4B03D8F9FCF8276A2FF956388
+:1005D000B87FDA26E882E549BF544F18E5DBCA2226
+:1005E000377DDF2F8F0F5823DC3FC6C77FE3E90B32
+:1005F00028BE25F36A1973E5CFB980F26C0CF5FBC0
+:10060000ECE21CA6E6CAC773EC2BCDC2EE15F5369C
+:100610006730C58BF3443E047BEE8D2BBF5B867C3D
+:1006200074E6E0F747A35CBBCA02FB8221E4D8EE84
+:100630001C2EC7FACC8E350A7C57E30C8EF0C2FA1A
+:10064000BF953A77061E29A81B31CD82471758F867
+:100650005115F19A29E8C43D87C3E7AE0928987778
+:10066000BAD2CEC7CD0C6A7E3AF7109CA35C077055
+:10067000AF54B8BC868FD2C98E2AD5D3F11C61A3E2
+:1006800038D7AA0AB97149E72615EDF59FB7BE35E7
+:1006900055D306E0FB858887FFA2C8783EA2DCCB55
+:1006A000ED6259CE56F50B90FE56ADF0BC36F31206
+:1006B0007CCEE9F8CAB4659598A77D556A4B25FAB2
+:1006C00069073D4F87E76509752B7FAFD1162FC0AE
+:1006D00073E60BEDC149888FCFE7BD7B27CA873B07
+:1006E00073DF7807F324DE300B3991AF88F5EE988D
+:1006F0009E06EB79ACD82DF23C6C440FC7C6723F16
+:10070000647F1EDB3885F2FA66CEE1E749AF65B15A
+:10071000B61EF89E9C15D03E637211D9913345DE0A
+:10072000C58CB70269E8179871435C43393A9C5D00
+:100730007495D7ACF724F0C3D5BAB17E6DA9B1FEDC
+:10074000359FB1FE8DC97F1A9B587FD9EE9F8DF4DE
+:10075000F4BCC2F33EC3973017D1BD4709A3FD32A5
+:10076000E1995C710E97E727FEABD8773D3399513D
+:100770007BD63EDB2E3C3720FDD7AA689FE065B6CE
+:10078000C20C7EEF03EABBB822F21C3D14D3610712
+:100790006F75713F2EBC6B817E0ECED3893FAA460A
+:1007A000DA52904EB21C267639F252A58DEC9A237D
+:1007B00082EEE4B9EA2A8D0530CF02869C83E51BE0
+:1007C00066D78BE8A70E7FC818E7DB691AE55B8A56
+:1007D00031185B41F587045D1F91F2FF079A585766
+:1007E000E04018EFECFA5C1E872E65745EFE6C65C7
+:1007F00009D525DD4BFE01AE1E8DA14145F427E94B
+:10080000F9A74E0BD1837ABF49F8BB34130259EADA
+:10081000927080B8C9423DC9C8FE9571BA7C9B6C84
+:10082000D7FCF87E0E93757EDE2B4BD4A1296AAAE5
+:1008300040FDFCF2EF487F3B7C419C8725CD46E79D
+:100840009386E3A35D827F7625F1914BBB9AF8E80E
+:10085000A7CE923B08EE6B9C2ED4AFA53097BA0C76
+:100860002AFD232AF03BCE4F6A8A4F47BEF966ED38
+:10087000F1A95A829C86EF9BF8F7A9C6EFBDF07DDF
+:1008800046C2F769F07DD9E0EF773B6D51D344EC78
+:10089000A74AEF217D18A5C95E23E6AD66F1EFAE4C
+:1008A0001179B1A3D3E07DD45BA5C63C1336D967DB
+:1008B000A3FCE4A4BC92AB94E539C85757DB9ABAC1
+:1008C0007BA0BF97C53A5E650A7EE682E72FCF2DF3
+:1008D000398AFC576B8B6898D7772D8BAEC2C5EDE4
+:1008E0009B167CC45D4CF2E159E4936635383603BF
+:1008F000EA67CCEDA36F2D22FE79CE9B39185E49B5
+:1009000027125EA417A43F492FC970F7AFE7D73B62
+:1009100029116F3BD851584ABB8AB1169E77ADE773
+:100920000FCC0B886886AD6534DA352F2F0993DC40
+:10093000B8CAFD00E565BD9C1BFC4F946775177E2A
+:1009400052A0E1CBDE796371DF00F0C6FE37E1959E
+:10095000F6E3A0BCE30F2D86BCE3E1F84C8E1B420E
+:10096000BB50C5FCE49D94471C9AE3F0E1799110DB
+:10097000E6C15652FC8AECC2E7146E6F87159BB035
+:10098000E3CE373F99717BAFA9DFDE33E4D77794AD
+:1009900073B83B6ED5E5FD35DC5E9CC7B83D394B81
+:1009A000B42F7451BBCCC3EFD8C9FD861D4F8FD572
+:1009B000B15FB003C97E60E9C2CE2C32DE9B837F7B
+:1009C0004AD640DEF86633B75FB7997C5594E76244
+:1009D000E1F7E29C91FE8C317CFC64FF626E8E62DA
+:1009E000884FF7D7FF4EFEC55277303F07FA5B5866
+:1009F000E62F504C0817F733027D3E1C6398FED655
+:100A0000321AEDFEAB59CB9BA662A2CFE21CA4CF5B
+:100A100009409FC506FA1C9D93C9E524C225E9B388
+:100A20009F2E4B93F3CA8217603F1DEECE5F35A316
+:100A3000BDDC6DF5F1BC5A9E27982C0712E059A039
+:100A400071783CAA4AF04CC27193E1391F3E49A427
+:100A5000CF6CC6F961387EC9D658D85931C02F2F0E
+:100A6000DB8335087F3FDFACE2FBA34170AB0EA216
+:100A7000AFEB6FE47194502AD747184FC981F167E3
+:100A800089F1AF5FCBE9F0FA7FB110DD02F8518454
+:100A90007FB6689FD5DD447954B36BCC2712ED0047
+:100AA00019B7A913EFCDF1949B9105E6CC34C64B51
+:100AB000EA6EE2F19AEB588B19E1BD7E8EB19F3A56
+:100AC000B6FE13CC0BABBBC9F83C98D31F67198B90
+:100AD0007196A3C28FD007FC82FCF4D3CCC50FDF84
+:100AE0000AF43BF6876515E877BA326BC9EE4D50CC
+:100AF000FFF1B6F154FF69D6B7BFF306B6EF28A1F0
+:100B00007A0D26B9E13E08F911F54DD58DD714C1FE
+:100B1000B847EDA2DF5BF939026F4AB06316BCE754
+:100B20009D388AF2216B84BCE95BC8DBAFBDD0C9BC
+:100B3000535E6FD6C9DF5893C2EFF579ADFCBF2B7A
+:100B4000303FB76694A8573C3F1EEB47954FE81ED1
+:100B500080DE268786F86FCEE57EDA09A54A741C0A
+:100B6000E0A52643F4DFC4E735B3E2D15CE48F9A15
+:100B70006ADECF04DFB4B5C5F89EE92CD57B736D72
+:100B800069280F259FB5E770FD2CEDA980E0FB6774
+:100B9000FCEFB68D807E0336C587530C4C7E97DF05
+:100BA0005FE5E0E7CB02FE220DFDBCD3FD3C7FB349
+:100BB000DAB62207F7E75F0F5A2A715E2E5BF9510A
+:100BC000B46FD2274F9B44F9BE3666463D0774DFAB
+:100BD000417C78F1270569486C0E23DD4BBA9A25D4
+:100BE000E9BDC648D7C0AFDB7232BF5C5E1BE8DA36
+:100BF0003E40D7C3D9B900D78F09AEA946FDD53F2E
+:100C00004E125F268F3B9CBCC0BF44793A005F27E1
+:100C1000F15F1E66C515237FB64BFEEC42382CA64D
+:100C2000189DB329547CE3E960EA307686842F1F4F
+:100C30007DAE1583E1C23F4DDA7FFCCF83FBF23CF2
+:100C4000D10EDFF959C6005C30FE2B240F577178A6
+:100C5000B62B2D5CBE087B5CEEE79BE57CBB8CF382
+:100C6000AD4AE1E7DEBDE87721DF7BF9F87EB8CF5A
+:100C7000631DE47C42426FCFB1059C1698DB75EE94
+:100C80007AA29F1B58F869B48F963983FF17F174C5
+:100C9000C4143E84FB9C85CC4FF157A08F77721211
+:100CA000EC0D096F329E9A8791A7C9F349C6CFC050
+:100CB000BAC5C8BE93E7D8FAE77B9EF3947689C796
+:100CC00062F4776508FF5486F0472145A17E9EC9EE
+:100CD000527CB82F98EE53C8BE98C96C249767D63B
+:100CE000727D9EE1E0F687D4FBC3F1C7159733927E
+:100CF00057331B993837C7E7954C87D9ACE70E2C8B
+:100D000067DAF4AD0B90EFD14ED107E09FE9E07EBA
+:100D1000ECEC5C213F58CF24D4F3FDF5417ABE675B
+:100D200012CA9FE4FBC9669EE3FED28C738CCA99FB
+:100D3000BE7727A19ECFA8ED998472CCE9F27B7390
+:100D4000270DDC1F988CC7D1B92619873B2FFA4C89
+:100D5000E61F193F6B7306C7E238D2CF714689553B
+:100D6000E14B151E97E83F588474EC76154D43FF10
+:100D7000C51C1BE82318BACB15BC3017E9ED8F0052
+:100D80000F6E0EF155C0E37535C17B343E2CE1E1A9
+:100D90003681872B855E3DFBB04AF1891A7FE94396
+:100DA000184208BD626611E2573FE94579BFD8593C
+:100DB00030A0A2F8FE634EB23316BF5A4FF195B180
+:100DC0005B4C4C4FD093E32229867B3226ECCB3010
+:100DD000D42FE8CC35BC7F61D728437B7974BCA184
+:100DE000FDA2572A0CF549B12986F72F7EABDA50C0
+:100DF000BFA4E71AC3FB533F986DA883C6D070DE2B
+:100E00007B9F55D83698F765F16F19BEFFCDB6199F
+:100E1000AF60BCF3A4D8F7B2B03F560A785820E9C7
+:100E2000F6DC7C637F5125AA5421DFF3BF05EB7903
+:100E3000BEF634C05C62BF0BDB8DF6C4E22DC67A11
+:100E400043F7A655281B07E779B454E35539C97908
+:100E50001E35AE7926A4CF502ED817E31011EC62C0
+:100E6000CC331B8ECFBF6CFD4BD8E82F5B7FFEFED3
+:100E7000160BD9F58B5F7DAA2A0A8FAC5EE3FADBED
+:100E800075E3FAA7961AD7DFE933AE7FFA64E3FA7F
+:100E9000BBFDC6F51F516B5CFFCC8071FDB3EB8CC5
+:100EA000EB9F1334AEFFC806E3FAE7B718D7BB7061
+:100EB00099713D8BC24B0DEDC9EB2FE565F19ADBC6
+:100EC0008CEF017A4D097420E96841A081F277C660
+:100ED000B47FCF304E323DC0BED144F7BFC13E6E6D
+:100EE0009B72FEF401D28AFCBDC9F4F16FB9C2EE67
+:100EF000147401FAA813E50AD8174F61593756D868
+:100F0000FB81A1ED0B29BF12F579E2BE7838B93625
+:100F1000484F897DF2B07A0AF7C9F6817DF270F404
+:100F20007B1CB38FC88E5A4F7EA51B5D1C8E4FF164
+:100F3000D125E8CF7D82F4F271007032C07B1CE7CE
+:100F400003E31F4F9940FE8D6FB328D9EDFF82193F
+:100F50009630D8CD98A8ADE23D4F3A95F5426F2F27
+:100F600014FE8F85F6E05BB9DCEF519885E3E6C5AA
+:100F7000E8BC147B6DC479DD237102E30820784F4F
+:100F8000611C01CA5E3BA79BD352AEF899EE49C0E3
+:100F9000E7FCE94A29D9B56A0AE53DCDBF4121FD03
+:100FA00034FF7F781917FA2CB95CB94CE2B35DD8DD
+:100FB00003DC2E48C7C39A1477624107E1CDE7C22C
+:100FC0007586FEB81FFF47FC7CCDE30AD32667D0A9
+:100FD00031335A675C6F3C0FA5DA389C8F9B990DB3
+:100FE000F1398105C90EBC5703D1C6FB1BCFFB7B72
+:100FF0006314FAD354F5FF7CAD06E3CF382EFA9F85
+:101000001D3E86FE66D5EB63E8BF1AF4FCC014BA39
+:1010100024A3BFCEF87BF88778917EC23C412FBBDA
+:101020009D8CFBBD92FC86235590C098BF63E6E77C
+:10103000C3BDDA16BE9F3CE65B634D9837636637E7
+:101040009EE7FB327B08F36D4F27E4C7C3BA0C79E8
+:101050008FE9B43CAEEF57B6365C8671A25E1107DD
+:10106000BBA7357819AEB7AAF9282F0EEF5772270C
+:101070007C6FF1407B029F6A8E0643DDEC08105EB8
+:1010800056B5B610DD98C53D50ABF36E730513FC35
+:1010900012178E14F6862DCC5C594C98C6F0F7C109
+:1010A0007486F3555DDAE9C47DA8D50BFD25CA2BFE
+:1010B000AD9025FAADD7B4B610DCAB9460103BB35D
+:1010C0008E66513BE0DBAAE1595478BEF52A92675F
+:1010D00016E76D3EBCF76738FC59BDDAE78972C880
+:1010E0003FD22887EE6FB55D8EF85AD9BA8CC69379
+:1010F000786B6F755D8EF58DAD5ED1BE82DA4DB5C4
+:10110000BA82F4711A6821867116ADC789713DB033
+:101110003319C603CD5E5B0499C8EAE1F0B2A305BA
+:10112000441F735D1C06F48DE5037DBCB3CC4CFB02
+:10113000D3DBF31DF4FEEDAF8F79D10F7C60011E80
+:1011400051FF8AF9F48F23F06711728869C100F2A8
+:10115000952557237F74866B36ADE3DFDA9FC4BBDA
+:10116000C5CE281FD492EF20BBEB7CE10C8D14F789
+:101170005009BC27E30FF04472F47681A7DBEFE25D
+:101180007EBEDBEF6094C7CE96C15FD5005D8D1447
+:10119000F2259B05A86C6F05C15282EB6563410B7C
+:1011A000E875D6492FDBD1BF83ED7ECD8DA1EA4D09
+:1011B000359E59586E9C7CAA1DD9F1BE4B3F8B6160
+:1011C00089BE74C497AB8145F0CC1FC58E3D781D98
+:1011D00035AFA789F6B43A5E4F17EDE9015ECFF758
+:1011E0003FA9D4206049F1977C47C6D5A351BE2DB5
+:1011F00060FC7CB2B8E7603B13F2C29131AB06DB16
+:101200006F6274BE40B6FF50B4E7384EAC29463921
+:101210003CC7F8FD5681876CC789F6E9149F31B643
+:10122000CBF84AA6E3EC2BF47D99B1FD41F1BDD397
+:101230007136361DDB471BC7DF20DA531D3CEF0834
+:10124000C4213F472FDAEF15ED766CC7F14B8DEDDA
+:101250006BC5F82B9500AD433F9F89F8E48E569DF2
+:10126000EAC97CF6EAC80C7E8E59F0996B191BF21C
+:10127000DCFCAB2379BE4C9ADEE3F70F210F657BD4
+:10128000864BA3B8AFEAB5101D591D428E083EEC3F
+:1012900097234A8B8F1317F7977F193D03E17E8EB3
+:1012A000F2AC00FE909EF3BE6362C1047996DB98B7
+:1012B000C28209EF7B176418EA5937E51ADEF7CCCA
+:1012C00019656877548E37B4B3583EF1C76D82AE56
+:1012D00052CA2A0CEDF2BE02A6733E9276B579F49C
+:1012E00014C37B674BF574A4EDD357CBFBAB7C36B3
+:1012F000940BB7394765231FFEA475321ADF20EF20
+:101300006CA27489D24B47C956B6EAA25E4AF5C7A9
+:10131000DC3CAF7A65AB8FD78B189D6F5ED95A4B8B
+:10132000F5C7812FB1FCD7563F957BA00E160EFB5B
+:1013300011F4AF433F3BA17FAC3F02FD63B91DFAFF
+:10134000C7F287D03FB66F857EB1FE10C085E583BA
+:10135000D00F3E7F00FAC7FAA6D600D5EF6BADA33B
+:10136000FA86D62095F7B636D0F3B5AD2D545FDDAD
+:10137000BA8CCA7B5AC354AE6C5D43ED16A1371FBD
+:1013800013E71F1F9BC6CF7D27AF7F469EF2D5EE8A
+:10139000BBA804455E65C893C8C8C37D75A7312F37
+:1013A00010F14770D8391E93E1182BE018CF622B4B
+:1013B00052B9DCA038EB982EDFDDA9C0A7235BF87B
+:1013C000BA1775C5A93DA7818F3756CC9379C22C22
+:1013D000AF8A1FEFC5F77A9558752A8F37931F8309
+:1013E00079013F55E2DC339179C484706993417F80
+:1013F00027CCB31F5F6E0E27E26D28782BF2787C26
+:1014000043ADECE4F79BD4B64791CD52FC2D74BFAD
+:1014100089AD2E10D5A0F40482744FC2F8733360E6
+:10142000930572EDDCE54C8732AFD1B8FFCA5D5051
+:1014300061D8E7A8E73632FD22E8B7CCB84F4A19A1
+:101440007D9BE13B5BDEF70CED16CFDD86F6F9B751
+:1014500014ADF2223E47328A3B59D7AF603900D7EC
+:10146000C28E4D045750E0BD57D1F9FDEDFBC5EFDD
+:101470004408FBFFC72E812FDB7ADAD78E75F36A1B
+:10148000497AD884FAE7E3A7D2498EEE7DC444FEB8
+:10149000ED712C6242793301CC486CBF006F7256FB
+:1014A000E9CA1C15EBE54C57B17E118BD3BE08EC95
+:1014B000FF3AA417B0FF1FB143FD4C7EF0C73CBFFD
+:1014C0002B4A7ABA44AC6789DC076DD192FDC373AD
+:1014D000F3C85F633C07D626F6012BDC55D918EF1D
+:1014E000ED1D26FFCEE9FDD6D405B01ECE9C3A2ACE
+:1014F000E5F30DBA69C873D1CBBE2ABF6C013D625A
+:10150000E4976508FF99CA9F67A1BBAA79749CF804
+:10151000A6CD2CE5989E8E726CA0EE4B27BBA23B0D
+:1015200087F0A389F5D9DB1AA4FC00394FED77D3F6
+:101530005C980F5622F24FF7B5DE3AB526211F66AA
+:10154000B7A0DF5216AB453D5A5A66F245A827AF01
+:10155000C17F611FDDEEC773FA5A05F3A1181EC7DC
+:10156000DAE9BCBAF6854A7940DA914B980E76B042
+:10157000C31165E1B2817E99F0837C47C8F5CF5CE9
+:1015800035340FAD40DA473ED4DDEC33873F867407
+:10159000F7598799B3E509637BA983919E5B546AE8
+:1015A00089E80AA623B4D33D8BDA0E85E515211C04
+:1015B000D3BDF3508F1F4C25BA4DDD524557C37B29
+:1015C0004CC1F57900C7991EFDA0491A57F05ED3AA
+:1015D00004CB2EB41BC7225E709CD1A584C7856244
+:1015E000BEFB5A57109E9E15F368CBEFC73B87870B
+:1015F000F9FC78CFE9A20EE9BF31CE734365F53728
+:10160000F0DEC6953155D874467CAE33C726CE532E
+:1016100006E002389F453855849BFCBF7C7E4D8F89
+:1016200070BF19C8B15A8ABB4E32B1C4B8AB2CA333
+:1016300042FECDC87311BC4EEFDCA90B2E4AACDFC5
+:101640004474FDB8C2E71F766A3C2FCDEFD713FD77
+:10165000C4EBE47E599C7F4811F0F6DFE3369EE749
+:10166000613A586C0BE62D0DB71FFE252ECAA4C497
+:10167000FD30E81818579D64A33C9F75328F4B7F4F
+:1016800043C77C332CF1FC8A4DD0E96AA731AFE423
+:101690005C1EB777CE89F5E8B371BEC6B8647956DB
+:1016A000C2BD17DDF5E4FF9171CCBE6E9E0F2EFD1D
+:1016B0006B4B0409F41DE578E87B58A5F8E592EE3C
+:1016C0006BF97DA1871EA07B56A12F1DE9A15EBCF1
+:1016D0005FBFC6E8EF59B03BB02A451FEC575AC46C
+:1016E000C2E4D748F62725FB917E9B27F6693E5634
+:1016F0008E71CA93EB8B8FA5E07EA688D1B9DB9162
+:10170000EA93748F3158FBED784F292BE3F7F424DB
+:10171000AFFB250516C2F33EB9AE631CE467D837AC
+:1017200089F3FFBE17CF7E7D0CF4F396AE18CE8101
+:10173000BCA59B098FE381AEB1EC64AC76A8FBA09D
+:10174000B2F34D5FEDBCC0A5C6DFD768EAEA3996B3
+:10175000AA93BCCBCA0778FA8EFD3EAD8CF8274E13
+:10176000BF075157C4E141B8F1FCCB7ED3277313B7
+:10177000E9607CBEC6ED837CD35793BF3546B8CEB7
+:1017800094BD99750D876B1CC2D51B3D919568B7AB
+:1017900048B8F60F73BFFAA55F154F938DFA200175
+:1017A0004F53FF129EF65B86866796C0CF4F8EF230
+:1017B000FB4206B77F45FDD56184F7CC63B1EB51A1
+:1017C0003C02BCB3087FDE5359143315F8EBAC145C
+:1017D000F45929E48E8FCEA8B0D0DB17537E5EA7D4
+:1017E000C6DB43772E8AE07902DF8B0B0AD1DFE07C
+:1017F0003C6EA57B9E42497922B25C2FE6B13F57F1
+:1018000019120FABF3B9BC78F1B5F9D4DFBD6F593C
+:1018100019CA83ED22DFF55E57A70DEFEF9578C467
+:101820007A0594214B7C112ABA7B2B3FB3E98E2198
+:10183000C633F1F1EE4BE21B399E2C57E49772BB95
+:101840005439AAE23987FB2E7D93EED9BAAF5223E1
+:1018500099FB37E37F7D12FEA36F667D9DD3CB8A14
+:101860007CF4A32AEFA57D03EA2125FEB332C49FB1
+:101870002548F30FBD6D653B95C1786A14F42BE7DD
+:1018800027E72FE1765EB680CE99E07A20E0ABC5FF
+:10189000FB524FA40BBD87F3223D71A9C6CF894CE3
+:1018A000D2685DEF9B3C85CEF5EC17F914F14B2C1B
+:1018B00043FE2EC333026FF79EFB450CEFA90D7755
+:1018C0009BE95E05A6F578BF0974147A5DA37B9A3F
+:1018D000819E6AF1DEA8175F3B9B86FBE803F966F1
+:1018E00082FB403E97877DE7D45A3A6FF3DA672E42
+:1018F0003581FE9FCE57855D128BE1399A8D15FC9F
+:10190000DC8043D8018ED74E3520FC8EC9DFB32A48
+:10191000097A764FBE95BEDB688967F9300E744848
+:101920006551EEDFA1FBEFFACF0BBA381E9A2B8F71
+:10193000929DE0E8E6F7E23D9DAF135C08F7417841
+:101940009E32EE33573DB657C278A306BE77BAF83B
+:101950007AA64CE2F7D0DC77E9CF5D78EF5EBAC2C9
+:10196000E8FEE84B0ACC06395E5FC4D7A1B3321655
+:101970001B85FCE5D228AFB6337A9B0DED7AC917EB
+:10198000A347A9F4DD6A9197BE7A7229F199A4E37D
+:10199000B905C157916E36025F3C49764E2C309D99
+:1019A000F0E32AC7FCE3C795581DB73F2C2ED42F70
+:1019B000A5269381DF8A0B38DDC812EC52B277EE90
+:1019C00010B42CF57D5BC4C630BFFFB7E766A5A396
+:1019D0005DDA9627ED3CBF0DF1B55D09A417E1383E
+:1019E000FFA5D2BEEFC5D74E34E0B86D302FE4DB93
+:1019F0007B7EEA588FF6499BCB4F7C2AC7D7DC26E3
+:101A0000B11EBC9FFD16FF2BE86F8CBBF97D4447D0
+:101A1000A65C6343FA87F74CD8CF7BADF80B1AD896
+:101A20004F0DF90716BA66CFC0EF16B1E02AB46BB6
+:101A30001775A8867B17EE11F262E1B914164DD81E
+:101A40001F2C9CFC2D3A37B6F05C1A8B82BD758F2B
+:101A500038177D8F3857C40A383D3B44E915E5DF18
+:101A6000CCF7BE24BD95F9CBBDF339DFB302E8B79F
+:101A700049E9B114C1101BA7FC9ECEEBBCD7EA62AA
+:101A8000D192047807CD73048B268CD3FFDE391BEB
+:101A9000CD67607D39FD0ECCD7417878AFD54B78D6
+:101AA0001CBEFF91063C0EF43FCA80C7C1FD97D013
+:101AB000F8EFB5967E49FF1386E95F37C03FD0EF58
+:101AC000681AB7F7C8FC1FA702DF1D89DEBDEDF954
+:101AD0004AFC1D332BFD7E01EBEAACA673848F33E9
+:101AE0003A677AE7E1DFBD83F99A77EEB2F8708C56
+:101AF0003E737CAE6F083D339AB9C2789F972CC76E
+:101B00001714D37C929FDBB4880BF3326DA59A0B2C
+:101B10007F1FD1C66291BB71DF5269233927E3422F
+:101B2000B2DF3FE5A9F23C3BC907796FCB12919731
+:101B300057EC085E81EBBED4D4DEFC13F8F683D2FA
+:101B4000363A37CC989BF633326EA3E12FBF15A3FC
+:101B50005F30C0F0FCCD137A70067EF74310271873
+:101B6000C7512FD81DC4BCB50D62DFB8C11EF3FA32
+:101B700012E4E60D05DA57B317DA93E876D22FF7B9
+:101B80004639DDDE50807E2235F6C4FC22CCB7ED2E
+:101B900011F776E9168A77551EA3FBFEE6CB7DFF8B
+:101BA0009AE4BC8E7C37DAD132CE94867977686B32
+:101BB0006CE4F7BED5A7F27AFD7F8CA07310B0FF5E
+:101BC000492D43F9B25FE5FE2011DF3A2BE6D067DD
+:101BD000DB5840F9F7221FE46CF74B74AFE4D935BA
+:101BE0006368FDEB5FF83EDD0BB73F97EBB1BE439B
+:101BF0004ED263F5565F15DE5BB83F97DBAB9D5A5F
+:101C000034AD22C17E5D9D574DF2F9E335634C89B9
+:101C1000F18FEF0A79B051FA37B578159E67F9B8A8
+:101C200032FA33D2A307ECF43B51A683BFABA2FB3D
+:101C30002D375AE97701AA0F8EDB5C87FBC3348D01
+:101C4000F2914D07ED04CF9975FC7E2DFC16E55DF4
+:101C5000D3C191F4FB56F5A971CA276C4AF195607E
+:101C6000DCAFFEE054BAD7FFE486710528FF4E646E
+:101C7000EA0574AFF1063CF409F54363F9F3B517CF
+:101C8000D37955E7C6D4E0507E10A98F92EFEFDAF2
+:101C90009F5BDEDB85F81967F3A1FC7D4FF1F1B89E
+:101CA000EF2BF1D93AC515F9F9D27AD769FA7DBC8B
+:101CB000FA8E776F62F4DC43742BF773C9E3D50BAC
+:101CC0007DB5DF129F8BBF4B56BF52E05DFC4E626D
+:101CD000BDA99C7EAF4FE27D63D23DB74F08FD2486
+:101CE000CB93AF69745F20D81105E81F3A79D84AC1
+:101CF000747672E3043AAF2EC7AB079CB8802F4FBF
+:101D000064E813715D9F16F2AA7E25DFA7CAE7304B
+:101D10007E0C7FE7307E48A5BCAE3E573C0DE3927B
+:101D2000F23D59EF9F4FB74ABF97B53FF7455A6FFE
+:101D3000A02786F4647AC1497A3AF4827517AEE72F
+:101D4000C7952C8CFECFF05BFCF7C78E1CB292FDC2
+:101D5000DC779CEF6F07DD9FE68817E0FDA1A117F8
+:101D600046921CEBCB8FEFE0F6B69DDFABF846F06A
+:101D70006211FFCD11F711E6A09DF7F9217B14ED5B
+:101D80003C28299E1066BBBDF4FC702A43FF0F94CB
+:101D900014CF63CA012FFDEE0C6B17DFC7E8FB3BC6
+:101DA0000B8263512EDF590CFD3BF0FB53F4DEE751
+:101DB000A38217520C8AB15C315E2EF59B1F2CA4B6
+:101DC000E7CA675EFE7B2AEDA23D46ED216BF0621D
+:101DD0009AC7AF9C6CE710F3FCAAF7EE1D2D1841D3
+:101DE000EB28E1063C93DD988C97B30526F17B3B0D
+:101DF0001C1FC974D9BF9E5F021FFA5FE8BCF621A1
+:101E0000BE8EEBC659B81C593B81EC63D69662C8AE
+:101E10009F5B7188DFC3D0BBC149EBDC67F63F84B1
+:101E2000FA28FE8699F17BEDC022403FC5E4A1F976
+:101E3000E523914FBF642DCFB3FBE8D1F70BE63913
+:101E4000F05CF2FB8673C9D25F089DA4A13FC6E196
+:101E5000D3D3E697717B5D25F8F8EF7A6D34EBF418
+:101E6000BB6BE10DE3C81F71D2A21FA4DF875B77B4
+:101E70008109E94A2D17F277139F9FBC2F4BDE7B18
+:101E8000958C9F8AC262927F4D2C7833DEA17E8230
+:101E9000E959C26146F7FF917BDF8469889A9FE226
+:101EA000B6AC85F4C2E07BF62C5FF2BB6CFFBBF5F1
+:101EB0002A5C2BF4EF9587D350AF7EE0E2FB463AE5
+:101EC0007D8F7A5DE5F36CC30F30AF8305A6144EAA
+:101ED000A27692871F28BC5DCAB941F3477AC17EBA
+:101EE000F03DE8EB9A42EE7F63AE0C71C82B6CC1FB
+:101EF0003C4DA99F428A66C273F3A7DC7A1AD2E3EB
+:101F0000A9B5C5192B300FC6AD6725DAD5A1A38CAD
+:101F1000CE8BEB78DFF8C5F8FB32FE89E8F7DB9F64
+:101F200061F43B24C3F3E4B49EB989ED730AB99E0E
+:101F30009B5F28F699854CE45726E38DAFFB62B191
+:101F4000EE6A79F072DA8726BDB7784BBAA087A41B
+:101F5000E7EDCF7F97F2A01E36DE1349B15F18EF91
+:101F600083572C61E5422C5328AFBD611397730D45
+:101F7000AFCE2CB98BD7E95E85693BEFA1DFE35982
+:101F8000B0EBCA12C6E516AD83A4C70505FE12B4B0
+:101F9000E3E25B5517F245C31695E051CD3ED756A7
+:101FA000787E7A8B99ECBB0601CFE9BC601AAD9BB9
+:101FB000C6340BE0FDB4164C23FB75ABF8DDA1A4D1
+:101FC00079C07B6F6A1543E0C7C6D799F0533C04CC
+:101FD0001DBC61A2755A80BF0B8970EC54C8BF79D3
+:101FE0003A3F7833D64FC1FE1FCFE9AB9B96D07DE9
+:101FF00036C9F83E6D0B127D2E16F391F84C1E4734
+:10200000E2B30FF189F6D22B5348EF851E5491624B
+:10201000D98BDD9FD2BE7CDAA12BDF998ACF3781A5
+:10202000DDA2A39E1DF5B36FA39E5BA3528C7AFE27
+:10203000A1E22C96A4AF71FF39FFF53969A6043DE2
+:10204000A93EC8F1A43AE7A42DA4F7CF7E1DE9EB81
+:1020500084EECBAA4878EFF1C2FEB88361BDEA37BF
+:10206000FD210DC769586FA679C975E9C379A07CB0
+:102070006B4F8D20FDF7E5C5A95FB94EFDF48DEBE3
+:1020800020E909DEFBAF429718274CF2E85451B023
+:10209000CA37049D2C7A00C6C5FEB638E9FED2F3D5
+:1020A0001D57E2A37FBD055F531DD7714711F9D1BD
+:1020B0004D6F6874C8E044FB5505C8C7F5A02FD024
+:1020C0006F51AFC4DFA17B640F59E91EE6FA4DB72B
+:1020D000DC8CE3D51FB79AB0FDD4E1AB26125C4986
+:1020E000EB0A782A188ADEFB8AE205BE04FC813DF1
+:1020F00041FC2DE7930037C101FB29BA8FA8AF0837
+:10210000D633410EBC59C8ED2E78DF6521FAE6F7CB
+:1021100061F5CFD795345F57D27CDF6444DFCC17AD
+:10212000A4F92C78DB6AC2E70BEEBFB604F73DA733
+:10213000D64DA7799DCAF04F44FE3A5500FD0F21B8
+:102140002F17DC0FF32CFB0BF36CB7D37A0D3BCFBF
+:102150008CF80EF617E6F989A04339CFF7343D0D18
+:10216000F3F943CFAA0CFD2EA1FCC0C6A9BC4EBFFB
+:10217000131732737A086D4AA57CDFDE6EFEFB040E
+:10218000520EC078E7490F26A28753D5FAE6C9D088
+:10219000DFFF073F3717B700800000001F8B0800E4
+:1021A0000000000000FFCD7D0B7854D5B5FF3E73D5
+:1021B00066269364924C12088140983C09908449A9
+:1021C00002888A767804D1020D4F798993071042EC
+:1021D0005EA0B5696BCD4002A2450D352A5AD401E7
+:1021E00081A2A20D0A0A15BC032A6245C5578BB607
+:1021F000E526405179C6A05EAEB5D7FFFAAD7D4E5B
+:1022000072CE9054DBDEFB7DFF7C1FDF669FFD5AA4
+:102210007BEDB5D75EAFBDE7C23DAACBEF16E2E4DA
+:10222000DD056FFFBC17A5F7AA2E81FC58DFCD0294
+:10223000F98FC32CFE144A938BA670FE659B6BA589
+:1022400022C489A6BFFD41A1FC857D36B7A0F20B53
+:102250002945F7CE467E8FEA5A41ED2F0C689F251F
+:102260008673B9D844E5EA5D239A502E1E1EE6CA4D
+:10227000A0F2F20D61426409FEFB56687F23E93B40
+:10228000520BA56B556F7834A54D2FFD44C9A56F32
+:1022900056378F57F3AB24F7DD347EB95558EDF937
+:1022A000A8DC9E392D4788F37B6D1303D9323F2379
+:1022B00087CB3FB052798D5DF85AF87BAD7D6A0EC1
+:1022C0008FE2B6D2388BA90F914AE9FA18EF60EA8B
+:1022D0007F318D9342E37D8BBF1F5C0EDF0ECBE71A
+:1022E0000B8AA89F7B6D62F673D95DF5F434DB4DE4
+:1022F0001DF6466D7B573B558825C63CE1A122243F
+:10230000BF14794757BE32A4BC2AA47C47BFCFA7CD
+:1023100014392F1F7F03C61FD185C7120D8F3B2C89
+:10232000F41DEB728F12D844FF2DB1BAEDCB09FE2C
+:10233000E7C6889BD14FA95538AECD47BD0E9E5FED
+:1023400089553486E5E3BB87EBE9F3A6FE1AC3E2C1
+:10235000281FD1CEE353BD8976439EDA9BE09AAB2A
+:10236000C1A3A74BB785BB4EEAF3A07F552DB1A6FD
+:102370007CCDEEBEAE93067C2FC57FFAD2BF49342A
+:10238000FB91C08BFCABDADD7A3092E8A74DF1CD42
+:102390007553BF170E7E1D9DEDE6751F5944EB9BCF
+:1023A000AFA63E7F98E6DBBE47F56C42BF6FD8FD17
+:1023B0004A0CFDE79B8B0F6EA7EFD52FA789BBDDDE
+:1023C0005DF30FC5E385DD17A353E9FBF943F60879
+:1023D000318CE6B9377EAC9DE862475C7BB778AF5D
+:1023E000D5D65DEFEFBCB5357AAAA1DE79D11A3D1D
+:1023F000CD402F25BB2FD68B5CC69F5FCDEFC2EFA4
+:10240000897DBDC7AAF4BDF4F7FDC65A28BD5FC3D8
+:10241000DBBD36F7136B096EFF9E30CF1682FBFCD7
+:102420001BB32D687FFE8D722DBDCDCBE95F4F2490
+:1024300063FC688BA4777DBC356E0BF7536A697BB0
+:10244000EC1ADA8FA5BFEB93D290D2555E6AC9CF52
+:10245000C43A6FB7B52F00DCE715B14689EBEAE760
+:102460007EB79BDB9FDFF3C963E00F27EE1D904F24
+:10247000644DF941B93E2A3FFF5141A68BFA3D7F99
+:102480004F5F0FF8C2769BFB36A6B7BBA23CD8F7CE
+:102490007A7F18A716FDEFB962A40FE947125ECA4A
+:1024A000E7FAE4B87E25BFABDF688BFBBED1E0174F
+:1024B000BFB779B650B2FCEF697D62313FECE76E91
+:1024C000D6A1744D98709BF8C94A86BB4478EC221B
+:1024D0004D960B03BD958922FEBEB0C9FC7D11F15E
+:1024E000097C5FBCDEFCBD5C34AD6EA5F92D09989E
+:1024F000BF0BDA3FFE04EC6BFDAFC55E14057AFF3F
+:1025000036CC544FF835FE401F095F25B41FC1C7B4
+:102510009E5102819558DFBB549E67E8BCDE75A7CB
+:1025200070BB8722FF6741AB615D8F5B843591F0A3
+:102530007ADC2E1C89F9E8470885FAF5EF0B0B6C5D
+:10254000A126770FFE2AB9047CAF31C22208BE5BF8
+:102550005DE07C42ACD8F74932FA295D53E86D352D
+:10256000C077C1E67DE8E7D4BEFD5DE2D754EFF861
+:10257000D840D35882EBF8DDAAA7A11BB84EAFB163
+:10258000884001E1E32E2102F1947FF293E4625A44
+:1025900097CFB67C925C62A47F45CC36D2A39E12C4
+:1025A00024BC3EEF61EFD2FC8ED35C309FD07A5DCD
+:1025B000EB6B8657C767B82A6ABBA387CF40F7542F
+:1025C0009EF5775578B1EFF7D902A0CFC88D5F3C63
+:1025D000380FF4B9D7E64AA1B16BF6A95E95E62D9E
+:1025E000F6A8810C9C637B4F4457E09CD953E05282
+:1025F0000DF3AED9A316E17C39BFFB62426936F711
+:1026000033C5ED44FB073CA0DF9EE0F89B5BFDF784
+:10261000F89FD7CCFFCE657F907003F8C0C6539962
+:10262000E0EFC407FFE6A6799ECFFCC68EBC10ADD6
+:1026300023417F045FB49BE0BC10F82A5A105C8EE3
+:10264000BDAA37D0CD3A44A5D8194FFF327C130923
+:10265000BE842EF8089EA894115D7056BBDBED3841
+:10266000672F38A273C14F694293F212B4F3C90DB8
+:10267000FE5A3A49107F1DBF67E1CA70C80B4D8AE8
+:10268000278CBE97ED55F9DC2ADB1B19C016183FC5
+:10269000C8C9F9D247D54018E527A8A3FF309BEA5F
+:1026A0002FBE47F5D08E14FB37DEF6071BD6758399
+:1026B0004DA01C88035C4B34B896ECFDE1670A8D95
+:1026C000B378DF2D0730CEE207140F17A8F3EDE83B
+:1026D00077C9438A88574067B6E3463A5BD864CEE9
+:1026E0002F12AD0B5415FCC1FC9DF09E5C41FD9674
+:1026F000EF0E73DD8DF102A1E542BC4AF0D468FF14
+:10270000CFCA583BF700D5CFDA68673C9C0F17E279
+:1027100008F6ABB53541200DB626631DCFEFF96B3A
+:1027200032D6B1E677FF9529BA59BFCEFDB437AAA4
+:10273000D7A94821AE4E51C4B7A9A0FB8B538ABA82
+:10274000A96F1B20F7C5369BBF9F87CA0F6CFC8AF9
+:10275000F9C1853DBE81AE6EE8B76BBFFAC32D8966
+:102760004883E102E9F016D70DD827240F62BE3561
+:102770009B564FDB44F9F0976C38B9444D8693F77C
+:102780000BF6C74243BFFA3ED906BE807484E40FFD
+:10279000B601F21C3DAA9D7BDBF6774CC9E8069E8C
+:1027A000A36E1BD7B30D105CEF5977D15CD05B845F
+:1027B000C51F0DBE2DBC5E772FC2B3A2D157435D9E
+:1027C000AD82EF89A289D3FEA285D34785F0395126
+:1027D0005F785CC0B3100362813FDEF38CCFBECC68
+:1027E000377FACAD217835E8C41F2B025BE8FFEAE8
+:1027F0004687506320EDB546A35154CEB4FB065234
+:10280000B9ED03D5A240DE1DA0AFA7C785FDF7A592
+:1028100073468C71FDF61F2E9988FEAA76A9228C2C
+:10282000FA3BB7D326824ED4A7FD027C1CFEC29E83
+:1028300002BEB4571190976B288FEF35A3ADDE80A1
+:10284000012F77A4D8180FD52999F29CB67A0F4D8D
+:10285000A27ECFBB4AEC90EB6D87CB26E2BCB125C4
+:1028600096D801D7FEC3631D2958B7582BEF9BD5C7
+:102870007BF5718FB8D07F54EC070C6F63B645447D
+:1028800053BBC6A3610146A643F2A1300DAF8DC173
+:10289000F10E7737EBE317E393C4282ADFA94E0440
+:1028A0009CE75C252EACA32D96E8EE0A6A6FF34EEA
+:1028B000BC9AFA0D8B8D8B077C6B52D2783DBF8A08
+:1028C000AD6538BF22F1C2CFFBB7B608F9C6FE65C9
+:1028D0002AE3BEE921DECF350E397ED43E95CF51B5
+:1028E00071A543E3DBEFBB4A699C05C9BE47410FB5
+:1028F0009DFC6DC4AB02FC39CB6261F9ACF135E7EC
+:102900005AF021BDFC6C8AA4377D3D56F5B2BAC0A1
+:102910003F1ED5E87395ABC8916F98A7ADB745C377
+:1029200057910378DA612F3A84F3A59DBEE3DC3C2E
+:102930009038CD013D85EA59D0CFA97ADA3176F4C5
+:102940003BC301FC2EEA553201ED168BDAD5D86F68
+:102950008BD7AB2268E0AB8D3639EEA24B11221833
+:10296000DF35EE225A3F6E7F295A04E9DC6D0C9761
+:10297000F51AA3E4FE792345EE9F0FB5F9B469F982
+:102980007F99AF7BCC7CFD5CEC1FB69648FEFE4683
+:102990000AF55BA5B44E48A1F9AD4EECB003BFA754
+:1029A000EA5D22986980F7B279C68BA061DCCE7AA5
+:1029B000971C3C9FAEF57033FC5DF375321E4ED50F
+:1029C00027321E7BEE3FC984C7AEFE534D78BCBC98
+:1029D000FF4C1EFF547DD677F43FB487FEDD26F80A
+:1029E000BBFA4DE771C56EDF40F0973B5DC40F98B1
+:1029F0006E885F50B95DF13D7E35E4DB8FC204E443
+:102A0000BEAFC27D835C06FEF00DCE65D6E782497F
+:102A1000E0B77ED1CC69CDEE8B13D0DE4D7C01FBCF
+:102A2000492FAF11ED0C27F885E88335B4BAB97C8E
+:102A3000B76F10F4221D8E4E79E675A7DF42FB209A
+:102A40006CDFDFA3B18F2F58DBA778286DD9AB4699
+:102A50001AF7757CAAA4A7B103BEC86DA5EFD56807
+:102A6000477CEFB697970E027EAAC3DA7301F7810F
+:102A700097FF968B73E4AB7D4B07E2FB36AACFF250
+:102A800087BDBDDA63E82F5DB8FC96515DA933556B
+:102A9000EEFFD0EFDBF635F4031CDB89BD09920BAA
+:102AA000ABEB2A0A4EC6830D79EF07FF12C4B75865
+:102AB0001FDA3D5D1D03F9EE439279283F7C8F9428
+:102AC0001B860F10014B0AE4BE0F67834F548FB073
+:102AD000BBA00A47E41D61793B6284C3A550FDBFDA
+:102AE000F797E3DB212FA4A17D613CE8F9CA64F1EB
+:102AF000EFC96D1B42F64FF0BDEAED345E95DA3A50
+:102B0000659CC2FB283F157CFBAD2FDED6F4D704B5
+:102B1000ACCF019C6B04CFFB5A3F65A9BE2B50CFB5
+:102B2000E768BDE70AAA377356DF64E847C59A7EAF
+:102B300026261152AE647E94033BC8E5E7B6D483E3
+:102B40005E527C3EE0C1DFD7E1C1F935344938FA45
+:102B5000125E456220751A8D3B21D5A2DB0F14C091
+:102B60003D449BE333FD5A96C7F2391988031DFD96
+:102B7000B3E34E4BF54E06FC7AFD0F67CDCBF175F6
+:102B8000736EE8F2BCDDDEB20C70B65739597FFCCB
+:102B90000045D4EE89596141351A7A8A730DF4F9EA
+:102BA000A3910B0EF6267C8C8FF2CD43FFB36FBC46
+:102BB0007E35F2CA8178F772D07371EB48D6EFC2D6
+:102BC0007D37A3BCD2E11B9840533C37C037280661
+:102BD000877C51BC5C27519453D42DFC129E6245D6
+:102BE0008EDF18E52B473FC596238F5D816FD62377
+:102BF0006C6F108DBDB99F737651DE9DFCAFE3E124
+:102C000098368FFD3671ED259ADFFE75319E06826E
+:102C1000B7ECCE1B17D450BAD0529410544D70DF7D
+:102C2000964A5D57FA8B07F62579EE9C4D83BB4E8D
+:102C300083DBEACA34EEE750B81B7479E5170AEB78
+:102C400083FC47F917FDB181BB291F66B9F8C17430
+:102C50009C5B3916B6936C88A0BD457AE43B1A9C00
+:102C60008FD2BE73C4F1F735F89E1821DB273E687A
+:102C700009C07E5034760FAFD313D54E8F4A6315FB
+:102C80000BB71D7250A9F0B2FEFCD7317FDBD74ADB
+:102C9000F36A4EF5DD07BCDD1C6F49FE80E1F00DE7
+:102CA0009D0A796BB49CC73F9037791ED384CBC6FD
+:102CB0004299586B81FC31CD25A7B25091FB63BA84
+:102CC000F0DA30DE4CE1E37AEF9DB77BA14FBC0731
+:102CD0005D88E0BE51F8F9FB1C11E0749E0872FD9E
+:102CE0009B442BE7757C137DDCDC4BD2C7277D54DE
+:102CF000C6FF56C0FD6E64EE803A9AC7D48706655B
+:102D0000B07ED5DC9BF1F35D704FD5E886F6EF6FB2
+:102D1000B18ED8BF33A89F693784ECDFF1BDF5F5DC
+:102D2000CCF847FBE84847A7FEE4EC4B78B84E5B8D
+:102D3000D2EBBC4B597F12C2C5F2D18FB47D5BA8D8
+:102D40003A452F5A9F236ED297089689639625623B
+:102D5000BEAFAF106F15D03ABE3E46150D5CD3CB5B
+:102D6000EDA668FD4DE93FE133D85B0F8B60AFE125
+:102D7000D4AEF092EFD518827B8ABABD3196CA27BD
+:102D8000F627BDC6C0EFAEEFB5C30AFDEE8674F3FD
+:102D9000F749D966FD67B2685231FE94E1E67AFBE5
+:102DA0008127A2B3F753A5FE22868821DFF27A0B92
+:102DB0008B713E1D932EDA2F101C1169BE8FB12E20
+:102DC000CB27FF7501C61556399FEAB755B6EB1DDF
+:102DD00027798B28509CACA7932253CA25C87F4AD9
+:102DE000F203D2D3F56E4ECFD2798FF2F3F51ECE29
+:102DF00017A4159D40BF256B3EB7627DEE0C97F87A
+:102E00002E6F699A00B02A76B71C445A162C9A8005
+:102E10006376D1A1DA8348EFECD4DB6A59BED3E103
+:102E2000BE45A3D35BA2A6FD3087D6E1963DAA8717
+:102E3000F303A64D9FDC0B791BE77BA2A3AA4B44AF
+:102E400033245754ABDE2F0197776FDBC1789ADFBD
+:102E500027F5A318EECFEABD0CF799FA899C4E4AE4
+:102E60002BFA1BE8CC2B3E67796CF2F6366B12D549
+:102E70002FF42A5EECDB6BBD2210A0FDB7DE26CF5F
+:102E800081F5740E601F8FC999F6E8AD027CDA6790
+:102E90004BA37166DEB0A410E34C19556C45BD1B05
+:102EA000BF211920A58B4EBF8BEEF5F95769EB7644
+:102EB000EE6585F1D8B1332D0672C1F25D697D9062
+:102EC00012BFD4F5DD48E0ADE39285E1EC381AC1DC
+:102ED000FA86DE6EF9AE48E63BCB07D803C260B790
+:102EE0003C43EB2C0CF2E699677EE2369E2B67E2C0
+:102EF0005ABEFA18FCED2F92BF916473EA11F0BF2D
+:102F0000FEFD3CA093F39A9C4D7A4624CEBF6ACD39
+:102F1000AE08FE84FC990869CF1DF96CD258EC2FDD
+:102F20008C471C4EE8FC2BF3D987527FEEEE1A6FCC
+:102F30005BCBC28F1FA1FCB980C56FA3F3E99C686E
+:102F400039FF3BF0DFCD4EB6EBDDA9103C387FB743
+:102F5000F4E37C96628DA8C3F92B02BCBFB314B70F
+:102F6000B58EF855E5730FF703FDBD44381845E5F8
+:102F70002FAD8B647EF692CD73AC0EFD3D2AFBFB2C
+:102F8000CDBD3F3DBE1BE93D55F93FC5F2A4C5315E
+:102F9000FECB7EB56408DAD3F92EFA527F4FBFA874
+:102FA00004C3693FE734EF5FD997E01BB6A1CDD2E8
+:102FB0008FD2BCCD4A03D2A1036E3804BBF30D6996
+:102FC0006E6E5FB03D454DC236EC17F8F8077CEEEB
+:102FD0009BE581ECE6CFC7F6135D72C110A5E5F461
+:102FE0004682352CF968BE8FF1D7C4F3D9B577FA8C
+:102FF000FBF304E6411207E02EB67BF81C0AF83713
+:10300000623DCFF9B23CACD715F91F069D9DF32563
+:1030100078702EBD407AFC55A87FCCCAF37C71F342
+:10302000BBD1B0EBC4907E1C0E7F485EFB04D4AFD6
+:103030001AE0167E6A3FE0B1EB26023FD53B776D82
+:10304000E47E2A1D1EE8B9E5BB2E1E4C829C78BD8D
+:10305000F064800E77CAFC2FC77B3D2A4DB57CE318
+:1030600097327FA488F345A4755A51BF54CA470FBD
+:1030700069E79F68CD65FEC8A4EDEE5AAF5F523197
+:10308000CAD7A7F8FBC2AEAD9F9B74DE55A561AB56
+:10309000D865FB2363E725335EBEE77967D7CE2D7E
+:1030A000BDBF87ECC21F4EFDC06C033BFA06BB3CA4
+:1030B000A7B7107F01BDE8E7348DFB0BEC5F6AEF2B
+:1030C000053F4D52959C9D848FA487C258CEF8BE73
+:1030D000E3CF8E59CDE7B62E67D544483EC8670585
+:1030E000B55F18E5BB0BF35BA89DF3C2EACE861C67
+:1030F0003223CA7B37BE573ADA9331073A3FEF455E
+:10310000BE5A25B92BCD207739E3BED7F95917E53B
+:103110006DC67CBE6FFDB19104670C525DCF22ADD0
+:10312000A35B7E9CBABD05FCF88130C98FA30A98C9
+:103130001FE9F30BEDFF15DAF73EE233AFD179E289
+:1031400023DC8F738EB1F27ABE6AA93C48E770A186
+:103150001C01846C8D1DCE796F14E16FBC5315BEBC
+:103160006EF4453DA5F57A1EF899D02BD254AFB038
+:1031700057AC1DFBF7FBCE5BD5D6478DD0F9A9BB6D
+:10318000977076376F39CF5BC247F4015EC62ADF8E
+:103190006FBE0E5BD141ACC338671E9F8BE39C535F
+:1031A0008FF904C37F18DF43E7193A1FE1F87EF275
+:1031B000D28F15E1B760FF7D6E67FBDA5E5BEBD304
+:1031C000BF257CEE5D92ED819DE805F05EF0CF6855
+:1031D0003BCBB37BA3841F7C65EFD48400EC452FED
+:1031E000414F04DFE82D6479B8ACBF770E95537F6B
+:1031F000FDC2685FC05E342F42EB9F0646FB157D23
+:10320000B87D8352FB660EDAAF8864BE733420F952
+:1032100078736C709E4ADF9B3FCF14A8775404D616
+:10322000A4A2DEEDD25F43E54935D46FF3922112BB
+:10323000CEFF51F9DC68CEF3F68D73321F67FB4C7D
+:10324000F3546F5FF8AF7A69EBD5BC5196F7833DC5
+:1032500014E52994A7F4639BAC3F57ABF7914697CD
+:10326000B4CF990FF8A6445A41E7FDD24BC2D29988
+:103270002979FBC2EFF3485906DB28E7565C9FC269
+:10328000F4A3D9CB666B7C5BEF0F0D1C23212FCBF6
+:10329000BF390BB784839E679687B741EE3B5ABE12
+:1032A000320A7AFB4C9F1A0C835C39A3D0DB29AF1E
+:1032B000A5625CAF1CB74CD7FF82A5C0EBCBED0E6F
+:1032C0007137CBF7C102A33EA5AF6F55CB9878A35A
+:1032D000DE5C6127FE42F02CD1F66D9AD3D73B7DA0
+:1032E00004F4E9EBE38DFAF4A7650FE4F2FED2C62D
+:1032F0003B5BEF8D3F990EB96D22A7FA789D7A0F4F
+:10330000D64DE757A097DB25BD086BFB478B29DF20
+:10331000307B8807F6EA89D31C4C6F1D2DE12C1FEA
+:1033200037CC8EF0C26ED7B02B8CED06376BFB839B
+:10333000F428A61BFFBE28EEA7D22EF395CF65304A
+:10334000DDBC600F3CB915E52F87B37FB6325A8ECE
+:103350005BF9BB248D2EBD29AB7AB15F8EE9A53216
+:10336000C21DC3E5BF8F677A7A36DC57007C127DB9
+:10337000B25DBCD21ECC8C25FC1FD3E80F7A23FB98
+:10338000F56AA3986E8596F7FD3C9EF538927F7995
+:103390003CDF7D4339EFB37BFB2EC43E5A1EC9F0A0
+:1033A0001C73C9F26395B1BC0FE6DFB7F430FCC5FE
+:1033B000C78AECBC5F8EED5559DEFA739D1A849F67
+:1033C0005BA7CF9A25C7DF86F9A8BAE1A3E4DDD4CD
+:1033D000CFFC955593D06E7EC5ED5370DEF69AF610
+:1033E00029FB6943F7F3FC4AB37FD497EE9D8CF930
+:1033F000D56407761CA47E1E9C736A11D6D39FEEFB
+:103400009B86F53E6F6F7DE14F0477EB8A3FB25E9E
+:10341000747DB46F26BE5FD8F31BAE5FBDF2BF16DE
+:1034200041CEAFB64A7AD1CFE31A8D7E45866F1E64
+:10343000EA57AE7C9DF581C8EC23927FDEFEFDF855
+:10344000CEE9BD5B5E50A8DDD288BDD59CAA815C6B
+:103450009C6B679460B492067C4A3DEDAC2B188D52
+:1034600075F159A49CB8745B881F184B91A0D97F43
+:10347000A8DDD21619BF42F2821DF4195A7F297DA8
+:10348000E77ADFF37B856891DF6377DF7BB55CF7F5
+:10349000607038FCAE199BB0EEE776FD26D3E87776
+:1034A0000D4D2F8757CEFFACB65FCEEAFB65B6BD9C
+:1034B000D35E00B9EBFC337D4C7476FEC9C19C3FF2
+:1034C000ADB42B114A977F57785A46727C8DB765F9
+:1034D00024E4E707B5EF4BE35B4682AFE97C4E3867
+:1034E0005A7259FFCF6AC985BEABF34751D492C90E
+:1034F000DF032D9968FF8245DA53F88FE0A8783A08
+:1035000069E3DDD20FE1B70C477EE826E4F5711AD6
+:10351000C2251FE969BE8FA54B3BE6F939F69BBD75
+:10352000547FD07ABBA97C70C09CDF9A2EEDE70354
+:1035300043E26FFAA9EDFBC3708E3C21BAF5D73F89
+:10354000A38DF3D4539D713CAAA6CF0AB74E1F6E2C
+:1035500029DFDB80EF8F3AF17D6B12F1E5A59863EF
+:103560002ACF5F9E674F49FBCD0B79BE249C17E79E
+:10357000811782FF8558CA6743BE9278D5F33A3ED9
+:1035800043E7BFF2A34549B0DF7E94AEDBF93C7D53
+:1035900040973ADE1A6CA4EF64433F2E2F386985BA
+:1035A000DEEC492CB31AECDAEBF31CD8578B37E47A
+:1035B000398C74D6B0ADE010491CE2EC36AB072074
+:1035C000375803F7427E6FD8A6B6F805973BBC5430
+:1035D000FFACF3C0DBA8B768436C3EE46DBDFDE211
+:1035E000F52312CB0C700EDD665E879C16737ED8B9
+:1035F0006E73FE04CE80DEFF7CBBBCA0395F70C85A
+:103600009CFFE4835B67819CCB55FFBD2AF4893F17
+:103610004D3884F3F1D3175E8CC6FA2CFD4BD9419B
+:10362000E849A17122B46E0AF408FF5685E9E3B2B5
+:1036300078911EF8811E0F819D61A4930AE13F6875
+:103640004DB9BCFE19D132CB4B745559B7BCE064AF
+:103650004157BF57B6ACB343CE0B1DB7A7FD2F9C48
+:103660005E37EC6AC5A364D9557563C509F82DD6D4
+:10367000BE3B01F457FC4B85E58AE2E707BD0ABE75
+:10368000DFB663CE0D9CCE9AC8F8D0ED7D8BF72ABD
+:10369000C128CABB4649BA5DB85E617DBDA4D11CD4
+:1036A0004757B63624DEA6D95CBE78F7FEFF869F64
+:1036B000BEDCF118C7335C1E271878057A5BC5A7F6
+:1036C00082ED3D159BBF0D3397CB792DD4E7E1BF3C
+:1036D00096E3E1AE92553ACFB793C8D0F9F04B5785
+:1036E000516A06E1FDAAE68DAA949BBDC5EC9775CB
+:1036F000DA39CEB0CA21829104CFA128BBD745DFE9
+:103700002FAE8F6279615118C99FF99C8A708E43E0
+:10371000F4C4A0DDA977549683AAE2251EAA1E57F9
+:1037200002B0C556C1488AFC1332BF04DE2655D20A
+:103730008FD7003FD6CD98174D526FABB406F70325
+:103740002F9DE7C03673BD4A9AE7D138C859E6EFD6
+:10375000D5A29DEBD7ECFE36CCF8DD60DF657D525F
+:10376000D76B55C83304A77A4704CBB3C49823401A
+:1037700057AB14EFC30E15299DE3A0EF254E962FEE
+:10378000E66E94E747338C839083D70D66B967AEB6
+:10379000E2CD04BEC4BA70D6A7A9DC1FDE8BE564F7
+:1037A0009643484E6639AA7D8E9DE3129BF35A825A
+:1037B00090C79A1F48F1D00A327FE4F3E89E7096D2
+:1037C0007B9AA74AB9A7795D1F6EFF3140EB0B3991
+:1037D0005AE2B9F99E1C1EB79F2ADB893E520F2080
+:1037E000B93A137A02C1E541B92E4767C5FA4AB022
+:1037F000EEFAFC9B63DBA3E0C712E5F1DF4B6ED86A
+:10380000A29D87EDEBC203F0539C548A0E5A0CF62E
+:10381000A95B32E4F93172AC77AB568FFD1965962E
+:10382000A977FF80E0297BD0E26E48E95A07E1F5ED
+:103830006662FE27D785E783EE468E95F6A7637905
+:10384000929F470E171CBF73BBD6EFED1916539A04
+:103850001841F448FD9C2C94F6EDA8E1456C07A4B2
+:1038600035BAB9BB38903519F29C2AB317FDFE9AC8
+:103870006EE0E9A48BF152DE3DB94CD924E1F2723D
+:10388000BCDFC85F85B3FDF0A476DEE8EB4174349D
+:1038900082CF718D9FADD3E8665DCF7463A28BB983
+:1038A00090B7413773E4B9D84957DAFA12DDF07AA4
+:1038B000B7135D48BA11E26BB42F744B793B44DF08
+:1038C000EAD4B77BD0B7880E9EC8E86DA817420728
+:1038D000C21A18F18FFC2C25A362472AB40449565A
+:1038E000E147DC2CCE46C6D75DD6C04A82A7BF557D
+:1038F000AECB00ABA43B3A65FC11F95CDF8BF8D989
+:10390000E2FB170B2FD52F4E126CB74A27F926264C
+:103910008EDB09A47007AAB0E7508AF6C531B2FF62
+:1039200062A26FC4B3517F5E4B9CC6DC46C27F2A45
+:10393000587E40FBE87C6EEFB7C8F65E2BA503D33C
+:10394000E43E6A5F15C6F82BBE734026E864D25881
+:10395000339D24664A39414F1B33DDBADC90087E23
+:1039600050D23898CF9986F0A2AA5DD8A7CF487DCB
+:10397000A378F54D934700BE67E33DD8C2A7A7ECF7
+:1039800060FF4A49E39C1F7F083D655B387FDF98F5
+:10399000E97B0F783FADB817ECA20F25335FB12755
+:1039A000527B5FCBD473BFA3748A7FC7DB9023A6FF
+:1039B000CC50B9FE1421EDB9A2518E33D9FFB935DF
+:1039C00091FA9B3C5AE1F094B67057F232F855B434
+:1039D000F53DA6D17743B898FD9C13700DC84CCD2A
+:1039E000861F8224D46EE4E401995AFD31CA06C8C8
+:1039F0004303C7C9FDA7D7473FE8372D53EEB7CFDD
+:103A0000B47DA7E709AF5CBF6C4D585B5A34525B7D
+:103A10007010A5F3B2C69E039F99942A26AC07DEC8
+:103A20007FAA8A4D0C6F7B31F385A84C37F8828FC3
+:103A30001459A6FB6D8399EEDBC6B4B7DD49F9B620
+:103A40002D39D27EA7E9F30B5D82E582B63192EF84
+:103A5000B56F8964FE73CCD51A1527ED5DACDF9781
+:103A60006A24F1D7BA867BE1372E75DADB707E2CBB
+:103A70007C603AFBFB4B9B49BF475CFD5AB37E4FD2
+:103A80007A78586637FA7AA85E0E9A011D95AD5578
+:103A9000980E073678EC7D99CF292ECCAFCC194CF7
+:103AA00007FF2FF384735CF0657AFB3784F791B0DE
+:103AB0001F0B0EBA1A3AC8D70BE3163715B37E1A86
+:103AC00099ED63FE355025BC101DCFD4E86F12EC84
+:103AD000A0E04BD6D6BED897AF6568DFE35C994EC1
+:103AE000A6EB70BE6FD066736502BEB655E1169C3C
+:103AF000B793564AFAA67DE7C0BD80BBAC2202FC54
+:103B0000E0B8D67EFE0A6BD146CAF777086B541C24
+:103B1000E82B8FE93B90E5FB0CEBF7E92FC428C8B5
+:103B20000DA56BD749B834FA10D623E3E3699C4F4F
+:103B3000B7A4E4C3AEA0D353206B6C76E608035D54
+:103B4000CC50981E683E87609F9D9755928F72FA61
+:103B5000BE1FF432696C301D71D8856A25C7AB76FB
+:103B6000240A0FE2873A443BCB231D248F803FEA8F
+:103B70007C46E72744175E4742D77AEB7C656B3D6E
+:103B8000814678DE56EFE0F4A97A97B0124FD85EFE
+:103B90009FC8F967EBDD9CB6D467F1F7E7EA3D9C77
+:103BA000DF593F8AF32FD47B39BFBB7E22A7BFAB3F
+:103BB0002FE2EF841FE64B3ADFD1F9934E5F3A9F35
+:103BC0000AA5AB058466DC33A0F6CC0F753E887978
+:103BD00058F2BBF893BECEA94A913F11FC50B4CE27
+:103BE00001FF2854CF3EF322E1B9A3DCC9F1A11DA6
+:103BF00042F2C10EA783CF8D64BBD80DFB40C33208
+:103C00006FDB9D8673785EB922AC06BABDA9365CBF
+:103C1000580D747D735DAC293FBFEEFDD7FA50FFA0
+:103C20003F8BF12DC2FA1CBBE3D4A37FA4EF8FDF3F
+:103C3000713A03EB4E706C7908E3DE1EA1C1D12A04
+:103C4000E1BADDCEF2D2C008A94FE1CF6188732D71
+:103C50004E897DFB3704E7316D1D06DA5DB346C141
+:103C60002EB34A75ADA42A1F63BDE8FB9FB5F52AA4
+:103C7000A90B637C96346AFBD418FF4CF83CDE57E2
+:103C8000B05CA77885801FE9F82FEC419211C471D0
+:103C9000C51150681C8594ADF9B017AE79FD28E4C4
+:103CA00074A5EE10CBD53E8793E32884DF76D6D873
+:103CB0009F527790EB89D6FEA638C8C8E15E3BF8E4
+:103CC00005681BEB56927540609F8B2685EFF1943B
+:103CD00069DFCBD628A6F8E27B3355E68B8732AC7A
+:103CE0009C0ECA149A13A589CF299D5E897F703CCA
+:103CF0006359539E7D91812F9768DF4BB32CA67833
+:103D0000C74319322E6A109805A57767A5DA1732CE
+:103D1000DF7373DCBD5EBF242B7F75EA70F483E82C
+:103D2000A0AEF68F645AB9DDA10C9784C741E7595C
+:103D300014C7E9747B2EE872CCA7F8EF950C3FEB23
+:103D40005915CF3EFD2CFC7B157F0AE3F3A9629841
+:103D500066DFC80E8C9CCEF28FD7A98C84FC2DD741
+:103D60007FFCD37F89467C54CD4E6957A5B40D693D
+:103D7000F5EDE56C57ABF6D0FE88039F35FBCD5FC4
+:103D80007DF64FD1ADAC97F893B4F85B8EF7AADE11
+:103D90007982E3C0F4B8AFD07635CA37ACA7EA7100
+:103DA00001BA3FB6709F8DF74DCD1E85F5989A5D8F
+:103DB0001713C0E76AF6AD4AE82E2E27B45F3D5EC2
+:103DC00040B7BFD588B59FC37F4884C3F80FADFF08
+:103DD000766654AF53430562D5AE603B8855701C80
+:103DE000C7722D8EB32390C17EE19EE4ED9AF5C497
+:103DF000F049BFEDB0BA6310AF7C418889DDAD53A7
+:103E0000FC20797E9FA37D04BFF085ED2ACB91171E
+:103E1000B647F17EA8DE7EFF41C4DB556F56D88DD4
+:103E200057258E30DEAA77AAC261E00F35B00BC5E8
+:103E3000F70CE7D2A7A36A415F4B5A14EF16F8AD0F
+:103E40001DEE98DE0678DA35FA5A1AD63292D74540
+:103E500083FF14F89A41CE5CB2F77E8E13A47AE702
+:103E600059AEF96D24C7B3510F6F03CE331B0AD877
+:103E70004FBDA4654735CB05DB235D10694EDBCC18
+:103E8000F729BED1C6FB4693D3CEC04F82F6CFAA48
+:103E90002C0F034EECCBD35A3CABDECE3248B6B33C
+:103EA0006878FB0DF6E788AEFA4B5ADAA2D3A9FE82
+:103EB00027BBDFE7D43948EEE325CE23B938473FA7
+:103EC000D919C9F7ED3ED9F9EB092FD178E75AC6D0
+:103ED000F4520CFB6CE0201BD73FB741C601F32521
+:103EE00011D60F5A783E67B62729AC2703DF849F87
+:103EF000333B9F8FB6F03EF6FF7B71ABB3156BC8BB
+:103F00007D84EBB24780FE5BB5FB11ED9AFDE57F4A
+:103F1000A7FF6AED7B9B52A48D23EF3B083D0EC2A9
+:103F2000A5ED3BD5C9FB6E79949DEF2F2C18E6BE0D
+:103F3000711EF8E89B328E51F4773F04FD6FC13B50
+:103F4000F16C6F596E73F741FE8BC336F6132C2854
+:103F5000F01CF5A17E8C9DED4A22B17504ECAD6D8F
+:103F60002952BEA85C433B9350DC8FE8CD4FF8ACA0
+:103F70000C58848FF29307A5F2BA3E526EF1DAD94B
+:103F8000FF13E4FB92C7ECC28F7B2FFEE7A47E5D9C
+:103F9000992AFD0E8F607F515A1917CC8C87DD4E00
+:103FA000A39BCA69546EA09FCA4DC14CC84F67ED10
+:103FB000D21E8972E84D95F9B25E8346A7E807FDE7
+:103FC000B6A5B8CEB3BCBB2B4A40EFB0BC1825EDAC
+:103FD00021BF09DF146638AF6F1A24E9B841F3072F
+:103FE000FAB748F80017E4F825F6A64CC8B9FAB8AD
+:103FF0004BA29B78BCB3DA784B229AA4FF448BC7C0
+:10400000437D1EDF26D8BFD3FE6418CBCBA7FB1E93
+:104010007901E39F7E7230C711B4A50416EDE6F274
+:10402000708EE3AE782A2C08783F7B328AED589F59
+:10403000D9A41CF6595402CB6187A21E5C80FE3ABB
+:10404000368729E0A39F29C29E88F22DBD590EA86C
+:10405000A8AF633F4905B117C8AF944E84DCF7D9C8
+:1040600096C16C27FAEC0D952F29D0F735F8EE1391
+:104070004D0B7EC6F2BFF43F9E7EEA6F83BBF3AF6B
+:10408000546C36DBC3F4F5D7CBEF1824ED03770C73
+:10409000927AC9CA412EE97F8B6C793095E729F96C
+:1040A00003AD03EB7FB41F13606F3FD6B22741719E
+:1040B00002CFC1CC5F03EFDBA49E757ABB8DFD42BE
+:1040C000152F4679D9FE74E7157CEFB042957278CA
+:1040D0008545DEDBABD0EE99564467B27D8BF0CDE3
+:1040E0007A6DFB16551B478EFBD9D601D29F10D493
+:1040F000F22FE4F03DB84971E2E6692C5F6DC80526
+:104100005E2F6E8EE4F8791AC78BB8878A9FFD5CA4
+:10411000E2336611EB0774AE317FAED4F873D59DF0
+:1041200057C7E05E817847E5FB1217AD9E3EE0BFC2
+:10413000A1F87A4FE3634B5F7894F94125ED17C4FA
+:10414000592DD5FCCB4B9F52589E5CBAFAEA879802
+:10415000EFBE6D13B85F70B6E5FE68E37AECD5F894
+:1041600067577B0FD75F4AF565FB37A3199EAD36BE
+:104170000FE0095DC7EFDDFE29F55F6A5FD142F20E
+:1041800045EEE5F3BF288EDCF627F095EDE16C6790
+:10419000A3F5E77B46676C2D8B30FF33CF8433BFAD
+:1041A00039132BF7FD27749EFAED80E787F7B15D91
+:1041B000EDBDE902E7D0E280B95F1DAEFD1ADFAFC9
+:1041C0008AF7C4C04F5345EB81FE687D7EC4EDDFA6
+:1041D000B171FBD0F93C8E76230CFBF49948A69B79
+:1041E00033FDE4BA9C7976109F676DB192DE09DEEB
+:1041F00064E84B6762658A1B3EA0870A97A48733F1
+:10420000635AD81E7046D9C1699B4DB6ABA8D3FC82
+:10421000DA447F89A01FD026ECA98EB54720C7803D
+:10422000CF8FCCE73488FBCEA17673D029CEBFBE2A
+:1042300059F2DC8478053ECF7E1BF6E3B4F03D7383
+:104240009F264F566EBFDC4F8875AADCAEB03FEBA1
+:104250009276FE02EA5EBADD9FE872A95FF1226EF5
+:104260006B69E3B225A0FBA5B5EBE681EEF5792CF1
+:10427000D5EE5FB7292AC3D3164EFB27FBF2F174A4
+:10428000FCAA598A1E9F275CFAF9457B382CCB2D56
+:10429000E988B24DD45F65A3B296C749D1F55B39C1
+:1042A0003F1D4FB8CD02FB5E9B76DFB9A7F9EB70DF
+:1042B000F6044F5296E44F6D29F29E6FFB5BF2BEFF
+:1042C000F6C56F0A62E2FE813CC891FA7A7F047FEC
+:1042D000166810728FC6E796C2AE4E70666E30FBDF
+:1042E00073B2369BF343B69BF3D93BCDF9DCBDE605
+:1042F000BCE75573DE85717B77E109FA36E203A1ED
+:104300006F2385BEEDCE94FA36F2D0B79142DFC668
+:1043100077E8DBC843DF461EFA36F2D0B79142DFBA
+:10432000C6F7391A9E2A357B29D681E3D4F684EB69
+:10433000F100BC5F2ECC49603E2AAC521FBDB024B8
+:104340009BE5C74E3BD35407DB99F438A7B7A27C53
+:10435000E3B27AC37F7B6475DF146EC7F6E79ADF3A
+:1043600049FB73657EB813F68ED6559FAC86D8137D
+:1043700088F24D44FD0BB6F6ADC06F55DD2BEC6FEA
+:104380006F5DE17EE70772FDD8EEA2C72D15E3DC75
+:1043900003DF267D49C66F7B1C463B6AA85F48AC9D
+:1043A00035E4213F359BF3A17E20F035AF695F35C1
+:1043B000311D3C6E6BEF0BBE7FE24907DFF33AA184
+:1043C000D9EDC46C17CB63BA3CDF298FDDA36CC277
+:1043D000F9BD242B8EDB771CCA30DDD30B4D4B2F60
+:1043E000E5B3BCDA995FAB58304ED98C15FB59AFA9
+:1043F0004E8CE673E9160DB64190FF0D700F0E441A
+:1044000098E868E8B6B810BF653F53FD61BB5343F9
+:10441000FC96434CE5D3D71698EFB5175D6D2A1F70
+:1044200068EF8C877348FF96069F4BD6B9E8CCE7B8
+:10443000F986D64B563C7F84BF56BC25E5D3329ACD
+:1044400087B7407B9F231FFE39EF14E0AFBCC51632
+:104450008BF3BE543B87449DF95C2EB70ABF2BAE4D
+:104460008BEECA5DC21B4BEDBFB43625331DDD712B
+:10447000345925142D19722437087DE58D2746827D
+:10448000AEAAD48DC92E2ABF55096CC545ECD3718F
+:104490003B12AEA4F2FFB4F81EC9A2754AB605EFEE
+:1044A0009D0F3EBA234DE0BD91136B9F8FE6B83C44
+:1044B0008DFE926DAE08D0C1C62695F514D8CDD428
+:1044C000B82E3AD9D8141F01BDA67C8CE297727120
+:1044D000B449DF0BC547A19AFD8E9BE67BF1902A7C
+:1044E000EF406AF35CEE92F545BA6CAFDFB3D7E705
+:1044F0007B52D3472B36BE96790B7D3F3B787F2E80
+:10450000AE8457D6EFE6792FB56CDFDA97D27B1DF4
+:10451000BE5D98D7F2B7C6455F49E37CB95DC687F3
+:10452000FFB5F989C7FCC44FEF6C7AC20EFB418519
+:104530003560871E5CFEE4463BE218AEDBB691BFF9
+:104540002FDA56CCF600FDBEDAA77A7CB3868FF25E
+:10455000B1CA0617CDB3FF60C94FCA23641C4BA173
+:104560003AFA35DC13B8B84DC9C3BC6614EDB0E3F4
+:104570001EFF3B1ADF09DD371D87A717F686BDAB87
+:1045800045F120DFD33E9989CB72440FD32FB9393F
+:104590009D716908EBD51F0AD2BE708E6487E8D77B
+:1045A000875569CF433C12AD73B93DD86B3AE4856A
+:1045B00097E5FB0F55740E8DCA87DE2EC4559416F1
+:1045C0008D564D745E333ED2B40F660BC3BEA2FE51
+:1045D00066897EA6FC8C4969A6FA37CE181AE2676E
+:1045E000CEEF2A67FE7595E95D97AADBFD6E85E340
+:1045F0007BC69ABF537A3BD3D90DA6F655629AE98A
+:104600005D97259BDF653C1395D9A18F956BF7418D
+:1046100066FBDAB4EFADFC9D2662DAAF03D33C7FD4
+:1046200094E7A58DFD08BA1D7D36FE9FD6DD79196C
+:10463000D1198F89F85BD83B7C6679E408EBA942F5
+:10464000AE4395668FAACA92F6A82AFF113BE29B59
+:1046500009FFD62442497593C2F646AAEF488A93C9
+:10466000F9DBF17DA7F95E07FABB84F2436A31F604
+:1046700057687935CD1BE74235EC47B083E9FD6BD0
+:10468000FDEAF4197ACF3EB41FDF6037EFE78A6D99
+:104690003B0EF623BC4C2F8ACD437C4965CB545B43
+:1046A00071F6E574A6F3FD8BE516B67F751C7E8565
+:1046B000E9ACA3DCEA91F1DDFF181FD55E696F0D4F
+:1046C000A5BF45341FF89917ED543C0145D6035E4C
+:1046D000FA812E43F092D40DBE743C75E22DA47C79
+:1046E00031FE331CF1114A007CF232BCE878D4FA76
+:1046F0005FE4132C67123C018627A43F312A74FF24
+:10470000DDC2EF20746C50844BF96E3C4CBB24ED41
+:104710003603D3E4BCDB77291EC8EBB32E59F97BF3
+:1047200027BD14C938F51993CCFBB3937E8AE47E78
+:1047300099792981DBFD6FD3D177D18FEE9F098DD8
+:10474000FFD6EF5D2D1AACDD4B1A21467CFB4FC422
+:10475000AFEB72404FE749E779E3D2F0EF4CEDF66B
+:104760001C5E1E95CAF1DA3ECD8EA8F3639FD64E2D
+:104770001FB798CADD05A0EFFE09B017AF6E4C4B0E
+:1047800036BE17E35B65633B6FF28A784E8BC35D81
+:104790000938478A57C8774D8EDFD52701FE88E351
+:1047A000AB6CBD2651D7C77F3A3C59E4205FC8E9BE
+:1047B000897561B38D76783D6D1A2CED35FA397EA9
+:1047C000CE72387A36F6DFAA5DD108055ABAEAFD0C
+:1047D000912E3ACF57597C8F0F667FEF463ECF859B
+:1047E0006B632EEC70BA3C51B1AAB00FCEFDCAFF7C
+:1047F00079E5319CFBBE15B604C8A39F7DA00A8451
+:10480000CED079C672C4A7E192AE3FDD12C9F710CF
+:104810003F558417FEA625EAFE5C97E95CDD3B0B5D
+:10482000E3FFDE41E38EC0B881AD8918D7E3CFC482
+:10483000B8BE151931DDD957F4B466BD94F3B6EAA4
+:10484000F664CDEE0CF91E79C8F7706241BE471EC2
+:10485000F23D52C8F7F8BE4DF32F0C6C68CF837E43
+:10486000EA1F2BB26AF9BC7566417EBF4589F080AC
+:10487000FFDCA278FA70BCC166F9DEC4F29075D58F
+:10488000D36BDA490633D0ED0F2E3984316E6E8C3E
+:104890008835E5C739FA9AEA17BA524CE5D7250E9A
+:1048A00036955FEFCE33E57F9875A5A9FE64CF18E6
+:1048B00053FE47A3AE37D59FEA9D6ACA4F9F38C7BC
+:1048C000547F6651B1A9FCC6D94B4CE5737CCB4CE7
+:1048D000F979E53F35D5BFA97685A9DC2B5C569CD7
+:1048E000777BA17711DE5F86DE45E92D6F65388D18
+:1048F000EB3A7A9CA5DB77794E697250BFA1DE3620
+:10490000D025EED7800E0768F767BEC0B9D21B7EF0
+:10491000C9A022F5DE237D4137A1F542CB47471ED2
+:10492000B8E8A6352C7A2A7AA695F8C4E82B0E1496
+:10493000A4517EF5538533ADC45F465F7DE0F954E5
+:10494000CA373DB54A960F3B7011E5514FDF20F352
+:10495000D3058B1A8F0CF97A869FE631FA07A96B7B
+:104960003DD26ED26DBC69A73D88F080784DE001E4
+:104970006990E813E901A24FA4AF127D96A50B71CF
+:1049800090E813E921D23FF1FDF7A47F223D4CFAD4
+:1049900027D2B749FF447A84F44FA4EFD5CFE6F489
+:1049A000837A1FB7FB437D39A747EB6BF9FBC7F54C
+:1049B000759CFEB9DECFDF5D43743B4390ED31BAA9
+:1049C000FFAB1A7E47D8ED76DBCE1AFDC28A579E22
+:1049D000A7BABFB2A156B446629FB65A634F39BA5E
+:1049E000FC903DF35BAB386590BF5E0FF7260DE1A1
+:1049F000F1FBBB986F6BDF8F89E903F2699D0A5267
+:104A00007D29289F995FBA2A86F8C70FBEA9B5816C
+:104A10005E3EB4747F7FFB0B8D4EDA877833878CD4
+:104A2000E8F2BBEB7EEFCEF81A835F1EFE6C3D8E84
+:104A300047F7C7F39F213E47F793EBF141D76AEF62
+:104A400023E97E703DFE47EFB7F09260BE77CD1A46
+:104A50002BCB2D515611C4387A9CCF358E963CC441
+:104A60003B5C53E9E438B73EF41DEF23523D2FDEA3
+:104A700099DBFC25D5CFEDF2BBF7D1E641E53C8FC4
+:104A8000C24B3EB6D75EA3C51DA0BD4396F33B7592
+:104A9000881183FC4129DBE11E55A87D7E571C004F
+:104AA000EA47CAFA41F497FE158D17DDB58F06C4A3
+:104AB000B5E4216E6C40B593E3C6368C09F2BDB9FE
+:104AC000E9B1D7DED3AA224E38E6C7D8474FA7FAB6
+:104AD0006602CFEFEE730FF0507E5A5C5A6FA4530C
+:104AE00043DEB5EB667DE6625D757CE978D7D74B32
+:104AF000C7B7219E8AF1FC5DEB17BA6EA1EBA5AF9B
+:104B000053E1A52EFC037F97AF4FD7FAC13EFBFFC1
+:104B1000CBFA0CB7B6F07DCCB04A8707707DD77A58
+:104B2000DDDC2E26E03E78F125F741A44BD27C5FF8
+:104B3000807F968A31135CC0914BCD819D27B4DE76
+:104B4000F2EF59EFE1907A07E20AD67C9D7679BDC3
+:104B5000DD21F51A620BD67E2DED4C37E27C3DE46B
+:104B6000B6B11FEDCD703D1EC3EBCCA3751CA7F1F4
+:104B7000A343A296CF0F12D7FC58DFF1DA528FCBA6
+:104B80005ECC72EE78A7596E9CF04D5123C69DD035
+:104B90002B448ED6FCE13768FD5E279AB8DFD07BC8
+:104BA000F23768F269E83DF9E78668F2658A4801FC
+:104BB0009F1A2F3C122EEDBD83F12ED96F92462FF6
+:104BC000696E558C063D089F15CCF155BC77908BCE
+:104BD00071FD9CBF5E0438FDA108723F938991224C
+:104BE000FF23216CF29D03793FB35AF5FD27E42C96
+:104BF000FD5EE6C270DFABD877AF444E998FF728E1
+:104C0000C6158C4B47BB03E3DD2C9F1C70A4B1BCC5
+:104C1000847D658BEBDA7F6FD0F9926E95F7069104
+:104C2000E2DE603A6D96D7E9FC41FE86AC1502EDF6
+:104C300026B8CD71387AFB1FBAC60A6B41CFFCFD8E
+:104C400087B97BFAC3AEF366ECA0F1B083BF197BE2
+:104C5000C578CCF7CDD83E169986D939CD7931BDF6
+:104C60003B794EA7E7AEF126086B7CCF78D6F11AD8
+:104C70008A4F1DCFFF025E2F7487D72F060B29376F
+:104C8000474A3EA2E3B72AACF31E671F635C44A504
+:104C900043E2E933808C7BB87557F13C3EA917FDA0
+:104CA00081EF4575A3B83CD40E2536C7705E7FC72B
+:104CB000ECCC83EF4627127CD7397CEA50C2CBD9A3
+:104CC000FC60264930E2930D0D7CEFFADCB3AA07B5
+:104CD000F27FA5EA5EEB014F7953653FA0F8E695B8
+:104CE00064F809C5E6EEE3A32B1D12AFBAFEB3329A
+:104CF000AD88F7A7701524CAF7D5E43D725D1EE8AC
+:104D00001F26E38BF5FBCC3DC9072323241FEB1F94
+:104D100026F9AEBE9ED48EF349D4CF48E25349F76C
+:104D200045B03EB0DBE54D1A0A7FCA786192A7759F
+:104D3000BDBFA3977C3FF05A91F9D068CA8F3F64FA
+:104D400013012AEF182F4CF164856F94F2BB16FA09
+:104D5000FD98B044D2AF0CFC20DC1D617A6F343278
+:104D60002BCE948FF2F433D58F19956A2A8FF50ED6
+:104D70003195C74FCC37E57B175D65AADF67F658DD
+:104D800053BEAFEF0653FDA4F269A6BCCE9792E4E2
+:104D90002731A076AEA9FDC0BA1253FD147F85F964
+:104DA000FD54BFF74856029E77947F696B9687BC87
+:104DB000AF6A1196915DEF90FC3A5ADE0799E85C74
+:104DC000C4EF916434FDCC0C8FFA8D8A732629468A
+:104DD000E1F724AE739BF96061A2393FDE95F72AB3
+:104DE000966E9C2B34FE28A8809E926AADA6EFF3A7
+:104DF000866A7C3457E4B29EFE5DEBEF1B625AFF7D
+:104E0000507C5D4E0FCFE705DDD29E6F9C17ECF90D
+:104E100046BCC09E6FCCC39E6FAC0F7BBEB11CF670
+:104E20007C6379C121331D8C3862A6832B8E9AE96D
+:104E300040A7CFD0F5BAB2D54C1FC2A7F8947FB027
+:104E40005E577F6AA69FD0F521098BD76F825311D9
+:104E50008FA4FCFBEBB52E64BD3AD787F00DF9F6B5
+:104E6000DAE050BE275B78481578B7E4516D9ED7DD
+:104E70000DADE527C3B65B7DBFE67DAED155435F83
+:104E800049571D879E0F071F7D34A4FFD7FBF902EA
+:104E9000A83F3BFE62B21DF4D12EDF456B031FEE2F
+:104EA000DD15B7497ABABC77F23395E3188E599A73
+:104EB00014F0EB8218DF36F0CB9BB36B15F8671359
+:104EC00045D18E4588CBF98FB064E4170C94F77701
+:104ED00045762BDF7FD0F9E282241917D83254F3BC
+:104EE000F37A64DCCEF343A5DD24CAE3E238E3E2DF
+:104EF0006C79BF83D499E40539C0C7E1F041C0475C
+:104F0000B385DF696CB5B9396EC4FF862AE0F783D3
+:104F10001C0BF9728026DF357CE47000FE41EB85C6
+:104F2000E99C1D1C7098E25B876E7399F2392D899C
+:104F3000A6FAC376BB4DE579C12C5379C1218F29DF
+:104F40003FE2C82853FD2B8E7A4DF92B5B279AEA56
+:104F50005FFD6991299F24DA1F067E072A528F3E42
+:104F6000333455E2C92D387E6FC19DB1F2DEA7A65C
+:104F70005FEB72BA1EF7ECD3E83954DE1F68F771A5
+:104F80001C75435FE1E17B180E4D9F12663DC0A783
+:104F9000C52D77DEA3F09BE396F578E54E7D41D3F2
+:104FA0000F7439DD10AFEC35C62B2F08EBFE3DE05A
+:104FB000FFD2D63D14FE817639DF869FDAF9DE888E
+:104FC0000E57283C33B538DA2D8EEEEFF5D8B225E2
+:104FD0009D256514FD1DF4FE98CDD3CA6FDD5F36A7
+:104FE0009EA7D54FF4D5F00BBB67A5FBBBC75B30C5
+:104FF0004CCE67BEC572F3D46C8ECF32BD83DF3B1F
+:105000005BEAFD51B94AB7F35B1023E3A7448CDD9B
+:105010000DFAED793C89CF44BB68E4FB475A9CFF0D
+:105020004D6B5BEE194445F3ED4DDA7B60011BE8F7
+:1050300061D25892C3F284D8B66557B393E4A2C73D
+:10504000EAAC6C3FE9BFDD358B24B8CEFB1B0349CE
+:10505000EF017D40B681BEB42147E571AEC19E1B14
+:1050600081FDF64D679C3DFB0584D0CE0BA94F75A5
+:10507000436F4C87FA3CFEAFE3ED43F1A4EBAD4246
+:105080008B334CD7E0D2F1D76977D0F0A7DF7F70B0
+:105090002FB3156D72F23D8A8988DBD2D7AF2547D1
+:1050A000D265AD860FD4033FEAA95EA19A1D03FB2A
+:1050B000728770C7B8BAA1433DFDBFC28B8EFF9EF9
+:1050C000EE57F5C41F42F9C277DDB7EA894EFFD922
+:1050D0007B57063E21E368B47509A45BD83F7D6722
+:1050E00094793F6FCC96768D71DABEA2F3DD996725
+:1050F000E61702F6F18655AAC62FE4395E9C52C423
+:10510000EF118B3A17CB33E51A2FD6CFD7850FC8BF
+:10511000F7E0AEF516255C45F992669BD848A015D8
+:10512000FBBB8FF366BF931B71FE9E44C0CD263739
+:105130001AB7B44909EC4FB9FCBDECC54EF97E5C19
+:10514000E8BBD98B35FD172F2A60DF86FA65EECFD5
+:10515000D6CE6B8FF07C2BE167BDA50B7E8DDE027A
+:10516000F21D31E8C3AAB4F3709C968E3737FC2445
+:10517000F15D79C26F4416CEF3466BB771749DF83A
+:10518000D5FD2A9D7EC2C31CAF1F1A1770D6FF4AD9
+:1051900074777E1ADD7FD3D33EE8F4DF7C875FA887
+:1051A000C369891E053E04FFBFDBE857F9F3488257
+:1051B00090FD2731F08FB46AFD898DB9DDDD4FF4A4
+:1051C000ADD8C5F110AB2CBEFF405CF219EA1FEF61
+:1051D000B0DEE53C9080FBF89334BBD3E5F3D6E436
+:1051E000B0D1F27E40875FE5F5EE9828EF73131F8C
+:1051F00015D877BA1F7FAA08F642AAFB497C6B46EE
+:1052000031FE753F49717014C339B361B10D4F4818
+:10521000B63E7C7B6184BBCB7FD23A40C6E7F4E4E8
+:1052200047997EC9C3FDCDB87415F7732C3B45CAA9
+:105230006B8DF72C039D0DD9266C9867ABADFBDF0A
+:1052400019989223F7D152F8D27B1BE27E5628ACF4
+:10525000072C57841E07C47C5ECF5F6CD2F2853268
+:105260007FCB2A996FD5DEC5DAAAD93B304FA498F7
+:105270000FF4F0ED9A3D04F3408A79E03BF81AF21E
+:10528000E06BC883AF210FBE86147C0DDF4B445109
+:10529000729E2AFD3DE30DFB03FE9EF106B909FE59
+:1052A0001E631EFE1E637DF87B8CE5F0F718CBE1D4
+:1052B000EF31E6E1EF31D687BFC79887BFC7581FE8
+:1052C000FE1E631EFE1E637DF87B8CE5F0F718CB97
+:1052D000E1EF31E6E1EF31D687BFC7587E739D62BB
+:1052E000F207DDACBD3B50BA3E8EE9A339B52829A3
+:1052F00087D6F73F23FFE7C7B654ACF3DE25FC6E35
+:1053000060558447AE73D344B9EE1621D7B97D0EEC
+:10531000AFF3ED76992F94F1C2A1F403BFCAF874EC
+:10532000E957410ABF0A52F85590C2AF32DE2AFD52
+:105330002A48E157C177F85590C2AF82147E15A470
+:10534000F0AB20855F0529FC2A6807BF0A52F85593
+:10535000F01D7E15A4F0ABE0FB318203FE151D2E7F
+:10536000C8F9E9263D94E8D0A487BA4C79C8F9C6B3
+:10537000FA90F38DE590F38DE590F38D79C8F9C639
+:10538000FA90F38DF91BF188716F29EF1BDB41DE79
+:1053900037E6739AFCAFC1863579C3F95791B646A3
+:1053A000298F292E92EB729E9A05FF586BB8921C9A
+:1053B000EB213976C56F678DBF92F889166F972BF1
+:1053C000DA2D586FF67BD3BAF98282E38373FE3B02
+:1053D00091CB757F2BFFD1BAE7ED14AC376CCB9036
+:1053E00070E9ED3DC2A522D5EB77E5BBAF173ABE1C
+:1053F0005E8FF9A5010E5228F310079177BB331F7A
+:10540000F1ED5B2D8A8C0B5D29E37243E9AA49E338
+:105410004B5B2D3B0E4450BBF662C5837B07995610
+:1054200071C8960F3CD5E6439EA8CB89D5E2836B25
+:10543000AF423C900EB76E7F243EC1F7DD46B70BFE
+:105440007B198D73CD17C28EDF5B986497F204DAF7
+:1054500041DF1CEA57BC9B0CF4BD32479E7B3EFFEC
+:10546000B2ABCAE8FBD0EDB557E11EDDA408D9EE1A
+:10547000378F47331EA7342A9BF0FEC9E8EDC28B55
+:10548000FBB1BFD4E01EBADD652FE3715D7CFF4E3A
+:10549000EFB7784332DF172C16ADE313D927A1F00D
+:1054A000FBE63ADE687EAF627EC4E20FC18EFC2F5F
+:1054B000DFC32171F1FBDCC3B966786C21E2DBC488
+:1054C0005EF90EE4E4E1C5AB7A135CBE807C07F2C2
+:1054D0009A2F6A5FE3FC66F90E2493CF48868FCF3C
+:1054E000C3417E85DFFF98E2DF68E9E5C6BDE015D0
+:1054F000B604D4DF2E3C500B060979AF559F57B642
+:1055000038620957402FE2957803FD11E798017A38
+:10551000C9F3D8F87D90A956970DFC4697738A5D1C
+:1055200072EC4275740CDFF70B91132E36F6E6B869
+:105530008D7F3D8EA483EF932FDF15CE72858FF87C
+:1055400007F8E6B93C197759B9ECC39196D4AE384F
+:1055500092D32981AD78DFF374EA8EE8510ACB113A
+:1055600087C05FDB1A9FE77B82C5AB5EE3FB10174A
+:105570001B1F8896F7AAA47FA54CC39B6E6F5AA8E1
+:10558000AD4F99163F74BC5EBECF4BE730BFF7718D
+:10559000B1D1C67246A8BC2884EB0F88732B6FB4B8
+:1055A000F1DDD3C56B8B57278AEE7E77C52BE3CF12
+:1055B000B5719734DA384EA85C7B472BF477589650
+:1055C0006A72E8D26DE6EF277242E44FFDFD44AD0A
+:1055D0004EF15BAFCC6439A8D6C671EEF35748B92B
+:1055E00048EC1001DC6798BF629C05EF58CCDFE502
+:1055F000F528DDD0D13B9A7C34098312DEA75E8A80
+:1056000060BE32ED523FCECFBA94C8E98D97B2E476
+:1056100077AC1DD14B6BA1BC5FFFBE2617CD441CE0
+:105620006501E4B23E4CD71D44D7182257E35743D7
+:10563000BCCA2B30C34FB2F956214E73D246C1F7C4
+:105640009126437EA282D990A70AB02F520AF93E32
+:10565000C64485EFB74C1EBE4CDB07B42F04F311D4
+:105660007EF7C3377E6A00F137B37D3B2C58777DD8
+:105670003FF8FC6DFC0EE664BF62C77B813E4DCFF8
+:10568000D6E93D745F2C88D4EC634E69FFEAB48F91
+:1056900001587E9C27F246C4B32E802DB39FB6B02E
+:1056A00084AAA86C599E9C1B79632394AC7FD36E0B
+:1056B00032DF6291F79F48FEE3787571A4B00FE581
+:1056C0008BD72AF98897D7E1FA7AD8D849C37A775D
+:1056D000D14149E7FECCEE03BD60F95D1926FF4CD0
+:1056E000685A4AF8C63E5A10D3FA63FCD2D0845C9A
+:1056F000E11D9F8877C8F5F98A20E202E76AF9DBA5
+:105700009EBDF28F6B9C8C27CE8FCDED7723E23F31
+:10571000FE65FE385FB11A7F37AA4DF17973E53D1A
+:10572000C80958DFC8EC767EC76066A64B9E2F215D
+:105730007696DB72DDF25D84107B4B69B63C6F843C
+:10574000D59D3C8FFD3A6EB657EAF33E6E33DF339C
+:10575000D5D3EA5C6937F8BFBA27F1A045DEFB7FF5
+:10576000C412D8F122D16BA0B76F01E6FB08E2BDED
+:10577000197E1FCF4F7F47A3934F69EF65E8F474FD
+:10578000ACEE22DF972871DADDAA819ECAD6287C8A
+:105790001FB1A44EDE27F6AD51E4BDFC1EEC578FC1
+:1057A000CFF99ADF517AFC1711B250C3EF7CFB910D
+:1057B000D71C295DF8FD53DDAF6C927F0633106F67
+:1057C0003FB7369CDF41FE7A58D18F017F64B687A0
+:1057D000D76912F134D49F1AE3FB29BE97882307B7
+:1057E000616F5CF0F3B7F87DE19ABD29FCEE61F1E1
+:1057F000EEBCD57847E5EB61BE3B72897E8B9D2E72
+:105800003BE490EAC6583E9717F4D1EEA98B76F6A2
+:10581000E7E9EBF360AE94078A3C729C0B9A3E4535
+:1058200008B34D35D593E77FE83ED4EDA2A1F695B8
+:10583000D0F72ABECB9E027B89DD6057D5ED31B60D
+:10584000ACE373709ECFB777FFBB8DAFEB76474D60
+:105850009F5DD8A9CF664FE803B97F9DE2821DBD49
+:10586000CCE9BE11F1F565876C88F01493E2DCF2A7
+:10587000DD92BBE4BB2525B7E6313F9B8F35C9C719
+:10588000BD8751BC8FCB0294C6F7BCDFE7AD7B650B
+:10589000C01ED053D0CBF7E0CB5C5E7B9C412E2A60
+:1058A0006D524CEF18E8F91773A51D723EA919C087
+:1058B000DF4DB7A6D8F186D07C128F1037F8BA46E4
+:1058C000277A3BAAC771259352C541F9AE14C19DF1
+:1058D00022C733FE4E514993F93D06AACF72DDFE31
+:1058E000DC28EEAFD845F34E41EA6238090F8CA7A9
+:1058F000F67BA83F378FC3EB511A0CD86037988FCF
+:105900007816CACF75056C18A7A451BE8FE25B2B21
+:10591000C7F1AD89B5E7402EB0BAEC038CF260A3B5
+:105920007CCF78BEF6FB11042FCBCB658427DCF34C
+:10593000D2EF7D86E2AB5883BFAC29D62C5F36AD63
+:10594000B3617DE6F4F05EC3971A1D97348EE1FBD8
+:10595000F565562FDF97F069F8FEEBB2F0BBE12753
+:1059600099D3FC902D05798D2F7D093CF7069E82F9
+:1059700019FC3ED2B2708E679EE36AE2F976E2FBD2
+:1059800001C20FE4155711E39BE8C48F38C0B2661B
+:10599000F3FA76C11325DF656F2EE6FDB7C8EAB3CB
+:1059A000BB8C70ACDF9F81FB5B7368DFE3FD27E19D
+:1059B000F2F17DCC530FDCC8BFFB063881E7288F9E
+:1059C0007B02DE3B22BA61BAD6E9674181DCCFFABD
+:1059D0007851C3ACD20E3FECBBF6A9F720E4F30636
+:1059E0005A6FD8FF7BDAA7765C00A471ED65F2DD13
+:1059F000BAD07DABEF577D9FEAFB56DFCF8FD98AB8
+:105A000082894A17DFA1F3BDF6B96EF03449837776
+:105A1000AEB6AE84D75785C1AE376298DCDFF3539C
+:105A2000CDFB1FFDA1DF54BD7C6C3003F73DF5FAC3
+:105A3000FAB8F3E3643BEC03D05BEA304B67FDE577
+:105A40005CDF62E21FA59DFC63FBAA04F08F1D0AC8
+:105A5000FBE196DF23E5BEE5CFC87BE16796BFF8A3
+:105A6000F62CAA77FAC18D0B8CF72FCA82925F2C85
+:105A700024790BFC6391260F6CCCF4E50D33ECE735
+:105A8000B2FB9FC9C4FE98DB92770A6FA8D1BCF91C
+:105A9000BDA33F3FF3D28757B9BBCE5D7D1E256BBB
+:105AA000DEB5153B8D7893F47E7756079F5BA5385E
+:105AB000B7E853696331F36191487A8FD2B5EEA1AB
+:105AC000F450DCA8B09C575A3732A0FE2FF2EBD22C
+:105AD000B553F98D287DBDF4775FF47357877FA6A2
+:105AE000B64E73357A9E3D4CEEC3B9E529F645BCFA
+:105AF000FF53ECF8BDCD395AF99C32F3F7CEF5726D
+:105B000075F2FBD5D827B89F84F5EA586B93F6CB8E
+:105B1000ED97AD5732E4021D8EC59A9D72A1666F56
+:105B20005CA4C9CBB45E8B8DEBB5F871B95EA5CF23
+:105B3000BEF517BC5346F3D3DEA393EF0A94B4EC3F
+:105B4000E0759BB3669D2D85EAFD64588A29FEA801
+:105B5000B436CF053BFDDC351B6DE0073F1926F160
+:105B6000164AF7F3B5F8621DAF388F14833F47AF7D
+:105B70000F3EB883C6B9755978B4F177ED021A3D76
+:105B800097D6C6C661BCD2DAE27BA17FE9E740E8DE
+:105B9000FE3B112EF74509F587FD79628C87EF559D
+:105BA000CFD77E372FB4FE431ADDFDDA26DFBF4C98
+:105BB0008A6C7992E33B6A223CE013E9E9AD018CFF
+:105BC0000B7A06DC768B7C2F33BDB2F573C041A215
+:105BD0003CC7F520C57B5B10ED1328BFC922EF79C8
+:105BE000A5AA32DDA7E107A637948B5EADFC1E5F48
+:105BF000E7BB5121F46A179BD7E0DD1F7B2FC1EF74
+:105C0000A6E9F4A9F7A3D3A74EBF3DCD6FD7F79C64
+:105C1000DF8914CDCE92E54976D0B80BEE1BC4BF18
+:105C20006BF15DF3B46BEF3576CE374CFEDEC765B6
+:105C3000F34D97FA52CFF36D2E4CE866BEA1F3D424
+:105C4000F7891E43DFE94F6992FE94130A9D63D4DE
+:105C5000EEC4B2708EABD3E7A5DBF5BFEFBD878F87
+:105C600086C569F6AAD628C897F3B5DF51114199C0
+:105C7000C7F7A986EFFAF9AFBF5FA7F3E993B5DAE3
+:105C8000F9285AEFC17E1675697C0FF558D389281B
+:105C9000BC1373628C844F6F77AB4DDE73165176F5
+:105CA00037DECFBBE9D63CFEBD94858D7D589FBDC8
+:105CB000A92E8DF9C24D7E581745A71EB048E38323
+:105CC00091B716AFBE02F5D7A7F0EFC22D747A4E8A
+:105CD000ADE7F6433D9013239BA7DA53591E96FA7E
+:105CE00082EE17BB5511457C4F0D7C12FBCBB23FAA
+:105CF0001DE7CFE2F5523F9864116BE03F1DD8508D
+:105D000034A12FF8C4C38AFC3D9A0DE6F7BC860E79
+:105D10002AFA027C26F45DBC5B6D2D5EE8A782E466
+:105D20000ED8D1163A8B589EBF45E393C79ADBF83D
+:105D3000BD7E1DAF8FE0BF78A72AC47E146A271AE4
+:105D4000A8D907FF1FAF8F7B3D0080000000000037
+:105D50001F8B08000000000000FFB57C0B5C546541
+:105D6000DAF87BCE992BCCC080C84512878B84850E
+:105D700034C080D7DA518150BBA0BBB9BA218E653F
+:105D8000CA650650DB5D77D7FE8CA1A6667DFA4515
+:105D9000A665ED80976AC376483428A8C90B99593F
+:105DA0007F62376A2FB9635BE62D40BAFCEDBF6DA9
+:105DB0007DCFF3BCE7301751DBFDBE6FFCF97B797B
+:105DC000DFF35E9FFBF3BCCF3963348C751B186324
+:105DD0002A8B8E413968488964998C8D09695F6185
+:105DE0004C89C3F625DB45C64640FB7C93C8621947
+:105DF0002BD731FA7D8FBF1F31761F3C37C3F3425B
+:105E0000A934D607FDD737CCA072C9D6C26DAEF182
+:105E10008C250925B1936360C0E36AB6078A25CE55
+:105E20001977302BCCD3A48DD225C373B52B29C7BA
+:105E3000E09F6F49E343490CC69D69D4CF77437B0C
+:105E400081694E41148C5FBA332A5B32FBFB5D6F74
+:105E500011181BC958A573461C4B61CCF1DDE167D5
+:105E60004CA9B01F98D304F37FE50977BBA08BA39F
+:105E7000AE2D4982233CAAB3A758A07F95D8316F95
+:105E800012CC734E70EF4DA0FEE63853C0FAA1E578
+:105E9000E93AC6CCE98C39FFCF8734CFE7E2893BBA
+:105EA00016C07887737F04CE53F5F81FF201326C69
+:105EB0009D68CFB2E4E1BC8D7B4D121C747B6356B0
+:105EC000099CE3BEC7C746DA332F9FF7B668B6A86A
+:105ED00004DACBDB18C157695FE88ED420DCED5EB5
+:105EE000A6316169629A6828CF486C9507CADB526F
+:105EF000D8A2B9067FBB0DE100EB9E89DC9254026B
+:105F0000ED157B9F48324379D6C8EBA57B7F7A9C01
+:105F10004540FFDD5A0DE2D5AE621A0B8CBBD7258A
+:105F2000D8DC50B2F268C61210A36E7D9991B159B7
+:105F300096709AAF627B0E63B9FE7DC1736A3FAB08
+:105F400062C5B88F31F503D9CBA1FC8BCA7B1FE2A8
+:105F5000F32FB57A8B2B19F16226BCFC658B548428
+:105F6000EDAEFB053656C0FA7E631AAC5F16C96A01
+:105F7000717CA1F4579B04CF571C10B2B5307B78CD
+:105F800066B7E61E039116D159B589D3D98A7675BD
+:105F90005122E07F458B402D0E9557331CBE2A2F92
+:105FA0004D66E680FD56B6B668CCB08EA319CE0914
+:105FB000FD1D9E539AA5785EB685B17CC027FE89EB
+:105FC000F86B3EA5B937003FD5AD1C2ECE56DEBED0
+:105FD0003803903B99B66213D2A0DE2650BD3E6BCB
+:105FE000C2FC35AAC07AFEFC3569589A084E4C3579
+:105FF000905402F0DC94D1A341FC3BD7CAF3425D3C
+:106000001DB05E0D12E548DE9E6AC0F1661AAF3C17
+:1060100077B646D178AF336C03BB0936516D50610A
+:1060200059EF344460B9B356CC50597173611609B5
+:10603000E0DF111691C52261CAAA5E3D4012503BB5
+:10604000705884F6DC48FB83489F710CB802E83333
+:1060500091790506F4DFDFF9592ECE7FCB18DF17D3
+:106060000CB6AE5E337D7E01D0C3268B7C8E4C5F3A
+:106070002ED2F1C84340AFB0BFA7D56C833E07CF47
+:1060800057C2E6423BCCC208CFDF84B9F7C0DFAFCE
+:10609000316F22CECF74DE541CF79ACCA7255AC399
+:1060A0000601F6F59B14FB63B88F3B05F5F86C1100
+:1060B00071208DC57EFD6AFE9C6D79C2A603FC4FE2
+:1060C000E7E867A345E66240A29A51F106A463C1DE
+:1060D0006663AB60FD07330FDDCB802E1E1ED03113
+:1060E0002D9CAF5ECFCF3D7D20EC9400FD468F2AE6
+:1060F000165916F437AB5829F43F94297A55D89F8E
+:10610000E9DCD89FE90A6DBE0C599681FCD0887AEB
+:106110001BF5EF78F31B01CA44E9E2E1483857E286
+:106120002F054B3DF4291B3CFDF4FF85B2F452537F
+:10613000CBEFA1FC75A4BD19517772B0F8941D5036
+:10614000F6B0C9A3B364F2F902F7DFF1AB6F22A294
+:1061500045FFBEFA074EEF7BD98AA5CE22C0B8E92B
+:106160001D92579B75F97EFAE361E3A9D48FE1395B
+:10617000FB0DA25B10B0FFE10F717FD37506AF146A
+:1061800081E3D4177C3AFF38661E1D75FA4646280F
+:10619000F83E91B158DC3C8C1FB8687037C1B96FBC
+:1061A00091F94FA1AF1E8B48F8E991F1A4C091E994
+:1061B000B222917EEBD58A5EF085B34C3F7FD6E864
+:1061C00038FF0C5E126D38FF60B9D6CD608AC18E83
+:1061D00054D2275792A77F0079CA40D7BC976AFB51
+:1061E00033C20FF94A07FC78970C2FC03FC3F9253B
+:1061F00079FEBB64B8DD6510399C7E120227996E6A
+:1062000014BA50F62F98635869B41F9FECD7DD4736
+:106210002393098FE3FF83E3EF13C2DF3727D60110
+:106220001BB151FF984578FC5FC09F57B4FE0BF837
+:10623000EB0EC59F577F3DE2EF71D1D284FC800801
+:10624000C8A1D226C2F9580623FE2F93C22C9BE088
+:106250007C76E4FF9B88EF8F22DF2BFC3EA6D837AD
+:106260001EF5E449C69EC17DF9440FB5A766A71087
+:106270009F5FC7BA13B01DF09C3717F12ED876E890
+:10628000242C7DFB5E86F55D1506CB1E386FBF5B4B
+:1062900074A961FE8628F78EA5B06EC35D991617A6
+:1062A000B63396D58672A03CCC827ABE218ACB8545
+:1062B0008605E9A4870F7E2725ADC2732C08B33469
+:1062C00041FF866CDF2313A0DE30D66C7141D757B7
+:1062D0000596BE1DC7CFD1D13A0D7338DD363C329D
+:1062E000DA8D7A05F4CFF37AA83F591EC6F09C0DDB
+:1062F0008DB68468A0CB9722ECA3B361FFA3244E94
+:10630000D70DC9D00EE536A164C17D38DF78BE6FE8
+:10631000DF82B017F7C22CFA341059D07E7295B1D3
+:1063200009E5A5429777A5737937C6756A07C2C98B
+:10633000359D65D4C2FC7F93E94B81BB60636C558E
+:10634000B41FFE0A9DC5C8701756737A734D97E542
+:10635000623573D70B085FE60B07F8966941414237
+:106360006934D9ADB8EFFAE5801709F7CFE17F526C
+:1063700064E59E61F8E747282CF3884C04E48F32EB
+:10638000C6F9A30CE908E96F15D05100FD31DF759E
+:1063900051A7C3653A82F16B8D25D370BDCF853F80
+:1063A000E463E3897F4AF3875B67563697030BF410
+:1063B000F699D89FED8E14515FAE30F1F54E647FA3
+:1063C000361AF5C5C95FBD791D96C7234A6ECB86BF
+:1063D000FEDB167C5D84E2FC6F093E359EE36F0BAD
+:1063E000FEFF68B443CA56BF49F4FE43F759281963
+:1063F00032504EAF047DA615B0E474B0F23E467440
+:1064000090C86A896EE365FD050CA3473975F300F2
+:10641000D88ECABCF0FF4797746C89CE5F9FC6A226
+:1064200082EA33740941FD0B4DC941CF6F8D1F17AF
+:10643000F47CA6393BA83E3B635250FFDB2DD38250
+:10644000EA774E9C19D47F8E6D4E50DDC64C241FCA
+:106450003AEA8A733F01BBE1B5BA92DC4F5497E345
+:1064600063AAF6D07EB305E824DB3B5F3509EA91E9
+:10647000875626437D53CB115E4F3CF44532E06690
+:1064800073CBD1F92AD0DB536F3CF4450AD41F6D8E
+:10649000E9E2CFA7C062A340ACB6BC39DF05F89AE9
+:1064A0009B62DF8AF89A77A9F6288AF9F7D7CCBDDC
+:1064B0002F5942B930677406EC2737C5FE103EBF2E
+:1064C0002BF69E759100FB1F7D5BAB463CBF985D34
+:1064D000B215E9A1FF22A7F353889791FF7E099691
+:1064E00003D9618A9CBD923C54F8AD03F4C61215E1
+:1064F000C24947A5B7CE44E5A1BA782A8FD499D925
+:10650000128063575D0695C7EA2CD47EBC6E229537
+:1065100027EA6C54BE5B574C65775D09950AFFB25C
+:10652000BD960D6A2442972AEAB4CE4F8F57D263A4
+:106530002028D969059FD0F94DBDAD399BCE759DF9
+:1065400009E959693FDAF9815904FA9D6AD5113D83
+:106550004F35749B75565E47B9B8FB22F38A11BC60
+:106560009F2AB05F8C271BFD98A90E03F54B1B8457
+:106570007E59D8EFCD0494F7536B3516B4639E5013
+:1065800033971EF66F14DF90701DE320CA6CD80598
+:1065900018D53A905771A06BF139F4633A28770F08
+:1065A000F2F54647D72E47F934BACC60A9E7F29501
+:1065B000E44BE2086F02EE2F71A586DA8D628F1927
+:1065C000E5605F9D7716D269812CE70A345CEF3075
+:1065D00011E4BD807CFB6D5722DAF3EDDC9E2FD0F9
+:1065E00096EC44FAAE5671FE65317AF71E5C47D5DB
+:1065F0005DF12CF4EB894DB46C4268C51F64696091
+:10660000B717D61467A2DCED615B88AFC15EFD13DE
+:10661000D2DB8F3381DF459948609EF8E2F0A64DCA
+:1066200002DAADD7E7215DCED59A0F30E0075FF6ED
+:1066300000D1FBDC48731E7A0ABEECAF793DCE7CFC
+:106640004080E7263630BF00EA55CFE94D9F04F081
+:10665000A9D3131554AF694B307D12C0A755F80765
+:10666000FA47B7092A94BB0E792BA704FB05C4B7D8
+:10667000B3F8730DDFDF8006EDD88BD966A26FB05B
+:106680009749EF0FCC34BA9B60BF71236AB357A010
+:10669000FD9469CEC37E49EA8108F463FABF5515BB
+:1066A000BBC9EF1988F8C9783F7D3DD321517B28BC
+:1066B000DDB5E6707FAF26CDB019F1501DAFD351D7
+:1066C000D971B188919D56928676B94DC3FDCBD0D4
+:1066D000F17B73B81E495EAF21B940A208B66C0BBE
+:1066E000634ADDC52632D6F88BB021BF07C0C93456
+:1066F00063653FC8356247415A507F1BF61F7A8E4B
+:10670000F61CF38F4F7949BB63AD4A5E0FE96529EB
+:1067100073A33F182AC7AB72A365B9C0F1FC748C90
+:10672000BE11F19C26017DE750C94C50268633B23C
+:1067300037135FD7BB913E77EB39FDA789BCDC2DC2
+:10674000F2FE9A30E6427A57FC874DB9F629B979BC
+:10675000348F97E6915AB291AE139887D657EC24AE
+:10676000A51FD8437A1202AA8174C4D754491C16B3
+:106770009E2772A615E58C44FEB0B14F03E4775F07
+:1067800078C4AA40FC55E37843E0B8E9344E19EFE9
+:106790005C25B24F47905C243A72A689E42F564B91
+:1067A000EC8880FE16EBD6A09E53C6F5821CFC1426
+:1067B000F0F047908B587E08F210D7FF33C8432C77
+:1067C000FF0AF210DB4F823CC4D207F210DB3F0617
+:1067D0007988E5BCBB8D56E49F9AB669ECD3207EE0
+:1067E00050DB7D01F5DE69C3D39143A6A3DEE4E16E
+:1067F0009FAFCBE17E45EF2D1C9FFDA0BFD1FF00D9
+:10680000BA5C6B8ABEB21EEF37B2F91E80D3B67C7B
+:106810006E87F427F0FAD21C35D56D22DB8EE3B7F4
+:10682000E56BF8FA2962393EB745F3797BD345B277
+:106830009FA64E9EB624079EDB62A13DC75FEFBDBB
+:10684000813FB78DE2ED437A567E3E25D7A4F8EF1F
+:10685000E9DC2F65642701BDD3FC4AFFF726723EB1
+:106860000CEDEF4E138BDDC3C0E32D996F892FD054
+:106870009E463E480EE08B6A33F18542870AFD55FD
+:10688000E57238A769653A07DD42F0431D83723A25
+:106890004E4FF625C0C5C6E03CBB05995F42F901E5
+:1068A0004AD4070A3F287CA0D07B22F09910ED3F04
+:1068B000C7CD21F4AA948FCAE7E88E35FE9CF0DAA2
+:1068C000A136A1DF7733CC87E313C5C177EF46FE4E
+:1068D0008C359AD1F52C7CC8503B9C1CEBFAEFC24E
+:1068E00043910B5780C76570D0F0F25F8503C939BB
+:1068F00094E348BFC3C8ADFD39D1B25DCEE9F744DA
+:106900008E6D1FD251BFA057A1DFD0AF67C3DAD9B8
+:10691000DBF2397F287454053A10EB8978CED4CB5A
+:10692000E59E729EA1732E6324FFD2C2787B289EBF
+:10693000957305C8BFC33901F11FC6B87D711DD855
+:1069400017E84F4DC935D33EFA477E56B695F9CF75
+:106950007F470E6F7F4A94881E14FD32D42E488BD9
+:10696000E66406E91D66423FAF534BFCEE057FE649
+:106970002518873E219BE43FBF20E37170FE58112C
+:10698000EDBBBEAF0D2ED4637DA3064E0A30BE6FA5
+:106990003B18366497D86E1340EFDE073A06F5D4FD
+:1069A00005907B2C9DB173721CA1CF73F124FA73F7
+:1069B000353B24A603504A3BBE9A87F4B4B4536DCA
+:1069C000A2B8D0F6C78E213D9E6E15CC6897F4B55F
+:1069D000C2F1A1BFB3C1E8D643FF22A863FF650699
+:1069E0008DDBCCD7A3F883435EEF537D750AC68554
+:1069F00066EC5013DC973E2FB9D13E3BBC7DA50A17
+:106A0000EBA7DD028B837145D2EAAE04A8573E2D79
+:106A100058B430CE61283A8BF182CAE799C50BF39E
+:106A200057B618C9CF5DDAA0FED817605F94BBB720
+:106A30006AD0EE29DF19DC5EB93BB80EF822F9EF17
+:106A40006886F600F9FC6D8E3186ECCD712C1BED5D
+:106A50004DD6C0E3B98A7CBFDC6E757139BA82CB82
+:106A60006DC6BE8C457F5FEAFC2AE96303AFCF9118
+:106A7000EBA7A0FEF9571C2F0A5CAAE5B53F4F60B3
+:106A8000560F9CB7BA536F42FFBFBAFDEF1118B74C
+:106A9000AF09F3517C9FBD2299D0DEDBD826B91017
+:106AA000BECE0EFD2E11E0567DE03D8DD988705F83
+:106AB0004EF6CAADCCB51EE3DC5E5164DD4447DD65
+:106AC00014A766B681A5384F5FBBDE847640F52BF0
+:106AD0001F74DD8DF50302D3231E47FB884E96EE0F
+:106AE0004086A52DDD26E4FBE94442BC229E3D9173
+:106AF00084AF658877C433E01DF12C213E71BC5111
+:106B0000E3E6742251FDF4731CBF0ADE8BA4CD1A98
+:106B10006CAF6CE4789EB163CFB630A2033593E9D5
+:106B200080F07E7A27C7BBA6739D6614D26F630878
+:106B30001DB46B87E800F777191D84E0BF02F08D64
+:106B40007220940E42F1DF93C3E506D8DFA79F427F
+:106B5000FBDB087E01F3C7234656F51E8D81F5CA7F
+:106B6000A2CF3B9743FBD8F89758DA088A7F15E401
+:106B700062FC6BE63BEB105D3DB35EC8467AA957FD
+:106B8000FBF63C81718BA8708AE3F427CFD9F932E8
+:106B90009CBB20FA9BA416D87FCD6B5ABADE28C9BD
+:106BA0001587EC358C9729F174C033C5C99C1D5AE3
+:106BB0001E176B2DB405FA73FD09FC5C859A81B232
+:106BC000E5E817C07CB88E60E37E5E55078F172816
+:106BD0007E59951237680E8E1B08A677A85F452E42
+:106BE0008F5FA5C6DD6C463BBC7E01B387A55E4DBD
+:106BF0003FF078CCD3B2DF7445FBF10A7A42B11B87
+:106C0000992B386EA1C8A96513F91E8FFEE2B86AE8
+:106C100004C6FD760B848F8A0E904F70DE0AB7DAB9
+:106C20006D1602F849EEFF19D21BC0ED8CABF6A031
+:106C30002821DD1968BF0E993EAB918EE0BC95D638
+:106C40003722F09C0E59AE38DA8D147FAB645B8A24
+:106C500090EE2A613DEF30F454F95C0BF929D7A28C
+:106C600027C5CEAC6E0DEEB7317748CE8CFF1EE057
+:106C7000BB016439D77B2E99FE3223F1DE6F9099E8
+:106C800023919F87F49FC0ED3745FE5CBF1D583CA4
+:106C900060DE716E1D5305AC7FE373A6A0FA784FDA
+:106CA0007C50FF9BDACC41CFB3BD1941CF738F59D4
+:106CB00082EA79DD1383FA4FF8D016549FE42B0E45
+:106CC000EA3FE54C49507D3013CE7395FBC15BE341
+:106CD00085A0FE33CDFAA0F967674405D5070D32CC
+:106CE0007C64BB52B1775FCEE5F66E68A9C0F776DB
+:106CF0004BF03A8ABF7EE7C4E0F5E6D882D7FBA125
+:106D000078D90BFA54057EC273A05FB1FC1DF8134D
+:106D10002AF0139AC19FC0FA8BE04F60E9017F020D
+:106D2000DB5F027F02EBADE04F60FD20F83F586F64
+:106D3000AB2BA6F295BA126ABF16FCBAE4758FC9DE
+:106D4000EB1E97D7FD77E174429EEF5D79BE6E9C96
+:106D50002FCDFFDC593C56BC04FC3C2DFAACC68759
+:106D60007EC30A5F11C62D06DE9218C6A599DD7D89
+:106D7000AC2E06F5D9088A33B39281B731AE527D75
+:106D800020D5B4C98CFAEC0FEFE2F3BE56C98C7C67
+:106D900079A8EDEF1138CF854B61745F4A7A10EF17
+:106DA0001BBF6154DF04CF310E3AB3050408E93745
+:106DB0000FE9B70B694ADD4DF7BD25CD2D1AC45338
+:106DC00015F2293C7FCBA30E7EFE5C63D07313F6D5
+:106DD00087B24AE5A638C2B936653E2FF577A4F1E9
+:106DE0007BCF73CF1D5E3F05F56FCBE211787F5EE1
+:106DF000D5FC5EECBD57C1C7E7075FC8A4FBCA76E8
+:106E000098CFE09FCFD9AE96EB7CFF8EB496A26868
+:106E1000541CCD021B0BC505B685EE5FAADAF63809
+:106E2000506E5565DCAD66009F7E8F24C737F8BD78
+:106E300091C3C4B81DE7F92202EF575FF71CBDC329
+:106E400086F8ED381C81EBF6B74A41FED3682BB7C4
+:106E50008F475B3584BF0BAD8723F05E77A3E730A8
+:106E600087BBCA4BE73F24D7FBA12478B74974FE00
+:106E70008A4B62D03D768655A27966B68D35E2B9E9
+:106E80007A3C7CBD1CAB99B7A72D5E82FB3F1EBF31
+:106E9000204F227B100435CAF11B66EF413BA4CA88
+:106EA00023D986F3EF0AE479BBD49C4EDF4ADBDFBB
+:106EB00085F2F878F1886CD2118A9F69E5766F9136
+:106EC000C69E867AA4C76036229D3F589C6A44FCC1
+:106ED0001EC212DB8B7769EC06BCC7E6EBF598BAED
+:106EE0002390EE7A5A7325B47794F9F2E57587E822
+:106EF0007B086F2EC253B9BBD180F3F8F1C7DB73A7
+:106F0000AC26EA7FDCFDDE3CB4AB7A32C2C92EE9A6
+:106F1000D230F2A7AB9AB95DDCD391D818784F92F2
+:106F20006395FDF20C91F0DAD7A696FBDDBD8705DF
+:106F3000F553D3392FEC0EDE8FC97DEA51B4C71D4E
+:106F40004F4B0CF5A2435D1B8BE7FF6C67F0FECA4D
+:106F500065383BD4DED8D8007A75B40FF18D81E85E
+:106F6000BC5DE11333E153C1634F06B7E77AE2F941
+:106F7000BDA4A3650FD1F5E5F1A4EE64F41F127F63
+:106F8000A9A378E7B5FC67C56E08F0AF18FA8BEADD
+:106F9000E2D43C31C56F1FBC966BABB68E44BFAB21
+:106FA00084FCCA1E06F62CACE9447B3A92F21FB66A
+:106FB000E1BA83AD6ABABF76EADA667D0276D9A015
+:106FC000051805F63DB8532DDF7BD90C68D72E95F3
+:106FD000EDDACFCCF67C09F4AF738D48E7736486A5
+:106FE000911FD327CBBDCF5B92EF24BBE1986442C6
+:106FF0007F688687DBC18E666ED7567B92FF632AD9
+:10700000DAEDCD6ACCD4608A1DE294ED90D3B2DD86
+:107010007B7ACD8086FC9B4E813D968C792A5BBB2A
+:1070200012E1B9337316D9B34EA999EC8965DB83A4
+:10703000ED07B06F82EA55CF85DA17727CCB13DC8F
+:10704000AEF887DBAC4376C638F4670AA5A971C8E9
+:107050000F2FC87855FC9B95E32D94B7B351659ECF
+:10706000A5C421105E359DFB2B70DF6E479885FC13
+:107070008D55AF105CFBBFE47E4C7F3C2378F4332E
+:107080000EDFFE364EE7356AC18DF9483540B6341D
+:107090009F4E70AFC138B36B3082E41363C5C8171D
+:1070A0002B16707FD586315F286B157E08D1ABB764
+:1070B000A87C5254809C68B3A650BF020DB3A33E77
+:1070C0005B69B4907E1BA3E3767AE16A4F36D2C344
+:1070D00018F0C7B501F1F831860101FBED7E80C7DC
+:1070E000FF9578C21C95491D15A01F195B43FD959E
+:1070F000F941A2F0F1D79ADF04F31BFCF303BC23A0
+:1071000011DE5F582DA4B793E628F7FFB5C497CAE0
+:10711000792E00BD611C1863348837C7CE37C89FED
+:1071200073B2EEF538AE2882EFA308F783F5305E30
+:10713000FE5196E7B179BCBC4D2E15F9D590677B11
+:10714000DF0AF59579F63F5949AE99883E57CAB49A
+:1071500002F64C9C6F18F9BBE21D89F0FA05F003AA
+:10716000F2FBC25AC19C16642F713AAFE14DEC3C60
+:10717000F3F44E4538B86CDD1998D7C6387F2D5AD0
+:10718000A537A705DE0720BDA3FF5102FFF2D12FCF
+:10719000E3BF7253C56D9457B52AD68CF71735C81F
+:1071A0000F29D7A6FF50BA87DF4EA4B76AA6B5A0AD
+:1071B0007EA9690B7D6E51A13DFE4D085F24C97407
+:1071C000DA6817E87EBDF15B158FA3950A1437BB0B
+:1071D0000B1A914EE987FDCAA7B9717ECCB3A0FB0B
+:1071E000AE861839EF2B86EEE17E229FFF2E95F7B3
+:1071F0000DE4EFA36A4F32C6718E3AF93DD502E62F
+:10720000A17BDD52D64D656F78F5012F4DEE1A8DBD
+:107210007EF807762DC5911AD7361951CE66B1B5CD
+:1072200026BC1F033679EEFBDC2BDB1BA1F7689431
+:107230009F95E7C7F3CABC92F83CA0833380A3F8BC
+:107240009CCBC757BD7F2002E17EFEFEFDF37ECAC8
+:10725000D00F02B905F354D6B664D0BD8C8B7567D8
+:10726000E4FBF1ABE053C11FB49983F00A67B90E98
+:10727000E0339F0DE4636ED3B5F0A9C039493DF00A
+:10728000630425E8319243A17856E05ECD6AD53C8F
+:10729000FE56FBEE02E8FFB3B5A219EDCACBF07EB5
+:1072A0000DFC78F5FC91D728903F7B257C29785AF6
+:1072B000C8BC54FF308A8FFB70A144F1C3FF697CC6
+:1072C00035E4D94BF2AEC2B7A17C7A25BE5CB42AB4
+:1072D000847F43F874882F2DF02F007FF65511C45A
+:1072E0008F0A7E1D66F09351FF75182D6E76393E1C
+:1072F000D1DFC5FD54B60AEC49E187F0AB8FFCE362
+:10730000507C01ADD8501F54E705F3A982C72BC9A3
+:107310002D45EE7DC4BC474D02DD67703EFE85966F
+:10732000F2E994FB0CE5DEE2D13CAE6F42CB8FC0BC
+:107330006EC17BA24D193D23D1DEEBD528F3F07B46
+:10734000D78FD6748FC67CCD8FA6F1B257C3F34CBE
+:1073500094BA2D8CC7033F4AD0BA106E1F09E3A61A
+:10736000A31DF091F0CB3B783D4E63C6FA82B8E99D
+:1073700026A8F7AA95F8E183B2FC7653F9D18209E1
+:1073800005D44F6047101E668195D03A82105D0C7F
+:10739000FBF9E8E76373F05E4039FF03793C8EF454
+:1073A0001BF91C43F1F65F09146F5F04AAC384F74D
+:1073B00002D39F284E81F693BF4ECDA6FBCA15C1BE
+:1073C000EBA3FE4DA638E5569AE7964B03EAC5991E
+:1073D000FE7D0DE9CD828BBC7DC9D8A07C665BF4B7
+:1073E00038EE27BB5323518F297A6DF0D87E436046
+:1073F0001CF5AC1C771EAA8F7B2429502FBEB1F739
+:10740000E1749CA75CE3CAB218308FF9A924B41FB9
+:10741000CAF73E944E76EDDE8DE9E89F94373D9CA9
+:107420006EA37AB89DFC23153FF7F97D93766D0A1C
+:10743000B0A36F9DC0EDFB52DD1B8568DFCEBAF1B6
+:10744000F37518B71FFB6B81E2700B59F73AD4B78D
+:1074500065199CAF58838EE43FCC47F7A47BC6DD0B
+:10746000BE1BE5FEF18CBFAB97A0FECD53D17C6572
+:10747000CCBD390EE36F1B048ABFF9FB8FA67BD707
+:10748000C56B054D7C0CEA519E77FDC7BC2882E395
+:107490003D1BB2BBB0BD6C356F9FA575B7F6E03C28
+:1074A0004F6828CF0A14654A49C03DF61FF3F83DDE
+:1074B000DDA2CD72BEB1BCCED86DB18D81E7FCA38B
+:1074C0008C7F56FE01C9833B65BCDCB6FABD23F157
+:1074D000306FA4DAFE67942BEF3E7E3A0DE55941FA
+:1074E000F4D94CA4F3B11AFB931578EE262DC52BD5
+:1074F000AD5989521CF4CFB97FDA63582E5ABDF8C2
+:10750000C90A8CFB6ED7911FA6EC6F856016D15F00
+:107510003DDCF8D37B106E671EE779A42B1AAF8F82
+:10752000BB5AFEE2B3753C1FFCF93A1D952FD49966
+:1075300098198EB8AF2E9EEABFAF3353C9E673FADF
+:1075400052F2A6AE345FEEA530CA5BB66ED0511EC5
+:107550007DAED6F6551EC06BEC0DCEA68DF2B9C62B
+:10756000C2F86C57F20C848375E3F22E34614FE558
+:1075700071FFEAED9E0D496487AF3EF54C053CCFA7
+:10758000CC2FF90EC7EB765EA478C1E1F687CA105E
+:10759000DEE54D5A7E3EF9DC671E4F8F7B12E3BC61
+:1075A0006FA9C97FAFD979EA998D50DEBB79B92629
+:1075B00090DE7FE879BF95F7732DBEBA121CFE7579
+:1075C000BE7A3889F8A709F82AF3DFE7AB9AD56BBA
+:1075D000087E73F34BC6E6C3FECFA85D49C84F676C
+:1075E000C6DD4C74EEEA1408FE8A1C57C6A7E6F303
+:1075F000FBE82AD1B399EC48598E7F059E23C2F748
+:107600008DF6CFD2D18EFEAA6DC155CF7DB00E3D85
+:10761000228C9BE9A80C7D9EAFB1A7625E71BEC8AB
+:10762000EDE7D0E7B7E72B71781EB7C59F1090A79D
+:10763000E2848D4546A3FE13BC6120979D6DB79EE5
+:1076400055A1FF067EE1C7C17628FB3840AF5F69D0
+:10765000BFD72AAB711E955FEE4EF85064DE003D39
+:107660003EC917C6BC01EB0EF92BD0A6A1FB9E04A8
+:10767000920B8837CC87EA6B1FD784F5B31A8EC775
+:10768000BE83E097F1B80C93F2FDE73CDB7E3E0B46
+:10769000E56CE879AB5F394FF4E1687BE8A240E73D
+:1076A0009F79569575EDF3BFB1F77C16E2EFACDA32
+:1076B000978FFE579FC6978578A87E95CBF37F1549
+:1076C0000E4A7BC5060D8F130A26F2230BA50B1459
+:1076D00007E83BC6E300D5EDBB489E0E76F0784C3C
+:1076E0008DD85D1487F18BDA535D28CF06E3B95F3F
+:1076F00006F3DB28CF2155D683AA81A43920D71ED3
+:1077000019A207EE0F9E41FED5E03C1E07E561651C
+:107710008533B42BCE213F437BD9AAE4F548E767F4
+:10772000DC2373503EBE9DF58F6A8ADFBD1E6E92CC
+:10773000C88E9530C778084E43E7704B3CD18729F7
+:10774000767138B305F4ABD198EF24BFFA38BF9FF8
+:10775000ABB981F3137B85F39373ED1B9AF880F932
+:107760007E25F393624FCE7AFD1FC4970FE7DA9E12
+:1077700040BE0C475988F3C547521EB5F21E8772AA
+:107780001F69E890FDF862899ED7B4490CEFE5586F
+:10779000BC91F20A8AD916CAB79CC53C53795E8F50
+:1077A000EFD129F07CF6EB522EE6A1813D4DF7DBBF
+:1077B0004561F634CCD3EA150519AE1EEB9C007D6D
+:1077C000F67E3EF757A74A02E9B1818470B253664C
+:1077D000CE7796E27E957E5A91EB339887EC2CE635
+:1077E0001EC8C27B55E61DC8C2FB56A5DFBCD7C369
+:1077F0006B492F328F755EC03AA7F379BCF30BBC8F
+:107800001F07795223DFC3164ADF6E437F6B45277C
+:10781000BF7FEC15933FC03C3317C019F17A1EF0BF
+:107820006A43FD6367361BF2CFF8916EE49F9A7D41
+:1078300002C37CBDEA766D13C685AAD5BE58A4E7FF
+:107840008D6DEF6B909E6BF05E763C8E6772BCDC4C
+:107850004479BF3526C6EFF5DAAEFF00E376CE6396
+:107860005C8B3A55EF513C00E536AE57D5DA42FE17
+:10787000BF8379C9FF773407D3CD603C8FE787F2A8
+:10788000C9E97C73107FCCDCCEF9631EE6731B68FC
+:1078900038C55F67C6C7915DE21FC7F16093CEAF81
+:1078A000433BA63F45A07CFCFE30D75AB48F5CE931
+:1078B000DCAEE97FED052BBDF7A3735B7F8CF93C54
+:1078C000B2DD3B73C3569514B09F991D3CDED81FA3
+:1078D000C6CA0F12DEEDD7213E7CB92567F231BE54
+:1078E000A31978770AC683441E1F0D3D875D8E6BF2
+:1078F0001C67FCFD2865DFB31313B93C636EA2A3BC
+:107900002E39BF5BC9D751C6DF324150EED1B89F87
+:107910002458AEFA5E1ADED7609E2BDED760F93BA4
+:10792000391F16EF6BB0FEA29C0F8BF735D88EF780
+:1079300035586F95F361F1BE06EB785F83E52B72E6
+:107940003EEC71DC2AE5F16D7C0AE9A20B796D94BD
+:10795000BFDE1B1D521F15DCBF375A08AE8F12A8A1
+:10796000BF69C2C6A730FF7893922FC5CC46B4C377
+:107970002AC2F9FB1AA9067BEC04F4F38B77ED45D8
+:107980007F1EF89BDE9F2B885E504AEF97C46819D4
+:10799000CAA3DB27D8474F80F1C78ECD48DB4A7298
+:1079A000524FF7ECBD3FBB3192E27A6F494C8225D2
+:1079B000A765E4AEB5427D9A4120FA85F96E2A5159
+:1079C000FC4C986746C762AB8ACB0713DACB85922B
+:1079D0006309AEB322419F8B72F888D59E81FB511B
+:1079E000E05D346A591ADA455D6AF307189F75BD80
+:1079F000A366E85729713CA5DF93D669F9B8BF990A
+:107A000019A96B73707E60369477360D6BC6FDD9FD
+:107A1000C470A19EE4975985F2207F02A79BE96676
+:107A20006E1F7B35665534FAF561D362F05EB74B55
+:107A3000C6F33119CFC7653CE33D57818ADF7361D7
+:107A400089F75C5886E6A32DCF2FB14D20780F24FF
+:107A500005E6B3CD92DF97000AA1F7D49C721CF320
+:107A60004B59EE34E695DCCAC779689E2A398E7781
+:107A70005E1D7C6FA88CF38F6754CEBD89CB6B16CF
+:107A8000A9E179BFD73117E615CF7D3981E2507D65
+:107A90006ED1A506BCCF055E4779C65EE6FE2E8B8D
+:107AA000E77C33777F1CF5AB97E3A9CEE8EE747CD7
+:107AB000AFA34FE62FA57EF03B9E97E4CC81BA8121
+:107AC000DE23A1F339E776A74741BD4FD08B485F4E
+:107AD000CE26FEBC47E63F678A3C9F7C1EA6F32469
+:107AE000213EFA3B5F4EC2F7103719BC4BB9FCF789
+:107AF000A693DC66DE74CC6F3A2F784E62BEF1AD91
+:107B00006D29A5986F7F5EED7906EBB3DBD2785DCA
+:107B10006839690A7C3ED29384F9C8B7B6A59662E3
+:107B20003EF2F9912DCF445902EAEA974EE273CD25
+:107B30008369A5989F3C5BEB3E568774F37B4E5F51
+:107B4000FA7D074E237CAADAB9FD3E7DDF810B2F3B
+:107B5000A17E3E60A4BC8275139209DFF5EDCF6E65
+:107B6000467AEB6B51133F6C6A7EFF99DF503F2DD5
+:107B70008559666B3D560CC994B41DBA1BF7353B4D
+:107B8000DCF325D6174FBC89F6317B04E7EBA51350
+:107B9000734A914FFB0EECFB05EAB3D99160D8E232
+:107BA0007E5ED0137E2AF78F2BC0B8409FB1BB0CEE
+:107BB000E7AFFE9D96E71FEC8F9B8E7182FF9CC006
+:107BC000F3312A6ED89284FA567CE5F9BDBFC1F82C
+:107BD000E6EFF474DF5313CDEDBD4AA9317F39E1EF
+:107BE0006FD75ECC5BE97B5E4FF7AF151893B3E2BE
+:107BF0007BAC63293EFFEA3FFF5E8678289476EEF1
+:107C0000C5F62F77EB4584438FC6167933F2618F23
+:107C10009AFCCE0AB95ED13B82EF27DC5744F88B41
+:107C2000D99284FAB672C4AFEEC07DCF96B63C83CB
+:107C30007E0F7B564B770E679F07B8C1B8B37BD4D6
+:107C4000984903FB30AA905ECE0B5BCA9EC4F9F73D
+:107C5000F07EE7F55B089EAE3DD7335C0FFA31D47A
+:107C6000C7E785AD41ED67F73C9B857EE9B9DFCD80
+:107C700026FF54A173855F2A776B83F422498258CB
+:107C80008C5BCA3F938B1902E259E70EEEE87B92B8
+:107C9000F9C79F6B567B3500A30A2D5B8BF9CD0A84
+:107CA0003F5426DE5A8CE7AB141BD3D17EA9C8F50E
+:107CB00095215F9CD5335D3CF47B5BD65B95AD6BCA
+:107CC000E6A01D7CA5FDFC4596475FC97CF8559B49
+:107CD000DE1D78DF185AFEB58E994FA8FCF585B5E4
+:107CE0005AB2E595F9DED6781CE8AF554773F971BD
+:107CF00012FA37831CFB93ACEF16AD0AEEFFEE04CD
+:107D00009E4F59ADF1A5A3FE53E67F7B8289DB87A9
+:107D10002A5F3ACAABD071B32559DEBC2090BCA90A
+:107D20006C154ED1FB2408D2583F3C2B752E37E6FC
+:107D3000130D8787F87C190F12E6F170BEAA6CD676
+:107D4000DBF4304F55982F02ED2587D117817650FF
+:107D5000DF2B126B92D117A3CC9FE25F4F89535652
+:107D600078D436FD70EBC171D04F5E867F03285604
+:107D70004FE47C53DE164EEB31932F1FE9B67C6740
+:107D8000F0383CA729801FFBDA76C506FAEB0CF722
+:107D90004DF751A7886FFAFFF931BD075E29B2B5DB
+:107DA000784F794EE0EF83409DDE073927DF775625
+:107DB0007E6D0843FA39F79583F8B84FF0919C7BB4
+:107DC000B1CD4672AC4FED2339B76B6211AF47F9B5
+:107DD000CA506EBD38F1A7243FFA127C65F89ED2D6
+:107DE00066A58E2FCC811DD0D1B690E4C96C89E7F1
+:107DF00051B05D6A138F1371782F93E1C4D886DE7A
+:107E00003AF243D466B4973A272AF7421AFFF92583
+:107E10003F3FF531F3BE56E4CF7203C57DC0BE6A65
+:107E20007E09EDC005B1168CA787C24DB95F8C895C
+:107E3000FE6629E2E91DA37DECC43CBCCFF4919F12
+:107E400001D44EF67CF56B5AF237FBD5037B517E9D
+:107E5000B98DF67113019E0E4DF77A547117D4BE89
+:107E60002E34ED6721BD911CE1F4D697B98BBF0785
+:107E700022DF4F4E92F100FA8C35227D081CCF870D
+:107E8000DBF69F4079D3D79D4A723A949FCEB63D98
+:107E9000168172E343D0EFAE8078C0878B9FA57CBC
+:107EA00080F9980702E53D6B83CF37F8ED8FC92F36
+:107EB000649B03DA911E1B82EBA17041BAF406F1B8
+:107EC000818BF67D3FF21BC0A76A7A7735C261A825
+:107ED0003E17EA5240FD50483DA43F2BE1F6C3FD5A
+:107EE0001318CDEB18EDED253F7E1FCFEFAD07BD8D
+:107EF00046F503E1743F2DEE03BD15C3F516EA8B7D
+:107F0000AA886E8A5FF51DD0D2BDCA83ED9F25E198
+:107F1000F9811E294E53D5FE722CFAF7EB2698698B
+:107F20007ED08FB1941773A03D16FD11A5DD217A87
+:107F3000D2E5F70CB2507E28ED4EC99B4E79E54252
+:107F400077163E5F27CB1987087509EB8CCEE110B9
+:107F500038DFB37689E47C28DE56C9F40AF2218B37
+:107F6000F2395EE1F103451E54C872E510B667723E
+:107F7000FE3729F75278CF847C3F8C9CF85A8123B6
+:107F8000ABA5F8CEFD13CDBC2E8FA77979FC89E780
+:107F9000EDBD7A3E2B2513C79995F745FDF228D5FF
+:107FA0002F5F500EC4931C78501D0BE7AA7C46B07F
+:107FB000D4C3908AD23545D09D2D532D2FA2B81A07
+:107FC000E6E71A2EDF57281D454EE4F8AD14B91F19
+:107FD0005EB957A0FBA5736A7E6F07F286DE0F5865
+:107FE00056B0A608F9EFBE18A726D05FBED6FC4B48
+:107FF0001B82EBCB6AD714C50DC3E795ABB6768D64
+:108000006497CF57616F2C8A355FDEAEECFB9C5EC8
+:10801000D9E774F5C84078CC5F533412CA65BA7F8B
+:10802000171EFCDCE7DAB55ECA572D5D43F7C4B70F
+:108030005CAA0D8AB35E6BBE0AE6A67B902BED3F71
+:10804000B47408DE5E8C2B31E0AF3DC467C03701ED
+:10805000EBC5CBF43A149F285F3C06FD53665F3CAA
+:1080600026303E115AE29B3322E58AB8A8043E2C02
+:10807000B30C030FA5FFD1893CCE1A3F91D3F1A8D1
+:10808000D9553B5E6214D7E941F97BA5F74CFE2236
+:10809000EFEF07BF6732239CF7EBD49B30FED3DFB3
+:1080A000F90DC587FBD719E6F37B07034B80E75D26
+:1080B000F1E39B02E3C0AB26713B24DCCAED9D9A41
+:1080C0000CF5D5E34B99C6A1F812D91B99E174DFE1
+:1080D000D2D7F605E9B7FE8E3C13DE8BF475BB0DE7
+:1080E000C86F35FFFC7FB1A887FB3A3EA5BCB4BE84
+:1080F0006F3FA37CB58D72DEE0A13639DFABDB6C60
+:10810000C4F6FEE2BF1761BF4D72E98F2FF0F898F9
+:10811000522AF18300FFF93BD4537B4C1B1FC554FB
+:1081200099CAB02D24BFC07F8E46BDE18F2B98E346
+:10813000868BC304C615D2543CAE8025C615D2D258
+:10814000785C01EB1857C012E30AD88E7105AC6356
+:108150005C01EB1857C03AC615B0C4B802B67F2907
+:10816000BFE7D10F828BC73D0D24F757627E33C026
+:108170006F6527BFBF5AB947A27B617CCF03F5DF8C
+:1081800065793BAD72DE8E672BDD07D61C902C889F
+:10819000227C1FC4958EF93B0347311E54D32258CD
+:1081A000D698B17D3EED636347DE07A5D8BE476D27
+:1081B00011CD444F1C9F8D825B8F7CD5B187E257D8
+:1081C00005719D94EF5FD32C308CBBCED3723FD919
+:1081D00029416B0EDDAB921DEDD47693FF52F59CD9
+:1081E000600E7CEFBB66E2459213CA7DF552FE88B5
+:1081F000393D7AF392203D6BE37957F827ECC72994
+:10820000E777931D1260172DC57B6C6C97BEA5F7A1
+:108210004D9CE0E08E10AE9D7755D9D1B21EF3B5DE
+:108220007E68FE55E124F9DE3A9BBF4752FCF89286
+:108230007D0760BDC12D5AB2536E9F60BF6D521E47
+:10824000E619D828EE72B4534F7ED6275BAF0F8A5B
+:10825000BB144AD751DC63855A20FD7DC46A9F3B1D
+:1082600009E87246F1BD146F99116F243E56E8F08B
+:10827000496BC94F70DE15E3F977980AB5ECE7341E
+:108280009F9CCFA5E0A9B05E70E3F72C16330BBD21
+:108290003FB008C0877151E5FB1F8B18CFAF50E886
+:1082A0006AC55681E88ABEBC10F0BD8445F83D1011
+:1082B000D07FF76AB9FD9B28F27BF2C44D3C8FE278
+:1082C0003E66A7FC9165487D12E9D7D77CD06E0F3A
+:1082D000BF2E89DBF7E6389C7FF17135E50717C6BD
+:1082E000DD9E6E273D5F40F91382F76EE9FB1BAF01
+:1082F000263F83F3278EAAB9DC0178929FD585F4B7
+:108300004AF11E3B95C7EBCAA99C22BF1F16FA5E15
+:10831000437FE7CB2D38BEB0C66041F85FF13DC06A
+:10832000B0ABBFFFE694F3EB12C59E5C33C2E36BC8
+:108330008305E15118D749EF89A5CAF33F9C5BB289
+:1083400009F1698B602E5C1FEF69B6007C8BF040F1
+:1083500002C6D13D367CCF66A05330513EF56572E2
+:1083600074EB3ACC53A949134C18AF2D0ADB5218C1
+:108370000BF317A524D377766ADA781CB60F4A4E2A
+:108380000753DC92C0C7AA62317ECFF1E8CBB53F7C
+:108390003D29CFDF3E5BE6B3FE8E2F781EF1B5E3BD
+:1083A000B4BBE9FB1C4C4FEFAFD30FF635FBC6D186
+:1083B00014AF55E868B039AE09E9A845D613A5A5AC
+:1083C000EFA9D18E68CCB337231CCA965C5C174BDF
+:1083D000E71C3E4EA6E4DF87C6C902E5EDFF46DE98
+:1083E000FD89BA5A2ADFAD5B4565779D8B9E07E80C
+:1083F0008B2308BF1F106F7D7BD230F156A6334709
+:1084000092BE05BEE7F1ED90F82AF0BB18C0EF333D
+:108410003AA2EED980F64883C682F7CD98FFBCD247
+:1084200040F2E1FD49C3C65915F819282E3BC8F49E
+:10843000398887E919A92A119EFF6D921014E74423
+:10844000BEC17322DF60897CA352F9F9E6690DA3EE
+:10845000EF94A17DE022FB404FF85DBF06E40AD413
+:10846000EF65A620B9722144AE8023F3337A5FAC66
+:1084700043CB3609FEFCCFE9505CCA1946CE78B82A
+:108480009C191DE6799EBEB3501D46F9C5C0EF4448
+:10849000674737F2BCBD25AC84D61D46DED07B3E97
+:1084A000F78E1838F914F4BFF76103D939EB139636
+:1084B000E6FF77E4CD9F2771783C81DF73505DED57
+:1084C0007B0E9B05BC8F5DB1906523BE95EF39C4D3
+:1084D000C118F27BFFF5EF398C983C12BFE7E00A38
+:1084E000FA9E43DC15BEE7306AB27161E0F71C46C4
+:1084F0004D1EB130F87B0EC685F89DB2FFC1EF3935
+:10850000A44FCEBBFC7B0E374E36FFA0EF39803D2B
+:108510009B89E34FE4D8C66399289F3BF4FDE5E3CC
+:10852000F23D6497682FC5B228C2A5A276D16DC569
+:10853000F26DD1733FB6035F4C4478153D967D03D1
+:108540007E972551EBA1BCF227ADB64938FF6BB938
+:10855000B6C9F83C34DE5F2F9F0FF6730BF60BCDD8
+:108560001F53E8E2AEC95C0ECD93CBA9F5C3BFC7DC
+:108570003F6F32BF4FBED6BE61BF77E07ACAFED929
+:1085800096C556DC0FECF74EDC27ECB7044B66883B
+:108590000E7A0FF8727A75C9FB62742E908FB33F12
+:1085A000E1F62895E92A7714DA0DA31E7047E17EDB
+:1085B00047350EE8F17D90DFBA06F4683FFC76F5AA
+:1085C000801EDB7F6BE3F9DAA1F36F9FCCFD91F4A2
+:1085D000A903347E0CFCDD4DFEC14014DA6DE9E5E3
+:1085E0004734AE147A4F6DF62741769399F87B8C19
+:1085F000DC36E60191213D8CD9C1781E63410CE93E
+:10860000B94A1DEF5AF9C0FD22D2D13837EC3B8070
+:10861000FEAEDFAE1A0C7EAFD74BE3AAE425C05EF8
+:108620000B7AEE643CBF74942C8FD05EC4EFD939C2
+:10863000CB8FD077A6C08E0B998FBE7930944F59CF
+:10864000ADB3BFE63353BE6250BFA577FF663DFAB8
+:10865000B5E5A55B35E4172F69598FA5C3F19E26B3
+:108660008E917D19D41FECCBA0FA65FB0CD947F590
+:10867000FD17D7C70DB32ED0C156A413850E8EAAF1
+:108680003DE3D04F3DEA0CB3F0F71D3CF45D9A2674
+:10869000F9BDF45DFF39DDCAF365395DC0F81D3FF2
+:1086A0008C8EEAA9BFF21DAF6B958A1C1CFACE8D89
+:1086B00086B9285E39CB4872AE46F6FFAA9798C8AD
+:1086C0001E51F8BA5AE539B51EFBC51879FE9B8ACA
+:1086D000D1F7AB7AC45194CF4D3FACCF4AA5FBAC98
+:1086E000D87A8F17E71DB85DA0EFB9158473B95A12
+:1086F0002896389E85E74744FE5D81A7517E4898BD
+:1087000047C1BF37302597BF3F10CFF877DB98CAF6
+:108710001CF29D36391E7AEDEFB4F1EF92CDE7F7FA
+:10872000720D5125A5CBF1F9821BE8F9C1EF521F5B
+:10873000B1E2FE2A94EFB4717BBF614E063D7F55D6
+:1087400030AF413DE17A805DE93B6D7AE4FB80EF3B
+:10875000B3BD87F8BAD6F7D994EF0F1C5D70C32369
+:108760007B391CBD78EF5533CB18E4AFFF17313C94
+:108770009ED2C05600000000000000000000000073
+:088780000408350000000000B0
+:00000001FF
diff --git a/firmware/bnx2x-e1h-4.8.53.0.fw.ihex b/firmware/bnx2x-e1h-4.8.53.0.fw.ihex
new file mode 100644
index 000000000000..48d7612907ee
--- /dev/null
+++ b/firmware/bnx2x-e1h-4.8.53.0.fw.ihex
@@ -0,0 +1,12028 @@
+:10000000000039D8000000600000063000003A40CF
+:100010000000191C000040780000009C0000599866
+:10002000000082E400005A38000000D40000DD2007
+:100030000000C7CC0000DDF8000000780001A5C872
+:10004000000056980001A648000000C00001FCE82E
+:100050000000F1D40001FDB0000000040002EF88B0
+:10006000020400480000000F020400540000004594
+:1000700002040058000000840204005C0000000636
+:100080000204007000000004020400780000000078
+:100090000204007C121700000204008022170000F6
+:1000A00002040084321700000604008800000005E6
+:1000B0000204009C12150000020400A0221500009A
+:1000C000020400A432150000060400A80000000489
+:1000D000020400B802100000020400BC001000007E
+:1000E000020400C010100000020400C42010000030
+:1000F000020400C830100000020400CC40100000D0
+:10010000060400D000000003020400DC0010000020
+:10011000020400E012140000020400E422140000B3
+:10012000020400E832140000020400EC4214000053
+:10013000060400F000000003010401240000000098
+:1001400001040128000000000104012C000000004F
+:100150000104013000000000020401D00000890603
+:1001600002040004000000FF02040008000000FF79
+:100170000204000C000000FF02040010000000FF59
+:1001800002040014000000FF02040018000000FF39
+:100190000204001C000000FF02040020000000FF19
+:1001A000020400240000003E0204002800000000B9
+:1001B0000204002C0000003F020400300000003F59
+:1001C000020400340000003F020400380000003F39
+:1001D0000204003C0000003F020400400000003F19
+:1001E000020400440000003F020404CC00000001AF
+:1001F00002042008000002110204200C000002008A
+:10020000020420100000020402042014000002195D
+:100210000204201C0000FFFF020420200000FFFF5A
+:10022000020420240000FFFF020420280000FFFF3A
+:1002300002042038000000200204203C00000000DE
+:100240000204204000000034020420440000003575
+:10025000060420480000001C020420B80000000131
+:10026000060420BC0000005F0204223807FFFFFFE5
+:100270000204223C0000003F0204224007FFFFFF6F
+:10028000020422440000000F010422480000000084
+:100290000104224C00000000010422500000000074
+:1002A0000104225400000000010422580000000054
+:1002B0000104225C00000000010422600000000034
+:1002C0000104226400000000010422680000000014
+:1002D0000104226C000000000104227000000000F4
+:1002E00001042274000000000104227800000000D4
+:1002F0000104227C000000000C042000000003E840
+:100300000A042000000000010B0420000000000A85
+:1003100002050044000000200205004800000032F1
+:10032000020500900215002002050094021500202D
+:1003300002050098000000300205009C0810000033
+:10034000020500A000000033020500A400000030F8
+:10035000020500A800000031020500AC0000000208
+:10036000020500B000000005020500B40000000610
+:10037000020500B800000002020500BC00000002F7
+:10038000020500C000000000020500C400000005D6
+:10039000020500C800000002020500CC00000002B7
+:1003A000020500D000000002020500D40000000198
+:1003B00002050114000000010205011C00000001FB
+:1003C00002050120000000020205020400000001F5
+:1003D0000205020C0000004002050210000000406F
+:1003E0000205021C0000002002050220000000138C
+:1003F0000205022400000020060502400000000A59
+:1004000004050280002000000205005000000007E3
+:100410000205005400000007020500580000000813
+:100420000205005C000000080205006000000001F9
+:100430000605006400000003020500D80000000665
+:100440000205000400000001020500080000000190
+:100450000205000C00000001020500100000000170
+:100460000205001400000001020500180000000150
+:100470000205001C00000001020500200000000130
+:100480000205002400000001020500280000000110
+:100490000205002C000000010205003000000001F0
+:1004A00002050034000000010205003800000001D0
+:1004B0000205003C000000010205004000000001B0
+:1004C000020500E00000000D020500E80000000742
+:1004D000020500F000000007020500F80000000718
+:1004E000020500E40000002D020500EC00000027DA
+:1004F000020500F400000027020500FC00000027B0
+:10050000020500E00000001D020500E800000017E1
+:10051000020500F000000017020500F800000017B7
+:10052000020500E40000003D020500EC0000003779
+:10053000020500F400000037020500FC000000374F
+:10054000020500E00000004D020500E80000004741
+:10055000020500F000000047020500F80000004717
+:10056000020500E40000006D020500EC00000067D9
+:10057000020500F400000067020500FC00000067AF
+:10058000020500E00000005D020500E800000057E1
+:10059000020500F000000057020500F800000057B7
+:1005A000020500E40000007D020500EC0000007779
+:1005B000020500F400000077020500FC000000774F
+:1005C0000406100002000020020600DC000000010A
+:1005D000010600D80000000004060200000302200B
+:1005E000020600DC00000000010600B80000000068
+:1005F000010600C800000000010600BC0000000069
+:10060000010600CC0000000007180400009B000059
+:1006100008180798000D0223071C0000325E000036
+:10062000071C800035960C98071D00001AEA19FE79
+:10063000081D43D057860225011800000000000065
+:10064000011800040000000001180008000000006C
+:100650000118000C0000000001180010000000004C
+:100660000118001400000000021800200000000122
+:1006700002180024000000020218002800000003F5
+:100680000218002C000000000218003000000004D6
+:1006900002180034000000010218003800000000B9
+:1006A0000218003C00000001021800400000000495
+:1006B0000218004400000000021800480000000179
+:1006C0000218004C00000003021800500000000057
+:1006D0000218005400000001021800580000000435
+:1006E0000218005C00000000021800600000000119
+:1006F00002180064000000030218006800000000F7
+:100700000218006C000000010218007000000004D4
+:1007100002180074000000000218007800000004B5
+:100720000218007C00000003061800800000000290
+:10073000021800A400003FFF021800A8000003FFF9
+:100740000218022400000000021802340000000019
+:100750000218024C00000000021802E4000000FF32
+:100760000618100000000400021B8BC000000001EE
+:10077000021B800000000034021B804000000018B3
+:10078000021B80800000000C021B80C000000020C3
+:100790000C1B83000007A1200A1B83000000013806
+:1007A0000B1B830000001388021B83C0000001F4B0
+:1007B000021B1480000000010A1B148000000000CE
+:1007C000061A1000000002B3041A1ACC0001022716
+:1007D000061AA020000000C8061AA00000000002AF
+:1007E000021A1AD000000000061A1AD800000004ED
+:1007F000061A367800000006061A3670000000025D
+:10080000061A500000000002061A500800000004FA
+:10081000061A501800000004061A502800000004B0
+:10082000061A503800000004061A50480000000460
+:10083000061A505800000004061A50680000000410
+:10084000061A507800000002061A4000000000025C
+:10085000061A400800000002041A62C000200228A4
+:10086000061A20000000016C061AB00000000028E3
+:10087000061AB1400000000C061A32C00000001237
+:10088000061A335000000064061A810800000002B6
+:10089000061A25B00000016C061AB0A0000000285E
+:1008A000061AB1700000000C061A3308000000128E
+:1008B000061A34E000000064061A811000000002ED
+:1008C000021A2B6000000000061A3000000000022F
+:1008D000041A300800050248061A301C0000000700
+:1008E000061A31C000000008061A5000000000027D
+:1008F000061A508000000012061A40000000000294
+:10090000021A2B6400000000061A303800000002B2
+:10091000041A30400005024D061A3054000000074A
+:10092000061A31E000000008061A5010000000020C
+:10093000061A50C800000012061A40080000000203
+:10094000021A2B6800000000061A30700000000236
+:10095000041A307800050252061A308C0000000795
+:10096000061A320000000008061A5020000000029B
+:10097000061A511000000012041A4010000202571B
+:10098000021A2B6C00000000061A30A800000002BA
+:10099000041A30B000050259061A30C400000007DE
+:1009A000061A322000000008061A5030000000022B
+:1009B000061A515800000012041A40180002025E84
+:1009C000021A2B7000000000061A30E0000000023E
+:1009D000041A30E800050260061A30FC0000000727
+:1009E000061A324000000008061A504000000002BB
+:1009F000061A51A000000012041A402000020265ED
+:100A0000021A2B7400000000061A311800000002C0
+:100A1000041A312000050267061A3134000000076D
+:100A2000061A326000000008061A5050000000024A
+:100A3000061A51E800000012041A40280002026C55
+:100A4000021A2B7800000000061A31500000000244
+:100A5000041A31580005026E061A316C00000007B6
+:100A6000061A328000000008061A506000000002DA
+:100A7000061A523000000012041A403000020273BD
+:100A8000021A2B7C00000000061A318800000002C8
+:100A9000041A319000050275061A31A400000007FF
+:100AA000061A32A000000008061A5070000000026A
+:100AB000061A527800000012041A40380002027A26
+:100AC0000200A294071D29110200A2980000000054
+:100AD0000200A29C009C04240200A2A000000000CE
+:100AE0000200A2A4000002090200A270000000009F
+:100AF0000200A274000000000200A27000000000CA
+:100B00000200A274000000000200A27000000000B9
+:100B10000200A274000000000200A27000000000A9
+:100B20000200A27400000000020100B400000001F5
+:100B3000020100B800000001020100DC0000000119
+:100B40000201010000000001020101040000000197
+:100B50000201007C00300000020100840000002837
+:100B60000201008C000000000201013000000004BE
+:100B70000201025C000000010201032800000000E5
+:100B800002016080000000010201055400000030F5
+:100B9000020100C400000001020100CC00000001BD
+:100BA000020100F800000001020100F00000000155
+:100BB00002010080003000000201008800000028CF
+:100BC0000201009000000000020101340000000456
+:100BD000020102DC000000010201032C0000000001
+:100BE0000201608400000001020105640000003081
+:100BF000020100C800000001020100D00000000155
+:100C0000020100FC00000001020100F400000001EC
+:100C1000020C100000000020020C2008000002114D
+:100C2000020C200C00000200020C20100000020444
+:100C3000020C201C0000FFFF020C20200000FFFF20
+:100C4000020C20240000FFFF020C20280000FFFF00
+:100C5000020C2038000000C6020C203C00000000FE
+:100C6000020C204000000034020C2044000000353B
+:100C7000060C20480000001C020C20B800000001F7
+:100C8000060C20BC0000005F020C223807FFFFFFAB
+:100C9000020C223C0000003F020C224007FFFFFF35
+:100CA000020C22440000000F010C2248000000004A
+:100CB000010C224C00000000010C2250000000003A
+:100CC000010C225400000000010C2258000000001A
+:100CD000010C225C00000000010C226000000000FA
+:100CE000010C226400000000010C226800000000DA
+:100CF000010C226C00000000010C227000000000BA
+:100D0000010C227400000000010C22780000000099
+:100D1000010C227C000000000C0C2000000003E805
+:100D20000A0C2000000000010B0C20000000000A4B
+:100D3000020C400800000411020C400C00000400EA
+:100D4000020C401000000404020C401400000421B6
+:100D5000020C401C0000FFFF020C40200000FFFFBF
+:100D6000020C40240000FFFF020C40280000FFFF9F
+:100D7000020C403800000046020C403C0000000518
+:100D8000020C404000000034020C404400000035DA
+:100D9000020C404800000007060C404C0000005BBD
+:100DA000020C41B800000001060C41BC0000000329
+:100DB000020C41C800000001060C41CC0000001BE1
+:100DC000020C423807FFFFFF020C423C0000003FCC
+:100DD000020C424007FFFFFF020C42440000000FDC
+:100DE000010C424800000000010C424C00000000D1
+:100DF000010C425000000000010C425400000000B1
+:100E0000010C425800000000010C425C0000000090
+:100E1000010C426000000000010C42640000000070
+:100E2000010C426800000000010C426C0000000050
+:100E3000010C427000000000010C42740000000030
+:100E4000010C427800000000010C427C0000000010
+:100E5000010C4280000000000C0C4000000003E880
+:100E60000A0C4000000000010B0C40000000000ACA
+:100E7000020D004400000032020D008C021500201B
+:100E8000020D009002150020020D009408100000D1
+:100E9000020D009800000033020D009C00000002CB
+:100EA000020D00A000000000020D00A400000005DB
+:100EB000020D00A800000005060D00AC00000002B5
+:100EC000020D00B400000002020D00B80000000393
+:100ED000020D00BC00000002020D00C00000000175
+:100EE000020D00C800000002020D00CC000000024C
+:100EF000020D010800000001020D015C000000016C
+:100F0000020D016400000001020D016800000002F2
+:100F1000020D020400000001020D020C000000207E
+:100F2000020D021000000040020D021400000040FB
+:100F3000020D022000000003020D02240000001830
+:100F4000060D028000000012040D03000024027C44
+:100F5000020D004C00000001020D005000000002D4
+:100F6000020D005400000008020D005800000008A7
+:100F7000060D005C00000004020D00C40000000427
+:100F8000020D000400000001020D00080000000135
+:100F9000020D000C00000001020D00100000000115
+:100FA000020D001400000001020D001800000001F5
+:100FB000020D001C00000001020D002000000001D5
+:100FC000020D002400000001020D002800000001B5
+:100FD000020D002C00000001020D00300000000195
+:100FE000020D003400000001020D00380000000175
+:100FF000020D003C00000001020D01140000000978
+:10100000020D011C0000000A020D0124000000076F
+:10101000020D012C00000007020D01340000000C3D
+:10102000020D013C0000000B020D0144000000070E
+:10103000020D011800000029020D01200000002A05
+:10104000020D012800000027020D013000000027DA
+:10105000020D01380000002C020D01400000002BA1
+:10106000020D014800000027020D011400000019C4
+:10107000020D011C0000001A020D012400000017DF
+:10108000020D012C00000017020D01340000001CAD
+:10109000020D013C0000001B020D0144000000177E
+:1010A000020D011800000039020D01200000003A75
+:1010B000020D012800000037020D0130000000374A
+:1010C000020D01380000003C020D01400000003B11
+:1010D000020D014800000037020D01140000004914
+:1010E000020D011C0000004A020D0124000000470F
+:1010F000020D012C00000047020D01340000004CDD
+:10110000020D013C0000004B020D014400000047AD
+:10111000020D011800000069020D01200000006AA4
+:10112000020D012800000067020D01300000006779
+:10113000020D01380000006C020D01400000006B40
+:10114000020D014800000067020D01140000005963
+:10115000020D011C0000005A020D0124000000577E
+:10116000020D012C00000057020D01340000005C4C
+:10117000020D013C0000005B020D0144000000571D
+:10118000020D011800000079020D01200000007A14
+:10119000020D012800000077020D013000000077E9
+:1011A000020D01380000007C020D01400000007BB0
+:1011B000020D014800000077020E004C00000032D2
+:1011C000020E009402150020020E00980215002065
+:1011D000020E009C00000030020E00A0081000006B
+:1011E000020E00A400000033020E00A80000003030
+:1011F000020E00AC00000031020E00B00000000240
+:10120000020E00B400000004020E00B8000000004E
+:10121000020E00BC00000002020E00C0000000022E
+:10122000020E00C400000000020E00C80000000210
+:10123000020E00CC00000007020E00D000000002E9
+:10124000020E00D400000002020E00D800000001CF
+:10125000020E00E400000001020E01440000000143
+:10126000020E014C00000001020E015000000002BD
+:10127000020E020400000001020E020C00000040F9
+:10128000020E021000000040020E021C00000004CA
+:10129000020E022000000020020E02240000000EB8
+:1012A000020E02280000001B060E030000000012C0
+:1012B000040E0280001B02A0020E00540000001069
+:1012C000020E005800000007020E005C0000000F34
+:1012D000020E006000000010020E00640000000B0F
+:1012E000060E006800000003020E00DC0000000390
+:1012F000020E000400000001020E000800000001C0
+:10130000020E000C00000001020E0010000000019F
+:10131000020E001400000001020E0018000000017F
+:10132000020E001C00000001020E0020000000015F
+:10133000020E002400000001020E0028000000013F
+:10134000020E002C00000001020E0030000000011F
+:10135000020E003400000001020E003800000001FF
+:10136000020E003C00000001020E004000000001DF
+:10137000020E004400000001020E01100000000FE8
+:10138000020E01180000000E020E012000000000F5
+:10139000020E012800000000020E01140000002FC0
+:1013A000020E011C0000002E020E012400000000AD
+:1013B000020E012C00000000020E01100000001FB0
+:1013C000020E01180000001E020E012000000000A5
+:1013D000020E012800000000020E01140000003F70
+:1013E000020E011C0000003E020E0124000000005D
+:1013F000020E012C00000000020E01100000004F40
+:10140000020E01180000004E020E01200000000034
+:10141000020E012800000000020E01140000006FFF
+:10142000020E011C0000006E020E012400000000EC
+:10143000020E012C00000000020E01100000005FEF
+:10144000020E01180000005E020E012000000000E4
+:10145000020E012800000000020E01140000007FAF
+:10146000020E011C0000007E020E0124000000009C
+:10147000020E012C000000000730040000D2000022
+:10148000083007A8000B02BB0734000031B600008B
+:101490000734800036500C6E0735000037591A03A8
+:1014A00007358000286127DA0835FF40401802BD63
+:1014B00001300000000000000130000400000000C6
+:1014C00001300008000000000130000C00000000A6
+:1014D0000130001000000000013000140000000086
+:1014E0000230002000000001023000240000000251
+:1014F00002300028000000030230002C0000000031
+:10150000023000300000000402300034000000010E
+:1015100002300038000000000230003C00000001F2
+:1015200002300040000000040230004400000000CF
+:1015300002300048000000010230004C00000003AF
+:101540000230005000000000023000540000000192
+:1015500002300058000000040230005C000000006F
+:10156000023000600000000102300064000000034F
+:1015700002300068000000000230006C0000000132
+:10158000023000700000000402300074000000000F
+:1015900002300078000000040230007C00000003EC
+:1015A0000630008000000002023000A400003FFF6F
+:1015B000023000A8000003FF0230022400000000F7
+:1015C00002300234000000000230024C0000000033
+:1015D000023002E40000FFFF063020000000080097
+:1015E00002338BC000000001023380000000001AAB
+:1015F000023380400000004E023380800000001063
+:10160000023380C0000000200C3383000007A120BB
+:101610000A338300000001380B3383000000138875
+:10162000023383C0000001F40C3383801DCD6500BC
+:101630000A3383800004C4B40B338380004C4B40D6
+:101640000A331480000000000233148000000001FF
+:10165000063220000000010206328980000000C826
+:1016600006328960000000020632322800000004C1
+:10167000063232000000000904323224000102BFA9
+:1016800006323180000000200632500000000400C5
+:10169000063240000000000204324008000102C08F
+:1016A0000632400C0000000306326B6800000002A6
+:1016B00004326B70000202C106326B10000000029F
+:1016C000043274C0000202C30233080001000000AB
+:1016D00004330C00001002C50233080000000000B3
+:1016E00004330C40001002D506329000000000A028
+:1016F0000632950000000040063297000000003CD2
+:1017000006322450000000B406322AD00000000245
+:101710000632308000000020063280000000012CDC
+:101720000232323800000000063250000000002073
+:101730000632510000000020063252000000002056
+:101740000632530000000020063254000000002042
+:10175000063255000000002006325600000000202E
+:10176000063257000000002006325800000000201A
+:10177000063259000000002006325A000000002006
+:1017800006325B000000002006325C0000000020F2
+:1017900006325D000000002006325E0000000020DE
+:1017A00006325F000000002006326B780000005215
+:1017B00006326E080000000C06329280000000A085
+:1017C0000632960000000040063297F00000003C10
+:1017D00006322720000000B406322AD8000000029A
+:1017E0000632310000000020063284B00000012CD7
+:1017F0000232323C0000000006325080000000201F
+:101800000632518000000020063252800000002085
+:101810000632538000000020063254800000002071
+:10182000063255800000002006325680000000205D
+:101830000632578000000020063258800000002049
+:10184000063259800000002006325A800000002035
+:1018500006325B800000002006325C800000002021
+:1018600006325D800000002006325E80000000200D
+:1018700006325F800000002006326CC0000000527B
+:1018800006326E380000000C02322A3000000000E0
+:10189000063230000000000406324018000000024A
+:1018A00002322A340000000006323010000000042A
+:1018B000063240280000000202322A3800000000F0
+:1018C00006323020000000040632403800000002DA
+:1018D00002322A3C000000000632303000000004D2
+:1018E000063240480000000202322A400000000098
+:1018F000063230400000000406324058000000026A
+:1019000002322A4400000000063230500000000479
+:10191000063240680000000202322A48000000003F
+:1019200006323060000000040632407800000002F9
+:1019300002322A4C00000000063230700000000421
+:1019400006324088000000020720040000740000F6
+:1019500008200780001002E507240000322600005E
+:1019600007248000246E0C8A0824CBB064F002E7C0
+:101970000120000000000000012000040000000021
+:1019800001200008000000000120000C0000000001
+:1019900001200010000000000120001400000000E1
+:1019A00002200020000000010220002400000002AC
+:1019B00002200028000000030220002C000000008C
+:1019C000022000300000000402200034000000016A
+:1019D00002200038000000000220003C000000014E
+:1019E000022000400000000402200044000000002B
+:1019F00002200048000000010220004C000000030B
+:101A000002200050000000000220005400000001ED
+:101A100002200058000000040220005C00000000CA
+:101A200002200060000000010220006400000003AA
+:101A300002200068000000000220006C000000018D
+:101A4000022000700000000402200074000000006A
+:101A500002200078000000040220007C0000000347
+:101A60000620008000000002022000A400003FFFCA
+:101A7000022000A8000003FF022002240000000052
+:101A800002200234000000000220024C000000008E
+:101A9000022002E40000FFFF0620200000000800F2
+:101AA00002238BC000000001022380000000001010
+:101AB00002238040000000120223808000000030DA
+:101AC000022380C00000000E022383C0000001F446
+:101AD00002231480000000010A231480000000008B
+:101AE000062210000000004206227020000000C8FC
+:101AF0000622700000000002022211E8000000002F
+:101B000006223000000000C0062240700000008065
+:101B10000622528000000004062267000000010037
+:101B2000062290000000040004226B08002002E955
+:101B300002230800013FFFFF04230C0000100309EB
+:101B4000022308000000000004230C4000100319C9
+:101B500006228000000000A0062285000000004050
+:101B6000062287000000003C0622404000000006DC
+:101B700006228280000000A00622860000000040AD
+:101B8000062287F00000003C0622405800000006B4
+:101B9000022211480000000006223300000000026B
+:101BA00006226040000000300222114C00000000BC
+:101BB0000622330800000002062261000000003007
+:101BC0000222115000000000062233100000000223
+:101BD000062261C000000030022211540000000003
+:101BE0000622331800000002062262800000003046
+:101BF00002221158000000000622332000000002DB
+:101C000006226340000000300222115C0000000048
+:101C10000622332800000002062264000000003083
+:101C20000222116000000000062233300000000292
+:101C3000062264C00000003002221164000000008F
+:101C400006223338000000020622658000000030C2
+:101C50000216100000000020021700080000000219
+:101C60000217002C000000030217003C00000004D3
+:101C7000021700440000000802170048000000029C
+:101C80000217004C00000090021700500000009066
+:101C9000021700540080009002170058081400003A
+:101CA000021700600000008A021700640000008034
+:101CB00002170068000000900217006C000000800E
+:101CC000021700700000000602170078000007D01D
+:101CD0000217007C0000076C02170038007C10041B
+:101CE000021700040000000F061640240000000246
+:101CF000021640700000001C02164208000000019D
+:101D000002164210000000010216422000000001ED
+:101D100002164228000000010216423000000001B5
+:101D20000216423800000001021642600000000264
+:101D30000C16401C0003D0900A16401C0000009CAA
+:101D40000B16401C000009C40216403000000008B9
+:101D5000021640340000000C02164038000000104B
+:101D6000021640440000002002164000000000015E
+:101D7000021640D8000000010216400800000001D1
+:101D80000216400C00000001021640100000000185
+:101D90000216424000000000021642480000000007
+:101DA00006164270000000020216425000000000B9
+:101DB0000216425800000000061642800000000291
+:101DC00002166008000004240216600C00000410D3
+:101DD00002166010000004140216601C0000FFFFD1
+:101DE000021660200000FFFF021660240000FFFFC3
+:101DF000021660280000FFFF021660380000002075
+:101E00000216603C00000020021660400000003412
+:101E100002166044000000350216604800000023EE
+:101E20000216604C000000240216605000000025DD
+:101E300002166054000000260216605800000027B9
+:101E40000216605C00000029021660600000002A93
+:101E5000021660640000002B021660680000002C6F
+:101E60000216606C0000002D061660700000005223
+:101E7000021661B800000001061661BC0000001FD8
+:101E80000216623807FFFFFF0216623C0000003FA7
+:101E90000216624007FFFFFF021662440000000FB7
+:101EA00001166248000000000116624C00000000AC
+:101EB000011662500000000001166254000000008C
+:101EC00001166258000000000116625C000000006C
+:101ED000011662600000000001166264000000004C
+:101EE00001166268000000000116626C000000002C
+:101EF000011662700000000001166274000000000C
+:101F000001166278000000000116627C00000000EB
+:101F10000C166000000003E80A16600000000001D3
+:101F20000B1660000000000A021680400000000648
+:101F30000216804400000005021680480000000AD6
+:101F40000216804C000000050216805400000002BA
+:101F5000021680CC00000004021680D000000004AD
+:101F6000021680D400000004021680D8000000048D
+:101F7000021680DC00000004021680E0000000046D
+:101F8000021680E400000004021680E8000000044D
+:101F90000216880400000004021680300000007C55
+:101FA000021680340000003D021680380000003F19
+:101FB0000216803C0000009C021680F00000000722
+:101FC000061680F4000000050216880C01010101CC
+:101FD00002168108000000000216810C00000004B7
+:101FE0000216811000000004021681140000000295
+:101FF000021688100801200402168118000000054E
+:102000000216811C00000005021681200000000558
+:1020100002168124000000050216882C20081001F9
+:1020200002168128000000080216812C000000061C
+:102030000216813000000007021681340000000003
+:1020400002168830010101200616813800000004C4
+:1020500002168834010101010216814800000000C7
+:102060000216814C0000000402168150000000049A
+:10207000021681540000000202168838080120046C
+:1020800002168158000000050216815C0000000560
+:102090000216816000000005021681640000000540
+:1020A0000216883C20081001021681680000000812
+:1020B0000216816C00000006021681700000000705
+:1020C00002168174000000010216884001010120FF
+:1020D00002168178000000010216817C00000001D8
+:1020E00002168180000000010216818400000001B8
+:1020F00002168844010101010216818800000001D6
+:102100000216818C00000004021681900000000479
+:10211000021681940000000202168848080120047B
+:1021200002168198000000050216819C000000053F
+:10213000021681A000000005021681A4000000051F
+:102140000216881420081001021681A80000000859
+:10215000021681AC00000006021681B000000007E4
+:10216000021681B400000001021688180101012046
+:10217000021681B800000001021681BC00000001B7
+:10218000021681C000000001021681C40000000197
+:102190000216881C01010101021681C8000000011D
+:1021A000021681CC00000004021681D00000000459
+:1021B000021681D4000000020216882008012004C3
+:1021C000021681D800000005021681DC000000051F
+:1021D000021681E000000005021681E400000005FF
+:1021E0000216882420081001021681E80000000869
+:1021F000021681EC00000006021681F000000007C4
+:102200000216E40C000000000216882801010120DB
+:102210000616E410000000040216E00001010101AE
+:102220000216E420000000000216E424000000046E
+:102230000216E428000000040216E42C000000024C
+:102240000216E004080120040216E4300000000534
+:102250000216E434000000050216E4380000000510
+:102260000216E43C000000050216E00820081001F8
+:102270000216E440000000080216E44400000006D4
+:102280000216E448000000070216E44C00000000BB
+:102290000216E00C010101200616E45000000004C3
+:1022A0000216E010010101010216E46000000000C6
+:1022B0000216E464000000040216E4680000000452
+:1022C0000216E46C000000020216E014080120046B
+:1022D0000216E470000000050216E4740000000518
+:1022E0000216E478000000050216E47C00000005F8
+:1022F0000216E018200810010216E4800000000811
+:102300000216E484000000060216E48800000007BC
+:102310000216E48C000000010216E01C01010120FD
+:102320000216E490000000010216E494000000018F
+:102330000216E498000000010216E49C000000016F
+:102340000216E020010101010216E4A000000001D4
+:102350000216E4A4000000040216E4A80000000431
+:102360000216E4AC000000020216E024080120047A
+:102370000216E4B0000000050216E4B400000005F7
+:102380000216E4B8000000050216E4BC00000005D7
+:102390000216E028200810010216E4C00000000820
+:1023A0000216E4C4000000060216E4C8000000079C
+:1023B0000216E4CC000000010216E02C010101200D
+:1023C0000216E4D0000000010216E4D4000000016F
+:1023D0000216E4D8000000010216E4DC000000014F
+:1023E0000216E030010101010216E4E000000001E4
+:1023F0000216E4E4000000040216E4E80000000411
+:102400000216E4EC000000020216E0340801200489
+:102410000216E4F0000000050216E4F400000005D6
+:102420000216E4F8000000050216E4FC00000005B6
+:102430000216E038200810010216E500000000082E
+:102440000216E504000000060216E5080000000779
+:102450000216E03C0101012002168240003F003FCD
+:1024600002168244000000000216E524003F003FEF
+:102470000216E52800000000021682480000000055
+:102480000216824C003F003F0216E52C00000000BF
+:102490000216E530003F003F0216825001000100A5
+:1024A00002168254010001000216E5340100010009
+:1024B0000216E538010001000616825800000002ED
+:1024C0000216E53C000000000216E5400000000096
+:1024D0000216826000C000C00216826400C000C004
+:1024E0000216E54400C000C00216E54800C000C066
+:1024F000021682681E001E000216826C1E001E005C
+:102500000216E54C1E001E000216E5501E001E00BD
+:1025100002168270400040000216827440004000A3
+:102520000216E554400040000216E5584000400005
+:1025300002168278800080000216827C8000800073
+:102540000216E55C800080000216E56080008000D5
+:1025500002168280200020000216828420002000C3
+:102560000216E564200020000216E5682000200025
+:1025700006168288000000020216E56C00000000CA
+:102580000216E570000000000216829000000000B4
+:1025900002168294000000000216E574000000009C
+:1025A0000216E57800000000021682980000000084
+:1025B0000216829C000000000216E57C000000006C
+:1025C0000216E58000000000021682A00000000054
+:1025D000021682A400000001061682A80000000A6C
+:1025E000021681F400000C08021681F80000004079
+:1025F000021681FC0000010002168200000000208B
+:1026000002168204000000170216820800000080F3
+:102610000216820C00000200021682100000000068
+:102620000216821801FF01FF0216821401FF01FF4A
+:102630000216E51001FF01FF0216E50C01FF01FF84
+:102640000216823C00000013021680900000013F39
+:102650000216806000000140021680640000014004
+:10266000061680680000000202168070000000C09C
+:1026700006168074000000070216809C00000048C7
+:10268000021680A000000048061680A40000000288
+:10269000021680AC00000048061680B0000000075B
+:1026A000021682380000800002168234000025E401
+:1026B0000216809400007FFF0216822000070007A8
+:1026C0000216821C000700070216E5180007000723
+:1026D0000216E51400070007021682280000000019
+:1026E00002168224FFFFFFFF0216E5200000000013
+:1026F0000216E51CFFFFFFFF0216E6BC000000000B
+:102700000216E6C0000000020216E6C40000000146
+:102710000216E6C8000000030216E6CC0000000422
+:102720000216E6D0000000060216E6D400000005FE
+:102730000216E6D800000007021680EC000000FF39
+:1027400002140000000000010214000C000000014F
+:1027500002140040000000010214004400007FFF4A
+:102760000214000C00000000021400000000000031
+:102770000214006C000000000214000400000001BC
+:1027800002140030000000010214000400000000E8
+:102790000214005C000000000214000800000001A8
+:1027A00002140034000000010214000800000000C0
+:1027B0000214006000000000020200580000003215
+:1027C000020200A003150020020200A4031500204D
+:1027D000020200A801000030020200AC0810000054
+:1027E000020200B000000033020200B4000000301A
+:1027F000020200B800000031020200BC0000000329
+:10280000020200C000000006020200C40000000333
+:10281000020200C800000003020200CC0000000217
+:10282000020200D000000000020200D400000002FA
+:10283000020200DC00000000020200E000000006CE
+:10284000020200E400000004020200E800000002AE
+:10285000020200EC00000002020200F00000000191
+:10286000020200FC0000000602020120000000003D
+:102870000202013400000002020201B00000000167
+:102880000202020C0000000102020214000000011A
+:10289000020202180000000202020404000000010B
+:1028A0000202040C0000004002020410000000407C
+:1028B0000202041C000000040202042000000020A8
+:1028C000020204240000000202020428000000208A
+:1028D000060205000000001204020480001F032904
+:1028E000020200600000000F020200640000000706
+:1028F000020200680000000B0202006C0000000EE3
+:10290000020200700000000E0602007400000003C6
+:10291000020200F4000000040202000400000001B2
+:1029200002020008000000010202000C0000000189
+:102930000202001000000001020200140000000169
+:1029400002020018000000010202001C0000000149
+:102950000202002000000001020200240000000129
+:1029600002020028000000010202002C0000000109
+:1029700002020030000000010202003400000001E9
+:1029800002020038000000010202003C00000001C9
+:1029900002020040000000010202004400000001A9
+:1029A00002020048000000010202004C0000000189
+:1029B000020200500000000102020108000000C8ED
+:1029C0000202011800000002020201C4000000001F
+:1029D000020201CC00000000020201D4000000024B
+:1029E000020201DC00000002020201E4000000FF1C
+:1029F000020201EC000000FF0202010000000000E2
+:102A00000202010C000000C80202011C00000002CA
+:102A1000020201C800000000020201D00000000014
+:102A2000020201D800000002020201E000000002E0
+:102A3000020201E8000000FF020201F0000000FFB6
+:102A4000020201040000000002020108000000C8A8
+:102A50000202011800000002020201C4000000008E
+:102A6000020201CC00000000020201D400000002BA
+:102A7000020201DC00000002020201E4000000FF8B
+:102A8000020201EC000000FF020201000000000051
+:102A90000202010C000000C80202011C000000023A
+:102AA000020201C800000000020201D00000000084
+:102AB000020201D800000002020201E00000000250
+:102AC000020201E8000000FF020201F0000000FF26
+:102AD000020201040000000002020108000000C818
+:102AE0000202011800000002020201C400000000FE
+:102AF000020201CC00000000020201D4000000022A
+:102B0000020201DC00000002020201E4000000FFFA
+:102B1000020201EC000000FF0202010000000000C0
+:102B20000202010C000000C80202011C00000002A9
+:102B3000020201C800000000020201D000000000F3
+:102B4000020201D800000002020201E000000002BF
+:102B5000020201E8000000FF020201F0000000FF95
+:102B6000020201040000000002020108000000C887
+:102B70000202011800000002020201C4000000006D
+:102B8000020201CC00000000020201D40000000299
+:102B9000020201DC00000002020201E4000000FF6A
+:102BA000020201EC000000FF020201000000000030
+:102BB0000202010C000000C80202011C0000000219
+:102BC000020201C800000000020201D00000000063
+:102BD000020201D800000002020201E0000000022F
+:102BE000020201E8000000FF020201F0000000FF05
+:102BF00002020104000000000728040000BD0000DC
+:102C0000082807A8000B0348072C00003406000022
+:102C1000072C800037960D02072D00003BC31AE8F1
+:102C2000072D8000382629D9072E0000124537E3EA
+:102C3000082E22203BBC034A0128000000000000AF
+:102C40000128000400000000012800080000000026
+:102C50000128000C00000000012800100000000006
+:102C600001280014000000000228002000000001DC
+:102C700002280024000000020228002800000003AF
+:102C80000228002C00000000022800300000000490
+:102C90000228003400000001022800380000000073
+:102CA0000228003C0000000102280040000000044F
+:102CB0000228004400000000022800480000000133
+:102CC0000228004C00000003022800500000000011
+:102CD00002280054000000010228005800000004EF
+:102CE0000228005C000000000228006000000001D3
+:102CF00002280064000000030228006800000000B1
+:102D00000228006C0000000102280070000000048E
+:102D1000022800740000000002280078000000046F
+:102D20000228007C0000000306280080000000024A
+:102D3000022800A400003FFF022800A8000003FFB3
+:102D400002280224000000000228023400000000D3
+:102D50000228024C00000000022802E40000FFFFED
+:102D60000628200000000800022B8BC00000000194
+:102D7000022B800000000000022B804000000018A1
+:102D8000022B80800000000C022B80C00000006637
+:102D90000C2B83000007A1200A2B830000000138C0
+:102DA0000B2B830000001388022B83C0000001F46A
+:102DB0000C2B8340000001F40A2B8340000000002C
+:102DC0000B2B8340000000050A2B83800004C4B451
+:102DD0000C2B83801DCD65000A2B148000000000A1
+:102DE0000B2B8380004C4B40022B14800000000111
+:102DF000062A29C800000004042A29D80002034C2E
+:102E0000062A208000000048062A9020000000C802
+:102E1000062A900000000002062A21A80000008671
+:102E2000062A200000000020022A23C8000000001B
+:102E3000042A23D00002034E042A249800040350DD
+:102E4000022A2C2000000000022A2C1000000000A2
+:102E5000042A2C0800020354022A3010000000014A
+:102E6000062A404000000010042A400000100356CB
+:102E7000062A6AC000000002062A6B000000000457
+:102E8000042A840800020366022B080000000000E8
+:102E9000042B0C0000100368022B08000100000046
+:102EA000042B0C4000080378022B080002000000ED
+:102EB000042B0C6000080380062AC000000000FC00
+:102EC000062A24A800000014062A25480000002431
+:102ED000062A266800000024062A2788000000240D
+:102EE000062A28A800000024062AA00000000028C6
+:102EF000062AA1400000000C042A29E000020388F1
+:102F0000022A300000000001062A502000000002C2
+:102F1000062A503000000002062A5000000000027D
+:102F2000062A501000000002022A52080000000188
+:102F3000042A6AC80002038A062A6B1000000042B5
+:102F4000062A6D2000000004062AC3F0000000FCE1
+:102F5000062A24F800000014062A25D800000024C0
+:102F6000062A26F800000024062A2818000000245B
+:102F7000062A293800000024062AA0A00000002804
+:102F8000062AA1700000000C042A29E80002038C24
+:102F9000022A300400000001062A50280000000226
+:102FA000062A503800000002062A500800000002DD
+:102FB000062A501800000002022A520C00000001EC
+:102FC000042A6AD00002038E062A6C180000004210
+:102FD000062A6D3000000004022AC7E0000000004D
+:102FE000042A29F000100390062A50480000000E21
+:102FF000022AC7E400000000042A2A30001003A0BF
+:10300000062A50800000000E022AC7E800000000D7
+:10301000042A2A70001003B0062A50B80000000EDF
+:10302000022AC7EC00000000042A2AB0001003C0E6
+:10303000062A50F00000000E022AC7F0000000002F
+:10304000042A2AF0001003D0062A51280000000E9E
+:10305000022AC7F400000000042A2B30001003E00D
+:10306000062A51600000000E022AC7F80000000086
+:10307000042A2B70001003F0062A51980000000E5D
+:10308000022AC7FC00000000042A2BB00010040034
+:10309000062A51D00000000E0210100800000001A6
+:1030A0000210105000000001021010000003D000B8
+:1030B000021010040000003D091018000200041066
+:1030C0000910110000280610061011A000000018B9
+:1030D00006102400000000E00210201C0000000088
+:1030E0000210202000000001021020C00000000299
+:1030F000021020040000000102102008000000015E
+:1031000009103C0000050638091038000005063D8E
+:10311000091038200005064206104C00000001008E
+:1031200002104028000000100210404400003FFF41
+:103130000210405800280000021040840084924A87
+:1031400002104058000000000210800000001080B3
+:10315000021080AC00000000021080380000001057
+:103160000210810000000000061081200000000213
+:1031700002108008000002B502108010000000005C
+:10318000061082000000004A021081080001FFFFC3
+:1031900006108140000000020210800000001A802A
+:1031A0000610900000000024061091200000004A44
+:1031B000061093700000004A061095C00000004AF7
+:1031C0000210800400001080021080B00000000196
+:1031D0000210803C0000001002108104000000007A
+:1031E00006108128000000020210800C000002B5C9
+:1031F0000210801400000000061084000000004A45
+:103200000210810C0001FFFF06108148000000023F
+:103210000210800400001A80061090900000002424
+:10322000061092480000004A061094980000004AD8
+:10323000061096E80000004A02108000000010808E
+:10324000021080AC00000002021080380000001064
+:103250000210810000000000061081200000000222
+:1032600002108008000002B502108010000000006B
+:10327000061082000000004A021081080001FFFFD2
+:1032800006108140000000020210800000001A8039
+:103290000610900000000024061091200000004A53
+:1032A000061093700000004A061095C00000004A06
+:1032B0000210800400001080021080B000000003A3
+:1032C0000210803C00000010021081040000000089
+:1032D00006108128000000020210800C000002B5D8
+:1032E0000210801400000000061084000000004A54
+:1032F0000210810C0001FFFF06108148000000024F
+:103300000210800400001A80061090900000002433
+:10331000061092480000004A061094980000004AE7
+:10332000061096E80000004A02108000000010809D
+:10333000021080AC00000004021080380000001071
+:103340000210810000000000061081200000000231
+:1033500002108008000002B502108010000000007A
+:10336000061082000000004A021081080001FFFFE1
+:1033700006108140000000020210800000001A8048
+:103380000610900000000024061091200000004A62
+:10339000061093700000004A061095C00000004A15
+:1033A0000210800400001080021080B000000005B0
+:1033B0000210803C00000010021081040000000098
+:1033C00006108128000000020210800C000002B5E7
+:1033D0000210801400000000061084000000004A63
+:1033E0000210810C0001FFFF06108148000000025E
+:1033F0000210800400001A80061090900000002443
+:10340000061092480000004A061094980000004AF6
+:10341000061096E80000004A0210800000001080AC
+:10342000021080AC0000000602108038000000107E
+:103430000210810000000000061081200000000240
+:1034400002108008000002B5021080100000000089
+:10345000061082000000004A021081080001FFFFF0
+:1034600006108140000000020210800000001A8057
+:103470000610900000000024061091200000004A71
+:10348000061093700000004A061095C00000004A24
+:103490000210800400001080021080B000000007BD
+:1034A0000210803C000000100210810400000000A7
+:1034B00006108128000000020210800C000002B5F6
+:1034C0000210801400000000061084000000004A72
+:1034D0000210810C0001FFFF06108148000000026D
+:1034E0000210800400001A80061090900000002452
+:1034F000061092480000004A061094980000004A06
+:10350000061096E80000004A021205B00000000113
+:103510000212049000E383400212051400003C10E4
+:103520000212066C0000000102120670000000008A
+:1035300002120494FFFFFFFF02120498FFFFFFFF37
+:103540000212049CFFFFFFFF021204A0FFFFFFFF17
+:10355000021204A4FFFFFFFF021204A8FFFFFFFFF7
+:10356000021204ACFFFFFFFF021204B0FFFFFFFFD7
+:10357000021204BCFFFFFFFF021204C0FFFFFFFFA7
+:10358000021204C4FFFFFFFF021204C8FFFFFFFF87
+:10359000021204CCFFFFFFFF021204D0FFFFFFFF67
+:1035A000021204D8FFFFFFFF021204DCFFFFFFFF3F
+:1035B000021204E0FFFFFFFF021204E4FFFFFFFF1F
+:1035C000021204E8FFFFFFFF021204ECFFFFFFFFFF
+:1035D000021204F0FFFFFFFF021204F4FFFFFFFFDF
+:1035E000021204F8FFFFFFFF021204FCFFFFFFFFBF
+:1035F00002120500FFFFFFFF02120504FFFFFFFF9D
+:1036000002120508FFFFFFFF0212050CFFFFFFFF7C
+:1036100002120510FFFFFFFF021204D4FF802000FA
+:10362000021204B4F0005000021204B8F00080004E
+:1036300002120390000000080212039C0000000820
+:10364000021203A000000008021203A400000002FE
+:10365000021203BC00000004021203C000000005B7
+:10366000021203C400000004021203D00000000094
+:103670000212036C00000001021203680000003F08
+:10368000021201BC00000040021201C00000180834
+:10369000021201C400000803021201C8000008035E
+:1036A000021201CC00000040021201D00000000311
+:1036B000021201D400000803021201D8000008031E
+:1036C000021201DC00000803021201E00001000305
+:1036D000021201E400000803021201E800000803DE
+:1036E000021201EC00000003021201F000000003CE
+:1036F000021201F400000003021201F800000003AE
+:10370000021201FC0000000302120200000000038C
+:10371000021202040000000302120208000000036B
+:103720000212020C0000000302120210000000034B
+:10373000021202140000000302120218000000032B
+:103740000212021C0000000302120220000000030B
+:1037500002120224000000030212022800002403C7
+:103760000212022C0000002F021202300000000999
+:103770000212023400000019021202380000018413
+:103780000212023C00000183021202400000030604
+:103790000212024400000019021202480000000652
+:1037A0000212024C0000030602120250000003063F
+:1037B00002120254000003060212025800000C8696
+:1037C0000212025C000003060212026000000306FF
+:1037D00002120264000000060212026800000006E5
+:1037E0000212026C000000060212027000000006C5
+:1037F00002120274000000060212027800000006A5
+:103800000212027C00000006021202800000000684
+:103810000212028400000006021202880000000664
+:103820000212028C00000006021202900000000644
+:103830000212029400000006021202980000000624
+:103840000212029C00000006021202A00000030601
+:10385000021202A400000013021202A800000006D7
+:10386000021202B000001004021202B400001004A0
+:103870000212032400106440021203280010644066
+:10388000021205B400000001021201B000000001A4
+:103890000600A000000000160200A0EC5554000035
+:1038A0000200A0F0555555550200A0F400005555F2
+:1038B0000200A0F8F00000000200A0FC5554000037
+:1038C0000200A100555555550200A10400005555B0
+:1038D0000200A108F00000000200A18C5554000075
+:1038E0000200A190555555550200A1940000555570
+:1038F0000200A198F00000000200A19C000000005E
+:103900000200A1A0000100000200A1A400005014C8
+:103910000200A1A8000000000200A45C00000C004E
+:103920000200A61C000000030200A06CFF5C000067
+:103930000200A070FFF55FFF0200A0740000FFFF0F
+:103940000200A078F00003E00200A07C000000006C
+:103950000200A0800000A0000600A0840000000576
+:103960000200A0980FE000000600A09C00000007E5
+:103970000200A0B8000004000600A0BC0000000384
+:103980000200A0C8000010000600A0CC0000000348
+:103990000200A0D8000040000600A0DC00000003E8
+:1039A0000200A0E8000100000600A22C00000004B4
+:1039B0000200A10CFF5C00000200A110FFF55FFFF8
+:1039C0000200A1140000FFFF0200A118F00003E0B4
+:1039D0000200A11C000000000200A1200000A000C5
+:1039E0000600A124000000050200A1380FE000003D
+:1039F0000600A13C000000070200A15800000800DA
+:103A00000600A15C000000030200A1680000200085
+:103A10000600A16C000000030200A17800008000F5
+:103A20000600A17C000000030200A1880002000043
+:103A30000600A23C0000000400000000000000009E
+:103A40000000003100000000000000000000000045
+:103A50000000000000000000000000000000000066
+:103A600000000000000000000000000000310032F3
+:103A70000000000000000000000000000000000046
+:103A80000000000000000000000000000000000036
+:103A9000000000000000000000320056000000009E
+:103AA0000000000000000000000000000000000016
+:103AB0000000000000000000000000000000000006
+:103AC000000000000056008C000000000000000014
+:103AD000008C009000900094009400980098009C46
+:103AE000009C00A000A000A400A400A800A800ACB6
+:103AF00000AC00B100B100B300B300B5000000009D
+:103B000000000000000000000000000000000000B5
+:103B100000000000000000000000000000B50100EF
+:103B2000010001060106010C010C01140114011C25
+:103B3000011C01240124012C012C01340134013C1D
+:103B4000013C01440144014C000000000000000061
+:103B50000000000000000000000000000000000065
+:103B60000000000000000000000000000000000055
+:103B70000000000000000000000000000000000045
+:103B80000000000000000000000000000000000035
+:103B90000000000000000000000000000000000025
+:103BA0000000000000000000000000000000000015
+:103BB0000000000000000000000000000000000005
+:103BC00000000000000000000000000000000000F5
+:103BD00000000000000000000000000000000000E5
+:103BE00000000000000000000000000000000000D5
+:103BF0000000000000000000014C01510000000026
+:103C000000000000015101520152015301530154BF
+:103C100001540155015501560156015701570158EC
+:103C200001580159000000000000000000000000E1
+:103C30000000000000000000000000000000000084
+:103C40000000000000000000000000000000000074
+:103C50000159015E015E016A016A017600000000FF
+:103C60000000000000000000000000000000000054
+:103C70000000000000000000000000000000000044
+:103C80000000000000000000000000000000000034
+:103C90000000000000000000000000000000000024
+:103CA0000000000000000000017601770000000025
+:103CB0000000000000000000000000000000000004
+:103CC00000000000000000000000000000000000F4
+:103CD000000000000177019A0000000000000000D1
+:103CE00000000000000000000000000000000000D4
+:103CF00000000000000000000000000000000000C4
+:103D0000019A01C200000000000000000000000055
+:103D100000000000000000000000000000000000A3
+:103D200000000000000000000000000001C201F3DC
+:103D3000000000000000000001F301FA01FA020196
+:103D4000020102080208020F020F02160216021DEB
+:103D5000021D02240224022B022B02630000000039
+:103D600000000000026302670267026B026B026FD1
+:103D7000026F0273027302770277027B027B027F7B
+:103D8000027F0283028302D102D102EB02EB030520
+:103D9000030503080308030B030B030E030E0311B3
+:103DA00003110314031403170317031A031A031D43
+:103DB000031D035E035E0362036203660366036919
+:103DC0000369036C036C036F036F03720372037563
+:103DD000037503780378037B037B037E037E037FF5
+:103DE00000000000000000000000000000000000D3
+:103DF00000000000000000000000000000000000C3
+:103E00000000000000000000037F0391000000009C
+:103E100000000000000000000000000000000000A2
+:103E20000000000000000000000000000000000092
+:103E300000000000039103A603A603A903A903AC95
+:103E40000000000000000000000000000000000072
+:103E50000000000000000000000000000000000062
+:103E600003AC03D9000000000000000000000000C7
+:103E70000000000000000000000000000000000042
+:103E800000000000000000000000000003D904DC76
+:103E90000000000000000000000000000000000022
+:103EA0000000000000000000000000000000000012
+:103EB000000000000000000004DC04E304E304E769
+:103EC00004E704EB00000000000000000000000018
+:103ED00000000000000000000000000000000000E2
+:103EE0000000000004EB052B0000000000000000B3
+:103EF000052B05340534053D053D05460546054FB2
+:103F0000054F0558055805610561056A056A057381
+:103F1000057305CB05CB05DD05DD05EF05EF05F2E6
+:103F200005F205F505F505F805F805FB05FB05FEA9
+:103F300005FE060106010604060406070607060E2E
+:103F40000000000000000000000000000000000071
+:103F50000000000000000000000000000000000061
+:103F60000000000000000000060E06140000000023
+:103F70000000000000000000000000000000000041
+:103F80000000000000000000000000000000000031
+:103F900000000000061406170000000000000000EA
+:103FA0000000000000000000000000000000000011
+:103FB0000000000000000000000000000000000001
+:103FC0000617061D000000000000000000000000B1
+:103FD00000000000000000000000000000000000E1
+:103FE00000000000000000000000000000000000D1
+:103FF0000000000000000000061D062C062C063BF9
+:10400000063B064A064A06590659066806680677B8
+:1040100006770686068606950695070600000000C8
+:104020000000000000000000000000000000000090
+:104030000000000000000000000000000000000080
+:1040400000000000070607190719072A072A073B7F
+:104050000000000000000000000000000000000060
+:104060000000000000000000000000000000000050
+:10407000000000000000000000010000000204C079
+:104080000003098000040E4000051300000617C05D
+:1040900000071C800008214000092600000A2AC0F1
+:1040A000000B2F80000C3440000D3900000E3DC085
+:1040B000000F42800010474000114C00001250C019
+:1040C0000013558000145A4000155F00001663C0AD
+:1040D0000017688000186D4000197200001A76C041
+:1040E000001B7B80001C8040001D8500001E89C0D5
+:1040F000001F8E8000209340000020000000400040
+:1041000000006000000080000000A0000000C0006F
+:104110000000E0000001000000012000000140005C
+:1041200000016000000180000001A0000001C0004B
+:104130000001E00000020000000220000002400038
+:1041400000026000000280000002A0000002C00027
+:104150000002E00000030000000320000003400014
+:1041600000036000000380000003A0000003C00003
+:104170000003E000000400000004200000044000F0
+:1041800000046000000480000004A0000004C000DF
+:104190000004E000000500000005200000054000CC
+:1041A00000056000000580000005A0000005C000BB
+:1041B0000005E000000600000006200000064000A8
+:1041C00000066000000680000006A0000006C00097
+:1041D0000006E00000070000000720000007400084
+:1041E00000076000000780000007A0000007C00073
+:1041F0000007E00000080000000820000008400060
+:1042000000086000000880000008A0000008C0004E
+:104210000008E0000009000000092000000940003B
+:1042200000096000000980000009A0000009C0002A
+:104230000009E000000A0000000A2000000A400017
+:10424000000A6000000A8000000AA000000AC00006
+:10425000000AE000000B0000000B2000000B4000F3
+:10426000000B6000000B8000000BA000000BC000E2
+:10427000000BE000000C0000000C2000000C4000CF
+:10428000000C6000000C8000000CA000000CC000BE
+:10429000000CE000000D0000000D2000000D4000AB
+:1042A000000D6000000D8000000DA000000DC0009A
+:1042B000000DE000000E0000000E2000000E400087
+:1042C000000E6000000E8000000EA000000EC00076
+:1042D000000EE000000F0000000F2000000F400063
+:1042E000000F6000000F8000000FA000000FC00052
+:1042F000000FE0000010000000102000001040003F
+:1043000000106000001080000010A0000010C0002D
+:104310000010E0000011000000112000001140001A
+:1043200000116000001180000011A0000011C00009
+:104330000011E000001200000012200000124000F6
+:1043400000126000001280000012A0000012C000E5
+:104350000012E000001300000013200000134000D2
+:1043600000136000001380000013A0000013C000C1
+:104370000013E000001400000014200000144000AE
+:1043800000146000001480000014A0000014C0009D
+:104390000014E0000015000000152000001540008A
+:1043A00000156000001580000015A0000015C00079
+:1043B0000015E00000160000001620000016400066
+:1043C00000166000001680000016A0000016C00055
+:1043D0000016E00000170000001720000017400042
+:1043E00000176000001780000017A0000017C00031
+:1043F0000017E0000018000000182000001840001E
+:1044000000186000001880000018A0000018C0000C
+:104410000018E000001900000019200000194000F9
+:1044200000196000001980000019A0000019C000E8
+:104430000019E000001A0000001A2000001A4000D5
+:10444000001A6000001A8000001AA000001AC000C4
+:10445000001AE000001B0000001B2000001B4000B1
+:10446000001B6000001B8000001BA000001BC000A0
+:10447000001BE000001C0000001C2000001C40008D
+:10448000001C6000001C8000001CA000001CC0007C
+:10449000001CE000001D0000001D2000001D400069
+:1044A000001D6000001D8000001DA000001DC00058
+:1044B000001DE000001E0000001E2000001E400045
+:1044C000001E6000001E8000001EA000001EC00034
+:1044D000001EE000001F0000001F2000001F400021
+:1044E000001F6000001F8000001FA000001FC00010
+:1044F000001FE000002000000020200000204000FD
+:1045000000206000002080000020A0000020C000EB
+:104510000020E000002100000021200000214000D8
+:1045200000216000002180000021A0000021C000C7
+:104530000021E000002200000022200000224000B4
+:1045400000226000002280000022A0000022C000A3
+:104550000022E00000230000002320000023400090
+:1045600000236000002380000023A0000023C0007F
+:104570000023E0000024000000242000002440006C
+:1045800000246000002480000024A0000024C0005B
+:104590000024E00000250000002520000025400048
+:1045A00000256000002580000025A0000025C00037
+:1045B0000025E00000260000002620000026400024
+:1045C00000266000002680000026A0000026C00013
+:1045D0000026E00000270000002720000027400000
+:1045E00000276000002780000027A0000027C000EF
+:1045F0000027E000002800000028200000284000DC
+:1046000000286000002880000028A0000028C000CA
+:104610000028E000002900000029200000294000B7
+:1046200000296000002980000029A0000029C000A6
+:104630000029E000002A0000002A2000002A400093
+:10464000002A6000002A8000002AA000002AC00082
+:10465000002AE000002B0000002B2000002B40006F
+:10466000002B6000002B8000002BA000002BC0005E
+:10467000002BE000002C0000002C2000002C40004B
+:10468000002C6000002C8000002CA000002CC0003A
+:10469000002CE000002D0000002D2000002D400027
+:1046A000002D6000002D8000002DA000002DC00016
+:1046B000002DE000002E0000002E2000002E400003
+:1046C000002E6000002E8000002EA000002EC000F2
+:1046D000002EE000002F0000002F2000002F4000DF
+:1046E000002F6000002F8000002FA000002FC000CE
+:1046F000002FE000003000000030200000304000BB
+:1047000000306000003080000030A0000030C000A9
+:104710000030E00000310000003120000031400096
+:1047200000316000003180000031A0000031C00085
+:104730000031E00000320000003220000032400072
+:1047400000326000003280000032A0000032C00061
+:104750000032E0000033000000332000003340004E
+:1047600000336000003380000033A0000033C0003D
+:104770000033E0000034000000342000003440002A
+:1047800000346000003480000034A0000034C00019
+:104790000034E00000350000003520000035400006
+:1047A00000356000003580000035A0000035C000F5
+:1047B0000035E000003600000036200000364000E2
+:1047C00000366000003680000036A0000036C000D1
+:1047D0000036E000003700000037200000374000BE
+:1047E00000376000003780000037A0000037C000AD
+:1047F0000037E0000038000000382000003840009A
+:1048000000386000003880000038A0000038C00088
+:104810000038E00000390000003920000039400075
+:1048200000396000003980000039A0000039C00064
+:104830000039E000003A0000003A2000003A400051
+:10484000003A6000003A8000003AA000003AC00040
+:10485000003AE000003B0000003B2000003B40002D
+:10486000003B6000003B8000003BA000003BC0001C
+:10487000003BE000003C0000003C2000003C400009
+:10488000003C6000003C8000003CA000003CC000F8
+:10489000003CE000003D0000003D2000003D4000E5
+:1048A000003D6000003D8000003DA000003DC000D4
+:1048B000003DE000003E0000003E2000003E4000C1
+:1048C000003E6000003E8000003EA000003EC000B0
+:1048D000003EE000003F0000003F2000003F40009D
+:1048E000003F6000003F8000003FA000003FC0008C
+:1048F000003FE000003FE00100000000000001FF79
+:104900000000020000007FF800007FF800000704AC
+:104910000000350000000001FFFFFFFFFFFFFFFF69
+:10492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10493000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10495000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10497000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10499000FFFFFFFFFFFFFFFFFFFFFFFF0000000023
+:1049A000FFFFFFFF00000000FFFFFFFFFFFFFFFF13
+:1049B00000000000FFFFFFFF00000000FFFFFFFFFF
+:1049C000FFFFFFFF00000000FFFFFFFF00000000EF
+:1049D000FFFFFFFF0000000300BEBC20FFFFFFFF42
+:1049E00000000000FFFFFFFF00000000FFFFFFFFCF
+:1049F0000000000300BEBC20FFFFFFFF000000001E
+:104A0000FFFFFFFF00000000FFFFFFFF00000003AB
+:104A100000BEBC20FFFFFFFF00000000FFFFFFFF04
+:104A200000000000FFFFFFFF0000000300BEBC20ED
+:104A3000FFFFFFFF00000000FFFFFFFF000000007E
+:104A4000FFFFFFFF0000000300BEBC20FFFFFFFFD1
+:104A500000000000FFFFFFFF00000000FFFFFFFF5E
+:104A60000000000300BEBC2000002000000040C089
+:104A700000006180000082400000A3000000C3C06D
+:104A80000000E4800001054000012600000146C04E
+:104A900000016780000188400001A9000001C9C031
+:104AA0000001EA8000020B4000022C0000024CC012
+:104AB00000026D8000028E400002AF000002CFC0F5
+:104AC0000002F0800003114000033200000352C0D6
+:104AD00000037380000394400003B5000003D5C0B9
+:104AE0000003F6800004174000043800000458C09A
+:104AF0000004798000049A400000800000010380D7
+:104B00000001870000020A8000028E00000311806D
+:104B1000000395000004188000049C0000051F801D
+:104B20000005A300000626800006AA0000072D80CD
+:104B30000007B100000834800008B80000093B807D
+:104B40000009BF00000A4280000AC600000B49802D
+:104B5000000BCD00000C5080000CD400000D5780DD
+:104B6000000DDB0000007FF800007FF800000487E4
+:104B700000001500000019000000002800100000CF
+:104B80000000000000000000FFFFFFFF40000000E9
+:104B90004000000040000000400000004000000015
+:104BA0004000000040000000400000004000000005
+:104BB00040000000400000004000000040000000F5
+:104BC00040000000400000004000000040000000E5
+:104BD00040000000400000004000000040000000D5
+:104BE00040000000400000004000000040000000C5
+:104BF00040000000400000004000000040000000B5
+:104C000040000000400000004000000000007FF86D
+:104C100000007FF8000003E000001500FFFFFFFF29
+:104C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:104C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:104C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:104C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:104C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:104C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:104C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:104C9000FFFFFFFFFFFFFFFFFFFFFFFF40000000E0
+:104CA0004000000040000000400000004000000004
+:104CB00040000000400000004000000040000000F4
+:104CC00040000000400000004000000040000000E4
+:104CD00040000000400000004000000040000000D4
+:104CE00040000000400000004000000040000000C4
+:104CF00040000000400000004000000040000000B4
+:104D000040000000400000004000000040000000A3
+:104D100040000000400000004000000000001000C3
+:104D2000000020800000310000004180000052009F
+:104D30000000628000007300000083800000940087
+:104D40000000A4800000B5000000C5800000D6006F
+:104D50000000E6800000F700000107800001180055
+:104D600000012880000139000001498000015A003B
+:104D700000016A8000017B0000018B8000019C0023
+:104D80000001AC800001BD000001CD800001DE000B
+:104D90000001EE800001FF0000007FF800007FF8B6
+:104DA0000000023E0000350010000000000028ADA9
+:104DB000000000000001000100350804CCCCCCC587
+:104DC000FFFFFFFFFFFFFFFF7058103C00000000D7
+:104DD000CCCC0201CCCCCCCCCCCC0201CCCCCCCC3D
+:104DE000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2D
+:104DF000CCCC0201CCCCCCCCCCCC0201CCCCCCCC1D
+:104E0000CCCC0201CCCCCCCCCCCC0201CCCCCCCC0C
+:104E100000000000FFFFFFFF400000004000000016
+:104E20004000000040000000400000004000000082
+:104E30004000000040000000400000004000000072
+:104E40004000000040000000400000004000000062
+:104E50004000000040000000400000004000000052
+:104E60004000000040000000400000004000000042
+:104E70004000000040000000400000004000000032
+:104E80004000000040000000400000004000000022
+:104E90004000000040000000000E0232011600D663
+:104EA000001000000000000000720236012300F331
+:104EB00000100000000000000000FFFF00000000E4
+:104EC0000000FFFF000000000000FFFF00000000E6
+:104ED0000000FFFF000000000000FFFF00000000D6
+:104EE0000000FFFF000000000000FFFF00000000C6
+:104EF0000000FFFF000000000000FFFF00000000B6
+:104F00000000FFFF000000000000FFFF00000000A5
+:104F10000000FFFF000000000000FFFF0000000095
+:104F20000000FFFF000000000000FFFF0000000085
+:104F30000000FFFF000000000000FFFF0000000075
+:104F40000000FFFF000000000000FFFF0000000065
+:104F50000000FFFF000000000000FFFF0000000055
+:104F60000000FFFF000000000000FFFF0000000045
+:104F70000000FFFF000000000000FFFF0000000035
+:104F80000000FFFF000000000000FFFF0000000025
+:104F90000000FFFF000000000000FFFF0000000015
+:104FA0000000FFFF000000000000FFFF0000000005
+:104FB0000000FFFF000000000000FFFF00000000F5
+:104FC0000000FFFF000000000000FFFF00000000E5
+:104FD0000000FFFF000000000000FFFF00000000D5
+:104FE0000000FFFF000000000000FFFF00000000C5
+:104FF0000000FFFF000000000000FFFF00000000B5
+:105000000000FFFF000000000000FFFF00000000A4
+:105010000000FFFF000000000000FFFF0000000094
+:105020000000FFFF000000000000FFFF0000000084
+:105030000000FFFF000000000000FFFF0000000074
+:105040000000FFFF000000000000FFFF0000000064
+:105050000000FFFF000000000000FFFF0000000054
+:105060000000FFFF000000000000FFFF0000000044
+:105070000000FFFF000000000000FFFF0000000034
+:105080000000FFFF000000000000FFFF0000000024
+:105090000000FFFF000000000000FFFF0000000014
+:1050A0000000FFFF000000000000FFFF0000000004
+:1050B0000000FFFF00000000FFFFFFF3320FFFFFC3
+:1050C0000C30C30CC30C30C3CF3CF300F3CF3CF324
+:1050D0000000CF3CCDCDCDCDFFFFFFF130EFFFFF86
+:1050E0000C30C30CC30C30C3CF3CF300F3CF3CF304
+:1050F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFF0
+:105100000C30C30CC30C30C3CF3CF300F3CF3CF3E3
+:105110000002CF3CCDCDCDCDFFFFF4061CBFFFFF7D
+:105120000C30C305C30C30C3CF300014F3CF3CF3B5
+:105130000004CF3CCDCDCDCDFFFFFFF2304FFFFFC0
+:105140000C30C30CC30C30C3CF3CF300F3CF3CF3A3
+:105150000008CF3CCDCDCDCDFFFFFFFA302FFFFFB4
+:105160000C30C30CC30C30C3CF3CF300F3CF3CF383
+:105170000010CF3CCDCDCDCDFFFFFFF731EFFFFFCE
+:105180000C30C30CC30C30C3CF3CF300F3CF3CF363
+:105190000020CF3CCDCDCDCDFFFFFFF5302FFFFF61
+:1051A0000C30C30CC30C30C3CF3CF300F3CF3CF343
+:1051B0000040CF3CCDCDCDCDFFFFFFF3310FFFFF42
+:1051C0000C30C30CC30C30C3CF3CF300F3CF3CF323
+:1051D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF64
+:1051E0000C30C30CC30C30C3CF3CF300F3CF3CF303
+:1051F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEF
+:105200000C30C30CC30C30C3CF3CF300F3CF3CF3E2
+:105210000002CF3CCDCDCDCDFFFFF4061CBFFFFF7C
+:105220000C30C305C30C30C3CF300014F3CF3CF3B4
+:105230000004CF3CCDCDCDCDFFFFFFF2304FFFFFBF
+:105240000C30C30CC30C30C3CF3CF300F3CF3CF3A2
+:105250000008CF3CCDCDCDCDFFFFFFFA302FFFFFB3
+:105260000C30C30CC30C30C3CF3CF300F3CF3CF382
+:105270000010CF3CCDCDCDCDFFFFFFF730EFFFFFCE
+:105280000C30C30CC30C30C3CF3CF300F3CF3CF362
+:105290000020CF3CCDCDCDCDFFFFFFF5304FFFFF40
+:1052A0000C30C30CC30C30C3CF3CF300F3CF3CF342
+:1052B0000040CF3CCDCDCDCDFFFFFFF331EFFFFF61
+:1052C0000C30C30CC30C30C3CF3CF300F3CF3CF322
+:1052D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF63
+:1052E0000C30C30CC30C30C3CF3CF300F3CF3CF302
+:1052F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEE
+:105300000C30C30CC30C30C3CF3CF300F3CF3CF3E1
+:105310000002CF3CCDCDCDCDFFFFF4061CBFFFFF7B
+:105320000C30C305C30C30C3CF300014F3CF3CF3B3
+:105330000004CF3CCDCDCDCDFFFFFFF2304FFFFFBE
+:105340000C30C30CC30C30C3CF3CF300F3CF3CF3A1
+:105350000008CF3CCDCDCDCDFFFFFFFA302FFFFFB2
+:105360000C30C30CC30C30C3CF3CF300F3CF3CF381
+:105370000010CF3CCDCDCDCDFFFFFF97056FFFFFD8
+:105380000C30C30CC30C30C3CF3CC000F3CF3CF394
+:105390000020CF3CCDCDCDCDFFFFFFF5310FFFFF7E
+:1053A0000C30C30CC30C30C3CF3CF300F3CF3CF341
+:1053B0000040CF3CCDCDCDCDFFFFFFF3320FFFFF3F
+:1053C0000C30C30CC30C30C3CF3CF300F3CF3CF321
+:1053D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF62
+:1053E0000C30C30CC30C30C3CF3CF300F3CF3CF301
+:1053F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFED
+:105400000C30C30CC30C30C3CF3CF300F3CF3CF3E0
+:105410000002CF3CCDCDCDCDFFFFF4061CBFFFFF7A
+:105420000C30C305C30C30C3CF300014F3CF3CF3B2
+:105430000004CF3CCDCDCDCDFFFFFFF2304FFFFFBD
+:105440000C30C30CC30C30C3CF3CF300F3CF3CF3A0
+:105450000008CF3CCDCDCDCDFFFFFF8A042FFFFF4D
+:105460000C30C30CC30C30C3CF3CC000F3CF3CF3B3
+:105470000010CF3CCDCDCDCDFFFFFF9705CFFFFF77
+:105480000C30C30CC30C30C3CF3CC000F3CF3CF393
+:105490000020CF3CCDCDCDCDFFFFFFF5310FFFFF7D
+:1054A0000C30C30CC30C30C3CF3CF300F3CF3CF340
+:1054B0000040CF3CCDCDCDCDFFFFFFF3316FFFFFDF
+:1054C0000C30C30CC30C30C3CF3CF300F3CF3CF320
+:1054D0000000CF3CCDCDCDCDFFFFFFF1302FFFFF42
+:1054E0000C30C30CC30C30C3CF3CF300F3CF3CF300
+:1054F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEC
+:105500000C30C30CC30C30C3CF3CF300F3CF3CF3DF
+:105510000002CF3CCDCDCDCDFFFFFFF630BFFFFF6A
+:105520000C30C30CC30C30C3CF3CF314F3CF3CF3AB
+:105530000004CF3CCDCDCDCDFFFFFFF2304FFFFFBC
+:105540000C30C30CC30C30C3CF3CF300F3CF3CF39F
+:105550000008CF3CCDCDCDCDFFFFFFFA302FFFFFB0
+:105560000C30C30CC30C30C3CF3CF300F3CF3CF37F
+:105570000010CF3CCDCDCDCDFFFFFFF731CFFFFFEA
+:105580000C30C30CC30C30C3CF3CF300F3CF3CF35F
+:105590000020CF3CCDCDCDCDFFFFFFF0307FFFFF12
+:1055A0000C30C30CC30C30C3CF3CF300F3CF3CF33F
+:1055B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF73
+:1055C0000C30C30CC30C30C3CF3CF3CCF3CF3CF353
+:1055D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF93
+:1055E0000C30C30CC30C30C3CF3CF3CCF3CF3CF333
+:1055F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF72
+:105600000C30C30CC30C30C3CF3CF3CCF3CF3CF312
+:105610000002CF3CCDCDCDCDFFFFFFFF30CFFFFF50
+:105620000C30C30CC30C30C3CF3CF3CCF3CF3CF3F2
+:105630000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2E
+:105640000C30C30CC30C30C3CF3CF3CCF3CF3CF3D2
+:105650000008CF3CCDCDCDCDFFFFFFFF30CFFFFF0A
+:105660000C30C30CC30C30C3CF3CF3CCF3CF3CF3B2
+:105670000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE2
+:105680000C30C30CC30C30C3CF3CF3CCF3CF3CF392
+:105690000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB2
+:1056A0000C30C30CC30C30C3CF3CF3CCF3CF3CF372
+:1056B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF72
+:1056C0000C30C30CC30C30C3CF3CF3CCF3CF3CF352
+:1056D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF92
+:1056E0000C30C30CC30C30C3CF3CF3CCF3CF3CF332
+:1056F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF71
+:105700000C30C30CC30C30C3CF3CF3CCF3CF3CF311
+:105710000002CF3CCDCDCDCDFFFFFFFF30CFFFFF4F
+:105720000C30C30CC30C30C3CF3CF3CCF3CF3CF3F1
+:105730000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2D
+:105740000C30C30CC30C30C3CF3CF3CCF3CF3CF3D1
+:105750000008CF3CCDCDCDCDFFFFFFFF30CFFFFF09
+:105760000C30C30CC30C30C3CF3CF3CCF3CF3CF3B1
+:105770000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE1
+:105780000C30C30CC30C30C3CF3CF3CCF3CF3CF391
+:105790000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB1
+:1057A0000C30C30CC30C30C3CF3CF3CCF3CF3CF371
+:1057B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF71
+:1057C0000C30C30CC30C30C3CF3CF3CCF3CF3CF351
+:1057D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF91
+:1057E0000C30C30CC30C30C3CF3CF3CCF3CF3CF331
+:1057F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF70
+:105800000C30C30CC30C30C3CF3CF3CCF3CF3CF310
+:105810000002CF3CCDCDCDCDFFFFFFFF30CFFFFF4E
+:105820000C30C30CC30C30C3CF3CF3CCF3CF3CF3F0
+:105830000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2C
+:105840000C30C30CC30C30C3CF3CF3CCF3CF3CF3D0
+:105850000008CF3CCDCDCDCDFFFFFFFF30CFFFFF08
+:105860000C30C30CC30C30C3CF3CF3CCF3CF3CF3B0
+:105870000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE0
+:105880000C30C30CC30C30C3CF3CF3CCF3CF3CF390
+:105890000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB0
+:1058A0000C30C30CC30C30C3CF3CF3CCF3CF3CF370
+:1058B0000040CF3CCDCDCDCD001000000007010051
+:1058C00000028170000B81980002025000010270FA
+:1058D000000F028000010370000800000008008033
+:1058E00000028100000B8128000201E0000102009B
+:1058F0000007021000020280000F0000000800F004
+:1059000000028170000B81980002025000010270B9
+:10591000000B82800008033800100000000801001E
+:1059200000028180000B81A80002026000018280D9
+:10593000000E829800080380000B0000000100B0F8
+:10594000000280C0000580E8000201400001016003
+:10595000000E017000038250CCCCCCCCCCCCCCCC93
+:10596000CCCCCCCCCCCCCCCC00002000CCCCCCCC87
+:10597000CCCCCCCCCCCCCCCCCCCCCCCC0000200077
+:10598000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC57
+:1059900004002000000000001F8B08000000000031
+:1059A00000FFFB51CFC0F0038A277033309CE345E2
+:1059B000F0E981831829D35FC6CEC05001C4554099
+:1059C000BC0B883FB132307C66255EFF352904DB95
+:1059D000488281211E88D7883130A84922C41DA45D
+:1059E00019182603F9A150B147403A5F8A32770F60
+:1059F000169CA68029E62A8760A7639147C6196886
+:105A0000F24BE550F99904F40F34BEA28ECAFFA2FE
+:105A10000AA113A0E257D1E4BF42E53BA0FEBAA61B
+:105A20008EDDDC4E32FD5DC302A101FC99B04798CA
+:105A300003000000000000001F8B080000000000B1
+:105A400000FFED7D0B7854D5B5F03E731E3393798E
+:105A5000E424E43181104E1E2068080384888AB74C
+:105A6000271030F6D27678D5582D0EAF10F2866B0F
+:105A70002DBDB67F06084978A8C11F11ADD5E12913
+:105A8000F6821D3122B6880328D2ABBD37587C552B
+:105A9000EB1FD10B8A90442A6AEFB5E5EEB5F63ECE
+:105AA000C99C9309047BDBAFFFFFFD7C9FEEECC735
+:105AB000D97BEDF5DA6BADFD18C93181A40D23E476
+:105AC00022FCFB0621929D1032A1379DE32021D7B5
+:105AD000184292662FFDDD921442DCBAE2BF49A360
+:105AE000A9BBFEE41A9A5F5FECF0AFA44D5B1F4DBB
+:105AF000786A092DBFEFA12FC34FD07CFAEC79ADA6
+:105B0000C5B47ECE24C90F5D1D1AAB1002EDE7D8D7
+:105B1000C276015281E5979030A17F92AFE8F845B7
+:105B200084B8E89F2497FE37891CB2A5603EE4D173
+:105B3000A09E029946483631FE55607E36FC09F536
+:105B4000447767D0EF759E77E513EC7F8E5F0ADBB5
+:105B5000E94773F20372C84DD3C6086D49C71DFBF0
+:105B60005D3908F9C00C99E46387B6D8FE6FCA0F97
+:105B70004C7514D2FE670B08FFF9D94936DA82CC8E
+:105B8000A6EDE13B224E1F1ACC679FD9E8B8DFE0B3
+:105B9000DFDDDF40FFA7C05F4B09A1E5CB1C0C9EFA
+:105BA000E4D9D9C530CE8919D71643BF73A61332AD
+:105BB00088564D9D3DF69044F3EB1A89DF4EDBCDC0
+:105BC000290D1CCF81D9F8CBA79302E8978EEE6000
+:105BD0007D5FC4FFEB38EF643EDE3FCC1E2B10FA36
+:105BE00041F6978AA95D72A0F953D14B486A052DF9
+:105BF0001F1953EE9F769AD0F2E4E9E6F64013724D
+:105C00001D2125C49372EA1AFA7716C9BA2842AD43
+:105C10006A0B8CEEE50F6B4AFFFDF922D001FA12F8
+:105C2000FBD61F6A9CE9E9A0F85A377B9687D0F427
+:105C3000F5C02C0FE0EFF5D9B3108FD6F673666779
+:105C400027025EFB1BEFFE063AD008FA3DC7B3B54C
+:105C50007E9048EA23F4FB393AD1C331FDDF01934A
+:105C60004D256409301B4DB325D5A6D2FA6C8DE8BD
+:105C70009138E39502B1693B92499928E352F30FB9
+:105C800061BB3726D94AC371E67307EFC7551AB807
+:105C9000670EA56FD674127551BA1229AAC6E2759D
+:105CA0005D8A541A8E03C7DD1C5E42687BCFC0E15B
+:105CB0007165D802D09F32470CC4C2F50380674299
+:105CC0006F4AA24CEEE6F818FD72BFFB6C508F33A2
+:105CD0008FBB008E0990AAEC3B0E8F0C7C9301B217
+:105CE0009682FC43C26324E0FBCC1EB9240107E585
+:105CF0008FA1F01715AE2DA47BD41214B256EC4729
+:105D0000F4A42403BD5711DE0F29514F517E1542D3
+:105D1000AB848BD75C6A9E123965F035F0A93B19CC
+:105D2000C7BF1C5E48A018E55231D48878C007E38D
+:105D30002BF94DED02A5CBBAD1E57E946F8A219067
+:105D400033437EE1DF57F43B37FFCCBD9CD291CA91
+:105D5000916B39D38F8ADF2C67EB928EB50820C800
+:105D600064B9490F1012244077036FEBBEA278BCD0
+:105D700004BF5BFBDD6FC8E7603298C927933F051E
+:105D8000FA07BD79D37E07F0F53ADF5E07CC6B5D8D
+:105D9000FE5E827A8AD3C7E8D795AF5D52CED681B0
+:105DA0007C8D80EEC348A79EF2D1A7C6027E76A660
+:105DB0002AF78B747E3B9308EAD9756B48782BD011
+:105DC000B594E5B56F69E1B5748E3B9DBCBE98D6C0
+:105DD000D3BC06EDA9BEDB3A490B87687E6B8B8D81
+:105DE000B51FAB85459A1F319184148A4F6DC5C28A
+:105DF000954E5ABE75A3EA17B55EFD34A225672DF0
+:105E0000B4DFB2DEA60AF0BD8FAD233BF3493844C0
+:105E1000C7DFB139F99B23693E14B2F987D34FF23A
+:105E2000F8FA45D9A5442802B4313A9C21795CAEF0
+:105E30000402E5A9BC7CCB7EFFBF8EA4F03D365D9D
+:105E4000F2AFA0453BD6CF4CD0289E766881043F68
+:105E50004D7FF0C07CCCEFCC0C2600DD766E9C9F95
+:105E6000004CF1C0E6991B46417B61D2611DE96C93
+:105E7000D6FF471F283AEC00384B999E4F6A0D7E9B
+:105E800053A2F9BC4912B9894E21CFAD21DCDB1FE9
+:105E9000B211584FFBE86D8BBE4ED4CD7957EBB4A1
+:105EA0008F817F5D0F160920DA3B3586E7413792F7
+:105EB000F08AECBEE3EF5CC8EA13295D800E2EBFCA
+:105EC000625967965AF856477970713CB95A751CF1
+:105ED0008F487A8990D68B57FA9F4662F0E97AF01C
+:105EE0002881F5E98AE76381275DA07C0F83AB9C5D
+:105EF000EFB91E1CF7CA5763E3F1B121EF1EA07F73
+:105F000022C577612404EB507A61240AFCE2C95768
+:105F100034B00B9A0931C9C5A1D1FB7C1D203713C0
+:105F2000223E58AFD78D7E83C98F5681F830E66FF9
+:105F3000B4F7E4B79358FBC1A88772F8CE537869D9
+:105F400039BB87CB594F7F84AD4724731CC2754F33
+:105F5000E161755E1C7D4CC80A94CB9749E07A815B
+:105F6000A6DECDED51A7066CAEDF0079B7400291F9
+:105F700038DF4D13D87AD242745DA0E9A3442F16BE
+:105F8000709D4B66FAD7B22EF5D19FBC5D16E9160F
+:105F900040DF68D43E803487F831CD23014C4792EE
+:105FA000564CAF26114CF3493BA605A41B5343AFF7
+:105FB000F8892A427EC4C4FAC920E7A4DA638BE5D3
+:105FC000BBD06432B23ECE3C9A2D787390F8EBF899
+:105FD0001D025FE748A68AFC43F87AF16EB018E824
+:105FE000C55428FCBBDBCCEFE224BE0E38EA3D6989
+:105FF000805733DD8D5454CD7C5A6DF0A944241C58
+:10600000C7321FC463CCB8D6FE5673FBC6989F9C9C
+:10601000A2231F496E66CF5038F4BD71F0D1280815
+:106020007C9E41ABDC3AB229BF4B49B6C85A9A6B49
+:10603000744F76E8382F3F894767EB7CACF02ABE77
+:1060400081C1B3A9079E0ACB3AFA97C2F34FA6FEC5
+:10605000A44CB21DD60BA28670DE56BCF6F9DE4209
+:106060008FFEE4D29169D6574A8AD70287859F0668
+:10607000687F7CE34BEA7FE4C3FA1B21412AECA949
+:10608000F90101E67FAD401A13295EC868A2EDA0B0
+:1060900070CDF56ACC8E8B693719F491660BC97493
+:1060A000BECF92EE23D03EE427911DF4B367F36D8B
+:1060B000A55B697DAA9FB663FD05401EAE1D6D0BF5
+:1060C00040B9D19F4E9E32F547FD2E11F0E136E8E2
+:1060D00063F1C3E4B136B41F957CA26F89235FC717
+:1060E000B97C151D71EAB09EB8CA94B0331BFA8F03
+:1060F00014433EB59AF8615D9FD4CDE651C6E130B8
+:10610000E69DFA5940007E6AF7313BC05548D03FC2
+:106110005432DA74F01FDDB40EF5427E541753503A
+:106120003FA23FD81F9E3D5F3DED0BD07E7DD4B991
+:106130006A07BE92FCE9A09F578F56C860FABDF867
+:106140003B3BF6FFB9A762188999CF470DD1B10B38
+:10615000A9C170A6E118A6671BDA31ED6C780BD3E4
+:10616000FEE94A598EDACEEB7EE2D7C01E100F3F11
+:1061700047340FC01DD5755C171CA212B32E808248
+:1061800006FF6FD3D8BCF0DA6CC46B08E64DD56758
+:10619000787836E05B0A009E873822C2D27C867708
+:1061A000C03FD001CA8B8E3CB702F15C4DC6029E47
+:1061B00037C9A40CF43CE013D6897D82ED0E800330
+:1061C000F2F369FEFA8FFAC1FB5986F78C97299E84
+:1061D000004E494B64C6AD8EF2953B910B12D7270A
+:1061E000BD7A92F9D9BDF6BDF6EF00CF964689ACDF
+:1061F00085BCA6684A11B7F7414A8215D3C1DFDCD6
+:10620000563EFD28D80BB9E25787645A3EB45E3A31
+:10621000D911234F596574FDA476C2B0E5E6F2ECBE
+:1062200090394F07407F34B7C55C3EC4C6F5AE8792
+:1062300078401EADF35AB6E85771FDD3550D24EAE8
+:106240009663F202C3A79117BC133B42747ECB4600
+:10625000118C034CB7B1F5B315BEA37C712F4FD78A
+:106260005BFA315269A2DB46C6303D196F7DBADD5B
+:10627000563CCE46FB6BB04D1E67A372E4922204DF
+:10628000EC77975BD1E3F993D36D128E9F20B5EB3A
+:106290002285ABFB3AE2DF4AF1BE4CEE8E827C2CCB
+:1062A0002BD6FC215047FE30CA6312D56162F61529
+:1062B000C153027050784A6C384E04FBE9A6380787
+:1062C000FB7D99CCFA5D364A236837F603E75536ED
+:1062D00019E10CD80409FD344E97551539F74DA333
+:1062E000D94E559F05FD67260567C17846B96F7E73
+:1062F00029FA6319C3CCF42B77D467017F540622A3
+:10630000D3807F4E7B5F6C92E9BCB73610BF44F1FF
+:10631000FF9E2B701BF457737BFD08B07FDF065E7A
+:1063200098002A3B807AACA564A55FA2E572891427
+:1063300095293FCA130FBF2517401A2A86388B9319
+:10634000D4337D47F54B2235BD1C23F58F217EA22A
+:10635000803CD072556F25600F38A8DB703286EF15
+:10636000944C731E6CFAD87C7F7AE3722998E727E5
+:106370008703FE09DAE9DD49CC7F9226FA0B00DEBD
+:106380007BAFFFA606F0FCC46633F967567F4D5A13
+:10639000FE6F69791068E2FEB6B4FCD5B4BCF1803A
+:1063A00097569C9763CA32940B05F02432F907BFC5
+:1063B000BE671DE478F85BCFDB582F5737BC35F844
+:1063C000C3E120A71D833FA4C4592D0591FF423E80
+:1063D000F0B5281C92998F09784F1362526E1718E6
+:1063E000F69B9C5A887494DCD2A98E98F5DDC08FF8
+:1063F000B2FCDDC11F8E87F46D4CAD7855A4200131
+:106400003FD068D713B718E0FAEF34E2A979C41F78
+:10641000A53873A4B0786A7A5E280AF37252FD092F
+:10642000EBD33D235F6BC5F081C50F3B94AD203F9F
+:10643000B48CB6615CB36578E49002F90C6A40D123
+:106440007A67CA5D21886D4CCD637CE3F4B3F5D4E3
+:10645000353C8C7E98A1BFBD1C1F5EAD1CF5B3679B
+:10646000A2D9DE31D601272BA2F436DB51CE94A679
+:106470004FC582BE7E9A539B761AE569A4B93F2325
+:10648000DED16EE3F18B6BC9B5683759E212FDE1DD
+:10649000CD6BF87113D9BCDCD34918FCE6F48951F3
+:1064A000C49BD7CFF066D89B1E3EBF9B4A2304FCFB
+:1064B000BE9EF8F3CD0C6FEBAF8BA27FB77EEC29BD
+:1064C000B467BD851D263FCEF81ECAA1FEFCC4766A
+:1064D000A8A1F618CB1B71238AA7E91969BDEB6146
+:1064E0002BB7DBAD7453279262D0634747A7158360
+:1064F000DEBEB784C24EAB3C7A589762F0ADF27EF6
+:10650000D47C86DF7BCBD87C697BF4D3EF9D9893DA
+:1065100004E366F2F8B0117FEEF1CBEBCD784F28B3
+:10652000B4C4852D7EB7EA67F4524BCCE5AB395F36
+:106530002B22A7572A19CEE835303E4F32F8BC84BB
+:10654000F17932DF37482FD10E011D924A99FF4D64
+:106550002C7EF34D291D8C5E378FC8003FFCFEA9B1
+:10656000DD3E669730BA26717EBCEFC61102C87157
+:10657000728926407D723EC35332C513AC77C9A5DC
+:10658000CCEFF64ED4B05D5209A35B0B7C4CE15FBF
+:1065900003748A891F3B4B5B75A07F6BF14E1D74A2
+:1065A0005932C5E1200ACFD4520A1BD89DB45F806E
+:1065B000D75318C5B85A524970D8A5FC7A42A2825E
+:1065C000CD87F8106C684BE93C25587E6862B22094
+:1065D000D07EEFA77CC0F180713C178FA3DF5F787E
+:1065E00012F5DCFDF04D36C8A9F6EB1C9A27A5364E
+:1065F0003FF807F797E608F1E2E7C6BCFB83CB2A32
+:10660000C712F83531FC7295C8E3DE16FE5D4722ED
+:106610006A2EC857486FF7A5F5EA0F83FF7AE4653D
+:1066200012E3CBFEF489A187DD2418B265F7D51FEC
+:1066300092CEF8DE9E174079EB03EF24C6AF528A64
+:10664000B9FC3691DB7F865ED19207142727A10023
+:10665000AE7722D74F4FDA020BC554F0BBC3B84E0A
+:10666000B8C874AE37199FCA9CFFA6E633BDE24A8C
+:1066700089B076978DA73A90DFD634A8A81F5AC65E
+:10668000DED59E43F1B06678931FBE738C6B19B94B
+:106690008DF6DB3C7C79702B0CC0FD30D4BF22AC76
+:1066A000838C5F8D7D30030E9219D2619FCC097E61
+:1066B00011E06724DB5F902412B58FEB1DDF954757
+:1066C000E1CD6769289FC10DFEC9EBB6E02A9C6F3A
+:1066D0007E6B94A29BCE9BC9CB6A21425C22CCEB01
+:1066E000727C1EB231BE8E9FF6F75D02ECD3C4E120
+:1066F000DFDD22DBA7592D478850087E1BED89F28C
+:10670000C9EA6C6A97C781A391F36BD52E67F8C36A
+:10671000187EAB892499F275FB33C21FC6FA117734
+:106720000AB84F51CDD158433AB200CFEF291AF6EB
+:10673000576BEB48837C17E94E5B027810038F8B15
+:1067400074FD7752BEC4B8907B60EBD6E5F0A781AC
+:106750000CD18540CBE4A90F79988E17DC07E3694B
+:106760002A2BBFD271E3F0F50BB17C4DC457596AA7
+:10677000E56B7F14F9DA9D12C57AB79FF1B5C18F29
+:10678000899C1FAD7C688CBF9EC7AFD6723E5F33BD
+:10679000A1498570DFDA519B309EE62CDA5C017CE2
+:1067A000DE32AA250C7CDE64F035DF17A1FE2EDB7D
+:1067B0001FD35AA3B04E2672BE56D4EE06907BEB82
+:1067C0007C5D9338BC3405BE06B8395FBF07F893CB
+:1067D000FDDD08AEC1D76B07CCD7BA456F9BD3FEA2
+:1067E000FC27D9C2D71E89F1E767C0D7004F0AB38B
+:1067F00063DC3E96CA7EEADFC7E9E70689F9996B52
+:10680000B91CACE572B0B61F39F83F22F303FE9A0B
+:1068100072308BC98143A2E58993AE8C1F25B0D31A
+:10682000E3C87B9E24FCB5E1DE3443BC723CFE270A
+:1068300030CD84BEF434D2CF44E7C0E43B8FC9737B
+:106840007F72BE76687C38FE5364F4A7F82E9226D9
+:106850005C39BEFF5A7015727E36F04382C528B788
+:10686000317A663AC02BA9869E7904D3A979AD28DE
+:10687000A786BE81580AFA2B6A2BC63B9C99AD6845
+:106880009F39F398BE31FC24EB7C8DB87813D73355
+:1068900049792102EB9F3D85703FAA9EF95199CC21
+:1068A0001F30E2D586FDA8187ED4D0BB709FA77993
+:1068B000783DDA97CD37D63BE2EDC336FBEE77F085
+:1068C0004D5FD33EEB1A5A0EFDAEC9BB9FC4B3C396
+:1068D0008C7918FB464E3E6E731EB5A8605CDF32A5
+:1068E000FCDE6AC73467B2FE7ABEE77A57EED1BBE8
+:1068F0002C8F76546E8C9F6FE9C7E00385E843A325
+:10690000103718E41E09E74C9A84043FD8C74D920B
+:10691000209D72901E7BA95A891640FF2766BC9C59
+:1069200085F6B23DB806E4BCE9AB8003E2A9AB53FF
+:106930005EF3C6969F9DF1E6B7C16CA5DFD5E27EFA
+:106940008E8348B1FB6327DCDBD17E4BC837C7E9B8
+:106950009C14AE0902C413CCE50A8FBF2899E672D5
+:1069600099C75FA4144B39E70FB934BE5E7993EB36
+:1069700015DF02764EE7C41C16D73B712B4F6730EC
+:10698000FE3EC7DB75F334C2F5EE5F531F25E5F617
+:10699000C2EF9BE2C7F822996547BB3E2B859D2B32
+:1069A00020B1E726E05F6BA24462FCCCA18197FF97
+:1069B00008F1D4610BBECA063C6B15EA615846DB90
+:1069C000A56C9CC76342F72818CFE63A8BFBF5020B
+:1069D00045E3726A120BF4DBDB2185EFBDC0523A4E
+:1069E0008F7B0591BFECC03722D0298CA98B44B195
+:1069F000DE433A309F081BE6B9E08751BF4BC433F2
+:106A00004C611BC68D7ECCF643D688786E83A80376
+:106A1000B4BFC9ED2AF89742887EE71AF877BE40DE
+:106A20006B31C8C4E0B208C693ADED7C53D839A031
+:106A30003E7AFBAF4FDF375273818F542C37E81CFF
+:106A400014F54E6942DFF25F8981F312C6AB58DC60
+:106A5000CD5A5F2AE91740DEACE5C20B7F3A057ECE
+:106A6000F4AA6764F4A3A73C2347BF41F3355B0452
+:106A7000F4536D079DE80F773EC2F2518FA243FB9E
+:106A800073DB058C07D5D9DBEFBD01E28ACF880423
+:106A9000FD8D7019EE8B9DE27326FB59BE9C07801D
+:106AA0006AB61C9A0BDF57ECB713D877A8796EF14A
+:106AB000B76FA0F9C5C764F4516A76AC50607F65C2
+:106AC00049588840BE6B32C1F143FBC4F00EDABEB8
+:106AD000CBDB9E36C70DFB2B0EA25D45E1F6B4A7BE
+:106AE000CDA6F4A90C3F350DBEABDC2DF8C1FF9847
+:106AF000F2CC8EA319F4BB9A27043CA750B5CB4522
+:106B0000B418BA9C6A13A3DF80F8339D27F8C58BAD
+:106B100049EB34C07BCD8E0D8A1613B73CD330922F
+:106B200068F6DE7CCD13741CFA5DED93821FA658C7
+:106B30006B2341E08FCEE79C65DBDC30BF15CA08D4
+:106B40000FCCAB5981768BC3F3F6C17E7A65788B17
+:106B5000328DD6573EB245298FE1A7AA5DD7102DB9
+:106B6000863F4E6DCE4DBFD47A7B86AE5BB1F0547E
+:106B700012A6B788145666C4EC7B76C8499C3F457C
+:106B800053FF06DF875E2718C70A3DEF41BC1A7422
+:106B90005BA632BD60D0EDBCCAE9287517CD88B3BD
+:106BA000AF7A2FD0C10EF12A15D3FB1B7C986E6CE7
+:106BB000D0903E9B007F57E1BE06967B279162886E
+:106BC0008B7875A2C2529F3C5D2F96214E1260F9C0
+:106BD000B4DB83827689F91BE92639380F825CB7EA
+:106BE000C94F4C96E8BABE49092E257E3ABEB47705
+:106BF00072C97560A705E7C8A9B09F1DAC60F1E830
+:106C0000880FE4A289EFCB7C4B66F2D694A1607C1E
+:106C100064D3F78BB6A1ED41185E367DBF7C27ECBF
+:106C2000ABD17EE6CA54AE1A65DA4FEEE5FB499B5E
+:106C30003BD1D44FDADC0AA39FC5D88F7360FD6CBB
+:106C40009A7BBD199EB995463FF5D88F6760F34A88
+:106C5000BB6392199E3BAAB19FF4DBFD681F8806B7
+:106C6000FF9076DC1775EF4E1AB796C4F2D1E41F89
+:106C7000C3781E2A55B17C943831C1244F497AB269
+:106C8000293FA874B0A97D6A20C7549F5E76B58558
+:106C90002FDDA8BF314F818A26B138AB325841BDB4
+:106CA000533CD881F9BB06BB51EFDC757DF02AB0AF
+:106CB000F70056D0F37729C1316A1CBEA1F3120840
+:106CC000C6CF341BA47DEC32BEEF3979C85723DE22
+:106CD000A7DFD7D9BA4724D1FC434AF12330EFAD1F
+:106CE00032B3E38D3843829DA0FE6BCE2EDA168A36
+:106CF000C16BCB50CA2F426FBF2D72D007FCB87347
+:106D0000F56F574A14BEA6A10A1E6E7A5CFEEDE12D
+:106D100010B5999B8796FB00FF7685EA8FD8F11511
+:106D20003A7E3E8EBF1BC6DF2B333BD93ABE3D6752
+:106D3000A2697C475685697C8742C7A7F2B16FF587
+:106D40003B7C7C8ABFEB0979567E07C7B76755E065
+:106D5000F8CD0AA9308D9FD033FE01909FC3FDCDA1
+:106D60003FE77AF3FCB32ACDF357D8FC8FAEFE8011
+:106D70008F9F80F37F59FE80CD3FAB92CDDFCEFA5F
+:106D8000ED19DFDB83FF5761FEAFF537FFDC49E626
+:106D9000F90FAB36CFDFCEC67F63F5277C7C378E0D
+:106DA000FFA6FC099BFFB06A1C5FB107FDC047CA84
+:106DB00090847AF09FA961A461405DA3E3403A9278
+:106DC000C5A937C83908C75D098CEF3E4FA0FCE65E
+:106DD000EED5A7244C2590EACB5ACED355BB8B15C4
+:106DE000E62F84D05F58C4415DB85FC4F58C6CB4A5
+:106DF000878753783BF78B21C82FDC78239E5BACC9
+:106E0000B313DC77A75630FA1FFFF1C0E8ADB1F33A
+:106E1000B2A68B5A65CBFE1383C738EF5424ABA6BA
+:106E2000FC2988A7503D7C12FC1F9A9E96E978B4F5
+:106E3000FC43F083AE8A951B762E8C7677229FCE0C
+:106E4000EBBB1CFE5312C3F7A93B05DC47F87CC320
+:106E50005205F4D9A25697C96FA8E374EA7ECE8E84
+:106E6000FB8DC679BE5B501409F9FDC16F1D05BBD2
+:106E700071F1E641A6EF6E27E1D5701473C1FA797E
+:106E800043553AFFDBCAECE3448C6BEB43581C9C44
+:106E90000C81B84959DB067908CDDC52269BECF908
+:106EA0005B83E6FC6D15E67CA71C966D60CF2C110C
+:106EB000C816DAEFF7EB65CBB900368E5749E676A0
+:106EC000251BEFBB948619B4E8FB908E836215E90D
+:106ED0003A5765DF1AF0D4DD2D9328AEC71DA9B847
+:106EE0000F144A45BF2DA8B2795BE19D2B3BF400FE
+:106EF0008567EE8F44C4A715FE8E832EDD46EDF325
+:106F00008ECD7F90217E6C9D8F15FE3B965BE7A317
+:106F10002AB03ECC0B59CB199F58F9A96E7FF13698
+:106F2000B33D7BF3B658FBB56AD70C537E49F85690
+:106F300053FBC59BE799EA17B52E31D52F68596ADF
+:106F4000CACF0BFDC8D4FE8EE52B4CF5DFAF5F63D7
+:106F5000AABFAD6283297F6BF02153FB5BCAB69851
+:106F6000EA6D07477D07E468D5EB229EFDBDE03E54
+:106F7000752FD89B17DC12EE737E44ED159083338A
+:106F8000D45E81B473FF78F4A7A91E2C874DA2F9B3
+:106F9000CA98552D99A09709EACF7265C2AAD02444
+:106FA0008A17B0D7A97C889B15121D04CE4C720F8E
+:106FB0001F778B31F51D97A9DF4C057D7CDF7AB1FA
+:106FC000237E79DDD679C3D4387E6AAFDC9221B0D6
+:106FD000CE7559CE9F1869B5E53CA7B1BF7D81EB51
+:106FE000D96A85E983EABD1993617386FAE523E2DC
+:106FF0009D9BECF93E22B00D48B0FE53811F869850
+:10700000F66BAA76E59AE4FBEC2111E1AA059D4016
+:10701000F5EA1752608D0272163D92356B34C0A1AD
+:10702000AF5540EFEC4FC575FD6C43E936D8AF3F27
+:10703000D310C0F4A386324C4F350431FDB0A10209
+:10704000D3930DF59876342CC7F4BD8610A6EF3691
+:10705000B460FABB86564CDF6AD88CE91B0D614CD4
+:107060003B1B744C0D79E8D1BF016E0F1B1BD784FD
+:10707000DBC37C2E8DA93DE7C270FFF7BCFBF3118B
+:1070800060EF9F7FCB8EFB6CFDE1CBCA6FFDD351D0
+:10709000477BA53C3C089D636BBD3381D1C9692307
+:1070A000A5641CECFFECF4CFCFC7BCC42EF584FD67
+:1070B000333C71FA85785DFAE5E944F4EE829994FF
+:1070C0001EA71EFEAF22E8F702AC7F60071C1171FD
+:1070D0001D26D16D7EA0D795E24D78E1F759102F8E
+:1070E0003BD783BFF62C888B5DABA8D8FFF9363B26
+:1070F00081F8D2F9032EBCCF75FED8362FC8E33203
+:107100009F188E3D47614D6B22D961B7C9EF36E7B5
+:10711000CFB70AA5781E9A6889B347035FA961387B
+:107120000FD2D9E0C3D4E867994FC171CEECCA65DC
+:1071300071337E5E83EC4E427EA57E27B6FF9F862E
+:10714000A7BF7E0C780869231F38085E71BB98DBE7
+:107150007FFB7EF949FA4C81F82A39207F0EF682AE
+:107160009DFE77111C652261DEE8B72E2286EC6356
+:10717000A07CB7693CFA9D66F8F417732EC5B7E694
+:10718000FB34220468BF469CA40AFE80F330F5025B
+:10719000C6AB8C784997E46E11C6F4C64BEA78BC4E
+:1071A000B8C6D1A10469D1B9B6DC4BEE9F9E69384F
+:1071B000A6C239AF0A47AB02CE4F45645409E8B9BD
+:1071C000736DABD2C01EAC12CFDF152F7E9B6767ED
+:1071D00071BD2561B9DBBC8E72FE20B45FA39C1D1E
+:1071E00072749F8AC99FB5313BDBDAEF04FBC0F6AE
+:1071F0002D6A771F9F7683D6174FB5FB3F55303EDC
+:107200002E11535CC9C0DF7B4A60829DE2A972D710
+:10721000FB688F7E248746DC7D09FDD4777E6E9FD8
+:10722000E97C7288B4C338F327F2818876CB3B744B
+:107230003DFDF815999DDBE4E7807BF695F9BEFEF0
+:10724000029E9BDF5685E7843EDEF78F68FF2D2484
+:10725000012FD281B416811D798ED84A014FE7C81B
+:107260006BDEF13174B8953A4A40EF052D663B86E6
+:10727000DABFA6FCE2CDE67C39999906FAA47CA394
+:107280004CC202CECF547FB35DC57E1793FA265809
+:107290005725EE8FCC57893484EAD59A677F5634C8
+:1072A0008FC211B4333FC888BF2C49667660654AE7
+:1072B00058817DC20FDAC67FF70620833DDC04715A
+:1072C000289248FC3B485FFC5E29FC56788DF5BA55
+:1072D0004F1C88C321EE12E2EE03D6DA056ECF868C
+:1072E000303DC0E76DF805C72CF915767EDE5224D7
+:1072F00022D0FD9CEA08D912B1DE1F8578DC5EBB86
+:107300007F950671FCC06A7B6A6FDCDF6897640F4B
+:1073100062F959E1D5723CF720450BF0DE218FEF81
+:107320002B9C1FC4046F019C23F540DC1ECE753AD4
+:10733000BD5B21DFE4A9C0F31F7520EFB4BF7BBCA8
+:10734000D38E419CDA415AA33AE55FBBCFB21FA06E
+:1073500099F32E904BD0675080E7A209C6B95C2301
+:10736000CDED3C7E73FE312E8F7481433EEE39DFCE
+:10737000E67047E13C0999289DEDF1B772C0DF63E3
+:10738000F0C3FD56687FA7CADAD7F27DDD3BDF9EEA
+:107390009C9E7C097D54F7A540C231EB489DD4AD3D
+:1073A000001FD67D2961F9D7D69B1A5D5563F4E697
+:1073B0002B4AF059FB04A627013E818E13BBDF64E4
+:1073C000BD877002F861422F3F7C6D385288497F3B
+:1073D000BFA7048FC583E36BF7EFEBD3FF09E0BBD7
+:1073E000FFB1FEF3FAF4DF110FFE9A67F7EC0BD151
+:1073F000F5B5F2170F78E110D3C7526B1A9CEFACBA
+:10740000DEB1DA0B72F99114F2025D3F0E8B71EF6F
+:10741000E7A63B0CBED3DD708FB096F3DD999FAF2E
+:10742000FB36F82F9FEF90558C0FECB247ED942967
+:107430006BDB9630F9D8657F9FE59BF1BC53DD7E11
+:10744000B3BEA87CFC81340D0F5585B8FF1C45FFE9
+:10745000A076FB7F4C03BBAB8E74A3DEB37E07E349
+:107460007F998CF6C03C25B16FBD710EAB8EE3A544
+:10747000AE6D1DDE13AF6BBBF934139A0EF43BAD4A
+:10748000DF5570BBDFE1309FDF34F042C2CCEE5FEE
+:10749000F5C48305EF53B8CE6E7FC52BE4C7F22940
+:1074A000D37FE7230B1EFBA5D6BF5C7552FD186B7F
+:1074B0005F1BEBB4B69FFB2B07585A2D47BDE00F5F
+:1074C000566F91F1BC7BF59E6D3B1F86F8CCDB7649
+:1074D000FF70DA7FD59E97DEB89EE6AB9E9253A6EC
+:1074E000B369B8E19EA2419F3AFADFF271BDF4A8F8
+:1074F0007CFA25451BCDCA7F9CDC4B97AAA70E2999
+:1075000064745F7C4C891C52D87EB6853E91F7A787
+:10751000815FB1EA892F14D05F1F1F14487A761C4F
+:107520007C6E7909ED63C013D293D3AB877E96F658
+:1075300075942EA8172DF4B2B6FB98AF07D02FC4C0
+:10754000E3297F3FF94BD8B7F99DDD0F78A878F292
+:107550009FBC309FD3523DE3F39FAD4E83FB20157C
+:1075600072284DC59495573CFA03E4BFC5C77F9078
+:10757000C6CEC5EA19FC5C5706CC73D12373709E46
+:10758000E524887C58F13376CFFC82444A9F8A23D5
+:1075900027F739D83A767AAB1D37114FC34202FB31
+:1075A00018AF89E11D180F64E70D7F60EC3F91650E
+:1075B00098BFE060F45AE430EEF1D1A524967FB78D
+:1075C00037B7039DCE0CD5D3218E5C47A410C78757
+:1075D0007091F62B1E9F9ACECF1D685211FF8EEA36
+:1075E000FF29500EEDDB65DD5960FA8E5CCCEE1D97
+:1075F000FF4E3E3E853B01ECD7D369D41E8C33BF92
+:10760000030E639DA676560C9FC5C83B93FFED6B9A
+:1076100098BC1BF21F9E510AF59F9D607204DF818A
+:10762000FD42E18AA663FDA1D902EA073B89C69320
+:10763000F3ED32977373BD955F28FC12ACC73D7CA8
+:1076400003E324231DD0BE2DDF48BF8FD5AB30AE62
+:10765000B76FBF861C2FE6FA60AD451F90475207F3
+:10766000B47F5B2D87773E0CF24BE535A481FCCAD5
+:10767000F85EC127BB8FBCF13D2AB79F440CB935DA
+:10768000EB55ABDC56EC9D40E2C9ED276E3F892BF4
+:10769000B7B43CAEDCBA3B909FFFD67AD5C0E3D3FB
+:1076A000163C1A7AB23F7C5AF5E4B71D5A5C3D4944
+:1076B000FF9D20457DF9D1E04383FF2AFFA506CF3A
+:1076C0000BF5F0A9C1873D7C6AF0619F78A4098F12
+:1076D000D6FABBE16F3A85C07332C6CFAB0FB0FDAF
+:1076E00067FADDD12185882F1D9739D27A74484AEF
+:1076F0006C3E6CC9472CED754B3E60691FB4E4EBE2
+:107700004DEDABF71F51D8B99EA8A99DB8FCA7E4D1
+:107710008338F101631DAA6BFB5409017FB8BBF1EB
+:107720007B79250979205EFEBC88F1F22E8AE3265A
+:107730003A4ED7EE6C7C8F60B593C557BAD46E2F96
+:10774000D893AB9358BE3B5569023D6894773B593B
+:10775000DCAF2BD0ED4D8AB1EFDE3F20A21EEF084B
+:1077600093D2787E28DE40A1F8ED20FDD5B3FD80D0
+:107770002EB0D761BC84AC30F0E354D19DB51CE28F
+:1077800035AD22DE6B5BB8E2162F9C23E93A90FB05
+:107790009D325ABEE8D722DBA60CE952468C1FF870
+:1077A00011096D9A24C0FEF57AE49F0507985FB829
+:1077B000707D7C79A8E4DF95BBEF5440EF527FEEFB
+:1077C00064ECBE87D14FC52396F203FFC8E5A6152A
+:1077D000E31F95DBCDF5411E3F18ECE4E7BEC792F1
+:1077E000B1DC7FB7C5DE0F9E2AE67FA78CD2A7EB60
+:1077F0009848E03CC1F90322D2E7FC6E767E00E3B4
+:10780000FCD701BF772BB1E7A9CE827C5DD5BF1E27
+:107810003BFBCCEF8BEE063EDAF74EC14F697A7632
+:10782000DFDB237E05F967DFCC7A87F46D3FE5A0C7
+:1078300013F755BA0E7A90FFBB9EFF4DD6DD907FB1
+:10784000CE8EF1ECAE835F14003F75ADB457801E51
+:10785000ECE2E7EF563DFF454107AEBF8D48C7A9B3
+:107860004EE64F9F3FF05FEFC1FD81F307E8ACC0EC
+:10787000BE38E842F9AAFBA513E36F5DCF7F511430
+:10788000EB27FCA5F3A9E5FB9D5D1E52B617E04B67
+:1078900062FB4475BFBA6E1BBC2F51D3764859406A
+:1078A000EBA7BCF0A702D0AF5D7B99DDD429773C74
+:1078B0000AFB7981350F34CA945E9D20648369FF89
+:1078C0006BDE280139EA8B973F615C71A0F858FCA8
+:1078D0007F0D3E049DE93F4F184C852907FFF8DED8
+:1078E0003BA0270EDA912F8DF97E125981F6CCE557
+:1078F000E6DDF4FFDCBC85E840E6BD03E63DE1EFF4
+:1079000077DED7C0A1A1D4BE72D097CF9FBF0BF3B3
+:107910007B3C7E847780FCFED2DFF9FCAF98EE7B67
+:1079200029DDBD979FF7877FE7F3EE9FEEBF9ECBE4
+:10793000E9AEC27998BA17FE84F05DA99E9312FE53
+:10794000BEE5BDBFF91BF6FE5A9BBF35271BCF9383
+:107950003AC0B0707B66B6407871EDC8992AD89D60
+:10796000623FEFD54C48607E9528B0F721C850168D
+:107970000F24DCCF82630DF80E889BDD3B93DC4D3A
+:10798000687713C9DFAE53BCACBD7ABE1FCF1A9166
+:10799000716F05219F39C98FF16E8BBFD928105D9A
+:1079A000A0F6AE74F5378F81DF238FB445ED0598CF
+:1079B000BE0F69338F63CAAA62F287DCF9E6BC5353
+:1079C00033E7EDBC3F0761F03B7C240CF16C71D4D4
+:1079D0006115CED3896325024FA538496B08FC0E8B
+:1079E000BBCFFC7D5202E17EEF5F86C78A0416A7FB
+:1079F000128571ED3AE071940DE3DC78481BF1E2F9
+:107A0000C7F7BA08F7AF7BF1DAD40EF894C03F6637
+:107A1000F617FAD584FBD312EF421A69D39DE676A6
+:107A2000DC8FBE2C9D185DB2AA399D9699E862D074
+:107A3000210E7D4C7431F07CA5F4B1D2C58AFFEBE8
+:107A400013185FF7472F832E996E1DEFD7C9DC7F80
+:107A500028013F13F2990182FBABDC7F905274BC8A
+:107A6000A724AA7EBC97007E5C941AE02FEFDE86E6
+:107A7000F1A4733F7FFFDB004FD5AF44E2A0F8EBEA
+:107A8000DCED2151F85E0A2BE09F56B689B84F40D5
+:107A9000A468D1AC987D62C30FA8FA8507E753B9F3
+:107AA000D71E9E4EBFAFDCF74101DA612BBBD1CFB1
+:107AB00009FD5C60740F7514C03E70A5C4FC112BE9
+:107AC000BFAC4960F196B3CFB9CA20AE23EC62E7F0
+:107AD0007F2B23B7C8F698734DA10499C59B9E735D
+:107AE000A15E083D21E0F928802FF6DCA9E1879C02
+:107AF0007D4260F0ED97F19D98CA5D4F75427CAA7A
+:107B0000F22DBB1FCCF8BA5D9FE27EC8945FECF10A
+:107B100076A01F2E9AE2127DE201BB44E48FDAB612
+:107B20001AF443681EF9A236C2FDEF2BF457AB7E60
+:107B3000F1FC3EB87056F5F4E35E887F9D69DFE1A5
+:107B4000C5B8C0AE4BC7E7FAF8FF9135DCFFFFD6EA
+:107B500069764F3BBEFF7F06FEA076F1D30996FB08
+:107B6000ABBB06B1F71449B4E852EF7155EDB9F06B
+:107B700028C4AFCFEEFDE45180BBFACF7F7814FC70
+:107B80000A72D0A9C27D82BA9FBF8EF13EE3BBDFED
+:107B9000703DD0F9C4E3182FED7C9BFA1FF45FE72A
+:107BA000F3A7B3C0CFEC7CEA8F69104FB9F3F9A902
+:107BB000F86ECE9DCF4C492771F4899102FF86075C
+:107BC00010AFB5D2ED48DB11F47FCE51BA83FFD9A7
+:107BD00013D789D4B07899C6E339BBE3C7C7FBC4D0
+:107BE0006FDA667DE7C6424865BF460610C7394171
+:107BF000E939660074DCCDE375916F5D328E730EEA
+:107C0000FEA0F43A6BA1E385B6458F3D0C756D83FC
+:107C1000FA8DE34407803F23FEBE3F41FF2201E48B
+:107C200068EFBF60FC0CE8379D4EB873CF852CD849
+:107C3000BFF848EE9E8BEF853C6F57211E51F9FC33
+:107C40009B284F9DCF1CC7F836E171F04ED2F38FC1
+:107C5000C52BF999CCBAED1E16FFE17480F890E6B9
+:107C6000C5721E07627C6DC487FA8B0B8D71B17370
+:107C700027C6BE40CDF67778BCA5976EC244A0D784
+:107C8000FB97DCCF30F0A0021EAE8D8D7BC68FC37C
+:107C9000F5C43D2D74037A42BCB327AE49D8137B9B
+:107CA0007561E1CD7871F4CE2D2C5EDA29C73F8F56
+:107CB00065C441AF7659E29FE181C53F2F378F2BD5
+:107CC000C5D3609786FD5AF175F6ABF8FAFD5BAE49
+:107CD000819D5FE8777FADDA7C1FE63D2538DD05C5
+:107CE000FB6B6DEF2B04CFA774B3732B7CBE67F9CE
+:107CF000F9D3B33F17312ED6143982FADDAA3F8C5F
+:107D0000FD572BBC7770786BF7B3F5E3EC5E4FD87B
+:107D10004DFB397BF839E4EBDADDEF635CEEE8AE7E
+:107D2000A7958E98F516D68F70CC7CCE3E79A8801C
+:107D3000C579E3DF1BAB71317BB3EE40FC71EA76B2
+:107D40007F6A1AA72A1451981D70E9F1CE48FA2DBE
+:107D5000D0DF997619DF4D3A1311E3BE171C70C9B5
+:107D60007C1FA195C90F5D47F19EC071767FA7F07A
+:107D7000B5043C577FE7F1D277E0FDB73BA95883C4
+:107D8000DDDFB682F169DB4FF42140EFB6E3DF13AC
+:107D900061FDDA07F88DB1FF8B4ED44FF150FD50E5
+:107DA000F46EA010D8D5AA77AE7DCB66829F8E9355
+:107DB0000EEB4223ED07EE83C0B939BC57EE9D565A
+:107DC0000AF088AA4D750A7DE721BBF97D55DEAF23
+:107DD000AC9AEF2190AFC66BD08F6F268B4B66CCE1
+:107DE0003252169F0C19F787CA13C2ABE87C7FAFDB
+:107DF0000637BB285E7C9E8DD92F1178276AA20694
+:107E0000F6D3632E7EDEC14BBCECBC833B64A37A0D
+:107E1000FD61FFF60D93089E67D8067CD9739E819D
+:107E2000440B802F8D767DEA2DE71D32E1132A5A0F
+:107E300022873317EE2550FDB26A86772BE41FF1B7
+:107E4000B0F7CDB248F72138DFB08DDBA3D960158C
+:107E5000E7F67DE7ECEBBE6F9632A578E9303F851B
+:107E6000D3F55F53E15C7CCA2DC54F0D5169852D5B
+:107E7000631ADCA34979BC786C06CDCF5FFFF4347C
+:107E8000ACFFF7E2B15934FF937B0EB2FA2A01CF6F
+:107E9000C1BEB0AE761AF0EFD796FBD9143366B9EF
+:107EA0007F05F0772EF0EE77176970AEA25BE1EFF9
+:107EB0006504A0DDD0890C7F99EE779F027F6598DD
+:107EC000AD6305F0EB63CF7F9184F716F9FBA12A30
+:107ED0006954E1DC152D9A78F112E7F3FABCFBCC7A
+:107EE000F5CB8D49C177813F9AE78DBC6F1A1DEFA5
+:107EF000E18A710E760ED0F24EA39A82745DC8E9C3
+:107F00004AF83DCB457C3E8BC590C202DFAD5C7F1D
+:107F100019EF51578B57F41E3587ABDBD5EFFB6755
+:107F20007F00783393827F00FC59DF3F7BC515B813
+:107F300000F519E55FE27D5CE33D33EBBB6844EAA5
+:107F40008EFB3EFB56FE2E5A7FF0FE9B3B28BA6905
+:107F5000FF392F687B8F51391BB350F1C3D1CF311B
+:107F6000CB0BFDD220C226047610A71F3CCF88F78A
+:107F70001FEE22B85FDB651774F0AFBBFE49457D8D
+:107F80009EB9703AFA5F5DAEEC089C33EABA5BC307
+:107F90007D3D8A0101E469E881C428F887541E3ECA
+:107FA000B7C8C3E766FE378FDB7551DBDF81FDA9FC
+:107FB000BC3F6AA0C5DC8BED12999EEE6AD0108E94
+:107FC000A1247408D6FD818E97E3E6EB37A7CF4650
+:107FD0009B9EEB9E80F81FEE8EC1FF2877BF74CC6E
+:107FE00077333AE6BBE3D0D1FA6EDD7BAEE058687A
+:107FF00077BAFC28BE5F677DAFCE4ADF3AA9F5218C
+:10800000783B2BEDC0A7B8FE18F41BB37C2CD2290B
+:10801000869E93008E31073EB501BC061D1FECE71E
+:108020003C79A99BAD73D6F1D2CA3A0607E3B49F57
+:10803000E5D64CF70E0A1C457E89CA69BA8DC587FC
+:10804000FAB6EFB7FF9C4B9DF32C5059BF14FF734A
+:10805000004F06FE6F75F3FBEA7DF17F3BB4A3F89A
+:10806000BF1DE63F00FCCFBB14FE0DFBBF8AEB87B4
+:108070002AD89FA27CF41FDACCB41C3AEE34D18DFE
+:1080800072B06487C8F731D9FB5F863E59725DFDD7
+:1080900021B817B9E46702F2EB42FEFEE527FCFDCA
+:1080A0004BEBB9C1F2B210EACBCB9F1F0CA33EAA97
+:1080B000DA652EFF6777CFBB975978DE172435AD89
+:1080C000F7BD4E2BFECFBBB9DE58E8B4C57B2FD72A
+:1080D0004887D6DB4CE7CC33A6F4F483FEA0CFA6CA
+:1080E000BD89F1B87F9509C4137429A510DE192044
+:1080F000854209F45BCCE5D7E86FD872F3FA9F1D8F
+:1081000032DF43CC6D31DF431CDE6ABE8778D56633
+:10811000F33DC45161F33DC46B768D33E54747AE03
+:1081200037B51FB37FB2293F36FA4D53FBF1C7660F
+:108130009AF213DABF676A7FED5BF34DF5D775549A
+:108140009AEA6FF86899297F63F73F9BDA471731FE
+:10815000FD78B8617911DC5B30F07278A96253A1C7
+:108160007CE9089B5A105B9EA66B059016E9E07FA0
+:10817000F5272F531C3F2A8A5DA78B896CD26F533A
+:108180001CE67CD46DFE7D8F972C7235A47E52CB7D
+:10819000089A1DBC240FCF6353F93AC6F5DBB10131
+:1081A000EAB7DFA07CD5469B206F952FE3BD019AEF
+:1081B00086D88FADB0779F1F729AF9D4D78F5EF9AA
+:1081C0009DDB3807D4CAFA53CBC64B263931CA3F98
+:1081D0002A8C2D17164FC77340FDF5ABF8165CB30C
+:1081E0007D10BC3B3C0F53A3BCA9CC16F7DCDF676A
+:1081F000EEBFD07FDADCC78EFA0CF07CCEF7DA2641
+:1082000038BF567B7B37FA511976335E7AF3EC5DD3
+:1082100063039E471A483EACF7C6FDB64534E1EB12
+:1082200036CE77D1DB33D3E09C41663FFE55A18744
+:10823000E9EB471B42D72C04C21187E95E7956B49B
+:108240006E1AF839C3F879EB4DB6F8E7A0923C0CFA
+:108250002FE9A048C15E50DD682F9C2B7FD70B4FC4
+:10826000C7DC680F2679E838F3C7B417B1FBD4BA76
+:108270007FE6E85EB80D7D94E50E6C02FD92E59315
+:108280008896DD179EF4DB832DF08E7863B2CDEFF8
+:10829000C67CB700E3D97F4CC8203A5EE39F458493
+:1082A000AFF1F075783EC8EEAEC7B8AB314FC2CF74
+:1082B000091871E60BBED98980CFC6AB7BEE07E10A
+:1082C0007B9017DCC176E8F7C24619C76D9C2C98E5
+:1082D000EA8D794B9BBF8DF7BEB2DC6CDEE574DEB8
+:1082E00000B73D93C1D5F8A8403211AEFFBDF428C8
+:1082F000F835FB5CF8DE07C5C710C0C7393DFB7316
+:108300009B31793AAF9A41EEAD6BD19E89EFA74E82
+:1083100037E6A18F34D13BE32A33FCE24619FDC690
+:1083200045496E3CEF106E8872FA9AE7DFE49BF9DC
+:108330009D5B295CAB4E88F8DEB6D6D1BAF428FD39
+:10834000AEBCCDE50F6B7DF17F4E63F052F8A77B9D
+:1083500040DE364FC3F9E3796A80FF31813C9C0DE2
+:10836000FC172C453E186C23B06FD3C74EF0307904
+:108370009EED51D97B35BE722687BE85D76CA7FD91
+:108380009579FA5DF76FF3B075FF364F9C75FF7204
+:10839000EF075797B51F8554D445B43708A91F1167
+:1083A0006B47533D560EFD1B7931F1C705D06FFF6A
+:1083B000769ABF6544F6E5ED34B0CF800F0DFBEC47
+:1083C0004E8FD9AE8CD1BB3FF430BDFB43CFC0F450
+:1083D000EE8FA1FDE9EF45E3DA35A94A7CBDF7B49C
+:1083E00087DD1FAC531582E703FBD90FD8C9E5DA47
+:1083F0003AEFFED6A5CBF91F392E834FCDFAFEFCFE
+:10840000312D11F454CA0742DC77B7862CBF6D3C7E
+:10841000D06B9BAD7833CCF76716FE78684D9FF52F
+:108420002BCCF1188E8BC76A8A479B098F3B3C97F0
+:10843000B00FBFB6BEAF30DFF3E9E4F8A67ABF09EC
+:10844000C63B37EBBD22886BD4CEF91CF5FED71E98
+:10845000A7CCBCAE187E391D6705E0A173D69F7905
+:108460007CAE03E34AAB9EB92A11E25835930D7AEC
+:1084700044F07DAAF3F939489773FBEC3AC0792EA2
+:10848000999D133DB7EFDAA310F7F8A4E158722CC9
+:108490007DCF3D79BC48A6FD9DDB7BBC48C2037700
+:1084A00061D33BD435177F5B1470F7DE4BE8E137BF
+:1084B000075B8F363A597CE54138173786DABF6A51
+:1084C00012F2657A9AED5E28171DBF1DFC215C39FA
+:1084D0003FE62FA659B24AD03316C17ED33C37EEC1
+:1084E00067F972C9C86CFA9D12AD87E3CCC4F96A0A
+:1084F00098C0EF04B84E44F1F7023CEF7660F83EC6
+:10850000F143B2029EC2FFBD1A3C09784F3AAB0953
+:10851000891AC4778A6E1E4753690AD3BFDDB73AFA
+:10852000F0F78C8405AFAA53A8FEDA3C93FD8EDDEC
+:10853000F9630B92C01F695599DEF20DEBE163B44C
+:108540008B07E76B371723E6757C574055191D924B
+:10855000336C6B8A358CC7F9F398FE25521AFF3DB0
+:1085600029CAB71ECDA6431CD8F8CEC5BF2B52FCD6
+:10857000BFCE037846DBFCF04E8FFBAB6F38CA9260
+:1085800069FBCC28BE5F5E94C0E19DC3DE07EFFBB4
+:108590004EE345D37D18B5D4FC4EB727D0B414E2D2
+:1085A000FCD0EF6DC9F8CE8BB99EA2389196BB0B6B
+:1085B000CDE5AE0A9A8FE147EB77D6F6865F92AEAD
+:1085C0003238F63738100FBF6C50FD79948F0E3467
+:1085D000F8307FB041C334DA3012CB0F37F8312F87
+:1085E000DAF46C984FFAAF7F9014BBEEC2EF549D53
+:1085F0008CE1C37572E4ADF9808FDF8888AF15AF69
+:108600008E47FEDE349A8E3A86BD677332C6FEFE12
+:10861000E9F257D24A285F0DF9D1AFD34AC6C3EF6A
+:1086200096B0F31770413AF61EEE7A25A0F993E062
+:108630007734C6343B86C2FBA4C15BC9589423FD82
+:10864000C589F0BB0B7B336CB47E9A94D7ECF807EA
+:1086500080ABDE64E7AFE7E7331F9F6CD6AFE3BCC8
+:108660004CFF660AC5E3BC71F8097E5300FDAC39C6
+:10867000C6B907331E8954BFE1768AEBE6EFB3DF54
+:108680005F4854C7FBE1BDF7CD5EC3CEA9F7C5BEB9
+:10869000E7BE99FF0E44E2E1256817293EF63B103C
+:1086A000290A7B0F8904934DEFEDCDE5FDCC06063D
+:1086B0009AD0571FCFE6FD151D790EFB83DF9788F3
+:1086C000F5EF87F0DFC3D8CCF5D3743550EC4DED22
+:1086D0006D67D45BBFEB59776D21D10BF6430189F0
+:1086E00080BD04ED8A69BBD40F0302DCEF33CED723
+:1086F0003E0BF8CDEFFDDD937D02C3EB933C7D8A0D
+:10870000FF4E49D4139807E3FB163C12DA0376CAEE
+:108710003EBB06625274E48FF87E94F83BC501E7D5
+:10872000FC530FBCCFEEE5D93A1438BFB8D25B7C0E
+:1087300013C45145A53E03F3F74E6F81FC839EFAA7
+:1087400087D8A3DDC537011FA4F3F706080400018D
+:108750000E08AAE18F63FD43B34E65649FCCF22BF4
+:10876000BD37368732215F3F0FF808F28DB4BF7DE9
+:1087700049C121C0476EE186E6633742DE687F0368
+:10878000B6FF895765FE8F3B980DF64A4F5EA57977
+:108790004F4C5E6279E260A931BF9A237FC473D0E7
+:1087A000B507D83B5DA907660830CFD4FD3310FF6D
+:1087B000E7D5B7BC2B348C878F60EB048B971BF409
+:1087C00030EEE1A6D983F77963F8619DD76CC7C411
+:1087D000DC27BC0FF0DDD31F8FAFCB36F69E4AF7F8
+:1087E0008FD8EFC60D037B5484B8B986692EDCA3FD
+:1087F000A7FEC170125C3998D65FE3CD413A5EB5F1
+:108800003BFBCDA95A2F5FA7642977803E4EB5F870
+:1088100035D95C3F8F508B7F93482B370AC1B5F019
+:108820009E6C688FACE27D935D19284767B98E22F4
+:10883000F583315FCDEFBFCB2B836B47811E59C4CE
+:10884000F46E5576A058A6DF573D978DBF0B67F0A5
+:108850005D5552246D9CBBF75CB791377E47E42190
+:10886000B5D509EFF218FB5AB5FB3764C13EFDC719
+:1088700087DE463B71496236C259D3765C81DF6937
+:10888000A96DA37C47BFFBD8D963C7A35FF287C894
+:10889000A06F02BEFED068C3CBDDFDD9552F52FDBF
+:1088A000A6D385EA688303D39D7AFDD5E00A9CF0C0
+:1088B0002EB8C949F9E9F11C5D05FEEABCB71EF501
+:1088C000D8E38A3A0AF8AFD3FBC366E0E7AA24915B
+:1088D000F3EB0F5FD6F3F87E3DCDEFB9B7EDA6BF52
+:1088E00068DF60A1D9FEA97BC48DFC41ED92DF0257
+:1088F0001FD56EB68560FDB339DAF1BE7327E81B6C
+:10890000D45FE6FB991B05A60F4373581CFA72F758
+:10891000342BBE7491708CFDBD2491E9AB0A29847F
+:10892000FB76155F7AB1FE2F1FC769BA0FDA771C85
+:1089300037D61BE354F78E837C52FDF661F4CF5F8C
+:10894000BCDAB0AF75D4FF773EC5CF6138F574E8B7
+:10895000E741D9D027D4CFA47886E71E793E24F901
+:108960000879A947FFAC6D2EC904FAF6D613B37E79
+:10897000D2254AB79712783E747F73C9A438ED1395
+:108980002CED738CFC4FB17F2B3C0F3A7BF30EDA4E
+:108990005EFA93BD270FF06DB059FA4B36C6DF86ED
+:1089A000FD19FCB7C7BBFB6578EFE9A5A440F11042
+:1089B00066DF6820875B24157F87D1C0F31EBE3E2B
+:1089C000557C798D09FFBD782F30959F6ED04CFB7B
+:1089D000A18B172EC37B3F7BF83A564142EC3EDB1E
+:1089E00023B9A67DD0FF0FC7D785A3B81F384AFE8D
+:1089F000C6708C32E9815E38F24DE55F170E316941
+:108A0000766936EC53ADB1A19F90660B3972C06E9A
+:108A1000FB5FECF71A203407E799A8616CDA57CEB0
+:108A200039609F07C6798E448E49E3409E746D0578
+:108A3000AC533F91D0AFA1E50E3919866ED5E1FD5B
+:108A40002B2A95D85F4E75B08619F5E6776287AB0D
+:108A5000A458A2E5E3D579B8EEE594DD5507F6FD17
+:108A60003677E1CF571393BCA27DB25A588AF6C726
+:108A70009AC4179B61DF383D81D9330279B1F95827
+:108A800046BC7A26AF2DF7BD7813C431B6AED4AE4E
+:108A9000067F6EAB331C390CEBF93D6EFC3DAADC56
+:108AA00075E116F8BD0A71830DD74B3129BC6B2BCC
+:108AB0009C177860841FEC8BAD60D740FB356E5CF3
+:108AC000FF5B1A42682FAFE2EBC0F6F5935438E72C
+:108AD000DCE8969261BD6B91EB6F05B85EBAEF640E
+:108AE000B3E33AD063FE96413CEFCB80754DCB713A
+:108AF0008CE5F514195B576883C18534F2C3FF44D4
+:108B0000AD12D43327D10E6B742FAB043B8ED6BF7E
+:108B1000ECA0787A3C99E385D7E7F4E8A593CDA05B
+:108B200007C515BDF9123AEF1D3F637AEA09DA3F2E
+:108B3000BC2B45E713827718BB4749E8872524C13A
+:108B40006FC7D074740EFB9D5BAA17BDE8C7493888
+:108B50005F631F4919C57E0F1DDAC37A9390918315
+:108B6000FB98CA0CF65E83E271E3FD66E37756DD9F
+:108B7000C4F8A7B37829DF677159DE4370AE5F8907
+:108B80009BE94E783721864F15CB7B0B1209CC071A
+:108B90007B4B54CDE5BF49E4FB4A83D8EFAD0EB71C
+:108BA00085D02EA35284E935248AF6D968D281F97A
+:108BB00031E06DE6C2352C0D2F8E8D27BAC8E2BB91
+:108BC0000111ECC7B45B8D784CF0F544BADEBF966A
+:108BD000C8E336FC778C536614E27E7D6612AB5F89
+:108BE00015C8BB0FECBC8D33A6619CC6B0EF8CF5ED
+:108BF000D2B0DF16729857AB425C7BC1B0EB163A2D
+:108C0000593E75B6FEE068886BB6530B341BEE2FE9
+:108C1000B3F86AF9E6E234B0CB161EBA15EDE44CAF
+:108C200095D9658B36CE5082A3E1DEDA3CF4078A13
+:108C3000374C48847D84D54E7FE27585E867E2FB3A
+:108C4000B903B5C7B6A65D3519E471AB8D1290CAEC
+:108C5000FB4BB2EE1E0B7CB1210FEDCCAD09C1C6B2
+:108C600024DAEFD67FD6FCAB68FEA74EBDF0388C79
+:108C7000B33A81D5C3BB51C09B3DE712B6E1BBC936
+:108C8000FD8D6F3D97F052127B7FCAA8FF6F537E18
+:108C90007C7D0080000000001F8B080000000000A9
+:108CA00000FFBD7D0B7C94D595F8FD66BE796566A9
+:108CB00092C963F2220913C24B5E4E9E80224C126F
+:108CC000C243B44C102A20E8F03490A7485DDCBAC7
+:108CD000FF0C043050B60657112BEA8462C5AABBBC
+:108CE00041A31B35EA8080B8D66D44DAD216FD8FD9
+:108CF0004A1510488AB5D2FEDD65CF39F7DECC7C47
+:108D00009319F0B5FFB4FE3EEEF7DDE779DF73CEE1
+:108D1000BD73E912FC4D612C94A43056CAD8C151E0
+:108D20008CF58C618CA9DE2406CF4D066FD2E2341F
+:108D3000C6FA7EA367BBE1F517666F92C3C6D82556
+:108D4000D12EFA79AA99B1A089B1B3CD6E161CC102
+:108D5000D8996633956B961F98C6A09F9A0E85B9D1
+:108D6000F2195BC5DA36633FAF3B9269DC55013DD2
+:108D70000B8E64F47709FE5BBDFC28D55FDDC9EB83
+:108D8000D7B20EAABF92314F073C6BF75A59D01C8D
+:108D9000AE5FDF51AC691F4AD251BFD725FB063BFE
+:108DA0009C8CDD5B3DFCBE2A789F565D62F6E1FA45
+:108DB000588EE313ABA8AF87F73AE6EB88B1AE77EE
+:108DC000045CDE49828A4EACEDD0B132C6D63AE0C0
+:108DD0009F2EC61E50D87C6CB7F6F715192963C2B2
+:108DE000EDD62A9E0CC798F8706ABCA86781D48813
+:108DF000B2DA67C4F5355E34D2FBF30EB35F0763B6
+:108E00001EC9F43F702DAC7F26EB5319CC539F90B5
+:108E1000388E5DCD588B2571373E67BA0C7DA10821
+:108E200038303353717E33F82BF6EBC469479471B5
+:108E3000D83E40ED67D98EA90C4073C45E7303839E
+:108E4000F737B090CA0A06CE0FFAFD28B2DF5923D1
+:108E5000B5E51BDDDAF2EC09DA32637E82D74F9A90
+:108E60009BCA4E1AC2FDFE04A6D611032EB70258A5
+:108E7000B17EED5E4BE064041EEB3B9235E5C6AE81
+:108E8000ACC0C988716AF11F59F05F135F779D58B4
+:108E9000F70746DFAD0EC05B3D0B1971DD40C146E3
+:108EA000EF58C6AC16E6457C1DD86FF1B012E8CF7E
+:108EB000666EB7007C1BBBAB9525F0DE6A87EF3092
+:108EC0003F2796E16935F0FA8C05880EE08FDA3994
+:108ED000BD99ED5B15E413B7ABDAFECDE7DD00FF1E
+:108EE000DD93024F953DAC2446ACA30ED6911E5E99
+:108EF000C739EB0765882F58CF6FECA5481746A6F2
+:108F00002485D7F3ADE1B55C0BAFC65D36A237184B
+:108F1000E7BD4418A761A7CE6F84B2CEDC63447E60
+:108F2000B917E93C06DE721C4A4C3C6F433CC7E073
+:108F3000A7EDACFC3EE4C71CE41F18C7B6EE2765DE
+:108F4000278B818FAA3717FAA0BE4D05FE86715474
+:108F5000F8BFA908C8D93B6D5532D0E9293BE7C312
+:108F60000D892E7AEE50BC0AE2355DE7C947FAD585
+:108F700027B843CCC1F1A366421960CBAEC162F9F8
+:108F8000BD1EE8EF21981BCB168409F078C8C2CB30
+:108F90002F39CAEFDD08E36E4AE6E50D3FBDB9D5CE
+:108FA0003F09CA16599E43E5870C6D413DE0DDFF40
+:108FB00082C9F5443EB5F728585E3032F0044C4D76
+:108FC0003F8465235EA62642E720B7F42F9A769B5E
+:108FD000A05ED0EEFB2784A75CFF39FBF13C362670
+:108FE000667F7E4D7F79DFAC3F18BF537775F8FB06
+:108FF000D4C49D413D6FE7C2762CA7E7033FF49FA1
+:10900000FEA2896D85E22306769B17DAD55D2C6377
+:10901000C10839D423F079B6D941725BBEAF43F9A8
+:109020003D06F9A987E4707D47AA46FE4AB95C7FF0
+:10903000F15A4D7F398E7CC257BDDA43F2ADFEE264
+:1090400064FA1E12F2F46C7326E989F8E30CD2C8B4
+:10905000F5F0381359B0F872E34CA2EF721CE6CB6E
+:1090600022B9BD06E70C24A43782BC87712E0C758B
+:1090700025255F469FD976029145AC679B1A3463DC
+:10908000FFDBDC071CBE18FC20E544B8BD51DB1E2D
+:10909000F4231B81F4ED6348B7FFAC7ACC91FAD48A
+:1090A00066F038506FA8F68A232E37344D7E6486DA
+:1090B0000A286951393D7FD9B681E8D16E701F41C8
+:1090C000FCDAED3A971FBEAFB7E93C48272D0E7387
+:1090D00000F1BD51B9C1817243F66B07318FF3B80E
+:1090E000601B427A3DDE7AD58B89540F669219A9AE
+:1090F0001FFFF7C683C5170F1C8FBD31F1880BFA10
+:10910000574B746E0BE00B91FA71041D44F763DF4B
+:10911000A9C69C77743D09FFB8F836841211FEE7A2
+:109120006DBA198118F32E4D56BE9B9E5A1425DF39
+:10913000937F3B3C88ED95D00F0AF249FE9626A31B
+:10914000FC2DBC9058E922399FEEB573B185E3B68A
+:10915000D88E9A7DA48F98ED13D9BF3E3EFD49B8B5
+:1091600018DEAA64881F6004867AE34A70B02B4137
+:109170002FE29715AA0CE5D3403A6FA7F9F4D777F9
+:1091800043E711EB6F51DD0EA46BFD751E33CA99D9
+:10919000F58E39E6109437AAAED9F92087FADE02A7
+:1091A0007B12D6B729ADC81C8B8F5AC16EC4F92D5E
+:1091B0004DD669D6239F661DE7DFE8F75B92B99E1F
+:1091C00068DD3FB1C753129F7E40D279518F9BCB50
+:1091D00054C756589FDEC0E76B896307CA7EE3C158
+:1091E0006BCB7E0BC96975A83980F644F4789B5423
+:1091F000778F07BE6F82F9F8B19CC3C7DF54A23ADC
+:109200007643D71657023347D437384B08FE176CCE
+:10921000694C0FDF37213DC6989784D3BCE4EF68D3
+:109220003FF9A2E832F7B7C3D9100D5DB6C6A2CB9D
+:1092300079A8374BF9FC993972FE4393BE8E7C8C2A
+:10924000A69BB249CC837C9701CF76586FA7CA669C
+:10925000EC437D80B6D64498DFCD36E600993E39A2
+:10926000B57C6732ACB7ACE78091213F743A691D99
+:1092700075A27DF4B8A6148E3F538A839E49C73DDC
+:109280004F4F01F876F624B814F8D49902FA300654
+:109290007C8F08BC33D6C69F6A681CF28FAC5FB661
+:1092A000887976C3F350026B3583BDB24FC807C6C9
+:1092B000EEE74F151817C699FDCAE8DD642F8AF549
+:1092C0001F02B580F5D3D343E314FD77C0DB5E58AE
+:1092D0007D04DEEACD21C2DBDB46DF6B089FC6E3FF
+:1092E000A1742C771E3D9387F870B670FBB5EF25FF
+:1092F0006B00E96E207ED6D3FCEA2E0E62FEE28180
+:1093000078AB5383A45FEB2EE6D17758B7DF9C127E
+:10931000FE3E1B6C8609B02E66E67042F8C4C2475A
+:10932000BBE06B890F50EBA3ED021F08A78FC43E73
+:10933000A71FEF4EE36606783F6BE6EF996724DFE1
+:1093400087097DFE51425E00F7331F0D07CE467A36
+:10935000505DE9917AA7CEE2B96F3EAC9BBDAB6799
+:109360004FC06359A5AD15EDAB65264F12DA5DCB45
+:10937000DED32BEBF30984C4072B043CCF32F75D1B
+:10938000883FFF368BE309C29F76FF97BFA3BCF8E7
+:109390001D68BFA24BEF46937169A5CD8FFD96F571
+:1093A000543C6D87F72B5BAD2E06FD2E9BE2FE0431
+:1093B000EDBD65F7595C1BF271BF38A43C0BFA5D3B
+:1093C000FB60BE03E581759D37D3EC0693E07EEB31
+:1093D0004C2BE06D93B264895208AC7D7FCA1615A0
+:1093E000F0ACFE57E56716285F757FC116F3758CE4
+:1093F000BD82B21CED59FFD09968DFFE12A746F678
+:109400002EB76F7F794427CAC55BA6820A18E5ECA0
+:10941000D4D960CE2B538AB79861FCF4144FA10EB7
+:10942000C65B93326126F6B7F4BEB17FDD09DF7704
+:10943000A4CC9AA9E613DE447BEFCCCAA1D06E92ED
+:109440002CCFB354427F695616B6A72700BF0F0929
+:109450008F8FF67767BFFDBD60E6D41CC04B4553C8
+:10946000A50AFDBF9E72DB9631573136FE817287A9
+:1094700007C63F98B264A615F0DF6994F5976DF1C1
+:10948000C0589DCCF78601BEFFF1FEBA9966A89F31
+:1094900096EA2D74C0FA53CDF76F9991FB1DF865CC
+:1094A000A412BD4F2C487112DF1C4690E6ADEB3381
+:1094B00072FD2AF83D87D3717F792494ED11E54C34
+:1094C0005EEEDC105B7E9C4EE572B93321F6778F41
+:1094D000904B00EFA00EE9B3CB1A18961F9627C049
+:1094E0004FE609C45FDBB93C01BE9A63273E8ED9C3
+:1094F000DF37E55F803BF5D3A97AACE8BF90720D0A
+:109500006666C571BE4C7669E47559CF5292B7BF95
+:109510004A157CEBE2F071566AE50A33F70C47B85E
+:10952000C8768BC53AF3474BFF52D088FCB9D6E2D8
+:10953000C9C0F9ACDD579EC12E6387D75D2CD7F823
+:109540004BC2EB984AEF07F40BFDB944FFEE315FD5
+:10955000075EC95780571A7DBFD23AC3FD69FD3BEC
+:1095600003FBE37E9E017AC5187B9E1B53B85E41C8
+:10957000F8EB22E4DA4A215F416A913D7EFEC5ABF9
+:10958000766FCD8F1C7703F50FF87D7A0AEE2F41A9
+:10959000BEA21C2B533DB3B07E594F8A03ED79A078
+:1095A000B78D82DE54A43789E7CE94A6725AEF763F
+:1095B000C5B13B861DF81339AF36C583F649C622BF
+:1095C0009F7E49C4FCA4FC87FE3B45FF259C9E1F53
+:1095D000EDA7E7C5C83FC22FC4DC40DF6307CE5FFD
+:1095E000C136CE08FDF5822580F39170FBB6F42FCD
+:1095F000ED87BAB87A2A91DA651C0F26BAA09E21A7
+:10960000C5C5F9B9E3E3C46B515F75E999E2E2EBD3
+:1096100046B95126E5A4BFE748854A764C582EBB8B
+:10962000C89E917233683687EBDFBFBD67C646942C
+:10963000AB26BE2F4FD383142F0ACFE3E514AE2FF2
+:1096400027F89827961D7824D92EE508ADE3E17513
+:1096500095EC63589F5DE8D709213FF9B39E4C66AE
+:10966000C23EE1F090FA7BB629F4AFDC4FA6A547E5
+:1096700059063BA5415710EE1FBFCF89A0FB63825F
+:109680000EA2F1F35DE513C0C18F70484DE172C8C1
+:10969000096505ED0B15F417C0FF5CB5CDBD353F71
+:1096A00062DE362E8F9D7A1D976357E08BB454FE91
+:1096B000BDEF253BF173181EDC8EF92F01F7761DE7
+:1096C000ABC17DC1211DF009D2A28DAFF3FC8B5936
+:1096D000D4EFE7293AB9FEEF452EB71B613CCED750
+:1096E000643FD6BF3CA85D3B7FDEDFDC544E8F6518
+:1096F000C73D8568C70CF3DADCB85F28EB9973C007
+:1097000000E5E1DD8A036B4B3A1FDEC1F914A84B7B
+:10971000C0E5AD6722FBB5A5723AFABED631FC387A
+:10972000A757C4CBE2083ECD4DB57178C1FA4C08BD
+:109730004F552B47E5F3FB9B87F78001D65B07F07E
+:1097400040B12DE1D6D9B1648305F9F83873231FF0
+:109750009FEF58A21B8B78DDC9C8BEEB970F0FF0A7
+:1097600075487B14E8B203E9F2EAD45C1A6FD87149
+:109770008F750C7C1F867613FA953BEC01DC574CF9
+:109780004EF5CD4D4578CEEDAB64204A1AAC4DEB8D
+:109790002D11EFFBEB77417DA2639F7E2CCEF3363C
+:1097A000C6B6BAC2EB81A9FAD11F5A6F043E2DA0EA
+:1097B0007210E1D669E4F5FB16338ACF34E8FB8CEE
+:1097C000F81DF4F72CA2CFA3BA14C42FEE9BD06ED1
+:1097D000AED37B7314DCD76798DCA807601F42F414
+:1097E0007EC8C2540BF4FF263C514E57E9EFD88F88
+:1097F000F0AA2A50DC2D24AEDA85DC6041DC37CDBE
+:109800009E62257A645FDD39B41AF5BF95E309FAE3
+:10981000318B7ECCE6A230FFFD3AEF2ADAFF48FD1D
+:10982000764851A89F43D78DDEDD12B12FC2FE507E
+:10983000FE1F52AA73EE40FA17FB3AB20FD3C27A58
+:1098400017ED95225B24DEFD627EA13CA4A3487B3C
+:1098500014EDD37E7BD6DFB1653AC8D9F1333A82B5
+:109860003A0752D1F333FF01D65105F6AC05E0704B
+:109870005B2A973387F2FDFA449CDF30583FBC3AAD
+:109880009CE01BD3640B8F932EFC0FE946EE2F4810
+:109890004FE0CFBFA7723BE727695C1EFE218D9783
+:1098A000D31363FB2BBE10F55413971F5BCBB9FC8E
+:1098B0008FAEB741F4FBADEDDE318A667F0F76EFF8
+:1098C00086546EF71AB95F88C713960AFA063B8763
+:1098D000F014B6AB783C50DAA15FF4CCA3F272F38B
+:1098E0007BD9E8BFBFED9FE6DD87F4B6F2377AF2A9
+:1098F000579C14F18295C9BEF464DCBF27C4F6AB53
+:109900003C27D675BA99911FF8538C1B82EC3D8980
+:10991000714328AFDAF9E034E4BFD52C40FEE0E52E
+:109920003B37515C707940612E05F7695EEE271672
+:10993000F858BD47AFF14BDFAE361993C784E977CE
+:10994000459B366E58B3AB5853FEF6F669250B446B
+:10995000C8A1B0FC9946EFA3FB95F41E6DA77ED479
+:10996000ECD2F8C397EE1C46EB97F5973137AD77FD
+:10997000596B8166DEAC95F349BCF949BA45BBD455
+:109980001F739E46CDFB8F00FEFE08FFFFD25343A0
+:10999000691E2DA9BEFF40BA09CFC3CAFC1ABFDA9F
+:1099A00024C727B05666E17E49A023FFE5EC81502D
+:1099B0002AA7FF6F0FF7D171F605E3FEBFEE0BCAC2
+:1099C000267139CCDA14360C1EE3A76AEDB4BFA0B9
+:1099D000BE2BC5A795EB6B61472D5FA4AD7751D426
+:1099E000BB28EA5DC9BF12699F290528D7787F0D7A
+:1099F000828FF3CF1C35BAA0DEF8346EC716393D1E
+:109A00009750EF6CB3248E437FCA364B5E00F552FD
+:109A1000FFFABA381D6D33483F8A3B03E1D6FE5F3B
+:109A200077B6A888C77DB00F007958FEE841168A3E
+:109A3000905337AE533CCB01DE7621EFEADC7C7DE0
+:109A400075EEA07128F4935DC7E795D3B15F5123FC
+:109A5000DAE5D4087F5F9A41B3CFCCC1324E258D71
+:109A6000CBE39C9AA03214EA65EFDAA3A8D85F870B
+:109A7000427A33BB0900134157D925DCBEB9B1A4E2
+:109A80005D5936260C87565DF51807E0A735DDEAE7
+:109A9000467D738FD337240DE7792218C4EDFCF887
+:109AA000133D2ADAEF3F757A0AD29C6138B8F48EFA
+:109AB0006CD4A7D6137C9E6DFDFB63AE6728A24DC8
+:109AC000FEABDDDC9ED1B3238CDB87A4AFD2378C19
+:109AD00024BD27E7979E22F4453AF33D67A3FAADEC
+:109AE0008CF0C9683DE91B86EFE6F62CC7775581F7
+:109AF000770FBEAFCAB8AAA805DE176C0BAA4BA198
+:109B0000DDCBBB62FB83CB853E81754CC2F5C9754D
+:109B10005C492EC87A86387E0AC90FD619B1F71F5C
+:109B200030227D2F7F346D21CEB76EA39199943072
+:109B3000FC7FEAF4CEC6F96477B42B081BE9DF9307
+:109B4000E34AFF1D7E47FEFCC828F996D35F5CFE02
+:109B50005FA7F72C8F94671B8D8427693F87E7C722
+:109B6000EDFDD5695CCFBEEAF42EC1F934746D27E2
+:109B70007FCFAA3D1F1A63F9ABA3F9E24A70546A7A
+:109B8000F8BEA06EBE3980EB2F7F54253AA8DD6861
+:109B9000A43859DD33FBB89FE71EE6463951D7B1EB
+:109BA0004F590EE3D63EB34F591101D74175010508
+:109BB000E733C22EF990CBAF68BA473F32DA2D8730
+:109BC0002D5C4E9C2DB7F91580EB5983AF0EEB9DA4
+:109BD000CDB2BAFDF9613CBCB96FFA11CC37B03FD8
+:109BE000670AE2B355B73BD30CF55A4719DD485F16
+:109BF0003F75FA36235C52546F27B64F4EB3BBD72E
+:109C0000435B978915A1BCFBBA70181F4527E3EF8A
+:109C1000E1FCD3857288DB9145C83F8134BBB4A792
+:109C200048AE1D36F0753CC7F87CFF9EEA7990E897
+:109C3000F8480A8D9B5D1754D09F9D7FE639926B43
+:109C4000B2FF309D791E89E4DF2BCFB3C388F45671
+:109C50002BE450F9A37B948F23E6FD4B30F4916EF7
+:109C6000B29F01BAB4D1F7FD33D3A83E33B9F0BDEA
+:109C700042ED6AE1FB8A087923D71143EEECC3F584
+:109C8000D84EF41CE47227C8FD8D62BED1F87C1555
+:109C9000E51F7C9A06EA99DE1BFD23312E7A78486F
+:109CA00002F527E54034DFBE2AE81CE5A5CE46FED6
+:109CB0005AB22BE5FC64BD2267C5FE3482430FC156
+:109CC000A17E974AEBA9327A87DE11C10FBF16FD3C
+:109CD0001DB8F90323CAFD07FEFD5DA2C7FA36854C
+:109CE000E2F1ACED5DE33CD447FEA7F46867CEE259
+:109CF0002601DBF1C2BB84A7599D5C2ED777EE53BA
+:109D000097D9C2749A7FE6C0AD4867F51D2686FBD9
+:109D100022A0BFDF207CA2E954C247CADD78F8B494
+:109D2000CEE07294F98DE44785FD543EFA29A4DC17
+:109D3000FE7BAA4EF809F8FB0B69BC1CA61FDFA727
+:109D4000088FB0DCB5105FE49F293A60C67DB85B30
+:109D5000213F7F5A258767E4BCAAC7C6979BCE548C
+:109D6000A137D450DE1C7B58BEF7CB7FD1FE0B81D0
+:109D70006F781FE4EFD910D4F372FED1F8CB77726D
+:109D80007D1B83CEFE1BD711ADDFA43D20E9E6C9C4
+:109D90005DAA468FD89D46EACF0E1B739CC78E7274
+:109DA0001ECFD861E0FA6CC77A7300E5C99B0B78C7
+:109DB0005E997DA13188CF43BAA575F8FD50361F55
+:109DC000BF55A75B83E5D60D36D64278F5243A4BCE
+:109DD000917E1219978F5C1E3EF03C9767757E5BF3
+:109DE00080C13FEB7C739753DC39CDE2C6B833F3C7
+:109DF0001D34CEB30FA42BD773FB8D2E783FAB83CE
+:109E0000F39FC403C853A22FC90F12AE617872B872
+:109E10004B7E92F8F8BBF46703BD7CA7BCAA3DDA81
+:109E200078DCDB46DFD54EBECF3A6C70A19F86C78B
+:109E300017E2D16FEDBAB7B34F821DB53AF32D7A61
+:109E40004ABE85FDAC86BF2709BC1738B9BEAF74C2
+:109E500072BAA92DE920BEAC3DD944FC6C9BC1E58A
+:109E60009AED84561E33F6CF62BDDBA85D95B563CF
+:109E70001AE677543DAE3870BF1F4F6EDEAEF0FC71
+:109E8000B84F77BD9188F972EC2BB0F2319E62E148
+:109E9000EB9DEBE472E2EC5E0038D17B93F172F65D
+:109EA000FB95FA63C1630AC2B356C0FAEC3395134B
+:109EB000FF847EECBD49EE61B0E4CF9EB9E9EE3F90
+:109EC000C1BCCFEE99E246F7655A8B97E8A7CF69F8
+:109ED00071E37E03C4F70CF417AEEF7823F15A68F0
+:109EE00077FAE9AB8B506ED78A799E795EBF0EE127
+:109EF000B2E1C97F9B8CDF6B034AAA09C7D9FBF883
+:109F00007F6763BEEA9E46F217B53CFDBA11F317B0
+:109F1000748176FE7E6F9203EB9DFEF9F6C908EF21
+:109F2000968E16FA7EE6E7ED543EF0E4BFBDF67776
+:109F3000F4E37813DD58EFCCF3FB092F753E95F26F
+:109F4000DBE2D1F58E7DFBB9BC443D8F7C309FCBED
+:109F50003149D7927E4F3F79DBC448BD21DFB70A34
+:109F60007F4E6B02D7239F09FEADADE0F1CECF9EB1
+:109F7000B5CCA7FD8131341CF7C57563385DDC2D88
+:109F8000E051D77187A1C146EDA99FDF02DFE373DE
+:109F90002CD0E72723298564CF25CAD7F957AA0FE4
+:109FA000F526A0BFE7E6451F2A381FEB9826432D6C
+:109FB000CDF369FE1D561DF9BD6C6D6C3FFBBF38BE
+:109FC0006DC22EE07C90DD599DE3223960720F8BCB
+:109FD000B087B36B7C2D1827BE7EADCFAD073CBEDE
+:109FE0007CEAE8B441507E72A4524CF8D72B5CCF87
+:109FF000F96D344E3DFAC1818F760B3E497730F5CD
+:10A000001A9203DC1F50A532D5467EAA3E9213F564
+:10A01000AD420FEE117E6E735FDE4D766A67BB2632
+:10A02000621F06ED6C362AF7E5FD10F34A67F8E784
+:10A0300093DE711969BE67A43C607EF27B4A7E8B19
+:10A04000F61BA1BCC1FCD1579DE55D281FE5333D42
+:10A050008EBFE4EFE2FBB8744F17CA15B63755A3AD
+:10A060000FE2C99503379FE77AFB950F890E1B9086
+:10A070000E717CDF498DDE5E4EC215E8F0A50F89BA
+:10A080000E977771F9DAD0556EC4FDD40EE1D76919
+:10A0900010F4847484FBE8BF3A93699C86C9A1E1FB
+:10A0A00028A7CE0BBA3BFF12A7B7433A1DF9010E02
+:10A0B000ED1EDDDEA20CD48F4A8D97F0DD00F8E6B0
+:10A0C00076F3DAA36867D5D73037F26B43A7E0079A
+:10A0D000B07B11BE0D5DD5CBB1BF416933C9DF0D7A
+:10A0E00076C9B441506EA863A5C86FD9BB2A5E4239
+:10A0F000BA605D7C3F9E5D03F62CD24D5ABD5B9FDE
+:10A100008F7A8FDBBDD78F2CA3F63B725D14E7F2FD
+:10A1100057318AF3EF40FB19F55DD6686E3FFB3689
+:10A1200092DDC55C09E437653E750DD66FF02F6290
+:10A1300094D711CDC72F29B40F680858291F685626
+:10A1400017B77F1ABA381F9F93F0914F43CFADE4F2
+:10A150008F7FC1C4FC11FED0375F9ACEF5EC8B2601
+:10A16000D2B39F357BD8C7B0A0B785BC9770AC6D14
+:10A17000CBD721DD32769309E7B14CCCA3CDC0F526
+:10A1800046B2D00305DBF83CD474E1774CD789A7FD
+:10A19000519BE7E2F0937FE19C188FC8225DE8397C
+:10A1A00018BA7E7990F8A4EE19DE5F9AC9537867E1
+:10A1B00004BD4AFB289A1E0BC4B8D9BB0E2A284CF2
+:10A1C000B277CDD1F0F9F5352CD808EBBC7E972EBF
+:10A1D00038651CD94D0B499EAF37B258F92A23D2A6
+:10A1E000B9FD5695EA2D44BF76D5CD3677A43FB953
+:10A1F0002AC1A3B3A01D5724FDD8DE128C1B9D4A93
+:10A20000B7BB116FE3D25DD20ED3D85B03F7DFDCAF
+:10A210000EBCA1CD3F0EF71F81F509F329AE09DA77
+:10A220008DFCDC0E688FFBF7DDD7FE9CEFDF5BB8A3
+:10A23000FF020407C999546F09FA8F9D05DEB55CCA
+:10A240003FD9DDB1D6F3AA93AFE7C0CDB716E23E52
+:10A25000B161AE8DF8E1815794A59CDE4011E2BE5C
+:10A26000DAC7F983017F3CE1227A243BAAA1C91B0A
+:10A27000884D8F9C5F1AC0AE423B1BE8710DB793AF
+:10A280006D8CF313A74BB9BF47B91569CF4A3E8D03
+:10A29000E67B49BFFD7CFF35F9FDBC81F3E37980A6
+:10A2A00003D27B3F9DBFCCE97CEB7AE047F8BE153B
+:10A2B000F8B12542FE47EF7F709EB81F90F2F61E60
+:10A2C000A777513ACAA1DD6F6DC650AB948F0D2FA1
+:10A2D0006F197E39BBCB8C95A15F33F06B24FD6089
+:10A2E0008CD65E444F3FEA09EBBAD8FE8FBBD26DE5
+:10A2F000DFCD3F3F302FE5AEF4D2817929E9A87355
+:10A30000106FBBAD01B48FA51F297A3E4B049F4946
+:10A310007CCAFD03C621B0FEFD82EF37897A8F88A3
+:10A3200067C4BE84F8C1A5F37D4879F671F4916CD9
+:10A33000F77DF9B5E438522F46D38D8CA3E07AAA85
+:10A34000C7C4AFD7B65FECCFA2E8F829C15F0B80D6
+:10A350003770DE6D86E017C48F77D819E513F8994A
+:10A360002715E371AF8DE07C34B26F38B6B766FA6B
+:10A37000BE44BA927E5D7C8F71AA5A11BFACDD6B70
+:10A3800008449E7FB93783D138BD76B35F0FFC9107
+:10A390009BE9DB87EDFD15CC1D443DF38F168A2B21
+:10A3A00081815B8AF2A691851211CEEF25FB5E209A
+:10A3B000FAD5F70C47BFE33925340EDF9F10FEDADC
+:10A3C00013C25FFB7ED77BCFBE02AD17BF726EF1AB
+:10A3D0008F91CE5EB4E4217D9CB0F4E7BF25A1DD72
+:10A3E0007D81B9922E770E699159EF5523FC67272D
+:10A3F000ECB1FD7F6F0B3C378A782B5319EDC3B757
+:10A400006770F9193EBFC4E3ADEFEBB4FE37F91C3A
+:10A4100093C1E1DF19E71C506106DFD7740EE1FC40
+:10A42000D8D7AE50BCAF66DDFA3FEB412ED4ACB509
+:10A4300007E9099FD18EAB71F8833A289F3070B934
+:10A44000047F73CD6561FD07F5D449C8337E07C528
+:10A45000BF960AFDB5ACE9CDBFA15FA14665E6494F
+:10A460004518C7F21E1E049F3EB52D4F44F1BFF2A2
+:10A470004777A6A37ECA58D426F2C1A63AD0FE5585
+:10A480003C37E82F592F676FA96427131D00DE1E84
+:10A49000CCF0F6221F2F4AE27EC145775A03FE0810
+:10A4A00079B857F06134FD7C10E7BCCD97191501E0
+:10A4B000EC6F61AAF76FD4EF9DE73472EDBC12FA2E
+:10A4C000C523485F77D8DD4FF0EEF222F363D20563
+:10A4D000FC6B310E04A2B1B7B067F8BA7CA4E3BE3E
+:10A4E000BCDFA15FABDBE4F0BBF0BB91BECB76F190
+:10A4F000E241F1E3402E23D247C34585E86169F785
+:10A500009BC751AE37A821A293A5661BE1B1E1A27A
+:10A51000CAE9A9D5703624DB03EED7A47AD232601B
+:10A520009EFE7B2725533C09F889C3172A459CE3E7
+:10A53000F832C3372803E0F79035F136DC7F5D3021
+:10A54000BB92308FADD108F4703575E73547D843ED
+:10A550002CC7AEA583EEB7FE86F35A6EF61951AF3F
+:10A56000AFF034D179B14549C152C79848BC4FD2F8
+:10A570005F1AFDF5F17E49C897F78D3C6F64209D09
+:10A58000733C6CCF10F5B239BFBC9FC76A9EC3E75E
+:10A59000287842BBF787887291280F17F5D279790E
+:10A5A0009AE097F7C7F17AD1E32C15E37C99E1990A
+:10A5B0008C7082764123D2C76B163A67C44A40FE3C
+:10A5C000A1BC5B934B762CC8B96908771827984CC7
+:10A5D000F54CA4675813C841C0676FA98BE0B3B5A9
+:10A5E0001CE805E341AF9A281E24F12BF11A8DCF08
+:10A5F0008519CA77CB4F1F18BF5E98513A307ECD70
+:10A60000D850C217D14B8CF31FF1F0F56B3BC70349
+:10A61000F0EBF20CD283C1B1917CB349C051CAB501
+:10A62000F713B478FD3C9DE3A15ED4BB84761FDABA
+:10A63000D1EE3EE2BFF75378FDB402AE97A45DFEC3
+:10A640004F022E5FA66B9F52CF44FBD1BF14F2E2A4
+:10A65000CB74EE4707BCDE8DF395FA09E44C301954
+:10A66000F878D1EB2692336C631FE5D540BDFF83AC
+:10A67000F05A64EABB3515F4CA0FC1DE311651BB7E
+:10A680004B284706ECEFC748BAB033D4DBAD190E00
+:10A690006E1F94F4F1B8D748BEAEA50CE48772657E
+:10A6A000FC630C210BE4F06B22BF42C1BCAE146210
+:10A6B0006717F60770FF978CD230DCA3C73B21E801
+:10A6C000E0D10C4525BC15B242C4DBADEF7E6E5F18
+:10A6D0000C5D9E13E765934DBE76ECE7ECDD6F9164
+:10A6E0009D7EC2181CDE668BF1DD187CEC2125FCFA
+:10A6F000FDB6A7F47EE3D5987F7EF6C19B61DD4B66
+:10A700007BF46E1C72E93D5FBC331EEDEC1E03C58D
+:10A710006B40DF6F5371DE4DDCAE3CA1D3D2C1671D
+:10A720007769F73DAF0B7A90E772A5DC91FA7C155B
+:10A730007373799390B81BCB1FDD713B9DCB5DCEBE
+:10A74000BC873D00F7D36B66925D7C3BF3515ECFD7
+:10A75000B256ED39DB156DDAF2ED3B079CC32539B6
+:10A76000BC2A10FD5EF8A52B63EBFBF3822E3F3372
+:10A770008AF8FD7A53CCF8FDEF85FC09C7D9FBB404
+:10A78000F1FB572F1FBF6F8C8ADF87ED88E8F83DFC
+:10A79000EFF713616F60BF9171FCCF2A62AFE3A343
+:10A7A0000C69B75835F9199F0CB05B12E97BE3458A
+:10A7B0004B9CF9D8E8FD672B638FD3D73F8E365F6C
+:10A7C00020DC9EE709C8FDB5A493C68B59A4676534
+:10A7D00059DAC7E17639F43DFABCBAF46F4BBEF8EA
+:10A7E0005861E62CF2476D1776BC9BF2333F46BBAF
+:10A7F00008F972BAEBB5104C71D98F270E578784C0
+:10A80000F9267A1D405F674211F2D898694F23FDFF
+:10A81000EB666E3A9727E8FED6BBABE87CCFFFBD70
+:10A82000A73223326E2AF7530D46698FD934FA9630
+:10A8300045E9E3655D6F911D06F6D770143E7F7A9A
+:10A84000F56ED2C32B99371DE9BDF7D511746EE5AE
+:10A85000DBEA61399F9BFC4B0C3CBF358DEC8739A3
+:10A86000623E3775733B5067F618681C0F7339D218
+:10A87000698BCDE70B425485F275FDF347E71D6305
+:10A8800093C4FC156C0FF0BD4E3CD9525F26CEDB55
+:10A8900084E3EA310D269089CF96896E173EA7286A
+:10A8A0005E95CF83E3791A6BCAC1FA3A7348CFD762
+:10A8B000093348C7F6FDF0A2B25D9437CEBD70EB08
+:10A8C0000A7C6FB3933C318A794CCF04B988FC6D14
+:10A8D00066665CB7C9163C4DF133F1F457B8888F02
+:10A8E000FD4318F9411258079D3FB5D9CEF971B112
+:10A8F0000EE650B06C715C08E27EE29CC3E6C7F3E2
+:10A90000C4202F6765A23F5FF9D54AC40BC867EE24
+:10A91000178AF75D0DF2F31142DEA588F9B50879C3
+:10A9200097C5DC8AB8C780E4DDFDF69537E07E2662
+:10A930008D79F7A3BC7B387106C5FD32988FE693FD
+:10A940003A43D5C82DA7575BCE98AF46CB3B05E71A
+:10A9500097E5D3BE37B3139497A404BD9997526972
+:10A960001F3612FD310621378E59783EC26631CF2F
+:10A970003B3353886E8E59785EC2B7B65BDCDA7DA6
+:10A980007D430A3FBF7F3EDD6CC6F1C08EB913E147
+:10A990000776CC077E16CEDF2C9CD24179029B6FC6
+:10A9A00054DC1BE0FD66BB6BBD0AA4EB9FA9707F66
+:10A9B0008FEA28C77C9CF63C871BF3441B45BEF7F7
+:10A9C000668BA3F619F2639A783DD6B719E396ED34
+:10A9D0005B1D0EAC9756D937CD88FBAA15CCB19B21
+:10A9E000C5A0F7AF808F60BE3FC732E04911F46366
+:10A9F0003DE2BA85D620BEEFC17F17F0F29432DC7B
+:10AA0000BFF2BF82EE423A77C93C7AD2978DDD859C
+:10AA10006FD860BC82B985E4AFF756F2B82F1372D5
+:10AA200060BC1C57F0D9B561BAA7EF85A23CB45BF6
+:10AA3000F87FD34C3CAEEB8021CAC49143AC9FC697
+:10AA4000F9C1CDE41FE7D36B58F80FFBAB0CF74F00
+:10AA500072696AF87398EF60A822B3BBA50EEA8DFD
+:10AA60005783FB91AFAF15CF42F13C547E23E9E50C
+:10AA70001E9DCD65D4713E3717A0ABC3AB47B894CC
+:10AA800039B6B4603FD729417AE6CDD8DE82D39F6C
+:10AA900023FC4CC999C6009E376B99007826BFC825
+:10AAA0009F0FA3FF5AFF2FAC18F174CC20F59E27FF
+:10AAB00089E7FFB9683DD50E3E5997CE337B2EC24C
+:10AAC000F9283FCFC6D0748BF8FE97A9554997D780
+:10AAD000BB3C0F30254BCFE5E30C1E876D9C6FA66A
+:10AAE000BCE546710F03537DF93F8CF0AFC8B8C584
+:10AAF000BB06367F5F8CFD464A16B707E6DCC0FD15
+:10AB0000C28D221F477E4FCCE27EB2BF644E7B37A0
+:10AB100093EC3D1E6FFD9D945F23D948945F11F225
+:10AB2000E58F245FCADF8E277FB4DF85FC99E72994
+:10AB300036D0BE40C82129EFBD22EF6801F31810BE
+:10AB40004F3DE21E95A3E5AB480EDDCC7CF4FEF74D
+:10AB5000153CFF0008D380FDDD34436B3FCDF36A25
+:10AB6000CB37CF8FB6AF383EE4B80B7CDAEF73A4A7
+:10AB70009D3C436B272FFA87AF9249CF67FCA2FE1B
+:10AB8000D2E0703E5163543E5183C8276AEC2A3CA0
+:10AB90009416914FD4D8CDF3891ABAAE944FC4ED20
+:10ABA00029AF29B01FE324DE5AD294EC0D917F72B5
+:10ABB00010F34F8AC2746EAFB0F33C0CE6A1BCA296
+:10ABC0001C8795CE5DB4EA8AC88FDB9A68D7F8DD1A
+:10ABD000B7AE7755613DE9BF95F9434837B1F6C344
+:10ABE000D9597C5FB343E17E74FF0233ED3B9D0591
+:10ABF0005E4D5CC1A967C7D1AFF86EA64BD6273FA3
+:10AC0000C90E832FAB189E0185D17989FEF67AB6DD
+:10AC100091FC905172CA99EAA6388033692CF9F5F3
+:10AC2000E77517923F92D92CEE614AB8FF7973DB32
+:10AC300055CCEB69EC6E5797DBC27437364BEC435F
+:10AC4000ACCC8AF4DAEFD77BCE447EBD6493B730C8
+:10AC50000BDAD71983E4BF8BA0577A1F4F5FDE2E24
+:10AC6000E8C550E15DB002E6D7FB8ED18DFB6B0AE3
+:10AC7000CC41FFCFBF944C7E49750E233DB5B19CAE
+:10AC8000CB935EF493C13A3E4DE6F7FA6CAC66A402
+:10AC90005FCFA74C233A5EC502873DE847DB0574CA
+:10ACA0001879CFD21E6DB98E7590FEA97B66003DD6
+:10ACB000937C94F2B89EB9F4068C1B746ADBB3A142
+:10ACC0005A395C28F447F1BCA92D98FF50ACE3F247
+:10ACD000912D770F9A43FBF5458E4F2C28727FA15B
+:10ACE0005CCEAEEBB59FD273FEE77AA154F41FADF4
+:10ACF000BF4A853D3719E417EE6FA57D06F5A97C9F
+:10AD000050D7ADCFD485E75922DA49BB50EA0B8939
+:10AD1000AFF2098CE179B5BBB2847C1AC28620BE41
+:10AD2000A17FE21305375829D4BF1FF785D78AF1D1
+:10AD3000801EFCA8BFFD3A7300E96BB3D244FAD27F
+:10AD40008CF63F3CB72A3ED20BFF5EE3D7237D4C07
+:10AD5000644D37DD00F526997BAC28B7804EFE3177
+:10AD6000927E5A58306F9FA2A123FA7E36F9ED9851
+:10AD70007424F55AF0F7DC9E99C5BC74CF93E70FA5
+:10AD8000DCEE3AA8F07D26D89F07D1EE7A5B3793A8
+:10AD9000E864262C03EB5539B4F89F9EA92D47DFB4
+:10ADA0000FC5D05A284374487806549C4FF4BD51BF
+:10ADB0001E29F79856EEE5B3AF78DEF896C33F420A
+:10ADC000FF83751D1B89F60E58AAC48FD1F4B027D6
+:10ADD000EB7B8FB7ECC98A116FE9157EE56B58687C
+:10ADE000E533CA407A3B7F689D3E33822E257FBC87
+:10ADF0006CE07913CAEB3CAE35C1CCC604112E25EC
+:10AE0000DCFF28F9E31AA4D39430FD9589F787A4D1
+:10AE10007C19CC0623BD5DD76509EA013F85A2BF39
+:10AE20006B90FE8AC2F689DC77B44C184067F998BB
+:10AE3000170EF64C01D295B44F8A958E163CE7FD5D
+:10AE4000FC4BF7B6E07C23E8EA2D84C35905E88A79
+:10AE5000FC6A03F4ADF67B14DD49FC4B7BBA9C35F0
+:10AE6000D17E676E02D7B3C1EADB49CF82B824BA7C
+:10AE70007B730EA7BB2AE621BA2B675A7AA9346BDB
+:10AE8000CBD1740923EAB474E723BA8BA6D77874BC
+:10AE90003718E94EEADBD42BD3DDE74877DFC58FDF
+:10AEA0003990EE3ECF72C6A7BB687A93F26C9FC50D
+:10AEB00051897675638D42FAA1F89DA12D581E51D6
+:10AEC0009F4F76F6BE6437D9DD8D4DFC7B498F47A9
+:10AED0008F7933056BC5F77C6F25961BD7C177E853
+:10AEE000BAF418CFAB197A0FFF5EB8A1E90DBCBF59
+:10AEF000A0D1CFDBBF7C7A339D870A6C16EDCBDB0C
+:10AF00002AB1DCD8CADB7F8A71AEAB31BF2DD082CB
+:10AF1000EFAFDA96EFE6DB6F6ED74F11EBDDA73CB4
+:10AF2000F706B56BE3ED6E3F6C4E60E427E0F6FA92
+:10AF300064B1CE29BBF83AD33EBE7E860BE86345AA
+:10AF40009F9FECB94F74756524EFE2ECB3CB95B6D7
+:10AF50001C7C4E4739A647BCBB5BF543781C743755
+:10AF60000C717536F7D3C8F821E6295447D817571E
+:10AF700067733B44D64B4F61747E8DFDCC4EFE72A1
+:10AF800019DF0C3EC414D407B8466197C48C774EC1
+:10AF90002F6822BB62FA6019E70CA94B61DCC24B37
+:10AFA0009F4F8BE5472ACBE6F6F329917721DFD730
+:10AFB00004F2754817FB9048E8FCF09077D09EDBD0
+:10AFC00097CC34E7DCF6E5F3F2D4ECBC7F6ECD0130
+:10AFD000F8EA9A54BCF78BE52994B7F2831E164C15
+:10AFE0004A1C38FFE92A0B1A290F8ACF7F658B513B
+:10AFF000DC57C2E5DA3C813F366918D1EF5C81A7A6
+:10B00000EA6CA1178B5931CAA979026F3F343719FD
+:10B01000B8BE6E3344C98F79D9283F1E8E6BCF6B73
+:10B02000BF47C9971A31EE4A61C7AF627DE43FFD61
+:10B0300044D8F1A71EE676FC6AD641FED3DE9F71A6
+:10B040003BBE1E9687F412ED07ADDDAB2DD77768BA
+:10B05000CB0DA0DEB1FFC6AE28B93386FBA57B1FA2
+:10B06000AE2F433F64CDCE77C8FF5D23E54C402B28
+:10B0700067C040E772E6A151E4BFFAD6F2E319D8FF
+:10B08000D59569F24BEFC97646F8775EE4792E0DD7
+:10B090008CFB117AED236FC17D2C8BD24FD172A521
+:10B0A00050C815E9FF90F25BCA9B42C6F514EC77D5
+:10B0B000DFF1609B283BEFE16CA1AFC4FE4DFA4D80
+:10B0C000A47D5488F611D2D7A82622BAB07E72BFCA
+:10B0D0006DD247E8A5052566C47B9119F81BE1A64A
+:10B0E000B78DF5D934F4F168F6E5F783DAEF51F46A
+:10B0F00023F7630B05FDDC84911818FF0F721FB84E
+:10B100008AD3CF5CE63D84F4F3FBD59C7EE4BEF0AD
+:10B110009BEF033DFAC87DA0DC4F7EDDFD603FDD87
+:10B1200058C03E86E7B15CE917E0F1FD4685D3459E
+:10B13000FD9CDF3D56C5C2F2E2683373AB8670B941
+:10B1400065A6C98C7E971603DF2FCD99F57ED9D2DF
+:10B1500008F913B4971F40B8B16E27F977EBADDA51
+:10B1600071362B3D77FD11F7558F5AC9AF74E10841
+:10B170002393E5C2AE11940FFE9981C75BE57C6E07
+:10B180003FBCF7B510D45BB9EE9662CC2FA8550240
+:10B190002FD6C1B70FACBE7791BF6B7541712F67CA
+:10B1A0000FC527E4B8F1FDBA7E92C7C6035C3FF72E
+:10B1B000290994DF0BEF8747C6E9FE3888CBEFDC1F
+:10B1C0004CDF07B81EA9475BFAF327F813B4301B0E
+:10B1D0009412CEA708E74D707FCB5F98E78A79136A
+:10B1E0001B23E204D03E66BEDB7921CF47617201AA
+:10B1F000CC6765BAA717D77F4AC4854F8938E2A9BB
+:10B20000441E57FC7B7F7DFEB40DE27AE894883BB8
+:10B210009E4AD1C69B64BD44F13CD96CF66E346045
+:10B22000BC9E793782FE703D646AA27C95451C5FA6
+:10B23000BD2F256BEE11C81A543E6A10B4FB99D38A
+:10B24000AB1F04E32C6FD39E83EA15F7DBF60ABA33
+:10B25000E9B5F0A71C376B50F5286CD7BB80DFB37E
+:10B26000DA5F9E28CB5EEABFF7BA10C9A3FEF28F61
+:10B2700042E29C3AF793C8F840BCF86174BC30FADB
+:10B280009C6974BC7FB1E43711EF5F24E4D4E26EB3
+:10B290001E6FB8D5CC360F82EFB7756750FCB82655
+:10B2A000D13F5C13EFF75BBF519E87A4CFDEDC9EDE
+:10B2B000FEF8F8CF22E2E3F5223E5A2FD7D7A95D58
+:10B2C000DF6401CFEF313E3E799073607C3C3A9F62
+:10B2D000E245B4330C613CAC7170B855E9EB2AD14E
+:10B2E0004F7C6139A33CF7356F2D6B413FF29A2DAE
+:10B2F000E296556177D70B38C75B97D3AB632E8D3A
+:10B30000BF3E81B922D693E54BD194C9928FC83301
+:10B310001D5493AD699FDB3444537FF0BA519AEFCB
+:10B32000F9FE224DB9A0F51A4DFD616D159AF2880E
+:10B330009DD76BEA17B22149E46F3BA2475F12BB6E
+:10B340002A3047F37DF4DE859AF69FB2A61D93A0BE
+:10B350005EA7457B2F33F37B7AC69485F3A9C77626
+:10B360002CD5F4C3824A50290BDF33F699B8A7795C
+:10B37000790F8F875CDDB55A334EADBE8EF0181D48
+:10B38000EF2D627DE4376E0828EE201B18FF5DD597
+:10B39000D54EEDAE64F7C878C8C64122DE97CDB26F
+:10B3A000395D47D3858DECC30BBBF4E47F2C64C3BC
+:10B3B0001F9A44F032B0806B20FE2E30EE17BBF0A7
+:10B3C0008CDD8D7945B7BFB58CE663CAD4D205DE76
+:10B3D0001F18B95EEB482D5DD8DD5A3A489AA0A5F2
+:10B3E000836878277BB474C142F0BFCBC03B7586BD
+:10B3F000966EFEB7E0DC81F0B586E15B7CD0D3626F
+:10B4000023B8F1BC35699F99843D141DD790764EC1
+:10B410007090B0BB453F322EB159F1935DD51F7787
+:10B420009C10CC0BE6A33DD5C4B85FC97B10E56F7B
+:10B430000CBF24BD8FE79794709D9BC0F5672DF3DB
+:10B4400092FC3E66E1FEA493D5ABC89FB4923591C1
+:10B45000DDFDD99CE9C2EFE8A77A57CA5318909F3F
+:10B4600000F6298BF0D7AE068B1AEF1F8A86A7D27B
+:10B47000AD04ED786E98754B7DE0A3FC150FDEED05
+:10B48000A989FF68ED5FE65122E597B487E5781258
+:10B490009E52AEC9714CAC499F897C1125E7D8C832
+:10B4A000E8F893D69F23FD41328E23E34CD1FE9BD7
+:10B4B00008BBB8558F71D2C1F92D78CEB7D8E1212C
+:10B4C0003F6129EBB905DF4F3077B4A82EE1BFB853
+:10B4D0008AF5FB2FE2EAAB2BC4B56FF22BA147F242
+:10B4E00007C6B3657C1C96FFF11FA1F124C5958B9F
+:10B4F000F398F3F20827D2D340BFA6FBF82BD08FE6
+:10B500005ED7978AF5AA30313D22DEFDA612A2F55C
+:10B51000FC907936459EDB6F601DD36E217F32E84B
+:10B5200049BC27A793FBBB5857B43DAC92BF590702
+:10B530002B41BAAF651171DEFCF0772AEB079665F7
+:10B540001ED295EC89A7F18272CAA3E0F9534CC8C8
+:10B5500041B9FF8CB7CF93F918F27E4F9977549485
+:10B5600023F8751C1B87FD03BF95E594A27F01F8A6
+:10B570005389E4C7FE3C25FA3E801FA3D62FF33142
+:10B58000F4F612F21B2D8B5CEFD78087B45B7E9CA8
+:10B59000C3E8E9C871D1B33EE1C46F3DF8B9A4472F
+:10B5A000933FDA68840D0DFA135E1479811D5ABB3E
+:10B5B000FD961C9D801BDFF75C095EF1F121F2F81E
+:10B5C000043EBEAE1D26F3F8241C970C84FB0A0D26
+:10B5D0005CFBF78FFD705F110BEE122EE74A7B7E4E
+:10B5E00081F8D2DB8FA523BC17A67A5763FDDCE375
+:10B5F000A14F145D785E55FAB394877BA14B4FE75A
+:10B60000FF1AAEE372B0E1253D8986F3DD268AB3E9
+:10B61000D674BD4176E1D96610B406FCBD0C187233
+:10B62000D865FC0851F08EB74F92EBD99023F6E520
+:10B6300062FD32EF07D6B93927665E473F1CB4DF9B
+:10B64000051CAAF46392F01C597FBE92DA97177911
+:10B650005F5FF43A2A7278FEDB29B3F73EECEFC362
+:10B660009E9C1DD85F95BEFB7036C267AD42E7BB9E
+:10B67000A698F879DC2C715E6F42A8C98DE79933E2
+:10B6800073F87D66237EA4F7621CF9FDB577A6E00A
+:10B690003934D9FF084547E747197BEE837F2CC132
+:10B6A000F8E62237DE6FBFD824EE2FBACB1A2C0073
+:10B6B00039F2BA91DF476518D244E766FA92F5E4A9
+:10B6C000D74CD3B3A9487772DEF2BCAD7C8FF701BB
+:10B6D000605EB17C3FA5A5AF780DFA7B043DC875CF
+:10B6E0004FA9EC2B6EB285E12FF33CA3E15325F873
+:10B6F00043EE431BF05E5BD0BFE7CDBC1C7DAF6D5E
+:10B70000FFFE7458FF3D36F6C8B87E83C593341EDD
+:10B71000F951DC6BFB17872789DF77A4BDA7F6BC3F
+:10B72000C8B797BF5312EFDE9BFFCC51BE977B8209
+:10B73000E2E585CBBCFF7870694856997A359D73F0
+:10B74000F75EAEDE2BFFAD8FB9DFBE28BEF7DFD3CD
+:10B75000F96AECBCC55EB1CE707E6188CE29F7E790
+:10B760002DBE547ED97B471AF03ED20838C8BCF6AD
+:10B7700006BC8FB43846BFD09FCB76E57B87AAC482
+:10B78000BC1A308F3035F23DA7B7F03869222F3020
+:10B7900094887CFBCB2E3D9DE3FFE511DD8CDD31F4
+:10B7A000E69D9BCBE132CAA9121F8D0EF2FBB5E3D9
+:10B7B000D593E779E4B9D8E8F97556846EC5F9638D
+:10B7C0009E72ACF11CB97C3F2BE7DD99C2F1D1F040
+:10B7D0009A89DF9BAAF27CF2CE94D04AE2138716B4
+:10B7E000CFC3041E3BAF0FE5D1B9B299DCEF108F88
+:10B7F0001E26A7FACA51BEC87BEECAD426C511C1FF
+:10B800008F57A28730DCF51ABC0E84BB91BECB7E6D
+:10B810004F1F157CCB3C36DCCF2D11FA6EC99E5ADA
+:10B82000B287E57EE9F44E3DE56F9C663CAE72BAA8
+:10B830004DA1FDD0521F63EB402EAD7CA27833AA00
+:10B84000AE2599B09614FE1E7F1F66E9C6A8F8BA09
+:10B85000D85F49BD2AC75FBE4D6B17D7B06D7F4615
+:10B86000FBE9F4512E3F56B026D23F2B1FD0F6579E
+:10B87000B367D6A738CFE8BC8011C28F372D57ECFD
+:10B8800057CA5819EA8F354F7C6EC49F6089C71715
+:10B89000F8FB4F4387F1DF7DC227FE8E083E6FC95C
+:10B8A000F5FC2017FD3EEFF2F9AECEF5CDC9457F90
+:10B8B000C9BB7C7E17EA2E703DB32B8DF45B8BFDEC
+:10B8C0002E92FFFAC15CFEDF8BF735009C4C26718F
+:10B8D0006FBAAE499F48F64D80E8EC43E71D737E92
+:10B8E00040657726F243DAD3D36760BFCEA7AD1E9B
+:10B8F0005CDFD6724F21FA2FB656F3F3A166138F91
+:10B90000DF077E39F100865386766CAF40179DA322
+:10B910007B7F10FD42ADBA3F1FC6BC98D6C93C5FC5
+:10B92000325D17DA3F28623CA7359089F17DE768E0
+:10B930007E6F4E9ABEBC90CB7F6E2736085C5CE86B
+:10B940002A207F62AF41FA173B2C742EAB8EFF2E5C
+:10B95000C628C6F12FF3EA700E9176F1D966A6F9E2
+:10B960009D86511D4AD09048F7A8503CA86E4330A0
+:10B97000FD16D4674FA9144F93F34B7B3DAB02E305
+:10B9800066528FDDA238B8BF4DD8FD0B98FCE3712D
+:10B99000B7F9829E16087BFF162B87F752E6CEC3B7
+:10B9A000760BCD2C5107AC764B654729ADB3D690BD
+:10B9B0008C76858C1FC5B74762FBC91A7E61E7E7A5
+:10B9C0009E95BEE1D8C919F4415D863FDB853C698F
+:10B9D00018CECFFFB1A1CC83F1CA86D746D0EF30C5
+:10B9E0009912783C1CE49619EF113A84FA1ED6BDE0
+:10B9F000EA158BC85B0A8873CDFCDED8C639394599
+:10BA0000741EF1781FDDFF71DE10CA23FE067984F3
+:10BA100037A6BE92FBBB1FE0BDEB0DD960D741F945
+:10BA200074EE9F7879486825DE1B9992778997474D
+:10BA3000853EC1724E5EC26C2A178556EAA13C3E15
+:10BA40002F939771030A0436356FF06C3FDA2DC9D6
+:10BA5000C22E7087E8BC77C3CB237491FE58771E43
+:10BA6000976767843FF94C3EBB6D0EC27B64ECFA6E
+:10BA70006979D2DE6EA3F5C9F5CAF62C3376BBFF21
+:10BA800010727E9538A73DC5CA5A2D3CFEE74F047B
+:10BA90003C1CEC1E41F1CB7FCD4DE1FD3B42744F90
+:10BAA0008FEC27FA771CE4B8AB15FE7B59E7A3F2BD
+:10BAB000BC7E97CBE52B8CB391C619EAE1E79BE7F7
+:10BAC000E41422FE006FAAC09BCAF7C9ED7C7ED0A9
+:10BAD0002FFEFE13E88762F4FB1FFC0AEAE787E704
+:10BAE0001D4D2727C538AB5A78DCB62FB980E869D9
+:10BAF0008A55DCF752A25DC7F83C6E9FBAF392C537
+:10BB0000791D09AF0C85C6691170CC090D9F33F6FC
+:10BB10009BAFFBAFFF4BEB8EC09707EF6D39D8C5DE
+:10BB2000EF371E9FC7F185F49C4276E0764D7F6724
+:10BB3000D647B59FC0285FAE21A580DADF2BEE6F18
+:10BB400095F7D961BBFC71DCBE45BB57DEA7C1FCD4
+:10BB50009359641CB2FFDE8C0E71BF70FF3A6F28E0
+:10BB600011EB7488753A22EF33ECE7CF637D79737C
+:10BB7000ED03E9B81FFEFDFD8D2912FD69F83C5665
+:10BB80007FC8D7F1F072551E9727DF1B5EE43CA3F8
+:10BB9000E0D90FE7A8F94978227F53BB315ABA940C
+:10BBA000F3CC11F43980BFF3BFE578E27ED9FABB5C
+:10BBB00079BE387369E9BABE335F87F909B2DD0728
+:10BBC00078C0A034EC27BC214FEC2773584E9CBCA6
+:10BBD000476F9E33A67F91DE47EF277B93E5EFD932
+:10BBE00069FD1ABD4EFE7B39FE73FC7E836BA3FCA0
+:10BBF0003C188F7ACE166E17D62FDAF263027E03C8
+:10BC0000FD547D7938BF1253C5F3F83B5BABF34A63
+:10BC100067AB6077942455DC990FE5A6C7C693FC03
+:10BC20002E1954F1793EC8F3358F4DE0DF47577C2C
+:10BC30003E04CB791379798AE77994F760B4CC9E86
+:10BC40009A15B62BEECC73D1B8FA4A1DDD6B67425C
+:10BC50002306D6637ADD44F98012AEF19E25265D77
+:10BC600053ACF3BFF7F4D3038FBF4CC07FBAD01FE0
+:10BC700028FC052155E32FE84DE4E7CF7B5FFD92DB
+:10BC8000CED7DC9BE75B9F07ED1BAD676FCD87F2DF
+:10BC900006EB0714EF533C6087A01FC6E5608B607E
+:10BCA000BECAD9AD5EB49FD86AB75925B80AFF1885
+:10BCB000DEA907F07BE5B5A77E3C880FE3C5794C8C
+:10BCC0001472A0F1B5BFFD15E3C48D676C6E341B13
+:10BCD00027763F7C27DA5F13BBDFFE1BD7C3FC3C14
+:10BCE000909CF744F47FC2FB095D269AFFC4EEAB3B
+:10BCF0005660FD6BDFEB2E403AB9EE44B005C5420D
+:10BD0000EFABFF3E48730E887D7AD97CD1B8F1390C
+:10BD1000098F3F01A093081E3FE7F0F88AF2D9CEC1
+:10BD20003B8F6E0E9193547BDE0AEC788A3B5F600A
+:10BD3000096E8C7BC873FDD17ED5E3D5B03E787F8C
+:10BD40005D1FCC20C29E9E72D10C82245C2E67C9DE
+:10BD50009A72A5394B53BFCA91AFF93E3DF32ACD34
+:10BD6000F799AE424D79D6C8899AFA37BACB35E5FC
+:10BD7000D913666AEA577BAA35E5C26087A67EF1C9
+:10BD8000912EEDF7634C8F78283AEE7E039FA5271E
+:10BD90003DE49E2D3BD5F4063E27FE858323DAAF96
+:10BDA0007CCDC58E37F0BDF42B479F9F927EE69BDE
+:10BDB000F5B68031B63F39532D08DF83A0D7F1F3B4
+:10BDC00053EF25FBFE807893E7A7A6A05F1990505C
+:10BDD00075DBB99FE2EF325C58C4FD6EC711319438
+:10BDE0004F6E277FE57143D3B37FE47903B928F71A
+:10BDF000AEEB9BAF59F7948B3ECDBACBD9AA283C7A
+:10BE0000DDA1295739EED6D49F9EB95EF37DA66B8E
+:10BE10004B149EB66BCA37BA1F8EC2537B149E9EBC
+:10BE2000D27C97F4DD2DFC5FAFA1DF0A9E93423DEB
+:10BE3000958887C9A7FA081F137ADA2A114FD71CE9
+:10BE4000EF207C9504BD95282ECB8E34BD81CF206C
+:10BE5000ECCBB0DD81E64C7A1E6C7691FFEB70F393
+:10BE6000487A1E6976D3FBFF689E40CF5F357BE83A
+:10BE7000F99FCD33E8D9D3ECA567477307D57FAEDB
+:10BE8000B98BFBCF52FBEFDDC845BFC1795DA8017F
+:10BE900023C68EC15B499E9E4F089DC7F2067FEB6D
+:10BEA000ECA92034F0671D902F7F209E452E4FFB7C
+:10BEB00060780E1ECCF8FD19227FA343E729443B8E
+:10BEC0007CF4E30FDEA7E632B669BD37137F3A187C
+:10BED000CB662813B2E9F7901EBCCF93C3D8B3A8A2
+:10BEE0004AE8BEF7076763B957FC9EE7E0C71F241F
+:10BEF0003BFC5BC7D93D03E2ECA307C788B33F7B9C
+:10BF0000CA65477FCFD1AF46D8111E4785DFCBC367
+:10BF10000A0DF83B1CE56AA101F5ECF138E7215464
+:10BF20005379C9E0525CB77B1EE5915F6FA0DFE1FA
+:10BF30009BA3F0FDAFAC97ECE2FAA0F74613EDA798
+:10BF40008EE93C2B903F7A95BEC710CE373DFE144C
+:10BF5000E9A95E7B5F1EC2AFFAF1BDBCECEC7B4C85
+:10BF60007147940D1C3E958F3F39DB6FFB5EE133CB
+:10BF70001BD7110D9FB9831D7C5F11F4E4A21D2016
+:10BF8000CBC7AA3DF514572CF70CC3751CF59A388E
+:10BF9000FF7AED8161E437F294CE8BF0FFF40C363A
+:10BFA000D0FAE7A2DE443FE8427D20D6EF159E1F7F
+:10BFB000CCED3DA213DC672EB0D2BEE0988EDFA39D
+:10BFC000105DDFEEE2FBA3CFE2DC879C28BE57DCEE
+:10BFD00054FFEC0BD05FEF5A0B75DDEB1D41F658AB
+:10BFE0006F13401768BAF754D339FEDDE41620A169
+:10BFF00038EF2DF82FF8FE6CF79D5FFC06EA7FB056
+:10C00000D6EA261DE21845F05B282A2F4E3593FD0F
+:10C01000B4784E6E05EAC55B44BCF056BB9A4E61DF
+:10C020004335D9E8807E96DB0A370304D9CAB46A5F
+:10C0300023FE64534DCE1D9BF1B97AE87623F25866
+:10C04000DD987D9BD18CAD07162E25F9177AA7199F
+:10C05000E675DB3ABD8BEFE7E4F9DADA6F94F722A5
+:10C06000E9F798C84F0220D07E35C9A568F649493E
+:10C07000824E1F182CE23163D9D84BDA78D74EE4C0
+:10C08000A3B38BDF191E271EA1FD2EECC7DF8A7B11
+:10C090009EA3EF4F91E33A5C7CFF75CC089489F640
+:10C0A000E442AE07C6CDFF7C4329AC7F5CB7434773
+:10C0B000790DB7D5BF8078B8D025F068605DC84FDE
+:10C0C00037F9977CF01B424C9AE6DCF095F4A5BB5F
+:10C0D000C75119A92F4B42DECA487D39A1AFAD1215
+:10C0E000F5A2D48FC1E61A218F9B488E1E6C5E4745
+:10C0F000E5C3CD7E7A1E696E15F2B88DBEFFAA79B2
+:10C10000A790C701218FF7D2FBEEE6F9F47CADD9F9
+:10C1100047CF85A9BED7116E328E3BD7ECA3BCDCCE
+:10C12000430F9B18C6F12E749B288F0338E2B1474A
+:10C13000D2304FC944E744A3F395A2E57C3F3D7458
+:10C140000EB8B7E56DE4F7FE3C23B41707C7A7A701
+:10C15000A3CC6547B9F4F1E0F324878EBA5C76B4DA
+:10C16000A74F3E2ECA1E97DD00E53F0DEE25FD715F
+:10C17000D4E7B29BA0FCC9E3BDFCBBDF65B740F9C7
+:10C18000D3C17DFC7B8051D0FFECE02F488E9533EE
+:10C19000E520F247A5397F2AA80BD0D7E507912FD4
+:10C1A000A6672E998A7CB160B08BE872A66BFD41C0
+:10C1B0002CCF1AD9AEE215151E5BE1466C5791568D
+:10C1C000AD62BBA939776CC476D3866E5723DBCDBD
+:10C1D00018B36F23966F70B7AB689F2E4039561A0D
+:10C1E000EE4796E57729A7653EDDD5DD5ED207E30C
+:10C1F000BABCA40F245C2AE6566F42FF676397E23D
+:10C20000C0DFA5A998ABF4273360EE6203DE930A82
+:10C21000F2FAFF3DAE77AC87753662F91A2AB7ADF0
+:10C22000FF06FAED7F00F6E231E800800000000032
+:10C230001F8B08000000000000FFD53C097854E582
+:10C24000B5E7CE9D2D64924C360842E2649924965F
+:10C250002C43B6261064480CEE3001F944651910E1
+:10C26000C2164804EB17AB7E191A17E0698D6BD123
+:10C27000AA6FC4B5AFB6E461D458091DAA52D287DB
+:10C280003A5510B47974A488F0999011DC78D2C72B
+:10C290003BE7FCF766E6CE248014FDBE078693FFDD
+:10C2A000FEFBD9CFF9FF5F008053F8B3027F603403
+:10C2B000FE38253D8C046804F167BFD16DB295034B
+:10C2C000AC34078CA0A32F41A3AB1060AF0E9676C1
+:10C2D0001400A424C3FC7A0B968DB0740B96E75D12
+:10C2E0006803480568DABA206E8185DABBE36660C8
+:10C2F000FB4517E2AF38CE52056E54E0930AD49B4B
+:10C300009C89344F9A4DD21FCAC76F8550784A0610
+:10C31000E8B79A3DBA048044937BAC0DC7ED9BFB14
+:10C320004E835887AF88D6316CBD1EEBE300326C6C
+:10C33000561E1FCA8219545E09ED46C846B8F5CF8D
+:10C34000FBA422DA97C52723844E435F205FECF9D4
+:10C350005416FE63063D54E07AE9036E6999D7707E
+:10C36000206056EAF1673974EC706622DE5ED47E96
+:10C370006F04BF18BF43FB7D15E28DBE377569BFE3
+:10C3800003545B0F8D433002CBB8DFD912FE5E85BC
+:10C39000FF0D8F874967C0C3A4A1F010B51FF01A25
+:10C3A000418EDED70ACB6EA673E4BEC09DCAFCD117
+:10C3B000088121F7A7F245F4FEDA05FEF502FF2514
+:10C3C00036E7745A5FDDFC389053008E6D35794D39
+:10C3D00099DCFFA93D2944179375832D9A3E5B5B39
+:10C3E0006783DE00B0ADD5CDD0D7BA14F476803FE8
+:10C3F000B53673F9ADD6162EEF68F530DCD9BA8EA6
+:10C40000E15F5ADBB97E57EB462EBFDBEA65E86F8A
+:10C410007D91BF5F3B7F6586DB124DFFD5C9CE4561
+:10C42000C48F9E7BAA13993EB8F753C8AB9E1AC817
+:10C430006FB644C30183659D94C0658F11F7E1D940
+:10C4400016E36DC37DFD738CBB89C619A8097EAD4B
+:10C45000437C434A80F1D030D2BD9ABE4B461C3A51
+:10C460008966F5E412FE0EEB3CBF0764D9569BD3F8
+:10C47000A5473E381A8F551700DC82650FCEF3783A
+:10C48000AAAB85FA417EC048E39CA23F93717C0928
+:10C490006677F03A10A21C0EC408E8B1492C8FD17F
+:10C4A00050C8DD40BA9FF960E0E91319B68233CB7A
+:10C4B000C570F8A893AB039E32A46765ACC384D55E
+:10C4C0007D12F8A412845346D6008ED3976ED413EF
+:10C4D0009C14445650C7C39FC9DF226386F1CB1416
+:10C4E00048D4946BCDA335EDEBAC999AFABEF45CCD
+:10C4F0001EFFD2B48B34EDFA46579AC5BC532F2396
+:10C50000D865746F5C80740956991C9BB0FEBD9809
+:10C51000F822280698161BBF89E07B31195E6A371E
+:10C52000EDC0C914C07D4E937D238B105597DBC69B
+:10C530006BC7ED995363C37657E65769D721C12579
+:10C54000B4DFAB1D5334DFA7575EAEE9EF32FB9388
+:10C5500008ADF5CE7ACDF7C696AF419F0C30B1E568
+:10C5600024E84B01C6FB3A34E394EEECD2B41FBF8F
+:10C570001B6412EB927D8E3709961F74CAC42A156C
+:10C58000879BDF2458F5A53F83F6014EB059519F94
+:10C590004B8ADC8347023D962729E5CAA0B72D8147
+:10C5A000E87012F2F548BF8930C2216363A9F2BF77
+:10C5B0004E101F4C5220003207F6AB164B80793AD2
+:10C5C0008BD798456A05E51BF5C106C991A6473882
+:10C5D000470E5450F928048A08CA3A979EF86B2AE5
+:10C5E000348FA5B209DC69043F4874BF4F7CDC2F4F
+:10C5F00005DAC4E282C9C4CF753FFF68DE6DAC17AF
+:10C60000621C265CDFEFBAFE914A6BFDBB3FF591E1
+:10C61000376C217E6FB27ECD7852CB8D2DC7197FBE
+:10C620006AB96F2DCC77E192DB0D689F1036FEAFB3
+:10C63000CC760AEDDA3AA25323FCC9B8BA20D41E4C
+:10C640003ABE18C47731EABF7A5AD304C2D7DF5D45
+:10C650004E6C576F1072089E45F54E1CA73E46293A
+:10C66000834FD4A72AEDA1B29ECBE96A7D95686F6E
+:10C6700057C77B58B41FAD9695F12E52CBCDA29CD7
+:10C68000A9CEF7A02817AAE5FF7071394EB43F6113
+:10C690009B55EF2908E9FF53AADD180FE3C96EA0E7
+:10C6A0003D9033C91E48BB1A981FA2ED85B65EB1F6
+:10C6B00017F37F237B8CC5448FCB63DF21B9EE90CA
+:10C6C00080E4BAF17683D38BF37F9ED451B4C61243
+:10C6D000C2DFE7B7087CBB6AE39C32B65FF96ADE6B
+:10C6E00026E223396EF7C885F8DD3A56C77AA74E99
+:10C6F000B63881E87BAFD0FB6AFF48D8D0F2868697
+:10C700009E51F5B2C4F3C16CFCC1F9FAEF1BF5F40C
+:10C7100006C2598E3F9770939929F4DC48D4AD95A1
+:10C72000F8F336EA5933D23D251B9C3A6C9FF21A36
+:10C73000EA67A2F141BFD0C7AFC5F824149C958F1A
+:10C74000BDC9F66FA18C528EF87B2DCF9D97897C49
+:10C750007A34CE9F4B7CDBD0B28DD7758DDDCAE3AA
+:10C76000833558108ECFE2CC28FC979E01FFA53F61
+:10C7700026FE718203A4CF752874B4BEE596B778FF
+:10C78000BFCB95EFAC5F3243EDB82C47978FC639DE
+:10C7900032081F0E854E0774B60A055F5713BEFA9E
+:10C7A00017FB7313B1ECF0F947BAD93EEC2A97881E
+:10C7B000EECD7140743F2AF98BF60E41FF8ED60EF6
+:10C7C000B6CB5B5ABB18BE8473D0BA557CDD108DD6
+:10C7D000DFF967C0EFFC1F13BFA3F401A303FBAD98
+:10C7E000DA073C4E85FF8011C2F44C2BF125E2277D
+:10C7F000A14BE2FA3AB92021A0A98F13FE528E7301
+:10C800003CF1E9CA19BBAA37482179981C0B1D31A4
+:10C8100049CCD70E85AF1DC4D72AFF223F96EA1117
+:10C82000CF6F9DC47E43E037C4BFC0F3A878BA3B46
+:10C830001AAF1B888EA7C1ABB6FE07C66B27FAC717
+:10C84000A43782AFC478376546E3F9770A5E557C32
+:10C850006F53E47F383C6F233CA79E7F3C6FCBB483
+:10C86000F1B891F81ECE3E45D2475DF710725A7E60
+:10C870002E723A2DDBAAF8DFE8771646D3FD6DA2BB
+:10C88000BB5943F79E33C853CF8F294F91788B8480
+:10C890008D12B83A2CD1DF3FCB1C56DF9D173C4E92
+:10C8A0000ACED6F86793BF756BFCB329186169FD92
+:10C8B000D89B34E53AEBAD9AF697A6ADD5D45F6E2A
+:10C8C0005BAFA9BF32FF014DF96AC763117EE6D3A2
+:10C8D0009AFA7AE76F34F5739BB76BEAE7B7F468B7
+:10C8E000EA1778FEAA29AB78DCDA0A1C2F6D6B35C3
+:10C8F0002BF1D3650CAB03FE5A12838B0F07D9DFE4
+:10C90000ACF4B7D7B24BB2AF83FDD1329FAB96C276
+:10C91000AA8A9DCD6F12F4B55A95782D8DE15BAD45
+:10C9200036D6EF3B5AF319EE6C7528F15A25C35DE4
+:10C93000AD4E254E73318CB40BAF66BBA764213D61
+:10C94000A6BDBC4407B880E97FF867C15E5ABC77D2
+:10C95000BC8EE2DC35CA5E8E577FB3FF36E4AFE3B0
+:10C96000CD2607957BB71F31D80AA3F965EEB732FC
+:10C9700038C3F86C6ECB5F0DE467CD450FBA630822
+:10C98000399D9AA5637E20F703502FCC368321056D
+:10C99000F5C1ECD992A30DF8BB079218FADC583F09
+:10C9A0004D0F3E1396EB2D7A9F299E97E632A33FBB
+:10C9B0003D4B2C134C7AF0503DA424739C7E0D7D8E
+:10C9C000B4A13C3865B818BFCF223F1CFB5D6FE9AE
+:10C9D0003090DDBD6EE72FFA6FC37AB8D353CEF136
+:10C9E0003D5C6225FD2D793ED69D1A37BCBC2035B5
+:10C9F000E150185F4F25194EA5F8D1E17752DC7A46
+:10CA000093C1F19C2DBADF05CA7EA7C912FB6FC185
+:10CA1000D74DDE4D52483E717F3B4DB8CF26E201E7
+:10CA2000DA67B3C19757447EF676F6B39B2AD716DA
+:10CA3000119D9A2E913E311585E29DA6962FD98F94
+:10CA40008FD4CF91F04CF190C36F65FEDBDFBA93CA
+:10CA5000F9458D8B7A5B7D5C2E0BB86AC3E3A339F5
+:10CA600093FF4DA6B8A7EA4B11FF4C3CE9DCFB5302
+:10CA7000DC77A0D5FF2FE517D4BC829A6788CC5B02
+:10CA8000A87A64DEAD75096EDCEF9A2C5106F3943A
+:10CA900074A6A35E4055DFDE9A156597EFC83ABDD0
+:10CAA0007ED6D6FFC0FAF96CF9BF314DD8D548BE55
+:10CAB000DF37E30503AD53E5EF48FE9F437D70FE8E
+:10CAC000394D92D7837A7AF69276C344E9DCF97DC0
+:10CAD000B9E5A0888B23EDC2F7B60736A69B5C2B81
+:10CAE000737C61926F72501E44A5434734DD3ACF88
+:10CAF00040B7CE1F936ED176F1E0BC73B38BA0F13B
+:10CB0000CFDFCB8AF2273EC83ABD1FA9ADFF81F720
+:10CB10006D1D6B63B87244EF3C5927EA457C620196
+:10CB20001DF2EF8057E6B87469667B3CC533501937
+:10CB30008C277DB7AC5B06F20F41EFD48F46FE5CCD
+:10CB4000A2F0671FF83E247E5C05F77E4109982518
+:10CB5000D54BAE223DB7F40943084FFCAF93F32702
+:10CB6000AB947ECB2D9D46DAEFF267B5EDD4711A0A
+:10CB70005F8AC81F575FFA19B0DDF073DE6F55A7E3
+:10CB8000B6DF77597129876259164B08EF67D2A72C
+:10CB900047C9AE1BC2CA275B39BF203FF3E0039EE3
+:10CBA000B121FAC46447F1715CF6E9F9585BFF23DF
+:10CBB000F3B11CF7AC91E8F97DF978BFDD9945EB4D
+:10CBC00056F5F3A0DE79C3C47A67A0DC26F2A43759
+:10CBD000FDAE2D9EF8E40438881D162AF9D2856A28
+:10CBE000BE749D365F3AB9CFC779B94907BD6D713B
+:10CBF00048F789BD1ECEDB55ED76B759B0FCD35D45
+:10CC00004E99FCA3F16FB9645AB7EADFA8FE4E480B
+:10CC10008FE5B0BEE3BC6BF6D9EB3BD52EAAF63060
+:10CC2000D20E5606DB6BC9FE4DF8B6E34D82E72BFC
+:10CC3000AF1E69F7DE8B137AE2A8C157BE97FC8C52
+:10CC4000D7631CCF41F4FAAFCB167EC64CCF02039C
+:10CC5000CB1F091FCADB0C456EAE4F765F974DF5B3
+:10CC60008ABDD0999D06B2A37572DF23D7125FF9F2
+:10CC700065CE1BDE7CC707BFFFB5EDCCF98526EB83
+:10CC800071F63F868B339A74E0A6F8A2A4D6564A72
+:10CC90007E0CC56D944754F38A91ED9FB0D7ACC814
+:10CCA000E63C57B5DF49EBD928D6331CBD9A5ABEAE
+:10CCB000D0E431879BBFA9BBDCBA304C3E5ECA16BC
+:10CCC000F12ED2DB7AC81CA2F7D9F2C5FFB7F865FE
+:10CCD0009A0C1E09ED6CA1E415FE2F083F780EF8A2
+:10CCE00019CE8320433758F97C6A2138182E021751
+:10CCF000C37CBBDB4B7C3360088E24BEEA7FF5BB74
+:10CD000002E29BFE8B27B657C1F93B5F8AF4FF0610
+:10CD1000C6DB78FE8157BEDB43FC397087E1ACF49B
+:10CD2000C6EA646727F151E479CBBB53643ED7016F
+:10CD3000FD7A968B7AABE80397A4721BEBD84CE68E
+:10CD40008B90DE1CF5B4AA371760BFC24F74ACD706
+:10CD50006099E4B563D3AE808E45AC7071A657A6DA
+:10CD600072A7A82F5C99E895B05C581523EA6F4A22
+:10CD7000F44226C5430196CBF900AC0F1780D08B47
+:10CD8000378293F78991419684FD176F3597703EEE
+:10CD9000160239A4FF8B288E1A224EB7E608792F87
+:10CDA000CE12FABEB8469B17F9305BC91BDB6B4A43
+:10CDB000721056E738F7121D8B93FC1B1E2AA37CBA
+:10CDC000900E36A17C7D56752B9F77AAFD1AED3506
+:10CDD000BD84BFCD1270BCE2E936799F13E78C2386
+:10CDE000C3CFCDF2EDB507A8DD115A7BF9F078C5B8
+:10CDF0007E1CF747CB9587D7574CB11BE7FBF14318
+:10CE000025CFCBE5FF79E6EBFA3B0BF84CC1437E2F
+:10CE100072A3DD7D9CD76F04B0D0FA9F14711440CB
+:10CE20007306E547973C65D2919FF1119A63C80359
+:10CE3000F81BC6DD04FF1BE367827FC7F899E02774
+:10CE4000183F13FC07C6CF04177F3B1E8322808D3B
+:10CE5000394E4B4E79E81C3072BD861C81CFC1F92A
+:10CE6000BB8D3C7F9DDDCDF81DA4F7EBE0A573994C
+:10CE7000CD89C10B924EC36F03DDDFF0F9E9707805
+:10CE800051CF2523EBBF53E85AD4A967FB5FD415D4
+:10CE9000886F086B77418E91EB0B5F39184FE31F5A
+:10CEA000B50EE2D729E196A7E944F982672D330848
+:10CEB000BF75766709ED1BE53C83F651D4F5C18358
+:10CEC00013CB787CAB64A375041FE5B821621F9176
+:10CED0007850F7B539D1BF81FA6F7E258B76827A8B
+:10CEE0000784DC101F4943ED772DF3CF7453B0CC8A
+:10CEF0008AEB9D7E4A6E1E0AFF75F6298CE77754F1
+:10CF00007E53CFC715FE52E976AEF21D391E906BE7
+:10CF1000847EE76AD2A536B24B27E3C92FAC57EE21
+:10CF2000197475E6BC47FBF4EC94C16E633ED6C839
+:10CF3000DF62855F5458D86D7411BD36771FCA59AA
+:10CF40006461FAE42CC6F6B372EC9ABC6761D589C9
+:10CF5000C71F4AE1F6569AEA3A78BACE8AE3DF600A
+:10CF6000DEFE366D69AEF593BA442CCF4F93761042
+:10CF70005C60CB9C9A64A3E57A79FD37E64FD94192
+:10CF8000227595A39EFDB929A464C2EC43AD3996E0
+:10CF90000E1F07CB75D6644DF9D2B4319AF697DBE4
+:10CFA000B235F557E68FD3D4ABF35EE528D5B42B75
+:10CFB0004E0A66515C87FB60B980E764AF5DA27D75
+:10CFC000EFBE621C96A73D3FCB416ECA66A57EDAD6
+:10CFD000965A2FD16300F1694487EA70E5FA471F3A
+:10CFE000A2C122E286C6EE6776386DE710370C13D1
+:10CFF0002FAC00718E3F5CDC10192FA0FE7C90F4EA
+:10D0000067F1ABD758DB70DCCD55272EB0E13EEF92
+:10D01000CCC13882EC8D12470CC73F837222D904F1
+:10D02000FFF4C8F0DC10FC03F00B851F059CF63EF6
+:10D03000FA3305DF5FBF7D4AFA8DF3071EC5EF5750
+:10D040006044BEAFD8E8786F0DE5A7DE9181CEF9D8
+:10D05000E124AE03EB1BE87739C4F7B0E8E9BB463F
+:10D06000A7F0770FB9A6AB94FCDF1F7314BFAA71AA
+:10D07000FB5DA3CB42F570F3279AF670BB74B7A69D
+:10D080007C67A6B67CEF94BBC3FB0FE797356C5C5F
+:10D090006074A39C363C2C39BD43E88BC1F5A428B1
+:10D0A000FAA17B09EBDB43DB97196D71D1ED57E1F9
+:10D0B0007894B76C18C6DEAA7AEA3A199A87AA7FDA
+:10D0C000479DCF717EE7FB08714FF6CDF39AB0C351
+:10D0D0001F25B88DE17CB22F479C7BF43FF6C01D25
+:10D0E0005FD379EEEB22BEEA4F14F6A3A8F3339D8B
+:10D0F0000E61F108C15F45D6808EECD2C0D2580FC8
+:10D10000A09C352D8BF3E88AC98F087E681E4F5E80
+:10D11000C72D0F9A91CE1FEB741ABB3C40C11696D7
+:10D12000FB9EFDD98C3BE9F702712FE97CEDB32F13
+:10D1300007847DAD117A631EF19F62B7005556D307
+:10D140005D3068C748CF105EA89C6BBFF5FD87C9EE
+:10D15000CFEF117A83F20A37B05FE0B468F30D1DA8
+:10D160002CE7F8BB2DFC3ED759EB8FB7DA8D96F341
+:10D17000A84746D8B5798721F4C5FB57223D9B5E69
+:10D1800097F95ED0B1ADF60408D31F91786CDA2818
+:10D19000B39CABE5A35BE5CBBC6C0F8319F585D1E4
+:10D1A000F806A783E57FB555CCB77AD23733C84E9A
+:10D1B000AFEED68B4B2FC3CDB34E065BD83C9BB79F
+:10D1C0009996925D53D73F6055F449F75749530AF2
+:10D1D000045C3B847D45BFC090427E41BDC4F1EC00
+:10D1E0009EEE513584A73D12F86C253CC435665C33
+:10D1F000DF4C311C7DB7505E14D2F2F99EA51AD7D0
+:10D20000AAF1ECACEE5976F2633FEC5CB807290763
+:10D2100093ECD9CC4FD78287FDEE3D89AE74CA938B
+:10D220004C53EE3FEC490CF691BFBD6752AC44F74E
+:10D230001970FC3B697C755F7B0CAEF466DE9792DF
+:10D240002F75FE443E157BF671A2AA67EBE4DBA7BF
+:10D250005C49E7F773C04AF1EC7459F8D5F04721FF
+:10D26000CFAA5E6D92FC496CAAED33A6DB114FA3E9
+:10D270005A7EA9E47DDB35F700CFD6AF1E8CA35FC5
+:10D2800094987F563944BCB1AAFAF347AEC5F95712
+:10D2900061BC4FFEDDC2AEEDFB087F91F1FD607C0D
+:10D2A000F52FE67BA3E333D732DADFCD771CDF73CC
+:10D2B0002D44C769837181EA5F3E17CBE7D6A85832
+:10D2C000857C28FC7A645BEEDE35587FE42F0666A9
+:10D2D000D73727FDEAE8AD58BEF9B958C6F391240F
+:10D2E000F0901D39B229CFEBC1064B74C15EB26F0D
+:10D2F000B0258ECF693E7B32EFB72F517EF2B776E5
+:10D30000F643487E6CE8C27C46F78FE8FBCBA3B9B6
+:10D310001FB8C5BC0D8A5CCA2F14DE5F4DF52F24E3
+:10D32000737E42A5DFE127639C14AC7D05BE222BF2
+:10D33000B2DEE792E710DD5B5CA17B69BF847CF91C
+:10D34000D508F706DAF7F2C7FFF3C389B89FDA17F3
+:10D35000AEFE5515AE6FD907A940E384E83AB4DFB5
+:10D36000706C6BB6907F053F2B5E8CF11E0CD32743
+:10D370002B3B1235E5A6AED1DE83617A68F09E7252
+:10D38000A3C4E7048D8A5CED37BADBED94D7A5FB27
+:10D39000A94C3F711FB584CEAB08FFF79918FF91D8
+:10D3A0007CF6A25D396756F33CC9604E23B9750B14
+:10D3B000FC0DDC97B789E2319F3D49F13B82B933DF
+:10D3C0000AC3F9B377D51B9CE731897B8F31439F23
+:10D3D000EB77DA13B97D83F94B4D9E6955CB094D37
+:10D3E000FE675501B01F50D2662BBD89CE8714BA97
+:10D3F000DC9FEE7A8DF1DEF1C0ABBB189F4FDCF203
+:10D4000031CDBBD3C2F4835D4A3C16116F3598BF52
+:10D4100050E4EF698D7F7EE8B1BD4594FF38F4CAD2
+:10D42000B822CAD32E94FD877E9DC9F79CF6DF866D
+:10D4300070CBCEF7392F1EB9DEA87B0C92D0438D6E
+:10D44000B48F64BAFFE37AC7CE722EF4C3810D8520
+:10D450008C3F351F3D7064E878505DA73ABEBA3EF8
+:10D46000757CB5DDDFEC225FD06FF41791FD5F4175
+:10D47000E73061FBEA8FF717255AE8BB55F81349E7
+:10D48000580EE3B77FF5BC2AF27C6AF05C56C947B8
+:10D49000EDD3ADFD9911F9AFAFE321833B5CEF7E96
+:10D4A000CF732A75BDEAFDDA7EAB85FD9B937625A9
+:10D4B0001F9F0EE9D40EEB1D3EF2BFB7981CE4C7C8
+:10D4C000279A5C908BF86934FAF8FE9ADA2FD1E447
+:10D4D000E6EF9179F9814423D0BDE58154E5FCF76D
+:10D4E0002B60BD4271E8169CB7AC56D7BCC512D2B2
+:10D4F00087AAFE2C1B87DF0BE81EA93EE42720DF4E
+:10D5000094156BDB87F6A32DFF7BAEA06359B26E3B
+:10D51000C838B92457C8651B74C8429E851D9DA88C
+:10D52000E01D0DBF1CEED7AC52F4FC40BCD9430744
+:10D53000BB13B78A7BAB13F5BEED04510B404B1206
+:10D540005D99F489F1BAB4FA9C6CC81CB6CBE3D8E7
+:10D550002E4F50C87DB7D4CCF75B43F75CFD32C18A
+:10D560008B21C8D009563D412403C34BC0C5702A46
+:10D570003433BC0CDA195E011D0CAF023F43F8894D
+:10D58000AF0DD81EDC6E65FFE9F2253AB2CB65D748
+:10D590000EED97CF52F0353C3E50CB579C3B3EA60C
+:10D5A0002AF77287C5CBD87CE67B152F26E24FEC95
+:10D5B0001703DE34829320C0E34C2646CEA678DDE6
+:10D5C000C6F77E6BC1C9E5BAB3C44765C0AD77176E
+:10D5D0000C8197DAA1F9649EC22703B9C0F851E91A
+:10D5E000F548AE8DCB2ADD30504C237B104D4FC813
+:10D5F000A07596C5D61CA7A722B73F5F36538F7A72
+:10D60000B4ACB4660DA9905FE64E15E589352FD30D
+:10D61000517DFBF3978A72714DA9C1815EE8DACB27
+:10D62000665E82FAD9ADDC2737A311A07B6372B6A0
+:10D630003817762BF7CA4D72E65ABA2F66BA0D58CC
+:10D64000DFB86300FCECD722B791BCB8451C7BB3B4
+:10D6500055D0AF3AD67D4B2ED933B32FDE8674B872
+:10D66000796DDD28B29BF718C5F89FA4DAC6BD8195
+:10D67000F83299C4BD5675BF58EF89C17240B2AD3A
+:10D6800069C90CAD4B5DC759CC7BD7E9E6CD4F7767
+:10D690006F203D023607C7156314FBBE65CBC4344B
+:10D6A000F430701D565E47202E774D0B56DD91EEFF
+:10D6B0007A84C61B88137CF808D1297578E8CB7565
+:10D6C0003E943BC4F781B5DFBCEA23BDF4292E04A8
+:10D6D000C7F94DAEFB715A47932E90518AF4FB4522
+:10D6E0002C7A000521BE96909873100F6D4EF01A9B
+:10D6F000595E947736CAF9992A17038B713CC44F47
+:10D7000099CB558BEE2254CC6E7E9360A5BBBD1693
+:10D710006B689E17683D4D72B081F8E468E207C6F9
+:10D720004F596EC70AFE54F459F7B69EDBC688A25D
+:10D730000BC2E4B269DB89AFFF86746F3A66715041
+:10D74000F3903C3EB6469CE75A34FA4695D3095DC1
+:10D75000263E389CB8F5A2C5D46ED207BDD9A4B771
+:10D7600027F706DAC87D1EE8DE3B46C889EAD77F80
+:10D77000239D8B7DF9CC8CFC914010F9235E9C831A
+:10D7800073FCF48A38075FADE43DA9ECE17D8B784A
+:10D79000548D3B57F6BC2DDE8579F06F05BD2B12FD
+:10D7A0007F963E71E355C46F91EF8BD478B449698D
+:10D7B000B7A2D77B37ED27F2BD5113C5A345C3BF31
+:10D7C000376A7AA296E3D1C8F746BDB94AFE4AB194
+:10D7D0008FA0F8A14B9436B43F0BC78746AF09F72B
+:10D7E000B6FAC9350E2B95D32D0ED6C7573D0EE18F
+:10D7F000EDE18964E619559E97AD93D8BF56F15A6D
+:10D80000FCBCC949EB287E7E14FBCDE8EF8B7BE99D
+:10D810004A3E91DE12D07B83CD89C12CBA67BAB95A
+:10D820003BDF41FEF81F5A9DF00F43687D6A3C5074
+:10D8300027BF544BEF878E2DC2380B3FADEE79A634
+:10D84000CD8CE5D5EBE95510A584F313C8AF2ADFDD
+:10D85000298397C601EF43D5083B153937A5E9C0A1
+:10D8600016868F18DB08B00D910F3029F48BCD4F41
+:10D87000D2D4C7392ED0F44FA8CCD2D4B7C588F7AC
+:10D8800032E071FA0B2A42EF48129D3FD1F4830037
+:10D89000FEAD08BD17B9277EEA4E7E4FE26FE03C31
+:10D8A00045F265259AF62679AB4CFC5DFDA55E43F5
+:10D8B000CF9F52A61BF156B91BFD1C9C67429FB619
+:10D8C0003E26E001EA17B35BAFC94B986CDAF285EC
+:10D8D000794A9E622C8CD5E42906F12EF8FED86197
+:10D8E0001DF34505E4FCAABA8CF06C00AF2D1A6F4D
+:10D8F000C740F85DC7C65A1CF4966A42CFCB32C9FE
+:10D9000041AA4B8BFF51B3B5F81FEDD6E27BCC5249
+:10D910002DBED39BB5F8BEB0458BD74C8F166FD9B3
+:10D92000EB2668DADBDB6B34E5BC8D5768DA5FE445
+:10D930009DA1298F7BF17A4DFBC28E859AFAE2AECA
+:10D94000E59A7A95CF86E383F1BED511FCA603DD77
+:10D9500069F8A074E7CF35F3FD50F49F9FA7E80561
+:10D9600085FED72B76E5DDF8C3F792B84E8B157A96
+:10D970007030DF506DE078EE3D5B726D1CE905C5DF
+:10D98000DEB9147B07394F89B255941D7E71BFA251
+:10D99000649FAB36DE46F72CC4FD8A8AC3EDB50919
+:10D9A000D43EE21DD6F44A4973DE1DF92E6BA667FC
+:10D9B000AD9C20D1BD44713F31F21E84FA3EABDEF6
+:10D9C00019A339271FEEBD969A5FC278018C142FD8
+:10D9D000E8CCFC3E31DA1F726C94D95F73B3FFF66A
+:10D9E00067C9CD79A76BCCFE0CE2EFECB1EEF5790F
+:10D9F00088B7A33A878DFD3DE5FDD6006D8CDF2FFE
+:10DA0000F5CCA43CE90086BB94D7D4DFB36326BD34
+:10DA10005BC4E55B031522ACA63F8FE6B91FA4717A
+:10DA20000E48D6BB4BB1EFBB133ECF207B66A27333
+:10DA3000FE123EFF7E382FFCFC7B14EE0FF56D408E
+:10DA400067F3F079EECF258E533EA7C1AAC2E477E3
+:10DA50009D41794F2AE2B6B90ABED4B86D8E32FF25
+:10DA6000011C6229EAF3B95D7F66BCAC48EB53E266
+:10DA7000BD668715C7BF71ACA584EF7B394B1D22EE
+:10DA8000DE57E3B831F2F7B1B367BA87B522ED8854
+:10DA9000269E86979287CC5746E6C542FB16E31F23
+:10DAA000581FCB76E8C0FA74CE3F86C63FCAF985C8
+:10DAB000B9CDDAFBDDF35B3ED2F0DF02CF279AFA75
+:10DAC000404AD03006F71F7875F4D41B107FFDAFA5
+:10DAD000982A289E45BAF5E49587C60FDC97778982
+:10DAE000F01BCEB4CFCF791DBDCAFD5A759FFB5B2D
+:10DAF000F77139D01A88B8EFE4D1C4BF2A34FE09CF
+:10DB0000F2C98F0E4A231C43E57366E78B38A95789
+:10DB10007977DAABBC3BED55DE89F62AEF427B958F
+:10DB200077A1EABBDD5E099C74BF648EE47A6A81EA
+:10DB3000C4EF760FD13E9B96078BE85D635371600F
+:10DB40009E24F3BBDD23F47D8877BB459295F46971
+:10DB5000EA35F46EF7F008CF51B2D8D9F989D75029
+:10DB6000BC70D828E4A3F4C56F66D27BBDC753DD73
+:10DB7000C789BF3F95641FF3F3EB129F2B8333607C
+:10DB80009C7116EF7ABFCB13E73427F3C4B9890A27
+:10DB900047E60BBD564AB09CE8726F2EBFBBDA68F1
+:10DBA000E27757389F5317761F22F27D5CC91F4DCD
+:10DBB0003ED21F6ADE27215F9C37D3BB395A67CA22
+:10DBC000FD26F16E2EE0CFA07776740FCA45F2BD28
+:10DBD0001B9CE21D5EDEA6F0F73009F9CA3DBD458B
+:10DBE000A079A7B7B2E7C07ED227AFE5B993F353C8
+:10DBF00043EFC756C66F677FAF20DFC6F3E27A797F
+:10DC0000FFA817EE24FA9CC77C61567E79F4FFD7F3
+:10DC10006038BCF52FF63F5A90197AF716F6DEAD4C
+:10DC2000203F2CAFA7AE3F34CEE9E542CD7BA9E53E
+:10DC3000438FDD934B72867411F948599A3F63887C
+:10DC4000FED3F305FDEF4F774DA0F997378BBC60FE
+:10DC5000886FDA6FF998E8DC6319F23EBFDA3F7239
+:10DC60009F2BB7F5303E709FF3687F61FBBC8CF053
+:10DC7000A5EEB3BF7BEFA305B673DFDFF77D776E4D
+:10DC80001A81716DD2507976B43E617E9949ED3F2B
+:10DC900056AFED8F0E39E5B1BB48DED16FE954E2E6
+:10DCA0001EB2CBC417AA5DEE54E22029B083ED0268
+:10DCB000CD4B7271B7E461FBA8E63BDA24B47F94E4
+:10DCC0005770AF617B215F6871105F7722EFF94970
+:10DCD0001EF4CE58CE7347C4D73F8B75DF4478BC53
+:10DCE000F9AF35A328FEDEF2972B94384ED8AB72ED
+:10DCF000853FCB697EDA474102F36D99B2BE0A7364
+:10DD000033FBC955E091455E43C993ACDFC1F1DFF8
+:10DD1000FF011A14AFAAD043000000000000000069
+:10DD20001F8B08000000000000FFFB51CFC0F00374
+:10DD30008A739418187A351818366B32306868313F
+:10DD400030883120E46885AF7153A69F9B9581810F
+:10DD50001788F981581088D73331306C60225EFF04
+:10DD6000115104FB9E2003C351207F1990EE1466CD
+:10DD7000605805641F03E22F40BE801003830C101F
+:10DD8000FF1561603005D2C1406C03C4C745F19BEB
+:10DD90007F82807CBC082ABF1B8D9F278C5FFF255C
+:10DDA00011FCF20F08C863C33216E4C74722057A94
+:10DDB00007023729A2F28FCA33303C546060D05139
+:10DDC00082F09B91E4ED8062C7E421EC2992C0B817
+:10DDD00007CAB5286237772A50FE0450CE4B8934E3
+:10DDE000F7DCD341E5AF3484D000BC3E14E4A80393
+:10DDF00000000000000000001F8B08000000000071
+:10DE000000FFE57D0B7C54C5B9F89C3DE7EC6E92B4
+:10DE1000DDCD262121BCC22601440DB8400CA04115
+:10DE2000370F5294A8E1A1A2226C782421EF22F6A8
+:10DE3000621FBFDDF088C4521B1FC5D48B7651B062
+:10DE4000D18B3640D058175C9E458B6DE845A0D5E8
+:10DE50007A13405E06B240A5B645FDCFF7CD9CDDF6
+:10DE6000734E36266AEFFFF6FEFFDB9F1DE6CCCC35
+:10DE70003733DF7CF3BDE69B8964BE91D88713F20C
+:10DE800025FC6E25E451891092184E9B3C93C69F49
+:10DE90009409B1ED7E24EA3B99840C9E6B7046D1C7
+:10DEA000A25F08644E4B0621C9658D7546FA3D791F
+:10DEB000917DBCE808C319987CE4BABD09840C7252
+:10DEC000D3F66682BF2FE97F3FB737C69174C87912
+:10DED00085A231E1FA4A9ABC48FA7B87AABE9B1414
+:10DEE00075A6DD48FBFB51FD20B785901FC3784622
+:10DEF00042A9CB40B2E8B8785D6F2EFD3F3A0EAF35
+:10DF0000CDE85B2910221A1CB1442424262348A002
+:10DF10009DBE9F673CEDD74908A736AAC84AE74986
+:10DF2000C8B49608F57289807888CD76257BE97823
+:10DF3000577D2EE2BC570D22A49DD62792D34E6862
+:10DF40003A95C461BDC72D2306427ED5AE3F120768
+:10DF5000851B9B19245E15DC060F210E13C5AFC768
+:10DF60008CE92A8F9DA7C9C4710D21AB3D0E4C577A
+:10DF7000794663FAD8D027DB7306D0F90C32D8E99A
+:10DF800048488363A6DD91118627C72D30E73809FD
+:10DF9000C92629AEC4545A2FD140C84D84DC42F35F
+:10DFA0007523081949EC8450FC3D93BC2CCA9D0193
+:10DFB0007907E6450371C37C6332032E91E22DC6D7
+:10DFC00069CF951CE1EFF81B80DF5F782C15D6C177
+:10DFD0007D1BCCEF19E2ECF0029EDD46E7265A7F6E
+:10DFE000A5EC4C5E4AE18A46DA2E83ADBB94101E46
+:10DFF000DF4CC01FED8FCCC9D5ACD730184722B449
+:10E0000073DC05EB6471B2755A097415611DE6F293
+:10E0100075586577D919FD384924FA11ED5AFAB1C6
+:10E020006468E98F7EB19FBA9EE769BF4D42ED3BC0
+:10E0300053E93CBD4B0CCE4DF4DB60A15100F80A16
+:10E04000BC25C480FD2AF9416552A063B41A9E170D
+:10E05000CBE9F7F60E73CFEF2D06E252E872532AA2
+:10E060007C77C4CEA0E3266647EC4C6BCFF187E902
+:10E0700024D925C940EF0E4C1B0447AC00E37C4774
+:10E08000249B049C7F72A4F6FFD3ED08F1E17A375C
+:10E09000F07554DA513C203D791F8B463C88503452
+:10E0A000390CE7171CCF17AD454F434A48E3685872
+:10E0B0005F9A5F87F463A6792BE69BB0DC1ECA3FAC
+:10E0C0008BE5C9AC3E5D5EBA18BDE3555917DA6EF3
+:10E0D00003C29142705E44389650BF9B303F2094FB
+:10E0E000FF25D61FCAEAF7B71F25EDCE0D9EC2F950
+:10E0F000BF2E3B009FC2DBD6C0AD942E0E6E107CAF
+:10E10000269A0FEC8C41FE757EFD0C9F89E267D745
+:10E1100038930BEA9FDF9883F9BCEDEFDB245A5E5E
+:10E12000B55D94206FD879D6D641F15B636A7FFCE8
+:10E1300066FA3DB85D242F6077D3719F9DE2B448A5
+:10E140003E63F9922896ADDAB06B1EC02D6B339109
+:10E15000280AA7EACDD23B6FA6F9D20332812A550D
+:10E160009BEA8C83697E894F6881FC8A9D1F603F92
+:10E17000DDB9A40CF6F739E05B942F75DBDA93EE8A
+:10E18000A6DFCB7D5B0AA07EF966C1094B5CBE7E33
+:10E19000D78700BFBC551E2152F815CD31C4A1DA76
+:10E1A0002F79DB17DF09E3AD7A472694ED91B2AB07
+:10E1B0000F199118A44623E0B56AD31346E09BE7F4
+:10E1C0003C07B01F059F552FD37E68BBEAD70427B5
+:10E1D0004CADDAC0F8CD8537A3E6BC688179D51996
+:10E1E0004741FB371F3542BD525FF1EB510E18DF3F
+:10E1F0000663018C73FD0663898A6F5634FF5633BC
+:10E20000AE534DE903DD19BDAFE739CEB7957C3983
+:10E21000154048DF92CF3843C5879E33C421FD5750
+:10E22000348BC411811F78DFE7FB608795F103BE53
+:10E230005E4BEDC01AC2EB75C9CED74F0A66CD88CA
+:10E24000C0E71EE7F2A391CB8F27417ED0F4692E61
+:10E250003FD671F9D1E471E2F7673D93305DEF711C
+:10E2600061FABC671AA63E4F11D67BC13307D38D26
+:10E270001E377E7FC9538669B3A716BFBFE2598E8A
+:10E28000E9668F17BFBFE65983698BA711D3AD9E8F
+:10E29000264C5B3D3EACF7BAA719D3364F0B7EFF39
+:10E2A000B5A70D53BF2780E94E585F9A063CED98FD
+:10E2B000EEF61CC374AFA703DBEDF79CC1742DC74A
+:10E2C000BB2D9BE448146F36174139185FE8CA919B
+:10E2D000693EBE88E593E67A738C349FE4A6798A1A
+:10E2E000C7C195811C13CD0FAE65E5293F24B966E2
+:10E2F0009A4FF1B2F2B4B5AEDC289A4F6B64E5A345
+:10E30000D67B73A3697E948F955FB739901B43F3D7
+:10E31000D7B5B0F2B17E9267A1F9B101961F7FD057
+:10E320009567A5F9F1ED2C9FF5A137CF46F3591D5F
+:10E33000ACFD4D5D81BC589ABF29C8CA6FB94AF27D
+:10E34000ED03402E0B98CFB5E4E4C7D17CAE9DE53C
+:10E350000B86164B8E08F4B753EE5808227C86B015
+:10E36000D125517EB3D3D8F110157D64A1F0AA4B0D
+:10E37000A2FC3320934550FEB0F03A96078C641906
+:10E38000943F2ABC8DE5BB650796FF5C38C0F2461A
+:10E390000796FF877008F37B651796EF10FEC4F2AF
+:10E3A000461796FF5E3881F9FDB21BCB3B852E9652
+:10E3B00037BAB1FC49E953573EED2FDFE09E2EDC22
+:10E3C0000872DB5D8672596A49067E59CFF9FF04EF
+:10E3D00040062DAF1F644439B8F3F3AC174581D321
+:10E3E000F600C897BC04FA0585335B48047D82C2F9
+:10E3F00011FB8673CB179334706EF9A24C81F32016
+:10E40000C289EA1F9C9D5FDCA41DCF17E50A9C1200
+:10E410009C97B57FF3BAE5CB6CED78BEAC54E0D4F5
+:10E42000209CB8FE8D27204FD4C009C8A50A9CE5C2
+:10E430000827B17FE37119276BE0B88C4B1438754E
+:10E44000086750FFE0048C376BC763AC50E03C8634
+:10E45000781ED6BF79B94C53B4E3315529709EC2AA
+:10E46000F1A4F60FCE6EAB163FBBAD21FCAC473826
+:10E4700023FB37AF5C9B163FB9B6107E36219C6BF1
+:10E48000FB0767B74D8B9FDDB6107E5E43FC8CE9C2
+:10E49000DFBC7263B5F8C98D0DE1E70D1CCFB8FE86
+:10E4A0008D676FA2163F7B1343F809209C1BFB3737
+:10E4B0009EFC242D7EF29342F87907E14CEE1F9CDE
+:10E4C000BD495AFCEC4D0AE1E70F08674AFFE695A3
+:10E4D0003F508B9FFC8121FC7C807072DCCD4CA96D
+:10E4E000A470ACBDC3D93F4C8B9FFDC342F83989A2
+:10E4F00070A65238E97DC32948D1E2A72025849F20
+:10E50000F308E7B6FEC1D99FA2C5CFFE94107EAE38
+:10E51000209C3BFA37AF82E15AFC140C67F8B955DE
+:10E520001A877286CA4E27D8E7DF199AE31232C1DA
+:10E530004E6279D1EE24A0F7888A3E43DA5D22AD9F
+:10E540006FD91C37FE31A2D66B728D064ACF56AA00
+:10E55000E5A9F59AD849D11A3D2ACE15AFC9274C5D
+:10E560001BACA99F5894A6291F38E73A4DF920F70C
+:10E57000784D7E48D94D9AFAC36A7335F9E1CB6F6D
+:10E58000D7D44FF5CED4E4D3D7DCAFA93FB2718155
+:10E59000A6FC9AA6724DF9B5BEA59AFCF5CDDFD7BB
+:10E5A000D41FD3B242537E43DB639AF27181273585
+:10E5B000F909079ED5D4BFB1FD054DF9C463AF6815
+:10E5C000CA27776CD5E46F3EF36B4DFD29C1DD9A08
+:10E5D000FCAD9FBDABA99F43FE53AB6F9B3FD0D417
+:10E5E0009F6A3FA129FF4EF2273A3D556B1FAFCCE2
+:10E5F00021CCAF3288D9AF01AB11F3C6C11666A7E3
+:10E60000584B1C2729FD18772F740CA0F4033403F2
+:10E610007651CEE0B26B3AE8F7EFDDE4BEC64EBF0E
+:10E620007FCFE8BEC11E41BFA1F4269064481D06FD
+:10E6300048F5E58FCA8CDE73875C1DD549DBD7189A
+:10E6400082A3E268FE2331E73EA0C7F90603EE830A
+:10E650006891D442BD681341BBE9D1D4AC17BDAABF
+:10E66000FDB06618D5338430DC35B23B19F528C3CC
+:10E67000F83AD09BEA87D1790D2664D18A71BBBC68
+:10E680002368FB6125C9E08F3019993F24D4BF91DD
+:10E69000F69F81FD2F81FE6B7AE9DF943649D3BF67
+:10E6A00039A54CD3BFD948FBB713F290E126DEBFA2
+:10E6B00019FD36CB564CC6FE4D2965D8FFA3466AD8
+:10E6C00077A9FB8F0EF5FF8881F6EB3130BBB9C718
+:10E6D000FCD36ED2CE3FA55C3B7F239BFF4A432EEB
+:10E6E000EF3F1AE7BF6A450E9B7F4A399BBF89C13E
+:10E6F0000DF56F0BE1BF01FAFF692FFD9BD2B3B59A
+:10E70000F31F5EA99DBF89F5FF94E176DEBF05FB8F
+:10E710007F7AC56D6CFEC32BB17FA3C9ED04FA31BE
+:10E720000E89AEF5D1FEC9506A250D0472A1FD40D7
+:10E730003A3A1EFD08771AD2701CDF8B66F47625F4
+:10E740009AD21BF2332FB3C37D947352BBAA9AD3D0
+:10E750007AC5E61C23F03D2C4F2264311FEAA23615
+:10E7600011E99B3C6DF28DA4E3BDD0267A21BFE870
+:10E77000E9293EE0AF352632BF08DA492400DF3F01
+:10E78000FED99817D4F3D2A78B1BE55391FC45DE35
+:10E790005C32BA968EEF0210812A7F9CDA71601883
+:10E7A0007F48ED1E42ED9F1332EBEF236AEF41BE2F
+:10E7B00083DA7B6838933AE657F3BADE1F41C75FC6
+:10E7C00044949F0BE7792F6E290A4F62FBF7F85AA2
+:10E7D000C107EB317F790C457E783CC5DE044DBE28
+:10E7E000C6C4EA076F137C2F0808C30DF899C1E16E
+:10E7F00011182FCDCFB1B3364777DEB15FB0D17DE1
+:10E80000B466085D8B309C59C4250FA4EDEF5E56AD
+:10E810002C836BA75D1086819FB066A14C02683780
+:10E820007B134906270E3ADEFBED0CFE0C977C525B
+:10E83000ED479B239B5D45743C738A451CFFAC6987
+:10E84000DAF23FED8C7119C6D274CD53D8CFDD45C5
+:10E85000DAF27BE768F3F7B9B5792A576590AB0F21
+:10E8600094E9BF53B42481DF31F41B00E37C90E3CF
+:10E87000E1C15AD9AB59576A761B95727084B809B1
+:10E88000CE0BDB8B3DEBCF5FAECD177BB5F9856B48
+:10E8900074F039DD9CE2EB7F1CE883A6A7813E285B
+:10E8A0003E4F72FA08F3552D7DDC139A06A30F65CF
+:10E8B0001EA724B604A7D633FA58DC1813991E8A6B
+:10E8C00043F4E052D397420FF3383DFC99D34369A8
+:10E8D0009396AEEE23BED5C9B4FD036B77E13A1D26
+:10E8E000118A193DFC40A1870E0D3DB8393DE8D78E
+:10E8F0006F1EA787798F307AD0AF6707A7878EA65C
+:10E90000CB3249EBB9AE741D3479BA0EBA75B7A3E0
+:10E910001F8AAE47447A58109A379D38CD2FE46548
+:10E920003DD68BD30396A701DA09E209DBA7F7AC42
+:10E930004FF984265FDA1479FD6BDA36AC3DA9FA1B
+:10E940005ED5F2F25AB57FBBA2798B26BFC4F7A67B
+:10E95000A67E69D32E4D7E71E33B9AFA0BD71CD26B
+:10E96000E48BBD7FD4D49FBFBC5353FE60ED594DA3
+:10E97000F903651735F9FBDC7FD3D4BF778EF0132D
+:10E9800075FEEEA2A89FA8EBCF9A16A7C9CF700D6F
+:10E99000D2D437ECBCF62EA0C783EF8B04F48F4F94
+:10E9A0009DA7D1FFF9A95376429D931E07EE83538D
+:10E9B0009ED1989EF138719F9CF34CC2F442DB1EAD
+:10E9C0000BC8152A474BE0C8A674E596BA35D9207E
+:10E9D000D709CADF8A956FD4798712B21494638AF3
+:10E9E000EFC22623094C204400E1C4C7151455E5A5
+:10E9F0001D7D9437514191D0B3BCB023F2F79A27D3
+:10EA00008B87DB239C7F84F73519027A52772FE7B7
+:10EA100024950229527F276405F281AD5C4FA93409
+:10EA2000327E51B975502EB1413E30AAF6ABFA6B29
+:10EA3000A19B6C20D049BA663F97365DAFE1F704E1
+:10EA4000BCCF89406F1334DF2B9A6FD6B4EBDA2535
+:10EA5000E2B8AB819750B9FD2A297A52043E15D805
+:10EA600093326B0C8CD3F514E6DB12518FECF2343D
+:10EA7000AF85F3C7739E164CCF78DA303DE509AC0D
+:10EA80008573C0939E03981EF7B463DAE13986E973
+:10EA9000479E0E4C3FF49CC1F44F9E20A6C73C9F5E
+:10EAA000617AC4437E02700E7BCC98FEC163C7B40A
+:10EAB000DD938CE9058F0FFB51F65D5F747786CB94
+:10EAC000ED73407F11E86CBB78AC6ECDD0309DBD4E
+:10EAD000B9F223A43305CF854D264E0F491A7A0883
+:10EAE00080ED7723D04B1FE54D32A7C3DEDA472EEA
+:10EAF000AF79E1BF87DEAE7C4B7A0BD3D3101D3DDF
+:10EB0000A5F7454F1FAAE9E98AC1CEE420A7A71FB0
+:10EB1000F3736B7DBF51123BA70CE977AEDB0C8022
+:10EB2000AAA5FCDC84906998BFC4FB5E49C1B5A36B
+:10EB30001EE81B0D72EBD2E8BF8F8273874BC7E8CC
+:10EB4000E2A7F63E3F3D9DF48E7717DA43253EBAA5
+:10EB5000E80911C61BCDF01A6520D3C878421A46C1
+:10EB6000BEE45C90817989C4437B9F734684F33A09
+:10EB700042756BC06F5F785D69BD3216E09D7AF6B5
+:10EB80001F59905EE1FA75F41E11F57C1278D109D7
+:10EB9000F80DC925933319FCF3C191463BEA09648A
+:10EBA000BA167FDEDB35F86B4855CECF1B93117F4D
+:10EBB00023AE8C1AD40FFCF5C5DFFBC2E70298F731
+:10EBC0007F033EFBE28F7DF145E272BCD646E7DF74
+:10EBD000BD73CCF8C71CC007BF1ADFCA799C7E3C46
+:10EBE000F992F4B5E8B83B49A1E3F614885BD82460
+:10EBF000DA11FEA5D66B62615D4270FA584FE1ED05
+:10EC00003FA780BD7F3E550B2F4B07EFD281176D7D
+:10EC100060772D4D5ED87032C23A2869554B5D83BE
+:10EC200045AD87B669F3971A85692D382E47ECEC08
+:10EC30003120276A1B18DF5E8EA90267697209F608
+:10EC400073AE393D96D97B3EC60F36C721BF38E734
+:10EC500029C3FAFFECF1F40647190F21ADE484193A
+:10EC6000F8312D4BEFBD7EAFF42CFDC588E7DD7E7E
+:10EC7000F90AE88966FADF9760771009F30ADC9AE7
+:10EC800016D16BBA01BE6FD6F447DB399433E22F4D
+:10EC9000D3BE6ADF48E49442B7545ED483BD80E7B4
+:10ECA0009B4B1AD47A5955CB7735F99AB6471AD473
+:10ECB0007A5C05FC83F25F522B484037959C8CBAF6
+:10ECC00025CB1A818EAF18824F808F08AC5E95B924
+:10ECD000C3E8A69FCEB7B275EB6D7CE73CE65488DF
+:10ECE0003B283337E2397259CBB5F92067CEB7AE3E
+:10ECF0004C02F95B215EFA5E5184F6BF94042E5FEC
+:10ED0000E4A056CFE7F441285CD5BCE9CF12C21786
+:10ED1000CD7719985F460FB78DCB91BEF053BDF9F3
+:10ED200050C1CD8E9E78AA6EBB6874235FA4FFCBC2
+:10ED30000AE349C15FB154D426D171973777A2FF56
+:10ED4000E28CEC1DF583AFE0973DE767493E15A3E4
+:10ED50009A9797B4433F0B26F18E88E3DE0F281F66
+:10ED60003FFB5B99001F225769AD2C74CD70BBC768
+:10ED7000400C5961BB67416B4521E0FBECEBD3D103
+:10ED8000EE5B448A6CB80EA4310BEC9CF3C480712A
+:10ED900055E7C91F6C1354EBF0B164E478A65C30FE
+:10EDA00089BB3410BE7B10D85FA639F5EDE258F868
+:10EDB0002E297690F025CA15B780F11773D8772FD2
+:10EDC00031D701FD527B4A63AF517B4A93A7F6943A
+:10EDD000265F426626413C45C9D332F10988274D5A
+:10EDE000F941C98EE32B25B5F5A01FFD9CFBE1166B
+:10EDF000D8893484CA87AA379ECB2AA6F3E9929889
+:10EE0000FF4B890F584265C5205A5E5EE633BA2C27
+:10EE10003DE777A275C23D94F3033C160770BFD15E
+:10EE2000C7E26B8843CAE2AA4F5AEFF31FD82ABA47
+:10EE3000A26C508F7E57C69BFAF5E7AF9F2F214FEC
+:10EE4000E23CCA9B67601C568F78073E1FB9597019
+:10EE5000F922EC27511634F12E0932C39FE2D71A5A
+:10EE6000AECB5F0F7995DF6BA2AEFC1BF39701442D
+:10EE7000C35F8A25F7703991F113C0BF2005717FF8
+:10EE80007D63F8C93DE05F2FDFF84F843F54BBEF4F
+:10EE900029FC89FFD4F18FE831FEBC48F0ABDE7865
+:10EEA000F57588772CFFD5CF6C84EEB7B35263929B
+:10EEB00093AE7BE5A6D53617F01DC96B837D71D661
+:10EEC000274E8B440FDF9779DC1F715904F0BBC2CA
+:10EED0003F29FC73AFFCF84EB0A3AE6C92EDE84F47
+:10EEE0006D36054C949EAB5B971492B198EF64F924
+:10EEF000472F02FDD7B4C9C7D5745AFECB9F254111
+:10EF00007C10A5942186644803689F546FFCB80068
+:10EF1000F48D1A12C4FDAA6F07FD7F168FF2B0D8C8
+:10EF200018DBB31C1D3449D09EFD6A5A7F7C51B456
+:10EF3000417ADB69E06FD4B244BF90BE5D19B73B44
+:10EF40002A64EB00E4AB13C944E0AB0A5E888FD9B6
+:10EF50001D2B5F7E666C271D57D7C6DFDA0415BEF2
+:10EF6000147BE952CBC25FFCDAD13B1FBF40F7A351
+:10EF70005ABF55E494A38DDB4B7E9656CA011BC441
+:10EF800073556E909D5EFAB9F2D5175F7A16FCD96B
+:10EF90007F34394752F815AFEE3B7213CD576C9161
+:10EFA0000714B2695884A4F0FAD4D0FF968F0FAF3B
+:10EFB00047F9B67D46C718F6FD87F1E175A9D8B2C5
+:10EFC000CB48C6F4C4475ECB2E638725C2FAB4741F
+:10EFD0001680FEB7F2E5BF1A81EF9DDD299081A969
+:10EFE00011F0B9611FEA8780275C4FBE5EA1F5D39F
+:10EFF000D5AFA1EB027246BF5EFA7A859CBF005C7A
+:10F0000088B3A1F4FDDAAF210EEE4F2627E0A1EC84
+:10F01000B5876C309FD3522DA3F3E7562701BF2B42
+:10F0200093BD49764CD9F7B2E71F46FA2B3DF470F1
+:10F0300012F357BA061950767A07C13C17AFBF1BB7
+:10F04000E75942DC488765CF89453E9A7E2A916917
+:10F050005B22EC934B7C9F9C7E812E2E9DE7694525
+:10F060002EFC41E472E1BBE80F7D98CF856A909851
+:10F07000FFD4CCD6EB806CD0C8D110FD6E7C14E5EB
+:10F08000C7B961AE8170EE561396172847C4435333
+:10F0900007B275627207DB51B99307DFA17EBBEC43
+:10F0A0008A1AAB69877246E97F19EF9F8E3B1AF483
+:10F0B000B7D34991ED91E146850F503D434567AA8D
+:10F0C000FDCEF6FFC606B6DF95FDEF9B310DCAFFFC
+:10F0D0007298ED23680772978E2B3010CB77CD1680
+:10F0E000903F984820D23EDF28F37DAE2DD7D30B3A
+:10F0F0001DBF24C4AAE806FA89C77540795FF234B7
+:10F100006DAFE2A335D0AFAD275C651F97727E70FF
+:10F110001EF8C1F5617E40D627F62B5EB452F6BDCF
+:10F12000F42CEC5FBA5FBD0ED8BF7211CCFF93CD4B
+:10F130007B8EDC4FF7ED272DCABED5F255FDBE2DD7
+:10F14000DBFA30C69FEBF7ED27436B49C47D4BBF1D
+:10F1500047DCB7433BFE47F8AA82C724A396AF2AF1
+:10F160007CB2377CEAF9E416D98178D5F349FA3BC9
+:10F170004CB27AD2A342870AFD95FF47D570E0478B
+:10F18000213A55E83044A70A1DEAE7ADC5A3BEFC05
+:10F1900023F02D527A297A53C6F3954A3F8B03A662
+:10F1A000EDF60FC9447CB950CC91C6FD4306A8F3D7
+:10F1B0003E5DBE4557DFA5CB17E9EABB75F95A4D51
+:10F1C000FDCAB63D46827410D0D41397FF3B393147
+:10F1D0002112DDFA98BFA1F5A211EE39D45882D8D8
+:10F1E0005E5E41BC101F19DC21E2B95137C5713D8B
+:10F1F000F83736A7FABC948FAC8E627E856E7BD0D2
+:10F20000164FD3D5712C1F4C34D6031F54BE07A301
+:10F2100098DFB1BB28688B53D95B9D7E11F9788745
+:10F220002FF2BD0D2A6970DD3B7AB9D7A19C8F758D
+:10F2300047DBC6627FD1293EA0C7A9A2256539F860
+:10F24000A11A4527E8EC8BEAEEB5C17955B73FFD29
+:10F25000AE39F4FBE27744168EE37549835476D0D9
+:10F2600019E25D972D405CF05AA49F857E66172DAC
+:10F270005A1B793F94F37625966546E0BBD40E3948
+:10F28000AE3EEF51E094ADD77DF74FE7FBA611ED11
+:10F29000FFF28DDA7237B79F7F64E4FC671C19C7F1
+:10F2A000ED57E6BFE17C7BAA9871D71CBA3EDD071B
+:10F2B0004462A2F94B7E11D7E7D266C107FE37E25E
+:10F2C0004DC4FD574D8246F57D882ED85FD7F4CECC
+:10F2D000C7BAB6FF39EB074047AF7F30F6DF69DAD0
+:10F2E000F5FA1F47BD05F9378EA67C407AD6CFDBED
+:10F2F0001985F102DD3BAD48FFDD3BDE4BF901E452
+:10F30000DF3439619CDD3BFF3A16E8A97B85A90C07
+:10F31000F860F730E6BF5DB9E3AF633B50FEAEC2C5
+:10F32000756C361A999FC9FF8F8FE0DEC2253F9D0D
+:10F3300015E8173CAEBEE6D7513E82F0FF9AA5BE57
+:10F340000FF46DE753CDE343BAAD64CE56185F1C9E
+:10F350008B7FA8796BF28B75B4FFAAD65DC685B496
+:10F360003CEFEDCFC7621CFD56A6375D903B9E87F4
+:10F37000F8876DC6EFAC94299E2FC026A346F65D94
+:10F38000A63579B08F7AE2E573F4A7F5171FEF1A67
+:10F39000997DFDAF8F0FC1C5F89FD5671660DE7FE1
+:10F3A000FBE803F4839A902E95F97ED25287FA4CAB
+:10F3B0005FF33EFBBF860EFA3B6F21D09F799B4DDA
+:10F3C000FFDAEBFDB8D181EBA2DF073DE97CC7F79F
+:10F3D00030FFAAD589E3ED27BD8F36FD3FB6EE5B42
+:10F3E000E9BADBFA9EF777FEC5E7DDFBBABF338FDC
+:10F3F000AFBB1DCE536BDEFE1CC7F775F95CE9FF92
+:10F4000052BA57F4FD7643AD3D938E6F0E69B482C8
+:10F4100062715FE2254BA603A2702F0FC0F83B3844
+:10F420005F8D6057359998BFCD241858BCDADD82BE
+:10F43000E247443BEB4EAE5FDC39B40CF5903B5DEC
+:10F440003F417D8248B5ED39B47E7BEE4227C66AE6
+:10F4500092F1C7DC909F3D85E7B5F6E6EF04E21236
+:10F46000A87E7F67EEF403A0E7DEE512510FA62920
+:10F47000EABFEFA714B0EF93B4F6D07D6E6DFEDE59
+:10F4800039DAFCDD1CDE3D848DFF9E22C1077E58EB
+:10F4900053CE5389E097352D9689900A7146B5ABC6
+:10F4A000C1EEB8BB48DB7E1928672A7FE337C5E386
+:10F4B0006F43785C8A78213922DE03ED138F7CDC80
+:10F4C000EDB3C7F920CE9A484E86C77BAA9CE83791
+:10F4D000E7F6B8CCDBCB9635EDB09F659D1DAED879
+:10F4E000D3BDE19B70FB1CE1A485F12FBB44B4CFDD
+:10F4F000659D7DAEACCBD75D0F651DBFEDBA3C07FA
+:10F50000EB7263785D865A5C04F6ABCCED877C8B3E
+:10F5100093E587161176AEE8C3FAD20017F1668438
+:10F52000E3D197988B2BE09CCC3C5A407FC85D6B15
+:10F5300045940FE60C01C7553449C6F8E38F0D45D5
+:10F5400059B0DE851326567F9F0DC309F85CC2F1C2
+:10F550005E426A517F2557BFFC323B0BCE2508EA3D
+:10F56000BF4B5C84DC41EDB8926C21100DF16A1246
+:10F57000F1C68E073FB9408E6BFCE4DA3CFC6E4965
+:10F580000AC3E9AB7E6FFCE59F9DFE17E567C729BF
+:10F590009174423A12BB97D476F77C3FC3634DA572
+:10F5A000E04B43BA0BC8EAFBD30566B60FFEEB8708
+:10F5B00013904FE6FC744C2CF30764E27DC41A6E82
+:10F5C000375CF23A62C10F76C99FCECF73F36C6A93
+:10F5D000BEAAA487B81DFE9F109748D3EE7CA15108
+:10F5E000043B8B04D1FFEBCD8FC27BC5FA76A3CC55
+:10F5F00006BEAF6BD12F003F11EEAFF27994D2A6C9
+:10F60000B1F1AA755B7BC759696CCF7580DF71D585
+:10F61000F9DDB7C52FD8FD80D743511D054511E64B
+:10F620003B89E3AF70F7DFF0FEEA4C7FAA0C7899D4
+:10F63000992F6ACEF99D66EECF984026C0B80A771A
+:10F64000DF669B0CEB724074C27DD51AFF45A33B6D
+:10F65000C2F9B11E9F001FFCF027646709E0F3C4E4
+:10F660004FA208D8D5EFF173C90CB8CF9181AE1E67
+:10F6700017F81D73CCCC4FB8CE6CC77456618E9CF6
+:10F6800048FBCD68B58F8350B5C1BCFE3AB303CB00
+:10F6900087F0764ABDC195AC5EA7D15E1D69FEBFFD
+:10F6A0008B12F87999F37B93847FBD75CBF9A935DB
+:10F6B000900BFA41BEE267D1D335C1FD71699AE082
+:10F6C00003F90DF630E60B05D41FDE53EEAFCF6421
+:10F6D0007256A17B3D9EABCDDAF7021EE7787F889C
+:10F6E000D387826705BFFAF12AF529BFBA55ED9F86
+:10F6F000BAAB6DDC6BA0DF54FB05BB8182AA963AE6
+:10F700008CB00F6BDA9E90E17CE63E07834BA4A29F
+:10F71000B1EAF8837566160FB267FCCDF3804E2E02
+:10F72000AF35812C24AE45176DC087DF33387F0F8E
+:10F73000716CDEDF8964D357F0AB0F3CF6F27C5975
+:10F740000D3715E733AB32470677DA0395BBE48113
+:10F750002A7A5A678EC772E5FBE04A07BE0F42FB62
+:10F76000C371781F3711B84F92D1D28EF76C1FA892
+:10F770008D637458D6B2CB88F954CD7B224A3FFAB8
+:10F78000FD34BB501BAFBC30AF6328E0A5D014588C
+:10F79000E68C40A793A39473CAAF29275C946EC7E5
+:10F7A000FE7F2427962972A203E3E395F602DFE7A2
+:10F7B0002A393130929C585AE71808EBB07447FA4E
+:10F7C00040D8244BDF999A14494EBCEF61E7CC47EF
+:10F7D000F97DF6EED9544EDCA09213B3A3904EF40B
+:10F7E000ED3E51F6495F724259B7FFCBFCE67D9082
+:10F7F0001311F6F7173A39718FBF18E5C43DB345B9
+:10F80000CDBDAC4FFB94133949F7615E76C644A079
+:10F810009FF7B97D7394DF0B807E405E6446D911FB
+:10F820006F7AB9D11B5FFF537FF9FAFF109E15BEA7
+:10F83000BE94DA3FA6D4487448909E97DE47F9BA42
+:10F8400000F4C8F8FAD207B99F53C7678B80CF6618
+:10F85000AAF92C6B5FED6672A1A62DF599B9B4FCDF
+:10F86000FE46D909A2F2FE30DFCD52F3DDCCA85E10
+:10F87000F86E19E3BB97FD13507FEA6D7E7FE6FCBF
+:10F8800096F2B311CE08F431676E8CE6DEDE897134
+:10F89000BFC9D806FBE53D11CF793FE67AC0C171FB
+:10F8A000BFC9047DFA493E9E797C3D2F7848793E58
+:10F8B000C55FDE22A64F576D16117FD5AD6CFF5781
+:10F8C000370B3E07CD178CFF1B9ED756EC60E7B574
+:10F8D00074068539AAF5AF78AFA31ECE092A36087B
+:10F8E00078DE0CF71E009FA51C9F25CE0A3C5729E9
+:10F8F0006DD2FAC11BA26D2F901B101EFAC3AB78FC
+:10F90000FD425310CF1D0A7F293837209FD4B6AB54
+:10F910001A71FB59B04F2A9A75DF9D0D78AE0437E6
+:10F92000D441AFAD6AD1967BF8BC178B818C6D1436
+:10F930003EF93DB3F3F478F7E8F153F62DF173880F
+:10F94000E227F39F879F25FE5D785EF075F1A2C7E1
+:10F95000475D143F1F184F32613F7E6C70217FF16D
+:10F96000BE2BE2BB4E8B9E18A9790FE5A71C2FEF8B
+:10F9700019DCF583A05EB580F54AD76FD99744F3BB
+:10F98000735BC8383866286DD2CAE390FC6F75A0E7
+:10F990007C9F5BBB4580B8DAC5FCBE6099EF097CF3
+:10F9A0003FE6C1E554DED3FA0BC79BDC705E7E28D0
+:10F9B0002A88FC53A1DF9D40BF946FFAF9384E0CA2
+:10F9C0000EE6A39C6A13ECB82F03514C6ED17582DE
+:10F9D000776DF64CFE6B015F17E65F6A63EB584389
+:10F9E000D70DF675819FE75B983EF880FF223BE7D5
+:10F9F000F4EF92D9FB380249407EE744FB5C918FDB
+:10FA000070EE9A93A45ADF1D9D8CFE37094EFCE0E0
+:10FA1000A3FFFB36EBDBCBBA2AFA4C7FD757C1D317
+:10FA20004EDD3A1F8A6A2F9C80E7728213DF0BF249
+:10FA3000C7E179D1C946F6FECD41AE1FE9F705D839
+:10FA40001FEAF77866C0C0212E7A5A14C69562BFA5
+:10FA5000694C3F53F329FD3B485F376EA986B4A339
+:10FA60005E168E7F74DF6E06B93F4DD0C449D11942
+:10FA7000E1BEFF27C097A3BE023E4936A37C79C8EA
+:10FA8000CEBEEE196624F01EDAE53532D2D1BD06BF
+:10FA9000C7916CE02F8FC904F6C7E583371E9D3BE5
+:10FAA00000CA45A48FE2F72654836BA598C5AA9196
+:10FAB000E247985C3AC1FBFF1395D7AE6B7897A0ED
+:10FAC000077BE27C70BF74B673D75407F85B320FC4
+:10FAD000AD8673CF5979F62347601D1BD8BB4FC73E
+:10FAE000D7E4A19DF6D07705DC67C7E87A019CBB17
+:10FAF00067A71E3942C7F7E09A443CB79CEB4ABC63
+:10FB000007CE31E71E149D0E5A6FE15D560B9C7FA8
+:10FB10004E1F2D12B70A2F0F9276F4EFCCADFDEEEB
+:10FB2000DDB04FCAA83C84F79CCAFC87A60E84FCB3
+:10FB30007A01DBD778DD46B8E7D9DE74D19849FB86
+:10FB40002FA1F500DD35EB59BD9A8D02BE1758E2A5
+:10FB50007F02F964C946011FC469A7FAAF99C1F5CC
+:10FB60008129D1BE9EB6A7F952680F7037C6DD0352
+:10FB7000E79335749CD87E521D9E5397D076B498E7
+:10FB8000B46FFC2EC25BB25E2070AFB06C52EAE381
+:10FB90009300DE41D909E54777FDDC08E39E47FB8A
+:10FBA0001B44E12F143BA6427DF203C18EEF2E15BC
+:10FBB0005E8BFBBA9BEF3B621FCDE21404A2DCEF2D
+:10FBC00093D4F12A25D169B89F4A96D7D5C3BC3AB8
+:10FBD000BC89A906A4A78B4690E32729BEDD547FE4
+:10FBE0003D616471307BBC278C1D2AFEB9323A1D01
+:10FBF000DB2F6ACB413EB39814613C85BB8EE92371
+:10FC00009DABA37CE057EB94ED29F07DCF6A137E8A
+:10FC1000BFF02A933B178675A07FFBF47A99C0BD8D
+:10FC2000C795EBD3D7C13A9EDE2C3BE1DC407C8EFE
+:10FC3000C51194BECAFC647BD633B8A79B197FCB91
+:10FC40007BEEEE02E0DBA5944F99707E5A3E56E2C1
+:10FC500028473EF55C14E34B7A7EA5E753658D1B80
+:10FC600022CBA1650591E5D0D07AEE378D2C9F6B24
+:10FC70008885E9BBE3C978F06316570D9BD704F478
+:10FC8000FC20BB70D01E78F3D39F81DCADB4E23B87
+:10FC900065D5927D9DC0E88300FF9FEBDFF229ECE4
+:10FCA00087B2B951F80ED929580FD8476B13F01CF9
+:10FCB000BBC4578C7857E2794B9BB4F4AEF821EF74
+:10FCC000738BC4A5965F6531C4A5AA77F447946E7B
+:10FCD000693FF3DB041FB0CAA33FEADCFF7026E6EE
+:10FCE000ED38AEE55C3F586B45BA3EFAC8C5D54025
+:10FCF000B7F37E2810D0DB89D75D0FF2B0BA497018
+:10FD0000809FB8F487AC7D296D0FE33EFA73465FA0
+:10FD100094CE1DB00FAAD73FB11FEB6F141C00FF8C
+:10FD2000E88662D427CABC22C1F28D9D684750790B
+:10FD300085F1687BBC6212EC83EA55263BB86215FC
+:10FD40007A52E8B393BFA740CCCEB1B3683B67B457
+:10FD500003F9B29E2EC53942489E02FDD47819BDE2
+:10FD600075BE2A3B618BF44D9FEC1EBD427F22D0B5
+:10FD70005F6698FEF6ACCF33023D9EF60918679198
+:10FD800007F40BF4F9B2E29F2116B51ED5177DEAF0
+:10FD9000E9B007FDC1CB58E961FA54E8514F87C774
+:10FDA00025720F8CFBA1D551388FBCFA37EF59CE95
+:10FDB000F6199ECFE5D53F9204FBBA446271400A22
+:10FDC0005EAB241637D6635C4FD71907F5677CBA4C
+:10FDD00071CC8A0EC9EDF120B7A93E4A02B49FDF6B
+:10FDE0006C7E11E32BCFBFD27927EA376F513A00EF
+:10FDF000FC6FB69200DA213EE447E5AD22C66913F6
+:10FE00002990354B65BF2B713115BFB222BECBB7E0
+:10FE10009A7C85B47DF9EB27C6625CC20AA67F7B1B
+:10FE20005F11D83988B7632CDC3B2A97587C8E5EEB
+:10FE30002FF85D34B3C3BBDE8C99037A9BD0CCDE44
+:10FE4000172C6FB95736A9FCBBFBA265A51E9E9364
+:10FE500079E93AC3FB0A303EF5FB764A5C4ED7CBD4
+:10FE60008CFECADB64D4E7CA9BB75C8078CDF263B2
+:10FE700026B4776B9A2F1AC19ECDFBD5ABEC1DC46F
+:10FE8000365113A7D7233EAE590C9820AEABB50A16
+:10FE9000CF7168BE13F32D3C1EED6BC66F55FC6A27
+:10FEA000C7EB5E8AC28A6DBFB4E17B85ED9B6C783F
+:10FEB0005FAAF9ABE3557BC4C3B534F078B83B4EC9
+:10FEC00013E48F91E3E1CEC13F28217D16AD8D87EC
+:10FED00023CD8CBFD17166457A0F35A477BDFAE981
+:10FEE000F310CFDDB5F593E761DC955F5C7E1EE234
+:10FEF0006CA88268073DA5E695F731FE5569171F86
+:10FF0000C3EDA0977F89F1C317FE687202B40B3B63
+:10FF10004EA780FE7161CBDF92202E78D98EA9E8A2
+:10FF2000DF59B63D0FDFBDEDCD9E05FAF5F5237E19
+:10FF300059BF6E7B5AF7603CD079BAEEC027427148
+:10FF40008E2D552C7ED4C1E31B37478E17EF11CF72
+:10FF5000D83AEBAE29C01F5B999ED0675CE361BACB
+:10FF60009E37F4631D37F3F8D5963BBE32AEF13CB5
+:10FF7000FC83AED7B8186D7CE8A7AD8B7FF12C94CD
+:10FF8000B526F41AD718E807FE9478F4CFA35DD904
+:10FF90003189B0DEFF81F1A4B07E850EE0D79FA647
+:10FFA00080BFF88C1C44BF44708709EF6B96EF3814
+:10FFB0008AFBE9C2F64318EF4D785CF80512FAB1F6
+:10FFC000F85DEE03AAD96865F1907C1D205ED261D0
+:10FFD000C3EF3C2E92D1B5122FD95B9CE4B298347A
+:10FFE000FE3E0B8BE7ACDAF8018F3F0CAF9B30097C
+:10FFF000D6ABF32BE350153CD8010F13D571C0914C
+:020000021000EC
+:10000000E3524371C0BA7583F5043E1E8AF3A5F925
+:10001000A110EFE9138E468A2BBFB081C50F5F9008
+:1000200023DF8F56E2826B6274FBD6D7BF78E0BEC7
+:10003000E6F175F1343FC6A1A11B055F5D5723F3BF
+:10004000F72763846F64B785EE9B540AFAFB2C4F45
+:10005000C4C07D99D64E23BE93A2D8557CBE5DDC2C
+:10006000DFD6F58A8871A2F52D7B90BFEBF9473575
+:100070003F47D18F77231F6F751B931F5D5BAD3E8D
+:100080000B85D3B5FB4DA4EBEACD9D18A7BABF797C
+:100090009BB14375FE0CF2C3A71A7FD76BBBC62278
+:1000A0003FE7EFA2E9FBD9CAF9638D3F723F359B69
+:1000B0002F6AFAA9F0B618ED96BEFB3B27B9EE05FC
+:1000C00078E7DA991E75AE459CE68BD0FFCF626467
+:1000D0006E5737323F3895A3F83E9C95BD0727DA17
+:1000E000A2512F5B669D740CDE215D6635625CCC8F
+:1000F000CA3A1E47F3236732ACF74AEBED04C6BB9E
+:100100001AF0ABB2EF65BB9B803E27271765AACFDD
+:100110006194F11B0718884FBD8FADD306827D4ACD
+:1001200024EF5018C79D697F95402EB67B987F9F1E
+:100130005C3D3102BEB74BF67D09146E7BBEE00418
+:10014000D76C4FBA67F0437E0697F61D5DBC5347E8
+:10015000E777C969403DD16A08D86915628D6A4F51
+:100160004603D7411C52125EA5C07889C73CE611F0
+:10017000703FD446A8DA0AF59C92E65D95D849927C
+:10018000EE9D15727804A5570BA757C55F6765FFED
+:10019000A6703BF0FD96B80C5207E4BBD6EA467D4C
+:1001A000E2299B0BEF3FD2DF6888938827D14EF579
+:1001B000BB50B45FCD7D3BDAAF261FE7D2E613A676
+:1001C000492723C99B043E8E02D18278889B6AE02E
+:1001D000FAB2AB70645278DC7189C41980F23B2C9E
+:1001E000788F806E2FAF7A1E168B76DC747C1A3E69
+:1001F000119BD1E135B0716ABEDB8903DF47A7E30C
+:100200003DAE1BAF266FB5707E271109F89DC5DC8A
+:100210004E38FE2F69F0BD4A2A8A4F224C64C238FC
+:10022000E93021DE2596CF83F6AFA96F07EF01EB0A
+:100230005F0B870CB5ABEFB5DEC0E5E0114B518A23
+:1002400085EE93ACE1B518B89D9D2CB84E4EA065D7
+:10025000FE01C89FD296E7615C8AD0C8E86AC45A9A
+:1002600082FB664490C755AD8A463DD56426DEA81C
+:10027000F1703F8E78E5F1D08B8F9F3F395618286B
+:1002800028690DA535DACE1FCC352CA68BD00245BA
+:1002900014FE108B6B0CF45F3FC39D6C1807D31BCF
+:1002A00056BF7728EEDA6BC16368A81BBAFFC0148B
+:1002B0006421F82E08F10EDD0F72B851C953C60E35
+:1002C000EF06344687F22E33E5F78D692C7FF3DA9B
+:1002D000A1F5F07E4DA7BDE8660B8CC76CBF0ECFB5
+:1002E000C302F19AF7D57B932FCA38476F0CE4C14C
+:1002F000FBC7B707D9FBC523ADA17BFC288F3759B6
+:10030000947C00ED8BA2D643C8D7AA5A0E61B901DE
+:10031000F2341D9E10C81B42E779BF654C41F2B50F
+:10032000145E6B71323CC1B1D03266BFA4C1C3B898
+:10033000FABDD9613C482B6ED0E1E186AF85878557
+:100340006B6FA887F755FA3B6F4A170B005FD373A3
+:100350000CF88EDBC46316F4BFD05F14CA230E679B
+:10036000432FF7BC153B85C22957D397D24EA1AB7B
+:10037000DEE8269DD8AF63EF836AE9E7DF2DAE871D
+:1003800000DE328B2BDD9688F3C77705A6BB8B8BFF
+:10039000F213C2744D2CEE09F0AEFE11CB821F5A3F
+:1003A00054FEDAE9394BC5343ADE1F0123B8313C3B
+:1003B0009FC4E5DEA851749E892E03C6D51FB1B82F
+:1003C00057403BDB9C600062CB2612F704410CF7E0
+:1003D000A3EC8FFA1DCC8EAF2F36F856B0F360FC2D
+:1003E000BB1D61FAE8D0D14790D1475B27D247B512
+:1003F000BF93D1475B5D6E343F57033BBA9104C74F
+:10040000C1BA37590A0BA461946E6282F54037B2C3
+:10041000F7B682C228C4EB3A185F8FF5E1E352E6E3
+:10042000D5DBFA361E48FB7106D899070D781EA653
+:10043000E04DA9B7C3C2E246FFCDE67E11FAA99905
+:10044000D4B11F966FEB813F605C87EDE0CC5DD04F
+:10045000DE369BAE9023DC6FE3C115F84E78237F28
+:10046000D73B9604BD20D77BC707DB3F217C80DECE
+:100470009301F8E8C4FDF20ABF6796DD26B840CEC6
+:100480000F8F61EF90BC6E6176F5BB1691A74CAFF4
+:10049000493CB85B04FB2B7B9501EB27429AA19E5C
+:1004A000FF2A5E5FD2F8DD957555E88972D218781B
+:1004B000CFE4F978F71E2DFDC4C7A4A9E029ED1EED
+:1004C000F790A245945026EE5DF010C8554A3F3E85
+:1004D0004DBB317214E02D443F943E23AD0F6D7738
+:1004E00088AD6B7C0CE80B5BF62E15F15D8E7EAE55
+:1004F0006B16BC4749EB67C590DAADB47D562C4D01
+:10050000219FC0F303797E084BD33F741A04FA7D10
+:1005100003F7CB9EE5782592FDBA996320CFF4B816
+:10052000ECE418940BCABE856754E05C5BE2E7DB41
+:1005300069C13403AC9BB28FA5A02160A5422B4DAD
+:10054000721820CEE15D8FBB08CE0B7BE33BB75F1B
+:10055000CBEE81EABF7FCEC7F38DF5EBBFF4B82FAA
+:10056000FE39E0B7CADCF1F84C9AAFBEF632FA6950
+:1005700057C454DFFC55EF68E8C7FFEED5DFC40071
+:100580001DFA3F3345BC3F35CECAE8F180670EB651
+:10059000CBE2EF0492814A1CB22ACE15CAB85E861D
+:1005A0004B9986DF51CFBA055920ACA7578A87F6F9
+:1005B00031A978AE78AB2EAE55392FBB25C0FC8063
+:1005C00059B1BE42ECEFFA74F6F7493E63FA9299DC
+:1005D000FE0FCEA1A6F27333D731FB5E1087590907
+:1005E0008DF9083F3615FD5A3944FBFE41D640AF20
+:1005F0006480F2F454849767D695A713F45B916BEB
+:10060000AEC3F94D252AFD0CE546A313F8F1F4D14C
+:1006100094FEF9F7CBF4BFE126327F86CACEB8CD7F
+:10062000715F51BE466F69C477857EFBB9383F5212
+:10063000FCC563213C1715413C801E8FB90E6195A6
+:10064000D5D113DF7AFCE9F1ADE0518FB79C0F9D56
+:10065000F9F18E9EF8D1E3237C7EE95B0BEB3075DC
+:10066000B488F24BC17B4FFCB0F5FAEDB5B49E00F7
+:10067000F442F10DF84C1730BE272B86D34F6C3A5D
+:10068000E2370B14C001480F98D7E3558FC7AC046D
+:10069000DE3E81D5DF0FF81A89FC00ED2165DDB261
+:1006A000D26BF7C641DEC4E84CD1ABA772BC50BDDB
+:1006B0001AF5E6BC442BFA9B40AF9E9A14C65B5ECB
+:1006C000151B57DE48CB0B609FFE0AFCD1B1080614
+:1006D000DFC5BC95F05FE0563C5FCAE25905DFB765
+:1006E0007EA6D593A7FA0BCE82FE3DDCE45E6505BF
+:1006F0007F8C1087E77914FFC775F8D7B6B36BF313
+:100700007A7CFC0AFE31B927DE147AABB372FD7C29
+:1007100030190AFAF2D8373363817F137F7C44BFE4
+:10072000C4C4634521389C6E919E05E20E7DB7A737
+:100730007F0B3E76904A49151FBB5372AFB3DED88C
+:10074000938F29EB3585AFC714E2DD057EA62944DA
+:10075000FA4BC81E480DCFFF792BF7B30D2143602C
+:100760009E5F581C8CFFF37986E64DD54BE83F9B86
+:10077000F79F6DB6E0FD1B1294BA42784EC3F79313
+:10078000BCC6F8F0386465BD536A09D3E7E6E2FBFE
+:10079000D9142FE4CB98F038B6590509DF0FE2E3FE
+:1007A00038DF6CF6429CDBD392FB0D2BF83D848343
+:1007B00063717E526014C83F7DF9E5B6BDD5504ED9
+:1007C000EB95603D3EFE0A91F91F823B4CBE1752ED
+:1007D0007BD753E9F64639A1D07136DC7BBD01E801
+:1007E0003E28C2B8FDFC5C65E74576CFC145ECAB61
+:1007F000AEA7F0F65D62F702F228DB817A7AFAEDB5
+:100800008B4EF349701EB4D3D3AB22CF1BF8FD5BE4
+:10081000453FBB6875BF0FEBDEC0EFE3FA2F8EBA22
+:100820000ED6E71BD3D5612D5D29F444E9EB38F4EE
+:10083000D39DF9F13A50CBDFCBBC9C04F251D1E30C
+:10084000C3FA8AEB63A8D79B3E3FDCE6EEB27E8517
+:100850003EAFE8357DD92364AF4446D371CEE3EB98
+:1008600033D7DC2EB38BC6418CD36F8856DECB7367
+:1008700044833E39AF21ED95663857AC637EF90766
+:100880006B658D3DEC86DBBED89EBD673B7FB9B600
+:10089000FC238AEF41F1F8CEADD68E86FD91147E11
+:1008A000CFB767BF062FC8C97923A3317E4EDFAF0C
+:1008B0007E7EFA7EF5FD3570FBAAC1D838DAA9D262
+:1008C0004FEC3616477D69CD93CDF0145E6FF8730B
+:1008D0009B87B8D47F6FAEA3217A4EA4F7681478B3
+:1008E0000ABEE7C2CB98E00FA895FF1EE99DDD6C1C
+:1008F00037F313F4D6EF88603EEA8386A70322E835
+:10090000F5238204F5F0ECA0CBB050630F307BB937
+:10091000873D00EFA4D07C65EB2E660FB4D4A15DBB
+:100920005149ED0A903B1BE01D90C17C401968279E
+:1009300084EC5E88AFCA867732B95D0C4FA7A537C5
+:10094000B2FA331F4F37358C00BBD59D0C2F93CE99
+:10095000B45DFBA899DA57F5A9248A50FBAAC8769A
+:10096000ED77D64EA2DC3BDE25C0BBA434FFA865E4
+:1009700072FFEDEC99B6D18F82BF81DA67B7D95497
+:10098000766F6FFBE3669B03F1D9DBFEE8B417CD0E
+:1009900004388ADF82F221E407FE28BEFFA342F476
+:1009A000170B7853E8E5F6E50BD1CE88BAE66A0A6C
+:1009B000C49365733A70DBB85F3686C1A9896170EC
+:1009C000264A6E37F4D3BDFBEA28F03BBF3BFA045E
+:1009D000DA797E2BF3DB1FF49415A9E3DB6B6D0250
+:1009E000A797C010D87F77DCB82701EC956C59C069
+:1009F000F74EFDB2EFE9F199C09F66DB57D2296649
+:100A00004F36E2FD327F5460C8C32A3DCECFDF4D62
+:100A1000F55FDC3F441DFFDC6ECDABB531F822C085
+:100A2000CFCEDC7B0CF480DEE44E58AEB804902BC5
+:100A3000E4EAA1243C5F6ADD67039F68177FE7E073
+:100A40007CEB9EA40534ADDAF29F36B0E3EA383E83
+:100A5000CE4BEDF85E53E57611DF13A1FD263D0088
+:100A60007EEBD68559ECDE1FBBAFA6C8D5F19FEF54
+:100A70001952C49C8978FF4CD137A798BD3E189F66
+:100A8000BF8EFD1DCC29BAF7C96EE5EF93E9F5CF0E
+:100A9000676CB2E22FC3F8A96576D64F6FFB2BFBCC
+:100AA000B304E253EDBF6C2920C2F8B33F4BC2EF51
+:100AB000E70FA43D5508F63D919D2301AC44F6A2F5
+:100AC0007ECBCFA7E86F2FBC7BBE9367DE6EBD3CAD
+:100AD000EB66246E2AD704D0C7DC0398D391C907EC
+:100AE00045FFBBF533ADDF55AF072B7232D73F6EF5
+:100AF000D510027877CCC2FB1307248CF7D2EBC950
+:100B0000538305BDE8C34F207D6D6D4D8F017BFE86
+:100B1000DF609F00DDB65EC6F783AA49E01E78C796
+:100B2000A9BA55B40760FC24F37AD8678A3EA1E0DD
+:100B3000A5EDEA1EF358DA7FF645837D0505F176CB
+:100B4000F02F68574FF8FDC1049067FEA084E707B7
+:100B5000D917F7C62C54F145FF55037E7FFBEA6E8B
+:100B6000EDF760FCF5D06E8B81D9CB7BF7FF3D06AE
+:100B7000F8D4DB572F21BC903ED1536F46FD3BCFBD
+:100B80002A86FCD16ABD9988D98721DE6B6A2C152B
+:100B90006B42EFFA70CE87649595F4D42B42782798
+:100BA0002E09F0D0431F56F0ACD3333EB2713D77DF
+:100BB00018190FEF5EB65D4DA8C07BC7FE18FB0A83
+:100BC00094CF4C8FEADE7BEEC9E9F0FDA0C8DE9D34
+:100BD000B82AE27EDABDB36278876ADF524E8AEBCA
+:100BE0007665D0C50B6FD1FA57F64533FFBAE4BC32
+:100BF0005E7D4F225CDFC7F11518CCCEE9BC83E1E6
+:100C0000BDA86FACCF74F5B0F7FF61433D39580014
+:100C1000E262D4FA4E23ACFFBFD98A3E67FCA52519
+:100C200006F88B97E40E21B4DFB268920B7415AC12
+:100C30002376B033B61F3018605D3237A5625CCFC3
+:100C40002BFC1C73494BA3315545174BF839D81968
+:100C5000D99B12AFFABE3296F19733FBCA7F8171EE
+:100C60001D7F34919111F4D085B14CFE6E337AA77B
+:100C70006F867AC70D78DF68EFFE5FEF877793970F
+:100C80001C738C03BFE09458B60FDA0EBE520F717E
+:100C9000C16D1F82D4A2726663B168A0FDBE451CFF
+:100CA000CCAF7798FDBDD6903F94B812609E37C503
+:100CB00032BEFDD60183E6DCEC2DFEBEEFF5B18C35
+:100CC0000FA5C632BFDAD603B9090B70FFB947C406
+:100CD000821FF064473D6C45C50FA8E86F930F6F06
+:100CE0009D3E86FE737297C10ECBED38FC8208F3F1
+:100CF000759C21244E203DF4390A6FAC1ADE5B5DF1
+:100D00000C1E1DC76ED8AF0AFEA904FE7106CDBF2A
+:100D1000D52EC5433C98827F651E4AFF8E16E2DAC7
+:100D200060C1ADE4DAFA15FE68E5EF314CB013E5C9
+:100D3000EF33205D6EB7B96E89C5726F0AE4CFECF0
+:100D4000637AD2362E4F4972F170C09FB24EF3795A
+:100D5000AA8CA7B7FEEFE7E354D2AF4BD7AFC80ECC
+:100D60002FD2CD76164FEEF006CCE91077D6968EC0
+:100D70007F9F4A15977B3F8EFF8CF6FDC2B60E8390
+:100D800001EE8F55EF10E250DDEDA7BE1DA233A995
+:100D900005E9AFED18C17D5CDEFC5DE68FA4729FB6
+:100DA000BFEB86E7EBB07FF839FB2081A693FD1BF4
+:100DB000560E41FC066CB0AFC278A2FB06D2DA46F2
+:100DC00023D0EB92652C2DE5E7D54B9ADCB83F4B51
+:100DD000D6B378C465B1A94C3E737A2586E8C1F8CC
+:100DE000DEBA4D7B8FF01F5C7E9E6D7D6A0FF44BEB
+:100DF000E9EBFB808F9BDA9E5807C355E8F5EC467C
+:100E000019E194456BCFF33DB1CCCFB8FD30A3F7DA
+:100E1000C91BE55C784F6CB297D8C1BFFDD6C64DF3
+:100E200022F0EFB7809E53D93E07797B66DF6331AE
+:100E3000DF07F9D66920E047DF6624655B54FB6273
+:100E4000EF863734FBB7BCB96E3AFAEB3BE205E00C
+:100E5000F3CABE55F0BECDE8BC0DF7FF9DBAFD9FAD
+:100E6000CFDAB7C2BAD07A4FF1FDFFD434BAFFE976
+:100E7000A7B88D7102C0D9668CFCCEDC4BDF90FE2A
+:100E8000427CB5A3075F7D2996F91F6CE9B4FFEAA0
+:100E90003B2EA1FF21343E4E374FE52B74932A00A1
+:100EA000FE1BE90A8E007C51BC023D533D7AFECC0C
+:100EB0000CDC9507243CFFE1E74B3C2E0477946A59
+:100EC000BF86F999B26FDD6FC038B2F26B57829E60
+:100ED0009F50E845FA3C2BB887C753797616F671D0
+:100EE000047EB08EE3E38AECEEEB7DFFC140CF657C
+:100EF000D46284F990F5821DD6452977AC67EFBDA1
+:100F00001EE6F094EF87BF2DBE833DDE213DCCF081
+:100F10001D34425CEB281F936344C8C5FD400CB7E9
+:100F20000F867DB684CAAFFB55F2EBACDC8874AAA1
+:100F3000E0E123CEB7AEC4B1793FCEC7E9071F5D6C
+:100F4000A20AFF8224096C3F8B02DBE722C03FBB71
+:100F5000EFA6DB90DEEF884CEF76B0B7E2E1EF472B
+:100F60006D40FA8C9B66C77B2F4F49CEA8388D7E8B
+:100F7000E4C374EFA667D0CE03FA85FDDE1BFD97B0
+:100F800001FD930874EFA374AF5A3F850E285DFCF2
+:100F90001DF0A57CD7D385720EA9E0659BEE1C736E
+:100FA000AA9DE1E9FF00528D6EB5008000000000AF
+:100FB0001F8B08000000000000FFBD7D097C54D598
+:100FC000D5F87DF366C93233994C76B230490CA01E
+:100FD0002C0E4980B0D84E08204A88C352D7A0931F
+:100FE00000094B36109556948120068B18152DB6A6
+:100FF000208385EF431B6D10A858832610112D62A6
+:10100000DCB17FA54190454122A81FED87F53BE764
+:10101000DC7B33336F26026AFFE1C7EFE6DE77DF62
+:101020005DCE7ECF39F7C56ED3313684310763AEDE
+:10103000E6018C7D8F3FBFF4978C2DA1E77337CFEE
+:101040005E712482D1CFF7F0BFBA795E50BD76C70A
+:10105000AF571CE9E7AFCFC55F52E0FF71A66789C4
+:101060008C55F147AC4CEF89B525C0FB119DD66C72
+:1010700098B466E2196384039F781983F66F631C42
+:10108000543EAA6FDED32B1FCA31CCE985A6399B0B
+:1010900033158F99B105361BAD67F927D393DDB0B2
+:1010A000DE46C6C6E3BA9BC57C72DDD93685C699D5
+:1010B000E029738F898367664F9E7BA0FFF90766DF
+:1010C0004F966D88BF3EA170BEEA18404B8CC47E1F
+:1010D0006355980CE69FBFC9E4336532B6059FC4DB
+:1010E000C32ADBA37C9B32FDEFD9F4CCA5B73396A2
+:1010F0006BCBA475C1EA5AB1EE58686497C1BCDFE6
+:101100006696B59BE1D1D51DDEE281B08F2D46EF0D
+:10111000D489993898F31A1CFF9A629DED01586A98
+:10112000ACCBA63807D092695EB68FCF9397EDEC23
+:10113000CFB2A1EE70E6B92D8C8D12F862AD30C938
+:10114000703F1C42F1C6E1D9135E17207C86501710
+:101150007A7EE2D5A81B7D66FFF34401BF2F63783A
+:10116000F9ADC1D3DB660E1D27603E554966CCCA7A
+:101170003C4B555CFF2866DBE4F03F778C622E1C0D
+:101180007F9A1857B6CBFA8FA6AFAE10FA9A867828
+:10119000AD8EE822BAEA53D06974C0BC4C19DD8B1D
+:1011A000C1FA98EEDA5EAC80BAEA71BD0048552902
+:1011B000E0EBC7F6848D33D7239ED90113CBC90C3E
+:1011C000DD67B5CDC0E1B6D130FA66E897E065B825
+:1011D00003C08B83E38535DE8AF86BDC686288D7D1
+:1011E0006F6339DCAC53D96803F4B7427F24F7C688
+:1011F000A99E035741BD31D9E850609E13862EC287
+:10120000FB89ABA08DE8C3AD20BE4FBC3AE29ADFAC
+:1012100040BB77A28EE5C08B5B8DB005A4C3BFA792
+:10122000F9362948A72DC427F3C7B2C12678DEBEF8
+:101230006918D1D5ACE22C05E976CEE658059FDBDE
+:10124000C7D8742AF3EF63D84295E813F8A0DE16E6
+:10125000808F61DE3A15E1D53BCE936C8865EC1149
+:10126000DB35E323D281CE3259241BCCD843505FE7
+:1012700009706BB4BB14164BF506730AF121632396
+:1012800008AEAD0CF0D418D55D774560FF2C5E7FBD
+:10129000A4F1EA868634C69E897135229E3E30BB13
+:1012A0001FC1F98726D5A944E782AE7F80CE7E1282
+:1012B000BDD42E2C6287F3E0F70E660EA41B904778
+:1012C000B76E06F895E83D9B705D35BD8E3E8EC3CA
+:1012D000D5B67C65F484A17BB98E782117D8C78CEC
+:1012E000F011EFAE53CBCD7EB9B3C566174CED52BE
+:1012F000265BFCFC8672EB7933973B59509A229817
+:10130000D762C77E3EA223ACC7E4FAE5D1CA62DD4C
+:10131000785F183E7E0D89EB6794CFACE57FFFF2D6
+:101320009BA1D01F7F57899F5EE3FCC4E5F5A3C551
+:101330009F26223C9093F0BDDBC51CEB973ADFEA79
+:101340008B74B95F659BA03ED864F42A31B86DE612
+:10135000B0258AF1900D5B9456CB20A8FF4B612EEF
+:10136000C0C3E97FA954AEBFD73D3E13DEAFD9A1BC
+:10137000732E857E352D0AF183B337F345001D3773
+:101380004759073118AF70B7D96580F6D34A04C9F9
+:10139000659C00D76190EB2FE8CA6882E7F52DC005
+:1013A0007F503D5D08A8C6F5EA9D316C801FBE8365
+:1013B000DE7CB41FEC00DA1B9DC8674F45F2F19F3D
+:1013C0008ACCF081108352BEE788014A6159826E4F
+:1013D000F47AC662004F5078B11CB530DBA5073CEB
+:1013E0002B7AE63500BE4675B5AA089FAC2E878ECF
+:1013F00099FDF3E9BB18ED3B4BEFD03903F4D5D69B
+:10140000BDCFAB7A80EBD0318DF52A9489319E6FB8
+:1014100010DE2346D5D5637B5CB157F540FF7CA534
+:101420006EB705E9EC1AE644B92AF924AE93B5C1C2
+:101430007259EC814E9715DA471C77B50D80FDC7C0
+:10144000B89982E349FD0D7CC662910EE35DCA4402
+:101450001867E83F18C1478EB375EF6805F93EBEBF
+:10146000638CE218104AE76B98E3B738AE779FCEEB
+:1014700089F8753433D70694137FBA620CC24BF6E1
+:10148000EF1DCBF5CA488FA7084415EE2706E71DC8
+:101490007EA36FB701D6336C9677B7D111B09FD9C1
+:1014A0008CC64BEDF4D23E520E780AB1CCB6C6D201
+:1014B00038238EB7B60D807E4975B01F684FEF7820
+:1014C0004F41B8A6D7752888CFAD7B77D17AD33A6C
+:1014D000DA7929F8EB79611774DB03561DED23DB0C
+:1014E000CAF5CDF2535C6F66C77AB2AD09FE7D2CAA
+:1014F0002FF424D7C1F86BF66675EF17E5EE952843
+:10150000E403E4526EAC91C6B9CBEAE98FFBABBD04
+:10151000B1730FD2E0F37BDFB1127FB4C4137E133B
+:10152000F77D4AF8485C48BA98ADD9375F4179B140
+:10153000A61470A684C259CA8D35B87EA21F5BF46A
+:1015400024A0CF27ED9E82D8407BA5CC1E9D1520E0
+:1015500097E47B8F2F66EE19B09061EDE55B59162D
+:10156000C9F77EB101F27DC2C0FB22919E9A2C2E5A
+:1015700017B69F56D88D38CF335842FB33065E9747
+:10158000F07A40E0333B7652B6750887930DE8F861
+:101590009948DE4F2B8FEE8DD509BB83D30BEBE043
+:1015A000F482FB08B4BF66C6723C8C74798AF49CE2
+:1015B0004EA6E2FE8617F87623DD0E1BEFDD8DF4D6
+:1015C0009FCE049D8CE774A2A5F7DB63B97C1D71E7
+:1015D000BC8B21DCF315E60E67EF54C672BB29BE47
+:1015E0006334D10FF04319CE3734B54E35A0DC66E5
+:1015F000B609A87F7E13EBA07E7905AEDD486F3675
+:10160000979BF879BED9C6E92693D307BC3F271C20
+:101610003F6D433E1AE0E7A378A44773283DDE26DA
+:10162000E0F41B01DFD0F13D77E1F8F11D3A9702BC
+:10163000830C3B60F631E83A6C01E849E45306F468
+:101640000F0BB4CFB215229FA5563915C4EB02B3C8
+:10165000FB1EDCD772948DF948CF3A5F3DBC976C86
+:101660007311FE7EB49E6867116C68909DF5402CE6
+:10167000B7E35795A1BC7EFA5B23CA5387E4BFBD8D
+:10168000B9D1E501F4F1C7507C3F120EDF5A39A7FA
+:10169000C5B75F2E04CB3980D75A8E0F6EE7C77758
+:1016A0002C50B97C08966B3DE123443E083CFCC1BC
+:1016B000ECDA84EBCCC64540E91DCDFA617B4FFAEC
+:1016C000F8C558F34FB3672FAC8F5F8C4D08D5C763
+:1016D000BA88AED7158047758BEA50610BF58BEC55
+:1016E0002EC4FFFA66C58976E1EE1695E861FDF233
+:1016F00028D29B72BD5F6E8F19C4AE8452F03F6BCF
+:101700008F257D5A1B2BE65F06BFC0FCA76DBCBAB8
+:10171000DDE6793D500EAD6FF92612E1DC3F5971DF
+:101720001D41BB4AAB8F81851478DF84BF2908D760
+:10173000C10D2A32D6F59EAD2695F0F62E8E378C49
+:1017400075BE330AD6F5A7A6D1BA407BEBEC8EAFB7
+:101750006FDD05EBAF8DE6FAB9369AEBE7D3BBCE7A
+:10176000F7417ABB76E174927BC3F49E8F03E5DC8C
+:101770001BFD0E7339CC4A6D47FBE3D42EE5FB68A5
+:1017800000A135A29F1EED0A35CAA906DB15441C2F
+:10179000F539001F845F5B14C1AF3E07F82E93D666
+:1017A0007902D7D96E31B214683F0BFC88FDE4BAD8
+:1017B0007FC47ACF845F6F9AED68B4A00BD5BFBEAB
+:1017C0006EBC201E607CD5A2A77D9C66514EC4676E
+:1017D000B3D1C510FFDE83C23E1078AB113477BAA7
+:1017E00065C8010FEC6FFD813427BE7F7AC7D948E9
+:1017F0009D19ED478F6A877DA9E95D56D487BB5B4C
+:10180000CE5EDE3980E49BC10EEB3BBBEFB0DD3337
+:10181000E047EDCF6ABF88FDD5EACD0D817622AADB
+:101820005952941A3A525ADAFEA90C22FE63280F32
+:10183000BD19CC570FFB5E3E50D0D354E640BED707
+:10184000E27BBBCD9D610FE0DBCD36B703D785F3DF
+:10185000A4E6D23EB3B03EE8CDE979061DEE6F0CAA
+:1018600043BD29ED3DB94FB4C72373FDFB93F65E2D
+:10187000F7FE73CE0FDAC768DF83EC740E742CC5E5
+:10188000735A2D2885073203F7DF4A78A916FBAC77
+:101890008E30B7AAB02FB6CD70B253CA83ACD07D0C
+:1018A000009E86F37D380F7810CF7F373BEB114ECB
+:1018B000FA0E1BDAAFB0AF91B80F5650968C70F895
+:1018C000C0EC9A8CF2FE99258CE8FAF4B3CCF714AC
+:1018D0006C7A4BBB8EE86603BB82E8FF0ADD995B3E
+:1018E000DD66E2EBB1F87E7E47A30EE56F8ECFA1F9
+:1018F00043B97A7947B34E47F4E0192FE074560F95
+:10190000EBEBDF54A7FE48BA98149E2E42F0F6ABDC
+:1019100040BC49B88D12F4300AE18632B94B7FB22F
+:1019200033C20F37C00B4BB5878EC7586706C2A9A5
+:10193000EDC5637D3A61BC9A978FDD8A70A9F9ABDA
+:10194000898861CC5F2F8F41BAFFB230BC5D737262
+:10195000719D5B0FC478AB3D8BE47B15EB30A2BD72
+:101960000072DDAD0F90EBD28EDB67E828C6F1F791
+:101970000D51D91280F359E7B02416465FC8723F63
+:10198000DA6D39007FF455E1F9E4C5FC186E47DAE9
+:1019900083FC5AB2DCB778967B8CA1E7F1F60D8E0A
+:1019A000247F4EB1C61E7AC8CEED8DA7ED5CCF81E7
+:1019B0006076E13A4FFDC5E2F342D3A9DCF7AD0C06
+:1019C000E0746ADBBB795EA0A353ACE3F69790DFCB
+:1019D000BE36D3B9AE78F0FB794B2C7EFEBC8AFBC9
+:1019E00052D8552FBC697540FFE22DBBE3BD01F015
+:1019F000BB8AE9BFEEA6EB4C9C97EF8FE93BFB203F
+:101A00003ED84B27121D5016BFF86A3CA703383743
+:101A10000D45FF14E78F3F635380DD5DBCB0C63DCD
+:101A2000262FC01F732E92F902EBFA0E231E89ABEC
+:101A3000CF99A9FD76BB259EE44D2FD60BE54D8FA2
+:101A4000F0BA48786ADB253CF70D3E9181F6C597E0
+:101A50003DD8C507ECC17EAF37167BDC6372FCF561
+:101A6000BF7DA7DEE60EF35E8B18FFAC737812DA4B
+:101A70007DC5C6D6CBC2F9E1E439530BA737CE57A3
+:101A800046E3B87F39671A1F6E5DDBEDBA9FE63F0C
+:101A9000D807AB0AB00B4BF49E37EDDC5FB06A326F
+:101AA000D46B2E3F3B8ECED9925E84DCBB8A79DB31
+:101AB000907FB5F421F1FDBEC45B2A4B45BC3D6966
+:101AC0007770BA11FC20F9430B476D39C1C83CE16E
+:101AD000CE03CF75C3359279411EDEBEC1407AFE7A
+:101AE000CDF31F4ECD037A3FB6D6605B0A53CE5A74
+:101AF000B73BED51F4A70D36D914A81F73B45E8619
+:101B00007C5FB94E75233D1C5B7B7BE27428BF0074
+:101B1000FEAD8275546E3050FBAC0D7750FB09C1A1
+:101B2000D795EB12FAA3BC7CB3FD8144C4E3ACEFC0
+:101B3000EEBF1EF1B2C568EB3F18CAAA26C53D2606
+:101B400000DE73364606D5B7E8D82CDC87C42B53A5
+:101B50003CDDCF1DB01E63DC4FC4636B881FD518FE
+:101B6000C7EDCC9229B0EF9A2167C9BEDFBD278AA5
+:101B7000F4C92B6695ECC8D6C1FFF3B72BA15EF470
+:101B80009DDE49369EC0F358816786CE40A08F8A7D
+:101B9000085E2F7A514F766891452578B7825C1D93
+:101BA000434ADE651E0BFD7E21DF5347AD1E0EFD51
+:101BB000C6C61818EAA15FB4CE2966A0277F794E61
+:101BC000FF6967C07E4633971EEDE24266086A5F92
+:101BD00011657D0AED5A184C8FFAB02822F8F9D811
+:101BE000CBAE3D81F6C4585B70BBA4BF9C38A0BF90
+:101BF000FE7EB9B17BCFE78F4C807D56EC53C99EFA
+:101C0000BE905CDE8FFBCA417CBF51DA04EFBD2978
+:101C1000A0F3E6F963CB5290BE0A14867EAE63E76A
+:101C2000C3F3E55C419F8C019EFBF9F13CD139BBCC
+:101C3000BB8E6C7F5DC1BCEE3AAEFFE2E5D90FCB47
+:101C4000AB4E3BF76F68F587967FFE53FAA378F0AB
+:101C5000AB195E0B95FF85E5C92D5CFE6AE58556DF
+:101C60005FC87569D75B7D4E0DD213CF0979E2D776
+:101C700017467AFE339E8F6BE286849E8FC19E212B
+:101C8000787987EAE95C0E76D7EDD86F80D911575D
+:101C9000084B5A66CB8A46B9D664F1DC1917E0972F
+:101CA000EADFD4A843F9D1EDAF3104FB6DE4F9F5D7
+:101CB0009E38BEFFF2385E87F32B9DFB3744799246
+:101CC000F5386F2FA333307E25CBFB85FC9076AFA4
+:101CD000B477A59D2BED597D03B767B363DD417ED6
+:101CE00033D6AF5F903F18ED74E473EFAE28DAE7B8
+:101CF000678A7B10F26915733D1417A007EB0D7C02
+:101D0000FDDAF5BC1627EC13E6263B41B6CF1C1DC9
+:101D10005E9E6F8DD353FFC2C76FCA403BEEB3B612
+:101D20009B3350CE7EA6F1FFF6C40F0F0B7E7D5085
+:101D3000E89358E1277808F908EAC0EDAE2DF0FEE7
+:101D40008AC56EE2ABDF2EBE91CA47172FA4E78F7C
+:101D5000C565D2FCB6C277DCD900A7232B55D217B4
+:101D6000338DEE3EB1F0DE91081DF91B0ED799C7F9
+:101D70006F33633BA3F3E5CCC7276CF206F8011F72
+:101D8000C37D0CE9799FAF09BC5E2A9D56B34E2BEB
+:101D9000EAAD6E7A3D10A2B7DB112FA7596722F684
+:101DA000AB553AFA3429A1F33FC85CAF61BF662353
+:101DB000EB8F7CD31CC5F592B6DF9B027FABD09E28
+:101DC00085F233D45F61E4CC3B825E7B5B5DEFC424
+:101DD00091BC3393DD4EEB56294EF43ECE07E7B46B
+:101DE0000FF139C689D05F976DB575C755F879C7BA
+:101DF000FD715C187F5C4FFE1FED3AEE89E770D5F0
+:101E0000FA856429FD42C7C47E16C5D982FC44E820
+:101E10000F0FE70FBA3ADE48FBDB10D5E9C5B8A8CB
+:101E2000F7667E3E4F1AE555D0DF955ADC5888FE9E
+:101E3000B07FC6713FA67DBC2719CFF1BD928D4EF4
+:101E4000F4E35C2C3F0E6876F138814747EB58D3BA
+:101E5000E18DEC03EB4AECF0141AA134C426D2F85D
+:101E600049AC6E09E20DFA1130F2DBA37C8A3C74B6
+:101E700043973C214761A591C877DBAD1E533CBC1D
+:101E80003774465D3DFAED53AB783CE284E2E96D90
+:101E9000CF0E8D1BCB32395EF0AF88BBE66F34D0EE
+:101EA000BAF2373E46F1D1FC8D57EB950039941FBD
+:101EB0006FA0FE275E9DD39BFC181F858FBF0E88E9
+:101EC000E7F462461FE1108A8786A5BF7EF13F31A5
+:101ED000AEDC09F650B03CEF173F24206FA1FA0C9E
+:101EE000C9737D3CD7237FC07C0558D31F66C87C4F
+:101EF000850DE48FDD6A6CBE06E351DE1A1D43BC1E
+:101F0000B7EFF92BC56B67CD7050BCB6FBFD7DCF2D
+:101F10002CC7F63FCC628311FE29BE8715F4CF7C17
+:101F20001BC9E3C9DF6E32B125B0A5D96F37533C69
+:101F3000784D958EA17CD1EE1B6632E8785CDBA0F3
+:101F40002BE0F8473928F10E0464447C48BC21FC9E
+:101F5000B698316EFC02AD5FAECB807EF004DCC77C
+:101F6000966B904E7A55D915F417C8755D489F4CFD
+:101F70008AFF69FAE467D4C3B7C55F9C1E9E81746B
+:101F8000AED5C35AFDDB64715562BF0BE9E1134264
+:101F9000FE4D89D7C443307E16066FC7841C0CF0F3
+:101FA0008FDF19FF23FCE31FA11C09E31F7FC6C8B5
+:101FB000E56FA39DDD36290CBFBC27E6D7ADEE3219
+:101FC000A2FE8C6F51C2CAB36CAB51C61357E0FA74
+:101FD00064FC442B8FC3C0B711FB5FDED4BA0B7B0C
+:101FE000E5C65E168DE6DB15DFC3B937CC3C6B0466
+:101FF0009F3B16308AA33AEA18C92BA8FBB893B0C6
+:1020000095F223001F4FE0B8178A639DB615921D05
+:1020100024E35686D8E0F3F89E78D9CFF547C46F0D
+:102020007A0F7AE24F625DB0FF67B05FFC02161470
+:102030009F917199F83AAF62CC4775C4C8DFDA3B1B
+:10204000CEB304F33FBA8633E753508F29B515A2B8
+:102050003CB5CF72B661FC66F929EE9F5F3E8FF901
+:10206000962A0179059E2CCA0342BC05FA07760A16
+:10207000F9B653AC1BF4E45FE3F9BA5AE203F4A4F3
+:10208000C4876E75AB4A78ED0AAFA702F0DAFE435B
+:1020900078FD19F9F29D8BE4CB0F2F856EFE7191BF
+:1020A00074F34B8C6F0C093BDF678857ED7C4067FE
+:1020B0004783F8BE073ADB7889F1D2F9E69FA8A7F3
+:1020C00042E1FA5D7C42285C5716EBFA91BC6651FE
+:1020D000CE707AD59660FE4FE791D812865C7A1E54
+:1020E000C9FA7B3B8D8867190791EBD5E68FC8F657
+:1020F0009A16250FCF9F85BBCFD339E074DBBFE89D
+:102100001C109A07C2E79D0FE48DFC39561DD0DCE8
+:102110000AFC77A6C948277595397E370AFDF77BF3
+:102120000DCCE7A0FE11D8FF0AC6FB5FD1B4BC03FB
+:10213000FD575730BD579C4795EFB91D15837C7CE3
+:10214000C55E95F2BFD866FEBC8E452C41FF744C2F
+:10215000818E3902E019EB8A628E0078C68DB7074E
+:10216000D5E53979AE9837C1DD2BE8FDA41BB382E4
+:10217000FAA778AE087A9E3A2B37A89E5E3722A837
+:102180007FEF85A383EA99DE6B83FA67374C0EAA4B
+:10219000E734DE1CD4FF18AB7B7C14ECB33FFA5B56
+:1021A000003FCCEBEAB80CD63B43ACB7EF9AF2A0B9
+:1021B000F781FD5A311E385390C917CF8DDFAB0020
+:1021C0001C6708FFCEE5BE3941E3CF55AB887E677B
+:1021D000361A8E04FA69F4AC6B4F2AC0B9C6A73818
+:1021E0005BA15EB926F8F9EC1D1BE8BDD9BEE0F68F
+:1021F000B99B83EB83DE9CD29FE701B929BF72466E
+:1022000042B0DF8785D08999E4F499B5DCFFA57ADF
+:10221000FB6AE824185FEC27D28D43D08D293998CA
+:102220006E221DC17453F9FAD6A108072DFCA3FB39
+:1022300069E8C90BFF7E00FE1667307D69E14EFB41
+:10224000837556EC50D8EF9550B8CF6A7978792AD3
+:102250000B853B633E23D71FC1ED8F68E0FD81D91D
+:10226000F318CA89B33B16A8188763E3793CFFECDF
+:102270008EAF07ED7384892FE584C497D62504F8C3
+:102280007F647CE934C619AF64171167DCFD4F84A5
+:1022900007C8008F01F3110B9C11DD71C5487F3C0D
+:1022A000492B3F6509FAE3B904D22BFE786C3DBC9B
+:1022B0003D34E60337AE53C6E564BE8ECC2B0A939D
+:1022C0009FFC978404CC0FB447E3F9754BFB7C3A31
+:1022D00077C9BC2226F202C3D8FFA44F9AF1D714C3
+:1022E000B20B762670BDFE0A8ED76D1788BC2FA95B
+:1022F000D77B1A47C6DF7A2A955D2AC513BB942877
+:10230000E75361F4CA47093F51BF85E68F7F14A8A0
+:10231000476AEE38BB07F50BC0FD636CB758406FDA
+:102320002B7EBDFDBB682BD16BD7EBAAAF2F349CA6
+:102330008970C4D8018E2D22DFAF45E4FBC9F5D6E4
+:1023400045A4BAF479D81E9CFF27E38ADAFD8DC232
+:10235000FE71FE3ABC1764972CCFE576DB690187E6
+:102360000D166E271813B99D50AB391FD53670FB6B
+:102370000CA4D7AC9680718C8916EADFDF5C684CC0
+:10238000C47184DF6579A64276C57245217BE47706
+:10239000B6D1F4FCCF09858644E8FF6F31AF1160F8
+:1023A000886563165F8F439317FE92E8FF52C268F9
+:1023B0002A8D8936E17FB65D81F4916A7619A95D2F
+:1023C0000D1FA78A4EE4FB1A29F264B47180714292
+:1023D0006EA2DFDFC4EDD2E2B18941FEFEF78CF1DF
+:1023E000C2DFAFD0EB2E9453BF1478EFC9FFEFEAF2
+:1023F000676B47F1ADF5FFAF8CE4FE7F191F08F165
+:10240000FF3BC785F5FF231EA2ED7EFEE993D82D85
+:102410009FD2503EED307AEAF1FCD5B51DEC7868DC
+:10242000EEE7EBA4B8C0C07DD94E3C672DCF64BBAE
+:102430002C486F4B18433B7F47A76E69243C5FE9EC
+:1024400065367C3E7C2D3FBF55AE7138719B520E78
+:102450005C9DC8FD8706381F5B72F1BDC96D1827EA
+:10246000583995D9510D35B2C6222BDA456B59D85A
+:10247000F3E368414F130A7751FE764217CFB70F47
+:10248000EDA793767E21E2735897E72C8FCF717971
+:10249000422211CFA9ED3A5FB8737DB2ADE86AA4CC
+:1024A000AF81BEF0E78891C24FE632BB27E2F80366
+:1024B000B7F17CD84A297F67E8981EF03E45E07561
+:1024C000CA5A9ED7C1CE7FFFBD2AED4546E333945D
+:1024D0002B95532D3EF41355B6647A695D6EC599FC
+:1024E00083F2A2E56D37D62BF3F36DE89770FD9D6F
+:1024F0002947FB91A9C9B8FCD2B3A3529E901E8F65
+:10250000A738D464416F23F1B09C40727E6534C01B
+:10251000BB72ED925D98D7F3FE1F19C59B0EA85DA7
+:102520004371B05F017016E662A967A5E4B748A6DB
+:1025300071A68A71BCFF827923FCF3FEAAE575DAE5
+:10254000CF0103F346001D9DDE798303EDEEE5091F
+:1025500011E4CF9371DA83AAE73E5242FAAE1A5CD5
+:10256000DA4D2DD136F4839CDEF9613AC64D3EB981
+:10257000E7AC05EDD87FE8BB2C982F7C7CD1BB164F
+:1025800017C0F193452AE59DDD2AF48684FB7D89F9
+:102590001CEE1F27BA1721DC6F5BFCDDD0C03C2A84
+:1025A000B63081E879B64FA5905CB79CDD1C8D16DE
+:1025B0004A77BDBA392EA82EF540B589D5853BBFDF
+:1025C000BC24E86976D30663AA03E7F7AC42FA387D
+:1025D000AEE774747C9BC5E7CDF4AFA7BC69B011BE
+:1025E000ED837FB498582BEA337D8781E749BB8A16
+:1025F00015A00B8FC0BF769D7B5E8EA6F1663EC692
+:10260000E54719CCB510E0EB69994D7241BB8F9944
+:102610009F38C625015C67AE5018FAE3B0FF22C0B0
+:102620009F67E1FD5FA1FDA5DD679937580E48F969
+:102630005529F03CBD21F87965CB6F699C19CC43D5
+:1026400079206027699E5F730CF50AD84741ED67D2
+:10265000F6669B518F6F4914F1EDA16CD8F7F0FE2F
+:10266000AE88EC184F187E92E5C9C53622D6CF1732
+:102670004750797C31A3725122A7E3AA96B7EF4461
+:102680007BA966C716238E73C9F1819613D69B99D1
+:102690005FEF96E83DAF211ED92C25284E50B3E1BF
+:1026A000AC91EC32019F52D15E8AF0003CDCC21C3E
+:1026B000ABF13C505A65F0C7E9E0FF5B72BFC36005
+:1026C000BF80DAD1913917B55FB94FB96FF9BC5AEC
+:1026D000057A0CF3BEE48345421FCDD83869792FC3
+:1026E0000051FDCE63199DFCBC49F67891C06B5139
+:1026F000C4FD648F1785D8E3EC3DDCB7A4C74AE678
+:10270000243DA2A53B4907CC6CA0F72384BDDE4D38
+:102710006F2D0F125C243DCC5C5D68E4E69BC7C85E
+:10272000ED4A6FB2F0D726A3BF16E830C83E06BA0E
+:102730000BAA6BEDF12F0D9D19281FB476B8CCE7CD
+:10274000D4C2E76022CF5F9AE1708DB30DC0738071
+:102750007B39F985F146CA10E4DBC63D7723DF6E8D
+:10276000E47CF30F410FB3923C1149F0DCB3F49ACF
+:102770001AC47FE7125306F2B367698A1A0FFD3D48
+:10278000AB1492C3A397A61811CED3970D1E877CC6
+:102790009DCB5C34FEB43816D66E189CC4E54779E0
+:1027A0009D811963082946F40B9F6A50C82F8C9AA3
+:1027B0006422E06B96C057F58AB7ADA4AF1CF06FEA
+:1027C000285E1FE03FB3EA2A091F70EE08CBC7520C
+:1027D000AF54B166630A8C3B67651BD1319C47825D
+:1027E000FAD7B29584AFEA664D7BDDD5843FD8B980
+:1027F00011CF89B53B829FF74F127682933991BEF4
+:102800003D775A2230AF71B4804FD94AC586726B7A
+:10281000FAB2B6841BA03E7DAFEA84ED74C387850F
+:10282000FA23281FEDCCDE1CF2579C713892B09F22
+:10283000C7CAED5245EF1986EDD3E23CC3D0CFD8DD
+:10284000F59185617EDFA1732A73E411950FA2FCD7
+:102850002A1B1B3429C0BE2F33D812311EE965F361
+:1028600093C53DB88840F8D446AC247EA8457E8800
+:10287000F0F3C3348C7BA1DDF3A24279846C473042
+:10288000BD9F703426C29190B9EF33909C2E6F8A11
+:10289000A5F371F9B22223EAD5F26DB1641FC1F933
+:1028A000F4BDCB86FAF1796859DE9E6418B7BC395D
+:1028B000D3A906E331F4DC19B0CE390D8724FE8E9E
+:1028C000F480BF23E1F007780B6A2F4F127249E0C2
+:1028D0008D2D8A23BD5A3AEFD59C0858D799BA480E
+:1028E000CA93ECE97CC4668CA0FC03E9BF1ADFAB99
+:1028F000DBCF44793E67570E21FC69F136FEDFD30A
+:1029000087A1BDCBFE6E6168674DCB66B74D86F67D
+:10291000DB14CE6FD3EAAF198F76C4DD495C9EBD60
+:102920000572D0D597B1B7410EBA400EBE0BF21169
+:10293000EBEF2F4EA6FA878B1D547EB4B81F954738
+:1029400084BF5FF21D1002D1ED92242E179724C987
+:10295000F8FA82643469C6FFFBDD213A1BDE676C3E
+:102960009B30369DB1EB5CC1FAF7C6A9C1FAB5D36D
+:10297000601B978CE7DB150AD9A3E5EE9141FDE1D9
+:10298000DC64C47B2BAC5F9EBF9DF486C33819E822
+:10299000F1A6E2B8A0FED737A406D59F4872D0FAB8
+:1029A000268DCF0E6ABFB9B47F50BDEC9C9131A487
+:1029B000774701F1CF0291670407778E171BEFFB72
+:1029C00075DDB0A4BB60BD5FEF33D0732D3E245ED8
+:1029D00067AC519907C69BBE06E41F2CF148E3740F
+:1029E000E2AF2F0E58E85CB2BC296F7F01D40F35DF
+:1029F00019280FE8D0B2B85568AF1D6A4AB032281E
+:102A00003DCB5561D7D88C2C40DE152D5B42F9A605
+:102A1000653E9393EC9776EF93B2EEC0F32A2E12B5
+:102A2000F9E43DD5D7AA10FE5C04DF6722E95EE138
+:102A300071B027F12AE1F44EBEAEE30A5B86F513CE
+:102A4000911FF7B90BD6716A6263850EFD15EABE58
+:102A500004929FCFAB0CE9B6749E81F20C66BFAFB7
+:102A60006EC03A53725339BE55CAA366CF98687C7C
+:102A7000D6051402FD163C6D7AEA01AEFF787DFBA7
+:102A800040DF03823E918E8EC732572C2D56A1F522
+:102A90007EFE76C2067CEE87A76F10EE7BBDC1FD81
+:102AA0006612E0EFF30ADF20926F8B1288AFB470EA
+:102AB0003F62E4F2CB8B7CA0F8E5A69FCF96927E96
+:102AC000986E70263A496EE5A7A0DC3AB2D24076FD
+:102AD00030D3BBAC93488F3E4F742CE739A2778C30
+:102AE000C3F51D69C864985F51BE52A5F30AD21F91
+:102AF000EFEFE3E7D487550FD824CCDBA07858520A
+:102B000028DDDC3E6F18E55D6AED6D597E09BCEA93
+:102B100009B04BE6ECE479812CBF533F7560E03E91
+:102B200096F1F93C0541F94A5559AF1D34EBC82ED1
+:102B30008CC173C289F754A2B313598D4393019F7B
+:102B40002775BB86DE05F52F267A8FEAA13E22DAAD
+:102B5000F32F84EB5CDDCA0C250BF3FA0FAF1A09D7
+:102B6000EF7DFEACC1496C2EECFC39CFCCEEFD43C1
+:102B7000F615D81BBDB8DDE14AC1FBCF731DCD1AD8
+:102B80007B80C3C78149200017DB6A056D377678E3
+:102B900088E5013C574FD7314FE079E0B0C8E3B149
+:102BA00024F373A8B41BA6247339335DC7E99BBD16
+:102BB000AC707A03FB2A500F48B93D17F3AA55BFF2
+:102BC0001E9072BB8A3552FE8A2399DB2FB3151FE4
+:102BD000D9DD35988902FD2B6C3C6856B5D9E4F3F4
+:102BE00065D298B640FB607A329727738CCF3E8EC1
+:102BF000E45BC93AF83E35FD3E37F82A3A3243F5F0
+:102C00004F856DC3323B8D6F70A29FB752F06B75CD
+:102C1000A3E26B253B85EB51E9579D29F4A8563F6C
+:102C200085E8258D3E9AA9D1BBAC3158CFC27AE94F
+:102C3000DEB25CAF769DEE680BC1610EAC0BF56F3A
+:102C400085C7B7A784D6AD3801A321EBA964EE31BF
+:102C5000B1B80F78DEEA085D9F765F21EB15FBD4F3
+:102C6000AEBBC2F9552BE6BB543529042FED3E24EB
+:102C70003EB4769CC44B8597C3B7A245217C7ED6D3
+:102C80006D1F32F26F4BBA61CDF02FE07D4947B036
+:102C9000AF12946F95AB411E6786D2D31CD66C459C
+:102CA000BAA961ADCB5390DF5A9BAF1F8E7E86B51C
+:102CB0006FD3F9A9D4DE9AA38B05507A73578EBFD0
+:102CC000CA4FE7178A27FC5CF0C3DDE9A59F1EE029
+:102CD0003573A3EA8A1C14D44FE43F7A098EB3BC3F
+:102CE0005E23FA6367093FE585D659ABE7F75F2EA8
+:102CF000B85E01CF9F7BDD0F27F76477853F17769E
+:102D0000DB5B1A3DFFB181FB5BA57CFE5AEF22FF26
+:102D10002EB40B3BACCEC6E37D1AB99E9E4F72BD5E
+:102D200042E87939CFD1355B295E3013ED8080F6EA
+:102D3000CF566FA578A5F1D99956B4CB8FAE99BE71
+:102D40000AF3528F364D27BD5FF97BA9F73DC64088
+:102D50007BA2684DD9FA7B908E3747525CB1A2DDD9
+:102D600023CE452067A19F630D97AB6C3597B39534
+:102D7000A81F07907EEC8BFDEEACF0F4457E086852
+:102D800027BD79E774CF9F77C2B877FE29DAE925A6
+:102D900050D85A7564CFDB5A513F56CFFFF020DE32
+:102DA000D3017BE0FD5F4B7B00AA45064F5B32EA17
+:102DB00021610754AB1B326C683708BDF11F807F5F
+:102DC0004478F8E712FCCB11FE01F1DB4F1B389C75
+:102DD000A76BE07F7825C7CBF2A66C2B9E2F3F6DAB
+:102DE000C826BBEBD3A61C82FF8C0700FEDC5F1F4E
+:102DF0006C773500FCF17C81F087F596B73B04FCDD
+:102E00009D1CFE0D1CEE6C252F6784C0D94BF95715
+:102E100077FED1E4443BE278642BD957C7B7A8AC1E
+:102E20003EC02E9376D137ACF149B4DF24FC67F76E
+:102E3000E91884F2A7F4E1D7AC8887D95B785031E0
+:102E400004FECC9544F1C7EEF9BBEDA86F115FDD30
+:102E500076D445E2A986B919E9C796D70EE039427A
+:102E60007171BF458DBC6FB623F8BE19E69295DA35
+:102E7000D1C5E28C88C0F5A469EFD37918C6BDBE70
+:102E8000CDF9EAD6F9C4E75D4179B925ACD580FE24
+:102E900036D6ACD03DEDEA0585D6428671B53A5AB4
+:102EA00087334509CACBAE5675644F5619457C44E5
+:102EB000E45524897E4929DC2F909C62A3F2742476
+:102EC000237D70DA62F4E17D2A385F25E3FCDE9D24
+:102ED00026C2DB415C13C05F350A3F33A842A4B76A
+:102EE0005B18A7D35BCC7B29AE07279775A81FA7D4
+:102EF0002D3439C9CE8D8FA1F8D2CD42DEDD625E90
+:102F0000EE463D31CD6C746109E37A31F9D7301A60
+:102F1000A687F90DBD8C74EFB034A2F3593C12DFD3
+:102F2000967CF88E0858EA95608EA31F187EDDF611
+:102F30007D5C285EFCF809F64BD74685F78B0C17AD
+:102F400070505C2EF23F9B60EC2858C7A814076FA6
+:102F500077D8B83F7A2DE0C9E2C7AFB69D7979FC42
+:102F6000B20AF3B1F9F758BC241F545D50BDCAC86A
+:102F70009F4F796243F1EA34C6DE618E8188B72AB9
+:102F8000942178EE2F8BF1617CEF3AF487DBB1D49A
+:102F900013BD4CD633AF8E970D663B0EC7FDE325B0
+:102FA000029EBF2A60AD3100F7D6D783FDF337B458
+:102FB000EA5AFB027CAFD3B7B6217DEA221C061B7E
+:102FC000CCE31EAFE4E239A56AE9C5ADB7E289A654
+:102FD000E2D5A3A0AEE3F9AC5DBFE6FE895B805904
+:102FE000116EB7EA59BB9ACBE900E1526B7778A929
+:102FF000DF3C85E237322E20F13F18860FC4E32DE7
+:10300000627D304E8315DF3786C7D77C812FCC8C0D
+:1030100046B8CF157C3757F25B5330BF3D827804FA
+:103020003E55D02E06B8DD22CA9EF8E2A1146E47A6
+:103030003F94C2CFEFF75CE27CCCDC95417979829A
+:103040005FAA4D7C7C39FF75A27C30C54EE3CBF581
+:1030500000BD7E8AE3E8400220BD1E69AC27FB6804
+:10306000160B88C365FAFB49BA0EAD77CB11DDF7B5
+:10307000581ABB6620E8955F443A518EDE626CCEEA
+:10308000A93387F69371E652D661A0EF03493F99C1
+:10309000D03F635533E535952AFC1EF4E9428B5742
+:1030A0000776E2C722BE7B06EC469CA73456A1FCFD
+:1030B000AF69317796205F975A8D7A2C3F16F1DFF2
+:1030C0005B59178DFF892D2BE60686DF4D5031E6C3
+:1030D000070BF8A4D805FBAD47F9C3EB2B5D69E4FA
+:1030E0008D12F54FF7615C66EA79A003AA1F2E7670
+:1030F000C1BCA75F15CFD991627C7EFA3E41CFDE7D
+:10310000E334DEE9C7E4F353FCF90AF9FC2B5E7FF4
+:10311000508E2FEA0F6B9E2FD13C7F82D75B9FF89A
+:10312000AAD88BF6EB684EDAA523149257462137BE
+:103130004A97B6129C4B75BB78399AB5EAF22FDCE8
+:10314000EF648ADB989280F7CE8F58500FFF33D50B
+:10315000654C817E9F2679FE86E59C498AD78872D8
+:10316000F73D1FE985921EF2278D42AE9FEAE5A644
+:10317000F7A51E8371DEC3F12F759CBB43C7F9E42D
+:10318000C78C734D6AC838477FCCBEFE9CCAE12409
+:10319000C791765171BA4BE985FC3A666490BF706D
+:1031A000EEBDCE18F44B31CC7703D0CF5DDA9C91D5
+:1031B00007E3CF7DEEC58C0AB49B84BEAF39A7323E
+:1031C00017C8A3DA730A955FB47D64C47BB335DB9B
+:1031D000DA8CE3A05F2D944501EBAA12EB047DA7E6
+:1031E0009F1CA0A78DBD74426E3CCCF3329E3BA1C8
+:1031F000477CCED5351FFD3DEAEF114AD8F8F2974E
+:10320000627F077BB81F61EEC5E551616F5734EEF1
+:10321000F314063960FCA2FAF0F902BF12EB28158C
+:10322000FA6FFA504B8403E03CE43D1E5FAF589BBD
+:10323000998BFE6263F2E804825B8F7ED62EEE6786
+:103240006DE17ED6527BC702FC4E99BB57EC83F8EA
+:10325000DDB209BF937C062C0BEF8E37C97ABF898C
+:103260006346713F18D6F37E9FF920F2CDDE286EBB
+:10327000CF4E1B36300AE5436766B4CE06FCAC4F32
+:103280002A73F74AC0F6ABC6617BA1C9D2A78CE00E
+:10329000CB882EF449EEFEB84EEC8FFE118FB1357F
+:1032A000E106D887E70D95EE037806457BC2C5CBCE
+:1032B0002FEFC5E5B9BB978DE0B15707EBCCF5AF64
+:1032C00043CE0F76FD820E18EFC8D294C10F38306E
+:1032D0001E53785DAF04FFFCB3923CA302E73FA20C
+:1032E000637DF06871B1EB182EF0711DC2064AF7CC
+:1032F00028A0B780F3DEE431D141F5A9C571CC1522
+:10330000E8BF9D9A1A54BFB1343BA8FFCD33FA07EA
+:103310003D9F68EAC8AF0BB0677BB697BC049F5A65
+:103320008B250AEDBA4F5ABEF9E016B40337AA4E00
+:10333000B45967EFDCF4C148E87506F01B477E49D5
+:1033400007F9D13E9779747A973E307E748A75502A
+:10335000BEA23CD75E6CDC68AEAD9DF2097FAE7854
+:10336000D1BC5EE2FC9BCB72513F9EA97B9FFC7956
+:103370003566BECF532F1EE2DF2D44BD02747F356C
+:10338000BE88F6E23910FCC0FF453B0E519CCD864D
+:10339000C14DB4F7D3E6E9F1FE642D94A85FC68170
+:1033A000DC8A01BAE9686303B761DE48A685DBE51C
+:1033B000E7A690BF7C6F14F7FBEC4D8CA5EF48CCD3
+:1033C0006DB886DA6BCE45D3F86FA91DE3282FFAC6
+:1033D0000585E2131353A72DC5FDEC8DF20EB81D24
+:1033E000E69DF8E7ABC723DC6AB6F17B0213D5771D
+:1033F000F2E74159D5780DBD3F51657B15B01F628D
+:10340000CEDD42E34E441B00EAEA50CB03A89755B9
+:10341000636B9F3FA0BC315A48DED49E8BA4F72635
+:103420001471FDFD7B214F0C9D7C5D63CF4DA2E7A8
+:10343000922E7CBDB282F2F70D091BF5F8BD214337
+:10344000A742FDAF3DD79F4AB9DF37FAFD91BE2FA6
+:103450006048F87A1CE68DBE11AFD8C82CD1C8E3FD
+:10346000B375C362581879D53DCF399E6F6C3AC792
+:10347000F38FFF3BCDF517E4C392459D7A8C17314E
+:1034800073840DE1555230D85111C067EAAE9B8C60
+:10349000881FC3EAB78DA8AF4D5016053CAF16F98B
+:1034A000585A79DD22E483FC8E9BD43F2C7906D1D7
+:1034B000E7AD3641A0828F9E167C2CDFEFA0330E45
+:1034C000E0713BF7F3B7A679DE4239D151C86E7C83
+:1034D0009EE4674706C6697EAEF5039E2314B21BC1
+:1034E0003B29AFBEA4C0A1C3F8C07BDD7A87F3F34C
+:1034F00085F6D126F6FD96CA16E2B86FFDF2971D45
+:103500002E18AFEDEEBC3CD40B72DECF7AF17B0B04
+:10351000CCD6751ECF87B52F473B90EF27E2E10C45
+:10352000E3A23B4D746E81768A77D4BE6C7A0AEF43
+:10353000BBD55AE1FC0AF317BD12D98A74DCF64AEE
+:10354000A41EF5C71DBD3D9F217C8A5EE93B06CFC9
+:103550008BAE16939E91FDE33A4AF2B687F55E482C
+:103560007E69E94CF2A7A781F34B99A0D372C17F82
+:103570001EC14767EB92880FCF2E8245633C759141
+:1035800032701BDA0B0E0B7D974EF2E5443C1F4167
+:10359000FBC4FEB1748FA1EA5C6C101F569FCB1464
+:1035A000FC1D47ED92DFCA059F98847D3143D0B55D
+:1035B000B45B243FB2744F622AEC63623DF0BD9568
+:1035C000E2FEF9C84F7EBA31DA90BE806E922B02CD
+:1035D000F8A7BEED2686768A29DE4D743303CA40ED
+:1035E0003B6566B79D621B9708EB2F5996A9C37B75
+:1035F0009BF2796AEAA5D17F44AAC82730B7E6A032
+:103600005D6BA88B74E27D9A33F13C1E347F058795
+:10361000E37C83BB08ED8CF94F28E43F43FB03E5D3
+:10362000D2D00375C640BFCA4DE706513C7DCAB92A
+:10363000CBA834267B2E4738949DBB5EE06BD08FA1
+:103640008A3F0E7171BF92C167726EC844BF9247C4
+:10365000453C1F4F67B64703E37D6B54F28FC9B8F3
+:10366000A4F43399F0DE4F803EFD46DF9841DFA39E
+:10367000D1FA9D0AB9FE3FB9D140FABFAAED9DA18A
+:103680003A78FE79A62B09F5C97A83A708F733673C
+:10369000B2EF3903D4E73EB8D53ADCE18767B3BE71
+:1036A0003507F56933C011FD5FCD2BD5F13E6EF7BF
+:1036B00044F3381AA76F49CF5A3A9F732E9BE07391
+:1036C000B6CE447AE82CD02D0BD04352EF48392F98
+:1036D000F58FA4EB6A3D975FD5E618CA23F3EB9DFF
+:1036E00049EE42A4BB7E3C1FD0AF779E5A3502F90B
+:1036F000E0743CE55D4BBD21F9E085C5C9944724E4
+:10370000F592E40329CFA57C97742FF5D6E83FFD09
+:10371000EFD6BFC3AF93D23C77A5027D5DABE7FA8E
+:10372000EB5ABD85E8676CFC243DD2CDC5CBD143B7
+:10373000428E1E0A92A3353DE88145A9527E5E1C49
+:103740001FCC117C33DEC4ED4894F381E3B5A68D24
+:103750007E08F7B13A95EBD99F6BDD3DC9FFD5A93E
+:103760009726FF97A45E9CFCFFEF54FE9D0AADBC1C
+:10377000C70F71A3BC3FBDF3721FEA83830CF40330
+:10378000EAC19668C726A10F485F44C5F87E481F66
+:1037900014F69EFEDFA9E1F5C1666CFFB1FA40D2D6
+:1037A00097E41BC927922FB47C24F962C26FE1BC55
+:1037B00088787A8BDF8FAAD67B9B280EE9881E8CAF
+:1037C000FCD96DC76D5388DF42F484E01F3FBF040E
+:1037D000EB0DC91F925F24FF540BFE9829F843F2AA
+:1037E000C56EB5F9D111980A90E6F908E588E49319
+:1037F000AAE7B5FAA147BA424F239B195FC790AE1B
+:10380000AAA10CA42B530FFC70F012F5C2BE8BA41E
+:10381000A7AFFEF3F4F4550FF474E6A7D053A81D38
+:10382000FB61BE03D673361FE46DA69FDE26FC8DBA
+:1038300071FB219B9F07F646F17DEE35A693FF674E
+:10384000C2F73CCF57DA033385BF41D2691ED80196
+:103850006943FCF8C7F3C0BC8B937B8467537C87B8
+:1038600011CF2733A10CB4037AB27F53D32E4DEE80
+:10387000458AFE17C2F380B49FDD6E1C90161EAF02
+:1038800003D37E025E2762A22AF92BB24B5CA3000F
+:103890003F0F89BAB74F09C2F1FA02F9FCB2552EAF
+:1038A0003DCA07D6FDDD75F477BCA5CA7ACEFE31D8
+:1038B000B09E098F32BF1F1D9E8F1D15D3ED1F5166
+:1038C00098BF7F715AD6FE95A4E71B45DE4AA79E96
+:1038D000C783443D1FEA96807A81A6BE96F7B7EA71
+:1038E0003B59603E09D28D92CBF1EC0EB01F60FACD
+:1038F000F6B3A82F6C0A43FF466DFC8657CFA25C37
+:10390000DBA1506CAA1B0EDE810407FA3E38D507F6
+:10391000EF775DC6D8CDDB78FDF6B54356792F132A
+:10392000E306DC1B32342B2ECA4728507C5999A160
+:10393000F0BE3D4DCA13B91E46F71402DE6798AFBC
+:103940007729EF77E74D67D1FBADA64B98FF8651FE
+:10395000E1EF6FAC10FDC6E4C7847DFE709ACAE14A
+:103960002FFC06343F344D690E7F9FFF09C12F1D88
+:10397000183F21784E5A85FEED0EA384B77B15C201
+:103980007B2C63417E34989FEA1BD7BA4B1AF47C98
+:10399000BB2E0DBC7E68BF77A505DB03F49B065FDD
+:1039A000A61F80F7DD61DE7704BFDFFA43F85A1205
+:1039B000F2BEA0DB59928E5D41F41EA377137DC643
+:1039C000C42B36B4A36BDC912BF1BCE0E7CFD21251
+:1039D000829B8C1384F0DFB4923103C84E12CF6FF8
+:1039E0005B85FCEBD675F7E7FC28E91AAF36015C7E
+:1039F000C9F507EFBF9C76EB2AF44F025DD073AA9E
+:103A0000EB03D6ADE5C7664D7D94867F05FF91FC3F
+:103A1000407D0070CA41F9167FC8E808A0934F04A2
+:103A20009C4E897CF28ED1DC9EECC8E2E577693C45
+:103A30002EF599A0CB53929EA202E09016443FF43B
+:103A4000F72102F64D70BA295EF2F3BD25C5C0BF5D
+:103A50001D76FEFC7FD6FE669537CD5FD78EF7CFFD
+:103A6000B5F796205CBAC7F72EDA8F76C44D026E92
+:103A7000DFADBD67BF7780C073A2FFBBAB401FF453
+:103A80003D9E6AA40F25943E5E0DA52FAFE67DFAFC
+:103A90003B043DBDFFB75079E0D2BCCFF07B10179F
+:103AA000FFBEC05BB106AFE335781DA3A997CABAC4
+:103AB0002F48FE4AB95CBEE3E1FB12E3D1AFA9D0C7
+:103AC00075243F3D3F48F43CD726E97715C1D54FD3
+:103AD000CF0FED47FA9DDC2CE9B591F4CF2494C3C8
+:103AE00023FCF5292887A8FE7009C6C5FCFAEA91CF
+:103AF0005528B76F6890FD1FA5FE372F93E3ADA63D
+:103B0000E7128F8C3D46FAEEA67CA9AF1E27B93F7F
+:103B1000A785BFEF4CFFDDFE1FE487460D5CD66A2C
+:103B2000EA5E4DFFD517D06FCB34EF2FD23C5FA9A3
+:103B3000A9AFD1D41B82DF2F9BA1101F9615F0389F
+:103B4000A5962FB5F4E14AEFB673BAF5B96226FB34
+:103B50002E88AF26D4F3FAB5E91B4B1ACC01F575C4
+:103B60009B4A385FC06C01F79F41E67A55A0074336
+:103B70000F72B320BD07B9D94FABEFF9F37FE0AFB8
+:103B80002914370AB24B76ABC1F53655ACDBBB75A1
+:103B9000FF820181F1D5E74BF05CDD631CC7DB5C84
+:103BA0003226D02E62CD25AE807DCAFEE3BEFB5EFE
+:103BB000C5F93CEBFE5CB2D18C714F11DFB4F3124E
+:103BC000F4A58AFABA56F86FC6611E2FC693A25A98
+:103BD00073E60F08D8276BEE83FB6CBB5BE5DFB7A2
+:103BE000AB07FC009CCA9883F250A73317E5A5B633
+:103BF000C5C42CFC2F786FF7DDEA42D4D30717C673
+:103C0000515ED32BE9FC7CB13BA677E24CA8B745CB
+:103C1000DF46F2B6EDFEB154EE525DCBBB6C8C2D9F
+:103C20005EF74A89F9727C1E4370BA3BFDA5922566
+:103C300040EFF7A63BE87D8FDD96B803EDED070C6E
+:103C40001437040E7892E8E741D3603C6F972DE972
+:103C50004F71B1F2C7268DC37BA4E5F719285ED258
+:103C6000A9B3919FC8F3C058CA939AB14C94DEABE4
+:103C7000A97CE5DF7FACC77BA65DEB14FA4ECD5582
+:103C80005F37FF6D10D42B1BB2E97EC6CBE774946F
+:103C900017FEE99ABE3ECC533E1C5947F9A5D09F6A
+:103CA000EEBB569E77EC2FC9C7FEAA0D53388E4245
+:103CB0003BDACF4757A84FE13DCE32AB250AF3BBE5
+:103CC0008F7EC7C8AF73F43E137DEFE653B3E7D6DC
+:103CD00035F1748F092D7D765471581580C3DAF44F
+:103CE000FD25C929D86E12F8DC6F2D033E2FD37540
+:103CF000D30FE9938A585E5FBBEECD924DB08FA390
+:103D00004FF4A57CB1840CD7BA7480D7E10CD7935B
+:103D1000548AFBD9AFFC9BC7255F3A599E88F4B5FE
+:103D200059D0F5CBE7CA1303FF6E41C5293DD1C178
+:103D30002B46C702FAEE6954BA82E76CA08338F4C6
+:103D40009BCF10E716A0E7855BC3D8574BD3B93D8F
+:103D5000D6F6DB84518E20BAFE98E4299D37A0FE6A
+:103D600062FA47A4E78E9816622E75773E24DB1D13
+:103D70004970323445FA2233D17FEA1AE7A2F34F71
+:103D8000739FC996003E14FD3FF1F2FCDF4FA03F48
+:103D90009EFB3EF1FE3F4B603C43F6AFB45ABC681D
+:103DA0005C1CB358F4888F83FAC547313FAD629DE0
+:103DB00081F440C5BA84455D287F806ED0BFA6DD02
+:103DC0009729C3C0FD183DC6573F2F199316785E3B
+:103DD0003941F2BB27BE7C37FD44C9C6013DF365BE
+:103DE000A58DCBA771EBF8F7752B8758F474BF7BC3
+:103DF000DDAB9BE81EF0BCC85CBC5751B9CE44F8A3
+:103E0000EAB458BCB62BF1BE81451F0BE5A174AED8
+:103E10004FF5190EC24791CAF411B954D23D0A198F
+:103E20003F3CB1F0D1C7311DF373E6BB7E18C0EF44
+:103E30008C8BD3E9996D2AF91FB5F1C4EAD7B71A6B
+:103E40000BD98F8827F61047AC629DE2BBE2E1E315
+:103E500089DA38E2BFD2C5BDB3EE38A281BE875140
+:103E600029E288456B155A7FE542FEBD92A238EEE5
+:103E70003F3EB218E8A02FEDDF6BCBC53C69AE7FAB
+:103E80002A99E28B805FAF5E3B8FFC9975E91C5EDF
+:103E900065E23BB087239D1978DEAF58174970AEB5
+:103EA0007C72F6074FE4E37DC089F181E76B9BA04C
+:103EB0000F189FE13D6839CEB125F7D077678BD6D3
+:103EC000C33919F3B463D973376522DE523230DE59
+:103ED00029FB552EBDBB0FEF07E76CD877D90A95A4
+:103EE0007F0F6BBB89F421F07C320BB82F3E63D976
+:103EF000EB4623D7672C79A8B0B31DFEFB6C9FC29D
+:103F000073FC0441ADB8B726E127EF5B95E9F8F7FC
+:103F1000364B750ADDC3028946F7977E91C1FDA332
+:103F20007919DCCE2DCB70D23D9EEA5526E7D24CD6
+:103F30003E4EF7BD7538E755EB3A2A28AEF9171310
+:103F4000F9576A9745BA22AD3C1FE3F9019477AD62
+:103F500037023CAA1C5C6EFC42D063AD63D2D594A0
+:103F60009FAE6707F0EF07565BB89CAC8E05B89B19
+:103F70003901E986E2F73919E553E2B8298302E607
+:103F800057443B8CE3B0FAC7DDAB630DE8A7C1FE35
+:103F9000970F4238C65D7F23AEEF5995F81A80B46B
+:103FA000AA00EDBF67D53C3C7797ADD83D0EE5F054
+:103FB000DC2D83F146052B7BEE5DD2237305FE3BA2
+:103FC000453E5A39D4F1BB81376470B9E951B9DF44
+:103FD000E806012F4907F279F50A03F7E383BC47A6
+:103FE0000153BDE4431AB7DAD2918872B87ABB8123
+:103FF000EE87DF8CEB0638972F491F7500E8AADCA7
+:104000001043DF51ADF24E3462BDAA51A1BAFFBDDB
+:10401000840CA4D32F96BD6045FA391CD99A83FA33
+:10402000A96B5EA493EE29DAB8DFEE8B653974AF25
+:104030006986ADC382DF6599B120DB8E72FCA0ADCD
+:10404000D588CF0F3667EAB0EEB2D94661DDA5BF9D
+:1040500092EA5F887C17FA41BA52389EAB9A761B77
+:10406000F1EF2FDD2BE8E2D4B3EFF6413F50754678
+:10407000471FD42F40077D5211CECF28A49F6B9AA3
+:10408000781EBCA4831AA403E0BB39820E6AB6BDB5
+:104090007017F2430DE23F37948E809EDBA9FDF945
+:1040A0000DE3187FBF1DE944EA33A82F33A03FCEAC
+:1040B000C8EB8B05FEA17D0C6FF70EE0F975DDF9FD
+:1040C00008417CD0137ED766E8043E4C2477D78A1B
+:1040D000FD76AED86E45FC9D7A76F71E8CB7543FC0
+:1040E0000FDADA11861F043C6A71FF565A3FD9195C
+:1040F000B5B85FAB7FFFDD742FF8B096F1FDC9FD59
+:10410000D6EAC5FEE573F1FE3AB1CF2A26E0B5AD99
+:104110002FE73BC167C8C7F4DD21B13F8F3DF8BB36
+:10412000BABBC5FE9A44C96CCD56840FE217E50FA1
+:10413000D08FCB28E5097439B56503E5F74B7CC909
+:10414000F5BFEFD72B2EFC9354128F9D3D7CF7B615
+:1041500045F0C9A1FB92327600FCBED84C9F0D24DD
+:104160007AD507CC27E946CE57F4A749D7E2BE61F6
+:10417000FC561C5FCE7BD01BADC7710E32CE1F72BA
+:10418000FD922F8BEAA75D3BD88AFD4E59B2D15ED6
+:1041900011787C3FC346EFBBD06E80F75D3B14F2D5
+:1041A0005F1F12E7FD43F7BD602D1FE0A7F777C53E
+:1041B000BA259DE10FFAC9E47AF7DAB93F58BB6E28
+:1041C0002987E4BA8BEEBFE15A6C97EBC7F8512010
+:1041D0009D4A384A7A95F7FAB4744B3427F5AADA2F
+:1041E000337DD7A61DA2FC9D9076ED78C23E3A2C79
+:1041F000F2CDBB9E56F97DE765C9ED41F78E1833C8
+:1042000007EA9F25F3AEB615623CB749A17B1E5263
+:10421000AFC0CF4A7D803E92F6C1F0DE3C7FA5362E
+:10422000DE7502F15975BC631C7E9244DAA5577D98
+:10423000DDAAC6A0FF6A1BCF8393745375B29DF8A5
+:10424000A15ADC932A5BF1EEC46148F74F1B28CEDC
+:104250005376DF5823DAFBB3374D1F8AE0C07B1259
+:1042600028DF4F6C1C9247E061B6C4EBF1BEC4C6B8
+:1042700047AFC7BF5F3A63874ADFA1C171908FCB59
+:10428000EEC8237FEBE1C8CE8923D0AEFFB56A43E9
+:10429000BB7EE4A6218BB0FF484BEF58FA78D0C61E
+:1042A00038AABBF431A427A41D2CF303EBC5BD90A1
+:1042B000ECDE9CAF7A75978AC80BACEF83F1F9AE50
+:1042C0000D91F4DDA852A3A3B915E7DB9944E78E5D
+:1042D0005A382625DBE99E2BD969B38C2C222597E9
+:1042E000DA233045F97543C71DA84F5EBFC33218A6
+:1042F000BF8BCBD4F343CBB97DCDE39071C1DF61EC
+:1043000092EBC8EACDE9573B9E7C7F2F9E2BEC7445
+:104310009F91DE3FB1ECE9EB511F9ED89C63C77DB6
+:104320001FDB1949F70B8E1982BFE778A9F7C2B4D2
+:10433000F7A9E43DD7FCDEC1F69CA4FB0BDECBB9AC
+:10434000ECD2F2984E2E66744FFC5C06E3FEE4E875
+:10435000EFB6627E6145A3C986F7648E20FD637C5B
+:104360006BBB4ADF01A2BBDF80AF23DBF3E83E700B
+:10437000C5C7BC5ED1ACF8F0FE72FBC3F753FEC2FA
+:104380004CB037F16A79B73DBDFAE1EB910DCE380B
+:104390003DCBF13B006736F37C8B90EF3ABCBE75AA
+:1043A0004F8AE3FFBFFD2CFD13D37B07DF4793F05C
+:1043B00096E7AA57802E0A72FDF0FB72F12CB29F8D
+:1043C0004F2EF650795A39B46A24D2B32586EE15A9
+:1043D000BCB4E35115BF7353BD6DF0793C1F8F30F2
+:1043E000C7D0F79FBE5CBC90829A2717D7893F8AB7
+:1043F000B654F8157C545EB5AD8DDEFB72475E0B8E
+:10440000DEEB7DD91CC3C59AAB20E83B9912BF3DBA
+:10441000DD5796FBFAFCD71CCF72DD9F6F9E6EC5F1
+:104420007DB5FD21AE6538E2373AC6867660A5C80F
+:104430002F39BA86DBD9C72362FEAB18F07C7CED3E
+:104440009444FC0ED1CCB6A9D7637BC54EC586E794
+:1044500003E7CE49563CCF7DA6EFB4E23DAACFD6C6
+:10446000C8FB573EFABB7B23C6B329D87F44AB9E1B
+:10447000393229844CF432FCA49EEECB7E01EDE46B
+:104480003F391F45FE13F889C37C92992F72BF4BA9
+:10449000F7F9579CFF468A7DB7F7B6CBF806B517F4
+:1044A00015F0F6636BB796D0DF4FDE68B0E1BABFA8
+:1044B000DC68A0F1E7C0B94D07EB3DBE999F83B022
+:1044C0008EE7E8139BF979674E333FEF54CF33B84B
+:1044D000F8FDD260BA2C0AE847DF2DEBE1BB23736D
+:1044E0005C7C7F73407FE27E2F44BFB1AC99EE9F2E
+:1044F0005D6A3EA9967EFFAA9117DD74DB13BD08A5
+:10450000B822FF23DD4ABA98B386C7F5EDCD830BF9
+:1045100091FE249D68BF03586F64FC3BB2BA28FA31
+:10452000EEF724B3C380FA624A7CE718044F5F07B2
+:1045300097AF6A91CE85F7E458BD29EC77C4DE15B4
+:10454000F2781ABC4BF7BB7ADBF8F7CFC47D315950
+:1045500082BE4A477D3E29DAFE8D03BA74AEFFF271
+:104560003A3DD0F5A491F63BB29D80D7F55FF37A42
+:104570009E7D7B16D43FEF7DF63A3DEC6FD295F6EB
+:104580002106A82F59F2CD7563E0B9C9E13AD83BAD
+:10459000609E139B92D2717FD07E08DBA7277A8E14
+:1045A00060592BEE8F9D56BA062DCCF4F77F7BA772
+:1045B000E5E04B0E7FBDD3C0E8BB3BA77BCBF587C7
+:1045C0002F9D0ED7A9DE09A1EDE58CDD47F97C5EB4
+:1045D0007E6F077EDC118978AF8AD35DB9BCC7D303
+:1045E000A0B9C7E3E4F7D5E4FD2A797FEA72FFFDBD
+:1045F000B3B59772FFECFF0069F3B24F0080000083
+:10460000000000001F8B08000000000000FFE57D97
+:104610000B74545596E8B955B73E492A4925845438
+:1046200025A984AA7C2B90C0257C0C3148E5030485
+:104630008858286AD4A005A2808214011D74F455FC
+:1046400061307C9AE98E9F1722462D10957178DD96
+:10465000D1B16D868F532032FC9A0EB463EB8CD3AC
+:104660001DD0D168631B3138F40C366FEF7DCE4D11
+:10467000EA562A80BEE77B6FAD975EF6619F73EEC8
+:10468000F9ECB3FF67DF5B5F192CEBA564C6240F61
+:1046900063AB53A1745A596319947BFFE9CFD26875
+:1046A000C69A83AC3B2E8FC15FA3F5D35150CF7C0C
+:1046B000BA4B502E4B481ACDC660991362D06F99F1
+:1046C00089B1AE12E8263B6DCCC2D81209FE9D011D
+:1046D000FFF9CA194B676C9515FEED44B84287F097
+:1046E0008366467F9F05983FDFC0D81F4F742539EA
+:1046F000F58C9D9D1D2E0CBB18FB65BCCFE69C0068
+:10470000ED1DCD8EA634C6BE7CC3A4D443FF9ED07F
+:10471000DF27F960FCA57AE6EF84926D1FCED824DE
+:10472000282FEAC353A0DF6157F1B68DF0BCCBA9A7
+:10473000630C9E3FEB0AE7FCF578C6822E93F232BB
+:10474000A37E773280EB1E9F3E1CFB9D7D7D5DFE30
+:104750003DB06E93CC5812EC7B068C590E7830002D
+:10476000AC2FC30742340EB40793A0BEC5F5740E38
+:10477000237C302F9BC8D80D8CEFEB0639BC1FF182
+:10478000C5946419F7379B6F0FDB83328CA33333E7
+:1047900003AEBB9875583F4D0098B18E4BC3607FF8
+:1047A00066C063329680C724C6A6EAA113ACAFE9FF
+:1047B00097FA9009D6D784781470D085237A2CD7AD
+:1047C000C3F88BC5BCCB8EBC6BC4C15810FE07EBC5
+:1047D0005922E65DDC71773D9ECB9290E14CB7C0EB
+:1047E000F525FA7F0F9DC772D1EFFEF2AD469CE230
+:1047F000FE1DDA7ECBD9A6AFF5F0FC52D66DC4FD16
+:104800002EEB8C6AEFA8F90CD7BB7C97B6BEDE996D
+:10481000988674C2C6B2B197F4544DE7BD48F49976
+:10482000AA6F74CAB89FE166C50413373D9F47F469
+:10483000C2DE0CB0C87EAC6318D14F8B4B4FE7B1D2
+:104840006497C49CE318BB7E5716734253FDAE6158
+:1048500054265DC8A0FACF5F3936DE5732705ED776
+:10486000BF6AABC6F55DFF6A1195EA3A9A041D4E20
+:10487000D5977486611DE72CB00E809B8EC0628137
+:104880007E9A6ED68718E19999B1BF572CC76B599C
+:10489000DFA54F42580E8AFD4A97243A84643C1F94
+:1048A000EF613D437A621E03B53B9979CDA55CA0CB
+:1048B0001BBB8E3963E0DF24CE2FCE19CF9CEE8157
+:1048C000763958FCB34A588761AE4109417B735C25
+:1048D000D236E43316F474E5C3730DE2B9AE384E44
+:1048E0003709EE54CDF32A1DDC2AFAAD4B9A76181F
+:1048F000E9B2C1B388E82151C9D4ACC7A45F6A400A
+:10490000FAB9D567F8A43B621CA25F58C70D5E29AF
+:1049100084FC787383B6DD50F975AD4425D4478E99
+:10492000E7D5F6FB29D203D03B107E71243D0C9CC9
+:1049300083C5A3C373F02412BDCBCCB9B912E05B1D
+:104940000E1B18EEDF14CFF7790E319786FD800F1E
+:1049500060E2758817A84F2ED7E237C5A3C5E7B028
+:104960003A2D7E867BB5FBB735E46ADA337C233596
+:10497000ED598BCB3470B6BF42D37FC4EA6A0DECDD
+:104980000ACED4F4CF5B7FA3062E68BD5DD3BFA84B
+:104990007D81A6BD38749FA67DD48E260D5CDAF984
+:1049A00088A6FF985D8F6BDAC786376ADAC71D7EE7
+:1049B0004A034FE8DAA2E97FCD07DB34ED93BA5F13
+:1049C000D3B45FDBF386069EDCBB5BD37FCA850373
+:1049D0001AB88A1DD3F4AF31FF56034FB5FEABA60C
+:1049E000FF74FBC79AF619CE3F6ADA67B9BFD1D216
+:1049F0006B3C9793D72BFFA579EE5993EFDF505F70
+:104A0000344B95DD4186F4EB243EBA354DA7840145
+:104A1000FE832A97041D9E1C612539C1F2598EB769
+:104A200014E9B0328C7C7C6E9744F2E0AB28BD2850
+:104A3000FFD1EB91A09DFD4A525E7622DD415DC41F
+:104A4000FC291E339323D639ACCEAA81877BED9AFD
+:104A5000FEB606A7A63DC3E7D6B4672D563470B69A
+:104A6000BF5CD37FC46A8F067605EB34FDF3D67B3B
+:104A70003570416B83A67F51BB4FD35E1C5AAC6926
+:104A80001FB5C3AF814B3B576BFA8FD915D4B48F89
+:104A90000DAFD7B48F3BDCAA812774B56BFA5FF3F7
+:104AA0004148D33EA97B87A6FDDA9E4E0D3CB977DF
+:104AB00097A6FF940B610D5CC58E68FAD7984F6A74
+:104AC000E0A9D60F35FDA7DB4F6BDA67383FD7B4C7
+:104AD000AB76D02CF7D7DA7A61175DAFFC59F37C4F
+:104AE000B0DAC3903E826F484AB313D6EB02E13F7F
+:104AF0009CE47C779C1EED282F18148C0129AD4175
+:104B0000FD920C420CE90A488C35A6E22840AC2004
+:104B1000B74955C1F3C9684F0090AA73B9FCA01FEB
+:104B200013D85AEBA766B21B1C9740DF5DC2BF29A2
+:104B3000834B94A09FAAEB85F966A14E023A6F724F
+:104B4000F93C2E58CF7D9DAF4FCB626827045B7038
+:104B50001DA00793BB416F9E886377794B068F3703
+:104B6000C30C788998EF485CABA3CC32F4FC33CC0F
+:104B700067A97FFFB8063EAE04FB6B8A18FFA7A0AB
+:104B8000EE65B0FB5A03C037058C3D15B012FC4CE6
+:104B9000C04E705BC049657BC04DE5968042ED1DFF
+:104BA0008172825F0878080E05EAA8DC16F052FDD3
+:104BB000F64003C1AF047C54EE082CA6F2B5809FEA
+:104BC000DA77065613FCF34090CACEC07AAA7F2348
+:104BD000D04AF09B817682DF0A84A8DC15D841E5B3
+:104BE000EE4027B5EF0DEC22F8ED4098E070E03094
+:104BF000C107025D041F0C7C40F0A140379587037C
+:104C00003D541E0DF452FBF1C0058207CE4B6B578D
+:104C10003361572E1274C0D2B83D792F3F52F685BA
+:104C20008E2D46BB7791A04343359887407786CC3D
+:104C3000C26DCD2E3C6AA01337D1C971B42FAF9687
+:104C40004ED070407A0D563337D29B5AB654E9C9CC
+:104C5000FE0CAE90422F73BB88EB6F3353F537B524
+:104C6000373E2885D09E9B0776B211F8E623619FD8
+:104C70007C14C7E5F539BFC18D765FA314AFC0665C
+:104C800001FE77B23BE02F8CA47FD75ED356B49F52
+:104C9000D4F535C2383A18E7BFEC2E5A57233B6C8F
+:104CA000C0F540BD470FFC72C6E6DBE202BABE2F7C
+:104CB0005B17342213594285DE44C68C76DFF348F5
+:104CC000E7E7FCF71CC2C1175995429CE77A537875
+:104CD000F8AD307FEF11BDB2CD39345E96B7CE005E
+:104CE000E17D99F6B73F77A01D5FF717BD0FCFE1C4
+:104CF0008421B1210474DDE99288CF3A5D3A4DD91F
+:104D000066F7FD02D7F96DA2FF4E1DA0F2DBEB5650
+:104D1000BCB212B6D4B8A22019ED55F00F0C685FE2
+:104D2000CF614E03CA879B98E75D1CEA66E623F8CD
+:104D30005616A452B6F976E1BE6E6321827D15A6A1
+:104D40009C58FB8A5ED73B38D8702C759AF290DD60
+:104D50007700C7FB36D143EB3A31697A21EE4B5DE0
+:104D60009739C349FD66B3DE17707DDFEEFBFA535A
+:104D7000296F309DFC88F4618169B03F33C2793777
+:104D800003EFE038CD0F4B21A473953E1AC14CA719
+:104D9000F11F857A29925E804ED07F4BEBCD99939F
+:104DA00048F4D24DF26F923E68047BFA842E542868
+:104DB000E9894E8C12AC73511AD049EED0F4F0C090
+:104DC0007A2823E420D0D91738DE9FFEE11A37E293
+:104DD0006DF9DB939C88B7661D9C07D073F0A89E85
+:104DE000EC042644BBFEDAD210F907B2A2CC29C5E6
+:104DF00073E37271BF9EAD7E3D86DC4DC8E5F474F1
+:104E0000C26EA80BD1B89CEFD5767D2E3F477D2E84
+:104E10003FDFA6159F2DD5C3FA4F1CF8DCE82C8D7B
+:104E2000B18FD53F79283F82AE97EF3A3DCD837E53
+:104E300017EB2EB93171A0BE50CCABD291DE98E801
+:104E4000DB6A895C573F5DC7E7225DA7005DE7111C
+:104E50005D7F8A76F96C9333F95628BB013561285A
+:104E60007D2F5AC97F5CC0142A17322F958B800C76
+:104E7000908EBDC1278D88F7FB5827D53F507E7790
+:104E80003AD2F5BD3A1FF9D94B5917D52F67BDB5A1
+:104E900078B437AF5FF3AE1D567D53EB9353914417
+:104EA0006F0CCD7F17CB39DBA54F834EE293EC5CC3
+:104EB000C047B7E47F2213E6BF7D67D51359503F43
+:104EC0005BCFCF851DE3E7A2CA91E87D035F14E0C5
+:104ED000F3DFA678685FFAA43A0D5F343ECE3C1249
+:104EE0008CD3BBCF14DAE68AE093F2FBFF9085F215
+:104EF0004CEEBD13CF7BF9DBA6543CEFFB18D7FB80
+:104F000092478DAFA8FA9E11BDDFCFE215ECF78571
+:104F1000A0EF2FB219D1F71712388A65037628CB84
+:104F2000F1D9CBF206F4F672DDCED18827D0EB951D
+:104F3000780EF77DDCD932D685FA2094837688E125
+:104F40003593D2ECD2E817762901858D9F213E7FDB
+:104F50008AE38E19BC2EA9FCD09FD1EE301959D00E
+:104F60005C467CCE26227F671A89BF9A11B57938B4
+:104F70008FD7E9B70C1EFF8458EFE1EFB83F1D84CF
+:104F8000FDBC2CC59A87EB2F53FCC03C2447D2199B
+:104F9000CD73472EE763753E66E976A09D7E34C1EA
+:104FA000773B9E8F1A4752FDC8C3AECFF2F17C66A5
+:104FB000576C50E5338DC7AEE372E984C11944F8EC
+:104FC00044954B0109D62F6F6F28FFA70F701D372F
+:104FD000982D618C77B04AC3D97EFF3577401FDFAB
+:104FE000A0EAE3CAA8F88E1AF7618A01D757CC3E27
+:104FF00052F141F11D554E0ED2BFB0B12EC49F8863
+:1050000097F5C779FEB93FCEA3C3798D428E32E6BC
+:10501000777B23F8D4D600AE8BC67F30B37C8DFF70
+:1050200060D5C0D97EBBA6FF88D54E4DBB2BE8D638
+:10503000B4E7AD573470416BB9A67F51BB47031736
+:1050400087EA34FD47EDF06AE0D2CE064DFF31BB72
+:105050007C9AF6B1E1C59AF67187FD1A7842D76A53
+:105060004DFF6B3E086ADA2775AFD7B45FDBD3AA72
+:105070008127F7B66BFA4FB910D2B457B1BFD5B488
+:10508000D7985FD7C02FC6F178E754EB3F689E9B57
+:105090006EDFAF815F88E7F19A19CE23DAE7C5F9B1
+:1050A000066F8B277E98E53EA969DFFFC8C8CD8DC6
+:1050B000C02FA14774E47FB6D5713DC51AAA391D2A
+:1050C000C4F1BED72B1F6AE6CBD1F7BA908E9D7A7A
+:1050D0006B26F2757EF99C034076ACD0B3A21AC55C
+:1050E0009DBBEEC903588EF4BE5E8D6C53D270F238
+:1050F0000096A37D5F570319336571CA3B5896F933
+:10510000C7D6D87089ABE7BC83E5C4E08A1A94B3EC
+:1051100060267EB108D67D3E38926D84752565AADD
+:10512000715E0FD1EDAA0C1DF1F9AADB2C14374BDF
+:10513000BFD622A33EDF1CE81A7910ECDCF4A7D31B
+:10514000D762DC693DD8F9A122B017C0EEC7F25989
+:10515000B0EB43E01C6D04BB1FCB4D60F763FD73E8
+:1051600060F7239CFE74D97A7C6ED5C97BEA7261A4
+:10517000FC110FCA563453D739752B0EC07AEC0F79
+:105180001AAD284B8CAE67E29CB08EEC65B08E0AEF
+:10519000428B0751FDEC52301C32391C07FDEC2BC1
+:1051A000741AB81DFF45B02E588BCF973EE9DEAE7E
+:1051B00030F6F9B6B337198A619F795DB76D4D0145
+:1051C000389779E602BED3F12C60FC93798FCD0934
+:1051D000960C8697147AFF487249EE2C463EB51617
+:1051E0007D9481EBDA50FD85A2B3E23C8FCC390887
+:1051F000EB7E7E78BC58E72373AAF2AF665CCF796A
+:1052000094EF50EFEF8C2147FE53E8FF93795C2F2A
+:10521000C39F15E5938D9308B3819D940CF276F3AB
+:10522000A4D5A7D1A790AD4109E523BB08CF4F1462
+:1052300028C823784AFC441EB247795354E433E724
+:10524000C178361FD84E91F1B1C55A78339CE71911
+:10525000C3C07A0C77E98232ECC1F0925751609E5C
+:105260008E79B05F80371BB5FE65918E917D719F01
+:10527000BAEE8B372968A7DD97C7F5F09680BBECAF
+:105280001303FA7F4AD9274047998BFD920FE4AB6D
+:10529000ADD1AB04A19FE1D2DFEF372261DFC53A88
+:1052A000519F63FD9A08BB27478C6BB8A427BC1994
+:1052B0009ABD4A6AC4FC06BDE4EF8C617795E6C9E5
+:1052C000FCB96646ED86771E969C305F666348BAE9
+:1052D00087C6F14B0AD4DBC2BC3EABB1535A08F0CF
+:1052E0001D794E3A07759CACC5B0FE083CD9E5A0C7
+:1052F0006485E7ED8F0625C483DDEA555822E2DA9E
+:105300004BFCBD52F0B47DF5C4B24F86E1BABD8A04
+:1053100017E79BA5F29BDFCA703D1F2BBFA942BDBB
+:10532000F61B3DC3FB8C6F9C4A725A8C7DA8A5A9C5
+:105330005BCF3C97F16792721EF1939EBCDDE22C2D
+:1053400000FE7DF1364BC3D6187476471EA7B375A1
+:1053500099AADEE2EB49D7733CA9FAEA1B2BA71FF7
+:10536000556EAD4CE1B03ACECAECF12437865A8F77
+:10537000AD3D8EF922D6BB19E6B1E2FDCC772BAC60
+:105380008837F021BC349FCCE5E9D6E7DDE4374629
+:10539000D3CF203E00D19B5C8674D91D6A06BA31FA
+:1053A000CD332A682FDAFE5B8B84722493B54A28AA
+:1053B000476DD9B58765D4E7B2AFD81BC38EBE128F
+:1053C0003FA8E7A9DA2583CFCFF9BB2AB2430D0C5A
+:1053D000E9B6C9E5B4E1F9A974DA746478AA2FE2F0
+:1053E0003CD70B3A2E67AD7AE4D30AD6496525EB54
+:1053F000A2F23AD64BA58759652CAB9942652DF39D
+:1054000052398DF9A9AC63AD54CE649D54D6B32EF8
+:105410002AC1BFA3D2CBACE487DE08760C96739981
+:1054200097CA5B989FCA2D48DF13F0FEA195E0DB79
+:10543000592795BB80FF9D45181F3153B917E43993
+:10544000966F833CC7320CF2DC69C2F8889BCA8332
+:105450000185CA4381722A0F073CD4EF68A08ECA27
+:10546000E3012F9527020D5476057CD4EF5460316B
+:1054700095EF05FC54BE1F584DE507812095FF129E
+:10548000584F659111E40AE2DBDD3D16FD9A9C8FD1
+:105490008D1E27E8A34FF384FFEBD1FDF7E2F178EF
+:1054A0008E3ABA83B1D5AE94901E6D6E9D2704E5F9
+:1054B000467793743794EB4E703BD6644B243BD9BC
+:1054C000D6BE4A72C2B8BBA46E7D029CEDDEBC0F94
+:1054D000E798414F54ED656B1314847FFFA419E8DE
+:1054E00070ABC1DFBB15DA7FF5D2BFCE3183CEAE54
+:1054F000483CF5C7D7384CED930EB2662BC007F287
+:105500004E3F9926F175A0103EFED2C773D6E4E354
+:105510003AB91C79D5058E36FA190F5BC8CF18DB5E
+:105520007E66AC0EE049AB2D65E81F47F4A3B8F5E5
+:1055300050FDA2DBD5E73A56A437231ED67D0AEEEE
+:105540008913E565F7588CCF458EABBBBAF999FE48
+:1055500032F347F6932E335E5191E754DEFF037426
+:105560001E4DDF864B1FBFAEA3F8983515F5FAF632
+:10557000142E777AB3E343DB60DDDB5305BC219F58
+:10558000F6B50E61D8D7BA8DB964C76F8FF3361DE3
+:10559000C1F6BFD129DBA0697BBC6F6331C1F914AF
+:1055A000AF5997EA77A35ECA49E0FAB1CDF1489CBA
+:1055B0003382FFFF22E4EEE6CABEAEADE84FADD7C0
+:1055C000B102786EDBFA051BDC30CE4B9BC02E029D
+:1055D0003879F2C20D05D09EBB4137512F641EAE03
+:1055E000E3A54D0B5FD928E1B823530B61DC3C21C7
+:1055F0003F7386758F5D0974DE66D4C615FAF56350
+:105600003EE7978530CC19D0BF39225EB1D5C01A9C
+:1056100022F566413E97B73545BC344CE1F13CD3A9
+:1056200088F8D0E3B0FFAA113CFE93BED64CF19FA0
+:1056300074C77F9E9C0EEDE91D3A054D5AD9B6748C
+:105640008D01FD9EDB5827F2E356893F1FCCE6769D
+:1056500032182CB97322FC1EB037CAF223E2A7F627
+:1056600086A084718CAA114B258C37A73BEE933012
+:10567000FE91DEE0937C89E827F9A9FDAE229F2BFD
+:105680001FD6676F84E735F7B1BE0C3C5798B781DA
+:10569000F20964561639DFEC228E872764203DB468
+:1056A000DFD71A695DD1F89AE5AE1E993F7CE01C00
+:1056B000A3DBBFCCE7E7B8FD719802F960128F1F3A
+:1056C0009C783993ECE5D96DF11EF4234F3C39B247
+:1056D00096E0A72A3C68FF9E78B9621A96B39F9A13
+:1056E00049FD4E48EC30C605663F75BB8CF53979EF
+:1056F000B02E1CEFB491E871F653F789E71FA9C5E6
+:10570000F6725DF0EFD09F2E6F7E2D01E3051589B7
+:105710006F64617942D7BD6A3FCC7F8395FD1AD50E
+:10572000B57743DADFD4C13FE63C996BC0788C375C
+:105730003F97CEF326E631F07C072FF9B7953BBAB9
+:10574000DE018B8E5DD7D95B83D7BA9E5DD6835839
+:1057500056871534A359ED61EF412CA775F96BD12C
+:10576000BCA9FBA0F52096DD237D5EC4FFABFFED59
+:1057700096375E0578C463ABAC6887E63FDE3D6371
+:105780001BC52F0D0CF9A16092BF558F046CF6A6B6
+:10579000A27C78F6195987FADDE46A8D43D8744FF4
+:1057A000AE0EE34CDB535A17D3BE0BE219E2F128DD
+:1057B000E821A48B82146F2AF213F0259DC39D82E9
+:1057C0003E4D297E6B0AD68B7B8EFE7EF11C5ED809
+:1057D000DFAF354EA27952A5A0C4CD08B423EC4268
+:1057E0009FB7337F06E2C396E8DF8AF1AD822ACE07
+:1057F000FF2C91D305766F99488F50103EBDD53F51
+:105800000BCFC1E6EBCF1BE074076AB0DF3EC925C2
+:1058100098EE7F364B1C063943EBC23F8CE7A45B06
+:10582000D2C9CE51D76F6B80F122EC0EDCC78D96BA
+:1058300081E754BADB20F6F584280BE6F3F1D4F5C2
+:105840006ECCE77A1DD6EDD4E17AF4623DB00F5DFF
+:10585000C47A22FAD1FEFAD7CD143BD205637E89F1
+:1058600097CC2947EE7FA1CE13371AD7FFD65F61B9
+:105870005C2909E508ACF367FB2799914FA3F7F181
+:1058800042BE88FB80BD8CFEC34C1FE7DFE646BFEF
+:1058900084FE940D61DCBF43F6605CD46669920CB3
+:1058A00011FBB539B89E9ED9E8DF8F7265667982A3
+:1058B00082F43D8B75AEB572FE3E980FEB2B62FD08
+:1058C0007F163671C04E7CFE99F74EE2913A5867CA
+:1058D0005531EACFC7EEA5BC89CD8FCC3C8CEBCF40
+:1058E000743FB93F1506F47E2DCE7D3E8F6F6577F0
+:1058F000C89ABC872CBFACC98BC858AC6D077AD08E
+:10590000C02A5DD9A5D529A86F7409253367A09D44
+:1059100092A423F90E724A9A1BD31E8DA22B817F6B
+:10592000F57CDECDCFA773B359F839B05EC57C7373
+:10593000A2D8AC7A4E306F33B07932D07D73AD3EA1
+:1059400024A11F8FFDF132B2970DF7260E3EA7ADB1
+:1059500006E7CC1928A71FD45929AF2A0AAFA06798
+:10596000FE99FC9407D3A81DEA6533C53D23D6AB49
+:105970008F056BCFE34AFD3B5878CE0CD7E0FA4C4D
+:10598000C7DC99A8673397323AFFE8F6A247B5E734
+:105990004A7EEF788CA3B150F8079CE74CC7F65AC3
+:1059A000B4EFA3CF55A5BB9C61B1F5C223055C2F15
+:1059B000E42428A7EAC8AE90C94EF066CBC323FD05
+:1059C000A4EFF2B91F30E55716D243EC6373081FFA
+:1059D00055C25D3F298673A8EED3A1FBC2DE3D7E92
+:1059E000E0E999504EFDF57B4DC7A0DFD4EF2CE3E5
+:1059F000B07E37EB9E8181A0E06103F98D6BBE7CA8
+:105A0000A5150344CD8D4C41BDABCEE328E0FA6E25
+:105A10008F21E425F95A2CB36D2407D9C54B11F415
+:105A200002909EE887B7316F632BF991B6FC12861E
+:105A3000793CCDACF30ED297678D0CE3AF37363897
+:105A40000D55B0FF1B1B9D86F9789F21B33AB423F7
+:105A50006E6A50A8FEA64685D79B79FDDC060FD559
+:105A6000CF6DF4F07A0BD45B300F29D41580716FB1
+:105A7000B6A43A75781FD0E8E5ED174CD47E1CFC2F
+:105A800001CC278C8F0B91BC6FEDD1F17B237F7CF8
+:105A90004882B59A12CB0E3B117FF7E8145017CC11
+:105AA000942D332BC0CF3678437A687F8E853210A1
+:105AB00091BB1736790BA17EB743B6E2FE76837BA6
+:105AC0008BF947C1A532E19DFE00DEBDD841F73A12
+:105AD0005B45FC3EB8C44CF166B07528DECC9664DC
+:105AE0000A3B86B7772CB086D01E033948E7D87BAF
+:105AF0008F4C7600C8C3A36EB48B76E62B189FCA72
+:105B00005CAAE5B7F4850BAA68BC4666453FBDBEF6
+:105B1000918FD7BC5317D2A15D65B97126D241F3DD
+:105B20000EA6A03FFBECC253B5C310EE50142E3F9F
+:105B3000B472A179E153479CB81FBFCE5A40FD799A
+:105B40001CAFD95FBD5D2F0DF0339DB773407E0C48
+:105B50009637CA611C27635EB582F1C174D827C627
+:105B6000F33B8CBC3E78A74CF72DE90BE5B075F400
+:105B7000007F670B14A6231F26917CD1F0D7C89D08
+:105B80005AF879C1A7C0EF32EE2BB89D513E67D1CC
+:105B9000766D3F90933A9457D9EDDAFA5B8BFAE33E
+:105BA000021A3C44E3D9E6E7722F7A9F03FB0AC747
+:105BB00015D1BE747C5F28D7A0BED87280EA8B1B3B
+:105BC00065C5E94479D7790AF75FB453666180EB1C
+:105BD0001796CD447AAADFA4A3F0C8F5AC8BE4C233
+:105BE00095F6ADC63BA2F719BDBFEFF2F55C8EA8E6
+:105BF000F6E01366B207DB1EB6E8F09E15ECAD7852
+:105C00008C2BDC55541D2C407B40C81DC3253D9773
+:105C100027CD16A25383ED517764FCA16554F5138B
+:105C200005D46FD88D753C6E41FB8E96633F17E3AC
+:105C30004DEAD6E6E35DDB131F953FA6CDC79B7209
+:105C400021332A7F2C2F2A7F6C94A67DAA755C5461
+:105C5000FED8B551F963351A78967B96A6FFF5CA3A
+:105C60004D1AF886F23B34FDE778EED6B4DF547770
+:105C7000BFA6FD66EF4A0D7C6BC35F6BFADFE66B78
+:105C8000D6B4DFB1F8279AF668FF492D771570F979
+:105C9000BED9EE3F49016CD0F791F73D6A99DE28F5
+:105CA000F7469E7B5202B7A7A2FBFDB980D3FB8BC0
+:105CB000129F8F05ED9A781CF3D835F1BA7045859F
+:105CC000B91BC6711A95DF21DD62E20EBFBFB66B4C
+:105CD000EED9F63F0EFD60BCA6C45C1BEA3B8CFF10
+:105CE000FA40B9378774745F615BBF4A223DB86977
+:105CF000158FAB5C30523CAF7F1DAC8EC6FB46DCD3
+:105D00006BA9EBEC1071A42D18474285E49941FD75
+:105D100056C6F17E3F4D57E38E3E1A37A3DC18A4DA
+:105D2000FCBC857E09E3C0CD3E66C57B9374CB0287
+:105D30009AFF9B0625995D262EDA16B0330FCC67A5
+:105D40005F155C6384BD7D52D0F7D4B3F0BCDDCF6A
+:105D5000281ED35BF0ED53188FE943E108749D21B1
+:105D6000733C3FF7C0EECF5F81F9DAE6A597A15CFF
+:105D70008D6ECF5ABEF7EB4397697F6ED95B1FDEFE
+:105D80007BB9E71FD875BA25A27DC838694326F3C9
+:105D900044D001E02CE6FD805CC8F5F9F20A23C589
+:105DA000B1AE01FC1502BEBFAAF8CF893BE0B93FF6
+:105DB00039FBEE443B1DEA65AC877E84D73FE59F07
+:105DC000A3FC929C5160DFA3FD1D179B6EC715724B
+:105DD000BA956D8DBD18076A4A343AD1CFCF32BB20
+:105DE000CA3E1907746DE07E75B4FFFE5CBFBFDD6F
+:105DF00049FE779118274B947A2B7F9E99834C4EBE
+:105E000017F71431F0A14F6A97505E652E943F8DBD
+:105E1000E48BFD89468A23A45B44DCC1B258131786
+:105E200050E306FB13EF9590EED3C34B289E8FF102
+:105E3000021C6F5CA193D6111D2FC832E7D3BA861E
+:105E40001E9FF5D7274831E6895A871A9F889E27D3
+:105E500084F604EA9965F1644F44EF7B4961557912
+:105E6000E170E4D7DE93D3517E9F32903E1C8A5E70
+:105E700030CF3C1431FEB442EEDF63FE78643DE681
+:105E8000878722E3D9CC41EF2B100C2A6684B17BA3
+:105E90004311CE7794CF77C2A0D8C91E04B587FE30
+:105EA0005F7D21D703D330976D38F219F7CBDB81B3
+:105EB000AFB1DC12B0927DD601FC87F00B012795C3
+:105EC000A1809BCA6D0185DAB707CA097E25E0214A
+:105ED0007847A08ECAD7025EAADF196820F8E701CA
+:105EE0001F959D81C554FF46C04FF09B81D504BFCF
+:105EF00085F66001C6A9D753B93BD04AED7B03EDC7
+:105F000004BF1D0851190EECA0FA03814E820F0642
+:105F100076117C281026F870E0309547035D547F99
+:105F20003CF001C137E33EC9AE58DF15C078854F5C
+:105F300076A27DF7AC6FA115ED6BFB7C9D15C57945
+:105F4000BB4FB704E31C1D8DFC1E13EF23310E0461
+:105F5000766808ED39FBFC678E4CA5F6B9D4BE19FE
+:105F60008704A7C4B682DBAF6C9991FAD930210AB5
+:105F70009EEB58DA18D203DC5A184FEDB61532F9F9
+:105F80006DCFE9FC2985DCEE22F96D3370FB41A56C
+:105F90008335855CDEAE29E4F75C1F16F1734ACACF
+:105FA0008BAD479E2D54EDA6F587717FF679B03FF6
+:105FB0005CEFBC5566BC97B5DDA3B3727B93DFCBBA
+:105FC0003A60BFB87E580FC585D97C6E2FDBE6AD31
+:105FD000A57539E6DF48EDD6A24753D04F6FF7AF2E
+:105FE0009A43EB6D9429AED9EE3B9082F76CCF8942
+:105FF0007C27DBF0786FA864F07A9E8D5A7F07E3E8
+:106000007E8303ECA5D763EC03D36E49CF3011C771
+:106010007BD41C338ED729E8D72171FE630FCAC405
+:106020007F2F30B0FBE0B92D60DF05510E54BFB6B5
+:1060300002E355BD85BE9D28379F778E3F20039C88
+:106040005AC7C7CF5D25BF8276349CF7E72D50BF76
+:10605000E1BE4D5E5CEAB04DCE35C86EEDF3DFCAF1
+:10606000C0F89743D29E8F5ABE2DF6F982878FB71C
+:1060700065954CF164DB8A375D07F9BCBB91FF3352
+:106080008B3E8AC3304CDE5CA70E4586639EFC3592
+:10609000CE1777FFA63A42CD268F3ADF589CEF6A9B
+:1060A000F134E2B15A9B2FC6BA869227579223BF8A
+:1060B0002914EF8164B12C9423CF19B8DC0A9EE433
+:1060C000F62425054D1A3C8F9A2FA0E60F44E70BC6
+:1060D000FC5EE029CBC462DEE77ED64FBF413AD7F3
+:1060E000173C1BBD9467E3923149873519D8127A62
+:1060F000EFA72ADEBA26063DA8E55328C700C11F30
+:106100001632712E9BEAF8383A3ECE64B682E02A07
+:106110008B3518435EABE533629C7F2BE4749B7533
+:10612000DFCE0D87F07C8F1A28376A8B2EB401FDE5
+:1061300084E0093DC9D74C7DE7D65722D6F51741F3
+:106140009F5B8CA162BC876E87F14A50AE22BF94E0
+:1061500050FC82D547E05D7DEE3F841DF0FCC575A7
+:106160002974FF3C6F6D1CDA47EDCC4CF46033F8BA
+:1061700053C646D0830DE932067D388B8C340EFC35
+:1061800059AA26E2BD0CD7CB35289760DDFB162631
+:10619000913EAC99FFDEAC310057F6C994CFB265A1
+:1061A00029CFD39CF4EF3ACA1379FB31EEF75DF7B0
+:1061B000502DBD9F9421CA67D1CF83B2723D53C287
+:1061C000702E950B2D14BF997C413E13E9A75148C1
+:1061D0007A3CFA173C5E736DAFAC790F6D528FB697
+:1061E0003F60548F764646B7B6DE3EEFCDD353615F
+:1061F0009EF6A5FCE1F68BBF3B827070958EE22483
+:10620000EAFB64509341F14D399881F99B1BCC8C8A
+:10621000E4B96DBED98AF2607F7A3CC9BFF6DB2C47
+:106220006487AECB6F8A433BD9346F550A96238C73
+:10623000C1AD183BBDE6D52D37D92791BC55F355D7
+:1062400082AC1CEC81BB8DDCC8093EF7F45419E527
+:1062500025CF6799F4EA96A783F9D8AD95D6E1D40E
+:10626000B14CBEF97EF876BAB796B8BE701AA11DC9
+:10627000E079A37CD715417B465A703F366DB69CBA
+:1062800069A47C6B4C3282F90D0BFDCC88F58D65D1
+:10629000E6483E57F9E4FBF27F3CC687875F590E1C
+:1062A0005C69DC2BF17B413EE79BA1FC69D310F2DA
+:1062B00054F58F1F29E0FC8B6C4B7AF58C31A67D51
+:1062C000F5AB22CE67E5469EA732BB615A1DDDC302
+:1062D00004BB65CCE77B51DC0BB5A727D23D717BB6
+:1062E0002E0BE3BD4170818EC77BD2F87FED8DB957
+:1062F000141F6A93FC29C13CCC97F0B9F0FCDA0179
+:106300004789307F5B0E97EB2CE4B7E27D358CB389
+:106310003872FDE0EF05B574CCC81EA6F8859E78EE
+:10632000CF698C88B7635C1CE317D1CF4DEED5C223
+:10633000532E68E12A66D0C035662D3CD5AA853734
+:1063400015713B7DBA5D5B3FC3A9851DD907E37419
+:106350003CCFDFC222E249F0F75E7E441C68DD6874
+:10636000FE3E5F76F7528ACBB6E5F0788F639536BE
+:10637000CE91C54212E22F7369543CD6BD663F866A
+:1063800097ED0BA3E341FC5E02F0A1A947318A7CA3
+:10639000F0EA689E87DE3DD2B7BD08CEB3600C5FE1
+:1063A000C7AB1D4D743FC5DAD388AF5C225F69B0BF
+:1063B000BE7C8AE8401D0FF92218B17FE48748F8B7
+:1063C000A151BE37701EE48B60A4FE2CE936D0FBD1
+:1063D000AB62BEA1F843E5CF72718FA2E6DDF4890E
+:1063E000B1D4BC9B55225F705754BE4E9FA3361943
+:1063F000FDE7BEAE95F1B1F810F92E68E27C88E5B4
+:1064000006917F837C182CE27C88F5A6EF56786392
+:10641000D98B0B055DDCBF63C9864F22F6B7AC7321
+:1064200085065EBEEBE10D91F951F7E33F3008BF01
+:106430009E517EED52B19D2F4FFFCB2BCD0CCD4801
+:10644000DF0728CF96159C31F27BA75E239EEB4297
+:1064500061FF99CCB3F2D12FDB11E2F26C9D88374A
+:10646000345B1533C681993B5513C750E3114D4B2F
+:106470005CB654D847727F7CC16BA57CDCE1F91413
+:10648000DF48AAF1DCCEC632D653649C6B0662DDCF
+:106490008EC156C0E9F957D93341C7C0BE4D17F870
+:1064A0007BC9FDB0EC67248F2EE468EADB449CA333
+:1064B0009FBF2D0BAA703E8BDB49FBB031FF1A1E2C
+:1064C00017D4C6D14CE23DE7C1E33B34F56D227EE3
+:1064D00072E5F1B57139D385BC21C62F8C1ADF1A4C
+:1064E00073FC8171B5F1BDABB8374F714F183A2EBF
+:1064F00036D2CDE9699DDDDF85713183E07F6606A7
+:106500003A9988F280FFE9E3797EAEC1A18D8F19B7
+:1065100030AF0BFA3F97B898E48AFA3EB5FD99057B
+:1065200012CACB27F0FDE8A4C1F2245A8ED844DE6B
+:106530007CB41C81F93470D3C35CCF364B8A0FE531
+:1065400073F47EFE7FF1877589E3BBC8AECE8E778C
+:106550009A2E630FB7058263F1B975F1FEC578070E
+:106560007EF78E91694F94E37BEB8CF86CC58E2996
+:1065700073310FB64DF0EB13693AA2A7F4DBD3B732
+:10658000EA23E829DDE873A13D9CAE13F95FF887A3
+:1065900071B427D2B76D8C31BF6AD7A9B0AD01D61F
+:1065A00011718E6DC29EEE9FEF8ECCADFA8871D2C6
+:1065B0004DBEB1345F7FFEA398AFE587CDB759C418
+:1065C000C3D4F96C776AF76733FA697F36A187D449
+:1065D000F936E3FE62F0D515E713FE75FF7C7769A7
+:1065E000F76733F9697F36F53B1BEA7C2D3F6C3E3C
+:1065F000BBE0CF76F1DE973D9E7F3764A8F7239A04
+:10660000FBF3CCBD66942FED6ABC50E8BB7351FA26
+:10661000AE49E83BF5F97369B914FF3D77F8267385
+:106620002C3D87FA8D093B93093B93093B13E1D934
+:1066300035A7570D077AFCBB1D37CF9541AFCFBEAD
+:10664000FFF4F81C80DFD9F18BB932E8A9D9AF9EED
+:106650007E330B1E29FEDBFB38FCF4E93E07B45BFE
+:1066600082CFCCAD05386918D7CFEABAD57977B9DA
+:10667000B95DB97C751E8F6F829C453DD69CE367E2
+:10668000187FFCCAD19B341FFA2FCFEE4D5F100349
+:106690002F6AB97C75217F1EADC08998CFC648AFDF
+:1066A000DDA8BEC752A77D8F25296923D987712C04
+:1066B0006445399660F6D0FB97D71673BD70335397
+:1066C0001AB85FE12C10791CF4DECB4DE5625C6BEF
+:1066D000E52FB1FD669DE709F477FF79D2BCE1684B
+:1066E0003EAB7973A306DE3BDDFE7DDE4F9EFDB142
+:1066F000C46DE5641E8F9936CAC9DF7B8B882BA2D7
+:106700005D3C143E3F7573FF7E009F1E8ECF540F7D
+:10671000C7A7B537690D9CFFF294DEF4C7894FC354
+:1067200031F13508AF51F8FB939BA97EA01EED888F
+:106730002BE15BC5AB9A5FD82C390BC85E67199A01
+:10674000FC60C61467AC7B1EA4CF483D6BB47B19BC
+:10675000DAA38634C58DF9EFCD7FD1C7CCDB7315B5
+:106760008BF85E523CE57D362719C91FDF9F3493B5
+:1067700061FC59B64C23BCD426D5513EA67E18EBFD
+:10678000447F353A0F5D9F7C3BE509E96DE8614048
+:10679000D99FC7EC31235FE93F56925D4800579976
+:1067A000872E5F290F3D7526CF434F323A315ED891
+:1067B0009E688C9987FEAD9BFB5DFB717F69B81F5E
+:1067C00023FF6E88D8976CE5F7EE589F00F546AB2F
+:1067D0008F51FC5DECFF5B6107A9FD4D563F43F90E
+:1067E000A0372A4EB45FF4A95C7FE0775BDC31E22E
+:1067F000285FBB0DF4FCFDA3AC5CCF99B9DD3EFB7B
+:1068000037B1DF27282B9644BC2436DD0D453737BA
+:10681000EA78DE9DCA97732D46CA079C6BB1D3F701
+:106820006CE60221F6A446F4BFEE56FE3EB5ACD8A7
+:10683000919E7E7BED945FFE96E1B50097DBA766A7
+:1068400018E8BDC25312F328A983F35DBDDE94A9F5
+:10685000B8CC1BEA4FAF45762C18C3C84E7A75C129
+:1068600043AD954EF28FEA8A919E7D73A6A20F7773
+:1068700063C3D877B1FFF2042ECFD5FBA5E509FCA1
+:106880007DDE6B64DF6CECFF55C51749D5485F7240
+:106890006F0EAE2BA23FDD3345F49F5B3C81FACFF8
+:1068A000E6AFDDF5D27739CEA59DF9C8C7E87CEC17
+:1068B000B1EC29F4B758E4BD86901FE87745D6A31C
+:1068C000BFC522CE535A506EEB8E214FD432C33EF9
+:1068D0006EE442A0D78C8CB154AAF5CF7AF475A19E
+:1068E00018E7FC9038E71FECF7B4C36A270EF83DB1
+:1068F000E0EF3C84F8F872E1A9F4F1B0A5076ABFB3
+:1069000026BFC76EECFFCE16F97103B0F6BEB32DED
+:10691000D05B8CDF196088878911F98B62BFF625FF
+:106920006B52D0EF81B3F420DD7604BC236B0D03F2
+:10693000CFBF2CE4080B16D2F306B12E475AEB0C4E
+:106940008CBB382C3ACA7360CCAA9167736A53A681
+:10695000A6A10BBB9C291627FAF75DE41764E0FBA0
+:106960000D189F7CE73686F75F59699D12DA75FD31
+:10697000F388F7C657897BE13E5F2DED27C3D6EF3D
+:106980009731F25FD38273506EF53DC35794F19205
+:10699000B6DD91C6F31FEE5D181F7202BD672DEDC7
+:1069A000C24F4FB00C70F830A69F71A9D9D5827232
+:1069B000E657091477D6B7E7B320C8FBB0ECFB1B4A
+:1069C000C277C8F9902E4F6C169E5BB6289EECB924
+:1069D00076A97506F931F7E858AC78D1CE62EEA702
+:1069E000FC8F622BBFCFB54FE4F4631F3F72E1B859
+:1069F000ABE7FF77849EF949B293DE7F52EDA34D5A
+:106A000043F8478E913A215F845E11F833339F1922
+:106A1000F9452F7979B074C76BAFBD96CEE8535B5B
+:106A200048471B84FDA38E139F1FA2C678C543F25F
+:106A300052B27AB8BEB0FAED4138AF75DFE963CE35
+:106A4000FF85A0FB35D90FD9B17FADD3E7C632FAA8
+:106A50003D98969C7BDD783E2D33FBE995ECBA960C
+:106A600033CEDF613E56F028CF37D89F5D68C3EF45
+:106A700041590E1B64D365E2F146D027CECBD8191D
+:106A80004691AFDE7280E799B658CABA30AFA1C559
+:106A90009256466AD8C2F356D5FE16CB21D20716B7
+:106AA00085DFDF5A507F48B84CC04709AEEB10E194
+:106AB00043ED7750C85D8B1266F85E5A9CD24AFD52
+:106AC000CCB2D78379CAE63446F744662BF017E296
+:106AD000355FC7CC31F4C9BE62AE4F5A4ACABAAAB2
+:106AE000697D327EB98EB5D8CBECA4E711EFF07C8E
+:106AF000738696CFBF137857C76916F9B477AE4E31
+:106B000009D68EC33893F71BA4E716CB027310F592
+:106B10005AE2F8CB8E671A39D478FBD78AF1BE4394
+:106B200079AE4F2CB3E27806C6F7158DF7E1629C7B
+:106B3000FFD5FB7BC02CBD474D301D58D81EEB7DCB
+:106B4000ACFEF313F7F2D1CFFD6079BC561B870280
+:106B500079EC1E09FB5A5672E65035D5F0F8D30B86
+:106B6000C29F51FD927431F60B127FBF3F28C52B97
+:106B7000F45D0CE1A7A4C769F130F03E2D3F876FAB
+:106B80001A781EDE37694C7C874ECBD7DF1CFF3866
+:106B900045939F057CEC31713FC623DEA7F588380D
+:106BA0001DC2186FA0179D04FFF7C7891B9C3FC328
+:106BB000EFAC99408EEB605CC9E127FA3639BA5DDB
+:106BC000C8EF39E2FB0FD178FEC9482EAFA5477A4E
+:106BD0005C78AF519BD69B118BDF5F7CF84206EE51
+:106BE000E7C519FD793B74DFF4E269E7E602C4CB3F
+:106BF00011EDFB6FEAF84D47CEA7F822FDA5C0E5E1
+:106C0000DF2F4B3AB37125D98D0BB8DDF87FFA7DB4
+:106C1000B317E6733B7597A495CF4F08B91C14FCC6
+:106C200060BB20D3F743EE2AF2AD403A6A93AC0B37
+:106C3000502EE73CCCF3F29A1E5BD5B328067FB406
+:106C40008CF2FDD5C808BFBA7CBD91E45EB3253790
+:106C5000F972F728439FBB9FE4947ADE558F9879A9
+:106C6000BE8A8FDBD1E9BE7B290F263A3F65A87E1D
+:106C7000D5239D440F6A7F138E8FF2C57223C515ED
+:106C8000CEA18F81713B2BB733A2D75989C898C049
+:106C9000F163067D997460491C8E6B10FEDC0B6AF3
+:106CA0005CA4A1CCEC8978DE705B99B93A824E9AEB
+:106CB00019CF0F8E1EFF372355FB22ACB1630CA8F2
+:106CC0007F31C694269FED973B6478F2FCB4950320
+:106CD0007CCCE30E43E7A3C571BE2D237BAC0DF343
+:106CE000D2C00E5ED3B06004E2B74DF6BD68033C7F
+:106CF000F47E68A23CEADF0B3EED167C3AD4F9053F
+:106D0000D90130D2187B9C1DC497E2804EC6272340
+:106D10005F34E7EBEA4231F6795CECF332F67878EF
+:106D2000E4F7B3C70F89FE1A7B1CED6D4FD4FD4607
+:106D3000248C76B627863D7E4212F105912774C2D7
+:106D4000E0DCD50D7839313999BE975690C0EF5DAA
+:106D50004EA07F52067EC8ABA7F3D17E992DF57F5A
+:106D60001749F8438C60F047FE05F9620EF3BFB691
+:106D700048223EE2F735781B9F7EE573DE3692D1DE
+:106D8000BA36C0F9E1FD46DBC5F93362DD67A48E92
+:106D900052FD37506511EF13333C9D88FBAC41F732
+:106DA0007451F772786DD39F77AC1FDCFF8672ED5C
+:106DB000BDD9868B3C2E625AC2428F4B9897AA6DE2
+:106DC000BFA9CE107D2FA8B94FBBD96B885E0F7DB0
+:106DD00017D421D69BDD711FDDBF4FCDE6F944A648
+:106DE000658CE204D1F76DA6B15D1E3DDACF0D8C46
+:106DF000ECFDE83839E6A952FCB081B12D12E579F5
+:106E00006BDF7379A6FE73FE7D94D63A9CC70E762F
+:106E100010DAD3D1EF49A8F75AEAF751553CABDF66
+:106E20008F4ABF4D47EB63C129D4AEC6FDF17BB895
+:106E300055E911F9E42B587F7F7A7F2B187BDF9B74
+:106E4000DBEA29CF2073BC7F6C189AB2144678C84D
+:106E50005AC8C86F003C68F2094CD9DB699FE71635
+:106E600033364C223C68DA3340D3D3FDC0426D7ECA
+:106E700001EC530347FBAB57F2534DD9F99795F308
+:106E8000578A639AC4BDE49451E2FB97A5AC14ED14
+:106E9000A2F4DB9EA1F33807E781715F749C62DD89
+:106EA0003B6E82F1D18FFC77C12FCDE26E5BFDAEE0
+:106EB0000FF3C8F41E9B54CED72C0DF3F27BE912CE
+:106EC000467C6E8A6766CC8F972A4C1EC4BBC90469
+:106ED000306C5932327306D4EB453C7B8DC46484EC
+:106EE000995531F3F8A3FA5DA1107D5768A879D4BC
+:106EF000EF2BB2207F4E9D67D077F52EF33CF97BC8
+:106F0000D6E8E76B299EA9CE3F14FE87FA8EDEBF36
+:106F1000D5BC3781C7531D44AF8D03F44AF07C4183
+:106F20008FF83CCA85BBD5667B5729FA0F671E4C84
+:106F300050364A11FB08CED2F3EF037EBFF1FAD7E9
+:106F4000617792BCEFDF9718EFFBEE8BFE22E4DA5D
+:106F50003A7C5909F35E1A19E531A4FBAA3F972937
+:106F6000FF00F6A0911311DF4980F1D63DCEEF1F4F
+:106F700036E3773EF0FEE7C040FEED13166CF7D126
+:106F80007736D4BC5CCCA35D5B32F03E72F47D837B
+:106F9000BD11C689986FB2990513409FA4F43105BD
+:106FA000BFF3ECB96854A6037E6C7DA05001BF937B
+:106FB0009989EEA52AAD7E33FF0EE10A166967EFC7
+:106FC000976EA5EFBD86BF6494BF143ECF88EEC315
+:106FD0009FC3C4702EFFF8DDFB7AE4CBA97D5D7AF8
+:106FE000D4F393FBFCA47FF6D94F3DEDE2E7629921
+:106FF00011911F751D5B54CFE98A9F972CEA275F7B
+:10700000306AF8FDDA5EA3461EC8175BBE46FD6512
+:10701000EA89AA67D33FE3E3F928DE2DDBB5ED5318
+:10702000443ED0DB2ADF5FC3AEA173BC981633CFDA
+:107030006EE0DCD5736EE27174C6C7796E94F79F0B
+:10704000464D40FFC04771E864C42FD8172995DD2D
+:10705000CC8E7958E54C998E72BDB2F31DA487E4AD
+:10706000B33C0F3C7AFCFD5FBE95857EC39EC99DF7
+:1070700059682FEDF9F2153D8E57D5D3CBB03E1997
+:107080004A1EA4584C78AA10B43350CFE34491F56B
+:10709000B49E4AE765E5E4CF504E1A876EDF33D9D8
+:1070A000C2C2E4877526A03DC77C7CFE64B3CA5784
+:1070B000EC2F97705E84819FF654EA526A619F7B41
+:1070C0009E91156CDCD3F34602CEBFE7EC39CD7A46
+:1070D00098FE22F345ACFB5A71EE532B7BC9FE7E22
+:1070E0004AAC2BF96C2FC5A15395DE30EADBD4C333
+:1070F0007AFAFE37B3F0BCC8614CA1389ABA5EFC8C
+:107100006E2A3ED78272DE88FBB3325628EC7E2888
+:10711000332A8355988F9ACC764A486B532B7D41FE
+:10712000A4E7E4A59C9E93ADFEC318BF4F5EAFA33A
+:107130003845F259DF06F4CB92CB6505C9E44AF82D
+:10714000EC10F3B78AF9D4F9D5F58CA8F44BE87EA6
+:1071500024B3E362FEAE2A138EBF5ACCEF14EB5970
+:10716000C5E83B2CC967AD55E82F27839D41DF3328
+:10717000B8E2799A35F345B7274FD99945E7E0B199
+:107180001ED90AE3A5645B365441B9CEA123FF3270
+:10719000A987513C3DA9279DE47D524FA128278A0C
+:1071A000FA69420F703993D4F3502DAF6FA1D2A476
+:1071B000CA17873F8CFB98DACBB87C717849BE98A8
+:1071C000D2B87C51E9B856952BCC5A321FEAF70F4A
+:1071D000FFACB5069E7BF773FEFEE5BBD95CBEBC7B
+:1071E000FB25F7FB4D69BFD3A35CAA42C305FA4D4B
+:1071F000BBC0ED33951FABBA25361148639A83E7C0
+:10720000871FBAC89F3B84D9D500AF6312C929959F
+:107210006E6B05DDAEB3EA8349D8FE8189DE773433
+:1072200039CEE598C11EFE83AEF7417CEFF8F73307
+:107230007AEF5D41F5827E434B492E9A846C39E4A6
+:107240005860413E847948AE1E7218E9BC0E083A77
+:107250003E67AFE908C33F5BCCDFFC693ED4FFC1AA
+:107260009EEB40934C3D971E412F5F88F33B2BE8EC
+:10727000A629DD7B53C904FCFE621ECD7BCEFE0D2C
+:10728000BD7FB2DCF61F9FC6FA2EA73A8EFA7C4F5E
+:1072900068A519CFF5D09B1F9F40B4ABE35F237B5C
+:1072A000EFE4E37E339AF8D0123BCF7890FCF3AD55
+:1072B00088967F8B4A860FC8BF7A6691791E12E73F
+:1072C000EB59421E4D55B8DD5E6FE5E7555FB25F85
+:1072D000A6FE8A8BF655AFD28DF2E45AE47F9BF27C
+:1072E00024D14B7D3EA797BD829E0F0A7CCEEC63D6
+:1072F0009DE897ED2F986E190BF83EE2D213FF1C14
+:1073000019BBC65206CF1D2995F04B026C7AC9D61F
+:10731000B5A900CF5224A2A7FA92AD1D4DD07F96F9
+:107320003541A903F8E8F9B31634AF0E05BC8497CC
+:10733000E972F8E354179E1BC7D3CCCAB08CFE4F3A
+:10734000BD63BF8CFAF66DC4AB11E32E1EC1677529
+:10735000041F576A2CB88F23A526212F3DE3515EC9
+:10736000CECA37D58FA1757C7D6C4C1ABE776F5015
+:10737000F8953CA7FFC9827EEACC276B53A0DFCCEF
+:10738000926619D77BD42C91FC3CDAD744F993C789
+:107390003B39ACD22D3D077479BC6F5B7312B66F6D
+:1073A00097483ED52B2F1DE2EA8FD3A73A7E0F0BCD
+:1073B000B6E17730CF29AFB7603EF5B1BE05CFCC8F
+:1073C000013C1C7F533FC4B84D1FADC071DF4C243E
+:1073D0003A9E6D3569F4B18C4E69845EAD1E6FD3F3
+:1073E000C0F54A0DC5D3CF2992E50678DEF35DAD31
+:1073F0007B3991D152DA77BDE87B4CE17C79CCA125
+:1074000023BE3CD6F7B89C8AF05946FB919976DEAC
+:10741000FA921AB2AFCE295BF54467820FD5F154C8
+:107420003A3E8A4F231EED9CFF8FF66DB320BD1DA3
+:1074300075BF23E3395D67891A57D0A1AADFF05DD4
+:1074400071A49FDA51FBF37E86EB5138FE6B94D723
+:107450008F237DD53B64A2A7A3CAFE9A1486BF27BB
+:1074600062D2ECFFFE1DC99AF19775DA3470B45DF3
+:10747000B5CFFDDBA7CBC40E66A447D847F9C23E03
+:10748000D21F77E0FAAE681729EBE8F74906D9452D
+:10749000F9DC2E8AB68754BE6ED689B8AC8EC76525
+:1074A000A3F9DF58FAC3EEF1D82A498EBCBF5BC6F8
+:1074B000BA7390BEE6A31286F11ED075A723FC1501
+:1074C000EB6D8B07397CADCC7669BFBFCABF373F48
+:1074D000BED4771EE59574364CDF6165AB18E507C1
+:1074E000E86B789E115E66AD88D48B25FDF12D8DFD
+:1074F0005DA44BD89B8578AC386BE4F18F9EE8385F
+:1075000097EA1F8525F22BAE522EEA93F9B87BE657
+:10751000F078677F79338F931509FCE5941A695DDC
+:107520008A80F7DC16FB9EB5A454FA41F9A2DF0766
+:10753000DF2980EFAF90E6619E3D55B1D79152CAE9
+:10754000E3B5779778F24AA12C2AF11596225E3D91
+:10755000605FD377C53D649FA9E3BC33CAE316FDE2
+:107560004661C9BCDC0E8FEE07ED63689C86D8E3EC
+:1075700040FB387A7E6EECF643B839FC7D23FB3055
+:10758000D243060C64A6F2522AE3E516FAAE468808
+:10759000FBE70D1ED2F34691AF88371091FCC7F47C
+:1075A000F534BE1C9E41F7582DD82583FBF9917602
+:1075B00094AC846A22E3AD6AB9A894DF73CE28152F
+:1075C000EFF34C6013C8AFA8BCFC3CEAF343CDC357
+:1075D000EC6557C87B5EF363D349FAC3E4275FA524
+:1075E0007D600E4A91DF391F6ABF894A941C8AC2A6
+:1075F000D350F35CED79DC22E8F66AD75D657ACC8E
+:107600004EF9D12ECE076B057DF5DBD53F1E3FBE73
+:107610003F1F86FECAD9FBFE93F87E4A4268A53713
+:10762000C67E5E14FBF931E5C1D370CE1B8CA1FB85
+:10763000D1DE9907A76302D27BC7F2F1F005B09EB5
+:1076400037C5FC2D9695EB6F85475B1CBA98F91EE4
+:107650006FFE787AA20D3FD9FF95E3DCFB6D20A782
+:107660005B1E7DD0ACB08175306BD915CEF947E388
+:1076700013755D6D5B305E624DBDAAF7145A5CAF49
+:1076800024E07D69EDE74D76FC0E46B43DA0C6438F
+:1076900054BDA5C64D54BBA4C2C1E31F33EDFC7B52
+:1076A0003D15F669A4DF0FB2AE1AF2AF303B6D2282
+:1076B000B10AFD19DD5AFBE43ABF57463B2ADA9E70
+:1076C000A84D3345D907BD7A94DF1517B5FD54FE93
+:1076D000F8AC54C45154791765479ACF9F4940BBC1
+:1076E000EBED0B67282E148D9FEB2E5CDE9FBDAE5D
+:1076F0005D4FF783D171ADB72FE4D2FDA011AF1B61
+:10770000C1D4CACC3FC48C80974C7B6B9511EC18CC
+:10771000A38329F8DD36FC5833C60D8D17789C7C81
+:10772000849DFBD7898BC12F85513395A07DC1786E
+:107730007CCE48EFD3995DEF91BDBD09EA86219ECD
+:10774000C79E19A68B110753CF638AC0EF6EE6B7A9
+:10775000E3EF814DB18BF7F72E46DB59FC3C2DA2B0
+:107760007FE2622D3E2DE23C27835B43DF79ECD341
+:107770003E6F11E76B591AFB1CECA3639F43A27A7F
+:107780000E13B6C5E1396C59BC4D8A750E998B2F15
+:107790007F0E5B845FA9D2EFB4AC04B2AFF7A6E86A
+:1077A000E8FB417B13C359CB31FEFDB299DECFAC70
+:1077B000107136B4A4109F6BB797BF8471DB71A3AF
+:1077C000F5748E7B25D1FFBC8EFFFE60CF78EA1F5B
+:1077D00027B383F8BB8007FBAAE9BB1BD1FCBBD353
+:1077E0007A00DD33B6CEB93D6B019C8325FB8099D1
+:1077F000FB9B83CF07EF3F4A05BE4B7BF8B954A6EE
+:107800009DD4A3BD5EF266ECF351E38F7BA49D3A59
+:10781000202B36AAAF8BFC98913BA3ECE9B32D64E7
+:10782000675BC647D5F7C039D1BD8E9FEC16D9A18D
+:107830003DAFEB8738A74A1187307F7D8AE265FB31
+:10784000FA4E717EE9D1C62527F75DFE9C5E13E7EF
+:10785000B453C4A17E2EE2009DC27F7E23E0A4F239
+:10786000CD809BEADF0A2804EF0A940B61C1CF7731
+:10787000563ECB4717AFAA84FBED47CF73BF7D7F42
+:1078800062A883BEEF74DE42DF17A4BD4D14BFDBD8
+:10789000077C722CCE49BF1F7834DB4CF1B3A3A513
+:1078A000BFFB7B8ABB7C6BD1F1B80BC7B37A4EEBC5
+:1078B000704E186F5D858BEEA536E04714A1FFEE84
+:1078C0003289BEFF341B0E04EF45543A37F569F197
+:1078D000590FFF6595F1DF1DC8427F618C8BE8A4CD
+:1078E00042EF73223E37BA4F915F1E57D8EE1B8787
+:1078F0007180F17A26BEFB143445AC3B0E6F42E03A
+:1079000079538944DF731A0ABFD1E58654AE2FA399
+:10791000EBFF7534D7831BDDDBE83C773BBAB25015
+:10792000AFEF13F910B3642948BF5F2877DDB11CAE
+:10793000F65B91651FBB11C02DA35368FDFB4A4F39
+:10794000531CF8D88557C621FD1DB3765A30CE7921
+:10795000CCC9DF53871395F97BB79DF22D31F2A483
+:10796000D5F258E922FAFD957FFC7CEFDAD17CDF75
+:107970004C52F50A8C5B81FB4D42F9DEB202F9C331
+:1079800098B983FCCCE873AA705FB388DEF364FC1B
+:107990007B4FBFB6862C783F1CED67027D6C42FFA3
+:1079A00078F7043D7DAFAD5EE6E782E788E7A41F88
+:1079B000A3137E99767C66653E63FAC079601DDE0E
+:1079C000D7D03AF13EAAEFADBF9262F8B583D6C9DF
+:1079D000FC9E58F9B0D1CFCD76B2209A86B3151659
+:1079E00076A19F70309FC6996DE5E3CC12717C9BA8
+:1079F000A0FF59177594DF81F4D680CF95CC2779F5
+:107A000072CCF550571DACB71ECEC641FE469356FC
+:107A10000E09395B5F5245F7BDC7DC07C6A3BEBF81
+:107A2000BE74E5E13227C29FD45441B729A52FD5B2
+:107A3000205D5A942E8A2F4C76CB745D787DB936B2
+:107A40004ED1AF17A3F44BB4BEA88F923B11F7549D
+:107A50004E43C4F9CF729F4B88A483ABC7CB1C2F76
+:107A60007EAF7BD6051EA71D8C97F7E973A503781B
+:107A7000893EEFD878893EA7013CADEAAACB1D8CA0
+:107A80005F156FBF2E79C91A99E71B8DB71F8AAF93
+:107A9000E6D15641AF5C9E5708BE7D3B3B4471B773
+:107AA000B74BF9EF4B1D73FF96E2BFB358A8630DB8
+:107AB000CA45E0CB3942F9E823E44C341E06F8F419
+:107AC0003F282EBFFBF3B7282EAACA2113F225EABE
+:107AD00013C11FEAB999901F916F2FF0EF875E2DA8
+:107AE0007FA87C45EB213F38A48FCC1FFCDFC55F0E
+:107AF0007B71CD18177616523CB8CAD1A5C77BAC9E
+:107B0000C950D23D92887FD23A9C91F53C6E1C5967
+:107B10004F712FA1F7D4B8A6DABE3EBB2B41185542
+:107B2000A4474DC2DE51FDC47D8E53647FAAFA5432
+:107B300016F7FE57AB4FF7087D3A54FBDE73BB795F
+:107B4000DCE7CB433D0F801C9F9C6FA4EFB84C0E2D
+:107B50003FCCDFA3708449FE6F7437911F0CFB6923
+:107B600046A304E67544E6F3A9E5BEF36D0AD6EF35
+:107B700095BBF40AF507FF16E0038656FA9D860DBD
+:107B80008F737D1357F451D6E5DE83BAB34F99E670
+:107B90004AC2EF616F5F83DF010B2A8CBEEB98B5A1
+:107BA000B48B45EEF7A531DCAF9D9CFFD61D076871
+:107BB000DD1FEA69DD6857039D4F969D0E05E7CFEF
+:107BC000F6DB23FDEC7DD9F7DA9D00B77C696C0804
+:107BD000D17AC3A37E01F3EC33578D074B8DED7340
+:107BE0001F18F50BC0C74673D504CCA3ACB6DFDBBA
+:107BF0003E1FE5DAD95B2660FC1BECBC56D4B7838C
+:107C0000F6DFB7CD8CBF3B5DED789FD631A2AFAB31
+:107C100006BFBF5AEDE0F748BED1BE87C64C407BD9
+:107C200039ECC1734F349F0C22DD4C16EB65172FD6
+:107C300051FC41BD97D9739ED347FFF8400FB88FD1
+:107C40006BBF5C45F722B97DBAF926A0D5757D3C9E
+:107C50007F0CDBF17BE058BF28861D00F35CE74B0F
+:107C6000C6F3EBCABA3786DECDEDFB36E083E7F626
+:107C70006470BC44B76F1EC3ED82B8AFDECF7292A2
+:107C80003DC0F57FB0C012F33B55B7A9FAD21A3BFD
+:107C90000F452D5579A5DA23805FB32102BF9BC61E
+:107CA00070FFFD7CA9A703F1F77DE77F0A710BE563
+:107CB000F152CFF631C391AE045FAD9763C601EECA
+:107CC0001CF3A3C52B6E4113EFABBE73E96FE986BE
+:107CD000A6DB41746550E9F821A2E3FF8BF47BE257
+:107CE000FBD0EF207974FE14DDC347D3B14ABF0344
+:107CF00074C8E69B9206E87928BAC17E8B9206E8A2
+:107D00007AA87EFBCEBF1F93DE07C6E9BD2CDDAB94
+:107D1000F4B759D0917A0F5429CE79FDD78CECFE67
+:107D2000A33D46F577C6357E11E83FCAA3AEB072D3
+:107D3000B97FB43797FB193D66BA9F9AE95E29BEB1
+:107D4000BB0D5D23C6AD11F27EA6DB755939AFEAD6
+:107D50000B55DFFD4F7C774398008000000000004A
+:107D60001F8B08000000000000FFED7D0B7454C75E
+:107D70009560BDEED73FA9919E3E881692A085C022
+:107D8000164640EBFF053D7D10321FA7C1180B9032
+:107D90004C8BE0041B49DD60E2903D9EA131321224
+:107DA0009FCD621FCC7866BD390D038C9DB177C025
+:107DB000561C610BDCE237384BECC671189C4C3C0E
+:107DC000C243086C6CD318C743B24ABCF7DE7A0FC3
+:107DD000F56B750BDB43EBCC6457E740A95EBDAA9E
+:107DE000BA75EBFE6FD5D37A3363CCCED817F85380
+:107DF0003DBCAC081A19CB65F4F305FCDBE2F2EBF1
+:107E0000252B63DFB9EECBB443F9932CDF0A671E51
+:107E100063AF5F35CAAC88B1AEA9E3F6EAB387FABF
+:107E20008F75088C15437B12748676EF54C17700EA
+:107E30001E31D1272E9D1E7DDE9F4CFDAECD958738
+:107E4000B3FA329D63687AAF3E8DB159F89B0ECA82
+:107E500020932D33A0CCED5AC712A0CC2CF9369626
+:107E60004C622EB1843193F29EE9CA6BDF15F03972
+:107E7000931983FEEB95F556307F5D0DC031CFCC65
+:107E8000BCF189387AD3C9C9D05ECD970AE369D7E6
+:107E90001DDE9FFEA529F3E430362E57A0F5CDFB5D
+:107EA0008CF94CF06B756EEB023603E78771CCD121
+:107EB000C7A9601E99E9011DE55EDB2AE83F6BAAB0
+:107EC000C9E1E5AF4BF8DE6CC6DF1B3ECE7AC64A91
+:107ED00086C6D9E209C8FA54C68E494CE92F5B6FB1
+:107EE000C167E7F8C37A85B23E536ECD55C4CBEB7C
+:107EF00092C7E10778670F868D6F1DCB583A63559F
+:107F00009F699F8B0E6D7D385C30FB58FAE54F5FA3
+:107F1000C07C4633C78F395D47F8795D32FA903EB1
+:107F20002AAED4EE6293184B96EC87FCF0DC2A99CB
+:107F30001D3E053633F6537EAFB8020404ED9FC2F2
+:107F4000BF1480739B6EEF5A27D0DD166C4C1FA2B6
+:107F500097250B4C1A38962E49D4D49B9AC769EAB8
+:107F6000CB574FD4EC6F73DBDD9AFA431B666AEA9A
+:107F7000AE274A35F5559DD59AF156EF9CAB69FF72
+:107F8000D6EE6F68EA6B9E7F50537F74FFCA11E98B
+:107F9000221A5F88B691E98979053BD2BF884D3AAC
+:107FA000FCCFC59CD3A3F7F7217FC27EBD6EAFB7D0
+:107FB000AD82FED5573F8DE7FDB4F4C5BC7200F924
+:107FC000A356D91798C72B407B8D52AD95BE45F46B
+:107FD0005E633645E41B95EEB60A5611C7AF66DA06
+:107FE000FDAAB06DBDAE477E2E1AD0EB61BE5937EB
+:107FF000B5FC572135FC06C767CCAFC7F584CBA5C8
+:10800000FFEE18937A399E60B57F01FCC4ACC98C31
+:108010009547C7A34AA7B75D37635F6FDDCAFCEA20
+:108020007A2B58A00EE93EDABA673BFC7A926B5184
+:10803000D61DBE5E15FEEF6F865F81EF5FFF23F3F7
+:10804000ED1310DBB288FCE6DF5DEBCFB52B400211
+:10805000BC27157AA8918227128B900E980365830E
+:108060007190F9510ED433C16F8452961C04AF380D
+:1080700068EF34302AEB717E711086A6D245EB355D
+:108080000ECA8D286F452CA9EE9CC7EB8E065E8725
+:10809000F7A82ED5F2BAE73E5E8792EA5E27AF4395
+:1080A0003FAAEF5A8CF5CEB8C0894401EBBE2558E3
+:1080B000370E1E5ACA4BFF05814A99E49638E85D8F
+:1080C000A7A77EEC22AF073771FAD0F283315EF6B4
+:1080D000F9B3195F3D3C3F81BF4DC2FD5CD76F00D6
+:1080E0003CD48A82C30EEFD50C32873F15F7D5E416
+:1080F00090D997E033A033316D88CF8C2C98B14A5A
+:10810000203E790FF1ADCAEDE1E368E9AB1EF55A07
+:1081100001EC3BFCBE3119E530A7A7FAB2E0122C06
+:10812000F1F913D03E7B32FC4B1E4E1F2A5CA2326B
+:108130005FA5B55F8FAAB6321826B75917D15985F2
+:10814000799D2CD987CB6D7150E52F2E2FC2E1562A
+:10815000E5AD391FF86C1AFB3A7C96B90A6AB3AEE2
+:10816000BEABF0D9BA303E93ADF79684F019103219
+:10817000D3F0D9B7899E6E275F4E09837526184FB5
+:10818000F60CE823CA9954C04342243E9BFB1BB221
+:108190001FA2C89737F01758676E7E989C51F45C01
+:1081A000B5AAE7FEA8B3A2DDE2677A11CB707CC85E
+:1081B0002C3B31D273B53CBE0906BA6BA80EF890C1
+:1081C0000F81BE631F15DC06CF9BC9CE62B85A80F3
+:1081D000C7AAE2318C6EAD712F9D90ECBC05F5EC19
+:1081E00018856E4E66A711DFC376BDC742E49DB504
+:1081F000E8CBF101CD3709C7736622BFD540DBC696
+:1082000082E1FD33B10FF09935C87C3E78CFEA08A2
+:108210000858AF46FD9E8DF4CFEA51FE575F09E83E
+:1082200025EAA5E5975B7400BF3F01A4578B7C51FD
+:10823000309C2E64E6D3E37E7CD5FDAFB61F349030
+:10824000BC0EDBFF9A41B0CF004E39D5E420FA1ABC
+:108250006464CFC84EC1C748BEAC21BCA8F6E3AD2C
+:10826000F6266817E8912E627BB340F6D0A76CB370
+:1082700081F305F3FA557A86E7CBAF303911ED3447
+:10828000CBF3D47E6C1323FAA8B6973C556747B856
+:108290000676CC44B824BD0A973F15C7BD60E2708E
+:1082A000F9DA087FD50AFEE4411D3343BBBF4F69AD
+:1082B0000FA35FFF20B7D3FC4FC42B70DDC8F04382
+:1082C000BF07D04E069368E5DD03FF4384F7DC6902
+:1082D000773FDF015DAE28F0FC6F856E3FDA2451F9
+:1082E000B93ECDF5FD7CA0C77F916E7CE266C80FDC
+:1082F0003944F7D5F6CF27901E52F1D93786F410BE
+:10830000C24DF8E8B34483DBAA107538BC0ABFE558
+:108310008CC8572A9C2A7C577C7AAB0BC67BB3E768
+:108320005F131CF621F84B45E77E84FBCDC14F67F8
+:10833000B888EF9235766634F96652FC88A44C967C
+:108340002BA6A23E8873CC85758CCB74D1BA4C36E3
+:10835000A31DFD024B2793F360487382CF8CF0F787
+:10836000A737ECD243FBD6A92233C1FB5BB3BC36A3
+:108370005AA7FE0986EB9993E96103D6E8F377657E
+:108380003E29119C835047BFC7C6F1A29F68F4F8ED
+:10839000E0B95FC7D61C0AC1CBC102EE8F9DCDE705
+:1083A000E5DA171ED97629843FDA0FADD3D4DDBDC7
+:1083B000DFDB762954DE6E1044DC9736858EDBD900
+:1083C000C004F45F5A453BE1A143379086F56B2C1E
+:1083D000787E0AAE0FE78F00FF3FE75B623DFFD27A
+:1083E000A950F68FE1FE69FF241FF90DEAFC1F2B4F
+:1083F000EBFF385F177338A6011EBAB3BFC5709F75
+:108400006A6C7C3F4D50727AE67243F577869E73B4
+:108410007951A53E0F3ADE73121DE91CA8764C99DE
+:10842000F611E97D27D2BB71A8BEB548D7E88BF01D
+:10843000FE730522C17BC016B93D5BA1979D135CFD
+:10844000DDD9E8DF3FAB736C8625CECBDC3A1EE589
+:10845000FD56DB7AA253E6E2EB58C038BFCECBF430
+:108460007819E8D179FEB782422AD68DCCC286F837
+:1084700057F50BE7893ED101FDBBF2D79971DD5D60
+:10848000B6F5661CCF84D6826E383CEABA0FECE6AD
+:10849000F3CECBF489E0E9B2B9B97BC501A83FA31B
+:1084A000AC7B5EEE3A6AAF6AF49F14097FE06743E3
+:1084B000DDE868F5E23C2687BD46C23A736CC6B279
+:1084C0004F7889EC1355BF0DE94FAD9D72FABA9103
+:1084D000E463D7159DCF44F2535E3007DE9FAFBCF7
+:1084E0006D0D727BBE6BBFA35FC4F71C02F9E3F393
+:1084F00073BF4D769D35772EB7E7B3567991549873
+:108500004FF0A13F314FC55B9E565F191D17B7A0B5
+:10851000FA30DED4EAD1592CC090BE2AC2FCF370E6
+:108520007D3BBB40B1D7725931DA2B2D26DF63C8B2
+:108530000F960D423AC2A1E27545818EE820867CF5
+:10854000B06726945DD965B4AFFACCD31704985FB1
+:1085500017DF6643BED0DB8C7EC41BB38A1F0DA819
+:10856000F34DC2FF3325B2B7B08E842F7D3979FC2D
+:108570006E96C786EBEC32B0A648F2A7B680F3FD44
+:1085800007597E920FD1DA8D1B04D27BAA7C376605
+:1085900032D937C278DB8C5CCE805FD22B40BF3EB5
+:1085A000A417A0FF175AB3F7E905A27B19E5F1ADAF
+:1085B00052B1EF120BB91FFE668189CA93CA7E546D
+:1085C0007F7136C33582FCAFAAF23084DF94CAC70C
+:1085D0003365F2F14C222F7395713F2EE27CDC5C07
+:1085E000147BB95F9A337AFB1C4B7A8D87522890A3
+:1085F000E879DD9887492EC5126F39A38837A35DC6
+:10860000A13F07A713B5FD7345DEFFAA20E674B2AC
+:10861000B47214E5412CE9A4E2CF83DECF97FF7951
+:10862000EC47DA68AEE3A399F2D442E093BF9C2E04
+:10863000DF83E596D723DBBBF3632F77D31E8072EE
+:10864000F104DF3723E9B37985B197FB4BD1BE48FD
+:10865000E1F645F8FCCB153D144B79D20465B31116
+:10866000D61F01FF8F8EC2FCCB7350EF727B81E56A
+:108670009EB9A40FB1DFE167B22EC43E067B141C85
+:1086800041B443053992DDED8DFD7E2D7D483F647B
+:10869000AFCC615C1FA8F32F2CE1F87A7A14E0B01C
+:1086A00000DEEA256EAF9BC2E050CBBF2D8CBD7DB6
+:1086B0002AE943E04805BB1FCB0542447BAFA7D066
+:1086C00018737E1A0B78D9E2608D91E4C9C9D8EF8E
+:1086D0004B9A0DCAAAE9CED328D7964B87E7605CA0
+:1086E000F9FBF81FE61BD279BE61A5C1E545FFAED7
+:1086F0004BB23BBC768C47ACA2FACA7CBB43AF52B0
+:108700003EB6DF947CDB056CD7517DE5EF241FDAA4
+:10871000C3DF17D69DC9C6F136EB1DFB18C69D9564
+:108720007C838DE71BAC369E9F106D3CEF60B529B6
+:1087300079071BCF3B586D4ADEC1C6F30E569B929C
+:1087400077B0F1BC83D5A6E41D6C3CEF60B5297908
+:10875000071BCF3B586D6ADEC1D33815E391369EB7
+:1087600077B0DA78DEC16AE379079897E71D6C3C49
+:10877000EF0070F1BC832D72DEC13A947720FFF1D7
+:108780001896A467B85F7F54A9CF067BDD34637861
+:108790005EB56AE7FE2D1817AB0972FC5539785E95
+:1087A000D914B4770A307E4566B0DF04FE65451102
+:1087B000C3F0D5B0F9C3F313DDD9E7BD02FAA3B016
+:1087C0009729BC03E529EA187F3F7CFE6171573B7E
+:1087D0008FE7D6657E8BF03BBB2C4878C3E71887C4
+:1087E000AD53F213B556ADFF2A7FE6B2F9715F992A
+:1087F000D49908F890456DBB88F92F8CBB5EF1D7F2
+:1088000061DCB76A501B7715331BD4B83CCF4B845F
+:10881000C139DFE11C5F046B6A017F2A01E6CFC129
+:10882000A415AE53127C5EA4B7DD1B88BEBC3B45CD
+:10883000C71468AA0464609EA512206A86D254C632
+:10884000ACD24CF29B389DFED7D4BDF1D9280F0392
+:108850007A46046C233CA8F9850458BF3483FC2B6A
+:10886000F2EF2A33FDBF473A50EB82CCF338825DFA
+:1088700062CD802FF96E265C3693ABCE906FEB45C0
+:10888000E635C37341E9379B05294E2D3389F276CE
+:10889000B5CC4165D174576911F0A3CEEC75E17A7E
+:1088A000AAEC6609F9853DEE3CDB48F1E47AE93251
+:1088B000E04900F6F862DA48768AC82EABF81C4523
+:1088C000BB481F2F7822C9AD8AD8EB61B2832A0A30
+:1088D00019C9C72D2CB2FC7CAC84CBCF374B5DDFE4
+:1088E000443CD7FB16D58F872E8FBED04A799B6D1F
+:1088F00061F1C25BFD8A626F4724E7903DB901E9EF
+:108900007AF1048F0DE18816C7782AF6F0EC491B3E
+:10891000C1AE7B7614EC5AD443B7EC2AFB9993FA98
+:10892000503BCAB10E4FBAD0EFBA929038AADDC30D
+:108930003C14678D1CAF796914E22099A8BF13FE1F
+:108940000B9D63EA3A02FB87E5FBBC54E1F88E42DB
+:1089500087E34B63CF17D3A0D4273E610B8D1B77E2
+:1089600059040E9741D0C0F5B962FFFDA024F678F6
+:108970002A81727DA9FC2EF261D574F96758AA7C10
+:108980003BDFE1BA40FC292DAA4F02F9BC667F7695
+:1089900001EA8906DB5EE32A80F7D552F9FD223A27
+:1089A0006FF41F5B1E6EB11E8F47BCF7B922CBA3BD
+:1089B000BB1109C5E44FDE28E2FEE467848728FE88
+:1089C000E4AF8B63BE2F7BEA7386FCC970FE1F5B2E
+:1089D000CCE39D6347018E06285746F1EBA68CC277
+:1089E000FC8D5ABF6EBF3E44CE104185E6696CDCFB
+:1089F000AF6311FC3D9735BABF377B14D6B110F386
+:108A000071B591F5DA7DC531F7AF967E03CA0733AC
+:108A10005BFDA9D0C4BC306FDA50BEB2C9D5AF0F70
+:108A20008D733F38E1E037E508707EB338E672F2C7
+:108A30007C9C1EF975BD19E1E96A067E8DB05F2543
+:108A400025DCFF9B3BE111968876633A43F711E4FE
+:108A500009CF3736297E6383A27F762A72D4532CBE
+:108A600052E92CE5F5B951E8FAD7CAFB8D4A9CB614
+:108A70005162F22B91F47FECE9E6FC3828E7C671ED
+:108A800038EF0DF3CFDF53F4C49ED8D3CF9E0CA0A4
+:108A900093B9B591F17530F674B17402CCBFD4F6C8
+:108AA000F41C90F8B02F9B0D945F9C2EBF580CEFD8
+:108AB0006D8BC2579F2B7869863E3AB0FB5BA03422
+:108AC00042F91090815440FAED55EC6F018E30144C
+:108AD0002004DEF1E8E7F43AE41E7CCE5C6DE47F2E
+:108AE00084C81BCA9F569939DF74A783FF88FE0E7E
+:108AF00033D33993AE20CF9F7665F2FC68383C6A59
+:108B0000FEF46F458F19CF71776516C485F2DDEBE2
+:108B10009B98266FDC7585E785C14F8AD3FA49C9D2
+:108B2000E427858F9F90B9745EA87F24C8DC1F025C
+:108B30007F26505C3CE417A9FECF987CF95CF17F5E
+:108B400002FD1DCD9F1147490F8B30073EFFDD749D
+:108B5000F9DF108F23D0D31FA3D0D39FB0DF7F3492
+:108B60007A62CC11B768CCF071BBB21EB7B58E700B
+:108B70003F2021D31991CE54FA027A9B503276E8E5
+:108B80007D21F3B44A6F134B8ABF3EBD5DC0BEF07A
+:108B9000EFACE1AFECD649D1FB9DB57ACC280FFA0A
+:108BA00032D79BF19EC4D4992E07CE6B11996C00DD
+:108BB00038BB5C3E339E7B003B2FBF6484BCC1CD81
+:108BC000222E3F7EADECFFDC099CFF2A960BBE7D7A
+:108BD000C07F4D6C9701F74D7DFF5849ECFD887BB8
+:108BE0007248EE35968C20F75E56F8E273055F2BDF
+:108BF000DAD629E7995844FB6755ECFD8C342B9461
+:108C00007352D745A4E35B7487E78522AC6714E20F
+:108C1000E0E7C7E4E03C4CCD2B6D40FC3E56C4F190
+:108C200017CDFE7D6A14FCB38900D74AF69901FD81
+:108C30006959FFC7AC48E7118E15D9399C069003D6
+:108C400080DF9559BAB731FCD995A4B587D4F767B9
+:108C50002BFEAE6714E467520ECEC3F11A7E0E4CA3
+:108C60002DCFC53E1EB0B488FBB9FF80FC0EFC734F
+:108C7000A8A458E3E7FEA864643FF7B57F8FDC1A29
+:108C800050E8A8CB11D99E7D21F6FB40E7E060DDDE
+:108C9000EF7C15B9116E6FAAE59ED8DB7B69597A16
+:108CA0009C87C3D1C8B4E7246EF1DF28E02D5D8F27
+:108CB000F368E97725E3FA5F85C3581AF3738CE705
+:108CC00067E831FFC3F9797DA92BBE94EC368F1983
+:108CD000F537D80714675FB939251FCD2AD8676BD8
+:108CE000A996BE934A47A6EFE4D23B40DFAA9CFC7C
+:108CF00017614C53A8BC99A8C89B69A5B1DFAF29DF
+:108D000018AF488E2CAF2B631FE7DB73774E747957
+:108D1000AC9E37FB47411B4F6EBD258F634E4769A5
+:108D2000A9FA2179ACEA87703C8D865E480CD10B9C
+:108D30000D51E4CC68C03136041FB59D02E5AF98F3
+:108D40008DF9A6C0AF9DD839E4DEC7965188134F80
+:108D50000F8D7FC860AF47A0E3DDA5B1CF7FA3BC77
+:108D6000E9377CDB36D2F947A3D5C5283F6273319A
+:108D70003BEC9FB1B395F2F6C605AD9487669D02B4
+:108D8000E5FD98F42EF979AB6CDEA7307D365C9E5C
+:108D90006C8D395E8B72D897F637C5287ECDEBF88F
+:108DA0004A3AF937AFA33C1524EE47B30DCC4EF742
+:108DB000A4AF7CB9FB582F2012302F9AC4E83E761E
+:108DC000A7E1C77ACC471B053EFE5CE6E7F94F9763
+:108DD00077FCA3F09EE5A0317F3B547F519A4DFB79
+:108DE000DE69E5CFBBF69BF39F84A59EB6159EC1B9
+:108DF000F3E153A727531CECC5038F6BECEC5ABC73
+:108E0000C7807EDF0B1E867EA229D33571243B9C52
+:108E1000317F92AE8C509AA8947A5EFA059D6DF8D7
+:108E2000FB3BF7F748E867BD78C04C727FEA819E4C
+:108E3000F85521E32796713EB6063DFE1900AF3581
+:108E4000D3733209EF1D2BF9739179CED4C22B6302
+:108E5000A4009D0FDF91576B0EA5BB2EA9D64C79B0
+:108E6000E45C9D638A1DEBFC1C43FCF4DAFD82404C
+:108E70007EDD2E1150EF9AE1BA867AEC0D89EBC3B4
+:108E8000A9536B49AB752AE71E76E42D3980EFC7ED
+:108E90004FAFA7F13B59647BCC58C6E5F08B0699E0
+:108EA000E67DF18048E7C855BCDE697CD6CB300F43
+:108EB000E0A3DEA6A77BD8A78D4E11E5D0E93481CB
+:108EC000ED822DDFE97885EE99EC8802EF2F4AB923
+:108ED0009FCA6CA9447FA7F7772E8F747E5FA5BFCA
+:108EE000C93364A90CEDC0499E2694FFCCB6E43684
+:108EF0007CF124DFBF4387E6CF03FCCF7DC17F2217
+:108F00000EF7216BCF785CF707A5766ABF450F1F78
+:108F1000BD42F4B0C5C8EFE37875718E03B08E859D
+:108F2000D60111CF4F18528394E76D2AE3F2748B68
+:108F3000CA0F63811FE03D7D06BF07C526DAA9CEB3
+:108F400026072784DEA39E55A6AC970532F1F9C209
+:108F5000F87737D81D8C15F6A6378BB0FE8589EFCC
+:108F60006EC8867A49EF785ECF78F7B36C89B1B274
+:108F7000DE0C5E9FF6EE6793A05ED19BC9EB953049
+:108F8000D478B09B7AB39ABD7938BEA419BF150FB7
+:108F900072147FFD526FD2458C5F3528EB871F031B
+:108FA000CEE3ECFB473AEFE2345BFD782E83C986D3
+:108FB000B0F8193485DC7760A90924FFD4FB0BF3E2
+:108FC000457F3FF6D799FD84DFBB5927D97380AD24
+:108FD000DD5F147E797B2E5CEE6DD9C85C784E8C9B
+:108FE000B16609EF33084CD67DC1E3784E9C5F85AE
+:108FF000479D7F185CB0B5C89F43703D4FE3A87094
+:109000005DCB377951DE7A6B59AE27044FD784E0B8
+:109010000F186C45DAAC1D0FE13E5D1B139C204020
+:109020003DB97C1BEDDBB5B1C11F088E90BA81EF55
+:10903000635B6F09ED639728B7219D9B8CD66E21EA
+:1090400091B1EEB884190CE6D931D6E5C57B6E40F6
+:109050007774EFD89B65741C0038EB8BB4F9A1C70B
+:10906000153AFB83220FE6987679CE015DBA7B0430
+:1090700086F770DC83378CA8FF16F65D3462BEA4D9
+:10908000A3E7A211E9BE03EB304EC7F3C688F96F20
+:1090900063B95EBD2F4AE791D64B1C4FA7B2EE7A5B
+:1090A0002A15E0E9582DD0BDBCF54792E6607D7DDC
+:1090B0002BAE92B1E55587E720B9B438FB9FC27259
+:1090C000251B38950A24B4CCA567F6103DB9624D2E
+:1090D0003CB387E8C9164F8AA6BE7217ECCE0C289F
+:1090E000376668FA31E5FEEA3236F483E7989A94F7
+:1090F0007D5C66DB19C0B8EE3297C13B1032DEC230
+:10910000BECD6232C2ED111C748DD2CBCF3FADE02B
+:109110002B84521C7A1FCFF7F40AC4EF1D6D7ABA64
+:10912000C7D3DCCBEDAEE63582CF2E201EF8BD0DC9
+:1091300077AF40EDEEDEA7EB9311EF1B000F00477A
+:10914000DAF8847D2C114793E9DCD54A055677DFA0
+:1091500039038EB3E23B02DD6755BF9BA0C2BFB2AD
+:10916000A991CE91017C5EA44F759D4DF647E95CB7
+:10917000D5CA89970DA887617D970634F8D4D65B48
+:109180003CDAFACA8DDAFAD132E59EF234360DF9BC
+:10919000E9789920E23924B5FE51D6F9B7F15EE7B6
+:1091A0006ED1790AE9B3CDE89F81FA7EB7E8A2BA19
+:1091B000DA0ECF3B18F19DF8E100F1B140FCB9C5E2
+:1091C000204B35F83D977681E87605B6ABF3670F0F
+:1091D000BD4F75FDF0FA4D55EE5A9C1BE8BB30476C
+:1091E0000509ED907A511693F3882F229E77F9BDE9
+:1091F000C2076FA3F603B8EE4222857DBAEBFE44A8
+:109200009F17E6BDEBCD563AE7765721D0811DF981
+:109210005E47E7D6E6E3792F28EF03796881F22EDF
+:10922000FDA12692EF338D12C977E59C972A2FE492
+:1092300017B5E7B6E6679E213BEBBEE776D279B578
+:10924000C93972C1D3A80F2D7CFE1D4704DF6618F3
+:10925000A723EF34C9CF71323F2FD76153E4682F72
+:10926000C85175FDB0BFE350AE612269411ECD9B70
+:109270006E56A95D263928F86B75E8FF8E53E6DD3A
+:109280005F6DA775A73D7A48C0756731EF6601E647
+:10929000BB823A7CEC50F955EDD7B5F80BE85D563A
+:1092A000AFB5635B45D7E365305FBB6DC0C8CF2DFD
+:1092B000068DA81FEEE0F8DE48E3C3F27574EE50A9
+:1092C000E2FB30473F988076CEFAA339E3D808F620
+:1092D0008DDEACD3C8118314A79137F373B5F26751
+:1092E000A1432B77BE5196A3695F244FD3B4DFDF30
+:1092F00058A8A93FE0ACD4BCFF60539DA66EB2CD88
+:10930000D3BC6FB12FD6D4E373976BDE1FE358A5A0
+:109310006937BDF5A32601ED71B377C00578E8067E
+:10932000DE284B1ED223D312E06528E30A2D562CEB
+:10933000BBF34D744EB67B3CE89744ECFF1D3A7787
+:10934000694E7CC95C03E5DF0BBE5AFC7E0EA0C9EA
+:1093500085F6DB3D4F68E3F0C7AB385FA96543B9DD
+:10936000EBC10A28F35EB067F07BE9817B707FCCAC
+:10937000718CDB45AF99C92E9A89765388BF71B03D
+:10938000BA667E39F67B42BE17F982F532690ABCAD
+:10939000B7CF083B8B7AEE3523F5CBEB1DD085E6B6
+:1093A000F77F59CEE5C1B3CEDA7B71FC8E3ED0B2E9
+:1093B000C84FCF7D6844BFAEA3AF3F01F5D90CE7DE
+:1093C0008746B4CF879E2B7A4E0CC6619CE31F0E56
+:1093D000E923DE63DD5E6EA4F14F2B72BDE53B7ABF
+:1093E0003A4F8BF7376B4A86E473CBE1A01FEF63EC
+:1093F000B7B4F37B9B788E36929C06F9FC61A8BCCF
+:109400007D361DF4C14C1A4FA30F9697F9E9DE3E45
+:10941000C86FCDFB2B97345CC57C25C871EDF34C30
+:109420007E1E96B10103FA7320D735ED1BCB95FB59
+:109430009CD358DE1720072E3823DFDB7DBB8A9FA5
+:1094400033B8E0AAA37D7816F089E7479F1D863FD1
+:109450008ED7DBE1ED65A48190FD1B66FF5771FFA0
+:10946000EAE52872FBA2B2BFFB8440010A55B7337C
+:109470008EE87785B975EDA542DC97CFB7A2BFDE40
+:10948000F22381EEC1FFB2FFAD343BACDF78F8547C
+:109490001ADE97761F3A9586F789DB0CF6CD68CFF2
+:1094A000037DD03DE48E5E3FC1DF7EA8B01F9FB735
+:1094B000F70A0E14C9EE9EEB0DB44E36B015FDA39F
+:1094C0007D51E03A58CEEDABC3E5762ADD2E9813F8
+:1094D000F57E8FC9E713901E403E215C47C00F8286
+:1094E000FABE6DE6A648F6D46505DF27B71919DE82
+:1094F000FB6D83FEB88ED359A78DF8BD8596C3B09A
+:109500002E01D771EE81781C7F8381A19DA1C2F7C6
+:109510007156E0035CFFFBAB0D0CCF2D6F59AD27EF
+:109520007CBFBF81DB27FA877FBD3503EACB802E66
+:10953000F13B0F2756DF389D01E3BEBF86DB69751F
+:109540000F1B882F97AD136EDD4B0EA56B956EFF2D
+:1095500046A1D370FA0DA7DB61F4BAE6EBD1EBDBE1
+:10956000E5B7EC9019A8F761FFE78C433AFA1E7350
+:109570001C407E1A3C611807704FDA2A39C0C36359
+:10958000D3F5BEA7D2506E9CE0EDF96D7B052E7F22
+:10959000ECCB717D19DD4686F7082E2AFB7651D972
+:1095A000373B0B0AF1C8CF626012CAA96C25CEF90D
+:1095B0008A81351D46FF52E4F267FA8F6D7BB787CB
+:1095C000D0EF7F2BE774ABCAC56946E63A6CC5F7A6
+:1095D0000F8D5F04E3BC6CE0E7352728E34DC90934
+:1095E000362C825257C1E5E46F1538D4FA9F143EE9
+:1095F00060277F43F85C68E6F89FB7D1DF8CEBF813
+:1096000099C975BD1CDE5F30E17C1BEABDEE493FA8
+:10961000C9E3DFB973901DEE56F07FA2FC37CF632C
+:10962000EECF32358EF6D772F46909E9D932A568E2
+:10963000DC48F130F7CD6CE64A01BABA9943A55A35
+:109640005F74FCAA7180FC82EB0DC42F37D3E9B99B
+:10965000DAEF5305EEE9468E07D6974A7A1BE4B651
+:109660005816926750F1A0FAE39629FB69BF1E5B7A
+:10967000C728EECFD8D3848F156DE7845618E741FD
+:10968000836CB002BECF2736ADBD3485B19F6C620E
+:10969000CC050B3ABBC9CC5C77037D6C92A81ED875
+:1096A00064A3FABB9BEC545EB638C7A2FE79E0A473
+:1096B000670AE2ED44D61E672DCC73EDAC81F04114
+:1096C0003B06F4FD98426B37FAF4CC0CED377A94F4
+:1096D000EFAD28F03F743383B940BEFC02E7838EC0
+:1096E000ED1B7F4672CFB1E67A03FA49F96D17B7E1
+:1096F00062DDBDF1770D685F7C00FA04E90CEC7E59
+:109700006613509E9C33DA810E9A6FA6D0382FEBE9
+:10971000820DC877DE630243FAFCA0F7BA711CD74A
+:1097200057742DE1F94D74E69F2DAD4822FCB8FB2E
+:10973000F2757C7F8B74A1F729FAEFF94302EE876B
+:1097400079A3FD9D4AEC7F46CF90AFB7D70613A40F
+:109750000872F8028C8B97A3701D5886B73719BD15
+:1097600053F03C419342C7E1ED8B15FA044C1B9436
+:10977000EF2932218D9F23C19F1658526232F94141
+:10978000FE38E0E796BEBAAB22961E817DA8F5CFE3
+:10979000D88721767C343AFCB2257E43E6C3294340
+:1097A00075F42343EF7FA01F19E9FB82A6ACC9E340
+:1097B000468A77B907C0BE83FDEA00C3C99E82F41A
+:1097C0003E8DCA4F8E74D9917FCC71C13DA82FD8E0
+:1097D0005D3AF23BDABD5A7BA841E18706C51E7AA5
+:1097E000B442EB3F819FD45EC1FDA484E34CE33FD0
+:1097F000853F27FFC98C7C05F34E83FD7925D2FE7A
+:1098000054D5AEC77E13D82EA27306748EF415BE3F
+:10981000CEBFA8E07A54E5EB65C8D748BFBD9CAF82
+:10982000C3C76DA9AAF90B1C775B947B10F757F19E
+:10983000F1DA9F13085FEEE752084F1FB3E79CB5BC
+:1098400040971F031CFB802EAF399DF149D0FF9A32
+:10985000CB199F6C1D92031DCFC553BF6D9317A7E6
+:10986000B442FD19A47B18EF93DE3A8A6F3EF41CD4
+:10987000E73F75BE0FFCCB52909F8A0D41A303DAE0
+:1098800033FB2E26A01D587CE4FE14E4C368706EE2
+:10989000AD54E0DCF8D8DA4B299C1EF01CEE5A459A
+:1098A000BFB99FF41B11FF6B3732A2DFFED77ED901
+:1098B000817CFC495FBC84FAF0E3A3F15E94FFD79E
+:1098C0008E997C3A81FC106F22C8B58F0D03F791F9
+:1098D000BD79442FA1FFE83EF6DB3DC88FEED74CA3
+:1098E00068F9B1B57D5DD751EFB5F5DD7B55C4F2B3
+:1098F000A5D1E587F68D8FD37AD5FA6F3799ED2804
+:10990000473F11B99C58DBFB2AD9BF6B076FCCC00E
+:1099100038EAC747FF4F09CA35F79B374A509EB907
+:10992000DFB85182EDEE1FC77B22D92D71B3F484CD
+:1099300057555F66BF276AE2451B14FAC8EEDCD5AF
+:109940003809F0577C6E8903F3B66A7BF1149D13D6
+:10995000DF2FFE797DCAC321FD3A0322E58D8ACE31
+:10996000D5C7AF0EA1CB47AA0C9AEF947DD5380F7F
+:10997000B6E2F72D6FC575023AFA0EECB680C8BF95
+:109980002FBB46F0A1BF01F64B783FB2A7AE3D9288
+:1099900042F71099E89C3FBD08EB531CDBED2856BD
+:1099A000CCA72687D84BCB023ABF09E8A8A9CFE4B9
+:1099B000277B3F205EA4BA62473D74FD3763B285C2
+:1099C00008719ADC77E7A01C0F8FD7C0CF18845B93
+:1099D000B5AFCEA7F3F851A647D22D04B89A3B995C
+:1099E00084781D16D7699A4BF1A2F0F88E3DB0DB52
+:1099F0008CFDEC937512C2ABDAA5B88F3D11E4C0B3
+:109A00005F567279A6F2576780E7F53A03B5E6C963
+:109A1000507E5769EF9174CC0B78E9ECBBFF00C620
+:109A2000173A071F8C9F0EF374BEB798619EE79A92
+:109A3000546B9E82FD06E79A1FC81BA29BF0F91A81
+:109A40002AB95D34642F44D67FA50A5F8F961E2CF9
+:109A5000ACFCF3D083E09F575472FF7C058F9F705E
+:109A6000FF3C5C7FA872591D77AD82EFE172F92A45
+:109A7000D939E047935C5E5B69A7F732FB16A59086
+:109A80007FFDDE9214BB75F8F839A243979C377CB2
+:109A90007CD59E737BE55366F47B643DF1A77B899F
+:109AA000E0C3FC976AFFB99D02D9E5EE66830FDF3C
+:109AB00053E10A2CE1F1D8076483CF220CD989AA9B
+:109AC0001D79ABDD2150BB6A57AAF663C0C9E3BB61
+:109AD0004B8A78FB658B6B55E5585CA7859E17977D
+:109AE000F3E78C394FA15FF5E05281911C50EC4AAD
+:109AF000954EC3EDCE4FFB7212478A433DAFD0A7C0
+:109B0000CA6713C2F843D563CF54707EEB403D5E05
+:109B1000887AFCF71AFB3C7C5CD0E38F57523F46B7
+:109B2000FD8B7E2E3A23F9EB6665FCADEAFE054E11
+:109B3000D620BC592CB019FDCC68FAF57B8A9D1350
+:109B4000ADFD19C57EBC1D3F1F56E4C868F1F3CBBF
+:109B500095B7F270FFA9F9F9967D688C62BF57D569
+:109B6000BC86FB1FA7F7046A90FFFE9781E2EEE137
+:109B7000EF3DA5FA9F22D3ECCFA92CA30EFD23F72E
+:109B80001A1E3FE84EB2BF437ECC5B7A86E3AC053B
+:109B90007F10EDB8476F2651D986F632942B5E3888
+:109BA00047F988156BB4F077634C17FBAFCBA6F37E
+:109BB000032DAC9EE24C2D7D49D216500ADD630F79
+:109BC0009D46BEF21ED0DB0F84BEFF88FABE99C749
+:109BD000E136A6FB28F71A660FB478C2ED7EAD7D9C
+:109BE00050A9C48DA2D9096FF45BB85C39A3273E94
+:109BF000EFC078D34CC68C7D5C2EB837F23849471D
+:109C0000DFE604FC086ABBD27E450C501C8AF26B6E
+:109C1000F0EAD5BEA7D3E83E97ACCD27B5EFFF3924
+:109C2000C9CBF0BC52720F974BEE36BD92472AA1BA
+:109C3000EF97B7833F390EED4BBBFD1B8877808BC9
+:109C4000F948DEC89AB8CB3E25AFF4E9997F253FA5
+:109C500074C5912879A4EE793C8FA47C2777781E6F
+:109C6000E9F4A90CFBEDF3481DBDE7E81ECBEDF2CE
+:109C700049A6AA5B711C8A3B4E14797C77629F20AF
+:109C800061BC6A621F5F77E9B638B2AF1B7EB53A36
+:109C900005E581BA4F9F2CE2F8FDE4FDCF6AB05F85
+:109CA000C9AF44C902EB7AE3FD0D3FCBE075BBD9E8
+:109CB0008EFD36C4A33FF3C9AFD6C7237EDF801223
+:109CC000F7E7C717C4C8F1C9A178756615C59D9592
+:109CD00078B508FA70CC505C27BCDF8B555C6E748D
+:109CE00083BB4271CD233CEFDF9DEE9A47F5BF9ECB
+:109CF000C4F8DF2990291EFD2AD035C68DA6C16281
+:109D0000312FFD3FE35827E691BAC7BA7E427CF473
+:109D1000D73A3BF211F4A7FC93F7B09DF423866A7F
+:109D200031CF33033F5B40F7315229DF738FB28F5E
+:109D3000E9E0CFA25F09D02CC13CF43425DF332306
+:109D40008E8938FE0E836BFB54CC2FF58B8ECDC4E1
+:109D5000048E143C6F199E7712649E2F57F34F6A3E
+:109D6000DE3C5AFE49C07994EF56F0F396B280F982
+:109D70007435CFC4963A29F9B5A5CC43F7427C8017
+:109D8000B3AF73DE6B84FCCFC31511F23FEB2B989E
+:109D9000629F69F38DDB735F213AFDAA79C6C378B0
+:109DA000AEE28EE6C5ECDC0F0D83BB28E9D334F2BE
+:109DB000BBFEF86F09A467FB6E903EBC1634B10081
+:109DC000C51F0778DCBDCF4071866BE0BF8D0DD11C
+:109DD000B3EF54F0718FF7D511FDF704EAE3F1FD0D
+:109DE000DF2BCFB7BDB7E47EB4F7BD01FE1D0BC6B8
+:109DF000B83FD613108BD16EB983FBF2646584F53E
+:109E000099E3B87E0AE7A35285FF4AAB389EEBDEA2
+:109E1000E77E987B03CFAF488A5C707B785EFD74E9
+:109E2000569AA0C6D3C745CABF1C0992DE687944BA
+:109E3000A0EFC97CD9FCCB33E991F3F12B7A2F4603
+:109E4000CEBF343690FC8C16CF0E8F63FF9D2AFF59
+:109E5000A6F338767A9544EB4EF6E4D78C6343EB61
+:109E6000BF83FBB07456847DB883E36F9C1DDBF128
+:109E7000EBCA633BFE13311E7F7B8CC7FF61796C9D
+:109E8000F3EBBA8AD8C2FFDB18C3DF1F09FEFF5706
+:109E9000CF0784E7FFC3CF0B849F0330BDF5B01716
+:109EA000DBBA849D413FC3EF8DBFD624801C149341
+:109EB000F6D37DCE05E53C1FB6ADDEECDB2B0C9D6D
+:109EC0001B50F1F56835F723A5BCEB5EFC5ED404AE
+:109ED00039509F82F1B272FE7743AE59785E8C8919
+:109EE000523AE6C9E0CDF4C56097745B22E7595356
+:109EF00095F1A2E99183D5358B6715E31F3D8A7CE7
+:109F00000EFF874A1C52EAE5F7E999684F5F4CF368
+:109F1000DAD3D11E4A3CC99F27F899BC97E0B267B3
+:109F20002FE67FDC201BE17B46C9FF26CFBB2B1B26
+:109F3000E3D2C96017625EF069CC0F923F2BD17BF0
+:109F4000EA7C9766713FEA190313309FEB9DCACFF5
+:109F500039B19EDF91FDA6E6F5CE1AFC975A05CAE7
+:109F6000EBB523FC3FD5F9F3F6652B440CF8CDEBAC
+:109F70009128DFF876F9DFE5BA681E9EE77B4CE2B0
+:109F8000AF9C40BF19E078EC6821D1EF8AE3E5FF90
+:109F9000D48CFEC76491F03CCCAF54E205179478A2
+:109FA000871A2F50F35BFFACC4493EC0F80B9403F3
+:109FB000180F8172FB2CDD9DD64FDB6745E0FF67F4
+:109FC000041E1FF2FE94C7870A8D8E9CD0F3947FE7
+:109FD000358BEF63AB9FE72FD478CF0F95F5147EC9
+:109FE0004FEFC7EFA1156E9D6E443D5FB8352B0E48
+:109FF000CB19B24F9706F85EB6FAB04EDDBF487483
+:10A00000B45759E7B63341CAEFBD1A96F7BF348B40
+:10A010009F6768A9E6FB7B09FFA018D41F9B226EEF
+:10A0200041F331B14AD247CA2BB5805F8C70B67606
+:10A0300073B8557CB7F8ED7538CFC553C1AD581618
+:10A04000ACC9AEA3B87BDBF5AD68BFB9076F9CAEFA
+:10A05000A67899D18EFEC44303DAB8DB13D53CFE53
+:10A06000FE2A1AE088B77B45F28F0BEF15897E92A6
+:10A070005B2CE4BF261B98DE8AF545DC2E2A684C53
+:10A08000ADC33A5B9244F660C1197BD2C379437188
+:10A09000B0E47B378C453CDD2ECFAAC6D32E5BE4E3
+:10A0A000E3B89F5F35CFDA7EF63D3A6FAAAE4BC577
+:10A0B0008B9A2F8D966755CF3DB81B3FD39CD3709D
+:10A0C0008BC1068C3F161EBD6854CE5F4AB6ECA10C
+:10A0D0003C6CE191EB947F55F3AD6ECF75B2ABA1C3
+:10A0E0009F11FBF76CE2F9D7D7000E2C7B61DDB234
+:10A0F00009EFA1DBA8EC8375E3F3639B72A9F46F0E
+:10A100007250797C531995F899C9F464CCDB5EA739
+:10A11000BCEDD559C3CE4D525E6FB7E8FC08F115C2
+:10A1200092F7A37A78DE4F1FC7E335EE3306FABE07
+:10A13000A1FBAC99E4774D5FEB44F40F3E3FE79A07
+:10A1400088707760DE2D842E3E911D9624F4839DC9
+:10A150000E0BE6DB0AFBAF1AF13C4C871830623C71
+:10A160000C20CFC0238BEE9EEBFCDC6F5F8D05F1E6
+:10A170007BDBFC58EFFFCF8F7D95FC5877353F2771
+:10A18000ADCA9102A74EDE8BE519D9F270889CD832
+:10A19000E6E4F9946D9327111FEE764E4A5A1D326C
+:10A1A0005E67238F5F24DF3BD912FAFC97D53C1FF3
+:10A1B000962C306724795633FBEBDDC71B416ED7F5
+:10A1C00044B2FB3FF929D0E54CA08B23DF9E3890A9
+:10A1D000C7193F341EB7AD71F5C431289F2E98D8EA
+:10A1E000141EAFD3C4E358585E2E5A5C6E45A34E7E
+:10A1F000B6D079A1E004D4DBE1F13326062770BDA7
+:10A200002E67E0BD1498318395B161F9B95F30DFF5
+:10A21000CF27C3FBCB1A75A42FD43C5D41A3C8360E
+:10A22000017D166C34F8283FD7285EA476C56FEC04
+:10A23000940A3290CE3F386B9430AE161E1F7334A2
+:10A24000EEEF9E04FD1D6D02DD0BBA5D1E4F3D0756
+:10A25000DED2DB3F07E36DF96C57773DF4CF9FAC5F
+:10A2600093F0FCF4F07C1E3FFF5DA0D839E171361D
+:10A27000A433B44BC2E3F01B153AD8389BEBADD7EF
+:10A28000147F531D47ED174E3F3F9DCDF56DB4B87C
+:10A29000FE5165BCCEC6826D93717F17E818EA93B4
+:10A2A000CEC65AF3E490F176CCE6E7DB9EC1FC60C3
+:10A2B0006A687E90E701C3F382AA9C2BECFF7D03C2
+:10A2C000E27B37C86BD4636E1BCF1F141EAB398380
+:10A2D0007263084EAEB777C39E07C8BE732431BE03
+:10A2E0002EFA7B45DEA302C5E70A167C763C1EEA01
+:10A2F000CC9944F7B0DC67276FB1A23C5A2016E333
+:10A30000BD1EB753B89567C27CD2FDEFACA1EFBCC0
+:10A31000163E907F0EF7E58166039D0F54F5DEFD36
+:10A32000EF3435F0F6BD4FC6617BAEE0B0D8F179C1
+:10A33000237D3F76FE4B7EFABB580B113A90E781A6
+:10A34000B39744E49BCB16D7DF231F152E52F24C54
+:10A35000CD5C4F3FD0B7C8C0C8CED3EACD13599F0C
+:10A36000533CE8465F21E58F52F0FC43DE90BE2966
+:10A370003C0A7A6CCC9DD3633F9D2D113E67821EB3
+:10A3800043789217F13C7DF8FEEF50F63F9A5E8AD3
+:10A39000268751FFF0FB63DE0CC1365C8FDB31EEAC
+:10A3A000538AF63A94E3A2D3DF1F6671BA4E8A62EB
+:10A3B000CFFD49A1DFA8E7A77A4727CFF487D97F48
+:10A3C0001E7963D5FF52F34DAABFF6A0620FAB65AD
+:10A3D0009352FEBBEF37A0728D78BF2139F2FD8614
+:10A3E000870E0968A7A8F71B4E1959CDE1543C4FB9
+:10A3F000ABDC77F22D223BE9D4DFFC62EB8BA97852
+:10A40000DF4990501DB51F3A477ABE1DEC23B2A715
+:10A41000FA7ECBE3AD87F8F9F0F6DEC8DFDDDBAD21
+:10A42000D8DFF53223B9D1AE9CB76DE851F244B70D
+:10A43000E2968F8BA1714BB73D30563DC7EB237F22
+:10A440004F1BC78C16B7EC60413AB7DBB14670A022
+:10A450007EB8DD39DC5DCA79DDA8714C79E473B969
+:10A46000E1714CB95A9BC7B96F96C4F7DB250868F0
+:10A47000EF9A75CE363AB77F4C90229DF35E5ACD57
+:10A48000E5F47C250F72D0C8E9E3608540F76FF0F2
+:10A490001E1EEEFBC163FC1ECEC1027E0F47CD7BAC
+:10A4A000A8F76BA60EE53DE8FE9D7A2F47BD67C372
+:10A4B000988FE05AF45C1C7DC76B87E1908DDBBD03
+:10A4C0005E7E3F1A6510E6434DCC13895F6BAB6B24
+:10A4D000C46A7AEF8EDB4F8F5447F07B7D8A1FE989
+:10A4E000AE8EEA2FACAFD6FA0B540FF717EE54DE50
+:10A4F000E38BD9EC4EFBFB87631C8F9E323BB6F19E
+:10A50000C4EC48FBB6C5A2FD1EAF5A5E56E4DFB0F0
+:10A51000EFC50DBB2FC9F57AB760FFA74ACAA71BC5
+:10A52000289FAECAD5EE317CFC1F29E3A9654029DE
+:10A53000BBA37CD7F9974ABCAC4B947B10EE692F38
+:10A5400068E397D30F69E397337B9335F57CFF7806
+:10A55000CDFB85672669DA8B03F768DA4B2F146821
+:10A56000EAE503159AF72BAFD46AEAB382DAF86505
+:10A57000F5CDC561F7387DB4BE1AA0DCD07E75E696
+:10A580006F6ADECB58A35D579647BBAE891BB5EB10
+:10A5900052C7CDF66AD797D3AD5D5F32E6E3F2BE20
+:10A5A0007E3E2E7FB65DC9C7E558B0DF338D932D53
+:10A5B00068B7A9F7A9D5F7FE2F376658DF407F00A7
+:10A5C00000000000000000001F8B080000000000D9
+:10A5D00000FFB3E46660F8510FC17BB918186E72C2
+:10A5E00021F84301CF6786D06A2C0C0C1A40CCC6E8
+:10A5F000C4C0C0CE44BC7E714E047B1D0703C34C57
+:10A6000020DEC831F0FE1A487C9D877E76A9F34291
+:10A610006859C181F73708570A3130B40A3330C45A
+:10A620008840F80CA2A8F2554208B6A924657639EC
+:10A6300002F5030024CC7134800300000000000008
+:10A6400000000000000000001F8B08000000000058
+:10A6500000FFE57D0B7854D5B5F03E731E3393793A
+:10A6600064F2200F02F18400A242180284870827B6
+:10A6700021C4A8018380BC54263C43483211A8BFA2
+:10A680006DBD77260411ADB551691BBCE81D1014D2
+:10A690001575A0D1061CE84014B1DADBA8F8A8D5DE
+:10A6A0007650444048C2CB8B2DD57FAFB5CF49E61D
+:10A6B0009C4C48D4F6BFFFFFFDF1F3DBECB3CFD9E0
+:10A6C0007BEDF5DA6BADBDF61EC1329A244E22E465
+:10A6D0005BF8A365842784F4E92CDB0ADA8F9164A4
+:10A6E00042FC2F8BF2368E10EE778EF0A45184BC94
+:10A6F000B5990B98693DBCCF4608AD9FDE343D60EF
+:10A70000CE2264FF08B302EF9FDE9A8FF5C92FBDFA
+:10A71000E714687BD54BBC0075D3BE13CE889D1063
+:10A72000AFB9E5A16BE9F3F69778B2850E45FC93D6
+:10A730004D2485906316C2FE2EB2FA522BAB566D95
+:10A74000DE7F07F45BDE642656DA4FD5EE65D3AEC6
+:10A75000A5F565874402AF546DAB95FAD2FAF200C5
+:10A760001784FA9A7D7FC671DA0A48797028212702
+:10A770007D16225F49EBCE969459F47945606711B6
+:10A78000BC5FB183739BE8FB159BF67F0CFD5734D0
+:10A790008A0379DAFF8AED36220F61637F4B601EF0
+:10A7A0004BA601BC556F88C44CEBE5975649047025
+:10A7B00024D44BA50E18FF614976C03887701C0D54
+:10A7C0009F55CFD071E877D52F706E985AB589789C
+:10A7D000009ED6DDD6394FDA615EB5D260F87EF7DD
+:10A7E0007D12BCB72C50F6B25506F8364B4500E743
+:10A7F000A6CDD2D2A19DFDADD8FEA60EAE630DD9D9
+:10A80000A99EA8766379D247886CEEAC5710A20453
+:10A81000ED0077409A3EACF3F9792E8190D1D03F8C
+:10A820004F644B67FF9430C807FEF7E83F810FF68F
+:10A830003A02DBB23AE9B5D245FF2D77D2EBAC4B09
+:10A84000A59FD09E17DDBF563E0474A0F0D4FB5CDC
+:10A85000583EE24BC372834F46BCFDCA3704CB0659
+:10A860009F1B9F3FE61B8BE5269F82E513BE622C54
+:10A8700003BE527C6F8B6F0E965B7D1E7CFE94AF89
+:10A880001CCBEDBE1A7CFEACEF6E2C77F8FCF8FC0E
+:10A8900005DF7A2C83BE7A2C77F91AB06CF405F0B8
+:10A8A000BD977DDBB16CF205F1F91E5F1396215F58
+:10A8B00018CB7D405F5A867D2D581EF07D88E5AB14
+:10A8C000BE087E77D0771CCB0755BC3B27907C8198
+:10A8D000E2CDA9101715179258A2E48BB49E58CA5E
+:10A8E000EA29B7F9F3255A4FF1D03AC563DFCA70A8
+:10A8F000BE99D6FBD6B0F6CC7B488185D633FDAC6D
+:10A900007DC0834A8195D607D4B3F6C19BFC0571FF
+:10A91000B43E38C0DAAFDE112EB0D1FAD541D69EA2
+:10A92000132293EDB49E1366F5DCB794C90E5ACF8B
+:10A930006D61F5BC8FFD939DB49E1761DF8F3F1550
+:10A940009E1C4FEBE3DB59FBC44BA4D045EB130932
+:10A9500087F5027B7E6102AD17B858BDA85F9920CC
+:10A96000C7E0BF7D626411A1BCB0DD7FB322A4D378
+:10A97000BA145945DC149FFE39580F8B6431B4BFAB
+:10A98000E52F538471B42E91D5D0FE177F05B61FE5
+:10A9900010656C6FF7AFC2F603928CEDA6DA7BB050
+:10A9A000FEAAA8607B72EDBDF8FEAB9282ED836BD0
+:10A9B0001FC2FA41D183ED636B7F8DEF1F943CD8AA
+:10A9C000FEC8DA805248EBFFC179B6005FD7719EAE
+:10A9D00072920DFC1A4C2BA5FCBA8E2373403E1EBE
+:10A9E00000A6A6F2B02E5D5240BFEDFB47DE933CC1
+:10A9F000A7F27632D4973EF54016F6F31CF623D232
+:10AA00007EF89EFB99F8CD585D3F13BF29D7FA69B0
+:10AA100084F7EAACBDEB67DF37E3F5F07C53A1F5D3
+:10AA2000B317FB71F46E5E13BF9DA087E7DB4AADE1
+:10AA30009F83D84F42EFE0098B6374FD84C5655A4C
+:10AA40003F7FC47EFAF40E1E451AA7EB4791966B22
+:10AA5000FD7C88FDA4F7AE9FB074AD1E1E6985D63F
+:10AA6000CF11ECA77FEFE6A598AFD3C363AED2FAC0
+:10AA7000398974CFEA5D3F071C7AFC1C7074E0E7EB
+:10AA80001CC233A877F32A70EAF153E0ECC0CF255B
+:10AA9000ECE7AADEF573C0A9C7CF0167077E440EB5
+:10AAA000E635AC77F32A88D7E3A720BE033F4E0EE6
+:10AAB000E019D13B785EEDA3C7CFAB7D3AF0938A26
+:10AAC000F08CEE1D3C85297AFC14A674E04746788C
+:10AAD000C6F5AE9F5753F4F87935A5033F57613F4C
+:10AAE000D7F56E5E85A97AFC14A676E02717FBC918
+:10AAF000F76C477808EDC7D17D3F07FBEBF173B0EA
+:10AB00007F077EAEC57EA6D07EB27BEEA728538F90
+:10AB10009FA2CC0EFC14229E6FE85D3F0733F5F830
+:10AB20003998D9819FA9D8CFD4DECDABE80A3D7E34
+:10AB30008AAE60F899248CC07586AE9D6E9E7E723A
+:10AB40007DBF7C85A3EFF32E56E75D6E02760FAFD7
+:10AB5000D933A445E1E9FBF61D09B90F9068BBA6FE
+:10AB6000E076C08F835A79D1764DFCD8389D1D95FB
+:10AB7000A024EAEA49C57D75EFF7291DA06B4F9D1A
+:10AB800073B5AE3DDD93ABAB67948FD7BDDFBFA68A
+:10AB90004057BFE2EE1B75EF67F96FD1D5B3D7CF42
+:10ABA000D3BD3FA87EA1AEFDCA860A5DFB55819547
+:10ABB000BAFA35DB7FA27B7F58708DAE7D78D303E8
+:10ABC000BAF611E14774F591871ED3BD3FBA658B84
+:10ABD000AE7DCC87CFEADAC74576E9EAD71EDFA398
+:10ABE0007BFFBAF603BAFAA48BBFD7BD9F4FDED561
+:10ABF000DBDB963FEBDE9FE2FA4CD77E7DDA9706F1
+:10AC00003BD5EE3A768D5AE741AE08FA25FE740937
+:10AC1000EDD5B043C2BAD4D7CEFC14C752F928E55B
+:10AC20001FE9C0223919F992FE51BB21BF6FF99576
+:10AC300011FAFCAEF19E2B5DF4F95D9267B82B869C
+:10AC40007D43F98D236950CA26288DEDF7898CDF65
+:10AC50000B322E0D3E42BFF79ADA0727D0FA703E2C
+:10AC60003F08F2F1326742BB3A8E2735F05E9C997D
+:10AC7000A0DF745F56DE93FE287958DF9FDA195CF7
+:10AC800067BFEB454F1ADA51B59FF8C1CE59D79F30
+:10AC9000CEAB2F21AF709F84FD03E9F7FD97A67916
+:10ACA000687F6689FA19D1E34B74FCA1387E18E4F9
+:10ACB000E1208C3FBAEBF8E6016375E35B32CB75BC
+:10ACC000E35B243ABE8B90DFD77EAE8E4F89309EF9
+:10ACD0009037B9CF717C7366398E7F9F44FDAEE8A3
+:10ACE000F1E33AC66F81F9BFDFDDFC078CD7CF3FB8
+:10ACF000B3423F7F89CDFFA3DAD3EAF87138FF3F33
+:10AD000073A7D9FC332BD8FCCDACDF8EF19D1DF899
+:10AD10008FC0F8C7BA19DF9C3D413FFF2B2AF5F3DE
+:10AD200037B3F14FD65E50C7B7E3F85F7217D8FC60
+:10AD3000AFA8C4F125B3C70DFC2365C4D504E8F85A
+:10AD4000A41F557CA9C02E741C28872452A12164FD
+:10AD50001B3700E1B82B8EF1DB577194DF509FF960
+:10AD6000F1390950CD9947FD4695D757ECC8974022
+:10AD7000EF613BF5B796A8A02E6EE291BFC90673AE
+:10AD8000601085B7B589F7437DF186EB02A05FBD02
+:10AD900066B2A014BE1348189E7FFECB615BA2E78B
+:10ADA000652C97D48BC72251F2D6E1071690213536
+:10ADB00014BE29C004A33BEB9F523F0E1CE38FA996
+:10ADC000DF43A8FFF399C8C6FB0BF5F7A01EA1FE51
+:10ADD0001E3ACEA416BFA3DD1D4EA3F097AAF07FA6
+:10ADE0002A3079FDF4362EE0A7F2F9D58F47A07FFF
+:10ADF000BDE06E1B457A271C65FE245D9DCECB0F02
+:10AE0000746ADF6D0E6CE110BF32E06B3A8A262166
+:10AE10008BD667505C77BEFFC1BEA907392721B723
+:10AE200012454CA5EFDFBE9AEBEFA2E3CE52CCB9B0
+:10AE30006C1D52324C28D724C33496905B1A478835
+:10AE4000B407325D113F8D448D3BA3585F9F55AAD7
+:10AE5000AFB78A8A68A270B54EE7C866DAEFEC39F8
+:10AE6000FA766D9C81A644466775BC528A9374FA43
+:10AE7000683694B9F0D885749EE362DF6AF078177B
+:10AE800089248C7EBCBF0F01BAFA93F1BD792E36AE
+:10AE90006F23BC73448B524AE739A78C0F007F1B8A
+:10AEA000E1FF689F4D31E5D072FDA32231759D8F82
+:10AEB00011FEB91EE37C8222ACF3F3CB8DCF19DFF8
+:10AEC0001C53E9FF29F0072DBF00FEA0F01F55F924
+:10AED000A353AF32FEF09A3DD3801FDA37F204E974
+:10AEE000AAF2CBAD2ABF2CA9D7F305211E11E8B8D1
+:10AEF0006C0E97FB40141FCC56F96059839E6F6E01
+:10AF0000277E313D065DE66ED87C6F9ADC757E9FAC
+:10AF1000A87C33FFC1FD889FAEF36474BA43A5D308
+:10AF2000ED35FAF65B55BADEAED2754EC3C3AF51FE
+:10AF3000F541E6C90111E4DDFB538D9E111D3D3D38
+:10AF40002A3D8D70DEA1D2F38E1F337A1AE18DA8CF
+:10AF5000F48C349C13C980AEF01AE15B707797F9DA
+:10AF6000605CABCC1F9B9EDEA6FC5547A39E57059D
+:10AF70006F5875344ACE566C9FAEAB2F0FCCD5BDF3
+:10AF8000BFACA14CD7BEA47EB9AE7DD1FA3B75F55E
+:10AF900032FF8F75EF2FB8BB56D77E7BCDFDBAF64B
+:10AFA000F9E50FEBEA733D1B75EFCF9EB359D73E22
+:10AFB000ABF4195DFB8CE29DBAFA7465B7EE7DD3F4
+:10AFC000BEAB6E06FE7CEB3D9E803D71C1FD05C6AD
+:10AFD000332FB84537BC73D427235F1FF30DC1F25D
+:10AFE000B8CF8D7C7FD23716CBD6A6663BAC137418
+:10AFF0005D5C4A12086932CDAB5DDF0FD66982EB2A
+:10B0000069C8E4A9F5D37AB34946792869904878A4
+:10B0100024211C2C362A1CED7C547BA487F606AA1E
+:10B02000F893BAB69744623FF73E527605F06577DB
+:10B03000EB03FDCB00BBA74DB5EB8DED951C298D2A
+:10B040007E4EC81A84C36A627647A5C4E4BF7257AD
+:10B050007A0171423D3CB8E672E3052993A7029F4D
+:10B0600064EBE47859C3353AFD4E209ADC07F86D5D
+:10B07000A4EEF98AEDD7EABE3BB59F47B8AB41577E
+:10B080008C8365B1F43313E8E17073E68C6100A73B
+:10B090007214EB4D7DD02E3CE52B5E757410D0AF55
+:10B0A00014CBE3BE39581EF379B03CEA2BC7F253F8
+:10B0B0005F0D9611DFDD58FEC5E7C7F263DF7A2C1E
+:10B0C0003FF2D563F9A1AF01CBF77D012C0FFBB6A1
+:10B0D00063F98E2F88658BAF09CB569F82A52677A3
+:10B0E0003DF1DD71751D3E09FC1783CFA43A7FED5C
+:10B0F000FA099D7C16C7DF877CA6E1B9A4C1ACF232
+:10B10000438A8E1F12C097433EEBA1BD4154F9B054
+:10B11000BBEF63B77BB7FC6BF86DEA0FE4B74E7E0D
+:10B12000CA30F053764FFC348C8FE2A7A92617B3B0
+:10B130007B547EFA19CC23865F310F8C903E51F6FA
+:10B140009A926F82756CA5BA0F421F60FDAC3A7679
+:10B150001D7DB705EDBAC0105837CE0EF9DB60D8AB
+:10B160004738FB21257E56F7F333F249F77857D05D
+:10B17000BF591AA0444FEADA6E8D6378B59A483108
+:10B18000A1EBDAFD839E722F1C8A758124C2F70120
+:10B19000F774478C7EA9AD0CF8ED09AF758EAF72D0
+:10B1A000A0BF638FFD3D0FCAA926662FC735F36880
+:10B1B000B793F0936EC06FC7BA6476A741BCBD7DEC
+:10B1C00090E442BB814CD6E3CF5FA0C3DFFD1447C0
+:10B1D0002DB8EED6A721FE067E3538BD17F8EB490F
+:10B1E000BFF784CF8530EF7F013E7BD28F3DE945AD
+:10B1F000A2C82F34D1F9B7ED1B96FB800CE35E1E7D
+:10B20000DFDAFE9A119E5F7E473E6E4BD1F8B8257D
+:10B2100093801FA4CACBD9C62BE3812E1DFDF44019
+:10B220004FEE779F6482FF7E3A4BDFDF7DC6FEE202
+:10B2300025C20DA7E33A2489C453BF92F76CE3D12A
+:10B240009F7147FC1037D86773D7C9E0379EFCAFB2
+:10B25000B00C3DEBE30B670F3DE9043F6C651A5FF3
+:10B260007334061DB5B22A9855638FF6579AF4F5D4
+:10B27000B3F55C7110E725C7CF1C06EB8CABE6A8D5
+:10B28000087A3F0D4BAD9F9569128E73727B763CA9
+:10B29000F3FF024C9FEC48407D73D267C1F7FFD9A2
+:10B2A000F074D78F060F218DE4330BE873DA96DD47
+:10B2B000FDFBDDCA83705E82F82909895F81BF6961
+:10B2C000A5FF7F3B00FA15B0AEF5EB0DF27EF370F3
+:10B2D00078BE43371EFD4ED6F68CE1BBEEE54E2020
+:10B2E000C734BEA7F4FBABBABFBD62BBB5466FC7E0
+:10B2F00026E8EADEA6F41A9D5D0BFF00C3BD8613A7
+:10B300006009AB54D9B04DB0AF077EDA03C149F044
+:10B310005F38F65E9525227964149716E0D385632D
+:10B3200035FE9767FF99EAA9136F8A04E48C5CA243
+:10B3300050E5A9AE20F29B8998687D91FAF6C2C6C5
+:10B340001525B06E9D78F926F44316935227F8C759
+:10B35000E5A43E0FE2B5A789A918E4F33479C7390B
+:10B36000324A1EAD82849D2E5AAFB7E3A97FAFABA0
+:10B370002F6BD0D797925B5260DF7EE9069104383D
+:10B38000D01BFAF6AF7917F6BB8CD4AC8375FB579C
+:10B390006ABC6BA18B0819546F55FDF6F1BC320ADB
+:10B3A000874B6071166D1F7A7922F37F2A66062417
+:10B3B00085BEFF59E3C85BA906A2DF07D6C17EBCE4
+:10B3C0007F3A716F235DE9F75DE137C2ABD9035D69
+:10B3D000F6C3553892B7734A20861ECB14382667B9
+:10B3E000AABE2B105CBAB8C73443FD7BF35332D1ED
+:10B3F000F1D31EDE93278C66FC03FCC009ED92E7B7
+:10B4000087F49FD6A5FF827F6AFFFD68FF79BAFEA9
+:10B41000A7FD53FB1FD805FE79B1FAAFFAEDF32F64
+:10B42000FBA93EA978F1974E42D7C913427D8A9B6A
+:10B43000D2B572DBBD4E8596C705BF13F8F54480C3
+:10B440002F8E45EF87054E1542C5CE41DC0DFE49D6
+:10B45000FB3FF9ECCF301EF1D536D185F1B4EDE6E6
+:10B46000B099CA6175E3F2129283F523AC7EDF19BD
+:10B470001EEA4D7AFEAB78FA9729901F4239458D26
+:10B480002F85D19EADDEFA7911AC4F5ED28E7264FB
+:10B49000FC0EC6BF9888FAAF4C8AEFDA4EE1C4388A
+:10B4A0008157C58BB7F16767782794377C01FA829B
+:10B4B0007A22E8C71BBF2B57EDD4358223F9988D2C
+:10B4C000FE7B0C19037A51C30B09303BB5EE995F33
+:10B4D000E71CA1709DDAFAA6938BC297264F67836B
+:10B4E0008BFE738FDCBDDE6DA5F2166D0F69EB96DA
+:10B4F000DCA4DAD72156568A6127E4F3546E16DDB0
+:10B500007EFAB8F2F9279F7A0CE2997F32BB07D115
+:10B51000FE573CFFDAFBE3697DC54E31B9844DC36C
+:10B52000CEA574D2C74BFFBF3BB7931E15BF794D55
+:10B530009287B1E7F72476D265C5CEFD1219D615EC
+:10B540001F9383FBA5883D067D82478AC05EA87B4A
+:10B55000E6BF2588339ED8C791D4AC18F8DCFC1A16
+:10B56000DA038027A4A74AAF0EFA19DEF752BA8091
+:10B57000DE36D2CBF8DE2255BF40BF906741F9FBE3
+:10B58000853D9007F591D90D78287F619513E6F3F5
+:10B590008550C3F8FCF17B53409F958BFE141796A2
+:10B5A000EC79F9133F42FE5BF6F68F5230BE4494BD
+:10B5B0007413AE45FE7498E7924DB3709E4B8907A5
+:10B5C000F9B0FC71BE3440CB0B0229DE19434EACFE
+:10B5D0002293932FB650E2D2797E01FE24E8EF77D2
+:10B5E000F8C036B4BBEF24A00F7EA4CE855A0C5809
+:10B5F000BF6061F4FAABBA2E10B03EA3F977EB7DD1
+:10B600002D40A793FD9554D877F112C1AFE283FB8B
+:10B6100096F6CBBF3D2595D189C8429EFA1D5DF7B0
+:10B6200027C37378BF4554AC39BAEFC8B7599DE307
+:10B63000AF56C7A770C7C17AFD454A6CFB354FD4DA
+:10B64000F4005DB7A3F82C4ADE99FC6FBD9FC9BB1F
+:10B6500026FF81E9C5D07EFE309323F80ED6430A3B
+:10B66000573815DBF7CFE4503F503F3A969C6F15A3
+:10B670005539D7B71BF985C22F70F1517C03E324EC
+:10B68000221D70DF65E906FA7D941EF5C2B8CEAEC4
+:10B69000FD6A72BC4CF35B45BD3E209B981EE8DE04
+:10B6A000AEF2239E2AC5C0538F81FC5279F5CB2080
+:10B6B000BF6229CCFFCB1DCDEFCFA372FB655093AA
+:10B6C0005BBD5E35CA6DF9AED12496DC7E69779399
+:10B6D00098724B9FC7945B7B04F9F9FFB45ED5F079
+:10B6E000380CF0784D271E353DD91D3E8D7AF290ED
+:10B6F00020235E8D7A92FE1D26795DF951E3438DFC
+:10B70000FF2A9EABBA02F451079F6A7CD8C1A71AE0
+:10B710001F7689EFEAF0686CBF00FB3414AEF9962F
+:10B720008DD38E5257D2D24E70DF267F268FFBAA42
+:10B7300096F384E5811011F3433F30D58C063B75B9
+:10B74000E2DF6F3D7D1785773EF18B2C2FA05E44A5
+:10B75000BBFFD2B7DF4EA0F399A7E2793E45FB5479
+:10B760004A973902178EA370CE15883F3E11E2B773
+:10B770001CF9340A8EF9E5FA3AFC4D4CE9ECA7A71E
+:10B78000F7BFAB9FF27DCBB7295D3F1D44C8BB50CF
+:10B790008A38BC10CD57D381AE147FDE515C600077
+:10B7A000EAA988501AE577BD2032FBF3EDC219A350
+:10B7B000C1BEC99F3D2C9EF1FB60F47BBDAA3E3B00
+:10B7C000EB97E341CF9F0D65A37F7BF6D02247AC7B
+:10B7D000BCD06695CF5E53F75DDAEC5C3D4FF9BFA8
+:10B7E0008DB4A37DE3B75BC9B618FB821B454D5FE3
+:10B7F000AB74A37F3C1D7F8ECA8773E9A7F1B95153
+:10B80000749B39F584E0EC4A07F8FB34CA0FFBA1BE
+:10B81000F805BE06FC365B2345A531E279CFA9F8D1
+:10B820009B78E06BCCCF2D0CE50B80C7423BAF8BF8
+:10B83000833CA9C9EB503214E09A7860F9CF4753A2
+:10B840003EF61EE2DD908FEB0D9D913C31FC6123B5
+:10B850003EA17FB0338F882EC4D77B62E912C0EB44
+:10B860007BB3AC04F635DF95DC55B1E02C33B3F592
+:10B87000662E29BD308AFBBF0FBFF9B31DE1028AD6
+:10B880008FB37696F7DD95FF98DC9F7571815A0E20
+:10B89000F89067F5642E0071B422E2F9F9040EE520
+:10B8A0007D52B4FECA6F9AFE3CE4F55487389789FE
+:10B8B000B6570B1109F8D8DBB45300FBFD269928C5
+:10B8C000188F106A86CD8C8A7B1D1105C457F3DF53
+:10B8D000E6DD0EF83D37D34C002E65E81927D80178
+:10B8E000E74223510EBA9BD71F7C645AA108FD1072
+:10B8F000E40F233F1425DB74F55993493F37A5DB4B
+:10B90000447364953B06FDEA24C667BDD66F96FF77
+:10B91000CFF4DB04AADF185F8BD1FAED2689F17D25
+:10B92000947E4B8DA5DF56D6CAA9C0172BF766A704
+:10B93000025D57BEB1A44F2CFDF6BA8FF9F76FA880
+:10B9400079E66DFDA87E1B1EA5DFFA51FD1623AE1C
+:10B950003B5AEAA57EB3FCCFC8DFEBA0DF62CCB7D1
+:10B9600058C59FA6DF8A43B5A8DF8AFBF1BA7CA938
+:10B9700049524FFAADEC97B3B02EBA6D31F807F0DB
+:10B980000AFAED0D55CFC138A0E7FE5D727D273D67
+:10B9900057D55B3DF73F84674DCFADECCFA13DD38D
+:10B9A000950F999E5B99C5F4DCCABD4CCFAD1CC404
+:10B9B000F49C51BF1574D16FECFBEA21F47BF423A6
+:10B9C000B37E7D1B6D2F9923BA2DF4FD12593B9F39
+:10B9D00051333A5ADFFDBBD48DBE739FC1732E3DE8
+:10B9E000E9BB3F82BE1B847A6C20C891913F6E1CDC
+:10B9F00068D3E5D3BDF7F5B1E75E0479F9038FFEAF
+:10BA0000F70726E627EDFBFAD84890BBF7001EAAF9
+:10BA1000EF9E51F9AFD5E7477D3A792893F7AA7B96
+:10BA200018FEAA1B3936DFD57C408675E06F17D12A
+:10BA30008FBE7D2FF3A3679B5BFAD8C0CFFF5F2239
+:10BA4000CA25FD2B298BE28739172B30EEB92BCE77
+:10BA5000B905FCCC3902B1801DBBE0D08D27C07E7A
+:10BA60005D70713DDABD0BE07922E9C8FB98DBA17E
+:10BA700027F5F6EBBCA69DAF6590AEF91013CD8C03
+:10BA80002E13577181CD595DF323A85D86F92DC61C
+:10BA90003C89DFABF39FCD47105FE48F7CCCF8E5AA
+:10BAA000EF8D787233BC54ADE6F578AAE162E28995
+:10BAB00052BAA42CA5132FB7BF14599701EDCB3957
+:10BAC000F4B78CF3D6F0669CBF8647CDBF59A0BEB5
+:10BAD0003F3F7424669E8886E72EF9221ADE0DF811
+:10BAE000784BD333D7906120971F983C3F1F0D7C34
+:10BAF000F47B8A170AE7AD7307E9CE2BBDA3E26595
+:10BB0000AAE748618A0C782435C067F3CA77BE96E5
+:10BB100042E777B392950B21F5597F933C108F68DC
+:10BB2000B6B6A31ED4F8709499C98559D52BEFF5F4
+:10BB30007515E27AD3C4B950BEC2063DA7E699791D
+:10BB4000EF61F2D7CCFDF7BA8C518867582E489137
+:10BB5000B65E015DE83FA786185DBC4017FACF6965
+:10BB6000A4FD20E0BD3A997387E1FDA69DF7023F51
+:10BB7000BD6EA5CF41CECB39F716860E7B7ACA654E
+:10BB8000F95888C5C718CCC8EB5C3F17C07B895DE6
+:10BB9000ED9389E696F7008E89546E36C3C300FD97
+:10BBA0002F8AFE46FBC5C8073DE50375C7EFB92AD6
+:10BBB0009E5F073AD801DFED12D843DE305B7FB4D9
+:10BBC00076AF201722DE343A34D1F56514A38329E9
+:10BBD000069E6FD6EA2A9EBD214E84EF6FA0FE6FAF
+:10BBE0001207BB7E5F1FD4F8DD2C77C513C415D2B6
+:10BBF000A3F406E8B7E87DCDEAA6B7115F37AEA695
+:10BC0000E699DC155F1A7D400F5E0E6FDDCA4FD3DB
+:10BC100091987961DF557E4699F5F2B3CFDAFEE669
+:10BC20007088ABEDE550AF9050822E7E30D3CCECD7
+:10BC30009666AB07F9BCFD0DD1BD45EEAA7FA6A85F
+:10BC400074017F25FA7CE2649808E84D97957CA6FC
+:10BC5000CD7B00E3B7E8F5E075AB07E9D75DFF33CF
+:10BC6000CCCCFEEDCE1ED3EAD7C37890D728EBC755
+:10BC700033AE475A5CA9A77979D471BFEFBCB471D0
+:10BC8000BEEBBE8497B4603C4EDB9FD8C37B768905
+:10BC9000603F1673BA7D100A39EE6FFE13FABF5972
+:10BCA0001ADD7DFF103F0A533CBFBEE3498C639F02
+:10BCB0007EF6C834909F15AFF0C442E5AF75878318
+:10BCC00084599E8804764245238FFB5D4408E7CD66
+:10BCD00088B233A827C3F0F1A203F55EC52E73A086
+:10BCE000847E5FF1F26739107F6B5DC3F49FFF596B
+:10BCF000951FFD911CC807A810D8FEBC913E8FA8C7
+:10BD0000FC796AB76D0EE86F6E3B3BC75B119C2DEB
+:10BD10009AA3E20CF79B4516E7DE6DC33C6CFF333C
+:10BD20001CE631037CD1E748B5FCD053CF30BD5C75
+:10BD3000D12406E03C70C5F69DAD1017AFF8D08C4D
+:10BD4000F6AB77FB1909ECD3C92F3ECFCE1B37F1E9
+:10BD5000BA78689738E4763E6C86F8596315EA013C
+:10BD60005A3F82F5A01AF7FB8E71B2152FEE7DD9DE
+:10BD70004F51B8E2374F3BF15C70CB3627C623B743
+:10BD80005F7E5FA04BDC3178BF1A779CFA05C1F566
+:10BD90002176DCF1A4CA2721B33EEE48B627613CE8
+:10BDA00092C299571A237ED1C1FFCF5F7802F6CD98
+:10BDB0004EEDFAF20980BBF29B734FFC94E2932A9A
+:10BDC0002017ACDBDE67DFC37D06EDBBF7557DD208
+:10BDD000FACCD3B84FD3FA27B31B7A6BDDFB4526D9
+:10BDE000EC53B4EEFC3A05E2B8ABF74E417F6DF58B
+:10BDF0004B9353490C7F402B817F03BDD82732D210
+:10BE0000ADB9B13913E03C4DE90EEB77473C3958F9
+:10BE1000C5E2F4B21A47DE117B5FAE4BDCB871C6E7
+:10BE2000CDD7C13ADE28BA65D28BF8F1614ACFE1AD
+:10BE3000BDA0E30E759F2038F5B2F1E3D3F00F4AB1
+:10BE4000AF0B667D1CFE42E392FF7C0CDA1A93BABC
+:10BE50008D1F877B813F6DDF6FBF59211690A35DDA
+:10BE6000CF61DC1EE8477D0FD2FAFC854C88BB1CF5
+:10BE700017DBEFC0FCEBBD66CCA3AAD8FB01CA530D
+:10BE8000EB4B6FE3BE1A51F7DF5A49C71FDB27514F
+:10BE90007D3AEF56078B3BAB7480B8B4ECC4E76ACD
+:10BEA000FC99F1B51697EE2E1E3DD63280EDBFAB54
+:10BEB000FB91555BFF2C1143BC9F1B0BF43A72D9CD
+:10BEC0007D540D0F2EC0C398E8FD96D8F1FF8EFD6E
+:10BED0001603DD809E608F75ECA7D07A3F88AB0794
+:10BEE000B80F62EDDFB56E66FB34AD62ECBC456D3C
+:10BEF000FF65A4C5B0EF12E8DDBE4B4FF3F8AE7896
+:10BF0000CA0627B44F577C9DBA145BBFDF6AE1D4E1
+:10BF10007B03BEE7BE7E2567CC1B98057C59D57890
+:10BF200044027B4A5BDFB4F99E52FDE753CFF278BF
+:10BF30004E645DB019F5BB517F5413163734C25BA4
+:10BF40006E617AABBA89AD1FA776390276DACFA9CE
+:10BF500003BB91AFAB771C91FCB4BF83DB7F234560
+:10BF6000A2F2AC60FD0844C17FEA85FD396C7F898F
+:10BF7000F9EBC671EE52C7F186628FE3DD71463789
+:10BF8000CE0A7F5062E77E2E3FDE4941990DFD9D2E
+:10BF90006C1109E4FD9F0CF2C58118E3CFB5885AF6
+:10BFA0003C8BC90F5D47F11CA6839DBBE41325B4F0
+:10BFB000BB573BC67E08E7FD573B2419E21775B512
+:10BFC0002C2FB5EEDFDC6940EFBA845B713FAEDE4B
+:10BFD000805F57B22B1FE21AAEC2D251C0AE46BD2F
+:10BFE00093A09874F0AF7614A7CA14CEB5AA9D4654
+:10BFF00004379E0BE59D45C5301FDE65725963EC25
+:10C000003B88F652E289C28BE8D29FE3249746CA66
+:10C01000D08F967F53696939888D2E05538C85B1F1
+:10C02000ECDDFC992E9C77DB0ED57F5088EC4A61C5
+:10C030007964B08EB4ED8ACF21C3F143A2507EB4AF
+:10C04000A9CFB91DFBF7835E5AEB244A0295338AC8
+:10C050005599CF86F3AC232C5C36F0E999FF7A85AD
+:10C06000F66B0DF1E857B4D9B57C522501E4CC4606
+:10C070001EC4BC4160E56F933AE134E613127825A3
+:10C08000EA3E8D29BC1DFDA1B39B587C802757FF3C
+:10C090007A028BCF9100C0AFAE2F2B5438CF12E273
+:10C0A0000EC3FB3B1C180F58F6C622941FA0433446
+:10C0B000BE928AF5E75E1BACCE1CF067365A55BFC0
+:10C0C000C6AFB4C0399BC56ABF7D4AF5E762A918FF
+:10C0D000FA415E97A8F2FAE5D2A243988FE6598A10
+:10C0E0007A3E758EFEDCAC314F4B20AA9F1C60FE61
+:10C0F0007397BCADA6CD08B7317F6BC5767D5DC3A8
+:10C10000E327A037AF027412FBE5E2803DE237324D
+:10C11000F8D713467D77FC9AD3F4F8B5CA7AFCDADF
+:10C120008618F1A7C7AFC3ADC797E6977687DFF844
+:10C13000B1FA73C8FF2AFC8A56D58E54F14AFF4AD9
+:10C140002D294C6503DCE94218E5C2284719F63071
+:10C1500007FFEE9F1CA8C5AFDC0ED4EF69EA7CB8E0
+:10C16000C5EC3B1BC8110FF0BA518EE02420E879D2
+:10C170001BF9D875CC0AC4FA8C7C7B4DF7F45C357E
+:10C18000FDD5230BE9579B807F87233FB0F3BE8902
+:10C190002450970572EA76C1FA1DF459DC8B45B834
+:10C1A000F785B8170F82FB5E5C583EA4E6ABB40D72
+:10C1B00025786E30183E9F02FAE9A1DCF669A0F7F7
+:10C1C000BC4B4829E8C11FC5B1F3030FA865BF38B0
+:10C1D00049D5AB856F4C82EF43A20CE7D5DB42DB40
+:10C1E0002C83A0DEC4E33D2ADE84FAAB60FCD6904B
+:10C1F000C8E05A6C090C8238C85E11C76D5D3C01FD
+:10C20000CF6576D86F21962FD216FACCB9284A9FDF
+:10C21000B7363D7A15C4B9369A62E7A94CB19A7E11
+:10C22000D8FA1BEC92B737C5CAF2EA1E1A40E7519A
+:10C230003DFDACBA0E3379B856A5F3AB4B6FC4F9DC
+:10C24000BF14E26458478AF8DB6E1A46E739EE3DC0
+:10C25000418DCFB078E528F5FD3AD02FA85FEBDF10
+:10C26000E5E9C3DD470502E7F446D52C457FEB152C
+:10C2700027E573CA17794A7024F06D612801EFCD64
+:10C28000F17E4CD0AE1FDD22E8F8334F5D57F3222C
+:10C29000545EC044F950DF3E2E2218ECA0000FFC83
+:10C2A00075ED71FDF38556D5EE729214E0F30D979E
+:10C2B000780EF25EDBDA897B0D85BB6D715F84A33E
+:10C2C000ED3C9CFAA5E525BE38D67ABFCACAF8620D
+:10C2D000A344709DD9B8D48EF1C5034B2BAE80F525
+:10C2E000FDAB1F7BAE88758E3C4A3FC5B37C2C25C9
+:10C2F0009E8C05FE5ECB31BCD7A797C6C8F7D7F892
+:10C3000059E36F8DAFD397C67962E5357E63657665
+:10C310005AC1D2219C04FEDA3E0E8FE3B6AEF15C28
+:10C32000F6DC8D9FACC90078BC4DE7D0EEB6843802
+:10C330002596BDB1C1EAC4FE5BD7F86B218FEF2E05
+:10C340002A9CA027BBEF7703FA5B3F81A02C7C6778
+:10C35000A92FC373BC4B2C640BC4BB85FAF45B1CC4
+:10C36000C0FF936F5847E17DACD484EBEB46D18D91
+:10C37000F0FBAB08C1F8831ACFED378D6C8E3ECF42
+:10C38000FC8435FF592BA5C7B35617D225C9E3E660
+:10C39000007EF73FFEDB09F2DD76D18C74ECABFA60
+:10C3A00043DA77AF5999DD36334ED90ADF93F26419
+:10C3B0009413B7C7E95E3C12EE4DA0788F92A34E5E
+:10C3C000FAF9F1BB440FD571149E44BB09F99228C8
+:10C3D0008AECD2C529FD28479A5C903047208F4DC2
+:10C3E000D3AB5C880B3BA81C8CB2D8C3E0772496F7
+:10C3F000D3795310ACC4C2FA6B114E759CCBC63CBA
+:10C4000079CA977970388A6048141271A17F4DDF1C
+:10C410006A7A7A6D02417959FBB010A8A3FD6C12BB
+:10C42000225688AF64297201A41A250A329E17EF9A
+:10C430005F4E30FFD296FD784287DD42857EC4375D
+:10C44000FC8258FB797C9C862FCF1F406FE41C6ACE
+:10C450003F00E68DDBCAC673BF66413BBD437FA884
+:10C46000F65891BAFE8EFBDCC4F209C29348F43E42
+:10C470009B517F68F6C9B8EB226B60BF68DC9F18E0
+:10C480009CB45B05BE1BADCEB7439FA8EBE69810EE
+:10C49000D527F4FBDCD0C866B8072BF76326C75D49
+:10C4A000F4C9213F0FF8FBBE7AC4C81723C2542E2B
+:10C4B000D5F6A132DCA7E1EAA843FB1983DE499E49
+:10C4C0003E2A15ED5C95DF8C78D6E4DB28F7B9774A
+:10C4D000BB9BCD0C2EE6471AC6215C271C7236E8A2
+:10C4E000A5B778B0F7DBF2291E285CBF02F9A3F4E8
+:10C4F0004B381FB801E6BF2174BD15E4E47BAF27BC
+:10C5000021FA75549EF6D3BC273EAE0FAE274EC01F
+:10C5100043F5FEF3EA7A12467A77C8019593E878F4
+:10C5200089C6FF467ED7E4A30E2EDEC8C673760406
+:10C53000D6599E0BE2653066B2C90578D5ECED3A66
+:10C54000D5BE25FE74B4FF56BB88BA1E6506804F63
+:10C55000EA44CD5E775BA2E353AB1D05A997DB4FA1
+:10C56000F55EA4FE59D4391BAFD08EFE9BF7A28492
+:10C57000CFBF37FE9A2814793AFC8D891BDD157FD1
+:10C58000F17184B0FBC2FE9F9FDF0C237FDC277715
+:10C59000CEEF5AE2792542F547DEAAF57536193F06
+:10C5A000399C96D7552F68FB9FDDE901A3BC8FA965
+:10C5B000AC6FC6704B0FF2EEB5A9F8256406E8B370
+:10C5C000F1616AB7647595FFF3EAFCBC3686F7B68D
+:10C5D0005BDB07833CADE73D3571682F464C26B0E9
+:10C5E0002B7613B47BDCFB8F3A51DE5B9274EB4FFE
+:10C5F00057BBC08FF2A9D9A79A5D6A7CAFC32E55ED
+:10C60000D71B2D3ECA355179A1F03C19E7F1031C27
+:10C61000752EE6BFC20157D0634F583D75C05F36D7
+:10C620003A9738D82F1912CE62F196B04E3EBB938E
+:10C63000479B41DE82143FB0FEF9E9FA3788EB1ED2
+:10C640009EB171090C5EAA85C0BEE99747D860D536
+:10C6500004F3C7FBE5B0FB6BFAE5B2FB3237C73139
+:10C66000FB658BA17CC25AFA18CC4B1488DF9CFB6B
+:10C67000FDE10650210EF9649CD200F8B0142B386D
+:10C680008F0C17717394DE19429083BC89C44A9948
+:10C6900063F147D2B9FF48FBCB2891F3813F3206C3
+:10C6A000123C379A118A7D9EE89538F187D9EB8D37
+:10C6B0005DCEC1BCA2CACF4189CE37A9849D83E992
+:10C6C00088FB50F001BFAD8E5B71B2AD17D83EABA9
+:10C6D0003F81E1D9E8BF01C1605E825ABF57228223
+:10C6E0003511FD2B3FF0AFDF6441FFCA46DC41D07E
+:10C6F000B71FC4B1F8EC3ACEBD1EEABF10DA2D70F8
+:10C70000CF8F26379A3C3C34E116B7405F755E7791
+:10C7100036077C5F2A17EF009E5B279C1DBC1667BF
+:10C72000D29EC9F84EE175F9F61AFD9A441DFDAC8A
+:10C73000105789D6F30E6908D8EDAD5C9C1BFCAA96
+:10C74000D6E51C8397B3A8E71104DD3CD36CCC1F5E
+:10C750006953F5E7DFE3B2901FB5F584CE6F3DC6B0
+:10C760007F0DF3E838876A38776A3C979A96DD112F
+:10C77000074AC77CDC5209EE3223674336B4E3BC78
+:10C78000CEF64C12E3BC646AC41AF35CB05652BCD9
+:10C790007D0D784B156B12401FA7DECEF488111F5C
+:10C7A0006D9C7FC441D847FB8318331F452BD3D2E0
+:10C7B0006E4A584CDF4F4BBF014BED79835D8819B2
+:10C7C000574CB2713FECDC6403B118FCCD241BED77
+:10C7D000EFB4E79DF71514FF768CBB37C431BC3737
+:10C7E000C431BC37481A3EE57890BFCEBA5B97F7A4
+:10C7F000B4C1674910200FD19F8EF2B9C4C5E8DDDE
+:10C80000F9BE82F64D1FA2DC301794C406916C432A
+:10C81000BE67F121ED7CC8AF7CCF2440BE94DB968F
+:10C82000A5FAFB1646DF0406F7F90D5370DC14B2C7
+:10C83000C63A98E27969A9C90D71A3D30B3F72C2B8
+:10C8400091E985192D79200FA7798F1BE6974A98D2
+:10C850005FB86C8E1408D32E931BA8C26274BA0101
+:10C86000F73BCB4C31F3AEC7D8D8FEE9D138179699
+:10C870006969D3904E9DF59204F04B8C7C4AE53566
+:10C880007DF1A8CE73CC946F145B0C796B134913B4
+:10C8900087EB5B18F195ACB1B3AAB7357949063986
+:10C8A000847DAB52AA47353A0F505F4DC1B828FE80
+:10C8B00071A1D7BF067FC3795D01EA454D8EC810CF
+:10C8C000A6E7ADA077A3E2A16D7B3FE80FFB8E9FAB
+:10C8D000FCDB3907EC3BFD556877809E3D7ECFBB86
+:10C8E0000E38C7F4C93D2C2E7287C14F5B6463FAC2
+:10C8F0007F8FAD741EE07781EF1F799E287E2577AC
+:10C90000B3FD93E501DE70DE5D7F6F505530C97079
+:10C910008F901FF15AA5DE1F66A4C7461B8BB72C4C
+:10C92000DFB159CA90617C4F258C7F5CF5438F370E
+:10C930003AD0DFD1E059B8638404BED95F4366754D
+:10C94000FFBD4564EB875202FB671E156F46380F2B
+:10C95000AAF76A2FF925CB8F29A363DD4DF5B02700
+:10C96000C4CE7B18E7B1E413B92895126FC9FD1C3A
+:10C97000FADDF0FE3D743DF3DC7D1FEEB319E7D91F
+:10C98000F55E1F05FDB3652ABD8DE76D9785D83E21
+:10C99000F862E241F9EC72FE36C4CEC518E38D6749
+:10C9A0000F65DB000FBFB0A9F1C43C3206CE6DEFBE
+:10C9B0003A3420FE72F7569F52EF8B827BBBA13C2C
+:10C9C000EE2358CE032390E2BF32F4F65DC05FD56C
+:10C9D0004D3BF13EB4EFAA8FAA42279C904BADE9A4
+:10C9E000256A876E03F9208B399D7D5ABDF99CC459
+:10C9F000FC6A869FDBD4E7B7013E7220DF5BFED97D
+:10CA0000044AEFDB2AC5F3D1F7A53D6FD3EFC3F797
+:10CA100076BEDA3CB5796BED556A5E9CF13B4D0E06
+:10CA2000E6A97CB978EBF4757D298AEAF67E91A9AE
+:10CA30009E93C3F3421A9F2D23A545E931F849A3DC
+:10CA40006F07DF847E8EF3D3E8BAB8BE4CC5833F50
+:10CA50004DDD4F4C837895918F7A3AA7DD2A463287
+:10CA600041BE8D7CD2DACD7D28211BB32F16CB4A57
+:10CA700011C4CFA8F9BBCE1565DF1C17EA0FFE1451
+:10CA8000E46E2BE3FB0E3D084E31E8F737455CFFC3
+:10CA9000573AE454B8FF0FE9370EF213CC7E784FC3
+:10CAA0001BE7984F51068A80FF622C4FFA4A958106
+:10CAB000833ADB976E3CE704FBBB6D08C1B851AB12
+:10CAC000430FEF691B8F7AE3B44A8F4AA1E59B3F7E
+:10CAD00083CEDADA827917C72EA971A74BE6E2581E
+:10CAE000F3B4D839DDBD7877A872A8F9350B54FABC
+:10CAF000DD1162FBE90B374D477A74C9BF54FDA1C4
+:10CB0000B2460EF58E913E4BDCD7633EDAA2403E34
+:10CB10007EDF855EE441A4BB916E77DA5DEC1E3763
+:10CB2000A146827BED8E6DE270FF7185107BFF73F5
+:10CB3000B6DDF49DE6639C4777F02FDB5ABBAE2F42
+:10CB400081F98F9080CF8DF06BF35F4214A6A7D44C
+:10CB5000F976372F1299C4F234D4757F399C5B81F2
+:10CB6000FD93077996CFADC6A134F835788DF328BB
+:10CB7000E22BF17C415B038F79D977F8D97D067779
+:10CB8000ACE570FDED8E4E9A5ED1F67BAA9BCA3065
+:10CB90006FCB43FB013BB6ED63C2F629D67378CF6A
+:10CBA0005BB7F40CB17CA5EEE84908A3DB624A3719
+:10CBB000F03FBBDE9F90AF0C8CDE270ADCA00C8C14
+:10CBC000DEB72241CC5759B17DBAEEF98D76358E5C
+:10CBD000A5EAF59EE48FD424C48C6F69F2A6C99FA0
+:10CBE000268F77DA65666F0A81831959809F87D10E
+:10CBF000BFA1FA7A9E9DF93D0FCDA5AF546F3CA71A
+:10CC0000DBA7583296D16B095F82CFBBD3BB140F21
+:10CC10003ABDBDD8AECFC3F8A1F3D1E6A1C98936DC
+:10CC20003FA39C18BF37D2438BEF19E962A407C01A
+:10CC3000097EC65B7B6D813514CEB73806B77FAFF2
+:10CC400015E16E4D9BACC0B9CDEAF4F958FE013E3A
+:10CC50004C07FBB0B4CE8E76AEEA878DEA5D5C22DF
+:10CC600057B5CB5EB22A23D9B9A7D224E09389B5B0
+:10CC700091191617218F3E585C04F7A44E7C383268
+:10CC80000342F1BF7EF04656DF1679D7E286FBFC01
+:10CC90004B8A0A69FD71D02FA02FFA95DBE0FB6E5D
+:10CCA000EBC473F9BACCDE1F652E9DCFEEB166EDF5
+:10CCB00095D43EB3D0F5AEF2F0E057417E2B5B4AFF
+:10CCC0008A212E54091178BADE5529CEB02D87ADB0
+:10CCD000FBE3E97B1FD93C4FD921EE76712DAE8B5A
+:10CCE000958705942F7288C567053A572BFD6E6DA1
+:10CCF0001CB593297ED7265ADCE017D3E77EF09740
+:10CD0000D7262AB21CF55CA31F7C0770AC35B17C1A
+:10CD100082FD6F0C8E8F5CC62ED8EF2325E0CF34BA
+:10CD2000FB2C581ADBF325179EE7C837B17889B179
+:10CD3000FD6DBB76AE49CE00BEA83E24A1FCC31F4C
+:10CD4000D89F5584C9493561E7D0AA0E133C775363
+:10CD50007DA808CFDDC0B9844F757AE05F73EEA679
+:10CD600093AF189E0A04AE44881AB7D06ED5D5F991
+:10CD700054D310980FE1E3DC706E84CF30D5ECA271
+:10CD8000F3E7AFA025C587E072F370FF4CFDE4899F
+:10CD90003CDC9F5527AA792D26763EBE63DD57E5FC
+:10CDA0004F2BFB394A8F02DD4FFFB125CFC6F6531B
+:10CDB000D0AFD6E65BC72984037FED3582E71972D1
+:10CDC000934933E0CF4694B1C06F1647A2CA976C1F
+:10CDD0003F9BFE6540E9369B7E23537EFFFAC19F51
+:10CDE00022FFBBE34DABB2689D73F8593DC3742E6F
+:10CDF0008BB230EFA865F56B4CE706D0BAE858C3A4
+:10CE0000EAB0F14A173EB3A3AEC83F14C67131BAB7
+:10CE1000EE50AE01FE164C2CAE231C90707F47CB1B
+:10CE200057594B7906F8D1E2607A745D6DC173365B
+:10CE3000889B172832E44FEC51EF41FABEA5865784
+:10CE4000DE66427F094AC07FBC83E153A30B69546D
+:10CE5000AE813C5E1254AE817DBD7E0E4FA2837EBC
+:10CE60003FF2AD9689A0CF1BDFF9280FEF73BF8289
+:10CE7000F533F22DEA43D2F99CFE6DFFCDD1FBE4F0
+:10CE8000FD1CF9A9F01D2503DAAF9CEC22B751393E
+:10CE9000AC53882C65839FADF72F1B09D34F1FD947
+:10CEA0004AAF70A03E09E33AF613BB6700D48D7E0B
+:10CEB000336949EC55DE9D947337EE172566347D52
+:10CEC000B810D685DFB17B4A3845C1FCD3173BEE9D
+:10CED0006B231897B2913837C48D899BA4F953D42A
+:10CEE000F89A89F155725E94FFACCE877E5F08791F
+:10CEF000F2636C2CBF81CE8F07FD3A82C8588E84B6
+:10CF0000385936A0D883F53D24F8E14F69FF8F5892
+:10CF1000597CCAB29DE8E28F650E16B779C0C9E2A6
+:10CF20008F7162F016B02BE2CE1017D8156D8F4BB3
+:10CF300002EECF0BAE9B70DFEEA009E3DC4F8B015E
+:10CF400017EC17B55F25C85B48677F6D2ADDB57E96
+:10CF50001F91E4AB20EEF70B27AB3F9D4F308FBB0B
+:10CF6000FD841480FDDCC40C4B4D743C699E83D958
+:10CF7000BBBF7315CC043A04F7C611187FCCBE387A
+:10CF800013D0E3B91DB956E08B170147140F89661A
+:10CF9000D79DD05FE2390A6F163E67F9FD823C22C9
+:10CFA0009EE277FC8D7619EED17ADA1ABC11F3562F
+:10CFB0009F37E1BDC12F4AEEE9507FF1ACEC023D55
+:10CFC000FC7456300EE7F3BC09E7F3625CFBD52B2B
+:10CFD00029DC0F0C61F12EC14604D0CF82A940BEDE
+:10CFE000933E5FAEF2B1A6AF37811CD1FA231CC1CC
+:10CFF000730C82291FE548CB276A6B27984FD467AB
+:10D00000660B0FFC1C375D8B3B857988174D2825F7
+:10D0100068CF4DB08B78CE05F299E1BCDB44550F5B
+:10D020004FFCB8B284E507BB0FC3BD9ECD76F57E3D
+:10D0300030759F7392CA27D791086FA1EDD75D24F1
+:10D040006E88274DBAA8DF8F78CA605F4E51FB57B4
+:10D05000DA5D85F0389FE8EDBF290D4527603D2C4E
+:10D06000208A00FC34D96268073BD209F7F0EB9FB5
+:10D070003FE050FDDC4C92199DC7A6ED434DE18782
+:10D080006E44FBB55872035E76DA950F203FC0DF21
+:10D090002292CBC5259FF2B17CC321176D04AE2C23
+:10D0A000A4FC6987F95CDD50EFB7D2795F3D90F55C
+:10D0B0000F7C08FAE5CAC7939340DF8F57E9A5951F
+:10D0C0001ADF017FB9E2197FB98677CAE7D38E2CC0
+:10D0D0007C4F9337E03BE8678F18981F6BBF9BF23C
+:10D0E000EBD3C0AF3BED04FDB89FA55BE6809C6928
+:10D0F000E3B4AA7C6D2CD7D5AEDC0FBFFBE4BFC078
+:10D10000D68DC2BE17A5E875BF4F0283D72BD7CFE8
+:10D11000980679687611F3CC52D47351D1FC921EE3
+:10D12000C52F1ADFB5DA599C48E39FC9BBDFE5E19B
+:10D13000F9E40B84B8B24887BFA2F1CF447F18F757
+:10D14000812712E69F18F9675737FC937F5E1640D8
+:10D150006F75E19F438C7FBAE31BDA0FDE6B61E4EE
+:10D160009F771CAABDDD2DFF5CC2F3FCABF74EBE62
+:10D17000EC7E65934F9F9F6A2CC7D962E72FBB5403
+:10D18000BCEF96EA6FCA01BD31D5C4CEEF0924E3E6
+:10D19000160AEFEE38EDDEFC9A6CA8EF14981EDA52
+:10D1A0001932A31EDA69F778307E9B6661E757056E
+:10D1B0004F04CE23B8FB5AE4E8DF21D9EE6076585D
+:10D1C000500C8FFB02ECF137181F8C9D9ACB432A31
+:10D1D0005AFA62A617461D9736C3EFCF3DEACCBF79
+:10D1E000007C9606B8A3DF798F4A78CF52F55109B3
+:10D1F000F5E36FF7BD5D04F1512DCF79CC9EB78B70
+:10D200000A86C2FB8CDFFEA1EA65AD8E4740405F17
+:10D210001AEEDD1FD7711E4B7F6F7E29F0514E67CE
+:10D22000BBF13EF9601CDB3F994D6411869871B4E7
+:10D23000F45EB8DECC78AFFCEC303BFF36F3B027C1
+:10D24000F6BDF22A7F18EF37A7F6778A13ECEFE7DF
+:10D250005AF6416884C86CDD0E4A35D7303FA326A4
+:10D260001BF8499343FCA3F80B7E3244F7BB06B787
+:10D27000A9F37FD02DB0FBA92212EE4BFE9CB0EF9C
+:10D2800082EA3A36CAC9F440EEEA17E6039C23CB99
+:10D290009566A0CBB32E16D7F905095BB2816E6EE9
+:10D2A00001F75382A23CF90BAEF33D22940EB1D3A9
+:10D2B000F63D7DE246C2F88F3A3D639C609F09EDE2
+:10D2C00087E0BB31E37347821EB78F589B04EB9A0C
+:10D2D000063785AB789BBD130E0DAE814EC6978F7A
+:10D2E0003ACBC6001EE03BD04B4D478E59E07B8DBC
+:10D2F0001F827BCF303E88E20BE0834EBEE01640BB
+:10D300005DC383A2AECFB7FD8BF8428B6BF4C81719
+:10D3100010B7707E2FBE980B7835F205B5E73CCE7E
+:10D3200018F65C50627993C6E73FB1E7E3FB6E897C
+:10D3300060DE13D96765BF6BE849C07D90DFB8D860
+:10D34000986D9F1CCBA4A62859E56476BDF63B2AB0
+:10D3500023C21CDA9F23A8A2B80DEDBC7EA827DD4E
+:10D360002AFEC8318E83FB4631373E03ECD0701263
+:10D37000D86B23CC256190875DB68919603FE6DACA
+:10D380002664C3FC5F1EB2FA4D58D25EEE5BFE9B74
+:10D39000AD72A77DA5E9C366B55B6DFC352A7F4CF0
+:10D3A00052D87927D0EBD17068EB039009E0E0C246
+:10D3B000B34DDFDA508F8722146F93000E8A87FDFA
+:10D3C0001C6904FB21DFA4244F063BB04F580038F2
+:10D3D000DBF67E9D09F1CE92D0EB1F02BC25DA3E32
+:10D3E000AC5BBF0F6BB4B7357B48F33F347B49F37D
+:10D3F0007BC1AE82F632D51F7199D9BED884B005F3
+:10D40000EF5378E4AC7C95A2CAB340E751A2CEE3D7
+:10D4100066D2827069F7A94C53F1517288FAAB3920
+:10D42000D04EC8548A87A9EA7D2A53DDFAFB226EC2
+:10D430001E1BFB3E15AD9F9EDE37AE1BD71AF6A313
+:10D440007E6879C8C7EE4FF9BD8FF9C3E307F07E58
+:10D4500001D6DFB159ECFE0917C3C32129F63A768C
+:10D460005195EBF1A6480E9CC7DEBFE7EFB86E1EE4
+:10D47000D8F3F7F7C18E1C77422090973BFEC4A8E3
+:10D4800078CC0F182B235F69FD7A3F6FB411F69C9F
+:10D4900044FFDECC410A8F7225C067C1F295538FDD
+:10D4A0003C0AFD9D3F2A90E8731F45926720C4E522
+:10D4B0008BD4DF1D3AC8317B4A6B3FA8FEDEC71113
+:10D4C000956F212143BB67C51C45E7A9EAFD1F1ADB
+:10D4D0005DA71E2F3E21E474A50FFCFD33E2105A18
+:10D4E000FCE19CAA0F49F39FF07CCEF58D770A6092
+:10D4F000BF5F9FC613256ADC1B64EAE947C5214E5E
+:10D500003A0DF66FF3338F4E83BCE5B7784C81F458
+:10D510008676BE9903F5163EE6BD2A46FC5E1FBA26
+:10D5200013EF55991BCFE4A3A7F1C75F4DF96438FA
+:10D53000D09D303B308FDD4B62A4EF813DFF9114D5
+:10D5400019DA3DBEBBA3BF910EAF9C2AC07DAC9E35
+:10D55000E861E4DB7D749EFE2BE177532DC48FBF21
+:10D560009BEAC2FAABBE34AC6BFCEADDFB6412D8BA
+:10D57000791A9F4E49627C336EF7A349C4DE492F66
+:10D5800023DE86C533FE7FC9AAD925EE59D3E8A389
+:10D5900077E93A848CEA272D903756AAC23AFB7075
+:10D5A00011DA25443DCF625CDF66F3B74D0175DAD1
+:10D5B000D3EFFECC94CB7AF57B39C56FD50BB00E8B
+:10D5C0001609AB991E53ED780D1E239DDF23A50888
+:10D5D0007F77F019F9C008E74B1DF9F60AAE07DAB4
+:10D5E000EFE0CC18982526C69887868F9984AEC719
+:10D5F000D9BD5F8F6F8CD7DBEFE78E17FE11D0DAC6
+:10D600009DBC19E9666CD7F447110C908BA51FECF3
+:10D6100093B9F12948DFA28B1251E83A43FAE9CFD6
+:10D62000F593922B91DF56B9D8B3EEF8ADFA224FAD
+:10D630003C233BF94E6C7AD8067CB75BA8B7411CFB
+:10D64000F53AFBF43A10BDC2CF0B66E2FD1511139B
+:10D6500081D0DA94D099668833783F2478BEA120AF
+:10D66000B47F32F0E9AB420BFA596DE7097938CA59
+:10D67000EE6C0AD5D9C02E6B4A66E7F30E26105D14
+:10D68000FEF4C578A66F9A8E9E9DA6C4681FEE62B2
+:10D69000FC3C8328C939F49F45EB297F801FDCC7F8
+:10D6A00081719242CEFD5A32D82D7339F423DAF6C5
+:10D6B0008E792D99C2DB7A7B02EA99294DF7DDE953
+:10D6C000A28408FE63243E6F2FE3F0FE8422D98DEE
+:10D6D000F5A2C559E8F78DF926694609B4DF20A2FD
+:10D6E000DF3385AF14205E753A8DC3AB3CF6709185
+:10D6F0005AF83D62FF74360E71F993C03F7DA7243E
+:10D700006904FE669EACD507E1EF2E1283FFB6FAE0
+:10D71000A573FBCDB47DF52C0EF38DA7B832883FF1
+:10D720008A7F8AD64B38AF5B42A905C0D7338AF5CA
+:10D73000E71EC3AA3D39ABD44602D1FBF99C0BE5E9
+:10D74000FAA0B5FD56FC1DF1BD2281F969727EA3D8
+:10D75000CAEFB3E724E9BE9B4E98DDA9C9D54DAA0F
+:10D76000FCDDA8FACD733D19BAF14B09B387FE4031
+:10D77000DA0B8164F7B8D87EF4B4F696C3F3E125EA
+:10D78000BEDF68D087370D31F8BD7CE55AE48B34B5
+:10D79000CE8DF7C8B8F5ED378FD5D78DF26BD40F96
+:10D7A000B3208B8FEFAA27347D306B2F2F423C683C
+:10D7B000563EC533DAC57ABBBD277D3126AE1B7D0B
+:10D7C0007149BE17CC902EFAE2E3E2EFA52F7E4B13
+:10D7D000DD96B154AEDF8E57D7CDFEA43FE88D293C
+:10D7E000FC8E47818FDAE8BA698EC147DABAA3C5E1
+:10D7F000018AA81CA31E38C5F663A65C4C27FE91BF
+:10D800009D71800E3D42ED12770C7BA9353E1BE5E4
+:10D81000AB43EF687A25CA2E11F37EB85D3285DA04
+:10D82000A3522EC0D70FE12B52EF252982842B88DB
+:10D830001FA69DC1389057A0FE2CAECF4F227F81EE
+:10D84000FEE3123BE5C368AF6871E80A97664FE9EB
+:10D85000F9A5231E3993DDC3AAF14911E013E47F32
+:10D86000268FFB04FF1BD47F03B300800000000061
+:10D870001F8B08000000000000FFC57C097854558C
+:10D8800096F079F55E2D495592AA6C148BF012B67C
+:10D890008424588480EC165958A314A080CB688146
+:10D8A0000B6B129A719CEE69FFA642024343B78349
+:10D8B000D2DACEE8F457D83A831AB40801039DD0DF
+:10D8C00015504C5834082EF8D91A6D1AD10E4984C7
+:10D8D000D646BBBFCFFF9C73EF4BAA2A854DFFFFF7
+:10D8E0003FDF9FB47DB9EFDE77EFB9673FE79E97E3
+:10D8F000DB9B55B3AD08E0F6998A071400D0F177A9
+:10D9000022C042E07FC3ACAD16F08EC7BED7FC6923
+:10D91000870DF8E73BFC2F9C90FC2CA450CF0B907C
+:10D9200009B054CE5FFC577D333D5E3C277AFE52F2
+:10D9300098FDB9920C701BF8CD301CF7F3C58EFF23
+:10D94000EC4B15C7972E8B7E9EE94C4ABF9087FF04
+:10D95000180123BE5301CAD4BA9DB722BCDD275596
+:10D960008F554C33D1FE0F39C5FE0F35970C807C97
+:10D9700080DF7416A7F8B13DB611211C0DD0BAD1C5
+:10D98000C6ED71EC07F1C5EFE8E7663C9F05FC21A9
+:10D9900007B6B45221B701480518EDC4452760FF0A
+:10D9A0002A9E3F0DC78624C0EF73245CD900AFE7E1
+:10D9B00098E704F1BDC3B85E00D70DE3FA015CF748
+:10D9C000C84627F75FDBE8E6FE0D2E446A06C0FA7C
+:10D9D0001427AF372FF776871FDF5BE3CCE6E750DE
+:10D9E0003EDA44F836E02F7B6A080410DFAF77ACEC
+:10D9F000D09474802AB7E2B166F5D1014FE3588E16
+:10DA0000F3CB25BE2BB72A10C4E7E51FAE2B07C406
+:10DA10005F5733EE87F8A92A558336FC6749D363ED
+:10DA20003B45DF0CD608FADE228E0233B516CD86D2
+:10DA3000FB2CF0281E15F7F13689F76FF52A411DEA
+:10DA4000FF798B279A1E8763E8BE58AEB380FE0F1E
+:10DA5000DF5B30470986719D0593A2DF5B7C75D63D
+:10DA6000E7CAD8FE7CB498E83EB63FBFDC4E74B738
+:10DA7000E33F86C130A2FB958BA56F8D853EBAC56D
+:10DA8000B6B1748E1DBF169DEF273A675C9BCEC65C
+:10DA9000FB7F8BCE0F114E90BE70F41B8B9E04301B
+:10DAA000BBE9071AD179F6558DD7AD32CE3314863E
+:10DAB000D279FED459F86FB742DFFCAAA62F2DFE0B
+:10DAC000826B9FE76FEDBF2245E7FD695F6F7EDFE9
+:10DAD000BEF33480C178CEF939D1F88DA56B2CBD59
+:10DAE00016CAF762E9B535E61C065DA013996860B1
+:10DAF0001CBC5F55198E6BD1AD972E16FF084F7E5B
+:10DB0000FF71805FF3B9FAD693748276CD5720E027
+:10DB10003247C803F2752005E95BDE0AE14404ECF4
+:10DB2000968B733ED7A8F528F069C439E8E753838C
+:10DB3000CE6ADFFA655707B2FC19FB966910B0147C
+:10DB4000D2732197B1F055D23A23697E80F968CB20
+:10DB50002ED3B2109E63BA05EEF5519B28DA034E20
+:10DB6000A1071A9D265EB7FB2B9B096E0478E5F092
+:10DB7000806240F83C56E709D28B2133F0FB45C95F
+:10DB80003ACFDF9C048104DC1FB4769B0FF9442B51
+:10DB900006C84139D306598235B8649D16F691DC22
+:10DBA000757B34A846B9BBD178EF48E02E40926C23
+:10DBB000FE7494A9268BDE0FB74FC57937156AFA24
+:10DBC000369CE2B2EA3FA0F1AE66AB93DEEB3EF8E4
+:10DBD000CF2D665AE72BF02084F05A3332158E4F42
+:10DBE000739883A437CAD493AA09FBDD3D00A48FA0
+:10DBF000A62D0B9700D26D3AB4D738B19D42748CE4
+:10DC000043BFBFD0793384DE1A88749A21E9344344
+:10DC1000EAAB926695F54649921A84AC3EFD74B320
+:10DC2000A4D18C407B490AEE3B43533C35D8BFF925
+:10DC3000AA16C58F2F933EBAB14F1F95C9F5BD3DAA
+:10DC4000BA869601664234FF96350A3D54628B7956
+:10DC50002EED0FBEC97C55E68C1E9F42BA13F9FB10
+:10DC6000628C5E8218FB53A6FE35B903F1F08AC5BB
+:10DC7000FBDE5484BBE7B4199EC5E770113B93FBF0
+:10DC8000E3A731C61EC5B6070F277A7584EB15E2E8
+:10DC90002307F50779F5B1D79E3FB6A3A7988EF174
+:10DCA0004ADD220DB2992DCFBA33FBF0DE0FBF92C1
+:10DCB0000EB178AD977ADEDBE87C8D8EDB0F8FAD11
+:10DCC000B3D89E97FC49D748F5FDBDF834E4E595F7
+:10DCD0000B895EE2FF572E0CF2B2FD4AD2593E0C80
+:10DCE000793878FE7222E951C4A7AE219FF4B86C4E
+:10DCF0009E67999F851C84068E0A6EC3FE8524C18B
+:10DD0000F7AF24F61CCF23BCDF62F23C4BDB68EBA1
+:10DD1000872F2A20FDB975D1793380E205E5872860
+:10DD20004F8AEE84BBB10DA03C11FF055221487211
+:10DD3000628610D0BE355E789ADA19D3F414C2FB2D
+:10DD4000655CB3DD41EBE929C4F7F0D72B137D0502
+:10DD5000FDF15FBF117C1AEED3B0D1E6D3502F1C7A
+:10DD6000D8E8E47EE34637B78736EADC6E3A91FCC2
+:10DD700043F21FAABC169F16A157E6A50AFD300361
+:10DD8000F50EC13503946000796FC623C0F2887226
+:10DD900010DCA410BDF03C397DF844FA5CEE88E854
+:10DDA00043AD563B2193A582E95E9867E2F7D1091E
+:10DDB000083E9FD57F3ED23FAABF8CFC1684C3EF9E
+:10DDC000F296B9B00D397CB35D88DF7A65E9D14B45
+:10DDD000C0FDB9F4BC5EB943BD84EB8F0FCF841F87
+:10DDE000A2BD188F8421BCE2CF5D04FF84160B1006
+:10DDF0007DD0B0B27C161AF2F9B5A25CC0FD4884A1
+:10DE0000BE1B8CEF59CBC3C44F07A0238DF05E64BB
+:10DE1000F3D9497E97B9043F7895DBDD0AAE3739EF
+:10DE2000C3E25109B4E1BEF1EB117F2D19B821CE47
+:10DE30006F69C91CA2E713B7BDF13EC9B7D7E608A1
+:10DE4000AB6C98CC9D1D11F67C003CE3247F927452
+:10DE5000DC7768475A3F4E0EB09EBB6A09925E6BF4
+:10DE60003D93EC09E33ED3AFDAD8BFACA717516EB0
+:10DE70000F27268F653D13420D43F26313E7986D1C
+:10DE8000F6AF233CA0653E7A0ADFFBED6500D2AF1A
+:10DE9000D3DB3F54C90F2D31E50EE840388F2AA35C
+:10DEA00053A87DF2E3E47C6ECF2477127E0E9BECC8
+:10DEB0003AEDFBCE46BD7404F2CBA98D503A02F97F
+:10DEC000E3AD8D366E4F6F74727B66A39BDBA33818
+:10DED0004EFCF33A8E137FBD81E3D46FC3716A4F5A
+:10DEE000E03AD47ADF7298487E67BCE5D0A82DBCB2
+:10DEF0002B89DBFA3B932C748EC3C95067EC4FFC23
+:10DF0000144E0C378007E52ED5FD53DB0D683FAD71
+:10DF1000FE02651CC0D454F75C6D3AAE3B7BE88FC3
+:10DF2000BEC2F119A9C37E6A43786F3BE3683889A2
+:10DF3000FDD2C7F59F3A883F4F24A292243C64B794
+:10DF4000795136C793D218C468F7C224ECA719FDDB
+:10DF5000ECB9A5C80A4B4A3AF2C005B0F3B1E17377
+:10DF60006D88DF2576FF3F51DF12689B533A9DFA9B
+:10DF7000107092BC2BE620CBFB10257D11DABFADD3
+:10DF80000EFFC4D4087FC0ABFC218DF4C344AF02A4
+:10DF9000AE74A67770A4D2F7DC98B7D55136311598
+:10DFA000F9F7D72E95F969C234C51B74F4975F63EE
+:10DFB000DE84F37A29D16FE2C559B5D42E98E3E215
+:10DFC000BE6FD94DB524FFA58E6BBD5FC2EF875CD8
+:10DFD00066D647C51ACE8B63178D79E391C9C8FF02
+:10DFE000EE694B0C3E4B7C7DD65F9384FD327756B9
+:10DFF000A12A753470DFB56B1B8D97BFDEC072E54B
+:10E0000049F2E859C48AEDA569383ED3A178C22403
+:10E010002AD33EA94DA371A7E221B4CDF48E3B557E
+:10E0200044E32354CF4CEA9FD54B9DD89ED1664EF6
+:10E03000BD84F366E7A4786CF8DE99F08FAE10FF2C
+:10E04000CECC49F224E81417049FAEA4BEC7EAA9B7
+:10E05000D6E91C8F9524D33ABAE23161BFFED6923D
+:10E06000FF457014FB52405168DCA5911FFBE4C7CB
+:10E070003F2975E2BCFAA10A90FC9C09E7FE91E0F9
+:10E080009FD99AA8272040F5166729BD576F519C44
+:10E090009BB8EF2BA1F9815166FD795CF7E49D7681
+:10E0A000B607E56FE5B35F74F2CEC16C17CADF9AAD
+:10E0B000564CED4993F0DBCBDF2A9FC3E326089350
+:10E0C0005229BFEB1FF8BD1D253F294DC7F54F0C49
+:10E0D00073B16E413A956A117A0DE78342EFDF55CD
+:10E0E000C1F35B94013F3A8FF3AFE4A7145A71FF79
+:10E0F00059E90951F3E70C7145F5E78D1858AA4520
+:10E10000D8B1F2FCACA8FEAD454AE98888F9BE69F1
+:10E110000951FD45A5AED21111F36F2B1F18D55F24
+:10E12000725B56547FA669B2D01F1BA1BC54C87D38
+:10E130007929FB9BD9AC870A9D62EE1B387E3F8E06
+:10E1400017B6097FAAD085FE14D2A5B4AD88FD808C
+:10E15000367C8FC68BEC528F05A0DD3D91EC80FCA8
+:10E1600009E22FF68B6577663BFA056389AE68B7DF
+:10E1700023E02F7544DBF1FA44E127CC017FAD0B9E
+:10E18000E939A7751EFB5765E9D54561207C46BF77
+:10E190001F0B372AD19D77131FB66AAC37E70C895E
+:10E1A000D9AFADD4C17E8CF4EFE6C8B78C7D21E049
+:10E1B0006D27FFC63887B1FFB5CE33479DC67EE1D8
+:10E1C000DF3AD7AC9C85A5A971E15FCFFE4C2C9CB2
+:10E1D00079A9324F81FE15FB85ADA9EC2FE24F7A6C
+:10E1E0003C3FC1F07FCA51CFB922F59C43495F58EB
+:10E1F000706D3D67AC7B2DFFCF58D7781FEA54DE9A
+:10E20000DF78BFF7B9AEC47FBE1BE727C5799EAEE6
+:10E21000C47FFE5CF4FC199A5EE340793E0E8A27C7
+:10E2200040783FA96BE49A959CF5D6525BF6A15FC6
+:10E2300023B770F6F9402DB5533B8327AD78FEB96F
+:10E2400039AA4EF907C32FEA1767A50A7FE4F855E4
+:10E25000DDAEE3787D40B753DC51FF886EA7F8AAA6
+:10E26000DE0B73288EF40E37ADA738C49B872DF6CE
+:10E27000EF4D15FA7E857CDF680FA9FE15047F85BA
+:10E28000ADE351F2492ABFE9B1105F1C277F2FBFD0
+:10E29000BFBF775C0B3A68BFE38F041DBE087D7E6D
+:10E2A000BDFEDE2262A60CE253C517A94F4A6C09D7
+:10E2B000BE48FD51E67445F5C793FF83EFCD760F59
+:10E2C0008C7A6FAE9E15350FFDD81CF2876A2C90A4
+:10E2D000A3913E35257AC8CF8BC5E3EFE5F93D0E16
+:10E2E00027B951604ED7557F1CFBE42911F88B7D6F
+:10E2F000BE3D55C47383C89EE33A2752756E6B5575
+:10E300009F70E6D07F267E88ED63ACBA8CD6C3952D
+:10E31000DDC4771EBBE90ABAE0F0D2E3F3E76A682E
+:10E32000FF3DE34DFF381CFBC71E5F21FA534DFB39
+:10E33000B2B1DFFAF87DA27FA369BCD983EC19B82A
+:10E340007F6E29F90BE9BE7F27FA759B1D5B15D4FB
+:10E35000039509A8D7B0D54C0A14A6F7C5C7DB2D7D
+:10E36000685F91C0C86C5E17D2C06E15F17465C24B
+:10E37000D020D913ADD8AB13DE2A130C7A77649270
+:10E380009D87DA0951719DDD82EFE1FB6536FF0B58
+:10E39000826FC2C93AEAA5870E960D20FE3891EA2F
+:10E3A000643CE4ED9BEA267D85F0ED21FBFEFF0158
+:10E3B000BEE678F0D59AC53E9DF57925648FF38643
+:10E3C0002179943EFA156A3A3F4F0821EFB0BFEE2B
+:10E3D0007553FEB1C665F190FF7E42F2EFF5B6359A
+:10E3E000328FA1DA051FA929A6F57BB17D5BF2CF9B
+:10E3F00019B92F6ABEA10B913FC0D933745181E87E
+:10E40000137FA86A610FF9E13DFF90E4A1F8F98359
+:10E4100044813F18D2F3D18FF1F97B77E779B6F1D8
+:10E420007381A765C1EC9A0EEC8FB3066FA0FCE375
+:10E43000A134FF4784873BADC191CC878EF549B4A9
+:10E440008FE2058E538CF80FE33CDD32BC7F5C70AD
+:10E45000EDFDC1467665E9648177637FC4B18DE8DF
+:10E46000F1DE24F1DC8007E1E8263E30E0EA8507B2
+:10E470008638398F0022FFD425E38B2E5A8FECA7E4
+:10E48000EA1079DC3F9838FF5245C28AFD7DE74D9E
+:10E490001C0F1A79E02210FB4D3EB54965E003F8E8
+:10E4A0003B51A2965E695CCBF1FD84762D26FEF68B
+:10E4B000B23D9D2ADFBFA9D55FE2A0F6FDE8795302
+:10E4C000651C3F09822AC559933B62C61BE77F46FC
+:10E4D000EB4FBD18FD3C294DDAC3413028324FB215
+:10E4E00041C64D974F66A7101F6B182BA8480F8B7E
+:10E4F000AEC2A4D43E3DD3B011E759499FDAB82D3E
+:10E5000038EBBC8FF669DC880C3F9AF4AA9B5B431E
+:10E51000EE0ACEC2BD3036621F2917061E2FBF2F4E
+:10E52000F038AE23E797D3B06F6E354350EFC3C3D7
+:10E5300014892F0CDF38FEBB7CD1C1F66B62DB6225
+:10E5400095E4D9EA36811E71BE043D11F4087D6C54
+:10E55000CF498DEAAB929EB509D17ECA78B94F9268
+:10E560006750D47A86BF62D0F350EAAC56F263C6E5
+:10E570003B56B1DF9232293B6AFDA293D1F82E04BB
+:10E580009F97E263CF87C071C0C4B35A947F32298A
+:10E59000BC83F963D287D1CFA79C8FEE97A6C9FC25
+:10E5A000562CDDAE854F18FBCB69E97F3F3E5DDE23
+:10E5B000687CA6CD89C667862F1A9F039645E36BB4
+:10E5C000A03F1A1F83578D891ABF617D61547FD880
+:10E5D0000FA744CDCF428319D91FBE755ED4FC91DD
+:10E5E0003B1645F5473F7567D4FCDCE08AA8F1BCD3
+:10E5F000DD6BFE2EFA17843644CD27349BBE87FE92
+:10E600003736FE4BD47EFF53F4AF8DA1FF56D2E7D1
+:10E6100013885EA8370BFBEC19B925A43F5D4D6F3D
+:10E620007C43799B40B1CEF9AAC03CF0D4E0D82F0E
+:10E63000549F427A6E30A2DA847AA3D604ABC81E05
+:10E640003C6A32711ED390F317D3843FF2629AC8AA
+:10E650007B19787B1AED22D94155EA4373FA8E244F
+:10E66000F253549309DAC9FE691ED61FE71C10BE87
+:10E6700019F7550701E7C54A92272D9888FCA8BECF
+:10E68000A972FCA90EF2838EF6A4E6E4CE53849F11
+:10E690002B0E9B4E7CABA6FA0364DFF09CA1E7A196
+:10E6A000BF9FF3DE465849F196D15FE65EBF99E61B
+:10E6B0002FBB7BE6488A7F7B9FDFADAC2C8DA043D0
+:10E6C000E43917C5F1AB0EA409FB67D813C37EDC90
+:10E6D00069D56B3AD03E8C53857D40BB71200DF1DE
+:10E6E000F181F28859F86901339D1FED2ADF27B8BF
+:10E6F000D021DF806D4A9FDDD2BF43E6FA203BDAAE
+:10E700006F7D9300A33844F7F03DE31D86FE5D95D1
+:10E71000CBF8BBEC889E7FF9FEE102AFF720F690C4
+:10E720000EE72CE23C06FC17A55EFE42EAE54ED25F
+:10E73000C711F9EB55BB7626917F7E2E47F8E3C6CD
+:10E74000F3DF493AFF2E4DE5F3AFDD9DB0FE7C04CB
+:10E75000DE2A42AEA87E55E3C0F591F9CDB5C639A3
+:10E76000FC8A46E75827E5A8A2B523F94E607FFE4C
+:10E77000C3345CB772D7957B0ED0FBA69E4C616705
+:10E7800003BCDFD2F780E382A57F8128BFB633CDFB
+:10E79000CC7075A689386109364EE4BB25E803B80C
+:10E7A000A87D63DA2CE23F7C1E56B0BFA015CCA436
+:10E7B000BF16FAB3CC84F433E079673F1EEDCF691E
+:10E7C0003AEF731BF8F87EFBDD7B2A92D80F34D624
+:10E7D00033D64181203FEF3D57C09C49799FE90ADC
+:10E7E000FB17B89F8D9EFBEE1EBC99ECB0B1DFBB52
+:10E7F000E0BFF40EF2C522F0F0BAC6FA40D73411E9
+:10E800007AF9034B2F1DED44BF0D6DA630E585361B
+:10E810009CB3F2BD4A7775CFCB0F239C1FAFF9662F
+:10E82000BF82707FB4BCE7BF0EE0F33B9E5241470E
+:10E83000BEF1D9FD5A7A44BC79EEFE2B2C6FE8AFBD
+:10E840003CFF2429A597AC1E92930FD6BC342A32E4
+:10E850005E484E9F99904EF73B93D2E2DE6FC4C65E
+:10E86000A56B883F597E75F64B0DBE5C2DF972C3C2
+:10E870000BA3F9F986A4DEF388FEF32AE7C1363448
+:10E880005B39AFF18EE487352F7E333132CF578F2E
+:10E890007CA95BA975724BF7A63AFA09FB4E5E1E7E
+:10E8A000CB71ABEACFA2731EBEFA6932F5F7BDF9A0
+:10E8B0002D9F076EBB3EF8BB11799178AE4AEA797D
+:10E8C00097F44AC501AB4EF9AC9203B927EEC27E6C
+:10E8D000652BEA1F3CCF2557C7B1A7291E3BA800CF
+:10E8E000E5B72AC309ACE42B1B9420E5C3D634EE6C
+:10E8F000DD3218FB6BEA161611BB56250B7D5659F7
+:10E90000AF0437B11F3E87E95C2865A3E450EEBF32
+:10E91000E5E378D771B1FE858DB0F63CC69D5DF517
+:10E920005F5E2038D6355A39CF7621296C198CFB99
+:10E930005EDAAB84027A9FDC76B9441CB62AF4987E
+:10E9400085F65DF5DCC211E436761D386D213DB9E2
+:10E95000AAE1B159F2799130FF41968BB5BB9595FB
+:10E960009179ACD5E80E42A4FD42F80213FBEA40CF
+:10E970004E49FA2C6B1A5E43E842BDB6FF6985F535
+:10E98000DA42E2970F0EEFF9DD6F68DF83FF3D9209
+:10E99000F15F747DF8075F80FD8B4AB90F5C3C63C3
+:10E9A000A1F8B2B2C17C21DEFD5263BAEF1EDACF0C
+:10E9B000888F63FDEE2D1610F73FD9107C9EEC82F8
+:10E9C000A3C7B21CE1F9579A80F068CE1ECB0AECBF
+:10E9D000DB48CEC85EB81DC17871F5BE748DF18478
+:10E9E000B1C4FA78F7A021395EA27758289F57E979
+:10E9F000EEB4105F57863F17F7FF8D9FCCF2C689A4
+:10EA0000B75F4E57A4333F274ADE37648C61B93075
+:10EA1000F7DAC3908DE5BE60450FD9A90D07913B8C
+:10EA200014A2B7BF87E00EEC4FD0E97C25073E9FCC
+:10EA3000D811B1CF1FA57CF4E6595EF964AC99F00A
+:10EA4000B9EF93B15A52DFF3AE4CC7AA78799997D0
+:10EA5000D385DDDE9CECBB182D07099E30EE5BD91B
+:10EA600064E77B1494832D2D45917270C7AA5DC411
+:10EA7000E74DAA0725022A1B17FAAB797E9287C8B1
+:10EA8000A336CE0C101FAA4E1FF327FC15F79B28A8
+:10EA9000EF8F50FFCD4DF73F4D72AC396065641E6E
+:10EAA000A4D2D4F1AB1685E8BAC36BA2FD0A81F5F6
+:10EAB00096EAF075703C5594A953DC7B74C22C2007
+:10EAC0003CFDBC59E1BCAF39D5BF358BE87B5CE57B
+:10EAD000F996A32F04E8BEBB6B1C14117CC6797F8A
+:10EAE0003E2E0C2AAEB3B9003CB4EDE6834BDDC438
+:10EAF000BF3FCF38C67E86DD1302D22B35E83F50AC
+:10EB0000DEC79E1F0AD33A0939BE2215F75993EE84
+:10EB100064BEB458FD1ECA273D20FB36CDB78AE03F
+:10EB2000B3A5278AF87BC8F5E5F9BA48FECD746F1E
+:10EB3000E9E77C4B9759F069D70DC07122D7FC4C9F
+:10EB4000A6212FE3CD063BB8AD6A54D646DAD744AA
+:10EB5000F0DBE879D7C1A51E82DF9C2DF93D33910A
+:10EB6000E52276FF8F889FA9CEC0B4626B16E1992B
+:10EB7000F0A6F79FF7A1E47B031FA0F973485E118D
+:10EB8000546FBCFC923FBDF82CD17573AA2FC7956A
+:10EB9000CFD7BCC2297627C6953B9CFF01C9B731A8
+:10EBA000BF95F089EF6FD1FC36C2EF51895FB3C5D5
+:10EBB000A73B59FE7D3AEDDF7BBE41F1CFF78D3C9F
+:10EBC000DF966CFFF79EEFCFF27CE654E4375A2FC6
+:10EBD00019789E39391820FEAB4D82A24DF8F8A85D
+:10EBE0006B969BE46ECB916F8692BCD72679DC4006
+:10EBF00079B1E69B9691DC6F197427F3FF172FE428
+:10EC000016AA11FB24A7177F45E73B2FCFB1C5E21A
+:10EC1000CFA1737C2CCF699C6B49BAEF2FE911F916
+:10EC20002618927E5DFCB3D7B8D794719E47DA61FF
+:10EC30008CF3388FD80D895C7FB657FAE11AF898B3
+:10EC40007FECE0D1D9BFF2C209AA2BA96931C13644
+:10EC50003A3E25B522EEFD925593110C7A6D18B20D
+:10EC6000D335348D3B9FD839AF16E13E080155F8B6
+:10EC700069D1F90CF02A5E25328FF1DA9AEBCB6379
+:10EC80003CE3AF21798DCD634C0E9B965B52AE2356
+:10EC90009FF1DABCB8F98CD119D171514186CEC03F
+:10ECA0008572047F86C28941913783F194BFEA2639
+:10ECB0005B85E39FE39959DE95AE1C9B0BEDE0135A
+:10ECC0004F6CDB3A0DE57084C003F56B88C9F5F134
+:10ECD000EC07F5E6475E1BC37E38EA3D95F3024E2E
+:10ECE000094B0C1D8BD07F1341A5272ABF123EF67E
+:10ECF0006D32F1DB9E54FD2DA24F4F9BCA75280942
+:10ED00005A87C51547EE0E907F8076E09F33843E8C
+:10ED1000B7358A7B4B9BEE653D99E0748E5323E4B7
+:10ED2000242F43D8A58A631F0CB5A02C5D329D4CBF
+:10ED3000CEC7F5D7EDAF4FA634DEDA736F4FA4D24E
+:10ED40009F3B35FF820C3CFF17CAAE5136F25BB7D2
+:10ED500006C7127E42E16CAECF2CD020A015F687FC
+:10ED6000A7EA293C14BA04954FA5715BD0347E25DF
+:10ED7000F15F55589C97F630A38ACC6D54B8DFD517
+:10ED800058934AEB55FDB67910E9AF9732849FF35B
+:10ED9000E2D53CF1BE061ACDBF3FC325992A68A231
+:10EDA0007CE34B324FD97555E579C6FE058D335559
+:10EDB00027F2417E78C711CE8B365975A26FC27388
+:10EDC00020F0D194C07E68D5E1D94076AFDB051E36
+:10EDD00005C7F724F67C44FCD0D36CD5E93E37C197
+:10EDE000B9035271FD3DB21E2C1719B6DED1F7DC06
+:10EDF000D82FA1E997944324BEE07BE5046D074C2E
+:10EE00007744E23B49D859C9577B12C326BA67E910
+:10EE100041DFEF5986AB0F4EE07D0D3873D90EEC14
+:10EE2000B1F45CF8713AC3E5243EC8050127348D7E
+:10EE3000D649AF2638BD7C8E04A7EE0928FDE1AA8D
+:10EE40001A8B8E20CACFA3A4CCA6F4C97755625FD3
+:10EE5000DF86B2B0271BA4FCB76E2B9D16D9478561
+:10EE600033A9EFFDFF78E2F8B6DA219CFF0BA84842
+:10EE70007F3BB649A9744E21572812DE8C42810788
+:10EE8000AA0BB4DBC478EF7CE473472ADB7F9EE7F0
+:10EE9000B13AEDF3B2585EF87ED1F00F1F52C217AF
+:10EEA0006E46D2763EE64BC9C773759A8E3C5C8738
+:10EEB000F3FEB83C342A8CFD16ABFF79E2CF573F06
+:10EEC0005CB1BD80F4EF1EB3A79CF44F47E071F630
+:10EED000CB5F34EBDB22E40E86F46472DD61CC3E62
+:10EEE00055E7363D4EFE76F74145A7FBF46E73CFEE
+:10EEF0005082BBB2E9330BD563561DFC84FDEBB2E7
+:10EF00004CFF5EDA6F526335D7CF4D861D5C3F876D
+:10EF10007A91EB20436EA14F2E9F1DF56C75041D59
+:10EF2000DE93F2063DFE6164BF9AA4BC1EA6381CA7
+:10EF3000DBFD2D770CA7F5F7CBFC80F15E351C19B6
+:10EF40004C78DF04AF716B3CEF0E6A5CBF9CF7AE90
+:10EF5000ED5E6FC4FCD352FE4FCBFD5667FADF2047
+:10EF600078D7B67C6AA1D2C2AAF3A1A114F78634DD
+:10EF70003DC519478FF4CA6F8C3C55693D169A5FA1
+:10EF8000751158AF20BD6B53907E2FBDDB386639AD
+:10EF90003EDF8F3449213B8BF12AD9E3FD66DF60E8
+:10EFA0009A5FFDCED763498F1D2420F07F5F37AF76
+:10EFB0001D467843FE2F4E2439DB0BACD70C39CDE0
+:10EFC0002739C5F7F389FF8BA89FCB7A798FA57D69
+:10EFD0001ECBE57E13905C22FFB33C20FF3BC9DFD4
+:10EFE000CB77A23CF0FBA359CEF7B49BBCEC37A384
+:10EFF0005E1FC9FDE2C5D4DFD35EEA6439A73A8457
+:10F000004292D7F0115E270440D7F2450AF822FD5C
+:10F01000FFBC8C64712F24F1393943D883508E9E04
+:10F02000E2C173D855354A3E22ECA5E84B7B5A9A8B
+:10F03000F9976DBF98465226ED8453DA49FF78D68A
+:10F04000FBFF286DD586D7A72CA8C3736E38A5F211
+:10F05000F86119F785259F1C91F91AB21B7A9AA8B5
+:10F060001FA6E713B04FF5E513BDEB4BC81C4D9A37
+:10F07000B3E328B5537CA11272DBA62D6B3F6A1651
+:10F08000629E47FCD770646E1ED5E3759FB3420243
+:10F0900082D8F06DCF472F221E1E3E8CF88F63A7BB
+:10F0A000F038CC7FE87F0D0677FFF16E45EA91409E
+:10F0B000D27CE2C7AE06B5AF8F8054226353DFFD2A
+:10F0C000A47D7B006DE77F677A0767223ECF0CF057
+:10F0D00073DB7DFADB4C12CBFD67455CDF60F1E64C
+:10F0E00011FF346463A81B874FAD9922EF536485E9
+:10F0F000B8F79C37670A39181580ED0AC7EBAA33B1
+:10F100008874BFD4A07A2DE82F5D84C092A9A46F23
+:10F11000645EF701903F5EFC45FA3C28BB0F90DF30
+:10F120008276EBC15FC4D61178D96F31F25800EB0B
+:10F130004DC45F2B9B14F80FC4C5AA67A2E7AF9319
+:10F1400075F2AB1B771D1B8C745DF35CCC38F92D0D
+:10F150007CFF11E278785D5D743DC3CD99D27F1953
+:10F160000EC3C97F41BE623D61D6A0D58A7CAC602A
+:10F17000144322F69249E00BF52BCB67BE616F8AF0
+:10F18000855EEAB9045CA794BB3B7494EA81A6D47B
+:10F190006579688F299A189FD29825EEA7B4A04A5E
+:10F1A000750C93BCFE59EC7707BC67A9DE6495D457
+:10F1B00097E0C45FCAFBC8D3AF92FEDDEA606C9DE6
+:10F1C000A8C053959C37198235B4EFCADDA2DE6919
+:10F1D000EDEEE8F955124FEB9E3A7D8CD28515A1E4
+:10F1E000987189A7AAC6983A16B138DC9F29EFAD65
+:10F1F000647DFBF5D65BFCD12CFC8DB7E53AC6F8F7
+:10F20000E64C91EFADC463107DD705D520F1D12A2E
+:10F2100025902CFC5E702CC7F3DD67B081ACCFBDB0
+:10F220005FE2E93EC93F7C7E7CBFE219F17DC5FD0E
+:10F230003F8B867F0DF82C83F1F9830D3FB050DEB4
+:10F240003196DF56D599D9FF5D23F113CB5F6B7AE9
+:10F25000F9678785EC5B2C7F55FA956BC02FFCF620
+:10F26000FF5BF80D3AAF91CBAC3587393FB5F60966
+:10F27000C543F9AB6B9DABF73CF27C7FEFB99E3594
+:10F28000E83D06C630BDE7A45D17BD63FDEDBD9644
+:10F29000DEBC26E7052FB766733EDDE0ABD87566AA
+:10F2A00049BF7DF653C27FBDD4586227FFA3FBA49C
+:10F2B000C9A3E89CAF4C2EC0F38F6F5681FC91EE32
+:10F2C000A6E13B03087FE1A9A2C5945F1F7F0AED79
+:10F2D00013DD07B716FD5702DF077BD248EE67B68E
+:10F2E0008D48FBBD83D761FBDE7DB2706739E9E9EC
+:10F2F00093A545B4AE82E3549F5E28ED54F5C94210
+:10F300007B4784BDFA4DA6C8CF6F71FFFE518A1BA3
+:10F3100066EF357B283F32DBECDF9480F015BEA032
+:10F3200078AA71B763ED479EA47551BE28CD8AF3C4
+:10F33000FEE9088D57ED5118FEEEA6B2BC3D643FC4
+:10F3400083AA87EC6277D37DF90F921FD4FC40FE2D
+:10F350007D11FB1D4B15FA66F60D66B6D79D83EC45
+:10F36000BF2EA7BCA87717EB8DCE43FB2CFC7DC32B
+:10F370001E05DC78CE63EEA32F131E3A0F9CB65009
+:10F380001050D270DAD211477F1BED250CF3C29CCE
+:10F39000AFDD61E1FACDFD7FB0D0792B9FFB84F327
+:10F3A0006F6B287E203FEF1995BF773ADAFCAA856C
+:10F3B000F8B4B24E81015991E3661E27FD4AFDCF94
+:10F3C000EA849E36F87F85E47783FF0D795821F52E
+:10F3D000DA7D5BE3F3BBA1FF1E04EF9641B8DE03C9
+:10F3E00075CBB90EE9811DD1F35752FC7A23CD17A5
+:10F3F000FCBEF2A9E8F1D5BD7C1E60FD1FAB47BF86
+:10F4000033F47F2EE4129F5F0EAF18A6A13C7D7DE2
+:10F410007ACD308893AF3C29FD06C36E5F0E9BD832
+:10F42000EEC5CEEB6ABC62217B5BD5FA27F673672B
+:10F43000357DC9F4286F6AE17AD95BC0BF8EF07957
+:10F440004B93DD49FE767987D003F39AACC1A04295
+:10F45000E3A15AA273F761F1BD49E090C2FE1648DC
+:10F46000BDB852E275A5C4E34A8CE306537D8C8C8B
+:10F47000E32B65BCBE3A67D7312A29A994E3EBDABE
+:10F480008E26131EE781D05BF342426F19F431ECF4
+:10F4900050ACBE400B770FD1776D9395EBD6E74B11
+:10F4A000BD35BF0EF596D25F7F740FB48BFCF17E35
+:10F4B0000177ACDDAD6C889EEF1A20FCD8CBD27FF3
+:10F4C0002E1C104D97F21EB0537E7F9EAE7A82FCAA
+:10F4D00056BB46FBB78E457EC3F55BF5E129F1EAE5
+:10F4E000B58CF64D191718FD059467C3F921E70E81
+:10F4F0004764DCFF9F03847FB366B21A20BA46C418
+:10F50000490B0AB3E2C6497309F43786DCF7B371D5
+:10F5100091719277D728E2B77F75EF2CA7BAA6AA88
+:10F520003AA12FBA26E1BA29E4F703FBD15575D6E3
+:10F5300020C53355C82FFC7D1AF109C96393524683
+:10F540007C8271C6EDB4FE42BAEAC4F32F6C44FB70
+:10F550008ECB2F2CFD92F9AB6D843837E26D40BC19
+:10F56000B8C388372AAF0ABFD6785EA97570DC5158
+:10F57000D924EAB51B8E7C33340BE1ED6EFEF3D05B
+:10F58000E5544F3E40D8E786E2D0A75457F4F51E25
+:10F590005B5CFFB557FF2BB52C0F95E68E4CF66BD9
+:10F5A0000EA21F7913EAD1B7BFE038A5E148C2BD6A
+:10F5B00094CFEB5AE11FE6FC1E3A55C326F683377B
+:10F5C000412DB7E41F45FA8D2B9DA24EE941693FBD
+:10F5D000A9FF08F2F583387746617FF937F449854A
+:10F5E000E4EBD510D83255E9AF072AA4DCACCDDF67
+:10F5F000B585AEF663FDA70A294F1831B0BD8CF56D
+:10F600009FFE33865FABDF4E64FFB8BB4D7552AED5
+:10F6100019F1FBAB41E427625C901D275FFB85E499
+:10F62000CF4E797F5C3D4965FC99268BD6F0B710AB
+:10F630008FCC37DDA71D41B26F79875FCD263E584D
+:10F64000BB3BFADE89E8E8E7BAB1A0C84785EC7CA5
+:10F6500017658CBF74F8D531C46FD56F7F3B4AD026
+:10F66000E79B5196F46BC367B48A22E2669322E269
+:10F67000E6FD5A4732C56B5507555F643DBF41EF04
+:10F6800097A53C8126F203F50374E6ABEA26C11F79
+:10F69000A666D1E2FE4B447EC8CCFBF71B2F46BECC
+:10F6A000F91E7B060417F24095B987F9AFEAB489D1
+:10F6B000E1A93A7D397344C47B015A7700E9BFEA76
+:10F6C00075C0FAC40EA46FE7D3F791D89FFF7E02EE
+:10F6D000FB61C7B2B7978BFB2F15487F3DFCF69AAD
+:10F6E000D191F660E200712F0E840737793FBF1089
+:10F6F000FB4B3C6C824532BF20F879AF8C9B302E9F
+:10F700007B73409CB8EC7AFDE9EA662B50FEB9EABF
+:10F71000032BD7197DDDBC92E37EB8EA1F4DFA06B4
+:10F72000FCFE1BA97DF8F0CAD1F4FCEBC3AB6FE47F
+:10F730007CA9B2292ACF1120F8DCE45F7DF5EE5DCB
+:10F74000E47FB669EC9F14B69D7D97EE69F7359816
+:10F75000F9DBD18AFD13760692C8AF2A9C4FDF11E0
+:10F76000ED6BD598FFD0DF32FC2B3BFB57A78AD837
+:10F77000BFC2757C416E8B4E94D3BAA78A8B689AB0
+:10F7800082E3A4D7C6937FE5E8F3B70C783E93F8FD
+:10F79000EC6E49E0BC8B02D982CF604414DCEB1ADA
+:10F7A0005E67FF645DA31AF5FD88F1DE5F06887B66
+:10F7B00087EF0C3E0B295EE6A3BDA25DD7B82F9361
+:10F7C000CEB1D61C623EA9AE338BF13DA205BA077D
+:10F7D0009AC01F4107083F27E811D2659E2538844B
+:10F7E000FCFABDBDF78AB22E2428EAF56A5A87F3DF
+:10F7F000774C975BF7A5C7B34327E99E071DBEE388
+:10F8000059221E8A1DFFAD5BE4418E9F13FAF1F869
+:10F810004CFFE8787A3200C5225FA048FA3588EFBD
+:10F82000ED63E735D37A78FEDD4302C7898F3BF776
+:10F8300026F0FD63A74BE4754BEADB34FA1E666DD8
+:10F84000833281ECD2DA9CF7F87B19EC17919E5C3D
+:10F850001B3EC8F7AF15757B6779E3C0B1DD2DECB2
+:10F86000C33CF99D72ECF87C397E063C19329EDB74
+:10F870004EF73E67CACD4EF1DD9BF8EEF556A9D79F
+:10F8800017DF62663FEA0CE866717F22EE391648A0
+:10F89000BD7DABD4F7B1DF631BFAFD76B9CEC2678D
+:10F8A0006033DD73C47E9F7DBBF40F178197D7EF64
+:10F8B000F75DBDF41363FFFE42895BEAF551308AC0
+:10F8C000F47A08ED0DD75BE426B0DD9E5F3032AEF2
+:10F8D000DF41DFA9EBF23B756A0DFA57E7BEC7F6C9
+:10F8E000F078CBB997F9FB867309901DE79EADCFF1
+:10F8F0001E1A7AE436417779EF51E114301AF4BFD9
+:10F9000084115A647ECDA0FF83920EFFC7754539DE
+:10F91000A045E6630EA9FE07DD195447DDC9FE3890
+:10F920009E80ED219E6BA83CD7506B849DBB3470AC
+:10F93000795C3EEE3B5F6A40D893746E5B72ADECCF
+:10F9400037568414FEEEB0220CA27F9BC2F9CA5136
+:10F950000D2D5CBFB1A454F178855A3C4BF0197C55
+:10F96000B4C026FC03835F7AF125F988C6C95FB865
+:10F9700055FA0BB1FC341ADA67D1FA4BBD8A87EA23
+:10F9800036AFC947CBC6BD4EE1EEB5F808F9D24C4B
+:10F990007A31969F5E73FB1F25FC75B75F5E5280C0
+:10F9A000EB1FCFFD6C28F14FE535E4E84549BFDD9D
+:10F9B0008EC071AE63A9977504F5B98D1D849756F5
+:10F9C00060BFB2D3D5BE6583F0B7B98EA0229CC00C
+:10F9D000F5A5154D76FE6EADA2A13A710CE9E326B0
+:10F9E000D563C77E79C3E952CA239417893A972A07
+:10F9F000BBA8BBABB28BBABBB9E9FEE7DC13F8EF2F
+:10FA00000344D711583A7EB5E17BF83E56DF359373
+:10FA10000F37E17F4E0F354BFC6C68BB923986C4C3
+:10FA200034DD7F88E0EE7EFD450B7D8A5135E6D5DD
+:10FA3000595482D6ECD679DE2D752DB5945636E024
+:10FA4000B7BB9D42EF9A8343D86FCDBFBE7A9BEA86
+:10FA5000836F8C25FBD5D5D236D612C1EF9D1B50B6
+:10FA60006FC7A1633598A41C6BDC2ACA22E9470939
+:10FA7000B9AE6A3E9A49F98B4E92E77C6ADF491E1D
+:10FA8000816DC5DE33C923C99FD92F5A63BD4B4D44
+:10FA90002ACF03AD63D4ED4991F06D66F82E85C48D
+:10FAA0003A001DA31617448ED7FCBFD60717853E14
+:10FAB000E888D207069E4216E0EF880387AD5CA770
+:10FAC00040F73FAE083A6A0305FD6EC2608AE476ED
+:10FAD00032DD7B0F27974F83BBA9AF41584BA5FB66
+:10FAE000E9B02AEAFB86B0BE9F28F7BF490BB750A2
+:10FAF0003DF064795F3A05DA79DE0CE8E1D60B4E29
+:10FB0000FE0EBA183CDC4EB285E7535A2B3F14E286
+:10FB1000EF7BC2999AEB824D7E6F1D87DE7D78D395
+:10FB2000E082810F95EED5443D53EC796E1828FCA8
+:10FB3000BC9BBC420F914B41F5C09320C4F7F9D355
+:10FB4000A143DEEBC73FC7548C0BE91E6F3ABA31B5
+:10FB5000898C8F20CF9F46E751E39DA7633E931981
+:10FB60004A9D049F12CE347D67BFFE7374533528BF
+:10FB7000E5BDEFEBE9FA7151DF3DA8A7E98DF7A9E3
+:10FB80007E59F17AB9BED943DF8D53FC13D63A7B47
+:10FB9000F55936C098812B72064EE8FB6E04FCC006
+:10FBA0007524B1DF8D447C27021723FE2E9251E786
+:10FBB000BB3BB848A73A9165E936FE7B3B85B6A1C9
+:10FBC000E329AF7928CD9F333083EA7DEB46F2629B
+:10FBD0005A7002FBB992BFECE09D447850BCC6F766
+:10FBE0002BC07CD3FBF70B3281BF27B25BC5773EBE
+:10FBF000DB911F6DA92C053AD55FC323253AF9D3B4
+:10FC00005B5C360F7D476C25B8ED7D70D7D8441D01
+:10FC1000488D4DD47918F572B178ADB119794E8F00
+:10FC20008DFDF198EF907E62F3DF42787A28A998F3
+:10FC3000FF0E53DE2BD3DC5C0F25BF7FAA4930F0CB
+:10FC4000506CE3E77DF594EC67D6523D37C259938B
+:10FC5000015CFF783469540AD565D5B4897AEE9A87
+:10FC60008C00EB77B35F617D5FD35AD24AF6E2B284
+:10FC7000C3C275DD352E51071FC880D0F37A343DDD
+:10FC8000A619F4A0FB4B598F64D0655C3A94D07BE5
+:10FC9000E3C2DE91849342DBCB37D0FDC2B87074EF
+:10FCA0007D19D26935D1A9F73B1ECDC9F51E067D58
+:10FCB000907198D99D92EE06BD9CC6DF23F06A51E3
+:10FCC0007F8FC0A0E3F644412F3355E00CE77775F2
+:10FCD0005A37964EFF1BE114C1BAB04B000000002A
+:10FCE00000000000000000001F8B08000000000062
+:10FCF00000FFCB936560F8518FC0F9D20C0CDEBCCD
+:10FD0000A862B4C40C5C0C0C41405C0EC41A407B6D
+:10FD10006F01E9DB401CCECDC01001C4FB81F81F90
+:10FD200010FF07620D20D604E25F407945A81B5BF7
+:10FD3000981818DA80B80388BB805887918141975A
+:10FD40009178FB93841918DE8923F87A120C0CCD74
+:10FD500052F4F3FF60C33156F4B5EF29D03E4E178D
+:10FD6000043FC71998245C50D570BBE03783074D1A
+:10FD70009E178DCF87477F9E212ABF5C0B953F4DF5
+:10FD80008781E123929A0A2DFC6E41C78A460C0CAA
+:10FD90004A46C4ABDF608CCA0F3081D000F9ADB1E8
+:10FDA00009A803000000000000000000000000009F
+:10FDB0001F8B08000000000000FFE57D097C54D582
+:10FDC000F5F07DF3969949662693900D0871028AA5
+:10FDD000A88013086940B4C322A2228E5BC50D26F9
+:10FDE00002D93710FDF0AFFD3210362DD6D0824645
+:10FDF0008B74C0A0C182040D1824E0002EF82FD50A
+:10FE0000D8BF7B5B0C4AC31692801B7EB5E57FCEC4
+:10FE1000B9F725EF4D26806DBF5FFBFDBF69F1E6A9
+:10FE2000BC7BDF5DCE76CF3DF7DCFB14DB2896F89C
+:10FE300063C6CEE00FD2AB2C8CB151DDE96CDBA0F8
+:10FE4000A187FA74E7FF5965D3EA87421EABD06EEB
+:10FE50001ED6FD9CB185547E408C6B38BB1CD3F400
+:10FE6000101B0E8F6DC91696CCD87D6E46BF01094A
+:10FE7000BE742991B1CE1556F7BA0C78AE7A5C08EB
+:10FE8000DFF7C8207750C2F73CC95216E43FA2BA48
+:10FE9000D701CCBE3F23B36CC666DAE06F0FFCC35C
+:10FEA0007AA0BE7CAC6C1063EA699905A07FEA7702
+:10FEB00012A5033436C3EF0078F92D6CDCD0EEFECA
+:10FEC000B913FDEC7380B7E8F9897E5BC0907F09B8
+:10FED00093A8FFECFB4AAA5F6F6FF1F25B6C3E07E1
+:10FEE0003616948DCF3B967FE9C2E78B9B6EA17A45
+:10FEF00018532CD8CF72B7C84FFC5C6396EEFABB90
+:10FF0000F114A27674D8D304EDFE8831E9B5BFB6FA
+:10FF100032C043D556D56305BC4CD8AA867F0C7039
+:10FF2000E95A2984B065979D31C04BFB6A0E879DC5
+:10FF30009A0FCB9FA80518AA28B736FFFC0AC4DB86
+:10FF40005699ADA366FC84F7561BC73B6BE4709EC5
+:10FF50009D83A56B774FC7F70B1AADCC0EF5956E49
+:10FF6000CF9F7A05C0F9FB5486454AD72FD0FA01B6
+:10FF70005C1892EA11EE18CFA8FDE03639B41ECA1B
+:10FF800077B89A936F83F11FABB431CFC5D06F6749
+:10FF900073F2AD8087A2D09649F85ED146C98B2C0A
+:10FFA0003461EBFA37FBC27BA51B24AF15F0525C22
+:10FFB00017CB3C43781FCEC0BFD60639FC63C89F21
+:10FFC0000BE3641948D7EA494CC6F657681E6737F1
+:10FFD0009E8E550E611E6B375CBA01DA81F7CA5EE0
+:10FFE00094BC38C4320B0B205FB66FB74F7BD68101
+:10FFF000E35BA00D76E2B8966A582E3F94BBCDEE37
+:020000022000DC
+:10000000C1FEADD526417ED1EAB55A9E81FEC575A9
+:1000100097318FCDD0AF9A412946FE884C8F019BF6
+:1000200018FB53C498AF1EF94409693719E4A29F1D
+:10003000144FF42EAE934DF50326194B82FF7E002C
+:100040007F02BE823B9D84579D6E73051FE9743B02
+:1000500025E487299DD9C6FAF5F4E74807E84F75E6
+:10006000A59BD25F54A652BAB2D243F47902F107EB
+:10007000E972D16FD758364E81765D3EE646314BF8
+:1000800098E21BA7029CE0E770F2DD01C97396F1CC
+:10009000EBE9136A20176572159BE453FA02AC056D
+:1000A000E6302FB4AFDCE89B389AB1D759E0711C29
+:1000B000FF222950807465AC3ED50F745922811EF1
+:1000C000017C2DC541021E96F4057E063A3D714F16
+:1000D000F6B3B224C69A8870DE738F66503D3554ED
+:1000E0008F0AF50C3A773DC9D3734CF5244F2FD0C6
+:1000F000EB594BF5D8CFAF9E27A68F31F7677A9192
+:100100005ECF0B586E91F3FCC6953C63ACB93F33A0
+:100110004AA89E94BBBD2C00E5659D7F58B34F86D1
+:100120007CC7C6F8118F32231F8DDF86F53941AAAF
+:100130008C7C1497136392A7785F8209EE33B99F82
+:10014000A97C927FA0293F65DAA5117CE970B75E92
+:100150002660E854385EA3FE6AFD34D23BE3FAD948
+:10016000087EA09F83F4CE03630217BBA1DFD8579C
+:1001700006F47F400B5CEE8EC237302E89A562EA12
+:10018000B1601A99BF54E5781BDFFFFBC107E1FDA1
+:10019000724BE7E07880FF4B1AF7218EFB8FA84C5B
+:1001A000816E3132ABC072315646FA6F6946F6B392
+:1001B00041035E970D007E91BAEB5DA60652911F3A
+:1001C0005B821541E4CF253041B07E8C1D6415E182
+:1001D000E085F0FE80BC54C4BF5503FD616C5F83B5
+:1001E000F68752FBADD87E5B2FED5B07E698DAB75A
+:1001F000A51798DAB769D03EC8476770BE681FF088
+:100200003786B1936C3EB56F4D2FA0F6976AACC0A0
+:10021000D47E4C57FBDF60BBDF63FB4951C63F70A8
+:100220008C79FCE945E6F16B7CFC6C4150B41F43D2
+:10023000E397A4201F7F7A111FBF95D7DBD5BEABF4
+:100240000BFF9A04ED3AA45EC63F68AC79FC1794A4
+:1002500098C76FE5EDBB172C13ED3BA8FD78691926
+:100260001FFF0525D4BE660D78918FB4FE31152190
+:100270009C4FD34080524807FA281D92C018E8933B
+:10028000DFB2818487076238DF7D1303FCE6E8D69E
+:10029000A72C041208F37099E0E9E28DE3343E3FA5
+:1002A00007695E9F2DBA3AAB51A6F98CADB4862E84
+:1002B00082FEB637CA418467ADBC3224D37C0A764D
+:1002C00002BEA7B0303EFFF3AA61EB8CE38A4C6715
+:1002D00057ABAD2D06B9EAD2EFE3D9900AE85F0536
+:1002E00032C1A86EB815F434033DFC39E8634C0FF5
+:1002F000ABDC2E39047A9C5D6C949B05DC2E09B234
+:10030000F78740FF7F22FADFAA707CB7CE9342883E
+:10031000FF6F56CCD1509FCDAE8E05A477F7A35C6E
+:10032000D0A973BB3544F6144C07889FDB491419D8
+:10033000FBD3AE1BDE945C303FD6F431BD77370B78
+:100340002D4E85F23397E70E70C3F8EF9A661D21A4
+:10035000E3FCC47CFD2D24C7ACBF2587B1690D2B00
+:10036000D4FE00DC3E4DFDBCC5F0FE1D01337C57C4
+:1003700081196E5743AA05ED994289AD857AEFA997
+:1003800030E7EBED4C9612385D457B3F011CF48560
+:1003900047F7603A021FBB89AED3DDFC5DBD3FE588
+:1003A0000FA92C4CF3714B1223FA2751B9809B8F64
+:1003B0003BB2BFD3559BCF0FFD99FEA04CF88CEC00
+:1003C0007FCBAE589F05ECD9969A2F5564C1C8F1E2
+:1003D00044F67FC6FCC8F1B8359C1F728391CF39B3
+:1003E0009F44F25379E3B85F1E32F05369FDB5BF05
+:1003F0003C6478AFB8EE26135C18BAC3543EBF26EF
+:10040000D7943FBBBAD0943F73D91C139C1B7CD0AC
+:10041000547EC6FC05A6FC7B2A1E31E5DF55B0C222
+:1004200004DF1178CA54FEF6696B4DF9965D97DCCE
+:10043000887254F581CC70DEF8DAD1FA73B437BF24
+:1004400076285EA4C711B057500E8E81BD82697B9D
+:10045000E348B2AB410FE63130A1564BFB83CBC62C
+:10046000A25E66A43F43D2EF83C134C69E973C840C
+:100470003FB94663616061892574F171A76CC86FEB
+:1004800039477E0D08FAC89EF9724BF4E7E5EB7226
+:100490002F40BDD39B3E805F7F9CE73A843D1099FF
+:1004A0005F2231BFF1B9BE7EBA5CE27ABE44AC5382
+:1004B0004A5EEA3B9EB9100E0FAE385B7BF5805466
+:1004C000D49368FD27213F801418E8515C37C82475
+:1004D000DF6DBB65EA5719EA04D0AB99CCBF574230
+:1004E0003D13DE9B7ECB30EC87EF75D4FBAC3189BE
+:1004F000E6F5B6CAC9BF3CA4227DFC941EA99C4661
+:10050000696B6580D2439505947E5E5941694BE5E0
+:100510007C4A0F540629FD63E5324A3FADACA6F490
+:10052000E3CA1A4A3FAC0C51DA5EE9A35497872E0E
+:10053000FDEB17F6B058B7C0036E0F8BB12C82B22B
+:10054000CD24E7DE5494F3538E6F06A3BD7FEA6398
+:1005500060A28CDEF115C96FBDD3D147F64A5E08A3
+:1005600098A74FCF7C7B0CA793DDC22633D0478F53
+:100570005CF49CF7DEA1042BC832C0A9DE9B9C5121
+:10058000EA85B90FE9752E3A315FE7705C67B73ECF
+:10059000FD976CACF77269209F87F7CA340FB3F0F0
+:1005A000B35EA4D70FC59BF4DA9FD25BA0DC892E83
+:1005B000FC35A73348E7486EAAFF5483952988C7BE
+:1005C000A6D8102E8D4FED7BD685F2383755AE3E2E
+:1005D00034B2777C95D667543B0CE3296F34C3A7BC
+:1005E000AAA5C9DC7FE089BB7518F295BBFAD04596
+:1005F00048FF544AF57AE6A66AD4CEB1BA41717C76
+:10060000FE0EF17970633CF12BAC3BA9FC3FBB3F84
+:10061000BDD5A3F787B106F6850DF501E40D3AF7D0
+:10062000FAA807DD95AF343FD2AB49FD06ED85183A
+:10063000F8776620D6AB10ACD75B5E2F07AD97E39B
+:10064000F38DA6F6E03D8FBEA6C7F77AE75B85B5CA
+:10065000EAE3047D75A5F0E714D7D9ABCDF34ABC26
+:10066000092E6FEC5B6D9A67F00F907F562129C8B9
+:100670003F25829B3A14C73209FA976AF150BDE5CB
+:10068000122F576A6BD1021E62C766B433EECDD10A
+:10069000F9CF73FB1F40DF1FFDADCA1EC57CE1D73C
+:1006A00051F56CB06F2DE8E711D0BD0DC55350EF7B
+:1006B0001DDD763DD927B398DF858BA402569D8D2D
+:1006C00076CE0966998CFC7F82FDDE35D2B0DEC81D
+:1006D000B768D49F99CBCCF32CD8672638BFC60C0B
+:1006E000E7B19B9391DFF356AA30B7A05C9AF36F02
+:1006F000B7B849BEF259C5125AEF083FD8BD6EA629
+:10070000F407B92F7DE599ECDCA1E887E0FA5BF707
+:100710000F1426703BA52831A4F920FF8B86913F4A
+:10072000B982E1FBA125A8A7824EE65DCF7AD2EF80
+:1007300087F63FB2BFFA7CD2C34F21FA21D749BE18
+:10074000509475DAC31649D85B414A978B71EB76A2
+:100750006B4D045C1B01D747C07F37BF253213BFE9
+:10076000A55A02359624CE5F682F484AA716F84747
+:10077000EA4FED517FED3FB5FE34A83FDB547FFDDE
+:100780003FB5FE0B7BF4BF295AFDA5AF6CDA16040A
+:100790007D53B479958BC13C7454A94EF602DD4B60
+:1007A000D62F76211F1C51822EE4E7A321797234C3
+:1007B0007EF8D222FCA2CCE790705D857F42FDC717
+:1007C0005EF8D954B4E7BE59AFBA69BD54670D5B42
+:1007D000414ECB1A0AA7A0DF17E0831C5E7A52466F
+:1007E000B8D1CC9F45CFAF4A46FF1E708A584F8480
+:1007F000C95E2AABFDF3249C87CA5927C959E47BFB
+:10080000D8FEE904D28FB95A5CCF7CE827D9F9E544
+:10081000022FE50D3F3B29BB30BDF630EA13B04C4B
+:10082000C80E8F7CAF40D841872CCEC4565842B1F9
+:100830001FB11FA1DED4F1C242DC0EAADAF0E4F04F
+:1008400083D0AFB6DADFBA2403BE74793B553FF3E9
+:10085000D7AF7A7AD7CBED62BDD7FD5E88DEF334B1
+:100860000AFBAD89A7256AD885F671C95AD51B84BC
+:10087000C7259B9E7DEE695CAF7E62F55E04F51731
+:100880006F7AE3C33100176F5113A7F06138A4E406
+:100890006EFA94C3BFF923BAE951F4F21B9A6718B0
+:1008A0007FFE7042375D8AB7ECD6D8B09EF898507C
+:1008B000BF5B6B7144A14FFDC1496867556DF85628
+:1008C000C375E5D15D124BC98882CFB56F90BD80ED
+:1008D00078227A0A7A75D12FA27C39D005F57A244C
+:1008E000BD22CBBD81FA6514AF17FD93C0DF2FBECB
+:1008F0008A7EEC4FAD5EC443C18BF7B9703C8795DF
+:100900000ACEE7CF2C4E463F7D811A4C7653CA9FC4
+:1009100017ACB99FF82FFFBDFB93F9FAD0D7D74298
+:100920007355B02F8E73F6EADB689C792C407C58A7
+:10093000F08CEC0F41FAB5C2266F892227C5329799
+:1009400093C3EB80B830CEC3B84E41BFEEEFE5D0D5
+:100950007AF28FCC61A80FEED7FDF16C2EC15F8BC0
+:10096000FD8471B2455FE7DA4CFC5BBBB419E974F6
+:100970006C802F05FD6AE54C090A7C4867A05EF98A
+:10098000BDAB53389D9847C916EF815D30019F6319
+:10099000F966D5671F6E7A8F9DC9E86E7F9E681FC6
+:1009A000FA1D83F3F9E16456501F657C35B2AE073A
+:1009B000605E37F09941DEB9FCD73EC2E55D97FF36
+:1009C000D04D9331FFABF7B91CE17B385F42BFC21A
+:1009D0002994BFFB5689F4839585A3C979AD2AE490
+:1009E000DC9C1FC92FD07F458A33F00DB69340742D
+:1009F00020BF5ADE4A78DFA857B15D57CF7A7539E4
+:100A0000CE17FA204F067D7059B73E60ABB91EE88D
+:100A1000DDEE0AF2F59B1A7AEE69945F90D7A00793
+:100A2000E557F5E3F88F6FDCFBE19D20B7C7EB7569
+:100A3000B935EBD548B92D7869BD847C1A29B7C77B
+:100A40000BC04A8926B7F03CAADC16B4FC4BF4AACA
+:100A50008EC7C765B35ED5F5646FF88CD49397CA1B
+:100A60009EA87A127EEFB3EC9EFCA8F3A1CE7F4540
+:100A7000BF29BD80FC093A9FEA7CD8C5A73A1FF67A
+:100A8000F0CF98F018997F3BF2040CC1BF5D257F31
+:100A9000624913DF8F83F7DEEC9F45F8F2D134C74C
+:100AA000AADFEC9F68844311707D44795F04EC8F6A
+:100AB000281F88802B4CE54B1AF76A8CF8206C2A8B
+:100AC000679DFF2BF6459475AC3E0F95379CD482FD
+:100AD000C81F699D1AEA3F752198A8E83FDC299351
+:100AE000FFB00370BC04DAE9D898110A821E596C71
+:100AF000E7EBCD0E77A72B01D2C5F11CEE4CD296B9
+:100B0000A01ED49F77DAB91FA4C3DFE98A37F83172
+:100B10000E36C9A4C75B426C72343F09CC3484DF03
+:100B200016D65B3EF78F76E0BE33B687FBCE40CF5E
+:100B3000AB6547FA7C5CBF56CB5E6023366BC1ED7C
+:100B40002E74A177340DBA711A3C9FFDB6CCB76DE7
+:100B5000823EA5AF61DD7184059F182BE17EDE72B8
+:100B6000E29F994D7C1D326B7974792812EFE5393B
+:100B7000E669A87761FDF0B9D10FACD753B03AE27E
+:100B800079D3F5426EAA693D58546BCE0F88F5D4DF
+:100B900037BAFEC96499A47F70A184EB7AA1B7AF7C
+:100BA0009687DE380DE8D3B14F66B8BF7AAA4926DA
+:100BB000FA9CDAC8F753593089E4AF8C7592BED4E9
+:100BC000F1D686F27571EF7AAC6DEB9FB21F423EA3
+:100BD000DAF687E1BF82B46DDB27837720FCCA4752
+:100BE000E97F603DCB4FD865273F73C72E27F17F44
+:100BF000C7CEDFA53F84F0762BF9F73A767D3B1C14
+:100C0000F9B163A1B500F560C700BE7EAADAF9EDBF
+:100C1000F0169A7F17111D33148DE87DAAE92F076E
+:100C2000302EE054138C0AED8B5DB1245FE5AFDA12
+:100C3000C91FD1B1F3DBEC80E39F379E32B1FFD304
+:100C4000E164D35EC2FEC573BF79F98ED1CF2EC0E9
+:100C5000FDF186DDDA4CC89FF0DA5F87A37EED7880
+:100C600089DB4DED6ACB1ADCDF18BA485EA802BDFD
+:100C7000DA51C8FA31B66FD1C4F128473DF1F257C5
+:100C8000F2B39C2F3E26287C3DFBEF8F0FC9C7F5A2
+:100C90009F33649370DCDF1DF803EA895D56E24BF5
+:100CA0007DBCC7EB17903D73AE71DFFB3F6EDC522E
+:100CB000F87CC6BDE0DF9CFFAD8A87FA1729073DA7
+:100CC000F97CE703046F727AA9BFE7C9EF6BFFA74E
+:100CD000D1FD25A0BBEBDCE30EFF3F4BF7B7A70B25
+:100CE000BABB313EA0FCB5BF52FF7EA89E6BF93760
+:100CF000A77B6FE3D7EDFDB72C9EF733A1FC6456BD
+:100D0000ED40C3E2DAD23D6F6742EE5B697BE3B14F
+:100D1000BFE323F67BF4345EE5FEB6F1B8EF03EDF6
+:100D2000B27849AC17F93AABBFB02FFACFCB233B1F
+:100D3000A47FDA63644F30C5B312F72BDF4A9FE913
+:100D4000A5D80B36E2E300C2EE2B056C5E6FFE4ABF
+:100D5000623EDC4AED9F7EFD3EB473D3D264B28323
+:100D60002125FBF775D764FEBC4433AD87AEF598FB
+:100D7000D7479312CDEBA889A2BEAB19EFFFD50ED2
+:100D80002914023C8C1FF0CB44F4A78EBF48651297
+:100D9000C093586011AE3B263ACCF59DC07D6C8364
+:100DA000BFF1EFC5E3C42E3C0E5CE9473C0E90C991
+:100DB000AF7A4E3C62BF096F99218CC7618A97E375
+:100DC00031A1D44B7E6AB11EC76EA21DA3389634E2
+:100DD000A33C2BB89EE678A075B8BE9EEE0DDF4C06
+:100DE000ACCF15D1A48E7F254DF6D9CDF5D1FA5CC7
+:100DF000A7CB0FA5874EC77F942EC9AA992E698EBF
+:100E0000390ACAEB645C3F8CC4F2991C4E0B2AB4BD
+:100E1000DF24D60FD778E628418027A4652A48AF7B
+:100E20007CDBF6228C1FB57925EAC7C56D169A1FA3
+:100E30006C5912E17D488D42F07B16F728A4F7D457
+:100E40002B5E39FE20433FBB4FE306BA9FEF977CF2
+:100E50007FE6CCD86CF4C7F01FC67FDE00EBB75935
+:100E6000AB593806F0345B61C1B804F4934BEC73B2
+:100E7000939FDC0CE3EFAAE4EE7ACE55BE37BDF2C9
+:100E8000CF4E5F013DF6F9458C6DC7946F8A28C639
+:100E9000F5F68F9A38BECAF7B3D0401E8721FB0DF6
+:100EA000FB8A2FABDC3FF3CA1F5F1A89EBDC711D95
+:100EB00043E3B87ECDE271A962BD708A79E2BC0ECF
+:100EC000D4AF83E268BF749FEC8C16E7B841ACBF27
+:100ED0007F83F1289076D4B26A19D757AC93FCBEC1
+:100EE000C15A1B5B1F251E668D6A117E224137F891
+:100EF000C9D9B87FC3DB9F0DAFC619E9D636E5A8BF
+:100F000032BC271DF0F7B961FFEA1FC52FAEF711FC
+:100F1000BF1BEC2D93FC51F447BDC0DFD43DDF91E6
+:100F20009FF4D2A6B516E4DF4B6B2DA6FDD83A553B
+:100F3000F83146B011D8AFA97BECCE2CA4CB3ED96A
+:100F40008BF1A5E54D27B540947DC4487C62FDE852
+:100F50007F6F55DDD4EE0EB57E26E275C7091BC343
+:100F600075F576ADBA385A3FEFB4F27ECE66F5F736
+:100F70000DCFF8F7C3EFB80E47783CAE3F6B99F052
+:100F80008344F21F233E3E55C74238BFE27A15F52F
+:100F9000C2A98D8CE67740C963B8FE0679FFB1D14E
+:100FA000AF7371E396DFA05D50D624B9714BA24CAC
+:100FB00069D1D08F5BDE182FE33C9CE9D1E36FDD74
+:100FC000C36E35C845ABAA10BEF68ED97117B6FBF5
+:100FD000659BC6D04EF1BDDEE9C279FCCBA691245B
+:100FE00007BD8DEBE54A563411E31C843E8CE48743
+:100FF000A11B634CF01572A01FCAD7546BCB3C6F7A
+:1010000014FA2DD324B18F789EFA2DF4FF997E7BAC
+:101010005FD76F01D96F9023BFC09B41BFA544D359
+:101020006F73254F0AE27DEECE412948D7B96FABE9
+:1010300049D1F4DBA64ABE2FBA59C44D7734807E1D
+:10104000BBDCA0DF1A40BF45891F19A3E97EFA73F4
+:10105000E8B7D0BF46FE36A17E8B32DE1B04FE749D
+:10106000FD36BCE920E9B7E10D16533CF0444DF8DC
+:101070009B7AD56F52D2AD681FEF53BDB151F8675F
+:1010800093B0C7378B38466C07F55C95F6C3F45CB4
+:10109000DEF9EAB97F119E753D37772BA3B8E89E3C
+:1010A0007CC8F5DCDCEDA0E724E447AEE7E6EE64BF
+:1010B000DC2F17A1DF86F4D06F8CCA9785F9FBE58A
+:1010C0008D194FDE0DF58DF0A95E1B941FD1ADEF8C
+:1010D0004619F55D95D68BBEDB777EFA6EABD07781
+:1010E000A0C706A27E8DE40F6F9339DE7CC7E8C3EC
+:1010F0001B5F4679F99D4CFB92EF59F8FED13BA35B
+:101100000F67217F7D2AFAF3A2C6E9D95E19A4FAF6
+:1011100027BCCEC757BA91FBCBCB1AB87D58562BFC
+:10112000873CF0E7A431DF69D8FFC29D124B01F87C
+:10113000266BF5130EB4EB9F5799581F4DC934F029
+:10114000C3AC9C62F2FB57D95DEBF0FCD12C85D986
+:10115000D0BF5FEC987414EDE0E21CBE1F502C9ED3
+:10116000EB71B0B3BBF464443C48E39C37FBB39EE3
+:10117000711653AD9CAE539F954218B7DA33EE22E9
+:10118000447AA1B8CEFCFC5D217F37C92D842FF6AF
+:10119000AE1C35EE432FD785A77D024F8017139ED7
+:1011A0004252543C01A5A7642677E3A5F0772D4B66
+:1011B000705FA0F02989F69123C7ADE32D72FC3A48
+:1011C0001E753F77B1A82FBF692D9D6B8AC48B8E8A
+:1011D000E7487C74E13D021FEF695D7EED9118D711
+:1011E000047C437A26F89F801768C73FEE22D3F924
+:1011F0009B8F045E46568F9B80E10F37611C3AE45B
+:10120000E7D5CC79B32FE063D4C79E11389D5E310A
+:10121000C61AC07DDA0DF64ED2833A1F0EB3723E67
+:10122000D4845ED9D1AF623CADF31B2537DA21E51A
+:10123000613BE1B51CF8D10E45F63EF5CD24815752
+:10124000379DAF6A14F313D0C182EB267DBE0AF13D
+:10125000F358239B385DCAEB385DB25827EDC7942D
+:10126000D548DE308CA7AC710EC5A1EBFA197E0E05
+:10127000239DA2F0AF128D7F193A9BB3BBE7CD62DD
+:10128000516EAAB5FA43DCE7990AF2B196D810FE7E
+:101290007716FE3E57FC5024BD2E1378DB847875FC
+:1012A00020FE3AB9FD15FE8ECE69E9F9E54AD084F3
+:1012B000D7094F9FE6FCB753F2A05FAC0B6FC8CFC6
+:1012C000903F4AC71BF233D2A1295746380FF0DDB1
+:1012D00027A3E77871BFD428F7853B0FF2FA9F91D7
+:1012E000BC2CCAB87F307FFF40BEEE4DDE8759C5AB
+:1012F0003A41F0F73BF6CEFD2391BF774ADC2FD180
+:10130000146FDAF7BCC1CAD74D1BEC2007B8DFF663
+:10131000B6EA5DE7E9A91FAEB27239C0F584C7E04D
+:10132000F7BA040782F1A675368A17A47E0CE4F694
+:10133000AA515F6FB2B3A45BB37AAF7F8AA8BF37FD
+:101340007B498787617BA8471BA1BD21DDED45CE89
+:1013500017BAFFE05CE3BA43F0CFDF3B2EBD9D1F21
+:101360001A4F55CE9A695F4C8FAB4AB5045E51D186
+:10137000BE9B2C99E2B7A0E782CEFF70FDB76AA3AF
+:101380007AAF9FA5DAC88ED0CFCB5E2D3B5810F038
+:10139000F6A54F2579012BE383B1387F8C8779102F
+:1013A000922FF78FFAE86ECA97699FEDC6DFF5298D
+:1013B000C57DC81B790C1DBB315322FBE13DAC6CD4
+:1013C00034DAE136E6B38A26213FE747F1213CD7FC
+:1013D00092595B3DC103723DA22E5485A9774267A5
+:1013E000E23B48AF7132437A35FBFA4CC0F9F7BEA5
+:1013F0003FB34CDC8A073B81EA19B18F2561B931D3
+:10140000BE245ACE8C6EF8EAFD5BA07FA3F7CB5EBC
+:101410000F94BB69AFC381723664B585050C78192A
+:10142000C34255E8771A7DC8770BEA8302B07BF098
+:101430007C4941D3DA2A17C2AB257ABF3C1898E41D
+:1014400082FE6DAA3939E932D40B500EAB295FCD3B
+:10145000CB95D74A5E0C71CE6B5A41F14879B512E3
+:101460001D60DC1492988DD71BB241BD9B56C3FB07
+:1014700059387FC1FB586FEDC9F76F41BD03FDA41B
+:10148000F737F2FDFA3C78CF8372523B87EA2B5C48
+:101490002D313C0753B091CF4F05FB552FE637EC6C
+:1014A0007E8AE6DD29D05EDF0C9C8FC213E93CD139
+:1014B00048C94DE7381FBE80F456070E185FF0A5E7
+:1014C000F3F80949C062FDA3DB7FFD6DFC5C539E10
+:1014D0007781D607EA79272729C342FC7492F6E17F
+:1014E0000F01BE03569C37793CCBDE9C2FB416C34C
+:1014F000FC98631B44EFCF6A1C47711EB3999FE2AF
+:101500003CA68EE676E7BB57DA43E8EF7B57ED4C17
+:10151000C3E77BAFB4D2F3F64D5C0FB70F6821BFC2
+:10152000FBE1D52AC3F32F55AB65D2138737AA74D5
+:101530006E577E86C737E46FE276C8DED5BCDEC361
+:1015400075DC7E9BF0CC6D93701ECE5FCFCFF9EA39
+:101550007A5A5F87E6B90B4DF35BA49ED5F570A967
+:10156000C04741F55ADA4F8FD4BBA5FA7C18A16F5A
+:101570004B719F9DF6D3C32447A5F591F1658E6EFF
+:10158000BF0DF243F83BE2EFB2FD2AC3758DF4457F
+:10159000DB248A67C3F91EF24737493E8C7B28F863
+:1015A000D81A227B3C943BE33F709EF9C4CAF0C832
+:1015B000482BD203F4548EB5F38FBF84E747DFB3D3
+:1015C00061E410F04F2EE15F8F13CE5ACFE37EB26D
+:1015D000DE5B998CE78DD9C43EA407F26B641630AC
+:1015E000E88DA392EF963BF9FCE046FB47A76B968C
+:1015F000569D87F36C918DEB47CF7A95CE8BC70BB9
+:1016000018D60B3EB4770AB7AF48D60CFC50B87367
+:101610004532A80EB644C4CB548973E6851A6FA729
+:101620007097E45E6B6847AF47AF57DBCEDF1BB404
+:1016300093A7BDD55F88FDA3717EADA1DE88ACA761
+:1016400047FBBDD493F35FA757E2B9FF9C77650AC8
+:1016500076CFF962CA20E33E8F9EEA7EE6ECF72D54
+:10166000CC67C05FCE1F6398CF40EF865120FF400C
+:10167000BF1B1AB93DD730EAA0569A45B01BE5BD4D
+:101680004CF8A3CB26F2FDBB86CCF716A1FC4FC9C4
+:1016900092881F5830A0F54924FBCD83FB00F959EF
+:1016A000FCFD7C781FE5B2E1292EA7A02F3CA84FB6
+:1016B000CA56AF9844E56B250FD6DFB03697EC924B
+:1016C000821C99517EED41B2930A1A0F26A23C83E7
+:1016D000FCAE447BA06CACD58DEA58974B5DCEDF59
+:1016E00015E76199CD3D0CCF77E0765834F996F740
+:1016F0003361B772B92CCFE172FBEE261547783E05
+:10170000724E72ADCBB18C729CD52DC77B574FD02A
+:1017100050AE0F87248AA399807A00E57C831EE768
+:10172000C4EDD8F395F373D999A520BF385FEA7259
+:10173000AECB75A43C372B2DB7623FEEBBD24EE348
+:101740009870D5F60FEFE3FA8AF65F275CF5603202
+:10175000EAC73C85C779E9782D55785C608F7EAD06
+:101760005CA0F53D9FFE45F4E333ABD95F126F8B70
+:10177000E7F1EFB52AF1FDB9E4B3879C9DA77C9E04
+:10178000AF5C9D4B3EF5F6E59DE67AE2916947F543
+:10179000ACAF1DF018063CBEB5F1598A0F3EF1C240
+:1017A000C1A94887E21DC0E7C85F1B9D2C8C7A4EFB
+:1017B00009D1BC55D420D33903A684B36F711AE57F
+:1017C00098C775156F76123F15BD640D4D81F78B67
+:1017D000B67D319CE26A167652DC5AF005612F071D
+:1017E0005B86A31C14293CBE2C522FFCDAC6EDE705
+:1017F000B6EDB1D3707C521DBFDFA2A8FE76D56ACC
+:10180000D8A778C2A652BB508EF67983C0C778FE9F
+:1018100017FB67BC57418F2B6BDBC0F54451A31AF4
+:10182000C27B328AEAB6B463BC71D1C756F27F95E7
+:10183000D79DA4F31413366F22FF4A79A36CDA8F75
+:10184000EB11DF592787AD1897D8504AFB90001F3E
+:1018500024B85EC453FEC0F8C3E2CD3BB705018592
+:10186000C52F3FEF42FD72AC79BD0BF10EF59E35F1
+:10187000DEBA473C67FD23229EF386C3746F4B2F6D
+:10188000F19CC7F00F1094B76DE6784E56D787ECF1
+:101890004BE867B63FCAFE47977DBEE9EB35781E39
+:1018A000A1EDA5E36BB0DF257FFB720DC689B15DAD
+:1018B000769AF7CA5FF880E2B7F5F7BEB0097FC83D
+:1018C00086E729FEBDFD13AB176B6BDF79381DE38F
+:1018D00006DBB77C978CFECC793BAF267FEFBCADA7
+:1018E0001352589479434F917F43E7117F1F49B7B3
+:1018F000BD0D7B299EED04D01DF560579C6E7D29A2
+:101900008F7FF688F8DC8DD1CF3BF488C76DB8E5C2
+:10191000C62B51FF37707BF29C71B9EF033D2F3F0F
+:101920000F3A6E14F1D7F5379C352EF704FE01F40B
+:10193000B2D8CD74FCBA61F6AF9FC6BC863EBDC6B8
+:10194000E586CF037FFA798A776C3EA71DE5E8A587
+:10195000DF503C34D26F8A07E7A3AFD3F13CCA1102
+:10196000B5733ACE3F9D3BAD74DF4FD1CE8F489ECD
+:10197000DAB7BE477E6A26CE35B4B3AE1F8F3F9727
+:10198000C4786B9D3C9E57D001E37D3D2E7A2EE2BC
+:101990007A395FEBF1BEBDC5F95E6D1F28EE0FE031
+:1019A000F1C8A5B57F10F1B3DD749372905E07CFD7
+:1019B0001A47ADE3C12DF472771C7BF4B8EAAE3858
+:1019C000F608BA213D719EEA8A5307386D04F94939
+:1019D0003E8A762EA27D2D8F7F6F57A39F37D6E349
+:1019E000DA7D11F4D6C7DB9BBCE8727BAE71FC508C
+:1019F0003CD16642524F7CB57D1F5DBFCFB44B7F5B
+:101A0000D7FABEEBBC548914791EEB5EE4CBD286C8
+:101A100083E4CFEC5A7F8BF1B609FF7BDB0B32C539
+:101A2000392FA9DF4BFA3D527F94E1BD2D51FA7B4E
+:101A3000BF5DD8E78D7CFE687BC91972403D6D7B28
+:101A4000B6135F976D3C4871D66FD6BDACB518E242
+:101A50002770FE0819C6D3F6E2EEE1A4CFC5FD302B
+:101A600091ED548976CA9BA2B753BEF1A4A99DE219
+:101A700060BDE6769CBBBD638AEF76ACEF5833B7AA
+:101A8000138FD5CB9343D1F669ECAAD8EFAFE629F3
+:101A9000CCA3740F8E93DF7B23BB62C8EE9CE7CC94
+:101AA000F9382E11538DE2BAAA168838B09F7A53AE
+:101AB00091DE55CEEB18F67731E2D7E0FF51DD012C
+:101AC00086F6AA9AEACF42BF43A4DED1122D2C6437
+:101AD000A0F73CE7E4140FED8B84D3909E07320F00
+:101AE000AB58EF6711FEABCF14B62405FAF7595087
+:101AF000F22E807AD9F75F0CF03B7BD6AFC381879B
+:101B00006593BFA9CCDA7900D72BEC353BED47C8FC
+:101B1000BBEC747F48F91A3B8D77EFD66F9F23BBE0
+:101B2000FBD756C6F787605583F796B9791D87B7F7
+:101B30007EBBE62F6857E3CBD07EFE1A288FEB8959
+:101B40008DB1B4FEE978298EEE51CB7FEDA1A9A825
+:101B5000D7F263393FE66F4E0955417DAD491C6EA2
+:101B6000DD3480EEAB287EC949F1A57BB7BE528635
+:101B7000F354FBE6580C3360EDAF09FBFF37E27E10
+:101B8000AD1AD5638C332F648AC7782EA818615399
+:101B90005C13233F06C911FAB11AE3E83C11D8C51A
+:101BA000A67A4EA89D0F78898F83FDF839AA703FD9
+:101BB000D40791E5F4FCFD767E8EBDDC0AEF39BAE0
+:101BC000CB976B9D791CAEEEC7F5493395FF44E783
+:101BD0007391DFB35E5EFE23BDDEAE7AF8FB65E295
+:101BE0007E9B48FE3DD4A557FE7A71B4FB5BA2F400
+:101BF0009F9EDF2FB1A005ED962D76BAB70BEF674C
+:101C0000C0730EDB34BEFF55E20AD3FD393B843E80
+:101C10002E8909D37D3EFD443FB03CC2CCD6F22292
+:101C2000D2BDF4153BC3F8B3D2D79C3EA477E9B636
+:101C30006F5B7F9585F18BB1E4D72B7DED7F111F15
+:101C4000945AC3D3E9FEBC2D5686F7E7B56D793BB0
+:101C50001DE5B54D0DA7279C655FAFB4DE6ABE5785
+:101C6000408CE35865E842BC77413FAF5BD48B9E24
+:101C7000B93286DBD7F6189F3586E4DD7C4FD4B1C8
+:101C8000CAC641C6F3FB459EE87AB17F8CFA8F9DA8
+:101C90004377F438F7DA3F2609ED99E66474409605
+:101CA000813D8EFABCA8EEE430F41F7C16A3DF6FF2
+:101CB000E089C3F9E833AD7318EABFCFD23B871987
+:101CC000E7992395368FA2925F87D28EB527F3FAD4
+:101CD000318C37B54F8BA6F786C5C412FE8A1E8E8F
+:101CE0008D7A8E7A4C0CE7AB34681F536C17E54342
+:101CF0006FF7332D447AB831C6C3EB490B69F8BC92
+:101D0000B86EFB20231E0A956A2A07724AF82C64D3
+:101D10002BB52C83FED6DB2B9CEFF028743F81F291
+:101D20007FBAF855EEA6333991318E51E014665CD6
+:101D3000F233EBE74814D56F43FC69CCEF5664648B
+:101D4000956A92F718564FA903CC2E7E5F5A054329
+:101D50003D7944ECEFA31F0CD36E7C3D487A3F38AD
+:101D600080B18B32F0BE094F9CDB80BF6B70B33EFD
+:101D700009E3692B18D71753DC688F48C1003B0370
+:101D8000FC5455593788DF03C27C182F49262CF4A0
+:101D9000CFE57EF33BB483804FF93D8457B15015B6
+:101DA000A018C386C9EF3A9EF1FBF3967DCC8CEB6D
+:101DB0008F12410716DC4D7ACCC1BA7F9D00A35A21
+:101DC000457D5B15F7B71CDC9F73B85918EDC358F8
+:101DD000070BC742EA18AA1C33CABF2B0B60035F6C
+:101DE000BAC79AF323E502F45A44BBF5843FA8F737
+:101DF000AB887ABF8AA8F7ABB3D5ABE3A9DC3628AA
+:101E000003EFA5585C592FF0C6DBB309BC017E86F1
+:101E1000E03D7FCC12E315FBE684D718D11B2B964F
+:101E200007BA6E8EC9207EFA59DCAE4E8C97668951
+:101E3000350CD7C38B24FDBE4FE67718DE636E1BCF
+:101E4000C9E123A29DCD02CF8B74BF558FF276B22C
+:101E5000BF7A94B7F7563E267A79676FFD898DDE93
+:101E60009FF85EEAAF8E8D5AFF0FD54B65AF7DF4BC
+:101E70000EEEEF76E92737A0DE6C676E46FD541A4A
+:101E8000DFFAB7167AC2ED4C5B9A99DE31C8DFC033
+:101E90006F31179A9F47F24914FE72F48571DF295A
+:101EA000DABBF3617E5E4DE7835C31BE89B57C9F12
+:101EB000FCEE79DC8F07CB461FE6DF25F2EFAEE1C3
+:101EC000F6E3DD0FCBB40F1B79BFD5C1FFCDEFE13A
+:101ED000B8071F80BCDD335F0A8533A2DDDBC5DEBA
+:101EE0008F877A6788FE44DE8315609E49CBE4685D
+:101EF000F76071BED4CFE145DE7F318BF9C5FD6659
+:101F0000E6E759316EE2DB2225A4550FED9EC7822C
+:101F10002B80EFD1FE04BEC7FD2F599CC7662E8DC6
+:101F2000C7D7DF9A60D27FA78678E270BE66AF8B94
+:101F3000E76EFE7CEEB59E14E37945E574ACE91ED0
+:101F4000A02AD59B8AFA4D3D7D3DF3801C6AA707E8
+:101F5000318F211FEC56127E0CF3243D95AA84503C
+:101F60002F2A6E3FCB47BB379EF3B35E5E4BBCAEB2
+:101F7000CBCE7C17FE1D46E681FFCF5DE1A1F3DFEE
+:101F80005739FCA771FE955D39DE80A3273F04B762
+:101F9000F27157E1B8337A8EA74AF37AC9DEBE0EE2
+:101FA000E645F2CB796DD83FD9EAF9C883FDFBADA0
+:101FB000CAD00FD3133FDE2321C83F15EA4F712447
+:101FC00072DC94C1D8FE72BC6F14F4FF3271BFE8AA
+:101FD000A24A26521E57B708EF1FA53447A43E91C8
+:101FE0004EA6728F8A7B4A97547A29D5F16BF356A5
+:101FF000D33D98B60B79FB36B7A05FA245E02F40E2
+:10200000F6972DB582F61DEDEE8A30DE27C7D26039
+:10201000DEC161B9AB09BF9A9B91BF13CA136C456E
+:102020001852B5660AD1497157B07CC84F7504067D
+:10203000C7A27DE331DF87694D1D71D6FB31BBF847
+:102040006D13C7FB6312E7B748BC3FA6367B306E03
+:10205000E2B16BBBEEAB22BCC37288E3FD3FF97EFD
+:102060006E4FBC374F9B69C0BB337B32E1FD6702CB
+:10207000CF4B055EAB041DAA043EABC4BDAF55E219
+:10208000DEDC2A81DF2AC43BA48F887B7B17233DBB
+:10209000209511EFC0BFD6A14126437B7C0F0F5284
+:1020A00087E05BB785FCA4B2C3EF43BC5B1339DEAA
+:1020B0006D0EA003F135E0DD83F941C2A7EAE078B7
+:1020C00086F29C0E025610EF23F139A707E0FDB609
+:1020D000D824D487634C78D612C79F1FDE9FE2F3C3
+:1020E0005BA290F348FC256AFC5E605DBE7BB38F0B
+:1020F000AB445C7695B89711F18876CD2AC00FBBBA
+:1021000098E3933F1F22602FA54962FD5F0574C0CD
+:10211000FC27853D8478C674672C5FB7245A2A76DD
+:10212000AB88A7047EDF0F4B0CB2B46CC64380F1C2
+:10213000971A641E84F5FDE15A33FFC86E25E27ECE
+:1021400049CF93C86F2BDF562DB87F2FCFBFDE74DA
+:10215000AE5B9EE68BF710FE0312DA353F1372B8C2
+:1021600002F985FAC7D7C38B051F2C15F7063F2246
+:10217000F8E73121CF8FEB7CE3E5E748964FE6F1B6
+:102180008E89991671BF629819E309E3BDF54C83F6
+:102190007ED1DAC64329DD9FC93EB692DCC60E6504
+:1021A0003EE4AFF88F1F0CF1FB70FD7DD11E8AD786
+:1021B000EFBF1DEB89BF830EB4871571CFA4CCD7B9
+:1021C00093CD51EF8DADF2EEB1A15FA6B7FEECBE9F
+:1021D000691BF173DEE5441ED627E0BF6336C08E6F
+:1021E0001A5857C12FD61BC85E8C7AA5C649FCEB7E
+:1021F00080FEE71BF824B617FFCE54C7B51B505F0F
+:10220000BC80062430C12F6A06D911CF80730FFA23
+:10221000B156A9FEBE382FAC8A8FEE8FFB652CDF3E
+:102220008770655D6AF22BAC547DF49E7BAC59EFF0
+:10223000AC14F344C244B39CE8F3C24F457D573914
+:10224000023BB15FC9A727923C27DE1C7D9EA852A6
+:10225000B520DEF751358CCB773057E3F6730FFDA1
+:10226000C3689FE45460F03AF483E97CB690717DD2
+:102270001764DCAED4C7F504F2BD15E70337F13FB0
+:10228000CE0708CB176AFCDEE3BB2DE4875822E4B7
+:10229000ED512167CB857CFD1CE5CB8AF7587B2966
+:1022A000FD8590AB952887901E8FCDE0F6BCB83F9A
+:1022B0004C5FCF2CB48DA0FB22AB1C169A17944F09
+:1022C000AC2107AE0F768F76A3FF477666B9034E33
+:1022D000CCCFA2FBDCA5F82C37F2CD37CE59179C1A
+:1022E0002D1E16C84FF7162B2AF74BEAF7C8578949
+:1022F000FB0854F7CD0CFDD54F2656D829DE359670
+:10230000C787D7E46613DE811E9DB186755ACAB4AD
+:10231000EBBAEEFBC3EA9FECE55E83EF85DE606916
+:102320004176A1414FD488FB249927C88618F4C56B
+:10233000C28B2631F4EFF5D413BDE8CDF55C6F2EDA
+:1023400092A2EB4DDD8ED7F566A47ED1D3C5174C96
+:10235000369DBF541D5E467A6748743F42B2C3CA79
+:10236000F72F99D79B9BD1331FF095EC30E00BED05
+:1023700021DD6FF1E328E389D49347AED3E7D7009B
+:10238000DD3B344BF33C39FAACF3AB795EC83FFD2F
+:1023900008CD4F79A747535A50732DD9230C77692D
+:1023A0000CF72E1C5E7DBF0BE97BB846EC9FAF5649
+:1023B0004318BF74B8667119C1D5760FD266DC2F89
+:1023C0001E74E13D4DB3D6C8B49F7E2426984EF1CD
+:1023D0009FDF9F39231BE26316AC5D9A8EFC386B3E
+:1023E000DD523A377B24C137D86F80599687EC7914
+:1023F000FDFEC6BC67AD3EB4C77BE3DBBCD5D1FDFB
+:102400003D55F827AE53987708AE4376BBC6748621
+:10241000810F8EFCC24EEB822A2DD88E70D5BA5811
+:102420007C83552544BF0F28D571B50FE994EAF098
+:102430005D8B297324D07E4FEF72C4DB6F455F3B09
+:10244000EEBB3E2DEE45023ADD64F2BBF27DD7567F
+:10245000E14763B65EF26344BEA7977C178F936231
+:10246000EEE8F97FB7FF69688FF55D318EBFB4E69E
+:10247000F8924FE889791FA150C48BCF5A171B5A85
+:102480001845CE6689F3C7B3C47E99CE8F85D7EB46
+:10249000F639E7E3483E975EB884F8FACB7D2ACD5B
+:1024A0006B65C0AFA8EFA51746D37D500B9EBBE26E
+:1024B000718C0BFC6ABF4CF925A7EDC4C7ED3FF545
+:1024C000D23982CEDFA9F49D88AFF65D4DE701DAFF
+:1024D000C5FDD33A9ED29C7C3DBCC6C1F550DEE919
+:1024E0009F913C74F15768A686729E77FAE75C5E0E
+:1024F000F0FED93138ECEBDE1C77A1E06B80D72CF5
+:102500009F346921D49BDFC2E58A8D0D96911F7B94
+:102510006DACF7D128F2BFC6E131F9B5F25B96F3A5
+:10252000F7C0AE4C34C499CC12DF7BC83FCDEF6509
+:1025300065EE204B457912FAB05B0ECCF772B7DB33
+:10254000CDE3D4D317BBC6798569FDD63DCEABE8C4
+:10255000799EB053F25B4613DC3D9E5F8D8E369EB6
+:10256000EE718CA5F2EDF1D1DBFF50B4DF5A59C00A
+:102570007CA04F8BC4FDBF79A1FB34D41F79ABE3A2
+:102580001324C3B8F26B8A4DF14F7935B974DF5F0C
+:10259000FEEA5CED5E83BC76D185CD36D1E543475E
+:1025A00080E832D5E1DFE340B97CA1F0814F3D58AE
+:1025B0002FA7D3112D38BC82F4DB7DAE68E7A73E90
+:1025C0008CA4538DA013AC1FB20C74D2E913F97E06
+:1025D000EBFAD2073EC5FD8BA7F8ED45BDEBB10880
+:1025E000FA6544C75FA783F36B2BD80F81F3C2DF73
+:1025F00065A6F8BB5EF127E8ADE3477F0EF6DF5135
+:1026000094FB4E94CD51581FE78773E1ADBB7DC15C
+:102610000FE3A28F27C5A9F3C37C1604013EAA715C
+:10262000FBA3F7F13CC482B6F3184F979C2E36F10A
+:10263000438A7301975341FFA37B1E21BE6E0DC5D4
+:102640007AED19BD8F27C5D90B1F5C186443B3FF02
+:10265000EFF1C111CD37F8299C4760DEC279BDF09A
+:10266000F9C7861BFB97EA1897E6C479A9FAFCF626
+:10267000B783E3BDFB701D1E5C277BAB6048258ED6
+:10268000C0607CBFC8F5F437E8DF5B14FFC4F068B6
+:1026900076F4E2CA7D97A0DFB5AAB2995255D8C5A3
+:1026A0000CEDE20CFE5D8F68F7055E2BF4EBE2CAE1
+:1026B00066EEB7B50599DB70CF003B3292FCD88A45
+:1026C000C36CCF696AC08D7E734DDC83A02A81659F
+:1026D0001959E8674ACC0C1AF0778D93EFD72C4F35
+:1026E000DDE3C6FD102BD48FFE335B9A72CAE4770C
+:1026F0007B5D99E5043AE9D744C7B07A9F24911FDE
+:10270000F254841FF294A91F89CDA67D8A48BC2863
+:1027100036FE1D288509FFB3C087FE9DA4A56E3E29
+:10272000CE95C28FFD04FAAF2F023B36D645F6C1D7
+:10273000920B2C7C7D6853E8BE2B6B3C2FAFC5F110
+:1027400071D871FF43C6F559986027DE1026D3D59E
+:102750008B12C2F1CC2321DC878597E07AA3635CDE
+:10276000CB03F8FC797B20D70978FFA66FF301092A
+:10277000F733FC818B11CF357230D303E57F2D7792
+:102780006662B974C8FA3881A717E0398780619FFB
+:1027900094DFD7DC0DCB3DE10BE62B11FB86DF5F31
+:1027A0006CCCB7C7F82AB01F91DFCB4AFC42A2FD20
+:1027B00041FC4C079FFFFD343F2F77F27505F10771
+:1027C000F2D73E6E3F9D523C71B8EF87D879DDB4A9
+:1027D000EF63F3BC6E684F11EBD85AE057C5B04FAA
+:1027E00077A1E2B3203F5D540DCF8DFD8D62272789
+:1027F00038E8DAF2A876BDDE3F3CAF83F8944F4F5D
+:10280000227B24922F7674ED27F0EF69DDA1339EB1
+:10281000B288C3F14CFFD1FAEE93AEFDAA451C7607
+:1028200073A8FC5EBE3FFE696E1CC599EAFDB8A3A5
+:10283000696933DAC57734F59D89F8BCA3E0E23FD6
+:1028400063BA43EDDC138BFAE27E89CE97DDF9C1E2
+:10285000EB6A2CA45BDF5F47F71F3C2FE4713AEB78
+:102860005491FE01E6D6F87E5788DF47C5BC02AE1C
+:1028700057D15F71773874DB0D00DDF37AE80634E9
+:10288000F7A6EFEB7C03D543A0DE3D89F694F4F781
+:102890001ABD6F7298BFD7357EC546E3E91EAF8D6E
+:1028A000C6AF8F0F7A4AF8EFC28FB8F74DC7C7F897
+:1028B000997CDC77C4DE751D3BCB3AE00EDBB03F84
+:1028C000F3783EDE9F48FC7C8559A01F5F74FAF6C2
+:1028D000203F3EE3F4ED45BD5762EB4C570692BCFA
+:1028E000BC85CFCBE4C005C930FE130302172721F6
+:1028F0001E9AFB9C97BD7FC0CEF9FB809DF3F781AC
+:102900000C9DAF5B9CC8D7EC74228D53FF7EC792A1
+:10291000AD871FBB1DF8FBC4DBFC3EBB52D973E384
+:1029200043E4979699312E3E323D20FC0C2D5D7C80
+:10293000C8C73B43E1F232A32196CEC1CC982F9B6E
+:10294000EEDB9F319FC7C332A579F8ADA675C222D1
+:1029500011D7D2B31EF48344D63373FE04BA17657D
+:102960009BE61E477E91359CCF664EF4C9788E60FB
+:10297000CC3289F6F1471FF234B6003C3314EF45F0
+:10298000319DF9E07F0DC2FB51CA9AB97F34459E53
+:1029900093F9534857EDE1F33DC273104F0E9FC7B3
+:1029A00061D8CF69532B32DDC8CFF7387CA80772C6
+:1029B0006FF57D8274D5FD22FABCFB0AD801181789
+:1029C0009A7BB72707F924B7DEEEA3D4C69418D0B4
+:1029D0006BB90AB3619AA231C58E690CB3619ABD15
+:1029E00050D84F353791FDE0CAF16B78BF796ED37F
+:1029F000F35FE3FBF94A78B764E0ABDCA6B7BFA3AB
+:102A000073763E3FC5FD5E56A799D69FC3EACDF0CB
+:102A1000E58D6638336C8647EE33C36538366867B4
+:102A20008CF81EE19E9D5686DF2B2BDE6CA538F4BC
+:102A30005771AEA0785E3BE9C509C54DD91827711D
+:102A4000FC45A705FD953BFEFA32C559746E8A65B3
+:102A50001867B8FBD318168371BC9BEDEB30BF1819
+:102A60006887FED9E2CDF6B5184FB3ED529D4F43BE
+:102A7000140FB5ED6FFCBC4BE7066B08E32E8E6FB1
+:102A80007FFE45E4CBE31BFA931DF6AA14B4607DE8
+:102A9000C14738DDC708BD3E46E8F5E23AF37AFCA7
+:102AA0000A976EAFBA87E2FC372681E3BBB5B22F37
+:102AB00087C5772574FB6D8CB067DD40CFCF8776F7
+:102AC000D37988D0CF79A17B351FD16B410CEAB384
+:102AD0008EA3DA0CF44B5D5C63C6A3CEDF9784CC87
+:102AE000CF27BA24A1E70CCF33305EC5B32415E756
+:102AF000EF67A3DF537FBD8BDB192FBCA0E9F2206A
+:102B00008B7B2A99C770AEB25BEFB379FD319E081B
+:102B1000E935B0FB797144BB7AFDB12E2ECF5FDA77
+:102B2000F879824481876395FBC86EE8B2232B7DD8
+:102B3000BE890638AF6677722EE16F77F2BD86F9EF
+:102B4000AA64C3DEE4BB304EAE4E418F362BB9E3F0
+:102B5000B99F8F49C4E7723DF613F3118F6DF56F7E
+:102B6000B8B01CD8D9238C7167F93557FB261AE405
+:102B7000FE87F2B94EB71237C7CB2B39CD93F09CF5
+:102B800048710DFF8E6171FD6DB7DC80F85ECDCFB1
+:102B9000D3672BCC2F833C966CB9EDFA61F0BCFC6B
+:102BA00099515EEC0F54712B3E2FDE7892CE153D7D
+:102BB0006AE1FE8E48FA04059F3DFA134701EA399F
+:102BC000A8EF75CB087A7F9F05EC9B23E383EFDCAE
+:102BD00005458EB3FA0F6FA0F830339F02DF4B68C4
+:102BE000BF75AE97BCEBE8E9C2EC9BD154F72DA0C2
+:102BF0007879C88FBA7E290C99EB89A4EF6AC16FE6
+:102C0000F01B62E493C8727DA604E9DC74C97CD031
+:102C10009306FF43C9A16A8ACF8D6C07235898C1D8
+:102C20000EDA81E17528979B789C16FC245BB688A8
+:102C3000631FC461BAC715F91118A2F85236D183BF
+:102C400078BD994DC654D7376D39F5C3B1FCAB5239
+:102C5000CB73BFA2FA9C24E76DEE30DD6FDB4F9C97
+:102C6000476FF37058FFEE8F9E5FD464A7B8AEE352
+:102C70002734D2BF0B309E14CBBF68B758C0683D15
+:102C8000BEA5CF788C536EABE7F7A51FABEF335ED5
+:102C90003BCBBC1EA94FF4F9F620FE391AFD7ABED3
+:102CA0002617CE838B781C774A9F8ACC8A2874D2C9
+:102CB000DF4BD42A3271FDD3798FC3BB8EF014CC95
+:102CC00050C8EF9F4A7E9A5CE19F3AE8F6BFED025A
+:102CD000BA39A1AC0FFE25EC93D7A1DFF30BD9FBDA
+:102CE000807B50F73EFDACAC009DDFA30FF440FBB2
+:102CF0003315165680DF66E23C359C609A4F67AE0E
+:102D000096289E71D672F378F0BE6EE3FC5AC0AA84
+:102D1000A9DE22564F69C16A737E21CE472E3C2719
+:102D2000C7E3768A6ACDF9FAB9C0928D67ACD1F063
+:102D3000F635D3C7E7FB02C727DD6CA3FEDDB72A54
+:102D40008EEF7769CC87F36DE72A27E9FF6216A03B
+:102D50007EDC29E6FDF207737DB320ED983FD33783
+:102D6000AB0F9ECBE7F3232D19499EF9BD7EC5130A
+:102D7000597800BFCF87E1BC5BDC248587216C03D9
+:102D8000511DC19FE3BD26387EE379367DFC386E48
+:102D9000E373F63EA76F119E9B92F9B88DF9250259
+:102DA0001F251BAD267FD1988D52D079399EAF6AF1
+:102DB000A1F7CA1ACE584DF58A791DEC016607BAFB
+:102DC0008D29582BE3605675E9F1D025D1CECB1C67
+:102DD00010785C755B5E5F94DBC7D1BEED27109DFC
+:102DE000437A4AF8A358D806EDC58CEC82293F7B7C
+:102DF000218793E21EBDA6268DBE2F4AFB61336557
+:102E0000FF9B780EB3323ED0370EDA9969F1A52BCD
+:102E100024BFBEC1E46F9DCFF1F0E4888A4B2AA2A3
+:102E2000ACB7753A3F21D5539C40703B9FA79D5945
+:102E30009D6AC0201723E3B8BE8CDBD342E78F3AEC
+:102E4000B74A74FEF929E9209D0F7EEA5A0F43FF25
+:102E5000402AD009F5EF53125B84F7FC6535DC346A
+:102E6000E70DA473568C17E30F4A1BC6C9A50E1AAB
+:102E70003FB7E3622BD6E2BE54CA8C212390DF61B8
+:102E8000DC336E86E7A3E33CD45E5F07A77BEAC230
+:102E900060C6DCA1D8BE7FCE1B288FC362E8BC7C95
+:102EA0000AE0CA9940E932B4CF5259E66EB43353BE
+:102EB000A77846A04F7F958BB793649167DC84F623
+:102EC000E3080E273C2CF9D61113AEA07652ACFCC9
+:102ED000937AF81CED4D1BFA271C067A4FA8C8C43C
+:102EE000F65306F134510BA7613DFBBBE81EA075FC
+:102EF000C83C37237D3DEFBB7129B82EDCDF060BC4
+:102F000075D063FBD3F4FD97B083ECFB0B87F0F235
+:102F1000C24E9997C9CFE724A6EBF6152FD7A1FA91
+:102F2000E246A25E7D8FDBF95F397CE407BF42EBAE
+:102F3000E53C80A053F9E9581632CC0BE5D3BE210D
+:102F4000FBB3FCB4CBF41CEF0935C6959714ECA188
+:102F5000EF3B94B2663A9F505A6F8E83BF22267A17
+:102F6000BB3A9F979F9659306ABB9AF9F9E93E2C74
+:102F7000D8275AB964F3F3D392196EFC569453E8E8
+:102F800039CB6971E1FA710ACE47A8674296A07AF7
+:102F900079375DDADD2DA679A8DDC3E10EB1BFA8D2
+:102FA000E7EBF5B74FD3C4393D7ECF7B5B252820B7
+:102FB000C0CFD34D27C9DF5DD2B49BF0A3F3453713
+:102FC0009E6259D080A7E4AAE6B00564FCE9B8FD8A
+:102FD0004B875E0224D9A3CBF33B4B7D63211FBFFC
+:102FE0006B6190EFD8AC2E792775B3CA220BFDF038
+:102FF000EED289638D302FDFFD7EF3351381B7B2BA
+:1030000086F2F76BE3DE7B6B21C606759D3BE84CD1
+:10301000F73B0DB02D0276003CCC00BB23F213230E
+:10302000F25323E0345EBECD194E97BD8C6D8EFBFE
+:10303000E01A05F45C5BDFF074BC796479D547D79E
+:10304000E0F78E4BB3F8F77BCB9A24AF64D0A3653F
+:103050005E1E87E4F0B6683387221E9ADF447D50F7
+:10306000D228B971FDE0A8DF122618DFF318DEAB15
+:10307000E7EBD392FA83F45EAFF50FB1903C3F3AA1
+:10308000E4732A77AEFD2D36C5FC3DAFDEF6BB52AC
+:103090002D81B750DFEAF7C7B76DF9A8FB7BAA20EF
+:1030A0007FED7D7D7B499F469C5B2FC7FE38BAE54F
+:1030B00045C7E3A3434ED17DBA7F18D6F4019A07E2
+:1030C000B1F34E2EC0AB75FF547A7814DA5F7827CF
+:1030D0002FCE1F4F48A14B705E7A9A052EC176EF16
+:1030E00029BD68377E6AEC80DAF20C5E09F34DDCAC
+:1030F00049C2FF0167CB00FC64DDE9C7FFC2E1A460
+:1031000016BA09E6B6EAEFAFC1EFCD1E18D032C04D
+:1031100002F0F78F5F3A99E08B5A9E41F8C2EA04B9
+:103120000E0F6B1920C3FB03837D2623FDD6BBA3A3
+:10313000CBFD09A16FF4FEC50EF61D8943FBAA84E1
+:10314000CF3B782CDA067A757AD1B14DEB011FD3DB
+:10315000FF2396F4DDFAB65BAEF3131E827E8C6F0E
+:103160004C11F8A67991F4BB42F6445F9C0B13BA5C
+:10317000E9E94C6FF6D0BC7169C516B41F52A60FB1
+:10318000A579E35597EF27EE51DDE9E9249EFEC4CA
+:10319000EDE6FA5BB650BC46CA434EB2AB1E17DF33
+:1031A0006700B923FE7008BA58DC7C3CFF0D197328
+:1031B000D11B0080000000001F8B080000000000F1
+:1031C00000FFDD7D0D7894C5B5F0BCBBEFFEEF26AA
+:1031D000BB9B4DB209F979F343081071139318A9F9
+:1031E000D64D881831B50B22626B7149F84930C948
+:1031F00046AD162DBD5948548208D146040AB8E19F
+:1032000002622BFD82458C1AE88288F62BBDDF72A4
+:10321000EBAD3FBDD71B7E8A884256B45CEA6DEBAE
+:103220009D736626D977935CA87A7B9FE78B8FBEC8
+:10323000CE3BF3CE9C3973FEE69C33B31ABB86902B
+:1032400064428E25DC30C74E9FDF31E6159D4C224F
+:10325000A4BB33F49C494BC87B1221C44548F009F8
+:1032600053687B0E21DFEDD1047589B4DEE14D7327
+:1032700016D1B2447CBD45C3E5BD7FD5DEE5B3D2F2
+:1032800072312DD3E7AB12998BF533BD690E5AFE1F
+:1032900002FEAEA7E51E569FAE25AD589FC3BE7F6A
+:1032A000AA84DCE5A3CFD4763A6E297DAE9DB8B56D
+:1032B0009D8E6B918917CA0BE7166C5D4E616A7320
+:1032C000CC427889D79B2651F84E36E66A56D1769D
+:1032D000BFA7AFC835845C51E0CDB097D1F940FFAE
+:1032E000741CD2442795363CFE1C9837ADAFD77A74
+:1032F000B3643ACFDB1DFE39D0BE5EE39D42B4D04D
+:1033000089B7C07705B423889F39763BB627F2404A
+:1033100019BCFFFF084F95B8EE5F114F77EF34757A
+:103320009D2C24F8F705FDB7B9D7A12A07FAD2BA20
+:103330004E1A87CB77C3FFD07148AD2493143A2C33
+:10334000AB226E8DFF36E8BF79E9077AA28137514B
+:103350003DF42FF0BE4E0AEB52E9FC82FB24CF76FF
+:10336000C2DECFB2119295E8BF13E621E09EF7C30B
+:10337000E6347FD1F07C2C3F78A9E6765A9CB7E4FE
+:10338000CCAEEDF4FB790F59085186DBD31E719D4D
+:10339000DF7FCFB89A5C499FFADEB086E2EBFD1979
+:1033A000C4B39CB67B5F431A00FFEF73BC953F74B8
+:1033B000F7113285905FD9B5F89D49D083E4DBBD24
+:1033C00088E2B753224123D0C34C3DD2C36088D298
+:1033D000C395B0FE747DE8FBEE07278782747D06F7
+:1033E000C90091613E15C4BE5D89A9BFA300EB2948
+:1033F0009D044DB43EDA680E6D95805E28A0A55000
+:103400003F09EB5F95D8FA07EF30E238DD33191D3D
+:1034100076373A43C11C00B68B00DEC6A2A3947671
+:1034200082744864EF9499B6617C6CE372C1523A3D
+:10343000F0E2DBB43FB2DAE4194F1FB0843294BB40
+:1034400052713C4A0FAB91BE640647FD8FD342AB2D
+:10345000705C4F39ACCBA336EF7C781FFD914501F2
+:10346000F83799C84A63097D4AA4C3E8A4EBC0E1D0
+:10347000215D4F13A083BB60008A877F6F386F5335
+:10348000E8FB9FD825840308CD584E481D61F5758B
+:10349000CB2CC7A429F0D4860D09F4DDCA1BBC03CC
+:1034A00082BE72D9D348FBF373BA22EBA336C08332
+:1034B0001FBE4B80FE3FB7295628D3EFA7C0F2D3DB
+:1034C000EF0B87BFFF39F07D19C0C7E0276D166588
+:1034D000BB348C1FF1FCB980AFEB696FEC78629C58
+:1034E000F87E8FD9BDFF07F045F11E4E74015EB422
+:1034F000B8AEF1F0BAF4D1C74DB47E5E9BD6B182BE
+:10350000E2D3BFD486F315F0DE951ABD8EE48DECC0
+:10351000FF94A5A55C86F92F65744F961928E26281
+:10352000F1A21F2E53D25D48A28735D228EFE5F0D5
+:1035300001807F5177CCF7F8DFBF1A62DB09BE212B
+:103540008A14073FA72B459261DDFC125B37BD3E15
+:103550003A0FE4563CDC029FFFC6E58DA08B787CD9
+:10356000FF1BE0BB6C24BE5DFA814CE8D7BFD48062
+:10357000788AEF9F90107EF7B489044D94EED64B75
+:1035800012D2EBFA072D21909B83A6E80EC067604C
+:10359000FF8DB8DEE71ACD0AA14D36EA19BF05F74F
+:1035A000DB181F170C1480DC3B47E7ECA5EB73EE30
+:1035B00037DA9EA0248020A4E537DAAD40FFE75E2D
+:1035C000BE89F5B3DCA2105A0E0086E9B881E07F0F
+:1035D000B6118A57699611C73FB1570A19A0BE8F15
+:1035E000E239465E9EA3FF36940CCB8D41A800388D
+:1035F000FA2C08079D69238EF75D335945C76FD1B3
+:10360000485E0DAD6F593229D4CEE031C6CAD51609
+:103610000DE9904A86F9BF4573BCE0DE225627A724
+:103620007079AC60BB431285B3C9B83AA205FA05FC
+:103630003EA0F54BA03E67781D5A567FF417984779
+:10364000CB1E357D343DAF9EC79258BACA19A61716
+:103650004B29C317A926A1F1145E1B2F5B6A2221F7
+:103660002DE063E93472E22ADAF4E0C074A0235B4F
+:10367000692FA9A3CFC069E20D51B8A7F6F7BC36F0
+:103680008EB677D4443261BA81A5BFCD3B79D5F0EF
+:103690003A0B38AFE97F424BAC381E7E4741F1EE22
+:1036A000B662BB89B3AE887DAEC0EF92354C2F0FAA
+:1036B000C02BE01F99E9CD755C6F52FD8AF27A61EB
+:1036C000D704D4AFA0FF40CE3D95C0F431C83D90A3
+:1036D000336D8EAAAB1C749E6667D51447191BC741
+:1036E0006783E927A1FE88A7EB783D24DAA5E6B534
+:1036F00016B75AC76E47F90CF116DD90C8E4882C4E
+:103700006179D1AF753DAB103E19E9E6DECD3928C0
+:10371000971B48971EE8BC8984F440C78B8C24987B
+:1037200040E962116D96489F8BD71B8812B37E8D3E
+:103730002175B989CB85BB4904BFBF7B675C7D35EB
+:1037400009DB687DB391842DF0EC55D7B7507D8EA1
+:103750007CD6F78521F63DE966F3BD8BAFBBA33A76
+:10376000A4F5D3796F3051DDEA84065DB83E5397F6
+:10377000F5E07A269678731E06BDF22B9D672BA581
+:10378000DB3FF0F512F83966AFAA00BC9BB51A9C76
+:103790007FF46103E2E724D5E3B0FE6B1DE4AE598C
+:1037A000F479AE8D78F37580267BD62CDB483CAF60
+:1037B0007AC5D40074D3E0D0A8E82AD3A1C372F9A3
+:1037C0000A8EFFE596D0D61C44F714A0A7F25CA1A0
+:1037D00057C99499B47C4C47ED3B5A6E9963F543B5
+:1037E0007F03604FD0F2FD0E26CFEE77E8713D45A6
+:1037F00059CC57D00D1D07FB335FC59E028E654324
+:10380000ED9F6074C3F5F0BA46730FEAE121FAD573
+:1038100010A4DF229F1EF0FA0A972BF3C16EA1F8C5
+:103820007E851214C88F602FB35F293EE62DA5E573
+:10383000574E1779562940674CDEBCF21D3359416B
+:10384000877CF3CC4F1FFB275A7FFEB45E31D0FA42
+:1038500005406B74FD5E918817C60BBE680881BE7B
+:103860006CD2337BB469FF15CC9ED1FB372C8471AD
+:103870005ED079C0DE694A083DB703EBD33C94A221
+:10388000C9AB3A86CFE0CB16F6BD39F4B39FBBA0E7
+:103890003ED513A4EDA326FF4658D7748392887AA9
+:1038A000F9D75AC2C6091738285E8F8798DD7D9CE4
+:1038B0005649304EBF0DFBA17C9AB690F673A233E9
+:1038C00015E743E52FDA5927D618B682FC5D373461
+:1038D000AE84ED8FEB7CD3D368F9F88BC59EE5B44D
+:1038E0006AD0A70FEB293D07D632BBAF5EA36C01B0
+:1038F000FC90FD169C87588FC09AC5B5501F58B2D2
+:10390000EC16908F63F139C87B122337CF9168167C
+:10391000F0D3C686DCDE30E895FE891E54AFC44D78
+:10392000179FD28D9DB53DA963F88DEED3213D5FE4
+:103930006EFF40177239D343304E80CA6522F80FAC
+:10394000E5724C593B5A99AD63E095546EDFA9EB93
+:103950005312FC47605D5A9EFC8FF7972A305E1425
+:10396000E522E94A46BE3CA9F3CE03BA755487F571
+:1039700075317AFDA483D999F5066E0792B03E960B
+:103980000F457D79959AEEC5F304A77F5B84C9F74F
+:1039900091F51ACE1FB71A408F4D6520936CD02336
+:1039A00056E85FC1FEA79E0EEBEB69397B5958BF05
+:1039B000883F814F28BEC3463AEF931B6C8CBF29CA
+:1039C0001AA09F451504F5E5222DB5634BE0BDD245
+:1039D0003740D7E5D48B0EA42FF2678A158AEFF90A
+:1039E00084B73350BB97CAB1973AA430EC0BE6AF1B
+:1039F000376C35E5005F7BB53658CFCD12CAB1F9CB
+:103A00001D95051B6879C99E2B70FD132A185D2E24
+:103A10000939502F4EE5F2B1DE10D2A31DFE3389D5
+:103A2000C03E88F68FF67413FD28AD64241E40AEA8
+:103A3000ABE8211453A6F6D1D45E26570995E724A6
+:103A4000C66E12F21EE43889B303D5F41114FA8855
+:103A5000C93DA2A482DC1372F998DD97E8443B3E8D
+:103A60003F15D697AE27939BBB25C46B3369457D25
+:103A700022F4C0D0B85C8F9CD20699BE323C81CF74
+:103A80007C670EAEEB12D28BFA44E895B1E820DFEA
+:103A9000A9E1FB88D1E960BC53C1FE9A4E93F07551
+:103AA00074BCA66524DC3C853D6D53503F323D69B6
+:103AB000647A129EE6CBD097F1FA315E1FC6EBC155
+:103AC000543DD377629D853D933A8DD901539785B7
+:103AD000B4A408FC35DEEA94E461BB26F08ED1A8DC
+:103AE0005C09651FC905F99E50F9622AAD0FC8C46B
+:103AF0000B7C65A178E9A1EF3773FBB72795CDD78C
+:103B0000AD67F4AB937DA4D80AEB12C17D6F3499F5
+:103B1000D8811E053E37DBE87725F01DE3B7A1EF1E
+:103B20008DA4C31CF37DD52B26D43F175EB6850C20
+:103B3000688FF8B31DB4BF94DF1BD04E3DF78A0DDC
+:103B4000F5E939AE0F5DC2EF401E617E16BEAE4193
+:103B500052358E00ED4B33C6810814F659B383D924
+:103B60005923ED215E9F1399C3E8CA80FBCD0B8ECC
+:103B70008107A04CE121A07F6E71327E0FEC995637
+:103B8000FC43FA3EE0B37A18F6FDC540AF06EDF708
+:103B9000E718297D4DD72E8B3E48E7D19C69B58328
+:103BA0007EABCEFED7DFDD41CB1FEED11103ACF3F0
+:103BB000F6697349EED8F2B731A43B3E10C32F77B4
+:103BC000EF54979B7BD5E5409FBA7CBFD3E63A651F
+:103BD00041D9E1F982D2B5C1D07ABA87C26B78D522
+:103BE00080FA6886D3FF9013E4AD267A18F06CC88B
+:103BF000FE780AF83B02FD9F48F03450368A1431B3
+:103C0000FC035F5F30CDCFB68F82B761FC11A30696
+:103C1000F14CAD75F6443917E07CE2D27B3F3C4075
+:103C2000E7BF6896D9BE02DF786BCBCAC19E441845
+:103C30004960FD4D1FC2BE8BB66B84F53F3593B610
+:103C4000A37035AC67FAB0894412806F5BA8DD6958
+:103C5000A44BFC1BCE6F777744CBC3F47FBB9D3561
+:103C600013014EF92FB20FE8E351E837C64EDEEAF2
+:103C70006472FC4BFB993246F899B602FE9A8D03AA
+:103C8000FA4A3AFEF57FF90CE5FDE2A5AFE13E8286
+:103C9000CE633EB3AB4D0AC8A7C50F1EC0F762DFA7
+:103CA000762AD38AFBB6D7361858D9A1C7F2A9CD40
+:103CB0006C5FB9B8570AC13CA55917932A412F6CBC
+:103CC000D6D90D64245EE3F1F8C1A6B713C0EFF5B1
+:103CD00001221DF67B12B3C7ECAD09B87F505A1311
+:103CE000C0BE0CACBFF143908F8B376B3D602F9003
+:103CF0007D36F4CF2CDE7CC3C48556E8E7D3A44AD6
+:103D0000F0136DB9013C54D0CE17627E9EC8F5F415
+:103D1000BDBCE56A05F8F1D06606FF62877107D081
+:103D2000D1F57FD1227FC91AE2073BB95BEF9D082D
+:103D30007CAD6CDA3E1DD6E78399E91A6CBF4B2245
+:103D400076C08B63690ABC5F2CC93EE0E386F58DC3
+:103D5000B5B1764F9D93F9C72AB397A50C5891AF8B
+:103D6000E6803E6DDE4CF908C69FF5DEEFEE700D85
+:103D7000F395346BFD2D53A1FF67751EE0BB217BCE
+:103D800066D3B790BEE02F4CF1B598E3EBABF29958
+:103D9000C122F8A4B500E4EAE215AD05F651EC8CB9
+:103DA000213ED944F9723221A79D12F902FC9319E0
+:103DB0004ED5BE63AC7D9AB550837AC6E821DEED60
+:103DC000F4994AB7C9B01FB725C9586F4BD2237DA4
+:103DD000CB7FBA77E76FE8BC9E74FA2F80BECC2603
+:103DE000DE62D06B4AD45E45CD5A4035DA61641349
+:103DF000B3AF89CCFC85EB92C98E5531FB7353125E
+:103E0000DB4F5039F105F473EEDD3F1F06FCB6645D
+:103E10007D3C05EC85C0C5CFF4E05FB3F64B28DFF1
+:103E2000AD1E1F01BA09F4CF240B8A86E572C0C308
+:103E3000F446FCBCE624E9981C7545B19F4A97827C
+:103E4000E56E07417ADAB8D48CF6FE4657C80440CE
+:103E5000FFAD7C2BECA746EE0F346EFB85570B7441
+:103E60001E92ECE3A1AC30FE186C9817D2D2713ED2
+:103E7000DC9617C4F29E4A8F96D659B7FDE3CA5C0A
+:103E8000C0539FCE03EDAD9E810498DF87DB4E24A7
+:103E9000C0FC1AB66971DE0DA14F5216160DCB0982
+:103EA0009DC65F900476825DB2C2F8425E7CB8ED3A
+:103EB000D3940556E63F407D5A3A3A5ECCCECAC905
+:103EC000F0FDF5DF64EB726697210472F08C89F9DE
+:103ED000F745BB3336A6FFAE4B12FECDDE2CD03FEE
+:103EE000436579A206E4C4F7ED6CFE2E7D6F16F0F3
+:103EF000E54792BA9F252BB52444E552E34A8984CD
+:103F0000A8CC3FF3DC4B5920FF3FDCFE52565D0C42
+:103F10007CF1DF89E78D496A7F9AF0AFBAF4E10C52
+:103F200018AFCE63607ECC31FCABA23D59CFFCA470
+:103F300083946B810EC577830D662FD8BB83C4181D
+:103F400002975B5D3FF7D77ABDF92ED8D788EFE3AC
+:103F5000FA5F0DF444E192FA24F427588AA2289FCC
+:103F6000BFB4FC77D1F58C91FF749D8DB04ECDC65A
+:103F7000E8E17104E9430F78D3B75865D05729EDCC
+:103F80008CBEA2F76B709FE532274C81B8803EDD76
+:103F90006D05F9767D81B9439308EFB342D03E3386
+:103FA000BD10BF0B5631FA0FA610F4C3A5915609E8
+:103FB000FDB476E6E7CFA820F655B4F8B32466E75B
+:103FC000B88967BD360FD75FC23807C78BD00F409F
+:103FD00047202FCF4846A423A95F427B54ABE99DDD
+:103FE00007FD8E45572BC5BA72BA1A2AFF9DE8EA1B
+:103FF0004941C723E8CAAF205DB98DA3D315F72384
+:104000005F767B12F4C1BE3695E36B2D973FD1FBF3
+:104010008DC2AF2EC17C6B797FB5466B580B7AC4CD
+:10402000A3FB38D63FBC89DAC5B07F4A03BB9E3EAE
+:10403000C7B5CF5770DD486400FC0896AB8DA82F3C
+:104040001FD34472C08E499DD4BA1BE823755E51BC
+:10405000493BEE0B331CA01740D7A27F74E9341FF5
+:10406000B323581C283A538FFB9C96072B7DCC8E8C
+:10407000A8417E09AC3629A007A7F5E72C07FA0866
+:104080002C231E03D271CF8645E0CF9D6DF580AC09
+:1040900013F125B252CD779D128B53056F22180F65
+:1040A0001B8E330D6CF921E8FFC622F49B0CF98FAF
+:1040B000F309EA8DCB8D43D6AD3621DE45FC68D0C1
+:1040C00046117425FA91B13F9268647A68A47C40E5
+:1040D000FF734A05117FEBA19C2ECA3CDE23F85FDB
+:1040E000C4A36C45BE1CB0C82B9C39BF32439C0492
+:1040F000FC776CB31684FD00FA8D5919DDCA4F693F
+:104100002820E950FB9FABAA3362CABCFDD0F7C19F
+:104110005537575F8BFA77A81EC0A67A5994BD26EB
+:1041200005E255C3F532B5838D7D12FFBEE2E61B75
+:10413000A8AA1E94C4F87FEEF4821FD14454E3C5AC
+:10414000C227C7F5AFA3FD5B15DE3E38EE26E8EFCC
+:10415000A912517EA0D34BE15BAB53F78728E5DF73
+:1041600043418CF77F530EAF5A9D316C1F507BE15A
+:10417000CF4965C376C2A3EFD5765D49C7B2D83FB4
+:10418000D583FE15FA3EE092D00E89E7D70497F466
+:10419000D5EC6B65847D9DE062F6F5746049BA2FBD
+:1041A00041F91D58E62360DF52BBC4E942BBE4E39A
+:1041B000530768FDB9599F1F1EA740BB7BE6C1BED0
+:1041C0002A705146F91BD8A90D49946F8CFDCCAECD
+:1041D000A6FA1CE305827E96D839FD388204FC9746
+:1041E000DDFBA432A077425AB36EA36BF903973775
+:1041F00013C7E1FBCDF87997BB985F205058B5A164
+:1042000000FADF2611B01756151E4F5980FBA9631F
+:10421000290B63BE6BEC7B0AF1D9B853372A1ECB4E
+:10422000A9E104786C79F9452FC88D3321096542DD
+:10423000831CEA04BBB6A141031621290DCDBF039F
+:10424000E31F73F5643C9D5F06D777819DB706A792
+:10425000C2BCE9BF127DB5D1B708E5C4C6B9462BCB
+:10426000C6910AEBEE413CD8CD5EC0C3AAC2AA34C7
+:1042700018A765E6743BC64DA83D07F52D0F7E07D0
+:10428000FD4502AE557DBA1AB077CAA95DF70B0A93
+:1042900077A673468D87F2F538EDEEE2FBAC10574A
+:1042A0001F5D8EFFBF6446171D922FF8ED52F48FED
+:1042B00092587F67761FB31F6F71E955FEF15B5C03
+:1042C000CCAEBD36189906E4B25F1EB0805D1D20ED
+:1042D000DE4F605F4D7C56653BAE13935FAE360597
+:1042E000FD6646D7C0635742FDB532EE67883CF0A5
+:1042F0006318F75CA7CBB38A703E80F283452190A8
+:10430000C7FB5CFEEFC2FA96737BF5DCCB371683F6
+:104310007F51D85F9DCF99506F76DA94276B404ECE
+:10432000FE49667903C668641AED67C9E74E1CB793
+:10433000D314EA84F50FF668B1BEC9EA5F04F4DB72
+:1043400078EBFA299887600D15801ED5B9BA08D088
+:1043500031DDBEA01FC5E8F21188234F0BCE972593
+:10436000D0177176CD34F063E1BEC5857EDC2ACEF0
+:104370001FE329159C32222B747C91346CE7BCF925
+:10438000E7D932BC14F68FC6C8FCEED573CD04EC69
+:104390005CF248F4B006FCF8AE08017BB8B957C22D
+:1043A000719A0B5FD0C3FEE5EE5EC6DF01BEDFA0F3
+:1043B000F8CBC27894CBC2ED810E46672472781C8C
+:1043C000E0F979B69E84D076317E5742963379C033
+:1043D000FBD3F3F84333F737514D88F5AB5CC2CECE
+:1043E00058A18E5BF071D74911AF16F05A2CA9FC79
+:1043F000E4E2D9C3BF4F3C189D0EFC1BA5F4057E1B
+:10440000A70DD2CC7B5EA7F3DB5036C903A6989BE1
+:104410009293B604DE5352A4782FEDFB643AD00D8C
+:10442000A921C8AF2D7D95DA662B8BEB605E8CA53C
+:10443000B507EA53EF2A44FD0C719359F4FDB31C00
+:10444000AF6956E6C773AF08E6401C34F1A0EF9E93
+:10445000D761FC2BCCE8874DA56B6373E27325F81D
+:10446000BDDCA4F800E86777AD5202F088781FC47D
+:104470000B67160DE7E3383D92772B7DEE76399882
+:10448000DFCE406A005E781FB20EC71FC19F07E3F0
+:10449000427C0F9EE7D2C232FAFFC9C096EDB8EF58
+:1044A00037603E486DDF1BEF80FEAD35925E8CC7F6
+:1044B000C6D92DD589B7BE02F43F78F6D4968701C8
+:1044C000AEDBF67A30EF25CE1EB9FE9BCC3E3FB375
+:1044D000DDA2003F6CE5729BDA8FC827C15D6C3F9F
+:1044E000196F471E75A9F72743E5AFDD8E64F00508
+:1044F000B7B33C0B21DF037CFF37D8703E01F4D704
+:10450000BF0DC113970FB28DE783F48F9E0FF2E6B4
+:104510000E4B10E8E17CAF09FD92328F7B9DB545D3
+:104520001F002475380ECF01791B5872E6E71ACAAE
+:104530007F720F8B23C9128F33FD4A4B585CCC6BB3
+:1045400007FF8B805B764C777B8B403EB27937716F
+:10455000BF5193B34061F12E9637D494102E007B57
+:10456000EA55AE879ACC2C5E35E8D087615DA326EC
+:10457000FF1F5D18D762DF935F1A94D8B8564F8833
+:10458000D975270A35613D9D670FD807B06EAB59C5
+:104590007C6B289F60BFA1C7C0E290581EECCC4145
+:1045A00039592FE256FB993FAE9EC7A74ECC5AF41D
+:1045B0000CA45C7448AD35B03FBBB0AA12FDE80F47
+:1045C0003C39139FF52BD57EFF45E0A7CF1B8E23EB
+:1045D0000BFF7B1DF1E899BD3CEC47D450FB4559DE
+:1045E000295781BECC21F61520FF95205DADABE9A2
+:1045F000B3833EC168973412D83972A7CB0CEBFB5A
+:10460000688706F554B043E3857602CF39C9CC8F6D
+:10461000744D32F36BD0A50AC138E2D9A1E371071A
+:10462000DEDF72A209C35323B1E7A376B966347DF6
+:104630002DFAEBD0B51AC14F17CDD4A0DFFB82DE27
+:104640003B17FDC6CE020279541DB6D69535AC1E79
+:1046500079E78229EAC3FAEB64664812C509F233A6
+:104660003599E7CBC5E16D6197BA1C1F8F690CA91D
+:10467000CBF5C43F212D8FC50F62DFA72633F97517
+:1046800061550EC7B707F3E3C4FC976730BC6932C6
+:10469000D93337B36A2ED0412EC49773E0C9FCAB2F
+:1046A0007426087FEE752E09E9230EDE0E30DA80BF
+:1046B000BE3A593CF46F853F1EEECAE414AE1FBCEF
+:1046C0006E885FD6DBF5188FBE5C3F495DB25A0E2F
+:1046D0000D95BFFEFD2CDB27756A799E8D1DE5507B
+:1046E0009D9DCDE584E4D91186F7566A2FC03C3AEA
+:1046F000B525603F4CBBD58AF368D96F423F70F354
+:10470000B2812CD0E32D55030510B789C72F402B5C
+:104710000BF945DBD5B9E8FE03EC84D8763C5F4B5A
+:104720001D67F5FE20B90CF6392776BF01FA6AB786
+:1047300009F515FDBF0306F0B3BC9C83F6CC8736A4
+:104740007F1BB40B98C35B9ECD01BB85D94DCDFDBE
+:10475000861EB00BEB3A62E27CF09FD5EAB81F5997
+:10476000E944FF3BE956BF6FD814F7DD883860177E
+:10477000AEF33ABD7F22F03BD53B987F70B65183B4
+:104780007903F55ACF2290B7674D6A7BFCAC8DADAB
+:10479000D796A175F6A0BDB565CC75F614C03AD70D
+:1047A0006B883FB69F665867BABE4D7C9DCFBE787A
+:1047B0007501ACF3C7BBAF2E80755EA7EBF202DFCD
+:1047C000B439FC5B9369BF276FF0A13D25F2582FE8
+:1047D000971EF724ABFD2B43E5FF21FFCA58FA30A3
+:1047E0003C04875A1FBAF44A06C8833AA3E1BFD5EE
+:1047F0008BF037AA1FCF68407FC7FE3F7FBA66079E
+:10480000C8817E2DDA23A2BFFDB23F0FECA1FDEFE0
+:10481000B83D4169ECFE1BB95FD86D2441F0AB880F
+:104820007D80B027E3E5F15B7C3E1F257B6F00BBFD
+:10483000E6CBFA8D1BF83B63E85366E76E933CCCFE
+:104840006FDC8B7EE4967DF3EDE0273E1D627EE318
+:1048500096178BD16FDC187A2D0C7965A45FB2C3E3
+:10486000FEA371DBB104C80710FB5CBAAF3D938CAB
+:10487000F4A8DEEF9E0E9D4880FC010A7725E871C2
+:104880008B2BAA07BA6FA1FB3DC8236C91A387A10C
+:10489000DF1617C13C97D23EF5FE4FC47937FAF4C4
+:1048A000287737F64B2190D7297A7F4E06E8359244
+:1048B00061C77820E7B38BC9DED494B2D8F8BAF7D1
+:1048C000F3E4E4E17CB0810D8948BF033AE2B583AB
+:1048D0003CDB60E3F24C46F9F6C74D8E10CB0F631C
+:1048E000EDFF18627642A3C80B934958A6EBB56852
+:1048F000B6F75D586F90F7E138791F5B1671FBBB17
+:104900004918F552331918CA0F8B6D171FD78778BE
+:10491000B8AA1FD25AAC801FEC4EAB07E081F8B8A2
+:10492000BA3EC8F6EB941F96960CD3AF580741BF1A
+:104930002DDC0F1D6838FE08D06FA04FB2837DD7E5
+:10494000E461F4DB44F75B90471BCFEFA4579D373E
+:104950003A16FF97A6A8F5D150F9EFE45FBD3E45A2
+:10496000CDF762FEC26F3F34CF7E89F165DCBCE2D9
+:10497000F7A9F1FE76B1CFBC5C793827452D0F87BA
+:10498000CA7F67795837B42EF1F2501DCFF89BE5F6
+:10499000E1FF705CE3997D4F27C0BE03EC78D8A798
+:1049A000ACDCAE63F91314FDB1F1E2E95AAB97C583
+:1049B0004FB5A25E1D8757A6F3383CE3EBD75ED414
+:1049C000E2BA35F33871F33E9B079A365817639C69
+:1049D000363E7EBA84EC9E0E4B151F476D027ECE8E
+:1049E000BB743C75750A8B8F525872206F213E6FD5
+:1049F000EB35EBA749FE9875AF2AA21B8251E8DB85
+:104A000028078933E6FDC6146657BFC6F38BDC7AE8
+:104A1000768E60ADCDE285FD8C5BC3F29F7EE0F2C9
+:104A20006D82BC18A3C2F1FAF2ED4443F1F28CAEF0
+:104A300017E54AB0D9EA013928FC37A2FF8B3C5E62
+:104A400071D9FA3F8EDEF7FC0FD37B3C7EF68BF1FB
+:104A5000FED6B8DD7A8A1B155F10A4E323105FCA67
+:104A60001949BF63F533161D1F4DF11D496176FECF
+:104A700014CC57B84C3963298D9E003F11D963502F
+:104A8000C0AF097E12D48FABD3783EAAA77C26E6AE
+:104A900069B37325E21CCE5876E40743EBC3ECC838
+:104AA0000FC65C9F2F6747DEEEF07D087476B2D2AA
+:104AB0008BE7011EB551F8617FF89C61D4732EE23B
+:104AC0003CC6A5FC2D5FC4D1D517FF4B72D4923ADA
+:104AD000965DF975CBD1CF13C07F3A763F419EFFEB
+:104AE0001941BC45F749646B8C5F3B1061F97B1938
+:104AF0001C5EF1FE3FF8BEA121D59B994ADF7FFCE9
+:104B0000AED14812A99E2E6572B1C567C5B8424B99
+:104B10002FCB7F695946508EB780DFB408FC8933AC
+:104B200009D87D4F3AFD13208FEED1F7AC416D22AD
+:104B3000F8DB6711B0F3CEBDCBCA339CFEC99867D2
+:104B4000B76C00E318DDB3CE601E56F9179F3E52D6
+:104B5000538AF0A23FC165509F67B93D95C933F1B3
+:104B60009C3D846F2FFAF33F6E60F9DA0197D70E00
+:104B70007E09E10FB728118C2BB4EC61C65BB996A6
+:104B8000CD87FC3003E9A9654F6531F84D49AFA9E0
+:104B900018ECDDF2DF5B71DFF7F183E99827B1CF25
+:104BA000E5AF027CD84A4337817D9A4DC701BBF7F8
+:104BB000E3DD371503DC42FEAD03BF391D7F9D4D9C
+:104BC000ED1727469677BF644726EE339BACFE5A17
+:104BD00098FF3A138323B89D9F4FE1FEF278FE17AA
+:104BE0007C9FAAD5E038A9DF35629C5CC885753A00
+:104BF000E237E60DCB93129E671870F13CC7FE9921
+:104C00002C4F8597AD2E75BEE747C93794003C25DC
+:104C1000A9F2578B675947E40B94A4B27896EA5CE3
+:104C2000A2E522B3A773ED7AA427DB4AC2E254942B
+:104C30009EC0AEBF361A9906E7BCF2BBC3D7029E30
+:104C4000F75FD4209EE49947303E9328B1F1F256A5
+:104C50000F744E007F8CFDADEB6049952E7B15A047
+:104C6000F449A7EF8154E4FFD64218AFEA5F742CF1
+:104C7000BF729F05FD0CDD594D985F79EE3D83EACB
+:104C80007C4EFC334856603E656EDF6F314E60DB14
+:104C9000238D9A27FB44AA15F9A62518998E393633
+:104CA000D7BA50CECAFB7E1F04BB43EE944102919B
+:104CB0000E9D5703E7D382CB09FAF5C777DB35B0F2
+:104CC0005ED93C3F6670FF7F4EF1E3BE45C40542AE
+:104CD0002CBF4937F008ECC7E4E503DF0CC27AECDF
+:104CE00071685AC07FAA8BB6A0DF659F05FDACD95D
+:104CF0007D792BBE41CBD92BED18071B7CE5EE6CE3
+:104D0000CCE7A7F31C3FCA3C1F4A65F948F23E8B2B
+:104D100006F499FC04F1C0A8B223A50AE17E8A96A4
+:104D2000693FDF077A4A1E8E9B823F0AF45443AAEA
+:104D30007F07D0CDD0B9A4A566762E899FA7B52DC3
+:104D40007D6F179CF7D9C2FDB907F74F9E85FEBF4F
+:104D50004E598275B8E060F9952FA4B278E248FC0C
+:104D60001FC43CD6DC7DBF657A8DE202FA97758C54
+:104D70005EE44E570FF8195F49F063DEEE751D6172
+:104D80002DC6CDEC277F5CA3C4EC77D6333DD3B2E0
+:104D900093EDCFE3F73797D22FBF1E92334CBF0C62
+:104DA00095FF4E76CBEFE2F4CADFBC6F21EAFD5EE1
+:104DB000BCFD12BFBF1B618FC7F537961D23F25094
+:104DC000AA86C761F6B44DD84941559E4E95959F28
+:104DD0003B34AAFB5F9F64477A10793B29EDCA7286
+:104DE000C8DB8FFE88A0DF4EE415893CA26015CB9E
+:104DF000F7096A8C782ED14DBA307F681C094B12A6
+:104E0000FAD706F0FC6D2AE411D1EF4FA4E662FF59
+:104E10009B8967A516E5A62201FC26C83F4902B872
+:104E2000431B16C178B759713C13E49F24E13E033C
+:104E3000F939DDC7F256A735B0B8433AD5CF504E51
+:104E4000CF6774699AABC73C56915722F24F045E04
+:104E5000AA38BED3272CCA01B928F254D6993DE509
+:104E60006017C1396838BF1C6C34F3BC13D66F7738
+:104E7000632E9E4FFEB27929F17816F929FA447F04
+:104E8000A6BB6CE43967413731EB89706DDCC7EC48
+:104E9000FCAA063DCE63B07106FA2B071B3504EC65
+:104EA00081AA7E03A3C3B8F136CED59330F42B8705
+:104EB0004C204F053D5CCACEA5EB5B08FEE0836D40
+:104EC0003BF34E52DE3FD4D68BCF4193D4ABBD12D1
+:104ED000CFA1CE03C9F58DB4FC5AF91AC8B78966BB
+:104EE0004994846AD3AFFA964CF5C46072F47D2875
+:104EF000DFBEE17BAC3C3EBA45A2ED9BD33E62ED0A
+:104F00008136D3A9D85EFFEFB541EB57D07F7F261E
+:104F1000F1F91C35EE64F4EB3C12413F12D77FA54A
+:104F20004C3EBAAD7AB49FDC3C1F9554F3FC5488D8
+:104F3000F8D0727B5A31C6EFAD44D91381FA0C0315
+:104F4000B32708E387F6F1CC6F6DE4F4403284BFF9
+:104F50006A2008F2AE3DC781DF0FC9E73D8610F336
+:104F60009BB1F18FBE78059E4B1279B684D833671A
+:104F70005F81F936AAF25A133FA729DB33E1BC7BE4
+:104F8000BB8EDBC1BC7CC4E65F88F304BEA4F6DD47
+:104F9000D11B7E5004FC7476EF0FF341CEDDA8A741
+:104FA000FB8451E45A593A936B833AEB4A897EB7B2
+:104FB000C6E66F013A7CC7326F3A1C319A9B54A9FE
+:104FC0007700BCC1E7B480D7644E278ED90C3E472A
+:104FD000B54F823CD476131B37D92F7BF15C847F8D
+:104FE000B6741B85BB5D62F29B7E94887655A19258
+:104FF0000871C8267EEE55CBE58896CB917F6E1B57
+:10500000C897A9C1784DEF135AB0E77FCBE3E2BF51
+:10501000CD519F9FE87133B8C5739656B902E8CF5A
+:10502000A5AB3A524BE940ABF78470FD326D1837AF
+:105030003E602B770FD0EFA5EC1F95423E777BE6C5
+:105040008F4A21BEA7757ADCBE98728F9BD17F35BF
+:10505000B403BC595A4BC1EFFBB5F59748FB2BFA8B
+:10506000F2FD0DF56360703519A359706EFE59930A
+:105070007F3BACFF85F9C7302EFC40FAD1F721AF5A
+:10508000E3A88ED15D3093E7E393EE690994EE0EC9
+:10509000E739785E0A8BBF1E9EC0FCA8547EB1FC27
+:1050A000D18912E621D6CE66E7626F26918E01FA8B
+:1050B0003D3A5968FDF48A1CB47F6B799EC8F47739
+:1050C0007C09B07ED36F8FCA20F7C7B2E76E74EB4E
+:1050D0009481183EBE4951976F2E5497BFE5519762
+:1050E000BF5DF19709B16593D97B10E8F55589DF6C
+:1050F00047710DB1237FBAA420D85D935F4AE7E7DB
+:1051000089593EE54FF97EF1A50A82F5293B8D5B71
+:105110008D50CFFDEF5A5E3FD94D8CD94EC407EA72
+:10512000E9A8C4F3325D1893227BEFB1333F346DAD
+:10513000ABA7FDEC9DAF201FA75835E49BC0EBA5A6
+:1051400046B4C3045FB49B287D533C968F339A8149
+:10515000DEDB759EF5D097D66C50402F572618B1E0
+:105160006FED3FC8A8D7969B0CC44ECB071F376383
+:10517000B95C263EC823A120CE86E7519D27D40ADC
+:10518000F3A5ED60BEED0E1657D796EB51CFD37E4B
+:10519000715D0F3EA109119C7FA58CF9A61C66C10B
+:1051A0007774247CFF34E76BAD8684518EA5B37B86
+:1051B000390ED1FEA1DF83BFD2F6A0DFAE50B91306
+:1051C000EACF1B27E0B9A8C0D0792F5903C015DA60
+:1051D000B97CE867E7F2043F0BF942A55EBE2B8578
+:1051E000309014F80F053B05EC0482FB0011B7CC9E
+:1051F000348A7AD90BFDA60DB567E7E05278995647
+:1052000085352560A7BCF127A0C3B1E445611A9399
+:1052100013E229E4C516C3C3476AAF196D3D0AEF0F
+:10522000C7F20C9B9DADC7840CE04BAD794206E8FC
+:10523000CD768747F1C5940BE9766AAE13F045DB6E
+:10524000D1F2AD35C7F2E518FD5498C6E4006DE71C
+:105250004DA2F01E342919C0BFA38CDBCCC6B57C8F
+:10526000BDE3BAE9B8B4DD411B1D97B6DB663284F5
+:105270003509A38D5FA1C078971A97A21D913F832E
+:10528000AF03A59320F8C10EDA3448AF3378BEF2ED
+:10529000C164361E2954E7FFE49BE9F8985FA6CE67
+:1052A000F7B951DAD4017AFA6953C256A0CF373828
+:1052B000DD1CB6FC433ED8696FCC2B388472267156
+:1052C000790710D10CD28BF246C8C10B69C7CAA1AD
+:1052D0004CE5E18D6974DE0FE41E9D079D1F723C55
+:1052E0009D8FF6A5D95B935636127E419F026EA024
+:1052F00053E08B213A8D835FD01BB9A51713253757
+:10530000533B179EC2EE25A495E5C52B99C3F3A385
+:10531000443EDDD8CAE6D11844B86F74FC18F3E6F1
+:10532000EE18E7FF1EC035F7CA4FF0BE22E29E3FDF
+:1053300001F67714DE7969C9FF7BF0C6DBF997CAFD
+:105340000F1F8BCFC5F8D2AC9D981F1E986DC57CE2
+:10535000F1693C3F36D0A0C1B800DD0FE23EA28526
+:1053600018432097A772BB5C9C5B784562FED6E031
+:105370008B06457D3F517CDEB88279E9C1652CBF43
+:105380007CC87E6F56D07E1FD273FC9C44773193CD
+:10539000EDDDF728EAFB89E613F5FD440BED2171FD
+:1053A0006F8A94329CBFDFDD4390FEBB6DB9589F7E
+:1053B000AE65FA887C83E9A3EE1CA2BA1F699D3909
+:1053C0003411F394785EC146C83FF86FF20B7E9AB1
+:1053D00026A9FCC243E5AFC92FDCE6F0EF023A5B39
+:1053E00058E4CD92283DD6EB997F98D2EBA6088160
+:1053F00074C5D67CD8A7DD445ADFD2E421BDFE02B5
+:10540000E97532A5D73C15BDEE61FC1544212DE8A8
+:1054100075884E0BE3F300FDFB60DC6E47EFEF5B3E
+:10542000605FD36FF0B03C6896D7192F1F62E059C8
+:105430002033785C5A2DC2F33AF4130FCFE5F04DC8
+:105440002C9DA612C61F63F14FAA4C82B69261FE34
+:105450003199FD6FC1B8437CF408DBCF8E805B6B64
+:10546000457A9A73078B7F052CCC2E8038581A1DED
+:105470007F261F7F4EA7AFDA01ED664A0C0F61FA57
+:105480000F857F16AF9FD9DF8C7970B3AA75C7637C
+:10549000ED20212F45DC6D2E6F7FAB7DA60EF2D265
+:1054A00067D7AAE35D73EF64F1B639B3D5FDCC25B8
+:1054B000AB3FC17C4DD2AA03FCCDBD535DFF49DAA1
+:1054C000509C6C02C4C90E713FD020E513E0A3D7F5
+:1054D00093176FBA87D2F9849F149580DFF0869472
+:1054E000C66D4FD0F2B31B2761F9F594EF7EFF280C
+:1054F000D46F29C072355CE204FB56E043CA67856D
+:10550000E577CCC849007DC2FBBD87E07BB7D9DF1A
+:105510003D93B6734FC9C53CD66AEED7185CC8EA4E
+:105520006FBED2C65295EF52D05F5C6D66F7351DE7
+:10553000297EBB04F2AAAB7379B9E4D549503E2465
+:105540007D82F73A9C6BB6CAB00E2DE9CCCF3EB93E
+:10555000500A4FA478A976F2FE9BD9BC6A4B9E4BA9
+:10556000073EA9AE62FD4CF65476E6413BCD792C60
+:105570009F4B372600FE05BFE5F07D95B02B7D5C87
+:105580004EBCE43DD69144FBF519250F4CD1577123
+:105590008CDD4B6665E7037DDE1C19FCF4D3BC2C67
+:1055A000EFB6CAB83C0DE4E12D7E7D29CCCB6E2C44
+:1055B0003E0479118915956598A76D24B8BE94FEAF
+:1055C000C7A7033F5EFD495602109D554DFF82BEA1
+:1055D000660ABAAF56D337E5DBC9E9659796DF2A85
+:1055E000FA360DD3F758F63E85AB02E1FA865AAF8C
+:1055F0000D8D13C79FF1E38E2537E02F56FE0EC3A6
+:10560000D78B7C9801D98D79C0A75D824F6F023806
+:10561000F49A089E8FCA963C93F0807185C7887A69
+:105620002F8E5F057C99E0332F190917FCC9C26ED4
+:10563000657F2EF0A364F07AFA9D973887E1A2E3A4
+:10564000DF910E7AFC1106CF66A995C919BE2F11FC
+:10565000FE971631DF3EF57CCBCDEC1E0337F8CB41
+:105660003076523C6908EECB5807319F00D7E7B33C
+:105670008D3E9B9ECEED36473DD2CFED54A33A28CA
+:105680005EC274FF0F701ED404F7C17E6F21F162F9
+:10569000FC9CD247203DC66E12F0C6E3A9650CB94A
+:1056A0001A3F9F78FC0CAF5B240D9EE2FCE1D07C9E
+:1056B0002F739EF1F68A4BAFF65B3AB97FD139EC86
+:1056C0004F2C84FA5A62F6A03FD123E17EAF96DADE
+:1056D0001F20A76B6B08FA719C560DFA13851D32BB
+:1056E000169F5CFF4D26B76A9B083FF7C8E6174F29
+:1056F0008FA964E07E78D61A950D0B80FF1BACAAAB
+:105700007306B556168F784EC8113250067A7FA8A8
+:105710003C42EF0F94811C8ABF7FAEF622F37B3BA5
+:105720002F4AF8ACF51C2B03BDEFAC1928037956B2
+:1057300067F7FE14D655DC13198FCFBDE91A919780
+:105740007259741ACF47220E7AC4E67F393DC63F9C
+:1057500075568AA09F75B5CBCEE7E7CF017A76D88C
+:10576000732AC1EF34DBD8AA03BB38D1E13F90CE16
+:10577000E4E8175FC0E6179A523CDE56ED7F5866A4
+:10578000C3221EEEE578B881EBD9F39BB4B80FA91C
+:10579000F6163E0DA1A0C09B3A1242BEF5A27E14A1
+:1057A000F7C69DA7065518DA3F6F437DBBF857F53E
+:1057B00018279BB05E4394187D39316456DD7F32E3
+:1057C00079A75355BEA2375DD5FECABE5C557D7123
+:1057D0007892AAFEAA374B54E5B2C85455FBABDF0A
+:1057E000A95295AF1998A16ABF03F43DC5E3374E9E
+:1057F000CF52BDFF68E3F437213E7D5DF43BAAEF55
+:105800004F703F04097A238574FE0B04BD5EAC53D0
+:105810007D4FCD9AB0540E7CCFFE16AC6679F795CD
+:105820001463B1FD2DEC52DB13379028E62BB684C0
+:10583000244F9840DE9DBABEB1AF07F17AA97B0F25
+:1058400026B8E66BC05497C6513B632220825C0D9C
+:10585000798363F1FBA5D6BF80E47FA9F537B8D57E
+:10586000EB6F52D4EB6F2954AFBFCDA35EFFC40AD8
+:10587000F5FA3BBCEAF54FAA51AF7FB24FBDFEA986
+:1058800073D5EB9FE657AFFFB806F5BA67B6AAD750
+:105890003B7BA97A5D73824B54F5F17420E849C8CB
+:1058A000CFBC95F7AADB53A46862E842D0D9025F67
+:1058B00003E6638DEF7A48355E3C7D4C203C8FF4E7
+:1058C0002BD247E5386E7F72BAA07AA96A5C32DAC9
+:1058D0001937C073EE046EFFFB46B73384FC8AD5DC
+:1058E000EBB1FBE6B1E4DA087DC5F7D163EA2BD86A
+:1058F000479B86F7D163D1EFBB84EA591C7C35FA0C
+:10590000CFEEB033380E9A993DFF29545D43DBD179
+:10591000361514DE77613E74FC77CD93D10FF21DFE
+:10592000D2AB8371EF24117CCE23517CFA895D7553
+:10593000BE6501F1E9B95F6409E0A9C938500E7A82
+:10594000FFC2FCA3EF637CEE48D265DD07721CE268
+:105950003FE30939C5E5C9498803D1F23913F7276F
+:105960007A89E28AC1E729EEF7AC9B26A19E255AE7
+:1059700033E6B1D5DD2EA19EAAFB0FF66C1FC7F44E
+:10598000DA88E75281D72E6E1F303BA10F0EDD6201
+:10599000FC90F8AD688F7AECB0DEB43F1687F9471B
+:1059A000767FB1DBC8E0DC2511B9C289C70671DD9D
+:1059B00061FDE17C9BDBC8E0DBA52346C0EF64E230
+:1059C00047FBF031998A3CD6EF24D6EFD15CF01733
+:1059D0009ACD6F7EAB1AF2A9E5E072F4DF7F8FA853
+:1059E000FDF777B64AE8BFFF1E859B3EDD768F1B2D
+:1059F000F4B228EF02B8211E00EDE8FB5477AB04A7
+:105A0000FEB1AFADBF3D0FB1765FB2BFA17E0883DF
+:105A10000BFE603D857F3683D2B781D2CBB6EF11C6
+:105A2000F41FC6FB6BC769A90681FC311DBB97C07B
+:105A30002DAF67FBE2C31EBBCACF44740E38477A52
+:105A4000297B0EF2BE4FC59CD3A07434EAFDBA1F69
+:105A500065B07CA4F6B6C844884B9EE371D787DB5B
+:105A6000DEC4B256F6605E26DCF7E588F95EEFA28A
+:105A7000F531724EB6D2EF63E48DCEEAC3CB6B1E26
+:105A8000698B60BC53C7EF257B34E35EBB3FC6BF69
+:105A9000F2CE386E271983C49E42B8694FFF4E4F2D
+:105AA00023403F5ABB7C2A761F6D70D3FE62F5EE11
+:105AB000C564121B7F58D9F60EC2FD88E4F7436710
+:105AC000867C1236517C1B6438034DDF6FB811E5BC
+:105AD000AFDE76AF07EEA11A0B7F06B77C21567EAC
+:105AE0007E388EDFCFC5E5E7936DD1C9304E7BDBC5
+:105AF000800A6F5D6D17F1FD9A3652C4EA3FC47A91
+:105B00004D8D82F4738AD24204E27AF2800DFCC198
+:105B1000D43E26107FD6B98D186F30B818BCE4A2D9
+:105B20000BE9639E9DC1003EBF4C4A1FEF2FD5E19C
+:105B3000FEFABE4C2BB6BFEF37E30F7829DFEA2918
+:105B40001AB47FC37C86C761F8D373F94964BF0F69
+:105B5000E4803E5DC63885D33E0BD7F1CBF627F007
+:105B6000AE3711CC47D6675AD15EB85C38DD196ABA
+:105B7000BCC7E38FE209E5FF7D1C4FF73DC8FC93EE
+:105B8000F7DD4FF03C05594AFFCA87E96A1C978741
+:105B9000A9C487CFAE362A080DB05E46E29F40ED1D
+:105BA00011D28B8D4DE0A7827AAFEC80D48827AAE2
+:105BB0005D33E1B9A6E26417B0E3DA6B3F8BC01343
+:105BC0006211802F7B0309C155BC98AB40C777F8A1
+:105BD000593981D727CC65E5445E9FE863E54CEFF2
+:105BE0000B523500161747CBB43A6FCA0779BC8001
+:105BF000B073F1FC7E8DCD84CB0BAB736635D4DFF7
+:105C000049F09C8BA8FF09AF4FB31E5F99077A63D9
+:105C1000B6FAFB0D1C0FA9D6E35DD330DEA6AE1796
+:105C2000F1AC64EBF937F1FB2275FD53FC7B9BF57E
+:105C30007C641AD4E7ABC77F9CD75BAC2CEF8DCAD2
+:105C40007E767F03AF7F8CD79BA01EC62F64F55A4C
+:105C500071DF096FD7C9E118E2331E430C2633BF49
+:105C6000F2963623F2573CBFDD07F773950DF39B91
+:105C70007D2919F5DE86FB3298DC495006BCDE51E1
+:105C8000E4A2A877DA65CC37D0BAF5484F062B974F
+:105C9000279C1F87E489D4EA6144C6E4F4A5E89A06
+:105CA00012F005906B59F40FE83AE3FB1AE28F917A
+:105CB00073E94D66E28FE583054E5539E5CE74559F
+:105CC0007BD7EC5C55BDB57492AA9ECC76229FDC46
+:105CD000CBE9CB5C54A2AA17F765906DBC9D9DB52E
+:105CE000D3E54F55B53B5FA824028D9FBA49DCA38D
+:105CF000E631827CB8D7969B0AFCF8B3B60A444ECC
+:105D00003BE527F6B4F3A71B8C59FA5478B910CBAE
+:105D1000CF3B587E7F7B9B879573089EAF6F6FABA1
+:105D2000C1F22ECA9FF0FC699B179FDB6959A1CF76
+:105D30007FA4FD2BB49F1EDA3F949FA1FDC3733354
+:105D4000ED1F9E3FA1FD43FD06DA2F949FA670C173
+:105D5000F329DA0FBCFF31ED1FCA4FB4F9B0BCB65E
+:105D60006D2E961F6FF3E3F3B1B6067CDFD9D68AAA
+:105D7000E547DB96E2F3E1B6203EDBDB56627D2FA2
+:105D8000A793E7F979DCE72BD9BD03F1EBDF9F217E
+:105D900061BB2F9D9F534A157AB92A3FA73F03FC49
+:105DA00002BDEAFC54C01FC26162788C87E36806BA
+:105DB000B30F2791C8720B931F18071FDFE75961B4
+:105DC000A1FC35AE95AD7B4E5F14EBD31AD8784766
+:105DD000B99D405C419251CE8E9B43BB7352A4CA85
+:105DE000C2F207D00F43DC143FE5EC5A7246E621BD
+:105DF0000DC02557503D1E33AF217C39189C80B70C
+:105E0000D1E0FD578E376D692FBB5FA7A62B0C6CB9
+:105E100066F6B6E2FD3AC6B9BEB04C9F2E9F1FEFA4
+:105E2000E99874713ADD2452F976F19B44A1CF8C44
+:105E300026F5FE317D41896A7FA6BDB8862857D1F7
+:105E40007E8BD4FB3C73FEBDAAEF8C190FA9EAF53B
+:105E5000AE15AAFABABB731E71033EC7B1B89961F9
+:105E6000F5720221E485DD4F205CE64C368F73929B
+:105E7000C27E5F6037FF3D13BE7F79D6CEF1655C91
+:105E80008DFBF2090E562C480C6A400F7DFC8B44AA
+:105E9000947F3B9ED1A09F7E22096940DE4CA6E6FE
+:105EA00024D45F01378C6BF1AA262D948B89A285AF
+:105EB000F255248AFB3ABA7FD164D2F56BD1FA9FAE
+:105EC00031D1F2D94CFFB32CBF308CFABA80AF6716
+:105ED00081D8C7AD97E3FDDCC64CF437A9CF257652
+:105EE000F0FD4B8789F90D973BCA53C10E3E3746EB
+:105EF0003EA8CD7DE28D0514DFB6B463F814EF1F24
+:105F00005734A39ED7CFCB94BE5A5EF77AAA4FD40C
+:105F10007C9307F3385BFACF29E0766BC98F22FFB9
+:105F200074E8843C5312419E0D973D8924661E3BC4
+:105F3000DADEC9935121FA116F325F37315FF94FC1
+:105F40009576C84B2CE079D13BDBD2F2ABC70F7F03
+:105F5000EFE37450482235A05F0B8B349E1074E041
+:105F6000B5ABFC31A6FC2E2F9C0B934B8807C4F2DB
+:105F700044D285F729C87FD5623E9A7CF01AA25098
+:105F8000FBD86A0D9360D170BF84FB75BECFE5FC72
+:105F900067F66A9C8F9C25EC260FE874F299D51B56
+:105FA000013AFCAC5BC7D8F4B8BABED04A50EF2D6A
+:105FB0002AD4871409EECBEBC27B40E52D12C9C869
+:105FC0000138A6B9E7837EDF6B413AB6AC2FC79F95
+:105FD00030B859E3AF40FC0E287B35C2E8A2ED9AF9
+:105FE00027EBB7823D3901F06205BCDC915F0D43C0
+:105FF000E717221E17F2792FE4F3E8C81CC23F838B
+:106000008778BC701FEFA26EE18F52CFF3F1D2AA56
+:106010006FC3BDA2ED112DFF9922353E57E92253E2
+:10602000E64BC37051381766825C01B8AF820FD857
+:10603000FC9A9F91C8C61C946B35686F9469303F79
+:106040003D9E2E9B3299DC8F66D8D97DE4EE534875
+:10605000CFC3E5936F2C48C2FD33B35B6C32CB8F5B
+:10606000F47A9558BFF72AE15FE4E772CC1CDEA111
+:106070007B0527B1BC602B89AC87BCB4B1F6F52B8E
+:10608000327370DCE17D3DB55D203FA5CC88795C45
+:10609000AB443EA172549969634F385765E474FA72
+:1060A000A84D9DF7B39DCF6F3B5F8F41A3C87BF297
+:1060B000D616C79CF3A9EBAF473F9688D30E72FF65
+:1060C000E1A0591D576DE4A43078A8ABCA0CF1C10A
+:1060D0002E16A76DECBF99DD6BBBEFC7782F30EDA7
+:1060E00053017AA8E7EDEB57AAFD580B77FA915FB9
+:1060F000E3FD64F17E318A393DEC1FE3FD625B33E1
+:10610000F97EC2438A210E7B6275DE6133EC7772C1
+:10611000089E0F1FA77D01EFDDA6BB812EB84F970C
+:1061200014B1FBA3E2D7FF54961EF1B253ACEF7843
+:106130002BDAA53BCB981CD879E0FC2DE3693F2BEB
+:106140007324D5F98095393A5CA7B7297DC3B397F5
+:10615000909AD1EE293B94A9F96A72EF5AF5EFC1F2
+:1061600034F70D1CB62828FF5E03BA1F3CFC7942A9
+:1061700011F251147FBFC408C23099C10DE7B37644
+:106180006B3E99174B0F6F67CA58FF36A78B2F0DC1
+:1061900057B51AAEB3456FA5CC6070FD0EE4C6B915
+:1061A000F0F194587B46C0B57B8CDF03F8F0ABE28E
+:1061B000A942AD1F62F074FABFC3D36EFDE8F0FCD4
+:1061C00095C3F3B343EC5E9B91F55F519F75ABE1D3
+:1061D0003DFB7C640E88490AEF5F117FEE9329181E
+:1061E00013E6F8EB2DE5F459CAE58F07CF5091C0BF
+:1061F0007B57631E66AF4C926AA15CBE007FF72C92
+:1062000093EFC3021A3F9EBF21EF1946957FD764D3
+:1062100031BADE9D2E8D8A87D22C36CF0347EAB263
+:10622000C1BFF1D83B0602726133CFBF7ECCDE6BBB
+:10623000847BA6051EA15C429F017D741128BCC70A
+:106240004A3F332AD651C6D3B0F1D6C6F18D184F86
+:106250003CA76415327B553AA48573386BAF7D0B30
+:10626000EF7F5B5B2AA3ECFDD2F85F1D87FFF05B3D
+:1062700029B7307A999245E16B91FE90F06D5A0EF4
+:1062800048D17F2A827C15BD1FE71FA078EC91467C
+:10629000E2292D8BD18B989F98BF80DB76DD025C45
+:1062A00007DBBB06541AA5BCBDD017895CFFC1BC77
+:1062B000505F5C2BB3734C6532AEFBDA8AA978EE83
+:1062C0006C37CF17895EA31FF577441670BC3D76F7
+:1062D000F1B711B84739D8AFC3FB3F883CE0BE15D2
+:1062E000EE1FFF8D8CF789537AAA81FBCC0E1C39E7
+:1062F0009F00FBEBF9593A847B3E97878317B535AE
+:10630000781EECC867766D0CFDD76569B97D12897A
+:10631000C039AF3525EC3C8B95DB03D623271B001A
+:106320007E6BC543062986DE66651910AE35FA68B0
+:106330008A87F617D8A72561E6FFC17B1987CEB3F8
+:10634000DA191E5A4A0FA1BD60ED67F735D66529E7
+:106350004CCE52B8F7D2F7E6899FD9EBA1BE948E06
+:10636000973BFCBDCDCED6D35CC6EE4B5A7BED3F02
+:10637000DBE13EC844F81D47D8EFF2790AB89272C3
+:1063800035BCDF482417F8CB2E63BE5A6FF85E2366
+:10639000D8FB822FDECAD562BB47F93989472B0A61
+:1063A0004370AE4CD0B135DBFF4016CC8FF2C50B3D
+:1063B00068EF447CD3103FF662C833DF2545E632F0
+:1063C0003B446F073E2CD46854FC16E1EB269E54E8
+:1063D000FDA3DD733FA75DA1F73B424602E74DFEFB
+:1063E00078716622D8A71D19C2DEF31A015F9B25BA
+:1063F0005F620E8CF32F5ADC0F1E3872BC01C6EDA3
+:10640000A0F302BE7DF875EB6AB0533AEC5EE4533C
+:1064100031BEECD0F0F560FDECD67BDF047F64D4B8
+:10642000C1EECD3A38758611E89FB6D3403F7FA0C4
+:10643000FBF7F004E8A71AFD060BEDB3A6C3778BB4
+:1064400088FF11B06F17756B55F7833CCCE5C5C25B
+:106450008B16128ED92F2CACF80E9E6B5C78310106
+:10646000DF3FCCCFED3FCCCFBDEDE2F878993F5F79
+:10647000CFFA8AFB6F4F9CDE4AFEDD8E3AC6F7BB31
+:1064800060FD9AA5013DA8FA35533FC7F3647F68C4
+:10649000B393B02106DE11F34C22E1987187DA5DE7
+:1064A00034917052ECFA32FA1D9EAF15EBFFD0E634
+:1064B000463C8EDDFF38151E87FBCF53E17164FF2C
+:1064C0000558FF87B6C24BF43F798CFE7354F00F2A
+:1064D000F79B8FEFCF1DAC7BD642F9EE6078C5C637
+:1064E000574BE1F7F70CF87B1BA4AFB70ACFB9EE17
+:1064F00022780EFA81FD7F7A1FF2521FD8AAF7C0C8
+:106500001883BAE83CCF287A269FD88370EF9C780E
+:10651000BE9D9587EB1CFFDE2887EC90676A2C9464
+:10652000EDA0E78C24125A01FB975223CA3911DFE0
+:1065300012FDFE3453AB92B3E27EA1469E7FD86833
+:1065400061F1AF26ABFF2CACFF124D57CBCF681FCC
+:10655000A70B3BF07C3B210EDCD788F88E0CFBC5EB
+:106560003C707DF9089C0B9B97E3FF0CBEFB091563
+:106570002B10EFD15EB1CD0FF9798FF37DE4E3A657
+:1065800088DB13233F75D9F257B31BBAE2E8B7ECA7
+:10659000773BC28C7E75D940BFDAC8CFEB72E07C06
+:1065A000E300BF674E41FBB9AEF430DE475927FC2C
+:1065B000022BE3F356321D604F8B785402E41782AE
+:1065C000DDB086DD53586F61E5FA5F27E1B917BA90
+:1065D0001FB214819CD9AD65FE221E073BCF611E00
+:1065E00034AEC902FC0EF27C97F3FDAFE1BDA7E724
+:1065F000578E473AA8FFE50FF11EC3DDE94C9F0D0A
+:10660000EEB3A13EAB3778CAE15ECDDDE9CC6EEDED
+:1066100095C309253176ECA3195528A73F5E395E4D
+:10662000131B27199FCDE4C21AE1FF94A3E570CE96
+:10663000EAE3D2F03FA13EDD63C2DF1BD3ECFD53A2
+:1066400039DEBFBAC680BF6351B577E2BAB9B05F71
+:106650004C90311F5BB3D784F09C5DC5EE83836F94
+:1066600041EE35EF1D87BFCB566F8962DE64B3D92B
+:106670005300F1C1FABDDFC0DF9F38F1F8C42C90A0
+:1066800083C793952CBC6FFB718A743AEFE3FB26AA
+:10669000B0F79D57E3B96ADB1A8B7F34FF88D04B84
+:1066A000F1F7CDED4E2F3ED707F89968F4801C5EC8
+:1066B00038E45F67F707D6BF199DA524A0FF06F34E
+:1066C00017EAEDA7F0F71DEBBB8FDD49303EE9423D
+:1066D000FA15FBBCF871EBB9FEDAAD8FCE83DFD5CE
+:1066E000AB6FE7F8E7BFF759AF29C6DF9B14F85F38
+:1066F00013771FF3F738DEC5F3C41119EFB9A47689
+:106700004516F88F4EEC3720BD9D583319EF5710C2
+:10671000E3D55358ED944F8F3B9529B0BE0BB2157E
+:1067200036FF76B67F15EFE9F811F8BDCEE83E2DBD
+:10673000E6AF0DDAA30910C714ED4479683EFD5A9F
+:10674000FCBDB7DDE90770DD295D11A02BCD2F6DF4
+:10675000A8B703BF64BF1BF7712909829F34F88E65
+:1067600001F77B07F719D09E1E7C979DCF1F71EF15
+:106770009F359A05F7DC067E390EE5DA6066740B04
+:10678000B3BF4D78CFE4E051FFD53C5E9CC6EFD15E
+:106790004C03BBEFC23E5318EC3EFAC4B843906CB6
+:1067A00073E3FBFD16BC2F883ED9F924698F1B7F4C
+:1067B000378974F1EF23F8FD0359FE0920A71FC89C
+:1067C000A3FD5BE1FB93D8EE42AEFF4A8C591192D8
+:1067D000CEC74BC77E33FDD9F85EFACCCD7E0FA86D
+:1067E0008BD747B03E60F05F8DF3F8BD8DF48C32EF
+:1067F000CFAF7A5FE47DD949B88E026E8A67B42341
+:10680000E3F1D293CDF69F021FF17439B49E9780C5
+:106810000FFC3278BFC03EB68EAB26EA993CE99CAD
+:106820008CF632DE30149327B87CDF074897833A22
+:10683000EFD3A097A2477584DDC3482D03F05754CA
+:10684000B076F516E6F710709CE1E7071A3B591E83
+:10685000E199E73EC89A6F85F3F31FA8CECF0BFFEF
+:1068600021ED2401FC33568F925057C4EC762DC293
+:10687000C57E8F6E8D4EC1DF0B0C3E3E11FD122783
+:10688000F4CA5EBC0776D5151AA0276D3197BF4FA5
+:10689000B07989FBDDC43D6DF17819C866FAB2990B
+:1068A000F8EF823BFE8F132585074BF1BE4A74FF3C
+:1068B0006B20CD52F69A587E3BEA8591F742EA2F3B
+:1068C000F17B82FFBBE553B05665809F6002E8D53F
+:1068D000D376B67FC45B2240BF6BD93C3BE003B8A4
+:1068E000FF82F84E835EC45B25281E4E4BAC3E9E55
+:1068F000CE84BC1B810FA01BE817BEA37D7F9E9D8D
+:10690000C3F63F76273F9417D4435EAAD057014978
+:10691000D6C07D0F271D4A02D0E5C9CE3CE772C81C
+:10692000F7712829B1F676E010C17B0E1438FF7399
+:1069300035FC2E92770AF805773BD5FE8878785E8D
+:10694000A81C40FDF35F98C6C553008000000000FE
+:106950001F8B08000000000000FFB57D0B7854D5A8
+:10696000B5FF3E73662633794E1E8484409824E436
+:10697000018430090F4141074810156878092885BE
+:10698000930710421E88B6175BDB0C24205AB441D3
+:1069900051D18B76404154B4414141037700A55811
+:1069A0005163D5566DCB0D88BC1F31A897FFADAD97
+:1069B000FFF55BFB9C64CE90A8B5B7F93ED8D967CC
+:1069C000BFD75A7BEDF5DA3BDF7C433FD7096175D2
+:1069D0002B42F41022CE6D11629810A3DC82F34298
+:1069E000D885C811FCF38DCA89DB3A5C8885F88D9F
+:1069F000AAAAF9DAB59EC82BEB2D5C1FE375467782
+:106A0000F1BDF1B5FF50F228B3214C0887FE3D5D82
+:106A1000880F311E8D7BEA90DDA70C461A2EAC093B
+:106A20004254AC75FA451AA56F4ECCBA53E685426E
+:106A300075C76C5C99D84AE3966F2ACA1291B21F47
+:106A400041F3AAD0E7559EEACD52870AD1F6A8EACB
+:106A5000DA84F6EB559E8F6AF3B81EA5EF27D6DBD6
+:106A60005CCBA99F0A7D3E277A6BD1C5B994B70A42
+:106A7000ABBD80F2562DDA45FD2E78542DF677B158
+:106A80003EAAF781B5A00BF8604D893A7C32A81E6A
+:106A9000D66994E3BFF7687257D1FCC2E977CC633B
+:106AA000A3E2F7D1FC4EF4D1E6217FFC9330B18212
+:106AB000F2EADA45D1EEDC2BE17DC2A1457B720121
+:106AC0005FB91E039EA1E318F0BC0878C620BDBACA
+:106AD000C54BF0AB7D48F5A0CEBEE64BD180DF982C
+:106AE0003D4547AEC1F7B561228CDAEC3B9CFECE4A
+:106AF000AD348F8BAB55413D8AD23D198982C6DBBF
+:106B00006EF97C2EE073BF4DCC7A91D2D2B7A747F5
+:106B10005B28FD46A71FF5210927356A7AF47CAE6C
+:106B2000DF3EB998F2C7DC9EC482A07A3FD6E92C3A
+:106B3000145F656BFF168D712AD6D8785D065E2EC0
+:106B4000621D34BF8B8D11FEE504978BBDDBB85FF2
+:106B5000034F46BF15C083414F546FA5DBA58FE39C
+:106B6000B31747115CD3B4E19E2EE864C183342E81
+:106B7000FA5B1FE575E67DFF710D7874E09B962545
+:106B80000CFC038F4FA46DBC97BE59DEB30AD193A2
+:106B9000E0D0787DAA42DFCBF6840985FA2B53DA60
+:106BA0008E28099C77FB14AC7FF13C8C57F67198CA
+:106BB00005E5C7F75E9FC7F30AC12BC129B52B7A3C
+:106BC000BF98D696EA0982DFC53E6D7379BE067D11
+:106BD00074CE9BE751BB374C605F5C4C237C4676A0
+:106BE000C2B101F819C6F55D76A66F6F1EE0D7B188
+:106BF0005E57C87A5D21EBFD40307D0B8FC6EB29D7
+:106C0000FF24CC82EFE50FDC94E5A6718EDF3B8E8E
+:106C1000D7753CCE9B87FD753C95FACFBD729DE53F
+:106C20000FD03A73BF659D8D4EC657B7EB8C6B7B0B
+:106C3000427CCB3A37EA7468ACF333AB3BDA8AFA7E
+:106C4000BB55B19C8A6AFB14DF7F8DCCBB56D0D07C
+:106C5000B536490FB56B23FCC0D78566DB047F6E64
+:106C6000271FA0F1BE273D58981E8E8F753F3C020E
+:106C7000F4759FEAF2B9019721EFFC9CF2C7EF5738
+:106C80005D02F9B1127EC40F2CE00FC7538B27733E
+:106C90007EAFCDB582FAF9B4F16F7F04FD5CDC63A1
+:106CA000730B5E5FF1FDB390A7F982AF115C6EC606
+:106CB000B854CEEB57EF19D68872F1E86057A6BBEF
+:106CC0000BBE1402E78A35AA691FD201C1E3D53E83
+:106CD00090E2C63A0C381387CD9A3AA8131EC84FD3
+:106CE0001FD409975ABBD09AF8FB12FB944141FC80
+:106CF0000CF04997E744FF3CC9C7D2A283F673C89A
+:106D0000FC42F98F51CF48FFD2C157CCFC7851706B
+:106D10009EE05019925F1CC237AA42CAAB43CAB761
+:106D2000F7FA9CF940E8F813D3E4BE31E058AAC35F
+:106D300071BB45917CE43EC5BF897E2DB5BAED4B54
+:106D400069FE2F8E11F3D04F995538AEE57DD9CE1F
+:106D5000EB2BB58A86B0027CF7703D63DDD45F43D0
+:106D6000581CE5C3251FA27A13EC417983DF1AF37F
+:106D7000094F93F030D2C55B9D8DC783E059DD1478
+:106D80006BCAD7EE4A6E3CEEE8CC2FC62FC9F46F23
+:106D900022AD7E38E0227FAA77B51E8C20FA49B258
+:106DA00068E169D4EFC583FF1B9DEB66BC0F2F26FE
+:106DB000FC16A8E92F1DA6F5B6ED563D9BD0EF9B1E
+:106DC000F2FC115F5F7A781B7DAFD99B21EE75775E
+:106DD000AE3F148E17775D8A4EA7EF170ED9C30505
+:106DE000C901A5CDF163EDD1BCBFBA84BB5B87BB44
+:106DF000D1DF056B6BF494A07A17446BF4D4207A3E
+:106E000029DD75A94EE431FC7C6A101FFF744F8F99
+:106E1000B12A7D2FFB7DAFB1164AC7E9FDDE6F7346
+:106E20003FB986E6EDDB1DE6D94CF3BEF0E62C0B50
+:106E3000DA5F78B3424F7FEAE5F4B34F53317EB463
+:106E400045D2BB31DE8834294F95598E3E311AFC2C
+:106E5000FFD59E69F5699DE56596822CE0799BAD2D
+:106E60006D2EE67D4111AB95B8CE7EC6A5B9B9FDB4
+:106E700085DD279F007FF8F4FE3E05602B177667BF
+:106E8000E769547EE1E321592EEAF7C27DC91EF07D
+:106E9000856D36F74F99DEEE89F260DF1BFD619C50
+:106EA00025E87FF755C335A41FCBF9523E4F93E336
+:106EB000FA9482CE7EA32DEE5F8F02BFF8BDCDB3D4
+:106EC0009992A57FCFE8198BF5613F778187B2D57D
+:106ED00061C26DE2272B78DEA5C263871C84721124
+:106EE000445FE5A298BFCF6F347F5F407C02DF171D
+:106EF000AE377FAF108DAB5A697D8BFCE6EF82F623
+:106F00008F2F11FBDAF869E2F37EF1D66FC24CF5F0
+:106F1000844FE70F0EE6C7A5B41FC1C79E57FCFEFE
+:106F200015C0EF3D2AAF33745DCBD3D2781D8F44AB
+:106F3000FC636E6B105E8F59843589E07ACC2E1C11
+:106F40004905E847089CABBE3D61FECDD4E4DEFEBA
+:106F50005FA59632DF4BB2E03CB8C305CE47FDEDEE
+:106F600039998A7ECA5617795B83E677D1E67DE444
+:106F7000E79057DF237E4DF58E8DF5378EA5791D71
+:106F8000BB57F5D47731AF33249FF9E3091EF728B7
+:106F9000C23F84F2CF9C4C2D21BC9CDE7C32B534A8
+:106FA00098FE15312B981E8D9466C2EB82AC89F445
+:106FB00018AD05EB09ADD7895FF37C0D783A55B173
+:106FC000A42B7A7814744FE5397F5705E4CE9A3DA7
+:106FD000363FE83362E3170FDF0AFA6CB6B940DADE
+:106FE000B57B542FE474B15BF567E21C6BFE34BAD9
+:106FF00012E7CCEE212E3568DD740E17E37CB9B0B4
+:10700000EB5262592EF73319F244ED9E873CA0DF14
+:10701000EEE6F15C9AFAAFF13FAF99FF9DCFFD200C
+:10702000F146F0818D27B2C0DF890F3E9786FD992A
+:10703000F5B51D79215A8783FE687E2CBF5FF47FEA
+:10704000C5F2A5A359F5FABBC0C39E343BC3FF07E5
+:10705000CF6F02CD2FB1737E349F3DE0CBC63C6B2A
+:10706000DC6D769CB3171DD179E0A7B4A089F989AE
+:10707000FAF9E4067F2D9B2888BF16EE9EBFC20951
+:1070800079A151F1400F286F56F9DC2ADFA0FADD13
+:107090008497C2ECBBF63B219F3E44E5D474BC3AD6
+:1070A000EA8FB3A8FEC2FB54CEEFDBF8D33FDA8001
+:1070B000D70D3611063C86476FD2C7637968913E7B
+:1070C000BF45CD379D56A0B7EC513D01B4DF1CE55F
+:1070D000C1F7B2D5B663C1F4351FBF507FF3D72BCC
+:1070E000FE401AF884B9FCC2309FCE2742BE6F5CC6
+:1070F00035757F02522BEB898BFCE672FCBC4EF39C
+:10710000A9D57FDF9AB9A617F073C129440BF6AB56
+:10711000B595F51D11684D051E2FECFE2C1578ACAC
+:107120007DF57FB24417F8EBD84FCD510927228463
+:10713000384BE7C63716D0FDA5C9C55DD47FB18FE2
+:10714000DC175B6DBE5E9063F76FFC8AF9C1C5DD2D
+:107150005A5F5717F4DBB95F7D4E4B12D280532034
+:107160001DDAE4BA11FB84E4C17B411F9B564DDD5F
+:107170004479E76B364842A2363392F70BF6C7FCE8
+:10718000A07E8D7DB2157C01E930C91F5EEC23E540
+:1071900084D5BABCB0755FFBE4CC2EE6B33ACD26FD
+:1071A000CFDB3E926FCC4D2B0E4F879C61F1450398
+:1071B0001FC2EB7527107C159DBEEA972D51F03D3F
+:1071C000493472DA5B3471FAB8105A24EA0B8F0B27
+:1071D0007016A24F2CE0C77B9ED7AB31DFFC898EA7
+:1071E0003BF06AD0832F56F837D3EFEA46875063D7
+:1071F00020EDB546A351D4A0A9BFEE4BE5B60F5480
+:10720000D69FD43E063E3D2EE0F7CBC8E931C1F80B
+:10721000DB77B87402FAABDE497A2EF5777E874DBC
+:1072200004A0575969BF503DDBE12FEC69E04BCD1D
+:107230008A80BC5C4B797CAF1D65F5FA83E0929740
+:107240002EE1919A9EC570BB60F51E9A08FA73955F
+:10725000DA21D7DB0E974FC079634B2AB5635EFB0B
+:107260000E8F75A4016FB156DE37AB9A8D715B5CE2
+:10727000E83F2AF6039E6F43AE454453BB868FC258
+:10728000FC0C4C87E443613A5C1B02850E7717F8CF
+:10729000F189C2143182CA77A81330CFF3AE5217E6
+:1072A000F0688B957687309B7702F49AB0D8B878DF
+:1072B000CC6F447A06CFFFABD8253CCFAF48BC801B
+:1072C000BE41F27A31F20DBDCB55867DE323BC8FF2
+:1072D0006B1D72FCA83D2A9FA362A443E7DBEFBBB2
+:1072E000CA689CC8BEDA24D083319FA861AF0BF076
+:1072F000E71C8B85E5B3863722D7802F18E51BD294
+:1073000025BD19F858996075817F3CAED3E74A577F
+:10731000B1A320689DB61E161D5EC50EC069BBBD1B
+:10732000F810CE9736FA8E73737FD25407F414AAEE
+:1073300067413F27EA68C764A3DFE90EC07741428F
+:10734000E978B45B2896ACC27E5BB85E1581203EBE
+:10735000DB6093E32EB81C2102433AC75D40F8E39B
+:10736000F697A3F97B8353D66B8892FBE7CE7429FB
+:107370002FAED4D3B57AFA83F9BAC7CCD7CFC7FE2C
+:10738000714BA9E4EF77A653BFD54AEB788826ABBB
+:1073900092DAED80EF893A97088405CDF78A75C6B1
+:1073A0008B40D0381DF52E3B45203E181F6EC6473A
+:1073B000E77A23B9FC445D12C3B1FBFE534C70EC79
+:1073C000EC3FC304C72BFBCFE2F2137539DFD1FFCB
+:1073D000C06EFA4F33CDBFB3DF7EFC5DECD2FA82D4
+:1073E000BFDCED227EC074D3CA7626BBA2FD067632
+:1073F0002FF1719880DCF79553CB7605F1876DE915
+:10740000765D9F0BA480DFFAC43A4E6B775D1A8FCE
+:10741000F66EE20B6CE7D0CB6B451BCF13FC02FA88
+:10742000BD48B6BAB97C97960DBDC89847873CF35E
+:10743000BB489F85F641D89EBF47631F5FB4B64DDA
+:10744000867DAAA9598D08DED707F4FD31B6CF177E
+:1074500079B0D7D5A01DF1BD9FEE5D9C0DF8D48409
+:10746000B5E561DEFBF7FE2D0FE7C8577B16F7C5C4
+:10747000F7AD549FE50F7B5B8D27A8BF7EC2E5B3B8
+:107480008CE84C9BF5FD1FFA7DEB9EFA5E98C736A3
+:10749000D83D482EAC59F656C6F178B021EF83E0BE
+:1074A0005F82F816EB43BBA6A96320DF7D48320F4D
+:1074B000E587EE9672C3D03EC26F4983DCF7E12CBC
+:1074C000F0899A61761754E1F0FC1696B7C38739B4
+:1074D0005C389F9FED93C1EBB3434EC840FBA2784D
+:1074E000A6E754F1AFC96D1B42F64FE00F35DB68DC
+:1074F000BC6AB575F23885F7D131F0A99AB7BF7873
+:1075000047D75F13819F5A8C4BF0785FEF27214359
+:107510003B897A9AA3F5BEABA8DE8C9B9353A11F3F
+:1075200095E8FA9998484019C9FC6810EC20579ED4
+:10753000DB520F7A4DD134C0C197ECF0E0FC1A98C1
+:10754000221CC971D8D0FEF4A934EE57E916C32E17
+:10755000AA60DE03F4353DDFAB69692C9F93FE38EA
+:10756000D0D13F3BAE25C3FB77F00BA3FE8737DFBF
+:107570003A48EBE2DC30E479BBBDE936CCB3AD3A56
+:1075800092F54798F3D0EEC99BC3022AEC8AB6C89D
+:10759000D5D0E73F8A987BB007C1E3FE282D228330
+:1075A000DACD9A79C32AE495FDF1EEA5A0E792D64B
+:1075B000E1C0E7D34E2D2683C6AF72687D1369897B
+:1075C000E7FB68D93138E48BE3259E44F1A0E22E35
+:1075D000E72FE753A2C8F10F476949E8A7C4D2F2E1
+:1075E000C455F8666D617B8368E8C1FD9CB78B8AE2
+:1075F000AEE47F030E47F475ECB3896B2FD3FAF634
+:10760000AD8DF1D4D37CCBEF9E39B796D2F996E20B
+:10761000C4806A9A7716D655E52BE99B4CF2F3792C
+:107620009B3EEF65FABCADAEACE0FD1C3AEF7A4391
+:107630005EF985C2FA20FF50FE155FACFF5ECA8777
+:10764000592E7D300DE7D6200BDB493684D3DE2260
+:107650003DF25D7D9E8FD3BE73C4F1F7D5F89E14C5
+:107660002EDB273D6CF1C37E503C7637E3E9C99AA7
+:10767000488F4A639508B71D725099F0B25CFCD9E7
+:1076800098BFED69A575156668D7016EF3E22DA95F
+:107690001FF03CB48153206F8D92EBF8167993D78D
+:1076A0003155B86C2C94893516C81F535D7229F377
+:1076B00015B93FA609AF0DE3CD101AD7FBC305BB23
+:1076C00017FAC41FA00BD1BC670A1F7F9F2DFC9C1B
+:1076D000DE2A025CFFC7A295F306BC893EE6254878
+:1076E000FA38D95365F8DF8C79BF1791D76719AD90
+:1076F00063CA23D999AC5FADEBC1F0F9AE794FD134
+:10770000E986F6EF3CF483FD3B9DFA997A63C8FE67
+:107710002DEC61E033F3DBF6514B7B87FE14994C83
+:1077200070B85E47E9F5DEC5AC3F15A991C247F8D0
+:107730006919A5FA21771CF22E4F48A075DCFDB916
+:10774000D4837EB75CBC3D84CA7F374615F5DCD256
+:10775000CBF2D464BD9FC9BDC79F869DF5B00824F8
+:107760000CA5B9175DD65E8FA1F94E56B735C45238
+:10777000F984DEA4C704F1BD1B12B65BA1D7DDD826
+:10778000CFFC7D62AE59DF99241A55C079F250734F
+:10779000BD7D800FD1D78A0CA9B788016280EEDF4A
+:1077A00063B9FB477A1FED132FD9E10B793543BB42
+:1077B00007705C3AE9B3B9185758E57A6ADE51D9CF
+:1077C0009E778CE42C2F9DDFC7EBE8840893F208AA
+:1077D000F2A7486E407AA6CECDE9393AE7517EA1AC
+:1077E000CE23EB67143F807D56BAFA732BF072B745
+:1077F00053C2F96E67AA1F76B58AA6C6F1985EE5F0
+:10780000AEA68348CB03C5E371CC2E38B4E420D2B6
+:10781000BB3BF4B6250EDD5FC0F3BF5DA7D3DBA392
+:10782000A6DE3488F6C9EDBBA5DFEBF63E53A74DC7
+:107830004A40DEC6F9EEE8A8FAB22234DA22CFA82E
+:10784000DECD58B7B7F9E8C1785AE7C9BA113CFF9D
+:10785000D3755E9EFFD9BA099CFE3DA3F839AE27C9
+:107860003E67796CD2B6A3D614AA5FE455BCD8B7EC
+:10787000D77A85DF4F74B1DE26CF81F5740E601F95
+:107880008F1934F5F13B30E90C6D27DACFB871511F
+:1078900011C6993CA2C48A7A33BF16223EAD934EDC
+:1078A000BF8BEE8DF557EBF83BBF5761789EDF1B22
+:1078B000CBF06CDF911103F960E9CE8C9E48896FA3
+:1078C0001A7A6F04E0D77ED9C2F36DFF289CF58E3B
+:1078D000D0F64B770EEC897A6709DF2248DE3CFB55
+:1078E000FC7FB883CF95B3714D5F7D02FEF657C91B
+:1078F000DF48B239F118F85FEF5E1ED0CB055DCEE0
+:10790000263D2302E75F8D6E57047F42FE6CB8B4BC
+:10791000E70E7F21652CF617C673139CC31C19B99B
+:10792000C787707F477E46FDBDFC589207FAEFB9C6
+:10793000ED8FA463FCAD4DF33F798CFA3FEFB7F8C0
+:107940006C744E9D174D175E051F7E2A92ED7B7756
+:107950002B342F9CC39B7B713E47B1862FC3392CA0
+:10796000FCBCCF7314B77519F1ADAA171FED057ADA
+:107970007C8D603082CA5F5B1BC17CED359BE7C8A4
+:1079800032F4F7B8ECEFE9FBEF3CB60BE97DD50537
+:107990007752FA65461CE3A1FC814503D09ECE795F
+:1079A000914CFD3DF78A1280BF6AD0BA7D2B926957
+:1079B0007E83371CB5F4A234FF29A51EE9C03E37EB
+:1079C0001E82FDF96F196E6E3F645B9A9A826DD9C3
+:1079D000CBFFC9757CFE9BE582DC759F8FED253A58
+:1079E000E583014AD3998D34D7B0D48F0A348663A6
+:1079F00023AF6767F3B4F76F155807491E98778967
+:107A0000DDC3E791DFB711783EAFE57858BF2BF6BD
+:107A10003D0A7A3BAF257A703EBD4CFAFCD5A87F73
+:107A2000C4CAEB7CE5A9F7A261DF89213DD909BF72
+:107A3000487EDB78D4AFEEE316F087F579E2FA09F9
+:107A4000804FCD8E9D1BB99F2A8707FA6EC5CE4BFE
+:107A50000753202FDE203C99A0C71D32FFAB42AF59
+:107A600047A5A5566CFC52E65B8A395F4CDA27FCC9
+:107A7000FEA24CCA498FE8E7A068CD637EC924EE18
+:107A8000EEC4D7AFA818E5EBD37CC9B06F1BE727CE
+:107A90009D7BA9FDB065ECB27DCBD85B53192EDF81
+:107AA000F3DCB3EBE797D1DF2376E173523F30DFAE
+:107AB000C09EBEC12ECFEBCDC467402FC6794DE32B
+:107AC000E6F593EDBDE0AF29AA326807C123E59141
+:107AD000309637BEEFF8B36256F1F96DC85BB5E189
+:107AE000922FF2D941ED5F88D2AEEE370C76327923
+:107AF000DE0BAB3B17F2C8E351DE6BFAB1BCD59697
+:107B00008A35D0397A1DE653A392FC9511247F451E
+:107B1000C67DAF733410E52D42FBEF5B7F6C04CD67
+:107B2000330629F1EF68A486DE455A4897FC397D73
+:107B30005B13F8F34361923F470D61BE64AC33744D
+:107B40009C03C40734E23B6FD039A3113F181739A7
+:107B5000C6CA787DDD527590CEE522390208DA1A60
+:107B60003B94F3DE28826361A42AB42EF4472325D4
+:107B7000BCCDC73AC7274498EA1525C4DAB18FBFF0
+:107B8000EFFA551D4F6AB83CBFD47083BFBA137467
+:107B9000BF7DC8FAE57A6F770E63BE3A56F97EEB81
+:107BA0002EB215DF093C8F8BCCE773735CE4942312
+:107BB0009AE075D4E17BE87A43D7251CDF4F8EFA33
+:107BC00089227C16ECC7CFED6C776BB6B53EF75BC0
+:107BD000826BF3A25C0FEC472FD3BE70809F4EB533
+:107BE000B39CDB0CD992EA37F770715CCB6BBADFD0
+:107BF000DC375B6FEF147CBE34CFEEC57EF45E6184
+:107C00003410EC48F5D26FD26C5BF216CEEBE6E5A1
+:107C1000291E9A8150C1EF69CB7CE497FCBC5E09B8
+:107C2000DC0A7F81EF73BB40FD75B1FED5E9945F3F
+:107C3000F78B0C9ECF47A48FD762BC8A70E65BEBB4
+:107C400062BDC971049F97FFA1F279B22E9FF29194
+:107C5000CCD7D96EB36E8A37197EAD041D6FEB3663
+:107C6000CAF25EB093A23C4DB6FFC426EBDFA2D7AA
+:107C70004BD0F1FBB14EA7B4FF993F689323ACA062
+:107C8000FF77FB95BEC6FB467893E1177AAC3C9331
+:107C90006D98B754DE90C6F4A4DBD366E9FCDCE84B
+:107CA000170D1CC3214FCB9FD9F3373B41DF332A3C
+:107CB0009C47211F7E54B1220A7AFD0C4D0D842170
+:107CC000BE6A7A91B743AE4BC7B85E396EB9A11F91
+:107CD00006CA00DFBD6D0E712FCBFF8121C1FA9660
+:107CE00081E745FABEAD6E1AF360B07E5D6927FE8E
+:107CF0003318E5723F57456ABF077DD5EEBAE1C13B
+:107D000060BDFB54F94379BCEFF471CFD5791F3CCA
+:107D10009E09396F02A7C6B81DFA11F049FDF6D5C4
+:107D2000CF73DAEF3E0BF0DAE494FA92B5EDE38527
+:107D300094AF9F3580CFF709531D5ED8F5DA77846D
+:107D4000F961AFAD9F15EEC5BAEAF744F9615798EE
+:107D5000A7EF1BD2BBF8BB6FBB8DE9ADCAEE7F6648
+:107D60000BB5ABDADB9FE989E895ED96BE57236446
+:107D700079B4376DE55094F764FA79CDE68EE1F287
+:107D80003755C1E5E181AC5882779B533B8575132C
+:107D9000BDB2FDBCCA2EBF1FD1E912FA25FBFF966A
+:107DA0004471BF42CF6B3F8F677D4F58BDC9F39180
+:107DB000BF7D20AF47B3CB7D216AA47E78C425E781
+:107DC00075A4399EF785418F478AB7DC939580EF7C
+:107DD00024AFD2FCFEB24C0DC01F6ED09F32F5F224
+:107DE000DB5751BB4F5F55D96F33E7D78B0FE3FBA1
+:107DF0009C15D51339ADBC6B329FCBF51FA7EEA2F6
+:107E0000F284A9A7D8BF6BE07F4E95D99F9A98E9D5
+:107E1000553381DF5CFFF68354FFE1D9271600AFAD
+:107E2000C333354726ECDBF6D697FF4CF36D5DFE8A
+:107E300027D6A336446B11F87E71F7D35CBF66C5B5
+:107E4000FF2C807E50639574639CDBB53A3DBF91F7
+:107E5000A9C5A2FFAA15BF633D2222B745F2D7BB31
+:107E6000BE1F3F3AD3BCF96585DA2D0E6FAEE154E3
+:107E7000F5E7E1FC3BAB04A2950C862BEB75E75CC8
+:107E80008168E047B348B972F1D610BF315092A86B
+:107E9000DB8BA8DDE226558F57F4DB41A7A1F51750
+:107EA000D377AEF73DBF578A26F93D76D7FDD73059
+:107EB000FE4500FEAE33CF646E023D9CDFF9745682
+:107EC000B09F3634BD72BE72FDE7F47D738EBED8AE
+:107ED000406FDBC24CF6850BCF24EBF426E9E9C2F8
+:107EE00033D9ECE74ED4F7D905C5670947BB5F081E
+:107EF0008E67109EA6E11C97E36D1A0EB9FB619D7B
+:107F00002F2E8E6F1A0EBE67F041E168CA63BB4127
+:107F10004E531EF464837F8AE2A62CFEEE6FCA42A3
+:107F2000FB972DD20E63CCA7F2B9148E7BA2B5F0CD
+:107F3000FEAE7C6EE026E48D71EA9D92EFD43B2587
+:107F40007F095DB79629EDE8A44FE61EA7B3A43ECE
+:107F500096F4825CE49365DE29F30B3794D8E16FE5
+:107F6000AFB7C9BC6B7D89FD18E6F73569B5C44F5D
+:107F70007374BFC5027FA9DD0BFBFEFAE5E11C3F70
+:107F800031DB3ECF4B69F67ABB695C030FFDFDE642
+:107F9000EF8BF4F9F40D890BEAA5B6ED0BC339F6B6
+:107FA000A4E8328E6049A6B4E33EFB6C477C91AAFC
+:107FB000EBDBC26DD0A15BEA1B8CD78FED065EEFC9
+:107FC00048A1F92FD6E3A55EB648B8FA9E957CE3A2
+:107FD000E57C2D05E7D505C01DE75C2CE57321EF99
+:107FE00049BC1979035FA1F05DF1F18214D8959F26
+:107FF000C894F6C7507C2C8F1ADE13E5065CCFD4EC
+:108000001DCA00DC8D759DA8F37AE968EBB4BFAF9B
+:10801000CF77688C8F7C47307DD76F1D7288242086
+:10802000716EABD58325D45BFDF743BFA8DFAA36BD
+:10803000F904973B80977391FBDF41BD051B620BF1
+:10804000A00F18ED17AE2FF29607CD7BE056335EEA
+:10805000063599F3837799F35B71060DFBE7DBE552
+:1080600007CCF92187CCF9931FDC7133B64F85EA31
+:10807000BB5F85BEF3E7F187704E9F7AF99568E0A4
+:108080006BF15FCB0F428F0B8D67213C2AD0737C45
+:108090005B14A6972BE25ABAE14346DC06766230BF
+:1080A000DD540ADF416BDA95F5CF8AA69BBD4467A4
+:1080B00055CBDECF907AB3EC7764D35A3BE4CED085
+:1080C00071BBE33B22D2EBC63E2A1921CBAE5E3612
+:1080D0004E7C8AFED6BC371EF458F22B85E59B9267
+:1080E00097B25F07DD1CDD3EFB464E6F9EC0F03051
+:1080F000EC920B9B954014E55D2344877F1FF18B29
+:10810000A50D21F19F6B42E282D699CB17EEDAF7EB
+:10811000FF104750E17882E32EAE8C67F41F805E3B
+:1081200059794AB07DAAF2A96FC2CCE5725DF3F528
+:108130007518E7ADF05DCBF17B57CBAAE238FEA313
+:1081400073E9A84B3B8573CB3877AF5EB75195F297
+:10815000BCB784FDC891768E8BAC76884004CDEB9D
+:108160005094DDEBA2EF97D647B1BCB280E45CE857
+:108170008B940A27C74D7A62D0EEC4BB2ACB65D553
+:10818000F1121ED5BF51FCB01D57C3A88BFC933212
+:10819000BF4804D8BE0B3AF206AD03F80BCE8B46AF
+:1081A000A95F565903FB009F8E7368ABB95E15AD8E
+:1081B000F3A338C87BE6EF35A28DEBD7EEFA262C79
+:1081C000F87B903D9AF55E43FF5675F94AFD653898
+:1081D000CB4F74208483BE6CBADCBEEE1E92236843
+:1081E0007D2B0D7BF85A29DFDDB2519E63249F67FA
+:1081F000014EEBD6927C86EFA46F20CE442C0AF77A
+:108200004BF95EEA0BEB6667B15CF4F23F5E0A4045
+:108210001F697B4861BBD2BA7CD9EFBAFBFA7339CC
+:10822000F8A7C2E384B11CB66E8A51DE87F5914F80
+:1082300030C564C8F9FAF71E6EFEDE4BF566C13E26
+:10824000221E74B27DC490FB0DB9BE2E56CBC91A46
+:10825000D6B9FE75B16D51F0BB898AF8EF25B76CC0
+:10826000D6CFE3365A3FFC2AC795E283F08F19F543
+:108270004666C97365F858EF16BD1EFB5FCA2D53DD
+:10828000EEBD8EE655FEB0C50D7BA18107E1F5661A
+:10829000010EC7D73A0B4077C3C74A7BD9917CC937
+:1082A000E723860A8E371AABF73B36CB624A93C276
+:1082B000891EA99FE345D21E1F35B498ED9624135D
+:1082C000CCEB2A6E65B2DE4FB9BDF8F7A3BB984F71
+:1082D000075D144AF9FBF86DCA26392F2FC7270E00
+:1082E0007FC0C9F6CEE3FA3964E081E86818CB0FA5
+:1082F0003A5F8B0DA19BB5A0079C87A00725986EC0
+:10830000CC74718B22E12BEE93F2F7BA589937E8CF
+:1083100082F43FF1BFA09B22C1F0EF4E0F34D6DBB9
+:108320009D1E4874B00874D0512F840E84D53FEC44
+:10833000DBFC42A52362872B848214ABF021CE178D
+:108340006724C3EB1EAB1FB178BDAD122F7DAC927D
+:10835000EEE8B4F18517707D2FE27D4B1E5C28BCE2
+:1083600054BF2445B07DAD1FC9553171DC4E204549
+:10837000588E0ABB13A5685F1223FB2FE92938FE2C
+:108380008EFAF35AE274E6361CFE5EC17205DA47D5
+:1083900017707B9F45B6F75A29ED9B21F598B69546
+:1083A000611CBF5C72779F2CD0C9C4B1663A39A2F8
+:1083B000D39591DE94EDD68D759E24F083D286FE02
+:1083C0007CDED43B8BAB77029FCF47B0FC59B2EA3F
+:1083D000C79386617E2FC47B80C23393B7B33FA817
+:1083E000B461F64F3E84BEB4D5C9DF2BB2B5F559A2
+:1083F00090FF15F7DC9DF4A174C6017B12B5D79AE6
+:10840000A69C7F95D2C9BEEDEF409E983C5DE5FAF3
+:108410009385B43F8B0639CE24DFE7D624EA6FD2AA
+:108420002885C3698E3A5DA9B7C10FA4E3F7A92CCB
+:1084300045977FE43D8192557DB2D273E13F21C9DA
+:10844000B80B39FD53A3FE186503E4A5BEE3E4FEB3
+:1084500033EAA31FF47B3A4BCA55BFD5E162E40966
+:10846000AE5CBF7C75D8D18C68A4B64036A5E9FD5A
+:10847000C7BE84754E4C17E3D703EE77AA6213CFBD
+:10848000B7AD84F94254961BF4AB9142CDFAE3D6D2
+:10849000FECC278F8E693B7A37E58F6E1E24ED8CDC
+:1084A000BA7D61BE4BB07C70748CE4776D9B239871
+:1084B000FE8FB85AA3E2A43D8EED0D653A497CB615
+:1084C000ACFE7EF8B9CB22ED47717ECC7F681AC72F
+:1084D0002794AD530361B807B0C66C6FA88AD4DE89
+:1084E000C67E08B51B84DA074033A0A3F2350AD351
+:1084F00061DF7A8F3D99F99CE2C2FACA2303FD70CD
+:108500000E947B9C1CC77C85FDE06B82FB70D8B908
+:10851000050789B5676B9F004E258D25ACEF46E4B6
+:108520006ACCBFFAAA0417EC179DFE26C25E0BBEEA
+:10853000646D4DC6BEFC55969BF13031CE9515C984
+:1085400074EDE4FB11476DAE2CCCEFE84AA705E7CC
+:10855000EDC41592BE69DF39708FE11EAB08073F8D
+:10856000D89A25FB9DB3DC5ABC91F2BD1DC21A15E9
+:1085700007FACA67FA5ED85FFB2DE675EA17620450
+:10858000E489B2356BE5BC74FA10D696C2781AE766
+:10859000D4E6B402D8013AE4DBFE63DB01C70EBACD
+:1085A00098AE303DD07A0EC18E9CDEBFF432CAE95F
+:1085B000FB3ED0CBC4B1817E881B2F52AB38BEB6F8
+:1085C0003D4978E0776C176D2C8FB4933C02BE6701
+:1085D000F019839F105D781D899DF8DE5247532264
+:1085E0001EBEB5CEC1E9B3752E6125786FAB4BE2E7
+:1085F000FC0B756E4E9BEA72F8FB8B751ECEEFA8D6
+:108600001BC1F997EBBC9CDF553781D357EB8AF937
+:10861000BBC1AF083ECC970CBE63F02783BE0C3EB7
+:10862000154A577309CCB81741ED991F1A7C10EB06
+:10863000B01474F22703CFE94AB12F09FC50B4CE2D
+:1086400006FF2852CF3DFF0AC1B9BD2292ED22EDAF
+:1086500042F2C1F648079F07A976B10BF689FADB0B
+:10866000BC47EF0E3A876FAD508435888E7FBCC40F
+:1086700029AC41743C6F59AC293F67D9FB6FF4A416
+:10868000FEDF8DD172B3691E477E79E2F13FD1F7EB
+:10869000DFFCF24C26F04EF3D8FC08C6BD2B5C9FE5
+:1086A00047AB9CD75D769697FA864B7DAB6FB8D477
+:1086B000B7F0E3088ACF3DA2E3A3242DF69DA7B12E
+:1086C0006FECAE9B47C04EB452DE4BFA04F8A3F2F7
+:1086D000BFE8F82B5D16C6702D6DD0F76B70DC36D9
+:1086E000C1F558B260F94EF10A01BFD7B15FD803A6
+:1086F000242B88638AC3AF407622E56B0EEC98ABDF
+:108700007FF711E47665D92196B3354724C77F08F2
+:108710009FED5C707FCAB2835C4FB4F636C56F467E
+:108720000CF5DAC13740E3C05F69CE7E81FD2E1AB9
+:1087300015BE7F54AE7F2F5FAD98E2A26764ABF2A7
+:10874000DE459695D3F359423F471AF9BC32E89675
+:10875000F808C7619637E6DB1704F1E752FD7B594D
+:108760008EC514A7797F969DFB398FCD49FDDE9B81
+:10877000936E9FCFFCCFCDF7058CFAA53905AB6082
+:108780004F2E5D83A8A6CEF625D9567D5E2EA97FF5
+:1087900039E85C8BE2F8A22ECF07439E39855F470C
+:1087A000F2FC59EFAA7CE1B917E08FACFC73189F7B
+:1087B00053958375FB4AAE7FF8349683BC91CA709B
+:1087C000C8E112FF85CFFD351A715DB53BA4BD9799
+:1087D000D2A3486BEEAA60FB5E8D87F6491CF8AD0C
+:1087E000D9EFFFFA0B7FE6FB9D84B0143D6E98E352
+:1087F000D46A767CCAF16BB0C7F986727F1C5F1DA4
+:10880000DABE56F99AF557422CC3A768CF97893C30
+:108810008F9D9712C1E76AF7AC4CEC2A8E28B41FE3
+:1088200023CEC1B0FFD58A359FC3CF597BD7849360
+:1088300092DE65FFA1ED1ECA8E4A38315020C6EE89
+:108840002AB6935805C79F2CD5ED38EDFE4CF6633C
+:10885000772777D7AEA7462492B55BDD3188B3BEC4
+:1088600028C484AEF0F449B6946BCFD33E823FFB6C
+:10887000E23695E5CA8BDBA2783FD46C7BF020E230
+:10888000046B9E52D8ED582D5A38CEAF66872A1CFD
+:10889000C1E71DEC47F1DDCF73F173514B405F8BA6
+:1088A0009A14EF669A4FBBC31DD323683EAF80BEB8
+:1088B00088341787350D47FFC6FC9F077F0B92371B
+:1088C00017353FC8F18D54EF02CB37BF8DE0383CF0
+:1088D0003AC9DEC13CCF6E18C2FEF5454DDB6B5880
+:1088E0003ED816E182E9E98CCD7C0FE4803EDE8142
+:1088F0006C298F9CD5EDD1675F50591FC23CB12FB9
+:10890000CFE871B846BB37F5766F664BF9A7265BA3
+:10891000EE4FA3FEA2A6A3D1FDA8FEC95DEF73FA98
+:10892000BEBE6F1645B6F03DCF933B22F89EE0C920
+:108930001DFF39FE351AEF7CD3980425689F9DC82A
+:10894000B6C97DBA41C62FF32517D6139A783D676D
+:10895000B7A528AC2F03DEA4B79FDDF112DF4336A5
+:10896000E4EB1F1C2F384BB186DCA3183D08728D39
+:10897000A355BFD7D1A6DB63FE6FFAAFD1BF27598E
+:108980008AF571E43D0D61C46FB864BD2235B72727
+:10899000F6DDDCC1EE99B8972DDE927197A2B7FB98
+:1089A00011E87F73DF8D67BBCB529BBB27F25F1C47
+:1089B000268595E0337788CE57925A87C1BE7B349F
+:1089C0004DCA15863FAD6AB522BC04BF5E44673E02
+:1089D000E4FDAAD06007C949677C3D5661F1DA71B0
+:1089E0003E46D9992EEAB73B37C1BE75C42E7CEC02
+:1089F0007F7BD129FD27E9D20FF218F617A5557113
+:108A000081AC78D8F174BAA99A4AE541F453B529F2
+:108A1000900539EA9C5DDA2B510EFDA9AA40D6AB30
+:108A2000D7E914FDA0DFA369AE0B2CF7EE8C12D0B2
+:108A30003F2CAF4449BBC8D3CE4D6141E776BF1C44
+:108A40008B1177C7FE4ADF66393FCC0BF2FC227BE5
+:108A50006316E45D63DC45D18D3CDE397DBC45E1C8
+:108A60008DD29FA3C711A23E8F6F13EC776A7B262E
+:108A70008CE5E633C92D2F63FC33CFF4E7B887A329
+:108A800069FE05BBB8DCC9F1E795CF860530DFD3B9
+:108A9000CF44B15DEBB44DCA63A7A312591E3B147A
+:108AA000F5F05CF6633D15A6C02E745A11F62494B9
+:108AB0006FEEC1F24065DD32F6D754127B811C4B5C
+:108AC000E904C87FA737F7677BD1E93755BE5C411A
+:108AD000DF57E3BB261AE7FE8CF58008B6239E79A4
+:108AE000F66FFD83FD3B465AF994D93E66D083511B
+:108AF0005E9423F960518ED4536EC871715A1DD1A2
+:108B0000F4703AAF53F207C203EB81B41F1361EF65
+:108B10003FD2B43B5189049C0359FF09B86F95FAC1
+:108B2000D6996D36F65355BE12E5653BD4DD57F147
+:108B30007DC94A55CAE3951679DF50F9E556B6FF67
+:108B4000D43FE32C003C08DEACDFB66D56F571E493
+:108B5000B8A7B7F4917E8D809E7F7910FB3526C62D
+:108B600089795359CEDA9007B85E7A2A82E3FE6992
+:108B70001C2FE2342A7FF67309CF9805AC27D0C1A9
+:108B8000CDFCB94AE7CFD5775F1383FB10E25D9543
+:108B9000EF795CB27A7A82FF86C2EBD11C9D3FBF2F
+:108BA000FC38F3832ADA37880F5BACFB13173FAB33
+:108BB000B05CB978D5358F30DF7DC726702FE25C89
+:108BC000D383D1C1F8A8CF91FCB0B3BD87EB2FA65A
+:108BD000FAB2FD5BD13C9F2D360FE6138AC7EFDD5D
+:108BE000FE59F507B5AF6C22F922EFCAF55F122DD9
+:108BF0003FFD33F8CB3627FB5109FF7C3FEAACAD94
+:108C00006901D67FF67927F39DB3B172DF9FA4F394
+:108C1000D4978DF9DCF46BB6CBFC619AC039B4D033
+:108C20006FEED798D7EA1C9BA4B7784F0CFC44D5BD
+:108C3000840FF447F8F911B77FD7C6ED43D7B34097
+:108C40006FD7B14F9F8F60BA39DB4BE2E5EC0BD9A0
+:108C50007C9E1D8D95F44EF34D85DE743656A6B878
+:108C600099047AA874497A383BA689ED026795ED94
+:108C70009C1EB5C97695CB747F3BD15F12E807B4D3
+:108C800009BBAA634D0BE419F0F9E1059C06704F8E
+:108C90003BD48E0E3AC5F9D7AAEF33E31D05F6EBA8
+:108CA000B09FA789EFC76BBA3C59B5ED4A7F25F055
+:108CB00054B54D617FDA7F19FDD0AC130C3F00D164
+:108CC000E5629FC2EF222C6EB86D11FBD396ACBD4E
+:108CD00015746FAC63B17E6FFCA8A2F27C8E3A690A
+:108CE000FFE45E399E01DFDFE7281DEF75B88CF3E6
+:108CF0008BF6F03B396E4947946DA4FEAA1A943561
+:108D00003C4E9AA1E7CAF5197022B0D861E73BAA98
+:108D1000DFD3EE6EFDC63CBB9BCF319DCF1F4D9385
+:108D2000F793DBDE96F7CC2F7D3D2426EE5BE44106
+:108D3000BE6160F487B863D020F5F322F81CF635E5
+:108D4000ECEB34CFAC0D66FF4ECE53E6FC806DE607
+:108D50007CEE0E733EAFD99CF7BC6ECEFF09E30EDE
+:108D6000EB8413F46FC43542FF460AFDDB1D26F584
+:108D70006FE4A17F2385FE8DEFD0BF9187FE8D3CF0
+:108D8000F46FE4A17F2385FE8DEFEEFE124E55BAFF
+:108D9000BD1478E0B8BADD4E233E81F7CBC5D98942
+:108DA000CC478555EAA51717E5B2FCD8616F9AE262
+:108DB000607B93118F9518AD85F7471C80D2B22A3E
+:108DC000398DDBB11DBAF6556987AE2A7046C2EE01
+:108DD000D1BAF2E42A883DA7A3B418D4BF686BDBEC
+:108DE00002F8562F3BC07EFFD6E5EE77AF93F863CF
+:108DF000FB8B115F5582730F7C9BF4251977EE7105
+:108E000004DB5343FD44624D501EF2D33A733ED40B
+:108E10002F04BEE635EDAB46C6C76F6C6DC9E0FBEF
+:108E20009F3EE3E0FB699FEAF63B31CBC1F298211C
+:108E3000CF23CE1B70597A9FB209E795A77F1CC339
+:108E4000B9FD50A6E97E61685A767908CBF31DF921
+:108E5000358A05E3944F5FBE8FF56ACDCBE7D2ED3F
+:108E6000FADCB2D75B4CF3EEEF0F37D1D1C0AD7166
+:108E7000217ECC5EA6FA8377A587F8310798CAA72A
+:108E8000AD1962BE8F5F7C8DA9BCAFBD236ECFA133
+:108E9000FBB9E4FC5CB2CEA5C8025E6F68BD54C5E8
+:108EA000F327F86FC5DB524E2DA773C61BAFBF2B40
+:108EB00052007F9D7732E057D1648B859DAD4C3F4A
+:108EC00087C432F3B95C61153E575C27DD55B88421
+:108ED0003796DA7F696D4C653AFAE547A92A8168C9
+:108EE000D180963CE8AF8BDE7C7238E8AA5ADD98D8
+:108EF000EAA2F23B14FF165C203F13B73D712495A4
+:108F000027A95A497FC273AA2D70FF1CF0D1ED1911
+:108F100002EFA47CBAE6A5688E1FD4E92FD5E60A35
+:108F2000071D6C6C54594F81FD4C8DEBA4938D8DB6
+:108F3000F1E1D06B2AC6283EC8C7065C0CFA08854A
+:108F400007C9EFEFBA69BD970EC9F7948C752E75F6
+:108F5000C9FAA241B637DE0730D67B5CD7472B373C
+:108F6000BE91753B7D3FD77F5F9E1B7EDCBA5DBCAB
+:108F7000EEC5966D5B92297DC7A1DD85752D7D7B44
+:108F80005CF4481AE7CB6D32AEFDB3754F3EE1237A
+:108F90007E7A77E39376E80F9556BF9DDFCD7966AD
+:108FA000A31DF10ED76FDDC8DF176C2D617B8071BB
+:108FB000CFEE941197ADC3A362ACB2C145EB3CDEDA
+:108FC0005FCA8515E1329EA6481DF54602D6B55505
+:108FD000C9C7BAA6176FB7E3FD8187F57AA1FBA6CB
+:108FE000FDF0B4A21EB07B35291CC7D4DD3E99111B
+:108FF000E8CFFB64DAE5344EA75F1EC87ADE8782CD
+:10900000B42F9C23B921FAF56155DAF59A55F94E3A
+:10901000983D90300DF2C25EF96E45359D43230AAE
+:10902000A0B70B7135A5C5A354139DD7164698F666
+:10903000C12C11B4AFA8BF9B452F537EFAC40C536B
+:10904000FD99D30786F89D0B3ACB997F5D6D7A8F9A
+:10905000A6FA2E9F5B61BBC758F3774AEF623ABB13
+:10906000D1D4BE5A4C35BD47B3E8A9F718CE4465F4
+:1090700076C4E154E8F758666947F5EFADFC9D16F4
+:1090800062DAAF7D333C7F92E7A58DFD09863D7D99
+:10909000167ECFE8EABC0CEF881745BC30EC1D9A71
+:1090A000591E69613D55483C54EBF6A8EA1C698F8E
+:1090B000AAF6B5D8118F4DF0B7A610486A1A15B6A2
+:1090C00037527D474A9CCCDF85EF3BCCF752D0DF4F
+:1090D00065941F524BB0BF42CB6B68DD38176A6096
+:1090E00047623BD884936C0733C6D1FB37E834F42E
+:1090F0007D80D0FE060C7033FFAEDCBAFD602F829F
+:10910000CFB4E2D87CC49D54354DB195E45E496F2F
+:1091100006FFBF546161BF7EFBE1034C6FED155646
+:109120008F8C4BFF76B8D478A5DD35940E17D0BA66
+:10913000E07F5EB043F1F815590FF0E905FA0C81B4
+:109140004F4A177033E0D501BF90727E3F6E28E220
+:1091500026E47B0A57C025149EFA380B34C17227C7
+:10916000CDCBCFF30AE9578C08DD8FB7DBD9FFB041
+:1091700041112EE5BBE131F5B2B4E3F4CD90EB6FD4
+:10918000DBA97820BFDF7CD9CADF3BE8A758C6D966
+:109190004F9F68DEAF1DF4542CF7CF8CCB89DCEEEB
+:1091A000DF4557DF454F86FF26347EDDB847E61999
+:1091B000A0DFB71A26867DF34FC4E11BF24177E7A3
+:1091C0004CC739E4D2F11099DEE5F9BC342A9DE3AD
+:1091D000CC35DDBE68F0694D6F678C5B42E5EE789B
+:1091E000D07B6F7E67715543466AF0FB37DA4A1BC6
+:1091F000DB815397C7735AE27425E27C29592EDF2D
+:109200006939764FCF44F8298EADB4254CA4AE8F82
+:10921000DD3934550C42BE88D34FD786CD0AB6CF40
+:109220001BE92D03E4F9619CEFE72D87A367613FFC
+:10923000AEDC198D90A1C52BDF1FEEA273BED9A2A3
+:109240002D1AC0FEE08D7CCE0BD7C63CD8E70C397A
+:10925000A37265514FC80355FF38F004E4016DB99E
+:109260002D1172EAE90F5481D01A3AE758BE38E559
+:1092700094F47D6A7304DFAB3CA5082FFC518BD4BA
+:109280007D792ED379DB7C33C68F70D2B8C330AEF4
+:109290007F4B12C6F5F8B230AEB63C33A62BBB8B73
+:1092A00091D6AE97F2DF16C3CEACDBA321F7230F26
+:1092B000B95F644BB91F79C8FD4821F7E37B0DFC0A
+:1092C0000EF01BD7B7E5436FF58D15394BF81C8EA3
+:1092D000CC815C7FBB12EE013FBA5DF1F4E478848F
+:1092E0000F62E5F91B8257231DDD46B25910DD5E82
+:1092F00077D92182E3EBC68858537E9C23D954BF8B
+:10930000C895662ABF3EA9BFA9FC0677BE297F5330
+:10931000CE4853FD499E31A6FC8F46DC60AA3FC56E
+:109320003BC5949F3661B6A9FE8CE21253F9CC5925
+:109330008B4CE5B3B5DB4CF95B2BEE34D5FFF192EA
+:10934000E5A672AF7059710E36431F23B8EF853E04
+:1093500046E9ED6F674606E375D4384B97EF0C3559
+:109360000D90FA5674AEF739D025EE09810EFBE860
+:10937000F780F6E29C1906BF654091FA704B32E81F
+:1093800026B45E68F9A888FD97F09465FFE76E9FA4
+:1093900061253E31EAAAFD4332287FFBC0E619561B
+:1093A000E22FA3AED9FF523AE57FF1DC37B27CF071
+:1093B000FE4B285772F7CBFC34C122C8AF06CE9BB8
+:1093C000E1A3758CBA2E7D8D47DA53BA8C53355292
+:1093D000C001719D8003D200D127D2FD449F485F18
+:1093E00027FA2CB7097190E813E921D24BF1FDF768
+:1093F000A497223D4C7A29D277482F45DA427A2920
+:10940000D23FD4CDE2F4833A8DDBFDB1AE82D38F6F
+:10941000EA96F0F74FEA9671FA973A1F7FFF648059
+:10942000617F08B09DC6F08BD5C01F097BDE2EDBA7
+:10943000B960BFB1E295E7ABE1C7AC5F225A23B098
+:109440004F5BADB1271C9DFEC9EEF9AD559C08924E
+:10945000CB9CE1DECF06F0F8BD5DCCB7F5EF47C49D
+:10946000B43E0584A74FD3B5B3E007330ACA56C646
+:1094700010FFB8EEEB2536D0CB8796AEEFA3EFD535
+:10948000F9DBA703BD6DE8F75AFD5DA66B1D32AE93
+:10949000F05A6B6B3DDBDBBF146EC403ED33ECEFB6
+:1094A000F758F95EB1F285E0FCE804C1F9FA2F5BE8
+:1094B000380EF15A972789CF1D3D6FC40575F8FD09
+:1094C000F11314EF63F8E18D789FC22F5AC7413E24
+:1094D000181D69778785C40DC0DFBE2FEA8FC6BC13
+:1094E000F87D27C3BFFFD4972280F7F20C3FFEB56B
+:1094F0008E9634D81546DFE1F004C73319FE7AE5BD
+:109500008B1615E78911AF648C63CC3BCA4AFD15F5
+:1095100074C6235DEB6ACA475C467D7524F7D79312
+:10952000BEE3DD49AAE755B95D533EECC7A3AB22C4
+:109530003D42E98C13E8A9AF9BEAF13A0BBFD03862
+:109540004E62B41E27817E1CB29CDF011C9D104818
+:10955000C6FB9FA397D83DB0833E8EB8B382CEB8EA
+:1095600005D48F08DAC79827FAEDF715CD17F2BCA6
+:10957000D7CBF09DE692F429DC7A5E3FAF85632C71
+:10958000DBBB543D5F1CE6FA6B04D1CFAD19DA901A
+:1095900081D4DF1F948CCC7CD617327A60DF4F09E0
+:1095A0007947B00BFA1931F0FF847EBC12EFBD058C
+:1095B000DBE142E9C8C08F414F06DEBBA32B830E1F
+:1095C00082E2D018EF1D71657A7FA1F4D61D9D1936
+:1095D000F475AD43D201F08CF82083AE942F9AF845
+:1095E0001EEBE82A079F7F065D85D2C5957425E9A5
+:1095F000B4FE270EEEEF4ABAEAA407C0E587D355BA
+:109600008B8AF3F89FA5A7796D623CEEFF975C7695
+:109610001F44DAAB9FB6177CA64C8C190F12132E81
+:109620007510EC62A1F532BAA9174A7FA1ED6EBCA4
+:10963000A25D466E70BB71FA5919DAAE12ED7A046A
+:10964000B71BC271116FE9F708DE721A712D9E996E
+:1096500090530EB96DF22D2FE18DCC27BA19A7F3D7
+:10966000F34362099FBF24EEFA404F853A698DCBE0
+:109670005DC8FA426164D7710537EAEDC77F5DDCEA
+:1096800080F98C4F30CBE337EAF2FCF5A291FB0F67
+:109690007D47E1C6DCEB59CE0F7D4761F3403DFECF
+:1096A000204DA481DF170A8F9C9FFE0E46A1BECFDE
+:1096B0005374BAC970AB62541CEE9B6A561C32AF2D
+:1096C000E31D8C3C8CEBE3FC0DC2CFE94D22C0FDC9
+:1096D0004CA20309F91F096193EF5FC8FBBA35AAD1
+:1096E000F6DF90578D7BBA4F3BB557B0CF0F444C48
+:1096F0009E83774AC60D19D70FEDF617BA59CEDB00
+:10970000EFC860B913FBD216D7C927DEA473BA5FBE
+:10971000A6BC378A14F746FBD179FA3B3AC791BF0A
+:109720003167B940BBF16E73BC93D1FE26D7386167
+:109730008DEFFE9CBC296F776FD8CDDE8ACD2E04CD
+:109740007EDF8ABDAA10EB7D2BB6A745A661764EBB
+:1097500007BDD2AF2BB9D8A0FBCEF1C6F378DDC1DF
+:10976000D9806B283C0D38FF00B81EEB0AAE7B0792
+:10977000089637AA23245FAD8E907CD580737558E8
+:10978000C77DDE9EC1F127550E09AFF9CBAE11564C
+:1097900012F5172C1BC9F99375C207B89FC69260C2
+:1097A000100FB1F709EB58CE1BEFDC9D7DF8BDE83B
+:1097B000249AE72A87F63F98DFB98240164984E267
+:1097C000E4867ABE8F7FFE05D5037DAA4A75AFF188
+:1097D000C0CEFA962AEF717D7D2015FE58F154D740
+:1097E000F1E8550E095F439F1CD2AF98F7ADB15F0A
+:1097F00085FEBE80215FF50E93F1DCC63DF7EEE4F9
+:10980000ADE1E192AFF50E93FCD8C0EB06BB7EEE66
+:10981000533FC3898FA6FC3A9CF5AB98586F4C2EEA
+:10982000EC8385C2A49F187695F604F97ECAB5220A
+:10983000EB9151942F3C64137E2A6F074340799239
+:10984000F4B3B61FBAA482EF174529FC3E86716FA8
+:10985000292CC922DC417CC2E90E37BD4B1B911378
+:1098600067CA47797A99EAC78C483795C77A0798C3
+:10987000CAE3271498F23D8AAF36D5EF396BAC298D
+:109880009FACDD68AA9F5231D59437F8588AFC24E2
+:10989000FA2CB9C5D4BEEFB25253FD345FA5A95C12
+:1098A000C53B9B3140ABB7252711CF81CA9F8CD5D3
+:1098B0004B43DEE3B508CBF0CE776BFE335ADECBFD
+:1098C0009910B980DFAFC96CFC99799EEA446B2C82
+:1098D000A5D7BBCD7CB128C99C1F17B94F81DF71BB
+:1098E0009CCBCC9F5396584DF91FE5EAFC344FE4CE
+:1098F000B1DDE3BBF0AF0D30E13F144E440FFC7E11
+:10990000683B9DEF3ECCEBCD327E0F077E93E0753A
+:10991000C06F120C07F84D82F3F09B04D787DF2449
+:10992000B81C7E93E0F22187CCF81FD662C6FF55A3
+:109930001F99F16FD06577781AD96AA60FA1299A75
+:10994000F22D78BAE694997E42F1731D895BB109D4
+:10995000C087E209B87F38BE5686E08BF0C3F73780
+:10996000DB7B47317E1ED7D7756D6020DF972E3A9F
+:10997000A40ABC6F63ACF371FDDC3F6DD51A73892B
+:10998000CFFCCE5D90043E769D907EDBF155164F68
+:1099900080BA7F20649CD929DA43A83F2BFE52AAC3
+:1099A0001D74D226DFCF7B0E7C79D895F1B23E12A2
+:1099B0004FF8BEF6CF54BE2775C4D2A8808FAF8EA5
+:1099C000D19E009F9997BB84D79B248AB72F405C78
+:1099D000D47F85A5223FB7AFBCC72D725BF9FE8946
+:1099E000C127E7A6C8B8A92DB9BA7FDD23E3A79E92
+:1099F000C995727794C7C571DE25B9F27E0DA98B22
+:109A0000A97307013E879DD980CF3A0BBFEBD98A56
+:109A10007BE4099DF7C8210F43FEECA3CB7FF51F24
+:109A20003B1C5847F67A613A7FFBFB1DA6F8E281A2
+:109A30005B5DA6FCA0A62453FDC1BBDCA6F2FC40E6
+:109A40008EA97CC8218F293FAC6584A9FE551F795A
+:109A50004DF991AD134CF5AF39556CCAA788B6478F
+:109A600001DFBE8AB4531CCD4D97FAB95B70DCE4BC
+:109A7000DCBB63E57D5FDD7E61C8FB46DCB9A6D358
+:109A800075A81ED1D72EE5E8FA6421F54687AE1FEA
+:109A90000AB33EA1E971E31DF7587CE6B871235E75
+:109AA000BC43EFD0F58A8E7B349DF1E2DEE078F1A5
+:109AB000B9615DBF1F7D5EC77BE8FCFBDAE57AEB31
+:109AC000EFB4F3BD1D635EA1F349C99674BBD9D150
+:109AD000F5BDAABFE54AFB466B66F125D0FD1336FE
+:109AE0004F2BFF6D842BC6F3B4225EB7FE1776CFE3
+:109AF0000AF7778F3777B05CCF1C8B65DE945C8E6E
+:109B00008B33FDDD84884192BEAD8375FB4AC878F6
+:109B1000736364DC9A88B1BB41BFDD8F27E1996430
+:109B2000170D7CFF4BBF67F1E3354DF7A1688EBD84
+:109B3000517F3FCE6F033D4C1C4BF2593EC9135B26
+:109B40007A3D144972CA13CBAC6C9F8A7BFE57379F
+:109B5000FBFA75DE9FE94BFA10E803B20EF4A80792
+:109B6000F25429B70C92EB2B52BFEEB8E7C07E1827
+:109B700021F4F34370BC4F17F4C67468ACE3DF758F
+:109B8000EFC1A0DB503819FAAFD0E33BFB19F3D299
+:109B9000E167EC07037EC6FD13F76DB6E24D917CDD
+:109BA0008F6502E2E50CFC6DC993F6C6053A3C50A0
+:109BB0000FFCA8BB7A456A6E0CECF7EDC21DE3EA18
+:109BC000820E3BEAFF9BE062C0BFBBFB6DDDF1870D
+:109BD00050BEF05DF7DDBAA3D37FF6DE5B109F9039
+:109BE000F14B3A5EFCFD2C1C17707794793F3F32A5
+:109BF00048F2899183F4FDE423FDD6CC2F04FC0FB9
+:109C0000F52B559D5FC8F3BC24AD98DFAFC6F98A2C
+:109C1000FB5BF3374AF94788E2C4AB87C28F6FE337
+:109C2000FBCBD77A05DB6D4A1B153FDEF92AF175B0
+:109C3000AD0FB39FCFCD7207BF3BC8264D6A5746C5
+:109C4000EDF6A55DF9CEFAC248F9EE60E8FBEA0B45
+:109C500075BD192F6A60DF86FABDEE19A4FBB13C11
+:109C6000C2C3F29C1ED750A1D7E9A037BF7C6F0EAC
+:109C70007A32F631A51C1F67C0CD0D3FD490CE3C83
+:109C8000C1373C07E77983B5CBF8C50EF81A7EAB30
+:109C90000EBFEC61BE27111A8F71CE7720BA2B3F11
+:109CA00098E11FEB6E1F74F8C7BEC3EFD61E69891B
+:109CB000C6DFF169DF26DF67E9F45BFD65B8CB221B
+:109CC000FD5331F03FB5EAFD898D795DDD0FD59605
+:109CD000EFE43894668BB67310ADEF2CF58F777B7D
+:109CE000EF89DC9F88771126EA76A92BD7ADCBCDFB
+:109CF000A314E98FF6A98CEFF609F25E3DF15181CC
+:109D00007D67C44F4C118104A4861F4A5B3D92E1DC
+:109D10006FF8A14A0223799E33EA17DAF0E468EB80
+:109D2000A3771585BB3BFD53AD7D645C54777EAA5C
+:109D30006997F3B9BFE997AFE17E3E189426E5B67F
+:109D400086FB6E039D0DD82A6C5867ABADEBBF4BFD
+:109D500051A8F3AB12E89A3D82E2AD962BBC2F9648
+:109D60002AC288BF623E6FE42F35EAF92299BF7D8F
+:109D7000A5CCB7EAEFA76DD1ED20582752AC077AF2
+:109D8000F936DD4E827520C53AF01D7C0D79F0352F
+:109D9000E4C1D790075F430ABE86EFA5A2381576C7
+:109DA0005BF8D30A83F607FC6985417213FC69C12D
+:109DB00079F8D382EBC39F165C0E7F5A7039FC6929
+:109DC000C179F8D382EBC39F169C873F2DB83EFC28
+:109DD00069C179F8D382EBC39F165C0E7F5A703944
+:109DE000FC69C179F8D382EBC39F165C3E6F996220
+:109DF000F2B7CDD3DF7F285B1FCFF45198511C9B66
+:109E000047F8FDEF887FFCC4960E3C372F02DD2E0D
+:109E1000AD0EF7483C374E9078B70889E7B6D98C35
+:109E2000E7BBEC325F24E3B443E9077EAB429BF42B
+:109E30005B2185DF0A29FC5648E1B72ACC947E2BAA
+:109E4000A4F05BE13BFC5648E1B7420ABF1552F86B
+:109E5000AD90C26F85147E2BB483DF0A29FC56F8BF
+:109E60000EBF1552F8ADF0FD08CD03FE2B635E90DA
+:109E7000F3FB99F452A243935EEA32E521E707D758
+:109E8000879C1F5C0E393FB81C727E701E727E70FC
+:109E90007DC8F9C1F94983DCBCBF20EF07B783BC9B
+:109EA0001F9C1FD4E87B03B6AB491B2EBC8EB43578
+:109EB0004A7942710931352F7326FC8BAD4E253519
+:109EC000D623846DF980998594D7F438C73CD16640
+:109ED00001BE39AE80F0A60504C7650FFA7FC95CE4
+:109EE0006EF8B3F987F09EBF43B0DE50A3DFAF3505
+:109EF000DA7B844B456AD4EFCC775D2F747CA31E4C
+:109F0000F3CBA0799062998F7893FCBB220B70AF52
+:109F1000608B4591F1B82B643C74285DADCA93E722
+:109F2000FB16CBF6FDE1885329513CB8EF9165153E
+:109F3000876C0580D392027EF72A2F565FD792ABAB
+:109F4000118765CCDBB04B129FE07B86A3DA84BD22
+:109F50009CC619FD85B0E3EF734CB44B7902EDA0BC
+:109F60006F0EF429DE4D41F4BD2C4F9E7B9AEFB667
+:109F7000ABCBE9FBC06D4BAEC6FDC589E1B2DDD30D
+:109F8000BF8966384E6E50F89ECEA86DC28BFBC955
+:109F9000CB757E3A709BCB5ECEE3BAF8DEA3D16F71
+:109FA000C98654BEA759225A0B710F450C55F83D6E
+:109FB0007C036EB4BED7B1BE2CDA2AB02FFFE0FB13
+:109FC0004F242E7E9FFB4FA387C61621AE5034CB65
+:109FD000F742270D2D59D983E6A5F9E57BA1A3BF4B
+:109FE00058F206E79F92EF8532F90CE7F9F179987C
+:109FF000ED53F8FD95C9BE8D960437EE652FB72554
+:10A00000A2FE36E1815805F508F78A8D75E58A16B6
+:10A010008B5301BD8803F141F4479C633AE825DF87
+:10A0200063E3F759A6585D36F01B43CE2971C9B1D9
+:10A030008BD451317CCF32444EB8D4D083E3627E8E
+:10A04000789C4E3BDFE75FBAD3C97285B65E61BECE
+:10A05000793E5FC6BB56DDF6E1704B7A679CCE99C0
+:10A0600034FF16BC037B267D7BF40885E588BD792B
+:10A0700004D7A30D2FF13DCD92956FF03D944B0D7C
+:10A080000F45CBFB6CD2FF52AEC3CDB03BCDD7F169
+:10A0900053AEC7691DAB93EF3AD339CCEFAE5C6AD0
+:10A0A000B0B19C112A2F1AF2A7F11E9110AE3FC237
+:10A0B000CE53D160E33BC00BD794AC4A1257CA9140
+:10A0C0008B75397351838DE3B22AF4F7D442FF6E56
+:10A0D000CF623D1E6BF156F3F74FF242E450E37D41
+:10A0E0004DBD4EC9DB0766B03CB4C4C6FECD39CB0E
+:10A0F000A57C24B60B3FEE93CC593ECE82F766E6A4
+:10A10000ECF47A942EE8E95D5D4E9AD8EA64F84F53
+:10A11000B91CC1FC65EAE514CEDF7C3999D3999767
+:10A1200065DC2AEE22816E5A8BE43B07EFEBF2D11D
+:10A130000CC4B1C6433EEBC9F4DD4EF48D21F2747C
+:10A14000BE35C0AB1C807838D1A6AD449CECC48D24
+:10A1500082EF834D821C45FDCF825C158FFD9156A9
+:10A16000C4F76126287CBF68D2D0DBF4FD40FB43F6
+:10A17000303FE1F757B4C2297EC439CDD2B65B80F7
+:10A180007F635F68BEA3FC5EEA249F62C73B929A2E
+:10A19000AE6F1B741FBA3FE646E876B2486907EB1C
+:10A1A000B09361B27824C9B76A26E4D3B9B06DF62A
+:10A1B000D20981601F952BCB7BFC76D5CC069241D2
+:10A1C000FF55FBC91C8B45DE3F233990EF0B88966A
+:10A1D000A29E942F59A314403F32E6F5B967EC389C
+:10A1E000CFB04E3A28EDD8A7F21EE5D27B324D7E95
+:10A1F0009BD0B48CE08DFD3437A6F5270A6168F456
+:10A2000060E12D1C81F7EB85F1285400F198B7E847
+:10A21000F9EAC13BFFB43A97E1C4F991BF7D68A662
+:10A220002FF25FE09373146BF0DF1B4BB268570D96
+:10A23000EEC1F750C703BF11B96DFC9E444AB64B3F
+:10A24000F2A9107B4BF56089C750BB4B59AE3C77E8
+:10A2500084D59D7A2BFB7BDC6CB734D67DCC66BE77
+:10A26000E76BA4F307EBE75EDDBFE79ECAC316F911
+:10A27000FEC26316FFF657885E2FF7D06660BD8F6B
+:10A2800021DE9EE7AFF1FA8CF74C3AF895FE6E8925
+:10A29000414F47965DE2FB2AA59176B71A444FE5F8
+:10A2A000AB15BE0F5ABA4CDEE7D6562BF25D846E64
+:10A2B000EC58BF99FDBFFC9ED56F7E112E0B75F833
+:10A2C000CEB1B7BCE148EB84EF9F973D60937C34FF
+:10A2D0009089FB0EB72C71F2BBD99F7B8AAB060F1E
+:10A2E000039E3C8CA771D8E5547F4B8CB604DF4BA2
+:10A2F00045CB41D81DE7FEFC6D7E8FBAB6398DDFA8
+:10A30000BF2CD995BF0AEFD97CEED17E82F5974458
+:10A31000BAEC90476A1A62F97C9EDB53BFCF2BDA06
+:10A32000D8CF67E0E7BEC1D28E777DBE1CE7A2AE74
+:10A330005711C06C534CF5BAB6631AF6D1503B4B6B
+:10A34000E8BB21DF655781DDC41E645F35EC32B6A2
+:10A350009C63B371AECFB177FDF73EF7EAF337F404
+:10A36000DAF91D7A6DEEF89E90FFD72A2ED8D3CB5E
+:10A3700023DD3371BFA1FC900D91B462629C5BBE82
+:10A380001F738F7C3FA6F48E7CE66773809302DC9C
+:10A390003B19C9FBB8DC4FE990EEF7FBAD6B0FF44E
+:10A3A000D90D7A0A78F91D827297D71E17241F9546
+:10A3B000352AA677248CFC0B8355C99748DD00FC11
+:10A3C0007E7C479A1D6F39CD213109F1997B412758
+:10A3D000C33ADB513D8E3F99982E0ECAF7BD14FE4D
+:10A3E000BBE4182FF8EF5B95369ADFC3A0FA2CDF99
+:10A3F000ED1A1CC5FD95B868DD69485D3C4F8203C8
+:10A40000C3A9ED3EEACFCDE3303ECA027E1BEC0786
+:10A410007310F742F95B5C7E1BC6296D90EFD46820
+:10A420006BE438DAEA58FB20C8075697BD4FB05C9A
+:10A43000D820DFBD9EA3FFDD119A2FCBCDE50427E9
+:10A44000DCB333EEDD86C2AB449F7F7963AC59CE7B
+:10A450006C5C6B037E6677F35EC639DD0E5DDA30C9
+:10A4600086DF3728B77AF9BE8AA6C3FBB3DB9CF731
+:10A47000C25F327BDD23B634CAFF65B0946BCFE98F
+:10A48000FB71627A2093DFA9BACDC9F1E3B35D8D88
+:10A49000BCDE0E783F44F081DCE22A6678139DF83A
+:10A4A000106F59BECE8CDFCEF944C977FCD795F03A
+:10A4B000FE5B60D5ECAEE079ACDF9789F8A1D9B44A
+:10A4C000EFF10E9770697C1FF6C44333F9EF056214
+:10A4D0009E1CCFE6718FC7BB5344374CD706FD187F
+:10A4E000F7F38DF1AC1EABB4C77BBE6B9F7A0F4206
+:10A4F0004EAF277CC30FD0DD3EB5E302268D6B2F18
+:10A5000097EF075EC1EFF4FDFAFF016A916CD3008B
+:10A51000800000001F8B08000000000000FFED7DA0
+:10A520007B5C5565BAF0BBD6DA57D8C0668BB051A4
+:10A53000C00D0262116D10101575A1805B736A6306
+:10A540003729C48DB7500191ACA89FF3B10D6FA905
+:10A5500095262A9675B6A68D957570B2461B9BD921
+:10A560006A9A5D0F3A8DD33953B6CD32BB09D234D6
+:10A570009F7DD399BEE779DEB560AF0DA475A6F9CE
+:10A58000CEEFFC3EFCE3F57DD77B7DEECFF35E7630
+:10A5900022634CB23136789883B1818C1918934577
+:10A5A000C83FA177FBED02639571ACBE2D13D22895
+:10A5B00056FF6B0B63DFE3DFF89E74A253642C8FAE
+:10A5C000B1DBA05D1B7CAF10D9ABCCD6F33DD3295A
+:10A5D000D0F78A1436D31DD41EFBC37EE3D5EF1308
+:10A5E000FC698B337BEAABE356D878BBA9D07E9A63
+:10A5F00005EB8BDDF51BA83ECFB3E92691C53236BE
+:10A60000DB04FF87A594487B56C4E632D6B057706A
+:10A610001AA1A8E14189B118489F8BF0B164C6BE68
+:10A6200068F8CD3BB740BDCF376FAF64437BE635AD
+:10A63000C73F8A39463036F75236730C606CDEA558
+:10A640003194560FF364380706D5DBF85CBA07C6B9
+:10A65000BFAD2DFBDC7F305AB79FE530F6FE73BFF0
+:10A66000FDE368E897319FDE7D4DCF3A66AD3EA1B0
+:10A67000AFB204C38DAF734D4657158379CEB6186C
+:10A680001C1214CD5E5EC5649827B333671AE413B9
+:10A6900075CC2B42BF6CFD16D904EBF330FE57B5D9
+:10A6A0005C90A95D63BE4F82F50C867AC61C5EDFA6
+:10A6B0000CF0F7580C678448A8E82D910319BCCD1D
+:10A6C000F7293DF81D0CA921A707EF890A1DCC5ECB
+:10A6D00057066D7BF0050333960FEB651CAEEAFC65
+:10A6E000A72AF3BF6DBD20FBA0DE0D4E07CF572775
+:10A6F0001BE6C17AE7AC4F36CC86B45CF95E3E47C8
+:10A700005BDE8D2FAB8AAFCC9576584F571BC75762
+:10A71000D73A3DE1AB6B4F2F7C2531A9671E7700FF
+:10A72000BED8008E2F3682E30B53C057A5332FA817
+:10A73000DEBF707CCD7EFEED0F5E76D0FAA8FFCE38
+:10A74000078DBE1DD0FFACB6BD84B7F2D51BF4C9D2
+:10A7500050AFCE994C7051DBCFAECFB63280E76DA3
+:10A76000ABB7EB1D16FCEEE893EE219559103F4177
+:10A770009E099067BA40BC3BA2A77E39A47B619C2E
+:10A78000258BCD91ECDA9E71B628F43CBB3EDA867F
+:10A79000E3CDAEAF7A886571FA7767F6E6BFB36648
+:10A7A000CE17B3A03FE4CFB345CE24E48B0A51D4F7
+:10A7B000F09B9A3E847883793D06E03523FEC3DB27
+:10A7C0009E46380C5E14E66C864FA9A9011F8E8B3D
+:10A7D000F48CF33688CC6B827AA935818B388F5410
+:10A7E000A0286C8769848D52160BF91D30ED024844
+:10A7F00053249EEE73F2F5C3773F7E6731813C5C54
+:10A80000BF4ACFA1F46A603B57A700FE0D31CCD9F7
+:10A81000ECE8A14FB51F953E55FAED6F7D7BAE700C
+:10A820007D6793393C598633C904E3563E3CCCB925
+:10A8300046B8FC3A0D61000F5BD07A81580B6C7DF5
+:10A84000AC3735905776CD0FADB7A524B68FF586CA
+:10A85000AE53E5933926CEC3C02751019877D7FA76
+:10A86000A1510CF12D302FCA9DB38BCD22CE5B5D53
+:10A87000D7534D5019E6B6BBC944E9334DC068C340
+:10A88000003E4D76CA3FDFE4A0B4AD2983CADB9D0C
+:10A89000369A3F6381886980A78A3085FFFD3C8FA7
+:10A8A000E56541E5536D9CEE4E5B0311B62039FD25
+:10A8B00071BD790D8B42FA0E3C88FCCC1A87B25DD3
+:10A8C00030D4E9F56723C44CA44F3E3FB5DD127D7B
+:10A8D00027C93F166170EC02969BB124FB7423E0FC
+:10A8E0006BEEF2382790129BD13894E4C20C6FB40F
+:10A8F0009300B07E0B4378CC53E460F892AA952382
+:10A90000B17E6BB2558071E65A9CE75AA9FDD5CE4F
+:10A91000FBF17B4B99212593AACA26906377287275
+:10A920006C89C0DCC88777A09C44FE120FA5A2FEEC
+:10A93000B9A355F01B29CF560B00D721CDEED27805
+:10A9400094135B05E70E6CBB0DE4A9A9479E760D39
+:10A95000737F817A817D07F407FD5F252002715D99
+:10A960006D721CCAF14D827517C379B90D089F0528
+:10A970000A9D9C6E3913E1C8EC81EBA3F85F10656A
+:10A98000CC238B286F1B143D86644079454E0E31D5
+:10A9900070F841CADA113F3AA709E9A0CB9212C573
+:10A9A000FA286F884889C3F239AD12C945959EAA25
+:10A9B000D535287C3317BEA3DE2B912A6291BE5673
+:10A9C000B64CA474CE8692CD5EA0E324C11D3B9A02
+:10A9D000D6A367B89E39B513AF47BC55EF30469B39
+:10A9E000006F497A6F524E103FCED9BE2A8941BBC3
+:10A9F000F3DBCDD351FE175BCB8AA3A1FDBC6DD198
+:10AA0000D952901E49CAE67A6441EDC43806F0ACCA
+:10AA1000F9FB9127ACA08FE7429F56E8FF9BB670E9
+:10AA20009F17AAD434ED4F9280E7DE3179E2B3A1CB
+:10AA3000FE42F1E02DA3501F08BEA7E2A9BE23CE1F
+:10AA4000DA873C50D373C00F0EA0F7DAFFF51EF57E
+:10AA5000F395F8D6F5E5D0BEA6F68548EC67E1A6F5
+:10AA60003FE45BA1FCA0E849C3FE3F17B63F654544
+:10AA7000026CDD9E857A7CEEA6B4284F1FF217F992
+:10AA800000F151BD5F20F8AAE5337C510684BBC7B5
+:10AA9000CF0C564CADCC80F47E5E628D680FA8F66C
+:10AAA0008C5A3E329BCBADF351EB93904EE63FB5C3
+:10AAB0002509F5CC67113C5FF1D4AD6FA0DCF2EC59
+:10AAC000341A10AF1E1D3338519F7941BF221D55D6
+:10AAD00003FFC693DD61AE047A2ACA0E27B8CE6F93
+:10AAE0001D41FA519D177CA7F2CF74CC85F318D283
+:10AAF000DC998D74FF679D7F2EE2F3CFF566A71773
+:10AB0000F199CDF5DB9FD74BA558EE0586417BE447
+:10AB1000CFEB5F8848B5F4D86F25D2FBB28476D6E8
+:10AB20008B4236EAEDF0CC76C32CB21B18D1599D7E
+:10AB300095D359C3017DE9E018B2C7A8A446E73709
+:10AB4000F485AF058ABDD59DDFB7D7807C52B3872A
+:10AB5000DB11356D67C88E50ED925A859F17EE391F
+:10AB6000437685DAAE6E1F874BED3E5E5E9501C87B
+:10AB70001DCDE5800042BA0AF105F9FBFEF5D7D3F9
+:10AB80009769F27B297FDFB5562E0F759D49A8B7CF
+:10AB9000D6649C3420FE6B972BFD425E1F34DEBCD6
+:10ABA000EC81042F2C1F6AC1F60E8DFD50BB2F9A2D
+:10ABB000DAFB6BC356A3BE97EB2C3A4C9B6B2DA4D0
+:10ABC000FFB7D58B19BA5C9C5C9813EDB983619182
+:10ABD000592847072E3C650648026A3B8F8850BEBD
+:10ABE0003ACA732FD2671C03AE90506FF805B45F5A
+:10ABF0003B5EF97404F63F6E48E06B0653D70BBF1B
+:10AC00009B5E0CF26419982D641F670646201D0F89
+:10AC10003CCCE5F4E37AB61AF51BD3B9D93428F75E
+:10AC2000A3DC423C7F1BE6DB05FFFF1DF30FC6FEE6
+:10AC300099C93F14DBBDA4D0A7DB68592DC0BCAEB9
+:10AC40001EEA59834BBE41D05F932D220EA434AC33
+:10AC5000D7A1E7DF557B758222A713C18E40BBC801
+:10AC600030C86E413A6E36F3F509B2CC1A611EF760
+:10AC7000671E9E8D7A7A6DA78919619D133AC3C8A4
+:10AC80007E4D1CE422BDD66C4E22BD2D3874AC0224
+:10AC9000EA1FCE14FD3AACCF4C3EACCF4C2176AE81
+:10ACA0006896B19D70F0B56F51BE0F962E1E8982C9
+:10ACB000F50DBE477036439DCAAE738FFF1BA415BA
+:10ACC0009776ECFD5748FF2DCAB313E17ABACB75DE
+:10ACD000C603A85B6B6D3339B9DE60C1EB3878EF22
+:10ACE000B79136B1677E1D9DE79EFB4D2EA62627A8
+:10ACF000EA9F090725D21FA1F3E9B0C3C487523DDB
+:10AD0000B23B3B2CA24F10B0FE91F7707E134C1655
+:10AD1000BF84F6BA49FF65B07E618EC4E87357936D
+:10AD20004A61DF8391108B93477D74D14276EB3873
+:10AD3000850F553A7B2B9BDB8F6F297255853373BB
+:10AD4000C82C58AFA8F06CD6ABFA2210CE327BF8E4
+:10AD5000769152AFEB9228931D5E6DF431E8B2EB21
+:10AD6000E050D233FDC9D93FA0DD01F6C4F254F959
+:10AD70005D842753F4EECD0AFC54FD2D29FDDFAC94
+:10AD8000C0F1668BC8E1765308DC147A0AA5971ED9
+:10AD90007A8841DBA31BCFECBEF6A351C984DF6BDD
+:10ADA0001EE678FD90F0FAED5B2B80CDD8A0BF4D6C
+:10ADB00021FCFE0C78F58BB93F02AFEDA178F59B35
+:10ADC00087215E37896467A01D8876A307E5C0B533
+:10ADD00094E7F66006233951298539D724E3778033
+:10ADE0004316C987A3281F54B930C415B806F5E91E
+:10ADF0006970E5717E01B18D97E7A4105D24B0F60E
+:10AE0000782C07BCE7A17D279986667E0C72B7E592
+:10AE100001DFDEDF403FCD826FEB3C988FF7668B22
+:10AE200013EDB70E9FE8D5C33C5AA259D67E18BF82
+:10AE300065FE554E2F9633456E4C37F8D07E83EF26
+:10AE4000498DF8BD9C7F7FE9EF671F44FBAC338DD4
+:10AE5000D1BA5AB2593ADA672D6519F4FDB7AADCAE
+:10AE6000793082B72FE3F4DD32DFE6433DF4E8A327
+:10AE7000BEE1A8275AB6CBF136480D519EF81C9872
+:10AE8000FF2089D37D4B329443BA597097CFC57E4A
+:10AE9000AEE1F30D94873DFF1474654E05D106E5D0
+:10AEA000A71B2376A05C55E974F0302EDF8778CF9E
+:10AEB0006C45387927B08C7AE8FF4385DE54F80B6F
+:10AEC000C0368D00F798103CA87417A3C05F58CA0D
+:10AED000E9CF3B41594F1DF3A1BF910053090738FA
+:10AEE000571AC1F0837496D5938DF36F5E0CF89169
+:10AEF000701D1C0FA74556DDD6075F15E628F10D1E
+:10AF00001802F9A69271BEA944BA427A6C04BA0A30
+:10AF1000A2471648883E17AED015CA8308F7B81C5A
+:10AF200058E757C21FF2B1F0ADFF94A6F735CEA493
+:10AF30001C2E2F1E337B4A7348EF4DD0D89D6F6572
+:10AF40007F9A88FAE5F4BDAF25609A14E59E8CEBF4
+:10AF5000D85CFED75214FF1FC607F4B88E0FCBFF84
+:10AF60004F22DA2D954B5F23FABFD2799699983705
+:10AF70001CE01E5D2C38FD00BF792D46E724F81635
+:10AF8000575C750CE159D66A74189156D8628D1CBD
+:10AF90003B2B8F40378A1DDA6A24BA39F74B89F484
+:10AFA000C1B9928BAF0E800FE756084EAC57D63220
+:10AFB0006C2590372B2916A85E9957A07A65A91C95
+:10AFC0005F271A05A23740AF253B28DE31A7F58E53
+:10AFD000A988DF13C55F0FA4F8C17A1847E5632E6F
+:10AFE000DE489E9529F5AB561B9147BBBF97B5AC84
+:10AFF000BA88FC3FD31B52DE3AE953ECB7AC515B45
+:10B00000EEC635821D77574E440CCA07E664CEEF74
+:10B010001148F240F20FFA93BB407144CF300FC297
+:10B02000C389BC617AA4EB990857A0DBE8A57CDD55
+:10B0300033A70ABE49B0CE9916CE671F9609BEFB4C
+:10B04000053EFF0940EF65501E0B745D16C3E438E2
+:10B0500048DD26E60FC7792E1DF609CADBD338D4A2
+:10B0600028AAEF8FB4A15CF7E81189B7322FA5E5C4
+:10B07000CC47E9EDCC4FF398C13A937490AF93FC71
+:10B080002B318EF32BB36703D2D75F8B4E9C16E028
+:10B09000FBDD3942DE2894438D0368DD975B1F702A
+:10B0A000A5807606AA41AC5F96E37E14FBB3CA4C3A
+:10B0B0008F71AB74958E5A993715D617BBDEE29B0C
+:10B0C00004EB8B6BF51CC2F5A64F373810EF8313DA
+:10B0D000F83A1374DC9F3F546E60A3810E363F181C
+:10B0E000E6433ADBBC3520DAA1FEE6038001CC97CB
+:10B0F000AF14BCF0DDEA614E8CD359751E11EDFE24
+:10B10000A2568F1808E2A7E1B241443991BED32379
+:10B11000A29EB45AD7533D355FACD44F3779065908
+:10B12000C94E9E4EF4335CA11FB59FD456835F0475
+:10B13000B817C94A7D99B757FB618A9E56DB6139BA
+:10B14000D2677AABA34F3F454D5B503F838FF808E2
+:10B15000C605D27BCA1F71FDDA84F01B78F3AB36CB
+:10B160004C370321F8711C9DC74CE379F83CD3158B
+:10B17000DA87BFBF7F8FE3631EF0BBB9F5FE22E421
+:10B18000A3CD001FC4F3E69DB3CCD4CFF4599A7974
+:10B1900031A986F22508074BEF753CA2CC2F3DD58F
+:10B1A000235A69BDCE4368E7A5CB8CE2016A3F769E
+:10B1B0001D7405F46A777A857ACCCB905A94B84797
+:10B1C0003A8EB34E40FF315DC157496BFD6133F696
+:10B1D000E366145F4CCF85FEA1FE268483A137FC75
+:10B1E00042E7995ECCE77342A9DF8EF194746CE775
+:10B1F00058114374C5E7D7D5EA14621C97B18FA0E4
+:10B20000FDC9907E9EC2B80CA4CF4E7E6D4A2EB46E
+:10B210007FFED19776B4D0520E3EB30FE556ABF514
+:10B22000E69B709C83229FFF4D72E25D98DF6D204C
+:10B230003D9ABE534EDB44799313FDEBAE56DF557A
+:10B240002F42BD2C18C664EB3D8F130A9CDA153AC9
+:10B25000383979CB205CEF5345772C5802ED875F66
+:10B26000F7388D3B7CCAFC9416C80F9BF8CBAB30EB
+:10B270007F5F8EC73C02E4FEB0D25FDEB60FE56AA8
+:10B28000E9FC1C8297C57645F2A939DAE3F502BFDD
+:10B290003747DC528EFCB8D26670482477EB19FA37
+:10B2A00059CD1177DBB1BFE5D1F9264C0DD6BF36AC
+:10B2B000A19C3C6EC931211E9A2D131896EBAC0A45
+:10B2C0009EBE1B4FFA40528872778473BA4C74E565
+:10B2D0006428270C0906ADBCD671792FD91D3EB460
+:10B2E0009FBAACF54881CC600954A07C935479692D
+:10B2F000717A713CC9E2B4A3BFB44291372C86AFD6
+:10B30000D36039F79F38AF5EFD632E96504B7F8632
+:10B31000B0CC2841F93FDA9BC6103E575383C5BBDA
+:10B3200018F544687F5D2070508EA34F4776337EBA
+:10B3300048EEDD5EB21B347AA45B5E7AA2F521F2A0
+:10B34000521E817AA2582079E961EB0CB8FE120CEA
+:10B35000B2005C3CDBB85E54F97B26CE05F0E549D3
+:10B3600065915C5EE9E473260EC6EFD1AE5C2A45BA
+:10B37000221E025EC9E0E9C39FF778937F501E9DAD
+:10B3800041FA87A90790FE21FD44E10F8F8A076FDC
+:10B39000D9F5A3505FCB12D90395CB8536B4CFE254
+:10B3A000BCD14769BEC5DC2E6897BFA6F51C2A89AB
+:10B3B0004B44797962D999C7EF41BDBE299CF4FF0E
+:10B3C000A4A56756603C6EA657701A21EF591A7DE6
+:10B3D000F77B986F343A5D903FABF081FB974591D6
+:10B3E000684F08B8CE8C9E75561632839BE239F1B1
+:10B3F0003396403B4FA3E0343B7AE0A1C77A52EF4B
+:10B40000F505BC3746FED0FA3FBCD7A8C859773EF1
+:10B41000CAD9A2C6E4870A705DEBF57C9E8DD1D7B0
+:10B4200053DE27393976B91C9EA9D83F9EA5B3575C
+:10B43000C6C3F7C06A41F9CEF156A9C8E540E38812
+:10B4400063183F0D2C17483E79BC52A21FDACD5C21
+:10B450009E4D78EF280A905DD8E53DB4925A2B7244
+:10B46000DEA37436178C58946FA7DFE3FE9F47FE68
+:10B470006325B69BD3A2B5832602FD0C40B8BC67FA
+:10B4800026FDE9F196D1BAEFF04569EA55AD8ED3C4
+:10B49000E43DAB8BAEC7B0E7AC7B27523CAF9239F3
+:10B4A0002291DE2A656E37C19F251BE633579D4FDB
+:10B4B00031B7C72A8BC17EA2EF5A7BB0C7FE893352
+:10B4C00020DFA87854F1133AEF5E7619E376D0AC1A
+:10B4D00075DA7ADD761030168ABACAE5DA76BF32C6
+:10B4E000BB9F45B9E8DE38E01BF2ABAE501E828050
+:10B4F000217F6E26E3711FA6E843D5CE2F597A51DE
+:10B500008F726866E3453DC273E6D21FE6A75F38D7
+:10B51000B5F3BEA1204ABB3E394E93BFD13544534B
+:10B52000FF66F730CDF75BA75FABF95EEE19A9C9EF
+:10B53000DF5E3D5E537F46FD24AD1C7A379AD6A36D
+:10B54000E2A7BF79BFA5E8A37742EC12359D3AE2A6
+:10B550003F1391BF3F2C67E4BF7C7833D3F8311D94
+:10B56000232482E7805C3DF931F7E5C8EF8F20BFE7
+:10B57000C94FF4A1C2F34373A1C928A27F62E47E3C
+:10B5800079A85F729039505ECED4B1FD42548FFFDE
+:10B59000670EF39CC7FEBAE30D4B0FF17843881F8B
+:10B5A00073A578FF7006CCBF0F79794D2EF7C316BF
+:10B5B000EE36AFFF38088EB56DD19AFCA2FDF1EBE7
+:10B5C0003F0ED63B4B041DAEB346E1935A16A07D09
+:10B5D00052BBE8A0FEEAC4402CE63B58676CB4F4CA
+:10B5E0008F838B0A0F808F253728DEA9FAC33F1976
+:10B5F0003E450A9ECBB4701A93CBE3905F8F10291F
+:10B60000DD9C23C7E7FE03F11CB49EF4DCBC7FDCA9
+:10B610007A2247C859089F9F1BAFDFE31E0F94177C
+:10B620008E900B7F26B84CFE47C2A547CF472FD838
+:10B630000DFAA3729D81FBFDDE335CBF3772FDFE08
+:10B640007CB48FF6879BF344E70E07ED97D23EE973
+:10B65000A17B8D611918DF59A1237D797A99908199
+:10B66000FEC226218CFC360FAB4816C8BEB978C87E
+:10B6700048FD31AA07EDFD3A90F351053E6B09E410
+:10B68000DFCCE571B1356E714A8A03F5F61FAC1E49
+:10B690008A8B7AE2111E9EFD30E16B69DF45EE2B4D
+:10B6A0007E12D06BE5D112858F5FCCD5D13A1F2E9B
+:10B6B00014B99D942ABA701F6315D8A968570696C5
+:10B6C000EB285F91C7E9596DF71F0A9DC794DD14F8
+:10B6D00086F388DA24BA7D7D8CFB512E8F0F3D795D
+:10B6E0005718EDB3012A7468EFDBBDD6692E58AF49
+:10B6F000BDD0968DB6DFDADC68EA6F4D469715CF80
+:10B70000A1FC8C7478CA8EFEA0C0FA8C33CD55E6AD
+:10B71000ABEE0F5894FE36E941BFA29D2298281E39
+:10B7200061F11AF9F91567B126DECA1C020B6EA782
+:10B73000D6F328F46AC7421BE197F6EFD578B15DDE
+:10B74000A117A41BC4BB4ACFA1FD8389EC8DCCE912
+:10B7500089F3D915528E1AE5D98D748FFDEA901FA1
+:10B76000BC5CFE076EBEC4E32CDED7DEC37988E185
+:10B770005F529C0CEC4ACE5F4B43E2BE3F914F02BE
+:10B78000660ECF4084561EDEABD0C9DA7F82DE481B
+:10B79000BA02BC3E9CCBE58FABC0FD36CA3BC7B2FC
+:10B7A000D430A2FB1F0B2796604538515EBA723821
+:10B7B00079F33D1F109E74CC6FB4717F0BF9E17269
+:10B7C0007CA4C23149649EBEF4F2883CE5FB1BCAEE
+:10B7D0007EAEB76AC80FD9612877C502C6D22CCC15
+:10B7E00061BCB6FF7A0E9C8F85E86A39D2E5AE96C9
+:10B7F0009430E4CF6465BCCA9BD2A70C77A05F20CD
+:10B8000018D00E04BFC3C0E33FDC4E57E57A4FB9F2
+:10B81000D67EC4724F668F1FA6DAF7EA773C97820E
+:10B82000E3AAF359A5D861FDCD7755124B72A2DC7E
+:10B830005A768F80F0DCB15AD4F87D715E612503B1
+:10B840003F3ECE7FAF13FD8E38B0AFCD28CF75F51C
+:10B850008233085E817B810A381387F82BE04FE240
+:10B860003ABD67895E42C757D7B1AB858F1BE75D8D
+:10B870002CC8909F54512FA0DFB756997F5C05A329
+:10B88000EF69993E01E3219E16568AE3555633032C
+:10B89000C6F52A33995386F2CAC64374DEEDB9025F
+:10B8A00039256F20C94F3A4FE32AF0A4E7011D4D17
+:10B8B0004D28437667B84B86F1897F161DA7B54C96
+:10B8C000F0A2EF59D4E23C84FE01D011C57D3C2D9D
+:10B8D000011A5FE7E571725D8BC1E98075488D657E
+:10B8E000B4FF21551B9C32D43BB629DF8FF1952D37
+:10B8F0008DDCDF0DF59374D6FAD7C3D15FAB109909
+:10B9000044010A792AFA5956852E5630773BEEF7CC
+:10B910003319FE41BB48A5DC5A3D6F2A6622E5D0AB
+:10B920007883DC139F409E6BDC40B2D394AA8D6772
+:10B93000482D2BC9AF33627DA8AC0F897748D5A5B8
+:10B94000141797ACDAF25BF32262088E593C1E9E04
+:10B9500073EF888DB7C27C727F79E31F303D8741DA
+:10B9600033805BFEB23B074C87FF16ACD87823A62A
+:10B970004FBCCEE89CC18FE057668CFAF1FCFAE828
+:10B9800095F2ABB2260FD0B9C2AF7DD2BF1A4F0924
+:10B99000E54F95FE43F94E4DD75E867FD7260512BB
+:10B9A000910F4FDF3B3203DB5736DE73C8C7885F2A
+:10B9B0000507D077A577711123BA605697D05B5EE3
+:10B9C00084370B49ECBF371F3F867C3BFEEFE71304
+:10B9D0007F08DF95098CCE6381FD49F69C9AAADF2A
+:10B9E00023F2B93EBD906724BC4E46C10AAC3B056C
+:10B9F000DAE0BEC778604E2BA47F2EF03C8BE34D7F
+:10BA0000813C9EEF7BFD406B0CAE374BC7F58EA79C
+:10BA1000DB8EE67648B7FFA8D80F59063605EDDC71
+:10BA2000C02611776E59E0C0E73BD6E2BE6BB9C9BC
+:10BA30009906EBCABADF48F484048AF6519668A7DF
+:10BA4000B8E5AEB68FCB699FB1D1C0D2286EE00EFB
+:10BA5000C3736400CFB0AA4CB257C3AC68AF7A8549
+:10BA6000A4AA881E7B08F5220AB42CEFAD53AC3093
+:10BA7000FEAE42B047337BEC1CD5FE599C9F4CEB8D
+:10BA800057ED2068C7B0DD8FE5A74A0B4B22BB19E5
+:10BA9000E683FBF7B64C2690ED1352FFF43223D920
+:10BAA000AF76AF7BCA70B45B97A7E6A0DD0AE39AD6
+:10BAB000246E7FFD3BCA67BB4EF95E28E6E0B949BC
+:10BAC000751F800574D1188753EDAAFEE7A563E7BB
+:10BAD00054B905957F9B2F9FC17EFF5972DD635539
+:10BAE000E84D4D63F879E0E90ABD8DCF37539A9E52
+:10BAF000FFB3DB73A7AE93FE79EBFE39D7E1FA9F74
+:10BB0000B18ED8FF21F8D83CF97FC63A6E99F24F32
+:10BB10005C87375F6EC8CF4379D646E788EC2E7EC8
+:10BB20002E1CE4DE3DBC9CCB398B930964C7FF74AB
+:10BB300079D784FD9D411F1CCFA17877083A1867FB
+:10BB400088A5A188ECCDA58CF681862CE5FB404329
+:10BB5000963A4D22DA03166E270E52ECCE414BB9BF
+:10BB6000DD19A79C2B888B117D32D43FF6CB5BCAA5
+:10BB7000E7C6E0BE9091ECD5E636DDF516D4535E0F
+:10BB800089CE8F86DA89D2D2954A9C5F6B9FAAF6BE
+:10BB9000681AE379FDB2B3B44FA7DAA34394F2B4C1
+:10BBA000A57C3F60488BD61E8DABD6DA8FFA82100B
+:10BBB0003B73A9BA7FD049EBD32DD7E9F1FC7FA81D
+:10BBC000DD897BB0A81407AB7A06B4FE4DD730F6FA
+:10BBD000747EF7F98C1CDC1F9AB95AD0E83955CF1E
+:10BBE0000224287EA4E2E343D473883FF734B55F90
+:10BBF000D26F3EAF48704C2E4FD79C5362EC7E1EE6
+:10BC00002F71733AFAF5EA116BD1AEDDB7EEC63794
+:10BC1000317D69FD9DE1E504AFF5546F7FCBC6EB47
+:10BC200030FF5076BB3D12E6F5D0A853EF09D0EFB8
+:10BC30006A3CE385EBB378298FB6149E8BD0B37A38
+:10BC4000DADFDBA40F4C9F0DE52B12451C91BE23C0
+:10BC50001D9832189D9F3059787EF5358CEEE33073
+:10BC6000E55C9F1A87093DD7B7CAC3C75905F0C419
+:10BC7000733596187E1FA939E1FEE908EF668781C2
+:10BC8000E139398B72EE4F62D5AE2AA877DC7EBFE0
+:10BC90007D16EE0B6718887EA498CE26C493D99E95
+:10BCA00063AFC27142E235CD29E9372059BCB5FBFB
+:10BCB000F09E67207D7BCFC92F319D2AB5EFC3F35E
+:10BCC000255246889FD26BBF9811DC9B87335F4A11
+:10BCD00032963B6E10914E75EB6F9A86FE54C150B2
+:10BCE000E71A584F5802F31B601E61BDF689797B35
+:10BCF000A9209CCED54896F5150DD8DFA808BA7FA7
+:10BD0000C0BE03AECBA7F34DF457F680A8473A0E5A
+:10BD100053F68FC3327BED1FD3FCC2304DE1593B4C
+:10BD2000E4C3157A5F637BCA87FB776B13526E108F
+:10BD30001D3DF5695F19D6BBF2BB1BAB685FFD26E5
+:10BD40009315CF9F8529FBCAA1E374A53A5B67438E
+:10BD50006AB418647316F1550F5F72E0D85383E626
+:10BD600001F5FA9CA73A6E731EC783DA9FD1C264AD
+:10BD7000B42343F7AD43FB817970BE56EAA9FD3188
+:10BD8000D646E70174888B517DB5ABA7B90DDFE9C5
+:10BD900024BB1FFF82E382CC1A43FC35AC55DBCEBB
+:10BDA0009CCACF0DA8F4182A2FA5D0FDF7D47A6F1E
+:10BDB00038E1819F2708AD1F0AD7D0F6F0B7335876
+:10BDC000DEDD60E1FB885DA99DB922AC7BA53D4726
+:10BDD000337F5ABFD0D37FEFFD3C6DBE4C36F6B9F2
+:10BDE0003E94077DCD77824EBB6F596CD1B62F8DB7
+:10BDF000D17E772568F39245E9DF916DA2F31A8E23
+:10BE00007C139EF753F9D818E2EFF78ADF2AFA2E4F
+:10BE100091C9741E7593DE790EE5C4E33340D201F7
+:10BE20007D3C2CF8CC582E55B45B510FC6ADD39346
+:10BE30009C7AFCAE5BCEE0BDA016A06B84E571F7EA
+:10BE4000479B6EC57CB148F10D9BFB7039D251CB3D
+:10BE5000775FBF371BCF9F3A0D74CE5B3DB7B1758F
+:10BE6000AC612B1E0B8ACB94CD69F0FDA12AE68430
+:10BE700099B02363632371FC2DD1A215F5DDF3D1B5
+:10BE8000F5FF8E7194E6198CF61942E15737D246C8
+:10BE900072366E75B680F75B1E1E9B5F8972310627
+:10BEA000FC6594AF90CA7DC517C715F0F8C0B6C53C
+:10BEB0002FC523BE37580FDB699E15A213A7D85292
+:10BEC000C1E57F8B85D13E7BF3A852371E4DEC72C6
+:10BED000C90E3C8BD8E2DE41F35E592D72D9AC9C81
+:10BEE000970158C851399CBE0C364AFD986E34B340
+:10BEF000F839289792C2E87C507FF681B484CB57FA
+:10BF00006C6FCCE9BFDE43118DF1C85CCB67E49F59
+:10BF10009F0BFD6D9DB199F2AA3C8D53E8BBBBDF31
+:10BF2000103DBA1BF04B72361AE42C9EC7638E8705
+:10BF300089B775F5C2B4203AD555807CCDE2E72E9D
+:10BF4000307EBBBEA834E387FC4C9D9BCBE51855E7
+:10BF50001EBBEB9761DC05DAFB515F633F78CE0FC8
+:10BF60005219D7B751A83F447EF30C8303EF39E849
+:10BF70002A400E437B5D82564F1C18C9F135FBC128
+:10BF8000BBCC9EA0384D8C721E66A3BEDE9C06EB19
+:10BF9000D93843746E07786CA96810FA8AC7C455FB
+:10BFA000707E990DF5D16FDE5291131BBC9E668C8D
+:10BFB00073C0D036D70F9FDBD385C8BF5D2379BC54
+:10BFC000BD67DD1CBE71403FA8879A4797AEE66A01
+:10BFD000DA41725567E56D6DAE7A3A07D955C1CF32
+:10BFE0005DAD13F87E82A4C4CB9B8BF249BFF44BAA
+:10BFF0002F152B499F84E2579D3FFDE507E91199D5
+:10C00000F1F119879BB4CE4CFAE107DA3B74F94A97
+:10C010007DD40B1E6D7FBA625136E3F8A85F10AF76
+:10C020003AE6C57B93A1FD952AFC163A1FC969E043
+:10C03000EDB19D8DF88BF4DB6901E0C8E982CEA1FA
+:10C04000B3F7383CB7243A7C6BF8012ED28774AE34
+:10C050002BA5F7788F098E65B8EFE87D5DA2F3E731
+:10C06000A17A4FCDAB7030B136E79C3EEC4D9C0FC2
+:10C07000EA3569A7D789FA01D0978AED362A4B09A4
+:10C08000BBB3D45CE0E8ADD7BA5C6DABAF82729362
+:10C090008399F6033C4C53997F30C079ED33CF1C24
+:10C0A000BF8AF53D0EAE03F899E0BCE6F94733E6EA
+:10C0B000407BF3EDAD26B4B943CFA1F56EEFA47686
+:10C0C000714BAB4CD319C5236554B986080BD9AF56
+:10C0D000CC7486E4B334C9C6EDA7103DB90EF85050
+:10C0E0008FF04A6404AFD03871E8F84905C9FCDE26
+:10C0F000E4E2521A774345A71EE3905DAE7AC54E3F
+:10C10000F2F4A9EF42FBB17B3AA723FF77151AC8D7
+:10C110001E7EF8C1499311CFDE6512C5D17AD17B5D
+:10C12000C8BA3D23F59CAE1C8BCD287FB7CCB9DBBC
+:10C13000ECE8C3FED852318BCE2F5A96703B63A5E4
+:10C14000BD81E488A542B9E7A2D8CB71AABF13A2EA
+:10C1500027B7543798F1DE9B7ADE9085D8DB97EDD0
+:10C16000BF1FBDBB61F98BF1A84FEE2A6988C77963
+:10C170006F89F04F7713DFD5939F02F2381EE5F1F8
+:10C18000A2910E922FDDF27FC6393B0E1E18695523
+:10C19000F88ADB435FE27F41BF668D92A714601C83
+:10C1A0002DB5448E7660BC74DFBBD300AE93BD7AF0
+:10C1B000F2638DFB81F4C12F322638495F9E1E68E1
+:10C1C000B0229DAC6AFC468FF76BCEE2E955E87F62
+:10C1D0005502B78756C51898DF42F3A1454F752E13
+:10C1E00066A8A7F509DC3701BFC58F79162310FDB6
+:10C1F0004C8EF1BAAD00872931BEBB30AD4AACD709
+:10C20000D9609C1247B480F09DA263C5061EAF9D05
+:10C2100085F35C11F311C55927A7C5D17D54A3C57A
+:10C22000ADC3FBC97A67D5F6B58CCE8B51BC15B0C2
+:10C230004AF7E18C18C7BDB6278EABEE13A9F1DC27
+:10C24000750529042F21C1FF2DE223CB1A10F11E01
+:10C250007E983E40F6F8AA4613F941CD093BDA91A3
+:10C260003D3223F83EA47A3E17E063B1027C560CBF
+:10C27000BC9BD6959414BB17E7A5FA91F120AF505B
+:10C28000DE6525CC9B8AEB4B7AC3ED4A867AC60CD9
+:10C290005D366016E0EAB9A278AC1EC6213C58D8DB
+:10C2A000384CFBABBF22D140F1D8D0F2270B785CE1
+:10C2B000320B0521AEEB5E13DDCF5D75E0BEF7AA54
+:10C2C000507E1E3039C967678114BCFFDE1D77665A
+:10C2D0007CFFDDAE9CBFB5DB0D743FA63BBECCF84A
+:10C2E000BEBC1AE7881AE5D98C78F231C721F4C7A9
+:10C2F000FEAB718F1B46CA4F607FAC6DC015C56326
+:10C30000C2C6EA689F2729857982F7055629EB5F1F
+:10C31000D50D877A3BEAF575289407F60F878D3798
+:10C32000E7BB2622DD46EC8847FDDA47BC431317FE
+:10C33000C17B2879B10462FA93AA799C2466EA3C0D
+:10C340008A774853F93ED90A1660FCDCA0C0847C89
+:10C35000BAEA4BFD0D7087E8D7CC7A929391AE90F4
+:10C36000B8482F7F45E6766588DCDBA2F0F9F1025C
+:10C3700025EE91CFF2BFE79325BB2852D9F7891854
+:10C38000954272E811570AD943C41C41F0BE9C9DE6
+:10C390007350B1877EA79C8FF72BE7830F2BE78322
+:10C3A0005FC5770BC0903F86EF16407ABCC949E560
+:10C3B0006F341528CA99E36F45EE9248B21F94F97D
+:10C3C000E994F9ADB04E7325037E566DD3D37958F9
+:10C3D00063C284E968CF32AFDC9E11DB73EF8775EF
+:10C3E000C2BFFC9E73A75D091E3A4F3AC7CAF73F0A
+:10C3F000557C2D54EAAF12B619905FC7766AE136C4
+:10C40000FE52A4C6AE2C62DAF397134D4334F54BBB
+:10C41000ACDAF39793ECD76ABE4F7668CF5F5E973E
+:10C42000313E641F564B570B13806E804EAA337DEE
+:10C4300034FF85D6528A7BCD0DB9C77447AB363FE2
+:10C44000DFA7CD2FDCADCDABE7C9C34629F43092D1
+:10C450008DFC31F14EE4F70C85EF0701BF6FB33A65
+:10C460009911DACF1678BFF81EC6001BED4BC976BE
+:10C470008C23ACE3F79FB05CC7CBBDC395F67ABE07
+:10C480006FC58EDBE8BE1D4BCCE1ED06F0EF7EFC08
+:10C490008EA4F1720EAF87FE12D61BA2F453C3E531
+:10C4A000939C45FE829BEC33236BB3626A01FEC210
+:10C4B000349A39E99E750CAB27BF7590727F325163
+:10C4C000E8A4BC43B086613E4570A6F0F8858FE4D1
+:10C4D000C35049FE752AF1895B7447F4E6970DB99C
+:10C4E000BA07F0AAF8860291E4E2235646EFF9D89B
+:10C4F0005CF713BF6EC316B06E336B8F49157AF8B5
+:10C50000E7EDBC61C45F135C0EDA2FB515240B7820
+:10C510002EA588859CCB364569E8A3C41A17425FCF
+:10C520004342E84B4B7F7F9DECD5453990CE42E8A6
+:10C53000F02FBEE5512C18AF4C8FFA058FD58976B8
+:10C540004A059ECA02964F75469B31EE678BD173A2
+:10C5500079A5D83FA54A9FABE459EBB2E1FB6B56F6
+:10C56000D149E6F6BA2D3DF12518DF9600F635EAF9
+:10C570006399915C7DB0D31F7635D47F04FCFF6551
+:10C580000CFD1BEB64BCEF65B5E4105F3F624979BD
+:10C5900000F35ED0E8587F4331F7AFE5E86C82EFF7
+:10C5A00051A1BE05EFA53DC2F24CA9C1F52DBCFEBF
+:10C5B0007A596451909F183182EABF9D6766F8CE20
+:10C5C0008177A0D98771EC63F2AC77DD41EB7F7B9B
+:10C5D00014D707AF191CF1A80F1E997C77A687D234
+:10C5E000748D5F684B10E4BECE17858F3672BD9296
+:10C5F0005BE2C7787C74C234579903FD1DB70BE921
+:10C6000042E712F1E85B37FD442B7EA8E406C10F38
+:10C610004B9B745D0E43FFE3110B77351E299ED5AE
+:10C620005286F90291EE03D95CE2EBD9B8AE027EF4
+:10C63000FEF04AE571A81E18329ADBBF9386443C8F
+:10C640003014FADF50245AB1FF0D7A2BDDE7F14E9A
+:10C6500066E45717BBEA97E0BC6D09110CCF6FDA9F
+:10C660000A1A78BED8C0CC004F936BBD17F1694A47
+:10C67000F58CC0F647077E7A1CED195B82483A704C
+:10C68000A2CBF9AE1BEB1728F19DE279EB703C9B36
+:10C6900045B49A590F1C54B9BE9EC9CBC9FFB20A02
+:10C6A000F4DECC0A6B430DCEE7918470B2F36DAE2D
+:10C6B000060BE279C3403DD14149227F576A55C2FA
+:10C6C000B40ACCFF62A09171BEF32F1F8AFE815382
+:10C6D000A075355B1A685EC72E8939C1EF96A8A987
+:10C6E000D9A185CFEF46F1F89009E3F1809FB7F526
+:10C6F000CC9C9A8BF4A3A778537F7C6B735DCE7E22
+:10C70000FB61FE2A94030B11BE8597C2984F40FA35
+:10C710003D2961FE777F015B80D6D960C1FE416E05
+:10C72000BBFAA2BF88D19C7E9B0B0E4BF84E82D7E2
+:10C7300021101F345B4E4E443E7828B58CE8E8A1AA
+:10C74000828F9A892F86F3FCDB79F7EE413C7A13CE
+:10C75000C3697FE7A1825931C1F4BE609448F432C5
+:10C76000EE6F614E3FE2639481F8FB9108C7568CEF
+:10C770004F79F3CC64BF4B8275D96C98E7C46228BB
+:10C7800087FEA25D623EF17E75058F0B2B307ED554
+:10C79000653B84F8904A66317EAE4939F71491EFD3
+:10C7A0005C4335B4FA6F952597DECFD892D07042AE
+:10C7B000D9B620BB6A9022570694884528DF0659CF
+:10C7C000B85D65EB940594BBA1FB47AABED729EDE4
+:10C7D0008C325BA6A3541B37D215707D1B6A7FE990
+:10C7E0002CDC5EC33FBC8FAECF353F89E738743158
+:10C7F000DA7A7F19A59C730AB1AF543ADF60E57A03
+:10C800006243AED18774BDA198DB592A1FABF247B2
+:10C8100085BF2A87D47B7EEF28F695514E5E3687FA
+:10C82000E4EA99E5786F07D49E7317C37B8956FABB
+:10C83000FEAE721FF194626FBDA7D85BFFA1D85BFB
+:10C84000EFA3BD05F986518308BF37142E76DD08A6
+:10C85000F31A902011DF143A4E4CC4EDAF71192732
+:10C860002C7DD96111D1A20EE3058F34F27B4936BC
+:10C8700097ED9815F159CF95F92C6B766934BBBCBF
+:10C880007CF2E37AD2D13EE4EB7B55B94F794C99F7
+:10C89000FF7165FE6F28F357ED8F4943BE32A1BC8F
+:10C8A000DF10AFEF477E29FC29A7D0B9A85079B592
+:10C8B00001C408E9EB2291FC9F2078E76AE4BD25DA
+:10C8C00020F7F54E59C9681EBFDB6076572C467CB1
+:10C8D0004E6614A79DE8AA27B96503B94572B3F857
+:10C8E0005CEB6CCA473883E59E518163B1CB5A8EAD
+:10C8F00072BE38464F1F5724A4D0BD5BD5FE0E1D17
+:10C90000F772F00C9567A682F55EE2F3FF47726C52
+:10C910002CE3E38EBD243AFD5CDE1C4F2679239187
+:10C920007C0AED5F95376F63CC6420BE4F64A1FB3A
+:10C9300000770A614E84E79D287C303F97D17DFFC8
+:10C94000C18A3D6757DED1014EA1B8CED84EB0F5B1
+:10C9500083F87AFC2553F71B6CDC8E8FD6E4279A7C
+:10C96000E235F54BACC99AEF93ECC335DF273BB208
+:10C9700035F9EB324669EAFFC259A4C9DF50305994
+:10C9800053BF4C2ED3E46566A577480E36ED1EFAEC
+:10C99000B11EFDA7B6A11FA7F5864FA1F1F00B0EA2
+:10C9A00060E1B5A38B67E80046855187EF4C86FCB4
+:10C9B000C6D19367E880EF0A071FFE3A195868D37B
+:10C9C000E8293C7FF5E1AF5320BF65F4753C3F8615
+:10C9D00091F0DC3A7AEA0C2FE0591CEA797434D0F1
+:10C9E000F12D97EA8FA23DF8C765D3E6264BF84EA6
+:10C9F00040596206CCE76C8AE761FC7E73ECAC15AB
+:10CA0000781176FC77F5748FED37A379BB8E8BFCAC
+:10CA10005D8D8E8BFC1D0DBBC8F1F65353F5BECB5F
+:10CA2000040E9A7EDF5F11647EAF05FDCD3969DCAF
+:10CA3000DFC414FD4D4CD1DFC414FDCD397AEE6F47
+:10CA4000628AFE2696A3BF89E95B4D32A5EF34B911
+:10CA5000286D6F7253DA7DBFE029E76A3D0A38EF2F
+:10CA60004F8B5B98C3E417114EA1E74A3AF49D4FF0
+:10CA7000D07ECA45E6C0FB1287224E3970BFAC3962
+:10CA8000CF44742E74B63B4CF0BD3097E79B2FB665
+:10CA90003B507E611EED9E8EE8B66C94BFCDB51600
+:10CAA00027EEBB355FF4C7239F14D61BE8DE4C711D
+:10CAB0006727C5E90A2DFCBD844311C78E28E39181
+:10CAC0005CDA7991F9457C27C7DCEEB02AE3603F58
+:10CAD000306E32EAB7C225302EF55BBF98FAA9B0A6
+:10CAE000748F2B848C6BFAE171270A41E3A67631AF
+:10CAF0007A1701C77568C6F54B743FFCA25FC27810
+:10CB00006147B4D38E714D355F8CDF21BF45CFDFD8
+:10CB10005F2C74F825D493B8BD89EF5BC681D833F8
+:10CB2000D3790D1FC965A84771B99D5D7C9D179A82
+:10CB3000FC0B909F8A957760C08CA57B9B4C0C73F7
+:10CB4000A2BE2891BE3B363817DF39E3EFA0151B94
+:10CB5000DDDB901FEB745CDEB01833DF57D0B5CF50
+:10CB6000FF15D43B193B98EC9504FB4B2C7504B492
+:10CB70005FE4CA44BBE3245B4F72687594E77F8F20
+:10CB8000067ABE31B35E50F427F5637785EFC0FDBA
+:10CB9000888E5786E5211F4D333A5E64C0BF7F1FE4
+:10CBA000DD44FC3C2DCA91872FACFD7DF40A9E8F9D
+:10CBB00073BC883783ADAC694671FC8F3F2F45F15C
+:10CBC0000D749AA70A3AB47FD4735376D1133606FC
+:10CBD000E054EBFACAC0E7D769C07870D41807C12F
+:10CBE0006FE06146E7983A2747F876E07EDF80FA03
+:10CBF0006C8C87B24C471ED64BD277D27DF28EEF2B
+:10CC0000F8FD27A819795350FCFE898392ABAFF841
+:10CC1000E3C931DC4E5D946A598778A8B39B4C9484
+:10CC20001EBC48E78299CE9D8AF16BD9D0F77BA9CB
+:10CC3000AF8EE1FA2179A54131024174C294E53009
+:10CC4000A6E6BD0CF4D0F6BBC3BADF8B037032434B
+:10CC50009AC8F3DE1D8F17EB34F565ACDFFD1DE3DD
+:10CC6000F4ACA7BDFCDBCD8F2F4F55C6437A99C7D7
+:10CC7000C87F0CD53B6B0B6DEA3B3F84E7C763CCA9
+:10CC8000DBE93D5249798714EA5A314E11CEE83D2D
+:10CC9000AEC1BF37FB9A819E769A393DA78A3CDDAB
+:10CCA00029F2FAEA3BA5EABB6BCF147A6E2BCCA330
+:10CCB0007EFCD48FB4371BDFCB88676D34BEFA6E31
+:10CCC000945A2F01F420092B5D673AE2AB5012FB16
+:10CCD00084E7E7638AE6201D5C68F2B24F82F4CDF8
+:10CCE00085F0C8C660FCD549DAF75A3F1F3381DAB0
+:10CCF000A9ED6B1B27B24F2878E9273AAA4D156991
+:10CD00001FBD4E62AFE23B9C20590DA897D576A778
+:10CD100040DEE278EF82FCC5F43D90BB9FE8D13E57
+:10CD20009D4EE9FB4D1E2A3FDD544D69A0A99ECAC8
+:10CD30003F6A6AA4F496DB2372917F16ED5FC63ECC
+:10CD400009A2F7DA36BD2710943F55D4371DAD51EF
+:10CD5000E8E85472DFDF9F1CC3EDBB53E3383E3B72
+:10CD6000C0DEC0F7DA802E975B6DFDDB1D1DCAFDAE
+:10CD7000AEA3E3F9FE65473CCF2F1FC3FD6E596498
+:10CD8000ADD8FEE87803EF3F45ACC6EFB28DF77B38
+:10CD90002A5DA477A47E35B1E8FE31583F16CA73E8
+:10CDA0007AF2A7AEE2DFE541BC5C9DAFFAFDB64288
+:10CDB000ABFAEE613A7FCF8FDFF7027AA7FED5FAA2
+:10CDC0006326703E0CADEF4BE5E7C943E1F1A9C224
+:10CDD000B7C4176867231F2407F1459D83F842A550
+:10CDE0004395FED6167238A71A153A0FE7E7EE07F5
+:10CDF000A32E847683E3CCB48F20E3BBCBB09E9D7F
+:10CE000082C22FA1FCA0BC63ACF283CA072ABD0F6B
+:10CE1000063EE3EF34F3758C95FA795F5859477BFA
+:10CE20006CC45D84D7837A2BEAADB1127F2F79B0C1
+:10CE3000D8F5CEEDC89FB1110E8C9196ACB2D4F757
+:10CE400025C73EFEAFC243950BFDC0A3171C0CCAFD
+:10CE5000BBC33F120E24E7508E23FDF621B74E8C44
+:10CE6000B1297617A7DFCFC7C86F221D7508661DC9
+:10CE7000DE7BE830F77D5FF0E878BE0E958ED61643
+:10CE8000324A07E33A87F6967BEA7ABAD7790723DC
+:10CE9000F9971AC6CB43F1ACAE2B48FE9DC179A9D8
+:10CEA000F0640CEC1FE827A1C642EFE8DD56E8E08D
+:10CEB000FC36F0D3CA0DAC67FD358A3E7B4C94F846
+:10CEC0007BC88A7EE92E17A49965991ABD4347CF7E
+:10CED0003A5FE1EF8AFB45568DEF72A36F1D1C1779
+:10CEE0001F52C8E543D7F43C11F7132FFCD542F786
+:10CEF0008B2F0CEA3C8DF6CE85563D53DE239B2AC4
+:10CF000080DE9D8B3E130CF9A5F29EF3E7E8F70E49
+:10CF1000837A6D174FA3BDB568ABC44C789E60EBA8
+:10CF200037B7203DCD7B454FE7999A5B371E477A4F
+:10CF30003CB74FC0E76FD9857D02C5316B5B227C62
+:10CF400066A85F0A79AC7FC76EC9C7E38B32C53963
+:10CF50006A94F13E31D7A5A05D3E71EB5D3A84FB4A
+:10CF6000BCED028B837E8FB4DE790CDF1D39B78D6B
+:10CF7000DF2F6B3647EEC0F9974AEB0C83A07CC1DC
+:10CF8000765E5E6329FD0CF743173CCD28FEB36047
+:10CF90006F04F98FF35AF41F0582EC8EEA6DDAFC08
+:10CFA0007CD666403A58B0535B5EB307F241F279E3
+:10CFB00050A1122F19CEB2295ED2C2E307AA7CEF8C
+:10CFC0006D5F7BB91C6D50DEFF667F89A5F70F5F33
+:10CFD000F926E9230BCF9729F93390FFEA1B8E1727
+:10CFE000152E75CAD85FC5B3DC365867DD2B662BA6
+:10CFF000FAED7507CE46E279B04561017A1799BD21
+:10D000002C59D1DE7B60BFE445F8D61E343F89FB46
+:10D0100098752F9E30603CA174DF62B2572631EFC5
+:10D020004AF49BFDA2C8DA898EDAE97D5F2677CEC5
+:10D03000C37E2E1C305BD10EA87BF94FC76EC7FC98
+:10D040008B02DDA7BC9018203A99B755A27B430C00
+:10D050002DB4FC1E3A9110AF88E7B6287A8FE50E02
+:10D06000C43BE219F0EE48463AE171D0794F4BF4F7
+:10D07000BDB9B5D980F5CFF9387E55BC974A4B0973
+:10D08000CF0B1EE7F89CB875D7E630A483A7F564EC
+:10D090008F1F817683783B0D1D185EE1FD5FD8C53B
+:10D0A000CF9177D3C10163371DE03C2F4707C0A75D
+:10D0B000A4F72F47079DE89792BFFFDDB9C7D00EB1
+:10D0C0008FE0E787D5771BD5771A072E3C7514DFDD
+:10D0D000E74AB3BF407677A5ED8BDAC58CDE099DB4
+:10D0E0005388E74B26BFBD02D17772CAB3D9142F3C
+:10D0F000D507766DC178437438C5C73A92CBB6E18F
+:10D10000FB98C5B66F93F6C23A16FDCE48E711EB11
+:10D11000157EC63F3C07A2BE4B0C78A7F319B50796
+:10D120008DFC5CC63EEDFBE11DF19CCE4B0C9D954C
+:10D130008BD14F80FE701C41E6FEE9C283FC1D4589
+:10D14000D59F5CA8BEA7B847FB6E83607D9BEA3D78
+:10D1500050984270181A37D68176797339F3840D56
+:10D16000FD217DC1DFA97C5CF18BFAB527FBD11BCA
+:10D17000AA1DC9BC21F7DA15B97547019FE3D1BBD8
+:10D18000DFD0E17B8C1D3BF9EF3BCC3F08F22A0658
+:10D19000F719F51AB953A7D4FF14E90FE076DE5B4F
+:10D1A000FF922805CB97F78BB19F9AA7793F7548D7
+:10D1B000571457F56F0E83FEBE6CD333E497054CBE
+:10D1C0009137FB23286ED44BBEECDCBE12CDF7505A
+:10D1D000BA5A0876262E2294BEEAF669EB3D5DA87F
+:10D1E000EC7B0E67D7E0F9FFAF31E090D7235FBA51
+:10D1F000DFE9678E28E4EF6E7D2868EFEF0F6B059F
+:10D20000960FEA77B8CFC463A44AFEEADD564DFE16
+:10D210009A36BBA6FEB5FB1D9AEFD9FE0CCDF711D1
+:10D22000C79D9A7C5E7B81A6FEC8F7644D7E54C084
+:10D23000A5A93FE6BC5B93EFCA84F5F461CFA8E9EA
+:10D2400024BBA0A93FD961D6F47F5D46B426DF6533
+:10D2500051E0A3D899AAFDFBA7426EFF86A62A7CBF
+:10D260007FE1D48EA3FAED371468C72B93B5E35D45
+:10D27000295EF01D419D9EFF7E02A6F8FB09BA348F
+:10D28000FEFB0998C7DF4FC0147F3F01CB7FDDE471
+:10D29000A4FCBEA602CABF047E09E6F7839F82E90A
+:10D2A000CBE09F60F9E5E0774C19F7B832EE1BCA86
+:10D2B000B83F154E6F29FDBDA3F487EF0DEAF43D8D
+:10D2C000DF6B5D79E225E0E322DB67745F596E086E
+:10D2D00094621CA3F37589E1F967E6F11D6F8A4139
+:10D2E000FD3680A19DC4DC9D6FE23E6EDD8B43ADBB
+:10D2F00078AEEF81FD7F7807BF5FD82751BCE6F09D
+:10D30000FEB391D8CF9797C2E9300AE945C8D77CD8
+:10D310002B507E0D7CC7736793F74ACABB676DA419
+:10D32000EFBE4C55F33EBA2FEDDEB3D780785AB836
+:10D330007B2F7D7F1DF85AF37DF776CD772BD6872F
+:10D3400074A1CE477185CFF7ABFDF9A97E4D2A7F39
+:10D350003FFEF3DD47568E417DBCB76A00C6B51768
+:10D36000EE39113BFB07F0F1D54BCF66A21EA83D6D
+:10D370002029E7D1787FB507F44A9ECFBF26756F85
+:10D38000299E37637B04BAB3F4255B4FE7C416EEDE
+:10D39000DF5583727661C6ED7A8A7FB5494ABC83D0
+:10D3A000BFD3506365DCAE6BFB3A12DFA9FF7DDBB8
+:10D3B000D1EBF11E74C7C123F45E4CC73E49E34F65
+:10D3C0008D1DCBF13B762CF7FFBEDC772412CF0905
+:10D3D0003ED07684C35DE7A7F51F56F21D9012BCC0
+:10D3E000F74BB4FEF99724CDEF01B8C071A1FBCD86
+:10D3F000FBD322705D27DBF878D3407D50796AD566
+:10D400001C9CFF1BF6F23CE57D32FADDA18EABAE33
+:10D41000DB857276619BD4E779F739D82FCCEF980A
+:10D420009ED3E9EBA92F1C1B04707FC335209B748E
+:10D430008452AF622CD79BA5064F2AEA91931647D8
+:10D4400004D2F9FDAEA11188DFC39862B9EB49BAE5
+:10D4500007BE601F1FEFA4B53D12E9EEE4BE1152F6
+:10D46000F0FECB2DCA7ABAE9BB1B6F5EC253B56F13
+:10D47000BB05FBE9C11F2F9F36D64AF5DFF09DB8EB
+:10D4800005EDAC9319FCDDC0630646FEF5C23DDC3C
+:10D490004E3E7970F0F6E0FB59D3147C7464F07D55
+:10D4A000F50BFBF54ABDDB77314D3D3DC7D74EED62
+:10D4B0007CACBE330FA17D5EF3B844671D6AF4F502
+:10D4C000B1B8FE4FB769E757ADC0B946EF8F8D0DC4
+:10D4D000A2D79A03DD7C63213A3FA0F28983F0A9A9
+:10D4E000E2F16486C4E765E7EFF8D5ECDD4574DD6D
+:10D4F0003BBEC4E3B783EF313929BE74197F5AB5F7
+:10D500001B82FC2DFABD23BD6B689E98D2631F9CC5
+:10D510002E941F1A9B877E989BFCCC930CEC5B1877
+:10D52000B316EDEB28FA1D89CD386ED73E3DBDFF11
+:10D530005F6B3AB000DF23EF7202A3C0BCBBB6E959
+:10D54000BBDF67463B779E62E77EEAF0E44BA07F55
+:10D550006B9789B4BE9A3D920FCF175C50E4DE57AB
+:10D560007B936F407AAD392E59D13F9AD896FC7093
+:10D57000612EE977B257EBDAB89D5CB75B20BB58F8
+:10D58000B5436A153BE49C62079F5BD6C9EDE35740
+:10D5900004B611EAAD0D037B04E65D9B3985ECDA38
+:10D5A0005A69DDCAC10E3C47A5B51BE61F3C44E7DE
+:10D5B000AEC0CED1942FDCADCDD7B669F3AABFF8FB
+:10D5C000D2D86E3B6338FA372552611CF2C39B0AEE
+:10D5D0005E557FE7CE6B9CF4FB270FE81C53D4B855
+:10D5E00004C26BD12B2FCCC779FB6AC29CE47F3479
+:10D5F000FE96E0DAF117EED774E0DE1BF233E3F0CB
+:10D60000EDD8CFE97C915EF0E1EFBA2C425D81FD6F
+:10D610009904DF328C3B7BBB22493E29E7081ACABA
+:10D62000B9FF2A630C18A6B27E2CF7E743F5EA3857
+:10D630005D408A0E921381B12954AFD8C0CF57DE16
+:10D6400019E124FD36C4C4EDF521266EAF0FD17566
+:10D650002EA3DF851824F07D8EAC9769FF606D9D49
+:10D6600085F617047B950EE1B17650950EE97D881D
+:10D67000B52D03FD3A355F8CDF337BEC83528B474E
+:10D6800087E3EC8C17947D04AE4FCB74567D749079
+:10D690007E656C99667EEA3DCC9F7D7E56989FA5FF
+:10D6A000677E80EF286CFF75AE93EC86A432F5F7A9
+:10D6B0001AEA492EA8F0FC12E8BD187045776C8173
+:10D6C0006E6AB61D22FFB296B5AFC476A5917C1DD9
+:10D6D000A506FEBE5169184F75E3B8FC2A51D2A5C4
+:10D6E000E3B4F6C39171B27E1CA43BC6B94DE3F21C
+:10D6F000683F9579617D0D6FF377D643E53E9413CE
+:10D700003D7D0D7C88F26F46BD604DD5D8699CBFCC
+:10D7100016F1A26E3E5AF8F693C427EA39CC6AC6CF
+:10D72000F97B66A3D99A1AC4178B90DFD0DE77C332
+:10D73000BF7C8C13F0BF6AEB7C3A97E9698CB5A289
+:10D740005FB748FA92F6257E2CDF2DDAAFCDFBCD00
+:10D750009CFEFD1102F94919E3BAE30DC48F490A91
+:10D760007F6CF708740E60FB773A1ECFAB10287EF3
+:10D7700077331436DA944962BDEA22BA4F7233E342
+:10D780004763594B8CF2BB3D31B46F7993B2EE9B3A
+:10D7900075FE4328578EEADB92319E74B4D6E4C4FA
+:10D7A000FECB591BBD6F5AC1DA293D155EF7A29F0A
+:10D7B0003AF72622DDFDC963A478D6F6E53B225070
+:10D7C000BE67B1E556DC4F0450ECC6B701FBB3733E
+:10D7D00042F71DD5FBC4602FC7217D02FE27211D06
+:10D7E0009C07DCD8737AB75FF8C71723117F5F2CCB
+:10D7F00079E1965B19FA5F9DE4472DA85F46F75DD6
+:10D80000819CDA33F27BF0AAE25DC55B375E1DF0E6
+:10D810002F18AFB0A6048493F46519C9A57F91E8C9
+:10D820009CD6E5F0AAC27DBC829F3B0E70F9158A9A
+:10D830006F150FB7E2BBF54349EF6E233C3123C9A7
+:10D84000CB507AB81CBE8030E93CD9C41823F9A16A
+:10D8500083452E4F07CF13285E793BF3BC1280F42B
+:10D8600096F0F7F5FCDE0AC75B8582B73F31DF2F04
+:10D870003292FF71783B32CEDD346E606FBE0DE5C3
+:10D88000D3FEF8B2C6E1FC37555FFA18F263083FE1
+:10D8900087F06B371E9DF02F088F9EC648E2CB6E37
+:10D8A0007C4B7BAE4C2FE27F308EB55FF0F993AFAF
+:10D8B000805F0546BFBFF8F838ADDE54F1A6C2A5BB
+:10D8C000BFB8E007CC7FD42AD0BE0AE7E3BB8D7493
+:10D8D000FF43DD5751F74F5E19C7F55C68FA01D871
+:10D8E0004BB85FB526E3E440B4334F19D47EF8FE5D
+:10D8F000EF07CBDA13F1F7B63E28E2E92903FFDDA3
+:10D900000F352F87F1B8E407F1462FC2E90361F81C
+:10D9100004D4331F08F75CCFF3710607E6CBE32688
+:10D92000E03D90537A358E79BF127FF0F179948F74
+:10D930002CA67A02FF5D4A07FEDE1DF62B0836177D
+:10D94000CCE783BBD2E87D9DEE7D8D71DC0E7F46FA
+:10D95000594777DCFF5E81E2FE335135E1FEC48436
+:10D960002D2E7C87F3F47D43B369DFB4413B3EEA5F
+:10D97000FD648A976EE0E7FE2E75EAAB82F45BB732
+:10D98000BE2DBEC8CBE7E4D1EF8CA8BF4727DB860E
+:10D9900073FFDCC77FDF50D5675DC75FB004C77317
+:10D9A0003F53E2DFDDF9E10F2605EBC3434FAD4DF9
+:10D9B000C77EAA0DDE2CA7057F87EEB124B45BAA33
+:10D9C0009F5A954EF6F4530FA4A35F54BD636DBAEE
+:10D9D0004CF9700FF9653ABEEE2F9E1B45E7F3D464
+:10D9E000FEF6CADCAFA8301D2A41BD3DE5EAAF56C0
+:10D9F000E0FE41DA7D02C5FF66B0F615A8672B335D
+:10DA0000385FB11613C97FE88FF66B770DFFC54EEF
+:10DA100094076F649CD5CF817A123E203510DFD5F4
+:10DA2000F2ADA3DF095CCD7F27B0A77E22EDFF56C4
+:10DA30002D17E89DAB19F5FC77F3A4F1D104C75974
+:10DA4000ABB38FD1FB574B79F914A36FDF49EC6768
+:10DA50008B81DF3F64EE94E0FB7092B25F38739D80
+:10DA6000F27B71CA38699B63B707AF5352F61D59F1
+:10DA7000EA7724DF6E50F03275E98957EDD0EF5424
+:10DA8000BDC73C1EBEBFB3E95CAA9F611CF4333A1C
+:10DA90005F9866F03C3A1FD7BDC34871D2DCACC179
+:10DAA000521CD4CF5952B411D3994BAB1E9D8F72D7
+:10DAB000B8D594CD8F35F2F935084E11E5F491EDD6
+:10DAC000B7CE42B89DDFC47FFFAB61FB30FADDC249
+:10DAD000FEE4DEAF9AF8EFF93DDD64A2F4D9262B1F
+:10DAE000C3A3EBCF35D929FFAF4D0E4AD9F43CCDB6
+:10DAF000EFD8F4D7DF884BE1F4BB73B9ABCDF43B7F
+:10DB0000880D4639753CC02BEDAADA1D0F28EBC2F3
+:10DB1000F7B8B2BDC913110EB90F2C3E86A6B37566
+:10DB20003CDF977DF3E4EA2414D6772C3DF3C47CE4
+:10DB3000F87EFB78F7350827D3B68B14A7387260C8
+:10DB40005525C2BB7A8791AF4F59F7F94DE9718FCF
+:10DB5000627CF9753DC50D166D3BF3C4030C7F87E0
+:10DB600077B12198DEAF74BD578FE77EE6E5F8AA5E
+:10DB70003F38FC78BE5A9B44FCB303F82AF3A7F362
+:10DB8000D5A2A5CB087ECBC6BB6F42B89DD77B93F1
+:10DB9000909FCE0F1F4B74EE7D4520F8AB72BCDB1F
+:10DBA000AF56E0BF506C5B5798DC23C7BF61B90428
+:10DBB000DF43073E4D47FBF99BFDE53FB8EE97601D
+:10DBC000DDFE6118AF33511AFA3DDFE019EA84F542
+:10DBD000E5F7F33EE8D2F16AFC9F9F53C03F213640
+:10DBE000F89D21E68D82F9D41C14FC6159A8CF263A
+:10DBF0007DA643BF11FCCF8F34E78C19FB28489FCB
+:10DC0000F737DFCBA575D84F5A8FDC1DF99EC8FCBE
+:10DC1000417A7B54208CF983C6EDF673A0CC40FB8F
+:10DC20004EF12417106F782EECC281E13B30FF9942
+:10DC300081E3F1C24B604FF1781093F27BD6F9D9B2
+:10DC4000812FB250CE86AEB7EEE52F883E6AF6AF92
+:10DC5000BA28D0FA277FA6CBBAFCFA0F3DF54516B5
+:10DC6000E2EF337D201FFDB60B864016E2A1EEB732
+:10DC70005C9EFF5838A8E5F3571BE8F73AEB04130E
+:10DC8000D14989F425C51F2E1CE7F187BA034F92AD
+:10DC90003CED3AC8E3408BC4F6D2388C9BD49F3914
+:10DCA00086F2ACCBCEFD31E89FDE712B1CAAE84199
+:10DCB0005D6712DEF73BD84D0FDC8F3C8FFC3B0CD1
+:10DCC000FB69A3F3BD2C2B9CA15DF139F2F3307CF1
+:10DCD000BF307925D2F979DFC01C948F6F66FDAD16
+:10DCE0008EE286BF0FA77BB2B56D92E69C79F73ABC
+:10DCF0007C123F70C454FB299CC9C1E7B90C8E1B30
+:10DD0000C86E7E83EF132EBA8AF3137B99F353ED1B
+:10DD1000F243067B507FBB157E52EDC829BFFF1B27
+:10DD2000F1E5B38532FD04D54FA5C7FF9FFEF74C43
+:10DD3000FF2F4133EC630080000000001F8B0800C0
+:10DD40000000000000FFA55A0D705455963EEFBD2F
+:10DD5000FE4927DD4913421208840642881A6203ED
+:10DD60008172D6C4E9FC6E2033BB016B2DC4088DD3
+:10DD700022249D7482E8EC6AB96E1A02AC6475368E
+:10DD80008C59471D479B9F8028EC769440C0A00D7E
+:10DD90000ACBA26B45AA263A555B54ABAC0EE0A663
+:10DDA00023823BD6E2B8E73BEFB5DD1DE24FEDA69F
+:10DDB0008ABA7DEECFB9E79E7BCE77CE3D8FB45247
+:10DDC00022CA226ACFCD082A0AFFA66EA245446D58
+:10DDD00029247FF641451FAFD364BC7D40A3C958B9
+:10DDE00093EB08CE9E415447DD269A45B4844265A4
+:10DDF000A471BF29F2CB5B79BCFE0D6D4117936115
+:10DE00001BAD6AB013D5A67A0B3614130DABCAAA94
+:10DE10008662CC0B952E9D4BF40DFE7E4A749B873B
+:10DE2000994F222AD3140FF61B9D9C16DCC95D8BDB
+:10DE300097FB1B494D98A7EAF3984F53087C82A3A0
+:10DE4000254B1DD868B46499233EEF8E37D2D60790
+:10DE5000314EA1D23B12F6F94B8F856821D117CBF9
+:10DE600017AA0F65F279AEDA037433518D76ED2976
+:10DE700085F7DD70CC4C5605FC67BCAFF239026704
+:10DE800034EA65FA52470A79ACCCCE4B1E0FCF1B51
+:10DE9000993B29D8C5E76F3FA09089E7B51DB1EE42
+:10DEA0004CE1796DE648B69BF7DD36F03B8B87DBBE
+:10DEB000F6FEF72CAEB958CF4736439E1415FA6DCF
+:10DEC00077F24F17917F60CEFB77313FFF694DF4BA
+:10DED000ED37BD6721D6D7059E8FFD5A0EF6D58248
+:10DEE0006EA5F05627DAFD3CAF48BF9B6FF8DFE523
+:10DEF0005C5786B3387EBEF8395DA2A718BDF869B5
+:10DF00003EF702D68B46EB437659EE21967B716E37
+:10DF1000CE8E2E25719DAE5F8F76694B0ECB159DF3
+:10DF2000A9B81566154D0D6C76421F858AB39717F3
+:10DF3000475F7FB9742DF49B122CBD9DCF17B59010
+:10DF4000DCC7E2C7B69BB40479160F6A1EDC433403
+:10DF5000959A0EC9BD7BA7E23EA8BC61A96712D6FF
+:10DF60008DBE7B2B6F195579BDFDFA7304CA757987
+:10DF7000CEB0A9C97D1B72D7E7E5ED80FED900C4FC
+:10DF80008E4EA9FAFE1E95C7E7C7D7BF689CA74665
+:10DF90002BCE89F0F806C59DE31C679F58BB87F51B
+:10DFA000BE86EFE945BE6FB42F753869CD6CA2FD12
+:10DFB0001DB942FF73874BDA504791F4BFD2E11687
+:10DFC000FA60C72D421FEAF0083DD05127EDD18EEF
+:10DFD00006E93F0351FF8C70A020ECE2147C6D4AEF
+:10DFE0009C1ECE1C434F499E3F9CA924D353149999
+:10DFF000FF70B83C1860FAA532A79C938DCAD1C0B7
+:10E00000FA684E4B2FA10CB4F9414A67BBB17B03B0
+:10E010001EB6FB3FD4EDDA4333C5CF4B30AF3AF3F6
+:10E02000CE46F8DBE52C2B69ACCFC31EEFDF63DEF9
+:10E03000E9D35505DBD13F68735BF9FE8757DC9464
+:10E0400001BD47FF4D238DB7AE285AB0B994E90AF8
+:10E05000BB2276CCFC6E6EC866BBC64FE65335B8A5
+:10E06000BAD4A4E38473B602FDB7AEC13E1B26DB6F
+:10E07000165879FC4AB9F757D827A6F7DA29EB0AD8
+:10E08000BCD08BD9F5BECAF302FF6EA65E9EF780A8
+:10E09000C39D64DF47CB2B82B09BC545B336CF070A
+:10E0A0007F76BAD9BC3FBBF57EC8E751D3944EC149
+:10E0B000319709B810C4FDF33E952E45EC306C71D4
+:10E0C0009932997F38B5222BC0EB4E19F77DDAB81B
+:10E0D000EF33C67DBFC3FDD5DCBECBFD6887B81F5F
+:10E0E000ED8A989E4DA385D05FF0A70D2F7944EF60
+:10E0F000A3F9A0A3665A0E3B5C023FD3F127BF8170
+:10E10000E578A25C97E36E037F866E6BE8D3D785D4
+:10E11000844F8B85BCB0FF4B589F609FB175F1F564
+:10E1200024EDB29B2990C2E7A0C3B620F4445389E2
+:10E13000805FCB0EE7082E6929B38ACF4F647A013E
+:10E14000099ED2AB567D5EAE6B21FC857524FB8C9F
+:10E1500004D58099EDC49F395498C9F28E187E1663
+:10E16000A30FFD4913FCF6CF679ADBD714FD7CFEA5
+:10E1700065438513B05EB1A9B033FF4E7DFCACE1C1
+:10E1800087FE99063FE33C9412CAC77D448F1DCE9B
+:10E19000BF87E92E7B78AD1E07C28582DF142E5C17
+:10E1A000069C5442E7C84DD477FC7DAFE927D047A1
+:10E1B000E879D0FDC77FAFD34ADF3967E2F8A450D2
+:10E1C000BEE204FD8141F73D3FC19D409B5F398721
+:10E1D00071CBA6DF7BAB27336E5883A73B6037FF3D
+:10E1E000A2DB97ED40FF27D05BCB112BC12E2B0F6D
+:10E1F000F47FF60A8FB7F43BDC80FBA86786E8BBA8
+:10E20000F3C8DEC7616F237D66F187AEFDBF7BFE7D
+:10E2100011996725985BBD35544ABCCFD1E37FE3A4
+:10E2200035619FB4D015D06F579C1739EA27EAFEA5
+:10E230003D54F1A93700BDF51FF86BC4B5FA0C0ABF
+:10E24000C06EE965BE4766E47BF5866A2AE171C760
+:10E25000D04AF06F7BC9EA869DFA5ECDA9841F5F24
+:10E26000F3CC14FB6BBEB13B1F71573DBA6FCF238C
+:10E2700059986723C8DB9EC976C47AF5693B16DDD9
+:10E280002FF7B76BCF6F20F73E1BED643ECDCC036D
+:10E29000FB35EF991D0CF0D15EFBFAE395B8871AB8
+:10E2A000EDB93DE8BFB2DBA6420F672D9E8C72F838
+:10E2B000E159B3BB17EB0CBA7978A22E4F5AA4568A
+:10E2C000EE2FAB3B1F71D737F1E1BF80DCF55AF77A
+:10E2D000F3CFE23C7BAD843871611FEB8DD75DE8F5
+:10E2E00035CFC72D8FEC7398602F9794EE95CF8222
+:10E2F0007FAF3EEF92AD5BF419E89D43D88FE711F5
+:10E30000E2F225657B52FF85DEBD255ED6DFC5972F
+:10E31000EA8BBD09F61BF317DF6E6B527C14246089
+:10E320005CF219BFC919203BC7DF6683BC78E89946
+:10E33000916729BEFEE27E73D8C23A6AB6D2E694ED
+:10E34000CCB83FF8F2FEBC0EE7F3A93B0A91C73404
+:10E350002F88AC845F5CB0514A2ECF7BDB885FBED8
+:10E36000831B972A25DF2D4F4D85EEC75773F53850
+:10E370007675C0160C28DF1D8FFEA3839CEFCC8E14
+:10E38000D377AF677E29717E6F5B42AD6EDEB72DAE
+:10E3900053C78F733C7F3FE35895B1CFAA8792E76D
+:10E3A000DF529129F6D3668914220EC6F82FAC8865
+:10E3B000E15AA4107835765D3DD213E0C8CB8AE0EF
+:10E3C00088EFA0F2A1966EA8343BAE4F5F4A20A81A
+:10E3D000958C7F0FB98B8C7B605EEF55E87EE5DB1B
+:10E3E0006FF3D8984F4B6A241D7953AB23928E7CE0
+:10E3F00068E4A8463B8DEBCB8AF19F19DFAF494615
+:10E40000B83F64F6D8C6DB8F8F433C6F1D7EB32ABE
+:10E410003EA9D0FDA669204DF623676411ECB6E94C
+:10E42000B9E47538A733C11F470676657B13E28FC1
+:10E43000CF903BAA7C287E13FDFAA37CD8814FA500
+:10E44000CD0AABF622AFB1650A4D293A1DB0B1E550
+:10E45000FBBEB4A7C27E2E5E6D153F1E5122827395
+:10E46000B927AE0A3E8C982382738ECAFF11FC181E
+:10E4700099105909DCCAADB4AF96F1C991952E1E19
+:10E48000FFB2C2A0A791E40385273257034FEAB534
+:10E49000D1B711376997D9093F89E97B9DA127A297
+:10E4A000C7863B78FC0F41B30BF1614EA562E40BCC
+:10E4B00096F8F9B5B83F8D90EBC041F86793DDDD74
+:10E4C0002BA3C1FDAF201FBC33DBDDE5BA5E6F328D
+:10E4D00087E5CACAFC6A2DEE293BDDFB8F15CCDF30
+:10E4E0005F1CC907CEB1B54B1C6A7BDDBA13FB4775
+:10E4F000CDA37B805F171CDE272B589FAD96A1AD67
+:10E50000A52CD267E6C829A4F84B606F8223BABD58
+:10E510008D14EFB2089F1E562AEB6797710F944B2C
+:10E52000B403F6A1E8F7FCE6C0ABEF006F468666E1
+:10E53000094E8FF5A70B034FA603373EE0F81E9850
+:10E5400013EFFF60F55E0BFA97BFB8C312E1F69EBA
+:10E55000CDC9E7BB7CEDF60CF80B3D9ED00F7BECF4
+:10E5600049A6C7EA0576194EF28380E8FD9CC729C3
+:10E57000F2B7540EB5410FDFD2CB98D612E8136331
+:10E58000E831F3A941CF1FCE7948F8B64E0B0F43BF
+:10E590006F2307CC047CEFE4B826747F5A10EF1A7F
+:10E5A000F500C7AD2C3D6E215EB4A40FADC4BD8C8B
+:10E5B000F45B9D98BFE9C8A7F9383FDB633ECEDB2B
+:10E5C00072E47036C1CE8DF704C7C76C8CB7F41FE8
+:10E5D000C9C6BB24D6DFAA860A211747B812E0476E
+:10E5E000ACDFAF850B217F8B325482F128E496F9A2
+:10E5F0004C6BA049CED1AAE87E4F4734C1F9B1F7A0
+:10E60000F651856EAF8C0F25C807371DBD5412B16A
+:10E61000C7F1A0D9C09513E82FD6FDDFB9C8C0094E
+:10E620005EDA0CBF1F0727BC31DCA3F516C87DAE30
+:10E6300042973BB65EF8CA3B2320E36DAF5D2A9953
+:10E64000598C75C63C4AC0A359717C010EE40A0E70
+:10E650006C3267F3B97CCF2BEE4E5ED2DCB8B1964C
+:10E66000A7D33AD3FDB5D06B1305E45D3756AEB1F1
+:10E6700076F470857EBF3E557F8FFBF628C14E969F
+:10E68000EB22637DEE7CC19B30F0675DF5C65AF8E6
+:10E69000DF7D597E4BE2BBF987F8AFED49A6D7ADD8
+:10E6A000DF589B338E9FFB1EDA7E6A125DCFAFD997
+:10E6B000BBA336DB757D7F4CEE8BB6989C95E64907
+:10E6C00089FA58BEB17612B7EB52FEAFFAD0CF7DC1
+:10E6D000F188358CB8CBFAB5E0FCB7FD71BD2509E2
+:10E6E000B77F805F33056B9D33BE5BFEB16DAB12B0
+:10E6F0001E56804FEC5FBDE267EC3709FB6DAA1830
+:10E7000053A7685A3D1D793779574F4FAC538C6DDD
+:10E710001928A7A8B788BD49CB7EB8D23D8E3E62E6
+:10E72000F36FAED4649F4D861D4FA96F79E6151E19
+:10E730007FB9CC5356C97E55AEA992BF8FDDA7A62F
+:10E7400052CF0F86B21DBF803D4507CD4EF849B967
+:10E75000A6EB334FBDFC2EFC312FDBE1EA647E35A6
+:10E760005569FABC633627EA40D1635FE57BE0FF79
+:10E770005BECCBA5CE62B2D3641E3F953B57F03D18
+:10E78000B6CFC7C63E69A57ABED35E64FEFE3A53D5
+:10E79000B1E3DB3A93E41BC569C1D91287BF90F896
+:10E7A000161D5CE8D45CC0F7A01DFED6FEF57F67A1
+:10E7B000230E8F0CFE67BA0BB875EDD374D8CFB6A5
+:10E7C000818FD3810F27066639D09E1D7239D01FE5
+:10E7D000ADFBB816F3BA8C365E67308B9CB136F65B
+:10E7E0007E8ED51312DED1CDD06BAF73DB2F4B6194
+:10E7F000EFA9DD8263FC8ECE44FC88D7195C39E337
+:10E80000D56512EB0C05B3F53A035AD4190ACC7A44
+:10E810009D0134EA0C685167403FEA0CA051670043
+:10E820008D3A0368D419D0A2CE80FE2BA86BB1BC60
+:10E83000514EDE50DFAAD1EC82FF0FF46A41E4F5BD
+:10E840000F1CD3747A8712C47D7FC6FB230E46AF9C
+:10E85000E875B028C75379E71F34CBFB201ADA5E7E
+:10E860003713F7D6AFB97155171137D914DBCDA3CC
+:10E8700027511F6AEF53DC1B5DE85F2E726C1B5C37
+:10E88000F87E23FA7BCD6ED585FBBA9A8DFA976F09
+:10E89000B057EA58D539C72C72CFFB15CAE1FDEF46
+:10E8A000B0EAEF64BFC6BD2CF7B045953CDA6F1DEA
+:10E8B00092F74BCB8B8A734D421EDA7ECBE78213E5
+:10E8C0009DB6F49D90D71FB239D724C5578FE47DEC
+:10E8D0007EFC74C18D3C43454CAFD5A790DF5E7B79
+:10E8E000013821F948427EB4D6D9FC33E467A45DEF
+:10E8F00033E1FC7E7EE84E64F9D63D6DFE2892B091
+:10E900007F733099F60DF66DCD23C899DC8F4A03DD
+:10E91000E2B23F94DC1FAA74647D92C63FE6D13C0C
+:10E92000E45B75FFB4E6403FEF77B9DB2AF9CA61D3
+:10E930008FF77025FBF149B347EA2F278FD9E4BD44
+:10E94000757EFB9CA4FA4B8D3655EA1F1BCC8AC4FE
+:10E95000F12BE5DE63B0CBAABA7BA5EE5295EB10A6
+:10E960007F8ED9E1D1F28637C077C35C97D4BF6A76
+:10E97000ACF40BE1C77E2FF73C68167FABE95482FD
+:10E980002AD3ABC96D817FAD62758A3D99ED8F2920
+:10E99000EC0FAB78AFC604BBDAB05D91BC420A1095
+:10E9A000ACE795863E570DFEEB570AFBCBBD563DB7
+:10E9B0000FCE5355E19FD7C5718BE7DF475E0BFC48
+:10E9C000661DC755B41C675F8F70BF376D6ABE9EEA
+:10E9D000E7BB72C07FF51933014F6A727E5EE8951E
+:10E9E000785FEDFC84EF5B09DFA57D73D3F7E1A8C9
+:10E9F000893E49C86B4F9A75FC617DCA7BEB14EC6C
+:10EA000055EA3E5E69CF743449BBA28CC4FF0B3417
+:10EA10003D6F2FE0BB72664ADDA20FEB6BDAED6E45
+:10EA2000E83F860BBB8DFCBE40E596E7ED4ED55B1F
+:10EA30000BD329DC3F8D5BCA147E61E77CD4715C0B
+:10EA4000C23F4F3DBBC0057D7C6977431F3539C749
+:10EA5000E6E1DD31CBE0FF7259C355DC97279D021B
+:10EA6000D89F8F43DDACDF5A1C48415D3DE4D15057
+:10EA7000273FA638F1AEBF1E4FB76F71C2CF0A1441
+:10EA800027EAB7B5A9DD35D9CCBF76E60C37F09CBF
+:10EA9000F155EA6123DCEA76706B5053F4B5A66C4D
+:10EAA000D4F30DFF29F7A6544D8AF7D71B7E141D0A
+:10EAB000FC221DF1F547D46D77837F806CEE5E8379
+:10EAC0003FECA0FEA66952BF8DD9D1E5FD393B616F
+:10EAD0004753ABF4758D8DEF99914F0CDDE6CDC1A9
+:10EAE000FE2BD77CBE255BCE397EBD8C713703B83B
+:10EAF0003BB65E16C3F13D46FD1D786B32EABA2681
+:10EB0000A3AE6B32EABA26A3AE6B32EABA26A3AE44
+:10EB10006B32EABA26A3AE6B32EABA26A913AE97D5
+:10EB2000F6DD8E87A41DEA08C87842BCB8B9EAC7EA
+:10EB3000D55D17558D5377A5145786C45DF67BBDFB
+:10EB4000DE3DA6CECAFEAE26F87BD5E0847B1E4312
+:10EB50005ED26371B338546BF1163C60177CF0548D
+:10EB60008D5B6F8DE9CF2EF5D9CB649B8F7BA82C65
+:10EB70009A655251C734EE2356EF84DFE09CF01BB8
+:10EB8000B4F01BD3ECB8DFFCD6C2AE5DAAE7090136
+:10EB9000C9136C72BF5B3732AE307D2F399370E58D
+:10EBA000B331B8C20F9A159063EDA095BA743F23A4
+:10EBB000F84F25377F9C3F0ECE84749C99961ADAC5
+:10EBC000877DA6B5A5BA9117B3BF8B9D9DDCA6889E
+:10EBD000BFAFA106D9771CBC49479E7CEFC4D17357
+:10EBE000BFE1F9F7FE835DF29DAD93D72EFAFFE00A
+:10EBF0004D4D95AE8F5F77847DE75996EA54B643C5
+:10EC00008E57D5162A92BAB89A2AFE50A33DAE580E
+:10EC100080A377D33CDC77B5B5E139C899C3FE2E24
+:10EC2000EFDF2CA3BE6B1A6ADECBF4D9EC3C37BE07
+:10EC3000AB4DCD3D44050B804775C5B0ABB3D4ADEE
+:10EC400060DD6319DEBF83BFDC5ECCA756E3FE96B2
+:10EC50005397B6B34BEE63CE42DCFB32ABAB1FF542
+:10EC6000862D6F9E907AC2B20CD742D41BB6BC7967
+:10EC70005AA7735CFD8A1BE5B213ABAB7F82F866C3
+:10EC8000EB3E9F1067FDA1094974FBC0E4EEF30958
+:10EC900071AE053FF89D4E3F534CB8AF5643945C60
+:10ECA000D5BB1DF2F9EBFE4B7FCFD3A8C4C9A7AAF1
+:10ECB000745C9C7482C2B0E7D1C50EF9FE973371C3
+:10ECC000FD3CD4DBA8D8B510F338AFFD35ECF8E245
+:10ECD000AD9EA7C127CF38770EF1793558C7900D73
+:10ECE000ED19E3BBE429D5DB88B6363D60927E356D
+:10ECF000588AF66D35F420FAD92F76814FED93F3CB
+:10ED00006E2C623ACF1A9AB7DE8E78E9D98DFE73EF
+:10ED1000659E5EEC37B6EEDF699C8FE5D98779C3D7
+:10ED200085AAE4F9C337EA6DCC2EC2553A0E1D37D9
+:10ED3000FCA8AC93E4FBE758FB395EA51A78F9FD13
+:10ED400072B3BC47204F4C7EEA5E5D0A7958DEA361
+:10ED500086BCAF619CEC99528FF96E7B0DC87EC763
+:10ED60000D3B657C6C39AFE3A3B485A6E004E40DEC
+:10ED7000531E0D4E80BC53768CDA5CDCBE1018B589
+:10ED8000217F78E16F476DE87FC14375E3E1BF56AE
+:10ED9000AD09DFC2B251593F9DF71A9277C2E8041C
+:10EDA000E46F854D6F59026CB7739EE67D93F2B7A1
+:10EDB000228963D30D5B9AFEA84AB087E9CF90E41D
+:10EDC000AB549D25E3BE14DDFF7D8F3EA8C28E6E41
+:10EDD00008B2DC09F637E769D3E54812DFB0AC6B5F
+:10EDE000317083F3B5A4713F3347BE3CC5C023E403
+:10EDF0008F8D8C37FEA6B7BE42BEC879DC187E8CDC
+:10EE00004D311C26C45DEFEB1117FC2079DEDABB17
+:10EE10001ED98AF76D53E3768BBC8FD7F46D45DB33
+:10EE2000DAFA9E258724BF4C9ACFF965127D9D9C06
+:10EE300063E4687BF0F3AD39E3ECCB76702DD10E53
+:10EE40004E9A4337E0BD7AD29FEA0E481C09DD0F87
+:10EE50007CD9D96A7723AEECFA55A5D8D7B7F5A9EE
+:10EE6000328FA9FA47D951A7CC0F545211FCE6872B
+:10EE7000DA11E0E1EC243C0C48DD72894370AEDD30
+:10EE80007807B6AD714A3E12F3EB3653E8C3AD983E
+:10EE900097E590EF110CB745A62C7C6F9AE2EE4AED
+:10EEA000C82BCE2E9915049DDD190A83EFE8CF15E6
+:10EEB00037EAC8D5693AAED6A80DAD7B79FC2D35B9
+:10EEC0002CB8F15BE007F36FB7AC977645D94CB13E
+:10EED000DB5C0A29FAFF67702DC47B3DF63DAD6708
+:10EEE0005BB0EF20DEFB4AF099B5A88FFE955DE49C
+:10EEF0008906D58099CFD3338104B77BEE2C94B8A3
+:10EF000013A586C6FB91FF2C4F953A6ACF04D71301
+:10EF1000F86EDAD37CA3E4F587FEA4C7FBD1A5295C
+:10EF20006EE4713DF35C1B71AE9E475D32FE9AA2AA
+:10EF3000F30B3CA1EBA767A97ECE9EE64C799FC55B
+:10EF4000EEA167876732BEBF5932BCE5D5A803186A
+:10EF5000DF1F7B66703FB74F290D77DE073E737565
+:10EF6000795794B9E4DE4EDE79E3137B747D86F144
+:10EF70001DAC7D8923E9FDFEBFFE80CBB3202200BE
+:10EF80000000000000000000040835000000000040
+:00000001FF
diff --git a/firmware/cis/3CCFEM556.cis.ihex b/firmware/cis/3CCFEM556.cis.ihex
new file mode 100644
index 000000000000..e4d92b173e17
--- /dev/null
+++ b/firmware/cis/3CCFEM556.cis.ihex
@@ -0,0 +1,13 @@
+:1000000001030000FF152D050033436F6D004D65A2
+:100010006761686572747A2033434346454D3535D0
+:1000200036004C414E202B2035366B204D6F6465D9
+:100030006D0000FF20040101560521020000060B9F
+:1000400002004D000000006B000000FF001303439E
+:100050004953210206001A060507001067021B0912
+:1000600087011901556430FFFFFF00130343495313
+:10007000210202001A060527001177021B09A701B9
+:090080001901552330FFFFFF00B8
+:00000001FF
+#
+# This card is MFC-compliant, but identifies itself as single function
+#
diff --git a/firmware/cis/3CXEM556.cis.ihex b/firmware/cis/3CXEM556.cis.ihex
new file mode 100644
index 000000000000..895010b230ff
--- /dev/null
+++ b/firmware/cis/3CXEM556.cis.ihex
@@ -0,0 +1,13 @@
+:1000000001030000FF152C050033436F6D004D65A3
+:100010006761686572747A20334358454D353536CB
+:10002000004C414E202B2035366B204D6F64656DA2
+:100030000000FF20040101350021020000060B0230
+:10004000004C0000000069000000FF00130343495A
+:1000500053210206001A0501070008631B098701E6
+:100060001901556430FFFFFF001303434953210278
+:1000700002001A0501270009631B09A70119015590
+:060080002330FFFFFF002A
+:00000001FF
+#
+# This card is MFC-compliant, but identifies itself as single function
+#
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 5f8ab8adb5f5..ab5547ff29a1 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -37,6 +37,7 @@
#include <linux/mount.h>
#include <linux/idr.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
@@ -155,6 +156,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
root = d_alloc_root(inode);
if (!root) {
+ iput(inode);
retval = -ENOMEM;
goto release_sb;
}
@@ -173,10 +175,7 @@ P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
return 0;
release_sb:
- if (sb) {
- up_write(&sb->s_umount);
- deactivate_super(sb);
- }
+ deactivate_locked_super(sb);
free_stat:
kfree(st);
@@ -230,9 +229,12 @@ static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt)
static void
v9fs_umount_begin(struct super_block *sb)
{
- struct v9fs_session_info *v9ses = sb->s_fs_info;
+ struct v9fs_session_info *v9ses;
+ lock_kernel();
+ v9ses = sb->s_fs_info;
v9fs_session_cancel(v9ses);
+ unlock_kernel();
}
static const struct super_operations v9fs_super_ops = {
diff --git a/fs/Kconfig b/fs/Kconfig
index 9f7270f36b2a..525da2e8f73b 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -62,6 +62,16 @@ source "fs/autofs/Kconfig"
source "fs/autofs4/Kconfig"
source "fs/fuse/Kconfig"
+config CUSE
+ tristate "Character device in Userpace support"
+ depends on FUSE_FS
+ help
+ This FUSE extension allows character devices to be
+ implemented in userspace.
+
+ If you want to develop or use userspace character device
+ based on CUSE, answer Y or M.
+
config GENERIC_ACL
bool
select FS_POSIX_ACL
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index dd9becca4241..0ec5aaf47aa7 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -132,11 +132,15 @@ static void adfs_put_super(struct super_block *sb)
int i;
struct adfs_sb_info *asb = ADFS_SB(sb);
+ lock_kernel();
+
for (i = 0; i < asb->s_map_size; i++)
brelse(asb->s_map[i].dm_bh);
kfree(asb->s_map);
kfree(asb);
sb->s_fs_info = NULL;
+
+ unlock_kernel();
}
static int adfs_show_options(struct seq_file *seq, struct vfsmount *mnt)
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 5ce695e707fe..280d361af41f 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -29,6 +29,8 @@ affs_put_super(struct super_block *sb)
struct affs_sb_info *sbi = AFFS_SB(sb);
pr_debug("AFFS: put_super()\n");
+ lock_kernel();
+
if (!(sb->s_flags & MS_RDONLY)) {
AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(1);
secs_to_datestamp(get_seconds(),
@@ -42,7 +44,8 @@ affs_put_super(struct super_block *sb)
affs_brelse(sbi->s_root_bh);
kfree(sbi);
sb->s_fs_info = NULL;
- return;
+
+ unlock_kernel();
}
static void
@@ -51,6 +54,7 @@ affs_write_super(struct super_block *sb)
int clean = 2;
struct affs_sb_info *sbi = AFFS_SB(sb);
+ lock_super(sb);
if (!(sb->s_flags & MS_RDONLY)) {
// if (sbi->s_bitmap[i].bm_bh) {
// if (buffer_dirty(sbi->s_bitmap[i].bm_bh)) {
@@ -63,6 +67,7 @@ affs_write_super(struct super_block *sb)
sb->s_dirt = !clean; /* redo until bitmap synced */
} else
sb->s_dirt = 0;
+ unlock_super(sb);
pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean);
}
@@ -507,8 +512,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
kfree(new_opts);
return -EINVAL;
}
- kfree(sb->s_options);
- sb->s_options = new_opts;
+ replace_mount_options(sb, new_opts);
sbi->s_flags = mount_flags;
sbi->s_mode = mode;
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index 2b9e2d03a390..c52be53f6946 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -244,7 +244,7 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
case -EBUSY:
/* someone else made a mount here whilst we were busy */
while (d_mountpoint(nd->path.dentry) &&
- follow_down(&nd->path.mnt, &nd->path.dentry))
+ follow_down(&nd->path))
;
err = 0;
default:
diff --git a/fs/afs/super.c b/fs/afs/super.c
index aee239a048cb..ad0514d0115f 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -405,21 +405,20 @@ static int afs_get_sb(struct file_system_type *fs_type,
sb->s_flags = flags;
ret = afs_fill_super(sb, &params);
if (ret < 0) {
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ deactivate_locked_super(sb);
goto error;
}
- sb->s_options = new_opts;
+ save_mount_options(sb, new_opts);
sb->s_flags |= MS_ACTIVE;
} else {
_debug("reuse");
- kfree(new_opts);
ASSERTCMP(sb->s_flags, &, MS_ACTIVE);
}
simple_set_mnt(mnt, sb);
afs_put_volume(params.volume);
afs_put_cell(params.cell);
+ kfree(new_opts);
_leave(" = 0 [%p]", sb);
return 0;
@@ -441,8 +440,12 @@ static void afs_put_super(struct super_block *sb)
_enter("");
+ lock_kernel();
+
afs_put_volume(as->volume);
+ unlock_kernel();
+
_leave("");
}
diff --git a/fs/autofs/dirhash.c b/fs/autofs/dirhash.c
index 4eb4d8dfb2f1..2316e944a109 100644
--- a/fs/autofs/dirhash.c
+++ b/fs/autofs/dirhash.c
@@ -85,13 +85,12 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
}
path.mnt = mnt;
path_get(&path);
- if (!follow_down(&path.mnt, &path.dentry)) {
+ if (!follow_down(&path)) {
path_put(&path);
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
continue;
}
- while (d_mountpoint(path.dentry) &&
- follow_down(&path.mnt, &path.dentry))
+ while (d_mountpoint(path.dentry) && follow_down(&path));
;
umount_ok = may_umount(path.mnt);
path_put(&path);
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index b7ff33c63101..8f7cdde41733 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -223,12 +223,12 @@ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify);
int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
void autofs4_catatonic_mode(struct autofs_sb_info *);
-static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+static inline int autofs4_follow_mount(struct path *path)
{
int res = 0;
- while (d_mountpoint(*dentry)) {
- int followed = follow_down(mnt, dentry);
+ while (d_mountpoint(path->dentry)) {
+ int followed = follow_down(path);
if (!followed)
break;
res = 1;
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 84168c0dcc2d..f3da2eb51f56 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -192,77 +192,42 @@ static int autofs_dev_ioctl_protosubver(struct file *fp,
return 0;
}
-/*
- * Walk down the mount stack looking for an autofs mount that
- * has the requested device number (aka. new_encode_dev(sb->s_dev).
- */
-static int autofs_dev_ioctl_find_super(struct nameidata *nd, dev_t devno)
+static int find_autofs_mount(const char *pathname,
+ struct path *res,
+ int test(struct path *path, void *data),
+ void *data)
{
- struct dentry *dentry;
- struct inode *inode;
- struct super_block *sb;
- dev_t s_dev;
- unsigned int err;
-
+ struct path path;
+ int err = kern_path(pathname, 0, &path);
+ if (err)
+ return err;
err = -ENOENT;
-
- /* Lookup the dentry name at the base of our mount point */
- dentry = d_lookup(nd->path.dentry, &nd->last);
- if (!dentry)
- goto out;
-
- dput(nd->path.dentry);
- nd->path.dentry = dentry;
-
- /* And follow the mount stack looking for our autofs mount */
- while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
- inode = nd->path.dentry->d_inode;
- if (!inode)
- break;
-
- sb = inode->i_sb;
- s_dev = new_encode_dev(sb->s_dev);
- if (devno == s_dev) {
- if (sb->s_magic == AUTOFS_SUPER_MAGIC) {
+ while (path.dentry == path.mnt->mnt_root) {
+ if (path.mnt->mnt_sb->s_magic == AUTOFS_SUPER_MAGIC) {
+ if (test(&path, data)) {
+ path_get(&path);
+ if (!err) /* already found some */
+ path_put(res);
+ *res = path;
err = 0;
- break;
}
}
+ if (!follow_up(&path))
+ break;
}
-out:
+ path_put(&path);
return err;
}
-/*
- * Walk down the mount stack looking for an autofs mount that
- * has the requested mount type (ie. indirect, direct or offset).
- */
-static int autofs_dev_ioctl_find_sbi_type(struct nameidata *nd, unsigned int type)
+static int test_by_dev(struct path *path, void *p)
{
- struct dentry *dentry;
- struct autofs_info *ino;
- unsigned int err;
-
- err = -ENOENT;
-
- /* Lookup the dentry name at the base of our mount point */
- dentry = d_lookup(nd->path.dentry, &nd->last);
- if (!dentry)
- goto out;
-
- dput(nd->path.dentry);
- nd->path.dentry = dentry;
+ return path->mnt->mnt_sb->s_dev == *(dev_t *)p;
+}
- /* And follow the mount stack looking for our autofs mount */
- while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
- ino = autofs4_dentry_ino(nd->path.dentry);
- if (ino && ino->sbi->type & type) {
- err = 0;
- break;
- }
- }
-out:
- return err;
+static int test_by_type(struct path *path, void *p)
+{
+ struct autofs_info *ino = autofs4_dentry_ino(path->dentry);
+ return ino && ino->sbi->type & *(unsigned *)p;
}
static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file)
@@ -283,31 +248,25 @@ static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file)
* Open a file descriptor on the autofs mount point corresponding
* to the given path and device number (aka. new_encode_dev(sb->s_dev)).
*/
-static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
+static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid)
{
- struct file *filp;
- struct nameidata nd;
int err, fd;
fd = get_unused_fd();
if (likely(fd >= 0)) {
- /* Get nameidata of the parent directory */
- err = path_lookup(path, LOOKUP_PARENT, &nd);
+ struct file *filp;
+ struct path path;
+
+ err = find_autofs_mount(name, &path, test_by_dev, &devid);
if (err)
goto out;
/*
- * Search down, within the parent, looking for an
- * autofs super block that has the device number
+ * Find autofs super block that has the device number
* corresponding to the autofs fs we want to open.
*/
- err = autofs_dev_ioctl_find_super(&nd, devid);
- if (err) {
- path_put(&nd.path);
- goto out;
- }
- filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
+ filp = dentry_open(path.dentry, path.mnt, O_RDONLY,
current_cred());
if (IS_ERR(filp)) {
err = PTR_ERR(filp);
@@ -340,7 +299,7 @@ static int autofs_dev_ioctl_openmount(struct file *fp,
param->ioctlfd = -1;
path = param->path;
- devid = param->openmount.devid;
+ devid = new_decode_dev(param->openmount.devid);
err = 0;
fd = autofs_dev_ioctl_open_mountpoint(path, devid);
@@ -475,8 +434,7 @@ static int autofs_dev_ioctl_requester(struct file *fp,
struct autofs_dev_ioctl *param)
{
struct autofs_info *ino;
- struct nameidata nd;
- const char *path;
+ struct path path;
dev_t devid;
int err = -ENOENT;
@@ -485,32 +443,24 @@ static int autofs_dev_ioctl_requester(struct file *fp,
goto out;
}
- path = param->path;
- devid = new_encode_dev(sbi->sb->s_dev);
+ devid = sbi->sb->s_dev;
param->requester.uid = param->requester.gid = -1;
- /* Get nameidata of the parent directory */
- err = path_lookup(path, LOOKUP_PARENT, &nd);
+ err = find_autofs_mount(param->path, &path, test_by_dev, &devid);
if (err)
goto out;
- err = autofs_dev_ioctl_find_super(&nd, devid);
- if (err)
- goto out_release;
-
- ino = autofs4_dentry_ino(nd.path.dentry);
+ ino = autofs4_dentry_ino(path.dentry);
if (ino) {
err = 0;
- autofs4_expire_wait(nd.path.dentry);
+ autofs4_expire_wait(path.dentry);
spin_lock(&sbi->fs_lock);
param->requester.uid = ino->uid;
param->requester.gid = ino->gid;
spin_unlock(&sbi->fs_lock);
}
-
-out_release:
- path_put(&nd.path);
+ path_put(&path);
out:
return err;
}
@@ -569,8 +519,8 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
struct autofs_sb_info *sbi,
struct autofs_dev_ioctl *param)
{
- struct nameidata nd;
- const char *path;
+ struct path path;
+ const char *name;
unsigned int type;
unsigned int devid, magic;
int err = -ENOENT;
@@ -580,71 +530,46 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
goto out;
}
- path = param->path;
+ name = param->path;
type = param->ismountpoint.in.type;
param->ismountpoint.out.devid = devid = 0;
param->ismountpoint.out.magic = magic = 0;
if (!fp || param->ioctlfd == -1) {
- if (autofs_type_any(type)) {
- struct super_block *sb;
-
- err = path_lookup(path, LOOKUP_FOLLOW, &nd);
- if (err)
- goto out;
-
- sb = nd.path.dentry->d_sb;
- devid = new_encode_dev(sb->s_dev);
- } else {
- struct autofs_info *ino;
-
- err = path_lookup(path, LOOKUP_PARENT, &nd);
- if (err)
- goto out;
-
- err = autofs_dev_ioctl_find_sbi_type(&nd, type);
- if (err)
- goto out_release;
-
- ino = autofs4_dentry_ino(nd.path.dentry);
- devid = autofs4_get_dev(ino->sbi);
- }
-
+ if (autofs_type_any(type))
+ err = kern_path(name, LOOKUP_FOLLOW, &path);
+ else
+ err = find_autofs_mount(name, &path, test_by_type, &type);
+ if (err)
+ goto out;
+ devid = new_encode_dev(path.mnt->mnt_sb->s_dev);
err = 0;
- if (nd.path.dentry->d_inode &&
- nd.path.mnt->mnt_root == nd.path.dentry) {
+ if (path.dentry->d_inode &&
+ path.mnt->mnt_root == path.dentry) {
err = 1;
- magic = nd.path.dentry->d_inode->i_sb->s_magic;
+ magic = path.dentry->d_inode->i_sb->s_magic;
}
} else {
- dev_t dev = autofs4_get_dev(sbi);
+ dev_t dev = sbi->sb->s_dev;
- err = path_lookup(path, LOOKUP_PARENT, &nd);
+ err = find_autofs_mount(name, &path, test_by_dev, &dev);
if (err)
goto out;
- err = autofs_dev_ioctl_find_super(&nd, dev);
- if (err)
- goto out_release;
-
- devid = dev;
+ devid = new_encode_dev(dev);
- err = have_submounts(nd.path.dentry);
+ err = have_submounts(path.dentry);
- if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) {
- if (follow_down(&nd.path.mnt, &nd.path.dentry)) {
- struct inode *inode = nd.path.dentry->d_inode;
- magic = inode->i_sb->s_magic;
- }
+ if (path.mnt->mnt_mountpoint != path.mnt->mnt_root) {
+ if (follow_down(&path))
+ magic = path.mnt->mnt_sb->s_magic;
}
}
param->ismountpoint.out.devid = devid;
param->ismountpoint.out.magic = magic;
-
-out_release:
- path_put(&nd.path);
+ path_put(&path);
out:
return err;
}
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 3077d8f16523..aa39ae83f019 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -48,19 +48,19 @@ static inline int autofs4_can_expire(struct dentry *dentry,
static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
{
struct dentry *top = dentry;
+ struct path path = {.mnt = mnt, .dentry = dentry};
int status = 1;
DPRINTK("dentry %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
- mntget(mnt);
- dget(dentry);
+ path_get(&path);
- if (!follow_down(&mnt, &dentry))
+ if (!follow_down(&path))
goto done;
- if (is_autofs4_dentry(dentry)) {
- struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
+ if (is_autofs4_dentry(path.dentry)) {
+ struct autofs_sb_info *sbi = autofs4_sbi(path.dentry->d_sb);
/* This is an autofs submount, we can't expire it */
if (autofs_type_indirect(sbi->type))
@@ -70,7 +70,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
* Otherwise it's an offset mount and we need to check
* if we can umount its mount, if there is one.
*/
- if (!d_mountpoint(dentry)) {
+ if (!d_mountpoint(path.dentry)) {
status = 0;
goto done;
}
@@ -86,8 +86,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
status = 0;
done:
DPRINTK("returning = %d", status);
- dput(dentry);
- mntput(mnt);
+ path_put(&path);
return status;
}
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index e383bf0334f1..b96a3c57359d 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -181,7 +181,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
nd->flags);
/*
* For an expire of a covered direct or offset mount we need
- * to beeak out of follow_down() at the autofs mount trigger
+ * to break out of follow_down() at the autofs mount trigger
* (d_mounted--), so we can see the expiring flag, and manage
* the blocking and following here until the expire is completed.
*/
@@ -190,7 +190,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
if (ino->flags & AUTOFS_INF_EXPIRING) {
spin_unlock(&sbi->fs_lock);
/* Follow down to our covering mount. */
- if (!follow_down(&nd->path.mnt, &nd->path.dentry))
+ if (!follow_down(&nd->path))
goto done;
goto follow;
}
@@ -230,8 +230,7 @@ follow:
* to follow it.
*/
if (d_mountpoint(dentry)) {
- if (!autofs4_follow_mount(&nd->path.mnt,
- &nd->path.dentry)) {
+ if (!autofs4_follow_mount(&nd->path)) {
status = -ENOENT;
goto out_error;
}
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 76afd0d6b86c..9367b6297d84 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -737,6 +737,8 @@ parse_options(char *options, befs_mount_options * opts)
static void
befs_put_super(struct super_block *sb)
{
+ lock_kernel();
+
kfree(BEFS_SB(sb)->mount_opts.iocharset);
BEFS_SB(sb)->mount_opts.iocharset = NULL;
@@ -747,7 +749,8 @@ befs_put_super(struct super_block *sb)
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
- return;
+
+ unlock_kernel();
}
/* Allocate private field of the superblock, fill it.
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index cc4062d12ca2..3a9a1361fdc1 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -30,6 +30,7 @@ MODULE_LICENSE("GPL");
#define dprintf(x...)
#endif
+static void bfs_write_super(struct super_block *s);
void dump_imap(const char *prefix, struct super_block *s);
struct inode *bfs_iget(struct super_block *sb, unsigned long ino)
@@ -216,11 +217,18 @@ static void bfs_put_super(struct super_block *s)
if (!info)
return;
+ lock_kernel();
+
+ if (s->s_dirt)
+ bfs_write_super(s);
+
brelse(info->si_sbh);
mutex_destroy(&info->bfs_lock);
kfree(info->si_imap);
kfree(info);
s->s_fs_info = NULL;
+
+ unlock_kernel();
}
static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index f45dbc18dd17..feddc50b406f 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -175,17 +175,22 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
iov, offset, nr_segs, blkdev_get_blocks, NULL);
}
+int __sync_blockdev(struct block_device *bdev, int wait)
+{
+ if (!bdev)
+ return 0;
+ if (!wait)
+ return filemap_flush(bdev->bd_inode->i_mapping);
+ return filemap_write_and_wait(bdev->bd_inode->i_mapping);
+}
+
/*
* Write out and wait upon all the dirty data associated with a block
* device via its mapping. Does not take the superblock lock.
*/
int sync_blockdev(struct block_device *bdev)
{
- int ret = 0;
-
- if (bdev)
- ret = filemap_write_and_wait(bdev->bd_inode->i_mapping);
- return ret;
+ return __sync_blockdev(bdev, 1);
}
EXPORT_SYMBOL(sync_blockdev);
@@ -198,7 +203,7 @@ int fsync_bdev(struct block_device *bdev)
{
struct super_block *sb = get_super(bdev);
if (sb) {
- int res = fsync_super(sb);
+ int res = sync_filesystem(sb);
drop_super(sb);
return res;
}
@@ -240,7 +245,7 @@ struct super_block *freeze_bdev(struct block_device *bdev)
sb->s_frozen = SB_FREEZE_WRITE;
smp_wmb();
- __fsync_super(sb);
+ sync_filesystem(sb);
sb->s_frozen = SB_FREEZE_TRANS;
smp_wmb();
@@ -331,6 +336,12 @@ static int blkdev_readpage(struct file * file, struct page * page)
return block_read_full_page(page, blkdev_get_block);
}
+static int blkdev_readpages(struct file *file, struct address_space *mapping,
+ struct list_head *pages, unsigned nr_pages)
+{
+ return mpage_readpages(mapping, pages, nr_pages, blkdev_get_block);
+}
+
static int blkdev_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
@@ -1399,6 +1410,7 @@ static int blkdev_releasepage(struct page *page, gfp_t wait)
static const struct address_space_operations def_blk_aops = {
.readpage = blkdev_readpage,
+ .readpages = blkdev_readpages,
.writepage = blkdev_writepage,
.sync_page = block_sync_page,
.write_begin = blkdev_write_begin,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 90c23eb28829..6bd6a8c9fd3b 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2327,7 +2327,6 @@ err:
btrfs_update_inode(trans, root, dir);
btrfs_drop_nlink(inode);
ret = btrfs_update_inode(trans, root, inode);
- dir->i_sb->s_dirt = 1;
out:
return ret;
}
@@ -2811,7 +2810,6 @@ error:
pending_del_nr);
}
btrfs_free_path(path);
- inode->i_sb->s_dirt = 1;
return ret;
}
@@ -3749,7 +3747,6 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
init_special_inode(inode, inode->i_mode, rdev);
btrfs_update_inode(trans, root, inode);
}
- dir->i_sb->s_dirt = 1;
btrfs_update_inode_block_group(trans, inode);
btrfs_update_inode_block_group(trans, dir);
out_unlock:
@@ -3814,7 +3811,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
inode->i_op = &btrfs_file_inode_operations;
BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
}
- dir->i_sb->s_dirt = 1;
btrfs_update_inode_block_group(trans, inode);
btrfs_update_inode_block_group(trans, dir);
out_unlock:
@@ -3861,7 +3857,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
if (err)
drop_inode = 1;
- dir->i_sb->s_dirt = 1;
btrfs_update_inode_block_group(trans, dir);
err = btrfs_update_inode(trans, root, inode);
@@ -3943,7 +3938,6 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
d_instantiate(dentry, inode);
drop_on_err = 0;
- dir->i_sb->s_dirt = 1;
btrfs_update_inode_block_group(trans, inode);
btrfs_update_inode_block_group(trans, dir);
@@ -4972,7 +4966,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
inode->i_op = &btrfs_file_inode_operations;
BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
}
- dir->i_sb->s_dirt = 1;
btrfs_update_inode_block_group(trans, inode);
btrfs_update_inode_block_group(trans, dir);
if (drop_inode)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3536bdb2d7cb..d455dfe1c178 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -60,8 +60,12 @@ static void btrfs_put_super(struct super_block *sb)
struct btrfs_root *root = btrfs_sb(sb);
int ret;
+ lock_kernel();
+
ret = close_ctree(root);
sb->s_fs_info = NULL;
+
+ unlock_kernel();
}
enum {
@@ -388,10 +392,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
struct btrfs_root *root = btrfs_sb(sb);
int ret;
- if (sb->s_flags & MS_RDONLY)
- return 0;
-
- sb->s_dirt = 0;
if (!wait) {
filemap_flush(root->fs_info->btree_inode->i_mapping);
return 0;
@@ -402,7 +402,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
trans = btrfs_start_transaction(root, 1);
ret = btrfs_commit_transaction(trans, root);
- sb->s_dirt = 0;
return ret;
}
@@ -444,11 +443,6 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
return 0;
}
-static void btrfs_write_super(struct super_block *sb)
-{
- sb->s_dirt = 0;
-}
-
static int btrfs_test_super(struct super_block *s, void *data)
{
struct btrfs_fs_devices *test_fs_devices = data;
@@ -502,8 +496,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
if (s->s_root) {
if ((flags ^ s->s_flags) & MS_RDONLY) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
error = -EBUSY;
goto error_close_devices;
}
@@ -517,8 +510,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
error = btrfs_fill_super(s, fs_devices, data,
flags & MS_SILENT ? 1 : 0);
if (error) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
goto error_free_subvol_name;
}
@@ -535,15 +527,13 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
mutex_unlock(&s->s_root->d_inode->i_mutex);
if (IS_ERR(root)) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
error = PTR_ERR(root);
goto error_free_subvol_name;
}
if (!root->d_inode) {
dput(root);
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
error = -ENXIO;
goto error_free_subvol_name;
}
@@ -682,7 +672,6 @@ static int btrfs_unfreeze(struct super_block *sb)
static struct super_operations btrfs_super_ops = {
.delete_inode = btrfs_delete_inode,
.put_super = btrfs_put_super,
- .write_super = btrfs_write_super,
.sync_fs = btrfs_sync_fs,
.show_options = btrfs_show_options,
.write_inode = btrfs_write_inode,
diff --git a/fs/buffer.c b/fs/buffer.c
index aed297739eb0..1864d0b63088 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2736,6 +2736,8 @@ has_buffers:
pos += blocksize;
}
+ map_bh.b_size = blocksize;
+ map_bh.b_state = 0;
err = get_block(inode, iblock, &map_bh, 0);
if (err)
goto unlock;
@@ -2933,6 +2935,8 @@ int submit_bh(int rw, struct buffer_head * bh)
BUG_ON(!buffer_locked(bh));
BUG_ON(!buffer_mapped(bh));
BUG_ON(!bh->b_end_io);
+ BUG_ON(buffer_delay(bh));
+ BUG_ON(buffer_unwritten(bh));
/*
* Mask in barrier bit for a write (could be either a WRITE or a
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 1e962348d111..431accd475a7 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -354,7 +354,9 @@ static void cachefiles_sync_cache(struct fscache_cache *_cache)
/* make sure all pages pinned by operations on behalf of the netfs are
* written to disc */
cachefiles_begin_secure(cache, &saved_cred);
- ret = fsync_super(cache->mnt->mnt_sb);
+ down_read(&cache->mnt->mnt_sb->s_umount);
+ ret = sync_filesystem(cache->mnt->mnt_sb);
+ up_read(&cache->mnt->mnt_sb->s_umount);
cachefiles_end_secure(cache, saved_cred);
if (ret == -EIO)
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 9d1fb6ec8a5a..f20c4069c220 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,16 @@
+Version 1.58
+------------
+Guard against buffer overruns in various UCS-2 to UTF-8 string conversions
+when the UTF-8 string is composed of unusually long (more than 4 byte) converted
+characters. Add support for mounting root of a share which redirects immediately
+to DFS target. Convert string conversion functions from Unicode to more
+accurately mark string length before allocating memory (which may help the
+rare cases where a UTF-8 string is much larger than the UCS2 string that
+we converted from). Fix endianness of the vcnum field used during
+session setup to distinguish multiple mounts to same server from different
+userids. Raw NTLMSSP fixed (it requires /proc/fs/cifs/experimental
+flag to be set to 2, and mount must enable krb5 to turn on extended security).
+
Version 1.57
------------
Improve support for multiple security contexts to the same server. We
diff --git a/fs/cifs/README b/fs/cifs/README
index 07434181623b..db208ddb9899 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -651,7 +651,15 @@ Experimental When set to 1 used to enable certain experimental
signing turned on in case buffer was modified
just before it was sent, also this flag will
be used to use the new experimental directory change
- notification code).
+ notification code). When set to 2 enables
+ an additional experimental feature, "raw ntlmssp"
+ session establishment support (which allows
+ specifying "sec=ntlmssp" on mount). The Linux cifs
+ module will use ntlmv2 authentication encapsulated
+ in "raw ntlmssp" (not using SPNEGO) when
+ "sec=ntlmssp" is specified on mount.
+ This support also requires building cifs with
+ the CONFIG_CIFS_EXPERIMENTAL configuration flag.
These experimental features and tracing can be enabled by changing flags in
/proc/fs/cifs (after the cifs module has been installed or built into the
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 5fdbf8a14472..3bb11be8b6a8 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -275,7 +275,7 @@ static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
case -EBUSY:
/* someone else made a mount here whilst we were busy */
while (d_mountpoint(nd->path.dentry) &&
- follow_down(&nd->path.mnt, &nd->path.dentry))
+ follow_down(&nd->path))
;
err = 0;
default:
@@ -340,28 +340,24 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
for (i = 0; i < num_referrals; i++) {
+ int len;
dump_referral(referrals+i);
- /* connect to a storage node */
- if (referrals[i].flags & DFSREF_STORAGE_SERVER) {
- int len;
- len = strlen(referrals[i].node_name);
- if (len < 2) {
- cERROR(1, ("%s: Net Address path too short: %s",
+ /* connect to a node */
+ len = strlen(referrals[i].node_name);
+ if (len < 2) {
+ cERROR(1, ("%s: Net Address path too short: %s",
__func__, referrals[i].node_name));
- rc = -EINVAL;
- goto out_err;
- }
- mnt = cifs_dfs_do_refmount(nd->path.mnt,
- nd->path.dentry,
- referrals + i);
- cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p",
- __func__,
+ rc = -EINVAL;
+ goto out_err;
+ }
+ mnt = cifs_dfs_do_refmount(nd->path.mnt,
+ nd->path.dentry, referrals + i);
+ cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", __func__,
referrals[i].node_name, mnt));
- /* complete mount procedure if we accured submount */
- if (!IS_ERR(mnt))
- break;
- }
+ /* complete mount procedure if we accured submount */
+ if (!IS_ERR(mnt))
+ break;
}
/* we need it cause for() above could exit without valid submount */
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 7d75272a6b3f..60e3c4253de0 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifs_unicode.c
*
- * Copyright (c) International Business Machines Corp., 2000,2005
+ * Copyright (c) International Business Machines Corp., 2000,2009
* Modified by Steve French (sfrench@us.ibm.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -26,31 +26,157 @@
#include "cifs_debug.h"
/*
- * NAME: cifs_strfromUCS()
- *
- * FUNCTION: Convert little-endian unicode string to character string
+ * cifs_ucs2_bytes - how long will a string be after conversion?
+ * @ucs - pointer to input string
+ * @maxbytes - don't go past this many bytes of input string
+ * @codepage - destination codepage
*
+ * Walk a ucs2le string and return the number of bytes that the string will
+ * be after being converted to the given charset, not including any null
+ * termination required. Don't walk past maxbytes in the source buffer.
*/
int
-cifs_strfromUCS_le(char *to, const __le16 *from,
- int len, const struct nls_table *codepage)
+cifs_ucs2_bytes(const __le16 *from, int maxbytes,
+ const struct nls_table *codepage)
{
int i;
- int outlen = 0;
+ int charlen, outlen = 0;
+ int maxwords = maxbytes / 2;
+ char tmp[NLS_MAX_CHARSET_SIZE];
- for (i = 0; (i < len) && from[i]; i++) {
- int charlen;
- /* 2.4.0 kernel or greater */
- charlen =
- codepage->uni2char(le16_to_cpu(from[i]), &to[outlen],
- NLS_MAX_CHARSET_SIZE);
- if (charlen > 0) {
+ for (i = 0; from[i] && i < maxwords; i++) {
+ charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp,
+ NLS_MAX_CHARSET_SIZE);
+ if (charlen > 0)
outlen += charlen;
- } else {
- to[outlen++] = '?';
+ else
+ outlen++;
+ }
+
+ return outlen;
+}
+
+/*
+ * cifs_mapchar - convert a little-endian char to proper char in codepage
+ * @target - where converted character should be copied
+ * @src_char - 2 byte little-endian source character
+ * @cp - codepage to which character should be converted
+ * @mapchar - should character be mapped according to mapchars mount option?
+ *
+ * This function handles the conversion of a single character. It is the
+ * responsibility of the caller to ensure that the target buffer is large
+ * enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE).
+ */
+static int
+cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp,
+ bool mapchar)
+{
+ int len = 1;
+
+ if (!mapchar)
+ goto cp_convert;
+
+ /*
+ * BB: Cannot handle remapping UNI_SLASH until all the calls to
+ * build_path_from_dentry are modified, as they use slash as
+ * separator.
+ */
+ switch (le16_to_cpu(src_char)) {
+ case UNI_COLON:
+ *target = ':';
+ break;
+ case UNI_ASTERIK:
+ *target = '*';
+ break;
+ case UNI_QUESTION:
+ *target = '?';
+ break;
+ case UNI_PIPE:
+ *target = '|';
+ break;
+ case UNI_GRTRTHAN:
+ *target = '>';
+ break;
+ case UNI_LESSTHAN:
+ *target = '<';
+ break;
+ default:
+ goto cp_convert;
+ }
+
+out:
+ return len;
+
+cp_convert:
+ len = cp->uni2char(le16_to_cpu(src_char), target,
+ NLS_MAX_CHARSET_SIZE);
+ if (len <= 0) {
+ *target = '?';
+ len = 1;
+ }
+ goto out;
+}
+
+/*
+ * cifs_from_ucs2 - convert utf16le string to local charset
+ * @to - destination buffer
+ * @from - source buffer
+ * @tolen - destination buffer size (in bytes)
+ * @fromlen - source buffer size (in bytes)
+ * @codepage - codepage to which characters should be converted
+ * @mapchar - should characters be remapped according to the mapchars option?
+ *
+ * Convert a little-endian ucs2le string (as sent by the server) to a string
+ * in the provided codepage. The tolen and fromlen parameters are to ensure
+ * that the code doesn't walk off of the end of the buffer (which is always
+ * a danger if the alignment of the source buffer is off). The destination
+ * string is always properly null terminated and fits in the destination
+ * buffer. Returns the length of the destination string in bytes (including
+ * null terminator).
+ *
+ * Note that some windows versions actually send multiword UTF-16 characters
+ * instead of straight UCS-2. The linux nls routines however aren't able to
+ * deal with those characters properly. In the event that we get some of
+ * those characters, they won't be translated properly.
+ */
+int
+cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
+ const struct nls_table *codepage, bool mapchar)
+{
+ int i, charlen, safelen;
+ int outlen = 0;
+ int nullsize = nls_nullsize(codepage);
+ int fromwords = fromlen / 2;
+ char tmp[NLS_MAX_CHARSET_SIZE];
+
+ /*
+ * because the chars can be of varying widths, we need to take care
+ * not to overflow the destination buffer when we get close to the
+ * end of it. Until we get to this offset, we don't need to check
+ * for overflow however.
+ */
+ safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize);
+
+ for (i = 0; i < fromwords && from[i]; i++) {
+ /*
+ * check to see if converting this character might make the
+ * conversion bleed into the null terminator
+ */
+ if (outlen >= safelen) {
+ charlen = cifs_mapchar(tmp, from[i], codepage, mapchar);
+ if ((outlen + charlen) > (tolen - nullsize))
+ break;
}
+
+ /* put converted char into 'to' buffer */
+ charlen = cifs_mapchar(&to[outlen], from[i], codepage, mapchar);
+ outlen += charlen;
}
- to[outlen] = 0;
+
+ /* properly null-terminate string */
+ for (i = 0; i < nullsize; i++)
+ to[outlen++] = 0;
+
return outlen;
}
@@ -88,3 +214,41 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
return i;
}
+/*
+ * cifs_strndup_from_ucs - copy a string from wire format to the local codepage
+ * @src - source string
+ * @maxlen - don't walk past this many bytes in the source string
+ * @is_unicode - is this a unicode string?
+ * @codepage - destination codepage
+ *
+ * Take a string given by the server, convert it to the local codepage and
+ * put it in a new buffer. Returns a pointer to the new string or NULL on
+ * error.
+ */
+char *
+cifs_strndup_from_ucs(const char *src, const int maxlen, const bool is_unicode,
+ const struct nls_table *codepage)
+{
+ int len;
+ char *dst;
+
+ if (is_unicode) {
+ len = cifs_ucs2_bytes((__le16 *) src, maxlen, codepage);
+ len += nls_nullsize(codepage);
+ dst = kmalloc(len, GFP_KERNEL);
+ if (!dst)
+ return NULL;
+ cifs_from_ucs2(dst, (__le16 *) src, len, maxlen, codepage,
+ false);
+ } else {
+ len = strnlen(src, maxlen);
+ len++;
+ dst = kmalloc(len, GFP_KERNEL);
+ if (!dst)
+ return NULL;
+ strlcpy(dst, src, len);
+ }
+
+ return dst;
+}
+
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index 14eb9a2395d3..650638275a6f 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -5,7 +5,7 @@
* Convert a unicode character to upper or lower case using
* compressed tables.
*
- * Copyright (c) International Business Machines Corp., 2000,2007
+ * Copyright (c) International Business Machines Corp., 2000,2009
*
* 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
@@ -37,6 +37,19 @@
#define UNIUPR_NOLOWER /* Example to not expand lower case tables */
+/*
+ * Windows maps these to the user defined 16 bit Unicode range since they are
+ * reserved symbols (along with \ and /), otherwise illegal to store
+ * in filenames in NTFS
+ */
+#define UNI_ASTERIK (__u16) ('*' + 0xF000)
+#define UNI_QUESTION (__u16) ('?' + 0xF000)
+#define UNI_COLON (__u16) (':' + 0xF000)
+#define UNI_GRTRTHAN (__u16) ('>' + 0xF000)
+#define UNI_LESSTHAN (__u16) ('<' + 0xF000)
+#define UNI_PIPE (__u16) ('|' + 0xF000)
+#define UNI_SLASH (__u16) ('\\' + 0xF000)
+
/* Just define what we want from uniupr.h. We don't want to define the tables
* in each source file.
*/
@@ -59,8 +72,14 @@ extern struct UniCaseRange UniLowerRange[];
#endif /* UNIUPR_NOLOWER */
#ifdef __KERNEL__
-int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *);
+int cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
+ const struct nls_table *codepage, bool mapchar);
+int cifs_ucs2_bytes(const __le16 *from, int maxbytes,
+ const struct nls_table *codepage);
int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
+char *cifs_strndup_from_ucs(const char *src, const int maxlen,
+ const bool is_unicode,
+ const struct nls_table *codepage);
#endif
/*
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 0d6d8b573652..116105c53335 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -35,6 +35,7 @@
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/smp_lock.h>
#include "cifsfs.h"
#include "cifspdu.h"
#define DECLARE_GLOBALS_HERE
@@ -203,6 +204,9 @@ cifs_put_super(struct super_block *sb)
cFYI(1, ("Empty cifs superblock info passed to unmount"));
return;
}
+
+ lock_kernel();
+
rc = cifs_umount(sb, cifs_sb);
if (rc)
cERROR(1, ("cifs_umount failed with return code %d", rc));
@@ -215,7 +219,8 @@ cifs_put_super(struct super_block *sb)
unload_nls(cifs_sb->local_nls);
kfree(cifs_sb);
- return;
+
+ unlock_kernel();
}
static int
@@ -530,6 +535,7 @@ static void cifs_umount_begin(struct super_block *sb)
if (tcon == NULL)
return;
+ lock_kernel();
read_lock(&cifs_tcp_ses_lock);
if (tcon->tc_count == 1)
tcon->tidStatus = CifsExiting;
@@ -548,6 +554,7 @@ static void cifs_umount_begin(struct super_block *sb)
}
/* BB FIXME - finish add checks for tidStatus BB */
+ unlock_kernel();
return;
}
@@ -599,8 +606,7 @@ cifs_get_sb(struct file_system_type *fs_type,
rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
if (rc) {
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ deactivate_locked_super(sb);
return rc;
}
sb->s_flags |= MS_ACTIVE;
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 77e190dc2883..051b71cfdea9 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -100,5 +100,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
extern const struct export_operations cifs_export_ops;
#endif /* EXPERIMENTAL */
-#define CIFS_VERSION "1.57"
+#define CIFS_VERSION "1.58"
#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index df40ab64cd95..a61ab772c6f6 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -82,8 +82,8 @@ enum securityEnum {
LANMAN, /* Legacy LANMAN auth */
NTLM, /* Legacy NTLM012 auth with NTLM hash */
NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
- RawNTLMSSP, /* NTLMSSP without SPNEGO */
- NTLMSSP, /* NTLMSSP via SPNEGO */
+ RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */
+ NTLMSSP, /* NTLMSSP via SPNEGO, NTLMv2 hash */
Kerberos, /* Kerberos via SPNEGO */
MSKerberos, /* MS Kerberos via SPNEGO */
};
@@ -531,6 +531,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
#define CIFSSEC_MAY_PLNTXT 0
#endif /* weak passwords */
#define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */
+#define CIFSSEC_MAY_NTLMSSP 0x00080 /* raw ntlmssp with ntlmv2 */
#define CIFSSEC_MUST_SIGN 0x01001
/* note that only one of the following can be set so the
@@ -543,22 +544,23 @@ require use of the stronger protocol */
#define CIFSSEC_MUST_LANMAN 0x10010
#define CIFSSEC_MUST_PLNTXT 0x20020
#ifdef CONFIG_CIFS_UPCALL
-#define CIFSSEC_MASK 0x3F03F /* allows weak security but also krb5 */
+#define CIFSSEC_MASK 0xAF0AF /* allows weak security but also krb5 */
#else
-#define CIFSSEC_MASK 0x37037 /* current flags supported if weak */
+#define CIFSSEC_MASK 0xA70A7 /* current flags supported if weak */
#endif /* UPCALL */
#else /* do not allow weak pw hash */
#ifdef CONFIG_CIFS_UPCALL
-#define CIFSSEC_MASK 0x0F00F /* flags supported if no weak allowed */
+#define CIFSSEC_MASK 0x8F08F /* flags supported if no weak allowed */
#else
-#define CIFSSEC_MASK 0x07007 /* flags supported if no weak allowed */
+#define CIFSSEC_MASK 0x87087 /* flags supported if no weak allowed */
#endif /* UPCALL */
#endif /* WEAK_PW_HASH */
#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */
+#define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */
#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2)
#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2)
-#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5)
+#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
/*
*****************************************************************
* All constants go here
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 4167716d32f2..fae083930eee 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -260,8 +260,7 @@ extern int CIFSUnixCreateSymLink(const int xid,
const struct nls_table *nls_codepage);
extern int CIFSSMBUnixQuerySymLink(const int xid,
struct cifsTconInfo *tcon,
- const unsigned char *searchName,
- char *syminfo, const int buflen,
+ const unsigned char *searchName, char **syminfo,
const struct nls_table *nls_codepage);
extern int CIFSSMBQueryReparseLinkInfo(const int xid,
struct cifsTconInfo *tcon,
@@ -307,8 +306,6 @@ extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, __u64 *inode_number,
const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
- const struct nls_table *codepage);
extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
const struct nls_table *cp, int mapChars);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index a0845dc7b8a9..75e6623a8635 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifssmb.c
*
- * Copyright (C) International Business Machines Corp., 2002,2008
+ * Copyright (C) International Business Machines Corp., 2002,2009
* Author(s): Steve French (sfrench@us.ibm.com)
*
* Contains the routines for constructing the SMB PDUs themselves
@@ -81,41 +81,6 @@ static struct {
#endif /* CONFIG_CIFS_WEAK_PW_HASH */
#endif /* CIFS_POSIX */
-/* Allocates buffer into dst and copies smb string from src to it.
- * caller is responsible for freeing dst if function returned 0.
- * returns:
- * on success - 0
- * on failure - errno
- */
-static int
-cifs_strncpy_to_host(char **dst, const char *src, const int maxlen,
- const bool is_unicode, const struct nls_table *nls_codepage)
-{
- int plen;
-
- if (is_unicode) {
- plen = UniStrnlen((wchar_t *)src, maxlen);
- *dst = kmalloc(plen + 2, GFP_KERNEL);
- if (!*dst)
- goto cifs_strncpy_to_host_ErrExit;
- cifs_strfromUCS_le(*dst, (__le16 *)src, plen, nls_codepage);
- } else {
- plen = strnlen(src, maxlen);
- *dst = kmalloc(plen + 2, GFP_KERNEL);
- if (!*dst)
- goto cifs_strncpy_to_host_ErrExit;
- strncpy(*dst, src, plen);
- }
- (*dst)[plen] = 0;
- (*dst)[plen+1] = 0; /* harmless for ASCII case, needed for Unicode */
- return 0;
-
-cifs_strncpy_to_host_ErrExit:
- cERROR(1, ("Failed to allocate buffer for string\n"));
- return -ENOMEM;
-}
-
-
/* Mark as invalid, all open files on tree connections since they
were closed when session to server was lost */
static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
@@ -484,6 +449,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
cFYI(1, ("Kerberos only mechanism, enable extended security"));
pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
}
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
+ pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+ else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
+ cFYI(1, ("NTLMSSP only mechanism, enable extended security"));
+ pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+ }
+#endif
count = 0;
for (i = 0; i < CIFS_NUM_PROT; i++) {
@@ -620,6 +593,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
server->secType = NTLMv2;
else if (secFlags & CIFSSEC_MAY_KRB5)
server->secType = Kerberos;
+ else if (secFlags & CIFSSEC_MAY_NTLMSSP)
+ server->secType = NTLMSSP;
else if (secFlags & CIFSSEC_MAY_LANMAN)
server->secType = LANMAN;
/* #ifdef CONFIG_CIFS_EXPERIMENTAL
@@ -2417,8 +2392,7 @@ winCreateHardLinkRetry:
int
CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
- const unsigned char *searchName,
- char *symlinkinfo, const int buflen,
+ const unsigned char *searchName, char **symlinkinfo,
const struct nls_table *nls_codepage)
{
/* SMB_QUERY_FILE_UNIX_LINK */
@@ -2428,6 +2402,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
int bytes_returned;
int name_len;
__u16 params, byte_count;
+ char *data_start;
cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName));
@@ -2482,30 +2457,26 @@ querySymLinkRetry:
/* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if (rc || (pSMBr->ByteCount < 2))
/* BB also check enough total bytes returned */
- rc = -EIO; /* bad smb */
+ if (rc || (pSMBr->ByteCount < 2))
+ rc = -EIO;
else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
+ bool is_unicode;
+ u16 count = le16_to_cpu(pSMBr->t2.DataCount);
+
+ data_start = ((char *) &pSMBr->hdr.Protocol) +
+ le16_to_cpu(pSMBr->t2.DataOffset);
+
+ if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
+ is_unicode = true;
+ else
+ is_unicode = false;
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = UniStrnlen((wchar_t *) ((char *)
- &pSMBr->hdr.Protocol + data_offset),
- min_t(const int, buflen, count) / 2);
/* BB FIXME investigate remapping reserved chars here */
- cifs_strfromUCS_le(symlinkinfo,
- (__le16 *) ((char *)&pSMBr->hdr.Protocol
- + data_offset),
- name_len, nls_codepage);
- } else {
- strncpy(symlinkinfo,
- (char *) &pSMBr->hdr.Protocol +
- data_offset,
- min_t(const int, buflen, count));
- }
- symlinkinfo[buflen] = 0;
- /* just in case so calling code does not go off the end of buffer */
+ *symlinkinfo = cifs_strndup_from_ucs(data_start, count,
+ is_unicode, nls_codepage);
+ if (!symlinkinfo)
+ rc = -ENOMEM;
}
}
cifs_buf_release(pSMB);
@@ -2603,7 +2574,6 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
*pparmlen = parm_count;
return 0;
}
-#endif /* CIFS_EXPERIMENTAL */
int
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
@@ -2613,7 +2583,6 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
{
int rc = 0;
int bytes_returned;
- int name_len;
struct smb_com_transaction_ioctl_req *pSMB;
struct smb_com_transaction_ioctl_rsp *pSMBr;
@@ -2650,59 +2619,55 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
} else { /* decode response */
__u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
__u32 data_count = le32_to_cpu(pSMBr->DataCount);
- if ((pSMBr->ByteCount < 2) || (data_offset > 512))
+ if ((pSMBr->ByteCount < 2) || (data_offset > 512)) {
/* BB also check enough total bytes returned */
rc = -EIO; /* bad smb */
- else {
- if (data_count && (data_count < 2048)) {
- char *end_of_smb = 2 /* sizeof byte count */ +
- pSMBr->ByteCount +
- (char *)&pSMBr->ByteCount;
+ goto qreparse_out;
+ }
+ if (data_count && (data_count < 2048)) {
+ char *end_of_smb = 2 /* sizeof byte count */ +
+ pSMBr->ByteCount + (char *)&pSMBr->ByteCount;
- struct reparse_data *reparse_buf =
+ struct reparse_data *reparse_buf =
(struct reparse_data *)
((char *)&pSMBr->hdr.Protocol
+ data_offset);
- if ((char *)reparse_buf >= end_of_smb) {
- rc = -EIO;
- goto qreparse_out;
- }
- if ((reparse_buf->LinkNamesBuf +
- reparse_buf->TargetNameOffset +
- reparse_buf->TargetNameLen) >
- end_of_smb) {
- cFYI(1, ("reparse buf beyond SMB"));
- rc = -EIO;
- goto qreparse_out;
- }
+ if ((char *)reparse_buf >= end_of_smb) {
+ rc = -EIO;
+ goto qreparse_out;
+ }
+ if ((reparse_buf->LinkNamesBuf +
+ reparse_buf->TargetNameOffset +
+ reparse_buf->TargetNameLen) > end_of_smb) {
+ cFYI(1, ("reparse buf beyond SMB"));
+ rc = -EIO;
+ goto qreparse_out;
+ }
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = UniStrnlen((wchar_t *)
+ if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
+ cifs_from_ucs2(symlinkinfo, (__le16 *)
(reparse_buf->LinkNamesBuf +
reparse_buf->TargetNameOffset),
- min(buflen/2,
- reparse_buf->TargetNameLen / 2));
- cifs_strfromUCS_le(symlinkinfo,
- (__le16 *) (reparse_buf->LinkNamesBuf +
- reparse_buf->TargetNameOffset),
- name_len, nls_codepage);
- } else { /* ASCII names */
- strncpy(symlinkinfo,
- reparse_buf->LinkNamesBuf +
- reparse_buf->TargetNameOffset,
- min_t(const int, buflen,
- reparse_buf->TargetNameLen));
- }
- } else {
- rc = -EIO;
- cFYI(1, ("Invalid return data count on "
- "get reparse info ioctl"));
+ buflen,
+ reparse_buf->TargetNameLen,
+ nls_codepage, 0);
+ } else { /* ASCII names */
+ strncpy(symlinkinfo,
+ reparse_buf->LinkNamesBuf +
+ reparse_buf->TargetNameOffset,
+ min_t(const int, buflen,
+ reparse_buf->TargetNameLen));
}
- symlinkinfo[buflen] = 0; /* just in case so the caller
- does not go off the end of the buffer */
- cFYI(1, ("readlink result - %s", symlinkinfo));
+ } else {
+ rc = -EIO;
+ cFYI(1, ("Invalid return data count on "
+ "get reparse info ioctl"));
}
+ symlinkinfo[buflen] = 0; /* just in case so the caller
+ does not go off the end of the buffer */
+ cFYI(1, ("readlink result - %s", symlinkinfo));
}
+
qreparse_out:
cifs_buf_release(pSMB);
@@ -2711,6 +2676,7 @@ qreparse_out:
return rc;
}
+#endif /* CIFS_EXPERIMENTAL */
#ifdef CONFIG_CIFS_POSIX
@@ -3928,27 +3894,6 @@ GetInodeNumOut:
return rc;
}
-/* computes length of UCS string converted to host codepage
- * @src: UCS string
- * @maxlen: length of the input string in UCS characters
- * (not in bytes)
- *
- * return: size of input string in host codepage
- */
-static int hostlen_fromUCS(const __le16 *src, const int maxlen,
- const struct nls_table *nls_codepage) {
- int i;
- int hostlen = 0;
- char to[4];
- int charlen;
- for (i = 0; (i < maxlen) && src[i]; ++i) {
- charlen = nls_codepage->uni2char(le16_to_cpu(src[i]),
- to, NLS_MAX_CHARSET_SIZE);
- hostlen += charlen > 0 ? charlen : 1;
- }
- return hostlen;
-}
-
/* parses DFS refferal V3 structure
* caller is responsible for freeing target_nodes
* returns:
@@ -3994,7 +3939,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n",
*num_of_nodes,
- le16_to_cpu(pSMBr->DFSFlags)));
+ le32_to_cpu(pSMBr->DFSFlags)));
*target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
*num_of_nodes, GFP_KERNEL);
@@ -4010,14 +3955,14 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
int max_len;
struct dfs_info3_param *node = (*target_nodes)+i;
- node->flags = le16_to_cpu(pSMBr->DFSFlags);
+ node->flags = le32_to_cpu(pSMBr->DFSFlags);
if (is_unicode) {
__le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
GFP_KERNEL);
cifsConvertToUCS((__le16 *) tmp, searchName,
PATH_MAX, nls_codepage, remap);
- node->path_consumed = hostlen_fromUCS(tmp,
- le16_to_cpu(pSMBr->PathConsumed)/2,
+ node->path_consumed = cifs_ucs2_bytes(tmp,
+ le16_to_cpu(pSMBr->PathConsumed),
nls_codepage);
kfree(tmp);
} else
@@ -4029,20 +3974,24 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
/* copy DfsPath */
temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
max_len = data_end - temp;
- rc = cifs_strncpy_to_host(&(node->path_name), temp,
- max_len, is_unicode, nls_codepage);
- if (rc)
+ node->path_name = cifs_strndup_from_ucs(temp, max_len,
+ is_unicode, nls_codepage);
+ if (IS_ERR(node->path_name)) {
+ rc = PTR_ERR(node->path_name);
+ node->path_name = NULL;
goto parse_DFS_referrals_exit;
+ }
/* copy link target UNC */
temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
max_len = data_end - temp;
- rc = cifs_strncpy_to_host(&(node->node_name), temp,
- max_len, is_unicode, nls_codepage);
- if (rc)
+ node->node_name = cifs_strndup_from_ucs(temp, max_len,
+ is_unicode, nls_codepage);
+ if (IS_ERR(node->node_name)) {
+ rc = PTR_ERR(node->node_name);
+ node->node_name = NULL;
goto parse_DFS_referrals_exit;
-
- ref += le16_to_cpu(ref->Size);
+ }
}
parse_DFS_referrals_exit:
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index bacdef1546b7..4aa81a507b74 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/connect.c
*
- * Copyright (C) International Business Machines Corp., 2002,2008
+ * Copyright (C) International Business Machines Corp., 2002,2009
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -32,6 +32,7 @@
#include <linux/kthread.h>
#include <linux/pagevec.h>
#include <linux/freezer.h>
+#include <linux/namei.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include <net/ipv6.h>
@@ -978,6 +979,13 @@ cifs_parse_mount_options(char *options, const char *devname,
return 1;
} else if (strnicmp(value, "krb5", 4) == 0) {
vol->secFlg |= CIFSSEC_MAY_KRB5;
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
+ vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
+ CIFSSEC_MUST_SIGN;
+ } else if (strnicmp(value, "ntlmssp", 7) == 0) {
+ vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
+#endif
} else if (strnicmp(value, "ntlmv2i", 7) == 0) {
vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
CIFSSEC_MUST_SIGN;
@@ -2278,6 +2286,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
#ifdef CONFIG_CIFS_DFS_UPCALL
struct dfs_info3_param *referrals = NULL;
unsigned int num_referrals = 0;
+ int referral_walks_count = 0;
try_mount_again:
#endif
full_path = NULL;
@@ -2525,6 +2534,16 @@ remote_path_check:
/* get referral if needed */
if (rc == -EREMOTE) {
#ifdef CONFIG_CIFS_DFS_UPCALL
+ if (referral_walks_count > MAX_NESTED_LINKS) {
+ /*
+ * BB: when we implement proper loop detection,
+ * we will remove this check. But now we need it
+ * to prevent an indefinite loop if 'DFS tree' is
+ * misconfigured (i.e. has loops).
+ */
+ rc = -ELOOP;
+ goto mount_fail_check;
+ }
/* convert forward to back slashes in prepath here if needed */
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
convert_delimiter(cifs_sb->prepath,
@@ -2558,6 +2577,7 @@ remote_path_check:
cleanup_volume_info(&volume_info);
FreeXid(xid);
kfree(full_path);
+ referral_walks_count++;
goto try_mount_again;
}
#else /* No DFS support, return error on mount */
@@ -2592,1041 +2612,6 @@ out:
return rc;
}
-static int
-CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
- char session_key[CIFS_SESS_KEY_SIZE],
- const struct nls_table *nls_codepage)
-{
- struct smb_hdr *smb_buffer;
- struct smb_hdr *smb_buffer_response;
- SESSION_SETUP_ANDX *pSMB;
- SESSION_SETUP_ANDX *pSMBr;
- char *bcc_ptr;
- char *user;
- char *domain;
- int rc = 0;
- int remaining_words = 0;
- int bytes_returned = 0;
- int len;
- __u32 capabilities;
- __u16 count;
-
- cFYI(1, ("In sesssetup"));
- if (ses == NULL)
- return -EINVAL;
- user = ses->userName;
- domain = ses->domainName;
- smb_buffer = cifs_buf_get();
-
- if (smb_buffer == NULL)
- return -ENOMEM;
-
- smb_buffer_response = smb_buffer;
- pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
-
- /* send SMBsessionSetup here */
- header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
- NULL /* no tCon exists yet */ , 13 /* wct */ );
-
- smb_buffer->Mid = GetNextMid(ses->server);
- pSMB->req_no_secext.AndXCommand = 0xFF;
- pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
- pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
-
- if (ses->server->secMode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
- capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
- CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
- if (ses->capabilities & CAP_UNICODE) {
- smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- capabilities |= CAP_UNICODE;
- }
- if (ses->capabilities & CAP_STATUS32) {
- smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- capabilities |= CAP_STATUS32;
- }
- if (ses->capabilities & CAP_DFS) {
- smb_buffer->Flags2 |= SMBFLG2_DFS;
- capabilities |= CAP_DFS;
- }
- pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
-
- pSMB->req_no_secext.CaseInsensitivePasswordLength =
- cpu_to_le16(CIFS_SESS_KEY_SIZE);
-
- pSMB->req_no_secext.CaseSensitivePasswordLength =
- cpu_to_le16(CIFS_SESS_KEY_SIZE);
- bcc_ptr = pByteArea(smb_buffer);
- memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
- bcc_ptr += CIFS_SESS_KEY_SIZE;
- memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
- bcc_ptr += CIFS_SESS_KEY_SIZE;
-
- if (ses->capabilities & CAP_UNICODE) {
- if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
- *bcc_ptr = 0;
- bcc_ptr++;
- }
- if (user == NULL)
- bytes_returned = 0; /* skip null user */
- else
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
- nls_codepage);
- /* convert number of 16 bit words to bytes */
- bcc_ptr += 2 * bytes_returned;
- bcc_ptr += 2; /* trailing null */
- if (domain == NULL)
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr,
- "CIFS_LINUX_DOM", 32, nls_codepage);
- else
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
- nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bcc_ptr += 2;
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
- 32, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
- 32, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bcc_ptr += 2;
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
- 64, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bcc_ptr += 2;
- } else {
- if (user != NULL) {
- strncpy(bcc_ptr, user, 200);
- bcc_ptr += strnlen(user, 200);
- }
- *bcc_ptr = 0;
- bcc_ptr++;
- if (domain == NULL) {
- strcpy(bcc_ptr, "CIFS_LINUX_DOM");
- bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
- } else {
- strncpy(bcc_ptr, domain, 64);
- bcc_ptr += strnlen(domain, 64);
- *bcc_ptr = 0;
- bcc_ptr++;
- }
- strcpy(bcc_ptr, "Linux version ");
- bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, utsname()->release);
- bcc_ptr += strlen(utsname()->release) + 1;
- strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
- bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
- }
- count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
- smb_buffer->smb_buf_length += count;
- pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
- &bytes_returned, CIFS_LONG_OP);
- if (rc) {
-/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
- } else if ((smb_buffer_response->WordCount == 3)
- || (smb_buffer_response->WordCount == 4)) {
- __u16 action = le16_to_cpu(pSMBr->resp.Action);
- __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
- if (action & GUEST_LOGIN)
- cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
- ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
- (little endian) */
- cFYI(1, ("UID = %d ", ses->Suid));
- /* response can have either 3 or 4 word count - Samba sends 3 */
- bcc_ptr = pByteArea(smb_buffer_response);
- if ((pSMBr->resp.hdr.WordCount == 3)
- || ((pSMBr->resp.hdr.WordCount == 4)
- && (blob_len < pSMBr->resp.ByteCount))) {
- if (pSMBr->resp.hdr.WordCount == 4)
- bcc_ptr += blob_len;
-
- if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
- if ((long) (bcc_ptr) % 2) {
- remaining_words =
- (BCC(smb_buffer_response) - 1) / 2;
- /* Unicode strings must be word
- aligned */
- bcc_ptr++;
- } else {
- remaining_words =
- BCC(smb_buffer_response) / 2;
- }
- len =
- UniStrnlen((wchar_t *) bcc_ptr,
- remaining_words - 1);
-/* We look for obvious messed up bcc or strings in response so we do not go off
- the end since (at least) WIN2K and Windows XP have a major bug in not null
- terminating last Unicode string in response */
- kfree(ses->serverOS);
- ses->serverOS = kzalloc(2 * (len + 1),
- GFP_KERNEL);
- if (ses->serverOS == NULL)
- goto sesssetup_nomem;
- cifs_strfromUCS_le(ses->serverOS,
- (__le16 *)bcc_ptr,
- len, nls_codepage);
- bcc_ptr += 2 * (len + 1);
- remaining_words -= len + 1;
- ses->serverOS[2 * len] = 0;
- ses->serverOS[1 + (2 * len)] = 0;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *)bcc_ptr,
- remaining_words-1);
- kfree(ses->serverNOS);
- ses->serverNOS = kzalloc(2 * (len + 1),
- GFP_KERNEL);
- if (ses->serverNOS == NULL)
- goto sesssetup_nomem;
- cifs_strfromUCS_le(ses->serverNOS,
- (__le16 *)bcc_ptr,
- len, nls_codepage);
- bcc_ptr += 2 * (len + 1);
- ses->serverNOS[2 * len] = 0;
- ses->serverNOS[1 + (2 * len)] = 0;
- if (strncmp(ses->serverNOS,
- "NT LAN Manager 4", 16) == 0) {
- cFYI(1, ("NT4 server"));
- ses->flags |= CIFS_SES_NT4;
- }
- remaining_words -= len + 1;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
- /* last string is not always null terminated
- (for e.g. for Windows XP & 2000) */
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2*(len+1),
- GFP_KERNEL);
- if (ses->serverDomain == NULL)
- goto sesssetup_nomem;
- cifs_strfromUCS_le(ses->serverDomain,
- (__le16 *)bcc_ptr,
- len, nls_codepage);
- bcc_ptr += 2 * (len + 1);
- ses->serverDomain[2*len] = 0;
- ses->serverDomain[1+(2*len)] = 0;
- } else { /* else no more room so create
- dummy domain string */
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2, GFP_KERNEL);
- }
- } else { /* no room so create dummy domain
- and NOS string */
-
- /* if these kcallocs fail not much we
- can do, but better to not fail the
- sesssetup itself */
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2, GFP_KERNEL);
- kfree(ses->serverNOS);
- ses->serverNOS =
- kzalloc(2, GFP_KERNEL);
- }
- } else { /* ASCII */
- len = strnlen(bcc_ptr, 1024);
- if (((long) bcc_ptr + len) - (long)
- pByteArea(smb_buffer_response)
- <= BCC(smb_buffer_response)) {
- kfree(ses->serverOS);
- ses->serverOS = kzalloc(len + 1,
- GFP_KERNEL);
- if (ses->serverOS == NULL)
- goto sesssetup_nomem;
- strncpy(ses->serverOS, bcc_ptr, len);
-
- bcc_ptr += len;
- /* null terminate the string */
- bcc_ptr[0] = 0;
- bcc_ptr++;
-
- len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverNOS);
- ses->serverNOS = kzalloc(len + 1,
- GFP_KERNEL);
- if (ses->serverNOS == NULL)
- goto sesssetup_nomem;
- strncpy(ses->serverNOS, bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
-
- len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverDomain);
- ses->serverDomain = kzalloc(len + 1,
- GFP_KERNEL);
- if (ses->serverDomain == NULL)
- goto sesssetup_nomem;
- strncpy(ses->serverDomain, bcc_ptr,
- len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
- } else
- cFYI(1,
- ("Variable field of length %d "
- "extends beyond end of smb ",
- len));
- }
- } else {
- cERROR(1, ("Security Blob Length extends beyond "
- "end of SMB"));
- }
- } else {
- cERROR(1, ("Invalid Word count %d: ",
- smb_buffer_response->WordCount));
- rc = -EIO;
- }
-sesssetup_nomem: /* do not return an error on nomem for the info strings,
- since that could make reconnection harder, and
- reconnection might be needed to free memory */
- cifs_buf_release(smb_buffer);
-
- return rc;
-}
-
-static int
-CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
- struct cifsSesInfo *ses, bool *pNTLMv2_flag,
- const struct nls_table *nls_codepage)
-{
- struct smb_hdr *smb_buffer;
- struct smb_hdr *smb_buffer_response;
- SESSION_SETUP_ANDX *pSMB;
- SESSION_SETUP_ANDX *pSMBr;
- char *bcc_ptr;
- char *domain;
- int rc = 0;
- int remaining_words = 0;
- int bytes_returned = 0;
- int len;
- int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
- PNEGOTIATE_MESSAGE SecurityBlob;
- PCHALLENGE_MESSAGE SecurityBlob2;
- __u32 negotiate_flags, capabilities;
- __u16 count;
-
- cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
- if (ses == NULL)
- return -EINVAL;
- domain = ses->domainName;
- *pNTLMv2_flag = false;
- smb_buffer = cifs_buf_get();
- if (smb_buffer == NULL) {
- return -ENOMEM;
- }
- smb_buffer_response = smb_buffer;
- pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
- pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
-
- /* send SMBsessionSetup here */
- header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
- NULL /* no tCon exists yet */ , 12 /* wct */ );
-
- smb_buffer->Mid = GetNextMid(ses->server);
- pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
- pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
-
- pSMB->req.AndXCommand = 0xFF;
- pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
- pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
-
- if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
- capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
- CAP_EXTENDED_SECURITY;
- if (ses->capabilities & CAP_UNICODE) {
- smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- capabilities |= CAP_UNICODE;
- }
- if (ses->capabilities & CAP_STATUS32) {
- smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- capabilities |= CAP_STATUS32;
- }
- if (ses->capabilities & CAP_DFS) {
- smb_buffer->Flags2 |= SMBFLG2_DFS;
- capabilities |= CAP_DFS;
- }
- pSMB->req.Capabilities = cpu_to_le32(capabilities);
-
- bcc_ptr = (char *) &pSMB->req.SecurityBlob;
- SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
- strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
- SecurityBlob->MessageType = NtLmNegotiate;
- negotiate_flags =
- NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
- NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
- NTLMSSP_NEGOTIATE_56 |
- /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
- if (sign_CIFS_PDUs)
- negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
-/* if (ntlmv2_support)
- negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
- /* setup pointers to domain name and workstation name */
- bcc_ptr += SecurityBlobLength;
-
- SecurityBlob->WorkstationName.Buffer = 0;
- SecurityBlob->WorkstationName.Length = 0;
- SecurityBlob->WorkstationName.MaximumLength = 0;
-
- /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
- along with username on auth request (ie the response to challenge) */
- SecurityBlob->DomainName.Buffer = 0;
- SecurityBlob->DomainName.Length = 0;
- SecurityBlob->DomainName.MaximumLength = 0;
- if (ses->capabilities & CAP_UNICODE) {
- if ((long) bcc_ptr % 2) {
- *bcc_ptr = 0;
- bcc_ptr++;
- }
-
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
- 32, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
- nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bcc_ptr += 2; /* null terminate Linux version */
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
- 64, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- *(bcc_ptr + 1) = 0;
- *(bcc_ptr + 2) = 0;
- bcc_ptr += 2; /* null terminate network opsys string */
- *(bcc_ptr + 1) = 0;
- *(bcc_ptr + 2) = 0;
- bcc_ptr += 2; /* null domain */
- } else { /* ASCII */
- strcpy(bcc_ptr, "Linux version ");
- bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, utsname()->release);
- bcc_ptr += strlen(utsname()->release) + 1;
- strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
- bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
- bcc_ptr++; /* empty domain field */
- *bcc_ptr = 0;
- }
- SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
- pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
- count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
- smb_buffer->smb_buf_length += count;
- pSMB->req.ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
- &bytes_returned, CIFS_LONG_OP);
-
- if (smb_buffer_response->Status.CifsError ==
- cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
- rc = 0;
-
- if (rc) {
-/* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
- } else if ((smb_buffer_response->WordCount == 3)
- || (smb_buffer_response->WordCount == 4)) {
- __u16 action = le16_to_cpu(pSMBr->resp.Action);
- __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
-
- if (action & GUEST_LOGIN)
- cFYI(1, ("Guest login"));
- /* Do we want to set anything in SesInfo struct when guest login? */
-
- bcc_ptr = pByteArea(smb_buffer_response);
- /* response can have either 3 or 4 word count - Samba sends 3 */
-
- SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
- if (SecurityBlob2->MessageType != NtLmChallenge) {
- cFYI(1, ("Unexpected NTLMSSP message type received %d",
- SecurityBlob2->MessageType));
- } else if (ses) {
- ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
- cFYI(1, ("UID = %d", ses->Suid));
- if ((pSMBr->resp.hdr.WordCount == 3)
- || ((pSMBr->resp.hdr.WordCount == 4)
- && (blob_len <
- pSMBr->resp.ByteCount))) {
-
- if (pSMBr->resp.hdr.WordCount == 4) {
- bcc_ptr += blob_len;
- cFYI(1, ("Security Blob Length %d",
- blob_len));
- }
-
- cFYI(1, ("NTLMSSP Challenge rcvd"));
-
- memcpy(ses->server->cryptKey,
- SecurityBlob2->Challenge,
- CIFS_CRYPTO_KEY_SIZE);
- if (SecurityBlob2->NegotiateFlags &
- cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
- *pNTLMv2_flag = true;
-
- if ((SecurityBlob2->NegotiateFlags &
- cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
- || (sign_CIFS_PDUs > 1))
- ses->server->secMode |=
- SECMODE_SIGN_REQUIRED;
- if ((SecurityBlob2->NegotiateFlags &
- cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
- ses->server->secMode |=
- SECMODE_SIGN_ENABLED;
-
- if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
- if ((long) (bcc_ptr) % 2) {
- remaining_words =
- (BCC(smb_buffer_response)
- - 1) / 2;
- /* Must word align unicode strings */
- bcc_ptr++;
- } else {
- remaining_words =
- BCC
- (smb_buffer_response) / 2;
- }
- len =
- UniStrnlen((wchar_t *) bcc_ptr,
- remaining_words - 1);
-/* We look for obvious messed up bcc or strings in response so we do not go off
- the end since (at least) WIN2K and Windows XP have a major bug in not null
- terminating last Unicode string in response */
- kfree(ses->serverOS);
- ses->serverOS =
- kzalloc(2 * (len + 1), GFP_KERNEL);
- cifs_strfromUCS_le(ses->serverOS,
- (__le16 *)
- bcc_ptr, len,
- nls_codepage);
- bcc_ptr += 2 * (len + 1);
- remaining_words -= len + 1;
- ses->serverOS[2 * len] = 0;
- ses->serverOS[1 + (2 * len)] = 0;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *)
- bcc_ptr,
- remaining_words
- - 1);
- kfree(ses->serverNOS);
- ses->serverNOS =
- kzalloc(2 * (len + 1),
- GFP_KERNEL);
- cifs_strfromUCS_le(ses->
- serverNOS,
- (__le16 *)
- bcc_ptr,
- len,
- nls_codepage);
- bcc_ptr += 2 * (len + 1);
- ses->serverNOS[2 * len] = 0;
- ses->serverNOS[1 +
- (2 * len)] = 0;
- remaining_words -= len + 1;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
- /* last string not always null terminated
- (for e.g. for Windows XP & 2000) */
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2 *
- (len +
- 1),
- GFP_KERNEL);
- cifs_strfromUCS_le
- (ses->serverDomain,
- (__le16 *)bcc_ptr,
- len, nls_codepage);
- bcc_ptr +=
- 2 * (len + 1);
- ses->serverDomain[2*len]
- = 0;
- ses->serverDomain
- [1 + (2 * len)]
- = 0;
- } /* else no more room so create dummy domain string */
- else {
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2,
- GFP_KERNEL);
- }
- } else { /* no room so create dummy domain and NOS string */
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2, GFP_KERNEL);
- kfree(ses->serverNOS);
- ses->serverNOS =
- kzalloc(2, GFP_KERNEL);
- }
- } else { /* ASCII */
- len = strnlen(bcc_ptr, 1024);
- if (((long) bcc_ptr + len) - (long)
- pByteArea(smb_buffer_response)
- <= BCC(smb_buffer_response)) {
- kfree(ses->serverOS);
- ses->serverOS =
- kzalloc(len + 1,
- GFP_KERNEL);
- strncpy(ses->serverOS,
- bcc_ptr, len);
-
- bcc_ptr += len;
- bcc_ptr[0] = 0; /* null terminate string */
- bcc_ptr++;
-
- len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverNOS);
- ses->serverNOS =
- kzalloc(len + 1,
- GFP_KERNEL);
- strncpy(ses->serverNOS, bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
-
- len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(len + 1,
- GFP_KERNEL);
- strncpy(ses->serverDomain,
- bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
- } else
- cFYI(1,
- ("field of length %d "
- "extends beyond end of smb",
- len));
- }
- } else {
- cERROR(1, ("Security Blob Length extends beyond"
- " end of SMB"));
- }
- } else {
- cERROR(1, ("No session structure passed in."));
- }
- } else {
- cERROR(1, ("Invalid Word count %d:",
- smb_buffer_response->WordCount));
- rc = -EIO;
- }
-
- cifs_buf_release(smb_buffer);
-
- return rc;
-}
-static int
-CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
- char *ntlm_session_key, bool ntlmv2_flag,
- const struct nls_table *nls_codepage)
-{
- struct smb_hdr *smb_buffer;
- struct smb_hdr *smb_buffer_response;
- SESSION_SETUP_ANDX *pSMB;
- SESSION_SETUP_ANDX *pSMBr;
- char *bcc_ptr;
- char *user;
- char *domain;
- int rc = 0;
- int remaining_words = 0;
- int bytes_returned = 0;
- int len;
- int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
- PAUTHENTICATE_MESSAGE SecurityBlob;
- __u32 negotiate_flags, capabilities;
- __u16 count;
-
- cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
- if (ses == NULL)
- return -EINVAL;
- user = ses->userName;
- domain = ses->domainName;
- smb_buffer = cifs_buf_get();
- if (smb_buffer == NULL) {
- return -ENOMEM;
- }
- smb_buffer_response = smb_buffer;
- pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
- pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
-
- /* send SMBsessionSetup here */
- header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
- NULL /* no tCon exists yet */ , 12 /* wct */ );
-
- smb_buffer->Mid = GetNextMid(ses->server);
- pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
- pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
- pSMB->req.AndXCommand = 0xFF;
- pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
- pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
-
- pSMB->req.hdr.Uid = ses->Suid;
-
- if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
- capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
- CAP_EXTENDED_SECURITY;
- if (ses->capabilities & CAP_UNICODE) {
- smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- capabilities |= CAP_UNICODE;
- }
- if (ses->capabilities & CAP_STATUS32) {
- smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- capabilities |= CAP_STATUS32;
- }
- if (ses->capabilities & CAP_DFS) {
- smb_buffer->Flags2 |= SMBFLG2_DFS;
- capabilities |= CAP_DFS;
- }
- pSMB->req.Capabilities = cpu_to_le32(capabilities);
-
- bcc_ptr = (char *)&pSMB->req.SecurityBlob;
- SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
- strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
- SecurityBlob->MessageType = NtLmAuthenticate;
- bcc_ptr += SecurityBlobLength;
- negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
- 0x80000000 | NTLMSSP_NEGOTIATE_128;
- if (sign_CIFS_PDUs)
- negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
- if (ntlmv2_flag)
- negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
-
-/* setup pointers to domain name and workstation name */
-
- SecurityBlob->WorkstationName.Buffer = 0;
- SecurityBlob->WorkstationName.Length = 0;
- SecurityBlob->WorkstationName.MaximumLength = 0;
- SecurityBlob->SessionKey.Length = 0;
- SecurityBlob->SessionKey.MaximumLength = 0;
- SecurityBlob->SessionKey.Buffer = 0;
-
- SecurityBlob->LmChallengeResponse.Length = 0;
- SecurityBlob->LmChallengeResponse.MaximumLength = 0;
- SecurityBlob->LmChallengeResponse.Buffer = 0;
-
- SecurityBlob->NtChallengeResponse.Length =
- cpu_to_le16(CIFS_SESS_KEY_SIZE);
- SecurityBlob->NtChallengeResponse.MaximumLength =
- cpu_to_le16(CIFS_SESS_KEY_SIZE);
- memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
- SecurityBlob->NtChallengeResponse.Buffer =
- cpu_to_le32(SecurityBlobLength);
- SecurityBlobLength += CIFS_SESS_KEY_SIZE;
- bcc_ptr += CIFS_SESS_KEY_SIZE;
-
- if (ses->capabilities & CAP_UNICODE) {
- if (domain == NULL) {
- SecurityBlob->DomainName.Buffer = 0;
- SecurityBlob->DomainName.Length = 0;
- SecurityBlob->DomainName.MaximumLength = 0;
- } else {
- __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
- nls_codepage);
- ln *= 2;
- SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(ln);
- SecurityBlob->DomainName.Buffer =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += ln;
- SecurityBlobLength += ln;
- SecurityBlob->DomainName.Length = cpu_to_le16(ln);
- }
- if (user == NULL) {
- SecurityBlob->UserName.Buffer = 0;
- SecurityBlob->UserName.Length = 0;
- SecurityBlob->UserName.MaximumLength = 0;
- } else {
- __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
- nls_codepage);
- ln *= 2;
- SecurityBlob->UserName.MaximumLength =
- cpu_to_le16(ln);
- SecurityBlob->UserName.Buffer =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += ln;
- SecurityBlobLength += ln;
- SecurityBlob->UserName.Length = cpu_to_le16(ln);
- }
-
- /* SecurityBlob->WorkstationName.Length =
- cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
- SecurityBlob->WorkstationName.Length *= 2;
- SecurityBlob->WorkstationName.MaximumLength =
- cpu_to_le16(SecurityBlob->WorkstationName.Length);
- SecurityBlob->WorkstationName.Buffer =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += SecurityBlob->WorkstationName.Length;
- SecurityBlobLength += SecurityBlob->WorkstationName.Length;
- SecurityBlob->WorkstationName.Length =
- cpu_to_le16(SecurityBlob->WorkstationName.Length); */
-
- if ((long) bcc_ptr % 2) {
- *bcc_ptr = 0;
- bcc_ptr++;
- }
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
- 32, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
- nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bcc_ptr += 2; /* null term version string */
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
- 64, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- *(bcc_ptr + 1) = 0;
- *(bcc_ptr + 2) = 0;
- bcc_ptr += 2; /* null terminate network opsys string */
- *(bcc_ptr + 1) = 0;
- *(bcc_ptr + 2) = 0;
- bcc_ptr += 2; /* null domain */
- } else { /* ASCII */
- if (domain == NULL) {
- SecurityBlob->DomainName.Buffer = 0;
- SecurityBlob->DomainName.Length = 0;
- SecurityBlob->DomainName.MaximumLength = 0;
- } else {
- __u16 ln;
- negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
- strncpy(bcc_ptr, domain, 63);
- ln = strnlen(domain, 64);
- SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(ln);
- SecurityBlob->DomainName.Buffer =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += ln;
- SecurityBlobLength += ln;
- SecurityBlob->DomainName.Length = cpu_to_le16(ln);
- }
- if (user == NULL) {
- SecurityBlob->UserName.Buffer = 0;
- SecurityBlob->UserName.Length = 0;
- SecurityBlob->UserName.MaximumLength = 0;
- } else {
- __u16 ln;
- strncpy(bcc_ptr, user, 63);
- ln = strnlen(user, 64);
- SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
- SecurityBlob->UserName.Buffer =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += ln;
- SecurityBlobLength += ln;
- SecurityBlob->UserName.Length = cpu_to_le16(ln);
- }
- /* BB fill in our workstation name if known BB */
-
- strcpy(bcc_ptr, "Linux version ");
- bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, utsname()->release);
- bcc_ptr += strlen(utsname()->release) + 1;
- strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
- bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
- bcc_ptr++; /* null domain */
- *bcc_ptr = 0;
- }
- SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
- pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
- count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
- smb_buffer->smb_buf_length += count;
- pSMB->req.ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
- &bytes_returned, CIFS_LONG_OP);
- if (rc) {
-/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
- } else if ((smb_buffer_response->WordCount == 3) ||
- (smb_buffer_response->WordCount == 4)) {
- __u16 action = le16_to_cpu(pSMBr->resp.Action);
- __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
- if (action & GUEST_LOGIN)
- cFYI(1, ("Guest login")); /* BB Should we set anything
- in SesInfo struct ? */
-/* if (SecurityBlob2->MessageType != NtLm??) {
- cFYI("Unexpected message type on auth response is %d"));
- } */
-
- if (ses) {
- cFYI(1,
- ("Check challenge UID %d vs auth response UID %d",
- ses->Suid, smb_buffer_response->Uid));
- /* UID left in wire format */
- ses->Suid = smb_buffer_response->Uid;
- bcc_ptr = pByteArea(smb_buffer_response);
- /* response can have either 3 or 4 word count - Samba sends 3 */
- if ((pSMBr->resp.hdr.WordCount == 3)
- || ((pSMBr->resp.hdr.WordCount == 4)
- && (blob_len <
- pSMBr->resp.ByteCount))) {
- if (pSMBr->resp.hdr.WordCount == 4) {
- bcc_ptr +=
- blob_len;
- cFYI(1,
- ("Security Blob Length %d ",
- blob_len));
- }
-
- cFYI(1,
- ("NTLMSSP response to Authenticate "));
-
- if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
- if ((long) (bcc_ptr) % 2) {
- remaining_words =
- (BCC(smb_buffer_response)
- - 1) / 2;
- bcc_ptr++; /* Unicode strings must be word aligned */
- } else {
- remaining_words = BCC(smb_buffer_response) / 2;
- }
- len = UniStrnlen((wchar_t *) bcc_ptr,
- remaining_words - 1);
-/* We look for obvious messed up bcc or strings in response so we do not go off
- the end since (at least) WIN2K and Windows XP have a major bug in not null
- terminating last Unicode string in response */
- kfree(ses->serverOS);
- ses->serverOS =
- kzalloc(2 * (len + 1), GFP_KERNEL);
- cifs_strfromUCS_le(ses->serverOS,
- (__le16 *)
- bcc_ptr, len,
- nls_codepage);
- bcc_ptr += 2 * (len + 1);
- remaining_words -= len + 1;
- ses->serverOS[2 * len] = 0;
- ses->serverOS[1 + (2 * len)] = 0;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *)
- bcc_ptr,
- remaining_words
- - 1);
- kfree(ses->serverNOS);
- ses->serverNOS =
- kzalloc(2 * (len + 1),
- GFP_KERNEL);
- cifs_strfromUCS_le(ses->
- serverNOS,
- (__le16 *)
- bcc_ptr,
- len,
- nls_codepage);
- bcc_ptr += 2 * (len + 1);
- ses->serverNOS[2 * len] = 0;
- ses->serverNOS[1+(2*len)] = 0;
- remaining_words -= len + 1;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
- /* last string not always null terminated (e.g. for Windows XP & 2000) */
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2 *
- (len +
- 1),
- GFP_KERNEL);
- cifs_strfromUCS_le
- (ses->
- serverDomain,
- (__le16 *)
- bcc_ptr, len,
- nls_codepage);
- bcc_ptr +=
- 2 * (len + 1);
- ses->
- serverDomain[2
- * len]
- = 0;
- ses->
- serverDomain[1
- +
- (2
- *
- len)]
- = 0;
- } /* else no more room so create dummy domain string */
- else {
- kfree(ses->serverDomain);
- ses->serverDomain = kzalloc(2,GFP_KERNEL);
- }
- } else { /* no room so create dummy domain and NOS string */
- kfree(ses->serverDomain);
- ses->serverDomain = kzalloc(2, GFP_KERNEL);
- kfree(ses->serverNOS);
- ses->serverNOS = kzalloc(2, GFP_KERNEL);
- }
- } else { /* ASCII */
- len = strnlen(bcc_ptr, 1024);
- if (((long) bcc_ptr + len) -
- (long) pByteArea(smb_buffer_response)
- <= BCC(smb_buffer_response)) {
- kfree(ses->serverOS);
- ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
- strncpy(ses->serverOS,bcc_ptr, len);
-
- bcc_ptr += len;
- bcc_ptr[0] = 0; /* null terminate the string */
- bcc_ptr++;
-
- len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverNOS);
- ses->serverNOS = kzalloc(len+1,
- GFP_KERNEL);
- strncpy(ses->serverNOS,
- bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
-
- len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(len+1,
- GFP_KERNEL);
- strncpy(ses->serverDomain,
- bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
- } else
- cFYI(1, ("field of length %d "
- "extends beyond end of smb ",
- len));
- }
- } else {
- cERROR(1, ("Security Blob extends beyond end "
- "of SMB"));
- }
- } else {
- cERROR(1, ("No session structure passed in."));
- }
- } else {
- cERROR(1, ("Invalid Word count %d: ",
- smb_buffer_response->WordCount));
- rc = -EIO;
- }
-
- cifs_buf_release(smb_buffer);
-
- return rc;
-}
-
int
CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
const char *tree, struct cifsTconInfo *tcon,
@@ -3638,7 +2623,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
TCONX_RSP *pSMBr;
unsigned char *bcc_ptr;
int rc = 0;
- int length;
+ int length, bytes_left;
__u16 count;
if (ses == NULL)
@@ -3726,14 +2711,22 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
CIFS_STD_OP);
- /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
/* above now done in SendReceive */
if ((rc == 0) && (tcon != NULL)) {
+ bool is_unicode;
+
tcon->tidStatus = CifsGood;
tcon->need_reconnect = false;
tcon->tid = smb_buffer_response->Tid;
bcc_ptr = pByteArea(smb_buffer_response);
- length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
+ bytes_left = BCC(smb_buffer_response);
+ length = strnlen(bcc_ptr, bytes_left - 2);
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
+ is_unicode = true;
+ else
+ is_unicode = false;
+
+
/* skip service field (NB: this field is always ASCII) */
if (length == 3) {
if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
@@ -3748,39 +2741,16 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
}
}
bcc_ptr += length + 1;
+ bytes_left -= (length + 1);
strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
- if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
- length = UniStrnlen((wchar_t *) bcc_ptr, 512);
- if ((bcc_ptr + (2 * length)) -
- pByteArea(smb_buffer_response) <=
- BCC(smb_buffer_response)) {
- kfree(tcon->nativeFileSystem);
- tcon->nativeFileSystem =
- kzalloc((4 * length) + 2, GFP_KERNEL);
- if (tcon->nativeFileSystem) {
- cifs_strfromUCS_le(
- tcon->nativeFileSystem,
- (__le16 *) bcc_ptr,
- length, nls_codepage);
- cFYI(1, ("nativeFileSystem=%s",
- tcon->nativeFileSystem));
- }
- }
- /* else do not bother copying these information fields*/
- } else {
- length = strnlen(bcc_ptr, 1024);
- if ((bcc_ptr + length) -
- pByteArea(smb_buffer_response) <=
- BCC(smb_buffer_response)) {
- kfree(tcon->nativeFileSystem);
- tcon->nativeFileSystem =
- kzalloc(length + 1, GFP_KERNEL);
- if (tcon->nativeFileSystem)
- strncpy(tcon->nativeFileSystem, bcc_ptr,
- length);
- }
- /* else do not bother copying these information fields*/
- }
+
+ /* mostly informational -- no need to fail on error here */
+ tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
+ bytes_left, is_unicode,
+ nls_codepage);
+
+ cFYI(1, ("nativeFileSystem=%s", tcon->nativeFileSystem));
+
if ((smb_buffer_response->WordCount == 3) ||
(smb_buffer_response->WordCount == 7))
/* field is in same location */
@@ -3819,8 +2789,6 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
struct nls_table *nls_info)
{
int rc = 0;
- char ntlm_session_key[CIFS_SESS_KEY_SIZE];
- bool ntlmv2_flag = false;
int first_time = 0;
struct TCP_Server_Info *server = pSesInfo->server;
@@ -3852,83 +2820,19 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
pSesInfo->capabilities = server->capabilities;
if (linuxExtEnabled == 0)
pSesInfo->capabilities &= (~CAP_UNIX);
- /* pSesInfo->sequence_number = 0;*/
+
cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
server->secMode, server->capabilities, server->timeAdj));
- if (experimEnabled < 2)
- rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
- else if (extended_security
- && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
- && (server->secType == NTLMSSP)) {
- rc = -EOPNOTSUPP;
- } else if (extended_security
- && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
- && (server->secType == RawNTLMSSP)) {
- cFYI(1, ("NTLMSSP sesssetup"));
- rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
- nls_info);
- if (!rc) {
- if (ntlmv2_flag) {
- char *v2_response;
- cFYI(1, ("more secure NTLM ver2 hash"));
- if (CalcNTLMv2_partial_mac_key(pSesInfo,
- nls_info)) {
- rc = -ENOMEM;
- goto ss_err_exit;
- } else
- v2_response = kmalloc(16 + 64 /* blob*/,
- GFP_KERNEL);
- if (v2_response) {
- CalcNTLMv2_response(pSesInfo,
- v2_response);
- /* if (first_time)
- cifs_calculate_ntlmv2_mac_key */
- kfree(v2_response);
- /* BB Put dummy sig in SessSetup PDU? */
- } else {
- rc = -ENOMEM;
- goto ss_err_exit;
- }
-
- } else {
- SMBNTencrypt(pSesInfo->password,
- server->cryptKey,
- ntlm_session_key);
-
- if (first_time)
- cifs_calculate_mac_key(
- &server->mac_signing_key,
- ntlm_session_key,
- pSesInfo->password);
- }
- /* for better security the weaker lanman hash not sent
- in AuthSessSetup so we no longer calculate it */
-
- rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
- ntlm_session_key,
- ntlmv2_flag,
- nls_info);
- }
- } else { /* old style NTLM 0.12 session setup */
- SMBNTencrypt(pSesInfo->password, server->cryptKey,
- ntlm_session_key);
-
- if (first_time)
- cifs_calculate_mac_key(&server->mac_signing_key,
- ntlm_session_key,
- pSesInfo->password);
-
- rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
- }
+ rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
if (rc) {
cERROR(1, ("Send error in SessSetup = %d", rc));
} else {
cFYI(1, ("CIFS Session Established successfully"));
- spin_lock(&GlobalMid_Lock);
- pSesInfo->status = CifsGood;
- pSesInfo->need_reconnect = false;
- spin_unlock(&GlobalMid_Lock);
+ spin_lock(&GlobalMid_Lock);
+ pSesInfo->status = CifsGood;
+ pSesInfo->need_reconnect = false;
+ spin_unlock(&GlobalMid_Lock);
}
ss_err_exit:
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 461750e01364..11431ed72a7f 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -281,6 +281,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
int create_options = CREATE_NOT_DIR;
int oplock = 0;
int oflags;
+ bool posix_create = false;
/*
* BB below access is probably too much for mknod to request
* but we have to do query and setpathinfo so requesting
@@ -328,11 +329,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
negotation. EREMOTE indicates DFS junction, which is not
handled in posix open */
- if ((rc == 0) && (newinode == NULL))
- goto cifs_create_get_file_info; /* query inode info */
- else if (rc == 0) /* success, no need to query */
- goto cifs_create_set_dentry;
- else if ((rc != -EIO) && (rc != -EREMOTE) &&
+ if (rc == 0) {
+ posix_create = true;
+ if (newinode == NULL) /* query inode info */
+ goto cifs_create_get_file_info;
+ else /* success, no need to query */
+ goto cifs_create_set_dentry;
+ } else if ((rc != -EIO) && (rc != -EREMOTE) &&
(rc != -EOPNOTSUPP)) /* path not found or net err */
goto cifs_create_out;
/* else fallthrough to retry, using older open call, this is
@@ -464,7 +467,7 @@ cifs_create_set_dentry:
if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) {
/* mknod case - do not leave file open */
CIFSSMBClose(xid, tcon, fileHandle);
- } else if (newinode) {
+ } else if (!(posix_create) && (newinode)) {
cifs_fill_fileinfo(newinode, fileHandle,
cifs_sb->tcon, write_only);
}
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 50ca088d8860..38c06f826575 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -129,15 +129,12 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode,
struct file *file, struct cifsInodeInfo *pCifsInode,
struct cifsFileInfo *pCifsFile, int oplock, u16 netfid)
{
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
-/* struct timespec temp; */ /* BB REMOVEME BB */
file->private_data = kmalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
if (file->private_data == NULL)
return -ENOMEM;
pCifsFile = cifs_init_private(file->private_data, inode, file, netfid);
write_lock(&GlobalSMBSeslock);
- list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList);
pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
if (pCifsInode == NULL) {
@@ -145,17 +142,6 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode,
return -EINVAL;
}
- /* want handles we can use to read with first
- in the list so we do not have to walk the
- list to search for one in write_begin */
- if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
- list_add_tail(&pCifsFile->flist,
- &pCifsInode->openFileList);
- } else {
- list_add(&pCifsFile->flist,
- &pCifsInode->openFileList);
- }
-
if (pCifsInode->clientCanCacheRead) {
/* we have the inode open somewhere else
no need to discard cache data */
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index f36b4e40e443..9c869a6dcba1 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -962,13 +962,21 @@ undo_setattr:
goto out_close;
}
+
+/*
+ * If dentry->d_inode is null (usually meaning the cached dentry
+ * is a negative dentry) then we would attempt a standard SMB delete, but
+ * if that fails we can not attempt the fall back mechanisms on EACESS
+ * but will return the EACESS to the caller. Note that the VFS does not call
+ * unlink on negative dentries currently.
+ */
int cifs_unlink(struct inode *dir, struct dentry *dentry)
{
int rc = 0;
int xid;
char *full_path = NULL;
struct inode *inode = dentry->d_inode;
- struct cifsInodeInfo *cifsInode = CIFS_I(inode);
+ struct cifsInodeInfo *cifs_inode;
struct super_block *sb = dir->i_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsTconInfo *tcon = cifs_sb->tcon;
@@ -1012,7 +1020,7 @@ psx_del_no_retry:
rc = cifs_rename_pending_delete(full_path, dentry, xid);
if (rc == 0)
drop_nlink(inode);
- } else if (rc == -EACCES && dosattr == 0) {
+ } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
if (attrs == NULL) {
rc = -ENOMEM;
@@ -1020,7 +1028,8 @@ psx_del_no_retry:
}
/* try to reset dos attributes */
- origattr = cifsInode->cifsAttrs;
+ cifs_inode = CIFS_I(inode);
+ origattr = cifs_inode->cifsAttrs;
if (origattr == 0)
origattr |= ATTR_NORMAL;
dosattr = origattr & ~ATTR_READONLY;
@@ -1041,13 +1050,13 @@ psx_del_no_retry:
out_reval:
if (inode) {
- cifsInode = CIFS_I(inode);
- cifsInode->time = 0; /* will force revalidate to get info
+ cifs_inode = CIFS_I(inode);
+ cifs_inode->time = 0; /* will force revalidate to get info
when needed */
inode->i_ctime = current_fs_time(sb);
}
dir->i_ctime = dir->i_mtime = current_fs_time(sb);
- cifsInode = CIFS_I(dir);
+ cifs_inode = CIFS_I(dir);
CIFS_I(dir)->time = 0; /* force revalidate of dir as well */
kfree(full_path);
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 63f644000ce5..ea9d11e3dcbb 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -119,16 +119,11 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
full_path = build_path_from_dentry(direntry);
if (!full_path)
- goto out_no_free;
+ goto out;
cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode));
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
- target_path = kmalloc(PATH_MAX, GFP_KERNEL);
- if (!target_path) {
- target_path = ERR_PTR(-ENOMEM);
- goto out;
- }
/* We could change this to:
if (pTcon->unix_ext)
@@ -138,8 +133,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
if (pTcon->ses->capabilities & CAP_UNIX)
rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
- target_path,
- PATH_MAX-1,
+ &target_path,
cifs_sb->local_nls);
else {
/* BB add read reparse point symlink code here */
@@ -148,22 +142,16 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
/* BB Add MAC style xsymlink check here if enabled */
}
- if (rc == 0) {
-
-/* BB Add special case check for Samba DFS symlinks */
-
- target_path[PATH_MAX-1] = 0;
- } else {
+ if (rc != 0) {
kfree(target_path);
target_path = ERR_PTR(rc);
}
-out:
kfree(full_path);
-out_no_free:
+out:
FreeXid(xid);
nd_set_link(nd, target_path);
- return NULL; /* No cookie */
+ return NULL;
}
int
@@ -224,98 +212,6 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
return rc;
}
-int
-cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
-{
- struct inode *inode = direntry->d_inode;
- int rc = -EACCES;
- int xid;
- int oplock = 0;
- struct cifs_sb_info *cifs_sb;
- struct cifsTconInfo *pTcon;
- char *full_path = NULL;
- char *tmpbuffer;
- int len;
- __u16 fid;
-
- xid = GetXid();
- cifs_sb = CIFS_SB(inode->i_sb);
- pTcon = cifs_sb->tcon;
-
-/* BB would it be safe against deadlock to grab this sem
- even though rename itself grabs the sem and calls lookup? */
-/* mutex_lock(&inode->i_sb->s_vfs_rename_mutex);*/
- full_path = build_path_from_dentry(direntry);
-/* mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);*/
-
- if (full_path == NULL) {
- FreeXid(xid);
- return -ENOMEM;
- }
-
- cFYI(1,
- ("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d",
- full_path, inode, pBuffer, buflen));
- if (buflen > PATH_MAX)
- len = PATH_MAX;
- else
- len = buflen;
- tmpbuffer = kmalloc(len, GFP_KERNEL);
- if (tmpbuffer == NULL) {
- kfree(full_path);
- FreeXid(xid);
- return -ENOMEM;
- }
-
-/* BB add read reparse point symlink code and
- Unix extensions symlink code here BB */
-/* We could disable this based on pTcon->unix_ext flag instead ... but why? */
- if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
- rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
- tmpbuffer,
- len - 1,
- cifs_sb->local_nls);
- else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
- cERROR(1, ("SFU style symlinks not implemented yet"));
- /* add open and read as in fs/cifs/inode.c */
- } else {
- rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
- OPEN_REPARSE_POINT, &fid, &oplock, NULL,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (!rc) {
- rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,
- tmpbuffer,
- len - 1,
- fid,
- cifs_sb->local_nls);
- if (CIFSSMBClose(xid, pTcon, fid)) {
- cFYI(1, ("Error closing junction point "
- "(open for ioctl)"));
- }
- /* If it is a DFS junction earlier we would have gotten
- PATH_NOT_COVERED returned from server so we do
- not need to request the DFS info here */
- }
- }
- /* BB Anything else to do to handle recursive links? */
- /* BB Should we be using page ops here? */
-
- /* BB null terminate returned string in pBuffer? BB */
- if (rc == 0) {
- rc = vfs_readlink(direntry, pBuffer, len, tmpbuffer);
- cFYI(1,
- ("vfs_readlink called from cifs_readlink returned %d",
- rc));
- }
-
- kfree(tmpbuffer);
- kfree(full_path);
- FreeXid(xid);
- return rc;
-}
-
void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
{
char *p = nd_get_link(nd);
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 4c89c572891a..e079a9190ec4 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -635,77 +635,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
return;
}
-/* Windows maps these to the user defined 16 bit Unicode range since they are
- reserved symbols (along with \ and /), otherwise illegal to store
- in filenames in NTFS */
-#define UNI_ASTERIK (__u16) ('*' + 0xF000)
-#define UNI_QUESTION (__u16) ('?' + 0xF000)
-#define UNI_COLON (__u16) (':' + 0xF000)
-#define UNI_GRTRTHAN (__u16) ('>' + 0xF000)
-#define UNI_LESSTHAN (__u16) ('<' + 0xF000)
-#define UNI_PIPE (__u16) ('|' + 0xF000)
-#define UNI_SLASH (__u16) ('\\' + 0xF000)
-
-/* Convert 16 bit Unicode pathname from wire format to string in current code
- page. Conversion may involve remapping up the seven characters that are
- only legal in POSIX-like OS (if they are present in the string). Path
- names are little endian 16 bit Unicode on the wire */
-int
-cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
- const struct nls_table *cp)
-{
- int i, j, len;
- __u16 src_char;
-
- for (i = 0, j = 0; i < maxlen; i++) {
- src_char = le16_to_cpu(source[i]);
- switch (src_char) {
- case 0:
- goto cUCS_out; /* BB check this BB */
- case UNI_COLON:
- target[j] = ':';
- break;
- case UNI_ASTERIK:
- target[j] = '*';
- break;
- case UNI_QUESTION:
- target[j] = '?';
- break;
- /* BB We can not handle remapping slash until
- all the calls to build_path_from_dentry
- are modified, as they use slash as separator BB */
- /* case UNI_SLASH:
- target[j] = '\\';
- break;*/
- case UNI_PIPE:
- target[j] = '|';
- break;
- case UNI_GRTRTHAN:
- target[j] = '>';
- break;
- case UNI_LESSTHAN:
- target[j] = '<';
- break;
- default:
- len = cp->uni2char(src_char, &target[j],
- NLS_MAX_CHARSET_SIZE);
- if (len > 0) {
- j += len;
- continue;
- } else {
- target[j] = '?';
- }
- }
- j++;
- /* make sure we do not overrun callers allocated temp buffer */
- if (j >= (2 * NAME_MAX))
- break;
- }
-cUCS_out:
- target[j] = 0;
- return j;
-}
-
/* Convert 16 bit Unicode pathname to wire format from string in current code
page. Conversion may involve remapping up the seven characters that are
only legal in POSIX-like OS (if they are present in the string). Path
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 8703d68f5b20..e2fe998989a3 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -79,6 +79,7 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
{ErrQuota, -EDQUOT},
{ErrNotALink, -ENOLINK},
{ERRnetlogonNotStarted, -ENOPROTOOPT},
+ {ERRsymlink, -EOPNOTSUPP},
{ErrTooManyLinks, -EMLINK},
{0, 0}
};
@@ -714,6 +715,7 @@ static const struct {
ERRDOS, ERRnoaccess, 0xc000028f}, {
ERRDOS, ERRnoaccess, 0xc0000290}, {
ERRDOS, ERRbadfunc, 0xc000029c}, {
+ ERRDOS, ERRsymlink, NT_STATUS_STOPPED_ON_SYMLINK}, {
ERRDOS, ERRinvlevel, 0x007c0001}, };
/*****************************************************************************
diff --git a/fs/cifs/nterr.h b/fs/cifs/nterr.h
index 588abbb9d08c..257267367d41 100644
--- a/fs/cifs/nterr.h
+++ b/fs/cifs/nterr.h
@@ -35,8 +35,6 @@ struct nt_err_code_struct {
extern const struct nt_err_code_struct nt_errs[];
/* Win32 Status codes. */
-
-#define STATUS_BUFFER_OVERFLOW 0x80000005
#define STATUS_MORE_ENTRIES 0x0105
#define ERROR_INVALID_PARAMETER 0x0057
#define ERROR_INSUFFICIENT_BUFFER 0x007a
@@ -50,6 +48,13 @@ extern const struct nt_err_code_struct nt_errs[];
#define STATUS_SOME_UNMAPPED 0x0107
#define STATUS_BUFFER_OVERFLOW 0x80000005
#define NT_STATUS_NO_MORE_ENTRIES 0x8000001a
+#define NT_STATUS_MEDIA_CHANGED 0x8000001c
+#define NT_STATUS_END_OF_MEDIA 0x8000001e
+#define NT_STATUS_MEDIA_CHECK 0x80000020
+#define NT_STATUS_NO_DATA_DETECTED 0x8000001c
+#define NT_STATUS_STOPPED_ON_SYMLINK 0x8000002d
+#define NT_STATUS_DEVICE_REQUIRES_CLEANING 0x80000288
+#define NT_STATUS_DEVICE_DOOR_OPEN 0x80000288
#define NT_STATUS_UNSUCCESSFUL 0xC0000000 | 0x0001
#define NT_STATUS_NOT_IMPLEMENTED 0xC0000000 | 0x0002
#define NT_STATUS_INVALID_INFO_CLASS 0xC0000000 | 0x0003
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index c377d8065d99..49c9a4e75319 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -27,29 +27,39 @@
#define UnknownMessage cpu_to_le32(8)
/* Negotiate Flags */
-#define NTLMSSP_NEGOTIATE_UNICODE 0x01 /* Text strings are in unicode */
-#define NTLMSSP_NEGOTIATE_OEM 0x02 /* Text strings are in OEM */
-#define NTLMSSP_REQUEST_TARGET 0x04 /* Server return its auth realm */
-#define NTLMSSP_NEGOTIATE_SIGN 0x0010 /* Request signature capability */
-#define NTLMSSP_NEGOTIATE_SEAL 0x0020 /* Request confidentiality */
-#define NTLMSSP_NEGOTIATE_DGRAM 0x0040
-#define NTLMSSP_NEGOTIATE_LM_KEY 0x0080 /* Sign/seal use LM session key */
-#define NTLMSSP_NEGOTIATE_NTLM 0x0200 /* NTLM authentication */
-#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x1000
+#define NTLMSSP_NEGOTIATE_UNICODE 0x01 /* Text strings are unicode */
+#define NTLMSSP_NEGOTIATE_OEM 0x02 /* Text strings are in OEM */
+#define NTLMSSP_REQUEST_TARGET 0x04 /* Srv returns its auth realm */
+/* define reserved9 0x08 */
+#define NTLMSSP_NEGOTIATE_SIGN 0x0010 /* Request signing capability */
+#define NTLMSSP_NEGOTIATE_SEAL 0x0020 /* Request confidentiality */
+#define NTLMSSP_NEGOTIATE_DGRAM 0x0040
+#define NTLMSSP_NEGOTIATE_LM_KEY 0x0080 /* Use LM session key */
+/* defined reserved 8 0x0100 */
+#define NTLMSSP_NEGOTIATE_NTLM 0x0200 /* NTLM authentication */
+#define NTLMSSP_NEGOTIATE_NT_ONLY 0x0400 /* Lanman not allowed */
+#define NTLMSSP_ANONYMOUS 0x0800
+#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x1000 /* reserved6 */
#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x2000
-#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x4000 /* client/server on same machine */
-#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x8000 /* Sign for all security levels */
-#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000
-#define NTLMSSP_TARGET_TYPE_SERVER 0x20000
-#define NTLMSSP_TARGET_TYPE_SHARE 0x40000
-#define NTLMSSP_NEGOTIATE_NTLMV2 0x80000
-#define NTLMSSP_REQUEST_INIT_RESP 0x100000
-#define NTLMSSP_REQUEST_ACCEPT_RESP 0x200000
-#define NTLMSSP_REQUEST_NOT_NT_KEY 0x400000
+#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x4000 /* client/server same machine */
+#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x8000 /* Sign. All security levels */
+#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000
+#define NTLMSSP_TARGET_TYPE_SERVER 0x20000
+#define NTLMSSP_TARGET_TYPE_SHARE 0x40000
+#define NTLMSSP_NEGOTIATE_EXTENDED_SEC 0x80000 /* NB:not related to NTLMv2 pwd*/
+/* #define NTLMSSP_REQUEST_INIT_RESP 0x100000 */
+#define NTLMSSP_NEGOTIATE_IDENTIFY 0x100000
+#define NTLMSSP_REQUEST_ACCEPT_RESP 0x200000 /* reserved5 */
+#define NTLMSSP_REQUEST_NON_NT_KEY 0x400000
#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x800000
-#define NTLMSSP_NEGOTIATE_128 0x20000000
-#define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000
-#define NTLMSSP_NEGOTIATE_56 0x80000000
+/* #define reserved4 0x1000000 */
+#define NTLMSSP_NEGOTIATE_VERSION 0x2000000 /* we do not set */
+/* #define reserved3 0x4000000 */
+/* #define reserved2 0x8000000 */
+/* #define reserved1 0x10000000 */
+#define NTLMSSP_NEGOTIATE_128 0x20000000
+#define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000
+#define NTLMSSP_NEGOTIATE_56 0x80000000
/* Although typedefs are not commonly used for structure definitions */
/* in the Linux kernel, in this particular case they are useful */
@@ -60,32 +70,36 @@
typedef struct _SECURITY_BUFFER {
__le16 Length;
__le16 MaximumLength;
- __le32 Buffer; /* offset to buffer */
+ __le32 BufferOffset; /* offset to buffer */
} __attribute__((packed)) SECURITY_BUFFER;
typedef struct _NEGOTIATE_MESSAGE {
__u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
- __le32 MessageType; /* 1 */
+ __le32 MessageType; /* NtLmNegotiate = 1 */
__le32 NegotiateFlags;
SECURITY_BUFFER DomainName; /* RFC 1001 style and ASCII */
SECURITY_BUFFER WorkstationName; /* RFC 1001 and ASCII */
+ /* SECURITY_BUFFER for version info not present since we
+ do not set the version is present flag */
char DomainString[0];
/* followed by WorkstationString */
} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
typedef struct _CHALLENGE_MESSAGE {
__u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
- __le32 MessageType; /* 2 */
+ __le32 MessageType; /* NtLmChallenge = 2 */
SECURITY_BUFFER TargetName;
__le32 NegotiateFlags;
__u8 Challenge[CIFS_CRYPTO_KEY_SIZE];
__u8 Reserved[8];
SECURITY_BUFFER TargetInfoArray;
+ /* SECURITY_BUFFER for version info not present since we
+ do not set the version is present flag */
} __attribute__((packed)) CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
typedef struct _AUTHENTICATE_MESSAGE {
- __u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
- __le32 MessageType; /* 3 */
+ __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
+ __le32 MessageType; /* NtLmsAuthenticate = 3 */
SECURITY_BUFFER LmChallengeResponse;
SECURITY_BUFFER NtChallengeResponse;
SECURITY_BUFFER DomainName;
@@ -93,5 +107,7 @@ typedef struct _AUTHENTICATE_MESSAGE {
SECURITY_BUFFER WorkstationName;
SECURITY_BUFFER SessionKey;
__le32 NegotiateFlags;
+ /* SECURITY_BUFFER for version info not present since we
+ do not set the version is present flag */
char UserString[0];
} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 1a8be6228333..964e097c8203 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -31,6 +31,13 @@
#include "cifs_fs_sb.h"
#include "cifsfs.h"
+/*
+ * To be safe - for UCS to UTF-8 with strings loaded with the rare long
+ * characters alloc more to account for such multibyte target UTF-8
+ * characters.
+ */
+#define UNICODE_NAME_MAX ((4 * NAME_MAX) + 2)
+
#ifdef CONFIG_CIFS_DEBUG2
static void dump_cifs_file_struct(struct file *file, char *label)
{
@@ -438,6 +445,38 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
}
}
+/* BB eventually need to add the following helper function to
+ resolve NT_STATUS_STOPPED_ON_SYMLINK return code when
+ we try to do FindFirst on (NTFS) directory symlinks */
+/*
+int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
+ int xid)
+{
+ __u16 fid;
+ int len;
+ int oplock = 0;
+ int rc;
+ struct cifsTconInfo *ptcon = cifs_sb->tcon;
+ char *tmpbuffer;
+
+ rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ,
+ OPEN_REPARSE_POINT, &fid, &oplock, NULL,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (!rc) {
+ tmpbuffer = kmalloc(maxpath);
+ rc = CIFSSMBQueryReparseLinkInfo(xid, ptcon, full_path,
+ tmpbuffer,
+ maxpath -1,
+ fid,
+ cifs_sb->local_nls);
+ if (CIFSSMBClose(xid, ptcon, fid)) {
+ cFYI(1, ("Error closing temporary reparsepoint open)"));
+ }
+ }
+}
+ */
+
static int initiate_cifs_search(const int xid, struct file *file)
{
int rc = 0;
@@ -493,7 +532,10 @@ ffirst_retry:
CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
if (rc == 0)
cifsFile->invalidHandle = false;
- if ((rc == -EOPNOTSUPP) &&
+ /* BB add following call to handle readdir on new NTFS symlink errors
+ else if STATUS_STOPPED_ON_SYMLINK
+ call get_symlink_reparse_path and retry with new path */
+ else if ((rc == -EOPNOTSUPP) &&
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
goto ffirst_retry;
@@ -822,7 +864,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
/* inode num, inode type and filename returned */
static int cifs_get_name_from_search_buf(struct qstr *pqst,
char *current_entry, __u16 level, unsigned int unicode,
- struct cifs_sb_info *cifs_sb, int max_len, __u64 *pinum)
+ struct cifs_sb_info *cifs_sb, unsigned int max_len, __u64 *pinum)
{
int rc = 0;
unsigned int len = 0;
@@ -881,14 +923,12 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
}
if (unicode) {
- /* BB fixme - test with long names */
- /* Note converted filename can be longer than in unicode */
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
- pqst->len = cifs_convertUCSpath((char *)pqst->name,
- (__le16 *)filename, len/2, nlt);
- else
- pqst->len = cifs_strfromUCS_le((char *)pqst->name,
- (__le16 *)filename, len/2, nlt);
+ pqst->len = cifs_from_ucs2((char *) pqst->name,
+ (__le16 *) filename,
+ UNICODE_NAME_MAX,
+ min(len, max_len), nlt,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
} else {
pqst->name = filename;
pqst->len = len;
@@ -898,8 +938,8 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
return rc;
}
-static int cifs_filldir(char *pfindEntry, struct file *file,
- filldir_t filldir, void *direntry, char *scratch_buf, int max_len)
+static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
+ void *direntry, char *scratch_buf, unsigned int max_len)
{
int rc = 0;
struct qstr qstring;
@@ -996,7 +1036,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
int num_to_fill = 0;
char *tmp_buf = NULL;
char *end_of_smb;
- int max_len;
+ unsigned int max_len;
xid = GetXid();
@@ -1070,11 +1110,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
cifsFile->srch_inf.ntwrk_buf_start);
end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
- /* To be safe - for UCS to UTF-8 with strings loaded
- with the rare long characters alloc more to account for
- such multibyte target UTF-8 characters. cifs_unicode.c,
- which actually does the conversion, has the same limit */
- tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL);
+ tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
if (current_entry == NULL) {
/* evaluate whether this case is an error */
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index c652c73760dd..897a052270f9 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -3,7 +3,7 @@
*
* SMB/CIFS session setup handling routines
*
- * Copyright (c) International Business Machines Corp., 2006, 2007
+ * Copyright (c) International Business Machines Corp., 2006, 2009
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -111,7 +111,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
get_vc_num_exit:
write_unlock(&cifs_tcp_ses_lock);
- return le16_to_cpu(vcnum);
+ return cpu_to_le16(vcnum);
}
static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
@@ -277,12 +277,11 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
*pbcc_area = bcc_ptr;
}
-static int decode_unicode_ssetup(char **pbcc_area, int bleft,
- struct cifsSesInfo *ses,
- const struct nls_table *nls_cp)
+static void
+decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
+ const struct nls_table *nls_cp)
{
- int rc = 0;
- int words_left, len;
+ int len;
char *data = *pbcc_area;
cFYI(1, ("bleft %d", bleft));
@@ -300,63 +299,29 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
++bleft;
}
- words_left = bleft / 2;
-
- /* save off server operating system */
- len = UniStrnlen((wchar_t *) data, words_left);
-
- if (len >= words_left)
- return rc;
-
kfree(ses->serverOS);
- /* UTF-8 string will not grow more than four times as big as UCS-16 */
- ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL);
- if (ses->serverOS != NULL) {
- cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
- cFYI(1, ("serverOS=%s", ses->serverOS));
- }
- data += 2 * (len + 1);
- words_left -= len + 1;
-
- /* save off server network operating system */
- len = UniStrnlen((wchar_t *) data, words_left);
-
- if (len >= words_left)
- return rc;
+ ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
+ cFYI(1, ("serverOS=%s", ses->serverOS));
+ len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
+ data += len;
+ bleft -= len;
+ if (bleft <= 0)
+ return;
kfree(ses->serverNOS);
- ses->serverNOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL);
- if (ses->serverNOS != NULL) {
- cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
- nls_cp);
- cFYI(1, ("serverNOS=%s", ses->serverNOS));
- if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
- cFYI(1, ("NT4 server"));
- ses->flags |= CIFS_SES_NT4;
- }
- }
- data += 2 * (len + 1);
- words_left -= len + 1;
-
- /* save off server domain */
- len = UniStrnlen((wchar_t *) data, words_left);
-
- if (len > words_left)
- return rc;
+ ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
+ cFYI(1, ("serverNOS=%s", ses->serverNOS));
+ len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
+ data += len;
+ bleft -= len;
+ if (bleft <= 0)
+ return;
kfree(ses->serverDomain);
- ses->serverDomain = kzalloc((4 * len) + 2, GFP_KERNEL);
- if (ses->serverDomain != NULL) {
- cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
- nls_cp);
- cFYI(1, ("serverDomain=%s", ses->serverDomain));
- }
- data += 2 * (len + 1);
- words_left -= len + 1;
-
- cFYI(1, ("words left: %d", words_left));
+ ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
+ cFYI(1, ("serverDomain=%s", ses->serverDomain));
- return rc;
+ return;
}
static int decode_ascii_ssetup(char **pbcc_area, int bleft,
@@ -413,6 +378,186 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
return rc;
}
+static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
+ struct cifsSesInfo *ses)
+{
+ CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
+
+ if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
+ cERROR(1, ("challenge blob len %d too small", blob_len));
+ return -EINVAL;
+ }
+
+ if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
+ cERROR(1, ("blob signature incorrect %s", pblob->Signature));
+ return -EINVAL;
+ }
+ if (pblob->MessageType != NtLmChallenge) {
+ cERROR(1, ("Incorrect message type %d", pblob->MessageType));
+ return -EINVAL;
+ }
+
+ memcpy(ses->server->cryptKey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
+ /* BB we could decode pblob->NegotiateFlags; some may be useful */
+ /* In particular we can examine sign flags */
+ /* BB spec says that if AvId field of MsvAvTimestamp is populated then
+ we must set the MIC field of the AUTHENTICATE_MESSAGE */
+
+ return 0;
+}
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+/* BB Move to ntlmssp.c eventually */
+
+/* We do not malloc the blob, it is passed in pbuffer, because
+ it is fixed size, and small, making this approach cleaner */
+static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
+ struct cifsSesInfo *ses)
+{
+ NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
+ __u32 flags;
+
+ memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
+ sec_blob->MessageType = NtLmNegotiate;
+
+ /* BB is NTLMV2 session security format easier to use here? */
+ flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
+ NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
+ NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;
+ if (ses->server->secMode &
+ (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+ flags |= NTLMSSP_NEGOTIATE_SIGN;
+ if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
+ flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+
+ sec_blob->NegotiateFlags |= cpu_to_le32(flags);
+
+ sec_blob->WorkstationName.BufferOffset = 0;
+ sec_blob->WorkstationName.Length = 0;
+ sec_blob->WorkstationName.MaximumLength = 0;
+
+ /* Domain name is sent on the Challenge not Negotiate NTLMSSP request */
+ sec_blob->DomainName.BufferOffset = 0;
+ sec_blob->DomainName.Length = 0;
+ sec_blob->DomainName.MaximumLength = 0;
+}
+
+/* We do not malloc the blob, it is passed in pbuffer, because its
+ maximum possible size is fixed and small, making this approach cleaner.
+ This function returns the length of the data in the blob */
+static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
+ struct cifsSesInfo *ses,
+ const struct nls_table *nls_cp, int first)
+{
+ AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
+ __u32 flags;
+ unsigned char *tmp;
+ char ntlm_session_key[CIFS_SESS_KEY_SIZE];
+
+ memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
+ sec_blob->MessageType = NtLmAuthenticate;
+
+ flags = NTLMSSP_NEGOTIATE_56 |
+ NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
+ NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
+ NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;
+ if (ses->server->secMode &
+ (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+ flags |= NTLMSSP_NEGOTIATE_SIGN;
+ if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
+ flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+
+ tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
+ sec_blob->NegotiateFlags |= cpu_to_le32(flags);
+
+ sec_blob->LmChallengeResponse.BufferOffset =
+ cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
+ sec_blob->LmChallengeResponse.Length = 0;
+ sec_blob->LmChallengeResponse.MaximumLength = 0;
+
+ /* calculate session key, BB what about adding similar ntlmv2 path? */
+ SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key);
+ if (first)
+ cifs_calculate_mac_key(&ses->server->mac_signing_key,
+ ntlm_session_key, ses->password);
+
+ memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE);
+ sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
+ sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE);
+ sec_blob->NtChallengeResponse.MaximumLength =
+ cpu_to_le16(CIFS_SESS_KEY_SIZE);
+
+ tmp += CIFS_SESS_KEY_SIZE;
+
+ if (ses->domainName == NULL) {
+ sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+ sec_blob->DomainName.Length = 0;
+ sec_blob->DomainName.MaximumLength = 0;
+ tmp += 2;
+ } else {
+ int len;
+ len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
+ MAX_USERNAME_SIZE, nls_cp);
+ len *= 2; /* unicode is 2 bytes each */
+ len += 2; /* trailing null */
+ sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+ sec_blob->DomainName.Length = cpu_to_le16(len);
+ sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
+ tmp += len;
+ }
+
+ if (ses->userName == NULL) {
+ sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+ sec_blob->UserName.Length = 0;
+ sec_blob->UserName.MaximumLength = 0;
+ tmp += 2;
+ } else {
+ int len;
+ len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
+ MAX_USERNAME_SIZE, nls_cp);
+ len *= 2; /* unicode is 2 bytes each */
+ len += 2; /* trailing null */
+ sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+ sec_blob->UserName.Length = cpu_to_le16(len);
+ sec_blob->UserName.MaximumLength = cpu_to_le16(len);
+ tmp += len;
+ }
+
+ sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+ sec_blob->WorkstationName.Length = 0;
+ sec_blob->WorkstationName.MaximumLength = 0;
+ tmp += 2;
+
+ sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
+ sec_blob->SessionKey.Length = 0;
+ sec_blob->SessionKey.MaximumLength = 0;
+ return tmp - pbuffer;
+}
+
+
+static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
+ struct cifsSesInfo *ses)
+{
+ build_ntlmssp_negotiate_blob(&pSMB->req.SecurityBlob[0], ses);
+ pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
+
+ return;
+}
+
+static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
+ struct cifsSesInfo *ses,
+ const struct nls_table *nls, int first_time)
+{
+ int bloblen;
+
+ bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls,
+ first_time);
+ pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen);
+
+ return bloblen;
+}
+#endif
+
int
CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
const struct nls_table *nls_cp)
@@ -431,6 +576,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
__u16 action;
int bytes_remaining;
struct key *spnego_key = NULL;
+ __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
if (ses == NULL)
return -EINVAL;
@@ -438,6 +584,10 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
type = ses->server->secType;
cFYI(1, ("sess setup type %d", type));
+ssetup_ntlmssp_authenticate:
+ if (phase == NtLmChallenge)
+ phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
+
if (type == LANMAN) {
#ifndef CONFIG_CIFS_WEAK_PW_HASH
/* LANMAN and plaintext are less secure and off by default.
@@ -651,9 +801,53 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
goto ssetup_exit;
#endif /* CONFIG_CIFS_UPCALL */
} else {
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ if ((experimEnabled > 1) && (type == RawNTLMSSP)) {
+ if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
+ cERROR(1, ("NTLMSSP requires Unicode support"));
+ rc = -ENOSYS;
+ goto ssetup_exit;
+ }
+
+ cFYI(1, ("ntlmssp session setup phase %d", phase));
+ pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
+ capabilities |= CAP_EXTENDED_SECURITY;
+ pSMB->req.Capabilities |= cpu_to_le32(capabilities);
+ if (phase == NtLmNegotiate) {
+ setup_ntlmssp_neg_req(pSMB, ses);
+ iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
+ } else if (phase == NtLmAuthenticate) {
+ int blob_len;
+ blob_len = setup_ntlmssp_auth_req(pSMB, ses,
+ nls_cp,
+ first_time);
+ iov[1].iov_len = blob_len;
+ /* Make sure that we tell the server that we
+ are using the uid that it just gave us back
+ on the response (challenge) */
+ smb_buf->Uid = ses->Suid;
+ } else {
+ cERROR(1, ("invalid phase %d", phase));
+ rc = -ENOSYS;
+ goto ssetup_exit;
+ }
+ iov[1].iov_base = &pSMB->req.SecurityBlob[0];
+ /* unicode strings must be word aligned */
+ if ((iov[0].iov_len + iov[1].iov_len) % 2) {
+ *bcc_ptr = 0;
+ bcc_ptr++;
+ }
+ unicode_oslm_strings(&bcc_ptr, nls_cp);
+ } else {
+ cERROR(1, ("secType %d not supported!", type));
+ rc = -ENOSYS;
+ goto ssetup_exit;
+ }
+#else
cERROR(1, ("secType %d not supported!", type));
rc = -ENOSYS;
goto ssetup_exit;
+#endif
}
iov[2].iov_base = str_area;
@@ -669,12 +863,23 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
/* SMB request buf freed in SendReceive2 */
cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
- if (rc)
- goto ssetup_exit;
pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
smb_buf = (struct smb_hdr *)iov[0].iov_base;
+ if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError ==
+ cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {
+ if (phase != NtLmNegotiate) {
+ cERROR(1, ("Unexpected more processing error"));
+ goto ssetup_exit;
+ }
+ /* NTLMSSP Negotiate sent now processing challenge (response) */
+ phase = NtLmChallenge; /* process ntlmssp challenge */
+ rc = 0; /* MORE_PROC rc is not an error here, but expected */
+ }
+ if (rc)
+ goto ssetup_exit;
+
if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
rc = -EIO;
cERROR(1, ("bad word count %d", smb_buf->WordCount));
@@ -693,12 +898,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
if (smb_buf->WordCount == 4) {
__u16 blob_len;
blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
- bcc_ptr += blob_len;
if (blob_len > bytes_remaining) {
cERROR(1, ("bad security blob length %d", blob_len));
rc = -EINVAL;
goto ssetup_exit;
}
+ if (phase == NtLmChallenge) {
+ rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
+ /* now goto beginning for ntlmssp authenticate phase */
+ if (rc)
+ goto ssetup_exit;
+ }
+ bcc_ptr += blob_len;
bytes_remaining -= blob_len;
}
@@ -709,8 +920,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
++bcc_ptr;
--bytes_remaining;
}
- rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
- ses, nls_cp);
+ decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp);
} else {
rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
ses, nls_cp);
@@ -728,5 +938,9 @@ ssetup_exit:
} else if (resp_buf_type == CIFS_LARGE_BUFFER)
cifs_buf_release(iov[0].iov_base);
+ /* if ntlmssp, and negotiate succeeded, proceed to authenticate phase */
+ if ((phase == NtLmChallenge) && (rc == 0))
+ goto ssetup_ntlmssp_authenticate;
+
return rc;
}
diff --git a/fs/cifs/smberr.h b/fs/cifs/smberr.h
index 7f50e8577c1c..c5084d27db7c 100644
--- a/fs/cifs/smberr.h
+++ b/fs/cifs/smberr.h
@@ -110,6 +110,7 @@
/* Below errors are used internally (do not come over the wire) for passthrough
from STATUS codes to POSIX only */
+#define ERRsymlink 0xFFFD
#define ErrTooManyLinks 0xFFFE
/* Following error codes may be generated with the ERRSRV error class.*/
diff --git a/fs/coda/file.c b/fs/coda/file.c
index 6a347fbc998a..ffd42815fda1 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -47,6 +47,8 @@ coda_file_splice_read(struct file *coda_file, loff_t *ppos,
struct pipe_inode_info *pipe, size_t count,
unsigned int flags)
{
+ ssize_t (*splice_read)(struct file *, loff_t *,
+ struct pipe_inode_info *, size_t, unsigned int);
struct coda_file_info *cfi;
struct file *host_file;
@@ -54,10 +56,11 @@ coda_file_splice_read(struct file *coda_file, loff_t *ppos,
BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
host_file = cfi->cfi_container;
- if (!host_file->f_op || !host_file->f_op->splice_read)
- return -EINVAL;
+ splice_read = host_file->f_op->splice_read;
+ if (!splice_read)
+ splice_read = default_file_splice_read;
- return host_file->f_op->splice_read(host_file, ppos, pipe, count,flags);
+ return splice_read(host_file, ppos, pipe, count, flags);
}
static ssize_t
diff --git a/fs/compat.c b/fs/compat.c
index bc45864e2e20..cdd51a3a7c53 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -812,10 +812,8 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
}
}
- lock_kernel();
retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
flags, (void*)data_page);
- unlock_kernel();
out4:
free_page(data_page);
@@ -1488,7 +1486,7 @@ int compat_do_execve(char * filename,
if (!bprm)
goto out_files;
- retval = mutex_lock_interruptible(&current->cred_exec_mutex);
+ retval = mutex_lock_interruptible(&current->cred_guard_mutex);
if (retval < 0)
goto out_free;
current->in_execve = 1;
@@ -1550,7 +1548,7 @@ int compat_do_execve(char * filename,
/* execve succeeded */
current->fs->in_exec = 0;
current->in_execve = 0;
- mutex_unlock(&current->cred_exec_mutex);
+ mutex_unlock(&current->cred_guard_mutex);
acct_update_integrals(current);
free_bprm(bprm);
if (displaced)
@@ -1573,7 +1571,7 @@ out_unmark:
out_unlock:
current->in_execve = 0;
- mutex_unlock(&current->cred_exec_mutex);
+ mutex_unlock(&current->cred_guard_mutex);
out_free:
free_bprm(bprm);
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h
index 762d287123ca..da6061a6df40 100644
--- a/fs/configfs/configfs_internal.h
+++ b/fs/configfs/configfs_internal.h
@@ -39,6 +39,9 @@ struct configfs_dirent {
umode_t s_mode;
struct dentry * s_dentry;
struct iattr * s_iattr;
+#ifdef CONFIG_LOCKDEP
+ int s_depth;
+#endif
};
#define CONFIGFS_ROOT 0x0001
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 05373db21a4e..63d88156db15 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -78,6 +78,92 @@ static const struct dentry_operations configfs_dentry_ops = {
.d_delete = configfs_d_delete,
};
+#ifdef CONFIG_LOCKDEP
+
+/*
+ * Helpers to make lockdep happy with our recursive locking of default groups'
+ * inodes (see configfs_attach_group() and configfs_detach_group()).
+ * We put default groups i_mutexes in separate classes according to their depth
+ * from the youngest non-default group ancestor.
+ *
+ * For a non-default group A having default groups A/B, A/C, and A/C/D, default
+ * groups A/B and A/C will have their inode's mutex in class
+ * default_group_class[0], and default group A/C/D will be in
+ * default_group_class[1].
+ *
+ * The lock classes are declared and assigned in inode.c, according to the
+ * s_depth value.
+ * The s_depth value is initialized to -1, adjusted to >= 0 when attaching
+ * default groups, and reset to -1 when all default groups are attached. During
+ * attachment, if configfs_create() sees s_depth > 0, the lock class of the new
+ * inode's mutex is set to default_group_class[s_depth - 1].
+ */
+
+static void configfs_init_dirent_depth(struct configfs_dirent *sd)
+{
+ sd->s_depth = -1;
+}
+
+static void configfs_set_dir_dirent_depth(struct configfs_dirent *parent_sd,
+ struct configfs_dirent *sd)
+{
+ int parent_depth = parent_sd->s_depth;
+
+ if (parent_depth >= 0)
+ sd->s_depth = parent_depth + 1;
+}
+
+static void
+configfs_adjust_dir_dirent_depth_before_populate(struct configfs_dirent *sd)
+{
+ /*
+ * item's i_mutex class is already setup, so s_depth is now only
+ * used to set new sub-directories s_depth, which is always done
+ * with item's i_mutex locked.
+ */
+ /*
+ * sd->s_depth == -1 iff we are a non default group.
+ * else (we are a default group) sd->s_depth > 0 (see
+ * create_dir()).
+ */
+ if (sd->s_depth == -1)
+ /*
+ * We are a non default group and we are going to create
+ * default groups.
+ */
+ sd->s_depth = 0;
+}
+
+static void
+configfs_adjust_dir_dirent_depth_after_populate(struct configfs_dirent *sd)
+{
+ /* We will not create default groups anymore. */
+ sd->s_depth = -1;
+}
+
+#else /* CONFIG_LOCKDEP */
+
+static void configfs_init_dirent_depth(struct configfs_dirent *sd)
+{
+}
+
+static void configfs_set_dir_dirent_depth(struct configfs_dirent *parent_sd,
+ struct configfs_dirent *sd)
+{
+}
+
+static void
+configfs_adjust_dir_dirent_depth_before_populate(struct configfs_dirent *sd)
+{
+}
+
+static void
+configfs_adjust_dir_dirent_depth_after_populate(struct configfs_dirent *sd)
+{
+}
+
+#endif /* CONFIG_LOCKDEP */
+
/*
* Allocates a new configfs_dirent and links it to the parent configfs_dirent
*/
@@ -94,6 +180,7 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare
INIT_LIST_HEAD(&sd->s_links);
INIT_LIST_HEAD(&sd->s_children);
sd->s_element = element;
+ configfs_init_dirent_depth(sd);
spin_lock(&configfs_dirent_lock);
if (parent_sd->s_type & CONFIGFS_USET_DROPPING) {
spin_unlock(&configfs_dirent_lock);
@@ -142,9 +229,15 @@ int configfs_make_dirent(struct configfs_dirent * parent_sd,
if (IS_ERR(sd))
return PTR_ERR(sd);
+ /*
+ * We need configfs_dirent_lock so that configfs_depend_prep()
+ * can see s_type accurately on other CPUs.
+ */
+ spin_lock(&configfs_dirent_lock);
sd->s_mode = mode;
sd->s_type = type;
sd->s_dentry = dentry;
+ spin_unlock(&configfs_dirent_lock);
if (dentry) {
dentry->d_fsdata = configfs_get(sd);
dentry->d_op = &configfs_dentry_ops;
@@ -187,6 +280,7 @@ static int create_dir(struct config_item * k, struct dentry * p,
error = configfs_make_dirent(p->d_fsdata, d, k, mode,
CONFIGFS_DIR | CONFIGFS_USET_CREATING);
if (!error) {
+ configfs_set_dir_dirent_depth(p->d_fsdata, d->d_fsdata);
error = configfs_create(d, mode, init_dir);
if (!error) {
inc_nlink(p->d_inode);
@@ -789,11 +883,13 @@ static int configfs_attach_group(struct config_item *parent_item,
* error, as rmdir() would.
*/
mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD);
+ configfs_adjust_dir_dirent_depth_before_populate(sd);
ret = populate_groups(to_config_group(item));
if (ret) {
configfs_detach_item(item);
dentry->d_inode->i_flags |= S_DEAD;
}
+ configfs_adjust_dir_dirent_depth_after_populate(sd);
mutex_unlock(&dentry->d_inode->i_mutex);
if (ret)
d_delete(dentry);
@@ -916,11 +1012,11 @@ static int configfs_dump(struct configfs_dirent *sd, int level)
* Note, btw, that this can be called at *any* time, even when a configfs
* subsystem isn't registered, or when configfs is loading or unloading.
* Just like configfs_register_subsystem(). So we take the same
- * precautions. We pin the filesystem. We lock each i_mutex _in_order_
- * on our way down the tree. If we can find the target item in the
+ * precautions. We pin the filesystem. We lock configfs_dirent_lock.
+ * If we can find the target item in the
* configfs tree, it must be part of the subsystem tree as well, so we
- * do not need the subsystem semaphore. Holding the i_mutex chain locks
- * out mkdir() and rmdir(), who might be racing us.
+ * do not need the subsystem semaphore. Holding configfs_dirent_lock helps
+ * locking out mkdir() and rmdir(), who might be racing us.
*/
/*
@@ -933,17 +1029,22 @@ static int configfs_dump(struct configfs_dirent *sd, int level)
* do that so we can unlock it if we find nothing.
*
* Here we do a depth-first search of the dentry hierarchy looking for
- * our object. We take i_mutex on each step of the way down. IT IS
- * ESSENTIAL THAT i_mutex LOCKING IS ORDERED. If we come back up a branch,
- * we'll drop the i_mutex.
+ * our object.
+ * We deliberately ignore items tagged as dropping since they are virtually
+ * dead, as well as items in the middle of attachment since they virtually
+ * do not exist yet. This completes the locking out of racing mkdir() and
+ * rmdir().
+ * Note: items in the middle of attachment start with s_type = 0
+ * (configfs_new_dirent()), and configfs_make_dirent() (called from
+ * create_dir()) sets s_type = CONFIGFS_DIR|CONFIGFS_USET_CREATING. In both
+ * cases the item is ignored. configfs_make_dirent() is locked out from
+ * updating s_type by configfs_dirent_lock.
*
- * If the target is not found, -ENOENT is bubbled up and we have released
- * all locks. If the target was found, the locks will be cleared by
- * configfs_depend_rollback().
+ * If the target is not found, -ENOENT is bubbled up.
*
* This adds a requirement that all config_items be unique!
*
- * This is recursive because the locking traversal is tricky. There isn't
+ * This is recursive. There isn't
* much on the stack, though, so folks that need this function - be careful
* about your stack! Patches will be accepted to make it iterative.
*/
@@ -955,13 +1056,13 @@ static int configfs_depend_prep(struct dentry *origin,
BUG_ON(!origin || !sd);
- /* Lock this guy on the way down */
- mutex_lock(&sd->s_dentry->d_inode->i_mutex);
if (sd->s_element == target) /* Boo-yah */
goto out;
list_for_each_entry(child_sd, &sd->s_children, s_sibling) {
- if (child_sd->s_type & CONFIGFS_DIR) {
+ if ((child_sd->s_type & CONFIGFS_DIR) &&
+ !(child_sd->s_type & CONFIGFS_USET_DROPPING) &&
+ !(child_sd->s_type & CONFIGFS_USET_CREATING)) {
ret = configfs_depend_prep(child_sd->s_dentry,
target);
if (!ret)
@@ -970,33 +1071,12 @@ static int configfs_depend_prep(struct dentry *origin,
}
/* We looped all our children and didn't find target */
- mutex_unlock(&sd->s_dentry->d_inode->i_mutex);
ret = -ENOENT;
out:
return ret;
}
-/*
- * This is ONLY called if configfs_depend_prep() did its job. So we can
- * trust the entire path from item back up to origin.
- *
- * We walk backwards from item, unlocking each i_mutex. We finish by
- * unlocking origin.
- */
-static void configfs_depend_rollback(struct dentry *origin,
- struct config_item *item)
-{
- struct dentry *dentry = item->ci_dentry;
-
- while (dentry != origin) {
- mutex_unlock(&dentry->d_inode->i_mutex);
- dentry = dentry->d_parent;
- }
-
- mutex_unlock(&origin->d_inode->i_mutex);
-}
-
int configfs_depend_item(struct configfs_subsystem *subsys,
struct config_item *target)
{
@@ -1037,17 +1117,21 @@ int configfs_depend_item(struct configfs_subsystem *subsys,
/* Ok, now we can trust subsys/s_item */
- /* Scan the tree, locking i_mutex recursively, return 0 if found */
+ spin_lock(&configfs_dirent_lock);
+ /* Scan the tree, return 0 if found */
ret = configfs_depend_prep(subsys_sd->s_dentry, target);
if (ret)
- goto out_unlock_fs;
+ goto out_unlock_dirent_lock;
- /* We hold all i_mutexes from the subsystem down to the target */
+ /*
+ * We are sure that the item is not about to be removed by rmdir(), and
+ * not in the middle of attachment by mkdir().
+ */
p = target->ci_dentry->d_fsdata;
p->s_dependent_count += 1;
- configfs_depend_rollback(subsys_sd->s_dentry, target);
-
+out_unlock_dirent_lock:
+ spin_unlock(&configfs_dirent_lock);
out_unlock_fs:
mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex);
@@ -1072,10 +1156,10 @@ void configfs_undepend_item(struct configfs_subsystem *subsys,
struct configfs_dirent *sd;
/*
- * Since we can trust everything is pinned, we just need i_mutex
- * on the item.
+ * Since we can trust everything is pinned, we just need
+ * configfs_dirent_lock.
*/
- mutex_lock(&target->ci_dentry->d_inode->i_mutex);
+ spin_lock(&configfs_dirent_lock);
sd = target->ci_dentry->d_fsdata;
BUG_ON(sd->s_dependent_count < 1);
@@ -1086,7 +1170,7 @@ void configfs_undepend_item(struct configfs_subsystem *subsys,
* After this unlock, we cannot trust the item to stay alive!
* DO NOT REFERENCE item after this unlock.
*/
- mutex_unlock(&target->ci_dentry->d_inode->i_mutex);
+ spin_unlock(&configfs_dirent_lock);
}
EXPORT_SYMBOL(configfs_undepend_item);
@@ -1286,13 +1370,6 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
if (sd->s_type & CONFIGFS_USET_DEFAULT)
return -EPERM;
- /*
- * Here's where we check for dependents. We're protected by
- * i_mutex.
- */
- if (sd->s_dependent_count)
- return -EBUSY;
-
/* Get a working ref until we have the child */
parent_item = configfs_get_config_item(dentry->d_parent);
subsys = to_config_group(parent_item)->cg_subsys;
@@ -1316,9 +1393,17 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
mutex_lock(&configfs_symlink_mutex);
spin_lock(&configfs_dirent_lock);
- ret = configfs_detach_prep(dentry, &wait_mutex);
- if (ret)
- configfs_detach_rollback(dentry);
+ /*
+ * Here's where we check for dependents. We're protected by
+ * configfs_dirent_lock.
+ * If no dependent, atomically tag the item as dropping.
+ */
+ ret = sd->s_dependent_count ? -EBUSY : 0;
+ if (!ret) {
+ ret = configfs_detach_prep(dentry, &wait_mutex);
+ if (ret)
+ configfs_detach_rollback(dentry);
+ }
spin_unlock(&configfs_dirent_lock);
mutex_unlock(&configfs_symlink_mutex);
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index 5d349d38e056..4921e7426d95 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -33,10 +33,15 @@
#include <linux/backing-dev.h>
#include <linux/capability.h>
#include <linux/sched.h>
+#include <linux/lockdep.h>
#include <linux/configfs.h>
#include "configfs_internal.h"
+#ifdef CONFIG_LOCKDEP
+static struct lock_class_key default_group_class[MAX_LOCK_DEPTH];
+#endif
+
extern struct super_block * configfs_sb;
static const struct address_space_operations configfs_aops = {
@@ -150,6 +155,38 @@ struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent * sd)
return inode;
}
+#ifdef CONFIG_LOCKDEP
+
+static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
+ struct inode *inode)
+{
+ int depth = sd->s_depth;
+
+ if (depth > 0) {
+ if (depth <= ARRAY_SIZE(default_group_class)) {
+ lockdep_set_class(&inode->i_mutex,
+ &default_group_class[depth - 1]);
+ } else {
+ /*
+ * In practice the maximum level of locking depth is
+ * already reached. Just inform about possible reasons.
+ */
+ printk(KERN_INFO "configfs: Too many levels of inodes"
+ " for the locking correctness validator.\n");
+ printk(KERN_INFO "Spurious warnings may appear.\n");
+ }
+ }
+}
+
+#else /* CONFIG_LOCKDEP */
+
+static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
+ struct inode *inode)
+{
+}
+
+#endif /* CONFIG_LOCKDEP */
+
int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
{
int error = 0;
@@ -162,6 +199,7 @@ int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *
struct inode *p_inode = dentry->d_parent->d_inode;
p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
}
+ configfs_set_inode_lock_class(sd, inode);
goto Proceed;
}
else
diff --git a/fs/dcache.c b/fs/dcache.c
index 1fcffebfb44f..9e5cd3c3a6ba 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -481,7 +481,7 @@ restart:
if ((flags & DCACHE_REFERENCED)
&& (dentry->d_flags & DCACHE_REFERENCED)) {
dentry->d_flags &= ~DCACHE_REFERENCED;
- list_move_tail(&dentry->d_lru, &referenced);
+ list_move(&dentry->d_lru, &referenced);
spin_unlock(&dentry->d_lock);
} else {
list_move_tail(&dentry->d_lru, &tmp);
@@ -1910,7 +1910,7 @@ char *__d_path(const struct path *path, struct path *root,
spin_lock(&vfsmount_lock);
prepend(&end, &buflen, "\0", 1);
- if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
+ if (d_unlinked(dentry) &&
(prepend(&end, &buflen, " (deleted)", 10) != 0))
goto Elong;
@@ -2035,7 +2035,7 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
spin_lock(&dcache_lock);
prepend(&end, &buflen, "\0", 1);
- if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
+ if (d_unlinked(dentry) &&
(prepend(&end, &buflen, "//deleted", 9) != 0))
goto Elong;
if (buflen < 1)
@@ -2097,9 +2097,8 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
read_unlock(&current->fs->lock);
error = -ENOENT;
- /* Has the current directory has been unlinked? */
spin_lock(&dcache_lock);
- if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) {
+ if (!d_unlinked(pwd.dentry)) {
unsigned long len;
struct path tmp = root;
char * cwd;
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 63a4a59e4148..21165cf934ff 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -389,11 +389,10 @@ static int devpts_get_sb(struct file_system_type *fs_type,
return 0;
out_dput:
- dput(s->s_root);
+ dput(s->s_root); /* undo dget() in simple_set_mnt() */
out_undo_sget:
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
return error;
}
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index cd8e2df3c295..d489fcc86713 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -384,7 +384,7 @@ static void threads_stop(void)
dlm_astd_stop();
}
-static int new_lockspace(char *name, int namelen, void **lockspace,
+static int new_lockspace(const char *name, int namelen, void **lockspace,
uint32_t flags, int lvblen)
{
struct dlm_ls *ls;
@@ -419,16 +419,14 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
break;
}
ls->ls_create_count++;
- module_put(THIS_MODULE);
- error = 1; /* not an error, return 0 */
+ *lockspace = ls;
+ error = 1;
break;
}
spin_unlock(&lslist_lock);
- if (error < 0)
- goto out;
if (error)
- goto ret_zero;
+ goto out;
error = -ENOMEM;
@@ -583,7 +581,6 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
dlm_create_debug_file(ls);
log_debug(ls, "join complete");
- ret_zero:
*lockspace = ls;
return 0;
@@ -614,7 +611,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
return error;
}
-int dlm_new_lockspace(char *name, int namelen, void **lockspace,
+int dlm_new_lockspace(const char *name, int namelen, void **lockspace,
uint32_t flags, int lvblen)
{
int error = 0;
@@ -628,7 +625,9 @@ int dlm_new_lockspace(char *name, int namelen, void **lockspace,
error = new_lockspace(name, namelen, lockspace, flags, lvblen);
if (!error)
ls_count++;
- else if (!ls_count)
+ if (error > 0)
+ error = 0;
+ if (!ls_count)
threads_stop();
out:
mutex_unlock(&ls_lock);
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index ccabd5faa04d..9f0aa9883c28 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -614,9 +614,8 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags,
}
goto out;
out_abort:
- dput(sb->s_root);
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ dput(sb->s_root); /* aka mnt->mnt_root, as set by get_sb_nodev() */
+ deactivate_locked_super(sb);
out:
return rc;
}
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index fa4c7e7d15d9..12d649602d3a 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/smp_lock.h>
#include <linux/file.h>
#include <linux/crypto.h>
#include "ecryptfs_kernel.h"
@@ -120,9 +121,13 @@ static void ecryptfs_put_super(struct super_block *sb)
{
struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb);
+ lock_kernel();
+
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);
+
+ unlock_kernel();
}
/**
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index a89f370fadb5..5458e80fc558 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -1212,7 +1212,7 @@ SYSCALL_DEFINE1(epoll_create1, int, flags)
SYSCALL_DEFINE1(epoll_create, int, size)
{
- if (size < 0)
+ if (size <= 0)
return -EINVAL;
return sys_epoll_create1(0);
diff --git a/fs/exec.c b/fs/exec.c
index 639177b0eeac..a7fcd975c6b2 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -105,40 +105,28 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
SYSCALL_DEFINE1(uselib, const char __user *, library)
{
struct file *file;
- struct nameidata nd;
char *tmp = getname(library);
int error = PTR_ERR(tmp);
- if (!IS_ERR(tmp)) {
- error = path_lookup_open(AT_FDCWD, tmp,
- LOOKUP_FOLLOW, &nd,
- FMODE_READ|FMODE_EXEC);
- putname(tmp);
- }
- if (error)
+ if (IS_ERR(tmp))
+ goto out;
+
+ file = do_filp_open(AT_FDCWD, tmp,
+ O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
+ MAY_READ | MAY_EXEC | MAY_OPEN);
+ putname(tmp);
+ error = PTR_ERR(file);
+ if (IS_ERR(file))
goto out;
error = -EINVAL;
- if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
+ if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
goto exit;
error = -EACCES;
- if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
- goto exit;
-
- error = inode_permission(nd.path.dentry->d_inode,
- MAY_READ | MAY_EXEC | MAY_OPEN);
- if (error)
- goto exit;
- error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
- if (error)
+ if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
goto exit;
- file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
- error = PTR_ERR(file);
- if (IS_ERR(file))
- goto out;
-
fsnotify_open(file->f_path.dentry);
error = -ENOEXEC;
@@ -160,13 +148,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
}
read_unlock(&binfmt_lock);
}
+exit:
fput(file);
out:
return error;
-exit:
- release_open_intent(&nd);
- path_put(&nd.path);
- goto out;
}
#ifdef CONFIG_MMU
@@ -661,47 +646,33 @@ EXPORT_SYMBOL(setup_arg_pages);
struct file *open_exec(const char *name)
{
- struct nameidata nd;
struct file *file;
int err;
- err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd,
- FMODE_READ|FMODE_EXEC);
- if (err)
+ file = do_filp_open(AT_FDCWD, name,
+ O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
+ MAY_EXEC | MAY_OPEN);
+ if (IS_ERR(file))
goto out;
err = -EACCES;
- if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
- goto out_path_put;
-
- if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
- goto out_path_put;
-
- err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
- if (err)
- goto out_path_put;
- err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
- if (err)
- goto out_path_put;
+ if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
+ goto exit;
- file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
- if (IS_ERR(file))
- return file;
+ if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
+ goto exit;
fsnotify_open(file->f_path.dentry);
err = deny_write_access(file);
- if (err) {
- fput(file);
- goto out;
- }
+ if (err)
+ goto exit;
+out:
return file;
- out_path_put:
- release_open_intent(&nd);
- path_put(&nd.path);
- out:
+exit:
+ fput(file);
return ERR_PTR(err);
}
EXPORT_SYMBOL(open_exec);
@@ -1045,7 +1016,7 @@ void install_exec_creds(struct linux_binprm *bprm)
commit_creds(bprm->cred);
bprm->cred = NULL;
- /* cred_exec_mutex must be held at least to this point to prevent
+ /* cred_guard_mutex must be held at least to this point to prevent
* ptrace_attach() from altering our determination of the task's
* credentials; any time after this it may be unlocked */
@@ -1055,7 +1026,7 @@ EXPORT_SYMBOL(install_exec_creds);
/*
* determine how safe it is to execute the proposed program
- * - the caller must hold current->cred_exec_mutex to protect against
+ * - the caller must hold current->cred_guard_mutex to protect against
* PTRACE_ATTACH
*/
int check_unsafe_exec(struct linux_binprm *bprm)
@@ -1297,7 +1268,7 @@ int do_execve(char * filename,
if (!bprm)
goto out_files;
- retval = mutex_lock_interruptible(&current->cred_exec_mutex);
+ retval = mutex_lock_interruptible(&current->cred_guard_mutex);
if (retval < 0)
goto out_free;
current->in_execve = 1;
@@ -1360,7 +1331,7 @@ int do_execve(char * filename,
/* execve succeeded */
current->fs->in_exec = 0;
current->in_execve = 0;
- mutex_unlock(&current->cred_exec_mutex);
+ mutex_unlock(&current->cred_guard_mutex);
acct_update_integrals(current);
free_bprm(bprm);
if (displaced)
@@ -1383,7 +1354,7 @@ out_unmark:
out_unlock:
current->in_execve = 0;
- mutex_unlock(&current->cred_exec_mutex);
+ mutex_unlock(&current->cred_guard_mutex);
out_free:
free_bprm(bprm);
diff --git a/fs/exofs/osd.c b/fs/exofs/osd.c
index b249ae97fb15..06ca92672eb5 100644
--- a/fs/exofs/osd.c
+++ b/fs/exofs/osd.c
@@ -50,10 +50,10 @@ int exofs_check_ok_resid(struct osd_request *or, u64 *in_resid, u64 *out_resid)
/* FIXME: should be include in osd_sense_info */
if (in_resid)
- *in_resid = or->in.req ? or->in.req->data_len : 0;
+ *in_resid = or->in.req ? or->in.req->resid_len : 0;
if (out_resid)
- *out_resid = or->out.req ? or->out.req->data_len : 0;
+ *out_resid = or->out.req ? or->out.req->resid_len : 0;
return ret;
}
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 9f1985e857e2..49e16af4e619 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -214,6 +214,7 @@ static void exofs_write_super(struct super_block *sb)
return;
}
+ lock_super(sb);
lock_kernel();
sbi = sb->s_fs_info;
fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
@@ -246,6 +247,7 @@ out:
if (or)
osd_end_request(or);
unlock_kernel();
+ unlock_super(sb);
kfree(fscb);
}
@@ -258,6 +260,11 @@ static void exofs_put_super(struct super_block *sb)
int num_pend;
struct exofs_sb_info *sbi = sb->s_fs_info;
+ lock_kernel();
+
+ if (sb->s_dirt)
+ exofs_write_super(sb);
+
/* make sure there are no pending commands */
for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
num_pend = atomic_read(&sbi->s_curr_pending)) {
@@ -271,6 +278,8 @@ static void exofs_put_super(struct super_block *sb)
osduld_put_device(sbi->s_dev);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
+
+ unlock_kernel();
}
/*
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 5c4afe652245..f5b7fadd2c07 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -114,6 +114,11 @@ static void ext2_put_super (struct super_block * sb)
int i;
struct ext2_sb_info *sbi = EXT2_SB(sb);
+ lock_kernel();
+
+ if (sb->s_dirt)
+ ext2_write_super(sb);
+
ext2_xattr_put_super(sb);
if (!(sb->s_flags & MS_RDONLY)) {
struct ext2_super_block *es = sbi->s_es;
@@ -135,7 +140,7 @@ static void ext2_put_super (struct super_block * sb)
kfree(sbi->s_blockgroup_lock);
kfree(sbi);
- return;
+ unlock_kernel();
}
static struct kmem_cache * ext2_inode_cachep;
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index d81ef2fdb08e..e0c745451715 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -129,12 +129,15 @@ fail:
static inline struct posix_acl *
ext3_iget_acl(struct inode *inode, struct posix_acl **i_acl)
{
- struct posix_acl *acl = EXT3_ACL_NOT_CACHED;
+ struct posix_acl *acl = ACCESS_ONCE(*i_acl);
- spin_lock(&inode->i_lock);
- if (*i_acl != EXT3_ACL_NOT_CACHED)
- acl = posix_acl_dup(*i_acl);
- spin_unlock(&inode->i_lock);
+ if (acl) {
+ spin_lock(&inode->i_lock);
+ acl = *i_acl;
+ if (acl != EXT3_ACL_NOT_CACHED)
+ acl = posix_acl_dup(acl);
+ spin_unlock(&inode->i_lock);
+ }
return acl;
}
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 225202db8974..27967f92e820 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -649,7 +649,7 @@ do_more:
count = overflow;
goto do_more;
}
- sb->s_dirt = 1;
+
error_return:
brelse(bitmap_bh);
ext3_std_error(sb, err);
@@ -1708,7 +1708,6 @@ allocated:
if (!fatal)
fatal = err;
- sb->s_dirt = 1;
if (fatal)
goto out;
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index dd13d60d524b..b39991285136 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -181,7 +181,7 @@ void ext3_free_inode (handle_t *handle, struct inode * inode)
err = ext3_journal_dirty_metadata(handle, bitmap_bh);
if (!fatal)
fatal = err;
- sb->s_dirt = 1;
+
error_return:
brelse(bitmap_bh);
ext3_std_error(sb, fatal);
@@ -537,7 +537,6 @@ got:
percpu_counter_dec(&sbi->s_freeinodes_counter);
if (S_ISDIR(mode))
percpu_counter_inc(&sbi->s_dirs_counter);
- sb->s_dirt = 1;
inode->i_uid = current_fsuid();
if (test_opt (sb, GRPID))
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index fcfa24361856..b0248c6d5d4c 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2960,7 +2960,6 @@ static int ext3_do_update_inode(handle_t *handle,
ext3_update_dynamic_rev(sb);
EXT3_SET_RO_COMPAT_FEATURE(sb,
EXT3_FEATURE_RO_COMPAT_LARGE_FILE);
- sb->s_dirt = 1;
handle->h_sync = 1;
err = ext3_journal_dirty_metadata(handle,
EXT3_SB(sb)->s_sbh);
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 78fdf3836370..8a0b26340b54 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -934,7 +934,6 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
EXT3_INODES_PER_GROUP(sb));
ext3_journal_dirty_metadata(handle, sbi->s_sbh);
- sb->s_dirt = 1;
exit_journal:
unlock_super(sb);
@@ -1066,7 +1065,6 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
}
es->s_blocks_count = cpu_to_le32(o_blocks_count + add);
ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
- sb->s_dirt = 1;
unlock_super(sb);
ext3_debug("freeing blocks %lu through "E3FSBLK"\n", o_blocks_count,
o_blocks_count + add);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 599dbfe504c3..0ca949dcc1ab 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -67,7 +67,6 @@ static const char *ext3_decode_error(struct super_block * sb, int errno,
static int ext3_remount (struct super_block * sb, int * flags, char * data);
static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf);
static int ext3_unfreeze(struct super_block *sb);
-static void ext3_write_super (struct super_block * sb);
static int ext3_freeze(struct super_block *sb);
/*
@@ -399,6 +398,8 @@ static void ext3_put_super (struct super_block * sb)
struct ext3_super_block *es = sbi->s_es;
int i, err;
+ lock_kernel();
+
ext3_xattr_put_super(sb);
err = journal_destroy(sbi->s_journal);
sbi->s_journal = NULL;
@@ -447,7 +448,8 @@ static void ext3_put_super (struct super_block * sb)
sb->s_fs_info = NULL;
kfree(sbi->s_blockgroup_lock);
kfree(sbi);
- return;
+
+ unlock_kernel();
}
static struct kmem_cache *ext3_inode_cachep;
@@ -761,7 +763,6 @@ static const struct super_operations ext3_sops = {
.dirty_inode = ext3_dirty_inode,
.delete_inode = ext3_delete_inode,
.put_super = ext3_put_super,
- .write_super = ext3_write_super,
.sync_fs = ext3_sync_fs,
.freeze_fs = ext3_freeze,
.unfreeze_fs = ext3_unfreeze,
@@ -1785,7 +1786,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
#else
es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
#endif
- sb->s_dirt = 1;
}
if (sbi->s_blocks_per_group > blocksize * 8) {
@@ -2264,7 +2264,6 @@ static int ext3_load_journal(struct super_block *sb,
if (journal_devnum &&
journal_devnum != le32_to_cpu(es->s_journal_dev)) {
es->s_journal_dev = cpu_to_le32(journal_devnum);
- sb->s_dirt = 1;
/* Make sure we flush the recovery flag to disk. */
ext3_commit_super(sb, es, 1);
@@ -2307,7 +2306,6 @@ static int ext3_create_journal(struct super_block * sb,
EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL);
es->s_journal_inum = cpu_to_le32(journal_inum);
- sb->s_dirt = 1;
/* Make sure we flush the recovery flag to disk. */
ext3_commit_super(sb, es, 1);
@@ -2353,7 +2351,6 @@ static void ext3_mark_recovery_complete(struct super_block * sb,
if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &&
sb->s_flags & MS_RDONLY) {
EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
- sb->s_dirt = 0;
ext3_commit_super(sb, es, 1);
}
unlock_super(sb);
@@ -2412,29 +2409,14 @@ int ext3_force_commit(struct super_block *sb)
return 0;
journal = EXT3_SB(sb)->s_journal;
- sb->s_dirt = 0;
ret = ext3_journal_force_commit(journal);
return ret;
}
-/*
- * Ext3 always journals updates to the superblock itself, so we don't
- * have to propagate any other updates to the superblock on disk at this
- * point. (We can probably nuke this function altogether, and remove
- * any mention to sb->s_dirt in all of fs/ext3; eventual cleanup...)
- */
-static void ext3_write_super (struct super_block * sb)
-{
- if (mutex_trylock(&sb->s_lock) != 0)
- BUG();
- sb->s_dirt = 0;
-}
-
static int ext3_sync_fs(struct super_block *sb, int wait)
{
tid_t target;
- sb->s_dirt = 0;
if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
if (wait)
log_wait_commit(EXT3_SB(sb)->s_journal, target);
@@ -2450,7 +2432,6 @@ static int ext3_freeze(struct super_block *sb)
{
int error = 0;
journal_t *journal;
- sb->s_dirt = 0;
if (!(sb->s_flags & MS_RDONLY)) {
journal = EXT3_SB(sb)->s_journal;
@@ -2509,6 +2490,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
#endif
/* Store the original options */
+ lock_super(sb);
old_sb_flags = sb->s_flags;
old_opts.s_mount_opt = sbi->s_mount_opt;
old_opts.s_resuid = sbi->s_resuid;
@@ -2616,6 +2598,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
old_opts.s_qf_names[i] != sbi->s_qf_names[i])
kfree(old_opts.s_qf_names[i]);
#endif
+ unlock_super(sb);
return 0;
restore_opts:
sb->s_flags = old_sb_flags;
@@ -2632,6 +2615,7 @@ restore_opts:
sbi->s_qf_names[i] = old_opts.s_qf_names[i];
}
#endif
+ unlock_super(sb);
return err;
}
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 83b7be849bd5..545e37c4b91e 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -463,7 +463,6 @@ static void ext3_xattr_update_super_block(handle_t *handle,
if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) {
EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR);
- sb->s_dirt = 1;
ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
}
}
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 647e0d65a284..605aeed96d68 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -129,12 +129,15 @@ fail:
static inline struct posix_acl *
ext4_iget_acl(struct inode *inode, struct posix_acl **i_acl)
{
- struct posix_acl *acl = EXT4_ACL_NOT_CACHED;
+ struct posix_acl *acl = ACCESS_ONCE(*i_acl);
- spin_lock(&inode->i_lock);
- if (*i_acl != EXT4_ACL_NOT_CACHED)
- acl = posix_acl_dup(*i_acl);
- spin_unlock(&inode->i_lock);
+ if (acl) {
+ spin_lock(&inode->i_lock);
+ acl = *i_acl;
+ if (acl != EXT4_ACL_NOT_CACHED)
+ acl = posix_acl_dup(acl);
+ spin_unlock(&inode->i_lock);
+ }
return acl;
}
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 53c72ad85877..e2126d70dff5 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -19,7 +19,6 @@
#include <linux/buffer_head.h>
#include "ext4.h"
#include "ext4_jbd2.h"
-#include "group.h"
#include "mballoc.h"
/*
@@ -88,6 +87,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
ext4_group_t block_group, struct ext4_group_desc *gdp)
{
int bit, bit_max;
+ ext4_group_t ngroups = ext4_get_groups_count(sb);
unsigned free_blocks, group_blocks;
struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -123,7 +123,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
bit_max += ext4_bg_num_gdb(sb, block_group);
}
- if (block_group == sbi->s_groups_count - 1) {
+ if (block_group == ngroups - 1) {
/*
* Even though mke2fs always initialize first and last group
* if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need
@@ -131,7 +131,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
*/
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));
+ (EXT4_BLOCKS_PER_GROUP(sb) * (ngroups - 1));
} else {
group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
}
@@ -205,18 +205,18 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
{
unsigned int group_desc;
unsigned int offset;
+ ext4_group_t ngroups = ext4_get_groups_count(sb);
struct ext4_group_desc *desc;
struct ext4_sb_info *sbi = EXT4_SB(sb);
- if (block_group >= sbi->s_groups_count) {
+ if (block_group >= ngroups) {
ext4_error(sb, "ext4_get_group_desc",
"block_group >= groups_count - "
"block_group = %u, groups_count = %u",
- block_group, sbi->s_groups_count);
+ block_group, ngroups);
return NULL;
}
- smp_rmb();
group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
@@ -326,16 +326,16 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
unlock_buffer(bh);
return bh;
}
- spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_lock_group(sb, block_group);
if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
ext4_init_block_bitmap(sb, bh, block_group, desc);
set_bitmap_uptodate(bh);
set_buffer_uptodate(bh);
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_unlock_group(sb, block_group);
unlock_buffer(bh);
return bh;
}
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_unlock_group(sb, block_group);
if (buffer_uptodate(bh)) {
/*
* if not uninit if bh is uptodate,
@@ -451,7 +451,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
down_write(&grp->alloc_sem);
for (i = 0, blocks_freed = 0; i < count; i++) {
BUFFER_TRACE(bitmap_bh, "clear bit");
- if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
+ if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group),
bit + i, bitmap_bh->b_data)) {
ext4_error(sb, __func__,
"bit already cleared for block %llu",
@@ -461,11 +461,11 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
blocks_freed++;
}
}
- spin_lock(sb_bgl_lock(sbi, block_group));
+ ext4_lock_group(sb, block_group);
blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc);
ext4_free_blks_set(sb, desc, blk_free_count);
desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
- spin_unlock(sb_bgl_lock(sbi, block_group));
+ ext4_unlock_group(sb, block_group);
percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed);
if (sbi->s_log_groups_per_flex) {
@@ -665,7 +665,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
ext4_fsblk_t desc_count;
struct ext4_group_desc *gdp;
ext4_group_t i;
- ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
+ ext4_group_t ngroups = ext4_get_groups_count(sb);
#ifdef EXT4FS_DEBUG
struct ext4_super_block *es;
ext4_fsblk_t bitmap_count;
@@ -677,7 +677,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
bitmap_count = 0;
gdp = NULL;
- smp_rmb();
for (i = 0; i < ngroups; i++) {
gdp = ext4_get_group_desc(sb, i, NULL);
if (!gdp)
@@ -700,7 +699,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
return bitmap_count;
#else
desc_count = 0;
- smp_rmb();
for (i = 0; i < ngroups; i++) {
gdp = ext4_get_group_desc(sb, i, NULL);
if (!gdp)
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index b64789929a65..9dc93168e262 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -131,8 +131,7 @@ static int ext4_readdir(struct file *filp,
struct buffer_head *bh = NULL;
map_bh.b_state = 0;
- err = ext4_get_blocks_wrap(NULL, inode, blk, 1, &map_bh,
- 0, 0, 0);
+ err = ext4_get_blocks(NULL, inode, blk, 1, &map_bh, 0);
if (err > 0) {
pgoff_t index = map_bh.b_blocknr >>
(PAGE_CACHE_SHIFT - inode->i_blkbits);
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index d0f15ef56de1..c2b3461fd251 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -21,7 +21,14 @@
#include <linux/magic.h>
#include <linux/jbd2.h>
#include <linux/quota.h>
-#include "ext4_i.h"
+#include <linux/rwsem.h>
+#include <linux/rbtree.h>
+#include <linux/seqlock.h>
+#include <linux/mutex.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/blockgroup_lock.h>
+#include <linux/percpu_counter.h>
/*
* The fourth extended filesystem constants/structures
@@ -46,6 +53,19 @@
#define ext4_debug(f, a...) do {} while (0)
#endif
+/* data type for block offset of block group */
+typedef int ext4_grpblk_t;
+
+/* data type for filesystem-wide blocks number */
+typedef unsigned long long ext4_fsblk_t;
+
+/* data type for file logical block number */
+typedef __u32 ext4_lblk_t;
+
+/* data type for block group number */
+typedef unsigned int ext4_group_t;
+
+
/* prefer goal again. length */
#define EXT4_MB_HINT_MERGE 1
/* blocks already reserved */
@@ -179,9 +199,6 @@ struct flex_groups {
#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 "ext4_sb.h"
-#endif
/*
* Macro-instructions used to manage group descriptors
*/
@@ -297,10 +314,20 @@ struct ext4_new_group_data {
};
/*
- * Following is used by preallocation code to tell get_blocks() that we
- * want uninitialzed extents.
+ * Flags used by ext4_get_blocks()
*/
-#define EXT4_CREATE_UNINITIALIZED_EXT 2
+ /* Allocate any needed blocks and/or convert an unitialized
+ extent to be an initialized ext4 */
+#define EXT4_GET_BLOCKS_CREATE 1
+ /* Request the creation of an unitialized extent */
+#define EXT4_GET_BLOCKS_UNINIT_EXT 2
+#define EXT4_GET_BLOCKS_CREATE_UNINIT_EXT (EXT4_GET_BLOCKS_UNINIT_EXT|\
+ EXT4_GET_BLOCKS_CREATE)
+ /* Update the ext4_inode_info i_disksize field */
+#define EXT4_GET_BLOCKS_EXTEND_DISKSIZE 4
+ /* Caller is from the delayed allocation writeout path,
+ so the filesystem blocks have already been accounted for */
+#define EXT4_GET_BLOCKS_DELALLOC_RESERVE 8
/*
* ioctl commands
@@ -516,6 +543,110 @@ do { \
#endif /* defined(__KERNEL__) || defined(__linux__) */
/*
+ * storage for cached extent
+ */
+struct ext4_ext_cache {
+ ext4_fsblk_t ec_start;
+ ext4_lblk_t ec_block;
+ __u32 ec_len; /* must be 32bit to return holes */
+ __u32 ec_type;
+};
+
+/*
+ * fourth extended file system inode data in memory
+ */
+struct ext4_inode_info {
+ __le32 i_data[15]; /* unconverted */
+ __u32 i_flags;
+ ext4_fsblk_t i_file_acl;
+ __u32 i_dtime;
+
+ /*
+ * i_block_group is the number of the block group which contains
+ * this file's inode. Constant across the lifetime of the inode,
+ * it is ued for making block allocation decisions - we try to
+ * place a file's data blocks near its inode block, and new inodes
+ * near to their parent directory's inode.
+ */
+ ext4_group_t i_block_group;
+ __u32 i_state; /* Dynamic state flags for ext4 */
+
+ ext4_lblk_t i_dir_start_lookup;
+#ifdef CONFIG_EXT4_FS_XATTR
+ /*
+ * Extended attributes can be read independently of the main file
+ * data. Taking i_mutex even when reading would cause contention
+ * between readers of EAs and writers of regular file data, so
+ * instead we synchronize on xattr_sem when reading or changing
+ * EAs.
+ */
+ struct rw_semaphore xattr_sem;
+#endif
+#ifdef CONFIG_EXT4_FS_POSIX_ACL
+ struct posix_acl *i_acl;
+ struct posix_acl *i_default_acl;
+#endif
+
+ struct list_head i_orphan; /* unlinked but open inodes */
+
+ /*
+ * i_disksize keeps track of what the inode size is ON DISK, not
+ * in memory. During truncate, i_size is set to the new size by
+ * the VFS prior to calling ext4_truncate(), but the filesystem won't
+ * set i_disksize to 0 until the truncate is actually under way.
+ *
+ * The intent is that i_disksize always represents the blocks which
+ * are used by this file. This allows recovery to restart truncate
+ * on orphans if we crash during truncate. We actually write i_disksize
+ * into the on-disk inode when writing inodes out, instead of i_size.
+ *
+ * The only time when i_disksize and i_size may be different is when
+ * a truncate is in progress. The only things which change i_disksize
+ * are ext4_get_block (growth) and ext4_truncate (shrinkth).
+ */
+ loff_t i_disksize;
+
+ /*
+ * i_data_sem is for serialising ext4_truncate() against
+ * ext4_getblock(). In the 2.4 ext2 design, great chunks of inode's
+ * data tree are chopped off during truncate. We can't do that in
+ * ext4 because whenever we perform intermediate commits during
+ * truncate, the inode and all the metadata blocks *must* be in a
+ * consistent state which allows truncation of the orphans to restart
+ * during recovery. Hence we must fix the get_block-vs-truncate race
+ * by other means, so we have i_data_sem.
+ */
+ struct rw_semaphore i_data_sem;
+ struct inode vfs_inode;
+ struct jbd2_inode jinode;
+
+ struct ext4_ext_cache i_cached_extent;
+ /*
+ * File creation time. Its function is same as that of
+ * struct timespec i_{a,c,m}time in the generic inode.
+ */
+ struct timespec i_crtime;
+
+ /* mballoc */
+ struct list_head i_prealloc_list;
+ spinlock_t i_prealloc_lock;
+
+ /* ialloc */
+ ext4_group_t i_last_alloc_group;
+
+ /* allocation reservation info for delalloc */
+ unsigned int i_reserved_data_blocks;
+ unsigned int i_reserved_meta_blocks;
+ unsigned int i_allocated_meta_blocks;
+ unsigned short i_delalloc_reserved_flag;
+
+ /* on-disk additional length */
+ __u16 i_extra_isize;
+
+ spinlock_t i_block_reservation_lock;
+};
+
+/*
* File system states
*/
#define EXT4_VALID_FS 0x0001 /* Unmounted cleanly */
@@ -689,6 +820,136 @@ struct ext4_super_block {
};
#ifdef __KERNEL__
+/*
+ * fourth extended-fs super-block data in memory
+ */
+struct ext4_sb_info {
+ unsigned long s_desc_size; /* Size of a group descriptor in bytes */
+ unsigned long s_inodes_per_block;/* Number of inodes per block */
+ 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 */
+ unsigned long s_gdb_count; /* Number of group descriptor blocks */
+ unsigned long s_desc_per_block; /* Number of group descriptors per block */
+ ext4_group_t s_groups_count; /* Number of groups in the fs */
+ unsigned long s_overhead_last; /* Last calculated overhead */
+ unsigned long s_blocks_last; /* Last seen block count */
+ loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */
+ struct buffer_head * s_sbh; /* Buffer containing the super block */
+ 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;
+ unsigned short s_pad;
+ int s_addr_per_block_bits;
+ int s_desc_per_block_bits;
+ int s_inode_size;
+ int s_first_ino;
+ unsigned int s_inode_readahead_blks;
+ spinlock_t s_next_gen_lock;
+ u32 s_next_generation;
+ u32 s_hash_seed[4];
+ int s_def_hash_version;
+ int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */
+ struct percpu_counter s_freeblocks_counter;
+ struct percpu_counter s_freeinodes_counter;
+ struct percpu_counter s_dirs_counter;
+ struct percpu_counter s_dirtyblocks_counter;
+ struct blockgroup_lock *s_blockgroup_lock;
+ struct proc_dir_entry *s_proc;
+ struct kobject s_kobj;
+ struct completion s_kobj_unregister;
+
+ /* Journaling */
+ struct inode *s_journal_inode;
+ struct journal_s *s_journal;
+ struct list_head s_orphan;
+ struct mutex s_orphan_lock;
+ struct mutex s_resize_lock;
+ unsigned long s_commit_interval;
+ u32 s_max_batch_time;
+ u32 s_min_batch_time;
+ struct block_device *journal_bdev;
+#ifdef CONFIG_JBD2_DEBUG
+ struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */
+ wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */
+#endif
+#ifdef CONFIG_QUOTA
+ char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */
+ int s_jquota_fmt; /* Format of quota to use */
+#endif
+ unsigned int s_want_extra_isize; /* New inodes should reserve # bytes */
+
+#ifdef EXTENTS_STATS
+ /* ext4 extents stats */
+ unsigned long s_ext_min;
+ unsigned long s_ext_max;
+ unsigned long s_depth_max;
+ spinlock_t s_ext_stats_lock;
+ unsigned long s_ext_blocks;
+ unsigned long s_ext_extents;
+#endif
+
+ /* for buddy allocator */
+ struct ext4_group_info ***s_group_info;
+ struct inode *s_buddy_cache;
+ long s_blocks_reserved;
+ spinlock_t s_reserve_lock;
+ spinlock_t s_md_lock;
+ tid_t s_last_transaction;
+ unsigned short *s_mb_offsets;
+ unsigned int *s_mb_maxs;
+
+ /* tunables */
+ unsigned long s_stripe;
+ unsigned int s_mb_stream_request;
+ unsigned int s_mb_max_to_scan;
+ unsigned int s_mb_min_to_scan;
+ unsigned int s_mb_stats;
+ unsigned int s_mb_order2_reqs;
+ unsigned int s_mb_group_prealloc;
+ /* where last allocation was done - for stream allocation */
+ unsigned long s_mb_last_group;
+ unsigned long s_mb_last_start;
+
+ /* history to debug policy */
+ struct ext4_mb_history *s_mb_history;
+ int s_mb_history_cur;
+ int s_mb_history_max;
+ int s_mb_history_num;
+ spinlock_t s_mb_history_lock;
+ int s_mb_history_filter;
+
+ /* stats for buddy allocator */
+ spinlock_t s_mb_pa_lock;
+ atomic_t s_bal_reqs; /* number of reqs with len > 1 */
+ atomic_t s_bal_success; /* we found long enough chunks */
+ atomic_t s_bal_allocated; /* in blocks */
+ atomic_t s_bal_ex_scanned; /* total extents scanned */
+ atomic_t s_bal_goals; /* goal hits */
+ atomic_t s_bal_breaks; /* too long searches */
+ atomic_t s_bal_2orders; /* 2^order hits */
+ spinlock_t s_bal_lock;
+ unsigned long s_mb_buddies_generated;
+ unsigned long long s_mb_generation_time;
+ atomic_t s_mb_lost_chunks;
+ atomic_t s_mb_preallocated;
+ atomic_t s_mb_discarded;
+
+ /* locality groups */
+ struct ext4_locality_group *s_locality_groups;
+
+ /* for write statistics */
+ unsigned long s_sectors_written_start;
+ u64 s_kbytes_written;
+
+ unsigned int s_log_groups_per_flex;
+ struct flex_groups *s_flex_groups;
+};
+
static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
{
return sb->s_fs_info;
@@ -704,7 +965,6 @@ static inline struct timespec ext4_current_time(struct inode *inode)
current_fs_time(inode->i_sb) : CURRENT_TIME_SEC;
}
-
static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
{
return ino == EXT4_ROOT_INO ||
@@ -1014,6 +1274,14 @@ extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
ext4_group_t block_group,
struct buffer_head ** bh);
extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
+struct buffer_head *ext4_read_block_bitmap(struct super_block *sb,
+ ext4_group_t block_group);
+extern unsigned ext4_init_block_bitmap(struct super_block *sb,
+ struct buffer_head *bh,
+ ext4_group_t group,
+ struct ext4_group_desc *desc);
+#define ext4_free_blocks_after_init(sb, group, desc) \
+ ext4_init_block_bitmap(sb, NULL, group, desc)
/* dir.c */
extern int ext4_check_dir_entry(const char *, struct inode *,
@@ -1038,6 +1306,11 @@ extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
extern unsigned long ext4_count_free_inodes(struct super_block *);
extern unsigned long ext4_count_dirs(struct super_block *);
extern void ext4_check_inodes_bitmap(struct super_block *);
+extern unsigned ext4_init_inode_bitmap(struct super_block *sb,
+ struct buffer_head *bh,
+ ext4_group_t group,
+ struct ext4_group_desc *desc);
+extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
/* mballoc.c */
extern long ext4_mb_stats;
@@ -1161,6 +1434,10 @@ extern void ext4_used_dirs_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count);
extern void ext4_itable_unused_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count);
+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);
static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
{
@@ -1228,6 +1505,18 @@ struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
return grp_info[indexv][indexh];
}
+/*
+ * Reading s_groups_count requires using smp_rmb() afterwards. See
+ * the locking protocol documented in the comments of ext4_group_add()
+ * in resize.c
+ */
+static inline ext4_group_t ext4_get_groups_count(struct super_block *sb)
+{
+ ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
+
+ smp_rmb();
+ return ngroups;
+}
static inline ext4_group_t ext4_flex_group(struct ext4_sb_info *sbi,
ext4_group_t block_group)
@@ -1283,33 +1572,31 @@ struct ext4_group_info {
};
#define EXT4_GROUP_INFO_NEED_INIT_BIT 0
-#define EXT4_GROUP_INFO_LOCKED_BIT 1
#define EXT4_MB_GRP_NEED_INIT(grp) \
(test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state)))
-static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
+static inline spinlock_t *ext4_group_lock_ptr(struct super_block *sb,
+ ext4_group_t group)
{
- struct ext4_group_info *grinfo = ext4_get_group_info(sb, group);
+ return bgl_lock_ptr(EXT4_SB(sb)->s_blockgroup_lock, group);
+}
- bit_spin_lock(EXT4_GROUP_INFO_LOCKED_BIT, &(grinfo->bb_state));
+static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
+{
+ spin_lock(ext4_group_lock_ptr(sb, group));
}
static inline void ext4_unlock_group(struct super_block *sb,
ext4_group_t group)
{
- struct ext4_group_info *grinfo = ext4_get_group_info(sb, group);
-
- bit_spin_unlock(EXT4_GROUP_INFO_LOCKED_BIT, &(grinfo->bb_state));
+ spin_unlock(ext4_group_lock_ptr(sb, group));
}
static inline int ext4_is_group_locked(struct super_block *sb,
ext4_group_t group)
{
- struct ext4_group_info *grinfo = ext4_get_group_info(sb, group);
-
- return bit_spin_is_locked(EXT4_GROUP_INFO_LOCKED_BIT,
- &(grinfo->bb_state));
+ return spin_is_locked(ext4_group_lock_ptr(sb, group));
}
/*
@@ -1326,6 +1613,7 @@ extern const struct file_operations ext4_file_operations;
/* namei.c */
extern const struct inode_operations ext4_dir_inode_operations;
extern const struct inode_operations ext4_special_inode_operations;
+extern struct dentry *ext4_get_parent(struct dentry *child);
/* symlink.c */
extern const struct inode_operations ext4_symlink_inode_operations;
@@ -1338,17 +1626,15 @@ extern int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks,
int chunk);
extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
ext4_lblk_t iblock, unsigned int max_blocks,
- struct buffer_head *bh_result,
- int create, int extend_disksize);
+ struct buffer_head *bh_result, int flags);
extern void ext4_ext_truncate(struct inode *);
extern void ext4_ext_init(struct super_block *);
extern void ext4_ext_release(struct super_block *);
extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset,
loff_t len);
-extern int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode,
- sector_t block, unsigned int max_blocks,
- struct buffer_head *bh, int create,
- int extend_disksize, int flag);
+extern int ext4_get_blocks(handle_t *handle, struct inode *inode,
+ sector_t block, unsigned int max_blocks,
+ struct buffer_head *bh, int flags);
extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
__u64 start, __u64 len);
diff --git a/fs/ext4/ext4_i.h b/fs/ext4/ext4_i.h
deleted file mode 100644
index 4ce2187123aa..000000000000
--- a/fs/ext4/ext4_i.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * ext4_i.h
- *
- * Copyright (C) 1992, 1993, 1994, 1995
- * Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- *
- * from
- *
- * linux/include/linux/minix_fs_i.h
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-#ifndef _EXT4_I
-#define _EXT4_I
-
-#include <linux/rwsem.h>
-#include <linux/rbtree.h>
-#include <linux/seqlock.h>
-#include <linux/mutex.h>
-
-/* data type for block offset of block group */
-typedef int ext4_grpblk_t;
-
-/* data type for filesystem-wide blocks number */
-typedef unsigned long long ext4_fsblk_t;
-
-/* data type for file logical block number */
-typedef __u32 ext4_lblk_t;
-
-/* data type for block group number */
-typedef unsigned int ext4_group_t;
-
-/*
- * storage for cached extent
- */
-struct ext4_ext_cache {
- ext4_fsblk_t ec_start;
- ext4_lblk_t ec_block;
- __u32 ec_len; /* must be 32bit to return holes */
- __u32 ec_type;
-};
-
-/*
- * fourth extended file system inode data in memory
- */
-struct ext4_inode_info {
- __le32 i_data[15]; /* unconverted */
- __u32 i_flags;
- ext4_fsblk_t i_file_acl;
- __u32 i_dtime;
-
- /*
- * i_block_group is the number of the block group which contains
- * this file's inode. Constant across the lifetime of the inode,
- * it is ued for making block allocation decisions - we try to
- * place a file's data blocks near its inode block, and new inodes
- * near to their parent directory's inode.
- */
- ext4_group_t i_block_group;
- __u32 i_state; /* Dynamic state flags for ext4 */
-
- ext4_lblk_t i_dir_start_lookup;
-#ifdef CONFIG_EXT4_FS_XATTR
- /*
- * Extended attributes can be read independently of the main file
- * data. Taking i_mutex even when reading would cause contention
- * between readers of EAs and writers of regular file data, so
- * instead we synchronize on xattr_sem when reading or changing
- * EAs.
- */
- struct rw_semaphore xattr_sem;
-#endif
-#ifdef CONFIG_EXT4_FS_POSIX_ACL
- struct posix_acl *i_acl;
- struct posix_acl *i_default_acl;
-#endif
-
- struct list_head i_orphan; /* unlinked but open inodes */
-
- /*
- * i_disksize keeps track of what the inode size is ON DISK, not
- * in memory. During truncate, i_size is set to the new size by
- * the VFS prior to calling ext4_truncate(), but the filesystem won't
- * set i_disksize to 0 until the truncate is actually under way.
- *
- * The intent is that i_disksize always represents the blocks which
- * are used by this file. This allows recovery to restart truncate
- * on orphans if we crash during truncate. We actually write i_disksize
- * into the on-disk inode when writing inodes out, instead of i_size.
- *
- * The only time when i_disksize and i_size may be different is when
- * a truncate is in progress. The only things which change i_disksize
- * are ext4_get_block (growth) and ext4_truncate (shrinkth).
- */
- loff_t i_disksize;
-
- /*
- * i_data_sem is for serialising ext4_truncate() against
- * ext4_getblock(). In the 2.4 ext2 design, great chunks of inode's
- * data tree are chopped off during truncate. We can't do that in
- * ext4 because whenever we perform intermediate commits during
- * truncate, the inode and all the metadata blocks *must* be in a
- * consistent state which allows truncation of the orphans to restart
- * during recovery. Hence we must fix the get_block-vs-truncate race
- * by other means, so we have i_data_sem.
- */
- struct rw_semaphore i_data_sem;
- struct inode vfs_inode;
- struct jbd2_inode jinode;
-
- struct ext4_ext_cache i_cached_extent;
- /*
- * File creation time. Its function is same as that of
- * struct timespec i_{a,c,m}time in the generic inode.
- */
- struct timespec i_crtime;
-
- /* mballoc */
- struct list_head i_prealloc_list;
- spinlock_t i_prealloc_lock;
-
- /* ialloc */
- ext4_group_t i_last_alloc_group;
-
- /* allocation reservation info for delalloc */
- unsigned int i_reserved_data_blocks;
- unsigned int i_reserved_meta_blocks;
- unsigned int i_allocated_meta_blocks;
- unsigned short i_delalloc_reserved_flag;
-
- /* on-disk additional length */
- __u16 i_extra_isize;
-
- spinlock_t i_block_reservation_lock;
-};
-
-#endif /* _EXT4_I */
diff --git a/fs/ext4/ext4_sb.h b/fs/ext4/ext4_sb.h
deleted file mode 100644
index 57b71fefbccf..000000000000
--- a/fs/ext4/ext4_sb.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * ext4_sb.h
- *
- * Copyright (C) 1992, 1993, 1994, 1995
- * Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- *
- * from
- *
- * linux/include/linux/minix_fs_sb.h
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-#ifndef _EXT4_SB
-#define _EXT4_SB
-
-#ifdef __KERNEL__
-#include <linux/timer.h>
-#include <linux/wait.h>
-#include <linux/blockgroup_lock.h>
-#include <linux/percpu_counter.h>
-#endif
-#include <linux/rbtree.h>
-
-/*
- * fourth extended-fs super-block data in memory
- */
-struct ext4_sb_info {
- unsigned long s_desc_size; /* Size of a group descriptor in bytes */
- unsigned long s_inodes_per_block;/* Number of inodes per block */
- 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 */
- unsigned long s_gdb_count; /* Number of group descriptor blocks */
- unsigned long s_desc_per_block; /* Number of group descriptors per block */
- ext4_group_t s_groups_count; /* Number of groups in the fs */
- unsigned long s_overhead_last; /* Last calculated overhead */
- unsigned long s_blocks_last; /* Last seen block count */
- loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */
- struct buffer_head * s_sbh; /* Buffer containing the super block */
- 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;
- unsigned short s_pad;
- int s_addr_per_block_bits;
- int s_desc_per_block_bits;
- int s_inode_size;
- int s_first_ino;
- unsigned int s_inode_readahead_blks;
- spinlock_t s_next_gen_lock;
- u32 s_next_generation;
- u32 s_hash_seed[4];
- int s_def_hash_version;
- int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */
- struct percpu_counter s_freeblocks_counter;
- struct percpu_counter s_freeinodes_counter;
- struct percpu_counter s_dirs_counter;
- struct percpu_counter s_dirtyblocks_counter;
- struct blockgroup_lock *s_blockgroup_lock;
- struct proc_dir_entry *s_proc;
- struct kobject s_kobj;
- struct completion s_kobj_unregister;
-
- /* Journaling */
- struct inode *s_journal_inode;
- struct journal_s *s_journal;
- struct list_head s_orphan;
- unsigned long s_commit_interval;
- u32 s_max_batch_time;
- u32 s_min_batch_time;
- struct block_device *journal_bdev;
-#ifdef CONFIG_JBD2_DEBUG
- struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */
- wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */
-#endif
-#ifdef CONFIG_QUOTA
- char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */
- int s_jquota_fmt; /* Format of quota to use */
-#endif
- unsigned int s_want_extra_isize; /* New inodes should reserve # bytes */
-
-#ifdef EXTENTS_STATS
- /* ext4 extents stats */
- unsigned long s_ext_min;
- unsigned long s_ext_max;
- unsigned long s_depth_max;
- spinlock_t s_ext_stats_lock;
- unsigned long s_ext_blocks;
- unsigned long s_ext_extents;
-#endif
-
- /* for buddy allocator */
- struct ext4_group_info ***s_group_info;
- struct inode *s_buddy_cache;
- long s_blocks_reserved;
- spinlock_t s_reserve_lock;
- spinlock_t s_md_lock;
- tid_t s_last_transaction;
- unsigned short *s_mb_offsets;
- unsigned int *s_mb_maxs;
-
- /* tunables */
- unsigned long s_stripe;
- unsigned int s_mb_stream_request;
- unsigned int s_mb_max_to_scan;
- unsigned int s_mb_min_to_scan;
- unsigned int s_mb_stats;
- unsigned int s_mb_order2_reqs;
- unsigned int s_mb_group_prealloc;
- /* where last allocation was done - for stream allocation */
- unsigned long s_mb_last_group;
- unsigned long s_mb_last_start;
-
- /* history to debug policy */
- struct ext4_mb_history *s_mb_history;
- int s_mb_history_cur;
- int s_mb_history_max;
- int s_mb_history_num;
- spinlock_t s_mb_history_lock;
- int s_mb_history_filter;
-
- /* stats for buddy allocator */
- spinlock_t s_mb_pa_lock;
- atomic_t s_bal_reqs; /* number of reqs with len > 1 */
- atomic_t s_bal_success; /* we found long enough chunks */
- atomic_t s_bal_allocated; /* in blocks */
- atomic_t s_bal_ex_scanned; /* total extents scanned */
- atomic_t s_bal_goals; /* goal hits */
- atomic_t s_bal_breaks; /* too long searches */
- atomic_t s_bal_2orders; /* 2^order hits */
- spinlock_t s_bal_lock;
- unsigned long s_mb_buddies_generated;
- unsigned long long s_mb_generation_time;
- atomic_t s_mb_lost_chunks;
- atomic_t s_mb_preallocated;
- atomic_t s_mb_discarded;
-
- /* locality groups */
- struct ext4_locality_group *s_locality_groups;
-
- /* for write statistics */
- unsigned long s_sectors_written_start;
- u64 s_kbytes_written;
-
- unsigned int s_log_groups_per_flex;
- struct flex_groups *s_flex_groups;
-};
-
-static inline spinlock_t *
-sb_bgl_lock(struct ext4_sb_info *sbi, unsigned int block_group)
-{
- return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group);
-}
-
-#endif /* _EXT4_SB */
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index e40332158340..e04124831657 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2777,7 +2777,7 @@ fix_extent_len:
int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
ext4_lblk_t iblock,
unsigned int max_blocks, struct buffer_head *bh_result,
- int create, int extend_disksize)
+ int flags)
{
struct ext4_ext_path *path = NULL;
struct ext4_extent_header *eh;
@@ -2796,7 +2796,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
cache_type = ext4_ext_in_cache(inode, iblock, &newex);
if (cache_type) {
if (cache_type == EXT4_EXT_CACHE_GAP) {
- if (!create) {
+ if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
/*
* block isn't allocated yet and
* user doesn't want to allocate it
@@ -2862,9 +2862,11 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
EXT4_EXT_CACHE_EXTENT);
goto out;
}
- if (create == EXT4_CREATE_UNINITIALIZED_EXT)
+ if (flags & EXT4_GET_BLOCKS_UNINIT_EXT)
goto out;
- if (!create) {
+ if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
+ if (allocated > max_blocks)
+ allocated = max_blocks;
/*
* We have blocks reserved already. We
* return allocated blocks so that delalloc
@@ -2872,9 +2874,9 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
* the buffer head will be unmapped so that
* a read from the block returns 0s.
*/
- if (allocated > max_blocks)
- allocated = max_blocks;
set_buffer_unwritten(bh_result);
+ bh_result->b_bdev = inode->i_sb->s_bdev;
+ bh_result->b_blocknr = newblock;
goto out2;
}
@@ -2894,7 +2896,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
* requested block isn't allocated yet;
* we couldn't try to create block if create flag is zero
*/
- if (!create) {
+ if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
/*
* put just found gap into cache to speed up
* subsequent requests
@@ -2923,10 +2925,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
* EXT_UNINIT_MAX_LEN.
*/
if (max_blocks > EXT_INIT_MAX_LEN &&
- create != EXT4_CREATE_UNINITIALIZED_EXT)
+ !(flags & EXT4_GET_BLOCKS_UNINIT_EXT))
max_blocks = EXT_INIT_MAX_LEN;
else if (max_blocks > EXT_UNINIT_MAX_LEN &&
- create == EXT4_CREATE_UNINITIALIZED_EXT)
+ (flags & EXT4_GET_BLOCKS_UNINIT_EXT))
max_blocks = EXT_UNINIT_MAX_LEN;
/* Check if we can really insert (iblock)::(iblock+max_blocks) extent */
@@ -2957,7 +2959,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
/* try to insert new extent into found leaf and return */
ext4_ext_store_pblock(&newex, newblock);
newex.ee_len = cpu_to_le16(ar.len);
- if (create == EXT4_CREATE_UNINITIALIZED_EXT) /* Mark uninitialized */
+ if (flags & EXT4_GET_BLOCKS_UNINIT_EXT) /* Mark uninitialized */
ext4_ext_mark_uninitialized(&newex);
err = ext4_ext_insert_extent(handle, inode, path, &newex);
if (err) {
@@ -2974,7 +2976,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
newblock = ext_pblock(&newex);
allocated = ext4_ext_get_actual_len(&newex);
outnew:
- if (extend_disksize) {
+ if (flags & EXT4_GET_BLOCKS_EXTEND_DISKSIZE) {
disksize = ((loff_t) iblock + ar.len) << inode->i_blkbits;
if (disksize > i_size_read(inode))
disksize = i_size_read(inode);
@@ -2985,7 +2987,7 @@ outnew:
set_buffer_new(bh_result);
/* Cache only when it is _not_ an uninitialized extent */
- if (create != EXT4_CREATE_UNINITIALIZED_EXT)
+ if ((flags & EXT4_GET_BLOCKS_UNINIT_EXT) == 0)
ext4_ext_put_in_cache(inode, iblock, allocated, newblock,
EXT4_EXT_CACHE_EXTENT);
out:
@@ -3141,9 +3143,10 @@ retry:
ret = PTR_ERR(handle);
break;
}
- ret = ext4_get_blocks_wrap(handle, inode, block,
- max_blocks, &map_bh,
- EXT4_CREATE_UNINITIALIZED_EXT, 0, 0);
+ map_bh.b_state = 0;
+ ret = ext4_get_blocks(handle, inode, block,
+ max_blocks, &map_bh,
+ EXT4_GET_BLOCKS_CREATE_UNINIT_EXT);
if (ret <= 0) {
#ifdef EXT4FS_DEBUG
WARN_ON(ret <= 0);
@@ -3186,7 +3189,7 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path,
void *data)
{
struct fiemap_extent_info *fieinfo = data;
- unsigned long blksize_bits = inode->i_sb->s_blocksize_bits;
+ unsigned char blksize_bits = inode->i_sb->s_blocksize_bits;
__u64 logical;
__u64 physical;
__u64 length;
@@ -3233,9 +3236,16 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path,
*
* XXX this might miss a single-block extent at EXT_MAX_BLOCK
*/
- if (logical + length - 1 == EXT_MAX_BLOCK ||
- ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK)
+ if (ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK ||
+ newex->ec_block + newex->ec_len - 1 == EXT_MAX_BLOCK) {
+ loff_t size = i_size_read(inode);
+ loff_t bs = EXT4_BLOCK_SIZE(inode->i_sb);
+
flags |= FIEMAP_EXTENT_LAST;
+ if ((flags & FIEMAP_EXTENT_DELALLOC) &&
+ logical+length > size)
+ length = (size - logical + bs - 1) & ~(bs-1);
+ }
error = fiemap_fill_next_extent(fieinfo, logical, physical,
length, flags);
diff --git a/fs/ext4/group.h b/fs/ext4/group.h
deleted file mode 100644
index c2c0a8d06d0e..000000000000
--- a/fs/ext4/group.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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 *ext4_read_block_bitmap(struct super_block *sb,
- ext4_group_t block_group);
-extern unsigned ext4_init_block_bitmap(struct super_block *sb,
- struct buffer_head *bh,
- ext4_group_t 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,
- ext4_group_t 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 f18e0a08a6b5..82f7d1d7eae0 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -27,7 +27,6 @@
#include "ext4_jbd2.h"
#include "xattr.h"
#include "acl.h"
-#include "group.h"
/*
* ialloc.c contains the inodes allocation and deallocation routines
@@ -123,16 +122,16 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
unlock_buffer(bh);
return bh;
}
- spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_lock_group(sb, block_group);
if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
ext4_init_inode_bitmap(sb, bh, block_group, desc);
set_bitmap_uptodate(bh);
set_buffer_uptodate(bh);
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_unlock_group(sb, block_group);
unlock_buffer(bh);
return bh;
}
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_unlock_group(sb, block_group);
if (buffer_uptodate(bh)) {
/*
* if not uninit if bh is uptodate,
@@ -247,9 +246,8 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
goto error_return;
/* Ok, now we can actually update the inode bitmaps.. */
- spin_lock(sb_bgl_lock(sbi, block_group));
- cleared = ext4_clear_bit(bit, bitmap_bh->b_data);
- spin_unlock(sb_bgl_lock(sbi, block_group));
+ cleared = ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group),
+ bit, bitmap_bh->b_data);
if (!cleared)
ext4_error(sb, "ext4_free_inode",
"bit already cleared for inode %lu", ino);
@@ -261,7 +259,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
if (fatal) goto error_return;
if (gdp) {
- spin_lock(sb_bgl_lock(sbi, block_group));
+ ext4_lock_group(sb, block_group);
count = ext4_free_inodes_count(sb, gdp) + 1;
ext4_free_inodes_set(sb, gdp, count);
if (is_directory) {
@@ -277,7 +275,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
}
gdp->bg_checksum = ext4_group_desc_csum(sbi,
block_group, gdp);
- spin_unlock(sb_bgl_lock(sbi, block_group));
+ ext4_unlock_group(sb, block_group);
percpu_counter_inc(&sbi->s_freeinodes_counter);
if (is_directory)
percpu_counter_dec(&sbi->s_dirs_counter);
@@ -316,7 +314,7 @@ error_return:
static int find_group_dir(struct super_block *sb, struct inode *parent,
ext4_group_t *best_group)
{
- ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
+ ext4_group_t ngroups = ext4_get_groups_count(sb);
unsigned int freei, avefreei;
struct ext4_group_desc *desc, *best_desc = NULL;
ext4_group_t group;
@@ -353,7 +351,7 @@ static int find_group_flex(struct super_block *sb, struct inode *parent,
struct flex_groups *flex_group = sbi->s_flex_groups;
ext4_group_t parent_group = EXT4_I(parent)->i_block_group;
ext4_group_t parent_fbg_group = ext4_flex_group(sbi, parent_group);
- ext4_group_t ngroups = sbi->s_groups_count;
+ ext4_group_t ngroups = ext4_get_groups_count(sb);
int flex_size = ext4_flex_bg_size(sbi);
ext4_group_t best_flex = parent_fbg_group;
int blocks_per_flex = sbi->s_blocks_per_group * flex_size;
@@ -362,7 +360,7 @@ static int find_group_flex(struct super_block *sb, struct inode *parent,
ext4_group_t n_fbg_groups;
ext4_group_t i;
- n_fbg_groups = (sbi->s_groups_count + flex_size - 1) >>
+ n_fbg_groups = (ngroups + flex_size - 1) >>
sbi->s_log_groups_per_flex;
find_close_to_parent:
@@ -478,20 +476,21 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
{
ext4_group_t parent_group = EXT4_I(parent)->i_block_group;
struct ext4_sb_info *sbi = EXT4_SB(sb);
- ext4_group_t ngroups = sbi->s_groups_count;
+ ext4_group_t real_ngroups = ext4_get_groups_count(sb);
int inodes_per_group = EXT4_INODES_PER_GROUP(sb);
unsigned int freei, avefreei;
ext4_fsblk_t freeb, avefreeb;
unsigned int ndirs;
int max_dirs, min_inodes;
ext4_grpblk_t min_blocks;
- ext4_group_t i, grp, g;
+ ext4_group_t i, grp, g, ngroups;
struct ext4_group_desc *desc;
struct orlov_stats stats;
int flex_size = ext4_flex_bg_size(sbi);
+ ngroups = real_ngroups;
if (flex_size > 1) {
- ngroups = (ngroups + flex_size - 1) >>
+ ngroups = (real_ngroups + flex_size - 1) >>
sbi->s_log_groups_per_flex;
parent_group >>= sbi->s_log_groups_per_flex;
}
@@ -543,7 +542,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
*/
grp *= flex_size;
for (i = 0; i < flex_size; i++) {
- if (grp+i >= sbi->s_groups_count)
+ if (grp+i >= real_ngroups)
break;
desc = ext4_get_group_desc(sb, grp+i, NULL);
if (desc && ext4_free_inodes_count(sb, desc)) {
@@ -583,7 +582,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
}
fallback:
- ngroups = sbi->s_groups_count;
+ ngroups = real_ngroups;
avefreei = freei / ngroups;
fallback_retry:
parent_group = EXT4_I(parent)->i_block_group;
@@ -613,9 +612,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
ext4_group_t *group, int mode)
{
ext4_group_t parent_group = EXT4_I(parent)->i_block_group;
- ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
+ ext4_group_t i, last, ngroups = ext4_get_groups_count(sb);
struct ext4_group_desc *desc;
- ext4_group_t i, last;
int flex_size = ext4_flex_bg_size(EXT4_SB(sb));
/*
@@ -708,10 +706,10 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
/*
* claim the inode from the inode bitmap. If the group
- * is uninit we need to take the groups's sb_bgl_lock
+ * is uninit we need to take the groups's ext4_group_lock
* and clear the uninit flag. The inode bitmap update
* and group desc uninit flag clear should be done
- * after holding sb_bgl_lock so that ext4_read_inode_bitmap
+ * after holding ext4_group_lock so that ext4_read_inode_bitmap
* doesn't race with the ext4_claim_inode
*/
static int ext4_claim_inode(struct super_block *sb,
@@ -722,7 +720,7 @@ static int ext4_claim_inode(struct super_block *sb,
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL);
- spin_lock(sb_bgl_lock(sbi, group));
+ ext4_lock_group(sb, group);
if (ext4_set_bit(ino, inode_bitmap_bh->b_data)) {
/* not a free inode */
retval = 1;
@@ -731,7 +729,7 @@ static int ext4_claim_inode(struct super_block *sb,
ino++;
if ((group == 0 && ino < EXT4_FIRST_INO(sb)) ||
ino > EXT4_INODES_PER_GROUP(sb)) {
- spin_unlock(sb_bgl_lock(sbi, group));
+ ext4_unlock_group(sb, group);
ext4_error(sb, __func__,
"reserved inode or inode > inodes count - "
"block_group = %u, inode=%lu", group,
@@ -780,7 +778,7 @@ static int ext4_claim_inode(struct super_block *sb,
}
gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
err_ret:
- spin_unlock(sb_bgl_lock(sbi, group));
+ ext4_unlock_group(sb, group);
return retval;
}
@@ -799,11 +797,10 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
struct super_block *sb;
struct buffer_head *inode_bitmap_bh = NULL;
struct buffer_head *group_desc_bh;
- ext4_group_t group = 0;
+ ext4_group_t ngroups, group = 0;
unsigned long ino = 0;
struct inode *inode;
struct ext4_group_desc *gdp = NULL;
- struct ext4_super_block *es;
struct ext4_inode_info *ei;
struct ext4_sb_info *sbi;
int ret2, err = 0;
@@ -818,15 +815,14 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
return ERR_PTR(-EPERM);
sb = dir->i_sb;
+ ngroups = ext4_get_groups_count(sb);
trace_mark(ext4_request_inode, "dev %s dir %lu mode %d", sb->s_id,
dir->i_ino, mode);
inode = new_inode(sb);
if (!inode)
return ERR_PTR(-ENOMEM);
ei = EXT4_I(inode);
-
sbi = EXT4_SB(sb);
- es = sbi->s_es;
if (sbi->s_log_groups_per_flex && test_opt(sb, OLDALLOC)) {
ret2 = find_group_flex(sb, dir, &group);
@@ -856,7 +852,7 @@ got_group:
if (ret2 == -1)
goto out;
- for (i = 0; i < sbi->s_groups_count; i++) {
+ for (i = 0; i < ngroups; i++) {
err = -EIO;
gdp = ext4_get_group_desc(sb, group, &group_desc_bh);
@@ -917,7 +913,7 @@ repeat_in_this_group:
* group descriptor metadata has not yet been updated.
* So we just go onto the next blockgroup.
*/
- if (++group == sbi->s_groups_count)
+ if (++group == ngroups)
group = 0;
}
err = -ENOSPC;
@@ -938,7 +934,7 @@ got:
}
free = 0;
- spin_lock(sb_bgl_lock(sbi, group));
+ ext4_lock_group(sb, group);
/* recheck and clear flag under lock if we still need to */
if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
free = ext4_free_blocks_after_init(sb, group, gdp);
@@ -947,7 +943,7 @@ got:
gdp->bg_checksum = ext4_group_desc_csum(sbi, group,
gdp);
}
- spin_unlock(sb_bgl_lock(sbi, group));
+ ext4_unlock_group(sb, group);
/* Don't need to dirty bitmap block if we didn't change it */
if (free) {
@@ -1158,7 +1154,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
{
unsigned long desc_count;
struct ext4_group_desc *gdp;
- ext4_group_t i;
+ ext4_group_t i, ngroups = ext4_get_groups_count(sb);
#ifdef EXT4FS_DEBUG
struct ext4_super_block *es;
unsigned long bitmap_count, x;
@@ -1168,7 +1164,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
desc_count = 0;
bitmap_count = 0;
gdp = NULL;
- for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
+ for (i = 0; i < ngroups; i++) {
gdp = ext4_get_group_desc(sb, i, NULL);
if (!gdp)
continue;
@@ -1190,7 +1186,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
return desc_count;
#else
desc_count = 0;
- for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
+ for (i = 0; i < ngroups; i++) {
gdp = ext4_get_group_desc(sb, i, NULL);
if (!gdp)
continue;
@@ -1205,9 +1201,9 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
unsigned long ext4_count_dirs(struct super_block * sb)
{
unsigned long count = 0;
- ext4_group_t i;
+ ext4_group_t i, ngroups = ext4_get_groups_count(sb);
- for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
+ for (i = 0; i < ngroups; i++) {
struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL);
if (!gdp)
continue;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index e91f978c7f12..73241048795d 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -892,6 +892,10 @@ err_out:
}
/*
+ * The ext4_ind_get_blocks() function handles non-extents inodes
+ * (i.e., using the traditional indirect/double-indirect i_blocks
+ * scheme) for ext4_get_blocks().
+ *
* Allocation strategy is simple: if we have to allocate something, we will
* have to go the whole way to leaf. So let's do it before attaching anything
* to tree, set linkage between the newborn blocks, write them if sync is
@@ -909,15 +913,16 @@ err_out:
* return = 0, if plain lookup failed.
* return < 0, error case.
*
- *
- * Need to be called with
- * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
- * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
+ * The ext4_ind_get_blocks() function should be called with
+ * down_write(&EXT4_I(inode)->i_data_sem) if allocating filesystem
+ * blocks (i.e., flags has EXT4_GET_BLOCKS_CREATE set) or
+ * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system
+ * blocks.
*/
-static int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
+static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode,
ext4_lblk_t iblock, unsigned int maxblocks,
struct buffer_head *bh_result,
- int create, int extend_disksize)
+ int flags)
{
int err = -EIO;
ext4_lblk_t offsets[4];
@@ -934,7 +939,7 @@ static int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL));
- J_ASSERT(handle != NULL || create == 0);
+ J_ASSERT(handle != NULL || (flags & EXT4_GET_BLOCKS_CREATE) == 0);
depth = ext4_block_to_path(inode, iblock, offsets,
&blocks_to_boundary);
@@ -963,7 +968,7 @@ static int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
}
/* Next simple case - plain lookup or failed read of indirect block */
- if (!create || err == -EIO)
+ if ((flags & EXT4_GET_BLOCKS_CREATE) == 0 || err == -EIO)
goto cleanup;
/*
@@ -1002,7 +1007,7 @@ static int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
* protect it if you're about to implement concurrent
* ext4_get_block() -bzzz
*/
- if (!err && extend_disksize) {
+ if (!err && (flags & EXT4_GET_BLOCKS_EXTEND_DISKSIZE)) {
disksize = ((loff_t) iblock + count) << inode->i_blkbits;
if (disksize > i_size_read(inode))
disksize = i_size_read(inode);
@@ -1121,7 +1126,7 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used)
}
/*
- * The ext4_get_blocks_wrap() function try to look up the requested blocks,
+ * The ext4_get_blocks() function tries to look up the requested blocks,
* and returns if the blocks are already mapped.
*
* Otherwise it takes the write lock of the i_data_sem and allocate blocks
@@ -1129,7 +1134,7 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used)
* mapped.
*
* If file type is extents based, it will call ext4_ext_get_blocks(),
- * Otherwise, call with ext4_get_blocks_handle() to handle indirect mapping
+ * Otherwise, call with ext4_ind_get_blocks() to handle indirect mapping
* based files
*
* On success, it returns the number of blocks being mapped or allocate.
@@ -1142,13 +1147,14 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used)
*
* It returns the error in case of allocation failure.
*/
-int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
- unsigned int max_blocks, struct buffer_head *bh,
- int create, int extend_disksize, int flag)
+int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
+ unsigned int max_blocks, struct buffer_head *bh,
+ int flags)
{
int retval;
clear_buffer_mapped(bh);
+ clear_buffer_unwritten(bh);
/*
* Try to see if we can get the block without requesting
@@ -1157,15 +1163,15 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
down_read((&EXT4_I(inode)->i_data_sem));
if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
retval = ext4_ext_get_blocks(handle, inode, block, max_blocks,
- bh, 0, 0);
+ bh, 0);
} else {
- retval = ext4_get_blocks_handle(handle,
- inode, block, max_blocks, bh, 0, 0);
+ retval = ext4_ind_get_blocks(handle, inode, block, max_blocks,
+ bh, 0);
}
up_read((&EXT4_I(inode)->i_data_sem));
/* If it is only a block(s) look up */
- if (!create)
+ if ((flags & EXT4_GET_BLOCKS_CREATE) == 0)
return retval;
/*
@@ -1179,6 +1185,18 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
return retval;
/*
+ * When we call get_blocks without the create flag, the
+ * BH_Unwritten flag could have gotten set if the blocks
+ * requested were part of a uninitialized extent. We need to
+ * clear this flag now that we are committed to convert all or
+ * part of the uninitialized extent to be an initialized
+ * extent. This is because we need to avoid the combination
+ * of BH_Unwritten and BH_Mapped flags being simultaneously
+ * set on the buffer_head.
+ */
+ clear_buffer_unwritten(bh);
+
+ /*
* New blocks allocate and/or writing to uninitialized extent
* will possibly result in updating i_data, so we take
* the write lock of i_data_sem, and call get_blocks()
@@ -1192,7 +1210,7 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
* let the underlying get_block() function know to
* avoid double accounting
*/
- if (flag)
+ if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
EXT4_I(inode)->i_delalloc_reserved_flag = 1;
/*
* We need to check for EXT4 here because migrate
@@ -1200,10 +1218,10 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
*/
if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
retval = ext4_ext_get_blocks(handle, inode, block, max_blocks,
- bh, create, extend_disksize);
+ bh, flags);
} else {
- retval = ext4_get_blocks_handle(handle, inode, block,
- max_blocks, bh, create, extend_disksize);
+ retval = ext4_ind_get_blocks(handle, inode, block,
+ max_blocks, bh, flags);
if (retval > 0 && buffer_new(bh)) {
/*
@@ -1216,7 +1234,7 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
}
}
- if (flag) {
+ if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) {
EXT4_I(inode)->i_delalloc_reserved_flag = 0;
/*
* Update reserved blocks/metadata blocks
@@ -1255,8 +1273,8 @@ int ext4_get_block(struct inode *inode, sector_t iblock,
started = 1;
}
- ret = ext4_get_blocks_wrap(handle, inode, iblock,
- max_blocks, bh_result, create, 0, 0);
+ ret = ext4_get_blocks(handle, inode, iblock, max_blocks, bh_result,
+ create ? EXT4_GET_BLOCKS_CREATE : 0);
if (ret > 0) {
bh_result->b_size = (ret << inode->i_blkbits);
ret = 0;
@@ -1275,17 +1293,19 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
{
struct buffer_head dummy;
int fatal = 0, err;
+ int flags = EXT4_GET_BLOCKS_EXTEND_DISKSIZE;
J_ASSERT(handle != NULL || create == 0);
dummy.b_state = 0;
dummy.b_blocknr = -1000;
buffer_trace_init(&dummy.b_history);
- err = ext4_get_blocks_wrap(handle, inode, block, 1,
- &dummy, create, 1, 0);
+ if (create)
+ flags |= EXT4_GET_BLOCKS_CREATE;
+ err = ext4_get_blocks(handle, inode, block, 1, &dummy, flags);
/*
- * ext4_get_blocks_handle() returns number of blocks
- * mapped. 0 in case of a HOLE.
+ * ext4_get_blocks() returns number of blocks mapped. 0 in
+ * case of a HOLE.
*/
if (err > 0) {
if (err > 1)
@@ -1839,7 +1859,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd)
* @logical - first logical block to start assignment with
*
* the function goes through all passed space and put actual disk
- * block numbers into buffer heads, dropping BH_Delay
+ * block numbers into buffer heads, dropping BH_Delay and BH_Unwritten
*/
static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical,
struct buffer_head *exbh)
@@ -1889,16 +1909,24 @@ static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical,
do {
if (cur_logical >= logical + blocks)
break;
- if (buffer_delay(bh)) {
- bh->b_blocknr = pblock;
- clear_buffer_delay(bh);
- bh->b_bdev = inode->i_sb->s_bdev;
- } else if (buffer_unwritten(bh)) {
- bh->b_blocknr = pblock;
- clear_buffer_unwritten(bh);
- set_buffer_mapped(bh);
- set_buffer_new(bh);
- bh->b_bdev = inode->i_sb->s_bdev;
+
+ if (buffer_delay(bh) ||
+ buffer_unwritten(bh)) {
+
+ BUG_ON(bh->b_bdev != inode->i_sb->s_bdev);
+
+ if (buffer_delay(bh)) {
+ clear_buffer_delay(bh);
+ bh->b_blocknr = pblock;
+ } else {
+ /*
+ * unwritten already should have
+ * blocknr assigned. Verify that
+ */
+ clear_buffer_unwritten(bh);
+ BUG_ON(bh->b_blocknr != pblock);
+ }
+
} else if (buffer_mapped(bh))
BUG_ON(bh->b_blocknr != pblock);
@@ -1977,9 +2005,14 @@ static void ext4_print_free_blocks(struct inode *inode)
return;
}
-#define EXT4_DELALLOC_RSVED 1
+/*
+ * This function is used by mpage_da_map_blocks(). We separate it out
+ * as a separate function just to make life easier, and because
+ * mpage_da_map_blocks() used to be a generic function that took a
+ * get_block_t.
+ */
static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,
- struct buffer_head *bh_result, int create)
+ struct buffer_head *bh_result)
{
int ret;
unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
@@ -1988,8 +2021,9 @@ static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,
handle = ext4_journal_current_handle();
BUG_ON(!handle);
- ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks,
- bh_result, create, 0, EXT4_DELALLOC_RSVED);
+ ret = ext4_get_blocks(handle, inode, iblock, max_blocks,
+ bh_result, EXT4_GET_BLOCKS_CREATE|
+ EXT4_GET_BLOCKS_DELALLOC_RESERVE);
if (ret <= 0)
return ret;
@@ -2008,8 +2042,8 @@ static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,
/*
* Update on-disk size along with block allocation we don't
- * use 'extend_disksize' as size may change within already
- * allocated block -bzzz
+ * use EXT4_GET_BLOCKS_EXTEND_DISKSIZE as size may change
+ * within already allocated block -bzzz
*/
disksize = ((loff_t) iblock + ret) << inode->i_blkbits;
if (disksize > i_size_read(inode))
@@ -2040,9 +2074,23 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
* We consider only non-mapped and non-allocated blocks
*/
if ((mpd->b_state & (1 << BH_Mapped)) &&
- !(mpd->b_state & (1 << BH_Delay)))
+ !(mpd->b_state & (1 << BH_Delay)) &&
+ !(mpd->b_state & (1 << BH_Unwritten)))
return 0;
- new.b_state = mpd->b_state;
+ /*
+ * We need to make sure the BH_Delay flag is passed down to
+ * ext4_da_get_block_write(), since it calls
+ * ext4_get_blocks_wrap() with the EXT4_DELALLOC_RSVED flag.
+ * This flag causes ext4_get_blocks_wrap() to call
+ * ext4_da_update_reserve_space() if the passed buffer head
+ * has the BH_Delay flag set. In the future, once we clean up
+ * the interfaces to ext4_get_blocks_wrap(), we should pass in
+ * a separate flag which requests that the delayed allocation
+ * statistics should be updated, instead of depending on the
+ * state information getting passed down via the map_bh's
+ * state bitmasks plus the magic EXT4_DELALLOC_RSVED flag.
+ */
+ new.b_state = mpd->b_state & (1 << BH_Delay);
new.b_blocknr = 0;
new.b_size = mpd->b_size;
next = mpd->b_blocknr;
@@ -2053,7 +2101,7 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
if (!new.b_size)
return 0;
- err = ext4_da_get_block_write(mpd->inode, next, &new, 1);
+ err = ext4_da_get_block_write(mpd->inode, next, &new);
if (err) {
/*
* If get block returns with error we simply
@@ -2179,6 +2227,17 @@ flush_it:
return;
}
+static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh)
+{
+ /*
+ * unmapped buffer is possible for holes.
+ * delay buffer is possible with delayed allocation.
+ * We also need to consider unwritten buffer as unmapped.
+ */
+ return (!buffer_mapped(bh) || buffer_delay(bh) ||
+ buffer_unwritten(bh)) && buffer_dirty(bh);
+}
+
/*
* __mpage_da_writepage - finds extent of pages and blocks
*
@@ -2263,8 +2322,7 @@ static int __mpage_da_writepage(struct page *page,
* Otherwise we won't make progress
* with the page in ext4_da_writepage
*/
- if (buffer_dirty(bh) &&
- (!buffer_mapped(bh) || buffer_delay(bh))) {
+ if (ext4_bh_unmapped_or_delay(NULL, bh)) {
mpage_add_bh_to_extent(mpd, logical,
bh->b_size,
bh->b_state);
@@ -2290,13 +2348,25 @@ static int __mpage_da_writepage(struct page *page,
}
/*
- * this is a special callback for ->write_begin() only
- * it's intention is to return mapped block or reserve space
+ * This is a special get_blocks_t callback which is used by
+ * ext4_da_write_begin(). It will either return mapped block or
+ * reserve space for a single block.
+ *
+ * For delayed buffer_head we have BH_Mapped, BH_New, BH_Delay set.
+ * We also have b_blocknr = -1 and b_bdev initialized properly
+ *
+ * For unwritten buffer_head we have BH_Mapped, BH_New, BH_Unwritten set.
+ * We also have b_blocknr = physicalblock mapping unwritten extent and b_bdev
+ * initialized properly.
*/
static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
int ret = 0;
+ sector_t invalid_block = ~((sector_t) 0xffff);
+
+ if (invalid_block < ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es))
+ invalid_block = ~0;
BUG_ON(create == 0);
BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize);
@@ -2306,7 +2376,7 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
* preallocated blocks are unmapped but should treated
* the same as allocated blocks.
*/
- ret = ext4_get_blocks_wrap(NULL, inode, iblock, 1, bh_result, 0, 0, 0);
+ ret = ext4_get_blocks(NULL, inode, iblock, 1, bh_result, 0);
if ((ret == 0) && !buffer_delay(bh_result)) {
/* the block isn't (pre)allocated yet, let's reserve space */
/*
@@ -2318,38 +2388,58 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
/* not enough space to reserve */
return ret;
- map_bh(bh_result, inode->i_sb, 0);
+ map_bh(bh_result, inode->i_sb, invalid_block);
set_buffer_new(bh_result);
set_buffer_delay(bh_result);
} else if (ret > 0) {
bh_result->b_size = (ret << inode->i_blkbits);
+ if (buffer_unwritten(bh_result)) {
+ /* A delayed write to unwritten bh should
+ * be marked new and mapped. Mapped ensures
+ * that we don't do get_block multiple times
+ * when we write to the same offset and new
+ * ensures that we do proper zero out for
+ * partial write.
+ */
+ set_buffer_new(bh_result);
+ set_buffer_mapped(bh_result);
+ }
ret = 0;
}
return ret;
}
-static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh)
-{
- /*
- * unmapped buffer is possible for holes.
- * delay buffer is possible with delayed allocation
- */
- return ((!buffer_mapped(bh) || buffer_delay(bh)) && buffer_dirty(bh));
-}
-
-static int ext4_normal_get_block_write(struct inode *inode, sector_t iblock,
+/*
+ * This function is used as a standard get_block_t calback function
+ * when there is no desire to allocate any blocks. It is used as a
+ * callback function for block_prepare_write(), nobh_writepage(), and
+ * block_write_full_page(). These functions should only try to map a
+ * single block at a time.
+ *
+ * Since this function doesn't do block allocations even if the caller
+ * requests it by passing in create=1, it is critically important that
+ * any caller checks to make sure that any buffer heads are returned
+ * by this function are either all already mapped or marked for
+ * delayed allocation before calling nobh_writepage() or
+ * block_write_full_page(). Otherwise, b_blocknr could be left
+ * unitialized, and the page write functions will be taken by
+ * surprise.
+ */
+static int noalloc_get_block_write(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
int ret = 0;
unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
+ BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize);
+
/*
* we don't want to do block allocation in writepage
* so call get_block_wrap with create = 0
*/
- ret = ext4_get_blocks_wrap(NULL, inode, iblock, max_blocks,
- bh_result, 0, 0, 0);
+ ret = ext4_get_blocks(NULL, inode, iblock, max_blocks, bh_result, 0);
+ BUG_ON(create && ret == 0);
if (ret > 0) {
bh_result->b_size = (ret << inode->i_blkbits);
ret = 0;
@@ -2412,7 +2502,7 @@ static int ext4_da_writepage(struct page *page,
* do block allocation here.
*/
ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE,
- ext4_normal_get_block_write);
+ noalloc_get_block_write);
if (!ret) {
page_bufs = page_buffers(page);
/* check whether all are mapped and non delay */
@@ -2437,11 +2527,10 @@ static int ext4_da_writepage(struct page *page,
}
if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
- ret = nobh_writepage(page, ext4_normal_get_block_write, wbc);
+ ret = nobh_writepage(page, noalloc_get_block_write, wbc);
else
- ret = block_write_full_page(page,
- ext4_normal_get_block_write,
- wbc);
+ ret = block_write_full_page(page, noalloc_get_block_write,
+ wbc);
return ret;
}
@@ -2753,7 +2842,7 @@ retry:
*pagep = page;
ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- ext4_da_get_block_prep);
+ ext4_da_get_block_prep);
if (ret < 0) {
unlock_page(page);
ext4_journal_stop(handle);
@@ -2791,7 +2880,7 @@ static int ext4_da_should_update_i_disksize(struct page *page,
for (i = 0; i < idx; i++)
bh = bh->b_this_page;
- if (!buffer_mapped(bh) || (buffer_delay(bh)))
+ if (!buffer_mapped(bh) || (buffer_delay(bh)) || buffer_unwritten(bh))
return 0;
return 1;
}
@@ -3061,12 +3150,10 @@ static int __ext4_normal_writepage(struct page *page,
struct inode *inode = page->mapping->host;
if (test_opt(inode->i_sb, NOBH))
- return nobh_writepage(page,
- ext4_normal_get_block_write, wbc);
+ return nobh_writepage(page, noalloc_get_block_write, wbc);
else
- return block_write_full_page(page,
- ext4_normal_get_block_write,
- wbc);
+ return block_write_full_page(page, noalloc_get_block_write,
+ wbc);
}
static int ext4_normal_writepage(struct page *page,
@@ -3118,7 +3205,7 @@ static int __ext4_journalled_writepage(struct page *page,
int err;
ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE,
- ext4_normal_get_block_write);
+ noalloc_get_block_write);
if (ret != 0)
goto out_unlock;
@@ -3203,9 +3290,8 @@ static int ext4_journalled_writepage(struct page *page,
* really know unless we go poke around in the buffer_heads.
* But block_write_full_page will do the right thing.
*/
- return block_write_full_page(page,
- ext4_normal_get_block_write,
- wbc);
+ return block_write_full_page(page, noalloc_get_block_write,
+ wbc);
}
no_write:
redirty_page_for_writepage(wbc, page);
@@ -4906,7 +4992,8 @@ static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
*/
int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk)
{
- int groups, gdpblocks;
+ ext4_group_t groups, ngroups = ext4_get_groups_count(inode->i_sb);
+ int gdpblocks;
int idxblocks;
int ret = 0;
@@ -4933,8 +5020,8 @@ int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk)
groups += nrblocks;
gdpblocks = groups;
- if (groups > EXT4_SB(inode->i_sb)->s_groups_count)
- groups = EXT4_SB(inode->i_sb)->s_groups_count;
+ if (groups > ngroups)
+ groups = ngroups;
if (groups > EXT4_SB(inode->i_sb)->s_gdb_count)
gdpblocks = EXT4_SB(inode->i_sb)->s_gdb_count;
@@ -4974,7 +5061,7 @@ int ext4_writepage_trans_blocks(struct inode *inode)
* Calculate the journal credits for a chunk of data modification.
*
* This is called from DIO, fallocate or whoever calling
- * ext4_get_blocks_wrap() to map/allocate a chunk of contigous disk blocks.
+ * ext4_get_blocks() to map/allocate a chunk of contigous disk blocks.
*
* journal buffers for data blocks are not included here, as DIO
* and fallocate do no need to journal data buffers.
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index f871677a7984..e76459cedcdb 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -372,24 +372,12 @@ static inline void mb_set_bit(int bit, void *addr)
ext4_set_bit(bit, addr);
}
-static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr)
-{
- addr = mb_correct_addr_and_bit(&bit, addr);
- ext4_set_bit_atomic(lock, bit, addr);
-}
-
static inline void mb_clear_bit(int bit, void *addr)
{
addr = mb_correct_addr_and_bit(&bit, addr);
ext4_clear_bit(bit, addr);
}
-static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr)
-{
- addr = mb_correct_addr_and_bit(&bit, addr);
- ext4_clear_bit_atomic(lock, bit, addr);
-}
-
static inline int mb_find_next_zero_bit(void *addr, int max, int start)
{
int fix = 0, ret, tmpmax;
@@ -739,6 +727,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb,
static int ext4_mb_init_cache(struct page *page, char *incore)
{
+ ext4_group_t ngroups;
int blocksize;
int blocks_per_page;
int groups_per_page;
@@ -757,6 +746,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
inode = page->mapping->host;
sb = inode->i_sb;
+ ngroups = ext4_get_groups_count(sb);
blocksize = 1 << inode->i_blkbits;
blocks_per_page = PAGE_CACHE_SIZE / blocksize;
@@ -780,7 +770,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
for (i = 0; i < groups_per_page; i++) {
struct ext4_group_desc *desc;
- if (first_group + i >= EXT4_SB(sb)->s_groups_count)
+ if (first_group + i >= ngroups)
break;
err = -EIO;
@@ -801,17 +791,17 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
unlock_buffer(bh[i]);
continue;
}
- spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
+ ext4_lock_group(sb, first_group + i);
if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
ext4_init_block_bitmap(sb, bh[i],
first_group + i, desc);
set_bitmap_uptodate(bh[i]);
set_buffer_uptodate(bh[i]);
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
+ ext4_unlock_group(sb, first_group + i);
unlock_buffer(bh[i]);
continue;
}
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
+ ext4_unlock_group(sb, first_group + i);
if (buffer_uptodate(bh[i])) {
/*
* if not uninit if bh is uptodate,
@@ -852,7 +842,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
struct ext4_group_info *grinfo;
group = (first_block + i) >> 1;
- if (group >= EXT4_SB(sb)->s_groups_count)
+ if (group >= ngroups)
break;
/*
@@ -1078,7 +1068,7 @@ static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
return 0;
}
-static void mb_clear_bits(spinlock_t *lock, void *bm, int cur, int len)
+static void mb_clear_bits(void *bm, int cur, int len)
{
__u32 *addr;
@@ -1091,15 +1081,12 @@ static void mb_clear_bits(spinlock_t *lock, void *bm, int cur, int len)
cur += 32;
continue;
}
- if (lock)
- mb_clear_bit_atomic(lock, cur, bm);
- else
- mb_clear_bit(cur, bm);
+ mb_clear_bit(cur, bm);
cur++;
}
}
-static void mb_set_bits(spinlock_t *lock, void *bm, int cur, int len)
+static void mb_set_bits(void *bm, int cur, int len)
{
__u32 *addr;
@@ -1112,10 +1099,7 @@ static void mb_set_bits(spinlock_t *lock, void *bm, int cur, int len)
cur += 32;
continue;
}
- if (lock)
- mb_set_bit_atomic(lock, cur, bm);
- else
- mb_set_bit(cur, bm);
+ mb_set_bit(cur, bm);
cur++;
}
}
@@ -1330,8 +1314,7 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
e4b->bd_info->bb_counters[ord]++;
}
- mb_set_bits(sb_bgl_lock(EXT4_SB(e4b->bd_sb), ex->fe_group),
- EXT4_MB_BITMAP(e4b), ex->fe_start, len0);
+ mb_set_bits(EXT4_MB_BITMAP(e4b), ex->fe_start, len0);
mb_check_buddy(e4b);
return ret;
@@ -1726,7 +1709,6 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac,
unsigned free, fragments;
unsigned i, bits;
int flex_size = ext4_flex_bg_size(EXT4_SB(ac->ac_sb));
- struct ext4_group_desc *desc;
struct ext4_group_info *grp = ext4_get_group_info(ac->ac_sb, group);
BUG_ON(cr < 0 || cr >= 4);
@@ -1742,10 +1724,6 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac,
switch (cr) {
case 0:
BUG_ON(ac->ac_2order == 0);
- /* If this group is uninitialized, skip it initially */
- desc = ext4_get_group_desc(ac->ac_sb, group, NULL);
- if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))
- return 0;
/* Avoid using the first bg of a flexgroup for data files */
if ((ac->ac_flags & EXT4_MB_HINT_DATA) &&
@@ -1788,6 +1766,7 @@ int ext4_mb_get_buddy_cache_lock(struct super_block *sb, ext4_group_t group)
int block, pnum;
int blocks_per_page;
int groups_per_page;
+ ext4_group_t ngroups = ext4_get_groups_count(sb);
ext4_group_t first_group;
struct ext4_group_info *grp;
@@ -1807,7 +1786,7 @@ int ext4_mb_get_buddy_cache_lock(struct super_block *sb, ext4_group_t group)
/* read all groups the page covers into the cache */
for (i = 0; i < groups_per_page; i++) {
- if ((first_group + i) >= EXT4_SB(sb)->s_groups_count)
+ if ((first_group + i) >= ngroups)
break;
grp = ext4_get_group_info(sb, first_group + i);
/* take all groups write allocation
@@ -1945,8 +1924,7 @@ err:
static noinline_for_stack int
ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
{
- ext4_group_t group;
- ext4_group_t i;
+ ext4_group_t ngroups, group, i;
int cr;
int err = 0;
int bsbits;
@@ -1957,6 +1935,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
sb = ac->ac_sb;
sbi = EXT4_SB(sb);
+ ngroups = ext4_get_groups_count(sb);
BUG_ON(ac->ac_status == AC_STATUS_FOUND);
/* first, try the goal */
@@ -2017,11 +1996,11 @@ repeat:
*/
group = ac->ac_g_ex.fe_group;
- for (i = 0; i < EXT4_SB(sb)->s_groups_count; group++, i++) {
+ for (i = 0; i < ngroups; group++, i++) {
struct ext4_group_info *grp;
struct ext4_group_desc *desc;
- if (group == EXT4_SB(sb)->s_groups_count)
+ if (group == ngroups)
group = 0;
/* quick check to skip empty groups */
@@ -2064,9 +2043,7 @@ repeat:
ac->ac_groups_scanned++;
desc = ext4_get_group_desc(sb, group, NULL);
- if (cr == 0 || (desc->bg_flags &
- cpu_to_le16(EXT4_BG_BLOCK_UNINIT) &&
- ac->ac_2order != 0))
+ if (cr == 0)
ext4_mb_simple_scan_group(ac, &e4b);
else if (cr == 1 &&
ac->ac_g_ex.fe_len == sbi->s_stripe)
@@ -2315,12 +2292,10 @@ static struct file_operations ext4_mb_seq_history_fops = {
static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos)
{
struct super_block *sb = seq->private;
- struct ext4_sb_info *sbi = EXT4_SB(sb);
ext4_group_t group;
- if (*pos < 0 || *pos >= sbi->s_groups_count)
+ if (*pos < 0 || *pos >= ext4_get_groups_count(sb))
return NULL;
-
group = *pos + 1;
return (void *) ((unsigned long) group);
}
@@ -2328,11 +2303,10 @@ static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos)
static void *ext4_mb_seq_groups_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct super_block *sb = seq->private;
- struct ext4_sb_info *sbi = EXT4_SB(sb);
ext4_group_t group;
++*pos;
- if (*pos < 0 || *pos >= sbi->s_groups_count)
+ if (*pos < 0 || *pos >= ext4_get_groups_count(sb))
return NULL;
group = *pos + 1;
return (void *) ((unsigned long) group);
@@ -2420,7 +2394,8 @@ static void ext4_mb_history_release(struct super_block *sb)
if (sbi->s_proc != NULL) {
remove_proc_entry("mb_groups", sbi->s_proc);
- remove_proc_entry("mb_history", sbi->s_proc);
+ if (sbi->s_mb_history_max)
+ remove_proc_entry("mb_history", sbi->s_proc);
}
kfree(sbi->s_mb_history);
}
@@ -2431,17 +2406,17 @@ static void ext4_mb_history_init(struct super_block *sb)
int i;
if (sbi->s_proc != NULL) {
- proc_create_data("mb_history", S_IRUGO, sbi->s_proc,
- &ext4_mb_seq_history_fops, sb);
+ if (sbi->s_mb_history_max)
+ proc_create_data("mb_history", S_IRUGO, sbi->s_proc,
+ &ext4_mb_seq_history_fops, sb);
proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
&ext4_mb_seq_groups_fops, sb);
}
- sbi->s_mb_history_max = 1000;
sbi->s_mb_history_cur = 0;
spin_lock_init(&sbi->s_mb_history_lock);
i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history);
- sbi->s_mb_history = kzalloc(i, GFP_KERNEL);
+ sbi->s_mb_history = i ? kzalloc(i, GFP_KERNEL) : NULL;
/* if we can't allocate history, then we simple won't use it */
}
@@ -2451,7 +2426,7 @@ ext4_mb_store_history(struct ext4_allocation_context *ac)
struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
struct ext4_mb_history h;
- if (unlikely(sbi->s_mb_history == NULL))
+ if (sbi->s_mb_history == NULL)
return;
if (!(ac->ac_op & sbi->s_mb_history_filter))
@@ -2587,6 +2562,7 @@ void ext4_mb_update_group_info(struct ext4_group_info *grp, ext4_grpblk_t add)
static int ext4_mb_init_backend(struct super_block *sb)
{
+ ext4_group_t ngroups = ext4_get_groups_count(sb);
ext4_group_t i;
int metalen;
struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -2598,7 +2574,7 @@ static int ext4_mb_init_backend(struct super_block *sb)
struct ext4_group_desc *desc;
/* This is the number of blocks used by GDT */
- num_meta_group_infos = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) -
+ num_meta_group_infos = (ngroups + EXT4_DESC_PER_BLOCK(sb) -
1) >> EXT4_DESC_PER_BLOCK_BITS(sb);
/*
@@ -2644,7 +2620,7 @@ static int ext4_mb_init_backend(struct super_block *sb)
for (i = 0; i < num_meta_group_infos; i++) {
if ((i + 1) == num_meta_group_infos)
metalen = sizeof(*meta_group_info) *
- (sbi->s_groups_count -
+ (ngroups -
(i << EXT4_DESC_PER_BLOCK_BITS(sb)));
meta_group_info = kmalloc(metalen, GFP_KERNEL);
if (meta_group_info == NULL) {
@@ -2655,7 +2631,7 @@ static int ext4_mb_init_backend(struct super_block *sb)
sbi->s_group_info[i] = meta_group_info;
}
- for (i = 0; i < sbi->s_groups_count; i++) {
+ for (i = 0; i < ngroups; i++) {
desc = ext4_get_group_desc(sb, i, NULL);
if (desc == NULL) {
printk(KERN_ERR
@@ -2761,7 +2737,7 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
return 0;
}
-/* need to called with ext4 group lock (ext4_lock_group) */
+/* need to called with the ext4 group lock held */
static void ext4_mb_cleanup_pa(struct ext4_group_info *grp)
{
struct ext4_prealloc_space *pa;
@@ -2781,13 +2757,14 @@ static void ext4_mb_cleanup_pa(struct ext4_group_info *grp)
int ext4_mb_release(struct super_block *sb)
{
+ ext4_group_t ngroups = ext4_get_groups_count(sb);
ext4_group_t i;
int num_meta_group_infos;
struct ext4_group_info *grinfo;
struct ext4_sb_info *sbi = EXT4_SB(sb);
if (sbi->s_group_info) {
- for (i = 0; i < sbi->s_groups_count; i++) {
+ for (i = 0; i < ngroups; i++) {
grinfo = ext4_get_group_info(sb, i);
#ifdef DOUBLE_CHECK
kfree(grinfo->bb_bitmap);
@@ -2797,7 +2774,7 @@ int ext4_mb_release(struct super_block *sb)
ext4_unlock_group(sb, i);
kfree(grinfo);
}
- num_meta_group_infos = (sbi->s_groups_count +
+ num_meta_group_infos = (ngroups +
EXT4_DESC_PER_BLOCK(sb) - 1) >>
EXT4_DESC_PER_BLOCK_BITS(sb);
for (i = 0; i < num_meta_group_infos; i++)
@@ -2997,14 +2974,17 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
* Fix the bitmap and repeat the block allocation
* We leak some of the blocks here.
*/
- mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group),
- bitmap_bh->b_data, ac->ac_b_ex.fe_start,
- ac->ac_b_ex.fe_len);
+ ext4_lock_group(sb, ac->ac_b_ex.fe_group);
+ mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,
+ ac->ac_b_ex.fe_len);
+ ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
if (!err)
err = -EAGAIN;
goto out_err;
}
+
+ ext4_lock_group(sb, ac->ac_b_ex.fe_group);
#ifdef AGGRESSIVE_CHECK
{
int i;
@@ -3014,9 +2994,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
}
}
#endif
- spin_lock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
- mb_set_bits(NULL, bitmap_bh->b_data,
- ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len);
+ mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,ac->ac_b_ex.fe_len);
if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
ext4_free_blks_set(sb, gdp,
@@ -3026,7 +3004,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
len = ext4_free_blks_count(sb, gdp) - ac->ac_b_ex.fe_len;
ext4_free_blks_set(sb, gdp, len);
gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
- spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
+
+ ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len);
/*
* Now reduce the dirty block count also. Should not go negative
@@ -3459,7 +3438,7 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
* the function goes through all block freed in the group
* but not yet committed and marks them used in in-core bitmap.
* buddy must be generated from this bitmap
- * Need to be called with ext4 group lock (ext4_lock_group)
+ * Need to be called with the ext4 group lock held
*/
static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
ext4_group_t group)
@@ -3473,9 +3452,7 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
while (n) {
entry = rb_entry(n, struct ext4_free_data, node);
- mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group),
- bitmap, entry->start_blk,
- entry->count);
+ mb_set_bits(bitmap, entry->start_blk, entry->count);
n = rb_next(n);
}
return;
@@ -3484,7 +3461,7 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
/*
* the function goes through all preallocation in this group and marks them
* used in in-core bitmap. buddy must be generated from this bitmap
- * Need to be called with ext4 group lock (ext4_lock_group)
+ * Need to be called with ext4 group lock held
*/
static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
ext4_group_t group)
@@ -3516,8 +3493,7 @@ static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
if (unlikely(len == 0))
continue;
BUG_ON(groupnr != group);
- mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group),
- bitmap, start, len);
+ mb_set_bits(bitmap, start, len);
preallocated += len;
count++;
}
@@ -4121,7 +4097,7 @@ static void ext4_mb_return_to_preallocation(struct inode *inode,
static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
{
struct super_block *sb = ac->ac_sb;
- ext4_group_t i;
+ ext4_group_t ngroups, i;
printk(KERN_ERR "EXT4-fs: Can't allocate:"
" Allocation context details:\n");
@@ -4145,7 +4121,8 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
printk(KERN_ERR "EXT4-fs: %lu scanned, %d found\n", ac->ac_ex_scanned,
ac->ac_found);
printk(KERN_ERR "EXT4-fs: groups: \n");
- for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
+ ngroups = ext4_get_groups_count(sb);
+ for (i = 0; i < ngroups; i++) {
struct ext4_group_info *grp = ext4_get_group_info(sb, i);
struct ext4_prealloc_space *pa;
ext4_grpblk_t start;
@@ -4469,13 +4446,13 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac)
static int ext4_mb_discard_preallocations(struct super_block *sb, int needed)
{
- ext4_group_t i;
+ ext4_group_t i, ngroups = ext4_get_groups_count(sb);
int ret;
int freed = 0;
trace_mark(ext4_mb_discard_preallocations, "dev %s needed %d",
sb->s_id, needed);
- for (i = 0; i < EXT4_SB(sb)->s_groups_count && needed > 0; i++) {
+ for (i = 0; i < ngroups && needed > 0; i++) {
ret = ext4_mb_discard_group_preallocations(sb, i, needed);
freed += ret;
needed -= ret;
@@ -4859,29 +4836,25 @@ do_more:
new_entry->group = block_group;
new_entry->count = count;
new_entry->t_tid = handle->h_transaction->t_tid;
+
ext4_lock_group(sb, block_group);
- mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
- bit, count);
+ mb_clear_bits(bitmap_bh->b_data, bit, count);
ext4_mb_free_metadata(handle, &e4b, new_entry);
- ext4_unlock_group(sb, block_group);
} else {
- ext4_lock_group(sb, block_group);
/* need to update group_info->bb_free and bitmap
* with group lock held. generate_buddy look at
* them with group lock_held
*/
- mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
- bit, count);
+ ext4_lock_group(sb, block_group);
+ mb_clear_bits(bitmap_bh->b_data, bit, count);
mb_free_blocks(inode, &e4b, bit, count);
ext4_mb_return_to_preallocation(inode, &e4b, block, count);
- ext4_unlock_group(sb, block_group);
}
- spin_lock(sb_bgl_lock(sbi, block_group));
ret = ext4_free_blks_count(sb, gdp) + count;
ext4_free_blks_set(sb, gdp, ret);
gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
- spin_unlock(sb_bgl_lock(sbi, block_group));
+ ext4_unlock_group(sb, block_group);
percpu_counter_add(&sbi->s_freeblocks_counter, count);
if (sbi->s_log_groups_per_flex) {
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index dd9e6cd5f6cf..75e34f69215b 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -23,7 +23,6 @@
#include <linux/mutex.h>
#include "ext4_jbd2.h"
#include "ext4.h"
-#include "group.h"
/*
* with AGGRESSIVE_CHECK allocator runs consistency checks over
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 22098e1cd085..f2bc160463b7 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -37,7 +37,6 @@
#include "ext4.h"
#include "ext4_jbd2.h"
-#include "namei.h"
#include "xattr.h"
#include "acl.h"
@@ -1997,7 +1996,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
if (!ext4_handle_valid(handle))
return 0;
- lock_super(sb);
+ mutex_lock(&EXT4_SB(sb)->s_orphan_lock);
if (!list_empty(&EXT4_I(inode)->i_orphan))
goto out_unlock;
@@ -2006,9 +2005,13 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
/* @@@ FIXME: Observation from aviro:
* I think I can trigger J_ASSERT in ext4_orphan_add(). We block
- * here (on lock_super()), so race with ext4_link() which might bump
+ * here (on s_orphan_lock), so race with ext4_link() which might bump
* ->i_nlink. For, say it, character device. Not a regular file,
* not a directory, not a symlink and ->i_nlink > 0.
+ *
+ * tytso, 4/25/2009: I'm not sure how that could happen;
+ * shouldn't the fs core protect us from these sort of
+ * unlink()/link() races?
*/
J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
@@ -2045,7 +2048,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
jbd_debug(4, "orphan inode %lu will point to %d\n",
inode->i_ino, NEXT_ORPHAN(inode));
out_unlock:
- unlock_super(sb);
+ mutex_unlock(&EXT4_SB(sb)->s_orphan_lock);
ext4_std_error(inode->i_sb, err);
return err;
}
@@ -2066,11 +2069,9 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
if (!ext4_handle_valid(handle))
return 0;
- lock_super(inode->i_sb);
- if (list_empty(&ei->i_orphan)) {
- unlock_super(inode->i_sb);
- return 0;
- }
+ mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock);
+ if (list_empty(&ei->i_orphan))
+ goto out;
ino_next = NEXT_ORPHAN(inode);
prev = ei->i_orphan.prev;
@@ -2120,7 +2121,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
out_err:
ext4_std_error(inode->i_sb, err);
out:
- unlock_super(inode->i_sb);
+ mutex_unlock(&EXT4_SB(inode->i_sb)->s_orphan_lock);
return err;
out_brelse:
@@ -2533,6 +2534,7 @@ const struct inode_operations ext4_dir_inode_operations = {
.removexattr = generic_removexattr,
#endif
.permission = ext4_permission,
+ .fiemap = ext4_fiemap,
};
const struct inode_operations ext4_special_inode_operations = {
diff --git a/fs/ext4/namei.h b/fs/ext4/namei.h
deleted file mode 100644
index 5e4dfff36a00..000000000000
--- a/fs/ext4/namei.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* linux/fs/ext4/namei.h
- *
- * Copyright (C) 2005 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
-*/
-
-extern struct dentry *ext4_get_parent(struct dentry *child);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 546c7dd869e1..27eb289eea37 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -15,7 +15,6 @@
#include <linux/slab.h>
#include "ext4_jbd2.h"
-#include "group.h"
#define outside(b, first, last) ((b) < (first) || (b) >= (last))
#define inside(b, first, last) ((b) >= (first) && (b) < (last))
@@ -193,7 +192,7 @@ static int setup_new_group_blocks(struct super_block *sb,
if (IS_ERR(handle))
return PTR_ERR(handle);
- lock_super(sb);
+ mutex_lock(&sbi->s_resize_lock);
if (input->group != sbi->s_groups_count) {
err = -EBUSY;
goto exit_journal;
@@ -302,7 +301,7 @@ exit_bh:
brelse(bh);
exit_journal:
- unlock_super(sb);
+ mutex_unlock(&sbi->s_resize_lock);
if ((err2 = ext4_journal_stop(handle)) && !err)
err = err2;
@@ -643,11 +642,12 @@ exit_free:
* important part is that the new block and inode counts are in the backup
* superblocks, and the location of the new group metadata in the GDT backups.
*
- * We do not need lock_super() for this, because these blocks are not
- * otherwise touched by the filesystem code when it is mounted. We don't
- * need to worry about last changing from sbi->s_groups_count, because the
- * worst that can happen is that we do not copy the full number of backups
- * at this time. The resize which changed s_groups_count will backup again.
+ * We do not need take the s_resize_lock for this, because these
+ * blocks are not otherwise touched by the filesystem code when it is
+ * mounted. We don't need to worry about last changing from
+ * sbi->s_groups_count, because the worst that can happen is that we
+ * do not copy the full number of backups at this time. The resize
+ * which changed s_groups_count will backup again.
*/
static void update_backups(struct super_block *sb,
int blk_off, char *data, int size)
@@ -809,7 +809,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
goto exit_put;
}
- lock_super(sb);
+ mutex_lock(&sbi->s_resize_lock);
if (input->group != sbi->s_groups_count) {
ext4_warning(sb, __func__,
"multiple resizers run on filesystem!");
@@ -840,7 +840,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
/*
* OK, now we've set up the new group. Time to make it active.
*
- * Current kernels don't lock all allocations via lock_super(),
+ * We do not lock all allocations via s_resize_lock
* so we have to be safe wrt. concurrent accesses the group
* data. So we need to be careful to set all of the relevant
* group descriptor data etc. *before* we enable the group.
@@ -900,12 +900,12 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
*
* The precise rules we use are:
*
- * * Writers of s_groups_count *must* hold lock_super
+ * * Writers of s_groups_count *must* hold s_resize_lock
* AND
* * Writers must perform a smp_wmb() after updating all dependent
* data and before modifying the groups count
*
- * * Readers must hold lock_super() over the access
+ * * Readers must hold s_resize_lock over the access
* OR
* * Readers must perform an smp_rmb() after reading the groups count
* and before reading any dependent data.
@@ -948,7 +948,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
sb->s_dirt = 1;
exit_journal:
- unlock_super(sb);
+ mutex_unlock(&sbi->s_resize_lock);
if ((err2 = ext4_journal_stop(handle)) && !err)
err = err2;
if (!err) {
@@ -986,7 +986,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
/* We don't need to worry about locking wrt other resizers just
* yet: we're going to revalidate es->s_blocks_count after
- * taking lock_super() below. */
+ * taking the s_resize_lock below. */
o_blocks_count = ext4_blocks_count(es);
o_groups_count = EXT4_SB(sb)->s_groups_count;
@@ -1056,11 +1056,11 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
goto exit_put;
}
- lock_super(sb);
+ mutex_lock(&EXT4_SB(sb)->s_resize_lock);
if (o_blocks_count != ext4_blocks_count(es)) {
ext4_warning(sb, __func__,
"multiple resizers run on filesystem!");
- unlock_super(sb);
+ mutex_unlock(&EXT4_SB(sb)->s_resize_lock);
ext4_journal_stop(handle);
err = -EBUSY;
goto exit_put;
@@ -1070,14 +1070,14 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
EXT4_SB(sb)->s_sbh))) {
ext4_warning(sb, __func__,
"error %d on journal write access", err);
- unlock_super(sb);
+ mutex_unlock(&EXT4_SB(sb)->s_resize_lock);
ext4_journal_stop(handle);
goto exit_put;
}
ext4_blocks_count_set(es, o_blocks_count + add);
ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
sb->s_dirt = 1;
- unlock_super(sb);
+ mutex_unlock(&EXT4_SB(sb)->s_resize_lock);
ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count,
o_blocks_count + add);
/* We add the blocks to the bitmap and set the group need init bit */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 2958f4e6f222..e44938cd8b1d 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -20,6 +20,7 @@
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/time.h>
+#include <linux/vmalloc.h>
#include <linux/jbd2.h>
#include <linux/slab.h>
#include <linux/init.h>
@@ -45,16 +46,20 @@
#include "ext4_jbd2.h"
#include "xattr.h"
#include "acl.h"
-#include "namei.h"
-#include "group.h"
+
+static int default_mb_history_length = 1000;
+
+module_param_named(default_mb_history_length, default_mb_history_length,
+ int, 0644);
+MODULE_PARM_DESC(default_mb_history_length,
+ "Default number of entries saved for mb_history");
struct proc_dir_entry *ext4_proc_root;
static struct kset *ext4_kset;
static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
unsigned long journal_devnum);
-static int ext4_commit_super(struct super_block *sb,
- struct ext4_super_block *es, int sync);
+static int ext4_commit_super(struct super_block *sb, int sync);
static void ext4_mark_recovery_complete(struct super_block *sb,
struct ext4_super_block *es);
static void ext4_clear_journal_err(struct super_block *sb,
@@ -66,6 +71,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data);
static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
static int ext4_unfreeze(struct super_block *sb);
static void ext4_write_super(struct super_block *sb);
+static void ext4_write_super_locked(struct super_block *sb);
static int ext4_freeze(struct super_block *sb);
@@ -305,7 +311,7 @@ static void ext4_handle_error(struct super_block *sb)
printk(KERN_CRIT "Remounting filesystem read-only\n");
sb->s_flags |= MS_RDONLY;
}
- ext4_commit_super(sb, es, 1);
+ ext4_commit_super(sb, 1);
if (test_opt(sb, ERRORS_PANIC))
panic("EXT4-fs (device %s): panic forced after error\n",
sb->s_id);
@@ -447,7 +453,7 @@ __acquires(bitlock)
if (test_opt(sb, ERRORS_CONT)) {
EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
- ext4_commit_super(sb, es, 0);
+ ext4_commit_super(sb, 0);
return;
}
ext4_unlock_group(sb, grp);
@@ -563,6 +569,11 @@ static void ext4_put_super(struct super_block *sb)
struct ext4_super_block *es = sbi->s_es;
int i, err;
+ lock_super(sb);
+ lock_kernel();
+ if (sb->s_dirt)
+ ext4_write_super_locked(sb);
+
ext4_mb_release(sb);
ext4_ext_release(sb);
ext4_xattr_put_super(sb);
@@ -576,7 +587,7 @@ static void ext4_put_super(struct super_block *sb)
if (!(sb->s_flags & MS_RDONLY)) {
EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
es->s_state = cpu_to_le16(sbi->s_mount_state);
- ext4_commit_super(sb, es, 1);
+ ext4_commit_super(sb, 1);
}
if (sbi->s_proc) {
remove_proc_entry(sb->s_id, ext4_proc_root);
@@ -586,7 +597,10 @@ static void ext4_put_super(struct super_block *sb)
for (i = 0; i < sbi->s_gdb_count; i++)
brelse(sbi->s_group_desc[i]);
kfree(sbi->s_group_desc);
- kfree(sbi->s_flex_groups);
+ if (is_vmalloc_addr(sbi->s_flex_groups))
+ vfree(sbi->s_flex_groups);
+ else
+ kfree(sbi->s_flex_groups);
percpu_counter_destroy(&sbi->s_freeblocks_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
@@ -625,11 +639,8 @@ static void ext4_put_super(struct super_block *sb)
unlock_super(sb);
kobject_put(&sbi->s_kobj);
wait_for_completion(&sbi->s_kobj_unregister);
- lock_super(sb);
- lock_kernel();
kfree(sbi->s_blockgroup_lock);
kfree(sbi);
- return;
}
static struct kmem_cache *ext4_inode_cachep;
@@ -992,7 +1003,6 @@ static const struct super_operations ext4_sops = {
.dirty_inode = ext4_dirty_inode,
.delete_inode = ext4_delete_inode,
.put_super = ext4_put_super,
- .write_super = ext4_write_super,
.sync_fs = ext4_sync_fs,
.freeze_fs = ext4_freeze,
.unfreeze_fs = ext4_unfreeze,
@@ -1007,6 +1017,25 @@ static const struct super_operations ext4_sops = {
.bdev_try_to_free_page = bdev_try_to_free_page,
};
+static const struct super_operations ext4_nojournal_sops = {
+ .alloc_inode = ext4_alloc_inode,
+ .destroy_inode = ext4_destroy_inode,
+ .write_inode = ext4_write_inode,
+ .dirty_inode = ext4_dirty_inode,
+ .delete_inode = ext4_delete_inode,
+ .write_super = ext4_write_super,
+ .put_super = ext4_put_super,
+ .statfs = ext4_statfs,
+ .remount_fs = ext4_remount,
+ .clear_inode = ext4_clear_inode,
+ .show_options = ext4_show_options,
+#ifdef CONFIG_QUOTA
+ .quota_read = ext4_quota_read,
+ .quota_write = ext4_quota_write,
+#endif
+ .bdev_try_to_free_page = bdev_try_to_free_page,
+};
+
static const struct export_operations ext4_export_ops = {
.fh_to_dentry = ext4_fh_to_dentry,
.fh_to_parent = ext4_fh_to_parent,
@@ -1023,7 +1052,7 @@ enum {
Opt_journal_update, Opt_journal_dev,
Opt_journal_checksum, Opt_journal_async_commit,
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
- Opt_data_err_abort, Opt_data_err_ignore,
+ Opt_data_err_abort, Opt_data_err_ignore, Opt_mb_history_length,
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize,
@@ -1069,6 +1098,7 @@ static const match_table_t tokens = {
{Opt_data_writeback, "data=writeback"},
{Opt_data_err_abort, "data_err=abort"},
{Opt_data_err_ignore, "data_err=ignore"},
+ {Opt_mb_history_length, "mb_history_length=%u"},
{Opt_offusrjquota, "usrjquota="},
{Opt_usrjquota, "usrjquota=%s"},
{Opt_offgrpjquota, "grpjquota="},
@@ -1310,6 +1340,13 @@ static int parse_options(char *options, struct super_block *sb,
case Opt_data_err_ignore:
clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
break;
+ case Opt_mb_history_length:
+ if (match_int(&args[0], &option))
+ return 0;
+ if (option < 0)
+ return 0;
+ sbi->s_mb_history_max = option;
+ break;
#ifdef CONFIG_QUOTA
case Opt_usrjquota:
qtype = USRQUOTA;
@@ -1479,7 +1516,7 @@ set_qf_format:
return 0;
if (option < 0 || option > (1 << 30))
return 0;
- if (option & (option - 1)) {
+ if (!is_power_of_2(option)) {
printk(KERN_ERR "EXT4-fs: inode_readahead_blks"
" must be a power of 2\n");
return 0;
@@ -1592,7 +1629,7 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
if (sbi->s_journal)
EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
- ext4_commit_super(sb, es, 1);
+ ext4_commit_super(sb, 1);
if (test_opt(sb, DEBUG))
printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%u, "
"bpg=%lu, ipg=%lu, mo=%04lx]\n",
@@ -1620,6 +1657,7 @@ static int ext4_fill_flex_info(struct super_block *sb)
ext4_group_t flex_group_count;
ext4_group_t flex_group;
int groups_per_flex = 0;
+ size_t size;
int i;
if (!sbi->s_es->s_log_groups_per_flex) {
@@ -1634,8 +1672,13 @@ static int ext4_fill_flex_info(struct super_block *sb)
flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex;
- sbi->s_flex_groups = kzalloc(flex_group_count *
- sizeof(struct flex_groups), GFP_KERNEL);
+ size = flex_group_count * sizeof(struct flex_groups);
+ sbi->s_flex_groups = kzalloc(size, GFP_KERNEL);
+ if (sbi->s_flex_groups == NULL) {
+ sbi->s_flex_groups = vmalloc(size);
+ if (sbi->s_flex_groups)
+ memset(sbi->s_flex_groups, 0, size);
+ }
if (sbi->s_flex_groups == NULL) {
printk(KERN_ERR "EXT4-fs: not enough memory for "
"%u flex groups\n", flex_group_count);
@@ -1744,18 +1787,18 @@ static int ext4_check_descriptors(struct super_block *sb)
"(block %llu)!\n", i, inode_table);
return 0;
}
- spin_lock(sb_bgl_lock(sbi, i));
+ ext4_lock_group(sb, i);
if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
"Checksum for group %u failed (%u!=%u)\n",
i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
gdp)), le16_to_cpu(gdp->bg_checksum));
if (!(sb->s_flags & MS_RDONLY)) {
- spin_unlock(sb_bgl_lock(sbi, i));
+ ext4_unlock_group(sb, i);
return 0;
}
}
- spin_unlock(sb_bgl_lock(sbi, i));
+ ext4_unlock_group(sb, i);
if (!flexbg_flag)
first_block += EXT4_BLOCKS_PER_GROUP(sb);
}
@@ -2091,8 +2134,7 @@ static ssize_t inode_readahead_blks_store(struct ext4_attr *a,
if (parse_strtoul(buf, 0x40000000, &t))
return -EINVAL;
- /* inode_readahead_blks must be a power of 2 */
- if (t & (t-1))
+ if (!is_power_of_2(t))
return -EINVAL;
sbi->s_inode_readahead_blks = t;
@@ -2321,6 +2363,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ;
sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME;
sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME;
+ sbi->s_mb_history_max = default_mb_history_length;
set_opt(sbi->s_mount_opt, BARRIER);
@@ -2607,7 +2650,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
/*
* set up enough so that it can read an inode
*/
- sb->s_op = &ext4_sops;
+ if (!test_opt(sb, NOLOAD) &&
+ EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
+ sb->s_op = &ext4_sops;
+ else
+ sb->s_op = &ext4_nojournal_sops;
sb->s_export_op = &ext4_export_ops;
sb->s_xattr = ext4_xattr_handlers;
#ifdef CONFIG_QUOTA
@@ -2615,6 +2662,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
sb->dq_op = &ext4_quota_operations;
#endif
INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
+ mutex_init(&sbi->s_orphan_lock);
+ mutex_init(&sbi->s_resize_lock);
sb->s_root = NULL;
@@ -2646,7 +2695,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
if (test_opt(sb, ERRORS_PANIC)) {
EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
- ext4_commit_super(sb, es, 1);
+ ext4_commit_super(sb, 1);
goto failed_mount4;
}
}
@@ -2798,14 +2847,6 @@ no_journal:
goto failed_mount4;
};
- /*
- * akpm: core read_super() calls in here with the superblock locked.
- * That deadlocks, because orphan cleanup needs to lock the superblock
- * in numerous places. Here we just pop the lock - it's relatively
- * harmless, because we are now ready to accept write_super() requests,
- * and aviro says that's the only reason for hanging onto the
- * superblock lock.
- */
EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
ext4_orphan_cleanup(sb, es);
EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
@@ -2842,6 +2883,12 @@ failed_mount4:
sbi->s_journal = NULL;
}
failed_mount3:
+ if (sbi->s_flex_groups) {
+ if (is_vmalloc_addr(sbi->s_flex_groups))
+ vfree(sbi->s_flex_groups);
+ else
+ kfree(sbi->s_flex_groups);
+ }
percpu_counter_destroy(&sbi->s_freeblocks_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
@@ -3114,18 +3161,17 @@ static int ext4_load_journal(struct super_block *sb,
if (journal_devnum &&
journal_devnum != le32_to_cpu(es->s_journal_dev)) {
es->s_journal_dev = cpu_to_le32(journal_devnum);
- sb->s_dirt = 1;
/* Make sure we flush the recovery flag to disk. */
- ext4_commit_super(sb, es, 1);
+ ext4_commit_super(sb, 1);
}
return 0;
}
-static int ext4_commit_super(struct super_block *sb,
- struct ext4_super_block *es, int sync)
+static int ext4_commit_super(struct super_block *sb, int sync)
{
+ struct ext4_super_block *es = EXT4_SB(sb)->s_es;
struct buffer_head *sbh = EXT4_SB(sb)->s_sbh;
int error = 0;
@@ -3154,7 +3200,7 @@ static int ext4_commit_super(struct super_block *sb,
&EXT4_SB(sb)->s_freeblocks_counter));
es->s_free_inodes_count = cpu_to_le32(percpu_counter_sum_positive(
&EXT4_SB(sb)->s_freeinodes_counter));
-
+ sb->s_dirt = 0;
BUFFER_TRACE(sbh, "marking dirty");
mark_buffer_dirty(sbh);
if (sync) {
@@ -3192,14 +3238,11 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
if (jbd2_journal_flush(journal) < 0)
goto out;
- lock_super(sb);
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) &&
sb->s_flags & MS_RDONLY) {
EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
- sb->s_dirt = 0;
- ext4_commit_super(sb, es, 1);
+ ext4_commit_super(sb, 1);
}
- unlock_super(sb);
out:
jbd2_journal_unlock_updates(journal);
@@ -3238,7 +3281,7 @@ static void ext4_clear_journal_err(struct super_block *sb,
EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
- ext4_commit_super(sb, es, 1);
+ ext4_commit_super(sb, 1);
jbd2_journal_clear_err(journal);
}
@@ -3257,29 +3300,22 @@ int ext4_force_commit(struct super_block *sb)
return 0;
journal = EXT4_SB(sb)->s_journal;
- if (journal) {
- sb->s_dirt = 0;
+ if (journal)
ret = ext4_journal_force_commit(journal);
- }
return ret;
}
-/*
- * Ext4 always journals updates to the superblock itself, so we don't
- * have to propagate any other updates to the superblock on disk at this
- * point. (We can probably nuke this function altogether, and remove
- * any mention to sb->s_dirt in all of fs/ext4; eventual cleanup...)
- */
+static void ext4_write_super_locked(struct super_block *sb)
+{
+ ext4_commit_super(sb, 1);
+}
+
static void ext4_write_super(struct super_block *sb)
{
- if (EXT4_SB(sb)->s_journal) {
- if (mutex_trylock(&sb->s_lock) != 0)
- BUG();
- sb->s_dirt = 0;
- } else {
- ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
- }
+ lock_super(sb);
+ ext4_write_super_locked(sb);
+ unlock_super(sb);
}
static int ext4_sync_fs(struct super_block *sb, int wait)
@@ -3288,16 +3324,9 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
tid_t target;
trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait);
- sb->s_dirt = 0;
- if (EXT4_SB(sb)->s_journal) {
- if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal,
- &target)) {
- if (wait)
- jbd2_log_wait_commit(EXT4_SB(sb)->s_journal,
- target);
- }
- } else {
- ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait);
+ if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) {
+ if (wait)
+ jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target);
}
return ret;
}
@@ -3310,34 +3339,32 @@ static int ext4_freeze(struct super_block *sb)
{
int error = 0;
journal_t *journal;
- sb->s_dirt = 0;
- if (!(sb->s_flags & MS_RDONLY)) {
- journal = EXT4_SB(sb)->s_journal;
+ if (sb->s_flags & MS_RDONLY)
+ return 0;
- if (journal) {
- /* Now we set up the journal barrier. */
- jbd2_journal_lock_updates(journal);
+ journal = EXT4_SB(sb)->s_journal;
- /*
- * We don't want to clear needs_recovery flag when we
- * failed to flush the journal.
- */
- error = jbd2_journal_flush(journal);
- if (error < 0)
- goto out;
- }
+ /* Now we set up the journal barrier. */
+ jbd2_journal_lock_updates(journal);
- /* Journal blocked and flushed, clear needs_recovery flag. */
- EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
- error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
- if (error)
- goto out;
+ /*
+ * Don't clear the needs_recovery flag if we failed to flush
+ * the journal.
+ */
+ error = jbd2_journal_flush(journal);
+ if (error < 0) {
+ out:
+ jbd2_journal_unlock_updates(journal);
+ return error;
}
+
+ /* Journal blocked and flushed, clear needs_recovery flag. */
+ EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+ error = ext4_commit_super(sb, 1);
+ if (error)
+ goto out;
return 0;
-out:
- jbd2_journal_unlock_updates(journal);
- return error;
}
/*
@@ -3346,14 +3373,15 @@ out:
*/
static int ext4_unfreeze(struct super_block *sb)
{
- if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) {
- lock_super(sb);
- /* Reser the needs_recovery flag before the fs is unlocked. */
- EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
- ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
- unlock_super(sb);
- jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
- }
+ if (sb->s_flags & MS_RDONLY)
+ return 0;
+
+ lock_super(sb);
+ /* Reset the needs_recovery flag before the fs is unlocked. */
+ EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+ ext4_commit_super(sb, 1);
+ unlock_super(sb);
+ jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
return 0;
}
@@ -3372,6 +3400,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
#endif
/* Store the original options */
+ lock_super(sb);
old_sb_flags = sb->s_flags;
old_opts.s_mount_opt = sbi->s_mount_opt;
old_opts.s_resuid = sbi->s_resuid;
@@ -3432,15 +3461,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
(sbi->s_mount_state & EXT4_VALID_FS))
es->s_state = cpu_to_le16(sbi->s_mount_state);
- /*
- * We have to unlock super so that we can wait for
- * transactions.
- */
- if (sbi->s_journal) {
- unlock_super(sb);
+ if (sbi->s_journal)
ext4_mark_recovery_complete(sb, es);
- lock_super(sb);
- }
} else {
int ret;
if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb,
@@ -3505,7 +3527,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
}
}
if (sbi->s_journal == NULL)
- ext4_commit_super(sb, es, 1);
+ ext4_commit_super(sb, 1);
#ifdef CONFIG_QUOTA
/* Release old quota file names */
@@ -3514,6 +3536,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
old_opts.s_qf_names[i] != sbi->s_qf_names[i])
kfree(old_opts.s_qf_names[i]);
#endif
+ unlock_super(sb);
return 0;
restore_opts:
sb->s_flags = old_sb_flags;
@@ -3532,6 +3555,7 @@ restore_opts:
sbi->s_qf_names[i] = old_opts.s_qf_names[i];
}
#endif
+ unlock_super(sb);
return err;
}
@@ -3545,9 +3569,8 @@ 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 != ext4_blocks_count(es)) {
- ext4_group_t ngroups = sbi->s_groups_count, i;
+ ext4_group_t i, ngroups = ext4_get_groups_count(sb);
ext4_fsblk_t overhead = 0;
- smp_rmb();
/*
* Compute the overhead (FS structures). This is constant
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 296785a0dec8..2292cbf7d364 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -441,16 +441,23 @@ static void fat_clear_inode(struct inode *inode)
static void fat_write_super(struct super_block *sb)
{
+ lock_super(sb);
sb->s_dirt = 0;
if (!(sb->s_flags & MS_RDONLY))
fat_clusters_flush(sb);
+ unlock_super(sb);
}
static void fat_put_super(struct super_block *sb)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ lock_kernel();
+
+ if (sb->s_dirt)
+ fat_write_super(sb);
+
if (sbi->nls_disk) {
unload_nls(sbi->nls_disk);
sbi->nls_disk = NULL;
@@ -467,6 +474,8 @@ static void fat_put_super(struct super_block *sb)
sb->s_fs_info = NULL;
kfree(sbi);
+
+ unlock_kernel();
}
static struct kmem_cache *fat_inode_cachep;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index cc8e4de2fee5..1ad703150dee 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -117,11 +117,13 @@ SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)
{
if (unlikely(newfd == oldfd)) { /* corner case */
struct files_struct *files = current->files;
+ int retval = oldfd;
+
rcu_read_lock();
if (!fcheck_files(files, oldfd))
- oldfd = -EBADF;
+ retval = -EBADF;
rcu_read_unlock();
- return oldfd;
+ return retval;
}
return sys_dup3(oldfd, newfd, 0);
}
diff --git a/fs/file_table.c b/fs/file_table.c
index 54018fe48840..334ce39881f8 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -214,7 +214,7 @@ int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry,
*/
if ((mode & FMODE_WRITE) && !special_file(dentry->d_inode->i_mode)) {
file_take_write(file);
- error = mnt_want_write(mnt);
+ error = mnt_clone_write(mnt);
WARN_ON(error);
}
return error;
@@ -399,6 +399,44 @@ too_bad:
return 0;
}
+/**
+ * mark_files_ro - mark all files read-only
+ * @sb: superblock in question
+ *
+ * All files are marked read-only. We don't care about pending
+ * delete files so this should be used in 'force' mode only.
+ */
+void mark_files_ro(struct super_block *sb)
+{
+ struct file *f;
+
+retry:
+ file_list_lock();
+ list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
+ struct vfsmount *mnt;
+ if (!S_ISREG(f->f_path.dentry->d_inode->i_mode))
+ continue;
+ if (!file_count(f))
+ continue;
+ if (!(f->f_mode & FMODE_WRITE))
+ continue;
+ f->f_mode &= ~FMODE_WRITE;
+ if (file_check_writeable(f) != 0)
+ continue;
+ file_release_write(f);
+ mnt = mntget(f->f_path.mnt);
+ file_list_unlock();
+ /*
+ * This can sleep, so we can't hold
+ * the file_list_lock() spinlock.
+ */
+ mnt_drop_write(mnt);
+ mntput(mnt);
+ goto retry;
+ }
+ file_list_unlock();
+}
+
void __init files_init(unsigned long mempages)
{
int n;
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 1dacda831577..cdbd1654e4cd 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -80,12 +80,16 @@ vxfs_put_super(struct super_block *sbp)
{
struct vxfs_sb_info *infp = VXFS_SBI(sbp);
+ lock_kernel();
+
vxfs_put_fake_inode(infp->vsi_fship);
vxfs_put_fake_inode(infp->vsi_ilist);
vxfs_put_fake_inode(infp->vsi_stilist);
brelse(infp->vsi_bp);
kfree(infp);
+
+ unlock_kernel();
}
/**
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 91013ff7dd53..e0fb2e789598 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -679,55 +679,6 @@ void sync_inodes_sb(struct super_block *sb, int wait)
}
/**
- * sync_inodes - writes all inodes to disk
- * @wait: wait for completion
- *
- * sync_inodes() goes through each super block's dirty inode list, writes the
- * inodes out, waits on the writeout and puts the inodes back on the normal
- * list.
- *
- * This is for sys_sync(). fsync_dev() uses the same algorithm. The subtle
- * part of the sync functions is that the blockdev "superblock" is processed
- * last. This is because the write_inode() function of a typical fs will
- * perform no I/O, but will mark buffers in the blockdev mapping as dirty.
- * What we want to do is to perform all that dirtying first, and then write
- * back all those inode blocks via the blockdev mapping in one sweep. So the
- * additional (somewhat redundant) sync_blockdev() calls here are to make
- * sure that really happens. Because if we call sync_inodes_sb(wait=1) with
- * outstanding dirty inodes, the writeback goes block-at-a-time within the
- * filesystem's write_inode(). This is extremely slow.
- */
-static void __sync_inodes(int wait)
-{
- struct super_block *sb;
-
- spin_lock(&sb_lock);
-restart:
- list_for_each_entry(sb, &super_blocks, s_list) {
- sb->s_count++;
- spin_unlock(&sb_lock);
- down_read(&sb->s_umount);
- if (sb->s_root) {
- sync_inodes_sb(sb, wait);
- sync_blockdev(sb->s_bdev);
- }
- up_read(&sb->s_umount);
- spin_lock(&sb_lock);
- if (__put_super_and_need_restart(sb))
- goto restart;
- }
- spin_unlock(&sb_lock);
-}
-
-void sync_inodes(int wait)
-{
- __sync_inodes(0);
-
- if (wait)
- __sync_inodes(1);
-}
-
-/**
* write_inode_now - write an inode to disk
* @inode: inode to write to disk
* @sync: whether the write should be synchronous or not
diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile
index 72437065f6ad..e95eeb445e58 100644
--- a/fs/fuse/Makefile
+++ b/fs/fuse/Makefile
@@ -3,5 +3,6 @@
#
obj-$(CONFIG_FUSE_FS) += fuse.o
+obj-$(CONFIG_CUSE) += cuse.o
fuse-objs := dev.o dir.o file.o inode.o control.o
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
new file mode 100644
index 000000000000..de792dcf3274
--- /dev/null
+++ b/fs/fuse/cuse.c
@@ -0,0 +1,610 @@
+/*
+ * CUSE: Character device in Userspace
+ *
+ * Copyright (C) 2008-2009 SUSE Linux Products GmbH
+ * Copyright (C) 2008-2009 Tejun Heo <tj@kernel.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * CUSE enables character devices to be implemented from userland much
+ * like FUSE allows filesystems. On initialization /dev/cuse is
+ * created. By opening the file and replying to the CUSE_INIT request
+ * userland CUSE server can create a character device. After that the
+ * operation is very similar to FUSE.
+ *
+ * A CUSE instance involves the following objects.
+ *
+ * cuse_conn : contains fuse_conn and serves as bonding structure
+ * channel : file handle connected to the userland CUSE server
+ * cdev : the implemented character device
+ * dev : generic device for cdev
+ *
+ * Note that 'channel' is what 'dev' is in FUSE. As CUSE deals with
+ * devices, it's called 'channel' to reduce confusion.
+ *
+ * channel determines when the character device dies. When channel is
+ * closed, everything begins to destruct. The cuse_conn is taken off
+ * the lookup table preventing further access from cdev, cdev and
+ * generic device are removed and the base reference of cuse_conn is
+ * put.
+ *
+ * On each open, the matching cuse_conn is looked up and if found an
+ * additional reference is taken which is released when the file is
+ * closed.
+ */
+
+#include <linux/fuse.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/kdev_t.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <linux/magic.h>
+#include <linux/miscdevice.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/stat.h>
+
+#include "fuse_i.h"
+
+#define CUSE_CONNTBL_LEN 64
+
+struct cuse_conn {
+ struct list_head list; /* linked on cuse_conntbl */
+ struct fuse_conn fc; /* fuse connection */
+ struct cdev *cdev; /* associated character device */
+ struct device *dev; /* device representing @cdev */
+
+ /* init parameters, set once during initialization */
+ bool unrestricted_ioctl;
+};
+
+static DEFINE_SPINLOCK(cuse_lock); /* protects cuse_conntbl */
+static struct list_head cuse_conntbl[CUSE_CONNTBL_LEN];
+static struct class *cuse_class;
+
+static struct cuse_conn *fc_to_cc(struct fuse_conn *fc)
+{
+ return container_of(fc, struct cuse_conn, fc);
+}
+
+static struct list_head *cuse_conntbl_head(dev_t devt)
+{
+ return &cuse_conntbl[(MAJOR(devt) + MINOR(devt)) % CUSE_CONNTBL_LEN];
+}
+
+
+/**************************************************************************
+ * CUSE frontend operations
+ *
+ * These are file operations for the character device.
+ *
+ * On open, CUSE opens a file from the FUSE mnt and stores it to
+ * private_data of the open file. All other ops call FUSE ops on the
+ * FUSE file.
+ */
+
+static ssize_t cuse_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ loff_t pos = 0;
+
+ return fuse_direct_io(file, buf, count, &pos, 0);
+}
+
+static ssize_t cuse_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ loff_t pos = 0;
+ /*
+ * No locking or generic_write_checks(), the server is
+ * responsible for locking and sanity checks.
+ */
+ return fuse_direct_io(file, buf, count, &pos, 1);
+}
+
+static int cuse_open(struct inode *inode, struct file *file)
+{
+ dev_t devt = inode->i_cdev->dev;
+ struct cuse_conn *cc = NULL, *pos;
+ int rc;
+
+ /* look up and get the connection */
+ spin_lock(&cuse_lock);
+ list_for_each_entry(pos, cuse_conntbl_head(devt), list)
+ if (pos->dev->devt == devt) {
+ fuse_conn_get(&pos->fc);
+ cc = pos;
+ break;
+ }
+ spin_unlock(&cuse_lock);
+
+ /* dead? */
+ if (!cc)
+ return -ENODEV;
+
+ /*
+ * Generic permission check is already done against the chrdev
+ * file, proceed to open.
+ */
+ rc = fuse_do_open(&cc->fc, 0, file, 0);
+ if (rc)
+ fuse_conn_put(&cc->fc);
+ return rc;
+}
+
+static int cuse_release(struct inode *inode, struct file *file)
+{
+ struct fuse_file *ff = file->private_data;
+ struct fuse_conn *fc = ff->fc;
+
+ fuse_sync_release(ff, file->f_flags);
+ fuse_conn_put(fc);
+
+ return 0;
+}
+
+static long cuse_file_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct fuse_file *ff = file->private_data;
+ struct cuse_conn *cc = fc_to_cc(ff->fc);
+ unsigned int flags = 0;
+
+ if (cc->unrestricted_ioctl)
+ flags |= FUSE_IOCTL_UNRESTRICTED;
+
+ return fuse_do_ioctl(file, cmd, arg, flags);
+}
+
+static long cuse_file_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct fuse_file *ff = file->private_data;
+ struct cuse_conn *cc = fc_to_cc(ff->fc);
+ unsigned int flags = FUSE_IOCTL_COMPAT;
+
+ if (cc->unrestricted_ioctl)
+ flags |= FUSE_IOCTL_UNRESTRICTED;
+
+ return fuse_do_ioctl(file, cmd, arg, flags);
+}
+
+static const struct file_operations cuse_frontend_fops = {
+ .owner = THIS_MODULE,
+ .read = cuse_read,
+ .write = cuse_write,
+ .open = cuse_open,
+ .release = cuse_release,
+ .unlocked_ioctl = cuse_file_ioctl,
+ .compat_ioctl = cuse_file_compat_ioctl,
+ .poll = fuse_file_poll,
+};
+
+
+/**************************************************************************
+ * CUSE channel initialization and destruction
+ */
+
+struct cuse_devinfo {
+ const char *name;
+};
+
+/**
+ * cuse_parse_one - parse one key=value pair
+ * @pp: i/o parameter for the current position
+ * @end: points to one past the end of the packed string
+ * @keyp: out parameter for key
+ * @valp: out parameter for value
+ *
+ * *@pp points to packed strings - "key0=val0\0key1=val1\0" which ends
+ * at @end - 1. This function parses one pair and set *@keyp to the
+ * start of the key and *@valp to the start of the value. Note that
+ * the original string is modified such that the key string is
+ * terminated with '\0'. *@pp is updated to point to the next string.
+ *
+ * RETURNS:
+ * 1 on successful parse, 0 on EOF, -errno on failure.
+ */
+static int cuse_parse_one(char **pp, char *end, char **keyp, char **valp)
+{
+ char *p = *pp;
+ char *key, *val;
+
+ while (p < end && *p == '\0')
+ p++;
+ if (p == end)
+ return 0;
+
+ if (end[-1] != '\0') {
+ printk(KERN_ERR "CUSE: info not properly terminated\n");
+ return -EINVAL;
+ }
+
+ key = val = p;
+ p += strlen(p);
+
+ if (valp) {
+ strsep(&val, "=");
+ if (!val)
+ val = key + strlen(key);
+ key = strstrip(key);
+ val = strstrip(val);
+ } else
+ key = strstrip(key);
+
+ if (!strlen(key)) {
+ printk(KERN_ERR "CUSE: zero length info key specified\n");
+ return -EINVAL;
+ }
+
+ *pp = p;
+ *keyp = key;
+ if (valp)
+ *valp = val;
+
+ return 1;
+}
+
+/**
+ * cuse_parse_dev_info - parse device info
+ * @p: device info string
+ * @len: length of device info string
+ * @devinfo: out parameter for parsed device info
+ *
+ * Parse @p to extract device info and store it into @devinfo. String
+ * pointed to by @p is modified by parsing and @devinfo points into
+ * them, so @p shouldn't be freed while @devinfo is in use.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+static int cuse_parse_devinfo(char *p, size_t len, struct cuse_devinfo *devinfo)
+{
+ char *end = p + len;
+ char *key, *val;
+ int rc;
+
+ while (true) {
+ rc = cuse_parse_one(&p, end, &key, &val);
+ if (rc < 0)
+ return rc;
+ if (!rc)
+ break;
+ if (strcmp(key, "DEVNAME") == 0)
+ devinfo->name = val;
+ else
+ printk(KERN_WARNING "CUSE: unknown device info \"%s\"\n",
+ key);
+ }
+
+ if (!devinfo->name || !strlen(devinfo->name)) {
+ printk(KERN_ERR "CUSE: DEVNAME unspecified\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void cuse_gendev_release(struct device *dev)
+{
+ kfree(dev);
+}
+
+/**
+ * cuse_process_init_reply - finish initializing CUSE channel
+ *
+ * This function creates the character device and sets up all the
+ * required data structures for it. Please read the comment at the
+ * top of this file for high level overview.
+ */
+static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
+{
+ struct cuse_conn *cc = fc_to_cc(fc);
+ struct cuse_init_out *arg = &req->misc.cuse_init_out;
+ struct page *page = req->pages[0];
+ struct cuse_devinfo devinfo = { };
+ struct device *dev;
+ struct cdev *cdev;
+ dev_t devt;
+ int rc;
+
+ if (req->out.h.error ||
+ arg->major != FUSE_KERNEL_VERSION || arg->minor < 11) {
+ goto err;
+ }
+
+ fc->minor = arg->minor;
+ fc->max_read = max_t(unsigned, arg->max_read, 4096);
+ fc->max_write = max_t(unsigned, arg->max_write, 4096);
+
+ /* parse init reply */
+ cc->unrestricted_ioctl = arg->flags & CUSE_UNRESTRICTED_IOCTL;
+
+ rc = cuse_parse_devinfo(page_address(page), req->out.args[1].size,
+ &devinfo);
+ if (rc)
+ goto err;
+
+ /* determine and reserve devt */
+ devt = MKDEV(arg->dev_major, arg->dev_minor);
+ if (!MAJOR(devt))
+ rc = alloc_chrdev_region(&devt, MINOR(devt), 1, devinfo.name);
+ else
+ rc = register_chrdev_region(devt, 1, devinfo.name);
+ if (rc) {
+ printk(KERN_ERR "CUSE: failed to register chrdev region\n");
+ goto err;
+ }
+
+ /* devt determined, create device */
+ rc = -ENOMEM;
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ goto err_region;
+
+ device_initialize(dev);
+ dev_set_uevent_suppress(dev, 1);
+ dev->class = cuse_class;
+ dev->devt = devt;
+ dev->release = cuse_gendev_release;
+ dev_set_drvdata(dev, cc);
+ dev_set_name(dev, "%s", devinfo.name);
+
+ rc = device_add(dev);
+ if (rc)
+ goto err_device;
+
+ /* register cdev */
+ rc = -ENOMEM;
+ cdev = cdev_alloc();
+ if (!cdev)
+ goto err_device;
+
+ cdev->owner = THIS_MODULE;
+ cdev->ops = &cuse_frontend_fops;
+
+ rc = cdev_add(cdev, devt, 1);
+ if (rc)
+ goto err_cdev;
+
+ cc->dev = dev;
+ cc->cdev = cdev;
+
+ /* make the device available */
+ spin_lock(&cuse_lock);
+ list_add(&cc->list, cuse_conntbl_head(devt));
+ spin_unlock(&cuse_lock);
+
+ /* announce device availability */
+ dev_set_uevent_suppress(dev, 0);
+ kobject_uevent(&dev->kobj, KOBJ_ADD);
+out:
+ __free_page(page);
+ return;
+
+err_cdev:
+ cdev_del(cdev);
+err_device:
+ put_device(dev);
+err_region:
+ unregister_chrdev_region(devt, 1);
+err:
+ fc->conn_error = 1;
+ goto out;
+}
+
+static int cuse_send_init(struct cuse_conn *cc)
+{
+ int rc;
+ struct fuse_req *req;
+ struct page *page;
+ struct fuse_conn *fc = &cc->fc;
+ struct cuse_init_in *arg;
+
+ BUILD_BUG_ON(CUSE_INIT_INFO_MAX > PAGE_SIZE);
+
+ req = fuse_get_req(fc);
+ if (IS_ERR(req)) {
+ rc = PTR_ERR(req);
+ goto err;
+ }
+
+ rc = -ENOMEM;
+ page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ if (!page)
+ goto err_put_req;
+
+ arg = &req->misc.cuse_init_in;
+ arg->major = FUSE_KERNEL_VERSION;
+ arg->minor = FUSE_KERNEL_MINOR_VERSION;
+ arg->flags |= CUSE_UNRESTRICTED_IOCTL;
+ req->in.h.opcode = CUSE_INIT;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(struct cuse_init_in);
+ req->in.args[0].value = arg;
+ req->out.numargs = 2;
+ req->out.args[0].size = sizeof(struct cuse_init_out);
+ req->out.args[0].value = &req->misc.cuse_init_out;
+ req->out.args[1].size = CUSE_INIT_INFO_MAX;
+ req->out.argvar = 1;
+ req->out.argpages = 1;
+ req->pages[0] = page;
+ req->num_pages = 1;
+ req->end = cuse_process_init_reply;
+ fuse_request_send_background(fc, req);
+
+ return 0;
+
+err_put_req:
+ fuse_put_request(fc, req);
+err:
+ return rc;
+}
+
+static void cuse_fc_release(struct fuse_conn *fc)
+{
+ struct cuse_conn *cc = fc_to_cc(fc);
+ kfree(cc);
+}
+
+/**
+ * cuse_channel_open - open method for /dev/cuse
+ * @inode: inode for /dev/cuse
+ * @file: file struct being opened
+ *
+ * Userland CUSE server can create a CUSE device by opening /dev/cuse
+ * and replying to the initilaization request kernel sends. This
+ * function is responsible for handling CUSE device initialization.
+ * Because the fd opened by this function is used during
+ * initialization, this function only creates cuse_conn and sends
+ * init. The rest is delegated to a kthread.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+static int cuse_channel_open(struct inode *inode, struct file *file)
+{
+ struct cuse_conn *cc;
+ int rc;
+
+ /* set up cuse_conn */
+ cc = kzalloc(sizeof(*cc), GFP_KERNEL);
+ if (!cc)
+ return -ENOMEM;
+
+ fuse_conn_init(&cc->fc);
+
+ INIT_LIST_HEAD(&cc->list);
+ cc->fc.release = cuse_fc_release;
+
+ cc->fc.connected = 1;
+ cc->fc.blocked = 0;
+ rc = cuse_send_init(cc);
+ if (rc) {
+ fuse_conn_put(&cc->fc);
+ return rc;
+ }
+ file->private_data = &cc->fc; /* channel owns base reference to cc */
+
+ return 0;
+}
+
+/**
+ * cuse_channel_release - release method for /dev/cuse
+ * @inode: inode for /dev/cuse
+ * @file: file struct being closed
+ *
+ * Disconnect the channel, deregister CUSE device and initiate
+ * destruction by putting the default reference.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+static int cuse_channel_release(struct inode *inode, struct file *file)
+{
+ struct cuse_conn *cc = fc_to_cc(file->private_data);
+ int rc;
+
+ /* remove from the conntbl, no more access from this point on */
+ spin_lock(&cuse_lock);
+ list_del_init(&cc->list);
+ spin_unlock(&cuse_lock);
+
+ /* remove device */
+ if (cc->dev)
+ device_unregister(cc->dev);
+ if (cc->cdev) {
+ unregister_chrdev_region(cc->cdev->dev, 1);
+ cdev_del(cc->cdev);
+ }
+
+ /* kill connection and shutdown channel */
+ fuse_conn_kill(&cc->fc);
+ rc = fuse_dev_release(inode, file); /* puts the base reference */
+
+ return rc;
+}
+
+static struct file_operations cuse_channel_fops; /* initialized during init */
+
+
+/**************************************************************************
+ * Misc stuff and module initializatiion
+ *
+ * CUSE exports the same set of attributes to sysfs as fusectl.
+ */
+
+static ssize_t cuse_class_waiting_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct cuse_conn *cc = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", atomic_read(&cc->fc.num_waiting));
+}
+
+static ssize_t cuse_class_abort_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct cuse_conn *cc = dev_get_drvdata(dev);
+
+ fuse_abort_conn(&cc->fc);
+ return count;
+}
+
+static struct device_attribute cuse_class_dev_attrs[] = {
+ __ATTR(waiting, S_IFREG | 0400, cuse_class_waiting_show, NULL),
+ __ATTR(abort, S_IFREG | 0200, NULL, cuse_class_abort_store),
+ { }
+};
+
+static struct miscdevice cuse_miscdev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "cuse",
+ .fops = &cuse_channel_fops,
+};
+
+static int __init cuse_init(void)
+{
+ int i, rc;
+
+ /* init conntbl */
+ for (i = 0; i < CUSE_CONNTBL_LEN; i++)
+ INIT_LIST_HEAD(&cuse_conntbl[i]);
+
+ /* inherit and extend fuse_dev_operations */
+ cuse_channel_fops = fuse_dev_operations;
+ cuse_channel_fops.owner = THIS_MODULE;
+ cuse_channel_fops.open = cuse_channel_open;
+ cuse_channel_fops.release = cuse_channel_release;
+
+ cuse_class = class_create(THIS_MODULE, "cuse");
+ if (IS_ERR(cuse_class))
+ return PTR_ERR(cuse_class);
+
+ cuse_class->dev_attrs = cuse_class_dev_attrs;
+
+ rc = misc_register(&cuse_miscdev);
+ if (rc) {
+ class_destroy(cuse_class);
+ return rc;
+ }
+
+ return 0;
+}
+
+static void __exit cuse_exit(void)
+{
+ misc_deregister(&cuse_miscdev);
+ class_destroy(cuse_class);
+}
+
+module_init(cuse_init);
+module_exit(cuse_exit);
+
+MODULE_AUTHOR("Tejun Heo <tj@kernel.org>");
+MODULE_DESCRIPTION("Character device in Userspace");
+MODULE_LICENSE("GPL");
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index ba76b68c52ff..8fed2ed12f38 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -46,6 +46,7 @@ struct fuse_req *fuse_request_alloc(void)
fuse_request_init(req);
return req;
}
+EXPORT_SYMBOL_GPL(fuse_request_alloc);
struct fuse_req *fuse_request_alloc_nofs(void)
{
@@ -124,6 +125,7 @@ struct fuse_req *fuse_get_req(struct fuse_conn *fc)
atomic_dec(&fc->num_waiting);
return ERR_PTR(err);
}
+EXPORT_SYMBOL_GPL(fuse_get_req);
/*
* Return request in fuse_file->reserved_req. However that may
@@ -208,6 +210,7 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
fuse_request_free(req);
}
}
+EXPORT_SYMBOL_GPL(fuse_put_request);
static unsigned len_args(unsigned numargs, struct fuse_arg *args)
{
@@ -282,7 +285,7 @@ __releases(&fc->lock)
wake_up_all(&fc->blocked_waitq);
}
if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
- fc->connected) {
+ fc->connected && fc->bdi_initialized) {
clear_bdi_congested(&fc->bdi, READ);
clear_bdi_congested(&fc->bdi, WRITE);
}
@@ -400,6 +403,7 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
}
spin_unlock(&fc->lock);
}
+EXPORT_SYMBOL_GPL(fuse_request_send);
static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
struct fuse_req *req)
@@ -408,7 +412,8 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
fc->num_background++;
if (fc->num_background == FUSE_MAX_BACKGROUND)
fc->blocked = 1;
- if (fc->num_background == FUSE_CONGESTION_THRESHOLD) {
+ if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
+ fc->bdi_initialized) {
set_bdi_congested(&fc->bdi, READ);
set_bdi_congested(&fc->bdi, WRITE);
}
@@ -439,6 +444,7 @@ void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
req->isreply = 1;
fuse_request_send_nowait(fc, req);
}
+EXPORT_SYMBOL_GPL(fuse_request_send_background);
/*
* Called under fc->lock
@@ -1105,8 +1111,9 @@ void fuse_abort_conn(struct fuse_conn *fc)
}
spin_unlock(&fc->lock);
}
+EXPORT_SYMBOL_GPL(fuse_abort_conn);
-static int fuse_dev_release(struct inode *inode, struct file *file)
+int fuse_dev_release(struct inode *inode, struct file *file)
{
struct fuse_conn *fc = fuse_get_conn(file);
if (fc) {
@@ -1120,6 +1127,7 @@ static int fuse_dev_release(struct inode *inode, struct file *file)
return 0;
}
+EXPORT_SYMBOL_GPL(fuse_dev_release);
static int fuse_dev_fasync(int fd, struct file *file, int on)
{
@@ -1142,6 +1150,7 @@ const struct file_operations fuse_dev_operations = {
.release = fuse_dev_release,
.fasync = fuse_dev_fasync,
};
+EXPORT_SYMBOL_GPL(fuse_dev_operations);
static struct miscdevice fuse_miscdevice = {
.minor = FUSE_MINOR,
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 8b8eebc5614b..b3089a083d30 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -362,19 +362,6 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
}
/*
- * Synchronous release for the case when something goes wrong in CREATE_OPEN
- */
-static void fuse_sync_release(struct fuse_conn *fc, struct fuse_file *ff,
- u64 nodeid, int flags)
-{
- fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE);
- ff->reserved_req->force = 1;
- fuse_request_send(fc, ff->reserved_req);
- fuse_put_request(fc, ff->reserved_req);
- kfree(ff);
-}
-
-/*
* Atomic create+open operation
*
* If the filesystem doesn't support this, then fall back to separate
@@ -445,12 +432,14 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
goto out_free_ff;
fuse_put_request(fc, req);
+ ff->fh = outopen.fh;
+ ff->nodeid = outentry.nodeid;
+ ff->open_flags = outopen.open_flags;
inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
&outentry.attr, entry_attr_timeout(&outentry), 0);
if (!inode) {
flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
- ff->fh = outopen.fh;
- fuse_sync_release(fc, ff, outentry.nodeid, flags);
+ fuse_sync_release(ff, flags);
fuse_send_forget(fc, forget_req, outentry.nodeid, 1);
return -ENOMEM;
}
@@ -460,11 +449,11 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
fuse_invalidate_attr(dir);
file = lookup_instantiate_filp(nd, entry, generic_file_open);
if (IS_ERR(file)) {
- ff->fh = outopen.fh;
- fuse_sync_release(fc, ff, outentry.nodeid, flags);
+ fuse_sync_release(ff, flags);
return PTR_ERR(file);
}
- fuse_finish_open(inode, file, ff, &outopen);
+ file->private_data = fuse_file_get(ff);
+ fuse_finish_open(inode, file);
return 0;
out_free_ff:
@@ -1035,7 +1024,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
req->out.argpages = 1;
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, file, file->f_pos, PAGE_SIZE, FUSE_READDIR);
fuse_request_send(fc, req);
nbytes = req->out.args[0].size;
err = req->out.h.error;
@@ -1101,12 +1090,14 @@ static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
static int fuse_dir_open(struct inode *inode, struct file *file)
{
- return fuse_open_common(inode, file, 1);
+ return fuse_open_common(inode, file, true);
}
static int fuse_dir_release(struct inode *inode, struct file *file)
{
- return fuse_release_common(inode, file, 1);
+ fuse_release_common(file, FUSE_RELEASEDIR);
+
+ return 0;
}
static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 06f30e965676..fce6ce694fde 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -12,13 +12,13 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/module.h>
static const struct file_operations fuse_direct_io_file_operations;
-static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
- struct fuse_open_out *outargp)
+static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
+ int opcode, struct fuse_open_out *outargp)
{
- struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_open_in inarg;
struct fuse_req *req;
int err;
@@ -31,8 +31,8 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
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.h.opcode = opcode;
+ req->in.h.nodeid = nodeid;
req->in.numargs = 1;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
@@ -49,22 +49,27 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
{
struct fuse_file *ff;
+
ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
- if (ff) {
- ff->reserved_req = fuse_request_alloc();
- if (!ff->reserved_req) {
- kfree(ff);
- return NULL;
- } else {
- INIT_LIST_HEAD(&ff->write_entry);
- atomic_set(&ff->count, 0);
- spin_lock(&fc->lock);
- ff->kh = ++fc->khctr;
- spin_unlock(&fc->lock);
- }
- RB_CLEAR_NODE(&ff->polled_node);
- init_waitqueue_head(&ff->poll_wait);
+ if (unlikely(!ff))
+ return NULL;
+
+ ff->fc = fc;
+ ff->reserved_req = fuse_request_alloc();
+ if (unlikely(!ff->reserved_req)) {
+ kfree(ff);
+ return NULL;
}
+
+ INIT_LIST_HEAD(&ff->write_entry);
+ atomic_set(&ff->count, 0);
+ RB_CLEAR_NODE(&ff->polled_node);
+ init_waitqueue_head(&ff->poll_wait);
+
+ spin_lock(&fc->lock);
+ ff->kh = ++fc->khctr;
+ spin_unlock(&fc->lock);
+
return ff;
}
@@ -74,7 +79,7 @@ void fuse_file_free(struct fuse_file *ff)
kfree(ff);
}
-static struct fuse_file *fuse_file_get(struct fuse_file *ff)
+struct fuse_file *fuse_file_get(struct fuse_file *ff)
{
atomic_inc(&ff->count);
return ff;
@@ -82,40 +87,65 @@ static struct fuse_file *fuse_file_get(struct fuse_file *ff)
static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req)
{
- dput(req->misc.release.dentry);
- mntput(req->misc.release.vfsmount);
+ path_put(&req->misc.release.path);
}
static void fuse_file_put(struct fuse_file *ff)
{
if (atomic_dec_and_test(&ff->count)) {
struct fuse_req *req = ff->reserved_req;
- struct inode *inode = req->misc.release.dentry->d_inode;
- struct fuse_conn *fc = get_fuse_conn(inode);
+
req->end = fuse_release_end;
- fuse_request_send_background(fc, req);
+ fuse_request_send_background(ff->fc, req);
kfree(ff);
}
}
-void fuse_finish_open(struct inode *inode, struct file *file,
- struct fuse_file *ff, struct fuse_open_out *outarg)
+int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
+ bool isdir)
{
- if (outarg->open_flags & FOPEN_DIRECT_IO)
+ struct fuse_open_out outarg;
+ struct fuse_file *ff;
+ int err;
+ int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
+
+ ff = fuse_file_alloc(fc);
+ if (!ff)
+ return -ENOMEM;
+
+ err = fuse_send_open(fc, nodeid, file, opcode, &outarg);
+ if (err) {
+ fuse_file_free(ff);
+ return err;
+ }
+
+ if (isdir)
+ outarg.open_flags &= ~FOPEN_DIRECT_IO;
+
+ ff->fh = outarg.fh;
+ ff->nodeid = nodeid;
+ ff->open_flags = outarg.open_flags;
+ file->private_data = fuse_file_get(ff);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fuse_do_open);
+
+void fuse_finish_open(struct inode *inode, struct file *file)
+{
+ struct fuse_file *ff = file->private_data;
+
+ if (ff->open_flags & FOPEN_DIRECT_IO)
file->f_op = &fuse_direct_io_file_operations;
- if (!(outarg->open_flags & FOPEN_KEEP_CACHE))
+ if (!(ff->open_flags & FOPEN_KEEP_CACHE))
invalidate_inode_pages2(inode->i_mapping);
- if (outarg->open_flags & FOPEN_NONSEEKABLE)
+ if (ff->open_flags & FOPEN_NONSEEKABLE)
nonseekable_open(inode, file);
- ff->fh = outarg->fh;
- file->private_data = fuse_file_get(ff);
}
-int fuse_open_common(struct inode *inode, struct file *file, int isdir)
+int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_open_out outarg;
- struct fuse_file *ff;
int err;
/* VFS checks this, but only _after_ ->open() */
@@ -126,78 +156,85 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
if (err)
return err;
- ff = fuse_file_alloc(fc);
- if (!ff)
- return -ENOMEM;
-
- err = fuse_send_open(inode, file, isdir, &outarg);
+ err = fuse_do_open(fc, get_node_id(inode), file, isdir);
if (err)
- fuse_file_free(ff);
- else {
- if (isdir)
- outarg.open_flags &= ~FOPEN_DIRECT_IO;
- fuse_finish_open(inode, file, ff, &outarg);
- }
+ return err;
- return err;
+ fuse_finish_open(inode, file);
+
+ return 0;
}
-void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode)
+static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode)
{
+ struct fuse_conn *fc = ff->fc;
struct fuse_req *req = ff->reserved_req;
struct fuse_release_in *inarg = &req->misc.release.in;
+ spin_lock(&fc->lock);
+ list_del(&ff->write_entry);
+ if (!RB_EMPTY_NODE(&ff->polled_node))
+ rb_erase(&ff->polled_node, &fc->polled_files);
+ spin_unlock(&fc->lock);
+
+ wake_up_interruptible_sync(&ff->poll_wait);
+
inarg->fh = ff->fh;
inarg->flags = flags;
req->in.h.opcode = opcode;
- req->in.h.nodeid = nodeid;
+ req->in.h.nodeid = ff->nodeid;
req->in.numargs = 1;
req->in.args[0].size = sizeof(struct fuse_release_in);
req->in.args[0].value = inarg;
}
-int fuse_release_common(struct inode *inode, struct file *file, int isdir)
+void fuse_release_common(struct file *file, int opcode)
{
- struct fuse_file *ff = file->private_data;
- if (ff) {
- struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_req *req = ff->reserved_req;
-
- fuse_release_fill(ff, get_node_id(inode), file->f_flags,
- isdir ? FUSE_RELEASEDIR : FUSE_RELEASE);
+ struct fuse_file *ff;
+ struct fuse_req *req;
- /* Hold vfsmount and dentry until release is finished */
- req->misc.release.vfsmount = mntget(file->f_path.mnt);
- req->misc.release.dentry = dget(file->f_path.dentry);
+ ff = file->private_data;
+ if (unlikely(!ff))
+ return;
- spin_lock(&fc->lock);
- list_del(&ff->write_entry);
- if (!RB_EMPTY_NODE(&ff->polled_node))
- rb_erase(&ff->polled_node, &fc->polled_files);
- spin_unlock(&fc->lock);
+ req = ff->reserved_req;
+ fuse_prepare_release(ff, file->f_flags, opcode);
- wake_up_interruptible_sync(&ff->poll_wait);
- /*
- * 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);
- }
+ /* Hold vfsmount and dentry until release is finished */
+ path_get(&file->f_path);
+ req->misc.release.path = file->f_path;
- /* Return value is ignored by VFS */
- return 0;
+ /*
+ * 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);
}
static int fuse_open(struct inode *inode, struct file *file)
{
- return fuse_open_common(inode, file, 0);
+ return fuse_open_common(inode, file, false);
}
static int fuse_release(struct inode *inode, struct file *file)
{
- return fuse_release_common(inode, file, 0);
+ fuse_release_common(file, FUSE_RELEASE);
+
+ /* return value is ignored by VFS */
+ return 0;
+}
+
+void fuse_sync_release(struct fuse_file *ff, int flags)
+{
+ WARN_ON(atomic_read(&ff->count) > 1);
+ fuse_prepare_release(ff, flags, FUSE_RELEASE);
+ ff->reserved_req->force = 1;
+ fuse_request_send(ff->fc, ff->reserved_req);
+ fuse_put_request(ff->fc, ff->reserved_req);
+ kfree(ff);
}
+EXPORT_SYMBOL_GPL(fuse_sync_release);
/*
* Scramble the ID space with XTEA, so that the value of the files_struct
@@ -371,8 +408,8 @@ 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,
- struct inode *inode, loff_t pos, size_t count, int opcode)
+void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos,
+ size_t count, int opcode)
{
struct fuse_read_in *inarg = &req->misc.read.in;
struct fuse_file *ff = file->private_data;
@@ -382,7 +419,7 @@ void fuse_read_fill(struct fuse_req *req, struct file *file,
inarg->size = count;
inarg->flags = file->f_flags;
req->in.h.opcode = opcode;
- req->in.h.nodeid = get_node_id(inode);
+ req->in.h.nodeid = ff->nodeid;
req->in.numargs = 1;
req->in.args[0].size = sizeof(struct fuse_read_in);
req->in.args[0].value = inarg;
@@ -392,12 +429,12 @@ 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,
- fl_owner_t owner)
+ loff_t pos, size_t count, fl_owner_t owner)
{
- struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_file *ff = file->private_data;
+ struct fuse_conn *fc = ff->fc;
- fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
+ fuse_read_fill(req, file, pos, count, FUSE_READ);
if (owner != NULL) {
struct fuse_read_in *inarg = &req->misc.read.in;
@@ -455,7 +492,7 @@ static int fuse_readpage(struct file *file, struct page *page)
req->out.argpages = 1;
req->num_pages = 1;
req->pages[0] = page;
- num_read = fuse_send_read(req, file, inode, pos, count, NULL);
+ num_read = fuse_send_read(req, file, pos, count, NULL);
err = req->out.h.error;
fuse_put_request(fc, req);
@@ -504,19 +541,18 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
fuse_file_put(req->ff);
}
-static void fuse_send_readpages(struct fuse_req *req, struct file *file,
- struct inode *inode)
+static void fuse_send_readpages(struct fuse_req *req, struct file *file)
{
- struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_file *ff = file->private_data;
+ struct fuse_conn *fc = ff->fc;
loff_t pos = page_offset(req->pages[0]);
size_t count = req->num_pages << PAGE_CACHE_SHIFT;
req->out.argpages = 1;
req->out.page_zeroing = 1;
- fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
+ fuse_read_fill(req, file, pos, count, FUSE_READ);
req->misc.read.attr_ver = fuse_get_attr_version(fc);
if (fc->async_read) {
- struct fuse_file *ff = file->private_data;
req->ff = fuse_file_get(ff);
req->end = fuse_readpages_end;
fuse_request_send_background(fc, req);
@@ -546,7 +582,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->file);
data->req = req = fuse_get_req(fc);
if (IS_ERR(req)) {
unlock_page(page);
@@ -580,7 +616,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, file);
else
fuse_put_request(fc, data.req);
}
@@ -607,24 +643,19 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
return generic_file_aio_read(iocb, iov, nr_segs, pos);
}
-static void fuse_write_fill(struct fuse_req *req, struct file *file,
- struct fuse_file *ff, struct inode *inode,
- loff_t pos, size_t count, int writepage)
+static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff,
+ loff_t pos, size_t count)
{
- struct fuse_conn *fc = get_fuse_conn(inode);
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;
- inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0;
- inarg->flags = file ? file->f_flags : 0;
req->in.h.opcode = FUSE_WRITE;
- req->in.h.nodeid = get_node_id(inode);
+ req->in.h.nodeid = ff->nodeid;
req->in.numargs = 2;
- if (fc->minor < 9)
+ if (ff->fc->minor < 9)
req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE;
else
req->in.args[0].size = sizeof(struct fuse_write_in);
@@ -636,13 +667,15 @@ static void fuse_write_fill(struct fuse_req *req, struct file *file,
}
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)
+ loff_t pos, size_t count, fl_owner_t owner)
{
- struct fuse_conn *fc = get_fuse_conn(inode);
- fuse_write_fill(req, file, file->private_data, inode, pos, count, 0);
+ struct fuse_file *ff = file->private_data;
+ struct fuse_conn *fc = ff->fc;
+ struct fuse_write_in *inarg = &req->misc.write.in;
+
+ fuse_write_fill(req, ff, pos, count);
+ inarg->flags = file->f_flags;
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);
}
@@ -700,7 +733,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode,
req->num_pages = 1;
req->pages[0] = page;
req->page_offset = offset;
- nres = fuse_send_write(req, file, inode, pos, count, NULL);
+ nres = fuse_send_write(req, file, pos, count, NULL);
err = req->out.h.error;
fuse_put_request(fc, req);
if (!err && !nres)
@@ -741,7 +774,7 @@ static size_t fuse_send_write_pages(struct fuse_req *req, struct file *file,
for (i = 0; i < req->num_pages; i++)
fuse_wait_on_page_writeback(inode, req->pages[i]->index);
- res = fuse_send_write(req, file, inode, pos, count, NULL);
+ res = fuse_send_write(req, file, pos, count, NULL);
offset = req->page_offset;
count = res;
@@ -979,25 +1012,23 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
return 0;
}
-static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos, int write)
+ssize_t fuse_direct_io(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos, int write)
{
- 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_conn *fc = ff->fc;
size_t nmax = write ? fc->max_write : fc->max_read;
loff_t pos = *ppos;
ssize_t res = 0;
struct fuse_req *req;
- if (is_bad_inode(inode))
- return -EIO;
-
req = fuse_get_req(fc);
if (IS_ERR(req))
return PTR_ERR(req);
while (count) {
size_t nres;
+ fl_owner_t owner = current->files;
size_t nbytes = min(count, nmax);
int err = fuse_get_user_pages(req, buf, &nbytes, write);
if (err) {
@@ -1006,11 +1037,10 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
}
if (write)
- nres = fuse_send_write(req, file, inode, pos, nbytes,
- current->files);
+ nres = fuse_send_write(req, file, pos, nbytes, owner);
else
- nres = fuse_send_read(req, file, inode, pos, nbytes,
- current->files);
+ nres = fuse_send_read(req, file, pos, nbytes, owner);
+
fuse_release_user_pages(req, !write);
if (req->out.h.error) {
if (!res)
@@ -1034,20 +1064,27 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
}
}
fuse_put_request(fc, req);
- if (res > 0) {
- if (write)
- fuse_write_update_size(inode, pos);
+ if (res > 0)
*ppos = pos;
- }
- fuse_invalidate_attr(inode);
return res;
}
+EXPORT_SYMBOL_GPL(fuse_direct_io);
static ssize_t fuse_direct_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- return fuse_direct_io(file, buf, count, ppos, 0);
+ ssize_t res;
+ struct inode *inode = file->f_path.dentry->d_inode;
+
+ if (is_bad_inode(inode))
+ return -EIO;
+
+ res = fuse_direct_io(file, buf, count, ppos, 0);
+
+ fuse_invalidate_attr(inode);
+
+ return res;
}
static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
@@ -1055,12 +1092,22 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
{
struct inode *inode = file->f_path.dentry->d_inode;
ssize_t res;
+
+ if (is_bad_inode(inode))
+ return -EIO;
+
/* Don't allow parallel writes to the same file */
mutex_lock(&inode->i_mutex);
res = generic_write_checks(file, ppos, &count, 0);
- if (!res)
+ if (!res) {
res = fuse_direct_io(file, buf, count, ppos, 1);
+ if (res > 0)
+ fuse_write_update_size(inode, *ppos);
+ }
mutex_unlock(&inode->i_mutex);
+
+ fuse_invalidate_attr(inode);
+
return res;
}
@@ -1177,9 +1224,10 @@ static int fuse_writepage_locked(struct page *page)
req->ff = fuse_file_get(ff);
spin_unlock(&fc->lock);
- fuse_write_fill(req, NULL, ff, inode, page_offset(page), 0, 1);
+ fuse_write_fill(req, ff, page_offset(page), 0);
copy_highpage(tmp_page, page);
+ req->misc.write.in.write_flags |= FUSE_WRITE_CACHE;
req->in.argpages = 1;
req->num_pages = 1;
req->pages[0] = tmp_page;
@@ -1603,12 +1651,11 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov,
* limits ioctl data transfers to well-formed ioctls and is the forced
* behavior for all FUSE servers.
*/
-static long fuse_file_do_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg, unsigned int flags)
+long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
+ unsigned int flags)
{
- struct inode *inode = file->f_dentry->d_inode;
struct fuse_file *ff = file->private_data;
- struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_conn *fc = ff->fc;
struct fuse_ioctl_in inarg = {
.fh = ff->fh,
.cmd = cmd,
@@ -1627,13 +1674,6 @@ static long fuse_file_do_ioctl(struct file *file, unsigned int cmd,
/* assume all the iovs returned by client always fits in a page */
BUILD_BUG_ON(sizeof(struct iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE);
- if (!fuse_allow_task(fc, current))
- return -EACCES;
-
- err = -EIO;
- if (is_bad_inode(inode))
- goto out;
-
err = -ENOMEM;
pages = kzalloc(sizeof(pages[0]) * FUSE_MAX_PAGES_PER_REQ, GFP_KERNEL);
iov_page = alloc_page(GFP_KERNEL);
@@ -1694,7 +1734,7 @@ static long fuse_file_do_ioctl(struct file *file, unsigned int cmd,
/* okay, let's send it to the client */
req->in.h.opcode = FUSE_IOCTL;
- req->in.h.nodeid = get_node_id(inode);
+ req->in.h.nodeid = ff->nodeid;
req->in.numargs = 1;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
@@ -1777,17 +1817,33 @@ static long fuse_file_do_ioctl(struct file *file, unsigned int cmd,
return err ? err : outarg.result;
}
+EXPORT_SYMBOL_GPL(fuse_do_ioctl);
+
+static long fuse_file_ioctl_common(struct file *file, unsigned int cmd,
+ unsigned long arg, unsigned int flags)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+
+ if (!fuse_allow_task(fc, current))
+ return -EACCES;
+
+ if (is_bad_inode(inode))
+ return -EIO;
+
+ return fuse_do_ioctl(file, cmd, arg, flags);
+}
static long fuse_file_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
- return fuse_file_do_ioctl(file, cmd, arg, 0);
+ return fuse_file_ioctl_common(file, cmd, arg, 0);
}
static long fuse_file_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
- return fuse_file_do_ioctl(file, cmd, arg, FUSE_IOCTL_COMPAT);
+ return fuse_file_ioctl_common(file, cmd, arg, FUSE_IOCTL_COMPAT);
}
/*
@@ -1841,11 +1897,10 @@ static void fuse_register_polled_file(struct fuse_conn *fc,
spin_unlock(&fc->lock);
}
-static unsigned fuse_file_poll(struct file *file, poll_table *wait)
+unsigned fuse_file_poll(struct file *file, poll_table *wait)
{
- struct inode *inode = file->f_dentry->d_inode;
struct fuse_file *ff = file->private_data;
- struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_conn *fc = ff->fc;
struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh };
struct fuse_poll_out outarg;
struct fuse_req *req;
@@ -1870,7 +1925,7 @@ static unsigned fuse_file_poll(struct file *file, poll_table *wait)
return PTR_ERR(req);
req->in.h.opcode = FUSE_POLL;
- req->in.h.nodeid = get_node_id(inode);
+ req->in.h.nodeid = ff->nodeid;
req->in.numargs = 1;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
@@ -1889,6 +1944,7 @@ static unsigned fuse_file_poll(struct file *file, poll_table *wait)
}
return POLLERR;
}
+EXPORT_SYMBOL_GPL(fuse_file_poll);
/*
* This is called from fuse_handle_notify() on FUSE_NOTIFY_POLL and
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 6fc5aedaa0d5..aaf2f9ff970e 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -97,8 +97,13 @@ struct fuse_inode {
struct list_head writepages;
};
+struct fuse_conn;
+
/** FUSE specific file data */
struct fuse_file {
+ /** Fuse connection for this file */
+ struct fuse_conn *fc;
+
/** Request reserved for flush and release */
struct fuse_req *reserved_req;
@@ -108,9 +113,15 @@ struct fuse_file {
/** File handle used by userspace */
u64 fh;
+ /** Node id of this file */
+ u64 nodeid;
+
/** Refcount */
atomic_t count;
+ /** FOPEN_* flags returned by open */
+ u32 open_flags;
+
/** Entry on inode's write_files list */
struct list_head write_entry;
@@ -185,8 +196,6 @@ enum fuse_req_state {
FUSE_REQ_FINISHED
};
-struct fuse_conn;
-
/**
* A request to the client
*/
@@ -248,11 +257,12 @@ struct fuse_req {
struct fuse_forget_in forget_in;
struct {
struct fuse_release_in in;
- struct vfsmount *vfsmount;
- struct dentry *dentry;
+ struct path path;
} release;
struct fuse_init_in init_in;
struct fuse_init_out init_out;
+ struct cuse_init_in cuse_init_in;
+ struct cuse_init_out cuse_init_out;
struct {
struct fuse_read_in in;
u64 attr_ver;
@@ -386,6 +396,9 @@ struct fuse_conn {
/** Filesystem supports NFS exporting. Only set in INIT */
unsigned export_support:1;
+ /** Set if bdi is valid */
+ unsigned bdi_initialized:1;
+
/*
* The following bitfields are only for optimization purposes
* and hence races in setting them will not cause malfunction
@@ -515,25 +528,24 @@ 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,
- struct inode *inode, loff_t pos, size_t count, int opcode);
+ loff_t pos, size_t count, int opcode);
/**
* Send OPEN or OPENDIR request
*/
-int fuse_open_common(struct inode *inode, struct file *file, int isdir);
+int fuse_open_common(struct inode *inode, struct file *file, bool isdir);
struct fuse_file *fuse_file_alloc(struct fuse_conn *fc);
+struct fuse_file *fuse_file_get(struct fuse_file *ff);
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);
+void fuse_finish_open(struct inode *inode, struct file *file);
-/** Fill in ff->reserved_req with a RELEASE request */
-void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode);
+void fuse_sync_release(struct fuse_file *ff, int flags);
/**
* Send RELEASE or RELEASEDIR request
*/
-int fuse_release_common(struct inode *inode, struct file *file, int isdir);
+void fuse_release_common(struct file *file, int opcode);
/**
* Send FSYNC or FSYNCDIR request
@@ -652,10 +664,12 @@ void fuse_invalidate_entry_cache(struct dentry *entry);
*/
struct fuse_conn *fuse_conn_get(struct fuse_conn *fc);
+void fuse_conn_kill(struct fuse_conn *fc);
+
/**
* Initialize fuse_conn
*/
-int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb);
+void fuse_conn_init(struct fuse_conn *fc);
/**
* Release reference to fuse_conn
@@ -694,4 +708,13 @@ void fuse_release_nowrite(struct inode *inode);
u64 fuse_get_attr_version(struct fuse_conn *fc);
+int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
+ bool isdir);
+ssize_t fuse_direct_io(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos, int write);
+long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
+ unsigned int flags);
+unsigned fuse_file_poll(struct file *file, poll_table *wait);
+int fuse_dev_release(struct inode *inode, struct file *file);
+
#endif /* _FS_FUSE_I_H */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 459b73dd45e1..aeaefca38dea 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -19,6 +19,7 @@
#include <linux/random.h>
#include <linux/sched.h>
#include <linux/exportfs.h>
+#include <linux/smp_lock.h>
MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
MODULE_DESCRIPTION("Filesystem in Userspace");
@@ -259,7 +260,9 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
static void fuse_umount_begin(struct super_block *sb)
{
+ lock_kernel();
fuse_abort_conn(get_fuse_conn_super(sb));
+ unlock_kernel();
}
static void fuse_send_destroy(struct fuse_conn *fc)
@@ -274,11 +277,14 @@ static void fuse_send_destroy(struct fuse_conn *fc)
}
}
-static void fuse_put_super(struct super_block *sb)
+static void fuse_bdi_destroy(struct fuse_conn *fc)
{
- struct fuse_conn *fc = get_fuse_conn_super(sb);
+ if (fc->bdi_initialized)
+ bdi_destroy(&fc->bdi);
+}
- fuse_send_destroy(fc);
+void fuse_conn_kill(struct fuse_conn *fc)
+{
spin_lock(&fc->lock);
fc->connected = 0;
fc->blocked = 0;
@@ -292,8 +298,21 @@ static void fuse_put_super(struct super_block *sb)
list_del(&fc->entry);
fuse_ctl_remove_conn(fc);
mutex_unlock(&fuse_mutex);
- bdi_destroy(&fc->bdi);
+ fuse_bdi_destroy(fc);
+}
+EXPORT_SYMBOL_GPL(fuse_conn_kill);
+
+static void fuse_put_super(struct super_block *sb)
+{
+ struct fuse_conn *fc = get_fuse_conn_super(sb);
+
+ lock_kernel();
+
+ fuse_send_destroy(fc);
+ fuse_conn_kill(fc);
fuse_conn_put(fc);
+
+ unlock_kernel();
}
static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr)
@@ -463,10 +482,8 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
return 0;
}
-int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb)
+void fuse_conn_init(struct fuse_conn *fc)
{
- int err;
-
memset(fc, 0, sizeof(*fc));
spin_lock_init(&fc->lock);
mutex_init(&fc->inst_mutex);
@@ -481,49 +498,12 @@ int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb)
INIT_LIST_HEAD(&fc->bg_queue);
INIT_LIST_HEAD(&fc->entry);
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;
- /* fuse does it's own writeback accounting */
- fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB;
fc->khctr = 0;
fc->polled_files = RB_ROOT;
- fc->dev = sb->s_dev;
- err = bdi_init(&fc->bdi);
- if (err)
- goto error_mutex_destroy;
- if (sb->s_bdev) {
- err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk",
- MAJOR(fc->dev), MINOR(fc->dev));
- } else {
- err = bdi_register_dev(&fc->bdi, fc->dev);
- }
- if (err)
- goto error_bdi_destroy;
- /*
- * For a single fuse filesystem use max 1% of dirty +
- * writeback threshold.
- *
- * This gives about 1M of write buffer for memory maps on a
- * machine with 1G and 10% dirty_ratio, which should be more
- * than enough.
- *
- * Privileged users can raise it by writing to
- *
- * /sys/class/bdi/<bdi>/max_ratio
- */
- bdi_set_max_ratio(&fc->bdi, 1);
fc->reqctr = 0;
fc->blocked = 1;
fc->attr_version = 1;
get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
-
- return 0;
-
- error_bdi_destroy:
- bdi_destroy(&fc->bdi);
- error_mutex_destroy:
- mutex_destroy(&fc->inst_mutex);
- return err;
}
EXPORT_SYMBOL_GPL(fuse_conn_init);
@@ -536,12 +516,14 @@ void fuse_conn_put(struct fuse_conn *fc)
fc->release(fc);
}
}
+EXPORT_SYMBOL_GPL(fuse_conn_put);
struct fuse_conn *fuse_conn_get(struct fuse_conn *fc)
{
atomic_inc(&fc->count);
return fc;
}
+EXPORT_SYMBOL_GPL(fuse_conn_get);
static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned mode)
{
@@ -794,6 +776,48 @@ static void fuse_free_conn(struct fuse_conn *fc)
kfree(fc);
}
+static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
+{
+ int err;
+
+ fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
+ fc->bdi.unplug_io_fn = default_unplug_io_fn;
+ /* fuse does it's own writeback accounting */
+ fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB;
+
+ err = bdi_init(&fc->bdi);
+ if (err)
+ return err;
+
+ fc->bdi_initialized = 1;
+
+ if (sb->s_bdev) {
+ err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk",
+ MAJOR(fc->dev), MINOR(fc->dev));
+ } else {
+ err = bdi_register_dev(&fc->bdi, fc->dev);
+ }
+
+ if (err)
+ return err;
+
+ /*
+ * For a single fuse filesystem use max 1% of dirty +
+ * writeback threshold.
+ *
+ * This gives about 1M of write buffer for memory maps on a
+ * machine with 1G and 10% dirty_ratio, which should be more
+ * than enough.
+ *
+ * Privileged users can raise it by writing to
+ *
+ * /sys/class/bdi/<bdi>/max_ratio
+ */
+ bdi_set_max_ratio(&fc->bdi, 1);
+
+ return 0;
+}
+
static int fuse_fill_super(struct super_block *sb, void *data, int silent)
{
struct fuse_conn *fc;
@@ -840,11 +864,12 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
if (!fc)
goto err_fput;
- err = fuse_conn_init(fc, sb);
- if (err) {
- kfree(fc);
- goto err_fput;
- }
+ fuse_conn_init(fc);
+
+ fc->dev = sb->s_dev;
+ err = fuse_bdi_init(fc, sb);
+ if (err)
+ goto err_put_conn;
fc->release = fuse_free_conn;
fc->flags = d.flags;
@@ -908,6 +933,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
err_put_root:
dput(root_dentry);
err_put_conn:
+ fuse_bdi_destroy(fc);
fuse_conn_put(fc);
err_fput:
fput(file);
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 1afd9f26bcb1..ff4981090489 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1304,6 +1304,7 @@ static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask)
nr--;
if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
gfs2_glock_put(gl);
+ got_ref = 0;
}
spin_lock(&lru_lock);
if (may_demote)
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 98918a756410..f2e449c595b4 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -120,7 +120,7 @@ __acquires(&sdp->sd_log_lock)
lock_buffer(bh);
if (test_clear_buffer_dirty(bh)) {
bh->b_end_io = end_buffer_write_sync;
- submit_bh(WRITE, bh);
+ submit_bh(WRITE_SYNC_PLUG, bh);
} else {
unlock_buffer(bh);
brelse(bh);
@@ -604,7 +604,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags))
goto skip_barrier;
get_bh(bh);
- submit_bh(WRITE_BARRIER | (1 << BIO_RW_META), bh);
+ submit_bh(WRITE_SYNC | (1 << BIO_RW_BARRIER) | (1 << BIO_RW_META), bh);
wait_on_buffer(bh);
if (buffer_eopnotsupp(bh)) {
clear_buffer_eopnotsupp(bh);
@@ -664,7 +664,7 @@ static void gfs2_ordered_write(struct gfs2_sbd *sdp)
lock_buffer(bh);
if (buffer_mapped(bh) && test_clear_buffer_dirty(bh)) {
bh->b_end_io = end_buffer_write_sync;
- submit_bh(WRITE, bh);
+ submit_bh(WRITE_SYNC_PLUG, bh);
} else {
unlock_buffer(bh);
brelse(bh);
@@ -764,7 +764,6 @@ void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
}
gfs2_log_unlock(sdp);
- sdp->sd_vfs->s_dirt = 0;
up_write(&sdp->sd_log_flush_lock);
kfree(ai);
@@ -823,7 +822,6 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
log_refund(sdp, tr);
buf_lo_incore_commit(sdp, tr);
- sdp->sd_vfs->s_dirt = 1;
up_read(&sdp->sd_log_flush_lock);
gfs2_log_lock(sdp);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 80e4f5f898bb..00315f50fa46 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -13,6 +13,8 @@
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/gfs2_ondisk.h>
+#include <linux/bio.h>
+#include <linux/fs.h>
#include "gfs2.h"
#include "incore.h"
@@ -189,7 +191,7 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp)
}
gfs2_log_unlock(sdp);
- submit_bh(WRITE, bh);
+ submit_bh(WRITE_SYNC_PLUG, bh);
gfs2_log_lock(sdp);
n = 0;
@@ -199,7 +201,7 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp)
gfs2_log_unlock(sdp);
lock_buffer(bd2->bd_bh);
bh = gfs2_log_fake_buf(sdp, bd2->bd_bh);
- submit_bh(WRITE, bh);
+ submit_bh(WRITE_SYNC_PLUG, bh);
gfs2_log_lock(sdp);
if (++n >= num)
break;
@@ -341,7 +343,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
sdp->sd_log_num_revoke--;
if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) {
- submit_bh(WRITE, bh);
+ submit_bh(WRITE_SYNC_PLUG, bh);
bh = gfs2_log_get_buf(sdp);
mh = (struct gfs2_meta_header *)bh->b_data;
@@ -358,7 +360,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
}
gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
- submit_bh(WRITE, bh);
+ submit_bh(WRITE_SYNC_PLUG, bh);
}
static void revoke_lo_before_scan(struct gfs2_jdesc *jd,
@@ -560,7 +562,7 @@ static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh,
ptr = bh_log_ptr(bh);
get_bh(bh);
- submit_bh(WRITE, bh);
+ submit_bh(WRITE_SYNC_PLUG, bh);
gfs2_log_lock(sdp);
while(!list_empty(list)) {
bd = list_entry(list->next, struct gfs2_bufdata, bd_le.le_list);
@@ -586,7 +588,7 @@ static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh,
} else {
bh1 = gfs2_log_fake_buf(sdp, bd->bd_bh);
}
- submit_bh(WRITE, bh1);
+ submit_bh(WRITE_SYNC_PLUG, bh1);
gfs2_log_lock(sdp);
ptr += 2;
}
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 8d6f13256b26..78a5f4312667 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -33,17 +33,65 @@
#include "util.h"
#include "ops_address.h"
-static int aspace_get_block(struct inode *inode, sector_t lblock,
- struct buffer_head *bh_result, int create)
+static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wbc)
{
- gfs2_assert_warn(inode->i_sb->s_fs_info, 0);
- return -EOPNOTSUPP;
-}
+ int err;
+ struct buffer_head *bh, *head;
+ int nr_underway = 0;
+ int write_op = (1 << BIO_RW_META) | ((wbc->sync_mode == WB_SYNC_ALL ?
+ WRITE_SYNC_PLUG : WRITE));
+
+ BUG_ON(!PageLocked(page));
+ BUG_ON(!page_has_buffers(page));
+
+ head = page_buffers(page);
+ bh = head;
+
+ do {
+ if (!buffer_mapped(bh))
+ continue;
+ /*
+ * If it's a fully non-blocking write attempt and we cannot
+ * lock the buffer then redirty the page. Note that this can
+ * potentially cause a busy-wait loop from pdflush and kswapd
+ * activity, but those code paths have their own higher-level
+ * throttling.
+ */
+ if (wbc->sync_mode != WB_SYNC_NONE || !wbc->nonblocking) {
+ lock_buffer(bh);
+ } else if (!trylock_buffer(bh)) {
+ redirty_page_for_writepage(wbc, page);
+ continue;
+ }
+ if (test_clear_buffer_dirty(bh)) {
+ mark_buffer_async_write(bh);
+ } else {
+ unlock_buffer(bh);
+ }
+ } while ((bh = bh->b_this_page) != head);
+
+ /*
+ * The page and its buffers are protected by PageWriteback(), so we can
+ * drop the bh refcounts early.
+ */
+ BUG_ON(PageWriteback(page));
+ set_page_writeback(page);
+
+ do {
+ struct buffer_head *next = bh->b_this_page;
+ if (buffer_async_write(bh)) {
+ submit_bh(write_op, bh);
+ nr_underway++;
+ }
+ bh = next;
+ } while (bh != head);
+ unlock_page(page);
-static int gfs2_aspace_writepage(struct page *page,
- struct writeback_control *wbc)
-{
- return block_write_full_page(page, aspace_get_block, wbc);
+ err = 0;
+ if (nr_underway == 0)
+ end_page_writeback(page);
+
+ return err;
}
static const struct address_space_operations aspace_aops = {
@@ -201,16 +249,32 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno)
int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
struct buffer_head **bhp)
{
- *bhp = gfs2_getbuf(gl, blkno, CREATE);
- if (!buffer_uptodate(*bhp)) {
- ll_rw_block(READ_META, 1, bhp);
- if (flags & DIO_WAIT) {
- int error = gfs2_meta_wait(gl->gl_sbd, *bhp);
- if (error) {
- brelse(*bhp);
- return error;
- }
- }
+ struct gfs2_sbd *sdp = gl->gl_sbd;
+ struct buffer_head *bh;
+
+ if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
+ return -EIO;
+
+ *bhp = bh = gfs2_getbuf(gl, blkno, CREATE);
+
+ lock_buffer(bh);
+ if (buffer_uptodate(bh)) {
+ unlock_buffer(bh);
+ return 0;
+ }
+ bh->b_end_io = end_buffer_read_sync;
+ get_bh(bh);
+ submit_bh(READ_SYNC | (1 << BIO_RW_META), bh);
+ if (!(flags & DIO_WAIT))
+ return 0;
+
+ wait_on_buffer(bh);
+ if (unlikely(!buffer_uptodate(bh))) {
+ struct gfs2_trans *tr = current->journal_info;
+ if (tr && tr->tr_touched)
+ gfs2_io_error_bh(sdp, bh);
+ brelse(bh);
+ return -EIO;
}
return 0;
@@ -404,7 +468,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen)
if (buffer_uptodate(first_bh))
goto out;
if (!buffer_locked(first_bh))
- ll_rw_block(READ_META, 1, &first_bh);
+ ll_rw_block(READ_SYNC | (1 << BIO_RW_META), 1, &first_bh);
dblock++;
extlen--;
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index a6dde1751e17..e5664210f0d8 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -781,10 +781,12 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
unlock_page(page);
page_cache_release(page);
- if (inode->i_size < to) {
- i_size_write(inode, to);
- ip->i_disksize = inode->i_size;
- di->di_size = cpu_to_be64(inode->i_size);
+ if (copied) {
+ if (inode->i_size < to) {
+ i_size_write(inode, to);
+ ip->i_disksize = inode->i_size;
+ }
+ gfs2_dinode_out(ip, di);
mark_inode_dirty(inode);
}
@@ -824,7 +826,6 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
struct gfs2_sbd *sdp = GFS2_SB(inode);
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;
@@ -847,11 +848,10 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
gfs2_page_add_databufs(ip, page, from, to);
ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
-
- if (likely(ret >= 0) && (inode->i_size > ip->i_disksize)) {
- di = (struct gfs2_dinode *)dibh->b_data;
- ip->i_disksize = inode->i_size;
- di->di_size = cpu_to_be64(inode->i_size);
+ if (ret > 0) {
+ if (inode->i_size > ip->i_disksize)
+ ip->i_disksize = inode->i_size;
+ gfs2_dinode_out(ip, dibh->b_data);
mark_inode_dirty(inode);
}
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 5d82e91887e3..0ee7bd287c5a 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -425,33 +425,36 @@ static struct vm_operations_struct gfs2_vm_ops = {
.page_mkwrite = gfs2_page_mkwrite,
};
-
/**
* gfs2_mmap -
* @file: The file to map
* @vma: The VMA which described the mapping
*
- * Returns: 0 or error code
+ * There is no need to get a lock here unless we should be updating
+ * atime. We ignore any locking errors since the only consequence is
+ * a missed atime update (which will just be deferred until later).
+ *
+ * Returns: 0
*/
static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
{
struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
- struct gfs2_holder i_gh;
- int error;
- gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh);
- error = gfs2_glock_nq(&i_gh);
- if (error) {
- gfs2_holder_uninit(&i_gh);
- return error;
- }
+ if (!(file->f_flags & O_NOATIME)) {
+ struct gfs2_holder i_gh;
+ int error;
+ gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
+ error = gfs2_glock_nq(&i_gh);
+ file_accessed(file);
+ if (error == 0)
+ gfs2_glock_dq_uninit(&i_gh);
+ }
vma->vm_ops = &gfs2_vm_ops;
+ vma->vm_flags |= VM_CAN_NONLINEAR;
- gfs2_glock_dq_uninit(&i_gh);
-
- return error;
+ return 0;
}
/**
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 650a730707b7..1ff9473ea753 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1282,21 +1282,21 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
static struct super_block *get_gfs2_sb(const char *dev_name)
{
struct super_block *sb;
- struct nameidata nd;
+ struct path path;
int error;
- error = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
+ error = kern_path(dev_name, LOOKUP_FOLLOW, &path);
if (error) {
printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n",
dev_name, error);
return NULL;
}
- sb = nd.path.dentry->d_inode->i_sb;
+ sb = path.dentry->d_inode->i_sb;
if (sb && (sb->s_type == &gfs2_fs_type))
atomic_inc(&sb->s_active);
else
sb = NULL;
- path_put(&nd.path);
+ path_put(&path);
return sb;
}
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 458019569dcb..1331f070520a 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -132,6 +132,8 @@ static void gfs2_put_super(struct super_block *sb)
struct gfs2_sbd *sdp = sb->s_fs_info;
int error;
+ lock_kernel();
+
/* Unfreeze the filesystem, if we need to */
mutex_lock(&sdp->sd_freeze_lock);
@@ -182,17 +184,8 @@ static void gfs2_put_super(struct super_block *sb)
/* At this point, we're through participating in the lockspace */
gfs2_sys_fs_del(sdp);
-}
-
-/**
- * gfs2_write_super
- * @sb: the superblock
- *
- */
-static void gfs2_write_super(struct super_block *sb)
-{
- sb->s_dirt = 0;
+ unlock_kernel();
}
/**
@@ -204,7 +197,6 @@ static void gfs2_write_super(struct super_block *sb)
static int gfs2_sync_fs(struct super_block *sb, int wait)
{
- sb->s_dirt = 0;
if (wait && sb->s_fs_info)
gfs2_log_flush(sb->s_fs_info, NULL);
return 0;
@@ -710,7 +702,6 @@ const struct super_operations gfs2_super_ops = {
.write_inode = gfs2_write_inode,
.delete_inode = gfs2_delete_inode,
.put_super = gfs2_put_super,
- .write_super = gfs2_write_super,
.sync_fs = gfs2_sync_fs,
.freeze_fs = gfs2_freeze,
.unfreeze_fs = gfs2_unfreeze,
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index a36bb749926d..3aac41751030 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -49,11 +49,13 @@ MODULE_LICENSE("GPL");
*/
static void hfs_write_super(struct super_block *sb)
{
+ lock_super(sb);
sb->s_dirt = 0;
- if (sb->s_flags & MS_RDONLY)
- return;
+
/* sync everything to the buffers */
- hfs_mdb_commit(sb);
+ if (!(sb->s_flags & MS_RDONLY))
+ hfs_mdb_commit(sb);
+ unlock_super(sb);
}
/*
@@ -65,9 +67,15 @@ static void hfs_write_super(struct super_block *sb)
*/
static void hfs_put_super(struct super_block *sb)
{
+ lock_kernel();
+
+ if (sb->s_dirt)
+ hfs_write_super(sb);
hfs_mdb_close(sb);
/* release the MDB's resources */
hfs_mdb_put(sb);
+
+ unlock_kernel();
}
/*
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index f2a64020f42e..1aab8aa7801e 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -157,10 +157,12 @@ static void hfsplus_write_super(struct super_block *sb)
struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
dprint(DBG_SUPER, "hfsplus_write_super\n");
+
+ lock_super(sb);
sb->s_dirt = 0;
if (sb->s_flags & MS_RDONLY)
/* warn? */
- return;
+ goto out;
vhdr->free_blocks = cpu_to_be32(HFSPLUS_SB(sb).free_blocks);
vhdr->next_alloc = cpu_to_be32(HFSPLUS_SB(sb).next_alloc);
@@ -192,6 +194,8 @@ static void hfsplus_write_super(struct super_block *sb)
}
HFSPLUS_SB(sb).flags &= ~HFSPLUS_SB_WRITEBACKUP;
}
+ out:
+ unlock_super(sb);
}
static void hfsplus_put_super(struct super_block *sb)
@@ -199,6 +203,11 @@ static void hfsplus_put_super(struct super_block *sb)
dprint(DBG_SUPER, "hfsplus_put_super\n");
if (!sb->s_fs_info)
return;
+
+ lock_kernel();
+
+ if (sb->s_dirt)
+ hfsplus_write_super(sb);
if (!(sb->s_flags & MS_RDONLY) && HFSPLUS_SB(sb).s_vhdr) {
struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
@@ -218,6 +227,8 @@ static void hfsplus_put_super(struct super_block *sb)
unload_nls(HFSPLUS_SB(sb).nls);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
+
+ unlock_kernel();
}
static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf)
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index fecf402d7b8a..f68193cf0811 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -99,11 +99,16 @@ int hpfs_stop_cycles(struct super_block *s, int key, int *c1, int *c2,
static void hpfs_put_super(struct super_block *s)
{
struct hpfs_sb_info *sbi = hpfs_sb(s);
+
+ lock_kernel();
+
kfree(sbi->sb_cp_table);
kfree(sbi->sb_bmp_dir);
unmark_dirty(s);
s->s_fs_info = NULL;
kfree(sbi);
+
+ unlock_kernel();
}
unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno)
@@ -393,6 +398,7 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
*flags |= MS_NOATIME;
+ lock_super(s);
uid = sbi->sb_uid; gid = sbi->sb_gid;
umask = 0777 & ~sbi->sb_mode;
lowercase = sbi->sb_lowercase; conv = sbi->sb_conv;
@@ -423,12 +429,13 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
if (!(*flags & MS_RDONLY)) mark_dirty(s);
- kfree(s->s_options);
- s->s_options = new_opts;
+ replace_mount_options(s, new_opts);
+ unlock_super(s);
return 0;
out_err:
+ unlock_super(s);
kfree(new_opts);
return -EINVAL;
}
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 153d9681192b..c1462d43e721 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -312,16 +312,6 @@ out:
return retval;
}
-/*
- * Read a page. Again trivial. If it didn't already exist
- * in the page cache, it is zero-filled.
- */
-static int hugetlbfs_readpage(struct file *file, struct page * page)
-{
- unlock_page(page);
- return -EINVAL;
-}
-
static int hugetlbfs_write_begin(struct file *file,
struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
@@ -701,7 +691,6 @@ static void hugetlbfs_destroy_inode(struct inode *inode)
}
static const struct address_space_operations hugetlbfs_aops = {
- .readpage = hugetlbfs_readpage,
.write_begin = hugetlbfs_write_begin,
.write_end = hugetlbfs_write_end,
.set_page_dirty = hugetlbfs_set_page_dirty,
diff --git a/fs/inode.c b/fs/inode.c
index 29ca11433325..03de16a904b5 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -99,7 +99,7 @@ static DEFINE_MUTEX(iprune_mutex);
*/
struct inodes_stat_t inodes_stat;
-static struct kmem_cache * inode_cachep __read_mostly;
+static struct kmem_cache *inode_cachep __read_mostly;
static void wake_up_inode(struct inode *inode)
{
@@ -124,7 +124,7 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
static struct inode_operations empty_iops;
static const struct file_operations empty_fops;
- struct address_space * const mapping = &inode->i_data;
+ struct address_space *const mapping = &inode->i_data;
inode->i_sb = sb;
inode->i_blkbits = sb->s_blocksize_bits;
@@ -216,7 +216,7 @@ static struct inode *alloc_inode(struct super_block *sb)
return NULL;
}
-void destroy_inode(struct inode *inode)
+void destroy_inode(struct inode *inode)
{
BUG_ON(inode_has_buffers(inode));
security_inode_free(inode);
@@ -252,12 +252,11 @@ void inode_init_once(struct inode *inode)
mutex_init(&inode->inotify_mutex);
#endif
}
-
EXPORT_SYMBOL(inode_init_once);
static void init_once(void *foo)
{
- struct inode * inode = (struct inode *) foo;
+ struct inode *inode = (struct inode *) foo;
inode_init_once(inode);
}
@@ -265,7 +264,7 @@ static void init_once(void *foo)
/*
* inode_lock must be held
*/
-void __iget(struct inode * inode)
+void __iget(struct inode *inode)
{
if (atomic_read(&inode->i_count)) {
atomic_inc(&inode->i_count);
@@ -289,7 +288,7 @@ void clear_inode(struct inode *inode)
{
might_sleep();
invalidate_inode_buffers(inode);
-
+
BUG_ON(inode->i_data.nrpages);
BUG_ON(!(inode->i_state & I_FREEING));
BUG_ON(inode->i_state & I_CLEAR);
@@ -303,7 +302,6 @@ void clear_inode(struct inode *inode)
cd_forget(inode);
inode->i_state = I_CLEAR;
}
-
EXPORT_SYMBOL(clear_inode);
/*
@@ -351,8 +349,8 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
next = head->next;
for (;;) {
- struct list_head * tmp = next;
- struct inode * inode;
+ struct list_head *tmp = next;
+ struct inode *inode;
/*
* We can reschedule here without worrying about the list's
@@ -391,7 +389,7 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
* fails because there are busy inodes then a non zero value is returned.
* If the discard is successful all the inodes have been discarded.
*/
-int invalidate_inodes(struct super_block * sb)
+int invalidate_inodes(struct super_block *sb)
{
int busy;
LIST_HEAD(throw_away);
@@ -407,7 +405,6 @@ int invalidate_inodes(struct super_block * sb)
return busy;
}
-
EXPORT_SYMBOL(invalidate_inodes);
static int can_unuse(struct inode *inode)
@@ -504,7 +501,7 @@ static int shrink_icache_memory(int nr, gfp_t gfp_mask)
* Nasty deadlock avoidance. We may hold various FS locks,
* and we don't want to recurse into the FS that called us
* in clear_inode() and friends..
- */
+ */
if (!(gfp_mask & __GFP_FS))
return -1;
prune_icache(nr);
@@ -524,10 +521,13 @@ static void __wait_on_freeing_inode(struct inode *inode);
* by hand after calling find_inode now! This simplifies iunique and won't
* add any additional branch in the common code.
*/
-static struct inode * find_inode(struct super_block * sb, struct hlist_head *head, int (*test)(struct inode *, void *), void *data)
+static struct inode *find_inode(struct super_block *sb,
+ struct hlist_head *head,
+ int (*test)(struct inode *, void *),
+ void *data)
{
struct hlist_node *node;
- struct inode * inode = NULL;
+ struct inode *inode = NULL;
repeat:
hlist_for_each_entry(inode, node, head, i_hash) {
@@ -548,10 +548,11 @@ repeat:
* find_inode_fast is the fast path version of find_inode, see the comment at
* iget_locked for details.
*/
-static struct inode * find_inode_fast(struct super_block * sb, struct hlist_head *head, unsigned long ino)
+static struct inode *find_inode_fast(struct super_block *sb,
+ struct hlist_head *head, unsigned long ino)
{
struct hlist_node *node;
- struct inode * inode = NULL;
+ struct inode *inode = NULL;
repeat:
hlist_for_each_entry(inode, node, head, i_hash) {
@@ -631,10 +632,10 @@ struct inode *new_inode(struct super_block *sb)
* here to attempt to avoid that.
*/
static unsigned int last_ino;
- struct inode * inode;
+ struct inode *inode;
spin_lock_prefetch(&inode_lock);
-
+
inode = alloc_inode(sb);
if (inode) {
spin_lock(&inode_lock);
@@ -645,7 +646,6 @@ struct inode *new_inode(struct super_block *sb)
}
return inode;
}
-
EXPORT_SYMBOL(new_inode);
void unlock_new_inode(struct inode *inode)
@@ -674,7 +674,6 @@ void unlock_new_inode(struct inode *inode)
inode->i_state &= ~(I_LOCK|I_NEW);
wake_up_inode(inode);
}
-
EXPORT_SYMBOL(unlock_new_inode);
/*
@@ -683,13 +682,17 @@ EXPORT_SYMBOL(unlock_new_inode);
* We no longer cache the sb_flags in i_flags - see fs.h
* -- rmk@arm.uk.linux.org
*/
-static struct inode * get_new_inode(struct super_block *sb, struct hlist_head *head, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data)
+static struct inode *get_new_inode(struct super_block *sb,
+ struct hlist_head *head,
+ int (*test)(struct inode *, void *),
+ int (*set)(struct inode *, void *),
+ void *data)
{
- struct inode * inode;
+ struct inode *inode;
inode = alloc_inode(sb);
if (inode) {
- struct inode * old;
+ struct inode *old;
spin_lock(&inode_lock);
/* We released the lock, so.. */
@@ -731,13 +734,14 @@ set_failed:
* get_new_inode_fast is the fast path version of get_new_inode, see the
* comment at iget_locked for details.
*/
-static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_head *head, unsigned long ino)
+static struct inode *get_new_inode_fast(struct super_block *sb,
+ struct hlist_head *head, unsigned long ino)
{
- struct inode * inode;
+ struct inode *inode;
inode = alloc_inode(sb);
if (inode) {
- struct inode * old;
+ struct inode *old;
spin_lock(&inode_lock);
/* We released the lock, so.. */
@@ -823,7 +827,6 @@ struct inode *igrab(struct inode *inode)
spin_unlock(&inode_lock);
return inode;
}
-
EXPORT_SYMBOL(igrab);
/**
@@ -924,7 +927,6 @@ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,
return ifind(sb, head, test, data, 0);
}
-
EXPORT_SYMBOL(ilookup5_nowait);
/**
@@ -953,7 +955,6 @@ struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
return ifind(sb, head, test, data, 1);
}
-
EXPORT_SYMBOL(ilookup5);
/**
@@ -976,7 +977,6 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino)
return ifind_fast(sb, head, ino);
}
-
EXPORT_SYMBOL(ilookup);
/**
@@ -1015,7 +1015,6 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
*/
return get_new_inode(sb, head, test, set, data);
}
-
EXPORT_SYMBOL(iget5_locked);
/**
@@ -1047,7 +1046,6 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
*/
return get_new_inode_fast(sb, head, ino);
}
-
EXPORT_SYMBOL(iget_locked);
int insert_inode_locked(struct inode *inode)
@@ -1076,7 +1074,6 @@ int insert_inode_locked(struct inode *inode)
iput(old);
}
}
-
EXPORT_SYMBOL(insert_inode_locked);
int insert_inode_locked4(struct inode *inode, unsigned long hashval,
@@ -1106,7 +1103,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
iput(old);
}
}
-
EXPORT_SYMBOL(insert_inode_locked4);
/**
@@ -1124,7 +1120,6 @@ void __insert_inode_hash(struct inode *inode, unsigned long hashval)
hlist_add_head(&inode->i_hash, head);
spin_unlock(&inode_lock);
}
-
EXPORT_SYMBOL(__insert_inode_hash);
/**
@@ -1139,7 +1134,6 @@ void remove_inode_hash(struct inode *inode)
hlist_del_init(&inode->i_hash);
spin_unlock(&inode_lock);
}
-
EXPORT_SYMBOL(remove_inode_hash);
/*
@@ -1187,7 +1181,6 @@ void generic_delete_inode(struct inode *inode)
BUG_ON(inode->i_state != I_CLEAR);
destroy_inode(inode);
}
-
EXPORT_SYMBOL(generic_delete_inode);
static void generic_forget_inode(struct inode *inode)
@@ -1237,12 +1230,11 @@ void generic_drop_inode(struct inode *inode)
else
generic_forget_inode(inode);
}
-
EXPORT_SYMBOL_GPL(generic_drop_inode);
/*
* Called when we're dropping the last reference
- * to an inode.
+ * to an inode.
*
* Call the FS "drop()" function, defaulting to
* the legacy UNIX filesystem behaviour..
@@ -1262,7 +1254,7 @@ static inline void iput_final(struct inode *inode)
}
/**
- * iput - put an inode
+ * iput - put an inode
* @inode: inode to put
*
* Puts an inode, dropping its usage count. If the inode use count hits
@@ -1279,7 +1271,6 @@ void iput(struct inode *inode)
iput_final(inode);
}
}
-
EXPORT_SYMBOL(iput);
/**
@@ -1290,10 +1281,10 @@ EXPORT_SYMBOL(iput);
* Returns the block number on the device holding the inode that
* is the disk block number for the block of the file requested.
* That is, asked for block 4 of inode 1 the function will return the
- * disk block relative to the disk start that holds that block of the
+ * disk block relative to the disk start that holds that block of the
* file.
*/
-sector_t bmap(struct inode * inode, sector_t block)
+sector_t bmap(struct inode *inode, sector_t block)
{
sector_t res = 0;
if (inode->i_mapping->a_ops->bmap)
@@ -1401,7 +1392,7 @@ void file_update_time(struct file *file)
if (IS_NOCMTIME(inode))
return;
- err = mnt_want_write(file->f_path.mnt);
+ err = mnt_want_write_file(file);
if (err)
return;
@@ -1425,7 +1416,6 @@ void file_update_time(struct file *file)
mark_inode_dirty_sync(inode);
mnt_drop_write(file->f_path.mnt);
}
-
EXPORT_SYMBOL(file_update_time);
int inode_needs_sync(struct inode *inode)
@@ -1436,7 +1426,6 @@ int inode_needs_sync(struct inode *inode)
return 1;
return 0;
}
-
EXPORT_SYMBOL(inode_needs_sync);
int inode_wait(void *word)
diff --git a/fs/internal.h b/fs/internal.h
index b4dac4fb6b61..d55ef562f0bb 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -25,6 +25,8 @@ static inline int sb_is_blkdev_sb(struct super_block *sb)
return sb == blockdev_superblock;
}
+extern int __sync_blockdev(struct block_device *bdev, int wait);
+
#else
static inline void bdev_cache_init(void)
{
@@ -34,6 +36,11 @@ static inline int sb_is_blkdev_sb(struct super_block *sb)
{
return 0;
}
+
+static inline int __sync_blockdev(struct block_device *bdev, int wait)
+{
+ return 0;
+}
#endif
/*
@@ -66,3 +73,13 @@ extern void __init mnt_init(void);
* fs_struct.c
*/
extern void chroot_fs_refs(struct path *, struct path *);
+
+/*
+ * file_table.c
+ */
+extern void mark_files_ro(struct super_block *);
+
+/*
+ * super.c
+ */
+extern int do_remount_sb(struct super_block *, int, void *, int);
diff --git a/fs/ioctl.c b/fs/ioctl.c
index ac2d47e43926..286f38dfc6c0 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -258,7 +258,7 @@ int __generic_block_fiemap(struct inode *inode,
long long length = 0, map_len = 0;
u64 logical = 0, phys = 0, size = 0;
u32 flags = FIEMAP_EXTENT_MERGED;
- int ret = 0;
+ int ret = 0, past_eof = 0, whole_file = 0;
if ((ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC)))
return ret;
@@ -266,6 +266,9 @@ int __generic_block_fiemap(struct inode *inode,
start_blk = logical_to_blk(inode, start);
length = (long long)min_t(u64, len, i_size_read(inode));
+ if (length < len)
+ whole_file = 1;
+
map_len = length;
do {
@@ -282,11 +285,26 @@ int __generic_block_fiemap(struct inode *inode,
/* HOLE */
if (!buffer_mapped(&tmp)) {
+ length -= blk_to_logical(inode, 1);
+ start_blk++;
+
+ /*
+ * we want to handle the case where there is an
+ * allocated block at the front of the file, and then
+ * nothing but holes up to the end of the file properly,
+ * to make sure that extent at the front gets properly
+ * marked with FIEMAP_EXTENT_LAST
+ */
+ if (!past_eof &&
+ blk_to_logical(inode, start_blk) >=
+ blk_to_logical(inode, 0)+i_size_read(inode))
+ past_eof = 1;
+
/*
* first hole after going past the EOF, this is our
* last extent
*/
- if (length <= 0) {
+ if (past_eof && size) {
flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST;
ret = fiemap_fill_next_extent(fieinfo, logical,
phys, size,
@@ -294,15 +312,37 @@ int __generic_block_fiemap(struct inode *inode,
break;
}
- length -= blk_to_logical(inode, 1);
-
/* if we have holes up to/past EOF then we're done */
- if (length <= 0)
+ if (length <= 0 || past_eof)
break;
-
- start_blk++;
} else {
- if (length <= 0 && size) {
+ /*
+ * we have gone over the length of what we wanted to
+ * map, and it wasn't the entire file, so add the extent
+ * we got last time and exit.
+ *
+ * This is for the case where say we want to map all the
+ * way up to the second to the last block in a file, but
+ * the last block is a hole, making the second to last
+ * block FIEMAP_EXTENT_LAST. In this case we want to
+ * see if there is a hole after the second to last block
+ * so we can mark it properly. If we found data after
+ * we exceeded the length we were requesting, then we
+ * are good to go, just add the extent to the fieinfo
+ * and break
+ */
+ if (length <= 0 && !whole_file) {
+ ret = fiemap_fill_next_extent(fieinfo, logical,
+ phys, size,
+ flags);
+ break;
+ }
+
+ /*
+ * if size != 0 then we know we already have an extent
+ * to add, so add it.
+ */
+ if (size) {
ret = fiemap_fill_next_extent(fieinfo, logical,
phys, size,
flags);
@@ -319,19 +359,14 @@ int __generic_block_fiemap(struct inode *inode,
start_blk += logical_to_blk(inode, size);
/*
- * if we are past the EOF we need to loop again to see
- * if there is a hole so we can mark this extent as the
- * last one, and if not keep mapping things until we
- * find a hole, or we run out of slots in the extent
- * array
+ * If we are past the EOF, then we need to make sure as
+ * soon as we find a hole that the last extent we found
+ * is marked with FIEMAP_EXTENT_LAST
*/
- if (length <= 0)
- continue;
-
- ret = fiemap_fill_next_extent(fieinfo, logical, phys,
- size, flags);
- if (ret)
- break;
+ if (!past_eof &&
+ logical+size >=
+ blk_to_logical(inode, 0)+i_size_read(inode))
+ past_eof = 1;
}
cond_resched();
} while (1);
@@ -379,10 +414,6 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
switch (cmd) {
case FIBMAP:
return ioctl_fibmap(filp, p);
- case FS_IOC_FIEMAP:
- return ioctl_fiemap(filp, arg);
- case FIGETBSZ:
- return put_user(inode->i_sb->s_blocksize, p);
case FIONREAD:
return put_user(i_size_read(inode) - filp->f_pos, p);
}
@@ -522,6 +553,16 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
error = ioctl_fsthaw(filp);
break;
+ case FS_IOC_FIEMAP:
+ return ioctl_fiemap(filp, arg);
+
+ case FIGETBSZ:
+ {
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ int __user *p = (int __user *)arg;
+ return put_user(inode->i_sb->s_blocksize, p);
+ }
+
default:
if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
error = file_ioctl(filp, cmd, arg);
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index b4cbe9603c7d..068b34b5a107 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -42,11 +42,16 @@ static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qst
static void isofs_put_super(struct super_block *sb)
{
struct isofs_sb_info *sbi = ISOFS_SB(sb);
+
#ifdef CONFIG_JOLIET
+ lock_kernel();
+
if (sbi->s_nls_iocharset) {
unload_nls(sbi->s_nls_iocharset);
sbi->s_nls_iocharset = NULL;
}
+
+ unlock_kernel();
#endif
kfree(sbi);
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 249305d65d5b..237b27a3d570 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -402,21 +402,6 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
return 0;
}
-void jffs2_write_super (struct super_block *sb)
-{
- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
- sb->s_dirt = 0;
-
- if (sb->s_flags & MS_RDONLY)
- return;
-
- D1(printk(KERN_DEBUG "jffs2_write_super()\n"));
- jffs2_garbage_collect_trigger(c);
- jffs2_erase_pending_blocks(c, 0);
- jffs2_flush_wbuf_gc(c, 0);
-}
-
-
/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
fill in the raw_inode while you're at it. */
struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 5e194a5c8e29..2228380c47b9 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -181,7 +181,6 @@ void jffs2_dirty_inode(struct inode *inode);
struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
struct jffs2_raw_inode *ri);
int jffs2_statfs (struct dentry *, struct kstatfs *);
-void jffs2_write_super (struct super_block *);
int jffs2_remount_fs (struct super_block *, int *, char *);
int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
void jffs2_gc_release_inode(struct jffs2_sb_info *c,
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 4c4e18c54a51..f7bfd3ac8bfa 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -53,6 +53,23 @@ static void jffs2_i_init_once(void *foo)
inode_init_once(&f->vfs_inode);
}
+static void jffs2_write_super(struct super_block *sb)
+{
+ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
+
+ lock_super(sb);
+ sb->s_dirt = 0;
+
+ if (!(sb->s_flags & MS_RDONLY)) {
+ D1(printk(KERN_DEBUG "jffs2_write_super()\n"));
+ jffs2_garbage_collect_trigger(c);
+ jffs2_erase_pending_blocks(c, 0);
+ jffs2_flush_wbuf_gc(c, 0);
+ }
+
+ unlock_super(sb);
+}
+
static int jffs2_sync_fs(struct super_block *sb, int wait)
{
struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
@@ -174,6 +191,11 @@ static void jffs2_put_super (struct super_block *sb)
D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
+ lock_kernel();
+
+ if (sb->s_dirt)
+ jffs2_write_super(sb);
+
mutex_lock(&c->alloc_sem);
jffs2_flush_wbuf_pad(c);
mutex_unlock(&c->alloc_sem);
@@ -192,6 +214,8 @@ static void jffs2_put_super (struct super_block *sb)
if (c->mtd->sync)
c->mtd->sync(c->mtd);
+ unlock_kernel();
+
D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
}
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 6f21adf9479a..3eb13adf3862 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -183,6 +183,9 @@ static void jfs_put_super(struct super_block *sb)
int rc;
jfs_info("In jfs_put_super");
+
+ lock_kernel();
+
rc = jfs_umount(sb);
if (rc)
jfs_err("jfs_umount failed with return code %d", rc);
@@ -195,6 +198,8 @@ static void jfs_put_super(struct super_block *sb)
sbi->direct_inode = NULL;
kfree(sbi);
+
+ unlock_kernel();
}
enum {
@@ -720,8 +725,10 @@ static ssize_t jfs_quota_write(struct super_block *sb, int type,
blk++;
}
out:
- if (len == towrite)
+ if (len == towrite) {
+ mutex_unlock(&inode->i_mutex);
return err;
+ }
if (inode->i_size < off+len-towrite)
i_size_write(inode, off+len-towrite);
inode->i_version++;
diff --git a/fs/libfs.c b/fs/libfs.c
index cd223190c4e9..80046ddf5063 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -246,8 +246,7 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name,
return 0;
Enomem:
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
return -ENOMEM;
}
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index abf83881f68a..1a54ae14a192 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -104,6 +104,16 @@ static void set_grace_period(void)
schedule_delayed_work(&grace_period_end, grace_period);
}
+static void restart_grace(void)
+{
+ if (nlmsvc_ops) {
+ cancel_delayed_work_sync(&grace_period_end);
+ locks_end_grace(&lockd_manager);
+ nlmsvc_invalidate_all();
+ set_grace_period();
+ }
+}
+
/*
* This is the lockd kernel thread
*/
@@ -149,10 +159,7 @@ lockd(void *vrqstp)
if (signalled()) {
flush_signals(current);
- if (nlmsvc_ops) {
- nlmsvc_invalidate_all();
- set_grace_period();
- }
+ restart_grace();
continue;
}
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 83ee34203bd7..e577a78d7bac 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -326,6 +326,8 @@ static void nlmsvc_freegrantargs(struct nlm_rqst *call)
{
if (call->a_args.lock.oh.data != call->a_owner)
kfree(call->a_args.lock.oh.data);
+
+ locks_release_private(&call->a_args.lock.fl);
}
/*
diff --git a/fs/locks.c b/fs/locks.c
index ec3deea29e37..b6440f52178f 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -151,7 +151,7 @@ static struct file_lock *locks_alloc_lock(void)
return kmem_cache_alloc(filelock_cache, GFP_KERNEL);
}
-static void locks_release_private(struct file_lock *fl)
+void locks_release_private(struct file_lock *fl)
{
if (fl->fl_ops) {
if (fl->fl_ops->fl_release_private)
@@ -165,6 +165,7 @@ static void locks_release_private(struct file_lock *fl)
}
}
+EXPORT_SYMBOL_GPL(locks_release_private);
/* Free a lock which is not in use. */
static void locks_free_lock(struct file_lock *fl)
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index daad3c2740db..7eb53970f4bc 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -35,6 +35,8 @@ static void minix_put_super(struct super_block *sb)
int i;
struct minix_sb_info *sbi = minix_sb(sb);
+ lock_kernel();
+
if (!(sb->s_flags & MS_RDONLY)) {
if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */
sbi->s_ms->s_state = sbi->s_mount_state;
@@ -49,7 +51,7 @@ static void minix_put_super(struct super_block *sb)
sb->s_fs_info = NULL;
kfree(sbi);
- return;
+ unlock_kernel();
}
static struct kmem_cache * minix_inode_cachep;
diff --git a/fs/mpage.c b/fs/mpage.c
index 680ba60863ff..42381bd6543b 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -379,7 +379,8 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
struct buffer_head map_bh;
unsigned long first_logical_block = 0;
- clear_buffer_mapped(&map_bh);
+ map_bh.b_state = 0;
+ map_bh.b_size = 0;
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
struct page *page = list_entry(pages->prev, struct page, lru);
@@ -412,7 +413,8 @@ int mpage_readpage(struct page *page, get_block_t get_block)
struct buffer_head map_bh;
unsigned long first_logical_block = 0;
- clear_buffer_mapped(&map_bh);
+ map_bh.b_state = 0;
+ map_bh.b_size = 0;
bio = do_mpage_readpage(bio, page, 1, &last_block_in_bio,
&map_bh, &first_logical_block, get_block);
if (bio)
diff --git a/fs/namei.c b/fs/namei.c
index 78f253cd2d4f..5472ed04ad79 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -552,6 +552,17 @@ static __always_inline int link_path_walk(const char *name, struct nameidata *nd
return result;
}
+static __always_inline void set_root(struct nameidata *nd)
+{
+ if (!nd->root.mnt) {
+ struct fs_struct *fs = current->fs;
+ read_lock(&fs->lock);
+ nd->root = fs->root;
+ path_get(&nd->root);
+ read_unlock(&fs->lock);
+ }
+}
+
static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
{
int res = 0;
@@ -560,14 +571,10 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
goto fail;
if (*link == '/') {
- struct fs_struct *fs = current->fs;
-
+ set_root(nd);
path_put(&nd->path);
-
- read_lock(&fs->lock);
- nd->path = fs->root;
- path_get(&fs->root);
- read_unlock(&fs->lock);
+ nd->path = nd->root;
+ path_get(&nd->root);
}
res = link_path_walk(link, nd);
@@ -668,23 +675,23 @@ loop:
return err;
}
-int follow_up(struct vfsmount **mnt, struct dentry **dentry)
+int follow_up(struct path *path)
{
struct vfsmount *parent;
struct dentry *mountpoint;
spin_lock(&vfsmount_lock);
- parent=(*mnt)->mnt_parent;
- if (parent == *mnt) {
+ parent = path->mnt->mnt_parent;
+ if (parent == path->mnt) {
spin_unlock(&vfsmount_lock);
return 0;
}
mntget(parent);
- mountpoint=dget((*mnt)->mnt_mountpoint);
+ mountpoint = dget(path->mnt->mnt_mountpoint);
spin_unlock(&vfsmount_lock);
- dput(*dentry);
- *dentry = mountpoint;
- mntput(*mnt);
- *mnt = parent;
+ dput(path->dentry);
+ path->dentry = mountpoint;
+ mntput(path->mnt);
+ path->mnt = parent;
return 1;
}
@@ -695,7 +702,7 @@ static int __follow_mount(struct path *path)
{
int res = 0;
while (d_mountpoint(path->dentry)) {
- struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry);
+ struct vfsmount *mounted = lookup_mnt(path);
if (!mounted)
break;
dput(path->dentry);
@@ -708,32 +715,32 @@ static int __follow_mount(struct path *path)
return res;
}
-static void follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+static void follow_mount(struct path *path)
{
- while (d_mountpoint(*dentry)) {
- struct vfsmount *mounted = lookup_mnt(*mnt, *dentry);
+ while (d_mountpoint(path->dentry)) {
+ struct vfsmount *mounted = lookup_mnt(path);
if (!mounted)
break;
- dput(*dentry);
- mntput(*mnt);
- *mnt = mounted;
- *dentry = dget(mounted->mnt_root);
+ dput(path->dentry);
+ mntput(path->mnt);
+ path->mnt = mounted;
+ path->dentry = dget(mounted->mnt_root);
}
}
/* no need for dcache_lock, as serialization is taken care in
* namespace.c
*/
-int follow_down(struct vfsmount **mnt, struct dentry **dentry)
+int follow_down(struct path *path)
{
struct vfsmount *mounted;
- mounted = lookup_mnt(*mnt, *dentry);
+ mounted = lookup_mnt(path);
if (mounted) {
- dput(*dentry);
- mntput(*mnt);
- *mnt = mounted;
- *dentry = dget(mounted->mnt_root);
+ dput(path->dentry);
+ mntput(path->mnt);
+ path->mnt = mounted;
+ path->dentry = dget(mounted->mnt_root);
return 1;
}
return 0;
@@ -741,19 +748,16 @@ int follow_down(struct vfsmount **mnt, struct dentry **dentry)
static __always_inline void follow_dotdot(struct nameidata *nd)
{
- struct fs_struct *fs = current->fs;
+ set_root(nd);
while(1) {
struct vfsmount *parent;
struct dentry *old = nd->path.dentry;
- read_lock(&fs->lock);
- if (nd->path.dentry == fs->root.dentry &&
- nd->path.mnt == fs->root.mnt) {
- read_unlock(&fs->lock);
+ if (nd->path.dentry == nd->root.dentry &&
+ nd->path.mnt == nd->root.mnt) {
break;
}
- read_unlock(&fs->lock);
spin_lock(&dcache_lock);
if (nd->path.dentry != nd->path.mnt->mnt_root) {
nd->path.dentry = dget(nd->path.dentry->d_parent);
@@ -775,7 +779,7 @@ static __always_inline void follow_dotdot(struct nameidata *nd)
mntput(nd->path.mnt);
nd->path.mnt = parent;
}
- follow_mount(&nd->path.mnt, &nd->path.dentry);
+ follow_mount(&nd->path);
}
/*
@@ -1016,25 +1020,23 @@ static int path_walk(const char *name, struct nameidata *nd)
return link_path_walk(name, nd);
}
-/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
-static int do_path_lookup(int dfd, const char *name,
- unsigned int flags, struct nameidata *nd)
+static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
{
int retval = 0;
int fput_needed;
struct file *file;
- struct fs_struct *fs = current->fs;
nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags;
nd->depth = 0;
+ nd->root.mnt = NULL;
if (*name=='/') {
- read_lock(&fs->lock);
- nd->path = fs->root;
- path_get(&fs->root);
- read_unlock(&fs->lock);
+ set_root(nd);
+ nd->path = nd->root;
+ path_get(&nd->root);
} else if (dfd == AT_FDCWD) {
+ struct fs_struct *fs = current->fs;
read_lock(&fs->lock);
nd->path = fs->pwd;
path_get(&fs->pwd);
@@ -1062,17 +1064,29 @@ static int do_path_lookup(int dfd, const char *name,
fput_light(file, fput_needed);
}
+ return 0;
- retval = path_walk(name, nd);
+fput_fail:
+ fput_light(file, fput_needed);
+out_fail:
+ return retval;
+}
+
+/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
+static int do_path_lookup(int dfd, const char *name,
+ unsigned int flags, struct nameidata *nd)
+{
+ int retval = path_init(dfd, name, flags, nd);
+ if (!retval)
+ retval = path_walk(name, nd);
if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
nd->path.dentry->d_inode))
audit_inode(name, nd->path.dentry);
-out_fail:
+ if (nd->root.mnt) {
+ path_put(&nd->root);
+ nd->root.mnt = NULL;
+ }
return retval;
-
-fput_fail:
- fput_light(file, fput_needed);
- goto out_fail;
}
int path_lookup(const char *name, unsigned int flags,
@@ -1112,14 +1126,18 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
nd->path.dentry = dentry;
nd->path.mnt = mnt;
path_get(&nd->path);
+ nd->root = nd->path;
+ path_get(&nd->root);
retval = path_walk(name, nd);
if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
nd->path.dentry->d_inode))
audit_inode(name, nd->path.dentry);
- return retval;
+ path_put(&nd->root);
+ nd->root.mnt = NULL;
+ return retval;
}
/**
@@ -1130,8 +1148,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
* @nd: pointer to nameidata
* @open_flags: open intent flags
*/
-int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
- struct nameidata *nd, int open_flags)
+static int path_lookup_open(int dfd, const char *name,
+ unsigned int lookup_flags, struct nameidata *nd, int open_flags)
{
struct file *filp = get_empty_filp();
int err;
@@ -1637,18 +1655,19 @@ static int open_will_write_to_fs(int flag, struct inode *inode)
* open_to_namei_flags() for more details.
*/
struct file *do_filp_open(int dfd, const char *pathname,
- int open_flag, int mode)
+ int open_flag, int mode, int acc_mode)
{
struct file *filp;
struct nameidata nd;
- int acc_mode, error;
+ int error;
struct path path;
struct dentry *dir;
int count = 0;
int will_write;
int flag = open_to_namei_flags(open_flag);
- acc_mode = MAY_OPEN | ACC_MODE(flag);
+ if (!acc_mode)
+ acc_mode = MAY_OPEN | ACC_MODE(flag);
/* O_TRUNC implies we need access checks for write permissions */
if (flag & O_TRUNC)
@@ -1673,9 +1692,14 @@ struct file *do_filp_open(int dfd, const char *pathname,
/*
* Create - we need to know the parent.
*/
- error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd);
+ error = path_init(dfd, pathname, LOOKUP_PARENT, &nd);
if (error)
return ERR_PTR(error);
+ error = path_walk(pathname, &nd);
+ if (error)
+ return ERR_PTR(error);
+ if (unlikely(!audit_dummy_context()))
+ audit_inode(pathname, nd.path.dentry);
/*
* We have the parent and last component. First of all, check
@@ -1803,6 +1827,8 @@ exit:
if (!IS_ERR(nd.intent.open.file))
release_open_intent(&nd);
exit_parent:
+ if (nd.root.mnt)
+ path_put(&nd.root);
path_put(&nd.path);
return ERR_PTR(error);
@@ -1869,7 +1895,7 @@ do_link:
*/
struct file *filp_open(const char *filename, int flags, int mode)
{
- return do_filp_open(AT_FDCWD, filename, flags, mode);
+ return do_filp_open(AT_FDCWD, filename, flags, mode, 0);
}
EXPORT_SYMBOL(filp_open);
diff --git a/fs/namespace.c b/fs/namespace.c
index 41196209a906..2dd333b0fe7f 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -131,10 +131,20 @@ struct vfsmount *alloc_vfsmnt(const char *name)
INIT_LIST_HEAD(&mnt->mnt_share);
INIT_LIST_HEAD(&mnt->mnt_slave_list);
INIT_LIST_HEAD(&mnt->mnt_slave);
- atomic_set(&mnt->__mnt_writers, 0);
+#ifdef CONFIG_SMP
+ mnt->mnt_writers = alloc_percpu(int);
+ if (!mnt->mnt_writers)
+ goto out_free_devname;
+#else
+ mnt->mnt_writers = 0;
+#endif
}
return mnt;
+#ifdef CONFIG_SMP
+out_free_devname:
+ kfree(mnt->mnt_devname);
+#endif
out_free_id:
mnt_free_id(mnt);
out_free_cache:
@@ -171,65 +181,38 @@ int __mnt_is_readonly(struct vfsmount *mnt)
}
EXPORT_SYMBOL_GPL(__mnt_is_readonly);
-struct mnt_writer {
- /*
- * If holding multiple instances of this lock, they
- * must be ordered by cpu number.
- */
- spinlock_t lock;
- struct lock_class_key lock_class; /* compiles out with !lockdep */
- unsigned long count;
- struct vfsmount *mnt;
-} ____cacheline_aligned_in_smp;
-static DEFINE_PER_CPU(struct mnt_writer, mnt_writers);
+static inline void inc_mnt_writers(struct vfsmount *mnt)
+{
+#ifdef CONFIG_SMP
+ (*per_cpu_ptr(mnt->mnt_writers, smp_processor_id()))++;
+#else
+ mnt->mnt_writers++;
+#endif
+}
-static int __init init_mnt_writers(void)
+static inline void dec_mnt_writers(struct vfsmount *mnt)
{
- int cpu;
- for_each_possible_cpu(cpu) {
- struct mnt_writer *writer = &per_cpu(mnt_writers, cpu);
- spin_lock_init(&writer->lock);
- lockdep_set_class(&writer->lock, &writer->lock_class);
- writer->count = 0;
- }
- return 0;
+#ifdef CONFIG_SMP
+ (*per_cpu_ptr(mnt->mnt_writers, smp_processor_id()))--;
+#else
+ mnt->mnt_writers--;
+#endif
}
-fs_initcall(init_mnt_writers);
-static void unlock_mnt_writers(void)
+static unsigned int count_mnt_writers(struct vfsmount *mnt)
{
+#ifdef CONFIG_SMP
+ unsigned int count = 0;
int cpu;
- struct mnt_writer *cpu_writer;
for_each_possible_cpu(cpu) {
- cpu_writer = &per_cpu(mnt_writers, cpu);
- spin_unlock(&cpu_writer->lock);
+ count += *per_cpu_ptr(mnt->mnt_writers, cpu);
}
-}
-static inline void __clear_mnt_count(struct mnt_writer *cpu_writer)
-{
- if (!cpu_writer->mnt)
- return;
- /*
- * This is in case anyone ever leaves an invalid,
- * old ->mnt and a count of 0.
- */
- if (!cpu_writer->count)
- return;
- atomic_add(cpu_writer->count, &cpu_writer->mnt->__mnt_writers);
- cpu_writer->count = 0;
-}
- /*
- * must hold cpu_writer->lock
- */
-static inline void use_cpu_writer_for_mount(struct mnt_writer *cpu_writer,
- struct vfsmount *mnt)
-{
- if (cpu_writer->mnt == mnt)
- return;
- __clear_mnt_count(cpu_writer);
- cpu_writer->mnt = mnt;
+ return count;
+#else
+ return mnt->mnt_writers;
+#endif
}
/*
@@ -253,74 +236,73 @@ static inline void use_cpu_writer_for_mount(struct mnt_writer *cpu_writer,
int mnt_want_write(struct vfsmount *mnt)
{
int ret = 0;
- struct mnt_writer *cpu_writer;
- cpu_writer = &get_cpu_var(mnt_writers);
- spin_lock(&cpu_writer->lock);
+ preempt_disable();
+ inc_mnt_writers(mnt);
+ /*
+ * The store to inc_mnt_writers must be visible before we pass
+ * MNT_WRITE_HOLD loop below, so that the slowpath can see our
+ * incremented count after it has set MNT_WRITE_HOLD.
+ */
+ smp_mb();
+ while (mnt->mnt_flags & MNT_WRITE_HOLD)
+ cpu_relax();
+ /*
+ * After the slowpath clears MNT_WRITE_HOLD, mnt_is_readonly will
+ * be set to match its requirements. So we must not load that until
+ * MNT_WRITE_HOLD is cleared.
+ */
+ smp_rmb();
if (__mnt_is_readonly(mnt)) {
+ dec_mnt_writers(mnt);
ret = -EROFS;
goto out;
}
- use_cpu_writer_for_mount(cpu_writer, mnt);
- cpu_writer->count++;
out:
- spin_unlock(&cpu_writer->lock);
- put_cpu_var(mnt_writers);
+ preempt_enable();
return ret;
}
EXPORT_SYMBOL_GPL(mnt_want_write);
-static void lock_mnt_writers(void)
-{
- int cpu;
- struct mnt_writer *cpu_writer;
-
- for_each_possible_cpu(cpu) {
- cpu_writer = &per_cpu(mnt_writers, cpu);
- spin_lock(&cpu_writer->lock);
- __clear_mnt_count(cpu_writer);
- cpu_writer->mnt = NULL;
- }
+/**
+ * mnt_clone_write - get write access to a mount
+ * @mnt: the mount on which to take a write
+ *
+ * This is effectively like mnt_want_write, except
+ * it must only be used to take an extra write reference
+ * on a mountpoint that we already know has a write reference
+ * on it. This allows some optimisation.
+ *
+ * After finished, mnt_drop_write must be called as usual to
+ * drop the reference.
+ */
+int mnt_clone_write(struct vfsmount *mnt)
+{
+ /* superblock may be r/o */
+ if (__mnt_is_readonly(mnt))
+ return -EROFS;
+ preempt_disable();
+ inc_mnt_writers(mnt);
+ preempt_enable();
+ return 0;
}
+EXPORT_SYMBOL_GPL(mnt_clone_write);
-/*
- * These per-cpu write counts are not guaranteed to have
- * matched increments and decrements on any given cpu.
- * A file open()ed for write on one cpu and close()d on
- * another cpu will imbalance this count. Make sure it
- * does not get too far out of whack.
+/**
+ * mnt_want_write_file - get write access to a file's mount
+ * @file: the file who's mount on which to take a write
+ *
+ * This is like mnt_want_write, but it takes a file and can
+ * do some optimisations if the file is open for write already
*/
-static void handle_write_count_underflow(struct vfsmount *mnt)
+int mnt_want_write_file(struct file *file)
{
- if (atomic_read(&mnt->__mnt_writers) >=
- MNT_WRITER_UNDERFLOW_LIMIT)
- return;
- /*
- * It isn't necessary to hold all of the locks
- * at the same time, but doing it this way makes
- * us share a lot more code.
- */
- lock_mnt_writers();
- /*
- * vfsmount_lock is for mnt_flags.
- */
- spin_lock(&vfsmount_lock);
- /*
- * If coalescing the per-cpu writer counts did not
- * get us back to a positive writer count, we have
- * a bug.
- */
- if ((atomic_read(&mnt->__mnt_writers) < 0) &&
- !(mnt->mnt_flags & MNT_IMBALANCED_WRITE_COUNT)) {
- WARN(1, KERN_DEBUG "leak detected on mount(%p) writers "
- "count: %d\n",
- mnt, atomic_read(&mnt->__mnt_writers));
- /* use the flag to keep the dmesg spam down */
- mnt->mnt_flags |= MNT_IMBALANCED_WRITE_COUNT;
- }
- spin_unlock(&vfsmount_lock);
- unlock_mnt_writers();
+ if (!(file->f_mode & FMODE_WRITE))
+ return mnt_want_write(file->f_path.mnt);
+ else
+ return mnt_clone_write(file->f_path.mnt);
}
+EXPORT_SYMBOL_GPL(mnt_want_write_file);
/**
* mnt_drop_write - give up write access to a mount
@@ -332,37 +314,9 @@ static void handle_write_count_underflow(struct vfsmount *mnt)
*/
void mnt_drop_write(struct vfsmount *mnt)
{
- int must_check_underflow = 0;
- struct mnt_writer *cpu_writer;
-
- cpu_writer = &get_cpu_var(mnt_writers);
- spin_lock(&cpu_writer->lock);
-
- use_cpu_writer_for_mount(cpu_writer, mnt);
- if (cpu_writer->count > 0) {
- cpu_writer->count--;
- } else {
- must_check_underflow = 1;
- atomic_dec(&mnt->__mnt_writers);
- }
-
- spin_unlock(&cpu_writer->lock);
- /*
- * Logically, we could call this each time,
- * but the __mnt_writers cacheline tends to
- * be cold, and makes this expensive.
- */
- if (must_check_underflow)
- handle_write_count_underflow(mnt);
- /*
- * This could be done right after the spinlock
- * is taken because the spinlock keeps us on
- * the cpu, and disables preemption. However,
- * putting it here bounds the amount that
- * __mnt_writers can underflow. Without it,
- * we could theoretically wrap __mnt_writers.
- */
- put_cpu_var(mnt_writers);
+ preempt_disable();
+ dec_mnt_writers(mnt);
+ preempt_enable();
}
EXPORT_SYMBOL_GPL(mnt_drop_write);
@@ -370,24 +324,41 @@ static int mnt_make_readonly(struct vfsmount *mnt)
{
int ret = 0;
- lock_mnt_writers();
+ spin_lock(&vfsmount_lock);
+ mnt->mnt_flags |= MNT_WRITE_HOLD;
/*
- * With all the locks held, this value is stable
+ * After storing MNT_WRITE_HOLD, we'll read the counters. This store
+ * should be visible before we do.
*/
- if (atomic_read(&mnt->__mnt_writers) > 0) {
- ret = -EBUSY;
- goto out;
- }
+ smp_mb();
+
/*
- * nobody can do a successful mnt_want_write() with all
- * of the counts in MNT_DENIED_WRITE and the locks held.
+ * With writers on hold, if this value is zero, then there are
+ * definitely no active writers (although held writers may subsequently
+ * increment the count, they'll have to wait, and decrement it after
+ * seeing MNT_READONLY).
+ *
+ * It is OK to have counter incremented on one CPU and decremented on
+ * another: the sum will add up correctly. The danger would be when we
+ * sum up each counter, if we read a counter before it is incremented,
+ * but then read another CPU's count which it has been subsequently
+ * decremented from -- we would see more decrements than we should.
+ * MNT_WRITE_HOLD protects against this scenario, because
+ * mnt_want_write first increments count, then smp_mb, then spins on
+ * MNT_WRITE_HOLD, so it can't be decremented by another CPU while
+ * we're counting up here.
*/
- spin_lock(&vfsmount_lock);
- if (!ret)
+ if (count_mnt_writers(mnt) > 0)
+ ret = -EBUSY;
+ else
mnt->mnt_flags |= MNT_READONLY;
+ /*
+ * MNT_READONLY must become visible before ~MNT_WRITE_HOLD, so writers
+ * that become unheld will see MNT_READONLY.
+ */
+ smp_wmb();
+ mnt->mnt_flags &= ~MNT_WRITE_HOLD;
spin_unlock(&vfsmount_lock);
-out:
- unlock_mnt_writers();
return ret;
}
@@ -410,6 +381,9 @@ void free_vfsmnt(struct vfsmount *mnt)
{
kfree(mnt->mnt_devname);
mnt_free_id(mnt);
+#ifdef CONFIG_SMP
+ free_percpu(mnt->mnt_writers);
+#endif
kmem_cache_free(mnt_cache, mnt);
}
@@ -442,11 +416,11 @@ struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
* lookup_mnt increments the ref count before returning
* the vfsmount struct.
*/
-struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
+struct vfsmount *lookup_mnt(struct path *path)
{
struct vfsmount *child_mnt;
spin_lock(&vfsmount_lock);
- if ((child_mnt = __lookup_mnt(mnt, dentry, 1)))
+ if ((child_mnt = __lookup_mnt(path->mnt, path->dentry, 1)))
mntget(child_mnt);
spin_unlock(&vfsmount_lock);
return child_mnt;
@@ -604,38 +578,18 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
static inline void __mntput(struct vfsmount *mnt)
{
- int cpu;
struct super_block *sb = mnt->mnt_sb;
/*
- * We don't have to hold all of the locks at the
- * same time here because we know that we're the
- * last reference to mnt and that no new writers
- * can come in.
- */
- for_each_possible_cpu(cpu) {
- struct mnt_writer *cpu_writer = &per_cpu(mnt_writers, cpu);
- spin_lock(&cpu_writer->lock);
- if (cpu_writer->mnt != mnt) {
- spin_unlock(&cpu_writer->lock);
- continue;
- }
- atomic_add(cpu_writer->count, &mnt->__mnt_writers);
- cpu_writer->count = 0;
- /*
- * Might as well do this so that no one
- * ever sees the pointer and expects
- * it to be valid.
- */
- cpu_writer->mnt = NULL;
- spin_unlock(&cpu_writer->lock);
- }
- /*
* This probably indicates that somebody messed
* up a mnt_want/drop_write() pair. If this
* happens, the filesystem was probably unable
* to make r/w->r/o transitions.
*/
- WARN_ON(atomic_read(&mnt->__mnt_writers));
+ /*
+ * atomic_dec_and_lock() used to deal with ->mnt_count decrements
+ * provides barriers, so count_mnt_writers() below is safe. AV
+ */
+ WARN_ON(count_mnt_writers(mnt));
dput(mnt->mnt_root);
free_vfsmnt(mnt);
deactivate_super(sb);
@@ -695,12 +649,16 @@ static inline void mangle(struct seq_file *m, const char *s)
*/
int generic_show_options(struct seq_file *m, struct vfsmount *mnt)
{
- const char *options = mnt->mnt_sb->s_options;
+ const char *options;
+
+ rcu_read_lock();
+ options = rcu_dereference(mnt->mnt_sb->s_options);
if (options != NULL && options[0]) {
seq_putc(m, ',');
mangle(m, options);
}
+ rcu_read_unlock();
return 0;
}
@@ -721,11 +679,22 @@ EXPORT_SYMBOL(generic_show_options);
*/
void save_mount_options(struct super_block *sb, char *options)
{
- kfree(sb->s_options);
- sb->s_options = kstrdup(options, GFP_KERNEL);
+ BUG_ON(sb->s_options);
+ rcu_assign_pointer(sb->s_options, kstrdup(options, GFP_KERNEL));
}
EXPORT_SYMBOL(save_mount_options);
+void replace_mount_options(struct super_block *sb, char *options)
+{
+ char *old = sb->s_options;
+ rcu_assign_pointer(sb->s_options, options);
+ if (old) {
+ synchronize_rcu();
+ kfree(old);
+ }
+}
+EXPORT_SYMBOL(replace_mount_options);
+
#ifdef CONFIG_PROC_FS
/* iterator */
static void *m_start(struct seq_file *m, loff_t *pos)
@@ -1073,9 +1042,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
*/
if (flags & MNT_FORCE && sb->s_op->umount_begin) {
- lock_kernel();
sb->s_op->umount_begin(sb);
- unlock_kernel();
}
/*
@@ -1093,11 +1060,8 @@ static int do_umount(struct vfsmount *mnt, int flags)
* we just try to remount it readonly.
*/
down_write(&sb->s_umount);
- if (!(sb->s_flags & MS_RDONLY)) {
- lock_kernel();
+ if (!(sb->s_flags & MS_RDONLY))
retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
- unlock_kernel();
- }
up_write(&sb->s_umount);
return retval;
}
@@ -1240,11 +1204,11 @@ Enomem:
return NULL;
}
-struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
+struct vfsmount *collect_mounts(struct path *path)
{
struct vfsmount *tree;
down_write(&namespace_sem);
- tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
+ tree = copy_tree(path->mnt, path->dentry, CL_COPY_ALL | CL_PRIVATE);
up_write(&namespace_sem);
return tree;
}
@@ -1417,7 +1381,7 @@ static int graft_tree(struct vfsmount *mnt, struct path *path)
goto out_unlock;
err = -ENOENT;
- if (IS_ROOT(path->dentry) || !d_unhashed(path->dentry))
+ if (!d_unlinked(path->dentry))
err = attach_recursive_mnt(mnt, path, NULL);
out_unlock:
mutex_unlock(&path->dentry->d_inode->i_mutex);
@@ -1588,7 +1552,7 @@ static int do_move_mount(struct path *path, char *old_name)
down_write(&namespace_sem);
while (d_mountpoint(path->dentry) &&
- follow_down(&path->mnt, &path->dentry))
+ follow_down(path))
;
err = -EINVAL;
if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
@@ -1599,7 +1563,7 @@ static int do_move_mount(struct path *path, char *old_name)
if (IS_DEADDIR(path->dentry->d_inode))
goto out1;
- if (!IS_ROOT(path->dentry) && d_unhashed(path->dentry))
+ if (d_unlinked(path->dentry))
goto out1;
err = -EINVAL;
@@ -1663,7 +1627,9 @@ static int do_new_mount(struct path *path, char *type, int flags,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+ lock_kernel();
mnt = do_kern_mount(type, flags, name, data);
+ unlock_kernel();
if (IS_ERR(mnt))
return PTR_ERR(mnt);
@@ -1682,10 +1648,10 @@ int do_add_mount(struct vfsmount *newmnt, struct path *path,
down_write(&namespace_sem);
/* Something was mounted here while we slept */
while (d_mountpoint(path->dentry) &&
- follow_down(&path->mnt, &path->dentry))
+ follow_down(path))
;
err = -EINVAL;
- if (!check_mnt(path->mnt))
+ if (!(mnt_flags & MNT_SHRINKABLE) && !check_mnt(path->mnt))
goto unlock;
/* Refuse the same filesystem on the same mount point */
@@ -2079,10 +2045,8 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
if (retval < 0)
goto out3;
- lock_kernel();
retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
flags, (void *)data_page);
- unlock_kernel();
free_page(data_page);
out3:
@@ -2162,9 +2126,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
error = -ENOENT;
if (IS_DEADDIR(new.dentry->d_inode))
goto out2;
- if (d_unhashed(new.dentry) && !IS_ROOT(new.dentry))
+ if (d_unlinked(new.dentry))
goto out2;
- if (d_unhashed(old.dentry) && !IS_ROOT(old.dentry))
+ if (d_unlinked(old.dentry))
goto out2;
error = -EBUSY;
if (new.mnt == root.mnt ||
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index d642f0e5b365..b99ce205b1bd 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -736,6 +736,8 @@ static void ncp_put_super(struct super_block *sb)
{
struct ncp_server *server = NCP_SBP(sb);
+ lock_kernel();
+
ncp_lock_server(server);
ncp_disconnect(server);
ncp_unlock_server(server);
@@ -769,6 +771,8 @@ static void ncp_put_super(struct super_block *sb)
vfree(server->packet);
sb->s_fs_info = NULL;
kfree(server);
+
+ unlock_kernel();
}
static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index e67f3ec07736..5d6d6f415935 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -74,6 +74,15 @@ config NFS_V4
If unsure, say N.
+config NFS_V4_1
+ bool "NFS client support for NFSv4.1 (DEVELOPER ONLY)"
+ depends on NFS_V4 && EXPERIMENTAL
+ help
+ This option enables support for minor version 1 of the NFSv4 protocol
+ (draft-ietf-nfsv4-minorversion1) in the kernel's NFS client.
+
+ Unless you're an NFS developer, say N.
+
config ROOT_NFS
bool "Root file system on NFS"
depends on NFS_FS=y && IP_PNP
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 75c9cd2aa119..3e232bf56dfb 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -102,6 +102,7 @@ struct nfs_client_initdata {
size_t addrlen;
const struct nfs_rpc_ops *rpc_ops;
int proto;
+ u32 minorversion;
};
/*
@@ -150,6 +151,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
clp->cl_boot_time = CURRENT_TIME;
clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
+ clp->cl_minorversion = cl_init->minorversion;
#endif
cred = rpc_lookup_machine_cred();
if (!IS_ERR(cred))
@@ -182,12 +184,29 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
}
/*
+ * Clears/puts all minor version specific parts from an nfs_client struct
+ * reverting it to minorversion 0.
+ */
+static void nfs4_clear_client_minor_version(struct nfs_client *clp)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (nfs4_has_session(clp)) {
+ nfs4_destroy_session(clp->cl_session);
+ clp->cl_session = NULL;
+ }
+
+ clp->cl_call_sync = _nfs4_call_sync;
+#endif /* CONFIG_NFS_V4_1 */
+}
+
+/*
* Destroy a shared client record
*/
static void nfs_free_client(struct nfs_client *clp)
{
dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version);
+ nfs4_clear_client_minor_version(clp);
nfs4_shutdown_client(clp);
nfs_fscache_release_client_cookie(clp);
@@ -347,7 +366,8 @@ struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion)
struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
/* Don't match clients that failed to initialise properly */
- if (clp->cl_cons_state != NFS_CS_READY)
+ if (!(clp->cl_cons_state == NFS_CS_READY ||
+ clp->cl_cons_state == NFS_CS_SESSION_INITING))
continue;
/* Different NFS versions cannot share the same nfs_client */
@@ -420,7 +440,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
if (clp->cl_proto != data->proto)
continue;
-
+ /* Match nfsv4 minorversion */
+ if (clp->cl_minorversion != data->minorversion)
+ continue;
/* Match the full socket address */
if (!nfs_sockaddr_cmp(sap, clap))
continue;
@@ -478,7 +500,7 @@ found_client:
nfs_free_client(new);
error = wait_event_killable(nfs_client_active_wq,
- clp->cl_cons_state != NFS_CS_INITING);
+ clp->cl_cons_state < NFS_CS_INITING);
if (error < 0) {
nfs_put_client(clp);
return ERR_PTR(-ERESTARTSYS);
@@ -499,13 +521,29 @@ found_client:
/*
* Mark a server as ready or failed
*/
-static void nfs_mark_client_ready(struct nfs_client *clp, int state)
+void nfs_mark_client_ready(struct nfs_client *clp, int state)
{
clp->cl_cons_state = state;
wake_up_all(&nfs_client_active_wq);
}
/*
+ * With sessions, the client is not marked ready until after a
+ * successful EXCHANGE_ID and CREATE_SESSION.
+ *
+ * Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate
+ * other versions of NFS can be tried.
+ */
+int nfs4_check_client_ready(struct nfs_client *clp)
+{
+ if (!nfs4_has_session(clp))
+ return 0;
+ if (clp->cl_cons_state < NFS_CS_READY)
+ return -EPROTONOSUPPORT;
+ return 0;
+}
+
+/*
* Initialise the timeout values for a connection
*/
static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
@@ -1050,6 +1088,33 @@ error:
#ifdef CONFIG_NFS_V4
/*
+ * Initialize the minor version specific parts of an NFS4 client record
+ */
+static int nfs4_init_client_minor_version(struct nfs_client *clp)
+{
+ clp->cl_call_sync = _nfs4_call_sync;
+
+#if defined(CONFIG_NFS_V4_1)
+ if (clp->cl_minorversion) {
+ struct nfs4_session *session = NULL;
+ /*
+ * Create the session and mark it expired.
+ * When a SEQUENCE operation encounters the expired session
+ * it will do session recovery to initialize it.
+ */
+ session = nfs4_alloc_session(clp);
+ if (!session)
+ return -ENOMEM;
+
+ clp->cl_session = session;
+ clp->cl_call_sync = _nfs4_call_sync_session;
+ }
+#endif /* CONFIG_NFS_V4_1 */
+
+ return 0;
+}
+
+/*
* Initialise an NFS4 client record
*/
static int nfs4_init_client(struct nfs_client *clp,
@@ -1083,7 +1148,12 @@ static int nfs4_init_client(struct nfs_client *clp,
}
__set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
- nfs_mark_client_ready(clp, NFS_CS_READY);
+ error = nfs4_init_client_minor_version(clp);
+ if (error < 0)
+ goto error;
+
+ if (!nfs4_has_session(clp))
+ nfs_mark_client_ready(clp, NFS_CS_READY);
return 0;
error:
@@ -1101,7 +1171,8 @@ static int nfs4_set_client(struct nfs_server *server,
const size_t addrlen,
const char *ip_addr,
rpc_authflavor_t authflavour,
- int proto, const struct rpc_timeout *timeparms)
+ int proto, const struct rpc_timeout *timeparms,
+ u32 minorversion)
{
struct nfs_client_initdata cl_init = {
.hostname = hostname,
@@ -1109,6 +1180,7 @@ static int nfs4_set_client(struct nfs_server *server,
.addrlen = addrlen,
.rpc_ops = &nfs_v4_clientops,
.proto = proto,
+ .minorversion = minorversion,
};
struct nfs_client *clp;
int error;
@@ -1138,6 +1210,36 @@ error:
}
/*
+ * Initialize a session.
+ * Note: save the mount rsize and wsize for create_server negotiation.
+ */
+static void nfs4_init_session(struct nfs_client *clp,
+ unsigned int wsize, unsigned int rsize)
+{
+#if defined(CONFIG_NFS_V4_1)
+ if (nfs4_has_session(clp)) {
+ clp->cl_session->fc_attrs.max_rqst_sz = wsize;
+ clp->cl_session->fc_attrs.max_resp_sz = rsize;
+ }
+#endif /* CONFIG_NFS_V4_1 */
+}
+
+/*
+ * Session has been established, and the client marked ready.
+ * Set the mount rsize and wsize with negotiated fore channel
+ * attributes which will be bound checked in nfs_server_set_fsinfo.
+ */
+static void nfs4_session_set_rwsize(struct nfs_server *server)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (!nfs4_has_session(server->nfs_client))
+ return;
+ server->rsize = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
+ server->wsize = server->nfs_client->cl_session->fc_attrs.max_rqst_sz;
+#endif /* CONFIG_NFS_V4_1 */
+}
+
+/*
* Create a version 4 volume record
*/
static int nfs4_init_server(struct nfs_server *server,
@@ -1164,7 +1266,8 @@ static int nfs4_init_server(struct nfs_server *server,
data->client_address,
data->auth_flavors[0],
data->nfs_server.protocol,
- &timeparms);
+ &timeparms,
+ data->minorversion);
if (error < 0)
goto error;
@@ -1214,6 +1317,8 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
BUG_ON(!server->nfs_client->rpc_ops);
BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
+ nfs4_init_session(server->nfs_client, server->wsize, server->rsize);
+
/* Probe the root fh to retrieve its FSID */
error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path);
if (error < 0)
@@ -1224,6 +1329,8 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
(unsigned long long) server->fsid.minor);
dprintk("Mount FH: %d\n", mntfh->size);
+ nfs4_session_set_rwsize(server);
+
error = nfs_probe_fsinfo(server, mntfh, &fattr);
if (error < 0)
goto error;
@@ -1282,7 +1389,8 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
parent_client->cl_ipaddr,
data->authflavor,
parent_server->client->cl_xprt->prot,
- parent_server->client->cl_timeout);
+ parent_server->client->cl_timeout,
+ parent_client->cl_minorversion);
if (error < 0)
goto error;
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 08f6b040d289..489fc01a3204 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -259,6 +259,9 @@ static void nfs_direct_read_release(void *calldata)
}
static const struct rpc_call_ops nfs_read_direct_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_read_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_direct_read_result,
.rpc_release = nfs_direct_read_release,
};
@@ -535,6 +538,9 @@ static void nfs_direct_commit_release(void *calldata)
}
static const struct rpc_call_ops nfs_commit_direct_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_write_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_direct_commit_result,
.rpc_release = nfs_direct_commit_release,
};
@@ -673,6 +679,9 @@ out_unlock:
}
static const struct rpc_call_ops nfs_write_direct_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_write_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_direct_write_result,
.rpc_release = nfs_direct_write_release,
};
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index e4d6a8348adf..acee3274d275 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -2,6 +2,7 @@
* NFS internal definitions
*/
+#include "nfs4_fs.h"
#include <linux/mount.h>
#include <linux/security.h>
@@ -17,6 +18,18 @@ struct nfs_string;
*/
#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
+/*
+ * Determine if sessions are in use.
+ */
+static inline int nfs4_has_session(const struct nfs_client *clp)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (clp->cl_session)
+ return 1;
+#endif /* CONFIG_NFS_V4_1 */
+ return 0;
+}
+
struct nfs_clone_mount {
const struct super_block *sb;
const struct dentry *dentry;
@@ -44,6 +57,7 @@ struct nfs_parsed_mount_data {
unsigned int auth_flavor_len;
rpc_authflavor_t auth_flavors[1];
char *client_address;
+ unsigned int minorversion;
char *fscache_uniq;
struct {
@@ -99,6 +113,8 @@ extern void nfs_free_server(struct nfs_server *server);
extern struct nfs_server *nfs_clone_server(struct nfs_server *,
struct nfs_fh *,
struct nfs_fattr *);
+extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
+extern int nfs4_check_client_ready(struct nfs_client *clp);
#ifdef CONFIG_PROC_FS
extern int __init nfs_fs_proc_init(void);
extern void nfs_fs_proc_exit(void);
@@ -146,6 +162,20 @@ extern __be32 * nfs_decode_dirent(__be32 *, struct nfs_entry *, int);
extern struct rpc_procinfo nfs3_procedures[];
extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int);
+/* nfs4proc.c */
+static inline void nfs4_restart_rpc(struct rpc_task *task,
+ const struct nfs_client *clp)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (nfs4_has_session(clp) &&
+ test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) {
+ rpc_restart_call_prepare(task);
+ return;
+ }
+#endif /* CONFIG_NFS_V4_1 */
+ rpc_restart_call(task);
+}
+
/* nfs4xdr.c */
#ifdef CONFIG_NFS_V4
extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
@@ -205,6 +235,38 @@ extern int nfs4_path_walk(struct nfs_server *server,
const char *path);
#endif
+/* read.c */
+extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
+
+/* write.c */
+extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
+
+/* nfs4proc.c */
+extern int _nfs4_call_sync(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply);
+extern int _nfs4_call_sync_session(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply);
+
+#ifdef CONFIG_NFS_V4_1
+extern void nfs41_sequence_free_slot(const struct nfs_client *,
+ struct nfs4_sequence_res *res);
+#endif /* CONFIG_NFS_V4_1 */
+
+static inline void nfs4_sequence_free_slot(const struct nfs_client *clp,
+ struct nfs4_sequence_res *res)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (nfs4_has_session(clp))
+ nfs41_sequence_free_slot(clp, res);
+#endif /* CONFIG_NFS_V4_1 */
+}
+
/*
* Determine the device name as a string
*/
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 64a288ee046d..f01caec84463 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -154,7 +154,7 @@ out_err:
goto out;
out_follow:
while (d_mountpoint(nd->path.dentry) &&
- follow_down(&nd->path.mnt, &nd->path.dentry))
+ follow_down(&nd->path))
;
err = 0;
goto out;
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 84345deab26f..61bc3a32e1e2 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -44,6 +44,7 @@ enum nfs4_client_state {
NFS4CLNT_RECLAIM_REBOOT,
NFS4CLNT_RECLAIM_NOGRACE,
NFS4CLNT_DELEGRETURN,
+ NFS4CLNT_SESSION_SETUP,
};
/*
@@ -177,6 +178,14 @@ struct nfs4_state_recovery_ops {
int state_flag_bit;
int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
int (*recover_lock)(struct nfs4_state *, struct file_lock *);
+ int (*establish_clid)(struct nfs_client *, struct rpc_cred *);
+ struct rpc_cred * (*get_clid_cred)(struct nfs_client *);
+};
+
+struct nfs4_state_maintenance_ops {
+ int (*sched_state_renewal)(struct nfs_client *, struct rpc_cred *);
+ struct rpc_cred * (*get_state_renewal_cred_locked)(struct nfs_client *);
+ int (*renew_lease)(struct nfs_client *, struct rpc_cred *);
};
extern const struct dentry_operations nfs4_dentry_operations;
@@ -193,6 +202,7 @@ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struc
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
+extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait);
extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
@@ -200,8 +210,26 @@ extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fh
extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
struct nfs4_fs_locations *fs_locations, struct page *page);
-extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
-extern struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops;
+extern struct nfs4_state_recovery_ops *nfs4_reboot_recovery_ops[];
+extern struct nfs4_state_recovery_ops *nfs4_nograce_recovery_ops[];
+#if defined(CONFIG_NFS_V4_1)
+extern int nfs4_setup_sequence(struct nfs_client *clp,
+ struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
+ int cache_reply, struct rpc_task *task);
+extern void nfs4_destroy_session(struct nfs4_session *session);
+extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
+extern int nfs4_proc_create_session(struct nfs_client *, int reset);
+extern int nfs4_proc_destroy_session(struct nfs4_session *);
+#else /* CONFIG_NFS_v4_1 */
+static inline int nfs4_setup_sequence(struct nfs_client *clp,
+ struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
+ int cache_reply, struct rpc_task *task)
+{
+ return 0;
+}
+#endif /* CONFIG_NFS_V4_1 */
+
+extern struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[];
extern const u32 nfs4_fattr_bitmap[2];
extern const u32 nfs4_statfs_bitmap[2];
@@ -216,7 +244,12 @@ extern void nfs4_kill_renewd(struct nfs_client *);
extern void nfs4_renew_state(struct work_struct *);
/* nfs4state.c */
+struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp);
struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp);
+#if defined(CONFIG_NFS_V4_1)
+struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
+struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp);
+#endif /* CONFIG_NFS_V4_1 */
extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
extern void nfs4_put_state_owner(struct nfs4_state_owner *);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a4d242680299..530ebb1e84fe 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -48,11 +48,13 @@
#include <linux/smp_lock.h>
#include <linux/namei.h>
#include <linux/mount.h>
+#include <linux/module.h>
#include "nfs4_fs.h"
#include "delegation.h"
#include "internal.h"
#include "iostat.h"
+#include "callback.h"
#define NFSDBG_FACILITY NFSDBG_PROC
@@ -247,7 +249,25 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
ret = nfs4_wait_clnt_recover(clp);
if (ret == 0)
exception->retry = 1;
+#if !defined(CONFIG_NFS_V4_1)
break;
+#else /* !defined(CONFIG_NFS_V4_1) */
+ if (!nfs4_has_session(server->nfs_client))
+ break;
+ /* FALLTHROUGH */
+ case -NFS4ERR_BADSESSION:
+ case -NFS4ERR_BADSLOT:
+ case -NFS4ERR_BAD_HIGH_SLOT:
+ case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+ case -NFS4ERR_DEADSESSION:
+ case -NFS4ERR_SEQ_FALSE_RETRY:
+ case -NFS4ERR_SEQ_MISORDERED:
+ dprintk("%s ERROR: %d Reset session\n", __func__,
+ errorcode);
+ set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
+ exception->retry = 1;
+ /* FALLTHROUGH */
+#endif /* !defined(CONFIG_NFS_V4_1) */
case -NFS4ERR_FILE_OPEN:
case -NFS4ERR_GRACE:
case -NFS4ERR_DELAY:
@@ -271,6 +291,353 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
spin_unlock(&clp->cl_lock);
}
+#if defined(CONFIG_NFS_V4_1)
+
+/*
+ * nfs4_free_slot - free a slot and efficiently update slot table.
+ *
+ * freeing a slot is trivially done by clearing its respective bit
+ * in the bitmap.
+ * If the freed slotid equals highest_used_slotid we want to update it
+ * so that the server would be able to size down the slot table if needed,
+ * otherwise we know that the highest_used_slotid is still in use.
+ * When updating highest_used_slotid there may be "holes" in the bitmap
+ * so we need to scan down from highest_used_slotid to 0 looking for the now
+ * highest slotid in use.
+ * If none found, highest_used_slotid is set to -1.
+ */
+static void
+nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
+{
+ int slotid = free_slotid;
+
+ spin_lock(&tbl->slot_tbl_lock);
+ /* clear used bit in bitmap */
+ __clear_bit(slotid, tbl->used_slots);
+
+ /* update highest_used_slotid when it is freed */
+ if (slotid == tbl->highest_used_slotid) {
+ slotid = find_last_bit(tbl->used_slots, tbl->max_slots);
+ if (slotid >= 0 && slotid < tbl->max_slots)
+ tbl->highest_used_slotid = slotid;
+ else
+ tbl->highest_used_slotid = -1;
+ }
+ rpc_wake_up_next(&tbl->slot_tbl_waitq);
+ spin_unlock(&tbl->slot_tbl_lock);
+ dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__,
+ free_slotid, tbl->highest_used_slotid);
+}
+
+void nfs41_sequence_free_slot(const struct nfs_client *clp,
+ struct nfs4_sequence_res *res)
+{
+ struct nfs4_slot_table *tbl;
+
+ if (!nfs4_has_session(clp)) {
+ dprintk("%s: No session\n", __func__);
+ return;
+ }
+ tbl = &clp->cl_session->fc_slot_table;
+ if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) {
+ dprintk("%s: No slot\n", __func__);
+ /* just wake up the next guy waiting since
+ * we may have not consumed a slot after all */
+ rpc_wake_up_next(&tbl->slot_tbl_waitq);
+ return;
+ }
+ nfs4_free_slot(tbl, res->sr_slotid);
+ res->sr_slotid = NFS4_MAX_SLOT_TABLE;
+}
+
+static void nfs41_sequence_done(struct nfs_client *clp,
+ struct nfs4_sequence_res *res,
+ int rpc_status)
+{
+ unsigned long timestamp;
+ struct nfs4_slot_table *tbl;
+ struct nfs4_slot *slot;
+
+ /*
+ * sr_status remains 1 if an RPC level error occurred. The server
+ * may or may not have processed the sequence operation..
+ * Proceed as if the server received and processed the sequence
+ * operation.
+ */
+ if (res->sr_status == 1)
+ res->sr_status = NFS_OK;
+
+ /* -ERESTARTSYS can result in skipping nfs41_sequence_setup */
+ if (res->sr_slotid == NFS4_MAX_SLOT_TABLE)
+ goto out;
+
+ tbl = &clp->cl_session->fc_slot_table;
+ slot = tbl->slots + res->sr_slotid;
+
+ if (res->sr_status == 0) {
+ /* Update the slot's sequence and clientid lease timer */
+ ++slot->seq_nr;
+ timestamp = res->sr_renewal_time;
+ spin_lock(&clp->cl_lock);
+ if (time_before(clp->cl_last_renewal, timestamp))
+ clp->cl_last_renewal = timestamp;
+ spin_unlock(&clp->cl_lock);
+ return;
+ }
+out:
+ /* The session may be reset by one of the error handlers. */
+ dprintk("%s: Error %d free the slot \n", __func__, res->sr_status);
+ nfs41_sequence_free_slot(clp, res);
+}
+
+/*
+ * nfs4_find_slot - efficiently look for a free slot
+ *
+ * nfs4_find_slot looks for an unset bit in the used_slots bitmap.
+ * If found, we mark the slot as used, update the highest_used_slotid,
+ * and respectively set up the sequence operation args.
+ * The slot number is returned if found, or NFS4_MAX_SLOT_TABLE otherwise.
+ *
+ * Note: must be called with under the slot_tbl_lock.
+ */
+static u8
+nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)
+{
+ int slotid;
+ u8 ret_id = NFS4_MAX_SLOT_TABLE;
+ BUILD_BUG_ON((u8)NFS4_MAX_SLOT_TABLE != (int)NFS4_MAX_SLOT_TABLE);
+
+ dprintk("--> %s used_slots=%04lx highest_used=%d max_slots=%d\n",
+ __func__, tbl->used_slots[0], tbl->highest_used_slotid,
+ tbl->max_slots);
+ slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slots);
+ if (slotid >= tbl->max_slots)
+ goto out;
+ __set_bit(slotid, tbl->used_slots);
+ if (slotid > tbl->highest_used_slotid)
+ tbl->highest_used_slotid = slotid;
+ ret_id = slotid;
+out:
+ dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n",
+ __func__, tbl->used_slots[0], tbl->highest_used_slotid, ret_id);
+ return ret_id;
+}
+
+static int nfs4_recover_session(struct nfs4_session *session)
+{
+ struct nfs_client *clp = session->clp;
+ int ret;
+
+ for (;;) {
+ ret = nfs4_wait_clnt_recover(clp);
+ if (ret != 0)
+ return ret;
+ if (!test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
+ break;
+ nfs4_schedule_state_manager(clp);
+ }
+ return 0;
+}
+
+static int nfs41_setup_sequence(struct nfs4_session *session,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply,
+ struct rpc_task *task)
+{
+ struct nfs4_slot *slot;
+ struct nfs4_slot_table *tbl;
+ int status = 0;
+ u8 slotid;
+
+ dprintk("--> %s\n", __func__);
+ /* slot already allocated? */
+ if (res->sr_slotid != NFS4_MAX_SLOT_TABLE)
+ return 0;
+
+ memset(res, 0, sizeof(*res));
+ res->sr_slotid = NFS4_MAX_SLOT_TABLE;
+ tbl = &session->fc_slot_table;
+
+ spin_lock(&tbl->slot_tbl_lock);
+ if (test_bit(NFS4CLNT_SESSION_SETUP, &session->clp->cl_state)) {
+ if (tbl->highest_used_slotid != -1) {
+ rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
+ spin_unlock(&tbl->slot_tbl_lock);
+ dprintk("<-- %s: Session reset: draining\n", __func__);
+ return -EAGAIN;
+ }
+
+ /* The slot table is empty; start the reset thread */
+ dprintk("%s Session Reset\n", __func__);
+ spin_unlock(&tbl->slot_tbl_lock);
+ status = nfs4_recover_session(session);
+ if (status)
+ return status;
+ spin_lock(&tbl->slot_tbl_lock);
+ }
+
+ slotid = nfs4_find_slot(tbl, task);
+ if (slotid == NFS4_MAX_SLOT_TABLE) {
+ rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
+ spin_unlock(&tbl->slot_tbl_lock);
+ dprintk("<-- %s: no free slots\n", __func__);
+ return -EAGAIN;
+ }
+ spin_unlock(&tbl->slot_tbl_lock);
+
+ slot = tbl->slots + slotid;
+ args->sa_session = session;
+ args->sa_slotid = slotid;
+ args->sa_cache_this = cache_reply;
+
+ dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr);
+
+ res->sr_session = session;
+ res->sr_slotid = slotid;
+ res->sr_renewal_time = jiffies;
+ /*
+ * sr_status is only set in decode_sequence, and so will remain
+ * set to 1 if an rpc level failure occurs.
+ */
+ res->sr_status = 1;
+ return 0;
+}
+
+int nfs4_setup_sequence(struct nfs_client *clp,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply,
+ struct rpc_task *task)
+{
+ int ret = 0;
+
+ dprintk("--> %s clp %p session %p sr_slotid %d\n",
+ __func__, clp, clp->cl_session, res->sr_slotid);
+
+ if (!nfs4_has_session(clp))
+ goto out;
+ ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply,
+ task);
+ if (ret != -EAGAIN) {
+ /* terminate rpc task */
+ task->tk_status = ret;
+ task->tk_action = NULL;
+ }
+out:
+ dprintk("<-- %s status=%d\n", __func__, ret);
+ return ret;
+}
+
+struct nfs41_call_sync_data {
+ struct nfs_client *clp;
+ struct nfs4_sequence_args *seq_args;
+ struct nfs4_sequence_res *seq_res;
+ int cache_reply;
+};
+
+static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
+{
+ struct nfs41_call_sync_data *data = calldata;
+
+ dprintk("--> %s data->clp->cl_session %p\n", __func__,
+ data->clp->cl_session);
+ if (nfs4_setup_sequence(data->clp, data->seq_args,
+ data->seq_res, data->cache_reply, task))
+ return;
+ rpc_call_start(task);
+}
+
+static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
+{
+ struct nfs41_call_sync_data *data = calldata;
+
+ nfs41_sequence_done(data->clp, data->seq_res, task->tk_status);
+ nfs41_sequence_free_slot(data->clp, data->seq_res);
+}
+
+struct rpc_call_ops nfs41_call_sync_ops = {
+ .rpc_call_prepare = nfs41_call_sync_prepare,
+ .rpc_call_done = nfs41_call_sync_done,
+};
+
+static int nfs4_call_sync_sequence(struct nfs_client *clp,
+ struct rpc_clnt *clnt,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply)
+{
+ int ret;
+ struct rpc_task *task;
+ struct nfs41_call_sync_data data = {
+ .clp = clp,
+ .seq_args = args,
+ .seq_res = res,
+ .cache_reply = cache_reply,
+ };
+ struct rpc_task_setup task_setup = {
+ .rpc_client = clnt,
+ .rpc_message = msg,
+ .callback_ops = &nfs41_call_sync_ops,
+ .callback_data = &data
+ };
+
+ res->sr_slotid = NFS4_MAX_SLOT_TABLE;
+ task = rpc_run_task(&task_setup);
+ if (IS_ERR(task))
+ ret = PTR_ERR(task);
+ else {
+ ret = task->tk_status;
+ rpc_put_task(task);
+ }
+ return ret;
+}
+
+int _nfs4_call_sync_session(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply)
+{
+ return nfs4_call_sync_sequence(server->nfs_client, server->client,
+ msg, args, res, cache_reply);
+}
+
+#endif /* CONFIG_NFS_V4_1 */
+
+int _nfs4_call_sync(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply)
+{
+ args->sa_session = res->sr_session = NULL;
+ return rpc_call_sync(server->client, msg, 0);
+}
+
+#define nfs4_call_sync(server, msg, args, res, cache_reply) \
+ (server)->nfs_client->cl_call_sync((server), (msg), &(args)->seq_args, \
+ &(res)->seq_res, (cache_reply))
+
+static void nfs4_sequence_done(const struct nfs_server *server,
+ struct nfs4_sequence_res *res, int rpc_status)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (nfs4_has_session(server->nfs_client))
+ nfs41_sequence_done(server->nfs_client, res, rpc_status);
+#endif /* CONFIG_NFS_V4_1 */
+}
+
+/* no restart, therefore free slot here */
+static void nfs4_sequence_done_free_slot(const struct nfs_server *server,
+ struct nfs4_sequence_res *res,
+ int rpc_status)
+{
+ nfs4_sequence_done(server, res, rpc_status);
+ nfs4_sequence_free_slot(server->nfs_client, res);
+}
+
static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
{
struct nfs_inode *nfsi = NFS_I(dir);
@@ -343,6 +710,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
p->o_arg.server = server;
p->o_arg.bitmask = server->attr_bitmask;
p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
+ p->o_res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
if (flags & O_EXCL) {
u32 *s = (u32 *) p->o_arg.u.verifier.data;
s[0] = jiffies;
@@ -929,6 +1297,10 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
}
data->timestamp = jiffies;
+ if (nfs4_setup_sequence(data->o_arg.server->nfs_client,
+ &data->o_arg.seq_args,
+ &data->o_res.seq_res, 1, task))
+ return;
rpc_call_start(task);
return;
out_no_action:
@@ -941,6 +1313,10 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
struct nfs4_opendata *data = calldata;
data->rpc_status = task->tk_status;
+
+ nfs4_sequence_done_free_slot(data->o_arg.server, &data->o_res.seq_res,
+ task->tk_status);
+
if (RPC_ASSASSINATED(task))
return;
if (task->tk_status == 0) {
@@ -1269,7 +1645,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
} else
memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &arg, &res, 1);
if (status == 0 && state != NULL)
renew_lease(server, timestamp);
return status;
@@ -1318,6 +1694,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
struct nfs4_state *state = calldata->state;
struct nfs_server *server = NFS_SERVER(calldata->inode);
+ nfs4_sequence_done(server, &calldata->res.seq_res, task->tk_status);
if (RPC_ASSASSINATED(task))
return;
/* hmm. we are done with the inode, and in the process of freeing
@@ -1336,10 +1713,11 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
break;
default:
if (nfs4_async_handle_error(task, server, state) == -EAGAIN) {
- rpc_restart_call(task);
+ nfs4_restart_rpc(task, server->nfs_client);
return;
}
}
+ nfs4_sequence_free_slot(server->nfs_client, &calldata->res.seq_res);
nfs_refresh_inode(calldata->inode, calldata->res.fattr);
}
@@ -1380,6 +1758,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
calldata->arg.fmode = FMODE_WRITE;
}
calldata->timestamp = jiffies;
+ if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client,
+ &calldata->arg.seq_args, &calldata->res.seq_res,
+ 1, task))
+ return;
rpc_call_start(task);
}
@@ -1419,13 +1801,15 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
};
int status = -ENOMEM;
- calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
+ calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
if (calldata == NULL)
goto out;
calldata->inode = state->inode;
calldata->state = state;
calldata->arg.fh = NFS_FH(state->inode);
calldata->arg.stateid = &state->open_stateid;
+ if (nfs4_has_session(server->nfs_client))
+ memset(calldata->arg.stateid->data, 0, 4); /* clear seqid */
/* Serialization for the sequence id */
calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
if (calldata->arg.seqid == NULL)
@@ -1435,6 +1819,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
calldata->res.fattr = &calldata->fattr;
calldata->res.seqid = calldata->arg.seqid;
calldata->res.server = server;
+ calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
calldata->path.mnt = mntget(path->mnt);
calldata->path.dentry = dget(path->dentry);
@@ -1584,15 +1969,18 @@ void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
{
+ struct nfs4_server_caps_arg args = {
+ .fhandle = fhandle,
+ };
struct nfs4_server_caps_res res = {};
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SERVER_CAPS],
- .rpc_argp = fhandle,
+ .rpc_argp = &args,
.rpc_resp = &res,
};
int status;
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &args, &res, 0);
if (status == 0) {
memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
@@ -1606,6 +1994,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
server->acl_bitmask = res.acl_bitmask;
}
+
return status;
}
@@ -1637,8 +2026,15 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
.rpc_argp = &args,
.rpc_resp = &res,
};
+ int status;
+
nfs_fattr_init(info->fattr);
- return rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_recover_expired_lease(server);
+ if (!status)
+ status = nfs4_check_client_ready(server->nfs_client);
+ if (!status)
+ status = nfs4_call_sync(server, &msg, &args, &res, 0);
+ return status;
}
static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -1728,7 +2124,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
};
nfs_fattr_init(fattr);
- return rpc_call_sync(server->client, &msg, 0);
+ return nfs4_call_sync(server, &msg, &args, &res, 0);
}
static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
@@ -1812,7 +2208,7 @@ static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *d
nfs_fattr_init(fattr);
dprintk("NFS call lookupfh %s\n", name->name);
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &args, &res, 0);
dprintk("NFS reply lookupfh: %d\n", status);
return status;
}
@@ -1898,7 +2294,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
args.access |= NFS4_ACCESS_EXECUTE;
}
nfs_fattr_init(&fattr);
- status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+ status = nfs4_call_sync(server, &msg, &args, &res, 0);
if (!status) {
entry->mask = 0;
if (res.access & NFS4_ACCESS_READ)
@@ -1957,13 +2353,14 @@ static int _nfs4_proc_readlink(struct inode *inode, struct page *page,
.pglen = pglen,
.pages = &page,
};
+ struct nfs4_readlink_res res;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READLINK],
.rpc_argp = &args,
- .rpc_resp = NULL,
+ .rpc_resp = &res,
};
- return rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+ return nfs4_call_sync(NFS_SERVER(inode), &msg, &args, &res, 0);
}
static int nfs4_proc_readlink(struct inode *inode, struct page *page,
@@ -2057,7 +2454,7 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
int status;
nfs_fattr_init(&res.dir_attr);
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &args, &res, 1);
if (status == 0) {
update_changeattr(dir, &res.cinfo);
nfs_post_op_update_inode(dir, &res.dir_attr);
@@ -2092,8 +2489,10 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
{
struct nfs_removeres *res = task->tk_msg.rpc_resp;
+ nfs4_sequence_done(res->server, &res->seq_res, task->tk_status);
if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
return 0;
+ nfs4_sequence_free_slot(res->server->nfs_client, &res->seq_res);
update_changeattr(dir, &res->cinfo);
nfs_post_op_update_inode(dir, &res->dir_attr);
return 1;
@@ -2125,7 +2524,7 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
nfs_fattr_init(res.old_fattr);
nfs_fattr_init(res.new_fattr);
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &arg, &res, 1);
if (!status) {
update_changeattr(old_dir, &res.old_cinfo);
@@ -2174,7 +2573,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
nfs_fattr_init(res.fattr);
nfs_fattr_init(res.dir_attr);
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &arg, &res, 1);
if (!status) {
update_changeattr(dir, &res.cinfo);
nfs_post_op_update_inode(dir, res.dir_attr);
@@ -2235,7 +2634,8 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data)
{
- int status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0);
+ int status = nfs4_call_sync(NFS_SERVER(dir), &data->msg,
+ &data->arg, &data->res, 1);
if (status == 0) {
update_changeattr(dir, &data->res.dir_cinfo);
nfs_post_op_update_inode(dir, data->res.dir_fattr);
@@ -2344,7 +2744,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
(unsigned long long)cookie);
nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
res.pgbase = args.pgbase;
- status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0);
if (status == 0)
memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
@@ -2422,14 +2822,17 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
.fh = fhandle,
.bitmask = server->attr_bitmask,
};
+ struct nfs4_statfs_res res = {
+ .fsstat = fsstat,
+ };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_STATFS],
.rpc_argp = &args,
- .rpc_resp = fsstat,
+ .rpc_resp = &res,
};
nfs_fattr_init(fsstat->fattr);
- return rpc_call_sync(server->client, &msg, 0);
+ return nfs4_call_sync(server, &msg, &args, &res, 0);
}
static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
@@ -2451,13 +2854,16 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
.fh = fhandle,
.bitmask = server->attr_bitmask,
};
+ struct nfs4_fsinfo_res res = {
+ .fsinfo = fsinfo,
+ };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO],
.rpc_argp = &args,
- .rpc_resp = fsinfo,
+ .rpc_resp = &res,
};
- return rpc_call_sync(server->client, &msg, 0);
+ return nfs4_call_sync(server, &msg, &args, &res, 0);
}
static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
@@ -2486,10 +2892,13 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
.fh = fhandle,
.bitmask = server->attr_bitmask,
};
+ struct nfs4_pathconf_res res = {
+ .pathconf = pathconf,
+ };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PATHCONF],
.rpc_argp = &args,
- .rpc_resp = pathconf,
+ .rpc_resp = &res,
};
/* None of the pathconf attributes are mandatory to implement */
@@ -2499,7 +2908,7 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
}
nfs_fattr_init(pathconf->fattr);
- return rpc_call_sync(server->client, &msg, 0);
+ return nfs4_call_sync(server, &msg, &args, &res, 0);
}
static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -2520,8 +2929,13 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
{
struct nfs_server *server = NFS_SERVER(data->inode);
+ dprintk("--> %s\n", __func__);
+
+ /* nfs4_sequence_free_slot called in the read rpc_call_done */
+ nfs4_sequence_done(server, &data->res.seq_res, task->tk_status);
+
if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
- rpc_restart_call(task);
+ nfs4_restart_rpc(task, server->nfs_client);
return -EAGAIN;
}
@@ -2541,8 +2955,12 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
{
struct inode *inode = data->inode;
+ /* slot is freed in nfs_writeback_done */
+ nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
+ task->tk_status);
+
if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
- rpc_restart_call(task);
+ nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
return -EAGAIN;
}
if (task->tk_status >= 0) {
@@ -2567,10 +2985,14 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
{
struct inode *inode = data->inode;
+ nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
+ task->tk_status);
if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
- rpc_restart_call(task);
+ nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
return -EAGAIN;
}
+ nfs4_sequence_free_slot(NFS_SERVER(inode)->nfs_client,
+ &data->res.seq_res);
nfs_refresh_inode(inode, data->res.fattr);
return 0;
}
@@ -2606,6 +3028,9 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
if (time_before(clp->cl_last_renewal,timestamp))
clp->cl_last_renewal = timestamp;
spin_unlock(&clp->cl_lock);
+ dprintk("%s calling put_rpccred on rpc_cred %p\n", __func__,
+ task->tk_msg.rpc_cred);
+ put_rpccred(task->tk_msg.rpc_cred);
}
static const struct rpc_call_ops nfs4_renew_ops = {
@@ -2745,12 +3170,14 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
.acl_pages = pages,
.acl_len = buflen,
};
- size_t resp_len = buflen;
+ struct nfs_getaclres res = {
+ .acl_len = buflen,
+ };
void *resp_buf;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
.rpc_argp = &args,
- .rpc_resp = &resp_len,
+ .rpc_resp = &res,
};
struct page *localpage = NULL;
int ret;
@@ -2764,26 +3191,26 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
return -ENOMEM;
args.acl_pages[0] = localpage;
args.acl_pgbase = 0;
- resp_len = args.acl_len = PAGE_SIZE;
+ args.acl_len = PAGE_SIZE;
} else {
resp_buf = buf;
buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
}
- ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+ ret = nfs4_call_sync(NFS_SERVER(inode), &msg, &args, &res, 0);
if (ret)
goto out_free;
- if (resp_len > args.acl_len)
- nfs4_write_cached_acl(inode, NULL, resp_len);
+ if (res.acl_len > args.acl_len)
+ nfs4_write_cached_acl(inode, NULL, res.acl_len);
else
- nfs4_write_cached_acl(inode, resp_buf, resp_len);
+ nfs4_write_cached_acl(inode, resp_buf, res.acl_len);
if (buf) {
ret = -ERANGE;
- if (resp_len > buflen)
+ if (res.acl_len > buflen)
goto out_free;
if (localpage)
- memcpy(buf, resp_buf, resp_len);
+ memcpy(buf, resp_buf, res.acl_len);
}
- ret = resp_len;
+ ret = res.acl_len;
out_free:
if (localpage)
__free_page(localpage);
@@ -2830,10 +3257,11 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
.acl_pages = pages,
.acl_len = buflen,
};
+ struct nfs_setaclres res;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETACL],
.rpc_argp = &arg,
- .rpc_resp = NULL,
+ .rpc_resp = &res,
};
int ret;
@@ -2841,7 +3269,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
return -EOPNOTSUPP;
nfs_inode_return_delegation(inode);
buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
- ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+ ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
nfs_access_zap_cache(inode);
nfs_zap_acl_cache(inode);
return ret;
@@ -2860,10 +3288,8 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
}
static int
-nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
+_nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs_client *clp, struct nfs4_state *state)
{
- struct nfs_client *clp = server->nfs_client;
-
if (!clp || task->tk_status >= 0)
return 0;
switch(task->tk_status) {
@@ -2882,8 +3308,23 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
task->tk_status = 0;
return -EAGAIN;
+#if defined(CONFIG_NFS_V4_1)
+ case -NFS4ERR_BADSESSION:
+ case -NFS4ERR_BADSLOT:
+ case -NFS4ERR_BAD_HIGH_SLOT:
+ case -NFS4ERR_DEADSESSION:
+ case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+ case -NFS4ERR_SEQ_FALSE_RETRY:
+ case -NFS4ERR_SEQ_MISORDERED:
+ dprintk("%s ERROR %d, Reset session\n", __func__,
+ task->tk_status);
+ set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
+ task->tk_status = 0;
+ return -EAGAIN;
+#endif /* CONFIG_NFS_V4_1 */
case -NFS4ERR_DELAY:
- nfs_inc_server_stats(server, NFSIOS_DELAY);
+ if (server)
+ nfs_inc_server_stats(server, NFSIOS_DELAY);
case -NFS4ERR_GRACE:
rpc_delay(task, NFS4_POLL_RETRY_MAX);
task->tk_status = 0;
@@ -2896,6 +3337,12 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
return 0;
}
+static int
+nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
+{
+ return _nfs4_async_handle_error(task, server, server->nfs_client, state);
+}
+
int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
{
nfs4_verifier sc_verifier;
@@ -3003,6 +3450,10 @@ struct nfs4_delegreturndata {
static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
{
struct nfs4_delegreturndata *data = calldata;
+
+ nfs4_sequence_done_free_slot(data->res.server, &data->res.seq_res,
+ task->tk_status);
+
data->rpc_status = task->tk_status;
if (data->rpc_status == 0)
renew_lease(data->res.server, data->timestamp);
@@ -3013,7 +3464,25 @@ static void nfs4_delegreturn_release(void *calldata)
kfree(calldata);
}
+#if defined(CONFIG_NFS_V4_1)
+static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
+{
+ struct nfs4_delegreturndata *d_data;
+
+ d_data = (struct nfs4_delegreturndata *)data;
+
+ if (nfs4_setup_sequence(d_data->res.server->nfs_client,
+ &d_data->args.seq_args,
+ &d_data->res.seq_res, 1, task))
+ return;
+ rpc_call_start(task);
+}
+#endif /* CONFIG_NFS_V4_1 */
+
static const struct rpc_call_ops nfs4_delegreturn_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs4_delegreturn_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs4_delegreturn_done,
.rpc_release = nfs4_delegreturn_release,
};
@@ -3035,7 +3504,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
};
int status = 0;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
data->args.fhandle = &data->fh;
@@ -3045,6 +3514,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
memcpy(&data->stateid, stateid, sizeof(data->stateid));
data->res.fattr = &data->fattr;
data->res.server = server;
+ data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
nfs_fattr_init(data->res.fattr);
data->timestamp = jiffies;
data->rpc_status = 0;
@@ -3130,7 +3600,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
goto out;
lsp = request->fl_u.nfs4_fl.owner;
arg.lock_owner.id = lsp->ls_id.id;
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &arg, &res, 1);
switch (status) {
case 0:
request->fl_type = F_UNLCK;
@@ -3190,13 +3660,14 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
struct nfs4_unlockdata *p;
struct inode *inode = lsp->ls_state->inode;
- p = kmalloc(sizeof(*p), GFP_KERNEL);
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL)
return NULL;
p->arg.fh = NFS_FH(inode);
p->arg.fl = &p->fl;
p->arg.seqid = seqid;
p->res.seqid = seqid;
+ p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
p->arg.stateid = &lsp->ls_stateid;
p->lsp = lsp;
atomic_inc(&lsp->ls_count);
@@ -3220,6 +3691,8 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
{
struct nfs4_unlockdata *calldata = data;
+ nfs4_sequence_done(calldata->server, &calldata->res.seq_res,
+ task->tk_status);
if (RPC_ASSASSINATED(task))
return;
switch (task->tk_status) {
@@ -3236,8 +3709,11 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
break;
default:
if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
- rpc_restart_call(task);
+ nfs4_restart_rpc(task,
+ calldata->server->nfs_client);
}
+ nfs4_sequence_free_slot(calldata->server->nfs_client,
+ &calldata->res.seq_res);
}
static void nfs4_locku_prepare(struct rpc_task *task, void *data)
@@ -3252,6 +3728,10 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
return;
}
calldata->timestamp = jiffies;
+ if (nfs4_setup_sequence(calldata->server->nfs_client,
+ &calldata->arg.seq_args,
+ &calldata->res.seq_res, 1, task))
+ return;
rpc_call_start(task);
}
@@ -3344,6 +3824,7 @@ struct nfs4_lockdata {
unsigned long timestamp;
int rpc_status;
int cancelled;
+ struct nfs_server *server;
};
static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
@@ -3369,7 +3850,9 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
p->arg.lock_owner.id = lsp->ls_id.id;
p->res.lock_seqid = p->arg.lock_seqid;
+ p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
p->lsp = lsp;
+ p->server = server;
atomic_inc(&lsp->ls_count);
p->ctx = get_nfs_open_context(ctx);
memcpy(&p->fl, fl, sizeof(p->fl));
@@ -3399,6 +3882,9 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
} else
data->arg.new_lock_owner = 0;
data->timestamp = jiffies;
+ if (nfs4_setup_sequence(data->server->nfs_client, &data->arg.seq_args,
+ &data->res.seq_res, 1, task))
+ return;
rpc_call_start(task);
dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
}
@@ -3409,6 +3895,9 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
dprintk("%s: begin!\n", __func__);
+ nfs4_sequence_done_free_slot(data->server, &data->res.seq_res,
+ task->tk_status);
+
data->rpc_status = task->tk_status;
if (RPC_ASSASSINATED(task))
goto out;
@@ -3709,10 +4198,13 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
.page = page,
.bitmask = bitmask,
};
+ struct nfs4_fs_locations_res res = {
+ .fs_locations = fs_locations,
+ };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
.rpc_argp = &args,
- .rpc_resp = fs_locations,
+ .rpc_resp = &res,
};
int status;
@@ -3720,24 +4212,663 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
nfs_fattr_init(&fs_locations->fattr);
fs_locations->server = server;
fs_locations->nlocations = 0;
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &args, &res, 0);
nfs_fixup_referral_attributes(&fs_locations->fattr);
dprintk("%s: returned status = %d\n", __func__, status);
return status;
}
-struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
+#ifdef CONFIG_NFS_V4_1
+/*
+ * nfs4_proc_exchange_id()
+ *
+ * Since the clientid has expired, all compounds using sessions
+ * associated with the stale clientid will be returning
+ * NFS4ERR_BADSESSION in the sequence operation, and will therefore
+ * be in some phase of session reset.
+ */
+static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
+{
+ nfs4_verifier verifier;
+ struct nfs41_exchange_id_args args = {
+ .client = clp,
+ .flags = clp->cl_exchange_flags,
+ };
+ struct nfs41_exchange_id_res res = {
+ .client = clp,
+ };
+ int status;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_EXCHANGE_ID],
+ .rpc_argp = &args,
+ .rpc_resp = &res,
+ .rpc_cred = cred,
+ };
+ __be32 *p;
+
+ dprintk("--> %s\n", __func__);
+ BUG_ON(clp == NULL);
+
+ p = (u32 *)verifier.data;
+ *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
+ *p = htonl((u32)clp->cl_boot_time.tv_nsec);
+ args.verifier = &verifier;
+
+ while (1) {
+ args.id_len = scnprintf(args.id, sizeof(args.id),
+ "%s/%s %u",
+ clp->cl_ipaddr,
+ rpc_peeraddr2str(clp->cl_rpcclient,
+ RPC_DISPLAY_ADDR),
+ clp->cl_id_uniquifier);
+
+ status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
+
+ if (status != NFS4ERR_CLID_INUSE)
+ break;
+
+ if (signalled())
+ break;
+
+ if (++clp->cl_id_uniquifier == 0)
+ break;
+ }
+
+ dprintk("<-- %s status= %d\n", __func__, status);
+ return status;
+}
+
+struct nfs4_get_lease_time_data {
+ struct nfs4_get_lease_time_args *args;
+ struct nfs4_get_lease_time_res *res;
+ struct nfs_client *clp;
+};
+
+static void nfs4_get_lease_time_prepare(struct rpc_task *task,
+ void *calldata)
+{
+ int ret;
+ struct nfs4_get_lease_time_data *data =
+ (struct nfs4_get_lease_time_data *)calldata;
+
+ dprintk("--> %s\n", __func__);
+ /* just setup sequence, do not trigger session recovery
+ since we're invoked within one */
+ ret = nfs41_setup_sequence(data->clp->cl_session,
+ &data->args->la_seq_args,
+ &data->res->lr_seq_res, 0, task);
+
+ BUG_ON(ret == -EAGAIN);
+ rpc_call_start(task);
+ dprintk("<-- %s\n", __func__);
+}
+
+/*
+ * Called from nfs4_state_manager thread for session setup, so don't recover
+ * from sequence operation or clientid errors.
+ */
+static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
+{
+ struct nfs4_get_lease_time_data *data =
+ (struct nfs4_get_lease_time_data *)calldata;
+
+ dprintk("--> %s\n", __func__);
+ nfs41_sequence_done(data->clp, &data->res->lr_seq_res, task->tk_status);
+ switch (task->tk_status) {
+ case -NFS4ERR_DELAY:
+ case -NFS4ERR_GRACE:
+ dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
+ rpc_delay(task, NFS4_POLL_RETRY_MIN);
+ task->tk_status = 0;
+ nfs4_restart_rpc(task, data->clp);
+ return;
+ }
+ nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res);
+ dprintk("<-- %s\n", __func__);
+}
+
+struct rpc_call_ops nfs4_get_lease_time_ops = {
+ .rpc_call_prepare = nfs4_get_lease_time_prepare,
+ .rpc_call_done = nfs4_get_lease_time_done,
+};
+
+int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
+{
+ struct rpc_task *task;
+ struct nfs4_get_lease_time_args args;
+ struct nfs4_get_lease_time_res res = {
+ .lr_fsinfo = fsinfo,
+ };
+ struct nfs4_get_lease_time_data data = {
+ .args = &args,
+ .res = &res,
+ .clp = clp,
+ };
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GET_LEASE_TIME],
+ .rpc_argp = &args,
+ .rpc_resp = &res,
+ };
+ struct rpc_task_setup task_setup = {
+ .rpc_client = clp->cl_rpcclient,
+ .rpc_message = &msg,
+ .callback_ops = &nfs4_get_lease_time_ops,
+ .callback_data = &data
+ };
+ int status;
+
+ res.lr_seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
+ dprintk("--> %s\n", __func__);
+ task = rpc_run_task(&task_setup);
+
+ if (IS_ERR(task))
+ status = PTR_ERR(task);
+ else {
+ status = task->tk_status;
+ rpc_put_task(task);
+ }
+ dprintk("<-- %s return %d\n", __func__, status);
+
+ return status;
+}
+
+/* Reset a slot table */
+static int nfs4_reset_slot_table(struct nfs4_session *session)
+{
+ struct nfs4_slot_table *tbl = &session->fc_slot_table;
+ int i, max_slots = session->fc_attrs.max_reqs;
+ int old_max_slots = session->fc_slot_table.max_slots;
+ int ret = 0;
+
+ dprintk("--> %s: max_reqs=%u, tbl %p\n", __func__,
+ session->fc_attrs.max_reqs, tbl);
+
+ /* Until we have dynamic slot table adjustment, insist
+ * upon the same slot table size */
+ if (max_slots != old_max_slots) {
+ dprintk("%s reset slot table does't match old\n",
+ __func__);
+ ret = -EINVAL; /*XXX NFS4ERR_REQ_TOO_BIG ? */
+ goto out;
+ }
+ spin_lock(&tbl->slot_tbl_lock);
+ for (i = 0; i < max_slots; ++i)
+ tbl->slots[i].seq_nr = 1;
+ tbl->highest_used_slotid = -1;
+ spin_unlock(&tbl->slot_tbl_lock);
+ dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
+ tbl, tbl->slots, tbl->max_slots);
+out:
+ dprintk("<-- %s: return %d\n", __func__, ret);
+ return ret;
+}
+
+/*
+ * Initialize slot table
+ */
+static int nfs4_init_slot_table(struct nfs4_session *session)
+{
+ struct nfs4_slot_table *tbl = &session->fc_slot_table;
+ int i, max_slots = session->fc_attrs.max_reqs;
+ struct nfs4_slot *slot;
+ int ret = -ENOMEM;
+
+ BUG_ON(max_slots > NFS4_MAX_SLOT_TABLE);
+
+ dprintk("--> %s: max_reqs=%u\n", __func__,
+ session->fc_attrs.max_reqs);
+
+ slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL);
+ if (!slot)
+ goto out;
+ for (i = 0; i < max_slots; ++i)
+ slot[i].seq_nr = 1;
+ ret = 0;
+
+ spin_lock(&tbl->slot_tbl_lock);
+ if (tbl->slots != NULL) {
+ spin_unlock(&tbl->slot_tbl_lock);
+ dprintk("%s: slot table already initialized. tbl=%p slots=%p\n",
+ __func__, tbl, tbl->slots);
+ WARN_ON(1);
+ goto out_free;
+ }
+ tbl->max_slots = max_slots;
+ tbl->slots = slot;
+ tbl->highest_used_slotid = -1; /* no slot is currently used */
+ spin_unlock(&tbl->slot_tbl_lock);
+ dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
+ tbl, tbl->slots, tbl->max_slots);
+out:
+ dprintk("<-- %s: return %d\n", __func__, ret);
+ return ret;
+out_free:
+ kfree(slot);
+ goto out;
+}
+
+/* Destroy the slot table */
+static void nfs4_destroy_slot_table(struct nfs4_session *session)
+{
+ if (session->fc_slot_table.slots == NULL)
+ return;
+ kfree(session->fc_slot_table.slots);
+ session->fc_slot_table.slots = NULL;
+ return;
+}
+
+struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
+{
+ struct nfs4_session *session;
+ struct nfs4_slot_table *tbl;
+
+ session = kzalloc(sizeof(struct nfs4_session), GFP_KERNEL);
+ if (!session)
+ return NULL;
+
+ set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
+ /*
+ * The create session reply races with the server back
+ * channel probe. Mark the client NFS_CS_SESSION_INITING
+ * so that the client back channel can find the
+ * nfs_client struct
+ */
+ clp->cl_cons_state = NFS_CS_SESSION_INITING;
+
+ tbl = &session->fc_slot_table;
+ spin_lock_init(&tbl->slot_tbl_lock);
+ rpc_init_wait_queue(&tbl->slot_tbl_waitq, "Slot table");
+ session->clp = clp;
+ return session;
+}
+
+void nfs4_destroy_session(struct nfs4_session *session)
+{
+ nfs4_destroy_slot_table(session);
+ kfree(session);
+}
+
+/*
+ * Initialize the values to be used by the client in CREATE_SESSION
+ * If nfs4_init_session set the fore channel request and response sizes,
+ * use them.
+ *
+ * Set the back channel max_resp_sz_cached to zero to force the client to
+ * always set csa_cachethis to FALSE because the current implementation
+ * of the back channel DRC only supports caching the CB_SEQUENCE operation.
+ */
+static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
+{
+ struct nfs4_session *session = args->client->cl_session;
+ unsigned int mxrqst_sz = session->fc_attrs.max_rqst_sz,
+ mxresp_sz = session->fc_attrs.max_resp_sz;
+
+ if (mxrqst_sz == 0)
+ mxrqst_sz = NFS_MAX_FILE_IO_SIZE;
+ if (mxresp_sz == 0)
+ mxresp_sz = NFS_MAX_FILE_IO_SIZE;
+ /* Fore channel attributes */
+ args->fc_attrs.headerpadsz = 0;
+ args->fc_attrs.max_rqst_sz = mxrqst_sz;
+ args->fc_attrs.max_resp_sz = mxresp_sz;
+ args->fc_attrs.max_resp_sz_cached = mxresp_sz;
+ args->fc_attrs.max_ops = NFS4_MAX_OPS;
+ args->fc_attrs.max_reqs = session->clp->cl_rpcclient->cl_xprt->max_reqs;
+
+ dprintk("%s: Fore Channel : max_rqst_sz=%u max_resp_sz=%u "
+ "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
+ __func__,
+ args->fc_attrs.max_rqst_sz, args->fc_attrs.max_resp_sz,
+ args->fc_attrs.max_resp_sz_cached, args->fc_attrs.max_ops,
+ args->fc_attrs.max_reqs);
+
+ /* Back channel attributes */
+ args->bc_attrs.headerpadsz = 0;
+ args->bc_attrs.max_rqst_sz = PAGE_SIZE;
+ args->bc_attrs.max_resp_sz = PAGE_SIZE;
+ args->bc_attrs.max_resp_sz_cached = 0;
+ args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
+ args->bc_attrs.max_reqs = 1;
+
+ dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u "
+ "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
+ __func__,
+ args->bc_attrs.max_rqst_sz, args->bc_attrs.max_resp_sz,
+ args->bc_attrs.max_resp_sz_cached, args->bc_attrs.max_ops,
+ args->bc_attrs.max_reqs);
+}
+
+static int _verify_channel_attr(char *chan, char *attr_name, u32 sent, u32 rcvd)
+{
+ if (rcvd <= sent)
+ return 0;
+ printk(KERN_WARNING "%s: Session INVALID: %s channel %s increased. "
+ "sent=%u rcvd=%u\n", __func__, chan, attr_name, sent, rcvd);
+ return -EINVAL;
+}
+
+#define _verify_fore_channel_attr(_name_) \
+ _verify_channel_attr("fore", #_name_, \
+ args->fc_attrs._name_, \
+ session->fc_attrs._name_)
+
+#define _verify_back_channel_attr(_name_) \
+ _verify_channel_attr("back", #_name_, \
+ args->bc_attrs._name_, \
+ session->bc_attrs._name_)
+
+/*
+ * The server is not allowed to increase the fore channel header pad size,
+ * maximum response size, or maximum number of operations.
+ *
+ * The back channel attributes are only negotiatied down: We send what the
+ * (back channel) server insists upon.
+ */
+static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args,
+ struct nfs4_session *session)
+{
+ int ret = 0;
+
+ ret |= _verify_fore_channel_attr(headerpadsz);
+ ret |= _verify_fore_channel_attr(max_resp_sz);
+ ret |= _verify_fore_channel_attr(max_ops);
+
+ ret |= _verify_back_channel_attr(headerpadsz);
+ ret |= _verify_back_channel_attr(max_rqst_sz);
+ ret |= _verify_back_channel_attr(max_resp_sz);
+ ret |= _verify_back_channel_attr(max_resp_sz_cached);
+ ret |= _verify_back_channel_attr(max_ops);
+ ret |= _verify_back_channel_attr(max_reqs);
+
+ return ret;
+}
+
+static int _nfs4_proc_create_session(struct nfs_client *clp)
+{
+ struct nfs4_session *session = clp->cl_session;
+ struct nfs41_create_session_args args = {
+ .client = clp,
+ .cb_program = NFS4_CALLBACK,
+ };
+ struct nfs41_create_session_res res = {
+ .client = clp,
+ };
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION],
+ .rpc_argp = &args,
+ .rpc_resp = &res,
+ };
+ int status;
+
+ nfs4_init_channel_attrs(&args);
+ args.flags = (SESSION4_PERSIST);
+
+ status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0);
+
+ if (!status)
+ /* Verify the session's negotiated channel_attrs values */
+ status = nfs4_verify_channel_attrs(&args, session);
+ if (!status) {
+ /* Increment the clientid slot sequence id */
+ clp->cl_seqid++;
+ }
+
+ return status;
+}
+
+/*
+ * Issues a CREATE_SESSION operation to the server.
+ * It is the responsibility of the caller to verify the session is
+ * expired before calling this routine.
+ */
+int nfs4_proc_create_session(struct nfs_client *clp, int reset)
+{
+ int status;
+ unsigned *ptr;
+ struct nfs_fsinfo fsinfo;
+ struct nfs4_session *session = clp->cl_session;
+
+ dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
+
+ status = _nfs4_proc_create_session(clp);
+ if (status)
+ goto out;
+
+ /* Init or reset the fore channel */
+ if (reset)
+ status = nfs4_reset_slot_table(session);
+ else
+ status = nfs4_init_slot_table(session);
+ dprintk("fore channel slot table initialization returned %d\n", status);
+ if (status)
+ goto out;
+
+ ptr = (unsigned *)&session->sess_id.data[0];
+ dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__,
+ clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]);
+
+ if (reset)
+ /* Lease time is aleady set */
+ goto out;
+
+ /* Get the lease time */
+ status = nfs4_proc_get_lease_time(clp, &fsinfo);
+ if (status == 0) {
+ /* Update lease time and schedule renewal */
+ spin_lock(&clp->cl_lock);
+ clp->cl_lease_time = fsinfo.lease_time * HZ;
+ clp->cl_last_renewal = jiffies;
+ clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
+ spin_unlock(&clp->cl_lock);
+
+ nfs4_schedule_state_renewal(clp);
+ }
+out:
+ dprintk("<-- %s\n", __func__);
+ return status;
+}
+
+/*
+ * Issue the over-the-wire RPC DESTROY_SESSION.
+ * The caller must serialize access to this routine.
+ */
+int nfs4_proc_destroy_session(struct nfs4_session *session)
+{
+ int status = 0;
+ struct rpc_message msg;
+
+ dprintk("--> nfs4_proc_destroy_session\n");
+
+ /* session is still being setup */
+ if (session->clp->cl_cons_state != NFS_CS_READY)
+ return status;
+
+ msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_SESSION];
+ msg.rpc_argp = session;
+ msg.rpc_resp = NULL;
+ msg.rpc_cred = NULL;
+ status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0);
+
+ if (status)
+ printk(KERN_WARNING
+ "Got error %d from the server on DESTROY_SESSION. "
+ "Session has been destroyed regardless...\n", status);
+
+ dprintk("<-- nfs4_proc_destroy_session\n");
+ return status;
+}
+
+/*
+ * Renew the cl_session lease.
+ */
+static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
+{
+ struct nfs4_sequence_args args;
+ struct nfs4_sequence_res res;
+
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE],
+ .rpc_argp = &args,
+ .rpc_resp = &res,
+ .rpc_cred = cred,
+ };
+
+ args.sa_cache_this = 0;
+
+ return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args,
+ &res, 0);
+}
+
+void nfs41_sequence_call_done(struct rpc_task *task, void *data)
+{
+ struct nfs_client *clp = (struct nfs_client *)data;
+
+ nfs41_sequence_done(clp, task->tk_msg.rpc_resp, task->tk_status);
+
+ if (task->tk_status < 0) {
+ dprintk("%s ERROR %d\n", __func__, task->tk_status);
+
+ if (_nfs4_async_handle_error(task, NULL, clp, NULL)
+ == -EAGAIN) {
+ nfs4_restart_rpc(task, clp);
+ return;
+ }
+ }
+ nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp);
+ dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
+
+ put_rpccred(task->tk_msg.rpc_cred);
+ kfree(task->tk_msg.rpc_argp);
+ kfree(task->tk_msg.rpc_resp);
+
+ dprintk("<-- %s\n", __func__);
+}
+
+static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
+{
+ struct nfs_client *clp;
+ struct nfs4_sequence_args *args;
+ struct nfs4_sequence_res *res;
+
+ clp = (struct nfs_client *)data;
+ args = task->tk_msg.rpc_argp;
+ res = task->tk_msg.rpc_resp;
+
+ if (nfs4_setup_sequence(clp, args, res, 0, task))
+ return;
+ rpc_call_start(task);
+}
+
+static const struct rpc_call_ops nfs41_sequence_ops = {
+ .rpc_call_done = nfs41_sequence_call_done,
+ .rpc_call_prepare = nfs41_sequence_prepare,
+};
+
+static int nfs41_proc_async_sequence(struct nfs_client *clp,
+ struct rpc_cred *cred)
+{
+ struct nfs4_sequence_args *args;
+ struct nfs4_sequence_res *res;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE],
+ .rpc_cred = cred,
+ };
+
+ args = kzalloc(sizeof(*args), GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
+ if (!res) {
+ kfree(args);
+ return -ENOMEM;
+ }
+ res->sr_slotid = NFS4_MAX_SLOT_TABLE;
+ msg.rpc_argp = args;
+ msg.rpc_resp = res;
+
+ return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
+ &nfs41_sequence_ops, (void *)clp);
+}
+
+#endif /* CONFIG_NFS_V4_1 */
+
+struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
+ .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
+ .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
+ .recover_open = nfs4_open_reclaim,
+ .recover_lock = nfs4_lock_reclaim,
+ .establish_clid = nfs4_init_clientid,
+ .get_clid_cred = nfs4_get_setclientid_cred,
+};
+
+#if defined(CONFIG_NFS_V4_1)
+struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
.owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
.state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
.recover_open = nfs4_open_reclaim,
.recover_lock = nfs4_lock_reclaim,
+ .establish_clid = nfs4_proc_exchange_id,
+ .get_clid_cred = nfs4_get_exchange_id_cred,
+};
+#endif /* CONFIG_NFS_V4_1 */
+
+struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = {
+ .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
+ .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
+ .recover_open = nfs4_open_expired,
+ .recover_lock = nfs4_lock_expired,
+ .establish_clid = nfs4_init_clientid,
+ .get_clid_cred = nfs4_get_setclientid_cred,
};
-struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops = {
+#if defined(CONFIG_NFS_V4_1)
+struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
.owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
.state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
.recover_open = nfs4_open_expired,
.recover_lock = nfs4_lock_expired,
+ .establish_clid = nfs4_proc_exchange_id,
+ .get_clid_cred = nfs4_get_exchange_id_cred,
+};
+#endif /* CONFIG_NFS_V4_1 */
+
+struct nfs4_state_maintenance_ops nfs40_state_renewal_ops = {
+ .sched_state_renewal = nfs4_proc_async_renew,
+ .get_state_renewal_cred_locked = nfs4_get_renew_cred_locked,
+ .renew_lease = nfs4_proc_renew,
+};
+
+#if defined(CONFIG_NFS_V4_1)
+struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = {
+ .sched_state_renewal = nfs41_proc_async_sequence,
+ .get_state_renewal_cred_locked = nfs4_get_machine_cred_locked,
+ .renew_lease = nfs4_proc_sequence,
+};
+#endif
+
+/*
+ * Per minor version reboot and network partition recovery ops
+ */
+
+struct nfs4_state_recovery_ops *nfs4_reboot_recovery_ops[] = {
+ &nfs40_reboot_recovery_ops,
+#if defined(CONFIG_NFS_V4_1)
+ &nfs41_reboot_recovery_ops,
+#endif
+};
+
+struct nfs4_state_recovery_ops *nfs4_nograce_recovery_ops[] = {
+ &nfs40_nograce_recovery_ops,
+#if defined(CONFIG_NFS_V4_1)
+ &nfs41_nograce_recovery_ops,
+#endif
+};
+
+struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[] = {
+ &nfs40_state_renewal_ops,
+#if defined(CONFIG_NFS_V4_1)
+ &nfs41_state_renewal_ops,
+#endif
};
static const struct inode_operations nfs4_file_inode_operations = {
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index f524e932ff7b..e27c6cef18f2 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -59,12 +59,14 @@
void
nfs4_renew_state(struct work_struct *work)
{
+ struct nfs4_state_maintenance_ops *ops;
struct nfs_client *clp =
container_of(work, struct nfs_client, cl_renewd.work);
struct rpc_cred *cred;
long lease, timeout;
unsigned long last, now;
+ ops = nfs4_state_renewal_ops[clp->cl_minorversion];
dprintk("%s: start\n", __func__);
/* Are there any active superblocks? */
if (list_empty(&clp->cl_superblocks))
@@ -76,7 +78,7 @@ nfs4_renew_state(struct work_struct *work)
timeout = (2 * lease) / 3 + (long)last - (long)now;
/* Are we close to a lease timeout? */
if (time_after(now, last + lease/3)) {
- cred = nfs4_get_renew_cred_locked(clp);
+ cred = ops->get_state_renewal_cred_locked(clp);
spin_unlock(&clp->cl_lock);
if (cred == NULL) {
if (list_empty(&clp->cl_delegations)) {
@@ -86,7 +88,7 @@ nfs4_renew_state(struct work_struct *work)
nfs_expire_all_delegations(clp);
} else {
/* Queue an asynchronous RENEW. */
- nfs4_proc_async_renew(clp, cred);
+ ops->sched_state_renewal(clp, cred);
put_rpccred(cred);
}
timeout = (2 * lease) / 3;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 0298e909559f..c16f24dd0e3e 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -60,7 +60,7 @@ const nfs4_stateid zero_stateid;
static LIST_HEAD(nfs4_clientid_list);
-static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
{
unsigned short port;
int status;
@@ -77,7 +77,7 @@ static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
return status;
}
-static struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
+struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
{
struct rpc_cred *cred = NULL;
@@ -114,17 +114,21 @@ struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
return cred;
}
-static struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
+#if defined(CONFIG_NFS_V4_1)
+
+struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
{
struct rpc_cred *cred;
spin_lock(&clp->cl_lock);
- cred = nfs4_get_renew_cred_locked(clp);
+ cred = nfs4_get_machine_cred_locked(clp);
spin_unlock(&clp->cl_lock);
return cred;
}
-static struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
+#endif /* CONFIG_NFS_V4_1 */
+
+struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
{
struct nfs4_state_owner *sp;
struct rb_node *pos;
@@ -738,12 +742,14 @@ static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
{
- if (status == -NFS4ERR_BAD_SEQID) {
- struct nfs4_state_owner *sp = container_of(seqid->sequence,
- struct nfs4_state_owner, so_seqid);
+ struct nfs4_state_owner *sp = container_of(seqid->sequence,
+ struct nfs4_state_owner, so_seqid);
+ struct nfs_server *server = sp->so_server;
+
+ if (status == -NFS4ERR_BAD_SEQID)
nfs4_drop_state_owner(sp);
- }
- nfs_increment_seqid(status, seqid);
+ if (!nfs4_has_session(server->nfs_client))
+ nfs_increment_seqid(status, seqid);
}
/*
@@ -1042,6 +1048,14 @@ static void nfs4_recovery_handle_error(struct nfs_client *clp, int error)
case -NFS4ERR_EXPIRED:
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
nfs4_state_start_reclaim_nograce(clp);
+ case -NFS4ERR_BADSESSION:
+ case -NFS4ERR_BADSLOT:
+ case -NFS4ERR_BAD_HIGH_SLOT:
+ case -NFS4ERR_DEADSESSION:
+ case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+ case -NFS4ERR_SEQ_FALSE_RETRY:
+ case -NFS4ERR_SEQ_MISORDERED:
+ set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
}
}
@@ -1075,18 +1089,22 @@ restart:
static int nfs4_check_lease(struct nfs_client *clp)
{
struct rpc_cred *cred;
+ struct nfs4_state_maintenance_ops *ops =
+ nfs4_state_renewal_ops[clp->cl_minorversion];
int status = -NFS4ERR_EXPIRED;
/* Is the client already known to have an expired lease? */
if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
return 0;
- cred = nfs4_get_renew_cred(clp);
+ spin_lock(&clp->cl_lock);
+ cred = ops->get_state_renewal_cred_locked(clp);
+ spin_unlock(&clp->cl_lock);
if (cred == NULL) {
cred = nfs4_get_setclientid_cred(clp);
if (cred == NULL)
goto out;
}
- status = nfs4_proc_renew(clp, cred);
+ status = ops->renew_lease(clp, cred);
put_rpccred(cred);
out:
nfs4_recovery_handle_error(clp, status);
@@ -1096,21 +1114,77 @@ out:
static int nfs4_reclaim_lease(struct nfs_client *clp)
{
struct rpc_cred *cred;
+ struct nfs4_state_recovery_ops *ops =
+ nfs4_reboot_recovery_ops[clp->cl_minorversion];
int status = -ENOENT;
- cred = nfs4_get_setclientid_cred(clp);
+ cred = ops->get_clid_cred(clp);
if (cred != NULL) {
- status = nfs4_init_client(clp, cred);
+ status = ops->establish_clid(clp, cred);
put_rpccred(cred);
/* Handle case where the user hasn't set up machine creds */
if (status == -EACCES && cred == clp->cl_machine_cred) {
nfs4_clear_machine_cred(clp);
status = -EAGAIN;
}
+ if (status == -NFS4ERR_MINOR_VERS_MISMATCH)
+ status = -EPROTONOSUPPORT;
}
return status;
}
+#ifdef CONFIG_NFS_V4_1
+static void nfs4_session_recovery_handle_error(struct nfs_client *clp, int err)
+{
+ switch (err) {
+ case -NFS4ERR_STALE_CLIENTID:
+ set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
+ set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
+ }
+}
+
+static int nfs4_reset_session(struct nfs_client *clp)
+{
+ int status;
+
+ status = nfs4_proc_destroy_session(clp->cl_session);
+ if (status && status != -NFS4ERR_BADSESSION &&
+ status != -NFS4ERR_DEADSESSION) {
+ nfs4_session_recovery_handle_error(clp, status);
+ goto out;
+ }
+
+ memset(clp->cl_session->sess_id.data, 0, NFS4_MAX_SESSIONID_LEN);
+ status = nfs4_proc_create_session(clp, 1);
+ if (status)
+ nfs4_session_recovery_handle_error(clp, status);
+ /* fall through*/
+out:
+ /* Wake up the next rpc task even on error */
+ rpc_wake_up_next(&clp->cl_session->fc_slot_table.slot_tbl_waitq);
+ return status;
+}
+
+static int nfs4_initialize_session(struct nfs_client *clp)
+{
+ int status;
+
+ status = nfs4_proc_create_session(clp, 0);
+ if (!status) {
+ nfs_mark_client_ready(clp, NFS_CS_READY);
+ } else if (status == -NFS4ERR_STALE_CLIENTID) {
+ set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
+ set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
+ } else {
+ nfs_mark_client_ready(clp, status);
+ }
+ return status;
+}
+#else /* CONFIG_NFS_V4_1 */
+static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
+static int nfs4_initialize_session(struct nfs_client *clp) { return 0; }
+#endif /* CONFIG_NFS_V4_1 */
+
static void nfs4_state_manager(struct nfs_client *clp)
{
int status = 0;
@@ -1124,6 +1198,9 @@ static void nfs4_state_manager(struct nfs_client *clp)
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
if (status == -EAGAIN)
continue;
+ if (clp->cl_cons_state ==
+ NFS_CS_SESSION_INITING)
+ nfs_mark_client_ready(clp, status);
goto out_error;
}
clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
@@ -1134,25 +1211,44 @@ static void nfs4_state_manager(struct nfs_client *clp)
if (status != 0)
continue;
}
-
+ /* Initialize or reset the session */
+ if (nfs4_has_session(clp) &&
+ test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) {
+ if (clp->cl_cons_state == NFS_CS_SESSION_INITING)
+ status = nfs4_initialize_session(clp);
+ else
+ status = nfs4_reset_session(clp);
+ if (status) {
+ if (status == -NFS4ERR_STALE_CLIENTID)
+ continue;
+ goto out_error;
+ }
+ }
/* First recover reboot state... */
if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) {
- status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops);
+ status = nfs4_do_reclaim(clp,
+ nfs4_reboot_recovery_ops[clp->cl_minorversion]);
if (status == -NFS4ERR_STALE_CLIENTID)
continue;
+ if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
+ continue;
nfs4_state_end_reclaim_reboot(clp);
continue;
}
/* Now recover expired state... */
if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
- status = nfs4_do_reclaim(clp, &nfs4_nograce_recovery_ops);
+ status = nfs4_do_reclaim(clp,
+ nfs4_nograce_recovery_ops[clp->cl_minorversion]);
if (status < 0) {
set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
if (status == -NFS4ERR_STALE_CLIENTID)
continue;
if (status == -NFS4ERR_EXPIRED)
continue;
+ if (test_bit(NFS4CLNT_SESSION_SETUP,
+ &clp->cl_state))
+ continue;
goto out_error;
} else
nfs4_state_end_reclaim_nograce(clp);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 1690f0e44b91..80af0aeaaf7d 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -192,12 +192,16 @@ static int nfs4_stat_to_errno(int);
decode_verifier_maxsz)
#define encode_remove_maxsz (op_encode_hdr_maxsz + \
nfs4_name_maxsz)
+#define decode_remove_maxsz (op_decode_hdr_maxsz + \
+ decode_change_info_maxsz)
#define encode_rename_maxsz (op_encode_hdr_maxsz + \
2 * nfs4_name_maxsz)
-#define decode_rename_maxsz (op_decode_hdr_maxsz + 5 + 5)
+#define decode_rename_maxsz (op_decode_hdr_maxsz + \
+ decode_change_info_maxsz + \
+ decode_change_info_maxsz)
#define encode_link_maxsz (op_encode_hdr_maxsz + \
nfs4_name_maxsz)
-#define decode_link_maxsz (op_decode_hdr_maxsz + 5)
+#define decode_link_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz)
#define encode_lock_maxsz (op_encode_hdr_maxsz + \
7 + \
1 + encode_stateid_maxsz + 8)
@@ -240,43 +244,115 @@ static int nfs4_stat_to_errno(int);
(encode_getattr_maxsz)
#define decode_fs_locations_maxsz \
(0)
+
+#if defined(CONFIG_NFS_V4_1)
+#define NFS4_MAX_MACHINE_NAME_LEN (64)
+
+#define encode_exchange_id_maxsz (op_encode_hdr_maxsz + \
+ encode_verifier_maxsz + \
+ 1 /* co_ownerid.len */ + \
+ XDR_QUADLEN(NFS4_EXCHANGE_ID_LEN) + \
+ 1 /* flags */ + \
+ 1 /* spa_how */ + \
+ 0 /* SP4_NONE (for now) */ + \
+ 1 /* zero implemetation id array */)
+#define decode_exchange_id_maxsz (op_decode_hdr_maxsz + \
+ 2 /* eir_clientid */ + \
+ 1 /* eir_sequenceid */ + \
+ 1 /* eir_flags */ + \
+ 1 /* spr_how */ + \
+ 0 /* SP4_NONE (for now) */ + \
+ 2 /* eir_server_owner.so_minor_id */ + \
+ /* eir_server_owner.so_major_id<> */ \
+ XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
+ /* eir_server_scope<> */ \
+ XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
+ 1 /* eir_server_impl_id array length */ + \
+ 0 /* ignored eir_server_impl_id contents */)
+#define encode_channel_attrs_maxsz (6 + 1 /* ca_rdma_ird.len (0) */)
+#define decode_channel_attrs_maxsz (6 + \
+ 1 /* ca_rdma_ird.len */ + \
+ 1 /* ca_rdma_ird */)
+#define encode_create_session_maxsz (op_encode_hdr_maxsz + \
+ 2 /* csa_clientid */ + \
+ 1 /* csa_sequence */ + \
+ 1 /* csa_flags */ + \
+ encode_channel_attrs_maxsz + \
+ encode_channel_attrs_maxsz + \
+ 1 /* csa_cb_program */ + \
+ 1 /* csa_sec_parms.len (1) */ + \
+ 1 /* cb_secflavor (AUTH_SYS) */ + \
+ 1 /* stamp */ + \
+ 1 /* machinename.len */ + \
+ XDR_QUADLEN(NFS4_MAX_MACHINE_NAME_LEN) + \
+ 1 /* uid */ + \
+ 1 /* gid */ + \
+ 1 /* gids.len (0) */)
+#define decode_create_session_maxsz (op_decode_hdr_maxsz + \
+ XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
+ 1 /* csr_sequence */ + \
+ 1 /* csr_flags */ + \
+ decode_channel_attrs_maxsz + \
+ decode_channel_attrs_maxsz)
+#define encode_destroy_session_maxsz (op_encode_hdr_maxsz + 4)
+#define decode_destroy_session_maxsz (op_decode_hdr_maxsz)
+#define encode_sequence_maxsz (op_encode_hdr_maxsz + \
+ XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4)
+#define decode_sequence_maxsz (op_decode_hdr_maxsz + \
+ XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)
+#else /* CONFIG_NFS_V4_1 */
+#define encode_sequence_maxsz 0
+#define decode_sequence_maxsz 0
+#endif /* CONFIG_NFS_V4_1 */
+
#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */
#define NFS4_dec_compound_sz (1024) /* XXX: large enough? */
#define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_read_maxsz)
#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_read_maxsz)
#define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_readlink_maxsz)
#define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_readlink_maxsz)
#define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_readdir_maxsz)
#define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_readdir_maxsz)
#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_write_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_write_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_commit_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_commit_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_open_maxsz + \
@@ -285,6 +361,7 @@ static int nfs4_stat_to_errno(int);
encode_restorefh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_open_maxsz + \
@@ -301,43 +378,53 @@ static int nfs4_stat_to_errno(int);
decode_putfh_maxsz + \
decode_open_confirm_maxsz)
#define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_open_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_open_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_open_downgrade_sz \
(compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_open_downgrade_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_open_downgrade_sz \
(compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_open_downgrade_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_close_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_close_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_setattr_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_setattr_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_fsinfo_maxsz)
#define NFS4_dec_fsinfo_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_fsinfo_maxsz)
#define NFS4_enc_renew_sz (compound_encode_hdr_maxsz + \
@@ -359,64 +446,81 @@ static int nfs4_stat_to_errno(int);
decode_putrootfh_maxsz + \
decode_fsinfo_maxsz)
#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_lock_maxsz)
#define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_lock_maxsz)
#define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_lockt_maxsz)
#define NFS4_dec_lockt_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_lockt_maxsz)
#define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_locku_maxsz)
#define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_locku_maxsz)
#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_access_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_access_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_lookup_maxsz + \
encode_getattr_maxsz + \
encode_getfh_maxsz)
#define NFS4_dec_lookup_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_lookup_maxsz + \
decode_getattr_maxsz + \
decode_getfh_maxsz)
#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putrootfh_maxsz + \
encode_getattr_maxsz + \
encode_getfh_maxsz)
#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putrootfh_maxsz + \
decode_getattr_maxsz + \
decode_getfh_maxsz)
#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_remove_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 5 + \
+ decode_remove_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_putfh_maxsz + \
@@ -425,6 +529,7 @@ static int nfs4_stat_to_errno(int);
encode_restorefh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_putfh_maxsz + \
@@ -433,6 +538,7 @@ static int nfs4_stat_to_errno(int);
decode_restorefh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_putfh_maxsz + \
@@ -441,6 +547,7 @@ static int nfs4_stat_to_errno(int);
encode_restorefh_maxsz + \
decode_getattr_maxsz)
#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_putfh_maxsz + \
@@ -449,16 +556,19 @@ static int nfs4_stat_to_errno(int);
decode_restorefh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_symlink_maxsz + \
encode_getattr_maxsz + \
encode_getfh_maxsz)
#define NFS4_dec_symlink_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_symlink_maxsz + \
decode_getattr_maxsz + \
decode_getfh_maxsz)
#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_create_maxsz + \
@@ -467,6 +577,7 @@ static int nfs4_stat_to_errno(int);
encode_restorefh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_create_maxsz + \
@@ -475,52 +586,98 @@ static int nfs4_stat_to_errno(int);
decode_restorefh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_pathconf_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_statfs_maxsz)
#define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_statfs_maxsz)
#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_delegreturn_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_delegreturn_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_getacl_maxsz)
#define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_getacl_maxsz)
#define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_setacl_maxsz)
#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_setacl_maxsz)
#define NFS4_enc_fs_locations_sz \
(compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_lookup_maxsz + \
encode_fs_locations_maxsz)
#define NFS4_dec_fs_locations_sz \
(compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_lookup_maxsz + \
decode_fs_locations_maxsz)
+#if defined(CONFIG_NFS_V4_1)
+#define NFS4_enc_exchange_id_sz \
+ (compound_encode_hdr_maxsz + \
+ encode_exchange_id_maxsz)
+#define NFS4_dec_exchange_id_sz \
+ (compound_decode_hdr_maxsz + \
+ decode_exchange_id_maxsz)
+#define NFS4_enc_create_session_sz \
+ (compound_encode_hdr_maxsz + \
+ encode_create_session_maxsz)
+#define NFS4_dec_create_session_sz \
+ (compound_decode_hdr_maxsz + \
+ decode_create_session_maxsz)
+#define NFS4_enc_destroy_session_sz (compound_encode_hdr_maxsz + \
+ encode_destroy_session_maxsz)
+#define NFS4_dec_destroy_session_sz (compound_decode_hdr_maxsz + \
+ decode_destroy_session_maxsz)
+#define NFS4_enc_sequence_sz \
+ (compound_decode_hdr_maxsz + \
+ encode_sequence_maxsz)
+#define NFS4_dec_sequence_sz \
+ (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz)
+#define NFS4_enc_get_lease_time_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
+ encode_putrootfh_maxsz + \
+ encode_fsinfo_maxsz)
+#define NFS4_dec_get_lease_time_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
+ decode_putrootfh_maxsz + \
+ decode_fsinfo_maxsz)
+#endif /* CONFIG_NFS_V4_1 */
static const umode_t nfs_type2fmt[] = {
[NF4BAD] = 0,
@@ -541,6 +698,8 @@ struct compound_hdr {
__be32 * nops_p;
uint32_t taglen;
char * tag;
+ uint32_t replen; /* expected reply words */
+ u32 minorversion;
};
/*
@@ -576,22 +735,31 @@ static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *
xdr_encode_opaque(p, str, len);
}
-static void encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
+static void encode_compound_hdr(struct xdr_stream *xdr,
+ struct rpc_rqst *req,
+ struct compound_hdr *hdr)
{
__be32 *p;
+ struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+
+ /* initialize running count of expected bytes in reply.
+ * NOTE: the replied tag SHOULD be the same is the one sent,
+ * but this is not required as a MUST for the server to do so. */
+ hdr->replen = RPC_REPHDRSIZE + auth->au_rslack + 3 + hdr->taglen;
dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag);
BUG_ON(hdr->taglen > NFS4_MAXTAGLEN);
RESERVE_SPACE(12+(XDR_QUADLEN(hdr->taglen)<<2));
WRITE32(hdr->taglen);
WRITEMEM(hdr->tag, hdr->taglen);
- WRITE32(NFS4_MINOR_VERSION);
+ WRITE32(hdr->minorversion);
hdr->nops_p = p;
WRITE32(hdr->nops);
}
static void encode_nops(struct compound_hdr *hdr)
{
+ BUG_ON(hdr->nops > NFS4_MAX_OPS);
*hdr->nops_p = htonl(hdr->nops);
}
@@ -736,6 +904,7 @@ static void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hd
WRITE32(OP_ACCESS);
WRITE32(access);
hdr->nops++;
+ hdr->replen += decode_access_maxsz;
}
static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
@@ -747,6 +916,7 @@ static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg
WRITE32(arg->seqid->sequence->counter);
WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
hdr->nops++;
+ hdr->replen += decode_close_maxsz;
}
static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
@@ -758,6 +928,7 @@ static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *ar
WRITE64(args->offset);
WRITE32(args->count);
hdr->nops++;
+ hdr->replen += decode_commit_maxsz;
}
static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create, struct compound_hdr *hdr)
@@ -789,6 +960,7 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *
WRITE32(create->name->len);
WRITEMEM(create->name->name, create->name->len);
hdr->nops++;
+ hdr->replen += decode_create_maxsz;
encode_attrs(xdr, create->attrs, create->server);
}
@@ -802,6 +974,7 @@ static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct c
WRITE32(1);
WRITE32(bitmap);
hdr->nops++;
+ hdr->replen += decode_getattr_maxsz;
}
static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1, struct compound_hdr *hdr)
@@ -814,6 +987,7 @@ static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm
WRITE32(bm0);
WRITE32(bm1);
hdr->nops++;
+ hdr->replen += decode_getattr_maxsz;
}
static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
@@ -841,6 +1015,7 @@ static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
RESERVE_SPACE(4);
WRITE32(OP_GETFH);
hdr->nops++;
+ hdr->replen += decode_getfh_maxsz;
}
static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
@@ -852,6 +1027,7 @@ static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct
WRITE32(name->len);
WRITEMEM(name->name, name->len);
hdr->nops++;
+ hdr->replen += decode_link_maxsz;
}
static inline int nfs4_lock_type(struct file_lock *fl, int block)
@@ -899,6 +1075,7 @@ static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args
WRITE32(args->lock_seqid->sequence->counter);
}
hdr->nops++;
+ hdr->replen += decode_lock_maxsz;
}
static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args, struct compound_hdr *hdr)
@@ -915,6 +1092,7 @@ static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *ar
WRITEMEM("lock id:", 8);
WRITE64(args->lock_owner.id);
hdr->nops++;
+ hdr->replen += decode_lockt_maxsz;
}
static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args, struct compound_hdr *hdr)
@@ -929,6 +1107,7 @@ static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *ar
WRITE64(args->fl->fl_start);
WRITE64(nfs4_lock_length(args->fl));
hdr->nops++;
+ hdr->replen += decode_locku_maxsz;
}
static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
@@ -941,6 +1120,7 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc
WRITE32(len);
WRITEMEM(name->name, len);
hdr->nops++;
+ hdr->replen += decode_lookup_maxsz;
}
static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode)
@@ -1080,6 +1260,7 @@ static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg,
BUG();
}
hdr->nops++;
+ hdr->replen += decode_open_maxsz;
}
static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg, struct compound_hdr *hdr)
@@ -1091,6 +1272,7 @@ static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_co
WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
WRITE32(arg->seqid->sequence->counter);
hdr->nops++;
+ hdr->replen += decode_open_confirm_maxsz;
}
static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
@@ -1103,6 +1285,7 @@ static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_close
WRITE32(arg->seqid->sequence->counter);
encode_share_access(xdr, arg->fmode);
hdr->nops++;
+ hdr->replen += decode_open_downgrade_maxsz;
}
static void
@@ -1116,6 +1299,7 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hd
WRITE32(len);
WRITEMEM(fh->data, len);
hdr->nops++;
+ hdr->replen += decode_putfh_maxsz;
}
static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
@@ -1125,6 +1309,7 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
RESERVE_SPACE(4);
WRITE32(OP_PUTROOTFH);
hdr->nops++;
+ hdr->replen += decode_putrootfh_maxsz;
}
static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx)
@@ -1153,6 +1338,7 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args,
WRITE64(args->offset);
WRITE32(args->count);
hdr->nops++;
+ hdr->replen += decode_read_maxsz;
}
static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
@@ -1178,6 +1364,7 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
WRITE32(attrs[0] & readdir->bitmask[0]);
WRITE32(attrs[1] & readdir->bitmask[1]);
hdr->nops++;
+ hdr->replen += decode_readdir_maxsz;
dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n",
__func__,
(unsigned long long)readdir->cookie,
@@ -1194,6 +1381,7 @@ static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *
RESERVE_SPACE(4);
WRITE32(OP_READLINK);
hdr->nops++;
+ hdr->replen += decode_readlink_maxsz;
}
static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
@@ -1205,6 +1393,7 @@ static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struc
WRITE32(name->len);
WRITEMEM(name->name, name->len);
hdr->nops++;
+ hdr->replen += decode_remove_maxsz;
}
static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname, struct compound_hdr *hdr)
@@ -1220,6 +1409,7 @@ static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, co
WRITE32(newname->len);
WRITEMEM(newname->name, newname->len);
hdr->nops++;
+ hdr->replen += decode_rename_maxsz;
}
static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid, struct compound_hdr *hdr)
@@ -1230,6 +1420,7 @@ static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client
WRITE32(OP_RENEW);
WRITE64(client_stateid->cl_clientid);
hdr->nops++;
+ hdr->replen += decode_renew_maxsz;
}
static void
@@ -1240,6 +1431,7 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
RESERVE_SPACE(4);
WRITE32(OP_RESTOREFH);
hdr->nops++;
+ hdr->replen += decode_restorefh_maxsz;
}
static int
@@ -1259,6 +1451,7 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun
WRITE32(arg->acl_len);
xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
hdr->nops++;
+ hdr->replen += decode_setacl_maxsz;
return 0;
}
@@ -1270,6 +1463,7 @@ encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
RESERVE_SPACE(4);
WRITE32(OP_SAVEFH);
hdr->nops++;
+ hdr->replen += decode_savefh_maxsz;
}
static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server, struct compound_hdr *hdr)
@@ -1280,6 +1474,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs
WRITE32(OP_SETATTR);
WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE);
hdr->nops++;
+ hdr->replen += decode_setattr_maxsz;
encode_attrs(xdr, arg->iap, server);
}
@@ -1299,6 +1494,7 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie
RESERVE_SPACE(4);
WRITE32(setclientid->sc_cb_ident);
hdr->nops++;
+ hdr->replen += decode_setclientid_maxsz;
}
static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state, struct compound_hdr *hdr)
@@ -1310,6 +1506,7 @@ static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_
WRITE64(client_state->cl_clientid);
WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE);
hdr->nops++;
+ hdr->replen += decode_setclientid_confirm_maxsz;
}
static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
@@ -1328,6 +1525,7 @@ static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *arg
xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
hdr->nops++;
+ hdr->replen += decode_write_maxsz;
}
static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid, struct compound_hdr *hdr)
@@ -1339,11 +1537,163 @@ static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *state
WRITE32(OP_DELEGRETURN);
WRITEMEM(stateid->data, NFS4_STATEID_SIZE);
hdr->nops++;
+ hdr->replen += decode_delegreturn_maxsz;
+}
+
+#if defined(CONFIG_NFS_V4_1)
+/* NFSv4.1 operations */
+static void encode_exchange_id(struct xdr_stream *xdr,
+ struct nfs41_exchange_id_args *args,
+ struct compound_hdr *hdr)
+{
+ uint32_t *p;
+
+ RESERVE_SPACE(4 + sizeof(args->verifier->data));
+ WRITE32(OP_EXCHANGE_ID);
+ WRITEMEM(args->verifier->data, sizeof(args->verifier->data));
+
+ encode_string(xdr, args->id_len, args->id);
+
+ RESERVE_SPACE(12);
+ WRITE32(args->flags);
+ WRITE32(0); /* zero length state_protect4_a */
+ WRITE32(0); /* zero length implementation id array */
+ hdr->nops++;
+ hdr->replen += decode_exchange_id_maxsz;
+}
+
+static void encode_create_session(struct xdr_stream *xdr,
+ struct nfs41_create_session_args *args,
+ struct compound_hdr *hdr)
+{
+ uint32_t *p;
+ char machine_name[NFS4_MAX_MACHINE_NAME_LEN];
+ uint32_t len;
+ struct nfs_client *clp = args->client;
+
+ RESERVE_SPACE(4);
+ WRITE32(OP_CREATE_SESSION);
+
+ RESERVE_SPACE(8);
+ WRITE64(clp->cl_ex_clid);
+
+ RESERVE_SPACE(8);
+ WRITE32(clp->cl_seqid); /*Sequence id */
+ WRITE32(args->flags); /*flags */
+
+ RESERVE_SPACE(2*28); /* 2 channel_attrs */
+ /* Fore Channel */
+ WRITE32(args->fc_attrs.headerpadsz); /* header padding size */
+ WRITE32(args->fc_attrs.max_rqst_sz); /* max req size */
+ WRITE32(args->fc_attrs.max_resp_sz); /* max resp size */
+ WRITE32(args->fc_attrs.max_resp_sz_cached); /* Max resp sz cached */
+ WRITE32(args->fc_attrs.max_ops); /* max operations */
+ WRITE32(args->fc_attrs.max_reqs); /* max requests */
+ WRITE32(0); /* rdmachannel_attrs */
+
+ /* Back Channel */
+ WRITE32(args->fc_attrs.headerpadsz); /* header padding size */
+ WRITE32(args->bc_attrs.max_rqst_sz); /* max req size */
+ WRITE32(args->bc_attrs.max_resp_sz); /* max resp size */
+ WRITE32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */
+ WRITE32(args->bc_attrs.max_ops); /* max operations */
+ WRITE32(args->bc_attrs.max_reqs); /* max requests */
+ WRITE32(0); /* rdmachannel_attrs */
+
+ RESERVE_SPACE(4);
+ WRITE32(args->cb_program); /* cb_program */
+
+ RESERVE_SPACE(4); /* # of security flavors */
+ WRITE32(1);
+
+ RESERVE_SPACE(4);
+ WRITE32(RPC_AUTH_UNIX); /* auth_sys */
+
+ /* authsys_parms rfc1831 */
+ RESERVE_SPACE(4);
+ WRITE32((u32)clp->cl_boot_time.tv_nsec); /* stamp */
+ len = scnprintf(machine_name, sizeof(machine_name), "%s",
+ clp->cl_ipaddr);
+ RESERVE_SPACE(16 + len);
+ WRITE32(len);
+ WRITEMEM(machine_name, len);
+ WRITE32(0); /* UID */
+ WRITE32(0); /* GID */
+ WRITE32(0); /* No more gids */
+ hdr->nops++;
+ hdr->replen += decode_create_session_maxsz;
}
+
+static void encode_destroy_session(struct xdr_stream *xdr,
+ struct nfs4_session *session,
+ struct compound_hdr *hdr)
+{
+ uint32_t *p;
+ RESERVE_SPACE(4 + NFS4_MAX_SESSIONID_LEN);
+ WRITE32(OP_DESTROY_SESSION);
+ WRITEMEM(session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
+ hdr->nops++;
+ hdr->replen += decode_destroy_session_maxsz;
+}
+#endif /* CONFIG_NFS_V4_1 */
+
+static void encode_sequence(struct xdr_stream *xdr,
+ const struct nfs4_sequence_args *args,
+ struct compound_hdr *hdr)
+{
+#if defined(CONFIG_NFS_V4_1)
+ struct nfs4_session *session = args->sa_session;
+ struct nfs4_slot_table *tp;
+ struct nfs4_slot *slot;
+ __be32 *p;
+
+ if (!session)
+ return;
+
+ tp = &session->fc_slot_table;
+
+ WARN_ON(args->sa_slotid == NFS4_MAX_SLOT_TABLE);
+ slot = tp->slots + args->sa_slotid;
+
+ RESERVE_SPACE(4);
+ WRITE32(OP_SEQUENCE);
+
+ /*
+ * Sessionid + seqid + slotid + max slotid + cache_this
+ */
+ dprintk("%s: sessionid=%u:%u:%u:%u seqid=%d slotid=%d "
+ "max_slotid=%d cache_this=%d\n",
+ __func__,
+ ((u32 *)session->sess_id.data)[0],
+ ((u32 *)session->sess_id.data)[1],
+ ((u32 *)session->sess_id.data)[2],
+ ((u32 *)session->sess_id.data)[3],
+ slot->seq_nr, args->sa_slotid,
+ tp->highest_used_slotid, args->sa_cache_this);
+ RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 16);
+ WRITEMEM(session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
+ WRITE32(slot->seq_nr);
+ WRITE32(args->sa_slotid);
+ WRITE32(tp->highest_used_slotid);
+ WRITE32(args->sa_cache_this);
+ hdr->nops++;
+ hdr->replen += decode_sequence_maxsz;
+#endif /* CONFIG_NFS_V4_1 */
+}
+
/*
* END OF "GENERIC" ENCODE ROUTINES.
*/
+static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args)
+{
+#if defined(CONFIG_NFS_V4_1)
+ if (args->sa_session)
+ return args->sa_session->clp->cl_minorversion;
+#endif /* CONFIG_NFS_V4_1 */
+ return 0;
+}
+
/*
* Encode an ACCESS request
*/
@@ -1351,11 +1701,12 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_access(&xdr, args->access, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1370,11 +1721,12 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
encode_lookup(&xdr, args->name, &hdr);
encode_getfh(&xdr, &hdr);
@@ -1390,11 +1742,12 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struc
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putrootfh(&xdr, &hdr);
encode_getfh(&xdr, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1409,11 +1762,12 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_remove(&xdr, &args->name, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1428,11 +1782,12 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->old_dir, &hdr);
encode_savefh(&xdr, &hdr);
encode_putfh(&xdr, args->new_dir, &hdr);
@@ -1451,11 +1806,12 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_savefh(&xdr, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
@@ -1474,11 +1830,12 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
encode_savefh(&xdr, &hdr);
encode_create(&xdr, args, &hdr);
@@ -1505,11 +1862,12 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
encode_nops(&hdr);
@@ -1523,11 +1881,12 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closea
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_close(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1542,11 +1901,12 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openarg
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_savefh(&xdr, &hdr);
encode_open(&xdr, args, &hdr);
@@ -1569,7 +1929,7 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_open_confirm(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1583,11 +1943,12 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_open(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1602,11 +1963,12 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct n
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_open_downgrade(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1621,11 +1983,12 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_ar
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_lock(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1639,11 +2002,12 @@ static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_lockt(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1657,11 +2021,12 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_locku(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1675,22 +2040,16 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
- unsigned int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_readlink(&xdr, args, req, &hdr);
- /* set up reply kvec
- * toplevel_status + taglen + rescount + OP_PUTFH + status
- * + OP_READLINK + status + string length = 8
- */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readlink_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
+ xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
args->pgbase, args->pglen);
encode_nops(&hdr);
return 0;
@@ -1703,25 +2062,19 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
- int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_readdir(&xdr, args, req, &hdr);
- /* set up reply kvec
- * toplevel_status + taglen + rescount + OP_PUTFH + status
- * + OP_READDIR + status + verifer(2) = 9
- */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readdir_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
+ xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
args->pgbase, args->count);
dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
- __func__, replen, args->pages,
+ __func__, hdr.replen << 2, args->pages,
args->pgbase, args->count);
encode_nops(&hdr);
return 0;
@@ -1732,24 +2085,18 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
*/
static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
{
- struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_read(&xdr, args, &hdr);
- /* set up reply kvec
- * toplevel status + taglen=0 + rescount + OP_PUTFH + status
- * + OP_READ + status + eof + datalen = 9
- */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen,
+ xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
args->pages, args->pgbase, args->count);
req->rq_rcv_buf.flags |= XDRBUF_READ;
encode_nops(&hdr);
@@ -1763,11 +2110,12 @@ static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_seta
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_setattr(&xdr, args, args->server, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1783,20 +2131,19 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
struct nfs_getaclargs *args)
{
struct xdr_stream xdr;
- struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- int replen;
+ uint32_t replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
+ replen = hdr.replen + nfs4_fattr_bitmap_maxsz + 1;
encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr);
- /* set up reply buffer: */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen,
+ xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
args->acl_pages, args->acl_pgbase, args->acl_len);
encode_nops(&hdr);
return 0;
@@ -1809,11 +2156,12 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writea
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_write(&xdr, args, &hdr);
req->rq_snd_buf.flags |= XDRBUF_WRITE;
@@ -1829,11 +2177,12 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_write
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_commit(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1848,11 +2197,12 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_fsinfo(&xdr, args->bitmask, &hdr);
encode_nops(&hdr);
@@ -1866,11 +2216,12 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getattr_one(&xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0],
&hdr);
@@ -1885,11 +2236,12 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getattr_two(&xdr, args->bitmask[0] & nfs4_statfs_bitmap[0],
args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr);
@@ -1900,16 +2252,18 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs
/*
* GETATTR_BITMAP request
*/
-static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struct nfs_fh *fhandle)
+static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_server_caps_arg *args)
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
- encode_putfh(&xdr, fhandle, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
+ encode_putfh(&xdr, args->fhandle, &hdr);
encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
FATTR4_WORD0_LINK_SUPPORT|
FATTR4_WORD0_SYMLINK_SUPPORT|
@@ -1929,7 +2283,7 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_renew(&xdr, clp, &hdr);
encode_nops(&hdr);
return 0;
@@ -1946,7 +2300,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_setclientid(&xdr, sc, &hdr);
encode_nops(&hdr);
return 0;
@@ -1964,7 +2318,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 };
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_setclientid_confirm(&xdr, clp, &hdr);
encode_putrootfh(&xdr, &hdr);
encode_fsinfo(&xdr, lease_bitmap, &hdr);
@@ -1979,11 +2333,12 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struc
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fhandle, &hdr);
encode_delegreturn(&xdr, args->stateid, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1998,28 +2353,119 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
- int replen;
+ uint32_t replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
encode_lookup(&xdr, args->name, &hdr);
+ replen = hdr.replen; /* get the attribute into args->page */
encode_fs_locations(&xdr, args->bitmask, &hdr);
- /* set up reply
- * toplevel_status + OP_PUTFH + status
- * + OP_LOOKUP + status + OP_GETATTR + status = 7
- */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page,
+ xdr_inline_pages(&req->rq_rcv_buf, replen << 2, &args->page,
0, PAGE_SIZE);
encode_nops(&hdr);
return 0;
}
+#if defined(CONFIG_NFS_V4_1)
+/*
+ * EXCHANGE_ID request
+ */
+static int nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, uint32_t *p,
+ struct nfs41_exchange_id_args *args)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr = {
+ .minorversion = args->client->cl_minorversion,
+ };
+
+ xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_exchange_id(&xdr, args, &hdr);
+ encode_nops(&hdr);
+ return 0;
+}
+
+/*
+ * a CREATE_SESSION request
+ */
+static int nfs4_xdr_enc_create_session(struct rpc_rqst *req, uint32_t *p,
+ struct nfs41_create_session_args *args)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr = {
+ .minorversion = args->client->cl_minorversion,
+ };
+
+ xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_create_session(&xdr, args, &hdr);
+ encode_nops(&hdr);
+ return 0;
+}
+
+/*
+ * a DESTROY_SESSION request
+ */
+static int nfs4_xdr_enc_destroy_session(struct rpc_rqst *req, uint32_t *p,
+ struct nfs4_session *session)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr = {
+ .minorversion = session->clp->cl_minorversion,
+ };
+
+ xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_destroy_session(&xdr, session, &hdr);
+ encode_nops(&hdr);
+ return 0;
+}
+
+/*
+ * a SEQUENCE request
+ */
+static int nfs4_xdr_enc_sequence(struct rpc_rqst *req, uint32_t *p,
+ struct nfs4_sequence_args *args)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr = {
+ .minorversion = nfs4_xdr_minorversion(args),
+ };
+
+ xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, args, &hdr);
+ encode_nops(&hdr);
+ return 0;
+}
+
+/*
+ * a GET_LEASE_TIME request
+ */
+static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p,
+ struct nfs4_get_lease_time_args *args)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr = {
+ .minorversion = nfs4_xdr_minorversion(&args->la_seq_args),
+ };
+ const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 };
+
+ xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->la_seq_args, &hdr);
+ encode_putrootfh(&xdr, &hdr);
+ encode_fsinfo(&xdr, lease_bitmap, &hdr);
+ encode_nops(&hdr);
+ return 0;
+}
+#endif /* CONFIG_NFS_V4_1 */
+
/*
* START OF "GENERIC" DECODE ROUTINES.
* These may look a little ugly since they are imported from a "generic"
@@ -3657,7 +4103,7 @@ decode_savefh(struct xdr_stream *xdr)
return decode_op_hdr(xdr, OP_SAVEFH);
}
-static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res)
+static int decode_setattr(struct xdr_stream *xdr)
{
__be32 *p;
uint32_t bmlen;
@@ -3735,6 +4181,175 @@ static int decode_delegreturn(struct xdr_stream *xdr)
return decode_op_hdr(xdr, OP_DELEGRETURN);
}
+#if defined(CONFIG_NFS_V4_1)
+static int decode_exchange_id(struct xdr_stream *xdr,
+ struct nfs41_exchange_id_res *res)
+{
+ uint32_t *p;
+ int status, dummy;
+ struct nfs_client *clp = res->client;
+
+ status = decode_op_hdr(xdr, OP_EXCHANGE_ID);
+ if (status)
+ return status;
+
+ READ_BUF(8);
+ READ64(clp->cl_ex_clid);
+ READ_BUF(12);
+ READ32(clp->cl_seqid);
+ READ32(clp->cl_exchange_flags);
+
+ /* We ask for SP4_NONE */
+ READ32(dummy);
+ if (dummy != SP4_NONE)
+ return -EIO;
+
+ /* minor_id */
+ READ_BUF(8);
+ READ64(res->server_owner.minor_id);
+
+ /* Major id */
+ READ_BUF(4);
+ READ32(res->server_owner.major_id_sz);
+ READ_BUF(res->server_owner.major_id_sz);
+ COPYMEM(res->server_owner.major_id, res->server_owner.major_id_sz);
+
+ /* server_scope */
+ READ_BUF(4);
+ READ32(res->server_scope.server_scope_sz);
+ READ_BUF(res->server_scope.server_scope_sz);
+ COPYMEM(res->server_scope.server_scope,
+ res->server_scope.server_scope_sz);
+ /* Throw away Implementation id array */
+ READ_BUF(4);
+ READ32(dummy);
+ p += XDR_QUADLEN(dummy);
+
+ return 0;
+}
+
+static int decode_create_session(struct xdr_stream *xdr,
+ struct nfs41_create_session_res *res)
+{
+ uint32_t *p;
+ int status;
+ u32 nr_attrs;
+ struct nfs_client *clp = res->client;
+ struct nfs4_session *session = clp->cl_session;
+
+ status = decode_op_hdr(xdr, OP_CREATE_SESSION);
+
+ if (status)
+ return status;
+
+ /* sessionid */
+ READ_BUF(NFS4_MAX_SESSIONID_LEN);
+ COPYMEM(&session->sess_id, NFS4_MAX_SESSIONID_LEN);
+
+ /* seqid, flags */
+ READ_BUF(8);
+ READ32(clp->cl_seqid);
+ READ32(session->flags);
+
+ /* Channel attributes */
+ /* fore channel */
+ READ_BUF(24);
+ READ32(session->fc_attrs.headerpadsz);
+ READ32(session->fc_attrs.max_rqst_sz);
+ READ32(session->fc_attrs.max_resp_sz);
+ READ32(session->fc_attrs.max_resp_sz_cached);
+ READ32(session->fc_attrs.max_ops);
+ READ32(session->fc_attrs.max_reqs);
+ READ_BUF(4);
+ READ32(nr_attrs);
+ if (nr_attrs == 1) {
+ READ_BUF(4);
+ p++; /* skip rdma_attrs */
+ }
+
+ /* back channel */
+ READ_BUF(24);
+ READ32(session->bc_attrs.headerpadsz);
+ READ32(session->bc_attrs.max_rqst_sz);
+ READ32(session->bc_attrs.max_resp_sz);
+ READ32(session->bc_attrs.max_resp_sz_cached);
+ READ32(session->bc_attrs.max_ops);
+ READ32(session->bc_attrs.max_reqs);
+ READ_BUF(4);
+ READ32(nr_attrs);
+ if (nr_attrs == 1) {
+ READ_BUF(4);
+ p++; /* skip rdma_attrs */
+ }
+
+ return 0;
+}
+
+static int decode_destroy_session(struct xdr_stream *xdr, void *dummy)
+{
+ return decode_op_hdr(xdr, OP_DESTROY_SESSION);
+}
+#endif /* CONFIG_NFS_V4_1 */
+
+static int decode_sequence(struct xdr_stream *xdr,
+ struct nfs4_sequence_res *res,
+ struct rpc_rqst *rqstp)
+{
+#if defined(CONFIG_NFS_V4_1)
+ struct nfs4_slot *slot;
+ struct nfs4_sessionid id;
+ u32 dummy;
+ int status;
+ __be32 *p;
+
+ if (!res->sr_session)
+ return 0;
+
+ status = decode_op_hdr(xdr, OP_SEQUENCE);
+ if (status)
+ goto out_err;
+
+ /*
+ * If the server returns different values for sessionID, slotID or
+ * sequence number, the server is looney tunes.
+ */
+ status = -ESERVERFAULT;
+
+ slot = &res->sr_session->fc_slot_table.slots[res->sr_slotid];
+ READ_BUF(NFS4_MAX_SESSIONID_LEN + 20);
+ COPYMEM(id.data, NFS4_MAX_SESSIONID_LEN);
+ if (memcmp(id.data, res->sr_session->sess_id.data,
+ NFS4_MAX_SESSIONID_LEN)) {
+ dprintk("%s Invalid session id\n", __func__);
+ goto out_err;
+ }
+ /* seqid */
+ READ32(dummy);
+ if (dummy != slot->seq_nr) {
+ dprintk("%s Invalid sequence number\n", __func__);
+ goto out_err;
+ }
+ /* slot id */
+ READ32(dummy);
+ if (dummy != res->sr_slotid) {
+ dprintk("%s Invalid slot id\n", __func__);
+ goto out_err;
+ }
+ /* highest slot id - currently not processed */
+ READ32(dummy);
+ /* target highest slot id - currently not processed */
+ READ32(dummy);
+ /* result flags - currently not processed */
+ READ32(dummy);
+ status = 0;
+out_err:
+ res->sr_status = status;
+ return status;
+#else /* CONFIG_NFS_V4_1 */
+ return 0;
+#endif /* CONFIG_NFS_V4_1 */
+}
+
/*
* END OF "GENERIC" DECODE ROUTINES.
*/
@@ -3752,6 +4367,9 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -3773,7 +4391,11 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
status = decode_putfh(&xdr);
if (status != 0)
@@ -3796,7 +4418,11 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lo
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -3819,7 +4445,11 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nf
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putrootfh(&xdr)) != 0)
goto out;
@@ -3839,7 +4469,11 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -3860,7 +4494,11 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -3890,7 +4528,11 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -3923,7 +4565,11 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_cr
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -3963,6 +4609,9 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -3979,12 +4628,13 @@ nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
int status;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
status = encode_setacl(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -3995,7 +4645,8 @@ nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args
* Decode SETACL response
*/
static int
-nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res)
+nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p,
+ struct nfs_setaclres *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4005,10 +4656,13 @@ nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res)
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
- status = decode_setattr(&xdr, res);
+ status = decode_setattr(&xdr);
out:
return status;
}
@@ -4017,7 +4671,8 @@ out:
* Decode GETACL response
*/
static int
-nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len)
+nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p,
+ struct nfs_getaclres *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4027,10 +4682,13 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len)
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
- status = decode_getacl(&xdr, rqstp, acl_len);
+ status = decode_getacl(&xdr, rqstp, &res->acl_len);
out:
return status;
@@ -4049,6 +4707,9 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4079,6 +4740,9 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openr
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4133,6 +4797,9 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nf
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4157,10 +4824,13 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_se
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
- status = decode_setattr(&xdr, res);
+ status = decode_setattr(&xdr);
if (status)
goto out;
decode_getfattr(&xdr, res->fattr, res->server);
@@ -4181,6 +4851,9 @@ static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4202,6 +4875,9 @@ static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4223,6 +4899,9 @@ static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4234,7 +4913,8 @@ out:
/*
* Decode READLINK response
*/
-static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res)
+static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p,
+ struct nfs4_readlink_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4244,6 +4924,9 @@ static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res)
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4265,6 +4948,9 @@ static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_r
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4286,6 +4972,9 @@ static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readr
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4309,6 +4998,9 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writ
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4335,6 +5027,9 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_wri
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4349,7 +5044,8 @@ out:
/*
* FSINFO request
*/
-static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo)
+static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_fsinfo_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4358,16 +5054,19 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinf
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
if (!status)
+ status = decode_sequence(&xdr, &res->seq_res, req);
+ if (!status)
status = decode_putfh(&xdr);
if (!status)
- status = decode_fsinfo(&xdr, fsinfo);
+ status = decode_fsinfo(&xdr, res->fsinfo);
return status;
}
/*
* PATHCONF request
*/
-static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *pathconf)
+static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_pathconf_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4376,16 +5075,19 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pat
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
if (!status)
+ status = decode_sequence(&xdr, &res->seq_res, req);
+ if (!status)
status = decode_putfh(&xdr);
if (!status)
- status = decode_pathconf(&xdr, pathconf);
+ status = decode_pathconf(&xdr, res->pathconf);
return status;
}
/*
* STATFS request
*/
-static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *fsstat)
+static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_statfs_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4394,9 +5096,11 @@ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fssta
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
if (!status)
+ status = decode_sequence(&xdr, &res->seq_res, req);
+ if (!status)
status = decode_putfh(&xdr);
if (!status)
- status = decode_statfs(&xdr, fsstat);
+ status = decode_statfs(&xdr, res->fsstat);
return status;
}
@@ -4410,7 +5114,11 @@ static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4
int status;
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, req);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -4483,7 +5191,10 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
- if (status != 0)
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
status = decode_putfh(&xdr);
if (status != 0)
@@ -4497,7 +5208,8 @@ out:
/*
* FS_LOCATIONS request
*/
-static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations *res)
+static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_fs_locations_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4505,18 +5217,113 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
- if (status != 0)
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, req);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
if ((status = decode_lookup(&xdr)) != 0)
goto out;
xdr_enter_page(&xdr, PAGE_SIZE);
- status = decode_getfattr(&xdr, &res->fattr, res->server);
+ status = decode_getfattr(&xdr, &res->fs_locations->fattr,
+ res->fs_locations->server);
out:
return status;
}
+#if defined(CONFIG_NFS_V4_1)
+/*
+ * EXCHANGE_ID request
+ */
+static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, uint32_t *p,
+ void *res)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr;
+ int status;
+
+ xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (!status)
+ status = decode_exchange_id(&xdr, res);
+ return status;
+}
+
+/*
+ * a CREATE_SESSION request
+ */
+static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, uint32_t *p,
+ struct nfs41_create_session_res *res)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr;
+ int status;
+
+ xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (!status)
+ status = decode_create_session(&xdr, res);
+ return status;
+}
+
+/*
+ * a DESTROY_SESSION request
+ */
+static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp, uint32_t *p,
+ void *dummy)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr;
+ int status;
+
+ xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (!status)
+ status = decode_destroy_session(&xdr, dummy);
+ return status;
+}
+
+/*
+ * a SEQUENCE request
+ */
+static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, uint32_t *p,
+ struct nfs4_sequence_res *res)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr;
+ int status;
+
+ xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (!status)
+ status = decode_sequence(&xdr, res, rqstp);
+ return status;
+}
+
+/*
+ * a GET_LEASE_TIME request
+ */
+static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p,
+ struct nfs4_get_lease_time_res *res)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr;
+ int status;
+
+ xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (!status)
+ status = decode_sequence(&xdr, &res->lr_seq_res, rqstp);
+ if (!status)
+ status = decode_putrootfh(&xdr);
+ if (!status)
+ status = decode_fsinfo(&xdr, res->lr_fsinfo);
+ return status;
+}
+#endif /* CONFIG_NFS_V4_1 */
+
__be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
{
uint32_t bitmap[2] = {0};
@@ -4686,6 +5493,13 @@ struct rpc_procinfo nfs4_procedures[] = {
PROC(GETACL, enc_getacl, dec_getacl),
PROC(SETACL, enc_setacl, dec_setacl),
PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations),
+#if defined(CONFIG_NFS_V4_1)
+ PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id),
+ PROC(CREATE_SESSION, enc_create_session, dec_create_session),
+ PROC(DESTROY_SESSION, enc_destroy_session, dec_destroy_session),
+ PROC(SEQUENCE, enc_sequence, dec_sequence),
+ PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time),
+#endif /* CONFIG_NFS_V4_1 */
};
struct rpc_version nfs_version4 = {
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 4ace3c50a8eb..96c4ebfa46f4 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -22,6 +22,7 @@
#include <asm/system.h>
+#include "nfs4_fs.h"
#include "internal.h"
#include "iostat.h"
#include "fscache.h"
@@ -46,6 +47,7 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->pages);
p->npages = pagecount;
+ p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
if (pagecount <= ARRAY_SIZE(p->page_array))
p->pagevec = p->page_array;
else {
@@ -357,19 +359,25 @@ static void nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data
struct nfs_readres *resp = &data->res;
if (resp->eof || resp->count == argp->count)
- return;
+ goto out;
/* This is a short read! */
nfs_inc_stats(data->inode, NFSIOS_SHORTREAD);
/* Has the server at least made some progress? */
if (resp->count == 0)
- return;
+ goto out;
/* Yes, so retry the read at the end of the data */
argp->offset += resp->count;
argp->pgbase += resp->count;
argp->count -= resp->count;
- rpc_restart_call(task);
+ nfs4_restart_rpc(task, NFS_SERVER(data->inode)->nfs_client);
+ return;
+out:
+ nfs4_sequence_free_slot(NFS_SERVER(data->inode)->nfs_client,
+ &data->res.seq_res);
+ return;
+
}
/*
@@ -406,7 +414,23 @@ static void nfs_readpage_release_partial(void *calldata)
nfs_readdata_release(calldata);
}
+#if defined(CONFIG_NFS_V4_1)
+void nfs_read_prepare(struct rpc_task *task, void *calldata)
+{
+ struct nfs_read_data *data = calldata;
+
+ if (nfs4_setup_sequence(NFS_SERVER(data->inode)->nfs_client,
+ &data->args.seq_args, &data->res.seq_res,
+ 0, task))
+ return;
+ rpc_call_start(task);
+}
+#endif /* CONFIG_NFS_V4_1 */
+
static const struct rpc_call_ops nfs_read_partial_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_read_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_readpage_result_partial,
.rpc_release = nfs_readpage_release_partial,
};
@@ -470,6 +494,9 @@ static void nfs_readpage_release_full(void *calldata)
}
static const struct rpc_call_ops nfs_read_full_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_read_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_readpage_result_full,
.rpc_release = nfs_readpage_release_full,
};
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 6717200923fe..73db6f8c145a 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -90,6 +90,7 @@ enum {
Opt_mountport,
Opt_mountvers,
Opt_nfsvers,
+ Opt_minorversion,
/* Mount options that take string arguments */
Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
@@ -155,6 +156,7 @@ static const match_table_t nfs_mount_option_tokens = {
{ Opt_mountvers, "mountvers=%u" },
{ Opt_nfsvers, "nfsvers=%u" },
{ Opt_nfsvers, "vers=%u" },
+ { Opt_minorversion, "minorversion=%u" },
{ Opt_sec, "sec=%s" },
{ Opt_proto, "proto=%s" },
@@ -683,9 +685,12 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
*/
static void nfs_umount_begin(struct super_block *sb)
{
- struct nfs_server *server = NFS_SB(sb);
+ struct nfs_server *server;
struct rpc_clnt *rpc;
+ lock_kernel();
+
+ server = NFS_SB(sb);
/* -EIO all pending I/O */
rpc = server->client_acl;
if (!IS_ERR(rpc))
@@ -693,6 +698,8 @@ static void nfs_umount_begin(struct super_block *sb)
rpc = server->client;
if (!IS_ERR(rpc))
rpc_killall_tasks(rpc);
+
+ unlock_kernel();
}
/*
@@ -1206,6 +1213,13 @@ static int nfs_parse_mount_options(char *raw,
nfs_parse_invalid_value("nfsvers");
}
break;
+ case Opt_minorversion:
+ if (match_int(args, &option))
+ return 0;
+ if (option < 0 || option > NFS4_MAX_MINOR_VERSION)
+ return 0;
+ mnt->minorversion = option;
+ break;
/*
* options that take text values
@@ -2106,8 +2120,7 @@ out_err_nosb:
error_splat_root:
dput(mntroot);
error_splat_super:
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
goto out;
}
@@ -2203,8 +2216,7 @@ out_err_noserver:
return error;
error_splat_super:
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
return error;
}
@@ -2258,6 +2270,7 @@ static int nfs4_validate_mount_data(void *options,
args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */
args->auth_flavors[0] = RPC_AUTH_UNIX;
args->auth_flavor_len = 0;
+ args->minorversion = 0;
switch (data->version) {
case 1:
@@ -2464,8 +2477,7 @@ out_free:
error_splat_root:
dput(mntroot);
error_splat_super:
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
goto out;
}
@@ -2473,12 +2485,14 @@ static void nfs4_kill_super(struct super_block *sb)
{
struct nfs_server *server = NFS_SB(sb);
+ dprintk("--> %s\n", __func__);
nfs_super_return_all_delegations(sb);
kill_anon_super(sb);
nfs4_renewd_prepare_shutdown(server);
nfs_fscache_release_super_cookie(sb);
nfs_free_server(server);
+ dprintk("<-- %s\n", __func__);
}
/*
@@ -2559,8 +2573,7 @@ out_err_noserver:
return error;
error_splat_super:
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
return error;
}
@@ -2644,8 +2657,7 @@ out_err_noserver:
return error;
error_splat_super:
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
return error;
}
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index ecc295347775..1064c91ae810 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -15,6 +15,7 @@
#include <linux/wait.h>
#include "internal.h"
+#include "nfs4_fs.h"
struct nfs_unlinkdata {
struct hlist_node list;
@@ -82,7 +83,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
struct inode *dir = data->dir;
if (!NFS_PROTO(dir)->unlink_done(task, dir))
- rpc_restart_call(task);
+ nfs4_restart_rpc(task, NFS_SERVER(dir)->nfs_client);
}
/**
@@ -102,9 +103,25 @@ static void nfs_async_unlink_release(void *calldata)
nfs_sb_deactive(sb);
}
+#if defined(CONFIG_NFS_V4_1)
+void nfs_unlink_prepare(struct rpc_task *task, void *calldata)
+{
+ struct nfs_unlinkdata *data = calldata;
+ struct nfs_server *server = NFS_SERVER(data->dir);
+
+ if (nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
+ &data->res.seq_res, 1, task))
+ return;
+ rpc_call_start(task);
+}
+#endif /* CONFIG_NFS_V4_1 */
+
static const struct rpc_call_ops nfs_unlink_ops = {
.rpc_call_done = nfs_async_unlink_done,
.rpc_release = nfs_async_unlink_release,
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_unlink_prepare,
+#endif /* CONFIG_NFS_V4_1 */
};
static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct nfs_unlinkdata *data)
@@ -241,6 +258,7 @@ nfs_async_unlink(struct inode *dir, struct dentry *dentry)
status = PTR_ERR(data->cred);
goto out_free;
}
+ data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
status = -EBUSY;
spin_lock(&dentry->d_lock);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index e560a78995a3..ce728829f79a 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -25,6 +25,7 @@
#include "delegation.h"
#include "internal.h"
#include "iostat.h"
+#include "nfs4_fs.h"
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
@@ -52,6 +53,7 @@ struct nfs_write_data *nfs_commitdata_alloc(void)
if (p) {
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->pages);
+ p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
}
return p;
}
@@ -71,6 +73,7 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->pages);
p->npages = pagecount;
+ p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
if (pagecount <= ARRAY_SIZE(p->page_array))
p->pagevec = p->page_array;
else {
@@ -1048,7 +1051,23 @@ out:
nfs_writedata_release(calldata);
}
+#if defined(CONFIG_NFS_V4_1)
+void nfs_write_prepare(struct rpc_task *task, void *calldata)
+{
+ struct nfs_write_data *data = calldata;
+ struct nfs_client *clp = (NFS_SERVER(data->inode))->nfs_client;
+
+ if (nfs4_setup_sequence(clp, &data->args.seq_args,
+ &data->res.seq_res, 1, task))
+ return;
+ rpc_call_start(task);
+}
+#endif /* CONFIG_NFS_V4_1 */
+
static const struct rpc_call_ops nfs_write_partial_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_write_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_writeback_done_partial,
.rpc_release = nfs_writeback_release_partial,
};
@@ -1111,6 +1130,9 @@ remove_request:
}
static const struct rpc_call_ops nfs_write_full_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_write_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_writeback_done_full,
.rpc_release = nfs_writeback_release_full,
};
@@ -1123,6 +1145,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
{
struct nfs_writeargs *argp = &data->args;
struct nfs_writeres *resp = &data->res;
+ struct nfs_server *server = NFS_SERVER(data->inode);
int status;
dprintk("NFS: %5u nfs_writeback_done (status %d)\n",
@@ -1155,7 +1178,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
if (time_before(complain, jiffies)) {
dprintk("NFS: faulty NFS server %s:"
" (committed = %d) != (stable = %d)\n",
- NFS_SERVER(data->inode)->nfs_client->cl_hostname,
+ server->nfs_client->cl_hostname,
resp->verf->committed, argp->stable);
complain = jiffies + 300 * HZ;
}
@@ -1181,7 +1204,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
*/
argp->stable = NFS_FILE_SYNC;
}
- rpc_restart_call(task);
+ nfs4_restart_rpc(task, server->nfs_client);
return -EAGAIN;
}
if (time_before(complain, jiffies)) {
@@ -1193,6 +1216,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
/* Can't do anything about it except throw an error. */
task->tk_status = -EIO;
}
+ nfs4_sequence_free_slot(server->nfs_client, &data->res.seq_res);
return 0;
}
@@ -1349,6 +1373,9 @@ static void nfs_commit_release(void *calldata)
}
static const struct rpc_call_ops nfs_commit_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_write_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_commit_done,
.rpc_release = nfs_commit_release,
};
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 5839b229cd0e..b92a27629fb7 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -464,16 +464,11 @@ static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
if (err)
return err;
/*
- * Just a quick sanity check; we could also try to check
- * whether this pseudoflavor is supported, but at worst
- * an unsupported pseudoflavor on the export would just
- * be a pseudoflavor that won't match the flavor of any
- * authenticated request. The administrator will
- * probably discover the problem when someone fails to
- * authenticate.
+ * XXX: It would be nice to also check whether this
+ * pseudoflavor is supported, so we can discover the
+ * problem at export time instead of when a client fails
+ * to authenticate.
*/
- if (f->pseudoflavor < 0)
- return -EINVAL;
err = get_int(mesg, &f->flags);
if (err)
return err;
@@ -847,9 +842,8 @@ exp_get_fsid_key(svc_client *clp, int fsid)
return exp_find_key(clp, FSID_NUM, fsidv, NULL);
}
-static 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, const struct path *path,
+ struct cache_req *reqp)
{
struct svc_export *exp, key;
int err;
@@ -858,8 +852,7 @@ static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt,
return ERR_PTR(-ENOENT);
key.ex_client = clp;
- key.ex_path.mnt = mnt;
- key.ex_path.dentry = dentry;
+ key.ex_path = *path;
exp = svc_export_lookup(&key);
if (exp == NULL)
@@ -873,24 +866,19 @@ static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt,
/*
* Find the export entry for a given dentry.
*/
-static 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 path *path)
{
- svc_export *exp;
-
- dget(dentry);
- exp = exp_get_by_name(clp, mnt, dentry, reqp);
-
- while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(dentry)) {
- struct dentry *parent;
-
- parent = dget_parent(dentry);
- dput(dentry);
- dentry = parent;
- exp = exp_get_by_name(clp, mnt, dentry, reqp);
+ struct dentry *saved = dget(path->dentry);
+ svc_export *exp = exp_get_by_name(clp, path, NULL);
+
+ while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
+ struct dentry *parent = dget_parent(path->dentry);
+ dput(path->dentry);
+ path->dentry = parent;
+ exp = exp_get_by_name(clp, path, NULL);
}
- dput(dentry);
+ dput(path->dentry);
+ path->dentry = saved;
return exp;
}
@@ -1018,7 +1006,7 @@ exp_export(struct nfsctl_export *nxp)
goto out_put_clp;
err = -EINVAL;
- exp = exp_get_by_name(clp, path.mnt, path.dentry, NULL);
+ exp = exp_get_by_name(clp, &path, NULL);
memset(&new, 0, sizeof(new));
@@ -1135,7 +1123,7 @@ exp_unexport(struct nfsctl_export *nxp)
goto out_domain;
err = -EINVAL;
- exp = exp_get_by_name(dom, path.mnt, path.dentry, NULL);
+ exp = exp_get_by_name(dom, &path, NULL);
path_put(&path);
if (IS_ERR(exp))
goto out_domain;
@@ -1177,7 +1165,7 @@ exp_rootfh(svc_client *clp, char *name, struct knfsd_fh *f, int maxsize)
dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
name, path.dentry, clp->name,
inode->i_sb->s_id, inode->i_ino);
- exp = exp_parent(clp, path.mnt, path.dentry, NULL);
+ exp = exp_parent(clp, &path);
if (IS_ERR(exp)) {
err = PTR_ERR(exp);
goto out;
@@ -1207,7 +1195,7 @@ static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type,
if (IS_ERR(ek))
return ERR_CAST(ek);
- exp = exp_get_by_name(clp, ek->ek_path.mnt, ek->ek_path.dentry, reqp);
+ exp = exp_get_by_name(clp, &ek->ek_path, reqp);
cache_put(&ek->h, &svc_expkey_cache);
if (IS_ERR(exp))
@@ -1247,8 +1235,7 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
* use exp_get_by_name() or exp_find().
*/
struct svc_export *
-rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt,
- struct dentry *dentry)
+rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
{
struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
@@ -1256,8 +1243,7 @@ rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt,
goto gss;
/* First try the auth_unix client: */
- exp = exp_get_by_name(rqstp->rq_client, mnt, dentry,
- &rqstp->rq_chandle);
+ exp = exp_get_by_name(rqstp->rq_client, path, &rqstp->rq_chandle);
if (PTR_ERR(exp) == -ENOENT)
goto gss;
if (IS_ERR(exp))
@@ -1269,8 +1255,7 @@ gss:
/* Otherwise, try falling back on gss client */
if (rqstp->rq_gssclient == NULL)
return exp;
- gssexp = exp_get_by_name(rqstp->rq_gssclient, mnt, dentry,
- &rqstp->rq_chandle);
+ gssexp = exp_get_by_name(rqstp->rq_gssclient, path, &rqstp->rq_chandle);
if (PTR_ERR(gssexp) == -ENOENT)
return exp;
if (!IS_ERR(exp))
@@ -1309,23 +1294,19 @@ gss:
}
struct svc_export *
-rqst_exp_parent(struct svc_rqst *rqstp, struct vfsmount *mnt,
- struct dentry *dentry)
+rqst_exp_parent(struct svc_rqst *rqstp, struct path *path)
{
- struct svc_export *exp;
-
- dget(dentry);
- exp = rqst_exp_get_by_name(rqstp, mnt, dentry);
-
- while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(dentry)) {
- struct dentry *parent;
-
- parent = dget_parent(dentry);
- dput(dentry);
- dentry = parent;
- exp = rqst_exp_get_by_name(rqstp, mnt, dentry);
+ struct dentry *saved = dget(path->dentry);
+ struct svc_export *exp = rqst_exp_get_by_name(rqstp, path);
+
+ while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
+ struct dentry *parent = dget_parent(path->dentry);
+ dput(path->dentry);
+ path->dentry = parent;
+ exp = rqst_exp_get_by_name(rqstp, path);
}
- dput(dentry);
+ dput(path->dentry);
+ path->dentry = saved;
return exp;
}
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 17d0dd997204..01d4ec1c88e0 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -272,6 +272,7 @@ void fill_post_wcc(struct svc_fh *fhp)
err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry,
&fhp->fh_post_attr);
+ fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version;
if (err)
fhp->fh_post_saved = 0;
else
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 290289bd44f7..f4fab69a8c30 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -215,18 +215,18 @@ encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
}
static int
-encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec)
+encode_cb_recall(struct xdr_stream *xdr, struct nfs4_delegation *dp)
{
__be32 *p;
- int len = cb_rec->cbr_fh.fh_size;
+ int len = dp->dl_fh.fh_size;
- RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len);
+ RESERVE_SPACE(12+sizeof(dp->dl_stateid) + len);
WRITE32(OP_CB_RECALL);
- WRITE32(cb_rec->cbr_stateid.si_generation);
- WRITEMEM(&cb_rec->cbr_stateid.si_opaque, sizeof(stateid_opaque_t));
- WRITE32(cb_rec->cbr_trunc);
+ WRITE32(dp->dl_stateid.si_generation);
+ WRITEMEM(&dp->dl_stateid.si_opaque, sizeof(stateid_opaque_t));
+ WRITE32(0); /* truncate optimization not implemented */
WRITE32(len);
- WRITEMEM(&cb_rec->cbr_fh.fh_base, len);
+ WRITEMEM(&dp->dl_fh.fh_base, len);
return 0;
}
@@ -241,11 +241,11 @@ nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p)
}
static int
-nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, struct nfs4_cb_recall *args)
+nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, struct nfs4_delegation *args)
{
struct xdr_stream xdr;
struct nfs4_cb_compound_hdr hdr = {
- .ident = args->cbr_ident,
+ .ident = args->dl_ident,
.nops = 1,
};
@@ -358,18 +358,21 @@ static struct rpc_program cb_program = {
.pipe_dir_name = "/nfsd4_cb",
};
+static int max_cb_time(void)
+{
+ return max(NFSD_LEASE_TIME/10, (time_t)1) * HZ;
+}
+
/* Reference counting, callback cleanup, etc., all look racy as heck.
* And why is cb_set an atomic? */
-static struct rpc_clnt *setup_callback_client(struct nfs4_client *clp)
+int setup_callback_client(struct nfs4_client *clp)
{
struct sockaddr_in addr;
- struct nfs4_callback *cb = &clp->cl_callback;
+ struct nfs4_cb_conn *cb = &clp->cl_cb_conn;
struct rpc_timeout timeparms = {
- .to_initval = (NFSD_LEASE_TIME/4) * HZ,
- .to_retries = 5,
- .to_maxval = (NFSD_LEASE_TIME/2) * HZ,
- .to_exponential = 1,
+ .to_initval = max_cb_time(),
+ .to_retries = 0,
};
struct rpc_create_args args = {
.protocol = IPPROTO_TCP,
@@ -386,7 +389,7 @@ static struct rpc_clnt *setup_callback_client(struct nfs4_client *clp)
struct rpc_clnt *client;
if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5))
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
/* Initialize address */
memset(&addr, 0, sizeof(addr));
@@ -396,48 +399,77 @@ static struct rpc_clnt *setup_callback_client(struct nfs4_client *clp)
/* Create RPC client */
client = rpc_create(&args);
- if (IS_ERR(client))
+ if (IS_ERR(client)) {
dprintk("NFSD: couldn't create callback client: %ld\n",
PTR_ERR(client));
- return client;
+ return PTR_ERR(client);
+ }
+ cb->cb_client = client;
+ return 0;
+
+}
+
+static void warn_no_callback_path(struct nfs4_client *clp, int reason)
+{
+ dprintk("NFSD: warning: no callback path to client %.*s: error %d\n",
+ (int)clp->cl_name.len, clp->cl_name.data, reason);
+}
+
+static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
+{
+ struct nfs4_client *clp = calldata;
+
+ if (task->tk_status)
+ warn_no_callback_path(clp, task->tk_status);
+ else
+ atomic_set(&clp->cl_cb_conn.cb_set, 1);
+ put_nfs4_client(clp);
+}
+
+static const struct rpc_call_ops nfsd4_cb_probe_ops = {
+ .rpc_call_done = nfsd4_cb_probe_done,
+};
+static struct rpc_cred *lookup_cb_cred(struct nfs4_cb_conn *cb)
+{
+ struct auth_cred acred = {
+ .machine_cred = 1
+ };
+
+ /*
+ * Note in the gss case this doesn't actually have to wait for a
+ * gss upcall (or any calls to the client); this just creates a
+ * non-uptodate cred which the rpc state machine will fill in with
+ * a refresh_upcall later.
+ */
+ return rpcauth_lookup_credcache(cb->cb_client->cl_auth, &acred,
+ RPCAUTH_LOOKUP_NEW);
}
-static int do_probe_callback(void *data)
+void do_probe_callback(struct nfs4_client *clp)
{
- struct nfs4_client *clp = data;
- struct nfs4_callback *cb = &clp->cl_callback;
+ struct nfs4_cb_conn *cb = &clp->cl_cb_conn;
struct rpc_message msg = {
.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
.rpc_argp = clp,
};
- struct rpc_clnt *client;
+ struct rpc_cred *cred;
int status;
- client = setup_callback_client(clp);
- if (IS_ERR(client)) {
- status = PTR_ERR(client);
- dprintk("NFSD: couldn't create callback client: %d\n",
- status);
- goto out_err;
+ cred = lookup_cb_cred(cb);
+ if (IS_ERR(cred)) {
+ status = PTR_ERR(cred);
+ goto out;
+ }
+ cb->cb_cred = cred;
+ msg.rpc_cred = cb->cb_cred;
+ status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_SOFT,
+ &nfsd4_cb_probe_ops, (void *)clp);
+out:
+ if (status) {
+ warn_no_callback_path(clp, status);
+ put_nfs4_client(clp);
}
-
- status = rpc_call_sync(client, &msg, RPC_TASK_SOFT);
-
- if (status)
- goto out_release_client;
-
- cb->cb_client = client;
- atomic_set(&cb->cb_set, 1);
- put_nfs4_client(clp);
- return 0;
-out_release_client:
- rpc_shutdown_client(client);
-out_err:
- dprintk("NFSD: warning: no callback path to client %.*s: error %d\n",
- (int)clp->cl_name.len, clp->cl_name.data, status);
- put_nfs4_client(clp);
- return 0;
}
/*
@@ -446,21 +478,65 @@ out_err:
void
nfsd4_probe_callback(struct nfs4_client *clp)
{
- struct task_struct *t;
+ int status;
+
+ BUG_ON(atomic_read(&clp->cl_cb_conn.cb_set));
- BUG_ON(atomic_read(&clp->cl_callback.cb_set));
+ status = setup_callback_client(clp);
+ if (status) {
+ warn_no_callback_path(clp, status);
+ return;
+ }
/* the task holds a reference to the nfs4_client struct */
atomic_inc(&clp->cl_count);
- t = kthread_run(do_probe_callback, clp, "nfs4_cb_probe");
+ do_probe_callback(clp);
+}
- if (IS_ERR(t))
- atomic_dec(&clp->cl_count);
+static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
+{
+ struct nfs4_delegation *dp = calldata;
+ struct nfs4_client *clp = dp->dl_client;
- return;
+ switch (task->tk_status) {
+ case -EIO:
+ /* Network partition? */
+ atomic_set(&clp->cl_cb_conn.cb_set, 0);
+ warn_no_callback_path(clp, task->tk_status);
+ case -EBADHANDLE:
+ case -NFS4ERR_BAD_STATEID:
+ /* Race: client probably got cb_recall
+ * before open reply granting delegation */
+ break;
+ default:
+ /* success, or error we can't handle */
+ return;
+ }
+ if (dp->dl_retries--) {
+ rpc_delay(task, 2*HZ);
+ task->tk_status = 0;
+ rpc_restart_call(task);
+ } else {
+ atomic_set(&clp->cl_cb_conn.cb_set, 0);
+ warn_no_callback_path(clp, task->tk_status);
+ }
}
+static void nfsd4_cb_recall_release(void *calldata)
+{
+ struct nfs4_delegation *dp = calldata;
+ struct nfs4_client *clp = dp->dl_client;
+
+ nfs4_put_delegation(dp);
+ put_nfs4_client(clp);
+}
+
+static const struct rpc_call_ops nfsd4_cb_recall_ops = {
+ .rpc_call_done = nfsd4_cb_recall_done,
+ .rpc_release = nfsd4_cb_recall_release,
+};
+
/*
* called with dp->dl_count inc'ed.
*/
@@ -468,41 +544,19 @@ void
nfsd4_cb_recall(struct nfs4_delegation *dp)
{
struct nfs4_client *clp = dp->dl_client;
- struct rpc_clnt *clnt = clp->cl_callback.cb_client;
- struct nfs4_cb_recall *cbr = &dp->dl_recall;
+ struct rpc_clnt *clnt = clp->cl_cb_conn.cb_client;
struct rpc_message msg = {
.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL],
- .rpc_argp = cbr,
+ .rpc_argp = dp,
+ .rpc_cred = clp->cl_cb_conn.cb_cred
};
- int retries = 1;
- int status = 0;
-
- cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */
- cbr->cbr_dp = dp;
-
- status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT);
- while (retries--) {
- switch (status) {
- case -EIO:
- /* Network partition? */
- atomic_set(&clp->cl_callback.cb_set, 0);
- case -EBADHANDLE:
- case -NFS4ERR_BAD_STATEID:
- /* Race: client probably got cb_recall
- * before open reply granting delegation */
- break;
- default:
- goto out_put_cred;
- }
- ssleep(2);
- status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT);
+ int status;
+
+ dp->dl_retries = 1;
+ status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT,
+ &nfsd4_cb_recall_ops, dp);
+ if (status) {
+ put_nfs4_client(clp);
+ nfs4_put_delegation(dp);
}
-out_put_cred:
- /*
- * Success or failure, now we're either waiting for lease expiration
- * or deleg_return.
- */
- put_nfs4_client(clp);
- nfs4_put_delegation(dp);
- return;
}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 5275097a7565..b5348405046b 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -229,7 +229,7 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
goto out;
status = vfs_readdir(filp, nfsd4_build_namelist, &names);
fput(filp);
- mutex_lock(&dir->d_inode->i_mutex);
+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
while (!list_empty(&names)) {
entry = list_entry(names.next, struct name_list, list);
@@ -264,7 +264,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
- mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
+ mutex_lock_nested(&rec_dir.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
dentry = lookup_one_len(name, rec_dir.dentry, namlen);
if (IS_ERR(dentry)) {
status = PTR_ERR(dentry);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index c65a27b76a9d..89d9ac55c034 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -182,7 +182,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
{
struct nfs4_delegation *dp;
struct nfs4_file *fp = stp->st_file;
- struct nfs4_callback *cb = &stp->st_stateowner->so_client->cl_callback;
+ struct nfs4_cb_conn *cb = &stp->st_stateowner->so_client->cl_cb_conn;
dprintk("NFSD alloc_init_deleg\n");
if (fp->fi_had_conflict)
@@ -203,10 +203,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
get_file(stp->st_vfs_file);
dp->dl_vfs_file = stp->st_vfs_file;
dp->dl_type = type;
- dp->dl_recall.cbr_dp = NULL;
- dp->dl_recall.cbr_ident = cb->cb_ident;
- dp->dl_recall.cbr_trunc = 0;
- dp->dl_stateid.si_boot = boot_time;
+ dp->dl_ident = cb->cb_ident;
+ dp->dl_stateid.si_boot = get_seconds();
dp->dl_stateid.si_stateownerid = current_delegid++;
dp->dl_stateid.si_fileid = 0;
dp->dl_stateid.si_generation = 0;
@@ -580,7 +578,6 @@ free_session(struct kref *kref)
struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry;
nfsd4_release_respages(e->ce_respages, e->ce_resused);
}
- kfree(ses->se_slots);
kfree(ses);
}
@@ -633,16 +630,20 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
static void
shutdown_callback_client(struct nfs4_client *clp)
{
- struct rpc_clnt *clnt = clp->cl_callback.cb_client;
+ struct rpc_clnt *clnt = clp->cl_cb_conn.cb_client;
if (clnt) {
/*
* Callback threads take a reference on the client, so there
* should be no outstanding callbacks at this point.
*/
- clp->cl_callback.cb_client = NULL;
+ clp->cl_cb_conn.cb_client = NULL;
rpc_shutdown_client(clnt);
}
+ if (clp->cl_cb_conn.cb_cred) {
+ put_rpccred(clp->cl_cb_conn.cb_cred);
+ clp->cl_cb_conn.cb_cred = NULL;
+ }
}
static inline void
@@ -715,7 +716,7 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir)
return NULL;
memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
atomic_set(&clp->cl_count, 1);
- atomic_set(&clp->cl_callback.cb_set, 0);
+ atomic_set(&clp->cl_cb_conn.cb_set, 0);
INIT_LIST_HEAD(&clp->cl_idhash);
INIT_LIST_HEAD(&clp->cl_strhash);
INIT_LIST_HEAD(&clp->cl_openowners);
@@ -967,7 +968,7 @@ parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigne
static void
gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
{
- struct nfs4_callback *cb = &clp->cl_callback;
+ struct nfs4_cb_conn *cb = &clp->cl_cb_conn;
/* Currently, we only support tcp for the callback channel */
if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3))
@@ -1687,9 +1688,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
else {
/* XXX: We just turn off callbacks until we can handle
* change request correctly. */
- atomic_set(&conf->cl_callback.cb_set, 0);
- gen_confirm(conf);
- nfsd4_remove_clid_dir(unconf);
+ atomic_set(&conf->cl_cb_conn.cb_set, 0);
expire_client(unconf);
status = nfs_ok;
@@ -1883,7 +1882,7 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *
stp->st_stateowner = sop;
get_nfs4_file(fp);
stp->st_file = fp;
- stp->st_stateid.si_boot = boot_time;
+ stp->st_stateid.si_boot = get_seconds();
stp->st_stateid.si_stateownerid = sop->so_id;
stp->st_stateid.si_fileid = fp->fi_id;
stp->st_stateid.si_generation = 0;
@@ -2060,19 +2059,6 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access)
}
/*
- * Recall a delegation
- */
-static int
-do_recall(void *__dp)
-{
- struct nfs4_delegation *dp = __dp;
-
- dp->dl_file->fi_had_conflict = true;
- nfsd4_cb_recall(dp);
- return 0;
-}
-
-/*
* Spawn a thread to perform a recall on the delegation represented
* by the lease (file_lock)
*
@@ -2083,8 +2069,7 @@ do_recall(void *__dp)
static
void nfsd_break_deleg_cb(struct file_lock *fl)
{
- struct nfs4_delegation *dp= (struct nfs4_delegation *)fl->fl_owner;
- struct task_struct *t;
+ struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl);
if (!dp)
@@ -2112,16 +2097,8 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
*/
fl->fl_break_time = 0;
- t = kthread_run(do_recall, dp, "%s", "nfs4_cb_recall");
- if (IS_ERR(t)) {
- struct nfs4_client *clp = dp->dl_client;
-
- printk(KERN_INFO "NFSD: Callback thread failed for "
- "for client (clientid %08x/%08x)\n",
- clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
- put_nfs4_client(dp->dl_client);
- nfs4_put_delegation(dp);
- }
+ dp->dl_file->fi_had_conflict = true;
+ nfsd4_cb_recall(dp);
}
/*
@@ -2423,7 +2400,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
{
struct nfs4_delegation *dp;
struct nfs4_stateowner *sop = stp->st_stateowner;
- struct nfs4_callback *cb = &sop->so_client->cl_callback;
+ struct nfs4_cb_conn *cb = &sop->so_client->cl_cb_conn;
struct file_lock fl, *flp = &fl;
int status, flag = 0;
@@ -2615,7 +2592,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
renew_client(clp);
status = nfserr_cb_path_down;
if (!list_empty(&clp->cl_delegations)
- && !atomic_read(&clp->cl_callback.cb_set))
+ && !atomic_read(&clp->cl_cb_conn.cb_set))
goto out;
status = nfs_ok;
out:
@@ -2739,12 +2716,42 @@ nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
static int
STALE_STATEID(stateid_t *stateid)
{
- if (stateid->si_boot == boot_time)
- return 0;
- dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
- stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
- stateid->si_generation);
- return 1;
+ if (time_after((unsigned long)boot_time,
+ (unsigned long)stateid->si_boot)) {
+ dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
+ stateid->si_boot, stateid->si_stateownerid,
+ stateid->si_fileid, stateid->si_generation);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+EXPIRED_STATEID(stateid_t *stateid)
+{
+ if (time_before((unsigned long)boot_time,
+ ((unsigned long)stateid->si_boot)) &&
+ time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) {
+ dprintk("NFSD: expired stateid (%08x/%08x/%08x/%08x)!\n",
+ stateid->si_boot, stateid->si_stateownerid,
+ stateid->si_fileid, stateid->si_generation);
+ return 1;
+ }
+ return 0;
+}
+
+static __be32
+stateid_error_map(stateid_t *stateid)
+{
+ if (STALE_STATEID(stateid))
+ return nfserr_stale_stateid;
+ if (EXPIRED_STATEID(stateid))
+ return nfserr_expired;
+
+ dprintk("NFSD: bad stateid (%08x/%08x/%08x/%08x)!\n",
+ stateid->si_boot, stateid->si_stateownerid,
+ stateid->si_fileid, stateid->si_generation);
+ return nfserr_bad_stateid;
}
static inline int
@@ -2868,8 +2875,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
status = nfserr_bad_stateid;
if (is_delegation_stateid(stateid)) {
dp = find_delegation_stateid(ino, stateid);
- if (!dp)
+ if (!dp) {
+ status = stateid_error_map(stateid);
goto out;
+ }
status = check_stateid_generation(stateid, &dp->dl_stateid,
flags);
if (status)
@@ -2882,8 +2891,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
*filpp = dp->dl_vfs_file;
} else { /* open or lock stateid */
stp = find_stateid(stateid, flags);
- if (!stp)
+ if (!stp) {
+ status = stateid_error_map(stateid);
goto out;
+ }
if (nfs4_check_fh(current_fh, stp))
goto out;
if (!stp->st_stateowner->so_confirmed)
@@ -2957,7 +2968,7 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
*/
sop = search_close_lru(stateid->si_stateownerid, flags);
if (sop == NULL)
- return nfserr_bad_stateid;
+ return stateid_error_map(stateid);
*sopp = sop;
goto check_replay;
}
@@ -3228,8 +3239,10 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (!is_delegation_stateid(stateid))
goto out;
dp = find_delegation_stateid(inode, stateid);
- if (!dp)
+ if (!dp) {
+ status = stateid_error_map(stateid);
goto out;
+ }
status = check_stateid_generation(stateid, &dp->dl_stateid, flags);
if (status)
goto out;
@@ -3456,7 +3469,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
stp->st_stateowner = sop;
get_nfs4_file(fp);
stp->st_file = fp;
- stp->st_stateid.si_boot = boot_time;
+ stp->st_stateid.si_boot = get_seconds();
stp->st_stateid.si_stateownerid = sop->so_id;
stp->st_stateid.si_fileid = fp->fi_id;
stp->st_stateid.si_generation = 0;
@@ -3988,6 +4001,7 @@ nfs4_state_init(void)
INIT_LIST_HEAD(&conf_str_hashtbl[i]);
INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
+ INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
}
for (i = 0; i < SESSION_HASH_SIZE; i++)
INIT_LIST_HEAD(&sessionid_hashtbl[i]);
@@ -4010,8 +4024,6 @@ nfs4_state_init(void)
INIT_LIST_HEAD(&close_lru);
INIT_LIST_HEAD(&client_lru);
INIT_LIST_HEAD(&del_recall_lru);
- for (i = 0; i < CLIENT_HASH_SIZE; i++)
- INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
reclaim_str_hashtbl_size = 0;
return 0;
}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index b820c311931c..fefb993654bb 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -83,16 +83,6 @@ check_filename(char *str, int len, __be32 err)
return 0;
}
-/*
- * START OF "GENERIC" DECODE ROUTINES.
- * These may look a little ugly since they are imported from a "generic"
- * set of XDR encode/decode routines which are intended to be shared by
- * all of our NFSv4 implementations (OpenBSD, MacOS X...).
- *
- * If the pain of reading these is too great, it should be a straightforward
- * task to translate them into Linux-specific versions which are more
- * consistent with the style used in NFSv2/v3...
- */
#define DECODE_HEAD \
__be32 *p; \
__be32 status
@@ -1328,64 +1318,64 @@ static nfsd4_dec nfsd4_dec_ops[] = {
};
static nfsd4_dec nfsd41_dec_ops[] = {
- [OP_ACCESS] (nfsd4_dec)nfsd4_decode_access,
- [OP_CLOSE] (nfsd4_dec)nfsd4_decode_close,
- [OP_COMMIT] (nfsd4_dec)nfsd4_decode_commit,
- [OP_CREATE] (nfsd4_dec)nfsd4_decode_create,
- [OP_DELEGPURGE] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_DELEGRETURN] (nfsd4_dec)nfsd4_decode_delegreturn,
- [OP_GETATTR] (nfsd4_dec)nfsd4_decode_getattr,
- [OP_GETFH] (nfsd4_dec)nfsd4_decode_noop,
- [OP_LINK] (nfsd4_dec)nfsd4_decode_link,
- [OP_LOCK] (nfsd4_dec)nfsd4_decode_lock,
- [OP_LOCKT] (nfsd4_dec)nfsd4_decode_lockt,
- [OP_LOCKU] (nfsd4_dec)nfsd4_decode_locku,
- [OP_LOOKUP] (nfsd4_dec)nfsd4_decode_lookup,
- [OP_LOOKUPP] (nfsd4_dec)nfsd4_decode_noop,
- [OP_NVERIFY] (nfsd4_dec)nfsd4_decode_verify,
- [OP_OPEN] (nfsd4_dec)nfsd4_decode_open,
- [OP_OPENATTR] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_OPEN_CONFIRM] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_OPEN_DOWNGRADE] (nfsd4_dec)nfsd4_decode_open_downgrade,
- [OP_PUTFH] (nfsd4_dec)nfsd4_decode_putfh,
- [OP_PUTPUBFH] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_PUTROOTFH] (nfsd4_dec)nfsd4_decode_noop,
- [OP_READ] (nfsd4_dec)nfsd4_decode_read,
- [OP_READDIR] (nfsd4_dec)nfsd4_decode_readdir,
- [OP_READLINK] (nfsd4_dec)nfsd4_decode_noop,
- [OP_REMOVE] (nfsd4_dec)nfsd4_decode_remove,
- [OP_RENAME] (nfsd4_dec)nfsd4_decode_rename,
- [OP_RENEW] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_RESTOREFH] (nfsd4_dec)nfsd4_decode_noop,
- [OP_SAVEFH] (nfsd4_dec)nfsd4_decode_noop,
- [OP_SECINFO] (nfsd4_dec)nfsd4_decode_secinfo,
- [OP_SETATTR] (nfsd4_dec)nfsd4_decode_setattr,
- [OP_SETCLIENTID] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_SETCLIENTID_CONFIRM](nfsd4_dec)nfsd4_decode_notsupp,
- [OP_VERIFY] (nfsd4_dec)nfsd4_decode_verify,
- [OP_WRITE] (nfsd4_dec)nfsd4_decode_write,
- [OP_RELEASE_LOCKOWNER] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access,
+ [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close,
+ [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit,
+ [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create,
+ [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn,
+ [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr,
+ [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop,
+ [OP_LINK] = (nfsd4_dec)nfsd4_decode_link,
+ [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock,
+ [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt,
+ [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku,
+ [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup,
+ [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop,
+ [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify,
+ [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open,
+ [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
+ [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
+ [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
+ [OP_READ] = (nfsd4_dec)nfsd4_decode_read,
+ [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
+ [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop,
+ [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove,
+ [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename,
+ [OP_RENEW] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop,
+ [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop,
+ [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo,
+ [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr,
+ [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_SETCLIENTID_CONFIRM]= (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify,
+ [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write,
+ [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp,
/* new operations for NFSv4.1 */
- [OP_BACKCHANNEL_CTL] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_BIND_CONN_TO_SESSION](nfsd4_dec)nfsd4_decode_notsupp,
- [OP_EXCHANGE_ID] (nfsd4_dec)nfsd4_decode_exchange_id,
- [OP_CREATE_SESSION] (nfsd4_dec)nfsd4_decode_create_session,
- [OP_DESTROY_SESSION] (nfsd4_dec)nfsd4_decode_destroy_session,
- [OP_FREE_STATEID] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_GET_DIR_DELEGATION] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_GETDEVICEINFO] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_GETDEVICELIST] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_LAYOUTCOMMIT] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_LAYOUTGET] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_LAYOUTRETURN] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_SECINFO_NO_NAME] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_SEQUENCE] (nfsd4_dec)nfsd4_decode_sequence,
- [OP_SET_SSV] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_TEST_STATEID] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_WANT_DELEGATION] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_DESTROY_CLIENTID] (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_RECLAIM_COMPLETE] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id,
+ [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session,
+ [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session,
+ [OP_FREE_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_GET_DIR_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence,
+ [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_notsupp,
};
struct nfsd4_minorversion_ops {
@@ -1489,21 +1479,6 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
DECODE_TAIL;
}
-/*
- * END OF "GENERIC" DECODE ROUTINES.
- */
-
-/*
- * START OF "GENERIC" ENCODE ROUTINES.
- * These may look a little ugly since they are imported from a "generic"
- * set of XDR encode/decode routines which are intended to be shared by
- * all of our NFSv4 implementations (OpenBSD, MacOS X...).
- *
- * If the pain of reading these is too great, it should be a straightforward
- * task to translate them into Linux-specific versions which are more
- * consistent with the style used in NFSv2/v3...
- */
-#define ENCODE_HEAD __be32 *p
#define WRITE32(n) *p++ = htonl(n)
#define WRITE64(n) do { \
@@ -1515,13 +1490,41 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
memcpy(p, ptr, nbytes); \
p += XDR_QUADLEN(nbytes); \
}} while (0)
-#define WRITECINFO(c) do { \
- *p++ = htonl(c.atomic); \
- *p++ = htonl(c.before_ctime_sec); \
- *p++ = htonl(c.before_ctime_nsec); \
- *p++ = htonl(c.after_ctime_sec); \
- *p++ = htonl(c.after_ctime_nsec); \
-} while (0)
+
+static void write32(__be32 **p, u32 n)
+{
+ *(*p)++ = n;
+}
+
+static void write64(__be32 **p, u64 n)
+{
+ write32(p, (u32)(n >> 32));
+ write32(p, (u32)n);
+}
+
+static void write_change(__be32 **p, struct kstat *stat, struct inode *inode)
+{
+ if (IS_I_VERSION(inode)) {
+ write64(p, inode->i_version);
+ } else {
+ write32(p, stat->ctime.tv_sec);
+ write32(p, stat->ctime.tv_nsec);
+ }
+}
+
+static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
+{
+ write32(p, c->atomic);
+ if (c->change_supported) {
+ write64(p, c->before_change);
+ write64(p, c->after_change);
+ } else {
+ write32(p, c->before_ctime_sec);
+ write32(p, c->before_ctime_nsec);
+ write32(p, c->after_ctime_sec);
+ write32(p, c->after_ctime_nsec);
+ }
+}
#define RESERVE_SPACE(nbytes) do { \
p = resp->p; \
@@ -1874,16 +1877,9 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME);
}
if (bmval0 & FATTR4_WORD0_CHANGE) {
- /*
- * Note: This _must_ be consistent with the scheme for writing
- * change_info, so any changes made here must be reflected there
- * as well. (See xdr4.h:set_change_info() and the WRITECINFO()
- * macro above.)
- */
if ((buflen -= 8) < 0)
goto out_resource;
- WRITE32(stat.ctime.tv_sec);
- WRITE32(stat.ctime.tv_nsec);
+ write_change(&p, &stat, dentry->d_inode);
}
if (bmval0 & FATTR4_WORD0_SIZE) {
if ((buflen -= 8) < 0)
@@ -2214,6 +2210,15 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
if (IS_ERR(dentry))
return nfserrno(PTR_ERR(dentry));
+ if (!dentry->d_inode) {
+ /*
+ * nfsd_buffered_readdir drops the i_mutex between
+ * readdir and calling this callback, leaving a window
+ * where this directory entry could have gone away.
+ */
+ dput(dentry);
+ return nfserr_noent;
+ }
exp_get(exp);
/*
@@ -2276,6 +2281,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
int buflen;
__be32 *p = cd->buffer;
+ __be32 *cookiep;
__be32 nfserr = nfserr_toosmall;
/* In nfsv4, "." and ".." never make it onto the wire.. */
@@ -2292,7 +2298,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
goto fail;
*p++ = xdr_one; /* mark entry present */
- cd->offset = p; /* remember pointer */
+ cookiep = p;
p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */
p = xdr_encode_array(p, name, namlen); /* name length & name */
@@ -2306,6 +2312,8 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
goto fail;
case nfserr_dropit:
goto fail;
+ case nfserr_noent:
+ goto skip_entry;
default:
/*
* If the client requested the RDATTR_ERROR attribute,
@@ -2324,6 +2332,8 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
}
cd->buflen -= (p - cd->buffer);
cd->buffer = p;
+ cd->offset = cookiep;
+skip_entry:
cd->common.err = nfs_ok;
return 0;
fail:
@@ -2334,7 +2344,7 @@ fail:
static void
nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid)
{
- ENCODE_HEAD;
+ __be32 *p;
RESERVE_SPACE(sizeof(stateid_t));
WRITE32(sid->si_generation);
@@ -2345,7 +2355,7 @@ nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid)
static __be32
nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
{
- ENCODE_HEAD;
+ __be32 *p;
if (!nfserr) {
RESERVE_SPACE(8);
@@ -2372,7 +2382,7 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c
static __be32
nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
{
- ENCODE_HEAD;
+ __be32 *p;
if (!nfserr) {
RESERVE_SPACE(8);
@@ -2385,11 +2395,11 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
static __be32
nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
{
- ENCODE_HEAD;
+ __be32 *p;
if (!nfserr) {
RESERVE_SPACE(32);
- WRITECINFO(create->cr_cinfo);
+ write_cinfo(&p, &create->cr_cinfo);
WRITE32(2);
WRITE32(create->cr_bmval[0]);
WRITE32(create->cr_bmval[1]);
@@ -2421,7 +2431,7 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh
{
struct svc_fh *fhp = *fhpp;
unsigned int len;
- ENCODE_HEAD;
+ __be32 *p;
if (!nfserr) {
len = fhp->fh_handle.fh_size;
@@ -2440,7 +2450,7 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh
static void
nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
{
- ENCODE_HEAD;
+ __be32 *p;
RESERVE_SPACE(32 + XDR_LEN(ld->ld_sop ? ld->ld_sop->so_owner.len : 0));
WRITE64(ld->ld_start);
@@ -2496,11 +2506,11 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l
static __be32
nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
{
- ENCODE_HEAD;
+ __be32 *p;
if (!nfserr) {
RESERVE_SPACE(20);
- WRITECINFO(link->li_cinfo);
+ write_cinfo(&p, &link->li_cinfo);
ADJUST_ARGS();
}
return nfserr;
@@ -2510,7 +2520,7 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_li
static __be32
nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
{
- ENCODE_HEAD;
+ __be32 *p;
ENCODE_SEQID_OP_HEAD;
if (nfserr)
@@ -2518,7 +2528,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
nfsd4_encode_stateid(resp, &open->op_stateid);
RESERVE_SPACE(40);
- WRITECINFO(open->op_cinfo);
+ write_cinfo(&p, &open->op_cinfo);
WRITE32(open->op_rflags);
WRITE32(2);
WRITE32(open->op_bmval[0]);
@@ -2605,7 +2615,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
int v, pn;
unsigned long maxcount;
long len;
- ENCODE_HEAD;
+ __be32 *p;
if (nfserr)
return nfserr;
@@ -2667,7 +2677,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
{
int maxcount;
char *page;
- ENCODE_HEAD;
+ __be32 *p;
if (nfserr)
return nfserr;
@@ -2716,7 +2726,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
int maxcount;
loff_t offset;
__be32 *page, *savep, *tailbase;
- ENCODE_HEAD;
+ __be32 *p;
if (nfserr)
return nfserr;
@@ -2792,11 +2802,11 @@ err_no_verf:
static __be32
nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
{
- ENCODE_HEAD;
+ __be32 *p;
if (!nfserr) {
RESERVE_SPACE(20);
- WRITECINFO(remove->rm_cinfo);
+ write_cinfo(&p, &remove->rm_cinfo);
ADJUST_ARGS();
}
return nfserr;
@@ -2805,12 +2815,12 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
static __be32
nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
{
- ENCODE_HEAD;
+ __be32 *p;
if (!nfserr) {
RESERVE_SPACE(40);
- WRITECINFO(rename->rn_sinfo);
- WRITECINFO(rename->rn_tinfo);
+ write_cinfo(&p, &rename->rn_sinfo);
+ write_cinfo(&p, &rename->rn_tinfo);
ADJUST_ARGS();
}
return nfserr;
@@ -2825,7 +2835,7 @@ nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
u32 nflavs;
struct exp_flavor_info *flavs;
struct exp_flavor_info def_flavs[2];
- ENCODE_HEAD;
+ __be32 *p;
if (nfserr)
goto out;
@@ -2890,7 +2900,7 @@ out:
static __be32
nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
{
- ENCODE_HEAD;
+ __be32 *p;
RESERVE_SPACE(12);
if (nfserr) {
@@ -2910,7 +2920,7 @@ nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
static __be32
nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
{
- ENCODE_HEAD;
+ __be32 *p;
if (!nfserr) {
RESERVE_SPACE(8 + sizeof(nfs4_verifier));
@@ -2930,7 +2940,7 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct n
static __be32
nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
{
- ENCODE_HEAD;
+ __be32 *p;
if (!nfserr) {
RESERVE_SPACE(16);
@@ -2946,7 +2956,7 @@ static __be32
nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr,
struct nfsd4_exchange_id *exid)
{
- ENCODE_HEAD;
+ __be32 *p;
char *major_id;
char *server_scope;
int major_id_sz;
@@ -3001,7 +3011,7 @@ static __be32
nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr,
struct nfsd4_create_session *sess)
{
- ENCODE_HEAD;
+ __be32 *p;
if (nfserr)
return nfserr;
@@ -3057,7 +3067,7 @@ __be32
nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
struct nfsd4_sequence *seq)
{
- ENCODE_HEAD;
+ __be32 *p;
if (nfserr)
return nfserr;
@@ -3205,7 +3215,7 @@ void
nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
{
__be32 *statp;
- ENCODE_HEAD;
+ __be32 *p;
RESERVE_SPACE(8);
WRITE32(op->opnum);
@@ -3239,7 +3249,7 @@ status:
void
nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
{
- ENCODE_HEAD;
+ __be32 *p;
struct nfs4_replay *rp = op->replay;
BUG_ON(!rp);
@@ -3254,10 +3264,6 @@ nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
ADJUST_ARGS();
}
-/*
- * END OF "GENERIC" ENCODE ROUTINES.
- */
-
int
nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
{
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index af16849d243a..877e713a0fd6 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -695,8 +695,9 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
if (rv)
return rv;
}
- sprintf(buf, "%d\n", nfsd_nrthreads());
- return strlen(buf);
+
+ return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n",
+ nfsd_nrthreads());
}
/**
@@ -793,7 +794,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
{
char *mesg = buf;
char *vers, *minorp, sign;
- int len, num;
+ int len, num, remaining;
unsigned minor;
ssize_t tlen = 0;
char *sep;
@@ -840,32 +841,50 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
}
next:
vers += len + 1;
- tlen += len;
} while ((len = qword_get(&mesg, vers, size)) > 0);
/* If all get turned off, turn them back on, as
* having no versions is BAD
*/
nfsd_reset_versions();
}
+
/* Now write current state into reply buffer */
len = 0;
sep = "";
+ remaining = SIMPLE_TRANSACTION_LIMIT;
for (num=2 ; num <= 4 ; num++)
if (nfsd_vers(num, NFSD_AVAIL)) {
- len += sprintf(buf+len, "%s%c%d", sep,
+ len = snprintf(buf, remaining, "%s%c%d", sep,
nfsd_vers(num, NFSD_TEST)?'+':'-',
num);
sep = " ";
+
+ if (len > remaining)
+ break;
+ remaining -= len;
+ buf += len;
+ tlen += len;
}
if (nfsd_vers(4, NFSD_AVAIL))
- for (minor = 1; minor <= NFSD_SUPPORTED_MINOR_VERSION; minor++)
- len += sprintf(buf+len, " %c4.%u",
+ for (minor = 1; minor <= NFSD_SUPPORTED_MINOR_VERSION;
+ minor++) {
+ len = snprintf(buf, remaining, " %c4.%u",
(nfsd_vers(4, NFSD_TEST) &&
nfsd_minorversion(minor, NFSD_TEST)) ?
'+' : '-',
minor);
- len += sprintf(buf+len, "\n");
- return len;
+
+ if (len > remaining)
+ break;
+ remaining -= len;
+ buf += len;
+ tlen += len;
+ }
+
+ len = snprintf(buf, remaining, "\n");
+ if (len > remaining)
+ return -EINVAL;
+ return tlen + len;
}
/**
@@ -910,104 +929,143 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
return rv;
}
-static ssize_t __write_ports(struct file *file, char *buf, size_t size)
+/*
+ * Zero-length write. Return a list of NFSD's current listener
+ * transports.
+ */
+static ssize_t __write_ports_names(char *buf)
{
- if (size == 0) {
- int len = 0;
+ if (nfsd_serv == NULL)
+ return 0;
+ return svc_xprt_names(nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT);
+}
- if (nfsd_serv)
- len = svc_xprt_names(nfsd_serv, buf, 0);
- return len;
- }
- /* Either a single 'fd' number is written, in which
- * case it must be for a socket of a supported family/protocol,
- * and we use it as an nfsd socket, or
- * A '-' followed by the 'name' of a socket in which case
- * we close the socket.
- */
- if (isdigit(buf[0])) {
- char *mesg = buf;
- int fd;
- int err;
- err = get_int(&mesg, &fd);
- if (err)
- return -EINVAL;
- if (fd < 0)
- return -EINVAL;
- err = nfsd_create_serv();
- if (!err) {
- err = svc_addsock(nfsd_serv, fd, buf);
- if (err >= 0) {
- err = lockd_up();
- if (err < 0)
- svc_sock_names(buf+strlen(buf)+1, nfsd_serv, buf);
- }
- /* Decrease the count, but don't shutdown the
- * the service
- */
- nfsd_serv->sv_nrthreads--;
- }
- return err < 0 ? err : 0;
- }
- if (buf[0] == '-' && isdigit(buf[1])) {
- char *toclose = kstrdup(buf+1, GFP_KERNEL);
- int len = 0;
- if (!toclose)
- return -ENOMEM;
- if (nfsd_serv)
- len = svc_sock_names(buf, nfsd_serv, toclose);
- if (len >= 0)
- lockd_down();
- kfree(toclose);
- return len;
- }
- /*
- * Add a transport listener by writing it's transport name
- */
- if (isalpha(buf[0])) {
- int err;
- char transport[16];
- int port;
- if (sscanf(buf, "%15s %4d", transport, &port) == 2) {
- if (port < 1 || port > 65535)
- return -EINVAL;
- err = nfsd_create_serv();
- if (!err) {
- err = svc_create_xprt(nfsd_serv,
- transport, PF_INET, port,
- SVC_SOCK_ANONYMOUS);
- if (err == -ENOENT)
- /* Give a reasonable perror msg for
- * bad transport string */
- err = -EPROTONOSUPPORT;
- }
- return err < 0 ? err : 0;
- }
- }
- /*
- * Remove a transport by writing it's transport name and port number
- */
- if (buf[0] == '-' && isalpha(buf[1])) {
- struct svc_xprt *xprt;
- int err = -EINVAL;
- char transport[16];
- int port;
- if (sscanf(&buf[1], "%15s %4d", transport, &port) == 2) {
- if (port < 1 || port > 65535)
- return -EINVAL;
- if (nfsd_serv) {
- xprt = svc_find_xprt(nfsd_serv, transport,
- AF_UNSPEC, port);
- if (xprt) {
- svc_close_xprt(xprt);
- svc_xprt_put(xprt);
- err = 0;
- } else
- err = -ENOTCONN;
- }
- return err < 0 ? err : 0;
- }
+/*
+ * A single 'fd' number was written, in which case it must be for
+ * a socket of a supported family/protocol, and we use it as an
+ * nfsd listener.
+ */
+static ssize_t __write_ports_addfd(char *buf)
+{
+ char *mesg = buf;
+ int fd, err;
+
+ err = get_int(&mesg, &fd);
+ if (err != 0 || fd < 0)
+ return -EINVAL;
+
+ err = nfsd_create_serv();
+ if (err != 0)
+ return err;
+
+ err = lockd_up();
+ if (err != 0)
+ goto out;
+
+ err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
+ if (err < 0)
+ lockd_down();
+
+out:
+ /* Decrease the count, but don't shut down the service */
+ nfsd_serv->sv_nrthreads--;
+ return err;
+}
+
+/*
+ * A '-' followed by the 'name' of a socket means we close the socket.
+ */
+static ssize_t __write_ports_delfd(char *buf)
+{
+ char *toclose;
+ int len = 0;
+
+ toclose = kstrdup(buf + 1, GFP_KERNEL);
+ if (toclose == NULL)
+ return -ENOMEM;
+
+ if (nfsd_serv != NULL)
+ len = svc_sock_names(nfsd_serv, buf,
+ SIMPLE_TRANSACTION_LIMIT, toclose);
+ if (len >= 0)
+ lockd_down();
+
+ kfree(toclose);
+ return len;
+}
+
+/*
+ * A transport listener is added by writing it's transport name and
+ * a port number.
+ */
+static ssize_t __write_ports_addxprt(char *buf)
+{
+ char transport[16];
+ int port, err;
+
+ if (sscanf(buf, "%15s %4u", transport, &port) != 2)
+ return -EINVAL;
+
+ if (port < 1 || port > USHORT_MAX)
+ return -EINVAL;
+
+ err = nfsd_create_serv();
+ if (err != 0)
+ return err;
+
+ err = svc_create_xprt(nfsd_serv, transport,
+ PF_INET, port, SVC_SOCK_ANONYMOUS);
+ if (err < 0) {
+ /* Give a reasonable perror msg for bad transport string */
+ if (err == -ENOENT)
+ err = -EPROTONOSUPPORT;
+ return err;
}
+ return 0;
+}
+
+/*
+ * A transport listener is removed by writing a "-", it's transport
+ * name, and it's port number.
+ */
+static ssize_t __write_ports_delxprt(char *buf)
+{
+ struct svc_xprt *xprt;
+ char transport[16];
+ int port;
+
+ if (sscanf(&buf[1], "%15s %4u", transport, &port) != 2)
+ return -EINVAL;
+
+ if (port < 1 || port > USHORT_MAX || nfsd_serv == NULL)
+ return -EINVAL;
+
+ xprt = svc_find_xprt(nfsd_serv, transport, AF_UNSPEC, port);
+ if (xprt == NULL)
+ return -ENOTCONN;
+
+ svc_close_xprt(xprt);
+ svc_xprt_put(xprt);
+ return 0;
+}
+
+static ssize_t __write_ports(struct file *file, char *buf, size_t size)
+{
+ if (size == 0)
+ return __write_ports_names(buf);
+
+ if (isdigit(buf[0]))
+ return __write_ports_addfd(buf);
+
+ if (buf[0] == '-' && isdigit(buf[1]))
+ return __write_ports_delfd(buf);
+
+ if (isalpha(buf[0]))
+ return __write_ports_addxprt(buf);
+
+ if (buf[0] == '-' && isalpha(buf[1]))
+ return __write_ports_delxprt(buf);
+
return -EINVAL;
}
@@ -1030,7 +1088,9 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size)
* buf: C string containing an unsigned
* integer value representing a bound
* but unconnected socket that is to be
- * used as an NFSD listener
+ * used as an NFSD listener; listen(3)
+ * must be called for a SOCK_STREAM
+ * socket, otherwise it is ignored
* size: non-zero length of C string in @buf
* Output:
* On success: NFS service is started;
@@ -1138,7 +1198,9 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
nfsd_max_blksize = bsize;
mutex_unlock(&nfsd_mutex);
}
- return sprintf(buf, "%d\n", nfsd_max_blksize);
+
+ return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n",
+ nfsd_max_blksize);
}
#ifdef CONFIG_NFSD_V4
@@ -1162,8 +1224,9 @@ static ssize_t __write_leasetime(struct file *file, char *buf, size_t size)
return -EINVAL;
nfs4_reset_lease(lease);
}
- sprintf(buf, "%ld\n", nfs4_lease_time());
- return strlen(buf);
+
+ return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n",
+ nfs4_lease_time());
}
/**
@@ -1219,8 +1282,9 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size)
status = nfs4_reset_recoverydir(recdir);
}
- sprintf(buf, "%s\n", nfs4_recoverydir());
- return strlen(buf);
+
+ return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s\n",
+ nfs4_recoverydir());
}
/**
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 6c68ffd6b4bb..6ef2b1dd3a2a 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -100,36 +100,35 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
{
struct svc_export *exp = *expp, *exp2 = NULL;
struct dentry *dentry = *dpp;
- struct vfsmount *mnt = mntget(exp->ex_path.mnt);
- struct dentry *mounts = dget(dentry);
+ struct path path = {.mnt = mntget(exp->ex_path.mnt),
+ .dentry = dget(dentry)};
int err = 0;
- while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts));
+ while (d_mountpoint(path.dentry) && follow_down(&path))
+ ;
- exp2 = rqst_exp_get_by_name(rqstp, mnt, mounts);
+ exp2 = rqst_exp_get_by_name(rqstp, &path);
if (IS_ERR(exp2)) {
if (PTR_ERR(exp2) != -ENOENT)
err = PTR_ERR(exp2);
- dput(mounts);
- mntput(mnt);
+ path_put(&path);
goto out;
}
if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) {
/* successfully crossed mount point */
/*
- * This is subtle: dentry is *not* under mnt at this point.
- * The only reason we are safe is that original mnt is pinned
- * down by exp, so we should dput before putting exp.
+ * This is subtle: path.dentry is *not* on path.mnt
+ * at this point. The only reason we are safe is that
+ * original mnt is pinned down by exp, so we should
+ * put path *before* putting exp
*/
- dput(dentry);
- *dpp = mounts;
- exp_put(exp);
+ *dpp = path.dentry;
+ path.dentry = dentry;
*expp = exp2;
- } else {
- exp_put(exp2);
- dput(mounts);
+ exp2 = exp;
}
- mntput(mnt);
+ path_put(&path);
+ exp_put(exp2);
out:
return err;
}
@@ -168,28 +167,29 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
/* checking mountpoint crossing is very different when stepping up */
struct svc_export *exp2 = NULL;
struct dentry *dp;
- struct vfsmount *mnt = mntget(exp->ex_path.mnt);
- dentry = dget(dparent);
- while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry))
+ struct path path = {.mnt = mntget(exp->ex_path.mnt),
+ .dentry = dget(dparent)};
+
+ while (path.dentry == path.mnt->mnt_root &&
+ follow_up(&path))
;
- dp = dget_parent(dentry);
- dput(dentry);
- dentry = dp;
+ dp = dget_parent(path.dentry);
+ dput(path.dentry);
+ path.dentry = dp;
- exp2 = rqst_exp_parent(rqstp, mnt, dentry);
+ exp2 = rqst_exp_parent(rqstp, &path);
if (PTR_ERR(exp2) == -ENOENT) {
- dput(dentry);
dentry = dget(dparent);
} else if (IS_ERR(exp2)) {
host_err = PTR_ERR(exp2);
- dput(dentry);
- mntput(mnt);
+ path_put(&path);
goto out_nfserr;
} else {
+ dentry = dget(path.dentry);
exp_put(exp);
exp = exp2;
}
- mntput(mnt);
+ path_put(&path);
}
} else {
fh_lock(fhp);
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index 108d281ebca5..50ff3f2cdf24 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -25,6 +25,7 @@
#include <linux/smp_lock.h> /* lock_kernel(), unlock_kernel() */
#include <linux/capability.h> /* capable() */
#include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */
+#include <linux/vmalloc.h>
#include <linux/nilfs2_fs.h>
#include "nilfs.h"
#include "segment.h"
@@ -147,29 +148,12 @@ static ssize_t
nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
void *buf, size_t size, size_t nmembs)
{
- return nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
- nmembs);
-}
-
-static int nilfs_ioctl_get_cpinfo(struct inode *inode, struct file *filp,
- unsigned int cmd, void __user *argp)
-{
- struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
- struct nilfs_argv argv;
int ret;
- if (copy_from_user(&argv, argp, sizeof(argv)))
- return -EFAULT;
-
down_read(&nilfs->ns_segctor_sem);
- ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
- nilfs_ioctl_do_get_cpinfo);
+ ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
+ nmembs);
up_read(&nilfs->ns_segctor_sem);
- if (ret < 0)
- return ret;
-
- if (copy_to_user(argp, &argv, sizeof(argv)))
- ret = -EFAULT;
return ret;
}
@@ -195,28 +179,11 @@ static ssize_t
nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
void *buf, size_t size, size_t nmembs)
{
- return nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, nmembs);
-}
-
-static int nilfs_ioctl_get_suinfo(struct inode *inode, struct file *filp,
- unsigned int cmd, void __user *argp)
-{
- struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
- struct nilfs_argv argv;
int ret;
- if (copy_from_user(&argv, argp, sizeof(argv)))
- return -EFAULT;
-
down_read(&nilfs->ns_segctor_sem);
- ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
- nilfs_ioctl_do_get_suinfo);
+ ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, nmembs);
up_read(&nilfs->ns_segctor_sem);
- if (ret < 0)
- return ret;
-
- if (copy_to_user(argp, &argv, sizeof(argv)))
- ret = -EFAULT;
return ret;
}
@@ -242,28 +209,11 @@ static ssize_t
nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
void *buf, size_t size, size_t nmembs)
{
- return nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, nmembs);
-}
-
-static int nilfs_ioctl_get_vinfo(struct inode *inode, struct file *filp,
- unsigned int cmd, void __user *argp)
-{
- struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
- struct nilfs_argv argv;
int ret;
- if (copy_from_user(&argv, argp, sizeof(argv)))
- return -EFAULT;
-
down_read(&nilfs->ns_segctor_sem);
- ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
- nilfs_ioctl_do_get_vinfo);
+ ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, nmembs);
up_read(&nilfs->ns_segctor_sem);
- if (ret < 0)
- return ret;
-
- if (copy_to_user(argp, &argv, sizeof(argv)))
- ret = -EFAULT;
return ret;
}
@@ -276,17 +226,21 @@ nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags,
struct nilfs_bdesc *bdescs = buf;
int ret, i;
+ down_read(&nilfs->ns_segctor_sem);
for (i = 0; i < nmembs; i++) {
ret = nilfs_bmap_lookup_at_level(bmap,
bdescs[i].bd_offset,
bdescs[i].bd_level + 1,
&bdescs[i].bd_blocknr);
if (ret < 0) {
- if (ret != -ENOENT)
+ if (ret != -ENOENT) {
+ up_read(&nilfs->ns_segctor_sem);
return ret;
+ }
bdescs[i].bd_blocknr = 0;
}
}
+ up_read(&nilfs->ns_segctor_sem);
return nmembs;
}
@@ -300,10 +254,11 @@ static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,
if (copy_from_user(&argv, argp, sizeof(argv)))
return -EFAULT;
- down_read(&nilfs->ns_segctor_sem);
+ if (argv.v_size != sizeof(struct nilfs_bdesc))
+ return -EINVAL;
+
ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
nilfs_ioctl_do_get_bdescs);
- up_read(&nilfs->ns_segctor_sem);
if (ret < 0)
return ret;
@@ -346,10 +301,10 @@ static int nilfs_ioctl_move_inode_block(struct inode *inode,
return 0;
}
-static ssize_t
-nilfs_ioctl_do_move_blocks(struct the_nilfs *nilfs, __u64 *posp, int flags,
- void *buf, size_t size, size_t nmembs)
+static int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, void *buf)
{
+ size_t nmembs = argv->v_nmembs;
struct inode *inode;
struct nilfs_vdesc *vdesc;
struct buffer_head *bh, *n;
@@ -410,19 +365,10 @@ nilfs_ioctl_do_move_blocks(struct the_nilfs *nilfs, __u64 *posp, int flags,
return ret;
}
-static inline int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
- struct nilfs_argv *argv,
- int dir)
-{
- return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
- nilfs_ioctl_do_move_blocks);
-}
-
-static ssize_t
-nilfs_ioctl_do_delete_checkpoints(struct the_nilfs *nilfs, __u64 *posp,
- int flags, void *buf, size_t size,
- size_t nmembs)
+static int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, void *buf)
{
+ size_t nmembs = argv->v_nmembs;
struct inode *cpfile = nilfs->ns_cpfile;
struct nilfs_period *periods = buf;
int ret, i;
@@ -436,36 +382,21 @@ nilfs_ioctl_do_delete_checkpoints(struct the_nilfs *nilfs, __u64 *posp,
return nmembs;
}
-static inline int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
- struct nilfs_argv *argv,
- int dir)
+static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, void *buf)
{
- return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
- nilfs_ioctl_do_delete_checkpoints);
-}
+ size_t nmembs = argv->v_nmembs;
+ int ret;
-static ssize_t
-nilfs_ioctl_do_free_vblocknrs(struct the_nilfs *nilfs, __u64 *posp, int flags,
- void *buf, size_t size, size_t nmembs)
-{
- int ret = nilfs_dat_freev(nilfs_dat_inode(nilfs), buf, nmembs);
+ ret = nilfs_dat_freev(nilfs_dat_inode(nilfs), buf, nmembs);
return (ret < 0) ? ret : nmembs;
}
-static inline int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
- struct nilfs_argv *argv,
- int dir)
-{
- return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
- nilfs_ioctl_do_free_vblocknrs);
-}
-
-static ssize_t
-nilfs_ioctl_do_mark_blocks_dirty(struct the_nilfs *nilfs, __u64 *posp,
- int flags, void *buf, size_t size,
- size_t nmembs)
+static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, void *buf)
{
+ size_t nmembs = argv->v_nmembs;
struct inode *dat = nilfs_dat_inode(nilfs);
struct nilfs_bmap *bmap = NILFS_I(dat)->i_bmap;
struct nilfs_bdesc *bdescs = buf;
@@ -504,55 +435,37 @@ nilfs_ioctl_do_mark_blocks_dirty(struct the_nilfs *nilfs, __u64 *posp,
return nmembs;
}
-static inline int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
- struct nilfs_argv *argv,
- int dir)
+static int nilfs_ioctl_free_segments(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, void *buf)
{
- return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
- nilfs_ioctl_do_mark_blocks_dirty);
-}
-
-static ssize_t
-nilfs_ioctl_do_free_segments(struct the_nilfs *nilfs, __u64 *posp, int flags,
- void *buf, size_t size, size_t nmembs)
-{
- struct nilfs_sb_info *sbi = nilfs_get_writer(nilfs);
+ size_t nmembs = argv->v_nmembs;
+ struct nilfs_sb_info *sbi = nilfs->ns_writer;
int ret;
- if (unlikely(!sbi))
+ if (unlikely(!sbi)) {
+ /* never happens because called for a writable mount */
+ WARN_ON(1);
return -EROFS;
+ }
ret = nilfs_segctor_add_segments_to_be_freed(
NILFS_SC(sbi), buf, nmembs);
- nilfs_put_writer(nilfs);
return (ret < 0) ? ret : nmembs;
}
-static inline int nilfs_ioctl_free_segments(struct the_nilfs *nilfs,
- struct nilfs_argv *argv,
- int dir)
-{
- return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
- nilfs_ioctl_do_free_segments);
-}
-
int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
- void __user *argp)
+ struct nilfs_argv *argv, void **kbufs)
{
- struct nilfs_argv argv[5];
const char *msg;
- int dir, ret;
-
- if (copy_from_user(argv, argp, sizeof(argv)))
- return -EFAULT;
+ int ret;
- dir = _IOC_WRITE;
- ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], dir);
+ ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], kbufs[0]);
if (ret < 0) {
msg = "cannot read source blocks";
goto failed;
}
- ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], dir);
+
+ ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]);
if (ret < 0) {
/*
* can safely abort because checkpoints can be removed
@@ -561,7 +474,7 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
msg = "cannot delete checkpoints";
goto failed;
}
- ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], dir);
+ ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], kbufs[2]);
if (ret < 0) {
/*
* can safely abort because DAT file is updated atomically
@@ -570,7 +483,7 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
msg = "cannot delete virtual blocks from DAT file";
goto failed;
}
- ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], dir);
+ ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], kbufs[3]);
if (ret < 0) {
/*
* can safely abort because the operation is nondestructive.
@@ -578,7 +491,7 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
msg = "cannot mark copying blocks dirty";
goto failed;
}
- ret = nilfs_ioctl_free_segments(nilfs, &argv[4], dir);
+ ret = nilfs_ioctl_free_segments(nilfs, &argv[4], kbufs[4]);
if (ret < 0) {
/*
* can safely abort because this operation is atomic.
@@ -598,9 +511,75 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
unsigned int cmd, void __user *argp)
{
+ struct nilfs_argv argv[5];
+ const static size_t argsz[5] = {
+ sizeof(struct nilfs_vdesc),
+ sizeof(struct nilfs_period),
+ sizeof(__u64),
+ sizeof(struct nilfs_bdesc),
+ sizeof(__u64),
+ };
+ void __user *base;
+ void *kbufs[5];
+ struct the_nilfs *nilfs;
+ size_t len, nsegs;
+ int n, ret;
+
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- return nilfs_clean_segments(inode->i_sb, argp);
+
+ if (copy_from_user(argv, argp, sizeof(argv)))
+ return -EFAULT;
+
+ nsegs = argv[4].v_nmembs;
+ if (argv[4].v_size != argsz[4])
+ return -EINVAL;
+ /*
+ * argv[4] points to segment numbers this ioctl cleans. We
+ * use kmalloc() for its buffer because memory used for the
+ * segment numbers is enough small.
+ */
+ kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base,
+ nsegs * sizeof(__u64));
+ if (IS_ERR(kbufs[4]))
+ return PTR_ERR(kbufs[4]);
+
+ nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+
+ for (n = 0; n < 4; n++) {
+ ret = -EINVAL;
+ if (argv[n].v_size != argsz[n])
+ goto out_free;
+
+ if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment)
+ goto out_free;
+
+ len = argv[n].v_size * argv[n].v_nmembs;
+ base = (void __user *)(unsigned long)argv[n].v_base;
+ if (len == 0) {
+ kbufs[n] = NULL;
+ continue;
+ }
+
+ kbufs[n] = vmalloc(len);
+ if (!kbufs[n]) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+ if (copy_from_user(kbufs[n], base, len)) {
+ ret = -EFAULT;
+ vfree(kbufs[n]);
+ goto out_free;
+ }
+ }
+
+ ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
+
+ out_free:
+ while (--n > 0)
+ vfree(kbufs[n]);
+ kfree(kbufs[4]);
+ return ret;
}
static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
@@ -621,6 +600,33 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
return 0;
}
+static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp,
+ size_t membsz,
+ ssize_t (*dofunc)(struct the_nilfs *,
+ __u64 *, int,
+ void *, size_t, size_t))
+
+{
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+ struct nilfs_argv argv;
+ int ret;
+
+ if (copy_from_user(&argv, argp, sizeof(argv)))
+ return -EFAULT;
+
+ if (argv.v_size != membsz)
+ return -EINVAL;
+
+ ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(argp, &argv, sizeof(argv)))
+ ret = -EFAULT;
+ return ret;
+}
+
long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct inode *inode = filp->f_dentry->d_inode;
@@ -632,16 +638,21 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
case NILFS_IOCTL_DELETE_CHECKPOINT:
return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp);
case NILFS_IOCTL_GET_CPINFO:
- return nilfs_ioctl_get_cpinfo(inode, filp, cmd, argp);
+ return nilfs_ioctl_get_info(inode, filp, cmd, argp,
+ sizeof(struct nilfs_cpinfo),
+ nilfs_ioctl_do_get_cpinfo);
case NILFS_IOCTL_GET_CPSTAT:
return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp);
case NILFS_IOCTL_GET_SUINFO:
- return nilfs_ioctl_get_suinfo(inode, filp, cmd, argp);
+ return nilfs_ioctl_get_info(inode, filp, cmd, argp,
+ sizeof(struct nilfs_suinfo),
+ nilfs_ioctl_do_get_suinfo);
case NILFS_IOCTL_GET_SUSTAT:
return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
case NILFS_IOCTL_GET_VINFO:
- /* XXX: rename to ??? */
- return nilfs_ioctl_get_vinfo(inode, filp, cmd, argp);
+ return nilfs_ioctl_get_info(inode, filp, cmd, argp,
+ sizeof(struct nilfs_vinfo),
+ nilfs_ioctl_do_get_vinfo);
case NILFS_IOCTL_GET_BDESCS:
return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp);
case NILFS_IOCTL_CLEAN_SEGMENTS:
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 47dd815433fd..bb78745a0e30 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -77,19 +77,22 @@ static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,
void *))
{
struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs;
- struct nilfs_sb_info *writer = NULL;
struct super_block *sb = inode->i_sb;
struct nilfs_transaction_info ti;
struct buffer_head *bh;
int err;
if (!sb) {
- writer = nilfs_get_writer(nilfs);
- if (!writer) {
+ /*
+ * Make sure this function is not called from any
+ * read-only context.
+ */
+ if (!nilfs->ns_writer) {
+ WARN_ON(1);
err = -EROFS;
goto out;
}
- sb = writer->s_super;
+ sb = nilfs->ns_writer->s_super;
}
nilfs_transaction_begin(sb, &ti, 0);
@@ -127,8 +130,6 @@ static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,
err = nilfs_transaction_commit(sb);
else
nilfs_transaction_abort(sb);
- if (writer)
- nilfs_put_writer(nilfs);
out:
return err;
}
@@ -299,7 +300,7 @@ int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)
int err;
err = nilfs_bmap_delete(ii->i_bmap, block);
- if (likely(!err)) {
+ if (!err || err == -ENOENT) {
nilfs_mdt_mark_dirty(inode);
nilfs_mdt_forget_block(inode, block);
}
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index 3d0c18a16db1..da6fc0bba2e5 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -236,7 +236,8 @@ extern int nilfs_sync_file(struct file *, struct dentry *, int);
/* ioctl.c */
long nilfs_ioctl(struct file *, unsigned int, unsigned long);
-int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, void __user *);
+int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, struct nilfs_argv *,
+ void **);
/* inode.c */
extern struct inode *nilfs_new_inode(struct inode *, int);
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 1bfbba9c0e9a..a2692bbc7b50 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -128,7 +128,8 @@ void nilfs_forget_buffer(struct buffer_head *bh)
lock_buffer(bh);
clear_buffer_nilfs_volatile(bh);
- if (test_clear_buffer_dirty(bh) && nilfs_page_buffers_clean(page))
+ clear_buffer_dirty(bh);
+ if (nilfs_page_buffers_clean(page))
__nilfs_clear_page_dirty(page);
clear_buffer_uptodate(bh);
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index 4fc081e47d70..57afa9d24061 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -407,6 +407,7 @@ void nilfs_dispose_segment_list(struct list_head *head)
}
static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
+ struct nilfs_sb_info *sbi,
struct nilfs_recovery_info *ri)
{
struct list_head *head = &ri->ri_used_segments;
@@ -421,6 +422,7 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
segnum[2] = ri->ri_segnum;
segnum[3] = ri->ri_nextnum;
+ nilfs_attach_writer(nilfs, sbi);
/*
* Releasing the next segment of the latest super root.
* The next segment is invalidated by this recovery.
@@ -459,10 +461,10 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
nilfs->ns_pseg_offset = 0;
nilfs->ns_seg_seq = ri->ri_seq + 2;
nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0];
- return 0;
failed:
/* No need to recover sufile because it will be destroyed on error */
+ nilfs_detach_writer(nilfs, sbi);
return err;
}
@@ -728,7 +730,7 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
goto failed;
if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) {
- err = nilfs_prepare_segment_for_recovery(nilfs, ri);
+ err = nilfs_prepare_segment_for_recovery(nilfs, sbi, ri);
if (unlikely(err)) {
printk(KERN_ERR "NILFS: Error preparing segments for "
"recovery.\n");
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index fb70ec3be20e..22c7f65c2403 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2589,7 +2589,8 @@ nilfs_remove_written_gcinodes(struct the_nilfs *nilfs, struct list_head *head)
}
}
-int nilfs_clean_segments(struct super_block *sb, void __user *argp)
+int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
+ void **kbufs)
{
struct nilfs_sb_info *sbi = NILFS_SB(sb);
struct nilfs_sc_info *sci = NILFS_SC(sbi);
@@ -2606,7 +2607,7 @@ int nilfs_clean_segments(struct super_block *sb, void __user *argp)
err = nilfs_init_gcdat_inode(nilfs);
if (unlikely(err))
goto out_unlock;
- err = nilfs_ioctl_prepare_clean_segments(nilfs, argp);
+ err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs);
if (unlikely(err))
goto out_unlock;
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index a98fc1ed0bbb..476bdd5df5be 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -222,7 +222,8 @@ extern int nilfs_construct_segment(struct super_block *);
extern int nilfs_construct_dsync_segment(struct super_block *, struct inode *,
loff_t, loff_t);
extern void nilfs_flush_segment(struct super_block *, ino_t);
-extern int nilfs_clean_segments(struct super_block *, void __user *);
+extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *,
+ void **);
extern int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *,
__u64 *, size_t);
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 6989b03e97ab..7262e8427c20 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -65,6 +65,7 @@ MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem "
"(NILFS)");
MODULE_LICENSE("GPL");
+static void nilfs_write_super(struct super_block *sb);
static int nilfs_remount(struct super_block *sb, int *flags, char *data);
static int test_exclusive_mount(struct file_system_type *fs_type,
struct block_device *bdev, int flags);
@@ -315,6 +316,11 @@ static void nilfs_put_super(struct super_block *sb)
struct nilfs_sb_info *sbi = NILFS_SB(sb);
struct the_nilfs *nilfs = sbi->s_nilfs;
+ lock_kernel();
+
+ if (sb->s_dirt)
+ nilfs_write_super(sb);
+
nilfs_detach_segment_constructor(sbi);
if (!(sb->s_flags & MS_RDONLY)) {
@@ -329,6 +335,8 @@ static void nilfs_put_super(struct super_block *sb)
sbi->s_super = NULL;
sb->s_fs_info = NULL;
kfree(sbi);
+
+ unlock_kernel();
}
/**
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index bed766e435b5..1634319e2404 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -220,7 +220,7 @@ static struct inotify_kernel_event * kernel_event(s32 wd, u32 mask, u32 cookie,
rem = 0;
}
- kevent->name = kmalloc(len + rem, GFP_KERNEL);
+ kevent->name = kmalloc(len + rem, GFP_NOFS);
if (unlikely(!kevent->name)) {
kmem_cache_free(event_cachep, kevent);
return NULL;
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index f76951dcd4a6..8013eb36abc9 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -2246,6 +2246,9 @@ static void ntfs_put_super(struct super_block *sb)
ntfs_volume *vol = NTFS_SB(sb);
ntfs_debug("Entering.");
+
+ lock_kernel();
+
#ifdef NTFS_RW
/*
* Commit all inodes while they are still open in case some of them
@@ -2444,7 +2447,8 @@ static void ntfs_put_super(struct super_block *sb)
}
sb->s_fs_info = NULL;
kfree(vol);
- return;
+
+ unlock_kernel();
}
/**
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index 7e72a81bc2d4..696c32e50716 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -48,34 +48,33 @@
* only emit the appropriage printk() when the caller passes in a constant
* mask, as is almost always the case.
*
- * All this bitmask nonsense is hidden from the /proc interface so that Joel
- * doesn't have an aneurism. Reading the file gives a straight forward
- * indication of which bits are on or off:
- * ENTRY off
- * EXIT off
+ * All this bitmask nonsense is managed from the files under
+ * /sys/fs/o2cb/logmask/. Reading the files gives a straightforward
+ * indication of which bits are allowed (allow) or denied (off/deny).
+ * ENTRY deny
+ * EXIT deny
* TCP off
* MSG off
* SOCKET off
- * ERROR off
- * NOTICE on
+ * ERROR allow
+ * NOTICE allow
*
* Writing changes the state of a given bit and requires a strictly formatted
* single write() call:
*
- * write(fd, "ENTRY on", 8);
+ * write(fd, "allow", 5);
*
- * would turn the entry bit on. "1" is also accepted in the place of "on", and
- * "off" and "0" behave as expected.
+ * Echoing allow/deny/off string into the logmask files can flip the bits
+ * on or off as expected; here is the bash script for example:
*
- * Some trivial shell can flip all the bits on or off:
+ * log_mask="/sys/fs/o2cb/log_mask"
+ * for node in ENTRY EXIT TCP MSG SOCKET ERROR NOTICE; do
+ * echo allow >"$log_mask"/"$node"
+ * done
*
- * log_mask="/proc/fs/ocfs2_nodemanager/log_mask"
- * cat $log_mask | (
- * while read bit status; do
- * # $1 is "on" or "off", say
- * echo "$bit $1" > $log_mask
- * done
- * )
+ * The debugfs.ocfs2 tool can also flip the bits with the -l option:
+ *
+ * debugfs.ocfs2 -l TCP allow
*/
/* for task_struct */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 79ff8d9d37e0..4a79de13b663 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -126,7 +126,6 @@ static int ocfs2_get_sector(struct super_block *sb,
struct buffer_head **bh,
int block,
int sect_size);
-static void ocfs2_write_super(struct super_block *sb);
static struct inode *ocfs2_alloc_inode(struct super_block *sb);
static void ocfs2_destroy_inode(struct inode *inode);
static int ocfs2_susp_quotas(struct ocfs2_super *osb, int unsuspend);
@@ -141,7 +140,6 @@ static const struct super_operations ocfs2_sops = {
.clear_inode = ocfs2_clear_inode,
.delete_inode = ocfs2_delete_inode,
.sync_fs = ocfs2_sync_fs,
- .write_super = ocfs2_write_super,
.put_super = ocfs2_put_super,
.remount_fs = ocfs2_remount,
.show_options = ocfs2_show_options,
@@ -365,24 +363,12 @@ static struct file_operations ocfs2_osb_debug_fops = {
.llseek = generic_file_llseek,
};
-/*
- * write_super and sync_fs ripped right out of ext3.
- */
-static void ocfs2_write_super(struct super_block *sb)
-{
- if (mutex_trylock(&sb->s_lock) != 0)
- BUG();
- sb->s_dirt = 0;
-}
-
static int ocfs2_sync_fs(struct super_block *sb, int wait)
{
int status;
tid_t target;
struct ocfs2_super *osb = OCFS2_SB(sb);
- sb->s_dirt = 0;
-
if (ocfs2_is_hard_readonly(osb))
return -EROFS;
@@ -1550,9 +1536,13 @@ static void ocfs2_put_super(struct super_block *sb)
{
mlog_entry("(0x%p)\n", sb);
+ lock_kernel();
+
ocfs2_sync_blockdev(sb);
ocfs2_dismount_volume(sb, 0);
+ unlock_kernel();
+
mlog_exit_void();
}
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index ed0a0cfd68d2..579dd1b1110f 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -39,6 +39,7 @@
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/utsname.h>
+#include <linux/namei.h>
#define MLOG_MASK_PREFIX ML_NAMEI
#include <cluster/masklog.h>
@@ -54,26 +55,6 @@
#include "buffer_head_io.h"
-static char *ocfs2_page_getlink(struct dentry * dentry,
- struct page **ppage);
-static char *ocfs2_fast_symlink_getlink(struct inode *inode,
- struct buffer_head **bh);
-
-/* get the link contents into pagecache */
-static char *ocfs2_page_getlink(struct dentry * dentry,
- struct page **ppage)
-{
- struct page * page;
- struct address_space *mapping = dentry->d_inode->i_mapping;
- page = read_mapping_page(mapping, 0, NULL);
- if (IS_ERR(page))
- goto sync_fail;
- *ppage = page;
- return kmap(page);
-
-sync_fail:
- return (char*)page;
-}
static char *ocfs2_fast_symlink_getlink(struct inode *inode,
struct buffer_head **bh)
@@ -128,40 +109,55 @@ out:
return ret;
}
-static void *ocfs2_follow_link(struct dentry *dentry,
- struct nameidata *nd)
+static void *ocfs2_fast_follow_link(struct dentry *dentry,
+ struct nameidata *nd)
{
- int status;
- char *link;
+ int status = 0;
+ int len;
+ char *target, *link = ERR_PTR(-ENOMEM);
struct inode *inode = dentry->d_inode;
- struct page *page = NULL;
struct buffer_head *bh = NULL;
-
- if (ocfs2_inode_is_fast_symlink(inode))
- link = ocfs2_fast_symlink_getlink(inode, &bh);
- else
- link = ocfs2_page_getlink(dentry, &page);
- if (IS_ERR(link)) {
- status = PTR_ERR(link);
+
+ mlog_entry_void();
+
+ BUG_ON(!ocfs2_inode_is_fast_symlink(inode));
+ target = ocfs2_fast_symlink_getlink(inode, &bh);
+ if (IS_ERR(target)) {
+ status = PTR_ERR(target);
mlog_errno(status);
goto bail;
}
- status = vfs_follow_link(nd, link);
+ /* Fast symlinks can't be large */
+ len = strlen(target);
+ link = kzalloc(len + 1, GFP_NOFS);
+ if (!link) {
+ status = -ENOMEM;
+ mlog_errno(status);
+ goto bail;
+ }
+
+ memcpy(link, target, len);
+ nd_set_link(nd, link);
bail:
- if (page) {
- kunmap(page);
- page_cache_release(page);
- }
brelse(bh);
- return ERR_PTR(status);
+ mlog_exit(status);
+ return status ? ERR_PTR(status) : link;
+}
+
+static void ocfs2_fast_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
+{
+ char *link = cookie;
+
+ kfree(link);
}
const struct inode_operations ocfs2_symlink_inode_operations = {
.readlink = page_readlink,
- .follow_link = ocfs2_follow_link,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
.getattr = ocfs2_getattr,
.setattr = ocfs2_setattr,
.setxattr = generic_setxattr,
@@ -171,7 +167,8 @@ const struct inode_operations ocfs2_symlink_inode_operations = {
};
const struct inode_operations ocfs2_fast_symlink_inode_operations = {
.readlink = ocfs2_readlink,
- .follow_link = ocfs2_follow_link,
+ .follow_link = ocfs2_fast_follow_link,
+ .put_link = ocfs2_fast_put_link,
.getattr = ocfs2_getattr,
.setattr = ocfs2_setattr,
.setxattr = generic_setxattr,
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 15631019dc63..ba320e250747 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -3154,7 +3154,7 @@ static int ocfs2_iterate_xattr_buckets(struct inode *inode,
le32_to_cpu(bucket_xh(bucket)->xh_entries[0].xe_name_hash));
if (func) {
ret = func(inode, bucket, para);
- if (ret)
+ if (ret && ret != -ERANGE)
mlog_errno(ret);
/* Fall through to bucket_relse() */
}
@@ -3261,7 +3261,8 @@ static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
ocfs2_list_xattr_bucket,
&xl);
if (ret) {
- mlog_errno(ret);
+ if (ret != -ERANGE)
+ mlog_errno(ret);
goto out;
}
diff --git a/fs/open.c b/fs/open.c
index 377eb25b6abf..7200e23d9258 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -612,7 +612,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
audit_inode(NULL, dentry);
- err = mnt_want_write(file->f_path.mnt);
+ err = mnt_want_write_file(file);
if (err)
goto out_putf;
mutex_lock(&inode->i_mutex);
@@ -761,7 +761,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
if (!file)
goto out;
- error = mnt_want_write(file->f_path.mnt);
+ error = mnt_want_write_file(file);
if (error)
goto out_fput;
dentry = file->f_path.dentry;
@@ -1033,7 +1033,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
if (!IS_ERR(tmp)) {
fd = get_unused_fd_flags(flags);
if (fd >= 0) {
- struct file *f = do_filp_open(dfd, tmp, flags, mode);
+ struct file *f = do_filp_open(dfd, tmp, flags, mode, 0);
if (IS_ERR(f)) {
put_unused_fd(fd);
fd = PTR_ERR(f);
diff --git a/fs/pipe.c b/fs/pipe.c
index 13414ec45b8d..f7dd21ad85a6 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -302,6 +302,20 @@ int generic_pipe_buf_confirm(struct pipe_inode_info *info,
return 0;
}
+/**
+ * generic_pipe_buf_release - put a reference to a &struct pipe_buffer
+ * @pipe: the pipe that the buffer belongs to
+ * @buf: the buffer to put a reference to
+ *
+ * Description:
+ * This function releases a reference to @buf.
+ */
+void generic_pipe_buf_release(struct pipe_inode_info *pipe,
+ struct pipe_buffer *buf)
+{
+ page_cache_release(buf->page);
+}
+
static const struct pipe_buf_operations anon_pipe_buf_ops = {
.can_merge = 1,
.map = generic_pipe_buf_map,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index fb45615943c2..23342e188a66 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2128,9 +2128,15 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
if (copy_from_user(page, buf, count))
goto out_free;
+ /* Guard against adverse ptrace interaction */
+ length = mutex_lock_interruptible(&task->cred_guard_mutex);
+ if (length < 0)
+ goto out_free;
+
length = security_setprocattr(task,
(char*)file->f_path.dentry->d_name.name,
(void*)page, count);
+ mutex_unlock(&task->cred_guard_mutex);
out_free:
free_page((unsigned long) page);
out:
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index f6db9618a888..753ca37002c8 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -92,3 +92,28 @@ struct pde_opener {
struct list_head lh;
};
void pde_users_dec(struct proc_dir_entry *pde);
+
+extern spinlock_t proc_subdir_lock;
+
+struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *);
+int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir);
+unsigned long task_vsize(struct mm_struct *);
+int task_statm(struct mm_struct *, int *, int *, int *, int *);
+void task_mem(struct seq_file *, struct mm_struct *);
+
+struct proc_dir_entry *de_get(struct proc_dir_entry *de);
+void de_put(struct proc_dir_entry *de);
+
+extern struct vfsmount *proc_mnt;
+int proc_fill_super(struct super_block *);
+struct inode *proc_get_inode(struct super_block *, unsigned int, struct proc_dir_entry *);
+
+/*
+ * These are generic /proc routines that use the internal
+ * "struct proc_dir_entry" tree to traverse the filesystem.
+ *
+ * The /proc root directory has extended versions to take care
+ * of the /proc/<pid> subdirectories.
+ */
+int proc_readdir(struct file *, void *, filldir_t);
+struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *);
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index de2bba5a3440..fc6c3025befd 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -11,6 +11,7 @@
#include <linux/string.h>
#include <asm/prom.h>
#include <asm/uaccess.h>
+#include "internal.h"
#ifndef HAVE_ARCH_DEVTREE_FIXUPS
static inline void set_node_proc_entry(struct device_node *np,
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 1e15a2b176e8..b080b791d9e3 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -67,8 +67,7 @@ static int proc_get_sb(struct file_system_type *fs_type,
sb->s_flags = flags;
err = proc_fill_super(sb);
if (err) {
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ deactivate_locked_super(sb);
return err;
}
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index fe1f0f31d11c..95c12fc613f1 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -70,14 +70,6 @@ static void qnx4_delete_inode(struct inode *inode)
unlock_kernel();
}
-static void qnx4_write_super(struct super_block *sb)
-{
- lock_kernel();
- QNX4DEBUG(("qnx4: write_super\n"));
- sb->s_dirt = 0;
- unlock_kernel();
-}
-
static int qnx4_write_inode(struct inode *inode, int unused)
{
struct qnx4_inode_entry *raw_inode;
@@ -138,7 +130,6 @@ static const struct super_operations qnx4_sops =
#ifdef CONFIG_QNX4FS_RW
.write_inode = qnx4_write_inode,
.delete_inode = qnx4_delete_inode,
- .write_super = qnx4_write_super,
#endif
};
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index b7f5a468f076..95c5b42384b2 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -159,10 +159,14 @@ static int check_quotactl_valid(struct super_block *sb, int type, int cmd,
return error;
}
-static void quota_sync_sb(struct super_block *sb, int type)
+#ifdef CONFIG_QUOTA
+void sync_quota_sb(struct super_block *sb, int type)
{
int cnt;
+ if (!sb->s_qcop->quota_sync)
+ return;
+
sb->s_qcop->quota_sync(sb, type);
if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)
@@ -191,17 +195,13 @@ static void quota_sync_sb(struct super_block *sb, int type)
}
mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
}
+#endif
-void sync_dquots(struct super_block *sb, int type)
+static void sync_dquots(int type)
{
+ struct super_block *sb;
int cnt;
- if (sb) {
- if (sb->s_qcop->quota_sync)
- quota_sync_sb(sb, type);
- return;
- }
-
spin_lock(&sb_lock);
restart:
list_for_each_entry(sb, &super_blocks, s_list) {
@@ -222,8 +222,8 @@ restart:
sb->s_count++;
spin_unlock(&sb_lock);
down_read(&sb->s_umount);
- if (sb->s_root && sb->s_qcop->quota_sync)
- quota_sync_sb(sb, type);
+ if (sb->s_root)
+ sync_quota_sb(sb, type);
up_read(&sb->s_umount);
spin_lock(&sb_lock);
if (__put_super_and_need_restart(sb))
@@ -301,7 +301,10 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
return sb->s_qcop->set_dqblk(sb, type, id, &idq);
}
case Q_SYNC:
- sync_dquots(sb, type);
+ if (sb)
+ sync_quota_sb(sb, type);
+ else
+ sync_dquots(type);
return 0;
case Q_XQUOTAON:
diff --git a/fs/read_write.c b/fs/read_write.c
index 9d1e76bb9ee1..6c8c55dec2bc 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -805,12 +805,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
goto out;
if (!(in_file->f_mode & FMODE_READ))
goto fput_in;
- retval = -EINVAL;
- in_inode = in_file->f_path.dentry->d_inode;
- if (!in_inode)
- goto fput_in;
- if (!in_file->f_op || !in_file->f_op->splice_read)
- goto fput_in;
retval = -ESPIPE;
if (!ppos)
ppos = &in_file->f_pos;
@@ -834,6 +828,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
retval = -EINVAL;
if (!out_file->f_op || !out_file->f_op->sendpage)
goto fput_out;
+ in_inode = in_file->f_path.dentry->d_inode;
out_inode = out_file->f_path.dentry->d_inode;
retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
if (retval < 0)
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 67a80d7e59e2..6d2668fdc384 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -41,6 +41,16 @@ static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
#define store_ih(where,what) copy_item_head (where, what)
+static inline bool is_privroot_deh(struct dentry *dir,
+ struct reiserfs_de_head *deh)
+{
+ struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root;
+ if (reiserfs_expose_privroot(dir->d_sb))
+ return 0;
+ return (dir == dir->d_parent && privroot->d_inode &&
+ deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid);
+}
+
int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent,
filldir_t filldir, loff_t *pos)
{
@@ -138,18 +148,8 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent,
}
/* Ignore the .reiserfs_priv entry */
- if (reiserfs_xattrs(inode->i_sb) &&
- !old_format_only(inode->i_sb) &&
- dentry == inode->i_sb->s_root &&
- REISERFS_SB(inode->i_sb)->priv_root &&
- REISERFS_SB(inode->i_sb)->priv_root->d_inode
- && deh_objectid(deh) ==
- le32_to_cpu(INODE_PKEY
- (REISERFS_SB(inode->i_sb)->
- priv_root->d_inode)->
- k_objectid)) {
+ if (is_privroot_deh(dentry, deh))
continue;
- }
d_off = deh_offset(deh);
*pos = d_off;
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index efd4d720718e..271579128634 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -338,21 +338,8 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
&path_to_entry, &de);
pathrelse(&path_to_entry);
if (retval == NAME_FOUND) {
- /* Hide the .reiserfs_priv directory */
- if (reiserfs_xattrs(dir->i_sb) &&
- !old_format_only(dir->i_sb) &&
- REISERFS_SB(dir->i_sb)->priv_root &&
- REISERFS_SB(dir->i_sb)->priv_root->d_inode &&
- de.de_objectid ==
- le32_to_cpu(INODE_PKEY
- (REISERFS_SB(dir->i_sb)->priv_root->d_inode)->
- k_objectid)) {
- reiserfs_write_unlock(dir->i_sb);
- return ERR_PTR(-EACCES);
- }
-
- inode =
- reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
+ inode = reiserfs_iget(dir->i_sb,
+ (struct cpu_key *)&(de.de_dir_id));
if (!inode || IS_ERR(inode)) {
reiserfs_write_unlock(dir->i_sb);
return ERR_PTR(-EACCES);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 0ae6486d9046..90dcb7b033ea 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -64,18 +64,15 @@ static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf);
static int reiserfs_sync_fs(struct super_block *s, int wait)
{
- if (!(s->s_flags & MS_RDONLY)) {
- struct reiserfs_transaction_handle th;
- reiserfs_write_lock(s);
- if (!journal_begin(&th, s, 1))
- if (!journal_end_sync(&th, s, 1))
- reiserfs_flush_old_commits(s);
- s->s_dirt = 0; /* Even if it's not true.
- * We'll loop forever in sync_supers otherwise */
- reiserfs_write_unlock(s);
- } else {
- s->s_dirt = 0;
- }
+ struct reiserfs_transaction_handle th;
+
+ reiserfs_write_lock(s);
+ if (!journal_begin(&th, s, 1))
+ if (!journal_end_sync(&th, s, 1))
+ reiserfs_flush_old_commits(s);
+ s->s_dirt = 0; /* Even if it's not true.
+ * We'll loop forever in sync_supers otherwise */
+ reiserfs_write_unlock(s);
return 0;
}
@@ -448,13 +445,11 @@ int remove_save_link(struct inode *inode, int truncate)
static void reiserfs_kill_sb(struct super_block *s)
{
if (REISERFS_SB(s)) {
-#ifdef CONFIG_REISERFS_FS_XATTR
if (REISERFS_SB(s)->xattr_root) {
d_invalidate(REISERFS_SB(s)->xattr_root);
dput(REISERFS_SB(s)->xattr_root);
REISERFS_SB(s)->xattr_root = NULL;
}
-#endif
if (REISERFS_SB(s)->priv_root) {
d_invalidate(REISERFS_SB(s)->priv_root);
dput(REISERFS_SB(s)->priv_root);
@@ -470,6 +465,11 @@ static void reiserfs_put_super(struct super_block *s)
struct reiserfs_transaction_handle th;
th.t_trans_id = 0;
+ lock_kernel();
+
+ if (s->s_dirt)
+ reiserfs_write_super(s);
+
/* change file system state to current state if it was mounted with read-write permissions */
if (!(s->s_flags & MS_RDONLY)) {
if (!journal_begin(&th, s, 10)) {
@@ -502,7 +502,7 @@ static void reiserfs_put_super(struct super_block *s)
kfree(s->s_fs_info);
s->s_fs_info = NULL;
- return;
+ unlock_kernel();
}
static struct kmem_cache *reiserfs_inode_cachep;
@@ -900,6 +900,7 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
{"conv",.setmask = 1 << REISERFS_CONVERT},
{"attrs",.setmask = 1 << REISERFS_ATTRS},
{"noattrs",.clrmask = 1 << REISERFS_ATTRS},
+ {"expose_privroot", .setmask = 1 << REISERFS_EXPOSE_PRIVROOT},
#ifdef CONFIG_REISERFS_FS_XATTR
{"user_xattr",.setmask = 1 << REISERFS_XATTRS_USER},
{"nouser_xattr",.clrmask = 1 << REISERFS_XATTRS_USER},
@@ -1316,8 +1317,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
}
out_ok:
- kfree(s->s_options);
- s->s_options = new_opts;
+ replace_mount_options(s, new_opts);
return 0;
out_err:
@@ -1842,7 +1842,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
goto error;
}
- if ((errval = reiserfs_xattr_init(s, s->s_flags))) {
+ if ((errval = reiserfs_lookup_privroot(s)) ||
+ (errval = reiserfs_xattr_init(s, s->s_flags))) {
dput(s->s_root);
s->s_root = NULL;
goto error;
@@ -1855,7 +1856,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
reiserfs_info(s, "using 3.5.x disk format\n");
}
- if ((errval = reiserfs_xattr_init(s, s->s_flags))) {
+ if ((errval = reiserfs_lookup_privroot(s)) ||
+ (errval = reiserfs_xattr_init(s, s->s_flags))) {
dput(s->s_root);
s->s_root = NULL;
goto error;
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index f83f52bae390..28dabc60bbad 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -113,41 +113,30 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry)
#define xattr_may_create(flags) (!flags || flags & XATTR_CREATE)
-/* Returns and possibly creates the xattr dir. */
-static struct dentry *lookup_or_create_dir(struct dentry *parent,
- const char *name, int flags)
+static struct dentry *open_xa_root(struct super_block *sb, int flags)
{
- struct dentry *dentry;
- BUG_ON(!parent);
-
- dentry = lookup_one_len(name, parent, strlen(name));
- if (IS_ERR(dentry))
- return dentry;
- else if (!dentry->d_inode) {
- int err = -ENODATA;
+ struct dentry *privroot = REISERFS_SB(sb)->priv_root;
+ struct dentry *xaroot;
+ if (!privroot->d_inode)
+ return ERR_PTR(-ENODATA);
- if (xattr_may_create(flags)) {
- mutex_lock_nested(&parent->d_inode->i_mutex,
- I_MUTEX_XATTR);
- err = xattr_mkdir(parent->d_inode, dentry, 0700);
- mutex_unlock(&parent->d_inode->i_mutex);
- }
+ mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR);
+ xaroot = dget(REISERFS_SB(sb)->xattr_root);
+ if (!xaroot)
+ xaroot = ERR_PTR(-ENODATA);
+ else if (!xaroot->d_inode) {
+ int err = -ENODATA;
+ if (xattr_may_create(flags))
+ err = xattr_mkdir(privroot->d_inode, xaroot, 0700);
if (err) {
- dput(dentry);
- dentry = ERR_PTR(err);
+ dput(xaroot);
+ xaroot = ERR_PTR(err);
}
}
- return dentry;
-}
-
-static struct dentry *open_xa_root(struct super_block *sb, int flags)
-{
- struct dentry *privroot = REISERFS_SB(sb)->priv_root;
- if (!privroot)
- return ERR_PTR(-ENODATA);
- return lookup_or_create_dir(privroot, XAROOT_NAME, flags);
+ mutex_unlock(&privroot->d_inode->i_mutex);
+ return xaroot;
}
static struct dentry *open_xa_dir(const struct inode *inode, int flags)
@@ -163,10 +152,22 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags)
le32_to_cpu(INODE_PKEY(inode)->k_objectid),
inode->i_generation);
- xadir = lookup_or_create_dir(xaroot, namebuf, flags);
+ mutex_lock_nested(&xaroot->d_inode->i_mutex, I_MUTEX_XATTR);
+
+ xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf));
+ if (!IS_ERR(xadir) && !xadir->d_inode) {
+ int err = -ENODATA;
+ if (xattr_may_create(flags))
+ err = xattr_mkdir(xaroot->d_inode, xadir, 0700);
+ if (err) {
+ dput(xadir);
+ xadir = ERR_PTR(err);
+ }
+ }
+
+ mutex_unlock(&xaroot->d_inode->i_mutex);
dput(xaroot);
return xadir;
-
}
/* The following are side effects of other operations that aren't explicitly
@@ -184,6 +185,7 @@ fill_with_dentries(void *buf, const char *name, int namelen, loff_t offset,
{
struct reiserfs_dentry_buf *dbuf = buf;
struct dentry *dentry;
+ WARN_ON_ONCE(!mutex_is_locked(&dbuf->xadir->d_inode->i_mutex));
if (dbuf->count == ARRAY_SIZE(dbuf->dentries))
return -ENOSPC;
@@ -349,6 +351,7 @@ static struct dentry *xattr_lookup(struct inode *inode, const char *name,
if (IS_ERR(xadir))
return ERR_CAST(xadir);
+ mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR);
xafile = lookup_one_len(name, xadir, strlen(name));
if (IS_ERR(xafile)) {
err = PTR_ERR(xafile);
@@ -360,18 +363,15 @@ static struct dentry *xattr_lookup(struct inode *inode, const char *name,
if (!xafile->d_inode) {
err = -ENODATA;
- if (xattr_may_create(flags)) {
- mutex_lock_nested(&xadir->d_inode->i_mutex,
- I_MUTEX_XATTR);
+ if (xattr_may_create(flags))
err = xattr_create(xadir->d_inode, xafile,
0700|S_IFREG);
- mutex_unlock(&xadir->d_inode->i_mutex);
- }
}
if (err)
dput(xafile);
out:
+ mutex_unlock(&xadir->d_inode->i_mutex);
dput(xadir);
if (err)
return ERR_PTR(err);
@@ -435,6 +435,7 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name)
if (IS_ERR(xadir))
return PTR_ERR(xadir);
+ mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR);
dentry = lookup_one_len(name, xadir, strlen(name));
if (IS_ERR(dentry)) {
err = PTR_ERR(dentry);
@@ -442,14 +443,13 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name)
}
if (dentry->d_inode) {
- mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR);
err = xattr_unlink(xadir->d_inode, dentry);
- mutex_unlock(&xadir->d_inode->i_mutex);
update_ctime(inode);
}
dput(dentry);
out_dput:
+ mutex_unlock(&xadir->d_inode->i_mutex);
dput(xadir);
return err;
}
@@ -687,20 +687,6 @@ out:
return err;
}
-/* Actual operations that are exported to VFS-land */
-struct xattr_handler *reiserfs_xattr_handlers[] = {
- &reiserfs_xattr_user_handler,
- &reiserfs_xattr_trusted_handler,
-#ifdef CONFIG_REISERFS_FS_SECURITY
- &reiserfs_xattr_security_handler,
-#endif
-#ifdef CONFIG_REISERFS_FS_POSIX_ACL
- &reiserfs_posix_acl_access_handler,
- &reiserfs_posix_acl_default_handler,
-#endif
- NULL
-};
-
/*
* In order to implement different sets of xattr operations for each xattr
* prefix with the generic xattr API, a filesystem should create a
@@ -843,7 +829,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
if (!dentry->d_inode)
return -EINVAL;
- if (!reiserfs_xattrs(dentry->d_sb) ||
+ if (!dentry->d_sb->s_xattr ||
get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
return -EOPNOTSUPP;
@@ -885,42 +871,50 @@ static int reiserfs_check_acl(struct inode *inode, int mask)
return error;
}
-int reiserfs_permission(struct inode *inode, int mask)
-{
- /*
- * We don't do permission checks on the internal objects.
- * Permissions are determined by the "owning" object.
- */
- if (IS_PRIVATE(inode))
- return 0;
- /*
- * Stat data v1 doesn't support ACLs.
- */
- if (get_inode_sd_version(inode) == STAT_DATA_V1)
- return generic_permission(inode, mask, NULL);
- else
- return generic_permission(inode, mask, reiserfs_check_acl);
-}
-
static int create_privroot(struct dentry *dentry)
{
int err;
struct inode *inode = dentry->d_parent->d_inode;
- mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR);
+ WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
+
err = xattr_mkdir(inode, dentry, 0700);
- mutex_unlock(&inode->i_mutex);
- if (err) {
- dput(dentry);
- dentry = NULL;
+ if (err || !dentry->d_inode) {
+ reiserfs_warning(dentry->d_sb, "jdm-20006",
+ "xattrs/ACLs enabled and couldn't "
+ "find/create .reiserfs_priv. "
+ "Failing mount.");
+ return -EOPNOTSUPP;
}
- if (dentry && dentry->d_inode)
- reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
- "storage.\n", PRIVROOT_NAME);
+ dentry->d_inode->i_flags |= S_PRIVATE;
+ reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
+ "storage.\n", PRIVROOT_NAME);
- return err;
+ return 0;
}
+#else
+int __init reiserfs_xattr_register_handlers(void) { return 0; }
+void reiserfs_xattr_unregister_handlers(void) {}
+static int create_privroot(struct dentry *dentry) { return 0; }
+#endif
+
+/* Actual operations that are exported to VFS-land */
+struct xattr_handler *reiserfs_xattr_handlers[] = {
+#ifdef CONFIG_REISERFS_FS_XATTR
+ &reiserfs_xattr_user_handler,
+ &reiserfs_xattr_trusted_handler,
+#endif
+#ifdef CONFIG_REISERFS_FS_SECURITY
+ &reiserfs_xattr_security_handler,
+#endif
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
+ &reiserfs_posix_acl_access_handler,
+ &reiserfs_posix_acl_default_handler,
+#endif
+ NULL
+};
+
static int xattr_mount_check(struct super_block *s)
{
/* We need generation numbers to ensure that the oid mapping is correct
@@ -940,21 +934,34 @@ static int xattr_mount_check(struct super_block *s)
return 0;
}
-#else
-int __init reiserfs_xattr_register_handlers(void) { return 0; }
-void reiserfs_xattr_unregister_handlers(void) {}
+int reiserfs_permission(struct inode *inode, int mask)
+{
+ /*
+ * We don't do permission checks on the internal objects.
+ * Permissions are determined by the "owning" object.
+ */
+ if (IS_PRIVATE(inode))
+ return 0;
+
+#ifdef CONFIG_REISERFS_FS_XATTR
+ /*
+ * Stat data v1 doesn't support ACLs.
+ */
+ if (get_inode_sd_version(inode) != STAT_DATA_V1)
+ return generic_permission(inode, mask, reiserfs_check_acl);
#endif
+ return generic_permission(inode, mask, NULL);
+}
+
/* This will catch lookups from the fs root to .reiserfs_priv */
static int
xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
{
struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root;
- if (name->len == priv_root->d_name.len &&
- name->hash == priv_root->d_name.hash &&
- !memcmp(name->name, priv_root->d_name.name, name->len)) {
+ if (container_of(q1, struct dentry, d_name) == priv_root)
return -ENOENT;
- } else if (q1->len == name->len &&
+ if (q1->len == name->len &&
!memcmp(q1->name, name->name, name->len))
return 0;
return 1;
@@ -964,73 +971,72 @@ static const struct dentry_operations xattr_lookup_poison_ops = {
.d_compare = xattr_lookup_poison,
};
+int reiserfs_lookup_privroot(struct super_block *s)
+{
+ struct dentry *dentry;
+ int err = 0;
+
+ /* If we don't have the privroot located yet - go find it */
+ mutex_lock(&s->s_root->d_inode->i_mutex);
+ dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
+ strlen(PRIVROOT_NAME));
+ if (!IS_ERR(dentry)) {
+ REISERFS_SB(s)->priv_root = dentry;
+ if (!reiserfs_expose_privroot(s))
+ s->s_root->d_op = &xattr_lookup_poison_ops;
+ if (dentry->d_inode)
+ dentry->d_inode->i_flags |= S_PRIVATE;
+ } else
+ err = PTR_ERR(dentry);
+ mutex_unlock(&s->s_root->d_inode->i_mutex);
+
+ return err;
+}
+
/* We need to take a copy of the mount flags since things like
* MS_RDONLY don't get set until *after* we're called.
* mount_flags != mount_options */
int reiserfs_xattr_init(struct super_block *s, int mount_flags)
{
int err = 0;
+ struct dentry *privroot = REISERFS_SB(s)->priv_root;
-#ifdef CONFIG_REISERFS_FS_XATTR
err = xattr_mount_check(s);
if (err)
goto error;
-#endif
-
- /* If we don't have the privroot located yet - go find it */
- if (!REISERFS_SB(s)->priv_root) {
- struct dentry *dentry;
- dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
- strlen(PRIVROOT_NAME));
- if (!IS_ERR(dentry)) {
-#ifdef CONFIG_REISERFS_FS_XATTR
- if (!(mount_flags & MS_RDONLY) && !dentry->d_inode)
- err = create_privroot(dentry);
-#endif
- if (!dentry->d_inode) {
- dput(dentry);
- dentry = NULL;
- }
- } else
- err = PTR_ERR(dentry);
- if (!err && dentry) {
- s->s_root->d_op = &xattr_lookup_poison_ops;
- dentry->d_inode->i_flags |= S_PRIVATE;
- REISERFS_SB(s)->priv_root = dentry;
-#ifdef CONFIG_REISERFS_FS_XATTR
- /* xattrs are unavailable */
- } else if (!(mount_flags & MS_RDONLY)) {
- /* If we're read-only it just means that the dir
- * hasn't been created. Not an error -- just no
- * xattrs on the fs. We'll check again if we
- * go read-write */
- reiserfs_warning(s, "jdm-20006",
- "xattrs/ACLs enabled and couldn't "
- "find/create .reiserfs_priv. "
- "Failing mount.");
- err = -EOPNOTSUPP;
-#endif
- }
+ if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) {
+ mutex_lock(&s->s_root->d_inode->i_mutex);
+ err = create_privroot(REISERFS_SB(s)->priv_root);
+ mutex_unlock(&s->s_root->d_inode->i_mutex);
}
-#ifdef CONFIG_REISERFS_FS_XATTR
- if (!err)
+ if (privroot->d_inode) {
s->s_xattr = reiserfs_xattr_handlers;
+ mutex_lock(&privroot->d_inode->i_mutex);
+ if (!REISERFS_SB(s)->xattr_root) {
+ struct dentry *dentry;
+ dentry = lookup_one_len(XAROOT_NAME, privroot,
+ strlen(XAROOT_NAME));
+ if (!IS_ERR(dentry))
+ REISERFS_SB(s)->xattr_root = dentry;
+ else
+ err = PTR_ERR(dentry);
+ }
+ mutex_unlock(&privroot->d_inode->i_mutex);
+ }
error:
if (err) {
clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt));
clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt));
}
-#endif
/* The super_block MS_POSIXACL must mirror the (no)acl mount option. */
- s->s_flags = s->s_flags & ~MS_POSIXACL;
-#ifdef CONFIG_REISERFS_FS_POSIX_ACL
if (reiserfs_posixacl(s))
s->s_flags |= MS_POSIXACL;
-#endif
+ else
+ s->s_flags &= ~MS_POSIXACL;
return err;
}
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
index 4d3c20e787c3..a92c8792c0f6 100644
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -55,8 +55,16 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
struct reiserfs_security_handle *sec)
{
int blocks = 0;
- int error = security_inode_init_security(inode, dir, &sec->name,
- &sec->value, &sec->length);
+ int error;
+
+ sec->name = NULL;
+
+ /* Don't add selinux attributes on xattrs - they'll never get used */
+ if (IS_PRIVATE(dir))
+ return 0;
+
+ error = security_inode_init_security(inode, dir, &sec->name,
+ &sec->value, &sec->length);
if (error) {
if (error == -EOPNOTSUPP)
error = 0;
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index c53b5ef8a02f..4ab3c03d8f95 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -298,7 +298,8 @@ static struct inode *romfs_iget(struct super_block *sb, unsigned long pos)
struct romfs_inode ri;
struct inode *i;
unsigned long nlen;
- unsigned nextfh, ret;
+ unsigned nextfh;
+ int ret;
umode_t mode;
/* we might have to traverse a chain of "hard link" file entries to get
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index fc27fbfc5397..1402d2d54f52 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -474,6 +474,8 @@ smb_put_super(struct super_block *sb)
{
struct smb_sb_info *server = SMB_SB(sb);
+ lock_kernel();
+
smb_lock_server(server);
server->state = CONN_INVALID;
smbiod_unregister_server(server);
@@ -489,6 +491,8 @@ smb_put_super(struct super_block *sb)
smb_unlock_server(server);
put_pid(server->conn_pid);
kfree(server);
+
+ unlock_kernel();
}
static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
diff --git a/fs/splice.c b/fs/splice.c
index 666953d59a35..c5e3c79b95a8 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -507,9 +507,129 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
return ret;
}
-
EXPORT_SYMBOL(generic_file_splice_read);
+static const struct pipe_buf_operations default_pipe_buf_ops = {
+ .can_merge = 0,
+ .map = generic_pipe_buf_map,
+ .unmap = generic_pipe_buf_unmap,
+ .confirm = generic_pipe_buf_confirm,
+ .release = generic_pipe_buf_release,
+ .steal = generic_pipe_buf_steal,
+ .get = generic_pipe_buf_get,
+};
+
+static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
+ unsigned long vlen, loff_t offset)
+{
+ mm_segment_t old_fs;
+ loff_t pos = offset;
+ ssize_t res;
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+ /* The cast to a user pointer is valid due to the set_fs() */
+ res = vfs_readv(file, (const struct iovec __user *)vec, vlen, &pos);
+ set_fs(old_fs);
+
+ return res;
+}
+
+static ssize_t kernel_writev(struct file *file, const struct iovec *vec,
+ unsigned long vlen, loff_t *ppos)
+{
+ mm_segment_t old_fs;
+ ssize_t res;
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+ /* The cast to a user pointer is valid due to the set_fs() */
+ res = vfs_writev(file, (const struct iovec __user *)vec, vlen, ppos);
+ set_fs(old_fs);
+
+ return res;
+}
+
+ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t len,
+ unsigned int flags)
+{
+ unsigned int nr_pages;
+ unsigned int nr_freed;
+ size_t offset;
+ struct page *pages[PIPE_BUFFERS];
+ struct partial_page partial[PIPE_BUFFERS];
+ struct iovec vec[PIPE_BUFFERS];
+ pgoff_t index;
+ ssize_t res;
+ size_t this_len;
+ int error;
+ int i;
+ struct splice_pipe_desc spd = {
+ .pages = pages,
+ .partial = partial,
+ .flags = flags,
+ .ops = &default_pipe_buf_ops,
+ .spd_release = spd_release_page,
+ };
+
+ index = *ppos >> PAGE_CACHE_SHIFT;
+ offset = *ppos & ~PAGE_CACHE_MASK;
+ nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+
+ for (i = 0; i < nr_pages && i < PIPE_BUFFERS && len; i++) {
+ struct page *page;
+
+ page = alloc_page(GFP_USER);
+ error = -ENOMEM;
+ if (!page)
+ goto err;
+
+ this_len = min_t(size_t, len, PAGE_CACHE_SIZE - offset);
+ vec[i].iov_base = (void __user *) page_address(page);
+ vec[i].iov_len = this_len;
+ pages[i] = page;
+ spd.nr_pages++;
+ len -= this_len;
+ offset = 0;
+ }
+
+ res = kernel_readv(in, vec, spd.nr_pages, *ppos);
+ if (res < 0)
+ goto err;
+
+ error = 0;
+ if (!res)
+ goto err;
+
+ nr_freed = 0;
+ for (i = 0; i < spd.nr_pages; i++) {
+ this_len = min_t(size_t, vec[i].iov_len, res);
+ partial[i].offset = 0;
+ partial[i].len = this_len;
+ if (!this_len) {
+ __free_page(pages[i]);
+ pages[i] = NULL;
+ nr_freed++;
+ }
+ res -= this_len;
+ }
+ spd.nr_pages -= nr_freed;
+
+ res = splice_to_pipe(pipe, &spd);
+ if (res > 0)
+ *ppos += res;
+
+ return res;
+
+err:
+ for (i = 0; i < spd.nr_pages; i++)
+ __free_page(pages[i]);
+
+ return error;
+}
+EXPORT_SYMBOL(default_file_splice_read);
+
/*
* Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos'
* using sendpage(). Return the number of bytes sent.
@@ -881,6 +1001,122 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
EXPORT_SYMBOL(generic_file_splice_write);
+static struct pipe_buffer *nth_pipe_buf(struct pipe_inode_info *pipe, int n)
+{
+ return &pipe->bufs[(pipe->curbuf + n) % PIPE_BUFFERS];
+}
+
+static ssize_t default_file_splice_write(struct pipe_inode_info *pipe,
+ struct file *out, loff_t *ppos,
+ size_t len, unsigned int flags)
+{
+ ssize_t ret = 0;
+ ssize_t total_len = 0;
+ int do_wakeup = 0;
+
+ pipe_lock(pipe);
+ while (len) {
+ struct pipe_buffer *buf;
+ void *data[PIPE_BUFFERS];
+ struct iovec vec[PIPE_BUFFERS];
+ unsigned int nr_pages = 0;
+ unsigned int write_len = 0;
+ unsigned int now_len = len;
+ unsigned int this_len;
+ int i;
+
+ BUG_ON(pipe->nrbufs > PIPE_BUFFERS);
+ for (i = 0; i < pipe->nrbufs && now_len; i++) {
+ buf = nth_pipe_buf(pipe, i);
+
+ ret = buf->ops->confirm(pipe, buf);
+ if (ret)
+ break;
+
+ data[i] = buf->ops->map(pipe, buf, 0);
+ this_len = min(buf->len, now_len);
+ vec[i].iov_base = (void __user *) data[i] + buf->offset;
+ vec[i].iov_len = this_len;
+ now_len -= this_len;
+ write_len += this_len;
+ nr_pages++;
+ }
+
+ if (nr_pages) {
+ ret = kernel_writev(out, vec, nr_pages, ppos);
+ if (ret == 0)
+ ret = -EIO;
+ if (ret > 0) {
+ len -= ret;
+ total_len += ret;
+ }
+ }
+
+ for (i = 0; i < nr_pages; i++) {
+ buf = nth_pipe_buf(pipe, i);
+ buf->ops->unmap(pipe, buf, data[i]);
+
+ if (ret > 0) {
+ this_len = min_t(unsigned, vec[i].iov_len, ret);
+ buf->offset += this_len;
+ buf->len -= this_len;
+ ret -= this_len;
+ }
+ }
+
+ if (ret < 0)
+ break;
+
+ while (pipe->nrbufs) {
+ const struct pipe_buf_operations *ops;
+
+ buf = nth_pipe_buf(pipe, 0);
+ if (buf->len)
+ break;
+
+ ops = buf->ops;
+ buf->ops = NULL;
+ ops->release(pipe, buf);
+ pipe->curbuf = (pipe->curbuf + 1) % PIPE_BUFFERS;
+ pipe->nrbufs--;
+ if (pipe->inode)
+ do_wakeup = 1;
+ }
+
+ if (pipe->nrbufs)
+ continue;
+ if (!pipe->writers)
+ break;
+ if (!pipe->waiting_writers) {
+ if (total_len)
+ break;
+ }
+
+ if (flags & SPLICE_F_NONBLOCK) {
+ ret = -EAGAIN;
+ break;
+ }
+
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+
+ if (do_wakeup) {
+ wakeup_pipe_writers(pipe);
+ do_wakeup = 0;
+ }
+
+ pipe_wait(pipe);
+ }
+ pipe_unlock(pipe);
+
+ if (do_wakeup)
+ wakeup_pipe_writers(pipe);
+
+ return total_len ? total_len : ret;
+}
+
/**
* generic_splice_sendpage - splice data from a pipe to a socket
* @pipe: pipe to splice from
@@ -908,11 +1144,10 @@ EXPORT_SYMBOL(generic_splice_sendpage);
static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
loff_t *ppos, size_t len, unsigned int flags)
{
+ ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
+ loff_t *, size_t, unsigned int);
int ret;
- if (unlikely(!out->f_op || !out->f_op->splice_write))
- return -EINVAL;
-
if (unlikely(!(out->f_mode & FMODE_WRITE)))
return -EBADF;
@@ -923,7 +1158,11 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
if (unlikely(ret < 0))
return ret;
- return out->f_op->splice_write(pipe, out, ppos, len, flags);
+ splice_write = out->f_op->splice_write;
+ if (!splice_write)
+ splice_write = default_file_splice_write;
+
+ return splice_write(pipe, out, ppos, len, flags);
}
/*
@@ -933,11 +1172,10 @@ static long do_splice_to(struct file *in, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len,
unsigned int flags)
{
+ ssize_t (*splice_read)(struct file *, loff_t *,
+ struct pipe_inode_info *, size_t, unsigned int);
int ret;
- if (unlikely(!in->f_op || !in->f_op->splice_read))
- return -EINVAL;
-
if (unlikely(!(in->f_mode & FMODE_READ)))
return -EBADF;
@@ -945,7 +1183,11 @@ static long do_splice_to(struct file *in, loff_t *ppos,
if (unlikely(ret < 0))
return ret;
- return in->f_op->splice_read(in, ppos, pipe, len, flags);
+ splice_read = in->f_op->splice_read;
+ if (!splice_read)
+ splice_read = default_file_splice_read;
+
+ return splice_read(in, ppos, pipe, len, flags);
}
/**
@@ -1112,6 +1354,9 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
return ret;
}
+static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
+ struct pipe_inode_info *opipe,
+ size_t len, unsigned int flags);
/*
* After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
* location, so checking ->i_pipe is not enough to verify that this is a
@@ -1132,12 +1377,32 @@ static long do_splice(struct file *in, loff_t __user *off_in,
struct file *out, loff_t __user *off_out,
size_t len, unsigned int flags)
{
- struct pipe_inode_info *pipe;
+ struct pipe_inode_info *ipipe;
+ struct pipe_inode_info *opipe;
loff_t offset, *off;
long ret;
- pipe = pipe_info(in->f_path.dentry->d_inode);
- if (pipe) {
+ ipipe = pipe_info(in->f_path.dentry->d_inode);
+ opipe = pipe_info(out->f_path.dentry->d_inode);
+
+ if (ipipe && opipe) {
+ if (off_in || off_out)
+ return -ESPIPE;
+
+ if (!(in->f_mode & FMODE_READ))
+ return -EBADF;
+
+ if (!(out->f_mode & FMODE_WRITE))
+ return -EBADF;
+
+ /* Splicing to self would be fun, but... */
+ if (ipipe == opipe)
+ return -EINVAL;
+
+ return splice_pipe_to_pipe(ipipe, opipe, len, flags);
+ }
+
+ if (ipipe) {
if (off_in)
return -ESPIPE;
if (off_out) {
@@ -1149,7 +1414,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
} else
off = &out->f_pos;
- ret = do_splice_from(pipe, out, off, len, flags);
+ ret = do_splice_from(ipipe, out, off, len, flags);
if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
ret = -EFAULT;
@@ -1157,8 +1422,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
return ret;
}
- pipe = pipe_info(out->f_path.dentry->d_inode);
- if (pipe) {
+ if (opipe) {
if (off_out)
return -ESPIPE;
if (off_in) {
@@ -1170,7 +1434,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
} else
off = &in->f_pos;
- ret = do_splice_to(in, off, pipe, len, flags);
+ ret = do_splice_to(in, off, opipe, len, flags);
if (off_in && copy_to_user(off_in, off, sizeof(loff_t)))
ret = -EFAULT;
@@ -1511,7 +1775,7 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
* Make sure there's data to read. Wait for input if we can, otherwise
* return an appropriate error.
*/
-static int link_ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
+static int ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
{
int ret;
@@ -1549,7 +1813,7 @@ static int link_ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
* Make sure there's writeable room. Wait for room if we can, otherwise
* return an appropriate error.
*/
-static int link_opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
+static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
{
int ret;
@@ -1587,6 +1851,124 @@ static int link_opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
}
/*
+ * Splice contents of ipipe to opipe.
+ */
+static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
+ struct pipe_inode_info *opipe,
+ size_t len, unsigned int flags)
+{
+ struct pipe_buffer *ibuf, *obuf;
+ int ret = 0, nbuf;
+ bool input_wakeup = false;
+
+
+retry:
+ ret = ipipe_prep(ipipe, flags);
+ if (ret)
+ return ret;
+
+ ret = opipe_prep(opipe, flags);
+ if (ret)
+ return ret;
+
+ /*
+ * Potential ABBA deadlock, work around it by ordering lock
+ * grabbing by pipe info address. Otherwise two different processes
+ * could deadlock (one doing tee from A -> B, the other from B -> A).
+ */
+ pipe_double_lock(ipipe, opipe);
+
+ do {
+ if (!opipe->readers) {
+ send_sig(SIGPIPE, current, 0);
+ if (!ret)
+ ret = -EPIPE;
+ break;
+ }
+
+ if (!ipipe->nrbufs && !ipipe->writers)
+ break;
+
+ /*
+ * Cannot make any progress, because either the input
+ * pipe is empty or the output pipe is full.
+ */
+ if (!ipipe->nrbufs || opipe->nrbufs >= PIPE_BUFFERS) {
+ /* Already processed some buffers, break */
+ if (ret)
+ break;
+
+ if (flags & SPLICE_F_NONBLOCK) {
+ ret = -EAGAIN;
+ break;
+ }
+
+ /*
+ * We raced with another reader/writer and haven't
+ * managed to process any buffers. A zero return
+ * value means EOF, so retry instead.
+ */
+ pipe_unlock(ipipe);
+ pipe_unlock(opipe);
+ goto retry;
+ }
+
+ ibuf = ipipe->bufs + ipipe->curbuf;
+ nbuf = (opipe->curbuf + opipe->nrbufs) % PIPE_BUFFERS;
+ obuf = opipe->bufs + nbuf;
+
+ if (len >= ibuf->len) {
+ /*
+ * Simply move the whole buffer from ipipe to opipe
+ */
+ *obuf = *ibuf;
+ ibuf->ops = NULL;
+ opipe->nrbufs++;
+ ipipe->curbuf = (ipipe->curbuf + 1) % PIPE_BUFFERS;
+ ipipe->nrbufs--;
+ input_wakeup = true;
+ } else {
+ /*
+ * Get a reference to this pipe buffer,
+ * so we can copy the contents over.
+ */
+ ibuf->ops->get(ipipe, ibuf);
+ *obuf = *ibuf;
+
+ /*
+ * Don't inherit the gift flag, we need to
+ * prevent multiple steals of this page.
+ */
+ obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
+
+ obuf->len = len;
+ opipe->nrbufs++;
+ ibuf->offset += obuf->len;
+ ibuf->len -= obuf->len;
+ }
+ ret += obuf->len;
+ len -= obuf->len;
+ } while (len);
+
+ pipe_unlock(ipipe);
+ pipe_unlock(opipe);
+
+ /*
+ * If we put data in the output pipe, wakeup any potential readers.
+ */
+ if (ret > 0) {
+ smp_mb();
+ if (waitqueue_active(&opipe->wait))
+ wake_up_interruptible(&opipe->wait);
+ kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN);
+ }
+ if (input_wakeup)
+ wakeup_pipe_writers(ipipe);
+
+ return ret;
+}
+
+/*
* Link contents of ipipe to opipe.
*/
static int link_pipe(struct pipe_inode_info *ipipe,
@@ -1690,9 +2072,9 @@ static long do_tee(struct file *in, struct file *out, size_t len,
* Keep going, unless we encounter an error. The ipipe/opipe
* ordering doesn't really matter.
*/
- ret = link_ipipe_prep(ipipe, flags);
+ ret = ipipe_prep(ipipe, flags);
if (!ret) {
- ret = link_opipe_prep(opipe, flags);
+ ret = opipe_prep(opipe, flags);
if (!ret)
ret = link_pipe(ipipe, opipe, len, flags);
}
diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile
index 8258cf9a0317..70e3244fa30f 100644
--- a/fs/squashfs/Makefile
+++ b/fs/squashfs/Makefile
@@ -5,4 +5,3 @@
obj-$(CONFIG_SQUASHFS) += squashfs.o
squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
squashfs-y += namei.o super.o symlink.o
-#squashfs-y += squashfs2_0.o
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c
index 1c4739e33af6..40c98fa6b5d6 100644
--- a/fs/squashfs/cache.c
+++ b/fs/squashfs/cache.c
@@ -252,6 +252,7 @@ struct squashfs_cache *squashfs_cache_init(char *name, int entries,
cache->entries = entries;
cache->block_size = block_size;
cache->pages = block_size >> PAGE_CACHE_SHIFT;
+ cache->pages = cache->pages ? cache->pages : 1;
cache->name = name;
cache->num_waiters = 0;
spin_lock_init(&cache->lock);
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index ffa6edcd2d0c..3b52770f46ff 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -157,6 +157,16 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE)
goto failed_mount;
+ /*
+ * Check the system page size is not larger than the filesystem
+ * block size (by default 128K). This is currently not supported.
+ */
+ if (PAGE_CACHE_SIZE > msblk->block_size) {
+ ERROR("Page size > filesystem block size (%d). This is "
+ "currently not supported!\n", msblk->block_size);
+ goto failed_mount;
+ }
+
msblk->block_log = le16_to_cpu(sblk->block_log);
if (msblk->block_log > SQUASHFS_FILE_MAX_LOG)
goto failed_mount;
@@ -328,6 +338,8 @@ static int squashfs_remount(struct super_block *sb, int *flags, char *data)
static void squashfs_put_super(struct super_block *sb)
{
+ lock_kernel();
+
if (sb->s_fs_info) {
struct squashfs_sb_info *sbi = sb->s_fs_info;
squashfs_cache_delete(sbi->block_cache);
@@ -340,6 +352,8 @@ static void squashfs_put_super(struct super_block *sb)
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
}
+
+ unlock_kernel();
}
diff --git a/fs/super.c b/fs/super.c
index 786fe7d72790..2ea158648e60 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -28,7 +28,6 @@
#include <linux/blkdev.h>
#include <linux/quotaops.h>
#include <linux/namei.h>
-#include <linux/buffer_head.h> /* for fsync_super() */
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/syscalls.h>
@@ -38,7 +37,6 @@
#include <linux/kobject.h>
#include <linux/mutex.h>
#include <linux/file.h>
-#include <linux/async.h>
#include <asm/uaccess.h>
#include "internal.h"
@@ -72,7 +70,6 @@ static struct super_block *alloc_super(struct file_system_type *type)
INIT_HLIST_HEAD(&s->s_anon);
INIT_LIST_HEAD(&s->s_inodes);
INIT_LIST_HEAD(&s->s_dentry_lru);
- INIT_LIST_HEAD(&s->s_async_list);
init_rwsem(&s->s_umount);
mutex_init(&s->s_lock);
lockdep_set_class(&s->s_umount, &type->s_umount_key);
@@ -208,6 +205,34 @@ void deactivate_super(struct super_block *s)
EXPORT_SYMBOL(deactivate_super);
/**
+ * deactivate_locked_super - drop an active reference to superblock
+ * @s: superblock to deactivate
+ *
+ * Equivalent of up_write(&s->s_umount); deactivate_super(s);, except that
+ * it does not unlock it until it's all over. As the result, it's safe to
+ * use to dispose of new superblock on ->get_sb() failure exits - nobody
+ * will see the sucker until it's all over. Equivalent using up_write +
+ * deactivate_super is safe for that purpose only if superblock is either
+ * safe to use or has NULL ->s_root when we unlock.
+ */
+void deactivate_locked_super(struct super_block *s)
+{
+ struct file_system_type *fs = s->s_type;
+ if (atomic_dec_and_lock(&s->s_active, &sb_lock)) {
+ s->s_count -= S_BIAS-1;
+ spin_unlock(&sb_lock);
+ vfs_dq_off(s, 0);
+ fs->kill_sb(s);
+ put_filesystem(fs);
+ put_super(s);
+ } else {
+ up_write(&s->s_umount);
+ }
+}
+
+EXPORT_SYMBOL(deactivate_locked_super);
+
+/**
* grab_super - acquire an active reference
* @s: reference we are trying to make active
*
@@ -257,38 +282,6 @@ void unlock_super(struct super_block * sb)
EXPORT_SYMBOL(lock_super);
EXPORT_SYMBOL(unlock_super);
-/*
- * Write out and wait upon all dirty data associated with this
- * superblock. Filesystem data as well as the underlying block
- * device. Takes the superblock lock. Requires a second blkdev
- * flush by the caller to complete the operation.
- */
-void __fsync_super(struct super_block *sb)
-{
- sync_inodes_sb(sb, 0);
- vfs_dq_sync(sb);
- lock_super(sb);
- if (sb->s_dirt && sb->s_op->write_super)
- sb->s_op->write_super(sb);
- unlock_super(sb);
- if (sb->s_op->sync_fs)
- sb->s_op->sync_fs(sb, 1);
- sync_blockdev(sb->s_bdev);
- sync_inodes_sb(sb, 1);
-}
-
-/*
- * Write out and wait upon all dirty data associated with this
- * superblock. Filesystem data as well as the underlying block
- * device. Takes the superblock lock.
- */
-int fsync_super(struct super_block *sb)
-{
- __fsync_super(sb);
- return sync_blockdev(sb->s_bdev);
-}
-EXPORT_SYMBOL_GPL(fsync_super);
-
/**
* generic_shutdown_super - common helper for ->kill_sb()
* @sb: superblock to kill
@@ -310,21 +303,13 @@ void generic_shutdown_super(struct super_block *sb)
if (sb->s_root) {
shrink_dcache_for_umount(sb);
- fsync_super(sb);
- lock_super(sb);
+ sync_filesystem(sb);
+ get_fs_excl();
sb->s_flags &= ~MS_ACTIVE;
- /*
- * wait for asynchronous fs operations to finish before going further
- */
- async_synchronize_full_domain(&sb->s_async_list);
-
/* bad name - it should be evict_inodes() */
invalidate_inodes(sb);
- lock_kernel();
- if (sop->write_super && sb->s_dirt)
- sop->write_super(sb);
if (sop->put_super)
sop->put_super(sb);
@@ -334,9 +319,7 @@ void generic_shutdown_super(struct super_block *sb)
"Self-destruct in 5 seconds. Have a nice day...\n",
sb->s_id);
}
-
- unlock_kernel();
- unlock_super(sb);
+ put_fs_excl();
}
spin_lock(&sb_lock);
/* should be initialized for __put_super_and_need_restart() */
@@ -413,16 +396,14 @@ void drop_super(struct super_block *sb)
EXPORT_SYMBOL(drop_super);
-static inline void write_super(struct super_block *sb)
-{
- lock_super(sb);
- if (sb->s_root && sb->s_dirt)
- if (sb->s_op->write_super)
- sb->s_op->write_super(sb);
- unlock_super(sb);
-}
-
-/*
+/**
+ * sync_supers - helper for periodic superblock writeback
+ *
+ * Call the write_super method if present on all dirty superblocks in
+ * the system. This is for the periodic writeback used by most older
+ * filesystems. For data integrity superblock writeback use
+ * sync_filesystems() instead.
+ *
* Note: check the dirty flag before waiting, so we don't
* hold up the sync while mounting a device. (The newly
* mounted device won't need syncing.)
@@ -434,12 +415,15 @@ void sync_supers(void)
spin_lock(&sb_lock);
restart:
list_for_each_entry(sb, &super_blocks, s_list) {
- if (sb->s_dirt) {
+ if (sb->s_op->write_super && sb->s_dirt) {
sb->s_count++;
spin_unlock(&sb_lock);
+
down_read(&sb->s_umount);
- write_super(sb);
+ if (sb->s_root && sb->s_dirt)
+ sb->s_op->write_super(sb);
up_read(&sb->s_umount);
+
spin_lock(&sb_lock);
if (__put_super_and_need_restart(sb))
goto restart;
@@ -448,60 +432,6 @@ restart:
spin_unlock(&sb_lock);
}
-/*
- * Call the ->sync_fs super_op against all filesystems which are r/w and
- * which implement it.
- *
- * This operation is careful to avoid the livelock which could easily happen
- * if two or more filesystems are being continuously dirtied. s_need_sync_fs
- * is used only here. We set it against all filesystems and then clear it as
- * we sync them. So redirtied filesystems are skipped.
- *
- * But if process A is currently running sync_filesystems and then process B
- * calls sync_filesystems as well, process B will set all the s_need_sync_fs
- * flags again, which will cause process A to resync everything. Fix that with
- * a local mutex.
- *
- * (Fabian) Avoid sync_fs with clean fs & wait mode 0
- */
-void sync_filesystems(int wait)
-{
- struct super_block *sb;
- static DEFINE_MUTEX(mutex);
-
- mutex_lock(&mutex); /* Could be down_interruptible */
- spin_lock(&sb_lock);
- list_for_each_entry(sb, &super_blocks, s_list) {
- if (!sb->s_op->sync_fs)
- continue;
- if (sb->s_flags & MS_RDONLY)
- continue;
- sb->s_need_sync_fs = 1;
- }
-
-restart:
- list_for_each_entry(sb, &super_blocks, s_list) {
- if (!sb->s_need_sync_fs)
- continue;
- sb->s_need_sync_fs = 0;
- if (sb->s_flags & MS_RDONLY)
- continue; /* hm. Was remounted r/o meanwhile */
- sb->s_count++;
- spin_unlock(&sb_lock);
- down_read(&sb->s_umount);
- async_synchronize_full_domain(&sb->s_async_list);
- if (sb->s_root && (wait || sb->s_dirt))
- sb->s_op->sync_fs(sb, wait);
- up_read(&sb->s_umount);
- /* restart only when sb is no longer on the list */
- spin_lock(&sb_lock);
- if (__put_super_and_need_restart(sb))
- goto restart;
- }
- spin_unlock(&sb_lock);
- mutex_unlock(&mutex);
-}
-
/**
* get_super - get the superblock of a device
* @bdev: device to get the superblock for
@@ -588,45 +518,6 @@ out:
}
/**
- * mark_files_ro - mark all files read-only
- * @sb: superblock in question
- *
- * All files are marked read-only. We don't care about pending
- * delete files so this should be used in 'force' mode only.
- */
-
-static void mark_files_ro(struct super_block *sb)
-{
- struct file *f;
-
-retry:
- file_list_lock();
- list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
- struct vfsmount *mnt;
- if (!S_ISREG(f->f_path.dentry->d_inode->i_mode))
- continue;
- if (!file_count(f))
- continue;
- if (!(f->f_mode & FMODE_WRITE))
- continue;
- f->f_mode &= ~FMODE_WRITE;
- if (file_check_writeable(f) != 0)
- continue;
- file_release_write(f);
- mnt = mntget(f->f_path.mnt);
- file_list_unlock();
- /*
- * This can sleep, so we can't hold
- * the file_list_lock() spinlock.
- */
- mnt_drop_write(mnt);
- mntput(mnt);
- goto retry;
- }
- file_list_unlock();
-}
-
-/**
* do_remount_sb - asks filesystem to change mount options.
* @sb: superblock in question
* @flags: numeric part of options
@@ -647,8 +538,9 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
if (flags & MS_RDONLY)
acct_auto_close(sb);
shrink_dcache_sb(sb);
- fsync_super(sb);
+ sync_filesystem(sb);
+ lock_kernel();
/* If we are remounting RDONLY and current sb is read/write,
make sure there are no rw files opened */
if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY)) {
@@ -663,13 +555,12 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY);
if (sb->s_op->remount_fs) {
- lock_super(sb);
retval = sb->s_op->remount_fs(sb, &flags, data);
- unlock_super(sb);
if (retval)
return retval;
}
sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
+ unlock_kernel();
if (remount_rw)
vfs_dq_quota_on_remount(sb);
return 0;
@@ -683,18 +574,17 @@ static void do_emergency_remount(struct work_struct *work)
list_for_each_entry(sb, &super_blocks, s_list) {
sb->s_count++;
spin_unlock(&sb_lock);
- down_read(&sb->s_umount);
+ down_write(&sb->s_umount);
if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) {
/*
* ->remount_fs needs lock_kernel().
*
* What lock protects sb->s_flags??
*/
- lock_kernel();
do_remount_sb(sb, MS_RDONLY, NULL, 1);
- unlock_kernel();
}
- drop_super(sb);
+ up_write(&sb->s_umount);
+ put_super(sb);
spin_lock(&sb_lock);
}
spin_unlock(&sb_lock);
@@ -797,8 +687,7 @@ int get_sb_ns(struct file_system_type *fs_type, int flags, void *data,
sb->s_flags = flags;
err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
if (err) {
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ deactivate_locked_super(sb);
return err;
}
@@ -854,8 +743,7 @@ int get_sb_bdev(struct file_system_type *fs_type,
if (s->s_root) {
if ((flags ^ s->s_flags) & MS_RDONLY) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
error = -EBUSY;
goto error_bdev;
}
@@ -870,8 +758,7 @@ int get_sb_bdev(struct file_system_type *fs_type,
sb_set_blocksize(s, block_size(bdev));
error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
if (error) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
goto error;
}
@@ -897,7 +784,7 @@ void kill_block_super(struct super_block *sb)
struct block_device *bdev = sb->s_bdev;
fmode_t mode = sb->s_mode;
- bdev->bd_super = 0;
+ bdev->bd_super = NULL;
generic_shutdown_super(sb);
sync_blockdev(bdev);
close_bdev_exclusive(bdev, mode);
@@ -921,8 +808,7 @@ int get_sb_nodev(struct file_system_type *fs_type,
error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
if (error) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
return error;
}
s->s_flags |= MS_ACTIVE;
@@ -952,8 +838,7 @@ int get_sb_single(struct file_system_type *fs_type,
s->s_flags = flags;
error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
if (error) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
return error;
}
s->s_flags |= MS_ACTIVE;
@@ -1006,8 +891,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
return mnt;
out_sb:
dput(mnt->mnt_root);
- up_write(&mnt->mnt_sb->s_umount);
- deactivate_super(mnt->mnt_sb);
+ deactivate_locked_super(mnt->mnt_sb);
out_free_secdata:
free_secdata(secdata);
out_mnt:
diff --git a/fs/sync.c b/fs/sync.c
index 7abc65fbf21d..e9d56f6c0b74 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -13,38 +13,125 @@
#include <linux/pagemap.h>
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
+#include "internal.h"
#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
SYNC_FILE_RANGE_WAIT_AFTER)
/*
- * sync everything. Start out by waking pdflush, because that writes back
- * all queues in parallel.
+ * Do the filesystem syncing work. For simple filesystems sync_inodes_sb(sb, 0)
+ * just dirties buffers with inodes so we have to submit IO for these buffers
+ * via __sync_blockdev(). This also speeds up the wait == 1 case since in that
+ * case write_inode() functions do sync_dirty_buffer() and thus effectively
+ * write one block at a time.
*/
-static void do_sync(unsigned long wait)
+static int __sync_filesystem(struct super_block *sb, int wait)
{
- wakeup_pdflush(0);
- sync_inodes(0); /* All mappings, inodes and their blockdevs */
- vfs_dq_sync(NULL);
- sync_supers(); /* Write the superblocks */
- sync_filesystems(0); /* Start syncing the filesystems */
- sync_filesystems(wait); /* Waitingly sync the filesystems */
- sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */
+ /* Avoid doing twice syncing and cache pruning for quota sync */
if (!wait)
- printk("Emergency Sync complete\n");
- if (unlikely(laptop_mode))
- laptop_sync_completion();
+ writeout_quota_sb(sb, -1);
+ else
+ sync_quota_sb(sb, -1);
+ sync_inodes_sb(sb, wait);
+ if (sb->s_dirt && sb->s_op->write_super)
+ sb->s_op->write_super(sb);
+ if (sb->s_op->sync_fs)
+ sb->s_op->sync_fs(sb, wait);
+ return __sync_blockdev(sb->s_bdev, wait);
+}
+
+/*
+ * Write out and wait upon all dirty data associated with this
+ * superblock. Filesystem data as well as the underlying block
+ * device. Takes the superblock lock.
+ */
+int sync_filesystem(struct super_block *sb)
+{
+ int ret;
+
+ /*
+ * We need to be protected against the filesystem going from
+ * r/o to r/w or vice versa.
+ */
+ WARN_ON(!rwsem_is_locked(&sb->s_umount));
+
+ /*
+ * No point in syncing out anything if the filesystem is read-only.
+ */
+ if (sb->s_flags & MS_RDONLY)
+ return 0;
+
+ ret = __sync_filesystem(sb, 0);
+ if (ret < 0)
+ return ret;
+ return __sync_filesystem(sb, 1);
+}
+EXPORT_SYMBOL_GPL(sync_filesystem);
+
+/*
+ * Sync all the data for all the filesystems (called by sys_sync() and
+ * emergency sync)
+ *
+ * This operation is careful to avoid the livelock which could easily happen
+ * if two or more filesystems are being continuously dirtied. s_need_sync
+ * is used only here. We set it against all filesystems and then clear it as
+ * we sync them. So redirtied filesystems are skipped.
+ *
+ * But if process A is currently running sync_filesystems and then process B
+ * calls sync_filesystems as well, process B will set all the s_need_sync
+ * flags again, which will cause process A to resync everything. Fix that with
+ * a local mutex.
+ */
+static void sync_filesystems(int wait)
+{
+ struct super_block *sb;
+ static DEFINE_MUTEX(mutex);
+
+ mutex_lock(&mutex); /* Could be down_interruptible */
+ spin_lock(&sb_lock);
+ list_for_each_entry(sb, &super_blocks, s_list)
+ sb->s_need_sync = 1;
+
+restart:
+ list_for_each_entry(sb, &super_blocks, s_list) {
+ if (!sb->s_need_sync)
+ continue;
+ sb->s_need_sync = 0;
+ sb->s_count++;
+ spin_unlock(&sb_lock);
+
+ down_read(&sb->s_umount);
+ if (!(sb->s_flags & MS_RDONLY) && sb->s_root)
+ __sync_filesystem(sb, wait);
+ up_read(&sb->s_umount);
+
+ /* restart only when sb is no longer on the list */
+ spin_lock(&sb_lock);
+ if (__put_super_and_need_restart(sb))
+ goto restart;
+ }
+ spin_unlock(&sb_lock);
+ mutex_unlock(&mutex);
}
SYSCALL_DEFINE0(sync)
{
- do_sync(1);
+ sync_filesystems(0);
+ sync_filesystems(1);
+ if (unlikely(laptop_mode))
+ laptop_sync_completion();
return 0;
}
static void do_sync_work(struct work_struct *work)
{
- do_sync(0);
+ /*
+ * Sync twice to reduce the possibility we skipped some inodes / pages
+ * because they were temporarily locked
+ */
+ sync_filesystems(0);
+ sync_filesystems(0);
+ printk("Emergency Sync complete\n");
kfree(work);
}
@@ -75,10 +162,8 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
/* sync the superblock to buffers */
sb = inode->i_sb;
- lock_super(sb);
if (sb->s_dirt && sb->s_op->write_super)
sb->s_op->write_super(sb);
- unlock_super(sb);
/* .. finally sync the buffers to disk */
err = sync_blockdev(sb->s_bdev);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index b1606e07b7a3..561a9c050cef 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -723,7 +723,7 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
mutex_unlock(&sysfs_workq_mutex);
if (sysfs_workqueue == NULL) {
- sysfs_workqueue = create_workqueue("sysfsd");
+ sysfs_workqueue = create_singlethread_workqueue("sysfsd");
if (sysfs_workqueue == NULL) {
module_put(owner);
return -ENOMEM;
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index da20b48d350f..a3f45fc626a1 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -37,6 +37,7 @@ static void sysv_write_super(struct super_block *sb)
struct sysv_sb_info *sbi = SYSV_SB(sb);
unsigned long time = get_seconds(), old_time;
+ lock_super(sb);
lock_kernel();
if (sb->s_flags & MS_RDONLY)
goto clean;
@@ -56,15 +57,18 @@ static void sysv_write_super(struct super_block *sb)
clean:
sb->s_dirt = 0;
unlock_kernel();
+ unlock_super(sb);
}
static int sysv_remount(struct super_block *sb, int *flags, char *data)
{
struct sysv_sb_info *sbi = SYSV_SB(sb);
+ lock_super(sb);
if (sbi->s_forced_ro)
*flags |= MS_RDONLY;
if (!(*flags & MS_RDONLY))
sb->s_dirt = 1;
+ unlock_super(sb);
return 0;
}
@@ -72,6 +76,11 @@ static void sysv_put_super(struct super_block *sb)
{
struct sysv_sb_info *sbi = SYSV_SB(sb);
+ lock_kernel();
+
+ if (sb->s_dirt)
+ sysv_write_super(sb);
+
if (!(sb->s_flags & MS_RDONLY)) {
/* XXX ext2 also updates the state here */
mark_buffer_dirty(sbi->s_bh1);
@@ -84,6 +93,8 @@ static void sysv_put_super(struct super_block *sb)
brelse(sbi->s_bh2);
kfree(sbi);
+
+ unlock_kernel();
}
static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf)
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index af1914462f02..d0231ba783df 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -628,7 +628,7 @@ void ubifs_convert_page_budget(struct ubifs_info *c)
*
* This function releases budget corresponding to a dirty inode. It is usually
* called when after the inode has been written to the media and marked as
- * clean.
+ * clean. It also causes the "no space" flags to be cleared.
*/
void ubifs_release_dirty_inode_budget(struct ubifs_info *c,
struct ubifs_inode *ui)
@@ -636,6 +636,7 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c,
struct ubifs_budget_req req;
memset(&req, 0, sizeof(struct ubifs_budget_req));
+ /* The "no space" flags will be cleared because dd_growth is > 0 */
req.dd_growth = c->inode_budget + ALIGN(ui->data_len, 8);
ubifs_release_budget(c, &req);
}
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index faa44f90608a..592e1d11bd20 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -360,6 +360,11 @@ static void ubifs_delete_inode(struct inode *inode)
out:
if (ui->dirty)
ubifs_release_dirty_inode_budget(c, ui);
+ else {
+ /* We've deleted something - clean the "no space" flags */
+ c->nospace = c->nospace_rp = 0;
+ smp_wmb();
+ }
clear_inode(inode);
}
@@ -447,9 +452,6 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
if (!wait)
return 0;
- if (sb->s_flags & MS_RDONLY)
- return 0;
-
/*
* VFS calls '->sync_fs()' before synchronizing all dirty inodes and
* pages, so synchronize them first, then commit the journal. Strictly
@@ -1687,6 +1689,9 @@ static void ubifs_put_super(struct super_block *sb)
ubifs_msg("un-mount UBI device %d, volume %d", c->vi.ubi_num,
c->vi.vol_id);
+
+ lock_kernel();
+
/*
* The following asserts are only valid if there has not been a failure
* of the media. For example, there will be dirty inodes if we failed
@@ -1753,6 +1758,8 @@ static void ubifs_put_super(struct super_block *sb)
ubi_close_volume(c->ubi);
mutex_unlock(&c->umount_mutex);
kfree(c);
+
+ unlock_kernel();
}
static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
@@ -2055,8 +2062,7 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
return 0;
out_deact:
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ deactivate_locked_super(sb);
out_close:
ubi_close_volume(ubi);
return err;
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 72348cc855a4..e2e06b0ea565 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -2062,6 +2062,9 @@ static void udf_put_super(struct super_block *sb)
struct udf_sb_info *sbi;
sbi = UDF_SB(sb);
+
+ lock_kernel();
+
if (sbi->s_vat_inode)
iput(sbi->s_vat_inode);
if (sbi->s_partitions)
@@ -2077,6 +2080,8 @@ static void udf_put_super(struct super_block *sb)
kfree(sbi->s_partmaps);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
+
+ unlock_kernel();
}
static int udf_sync_fs(struct super_block *sb, int wait)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index dbbbc4668769..6321b797061b 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -666,6 +666,6 @@ not_empty:
const struct file_operations ufs_dir_operations = {
.read = generic_read_dir,
.readdir = ufs_readdir,
- .fsync = file_fsync,
+ .fsync = ufs_sync_file,
.llseek = generic_file_llseek,
};
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 625ef17c6f83..2bd3a1615714 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -30,7 +30,7 @@
#include "ufs.h"
-static int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync)
+int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync)
{
struct inode *inode = dentry->d_inode;
int err;
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 60359291761f..c97210ee0670 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -594,6 +594,9 @@ static void ufs_put_super_internal(struct super_block *sb)
UFSD("ENTER\n");
+
+ lock_kernel();
+
ufs_put_cstotal(sb);
size = uspi->s_cssize;
blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
@@ -621,6 +624,9 @@ static void ufs_put_super_internal(struct super_block *sb)
brelse (sbi->s_ucg[i]);
kfree (sbi->s_ucg);
kfree (base);
+
+ unlock_kernel();
+
UFSD("EXIT\n");
}
@@ -1125,6 +1131,7 @@ static void ufs_write_super(struct super_block *sb)
struct ufs_super_block_third * usb3;
unsigned flags;
+ lock_super(sb);
lock_kernel();
UFSD("ENTER\n");
flags = UFS_SB(sb)->s_flags;
@@ -1144,6 +1151,7 @@ static void ufs_write_super(struct super_block *sb)
sb->s_dirt = 0;
UFSD("EXIT\n");
unlock_kernel();
+ unlock_super(sb);
}
static void ufs_put_super(struct super_block *sb)
@@ -1152,6 +1160,9 @@ static void ufs_put_super(struct super_block *sb)
UFSD("ENTER\n");
+ if (sb->s_dirt)
+ ufs_write_super(sb);
+
if (!(sb->s_flags & MS_RDONLY))
ufs_put_super_internal(sb);
@@ -1172,6 +1183,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
unsigned new_mount_opt, ufstype;
unsigned flags;
+ lock_super(sb);
uspi = UFS_SB(sb)->s_uspi;
flags = UFS_SB(sb)->s_flags;
usb1 = ubh_get_usb_first(uspi);
@@ -1184,17 +1196,21 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
ufstype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE;
new_mount_opt = 0;
ufs_set_opt (new_mount_opt, ONERROR_LOCK);
- if (!ufs_parse_options (data, &new_mount_opt))
+ if (!ufs_parse_options (data, &new_mount_opt)) {
+ unlock_super(sb);
return -EINVAL;
+ }
if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
new_mount_opt |= ufstype;
} else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
printk("ufstype can't be changed during remount\n");
+ unlock_super(sb);
return -EINVAL;
}
if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
UFS_SB(sb)->s_mount_opt = new_mount_opt;
+ unlock_super(sb);
return 0;
}
@@ -1219,6 +1235,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
#ifndef CONFIG_UFS_FS_WRITE
printk("ufs was compiled with read-only support, "
"can't be mounted as read-write\n");
+ unlock_super(sb);
return -EINVAL;
#else
if (ufstype != UFS_MOUNT_UFSTYPE_SUN &&
@@ -1227,16 +1244,19 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
printk("this ufstype is read-only supported\n");
+ unlock_super(sb);
return -EINVAL;
}
if (!ufs_read_cylinder_structures(sb)) {
printk("failed during remounting\n");
+ unlock_super(sb);
return -EPERM;
}
sb->s_flags &= ~MS_RDONLY;
#endif
}
UFS_SB(sb)->s_mount_opt = new_mount_opt;
+ unlock_super(sb);
return 0;
}
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 69b3427d7885..d0c4acd4f1f3 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -98,8 +98,8 @@ extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
/* 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;
+extern int ufs_sync_file(struct file *, struct dentry *, int);
/* ialloc.c */
extern void ufs_free_inode (struct inode *inode);
diff --git a/fs/xattr.c b/fs/xattr.c
index d51b8f9db921..1c3d0af59ddf 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -297,7 +297,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
return error;
dentry = f->f_path.dentry;
audit_inode(NULL, dentry);
- error = mnt_want_write(f->f_path.mnt);
+ error = mnt_want_write_file(f);
if (!error) {
error = setxattr(dentry, name, value, size, flags);
mnt_drop_write(f->f_path.mnt);
@@ -524,7 +524,7 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
return error;
dentry = f->f_path.dentry;
audit_inode(NULL, dentry);
- error = mnt_want_write(f->f_path.mnt);
+ error = mnt_want_write_file(f);
if (!error) {
error = removexattr(dentry, name);
mnt_drop_write(f->f_path.mnt);
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index bb685269f832..d29218edd81e 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1062,6 +1062,8 @@ xfs_fs_put_super(
struct xfs_inode *rip = mp->m_rootip;
int unmount_event_flags = 0;
+ lock_kernel();
+
xfs_syncd_stop(mp);
xfs_sync_inodes(mp, SYNC_ATTR|SYNC_DELWRI);
@@ -1102,6 +1104,8 @@ xfs_fs_put_super(
xfs_dmops_put(mp);
xfs_free_fsname(mp);
kfree(mp);
+
+ unlock_kernel();
}
STATIC void
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index e6d839bddbf0..7465f9ee125f 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -347,13 +347,15 @@ xfs_swap_extents(
error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
-out_unlock:
- xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
out:
kmem_free(tempifp);
return error;
+out_unlock:
+ xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
+ xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
+ goto out;
+
out_trans_cancel:
xfs_trans_cancel(tp, 0);
goto out_unlock;
diff --git a/include/Kbuild b/include/Kbuild
index d8c3e3cbf416..8d226bfa2696 100644
--- a/include/Kbuild
+++ b/include/Kbuild
@@ -8,3 +8,5 @@ header-y += mtd/
header-y += rdma/
header-y += video/
header-y += drm/
+header-y += xen/
+header-y += scsi/
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 4db89e98535d..60b76a3fb3a1 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -47,7 +47,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20090320
+#define ACPI_CA_VERSION 0x20090422
#include "actypes.h"
#include "actbl.h"
@@ -375,7 +375,7 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state);
acpi_status acpi_leave_sleep_state(u8 sleep_state);
/*
- * Debug output
+ * Error/Warning output
*/
void ACPI_INTERNAL_VAR_XFACE
acpi_error(const char *module_name,
@@ -394,6 +394,9 @@ void ACPI_INTERNAL_VAR_XFACE
acpi_info(const char *module_name,
u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3);
+/*
+ * Debug output
+ */
#ifdef ACPI_DEBUG_OUTPUT
void ACPI_INTERNAL_VAR_XFACE
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index f555d927f7c0..37ba576d06e8 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -429,20 +429,12 @@ typedef unsigned long long acpi_integer;
/* Data manipulation */
-#define ACPI_LOWORD(l) ((u16)(u32)(l))
-#define ACPI_HIWORD(l) ((u16)((((u32)(l)) >> 16) & 0xFFFF))
-#define ACPI_LOBYTE(l) ((u8)(u16)(l))
-#define ACPI_HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF))
-
-/* Full 64-bit integer must be available on both 32-bit and 64-bit platforms */
-
-struct acpi_integer_overlay {
- u32 lo_dword;
- u32 hi_dword;
-};
-
-#define ACPI_LODWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->lo_dword)
-#define ACPI_HIDWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->hi_dword)
+#define ACPI_LOBYTE(integer) ((u8) (u16)(integer))
+#define ACPI_HIBYTE(integer) ((u8) (((u16)(integer)) >> 8))
+#define ACPI_LOWORD(integer) ((u16) (u32)(integer))
+#define ACPI_HIWORD(integer) ((u16)(((u32)(integer)) >> 16))
+#define ACPI_LODWORD(integer64) ((u32) (u64)(integer64))
+#define ACPI_HIDWORD(integer64) ((u32)(((u64)(integer64)) >> 32))
#define ACPI_SET_BIT(target,bit) ((target) |= (bit))
#define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit))
diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h
index 8e2cdc57b197..935c5d7fc86e 100644
--- a/include/acpi/platform/acgcc.h
+++ b/include/acpi/platform/acgcc.h
@@ -62,4 +62,8 @@
*/
#define ACPI_UNUSED_VAR __attribute__ ((unused))
+#ifdef _ANSI
+#define inline
+#endif
+
#endif /* __ACGCC_H__ */
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 6d49b2a498c4..fcb8e4b159b1 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -1,11 +1,11 @@
/******************************************************************************
*
- * Name: aclinux.h - OS specific defines, etc.
+ * Name: aclinux.h - OS specific defines, etc. for Linux
*
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2009, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -44,10 +44,13 @@
#ifndef __ACLINUX_H__
#define __ACLINUX_H__
+/* Common (in-kernel/user-space) ACPICA configuration */
+
#define ACPI_USE_SYSTEM_CLIBRARY
#define ACPI_USE_DO_WHILE_0
#define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE
+
#ifdef __KERNEL__
#include <linux/string.h>
@@ -63,15 +66,18 @@
#include <linux/spinlock_types.h>
#include <asm/current.h>
-/* Host-dependent types and defines */
+/* Host-dependent types and defines for in-kernel ACPICA */
#define ACPI_MACHINE_WIDTH BITS_PER_LONG
-#define acpi_cache_t struct kmem_cache
-#define acpi_spinlock spinlock_t *
#define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol);
#define strtoul simple_strtoul
-#else /* !__KERNEL__ */
+#define acpi_cache_t struct kmem_cache
+#define acpi_spinlock spinlock_t *
+#define acpi_cpu_flags unsigned long
+#define acpi_thread_id struct task_struct *
+
+#else /* !__KERNEL__ */
#include <stdarg.h>
#include <string.h>
@@ -79,6 +85,11 @@
#include <ctype.h>
#include <unistd.h>
+/* Host-dependent types and defines for user-space ACPICA */
+
+#define ACPI_FLUSH_CPU_CACHE()
+#define acpi_thread_id pthread_t
+
#if defined(__ia64__) || defined(__x86_64__)
#define ACPI_MACHINE_WIDTH 64
#define COMPILER_DEPENDENT_INT64 long
@@ -94,17 +105,17 @@
#define __cdecl
#endif
-#define ACPI_FLUSH_CPU_CACHE()
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
/* Linux uses GCC */
#include "acgcc.h"
-#define acpi_cpu_flags unsigned long
-
-#define acpi_thread_id struct task_struct *
+#ifdef __KERNEL__
+/*
+ * Overrides for in-kernel ACPICA
+ */
static inline acpi_thread_id acpi_os_get_thread_id(void)
{
return current;
@@ -119,30 +130,32 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
#include <acpi/actypes.h>
static inline void *acpi_os_allocate(acpi_size size)
{
- return kmalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL);
+ return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
}
+
static inline void *acpi_os_allocate_zeroed(acpi_size size)
{
- return kzalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL);
+ return kzalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
}
static inline void *acpi_os_acquire_object(acpi_cache_t * cache)
{
return kmem_cache_zalloc(cache,
- irqs_disabled()? GFP_ATOMIC : GFP_KERNEL);
+ irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
}
-#define ACPI_ALLOCATE(a) acpi_os_allocate(a)
-#define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a)
-#define ACPI_FREE(a) kfree(a)
+#define ACPI_ALLOCATE(a) acpi_os_allocate(a)
+#define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a)
+#define ACPI_FREE(a) kfree(a)
-/*
- * We need to show where it is safe to preempt execution of ACPICA
- */
-#define ACPI_PREEMPTION_POINT() \
- do { \
- if (!irqs_disabled()) \
- cond_resched(); \
+/* Used within ACPICA to show where it is safe to preempt execution */
+
+#define ACPI_PREEMPTION_POINT() \
+ do { \
+ if (!irqs_disabled()) \
+ cond_resched(); \
} while (0)
-#endif /* __ACLINUX_H__ */
+#endif /* __KERNEL__ */
+
+#endif /* __ACLINUX_H__ */
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index e727fe0d1451..4b6755984d24 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -58,12 +58,13 @@ struct bug_entry {
*/
#ifndef __WARN
#ifndef __ASSEMBLY__
-extern void warn_slowpath(const char *file, const int line,
+extern void warn_slowpath_fmt(const char *file, const int line,
const char *fmt, ...) __attribute__((format(printf, 3, 4)));
+extern void warn_slowpath_null(const char *file, const int line);
#define WANT_WARN_ON_SLOWPATH
#endif
-#define __WARN() warn_slowpath(__FILE__, __LINE__, NULL)
-#define __WARN_printf(arg...) warn_slowpath(__FILE__, __LINE__, arg)
+#define __WARN() warn_slowpath_null(__FILE__, __LINE__)
+#define __WARN_printf(arg...) warn_slowpath_fmt(__FILE__, __LINE__, arg)
#else
#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0)
#endif
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 8e6d0ca70aba..e410f602cab1 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -280,17 +280,18 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm,
#endif
/*
- * A facility to provide batching of the reload of page tables with the
- * actual context switch code for paravirtualized guests. By convention,
- * only one of the lazy modes (CPU, MMU) should be active at any given
- * time, entry should never be nested, and entry and exits should always
- * be paired. This is for sanity of maintaining and reasoning about the
- * kernel code.
+ * A facility to provide batching of the reload of page tables and
+ * other process state with the actual context switch code for
+ * paravirtualized guests. By convention, only one of the batched
+ * update (lazy) modes (CPU, MMU) should be active at any given time,
+ * entry should never be nested, and entry and exits should always be
+ * paired. This is for sanity of maintaining and reasoning about the
+ * kernel code. In this case, the exit (end of the context switch) is
+ * in architecture-specific code, and so doesn't need a generic
+ * definition.
*/
-#ifndef __HAVE_ARCH_ENTER_LAZY_CPU_MODE
-#define arch_enter_lazy_cpu_mode() do {} while (0)
-#define arch_leave_lazy_cpu_mode() do {} while (0)
-#define arch_flush_lazy_cpu_mode() do {} while (0)
+#ifndef __HAVE_ARCH_START_CONTEXT_SWITCH
+#define arch_start_context_switch(prev) do {} while (0)
#endif
#ifndef __HAVE_PFNMAP_TRACKING
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 89853bcd27a6..f1736ca7922c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -63,7 +63,7 @@
#define BRANCH_PROFILE()
#endif
-#ifdef CONFIG_EVENT_TRACER
+#ifdef CONFIG_EVENT_TRACING
#define FTRACE_EVENTS() VMLINUX_SYMBOL(__start_ftrace_events) = .; \
*(_ftrace_events) \
VMLINUX_SYMBOL(__stop_ftrace_events) = .;
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index ca9b9b9bd331..3f0eaa397ef5 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -138,6 +138,7 @@ header-y += qnxtypes.h
header-y += radeonfb.h
header-y += raw.h
header-y += resource.h
+header-y += romfs_fs.h
header-y += rose.h
header-y += serial_reg.h
header-y += smbno.h
@@ -314,7 +315,6 @@ unifdef-y += irqnr.h
unifdef-y += reboot.h
unifdef-y += reiserfs_fs.h
unifdef-y += reiserfs_xattr.h
-unifdef-y += romfs_fs.h
unifdef-y += route.h
unifdef-y += rtc.h
unifdef-y += rtnetlink.h
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 88be890ee3c7..51b4b0a5ce8c 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -119,7 +119,7 @@ extern int pci_mmcfg_config_num;
extern int sbf_port;
extern unsigned long acpi_realmode_flags;
-int acpi_register_gsi (u32 gsi, int triggering, int polarity);
+int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity);
int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
#ifdef CONFIG_X86_IO_APIC
diff --git a/include/linux/atmel-mci.h b/include/linux/atmel-mci.h
index 2f1f95737acb..57b1846a3c87 100644
--- a/include/linux/atmel-mci.h
+++ b/include/linux/atmel-mci.h
@@ -10,6 +10,7 @@
* @bus_width: Number of data lines wired up the slot
* @detect_pin: GPIO pin wired to the card detect switch
* @wp_pin: GPIO pin wired to the write protect sensor
+ * @detect_is_active_high: The state of the detect pin when it is active
*
* If a given slot is not present on the board, @bus_width should be
* set to 0. The other fields are ignored in this case.
@@ -24,6 +25,7 @@ struct mci_slot_pdata {
unsigned int bus_width;
int detect_pin;
int wp_pin;
+ bool detect_is_active_high;
};
/**
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 7b214fd672a2..d30ec6f30dd7 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -218,12 +218,12 @@ struct bio {
#define bio_sectors(bio) ((bio)->bi_size >> 9)
#define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio) && !bio_discard(bio))
-static inline unsigned int bio_cur_sectors(struct bio *bio)
+static inline unsigned int bio_cur_bytes(struct bio *bio)
{
if (bio->bi_vcnt)
- return bio_iovec(bio)->bv_len >> 9;
+ return bio_iovec(bio)->bv_len;
else /* dataless requests such as discard */
- return bio->bi_size >> 9;
+ return bio->bi_size;
}
static inline void *bio_data(struct bio *bio)
@@ -506,7 +506,7 @@ static inline int bio_has_data(struct bio *bio)
}
/*
- * BIO list managment for use by remapping drivers (e.g. DM or MD).
+ * BIO list management for use by remapping drivers (e.g. DM or MD) and loop.
*
* A bio_list anchors a singly-linked list of bios chained through the bi_next
* member of the bio. The bio_list also caches the last list member to allow
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index b4f71f1a4af7..3b5c56489292 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -166,19 +166,9 @@ struct request {
enum rq_cmd_type_bits cmd_type;
unsigned long atomic_flags;
- /* Maintain bio traversal state for part by part I/O submission.
- * hard_* are block layer internals, no driver should touch them!
- */
-
- sector_t sector; /* next sector to submit */
- sector_t hard_sector; /* next sector to complete */
- unsigned long nr_sectors; /* no. of sectors left to submit */
- unsigned long hard_nr_sectors; /* no. of sectors left to complete */
- /* no. of sectors left to submit in the current segment */
- unsigned int current_nr_sectors;
-
- /* no. of sectors left to complete in the current segment */
- unsigned int hard_cur_sectors;
+ /* the following two fields are internal, NEVER access directly */
+ sector_t __sector; /* sector cursor */
+ unsigned int __data_len; /* total data len */
struct bio *bio;
struct bio *biotail;
@@ -211,8 +201,8 @@ struct request {
unsigned short ioprio;
- void *special;
- char *buffer;
+ void *special; /* opaque pointer available for LLD use */
+ char *buffer; /* kaddr of the current segment if available */
int tag;
int errors;
@@ -226,10 +216,9 @@ struct request {
unsigned char __cmd[BLK_MAX_CDB];
unsigned char *cmd;
- unsigned int data_len;
unsigned int extra_len; /* length of alignment and padding */
unsigned int sense_len;
- void *data;
+ unsigned int resid_len; /* residual count */
void *sense;
unsigned long deadline;
@@ -798,7 +787,6 @@ extern void blk_sync_queue(struct request_queue *q);
extern void __blk_stop_queue(struct request_queue *q);
extern void __blk_run_queue(struct request_queue *);
extern void blk_run_queue(struct request_queue *);
-extern void blk_start_queueing(struct request_queue *);
extern int blk_rq_map_user(struct request_queue *, struct request *,
struct rq_map_data *, void __user *, unsigned long,
gfp_t);
@@ -831,41 +819,185 @@ static inline void blk_run_address_space(struct address_space *mapping)
blk_run_backing_dev(mapping->backing_dev_info, NULL);
}
-extern void blkdev_dequeue_request(struct request *req);
+/*
+ * blk_rq_pos() : the current sector
+ * blk_rq_bytes() : bytes left in the entire request
+ * blk_rq_cur_bytes() : bytes left in the current segment
+ * blk_rq_sectors() : sectors left in the entire request
+ * blk_rq_cur_sectors() : sectors left in the current segment
+ */
+static inline sector_t blk_rq_pos(const struct request *rq)
+{
+ return rq->__sector;
+}
+
+static inline unsigned int blk_rq_bytes(const struct request *rq)
+{
+ return rq->__data_len;
+}
+
+static inline int blk_rq_cur_bytes(const struct request *rq)
+{
+ return rq->bio ? bio_cur_bytes(rq->bio) : 0;
+}
+
+static inline unsigned int blk_rq_sectors(const struct request *rq)
+{
+ return blk_rq_bytes(rq) >> 9;
+}
+
+static inline unsigned int blk_rq_cur_sectors(const struct request *rq)
+{
+ return blk_rq_cur_bytes(rq) >> 9;
+}
+
+/*
+ * Request issue related functions.
+ */
+extern struct request *blk_peek_request(struct request_queue *q);
+extern void blk_start_request(struct request *rq);
+extern struct request *blk_fetch_request(struct request_queue *q);
/*
- * blk_end_request() and friends.
- * __blk_end_request() and end_request() must be called with
- * the request queue spinlock acquired.
+ * Request completion related functions.
+ *
+ * blk_update_request() completes given number of bytes and updates
+ * the request without completing it.
+ *
+ * blk_end_request() and friends. __blk_end_request() must be called
+ * with the request queue spinlock acquired.
*
* Several drivers define their own end_request and call
* blk_end_request() for parts of the original function.
* This prevents code duplication in drivers.
*/
-extern int blk_end_request(struct request *rq, int error,
- unsigned int nr_bytes);
-extern int __blk_end_request(struct request *rq, int error,
- unsigned int nr_bytes);
-extern int blk_end_bidi_request(struct request *rq, int error,
- unsigned int nr_bytes, unsigned int bidi_bytes);
-extern void end_request(struct request *, int);
-extern int blk_end_request_callback(struct request *rq, int error,
- unsigned int nr_bytes,
- int (drv_callback)(struct request *));
+extern bool blk_update_request(struct request *rq, int error,
+ unsigned int nr_bytes);
+extern bool blk_end_bidi_request(struct request *rq, int error,
+ unsigned int nr_bytes,
+ unsigned int bidi_bytes);
+extern bool __blk_end_bidi_request(struct request *rq, int error,
+ unsigned int nr_bytes,
+ unsigned int bidi_bytes);
+
+/**
+ * blk_end_request - Helper function for drivers to complete the request.
+ * @rq: the request being processed
+ * @error: %0 for success, < %0 for error
+ * @nr_bytes: number of bytes to complete
+ *
+ * Description:
+ * Ends I/O on a number of bytes attached to @rq.
+ * If @rq has leftover, sets it up for the next range of segments.
+ *
+ * Return:
+ * %false - we are done with this request
+ * %true - still buffers pending for this request
+ **/
+static inline bool blk_end_request(struct request *rq, int error,
+ unsigned int nr_bytes)
+{
+ return blk_end_bidi_request(rq, error, nr_bytes, 0);
+}
+
+/**
+ * blk_end_request_all - Helper function for drives to finish the request.
+ * @rq: the request to finish
+ * @err: %0 for success, < %0 for error
+ *
+ * Description:
+ * Completely finish @rq.
+ */
+static inline void blk_end_request_all(struct request *rq, int error)
+{
+ bool pending;
+ unsigned int bidi_bytes = 0;
+
+ if (unlikely(blk_bidi_rq(rq)))
+ bidi_bytes = blk_rq_bytes(rq->next_rq);
+
+ pending = blk_end_bidi_request(rq, error, blk_rq_bytes(rq), bidi_bytes);
+ BUG_ON(pending);
+}
+
+/**
+ * blk_end_request_cur - Helper function to finish the current request chunk.
+ * @rq: the request to finish the current chunk for
+ * @err: %0 for success, < %0 for error
+ *
+ * Description:
+ * Complete the current consecutively mapped chunk from @rq.
+ *
+ * Return:
+ * %false - we are done with this request
+ * %true - still buffers pending for this request
+ */
+static inline bool blk_end_request_cur(struct request *rq, int error)
+{
+ return blk_end_request(rq, error, blk_rq_cur_bytes(rq));
+}
+
+/**
+ * __blk_end_request - Helper function for drivers to complete the request.
+ * @rq: the request being processed
+ * @error: %0 for success, < %0 for error
+ * @nr_bytes: number of bytes to complete
+ *
+ * Description:
+ * Must be called with queue lock held unlike blk_end_request().
+ *
+ * Return:
+ * %false - we are done with this request
+ * %true - still buffers pending for this request
+ **/
+static inline bool __blk_end_request(struct request *rq, int error,
+ unsigned int nr_bytes)
+{
+ return __blk_end_bidi_request(rq, error, nr_bytes, 0);
+}
+
+/**
+ * __blk_end_request_all - Helper function for drives to finish the request.
+ * @rq: the request to finish
+ * @err: %0 for success, < %0 for error
+ *
+ * Description:
+ * Completely finish @rq. Must be called with queue lock held.
+ */
+static inline void __blk_end_request_all(struct request *rq, int error)
+{
+ bool pending;
+ unsigned int bidi_bytes = 0;
+
+ if (unlikely(blk_bidi_rq(rq)))
+ bidi_bytes = blk_rq_bytes(rq->next_rq);
+
+ pending = __blk_end_bidi_request(rq, error, blk_rq_bytes(rq), bidi_bytes);
+ BUG_ON(pending);
+}
+
+/**
+ * __blk_end_request_cur - Helper function to finish the current request chunk.
+ * @rq: the request to finish the current chunk for
+ * @err: %0 for success, < %0 for error
+ *
+ * Description:
+ * Complete the current consecutively mapped chunk from @rq. Must
+ * be called with queue lock held.
+ *
+ * Return:
+ * %false - we are done with this request
+ * %true - still buffers pending for this request
+ */
+static inline bool __blk_end_request_cur(struct request *rq, int error)
+{
+ return __blk_end_request(rq, error, blk_rq_cur_bytes(rq));
+}
+
extern void blk_complete_request(struct request *);
extern void __blk_complete_request(struct request *);
extern void blk_abort_request(struct request *);
extern void blk_abort_queue(struct request_queue *);
-extern void blk_update_request(struct request *rq, int error,
- unsigned int nr_bytes);
-
-/*
- * blk_end_request() takes bytes instead of sectors as a complete size.
- * blk_rq_bytes() returns bytes left to complete in the entire request.
- * blk_rq_cur_bytes() returns bytes left to complete in the current segment.
- */
-extern unsigned int blk_rq_bytes(struct request *rq);
-extern unsigned int blk_rq_cur_bytes(struct request *rq);
/*
* Access functions for manipulating queue properties
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index d960889e92ef..82b4636030e9 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -116,9 +116,9 @@ struct blk_io_trace {
* The remap event
*/
struct blk_io_trace_remap {
- __be32 device;
__be32 device_from;
- __be64 sector;
+ __be32 device_to;
+ __be64 sector_from;
};
enum {
@@ -165,8 +165,9 @@ struct blk_trace {
extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *);
extern void blk_trace_shutdown(struct request_queue *);
-extern int do_blk_trace_setup(struct request_queue *q,
- char *name, dev_t dev, struct blk_user_trace_setup *buts);
+extern int do_blk_trace_setup(struct request_queue *q, char *name,
+ dev_t dev, struct block_device *bdev,
+ struct blk_user_trace_setup *buts);
extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
/**
@@ -193,22 +194,29 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
extern void blk_add_driver_data(struct request_queue *q, struct request *rq,
void *data, size_t len);
extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+ struct block_device *bdev,
char __user *arg);
extern int blk_trace_startstop(struct request_queue *q, int start);
extern int blk_trace_remove(struct request_queue *q);
+extern int blk_trace_init_sysfs(struct device *dev);
extern struct attribute_group blk_trace_attr_group;
#else /* !CONFIG_BLK_DEV_IO_TRACE */
-#define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY)
-#define blk_trace_shutdown(q) do { } while (0)
-#define do_blk_trace_setup(q, name, dev, buts) (-ENOTTY)
-#define blk_add_driver_data(q, rq, data, len) do {} while (0)
-#define blk_trace_setup(q, name, dev, arg) (-ENOTTY)
-#define blk_trace_startstop(q, start) (-ENOTTY)
-#define blk_trace_remove(q) (-ENOTTY)
-#define blk_add_trace_msg(q, fmt, ...) do { } while (0)
+# define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY)
+# define blk_trace_shutdown(q) do { } while (0)
+# define do_blk_trace_setup(q, name, dev, bdev, buts) (-ENOTTY)
+# define blk_add_driver_data(q, rq, data, len) do {} while (0)
+# define blk_trace_setup(q, name, dev, bdev, arg) (-ENOTTY)
+# define blk_trace_startstop(q, start) (-ENOTTY)
+# define blk_trace_remove(q) (-ENOTTY)
+# define blk_add_trace_msg(q, fmt, ...) do { } while (0)
+static inline int blk_trace_init_sysfs(struct device *dev)
+{
+ return 0;
+}
#endif /* CONFIG_BLK_DEV_IO_TRACE */
+
#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 5a40d14daa9f..c56457c8334e 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -288,7 +288,15 @@ static inline cycle_t clocksource_read(struct clocksource *cs)
*/
static inline int clocksource_enable(struct clocksource *cs)
{
- return cs->enable ? cs->enable(cs) : 0;
+ int ret = 0;
+
+ if (cs->enable)
+ ret = cs->enable(cs);
+
+ /* save mult_orig on enable */
+ cs->mult_orig = cs->mult;
+
+ return ret;
}
/**
diff --git a/include/linux/compat.h b/include/linux/compat.h
index f2ded21f9a3c..af931ee43dd8 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -222,6 +222,8 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from);
int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from);
int get_compat_sigevent(struct sigevent *event,
const struct compat_sigevent __user *u_event);
+long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig,
+ struct compat_siginfo __user *uinfo);
static inline int compat_timeval_compare(struct compat_timeval *lhs,
struct compat_timeval *rhs)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 37bcb50a4d7c..04fb5135b4e1 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -261,6 +261,11 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
# define __section(S) __attribute__ ((__section__(#S)))
#endif
+/* Are two types/vars the same type (ignoring qualifiers)? */
+#ifndef __same_type
+# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
+#endif
+
/*
* Prevent the compiler from merging or refetching accesses. The compiler
* is also forbidden from reordering successive instances of ACCESS_ONCE(),
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 2643d848df90..4d668e05d458 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -69,7 +69,6 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb)
int cpu_up(unsigned int cpu);
void notify_cpu_starting(unsigned int cpu);
-extern void cpu_hotplug_init(void);
extern void cpu_maps_update_begin(void);
extern void cpu_maps_update_done(void);
@@ -84,10 +83,6 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb)
{
}
-static inline void cpu_hotplug_init(void)
-{
-}
-
static inline void cpu_maps_update_begin(void)
{
}
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h
index 788850ba4e75..1fbdea4f08eb 100644
--- a/include/linux/cyclades.h
+++ b/include/linux/cyclades.h
@@ -142,19 +142,6 @@ struct CYZ_BOOT_CTRL {
#ifndef DP_WINDOW_SIZE
-/* #include "cyclomz.h" */
-/****************** ****************** *******************/
-/*
- * The data types defined below are used in all ZFIRM interface
- * data structures. They accomodate differences between HW
- * architectures and compilers.
- */
-
-typedef __u64 ucdouble; /* 64 bits, unsigned */
-typedef __u32 uclong; /* 32 bits, unsigned */
-typedef __u16 ucshort; /* 16 bits, unsigned */
-typedef __u8 ucchar; /* 8 bits, unsigned */
-
/*
* Memory Window Sizes
*/
@@ -507,16 +494,20 @@ struct ZFW_CTRL {
/* Per card data structure */
struct cyclades_card {
- void __iomem *base_addr;
- void __iomem *ctl_addr;
- int irq;
- 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;
+ void __iomem *base_addr;
+ union {
+ void __iomem *p9050;
+ struct RUNTIME_9060 __iomem *p9060;
+ } ctl_addr;
+ int irq;
+ 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 */
+ u32 hw_ver;
+ spinlock_t card_lock;
+ struct cyclades_port *ports;
};
/***************************************
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 15156364d196..da8066cf357f 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -351,6 +351,11 @@ static inline int d_unhashed(struct dentry *dentry)
return (dentry->d_flags & DCACHE_UNHASHED);
}
+static inline int d_unlinked(struct dentry *dentry)
+{
+ return d_unhashed(dentry) && !IS_ROOT(dentry);
+}
+
static inline struct dentry *dget_parent(struct dentry *dentry)
{
struct dentry *ret;
@@ -368,7 +373,7 @@ static inline int d_mountpoint(struct dentry *dentry)
return dentry->d_mounted;
}
-extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *);
+extern struct vfsmount *lookup_mnt(struct path *);
extern struct dentry *lookup_create(struct nameidata *nd, int is_dir);
extern int sysctl_vfs_cache_pressure;
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index ded2d7c42668..8e70c704a497 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -21,6 +21,7 @@ typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t;
union map_info {
void *ptr;
unsigned long long ll;
+ unsigned flush_request;
};
/*
@@ -168,6 +169,16 @@ struct dm_target {
sector_t split_io;
/*
+ * A number of zero-length barrier requests that will be submitted
+ * to the target for the purpose of flushing cache.
+ *
+ * The request number will be placed in union map_info->flush_request.
+ * It is a responsibility of the target driver to remap these requests
+ * to the real underlying devices.
+ */
+ unsigned num_flush_requests;
+
+ /*
* These are automatically filled in by
* dm_table_get_device.
*/
diff --git a/include/linux/device.h b/include/linux/device.h
index 6a69caaac18a..5d5c197bad45 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -384,13 +384,8 @@ struct device {
struct device_driver *driver; /* which driver has allocated this
device */
void *driver_data; /* data private to the driver */
-
- void *platform_data; /* We will remove platform_data
- field if all platform devices
- pass its platform specific data
- from platform_device->platform_data,
- other kind of devices should not
- use platform_data. */
+ void *platform_data; /* Platform specific data, device
+ core doesn't touch it */
struct dev_pm_info power;
#ifdef CONFIG_NUMA
diff --git a/include/linux/dlm.h b/include/linux/dlm.h
index b9cd38603fd8..0b3518c42356 100644
--- a/include/linux/dlm.h
+++ b/include/linux/dlm.h
@@ -81,8 +81,8 @@ struct dlm_lksb {
* the cluster, the calling node joins it.
*/
-int dlm_new_lockspace(char *name, int namelen, dlm_lockspace_t **lockspace,
- uint32_t flags, int lvblen);
+int dlm_new_lockspace(const char *name, int namelen,
+ dlm_lockspace_t **lockspace, uint32_t flags, int lvblen);
/*
* dlm_release_lockspace
diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
index 28d53cb7b5a2..171ad8aedc83 100644
--- a/include/linux/dma-debug.h
+++ b/include/linux/dma-debug.h
@@ -32,6 +32,8 @@ extern void dma_debug_add_bus(struct bus_type *bus);
extern void dma_debug_init(u32 num_entries);
+extern int dma_debug_resize_entries(u32 num_entries);
+
extern void debug_dma_map_page(struct device *dev, struct page *page,
size_t offset, size_t size,
int direction, dma_addr_t dma_addr,
@@ -91,6 +93,11 @@ static inline void dma_debug_init(u32 num_entries)
{
}
+static inline int dma_debug_resize_entries(u32 num_entries)
+{
+ return 0;
+}
+
static inline void debug_dma_map_page(struct device *dev, struct page *page,
size_t offset, size_t size,
int direction, dma_addr_t dma_addr,
diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h
index 1a455f1f86d7..e0a03aff63d9 100644
--- a/include/linux/dma_remapping.h
+++ b/include/linux/dma_remapping.h
@@ -13,6 +13,9 @@
#define DMA_PTE_WRITE (2)
#define DMA_PTE_SNP (1 << 11)
+#define CONTEXT_TT_MULTI_LEVEL 0
+#define CONTEXT_TT_PASS_THROUGH 2
+
struct intel_iommu;
struct dmar_domain;
struct root_entry;
@@ -21,11 +24,16 @@ extern void free_dmar_iommu(struct intel_iommu *iommu);
#ifdef CONFIG_DMAR
extern int iommu_calculate_agaw(struct intel_iommu *iommu);
+extern int iommu_calculate_max_sagaw(struct intel_iommu *iommu);
#else
static inline int iommu_calculate_agaw(struct intel_iommu *iommu)
{
return 0;
}
+static inline int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
+{
+ return 0;
+}
#endif
extern int dmar_disabled;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 2e2aa3df170c..ffefba81c818 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -78,12 +78,18 @@ enum dma_transaction_type {
* dependency chains
* @DMA_COMPL_SKIP_SRC_UNMAP - set to disable dma-unmapping the source buffer(s)
* @DMA_COMPL_SKIP_DEST_UNMAP - set to disable dma-unmapping the destination(s)
+ * @DMA_COMPL_SRC_UNMAP_SINGLE - set to do the source dma-unmapping as single
+ * (if not set, do the source dma-unmapping as page)
+ * @DMA_COMPL_DEST_UNMAP_SINGLE - set to do the destination dma-unmapping as single
+ * (if not set, do the destination dma-unmapping as page)
*/
enum dma_ctrl_flags {
DMA_PREP_INTERRUPT = (1 << 0),
DMA_CTRL_ACK = (1 << 1),
DMA_COMPL_SKIP_SRC_UNMAP = (1 << 2),
DMA_COMPL_SKIP_DEST_UNMAP = (1 << 3),
+ DMA_COMPL_SRC_UNMAP_SINGLE = (1 << 4),
+ DMA_COMPL_DEST_UNMAP_SINGLE = (1 << 5),
};
/**
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index e397dc342cda..10ff5c498824 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -108,6 +108,7 @@ struct irte {
};
#ifdef CONFIG_INTR_REMAP
extern int intr_remapping_enabled;
+extern int intr_remapping_supported(void);
extern int enable_intr_remapping(int);
extern void disable_intr_remapping(void);
extern int reenable_intr_remapping(int);
@@ -157,6 +158,8 @@ static inline struct intel_iommu *map_ioapic_to_ir(int apic)
}
#define irq_remapped(irq) (0)
#define enable_intr_remapping(mode) (-1)
+#define disable_intr_remapping() (0)
+#define reenable_intr_remapping(mode) (0)
#define intr_remapping_enabled (0)
#endif
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index c59b769f62b0..1cb3372e65d8 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -103,10 +103,8 @@ extern int elv_merge(struct request_queue *, struct request **, struct bio *);
extern void elv_merge_requests(struct request_queue *, struct request *,
struct request *);
extern void elv_merged_request(struct request_queue *, struct request *, int);
-extern void elv_dequeue_request(struct request_queue *, struct request *);
extern void elv_requeue_request(struct request_queue *, struct request *);
extern int elv_queue_empty(struct request_queue *);
-extern struct request *elv_next_request(struct request_queue *q);
extern struct request *elv_former_request(struct request_queue *, struct request *);
extern struct request *elv_latter_request(struct request_queue *, struct request *);
extern int elv_register_queue(struct request_queue *q);
@@ -171,7 +169,7 @@ enum {
ELV_MQUEUE_MUST,
};
-#define rq_end_sector(rq) ((rq)->sector + (rq)->nr_sectors)
+#define rq_end_sector(rq) (blk_rq_pos(rq) + blk_rq_sectors(rq))
#define rb_entry_rq(node) rb_entry((node), struct request, rb_node)
/*
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index a1f17abba7dc..3d7a6687d247 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -182,6 +182,33 @@ static inline unsigned compare_ether_addr_64bits(const u8 addr1[6+2],
return compare_ether_addr(addr1, addr2);
#endif
}
+
+/**
+ * is_etherdev_addr - Tell if given Ethernet address belongs to the device.
+ * @dev: Pointer to a device structure
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Compare passed address with all addresses of the device. Return true if the
+ * address if one of the device addresses.
+ *
+ * Note that this function calls compare_ether_addr_64bits() so take care of
+ * the right padding.
+ */
+static inline bool is_etherdev_addr(const struct net_device *dev,
+ const u8 addr[6 + 2])
+{
+ struct netdev_hw_addr *ha;
+ int res = 1;
+
+ rcu_read_lock();
+ for_each_dev_addr(dev, ha) {
+ res = compare_ether_addr_64bits(addr, ha->addr);
+ if (!res)
+ break;
+ }
+ rcu_read_unlock();
+ return !res;
+}
#endif /* __KERNEL__ */
/**
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 131b127b70f8..380b04272bf1 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -26,11 +26,13 @@ struct ethtool_cmd {
__u8 phy_address;
__u8 transceiver; /* Which transceiver to use */
__u8 autoneg; /* Enable or disable autonegotiation */
+ __u8 mdio_support;
__u32 maxtxpkt; /* Tx pkts before generating tx int */
__u32 maxrxpkt; /* Rx pkts before generating rx int */
__u16 speed_hi;
__u16 reserved2;
- __u32 reserved[3];
+ __u32 lp_advertising; /* Features the link partner advertises */
+ __u32 reserved[2];
};
static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
@@ -563,6 +565,11 @@ struct ethtool_ops {
#define SUPPORTED_Pause (1 << 13)
#define SUPPORTED_Asym_Pause (1 << 14)
#define SUPPORTED_2500baseX_Full (1 << 15)
+#define SUPPORTED_Backplane (1 << 16)
+#define SUPPORTED_1000baseKX_Full (1 << 17)
+#define SUPPORTED_10000baseKX4_Full (1 << 18)
+#define SUPPORTED_10000baseKR_Full (1 << 19)
+#define SUPPORTED_10000baseR_FEC (1 << 20)
/* Indicates what features are advertised by the interface. */
#define ADVERTISED_10baseT_Half (1 << 0)
@@ -581,6 +588,11 @@ struct ethtool_ops {
#define ADVERTISED_Pause (1 << 13)
#define ADVERTISED_Asym_Pause (1 << 14)
#define ADVERTISED_2500baseX_Full (1 << 15)
+#define ADVERTISED_Backplane (1 << 16)
+#define ADVERTISED_1000baseKX_Full (1 << 17)
+#define ADVERTISED_10000baseKX4_Full (1 << 18)
+#define ADVERTISED_10000baseKR_Full (1 << 19)
+#define ADVERTISED_10000baseR_FEC (1 << 20)
/* The following are all involved in forcing a particular link
* mode for the device for setting things. When getting the
@@ -605,6 +617,7 @@ struct ethtool_ops {
#define PORT_MII 0x02
#define PORT_FIBRE 0x03
#define PORT_BNC 0x04
+#define PORT_OTHER 0xff
/* Which transceiver to use. */
#define XCVR_INTERNAL 0x00
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 5bed436f4353..7eb540053866 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1108,6 +1108,7 @@ extern void locks_copy_lock(struct file_lock *, struct file_lock *);
extern void __locks_copy_lock(struct file_lock *, const struct file_lock *);
extern void locks_remove_posix(struct file *, fl_owner_t);
extern void locks_remove_flock(struct file *);
+extern void locks_release_private(struct file_lock *);
extern void posix_test_lock(struct file *, struct file_lock *);
extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *);
extern int posix_lock_file_wait(struct file *, struct file_lock *);
@@ -1321,7 +1322,7 @@ struct super_block {
struct rw_semaphore s_umount;
struct mutex s_lock;
int s_count;
- int s_need_sync_fs;
+ int s_need_sync;
atomic_t s_active;
#ifdef CONFIG_SECURITY
void *s_security;
@@ -1372,11 +1373,6 @@ struct super_block {
* generic_show_options()
*/
char *s_options;
-
- /*
- * storage for asynchronous operations
- */
- struct list_head s_async_list;
};
extern struct timespec current_fs_time(struct super_block *sb);
@@ -1775,6 +1771,7 @@ void kill_block_super(struct super_block *sb);
void kill_anon_super(struct super_block *sb);
void kill_litter_super(struct super_block *sb);
void deactivate_super(struct super_block *sb);
+void deactivate_locked_super(struct super_block *sb);
int set_anon_super(struct super_block *s, void *data);
struct super_block *sget(struct file_system_type *type,
int (*test)(struct super_block *,void *),
@@ -1799,7 +1796,7 @@ extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
extern int may_umount_tree(struct vfsmount *);
extern int may_umount(struct vfsmount *);
extern long do_mount(char *, char *, char *, unsigned long, void *);
-extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *);
+extern struct vfsmount *collect_mounts(struct path *);
extern void drop_collected_mounts(struct vfsmount *);
extern int vfs_statfs(struct dentry *, struct kstatfs *);
@@ -1946,8 +1943,6 @@ extern struct super_block *freeze_bdev(struct block_device *);
extern void emergency_thaw_all(void);
extern int thaw_bdev(struct block_device *bdev, struct super_block *sb);
extern int fsync_bdev(struct block_device *);
-extern int fsync_super(struct super_block *);
-extern int fsync_no_super(struct block_device *);
#else
static inline void bd_forget(struct inode *inode) {}
static inline int sync_blockdev(struct block_device *bdev) { return 0; }
@@ -1963,6 +1958,7 @@ static inline int thaw_bdev(struct block_device *bdev, struct super_block *sb)
return 0;
}
#endif
+extern int sync_filesystem(struct super_block *);
extern const struct file_operations def_blk_fops;
extern const struct file_operations def_chr_fops;
extern const struct file_operations bad_sock_fops;
@@ -2081,12 +2077,8 @@ extern int filemap_fdatawrite_range(struct address_space *mapping,
extern int vfs_fsync(struct file *file, struct dentry *dentry, int datasync);
extern void sync_supers(void);
-extern void sync_filesystems(int wait);
-extern void __fsync_super(struct super_block *sb);
extern void emergency_sync(void);
extern void emergency_remount(void);
-extern int do_remount_sb(struct super_block *sb, int flags,
- void *data, int force);
#ifdef CONFIG_BLOCK
extern sector_t bmap(struct inode *, sector_t);
#endif
@@ -2117,7 +2109,7 @@ extern struct file *create_write_pipe(int flags);
extern void free_write_pipe(struct file *);
extern struct file *do_filp_open(int dfd, const char *pathname,
- int open_flag, int mode);
+ int open_flag, int mode, int acc_mode);
extern int may_open(struct path *, int, int);
extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
@@ -2204,6 +2196,8 @@ extern int generic_segment_checks(const struct iovec *iov,
/* fs/splice.c */
extern ssize_t generic_file_splice_read(struct file *, loff_t *,
struct pipe_inode_info *, size_t, unsigned int);
+extern ssize_t default_file_splice_read(struct file *, loff_t *,
+ struct pipe_inode_info *, size_t, unsigned int);
extern ssize_t generic_file_splice_write(struct pipe_inode_info *,
struct file *, loff_t *, size_t, unsigned int);
extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe,
@@ -2367,6 +2361,7 @@ extern void file_update_time(struct file *file);
extern int generic_show_options(struct seq_file *m, struct vfsmount *mnt);
extern void save_mount_options(struct super_block *sb, char *options);
+extern void replace_mount_options(struct super_block *sb, char *options);
static inline ino_t parent_ino(struct dentry *dentry)
{
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index 8300cab30f9a..51b793466ff3 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -17,6 +17,7 @@
#define FS_ENET_PD_H
#include <linux/string.h>
+#include <linux/of_mdio.h>
#include <asm/types.h>
#define FS_ENET_NAME "fs_enet"
@@ -130,10 +131,7 @@ struct fs_platform_info {
u32 device_flags;
- int phy_addr; /* the phy address (-1 no phy) */
- char bus_id[16];
- int phy_irq; /* the phy irq (if it exists) */
-
+ struct device_node *phy_node;
const struct fs_mii_bus_info *bus_info;
int rx_ring, tx_ring; /* number of buffers on rx */
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 8a0c2f221e6b..39b95c56587e 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -233,8 +233,6 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
extern int skip_trace(unsigned long ip);
-extern void ftrace_release(void *start, unsigned long size);
-
extern void ftrace_disable_daemon(void);
extern void ftrace_enable_daemon(void);
#else
@@ -325,13 +323,8 @@ static inline void __ftrace_enabled_restore(int enabled)
#ifdef CONFIG_FTRACE_MCOUNT_RECORD
extern void ftrace_init(void);
-extern void ftrace_init_module(struct module *mod,
- unsigned long *start, unsigned long *end);
#else
static inline void ftrace_init(void) { }
-static inline void
-ftrace_init_module(struct module *mod,
- unsigned long *start, unsigned long *end) { }
#endif
/*
@@ -368,6 +361,7 @@ struct ftrace_ret_stack {
unsigned long ret;
unsigned long func;
unsigned long long calltime;
+ unsigned long long subtime;
};
/*
@@ -379,8 +373,6 @@ extern void return_to_handler(void);
extern int
ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth);
-extern void
-ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret);
/*
* Sometimes we don't want to trace a function with the function
@@ -496,8 +488,15 @@ static inline int test_tsk_trace_graph(struct task_struct *tsk)
extern int ftrace_dump_on_oops;
+#ifdef CONFIG_PREEMPT
+#define INIT_TRACE_RECURSION .trace_recursion = 0,
+#endif
+
#endif /* CONFIG_TRACING */
+#ifndef INIT_TRACE_RECURSION
+#define INIT_TRACE_RECURSION
+#endif
#ifdef CONFIG_HW_BRANCH_TRACER
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
new file mode 100644
index 000000000000..bae51ddfabd3
--- /dev/null
+++ b/include/linux/ftrace_event.h
@@ -0,0 +1,158 @@
+#ifndef _LINUX_FTRACE_EVENT_H
+#define _LINUX_FTRACE_EVENT_H
+
+#include <linux/trace_seq.h>
+#include <linux/ring_buffer.h>
+
+
+struct trace_array;
+struct tracer;
+struct dentry;
+
+/*
+ * The trace entry - the most basic unit of tracing. This is what
+ * is printed in the end as a single line in the trace output, such as:
+ *
+ * bash-15816 [01] 235.197585: idle_cpu <- irq_enter
+ */
+struct trace_entry {
+ unsigned short type;
+ unsigned char flags;
+ unsigned char preempt_count;
+ int pid;
+ int tgid;
+};
+
+#define FTRACE_MAX_EVENT \
+ ((1 << (sizeof(((struct trace_entry *)0)->type) * 8)) - 1)
+
+/*
+ * Trace iterator - used by printout routines who present trace
+ * results to users and which routines might sleep, etc:
+ */
+struct trace_iterator {
+ struct trace_array *tr;
+ struct tracer *trace;
+ void *private;
+ int cpu_file;
+ struct mutex mutex;
+ struct ring_buffer_iter *buffer_iter[NR_CPUS];
+
+ /* The below is zeroed out in pipe_read */
+ struct trace_seq seq;
+ struct trace_entry *ent;
+ int cpu;
+ u64 ts;
+
+ unsigned long iter_flags;
+ loff_t pos;
+ long idx;
+
+ cpumask_var_t started;
+};
+
+
+typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter,
+ int flags);
+struct trace_event {
+ struct hlist_node node;
+ struct list_head list;
+ int type;
+ trace_print_func trace;
+ trace_print_func raw;
+ trace_print_func hex;
+ trace_print_func binary;
+};
+
+extern int register_ftrace_event(struct trace_event *event);
+extern int unregister_ftrace_event(struct trace_event *event);
+
+/* Return values for print_line callback */
+enum print_line_t {
+ TRACE_TYPE_PARTIAL_LINE = 0, /* Retry after flushing the seq */
+ TRACE_TYPE_HANDLED = 1,
+ TRACE_TYPE_UNHANDLED = 2, /* Relay to other output functions */
+ TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */
+};
+
+
+struct ring_buffer_event *
+trace_current_buffer_lock_reserve(int type, unsigned long len,
+ unsigned long flags, int pc);
+void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
+ unsigned long flags, int pc);
+void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event,
+ unsigned long flags, int pc);
+void trace_current_buffer_discard_commit(struct ring_buffer_event *event);
+
+void tracing_record_cmdline(struct task_struct *tsk);
+
+struct ftrace_event_call {
+ struct list_head list;
+ char *name;
+ char *system;
+ struct dentry *dir;
+ struct trace_event *event;
+ int enabled;
+ int (*regfunc)(void);
+ void (*unregfunc)(void);
+ int id;
+ int (*raw_init)(void);
+ int (*show_format)(struct trace_seq *s);
+ int (*define_fields)(void);
+ struct list_head fields;
+ int filter_active;
+ void *filter;
+ void *mod;
+
+#ifdef CONFIG_EVENT_PROFILE
+ atomic_t profile_count;
+ int (*profile_enable)(struct ftrace_event_call *);
+ void (*profile_disable)(struct ftrace_event_call *);
+#endif
+};
+
+#define MAX_FILTER_PRED 32
+#define MAX_FILTER_STR_VAL 128
+
+extern int init_preds(struct ftrace_event_call *call);
+extern void destroy_preds(struct ftrace_event_call *call);
+extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
+extern int filter_current_check_discard(struct ftrace_event_call *call,
+ void *rec,
+ struct ring_buffer_event *event);
+
+extern int trace_define_field(struct ftrace_event_call *call, char *type,
+ char *name, int offset, int size, int is_signed);
+
+#define is_signed_type(type) (((type)(-1)) < 0)
+
+int trace_set_clr_event(const char *system, const char *event, int set);
+
+/*
+ * The double __builtin_constant_p is because gcc will give us an error
+ * if we try to allocate the static variable to fmt if it is not a
+ * constant. Even with the outer if statement optimizing out.
+ */
+#define event_trace_printk(ip, fmt, args...) \
+do { \
+ __trace_printk_check_format(fmt, ##args); \
+ tracing_record_cmdline(current); \
+ if (__builtin_constant_p(fmt)) { \
+ static const char *trace_printk_fmt \
+ __attribute__((section("__trace_printk_fmt"))) = \
+ __builtin_constant_p(fmt) ? fmt : NULL; \
+ \
+ __trace_bprintk(ip, trace_printk_fmt, ##args); \
+ } else \
+ __trace_printk(ip, fmt, ##args); \
+} while (0)
+
+#define __common_field(type, item, is_signed) \
+ ret = trace_define_field(event_call, #type, "common_" #item, \
+ offsetof(typeof(field.ent), item), \
+ sizeof(field.ent.item), is_signed); \
+ if (ret) \
+ return ret;
+
+#endif /* _LINUX_FTRACE_EVENT_H */
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 162e5defe683..d41ed593f79f 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -121,6 +121,13 @@ struct fuse_file_lock {
#define FUSE_BIG_WRITES (1 << 5)
/**
+ * CUSE INIT request/reply flags
+ *
+ * CUSE_UNRESTRICTED_IOCTL: use unrestricted ioctl
+ */
+#define CUSE_UNRESTRICTED_IOCTL (1 << 0)
+
+/**
* Release flags
*/
#define FUSE_RELEASE_FLUSH (1 << 0)
@@ -210,6 +217,9 @@ enum fuse_opcode {
FUSE_DESTROY = 38,
FUSE_IOCTL = 39,
FUSE_POLL = 40,
+
+ /* CUSE specific operations */
+ CUSE_INIT = 4096,
};
enum fuse_notify_code {
@@ -401,6 +411,27 @@ struct fuse_init_out {
__u32 max_write;
};
+#define CUSE_INIT_INFO_MAX 4096
+
+struct cuse_init_in {
+ __u32 major;
+ __u32 minor;
+ __u32 unused;
+ __u32 flags;
+};
+
+struct cuse_init_out {
+ __u32 major;
+ __u32 minor;
+ __u32 unused;
+ __u32 flags;
+ __u32 max_read;
+ __u32 max_write;
+ __u32 dev_major; /* chardev major */
+ __u32 dev_minor; /* chardev minor */
+ __u32 spare[10];
+};
+
struct fuse_interrupt_in {
__u64 unique;
};
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 3bf5bb5a34f9..34956c8fdebf 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -23,6 +23,8 @@ union ktime;
#define FUTEX_TRYLOCK_PI 8
#define FUTEX_WAIT_BITSET 9
#define FUTEX_WAKE_BITSET 10
+#define FUTEX_WAIT_REQUEUE_PI 11
+#define FUTEX_CMP_REQUEUE_PI 12
#define FUTEX_PRIVATE_FLAG 128
#define FUTEX_CLOCK_REALTIME 256
@@ -38,6 +40,10 @@ union ktime;
#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITS | FUTEX_PRIVATE_FLAG)
#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITS | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | \
+ FUTEX_PRIVATE_FLAG)
+#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \
+ FUTEX_PRIVATE_FLAG)
/*
* Support for robust futexes: the kernel cleans up held futexes at
diff --git a/include/linux/gameport.h b/include/linux/gameport.h
index 0cd825f7363a..1bc08541c2b9 100644
--- a/include/linux/gameport.h
+++ b/include/linux/gameport.h
@@ -11,6 +11,7 @@
#ifdef __KERNEL__
#include <asm/io.h>
+#include <linux/types.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/device.h>
@@ -62,7 +63,7 @@ struct gameport_driver {
struct device_driver driver;
- unsigned int ignore;
+ bool ignore;
};
#define to_gameport_driver(d) container_of(d, struct gameport_driver, driver)
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index ad2580596033..844d2662a875 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -100,9 +100,8 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client,
* @class: What kind of i2c device we instantiate (for detect)
* @attach_adapter: Callback for bus addition (for legacy drivers)
* @detach_adapter: Callback for bus removal (for legacy drivers)
- * @detach_client: Callback for device removal (for legacy drivers)
- * @probe: Callback for device binding (new-style drivers)
- * @remove: Callback for device unbinding (new-style drivers)
+ * @probe: Callback for device binding
+ * @remove: Callback for device unbinding
* @shutdown: Callback for device shutdown
* @suspend: Callback for device suspend
* @resume: Callback for device resume
@@ -137,26 +136,14 @@ struct i2c_driver {
int id;
unsigned int class;
- /* Notifies the driver that a new bus has appeared. This routine
- * can be used by the driver to test if the bus meets its conditions
- * & seek for the presence of the chip(s) it supports. If found, it
- * registers the client(s) that are on the bus to the i2c admin. via
- * i2c_attach_client. (LEGACY I2C DRIVERS ONLY)
+ /* Notifies the driver that a new bus has appeared or is about to be
+ * removed. You should avoid using this if you can, it will probably
+ * be removed in a near future.
*/
int (*attach_adapter)(struct i2c_adapter *);
int (*detach_adapter)(struct i2c_adapter *);
- /* tells the driver that a client is about to be deleted & gives it
- * the chance to remove its private data. Also, if the client struct
- * has been dynamically allocated by the driver in the function above,
- * it must be freed here. (LEGACY I2C DRIVERS ONLY)
- */
- int (*detach_client)(struct i2c_client *) __deprecated;
-
- /* Standard driver model interfaces, for "new style" i2c drivers.
- * With the driver model, device enumeration is NEVER done by drivers;
- * it's done by infrastructure. (NEW STYLE DRIVERS ONLY)
- */
+ /* Standard driver model interfaces */
int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *);
@@ -191,9 +178,8 @@ struct i2c_driver {
* @driver: device's driver, hence pointer to access routines
* @dev: Driver model device node for the slave.
* @irq: indicates the IRQ generated by this device (if any)
- * @list: list of active/busy clients (DEPRECATED)
- * @detected: member of an i2c_driver.clients list
- * @released: used to synchronize client releases & detaches and references
+ * @detected: member of an i2c_driver.clients list or i2c-core's
+ * userspace_devices list
*
* An i2c_client identifies a single device (i.e. chip) connected to an
* i2c bus. The behaviour exposed to Linux is defined by the driver
@@ -209,9 +195,7 @@ struct i2c_client {
struct i2c_driver *driver; /* and our access routines */
struct device dev; /* the device structure */
int irq; /* irq issued by device */
- struct list_head list; /* DEPRECATED */
struct list_head detected;
- struct completion released;
};
#define to_i2c_client(d) container_of(d, struct i2c_client, dev)
@@ -248,11 +232,10 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data)
* that, such as chip type, configuration, associated IRQ, and so on.
*
* i2c_board_info is used to build tables of information listing I2C devices
- * that are present. This information is used to grow the driver model tree
- * for "new style" I2C drivers. For mainboards this is done statically using
- * i2c_register_board_info(); bus numbers identify adapters that aren't
- * yet available. For add-on boards, i2c_new_device() does this dynamically
- * with the adapter already known.
+ * that are present. This information is used to grow the driver model tree.
+ * For mainboards this is done statically using i2c_register_board_info();
+ * bus numbers identify adapters that aren't yet available. For add-on boards,
+ * i2c_new_device() does this dynamically with the adapter already known.
*/
struct i2c_board_info {
char type[I2C_NAME_SIZE];
@@ -352,21 +335,15 @@ struct i2c_adapter {
const struct i2c_algorithm *algo; /* the algorithm to access the bus */
void *algo_data;
- /* --- administration stuff. */
- int (*client_register)(struct i2c_client *) __deprecated;
- int (*client_unregister)(struct i2c_client *) __deprecated;
-
/* data fields that are valid for all devices */
u8 level; /* nesting level for lockdep */
struct mutex bus_lock;
- struct mutex clist_lock;
int timeout; /* in jiffies */
int retries;
struct device dev; /* the adapter device */
int nr;
- struct list_head clients; /* DEPRECATED */
char name[48];
struct completion dev_released;
};
@@ -429,11 +406,6 @@ static inline int i2c_add_driver(struct i2c_driver *driver)
return i2c_register_driver(THIS_MODULE, driver);
}
-/* These are deprecated, your driver should use the standard .probe()
- * and .remove() methods instead. */
-extern int __deprecated i2c_attach_client(struct i2c_client *);
-extern int __deprecated i2c_detach_client(struct i2c_client *);
-
extern struct i2c_client *i2c_use_client(struct i2c_client *client);
extern void i2c_release_client(struct i2c_client *client);
@@ -442,14 +414,6 @@ extern void i2c_release_client(struct i2c_client *client);
extern void i2c_clients_command(struct i2c_adapter *adap,
unsigned int cmd, void *arg);
-/* Detect function. It iterates over all possible addresses itself.
- * It will only call found_proc if some client is connected at the
- * specific address (unless a 'force' matched);
- */
-extern int i2c_probe(struct i2c_adapter *adapter,
- const struct i2c_client_address_data *address_data,
- int (*found_proc) (struct i2c_adapter *, int, int));
-
extern struct i2c_adapter *i2c_get_adapter(int id);
extern void i2c_put_adapter(struct i2c_adapter *adap);
diff --git a/include/linux/ide.h b/include/linux/ide.h
index ff65fffb078f..34c128f0a33c 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -26,6 +26,9 @@
#include <asm/io.h>
#include <asm/mutex.h>
+/* for request_sense */
+#include <linux/cdrom.h>
+
#if defined(CONFIG_CRIS) || defined(CONFIG_FRV) || defined(CONFIG_MN10300)
# define SUPPORT_VLB_SYNC 0
#else
@@ -324,7 +327,6 @@ struct ide_cmd {
unsigned int cursg_ofs;
struct request *rq; /* copy of request */
- void *special; /* valid_t generally */
};
/* ATAPI packet command flags */
@@ -360,11 +362,7 @@ struct ide_atapi_pc {
/* data buffer */
u8 *buf;
- /* current buffer position */
- u8 *cur_pos;
int buf_size;
- /* missing/available data on the current buffer */
- int b_count;
/* the corresponding request */
struct request *rq;
@@ -377,10 +375,6 @@ struct ide_atapi_pc {
*/
u8 pc_buf[IDE_PC_BUFFER_SIZE];
- /* idetape only */
- struct idetape_bh *bh;
- char *b_data;
-
unsigned long timeout;
};
@@ -593,16 +587,16 @@ struct ide_drive_s {
/* callback for packet commands */
int (*pc_callback)(struct ide_drive_s *, int);
- void (*pc_update_buffers)(struct ide_drive_s *, struct ide_atapi_pc *);
- int (*pc_io_buffers)(struct ide_drive_s *, struct ide_atapi_pc *,
- unsigned int, int);
-
ide_startstop_t (*irq_handler)(struct ide_drive_s *);
unsigned long atapi_flags;
struct ide_atapi_pc request_sense_pc;
- struct request request_sense_rq;
+
+ /* current sense rq and buffer */
+ bool sense_rq_armed;
+ struct request sense_rq;
+ struct request_sense sense_data;
};
typedef struct ide_drive_s ide_drive_t;
@@ -1174,7 +1168,10 @@ int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *);
int ide_do_start_stop(ide_drive_t *, struct gendisk *, int);
int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);
void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *);
-void ide_retry_pc(ide_drive_t *, struct gendisk *);
+void ide_retry_pc(ide_drive_t *drive);
+
+void ide_prep_sense(ide_drive_t *drive, struct request *rq);
+int ide_queue_sense_rq(ide_drive_t *drive, void *special);
int ide_cd_expiry(ide_drive_t *);
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 4b501b48ce86..05c29c01174c 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -540,10 +540,10 @@ struct ieee80211_tim_ie {
u8 dtim_period;
u8 bitmap_ctrl;
/* variable size: 1 - 251 bytes */
- u8 virtual_map[0];
+ u8 virtual_map[1];
} __attribute__ ((packed));
-#define WLAN_SA_QUERY_TR_ID_LEN 16
+#define WLAN_SA_QUERY_TR_ID_LEN 2
struct ieee80211_mgmt {
__le16 frame_control;
@@ -1068,8 +1068,12 @@ enum ieee80211_category {
WLAN_CATEGORY_DLS = 2,
WLAN_CATEGORY_BACK = 3,
WLAN_CATEGORY_PUBLIC = 4,
+ WLAN_CATEGORY_HT = 7,
WLAN_CATEGORY_SA_QUERY = 8,
+ WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
WLAN_CATEGORY_WMM = 17,
+ WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
+ WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
};
/* SPECTRUM_MGMT action code */
@@ -1261,7 +1265,9 @@ static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
if (ieee80211_has_protected(hdr->frame_control))
return true;
category = ((u8 *) hdr) + 24;
- return *category != WLAN_CATEGORY_PUBLIC;
+ return *category != WLAN_CATEGORY_PUBLIC &&
+ *category != WLAN_CATEGORY_HT &&
+ *category != WLAN_CATEGORY_VENDOR_SPECIFIC;
}
return false;
@@ -1383,4 +1389,43 @@ static inline int ieee80211_freq_to_ofdm_chan(int s_freq, int freq)
return -1;
}
+/**
+ * ieee80211_tu_to_usec - convert time units (TU) to microseconds
+ * @tu: the TUs
+ */
+static inline unsigned long ieee80211_tu_to_usec(unsigned long tu)
+{
+ return 1024 * tu;
+}
+
+/**
+ * ieee80211_check_tim - check if AID bit is set in TIM
+ * @tim: the TIM IE
+ * @tim_len: length of the TIM IE
+ * @aid: the AID to look for
+ */
+static inline bool ieee80211_check_tim(struct ieee80211_tim_ie *tim,
+ u8 tim_len, u16 aid)
+{
+ u8 mask;
+ u8 index, indexn1, indexn2;
+
+ if (unlikely(!tim || tim_len < sizeof(*tim)))
+ return false;
+
+ aid &= 0x3fff;
+ index = aid / 8;
+ mask = 1 << (aid & 7);
+
+ indexn1 = tim->bitmap_ctrl & 0xfe;
+ indexn2 = tim_len + indexn1 - 4;
+
+ if (index < indexn1 || index > indexn2)
+ return false;
+
+ index -= indexn1;
+
+ return !!(tim->virtual_map[index] & mask);
+}
+
#endif /* LINUX_IEEE80211_H */
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
index 049d6c9428db..915ba5789f0e 100644
--- a/include/linux/if_tun.h
+++ b/include/linux/if_tun.h
@@ -55,6 +55,7 @@
#define IFF_NO_PI 0x1000
#define IFF_ONE_QUEUE 0x2000
#define IFF_VNET_HDR 0x4000
+#define IFF_TUN_EXCL 0x8000
/* Features for GSO (TUNSETOFFLOAD). */
#define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index e1ff5b14310e..7ff9af1d0f05 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -118,8 +118,7 @@ extern int vlan_hwaccel_do_receive(struct sk_buff *skb);
extern int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
unsigned int vlan_tci, struct sk_buff *skb);
extern int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
- unsigned int vlan_tci,
- struct napi_gro_fraginfo *info);
+ unsigned int vlan_tci);
#else
static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
@@ -154,8 +153,7 @@ static inline int vlan_gro_receive(struct napi_struct *napi,
}
static inline int vlan_gro_frags(struct napi_struct *napi,
- struct vlan_group *grp, unsigned int vlan_tci,
- struct napi_gro_fraginfo *info)
+ struct vlan_group *grp, unsigned int vlan_tci)
{
return NET_RX_DROP;
}
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index d87247d2641f..6646bfc7b892 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -145,8 +145,8 @@ extern struct cred init_cred;
.group_leader = &tsk, \
.real_cred = &init_cred, \
.cred = &init_cred, \
- .cred_exec_mutex = \
- __MUTEX_INITIALIZER(tsk.cred_exec_mutex), \
+ .cred_guard_mutex = \
+ __MUTEX_INITIALIZER(tsk.cred_guard_mutex), \
.comm = "swapper", \
.thread = INIT_THREAD, \
.fs = &init_fs, \
@@ -174,6 +174,7 @@ extern struct cred init_cred;
INIT_TRACE_IRQFLAGS \
INIT_LOCKDEP \
INIT_FTRACE_GRAPH \
+ INIT_TRACE_RECURSION \
}
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index aa8c53171233..29e05a034c09 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -120,6 +120,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
(ecap_iotlb_offset(e) + ecap_niotlb_iunits(e) * 16)
#define ecap_coherent(e) ((e) & 0x1)
#define ecap_qis(e) ((e) & 0x2)
+#define ecap_pass_through(e) ((e >> 6) & 0x1)
#define ecap_eim_support(e) ((e >> 4) & 0x1)
#define ecap_ir_support(e) ((e >> 3) & 0x1)
#define ecap_max_handle_mask(e) ((e >> 20) & 0xf)
@@ -280,10 +281,10 @@ struct ir_table {
#endif
struct iommu_flush {
- int (*flush_context)(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
- u64 type, int non_present_entry_flush);
- int (*flush_iotlb)(struct intel_iommu *iommu, u16 did, u64 addr,
- unsigned int size_order, u64 type, int non_present_entry_flush);
+ void (*flush_context)(struct intel_iommu *iommu, u16 did, u16 sid,
+ u8 fm, u64 type);
+ void (*flush_iotlb)(struct intel_iommu *iommu, u16 did, u64 addr,
+ unsigned int size_order, u64 type);
};
enum {
@@ -302,6 +303,7 @@ struct intel_iommu {
spinlock_t register_lock; /* protect register handling */
int seq_id; /* sequence id of the iommu */
int agaw; /* agaw of this iommu */
+ int msagaw; /* max sagaw of this iommu */
unsigned int irq;
unsigned char name[13]; /* Device Name */
@@ -337,11 +339,10 @@ extern void dmar_disable_qi(struct intel_iommu *iommu);
extern int dmar_reenable_qi(struct intel_iommu *iommu);
extern void qi_global_iec(struct intel_iommu *iommu);
-extern int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
- u8 fm, u64 type, int non_present_entry_flush);
-extern int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
- unsigned int size_order, u64 type,
- int non_present_entry_flush);
+extern void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
+ u8 fm, u64 type);
+extern void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
+ unsigned int size_order, u64 type);
extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 91bb76f44f14..ff374ceface0 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -566,6 +566,6 @@ struct irq_desc;
extern int early_irq_init(void);
extern int arch_probe_nr_irqs(void);
extern int arch_early_irq_init(void);
-extern int arch_init_chip_data(struct irq_desc *desc, int cpu);
+extern int arch_init_chip_data(struct irq_desc *desc, int node);
#endif
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 32e4b2f72294..786e7b8cece9 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -49,6 +49,8 @@ struct resource_list {
#define IORESOURCE_SIZEALIGN 0x00020000 /* size indicates alignment */
#define IORESOURCE_STARTALIGN 0x00040000 /* start field is alignment */
+#define IORESOURCE_MEM_64 0x00100000
+
#define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */
#define IORESOURCE_DISABLED 0x10000000
#define IORESOURCE_UNSET 0x20000000
diff --git a/include/linux/irq.h b/include/linux/irq.h
index b7cbeed972e4..eedbb8e5e0cc 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -117,7 +117,7 @@ struct irq_chip {
void (*eoi)(unsigned int irq);
void (*end)(unsigned int irq);
- void (*set_affinity)(unsigned int irq,
+ int (*set_affinity)(unsigned int irq,
const struct cpumask *dest);
int (*retrigger)(unsigned int irq);
int (*set_type)(unsigned int irq, unsigned int flow_type);
@@ -187,7 +187,7 @@ struct irq_desc {
spinlock_t lock;
#ifdef CONFIG_SMP
cpumask_var_t affinity;
- unsigned int cpu;
+ unsigned int node;
#ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_var_t pending_mask;
#endif
@@ -201,26 +201,23 @@ struct irq_desc {
} ____cacheline_internodealigned_in_smp;
extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
- struct irq_desc *desc, int cpu);
+ struct irq_desc *desc, int node);
extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
#ifndef CONFIG_SPARSE_IRQ
extern struct irq_desc irq_desc[NR_IRQS];
-#else /* CONFIG_SPARSE_IRQ */
-extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
-#endif /* CONFIG_SPARSE_IRQ */
-
-extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);
+#endif
-static inline struct irq_desc *
-irq_remap_to_desc(unsigned int irq, struct irq_desc *desc)
-{
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
- return irq_to_desc(irq);
+#ifdef CONFIG_NUMA_IRQ_DESC
+extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int node);
#else
+static inline struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
+{
return desc;
-#endif
}
+#endif
+
+extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
/*
* Migration helpers for obsolete names, they will go away:
@@ -386,7 +383,7 @@ extern void set_irq_noprobe(unsigned int irq);
extern void set_irq_probe(unsigned int irq);
/* Handle dynamic irq creation and destruction */
-extern unsigned int create_irq_nr(unsigned int irq_want);
+extern unsigned int create_irq_nr(unsigned int irq_want, int node);
extern int create_irq(void);
extern void destroy_irq(unsigned int irq);
@@ -424,47 +421,48 @@ extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
#ifdef CONFIG_SMP
/**
- * init_alloc_desc_masks - allocate cpumasks for irq_desc
+ * alloc_desc_masks - allocate cpumasks for irq_desc
* @desc: pointer to irq_desc struct
* @cpu: cpu which will be handling the cpumasks
* @boot: true if need bootmem
*
* Allocates affinity and pending_mask cpumask if required.
* Returns true if successful (or not required).
- * Side effect: affinity has all bits set, pending_mask has all bits clear.
*/
-static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
+static inline bool alloc_desc_masks(struct irq_desc *desc, int node,
bool boot)
{
- int node;
-
+#ifdef CONFIG_CPUMASK_OFFSTACK
if (boot) {
alloc_bootmem_cpumask_var(&desc->affinity);
- cpumask_setall(desc->affinity);
#ifdef CONFIG_GENERIC_PENDING_IRQ
alloc_bootmem_cpumask_var(&desc->pending_mask);
- cpumask_clear(desc->pending_mask);
#endif
return true;
}
- node = cpu_to_node(cpu);
-
if (!alloc_cpumask_var_node(&desc->affinity, GFP_ATOMIC, node))
return false;
- cpumask_setall(desc->affinity);
#ifdef CONFIG_GENERIC_PENDING_IRQ
if (!alloc_cpumask_var_node(&desc->pending_mask, GFP_ATOMIC, node)) {
free_cpumask_var(desc->affinity);
return false;
}
- cpumask_clear(desc->pending_mask);
+#endif
#endif
return true;
}
+static inline void init_desc_masks(struct irq_desc *desc)
+{
+ cpumask_setall(desc->affinity);
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+ cpumask_clear(desc->pending_mask);
+#endif
+}
+
/**
* init_copy_desc_masks - copy cpumasks for irq_desc
* @old_desc: pointer to old irq_desc struct
@@ -478,7 +476,7 @@ static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
static inline void init_copy_desc_masks(struct irq_desc *old_desc,
struct irq_desc *new_desc)
{
-#ifdef CONFIG_CPUMASKS_OFFSTACK
+#ifdef CONFIG_CPUMASK_OFFSTACK
cpumask_copy(new_desc->affinity, old_desc->affinity);
#ifdef CONFIG_GENERIC_PENDING_IRQ
@@ -499,12 +497,16 @@ static inline void free_desc_masks(struct irq_desc *old_desc,
#else /* !CONFIG_SMP */
-static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
+static inline bool alloc_desc_masks(struct irq_desc *desc, int node,
bool boot)
{
return true;
}
+static inline void init_desc_masks(struct irq_desc *desc)
+{
+}
+
static inline void init_copy_desc_masks(struct irq_desc *old_desc,
struct irq_desc *new_desc)
{
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
index 6adcc297e354..3318b9416c66 100644
--- a/include/linux/kgdb.h
+++ b/include/linux/kgdb.h
@@ -29,8 +29,7 @@ struct pt_regs;
*
* On some architectures it is required to skip a breakpoint
* exception when it occurs after a breakpoint has been removed.
- * This can be implemented in the architecture specific portion of
- * for kgdb.
+ * This can be implemented in the architecture specific portion of kgdb.
*/
extern int kgdb_skipexception(int exception, struct pt_regs *regs);
@@ -42,7 +41,7 @@ extern int kgdb_skipexception(int exception, struct pt_regs *regs);
*
* This is usually needed on architectures which support SMP and
* KGDB. This function is called after all the secondary cpus have
- * been put to a know spin state and the primary CPU has control over
+ * been put to a known spin state and the primary CPU has control over
* KGDB.
*/
extern void kgdb_post_primary_code(struct pt_regs *regs, int e_vector,
@@ -65,7 +64,7 @@ struct uart_port;
/**
* kgdb_breakpoint - compiled in breakpoint
*
- * This will be impelmented a static inline per architecture. This
+ * This will be implemented as a static inline per architecture. This
* function is called by the kgdb core to execute an architecture
* specific trap to cause kgdb to enter the exception processing.
*
@@ -190,7 +189,7 @@ kgdb_arch_handle_exception(int vector, int signo, int err_code,
* @flags: Current IRQ state
*
* On SMP systems, we need to get the attention of the other CPUs
- * and get them be in a known state. This should do what is needed
+ * and get them into a known state. This should do what is needed
* to get the other CPUs to call kgdb_wait(). Note that on some arches,
* the NMI approach is not used for rounding up all the CPUs. For example,
* in case of MIPS, smp_call_function() is used to roundup CPUs. In
@@ -267,8 +266,45 @@ extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops);
extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops);
extern int kgdb_hex2long(char **ptr, unsigned long *long_val);
-extern int kgdb_mem2hex(char *mem, char *buf, int count);
-extern int kgdb_hex2mem(char *buf, char *mem, int count);
+
+/**
+ * kgdb_mem2hex - (optional arch override) translate bin to hex chars
+ * @mem: source buffer
+ * @buf: target buffer
+ * @count: number of bytes in mem
+ *
+ * Architectures which do not support probe_kernel_(read|write),
+ * can make an alternate implementation of this function.
+ * This function safely reads memory into hex
+ * characters for use with the kgdb protocol.
+ */
+extern int __weak kgdb_mem2hex(char *mem, char *buf, int count);
+
+/**
+ * kgdb_hex2mem - (optional arch override) translate hex chars to bin
+ * @buf: source buffer
+ * @mem: target buffer
+ * @count: number of bytes in mem
+ *
+ * Architectures which do not support probe_kernel_(read|write),
+ * can make an alternate implementation of this function.
+ * This function safely writes hex characters into memory
+ * for use with the kgdb protocol.
+ */
+extern int __weak kgdb_hex2mem(char *buf, char *mem, int count);
+
+/**
+ * kgdb_ebin2mem - (optional arch override) Copy binary array from @buf into @mem
+ * @buf: source buffer
+ * @mem: target buffer
+ * @count: number of bytes in mem
+ *
+ * Architectures which do not support probe_kernel_(read|write),
+ * can make an alternate implementation of this function.
+ * This function safely copies binary array into memory
+ * for use with the kgdb protocol.
+ */
+extern int __weak kgdb_ebin2mem(char *buf, char *mem, int count);
extern int kgdb_isremovedbreak(unsigned long addr);
diff --git a/include/linux/kmemtrace.h b/include/linux/kmemtrace.h
new file mode 100644
index 000000000000..b616d3930c3b
--- /dev/null
+++ b/include/linux/kmemtrace.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2008 Eduard - Gabriel Munteanu
+ *
+ * This file is released under GPL version 2.
+ */
+
+#ifndef _LINUX_KMEMTRACE_H
+#define _LINUX_KMEMTRACE_H
+
+#ifdef __KERNEL__
+
+#include <trace/events/kmem.h>
+
+#ifdef CONFIG_KMEMTRACE
+extern void kmemtrace_init(void);
+#else
+static inline void kmemtrace_init(void)
+{
+}
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_KMEMTRACE_H */
+
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 8cc137911b34..3db5d8d37485 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -119,7 +119,7 @@ struct kvm_run {
__u32 error_code;
} ex;
/* KVM_EXIT_IO */
- struct kvm_io {
+ struct {
#define KVM_EXIT_IO_IN 0
#define KVM_EXIT_IO_OUT 1
__u8 direction;
@@ -224,10 +224,10 @@ struct kvm_interrupt {
/* for KVM_GET_DIRTY_LOG */
struct kvm_dirty_log {
__u32 slot;
- __u32 padding;
+ __u32 padding1;
union {
void __user *dirty_bitmap; /* one bit per page */
- __u64 padding;
+ __u64 padding2;
};
};
@@ -409,6 +409,10 @@ struct kvm_trace_rec {
#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
#define KVM_CAP_DEVICE_DEASSIGNMENT 27
#endif
+#ifdef __KVM_HAVE_MSIX
+#define KVM_CAP_DEVICE_MSIX 28
+#endif
+#define KVM_CAP_ASSIGN_DEV_IRQ 29
/* Another bug in KVM_SET_USER_MEMORY_REGION fixed: */
#define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30
@@ -482,11 +486,18 @@ struct kvm_irq_routing {
#define KVM_ASSIGN_PCI_DEVICE _IOR(KVMIO, 0x69, \
struct kvm_assigned_pci_dev)
#define KVM_SET_GSI_ROUTING _IOW(KVMIO, 0x6a, struct kvm_irq_routing)
+/* deprecated, replaced by KVM_ASSIGN_DEV_IRQ */
#define KVM_ASSIGN_IRQ _IOR(KVMIO, 0x70, \
struct kvm_assigned_irq)
+#define KVM_ASSIGN_DEV_IRQ _IOW(KVMIO, 0x70, struct kvm_assigned_irq)
#define KVM_REINJECT_CONTROL _IO(KVMIO, 0x71)
#define KVM_DEASSIGN_PCI_DEVICE _IOW(KVMIO, 0x72, \
struct kvm_assigned_pci_dev)
+#define KVM_ASSIGN_SET_MSIX_NR \
+ _IOW(KVMIO, 0x73, struct kvm_assigned_msix_nr)
+#define KVM_ASSIGN_SET_MSIX_ENTRY \
+ _IOW(KVMIO, 0x74, struct kvm_assigned_msix_entry)
+#define KVM_DEASSIGN_DEV_IRQ _IOW(KVMIO, 0x75, struct kvm_assigned_irq)
/*
* ioctls for vcpu fds
@@ -577,6 +588,8 @@ struct kvm_debug_guest {
#define KVM_TRC_STLB_INVAL (KVM_TRC_HANDLER + 0x18)
#define KVM_TRC_PPC_INSTR (KVM_TRC_HANDLER + 0x19)
+#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
+
struct kvm_assigned_pci_dev {
__u32 assigned_dev_id;
__u32 busnr;
@@ -587,6 +600,17 @@ struct kvm_assigned_pci_dev {
};
};
+#define KVM_DEV_IRQ_HOST_INTX (1 << 0)
+#define KVM_DEV_IRQ_HOST_MSI (1 << 1)
+#define KVM_DEV_IRQ_HOST_MSIX (1 << 2)
+
+#define KVM_DEV_IRQ_GUEST_INTX (1 << 8)
+#define KVM_DEV_IRQ_GUEST_MSI (1 << 9)
+#define KVM_DEV_IRQ_GUEST_MSIX (1 << 10)
+
+#define KVM_DEV_IRQ_HOST_MASK 0x00ff
+#define KVM_DEV_IRQ_GUEST_MASK 0xff00
+
struct kvm_assigned_irq {
__u32 assigned_dev_id;
__u32 host_irq;
@@ -602,9 +626,19 @@ struct kvm_assigned_irq {
};
};
-#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
-#define KVM_DEV_IRQ_ASSIGN_MSI_ACTION KVM_DEV_IRQ_ASSIGN_ENABLE_MSI
-#define KVM_DEV_IRQ_ASSIGN_ENABLE_MSI (1 << 0)
+struct kvm_assigned_msix_nr {
+ __u32 assigned_dev_id;
+ __u16 entry_nr;
+ __u16 padding;
+};
+
+#define KVM_MAX_MSIX_PER_DEV 512
+struct kvm_assigned_msix_entry {
+ __u32 assigned_dev_id;
+ __u32 gsi;
+ __u16 entry; /* The index of entry in the MSI-X table */
+ __u16 padding[3];
+};
#endif
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 894a56e365e8..2b8df0cadac7 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -38,6 +38,7 @@
#define KVM_REQ_UNHALT 6
#define KVM_REQ_MMU_SYNC 7
#define KVM_REQ_KVMCLOCK_UPDATE 8
+#define KVM_REQ_KICK 9
#define KVM_USERSPACE_IRQ_SOURCE_ID 0
@@ -72,7 +73,6 @@ struct kvm_vcpu {
struct mutex mutex;
int cpu;
struct kvm_run *run;
- int guest_mode;
unsigned long requests;
unsigned long guest_debug;
int fpu_active;
@@ -298,6 +298,7 @@ int kvm_arch_hardware_setup(void);
void kvm_arch_hardware_unsetup(void);
void kvm_arch_check_processor_compat(void *rtn);
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
void kvm_free_physmem(struct kvm *kvm);
@@ -319,6 +320,13 @@ struct kvm_irq_ack_notifier {
void (*irq_acked)(struct kvm_irq_ack_notifier *kian);
};
+#define KVM_ASSIGNED_MSIX_PENDING 0x1
+struct kvm_guest_msix_entry {
+ u32 vector;
+ u16 entry;
+ u16 flags;
+};
+
struct kvm_assigned_dev_kernel {
struct kvm_irq_ack_notifier ack_notifier;
struct work_struct interrupt_work;
@@ -326,18 +334,18 @@ struct kvm_assigned_dev_kernel {
int assigned_dev_id;
int host_busnr;
int host_devfn;
+ unsigned int entries_nr;
int host_irq;
bool host_irq_disabled;
+ struct msix_entry *host_msix_entries;
int guest_irq;
-#define KVM_ASSIGNED_DEV_GUEST_INTX (1 << 0)
-#define KVM_ASSIGNED_DEV_GUEST_MSI (1 << 1)
-#define KVM_ASSIGNED_DEV_HOST_INTX (1 << 8)
-#define KVM_ASSIGNED_DEV_HOST_MSI (1 << 9)
+ struct kvm_guest_msix_entry *guest_msix_entries;
unsigned long irq_requested_type;
int irq_source_id;
int flags;
struct pci_dev *dev;
struct kvm *kvm;
+ spinlock_t assigned_dev_lock;
};
struct kvm_irq_mask_notifier {
@@ -352,6 +360,11 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
struct kvm_irq_mask_notifier *kimn);
void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask);
+#ifdef __KVM_HAVE_IOAPIC
+void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic,
+ union kvm_ioapic_redirect_entry *entry,
+ unsigned long *deliver_bitmask);
+#endif
int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level);
void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin);
void kvm_register_irq_ack_notifier(struct kvm *kvm,
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index 2b8318c83e53..fb46efbeabec 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -40,4 +40,31 @@ typedef unsigned long hfn_t;
typedef hfn_t pfn_t;
+union kvm_ioapic_redirect_entry {
+ u64 bits;
+ struct {
+ u8 vector;
+ u8 delivery_mode:3;
+ u8 dest_mode:1;
+ u8 delivery_status:1;
+ u8 polarity:1;
+ u8 remote_irr:1;
+ u8 trig_mode:1;
+ u8 mask:1;
+ u8 reserve:7;
+ u8 reserved[4];
+ u8 dest_id;
+ } fields;
+};
+
+struct kvm_lapic_irq {
+ u32 vector;
+ u32 delivery_mode;
+ u32 dest_mode;
+ u32 level;
+ u32 trig_mode;
+ u32 shorthand;
+ u32 dest_id;
+};
+
#endif /* __KVM_TYPES_H__ */
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 40725447f5e0..66c194e2d9b9 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -56,8 +56,7 @@ struct loop_device {
gfp_t old_gfp_mask;
spinlock_t lo_lock;
- struct bio *lo_bio;
- struct bio *lo_biotail;
+ struct bio_list lo_bio_list;
int lo_state;
struct mutex lo_ctl_mutex;
struct task_struct *lo_thread;
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
new file mode 100644
index 000000000000..e461b2c3d711
--- /dev/null
+++ b/include/linux/lsm_audit.h
@@ -0,0 +1,111 @@
+/*
+ * Common LSM logging functions
+ * Heavily borrowed from selinux/avc.h
+ *
+ * Author : Etienne BASSET <etienne.basset@ensta.org>
+ *
+ * All credits to : Stephen Smalley, <sds@epoch.ncsc.mil>
+ * All BUGS to : Etienne BASSET <etienne.basset@ensta.org>
+ */
+#ifndef _LSM_COMMON_LOGGING_
+#define _LSM_COMMON_LOGGING_
+
+#include <linux/stddef.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/audit.h>
+#include <linux/in6.h>
+#include <linux/path.h>
+#include <linux/key.h>
+#include <linux/skbuff.h>
+#include <asm/system.h>
+
+
+/* Auxiliary data to use in generating the audit record. */
+struct common_audit_data {
+ char type;
+#define LSM_AUDIT_DATA_FS 1
+#define LSM_AUDIT_DATA_NET 2
+#define LSM_AUDIT_DATA_CAP 3
+#define LSM_AUDIT_DATA_IPC 4
+#define LSM_AUDIT_DATA_TASK 5
+#define LSM_AUDIT_DATA_KEY 6
+ struct task_struct *tsk;
+ union {
+ struct {
+ struct path path;
+ struct inode *inode;
+ } fs;
+ struct {
+ int netif;
+ struct sock *sk;
+ u16 family;
+ __be16 dport;
+ __be16 sport;
+ union {
+ struct {
+ __be32 daddr;
+ __be32 saddr;
+ } v4;
+ struct {
+ struct in6_addr daddr;
+ struct in6_addr saddr;
+ } v6;
+ } fam;
+ } net;
+ int cap;
+ int ipc_id;
+ struct task_struct *tsk;
+#ifdef CONFIG_KEYS
+ struct {
+ key_serial_t key;
+ char *key_desc;
+ } key_struct;
+#endif
+ } u;
+ const char *function;
+ /* this union contains LSM specific data */
+ union {
+ /* SMACK data */
+ struct smack_audit_data {
+ char *subject;
+ char *object;
+ char *request;
+ int result;
+ } smack_audit_data;
+ /* SELinux data */
+ struct {
+ u32 ssid;
+ u32 tsid;
+ u16 tclass;
+ u32 requested;
+ u32 audited;
+ struct av_decision *avd;
+ int result;
+ } selinux_audit_data;
+ } lsm_priv;
+ /* these callback will be implemented by a specific LSM */
+ void (*lsm_pre_audit)(struct audit_buffer *, void *);
+ void (*lsm_post_audit)(struct audit_buffer *, void *);
+};
+
+#define v4info fam.v4
+#define v6info fam.v6
+
+int ipv4_skb_to_auditdata(struct sk_buff *skb,
+ struct common_audit_data *ad, u8 *proto);
+
+int ipv6_skb_to_auditdata(struct sk_buff *skb,
+ struct common_audit_data *ad, u8 *proto);
+
+/* Initialize an LSM audit data structure. */
+#define COMMON_AUDIT_DATA_INIT(_d, _t) \
+ { memset((_d), 0, sizeof(struct common_audit_data)); \
+ (_d)->type = LSM_AUDIT_DATA_##_t; (_d)->function = __func__; }
+
+void common_lsm_audit(struct common_audit_data *a);
+
+#endif
diff --git a/include/linux/magic.h b/include/linux/magic.h
index 5b4e28bcb788..4596c9e25e09 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -3,10 +3,11 @@
#define ADFS_SUPER_MAGIC 0xadf5
#define AFFS_SUPER_MAGIC 0xadff
-#define AFS_SUPER_MAGIC 0x5346414F
+#define AFS_SUPER_MAGIC 0x5346414F
#define AUTOFS_SUPER_MAGIC 0x0187
#define CODA_SUPER_MAGIC 0x73757245
-#define DEBUGFS_MAGIC 0x64626720
+#define CUSE_SUPER_MAGIC 0x43555345
+#define DEBUGFS_MAGIC 0x64626720
#define SYSFS_MAGIC 0x62656572
#define SECURITYFS_MAGIC 0x73636673
#define TMPFS_MAGIC 0x01021994
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
new file mode 100644
index 000000000000..26b4eb3bbee9
--- /dev/null
+++ b/include/linux/mdio.h
@@ -0,0 +1,312 @@
+/*
+ * linux/mdio.h: definitions for MDIO (clause 45) transceivers
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#ifndef __LINUX_MDIO_H__
+#define __LINUX_MDIO_H__
+
+#include <linux/mii.h>
+
+/* MDIO Manageable Devices (MMDs). */
+#define MDIO_MMD_PMAPMD 1 /* Physical Medium Attachment/
+ * Physical Medium Dependent */
+#define MDIO_MMD_WIS 2 /* WAN Interface Sublayer */
+#define MDIO_MMD_PCS 3 /* Physical Coding Sublayer */
+#define MDIO_MMD_PHYXS 4 /* PHY Extender Sublayer */
+#define MDIO_MMD_DTEXS 5 /* DTE Extender Sublayer */
+#define MDIO_MMD_TC 6 /* Transmission Convergence */
+#define MDIO_MMD_AN 7 /* Auto-Negotiation */
+#define MDIO_MMD_C22EXT 29 /* Clause 22 extension */
+#define MDIO_MMD_VEND1 30 /* Vendor specific 1 */
+#define MDIO_MMD_VEND2 31 /* Vendor specific 2 */
+
+/* Generic MDIO registers. */
+#define MDIO_CTRL1 MII_BMCR
+#define MDIO_STAT1 MII_BMSR
+#define MDIO_DEVID1 MII_PHYSID1
+#define MDIO_DEVID2 MII_PHYSID2
+#define MDIO_SPEED 4 /* Speed ability */
+#define MDIO_DEVS1 5 /* Devices in package */
+#define MDIO_DEVS2 6
+#define MDIO_CTRL2 7 /* 10G control 2 */
+#define MDIO_STAT2 8 /* 10G status 2 */
+#define MDIO_PMA_TXDIS 9 /* 10G PMA/PMD transmit disable */
+#define MDIO_PMA_RXDET 10 /* 10G PMA/PMD receive signal detect */
+#define MDIO_PMA_EXTABLE 11 /* 10G PMA/PMD extended ability */
+#define MDIO_PKGID1 14 /* Package identifier */
+#define MDIO_PKGID2 15
+#define MDIO_AN_ADVERTISE 16 /* AN advertising (base page) */
+#define MDIO_AN_LPA 19 /* AN LP abilities (base page) */
+#define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */
+
+/* Media-dependent registers. */
+#define MDIO_PMA_10GBT_TXPWR 131 /* 10GBASE-T TX power control */
+#define MDIO_PMA_10GBR_FECABLE 170 /* 10GBASE-R FEC ability */
+#define MDIO_PCS_10GBX_STAT1 24 /* 10GBASE-X PCS status 1 */
+#define MDIO_PCS_10GBRT_STAT1 32 /* 10GBASE-R/-T PCS status 1 */
+#define MDIO_PCS_10GBRT_STAT2 33 /* 10GBASE-R/-T PCS status 2 */
+#define MDIO_AN_10GBT_CTRL 32 /* 10GBASE-T auto-negotiation control */
+#define MDIO_AN_10GBT_STAT 33 /* 10GBASE-T auto-negotiation status */
+
+/* Control register 1. */
+/* Enable extended speed selection */
+#define MDIO_CTRL1_SPEEDSELEXT (BMCR_SPEED1000 | BMCR_SPEED100)
+/* All speed selection bits */
+#define MDIO_CTRL1_SPEEDSEL (MDIO_CTRL1_SPEEDSELEXT | 0x003c)
+#define MDIO_CTRL1_FULLDPLX BMCR_FULLDPLX
+#define MDIO_CTRL1_LPOWER BMCR_PDOWN
+#define MDIO_CTRL1_RESET BMCR_RESET
+#define MDIO_PMA_CTRL1_LOOPBACK 0x0001
+#define MDIO_PMA_CTRL1_SPEED1000 BMCR_SPEED1000
+#define MDIO_PMA_CTRL1_SPEED100 BMCR_SPEED100
+#define MDIO_PCS_CTRL1_LOOPBACK BMCR_LOOPBACK
+#define MDIO_PHYXS_CTRL1_LOOPBACK BMCR_LOOPBACK
+#define MDIO_AN_CTRL1_RESTART BMCR_ANRESTART
+#define MDIO_AN_CTRL1_ENABLE BMCR_ANENABLE
+#define MDIO_AN_CTRL1_XNP 0x2000 /* Enable extended next page */
+
+/* 10 Gb/s */
+#define MDIO_CTRL1_SPEED10G (MDIO_CTRL1_SPEEDSELEXT | 0x00)
+/* 10PASS-TS/2BASE-TL */
+#define MDIO_CTRL1_SPEED10P2B (MDIO_CTRL1_SPEEDSELEXT | 0x04)
+
+/* Status register 1. */
+#define MDIO_STAT1_LPOWERABLE 0x0002 /* Low-power ability */
+#define MDIO_STAT1_LSTATUS BMSR_LSTATUS
+#define MDIO_STAT1_FAULT 0x0080 /* Fault */
+#define MDIO_AN_STAT1_LPABLE 0x0001 /* Link partner AN ability */
+#define MDIO_AN_STAT1_ABLE BMSR_ANEGCAPABLE
+#define MDIO_AN_STAT1_RFAULT BMSR_RFAULT
+#define MDIO_AN_STAT1_COMPLETE BMSR_ANEGCOMPLETE
+#define MDIO_AN_STAT1_PAGE 0x0040 /* Page received */
+#define MDIO_AN_STAT1_XNP 0x0080 /* Extended next page status */
+
+/* Speed register. */
+#define MDIO_SPEED_10G 0x0001 /* 10G capable */
+#define MDIO_PMA_SPEED_2B 0x0002 /* 2BASE-TL capable */
+#define MDIO_PMA_SPEED_10P 0x0004 /* 10PASS-TS capable */
+#define MDIO_PMA_SPEED_1000 0x0010 /* 1000M capable */
+#define MDIO_PMA_SPEED_100 0x0020 /* 100M capable */
+#define MDIO_PMA_SPEED_10 0x0040 /* 10M capable */
+#define MDIO_PCS_SPEED_10P2B 0x0002 /* 10PASS-TS/2BASE-TL capable */
+
+/* Device present registers. */
+#define MDIO_DEVS_PRESENT(devad) (1 << (devad))
+#define MDIO_DEVS_PMAPMD MDIO_DEVS_PRESENT(MDIO_MMD_PMAPMD)
+#define MDIO_DEVS_WIS MDIO_DEVS_PRESENT(MDIO_MMD_WIS)
+#define MDIO_DEVS_PCS MDIO_DEVS_PRESENT(MDIO_MMD_PCS)
+#define MDIO_DEVS_PHYXS MDIO_DEVS_PRESENT(MDIO_MMD_PHYXS)
+#define MDIO_DEVS_DTEXS MDIO_DEVS_PRESENT(MDIO_MMD_DTEXS)
+#define MDIO_DEVS_TC MDIO_DEVS_PRESENT(MDIO_MMD_TC)
+#define MDIO_DEVS_AN MDIO_DEVS_PRESENT(MDIO_MMD_AN)
+#define MDIO_DEVS_C22EXT MDIO_DEVS_PRESENT(MDIO_MMD_C22EXT)
+
+/* Control register 2. */
+#define MDIO_PMA_CTRL2_TYPE 0x000f /* PMA/PMD type selection */
+#define MDIO_PMA_CTRL2_10GBCX4 0x0000 /* 10GBASE-CX4 type */
+#define MDIO_PMA_CTRL2_10GBEW 0x0001 /* 10GBASE-EW type */
+#define MDIO_PMA_CTRL2_10GBLW 0x0002 /* 10GBASE-LW type */
+#define MDIO_PMA_CTRL2_10GBSW 0x0003 /* 10GBASE-SW type */
+#define MDIO_PMA_CTRL2_10GBLX4 0x0004 /* 10GBASE-LX4 type */
+#define MDIO_PMA_CTRL2_10GBER 0x0005 /* 10GBASE-ER type */
+#define MDIO_PMA_CTRL2_10GBLR 0x0006 /* 10GBASE-LR type */
+#define MDIO_PMA_CTRL2_10GBSR 0x0007 /* 10GBASE-SR type */
+#define MDIO_PMA_CTRL2_10GBLRM 0x0008 /* 10GBASE-LRM type */
+#define MDIO_PMA_CTRL2_10GBT 0x0009 /* 10GBASE-T type */
+#define MDIO_PMA_CTRL2_10GBKX4 0x000a /* 10GBASE-KX4 type */
+#define MDIO_PMA_CTRL2_10GBKR 0x000b /* 10GBASE-KR type */
+#define MDIO_PMA_CTRL2_1000BT 0x000c /* 1000BASE-T type */
+#define MDIO_PMA_CTRL2_1000BKX 0x000d /* 1000BASE-KX type */
+#define MDIO_PMA_CTRL2_100BTX 0x000e /* 100BASE-TX type */
+#define MDIO_PMA_CTRL2_10BT 0x000f /* 10BASE-T type */
+#define MDIO_PCS_CTRL2_TYPE 0x0003 /* PCS type selection */
+#define MDIO_PCS_CTRL2_10GBR 0x0000 /* 10GBASE-R type */
+#define MDIO_PCS_CTRL2_10GBX 0x0001 /* 10GBASE-X type */
+#define MDIO_PCS_CTRL2_10GBW 0x0002 /* 10GBASE-W type */
+#define MDIO_PCS_CTRL2_10GBT 0x0003 /* 10GBASE-T type */
+
+/* Status register 2. */
+#define MDIO_STAT2_RXFAULT 0x0400 /* Receive fault */
+#define MDIO_STAT2_TXFAULT 0x0800 /* Transmit fault */
+#define MDIO_STAT2_DEVPRST 0xc000 /* Device present */
+#define MDIO_STAT2_DEVPRST_VAL 0x8000 /* Device present value */
+#define MDIO_PMA_STAT2_LBABLE 0x0001 /* PMA loopback ability */
+#define MDIO_PMA_STAT2_10GBEW 0x0002 /* 10GBASE-EW ability */
+#define MDIO_PMA_STAT2_10GBLW 0x0004 /* 10GBASE-LW ability */
+#define MDIO_PMA_STAT2_10GBSW 0x0008 /* 10GBASE-SW ability */
+#define MDIO_PMA_STAT2_10GBLX4 0x0010 /* 10GBASE-LX4 ability */
+#define MDIO_PMA_STAT2_10GBER 0x0020 /* 10GBASE-ER ability */
+#define MDIO_PMA_STAT2_10GBLR 0x0040 /* 10GBASE-LR ability */
+#define MDIO_PMA_STAT2_10GBSR 0x0080 /* 10GBASE-SR ability */
+#define MDIO_PMD_STAT2_TXDISAB 0x0100 /* PMD TX disable ability */
+#define MDIO_PMA_STAT2_EXTABLE 0x0200 /* Extended abilities */
+#define MDIO_PMA_STAT2_RXFLTABLE 0x1000 /* Receive fault ability */
+#define MDIO_PMA_STAT2_TXFLTABLE 0x2000 /* Transmit fault ability */
+#define MDIO_PCS_STAT2_10GBR 0x0001 /* 10GBASE-R capable */
+#define MDIO_PCS_STAT2_10GBX 0x0002 /* 10GBASE-X capable */
+#define MDIO_PCS_STAT2_10GBW 0x0004 /* 10GBASE-W capable */
+#define MDIO_PCS_STAT2_RXFLTABLE 0x1000 /* Receive fault ability */
+#define MDIO_PCS_STAT2_TXFLTABLE 0x2000 /* Transmit fault ability */
+
+/* Transmit disable register. */
+#define MDIO_PMD_TXDIS_GLOBAL 0x0001 /* Global PMD TX disable */
+#define MDIO_PMD_TXDIS_0 0x0002 /* PMD TX disable 0 */
+#define MDIO_PMD_TXDIS_1 0x0004 /* PMD TX disable 1 */
+#define MDIO_PMD_TXDIS_2 0x0008 /* PMD TX disable 2 */
+#define MDIO_PMD_TXDIS_3 0x0010 /* PMD TX disable 3 */
+
+/* Receive signal detect register. */
+#define MDIO_PMD_RXDET_GLOBAL 0x0001 /* Global PMD RX signal detect */
+#define MDIO_PMD_RXDET_0 0x0002 /* PMD RX signal detect 0 */
+#define MDIO_PMD_RXDET_1 0x0004 /* PMD RX signal detect 1 */
+#define MDIO_PMD_RXDET_2 0x0008 /* PMD RX signal detect 2 */
+#define MDIO_PMD_RXDET_3 0x0010 /* PMD RX signal detect 3 */
+
+/* Extended abilities register. */
+#define MDIO_PMA_EXTABLE_10GCX4 0x0001 /* 10GBASE-CX4 ability */
+#define MDIO_PMA_EXTABLE_10GBLRM 0x0002 /* 10GBASE-LRM ability */
+#define MDIO_PMA_EXTABLE_10GBT 0x0004 /* 10GBASE-T ability */
+#define MDIO_PMA_EXTABLE_10GBKX4 0x0008 /* 10GBASE-KX4 ability */
+#define MDIO_PMA_EXTABLE_10GBKR 0x0010 /* 10GBASE-KR ability */
+#define MDIO_PMA_EXTABLE_1000BT 0x0020 /* 1000BASE-T ability */
+#define MDIO_PMA_EXTABLE_1000BKX 0x0040 /* 1000BASE-KX ability */
+#define MDIO_PMA_EXTABLE_100BTX 0x0080 /* 100BASE-TX ability */
+#define MDIO_PMA_EXTABLE_10BT 0x0100 /* 10BASE-T ability */
+
+/* PHY XGXS lane state register. */
+#define MDIO_PHYXS_LNSTAT_SYNC0 0x0001
+#define MDIO_PHYXS_LNSTAT_SYNC1 0x0002
+#define MDIO_PHYXS_LNSTAT_SYNC2 0x0004
+#define MDIO_PHYXS_LNSTAT_SYNC3 0x0008
+#define MDIO_PHYXS_LNSTAT_ALIGN 0x1000
+
+/* PMA 10GBASE-T TX power register. */
+#define MDIO_PMA_10GBT_TXPWR_SHORT 0x0001 /* Short-reach mode */
+
+/* PMA 10GBASE-R FEC ability register. */
+#define MDIO_PMA_10GBR_FECABLE_ABLE 0x0001 /* FEC ability */
+#define MDIO_PMA_10GBR_FECABLE_ERRABLE 0x0002 /* FEC error indic. ability */
+
+/* PCS 10GBASE-R/-T status register 1. */
+#define MDIO_PCS_10GBRT_STAT1_BLKLK 0x0001 /* Block lock attained */
+
+/* PCS 10GBASE-R/-T status register 2. */
+#define MDIO_PCS_10GBRT_STAT2_ERR 0x00ff
+#define MDIO_PCS_10GBRT_STAT2_BER 0x3f00
+
+/* AN 10GBASE-T control register. */
+#define MDIO_AN_10GBT_CTRL_ADV10G 0x1000 /* Advertise 10GBASE-T */
+
+/* AN 10GBASE-T status register. */
+#define MDIO_AN_10GBT_STAT_LPTRR 0x0200 /* LP training reset req. */
+#define MDIO_AN_10GBT_STAT_LPLTABLE 0x0400 /* LP loop timing ability */
+#define MDIO_AN_10GBT_STAT_LP10G 0x0800 /* LP is 10GBT capable */
+#define MDIO_AN_10GBT_STAT_REMOK 0x1000 /* Remote OK */
+#define MDIO_AN_10GBT_STAT_LOCOK 0x2000 /* Local OK */
+#define MDIO_AN_10GBT_STAT_MS 0x4000 /* Master/slave config */
+#define MDIO_AN_10GBT_STAT_MSFLT 0x8000 /* Master/slave config fault */
+
+/* Mapping between MDIO PRTAD/DEVAD and mii_ioctl_data::phy_id */
+
+#define MDIO_PHY_ID_C45 0x8000
+#define MDIO_PHY_ID_PRTAD 0x03e0
+#define MDIO_PHY_ID_DEVAD 0x001f
+#define MDIO_PHY_ID_C45_MASK \
+ (MDIO_PHY_ID_C45 | MDIO_PHY_ID_PRTAD | MDIO_PHY_ID_DEVAD)
+
+static inline __u16 mdio_phy_id_c45(int prtad, int devad)
+{
+ return MDIO_PHY_ID_C45 | (prtad << 5) | devad;
+}
+
+static inline bool mdio_phy_id_is_c45(int phy_id)
+{
+ return (phy_id & MDIO_PHY_ID_C45) && !(phy_id & ~MDIO_PHY_ID_C45_MASK);
+}
+
+static inline __u16 mdio_phy_id_prtad(int phy_id)
+{
+ return (phy_id & MDIO_PHY_ID_PRTAD) >> 5;
+}
+
+static inline __u16 mdio_phy_id_devad(int phy_id)
+{
+ return phy_id & MDIO_PHY_ID_DEVAD;
+}
+
+#define MDIO_SUPPORTS_C22 1
+#define MDIO_SUPPORTS_C45 2
+
+#ifdef __KERNEL__
+
+/**
+ * struct mdio_if_info - Ethernet controller MDIO interface
+ * @prtad: PRTAD of the PHY (%MDIO_PRTAD_NONE if not present/unknown)
+ * @mmds: Mask of MMDs expected to be present in the PHY. This must be
+ * non-zero unless @prtad = %MDIO_PRTAD_NONE.
+ * @mode_support: MDIO modes supported. If %MDIO_SUPPORTS_C22 is set then
+ * MII register access will be passed through with @devad =
+ * %MDIO_DEVAD_NONE. If %MDIO_EMULATE_C22 is set then access to
+ * commonly used clause 22 registers will be translated into
+ * clause 45 registers.
+ * @dev: Net device structure
+ * @mdio_read: Register read function; returns value or negative error code
+ * @mdio_write: Register write function; returns 0 or negative error code
+ */
+struct mdio_if_info {
+ int prtad;
+ u32 __bitwise mmds;
+ unsigned mode_support;
+
+ struct net_device *dev;
+ int (*mdio_read)(struct net_device *dev, int prtad, int devad,
+ u16 addr);
+ int (*mdio_write)(struct net_device *dev, int prtad, int devad,
+ u16 addr, u16 val);
+};
+
+#define MDIO_PRTAD_NONE (-1)
+#define MDIO_DEVAD_NONE (-1)
+#define MDIO_EMULATE_C22 4
+
+struct ethtool_cmd;
+struct ethtool_pauseparam;
+extern int mdio45_probe(struct mdio_if_info *mdio, int prtad);
+extern int mdio_set_flag(const struct mdio_if_info *mdio,
+ int prtad, int devad, u16 addr, int mask,
+ bool sense);
+extern int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmds);
+extern int mdio45_nway_restart(const struct mdio_if_info *mdio);
+extern void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
+ struct ethtool_cmd *ecmd,
+ u32 npage_adv, u32 npage_lpa);
+extern void
+mdio45_ethtool_spauseparam_an(const struct mdio_if_info *mdio,
+ const struct ethtool_pauseparam *ecmd);
+
+/**
+ * mdio45_ethtool_gset - get settings for ETHTOOL_GSET
+ * @mdio: MDIO interface
+ * @ecmd: Ethtool request structure
+ *
+ * Since the CSRs for auto-negotiation using next pages are not fully
+ * standardised, this function does not attempt to decode them. Use
+ * mdio45_ethtool_gset_npage() to specify advertisement bits from next
+ * pages.
+ */
+static inline void mdio45_ethtool_gset(const struct mdio_if_info *mdio,
+ struct ethtool_cmd *ecmd)
+{
+ mdio45_ethtool_gset_npage(mdio, ecmd, 0, 0);
+}
+
+extern int mdio_mii_ioctl(const struct mdio_if_info *mdio,
+ struct mii_ioctl_data *mii_data, int cmd);
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_MDIO_H__ */
diff --git a/include/linux/mg_disk.h b/include/linux/mg_disk.h
deleted file mode 100644
index 1f76b1ebf627..000000000000
--- a/include/linux/mg_disk.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * include/linux/mg_disk.c
- *
- * Support for the mGine m[g]flash IO mode.
- * Based on legacy hd.c
- *
- * (c) 2008 mGine Co.,LTD
- * (c) 2008 unsik Kim <donari75@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 __MG_DISK_H__
-#define __MG_DISK_H__
-
-#include <linux/blkdev.h>
-#include <linux/ata.h>
-
-/* name for block device */
-#define MG_DISK_NAME "mgd"
-/* name for platform device */
-#define MG_DEV_NAME "mg_disk"
-
-#define MG_DISK_MAJ 0
-#define MG_DISK_MAX_PART 16
-#define MG_SECTOR_SIZE 512
-#define MG_MAX_SECTS 256
-
-/* Register offsets */
-#define MG_BUFF_OFFSET 0x8000
-#define MG_STORAGE_BUFFER_SIZE 0x200
-#define MG_REG_OFFSET 0xC000
-#define MG_REG_FEATURE (MG_REG_OFFSET + 2) /* write case */
-#define MG_REG_ERROR (MG_REG_OFFSET + 2) /* read case */
-#define MG_REG_SECT_CNT (MG_REG_OFFSET + 4)
-#define MG_REG_SECT_NUM (MG_REG_OFFSET + 6)
-#define MG_REG_CYL_LOW (MG_REG_OFFSET + 8)
-#define MG_REG_CYL_HIGH (MG_REG_OFFSET + 0xA)
-#define MG_REG_DRV_HEAD (MG_REG_OFFSET + 0xC)
-#define MG_REG_COMMAND (MG_REG_OFFSET + 0xE) /* write case */
-#define MG_REG_STATUS (MG_REG_OFFSET + 0xE) /* read case */
-#define MG_REG_DRV_CTRL (MG_REG_OFFSET + 0x10)
-#define MG_REG_BURST_CTRL (MG_REG_OFFSET + 0x12)
-
-/* "Drive Select/Head Register" bit values */
-#define MG_REG_HEAD_MUST_BE_ON 0xA0 /* These 2 bits are always on */
-#define MG_REG_HEAD_DRIVE_MASTER (0x00 | MG_REG_HEAD_MUST_BE_ON)
-#define MG_REG_HEAD_DRIVE_SLAVE (0x10 | MG_REG_HEAD_MUST_BE_ON)
-#define MG_REG_HEAD_LBA_MODE (0x40 | MG_REG_HEAD_MUST_BE_ON)
-
-
-/* "Device Control Register" bit values */
-#define MG_REG_CTRL_INTR_ENABLE 0x0
-#define MG_REG_CTRL_INTR_DISABLE (0x1<<1)
-#define MG_REG_CTRL_RESET (0x1<<2)
-#define MG_REG_CTRL_INTR_POLA_ACTIVE_HIGH 0x0
-#define MG_REG_CTRL_INTR_POLA_ACTIVE_LOW (0x1<<4)
-#define MG_REG_CTRL_DPD_POLA_ACTIVE_LOW 0x0
-#define MG_REG_CTRL_DPD_POLA_ACTIVE_HIGH (0x1<<5)
-#define MG_REG_CTRL_DPD_DISABLE 0x0
-#define MG_REG_CTRL_DPD_ENABLE (0x1<<6)
-
-/* Status register bit */
-/* error bit in status register */
-#define MG_REG_STATUS_BIT_ERROR 0x01
-/* corrected error in status register */
-#define MG_REG_STATUS_BIT_CORRECTED_ERROR 0x04
-/* data request bit in status register */
-#define MG_REG_STATUS_BIT_DATA_REQ 0x08
-/* DSC - Drive Seek Complete */
-#define MG_REG_STATUS_BIT_SEEK_DONE 0x10
-/* DWF - Drive Write Fault */
-#define MG_REG_STATUS_BIT_WRITE_FAULT 0x20
-#define MG_REG_STATUS_BIT_READY 0x40
-#define MG_REG_STATUS_BIT_BUSY 0x80
-
-/* handy status */
-#define MG_STAT_READY (MG_REG_STATUS_BIT_READY | MG_REG_STATUS_BIT_SEEK_DONE)
-#define MG_READY_OK(s) (((s) & (MG_STAT_READY | \
- (MG_REG_STATUS_BIT_BUSY | \
- MG_REG_STATUS_BIT_WRITE_FAULT | \
- MG_REG_STATUS_BIT_ERROR))) == MG_STAT_READY)
-
-/* Error register */
-#define MG_REG_ERR_AMNF 0x01
-#define MG_REG_ERR_ABRT 0x04
-#define MG_REG_ERR_IDNF 0x10
-#define MG_REG_ERR_UNC 0x40
-#define MG_REG_ERR_BBK 0x80
-
-/* error code for others */
-#define MG_ERR_NONE 0
-#define MG_ERR_TIMEOUT 0x100
-#define MG_ERR_INIT_STAT 0x101
-#define MG_ERR_TRANSLATION 0x102
-#define MG_ERR_CTRL_RST 0x103
-#define MG_ERR_INV_STAT 0x104
-#define MG_ERR_RSTOUT 0x105
-
-#define MG_MAX_ERRORS 6 /* Max read/write errors */
-
-/* command */
-#define MG_CMD_RD 0x20
-#define MG_CMD_WR 0x30
-#define MG_CMD_SLEEP 0x99
-#define MG_CMD_WAKEUP 0xC3
-#define MG_CMD_ID 0xEC
-#define MG_CMD_WR_CONF 0x3C
-#define MG_CMD_RD_CONF 0x40
-
-/* operation mode */
-#define MG_OP_CASCADE (1 << 0)
-#define MG_OP_CASCADE_SYNC_RD (1 << 1)
-#define MG_OP_CASCADE_SYNC_WR (1 << 2)
-#define MG_OP_INTERLEAVE (1 << 3)
-
-/* synchronous */
-#define MG_BURST_LAT_4 (3 << 4)
-#define MG_BURST_LAT_5 (4 << 4)
-#define MG_BURST_LAT_6 (5 << 4)
-#define MG_BURST_LAT_7 (6 << 4)
-#define MG_BURST_LAT_8 (7 << 4)
-#define MG_BURST_LEN_4 (1 << 1)
-#define MG_BURST_LEN_8 (2 << 1)
-#define MG_BURST_LEN_16 (3 << 1)
-#define MG_BURST_LEN_32 (4 << 1)
-#define MG_BURST_LEN_CONT (0 << 1)
-
-/* timeout value (unit: ms) */
-#define MG_TMAX_CONF_TO_CMD 1
-#define MG_TMAX_WAIT_RD_DRQ 10
-#define MG_TMAX_WAIT_WR_DRQ 500
-#define MG_TMAX_RST_TO_BUSY 10
-#define MG_TMAX_HDRST_TO_RDY 500
-#define MG_TMAX_SWRST_TO_RDY 500
-#define MG_TMAX_RSTOUT 3000
-
-/* device attribution */
-/* use mflash as boot device */
-#define MG_BOOT_DEV (1 << 0)
-/* use mflash as storage device */
-#define MG_STORAGE_DEV (1 << 1)
-/* same as MG_STORAGE_DEV, but bootloader already done reset sequence */
-#define MG_STORAGE_DEV_SKIP_RST (1 << 2)
-
-#define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST)
-
-/* names of GPIO resource */
-#define MG_RST_PIN "mg_rst"
-/* except MG_BOOT_DEV, reset-out pin should be assigned */
-#define MG_RSTOUT_PIN "mg_rstout"
-
-/* private driver data */
-struct mg_drv_data {
- /* disk resource */
- u32 use_polling;
-
- /* device attribution */
- u32 dev_attr;
-
- /* internally used */
- struct mg_host *host;
-};
-
-/* main structure for mflash driver */
-struct mg_host {
- struct device *dev;
-
- struct request_queue *breq;
- spinlock_t lock;
- struct gendisk *gd;
-
- struct timer_list timer;
- void (*mg_do_intr) (struct mg_host *);
-
- u16 id[ATA_ID_WORDS];
-
- u16 cyls;
- u16 heads;
- u16 sectors;
- u32 n_sectors;
- u32 nres_sectors;
-
- void __iomem *dev_base;
- unsigned int irq;
- unsigned int rst;
- unsigned int rstout;
-
- u32 major;
- u32 error;
-};
-
-/*
- * Debugging macro and defines
- */
-#undef DO_MG_DEBUG
-#ifdef DO_MG_DEBUG
-# define MG_DBG(fmt, args...) \
- printk(KERN_DEBUG "%s:%d "fmt, __func__, __LINE__, ##args)
-#else /* CONFIG_MG_DEBUG */
-# define MG_DBG(fmt, args...) do { } while (0)
-#endif /* CONFIG_MG_DEBUG */
-
-#endif
diff --git a/include/linux/mii.h b/include/linux/mii.h
index ad748588faf1..359fba880274 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -240,6 +240,22 @@ static inline unsigned int mii_duplex (unsigned int duplex_lock,
}
/**
+ * mii_advertise_flowctrl - get flow control advertisement flags
+ * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
+ */
+static inline u16 mii_advertise_flowctrl(int cap)
+{
+ u16 adv = 0;
+
+ if (cap & FLOW_CTRL_RX)
+ adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+ if (cap & FLOW_CTRL_TX)
+ adv ^= ADVERTISE_PAUSE_ASYM;
+
+ return adv;
+}
+
+/**
* mii_resolve_flowctrl_fdx
* @lcladv: value of MII ADVERTISE register
* @rmtadv: value of MII LPA register
@@ -250,18 +266,12 @@ static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
{
u8 cap = 0;
- if (lcladv & ADVERTISE_PAUSE_CAP) {
- if (lcladv & ADVERTISE_PAUSE_ASYM) {
- if (rmtadv & LPA_PAUSE_CAP)
- cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
- else if (rmtadv & LPA_PAUSE_ASYM)
- cap = FLOW_CTRL_RX;
- } else {
- if (rmtadv & LPA_PAUSE_CAP)
- cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
- }
- } else if (lcladv & ADVERTISE_PAUSE_ASYM) {
- if ((rmtadv & LPA_PAUSE_CAP) && (rmtadv & LPA_PAUSE_ASYM))
+ if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) {
+ cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
+ } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) {
+ if (lcladv & ADVERTISE_PAUSE_CAP)
+ cap = FLOW_CTRL_RX;
+ else if (rmtadv & ADVERTISE_PAUSE_CAP)
cap = FLOW_CTRL_TX;
}
diff --git a/include/linux/mm.h b/include/linux/mm.h
index bff1f0d475c7..009eabd3c21c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -19,6 +19,7 @@ struct anon_vma;
struct file_ra_state;
struct user_struct;
struct writeback_control;
+struct rlimit;
#ifndef CONFIG_DISCONTIGMEM /* Don't use mapnrs, do it properly */
extern unsigned long max_mapnr;
@@ -1319,8 +1320,8 @@ int vmemmap_populate_basepages(struct page *start_page,
int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
void vmemmap_populate_print_last(void);
-extern void *alloc_locked_buffer(size_t size);
-extern void free_locked_buffer(void *buffer, size_t size);
-extern void release_locked_buffer(void *buffer, size_t size);
+extern int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
+ size_t size);
+extern void refund_locked_memory(struct mm_struct *mm, size_t size);
#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index ea1bf5ba092f..b2c73cdabd05 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -24,6 +24,16 @@
*/
#define SDIO_VENDOR_ID_MARVELL 0x02df
+#define SDIO_VENDOR_ID_SIANO 0x039a
+
#define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103
+#define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104
+#define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105
+#define SDIO_DEVICE_ID_SIANO_STELLAR 0x5347
+#define SDIO_DEVICE_ID_SIANO_NOVA_A0 0x1100
+#define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201
+#define SDIO_DEVICE_ID_SIANO_NICE 0x0202
+#define SDIO_DEVICE_ID_SIANO_VEGA_A0 0x0300
+#define SDIO_DEVICE_ID_SIANO_VENICE 0x0301
#endif
diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h
index 3d1b7bde1283..97491f78b08c 100644
--- a/include/linux/mmiotrace.h
+++ b/include/linux/mmiotrace.h
@@ -30,6 +30,8 @@ extern unsigned int kmmio_count;
extern int register_kmmio_probe(struct kmmio_probe *p);
extern void unregister_kmmio_probe(struct kmmio_probe *p);
+extern int kmmio_init(void);
+extern void kmmio_cleanup(void);
#ifdef CONFIG_MMIOTRACE
/* kmmio is active by some kmmio_probes? */
diff --git a/include/linux/module.h b/include/linux/module.h
index 627ac082e2a6..a8f2c0aa4c32 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -337,6 +337,14 @@ struct module
const char **trace_bprintk_fmt_start;
unsigned int num_trace_bprintk_fmt;
#endif
+#ifdef CONFIG_EVENT_TRACING
+ struct ftrace_event_call *trace_events;
+ unsigned int num_trace_events;
+#endif
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+ unsigned long *ftrace_callsites;
+ unsigned int num_ftrace_callsites;
+#endif
#ifdef CONFIG_MODULE_UNLOAD
/* What modules depend on me? */
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index a4f0b931846c..6547c3cdbc4c 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -36,9 +36,14 @@ typedef int (*param_set_fn)(const char *val, struct kernel_param *kp);
/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp);
+/* Flag bits for kernel_param.flags */
+#define KPARAM_KMALLOCED 1
+#define KPARAM_ISBOOL 2
+
struct kernel_param {
const char *name;
- unsigned int perm;
+ u16 perm;
+ u16 flags;
param_set_fn set;
param_get_fn get;
union {
@@ -79,7 +84,7 @@ struct kparam_array
parameters. perm sets the visibility in sysfs: 000 means it's
not there, read bits mean it's readable, write bits mean it's
writable. */
-#define __module_param_call(prefix, name, set, get, arg, perm) \
+#define __module_param_call(prefix, name, set, get, arg, isbool, perm) \
/* Default value instead of permissions? */ \
static int __param_perm_check_##name __attribute__((unused)) = \
BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \
@@ -88,10 +93,13 @@ struct kparam_array
static struct kernel_param __moduleparam_const __param_##name \
__used \
__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
- = { __param_str_##name, perm, set, get, { arg } }
+ = { __param_str_##name, perm, isbool ? KPARAM_ISBOOL : 0, \
+ set, get, { arg } }
#define module_param_call(name, set, get, arg, perm) \
- __module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm)
+ __module_param_call(MODULE_PARAM_PREFIX, \
+ name, set, get, arg, \
+ __same_type(*(arg), bool), perm)
/* Helper functions: type is byte, short, ushort, int, uint, long,
ulong, charp, bool or invbool, or XXX if you define param_get_XXX,
@@ -120,15 +128,16 @@ struct kparam_array
#define core_param(name, var, type, perm) \
param_check_##type(name, &(var)); \
__module_param_call("", name, param_set_##type, param_get_##type, \
- &var, perm)
+ &var, __same_type(var, bool), perm)
#endif /* !MODULE */
/* Actually copy string: maxlen param is usually sizeof(string). */
#define module_param_string(name, string, len, perm) \
static const struct kparam_string __param_string_##name \
= { len, string }; \
- module_param_call(name, param_set_copystring, param_get_string, \
- .str = &__param_string_##name, perm); \
+ __module_param_call(MODULE_PARAM_PREFIX, name, \
+ param_set_copystring, param_get_string, \
+ .str = &__param_string_##name, 0, perm); \
__MODULE_PARM_TYPE(name, "string")
/* Called on module insert or kernel boot */
@@ -186,21 +195,30 @@ extern int param_set_charp(const char *val, struct kernel_param *kp);
extern int param_get_charp(char *buffer, struct kernel_param *kp);
#define param_check_charp(name, p) __param_check(name, p, char *)
+/* For historical reasons "bool" parameters can be (unsigned) "int". */
extern int param_set_bool(const char *val, struct kernel_param *kp);
extern int param_get_bool(char *buffer, struct kernel_param *kp);
-#define param_check_bool(name, p) __param_check(name, p, int)
+#define param_check_bool(name, p) \
+ static inline void __check_##name(void) \
+ { \
+ BUILD_BUG_ON(!__same_type(*(p), bool) && \
+ !__same_type(*(p), unsigned int) && \
+ !__same_type(*(p), int)); \
+ }
extern int param_set_invbool(const char *val, struct kernel_param *kp);
extern int param_get_invbool(char *buffer, struct kernel_param *kp);
-#define param_check_invbool(name, p) __param_check(name, p, int)
+#define param_check_invbool(name, p) __param_check(name, p, bool)
/* Comma-separated array: *nump is set to number they actually specified. */
#define module_param_array_named(name, array, type, nump, perm) \
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, \
- .arr = &__param_arr_##name, perm); \
+ __module_param_call(MODULE_PARAM_PREFIX, name, \
+ param_array_set, param_array_get, \
+ .arr = &__param_arr_##name, \
+ __same_type(array[0], bool), perm); \
__MODULE_PARM_TYPE(name, "array of " #type)
#define module_param_array(name, type, nump, perm) \
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 51f55f903aff..5d5275364867 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -30,7 +30,7 @@ struct mnt_namespace;
#define MNT_STRICTATIME 0x80
#define MNT_SHRINKABLE 0x100
-#define MNT_IMBALANCED_WRITE_COUNT 0x200 /* just for debugging */
+#define MNT_WRITE_HOLD 0x200
#define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */
#define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */
@@ -65,13 +65,22 @@ struct vfsmount {
int mnt_expiry_mark; /* true if marked for expiry */
int mnt_pinned;
int mnt_ghosts;
- /*
- * This value is not stable unless all of the mnt_writers[] spinlocks
- * are held, and all mnt_writer[]s on this mount have 0 as their ->count
- */
- atomic_t __mnt_writers;
+#ifdef CONFIG_SMP
+ int *mnt_writers;
+#else
+ int mnt_writers;
+#endif
};
+static inline int *get_mnt_writers_ptr(struct vfsmount *mnt)
+{
+#ifdef CONFIG_SMP
+ return mnt->mnt_writers;
+#else
+ return &mnt->mnt_writers;
+#endif
+}
+
static inline struct vfsmount *mntget(struct vfsmount *mnt)
{
if (mnt)
@@ -79,7 +88,11 @@ static inline struct vfsmount *mntget(struct vfsmount *mnt)
return mnt;
}
+struct file; /* forward dec */
+
extern int mnt_want_write(struct vfsmount *mnt);
+extern int mnt_want_write_file(struct file *file);
+extern int mnt_clone_write(struct vfsmount *mnt);
extern void mnt_drop_write(struct vfsmount *mnt);
extern void mntput_no_expire(struct vfsmount *mnt);
extern void mnt_pin(struct vfsmount *mnt);
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 3069ec7e0ab8..878cab4f5fcc 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -150,5 +150,6 @@ extern int __must_check mutex_lock_killable(struct mutex *lock);
*/
extern int mutex_trylock(struct mutex *lock);
extern void mutex_unlock(struct mutex *lock);
+extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);
#endif
diff --git a/include/linux/namei.h b/include/linux/namei.h
index fc2e03579877..d870ae2faedc 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -18,6 +18,7 @@ enum { MAX_NESTED_LINKS = 8 };
struct nameidata {
struct path path;
struct qstr last;
+ struct path root;
unsigned int flags;
int last_type;
unsigned depth;
@@ -69,7 +70,6 @@ extern int path_lookup(const char *, unsigned, struct nameidata *);
extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
const char *, unsigned int, struct nameidata *);
-extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);
extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
int (*open)(struct inode *, struct file *));
extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
@@ -78,8 +78,8 @@ extern void release_open_intent(struct nameidata *);
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 **);
+extern int follow_down(struct path *);
+extern int follow_up(struct path *);
extern struct dentry *lock_rename(struct dentry *, struct dentry *);
extern void unlock_rename(struct dentry *, struct dentry *);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5a96a1a406e9..2af89b662cad 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -39,9 +39,11 @@
#include <linux/device.h>
#include <linux/percpu.h>
+#include <linux/rculist.h>
#include <linux/dmaengine.h>
#include <linux/workqueue.h>
+#include <linux/ethtool.h>
#include <net/net_namespace.h>
#include <net/dsa.h>
#ifdef CONFIG_DCB
@@ -49,7 +51,6 @@
#endif
struct vlan_group;
-struct ethtool_ops;
struct netpoll_info;
/* 802.11 specific */
struct wireless_dev;
@@ -210,6 +211,16 @@ struct dev_addr_list
#define dmi_users da_users
#define dmi_gusers da_gusers
+struct netdev_hw_addr {
+ struct list_head list;
+ unsigned char addr[MAX_ADDR_LEN];
+ unsigned char type;
+#define NETDEV_HW_ADDR_T_LAN 1
+#define NETDEV_HW_ADDR_T_SAN 2
+#define NETDEV_HW_ADDR_T_SLAVE 3
+ struct rcu_head rcu_head;
+};
+
struct hh_cache
{
struct hh_cache *hh_next; /* Next entry */
@@ -447,12 +458,18 @@ enum netdev_queue_state_t
};
struct netdev_queue {
+/*
+ * read mostly part
+ */
struct net_device *dev;
struct Qdisc *qdisc;
unsigned long state;
- spinlock_t _xmit_lock;
- int xmit_lock_owner;
struct Qdisc *qdisc_sleeping;
+/*
+ * write mostly part
+ */
+ spinlock_t _xmit_lock ____cacheline_aligned_in_smp;
+ int xmit_lock_owner;
} ____cacheline_aligned_in_smp;
@@ -670,7 +687,9 @@ struct net_device
#define NETIF_F_GRO 16384 /* Generic receive offload */
#define NETIF_F_LRO 32768 /* large receive offload */
+/* the GSO_MASK reserves bits 16 through 23 */
#define NETIF_F_FCOE_CRC (1 << 24) /* FCoE CRC32 */
+#define NETIF_F_SCTP_CSUM (1 << 25) /* SCTP checksum offload */
/* Segmentation offload features */
#define NETIF_F_GSO_SHIFT 16
@@ -776,8 +795,11 @@ struct net_device
*/
unsigned long last_rx; /* Time of last Rx */
/* Interface address info used in eth_type_trans() */
- unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast
- because most packets are unicast) */
+ unsigned char *dev_addr; /* hw address, (before bcast
+ because most packets are
+ unicast) */
+
+ struct list_head dev_addr_list; /* list of device hw addresses */
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
@@ -1047,14 +1069,6 @@ struct packet_type {
struct list_head list;
};
-struct napi_gro_fraginfo {
- skb_frag_t frags[MAX_SKB_FRAGS];
- unsigned int nr_frags;
- unsigned int ip_summed;
- unsigned int len;
- __wsum csum;
-};
-
#include <linux/interrupt.h>
#include <linux/notifier.h>
@@ -1145,11 +1159,18 @@ static inline void skb_gro_reset_offset(struct sk_buff *skb)
static inline void *skb_gro_mac_header(struct sk_buff *skb)
{
- return skb_mac_header(skb) < skb->data ? skb_mac_header(skb) :
+ return skb_headlen(skb) ? skb_mac_header(skb) :
page_address(skb_shinfo(skb)->frags[0].page) +
skb_shinfo(skb)->frags[0].page_offset;
}
+static inline void *skb_gro_network_header(struct sk_buff *skb)
+{
+ return skb_headlen(skb) ? skb_network_header(skb) :
+ page_address(skb_shinfo(skb)->frags[0].page) +
+ skb_shinfo(skb)->frags[0].page_offset + skb_network_offset(skb);
+}
+
static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type,
const void *daddr, const void *saddr,
@@ -1442,12 +1463,18 @@ extern int napi_gro_receive(struct napi_struct *napi,
struct sk_buff *skb);
extern void napi_reuse_skb(struct napi_struct *napi,
struct sk_buff *skb);
-extern struct sk_buff * napi_fraginfo_skb(struct napi_struct *napi,
- struct napi_gro_fraginfo *info);
+extern struct sk_buff * napi_get_frags(struct napi_struct *napi);
extern int napi_frags_finish(struct napi_struct *napi,
struct sk_buff *skb, int ret);
-extern int napi_gro_frags(struct napi_struct *napi,
- struct napi_gro_fraginfo *info);
+extern struct sk_buff * napi_frags_skb(struct napi_struct *napi);
+extern int napi_gro_frags(struct napi_struct *napi);
+
+static inline void napi_free_frags(struct napi_struct *napi)
+{
+ kfree_skb(napi->skb);
+ napi->skb = NULL;
+}
+
extern void netif_nit_deliver(struct sk_buff *skb);
extern int dev_valid_name(const char *name);
extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
@@ -1778,6 +1805,13 @@ static inline void netif_addr_unlock_bh(struct net_device *dev)
spin_unlock_bh(&dev->addr_list_lock);
}
+/*
+ * dev_addr_list walker. Should be used only for read access. Call with
+ * rcu_read_lock held.
+ */
+#define for_each_dev_addr(dev, ha) \
+ list_for_each_entry_rcu(ha, &dev->dev_addr_list, list)
+
/* These functions live elsewhere (drivers/net/net_init.c, but related) */
extern void ether_setup(struct net_device *dev);
@@ -1790,6 +1824,19 @@ extern struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
alloc_netdev_mq(sizeof_priv, name, setup, 1)
extern int register_netdev(struct net_device *dev);
extern void unregister_netdev(struct net_device *dev);
+
+/* Functions used for device addresses handling */
+extern int dev_addr_add(struct net_device *dev, unsigned char *addr,
+ unsigned char addr_type);
+extern int dev_addr_del(struct net_device *dev, unsigned char *addr,
+ unsigned char addr_type);
+extern int dev_addr_add_multiple(struct net_device *to_dev,
+ struct net_device *from_dev,
+ unsigned char addr_type);
+extern int dev_addr_del_multiple(struct net_device *to_dev,
+ struct net_device *from_dev,
+ unsigned char addr_type);
+
/* Functions used for secondary unicast and multicast support */
extern void dev_set_rx_mode(struct net_device *dev);
extern void __dev_set_rx_mode(struct net_device *dev);
@@ -1908,6 +1955,28 @@ static inline int skb_bond_should_drop(struct sk_buff *skb)
}
extern struct pernet_operations __net_initdata loopback_net_ops;
+
+static inline int dev_ethtool_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
+ return -EOPNOTSUPP;
+ return dev->ethtool_ops->get_settings(dev, cmd);
+}
+
+static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev)
+{
+ if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum)
+ return 0;
+ return dev->ethtool_ops->get_rx_csum(dev);
+}
+
+static inline u32 dev_ethtool_get_flags(struct net_device *dev)
+{
+ if (!dev->ethtool_ops || !dev->ethtool_ops->get_flags)
+ return 0;
+ return dev->ethtool_ops->get_flags(dev);
+}
#endif /* __KERNEL__ */
#endif /* _LINUX_DEV_H */
diff --git a/include/linux/netfilter/xt_LED.h b/include/linux/netfilter/xt_LED.h
index 4c91a0d770d0..f5509e7524d3 100644
--- a/include/linux/netfilter/xt_LED.h
+++ b/include/linux/netfilter/xt_LED.h
@@ -1,6 +1,8 @@
#ifndef _XT_LED_H
#define _XT_LED_H
+#include <linux/types.h>
+
struct xt_led_info {
char id[27]; /* Unique ID for this trigger in the LED class */
__u8 always_blink; /* Blink even if the LED is already on */
diff --git a/include/linux/netfilter/xt_cluster.h b/include/linux/netfilter/xt_cluster.h
index 5e0a0d07b526..886682656f09 100644
--- a/include/linux/netfilter/xt_cluster.h
+++ b/include/linux/netfilter/xt_cluster.h
@@ -12,4 +12,6 @@ struct xt_cluster_match_info {
u_int32_t flags;
};
+#define XT_CLUSTER_NODES_MAX 32
+
#endif /* _XT_CLUSTER_MATCH_H */
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index e3f0cbcbd0db..bd2eba530667 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -21,6 +21,7 @@
#define NFS4_FHSIZE 128
#define NFS4_MAXPATHLEN PATH_MAX
#define NFS4_MAXNAMLEN NAME_MAX
+#define NFS4_OPAQUE_LIMIT 1024
#define NFS4_MAX_SESSIONID_LEN 16
#define NFS4_ACCESS_READ 0x0001
@@ -130,6 +131,16 @@
#define NFS4_MAX_UINT64 (~(u64)0)
+/* An NFS4 sessions server must support at least NFS4_MAX_OPS operations.
+ * If a compound requires more operations, adjust NFS4_MAX_OPS accordingly.
+ */
+#define NFS4_MAX_OPS 8
+
+/* Our NFS4 client back channel server only wants the cb_sequene and the
+ * actual operation per compound
+ */
+#define NFS4_MAX_BACK_CHANNEL_OPS 2
+
enum nfs4_acl_whotype {
NFS4_ACL_WHO_NAMED = 0,
NFS4_ACL_WHO_OWNER,
@@ -462,6 +473,13 @@ enum lock_type4 {
#define NFSPROC4_NULL 0
#define NFSPROC4_COMPOUND 1
#define NFS4_MINOR_VERSION 0
+
+#if defined(CONFIG_NFS_V4_1)
+#define NFS4_MAX_MINOR_VERSION 1
+#else
+#define NFS4_MAX_MINOR_VERSION 0
+#endif /* CONFIG_NFS_V4_1 */
+
#define NFS4_DEBUG 1
/* Index of predefined Linux client operations */
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 6ad75948cbf7..d0902ccec9ce 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -4,11 +4,17 @@
#include <linux/list.h>
#include <linux/backing-dev.h>
#include <linux/wait.h>
+#include <linux/nfs_xdr.h>
+#include <linux/sunrpc/xprt.h>
#include <asm/atomic.h>
+struct nfs4_session;
struct nfs_iostats;
struct nlm_host;
+struct nfs4_sequence_args;
+struct nfs4_sequence_res;
+struct nfs_server;
/*
* The nfs_client identifies our client state to the server.
@@ -18,6 +24,7 @@ struct nfs_client {
int cl_cons_state; /* current construction state (-ve: init error) */
#define NFS_CS_READY 0 /* ready to be used */
#define NFS_CS_INITING 1 /* busy initialising */
+#define NFS_CS_SESSION_INITING 2 /* busy initialising session */
unsigned long cl_res_state; /* NFS resources state */
#define NFS_CS_CALLBACK 1 /* - callback started */
#define NFS_CS_IDMAP 2 /* - idmap started */
@@ -32,6 +39,7 @@ struct nfs_client {
const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */
int cl_proto; /* Network transport protocol */
+ u32 cl_minorversion;/* NFSv4 minorversion */
struct rpc_cred *cl_machine_cred;
#ifdef CONFIG_NFS_V4
@@ -63,7 +71,22 @@ struct nfs_client {
*/
char cl_ipaddr[48];
unsigned char cl_id_uniquifier;
-#endif
+ int (* cl_call_sync)(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply);
+#endif /* CONFIG_NFS_V4 */
+
+#ifdef CONFIG_NFS_V4_1
+ /* clientid returned from EXCHANGE_ID, used by session operations */
+ u64 cl_ex_clid;
+ /* The sequence id to use for the next CREATE_SESSION */
+ u32 cl_seqid;
+ /* The flags used for obtaining the clientid during EXCHANGE_ID */
+ u32 cl_exchange_flags;
+ struct nfs4_session *cl_session; /* sharred session */
+#endif /* CONFIG_NFS_V4_1 */
#ifdef CONFIG_NFS_FSCACHE
struct fscache_cookie *fscache; /* client index cache cookie */
@@ -145,4 +168,46 @@ struct nfs_server {
#define NFS_CAP_ACLS (1U << 3)
#define NFS_CAP_ATOMIC_OPEN (1U << 4)
+
+/* maximum number of slots to use */
+#define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE
+
+#if defined(CONFIG_NFS_V4_1)
+
+/* Sessions */
+#define SLOT_TABLE_SZ (NFS4_MAX_SLOT_TABLE/(8*sizeof(long)))
+struct nfs4_slot_table {
+ struct nfs4_slot *slots; /* seqid per slot */
+ unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */
+ spinlock_t slot_tbl_lock;
+ struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */
+ int max_slots; /* # slots in table */
+ int highest_used_slotid; /* sent to server on each SEQ.
+ * op for dynamic resizing */
+};
+
+static inline int slot_idx(struct nfs4_slot_table *tbl, struct nfs4_slot *sp)
+{
+ return sp - tbl->slots;
+}
+
+/*
+ * Session related parameters
+ */
+struct nfs4_session {
+ struct nfs4_sessionid sess_id;
+ u32 flags;
+ unsigned long session_state;
+ u32 hash_alg;
+ u32 ssv_len;
+
+ /* The fore and back channel */
+ struct nfs4_channel_attrs fc_attrs;
+ struct nfs4_slot_table fc_slot_table;
+ struct nfs4_channel_attrs bc_attrs;
+ /* back channel has one slot */
+ struct nfs_client *clp;
+};
+
+#endif /* CONFIG_NFS_V4_1 */
#endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index b89c34e40bc2..071a6d10ae13 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -145,6 +145,44 @@ struct nfs4_change_info {
};
struct nfs_seqid;
+
+/* nfs41 sessions channel attributes */
+struct nfs4_channel_attrs {
+ u32 headerpadsz;
+ u32 max_rqst_sz;
+ u32 max_resp_sz;
+ u32 max_resp_sz_cached;
+ u32 max_ops;
+ u32 max_reqs;
+};
+
+/* nfs41 sessions slot seqid */
+struct nfs4_slot {
+ u32 seq_nr;
+};
+
+struct nfs4_sequence_args {
+ struct nfs4_session *sa_session;
+ u8 sa_slotid;
+ u8 sa_cache_this;
+};
+
+struct nfs4_sequence_res {
+ struct nfs4_session *sr_session;
+ u8 sr_slotid; /* slot used to send request */
+ unsigned long sr_renewal_time;
+ int sr_status; /* sequence operation status */
+};
+
+struct nfs4_get_lease_time_args {
+ struct nfs4_sequence_args la_seq_args;
+};
+
+struct nfs4_get_lease_time_res {
+ struct nfs_fsinfo *lr_fsinfo;
+ struct nfs4_sequence_res lr_seq_res;
+};
+
/*
* Arguments to the open call.
*/
@@ -165,6 +203,7 @@ struct nfs_openargs {
const struct nfs_server *server; /* Needed for ID mapping */
const u32 * bitmask;
__u32 claim;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_openres {
@@ -181,6 +220,7 @@ struct nfs_openres {
__u32 do_recall;
__u64 maxsize;
__u32 attrset[NFS4_BITMAP_SIZE];
+ struct nfs4_sequence_res seq_res;
};
/*
@@ -206,6 +246,7 @@ struct nfs_closeargs {
struct nfs_seqid * seqid;
fmode_t fmode;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_closeres {
@@ -213,6 +254,7 @@ struct nfs_closeres {
struct nfs_fattr * fattr;
struct nfs_seqid * seqid;
const struct nfs_server *server;
+ struct nfs4_sequence_res seq_res;
};
/*
* * Arguments to the lock,lockt, and locku call.
@@ -233,12 +275,14 @@ struct nfs_lock_args {
unsigned char block : 1;
unsigned char reclaim : 1;
unsigned char new_lock_owner : 1;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_lock_res {
nfs4_stateid stateid;
struct nfs_seqid * lock_seqid;
struct nfs_seqid * open_seqid;
+ struct nfs4_sequence_res seq_res;
};
struct nfs_locku_args {
@@ -246,32 +290,38 @@ struct nfs_locku_args {
struct file_lock * fl;
struct nfs_seqid * seqid;
nfs4_stateid * stateid;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_locku_res {
nfs4_stateid stateid;
struct nfs_seqid * seqid;
+ struct nfs4_sequence_res seq_res;
};
struct nfs_lockt_args {
struct nfs_fh * fh;
struct file_lock * fl;
struct nfs_lowner lock_owner;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_lockt_res {
struct file_lock * denied; /* LOCK, LOCKT failed */
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_delegreturnargs {
const struct nfs_fh *fhandle;
const nfs4_stateid *stateid;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_delegreturnres {
struct nfs_fattr * fattr;
const struct nfs_server *server;
+ struct nfs4_sequence_res seq_res;
};
/*
@@ -284,12 +334,14 @@ struct nfs_readargs {
__u32 count;
unsigned int pgbase;
struct page ** pages;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_readres {
struct nfs_fattr * fattr;
__u32 count;
int eof;
+ struct nfs4_sequence_res seq_res;
};
/*
@@ -304,6 +356,7 @@ struct nfs_writeargs {
unsigned int pgbase;
struct page ** pages;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_writeverf {
@@ -316,6 +369,7 @@ struct nfs_writeres {
struct nfs_writeverf * verf;
__u32 count;
const struct nfs_server *server;
+ struct nfs4_sequence_res seq_res;
};
/*
@@ -325,12 +379,14 @@ struct nfs_removeargs {
const struct nfs_fh *fh;
struct qstr name;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_removeres {
const struct nfs_server *server;
struct nfs4_change_info cinfo;
struct nfs_fattr dir_attr;
+ struct nfs4_sequence_res seq_res;
};
/*
@@ -383,6 +439,7 @@ struct nfs_setattrargs {
struct iattr * iap;
const struct nfs_server * server; /* Needed for name mapping */
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_setaclargs {
@@ -390,6 +447,11 @@ struct nfs_setaclargs {
size_t acl_len;
unsigned int acl_pgbase;
struct page ** acl_pages;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs_setaclres {
+ struct nfs4_sequence_res seq_res;
};
struct nfs_getaclargs {
@@ -397,11 +459,18 @@ struct nfs_getaclargs {
size_t acl_len;
unsigned int acl_pgbase;
struct page ** acl_pages;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs_getaclres {
+ size_t acl_len;
+ struct nfs4_sequence_res seq_res;
};
struct nfs_setattrres {
struct nfs_fattr * fattr;
const struct nfs_server * server;
+ struct nfs4_sequence_res seq_res;
};
struct nfs_linkargs {
@@ -583,6 +652,7 @@ struct nfs4_accessargs {
const struct nfs_fh * fh;
const u32 * bitmask;
u32 access;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_accessres {
@@ -590,6 +660,7 @@ struct nfs4_accessres {
struct nfs_fattr * fattr;
u32 supported;
u32 access;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_create_arg {
@@ -609,6 +680,7 @@ struct nfs4_create_arg {
const struct iattr * attrs;
const struct nfs_fh * dir_fh;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_create_res {
@@ -617,21 +689,30 @@ struct nfs4_create_res {
struct nfs_fattr * fattr;
struct nfs4_change_info dir_cinfo;
struct nfs_fattr * dir_fattr;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_fsinfo_arg {
const struct nfs_fh * fh;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs4_fsinfo_res {
+ struct nfs_fsinfo *fsinfo;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_getattr_arg {
const struct nfs_fh * fh;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_getattr_res {
const struct nfs_server * server;
struct nfs_fattr * fattr;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_link_arg {
@@ -639,6 +720,7 @@ struct nfs4_link_arg {
const struct nfs_fh * dir_fh;
const struct qstr * name;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_link_res {
@@ -646,6 +728,7 @@ struct nfs4_link_res {
struct nfs_fattr * fattr;
struct nfs4_change_info cinfo;
struct nfs_fattr * dir_attr;
+ struct nfs4_sequence_res seq_res;
};
@@ -653,21 +736,30 @@ struct nfs4_lookup_arg {
const struct nfs_fh * dir_fh;
const struct qstr * name;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_lookup_res {
const struct nfs_server * server;
struct nfs_fattr * fattr;
struct nfs_fh * fh;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_lookup_root_arg {
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_pathconf_arg {
const struct nfs_fh * fh;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs4_pathconf_res {
+ struct nfs_pathconf *pathconf;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_readdir_arg {
@@ -678,11 +770,13 @@ struct nfs4_readdir_arg {
struct page ** pages; /* zero-copy data */
unsigned int pgbase; /* zero-copy data */
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_readdir_res {
nfs4_verifier verifier;
unsigned int pgbase;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_readlink {
@@ -690,6 +784,11 @@ struct nfs4_readlink {
unsigned int pgbase;
unsigned int pglen; /* zero-copy data */
struct page ** pages; /* zero-copy data */
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs4_readlink_res {
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_rename_arg {
@@ -698,6 +797,7 @@ struct nfs4_rename_arg {
const struct qstr * old_name;
const struct qstr * new_name;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_rename_res {
@@ -706,6 +806,7 @@ struct nfs4_rename_res {
struct nfs_fattr * old_fattr;
struct nfs4_change_info new_cinfo;
struct nfs_fattr * new_fattr;
+ struct nfs4_sequence_res seq_res;
};
#define NFS4_SETCLIENTID_NAMELEN (127)
@@ -724,6 +825,17 @@ struct nfs4_setclientid {
struct nfs4_statfs_arg {
const struct nfs_fh * fh;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs4_statfs_res {
+ struct nfs_fsstat *fsstat;
+ struct nfs4_sequence_res seq_res;
+};
+
+struct nfs4_server_caps_arg {
+ struct nfs_fh *fhandle;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_server_caps_res {
@@ -731,6 +843,7 @@ struct nfs4_server_caps_res {
u32 acl_bitmask;
u32 has_links;
u32 has_symlinks;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_string {
@@ -765,10 +878,71 @@ struct nfs4_fs_locations_arg {
const struct qstr *name;
struct page *page;
const u32 *bitmask;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs4_fs_locations_res {
+ struct nfs4_fs_locations *fs_locations;
+ struct nfs4_sequence_res seq_res;
};
#endif /* CONFIG_NFS_V4 */
+struct nfstime4 {
+ u64 seconds;
+ u32 nseconds;
+};
+
+#ifdef CONFIG_NFS_V4_1
+struct nfs_impl_id4 {
+ u32 domain_len;
+ char *domain;
+ u32 name_len;
+ char *name;
+ struct nfstime4 date;
+};
+
+#define NFS4_EXCHANGE_ID_LEN (48)
+struct nfs41_exchange_id_args {
+ struct nfs_client *client;
+ nfs4_verifier *verifier;
+ unsigned int id_len;
+ char id[NFS4_EXCHANGE_ID_LEN];
+ u32 flags;
+};
+
+struct server_owner {
+ uint64_t minor_id;
+ uint32_t major_id_sz;
+ char major_id[NFS4_OPAQUE_LIMIT];
+};
+
+struct server_scope {
+ uint32_t server_scope_sz;
+ char server_scope[NFS4_OPAQUE_LIMIT];
+};
+
+struct nfs41_exchange_id_res {
+ struct nfs_client *client;
+ u32 flags;
+ struct server_owner server_owner;
+ struct server_scope server_scope;
+ struct nfs_impl_id4 impl_id;
+};
+
+struct nfs41_create_session_args {
+ struct nfs_client *client;
+ uint32_t flags;
+ uint32_t cb_program;
+ struct nfs4_channel_attrs fc_attrs; /* Fore Channel */
+ struct nfs4_channel_attrs bc_attrs; /* Back Channel */
+};
+
+struct nfs41_create_session_res {
+ struct nfs_client *client;
+};
+#endif /* CONFIG_NFS_V4_1 */
+
struct nfs_page;
#define NFS_PAGEVEC_SIZE (8U)
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index bcd0201589f8..a6d9ef2bb34a 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -125,11 +125,9 @@ void nfsd_export_flush(void);
void exp_readlock(void);
void exp_readunlock(void);
struct svc_export * rqst_exp_get_by_name(struct svc_rqst *,
- struct vfsmount *,
- struct dentry *);
+ struct path *);
struct svc_export * rqst_exp_parent(struct svc_rqst *,
- struct vfsmount *mnt,
- struct dentry *dentry);
+ struct path *);
int exp_rootfh(struct auth_domain *,
char *path, struct knfsd_fh *, int maxsize);
__be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *);
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
index afa19016c4a8..8f641c908450 100644
--- a/include/linux/nfsd/nfsfh.h
+++ b/include/linux/nfsd/nfsfh.h
@@ -151,9 +151,15 @@ typedef struct svc_fh {
__u64 fh_pre_size; /* size before operation */
struct timespec fh_pre_mtime; /* mtime before oper */
struct timespec fh_pre_ctime; /* ctime before oper */
+ /*
+ * pre-op nfsv4 change attr: note must check IS_I_VERSION(inode)
+ * to find out if it is valid.
+ */
+ u64 fh_pre_change;
/* Post-op attributes saved in fh_unlock */
struct kstat fh_post_attr; /* full attrs after operation */
+ u64 fh_post_change; /* nfsv4 change; see above */
#endif /* CONFIG_NFSD_V3 */
} svc_fh;
@@ -298,6 +304,7 @@ fill_pre_wcc(struct svc_fh *fhp)
fhp->fh_pre_mtime = inode->i_mtime;
fhp->fh_pre_ctime = inode->i_ctime;
fhp->fh_pre_size = inode->i_size;
+ fhp->fh_pre_change = inode->i_version;
fhp->fh_pre_saved = 1;
}
}
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index 4d61c873feed..b60ba43df041 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -41,7 +41,6 @@
#include <linux/kref.h>
#include <linux/sunrpc/clnt.h>
-#define NFS4_OPAQUE_LIMIT 1024
typedef struct {
u32 cl_boot;
u32 cl_id;
@@ -61,15 +60,6 @@ typedef struct {
#define si_stateownerid si_opaque.so_stateownerid
#define si_fileid si_opaque.so_fileid
-
-struct nfs4_cb_recall {
- u32 cbr_ident;
- int cbr_trunc;
- stateid_t cbr_stateid;
- struct knfsd_fh cbr_fh;
- struct nfs4_delegation *cbr_dp;
-};
-
struct nfs4_delegation {
struct list_head dl_perfile;
struct list_head dl_perclnt;
@@ -81,14 +71,15 @@ struct nfs4_delegation {
struct file *dl_vfs_file;
u32 dl_type;
time_t dl_time;
- struct nfs4_cb_recall dl_recall;
+/* For recall: */
+ u32 dl_ident;
+ stateid_t dl_stateid;
+ struct knfsd_fh dl_fh;
+ int dl_retries;
};
-#define dl_stateid dl_recall.cbr_stateid
-#define dl_fh dl_recall.cbr_fh
-
/* client delegation callback info */
-struct nfs4_callback {
+struct nfs4_cb_conn {
/* SETCLIENTID info */
u32 cb_addr;
unsigned short cb_port;
@@ -97,6 +88,7 @@ struct nfs4_callback {
/* RPC client info */
atomic_t cb_set; /* successful CB_NULL call */
struct rpc_clnt * cb_client;
+ struct rpc_cred * cb_cred;
};
/* Maximum number of slots per session. 128 is useful for long haul TCP */
@@ -185,7 +177,7 @@ struct nfs4_client {
struct svc_cred cl_cred; /* setclientid principal */
clientid_t cl_clientid; /* generated by server */
nfs4_verifier cl_confirm; /* generated by server */
- struct nfs4_callback cl_callback; /* callback info */
+ struct nfs4_cb_conn cl_cb_conn; /* callback info */
atomic_t cl_count; /* ref count */
u32 cl_firststate; /* recovery dir creation */
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index f80d6013fdc3..d0f050f01eca 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -64,10 +64,13 @@ static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
struct nfsd4_change_info {
u32 atomic;
+ bool change_supported;
u32 before_ctime_sec;
u32 before_ctime_nsec;
+ u64 before_change;
u32 after_ctime_sec;
u32 after_ctime_nsec;
+ u64 after_change;
};
struct nfsd4_access {
@@ -503,10 +506,16 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
{
BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
cinfo->atomic = 1;
- cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
- cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
- cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
- cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
+ cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode);
+ if (cinfo->change_supported) {
+ cinfo->before_change = fhp->fh_pre_change;
+ cinfo->after_change = fhp->fh_post_change;
+ } else {
+ cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
+ cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
+ cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
+ cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
+ }
}
int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index cbe8ce3bf486..dbea93b694e5 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -7,7 +7,7 @@
* Copyright 2008 Michael Wu <flamingice@sourmilk.net>
* Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com>
* Copyright 2008 Michael Buesch <mb@bu3sch.de>
- * Copyright 2008 Luis R. Rodriguez <lrodriguez@atheros.com>
+ * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez@atheros.com>
* Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
* Copyright 2008 Colin McCabe <colin@cozybit.com>
*
@@ -25,6 +25,8 @@
*
*/
+#include <linux/types.h>
+
/**
* DOC: Station handling
*
@@ -46,8 +48,10 @@
* to get a list of all present wiphys.
* @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
* %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
- * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, and/or
- * %NL80211_ATTR_WIPHY_CHANNEL_TYPE.
+ * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ,
+ * %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT,
+ * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+ * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
* @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
* or rename notification. Has attributes %NL80211_ATTR_WIPHY and
* %NL80211_ATTR_WIPHY_NAME.
@@ -75,8 +79,8 @@
* @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
* %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
* @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
- * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC and %NL80211_ATTR_KEY_CIPHER
- * attributes.
+ * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,
+ * and %NL80211_ATTR_KEY_SEQ attributes.
* @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
* or %NL80211_ATTR_MAC.
*
@@ -166,6 +170,22 @@
* set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
* %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
* to (%NL80211_ATTR_REG_ALPHA2).
+ * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon
+ * has been found while world roaming thus enabling active scan or
+ * any mode of operation that initiates TX (beacons) on a channel
+ * where we would not have been able to do either before. As an example
+ * if you are world roaming (regulatory domain set to world or if your
+ * driver is using a custom world roaming regulatory domain) and while
+ * doing a passive scan on the 5 GHz band you find an AP there (if not
+ * on a DFS channel) you will now be able to actively scan for that AP
+ * or use AP mode on your card on that same channel. Note that this will
+ * never be used for channels 1-11 on the 2 GHz band as they are always
+ * enabled world wide. This beacon hint is only sent if your device had
+ * either disabled active scanning or beaconing on a channel. We send to
+ * userspace the wiphy on which we removed a restriction from
+ * (%NL80211_ATTR_WIPHY) and the channel on which this occurred
+ * before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER)
+ * the beacon hint was processed.
*
* @NL80211_CMD_AUTHENTICATE: authentication request and notification.
* This command is used both as a command (request to authenticate) and
@@ -185,8 +205,12 @@
* frame, i.e., it was for the local STA and was received in correct
* state. This is similar to MLME-AUTHENTICATE.confirm primitive in the
* MLME SAP interface (kernel providing MLME, userspace SME). The
- * included NL80211_ATTR_FRAME attribute contains the management frame
- * (including both the header and frame body, but not FCS).
+ * included %NL80211_ATTR_FRAME attribute contains the management frame
+ * (including both the header and frame body, but not FCS). This event is
+ * also used to indicate if the authentication attempt timed out. In that
+ * case the %NL80211_ATTR_FRAME attribute is replaced with a
+ * %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which
+ * pending authentication timed out).
* @NL80211_CMD_ASSOCIATE: association request and notification; like
* NL80211_CMD_AUTHENTICATE but for Association and Reassociation
* (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request,
@@ -199,6 +223,25 @@
* NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to
* MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives).
*
+ * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael
+ * MIC (part of TKIP) failure; sent on the "mlme" multicast group; the
+ * event includes %NL80211_ATTR_MAC to describe the source MAC address of
+ * the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key
+ * type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and
+ * %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this
+ * event matches with MLME-MICHAELMICFAILURE.indication() primitive
+ *
+ * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a
+ * FREQ attribute (for the initial frequency if no peer can be found)
+ * and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those
+ * should be fixed rather than automatically determined. Can only be
+ * executed on a network interface that is UP, and fixed BSSID/FREQ
+ * may be rejected. Another optional parameter is the beacon interval,
+ * given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not
+ * given defaults to 100 TU (102.4ms).
+ * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
+ * determined by the network interface.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -260,6 +303,13 @@ enum nl80211_commands {
NL80211_CMD_DEAUTHENTICATE,
NL80211_CMD_DISASSOCIATE,
+ NL80211_CMD_MICHAEL_MIC_FAILURE,
+
+ NL80211_CMD_REG_BEACON_HINT,
+
+ NL80211_CMD_JOIN_IBSS,
+ NL80211_CMD_LEAVE_IBSS,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -278,6 +328,7 @@ enum nl80211_commands {
#define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE
#define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE
#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
+#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
/**
* enum nl80211_attrs - nl80211 netlink attributes
@@ -296,6 +347,18 @@ enum nl80211_commands {
* NL80211_CHAN_HT20 = HT20 only
* NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel
* NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel
+ * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is
+ * less than or equal to the RTS threshold; allowed range: 1..255;
+ * dot11ShortRetryLimit; u8
+ * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is
+ * greater than the RTS threshold; allowed range: 1..255;
+ * dot11ShortLongLimit; u8
+ * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum
+ * length in octets for frames; allowed range: 256..8000, disable
+ * fragmentation with (u32)-1; dot11FragmentationThreshold; u32
+ * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length
+ * larger than or equal to this use RTS/CTS handshake); allowed range:
+ * 0..65536, disable with (u32)-1; dot11RTSThreshold; u32
*
* @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
* @NL80211_ATTR_IFNAME: network interface name
@@ -319,7 +382,7 @@ enum nl80211_commands {
*
* @NL80211_ATTR_STA_AID: Association ID for the station (u16)
* @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of
- * &enum nl80211_sta_flags.
+ * &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2)
* @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by
* IEEE 802.11 7.3.1.6 (u16).
* @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported
@@ -380,6 +443,8 @@ enum nl80211_commands {
*
* @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with
* a single scan request, a wiphy attribute.
+ * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements
+ * that can be added to a scan request
*
* @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz)
* @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive
@@ -408,6 +473,44 @@ enum nl80211_commands {
* @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and
* %NL80211_CMD_DISASSOCIATE, u16
*
+ * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as
+ * a u32
+ *
+ * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change
+ * due to considerations from a beacon hint. This attribute reflects
+ * the state of the channel _before_ the beacon hint processing. This
+ * attributes consists of a nested attribute containing
+ * NL80211_FREQUENCY_ATTR_*
+ * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change
+ * due to considerations from a beacon hint. This attribute reflects
+ * the state of the channel _after_ the beacon hint processing. This
+ * attributes consists of a nested attribute containing
+ * NL80211_FREQUENCY_ATTR_*
+ *
+ * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported
+ * cipher suites
+ *
+ * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look
+ * for other networks on different channels
+ *
+ * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
+ * is used, e.g., with %NL80211_CMD_AUTHENTICATE event
+ *
+ * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
+ * used for the association (&enum nl80211_mfp, represented as a u32);
+ * this attribute can be used
+ * with %NL80211_CMD_ASSOCIATE request
+ *
+ * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
+ * &struct nl80211_sta_flag_update.
+ *
+ * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls
+ * IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in
+ * station mode. If the flag is included in %NL80211_CMD_ASSOCIATE
+ * request, the driver will assume that the port is unauthorized until
+ * authorized by user space. Otherwise, port is marked authorized by
+ * default in station mode.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -492,6 +595,30 @@ enum nl80211_attrs {
NL80211_ATTR_AUTH_TYPE,
NL80211_ATTR_REASON_CODE,
+ NL80211_ATTR_KEY_TYPE,
+
+ NL80211_ATTR_MAX_SCAN_IE_LEN,
+ NL80211_ATTR_CIPHER_SUITES,
+
+ NL80211_ATTR_FREQ_BEFORE,
+ NL80211_ATTR_FREQ_AFTER,
+
+ NL80211_ATTR_FREQ_FIXED,
+
+
+ NL80211_ATTR_WIPHY_RETRY_SHORT,
+ NL80211_ATTR_WIPHY_RETRY_LONG,
+ NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+ NL80211_ATTR_WIPHY_RTS_THRESHOLD,
+
+ NL80211_ATTR_TIMED_OUT,
+
+ NL80211_ATTR_USE_MFP,
+
+ NL80211_ATTR_STA_FLAGS2,
+
+ NL80211_ATTR_CONTROL_PORT,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -581,6 +708,18 @@ enum nl80211_sta_flags {
};
/**
+ * struct nl80211_sta_flag_update - station flags mask/set
+ * @mask: mask of station flags to set
+ * @set: which values to set them to
+ *
+ * Both mask and set contain bits as per &enum nl80211_sta_flags.
+ */
+struct nl80211_sta_flag_update {
+ __u32 mask;
+ __u32 set;
+} __attribute__((packed));
+
+/**
* enum nl80211_rate_info - bitrate information
*
* These attribute types are used with %NL80211_STA_INFO_TXRATE
@@ -1062,4 +1201,27 @@ enum nl80211_auth_type {
NL80211_AUTHTYPE_FT,
NL80211_AUTHTYPE_NETWORK_EAP,
};
+
+/**
+ * enum nl80211_key_type - Key Type
+ * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key
+ * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key
+ * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS)
+ */
+enum nl80211_key_type {
+ NL80211_KEYTYPE_GROUP,
+ NL80211_KEYTYPE_PAIRWISE,
+ NL80211_KEYTYPE_PEERKEY,
+};
+
+/**
+ * enum nl80211_mfp - Management frame protection state
+ * @NL80211_MFP_NO: Management frame protection not used
+ * @NL80211_MFP_REQUIRED: Management frame protection required
+ */
+enum nl80211_mfp {
+ NL80211_MFP_NO,
+ NL80211_MFP_REQUIRED,
+};
+
#endif /* __LINUX_NL80211_H */
diff --git a/include/linux/nls.h b/include/linux/nls.h
index 6a882208301a..52b1a76c1b43 100644
--- a/include/linux/nls.h
+++ b/include/linux/nls.h
@@ -58,6 +58,25 @@ static inline int nls_strnicmp(struct nls_table *t, const unsigned char *s1,
return 0;
}
+/*
+ * nls_nullsize - return length of null character for codepage
+ * @codepage - codepage for which to return length of NULL terminator
+ *
+ * Since we can't guarantee that the null terminator will be a particular
+ * length, we have to check against the codepage. If there's a problem
+ * determining it, assume a single-byte NULL terminator.
+ */
+static inline int
+nls_nullsize(const struct nls_table *codepage)
+{
+ int charlen;
+ char tmp[NLS_MAX_CHARSET_SIZE];
+
+ charlen = codepage->uni2char(0, tmp, NLS_MAX_CHARSET_SIZE);
+
+ return charlen > 0 ? charlen : 1;
+}
+
#define MODULE_ALIAS_NLS(name) MODULE_ALIAS("nls_" __stringify(name))
#endif /* _LINUX_NLS_H */
diff --git a/include/linux/of.h b/include/linux/of.h
index 6a7efa242f5e..7be2d1043c16 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -77,6 +77,9 @@ extern int of_n_size_cells(struct device_node *np);
extern const struct of_device_id *of_match_node(
const struct of_device_id *matches, const struct device_node *node);
extern int of_modalias_node(struct device_node *node, char *modalias, int len);
+extern struct device_node *of_parse_phandle(struct device_node *np,
+ const char *phandle_name,
+ int index);
extern int of_parse_phandles_with_args(struct device_node *np,
const char *list_name, const char *cells_name, int index,
struct device_node **out_node, const void **out_args);
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
new file mode 100644
index 000000000000..c9663c690303
--- /dev/null
+++ b/include/linux/of_mdio.h
@@ -0,0 +1,22 @@
+/*
+ * OF helpers for the MDIO (Ethernet PHY) API
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_OF_MDIO_H
+#define __LINUX_OF_MDIO_H
+
+#include <linux/phy.h>
+#include <linux/of.h>
+
+extern int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np);
+extern struct phy_device *of_phy_find_device(struct device_node *phy_np);
+extern struct phy_device *of_phy_connect(struct net_device *dev,
+ struct device_node *phy_np,
+ void (*hndlr)(struct net_device *),
+ u32 flags, phy_interface_t iface);
+
+#endif /* __LINUX_OF_MDIO_H */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 62214c7d2d93..f036dfbdad54 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -120,7 +120,6 @@ enum pageflags {
PG_savepinned = PG_dirty,
/* SLOB */
- PG_slob_page = PG_active,
PG_slob_free = PG_private,
/* SLUB */
@@ -203,7 +202,6 @@ PAGEFLAG(SavePinned, savepinned); /* Xen */
PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
-__PAGEFLAG(SlobPage, slob_page)
__PAGEFLAG(SlobFree, slob_free)
__PAGEFLAG(SlubFrozen, slub_frozen)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 72698d89e767..19ee92c53ef7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -599,8 +599,6 @@ extern void pci_sort_breadthfirst(void);
struct pci_dev __deprecated *pci_find_device(unsigned int vendor,
unsigned int device,
struct pci_dev *from);
-struct pci_dev __deprecated *pci_find_slot(unsigned int bus,
- unsigned int devfn);
#endif /* CONFIG_PCI_LEGACY */
enum pci_lost_interrupt_reason {
@@ -936,12 +934,6 @@ static inline struct pci_dev *pci_find_device(unsigned int vendor,
return NULL;
}
-static inline struct pci_dev *pci_find_slot(unsigned int bus,
- unsigned int devfn)
-{
- return NULL;
-}
-
static inline struct pci_dev *pci_get_device(unsigned int vendor,
unsigned int device,
struct pci_dev *from)
@@ -1097,6 +1089,10 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
#include <asm/pci.h>
+#ifndef PCIBIOS_MAX_MEM_32
+#define PCIBIOS_MAX_MEM_32 (-1)
+#endif
+
/* these helpers provide future and backwards compatibility
* for accessing popular PCI BAR info */
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 06ba90c211a5..c9e28326d146 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1005,6 +1005,7 @@
#define PCI_DEVICE_ID_PLX_PCI200SYN 0x3196
#define PCI_DEVICE_ID_PLX_9030 0x9030
#define PCI_DEVICE_ID_PLX_9050 0x9050
+#define PCI_DEVICE_ID_PLX_9056 0x9056
#define PCI_DEVICE_ID_PLX_9080 0x9080
#define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001
@@ -1847,6 +1848,10 @@
#define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107
#define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108
+#define PCI_VENDOR_ID_DIGIGRAM 0x1369
+#define PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM 0xc001
+#define PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_CAE_SERIAL_SUBSYSTEM 0xc002
+
#define PCI_VENDOR_ID_KAWASAKI 0x136b
#define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01
@@ -1996,10 +2001,12 @@
#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_U 0xC118
#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_GU 0xC11C
#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
+#define PCI_DEVICE_ID_OXSEMI_C950 0x950B
#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511
#define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513
#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x9521
#define PCI_DEVICE_ID_OXSEMI_16PCI952PP 0x9523
+#define PCI_SUBDEVICE_ID_OXSEMI_C950 0x0001
#define PCI_VENDOR_ID_CHELSIO 0x1425
@@ -2274,6 +2281,8 @@
#define PCI_DEVICE_ID_MPC8547E 0x0018
#define PCI_DEVICE_ID_MPC8545E 0x0019
#define PCI_DEVICE_ID_MPC8545 0x001a
+#define PCI_DEVICE_ID_MPC8569E 0x0061
+#define PCI_DEVICE_ID_MPC8569 0x0060
#define PCI_DEVICE_ID_MPC8568E 0x0020
#define PCI_DEVICE_ID_MPC8568 0x0021
#define PCI_DEVICE_ID_MPC8567E 0x0022
@@ -2313,6 +2322,8 @@
#define PCI_VENDOR_ID_QMI 0x1a32
+#define PCI_VENDOR_ID_AZWAVE 0x1a3b
+
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 616bf8b3c8b5..83b02f5a25b2 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -295,8 +295,9 @@
#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
+#define PCI_MSI_MASK_32 12 /* Mask bits register for 32-bit devices */
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
-#define PCI_MSI_MASK_BIT 16 /* Mask bits register */
+#define PCI_MSI_MASK_64 16 /* Mask bits register for 64-bit devices */
/* MSI-X registers (these are at offset PCI_MSIX_FLAGS) */
#define PCI_MSIX_FLAGS 2
@@ -304,7 +305,6 @@
#define PCI_MSIX_FLAGS_ENABLE (1 << 15)
#define PCI_MSIX_FLAGS_MASKALL (1 << 14)
#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
-#define PCI_MSIX_FLAGS_BITMASK (1 << 0)
/* CompactPCI Hotswap Register */
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 97e40cb6b588..c216e4e503b3 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -444,10 +444,16 @@ static inline int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
+int phy_device_register(struct phy_device *phy);
int phy_clear_interrupt(struct phy_device *phydev);
int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
+int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
+ u32 flags, phy_interface_t interface);
struct phy_device * phy_attach(struct net_device *dev,
const char *bus_id, u32 flags, phy_interface_t interface);
+int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
+ void (*handler)(struct net_device *), u32 flags,
+ phy_interface_t interface);
struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
void (*handler)(struct net_device *), u32 flags,
phy_interface_t interface);
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index c8f038554e80..b43a9e039059 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -152,5 +152,6 @@ void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void
void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
+void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
#endif
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 72736fd8223c..b67bb5d7b221 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -20,7 +20,6 @@ struct platform_device {
struct device dev;
u32 num_resources;
struct resource * resource;
- void *platform_data;
struct platform_device_id *id_entry;
};
diff --git a/include/linux/poison.h b/include/linux/poison.h
index 6729f7dcd60e..229322707f5f 100644
--- a/include/linux/poison.h
+++ b/include/linux/poison.h
@@ -2,13 +2,25 @@
#define _LINUX_POISON_H
/********** include/linux/list.h **********/
+
+/*
+ * Architectures might want to move the poison pointer offset
+ * into some well-recognized area such as 0xdead000000000000,
+ * that is also not mappable by user-space exploits:
+ */
+#ifdef CONFIG_ILLEGAL_POINTER_VALUE
+# define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL)
+#else
+# define POISON_POINTER_DELTA 0
+#endif
+
/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized list entries.
*/
-#define LIST_POISON1 ((void *) 0x00100100)
-#define LIST_POISON2 ((void *) 0x00200200)
+#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA)
+#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA)
/********** include/linux/timer.h **********/
/*
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index fbfa3d44d33d..e6e77d31c418 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -93,20 +93,9 @@ struct vmcore {
#ifdef CONFIG_PROC_FS
-extern spinlock_t proc_subdir_lock;
-
extern void proc_root_init(void);
void proc_flush_task(struct task_struct *task);
-struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *);
-int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir);
-unsigned long task_vsize(struct mm_struct *);
-int task_statm(struct mm_struct *, int *, int *, int *, int *);
-void task_mem(struct seq_file *, struct mm_struct *);
-void clear_refs_smap(struct mm_struct *mm);
-
-struct proc_dir_entry *de_get(struct proc_dir_entry *de);
-void de_put(struct proc_dir_entry *de);
extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
struct proc_dir_entry *parent);
@@ -116,20 +105,7 @@ struct proc_dir_entry *proc_create_data(const char *name, mode_t mode,
void *data);
extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
-extern struct vfsmount *proc_mnt;
struct pid_namespace;
-extern int proc_fill_super(struct super_block *);
-extern struct inode *proc_get_inode(struct super_block *, unsigned int, struct proc_dir_entry *);
-
-/*
- * These are generic /proc routines that use the internal
- * "struct proc_dir_entry" tree to traverse the filesystem.
- *
- * The /proc root directory has extended versions to take care
- * of the /proc/<pid> subdirectories.
- */
-extern int proc_readdir(struct file *, void *, filldir_t);
-extern struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *);
extern int pid_ns_prepare_proc(struct pid_namespace *ns);
extern void pid_ns_release_proc(struct pid_namespace *ns);
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 67c15653fc23..59e133d39d50 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -95,7 +95,6 @@ extern void __ptrace_link(struct task_struct *child,
struct task_struct *new_parent);
extern void __ptrace_unlink(struct task_struct *child);
extern void exit_ptrace(struct task_struct *tracer);
-extern void ptrace_fork(struct task_struct *task, unsigned long clone_flags);
#define PTRACE_MODE_READ 1
#define PTRACE_MODE_ATTACH 2
/* Returns 0 on success, -errno on denial. */
@@ -327,15 +326,6 @@ static inline void user_enable_block_step(struct task_struct *task)
#define arch_ptrace_untrace(task) do { } while (0)
#endif
-#ifndef arch_ptrace_fork
-/*
- * Do machine-specific work to initialize a new task.
- *
- * This is called from copy_process().
- */
-#define arch_ptrace_fork(child, clone_flags) do { } while (0)
-#endif
-
extern int task_current_syscall(struct task_struct *target, long *callno,
unsigned long args[6], unsigned int maxargs,
unsigned long *sp, unsigned long *pc);
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 36353d95c8db..7bc457593684 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -20,7 +20,12 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb)
/*
* declaration of quota_function calls in kernel.
*/
-void sync_dquots(struct super_block *sb, int type);
+void sync_quota_sb(struct super_block *sb, int type);
+static inline void writeout_quota_sb(struct super_block *sb, int type)
+{
+ if (sb->s_qcop->quota_sync)
+ sb->s_qcop->quota_sync(sb, type);
+}
int dquot_initialize(struct inode *inode, int type);
int dquot_drop(struct inode *inode);
@@ -253,12 +258,7 @@ static inline void vfs_dq_free_inode(struct inode *inode)
inode->i_sb->dq_op->free_inode(inode, 1);
}
-/* The following two functions cannot be called inside a transaction */
-static inline void vfs_dq_sync(struct super_block *sb)
-{
- sync_dquots(sb, -1);
-}
-
+/* Cannot be called inside a transaction */
static inline int vfs_dq_off(struct super_block *sb, int remount)
{
int ret = -ENOSYS;
@@ -334,7 +334,11 @@ static inline void vfs_dq_free_inode(struct inode *inode)
{
}
-static inline void vfs_dq_sync(struct super_block *sb)
+static inline void sync_quota_sb(struct super_block *sb, int type)
+{
+}
+
+static inline void writeout_quota_sb(struct super_block *sb, int type)
{
}
diff --git a/include/linux/rcu_types.h b/include/linux/rcu_types.h
new file mode 100644
index 000000000000..fd3570d0e6c1
--- /dev/null
+++ b/include/linux/rcu_types.h
@@ -0,0 +1,18 @@
+#ifndef __LINUX_RCU_TYPES_H
+#define __LINUX_RCU_TYPES_H
+
+#ifdef __KERNEL__
+
+/**
+ * struct rcu_head - callback structure for use with RCU
+ * @next: next update requests in a list
+ * @func: actual update function to call after the grace period.
+ */
+struct rcu_head {
+ struct rcu_head *next;
+ void (*func)(struct rcu_head *head);
+};
+
+#endif
+
+#endif
diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index e649bd3f2c97..5710f43bbc9e 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -198,6 +198,32 @@ static inline void list_splice_init_rcu(struct list_head *list,
at->prev = last;
}
+/**
+ * list_entry_rcu - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ *
+ * This primitive may safely run concurrently with the _rcu list-mutation
+ * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
+ */
+#define list_entry_rcu(ptr, type, member) \
+ container_of(rcu_dereference(ptr), type, member)
+
+/**
+ * list_first_entry_rcu - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ *
+ * This primitive may safely run concurrently with the _rcu list-mutation
+ * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
+ */
+#define list_first_entry_rcu(ptr, type, member) \
+ list_entry_rcu((ptr)->next, type, member)
+
#define __list_for_each_rcu(pos, head) \
for (pos = rcu_dereference((head)->next); \
pos != (head); \
@@ -214,9 +240,9 @@ static inline void list_splice_init_rcu(struct list_head *list,
* as long as the traversal is guarded by rcu_read_lock().
*/
#define list_for_each_entry_rcu(pos, head, member) \
- for (pos = list_entry(rcu_dereference((head)->next), typeof(*pos), member); \
+ for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
- pos = list_entry(rcu_dereference(pos->member.next), typeof(*pos), member))
+ pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
/**
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 15fbb3ca634d..19b82b96affa 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -33,6 +33,7 @@
#ifndef __LINUX_RCUPDATE_H
#define __LINUX_RCUPDATE_H
+#include <linux/rcu_types.h>
#include <linux/cache.h>
#include <linux/spinlock.h>
#include <linux/threads.h>
@@ -41,16 +42,6 @@
#include <linux/lockdep.h>
#include <linux/completion.h>
-/**
- * struct rcu_head - callback structure for use with RCU
- * @next: next update requests in a list
- * @func: actual update function to call after the grace period.
- */
-struct rcu_head {
- struct rcu_head *next;
- void (*func)(struct rcu_head *head);
-};
-
/* Internal to kernel, but needed by rcupreempt.h. */
extern int rcu_scheduler_active;
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index 58b2aa5312b9..5a5153806c42 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -161,8 +161,15 @@ struct rcu_data {
unsigned long offline_fqs; /* Kicked due to being offline. */
unsigned long resched_ipi; /* Sent a resched IPI. */
- /* 5) For future __rcu_pending statistics. */
+ /* 5) __rcu_pending() statistics. */
long n_rcu_pending; /* rcu_pending() calls since boot. */
+ long n_rp_qs_pending;
+ long n_rp_cb_ready;
+ long n_rp_cpu_needs_gp;
+ long n_rp_gp_completed;
+ long n_rp_gp_started;
+ long n_rp_need_fqs;
+ long n_rp_need_nothing;
int cpu;
};
diff --git a/include/linux/regulator/max1586.h b/include/linux/regulator/max1586.h
new file mode 100644
index 000000000000..2056973396b6
--- /dev/null
+++ b/include/linux/regulator/max1586.h
@@ -0,0 +1,52 @@
+/*
+ * max1586.h -- Voltage regulation for the Maxim 1586
+ *
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * 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
+ */
+
+#ifndef REGULATOR_MAX1586
+#define REGULATOR_MAX1586
+
+#include <linux/regulator/machine.h>
+
+#define MAX1586_V3 0
+#define MAX1586_V6 1
+
+/**
+ * max1586_subdev_data - regulator data
+ * @id: regulator Id (either MAX1586_V3 or MAX1586_V6)
+ * @name: regulator cute name (example for V3: "vcc_core")
+ * @platform_data: regulator init data (contraints, supplies, ...)
+ */
+struct max1586_subdev_data {
+ int id;
+ char *name;
+ struct regulator_init_data *platform_data;
+};
+
+/**
+ * max1586_platform_data - platform data for max1586
+ * @num_subdevs: number of regultors used (may be 1 or 2)
+ * @subdevs: regulator used
+ * At most, there will be a regulator for V3 and one for V6 voltages.
+ */
+struct max1586_platform_data {
+ int num_subdevs;
+ struct max1586_subdev_data *subdevs;
+};
+
+#endif
diff --git a/include/linux/regulator/userspace-consumer.h b/include/linux/regulator/userspace-consumer.h
new file mode 100644
index 000000000000..b4554ce9d4bb
--- /dev/null
+++ b/include/linux/regulator/userspace-consumer.h
@@ -0,0 +1,25 @@
+#ifndef __REGULATOR_PLATFORM_CONSUMER_H_
+#define __REGULATOR_PLATFORM_CONSUMER_H_
+
+struct regulator_consumer_supply;
+
+/**
+ * struct regulator_userspace_consumer_data - line consumer
+ * initialisation data.
+ *
+ * @name: Name for the consumer line
+ * @num_supplies: Number of supplies feeding the line
+ * @supplies: Supplies configuration.
+ * @init_on: Set if the regulators supplying the line should be
+ * enabled during initialisation
+ */
+struct regulator_userspace_consumer_data {
+ const char *name;
+
+ int num_supplies;
+ struct regulator_bulk_data *supplies;
+
+ bool init_on;
+};
+
+#endif /* __REGULATOR_PLATFORM_CONSUMER_H_ */
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index 6b361d23a499..dab68bbed675 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -402,7 +402,7 @@ struct reiserfs_sb_info {
int reserved_blocks; /* amount of blocks reserved for further allocations */
spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */
struct dentry *priv_root; /* root of /.reiserfs_priv */
- struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
+ struct dentry *xattr_root; /* root of /.reiserfs_priv/xattrs */
int j_errno;
#ifdef CONFIG_QUOTA
char *s_qf_names[MAXQUOTAS];
@@ -453,6 +453,7 @@ enum reiserfs_mount_options {
REISERFS_ATTRS,
REISERFS_XATTRS_USER,
REISERFS_POSIXACL,
+ REISERFS_EXPOSE_PRIVROOT,
REISERFS_BARRIER_NONE,
REISERFS_BARRIER_FLUSH,
@@ -488,9 +489,9 @@ enum reiserfs_mount_options {
#define reiserfs_data_log(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_LOG))
#define reiserfs_data_ordered(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_ORDERED))
#define reiserfs_data_writeback(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_WRITEBACK))
-#define reiserfs_xattrs(s) ((s)->s_xattr != NULL)
#define reiserfs_xattrs_user(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_XATTRS_USER))
#define reiserfs_posixacl(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_POSIXACL))
+#define reiserfs_expose_privroot(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_EXPOSE_PRIVROOT))
#define reiserfs_xattrs_optional(s) (reiserfs_xattrs_user(s) || reiserfs_posixacl(s))
#define reiserfs_barrier_none(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_BARRIER_NONE))
#define reiserfs_barrier_flush(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_BARRIER_FLUSH))
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h
index dcae01e63e40..99928dce37ea 100644
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -38,8 +38,10 @@ struct nameidata;
int reiserfs_xattr_register_handlers(void) __init;
void reiserfs_xattr_unregister_handlers(void);
int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
+int reiserfs_lookup_privroot(struct super_block *sb);
int reiserfs_delete_xattrs(struct inode *inode);
int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs);
+int reiserfs_permission(struct inode *inode, int mask);
#ifdef CONFIG_REISERFS_FS_XATTR
#define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir)
@@ -49,7 +51,6 @@ int reiserfs_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags);
ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
int reiserfs_removexattr(struct dentry *dentry, const char *name);
-int reiserfs_permission(struct inode *inode, int mask);
int reiserfs_xattr_get(struct inode *, const char *, void *, size_t);
int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int);
@@ -97,7 +98,7 @@ static inline size_t reiserfs_xattr_jcreate_nblocks(struct inode *inode)
if ((REISERFS_I(inode)->i_flags & i_has_xattr_dir) == 0) {
nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
- if (REISERFS_SB(inode->i_sb)->xattr_root == NULL)
+ if (!REISERFS_SB(inode->i_sb)->xattr_root->d_inode)
nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
}
@@ -116,8 +117,6 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
#define reiserfs_listxattr NULL
#define reiserfs_removexattr NULL
-#define reiserfs_permission NULL
-
static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
{
}
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 164332cbb77c..e1ec7d9aa49c 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -52,14 +52,6 @@ enum rfkill_state {
RFKILL_STATE_MAX, /* marker for last valid state */
};
-/*
- * These are DEPRECATED, drivers using them should be verified to
- * comply with the rfkill usage guidelines in Documentation/rfkill.txt
- * and then converted to use the new names for rfkill_state
- */
-#define RFKILL_STATE_OFF RFKILL_STATE_SOFT_BLOCKED
-#define RFKILL_STATE_ON RFKILL_STATE_UNBLOCKED
-
/**
* struct rfkill - rfkill control structure.
* @name: Name of the switch.
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index e1b7b2173885..f1345828c7c5 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -11,7 +11,7 @@ struct ring_buffer_iter;
* Don't refer to this struct directly, use functions below.
*/
struct ring_buffer_event {
- u32 type:2, len:3, time_delta:27;
+ u32 type_len:5, time_delta:27;
u32 array[];
};
@@ -24,7 +24,8 @@ struct ring_buffer_event {
* size is variable depending on how much
* padding is needed
* If time_delta is non zero:
- * everything else same as RINGBUF_TYPE_DATA
+ * array[0] holds the actual length
+ * size = 4 + length (bytes)
*
* @RINGBUF_TYPE_TIME_EXTEND: Extend the time delta
* array[0] = time delta (28 .. 59)
@@ -35,22 +36,23 @@ struct ring_buffer_event {
* array[1..2] = tv_sec
* size = 16 bytes
*
- * @RINGBUF_TYPE_DATA: Data record
- * If len is zero:
+ * <= @RINGBUF_TYPE_DATA_TYPE_LEN_MAX:
+ * Data record
+ * If type_len is zero:
* array[0] holds the actual length
* array[1..(length+3)/4] holds data
- * size = 4 + 4 + length (bytes)
+ * size = 4 + length (bytes)
* else
- * length = len << 2
+ * length = type_len << 2
* array[0..(length+3)/4-1] holds data
* size = 4 + length (bytes)
*/
enum ring_buffer_type {
+ RINGBUF_TYPE_DATA_TYPE_LEN_MAX = 28,
RINGBUF_TYPE_PADDING,
RINGBUF_TYPE_TIME_EXTEND,
/* FIXME: RINGBUF_TYPE_TIME_STAMP not implemented */
RINGBUF_TYPE_TIME_STAMP,
- RINGBUF_TYPE_DATA,
};
unsigned ring_buffer_event_length(struct ring_buffer_event *event);
@@ -68,9 +70,38 @@ ring_buffer_event_time_delta(struct ring_buffer_event *event)
return event->time_delta;
}
+/*
+ * ring_buffer_event_discard can discard any event in the ring buffer.
+ * it is up to the caller to protect against a reader from
+ * consuming it or a writer from wrapping and replacing it.
+ *
+ * No external protection is needed if this is called before
+ * the event is commited. But in that case it would be better to
+ * use ring_buffer_discard_commit.
+ *
+ * Note, if an event that has not been committed is discarded
+ * with ring_buffer_event_discard, it must still be committed.
+ */
void ring_buffer_event_discard(struct ring_buffer_event *event);
/*
+ * ring_buffer_discard_commit will remove an event that has not
+ * ben committed yet. If this is used, then ring_buffer_unlock_commit
+ * must not be called on the discarded event. This function
+ * will try to remove the event from the ring buffer completely
+ * if another event has not been written after it.
+ *
+ * Example use:
+ *
+ * if (some_condition)
+ * ring_buffer_discard_commit(buffer, event);
+ * else
+ * ring_buffer_unlock_commit(buffer, event);
+ */
+void ring_buffer_discard_commit(struct ring_buffer *buffer,
+ struct ring_buffer_event *event);
+
+/*
* size is in bytes for each per CPU buffer.
*/
struct ring_buffer *
@@ -122,6 +153,8 @@ unsigned long ring_buffer_entries(struct ring_buffer *buffer);
unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu);
unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu);
+unsigned long ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu);
+unsigned long ring_buffer_nmi_dropped_cpu(struct ring_buffer *buffer, int cpu);
u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu);
void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
@@ -137,6 +170,11 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data);
int ring_buffer_read_page(struct ring_buffer *buffer, void **data_page,
size_t len, int cpu, int full);
+struct trace_seq;
+
+int ring_buffer_print_entry_header(struct trace_seq *s);
+int ring_buffer_print_page_header(struct trace_seq *s);
+
enum ring_buffer_flags {
RB_FL_OVERWRITE = 1 << 0,
};
diff --git a/include/linux/romfs_fs.h b/include/linux/romfs_fs.h
index e20bbf9eb365..c490fbc43fe2 100644
--- a/include/linux/romfs_fs.h
+++ b/include/linux/romfs_fs.h
@@ -53,9 +53,4 @@ struct romfs_inode {
#define ROMFH_PAD (ROMFH_SIZE-1)
#define ROMFH_MASK (~ROMFH_PAD)
-#ifdef __KERNEL__
-
-/* Not much now */
-
-#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/rotary_encoder.h b/include/linux/rotary_encoder.h
index 12d63a30c347..215278b8df2a 100644
--- a/include/linux/rotary_encoder.h
+++ b/include/linux/rotary_encoder.h
@@ -8,6 +8,8 @@ struct rotary_encoder_platform_data {
unsigned int gpio_b;
unsigned int inverted_a;
unsigned int inverted_b;
+ bool relative_axis;
+ bool rollover;
};
#endif /* __ROTARY_ENCODER_H__ */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index b4c38bc8049c..efd2470c0915 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -77,6 +77,7 @@ struct sched_param {
#include <linux/proportions.h>
#include <linux/seccomp.h>
#include <linux/rcupdate.h>
+#include <linux/rculist.h>
#include <linux/rtmutex.h>
#include <linux/time.h>
@@ -96,8 +97,8 @@ struct exec_domain;
struct futex_pi_state;
struct robust_list_head;
struct bio;
-struct bts_tracer;
struct fs_struct;
+struct bts_context;
/*
* List of flags we want to share for kernel threads,
@@ -1209,18 +1210,11 @@ struct task_struct {
struct list_head ptraced;
struct list_head ptrace_entry;
-#ifdef CONFIG_X86_PTRACE_BTS
/*
* This is the tracer handle for the ptrace BTS extension.
* This field actually belongs to the ptracer task.
*/
- struct bts_tracer *bts;
- /*
- * The buffer to hold the BTS data.
- */
- void *bts_buffer;
- size_t bts_size;
-#endif /* CONFIG_X86_PTRACE_BTS */
+ struct bts_context *bts;
/* PID/PID hash table linkage. */
struct pid_link pids[PIDTYPE_MAX];
@@ -1247,7 +1241,9 @@ struct task_struct {
* credentials (COW) */
const struct cred *cred; /* effective (overridable) subjective task
* credentials (COW) */
- struct mutex cred_exec_mutex; /* execve vs ptrace cred calculation mutex */
+ struct mutex cred_guard_mutex; /* guard against foreign influences on
+ * credential calculations
+ * (notably. ptrace) */
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
@@ -1428,7 +1424,9 @@ struct task_struct {
#ifdef CONFIG_TRACING
/* state flags for use by tracers */
unsigned long trace;
-#endif
+ /* bitmask of trace recursion */
+ unsigned long trace_recursion;
+#endif /* CONFIG_TRACING */
};
/* Future-safe accessor for struct task_struct's cpus_allowed. */
@@ -1885,6 +1883,7 @@ extern void sched_dead(struct task_struct *p);
extern void proc_caches_init(void);
extern void flush_signals(struct task_struct *);
+extern void __flush_signals(struct task_struct *);
extern void ignore_signals(struct task_struct *);
extern void flush_signal_handlers(struct task_struct *, int force_default);
extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info);
@@ -2001,8 +2000,10 @@ extern void set_task_comm(struct task_struct *tsk, char *from);
extern char *get_task_comm(char *to, struct task_struct *tsk);
#ifdef CONFIG_SMP
+extern void wait_task_context_switch(struct task_struct *p);
extern unsigned long wait_task_inactive(struct task_struct *, long match_state);
#else
+static inline void wait_task_context_switch(struct task_struct *p) {}
static inline unsigned long wait_task_inactive(struct task_struct *p,
long match_state)
{
@@ -2010,7 +2011,8 @@ static inline unsigned long wait_task_inactive(struct task_struct *p,
}
#endif
-#define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks)
+#define next_task(p) \
+ list_entry_rcu((p)->tasks.next, struct task_struct, tasks)
#define for_each_process(p) \
for (p = &init_task ; (p = next_task(p)) != &init_task ; )
@@ -2049,8 +2051,8 @@ int same_thread_group(struct task_struct *p1, struct task_struct *p2)
static inline struct task_struct *next_thread(const struct task_struct *p)
{
- return list_entry(rcu_dereference(p->thread_group.next),
- struct task_struct, thread_group);
+ return list_entry_rcu(p->thread_group.next,
+ struct task_struct, thread_group);
}
static inline int thread_group_empty(struct task_struct *p)
diff --git a/include/linux/serial.h b/include/linux/serial.h
index 9136cc5608c3..e5bb75a63802 100644
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -96,54 +96,76 @@ struct serial_uart_config {
/*
* Definitions for async_struct (and serial_struct) flags field
+ *
+ * Define ASYNCB_* for convenient use with {test,set,clear}_bit.
*/
-#define ASYNC_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes
- on the callout port */
-#define ASYNC_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */
-#define ASYNC_SAK 0x0004 /* Secure Attention Key (Orange book) */
-#define ASYNC_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
-
-#define ASYNC_SPD_MASK 0x1030
-#define ASYNC_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */
-
-#define ASYNC_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */
-#define ASYNC_SPD_CUST 0x0030 /* Use user-specified divisor */
-
-#define ASYNC_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */
-#define ASYNC_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */
-#define ASYNC_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
-#define ASYNC_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */
-#define ASYNC_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */
-
-#define ASYNC_HARDPPS_CD 0x0800 /* Call hardpps when CD goes high */
-
-#define ASYNC_SPD_SHI 0x1000 /* Use 230400 instead of 38400 bps */
-#define ASYNC_SPD_WARP 0x1010 /* Use 460800 instead of 38400 bps */
-
-#define ASYNC_LOW_LATENCY 0x2000 /* Request low latency behaviour */
-
-#define ASYNC_BUGGY_UART 0x4000 /* This is a buggy UART, skip some safety
- * checks. Note: can be dangerous! */
-
-#define ASYNC_AUTOPROBE 0x8000 /* Port was autoprobed by PCI or PNP code */
-
-#define ASYNC_FLAGS 0x7FFF /* Possible legal async flags */
-#define ASYNC_USR_MASK 0x3430 /* Legal flags that non-privileged
- * users can set or reset */
-
-/* Internal flags used only by kernel/chr_drv/serial.c */
-#define ASYNC_INITIALIZED 0x80000000 /* Serial port was initialized */
-#define ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device is active */
-#define ASYNC_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */
-#define ASYNC_CLOSING 0x08000000 /* Serial port is closing */
-#define ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */
-#define ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */
-#define ASYNC_SHARE_IRQ 0x01000000 /* for multifunction cards
- --- no longer used */
-#define ASYNC_CONS_FLOW 0x00800000 /* flow control for console */
-
-#define ASYNC_BOOT_ONLYMCA 0x00400000 /* Probe only if MCA bus */
-#define ASYNC_INTERNAL_FLAGS 0xFFC00000 /* Internal flags */
+#define ASYNCB_HUP_NOTIFY 0 /* Notify getty on hangups and closes
+ * on the callout port */
+#define ASYNCB_FOURPORT 1 /* Set OU1, OUT2 per AST Fourport settings */
+#define ASYNCB_SAK 2 /* Secure Attention Key (Orange book) */
+#define ASYNCB_SPLIT_TERMIOS 3 /* Separate termios for dialin/callout */
+#define ASYNCB_SPD_HI 4 /* Use 56000 instead of 38400 bps */
+#define ASYNCB_SPD_VHI 5 /* Use 115200 instead of 38400 bps */
+#define ASYNCB_SKIP_TEST 6 /* Skip UART test during autoconfiguration */
+#define ASYNCB_AUTO_IRQ 7 /* Do automatic IRQ during
+ * autoconfiguration */
+#define ASYNCB_SESSION_LOCKOUT 8 /* Lock out cua opens based on session */
+#define ASYNCB_PGRP_LOCKOUT 9 /* Lock out cua opens based on pgrp */
+#define ASYNCB_CALLOUT_NOHUP 10 /* Don't do hangups for cua device */
+#define ASYNCB_HARDPPS_CD 11 /* Call hardpps when CD goes high */
+#define ASYNCB_SPD_SHI 12 /* Use 230400 instead of 38400 bps */
+#define ASYNCB_LOW_LATENCY 13 /* Request low latency behaviour */
+#define ASYNCB_BUGGY_UART 14 /* This is a buggy UART, skip some safety
+ * checks. Note: can be dangerous! */
+#define ASYNCB_AUTOPROBE 15 /* Port was autoprobed by PCI or PNP code */
+#define ASYNCB_LAST_USER 15
+
+/* Internal flags used only by kernel */
+#define ASYNCB_INITIALIZED 31 /* Serial port was initialized */
+#define ASYNCB_NORMAL_ACTIVE 29 /* Normal device is active */
+#define ASYNCB_BOOT_AUTOCONF 28 /* Autoconfigure port on bootup */
+#define ASYNCB_CLOSING 27 /* Serial port is closing */
+#define ASYNCB_CTS_FLOW 26 /* Do CTS flow control */
+#define ASYNCB_CHECK_CD 25 /* i.e., CLOCAL */
+#define ASYNCB_SHARE_IRQ 24 /* for multifunction cards, no longer used */
+#define ASYNCB_CONS_FLOW 23 /* flow control for console */
+#define ASYNCB_BOOT_ONLYMCA 22 /* Probe only if MCA bus */
+#define ASYNCB_FIRST_KERNEL 22
+
+#define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY)
+#define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT)
+#define ASYNC_SAK (1U << ASYNCB_SAK)
+#define ASYNC_SPLIT_TERMIOS (1U << ASYNCB_SPLIT_TERMIOS)
+#define ASYNC_SPD_HI (1U << ASYNCB_SPD_HI)
+#define ASYNC_SPD_VHI (1U << ASYNCB_SPD_VHI)
+#define ASYNC_SKIP_TEST (1U << ASYNCB_SKIP_TEST)
+#define ASYNC_AUTO_IRQ (1U << ASYNCB_AUTO_IRQ)
+#define ASYNC_SESSION_LOCKOUT (1U << ASYNCB_SESSION_LOCKOUT)
+#define ASYNC_PGRP_LOCKOUT (1U << ASYNCB_PGRP_LOCKOUT)
+#define ASYNC_CALLOUT_NOHUP (1U << ASYNCB_CALLOUT_NOHUP)
+#define ASYNC_HARDPPS_CD (1U << ASYNCB_HARDPPS_CD)
+#define ASYNC_SPD_SHI (1U << ASYNCB_SPD_SHI)
+#define ASYNC_LOW_LATENCY (1U << ASYNCB_LOW_LATENCY)
+#define ASYNC_BUGGY_UART (1U << ASYNCB_BUGGY_UART)
+#define ASYNC_AUTOPROBE (1U << ASYNCB_AUTOPROBE)
+
+#define ASYNC_FLAGS ((1U << ASYNCB_LAST_USER) - 1)
+#define ASYNC_USR_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI| \
+ ASYNC_CALLOUT_NOHUP|ASYNC_SPD_SHI|ASYNC_LOW_LATENCY)
+#define ASYNC_SPD_CUST (ASYNC_SPD_HI|ASYNC_SPD_VHI)
+#define ASYNC_SPD_WARP (ASYNC_SPD_HI|ASYNC_SPD_SHI)
+#define ASYNC_SPD_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI|ASYNC_SPD_SHI)
+
+#define ASYNC_INITIALIZED (1U << ASYNCB_INITIALIZED)
+#define ASYNC_NORMAL_ACTIVE (1U << ASYNCB_NORMAL_ACTIVE)
+#define ASYNC_BOOT_AUTOCONF (1U << ASYNCB_BOOT_AUTOCONF)
+#define ASYNC_CLOSING (1U << ASYNCB_CLOSING)
+#define ASYNC_CTS_FLOW (1U << ASYNCB_CTS_FLOW)
+#define ASYNC_CHECK_CD (1U << ASYNCB_CHECK_CD)
+#define ASYNC_SHARE_IRQ (1U << ASYNCB_SHARE_IRQ)
+#define ASYNC_CONS_FLOW (1U << ASYNCB_CONS_FLOW)
+#define ASYNC_BOOT_ONLYMCA (1U << ASYNCB_BOOT_ONLYMCA)
+#define ASYNC_INTERNAL_FLAGS (~((1U << ASYNCB_FIRST_KERNEL) - 1))
/*
* Multiport serial configuration structure --- external structure
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index 893cc53486bc..1c297ddc9d5a 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -25,8 +25,7 @@ struct plat_sci_port {
unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */
unsigned int type; /* SCI / SCIF / IRDA */
upf_t flags; /* UPF_* flags */
+ char *clk; /* clock string */
};
-int early_sci_setup(struct uart_port *port);
-
#endif /* __LINUX_SERIAL_SCI_H */
diff --git a/include/linux/serio.h b/include/linux/serio.h
index e0417e4d3f15..126d24c9eaa8 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -15,6 +15,7 @@
#ifdef __KERNEL__
+#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/spinlock.h>
@@ -28,7 +29,10 @@ struct serio {
char name[32];
char phys[32];
- unsigned int manual_bind;
+ bool manual_bind;
+ bool registered; /* port has been fully registered with driver core */
+ bool suspended; /* port is suspended */
+
struct serio_device_id id;
@@ -47,7 +51,6 @@ struct serio {
struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */
struct device dev;
- unsigned int registered; /* port has been fully registered with driver core */
struct list_head node;
};
@@ -58,7 +61,7 @@ struct serio_driver {
char *description;
struct serio_device_id *id_table;
- unsigned int manual_bind;
+ bool manual_bind;
void (*write_wakeup)(struct serio *);
irqreturn_t (*interrupt)(struct serio *, unsigned char, unsigned int);
diff --git a/include/linux/sh_cmt.h b/include/linux/sh_cmt.h
deleted file mode 100644
index 68cacde5954f..000000000000
--- a/include/linux/sh_cmt.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __SH_CMT_H__
-#define __SH_CMT_H__
-
-struct sh_cmt_config {
- char *name;
- unsigned long channel_offset;
- int timer_bit;
- char *clk;
- unsigned long clockevent_rating;
- unsigned long clocksource_rating;
-};
-
-#endif /* __SH_CMT_H__ */
diff --git a/include/linux/sh_timer.h b/include/linux/sh_timer.h
new file mode 100644
index 000000000000..864bd56bd3b0
--- /dev/null
+++ b/include/linux/sh_timer.h
@@ -0,0 +1,13 @@
+#ifndef __SH_TIMER_H__
+#define __SH_TIMER_H__
+
+struct sh_timer_config {
+ char *name;
+ long channel_offset;
+ int timer_bit;
+ char *clk;
+ unsigned long clockevent_rating;
+ unsigned long clocksource_rating;
+};
+
+#endif /* __SH_TIMER_H__ */
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 84f997f8aa53..c7552836bd95 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -235,6 +235,8 @@ static inline int valid_signal(unsigned long sig)
extern int next_signal(struct sigpending *pending, sigset_t *mask);
extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
+extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig,
+ siginfo_t *info);
extern long do_sigpending(void __user *, unsigned long);
extern int sigprocmask(int, sigset_t *, sigset_t *);
extern int show_unhandled_signals;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 5fd389162f01..1b5c3d298f43 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1715,8 +1715,14 @@ extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
struct iovec *iov);
extern int skb_copy_datagram_from_iovec(struct sk_buff *skb,
int offset,
- struct iovec *from,
+ const struct iovec *from,
+ int from_offset,
int len);
+extern int skb_copy_datagram_const_iovec(const struct sk_buff *from,
+ int offset,
+ const struct iovec *to,
+ int to_offset,
+ int size);
extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb);
extern int skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
unsigned int flags);
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 24c5602bee99..6daa700e8235 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -65,6 +65,10 @@
/* 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 */
+
+/* Following flags should only be used by allocator specific flags */
+#define SLAB_ALLOC_PRIVATE 0x000000ffUL
+
/*
* ZERO_SIZE_PTR will be returned for zero sized kmalloc requests.
*
@@ -151,6 +155,8 @@ size_t ksize(const void *);
*/
#ifdef CONFIG_SLUB
#include <linux/slub_def.h>
+#elif defined(CONFIG_SLQB)
+#include <linux/slqb_def.h>
#elif defined(CONFIG_SLOB)
#include <linux/slob_def.h>
#else
@@ -253,7 +259,7 @@ static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
* allocator where we care about the real place the memory allocation
* request comes from.
*/
-#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB)
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) || defined(CONFIG_SLQB_DEBUG)
extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long);
#define kmalloc_track_caller(size, flags) \
__kmalloc_track_caller(size, flags, _RET_IP_)
@@ -271,7 +277,7 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long);
* standard allocator where we care about the real place the memory
* allocation request comes from.
*/
-#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB)
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) || defined(CONFIG_SLQB_DEBUG)
extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, unsigned long);
#define kmalloc_node_track_caller(size, flags, node) \
__kmalloc_node_track_caller(size, flags, node, \
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 5ac9b0bcaf9a..713f841ecaa9 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -14,7 +14,7 @@
#include <asm/page.h> /* kmalloc_sizes.h needs PAGE_SIZE */
#include <asm/cache.h> /* kmalloc_sizes.h needs L1_CACHE_BYTES */
#include <linux/compiler.h>
-#include <trace/kmemtrace.h>
+#include <linux/kmemtrace.h>
/* Size description struct for general caches. */
struct cache_sizes {
diff --git a/include/linux/slqb_def.h b/include/linux/slqb_def.h
new file mode 100644
index 000000000000..7b4a601fd87e
--- /dev/null
+++ b/include/linux/slqb_def.h
@@ -0,0 +1,298 @@
+#ifndef _LINUX_SLQB_DEF_H
+#define _LINUX_SLQB_DEF_H
+
+/*
+ * SLQB : A slab allocator with object queues.
+ *
+ * (C) 2008 Nick Piggin <npiggin@suse.de>
+ */
+#include <linux/types.h>
+#include <linux/gfp.h>
+#include <linux/workqueue.h>
+#include <linux/kobject.h>
+#include <linux/rcu_types.h>
+#include <linux/mm_types.h>
+#include <linux/kernel.h>
+#include <linux/kobject.h>
+
+#define SLAB_NUMA 0x00000001UL /* shortcut */
+
+enum stat_item {
+ ALLOC, /* Allocation count */
+ ALLOC_SLAB_FILL, /* Fill freelist from page list */
+ ALLOC_SLAB_NEW, /* New slab acquired from page allocator */
+ FREE, /* Free count */
+ FREE_REMOTE, /* NUMA: freeing to remote list */
+ FLUSH_FREE_LIST, /* Freelist flushed */
+ FLUSH_FREE_LIST_OBJECTS, /* Objects flushed from freelist */
+ FLUSH_FREE_LIST_REMOTE, /* Objects flushed from freelist to remote */
+ FLUSH_SLAB_PARTIAL, /* Freeing moves slab to partial list */
+ FLUSH_SLAB_FREE, /* Slab freed to the page allocator */
+ FLUSH_RFREE_LIST, /* Rfree list flushed */
+ FLUSH_RFREE_LIST_OBJECTS, /* Rfree objects flushed */
+ CLAIM_REMOTE_LIST, /* Remote freed list claimed */
+ CLAIM_REMOTE_LIST_OBJECTS, /* Remote freed objects claimed */
+ NR_SLQB_STAT_ITEMS
+};
+
+/*
+ * Singly-linked list with head, tail, and nr
+ */
+struct kmlist {
+ unsigned long nr;
+ void **head;
+ void **tail;
+};
+
+/*
+ * Every kmem_cache_list has a kmem_cache_remote_free structure, by which
+ * objects can be returned to the kmem_cache_list from remote CPUs.
+ */
+struct kmem_cache_remote_free {
+ spinlock_t lock;
+ struct kmlist list;
+} ____cacheline_aligned;
+
+/*
+ * A kmem_cache_list manages all the slabs and objects allocated from a given
+ * source. Per-cpu kmem_cache_lists allow node-local allocations. Per-node
+ * kmem_cache_lists allow off-node allocations (but require locking).
+ */
+struct kmem_cache_list {
+ /* Fastpath LIFO freelist of objects */
+ struct kmlist freelist;
+#ifdef CONFIG_SMP
+ /* remote_free has reached a watermark */
+ int remote_free_check;
+#endif
+ /* kmem_cache corresponding to this list */
+ struct kmem_cache *cache;
+
+ /* Number of partial slabs (pages) */
+ unsigned long nr_partial;
+
+ /* Slabs which have some free objects */
+ struct list_head partial;
+
+ /* Total number of slabs allocated */
+ unsigned long nr_slabs;
+
+ /* Protects nr_partial, nr_slabs, and partial */
+ spinlock_t page_lock;
+
+#ifdef CONFIG_SMP
+ /*
+ * In the case of per-cpu lists, remote_free is for objects freed by
+ * non-owner CPU back to its home list. For per-node lists, remote_free
+ * is always used to free objects.
+ */
+ struct kmem_cache_remote_free remote_free;
+#endif
+
+#ifdef CONFIG_SLQB_STATS
+ unsigned long stats[NR_SLQB_STAT_ITEMS];
+#endif
+} ____cacheline_aligned;
+
+/*
+ * Primary per-cpu, per-kmem_cache structure.
+ */
+struct kmem_cache_cpu {
+ struct kmem_cache_list list; /* List for node-local slabs */
+ unsigned int colour_next; /* Next colour offset to use */
+
+#ifdef CONFIG_SMP
+ /*
+ * rlist is a list of objects that don't fit on list.freelist (ie.
+ * wrong node). The objects all correspond to a given kmem_cache_list,
+ * remote_cache_list. To free objects to another list, we must first
+ * flush the existing objects, then switch remote_cache_list.
+ *
+ * An NR_CPUS or MAX_NUMNODES array would be nice here, but then we
+ * get to O(NR_CPUS^2) memory consumption situation.
+ */
+ struct kmlist rlist;
+ struct kmem_cache_list *remote_cache_list;
+#endif
+} ____cacheline_aligned_in_smp;
+
+/*
+ * Per-node, per-kmem_cache structure. Used for node-specific allocations.
+ */
+struct kmem_cache_node {
+ struct kmem_cache_list list;
+ spinlock_t list_lock; /* protects access to list */
+} ____cacheline_aligned;
+
+/*
+ * Management object for a slab cache.
+ */
+struct kmem_cache {
+ unsigned long flags;
+ int hiwater; /* LIFO list high watermark */
+ int freebatch; /* LIFO freelist batch flush size */
+#ifdef CONFIG_SMP
+ struct kmem_cache_cpu **cpu_slab; /* dynamic per-cpu structures */
+#else
+ struct kmem_cache_cpu cpu_slab;
+#endif
+ int objsize; /* Size of object without meta data */
+ int offset; /* Free pointer offset. */
+ int objects; /* Number of objects in slab */
+
+#ifdef CONFIG_NUMA
+ struct kmem_cache_node **node_slab; /* dynamic per-node structures */
+#endif
+
+ int size; /* Size of object including meta data */
+ int order; /* Allocation order */
+ gfp_t allocflags; /* gfp flags to use on allocation */
+ unsigned int colour_range; /* range of colour counter */
+ unsigned int colour_off; /* offset per colour */
+ void (*ctor)(void *);
+
+ const char *name; /* Name (only for display!) */
+ struct list_head list; /* List of slab caches */
+
+ int align; /* Alignment */
+ int inuse; /* Offset to metadata */
+
+#ifdef CONFIG_SLQB_SYSFS
+ struct kobject kobj; /* For sysfs */
+#endif
+} ____cacheline_aligned;
+
+/*
+ * Kmalloc subsystem.
+ */
+#if defined(ARCH_KMALLOC_MINALIGN) && ARCH_KMALLOC_MINALIGN > 8
+#define KMALLOC_MIN_SIZE ARCH_KMALLOC_MINALIGN
+#else
+#define KMALLOC_MIN_SIZE 8
+#endif
+
+#define KMALLOC_SHIFT_LOW ilog2(KMALLOC_MIN_SIZE)
+#define KMALLOC_SHIFT_SLQB_HIGH (PAGE_SHIFT + \
+ ((9 <= (MAX_ORDER - 1)) ? 9 : (MAX_ORDER - 1)))
+
+extern struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_SLQB_HIGH + 1];
+extern struct kmem_cache kmalloc_caches_dma[KMALLOC_SHIFT_SLQB_HIGH + 1];
+
+/*
+ * Constant size allocations use this path to find index into kmalloc caches
+ * arrays. get_slab() function is used for non-constant sizes.
+ */
+static __always_inline int kmalloc_index(size_t size)
+{
+ if (unlikely(!size))
+ return 0;
+ if (unlikely(size > 1UL << KMALLOC_SHIFT_SLQB_HIGH))
+ return 0;
+
+ if (unlikely(size <= KMALLOC_MIN_SIZE))
+ return KMALLOC_SHIFT_LOW;
+
+#if L1_CACHE_BYTES < 64
+ if (size > 64 && size <= 96)
+ return 1;
+#endif
+#if L1_CACHE_BYTES < 128
+ if (size > 128 && size <= 192)
+ return 2;
+#endif
+ if (size <= 8) return 3;
+ if (size <= 16) return 4;
+ if (size <= 32) return 5;
+ if (size <= 64) return 6;
+ if (size <= 128) return 7;
+ if (size <= 256) return 8;
+ if (size <= 512) return 9;
+ if (size <= 1024) return 10;
+ if (size <= 2 * 1024) return 11;
+ if (size <= 4 * 1024) return 12;
+ if (size <= 8 * 1024) return 13;
+ if (size <= 16 * 1024) return 14;
+ if (size <= 32 * 1024) return 15;
+ 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 <= 1024 * 1024) return 20;
+ if (size <= 2 * 1024 * 1024) return 21;
+ return -1;
+}
+
+#ifdef CONFIG_ZONE_DMA
+#define SLQB_DMA __GFP_DMA
+#else
+/* Disable "DMA slabs" */
+#define SLQB_DMA (__force gfp_t)0
+#endif
+
+/*
+ * Find the kmalloc slab cache for a given combination of allocation flags and
+ * size. Should really only be used for constant 'size' arguments, due to
+ * bloat.
+ */
+static __always_inline struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags)
+{
+ int index;
+
+ index = kmalloc_index(size);
+ if (unlikely(index == 0))
+ return ZERO_SIZE_PTR;
+
+ if (likely(!(flags & SLQB_DMA)))
+ return &kmalloc_caches[index];
+ else
+ return &kmalloc_caches_dma[index];
+}
+
+void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
+void *__kmalloc(size_t size, gfp_t flags);
+
+#ifndef ARCH_KMALLOC_MINALIGN
+#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long)
+#endif
+
+#ifndef ARCH_SLAB_MINALIGN
+#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long)
+#endif
+
+#define KMALLOC_HEADER (ARCH_KMALLOC_MINALIGN < sizeof(void *) ? \
+ sizeof(void *) : ARCH_KMALLOC_MINALIGN)
+
+static __always_inline void *kmalloc(size_t size, gfp_t flags)
+{
+ if (__builtin_constant_p(size)) {
+ struct kmem_cache *s;
+
+ s = kmalloc_slab(size, flags);
+ if (unlikely(ZERO_OR_NULL_PTR(s)))
+ return s;
+
+ return kmem_cache_alloc(s, flags);
+ }
+ return __kmalloc(size, flags);
+}
+
+#ifdef CONFIG_NUMA
+void *__kmalloc_node(size_t size, gfp_t flags, int node);
+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)) {
+ struct kmem_cache *s;
+
+ s = kmalloc_slab(size, flags);
+ if (unlikely(ZERO_OR_NULL_PTR(s)))
+ return s;
+
+ return kmem_cache_alloc_node(s, flags, node);
+ }
+ return __kmalloc_node(size, flags, node);
+}
+#endif
+
+#endif /* _LINUX_SLQB_DEF_H */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 5046f90c1171..be5d40c43bd2 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -10,7 +10,7 @@
#include <linux/gfp.h>
#include <linux/workqueue.h>
#include <linux/kobject.h>
-#include <trace/kmemtrace.h>
+#include <linux/kmemtrace.h>
enum stat_item {
ALLOC_FASTPATH, /* Allocation from cpu slab */
diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h
index b32725075d71..5241e4fb4eca 100644
--- a/include/linux/smsc911x.h
+++ b/include/linux/smsc911x.h
@@ -47,4 +47,14 @@ struct smsc911x_platform_config {
#define SMSC911X_FORCE_EXTERNAL_PHY (BIT(3))
#define SMSC911X_SAVE_MAC_ADDRESS (BIT(4))
+/*
+ * SMSC911X_SWAP_FIFO:
+ * Enables software byte swap for fifo data. Should only be used as a
+ * "last resort" in the case of big endian mode on boards with incorrectly
+ * routed data bus to older devices such as LAN9118. Newer devices such as
+ * LAN9221 can handle this in hardware, there are registers to control
+ * this swapping but the driver doesn't currently use them.
+ */
+#define SMSC911X_SWAP_FIFO (BIT(5))
+
#endif /* __LINUX_SMSC911X_H__ */
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index aee3f1e1d1ce..0f953fe40413 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -18,7 +18,7 @@
enum
{
IPSTATS_MIB_NUM = 0,
- IPSTATS_MIB_INRECEIVES, /* InReceives */
+ IPSTATS_MIB_INPKTS, /* InReceives */
IPSTATS_MIB_INHDRERRORS, /* InHdrErrors */
IPSTATS_MIB_INTOOBIGERRORS, /* InTooBigErrors */
IPSTATS_MIB_INNOROUTES, /* InNoRoutes */
@@ -28,7 +28,7 @@ enum
IPSTATS_MIB_INDISCARDS, /* InDiscards */
IPSTATS_MIB_INDELIVERS, /* InDelivers */
IPSTATS_MIB_OUTFORWDATAGRAMS, /* OutForwDatagrams */
- IPSTATS_MIB_OUTREQUESTS, /* OutRequests */
+ IPSTATS_MIB_OUTPKTS, /* OutRequests */
IPSTATS_MIB_OUTDISCARDS, /* OutDiscards */
IPSTATS_MIB_OUTNOROUTES, /* OutNoRoutes */
IPSTATS_MIB_REASMTIMEOUT, /* ReasmTimeout */
@@ -42,6 +42,12 @@ enum
IPSTATS_MIB_OUTMCASTPKTS, /* OutMcastPkts */
IPSTATS_MIB_INBCASTPKTS, /* InBcastPkts */
IPSTATS_MIB_OUTBCASTPKTS, /* OutBcastPkts */
+ IPSTATS_MIB_INOCTETS, /* InOctets */
+ IPSTATS_MIB_OUTOCTETS, /* OutOctets */
+ IPSTATS_MIB_INMCASTOCTETS, /* InMcastOctets */
+ IPSTATS_MIB_OUTMCASTOCTETS, /* OutMcastOctets */
+ IPSTATS_MIB_INBCASTOCTETS, /* InBcastOctets */
+ IPSTATS_MIB_OUTBCASTOCTETS, /* OutBcastOctets */
__IPSTATS_MIB_MAX
};
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 421afb4d29b0..d2310cb45d2f 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -303,14 +303,15 @@ struct ucred {
#define SOL_BLUETOOTH 274
#define SOL_PNPIPE 275
#define SOL_RDS 276
+#define SOL_IUCV 277
/* IPX options */
#define IPX_TYPE 1
#ifdef __KERNEL__
extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
-extern int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov,
- int offset, int len);
+extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
+ int offset, int len);
extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
struct iovec *iov,
int offset,
@@ -318,6 +319,8 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode);
extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
+extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
+ int offset, int len);
extern int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, int __user *ulen);
extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr);
extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
diff --git a/include/linux/spi/wl12xx.h b/include/linux/spi/wl12xx.h
new file mode 100644
index 000000000000..11430cab2aad
--- /dev/null
+++ b/include/linux/spi/wl12xx.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as 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 _LINUX_SPI_WL12XX_H
+#define _LINUX_SPI_WL12XX_H
+
+struct wl12xx_platform_data {
+ void (*set_power)(bool enable);
+};
+
+#endif
diff --git a/include/linux/splice.h b/include/linux/splice.h
index 5f3faa9d15ae..18e7c7c0cae6 100644
--- a/include/linux/splice.h
+++ b/include/linux/splice.h
@@ -11,8 +11,7 @@
#include <linux/pipe_fs_i.h>
/*
- * splice is tied to pipes as a transport (at least for now), so we'll just
- * add the splice flags here.
+ * Flags passed in from splice/tee/vmsplice
*/
#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */
#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index c39a21040dcb..37881f1a0bd7 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -143,6 +143,7 @@ int rpc_call_sync(struct rpc_clnt *clnt,
const struct rpc_message *msg, int flags);
struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred,
int flags);
+void rpc_restart_call_prepare(struct rpc_task *);
void rpc_restart_call(struct rpc_task *);
void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
size_t rpc_max_payload(struct rpc_clnt *);
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 64981a2f1cae..177376880fab 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -237,6 +237,7 @@ void rpc_show_tasks(void);
int rpc_init_mempool(void);
void rpc_destroy_mempool(void);
extern struct workqueue_struct *rpciod_workqueue;
+void rpc_prepare_task(struct rpc_task *task);
static inline void rpc_exit(struct rpc_task *task, int status)
{
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 0d9cb6ef28b0..2223ae0b5ed5 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -83,7 +83,7 @@ int svc_port_is_privileged(struct sockaddr *sin);
int svc_print_xprts(char *buf, int maxlen);
struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
const sa_family_t af, const unsigned short port);
-int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen);
+int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen);
static inline void svc_xprt_get(struct svc_xprt *xprt)
{
@@ -118,7 +118,7 @@ static inline unsigned short svc_addr_port(const struct sockaddr *sa)
return 0;
}
-static inline size_t svc_addr_len(struct sockaddr *sa)
+static inline size_t svc_addr_len(const struct sockaddr *sa)
{
switch (sa->sa_family) {
case AF_INET:
@@ -126,7 +126,8 @@ static inline size_t svc_addr_len(struct sockaddr *sa)
case AF_INET6:
return sizeof(struct sockaddr_in6);
}
- return -EAFNOSUPPORT;
+
+ return 0;
}
static inline unsigned short svc_xprt_local_port(const struct svc_xprt *xprt)
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index 483e10380aae..827163138949 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -38,8 +38,11 @@ int svc_recv(struct svc_rqst *, long);
int svc_send(struct svc_rqst *);
void svc_drop(struct svc_rqst *);
void svc_sock_update_bufs(struct svc_serv *serv);
-int svc_sock_names(char *buf, struct svc_serv *serv, char *toclose);
-int svc_addsock(struct svc_serv *serv, int fd, char *name_return);
+int svc_sock_names(struct svc_serv *serv, char *buf,
+ const size_t buflen,
+ const char *toclose);
+int svc_addsock(struct svc_serv *serv, const int fd,
+ char *name_return, const size_t len);
void svc_init_xprt_sock(void);
void svc_cleanup_xprt_sock(void);
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index ac9ff54f7cb3..cb1a6631b8f4 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -29,7 +29,8 @@ extern void *swiotlb_alloc(unsigned order, unsigned long nslabs);
extern dma_addr_t swiotlb_phys_to_bus(struct device *hwdev,
phys_addr_t address);
-extern phys_addr_t swiotlb_bus_to_phys(dma_addr_t address);
+extern phys_addr_t swiotlb_bus_to_phys(struct device *hwdev,
+ dma_addr_t address);
extern int swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 40617c1d8976..30520844b8da 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -433,6 +433,7 @@ asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
asmlinkage long sys_fcntl64(unsigned int fd,
unsigned int cmd, unsigned long arg);
#endif
+asmlinkage long sys_pipe2(int __user *fildes, int flags);
asmlinkage long sys_dup(unsigned int fildes);
asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd);
asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags);
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 9d5078bd23a3..8afac76cd748 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -377,7 +377,7 @@ struct tcp_sock {
unsigned int keepalive_time; /* time before keep alive takes place */
unsigned int keepalive_intvl; /* time interval between keep alive probes */
- unsigned long last_synq_overflow;
+ int linger2;
/* Receiver side RTT estimation */
struct {
@@ -406,8 +406,6 @@ struct tcp_sock {
/* TCP MD5 Signagure Option information */
struct tcp_md5sig_info *md5sig_info;
#endif
-
- int linger2;
};
static inline struct tcp_sock *tcp_sk(const struct sock *sk)
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index e6b820f8b56b..a8cc4e13434c 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -21,13 +21,14 @@ struct restart_block {
struct {
unsigned long arg0, arg1, arg2, arg3;
};
- /* For futex_wait */
+ /* For futex_wait and futex_wait_requeue_pi */
struct {
u32 *uaddr;
u32 val;
u32 flags;
u32 bitset;
u64 time;
+ u32 *uaddr2;
} futex;
/* For nanosleep */
struct {
diff --git a/include/linux/time.h b/include/linux/time.h
index 242f62499bb7..ea16c1a01d51 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -113,6 +113,21 @@ struct timespec current_kernel_time(void);
#define CURRENT_TIME (current_kernel_time())
#define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 })
+/* Some architectures do not supply their own clocksource.
+ * This is mainly the case in architectures that get their
+ * inter-tick times by reading the counter on their interval
+ * timer. Since these timers wrap every tick, they're not really
+ * useful as clocksources. Wrapping them to act like one is possible
+ * but not very efficient. So we provide a callout these arches
+ * can implement for use with the jiffies clocksource to provide
+ * finer then tick granular time.
+ */
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+extern u32 arch_gettimeoffset(void);
+#else
+static inline u32 arch_gettimeoffset(void) { return 0; }
+#endif
+
extern void do_gettimeofday(struct timeval *tv);
extern int do_settimeofday(struct timespec *tv);
extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);
diff --git a/include/linux/timex.h b/include/linux/timex.h
index aa3475fcff64..0daf9611ef4f 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -170,17 +170,37 @@ struct timex {
#include <asm/timex.h>
/*
- * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen
- * for a slightly underdamped convergence characteristic. SHIFT_KH
- * establishes the damping of the FLL and is chosen by wisdom and black
- * art.
+ * SHIFT_PLL is used as a dampening factor to define how much we
+ * adjust the frequency correction for a given offset in PLL mode.
+ * It also used in dampening the offset correction, to define how
+ * much of the current value in time_offset we correct for each
+ * second. Changing this value changes the stiffness of the ntp
+ * adjustment code. A lower value makes it more flexible, reducing
+ * NTP convergence time. A higher value makes it stiffer, increasing
+ * convergence time, but making the clock more stable.
*
- * MAXTC establishes the maximum time constant of the PLL. With the
- * SHIFT_KG and SHIFT_KF values given and a time constant range from
- * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours,
- * respectively.
+ * In David Mills' nanokenrel reference implmentation SHIFT_PLL is 4.
+ * However this seems to increase convergence time much too long.
+ *
+ * https://lists.ntp.org/pipermail/hackers/2008-January/003487.html
+ *
+ * In the above mailing list discussion, it seems the value of 4
+ * was appropriate for other Unix systems with HZ=100, and that
+ * SHIFT_PLL should be decreased as HZ increases. However, Linux's
+ * clock steering implementation is HZ independent.
+ *
+ * Through experimentation, a SHIFT_PLL value of 2 was found to allow
+ * for fast convergence (very similar to the NTPv3 code used prior to
+ * v2.6.19), with good clock stability.
+ *
+ *
+ * SHIFT_FLL is used as a dampening factor to define how much we
+ * adjust the frequency correction for a given offset in FLL mode.
+ * In David Mills' nanokenrel reference implmentation SHIFT_PLL is 2.
+ *
+ * MAXTC establishes the maximum time constant of the PLL.
*/
-#define SHIFT_PLL 4 /* PLL frequency factor (shift) */
+#define SHIFT_PLL 2 /* PLL frequency factor (shift) */
#define SHIFT_FLL 2 /* FLL frequency factor (shift) */
#define MAXTC 10 /* maximum time constant (shift) */
@@ -192,10 +212,10 @@ struct timex {
#define SHIFT_USEC 16 /* frequency offset scale (shift) */
#define PPM_SCALE ((s64)NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC))
#define PPM_SCALE_INV_SHIFT 19
-#define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \
+#define PPM_SCALE_INV ((1LL << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \
PPM_SCALE + 1)
-#define MAXPHASE 500000000l /* max phase error (ns) */
+#define MAXPHASE 500000000L /* max phase error (ns) */
#define MAXFREQ 500000 /* max frequency error (ns/s) */
#define MAXFREQ_SCALED ((s64)MAXFREQ << NTP_SCALE_SHIFT)
#define MINSEC 256 /* min interval between updates (s) */
diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h
new file mode 100644
index 000000000000..ba9627f00d3f
--- /dev/null
+++ b/include/linux/trace_seq.h
@@ -0,0 +1,90 @@
+#ifndef _LINUX_TRACE_SEQ_H
+#define _LINUX_TRACE_SEQ_H
+
+#include <linux/fs.h>
+
+/*
+ * Trace sequences are used to allow a function to call several other functions
+ * to create a string of data to use (up to a max of PAGE_SIZE.
+ */
+
+struct trace_seq {
+ unsigned char buffer[PAGE_SIZE];
+ unsigned int len;
+ unsigned int readpos;
+};
+
+static inline void
+trace_seq_init(struct trace_seq *s)
+{
+ s->len = 0;
+ s->readpos = 0;
+}
+
+/*
+ * Currently only defined when tracing is enabled.
+ */
+#ifdef CONFIG_TRACING
+extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+extern int
+trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
+extern void trace_print_seq(struct seq_file *m, struct trace_seq *s);
+extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
+ size_t cnt);
+extern int trace_seq_puts(struct trace_seq *s, const char *str);
+extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
+extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len);
+extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
+ size_t len);
+extern void *trace_seq_reserve(struct trace_seq *s, size_t len);
+extern int trace_seq_path(struct trace_seq *s, struct path *path);
+
+#else /* CONFIG_TRACING */
+static inline int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
+{
+ return 0;
+}
+static inline int
+trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
+{
+ return 0;
+}
+
+static inline void trace_print_seq(struct seq_file *m, struct trace_seq *s)
+{
+}
+static inline ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
+ size_t cnt)
+{
+ return 0;
+}
+static inline int trace_seq_puts(struct trace_seq *s, const char *str)
+{
+ return 0;
+}
+static inline int trace_seq_putc(struct trace_seq *s, unsigned char c)
+{
+ return 0;
+}
+static inline int
+trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
+{
+ return 0;
+}
+static inline int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
+ size_t len)
+{
+ return 0;
+}
+static inline void *trace_seq_reserve(struct trace_seq *s, size_t len)
+{
+ return NULL;
+}
+static inline int trace_seq_path(struct trace_seq *s, struct path *path)
+{
+ return 0;
+}
+#endif /* CONFIG_TRACING */
+
+#endif /* _LINUX_TRACE_SEQ_H */
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index d35a7ee7611f..14df7e635d43 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -31,6 +31,8 @@ struct tracepoint {
* Keep in sync with vmlinux.lds.h.
*/
+#ifndef DECLARE_TRACE
+
#define TP_PROTO(args...) args
#define TP_ARGS(args...) args
@@ -114,6 +116,7 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin,
struct tracepoint *end)
{ }
#endif /* CONFIG_TRACEPOINTS */
+#endif /* DECLARE_TRACE */
/*
* Connect a probe to a tracepoint.
@@ -154,10 +157,8 @@ static inline void tracepoint_synchronize_unregister(void)
}
#define PARAMS(args...) args
-#define TRACE_FORMAT(name, proto, args, fmt) \
- DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
-
+#ifndef TRACE_EVENT
/*
* For use with the TRACE_EVENT macro:
*
@@ -262,5 +263,6 @@ static inline void tracepoint_synchronize_unregister(void)
#define TRACE_EVENT(name, proto, args, struct, assign, print) \
DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
+#endif
#endif
diff --git a/include/linux/tty.h b/include/linux/tty.h
index fc39db95499f..bed5a3d40307 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -185,7 +185,7 @@ struct tty_port;
struct tty_port_operations {
/* Return 1 if the carrier is raised */
int (*carrier_raised)(struct tty_port *port);
- void (*raise_dtr_rts)(struct tty_port *port);
+ void (*dtr_rts)(struct tty_port *port, int raise);
};
struct tty_port {
@@ -201,6 +201,9 @@ struct tty_port {
unsigned char *xmit_buf; /* Optional buffer */
int close_delay; /* Close port delay */
int closing_wait; /* Delay for output */
+ int drain_delay; /* Set to zero if no pure time
+ based drain is needed else
+ set to size of fifo */
};
/*
@@ -438,6 +441,7 @@ extern struct tty_struct *tty_port_tty_get(struct tty_port *port);
extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty);
extern int tty_port_carrier_raised(struct tty_port *port);
extern void tty_port_raise_dtr_rts(struct tty_port *port);
+extern void tty_port_lower_dtr_rts(struct tty_port *port);
extern void tty_port_hangup(struct tty_port *port);
extern int tty_port_block_til_ready(struct tty_port *port,
struct tty_struct *tty, struct file *filp);
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 625e9e4639c6..8cdfed738fe4 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -224,8 +224,7 @@ struct usb_serial_driver {
/* Called by console with tty = NULL and by tty */
int (*open)(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
- void (*close)(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+ void (*close)(struct usb_serial_port *port);
int (*write)(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
/* Called only by the tty layer */
@@ -241,6 +240,10 @@ struct usb_serial_driver {
int (*tiocmget)(struct tty_struct *tty, struct file *file);
int (*tiocmset)(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
+ /* Called by the tty layer for port level work. There may or may not
+ be an attached tty at this point */
+ void (*dtr_rts)(struct usb_serial_port *port, int on);
+ int (*carrier_raised)(struct usb_serial_port *port);
/* USB events */
void (*read_int_callback)(struct urb *urb);
void (*write_int_callback)(struct urb *urb);
@@ -283,8 +286,7 @@ extern int usb_serial_generic_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
extern int usb_serial_generic_write(struct tty_struct *tty,
struct usb_serial_port *port, const unsigned char *buf, int count);
-extern void usb_serial_generic_close(struct tty_struct *tty,
- struct usb_serial_port *port, struct file *filp);
+extern void usb_serial_generic_close(struct usb_serial_port *port);
extern int usb_serial_generic_resume(struct usb_serial *serial);
extern int usb_serial_generic_write_room(struct tty_struct *tty);
extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty);
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 36fabb95c7d3..5d44059f6d63 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -183,6 +183,7 @@ extern void usbnet_tx_timeout (struct net_device *net);
extern int usbnet_change_mtu (struct net_device *net, int new_mtu);
extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *);
+extern int usbnet_get_ethernet_addr(struct usbnet *, int);
extern void usbnet_defer_kevent (struct usbnet *, int);
extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
extern void usbnet_unlink_rx_urbs(struct usbnet *);
diff --git a/include/linux/wait.h b/include/linux/wait.h
index bc024632f365..6788e1a4d4ca 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -132,8 +132,6 @@ static inline void __remove_wait_queue(wait_queue_head_t *head,
list_del(&old->task_list);
}
-void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
- int nr_exclusive, int sync, void *key);
void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key);
void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode, int nr,
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 9c1ed1fb6ddb..943d1c9fca9b 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -79,7 +79,6 @@ struct writeback_control {
void writeback_inodes(struct writeback_control *wbc);
int inode_wait(void *);
void sync_inodes_sb(struct super_block *, int wait);
-void sync_inodes(int wait);
/* writeback.h requires fs.h; it, too, is not included from here. */
static inline void wait_on_inode(struct inode *inode)
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index 07963d705400..3ad4ed5402fb 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -7,7 +7,7 @@ struct IR_i2c;
struct IR_i2c {
IR_KEYTAB_TYPE *ir_codes;
- struct i2c_client c;
+ struct i2c_client *c;
struct input_dev *input;
struct ir_input_state ir;
@@ -15,7 +15,15 @@ struct IR_i2c {
unsigned char old;
struct delayed_work work;
+ char name[32];
char phys[32];
int (*get_key)(struct IR_i2c*, u32*, u32*);
};
+
+/* Can be passed when instantiating an ir_video i2c device */
+struct IR_i2c_init_data {
+ IR_KEYTAB_TYPE *ir_codes;
+ const char *name;
+ int (*get_key)(struct IR_i2c*, u32*, u32*);
+};
#endif
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 37013688af44..23ecead35e7a 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -60,7 +60,7 @@ struct soc_camera_file {
struct soc_camera_host {
struct list_head list;
- struct device dev;
+ struct device *dev;
unsigned char nr; /* Host number */
void *priv;
const char *drv_name;
@@ -92,11 +92,16 @@ struct soc_camera_host_ops {
#define SOCAM_SENSOR_INVERT_VSYNC (1 << 3)
#define SOCAM_SENSOR_INVERT_DATA (1 << 4)
+struct i2c_board_info;
+
struct soc_camera_link {
/* Camera bus id, used to match a camera and a bus */
int bus_id;
/* Per camera SOCAM_SENSOR_* bus flags */
unsigned long flags;
+ int i2c_adapter_id;
+ struct i2c_board_info *board_info;
+ const char *module_name;
/* Optional callbacks to power on or off and reset the sensor */
int (*power)(struct device *, int);
int (*reset)(struct device *);
@@ -107,6 +112,7 @@ struct soc_camera_link {
*/
int (*set_bus_param)(struct soc_camera_link *, unsigned long flags);
unsigned long (*query_bus_param)(struct soc_camera_link *);
+ void (*free_bus)(struct soc_camera_link *);
};
static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev)
@@ -116,7 +122,7 @@ static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev)
static inline struct soc_camera_host *to_soc_camera_host(struct device *dev)
{
- return container_of(dev, struct soc_camera_host, dev);
+ return dev_get_drvdata(dev);
}
extern int soc_camera_host_register(struct soc_camera_host *ici);
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 0dd3e8e8653e..5d5d550e63ad 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -30,7 +30,7 @@
basic V4L2 device-level support.
*/
-#define V4L2_DEVICE_NAME_SIZE (BUS_ID_SIZE + 16)
+#define V4L2_DEVICE_NAME_SIZE (20 + 16)
struct v4l2_device {
/* dev->driver_data points to this struct.
@@ -53,10 +53,31 @@ struct v4l2_device {
dev may be NULL in rare cases (ISA devices). In that case you
must fill in the v4l2_dev->name field before calling this function. */
int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
+
+/* Optional function to initialize the name field of struct v4l2_device using
+ the driver name and a driver-global atomic_t instance.
+ This function will increment the instance counter and returns the instance
+ value used in the name.
+
+ Example:
+
+ static atomic_t drv_instance = ATOMIC_INIT(0);
+
+ ...
+
+ instance = v4l2_device_set_name(&v4l2_dev, "foo", &drv_instance);
+
+ The first time this is called the name field will be set to foo0 and
+ this function returns 0. If the name ends with a digit (e.g. cx18),
+ then the name will be set to cx18-0 since cx180 looks really odd. */
+int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
+ atomic_t *instance);
+
/* Set v4l2_dev->dev to NULL. Call when the USB parent disconnects.
Since the parent disappears this ensures that v4l2_dev doesn't have an
invalid parent pointer. */
void v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
+
/* Unregister all sub-devices and any other resources related to v4l2_dev. */
void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 17856081c809..a503e1cee78b 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -230,12 +230,16 @@ struct v4l2_subdev_ops {
#define V4L2_SUBDEV_NAME_SIZE 32
+/* Set this flag if this subdev is a i2c device. */
+#define V4L2_SUBDEV_FL_IS_I2C (1U << 0)
+
/* Each instance of a subdev driver should create this struct, either
stand-alone or embedded in a larger struct.
*/
struct v4l2_subdev {
struct list_head list;
struct module *owner;
+ u32 flags;
struct v4l2_device *v4l2_dev;
const struct v4l2_subdev_ops *ops;
/* name must be unique */
@@ -264,6 +268,7 @@ static inline void v4l2_subdev_init(struct v4l2_subdev *sd,
BUG_ON(!ops || !ops->core);
sd->ops = ops;
sd->v4l2_dev = NULL;
+ sd->flags = 0;
sd->name[0] = '\0';
sd->grp_id = 0;
sd->priv = NULL;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5389afdc1297..9e17a83d3432 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1,71 +1,217 @@
#ifndef __NET_CFG80211_H
#define __NET_CFG80211_H
+/*
+ * 802.11 device and configuration interface
+ *
+ * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.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.
+ */
+#include <linux/netdevice.h>
+#include <linux/debugfs.h>
+#include <linux/list.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <linux/nl80211.h>
#include <linux/if_ether.h>
#include <linux/ieee80211.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <net/genetlink.h>
+#include <net/regulatory.h>
+
/* remove once we remove the wext stuff */
#include <net/iw_handler.h>
+#include <linux/wireless.h>
+
/*
- * 802.11 configuration in-kernel interface
+ * wireless hardware capability structures
+ */
+
+/**
+ * enum ieee80211_band - supported frequency bands
+ *
+ * The bands are assigned this way because the supported
+ * bitrates differ in these bands.
*
- * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
+ * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band
+ * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7)
*/
+enum ieee80211_band {
+ IEEE80211_BAND_2GHZ,
+ IEEE80211_BAND_5GHZ,
+
+ /* keep last */
+ IEEE80211_NUM_BANDS
+};
/**
- * struct vif_params - describes virtual interface parameters
- * @mesh_id: mesh ID to use
- * @mesh_id_len: length of the mesh ID
+ * enum ieee80211_channel_flags - channel flags
+ *
+ * Channel flags set by the regulatory control code.
+ *
+ * @IEEE80211_CHAN_DISABLED: This channel is disabled.
+ * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted
+ * on this channel.
+ * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
+ * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
+ * @IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel
+ * is not permitted.
+ * @IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel
+ * is not permitted.
*/
-struct vif_params {
- u8 *mesh_id;
- int mesh_id_len;
+enum ieee80211_channel_flags {
+ IEEE80211_CHAN_DISABLED = 1<<0,
+ IEEE80211_CHAN_PASSIVE_SCAN = 1<<1,
+ IEEE80211_CHAN_NO_IBSS = 1<<2,
+ IEEE80211_CHAN_RADAR = 1<<3,
+ IEEE80211_CHAN_NO_FAT_ABOVE = 1<<4,
+ IEEE80211_CHAN_NO_FAT_BELOW = 1<<5,
};
-/* Radiotap header iteration
- * implemented in net/wireless/radiotap.c
- * docs in Documentation/networking/radiotap-headers.txt
+/**
+ * struct ieee80211_channel - channel definition
+ *
+ * This structure describes a single channel for use
+ * with cfg80211.
+ *
+ * @center_freq: center frequency in MHz
+ * @max_bandwidth: maximum allowed bandwidth for this channel, in MHz
+ * @hw_value: hardware-specific value for the channel
+ * @flags: channel flags from &enum ieee80211_channel_flags.
+ * @orig_flags: channel flags at registration time, used by regulatory
+ * code to support devices with additional restrictions
+ * @band: band this channel belongs to.
+ * @max_antenna_gain: maximum antenna gain in dBi
+ * @max_power: maximum transmission power (in dBm)
+ * @beacon_found: helper to regulatory code to indicate when a beacon
+ * has been found on this channel. Use regulatory_hint_found_beacon()
+ * to enable this, this is is useful only on 5 GHz band.
+ * @orig_mag: internal use
+ * @orig_mpwr: internal use
*/
+struct ieee80211_channel {
+ enum ieee80211_band band;
+ u16 center_freq;
+ u8 max_bandwidth;
+ u16 hw_value;
+ u32 flags;
+ int max_antenna_gain;
+ int max_power;
+ bool beacon_found;
+ u32 orig_flags;
+ int orig_mag, orig_mpwr;
+};
+
/**
- * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
- * @rtheader: pointer to the radiotap header we are walking through
- * @max_length: length of radiotap header in cpu byte ordering
- * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg
- * @this_arg: pointer to current radiotap arg
- * @arg_index: internal next argument index
- * @arg: internal next argument pointer
- * @next_bitmap: internal pointer to next present u32
- * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
+ * enum ieee80211_rate_flags - rate flags
+ *
+ * Hardware/specification flags for rates. These are structured
+ * in a way that allows using the same bitrate structure for
+ * different bands/PHY modes.
+ *
+ * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short
+ * preamble on this bitrate; only relevant in 2.4GHz band and
+ * with CCK rates.
+ * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate
+ * when used with 802.11a (on the 5 GHz band); filled by the
+ * core code when registering the wiphy.
+ * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate
+ * when used with 802.11b (on the 2.4 GHz band); filled by the
+ * core code when registering the wiphy.
+ * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate
+ * when used with 802.11g (on the 2.4 GHz band); filled by the
+ * core code when registering the wiphy.
+ * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode.
*/
+enum ieee80211_rate_flags {
+ IEEE80211_RATE_SHORT_PREAMBLE = 1<<0,
+ IEEE80211_RATE_MANDATORY_A = 1<<1,
+ IEEE80211_RATE_MANDATORY_B = 1<<2,
+ IEEE80211_RATE_MANDATORY_G = 1<<3,
+ IEEE80211_RATE_ERP_G = 1<<4,
+};
-struct ieee80211_radiotap_iterator {
- struct ieee80211_radiotap_header *rtheader;
- int max_length;
- int this_arg_index;
- u8 *this_arg;
+/**
+ * struct ieee80211_rate - bitrate definition
+ *
+ * This structure describes a bitrate that an 802.11 PHY can
+ * operate with. The two values @hw_value and @hw_value_short
+ * are only for driver use when pointers to this structure are
+ * passed around.
+ *
+ * @flags: rate-specific flags
+ * @bitrate: bitrate in units of 100 Kbps
+ * @hw_value: driver/hardware value for this rate
+ * @hw_value_short: driver/hardware value for this rate when
+ * short preamble is used
+ */
+struct ieee80211_rate {
+ u32 flags;
+ u16 bitrate;
+ u16 hw_value, hw_value_short;
+};
- int arg_index;
- u8 *arg;
- __le32 *next_bitmap;
- u32 bitmap_shifter;
+/**
+ * struct ieee80211_sta_ht_cap - STA's HT capabilities
+ *
+ * This structure describes most essential parameters needed
+ * to describe 802.11n HT capabilities for an STA.
+ *
+ * @ht_supported: is HT supported by the STA
+ * @cap: HT capabilities map as described in 802.11n spec
+ * @ampdu_factor: Maximum A-MPDU length factor
+ * @ampdu_density: Minimum A-MPDU spacing
+ * @mcs: Supported MCS rates
+ */
+struct ieee80211_sta_ht_cap {
+ u16 cap; /* use IEEE80211_HT_CAP_ */
+ bool ht_supported;
+ u8 ampdu_factor;
+ u8 ampdu_density;
+ struct ieee80211_mcs_info mcs;
};
-extern int ieee80211_radiotap_iterator_init(
- struct ieee80211_radiotap_iterator *iterator,
- struct ieee80211_radiotap_header *radiotap_header,
- int max_length);
+/**
+ * struct ieee80211_supported_band - frequency band definition
+ *
+ * This structure describes a frequency band a wiphy
+ * is able to operate in.
+ *
+ * @channels: Array of channels the hardware can operate in
+ * in this band.
+ * @band: the band this structure represents
+ * @n_channels: Number of channels in @channels
+ * @bitrates: Array of bitrates the hardware can operate with
+ * in this band. Must be sorted to give a valid "supported
+ * rates" IE, i.e. CCK rates first, then OFDM.
+ * @n_bitrates: Number of bitrates in @bitrates
+ */
+struct ieee80211_supported_band {
+ struct ieee80211_channel *channels;
+ struct ieee80211_rate *bitrates;
+ enum ieee80211_band band;
+ int n_channels;
+ int n_bitrates;
+ struct ieee80211_sta_ht_cap ht_cap;
+};
-extern int ieee80211_radiotap_iterator_next(
- struct ieee80211_radiotap_iterator *iterator);
+/*
+ * Wireless hardware/device configuration structures and methods
+ */
+/**
+ * struct vif_params - describes virtual interface parameters
+ * @mesh_id: mesh ID to use
+ * @mesh_id_len: length of the mesh ID
+ */
+struct vif_params {
+ u8 *mesh_id;
+ int mesh_id_len;
+};
- /**
+/**
* struct key_params - key information
*
* Information about a key
@@ -106,27 +252,6 @@ struct beacon_parameters {
};
/**
- * enum station_flags - station flags
- *
- * Station capability flags. Note that these must be the bits
- * according to the nl80211 flags.
- *
- * @STATION_FLAG_CHANGED: station flags were changed
- * @STATION_FLAG_AUTHORIZED: station is authorized to send frames (802.1X)
- * @STATION_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
- * with short preambles
- * @STATION_FLAG_WME: station is WME/QoS capable
- * @STATION_FLAG_MFP: station uses management frame protection
- */
-enum station_flags {
- STATION_FLAG_CHANGED = 1<<0,
- STATION_FLAG_AUTHORIZED = 1<<NL80211_STA_FLAG_AUTHORIZED,
- STATION_FLAG_SHORT_PREAMBLE = 1<<NL80211_STA_FLAG_SHORT_PREAMBLE,
- STATION_FLAG_WME = 1<<NL80211_STA_FLAG_WME,
- STATION_FLAG_MFP = 1<<NL80211_STA_FLAG_MFP,
-};
-
-/**
* enum plink_action - actions to perform in mesh peers
*
* @PLINK_ACTION_INVALID: action 0 is reserved
@@ -148,14 +273,17 @@ enum plink_actions {
* @supported_rates: supported rates in IEEE 802.11 format
* (or NULL for no change)
* @supported_rates_len: number of supported rates
- * @station_flags: station flags (see &enum station_flags)
+ * @sta_flags_mask: station flags that changed
+ * (bitmask of BIT(NL80211_STA_FLAG_...))
+ * @sta_flags_set: station flags values
+ * (bitmask of BIT(NL80211_STA_FLAG_...))
* @listen_interval: listen interval or -1 for no change
* @aid: AID or zero for no change
*/
struct station_parameters {
u8 *supported_rates;
struct net_device *vlan;
- u32 station_flags;
+ u32 sta_flags_mask, sta_flags_set;
int listen_interval;
u16 aid;
u8 supported_rates_len;
@@ -348,92 +476,6 @@ struct bss_parameters {
u8 basic_rates_len;
};
-/**
- * enum environment_cap - Environment parsed from country IE
- * @ENVIRON_ANY: indicates country IE applies to both indoor and
- * outdoor operation.
- * @ENVIRON_INDOOR: indicates country IE applies only to indoor operation
- * @ENVIRON_OUTDOOR: indicates country IE applies only to outdoor operation
- */
-enum environment_cap {
- ENVIRON_ANY,
- ENVIRON_INDOOR,
- ENVIRON_OUTDOOR,
-};
-
-/**
- * struct regulatory_request - used to keep track of regulatory requests
- *
- * @wiphy_idx: this is set if this request's initiator is
- * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
- * can be used by the wireless core to deal with conflicts
- * and potentially inform users of which devices specifically
- * cased the conflicts.
- * @initiator: indicates who sent this request, could be any of
- * of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*)
- * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
- * regulatory domain. We have a few special codes:
- * 00 - World regulatory domain
- * 99 - built by driver but a specific alpha2 cannot be determined
- * 98 - result of an intersection between two regulatory domains
- * @intersect: indicates whether the wireless core should intersect
- * the requested regulatory domain with the presently set regulatory
- * domain.
- * @country_ie_checksum: checksum of the last processed and accepted
- * country IE
- * @country_ie_env: lets us know if the AP is telling us we are outdoor,
- * indoor, or if it doesn't matter
- * @list: used to insert into the reg_requests_list linked list
- */
-struct regulatory_request {
- int wiphy_idx;
- enum nl80211_reg_initiator initiator;
- char alpha2[2];
- bool intersect;
- u32 country_ie_checksum;
- enum environment_cap country_ie_env;
- struct list_head list;
-};
-
-struct ieee80211_freq_range {
- u32 start_freq_khz;
- u32 end_freq_khz;
- u32 max_bandwidth_khz;
-};
-
-struct ieee80211_power_rule {
- u32 max_antenna_gain;
- u32 max_eirp;
-};
-
-struct ieee80211_reg_rule {
- struct ieee80211_freq_range freq_range;
- struct ieee80211_power_rule power_rule;
- u32 flags;
-};
-
-struct ieee80211_regdomain {
- u32 n_reg_rules;
- char alpha2[2];
- struct ieee80211_reg_rule reg_rules[];
-};
-
-#define MHZ_TO_KHZ(freq) ((freq) * 1000)
-#define KHZ_TO_MHZ(freq) ((freq) / 1000)
-#define DBI_TO_MBI(gain) ((gain) * 100)
-#define MBI_TO_DBI(gain) ((gain) / 100)
-#define DBM_TO_MBM(gain) ((gain) * 100)
-#define MBM_TO_DBM(gain) ((gain) / 100)
-
-#define REG_RULE(start, end, bw, gain, eirp, reg_flags) { \
- .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
- .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \
- .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \
- .power_rule.max_antenna_gain = DBI_TO_MBI(gain), \
- .power_rule.max_eirp = DBM_TO_MBM(eirp), \
- .flags = reg_flags, \
- }
-
struct mesh_config {
/* Timeouts in ms */
/* Mesh plink management parameters */
@@ -504,7 +546,7 @@ struct cfg80211_scan_request {
int n_ssids;
struct ieee80211_channel **channels;
u32 n_channels;
- u8 *ie;
+ const u8 *ie;
size_t ie_len;
/* internal */
@@ -612,6 +654,11 @@ struct cfg80211_auth_request {
* @ssid_len: Length of ssid in octets
* @ie: Extra IEs to add to (Re)Association Request frame or %NULL
* @ie_len: Length of ie buffer in octets
+ * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
+ * @control_port: Whether user space controls IEEE 802.1X port, i.e.,
+ * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
+ * required to assume that the port is unauthorized until authorized by
+ * user space. Otherwise, port is marked authorized by default.
*/
struct cfg80211_assoc_request {
struct ieee80211_channel *chan;
@@ -620,6 +667,8 @@ struct cfg80211_assoc_request {
size_t ssid_len;
const u8 *ie;
size_t ie_len;
+ bool use_mfp;
+ bool control_port;
};
/**
@@ -659,6 +708,47 @@ struct cfg80211_disassoc_request {
};
/**
+ * struct cfg80211_ibss_params - IBSS parameters
+ *
+ * This structure defines the IBSS parameters for the join_ibss()
+ * method.
+ *
+ * @ssid: The SSID, will always be non-null.
+ * @ssid_len: The length of the SSID, will always be non-zero.
+ * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not
+ * search for IBSSs with a different BSSID.
+ * @channel: The channel to use if no IBSS can be found to join.
+ * @channel_fixed: The channel should be fixed -- do not search for
+ * IBSSs to join on other channels.
+ * @ie: information element(s) to include in the beacon
+ * @ie_len: length of that
+ * @beacon_interval: beacon interval to use
+ */
+struct cfg80211_ibss_params {
+ u8 *ssid;
+ u8 *bssid;
+ struct ieee80211_channel *channel;
+ u8 *ie;
+ u8 ssid_len, ie_len;
+ u16 beacon_interval;
+ bool channel_fixed;
+};
+
+/**
+ * enum wiphy_params_flags - set_wiphy_params bitfield values
+ * WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed
+ * WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed
+ * WIPHY_PARAM_FRAG_THRESHOLD: wiphy->frag_threshold has changed
+ * WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed
+ */
+enum wiphy_params_flags {
+ WIPHY_PARAM_RETRY_SHORT = 1 << 0,
+ WIPHY_PARAM_RETRY_LONG = 1 << 1,
+ WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2,
+ WIPHY_PARAM_RTS_THRESHOLD = 1 << 3,
+};
+
+/**
* struct cfg80211_ops - backend description for wireless configuration
*
* This struct is registered by fullmac card drivers and/or wireless stacks
@@ -733,6 +823,16 @@ struct cfg80211_disassoc_request {
* @assoc: Request to (re)associate with the specified peer
* @deauth: Request to deauthenticate from the specified peer
* @disassoc: Request to disassociate from the specified peer
+ *
+ * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
+ * cfg80211_ibss_joined(), also call that function when changing BSSID due
+ * to a merge.
+ * @leave_ibss: Leave the IBSS.
+ *
+ * @set_wiphy_params: Notify that wiphy parameters have changed;
+ * @changed bitfield (see &enum wiphy_params_flags) describes which values
+ * have changed. The actual parameter values are available in
+ * struct wiphy. If returning an error, no value should be changed.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy);
@@ -747,13 +847,13 @@ struct cfg80211_ops {
struct vif_params *params);
int (*add_key)(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, u8 *mac_addr,
+ u8 key_index, const u8 *mac_addr,
struct key_params *params);
int (*get_key)(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, u8 *mac_addr, void *cookie,
+ u8 key_index, const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie, struct key_params*));
int (*del_key)(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, u8 *mac_addr);
+ u8 key_index, const u8 *mac_addr);
int (*set_default_key)(struct wiphy *wiphy,
struct net_device *netdev,
u8 key_index);
@@ -818,9 +918,417 @@ struct cfg80211_ops {
struct cfg80211_deauth_request *req);
int (*disassoc)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_disassoc_request *req);
+
+ int (*join_ibss)(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ibss_params *params);
+ int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev);
+
+ int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed);
};
-/* temporary wext handlers */
+/*
+ * wireless hardware and networking interfaces structures
+ * and registration/helper functions
+ */
+
+/**
+ * struct wiphy - wireless hardware description
+ * @idx: the wiphy index assigned to this item
+ * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name>
+ * @custom_regulatory: tells us the driver for this device
+ * has its own custom regulatory domain and cannot identify the
+ * ISO / IEC 3166 alpha2 it belongs to. When this is enabled
+ * we will disregard the first regulatory hint (when the
+ * initiator is %REGDOM_SET_BY_CORE).
+ * @strict_regulatory: tells us the driver for this device will ignore
+ * regulatory domain settings until it gets its own regulatory domain
+ * via its regulatory_hint(). After its gets its own regulatory domain
+ * it will only allow further regulatory domain settings to further
+ * enhance compliance. For example if channel 13 and 14 are disabled
+ * by this regulatory domain no user regulatory domain can enable these
+ * channels at a later time. This can be used for devices which do not
+ * have calibration information gauranteed for frequencies or settings
+ * outside of its regulatory domain.
+ * @reg_notifier: the driver's regulatory notification callback
+ * @regd: the driver's regulatory domain, if one was requested via
+ * the regulatory_hint() API. This can be used by the driver
+ * on the reg_notifier() if it chooses to ignore future
+ * regulatory domain changes caused by other drivers.
+ * @signal_type: signal type reported in &struct cfg80211_bss.
+ * @cipher_suites: supported cipher suites
+ * @n_cipher_suites: number of supported cipher suites
+ * @retry_short: Retry limit for short frames (dot11ShortRetryLimit)
+ * @retry_long: Retry limit for long frames (dot11LongRetryLimit)
+ * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold);
+ * -1 = fragmentation disabled, only odd values >= 256 used
+ * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled
+ */
+struct wiphy {
+ /* assign these fields before you register the wiphy */
+
+ /* permanent MAC address */
+ u8 perm_addr[ETH_ALEN];
+
+ /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
+ u16 interface_modes;
+
+ bool custom_regulatory;
+ bool strict_regulatory;
+
+ enum cfg80211_signal_type signal_type;
+
+ int bss_priv_size;
+ u8 max_scan_ssids;
+ u16 max_scan_ie_len;
+
+ int n_cipher_suites;
+ const u32 *cipher_suites;
+
+ u8 retry_short;
+ u8 retry_long;
+ u32 frag_threshold;
+ u32 rts_threshold;
+
+ /* If multiple wiphys are registered and you're handed e.g.
+ * a regular netdev with assigned ieee80211_ptr, you won't
+ * know whether it points to a wiphy your driver has registered
+ * or not. Assign this to something global to your driver to
+ * help determine whether you own this wiphy or not. */
+ void *privid;
+
+ struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
+
+ /* Lets us get back the wiphy on the callback */
+ int (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *request);
+
+ /* fields below are read-only, assigned by cfg80211 */
+
+ const struct ieee80211_regdomain *regd;
+
+ /* the item in /sys/class/ieee80211/ points to this,
+ * you need use set_wiphy_dev() (see below) */
+ struct device dev;
+
+ /* dir in debugfs: ieee80211/<wiphyname> */
+ struct dentry *debugfsdir;
+
+ char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
+};
+
+/**
+ * wiphy_priv - return priv from wiphy
+ *
+ * @wiphy: the wiphy whose priv pointer to return
+ */
+static inline void *wiphy_priv(struct wiphy *wiphy)
+{
+ BUG_ON(!wiphy);
+ return &wiphy->priv;
+}
+
+/**
+ * set_wiphy_dev - set device pointer for wiphy
+ *
+ * @wiphy: The wiphy whose device to bind
+ * @dev: The device to parent it to
+ */
+static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev)
+{
+ wiphy->dev.parent = dev;
+}
+
+/**
+ * wiphy_dev - get wiphy dev pointer
+ *
+ * @wiphy: The wiphy whose device struct to look up
+ */
+static inline struct device *wiphy_dev(struct wiphy *wiphy)
+{
+ return wiphy->dev.parent;
+}
+
+/**
+ * wiphy_name - get wiphy name
+ *
+ * @wiphy: The wiphy whose name to return
+ */
+static inline const char *wiphy_name(struct wiphy *wiphy)
+{
+ return dev_name(&wiphy->dev);
+}
+
+/**
+ * wiphy_new - create a new wiphy for use with cfg80211
+ *
+ * @ops: The configuration operations for this device
+ * @sizeof_priv: The size of the private area to allocate
+ *
+ * Create a new wiphy and associate the given operations with it.
+ * @sizeof_priv bytes are allocated for private use.
+ *
+ * The returned pointer must be assigned to each netdev's
+ * ieee80211_ptr for proper operation.
+ */
+struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv);
+
+/**
+ * wiphy_register - register a wiphy with cfg80211
+ *
+ * @wiphy: The wiphy to register.
+ *
+ * Returns a non-negative wiphy index or a negative error code.
+ */
+extern int wiphy_register(struct wiphy *wiphy);
+
+/**
+ * wiphy_unregister - deregister a wiphy from cfg80211
+ *
+ * @wiphy: The wiphy to unregister.
+ *
+ * After this call, no more requests can be made with this priv
+ * pointer, but the call may sleep to wait for an outstanding
+ * request that is being handled.
+ */
+extern void wiphy_unregister(struct wiphy *wiphy);
+
+/**
+ * wiphy_free - free wiphy
+ *
+ * @wiphy: The wiphy to free
+ */
+extern void wiphy_free(struct wiphy *wiphy);
+
+/**
+ * struct wireless_dev - wireless per-netdev state
+ *
+ * This structure must be allocated by the driver/stack
+ * that uses the ieee80211_ptr field in struct net_device
+ * (this is intentional so it can be allocated along with
+ * the netdev.)
+ *
+ * @wiphy: pointer to hardware description
+ * @iftype: interface type
+ * @list: (private) Used to collect the interfaces
+ * @netdev: (private) Used to reference back to the netdev
+ * @current_bss: (private) Used by the internal configuration code
+ * @bssid: (private) Used by the internal configuration code
+ * @ssid: (private) Used by the internal configuration code
+ * @ssid_len: (private) Used by the internal configuration code
+ * @wext: (private) Used by the internal wireless extensions compat code
+ * @wext_bssid: (private) Used by the internal wireless extensions compat code
+ */
+struct wireless_dev {
+ struct wiphy *wiphy;
+ enum nl80211_iftype iftype;
+
+ /* private to the generic wireless code */
+ struct list_head list;
+ struct net_device *netdev;
+
+ /* currently used for IBSS - might be rearranged in the future */
+ struct cfg80211_bss *current_bss;
+ u8 bssid[ETH_ALEN];
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 ssid_len;
+
+#ifdef CONFIG_WIRELESS_EXT
+ /* wext data */
+ struct {
+ struct cfg80211_ibss_params ibss;
+ u8 bssid[ETH_ALEN];
+ s8 default_key, default_mgmt_key;
+ } wext;
+#endif
+};
+
+/**
+ * wdev_priv - return wiphy priv from wireless_dev
+ *
+ * @wdev: The wireless device whose wiphy's priv pointer to return
+ */
+static inline void *wdev_priv(struct wireless_dev *wdev)
+{
+ BUG_ON(!wdev);
+ return wiphy_priv(wdev->wiphy);
+}
+
+/*
+ * Utility functions
+ */
+
+/**
+ * ieee80211_channel_to_frequency - convert channel number to frequency
+ */
+extern int ieee80211_channel_to_frequency(int chan);
+
+/**
+ * ieee80211_frequency_to_channel - convert frequency to channel number
+ */
+extern int ieee80211_frequency_to_channel(int freq);
+
+/*
+ * Name indirection necessary because the ieee80211 code also has
+ * a function named "ieee80211_get_channel", so if you include
+ * cfg80211's header file you get cfg80211's version, if you try
+ * to include both header files you'll (rightfully!) get a symbol
+ * clash.
+ */
+extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
+ int freq);
+/**
+ * ieee80211_get_channel - get channel struct from wiphy for specified frequency
+ */
+static inline struct ieee80211_channel *
+ieee80211_get_channel(struct wiphy *wiphy, int freq)
+{
+ return __ieee80211_get_channel(wiphy, freq);
+}
+
+/**
+ * ieee80211_get_response_rate - get basic rate for a given rate
+ *
+ * @sband: the band to look for rates in
+ * @basic_rates: bitmap of basic rates
+ * @bitrate: the bitrate for which to find the basic rate
+ *
+ * This function returns the basic rate corresponding to a given
+ * bitrate, that is the next lower bitrate contained in the basic
+ * rate map, which is, for this function, given as a bitmap of
+ * indices of rates in the band's bitrate table.
+ */
+struct ieee80211_rate *
+ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
+ u32 basic_rates, int bitrate);
+
+/*
+ * Radiotap parsing functions -- for controlled injection support
+ *
+ * Implemented in net/wireless/radiotap.c
+ * Documentation in Documentation/networking/radiotap-headers.txt
+ */
+
+/**
+ * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
+ * @rtheader: pointer to the radiotap header we are walking through
+ * @max_length: length of radiotap header in cpu byte ordering
+ * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg
+ * @this_arg: pointer to current radiotap arg
+ * @arg_index: internal next argument index
+ * @arg: internal next argument pointer
+ * @next_bitmap: internal pointer to next present u32
+ * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
+ */
+
+struct ieee80211_radiotap_iterator {
+ struct ieee80211_radiotap_header *rtheader;
+ int max_length;
+ int this_arg_index;
+ u8 *this_arg;
+
+ int arg_index;
+ u8 *arg;
+ __le32 *next_bitmap;
+ u32 bitmap_shifter;
+};
+
+extern int ieee80211_radiotap_iterator_init(
+ struct ieee80211_radiotap_iterator *iterator,
+ struct ieee80211_radiotap_header *radiotap_header,
+ int max_length);
+
+extern int ieee80211_radiotap_iterator_next(
+ struct ieee80211_radiotap_iterator *iterator);
+
+/*
+ * Regulatory helper functions for wiphys
+ */
+
+/**
+ * regulatory_hint - driver hint to the wireless core a regulatory domain
+ * @wiphy: the wireless device giving the hint (used only for reporting
+ * conflicts)
+ * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
+ * should be in. If @rd is set this should be NULL. Note that if you
+ * set this to NULL you should still set rd->alpha2 to some accepted
+ * alpha2.
+ *
+ * Wireless drivers can use this function to hint to the wireless core
+ * what it believes should be the current regulatory domain by
+ * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
+ * domain should be in or by providing a completely build regulatory domain.
+ * If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried
+ * for a regulatory domain structure for the respective country.
+ *
+ * The wiphy must have been registered to cfg80211 prior to this call.
+ * For cfg80211 drivers this means you must first use wiphy_register(),
+ * for mac80211 drivers you must first use ieee80211_register_hw().
+ *
+ * Drivers should check the return value, its possible you can get
+ * an -ENOMEM.
+ */
+extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
+
+/**
+ * regulatory_hint_11d - hints a country IE as a regulatory domain
+ * @wiphy: the wireless device giving the hint (used only for reporting
+ * conflicts)
+ * @country_ie: pointer to the country IE
+ * @country_ie_len: length of the country IE
+ *
+ * We will intersect the rd with the what CRDA tells us should apply
+ * for the alpha2 this country IE belongs to, this prevents APs from
+ * sending us incorrect or outdated information against a country.
+ */
+extern void regulatory_hint_11d(struct wiphy *wiphy,
+ u8 *country_ie,
+ u8 country_ie_len);
+/**
+ * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain
+ * @wiphy: the wireless device we want to process the regulatory domain on
+ * @regd: the custom regulatory domain to use for this wiphy
+ *
+ * Drivers can sometimes have custom regulatory domains which do not apply
+ * to a specific country. Drivers can use this to apply such custom regulatory
+ * domains. This routine must be called prior to wiphy registration. The
+ * custom regulatory domain will be trusted completely and as such previous
+ * default channel settings will be disregarded. If no rule is found for a
+ * channel on the regulatory domain the channel will be disabled.
+ */
+extern void wiphy_apply_custom_regulatory(
+ struct wiphy *wiphy,
+ const struct ieee80211_regdomain *regd);
+
+/**
+ * freq_reg_info - get regulatory information for the given frequency
+ * @wiphy: the wiphy for which we want to process this rule for
+ * @center_freq: Frequency in KHz for which we want regulatory information for
+ * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one
+ * you can set this to 0. If this frequency is allowed we then set
+ * this value to the maximum allowed bandwidth.
+ * @reg_rule: the regulatory rule which we have for this frequency
+ *
+ * Use this function to get the regulatory rule for a specific frequency on
+ * a given wireless device. If the device has a specific regulatory domain
+ * it wants to follow we respect that unless a country IE has been received
+ * and processed already.
+ *
+ * Returns 0 if it was able to find a valid regulatory rule which does
+ * apply to the given center_freq otherwise it returns non-zero. It will
+ * also return -ERANGE if we determine the given center_freq does not even have
+ * a regulatory rule for a frequency range in the center_freq's band. See
+ * freq_in_rule_band() for our current definition of a band -- this is purely
+ * subjective and right now its 802.11 specific.
+ */
+extern int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth,
+ const struct ieee80211_reg_rule **reg_rule);
+
+/*
+ * Temporary wext handlers & helper functions
+ *
+ * In the future cfg80211 will simply assign the entire wext handler
+ * structure to netdevs it manages, but we're not there yet.
+ */
int cfg80211_wext_giwname(struct net_device *dev,
struct iw_request_info *info,
char *name, char *extra);
@@ -834,9 +1342,66 @@ int cfg80211_wext_siwscan(struct net_device *dev,
int cfg80211_wext_giwscan(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra);
+int cfg80211_wext_siwmlme(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra);
int cfg80211_wext_giwrange(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra);
+int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_siwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid);
+int cfg80211_ibss_wext_giwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid);
+int cfg80211_ibss_wext_siwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra);
+int cfg80211_ibss_wext_giwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra);
+
+struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
+ struct iw_freq *freq);
+
+int cfg80211_wext_siwrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra);
+int cfg80211_wext_giwrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra);
+int cfg80211_wext_siwfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra);
+int cfg80211_wext_giwfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra);
+int cfg80211_wext_siwretry(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra);
+int cfg80211_wext_giwretry(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra);
+int cfg80211_wext_siwencodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *extra);
+int cfg80211_wext_siwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *keybuf);
+int cfg80211_wext_giwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *keybuf);
+
+/*
+ * callbacks for asynchronous cfg80211 methods, notification
+ * functions and BSS handling helpers
+ */
/**
* cfg80211_scan_done - notify that scan finished
@@ -864,6 +1429,14 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
struct ieee80211_mgmt *mgmt, size_t len,
s32 signal, gfp_t gfp);
+struct cfg80211_bss*
+cfg80211_inform_bss(struct wiphy *wiphy,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
+ u64 timestamp, u16 capability, u16 beacon_interval,
+ const u8 *ie, size_t ielen,
+ s32 signal, gfp_t gfp);
+
struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
struct ieee80211_channel *channel,
const u8 *bssid,
@@ -883,6 +1456,7 @@ struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
const u8 *meshid, size_t meshidlen,
const u8 *meshcfg);
void cfg80211_put_bss(struct cfg80211_bss *bss);
+
/**
* cfg80211_unlink_bss - unlink BSS from internal data structures
* @wiphy: the wiphy
@@ -902,44 +1476,62 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
* @len: length of the frame data
*
* This function is called whenever an authentication has been processed in
- * station mode.
+ * station mode. The driver is required to call either this function or
+ * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth()
+ * call.
*/
void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
/**
+ * cfg80211_send_auth_timeout - notification of timed out authentication
+ * @dev: network device
+ * @addr: The MAC address of the device with which the authentication timed out
+ */
+void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
+
+/**
* cfg80211_send_rx_assoc - notification of processed association
* @dev: network device
* @buf: (re)association response frame (header + body)
* @len: length of the frame data
*
* This function is called whenever a (re)association response has been
- * processed in station mode.
+ * processed in station mode. The driver is required to call either this
+ * function or cfg80211_send_assoc_timeout() to indicate the result of
+ * cfg80211_ops::assoc() call.
*/
void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);
/**
- * cfg80211_send_rx_deauth - notification of processed deauthentication
+ * cfg80211_send_assoc_timeout - notification of timed out association
+ * @dev: network device
+ * @addr: The MAC address of the device with which the association timed out
+ */
+void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);
+
+/**
+ * cfg80211_send_deauth - notification of processed deauthentication
* @dev: network device
* @buf: deauthentication frame (header + body)
* @len: length of the frame data
*
* This function is called whenever deauthentication has been processed in
- * station mode.
+ * station mode. This includes both received deauthentication frames and
+ * locally generated ones.
*/
-void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf,
- size_t len);
+void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
/**
- * cfg80211_send_rx_disassoc - notification of processed disassociation
+ * cfg80211_send_disassoc - notification of processed disassociation
* @dev: network device
* @buf: disassociation response frame (header + body)
* @len: length of the frame data
*
* This function is called whenever disassociation has been processed in
- * station mode.
+ * station mode. This includes both received disassociation frames and locally
+ * generated ones.
*/
-void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf,
- size_t len);
+void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len);
/**
* cfg80211_hold_bss - exclude bss from expiration
@@ -958,4 +1550,36 @@ void cfg80211_hold_bss(struct cfg80211_bss *bss);
*/
void cfg80211_unhold_bss(struct cfg80211_bss *bss);
+/**
+ * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
+ * @dev: network device
+ * @addr: The source MAC address of the frame
+ * @key_type: The key type that the received frame used
+ * @key_id: Key identifier (0..3)
+ * @tsc: The TSC value of the frame that generated the MIC failure (6 octets)
+ *
+ * This function is called whenever the local MAC detects a MIC failure in a
+ * received frame. This matches with MLME-MICHAELMICFAILURE.indication()
+ * primitive.
+ */
+void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
+ enum nl80211_key_type key_type, int key_id,
+ const u8 *tsc);
+
+/**
+ * cfg80211_ibss_joined - notify cfg80211 that device joined an IBSS
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the IBSS joined
+ * @gfp: allocation flags
+ *
+ * This function notifies cfg80211 that the device joined an IBSS or
+ * switched to a different BSSID. Before this function can be called,
+ * either a beacon has to have been received from the IBSS, or one of
+ * the cfg80211_inform_bss{,_frame} functions must have been called
+ * with the locally generated beacon -- this guarantees that there is
+ * always a scan result for this IBSS. cfg80211 will handle the rest.
+ */
+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
+
#endif /* __NET_CFG80211_H */
diff --git a/include/net/ip.h b/include/net/ip.h
index 4ac7577f98d0..72c36926c26d 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -168,7 +168,10 @@ struct ipv4_config
extern struct ipv4_config ipv4_config;
#define IP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.ip_statistics, field)
#define IP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.ip_statistics, field)
+#define IP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.ip_statistics, field, val)
#define IP_ADD_STATS_BH(net, field, val) SNMP_ADD_STATS_BH((net)->mib.ip_statistics, field, val)
+#define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS((net)->mib.ip_statistics, field, val)
+#define IP_UPD_PO_STATS_BH(net, field, val) SNMP_UPD_PO_STATS_BH((net)->mib.ip_statistics, field, val)
#define NET_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.net_statistics, field)
#define NET_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.net_statistics, field)
#define NET_INC_STATS_USER(net, field) SNMP_INC_STATS_USER((net)->mib.net_statistics, field)
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 8b12667f7a2b..ef91fe924ba4 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -124,14 +124,12 @@ struct fib_result_nl {
#ifdef CONFIG_IP_ROUTE_MULTIPATH
#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
-#define FIB_RES_RESET(res) ((res).nh_sel = 0)
#define FIB_TABLE_HASHSZ 2
#else /* CONFIG_IP_ROUTE_MULTIPATH */
#define FIB_RES_NH(res) ((res).fi->fib_nh[0])
-#define FIB_RES_RESET(res)
#define FIB_TABLE_HASHSZ 256
@@ -145,7 +143,6 @@ struct fib_result_nl {
struct fib_table {
struct hlist_node tb_hlist;
u32 tb_id;
- unsigned tb_stamp;
int tb_default;
int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
int (*tb_insert)(struct fib_table *, struct fib_config *);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index c1f16fc49ade..f27fd83d67d8 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -126,15 +126,28 @@ extern struct ctl_path net_ipv6_ctl_path[];
SNMP_ADD_STATS##modifier((net)->mib.statname##_statistics, (field), (val));\
})
+#define _DEVUPD(net, statname, modifier, idev, field, val) \
+({ \
+ struct inet6_dev *_idev = (idev); \
+ if (likely(_idev != NULL)) \
+ SNMP_UPD_PO_STATS##modifier((_idev)->stats.statname, field, (val)); \
+ SNMP_UPD_PO_STATS##modifier((net)->mib.statname##_statistics, field, (val));\
+})
+
/* MIBs */
#define IP6_INC_STATS(net, idev,field) \
_DEVINC(net, ipv6, , idev, field)
#define IP6_INC_STATS_BH(net, idev,field) \
_DEVINC(net, ipv6, _BH, idev, field)
+#define IP6_ADD_STATS(net, idev,field,val) \
+ _DEVADD(net, ipv6, , idev, field, val)
#define IP6_ADD_STATS_BH(net, idev,field,val) \
_DEVADD(net, ipv6, _BH, idev, field, val)
-
+#define IP6_UPD_PO_STATS(net, idev,field,val) \
+ _DEVUPD(net, ipv6, , idev, field, val)
+#define IP6_UPD_PO_STATS_BH(net, idev,field,val) \
+ _DEVUPD(net, ipv6, _BH, idev, field, val)
#define ICMP6_INC_STATS(net, idev, field) \
_DEVINC(net, icmpv6, , idev, field)
#define ICMP6_INC_STATS_BH(net, idev, field) \
diff --git a/include/net/iucv/af_iucv.h b/include/net/iucv/af_iucv.h
index 85f80eadfa35..21ee49ffcbaf 100644
--- a/include/net/iucv/af_iucv.h
+++ b/include/net/iucv/af_iucv.h
@@ -73,8 +73,17 @@ struct iucv_sock {
struct sk_buff_head backlog_skb_q;
struct sock_msg_q message_q;
unsigned int send_tag;
+ u8 flags;
+ u16 msglimit;
};
+/* iucv socket options (SOL_IUCV) */
+#define SO_IPRMDATA_MSG 0x0080 /* send/recv IPRM_DATA msgs */
+#define SO_MSGLIMIT 0x1000 /* get/set IUCV MSGLIMIT */
+
+/* iucv related control messages (scm) */
+#define SCM_IUCV_TRGCLS 0x0001 /* target class control message */
+
struct iucv_sock_list {
struct hlist_head head;
rwlock_t lock;
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 3b83a80e3fe0..d10ed1776fcd 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -19,7 +19,6 @@
#include <linux/wireless.h>
#include <linux/device.h>
#include <linux/ieee80211.h>
-#include <net/wireless.h>
#include <net/cfg80211.h>
/**
@@ -74,22 +73,6 @@
*/
/**
- * struct ieee80211_ht_bss_info - describing BSS's HT characteristics
- *
- * This structure describes most essential parameters needed
- * to describe 802.11n HT characteristics in a BSS.
- *
- * @primary_channel: channel number of primery channel
- * @bss_cap: 802.11n's general BSS capabilities (e.g. channel width)
- * @bss_op_mode: 802.11n's BSS operation modes (e.g. HT protection)
- */
-struct ieee80211_ht_bss_info {
- u8 primary_channel;
- u8 bss_cap; /* use IEEE80211_HT_IE_CHA_ */
- u8 bss_op_mode; /* use IEEE80211_HT_IE_ */
-};
-
-/**
* enum ieee80211_max_queues - maximum number of queues
*
* @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
@@ -150,6 +133,13 @@ struct ieee80211_low_level_stats {
* @BSS_CHANGED_ERP_SLOT: slot timing changed
* @BSS_CHANGED_HT: 802.11n parameters changed
* @BSS_CHANGED_BASIC_RATES: Basic rateset changed
+ * @BSS_CHANGED_BEACON_INT: Beacon interval changed
+ * @BSS_CHANGED_BSSID: BSSID changed, for whatever
+ * reason (IBSS and managed mode)
+ * @BSS_CHANGED_BEACON: Beacon data changed, retrieve
+ * new beacon (beaconing modes)
+ * @BSS_CHANGED_BEACON_ENABLED: Beaconing should be
+ * enabled/disabled (beaconing modes)
*/
enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0,
@@ -158,14 +148,10 @@ enum ieee80211_bss_change {
BSS_CHANGED_ERP_SLOT = 1<<3,
BSS_CHANGED_HT = 1<<4,
BSS_CHANGED_BASIC_RATES = 1<<5,
-};
-
-/**
- * struct ieee80211_bss_ht_conf - BSS's changing HT configuration
- * @operation_mode: HT operation mode (like in &struct ieee80211_ht_info)
- */
-struct ieee80211_bss_ht_conf {
- u16 operation_mode;
+ BSS_CHANGED_BEACON_INT = 1<<6,
+ BSS_CHANGED_BSSID = 1<<7,
+ BSS_CHANGED_BEACON = 1<<8,
+ BSS_CHANGED_BEACON_ENABLED = 1<<9,
};
/**
@@ -191,8 +177,13 @@ struct ieee80211_bss_ht_conf {
* @basic_rates: bitmap of basic rates, each bit stands for an
* index into the rate table configured by the driver in
* the current band.
+ * @bssid: The BSSID for this BSS
+ * @enable_beacon: whether beaconing should be enabled or not
+ * @ht_operation_mode: HT operation mode (like in &struct ieee80211_ht_info).
+ * This field is only valid when the channel type is one of the HT types.
*/
struct ieee80211_bss_conf {
+ const u8 *bssid;
/* association related data */
bool assoc;
u16 aid;
@@ -200,12 +191,13 @@ struct ieee80211_bss_conf {
bool use_cts_prot;
bool use_short_preamble;
bool use_short_slot;
+ bool enable_beacon;
u8 dtim_period;
u16 beacon_int;
u16 assoc_capability;
u64 timestamp;
u32 basic_rates;
- struct ieee80211_bss_ht_conf ht;
+ u16 ht_operation_mode;
};
/**
@@ -518,11 +510,17 @@ struct ieee80211_rx_status {
* Flags to define PHY configuration options
*
* @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported)
- * @IEEE80211_CONF_PS: Enable 802.11 power save mode
+ * @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only)
+ * @IEEE80211_CONF_IDLE: The device is running, but idle; if the flag is set
+ * the driver should be prepared to handle configuration requests but
+ * may turn the device off as much as possible. Typically, this flag will
+ * be set when an interface is set UP but not associated or scanning, but
+ * it can also be unset in that case when monitor interfaces are active.
*/
enum ieee80211_conf_flags {
IEEE80211_CONF_RADIOTAP = (1<<0),
IEEE80211_CONF_PS = (1<<1),
+ IEEE80211_CONF_IDLE = (1<<2),
};
@@ -530,40 +528,60 @@ enum ieee80211_conf_flags {
* enum ieee80211_conf_changed - denotes which configuration changed
*
* @IEEE80211_CONF_CHANGE_RADIO_ENABLED: the value of radio_enabled changed
- * @IEEE80211_CONF_CHANGE_BEACON_INTERVAL: the beacon interval changed
+ * @_IEEE80211_CONF_CHANGE_BEACON_INTERVAL: DEPRECATED
* @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed
* @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed
- * @IEEE80211_CONF_CHANGE_PS: the PS flag changed
- * @IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT: the dynamic PS timeout changed
+ * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed
* @IEEE80211_CONF_CHANGE_POWER: the TX power changed
* @IEEE80211_CONF_CHANGE_CHANNEL: the channel/channel_type changed
* @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed
+ * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed
*/
enum ieee80211_conf_changed {
IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0),
- IEEE80211_CONF_CHANGE_BEACON_INTERVAL = BIT(1),
+ _IEEE80211_CONF_CHANGE_BEACON_INTERVAL = BIT(1),
IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2),
IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3),
IEEE80211_CONF_CHANGE_PS = BIT(4),
- IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT = BIT(5),
- IEEE80211_CONF_CHANGE_POWER = BIT(6),
- IEEE80211_CONF_CHANGE_CHANNEL = BIT(7),
- IEEE80211_CONF_CHANGE_RETRY_LIMITS = BIT(8),
+ IEEE80211_CONF_CHANGE_POWER = BIT(5),
+ IEEE80211_CONF_CHANGE_CHANNEL = BIT(6),
+ IEEE80211_CONF_CHANGE_RETRY_LIMITS = BIT(7),
+ IEEE80211_CONF_CHANGE_IDLE = BIT(8),
};
+static inline __deprecated enum ieee80211_conf_changed
+__IEEE80211_CONF_CHANGE_BEACON_INTERVAL(void)
+{
+ return _IEEE80211_CONF_CHANGE_BEACON_INTERVAL;
+}
+#define IEEE80211_CONF_CHANGE_BEACON_INTERVAL \
+ __IEEE80211_CONF_CHANGE_BEACON_INTERVAL()
+
/**
* struct ieee80211_conf - configuration of the device
*
* This struct indicates how the driver shall configure the hardware.
*
+ * @flags: configuration flags defined above
+ *
* @radio_enabled: when zero, driver is required to switch off the radio.
* @beacon_int: beacon interval (TODO make interface config)
+ *
* @listen_interval: listen interval in units of beacon interval
- * @flags: configuration flags defined above
+ * @max_sleep_period: the maximum number of beacon intervals to sleep for
+ * before checking the beacon for a TIM bit (managed mode only); this
+ * value will be only achievable between DTIM frames, the hardware
+ * needs to check for the multicast traffic bit in DTIM beacons.
+ * This variable is valid only when the CONF_PS flag is set.
+ * @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the
+ * powersave documentation below. This variable is valid only when
+ * the CONF_PS flag is set.
+ *
* @power_level: requested transmit power (in dBm)
- * @dynamic_ps_timeout: dynamic powersave timeout (in ms)
+ *
* @channel: the channel to tune to
* @channel_type: the channel (HT) type
+ *
* @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame
* (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11,
* but actually means the number of transmissions not the number of retries
@@ -575,6 +593,7 @@ struct ieee80211_conf {
int beacon_int;
u32 flags;
int power_level, dynamic_ps_timeout;
+ int max_sleep_period;
u16 listen_interval;
bool radio_enabled;
@@ -640,37 +659,6 @@ struct ieee80211_if_init_conf {
};
/**
- * enum ieee80211_if_conf_change - interface config change flags
- *
- * @IEEE80211_IFCC_BSSID: The BSSID changed.
- * @IEEE80211_IFCC_BEACON: The beacon for this interface changed
- * (currently AP and MESH only), use ieee80211_beacon_get().
- * @IEEE80211_IFCC_BEACON_ENABLED: The enable_beacon value changed.
- */
-enum ieee80211_if_conf_change {
- IEEE80211_IFCC_BSSID = BIT(0),
- IEEE80211_IFCC_BEACON = BIT(1),
- IEEE80211_IFCC_BEACON_ENABLED = BIT(2),
-};
-
-/**
- * struct ieee80211_if_conf - configuration of an interface
- *
- * @changed: parameters that have changed, see &enum ieee80211_if_conf_change.
- * @bssid: BSSID of the network we are associated to/creating.
- * @enable_beacon: Indicates whether beacons can be sent.
- * This is valid only for AP/IBSS/MESH modes.
- *
- * This structure is passed to the config_interface() callback of
- * &struct ieee80211_hw.
- */
-struct ieee80211_if_conf {
- u32 changed;
- const u8 *bssid;
- bool enable_beacon;
-};
-
-/**
* enum ieee80211_key_alg - key algorithm
* @ALG_WEP: WEP40 or WEP104
* @ALG_TKIP: TKIP
@@ -1109,11 +1097,9 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
* need software support for parsing the TIM bitmap. This is also supported
* by mac80211 by combining the %IEEE80211_HW_SUPPORTS_PS and
* %IEEE80211_HW_PS_NULLFUNC_STACK flags. The hardware is of course still
- * required to pass up beacons. Additionally, in this case, mac80211 will
- * wake up the hardware when multicast traffic is announced in the beacon.
- *
- * FIXME: I don't think we can be fast enough in software when we want to
- * receive multicast traffic?
+ * required to pass up beacons. The hardware is still required to handle
+ * waking up for multicast traffic; if it cannot the driver must handle that
+ * as best as it can, mac80211 is too slow.
*
* Dynamic powersave mode is an extension to normal powersave mode in which
* the hardware stays awake for a user-specified period of time after sending
@@ -1134,11 +1120,53 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
* way the host will only receive beacons where some relevant information
* (for example ERP protection or WMM settings) have changed.
*
- * Beacon filter support is informed with %IEEE80211_HW_BEACON_FILTER flag.
- * The driver needs to enable beacon filter support whenever power save is
- * enabled, that is %IEEE80211_CONF_PS is set. When power save is enabled,
- * the stack will not check for beacon miss at all and the driver needs to
- * notify about complete loss of beacons with ieee80211_beacon_loss().
+ * Beacon filter support is advertised with the %IEEE80211_HW_BEACON_FILTER
+ * hardware capability. The driver needs to enable beacon filter support
+ * whenever power save is enabled, that is %IEEE80211_CONF_PS is set. When
+ * power save is enabled, the stack will not check for beacon loss and the
+ * driver needs to notify about loss of beacons with ieee80211_beacon_loss().
+ *
+ * The time (or number of beacons missed) until the firmware notifies the
+ * driver of a beacon loss event (which in turn causes the driver to call
+ * ieee80211_beacon_loss()) should be configurable and will be controlled
+ * by mac80211 and the roaming algorithm in the future.
+ *
+ * Since there may be constantly changing information elements that nothing
+ * in the software stack cares about, we will, in the future, have mac80211
+ * tell the driver which information elements are interesting in the sense
+ * that we want to see changes in them. This will include
+ * - a list of information element IDs
+ * - a list of OUIs for the vendor information element
+ *
+ * Ideally, the hardware would filter out any beacons without changes in the
+ * requested elements, but if it cannot support that it may, at the expense
+ * of some efficiency, filter out only a subset. For example, if the device
+ * doesn't support checking for OUIs it should pass up all changes in all
+ * vendor information elements.
+ *
+ * Note that change, for the sake of simplification, also includes information
+ * elements appearing or disappearing from the beacon.
+ *
+ * Some hardware supports an "ignore list" instead, just make sure nothing
+ * that was requested is on the ignore list, and include commonly changing
+ * information element IDs in the ignore list, for example 11 (BSS load) and
+ * the various vendor-assigned IEs with unknown contents (128, 129, 133-136,
+ * 149, 150, 155, 156, 173, 176, 178, 179, 219); for forward compatibility
+ * it could also include some currently unused IDs.
+ *
+ *
+ * In addition to these capabilities, hardware should support notifying the
+ * host of changes in the beacon RSSI. This is relevant to implement roaming
+ * when no traffic is flowing (when traffic is flowing we see the RSSI of
+ * the received data packets). This can consist in notifying the host when
+ * the RSSI changes significantly or when it drops below or rises above
+ * configurable thresholds. In the future these thresholds will also be
+ * configured by mac80211 (which gets them from userspace) to implement
+ * them as the roaming algorithm requires.
+ *
+ * If the hardware cannot implement this, the driver should ask it to
+ * periodically pass beacon frames to the host so that software can do the
+ * signal strength threshold checking.
*/
/**
@@ -1298,10 +1326,6 @@ enum ieee80211_ampdu_mlme_action {
* This function should never fail but returns a negative error code
* if it does.
*
- * @config_interface: Handler for configuration requests related to interfaces
- * (e.g. BSSID changes.)
- * Returns a negative error code which will be seen in userspace.
- *
* @bss_info_changed: Handler for configuration requests related to BSS
* parameters that may vary during BSS's lifespan, and may affect low
* level driver (e.g. assoc/disassoc status, erp parameters).
@@ -1330,11 +1354,14 @@ enum ieee80211_ampdu_mlme_action {
* the scan state machine in stack. The scan must honour the channel
* configuration done by the regulatory agent in the wiphy's
* registered bands. The hardware (or the driver) needs to make sure
- * that power save is disabled. When the scan finishes,
- * ieee80211_scan_completed() must be called; note that it also must
- * be called when the scan cannot finish because the hardware is
- * turned off! Anything else is a bug! Returns a negative error code
- * which will be seen in userspace.
+ * that power save is disabled.
+ * The @req ie/ie_len members are rewritten by mac80211 to contain the
+ * entire IEs after the SSID, so that drivers need not look at these
+ * at all but just send them after the SSID -- mac80211 includes the
+ * (extended) supported rates and HT information (where applicable).
+ * When the scan finishes, ieee80211_scan_completed() must be called;
+ * note that it also must be called when the scan cannot finish due to
+ * any error unless this callback returned a negative error code.
*
* @sw_scan_start: Notifier function that is called just before a software scan
* is started. Can be NULL, if the driver doesn't need this notification.
@@ -1400,9 +1427,6 @@ struct ieee80211_ops {
void (*remove_interface)(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf);
int (*config)(struct ieee80211_hw *hw, u32 changed);
- int (*config_interface)(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf);
void (*bss_info_changed)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
@@ -1572,6 +1596,20 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw);
*/
void ieee80211_free_hw(struct ieee80211_hw *hw);
+/**
+ * ieee80211_restart_hw - restart hardware completely
+ *
+ * Call this function when the hardware was restarted for some reason
+ * (hardware error, ...) and the driver is unable to restore its state
+ * by itself. mac80211 assumes that at this point the driver/hardware
+ * is completely uninitialised and stopped, it starts the process by
+ * calling the ->start() operation. The driver will need to reset all
+ * internal state that it has prior to calling this function.
+ *
+ * @hw: the hardware to restart
+ */
+void ieee80211_restart_hw(struct ieee80211_hw *hw);
+
/* trick to avoid symbol clashes with the ieee80211 subsystem */
void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ieee80211_rx_status *status);
diff --git a/include/net/regulatory.h b/include/net/regulatory.h
new file mode 100644
index 000000000000..47995b81c5d7
--- /dev/null
+++ b/include/net/regulatory.h
@@ -0,0 +1,101 @@
+#ifndef __NET_REGULATORY_H
+#define __NET_REGULATORY_H
+/*
+ * regulatory support structures
+ *
+ * Copyright 2008-2009 Luis R. Rodriguez <lrodriguez@atheros.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.
+ */
+
+
+/**
+ * enum environment_cap - Environment parsed from country IE
+ * @ENVIRON_ANY: indicates country IE applies to both indoor and
+ * outdoor operation.
+ * @ENVIRON_INDOOR: indicates country IE applies only to indoor operation
+ * @ENVIRON_OUTDOOR: indicates country IE applies only to outdoor operation
+ */
+enum environment_cap {
+ ENVIRON_ANY,
+ ENVIRON_INDOOR,
+ ENVIRON_OUTDOOR,
+};
+
+/**
+ * struct regulatory_request - used to keep track of regulatory requests
+ *
+ * @wiphy_idx: this is set if this request's initiator is
+ * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
+ * can be used by the wireless core to deal with conflicts
+ * and potentially inform users of which devices specifically
+ * cased the conflicts.
+ * @initiator: indicates who sent this request, could be any of
+ * of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*)
+ * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
+ * regulatory domain. We have a few special codes:
+ * 00 - World regulatory domain
+ * 99 - built by driver but a specific alpha2 cannot be determined
+ * 98 - result of an intersection between two regulatory domains
+ * @intersect: indicates whether the wireless core should intersect
+ * the requested regulatory domain with the presently set regulatory
+ * domain.
+ * @country_ie_checksum: checksum of the last processed and accepted
+ * country IE
+ * @country_ie_env: lets us know if the AP is telling us we are outdoor,
+ * indoor, or if it doesn't matter
+ * @list: used to insert into the reg_requests_list linked list
+ */
+struct regulatory_request {
+ int wiphy_idx;
+ enum nl80211_reg_initiator initiator;
+ char alpha2[2];
+ bool intersect;
+ u32 country_ie_checksum;
+ enum environment_cap country_ie_env;
+ struct list_head list;
+};
+
+struct ieee80211_freq_range {
+ u32 start_freq_khz;
+ u32 end_freq_khz;
+ u32 max_bandwidth_khz;
+};
+
+struct ieee80211_power_rule {
+ u32 max_antenna_gain;
+ u32 max_eirp;
+};
+
+struct ieee80211_reg_rule {
+ struct ieee80211_freq_range freq_range;
+ struct ieee80211_power_rule power_rule;
+ u32 flags;
+};
+
+struct ieee80211_regdomain {
+ u32 n_reg_rules;
+ char alpha2[2];
+ struct ieee80211_reg_rule reg_rules[];
+};
+
+#define MHZ_TO_KHZ(freq) ((freq) * 1000)
+#define KHZ_TO_MHZ(freq) ((freq) / 1000)
+#define DBI_TO_MBI(gain) ((gain) * 100)
+#define MBI_TO_DBI(gain) ((gain) / 100)
+#define DBM_TO_MBM(gain) ((gain) * 100)
+#define MBM_TO_DBM(gain) ((gain) / 100)
+
+#define REG_RULE(start, end, bw, gain, eirp, reg_flags) \
+{ \
+ .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
+ .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \
+ .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \
+ .power_rule.max_antenna_gain = DBI_TO_MBI(gain),\
+ .power_rule.max_eirp = DBM_TO_MBM(eirp), \
+ .flags = reg_flags, \
+}
+
+#endif
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 57c93628695f..8c842e06bec8 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -153,6 +153,11 @@ struct linux_xfrm_mib {
per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]--; \
put_cpu(); \
} while (0)
+#define SNMP_ADD_STATS(mib, field, addend) \
+ do { \
+ per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field] += addend; \
+ put_cpu(); \
+ } while (0)
#define SNMP_ADD_STATS_BH(mib, field, addend) \
(per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend)
#define SNMP_ADD_STATS_USER(mib, field, addend) \
@@ -160,5 +165,17 @@ struct linux_xfrm_mib {
per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \
put_cpu(); \
} while (0)
-
+#define SNMP_UPD_PO_STATS(mib, basefield, addend) \
+ do { \
+ __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], get_cpu());\
+ ptr->mibs[basefield##PKTS]++; \
+ ptr->mibs[basefield##OCTETS] += addend;\
+ put_cpu(); \
+ } while (0)
+#define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \
+ do { \
+ __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id());\
+ ptr->mibs[basefield##PKTS]++; \
+ ptr->mibs[basefield##OCTETS] += addend;\
+ } while (0)
#endif
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 646dbe3962ea..19f4150f4d4d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -266,6 +266,19 @@ static inline int tcp_too_many_orphans(struct sock *sk, int num)
atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]);
}
+/* syncookies: remember time of last synqueue overflow */
+static inline void tcp_synq_overflow(struct sock *sk)
+{
+ tcp_sk(sk)->rx_opt.ts_recent_stamp = jiffies;
+}
+
+/* syncookies: no recent synqueue overflow on this listening socket? */
+static inline int tcp_synq_no_recent_overflow(const struct sock *sk)
+{
+ unsigned long last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
+ return time_after(jiffies, last_overflow + TCP_TIMEOUT_INIT);
+}
+
extern struct proto tcp_prot;
#define TCP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.tcp_statistics, field)
@@ -889,30 +902,32 @@ static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
{
struct tcp_sock *tp = tcp_sk(sk);
- if (!sysctl_tcp_low_latency && tp->ucopy.task) {
- __skb_queue_tail(&tp->ucopy.prequeue, skb);
- tp->ucopy.memory += skb->truesize;
- if (tp->ucopy.memory > sk->sk_rcvbuf) {
- struct sk_buff *skb1;
-
- BUG_ON(sock_owned_by_user(sk));
-
- while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) {
- sk_backlog_rcv(sk, skb1);
- NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPPREQUEUEDROPPED);
- }
-
- tp->ucopy.memory = 0;
- } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) {
- wake_up_interruptible(sk->sk_sleep);
- if (!inet_csk_ack_scheduled(sk))
- inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
- (3 * tcp_rto_min(sk)) / 4,
- TCP_RTO_MAX);
+ if (sysctl_tcp_low_latency || !tp->ucopy.task)
+ return 0;
+
+ __skb_queue_tail(&tp->ucopy.prequeue, skb);
+ tp->ucopy.memory += skb->truesize;
+ if (tp->ucopy.memory > sk->sk_rcvbuf) {
+ struct sk_buff *skb1;
+
+ BUG_ON(sock_owned_by_user(sk));
+
+ while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) {
+ sk_backlog_rcv(sk, skb1);
+ NET_INC_STATS_BH(sock_net(sk),
+ LINUX_MIB_TCPPREQUEUEDROPPED);
}
- return 1;
+
+ tp->ucopy.memory = 0;
+ } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) {
+ wake_up_interruptible_poll(sk->sk_sleep,
+ POLLIN | POLLRDNORM | POLLRDBAND);
+ if (!inet_csk_ack_scheduled(sk))
+ inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
+ (3 * tcp_rto_min(sk)) / 4,
+ TCP_RTO_MAX);
}
- return 0;
+ return 1;
}
diff --git a/include/net/wireless.h b/include/net/wireless.h
deleted file mode 100644
index 64a76208580c..000000000000
--- a/include/net/wireless.h
+++ /dev/null
@@ -1,472 +0,0 @@
-#ifndef __NET_WIRELESS_H
-#define __NET_WIRELESS_H
-
-/*
- * 802.11 device management
- *
- * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
- */
-
-#include <linux/netdevice.h>
-#include <linux/debugfs.h>
-#include <linux/list.h>
-#include <linux/ieee80211.h>
-#include <net/cfg80211.h>
-
-/**
- * enum ieee80211_band - supported frequency bands
- *
- * The bands are assigned this way because the supported
- * bitrates differ in these bands.
- *
- * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band
- * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7)
- */
-enum ieee80211_band {
- IEEE80211_BAND_2GHZ,
- IEEE80211_BAND_5GHZ,
-
- /* keep last */
- IEEE80211_NUM_BANDS
-};
-
-/**
- * enum ieee80211_channel_flags - channel flags
- *
- * Channel flags set by the regulatory control code.
- *
- * @IEEE80211_CHAN_DISABLED: This channel is disabled.
- * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted
- * on this channel.
- * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
- * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
- * @IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel
- * is not permitted.
- * @IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel
- * is not permitted.
- */
-enum ieee80211_channel_flags {
- IEEE80211_CHAN_DISABLED = 1<<0,
- IEEE80211_CHAN_PASSIVE_SCAN = 1<<1,
- IEEE80211_CHAN_NO_IBSS = 1<<2,
- IEEE80211_CHAN_RADAR = 1<<3,
- IEEE80211_CHAN_NO_FAT_ABOVE = 1<<4,
- IEEE80211_CHAN_NO_FAT_BELOW = 1<<5,
-};
-
-/**
- * struct ieee80211_channel - channel definition
- *
- * This structure describes a single channel for use
- * with cfg80211.
- *
- * @center_freq: center frequency in MHz
- * @max_bandwidth: maximum allowed bandwidth for this channel, in MHz
- * @hw_value: hardware-specific value for the channel
- * @flags: channel flags from &enum ieee80211_channel_flags.
- * @orig_flags: channel flags at registration time, used by regulatory
- * code to support devices with additional restrictions
- * @band: band this channel belongs to.
- * @max_antenna_gain: maximum antenna gain in dBi
- * @max_power: maximum transmission power (in dBm)
- * @beacon_found: helper to regulatory code to indicate when a beacon
- * has been found on this channel. Use regulatory_hint_found_beacon()
- * to enable this, this is is useful only on 5 GHz band.
- * @orig_mag: internal use
- * @orig_mpwr: internal use
- */
-struct ieee80211_channel {
- enum ieee80211_band band;
- u16 center_freq;
- u8 max_bandwidth;
- u16 hw_value;
- u32 flags;
- int max_antenna_gain;
- int max_power;
- bool beacon_found;
- u32 orig_flags;
- int orig_mag, orig_mpwr;
-};
-
-/**
- * enum ieee80211_rate_flags - rate flags
- *
- * Hardware/specification flags for rates. These are structured
- * in a way that allows using the same bitrate structure for
- * different bands/PHY modes.
- *
- * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short
- * preamble on this bitrate; only relevant in 2.4GHz band and
- * with CCK rates.
- * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate
- * when used with 802.11a (on the 5 GHz band); filled by the
- * core code when registering the wiphy.
- * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate
- * when used with 802.11b (on the 2.4 GHz band); filled by the
- * core code when registering the wiphy.
- * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate
- * when used with 802.11g (on the 2.4 GHz band); filled by the
- * core code when registering the wiphy.
- * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode.
- */
-enum ieee80211_rate_flags {
- IEEE80211_RATE_SHORT_PREAMBLE = 1<<0,
- IEEE80211_RATE_MANDATORY_A = 1<<1,
- IEEE80211_RATE_MANDATORY_B = 1<<2,
- IEEE80211_RATE_MANDATORY_G = 1<<3,
- IEEE80211_RATE_ERP_G = 1<<4,
-};
-
-/**
- * struct ieee80211_rate - bitrate definition
- *
- * This structure describes a bitrate that an 802.11 PHY can
- * operate with. The two values @hw_value and @hw_value_short
- * are only for driver use when pointers to this structure are
- * passed around.
- *
- * @flags: rate-specific flags
- * @bitrate: bitrate in units of 100 Kbps
- * @hw_value: driver/hardware value for this rate
- * @hw_value_short: driver/hardware value for this rate when
- * short preamble is used
- */
-struct ieee80211_rate {
- u32 flags;
- u16 bitrate;
- u16 hw_value, hw_value_short;
-};
-
-/**
- * struct ieee80211_sta_ht_cap - STA's HT capabilities
- *
- * This structure describes most essential parameters needed
- * to describe 802.11n HT capabilities for an STA.
- *
- * @ht_supported: is HT supported by the STA
- * @cap: HT capabilities map as described in 802.11n spec
- * @ampdu_factor: Maximum A-MPDU length factor
- * @ampdu_density: Minimum A-MPDU spacing
- * @mcs: Supported MCS rates
- */
-struct ieee80211_sta_ht_cap {
- u16 cap; /* use IEEE80211_HT_CAP_ */
- bool ht_supported;
- u8 ampdu_factor;
- u8 ampdu_density;
- struct ieee80211_mcs_info mcs;
-};
-
-/**
- * struct ieee80211_supported_band - frequency band definition
- *
- * This structure describes a frequency band a wiphy
- * is able to operate in.
- *
- * @channels: Array of channels the hardware can operate in
- * in this band.
- * @band: the band this structure represents
- * @n_channels: Number of channels in @channels
- * @bitrates: Array of bitrates the hardware can operate with
- * in this band. Must be sorted to give a valid "supported
- * rates" IE, i.e. CCK rates first, then OFDM.
- * @n_bitrates: Number of bitrates in @bitrates
- */
-struct ieee80211_supported_band {
- struct ieee80211_channel *channels;
- struct ieee80211_rate *bitrates;
- enum ieee80211_band band;
- int n_channels;
- int n_bitrates;
- struct ieee80211_sta_ht_cap ht_cap;
-};
-
-/**
- * struct wiphy - wireless hardware description
- * @idx: the wiphy index assigned to this item
- * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name>
- * @custom_regulatory: tells us the driver for this device
- * has its own custom regulatory domain and cannot identify the
- * ISO / IEC 3166 alpha2 it belongs to. When this is enabled
- * we will disregard the first regulatory hint (when the
- * initiator is %REGDOM_SET_BY_CORE).
- * @strict_regulatory: tells us the driver for this device will ignore
- * regulatory domain settings until it gets its own regulatory domain
- * via its regulatory_hint(). After its gets its own regulatory domain
- * it will only allow further regulatory domain settings to further
- * enhance compliance. For example if channel 13 and 14 are disabled
- * by this regulatory domain no user regulatory domain can enable these
- * channels at a later time. This can be used for devices which do not
- * have calibration information gauranteed for frequencies or settings
- * outside of its regulatory domain.
- * @reg_notifier: the driver's regulatory notification callback
- * @regd: the driver's regulatory domain, if one was requested via
- * the regulatory_hint() API. This can be used by the driver
- * on the reg_notifier() if it chooses to ignore future
- * regulatory domain changes caused by other drivers.
- * @signal_type: signal type reported in &struct cfg80211_bss.
- */
-struct wiphy {
- /* assign these fields before you register the wiphy */
-
- /* permanent MAC address */
- u8 perm_addr[ETH_ALEN];
-
- /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
- u16 interface_modes;
-
- bool custom_regulatory;
- bool strict_regulatory;
-
- enum cfg80211_signal_type signal_type;
-
- int bss_priv_size;
- u8 max_scan_ssids;
-
- /* If multiple wiphys are registered and you're handed e.g.
- * a regular netdev with assigned ieee80211_ptr, you won't
- * know whether it points to a wiphy your driver has registered
- * or not. Assign this to something global to your driver to
- * help determine whether you own this wiphy or not. */
- void *privid;
-
- struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
-
- /* Lets us get back the wiphy on the callback */
- int (*reg_notifier)(struct wiphy *wiphy,
- struct regulatory_request *request);
-
- /* fields below are read-only, assigned by cfg80211 */
-
- const struct ieee80211_regdomain *regd;
-
- /* the item in /sys/class/ieee80211/ points to this,
- * you need use set_wiphy_dev() (see below) */
- struct device dev;
-
- /* dir in debugfs: ieee80211/<wiphyname> */
- struct dentry *debugfsdir;
-
- char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
-};
-
-/** struct wireless_dev - wireless per-netdev state
- *
- * This structure must be allocated by the driver/stack
- * that uses the ieee80211_ptr field in struct net_device
- * (this is intentional so it can be allocated along with
- * the netdev.)
- *
- * @wiphy: pointer to hardware description
- * @iftype: interface type
- */
-struct wireless_dev {
- struct wiphy *wiphy;
- enum nl80211_iftype iftype;
-
- /* private to the generic wireless code */
- struct list_head list;
- struct net_device *netdev;
-};
-
-/**
- * wiphy_priv - return priv from wiphy
- */
-static inline void *wiphy_priv(struct wiphy *wiphy)
-{
- BUG_ON(!wiphy);
- return &wiphy->priv;
-}
-
-/**
- * set_wiphy_dev - set device pointer for wiphy
- */
-static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev)
-{
- wiphy->dev.parent = dev;
-}
-
-/**
- * wiphy_dev - get wiphy dev pointer
- */
-static inline struct device *wiphy_dev(struct wiphy *wiphy)
-{
- return wiphy->dev.parent;
-}
-
-/**
- * wiphy_name - get wiphy name
- */
-static inline const char *wiphy_name(struct wiphy *wiphy)
-{
- return dev_name(&wiphy->dev);
-}
-
-/**
- * wdev_priv - return wiphy priv from wireless_dev
- */
-static inline void *wdev_priv(struct wireless_dev *wdev)
-{
- BUG_ON(!wdev);
- return wiphy_priv(wdev->wiphy);
-}
-
-/**
- * wiphy_new - create a new wiphy for use with cfg80211
- *
- * create a new wiphy and associate the given operations with it.
- * @sizeof_priv bytes are allocated for private use.
- *
- * the returned pointer must be assigned to each netdev's
- * ieee80211_ptr for proper operation.
- */
-struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv);
-
-/**
- * wiphy_register - register a wiphy with cfg80211
- *
- * register the given wiphy
- *
- * Returns a non-negative wiphy index or a negative error code.
- */
-extern int wiphy_register(struct wiphy *wiphy);
-
-/**
- * wiphy_unregister - deregister a wiphy from cfg80211
- *
- * unregister a device with the given priv pointer.
- * After this call, no more requests can be made with this priv
- * pointer, but the call may sleep to wait for an outstanding
- * request that is being handled.
- */
-extern void wiphy_unregister(struct wiphy *wiphy);
-
-/**
- * wiphy_free - free wiphy
- */
-extern void wiphy_free(struct wiphy *wiphy);
-
-/**
- * ieee80211_channel_to_frequency - convert channel number to frequency
- */
-extern int ieee80211_channel_to_frequency(int chan);
-
-/**
- * ieee80211_frequency_to_channel - convert frequency to channel number
- */
-extern int ieee80211_frequency_to_channel(int freq);
-
-/*
- * Name indirection necessary because the ieee80211 code also has
- * a function named "ieee80211_get_channel", so if you include
- * cfg80211's header file you get cfg80211's version, if you try
- * to include both header files you'll (rightfully!) get a symbol
- * clash.
- */
-extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
- int freq);
-/**
- * ieee80211_get_channel - get channel struct from wiphy for specified frequency
- */
-static inline struct ieee80211_channel *
-ieee80211_get_channel(struct wiphy *wiphy, int freq)
-{
- return __ieee80211_get_channel(wiphy, freq);
-}
-
-/**
- * ieee80211_get_response_rate - get basic rate for a given rate
- *
- * @sband: the band to look for rates in
- * @basic_rates: bitmap of basic rates
- * @bitrate: the bitrate for which to find the basic rate
- *
- * This function returns the basic rate corresponding to a given
- * bitrate, that is the next lower bitrate contained in the basic
- * rate map, which is, for this function, given as a bitmap of
- * indices of rates in the band's bitrate table.
- */
-struct ieee80211_rate *
-ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
- u32 basic_rates, int bitrate);
-
-/**
- * regulatory_hint - driver hint to the wireless core a regulatory domain
- * @wiphy: the wireless device giving the hint (used only for reporting
- * conflicts)
- * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
- * should be in. If @rd is set this should be NULL. Note that if you
- * set this to NULL you should still set rd->alpha2 to some accepted
- * alpha2.
- *
- * Wireless drivers can use this function to hint to the wireless core
- * what it believes should be the current regulatory domain by
- * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
- * domain should be in or by providing a completely build regulatory domain.
- * If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried
- * for a regulatory domain structure for the respective country.
- *
- * The wiphy must have been registered to cfg80211 prior to this call.
- * For cfg80211 drivers this means you must first use wiphy_register(),
- * for mac80211 drivers you must first use ieee80211_register_hw().
- *
- * Drivers should check the return value, its possible you can get
- * an -ENOMEM.
- */
-extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
-
-/**
- * regulatory_hint_11d - hints a country IE as a regulatory domain
- * @wiphy: the wireless device giving the hint (used only for reporting
- * conflicts)
- * @country_ie: pointer to the country IE
- * @country_ie_len: length of the country IE
- *
- * We will intersect the rd with the what CRDA tells us should apply
- * for the alpha2 this country IE belongs to, this prevents APs from
- * sending us incorrect or outdated information against a country.
- */
-extern void regulatory_hint_11d(struct wiphy *wiphy,
- u8 *country_ie,
- u8 country_ie_len);
-/**
- * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain
- * @wiphy: the wireless device we want to process the regulatory domain on
- * @regd: the custom regulatory domain to use for this wiphy
- *
- * Drivers can sometimes have custom regulatory domains which do not apply
- * to a specific country. Drivers can use this to apply such custom regulatory
- * domains. This routine must be called prior to wiphy registration. The
- * custom regulatory domain will be trusted completely and as such previous
- * default channel settings will be disregarded. If no rule is found for a
- * channel on the regulatory domain the channel will be disabled.
- */
-extern void wiphy_apply_custom_regulatory(
- struct wiphy *wiphy,
- const struct ieee80211_regdomain *regd);
-
-/**
- * freq_reg_info - get regulatory information for the given frequency
- * @wiphy: the wiphy for which we want to process this rule for
- * @center_freq: Frequency in KHz for which we want regulatory information for
- * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one
- * you can set this to 0. If this frequency is allowed we then set
- * this value to the maximum allowed bandwidth.
- * @reg_rule: the regulatory rule which we have for this frequency
- *
- * Use this function to get the regulatory rule for a specific frequency on
- * a given wireless device. If the device has a specific regulatory domain
- * it wants to follow we respect that unless a country IE has been received
- * and processed already.
- *
- * Returns 0 if it was able to find a valid regulatory rule which does
- * apply to the given center_freq otherwise it returns non-zero. It will
- * also return -ERANGE if we determine the given center_freq does not even have
- * a regulatory rule for a frequency range in the center_freq's band. See
- * freq_in_rule_band() for our current definition of a band -- this is purely
- * subjective and right now its 802.11 specific.
- */
-extern int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth,
- const struct ieee80211_reg_rule **reg_rule);
-
-#endif /* __NET_WIRELESS_H */
diff --git a/include/scsi/Kbuild b/include/scsi/Kbuild
new file mode 100644
index 000000000000..33b2750e9283
--- /dev/null
+++ b/include/scsi/Kbuild
@@ -0,0 +1,4 @@
+header-y += scsi.h
+header-y += scsi_netlink.h
+header-y += scsi_netlink_fc.h
+header-y += scsi_bsg_fc.h
diff --git a/include/scsi/scsi_bsg_fc.h b/include/scsi/scsi_bsg_fc.h
new file mode 100644
index 000000000000..a4b233318179
--- /dev/null
+++ b/include/scsi/scsi_bsg_fc.h
@@ -0,0 +1,322 @@
+/*
+ * FC Transport BSG Interface
+ *
+ * Copyright (C) 2008 James Smart, Emulex 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
+ *
+ */
+
+#ifndef SCSI_BSG_FC_H
+#define SCSI_BSG_FC_H
+
+/*
+ * This file intended to be included by both kernel and user space
+ */
+
+#include <scsi/scsi.h>
+
+/*
+ * FC Transport SGIO v4 BSG Message Support
+ */
+
+/* Default BSG request timeout (in seconds) */
+#define FC_DEFAULT_BSG_TIMEOUT (10 * HZ)
+
+
+/*
+ * Request Message Codes supported by the FC Transport
+ */
+
+/* define the class masks for the message codes */
+#define FC_BSG_CLS_MASK 0xF0000000 /* find object class */
+#define FC_BSG_HST_MASK 0x80000000 /* fc host class */
+#define FC_BSG_RPT_MASK 0x40000000 /* fc rport class */
+
+ /* fc_host Message Codes */
+#define FC_BSG_HST_ADD_RPORT (FC_BSG_HST_MASK | 0x00000001)
+#define FC_BSG_HST_DEL_RPORT (FC_BSG_HST_MASK | 0x00000002)
+#define FC_BSG_HST_ELS_NOLOGIN (FC_BSG_HST_MASK | 0x00000003)
+#define FC_BSG_HST_CT (FC_BSG_HST_MASK | 0x00000004)
+#define FC_BSG_HST_VENDOR (FC_BSG_HST_MASK | 0x000000FF)
+
+ /* fc_rport Message Codes */
+#define FC_BSG_RPT_ELS (FC_BSG_RPT_MASK | 0x00000001)
+#define FC_BSG_RPT_CT (FC_BSG_RPT_MASK | 0x00000002)
+
+
+
+/*
+ * FC Address Identifiers in Message Structures :
+ *
+ * Whenever a command payload contains a FC Address Identifier
+ * (aka port_id), the value is effectively in big-endian
+ * order, thus the array elements are decoded as follows:
+ * element [0] is bits 23:16 of the FC Address Identifier
+ * element [1] is bits 15:8 of the FC Address Identifier
+ * element [2] is bits 7:0 of the FC Address Identifier
+ */
+
+
+/*
+ * FC Host Messages
+ */
+
+/* FC_BSG_HST_ADDR_PORT : */
+
+/* Request:
+ * This message requests the FC host to login to the remote port
+ * at the specified N_Port_Id. The remote port is to be enumerated
+ * with the transport upon completion of the login.
+ */
+struct fc_bsg_host_add_rport {
+ uint8_t reserved;
+
+ /* FC Address Identier of the remote port to login to */
+ uint8_t port_id[3];
+};
+
+/* Response:
+ * There is no additional response data - fc_bsg_reply->result is sufficient
+ */
+
+
+/* FC_BSG_HST_DEL_RPORT : */
+
+/* Request:
+ * This message requests the FC host to remove an enumerated
+ * remote port and to terminate the login to it.
+ *
+ * Note: The driver is free to reject this request if it desires to
+ * remain logged in with the remote port.
+ */
+struct fc_bsg_host_del_rport {
+ uint8_t reserved;
+
+ /* FC Address Identier of the remote port to logout of */
+ uint8_t port_id[3];
+};
+
+/* Response:
+ * There is no additional response data - fc_bsg_reply->result is sufficient
+ */
+
+
+/* FC_BSG_HST_ELS_NOLOGIN : */
+
+/* Request:
+ * This message requests the FC_Host to send an ELS to a specific
+ * N_Port_ID. The host does not need to log into the remote port,
+ * nor does it need to enumerate the rport for further traffic
+ * (although, the FC host is free to do so if it desires).
+ */
+struct fc_bsg_host_els {
+ /*
+ * ELS Command Code being sent (must be the same as byte 0
+ * of the payload)
+ */
+ uint8_t command_code;
+
+ /* FC Address Identier of the remote port to send the ELS to */
+ uint8_t port_id[3];
+};
+
+/* Response:
+ */
+/* fc_bsg_ctels_reply->status values */
+#define FC_CTELS_STATUS_OK 0x00000000
+#define FC_CTELS_STATUS_REJECT 0x00000001
+#define FC_CTELS_STATUS_P_RJT 0x00000002
+#define FC_CTELS_STATUS_F_RJT 0x00000003
+#define FC_CTELS_STATUS_P_BSY 0x00000004
+#define FC_CTELS_STATUS_F_BSY 0x00000006
+struct fc_bsg_ctels_reply {
+ /*
+ * Note: An ELS LS_RJT may be reported in 2 ways:
+ * a) A status of FC_CTELS_STATUS_OK is returned. The caller
+ * is to look into the ELS receive payload to determine
+ * LS_ACC or LS_RJT (by contents of word 0). The reject
+ * data will be in word 1.
+ * b) A status of FC_CTELS_STATUS_REJECT is returned, The
+ * rjt_data field will contain valid data.
+ *
+ * Note: ELS LS_ACC is determined by an FC_CTELS_STATUS_OK, and
+ * the receive payload word 0 indicates LS_ACC
+ * (e.g. value is 0x02xxxxxx).
+ *
+ * Note: Similarly, a CT Reject may be reported in 2 ways:
+ * a) A status of FC_CTELS_STATUS_OK is returned. The caller
+ * is to look into the CT receive payload to determine
+ * Accept or Reject (by contents of word 2). The reject
+ * data will be in word 3.
+ * b) A status of FC_CTELS_STATUS_REJECT is returned, The
+ * rjt_data field will contain valid data.
+ *
+ * Note: x_RJT/BSY status will indicae that the rjt_data field
+ * is valid and contains the reason/explanation values.
+ */
+ uint32_t status; /* See FC_CTELS_STATUS_xxx */
+
+ /* valid if status is not FC_CTELS_STATUS_OK */
+ struct {
+ uint8_t action; /* fragment_id for CT REJECT */
+ uint8_t reason_code;
+ uint8_t reason_explanation;
+ uint8_t vendor_unique;
+ } rjt_data;
+};
+
+
+/* FC_BSG_HST_CT : */
+
+/* Request:
+ * This message requests that a CT Request be performed with the
+ * indicated N_Port_ID. The driver is responsible for logging in with
+ * the fabric and/or N_Port_ID, etc as per FC rules. This request does
+ * not mandate that the driver must enumerate the destination in the
+ * transport. The driver is allowed to decide whether to enumerate it,
+ * and whether to tear it down after the request.
+ */
+struct fc_bsg_host_ct {
+ uint8_t reserved;
+
+ /* FC Address Identier of the remote port to send the ELS to */
+ uint8_t port_id[3];
+
+ /*
+ * We need words 0-2 of the generic preamble for the LLD's
+ */
+ uint32_t preamble_word0; /* revision & IN_ID */
+ uint32_t preamble_word1; /* GS_Type, GS_SubType, Options, Rsvd */
+ uint32_t preamble_word2; /* Cmd Code, Max Size */
+
+};
+/* Response:
+ *
+ * The reply structure is an fc_bsg_ctels_reply structure
+ */
+
+
+/* FC_BSG_HST_VENDOR : */
+
+/* Request:
+ * Note: When specifying vendor_id, be sure to read the Vendor Type and ID
+ * formatting requirements specified in scsi_netlink.h
+ */
+struct fc_bsg_host_vendor {
+ /*
+ * Identifies the vendor that the message is formatted for. This
+ * should be the recipient of the message.
+ */
+ uint64_t vendor_id;
+
+ /* start of vendor command area */
+ uint32_t vendor_cmd[0];
+};
+
+/* Response:
+ */
+struct fc_bsg_host_vendor_reply {
+ /* start of vendor response area */
+ uint32_t vendor_rsp[0];
+};
+
+
+
+/*
+ * FC Remote Port Messages
+ */
+
+/* FC_BSG_RPT_ELS : */
+
+/* Request:
+ * This message requests that an ELS be performed with the rport.
+ */
+struct fc_bsg_rport_els {
+ /*
+ * ELS Command Code being sent (must be the same as
+ * byte 0 of the payload)
+ */
+ uint8_t els_code;
+};
+
+/* Response:
+ *
+ * The reply structure is an fc_bsg_ctels_reply structure
+ */
+
+
+/* FC_BSG_RPT_CT : */
+
+/* Request:
+ * This message requests that a CT Request be performed with the rport.
+ */
+struct fc_bsg_rport_ct {
+ /*
+ * We need words 0-2 of the generic preamble for the LLD's
+ */
+ uint32_t preamble_word0; /* revision & IN_ID */
+ uint32_t preamble_word1; /* GS_Type, GS_SubType, Options, Rsvd */
+ uint32_t preamble_word2; /* Cmd Code, Max Size */
+};
+/* Response:
+ *
+ * The reply structure is an fc_bsg_ctels_reply structure
+ */
+
+
+
+
+/* request (CDB) structure of the sg_io_v4 */
+struct fc_bsg_request {
+ uint32_t msgcode;
+ union {
+ struct fc_bsg_host_add_rport h_addrport;
+ struct fc_bsg_host_del_rport h_delrport;
+ struct fc_bsg_host_els h_els;
+ struct fc_bsg_host_ct h_ct;
+ struct fc_bsg_host_vendor h_vendor;
+
+ struct fc_bsg_rport_els r_els;
+ struct fc_bsg_rport_ct r_ct;
+ } rqst_data;
+};
+
+
+/* response (request sense data) structure of the sg_io_v4 */
+struct fc_bsg_reply {
+ /*
+ * The completion result. Result exists in two forms:
+ * if negative, it is an -Exxx system errno value. There will
+ * be no further reply information supplied.
+ * else, it's the 4-byte scsi error result, with driver, host,
+ * msg and status fields. The per-msgcode reply structure
+ * will contain valid data.
+ */
+ uint32_t result;
+
+ /* If there was reply_payload, how much was recevied ? */
+ uint32_t reply_payload_rcv_len;
+
+ union {
+ struct fc_bsg_host_vendor_reply vendor_reply;
+
+ struct fc_bsg_ctels_reply ctels_reply;
+ } reply_data;
+};
+
+
+#endif /* SCSI_BSG_FC_H */
+
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 43b50d36925c..3878d1dc7f59 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -270,7 +270,7 @@ static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd)
static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd)
{
- return scmd->request->sector;
+ return blk_rq_pos(scmd->request);
}
static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd)
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index d123ca84e732..b62a097b3ecb 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -478,6 +478,15 @@ struct scsi_host_template {
* module_init/module_exit.
*/
struct list_head legacy_hosts;
+
+ /*
+ * Vendor Identifier associated with the host
+ *
+ * Note: When specifying vendor_id, be sure to read the
+ * Vendor Type and ID formatting requirements specified in
+ * scsi_netlink.h
+ */
+ u64 vendor_id;
};
/*
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index c9184f756cad..620db73889c1 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -33,7 +33,6 @@
struct scsi_transport_template;
-
/*
* FC Port definitions - Following FC HBAAPI guidelines
*
@@ -352,6 +351,7 @@ struct fc_rport { /* aka fc_starget_attrs */
struct delayed_work fail_io_work;
struct work_struct stgt_delete_work;
struct work_struct rport_delete_work;
+ struct request_queue *rqst_q; /* bsg support */
} __attribute__((aligned(sizeof(unsigned long))));
/* bit field values for struct fc_rport "flags" field: */
@@ -514,6 +514,9 @@ struct fc_host_attrs {
struct workqueue_struct *work_q;
char devloss_work_q_name[20];
struct workqueue_struct *devloss_work_q;
+
+ /* bsg support */
+ struct request_queue *rqst_q;
};
#define shost_to_fc_host(x) \
@@ -579,6 +582,47 @@ struct fc_host_attrs {
(((struct fc_host_attrs *)(x)->shost_data)->devloss_work_q)
+struct fc_bsg_buffer {
+ unsigned int payload_len;
+ int sg_cnt;
+ struct scatterlist *sg_list;
+};
+
+/* Values for fc_bsg_job->state_flags (bitflags) */
+#define FC_RQST_STATE_INPROGRESS 0
+#define FC_RQST_STATE_DONE 1
+
+struct fc_bsg_job {
+ struct Scsi_Host *shost;
+ struct fc_rport *rport;
+ struct device *dev;
+ struct request *req;
+ spinlock_t job_lock;
+ unsigned int state_flags;
+ unsigned int ref_cnt;
+ void (*job_done)(struct fc_bsg_job *);
+
+ struct fc_bsg_request *request;
+ struct fc_bsg_reply *reply;
+ unsigned int request_len;
+ unsigned int reply_len;
+ /*
+ * On entry : reply_len indicates the buffer size allocated for
+ * the reply.
+ *
+ * Upon completion : the message handler must set reply_len
+ * to indicates the size of the reply to be returned to the
+ * caller.
+ */
+
+ /* DMA payloads for the request/response */
+ struct fc_bsg_buffer request_payload;
+ struct fc_bsg_buffer reply_payload;
+
+ void *dd_data; /* Used for driver-specific storage */
+};
+
+
/* The functions by which the transport class and the driver communicate */
struct fc_function_template {
void (*get_rport_dev_loss_tmo)(struct fc_rport *);
@@ -614,9 +658,14 @@ struct fc_function_template {
int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int);
int (* it_nexus_response)(struct Scsi_Host *, u64, int);
+ /* bsg support */
+ int (*bsg_request)(struct fc_bsg_job *);
+ int (*bsg_timeout)(struct fc_bsg_job *);
+
/* allocation lengths for host-specific data */
u32 dd_fcrport_size;
u32 dd_fcvport_size;
+ u32 dd_bsg_size;
/*
* The driver sets these to tell the transport class it
@@ -737,7 +786,6 @@ fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_state)
vport->vport_state = new_state;
}
-
struct scsi_transport_template *fc_attach_transport(
struct fc_function_template *);
void fc_release_transport(struct scsi_transport_template *);
diff --git a/include/sound/core.h b/include/sound/core.h
index 3dea79829acc..a26bbdcc6765 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -300,16 +300,6 @@ int snd_card_create(int idx, const char *id,
struct module *module, int extra_size,
struct snd_card **card_ret);
-static inline __deprecated
-struct snd_card *snd_card_new(int idx, const char *id,
- struct module *module, int extra_size)
-{
- struct snd_card *card;
- if (snd_card_create(idx, id, module, extra_size, &card) < 0)
- return NULL;
- return card;
-}
-
int snd_card_disconnect(struct snd_card *card);
int snd_card_free(struct snd_card *card);
int snd_card_free_when_closed(struct snd_card *card);
diff --git a/include/sound/driver.h b/include/sound/driver.h
deleted file mode 100644
index f0359437d01a..000000000000
--- a/include/sound/driver.h
+++ /dev/null
@@ -1 +0,0 @@
-#warning "This file is deprecated"
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index c17296891617..267effddb070 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -270,6 +270,7 @@ struct snd_pcm_runtime {
snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */
unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */
+ snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */
/* -- HW params -- */
snd_pcm_access_t access; /* access mode */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 13676472ddfc..496dc30457b7 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -45,24 +45,6 @@ struct snd_pcm_substream;
#define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated */
/*
- * DAI Left/Right Clocks.
- *
- * Specifies whether the DAI can support different samples for similtanious
- * playback and capture. This usually requires a seperate physical frame
- * clock for playback and capture.
- */
-#define SND_SOC_DAIFMT_SYNC (0 << 5) /* Tx FRM = Rx FRM */
-#define SND_SOC_DAIFMT_ASYNC (1 << 5) /* Tx FRM ~ Rx FRM */
-
-/*
- * TDM
- *
- * Time Division Multiplexing. Allows PCM data to be multplexed with other
- * data on the DAI.
- */
-#define SND_SOC_DAIFMT_TDM (1 << 6)
-
-/*
* DAI hardware signal inversions.
*
* Specifies whether the DAI can also support inverted clocks for the specified
@@ -96,6 +78,9 @@ struct snd_pcm_substream;
#define SND_SOC_CLOCK_IN 0
#define SND_SOC_CLOCK_OUT 1
+#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
struct snd_soc_dai_ops;
struct snd_soc_dai;
struct snd_ac97_bus_ops;
@@ -208,6 +193,7 @@ struct snd_soc_dai {
/* DAI capabilities */
struct snd_soc_pcm_stream capture;
struct snd_soc_pcm_stream playback;
+ unsigned int symmetric_rates:1;
/* DAI runtime info */
struct snd_pcm_runtime *runtime;
@@ -219,11 +205,8 @@ struct snd_soc_dai {
/* DAI private data */
void *private_data;
- /* parent codec/platform */
- union {
- struct snd_soc_codec *codec;
- struct snd_soc_platform *platform;
- };
+ /* parent platform */
+ struct snd_soc_platform *platform;
struct list_head list;
};
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index a7def6a9a030..533f9f256496 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -140,16 +140,30 @@
#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert}
+#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \
+ wevent, wflags) \
+{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
+ .shift = wshift, .invert = winvert, \
+ .event = wevent, .event_flags = wflags}
#define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert}
+#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \
+ wevent, wflags) \
+{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
+ .shift = wshift, .invert = winvert, \
+ .event = wevent, .event_flags = wflags}
-/* generic register modifier widget */
+/* generic widgets */
#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
{ .id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \
.reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \
.on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
+#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
+{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \
+ .shift = wshift, .invert = winvert, .event = wevent, \
+ .event_flags = wflags}
/* dapm kcontrol types */
#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
@@ -298,6 +312,7 @@ enum snd_soc_dapm_type {
snd_soc_dapm_vmid, /* codec bias/vmid - to minimise pops */
snd_soc_dapm_pre, /* machine specific pre widget - exec first */
snd_soc_dapm_post, /* machine specific post widget - exec last */
+ snd_soc_dapm_supply, /* power/clock supply */
};
/*
@@ -357,6 +372,8 @@ struct snd_soc_dapm_widget {
unsigned char suspend:1; /* was active before suspend */
unsigned char pmdown:1; /* waiting for timeout */
+ int (*power_check)(struct snd_soc_dapm_widget *w);
+
/* external events */
unsigned short event_flags; /* flags to specify event types */
int (*event)(struct snd_soc_dapm_widget*, struct snd_kcontrol *, int);
diff --git a/include/sound/soc.h b/include/sound/soc.h
index a40bc6f316fc..6ab80bf7abd2 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -118,6 +118,14 @@
.info = snd_soc_info_volsw, \
.get = xhandler_get, .put = xhandler_put, \
.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
+#define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, xmax, xinvert,\
+ xhandler_get, xhandler_put) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+ .info = snd_soc_info_volsw, \
+ .get = xhandler_get, .put = xhandler_put, \
+ .private_value = (unsigned long)&(struct soc_mixer_control) \
+ {.reg = xreg, .shift = shift_left, .rshift = shift_right, \
+ .max = xmax, .invert = xinvert} }
#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
xhandler_get, xhandler_put, tlv_array) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -417,6 +425,12 @@ struct snd_soc_dai_link {
/* codec/machine specific init - e.g. add machine controls */
int (*init)(struct snd_soc_codec *codec);
+ /* Symmetry requirements */
+ unsigned int symmetric_rates:1;
+
+ /* Symmetry data - only valid if symmetry is being enforced */
+ unsigned int rate;
+
/* DAI pcm */
struct snd_pcm *pcm;
};
diff --git a/include/sound/version.h b/include/sound/version.h
index a7e74e23ad2e..456f1359e1c0 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
/* include/version.h */
-#define CONFIG_SND_VERSION "1.0.19"
+#define CONFIG_SND_VERSION "1.0.20"
#define CONFIG_SND_DATE ""
diff --git a/include/trace/block.h b/include/trace/block.h
index 25b7068b819e..5b12efa096b6 100644
--- a/include/trace/block.h
+++ b/include/trace/block.h
@@ -70,7 +70,7 @@ DECLARE_TRACE(block_split,
DECLARE_TRACE(block_remap,
TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev,
- sector_t from, sector_t to),
- TP_ARGS(q, bio, dev, from, to));
+ sector_t from),
+ TP_ARGS(q, bio, dev, from));
#endif
diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h
new file mode 100644
index 000000000000..f7a7ae1e8f90
--- /dev/null
+++ b/include/trace/define_trace.h
@@ -0,0 +1,75 @@
+/*
+ * Trace files that want to automate creationg of all tracepoints defined
+ * in their file should include this file. The following are macros that the
+ * trace file may define:
+ *
+ * TRACE_SYSTEM defines the system the tracepoint is for
+ *
+ * TRACE_INCLUDE_FILE if the file name is something other than TRACE_SYSTEM.h
+ * This macro may be defined to tell define_trace.h what file to include.
+ * Note, leave off the ".h".
+ *
+ * TRACE_INCLUDE_PATH if the path is something other than core kernel include/trace
+ * then this macro can define the path to use. Note, the path is relative to
+ * define_trace.h, not the file including it. Full path names for out of tree
+ * modules must be used.
+ */
+
+#ifdef CREATE_TRACE_POINTS
+
+/* Prevent recursion */
+#undef CREATE_TRACE_POINTS
+
+#include <linux/stringify.h>
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
+ DEFINE_TRACE(name)
+
+#undef DECLARE_TRACE
+#define DECLARE_TRACE(name, proto, args) \
+ DEFINE_TRACE(name)
+
+#undef TRACE_INCLUDE
+#undef __TRACE_INCLUDE
+
+#ifndef TRACE_INCLUDE_FILE
+# define TRACE_INCLUDE_FILE TRACE_SYSTEM
+# define UNDEF_TRACE_INCLUDE_FILE
+#endif
+
+#ifndef TRACE_INCLUDE_PATH
+# define __TRACE_INCLUDE(system) <trace/events/system.h>
+# define UNDEF_TRACE_INCLUDE_PATH
+#else
+# define __TRACE_INCLUDE(system) __stringify(TRACE_INCLUDE_PATH/system.h)
+#endif
+
+# define TRACE_INCLUDE(system) __TRACE_INCLUDE(system)
+
+/* Let the trace headers be reread */
+#define TRACE_HEADER_MULTI_READ
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+#ifdef CONFIG_EVENT_TRACING
+#include <trace/ftrace.h>
+#endif
+
+#undef TRACE_HEADER_MULTI_READ
+
+/* Only undef what we defined in this file */
+#ifdef UNDEF_TRACE_INCLUDE_FILE
+# undef TRACE_INCLUDE_FILE
+# undef UNDEF_TRACE_INCLUDE_FILE
+#endif
+
+#ifdef UNDEF_TRACE_INCLUDE_PATH
+# undef TRACE_INCLUDE_PATH
+# undef UNDEF_TRACE_INCLUDE_PATH
+#endif
+
+/* We may be processing more files */
+#define CREATE_TRACE_POINTS
+
+#endif /* CREATE_TRACE_POINTS */
diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h
new file mode 100644
index 000000000000..32a9f7ef432b
--- /dev/null
+++ b/include/trace/events/irq.h
@@ -0,0 +1,134 @@
+#if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_IRQ_H
+
+#include <linux/tracepoint.h>
+#include <linux/interrupt.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM irq
+
+/**
+ * irq_handler_entry - called immediately before the irq action handler
+ * @irq: irq number
+ * @action: pointer to struct irqaction
+ *
+ * The struct irqaction pointed to by @action contains various
+ * information about the handler, including the device name,
+ * @action->name, and the device id, @action->dev_id. When used in
+ * conjunction with the irq_handler_exit tracepoint, we can figure
+ * out irq handler latencies.
+ */
+TRACE_EVENT(irq_handler_entry,
+
+ TP_PROTO(int irq, struct irqaction *action),
+
+ TP_ARGS(irq, action),
+
+ TP_STRUCT__entry(
+ __field( int, irq )
+ __string( name, action->name )
+ ),
+
+ TP_fast_assign(
+ __entry->irq = irq;
+ __assign_str(name, action->name);
+ ),
+
+ TP_printk("irq=%d handler=%s", __entry->irq, __get_str(name))
+);
+
+/**
+ * irq_handler_exit - called immediately after the irq action handler returns
+ * @irq: irq number
+ * @action: pointer to struct irqaction
+ * @ret: return value
+ *
+ * If the @ret value is set to IRQ_HANDLED, then we know that the corresponding
+ * @action->handler scuccessully handled this irq. Otherwise, the irq might be
+ * a shared irq line, or the irq was not handled successfully. Can be used in
+ * conjunction with the irq_handler_entry to understand irq handler latencies.
+ */
+TRACE_EVENT(irq_handler_exit,
+
+ TP_PROTO(int irq, struct irqaction *action, int ret),
+
+ TP_ARGS(irq, action, ret),
+
+ TP_STRUCT__entry(
+ __field( int, irq )
+ __field( int, ret )
+ ),
+
+ TP_fast_assign(
+ __entry->irq = irq;
+ __entry->ret = ret;
+ ),
+
+ TP_printk("irq=%d return=%s",
+ __entry->irq, __entry->ret ? "handled" : "unhandled")
+);
+
+/**
+ * softirq_entry - called immediately before the softirq handler
+ * @h: pointer to struct softirq_action
+ * @vec: pointer to first struct softirq_action in softirq_vec array
+ *
+ * The @h parameter, contains a pointer to the struct softirq_action
+ * which has a pointer to the action handler that is called. By subtracting
+ * the @vec pointer from the @h pointer, we can determine the softirq
+ * number. Also, when used in combination with the softirq_exit tracepoint
+ * we can determine the softirq latency.
+ */
+TRACE_EVENT(softirq_entry,
+
+ TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+
+ TP_ARGS(h, vec),
+
+ TP_STRUCT__entry(
+ __field( int, vec )
+ __string( name, softirq_to_name[h-vec] )
+ ),
+
+ TP_fast_assign(
+ __entry->vec = (int)(h - vec);
+ __assign_str(name, softirq_to_name[h-vec]);
+ ),
+
+ TP_printk("softirq=%d action=%s", __entry->vec, __get_str(name))
+);
+
+/**
+ * softirq_exit - called immediately after the softirq handler returns
+ * @h: pointer to struct softirq_action
+ * @vec: pointer to first struct softirq_action in softirq_vec array
+ *
+ * The @h parameter contains a pointer to the struct softirq_action
+ * that has handled the softirq. By subtracting the @vec pointer from
+ * the @h pointer, we can determine the softirq number. Also, when used in
+ * combination with the softirq_entry tracepoint we can determine the softirq
+ * latency.
+ */
+TRACE_EVENT(softirq_exit,
+
+ TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+
+ TP_ARGS(h, vec),
+
+ TP_STRUCT__entry(
+ __field( int, vec )
+ __string( name, softirq_to_name[h-vec] )
+ ),
+
+ TP_fast_assign(
+ __entry->vec = (int)(h - vec);
+ __assign_str(name, softirq_to_name[h-vec]);
+ ),
+
+ TP_printk("softirq=%d action=%s", __entry->vec, __get_str(name))
+);
+
+#endif /* _TRACE_IRQ_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
new file mode 100644
index 000000000000..c22c42f980b5
--- /dev/null
+++ b/include/trace/events/kmem.h
@@ -0,0 +1,194 @@
+#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KMEM_H
+
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kmem
+
+TRACE_EVENT(kmalloc,
+
+ TP_PROTO(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags),
+
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, call_site )
+ __field( const void *, ptr )
+ __field( size_t, bytes_req )
+ __field( size_t, bytes_alloc )
+ __field( gfp_t, gfp_flags )
+ ),
+
+ TP_fast_assign(
+ __entry->call_site = call_site;
+ __entry->ptr = ptr;
+ __entry->bytes_req = bytes_req;
+ __entry->bytes_alloc = bytes_alloc;
+ __entry->gfp_flags = gfp_flags;
+ ),
+
+ TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x",
+ __entry->call_site,
+ __entry->ptr,
+ __entry->bytes_req,
+ __entry->bytes_alloc,
+ __entry->gfp_flags)
+);
+
+TRACE_EVENT(kmem_cache_alloc,
+
+ TP_PROTO(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags),
+
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, call_site )
+ __field( const void *, ptr )
+ __field( size_t, bytes_req )
+ __field( size_t, bytes_alloc )
+ __field( gfp_t, gfp_flags )
+ ),
+
+ TP_fast_assign(
+ __entry->call_site = call_site;
+ __entry->ptr = ptr;
+ __entry->bytes_req = bytes_req;
+ __entry->bytes_alloc = bytes_alloc;
+ __entry->gfp_flags = gfp_flags;
+ ),
+
+ TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x",
+ __entry->call_site,
+ __entry->ptr,
+ __entry->bytes_req,
+ __entry->bytes_alloc,
+ __entry->gfp_flags)
+);
+
+TRACE_EVENT(kmalloc_node,
+
+ TP_PROTO(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags,
+ int node),
+
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, call_site )
+ __field( const void *, ptr )
+ __field( size_t, bytes_req )
+ __field( size_t, bytes_alloc )
+ __field( gfp_t, gfp_flags )
+ __field( int, node )
+ ),
+
+ TP_fast_assign(
+ __entry->call_site = call_site;
+ __entry->ptr = ptr;
+ __entry->bytes_req = bytes_req;
+ __entry->bytes_alloc = bytes_alloc;
+ __entry->gfp_flags = gfp_flags;
+ __entry->node = node;
+ ),
+
+ TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x node=%d",
+ __entry->call_site,
+ __entry->ptr,
+ __entry->bytes_req,
+ __entry->bytes_alloc,
+ __entry->gfp_flags,
+ __entry->node)
+);
+
+TRACE_EVENT(kmem_cache_alloc_node,
+
+ TP_PROTO(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags,
+ int node),
+
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, call_site )
+ __field( const void *, ptr )
+ __field( size_t, bytes_req )
+ __field( size_t, bytes_alloc )
+ __field( gfp_t, gfp_flags )
+ __field( int, node )
+ ),
+
+ TP_fast_assign(
+ __entry->call_site = call_site;
+ __entry->ptr = ptr;
+ __entry->bytes_req = bytes_req;
+ __entry->bytes_alloc = bytes_alloc;
+ __entry->gfp_flags = gfp_flags;
+ __entry->node = node;
+ ),
+
+ TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%08x node=%d",
+ __entry->call_site,
+ __entry->ptr,
+ __entry->bytes_req,
+ __entry->bytes_alloc,
+ __entry->gfp_flags,
+ __entry->node)
+);
+
+TRACE_EVENT(kfree,
+
+ TP_PROTO(unsigned long call_site, const void *ptr),
+
+ TP_ARGS(call_site, ptr),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, call_site )
+ __field( const void *, ptr )
+ ),
+
+ TP_fast_assign(
+ __entry->call_site = call_site;
+ __entry->ptr = ptr;
+ ),
+
+ TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr)
+);
+
+TRACE_EVENT(kmem_cache_free,
+
+ TP_PROTO(unsigned long call_site, const void *ptr),
+
+ TP_ARGS(call_site, ptr),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, call_site )
+ __field( const void *, ptr )
+ ),
+
+ TP_fast_assign(
+ __entry->call_site = call_site;
+ __entry->ptr = ptr;
+ ),
+
+ TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr)
+);
+#endif /* _TRACE_KMEM_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/lockdep.h b/include/trace/events/lockdep.h
new file mode 100644
index 000000000000..0e956c9dfd7e
--- /dev/null
+++ b/include/trace/events/lockdep.h
@@ -0,0 +1,96 @@
+#if !defined(_TRACE_LOCKDEP_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_LOCKDEP_H
+
+#include <linux/lockdep.h>
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM lockdep
+
+#ifdef CONFIG_LOCKDEP
+
+TRACE_EVENT(lock_acquire,
+
+ TP_PROTO(struct lockdep_map *lock, unsigned int subclass,
+ int trylock, int read, int check,
+ struct lockdep_map *next_lock, unsigned long ip),
+
+ TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, flags)
+ __string(name, lock->name)
+ ),
+
+ TP_fast_assign(
+ __entry->flags = (trylock ? 1 : 0) | (read ? 2 : 0);
+ __assign_str(name, lock->name);
+ ),
+
+ TP_printk("%s%s%s", (__entry->flags & 1) ? "try " : "",
+ (__entry->flags & 2) ? "read " : "",
+ __get_str(name))
+);
+
+TRACE_EVENT(lock_release,
+
+ TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip),
+
+ TP_ARGS(lock, nested, ip),
+
+ TP_STRUCT__entry(
+ __string(name, lock->name)
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, lock->name);
+ ),
+
+ TP_printk("%s", __get_str(name))
+);
+
+#ifdef CONFIG_LOCK_STAT
+
+TRACE_EVENT(lock_contended,
+
+ TP_PROTO(struct lockdep_map *lock, unsigned long ip),
+
+ TP_ARGS(lock, ip),
+
+ TP_STRUCT__entry(
+ __string(name, lock->name)
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, lock->name);
+ ),
+
+ TP_printk("%s", __get_str(name))
+);
+
+TRACE_EVENT(lock_acquired,
+ TP_PROTO(struct lockdep_map *lock, unsigned long ip, s64 waittime),
+
+ TP_ARGS(lock, ip, waittime),
+
+ TP_STRUCT__entry(
+ __string(name, lock->name)
+ __field(unsigned long, wait_usec)
+ __field(unsigned long, wait_nsec_rem)
+ ),
+ TP_fast_assign(
+ __assign_str(name, lock->name);
+ __entry->wait_nsec_rem = do_div(waittime, NSEC_PER_USEC);
+ __entry->wait_usec = (unsigned long) waittime;
+ ),
+ TP_printk("%s (%lu.%03lu us)", __get_str(name), __entry->wait_usec,
+ __entry->wait_nsec_rem)
+);
+
+#endif
+#endif
+
+#endif /* _TRACE_LOCKDEP_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/mm.h b/include/trace/events/mm.h
new file mode 100644
index 000000000000..4ec5bd5993bb
--- /dev/null
+++ b/include/trace/events/mm.h
@@ -0,0 +1,48 @@
+#if !defined(_TRACE_MM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_MM_H
+
+#include <linux/tracepoint.h>
+#include <linux/mm.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM mm
+
+/**
+ * dump_pages - called by the trace page dump trigger
+ * @pfn: page frame number
+ * @page: pointer to the page frame
+ *
+ * This is a helper trace point into the dumping of the page frames.
+ * It will record various infromation about a page frame.
+ */
+TRACE_EVENT(dump_pages,
+
+ TP_PROTO(unsigned long pfn, struct page *page),
+
+ TP_ARGS(pfn, page),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, pfn )
+ __field( unsigned long, flags )
+ __field( unsigned long, index )
+ __field( unsigned int, count )
+ __field( unsigned int, mapcount )
+ ),
+
+ TP_fast_assign(
+ __entry->pfn = pfn;
+ __entry->flags = page->flags;
+ __entry->count = atomic_read(&page->_count);
+ __entry->mapcount = page_mapcount(page);
+ __entry->index = page->index;
+ ),
+
+ TP_printk("pfn=%lu flags=%lx count=%u mapcount=%u index=%lu",
+ __entry->pfn, __entry->flags, __entry->count,
+ __entry->mapcount, __entry->index)
+);
+
+#endif /* _TRACE_MM_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/sched_event_types.h b/include/trace/events/sched.h
index 63547dc1125f..dd4033cf5b09 100644
--- a/include/trace/sched_event_types.h
+++ b/include/trace/events/sched.h
@@ -1,9 +1,8 @@
+#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SCHED_H
-/* use <trace/sched.h> instead */
-#ifndef TRACE_EVENT
-# error Do not include this file directly.
-# error Unless you know what you are doing.
-#endif
+#include <linux/sched.h>
+#include <linux/tracepoint.h>
#undef TRACE_SYSTEM
#define TRACE_SYSTEM sched
@@ -181,9 +180,9 @@ TRACE_EVENT(sched_switch,
*/
TRACE_EVENT(sched_migrate_task,
- TP_PROTO(struct task_struct *p, int orig_cpu, int dest_cpu),
+ TP_PROTO(struct task_struct *p, int dest_cpu),
- TP_ARGS(p, orig_cpu, dest_cpu),
+ TP_ARGS(p, dest_cpu),
TP_STRUCT__entry(
__array( char, comm, TASK_COMM_LEN )
@@ -197,7 +196,7 @@ TRACE_EVENT(sched_migrate_task,
memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
__entry->pid = p->pid;
__entry->prio = p->prio;
- __entry->orig_cpu = orig_cpu;
+ __entry->orig_cpu = task_cpu(p);
__entry->dest_cpu = dest_cpu;
),
@@ -334,4 +333,7 @@ TRACE_EVENT(sched_signal_send,
__entry->sig, __entry->comm, __entry->pid)
);
-#undef TRACE_SYSTEM
+#endif /* _TRACE_SCHED_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
new file mode 100644
index 000000000000..1e8fabb57c06
--- /dev/null
+++ b/include/trace/events/skb.h
@@ -0,0 +1,40 @@
+#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SKB_H
+
+#include <linux/skbuff.h>
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM skb
+
+/*
+ * Tracepoint for free an sk_buff:
+ */
+TRACE_EVENT(kfree_skb,
+
+ TP_PROTO(struct sk_buff *skb, void *location),
+
+ TP_ARGS(skb, location),
+
+ TP_STRUCT__entry(
+ __field( void *, skbaddr )
+ __field( unsigned short, protocol )
+ __field( void *, location )
+ ),
+
+ TP_fast_assign(
+ __entry->skbaddr = skb;
+ if (skb) {
+ __entry->protocol = ntohs(skb->protocol);
+ }
+ __entry->location = location;
+ ),
+
+ TP_printk("skbaddr=%p protocol=%u location=%p",
+ __entry->skbaddr, __entry->protocol, __entry->location)
+);
+
+#endif /* _TRACE_SKB_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
new file mode 100644
index 000000000000..edb02bc9f8ff
--- /dev/null
+++ b/include/trace/ftrace.h
@@ -0,0 +1,509 @@
+/*
+ * Stage 1 of the trace events.
+ *
+ * Override the macros in <trace/trace_events.h> to include the following:
+ *
+ * struct ftrace_raw_<call> {
+ * struct trace_entry ent;
+ * <type> <item>;
+ * <type2> <item2>[<len>];
+ * [...]
+ * };
+ *
+ * The <type> <item> is created by the __field(type, item) macro or
+ * the __array(type2, item2, len) macro.
+ * We simply do "type item;", and that will create the fields
+ * in the structure.
+ */
+
+#include <linux/ftrace_event.h>
+
+#undef __array
+#define __array(type, item, len) type item[len];
+
+#undef __field
+#define __field(type, item) type item;
+
+#undef __string
+#define __string(item, src) int __str_loc_##item;
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
+ struct ftrace_raw_##name { \
+ struct trace_entry ent; \
+ tstruct \
+ char __str_data[0]; \
+ }; \
+ static struct ftrace_event_call event_##name
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+
+/*
+ * Stage 2 of the trace events.
+ *
+ * Include the following:
+ *
+ * struct ftrace_str_offsets_<call> {
+ * int <str1>;
+ * int <str2>;
+ * [...]
+ * };
+ *
+ * The __string() macro will create each int <str>, this is to
+ * keep the offset of each string from the beggining of the event
+ * once we perform the strlen() of the src strings.
+ *
+ */
+
+#undef __array
+#define __array(type, item, len)
+
+#undef __field
+#define __field(type, item);
+
+#undef __string
+#define __string(item, src) int item;
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
+ struct ftrace_str_offsets_##call { \
+ tstruct; \
+ };
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+/*
+ * Stage 3 of the trace events.
+ *
+ * Override the macros in <trace/trace_events.h> to include the following:
+ *
+ * enum print_line_t
+ * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags)
+ * {
+ * struct trace_seq *s = &iter->seq;
+ * struct ftrace_raw_<call> *field; <-- defined in stage 1
+ * struct trace_entry *entry;
+ * int ret;
+ *
+ * entry = iter->ent;
+ *
+ * if (entry->type != event_<call>.id) {
+ * WARN_ON_ONCE(1);
+ * return TRACE_TYPE_UNHANDLED;
+ * }
+ *
+ * field = (typeof(field))entry;
+ *
+ * ret = trace_seq_printf(s, <TP_printk> "\n");
+ * if (!ret)
+ * return TRACE_TYPE_PARTIAL_LINE;
+ *
+ * return TRACE_TYPE_HANDLED;
+ * }
+ *
+ * This is the method used to print the raw event to the trace
+ * output format. Note, this is not needed if the data is read
+ * in binary.
+ */
+
+#undef __entry
+#define __entry field
+
+#undef TP_printk
+#define TP_printk(fmt, args...) fmt "\n", args
+
+#undef __get_str
+#define __get_str(field) ((char *)__entry + __entry->__str_loc_##field)
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
+enum print_line_t \
+ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
+{ \
+ struct trace_seq *s = &iter->seq; \
+ struct ftrace_raw_##call *field; \
+ struct trace_entry *entry; \
+ int ret; \
+ \
+ entry = iter->ent; \
+ \
+ if (entry->type != event_##call.id) { \
+ WARN_ON_ONCE(1); \
+ return TRACE_TYPE_UNHANDLED; \
+ } \
+ \
+ field = (typeof(field))entry; \
+ \
+ ret = trace_seq_printf(s, #call ": " print); \
+ if (!ret) \
+ return TRACE_TYPE_PARTIAL_LINE; \
+ \
+ return TRACE_TYPE_HANDLED; \
+}
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+/*
+ * Setup the showing format of trace point.
+ *
+ * int
+ * ftrace_format_##call(struct trace_seq *s)
+ * {
+ * struct ftrace_raw_##call field;
+ * int ret;
+ *
+ * ret = trace_seq_printf(s, #type " " #item ";"
+ * " offset:%u; size:%u;\n",
+ * offsetof(struct ftrace_raw_##call, item),
+ * sizeof(field.type));
+ *
+ * }
+ */
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args
+
+#undef __field
+#define __field(type, item) \
+ ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
+ "offset:%u;\tsize:%u;\n", \
+ (unsigned int)offsetof(typeof(field), item), \
+ (unsigned int)sizeof(field.item)); \
+ if (!ret) \
+ return 0;
+
+#undef __array
+#define __array(type, item, len) \
+ ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
+ "offset:%u;\tsize:%u;\n", \
+ (unsigned int)offsetof(typeof(field), item), \
+ (unsigned int)sizeof(field.item)); \
+ if (!ret) \
+ return 0;
+
+#undef __string
+#define __string(item, src) \
+ ret = trace_seq_printf(s, "\tfield: __str_loc " #item ";\t" \
+ "offset:%u;tsize:%u;\n", \
+ (unsigned int)offsetof(typeof(field), \
+ __str_loc_##item), \
+ (unsigned int)sizeof(field.__str_loc_##item)); \
+ if (!ret) \
+ return 0;
+
+#undef __entry
+#define __entry REC
+
+#undef TP_printk
+#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
+
+#undef TP_fast_assign
+#define TP_fast_assign(args...) args
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
+static int \
+ftrace_format_##call(struct trace_seq *s) \
+{ \
+ struct ftrace_raw_##call field __attribute__((unused)); \
+ int ret = 0; \
+ \
+ tstruct; \
+ \
+ trace_seq_printf(s, "\nprint fmt: " print); \
+ \
+ return ret; \
+}
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+#undef __field
+#define __field(type, item) \
+ ret = trace_define_field(event_call, #type, #item, \
+ offsetof(typeof(field), item), \
+ sizeof(field.item), is_signed_type(type)); \
+ if (ret) \
+ return ret;
+
+#undef __array
+#define __array(type, item, len) \
+ BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \
+ ret = trace_define_field(event_call, #type "[" #len "]", #item, \
+ offsetof(typeof(field), item), \
+ sizeof(field.item), 0); \
+ if (ret) \
+ return ret;
+
+#undef __string
+#define __string(item, src) \
+ ret = trace_define_field(event_call, "__str_loc", #item, \
+ offsetof(typeof(field), __str_loc_##item), \
+ sizeof(field.__str_loc_##item), 0);
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
+int \
+ftrace_define_fields_##call(void) \
+{ \
+ struct ftrace_raw_##call field; \
+ struct ftrace_event_call *event_call = &event_##call; \
+ int ret; \
+ \
+ __common_field(int, type, 1); \
+ __common_field(unsigned char, flags, 0); \
+ __common_field(unsigned char, preempt_count, 0); \
+ __common_field(int, pid, 1); \
+ __common_field(int, tgid, 1); \
+ \
+ tstruct; \
+ \
+ return ret; \
+}
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+/*
+ * Stage 4 of the trace events.
+ *
+ * Override the macros in <trace/trace_events.h> to include the following:
+ *
+ * static void ftrace_event_<call>(proto)
+ * {
+ * event_trace_printk(_RET_IP_, "<call>: " <fmt>);
+ * }
+ *
+ * static int ftrace_reg_event_<call>(void)
+ * {
+ * int ret;
+ *
+ * ret = register_trace_<call>(ftrace_event_<call>);
+ * if (!ret)
+ * pr_info("event trace: Could not activate trace point "
+ * "probe to <call>");
+ * return ret;
+ * }
+ *
+ * static void ftrace_unreg_event_<call>(void)
+ * {
+ * unregister_trace_<call>(ftrace_event_<call>);
+ * }
+ *
+ *
+ * For those macros defined with TRACE_EVENT:
+ *
+ * static struct ftrace_event_call event_<call>;
+ *
+ * static void ftrace_raw_event_<call>(proto)
+ * {
+ * struct ring_buffer_event *event;
+ * struct ftrace_raw_<call> *entry; <-- defined in stage 1
+ * unsigned long irq_flags;
+ * int pc;
+ *
+ * local_save_flags(irq_flags);
+ * pc = preempt_count();
+ *
+ * event = trace_current_buffer_lock_reserve(event_<call>.id,
+ * sizeof(struct ftrace_raw_<call>),
+ * irq_flags, pc);
+ * if (!event)
+ * return;
+ * entry = ring_buffer_event_data(event);
+ *
+ * <assign>; <-- Here we assign the entries by the __field and
+ * __array macros.
+ *
+ * trace_current_buffer_unlock_commit(event, irq_flags, pc);
+ * }
+ *
+ * static int ftrace_raw_reg_event_<call>(void)
+ * {
+ * int ret;
+ *
+ * ret = register_trace_<call>(ftrace_raw_event_<call>);
+ * if (!ret)
+ * pr_info("event trace: Could not activate trace point "
+ * "probe to <call>");
+ * return ret;
+ * }
+ *
+ * static void ftrace_unreg_event_<call>(void)
+ * {
+ * unregister_trace_<call>(ftrace_raw_event_<call>);
+ * }
+ *
+ * static struct trace_event ftrace_event_type_<call> = {
+ * .trace = ftrace_raw_output_<call>, <-- stage 2
+ * };
+ *
+ * static int ftrace_raw_init_event_<call>(void)
+ * {
+ * int id;
+ *
+ * id = register_ftrace_event(&ftrace_event_type_<call>);
+ * if (!id)
+ * return -ENODEV;
+ * event_<call>.id = id;
+ * return 0;
+ * }
+ *
+ * static struct ftrace_event_call __used
+ * __attribute__((__aligned__(4)))
+ * __attribute__((section("_ftrace_events"))) event_<call> = {
+ * .name = "<call>",
+ * .system = "<system>",
+ * .raw_init = ftrace_raw_init_event_<call>,
+ * .regfunc = ftrace_reg_event_<call>,
+ * .unregfunc = ftrace_unreg_event_<call>,
+ * .show_format = ftrace_format_<call>,
+ * }
+ *
+ */
+
+#undef TP_FMT
+#define TP_FMT(fmt, args...) fmt "\n", ##args
+
+#ifdef CONFIG_EVENT_PROFILE
+#define _TRACE_PROFILE(call, proto, args) \
+static void ftrace_profile_##call(proto) \
+{ \
+ extern void perf_tpcounter_event(int); \
+ perf_tpcounter_event(event_##call.id); \
+} \
+ \
+static int ftrace_profile_enable_##call(struct ftrace_event_call *call) \
+{ \
+ int ret = 0; \
+ \
+ if (!atomic_inc_return(&call->profile_count)) \
+ ret = register_trace_##call(ftrace_profile_##call); \
+ \
+ return ret; \
+} \
+ \
+static void ftrace_profile_disable_##call(struct ftrace_event_call *call) \
+{ \
+ if (atomic_add_negative(-1, &call->profile_count)) \
+ unregister_trace_##call(ftrace_profile_##call); \
+}
+
+#define _TRACE_PROFILE_INIT(call) \
+ .profile_count = ATOMIC_INIT(-1), \
+ .profile_enable = ftrace_profile_enable_##call, \
+ .profile_disable = ftrace_profile_disable_##call,
+
+#else
+#define _TRACE_PROFILE(call, proto, args)
+#define _TRACE_PROFILE_INIT(call)
+#endif
+
+#undef __entry
+#define __entry entry
+
+#undef __field
+#define __field(type, item)
+
+#undef __array
+#define __array(type, item, len)
+
+#undef __string
+#define __string(item, src) \
+ __str_offsets.item = __str_size + \
+ offsetof(typeof(*entry), __str_data); \
+ __str_size += strlen(src) + 1;
+
+#undef __assign_str
+#define __assign_str(dst, src) \
+ __entry->__str_loc_##dst = __str_offsets.dst; \
+ strcpy(__get_str(dst), src);
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
+_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \
+ \
+static struct ftrace_event_call event_##call; \
+ \
+static void ftrace_raw_event_##call(proto) \
+{ \
+ struct ftrace_str_offsets_##call __maybe_unused __str_offsets; \
+ struct ftrace_event_call *call = &event_##call; \
+ struct ring_buffer_event *event; \
+ struct ftrace_raw_##call *entry; \
+ unsigned long irq_flags; \
+ int __str_size = 0; \
+ int pc; \
+ \
+ local_save_flags(irq_flags); \
+ pc = preempt_count(); \
+ \
+ tstruct; \
+ \
+ event = trace_current_buffer_lock_reserve(event_##call.id, \
+ sizeof(struct ftrace_raw_##call) + __str_size,\
+ irq_flags, pc); \
+ if (!event) \
+ return; \
+ entry = ring_buffer_event_data(event); \
+ \
+ assign; \
+ \
+ if (!filter_current_check_discard(call, entry, event)) \
+ trace_nowake_buffer_unlock_commit(event, irq_flags, pc); \
+} \
+ \
+static int ftrace_raw_reg_event_##call(void) \
+{ \
+ int ret; \
+ \
+ ret = register_trace_##call(ftrace_raw_event_##call); \
+ if (ret) \
+ pr_info("event trace: Could not activate trace point " \
+ "probe to " #call "\n"); \
+ return ret; \
+} \
+ \
+static void ftrace_raw_unreg_event_##call(void) \
+{ \
+ unregister_trace_##call(ftrace_raw_event_##call); \
+} \
+ \
+static struct trace_event ftrace_event_type_##call = { \
+ .trace = ftrace_raw_output_##call, \
+}; \
+ \
+static int ftrace_raw_init_event_##call(void) \
+{ \
+ int id; \
+ \
+ id = register_ftrace_event(&ftrace_event_type_##call); \
+ if (!id) \
+ return -ENODEV; \
+ event_##call.id = id; \
+ INIT_LIST_HEAD(&event_##call.fields); \
+ init_preds(&event_##call); \
+ return 0; \
+} \
+ \
+static struct ftrace_event_call __used \
+__attribute__((__aligned__(4))) \
+__attribute__((section("_ftrace_events"))) event_##call = { \
+ .name = #call, \
+ .system = __stringify(TRACE_SYSTEM), \
+ .event = &ftrace_event_type_##call, \
+ .raw_init = ftrace_raw_init_event_##call, \
+ .regfunc = ftrace_raw_reg_event_##call, \
+ .unregfunc = ftrace_raw_unreg_event_##call, \
+ .show_format = ftrace_format_##call, \
+ .define_fields = ftrace_define_fields_##call, \
+ _TRACE_PROFILE_INIT(call) \
+}
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+#undef _TRACE_PROFILE
+#undef _TRACE_PROFILE_INIT
+
diff --git a/include/trace/irq.h b/include/trace/irq.h
deleted file mode 100644
index ff5d4495dc37..000000000000
--- a/include/trace/irq.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _TRACE_IRQ_H
-#define _TRACE_IRQ_H
-
-#include <linux/interrupt.h>
-#include <linux/tracepoint.h>
-
-#include <trace/irq_event_types.h>
-
-#endif
diff --git a/include/trace/irq_event_types.h b/include/trace/irq_event_types.h
deleted file mode 100644
index 85964ebd47ec..000000000000
--- a/include/trace/irq_event_types.h
+++ /dev/null
@@ -1,55 +0,0 @@
-
-/* use <trace/irq.h> instead */
-#ifndef TRACE_FORMAT
-# error Do not include this file directly.
-# error Unless you know what you are doing.
-#endif
-
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM irq
-
-/*
- * Tracepoint for entry of interrupt handler:
- */
-TRACE_FORMAT(irq_handler_entry,
- TP_PROTO(int irq, struct irqaction *action),
- TP_ARGS(irq, action),
- TP_FMT("irq=%d handler=%s", irq, action->name)
- );
-
-/*
- * Tracepoint for return of an interrupt handler:
- */
-TRACE_EVENT(irq_handler_exit,
-
- TP_PROTO(int irq, struct irqaction *action, int ret),
-
- TP_ARGS(irq, action, ret),
-
- TP_STRUCT__entry(
- __field( int, irq )
- __field( int, ret )
- ),
-
- TP_fast_assign(
- __entry->irq = irq;
- __entry->ret = ret;
- ),
-
- TP_printk("irq=%d return=%s",
- __entry->irq, __entry->ret ? "handled" : "unhandled")
-);
-
-TRACE_FORMAT(softirq_entry,
- TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
- TP_ARGS(h, vec),
- TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec])
- );
-
-TRACE_FORMAT(softirq_exit,
- TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
- TP_ARGS(h, vec),
- TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec])
- );
-
-#undef TRACE_SYSTEM
diff --git a/include/trace/kmemtrace.h b/include/trace/kmemtrace.h
deleted file mode 100644
index 28ee69f9cd46..000000000000
--- a/include/trace/kmemtrace.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2008 Eduard - Gabriel Munteanu
- *
- * This file is released under GPL version 2.
- */
-
-#ifndef _LINUX_KMEMTRACE_H
-#define _LINUX_KMEMTRACE_H
-
-#ifdef __KERNEL__
-
-#include <linux/tracepoint.h>
-#include <linux/types.h>
-
-#ifdef CONFIG_KMEMTRACE
-extern void kmemtrace_init(void);
-#else
-static inline void kmemtrace_init(void)
-{
-}
-#endif
-
-DECLARE_TRACE(kmalloc,
- TP_PROTO(unsigned long call_site,
- const void *ptr,
- size_t bytes_req,
- size_t bytes_alloc,
- gfp_t gfp_flags),
- TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags));
-DECLARE_TRACE(kmem_cache_alloc,
- TP_PROTO(unsigned long call_site,
- const void *ptr,
- size_t bytes_req,
- size_t bytes_alloc,
- gfp_t gfp_flags),
- TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags));
-DECLARE_TRACE(kmalloc_node,
- TP_PROTO(unsigned long call_site,
- const void *ptr,
- size_t bytes_req,
- size_t bytes_alloc,
- gfp_t gfp_flags,
- int node),
- TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node));
-DECLARE_TRACE(kmem_cache_alloc_node,
- TP_PROTO(unsigned long call_site,
- const void *ptr,
- size_t bytes_req,
- size_t bytes_alloc,
- gfp_t gfp_flags,
- int node),
- TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node));
-DECLARE_TRACE(kfree,
- TP_PROTO(unsigned long call_site, const void *ptr),
- TP_ARGS(call_site, ptr));
-DECLARE_TRACE(kmem_cache_free,
- TP_PROTO(unsigned long call_site, const void *ptr),
- TP_ARGS(call_site, ptr));
-
-#endif /* __KERNEL__ */
-
-#endif /* _LINUX_KMEMTRACE_H */
-
diff --git a/include/trace/lockdep.h b/include/trace/lockdep.h
deleted file mode 100644
index 5ca67df87f2a..000000000000
--- a/include/trace/lockdep.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _TRACE_LOCKDEP_H
-#define _TRACE_LOCKDEP_H
-
-#include <linux/lockdep.h>
-#include <linux/tracepoint.h>
-
-#include <trace/lockdep_event_types.h>
-
-#endif
diff --git a/include/trace/lockdep_event_types.h b/include/trace/lockdep_event_types.h
deleted file mode 100644
index adccfcd2ec8f..000000000000
--- a/include/trace/lockdep_event_types.h
+++ /dev/null
@@ -1,44 +0,0 @@
-
-#ifndef TRACE_FORMAT
-# error Do not include this file directly.
-# error Unless you know what you are doing.
-#endif
-
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM lock
-
-#ifdef CONFIG_LOCKDEP
-
-TRACE_FORMAT(lock_acquire,
- TP_PROTO(struct lockdep_map *lock, unsigned int subclass,
- int trylock, int read, int check,
- struct lockdep_map *next_lock, unsigned long ip),
- TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip),
- TP_FMT("%s%s%s", trylock ? "try " : "",
- read ? "read " : "", lock->name)
- );
-
-TRACE_FORMAT(lock_release,
- TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip),
- TP_ARGS(lock, nested, ip),
- TP_FMT("%s", lock->name)
- );
-
-#ifdef CONFIG_LOCK_STAT
-
-TRACE_FORMAT(lock_contended,
- TP_PROTO(struct lockdep_map *lock, unsigned long ip),
- TP_ARGS(lock, ip),
- TP_FMT("%s", lock->name)
- );
-
-TRACE_FORMAT(lock_acquired,
- TP_PROTO(struct lockdep_map *lock, unsigned long ip),
- TP_ARGS(lock, ip),
- TP_FMT("%s", lock->name)
- );
-
-#endif
-#endif
-
-#undef TRACE_SYSTEM
diff --git a/include/trace/sched.h b/include/trace/sched.h
deleted file mode 100644
index 4e372a1a29bf..000000000000
--- a/include/trace/sched.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _TRACE_SCHED_H
-#define _TRACE_SCHED_H
-
-#include <linux/sched.h>
-#include <linux/tracepoint.h>
-
-#include <trace/sched_event_types.h>
-
-#endif
diff --git a/include/trace/skb.h b/include/trace/skb.h
deleted file mode 100644
index b66206d9be72..000000000000
--- a/include/trace/skb.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _TRACE_SKB_H_
-#define _TRACE_SKB_H_
-
-#include <linux/skbuff.h>
-#include <linux/tracepoint.h>
-
-DECLARE_TRACE(kfree_skb,
- TP_PROTO(struct sk_buff *skb, void *location),
- TP_ARGS(skb, location));
-
-#endif
diff --git a/include/trace/trace_event_types.h b/include/trace/trace_event_types.h
deleted file mode 100644
index df56f5694be6..000000000000
--- a/include/trace/trace_event_types.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/* trace/<type>_event_types.h here */
-
-#include <trace/sched_event_types.h>
-#include <trace/irq_event_types.h>
-#include <trace/lockdep_event_types.h>
diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h
deleted file mode 100644
index fd13750ca4ba..000000000000
--- a/include/trace/trace_events.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/* trace/<type>.h here */
-
-#include <trace/sched.h>
-#include <trace/irq.h>
-#include <trace/lockdep.h>
diff --git a/include/xen/Kbuild b/include/xen/Kbuild
new file mode 100644
index 000000000000..4e65c16a445b
--- /dev/null
+++ b/include/xen/Kbuild
@@ -0,0 +1 @@
+header-y += evtchn.h
diff --git a/include/xen/events.h b/include/xen/events.h
index 0d5f1adc0363..e68d59a90ca8 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -53,4 +53,7 @@ bool xen_test_irq_pending(int irq);
irq will be disabled so it won't deliver an interrupt. */
void xen_poll_irq(int irq);
+/* Determine the IRQ which is bound to an event channel */
+unsigned irq_from_evtchn(unsigned int evtchn);
+
#endif /* _XEN_EVENTS_H */
diff --git a/include/xen/evtchn.h b/include/xen/evtchn.h
new file mode 100644
index 000000000000..14e833ee4e0b
--- /dev/null
+++ b/include/xen/evtchn.h
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * evtchn.h
+ *
+ * Interface to /dev/xen/evtchn.
+ *
+ * Copyright (c) 2003-2005, K A Fraser
+ *
+ * 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; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __LINUX_PUBLIC_EVTCHN_H__
+#define __LINUX_PUBLIC_EVTCHN_H__
+
+/*
+ * Bind a fresh port to VIRQ @virq.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_VIRQ \
+ _IOC(_IOC_NONE, 'E', 0, sizeof(struct ioctl_evtchn_bind_virq))
+struct ioctl_evtchn_bind_virq {
+ unsigned int virq;
+};
+
+/*
+ * Bind a fresh port to remote <@remote_domain, @remote_port>.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_INTERDOMAIN \
+ _IOC(_IOC_NONE, 'E', 1, sizeof(struct ioctl_evtchn_bind_interdomain))
+struct ioctl_evtchn_bind_interdomain {
+ unsigned int remote_domain, remote_port;
+};
+
+/*
+ * Allocate a fresh port for binding to @remote_domain.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_UNBOUND_PORT \
+ _IOC(_IOC_NONE, 'E', 2, sizeof(struct ioctl_evtchn_bind_unbound_port))
+struct ioctl_evtchn_bind_unbound_port {
+ unsigned int remote_domain;
+};
+
+/*
+ * Unbind previously allocated @port.
+ */
+#define IOCTL_EVTCHN_UNBIND \
+ _IOC(_IOC_NONE, 'E', 3, sizeof(struct ioctl_evtchn_unbind))
+struct ioctl_evtchn_unbind {
+ unsigned int port;
+};
+
+/*
+ * Unbind previously allocated @port.
+ */
+#define IOCTL_EVTCHN_NOTIFY \
+ _IOC(_IOC_NONE, 'E', 4, sizeof(struct ioctl_evtchn_notify))
+struct ioctl_evtchn_notify {
+ unsigned int port;
+};
+
+/* Clear and reinitialise the event buffer. Clear error condition. */
+#define IOCTL_EVTCHN_RESET \
+ _IOC(_IOC_NONE, 'E', 5, 0)
+
+#endif /* __LINUX_PUBLIC_EVTCHN_H__ */
diff --git a/include/xen/interface/version.h b/include/xen/interface/version.h
index 453235e923f0..e8b6519d47e9 100644
--- a/include/xen/interface/version.h
+++ b/include/xen/interface/version.h
@@ -57,4 +57,7 @@ struct xen_feature_info {
/* Declares the features reported by XENVER_get_features. */
#include "features.h"
+/* arg == NULL; returns host memory page size. */
+#define XENVER_pagesize 7
+
#endif /* __XEN_PUBLIC_VERSION_H__ */
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
index f87f9614844d..b9763badbd77 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
@@ -91,8 +91,7 @@ struct xenbus_driver {
void (*otherend_changed)(struct xenbus_device *dev,
enum xenbus_state backend_state);
int (*remove)(struct xenbus_device *dev);
- int (*suspend)(struct xenbus_device *dev);
- int (*suspend_cancel)(struct xenbus_device *dev);
+ int (*suspend)(struct xenbus_device *dev, pm_message_t state);
int (*resume)(struct xenbus_device *dev);
int (*uevent)(struct xenbus_device *, char **, int, char *, int);
struct device_driver driver;
diff --git a/init/Kconfig b/init/Kconfig
index 7be4d3836745..57651e305a4c 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -308,7 +308,7 @@ menu "RCU Subsystem"
choice
prompt "RCU Implementation"
- default CLASSIC_RCU
+ default TREE_RCU
config CLASSIC_RCU
bool "Classic RCU"
@@ -975,18 +975,23 @@ config COMPAT_BRK
choice
prompt "Choose SLAB allocator"
- default SLUB
+ default SLQB_ALLOCATOR
help
This option allows to select a slab allocator.
-config SLAB
+config SLAB_ALLOCATOR
bool "SLAB"
help
The regular slab allocator that is established and known to work
well in all environments. It organizes cache hot objects in
per cpu and per node queues.
-config SLUB
+config SLAB
+ bool
+ default y
+ depends on SLAB_ALLOCATOR
+
+config SLUB_ALLOCATOR
bool "SLUB (Unqueued Allocator)"
help
SLUB is a slab allocator that minimizes cache line usage
@@ -996,6 +1001,21 @@ config SLUB
and has enhanced diagnostics. SLUB is the default choice for
a slab allocator.
+config SLUB
+ bool
+ default y
+ depends on SLUB_ALLOCATOR
+
+config SLQB_ALLOCATOR
+ bool "SLQB (Queued allocator)"
+ help
+ SLQB is a proposed new slab allocator.
+
+config SLQB
+ bool
+ default y
+ depends on SLQB_ALLOCATOR
+
config SLOB
depends on EMBEDDED
bool "SLOB (Simple Allocator)"
@@ -1051,7 +1071,7 @@ config HAVE_GENERIC_DMA_COHERENT
config SLABINFO
bool
depends on PROC_FS
- depends on SLAB || SLUB_DEBUG
+ depends on SLAB || SLUB_DEBUG || SLQB
default y
config RT_MUTEXES
diff --git a/init/initramfs.c b/init/initramfs.c
index 9ee7b7810417..4c00edc59689 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -574,11 +574,10 @@ static int __init populate_rootfs(void)
if (initrd_start) {
#ifdef CONFIG_BLK_DEV_RAM
int fd;
- printk(KERN_INFO "checking if image is initramfs...\n");
+ printk(KERN_INFO "Trying to unpack rootfs image as initramfs...\n");
err = unpack_to_rootfs((char *)initrd_start,
initrd_end - initrd_start);
if (!err) {
- printk(KERN_INFO "rootfs image is initramfs; unpacking...\n");
free_initrd();
return 0;
} else {
@@ -596,15 +595,11 @@ static int __init populate_rootfs(void)
free_initrd();
}
#else
- printk(KERN_INFO "Unpacking initramfs...");
+ printk(KERN_INFO "Unpacking initramfs...\n");
err = unpack_to_rootfs((char *)initrd_start,
initrd_end - initrd_start);
- if (err) {
- printk(" failed!\n");
- printk(KERN_EMERG "%s\n", err);
- } else {
- printk(" done\n");
- }
+ if (err)
+ printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);
free_initrd();
#endif
}
diff --git a/init/main.c b/init/main.c
index 3bbf93be744c..064fb795d2c4 100644
--- a/init/main.c
+++ b/init/main.c
@@ -64,6 +64,7 @@
#include <linux/idr.h>
#include <linux/ftrace.h>
#include <linux/async.h>
+#include <linux/kmemtrace.h>
#include <trace/boot.h>
#include <asm/io.h>
@@ -71,7 +72,6 @@
#include <asm/setup.h>
#include <asm/sections.h>
#include <asm/cacheflush.h>
-#include <trace/kmemtrace.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/smp.h>
@@ -652,7 +652,6 @@ asmlinkage void __init start_kernel(void)
page_cgroup_init();
mem_init();
enable_debug_pagealloc();
- cpu_hotplug_init();
kmem_cache_init();
kmemtrace_init();
debug_objects_mem_init();
diff --git a/ipc/sem.c b/ipc/sem.c
index 16a2189e96f9..87c2b641fd7b 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1290,8 +1290,8 @@ void exit_sem(struct task_struct *tsk)
int i;
rcu_read_lock();
- un = list_entry(rcu_dereference(ulp->list_proc.next),
- struct sem_undo, list_proc);
+ un = list_entry_rcu(ulp->list_proc.next,
+ struct sem_undo, list_proc);
if (&un->list_proc == &ulp->list_proc)
semid = -1;
else
diff --git a/kernel/Makefile b/kernel/Makefile
index 42423665660a..a35eee3436de 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_LATENCYTOP) += latencytop.o
obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
obj-$(CONFIG_FUNCTION_TRACER) += trace/
obj-$(CONFIG_TRACING) += trace/
+obj-$(CONFIG_X86_DS) += trace/
obj-$(CONFIG_SMP) += sched_cpupri.o
obj-$(CONFIG_SLOW_WORK) += slow-work.o
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 6e7351739a82..1f6396d76687 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -568,7 +568,7 @@ void audit_trim_trees(void)
if (err)
goto skip_it;
- root_mnt = collect_mounts(path.mnt, path.dentry);
+ root_mnt = collect_mounts(&path);
path_put(&path);
if (!root_mnt)
goto skip_it;
@@ -660,7 +660,7 @@ int audit_add_tree_rule(struct audit_krule *rule)
err = kern_path(tree->pathname, 0, &path);
if (err)
goto Err;
- mnt = collect_mounts(path.mnt, path.dentry);
+ mnt = collect_mounts(&path);
path_put(&path);
if (!mnt) {
err = -ENOMEM;
@@ -720,7 +720,7 @@ int audit_tag_tree(char *old, char *new)
err = kern_path(new, 0, &path);
if (err)
return err;
- tagged = collect_mounts(path.mnt, path.dentry);
+ tagged = collect_mounts(&path);
path_put(&path);
if (!tagged)
return -ENOMEM;
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index a6fe71fd5d1b..713098ee5a02 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1028,7 +1028,7 @@ static void audit_update_watch(struct audit_parent *parent,
if (audit_enabled) {
struct audit_buffer *ab;
- ab = audit_log_start(NULL, GFP_KERNEL,
+ ab = audit_log_start(NULL, GFP_NOFS,
AUDIT_CONFIG_CHANGE);
audit_log_format(ab, "auid=%u ses=%u",
audit_get_loginuid(current),
@@ -1067,7 +1067,7 @@ static void audit_remove_parent_watches(struct audit_parent *parent)
e = container_of(r, struct audit_entry, rule);
if (audit_enabled) {
struct audit_buffer *ab;
- ab = audit_log_start(NULL, GFP_KERNEL,
+ ab = audit_log_start(NULL, GFP_NOFS,
AUDIT_CONFIG_CHANGE);
audit_log_format(ab, "auid=%u ses=%u",
audit_get_loginuid(current),
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 382109b5baeb..a7267bfd3765 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1133,8 +1133,7 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
free_cg_links:
free_cg_links(&tmp_cg_links);
drop_new_super:
- up_write(&sb->s_umount);
- deactivate_super(sb);
+ deactivate_locked_super(sb);
return ret;
}
diff --git a/kernel/compat.c b/kernel/compat.c
index 42d56544460f..f6c204f07ea6 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -882,6 +882,17 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
}
+asmlinkage long
+compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig,
+ struct compat_siginfo __user *uinfo)
+{
+ siginfo_t info;
+
+ if (copy_siginfo_from_user32(&info, uinfo))
+ return -EFAULT;
+ return do_rt_tgsigqueueinfo(tgid, pid, sig, &info);
+}
+
#ifdef __ARCH_WANT_COMPAT_SYS_TIME
/* compat_time_t is a 32 bit "long" and needs to get converted. */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 395b6974dc8d..609fae119e57 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -34,14 +34,9 @@ static struct {
* an ongoing cpu hotplug operation.
*/
int refcount;
-} cpu_hotplug;
-
-void __init cpu_hotplug_init(void)
-{
- cpu_hotplug.active_writer = NULL;
- mutex_init(&cpu_hotplug.lock);
- cpu_hotplug.refcount = 0;
-}
+} cpu_hotplug = {
+ .lock = __MUTEX_INITIALIZER(cpu_hotplug.lock),
+};
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/kernel/cred.c b/kernel/cred.c
index 3a039189d707..1bb4d7e5d616 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -167,7 +167,7 @@ EXPORT_SYMBOL(prepare_creds);
/*
* Prepare credentials for current to perform an execve()
- * - The caller must hold current->cred_exec_mutex
+ * - The caller must hold current->cred_guard_mutex
*/
struct cred *prepare_exec_creds(void)
{
@@ -276,7 +276,7 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
struct cred *new;
int ret;
- mutex_init(&p->cred_exec_mutex);
+ mutex_init(&p->cred_guard_mutex);
if (
#ifdef CONFIG_KEYS
diff --git a/kernel/exit.c b/kernel/exit.c
index abf9cf3b95c6..51d1fe3fb7ad 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -48,7 +48,7 @@
#include <linux/tracehook.h>
#include <linux/fs_struct.h>
#include <linux/init_task.h>
-#include <trace/sched.h>
+#include <trace/events/sched.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -56,10 +56,6 @@
#include <asm/mmu_context.h>
#include "cred-internals.h"
-DEFINE_TRACE(sched_process_free);
-DEFINE_TRACE(sched_process_exit);
-DEFINE_TRACE(sched_process_wait);
-
static void exit_mm(struct task_struct * tsk);
static void __unhash_process(struct task_struct *p)
@@ -1476,6 +1472,7 @@ static int wait_consider_task(struct task_struct *parent, int ptrace,
*/
if (*notask_error)
*notask_error = ret;
+ return 0;
}
if (likely(!ptrace) && unlikely(p->ptrace)) {
diff --git a/kernel/fork.c b/kernel/fork.c
index b9e2edd00726..711468f3db2a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -61,7 +61,6 @@
#include <linux/proc_fs.h>
#include <linux/blkdev.h>
#include <linux/fs_struct.h>
-#include <trace/sched.h>
#include <linux/magic.h>
#include <asm/pgtable.h>
@@ -71,6 +70,8 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
+#include <trace/events/sched.h>
+
/*
* Protected counters by write_lock_irq(&tasklist_lock)
*/
@@ -83,8 +84,6 @@ DEFINE_PER_CPU(unsigned long, process_counts) = 0;
__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */
-DEFINE_TRACE(sched_process_fork);
-
int nr_processes(void)
{
int cpu;
@@ -1089,8 +1088,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
#ifdef CONFIG_DEBUG_MUTEXES
p->blocked_on = NULL; /* not blocked yet */
#endif
- if (unlikely(current->ptrace))
- ptrace_fork(p, clone_flags);
+
+ p->bts = NULL;
/* Perform scheduler related setup. Assign this task to a CPU. */
sched_fork(p, clone_flags);
diff --git a/kernel/futex.c b/kernel/futex.c
index eef8cd26b5e5..0c406a3ddc37 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -19,6 +19,10 @@
* PRIVATE futexes by Eric Dumazet
* Copyright (C) 2007 Eric Dumazet <dada1@cosmosbay.com>
*
+ * Requeue-PI support by Darren Hart <dvhltc@us.ibm.com>
+ * Copyright (C) IBM Corporation, 2009
+ * Thanks to Thomas Gleixner for conceptual design and careful reviews.
+ *
* Thanks to Ben LaHaise for yelling "hashed waitqueues" loudly
* enough at me, Linus for the original (flawed) idea, Matthew
* Kirkwood for proof-of-concept implementation.
@@ -109,6 +113,9 @@ struct futex_q {
struct futex_pi_state *pi_state;
struct task_struct *task;
+ /* rt_waiter storage for requeue_pi: */
+ struct rt_mutex_waiter *rt_waiter;
+
/* Bitset for the optional bitmasked wakeup */
u32 bitset;
};
@@ -276,6 +283,25 @@ void put_futex_key(int fshared, union futex_key *key)
drop_futex_key_refs(key);
}
+/**
+ * futex_top_waiter() - Return the highest priority waiter on a futex
+ * @hb: the hash bucket the futex_q's reside in
+ * @key: the futex key (to distinguish it from other futex futex_q's)
+ *
+ * Must be called with the hb lock held.
+ */
+static struct futex_q *futex_top_waiter(struct futex_hash_bucket *hb,
+ union futex_key *key)
+{
+ struct futex_q *this;
+
+ plist_for_each_entry(this, &hb->chain, list) {
+ if (match_futex(&this->key, key))
+ return this;
+ }
+ return NULL;
+}
+
static u32 cmpxchg_futex_value_locked(u32 __user *uaddr, u32 uval, u32 newval)
{
u32 curval;
@@ -537,6 +563,131 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
return 0;
}
+/**
+ * futex_lock_pi_atomic() - atomic work required to acquire a pi aware futex
+ * @uaddr: the pi futex user address
+ * @hb: the pi futex hash bucket
+ * @key: the futex key associated with uaddr and hb
+ * @ps: the pi_state pointer where we store the result of the
+ * lookup
+ * @task: the task to perform the atomic lock work for. This will
+ * be "current" except in the case of requeue pi.
+ * @set_waiters: force setting the FUTEX_WAITERS bit (1) or not (0)
+ *
+ * Returns:
+ * 0 - ready to wait
+ * 1 - acquired the lock
+ * <0 - error
+ *
+ * The hb->lock and futex_key refs shall be held by the caller.
+ */
+static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
+ union futex_key *key,
+ struct futex_pi_state **ps,
+ struct task_struct *task, int set_waiters)
+{
+ int lock_taken, ret, ownerdied = 0;
+ u32 uval, newval, curval;
+
+retry:
+ ret = lock_taken = 0;
+
+ /*
+ * To avoid races, we attempt to take the lock here again
+ * (by doing a 0 -> TID atomic cmpxchg), while holding all
+ * the locks. It will most likely not succeed.
+ */
+ newval = task_pid_vnr(task);
+ if (set_waiters)
+ newval |= FUTEX_WAITERS;
+
+ curval = cmpxchg_futex_value_locked(uaddr, 0, newval);
+
+ if (unlikely(curval == -EFAULT))
+ return -EFAULT;
+
+ /*
+ * Detect deadlocks.
+ */
+ if ((unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(task))))
+ return -EDEADLK;
+
+ /*
+ * Surprise - we got the lock. Just return to userspace:
+ */
+ if (unlikely(!curval))
+ return 1;
+
+ uval = curval;
+
+ /*
+ * Set the FUTEX_WAITERS flag, so the owner will know it has someone
+ * to wake at the next unlock.
+ */
+ newval = curval | FUTEX_WAITERS;
+
+ /*
+ * There are two cases, where a futex might have no owner (the
+ * owner TID is 0): OWNER_DIED. We take over the futex in this
+ * case. We also do an unconditional take over, when the owner
+ * of the futex died.
+ *
+ * This is safe as we are protected by the hash bucket lock !
+ */
+ if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
+ /* Keep the OWNER_DIED bit */
+ newval = (curval & ~FUTEX_TID_MASK) | task_pid_vnr(task);
+ ownerdied = 0;
+ lock_taken = 1;
+ }
+
+ curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
+
+ if (unlikely(curval == -EFAULT))
+ return -EFAULT;
+ if (unlikely(curval != uval))
+ goto retry;
+
+ /*
+ * We took the lock due to owner died take over.
+ */
+ if (unlikely(lock_taken))
+ return 1;
+
+ /*
+ * We dont have the lock. Look up the PI state (or create it if
+ * we are the first waiter):
+ */
+ ret = lookup_pi_state(uval, hb, key, ps);
+
+ if (unlikely(ret)) {
+ switch (ret) {
+ case -ESRCH:
+ /*
+ * No owner found for this futex. Check if the
+ * OWNER_DIED bit is set to figure out whether
+ * this is a robust futex or not.
+ */
+ if (get_futex_value_locked(&curval, uaddr))
+ return -EFAULT;
+
+ /*
+ * We simply start over in case of a robust
+ * futex. The code above will take the futex
+ * and return happy.
+ */
+ if (curval & FUTEX_OWNER_DIED) {
+ ownerdied = 1;
+ goto retry;
+ }
+ default:
+ break;
+ }
+ }
+
+ return ret;
+}
+
/*
* The hash bucket lock must be held when this is called.
* Afterwards, the futex_q must not be accessed.
@@ -687,7 +838,7 @@ static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset)
plist_for_each_entry_safe(this, next, head, list) {
if (match_futex (&this->key, &key)) {
- if (this->pi_state) {
+ if (this->pi_state || this->rt_waiter) {
ret = -EINVAL;
break;
}
@@ -800,20 +951,180 @@ out:
return ret;
}
-/*
- * Requeue all waiters hashed on one physical page to another
- * physical page.
+/**
+ * requeue_futex() - Requeue a futex_q from one hb to another
+ * @q: the futex_q to requeue
+ * @hb1: the source hash_bucket
+ * @hb2: the target hash_bucket
+ * @key2: the new key for the requeued futex_q
+ */
+static inline
+void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1,
+ struct futex_hash_bucket *hb2, union futex_key *key2)
+{
+
+ /*
+ * If key1 and key2 hash to the same bucket, no need to
+ * requeue.
+ */
+ if (likely(&hb1->chain != &hb2->chain)) {
+ plist_del(&q->list, &hb1->chain);
+ plist_add(&q->list, &hb2->chain);
+ q->lock_ptr = &hb2->lock;
+#ifdef CONFIG_DEBUG_PI_LIST
+ q->list.plist.lock = &hb2->lock;
+#endif
+ }
+ get_futex_key_refs(key2);
+ q->key = *key2;
+}
+
+/**
+ * requeue_pi_wake_futex() - Wake a task that acquired the lock during requeue
+ * q: the futex_q
+ * key: the key of the requeue target futex
+ *
+ * During futex_requeue, with requeue_pi=1, it is possible to acquire the
+ * target futex if it is uncontended or via a lock steal. Set the futex_q key
+ * to the requeue target futex so the waiter can detect the wakeup on the right
+ * futex, but remove it from the hb and NULL the rt_waiter so it can detect
+ * atomic lock acquisition. Must be called with the q->lock_ptr held.
+ */
+static inline
+void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key)
+{
+ drop_futex_key_refs(&q->key);
+ get_futex_key_refs(key);
+ q->key = *key;
+
+ WARN_ON(plist_node_empty(&q->list));
+ plist_del(&q->list, &q->list.plist);
+
+ WARN_ON(!q->rt_waiter);
+ q->rt_waiter = NULL;
+
+ wake_up(&q->waiter);
+}
+
+/**
+ * futex_proxy_trylock_atomic() - Attempt an atomic lock for the top waiter
+ * @pifutex: the user address of the to futex
+ * @hb1: the from futex hash bucket, must be locked by the caller
+ * @hb2: the to futex hash bucket, must be locked by the caller
+ * @key1: the from futex key
+ * @key2: the to futex key
+ * @ps: address to store the pi_state pointer
+ * @set_waiters: force setting the FUTEX_WAITERS bit (1) or not (0)
+ *
+ * Try and get the lock on behalf of the top waiter if we can do it atomically.
+ * Wake the top waiter if we succeed. If the caller specified set_waiters,
+ * then direct futex_lock_pi_atomic() to force setting the FUTEX_WAITERS bit.
+ * hb1 and hb2 must be held by the caller.
+ *
+ * Returns:
+ * 0 - failed to acquire the lock atomicly
+ * 1 - acquired the lock
+ * <0 - error
+ */
+static int futex_proxy_trylock_atomic(u32 __user *pifutex,
+ struct futex_hash_bucket *hb1,
+ struct futex_hash_bucket *hb2,
+ union futex_key *key1, union futex_key *key2,
+ struct futex_pi_state **ps, int set_waiters)
+{
+ struct futex_q *top_waiter = NULL;
+ u32 curval;
+ int ret;
+
+ if (get_futex_value_locked(&curval, pifutex))
+ return -EFAULT;
+
+ /*
+ * Find the top_waiter and determine if there are additional waiters.
+ * If the caller intends to requeue more than 1 waiter to pifutex,
+ * force futex_lock_pi_atomic() to set the FUTEX_WAITERS bit now,
+ * as we have means to handle the possible fault. If not, don't set
+ * the bit unecessarily as it will force the subsequent unlock to enter
+ * the kernel.
+ */
+ top_waiter = futex_top_waiter(hb1, key1);
+
+ /* There are no waiters, nothing for us to do. */
+ if (!top_waiter)
+ return 0;
+
+ /*
+ * Try to take the lock for top_waiter. Set the FUTEX_WAITERS bit in
+ * the contended case or if set_waiters is 1. The pi_state is returned
+ * in ps in contended cases.
+ */
+ ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task,
+ set_waiters);
+ if (ret == 1)
+ requeue_pi_wake_futex(top_waiter, key2);
+
+ return ret;
+}
+
+/**
+ * futex_requeue() - Requeue waiters from uaddr1 to uaddr2
+ * uaddr1: source futex user address
+ * uaddr2: target futex user address
+ * nr_wake: number of waiters to wake (must be 1 for requeue_pi)
+ * nr_requeue: number of waiters to requeue (0-INT_MAX)
+ * requeue_pi: if we are attempting to requeue from a non-pi futex to a
+ * pi futex (pi to pi requeue is not supported)
+ *
+ * Requeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire
+ * uaddr2 atomically on behalf of the top waiter.
+ *
+ * Returns:
+ * >=0 - on success, the number of tasks requeued or woken
+ * <0 - on error
*/
static int futex_requeue(u32 __user *uaddr1, int fshared, u32 __user *uaddr2,
- int nr_wake, int nr_requeue, u32 *cmpval)
+ int nr_wake, int nr_requeue, u32 *cmpval,
+ int requeue_pi)
{
union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT;
+ int drop_count = 0, task_count = 0, ret;
+ struct futex_pi_state *pi_state = NULL;
struct futex_hash_bucket *hb1, *hb2;
struct plist_head *head1;
struct futex_q *this, *next;
- int ret, drop_count = 0;
+ u32 curval2;
+
+ if (requeue_pi) {
+ /*
+ * requeue_pi requires a pi_state, try to allocate it now
+ * without any locks in case it fails.
+ */
+ if (refill_pi_state_cache())
+ return -ENOMEM;
+ /*
+ * requeue_pi must wake as many tasks as it can, up to nr_wake
+ * + nr_requeue, since it acquires the rt_mutex prior to
+ * returning to userspace, so as to not leave the rt_mutex with
+ * waiters and no owner. However, second and third wake-ups
+ * cannot be predicted as they involve race conditions with the
+ * first wake and a fault while looking up the pi_state. Both
+ * pthread_cond_signal() and pthread_cond_broadcast() should
+ * use nr_wake=1.
+ */
+ if (nr_wake != 1)
+ return -EINVAL;
+ }
retry:
+ if (pi_state != NULL) {
+ /*
+ * We will have to lookup the pi_state again, so free this one
+ * to keep the accounting correct.
+ */
+ free_pi_state(pi_state);
+ pi_state = NULL;
+ }
+
ret = get_futex_key(uaddr1, fshared, &key1);
if (unlikely(ret != 0))
goto out;
@@ -852,32 +1163,99 @@ retry_private:
}
}
+ if (requeue_pi && (task_count - nr_wake < nr_requeue)) {
+ /*
+ * Attempt to acquire uaddr2 and wake the top waiter. If we
+ * intend to requeue waiters, force setting the FUTEX_WAITERS
+ * bit. We force this here where we are able to easily handle
+ * faults rather in the requeue loop below.
+ */
+ ret = futex_proxy_trylock_atomic(uaddr2, hb1, hb2, &key1,
+ &key2, &pi_state, nr_requeue);
+
+ /*
+ * At this point the top_waiter has either taken uaddr2 or is
+ * waiting on it. If the former, then the pi_state will not
+ * exist yet, look it up one more time to ensure we have a
+ * reference to it.
+ */
+ if (ret == 1) {
+ WARN_ON(pi_state);
+ task_count++;
+ ret = get_futex_value_locked(&curval2, uaddr2);
+ if (!ret)
+ ret = lookup_pi_state(curval2, hb2, &key2,
+ &pi_state);
+ }
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EFAULT:
+ double_unlock_hb(hb1, hb2);
+ put_futex_key(fshared, &key2);
+ put_futex_key(fshared, &key1);
+ ret = get_user(curval2, uaddr2);
+ if (!ret)
+ goto retry;
+ goto out;
+ case -EAGAIN:
+ /* The owner was exiting, try again. */
+ double_unlock_hb(hb1, hb2);
+ put_futex_key(fshared, &key2);
+ put_futex_key(fshared, &key1);
+ cond_resched();
+ goto retry;
+ default:
+ goto out_unlock;
+ }
+ }
+
head1 = &hb1->chain;
plist_for_each_entry_safe(this, next, head1, list) {
- if (!match_futex (&this->key, &key1))
+ if (task_count - nr_wake >= nr_requeue)
+ break;
+
+ if (!match_futex(&this->key, &key1))
continue;
- if (++ret <= nr_wake) {
+
+ WARN_ON(!requeue_pi && this->rt_waiter);
+ WARN_ON(requeue_pi && !this->rt_waiter);
+
+ /*
+ * Wake nr_wake waiters. For requeue_pi, if we acquired the
+ * lock, we already woke the top_waiter. If not, it will be
+ * woken by futex_unlock_pi().
+ */
+ if (++task_count <= nr_wake && !requeue_pi) {
wake_futex(this);
- } else {
- /*
- * If key1 and key2 hash to the same bucket, no need to
- * requeue.
- */
- if (likely(head1 != &hb2->chain)) {
- plist_del(&this->list, &hb1->chain);
- plist_add(&this->list, &hb2->chain);
- this->lock_ptr = &hb2->lock;
-#ifdef CONFIG_DEBUG_PI_LIST
- this->list.plist.lock = &hb2->lock;
-#endif
- }
- this->key = key2;
- get_futex_key_refs(&key2);
- drop_count++;
+ continue;
+ }
- if (ret - nr_wake >= nr_requeue)
- break;
+ /*
+ * Requeue nr_requeue waiters and possibly one more in the case
+ * of requeue_pi if we couldn't acquire the lock atomically.
+ */
+ if (requeue_pi) {
+ /* Prepare the waiter to take the rt_mutex. */
+ atomic_inc(&pi_state->refcount);
+ this->pi_state = pi_state;
+ ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex,
+ this->rt_waiter,
+ this->task, 1);
+ if (ret == 1) {
+ /* We got the lock. */
+ requeue_pi_wake_futex(this, &key2);
+ continue;
+ } else if (ret) {
+ /* -EDEADLK */
+ this->pi_state = NULL;
+ free_pi_state(pi_state);
+ goto out_unlock;
+ }
}
+ requeue_futex(this, hb1, hb2, &key2);
+ drop_count++;
}
out_unlock:
@@ -897,7 +1275,9 @@ out_put_keys:
out_put_key1:
put_futex_key(fshared, &key1);
out:
- return ret;
+ if (pi_state != NULL)
+ free_pi_state(pi_state);
+ return ret ? ret : task_count;
}
/* The key must be already stored in q->key. */
@@ -1117,35 +1497,160 @@ handle_fault:
*/
#define FLAGS_SHARED 0x01
#define FLAGS_CLOCKRT 0x02
+#define FLAGS_HAS_TIMEOUT 0x04
static long futex_wait_restart(struct restart_block *restart);
+static long futex_lock_pi_restart(struct restart_block *restart);
-static int futex_wait(u32 __user *uaddr, int fshared,
- u32 val, ktime_t *abs_time, u32 bitset, int clockrt)
+/**
+ * fixup_owner() - Post lock pi_state and corner case management
+ * @uaddr: user address of the futex
+ * @fshared: whether the futex is shared (1) or not (0)
+ * @q: futex_q (contains pi_state and access to the rt_mutex)
+ * @locked: if the attempt to take the rt_mutex succeeded (1) or not (0)
+ *
+ * After attempting to lock an rt_mutex, this function is called to cleanup
+ * the pi_state owner as well as handle race conditions that may allow us to
+ * acquire the lock. Must be called with the hb lock held.
+ *
+ * Returns:
+ * 1 - success, lock taken
+ * 0 - success, lock not taken
+ * <0 - on error (-EFAULT)
+ */
+static int fixup_owner(u32 __user *uaddr, int fshared, struct futex_q *q,
+ int locked)
{
- struct task_struct *curr = current;
- struct restart_block *restart;
- DECLARE_WAITQUEUE(wait, curr);
- struct futex_hash_bucket *hb;
- struct futex_q q;
- u32 uval;
- int ret;
- struct hrtimer_sleeper t;
- int rem = 0;
+ struct task_struct *owner;
+ int ret = 0;
- if (!bitset)
- return -EINVAL;
+ if (locked) {
+ /*
+ * Got the lock. We might not be the anticipated owner if we
+ * did a lock-steal - fix up the PI-state in that case:
+ */
+ if (q->pi_state->owner != current)
+ ret = fixup_pi_state_owner(uaddr, q, current, fshared);
+ goto out;
+ }
- q.pi_state = NULL;
- q.bitset = bitset;
-retry:
- q.key = FUTEX_KEY_INIT;
- ret = get_futex_key(uaddr, fshared, &q.key);
- if (unlikely(ret != 0))
+ /*
+ * Catch the rare case, where the lock was released when we were on the
+ * way back before we locked the hash bucket.
+ */
+ if (q->pi_state->owner == current) {
+ /*
+ * Try to get the rt_mutex now. This might fail as some other
+ * task acquired the rt_mutex after we removed ourself from the
+ * rt_mutex waiters list.
+ */
+ if (rt_mutex_trylock(&q->pi_state->pi_mutex)) {
+ locked = 1;
+ goto out;
+ }
+
+ /*
+ * pi_state is incorrect, some other task did a lock steal and
+ * we returned due to timeout or signal without taking the
+ * rt_mutex. Too late. We can access the rt_mutex_owner without
+ * locking, as the other task is now blocked on the hash bucket
+ * lock. Fix the state up.
+ */
+ owner = rt_mutex_owner(&q->pi_state->pi_mutex);
+ ret = fixup_pi_state_owner(uaddr, q, owner, fshared);
goto out;
+ }
-retry_private:
- hb = queue_lock(&q);
+ /*
+ * Paranoia check. If we did not take the lock, then we should not be
+ * the owner, nor the pending owner, of the rt_mutex.
+ */
+ if (rt_mutex_owner(&q->pi_state->pi_mutex) == current)
+ printk(KERN_ERR "fixup_owner: ret = %d pi-mutex: %p "
+ "pi-state %p\n", ret,
+ q->pi_state->pi_mutex.owner,
+ q->pi_state->owner);
+
+out:
+ return ret ? ret : locked;
+}
+
+/**
+ * futex_wait_queue_me() - queue_me() and wait for wakeup, timeout, or signal
+ * @hb: the futex hash bucket, must be locked by the caller
+ * @q: the futex_q to queue up on
+ * @timeout: the prepared hrtimer_sleeper, or null for no timeout
+ * @wait: the wait_queue to add to the futex_q after queueing in the hb
+ */
+static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
+ struct hrtimer_sleeper *timeout,
+ wait_queue_t *wait)
+{
+ queue_me(q, hb);
+
+ /*
+ * There might have been scheduling since the queue_me(), as we
+ * cannot hold a spinlock across the get_user() in case it
+ * faults, and we cannot just set TASK_INTERRUPTIBLE state when
+ * queueing ourselves into the futex hash. This code thus has to
+ * rely on the futex_wake() code removing us from hash when it
+ * wakes us up.
+ */
+
+ /* add_wait_queue is the barrier after __set_current_state. */
+ __set_current_state(TASK_INTERRUPTIBLE);
+
+ /*
+ * Add current as the futex_q waiter. We don't remove ourselves from
+ * the wait_queue because we are the only user of it.
+ */
+ add_wait_queue(&q->waiter, wait);
+
+ /* Arm the timer */
+ if (timeout) {
+ hrtimer_start_expires(&timeout->timer, HRTIMER_MODE_ABS);
+ if (!hrtimer_active(&timeout->timer))
+ timeout->task = NULL;
+ }
+
+ /*
+ * !plist_node_empty() is safe here without any lock.
+ * q.lock_ptr != 0 is not safe, because of ordering against wakeup.
+ */
+ if (likely(!plist_node_empty(&q->list))) {
+ /*
+ * If the timer has already expired, current will already be
+ * flagged for rescheduling. Only call schedule if there
+ * is no timeout, or if it has yet to expire.
+ */
+ if (!timeout || timeout->task)
+ schedule();
+ }
+ __set_current_state(TASK_RUNNING);
+}
+
+/**
+ * futex_wait_setup() - Prepare to wait on a futex
+ * @uaddr: the futex userspace address
+ * @val: the expected value
+ * @fshared: whether the futex is shared (1) or not (0)
+ * @q: the associated futex_q
+ * @hb: storage for hash_bucket pointer to be returned to caller
+ *
+ * Setup the futex_q and locate the hash_bucket. Get the futex value and
+ * compare it with the expected value. Handle atomic faults internally.
+ * Return with the hb lock held and a q.key reference on success, and unlocked
+ * with no q.key reference on failure.
+ *
+ * Returns:
+ * 0 - uaddr contains val and hb has been locked
+ * <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlcoked
+ */
+static int futex_wait_setup(u32 __user *uaddr, u32 val, int fshared,
+ struct futex_q *q, struct futex_hash_bucket **hb)
+{
+ u32 uval;
+ int ret;
/*
* Access the page AFTER the hash-bucket is locked.
@@ -1163,95 +1668,84 @@ retry_private:
* A consequence is that futex_wait() can return zero and absorb
* a wakeup when *uaddr != val on entry to the syscall. This is
* rare, but normal.
- *
- * For shared futexes, we hold the mmap semaphore, so the mapping
- * cannot have changed since we looked it up in get_futex_key.
*/
+retry:
+ q->key = FUTEX_KEY_INIT;
+ ret = get_futex_key(uaddr, fshared, &q->key);
+ if (unlikely(ret != 0))
+ return ret;
+
+retry_private:
+ *hb = queue_lock(q);
+
ret = get_futex_value_locked(&uval, uaddr);
- if (unlikely(ret)) {
- queue_unlock(&q, hb);
+ if (ret) {
+ queue_unlock(q, *hb);
ret = get_user(uval, uaddr);
if (ret)
- goto out_put_key;
+ goto out;
if (!fshared)
goto retry_private;
- put_futex_key(fshared, &q.key);
+ put_futex_key(fshared, &q->key);
goto retry;
}
- ret = -EWOULDBLOCK;
- if (unlikely(uval != val)) {
- queue_unlock(&q, hb);
- goto out_put_key;
- }
- /* Only actually queue if *uaddr contained val. */
- queue_me(&q, hb);
+ if (uval != val) {
+ queue_unlock(q, *hb);
+ ret = -EWOULDBLOCK;
+ }
- /*
- * There might have been scheduling since the queue_me(), as we
- * cannot hold a spinlock across the get_user() in case it
- * faults, and we cannot just set TASK_INTERRUPTIBLE state when
- * queueing ourselves into the futex hash. This code thus has to
- * rely on the futex_wake() code removing us from hash when it
- * wakes us up.
- */
+out:
+ if (ret)
+ put_futex_key(fshared, &q->key);
+ return ret;
+}
- /* add_wait_queue is the barrier after __set_current_state. */
- __set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&q.waiter, &wait);
- /*
- * !plist_node_empty() is safe here without any lock.
- * q.lock_ptr != 0 is not safe, because of ordering against wakeup.
- */
- if (likely(!plist_node_empty(&q.list))) {
- if (!abs_time)
- schedule();
- else {
- hrtimer_init_on_stack(&t.timer,
- clockrt ? CLOCK_REALTIME :
- CLOCK_MONOTONIC,
- HRTIMER_MODE_ABS);
- hrtimer_init_sleeper(&t, current);
- hrtimer_set_expires_range_ns(&t.timer, *abs_time,
- current->timer_slack_ns);
-
- hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS);
- if (!hrtimer_active(&t.timer))
- t.task = NULL;
+static int futex_wait(u32 __user *uaddr, int fshared,
+ u32 val, ktime_t *abs_time, u32 bitset, int clockrt)
+{
+ struct hrtimer_sleeper timeout, *to = NULL;
+ DECLARE_WAITQUEUE(wait, current);
+ struct restart_block *restart;
+ struct futex_hash_bucket *hb;
+ struct futex_q q;
+ int ret;
- /*
- * the timer could have already expired, in which
- * case current would be flagged for rescheduling.
- * Don't bother calling schedule.
- */
- if (likely(t.task))
- schedule();
+ if (!bitset)
+ return -EINVAL;
- hrtimer_cancel(&t.timer);
+ q.pi_state = NULL;
+ q.bitset = bitset;
+ q.rt_waiter = NULL;
- /* Flag if a timeout occured */
- rem = (t.task == NULL);
+ if (abs_time) {
+ to = &timeout;
- destroy_hrtimer_on_stack(&t.timer);
- }
+ hrtimer_init_on_stack(&to->timer, clockrt ? CLOCK_REALTIME :
+ CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ hrtimer_init_sleeper(to, current);
+ hrtimer_set_expires_range_ns(&to->timer, *abs_time,
+ current->timer_slack_ns);
}
- __set_current_state(TASK_RUNNING);
- /*
- * NOTE: we don't remove ourselves from the waitqueue because
- * we are the only user of it.
- */
+ /* Prepare to wait on uaddr. */
+ ret = futex_wait_setup(uaddr, val, fshared, &q, &hb);
+ if (ret)
+ goto out;
+
+ /* queue_me and wait for wakeup, timeout, or a signal. */
+ futex_wait_queue_me(hb, &q, to, &wait);
/* If we were woken (and unqueued), we succeeded, whatever. */
ret = 0;
if (!unqueue_me(&q))
goto out_put_key;
ret = -ETIMEDOUT;
- if (rem)
+ if (to && !to->task)
goto out_put_key;
/*
@@ -1268,7 +1762,7 @@ retry_private:
restart->futex.val = val;
restart->futex.time = abs_time->tv64;
restart->futex.bitset = bitset;
- restart->futex.flags = 0;
+ restart->futex.flags = FLAGS_HAS_TIMEOUT;
if (fshared)
restart->futex.flags |= FLAGS_SHARED;
@@ -1280,6 +1774,10 @@ retry_private:
out_put_key:
put_futex_key(fshared, &q.key);
out:
+ if (to) {
+ hrtimer_cancel(&to->timer);
+ destroy_hrtimer_on_stack(&to->timer);
+ }
return ret;
}
@@ -1288,13 +1786,16 @@ static long futex_wait_restart(struct restart_block *restart)
{
u32 __user *uaddr = (u32 __user *)restart->futex.uaddr;
int fshared = 0;
- ktime_t t;
+ ktime_t t, *tp = NULL;
- t.tv64 = restart->futex.time;
+ if (restart->futex.flags & FLAGS_HAS_TIMEOUT) {
+ t.tv64 = restart->futex.time;
+ tp = &t;
+ }
restart->fn = do_no_restart_syscall;
if (restart->futex.flags & FLAGS_SHARED)
fshared = 1;
- return (long)futex_wait(uaddr, fshared, restart->futex.val, &t,
+ return (long)futex_wait(uaddr, fshared, restart->futex.val, tp,
restart->futex.bitset,
restart->futex.flags & FLAGS_CLOCKRT);
}
@@ -1310,11 +1811,10 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
int detect, ktime_t *time, int trylock)
{
struct hrtimer_sleeper timeout, *to = NULL;
- struct task_struct *curr = current;
struct futex_hash_bucket *hb;
- u32 uval, newval, curval;
+ u32 uval;
struct futex_q q;
- int ret, lock_taken, ownerdied = 0;
+ int res, ret;
if (refill_pi_state_cache())
return -ENOMEM;
@@ -1328,6 +1828,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
}
q.pi_state = NULL;
+ q.rt_waiter = NULL;
retry:
q.key = FUTEX_KEY_INIT;
ret = get_futex_key(uaddr, fshared, &q.key);
@@ -1337,81 +1838,15 @@ retry:
retry_private:
hb = queue_lock(&q);
-retry_locked:
- ret = lock_taken = 0;
-
- /*
- * To avoid races, we attempt to take the lock here again
- * (by doing a 0 -> TID atomic cmpxchg), while holding all
- * the locks. It will most likely not succeed.
- */
- newval = task_pid_vnr(current);
-
- curval = cmpxchg_futex_value_locked(uaddr, 0, newval);
-
- if (unlikely(curval == -EFAULT))
- goto uaddr_faulted;
-
- /*
- * Detect deadlocks. In case of REQUEUE_PI this is a valid
- * situation and we return success to user space.
- */
- if (unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(current))) {
- ret = -EDEADLK;
- goto out_unlock_put_key;
- }
-
- /*
- * Surprise - we got the lock. Just return to userspace:
- */
- if (unlikely(!curval))
- goto out_unlock_put_key;
-
- uval = curval;
-
- /*
- * Set the WAITERS flag, so the owner will know it has someone
- * to wake at next unlock
- */
- newval = curval | FUTEX_WAITERS;
-
- /*
- * There are two cases, where a futex might have no owner (the
- * owner TID is 0): OWNER_DIED. We take over the futex in this
- * case. We also do an unconditional take over, when the owner
- * of the futex died.
- *
- * This is safe as we are protected by the hash bucket lock !
- */
- if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
- /* Keep the OWNER_DIED bit */
- newval = (curval & ~FUTEX_TID_MASK) | task_pid_vnr(current);
- ownerdied = 0;
- lock_taken = 1;
- }
-
- curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
-
- if (unlikely(curval == -EFAULT))
- goto uaddr_faulted;
- if (unlikely(curval != uval))
- goto retry_locked;
-
- /*
- * We took the lock due to owner died take over.
- */
- if (unlikely(lock_taken))
- goto out_unlock_put_key;
-
- /*
- * We dont have the lock. Look up the PI state (or create it if
- * we are the first waiter):
- */
- ret = lookup_pi_state(uval, hb, &q.key, &q.pi_state);
-
+ ret = futex_lock_pi_atomic(uaddr, hb, &q.key, &q.pi_state, current, 0);
if (unlikely(ret)) {
switch (ret) {
-
+ case 1:
+ /* We got the lock. */
+ ret = 0;
+ goto out_unlock_put_key;
+ case -EFAULT:
+ goto uaddr_faulted;
case -EAGAIN:
/*
* Task is exiting and we just wait for the
@@ -1421,25 +1856,6 @@ retry_locked:
put_futex_key(fshared, &q.key);
cond_resched();
goto retry;
-
- case -ESRCH:
- /*
- * No owner found for this futex. Check if the
- * OWNER_DIED bit is set to figure out whether
- * this is a robust futex or not.
- */
- if (get_futex_value_locked(&curval, uaddr))
- goto uaddr_faulted;
-
- /*
- * We simply start over in case of a robust
- * futex. The code above will take the futex
- * and return happy.
- */
- if (curval & FUTEX_OWNER_DIED) {
- ownerdied = 1;
- goto retry_locked;
- }
default:
goto out_unlock_put_key;
}
@@ -1463,71 +1879,21 @@ retry_locked:
}
spin_lock(q.lock_ptr);
-
- if (!ret) {
- /*
- * Got the lock. We might not be the anticipated owner
- * if we did a lock-steal - fix up the PI-state in
- * that case:
- */
- if (q.pi_state->owner != curr)
- ret = fixup_pi_state_owner(uaddr, &q, curr, fshared);
- } else {
- /*
- * Catch the rare case, where the lock was released
- * when we were on the way back before we locked the
- * hash bucket.
- */
- if (q.pi_state->owner == curr) {
- /*
- * Try to get the rt_mutex now. This might
- * fail as some other task acquired the
- * rt_mutex after we removed ourself from the
- * rt_mutex waiters list.
- */
- if (rt_mutex_trylock(&q.pi_state->pi_mutex))
- ret = 0;
- else {
- /*
- * pi_state is incorrect, some other
- * task did a lock steal and we
- * returned due to timeout or signal
- * without taking the rt_mutex. Too
- * late. We can access the
- * rt_mutex_owner without locking, as
- * the other task is now blocked on
- * the hash bucket lock. Fix the state
- * up.
- */
- struct task_struct *owner;
- int res;
-
- owner = rt_mutex_owner(&q.pi_state->pi_mutex);
- res = fixup_pi_state_owner(uaddr, &q, owner,
- fshared);
-
- /* propagate -EFAULT, if the fixup failed */
- if (res)
- ret = res;
- }
- } else {
- /*
- * Paranoia check. If we did not take the lock
- * in the trylock above, then we should not be
- * the owner of the rtmutex, neither the real
- * nor the pending one:
- */
- if (rt_mutex_owner(&q.pi_state->pi_mutex) == curr)
- printk(KERN_ERR "futex_lock_pi: ret = %d "
- "pi-mutex: %p pi-state %p\n", ret,
- q.pi_state->pi_mutex.owner,
- q.pi_state->owner);
- }
- }
+ /*
+ * Fixup the pi_state owner and possibly acquire the lock if we
+ * haven't already.
+ */
+ res = fixup_owner(uaddr, fshared, &q, !ret);
+ /*
+ * If fixup_owner() returned an error, proprogate that. If it acquired
+ * the lock, clear our -ETIMEDOUT or -EINTR.
+ */
+ if (res)
+ ret = (res < 0) ? res : 0;
/*
- * If fixup_pi_state_owner() faulted and was unable to handle the
- * fault, unlock it and return the fault to userspace.
+ * If fixup_owner() faulted and was unable to handle the fault, unlock
+ * it and return the fault to userspace.
*/
if (ret && (rt_mutex_owner(&q.pi_state->pi_mutex) == current))
rt_mutex_unlock(&q.pi_state->pi_mutex);
@@ -1535,9 +1901,7 @@ retry_locked:
/* Unqueue and drop the lock */
unqueue_me_pi(&q);
- if (to)
- destroy_hrtimer_on_stack(&to->timer);
- return ret != -EINTR ? ret : -ERESTARTNOINTR;
+ goto out;
out_unlock_put_key:
queue_unlock(&q, hb);
@@ -1547,7 +1911,7 @@ out_put_key:
out:
if (to)
destroy_hrtimer_on_stack(&to->timer);
- return ret;
+ return ret != -EINTR ? ret : -ERESTARTNOINTR;
uaddr_faulted:
/*
@@ -1570,6 +1934,20 @@ uaddr_faulted:
goto retry;
}
+static long futex_lock_pi_restart(struct restart_block *restart)
+{
+ u32 __user *uaddr = (u32 __user *)restart->futex.uaddr;
+ ktime_t t, *tp = NULL;
+ int fshared = restart->futex.flags & FLAGS_SHARED;
+
+ if (restart->futex.flags & FLAGS_HAS_TIMEOUT) {
+ t.tv64 = restart->futex.time;
+ tp = &t;
+ }
+ restart->fn = do_no_restart_syscall;
+
+ return (long)futex_lock_pi(uaddr, fshared, restart->futex.val, tp, 0);
+}
/*
* Userspace attempted a TID -> 0 atomic transition, and failed.
@@ -1672,6 +2050,253 @@ pi_faulted:
return ret;
}
+/**
+ * handle_early_requeue_pi_wakeup() - Detect early wakeup on the initial futex
+ * @hb: the hash_bucket futex_q was original enqueued on
+ * @q: the futex_q woken while waiting to be requeued
+ * @key2: the futex_key of the requeue target futex
+ * @timeout: the timeout associated with the wait (NULL if none)
+ *
+ * Detect if the task was woken on the initial futex as opposed to the requeue
+ * target futex. If so, determine if it was a timeout or a signal that caused
+ * the wakeup and return the appropriate error code to the caller. Must be
+ * called with the hb lock held.
+ *
+ * Returns
+ * 0 - no early wakeup detected
+ * <0 - -ETIMEDOUT or -ERESTARTSYS (FIXME: or ERESTARTNOINTR?)
+ */
+static inline
+int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
+ struct futex_q *q, union futex_key *key2,
+ struct hrtimer_sleeper *timeout)
+{
+ int ret = 0;
+
+ /*
+ * With the hb lock held, we avoid races while we process the wakeup.
+ * We only need to hold hb (and not hb2) to ensure atomicity as the
+ * wakeup code can't change q.key from uaddr to uaddr2 if we hold hb.
+ * It can't be requeued from uaddr2 to something else since we don't
+ * support a PI aware source futex for requeue.
+ */
+ if (!match_futex(&q->key, key2)) {
+ WARN_ON(q->lock_ptr && (&hb->lock != q->lock_ptr));
+ /*
+ * We were woken prior to requeue by a timeout or a signal.
+ * Unqueue the futex_q and determine which it was.
+ */
+ plist_del(&q->list, &q->list.plist);
+ drop_futex_key_refs(&q->key);
+
+ if (timeout && !timeout->task)
+ ret = -ETIMEDOUT;
+ else {
+ /*
+ * We expect signal_pending(current), but another
+ * thread may have handled it for us already.
+ */
+ /* FIXME: ERESTARTSYS or ERESTARTNOINTR? Do we care if
+ * the user specified SA_RESTART or not? */
+ ret = -ERESTARTSYS;
+ }
+ }
+ return ret;
+}
+
+/**
+ * futex_wait_requeue_pi() - Wait on uaddr and take uaddr2
+ * @uaddr: the futex we initialyl wait on (non-pi)
+ * @fshared: whether the futexes are shared (1) or not (0). They must be
+ * the same type, no requeueing from private to shared, etc.
+ * @val: the expected value of uaddr
+ * @abs_time: absolute timeout
+ * @bitset: 32 bit wakeup bitset set by userspace, defaults to all.
+ * @clockrt: whether to use CLOCK_REALTIME (1) or CLOCK_MONOTONIC (0)
+ * @uaddr2: the pi futex we will take prior to returning to user-space
+ *
+ * The caller will wait on uaddr and will be requeued by futex_requeue() to
+ * uaddr2 which must be PI aware. Normal wakeup will wake on uaddr2 and
+ * complete the acquisition of the rt_mutex prior to returning to userspace.
+ * This ensures the rt_mutex maintains an owner when it has waiters; without
+ * one, the pi logic wouldn't know which task to boost/deboost, if there was a
+ * need to.
+ *
+ * We call schedule in futex_wait_queue_me() when we enqueue and return there
+ * via the following:
+ * 1) wakeup on uaddr2 after an atomic lock acquisition by futex_requeue()
+ * 2) wakeup on uaddr2 after a requeue and subsequent unlock
+ * 3) signal (before or after requeue)
+ * 4) timeout (before or after requeue)
+ *
+ * If 3, we setup a restart_block with futex_wait_requeue_pi() as the function.
+ *
+ * If 2, we may then block on trying to take the rt_mutex and return via:
+ * 5) successful lock
+ * 6) signal
+ * 7) timeout
+ * 8) other lock acquisition failure
+ *
+ * If 6, we setup a restart_block with futex_lock_pi() as the function.
+ *
+ * If 4 or 7, we cleanup and return with -ETIMEDOUT.
+ *
+ * Returns:
+ * 0 - On success
+ * <0 - On error
+ */
+static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared,
+ u32 val, ktime_t *abs_time, u32 bitset,
+ int clockrt, u32 __user *uaddr2)
+{
+ struct hrtimer_sleeper timeout, *to = NULL;
+ struct rt_mutex_waiter rt_waiter;
+ struct rt_mutex *pi_mutex = NULL;
+ DECLARE_WAITQUEUE(wait, current);
+ struct restart_block *restart;
+ struct futex_hash_bucket *hb;
+ union futex_key key2;
+ struct futex_q q;
+ int res, ret;
+ u32 uval;
+
+ if (!bitset)
+ return -EINVAL;
+
+ if (abs_time) {
+ to = &timeout;
+ hrtimer_init_on_stack(&to->timer, clockrt ? CLOCK_REALTIME :
+ CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ hrtimer_init_sleeper(to, current);
+ hrtimer_set_expires_range_ns(&to->timer, *abs_time,
+ current->timer_slack_ns);
+ }
+
+ /*
+ * The waiter is allocated on our stack, manipulated by the requeue
+ * code while we sleep on uaddr.
+ */
+ debug_rt_mutex_init_waiter(&rt_waiter);
+ rt_waiter.task = NULL;
+
+ q.pi_state = NULL;
+ q.bitset = bitset;
+ q.rt_waiter = &rt_waiter;
+
+ key2 = FUTEX_KEY_INIT;
+ ret = get_futex_key(uaddr2, fshared, &key2);
+ if (unlikely(ret != 0))
+ goto out;
+
+ /* Prepare to wait on uaddr. */
+ ret = futex_wait_setup(uaddr, val, fshared, &q, &hb);
+ if (ret) {
+ put_futex_key(fshared, &key2);
+ goto out;
+ }
+
+ /* Queue the futex_q, drop the hb lock, wait for wakeup. */
+ futex_wait_queue_me(hb, &q, to, &wait);
+
+ spin_lock(&hb->lock);
+ ret = handle_early_requeue_pi_wakeup(hb, &q, &key2, to);
+ spin_unlock(&hb->lock);
+ if (ret)
+ goto out_put_keys;
+
+ /*
+ * In order for us to be here, we know our q.key == key2, and since
+ * we took the hb->lock above, we also know that futex_requeue() has
+ * completed and we no longer have to concern ourselves with a wakeup
+ * race with the atomic proxy lock acquition by the requeue code.
+ */
+
+ /* Check if the requeue code acquired the second futex for us. */
+ if (!q.rt_waiter) {
+ /*
+ * Got the lock. We might not be the anticipated owner if we
+ * did a lock-steal - fix up the PI-state in that case.
+ */
+ if (q.pi_state && (q.pi_state->owner != current)) {
+ spin_lock(q.lock_ptr);
+ ret = fixup_pi_state_owner(uaddr2, &q, current,
+ fshared);
+ spin_unlock(q.lock_ptr);
+ }
+ } else {
+ /*
+ * We have been woken up by futex_unlock_pi(), a timeout, or a
+ * signal. futex_unlock_pi() will not destroy the lock_ptr nor
+ * the pi_state.
+ */
+ WARN_ON(!&q.pi_state);
+ pi_mutex = &q.pi_state->pi_mutex;
+ ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1);
+ debug_rt_mutex_free_waiter(&rt_waiter);
+
+ spin_lock(q.lock_ptr);
+ /*
+ * Fixup the pi_state owner and possibly acquire the lock if we
+ * haven't already.
+ */
+ res = fixup_owner(uaddr2, fshared, &q, !ret);
+ /*
+ * If fixup_owner() returned an error, proprogate that. If it
+ * acquired the lock, clear our -ETIMEDOUT or -EINTR.
+ */
+ if (res)
+ ret = (res < 0) ? res : 0;
+
+ /* Unqueue and drop the lock. */
+ unqueue_me_pi(&q);
+ }
+
+ /*
+ * If fixup_pi_state_owner() faulted and was unable to handle the
+ * fault, unlock the rt_mutex and return the fault to userspace.
+ */
+ if (ret == -EFAULT) {
+ if (rt_mutex_owner(pi_mutex) == current)
+ rt_mutex_unlock(pi_mutex);
+ } else if (ret == -EINTR) {
+ ret = -EFAULT;
+ if (get_user(uval, uaddr2))
+ goto out_put_keys;
+
+ /*
+ * We've already been requeued, so restart by calling
+ * futex_lock_pi() directly, rather then returning to this
+ * function.
+ */
+ ret = -ERESTART_RESTARTBLOCK;
+ restart = &current_thread_info()->restart_block;
+ restart->fn = futex_lock_pi_restart;
+ restart->futex.uaddr = (u32 *)uaddr2;
+ restart->futex.val = uval;
+ restart->futex.flags = 0;
+ if (abs_time) {
+ restart->futex.flags |= FLAGS_HAS_TIMEOUT;
+ restart->futex.time = abs_time->tv64;
+ }
+
+ if (fshared)
+ restart->futex.flags |= FLAGS_SHARED;
+ if (clockrt)
+ restart->futex.flags |= FLAGS_CLOCKRT;
+ }
+
+out_put_keys:
+ put_futex_key(fshared, &q.key);
+ put_futex_key(fshared, &key2);
+
+out:
+ if (to) {
+ hrtimer_cancel(&to->timer);
+ destroy_hrtimer_on_stack(&to->timer);
+ }
+ return ret;
+}
+
/*
* Support for robust futexes: the kernel cleans up held futexes at
* thread exit time.
@@ -1894,7 +2519,7 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
fshared = 1;
clockrt = op & FUTEX_CLOCK_REALTIME;
- if (clockrt && cmd != FUTEX_WAIT_BITSET)
+ if (clockrt && cmd != FUTEX_WAIT_BITSET && cmd != FUTEX_WAIT_REQUEUE_PI)
return -ENOSYS;
switch (cmd) {
@@ -1909,10 +2534,11 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
ret = futex_wake(uaddr, fshared, val, val3);
break;
case FUTEX_REQUEUE:
- ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, NULL);
+ ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, NULL, 0);
break;
case FUTEX_CMP_REQUEUE:
- ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, &val3);
+ ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, &val3,
+ 0);
break;
case FUTEX_WAKE_OP:
ret = futex_wake_op(uaddr, fshared, uaddr2, val, val2, val3);
@@ -1929,6 +2555,15 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
if (futex_cmpxchg_enabled)
ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1);
break;
+ case FUTEX_WAIT_REQUEUE_PI:
+ val3 = FUTEX_BITSET_MATCH_ANY;
+ ret = futex_wait_requeue_pi(uaddr, fshared, val, timeout, val3,
+ clockrt, uaddr2);
+ break;
+ case FUTEX_CMP_REQUEUE_PI:
+ ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, &val3,
+ 1);
+ break;
default:
ret = -ENOSYS;
}
@@ -1946,7 +2581,8 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
int cmd = op & FUTEX_CMD_MASK;
if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
- cmd == FUTEX_WAIT_BITSET)) {
+ cmd == FUTEX_WAIT_BITSET ||
+ cmd == FUTEX_WAIT_REQUEUE_PI)) {
if (copy_from_user(&ts, utime, sizeof(ts)) != 0)
return -EFAULT;
if (!timespec_valid(&ts))
@@ -1958,11 +2594,11 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
tp = &t;
}
/*
- * requeue parameter in 'utime' if cmd == FUTEX_REQUEUE.
+ * requeue parameter in 'utime' if cmd == FUTEX_*_REQUEUE_*.
* number of waiters to wake in 'utime' if cmd == FUTEX_WAKE_OP.
*/
if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE ||
- cmd == FUTEX_WAKE_OP)
+ cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP)
val2 = (u32) (unsigned long) utime;
return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile
index 3394f8f52964..7d047808419d 100644
--- a/kernel/irq/Makefile
+++ b/kernel/irq/Makefile
@@ -3,5 +3,5 @@ obj-y := handle.o manage.o spurious.o resend.o chip.o devres.o
obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
-obj-$(CONFIG_NUMA_MIGRATE_IRQ_DESC) += numa_migrate.o
+obj-$(CONFIG_NUMA_IRQ_DESC) += numa_migrate.o
obj-$(CONFIG_PM_SLEEP) += pm.o
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index c687ba4363f2..13c68e71b726 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -359,7 +359,6 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
spin_lock(&desc->lock);
mask_ack_irq(desc, irq);
- desc = irq_remap_to_desc(irq, desc);
if (unlikely(desc->status & IRQ_INPROGRESS))
goto out_unlock;
@@ -438,7 +437,6 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
desc->status &= ~IRQ_INPROGRESS;
out:
desc->chip->eoi(irq);
- desc = irq_remap_to_desc(irq, desc);
spin_unlock(&desc->lock);
}
@@ -475,7 +473,6 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
!desc->action)) {
desc->status |= (IRQ_PENDING | IRQ_MASKED);
mask_ack_irq(desc, irq);
- desc = irq_remap_to_desc(irq, desc);
goto out_unlock;
}
kstat_incr_irqs_this_cpu(irq, desc);
@@ -483,7 +480,6 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
/* Start handling the irq */
if (desc->chip->ack)
desc->chip->ack(irq);
- desc = irq_remap_to_desc(irq, desc);
/* Mark the IRQ currently in progress.*/
desc->status |= IRQ_INPROGRESS;
@@ -544,10 +540,8 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
if (!noirqdebug)
note_interrupt(irq, desc, action_ret);
- if (desc->chip->eoi) {
+ if (desc->chip->eoi)
desc->chip->eoi(irq);
- desc = irq_remap_to_desc(irq, desc);
- }
}
void
@@ -582,10 +576,8 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
/* Uninstall? */
if (handle == handle_bad_irq) {
- if (desc->chip != &no_irq_chip) {
+ if (desc->chip != &no_irq_chip)
mask_ack_irq(desc, irq);
- desc = irq_remap_to_desc(irq, desc);
- }
desc->status |= IRQ_DISABLED;
desc->depth = 1;
}
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 26e08754744f..33ff8f55befe 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -17,8 +17,8 @@
#include <linux/kernel_stat.h>
#include <linux/rculist.h>
#include <linux/hash.h>
-#include <trace/irq.h>
#include <linux/bootmem.h>
+#include <trace/events/irq.h>
#include "internals.h"
@@ -81,12 +81,10 @@ static struct irq_desc irq_desc_init = {
.lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
};
-void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
+void init_kstat_irqs(struct irq_desc *desc, int node, int nr)
{
- int node;
void *ptr;
- node = cpu_to_node(cpu);
ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs), GFP_ATOMIC, node);
/*
@@ -94,32 +92,32 @@ void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
* init_copy_kstat_irqs() could still use old one
*/
if (ptr) {
- printk(KERN_DEBUG " alloc kstat_irqs on cpu %d node %d\n",
- cpu, node);
+ printk(KERN_DEBUG " alloc kstat_irqs on node %d\n", node);
desc->kstat_irqs = ptr;
}
}
-static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
+static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
{
memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
spin_lock_init(&desc->lock);
desc->irq = irq;
#ifdef CONFIG_SMP
- desc->cpu = cpu;
+ desc->node = node;
#endif
lockdep_set_class(&desc->lock, &irq_desc_lock_class);
- init_kstat_irqs(desc, cpu, nr_cpu_ids);
+ init_kstat_irqs(desc, node, nr_cpu_ids);
if (!desc->kstat_irqs) {
printk(KERN_ERR "can not alloc kstat_irqs\n");
BUG_ON(1);
}
- if (!init_alloc_desc_masks(desc, cpu, false)) {
+ if (!alloc_desc_masks(desc, node, false)) {
printk(KERN_ERR "can not alloc irq_desc cpumasks\n");
BUG_ON(1);
}
- arch_init_chip_data(desc, cpu);
+ init_desc_masks(desc);
+ arch_init_chip_data(desc, node);
}
/*
@@ -169,7 +167,8 @@ int __init early_irq_init(void)
desc[i].irq = i;
desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
- init_alloc_desc_masks(&desc[i], 0, true);
+ alloc_desc_masks(&desc[i], 0, true);
+ init_desc_masks(&desc[i]);
irq_desc_ptrs[i] = desc + i;
}
@@ -187,11 +186,10 @@ struct irq_desc *irq_to_desc(unsigned int irq)
return NULL;
}
-struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
+struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
{
struct irq_desc *desc;
unsigned long flags;
- int node;
if (irq >= nr_irqs) {
WARN(1, "irq (%d) >= nr_irqs (%d) in irq_to_desc_alloc\n",
@@ -210,15 +208,13 @@ struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
if (desc)
goto out_unlock;
- node = cpu_to_node(cpu);
desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
- printk(KERN_DEBUG " alloc irq_desc for %d on cpu %d node %d\n",
- irq, cpu, node);
+ printk(KERN_DEBUG " alloc irq_desc for %d on node %d\n", irq, node);
if (!desc) {
printk(KERN_ERR "can not alloc irq_desc\n");
BUG_ON(1);
}
- init_one_irq_desc(irq, desc, cpu);
+ init_one_irq_desc(irq, desc, node);
irq_desc_ptrs[irq] = desc;
@@ -256,7 +252,8 @@ int __init early_irq_init(void)
for (i = 0; i < count; i++) {
desc[i].irq = i;
- init_alloc_desc_masks(&desc[i], 0, true);
+ alloc_desc_masks(&desc[i], 0, true);
+ init_desc_masks(&desc[i]);
desc[i].kstat_irqs = kstat_irqs_all[i];
}
return arch_early_irq_init();
@@ -267,7 +264,7 @@ struct irq_desc *irq_to_desc(unsigned int irq)
return (irq < NR_IRQS) ? irq_desc + irq : NULL;
}
-struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
+struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
{
return irq_to_desc(irq);
}
@@ -348,9 +345,6 @@ static void warn_no_thread(unsigned int irq, struct irqaction *action)
"but no thread function available.", irq, action->name);
}
-DEFINE_TRACE(irq_handler_entry);
-DEFINE_TRACE(irq_handler_exit);
-
/**
* handle_IRQ_event - irq action chain handler
* @irq: the interrupt number
@@ -453,11 +447,8 @@ unsigned int __do_IRQ(unsigned int irq)
/*
* No locking required for CPU-local interrupts:
*/
- if (desc->chip->ack) {
+ if (desc->chip->ack)
desc->chip->ack(irq);
- /* get new one */
- desc = irq_remap_to_desc(irq, desc);
- }
if (likely(!(desc->status & IRQ_DISABLED))) {
action_ret = handle_IRQ_event(irq, desc->action);
if (!noirqdebug)
@@ -468,10 +459,8 @@ unsigned int __do_IRQ(unsigned int irq)
}
spin_lock(&desc->lock);
- if (desc->chip->ack) {
+ if (desc->chip->ack)
desc->chip->ack(irq);
- desc = irq_remap_to_desc(irq, desc);
- }
/*
* REPLAY is when Linux resends an IRQ that was dropped earlier
* WAITING is used by probe to mark irqs that are being tested
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 01ce20eab38f..73468253143b 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -16,7 +16,7 @@ extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
extern struct lock_class_key irq_desc_lock_class;
-extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr);
+extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
extern void clear_kstat_irqs(struct irq_desc *desc);
extern spinlock_t sparse_irq_lock;
@@ -42,6 +42,9 @@ static inline void unregister_handler_proc(unsigned int irq,
extern int irq_select_affinity_usr(unsigned int irq);
+extern void
+irq_set_thread_affinity(struct irq_desc *desc, const struct cpumask *cpumask);
+
/*
* Debugging printout:
*/
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 2734eca59243..5524ec07089c 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -80,7 +80,7 @@ int irq_can_set_affinity(unsigned int irq)
return 1;
}
-static void
+void
irq_set_thread_affinity(struct irq_desc *desc, const struct cpumask *cpumask)
{
struct irqaction *action = desc->action;
@@ -109,17 +109,22 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
spin_lock_irqsave(&desc->lock, flags);
#ifdef CONFIG_GENERIC_PENDING_IRQ
- if (desc->status & IRQ_MOVE_PCNTXT)
- desc->chip->set_affinity(irq, cpumask);
+ if (desc->status & IRQ_MOVE_PCNTXT) {
+ if (!desc->chip->set_affinity(irq, cpumask)) {
+ cpumask_copy(desc->affinity, cpumask);
+ irq_set_thread_affinity(desc, cpumask);
+ }
+ }
else {
desc->status |= IRQ_MOVE_PENDING;
cpumask_copy(desc->pending_mask, cpumask);
}
#else
- cpumask_copy(desc->affinity, cpumask);
- desc->chip->set_affinity(irq, cpumask);
+ if (!desc->chip->set_affinity(irq, cpumask)) {
+ cpumask_copy(desc->affinity, cpumask);
+ irq_set_thread_affinity(desc, cpumask);
+ }
#endif
- irq_set_thread_affinity(desc, cpumask);
desc->status |= IRQ_AFFINITY_SET;
spin_unlock_irqrestore(&desc->lock, flags);
return 0;
@@ -930,7 +935,7 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
kfree(action);
#ifdef CONFIG_DEBUG_SHIRQ
- if (irqflags & IRQF_SHARED) {
+ if (!retval && (irqflags & IRQF_SHARED)) {
/*
* It's a shared IRQ -- the driver ought to be prepared for it
* to happen immediately, so let's make sure....
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index e05ad9be43b7..cfe767ca1545 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -1,5 +1,8 @@
#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include "internals.h"
void move_masked_irq(int irq)
{
@@ -39,11 +42,12 @@ void move_masked_irq(int irq)
* masking the irqs.
*/
if (likely(cpumask_any_and(desc->pending_mask, cpu_online_mask)
- < nr_cpu_ids)) {
- cpumask_and(desc->affinity,
- desc->pending_mask, cpu_online_mask);
- desc->chip->set_affinity(irq, desc->affinity);
- }
+ < nr_cpu_ids))
+ if (!desc->chip->set_affinity(irq, desc->pending_mask)) {
+ cpumask_copy(desc->affinity, desc->pending_mask);
+ irq_set_thread_affinity(desc, desc->pending_mask);
+ }
+
cpumask_clear(desc->pending_mask);
}
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index 44bbdcbaf8d2..2f69bee57bf2 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -15,9 +15,9 @@
static void init_copy_kstat_irqs(struct irq_desc *old_desc,
struct irq_desc *desc,
- int cpu, int nr)
+ int node, int nr)
{
- init_kstat_irqs(desc, cpu, nr);
+ init_kstat_irqs(desc, node, nr);
if (desc->kstat_irqs != old_desc->kstat_irqs)
memcpy(desc->kstat_irqs, old_desc->kstat_irqs,
@@ -34,20 +34,20 @@ static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)
}
static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,
- struct irq_desc *desc, int cpu)
+ struct irq_desc *desc, int node)
{
memcpy(desc, old_desc, sizeof(struct irq_desc));
- if (!init_alloc_desc_masks(desc, cpu, false)) {
+ if (!alloc_desc_masks(desc, node, false)) {
printk(KERN_ERR "irq %d: can not get new irq_desc cpumask "
"for migration.\n", irq);
return false;
}
spin_lock_init(&desc->lock);
- desc->cpu = cpu;
+ desc->node = node;
lockdep_set_class(&desc->lock, &irq_desc_lock_class);
- init_copy_kstat_irqs(old_desc, desc, cpu, nr_cpu_ids);
+ init_copy_kstat_irqs(old_desc, desc, node, nr_cpu_ids);
init_copy_desc_masks(old_desc, desc);
- arch_init_copy_chip_data(old_desc, desc, cpu);
+ arch_init_copy_chip_data(old_desc, desc, node);
return true;
}
@@ -59,12 +59,11 @@ static void free_one_irq_desc(struct irq_desc *old_desc, struct irq_desc *desc)
}
static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
- int cpu)
+ int node)
{
struct irq_desc *desc;
unsigned int irq;
unsigned long flags;
- int node;
irq = old_desc->irq;
@@ -76,7 +75,6 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
if (desc && old_desc != desc)
goto out_unlock;
- node = cpu_to_node(cpu);
desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
if (!desc) {
printk(KERN_ERR "irq %d: can not get new irq_desc "
@@ -85,7 +83,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
desc = old_desc;
goto out_unlock;
}
- if (!init_copy_one_irq_desc(irq, old_desc, desc, cpu)) {
+ if (!init_copy_one_irq_desc(irq, old_desc, desc, node)) {
/* still use old one */
kfree(desc);
desc = old_desc;
@@ -97,9 +95,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
/* free the old one */
free_one_irq_desc(old_desc, desc);
- spin_unlock(&old_desc->lock);
kfree(old_desc);
- spin_lock(&desc->lock);
return desc;
@@ -109,24 +105,14 @@ out_unlock:
return desc;
}
-struct irq_desc *move_irq_desc(struct irq_desc *desc, int cpu)
+struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
{
- int old_cpu;
- int node, old_node;
-
/* those all static, do move them */
if (desc->irq < NR_IRQS_LEGACY)
return desc;
- old_cpu = desc->cpu;
- if (old_cpu != cpu) {
- node = cpu_to_node(cpu);
- old_node = cpu_to_node(old_cpu);
- if (old_node != node)
- desc = __real_move_irq_desc(desc, cpu);
- else
- desc->cpu = cpu;
- }
+ if (desc->node != node)
+ desc = __real_move_irq_desc(desc, node);
return desc;
}
diff --git a/kernel/kgdb.c b/kernel/kgdb.c
index e4dcfb2272a4..b5ea4650f2ea 100644
--- a/kernel/kgdb.c
+++ b/kernel/kgdb.c
@@ -363,7 +363,7 @@ static void put_packet(char *buffer)
* Convert the memory pointed to by mem into hex, placing result in buf.
* Return a pointer to the last char put in buf (null). May return an error.
*/
-int kgdb_mem2hex(char *mem, char *buf, int count)
+int __weak kgdb_mem2hex(char *mem, char *buf, int count)
{
char *tmp;
int err;
@@ -393,7 +393,7 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
* 0x7d escaped with 0x7d. Return a pointer to the character after
* the last byte written.
*/
-static int kgdb_ebin2mem(char *buf, char *mem, int count)
+int __weak kgdb_ebin2mem(char *buf, char *mem, int count)
{
int err = 0;
char c;
@@ -418,7 +418,7 @@ static int kgdb_ebin2mem(char *buf, char *mem, int count)
* Return a pointer to the character AFTER the last byte written.
* May return an error.
*/
-int kgdb_hex2mem(char *buf, char *mem, int count)
+int __weak kgdb_hex2mem(char *buf, char *mem, int count)
{
char *tmp_raw;
char *tmp_hex;
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index a5e74ddee0e2..c0fa54b276d9 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -319,6 +319,22 @@ struct kprobe __kprobes *get_kprobe(void *addr)
return NULL;
}
+/* Arm a kprobe with text_mutex */
+static void __kprobes arm_kprobe(struct kprobe *kp)
+{
+ mutex_lock(&text_mutex);
+ arch_arm_kprobe(kp);
+ mutex_unlock(&text_mutex);
+}
+
+/* Disarm a kprobe with text_mutex */
+static void __kprobes disarm_kprobe(struct kprobe *kp)
+{
+ mutex_lock(&text_mutex);
+ arch_disarm_kprobe(kp);
+ mutex_unlock(&text_mutex);
+}
+
/*
* Aggregate handlers for multiple kprobes support - these handlers
* take care of invoking the individual kprobe handlers on p->list
@@ -538,7 +554,7 @@ static int __kprobes add_new_kprobe(struct kprobe *ap, struct kprobe *p)
ap->flags &= ~KPROBE_FLAG_DISABLED;
if (!kprobes_all_disarmed)
/* Arm the breakpoint again. */
- arch_arm_kprobe(ap);
+ arm_kprobe(ap);
}
return 0;
}
@@ -789,11 +805,8 @@ static int __kprobes __unregister_kprobe_top(struct kprobe *p)
* enabled and not gone - otherwise, the breakpoint would
* already have been removed. We save on flushing icache.
*/
- if (!kprobes_all_disarmed && !kprobe_disabled(old_p)) {
- mutex_lock(&text_mutex);
- arch_disarm_kprobe(p);
- mutex_unlock(&text_mutex);
- }
+ if (!kprobes_all_disarmed && !kprobe_disabled(old_p))
+ disarm_kprobe(p);
hlist_del_rcu(&old_p->hlist);
} else {
if (p->break_handler && !kprobe_gone(p))
@@ -810,7 +823,7 @@ noclean:
if (!kprobe_disabled(old_p)) {
try_to_disable_aggr_kprobe(old_p);
if (!kprobes_all_disarmed && kprobe_disabled(old_p))
- arch_disarm_kprobe(old_p);
+ disarm_kprobe(old_p);
}
}
return 0;
@@ -1364,7 +1377,7 @@ int __kprobes disable_kprobe(struct kprobe *kp)
try_to_disable_aggr_kprobe(p);
if (!kprobes_all_disarmed && kprobe_disabled(p))
- arch_disarm_kprobe(p);
+ disarm_kprobe(p);
out:
mutex_unlock(&kprobe_mutex);
return ret;
@@ -1393,7 +1406,7 @@ int __kprobes enable_kprobe(struct kprobe *kp)
}
if (!kprobes_all_disarmed && kprobe_disabled(p))
- arch_arm_kprobe(p);
+ arm_kprobe(p);
p->flags &= ~KPROBE_FLAG_DISABLED;
if (p != kp)
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 4ebaf8519abf..41c88fe40500 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -13,7 +13,7 @@
#include <linux/file.h>
#include <linux/module.h>
#include <linux/mutex.h>
-#include <trace/sched.h>
+#include <trace/events/sched.h>
#define KTHREAD_NICE_LEVEL (-5)
@@ -21,9 +21,6 @@ static DEFINE_SPINLOCK(kthread_create_lock);
static LIST_HEAD(kthread_create_list);
struct task_struct *kthreadd_task;
-DEFINE_TRACE(sched_kthread_stop);
-DEFINE_TRACE(sched_kthread_stop_ret);
-
struct kthread_create_info
{
/* Information passed to kthread() from kthreadd. */
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index accb40cdb12a..8bbeef996c76 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -42,12 +42,14 @@
#include <linux/hash.h>
#include <linux/ftrace.h>
#include <linux/stringify.h>
-#include <trace/lockdep.h>
#include <asm/sections.h>
#include "lockdep_internals.h"
+#define CREATE_TRACE_POINTS
+#include <trace/events/lockdep.h>
+
#ifdef CONFIG_PROVE_LOCKING
int prove_locking = 1;
module_param(prove_locking, int, 0644);
@@ -2935,8 +2937,6 @@ void lock_set_class(struct lockdep_map *lock, const char *name,
}
EXPORT_SYMBOL_GPL(lock_set_class);
-DEFINE_TRACE(lock_acquire);
-
/*
* We are not always called with irqs disabled - do that here,
* and also avoid lockdep recursion:
@@ -2963,8 +2963,6 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
}
EXPORT_SYMBOL_GPL(lock_acquire);
-DEFINE_TRACE(lock_release);
-
void lock_release(struct lockdep_map *lock, int nested,
unsigned long ip)
{
@@ -3105,6 +3103,8 @@ found_it:
hlock->holdtime_stamp = now;
}
+ trace_lock_acquired(lock, ip, waittime);
+
stats = get_lock_stats(hlock_class(hlock));
if (waittime) {
if (hlock->read)
@@ -3120,8 +3120,6 @@ found_it:
lock->ip = ip;
}
-DEFINE_TRACE(lock_contended);
-
void lock_contended(struct lockdep_map *lock, unsigned long ip)
{
unsigned long flags;
@@ -3143,14 +3141,10 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
}
EXPORT_SYMBOL_GPL(lock_contended);
-DEFINE_TRACE(lock_acquired);
-
void lock_acquired(struct lockdep_map *lock, unsigned long ip)
{
unsigned long flags;
- trace_lock_acquired(lock, ip);
-
if (unlikely(!lock_stat))
return;
diff --git a/kernel/module.c b/kernel/module.c
index e797812a4d95..278e9b6762bb 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -18,6 +18,7 @@
*/
#include <linux/module.h>
#include <linux/moduleloader.h>
+#include <linux/ftrace_event.h>
#include <linux/init.h>
#include <linux/kallsyms.h>
#include <linux/fs.h>
@@ -72,6 +73,9 @@ DEFINE_MUTEX(module_mutex);
EXPORT_SYMBOL_GPL(module_mutex);
static LIST_HEAD(modules);
+/* Block module loading/unloading? */
+int modules_disabled = 0;
+
/* Waiting for a module to finish initializing? */
static DECLARE_WAIT_QUEUE_HEAD(module_wq);
@@ -777,7 +781,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
char name[MODULE_NAME_LEN];
int ret, forced = 0;
- if (!capable(CAP_SYS_MODULE))
+ if (!capable(CAP_SYS_MODULE) || modules_disabled)
return -EPERM;
if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
@@ -1489,9 +1493,6 @@ static void free_module(struct module *mod)
/* Free any allocated parameters. */
destroy_params(mod->kp, mod->num_kp);
- /* release any pointers to mcount in this module */
- ftrace_release(mod->module_core, mod->core_size);
-
/* This may be NULL, but that's OK */
module_free(mod, mod->module_init);
kfree(mod->args);
@@ -1892,11 +1893,9 @@ static noinline struct module *load_module(void __user *umod,
unsigned int symindex = 0;
unsigned int strindex = 0;
unsigned int modindex, versindex, infoindex, pcpuindex;
- unsigned int num_mcount;
struct module *mod;
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
- unsigned long *mseg;
mm_segment_t old_fs;
DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
@@ -2172,7 +2171,19 @@ static noinline struct module *load_module(void __user *umod,
sizeof(*mod->tracepoints),
&mod->num_tracepoints);
#endif
-
+#ifdef CONFIG_EVENT_TRACING
+ mod->trace_events = section_objs(hdr, sechdrs, secstrings,
+ "_ftrace_events",
+ sizeof(*mod->trace_events),
+ &mod->num_trace_events);
+#endif
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+ /* sechdrs[0].sh_size is always zero */
+ mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings,
+ "__mcount_loc",
+ sizeof(*mod->ftrace_callsites),
+ &mod->num_ftrace_callsites);
+#endif
#ifdef CONFIG_MODVERSIONS
if ((mod->num_syms && !mod->crcs)
|| (mod->num_gpl_syms && !mod->gpl_crcs)
@@ -2237,11 +2248,6 @@ static noinline struct module *load_module(void __user *umod,
dynamic_debug_setup(debug, num_debug);
}
- /* sechdrs[0].sh_size is always zero */
- mseg = section_objs(hdr, sechdrs, secstrings, "__mcount_loc",
- sizeof(*mseg), &num_mcount);
- ftrace_init_module(mod, mseg, mseg + num_mcount);
-
err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
goto cleanup;
@@ -2302,7 +2308,6 @@ static noinline struct module *load_module(void __user *umod,
cleanup:
kobject_del(&mod->mkobj.kobj);
kobject_put(&mod->mkobj.kobj);
- ftrace_release(mod->module_core, mod->core_size);
free_unload:
module_unload_free(mod);
#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
@@ -2336,7 +2341,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
int ret = 0;
/* Must have permission */
- if (!capable(CAP_SYS_MODULE))
+ if (!capable(CAP_SYS_MODULE) || modules_disabled)
return -EPERM;
/* Only one module load at a time, please */
diff --git a/kernel/mutex.c b/kernel/mutex.c
index 507cf2b5e9f1..e5cc0cd28d54 100644
--- a/kernel/mutex.c
+++ b/kernel/mutex.c
@@ -249,7 +249,9 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
/* didnt get the lock, go to sleep: */
spin_unlock_mutex(&lock->wait_lock, flags);
- __schedule();
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
spin_lock_mutex(&lock->wait_lock, flags);
}
@@ -471,5 +473,28 @@ int __sched mutex_trylock(struct mutex *lock)
return ret;
}
-
EXPORT_SYMBOL(mutex_trylock);
+
+/**
+ * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0
+ * @cnt: the atomic which we are to dec
+ * @lock: the mutex to return holding if we dec to 0
+ *
+ * return true and hold lock if we dec to 0, return false otherwise
+ */
+int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock)
+{
+ /* dec if we can't possibly hit 0 */
+ if (atomic_add_unless(cnt, -1, 1))
+ return 0;
+ /* we might hit 0, so take the lock */
+ mutex_lock(lock);
+ if (!atomic_dec_and_test(cnt)) {
+ /* when we actually did the dec, we didn't hit 0 */
+ mutex_unlock(lock);
+ return 0;
+ }
+ /* we hit 0, and we hold the lock */
+ return 1;
+}
+EXPORT_SYMBOL(atomic_dec_and_mutex_lock);
diff --git a/kernel/panic.c b/kernel/panic.c
index 3dcaa1661357..874ecf1307ae 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -340,7 +340,7 @@ void oops_exit(void)
}
#ifdef WANT_WARN_ON_SLOWPATH
-void warn_slowpath(const char *file, int line, const char *fmt, ...)
+void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...)
{
va_list args;
char function[KSYM_SYMBOL_LEN];
@@ -356,7 +356,7 @@ void warn_slowpath(const char *file, int line, const char *fmt, ...)
if (board)
printk(KERN_WARNING "Hardware name: %s\n", board);
- if (fmt) {
+ if (*fmt) {
va_start(args, fmt);
vprintk(fmt, args);
va_end(args);
@@ -367,7 +367,14 @@ void warn_slowpath(const char *file, int line, const char *fmt, ...)
print_oops_end_marker();
add_taint(TAINT_WARN);
}
-EXPORT_SYMBOL(warn_slowpath);
+EXPORT_SYMBOL(warn_slowpath_fmt);
+
+void warn_slowpath_null(const char *file, int line)
+{
+ static const char *empty = "";
+ warn_slowpath_fmt(file, line, empty);
+}
+EXPORT_SYMBOL(warn_slowpath_null);
#endif
#ifdef CONFIG_CC_STACKPROTECTOR
diff --git a/kernel/params.c b/kernel/params.c
index de273ec85bd2..7f6912ced2ba 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -24,9 +24,6 @@
#include <linux/err.h>
#include <linux/slab.h>
-/* We abuse the high bits of "perm" to record whether we kmalloc'ed. */
-#define KPARAM_KMALLOCED 0x80000000
-
#if 0
#define DEBUGP printk
#else
@@ -220,13 +217,13 @@ int param_set_charp(const char *val, struct kernel_param *kp)
return -ENOSPC;
}
- if (kp->perm & KPARAM_KMALLOCED)
+ if (kp->flags & KPARAM_KMALLOCED)
kfree(*(char **)kp->arg);
/* This is a hack. We can't need to strdup in early boot, and we
* don't need to; this mangled commandline is preserved. */
if (slab_is_available()) {
- kp->perm |= KPARAM_KMALLOCED;
+ kp->flags |= KPARAM_KMALLOCED;
*(char **)kp->arg = kstrdup(val, GFP_KERNEL);
if (!kp->arg)
return -ENOMEM;
@@ -241,44 +238,63 @@ int param_get_charp(char *buffer, struct kernel_param *kp)
return sprintf(buffer, "%s", *((char **)kp->arg));
}
+/* Actually could be a bool or an int, for historical reasons. */
int param_set_bool(const char *val, struct kernel_param *kp)
{
+ bool v;
+
/* No equals means "set"... */
if (!val) val = "1";
/* One of =[yYnN01] */
switch (val[0]) {
case 'y': case 'Y': case '1':
- *(int *)kp->arg = 1;
- return 0;
+ v = true;
+ break;
case 'n': case 'N': case '0':
- *(int *)kp->arg = 0;
- return 0;
+ v = false;
+ break;
+ default:
+ return -EINVAL;
}
- return -EINVAL;
+
+ if (kp->flags & KPARAM_ISBOOL)
+ *(bool *)kp->arg = v;
+ else
+ *(int *)kp->arg = v;
+ return 0;
}
int param_get_bool(char *buffer, struct kernel_param *kp)
{
+ bool val;
+ if (kp->flags & KPARAM_ISBOOL)
+ val = *(bool *)kp->arg;
+ else
+ val = *(int *)kp->arg;
+
/* Y and N chosen as being relatively non-coder friendly */
- return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'Y' : 'N');
+ return sprintf(buffer, "%c", val ? 'Y' : 'N');
}
+/* This one must be bool. */
int param_set_invbool(const char *val, struct kernel_param *kp)
{
- int boolval, ret;
+ int ret;
+ bool boolval;
struct kernel_param dummy;
dummy.arg = &boolval;
+ dummy.flags = KPARAM_ISBOOL;
ret = param_set_bool(val, &dummy);
if (ret == 0)
- *(int *)kp->arg = !boolval;
+ *(bool *)kp->arg = !boolval;
return ret;
}
int param_get_invbool(char *buffer, struct kernel_param *kp)
{
- return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'N' : 'Y');
+ return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y');
}
/* We break the rule and mangle the string. */
@@ -591,7 +607,7 @@ void destroy_params(const struct kernel_param *params, unsigned num)
unsigned int i;
for (i = 0; i < num; i++)
- if (params[i].perm & KPARAM_KMALLOCED)
+ if (params[i].flags & KPARAM_KMALLOCED)
kfree(*(char **)params[i].arg);
}
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 0692ab5a0d67..37a8d813f223 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -25,16 +25,6 @@
/*
- * Initialize a new task whose father had been ptraced.
- *
- * Called from copy_process().
- */
-void ptrace_fork(struct task_struct *child, unsigned long clone_flags)
-{
- arch_ptrace_fork(child, clone_flags);
-}
-
-/*
* ptrace a task: make the debugger its new parent and
* move it to the ptrace list.
*
@@ -185,10 +175,11 @@ int ptrace_attach(struct task_struct *task)
if (same_thread_group(task, current))
goto out;
- /* Protect exec's credential calculations against our interference;
- * SUID, SGID and LSM creds get determined differently under ptrace.
+ /* Protect the target's credential calculations against our
+ * interference; SUID, SGID and LSM creds get determined differently
+ * under ptrace.
*/
- retval = mutex_lock_interruptible(&task->cred_exec_mutex);
+ retval = mutex_lock_interruptible(&task->cred_guard_mutex);
if (retval < 0)
goto out;
@@ -232,7 +223,7 @@ repeat:
bad:
write_unlock_irqrestore(&tasklist_lock, flags);
task_unlock(task);
- mutex_unlock(&task->cred_exec_mutex);
+ mutex_unlock(&task->cred_guard_mutex);
out:
return retval;
}
diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c
index ce97a4df64d3..beb0e659adcc 100644
--- a/kernel/rcupreempt.c
+++ b/kernel/rcupreempt.c
@@ -1356,17 +1356,11 @@ static int rcu_sched_grace_period(void *arg)
rcu_ctrlblk.sched_sleep = rcu_sched_sleeping;
spin_unlock_irqrestore(&rcu_ctrlblk.schedlock, flags);
- ret = 0;
+ ret = 0; /* unused */
__wait_event_interruptible(rcu_ctrlblk.sched_wq,
rcu_ctrlblk.sched_sleep != rcu_sched_sleeping,
ret);
- /*
- * Signals would prevent us from sleeping, and we cannot
- * do much with them in any case. So flush them.
- */
- if (ret)
- flush_signals(current);
couldsleepnext = 0;
} while (!kthread_should_stop());
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index d2a372fb0b9b..0dccfbba6d26 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1259,31 +1259,44 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
check_cpu_stall(rsp, rdp);
/* Is the RCU core waiting for a quiescent state from this CPU? */
- if (rdp->qs_pending)
+ if (rdp->qs_pending) {
+ rdp->n_rp_qs_pending++;
return 1;
+ }
/* Does this CPU have callbacks ready to invoke? */
- if (cpu_has_callbacks_ready_to_invoke(rdp))
+ if (cpu_has_callbacks_ready_to_invoke(rdp)) {
+ rdp->n_rp_cb_ready++;
return 1;
+ }
/* Has RCU gone idle with this CPU needing another grace period? */
- if (cpu_needs_another_gp(rsp, rdp))
+ if (cpu_needs_another_gp(rsp, rdp)) {
+ rdp->n_rp_cpu_needs_gp++;
return 1;
+ }
/* Has another RCU grace period completed? */
- if (ACCESS_ONCE(rsp->completed) != rdp->completed) /* outside of lock */
+ if (ACCESS_ONCE(rsp->completed) != rdp->completed) { /* outside lock */
+ rdp->n_rp_gp_completed++;
return 1;
+ }
/* Has a new RCU grace period started? */
- if (ACCESS_ONCE(rsp->gpnum) != rdp->gpnum) /* outside of lock */
+ if (ACCESS_ONCE(rsp->gpnum) != rdp->gpnum) { /* outside lock */
+ rdp->n_rp_gp_started++;
return 1;
+ }
/* Has an RCU GP gone long enough to send resched IPIs &c? */
if (ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum) &&
- ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0))
+ ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)) {
+ rdp->n_rp_need_fqs++;
return 1;
+ }
/* nothing to do */
+ rdp->n_rp_need_nothing++;
return 0;
}
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c
index 4b1875ba9404..fe1dcdbf1ca3 100644
--- a/kernel/rcutree_trace.c
+++ b/kernel/rcutree_trace.c
@@ -213,7 +213,63 @@ static struct file_operations rcugp_fops = {
.release = single_release,
};
-static struct dentry *rcudir, *datadir, *datadir_csv, *hierdir, *gpdir;
+static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp)
+{
+ seq_printf(m, "%3d%cnp=%ld "
+ "qsp=%ld cbr=%ld cng=%ld gpc=%ld gps=%ld nf=%ld nn=%ld\n",
+ rdp->cpu,
+ cpu_is_offline(rdp->cpu) ? '!' : ' ',
+ rdp->n_rcu_pending,
+ rdp->n_rp_qs_pending,
+ rdp->n_rp_cb_ready,
+ rdp->n_rp_cpu_needs_gp,
+ rdp->n_rp_gp_completed,
+ rdp->n_rp_gp_started,
+ rdp->n_rp_need_fqs,
+ rdp->n_rp_need_nothing);
+}
+
+static void print_rcu_pendings(struct seq_file *m, struct rcu_state *rsp)
+{
+ int cpu;
+ struct rcu_data *rdp;
+
+ for_each_possible_cpu(cpu) {
+ rdp = rsp->rda[cpu];
+ if (rdp->beenonline)
+ print_one_rcu_pending(m, rdp);
+ }
+}
+
+static int show_rcu_pending(struct seq_file *m, void *unused)
+{
+ seq_puts(m, "rcu:\n");
+ print_rcu_pendings(m, &rcu_state);
+ seq_puts(m, "rcu_bh:\n");
+ print_rcu_pendings(m, &rcu_bh_state);
+ return 0;
+}
+
+static int rcu_pending_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, show_rcu_pending, NULL);
+}
+
+static struct file_operations rcu_pending_fops = {
+ .owner = THIS_MODULE,
+ .open = rcu_pending_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct dentry *rcudir;
+static struct dentry *datadir;
+static struct dentry *datadir_csv;
+static struct dentry *gpdir;
+static struct dentry *hierdir;
+static struct dentry *rcu_pendingdir;
+
static int __init rcuclassic_trace_init(void)
{
rcudir = debugfs_create_dir("rcu", NULL);
@@ -238,6 +294,11 @@ static int __init rcuclassic_trace_init(void)
NULL, &rcuhier_fops);
if (!hierdir)
goto free_out;
+
+ rcu_pendingdir = debugfs_create_file("rcu_pending", 0444, rcudir,
+ NULL, &rcu_pending_fops);
+ if (!rcu_pendingdir)
+ goto free_out;
return 0;
free_out:
if (datadir)
@@ -257,6 +318,7 @@ static void __exit rcuclassic_trace_cleanup(void)
debugfs_remove(datadir_csv);
debugfs_remove(gpdir);
debugfs_remove(hierdir);
+ debugfs_remove(rcu_pendingdir);
debugfs_remove(rcudir);
}
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
index 69d9cb921ffa..820c5af44f3e 100644
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -300,7 +300,8 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
* assigned pending owner [which might not have taken the
* lock yet]:
*/
-static inline int try_to_steal_lock(struct rt_mutex *lock)
+static inline int try_to_steal_lock(struct rt_mutex *lock,
+ struct task_struct *task)
{
struct task_struct *pendowner = rt_mutex_owner(lock);
struct rt_mutex_waiter *next;
@@ -309,11 +310,11 @@ static inline int try_to_steal_lock(struct rt_mutex *lock)
if (!rt_mutex_owner_pending(lock))
return 0;
- if (pendowner == current)
+ if (pendowner == task)
return 1;
spin_lock_irqsave(&pendowner->pi_lock, flags);
- if (current->prio >= pendowner->prio) {
+ if (task->prio >= pendowner->prio) {
spin_unlock_irqrestore(&pendowner->pi_lock, flags);
return 0;
}
@@ -338,21 +339,21 @@ static inline int try_to_steal_lock(struct rt_mutex *lock)
* We are going to steal the lock and a waiter was
* enqueued on the pending owners pi_waiters queue. So
* we have to enqueue this waiter into
- * current->pi_waiters list. This covers the case,
- * where current is boosted because it holds another
+ * task->pi_waiters list. This covers the case,
+ * where task is boosted because it holds another
* lock and gets unboosted because the booster is
* interrupted, so we would delay a waiter with higher
- * priority as current->normal_prio.
+ * priority as task->normal_prio.
*
* Note: in the rare case of a SCHED_OTHER task changing
* its priority and thus stealing the lock, next->task
- * might be current:
+ * might be task:
*/
- if (likely(next->task != current)) {
- spin_lock_irqsave(&current->pi_lock, flags);
- plist_add(&next->pi_list_entry, &current->pi_waiters);
- __rt_mutex_adjust_prio(current);
- spin_unlock_irqrestore(&current->pi_lock, flags);
+ if (likely(next->task != task)) {
+ spin_lock_irqsave(&task->pi_lock, flags);
+ plist_add(&next->pi_list_entry, &task->pi_waiters);
+ __rt_mutex_adjust_prio(task);
+ spin_unlock_irqrestore(&task->pi_lock, flags);
}
return 1;
}
@@ -389,7 +390,7 @@ static int try_to_take_rt_mutex(struct rt_mutex *lock)
*/
mark_rt_mutex_waiters(lock);
- if (rt_mutex_owner(lock) && !try_to_steal_lock(lock))
+ if (rt_mutex_owner(lock) && !try_to_steal_lock(lock, current))
return 0;
/* We got the lock. */
@@ -411,6 +412,7 @@ static int try_to_take_rt_mutex(struct rt_mutex *lock)
*/
static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
struct rt_mutex_waiter *waiter,
+ struct task_struct *task,
int detect_deadlock)
{
struct task_struct *owner = rt_mutex_owner(lock);
@@ -418,21 +420,21 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
unsigned long flags;
int chain_walk = 0, res;
- spin_lock_irqsave(&current->pi_lock, flags);
- __rt_mutex_adjust_prio(current);
- waiter->task = current;
+ spin_lock_irqsave(&task->pi_lock, flags);
+ __rt_mutex_adjust_prio(task);
+ waiter->task = task;
waiter->lock = lock;
- plist_node_init(&waiter->list_entry, current->prio);
- plist_node_init(&waiter->pi_list_entry, current->prio);
+ plist_node_init(&waiter->list_entry, task->prio);
+ plist_node_init(&waiter->pi_list_entry, task->prio);
/* Get the top priority waiter on the lock */
if (rt_mutex_has_waiters(lock))
top_waiter = rt_mutex_top_waiter(lock);
plist_add(&waiter->list_entry, &lock->wait_list);
- current->pi_blocked_on = waiter;
+ task->pi_blocked_on = waiter;
- spin_unlock_irqrestore(&current->pi_lock, flags);
+ spin_unlock_irqrestore(&task->pi_lock, flags);
if (waiter == rt_mutex_top_waiter(lock)) {
spin_lock_irqsave(&owner->pi_lock, flags);
@@ -460,7 +462,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
spin_unlock(&lock->wait_lock);
res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter,
- current);
+ task);
spin_lock(&lock->wait_lock);
@@ -605,37 +607,25 @@ void rt_mutex_adjust_pi(struct task_struct *task)
rt_mutex_adjust_prio_chain(task, 0, NULL, NULL, task);
}
-/*
- * Slow path lock function:
+/**
+ * __rt_mutex_slowlock() - Perform the wait-wake-try-to-take loop
+ * @lock: the rt_mutex to take
+ * @state: the state the task should block in (TASK_INTERRUPTIBLE
+ * or TASK_UNINTERRUPTIBLE)
+ * @timeout: the pre-initialized and started timer, or NULL for none
+ * @waiter: the pre-initialized rt_mutex_waiter
+ * @detect_deadlock: passed to task_blocks_on_rt_mutex
+ *
+ * lock->wait_lock must be held by the caller.
*/
static int __sched
-rt_mutex_slowlock(struct rt_mutex *lock, int state,
- struct hrtimer_sleeper *timeout,
- int detect_deadlock)
+__rt_mutex_slowlock(struct rt_mutex *lock, int state,
+ struct hrtimer_sleeper *timeout,
+ struct rt_mutex_waiter *waiter,
+ int detect_deadlock)
{
- struct rt_mutex_waiter waiter;
int ret = 0;
- debug_rt_mutex_init_waiter(&waiter);
- waiter.task = NULL;
-
- spin_lock(&lock->wait_lock);
-
- /* Try to acquire the lock again: */
- if (try_to_take_rt_mutex(lock)) {
- spin_unlock(&lock->wait_lock);
- return 0;
- }
-
- set_current_state(state);
-
- /* Setup the timer, when timeout != NULL */
- if (unlikely(timeout)) {
- hrtimer_start_expires(&timeout->timer, HRTIMER_MODE_ABS);
- if (!hrtimer_active(&timeout->timer))
- timeout->task = NULL;
- }
-
for (;;) {
/* Try to acquire the lock: */
if (try_to_take_rt_mutex(lock))
@@ -656,19 +646,19 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state,
}
/*
- * waiter.task is NULL the first time we come here and
+ * waiter->task is NULL the first time we come here and
* when we have been woken up by the previous owner
* but the lock got stolen by a higher prio task.
*/
- if (!waiter.task) {
- ret = task_blocks_on_rt_mutex(lock, &waiter,
+ if (!waiter->task) {
+ ret = task_blocks_on_rt_mutex(lock, waiter, current,
detect_deadlock);
/*
* If we got woken up by the owner then start loop
* all over without going into schedule to try
* to get the lock now:
*/
- if (unlikely(!waiter.task)) {
+ if (unlikely(!waiter->task)) {
/*
* Reset the return value. We might
* have returned with -EDEADLK and the
@@ -684,15 +674,52 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state,
spin_unlock(&lock->wait_lock);
- debug_rt_mutex_print_deadlock(&waiter);
+ debug_rt_mutex_print_deadlock(waiter);
- if (waiter.task)
+ if (waiter->task)
schedule_rt_mutex(lock);
spin_lock(&lock->wait_lock);
set_current_state(state);
}
+ return ret;
+}
+
+/*
+ * Slow path lock function:
+ */
+static int __sched
+rt_mutex_slowlock(struct rt_mutex *lock, int state,
+ struct hrtimer_sleeper *timeout,
+ int detect_deadlock)
+{
+ struct rt_mutex_waiter waiter;
+ int ret = 0;
+
+ debug_rt_mutex_init_waiter(&waiter);
+ waiter.task = NULL;
+
+ spin_lock(&lock->wait_lock);
+
+ /* Try to acquire the lock again: */
+ if (try_to_take_rt_mutex(lock)) {
+ spin_unlock(&lock->wait_lock);
+ return 0;
+ }
+
+ set_current_state(state);
+
+ /* Setup the timer, when timeout != NULL */
+ if (unlikely(timeout)) {
+ hrtimer_start_expires(&timeout->timer, HRTIMER_MODE_ABS);
+ if (!hrtimer_active(&timeout->timer))
+ timeout->task = NULL;
+ }
+
+ ret = __rt_mutex_slowlock(lock, state, timeout, &waiter,
+ detect_deadlock);
+
set_current_state(TASK_RUNNING);
if (unlikely(waiter.task))
@@ -864,9 +891,9 @@ int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock,
EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible);
/**
- * rt_mutex_lock_interruptible_ktime - lock a rt_mutex interruptible
- * the timeout structure is provided
- * by the caller
+ * rt_mutex_timed_lock - lock a rt_mutex interruptible
+ * the timeout structure is provided
+ * by the caller
*
* @lock: the rt_mutex to be locked
* @timeout: timeout structure or NULL (no timeout)
@@ -913,7 +940,7 @@ void __sched rt_mutex_unlock(struct rt_mutex *lock)
}
EXPORT_SYMBOL_GPL(rt_mutex_unlock);
-/***
+/**
* rt_mutex_destroy - mark a mutex unusable
* @lock: the mutex to be destroyed
*
@@ -986,6 +1013,59 @@ void rt_mutex_proxy_unlock(struct rt_mutex *lock,
}
/**
+ * rt_mutex_start_proxy_lock() - Start lock acquisition for another task
+ * @lock: the rt_mutex to take
+ * @waiter: the pre-initialized rt_mutex_waiter
+ * @task: the task to prepare
+ * @detect_deadlock: perform deadlock detection (1) or not (0)
+ *
+ * Returns:
+ * 0 - task blocked on lock
+ * 1 - acquired the lock for task, caller should wake it up
+ * <0 - error
+ *
+ * Special API call for FUTEX_REQUEUE_PI support.
+ */
+int rt_mutex_start_proxy_lock(struct rt_mutex *lock,
+ struct rt_mutex_waiter *waiter,
+ struct task_struct *task, int detect_deadlock)
+{
+ int ret;
+
+ spin_lock(&lock->wait_lock);
+
+ mark_rt_mutex_waiters(lock);
+
+ if (!rt_mutex_owner(lock) || try_to_steal_lock(lock, task)) {
+ /* We got the lock for task. */
+ debug_rt_mutex_lock(lock);
+
+ rt_mutex_set_owner(lock, task, 0);
+
+ rt_mutex_deadlock_account_lock(lock, task);
+ return 1;
+ }
+
+ ret = task_blocks_on_rt_mutex(lock, waiter, task, detect_deadlock);
+
+
+ if (ret && !waiter->task) {
+ /*
+ * Reset the return value. We might have
+ * returned with -EDEADLK and the owner
+ * released the lock while we were walking the
+ * pi chain. Let the waiter sort it out.
+ */
+ ret = 0;
+ }
+ spin_unlock(&lock->wait_lock);
+
+ debug_rt_mutex_print_deadlock(waiter);
+
+ return ret;
+}
+
+/**
* rt_mutex_next_owner - return the next owner of the lock
*
* @lock: the rt lock query
@@ -1004,3 +1084,57 @@ struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock)
return rt_mutex_top_waiter(lock)->task;
}
+
+/**
+ * rt_mutex_finish_proxy_lock() - Complete lock acquisition
+ * @lock: the rt_mutex we were woken on
+ * @to: the timeout, null if none. hrtimer should already have
+ * been started.
+ * @waiter: the pre-initialized rt_mutex_waiter
+ * @detect_deadlock: perform deadlock detection (1) or not (0)
+ *
+ * Complete the lock acquisition started our behalf by another thread.
+ *
+ * Returns:
+ * 0 - success
+ * <0 - error, one of -EINTR, -ETIMEDOUT, or -EDEADLK
+ *
+ * Special API call for PI-futex requeue support
+ */
+int rt_mutex_finish_proxy_lock(struct rt_mutex *lock,
+ struct hrtimer_sleeper *to,
+ struct rt_mutex_waiter *waiter,
+ int detect_deadlock)
+{
+ int ret;
+
+ spin_lock(&lock->wait_lock);
+
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ ret = __rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, to, waiter,
+ detect_deadlock);
+
+ set_current_state(TASK_RUNNING);
+
+ if (unlikely(waiter->task))
+ remove_waiter(lock, waiter);
+
+ /*
+ * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might
+ * have to fix that up.
+ */
+ fixup_rt_mutex_waiters(lock);
+
+ spin_unlock(&lock->wait_lock);
+
+ /*
+ * Readjust priority, when we did not get the lock. We might have been
+ * the pending owner and boosted. Since we did not take the lock, the
+ * PI boost has to go.
+ */
+ if (unlikely(ret))
+ rt_mutex_adjust_prio(current);
+
+ return ret;
+}
diff --git a/kernel/rtmutex_common.h b/kernel/rtmutex_common.h
index e124bf5800ea..97a2f81866af 100644
--- a/kernel/rtmutex_common.h
+++ b/kernel/rtmutex_common.h
@@ -120,6 +120,14 @@ extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
struct task_struct *proxy_owner);
extern void rt_mutex_proxy_unlock(struct rt_mutex *lock,
struct task_struct *proxy_owner);
+extern int rt_mutex_start_proxy_lock(struct rt_mutex *lock,
+ struct rt_mutex_waiter *waiter,
+ struct task_struct *task,
+ int detect_deadlock);
+extern int rt_mutex_finish_proxy_lock(struct rt_mutex *lock,
+ struct hrtimer_sleeper *to,
+ struct rt_mutex_waiter *waiter,
+ int detect_deadlock);
#ifdef CONFIG_DEBUG_RT_MUTEXES
# include "rtmutex-debug.h"
diff --git a/kernel/sched.c b/kernel/sched.c
index 26efa475bdc1..d6fa89ce687b 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -72,13 +72,15 @@
#include <linux/debugfs.h>
#include <linux/ctype.h>
#include <linux/ftrace.h>
-#include <trace/sched.h>
#include <asm/tlb.h>
#include <asm/irq_regs.h>
#include "sched_cpupri.h"
+#define CREATE_TRACE_POINTS
+#include <trace/events/sched.h>
+
/*
* Convert user-nice values [ -20 ... 0 ... 19 ]
* to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
@@ -118,12 +120,6 @@
*/
#define RUNTIME_INF ((u64)~0ULL)
-DEFINE_TRACE(sched_wait_task);
-DEFINE_TRACE(sched_wakeup);
-DEFINE_TRACE(sched_wakeup_new);
-DEFINE_TRACE(sched_switch);
-DEFINE_TRACE(sched_migrate_task);
-
#ifdef CONFIG_SMP
static void double_rq_lock(struct rq *rq1, struct rq *rq2);
@@ -1958,7 +1954,7 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
clock_offset = old_rq->clock - new_rq->clock;
- trace_sched_migrate_task(p, task_cpu(p), new_cpu);
+ trace_sched_migrate_task(p, new_cpu);
#ifdef CONFIG_SCHEDSTATS
if (p->se.wait_start)
@@ -2015,6 +2011,49 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
}
/*
+ * wait_task_context_switch - wait for a thread to complete at least one
+ * context switch.
+ *
+ * @p must not be current.
+ */
+void wait_task_context_switch(struct task_struct *p)
+{
+ unsigned long nvcsw, nivcsw, flags;
+ int running;
+ struct rq *rq;
+
+ nvcsw = p->nvcsw;
+ nivcsw = p->nivcsw;
+ for (;;) {
+ /*
+ * The runqueue is assigned before the actual context
+ * switch. We need to take the runqueue lock.
+ *
+ * We could check initially without the lock but it is
+ * very likely that we need to take the lock in every
+ * iteration.
+ */
+ rq = task_rq_lock(p, &flags);
+ running = task_running(rq, p);
+ task_rq_unlock(rq, &flags);
+
+ if (likely(!running))
+ break;
+ /*
+ * The switch count is incremented before the actual
+ * context switch. We thus wait for two switches to be
+ * sure at least one completed.
+ */
+ if ((p->nvcsw - nvcsw) > 1)
+ break;
+ if ((p->nivcsw - nivcsw) > 1)
+ break;
+
+ cpu_relax();
+ }
+}
+
+/*
* wait_task_inactive - wait for a thread to unschedule.
*
* If @match_state is nonzero, it's the @p->state value just checked and
@@ -2458,6 +2497,17 @@ out:
return success;
}
+/**
+ * wake_up_process - Wake up a specific process
+ * @p: The process to be woken up.
+ *
+ * Attempt to wake up the nominated process and move it to the set of runnable
+ * processes. Returns 1 if the process was woken up, 0 if it was already
+ * running.
+ *
+ * It may be assumed that this function implies a write memory barrier before
+ * changing the task state if and only if any tasks are woken up.
+ */
int wake_up_process(struct task_struct *p)
{
return try_to_wake_up(p, TASK_ALL, 0);
@@ -2766,7 +2816,7 @@ context_switch(struct rq *rq, struct task_struct *prev,
* combine the page table reload and the switch backend into
* one hypercall.
*/
- arch_enter_lazy_cpu_mode();
+ arch_start_context_switch(prev);
if (unlikely(!mm)) {
next->active_mm = oldmm;
@@ -4240,10 +4290,126 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
static struct {
atomic_t load_balancer;
cpumask_var_t cpu_mask;
+ cpumask_var_t ilb_grp_nohz_mask;
} nohz ____cacheline_aligned = {
.load_balancer = ATOMIC_INIT(-1),
};
+#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
+/**
+ * lowest_flag_domain - Return lowest sched_domain containing flag.
+ * @cpu: The cpu whose lowest level of sched domain is to
+ * be returned.
+ * @flag: The flag to check for the lowest sched_domain
+ * for the given cpu.
+ *
+ * Returns the lowest sched_domain of a cpu which contains the given flag.
+ */
+static inline struct sched_domain *lowest_flag_domain(int cpu, int flag)
+{
+ struct sched_domain *sd;
+
+ for_each_domain(cpu, sd)
+ if (sd && (sd->flags & flag))
+ break;
+
+ return sd;
+}
+
+/**
+ * for_each_flag_domain - Iterates over sched_domains containing the flag.
+ * @cpu: The cpu whose domains we're iterating over.
+ * @sd: variable holding the value of the power_savings_sd
+ * for cpu.
+ * @flag: The flag to filter the sched_domains to be iterated.
+ *
+ * Iterates over all the scheduler domains for a given cpu that has the 'flag'
+ * set, starting from the lowest sched_domain to the highest.
+ */
+#define for_each_flag_domain(cpu, sd, flag) \
+ for (sd = lowest_flag_domain(cpu, flag); \
+ (sd && (sd->flags & flag)); sd = sd->parent)
+
+/**
+ * is_semi_idle_group - Checks if the given sched_group is semi-idle.
+ * @ilb_group: group to be checked for semi-idleness
+ *
+ * Returns: 1 if the group is semi-idle. 0 otherwise.
+ *
+ * We define a sched_group to be semi idle if it has atleast one idle-CPU
+ * and atleast one non-idle CPU. This helper function checks if the given
+ * sched_group is semi-idle or not.
+ */
+static inline int is_semi_idle_group(struct sched_group *ilb_group)
+{
+ cpumask_and(nohz.ilb_grp_nohz_mask, nohz.cpu_mask,
+ sched_group_cpus(ilb_group));
+
+ /*
+ * A sched_group is semi-idle when it has atleast one busy cpu
+ * and atleast one idle cpu.
+ */
+ if (cpumask_empty(nohz.ilb_grp_nohz_mask))
+ return 0;
+
+ if (cpumask_equal(nohz.ilb_grp_nohz_mask, sched_group_cpus(ilb_group)))
+ return 0;
+
+ return 1;
+}
+/**
+ * find_new_ilb - Finds the optimum idle load balancer for nomination.
+ * @cpu: The cpu which is nominating a new idle_load_balancer.
+ *
+ * Returns: Returns the id of the idle load balancer if it exists,
+ * Else, returns >= nr_cpu_ids.
+ *
+ * This algorithm picks the idle load balancer such that it belongs to a
+ * semi-idle powersavings sched_domain. The idea is to try and avoid
+ * completely idle packages/cores just for the purpose of idle load balancing
+ * when there are other idle cpu's which are better suited for that job.
+ */
+static int find_new_ilb(int cpu)
+{
+ struct sched_domain *sd;
+ struct sched_group *ilb_group;
+
+ /*
+ * Have idle load balancer selection from semi-idle packages only
+ * when power-aware load balancing is enabled
+ */
+ if (!(sched_smt_power_savings || sched_mc_power_savings))
+ goto out_done;
+
+ /*
+ * Optimize for the case when we have no idle CPUs or only one
+ * idle CPU. Don't walk the sched_domain hierarchy in such cases
+ */
+ if (cpumask_weight(nohz.cpu_mask) < 2)
+ goto out_done;
+
+ for_each_flag_domain(cpu, sd, SD_POWERSAVINGS_BALANCE) {
+ ilb_group = sd->groups;
+
+ do {
+ if (is_semi_idle_group(ilb_group))
+ return cpumask_first(nohz.ilb_grp_nohz_mask);
+
+ ilb_group = ilb_group->next;
+
+ } while (ilb_group != sd->groups);
+ }
+
+out_done:
+ return cpumask_first(nohz.cpu_mask);
+}
+#else /* (CONFIG_SCHED_MC || CONFIG_SCHED_SMT) */
+static inline int find_new_ilb(int call_cpu)
+{
+ return cpumask_first(nohz.cpu_mask);
+}
+#endif
+
/*
* This routine will try to nominate the ilb (idle load balancing)
* owner among the cpus whose ticks are stopped. ilb owner will do the idle
@@ -4298,8 +4464,24 @@ int select_nohz_load_balancer(int stop_tick)
/* make me the ilb owner */
if (atomic_cmpxchg(&nohz.load_balancer, -1, cpu) == -1)
return 1;
- } else if (atomic_read(&nohz.load_balancer) == cpu)
+ } else if (atomic_read(&nohz.load_balancer) == cpu) {
+ int new_ilb;
+
+ if (!(sched_smt_power_savings ||
+ sched_mc_power_savings))
+ return 1;
+ /*
+ * Check to see if there is a more power-efficient
+ * ilb.
+ */
+ new_ilb = find_new_ilb(cpu);
+ if (new_ilb < nr_cpu_ids && new_ilb != cpu) {
+ atomic_set(&nohz.load_balancer, -1);
+ resched_cpu(new_ilb);
+ return 0;
+ }
return 1;
+ }
} else {
if (!cpumask_test_cpu(cpu, nohz.cpu_mask))
return 0;
@@ -4468,15 +4650,7 @@ static inline void trigger_load_balance(struct rq *rq, int cpu)
}
if (atomic_read(&nohz.load_balancer) == -1) {
- /*
- * simple selection for now: Nominate the
- * first cpu in the nohz list to be the next
- * ilb owner.
- *
- * TBD: Traverse the sched domains and nominate
- * the nearest cpu in the nohz.cpu_mask.
- */
- int ilb = cpumask_first(nohz.cpu_mask);
+ int ilb = find_new_ilb(cpu);
if (ilb < nr_cpu_ids)
resched_cpu(ilb);
@@ -5007,13 +5181,15 @@ pick_next_task(struct rq *rq)
/*
* schedule() is the main scheduler function.
*/
-asmlinkage void __sched __schedule(void)
+asmlinkage void __sched schedule(void)
{
struct task_struct *prev, *next;
unsigned long *switch_count;
struct rq *rq;
int cpu;
+need_resched:
+ preempt_disable();
cpu = smp_processor_id();
rq = cpu_rq(cpu);
rcu_qsctr_inc(cpu);
@@ -5070,15 +5246,9 @@ need_resched_nonpreemptible:
if (unlikely(reacquire_kernel_lock(current) < 0))
goto need_resched_nonpreemptible;
-}
-asmlinkage void __sched schedule(void)
-{
-need_resched:
- preempt_disable();
- __schedule();
preempt_enable_no_resched();
- if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
+ if (need_resched())
goto need_resched;
}
EXPORT_SYMBOL(schedule);
@@ -5221,7 +5391,7 @@ EXPORT_SYMBOL(default_wake_function);
* started to run but is not in state TASK_RUNNING. try_to_wake_up() returns
* zero in this (rare) case, and we handle it by continuing to scan the queue.
*/
-void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
+static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, int sync, void *key)
{
wait_queue_t *curr, *next;
@@ -5241,6 +5411,9 @@ void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
* @mode: which threads
* @nr_exclusive: how many wake-one or wake-many threads to wake up
* @key: is directly passed to the wakeup function
+ *
+ * It may be assumed that this function implies a write memory barrier before
+ * changing the task state if and only if any tasks are woken up.
*/
void __wake_up(wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, void *key)
@@ -5279,6 +5452,9 @@ void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key)
* with each other. This can prevent needless bouncing between CPUs.
*
* On UP it can prevent extra preemption.
+ *
+ * It may be assumed that this function implies a write memory barrier before
+ * changing the task state if and only if any tasks are woken up.
*/
void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, void *key)
@@ -5315,6 +5491,9 @@ EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */
* awakened in the same order in which they were queued.
*
* See also complete_all(), wait_for_completion() and related routines.
+ *
+ * It may be assumed that this function implies a write memory barrier before
+ * changing the task state if and only if any tasks are woken up.
*/
void complete(struct completion *x)
{
@@ -5332,6 +5511,9 @@ EXPORT_SYMBOL(complete);
* @x: holds the state of this particular completion
*
* This will wake up all threads waiting on this particular completion event.
+ *
+ * It may be assumed that this function implies a write memory barrier before
+ * changing the task state if and only if any tasks are woken up.
*/
void complete_all(struct completion *x)
{
@@ -6490,8 +6672,9 @@ void sched_show_task(struct task_struct *p)
#ifdef CONFIG_DEBUG_STACK_USAGE
free = stack_not_used(p);
#endif
- printk(KERN_CONT "%5lu %5d %6d\n", free,
- task_pid_nr(p), task_pid_nr(p->real_parent));
+ printk(KERN_CONT "%5lu %5d %6d 0x%08lx\n", free,
+ task_pid_nr(p), task_pid_nr(p->real_parent),
+ (unsigned long)task_thread_info(p)->flags);
show_stack(p, NULL);
}
@@ -7875,7 +8058,7 @@ static void init_numa_sched_groups_power(struct sched_group *group_head)
struct sched_domain *sd;
sd = &per_cpu(phys_domains, j).sd;
- if (j != cpumask_first(sched_group_cpus(sd->groups))) {
+ if (j != group_first_cpu(sd->groups)) {
/*
* Only add "power" once for each
* physical package.
@@ -7953,7 +8136,7 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd)
WARN_ON(!sd || !sd->groups);
- if (cpu != cpumask_first(sched_group_cpus(sd->groups)))
+ if (cpu != group_first_cpu(sd->groups))
return;
child = sd->child;
@@ -9055,6 +9238,7 @@ void __init sched_init(void)
#ifdef CONFIG_SMP
#ifdef CONFIG_NO_HZ
alloc_bootmem_cpumask_var(&nohz.cpu_mask);
+ alloc_bootmem_cpumask_var(&nohz.ilb_grp_nohz_mask);
#endif
alloc_bootmem_cpumask_var(&cpu_isolated_map);
#endif /* SMP */
@@ -9800,6 +9984,13 @@ static int sched_rt_global_constraints(void)
if (sysctl_sched_rt_period <= 0)
return -EINVAL;
+ /*
+ * There's always some RT tasks in the root group
+ * -- migration, kstopmachine etc..
+ */
+ if (sysctl_sched_rt_runtime == 0)
+ return -EBUSY;
+
spin_lock_irqsave(&def_rt_bandwidth.rt_runtime_lock, flags);
for_each_possible_cpu(i) {
struct rt_rq *rt_rq = &cpu_rq(i)->rt;
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
index 819f17ac796e..e1d16c9a7680 100644
--- a/kernel/sched_clock.c
+++ b/kernel/sched_clock.c
@@ -38,7 +38,8 @@
*/
unsigned long long __attribute__((weak)) sched_clock(void)
{
- return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
+ return (unsigned long long)(jiffies - INITIAL_JIFFIES)
+ * (NSEC_PER_SEC / HZ);
}
static __read_mostly int sched_clock_running;
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 3816f217f119..5f9650e8fe75 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -1487,17 +1487,10 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
find_matching_se(&se, &pse);
- while (se) {
- BUG_ON(!pse);
+ BUG_ON(!pse);
- if (wakeup_preempt_entity(se, pse) == 1) {
- resched_task(curr);
- break;
- }
-
- se = parent_entity(se);
- pse = parent_entity(pse);
- }
+ if (wakeup_preempt_entity(se, pse) == 1)
+ resched_task(curr);
}
static struct task_struct *pick_next_task_fair(struct rq *rq)
diff --git a/kernel/signal.c b/kernel/signal.c
index d8034737db4c..809a228019ad 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -27,7 +27,7 @@
#include <linux/freezer.h>
#include <linux/pid_namespace.h>
#include <linux/nsproxy.h>
-#include <trace/sched.h>
+#include <trace/events/sched.h>
#include <asm/param.h>
#include <asm/uaccess.h>
@@ -41,8 +41,6 @@
static struct kmem_cache *sigqueue_cachep;
-DEFINE_TRACE(sched_signal_send);
-
static void __user *sig_handler(struct task_struct *t, int sig)
{
return t->sighand->action[sig - 1].sa.sa_handler;
@@ -249,14 +247,19 @@ void flush_sigqueue(struct sigpending *queue)
/*
* Flush all pending signals for a task.
*/
+void __flush_signals(struct task_struct *t)
+{
+ clear_tsk_thread_flag(t, TIF_SIGPENDING);
+ flush_sigqueue(&t->pending);
+ flush_sigqueue(&t->signal->shared_pending);
+}
+
void flush_signals(struct task_struct *t)
{
unsigned long flags;
spin_lock_irqsave(&t->sighand->siglock, flags);
- clear_tsk_thread_flag(t, TIF_SIGPENDING);
- flush_sigqueue(&t->pending);
- flush_sigqueue(&t->signal->shared_pending);
+ __flush_signals(t);
spin_unlock_irqrestore(&t->sighand->siglock, flags);
}
@@ -2278,24 +2281,17 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
return kill_something_info(sig, &info, pid);
}
-static int do_tkill(pid_t tgid, pid_t pid, int sig)
+static int
+do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
{
- int error;
- struct siginfo info;
struct task_struct *p;
unsigned long flags;
-
- error = -ESRCH;
- info.si_signo = sig;
- info.si_errno = 0;
- info.si_code = SI_TKILL;
- info.si_pid = task_tgid_vnr(current);
- info.si_uid = current_uid();
+ int error = -ESRCH;
rcu_read_lock();
p = find_task_by_vpid(pid);
if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) {
- error = check_kill_permission(sig, &info, p);
+ error = check_kill_permission(sig, info, p);
/*
* The null signal is a permissions and process existence
* probe. No signal is actually delivered.
@@ -2305,7 +2301,7 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig)
* signal is private anyway.
*/
if (!error && sig && lock_task_sighand(p, &flags)) {
- error = specific_send_sig_info(sig, &info, p);
+ error = specific_send_sig_info(sig, info, p);
unlock_task_sighand(p, &flags);
}
}
@@ -2314,6 +2310,19 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig)
return error;
}
+static int do_tkill(pid_t tgid, pid_t pid, int sig)
+{
+ struct siginfo info;
+
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = SI_TKILL;
+ info.si_pid = task_tgid_vnr(current);
+ info.si_uid = current_uid();
+
+ return do_send_specific(tgid, pid, sig, &info);
+}
+
/**
* sys_tgkill - send signal to one specific thread
* @tgid: the thread group ID of the thread
@@ -2363,6 +2372,32 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig,
return kill_proc_info(sig, &info, pid);
}
+long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
+{
+ /* This is only valid for single tasks */
+ if (pid <= 0 || tgid <= 0)
+ return -EINVAL;
+
+ /* Not even root can pretend to send signals from the kernel.
+ Nor can they impersonate a kill(), which adds source info. */
+ if (info->si_code >= 0)
+ return -EPERM;
+ info->si_signo = sig;
+
+ return do_send_specific(tgid, pid, sig, info);
+}
+
+SYSCALL_DEFINE4(rt_tgsigqueueinfo, pid_t, tgid, pid_t, pid, int, sig,
+ siginfo_t __user *, uinfo)
+{
+ siginfo_t info;
+
+ if (copy_from_user(&info, uinfo, sizeof(siginfo_t)))
+ return -EFAULT;
+
+ return do_rt_tgsigqueueinfo(tgid, pid, sig, &info);
+}
+
int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
{
struct task_struct *t = current;
diff --git a/kernel/softirq.c b/kernel/softirq.c
index b525dd348511..258885a543db 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -24,7 +24,9 @@
#include <linux/ftrace.h>
#include <linux/smp.h>
#include <linux/tick.h>
-#include <trace/irq.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/irq.h>
#include <asm/irq.h>
/*
@@ -186,9 +188,6 @@ EXPORT_SYMBOL(local_bh_enable_ip);
*/
#define MAX_SOFTIRQ_RESTART 10
-DEFINE_TRACE(softirq_entry);
-DEFINE_TRACE(softirq_exit);
-
asmlinkage void __do_softirq(void)
{
struct softirq_action *h;
@@ -828,7 +827,7 @@ int __init __weak arch_early_irq_init(void)
return 0;
}
-int __weak arch_init_chip_data(struct irq_desc *desc, int cpu)
+int __weak arch_init_chip_data(struct irq_desc *desc, int node)
{
return 0;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index ea78fa101ad6..98ecf35d5bf2 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -115,6 +115,7 @@ static int ngroups_max = NGROUPS_MAX;
#ifdef CONFIG_MODULES
extern char modprobe_path[];
+extern int modules_disabled;
#endif
#ifdef CONFIG_CHR_DEV_SG
extern int sg_big_buff;
@@ -535,6 +536,17 @@ static struct ctl_table kern_table[] = {
.proc_handler = &proc_dostring,
.strategy = &sysctl_string,
},
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "modules_disabled",
+ .data = &modules_disabled,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ /* only handle a transition from default "0" to "1" */
+ .proc_handler = &proc_dointvec_minmax,
+ .extra1 = &one,
+ .extra2 = &one,
+ },
#endif
#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
{
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index d13be216a790..3948fa644a2d 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -54,6 +54,7 @@ unsigned long clockevent_delta2ns(unsigned long latch,
return (unsigned long) clc;
}
+EXPORT_SYMBOL_GPL(clockevent_delta2ns);
/**
* clockevents_set_mode - set the operating mode of a clock event device
@@ -187,6 +188,7 @@ void clockevents_register_device(struct clock_event_device *dev)
spin_unlock(&clockevents_lock);
}
+EXPORT_SYMBOL_GPL(clockevents_register_device);
/*
* Noop handler when we shut down an event device
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index ecfd7b5187e0..80189f6f1c5a 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -402,9 +402,6 @@ int clocksource_register(struct clocksource *c)
unsigned long flags;
int ret;
- /* save mult_orig on registration */
- c->mult_orig = c->mult;
-
spin_lock_irqsave(&clocksource_lock, flags);
ret = clocksource_enqueue(c);
if (!ret)
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 118a3b3b3f9a..877dbedc3118 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -27,7 +27,7 @@
* timer stops in C3 state.
*/
-struct tick_device tick_broadcast_device;
+static struct tick_device tick_broadcast_device;
/* FIXME: Use cpumask_var_t. */
static DECLARE_BITMAP(tick_broadcast_mask, NR_CPUS);
static DECLARE_BITMAP(tmpmask, NR_CPUS);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 687dff49f6e7..e97c50f8458b 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -77,6 +77,10 @@ static void clocksource_forward_now(void)
clock->cycle_last = cycle_now;
nsec = cyc2ns(clock, cycle_delta);
+
+ /* If arch requires, add in gettimeoffset() */
+ nsec += arch_gettimeoffset();
+
timespec_add_ns(&xtime, nsec);
nsec = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
@@ -111,6 +115,9 @@ void getnstimeofday(struct timespec *ts)
/* convert to nanoseconds: */
nsecs = cyc2ns(clock, cycle_delta);
+ /* If arch requires, add in gettimeoffset() */
+ nsecs += arch_gettimeoffset();
+
} while (read_seqretry(&xtime_lock, seq));
timespec_add_ns(ts, nsecs);
diff --git a/kernel/timer.c b/kernel/timer.c
index cffffad01c31..5c1e84beaf4a 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1015,6 +1015,9 @@ cascade:
index = slot = timer_jiffies & TVN_MASK;
do {
list_for_each_entry(nte, varp->vec + slot, entry) {
+ if (tbase_get_deferrable(nte->base))
+ continue;
+
found = 1;
if (time_before(nte->expires, expires))
expires = nte->expires;
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 417d1985e299..f61be3015783 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -48,6 +48,9 @@ config FTRACE_NMI_ENTER
depends on HAVE_FTRACE_NMI_ENTER
default y
+config EVENT_TRACING
+ bool
+
config TRACING
bool
select DEBUG_FS
@@ -56,6 +59,7 @@ config TRACING
select TRACEPOINTS
select NOP_TRACER
select BINARY_PRINTF
+ select EVENT_TRACING
#
# Minimum requirements an architecture has to meet for us to
@@ -73,7 +77,13 @@ config TRACING_SUPPORT
if TRACING_SUPPORT
-menu "Tracers"
+menuconfig FTRACE
+ bool "Tracers"
+ default y if DEBUG_KERNEL
+ help
+ Enable the kernel tracing infrastructure.
+
+if FTRACE
config FUNCTION_TRACER
bool "Kernel Function Tracer"
@@ -104,6 +114,7 @@ config FUNCTION_GRAPH_TRACER
the return value. This is done by setting the current return
address on the current task structure into a stack of calls.
+
config IRQSOFF_TRACER
bool "Interrupts-off Latency Tracer"
default n
@@ -173,7 +184,7 @@ config CONTEXT_SWITCH_TRACER
This tracer gets called from the context switch and records
all switching of tasks.
-config EVENT_TRACER
+config ENABLE_EVENT_TRACING
bool "Trace various events in the kernel"
select TRACING
help
@@ -181,6 +192,10 @@ config EVENT_TRACER
allowing the user to pick and choose which trace point they
want to trace.
+ Note, all tracers enable event tracing. This option is
+ only a convenience to enable event tracing when no other
+ tracers are selected.
+
config FTRACE_SYSCALLS
bool "Trace syscalls"
depends on HAVE_FTRACE_SYSCALLS
@@ -207,8 +222,36 @@ config BOOT_TRACER
to enable this on bootup.
config TRACE_BRANCH_PROFILING
- bool "Trace likely/unlikely profiler"
+ bool
select TRACING
+
+choice
+ prompt "Branch Profiling"
+ default BRANCH_PROFILE_NONE
+ help
+ The branch profiling is a software profiler. It will add hooks
+ into the C conditionals to test which path a branch takes.
+
+ The likely/unlikely profiler only looks at the conditions that
+ are annotated with a likely or unlikely macro.
+
+ The "all branch" profiler will profile every if statement in the
+ kernel. This profiler will also enable the likely/unlikely
+ profiler as well.
+
+ Either of the above profilers add a bit of overhead to the system.
+ If unsure choose "No branch profiling".
+
+config BRANCH_PROFILE_NONE
+ bool "No branch profiling"
+ help
+ No branch profiling. Branch profiling adds a bit of overhead.
+ Only enable it if you want to analyse the branching behavior.
+ Otherwise keep it disabled.
+
+config PROFILE_ANNOTATED_BRANCHES
+ bool "Trace likely/unlikely profiler"
+ select TRACE_BRANCH_PROFILING
help
This tracer profiles all the the likely and unlikely macros
in the kernel. It will display the results in:
@@ -218,11 +261,9 @@ config TRACE_BRANCH_PROFILING
Note: this will add a significant overhead, only turn this
on if you need to profile the system's use of these macros.
- Say N if unsure.
-
config PROFILE_ALL_BRANCHES
bool "Profile all if conditionals"
- depends on TRACE_BRANCH_PROFILING
+ select TRACE_BRANCH_PROFILING
help
This tracer profiles all branch conditions. Every if ()
taken in the kernel is recorded whether it hit or miss.
@@ -230,11 +271,12 @@ config PROFILE_ALL_BRANCHES
/debugfs/tracing/profile_branch
+ This option also enables the likely/unlikely profiler.
+
This configuration, when enabled, will impose a great overhead
on the system. This should only be enabled when the system
is to be analyzed
-
- Say N if unsure.
+endchoice
config TRACING_BRANCHES
bool
@@ -375,6 +417,20 @@ config DYNAMIC_FTRACE
were made. If so, it runs stop_machine (stops all CPUS)
and modifies the code to jump over the call to ftrace.
+config FUNCTION_PROFILER
+ bool "Kernel function profiler"
+ depends on FUNCTION_TRACER
+ default n
+ help
+ This option enables the kernel function profiler. A file is created
+ in debugfs called function_profile_enabled which defaults to zero.
+ When a 1 is echoed into this file profiling begins, and when a
+ zero is entered, profiling stops. A file in the trace_stats
+ directory called functions, that show the list of functions that
+ have been hit and their counters.
+
+ If in doubt, say N
+
config FTRACE_MCOUNT_RECORD
def_bool y
depends on DYNAMIC_FTRACE
@@ -416,7 +472,23 @@ config MMIOTRACE_TEST
Say N, unless you absolutely know what you are doing.
-endmenu
+config RING_BUFFER_BENCHMARK
+ tristate "Ring buffer benchmark stress tester"
+ depends on RING_BUFFER
+ help
+ This option creates a test to stress the ring buffer and bench mark it.
+ It creates its own ring buffer such that it will not interfer with
+ any other users of the ring buffer (such as ftrace). It then creates
+ a producer and consumer that will run for 10 seconds and sleep for
+ 10 seconds. Each interval it will print out the number of events
+ it recorded and give a rough estimate of how long each iteration took.
+
+ It does not disable interrupts or raise its priority, so it may be
+ affected by processes that are running.
+
+ If unsure, say N
+
+endif # FTRACE
endif # TRACING_SUPPORT
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 2630f5121ec1..848e5ced3c8a 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -15,11 +15,17 @@ ifdef CONFIG_TRACING_BRANCHES
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
endif
+#
+# Make the trace clocks available generally: it's infrastructure
+# relied on by ptrace for example:
+#
+obj-y += trace_clock.o
+
obj-$(CONFIG_FUNCTION_TRACER) += libftrace.o
obj-$(CONFIG_RING_BUFFER) += ring_buffer.o
+obj-$(CONFIG_RING_BUFFER_BENCHMARK) += ring_buffer_benchmark.o
obj-$(CONFIG_TRACING) += trace.o
-obj-$(CONFIG_TRACING) += trace_clock.o
obj-$(CONFIG_TRACING) += trace_output.o
obj-$(CONFIG_TRACING) += trace_stat.o
obj-$(CONFIG_TRACING) += trace_printk.o
@@ -40,11 +46,11 @@ obj-$(CONFIG_POWER_TRACER) += trace_power.o
obj-$(CONFIG_KMEMTRACE) += kmemtrace.o
obj-$(CONFIG_WORKQUEUE_TRACER) += trace_workqueue.o
obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o
-obj-$(CONFIG_EVENT_TRACER) += trace_events.o
-obj-$(CONFIG_EVENT_TRACER) += events.o
-obj-$(CONFIG_EVENT_TRACER) += trace_export.o
+obj-$(CONFIG_EVENT_TRACING) += trace_events.o
+obj-$(CONFIG_EVENT_TRACING) += trace_export.o
obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o
-obj-$(CONFIG_EVENT_TRACER) += trace_events_filter.o
+obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
+obj-$(CONFIG_EVENT_TRACING) += trace_mm.o
libftrace-y := ftrace.o
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 921ef5d1f0ba..55e54accedbf 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -147,7 +147,7 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
{
if (((bt->act_mask << BLK_TC_SHIFT) & what) == 0)
return 1;
- if (sector < bt->start_lba || sector > bt->end_lba)
+ if (sector && (sector < bt->start_lba || sector > bt->end_lba))
return 1;
if (bt->pid && pid != bt->pid)
return 1;
@@ -192,7 +192,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
what |= MASK_TC_BIT(rw, DISCARD);
pid = tsk->pid;
- if (unlikely(act_log_check(bt, what, sector, pid)))
+ if (act_log_check(bt, what, sector, pid))
return;
cpu = raw_smp_processor_id();
@@ -403,11 +403,29 @@ static struct rchan_callbacks blk_relay_callbacks = {
.remove_buf_file = blk_remove_buf_file_callback,
};
+static void blk_trace_setup_lba(struct blk_trace *bt,
+ struct block_device *bdev)
+{
+ struct hd_struct *part = NULL;
+
+ if (bdev)
+ part = bdev->bd_part;
+
+ if (part) {
+ bt->start_lba = part->start_sect;
+ bt->end_lba = part->start_sect + part->nr_sects;
+ } else {
+ bt->start_lba = 0;
+ bt->end_lba = -1ULL;
+ }
+}
+
/*
* Setup everything required to start tracing
*/
int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
- struct blk_user_trace_setup *buts)
+ struct block_device *bdev,
+ struct blk_user_trace_setup *buts)
{
struct blk_trace *old_bt, *bt = NULL;
struct dentry *dir = NULL;
@@ -480,10 +498,13 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (!bt->act_mask)
bt->act_mask = (u16) -1;
- bt->start_lba = buts->start_lba;
- bt->end_lba = buts->end_lba;
- if (!bt->end_lba)
- bt->end_lba = -1ULL;
+ blk_trace_setup_lba(bt, bdev);
+
+ /* overwrite with user settings */
+ if (buts->start_lba)
+ bt->start_lba = buts->start_lba;
+ if (buts->end_lba)
+ bt->end_lba = buts->end_lba;
bt->pid = buts->pid;
bt->trace_state = Blktrace_setup;
@@ -505,6 +526,7 @@ err:
}
int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+ struct block_device *bdev,
char __user *arg)
{
struct blk_user_trace_setup buts;
@@ -514,7 +536,7 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (ret)
return -EFAULT;
- ret = do_blk_trace_setup(q, name, dev, &buts);
+ ret = do_blk_trace_setup(q, name, dev, bdev, &buts);
if (ret)
return ret;
@@ -582,7 +604,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
switch (cmd) {
case BLKTRACESETUP:
bdevname(bdev, b);
- ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
+ ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
break;
case BLKTRACESTART:
start = 1;
@@ -642,12 +664,12 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
if (blk_pc_request(rq)) {
what |= BLK_TC_ACT(BLK_TC_PC);
- __blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors,
- rq->cmd_len, rq->cmd);
+ __blk_add_trace(bt, 0, blk_rq_bytes(rq), rw,
+ what, rq->errors, rq->cmd_len, rq->cmd);
} else {
what |= BLK_TC_ACT(BLK_TC_FS);
- __blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
- rw, what, rq->errors, 0, NULL);
+ __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), rw,
+ what, rq->errors, 0, NULL);
}
}
@@ -809,7 +831,6 @@ static void blk_add_trace_split(struct request_queue *q, struct bio *bio,
* @bio: the source bio
* @dev: target device
* @from: source sector
- * @to: target sector
*
* Description:
* Device mapper or raid target sometimes need to split a bio because
@@ -817,7 +838,7 @@ static void blk_add_trace_split(struct request_queue *q, struct bio *bio,
*
**/
static void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
- dev_t dev, sector_t from, sector_t to)
+ dev_t dev, sector_t from)
{
struct blk_trace *bt = q->blk_trace;
struct blk_io_trace_remap r;
@@ -825,12 +846,13 @@ static void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
if (likely(!bt))
return;
- r.device = cpu_to_be32(dev);
- r.device_from = cpu_to_be32(bio->bi_bdev->bd_dev);
- r.sector = cpu_to_be64(to);
+ r.device_from = cpu_to_be32(dev);
+ r.device_to = cpu_to_be32(bio->bi_bdev->bd_dev);
+ r.sector_from = cpu_to_be64(from);
- __blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP,
- !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r);
+ __blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw,
+ BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE),
+ sizeof(r), &r);
}
/**
@@ -854,11 +876,11 @@ void blk_add_driver_data(struct request_queue *q,
return;
if (blk_pc_request(rq))
- __blk_add_trace(bt, 0, rq->data_len, 0, BLK_TA_DRV_DATA,
- rq->errors, len, data);
+ __blk_add_trace(bt, 0, blk_rq_bytes(rq), 0,
+ BLK_TA_DRV_DATA, rq->errors, len, data);
else
- __blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
- 0, BLK_TA_DRV_DATA, rq->errors, len, data);
+ __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), 0,
+ BLK_TA_DRV_DATA, rq->errors, len, data);
}
EXPORT_SYMBOL_GPL(blk_add_driver_data);
@@ -971,6 +993,16 @@ static inline const void *pdu_start(const struct trace_entry *ent)
return te_blk_io_trace(ent) + 1;
}
+static inline u32 t_action(const struct trace_entry *ent)
+{
+ return te_blk_io_trace(ent)->action;
+}
+
+static inline u32 t_bytes(const struct trace_entry *ent)
+{
+ return te_blk_io_trace(ent)->bytes;
+}
+
static inline u32 t_sec(const struct trace_entry *ent)
{
return te_blk_io_trace(ent)->bytes >> 9;
@@ -996,11 +1028,11 @@ static void get_pdu_remap(const struct trace_entry *ent,
struct blk_io_trace_remap *r)
{
const struct blk_io_trace_remap *__r = pdu_start(ent);
- __u64 sector = __r->sector;
+ __u64 sector_from = __r->sector_from;
- r->device = be32_to_cpu(__r->device);
r->device_from = be32_to_cpu(__r->device_from);
- r->sector = be64_to_cpu(sector);
+ r->device_to = be32_to_cpu(__r->device_to);
+ r->sector_from = be64_to_cpu(sector_from);
}
typedef int (blk_log_action_t) (struct trace_iterator *iter, const char *act);
@@ -1031,36 +1063,98 @@ static int blk_log_action(struct trace_iterator *iter, const char *act)
MAJOR(t->device), MINOR(t->device), act, rwbs);
}
+static int blk_log_dump_pdu(struct trace_seq *s, const struct trace_entry *ent)
+{
+ const unsigned char *pdu_buf;
+ int pdu_len;
+ int i, end, ret;
+
+ pdu_buf = pdu_start(ent);
+ pdu_len = te_blk_io_trace(ent)->pdu_len;
+
+ if (!pdu_len)
+ return 1;
+
+ /* find the last zero that needs to be printed */
+ for (end = pdu_len - 1; end >= 0; end--)
+ if (pdu_buf[end])
+ break;
+ end++;
+
+ if (!trace_seq_putc(s, '('))
+ return 0;
+
+ for (i = 0; i < pdu_len; i++) {
+
+ ret = trace_seq_printf(s, "%s%02x",
+ i == 0 ? "" : " ", pdu_buf[i]);
+ if (!ret)
+ return ret;
+
+ /*
+ * stop when the rest is just zeroes and indicate so
+ * with a ".." appended
+ */
+ if (i == end && end != pdu_len - 1)
+ return trace_seq_puts(s, " ..) ");
+ }
+
+ return trace_seq_puts(s, ") ");
+}
+
static int blk_log_generic(struct trace_seq *s, const struct trace_entry *ent)
{
char cmd[TASK_COMM_LEN];
trace_find_cmdline(ent->pid, cmd);
- if (t_sec(ent))
- return trace_seq_printf(s, "%llu + %u [%s]\n",
- t_sector(ent), t_sec(ent), cmd);
- return trace_seq_printf(s, "[%s]\n", cmd);
+ if (t_action(ent) & BLK_TC_ACT(BLK_TC_PC)) {
+ int ret;
+
+ ret = trace_seq_printf(s, "%u ", t_bytes(ent));
+ if (!ret)
+ return 0;
+ ret = blk_log_dump_pdu(s, ent);
+ if (!ret)
+ return 0;
+ return trace_seq_printf(s, "[%s]\n", cmd);
+ } else {
+ if (t_sec(ent))
+ return trace_seq_printf(s, "%llu + %u [%s]\n",
+ t_sector(ent), t_sec(ent), cmd);
+ return trace_seq_printf(s, "[%s]\n", cmd);
+ }
}
static int blk_log_with_error(struct trace_seq *s,
const struct trace_entry *ent)
{
- if (t_sec(ent))
- return trace_seq_printf(s, "%llu + %u [%d]\n", t_sector(ent),
- t_sec(ent), t_error(ent));
- return trace_seq_printf(s, "%llu [%d]\n", t_sector(ent), t_error(ent));
+ if (t_action(ent) & BLK_TC_ACT(BLK_TC_PC)) {
+ int ret;
+
+ ret = blk_log_dump_pdu(s, ent);
+ if (ret)
+ return trace_seq_printf(s, "[%d]\n", t_error(ent));
+ return 0;
+ } else {
+ if (t_sec(ent))
+ return trace_seq_printf(s, "%llu + %u [%d]\n",
+ t_sector(ent),
+ t_sec(ent), t_error(ent));
+ return trace_seq_printf(s, "%llu [%d]\n",
+ t_sector(ent), t_error(ent));
+ }
}
static int blk_log_remap(struct trace_seq *s, const struct trace_entry *ent)
{
- struct blk_io_trace_remap r = { .device = 0, };
+ struct blk_io_trace_remap r = { .device_from = 0, };
get_pdu_remap(ent, &r);
return trace_seq_printf(s, "%llu + %u <- (%d,%d) %llu\n",
- t_sector(ent),
- t_sec(ent), MAJOR(r.device), MINOR(r.device),
- (unsigned long long)r.sector);
+ t_sector(ent), t_sec(ent),
+ MAJOR(r.device_from), MINOR(r.device_from),
+ (unsigned long long)r.sector_from);
}
static int blk_log_plug(struct trace_seq *s, const struct trace_entry *ent)
@@ -1117,7 +1211,6 @@ static void blk_tracer_print_header(struct seq_file *m)
static void blk_tracer_start(struct trace_array *tr)
{
blk_tracer_enabled = true;
- trace_flags &= ~TRACE_ITER_CONTEXT_INFO;
}
static int blk_tracer_init(struct trace_array *tr)
@@ -1130,7 +1223,6 @@ static int blk_tracer_init(struct trace_array *tr)
static void blk_tracer_stop(struct trace_array *tr)
{
blk_tracer_enabled = false;
- trace_flags |= TRACE_ITER_CONTEXT_INFO;
}
static void blk_tracer_reset(struct trace_array *tr)
@@ -1182,7 +1274,7 @@ static enum print_line_t print_one_line(struct trace_iterator *iter,
}
if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act)))
- ret = trace_seq_printf(s, "Bad pc action %x\n", what);
+ ret = trace_seq_printf(s, "Unknown action %x\n", what);
else {
ret = log_action(iter, what2act[what].act[long_act]);
if (ret)
@@ -1195,9 +1287,6 @@ out:
static enum print_line_t blk_trace_event_print(struct trace_iterator *iter,
int flags)
{
- if (!trace_print_context(iter))
- return TRACE_TYPE_PARTIAL_LINE;
-
return print_one_line(iter, false);
}
@@ -1232,6 +1321,18 @@ static enum print_line_t blk_tracer_print_line(struct trace_iterator *iter)
return print_one_line(iter, true);
}
+static int blk_tracer_set_flag(u32 old_flags, u32 bit, int set)
+{
+ /* don't output context-info for blk_classic output */
+ if (bit == TRACE_BLK_OPT_CLASSIC) {
+ if (set)
+ trace_flags &= ~TRACE_ITER_CONTEXT_INFO;
+ else
+ trace_flags |= TRACE_ITER_CONTEXT_INFO;
+ }
+ return 0;
+}
+
static struct tracer blk_tracer __read_mostly = {
.name = "blk",
.init = blk_tracer_init,
@@ -1241,6 +1342,7 @@ static struct tracer blk_tracer __read_mostly = {
.print_header = blk_tracer_print_header,
.print_line = blk_tracer_print_line,
.flags = &blk_tracer_flags,
+ .set_flag = blk_tracer_set_flag,
};
static struct trace_event trace_blk_event = {
@@ -1285,7 +1387,8 @@ static int blk_trace_remove_queue(struct request_queue *q)
/*
* Setup everything required to start tracing
*/
-static int blk_trace_setup_queue(struct request_queue *q, dev_t dev)
+static int blk_trace_setup_queue(struct request_queue *q,
+ struct block_device *bdev)
{
struct blk_trace *old_bt, *bt = NULL;
int ret = -ENOMEM;
@@ -1298,9 +1401,10 @@ static int blk_trace_setup_queue(struct request_queue *q, dev_t dev)
if (!bt->msg_data)
goto free_bt;
- bt->dev = dev;
+ bt->dev = bdev->bd_dev;
bt->act_mask = (u16)-1;
- bt->end_lba = -1ULL;
+
+ blk_trace_setup_lba(bt, bdev);
old_bt = xchg(&q->blk_trace, bt);
if (old_bt != NULL) {
@@ -1517,7 +1621,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
if (attr == &dev_attr_enable) {
if (value)
- ret = blk_trace_setup_queue(q, bdev->bd_dev);
+ ret = blk_trace_setup_queue(q, bdev);
else
ret = blk_trace_remove_queue(q);
goto out_unlock_bdev;
@@ -1525,7 +1629,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
ret = 0;
if (q->blk_trace == NULL)
- ret = blk_trace_setup_queue(q, bdev->bd_dev);
+ ret = blk_trace_setup_queue(q, bdev);
if (ret == 0) {
if (attr == &dev_attr_act_mask)
@@ -1548,3 +1652,8 @@ out:
return ret ? ret : count;
}
+int blk_trace_init_sysfs(struct device *dev)
+{
+ return sysfs_create_group(&dev->kobj, &blk_trace_attr_group);
+}
+
diff --git a/kernel/trace/events.c b/kernel/trace/events.c
deleted file mode 100644
index 246f2aa6dc46..000000000000
--- a/kernel/trace/events.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * This is the place to register all trace points as events.
- */
-
-#include <linux/stringify.h>
-
-#include <trace/trace_events.h>
-
-#include "trace_output.h"
-
-#include "trace_events_stage_1.h"
-#include "trace_events_stage_2.h"
-#include "trace_events_stage_3.h"
-
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index f1ed080406c3..5b606f45b6c4 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -29,11 +29,12 @@
#include <linux/list.h>
#include <linux/hash.h>
-#include <trace/sched.h>
+#include <trace/events/sched.h>
#include <asm/ftrace.h>
-#include "trace.h"
+#include "trace_output.h"
+#include "trace_stat.h"
#define FTRACE_WARN_ON(cond) \
do { \
@@ -68,7 +69,7 @@ static DEFINE_MUTEX(ftrace_lock);
static struct ftrace_ops ftrace_list_end __read_mostly =
{
- .func = ftrace_stub,
+ .func = ftrace_stub,
};
static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end;
@@ -240,6 +241,576 @@ static void ftrace_update_pid_func(void)
#endif
}
+#ifdef CONFIG_FUNCTION_PROFILER
+struct ftrace_profile {
+ struct hlist_node node;
+ unsigned long ip;
+ unsigned long counter;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ unsigned long long time;
+#endif
+};
+
+struct ftrace_profile_page {
+ struct ftrace_profile_page *next;
+ unsigned long index;
+ struct ftrace_profile records[];
+};
+
+struct ftrace_profile_stat {
+ atomic_t disabled;
+ struct hlist_head *hash;
+ struct ftrace_profile_page *pages;
+ struct ftrace_profile_page *start;
+ struct tracer_stat stat;
+};
+
+#define PROFILE_RECORDS_SIZE \
+ (PAGE_SIZE - offsetof(struct ftrace_profile_page, records))
+
+#define PROFILES_PER_PAGE \
+ (PROFILE_RECORDS_SIZE / sizeof(struct ftrace_profile))
+
+static int ftrace_profile_bits __read_mostly;
+static int ftrace_profile_enabled __read_mostly;
+
+/* ftrace_profile_lock - synchronize the enable and disable of the profiler */
+static DEFINE_MUTEX(ftrace_profile_lock);
+
+static DEFINE_PER_CPU(struct ftrace_profile_stat, ftrace_profile_stats);
+
+#define FTRACE_PROFILE_HASH_SIZE 1024 /* must be power of 2 */
+
+static void *
+function_stat_next(void *v, int idx)
+{
+ struct ftrace_profile *rec = v;
+ struct ftrace_profile_page *pg;
+
+ pg = (struct ftrace_profile_page *)((unsigned long)rec & PAGE_MASK);
+
+ again:
+ rec++;
+ if ((void *)rec >= (void *)&pg->records[pg->index]) {
+ pg = pg->next;
+ if (!pg)
+ return NULL;
+ rec = &pg->records[0];
+ if (!rec->counter)
+ goto again;
+ }
+
+ return rec;
+}
+
+static void *function_stat_start(struct tracer_stat *trace)
+{
+ struct ftrace_profile_stat *stat =
+ container_of(trace, struct ftrace_profile_stat, stat);
+
+ if (!stat || !stat->start)
+ return NULL;
+
+ return function_stat_next(&stat->start->records[0], 0);
+}
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+/* function graph compares on total time */
+static int function_stat_cmp(void *p1, void *p2)
+{
+ struct ftrace_profile *a = p1;
+ struct ftrace_profile *b = p2;
+
+ if (a->time < b->time)
+ return -1;
+ if (a->time > b->time)
+ return 1;
+ else
+ return 0;
+}
+#else
+/* not function graph compares against hits */
+static int function_stat_cmp(void *p1, void *p2)
+{
+ struct ftrace_profile *a = p1;
+ struct ftrace_profile *b = p2;
+
+ if (a->counter < b->counter)
+ return -1;
+ if (a->counter > b->counter)
+ return 1;
+ else
+ return 0;
+}
+#endif
+
+static int function_stat_headers(struct seq_file *m)
+{
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ seq_printf(m, " Function "
+ "Hit Time Avg\n"
+ " -------- "
+ "--- ---- ---\n");
+#else
+ seq_printf(m, " Function Hit\n"
+ " -------- ---\n");
+#endif
+ return 0;
+}
+
+static int function_stat_show(struct seq_file *m, void *v)
+{
+ struct ftrace_profile *rec = v;
+ char str[KSYM_SYMBOL_LEN];
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ static DEFINE_MUTEX(mutex);
+ static struct trace_seq s;
+ unsigned long long avg;
+#endif
+
+ kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
+ seq_printf(m, " %-30.30s %10lu", str, rec->counter);
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ seq_printf(m, " ");
+ avg = rec->time;
+ do_div(avg, rec->counter);
+
+ mutex_lock(&mutex);
+ trace_seq_init(&s);
+ trace_print_graph_duration(rec->time, &s);
+ trace_seq_puts(&s, " ");
+ trace_print_graph_duration(avg, &s);
+ trace_print_seq(m, &s);
+ mutex_unlock(&mutex);
+#endif
+ seq_putc(m, '\n');
+
+ return 0;
+}
+
+static void ftrace_profile_reset(struct ftrace_profile_stat *stat)
+{
+ struct ftrace_profile_page *pg;
+
+ pg = stat->pages = stat->start;
+
+ while (pg) {
+ memset(pg->records, 0, PROFILE_RECORDS_SIZE);
+ pg->index = 0;
+ pg = pg->next;
+ }
+
+ memset(stat->hash, 0,
+ FTRACE_PROFILE_HASH_SIZE * sizeof(struct hlist_head));
+}
+
+int ftrace_profile_pages_init(struct ftrace_profile_stat *stat)
+{
+ struct ftrace_profile_page *pg;
+ int functions;
+ int pages;
+ int i;
+
+ /* If we already allocated, do nothing */
+ if (stat->pages)
+ return 0;
+
+ stat->pages = (void *)get_zeroed_page(GFP_KERNEL);
+ if (!stat->pages)
+ return -ENOMEM;
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+ functions = ftrace_update_tot_cnt;
+#else
+ /*
+ * We do not know the number of functions that exist because
+ * dynamic tracing is what counts them. With past experience
+ * we have around 20K functions. That should be more than enough.
+ * It is highly unlikely we will execute every function in
+ * the kernel.
+ */
+ functions = 20000;
+#endif
+
+ pg = stat->start = stat->pages;
+
+ pages = DIV_ROUND_UP(functions, PROFILES_PER_PAGE);
+
+ for (i = 0; i < pages; i++) {
+ pg->next = (void *)get_zeroed_page(GFP_KERNEL);
+ if (!pg->next)
+ goto out_free;
+ pg = pg->next;
+ }
+
+ return 0;
+
+ out_free:
+ pg = stat->start;
+ while (pg) {
+ unsigned long tmp = (unsigned long)pg;
+
+ pg = pg->next;
+ free_page(tmp);
+ }
+
+ free_page((unsigned long)stat->pages);
+ stat->pages = NULL;
+ stat->start = NULL;
+
+ return -ENOMEM;
+}
+
+static int ftrace_profile_init_cpu(int cpu)
+{
+ struct ftrace_profile_stat *stat;
+ int size;
+
+ stat = &per_cpu(ftrace_profile_stats, cpu);
+
+ if (stat->hash) {
+ /* If the profile is already created, simply reset it */
+ ftrace_profile_reset(stat);
+ return 0;
+ }
+
+ /*
+ * We are profiling all functions, but usually only a few thousand
+ * functions are hit. We'll make a hash of 1024 items.
+ */
+ size = FTRACE_PROFILE_HASH_SIZE;
+
+ stat->hash = kzalloc(sizeof(struct hlist_head) * size, GFP_KERNEL);
+
+ if (!stat->hash)
+ return -ENOMEM;
+
+ if (!ftrace_profile_bits) {
+ size--;
+
+ for (; size; size >>= 1)
+ ftrace_profile_bits++;
+ }
+
+ /* Preallocate the function profiling pages */
+ if (ftrace_profile_pages_init(stat) < 0) {
+ kfree(stat->hash);
+ stat->hash = NULL;
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int ftrace_profile_init(void)
+{
+ int cpu;
+ int ret = 0;
+
+ for_each_online_cpu(cpu) {
+ ret = ftrace_profile_init_cpu(cpu);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/* interrupts must be disabled */
+static struct ftrace_profile *
+ftrace_find_profiled_func(struct ftrace_profile_stat *stat, unsigned long ip)
+{
+ struct ftrace_profile *rec;
+ struct hlist_head *hhd;
+ struct hlist_node *n;
+ unsigned long key;
+
+ key = hash_long(ip, ftrace_profile_bits);
+ hhd = &stat->hash[key];
+
+ if (hlist_empty(hhd))
+ return NULL;
+
+ hlist_for_each_entry_rcu(rec, n, hhd, node) {
+ if (rec->ip == ip)
+ return rec;
+ }
+
+ return NULL;
+}
+
+static void ftrace_add_profile(struct ftrace_profile_stat *stat,
+ struct ftrace_profile *rec)
+{
+ unsigned long key;
+
+ key = hash_long(rec->ip, ftrace_profile_bits);
+ hlist_add_head_rcu(&rec->node, &stat->hash[key]);
+}
+
+/*
+ * The memory is already allocated, this simply finds a new record to use.
+ */
+static struct ftrace_profile *
+ftrace_profile_alloc(struct ftrace_profile_stat *stat, unsigned long ip)
+{
+ struct ftrace_profile *rec = NULL;
+
+ /* prevent recursion (from NMIs) */
+ if (atomic_inc_return(&stat->disabled) != 1)
+ goto out;
+
+ /*
+ * Try to find the function again since an NMI
+ * could have added it
+ */
+ rec = ftrace_find_profiled_func(stat, ip);
+ if (rec)
+ goto out;
+
+ if (stat->pages->index == PROFILES_PER_PAGE) {
+ if (!stat->pages->next)
+ goto out;
+ stat->pages = stat->pages->next;
+ }
+
+ rec = &stat->pages->records[stat->pages->index++];
+ rec->ip = ip;
+ ftrace_add_profile(stat, rec);
+
+ out:
+ atomic_dec(&stat->disabled);
+
+ return rec;
+}
+
+static void
+function_profile_call(unsigned long ip, unsigned long parent_ip)
+{
+ struct ftrace_profile_stat *stat;
+ struct ftrace_profile *rec;
+ unsigned long flags;
+
+ if (!ftrace_profile_enabled)
+ return;
+
+ local_irq_save(flags);
+
+ stat = &__get_cpu_var(ftrace_profile_stats);
+ if (!stat->hash)
+ goto out;
+
+ rec = ftrace_find_profiled_func(stat, ip);
+ if (!rec) {
+ rec = ftrace_profile_alloc(stat, ip);
+ if (!rec)
+ goto out;
+ }
+
+ rec->counter++;
+ out:
+ local_irq_restore(flags);
+}
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static int profile_graph_entry(struct ftrace_graph_ent *trace)
+{
+ function_profile_call(trace->func, 0);
+ return 1;
+}
+
+static void profile_graph_return(struct ftrace_graph_ret *trace)
+{
+ struct ftrace_profile_stat *stat;
+ unsigned long long calltime;
+ struct ftrace_profile *rec;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ stat = &__get_cpu_var(ftrace_profile_stats);
+ if (!stat->hash)
+ goto out;
+
+ calltime = trace->rettime - trace->calltime;
+
+ if (!(trace_flags & TRACE_ITER_GRAPH_TIME)) {
+ int index;
+
+ index = trace->depth;
+
+ /* Append this call time to the parent time to subtract */
+ if (index)
+ current->ret_stack[index - 1].subtime += calltime;
+
+ if (current->ret_stack[index].subtime < calltime)
+ calltime -= current->ret_stack[index].subtime;
+ else
+ calltime = 0;
+ }
+
+ rec = ftrace_find_profiled_func(stat, trace->func);
+ if (rec)
+ rec->time += calltime;
+
+ out:
+ local_irq_restore(flags);
+}
+
+static int register_ftrace_profiler(void)
+{
+ return register_ftrace_graph(&profile_graph_return,
+ &profile_graph_entry);
+}
+
+static void unregister_ftrace_profiler(void)
+{
+ unregister_ftrace_graph();
+}
+#else
+static struct ftrace_ops ftrace_profile_ops __read_mostly =
+{
+ .func = function_profile_call,
+};
+
+static int register_ftrace_profiler(void)
+{
+ return register_ftrace_function(&ftrace_profile_ops);
+}
+
+static void unregister_ftrace_profiler(void)
+{
+ unregister_ftrace_function(&ftrace_profile_ops);
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+static ssize_t
+ftrace_profile_write(struct file *filp, const char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ unsigned long val;
+ char buf[64]; /* big enough to hold a number */
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+
+ buf[cnt] = 0;
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ val = !!val;
+
+ mutex_lock(&ftrace_profile_lock);
+ if (ftrace_profile_enabled ^ val) {
+ if (val) {
+ ret = ftrace_profile_init();
+ if (ret < 0) {
+ cnt = ret;
+ goto out;
+ }
+
+ ret = register_ftrace_profiler();
+ if (ret < 0) {
+ cnt = ret;
+ goto out;
+ }
+ ftrace_profile_enabled = 1;
+ } else {
+ ftrace_profile_enabled = 0;
+ unregister_ftrace_profiler();
+ }
+ }
+ out:
+ mutex_unlock(&ftrace_profile_lock);
+
+ filp->f_pos += cnt;
+
+ return cnt;
+}
+
+static ssize_t
+ftrace_profile_read(struct file *filp, char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ char buf[64]; /* big enough to hold a number */
+ int r;
+
+ r = sprintf(buf, "%u\n", ftrace_profile_enabled);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static const struct file_operations ftrace_profile_fops = {
+ .open = tracing_open_generic,
+ .read = ftrace_profile_read,
+ .write = ftrace_profile_write,
+};
+
+/* used to initialize the real stat files */
+static struct tracer_stat function_stats __initdata = {
+ .name = "functions",
+ .stat_start = function_stat_start,
+ .stat_next = function_stat_next,
+ .stat_cmp = function_stat_cmp,
+ .stat_headers = function_stat_headers,
+ .stat_show = function_stat_show
+};
+
+static void ftrace_profile_debugfs(struct dentry *d_tracer)
+{
+ struct ftrace_profile_stat *stat;
+ struct dentry *entry;
+ char *name;
+ int ret;
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ stat = &per_cpu(ftrace_profile_stats, cpu);
+
+ /* allocate enough for function name + cpu number */
+ name = kmalloc(32, GFP_KERNEL);
+ if (!name) {
+ /*
+ * The files created are permanent, if something happens
+ * we still do not free memory.
+ */
+ kfree(stat);
+ WARN(1,
+ "Could not allocate stat file for cpu %d\n",
+ cpu);
+ return;
+ }
+ stat->stat = function_stats;
+ snprintf(name, 32, "function%d", cpu);
+ stat->stat.name = name;
+ ret = register_stat_tracer(&stat->stat);
+ if (ret) {
+ WARN(1,
+ "Could not register function stat for cpu %d\n",
+ cpu);
+ kfree(name);
+ return;
+ }
+ }
+
+ entry = debugfs_create_file("function_profile_enabled", 0644,
+ d_tracer, NULL, &ftrace_profile_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'function_profile_enabled' entry\n");
+}
+
+#else /* CONFIG_FUNCTION_PROFILER */
+static void ftrace_profile_debugfs(struct dentry *d_tracer)
+{
+}
+#endif /* CONFIG_FUNCTION_PROFILER */
+
/* set when tracing only a pid */
struct pid *ftrace_pid_trace;
static struct pid * const ftrace_swapper_pid = &init_struct_pid;
@@ -261,7 +832,6 @@ struct ftrace_func_probe {
struct rcu_head rcu;
};
-
enum {
FTRACE_ENABLE_CALLS = (1 << 0),
FTRACE_DISABLE_CALLS = (1 << 1),
@@ -346,30 +916,6 @@ static void ftrace_free_rec(struct dyn_ftrace *rec)
rec->flags |= FTRACE_FL_FREE;
}
-void ftrace_release(void *start, unsigned long size)
-{
- struct dyn_ftrace *rec;
- struct ftrace_page *pg;
- unsigned long s = (unsigned long)start;
- unsigned long e = s + size;
-
- if (ftrace_disabled || !start)
- return;
-
- mutex_lock(&ftrace_lock);
- do_for_each_ftrace_rec(pg, rec) {
- if ((rec->ip >= s) && (rec->ip < e)) {
- /*
- * rec->ip is changed in ftrace_free_rec()
- * It should not between s and e if record was freed.
- */
- FTRACE_WARN_ON(rec->flags & FTRACE_FL_FREE);
- ftrace_free_rec(rec);
- }
- } while_for_each_ftrace_rec();
- mutex_unlock(&ftrace_lock);
-}
-
static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
{
struct dyn_ftrace *rec;
@@ -1408,7 +1954,7 @@ function_trace_probe_call(unsigned long ip, unsigned long parent_ip)
static struct ftrace_ops trace_probe_ops __read_mostly =
{
- .func = function_trace_probe_call,
+ .func = function_trace_probe_call,
};
static int ftrace_probe_registered;
@@ -2128,38 +2674,23 @@ static const struct file_operations ftrace_graph_fops = {
static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
{
- struct dentry *entry;
- entry = debugfs_create_file("available_filter_functions", 0444,
- d_tracer, NULL, &ftrace_avail_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'available_filter_functions' entry\n");
+ trace_create_file("available_filter_functions", 0444,
+ d_tracer, NULL, &ftrace_avail_fops);
- entry = debugfs_create_file("failures", 0444,
- d_tracer, NULL, &ftrace_failures_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'failures' entry\n");
+ trace_create_file("failures", 0444,
+ d_tracer, NULL, &ftrace_failures_fops);
- entry = debugfs_create_file("set_ftrace_filter", 0644, d_tracer,
- NULL, &ftrace_filter_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'set_ftrace_filter' entry\n");
+ trace_create_file("set_ftrace_filter", 0644, d_tracer,
+ NULL, &ftrace_filter_fops);
- entry = debugfs_create_file("set_ftrace_notrace", 0644, d_tracer,
+ trace_create_file("set_ftrace_notrace", 0644, d_tracer,
NULL, &ftrace_notrace_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'set_ftrace_notrace' entry\n");
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- entry = debugfs_create_file("set_graph_function", 0444, d_tracer,
+ trace_create_file("set_graph_function", 0444, d_tracer,
NULL,
&ftrace_graph_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'set_graph_function' entry\n");
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
return 0;
@@ -2197,14 +2728,72 @@ static int ftrace_convert_nops(struct module *mod,
return 0;
}
-void ftrace_init_module(struct module *mod,
- unsigned long *start, unsigned long *end)
+#ifdef CONFIG_MODULES
+void ftrace_release(void *start, void *end)
+{
+ struct dyn_ftrace *rec;
+ struct ftrace_page *pg;
+ unsigned long s = (unsigned long)start;
+ unsigned long e = (unsigned long)end;
+
+ if (ftrace_disabled || !start || start == end)
+ return;
+
+ mutex_lock(&ftrace_lock);
+ do_for_each_ftrace_rec(pg, rec) {
+ if ((rec->ip >= s) && (rec->ip < e)) {
+ /*
+ * rec->ip is changed in ftrace_free_rec()
+ * It should not between s and e if record was freed.
+ */
+ FTRACE_WARN_ON(rec->flags & FTRACE_FL_FREE);
+ ftrace_free_rec(rec);
+ }
+ } while_for_each_ftrace_rec();
+ mutex_unlock(&ftrace_lock);
+}
+
+static void ftrace_init_module(struct module *mod,
+ unsigned long *start, unsigned long *end)
{
if (ftrace_disabled || start == end)
return;
ftrace_convert_nops(mod, start, end);
}
+static int ftrace_module_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ struct module *mod = data;
+
+ switch (val) {
+ case MODULE_STATE_COMING:
+ ftrace_init_module(mod, mod->ftrace_callsites,
+ mod->ftrace_callsites +
+ mod->num_ftrace_callsites);
+ break;
+ case MODULE_STATE_GOING:
+ ftrace_release(mod->ftrace_callsites,
+ mod->ftrace_callsites +
+ mod->num_ftrace_callsites);
+ break;
+ }
+
+ return 0;
+}
+#else
+static int ftrace_module_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ return 0;
+}
+#endif /* CONFIG_MODULES */
+
+struct notifier_block ftrace_module_nb = {
+ .notifier_call = ftrace_module_notify,
+ .priority = 0,
+};
+
extern unsigned long __start_mcount_loc[];
extern unsigned long __stop_mcount_loc[];
@@ -2236,6 +2825,10 @@ void __init ftrace_init(void)
__start_mcount_loc,
__stop_mcount_loc);
+ ret = register_module_notifier(&ftrace_module_nb);
+ if (!ret)
+ pr_warning("Failed to register trace ftrace module notifier\n");
+
return;
failed:
ftrace_disabled = 1;
@@ -2417,7 +3010,6 @@ static const struct file_operations ftrace_pid_fops = {
static __init int ftrace_init_debugfs(void)
{
struct dentry *d_tracer;
- struct dentry *entry;
d_tracer = tracing_init_dentry();
if (!d_tracer)
@@ -2425,11 +3017,11 @@ static __init int ftrace_init_debugfs(void)
ftrace_init_dyn_debugfs(d_tracer);
- entry = debugfs_create_file("set_ftrace_pid", 0644, d_tracer,
- NULL, &ftrace_pid_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'set_ftrace_pid' entry\n");
+ trace_create_file("set_ftrace_pid", 0644, d_tracer,
+ NULL, &ftrace_pid_fops);
+
+ ftrace_profile_debugfs(d_tracer);
+
return 0;
}
fs_initcall(ftrace_init_debugfs);
@@ -2538,7 +3130,7 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-static atomic_t ftrace_graph_active;
+static int ftrace_graph_active;
static struct notifier_block ftrace_suspend_notifier;
int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
@@ -2690,7 +3282,7 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
mutex_lock(&ftrace_lock);
/* we currently allow only one tracer registered at a time */
- if (atomic_read(&ftrace_graph_active)) {
+ if (ftrace_graph_active) {
ret = -EBUSY;
goto out;
}
@@ -2698,10 +3290,10 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call;
register_pm_notifier(&ftrace_suspend_notifier);
- atomic_inc(&ftrace_graph_active);
+ ftrace_graph_active++;
ret = start_graph_tracing();
if (ret) {
- atomic_dec(&ftrace_graph_active);
+ ftrace_graph_active--;
goto out;
}
@@ -2719,10 +3311,10 @@ void unregister_ftrace_graph(void)
{
mutex_lock(&ftrace_lock);
- if (!unlikely(atomic_read(&ftrace_graph_active)))
+ if (unlikely(!ftrace_graph_active))
goto out;
- atomic_dec(&ftrace_graph_active);
+ ftrace_graph_active--;
unregister_trace_sched_switch(ftrace_graph_probe_sched_switch);
ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
ftrace_graph_entry = ftrace_graph_entry_stub;
@@ -2736,7 +3328,7 @@ void unregister_ftrace_graph(void)
/* Allocate a return stack for newly created task */
void ftrace_graph_init_task(struct task_struct *t)
{
- if (atomic_read(&ftrace_graph_active)) {
+ if (ftrace_graph_active) {
t->ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH
* sizeof(struct ftrace_ret_stack),
GFP_KERNEL);
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c
index 5011f4d91e37..86cdf671d7e2 100644
--- a/kernel/trace/kmemtrace.c
+++ b/kernel/trace/kmemtrace.c
@@ -12,7 +12,7 @@
#include <linux/dcache.h>
#include <linux/fs.h>
-#include <trace/kmemtrace.h>
+#include <linux/kmemtrace.h>
#include "trace_output.h"
#include "trace.h"
@@ -42,6 +42,7 @@ static inline void kmemtrace_alloc(enum kmemtrace_type_id type_id,
gfp_t gfp_flags,
int node)
{
+ struct ftrace_event_call *call = &event_kmem_alloc;
struct trace_array *tr = kmemtrace_array;
struct kmemtrace_alloc_entry *entry;
struct ring_buffer_event *event;
@@ -62,7 +63,8 @@ static inline void kmemtrace_alloc(enum kmemtrace_type_id type_id,
entry->gfp_flags = gfp_flags;
entry->node = node;
- ring_buffer_unlock_commit(tr->buffer, event);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ ring_buffer_unlock_commit(tr->buffer, event);
trace_wake_up();
}
@@ -71,6 +73,7 @@ static inline void kmemtrace_free(enum kmemtrace_type_id type_id,
unsigned long call_site,
const void *ptr)
{
+ struct ftrace_event_call *call = &event_kmem_free;
struct trace_array *tr = kmemtrace_array;
struct kmemtrace_free_entry *entry;
struct ring_buffer_event *event;
@@ -86,7 +89,8 @@ static inline void kmemtrace_free(enum kmemtrace_type_id type_id,
entry->call_site = call_site;
entry->ptr = ptr;
- ring_buffer_unlock_commit(tr->buffer, event);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ ring_buffer_unlock_commit(tr->buffer, event);
trace_wake_up();
}
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 960cbf44c844..361170609bd0 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -22,6 +22,28 @@
#include "trace.h"
/*
+ * The ring buffer header is special. We must manually up keep it.
+ */
+int ring_buffer_print_entry_header(struct trace_seq *s)
+{
+ int ret;
+
+ ret = trace_seq_printf(s, "# compressed entry header\n");
+ ret = trace_seq_printf(s, "\ttype_len : 5 bits\n");
+ ret = trace_seq_printf(s, "\ttime_delta : 27 bits\n");
+ ret = trace_seq_printf(s, "\tarray : 32 bits\n");
+ ret = trace_seq_printf(s, "\n");
+ ret = trace_seq_printf(s, "\tpadding : type == %d\n",
+ RINGBUF_TYPE_PADDING);
+ ret = trace_seq_printf(s, "\ttime_extend : type == %d\n",
+ RINGBUF_TYPE_TIME_EXTEND);
+ ret = trace_seq_printf(s, "\tdata max type_len == %d\n",
+ RINGBUF_TYPE_DATA_TYPE_LEN_MAX);
+
+ return ret;
+}
+
+/*
* The ring buffer is made up of a list of pages. A separate list of pages is
* allocated for each CPU. A writer may only write to a buffer that is
* associated with the CPU it is currently executing on. A reader may read
@@ -182,7 +204,10 @@ EXPORT_SYMBOL_GPL(tracing_is_on);
#define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array))
#define RB_ALIGNMENT 4U
-#define RB_MAX_SMALL_DATA 28
+#define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX)
+
+/* define RINGBUF_TYPE_DATA for 'case RINGBUF_TYPE_DATA:' */
+#define RINGBUF_TYPE_DATA 0 ... RINGBUF_TYPE_DATA_TYPE_LEN_MAX
enum {
RB_LEN_TIME_EXTEND = 8,
@@ -191,48 +216,28 @@ enum {
static inline int rb_null_event(struct ring_buffer_event *event)
{
- return event->type == RINGBUF_TYPE_PADDING && event->time_delta == 0;
+ return event->type_len == RINGBUF_TYPE_PADDING
+ && event->time_delta == 0;
}
static inline int rb_discarded_event(struct ring_buffer_event *event)
{
- return event->type == RINGBUF_TYPE_PADDING && event->time_delta;
+ return event->type_len == RINGBUF_TYPE_PADDING && event->time_delta;
}
static void rb_event_set_padding(struct ring_buffer_event *event)
{
- event->type = RINGBUF_TYPE_PADDING;
+ event->type_len = RINGBUF_TYPE_PADDING;
event->time_delta = 0;
}
-/**
- * ring_buffer_event_discard - discard an event in the ring buffer
- * @buffer: the ring buffer
- * @event: the event to discard
- *
- * Sometimes a event that is in the ring buffer needs to be ignored.
- * This function lets the user discard an event in the ring buffer
- * and then that event will not be read later.
- *
- * Note, it is up to the user to be careful with this, and protect
- * against races. If the user discards an event that has been consumed
- * it is possible that it could corrupt the ring buffer.
- */
-void ring_buffer_event_discard(struct ring_buffer_event *event)
-{
- event->type = RINGBUF_TYPE_PADDING;
- /* time delta must be non zero */
- if (!event->time_delta)
- event->time_delta = 1;
-}
-
static unsigned
rb_event_data_length(struct ring_buffer_event *event)
{
unsigned length;
- if (event->len)
- length = event->len * RB_ALIGNMENT;
+ if (event->type_len)
+ length = event->type_len * RB_ALIGNMENT;
else
length = event->array[0];
return length + RB_EVNT_HDR_SIZE;
@@ -242,12 +247,12 @@ rb_event_data_length(struct ring_buffer_event *event)
static unsigned
rb_event_length(struct ring_buffer_event *event)
{
- switch (event->type) {
+ switch (event->type_len) {
case RINGBUF_TYPE_PADDING:
if (rb_null_event(event))
/* undefined */
return -1;
- return rb_event_data_length(event);
+ return event->array[0] + RB_EVNT_HDR_SIZE;
case RINGBUF_TYPE_TIME_EXTEND:
return RB_LEN_TIME_EXTEND;
@@ -271,7 +276,7 @@ rb_event_length(struct ring_buffer_event *event)
unsigned ring_buffer_event_length(struct ring_buffer_event *event)
{
unsigned length = rb_event_length(event);
- if (event->type != RINGBUF_TYPE_DATA)
+ if (event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX)
return length;
length -= RB_EVNT_HDR_SIZE;
if (length > RB_MAX_SMALL_DATA + sizeof(event->array[0]))
@@ -284,9 +289,9 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_length);
static void *
rb_event_data(struct ring_buffer_event *event)
{
- BUG_ON(event->type != RINGBUF_TYPE_DATA);
+ BUG_ON(event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX);
/* If length is in len field, then array[0] has the data */
- if (event->len)
+ if (event->type_len)
return (void *)&event->array[0];
/* Otherwise length is in array[0] and array[1] has the data */
return (void *)&event->array[1];
@@ -316,9 +321,10 @@ struct buffer_data_page {
};
struct buffer_page {
+ struct list_head list; /* list of buffer pages */
local_t write; /* index for next write */
unsigned read; /* index for next read */
- struct list_head list; /* list of free pages */
+ local_t entries; /* entries on this page */
struct buffer_data_page *page; /* Actual data page */
};
@@ -361,6 +367,28 @@ static inline int test_time_stamp(u64 delta)
#define BUF_PAGE_SIZE (PAGE_SIZE - BUF_PAGE_HDR_SIZE)
+int ring_buffer_print_page_header(struct trace_seq *s)
+{
+ struct buffer_data_page field;
+ int ret;
+
+ ret = trace_seq_printf(s, "\tfield: u64 timestamp;\t"
+ "offset:0;\tsize:%u;\n",
+ (unsigned int)sizeof(field.time_stamp));
+
+ ret = trace_seq_printf(s, "\tfield: local_t commit;\t"
+ "offset:%u;\tsize:%u;\n",
+ (unsigned int)offsetof(typeof(field), commit),
+ (unsigned int)sizeof(field.commit));
+
+ ret = trace_seq_printf(s, "\tfield: char data;\t"
+ "offset:%u;\tsize:%u;\n",
+ (unsigned int)offsetof(typeof(field), data),
+ (unsigned int)BUF_PAGE_SIZE);
+
+ return ret;
+}
+
/*
* head_page == tail_page && head == tail then buffer is empty.
*/
@@ -375,8 +403,11 @@ struct ring_buffer_per_cpu {
struct buffer_page *tail_page; /* write to tail */
struct buffer_page *commit_page; /* committed pages */
struct buffer_page *reader_page;
+ unsigned long nmi_dropped;
+ unsigned long commit_overrun;
unsigned long overrun;
- unsigned long entries;
+ unsigned long read;
+ local_t entries;
u64 write_stamp;
u64 read_stamp;
atomic_t record_disabled;
@@ -947,31 +978,6 @@ static inline unsigned rb_head_size(struct ring_buffer_per_cpu *cpu_buffer)
return rb_page_commit(cpu_buffer->head_page);
}
-/*
- * When the tail hits the head and the buffer is in overwrite mode,
- * the head jumps to the next page and all content on the previous
- * page is discarded. But before doing so, we update the overrun
- * variable of the buffer.
- */
-static void rb_update_overflow(struct ring_buffer_per_cpu *cpu_buffer)
-{
- struct ring_buffer_event *event;
- unsigned long head;
-
- for (head = 0; head < rb_head_size(cpu_buffer);
- head += rb_event_length(event)) {
-
- event = __rb_page_index(cpu_buffer->head_page, head);
- if (RB_WARN_ON(cpu_buffer, rb_null_event(event)))
- return;
- /* Only count data entries */
- if (event->type != RINGBUF_TYPE_DATA)
- continue;
- cpu_buffer->overrun++;
- cpu_buffer->entries--;
- }
-}
-
static inline void rb_inc_page(struct ring_buffer_per_cpu *cpu_buffer,
struct buffer_page **bpage)
{
@@ -1110,28 +1116,21 @@ static void
rb_update_event(struct ring_buffer_event *event,
unsigned type, unsigned length)
{
- event->type = type;
+ event->type_len = type;
switch (type) {
case RINGBUF_TYPE_PADDING:
- break;
-
case RINGBUF_TYPE_TIME_EXTEND:
- event->len = DIV_ROUND_UP(RB_LEN_TIME_EXTEND, RB_ALIGNMENT);
- break;
-
case RINGBUF_TYPE_TIME_STAMP:
- event->len = DIV_ROUND_UP(RB_LEN_TIME_STAMP, RB_ALIGNMENT);
break;
- case RINGBUF_TYPE_DATA:
+ case 0:
length -= RB_EVNT_HDR_SIZE;
- if (length > RB_MAX_SMALL_DATA) {
- event->len = 0;
+ if (length > RB_MAX_SMALL_DATA)
event->array[0] = length;
- } else
- event->len = DIV_ROUND_UP(length, RB_ALIGNMENT);
+ else
+ event->type_len = DIV_ROUND_UP(length, RB_ALIGNMENT);
break;
default:
BUG();
@@ -1155,131 +1154,156 @@ static unsigned rb_calculate_event_length(unsigned length)
return length;
}
+
static struct ring_buffer_event *
-__rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
- unsigned type, unsigned long length, u64 *ts)
+rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer,
+ unsigned long length, unsigned long tail,
+ struct buffer_page *commit_page,
+ struct buffer_page *tail_page, u64 *ts)
{
- struct buffer_page *tail_page, *head_page, *reader_page, *commit_page;
- unsigned long tail, write;
+ struct buffer_page *next_page, *head_page, *reader_page;
struct ring_buffer *buffer = cpu_buffer->buffer;
struct ring_buffer_event *event;
- unsigned long flags;
bool lock_taken = false;
+ unsigned long flags;
- commit_page = cpu_buffer->commit_page;
- /* we just need to protect against interrupts */
- barrier();
- tail_page = cpu_buffer->tail_page;
- write = local_add_return(length, &tail_page->write);
- tail = write - length;
+ next_page = tail_page;
- /* See if we shot pass the end of this buffer page */
- if (write > BUF_PAGE_SIZE) {
- struct buffer_page *next_page = tail_page;
+ local_irq_save(flags);
+ /*
+ * Since the write to the buffer is still not
+ * fully lockless, we must be careful with NMIs.
+ * The locks in the writers are taken when a write
+ * crosses to a new page. The locks protect against
+ * races with the readers (this will soon be fixed
+ * with a lockless solution).
+ *
+ * Because we can not protect against NMIs, and we
+ * want to keep traces reentrant, we need to manage
+ * what happens when we are in an NMI.
+ *
+ * NMIs can happen after we take the lock.
+ * If we are in an NMI, only take the lock
+ * if it is not already taken. Otherwise
+ * simply fail.
+ */
+ if (unlikely(in_nmi())) {
+ if (!__raw_spin_trylock(&cpu_buffer->lock)) {
+ cpu_buffer->nmi_dropped++;
+ goto out_reset;
+ }
+ } else
+ __raw_spin_lock(&cpu_buffer->lock);
- local_irq_save(flags);
- /*
- * Since the write to the buffer is still not
- * fully lockless, we must be careful with NMIs.
- * The locks in the writers are taken when a write
- * crosses to a new page. The locks protect against
- * races with the readers (this will soon be fixed
- * with a lockless solution).
- *
- * Because we can not protect against NMIs, and we
- * want to keep traces reentrant, we need to manage
- * what happens when we are in an NMI.
- *
- * NMIs can happen after we take the lock.
- * If we are in an NMI, only take the lock
- * if it is not already taken. Otherwise
- * simply fail.
- */
- if (unlikely(in_nmi())) {
- if (!__raw_spin_trylock(&cpu_buffer->lock))
- goto out_reset;
- } else
- __raw_spin_lock(&cpu_buffer->lock);
+ lock_taken = true;
- lock_taken = true;
+ rb_inc_page(cpu_buffer, &next_page);
- rb_inc_page(cpu_buffer, &next_page);
+ head_page = cpu_buffer->head_page;
+ reader_page = cpu_buffer->reader_page;
- head_page = cpu_buffer->head_page;
- reader_page = cpu_buffer->reader_page;
+ /* we grabbed the lock before incrementing */
+ if (RB_WARN_ON(cpu_buffer, next_page == reader_page))
+ goto out_reset;
- /* we grabbed the lock before incrementing */
- if (RB_WARN_ON(cpu_buffer, next_page == reader_page))
- goto out_reset;
+ /*
+ * If for some reason, we had an interrupt storm that made
+ * it all the way around the buffer, bail, and warn
+ * about it.
+ */
+ if (unlikely(next_page == commit_page)) {
+ cpu_buffer->commit_overrun++;
+ goto out_reset;
+ }
- /*
- * If for some reason, we had an interrupt storm that made
- * it all the way around the buffer, bail, and warn
- * about it.
- */
- if (unlikely(next_page == commit_page)) {
- WARN_ON_ONCE(1);
+ if (next_page == head_page) {
+ if (!(buffer->flags & RB_FL_OVERWRITE))
goto out_reset;
- }
-
- if (next_page == head_page) {
- if (!(buffer->flags & RB_FL_OVERWRITE))
- goto out_reset;
- /* tail_page has not moved yet? */
- if (tail_page == cpu_buffer->tail_page) {
- /* count overflows */
- rb_update_overflow(cpu_buffer);
+ /* tail_page has not moved yet? */
+ if (tail_page == cpu_buffer->tail_page) {
+ /* count overflows */
+ cpu_buffer->overrun +=
+ local_read(&head_page->entries);
- rb_inc_page(cpu_buffer, &head_page);
- cpu_buffer->head_page = head_page;
- cpu_buffer->head_page->read = 0;
- }
+ rb_inc_page(cpu_buffer, &head_page);
+ cpu_buffer->head_page = head_page;
+ cpu_buffer->head_page->read = 0;
}
+ }
- /*
- * If the tail page is still the same as what we think
- * it is, then it is up to us to update the tail
- * pointer.
- */
- if (tail_page == cpu_buffer->tail_page) {
- local_set(&next_page->write, 0);
- local_set(&next_page->page->commit, 0);
- cpu_buffer->tail_page = next_page;
+ /*
+ * If the tail page is still the same as what we think
+ * it is, then it is up to us to update the tail
+ * pointer.
+ */
+ if (tail_page == cpu_buffer->tail_page) {
+ local_set(&next_page->write, 0);
+ local_set(&next_page->entries, 0);
+ local_set(&next_page->page->commit, 0);
+ cpu_buffer->tail_page = next_page;
+
+ /* reread the time stamp */
+ *ts = ring_buffer_time_stamp(buffer, cpu_buffer->cpu);
+ cpu_buffer->tail_page->page->time_stamp = *ts;
+ }
- /* reread the time stamp */
- *ts = ring_buffer_time_stamp(buffer, cpu_buffer->cpu);
- cpu_buffer->tail_page->page->time_stamp = *ts;
- }
+ /*
+ * The actual tail page has moved forward.
+ */
+ if (tail < BUF_PAGE_SIZE) {
+ /* Mark the rest of the page with padding */
+ event = __rb_page_index(tail_page, tail);
+ rb_event_set_padding(event);
+ }
- /*
- * The actual tail page has moved forward.
- */
- if (tail < BUF_PAGE_SIZE) {
- /* Mark the rest of the page with padding */
- event = __rb_page_index(tail_page, tail);
- rb_event_set_padding(event);
- }
+ /* Set the write back to the previous setting */
+ local_sub(length, &tail_page->write);
- if (tail <= BUF_PAGE_SIZE)
- /* Set the write back to the previous setting */
- local_set(&tail_page->write, tail);
+ /*
+ * If this was a commit entry that failed,
+ * increment that too
+ */
+ if (tail_page == cpu_buffer->commit_page &&
+ tail == rb_commit_index(cpu_buffer)) {
+ rb_set_commit_to_write(cpu_buffer);
+ }
- /*
- * If this was a commit entry that failed,
- * increment that too
- */
- if (tail_page == cpu_buffer->commit_page &&
- tail == rb_commit_index(cpu_buffer)) {
- rb_set_commit_to_write(cpu_buffer);
- }
+ __raw_spin_unlock(&cpu_buffer->lock);
+ local_irq_restore(flags);
+
+ /* fail and let the caller try again */
+ return ERR_PTR(-EAGAIN);
+
+ out_reset:
+ /* reset write */
+ local_sub(length, &tail_page->write);
+ if (likely(lock_taken))
__raw_spin_unlock(&cpu_buffer->lock);
- local_irq_restore(flags);
+ local_irq_restore(flags);
+ return NULL;
+}
- /* fail and let the caller try again */
- return ERR_PTR(-EAGAIN);
- }
+static struct ring_buffer_event *
+__rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
+ unsigned type, unsigned long length, u64 *ts)
+{
+ struct buffer_page *tail_page, *commit_page;
+ struct ring_buffer_event *event;
+ unsigned long tail, write;
+
+ commit_page = cpu_buffer->commit_page;
+ /* we just need to protect against interrupts */
+ barrier();
+ tail_page = cpu_buffer->tail_page;
+ write = local_add_return(length, &tail_page->write);
+ tail = write - length;
+
+ /* See if we shot pass the end of this buffer page */
+ if (write > BUF_PAGE_SIZE)
+ return rb_move_tail(cpu_buffer, length, tail,
+ commit_page, tail_page, ts);
/* We reserved something on the buffer */
@@ -1289,6 +1313,10 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
event = __rb_page_index(tail_page, tail);
rb_update_event(event, type, length);
+ /* The passed in type is zero for DATA */
+ if (likely(!type))
+ local_inc(&tail_page->entries);
+
/*
* If this is a commit and the tail is zero, then update
* this page's time stamp.
@@ -1297,16 +1325,6 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
cpu_buffer->commit_page->page->time_stamp = *ts;
return event;
-
- out_reset:
- /* reset write */
- if (tail <= BUF_PAGE_SIZE)
- local_set(&tail_page->write, tail);
-
- if (likely(lock_taken))
- __raw_spin_unlock(&cpu_buffer->lock);
- local_irq_restore(flags);
- return NULL;
}
static int
@@ -1458,6 +1476,36 @@ rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer,
return event;
}
+#define TRACE_RECURSIVE_DEPTH 16
+
+static int trace_recursive_lock(void)
+{
+ current->trace_recursion++;
+
+ if (likely(current->trace_recursion < TRACE_RECURSIVE_DEPTH))
+ return 0;
+
+ /* Disable all tracing before we do anything else */
+ tracing_off_permanent();
+
+ printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:"
+ "HC[%lu]:SC[%lu]:NMI[%lu]\n",
+ current->trace_recursion,
+ hardirq_count() >> HARDIRQ_SHIFT,
+ softirq_count() >> SOFTIRQ_SHIFT,
+ in_nmi());
+
+ WARN_ON_ONCE(1);
+ return -1;
+}
+
+static void trace_recursive_unlock(void)
+{
+ WARN_ON_ONCE(!current->trace_recursion);
+
+ current->trace_recursion--;
+}
+
static DEFINE_PER_CPU(int, rb_need_resched);
/**
@@ -1491,6 +1539,9 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length)
/* If we are tracing schedule, we don't want to recurse */
resched = ftrace_preempt_disable();
+ if (trace_recursive_lock())
+ goto out_nocheck;
+
cpu = raw_smp_processor_id();
if (!cpumask_test_cpu(cpu, buffer->cpumask))
@@ -1505,7 +1556,7 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length)
if (length > BUF_PAGE_SIZE)
goto out;
- event = rb_reserve_next_event(cpu_buffer, RINGBUF_TYPE_DATA, length);
+ event = rb_reserve_next_event(cpu_buffer, 0, length);
if (!event)
goto out;
@@ -1520,6 +1571,9 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length)
return event;
out:
+ trace_recursive_unlock();
+
+ out_nocheck:
ftrace_preempt_enable(resched);
return NULL;
}
@@ -1528,7 +1582,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_lock_reserve);
static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer,
struct ring_buffer_event *event)
{
- cpu_buffer->entries++;
+ local_inc(&cpu_buffer->entries);
/* Only process further if we own the commit */
if (!rb_is_commit(cpu_buffer, event))
@@ -1558,6 +1612,8 @@ int ring_buffer_unlock_commit(struct ring_buffer *buffer,
rb_commit(cpu_buffer, event);
+ trace_recursive_unlock();
+
/*
* Only the last preempt count needs to restore preemption.
*/
@@ -1570,6 +1626,119 @@ int ring_buffer_unlock_commit(struct ring_buffer *buffer,
}
EXPORT_SYMBOL_GPL(ring_buffer_unlock_commit);
+static inline void rb_event_discard(struct ring_buffer_event *event)
+{
+ /* array[0] holds the actual length for the discarded event */
+ event->array[0] = rb_event_data_length(event) - RB_EVNT_HDR_SIZE;
+ event->type_len = RINGBUF_TYPE_PADDING;
+ /* time delta must be non zero */
+ if (!event->time_delta)
+ event->time_delta = 1;
+}
+
+/**
+ * ring_buffer_event_discard - discard any event in the ring buffer
+ * @event: the event to discard
+ *
+ * Sometimes a event that is in the ring buffer needs to be ignored.
+ * This function lets the user discard an event in the ring buffer
+ * and then that event will not be read later.
+ *
+ * Note, it is up to the user to be careful with this, and protect
+ * against races. If the user discards an event that has been consumed
+ * it is possible that it could corrupt the ring buffer.
+ */
+void ring_buffer_event_discard(struct ring_buffer_event *event)
+{
+ rb_event_discard(event);
+}
+EXPORT_SYMBOL_GPL(ring_buffer_event_discard);
+
+/**
+ * ring_buffer_commit_discard - discard an event that has not been committed
+ * @buffer: the ring buffer
+ * @event: non committed event to discard
+ *
+ * This is similar to ring_buffer_event_discard but must only be
+ * performed on an event that has not been committed yet. The difference
+ * is that this will also try to free the event from the ring buffer
+ * if another event has not been added behind it.
+ *
+ * If another event has been added behind it, it will set the event
+ * up as discarded, and perform the commit.
+ *
+ * If this function is called, do not call ring_buffer_unlock_commit on
+ * the event.
+ */
+void ring_buffer_discard_commit(struct ring_buffer *buffer,
+ struct ring_buffer_event *event)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ unsigned long new_index, old_index;
+ struct buffer_page *bpage;
+ unsigned long index;
+ unsigned long addr;
+ int cpu;
+
+ /* The event is discarded regardless */
+ rb_event_discard(event);
+
+ /*
+ * This must only be called if the event has not been
+ * committed yet. Thus we can assume that preemption
+ * is still disabled.
+ */
+ RB_WARN_ON(buffer, preemptible());
+
+ cpu = smp_processor_id();
+ cpu_buffer = buffer->buffers[cpu];
+
+ new_index = rb_event_index(event);
+ old_index = new_index + rb_event_length(event);
+ addr = (unsigned long)event;
+ addr &= PAGE_MASK;
+
+ bpage = cpu_buffer->tail_page;
+
+ if (bpage == (void *)addr && rb_page_write(bpage) == old_index) {
+ /*
+ * This is on the tail page. It is possible that
+ * a write could come in and move the tail page
+ * and write to the next page. That is fine
+ * because we just shorten what is on this page.
+ */
+ index = local_cmpxchg(&bpage->write, old_index, new_index);
+ if (index == old_index)
+ goto out;
+ }
+
+ /*
+ * The commit is still visible by the reader, so we
+ * must increment entries.
+ */
+ local_inc(&cpu_buffer->entries);
+ out:
+ /*
+ * If a write came in and pushed the tail page
+ * we still need to update the commit pointer
+ * if we were the commit.
+ */
+ if (rb_is_commit(cpu_buffer, event))
+ rb_set_commit_to_write(cpu_buffer);
+
+ trace_recursive_unlock();
+
+ /*
+ * Only the last preempt count needs to restore preemption.
+ */
+ if (preempt_count() == 1)
+ ftrace_preempt_enable(per_cpu(rb_need_resched, cpu));
+ else
+ preempt_enable_no_resched_notrace();
+
+}
+EXPORT_SYMBOL_GPL(ring_buffer_discard_commit);
+
/**
* ring_buffer_write - write data to the buffer without reserving
* @buffer: The ring buffer to write to.
@@ -1613,8 +1782,7 @@ int ring_buffer_write(struct ring_buffer *buffer,
goto out;
event_length = rb_calculate_event_length(length);
- event = rb_reserve_next_event(cpu_buffer,
- RINGBUF_TYPE_DATA, event_length);
+ event = rb_reserve_next_event(cpu_buffer, 0, event_length);
if (!event)
goto out;
@@ -1728,7 +1896,8 @@ unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu)
return 0;
cpu_buffer = buffer->buffers[cpu];
- ret = cpu_buffer->entries;
+ ret = (local_read(&cpu_buffer->entries) - cpu_buffer->overrun)
+ - cpu_buffer->read;
return ret;
}
@@ -1755,6 +1924,47 @@ unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu)
EXPORT_SYMBOL_GPL(ring_buffer_overrun_cpu);
/**
+ * ring_buffer_nmi_dropped_cpu - get the number of nmis that were dropped
+ * @buffer: The ring buffer
+ * @cpu: The per CPU buffer to get the number of overruns from
+ */
+unsigned long ring_buffer_nmi_dropped_cpu(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ unsigned long ret;
+
+ if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ return 0;
+
+ cpu_buffer = buffer->buffers[cpu];
+ ret = cpu_buffer->nmi_dropped;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_nmi_dropped_cpu);
+
+/**
+ * ring_buffer_commit_overrun_cpu - get the number of overruns caused by commits
+ * @buffer: The ring buffer
+ * @cpu: The per CPU buffer to get the number of overruns from
+ */
+unsigned long
+ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ unsigned long ret;
+
+ if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ return 0;
+
+ cpu_buffer = buffer->buffers[cpu];
+ ret = cpu_buffer->commit_overrun;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_commit_overrun_cpu);
+
+/**
* ring_buffer_entries - get the number of entries in a buffer
* @buffer: The ring buffer
*
@@ -1770,7 +1980,8 @@ unsigned long ring_buffer_entries(struct ring_buffer *buffer)
/* if you care about this being correct, lock the buffer */
for_each_buffer_cpu(buffer, cpu) {
cpu_buffer = buffer->buffers[cpu];
- entries += cpu_buffer->entries;
+ entries += (local_read(&cpu_buffer->entries) -
+ cpu_buffer->overrun) - cpu_buffer->read;
}
return entries;
@@ -1862,7 +2073,7 @@ rb_update_read_stamp(struct ring_buffer_per_cpu *cpu_buffer,
{
u64 delta;
- switch (event->type) {
+ switch (event->type_len) {
case RINGBUF_TYPE_PADDING:
return;
@@ -1893,7 +2104,7 @@ rb_update_iter_read_stamp(struct ring_buffer_iter *iter,
{
u64 delta;
- switch (event->type) {
+ switch (event->type_len) {
case RINGBUF_TYPE_PADDING:
return;
@@ -1966,6 +2177,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
cpu_buffer->reader_page->list.prev = reader->list.prev;
local_set(&cpu_buffer->reader_page->write, 0);
+ local_set(&cpu_buffer->reader_page->entries, 0);
local_set(&cpu_buffer->reader_page->page->commit, 0);
/* Make the reader page now replace the head */
@@ -2008,8 +2220,9 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer)
event = rb_reader_event(cpu_buffer);
- if (event->type == RINGBUF_TYPE_DATA || rb_discarded_event(event))
- cpu_buffer->entries--;
+ if (event->type_len <= RINGBUF_TYPE_DATA_TYPE_LEN_MAX
+ || rb_discarded_event(event))
+ cpu_buffer->read++;
rb_update_read_stamp(cpu_buffer, event);
@@ -2089,7 +2302,7 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
event = rb_reader_event(cpu_buffer);
- switch (event->type) {
+ switch (event->type_len) {
case RINGBUF_TYPE_PADDING:
if (rb_null_event(event))
RB_WARN_ON(cpu_buffer, 1);
@@ -2161,7 +2374,7 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
event = rb_iter_head_event(iter);
- switch (event->type) {
+ switch (event->type_len) {
case RINGBUF_TYPE_PADDING:
if (rb_null_event(event)) {
rb_inc_iter(iter);
@@ -2220,7 +2433,7 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
event = rb_buffer_peek(buffer, cpu, ts);
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
- if (event && event->type == RINGBUF_TYPE_PADDING) {
+ if (event && event->type_len == RINGBUF_TYPE_PADDING) {
cpu_relax();
goto again;
}
@@ -2248,7 +2461,7 @@ ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
event = rb_iter_peek(iter, ts);
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
- if (event && event->type == RINGBUF_TYPE_PADDING) {
+ if (event && event->type_len == RINGBUF_TYPE_PADDING) {
cpu_relax();
goto again;
}
@@ -2293,7 +2506,7 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
out:
preempt_enable();
- if (event && event->type == RINGBUF_TYPE_PADDING) {
+ if (event && event->type_len == RINGBUF_TYPE_PADDING) {
cpu_relax();
goto again;
}
@@ -2386,7 +2599,7 @@ ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts)
out:
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
- if (event && event->type == RINGBUF_TYPE_PADDING) {
+ if (event && event->type_len == RINGBUF_TYPE_PADDING) {
cpu_relax();
goto again;
}
@@ -2411,6 +2624,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
cpu_buffer->head_page
= list_entry(cpu_buffer->pages.next, struct buffer_page, list);
local_set(&cpu_buffer->head_page->write, 0);
+ local_set(&cpu_buffer->head_page->entries, 0);
local_set(&cpu_buffer->head_page->page->commit, 0);
cpu_buffer->head_page->read = 0;
@@ -2420,11 +2634,15 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
local_set(&cpu_buffer->reader_page->write, 0);
+ local_set(&cpu_buffer->reader_page->entries, 0);
local_set(&cpu_buffer->reader_page->page->commit, 0);
cpu_buffer->reader_page->read = 0;
+ cpu_buffer->nmi_dropped = 0;
+ cpu_buffer->commit_overrun = 0;
cpu_buffer->overrun = 0;
- cpu_buffer->entries = 0;
+ cpu_buffer->read = 0;
+ local_set(&cpu_buffer->entries, 0);
cpu_buffer->write_stamp = 0;
cpu_buffer->read_stamp = 0;
@@ -2443,6 +2661,8 @@ void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu)
if (!cpumask_test_cpu(cpu, buffer->cpumask))
return;
+ atomic_inc(&cpu_buffer->record_disabled);
+
spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
__raw_spin_lock(&cpu_buffer->lock);
@@ -2452,6 +2672,8 @@ void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu)
__raw_spin_unlock(&cpu_buffer->lock);
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+
+ atomic_dec(&cpu_buffer->record_disabled);
}
EXPORT_SYMBOL_GPL(ring_buffer_reset_cpu);
@@ -2578,28 +2800,6 @@ out:
}
EXPORT_SYMBOL_GPL(ring_buffer_swap_cpu);
-static void rb_remove_entries(struct ring_buffer_per_cpu *cpu_buffer,
- struct buffer_data_page *bpage,
- unsigned int offset)
-{
- struct ring_buffer_event *event;
- unsigned long head;
-
- __raw_spin_lock(&cpu_buffer->lock);
- for (head = offset; head < local_read(&bpage->commit);
- head += rb_event_length(event)) {
-
- event = __rb_data_page_index(bpage, head);
- if (RB_WARN_ON(cpu_buffer, rb_null_event(event)))
- return;
- /* Only count data entries */
- if (event->type != RINGBUF_TYPE_DATA)
- continue;
- cpu_buffer->entries--;
- }
- __raw_spin_unlock(&cpu_buffer->lock);
-}
-
/**
* ring_buffer_alloc_read_page - allocate a page to read from buffer
* @buffer: the buffer to allocate for.
@@ -2630,6 +2830,7 @@ void *ring_buffer_alloc_read_page(struct ring_buffer *buffer)
return bpage;
}
+EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);
/**
* ring_buffer_free_read_page - free an allocated read page
@@ -2642,6 +2843,7 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data)
{
free_page((unsigned long)data);
}
+EXPORT_SYMBOL_GPL(ring_buffer_free_read_page);
/**
* ring_buffer_read_page - extract a page from the ring buffer
@@ -2768,16 +2970,17 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
/* we copied everything to the beginning */
read = 0;
} else {
+ /* update the entry counter */
+ cpu_buffer->read += local_read(&reader->entries);
+
/* swap the pages */
rb_init_page(bpage);
bpage = reader->page;
reader->page = *data_page;
local_set(&reader->write, 0);
+ local_set(&reader->entries, 0);
reader->read = 0;
*data_page = bpage;
-
- /* update the entry counter */
- rb_remove_entries(cpu_buffer, bpage, read);
}
ret = read;
@@ -2787,6 +2990,7 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
out:
return ret;
}
+EXPORT_SYMBOL_GPL(ring_buffer_read_page);
static ssize_t
rb_simple_read(struct file *filp, char __user *ubuf,
@@ -2845,14 +3049,11 @@ static const struct file_operations rb_simple_fops = {
static __init int rb_init_debugfs(void)
{
struct dentry *d_tracer;
- struct dentry *entry;
d_tracer = tracing_init_dentry();
- entry = debugfs_create_file("tracing_on", 0644, d_tracer,
- &ring_buffer_flags, &rb_simple_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'tracing_on' entry\n");
+ trace_create_file("tracing_on", 0644, d_tracer,
+ &ring_buffer_flags, &rb_simple_fops);
return 0;
}
diff --git a/kernel/trace/ring_buffer_benchmark.c b/kernel/trace/ring_buffer_benchmark.c
new file mode 100644
index 000000000000..a21aa7b3d05e
--- /dev/null
+++ b/kernel/trace/ring_buffer_benchmark.c
@@ -0,0 +1,408 @@
+/*
+ * ring buffer tester and benchmark
+ *
+ * Copyright (C) 2009 Steven Rostedt <srostedt@redhat.com>
+ */
+#include <linux/ring_buffer.h>
+#include <linux/completion.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/time.h>
+
+struct rb_page {
+ u64 ts;
+ local_t commit;
+ char data[4080];
+};
+
+/* run time and sleep time in seconds */
+#define RUN_TIME 10
+#define SLEEP_TIME 10
+
+/* number of events for writer to wake up the reader */
+static int wakeup_interval = 100;
+
+static int reader_finish;
+static struct completion read_start;
+static struct completion read_done;
+
+static struct ring_buffer *buffer;
+static struct task_struct *producer;
+static struct task_struct *consumer;
+static unsigned long read;
+
+static int disable_reader;
+module_param(disable_reader, uint, 0644);
+MODULE_PARM_DESC(disable_reader, "only run producer");
+
+static int read_events;
+
+static int kill_test;
+
+#define KILL_TEST() \
+ do { \
+ if (!kill_test) { \
+ kill_test = 1; \
+ WARN_ON(1); \
+ } \
+ } while (0)
+
+enum event_status {
+ EVENT_FOUND,
+ EVENT_DROPPED,
+};
+
+static enum event_status read_event(int cpu)
+{
+ struct ring_buffer_event *event;
+ int *entry;
+ u64 ts;
+
+ event = ring_buffer_consume(buffer, cpu, &ts);
+ if (!event)
+ return EVENT_DROPPED;
+
+ entry = ring_buffer_event_data(event);
+ if (*entry != cpu) {
+ KILL_TEST();
+ return EVENT_DROPPED;
+ }
+
+ read++;
+ return EVENT_FOUND;
+}
+
+static enum event_status read_page(int cpu)
+{
+ struct ring_buffer_event *event;
+ struct rb_page *rpage;
+ unsigned long commit;
+ void *bpage;
+ int *entry;
+ int ret;
+ int inc;
+ int i;
+
+ bpage = ring_buffer_alloc_read_page(buffer);
+ if (!bpage)
+ return EVENT_DROPPED;
+
+ ret = ring_buffer_read_page(buffer, &bpage, PAGE_SIZE, cpu, 1);
+ if (ret >= 0) {
+ rpage = bpage;
+ commit = local_read(&rpage->commit);
+ for (i = 0; i < commit && !kill_test; i += inc) {
+
+ if (i >= (PAGE_SIZE - offsetof(struct rb_page, data))) {
+ KILL_TEST();
+ break;
+ }
+
+ inc = -1;
+ event = (void *)&rpage->data[i];
+ switch (event->type_len) {
+ case RINGBUF_TYPE_PADDING:
+ /* We don't expect any padding */
+ KILL_TEST();
+ break;
+ case RINGBUF_TYPE_TIME_EXTEND:
+ inc = 8;
+ break;
+ case 0:
+ entry = ring_buffer_event_data(event);
+ if (*entry != cpu) {
+ KILL_TEST();
+ break;
+ }
+ read++;
+ if (!event->array[0]) {
+ KILL_TEST();
+ break;
+ }
+ inc = event->array[0];
+ break;
+ default:
+ entry = ring_buffer_event_data(event);
+ if (*entry != cpu) {
+ KILL_TEST();
+ break;
+ }
+ read++;
+ inc = ((event->type_len + 1) * 4);
+ }
+ if (kill_test)
+ break;
+
+ if (inc <= 0) {
+ KILL_TEST();
+ break;
+ }
+ }
+ }
+ ring_buffer_free_read_page(buffer, bpage);
+
+ if (ret < 0)
+ return EVENT_DROPPED;
+ return EVENT_FOUND;
+}
+
+static void ring_buffer_consumer(void)
+{
+ /* toggle between reading pages and events */
+ read_events ^= 1;
+
+ read = 0;
+ while (!reader_finish && !kill_test) {
+ int found;
+
+ do {
+ int cpu;
+
+ found = 0;
+ for_each_online_cpu(cpu) {
+ enum event_status stat;
+
+ if (read_events)
+ stat = read_event(cpu);
+ else
+ stat = read_page(cpu);
+
+ if (kill_test)
+ break;
+ if (stat == EVENT_FOUND)
+ found = 1;
+ }
+ } while (found && !kill_test);
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (reader_finish)
+ break;
+
+ schedule();
+ __set_current_state(TASK_RUNNING);
+ }
+ reader_finish = 0;
+ complete(&read_done);
+}
+
+static void ring_buffer_producer(void)
+{
+ struct timeval start_tv;
+ struct timeval end_tv;
+ unsigned long long time;
+ unsigned long long entries;
+ unsigned long long overruns;
+ unsigned long missed = 0;
+ unsigned long hit = 0;
+ unsigned long avg;
+ int cnt = 0;
+
+ /*
+ * Hammer the buffer for 10 secs (this may
+ * make the system stall)
+ */
+ pr_info("Starting ring buffer hammer\n");
+ do_gettimeofday(&start_tv);
+ do {
+ struct ring_buffer_event *event;
+ int *entry;
+
+ event = ring_buffer_lock_reserve(buffer, 10);
+ if (!event) {
+ missed++;
+ } else {
+ hit++;
+ entry = ring_buffer_event_data(event);
+ *entry = smp_processor_id();
+ ring_buffer_unlock_commit(buffer, event);
+ }
+ do_gettimeofday(&end_tv);
+
+ cnt++;
+ if (consumer && !(cnt % wakeup_interval))
+ wake_up_process(consumer);
+
+#ifndef CONFIG_PREEMPT
+ /*
+ * If we are a non preempt kernel, the 10 second run will
+ * stop everything while it runs. Instead, we will call
+ * cond_resched and also add any time that was lost by a
+ * rescedule.
+ *
+ * Do a cond resched at the same frequency we would wake up
+ * the reader.
+ */
+ if (cnt % wakeup_interval)
+ cond_resched();
+#endif
+
+ } while (end_tv.tv_sec < (start_tv.tv_sec + RUN_TIME) && !kill_test);
+ pr_info("End ring buffer hammer\n");
+
+ if (consumer) {
+ /* Init both completions here to avoid races */
+ init_completion(&read_start);
+ init_completion(&read_done);
+ /* the completions must be visible before the finish var */
+ smp_wmb();
+ reader_finish = 1;
+ /* finish var visible before waking up the consumer */
+ smp_wmb();
+ wake_up_process(consumer);
+ wait_for_completion(&read_done);
+ }
+
+ time = end_tv.tv_sec - start_tv.tv_sec;
+ time *= 1000000;
+ time += (long long)((long)end_tv.tv_usec - (long)start_tv.tv_usec);
+
+ entries = ring_buffer_entries(buffer);
+ overruns = ring_buffer_overruns(buffer);
+
+ if (kill_test)
+ pr_info("ERROR!\n");
+ pr_info("Time: %lld (usecs)\n", time);
+ pr_info("Overruns: %lld\n", overruns);
+ if (disable_reader)
+ pr_info("Read: (reader disabled)\n");
+ else
+ pr_info("Read: %ld (by %s)\n", read,
+ read_events ? "events" : "pages");
+ pr_info("Entries: %lld\n", entries);
+ pr_info("Total: %lld\n", entries + overruns + read);
+ pr_info("Missed: %ld\n", missed);
+ pr_info("Hit: %ld\n", hit);
+
+ do_div(time, 1000);
+ if (time)
+ hit /= (long)time;
+ else
+ pr_info("TIME IS ZERO??\n");
+
+ pr_info("Entries per millisec: %ld\n", hit);
+
+ if (hit) {
+ avg = 1000000 / hit;
+ pr_info("%ld ns per entry\n", avg);
+ }
+
+
+ if (missed) {
+ if (time)
+ missed /= (long)time;
+
+ pr_info("Total iterations per millisec: %ld\n", hit + missed);
+
+ avg = 1000000 / (hit + missed);
+ pr_info("%ld ns per entry\n", avg);
+ }
+}
+
+static void wait_to_die(void)
+{
+ set_current_state(TASK_INTERRUPTIBLE);
+ while (!kthread_should_stop()) {
+ schedule();
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+ __set_current_state(TASK_RUNNING);
+}
+
+static int ring_buffer_consumer_thread(void *arg)
+{
+ while (!kthread_should_stop() && !kill_test) {
+ complete(&read_start);
+
+ ring_buffer_consumer();
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (kthread_should_stop() || kill_test)
+ break;
+
+ schedule();
+ __set_current_state(TASK_RUNNING);
+ }
+ __set_current_state(TASK_RUNNING);
+
+ if (kill_test)
+ wait_to_die();
+
+ return 0;
+}
+
+static int ring_buffer_producer_thread(void *arg)
+{
+ init_completion(&read_start);
+
+ while (!kthread_should_stop() && !kill_test) {
+ ring_buffer_reset(buffer);
+
+ if (consumer) {
+ smp_wmb();
+ wake_up_process(consumer);
+ wait_for_completion(&read_start);
+ }
+
+ ring_buffer_producer();
+
+ pr_info("Sleeping for 10 secs\n");
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ * SLEEP_TIME);
+ __set_current_state(TASK_RUNNING);
+ }
+
+ if (kill_test)
+ wait_to_die();
+
+ return 0;
+}
+
+static int __init ring_buffer_benchmark_init(void)
+{
+ int ret;
+
+ /* make a one meg buffer in overwite mode */
+ buffer = ring_buffer_alloc(1000000, RB_FL_OVERWRITE);
+ if (!buffer)
+ return -ENOMEM;
+
+ if (!disable_reader) {
+ consumer = kthread_create(ring_buffer_consumer_thread,
+ NULL, "rb_consumer");
+ ret = PTR_ERR(consumer);
+ if (IS_ERR(consumer))
+ goto out_fail;
+ }
+
+ producer = kthread_run(ring_buffer_producer_thread,
+ NULL, "rb_producer");
+ ret = PTR_ERR(producer);
+
+ if (IS_ERR(producer))
+ goto out_kill;
+
+ return 0;
+
+ out_kill:
+ if (consumer)
+ kthread_stop(consumer);
+
+ out_fail:
+ ring_buffer_free(buffer);
+ return ret;
+}
+
+static void __exit ring_buffer_benchmark_exit(void)
+{
+ kthread_stop(producer);
+ if (consumer)
+ kthread_stop(consumer);
+ ring_buffer_free(buffer);
+}
+
+module_init(ring_buffer_benchmark_init);
+module_exit(ring_buffer_benchmark_exit);
+
+MODULE_AUTHOR("Steven Rostedt");
+MODULE_DESCRIPTION("ring_buffer_benchmark");
+MODULE_LICENSE("GPL");
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index a884c09006c4..dd40d2320346 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -171,6 +171,13 @@ static struct trace_array global_trace;
static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu);
+int filter_current_check_discard(struct ftrace_event_call *call, void *rec,
+ struct ring_buffer_event *event)
+{
+ return filter_check_discard(call, rec, global_trace.buffer, event);
+}
+EXPORT_SYMBOL_GPL(filter_current_check_discard);
+
cycle_t ftrace_now(int cpu)
{
u64 ts;
@@ -255,7 +262,8 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait);
/* trace_flags holds trace_options default values */
unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
- TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME;
+ TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME |
+ TRACE_ITER_GRAPH_TIME;
/**
* trace_wake_up - wake up tasks waiting for trace input
@@ -317,6 +325,7 @@ static const char *trace_options[] = {
"latency-format",
"global-clock",
"sleep-time",
+ "graph-time",
NULL
};
@@ -402,17 +411,6 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
return cnt;
}
-static void
-trace_print_seq(struct seq_file *m, struct trace_seq *s)
-{
- int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
-
- s->buffer[len] = 0;
- seq_puts(m, s->buffer);
-
- trace_seq_init(s);
-}
-
/**
* update_max_tr - snapshot all trace buffers from global_trace to max_tr
* @tr: tracer
@@ -641,6 +639,16 @@ void tracing_reset_online_cpus(struct trace_array *tr)
tracing_reset(tr, cpu);
}
+void tracing_reset_current(int cpu)
+{
+ tracing_reset(&global_trace, cpu);
+}
+
+void tracing_reset_current_online_cpus(void)
+{
+ tracing_reset_online_cpus(&global_trace);
+}
+
#define SAVED_CMDLINES 128
#define NO_CMDLINE_MAP UINT_MAX
static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
@@ -840,7 +848,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
}
struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
- unsigned char type,
+ int type,
unsigned long len,
unsigned long flags, int pc)
{
@@ -883,30 +891,40 @@ void trace_buffer_unlock_commit(struct trace_array *tr,
}
struct ring_buffer_event *
-trace_current_buffer_lock_reserve(unsigned char type, unsigned long len,
+trace_current_buffer_lock_reserve(int type, unsigned long len,
unsigned long flags, int pc)
{
return trace_buffer_lock_reserve(&global_trace,
type, len, flags, pc);
}
+EXPORT_SYMBOL_GPL(trace_current_buffer_lock_reserve);
void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
unsigned long flags, int pc)
{
- return __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 1);
+ __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 1);
}
+EXPORT_SYMBOL_GPL(trace_current_buffer_unlock_commit);
void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event,
unsigned long flags, int pc)
{
- return __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 0);
+ __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 0);
}
+EXPORT_SYMBOL_GPL(trace_nowake_buffer_unlock_commit);
+
+void trace_current_buffer_discard_commit(struct ring_buffer_event *event)
+{
+ ring_buffer_discard_commit(global_trace.buffer, event);
+}
+EXPORT_SYMBOL_GPL(trace_current_buffer_discard_commit);
void
trace_function(struct trace_array *tr,
unsigned long ip, unsigned long parent_ip, unsigned long flags,
int pc)
{
+ struct ftrace_event_call *call = &event_function;
struct ring_buffer_event *event;
struct ftrace_entry *entry;
@@ -921,7 +939,9 @@ trace_function(struct trace_array *tr,
entry = ring_buffer_event_data(event);
entry->ip = ip;
entry->parent_ip = parent_ip;
- ring_buffer_unlock_commit(tr->buffer, event);
+
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ ring_buffer_unlock_commit(tr->buffer, event);
}
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
@@ -930,6 +950,7 @@ static int __trace_graph_entry(struct trace_array *tr,
unsigned long flags,
int pc)
{
+ struct ftrace_event_call *call = &event_funcgraph_entry;
struct ring_buffer_event *event;
struct ftrace_graph_ent_entry *entry;
@@ -942,7 +963,8 @@ static int __trace_graph_entry(struct trace_array *tr,
return 0;
entry = ring_buffer_event_data(event);
entry->graph_ent = *trace;
- ring_buffer_unlock_commit(global_trace.buffer, event);
+ if (!filter_current_check_discard(call, entry, event))
+ ring_buffer_unlock_commit(global_trace.buffer, event);
return 1;
}
@@ -952,6 +974,7 @@ static void __trace_graph_return(struct trace_array *tr,
unsigned long flags,
int pc)
{
+ struct ftrace_event_call *call = &event_funcgraph_exit;
struct ring_buffer_event *event;
struct ftrace_graph_ret_entry *entry;
@@ -964,7 +987,8 @@ static void __trace_graph_return(struct trace_array *tr,
return;
entry = ring_buffer_event_data(event);
entry->ret = *trace;
- ring_buffer_unlock_commit(global_trace.buffer, event);
+ if (!filter_current_check_discard(call, entry, event))
+ ring_buffer_unlock_commit(global_trace.buffer, event);
}
#endif
@@ -982,6 +1006,7 @@ static void __ftrace_trace_stack(struct trace_array *tr,
int skip, int pc)
{
#ifdef CONFIG_STACKTRACE
+ struct ftrace_event_call *call = &event_kernel_stack;
struct ring_buffer_event *event;
struct stack_entry *entry;
struct stack_trace trace;
@@ -999,7 +1024,8 @@ static void __ftrace_trace_stack(struct trace_array *tr,
trace.entries = entry->caller;
save_stack_trace(&trace);
- ring_buffer_unlock_commit(tr->buffer, event);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ ring_buffer_unlock_commit(tr->buffer, event);
#endif
}
@@ -1024,6 +1050,7 @@ static void ftrace_trace_userstack(struct trace_array *tr,
unsigned long flags, int pc)
{
#ifdef CONFIG_STACKTRACE
+ struct ftrace_event_call *call = &event_user_stack;
struct ring_buffer_event *event;
struct userstack_entry *entry;
struct stack_trace trace;
@@ -1045,7 +1072,8 @@ static void ftrace_trace_userstack(struct trace_array *tr,
trace.entries = entry->caller;
save_stack_trace_user(&trace);
- ring_buffer_unlock_commit(tr->buffer, event);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ ring_buffer_unlock_commit(tr->buffer, event);
#endif
}
@@ -1089,6 +1117,7 @@ tracing_sched_switch_trace(struct trace_array *tr,
struct task_struct *next,
unsigned long flags, int pc)
{
+ struct ftrace_event_call *call = &event_context_switch;
struct ring_buffer_event *event;
struct ctx_switch_entry *entry;
@@ -1104,7 +1133,9 @@ tracing_sched_switch_trace(struct trace_array *tr,
entry->next_prio = next->prio;
entry->next_state = next->state;
entry->next_cpu = task_cpu(next);
- trace_buffer_unlock_commit(tr, event, flags, pc);
+
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ trace_buffer_unlock_commit(tr, event, flags, pc);
}
void
@@ -1113,6 +1144,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
struct task_struct *curr,
unsigned long flags, int pc)
{
+ struct ftrace_event_call *call = &event_wakeup;
struct ring_buffer_event *event;
struct ctx_switch_entry *entry;
@@ -1129,7 +1161,8 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
entry->next_state = wakee->state;
entry->next_cpu = task_cpu(wakee);
- ring_buffer_unlock_commit(tr->buffer, event);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ ring_buffer_unlock_commit(tr->buffer, event);
ftrace_trace_stack(tr, flags, 6, pc);
ftrace_trace_userstack(tr, flags, pc);
}
@@ -1230,11 +1263,13 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
(raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
static u32 trace_buf[TRACE_BUF_SIZE];
+ struct ftrace_event_call *call = &event_bprint;
struct ring_buffer_event *event;
struct trace_array *tr = &global_trace;
struct trace_array_cpu *data;
struct bprint_entry *entry;
unsigned long flags;
+ int disable;
int resched;
int cpu, len = 0, size, pc;
@@ -1249,7 +1284,8 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
cpu = raw_smp_processor_id();
data = tr->data[cpu];
- if (unlikely(atomic_read(&data->disabled)))
+ disable = atomic_inc_return(&data->disabled);
+ if (unlikely(disable != 1))
goto out;
/* Lockdep uses trace_printk for lock tracing */
@@ -1269,13 +1305,15 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
entry->fmt = fmt;
memcpy(entry->buf, trace_buf, sizeof(u32) * len);
- ring_buffer_unlock_commit(tr->buffer, event);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ ring_buffer_unlock_commit(tr->buffer, event);
out_unlock:
__raw_spin_unlock(&trace_buf_lock);
local_irq_restore(flags);
out:
+ atomic_dec_return(&data->disabled);
ftrace_preempt_enable(resched);
unpause_graph_tracing();
@@ -1288,12 +1326,14 @@ int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
static raw_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED;
static char trace_buf[TRACE_BUF_SIZE];
+ struct ftrace_event_call *call = &event_print;
struct ring_buffer_event *event;
struct trace_array *tr = &global_trace;
struct trace_array_cpu *data;
int cpu, len = 0, size, pc;
struct print_entry *entry;
unsigned long irq_flags;
+ int disable;
if (tracing_disabled || tracing_selftest_running)
return 0;
@@ -1303,7 +1343,8 @@ int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
cpu = raw_smp_processor_id();
data = tr->data[cpu];
- if (unlikely(atomic_read(&data->disabled)))
+ disable = atomic_inc_return(&data->disabled);
+ if (unlikely(disable != 1))
goto out;
pause_graph_tracing();
@@ -1323,13 +1364,15 @@ int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
memcpy(&entry->buf, trace_buf, len);
entry->buf[len] = 0;
- ring_buffer_unlock_commit(tr->buffer, event);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ ring_buffer_unlock_commit(tr->buffer, event);
out_unlock:
__raw_spin_unlock(&trace_buf_lock);
raw_local_irq_restore(irq_flags);
unpause_graph_tracing();
out:
+ atomic_dec_return(&data->disabled);
preempt_enable_notrace();
return len;
@@ -2397,6 +2440,56 @@ static const struct file_operations tracing_readme_fops = {
};
static ssize_t
+tracing_saved_cmdlines_read(struct file *file, char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ char *buf_comm;
+ char *file_buf;
+ char *buf;
+ int len = 0;
+ int pid;
+ int i;
+
+ file_buf = kmalloc(SAVED_CMDLINES*(16+TASK_COMM_LEN), GFP_KERNEL);
+ if (!file_buf)
+ return -ENOMEM;
+
+ buf_comm = kmalloc(TASK_COMM_LEN, GFP_KERNEL);
+ if (!buf_comm) {
+ kfree(file_buf);
+ return -ENOMEM;
+ }
+
+ buf = file_buf;
+
+ for (i = 0; i < SAVED_CMDLINES; i++) {
+ int r;
+
+ pid = map_cmdline_to_pid[i];
+ if (pid == -1 || pid == NO_CMDLINE_MAP)
+ continue;
+
+ trace_find_cmdline(pid, buf_comm);
+ r = sprintf(buf, "%d %s\n", pid, buf_comm);
+ buf += r;
+ len += r;
+ }
+
+ len = simple_read_from_buffer(ubuf, cnt, ppos,
+ file_buf, len);
+
+ kfree(file_buf);
+ kfree(buf_comm);
+
+ return len;
+}
+
+static const struct file_operations tracing_saved_cmdlines_fops = {
+ .open = tracing_open_generic,
+ .read = tracing_saved_cmdlines_read,
+};
+
+static ssize_t
tracing_ctrl_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
@@ -3425,7 +3518,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
.spd_release = buffer_spd_release,
};
struct buffer_ref *ref;
- int size, i;
+ int entries, size, i;
size_t ret;
if (*ppos & (PAGE_SIZE - 1)) {
@@ -3440,7 +3533,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
len &= PAGE_MASK;
}
- for (i = 0; i < PIPE_BUFFERS && len; i++, len -= PAGE_SIZE) {
+ entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu);
+
+ for (i = 0; i < PIPE_BUFFERS && len && entries; i++, len -= PAGE_SIZE) {
struct page *page;
int r;
@@ -3457,7 +3552,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
}
r = ring_buffer_read_page(ref->buffer, &ref->page,
- len, info->cpu, 0);
+ len, info->cpu, 1);
if (r < 0) {
ring_buffer_free_read_page(ref->buffer,
ref->page);
@@ -3481,6 +3576,8 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
spd.partial[i].private = (unsigned long)ref;
spd.nr_pages++;
*ppos += PAGE_SIZE;
+
+ entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu);
}
spd.nr_pages = i;
@@ -3508,6 +3605,45 @@ static const struct file_operations tracing_buffers_fops = {
.llseek = no_llseek,
};
+static ssize_t
+tracing_stats_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long cpu = (unsigned long)filp->private_data;
+ struct trace_array *tr = &global_trace;
+ struct trace_seq *s;
+ unsigned long cnt;
+
+ s = kmalloc(sizeof(*s), GFP_ATOMIC);
+ if (!s)
+ return ENOMEM;
+
+ trace_seq_init(s);
+
+ cnt = ring_buffer_entries_cpu(tr->buffer, cpu);
+ trace_seq_printf(s, "entries: %ld\n", cnt);
+
+ cnt = ring_buffer_overrun_cpu(tr->buffer, cpu);
+ trace_seq_printf(s, "overrun: %ld\n", cnt);
+
+ cnt = ring_buffer_commit_overrun_cpu(tr->buffer, cpu);
+ trace_seq_printf(s, "commit overrun: %ld\n", cnt);
+
+ cnt = ring_buffer_nmi_dropped_cpu(tr->buffer, cpu);
+ trace_seq_printf(s, "nmi dropped: %ld\n", cnt);
+
+ count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len);
+
+ kfree(s);
+
+ return count;
+}
+
+static const struct file_operations tracing_stats_fops = {
+ .open = tracing_open_generic,
+ .read = tracing_stats_read,
+};
+
#ifdef CONFIG_DYNAMIC_FTRACE
int __weak ftrace_arch_read_dyn_info(char *buf, int size)
@@ -3597,7 +3733,7 @@ struct dentry *tracing_dentry_percpu(void)
static void tracing_init_debugfs_percpu(long cpu)
{
struct dentry *d_percpu = tracing_dentry_percpu();
- struct dentry *entry, *d_cpu;
+ struct dentry *d_cpu;
/* strlen(cpu) + MAX(log10(cpu)) + '\0' */
char cpu_dir[7];
@@ -3612,21 +3748,18 @@ static void tracing_init_debugfs_percpu(long cpu)
}
/* per cpu trace_pipe */
- entry = debugfs_create_file("trace_pipe", 0444, d_cpu,
- (void *) cpu, &tracing_pipe_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'trace_pipe' entry\n");
+ trace_create_file("trace_pipe", 0444, d_cpu,
+ (void *) cpu, &tracing_pipe_fops);
/* per cpu trace */
- entry = debugfs_create_file("trace", 0644, d_cpu,
- (void *) cpu, &tracing_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'trace' entry\n");
+ trace_create_file("trace", 0644, d_cpu,
+ (void *) cpu, &tracing_fops);
- entry = debugfs_create_file("trace_pipe_raw", 0444, d_cpu,
- (void *) cpu, &tracing_buffers_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'trace_pipe_raw' entry\n");
+ trace_create_file("trace_pipe_raw", 0444, d_cpu,
+ (void *) cpu, &tracing_buffers_fops);
+
+ trace_create_file("stats", 0444, d_cpu,
+ (void *) cpu, &tracing_stats_fops);
}
#ifdef CONFIG_FTRACE_SELFTEST
@@ -3782,6 +3915,22 @@ static const struct file_operations trace_options_core_fops = {
.write = trace_options_core_write,
};
+struct dentry *trace_create_file(const char *name,
+ mode_t mode,
+ struct dentry *parent,
+ void *data,
+ const struct file_operations *fops)
+{
+ struct dentry *ret;
+
+ ret = debugfs_create_file(name, mode, parent, data, fops);
+ if (!ret)
+ pr_warning("Could not create debugfs '%s' entry\n", name);
+
+ return ret;
+}
+
+
static struct dentry *trace_options_init_dentry(void)
{
struct dentry *d_tracer;
@@ -3809,7 +3958,6 @@ create_trace_option_file(struct trace_option_dentry *topt,
struct tracer_opt *opt)
{
struct dentry *t_options;
- struct dentry *entry;
t_options = trace_options_init_dentry();
if (!t_options)
@@ -3818,11 +3966,9 @@ create_trace_option_file(struct trace_option_dentry *topt,
topt->flags = flags;
topt->opt = opt;
- entry = debugfs_create_file(opt->name, 0644, t_options, topt,
+ topt->entry = trace_create_file(opt->name, 0644, t_options, topt,
&trace_options_fops);
- topt->entry = entry;
-
}
static struct trace_option_dentry *
@@ -3877,123 +4023,84 @@ static struct dentry *
create_trace_option_core_file(const char *option, long index)
{
struct dentry *t_options;
- struct dentry *entry;
t_options = trace_options_init_dentry();
if (!t_options)
return NULL;
- entry = debugfs_create_file(option, 0644, t_options, (void *)index,
+ return trace_create_file(option, 0644, t_options, (void *)index,
&trace_options_core_fops);
-
- return entry;
}
static __init void create_trace_options_dir(void)
{
struct dentry *t_options;
- struct dentry *entry;
int i;
t_options = trace_options_init_dentry();
if (!t_options)
return;
- for (i = 0; trace_options[i]; i++) {
- entry = create_trace_option_core_file(trace_options[i], i);
- if (!entry)
- pr_warning("Could not create debugfs %s entry\n",
- trace_options[i]);
- }
+ for (i = 0; trace_options[i]; i++)
+ create_trace_option_core_file(trace_options[i], i);
}
static __init int tracer_init_debugfs(void)
{
struct dentry *d_tracer;
- struct dentry *entry;
int cpu;
d_tracer = tracing_init_dentry();
- entry = debugfs_create_file("tracing_enabled", 0644, d_tracer,
- &global_trace, &tracing_ctrl_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'tracing_enabled' entry\n");
+ trace_create_file("tracing_enabled", 0644, d_tracer,
+ &global_trace, &tracing_ctrl_fops);
- entry = debugfs_create_file("trace_options", 0644, d_tracer,
- NULL, &tracing_iter_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'trace_options' entry\n");
+ trace_create_file("trace_options", 0644, d_tracer,
+ NULL, &tracing_iter_fops);
- create_trace_options_dir();
+ trace_create_file("tracing_cpumask", 0644, d_tracer,
+ NULL, &tracing_cpumask_fops);
+
+ trace_create_file("trace", 0644, d_tracer,
+ (void *) TRACE_PIPE_ALL_CPU, &tracing_fops);
+
+ trace_create_file("available_tracers", 0444, d_tracer,
+ &global_trace, &show_traces_fops);
- entry = debugfs_create_file("tracing_cpumask", 0644, d_tracer,
- NULL, &tracing_cpumask_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'tracing_cpumask' entry\n");
-
- entry = debugfs_create_file("trace", 0644, d_tracer,
- (void *) TRACE_PIPE_ALL_CPU, &tracing_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'trace' entry\n");
-
- entry = debugfs_create_file("available_tracers", 0444, d_tracer,
- &global_trace, &show_traces_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'available_tracers' entry\n");
-
- entry = debugfs_create_file("current_tracer", 0444, d_tracer,
- &global_trace, &set_tracer_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'current_tracer' entry\n");
-
- entry = debugfs_create_file("tracing_max_latency", 0644, d_tracer,
- &tracing_max_latency,
- &tracing_max_lat_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'tracing_max_latency' entry\n");
-
- entry = debugfs_create_file("tracing_thresh", 0644, d_tracer,
- &tracing_thresh, &tracing_max_lat_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'tracing_thresh' entry\n");
- entry = debugfs_create_file("README", 0644, d_tracer,
- NULL, &tracing_readme_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'README' entry\n");
-
- entry = debugfs_create_file("trace_pipe", 0444, d_tracer,
+ trace_create_file("current_tracer", 0644, d_tracer,
+ &global_trace, &set_tracer_fops);
+
+ trace_create_file("tracing_max_latency", 0644, d_tracer,
+ &tracing_max_latency, &tracing_max_lat_fops);
+
+ trace_create_file("tracing_thresh", 0644, d_tracer,
+ &tracing_thresh, &tracing_max_lat_fops);
+
+ trace_create_file("README", 0444, d_tracer,
+ NULL, &tracing_readme_fops);
+
+ trace_create_file("trace_pipe", 0444, d_tracer,
(void *) TRACE_PIPE_ALL_CPU, &tracing_pipe_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'trace_pipe' entry\n");
-
- entry = debugfs_create_file("buffer_size_kb", 0644, d_tracer,
- &global_trace, &tracing_entries_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'buffer_size_kb' entry\n");
-
- entry = debugfs_create_file("trace_marker", 0220, d_tracer,
- NULL, &tracing_mark_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'trace_marker' entry\n");
+
+ trace_create_file("buffer_size_kb", 0644, d_tracer,
+ &global_trace, &tracing_entries_fops);
+
+ trace_create_file("trace_marker", 0220, d_tracer,
+ NULL, &tracing_mark_fops);
+
+ trace_create_file("saved_cmdlines", 0444, d_tracer,
+ NULL, &tracing_saved_cmdlines_fops);
#ifdef CONFIG_DYNAMIC_FTRACE
- entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer,
- &ftrace_update_tot_cnt,
- &tracing_dyn_info_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'dyn_ftrace_total_info' entry\n");
+ trace_create_file("dyn_ftrace_total_info", 0444, d_tracer,
+ &ftrace_update_tot_cnt, &tracing_dyn_info_fops);
#endif
#ifdef CONFIG_SYSPROF_TRACER
init_tracer_sysprof_debugfs(d_tracer);
#endif
+ create_trace_options_dir();
+
for_each_tracing_cpu(cpu)
tracing_init_debugfs_percpu(cpu);
@@ -4064,7 +4171,8 @@ trace_printk_seq(struct trace_seq *s)
static void __ftrace_dump(bool disable_tracing)
{
- static DEFINE_SPINLOCK(ftrace_dump_lock);
+ static raw_spinlock_t ftrace_dump_lock =
+ (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
/* use static because iter can be a bit big for the stack */
static struct trace_iterator iter;
unsigned int old_userobj;
@@ -4073,7 +4181,8 @@ static void __ftrace_dump(bool disable_tracing)
int cnt = 0, cpu;
/* only one dump */
- spin_lock_irqsave(&ftrace_dump_lock, flags);
+ local_irq_save(flags);
+ __raw_spin_lock(&ftrace_dump_lock);
if (dump_ran)
goto out;
@@ -4145,7 +4254,8 @@ static void __ftrace_dump(bool disable_tracing)
}
out:
- spin_unlock_irqrestore(&ftrace_dump_lock, flags);
+ __raw_spin_unlock(&ftrace_dump_lock);
+ local_irq_restore(flags);
}
/* By default: disable tracing after the dump */
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index e685ac2b2ba1..6e735d4771f8 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -9,9 +9,12 @@
#include <linux/mmiotrace.h>
#include <linux/ftrace.h>
#include <trace/boot.h>
-#include <trace/kmemtrace.h>
+#include <linux/kmemtrace.h>
#include <trace/power.h>
+#include <linux/trace_seq.h>
+#include <linux/ftrace_event.h>
+
enum trace_type {
__TRACE_FIRST_TYPE = 0,
@@ -42,20 +45,6 @@ enum trace_type {
};
/*
- * The trace entry - the most basic unit of tracing. This is what
- * is printed in the end as a single line in the trace output, such as:
- *
- * bash-15816 [01] 235.197585: idle_cpu <- irq_enter
- */
-struct trace_entry {
- unsigned char type;
- unsigned char flags;
- unsigned char preempt_count;
- int pid;
- int tgid;
-};
-
-/*
* Function trace entry - function address and parent function addres:
*/
struct ftrace_entry {
@@ -263,8 +252,6 @@ struct trace_array_cpu {
char comm[TASK_COMM_LEN];
};
-struct trace_iterator;
-
/*
* The trace array - an array of per-CPU trace arrays. This is the
* highest level data structure that individual tracers deal with.
@@ -339,15 +326,6 @@ extern void __ftrace_bad_type(void);
__ftrace_bad_type(); \
} while (0)
-/* Return values for print_line callback */
-enum print_line_t {
- TRACE_TYPE_PARTIAL_LINE = 0, /* Retry after flushing the seq */
- TRACE_TYPE_HANDLED = 1,
- TRACE_TYPE_UNHANDLED = 2, /* Relay to other output functions */
- TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */
-};
-
-
/*
* An option specific to a tracer. This is a boolean value.
* The bit is the bit index that sets its value on the
@@ -423,60 +401,30 @@ struct tracer {
struct tracer_stat *stats;
};
-struct trace_seq {
- unsigned char buffer[PAGE_SIZE];
- unsigned int len;
- unsigned int readpos;
-};
-
-static inline void
-trace_seq_init(struct trace_seq *s)
-{
- s->len = 0;
- s->readpos = 0;
-}
-
#define TRACE_PIPE_ALL_CPU -1
-/*
- * Trace iterator - used by printout routines who present trace
- * results to users and which routines might sleep, etc:
- */
-struct trace_iterator {
- struct trace_array *tr;
- struct tracer *trace;
- void *private;
- int cpu_file;
- struct mutex mutex;
- struct ring_buffer_iter *buffer_iter[NR_CPUS];
-
- /* The below is zeroed out in pipe_read */
- struct trace_seq seq;
- struct trace_entry *ent;
- int cpu;
- u64 ts;
-
- unsigned long iter_flags;
- loff_t pos;
- long idx;
-
- cpumask_var_t started;
-};
-
int tracer_init(struct tracer *t, struct trace_array *tr);
int tracing_is_enabled(void);
void trace_wake_up(void);
void tracing_reset(struct trace_array *tr, int cpu);
void tracing_reset_online_cpus(struct trace_array *tr);
+void tracing_reset_current(int cpu);
+void tracing_reset_current_online_cpus(void);
int tracing_open_generic(struct inode *inode, struct file *filp);
+struct dentry *trace_create_file(const char *name,
+ mode_t mode,
+ struct dentry *parent,
+ void *data,
+ const struct file_operations *fops);
+
struct dentry *tracing_init_dentry(void);
void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
struct ring_buffer_event;
struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
- unsigned char type,
+ int type,
unsigned long len,
unsigned long flags,
int pc);
@@ -484,14 +432,6 @@ void trace_buffer_unlock_commit(struct trace_array *tr,
struct ring_buffer_event *event,
unsigned long flags, int pc);
-struct ring_buffer_event *
-trace_current_buffer_lock_reserve(unsigned char type, unsigned long len,
- unsigned long flags, int pc);
-void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
- unsigned long flags, int pc);
-void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event,
- unsigned long flags, int pc);
-
struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
struct trace_array_cpu *data);
@@ -514,7 +454,6 @@ void tracing_sched_switch_trace(struct trace_array *tr,
struct task_struct *prev,
struct task_struct *next,
unsigned long flags, int pc);
-void tracing_record_cmdline(struct task_struct *tsk);
void tracing_sched_wakeup_trace(struct trace_array *tr,
struct task_struct *wakee,
@@ -599,6 +538,8 @@ extern int trace_selftest_startup_sysprof(struct tracer *trace,
struct trace_array *tr);
extern int trace_selftest_startup_branch(struct tracer *trace,
struct trace_array *tr);
+extern int trace_selftest_startup_hw_branches(struct tracer *trace,
+ struct trace_array *tr);
#endif /* CONFIG_FTRACE_STARTUP_TEST */
extern void *head_page(struct trace_array_cpu *data);
@@ -613,6 +554,8 @@ extern unsigned long trace_flags;
/* Standard output formatting function used for function return traces */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
extern enum print_line_t print_graph_function(struct trace_iterator *iter);
+extern enum print_line_t
+trace_print_graph_duration(unsigned long long duration, struct trace_seq *s);
#ifdef CONFIG_DYNAMIC_FTRACE
/* TODO: make this variable */
@@ -644,7 +587,6 @@ static inline int ftrace_graph_addr(unsigned long addr)
return 1;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
-
#else /* CONFIG_FUNCTION_GRAPH_TRACER */
static inline enum print_line_t
print_graph_function(struct trace_iterator *iter)
@@ -692,6 +634,7 @@ enum trace_iterator_flags {
TRACE_ITER_LATENCY_FMT = 0x40000,
TRACE_ITER_GLOBAL_CLK = 0x80000,
TRACE_ITER_SLEEP_TIME = 0x100000,
+ TRACE_ITER_GRAPH_TIME = 0x200000,
};
/*
@@ -790,103 +733,113 @@ struct ftrace_event_field {
char *type;
int offset;
int size;
+ int is_signed;
};
-struct ftrace_event_call {
- char *name;
- char *system;
- struct dentry *dir;
- int enabled;
- int (*regfunc)(void);
- void (*unregfunc)(void);
- int id;
- int (*raw_init)(void);
- int (*show_format)(struct trace_seq *s);
- int (*define_fields)(void);
- struct list_head fields;
+struct event_filter {
+ int n_preds;
struct filter_pred **preds;
-
-#ifdef CONFIG_EVENT_PROFILE
- atomic_t profile_count;
- int (*profile_enable)(struct ftrace_event_call *);
- void (*profile_disable)(struct ftrace_event_call *);
-#endif
+ char *filter_string;
};
struct event_subsystem {
struct list_head list;
const char *name;
struct dentry *entry;
- struct filter_pred **preds;
+ void *filter;
};
-#define events_for_each(event) \
- for (event = __start_ftrace_events; \
- (unsigned long)event < (unsigned long)__stop_ftrace_events; \
- event++)
-
-#define MAX_FILTER_PRED 8
-
struct filter_pred;
-typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event);
+typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event,
+ int val1, int val2);
struct filter_pred {
filter_pred_fn_t fn;
u64 val;
- char *str_val;
+ char str_val[MAX_FILTER_STR_VAL];
int str_len;
char *field_name;
int offset;
int not;
- int or;
- int compound;
- int clear;
+ int op;
+ int pop_n;
};
-int trace_define_field(struct ftrace_event_call *call, char *type,
- char *name, int offset, int size);
-extern void filter_free_pred(struct filter_pred *pred);
-extern void filter_print_preds(struct filter_pred **preds,
+extern void print_event_filter(struct ftrace_event_call *call,
struct trace_seq *s);
-extern int filter_parse(char **pbuf, struct filter_pred *pred);
-extern int filter_add_pred(struct ftrace_event_call *call,
- struct filter_pred *pred);
-extern void filter_free_preds(struct ftrace_event_call *call);
-extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
-extern void filter_free_subsystem_preds(struct event_subsystem *system);
-extern int filter_add_subsystem_pred(struct event_subsystem *system,
- struct filter_pred *pred);
-
-void event_trace_printk(unsigned long ip, const char *fmt, ...);
-extern struct ftrace_event_call __start_ftrace_events[];
-extern struct ftrace_event_call __stop_ftrace_events[];
-
-#define for_each_event(event) \
- for (event = __start_ftrace_events; \
- (unsigned long)event < (unsigned long)__stop_ftrace_events; \
- event++)
+extern int apply_event_filter(struct ftrace_event_call *call,
+ char *filter_string);
+extern int apply_subsystem_event_filter(struct event_subsystem *system,
+ char *filter_string);
+extern void print_subsystem_event_filter(struct event_subsystem *system,
+ struct trace_seq *s);
+
+static inline int
+filter_check_discard(struct ftrace_event_call *call, void *rec,
+ struct ring_buffer *buffer,
+ struct ring_buffer_event *event)
+{
+ if (unlikely(call->filter_active) && !filter_match_preds(call, rec)) {
+ ring_buffer_discard_commit(buffer, event);
+ return 1;
+ }
+
+ return 0;
+}
+
+#define DEFINE_COMPARISON_PRED(type) \
+static int filter_pred_##type(struct filter_pred *pred, void *event, \
+ int val1, int val2) \
+{ \
+ type *addr = (type *)(event + pred->offset); \
+ type val = (type)pred->val; \
+ int match = 0; \
+ \
+ switch (pred->op) { \
+ case OP_LT: \
+ match = (*addr < val); \
+ break; \
+ case OP_LE: \
+ match = (*addr <= val); \
+ break; \
+ case OP_GT: \
+ match = (*addr > val); \
+ break; \
+ case OP_GE: \
+ match = (*addr >= val); \
+ break; \
+ default: \
+ break; \
+ } \
+ \
+ return match; \
+}
+
+#define DEFINE_EQUALITY_PRED(size) \
+static int filter_pred_##size(struct filter_pred *pred, void *event, \
+ int val1, int val2) \
+{ \
+ u##size *addr = (u##size *)(event + pred->offset); \
+ u##size val = (u##size)pred->val; \
+ int match; \
+ \
+ match = (val == *addr) ^ pred->not; \
+ \
+ return match; \
+}
+
+extern struct mutex event_mutex;
+extern struct list_head ftrace_events;
extern const char *__start___trace_bprintk_fmt[];
extern const char *__stop___trace_bprintk_fmt[];
-/*
- * The double __builtin_constant_p is because gcc will give us an error
- * if we try to allocate the static variable to fmt if it is not a
- * constant. Even with the outer if statement optimizing out.
- */
-#define event_trace_printk(ip, fmt, args...) \
-do { \
- __trace_printk_check_format(fmt, ##args); \
- tracing_record_cmdline(current); \
- if (__builtin_constant_p(fmt)) { \
- static const char *trace_printk_fmt \
- __attribute__((section("__trace_printk_fmt"))) = \
- __builtin_constant_p(fmt) ? fmt : NULL; \
- \
- __trace_bprintk(ip, trace_printk_fmt, ##args); \
- } else \
- __trace_printk(ip, fmt, ##args); \
-} while (0)
+#undef TRACE_EVENT_FORMAT
+#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \
+ extern struct ftrace_event_call event_##call;
+#undef TRACE_EVENT_FORMAT_NOFILTER
+#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, tpfmt)
+#include "trace_event_types.h"
#endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
index 7a30fc4c3642..a29ef23ffb47 100644
--- a/kernel/trace/trace_boot.c
+++ b/kernel/trace/trace_boot.c
@@ -9,6 +9,7 @@
#include <linux/debugfs.h>
#include <linux/ftrace.h>
#include <linux/kallsyms.h>
+#include <linux/time.h>
#include "trace.h"
#include "trace_output.h"
@@ -67,7 +68,7 @@ initcall_call_print_line(struct trace_iterator *iter)
trace_assign_type(field, entry);
call = &field->boot_call;
ts = iter->ts;
- nsec_rem = do_div(ts, 1000000000);
+ nsec_rem = do_div(ts, NSEC_PER_SEC);
ret = trace_seq_printf(s, "[%5ld.%09ld] calling %s @ %i\n",
(unsigned long)ts, nsec_rem, call->func, call->caller);
@@ -92,7 +93,7 @@ initcall_ret_print_line(struct trace_iterator *iter)
trace_assign_type(field, entry);
init_ret = &field->boot_ret;
ts = iter->ts;
- nsec_rem = do_div(ts, 1000000000);
+ nsec_rem = do_div(ts, NSEC_PER_SEC);
ret = trace_seq_printf(s, "[%5ld.%09ld] initcall %s "
"returned %d after %llu msecs\n",
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
index 8333715e4066..7a7a9fd249a9 100644
--- a/kernel/trace/trace_branch.c
+++ b/kernel/trace/trace_branch.c
@@ -30,6 +30,7 @@ static struct trace_array *branch_tracer;
static void
probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
{
+ struct ftrace_event_call *call = &event_branch;
struct trace_array *tr = branch_tracer;
struct ring_buffer_event *event;
struct trace_branch *entry;
@@ -73,7 +74,8 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
entry->line = f->line;
entry->correct = val == expect;
- ring_buffer_unlock_commit(tr->buffer, event);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ ring_buffer_unlock_commit(tr->buffer, event);
out:
atomic_dec(&tr->data[cpu]->disabled);
@@ -271,7 +273,7 @@ static int branch_stat_show(struct seq_file *m, void *v)
return 0;
}
-static void *annotated_branch_stat_start(void)
+static void *annotated_branch_stat_start(struct tracer_stat *trace)
{
return __start_annotated_branch_profile;
}
@@ -346,7 +348,7 @@ static int all_branch_stat_headers(struct seq_file *m)
return 0;
}
-static void *all_branch_stat_start(void)
+static void *all_branch_stat_start(struct tracer_stat *trace)
{
return __start_branch_profile;
}
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c
index 22cba9970776..5b5895afecfe 100644
--- a/kernel/trace/trace_event_profile.c
+++ b/kernel/trace/trace_event_profile.c
@@ -10,22 +10,30 @@
int ftrace_profile_enable(int event_id)
{
struct ftrace_event_call *event;
+ int ret = -EINVAL;
- for_each_event(event) {
- if (event->id == event_id)
- return event->profile_enable(event);
+ mutex_lock(&event_mutex);
+ list_for_each_entry(event, &ftrace_events, list) {
+ if (event->id == event_id) {
+ ret = event->profile_enable(event);
+ break;
+ }
}
+ mutex_unlock(&event_mutex);
- return -EINVAL;
+ return ret;
}
void ftrace_profile_disable(int event_id)
{
struct ftrace_event_call *event;
- for_each_event(event) {
- if (event->id == event_id)
- return event->profile_disable(event);
+ mutex_lock(&event_mutex);
+ list_for_each_entry(event, &ftrace_events, list) {
+ if (event->id == event_id) {
+ event->profile_disable(event);
+ break;
+ }
}
+ mutex_unlock(&event_mutex);
}
-
diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h
index fd78bee71dd7..5e32e375134d 100644
--- a/kernel/trace/trace_event_types.h
+++ b/kernel/trace/trace_event_types.h
@@ -57,7 +57,7 @@ TRACE_EVENT_FORMAT(context_switch, TRACE_CTX, ctx_switch_entry, ignore,
TP_RAW_FMT("%u:%u:%u ==+ %u:%u:%u [%03u]")
);
-TRACE_EVENT_FORMAT(special, TRACE_SPECIAL, special_entry, ignore,
+TRACE_EVENT_FORMAT_NOFILTER(special, TRACE_SPECIAL, special_entry, ignore,
TRACE_STRUCT(
TRACE_FIELD(unsigned long, arg1, arg1)
TRACE_FIELD(unsigned long, arg2, arg2)
@@ -122,8 +122,10 @@ TRACE_EVENT_FORMAT(print, TRACE_PRINT, print_entry, ignore,
TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore,
TRACE_STRUCT(
TRACE_FIELD(unsigned int, line, line)
- TRACE_FIELD_SPECIAL(char func[TRACE_FUNC_SIZE+1], func, func)
- TRACE_FIELD_SPECIAL(char file[TRACE_FUNC_SIZE+1], file, file)
+ TRACE_FIELD_SPECIAL(char func[TRACE_FUNC_SIZE+1], func,
+ TRACE_FUNC_SIZE+1, func)
+ TRACE_FIELD_SPECIAL(char file[TRACE_FUNC_SIZE+1], file,
+ TRACE_FUNC_SIZE+1, file)
TRACE_FIELD(char, correct, correct)
),
TP_RAW_FMT("%u:%s:%s (%u)")
@@ -139,8 +141,8 @@ TRACE_EVENT_FORMAT(hw_branch, TRACE_HW_BRANCHES, hw_branch_entry, ignore,
TRACE_EVENT_FORMAT(power, TRACE_POWER, trace_power, ignore,
TRACE_STRUCT(
- TRACE_FIELD(ktime_t, state_data.stamp, stamp)
- TRACE_FIELD(ktime_t, state_data.end, end)
+ TRACE_FIELD_SIGN(ktime_t, state_data.stamp, stamp, 1)
+ TRACE_FIELD_SIGN(ktime_t, state_data.end, end, 1)
TRACE_FIELD(int, state_data.type, type)
TRACE_FIELD(int, state_data.state, state)
),
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 576f4fa2af0d..0eec0c55dd87 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -8,19 +8,25 @@
*
*/
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include <linux/kthread.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/ctype.h>
+#include <linux/delay.h>
#include "trace_output.h"
#define TRACE_SYSTEM "TRACE_SYSTEM"
-static DEFINE_MUTEX(event_mutex);
+DEFINE_MUTEX(event_mutex);
+
+LIST_HEAD(ftrace_events);
int trace_define_field(struct ftrace_event_call *call, char *type,
- char *name, int offset, int size)
+ char *name, int offset, int size, int is_signed)
{
struct ftrace_event_field *field;
@@ -38,6 +44,7 @@ int trace_define_field(struct ftrace_event_call *call, char *type,
field->offset = offset;
field->size = size;
+ field->is_signed = is_signed;
list_add(&field->link, &call->fields);
return 0;
@@ -51,20 +58,37 @@ err:
return -ENOMEM;
}
+EXPORT_SYMBOL_GPL(trace_define_field);
-static void ftrace_clear_events(void)
+#ifdef CONFIG_MODULES
+
+static void trace_destroy_fields(struct ftrace_event_call *call)
{
- struct ftrace_event_call *call = (void *)__start_ftrace_events;
+ struct ftrace_event_field *field, *next;
+
+ list_for_each_entry_safe(field, next, &call->fields, link) {
+ list_del(&field->link);
+ kfree(field->type);
+ kfree(field->name);
+ kfree(field);
+ }
+}
+
+#endif /* CONFIG_MODULES */
+static void ftrace_clear_events(void)
+{
+ struct ftrace_event_call *call;
- while ((unsigned long)call < (unsigned long)__stop_ftrace_events) {
+ mutex_lock(&event_mutex);
+ list_for_each_entry(call, &ftrace_events, list) {
if (call->enabled) {
call->enabled = 0;
call->unregfunc();
}
- call++;
}
+ mutex_unlock(&event_mutex);
}
static void ftrace_event_enable_disable(struct ftrace_event_call *call,
@@ -87,11 +111,44 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call,
}
}
+/*
+ * __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events.
+ */
+static int __ftrace_set_clr_event(const char *match, const char *sub,
+ const char *event, int set)
+{
+ struct ftrace_event_call *call;
+ int ret = -EINVAL;
+
+ mutex_lock(&event_mutex);
+ list_for_each_entry(call, &ftrace_events, list) {
+
+ if (!call->name || !call->regfunc)
+ continue;
+
+ if (match &&
+ strcmp(match, call->name) != 0 &&
+ strcmp(match, call->system) != 0)
+ continue;
+
+ if (sub && strcmp(sub, call->system) != 0)
+ continue;
+
+ if (event && strcmp(event, call->name) != 0)
+ continue;
+
+ ftrace_event_enable_disable(call, set);
+
+ ret = 0;
+ }
+ mutex_unlock(&event_mutex);
+
+ return ret;
+}
+
static int ftrace_set_clr_event(char *buf, int set)
{
- struct ftrace_event_call *call = __start_ftrace_events;
char *event = NULL, *sub = NULL, *match;
- int ret = -EINVAL;
/*
* The buf format can be <subsystem>:<event-name>
@@ -117,30 +174,24 @@ static int ftrace_set_clr_event(char *buf, int set)
event = NULL;
}
- mutex_lock(&event_mutex);
- for_each_event(call) {
-
- if (!call->name || !call->regfunc)
- continue;
-
- if (match &&
- strcmp(match, call->name) != 0 &&
- strcmp(match, call->system) != 0)
- continue;
-
- if (sub && strcmp(sub, call->system) != 0)
- continue;
-
- if (event && strcmp(event, call->name) != 0)
- continue;
-
- ftrace_event_enable_disable(call, set);
-
- ret = 0;
- }
- mutex_unlock(&event_mutex);
+ return __ftrace_set_clr_event(match, sub, event, set);
+}
- return ret;
+/**
+ * trace_set_clr_event - enable or disable an event
+ * @system: system name to match (NULL for any system)
+ * @event: event name to match (NULL for all events, within system)
+ * @set: 1 to enable, 0 to disable
+ *
+ * This is a way for other parts of the kernel to enable or disable
+ * event recording.
+ *
+ * Returns 0 on success, -EINVAL if the parameters do not match any
+ * registered events.
+ */
+int trace_set_clr_event(const char *system, const char *event, int set)
+{
+ return __ftrace_set_clr_event(NULL, system, event, set);
}
/* 128 should be much more than enough */
@@ -224,15 +275,17 @@ ftrace_event_write(struct file *file, const char __user *ubuf,
static void *
t_next(struct seq_file *m, void *v, loff_t *pos)
{
- struct ftrace_event_call *call = m->private;
- struct ftrace_event_call *next = call;
+ struct list_head *list = m->private;
+ struct ftrace_event_call *call;
(*pos)++;
for (;;) {
- if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
+ if (list == &ftrace_events)
return NULL;
+ call = list_entry(list, struct ftrace_event_call, list);
+
/*
* The ftrace subsystem is for showing formats only.
* They can not be enabled or disabled via the event files.
@@ -240,45 +293,51 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
if (call->regfunc)
break;
- call++;
- next = call;
+ list = list->next;
}
- m->private = ++next;
+ m->private = list->next;
return call;
}
static void *t_start(struct seq_file *m, loff_t *pos)
{
+ mutex_lock(&event_mutex);
+ if (*pos == 0)
+ m->private = ftrace_events.next;
return t_next(m, NULL, pos);
}
static void *
s_next(struct seq_file *m, void *v, loff_t *pos)
{
- struct ftrace_event_call *call = m->private;
- struct ftrace_event_call *next;
+ struct list_head *list = m->private;
+ struct ftrace_event_call *call;
(*pos)++;
retry:
- if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
+ if (list == &ftrace_events)
return NULL;
+ call = list_entry(list, struct ftrace_event_call, list);
+
if (!call->enabled) {
- call++;
+ list = list->next;
goto retry;
}
- next = call;
- m->private = ++next;
+ m->private = list->next;
return call;
}
static void *s_start(struct seq_file *m, loff_t *pos)
{
+ mutex_lock(&event_mutex);
+ if (*pos == 0)
+ m->private = ftrace_events.next;
return s_next(m, NULL, pos);
}
@@ -295,12 +354,12 @@ static int t_show(struct seq_file *m, void *v)
static void t_stop(struct seq_file *m, void *p)
{
+ mutex_unlock(&event_mutex);
}
static int
ftrace_event_seq_open(struct inode *inode, struct file *file)
{
- int ret;
const struct seq_operations *seq_ops;
if ((file->f_mode & FMODE_WRITE) &&
@@ -308,13 +367,7 @@ ftrace_event_seq_open(struct inode *inode, struct file *file)
ftrace_clear_events();
seq_ops = inode->i_private;
- ret = seq_open(file, seq_ops);
- if (!ret) {
- struct seq_file *m = file->private_data;
-
- m->private = __start_ftrace_events;
- }
- return ret;
+ return seq_open(file, seq_ops);
}
static ssize_t
@@ -374,8 +427,93 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
return cnt;
}
+static ssize_t
+system_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ const char set_to_char[4] = { '?', '0', '1', 'X' };
+ const char *system = filp->private_data;
+ struct ftrace_event_call *call;
+ char buf[2];
+ int set = 0;
+ int ret;
+
+ mutex_lock(&event_mutex);
+ list_for_each_entry(call, &ftrace_events, list) {
+ if (!call->name || !call->regfunc)
+ continue;
+
+ if (system && strcmp(call->system, system) != 0)
+ continue;
+
+ /*
+ * We need to find out if all the events are set
+ * or if all events or cleared, or if we have
+ * a mixture.
+ */
+ set |= (1 << !!call->enabled);
+
+ /*
+ * If we have a mixture, no need to look further.
+ */
+ if (set == 3)
+ break;
+ }
+ mutex_unlock(&event_mutex);
+
+ buf[0] = set_to_char[set];
+ buf[1] = '\n';
+
+ ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
+
+ return ret;
+}
+
+static ssize_t
+system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ const char *system = filp->private_data;
+ unsigned long val;
+ char buf[64];
+ ssize_t ret;
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+
+ buf[cnt] = 0;
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ ret = tracing_update_buffers();
+ if (ret < 0)
+ return ret;
+
+ if (val != 0 && val != 1)
+ return -EINVAL;
+
+ ret = __ftrace_set_clr_event(NULL, system, NULL, val);
+ if (ret)
+ goto out;
+
+ ret = cnt;
+
+out:
+ *ppos += cnt;
+
+ return ret;
+}
+
+extern char *__bad_type_size(void);
+
#undef FIELD
#define FIELD(type, name) \
+ sizeof(type) != sizeof(field.name) ? __bad_type_size() : \
#type, "common_" #name, offsetof(typeof(field), name), \
sizeof(field.name)
@@ -391,7 +529,7 @@ static int trace_write_header(struct trace_seq *s)
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
"\n",
- FIELD(unsigned char, type),
+ FIELD(unsigned short, type),
FIELD(unsigned char, flags),
FIELD(unsigned char, preempt_count),
FIELD(int, pid),
@@ -481,7 +619,7 @@ event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
trace_seq_init(s);
- filter_print_preds(call->preds, s);
+ print_event_filter(call, s);
r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
kfree(s);
@@ -494,38 +632,26 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
loff_t *ppos)
{
struct ftrace_event_call *call = filp->private_data;
- char buf[64], *pbuf = buf;
- struct filter_pred *pred;
+ char *buf;
int err;
- if (cnt >= sizeof(buf))
+ if (cnt >= PAGE_SIZE)
return -EINVAL;
- if (copy_from_user(&buf, ubuf, cnt))
- return -EFAULT;
- buf[cnt] = '\0';
-
- pred = kzalloc(sizeof(*pred), GFP_KERNEL);
- if (!pred)
+ buf = (char *)__get_free_page(GFP_TEMPORARY);
+ if (!buf)
return -ENOMEM;
- err = filter_parse(&pbuf, pred);
- if (err < 0) {
- filter_free_pred(pred);
- return err;
- }
-
- if (pred->clear) {
- filter_free_preds(call);
- filter_free_pred(pred);
- return cnt;
+ if (copy_from_user(buf, ubuf, cnt)) {
+ free_page((unsigned long) buf);
+ return -EFAULT;
}
+ buf[cnt] = '\0';
- err = filter_add_pred(call, pred);
- if (err < 0) {
- filter_free_pred(pred);
+ err = apply_event_filter(call, buf);
+ free_page((unsigned long) buf);
+ if (err < 0)
return err;
- }
*ppos += cnt;
@@ -549,7 +675,7 @@ subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
trace_seq_init(s);
- filter_print_preds(system->preds, s);
+ print_subsystem_event_filter(system, s);
r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
kfree(s);
@@ -562,45 +688,56 @@ subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
loff_t *ppos)
{
struct event_subsystem *system = filp->private_data;
- char buf[64], *pbuf = buf;
- struct filter_pred *pred;
+ char *buf;
int err;
- if (cnt >= sizeof(buf))
+ if (cnt >= PAGE_SIZE)
return -EINVAL;
- if (copy_from_user(&buf, ubuf, cnt))
- return -EFAULT;
- buf[cnt] = '\0';
-
- pred = kzalloc(sizeof(*pred), GFP_KERNEL);
- if (!pred)
+ buf = (char *)__get_free_page(GFP_TEMPORARY);
+ if (!buf)
return -ENOMEM;
- err = filter_parse(&pbuf, pred);
- if (err < 0) {
- filter_free_pred(pred);
- return err;
- }
-
- if (pred->clear) {
- filter_free_subsystem_preds(system);
- filter_free_pred(pred);
- return cnt;
+ if (copy_from_user(buf, ubuf, cnt)) {
+ free_page((unsigned long) buf);
+ return -EFAULT;
}
+ buf[cnt] = '\0';
- err = filter_add_subsystem_pred(system, pred);
- if (err < 0) {
- filter_free_subsystem_preds(system);
- filter_free_pred(pred);
+ err = apply_subsystem_event_filter(system, buf);
+ free_page((unsigned long) buf);
+ if (err < 0)
return err;
- }
*ppos += cnt;
return cnt;
}
+static ssize_t
+show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ int (*func)(struct trace_seq *s) = filp->private_data;
+ struct trace_seq *s;
+ int r;
+
+ if (*ppos)
+ return 0;
+
+ s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ trace_seq_init(s);
+
+ func(s);
+ r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
+
+ kfree(s);
+
+ return r;
+}
+
static const struct seq_operations show_event_seq_ops = {
.start = t_start,
.next = t_next,
@@ -658,6 +795,17 @@ static const struct file_operations ftrace_subsystem_filter_fops = {
.write = subsystem_filter_write,
};
+static const struct file_operations ftrace_system_enable_fops = {
+ .open = tracing_open_generic,
+ .read = system_enable_read,
+ .write = system_enable_write,
+};
+
+static const struct file_operations ftrace_show_header_fops = {
+ .open = tracing_open_generic,
+ .read = show_header,
+};
+
static struct dentry *event_trace_events_dir(void)
{
static struct dentry *d_tracer;
@@ -684,6 +832,7 @@ static struct dentry *
event_subsystem_dir(const char *name, struct dentry *d_events)
{
struct event_subsystem *system;
+ struct dentry *entry;
/* First see if we did not already create this dir */
list_for_each_entry(system, &event_subsystems, list) {
@@ -707,16 +856,46 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
return d_events;
}
- system->name = name;
+ system->name = kstrdup(name, GFP_KERNEL);
+ if (!system->name) {
+ debugfs_remove(system->entry);
+ kfree(system);
+ return d_events;
+ }
+
list_add(&system->list, &event_subsystems);
- system->preds = NULL;
+ system->filter = NULL;
+
+ system->filter = kzalloc(sizeof(struct event_filter), GFP_KERNEL);
+ if (!system->filter) {
+ pr_warning("Could not allocate filter for subsystem "
+ "'%s'\n", name);
+ return system->entry;
+ }
+
+ entry = debugfs_create_file("filter", 0644, system->entry, system,
+ &ftrace_subsystem_filter_fops);
+ if (!entry) {
+ kfree(system->filter);
+ system->filter = NULL;
+ pr_warning("Could not create debugfs "
+ "'%s/filter' entry\n", name);
+ }
+
+ entry = trace_create_file("enable", 0644, system->entry,
+ (void *)system->name,
+ &ftrace_system_enable_fops);
return system->entry;
}
static int
-event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
+event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
+ const struct file_operations *id,
+ const struct file_operations *enable,
+ const struct file_operations *filter,
+ const struct file_operations *format)
{
struct dentry *entry;
int ret;
@@ -725,7 +904,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
* If the trace point header did not define TRACE_SYSTEM
* then the system would be called "TRACE_SYSTEM".
*/
- if (strcmp(call->system, "TRACE_SYSTEM") != 0)
+ if (strcmp(call->system, TRACE_SYSTEM) != 0)
d_events = event_subsystem_dir(call->system, d_events);
if (call->raw_init) {
@@ -744,21 +923,13 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
return -1;
}
- if (call->regfunc) {
- entry = debugfs_create_file("enable", 0644, call->dir, call,
- &ftrace_enable_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'%s/enable' entry\n", call->name);
- }
+ if (call->regfunc)
+ entry = trace_create_file("enable", 0644, call->dir, call,
+ enable);
- if (call->id) {
- entry = debugfs_create_file("id", 0444, call->dir, call,
- &ftrace_event_id_fops);
- if (!entry)
- pr_warning("Could not create debugfs '%s/id' entry\n",
- call->name);
- }
+ if (call->id)
+ entry = trace_create_file("id", 0444, call->dir, call,
+ id);
if (call->define_fields) {
ret = call->define_fields();
@@ -767,32 +938,196 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
" events/%s\n", call->name);
return ret;
}
- entry = debugfs_create_file("filter", 0644, call->dir, call,
- &ftrace_event_filter_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'%s/filter' entry\n", call->name);
+ entry = trace_create_file("filter", 0644, call->dir, call,
+ filter);
}
/* A trace may not want to export its format */
if (!call->show_format)
return 0;
- entry = debugfs_create_file("format", 0444, call->dir, call,
- &ftrace_event_format_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'%s/format' entry\n", call->name);
+ entry = trace_create_file("format", 0444, call->dir, call,
+ format);
+
+ return 0;
+}
+
+#define for_each_event(event, start, end) \
+ for (event = start; \
+ (unsigned long)event < (unsigned long)end; \
+ event++)
+
+#ifdef CONFIG_MODULES
+
+static LIST_HEAD(ftrace_module_file_list);
+
+/*
+ * Modules must own their file_operations to keep up with
+ * reference counting.
+ */
+struct ftrace_module_file_ops {
+ struct list_head list;
+ struct module *mod;
+ struct file_operations id;
+ struct file_operations enable;
+ struct file_operations format;
+ struct file_operations filter;
+};
+
+static struct ftrace_module_file_ops *
+trace_create_file_ops(struct module *mod)
+{
+ struct ftrace_module_file_ops *file_ops;
+
+ /*
+ * This is a bit of a PITA. To allow for correct reference
+ * counting, modules must "own" their file_operations.
+ * To do this, we allocate the file operations that will be
+ * used in the event directory.
+ */
+
+ file_ops = kmalloc(sizeof(*file_ops), GFP_KERNEL);
+ if (!file_ops)
+ return NULL;
+
+ file_ops->mod = mod;
+
+ file_ops->id = ftrace_event_id_fops;
+ file_ops->id.owner = mod;
+
+ file_ops->enable = ftrace_enable_fops;
+ file_ops->enable.owner = mod;
+
+ file_ops->filter = ftrace_event_filter_fops;
+ file_ops->filter.owner = mod;
+
+ file_ops->format = ftrace_event_format_fops;
+ file_ops->format.owner = mod;
+
+ list_add(&file_ops->list, &ftrace_module_file_list);
+
+ return file_ops;
+}
+
+static void trace_module_add_events(struct module *mod)
+{
+ struct ftrace_module_file_ops *file_ops = NULL;
+ struct ftrace_event_call *call, *start, *end;
+ struct dentry *d_events;
+
+ start = mod->trace_events;
+ end = mod->trace_events + mod->num_trace_events;
+
+ if (start == end)
+ return;
+
+ d_events = event_trace_events_dir();
+ if (!d_events)
+ return;
+
+ for_each_event(call, start, end) {
+ /* The linker may leave blanks */
+ if (!call->name)
+ continue;
+
+ /*
+ * This module has events, create file ops for this module
+ * if not already done.
+ */
+ if (!file_ops) {
+ file_ops = trace_create_file_ops(mod);
+ if (!file_ops)
+ return;
+ }
+ call->mod = mod;
+ list_add(&call->list, &ftrace_events);
+ event_create_dir(call, d_events,
+ &file_ops->id, &file_ops->enable,
+ &file_ops->filter, &file_ops->format);
+ }
+}
+
+static void trace_module_remove_events(struct module *mod)
+{
+ struct ftrace_module_file_ops *file_ops;
+ struct ftrace_event_call *call, *p;
+ bool found = false;
+
+ list_for_each_entry_safe(call, p, &ftrace_events, list) {
+ if (call->mod == mod) {
+ found = true;
+ if (call->enabled) {
+ call->enabled = 0;
+ call->unregfunc();
+ }
+ if (call->event)
+ unregister_ftrace_event(call->event);
+ debugfs_remove_recursive(call->dir);
+ list_del(&call->list);
+ trace_destroy_fields(call);
+ destroy_preds(call);
+ }
+ }
+
+ /* Now free the file_operations */
+ list_for_each_entry(file_ops, &ftrace_module_file_list, list) {
+ if (file_ops->mod == mod)
+ break;
+ }
+ if (&file_ops->list != &ftrace_module_file_list) {
+ list_del(&file_ops->list);
+ kfree(file_ops);
+ }
+
+ /*
+ * It is safest to reset the ring buffer if the module being unloaded
+ * registered any events.
+ */
+ if (found)
+ tracing_reset_current_online_cpus();
+}
+
+static int trace_module_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ struct module *mod = data;
+
+ mutex_lock(&event_mutex);
+ switch (val) {
+ case MODULE_STATE_COMING:
+ trace_module_add_events(mod);
+ break;
+ case MODULE_STATE_GOING:
+ trace_module_remove_events(mod);
+ break;
+ }
+ mutex_unlock(&event_mutex);
return 0;
}
+#else
+static int trace_module_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ return 0;
+}
+#endif /* CONFIG_MODULES */
+
+struct notifier_block trace_module_nb = {
+ .notifier_call = trace_module_notify,
+ .priority = 0,
+};
+
+extern struct ftrace_event_call __start_ftrace_events[];
+extern struct ftrace_event_call __stop_ftrace_events[];
static __init int event_trace_init(void)
{
- struct ftrace_event_call *call = __start_ftrace_events;
+ struct ftrace_event_call *call;
struct dentry *d_tracer;
struct dentry *entry;
struct dentry *d_events;
+ int ret;
d_tracer = tracing_init_dentry();
if (!d_tracer)
@@ -816,13 +1151,247 @@ static __init int event_trace_init(void)
if (!d_events)
return 0;
- for_each_event(call) {
+ /* ring buffer internal formats */
+ trace_create_file("header_page", 0444, d_events,
+ ring_buffer_print_page_header,
+ &ftrace_show_header_fops);
+
+ trace_create_file("header_event", 0444, d_events,
+ ring_buffer_print_entry_header,
+ &ftrace_show_header_fops);
+
+ trace_create_file("enable", 0644, d_events,
+ NULL, &ftrace_system_enable_fops);
+
+ for_each_event(call, __start_ftrace_events, __stop_ftrace_events) {
/* The linker may leave blanks */
if (!call->name)
continue;
- event_create_dir(call, d_events);
+ list_add(&call->list, &ftrace_events);
+ event_create_dir(call, d_events, &ftrace_event_id_fops,
+ &ftrace_enable_fops, &ftrace_event_filter_fops,
+ &ftrace_event_format_fops);
}
+ ret = register_module_notifier(&trace_module_nb);
+ if (!ret)
+ pr_warning("Failed to register trace events module notifier\n");
+
return 0;
}
fs_initcall(event_trace_init);
+
+#ifdef CONFIG_FTRACE_STARTUP_TEST
+
+static DEFINE_SPINLOCK(test_spinlock);
+static DEFINE_SPINLOCK(test_spinlock_irq);
+static DEFINE_MUTEX(test_mutex);
+
+static __init void test_work(struct work_struct *dummy)
+{
+ spin_lock(&test_spinlock);
+ spin_lock_irq(&test_spinlock_irq);
+ udelay(1);
+ spin_unlock_irq(&test_spinlock_irq);
+ spin_unlock(&test_spinlock);
+
+ mutex_lock(&test_mutex);
+ msleep(1);
+ mutex_unlock(&test_mutex);
+}
+
+static __init int event_test_thread(void *unused)
+{
+ void *test_malloc;
+
+ test_malloc = kmalloc(1234, GFP_KERNEL);
+ if (!test_malloc)
+ pr_info("failed to kmalloc\n");
+
+ schedule_on_each_cpu(test_work);
+
+ kfree(test_malloc);
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ while (!kthread_should_stop())
+ schedule();
+
+ return 0;
+}
+
+/*
+ * Do various things that may trigger events.
+ */
+static __init void event_test_stuff(void)
+{
+ struct task_struct *test_thread;
+
+ test_thread = kthread_run(event_test_thread, NULL, "test-events");
+ msleep(1);
+ kthread_stop(test_thread);
+}
+
+/*
+ * For every trace event defined, we will test each trace point separately,
+ * and then by groups, and finally all trace points.
+ */
+static __init void event_trace_self_tests(void)
+{
+ struct ftrace_event_call *call;
+ struct event_subsystem *system;
+ int ret;
+
+ pr_info("Running tests on trace events:\n");
+
+ list_for_each_entry(call, &ftrace_events, list) {
+
+ /* Only test those that have a regfunc */
+ if (!call->regfunc)
+ continue;
+
+ pr_info("Testing event %s: ", call->name);
+
+ /*
+ * If an event is already enabled, someone is using
+ * it and the self test should not be on.
+ */
+ if (call->enabled) {
+ pr_warning("Enabled event during self test!\n");
+ WARN_ON_ONCE(1);
+ continue;
+ }
+
+ call->enabled = 1;
+ call->regfunc();
+
+ event_test_stuff();
+
+ call->unregfunc();
+ call->enabled = 0;
+
+ pr_cont("OK\n");
+ }
+
+ /* Now test at the sub system level */
+
+ pr_info("Running tests on trace event systems:\n");
+
+ list_for_each_entry(system, &event_subsystems, list) {
+
+ /* the ftrace system is special, skip it */
+ if (strcmp(system->name, "ftrace") == 0)
+ continue;
+
+ pr_info("Testing event system %s: ", system->name);
+
+ ret = __ftrace_set_clr_event(NULL, system->name, NULL, 1);
+ if (WARN_ON_ONCE(ret)) {
+ pr_warning("error enabling system %s\n",
+ system->name);
+ continue;
+ }
+
+ event_test_stuff();
+
+ ret = __ftrace_set_clr_event(NULL, system->name, NULL, 0);
+ if (WARN_ON_ONCE(ret))
+ pr_warning("error disabling system %s\n",
+ system->name);
+
+ pr_cont("OK\n");
+ }
+
+ /* Test with all events enabled */
+
+ pr_info("Running tests on all trace events:\n");
+ pr_info("Testing all events: ");
+
+ ret = __ftrace_set_clr_event(NULL, NULL, NULL, 1);
+ if (WARN_ON_ONCE(ret)) {
+ pr_warning("error enabling all events\n");
+ return;
+ }
+
+ event_test_stuff();
+
+ /* reset sysname */
+ ret = __ftrace_set_clr_event(NULL, NULL, NULL, 0);
+ if (WARN_ON_ONCE(ret)) {
+ pr_warning("error disabling all events\n");
+ return;
+ }
+
+ pr_cont("OK\n");
+}
+
+#ifdef CONFIG_FUNCTION_TRACER
+
+static DEFINE_PER_CPU(atomic_t, test_event_disable);
+
+static void
+function_test_events_call(unsigned long ip, unsigned long parent_ip)
+{
+ struct ring_buffer_event *event;
+ struct ftrace_entry *entry;
+ unsigned long flags;
+ long disabled;
+ int resched;
+ int cpu;
+ int pc;
+
+ pc = preempt_count();
+ resched = ftrace_preempt_disable();
+ cpu = raw_smp_processor_id();
+ disabled = atomic_inc_return(&per_cpu(test_event_disable, cpu));
+
+ if (disabled != 1)
+ goto out;
+
+ local_save_flags(flags);
+
+ event = trace_current_buffer_lock_reserve(TRACE_FN, sizeof(*entry),
+ flags, pc);
+ if (!event)
+ goto out;
+ entry = ring_buffer_event_data(event);
+ entry->ip = ip;
+ entry->parent_ip = parent_ip;
+
+ trace_nowake_buffer_unlock_commit(event, flags, pc);
+
+ out:
+ atomic_dec(&per_cpu(test_event_disable, cpu));
+ ftrace_preempt_enable(resched);
+}
+
+static struct ftrace_ops trace_ops __initdata =
+{
+ .func = function_test_events_call,
+};
+
+static __init void event_trace_self_test_with_function(void)
+{
+ register_ftrace_function(&trace_ops);
+ pr_info("Running tests again, along with the function tracer\n");
+ event_trace_self_tests();
+ unregister_ftrace_function(&trace_ops);
+}
+#else
+static __init void event_trace_self_test_with_function(void)
+{
+}
+#endif
+
+static __init int event_trace_self_tests_init(void)
+{
+
+ event_trace_self_tests();
+
+ event_trace_self_test_with_function();
+
+ return 0;
+}
+
+late_initcall(event_trace_self_tests_init);
+
+#endif
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index e03cbf1e38f3..85ad6a8939ad 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -22,119 +22,297 @@
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/ctype.h>
+#include <linux/mutex.h>
#include "trace.h"
#include "trace_output.h"
-static int filter_pred_64(struct filter_pred *pred, void *event)
+static DEFINE_MUTEX(filter_mutex);
+
+enum filter_op_ids
+{
+ OP_OR,
+ OP_AND,
+ OP_NE,
+ OP_EQ,
+ OP_LT,
+ OP_LE,
+ OP_GT,
+ OP_GE,
+ OP_NONE,
+ OP_OPEN_PAREN,
+};
+
+struct filter_op {
+ int id;
+ char *string;
+ int precedence;
+};
+
+static struct filter_op filter_ops[] = {
+ { OP_OR, "||", 1 },
+ { OP_AND, "&&", 2 },
+ { OP_NE, "!=", 4 },
+ { OP_EQ, "==", 4 },
+ { OP_LT, "<", 5 },
+ { OP_LE, "<=", 5 },
+ { OP_GT, ">", 5 },
+ { OP_GE, ">=", 5 },
+ { OP_NONE, "OP_NONE", 0 },
+ { OP_OPEN_PAREN, "(", 0 },
+};
+
+enum {
+ FILT_ERR_NONE,
+ FILT_ERR_INVALID_OP,
+ FILT_ERR_UNBALANCED_PAREN,
+ FILT_ERR_TOO_MANY_OPERANDS,
+ FILT_ERR_OPERAND_TOO_LONG,
+ FILT_ERR_FIELD_NOT_FOUND,
+ FILT_ERR_ILLEGAL_FIELD_OP,
+ FILT_ERR_ILLEGAL_INTVAL,
+ FILT_ERR_BAD_SUBSYS_FILTER,
+ FILT_ERR_TOO_MANY_PREDS,
+ FILT_ERR_MISSING_FIELD,
+ FILT_ERR_INVALID_FILTER,
+};
+
+static char *err_text[] = {
+ "No error",
+ "Invalid operator",
+ "Unbalanced parens",
+ "Too many operands",
+ "Operand too long",
+ "Field not found",
+ "Illegal operation for field type",
+ "Illegal integer value",
+ "Couldn't find or set field in one of a subsystem's events",
+ "Too many terms in predicate expression",
+ "Missing field name and/or value",
+ "Meaningless filter expression",
+};
+
+struct opstack_op {
+ int op;
+ struct list_head list;
+};
+
+struct postfix_elt {
+ int op;
+ char *operand;
+ struct list_head list;
+};
+
+struct filter_parse_state {
+ struct filter_op *ops;
+ struct list_head opstack;
+ struct list_head postfix;
+ int lasterr;
+ int lasterr_pos;
+
+ struct {
+ char *string;
+ unsigned int cnt;
+ unsigned int tail;
+ } infix;
+
+ struct {
+ char string[MAX_FILTER_STR_VAL];
+ int pos;
+ unsigned int tail;
+ } operand;
+};
+
+DEFINE_COMPARISON_PRED(s64);
+DEFINE_COMPARISON_PRED(u64);
+DEFINE_COMPARISON_PRED(s32);
+DEFINE_COMPARISON_PRED(u32);
+DEFINE_COMPARISON_PRED(s16);
+DEFINE_COMPARISON_PRED(u16);
+DEFINE_COMPARISON_PRED(s8);
+DEFINE_COMPARISON_PRED(u8);
+
+DEFINE_EQUALITY_PRED(64);
+DEFINE_EQUALITY_PRED(32);
+DEFINE_EQUALITY_PRED(16);
+DEFINE_EQUALITY_PRED(8);
+
+static int filter_pred_and(struct filter_pred *pred __attribute((unused)),
+ void *event __attribute((unused)),
+ int val1, int val2)
+{
+ return val1 && val2;
+}
+
+static int filter_pred_or(struct filter_pred *pred __attribute((unused)),
+ void *event __attribute((unused)),
+ int val1, int val2)
+{
+ return val1 || val2;
+}
+
+/* Filter predicate for fixed sized arrays of characters */
+static int filter_pred_string(struct filter_pred *pred, void *event,
+ int val1, int val2)
{
- u64 *addr = (u64 *)(event + pred->offset);
- u64 val = (u64)pred->val;
- int match;
+ char *addr = (char *)(event + pred->offset);
+ int cmp, match;
+
+ cmp = strncmp(addr, pred->str_val, pred->str_len);
- match = (val == *addr) ^ pred->not;
+ match = (!cmp) ^ pred->not;
return match;
}
-static int filter_pred_32(struct filter_pred *pred, void *event)
+/*
+ * Filter predicate for dynamic sized arrays of characters.
+ * These are implemented through a list of strings at the end
+ * of the entry.
+ * Also each of these strings have a field in the entry which
+ * contains its offset from the beginning of the entry.
+ * We have then first to get this field, dereference it
+ * and add it to the address of the entry, and at last we have
+ * the address of the string.
+ */
+static int filter_pred_strloc(struct filter_pred *pred, void *event,
+ int val1, int val2)
{
- u32 *addr = (u32 *)(event + pred->offset);
- u32 val = (u32)pred->val;
- int match;
+ int str_loc = *(int *)(event + pred->offset);
+ char *addr = (char *)(event + str_loc);
+ int cmp, match;
+
+ cmp = strncmp(addr, pred->str_val, pred->str_len);
- match = (val == *addr) ^ pred->not;
+ match = (!cmp) ^ pred->not;
return match;
}
-static int filter_pred_16(struct filter_pred *pred, void *event)
+static int filter_pred_none(struct filter_pred *pred, void *event,
+ int val1, int val2)
+{
+ return 0;
+}
+
+/* return 1 if event matches, 0 otherwise (discard) */
+int filter_match_preds(struct ftrace_event_call *call, void *rec)
{
- u16 *addr = (u16 *)(event + pred->offset);
- u16 val = (u16)pred->val;
- int match;
+ struct event_filter *filter = call->filter;
+ int match, top = 0, val1 = 0, val2 = 0;
+ int stack[MAX_FILTER_PRED];
+ struct filter_pred *pred;
+ int i;
+
+ for (i = 0; i < filter->n_preds; i++) {
+ pred = filter->preds[i];
+ if (!pred->pop_n) {
+ match = pred->fn(pred, rec, val1, val2);
+ stack[top++] = match;
+ continue;
+ }
+ if (pred->pop_n > top) {
+ WARN_ON_ONCE(1);
+ return 0;
+ }
+ val1 = stack[--top];
+ val2 = stack[--top];
+ match = pred->fn(pred, rec, val1, val2);
+ stack[top++] = match;
+ }
- match = (val == *addr) ^ pred->not;
+ return stack[--top];
+}
+EXPORT_SYMBOL_GPL(filter_match_preds);
- return match;
+static void parse_error(struct filter_parse_state *ps, int err, int pos)
+{
+ ps->lasterr = err;
+ ps->lasterr_pos = pos;
}
-static int filter_pred_8(struct filter_pred *pred, void *event)
+static void remove_filter_string(struct event_filter *filter)
{
- u8 *addr = (u8 *)(event + pred->offset);
- u8 val = (u8)pred->val;
- int match;
+ kfree(filter->filter_string);
+ filter->filter_string = NULL;
+}
- match = (val == *addr) ^ pred->not;
+static int replace_filter_string(struct event_filter *filter,
+ char *filter_string)
+{
+ kfree(filter->filter_string);
+ filter->filter_string = kstrdup(filter_string, GFP_KERNEL);
+ if (!filter->filter_string)
+ return -ENOMEM;
- return match;
+ return 0;
}
-static int filter_pred_string(struct filter_pred *pred, void *event)
+static int append_filter_string(struct event_filter *filter,
+ char *string)
{
- char *addr = (char *)(event + pred->offset);
- int cmp, match;
+ int newlen;
+ char *new_filter_string;
- cmp = strncmp(addr, pred->str_val, pred->str_len);
+ BUG_ON(!filter->filter_string);
+ newlen = strlen(filter->filter_string) + strlen(string) + 1;
+ new_filter_string = kmalloc(newlen, GFP_KERNEL);
+ if (!new_filter_string)
+ return -ENOMEM;
- match = (!cmp) ^ pred->not;
+ strcpy(new_filter_string, filter->filter_string);
+ strcat(new_filter_string, string);
+ kfree(filter->filter_string);
+ filter->filter_string = new_filter_string;
- return match;
+ return 0;
}
-/* return 1 if event matches, 0 otherwise (discard) */
-int filter_match_preds(struct ftrace_event_call *call, void *rec)
+static void append_filter_err(struct filter_parse_state *ps,
+ struct event_filter *filter)
{
- int i, matched, and_failed = 0;
- struct filter_pred *pred;
+ int pos = ps->lasterr_pos;
+ char *buf, *pbuf;
- for (i = 0; i < MAX_FILTER_PRED; i++) {
- if (call->preds[i]) {
- pred = call->preds[i];
- if (and_failed && !pred->or)
- continue;
- matched = pred->fn(pred, rec);
- if (!matched && !pred->or) {
- and_failed = 1;
- continue;
- } else if (matched && pred->or)
- return 1;
- } else
- break;
- }
+ buf = (char *)__get_free_page(GFP_TEMPORARY);
+ if (!buf)
+ return;
- if (and_failed)
- return 0;
+ append_filter_string(filter, "\n");
+ memset(buf, ' ', PAGE_SIZE);
+ if (pos > PAGE_SIZE - 128)
+ pos = 0;
+ buf[pos] = '^';
+ pbuf = &buf[pos] + 1;
- return 1;
+ sprintf(pbuf, "\nparse_error: %s\n", err_text[ps->lasterr]);
+ append_filter_string(filter, buf);
+ free_page((unsigned long) buf);
}
-void filter_print_preds(struct filter_pred **preds, struct trace_seq *s)
+void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s)
{
- char *field_name;
- struct filter_pred *pred;
- int i;
+ struct event_filter *filter = call->filter;
- if (!preds) {
+ mutex_lock(&filter_mutex);
+ if (filter->filter_string)
+ trace_seq_printf(s, "%s\n", filter->filter_string);
+ else
trace_seq_printf(s, "none\n");
- return;
- }
+ mutex_unlock(&filter_mutex);
+}
- for (i = 0; i < MAX_FILTER_PRED; i++) {
- if (preds[i]) {
- pred = preds[i];
- field_name = pred->field_name;
- if (i)
- trace_seq_printf(s, pred->or ? "|| " : "&& ");
- trace_seq_printf(s, "%s ", field_name);
- trace_seq_printf(s, pred->not ? "!= " : "== ");
- if (pred->str_val)
- trace_seq_printf(s, "%s\n", pred->str_val);
- else
- trace_seq_printf(s, "%llu\n", pred->val);
- } else
- break;
- }
+void print_subsystem_event_filter(struct event_subsystem *system,
+ struct trace_seq *s)
+{
+ struct event_filter *filter = system->filter;
+
+ mutex_lock(&filter_mutex);
+ if (filter->filter_string)
+ trace_seq_printf(s, "%s\n", filter->filter_string);
+ else
+ trace_seq_printf(s, "none\n");
+ mutex_unlock(&filter_mutex);
}
static struct ftrace_event_field *
@@ -150,284 +328,826 @@ find_event_field(struct ftrace_event_call *call, char *name)
return NULL;
}
-void filter_free_pred(struct filter_pred *pred)
+static void filter_free_pred(struct filter_pred *pred)
{
if (!pred)
return;
kfree(pred->field_name);
- kfree(pred->str_val);
kfree(pred);
}
-void filter_free_preds(struct ftrace_event_call *call)
+static void filter_clear_pred(struct filter_pred *pred)
{
- int i;
+ kfree(pred->field_name);
+ pred->field_name = NULL;
+ pred->str_len = 0;
+}
- if (call->preds) {
- for (i = 0; i < MAX_FILTER_PRED; i++)
- filter_free_pred(call->preds[i]);
- kfree(call->preds);
- call->preds = NULL;
+static int filter_set_pred(struct filter_pred *dest,
+ struct filter_pred *src,
+ filter_pred_fn_t fn)
+{
+ *dest = *src;
+ if (src->field_name) {
+ dest->field_name = kstrdup(src->field_name, GFP_KERNEL);
+ if (!dest->field_name)
+ return -ENOMEM;
}
+ dest->fn = fn;
+
+ return 0;
}
-void filter_free_subsystem_preds(struct event_subsystem *system)
+static void filter_disable_preds(struct ftrace_event_call *call)
{
- struct ftrace_event_call *call = __start_ftrace_events;
+ struct event_filter *filter = call->filter;
int i;
- if (system->preds) {
- for (i = 0; i < MAX_FILTER_PRED; i++)
- filter_free_pred(system->preds[i]);
- kfree(system->preds);
- system->preds = NULL;
- }
+ call->filter_active = 0;
+ filter->n_preds = 0;
- events_for_each(call) {
- if (!call->name || !call->regfunc)
- continue;
+ for (i = 0; i < MAX_FILTER_PRED; i++)
+ filter->preds[i]->fn = filter_pred_none;
+}
+
+void destroy_preds(struct ftrace_event_call *call)
+{
+ struct event_filter *filter = call->filter;
+ int i;
- if (!strcmp(call->system, system->name))
- filter_free_preds(call);
+ for (i = 0; i < MAX_FILTER_PRED; i++) {
+ if (filter->preds[i])
+ filter_free_pred(filter->preds[i]);
}
+ kfree(filter->preds);
+ kfree(filter);
+ call->filter = NULL;
}
-static int __filter_add_pred(struct ftrace_event_call *call,
- struct filter_pred *pred)
+int init_preds(struct ftrace_event_call *call)
{
+ struct event_filter *filter;
+ struct filter_pred *pred;
int i;
- if (call->preds && !pred->compound)
- filter_free_preds(call);
+ filter = call->filter = kzalloc(sizeof(*filter), GFP_KERNEL);
+ if (!call->filter)
+ return -ENOMEM;
- if (!call->preds) {
- call->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred),
- GFP_KERNEL);
- if (!call->preds)
- return -ENOMEM;
- }
+ call->filter_active = 0;
+ filter->n_preds = 0;
+
+ filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL);
+ if (!filter->preds)
+ goto oom;
for (i = 0; i < MAX_FILTER_PRED; i++) {
- if (!call->preds[i]) {
- call->preds[i] = pred;
- return 0;
+ pred = kzalloc(sizeof(*pred), GFP_KERNEL);
+ if (!pred)
+ goto oom;
+ pred->fn = filter_pred_none;
+ filter->preds[i] = pred;
+ }
+
+ return 0;
+
+oom:
+ destroy_preds(call);
+
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(init_preds);
+
+static void filter_free_subsystem_preds(struct event_subsystem *system)
+{
+ struct event_filter *filter = system->filter;
+ struct ftrace_event_call *call;
+ int i;
+
+ if (filter->n_preds) {
+ for (i = 0; i < filter->n_preds; i++)
+ filter_free_pred(filter->preds[i]);
+ kfree(filter->preds);
+ filter->preds = NULL;
+ filter->n_preds = 0;
+ }
+
+ mutex_lock(&event_mutex);
+ list_for_each_entry(call, &ftrace_events, list) {
+ if (!call->define_fields)
+ continue;
+
+ if (!strcmp(call->system, system->name)) {
+ filter_disable_preds(call);
+ remove_filter_string(call->filter);
}
}
+ mutex_unlock(&event_mutex);
+}
+
+static int filter_add_pred_fn(struct filter_parse_state *ps,
+ struct ftrace_event_call *call,
+ struct filter_pred *pred,
+ filter_pred_fn_t fn)
+{
+ struct event_filter *filter = call->filter;
+ int idx, err;
+
+ if (filter->n_preds == MAX_FILTER_PRED) {
+ parse_error(ps, FILT_ERR_TOO_MANY_PREDS, 0);
+ return -ENOSPC;
+ }
+
+ idx = filter->n_preds;
+ filter_clear_pred(filter->preds[idx]);
+ err = filter_set_pred(filter->preds[idx], pred, fn);
+ if (err)
+ return err;
- return -ENOSPC;
+ filter->n_preds++;
+ call->filter_active = 1;
+
+ return 0;
}
+enum {
+ FILTER_STATIC_STRING = 1,
+ FILTER_DYN_STRING
+};
+
static int is_string_field(const char *type)
{
if (strchr(type, '[') && strstr(type, "char"))
- return 1;
+ return FILTER_STATIC_STRING;
+
+ if (!strcmp(type, "__str_loc"))
+ return FILTER_DYN_STRING;
return 0;
}
-int filter_add_pred(struct ftrace_event_call *call, struct filter_pred *pred)
+static int is_legal_op(struct ftrace_event_field *field, int op)
+{
+ if (is_string_field(field->type) && (op != OP_EQ && op != OP_NE))
+ return 0;
+
+ return 1;
+}
+
+static filter_pred_fn_t select_comparison_fn(int op, int field_size,
+ int field_is_signed)
+{
+ filter_pred_fn_t fn = NULL;
+
+ switch (field_size) {
+ case 8:
+ if (op == OP_EQ || op == OP_NE)
+ fn = filter_pred_64;
+ else if (field_is_signed)
+ fn = filter_pred_s64;
+ else
+ fn = filter_pred_u64;
+ break;
+ case 4:
+ if (op == OP_EQ || op == OP_NE)
+ fn = filter_pred_32;
+ else if (field_is_signed)
+ fn = filter_pred_s32;
+ else
+ fn = filter_pred_u32;
+ break;
+ case 2:
+ if (op == OP_EQ || op == OP_NE)
+ fn = filter_pred_16;
+ else if (field_is_signed)
+ fn = filter_pred_s16;
+ else
+ fn = filter_pred_u16;
+ break;
+ case 1:
+ if (op == OP_EQ || op == OP_NE)
+ fn = filter_pred_8;
+ else if (field_is_signed)
+ fn = filter_pred_s8;
+ else
+ fn = filter_pred_u8;
+ break;
+ }
+
+ return fn;
+}
+
+static int filter_add_pred(struct filter_parse_state *ps,
+ struct ftrace_event_call *call,
+ struct filter_pred *pred)
{
struct ftrace_event_field *field;
+ filter_pred_fn_t fn;
+ unsigned long long val;
+ int string_type;
+
+ pred->fn = filter_pred_none;
+
+ if (pred->op == OP_AND) {
+ pred->pop_n = 2;
+ return filter_add_pred_fn(ps, call, pred, filter_pred_and);
+ } else if (pred->op == OP_OR) {
+ pred->pop_n = 2;
+ return filter_add_pred_fn(ps, call, pred, filter_pred_or);
+ }
field = find_event_field(call, pred->field_name);
- if (!field)
+ if (!field) {
+ parse_error(ps, FILT_ERR_FIELD_NOT_FOUND, 0);
return -EINVAL;
+ }
pred->offset = field->offset;
- if (is_string_field(field->type)) {
- if (!pred->str_val)
- return -EINVAL;
- pred->fn = filter_pred_string;
+ if (!is_legal_op(field, pred->op)) {
+ parse_error(ps, FILT_ERR_ILLEGAL_FIELD_OP, 0);
+ return -EINVAL;
+ }
+
+ string_type = is_string_field(field->type);
+ if (string_type) {
+ if (string_type == FILTER_STATIC_STRING)
+ fn = filter_pred_string;
+ else
+ fn = filter_pred_strloc;
pred->str_len = field->size;
- return __filter_add_pred(call, pred);
+ if (pred->op == OP_NE)
+ pred->not = 1;
+ return filter_add_pred_fn(ps, call, pred, fn);
} else {
- if (pred->str_val)
+ if (strict_strtoull(pred->str_val, 0, &val)) {
+ parse_error(ps, FILT_ERR_ILLEGAL_INTVAL, 0);
return -EINVAL;
+ }
+ pred->val = val;
}
- switch (field->size) {
- case 8:
- pred->fn = filter_pred_64;
- break;
- case 4:
- pred->fn = filter_pred_32;
- break;
- case 2:
- pred->fn = filter_pred_16;
- break;
- case 1:
- pred->fn = filter_pred_8;
- break;
- default:
+ fn = select_comparison_fn(pred->op, field->size, field->is_signed);
+ if (!fn) {
+ parse_error(ps, FILT_ERR_INVALID_OP, 0);
return -EINVAL;
}
- return __filter_add_pred(call, pred);
+ if (pred->op == OP_NE)
+ pred->not = 1;
+
+ return filter_add_pred_fn(ps, call, pred, fn);
}
-static struct filter_pred *copy_pred(struct filter_pred *pred)
+static int filter_add_subsystem_pred(struct filter_parse_state *ps,
+ struct event_subsystem *system,
+ struct filter_pred *pred,
+ char *filter_string)
{
- struct filter_pred *new_pred = kmalloc(sizeof(*pred), GFP_KERNEL);
- if (!new_pred)
- return NULL;
+ struct event_filter *filter = system->filter;
+ struct ftrace_event_call *call;
+ int err = 0;
+
+ if (!filter->preds) {
+ filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred),
+ GFP_KERNEL);
- memcpy(new_pred, pred, sizeof(*pred));
+ if (!filter->preds)
+ return -ENOMEM;
+ }
- if (pred->field_name) {
- new_pred->field_name = kstrdup(pred->field_name, GFP_KERNEL);
- if (!new_pred->field_name) {
- kfree(new_pred);
- return NULL;
- }
+ if (filter->n_preds == MAX_FILTER_PRED) {
+ parse_error(ps, FILT_ERR_TOO_MANY_PREDS, 0);
+ return -ENOSPC;
}
- if (pred->str_val) {
- new_pred->str_val = kstrdup(pred->str_val, GFP_KERNEL);
- if (!new_pred->str_val) {
- filter_free_pred(new_pred);
- return NULL;
+ filter->preds[filter->n_preds] = pred;
+ filter->n_preds++;
+
+ mutex_lock(&event_mutex);
+ list_for_each_entry(call, &ftrace_events, list) {
+
+ if (!call->define_fields)
+ continue;
+
+ if (strcmp(call->system, system->name))
+ continue;
+
+ err = filter_add_pred(ps, call, pred);
+ if (err) {
+ mutex_unlock(&event_mutex);
+ filter_free_subsystem_preds(system);
+ parse_error(ps, FILT_ERR_BAD_SUBSYS_FILTER, 0);
+ goto out;
}
+ replace_filter_string(call->filter, filter_string);
}
+ mutex_unlock(&event_mutex);
+out:
+ return err;
+}
+
+static void parse_init(struct filter_parse_state *ps,
+ struct filter_op *ops,
+ char *infix_string)
+{
+ memset(ps, '\0', sizeof(*ps));
- return new_pred;
+ ps->infix.string = infix_string;
+ ps->infix.cnt = strlen(infix_string);
+ ps->ops = ops;
+
+ INIT_LIST_HEAD(&ps->opstack);
+ INIT_LIST_HEAD(&ps->postfix);
}
-int filter_add_subsystem_pred(struct event_subsystem *system,
- struct filter_pred *pred)
+static char infix_next(struct filter_parse_state *ps)
{
- struct ftrace_event_call *call = __start_ftrace_events;
- struct filter_pred *event_pred;
- int i;
+ ps->infix.cnt--;
- if (system->preds && !pred->compound)
- filter_free_subsystem_preds(system);
+ return ps->infix.string[ps->infix.tail++];
+}
- if (!system->preds) {
- system->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred),
- GFP_KERNEL);
- if (!system->preds)
- return -ENOMEM;
+static char infix_peek(struct filter_parse_state *ps)
+{
+ if (ps->infix.tail == strlen(ps->infix.string))
+ return 0;
+
+ return ps->infix.string[ps->infix.tail];
+}
+
+static void infix_advance(struct filter_parse_state *ps)
+{
+ ps->infix.cnt--;
+ ps->infix.tail++;
+}
+
+static inline int is_precedence_lower(struct filter_parse_state *ps,
+ int a, int b)
+{
+ return ps->ops[a].precedence < ps->ops[b].precedence;
+}
+
+static inline int is_op_char(struct filter_parse_state *ps, char c)
+{
+ int i;
+
+ for (i = 0; strcmp(ps->ops[i].string, "OP_NONE"); i++) {
+ if (ps->ops[i].string[0] == c)
+ return 1;
}
- for (i = 0; i < MAX_FILTER_PRED; i++) {
- if (!system->preds[i]) {
- system->preds[i] = pred;
- break;
+ return 0;
+}
+
+static int infix_get_op(struct filter_parse_state *ps, char firstc)
+{
+ char nextc = infix_peek(ps);
+ char opstr[3];
+ int i;
+
+ opstr[0] = firstc;
+ opstr[1] = nextc;
+ opstr[2] = '\0';
+
+ for (i = 0; strcmp(ps->ops[i].string, "OP_NONE"); i++) {
+ if (!strcmp(opstr, ps->ops[i].string)) {
+ infix_advance(ps);
+ return ps->ops[i].id;
}
}
- if (i == MAX_FILTER_PRED)
- return -ENOSPC;
+ opstr[1] = '\0';
+
+ for (i = 0; strcmp(ps->ops[i].string, "OP_NONE"); i++) {
+ if (!strcmp(opstr, ps->ops[i].string))
+ return ps->ops[i].id;
+ }
+
+ return OP_NONE;
+}
+
+static inline void clear_operand_string(struct filter_parse_state *ps)
+{
+ memset(ps->operand.string, '\0', MAX_FILTER_STR_VAL);
+ ps->operand.tail = 0;
+}
+
+static inline int append_operand_char(struct filter_parse_state *ps, char c)
+{
+ if (ps->operand.tail == MAX_FILTER_STR_VAL)
+ return -EINVAL;
+
+ ps->operand.string[ps->operand.tail++] = c;
+
+ return 0;
+}
+
+static int filter_opstack_push(struct filter_parse_state *ps, int op)
+{
+ struct opstack_op *opstack_op;
+
+ opstack_op = kmalloc(sizeof(*opstack_op), GFP_KERNEL);
+ if (!opstack_op)
+ return -ENOMEM;
+
+ opstack_op->op = op;
+ list_add(&opstack_op->list, &ps->opstack);
+
+ return 0;
+}
+
+static int filter_opstack_empty(struct filter_parse_state *ps)
+{
+ return list_empty(&ps->opstack);
+}
+
+static int filter_opstack_top(struct filter_parse_state *ps)
+{
+ struct opstack_op *opstack_op;
+
+ if (filter_opstack_empty(ps))
+ return OP_NONE;
+
+ opstack_op = list_first_entry(&ps->opstack, struct opstack_op, list);
+
+ return opstack_op->op;
+}
+
+static int filter_opstack_pop(struct filter_parse_state *ps)
+{
+ struct opstack_op *opstack_op;
+ int op;
+
+ if (filter_opstack_empty(ps))
+ return OP_NONE;
+
+ opstack_op = list_first_entry(&ps->opstack, struct opstack_op, list);
+ op = opstack_op->op;
+ list_del(&opstack_op->list);
+
+ kfree(opstack_op);
+
+ return op;
+}
+
+static void filter_opstack_clear(struct filter_parse_state *ps)
+{
+ while (!filter_opstack_empty(ps))
+ filter_opstack_pop(ps);
+}
+
+static char *curr_operand(struct filter_parse_state *ps)
+{
+ return ps->operand.string;
+}
+
+static int postfix_append_operand(struct filter_parse_state *ps, char *operand)
+{
+ struct postfix_elt *elt;
+
+ elt = kmalloc(sizeof(*elt), GFP_KERNEL);
+ if (!elt)
+ return -ENOMEM;
+
+ elt->op = OP_NONE;
+ elt->operand = kstrdup(operand, GFP_KERNEL);
+ if (!elt->operand) {
+ kfree(elt);
+ return -ENOMEM;
+ }
+
+ list_add_tail(&elt->list, &ps->postfix);
+
+ return 0;
+}
+
+static int postfix_append_op(struct filter_parse_state *ps, int op)
+{
+ struct postfix_elt *elt;
+
+ elt = kmalloc(sizeof(*elt), GFP_KERNEL);
+ if (!elt)
+ return -ENOMEM;
+
+ elt->op = op;
+ elt->operand = NULL;
+
+ list_add_tail(&elt->list, &ps->postfix);
+
+ return 0;
+}
+
+static void postfix_clear(struct filter_parse_state *ps)
+{
+ struct postfix_elt *elt;
+
+ while (!list_empty(&ps->postfix)) {
+ elt = list_first_entry(&ps->postfix, struct postfix_elt, list);
+ kfree(elt->operand);
+ list_del(&elt->list);
+ }
+}
- events_for_each(call) {
- int err;
+static int filter_parse(struct filter_parse_state *ps)
+{
+ int in_string = 0;
+ int op, top_op;
+ char ch;
- if (!call->name || !call->regfunc)
+ while ((ch = infix_next(ps))) {
+ if (ch == '"') {
+ in_string ^= 1;
continue;
+ }
- if (strcmp(call->system, system->name))
+ if (in_string)
+ goto parse_operand;
+
+ if (isspace(ch))
continue;
- if (!find_event_field(call, pred->field_name))
+ if (is_op_char(ps, ch)) {
+ op = infix_get_op(ps, ch);
+ if (op == OP_NONE) {
+ parse_error(ps, FILT_ERR_INVALID_OP, 0);
+ return -EINVAL;
+ }
+
+ if (strlen(curr_operand(ps))) {
+ postfix_append_operand(ps, curr_operand(ps));
+ clear_operand_string(ps);
+ }
+
+ while (!filter_opstack_empty(ps)) {
+ top_op = filter_opstack_top(ps);
+ if (!is_precedence_lower(ps, top_op, op)) {
+ top_op = filter_opstack_pop(ps);
+ postfix_append_op(ps, top_op);
+ continue;
+ }
+ break;
+ }
+
+ filter_opstack_push(ps, op);
continue;
+ }
- event_pred = copy_pred(pred);
- if (!event_pred)
- goto oom;
+ if (ch == '(') {
+ filter_opstack_push(ps, OP_OPEN_PAREN);
+ continue;
+ }
- err = filter_add_pred(call, event_pred);
- if (err)
- filter_free_pred(event_pred);
- if (err == -ENOMEM)
- goto oom;
+ if (ch == ')') {
+ if (strlen(curr_operand(ps))) {
+ postfix_append_operand(ps, curr_operand(ps));
+ clear_operand_string(ps);
+ }
+
+ top_op = filter_opstack_pop(ps);
+ while (top_op != OP_NONE) {
+ if (top_op == OP_OPEN_PAREN)
+ break;
+ postfix_append_op(ps, top_op);
+ top_op = filter_opstack_pop(ps);
+ }
+ if (top_op == OP_NONE) {
+ parse_error(ps, FILT_ERR_UNBALANCED_PAREN, 0);
+ return -EINVAL;
+ }
+ continue;
+ }
+parse_operand:
+ if (append_operand_char(ps, ch)) {
+ parse_error(ps, FILT_ERR_OPERAND_TOO_LONG, 0);
+ return -EINVAL;
+ }
+ }
+
+ if (strlen(curr_operand(ps)))
+ postfix_append_operand(ps, curr_operand(ps));
+
+ while (!filter_opstack_empty(ps)) {
+ top_op = filter_opstack_pop(ps);
+ if (top_op == OP_NONE)
+ break;
+ if (top_op == OP_OPEN_PAREN) {
+ parse_error(ps, FILT_ERR_UNBALANCED_PAREN, 0);
+ return -EINVAL;
+ }
+ postfix_append_op(ps, top_op);
}
return 0;
+}
-oom:
- system->preds[i] = NULL;
- return -ENOMEM;
+static struct filter_pred *create_pred(int op, char *operand1, char *operand2)
+{
+ struct filter_pred *pred;
+
+ pred = kzalloc(sizeof(*pred), GFP_KERNEL);
+ if (!pred)
+ return NULL;
+
+ pred->field_name = kstrdup(operand1, GFP_KERNEL);
+ if (!pred->field_name) {
+ kfree(pred);
+ return NULL;
+ }
+
+ strcpy(pred->str_val, operand2);
+ pred->str_len = strlen(operand2);
+
+ pred->op = op;
+
+ return pred;
}
-int filter_parse(char **pbuf, struct filter_pred *pred)
+static struct filter_pred *create_logical_pred(int op)
{
- char *tmp, *tok, *val_str = NULL;
- int tok_n = 0;
+ struct filter_pred *pred;
- /* field ==/!= number, or/and field ==/!= number, number */
- while ((tok = strsep(pbuf, " \n"))) {
- if (tok_n == 0) {
- if (!strcmp(tok, "0")) {
- pred->clear = 1;
- return 0;
- } else if (!strcmp(tok, "&&")) {
- pred->or = 0;
- pred->compound = 1;
- } else if (!strcmp(tok, "||")) {
- pred->or = 1;
- pred->compound = 1;
- } else
- pred->field_name = tok;
- tok_n = 1;
+ pred = kzalloc(sizeof(*pred), GFP_KERNEL);
+ if (!pred)
+ return NULL;
+
+ pred->op = op;
+
+ return pred;
+}
+
+static int check_preds(struct filter_parse_state *ps)
+{
+ int n_normal_preds = 0, n_logical_preds = 0;
+ struct postfix_elt *elt;
+
+ list_for_each_entry(elt, &ps->postfix, list) {
+ if (elt->op == OP_NONE)
+ continue;
+
+ if (elt->op == OP_AND || elt->op == OP_OR) {
+ n_logical_preds++;
continue;
}
- if (tok_n == 1) {
- if (!pred->field_name)
- pred->field_name = tok;
- else if (!strcmp(tok, "!="))
- pred->not = 1;
- else if (!strcmp(tok, "=="))
- pred->not = 0;
+ n_normal_preds++;
+ }
+
+ if (!n_normal_preds || n_logical_preds >= n_normal_preds) {
+ parse_error(ps, FILT_ERR_INVALID_FILTER, 0);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int replace_preds(struct event_subsystem *system,
+ struct ftrace_event_call *call,
+ struct filter_parse_state *ps,
+ char *filter_string)
+{
+ char *operand1 = NULL, *operand2 = NULL;
+ struct filter_pred *pred;
+ struct postfix_elt *elt;
+ int err;
+
+ err = check_preds(ps);
+ if (err)
+ return err;
+
+ list_for_each_entry(elt, &ps->postfix, list) {
+ if (elt->op == OP_NONE) {
+ if (!operand1)
+ operand1 = elt->operand;
+ else if (!operand2)
+ operand2 = elt->operand;
else {
- pred->field_name = NULL;
+ parse_error(ps, FILT_ERR_TOO_MANY_OPERANDS, 0);
return -EINVAL;
}
- tok_n = 2;
continue;
}
- if (tok_n == 2) {
- if (pred->compound) {
- if (!strcmp(tok, "!="))
- pred->not = 1;
- else if (!strcmp(tok, "=="))
- pred->not = 0;
- else {
- pred->field_name = NULL;
- return -EINVAL;
- }
- } else {
- val_str = tok;
- break; /* done */
- }
- tok_n = 3;
+
+ if (elt->op == OP_AND || elt->op == OP_OR) {
+ pred = create_logical_pred(elt->op);
+ if (call) {
+ err = filter_add_pred(ps, call, pred);
+ filter_free_pred(pred);
+ } else
+ err = filter_add_subsystem_pred(ps, system,
+ pred, filter_string);
+ if (err)
+ return err;
+
+ operand1 = operand2 = NULL;
continue;
}
- if (tok_n == 3) {
- val_str = tok;
- break; /* done */
+
+ if (!operand1 || !operand2) {
+ parse_error(ps, FILT_ERR_MISSING_FIELD, 0);
+ return -EINVAL;
}
+
+ pred = create_pred(elt->op, operand1, operand2);
+ if (call) {
+ err = filter_add_pred(ps, call, pred);
+ filter_free_pred(pred);
+ } else
+ err = filter_add_subsystem_pred(ps, system, pred,
+ filter_string);
+ if (err)
+ return err;
+
+ operand1 = operand2 = NULL;
}
- if (!val_str) {
- pred->field_name = NULL;
- return -EINVAL;
+ return 0;
+}
+
+int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
+{
+ int err;
+
+ struct filter_parse_state *ps;
+
+ mutex_lock(&filter_mutex);
+
+ if (!strcmp(strstrip(filter_string), "0")) {
+ filter_disable_preds(call);
+ remove_filter_string(call->filter);
+ mutex_unlock(&filter_mutex);
+ return 0;
}
- pred->field_name = kstrdup(pred->field_name, GFP_KERNEL);
- if (!pred->field_name)
+ ps = kzalloc(sizeof(*ps), GFP_KERNEL);
+ if (!ps)
return -ENOMEM;
- pred->val = simple_strtoull(val_str, &tmp, 0);
- if (tmp == val_str) {
- pred->str_val = kstrdup(val_str, GFP_KERNEL);
- if (!pred->str_val)
- return -ENOMEM;
- } else if (*tmp != '\0')
- return -EINVAL;
+ filter_disable_preds(call);
+ replace_filter_string(call->filter, filter_string);
- return 0;
+ parse_init(ps, filter_ops, filter_string);
+ err = filter_parse(ps);
+ if (err) {
+ append_filter_err(ps, call->filter);
+ goto out;
+ }
+
+ err = replace_preds(NULL, call, ps, filter_string);
+ if (err)
+ append_filter_err(ps, call->filter);
+
+out:
+ filter_opstack_clear(ps);
+ postfix_clear(ps);
+ kfree(ps);
+
+ mutex_unlock(&filter_mutex);
+
+ return err;
}
+int apply_subsystem_event_filter(struct event_subsystem *system,
+ char *filter_string)
+{
+ int err;
+
+ struct filter_parse_state *ps;
+
+ mutex_lock(&filter_mutex);
+
+ if (!strcmp(strstrip(filter_string), "0")) {
+ filter_free_subsystem_preds(system);
+ remove_filter_string(system->filter);
+ mutex_unlock(&filter_mutex);
+ return 0;
+ }
+
+ ps = kzalloc(sizeof(*ps), GFP_KERNEL);
+ if (!ps)
+ return -ENOMEM;
+
+ filter_free_subsystem_preds(system);
+ replace_filter_string(system->filter, filter_string);
+
+ parse_init(ps, filter_ops, filter_string);
+ err = filter_parse(ps);
+ if (err) {
+ append_filter_err(ps, system->filter);
+ goto out;
+ }
+
+ err = replace_preds(system, NULL, ps, filter_string);
+ if (err)
+ append_filter_err(ps, system->filter);
+
+out:
+ filter_opstack_clear(ps);
+ postfix_clear(ps);
+ kfree(ps);
+
+ mutex_unlock(&filter_mutex);
+
+ return err;
+}
diff --git a/kernel/trace/trace_events_stage_1.h b/kernel/trace/trace_events_stage_1.h
deleted file mode 100644
index 38985f9b379c..000000000000
--- a/kernel/trace/trace_events_stage_1.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Stage 1 of the trace events.
- *
- * Override the macros in <trace/trace_event_types.h> to include the following:
- *
- * struct ftrace_raw_<call> {
- * struct trace_entry ent;
- * <type> <item>;
- * <type2> <item2>[<len>];
- * [...]
- * };
- *
- * The <type> <item> is created by the __field(type, item) macro or
- * the __array(type2, item2, len) macro.
- * We simply do "type item;", and that will create the fields
- * in the structure.
- */
-
-#undef TRACE_FORMAT
-#define TRACE_FORMAT(call, proto, args, fmt)
-
-#undef __array
-#define __array(type, item, len) type item[len];
-
-#undef __field
-#define __field(type, item) type item;
-
-#undef TP_STRUCT__entry
-#define TP_STRUCT__entry(args...) args
-
-#undef TRACE_EVENT
-#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
- struct ftrace_raw_##name { \
- struct trace_entry ent; \
- tstruct \
- }; \
- static struct ftrace_event_call event_##name
-
-#include <trace/trace_event_types.h>
diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h
deleted file mode 100644
index d363c6672c6c..000000000000
--- a/kernel/trace/trace_events_stage_2.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Stage 2 of the trace events.
- *
- * Override the macros in <trace/trace_event_types.h> to include the following:
- *
- * enum print_line_t
- * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags)
- * {
- * struct trace_seq *s = &iter->seq;
- * struct ftrace_raw_<call> *field; <-- defined in stage 1
- * struct trace_entry *entry;
- * int ret;
- *
- * entry = iter->ent;
- *
- * if (entry->type != event_<call>.id) {
- * WARN_ON_ONCE(1);
- * return TRACE_TYPE_UNHANDLED;
- * }
- *
- * field = (typeof(field))entry;
- *
- * ret = trace_seq_printf(s, <TP_printk> "\n");
- * if (!ret)
- * return TRACE_TYPE_PARTIAL_LINE;
- *
- * return TRACE_TYPE_HANDLED;
- * }
- *
- * This is the method used to print the raw event to the trace
- * output format. Note, this is not needed if the data is read
- * in binary.
- */
-
-#undef __entry
-#define __entry field
-
-#undef TP_printk
-#define TP_printk(fmt, args...) fmt "\n", args
-
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
-enum print_line_t \
-ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
-{ \
- struct trace_seq *s = &iter->seq; \
- struct ftrace_raw_##call *field; \
- struct trace_entry *entry; \
- int ret; \
- \
- entry = iter->ent; \
- \
- if (entry->type != event_##call.id) { \
- WARN_ON_ONCE(1); \
- return TRACE_TYPE_UNHANDLED; \
- } \
- \
- field = (typeof(field))entry; \
- \
- ret = trace_seq_printf(s, #call ": " print); \
- if (!ret) \
- return TRACE_TYPE_PARTIAL_LINE; \
- \
- return TRACE_TYPE_HANDLED; \
-}
-
-#include <trace/trace_event_types.h>
-
-/*
- * Setup the showing format of trace point.
- *
- * int
- * ftrace_format_##call(struct trace_seq *s)
- * {
- * struct ftrace_raw_##call field;
- * int ret;
- *
- * ret = trace_seq_printf(s, #type " " #item ";"
- * " offset:%u; size:%u;\n",
- * offsetof(struct ftrace_raw_##call, item),
- * sizeof(field.type));
- *
- * }
- */
-
-#undef TP_STRUCT__entry
-#define TP_STRUCT__entry(args...) args
-
-#undef __field
-#define __field(type, item) \
- ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
- "offset:%u;\tsize:%u;\n", \
- (unsigned int)offsetof(typeof(field), item), \
- (unsigned int)sizeof(field.item)); \
- if (!ret) \
- return 0;
-
-#undef __array
-#define __array(type, item, len) \
- ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
- "offset:%u;\tsize:%u;\n", \
- (unsigned int)offsetof(typeof(field), item), \
- (unsigned int)sizeof(field.item)); \
- if (!ret) \
- return 0;
-
-#undef __entry
-#define __entry REC
-
-#undef TP_printk
-#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
-
-#undef TP_fast_assign
-#define TP_fast_assign(args...) args
-
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
-static int \
-ftrace_format_##call(struct trace_seq *s) \
-{ \
- struct ftrace_raw_##call field; \
- int ret; \
- \
- tstruct; \
- \
- trace_seq_printf(s, "\nprint fmt: " print); \
- \
- return ret; \
-}
-
-#include <trace/trace_event_types.h>
-
-#undef __field
-#define __field(type, item) \
- ret = trace_define_field(event_call, #type, #item, \
- offsetof(typeof(field), item), \
- sizeof(field.item)); \
- if (ret) \
- return ret;
-
-#undef __array
-#define __array(type, item, len) \
- ret = trace_define_field(event_call, #type "[" #len "]", #item, \
- offsetof(typeof(field), item), \
- sizeof(field.item)); \
- if (ret) \
- return ret;
-
-#define __common_field(type, item) \
- ret = trace_define_field(event_call, #type, "common_" #item, \
- offsetof(typeof(field.ent), item), \
- sizeof(field.ent.item)); \
- if (ret) \
- return ret;
-
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
-int \
-ftrace_define_fields_##call(void) \
-{ \
- struct ftrace_raw_##call field; \
- struct ftrace_event_call *event_call = &event_##call; \
- int ret; \
- \
- __common_field(unsigned char, type); \
- __common_field(unsigned char, flags); \
- __common_field(unsigned char, preempt_count); \
- __common_field(int, pid); \
- __common_field(int, tgid); \
- \
- tstruct; \
- \
- return ret; \
-}
-
-#include <trace/trace_event_types.h>
diff --git a/kernel/trace/trace_events_stage_3.h b/kernel/trace/trace_events_stage_3.h
deleted file mode 100644
index 9d2fa78cecca..000000000000
--- a/kernel/trace/trace_events_stage_3.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Stage 3 of the trace events.
- *
- * Override the macros in <trace/trace_event_types.h> to include the following:
- *
- * static void ftrace_event_<call>(proto)
- * {
- * event_trace_printk(_RET_IP_, "<call>: " <fmt>);
- * }
- *
- * static int ftrace_reg_event_<call>(void)
- * {
- * int ret;
- *
- * ret = register_trace_<call>(ftrace_event_<call>);
- * if (!ret)
- * pr_info("event trace: Could not activate trace point "
- * "probe to <call>");
- * return ret;
- * }
- *
- * static void ftrace_unreg_event_<call>(void)
- * {
- * unregister_trace_<call>(ftrace_event_<call>);
- * }
- *
- * For those macros defined with TRACE_FORMAT:
- *
- * static struct ftrace_event_call __used
- * __attribute__((__aligned__(4)))
- * __attribute__((section("_ftrace_events"))) event_<call> = {
- * .name = "<call>",
- * .regfunc = ftrace_reg_event_<call>,
- * .unregfunc = ftrace_unreg_event_<call>,
- * }
- *
- *
- * For those macros defined with TRACE_EVENT:
- *
- * static struct ftrace_event_call event_<call>;
- *
- * static void ftrace_raw_event_<call>(proto)
- * {
- * struct ring_buffer_event *event;
- * struct ftrace_raw_<call> *entry; <-- defined in stage 1
- * unsigned long irq_flags;
- * int pc;
- *
- * local_save_flags(irq_flags);
- * pc = preempt_count();
- *
- * event = trace_current_buffer_lock_reserve(event_<call>.id,
- * sizeof(struct ftrace_raw_<call>),
- * irq_flags, pc);
- * if (!event)
- * return;
- * entry = ring_buffer_event_data(event);
- *
- * <assign>; <-- Here we assign the entries by the __field and
- * __array macros.
- *
- * trace_current_buffer_unlock_commit(event, irq_flags, pc);
- * }
- *
- * static int ftrace_raw_reg_event_<call>(void)
- * {
- * int ret;
- *
- * ret = register_trace_<call>(ftrace_raw_event_<call>);
- * if (!ret)
- * pr_info("event trace: Could not activate trace point "
- * "probe to <call>");
- * return ret;
- * }
- *
- * static void ftrace_unreg_event_<call>(void)
- * {
- * unregister_trace_<call>(ftrace_raw_event_<call>);
- * }
- *
- * static struct trace_event ftrace_event_type_<call> = {
- * .trace = ftrace_raw_output_<call>, <-- stage 2
- * };
- *
- * static int ftrace_raw_init_event_<call>(void)
- * {
- * int id;
- *
- * id = register_ftrace_event(&ftrace_event_type_<call>);
- * if (!id)
- * return -ENODEV;
- * event_<call>.id = id;
- * return 0;
- * }
- *
- * static struct ftrace_event_call __used
- * __attribute__((__aligned__(4)))
- * __attribute__((section("_ftrace_events"))) event_<call> = {
- * .name = "<call>",
- * .system = "<system>",
- * .raw_init = ftrace_raw_init_event_<call>,
- * .regfunc = ftrace_reg_event_<call>,
- * .unregfunc = ftrace_unreg_event_<call>,
- * .show_format = ftrace_format_<call>,
- * }
- *
- */
-
-#undef TP_FMT
-#define TP_FMT(fmt, args...) fmt "\n", ##args
-
-#ifdef CONFIG_EVENT_PROFILE
-#define _TRACE_PROFILE(call, proto, args) \
-static void ftrace_profile_##call(proto) \
-{ \
- extern void perf_tpcounter_event(int); \
- perf_tpcounter_event(event_##call.id); \
-} \
- \
-static int ftrace_profile_enable_##call(struct ftrace_event_call *call) \
-{ \
- int ret = 0; \
- \
- if (!atomic_inc_return(&call->profile_count)) \
- ret = register_trace_##call(ftrace_profile_##call); \
- \
- return ret; \
-} \
- \
-static void ftrace_profile_disable_##call(struct ftrace_event_call *call) \
-{ \
- if (atomic_add_negative(-1, &call->profile_count)) \
- unregister_trace_##call(ftrace_profile_##call); \
-}
-
-#define _TRACE_PROFILE_INIT(call) \
- .profile_count = ATOMIC_INIT(-1), \
- .profile_enable = ftrace_profile_enable_##call, \
- .profile_disable = ftrace_profile_disable_##call,
-
-#else
-#define _TRACE_PROFILE(call, proto, args)
-#define _TRACE_PROFILE_INIT(call)
-#endif
-
-#define _TRACE_FORMAT(call, proto, args, fmt) \
-static void ftrace_event_##call(proto) \
-{ \
- event_trace_printk(_RET_IP_, #call ": " fmt); \
-} \
- \
-static int ftrace_reg_event_##call(void) \
-{ \
- int ret; \
- \
- ret = register_trace_##call(ftrace_event_##call); \
- if (ret) \
- pr_info("event trace: Could not activate trace point " \
- "probe to " #call "\n"); \
- return ret; \
-} \
- \
-static void ftrace_unreg_event_##call(void) \
-{ \
- unregister_trace_##call(ftrace_event_##call); \
-} \
- \
-static struct ftrace_event_call event_##call; \
- \
-static int ftrace_init_event_##call(void) \
-{ \
- int id; \
- \
- id = register_ftrace_event(NULL); \
- if (!id) \
- return -ENODEV; \
- event_##call.id = id; \
- return 0; \
-}
-
-#undef TRACE_FORMAT
-#define TRACE_FORMAT(call, proto, args, fmt) \
-_TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt)) \
-_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \
-static struct ftrace_event_call __used \
-__attribute__((__aligned__(4))) \
-__attribute__((section("_ftrace_events"))) event_##call = { \
- .name = #call, \
- .system = __stringify(TRACE_SYSTEM), \
- .raw_init = ftrace_init_event_##call, \
- .regfunc = ftrace_reg_event_##call, \
- .unregfunc = ftrace_unreg_event_##call, \
- _TRACE_PROFILE_INIT(call) \
-}
-
-#undef __entry
-#define __entry entry
-
-#undef TRACE_EVENT
-#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
-_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \
- \
-static struct ftrace_event_call event_##call; \
- \
-static void ftrace_raw_event_##call(proto) \
-{ \
- struct ftrace_event_call *call = &event_##call; \
- struct ring_buffer_event *event; \
- struct ftrace_raw_##call *entry; \
- unsigned long irq_flags; \
- int pc; \
- \
- local_save_flags(irq_flags); \
- pc = preempt_count(); \
- \
- event = trace_current_buffer_lock_reserve(event_##call.id, \
- sizeof(struct ftrace_raw_##call), \
- irq_flags, pc); \
- if (!event) \
- return; \
- entry = ring_buffer_event_data(event); \
- \
- assign; \
- \
- if (call->preds && !filter_match_preds(call, entry)) \
- ring_buffer_event_discard(event); \
- \
- trace_nowake_buffer_unlock_commit(event, irq_flags, pc); \
- \
-} \
- \
-static int ftrace_raw_reg_event_##call(void) \
-{ \
- int ret; \
- \
- ret = register_trace_##call(ftrace_raw_event_##call); \
- if (ret) \
- pr_info("event trace: Could not activate trace point " \
- "probe to " #call "\n"); \
- return ret; \
-} \
- \
-static void ftrace_raw_unreg_event_##call(void) \
-{ \
- unregister_trace_##call(ftrace_raw_event_##call); \
-} \
- \
-static struct trace_event ftrace_event_type_##call = { \
- .trace = ftrace_raw_output_##call, \
-}; \
- \
-static int ftrace_raw_init_event_##call(void) \
-{ \
- int id; \
- \
- id = register_ftrace_event(&ftrace_event_type_##call); \
- if (!id) \
- return -ENODEV; \
- event_##call.id = id; \
- INIT_LIST_HEAD(&event_##call.fields); \
- return 0; \
-} \
- \
-static struct ftrace_event_call __used \
-__attribute__((__aligned__(4))) \
-__attribute__((section("_ftrace_events"))) event_##call = { \
- .name = #call, \
- .system = __stringify(TRACE_SYSTEM), \
- .raw_init = ftrace_raw_init_event_##call, \
- .regfunc = ftrace_raw_reg_event_##call, \
- .unregfunc = ftrace_raw_unreg_event_##call, \
- .show_format = ftrace_format_##call, \
- .define_fields = ftrace_define_fields_##call, \
- _TRACE_PROFILE_INIT(call) \
-}
-
-#include <trace/trace_event_types.h>
-
-#undef _TRACE_PROFILE
-#undef _TRACE_PROFILE_INIT
-
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
index 07a22c33ebf3..d06cf898dc86 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -19,8 +19,12 @@
#undef TRACE_STRUCT
#define TRACE_STRUCT(args...) args
+extern void __bad_type_size(void);
+
#undef TRACE_FIELD
#define TRACE_FIELD(type, item, assign) \
+ if (sizeof(type) != sizeof(field.item)) \
+ __bad_type_size(); \
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
"offset:%u;\tsize:%u;\n", \
(unsigned int)offsetof(typeof(field), item), \
@@ -30,7 +34,7 @@
#undef TRACE_FIELD_SPECIAL
-#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \
+#define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \
ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t" \
"offset:%u;\tsize:%u;\n", \
(unsigned int)offsetof(typeof(field), item), \
@@ -46,6 +50,9 @@
if (!ret) \
return 0;
+#undef TRACE_FIELD_SIGN
+#define TRACE_FIELD_SIGN(type, item, assign, is_signed) \
+ TRACE_FIELD(type, item, assign)
#undef TP_RAW_FMT
#define TP_RAW_FMT(args...) args
@@ -65,6 +72,22 @@ ftrace_format_##call(struct trace_seq *s) \
return ret; \
}
+#undef TRACE_EVENT_FORMAT_NOFILTER
+#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \
+ tpfmt) \
+static int \
+ftrace_format_##call(struct trace_seq *s) \
+{ \
+ struct args field; \
+ int ret; \
+ \
+ tstruct; \
+ \
+ trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt); \
+ \
+ return ret; \
+}
+
#include "trace_event_types.h"
#undef TRACE_ZERO_CHAR
@@ -78,6 +101,10 @@ ftrace_format_##call(struct trace_seq *s) \
#define TRACE_FIELD(type, item, assign)\
entry->item = assign;
+#undef TRACE_FIELD_SIGN
+#define TRACE_FIELD_SIGN(type, item, assign, is_signed) \
+ TRACE_FIELD(type, item, assign)
+
#undef TP_CMD
#define TP_CMD(cmd...) cmd
@@ -85,18 +112,95 @@ ftrace_format_##call(struct trace_seq *s) \
#define TRACE_ENTRY entry
#undef TRACE_FIELD_SPECIAL
-#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \
+#define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \
cmd;
#undef TRACE_EVENT_FORMAT
#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \
+int ftrace_define_fields_##call(void); \
+static int ftrace_raw_init_event_##call(void); \
+ \
+struct ftrace_event_call __used \
+__attribute__((__aligned__(4))) \
+__attribute__((section("_ftrace_events"))) event_##call = { \
+ .name = #call, \
+ .id = proto, \
+ .system = __stringify(TRACE_SYSTEM), \
+ .raw_init = ftrace_raw_init_event_##call, \
+ .show_format = ftrace_format_##call, \
+ .define_fields = ftrace_define_fields_##call, \
+}; \
+static int ftrace_raw_init_event_##call(void) \
+{ \
+ INIT_LIST_HEAD(&event_##call.fields); \
+ init_preds(&event_##call); \
+ return 0; \
+} \
+
+#undef TRACE_EVENT_FORMAT_NOFILTER
+#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \
+ tpfmt) \
\
-static struct ftrace_event_call __used \
+struct ftrace_event_call __used \
__attribute__((__aligned__(4))) \
__attribute__((section("_ftrace_events"))) event_##call = { \
.name = #call, \
.id = proto, \
.system = __stringify(TRACE_SYSTEM), \
.show_format = ftrace_format_##call, \
+};
+
+#include "trace_event_types.h"
+
+#undef TRACE_FIELD
+#define TRACE_FIELD(type, item, assign) \
+ ret = trace_define_field(event_call, #type, #item, \
+ offsetof(typeof(field), item), \
+ sizeof(field.item), is_signed_type(type)); \
+ if (ret) \
+ return ret;
+
+#undef TRACE_FIELD_SPECIAL
+#define TRACE_FIELD_SPECIAL(type, item, len, cmd) \
+ ret = trace_define_field(event_call, #type "[" #len "]", #item, \
+ offsetof(typeof(field), item), \
+ sizeof(field.item), 0); \
+ if (ret) \
+ return ret;
+
+#undef TRACE_FIELD_SIGN
+#define TRACE_FIELD_SIGN(type, item, assign, is_signed) \
+ ret = trace_define_field(event_call, #type, #item, \
+ offsetof(typeof(field), item), \
+ sizeof(field.item), is_signed); \
+ if (ret) \
+ return ret;
+
+#undef TRACE_FIELD_ZERO_CHAR
+#define TRACE_FIELD_ZERO_CHAR(item)
+
+#undef TRACE_EVENT_FORMAT
+#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \
+int \
+ftrace_define_fields_##call(void) \
+{ \
+ struct ftrace_event_call *event_call = &event_##call; \
+ struct args field; \
+ int ret; \
+ \
+ __common_field(unsigned char, type, 0); \
+ __common_field(unsigned char, flags, 0); \
+ __common_field(unsigned char, preempt_count, 0); \
+ __common_field(int, pid, 1); \
+ __common_field(int, tgid, 1); \
+ \
+ tstruct; \
+ \
+ return ret; \
}
+
+#undef TRACE_EVENT_FORMAT_NOFILTER
+#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \
+ tpfmt)
+
#include "trace_event_types.h"
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index d28687e7b3a7..10f6ad7d85f6 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -78,13 +78,14 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth)
current->ret_stack[index].ret = ret;
current->ret_stack[index].func = func;
current->ret_stack[index].calltime = calltime;
+ current->ret_stack[index].subtime = 0;
*depth = index;
return 0;
}
/* Retrieve a function return address to the trace stack on thread info.*/
-void
+static void
ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
{
int index;
@@ -104,9 +105,6 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
trace->calltime = current->ret_stack[index].calltime;
trace->overrun = atomic_read(&current->trace_overrun);
trace->depth = index;
- barrier();
- current->curr_ret_stack--;
-
}
/*
@@ -121,6 +119,8 @@ unsigned long ftrace_return_to_handler(void)
ftrace_pop_return_trace(&trace, &ret);
trace.rettime = trace_clock_local();
ftrace_graph_return(&trace);
+ barrier();
+ current->curr_ret_stack--;
if (unlikely(!ret)) {
ftrace_graph_stop();
@@ -426,8 +426,8 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
return TRACE_TYPE_HANDLED;
}
-static enum print_line_t
-print_graph_duration(unsigned long long duration, struct trace_seq *s)
+enum print_line_t
+trace_print_graph_duration(unsigned long long duration, struct trace_seq *s)
{
unsigned long nsecs_rem = do_div(duration, 1000);
/* log10(ULONG_MAX) + '\0' */
@@ -464,12 +464,23 @@ print_graph_duration(unsigned long long duration, struct trace_seq *s)
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
}
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t
+print_graph_duration(unsigned long long duration, struct trace_seq *s)
+{
+ int ret;
+
+ ret = trace_print_graph_duration(duration, s);
+ if (ret != TRACE_TYPE_HANDLED)
+ return ret;
ret = trace_seq_printf(s, "| ");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
- return TRACE_TYPE_HANDLED;
+ return TRACE_TYPE_HANDLED;
}
/* Case of a leaf function on its call entry */
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
index 7bfdf4c2347f..ca7d7c4d0c2a 100644
--- a/kernel/trace/trace_hw_branches.c
+++ b/kernel/trace/trace_hw_branches.c
@@ -1,10 +1,9 @@
/*
- * h/w branch tracer for x86 based on bts
+ * h/w branch tracer for x86 based on BTS
*
* Copyright (C) 2008-2009 Intel Corporation.
* Markus Metzger <markus.t.metzger@gmail.com>, 2008-2009
*/
-#include <linux/spinlock.h>
#include <linux/kallsyms.h>
#include <linux/debugfs.h>
#include <linux/ftrace.h>
@@ -15,110 +14,119 @@
#include <asm/ds.h>
-#include "trace.h"
#include "trace_output.h"
+#include "trace.h"
-#define SIZEOF_BTS (1 << 13)
+#define BTS_BUFFER_SIZE (1 << 13)
-/*
- * The tracer lock protects the below per-cpu tracer array.
- * It needs to be held to:
- * - start tracing on all cpus
- * - stop tracing on all cpus
- * - start tracing on a single hotplug cpu
- * - stop tracing on a single hotplug cpu
- * - read the trace from all cpus
- * - read the trace from a single cpu
- */
-static DEFINE_SPINLOCK(bts_tracer_lock);
static DEFINE_PER_CPU(struct bts_tracer *, tracer);
-static DEFINE_PER_CPU(unsigned char[SIZEOF_BTS], buffer);
+static DEFINE_PER_CPU(unsigned char[BTS_BUFFER_SIZE], buffer);
#define this_tracer per_cpu(tracer, smp_processor_id())
-#define this_buffer per_cpu(buffer, smp_processor_id())
-static int __read_mostly trace_hw_branches_enabled;
+static int trace_hw_branches_enabled __read_mostly;
+static int trace_hw_branches_suspended __read_mostly;
static struct trace_array *hw_branch_trace __read_mostly;
-/*
- * Start tracing on the current cpu.
- * The argument is ignored.
- *
- * pre: bts_tracer_lock must be locked.
- */
-static void bts_trace_start_cpu(void *arg)
+static void bts_trace_init_cpu(int cpu)
{
- if (this_tracer)
- ds_release_bts(this_tracer);
-
- this_tracer =
- ds_request_bts(/* task = */ NULL, this_buffer, SIZEOF_BTS,
- /* ovfl = */ NULL, /* th = */ (size_t)-1,
- BTS_KERNEL);
- if (IS_ERR(this_tracer)) {
- this_tracer = NULL;
- return;
- }
+ per_cpu(tracer, cpu) =
+ ds_request_bts_cpu(cpu, per_cpu(buffer, cpu), BTS_BUFFER_SIZE,
+ NULL, (size_t)-1, BTS_KERNEL);
+
+ if (IS_ERR(per_cpu(tracer, cpu)))
+ per_cpu(tracer, cpu) = NULL;
}
-static void bts_trace_start(struct trace_array *tr)
+static int bts_trace_init(struct trace_array *tr)
{
- spin_lock(&bts_tracer_lock);
+ int cpu;
+
+ hw_branch_trace = tr;
+ trace_hw_branches_enabled = 0;
- on_each_cpu(bts_trace_start_cpu, NULL, 1);
- trace_hw_branches_enabled = 1;
+ get_online_cpus();
+ for_each_online_cpu(cpu) {
+ bts_trace_init_cpu(cpu);
- spin_unlock(&bts_tracer_lock);
+ if (likely(per_cpu(tracer, cpu)))
+ trace_hw_branches_enabled = 1;
+ }
+ trace_hw_branches_suspended = 0;
+ put_online_cpus();
+
+ /* If we could not enable tracing on a single cpu, we fail. */
+ return trace_hw_branches_enabled ? 0 : -EOPNOTSUPP;
}
-/*
- * Stop tracing on the current cpu.
- * The argument is ignored.
- *
- * pre: bts_tracer_lock must be locked.
- */
-static void bts_trace_stop_cpu(void *arg)
+static void bts_trace_reset(struct trace_array *tr)
{
- if (this_tracer) {
- ds_release_bts(this_tracer);
- this_tracer = NULL;
+ int cpu;
+
+ get_online_cpus();
+ for_each_online_cpu(cpu) {
+ if (likely(per_cpu(tracer, cpu))) {
+ ds_release_bts(per_cpu(tracer, cpu));
+ per_cpu(tracer, cpu) = NULL;
+ }
}
+ trace_hw_branches_enabled = 0;
+ trace_hw_branches_suspended = 0;
+ put_online_cpus();
}
-static void bts_trace_stop(struct trace_array *tr)
+static void bts_trace_start(struct trace_array *tr)
{
- spin_lock(&bts_tracer_lock);
+ int cpu;
- trace_hw_branches_enabled = 0;
- on_each_cpu(bts_trace_stop_cpu, NULL, 1);
+ get_online_cpus();
+ for_each_online_cpu(cpu)
+ if (likely(per_cpu(tracer, cpu)))
+ ds_resume_bts(per_cpu(tracer, cpu));
+ trace_hw_branches_suspended = 0;
+ put_online_cpus();
+}
- spin_unlock(&bts_tracer_lock);
+static void bts_trace_stop(struct trace_array *tr)
+{
+ int cpu;
+
+ get_online_cpus();
+ for_each_online_cpu(cpu)
+ if (likely(per_cpu(tracer, cpu)))
+ ds_suspend_bts(per_cpu(tracer, cpu));
+ trace_hw_branches_suspended = 1;
+ put_online_cpus();
}
static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
- unsigned int cpu = (unsigned long)hcpu;
-
- spin_lock(&bts_tracer_lock);
-
- if (!trace_hw_branches_enabled)
- goto out;
+ int cpu = (long)hcpu;
switch (action) {
case CPU_ONLINE:
case CPU_DOWN_FAILED:
- smp_call_function_single(cpu, bts_trace_start_cpu, NULL, 1);
+ /* The notification is sent with interrupts enabled. */
+ if (trace_hw_branches_enabled) {
+ bts_trace_init_cpu(cpu);
+
+ if (trace_hw_branches_suspended &&
+ likely(per_cpu(tracer, cpu)))
+ ds_suspend_bts(per_cpu(tracer, cpu));
+ }
break;
+
case CPU_DOWN_PREPARE:
- smp_call_function_single(cpu, bts_trace_stop_cpu, NULL, 1);
- break;
+ /* The notification is sent with interrupts enabled. */
+ if (likely(per_cpu(tracer, cpu))) {
+ ds_release_bts(per_cpu(tracer, cpu));
+ per_cpu(tracer, cpu) = NULL;
+ }
}
- out:
- spin_unlock(&bts_tracer_lock);
return NOTIFY_DONE;
}
@@ -126,20 +134,6 @@ static struct notifier_block bts_hotcpu_notifier __cpuinitdata = {
.notifier_call = bts_hotcpu_handler
};
-static int bts_trace_init(struct trace_array *tr)
-{
- hw_branch_trace = tr;
-
- bts_trace_start(tr);
-
- return 0;
-}
-
-static void bts_trace_reset(struct trace_array *tr)
-{
- bts_trace_stop(tr);
-}
-
static void bts_trace_print_header(struct seq_file *m)
{
seq_puts(m, "# CPU# TO <- FROM\n");
@@ -147,10 +141,10 @@ static void bts_trace_print_header(struct seq_file *m)
static enum print_line_t bts_trace_print_line(struct trace_iterator *iter)
{
+ unsigned long symflags = TRACE_ITER_SYM_OFFSET;
struct trace_entry *entry = iter->ent;
struct trace_seq *seq = &iter->seq;
struct hw_branch_entry *it;
- unsigned long symflags = TRACE_ITER_SYM_OFFSET;
trace_assign_type(it, entry);
@@ -168,6 +162,7 @@ static enum print_line_t bts_trace_print_line(struct trace_iterator *iter)
void trace_hw_branch(u64 from, u64 to)
{
+ struct ftrace_event_call *call = &event_hw_branch;
struct trace_array *tr = hw_branch_trace;
struct ring_buffer_event *event;
struct hw_branch_entry *entry;
@@ -194,7 +189,8 @@ void trace_hw_branch(u64 from, u64 to)
entry->ent.type = TRACE_HW_BRANCHES;
entry->from = from;
entry->to = to;
- trace_buffer_unlock_commit(tr, event, 0, 0);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ trace_buffer_unlock_commit(tr, event, 0, 0);
out:
atomic_dec(&tr->data[cpu]->disabled);
@@ -224,11 +220,11 @@ static void trace_bts_at(const struct bts_trace *trace, void *at)
/*
* Collect the trace on the current cpu and write it into the ftrace buffer.
*
- * pre: bts_tracer_lock must be locked
+ * pre: tracing must be suspended on the current cpu
*/
static void trace_bts_cpu(void *arg)
{
- struct trace_array *tr = (struct trace_array *) arg;
+ struct trace_array *tr = (struct trace_array *)arg;
const struct bts_trace *trace;
unsigned char *at;
@@ -241,10 +237,9 @@ static void trace_bts_cpu(void *arg)
if (unlikely(!this_tracer))
return;
- ds_suspend_bts(this_tracer);
trace = ds_read_bts(this_tracer);
if (!trace)
- goto out;
+ return;
for (at = trace->ds.top; (void *)at < trace->ds.end;
at += trace->ds.size)
@@ -253,18 +248,27 @@ static void trace_bts_cpu(void *arg)
for (at = trace->ds.begin; (void *)at < trace->ds.top;
at += trace->ds.size)
trace_bts_at(trace, at);
-
-out:
- ds_resume_bts(this_tracer);
}
static void trace_bts_prepare(struct trace_iterator *iter)
{
- spin_lock(&bts_tracer_lock);
+ int cpu;
+ get_online_cpus();
+ for_each_online_cpu(cpu)
+ if (likely(per_cpu(tracer, cpu)))
+ ds_suspend_bts(per_cpu(tracer, cpu));
+ /*
+ * We need to collect the trace on the respective cpu since ftrace
+ * implicitly adds the record for the current cpu.
+ * Once that is more flexible, we could collect the data from any cpu.
+ */
on_each_cpu(trace_bts_cpu, iter->tr, 1);
- spin_unlock(&bts_tracer_lock);
+ for_each_online_cpu(cpu)
+ if (likely(per_cpu(tracer, cpu)))
+ ds_resume_bts(per_cpu(tracer, cpu));
+ put_online_cpus();
}
static void trace_bts_close(struct trace_iterator *iter)
@@ -274,11 +278,11 @@ static void trace_bts_close(struct trace_iterator *iter)
void trace_hw_branch_oops(void)
{
- spin_lock(&bts_tracer_lock);
-
- trace_bts_cpu(hw_branch_trace);
-
- spin_unlock(&bts_tracer_lock);
+ if (this_tracer) {
+ ds_suspend_bts_noirq(this_tracer);
+ trace_bts_cpu(hw_branch_trace);
+ ds_resume_bts_noirq(this_tracer);
+ }
}
struct tracer bts_tracer __read_mostly =
@@ -291,7 +295,10 @@ struct tracer bts_tracer __read_mostly =
.start = bts_trace_start,
.stop = bts_trace_stop,
.open = trace_bts_prepare,
- .close = trace_bts_close
+ .close = trace_bts_close,
+#ifdef CONFIG_FTRACE_SELFTEST
+ .selftest = trace_selftest_startup_hw_branches,
+#endif /* CONFIG_FTRACE_SELFTEST */
};
__init static int init_bts_trace(void)
diff --git a/kernel/trace/trace_mm.c b/kernel/trace/trace_mm.c
new file mode 100644
index 000000000000..4bc7fc0e6b53
--- /dev/null
+++ b/kernel/trace/trace_mm.c
@@ -0,0 +1,172 @@
+/*
+ * Trace mm pages
+ *
+ * Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ * Code based on Matt Mackall's /proc/[kpagecount|kpageflags] code.
+ */
+#include <linux/module.h>
+#include <linux/bootmem.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include "trace_output.h"
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/mm.h>
+
+void trace_read_page_frames(unsigned long start, unsigned long end,
+ void (*trace)(unsigned long pfn, struct page *page))
+{
+ unsigned long pfn = start;
+ struct page *page;
+
+ if (start > max_pfn - 1)
+ return;
+
+ if (end > max_pfn - 1)
+ end = max_pfn - 1;
+
+ while (pfn < end) {
+ page = NULL;
+ if (pfn_valid(pfn))
+ page = pfn_to_page(pfn);
+ pfn++;
+ if (page)
+ trace(pfn, page);
+ }
+}
+
+static void trace_do_dump_pages(unsigned long pfn, struct page *page)
+{
+ trace_dump_pages(pfn, page);
+}
+
+static ssize_t
+trace_mm_dump_range_read(struct file *filp, char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ return simple_read_from_buffer(ubuf, cnt, ppos, "0\n", 2);
+}
+
+
+static ssize_t
+trace_mm_dump_range_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ unsigned long val, start, end;
+ char buf[64];
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+
+ if (tracing_update_buffers() < 0)
+ return -ENOMEM;
+
+ if (trace_set_clr_event("mm", "dump_pages", 1))
+ return -EINVAL;
+
+ buf[cnt] = 0;
+
+ ret = strict_strtol(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ start = *ppos;
+ if (val < 0)
+ end = max_pfn - 1;
+ else
+ end = start + val;
+
+ trace_read_page_frames(start, end, trace_do_dump_pages);
+
+ *ppos += cnt;
+
+ return cnt;
+}
+
+static const struct file_operations trace_mm_fops = {
+ .open = tracing_open_generic,
+ .read = trace_mm_dump_range_read,
+ .write = trace_mm_dump_range_write,
+};
+
+/* move this into trace_objects.c when that file is created */
+static struct dentry *trace_objects_dir(void)
+{
+ static struct dentry *d_objects;
+ struct dentry *d_tracer;
+
+ if (d_objects)
+ return d_objects;
+
+ d_tracer = tracing_init_dentry();
+ if (!d_tracer)
+ return NULL;
+
+ d_objects = debugfs_create_dir("objects", d_tracer);
+ if (!d_objects)
+ pr_warning("Could not create debugfs "
+ "'objects' directory\n");
+
+ return d_objects;
+}
+
+
+static struct dentry *trace_objects_mm_dir(void)
+{
+ static struct dentry *d_mm;
+ struct dentry *d_objects;
+
+ if (d_mm)
+ return d_mm;
+
+ d_objects = trace_objects_dir();
+ if (!d_objects)
+ return NULL;
+
+ d_mm = debugfs_create_dir("mm", d_objects);
+ if (!d_mm)
+ pr_warning("Could not create 'objects/mm' directory\n");
+
+ return d_mm;
+}
+
+static struct dentry *trace_objects_mm_pages_dir(void)
+{
+ static struct dentry *d_pages;
+ struct dentry *d_mm;
+
+ if (d_pages)
+ return d_pages;
+
+ d_mm = trace_objects_mm_dir();
+ if (!d_mm)
+ return NULL;
+
+ d_pages = debugfs_create_dir("pages", d_mm);
+ if (!d_pages)
+ pr_warning("Could not create debugfs "
+ "'objects/mm/pages' directory\n");
+
+ return d_pages;
+}
+
+static __init int trace_objects_mm_init(void)
+{
+ struct dentry *d_pages;
+
+ d_pages = trace_objects_mm_pages_dir();
+ if (!d_pages)
+ return 0;
+
+ trace_create_file("dump_range", 0600, d_pages, NULL,
+ &trace_mm_fops);
+
+ return 0;
+}
+fs_initcall(trace_objects_mm_init);
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index 8e37fcddd8b4..d53b45ed0806 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -9,6 +9,8 @@
#include <linux/kernel.h>
#include <linux/mmiotrace.h>
#include <linux/pci.h>
+#include <linux/time.h>
+
#include <asm/atomic.h>
#include "trace.h"
@@ -174,7 +176,7 @@ static enum print_line_t mmio_print_rw(struct trace_iterator *iter)
struct mmiotrace_rw *rw;
struct trace_seq *s = &iter->seq;
unsigned long long t = ns2usecs(iter->ts);
- unsigned long usec_rem = do_div(t, 1000000ULL);
+ unsigned long usec_rem = do_div(t, USEC_PER_SEC);
unsigned secs = (unsigned long)t;
int ret = 1;
@@ -221,7 +223,7 @@ static enum print_line_t mmio_print_map(struct trace_iterator *iter)
struct mmiotrace_map *m;
struct trace_seq *s = &iter->seq;
unsigned long long t = ns2usecs(iter->ts);
- unsigned long usec_rem = do_div(t, 1000000ULL);
+ unsigned long usec_rem = do_div(t, USEC_PER_SEC);
unsigned secs = (unsigned long)t;
int ret;
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 64b54a59c55b..8bd9a2c1a46a 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -19,6 +19,16 @@ static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
static int next_event_type = __TRACE_LAST_TYPE + 1;
+void trace_print_seq(struct seq_file *m, struct trace_seq *s)
+{
+ int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
+
+ s->buffer[len] = 0;
+ seq_puts(m, s->buffer);
+
+ trace_seq_init(s);
+}
+
enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter)
{
struct trace_seq *s = &iter->seq;
@@ -84,6 +94,7 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
return len;
}
+EXPORT_SYMBOL_GPL(trace_seq_printf);
int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
{
@@ -472,6 +483,36 @@ struct trace_event *ftrace_find_event(int type)
return NULL;
}
+static LIST_HEAD(ftrace_event_list);
+
+static int trace_search_list(struct list_head **list)
+{
+ struct trace_event *e;
+ int last = __TRACE_LAST_TYPE;
+
+ if (list_empty(&ftrace_event_list)) {
+ *list = &ftrace_event_list;
+ return last + 1;
+ }
+
+ /*
+ * We used up all possible max events,
+ * lets see if somebody freed one.
+ */
+ list_for_each_entry(e, &ftrace_event_list, list) {
+ if (e->type != last + 1)
+ break;
+ last++;
+ }
+
+ /* Did we used up all 65 thousand events??? */
+ if ((last + 1) > FTRACE_MAX_EVENT)
+ return 0;
+
+ *list = &e->list;
+ return last + 1;
+}
+
/**
* register_ftrace_event - register output for an event type
* @event: the event type to register
@@ -494,20 +535,40 @@ int register_ftrace_event(struct trace_event *event)
mutex_lock(&trace_event_mutex);
- if (!event) {
- ret = next_event_type++;
+ if (WARN_ON(!event))
goto out;
- }
- if (!event->type)
- event->type = next_event_type++;
- else if (event->type > __TRACE_LAST_TYPE) {
+ INIT_LIST_HEAD(&event->list);
+
+ if (!event->type) {
+ struct list_head *list = NULL;
+
+ if (next_event_type > FTRACE_MAX_EVENT) {
+
+ event->type = trace_search_list(&list);
+ if (!event->type)
+ goto out;
+
+ } else {
+
+ event->type = next_event_type++;
+ list = &ftrace_event_list;
+ }
+
+ if (WARN_ON(ftrace_find_event(event->type)))
+ goto out;
+
+ list_add_tail(&event->list, list);
+
+ } else if (event->type > __TRACE_LAST_TYPE) {
printk(KERN_WARNING "Need to add type to trace.h\n");
WARN_ON(1);
- }
-
- if (ftrace_find_event(event->type))
goto out;
+ } else {
+ /* Is this event already used */
+ if (ftrace_find_event(event->type))
+ goto out;
+ }
if (event->trace == NULL)
event->trace = trace_nop_print;
@@ -528,6 +589,7 @@ int register_ftrace_event(struct trace_event *event)
return ret;
}
+EXPORT_SYMBOL_GPL(register_ftrace_event);
/**
* unregister_ftrace_event - remove a no longer used event
@@ -537,10 +599,12 @@ int unregister_ftrace_event(struct trace_event *event)
{
mutex_lock(&trace_event_mutex);
hlist_del(&event->node);
+ list_del(&event->list);
mutex_unlock(&trace_event_mutex);
return 0;
}
+EXPORT_SYMBOL_GPL(unregister_ftrace_event);
/*
* Standard events
diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h
index e0bde39c2dd9..6e220a8e5706 100644
--- a/kernel/trace/trace_output.h
+++ b/kernel/trace/trace_output.h
@@ -1,41 +1,17 @@
#ifndef __TRACE_EVENTS_H
#define __TRACE_EVENTS_H
+#include <linux/trace_seq.h>
#include "trace.h"
-typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter,
- int flags);
-
-struct trace_event {
- struct hlist_node node;
- int type;
- trace_print_func trace;
- trace_print_func raw;
- trace_print_func hex;
- trace_print_func binary;
-};
-
extern enum print_line_t
trace_print_bprintk_msg_only(struct trace_iterator *iter);
extern enum print_line_t
trace_print_printk_msg_only(struct trace_iterator *iter);
-extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
- __attribute__ ((format (printf, 2, 3)));
-extern int
-trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
extern int
seq_print_ip_sym(struct trace_seq *s, unsigned long ip,
unsigned long sym_flags);
-extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
- size_t cnt);
-extern int trace_seq_puts(struct trace_seq *s, const char *str);
-extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
-extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len);
-extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
- size_t len);
-extern void *trace_seq_reserve(struct trace_seq *s, size_t len);
-extern int trace_seq_path(struct trace_seq *s, struct path *path);
extern int seq_print_userip_objs(const struct userstack_entry *entry,
struct trace_seq *s, unsigned long sym_flags);
extern int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
@@ -45,8 +21,6 @@ extern int trace_print_context(struct trace_iterator *iter);
extern int trace_print_lat_context(struct trace_iterator *iter);
extern struct trace_event *ftrace_find_event(int type);
-extern int register_ftrace_event(struct trace_event *event);
-extern int unregister_ftrace_event(struct trace_event *event);
extern enum print_line_t trace_nop_print(struct trace_iterator *iter,
int flags);
diff --git a/kernel/trace/trace_power.c b/kernel/trace/trace_power.c
index 118439709fb7..8a30d9874cd4 100644
--- a/kernel/trace/trace_power.c
+++ b/kernel/trace/trace_power.c
@@ -36,6 +36,7 @@ static void probe_power_start(struct power_trace *it, unsigned int type,
static void probe_power_end(struct power_trace *it)
{
+ struct ftrace_event_call *call = &event_power;
struct ring_buffer_event *event;
struct trace_power *entry;
struct trace_array_cpu *data;
@@ -54,7 +55,8 @@ static void probe_power_end(struct power_trace *it)
goto out;
entry = ring_buffer_event_data(event);
entry->state_data = *it;
- trace_buffer_unlock_commit(tr, event, 0, 0);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ trace_buffer_unlock_commit(tr, event, 0, 0);
out:
preempt_enable();
}
@@ -62,6 +64,7 @@ static void probe_power_end(struct power_trace *it)
static void probe_power_mark(struct power_trace *it, unsigned int type,
unsigned int level)
{
+ struct ftrace_event_call *call = &event_power;
struct ring_buffer_event *event;
struct trace_power *entry;
struct trace_array_cpu *data;
@@ -84,7 +87,8 @@ static void probe_power_mark(struct power_trace *it, unsigned int type,
goto out;
entry = ring_buffer_event_data(event);
entry->state_data = *it;
- trace_buffer_unlock_commit(tr, event, 0, 0);
+ if (!filter_check_discard(call, entry, tr->buffer, event))
+ trace_buffer_unlock_commit(tr, event, 0, 0);
out:
preempt_enable();
}
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index eb81556107fe..9bece9687b62 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -245,17 +245,13 @@ static const struct file_operations ftrace_formats_fops = {
static __init int init_trace_printk_function_export(void)
{
struct dentry *d_tracer;
- struct dentry *entry;
d_tracer = tracing_init_dentry();
if (!d_tracer)
return 0;
- entry = debugfs_create_file("printk_formats", 0444, d_tracer,
+ trace_create_file("printk_formats", 0444, d_tracer,
NULL, &ftrace_formats_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'printk_formats' entry\n");
return 0;
}
diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c
index 9117cea6f1ae..a98106dd979c 100644
--- a/kernel/trace/trace_sched_switch.c
+++ b/kernel/trace/trace_sched_switch.c
@@ -10,7 +10,7 @@
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>
-#include <trace/sched.h>
+#include <trace/events/sched.h>
#include "trace.h"
@@ -29,13 +29,13 @@ probe_sched_switch(struct rq *__rq, struct task_struct *prev,
int cpu;
int pc;
- if (!sched_ref || sched_stopped)
+ if (unlikely(!sched_ref))
return;
tracing_record_cmdline(prev);
tracing_record_cmdline(next);
- if (!tracer_enabled)
+ if (!tracer_enabled || sched_stopped)
return;
pc = preempt_count();
@@ -56,15 +56,15 @@ probe_sched_wakeup(struct rq *__rq, struct task_struct *wakee, int success)
unsigned long flags;
int cpu, pc;
- if (!likely(tracer_enabled))
+ if (unlikely(!sched_ref))
return;
- pc = preempt_count();
tracing_record_cmdline(current);
- if (sched_stopped)
+ if (!tracer_enabled || sched_stopped)
return;
+ pc = preempt_count();
local_irq_save(flags);
cpu = raw_smp_processor_id();
data = ctx_trace->data[cpu];
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index 5bc00e8f153e..eacb27225173 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -15,7 +15,7 @@
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>
-#include <trace/sched.h>
+#include <trace/events/sched.h>
#include "trace.h"
@@ -138,9 +138,6 @@ probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
pc = preempt_count();
- /* The task we are waiting for is waking up */
- data = wakeup_trace->data[wakeup_cpu];
-
/* disable local data, not wakeup_cpu data */
cpu = raw_smp_processor_id();
disabled = atomic_inc_return(&wakeup_trace->data[cpu]->disabled);
@@ -154,6 +151,9 @@ probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
if (unlikely(!tracer_enabled || next != wakeup_task))
goto out_unlock;
+ /* The task we are waiting for is waking up */
+ data = wakeup_trace->data[wakeup_cpu];
+
trace_function(wakeup_trace, CALLER_ADDR0, CALLER_ADDR1, flags, pc);
tracing_sched_switch_trace(wakeup_trace, prev, next, flags, pc);
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index 08f4eb2763d1..00dd6485bdd7 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -16,6 +16,7 @@ static inline int trace_valid_entry(struct trace_entry *entry)
case TRACE_BRANCH:
case TRACE_GRAPH_ENT:
case TRACE_GRAPH_RET:
+ case TRACE_HW_BRANCHES:
return 1;
}
return 0;
@@ -188,6 +189,7 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
#else
# define trace_selftest_startup_dynamic_tracing(trace, tr, func) ({ 0; })
#endif /* CONFIG_DYNAMIC_FTRACE */
+
/*
* Simple verification test of ftrace function tracer.
* Enable ftrace, sleep 1/10 second, and then read the trace
@@ -749,3 +751,59 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
return ret;
}
#endif /* CONFIG_BRANCH_TRACER */
+
+#ifdef CONFIG_HW_BRANCH_TRACER
+int
+trace_selftest_startup_hw_branches(struct tracer *trace,
+ struct trace_array *tr)
+{
+ struct trace_iterator *iter;
+ struct tracer tracer;
+ unsigned long count;
+ int ret;
+
+ if (!trace->open) {
+ printk(KERN_CONT "missing open function...");
+ return -1;
+ }
+
+ ret = tracer_init(trace, tr);
+ if (ret) {
+ warn_failed_init_tracer(trace, ret);
+ return ret;
+ }
+
+ /*
+ * The hw-branch tracer needs to collect the trace from the various
+ * cpu trace buffers - before tracing is stopped.
+ */
+ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
+ if (!iter)
+ return -ENOMEM;
+
+ memcpy(&tracer, trace, sizeof(tracer));
+
+ iter->trace = &tracer;
+ iter->tr = tr;
+ iter->pos = -1;
+ mutex_init(&iter->mutex);
+
+ trace->open(iter);
+
+ mutex_destroy(&iter->mutex);
+ kfree(iter);
+
+ tracing_stop();
+
+ ret = trace_test_buffer(tr, &count);
+ trace->reset(tr);
+ tracing_start();
+
+ if (!ret && !count) {
+ printk(KERN_CONT "no entries found..");
+ ret = -1;
+ }
+
+ return ret;
+}
+#endif /* CONFIG_HW_BRANCH_TRACER */
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index c750f65f9661..1796f00524e1 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -352,19 +352,14 @@ __setup("stacktrace", enable_stacktrace);
static __init int stack_trace_init(void)
{
struct dentry *d_tracer;
- struct dentry *entry;
d_tracer = tracing_init_dentry();
- entry = debugfs_create_file("stack_max_size", 0644, d_tracer,
- &max_stack_size, &stack_max_size_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'stack_max_size' entry\n");
+ trace_create_file("stack_max_size", 0644, d_tracer,
+ &max_stack_size, &stack_max_size_fops);
- entry = debugfs_create_file("stack_trace", 0444, d_tracer,
- NULL, &stack_trace_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'stack_trace' entry\n");
+ trace_create_file("stack_trace", 0444, d_tracer,
+ NULL, &stack_trace_fops);
if (stack_tracer_enabled)
register_ftrace_function(&trace_ops);
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
index acdebd771a93..fdde3a4a94cd 100644
--- a/kernel/trace/trace_stat.c
+++ b/kernel/trace/trace_stat.c
@@ -85,7 +85,7 @@ static int stat_seq_init(struct tracer_stat_session *session)
if (!ts->stat_cmp)
ts->stat_cmp = dummy_cmp;
- stat = ts->stat_start();
+ stat = ts->stat_start(ts);
if (!stat)
goto exit;
diff --git a/kernel/trace/trace_stat.h b/kernel/trace/trace_stat.h
index 202274cf7f3d..f3546a2cd826 100644
--- a/kernel/trace/trace_stat.h
+++ b/kernel/trace/trace_stat.h
@@ -12,7 +12,7 @@ struct tracer_stat {
/* The name of your stat file */
const char *name;
/* Iteration over statistic entries */
- void *(*stat_start)(void);
+ void *(*stat_start)(struct tracer_stat *trace);
void *(*stat_next)(void *prev, int idx);
/* Compare two entries for stats sorting */
int (*stat_cmp)(void *p1, void *p2);
diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c
index 91fd19c2149f..e04b76cc238a 100644
--- a/kernel/trace/trace_sysprof.c
+++ b/kernel/trace/trace_sysprof.c
@@ -321,11 +321,7 @@ static const struct file_operations sysprof_sample_fops = {
void init_tracer_sysprof_debugfs(struct dentry *d_tracer)
{
- struct dentry *entry;
- entry = debugfs_create_file("sysprof_sample_period", 0644,
+ trace_create_file("sysprof_sample_period", 0644,
d_tracer, NULL, &sysprof_sample_fops);
- if (entry)
- return;
- pr_warning("Could not create debugfs 'sysprof_sample_period' entry\n");
}
diff --git a/kernel/trace/trace_workqueue.c b/kernel/trace/trace_workqueue.c
index 797201e4a137..984b9175c13d 100644
--- a/kernel/trace/trace_workqueue.c
+++ b/kernel/trace/trace_workqueue.c
@@ -152,7 +152,7 @@ static struct cpu_workqueue_stats *workqueue_stat_start_cpu(int cpu)
return ret;
}
-static void *workqueue_stat_start(void)
+static void *workqueue_stat_start(struct tracer_stat *trace)
{
int cpu;
void *ret = NULL;
diff --git a/kernel/wait.c b/kernel/wait.c
index 42a2dbc181c8..ea7c3b4275cf 100644
--- a/kernel/wait.c
+++ b/kernel/wait.c
@@ -154,7 +154,7 @@ void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait,
if (!list_empty(&wait->task_list))
list_del_init(&wait->task_list);
else if (waitqueue_active(q))
- __wake_up_common(q, mode, 1, 0, key);
+ __wake_up_locked_key(q, mode, key);
spin_unlock_irqrestore(&q->lock, flags);
}
EXPORT_SYMBOL(abort_exclusive_wait);
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 812c28207baf..ee5853ee9bd3 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -336,6 +336,26 @@ config SLUB_STATS
out which slabs are relevant to a particular load.
Try running: slabinfo -DA
+config SLQB_DEBUG
+ default y
+ bool "Enable SLQB debugging support"
+ depends on SLQB
+
+config SLQB_DEBUG_ON
+ default n
+ bool "SLQB debugging on by default"
+ depends on SLQB_DEBUG
+
+config SLQB_SYSFS
+ bool "Create SYSFS entries for slab caches"
+ default n
+ depends on SLQB
+
+config SLQB_STATS
+ bool "Enable SLQB performance statistics"
+ default n
+ depends on SLQB_SYSFS
+
config DEBUG_PREEMPT
bool "Debug preemptible kernel"
depends on DEBUG_KERNEL && PREEMPT && (TRACE_IRQFLAGS_SUPPORT || PPC64)
@@ -891,7 +911,6 @@ config DYNAMIC_DEBUG
default n
depends on PRINTK
depends on DEBUG_FS
- select PRINTK_DEBUG
help
Compiles debug level messages into the kernel, which would not
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 69da09a085a1..cdd205d6bf7c 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -85,6 +85,7 @@ static u32 show_num_errors = 1;
static u32 num_free_entries;
static u32 min_free_entries;
+static u32 nr_total_entries;
/* number of preallocated entries requested by kernel cmdline */
static u32 req_entries;
@@ -257,6 +258,21 @@ static void add_dma_entry(struct dma_debug_entry *entry)
put_hash_bucket(bucket, &flags);
}
+static struct dma_debug_entry *__dma_entry_alloc(void)
+{
+ struct dma_debug_entry *entry;
+
+ entry = list_entry(free_entries.next, struct dma_debug_entry, list);
+ list_del(&entry->list);
+ memset(entry, 0, sizeof(*entry));
+
+ num_free_entries -= 1;
+ if (num_free_entries < min_free_entries)
+ min_free_entries = num_free_entries;
+
+ return entry;
+}
+
/* struct dma_entry allocator
*
* The next two functions implement the allocator for
@@ -276,9 +292,7 @@ static struct dma_debug_entry *dma_entry_alloc(void)
goto out;
}
- entry = list_entry(free_entries.next, struct dma_debug_entry, list);
- list_del(&entry->list);
- memset(entry, 0, sizeof(*entry));
+ entry = __dma_entry_alloc();
#ifdef CONFIG_STACKTRACE
entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES;
@@ -286,9 +300,6 @@ static struct dma_debug_entry *dma_entry_alloc(void)
entry->stacktrace.skip = 2;
save_stack_trace(&entry->stacktrace);
#endif
- num_free_entries -= 1;
- if (num_free_entries < min_free_entries)
- min_free_entries = num_free_entries;
out:
spin_unlock_irqrestore(&free_entries_lock, flags);
@@ -310,6 +321,53 @@ static void dma_entry_free(struct dma_debug_entry *entry)
spin_unlock_irqrestore(&free_entries_lock, flags);
}
+int dma_debug_resize_entries(u32 num_entries)
+{
+ int i, delta, ret = 0;
+ unsigned long flags;
+ struct dma_debug_entry *entry;
+ LIST_HEAD(tmp);
+
+ spin_lock_irqsave(&free_entries_lock, flags);
+
+ if (nr_total_entries < num_entries) {
+ delta = num_entries - nr_total_entries;
+
+ spin_unlock_irqrestore(&free_entries_lock, flags);
+
+ for (i = 0; i < delta; i++) {
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ break;
+
+ list_add_tail(&entry->list, &tmp);
+ }
+
+ spin_lock_irqsave(&free_entries_lock, flags);
+
+ list_splice(&tmp, &free_entries);
+ nr_total_entries += i;
+ num_free_entries += i;
+ } else {
+ delta = nr_total_entries - num_entries;
+
+ for (i = 0; i < delta && !list_empty(&free_entries); i++) {
+ entry = __dma_entry_alloc();
+ kfree(entry);
+ }
+
+ nr_total_entries -= i;
+ }
+
+ if (nr_total_entries != num_entries)
+ ret = 1;
+
+ spin_unlock_irqrestore(&free_entries_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(dma_debug_resize_entries);
+
/*
* DMA-API debugging init code
*
@@ -439,6 +497,8 @@ void dma_debug_init(u32 num_entries)
return;
}
+ nr_total_entries = num_free_entries;
+
printk(KERN_INFO "DMA-API: debugging enabled by kernel config\n");
}
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 2b0b5a7d2ced..bffe6d7ef9d9 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -60,8 +60,8 @@ enum dma_sync_target {
int swiotlb_force;
/*
- * Used to do a quick range check in swiotlb_unmap_single and
- * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
+ * Used to do a quick range check in unmap_single and
+ * sync_single_*, to see if the memory was in fact allocated by this
* API.
*/
static char *io_tlb_start, *io_tlb_end;
@@ -129,7 +129,7 @@ dma_addr_t __weak swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr)
return paddr;
}
-phys_addr_t __weak swiotlb_bus_to_phys(dma_addr_t baddr)
+phys_addr_t __weak swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr)
{
return baddr;
}
@@ -140,9 +140,15 @@ static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev,
return swiotlb_phys_to_bus(hwdev, virt_to_phys(address));
}
-static void *swiotlb_bus_to_virt(dma_addr_t address)
+void * __weak swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t address)
{
- return phys_to_virt(swiotlb_bus_to_phys(address));
+ return phys_to_virt(swiotlb_bus_to_phys(hwdev, address));
+}
+
+int __weak swiotlb_arch_address_needs_mapping(struct device *hwdev,
+ dma_addr_t addr, size_t size)
+{
+ return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size);
}
int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size)
@@ -309,10 +315,10 @@ cleanup1:
return -ENOMEM;
}
-static int
+static inline int
address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size)
{
- return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size);
+ return swiotlb_arch_address_needs_mapping(hwdev, addr, size);
}
static inline int range_needs_mapping(phys_addr_t paddr, size_t size)
@@ -341,7 +347,7 @@ static void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size,
unsigned long flags;
while (size) {
- sz = min(PAGE_SIZE - offset, size);
+ sz = min_t(size_t, PAGE_SIZE - offset, size);
local_irq_save(flags);
buffer = kmap_atomic(pfn_to_page(pfn),
@@ -476,7 +482,7 @@ found:
* dma_addr is the kernel virtual address of the bounce buffer to unmap.
*/
static void
-unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
+do_unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
{
unsigned long flags;
int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
@@ -560,7 +566,6 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
size)) {
/*
* The allocated memory isn't reachable by the device.
- * Fall back on swiotlb_map_single().
*/
free_pages((unsigned long) ret, order);
ret = NULL;
@@ -568,9 +573,8 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
if (!ret) {
/*
* We are either out of memory or the device can't DMA
- * to GFP_DMA memory; fall back on
- * swiotlb_map_single(), which will grab memory from
- * the lowest available address range.
+ * to GFP_DMA memory; fall back on map_single(), which
+ * will grab memory from the lowest available address range.
*/
ret = map_single(hwdev, 0, size, DMA_FROM_DEVICE);
if (!ret)
@@ -587,7 +591,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
(unsigned long long)dev_addr);
/* DMA_TO_DEVICE to avoid memcpy in unmap_single */
- unmap_single(hwdev, ret, size, DMA_TO_DEVICE);
+ do_unmap_single(hwdev, ret, size, DMA_TO_DEVICE);
return NULL;
}
*dma_handle = dev_addr;
@@ -604,7 +608,7 @@ swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
free_pages((unsigned long) vaddr, get_order(size));
else
/* DMA_TO_DEVICE to avoid memcpy in unmap_single */
- unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE);
+ do_unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE);
}
EXPORT_SYMBOL(swiotlb_free_coherent);
@@ -634,7 +638,7 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
* physical address to use is returned.
*
* Once the device is given the dma address, the device owns this memory until
- * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed.
+ * either swiotlb_unmap_page or swiotlb_dma_sync_single is performed.
*/
dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
@@ -642,18 +646,17 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
struct dma_attrs *attrs)
{
phys_addr_t phys = page_to_phys(page) + offset;
- void *ptr = page_address(page) + offset;
dma_addr_t dev_addr = swiotlb_phys_to_bus(dev, phys);
void *map;
BUG_ON(dir == DMA_NONE);
/*
- * If the pointer passed in happens to be in the device's DMA window,
+ * If the address happens to be in the device's DMA window,
* we can safely return the device addr and not worry about bounce
* buffering it.
*/
if (!address_needs_mapping(dev, dev_addr, size) &&
- !range_needs_mapping(virt_to_phys(ptr), size))
+ !range_needs_mapping(phys, size))
return dev_addr;
/*
@@ -679,23 +682,35 @@ EXPORT_SYMBOL_GPL(swiotlb_map_page);
/*
* Unmap a single streaming mode DMA translation. The dma_addr and size must
- * match what was provided for in a previous swiotlb_map_single call. All
+ * match what was provided for in a previous swiotlb_map_page call. All
* other usages are undefined.
*
* After this call, reads by the cpu to the buffer are guaranteed to see
* whatever the device wrote there.
*/
+static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
+ size_t size, int dir)
+{
+ char *dma_addr = swiotlb_bus_to_virt(hwdev, dev_addr);
+
+ BUG_ON(dir == DMA_NONE);
+
+ if (is_swiotlb_buffer(dma_addr)) {
+ do_unmap_single(hwdev, dma_addr, size, dir);
+ return;
+ }
+
+ if (dir != DMA_FROM_DEVICE)
+ return;
+
+ dma_mark_clean(dma_addr, size);
+}
+
void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
size_t size, enum dma_data_direction dir,
struct dma_attrs *attrs)
{
- char *dma_addr = swiotlb_bus_to_virt(dev_addr);
-
- BUG_ON(dir == DMA_NONE);
- if (is_swiotlb_buffer(dma_addr))
- unmap_single(hwdev, dma_addr, size, dir);
- else if (dir == DMA_FROM_DEVICE)
- dma_mark_clean(dma_addr, size);
+ unmap_single(hwdev, dev_addr, size, dir);
}
EXPORT_SYMBOL_GPL(swiotlb_unmap_page);
@@ -703,7 +718,7 @@ EXPORT_SYMBOL_GPL(swiotlb_unmap_page);
* Make physical memory consistent for a single streaming mode DMA translation
* after a transfer.
*
- * If you perform a swiotlb_map_single() but wish to interrogate the buffer
+ * If you perform a swiotlb_map_page() but wish to interrogate the buffer
* using the cpu, yet do not wish to teardown the dma mapping, you must
* call this function before doing so. At the next point you give the dma
* address back to the card, you must first perform a
@@ -713,13 +728,19 @@ static void
swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,
size_t size, int dir, int target)
{
- char *dma_addr = swiotlb_bus_to_virt(dev_addr);
+ char *dma_addr = swiotlb_bus_to_virt(hwdev, dev_addr);
BUG_ON(dir == DMA_NONE);
- if (is_swiotlb_buffer(dma_addr))
+
+ if (is_swiotlb_buffer(dma_addr)) {
sync_single(hwdev, dma_addr, size, dir, target);
- else if (dir == DMA_FROM_DEVICE)
- dma_mark_clean(dma_addr, size);
+ return;
+ }
+
+ if (dir != DMA_FROM_DEVICE)
+ return;
+
+ dma_mark_clean(dma_addr, size);
}
void
@@ -746,13 +767,7 @@ swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr,
unsigned long offset, size_t size,
int dir, int target)
{
- char *dma_addr = swiotlb_bus_to_virt(dev_addr) + offset;
-
- BUG_ON(dir == DMA_NONE);
- if (is_swiotlb_buffer(dma_addr))
- sync_single(hwdev, dma_addr, size, dir, target);
- else if (dir == DMA_FROM_DEVICE)
- dma_mark_clean(dma_addr, size);
+ swiotlb_sync_single(hwdev, dev_addr + offset, size, dir, target);
}
void
@@ -777,7 +792,7 @@ EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device);
/*
* Map a set of buffers described by scatterlist in streaming mode for DMA.
- * This is the scatter-gather version of the above swiotlb_map_single
+ * This is the scatter-gather version of the above swiotlb_map_page
* interface. Here the scatter gather list elements are each tagged with the
* appropriate dma address and length. They are obtained via
* sg_dma_{address,length}(SG).
@@ -788,7 +803,7 @@ EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device);
* The routine returns the number of addr/length pairs actually
* used, at most nents.
*
- * Device ownership issues as mentioned above for swiotlb_map_single are the
+ * Device ownership issues as mentioned above for swiotlb_map_page are the
* same here.
*/
int
@@ -836,7 +851,7 @@ EXPORT_SYMBOL(swiotlb_map_sg);
/*
* Unmap a set of streaming mode DMA translations. Again, cpu read rules
- * concerning calls here are the same as for swiotlb_unmap_single() above.
+ * concerning calls here are the same as for swiotlb_unmap_page() above.
*/
void
swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
@@ -847,13 +862,9 @@ swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
BUG_ON(dir == DMA_NONE);
- for_each_sg(sgl, sg, nelems, i) {
- if (sg->dma_address != swiotlb_phys_to_bus(hwdev, sg_phys(sg)))
- unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address),
- sg->dma_length, dir);
- else if (dir == DMA_FROM_DEVICE)
- dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length);
- }
+ for_each_sg(sgl, sg, nelems, i)
+ unmap_single(hwdev, sg->dma_address, sg->dma_length, dir);
+
}
EXPORT_SYMBOL(swiotlb_unmap_sg_attrs);
@@ -879,15 +890,9 @@ swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sgl,
struct scatterlist *sg;
int i;
- BUG_ON(dir == DMA_NONE);
-
- for_each_sg(sgl, sg, nelems, i) {
- if (sg->dma_address != swiotlb_phys_to_bus(hwdev, sg_phys(sg)))
- sync_single(hwdev, swiotlb_bus_to_virt(sg->dma_address),
+ for_each_sg(sgl, sg, nelems, i)
+ swiotlb_sync_single(hwdev, sg->dma_address,
sg->dma_length, dir, target);
- else if (dir == DMA_FROM_DEVICE)
- dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length);
- }
}
void
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 7536acea135b..756ccafa9cec 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -408,6 +408,8 @@ enum format_type {
FORMAT_TYPE_LONG_LONG,
FORMAT_TYPE_ULONG,
FORMAT_TYPE_LONG,
+ FORMAT_TYPE_UBYTE,
+ FORMAT_TYPE_BYTE,
FORMAT_TYPE_USHORT,
FORMAT_TYPE_SHORT,
FORMAT_TYPE_UINT,
@@ -573,12 +575,15 @@ static char *string(char *buf, char *end, char *s, struct printf_spec spec)
}
static char *symbol_string(char *buf, char *end, void *ptr,
- struct printf_spec spec)
+ struct printf_spec spec, char ext)
{
unsigned long value = (unsigned long) ptr;
#ifdef CONFIG_KALLSYMS
char sym[KSYM_SYMBOL_LEN];
- sprint_symbol(sym, value);
+ if (ext != 'f')
+ sprint_symbol(sym, value);
+ else
+ kallsyms_lookup(value, NULL, NULL, NULL, sym);
return string(buf, end, sym, spec);
#else
spec.field_width = 2*sizeof(void *);
@@ -690,7 +695,8 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr,
*
* Right now we handle:
*
- * - 'F' For symbolic function descriptor pointers
+ * - 'F' For symbolic function descriptor pointers with offset
+ * - 'f' For simple symbolic function names without offset
* - 'S' For symbolic direct pointers
* - 'R' For a struct resource pointer, it prints the range of
* addresses (not the name nor the flags)
@@ -713,10 +719,11 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
switch (*fmt) {
case 'F':
+ case 'f':
ptr = dereference_function_descriptor(ptr);
/* Fallthrough */
case 'S':
- return symbol_string(buf, end, ptr, spec);
+ return symbol_string(buf, end, ptr, spec, *fmt);
case 'R':
return resource_string(buf, end, ptr, spec);
case 'm':
@@ -853,11 +860,15 @@ qualifier:
spec->qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
*fmt == 'Z' || *fmt == 'z' || *fmt == 't') {
- spec->qualifier = *fmt;
- ++fmt;
- if (spec->qualifier == 'l' && *fmt == 'l') {
- spec->qualifier = 'L';
- ++fmt;
+ spec->qualifier = *fmt++;
+ if (unlikely(spec->qualifier == *fmt)) {
+ if (spec->qualifier == 'l') {
+ spec->qualifier = 'L';
+ ++fmt;
+ } else if (spec->qualifier == 'h') {
+ spec->qualifier = 'H';
+ ++fmt;
+ }
}
}
@@ -919,6 +930,11 @@ qualifier:
spec->type = FORMAT_TYPE_SIZE_T;
} else if (spec->qualifier == 't') {
spec->type = FORMAT_TYPE_PTRDIFF;
+ } else if (spec->qualifier == 'H') {
+ if (spec->flags & SIGN)
+ spec->type = FORMAT_TYPE_BYTE;
+ else
+ spec->type = FORMAT_TYPE_UBYTE;
} else if (spec->qualifier == 'h') {
if (spec->flags & SIGN)
spec->type = FORMAT_TYPE_SHORT;
@@ -943,7 +959,8 @@ qualifier:
*
* This function follows C99 vsnprintf, but has some extensions:
* %pS output the name of a text symbol
- * %pF output the name of a function pointer
+ * %pF output the name of a function pointer with its offset
+ * %pf output the name of a function pointer without its offset
* %pR output the address range in a struct resource
*
* The return value is the number of characters which would
@@ -1087,6 +1104,12 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
case FORMAT_TYPE_PTRDIFF:
num = va_arg(args, ptrdiff_t);
break;
+ case FORMAT_TYPE_UBYTE:
+ num = (unsigned char) va_arg(args, int);
+ break;
+ case FORMAT_TYPE_BYTE:
+ num = (signed char) va_arg(args, int);
+ break;
case FORMAT_TYPE_USHORT:
num = (unsigned short) va_arg(args, int);
break;
@@ -1363,6 +1386,10 @@ do { \
case FORMAT_TYPE_PTRDIFF:
save_arg(ptrdiff_t);
break;
+ case FORMAT_TYPE_UBYTE:
+ case FORMAT_TYPE_BYTE:
+ save_arg(char);
+ break;
case FORMAT_TYPE_USHORT:
case FORMAT_TYPE_SHORT:
save_arg(short);
@@ -1391,7 +1418,8 @@ EXPORT_SYMBOL_GPL(vbin_printf);
*
* The format follows C99 vsnprintf, but has some extensions:
* %pS output the name of a text symbol
- * %pF output the name of a function pointer
+ * %pF output the name of a function pointer with its offset
+ * %pf output the name of a function pointer without its offset
* %pR output the address range in a struct resource
* %n is ignored
*
@@ -1538,6 +1566,12 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
case FORMAT_TYPE_PTRDIFF:
num = get_arg(ptrdiff_t);
break;
+ case FORMAT_TYPE_UBYTE:
+ num = get_arg(unsigned char);
+ break;
+ case FORMAT_TYPE_BYTE:
+ num = get_arg(signed char);
+ break;
case FORMAT_TYPE_USHORT:
num = get_arg(unsigned short);
break;
diff --git a/mm/Kconfig b/mm/Kconfig
index 57971d2ab848..c2b57d81e153 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -225,3 +225,31 @@ config HAVE_MLOCKED_PAGE_BIT
config MMU_NOTIFIER
bool
+
+config NOMMU_INITIAL_TRIM_EXCESS
+ int "Turn on mmap() excess space trimming before booting"
+ depends on !MMU
+ default 1
+ help
+ The NOMMU mmap() frequently needs to allocate large contiguous chunks
+ of memory on which to store mappings, but it can only ask the system
+ allocator for chunks in 2^N*PAGE_SIZE amounts - which is frequently
+ more than it requires. To deal with this, mmap() is able to trim off
+ the excess and return it to the allocator.
+
+ If trimming is enabled, the excess is trimmed off and returned to the
+ system allocator, which can cause extra fragmentation, particularly
+ if there are a lot of transient processes.
+
+ If trimming is disabled, the excess is kept, but not used, which for
+ long-term mappings means that the space is wasted.
+
+ Trimming can be dynamically controlled through a sysctl option
+ (/proc/sys/vm/nr_trim_pages) which specifies the minimum number of
+ excess pages there must be before trimming should occur, or zero if
+ no trimming is to occur.
+
+ This option specifies the initial value of this option. The default
+ of 1 says that all excess pages should be trimmed.
+
+ See Documentation/nommu-mmap.txt for more information.
diff --git a/mm/Makefile b/mm/Makefile
index ec73c68b6015..cd639cd25f1a 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o
obj-$(CONFIG_PAGE_POISONING) += debug-pagealloc.o
obj-$(CONFIG_SLAB) += slab.o
obj-$(CONFIG_SLUB) += slub.o
+obj-$(CONFIG_SLQB) += slqb.o
obj-$(CONFIG_FAILSLAB) += failslab.o
obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
obj-$(CONFIG_FS_XIP) += filemap_xip.o
diff --git a/mm/madvise.c b/mm/madvise.c
index 36d6ea2b6340..b9ce574827c8 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -112,14 +112,6 @@ static long madvise_willneed(struct vm_area_struct * vma,
if (!file)
return -EBADF;
- /*
- * Page cache readahead assumes page cache pages are order-0 which
- * is not the case for hugetlbfs. Do not give a bad return value
- * but ignore the advice.
- */
- if (vma->vm_flags & VM_HUGETLB)
- return 0;
-
if (file->f_mapping->a_ops->get_xip_mem) {
/* no bad return value, but ignore advice */
return 0;
diff --git a/mm/mlock.c b/mm/mlock.c
index cbe9e0581b75..ac130433c7d3 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -629,52 +629,43 @@ void user_shm_unlock(size_t size, struct user_struct *user)
free_uid(user);
}
-void *alloc_locked_buffer(size_t size)
+int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
+ size_t size)
{
- unsigned long rlim, vm, pgsz;
- void *buffer = NULL;
+ unsigned long lim, vm, pgsz;
+ int error = -ENOMEM;
pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
- down_write(&current->mm->mmap_sem);
-
- rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
- vm = current->mm->total_vm + pgsz;
- if (rlim < vm)
- goto out;
+ down_write(&mm->mmap_sem);
- rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
- vm = current->mm->locked_vm + pgsz;
- if (rlim < vm)
+ lim = rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
+ vm = mm->total_vm + pgsz;
+ if (lim < vm)
goto out;
- buffer = kzalloc(size, GFP_KERNEL);
- if (!buffer)
+ lim = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+ vm = mm->locked_vm + pgsz;
+ if (lim < vm)
goto out;
- current->mm->total_vm += pgsz;
- current->mm->locked_vm += pgsz;
+ mm->total_vm += pgsz;
+ mm->locked_vm += pgsz;
+ error = 0;
out:
- up_write(&current->mm->mmap_sem);
- return buffer;
+ up_write(&mm->mmap_sem);
+ return error;
}
-void release_locked_buffer(void *buffer, size_t size)
+void refund_locked_memory(struct mm_struct *mm, size_t size)
{
unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
- down_write(&current->mm->mmap_sem);
-
- current->mm->total_vm -= pgsz;
- current->mm->locked_vm -= pgsz;
-
- up_write(&current->mm->mmap_sem);
-}
+ down_write(&mm->mmap_sem);
-void free_locked_buffer(void *buffer, size_t size)
-{
- release_locked_buffer(buffer, size);
+ mm->total_vm -= pgsz;
+ mm->locked_vm -= pgsz;
- kfree(buffer);
+ up_write(&mm->mmap_sem);
}
diff --git a/mm/nommu.c b/mm/nommu.c
index 809998aa7b50..b571ef707428 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -66,7 +66,7 @@ struct percpu_counter vm_committed_as;
int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
int sysctl_overcommit_ratio = 50; /* default is 50% */
int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
-int sysctl_nr_trim_pages = 1; /* page trimming behaviour */
+int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
int heap_stack_gap = 0;
atomic_long_t mmap_pages_allocated;
@@ -515,8 +515,6 @@ static void add_nommu_region(struct vm_region *region)
validate_nommu_regions();
- BUG_ON(region->vm_start & ~PAGE_MASK);
-
parent = NULL;
p = &nommu_region_tree.rb_node;
while (*p) {
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 2f3166e308d9..92bcf1db16b2 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -514,34 +514,32 @@ void clear_zonelist_oom(struct zonelist *zonelist, gfp_t gfp_mask)
*/
static void __out_of_memory(gfp_t gfp_mask, int order)
{
- if (sysctl_oom_kill_allocating_task) {
- oom_kill_process(current, gfp_mask, order, 0, NULL,
- "Out of memory (oom_kill_allocating_task)");
-
- } else {
- unsigned long points;
- struct task_struct *p;
-
-retry:
- /*
- * Rambo mode: Shoot down a process and hope it solves whatever
- * issues we may have.
- */
- p = select_bad_process(&points, NULL);
+ struct task_struct *p;
+ unsigned long points;
- if (PTR_ERR(p) == -1UL)
+ if (sysctl_oom_kill_allocating_task)
+ if (!oom_kill_process(current, gfp_mask, order, 0, NULL,
+ "Out of memory (oom_kill_allocating_task)"))
return;
+retry:
+ /*
+ * Rambo mode: Shoot down a process and hope it solves whatever
+ * issues we may have.
+ */
+ p = select_bad_process(&points, NULL);
- /* Found nothing?!?! Either we hang forever, or we panic. */
- if (!p) {
- read_unlock(&tasklist_lock);
- panic("Out of memory and no killable processes...\n");
- }
+ if (PTR_ERR(p) == -1UL)
+ return;
- if (oom_kill_process(p, gfp_mask, order, points, NULL,
- "Out of memory"))
- goto retry;
+ /* Found nothing?!?! Either we hang forever, or we panic. */
+ if (!p) {
+ read_unlock(&tasklist_lock);
+ panic("Out of memory and no killable processes...\n");
}
+
+ if (oom_kill_process(p, gfp_mask, order, points, NULL,
+ "Out of memory"))
+ goto retry;
}
/*
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e2f26991fff1..fe753ecf2aa5 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2681,6 +2681,7 @@ static void __meminit zone_init_free_lists(struct zone *zone)
static int zone_batchsize(struct zone *zone)
{
+#ifdef CONFIG_MMU
int batch;
/*
@@ -2706,9 +2707,26 @@ static int zone_batchsize(struct zone *zone)
* of pages of one half of the possible page colors
* and the other with pages of the other colors.
*/
- batch = (1 << (fls(batch + batch/2)-1)) - 1;
+ batch = rounddown_pow_of_two(batch + batch/2) - 1;
return batch;
+
+#else
+ /* The deferral and batching of frees should be suppressed under NOMMU
+ * conditions.
+ *
+ * The problem is that NOMMU needs to be able to allocate large chunks
+ * of contiguous memory as there's no hardware page translation to
+ * assemble apparent contiguous memory from discontiguous pages.
+ *
+ * Queueing large contiguous runs of pages for batching, however,
+ * causes the pages to actually be freed in smaller chunks. As there
+ * can be a significant delay between the individual batches being
+ * recycled, this leads to the once large chunks of space being
+ * fragmented and becoming unavailable for high-order allocations.
+ */
+ return 0;
+#endif
}
static void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
diff --git a/mm/percpu.c b/mm/percpu.c
index 1aa5d8fbca12..c0b2c1a76e81 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -23,7 +23,7 @@
* Allocation is done in offset-size areas of single unit space. Ie,
* an area of 512 bytes at 6k in c1 occupies 512 bytes at 6k of c1:u0,
* c1:u1, c1:u2 and c1:u3. Percpu access can be done by configuring
- * percpu base registers UNIT_SIZE apart.
+ * percpu base registers pcpu_unit_size apart.
*
* There are usually many small percpu allocations many of them as
* small as 4 bytes. The allocator organizes chunks into lists
@@ -38,8 +38,8 @@
* region and negative allocated. Allocation inside a chunk is done
* by scanning this map sequentially and serving the first matching
* entry. This is mostly copied from the percpu_modalloc() allocator.
- * Chunks are also linked into a rb tree to ease address to chunk
- * mapping during free.
+ * Chunks can be determined from the address using the index field
+ * in the page struct. The index field contains a pointer to the chunk.
*
* To use this allocator, arch code should do the followings.
*
@@ -61,7 +61,6 @@
#include <linux/mutex.h>
#include <linux/percpu.h>
#include <linux/pfn.h>
-#include <linux/rbtree.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/vmalloc.h>
@@ -88,7 +87,6 @@
struct pcpu_chunk {
struct list_head list; /* linked to pcpu_slot lists */
- struct rb_node rb_node; /* key is chunk->vm->addr */
int free_size; /* free bytes in the chunk */
int contig_hint; /* max contiguous size hint */
struct vm_struct *vm; /* mapped vmalloc region */
@@ -110,9 +108,21 @@ static size_t pcpu_chunk_struct_size __read_mostly;
void *pcpu_base_addr __read_mostly;
EXPORT_SYMBOL_GPL(pcpu_base_addr);
-/* optional reserved chunk, only accessible for reserved allocations */
+/*
+ * The first chunk which always exists. Note that unlike other
+ * chunks, this one can be allocated and mapped in several different
+ * ways and thus often doesn't live in the vmalloc area.
+ */
+static struct pcpu_chunk *pcpu_first_chunk;
+
+/*
+ * Optional reserved chunk. This chunk reserves part of the first
+ * chunk and serves it for reserved allocations. The amount of
+ * reserved offset is in pcpu_reserved_chunk_limit. When reserved
+ * area doesn't exist, the following variables contain NULL and 0
+ * respectively.
+ */
static struct pcpu_chunk *pcpu_reserved_chunk;
-/* offset limit of the reserved chunk */
static int pcpu_reserved_chunk_limit;
/*
@@ -121,7 +131,7 @@ static int pcpu_reserved_chunk_limit;
* There are two locks - pcpu_alloc_mutex and pcpu_lock. The former
* protects allocation/reclaim paths, chunks and chunk->page arrays.
* The latter is a spinlock and protects the index data structures -
- * chunk slots, rbtree, chunks and area maps in chunks.
+ * chunk slots, chunks and area maps in chunks.
*
* During allocation, pcpu_alloc_mutex is kept locked all the time and
* pcpu_lock is grabbed and released as necessary. All actual memory
@@ -140,7 +150,6 @@ static DEFINE_MUTEX(pcpu_alloc_mutex); /* protects whole alloc and reclaim */
static DEFINE_SPINLOCK(pcpu_lock); /* protects index data structures */
static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
-static struct rb_root pcpu_addr_root = RB_ROOT; /* chunks by address */
/* reclaim work to release fully free chunks, scheduled from free path */
static void pcpu_reclaim(struct work_struct *work);
@@ -191,6 +200,18 @@ static bool pcpu_chunk_page_occupied(struct pcpu_chunk *chunk,
return *pcpu_chunk_pagep(chunk, 0, page_idx) != NULL;
}
+/* set the pointer to a chunk in a page struct */
+static void pcpu_set_page_chunk(struct page *page, struct pcpu_chunk *pcpu)
+{
+ page->index = (unsigned long)pcpu;
+}
+
+/* obtain pointer to a chunk from a page struct */
+static struct pcpu_chunk *pcpu_get_page_chunk(struct page *page)
+{
+ return (struct pcpu_chunk *)page->index;
+}
+
/**
* pcpu_mem_alloc - allocate memory
* @size: bytes to allocate
@@ -257,93 +278,26 @@ static void pcpu_chunk_relocate(struct pcpu_chunk *chunk, int oslot)
}
}
-static struct rb_node **pcpu_chunk_rb_search(void *addr,
- struct rb_node **parentp)
-{
- struct rb_node **p = &pcpu_addr_root.rb_node;
- struct rb_node *parent = NULL;
- struct pcpu_chunk *chunk;
-
- while (*p) {
- parent = *p;
- chunk = rb_entry(parent, struct pcpu_chunk, rb_node);
-
- if (addr < chunk->vm->addr)
- p = &(*p)->rb_left;
- else if (addr > chunk->vm->addr)
- p = &(*p)->rb_right;
- else
- break;
- }
-
- if (parentp)
- *parentp = parent;
- return p;
-}
-
/**
- * pcpu_chunk_addr_search - search for chunk containing specified address
- * @addr: address to search for
- *
- * Look for chunk which might contain @addr. More specifically, it
- * searchs for the chunk with the highest start address which isn't
- * beyond @addr.
- *
- * CONTEXT:
- * pcpu_lock.
+ * pcpu_chunk_addr_search - determine chunk containing specified address
+ * @addr: address for which the chunk needs to be determined.
*
* RETURNS:
* The address of the found chunk.
*/
static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr)
{
- struct rb_node *n, *parent;
- struct pcpu_chunk *chunk;
+ void *first_start = pcpu_first_chunk->vm->addr;
- /* is it in the reserved chunk? */
- if (pcpu_reserved_chunk) {
- void *start = pcpu_reserved_chunk->vm->addr;
-
- if (addr >= start && addr < start + pcpu_reserved_chunk_limit)
+ /* is it in the first chunk? */
+ if (addr >= first_start && addr < first_start + pcpu_chunk_size) {
+ /* is it in the reserved area? */
+ if (addr < first_start + pcpu_reserved_chunk_limit)
return pcpu_reserved_chunk;
+ return pcpu_first_chunk;
}
- /* nah... search the regular ones */
- n = *pcpu_chunk_rb_search(addr, &parent);
- if (!n) {
- /* no exactly matching chunk, the parent is the closest */
- n = parent;
- BUG_ON(!n);
- }
- chunk = rb_entry(n, struct pcpu_chunk, rb_node);
-
- if (addr < chunk->vm->addr) {
- /* the parent was the next one, look for the previous one */
- n = rb_prev(n);
- BUG_ON(!n);
- chunk = rb_entry(n, struct pcpu_chunk, rb_node);
- }
-
- return chunk;
-}
-
-/**
- * pcpu_chunk_addr_insert - insert chunk into address rb tree
- * @new: chunk to insert
- *
- * Insert @new into address rb tree.
- *
- * CONTEXT:
- * pcpu_lock.
- */
-static void pcpu_chunk_addr_insert(struct pcpu_chunk *new)
-{
- struct rb_node **p, *parent;
-
- p = pcpu_chunk_rb_search(new->vm->addr, &parent);
- BUG_ON(*p);
- rb_link_node(&new->rb_node, parent, p);
- rb_insert_color(&new->rb_node, &pcpu_addr_root);
+ return pcpu_get_page_chunk(vmalloc_to_page(addr));
}
/**
@@ -755,6 +709,7 @@ static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size)
alloc_mask, 0);
if (!*pagep)
goto err;
+ pcpu_set_page_chunk(*pagep, chunk);
}
}
@@ -879,7 +834,6 @@ restart:
spin_lock_irq(&pcpu_lock);
pcpu_chunk_relocate(chunk, -1);
- pcpu_chunk_addr_insert(chunk);
goto restart;
area_found:
@@ -968,7 +922,6 @@ static void pcpu_reclaim(struct work_struct *work)
if (chunk == list_first_entry(head, struct pcpu_chunk, list))
continue;
- rb_erase(&chunk->rb_node, &pcpu_addr_root);
list_move(&chunk->list, &todo);
}
@@ -1147,7 +1100,8 @@ size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn,
if (reserved_size) {
schunk->free_size = reserved_size;
- pcpu_reserved_chunk = schunk; /* not for dynamic alloc */
+ pcpu_reserved_chunk = schunk;
+ pcpu_reserved_chunk_limit = static_size + reserved_size;
} else {
schunk->free_size = dyn_size;
dyn_size = 0; /* dynamic area covered */
@@ -1158,8 +1112,6 @@ size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn,
if (schunk->free_size)
schunk->map[schunk->map_used++] = schunk->free_size;
- pcpu_reserved_chunk_limit = static_size + schunk->free_size;
-
/* init dynamic chunk if necessary */
if (dyn_size) {
dchunk = alloc_bootmem(sizeof(struct pcpu_chunk));
@@ -1226,13 +1178,8 @@ size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn,
}
/* link the first chunk in */
- if (!dchunk) {
- pcpu_chunk_relocate(schunk, -1);
- pcpu_chunk_addr_insert(schunk);
- } else {
- pcpu_chunk_relocate(dchunk, -1);
- pcpu_chunk_addr_insert(dchunk);
- }
+ pcpu_first_chunk = dchunk ?: schunk;
+ pcpu_chunk_relocate(pcpu_first_chunk, -1);
/* we're done */
pcpu_base_addr = (void *)pcpu_chunk_addr(schunk, 0, 0);
diff --git a/mm/slab.c b/mm/slab.c
index 9a90b00d2f91..f85831da9080 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -102,7 +102,7 @@
#include <linux/cpu.h>
#include <linux/sysctl.h>
#include <linux/module.h>
-#include <trace/kmemtrace.h>
+#include <linux/kmemtrace.h>
#include <linux/rcupdate.h>
#include <linux/string.h>
#include <linux/uaccess.h>
diff --git a/mm/slob.c b/mm/slob.c
index a2d4ab32198d..9aae0b5969c0 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -60,12 +60,13 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
+#include <linux/swap.h> /* struct reclaim_state */
#include <linux/cache.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
-#include <trace/kmemtrace.h>
+#include <linux/kmemtrace.h>
#include <asm/atomic.h>
/*
@@ -131,17 +132,17 @@ static LIST_HEAD(free_slob_large);
*/
static inline int is_slob_page(struct slob_page *sp)
{
- return PageSlobPage((struct page *)sp);
+ return PageSlab((struct page *)sp);
}
static inline void set_slob_page(struct slob_page *sp)
{
- __SetPageSlobPage((struct page *)sp);
+ __SetPageSlab((struct page *)sp);
}
static inline void clear_slob_page(struct slob_page *sp)
{
- __ClearPageSlobPage((struct page *)sp);
+ __ClearPageSlab((struct page *)sp);
}
static inline struct slob_page *slob_page(const void *addr)
@@ -255,6 +256,8 @@ static void *slob_new_pages(gfp_t gfp, int order, int node)
static void slob_free_pages(void *b, int order)
{
+ if (current->reclaim_state)
+ current->reclaim_state->reclaimed_slab += 1 << order;
free_pages((unsigned long)b, order);
}
@@ -407,7 +410,7 @@ static void slob_free(void *block, int size)
spin_unlock_irqrestore(&slob_lock, flags);
clear_slob_page(sp);
free_slob_page(sp);
- free_page((unsigned long)b);
+ slob_free_pages(b, 0);
return;
}
diff --git a/mm/slqb.c b/mm/slqb.c
new file mode 100644
index 000000000000..5d0642fb6f01
--- /dev/null
+++ b/mm/slqb.c
@@ -0,0 +1,3746 @@
+/*
+ * SLQB: A slab allocator that focuses on per-CPU scaling, and good performance
+ * with order-0 allocations. Fastpaths emphasis is placed on local allocaiton
+ * and freeing, but with a secondary goal of good remote freeing (freeing on
+ * another CPU from that which allocated).
+ *
+ * Using ideas and code from mm/slab.c, mm/slob.c, and mm/slub.c.
+ */
+
+#include <linux/mm.h>
+#include <linux/swap.h> /* struct reclaim_state */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/cpuset.h>
+#include <linux/mempolicy.h>
+#include <linux/ctype.h>
+#include <linux/kallsyms.h>
+#include <linux/memory.h>
+
+/*
+ * TODO
+ * - fix up releasing of offlined data structures. Not a big deal because
+ * they don't get cumulatively leaked with successive online/offline cycles
+ * - allow OOM conditions to flush back per-CPU pages to common lists to be
+ * reused by other CPUs.
+ * - investiage performance with memoryless nodes. Perhaps CPUs can be given
+ * a default closest home node via which it can use fastpath functions.
+ * Perhaps it is not a big problem.
+ */
+
+/*
+ * slqb_page overloads struct page, and is used to manage some slob allocation
+ * aspects, however to avoid the horrible mess in include/linux/mm_types.h,
+ * we'll just define our own struct slqb_page type variant here.
+ */
+struct slqb_page {
+ union {
+ struct {
+ unsigned long flags; /* mandatory */
+ atomic_t _count; /* mandatory */
+ unsigned int inuse; /* Nr of objects */
+ struct kmem_cache_list *list; /* Pointer to list */
+ void **freelist; /* LIFO freelist */
+ union {
+ struct list_head lru; /* misc. list */
+ struct rcu_head rcu_head; /* for rcu freeing */
+ };
+ };
+ struct page page;
+ };
+};
+static inline void struct_slqb_page_wrong_size(void)
+{ BUILD_BUG_ON(sizeof(struct slqb_page) != sizeof(struct page)); }
+
+#define PG_SLQB_BIT (1 << PG_slab)
+
+/*
+ * slqb_min_order: minimum allocation order for slabs
+ */
+static int slqb_min_order;
+
+/*
+ * slqb_min_objects: minimum number of objects per slab. Increasing this
+ * will increase the allocation order for slabs with larger objects
+ */
+static int slqb_min_objects = 1;
+
+#ifdef CONFIG_NUMA
+static inline int slab_numa(struct kmem_cache *s)
+{
+ return s->flags & SLAB_NUMA;
+}
+#else
+static inline int slab_numa(struct kmem_cache *s)
+{
+ return 0;
+}
+#endif
+
+static inline int slab_hiwater(struct kmem_cache *s)
+{
+ return s->hiwater;
+}
+
+static inline int slab_freebatch(struct kmem_cache *s)
+{
+ return s->freebatch;
+}
+
+/*
+ * Lock order:
+ * kmem_cache_node->list_lock
+ * kmem_cache_remote_free->lock
+ *
+ * Data structures:
+ * SLQB is primarily per-cpu. For each kmem_cache, each CPU has:
+ *
+ * - A LIFO list of node-local objects. Allocation and freeing of node local
+ * objects goes first to this list.
+ *
+ * - 2 Lists of slab pages, free and partial pages. If an allocation misses
+ * the object list, it tries from the partial list, then the free list.
+ * After freeing an object to the object list, if it is over a watermark,
+ * some objects are freed back to pages. If an allocation misses these lists,
+ * a new slab page is allocated from the page allocator. If the free list
+ * reaches a watermark, some of its pages are returned to the page allocator.
+ *
+ * - A remote free queue, where objects freed that did not come from the local
+ * node are queued to. When this reaches a watermark, the objects are
+ * flushed.
+ *
+ * - A remotely freed queue, where objects allocated from this CPU are flushed
+ * to from other CPUs' remote free queues. kmem_cache_remote_free->lock is
+ * used to protect access to this queue.
+ *
+ * When the remotely freed queue reaches a watermark, a flag is set to tell
+ * the owner CPU to check it. The owner CPU will then check the queue on the
+ * next allocation that misses the object list. It will move all objects from
+ * this list onto the object list and then allocate one.
+ *
+ * This system of remote queueing is intended to reduce lock and remote
+ * cacheline acquisitions, and give a cooling off period for remotely freed
+ * objects before they are re-allocated.
+ *
+ * node specific allocations from somewhere other than the local node are
+ * handled by a per-node list which is the same as the above per-CPU data
+ * structures except for the following differences:
+ *
+ * - kmem_cache_node->list_lock is used to protect access for multiple CPUs to
+ * allocate from a given node.
+ *
+ * - There is no remote free queue. Nodes don't free objects, CPUs do.
+ */
+
+static inline void slqb_stat_inc(struct kmem_cache_list *list,
+ enum stat_item si)
+{
+#ifdef CONFIG_SLQB_STATS
+ list->stats[si]++;
+#endif
+}
+
+static inline void slqb_stat_add(struct kmem_cache_list *list,
+ enum stat_item si, unsigned long nr)
+{
+#ifdef CONFIG_SLQB_STATS
+ list->stats[si] += nr;
+#endif
+}
+
+static inline int slqb_page_to_nid(struct slqb_page *page)
+{
+ return page_to_nid(&page->page);
+}
+
+static inline void *slqb_page_address(struct slqb_page *page)
+{
+ return page_address(&page->page);
+}
+
+static inline struct zone *slqb_page_zone(struct slqb_page *page)
+{
+ return page_zone(&page->page);
+}
+
+static inline int virt_to_nid(const void *addr)
+{
+ return page_to_nid(virt_to_page(addr));
+}
+
+static inline struct slqb_page *virt_to_head_slqb_page(const void *addr)
+{
+ struct page *p;
+
+ p = virt_to_head_page(addr);
+ return (struct slqb_page *)p;
+}
+
+static inline void __free_slqb_pages(struct slqb_page *page, unsigned int order,
+ int pages)
+{
+ struct page *p = &page->page;
+
+ reset_page_mapcount(p);
+ p->mapping = NULL;
+ VM_BUG_ON(!(p->flags & PG_SLQB_BIT));
+ p->flags &= ~PG_SLQB_BIT;
+
+ if (current->reclaim_state)
+ current->reclaim_state->reclaimed_slab += pages;
+ __free_pages(p, order);
+}
+
+#ifdef CONFIG_SLQB_DEBUG
+static inline int slab_debug(struct kmem_cache *s)
+{
+ return s->flags &
+ (SLAB_DEBUG_FREE |
+ SLAB_RED_ZONE |
+ SLAB_POISON |
+ SLAB_STORE_USER |
+ SLAB_TRACE);
+}
+static inline int slab_poison(struct kmem_cache *s)
+{
+ return s->flags & SLAB_POISON;
+}
+#else
+static inline int slab_debug(struct kmem_cache *s)
+{
+ return 0;
+}
+static inline int slab_poison(struct kmem_cache *s)
+{
+ return 0;
+}
+#endif
+
+#define DEBUG_DEFAULT_FLAGS (SLAB_DEBUG_FREE | SLAB_RED_ZONE | \
+ SLAB_POISON | SLAB_STORE_USER)
+
+/* Internal SLQB flags */
+#define __OBJECT_POISON 0x80000000 /* Poison object */
+
+/* Not all arches define cache_line_size */
+#ifndef cache_line_size
+#define cache_line_size() L1_CACHE_BYTES
+#endif
+
+#ifdef CONFIG_SMP
+static struct notifier_block slab_notifier;
+#endif
+
+/*
+ * slqb_lock protects slab_caches list and serialises hotplug operations.
+ * hotplug operations take lock for write, other operations can hold off
+ * hotplug by taking it for read (or write).
+ */
+static DECLARE_RWSEM(slqb_lock);
+
+/*
+ * A list of all slab caches on the system
+ */
+static LIST_HEAD(slab_caches);
+
+/*
+ * Tracking user of a slab.
+ */
+struct track {
+ unsigned long addr; /* Called from address */
+ int cpu; /* Was running on cpu */
+ int pid; /* Pid context */
+ unsigned long when; /* When did the operation occur */
+};
+
+enum track_item { TRACK_ALLOC, TRACK_FREE };
+
+static struct kmem_cache kmem_cache_cache;
+
+#ifdef CONFIG_SLQB_SYSFS
+static int sysfs_slab_add(struct kmem_cache *s);
+static void sysfs_slab_remove(struct kmem_cache *s);
+#else
+static inline int sysfs_slab_add(struct kmem_cache *s)
+{
+ return 0;
+}
+static inline void sysfs_slab_remove(struct kmem_cache *s)
+{
+ kmem_cache_free(&kmem_cache_cache, s);
+}
+#endif
+
+/********************************************************************
+ * Core slab cache functions
+ *******************************************************************/
+
+static int __slab_is_available __read_mostly;
+int slab_is_available(void)
+{
+ return __slab_is_available;
+}
+
+static inline struct kmem_cache_cpu *get_cpu_slab(struct kmem_cache *s, int cpu)
+{
+#ifdef CONFIG_SMP
+ VM_BUG_ON(!s->cpu_slab[cpu]);
+ return s->cpu_slab[cpu];
+#else
+ return &s->cpu_slab;
+#endif
+}
+
+static inline int check_valid_pointer(struct kmem_cache *s,
+ struct slqb_page *page, const void *object)
+{
+ void *base;
+
+ base = slqb_page_address(page);
+ if (object < base || object >= base + s->objects * s->size ||
+ (object - base) % s->size) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static inline void *get_freepointer(struct kmem_cache *s, void *object)
+{
+ return *(void **)(object + s->offset);
+}
+
+static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
+{
+ *(void **)(object + s->offset) = fp;
+}
+
+/* Loop over all objects in a slab */
+#define for_each_object(__p, __s, __addr) \
+ for (__p = (__addr); __p < (__addr) + (__s)->objects * (__s)->size;\
+ __p += (__s)->size)
+
+/* Scan freelist */
+#define for_each_free_object(__p, __s, __free) \
+ for (__p = (__free); (__p) != NULL; __p = get_freepointer((__s),\
+ __p))
+
+#ifdef CONFIG_SLQB_DEBUG
+/*
+ * Debug settings:
+ */
+#ifdef CONFIG_SLQB_DEBUG_ON
+static int slqb_debug __read_mostly = DEBUG_DEFAULT_FLAGS;
+#else
+static int slqb_debug __read_mostly;
+#endif
+
+static char *slqb_debug_slabs;
+
+/*
+ * Object debugging
+ */
+static void print_section(char *text, u8 *addr, unsigned int length)
+{
+ int i, offset;
+ int newline = 1;
+ char ascii[17];
+
+ ascii[16] = 0;
+
+ for (i = 0; i < length; i++) {
+ if (newline) {
+ printk(KERN_ERR "%8s 0x%p: ", text, addr + i);
+ newline = 0;
+ }
+ printk(KERN_CONT " %02x", addr[i]);
+ offset = i % 16;
+ ascii[offset] = isgraph(addr[i]) ? addr[i] : '.';
+ if (offset == 15) {
+ printk(KERN_CONT " %s\n", ascii);
+ newline = 1;
+ }
+ }
+ if (!newline) {
+ i %= 16;
+ while (i < 16) {
+ printk(KERN_CONT " ");
+ ascii[i] = ' ';
+ i++;
+ }
+ printk(KERN_CONT " %s\n", ascii);
+ }
+}
+
+static struct track *get_track(struct kmem_cache *s, void *object,
+ enum track_item alloc)
+{
+ struct track *p;
+
+ if (s->offset)
+ p = object + s->offset + sizeof(void *);
+ else
+ p = object + s->inuse;
+
+ return p + alloc;
+}
+
+static void set_track(struct kmem_cache *s, void *object,
+ enum track_item alloc, unsigned long addr)
+{
+ struct track *p;
+
+ if (s->offset)
+ p = object + s->offset + sizeof(void *);
+ else
+ p = object + s->inuse;
+
+ p += alloc;
+ if (addr) {
+ p->addr = addr;
+ p->cpu = raw_smp_processor_id();
+ p->pid = current ? current->pid : -1;
+ p->when = jiffies;
+ } else
+ memset(p, 0, sizeof(struct track));
+}
+
+static void init_tracking(struct kmem_cache *s, void *object)
+{
+ if (!(s->flags & SLAB_STORE_USER))
+ return;
+
+ set_track(s, object, TRACK_FREE, 0UL);
+ set_track(s, object, TRACK_ALLOC, 0UL);
+}
+
+static void print_track(const char *s, struct track *t)
+{
+ if (!t->addr)
+ return;
+
+ printk(KERN_ERR "INFO: %s in ", s);
+ __print_symbol("%s", (unsigned long)t->addr);
+ printk(" age=%lu cpu=%u pid=%d\n", jiffies - t->when, t->cpu, t->pid);
+}
+
+static void print_tracking(struct kmem_cache *s, void *object)
+{
+ if (!(s->flags & SLAB_STORE_USER))
+ return;
+
+ print_track("Allocated", get_track(s, object, TRACK_ALLOC));
+ print_track("Freed", get_track(s, object, TRACK_FREE));
+}
+
+static void print_page_info(struct slqb_page *page)
+{
+ printk(KERN_ERR "INFO: Slab 0x%p used=%u fp=0x%p flags=0x%04lx\n",
+ page, page->inuse, page->freelist, page->flags);
+
+}
+
+#define MAX_ERR_STR 100
+static void slab_bug(struct kmem_cache *s, char *fmt, ...)
+{
+ va_list args;
+ char buf[MAX_ERR_STR];
+
+ va_start(args, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+ printk(KERN_ERR "========================================"
+ "=====================================\n");
+ printk(KERN_ERR "BUG %s: %s\n", s->name, buf);
+ printk(KERN_ERR "----------------------------------------"
+ "-------------------------------------\n\n");
+}
+
+static void slab_fix(struct kmem_cache *s, char *fmt, ...)
+{
+ va_list args;
+ char buf[100];
+
+ va_start(args, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+ printk(KERN_ERR "FIX %s: %s\n", s->name, buf);
+}
+
+static void print_trailer(struct kmem_cache *s, struct slqb_page *page, u8 *p)
+{
+ unsigned int off; /* Offset of last byte */
+ u8 *addr = slqb_page_address(page);
+
+ print_tracking(s, p);
+
+ print_page_info(page);
+
+ printk(KERN_ERR "INFO: Object 0x%p @offset=%tu fp=0x%p\n\n",
+ p, p - addr, get_freepointer(s, p));
+
+ if (p > addr + 16)
+ print_section("Bytes b4", p - 16, 16);
+
+ print_section("Object", p, min(s->objsize, 128));
+
+ if (s->flags & SLAB_RED_ZONE)
+ print_section("Redzone", p + s->objsize, s->inuse - s->objsize);
+
+ if (s->offset)
+ off = s->offset + sizeof(void *);
+ else
+ off = s->inuse;
+
+ if (s->flags & SLAB_STORE_USER)
+ off += 2 * sizeof(struct track);
+
+ if (off != s->size) {
+ /* Beginning of the filler is the free pointer */
+ print_section("Padding", p + off, s->size - off);
+ }
+
+ dump_stack();
+}
+
+static void object_err(struct kmem_cache *s, struct slqb_page *page,
+ u8 *object, char *reason)
+{
+ slab_bug(s, reason);
+ print_trailer(s, page, object);
+}
+
+static void slab_err(struct kmem_cache *s, struct slqb_page *page,
+ char *fmt, ...)
+{
+ slab_bug(s, fmt);
+ print_page_info(page);
+ dump_stack();
+}
+
+static void init_object(struct kmem_cache *s, void *object, int active)
+{
+ u8 *p = object;
+
+ if (s->flags & __OBJECT_POISON) {
+ memset(p, POISON_FREE, s->objsize - 1);
+ p[s->objsize - 1] = POISON_END;
+ }
+
+ if (s->flags & SLAB_RED_ZONE) {
+ memset(p + s->objsize,
+ active ? SLUB_RED_ACTIVE : SLUB_RED_INACTIVE,
+ s->inuse - s->objsize);
+ }
+}
+
+static u8 *check_bytes(u8 *start, unsigned int value, unsigned int bytes)
+{
+ while (bytes) {
+ if (*start != (u8)value)
+ return start;
+ start++;
+ bytes--;
+ }
+ return NULL;
+}
+
+static void restore_bytes(struct kmem_cache *s, char *message, u8 data,
+ void *from, void *to)
+{
+ slab_fix(s, "Restoring 0x%p-0x%p=0x%x\n", from, to - 1, data);
+ memset(from, data, to - from);
+}
+
+static int check_bytes_and_report(struct kmem_cache *s, struct slqb_page *page,
+ u8 *object, char *what,
+ u8 *start, unsigned int value, unsigned int bytes)
+{
+ u8 *fault;
+ u8 *end;
+
+ fault = check_bytes(start, value, bytes);
+ if (!fault)
+ return 1;
+
+ end = start + bytes;
+ while (end > fault && end[-1] == value)
+ end--;
+
+ slab_bug(s, "%s overwritten", what);
+ printk(KERN_ERR "INFO: 0x%p-0x%p. First byte 0x%x instead of 0x%x\n",
+ fault, end - 1, fault[0], value);
+ print_trailer(s, page, object);
+
+ restore_bytes(s, what, value, fault, end);
+ return 0;
+}
+
+/*
+ * Object layout:
+ *
+ * object address
+ * Bytes of the object to be managed.
+ * If the freepointer may overlay the object then the free
+ * pointer is the first word of the object.
+ *
+ * Poisoning uses 0x6b (POISON_FREE) and the last byte is
+ * 0xa5 (POISON_END)
+ *
+ * object + s->objsize
+ * Padding to reach word boundary. This is also used for Redzoning.
+ * Padding is extended by another word if Redzoning is enabled and
+ * objsize == inuse.
+ *
+ * We fill with 0xbb (RED_INACTIVE) for inactive objects and with
+ * 0xcc (RED_ACTIVE) for objects in use.
+ *
+ * object + s->inuse
+ * Meta data starts here.
+ *
+ * A. Free pointer (if we cannot overwrite object on free)
+ * B. Tracking data for SLAB_STORE_USER
+ * C. Padding to reach required alignment boundary or at mininum
+ * one word if debuggin is on to be able to detect writes
+ * before the word boundary.
+ *
+ * Padding is done using 0x5a (POISON_INUSE)
+ *
+ * object + s->size
+ * Nothing is used beyond s->size.
+ */
+
+static int check_pad_bytes(struct kmem_cache *s, struct slqb_page *page, u8 *p)
+{
+ unsigned long off = s->inuse; /* The end of info */
+
+ if (s->offset) {
+ /* Freepointer is placed after the object. */
+ off += sizeof(void *);
+ }
+
+ if (s->flags & SLAB_STORE_USER) {
+ /* We also have user information there */
+ off += 2 * sizeof(struct track);
+ }
+
+ if (s->size == off)
+ return 1;
+
+ return check_bytes_and_report(s, page, p, "Object padding",
+ p + off, POISON_INUSE, s->size - off);
+}
+
+static int slab_pad_check(struct kmem_cache *s, struct slqb_page *page)
+{
+ u8 *start;
+ u8 *fault;
+ u8 *end;
+ int length;
+ int remainder;
+
+ if (!(s->flags & SLAB_POISON))
+ return 1;
+
+ start = slqb_page_address(page);
+ end = start + (PAGE_SIZE << s->order);
+ length = s->objects * s->size;
+ remainder = end - (start + length);
+ if (!remainder)
+ return 1;
+
+ fault = check_bytes(start + length, POISON_INUSE, remainder);
+ if (!fault)
+ return 1;
+
+ while (end > fault && end[-1] == POISON_INUSE)
+ end--;
+
+ slab_err(s, page, "Padding overwritten. 0x%p-0x%p", fault, end - 1);
+ print_section("Padding", start, length);
+
+ restore_bytes(s, "slab padding", POISON_INUSE, start, end);
+ return 0;
+}
+
+static int check_object(struct kmem_cache *s, struct slqb_page *page,
+ void *object, int active)
+{
+ u8 *p = object;
+ u8 *endobject = object + s->objsize;
+
+ if (s->flags & SLAB_RED_ZONE) {
+ unsigned int red =
+ active ? SLUB_RED_ACTIVE : SLUB_RED_INACTIVE;
+
+ if (!check_bytes_and_report(s, page, object, "Redzone",
+ endobject, red, s->inuse - s->objsize))
+ return 0;
+ } else {
+ if ((s->flags & SLAB_POISON) && s->objsize < s->inuse) {
+ check_bytes_and_report(s, page, p, "Alignment padding",
+ endobject, POISON_INUSE, s->inuse - s->objsize);
+ }
+ }
+
+ if (s->flags & SLAB_POISON) {
+ if (!active && (s->flags & __OBJECT_POISON)) {
+ if (!check_bytes_and_report(s, page, p, "Poison", p,
+ POISON_FREE, s->objsize - 1))
+ return 0;
+
+ if (!check_bytes_and_report(s, page, p, "Poison",
+ p + s->objsize - 1, POISON_END, 1))
+ return 0;
+ }
+
+ /*
+ * check_pad_bytes cleans up on its own.
+ */
+ check_pad_bytes(s, page, p);
+ }
+
+ return 1;
+}
+
+static int check_slab(struct kmem_cache *s, struct slqb_page *page)
+{
+ if (!(page->flags & PG_SLQB_BIT)) {
+ slab_err(s, page, "Not a valid slab page");
+ return 0;
+ }
+ if (page->inuse == 0) {
+ slab_err(s, page, "inuse before free / after alloc", s->name);
+ return 0;
+ }
+ if (page->inuse > s->objects) {
+ slab_err(s, page, "inuse %u > max %u",
+ s->name, page->inuse, s->objects);
+ return 0;
+ }
+ /* Slab_pad_check fixes things up after itself */
+ slab_pad_check(s, page);
+ return 1;
+}
+
+static void trace(struct kmem_cache *s, struct slqb_page *page,
+ void *object, int alloc)
+{
+ if (s->flags & SLAB_TRACE) {
+ printk(KERN_INFO "TRACE %s %s 0x%p inuse=%d fp=0x%p\n",
+ s->name,
+ alloc ? "alloc" : "free",
+ object, page->inuse,
+ page->freelist);
+
+ if (!alloc)
+ print_section("Object", (void *)object, s->objsize);
+
+ dump_stack();
+ }
+}
+
+static void setup_object_debug(struct kmem_cache *s, struct slqb_page *page,
+ void *object)
+{
+ if (!slab_debug(s))
+ return;
+
+ if (!(s->flags & (SLAB_STORE_USER|SLAB_RED_ZONE|__OBJECT_POISON)))
+ return;
+
+ init_object(s, object, 0);
+ init_tracking(s, object);
+}
+
+static int alloc_debug_processing(struct kmem_cache *s,
+ void *object, unsigned long addr)
+{
+ struct slqb_page *page;
+ page = virt_to_head_slqb_page(object);
+
+ if (!check_slab(s, page))
+ goto bad;
+
+ if (!check_valid_pointer(s, page, object)) {
+ object_err(s, page, object, "Freelist Pointer check fails");
+ goto bad;
+ }
+
+ if (object && !check_object(s, page, object, 0))
+ goto bad;
+
+ /* Success perform special debug activities for allocs */
+ if (s->flags & SLAB_STORE_USER)
+ set_track(s, object, TRACK_ALLOC, addr);
+ trace(s, page, object, 1);
+ init_object(s, object, 1);
+ return 1;
+
+bad:
+ return 0;
+}
+
+static int free_debug_processing(struct kmem_cache *s,
+ void *object, unsigned long addr)
+{
+ struct slqb_page *page;
+ page = virt_to_head_slqb_page(object);
+
+ if (!check_slab(s, page))
+ goto fail;
+
+ if (!check_valid_pointer(s, page, object)) {
+ slab_err(s, page, "Invalid object pointer 0x%p", object);
+ goto fail;
+ }
+
+ if (!check_object(s, page, object, 1))
+ return 0;
+
+ /* Special debug activities for freeing objects */
+ if (s->flags & SLAB_STORE_USER)
+ set_track(s, object, TRACK_FREE, addr);
+ trace(s, page, object, 0);
+ init_object(s, object, 0);
+ return 1;
+
+fail:
+ slab_fix(s, "Object at 0x%p not freed", object);
+ return 0;
+}
+
+static int __init setup_slqb_debug(char *str)
+{
+ slqb_debug = DEBUG_DEFAULT_FLAGS;
+ if (*str++ != '=' || !*str) {
+ /*
+ * No options specified. Switch on full debugging.
+ */
+ goto out;
+ }
+
+ if (*str == ',') {
+ /*
+ * No options but restriction on slabs. This means full
+ * debugging for slabs matching a pattern.
+ */
+ goto check_slabs;
+ }
+
+ slqb_debug = 0;
+ if (*str == '-') {
+ /*
+ * Switch off all debugging measures.
+ */
+ goto out;
+ }
+
+ /*
+ * Determine which debug features should be switched on
+ */
+ for (; *str && *str != ','; str++) {
+ switch (tolower(*str)) {
+ case 'f':
+ slqb_debug |= SLAB_DEBUG_FREE;
+ break;
+ case 'z':
+ slqb_debug |= SLAB_RED_ZONE;
+ break;
+ case 'p':
+ slqb_debug |= SLAB_POISON;
+ break;
+ case 'u':
+ slqb_debug |= SLAB_STORE_USER;
+ break;
+ case 't':
+ slqb_debug |= SLAB_TRACE;
+ break;
+ default:
+ printk(KERN_ERR "slqb_debug option '%c' "
+ "unknown. skipped\n", *str);
+ }
+ }
+
+check_slabs:
+ if (*str == ',')
+ slqb_debug_slabs = str + 1;
+out:
+ return 1;
+}
+__setup("slqb_debug", setup_slqb_debug);
+
+static int __init setup_slqb_min_order(char *str)
+{
+ get_option(&str, &slqb_min_order);
+ slqb_min_order = min(slqb_min_order, MAX_ORDER - 1);
+
+ return 1;
+}
+__setup("slqb_min_order=", setup_slqb_min_order);
+
+static int __init setup_slqb_min_objects(char *str)
+{
+ get_option(&str, &slqb_min_objects);
+
+ return 1;
+}
+
+__setup("slqb_min_objects=", setup_slqb_min_objects);
+
+static unsigned long kmem_cache_flags(unsigned long objsize,
+ unsigned long flags, const char *name,
+ void (*ctor)(void *))
+{
+ /*
+ * Enable debugging if selected on the kernel commandline.
+ */
+ if (slqb_debug && (!slqb_debug_slabs ||
+ strncmp(slqb_debug_slabs, name,
+ strlen(slqb_debug_slabs)) == 0))
+ flags |= slqb_debug;
+
+ if (num_possible_nodes() > 1)
+ flags |= SLAB_NUMA;
+
+ return flags;
+}
+#else
+static inline void setup_object_debug(struct kmem_cache *s,
+ struct slqb_page *page, void *object)
+{
+}
+
+static inline int alloc_debug_processing(struct kmem_cache *s,
+ void *object, unsigned long addr)
+{
+ return 0;
+}
+
+static inline int free_debug_processing(struct kmem_cache *s,
+ void *object, unsigned long addr)
+{
+ return 0;
+}
+
+static inline int slab_pad_check(struct kmem_cache *s, struct slqb_page *page)
+{
+ return 1;
+}
+
+static inline int check_object(struct kmem_cache *s, struct slqb_page *page,
+ void *object, int active)
+{
+ return 1;
+}
+
+static inline void add_full(struct kmem_cache_node *n, struct slqb_page *page)
+{
+}
+
+static inline unsigned long kmem_cache_flags(unsigned long objsize,
+ unsigned long flags, const char *name, void (*ctor)(void *))
+{
+ if (num_possible_nodes() > 1)
+ flags |= SLAB_NUMA;
+ return flags;
+}
+
+static const int slqb_debug;
+#endif
+
+/*
+ * allocate a new slab (return its corresponding struct slqb_page)
+ */
+static struct slqb_page *allocate_slab(struct kmem_cache *s,
+ gfp_t flags, int node)
+{
+ struct slqb_page *page;
+ int pages = 1 << s->order;
+
+ flags |= s->allocflags;
+
+ page = (struct slqb_page *)alloc_pages_node(node, flags, s->order);
+ if (!page)
+ return NULL;
+
+ mod_zone_page_state(slqb_page_zone(page),
+ (s->flags & SLAB_RECLAIM_ACCOUNT) ?
+ NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
+ pages);
+
+ return page;
+}
+
+/*
+ * Called once for each object on a new slab page
+ */
+static void setup_object(struct kmem_cache *s,
+ struct slqb_page *page, void *object)
+{
+ setup_object_debug(s, page, object);
+ if (unlikely(s->ctor))
+ s->ctor(object);
+}
+
+/*
+ * Allocate a new slab, set up its object list.
+ */
+static struct slqb_page *new_slab_page(struct kmem_cache *s,
+ gfp_t flags, int node, unsigned int colour)
+{
+ struct slqb_page *page;
+ void *start;
+ void *last;
+ void *p;
+
+ BUG_ON(flags & GFP_SLAB_BUG_MASK);
+
+ page = allocate_slab(s,
+ flags & (GFP_RECLAIM_MASK | GFP_CONSTRAINT_MASK), node);
+ if (!page)
+ goto out;
+
+ page->flags |= PG_SLQB_BIT;
+
+ start = page_address(&page->page);
+
+ if (unlikely(slab_poison(s)))
+ memset(start, POISON_INUSE, PAGE_SIZE << s->order);
+
+ start += colour;
+
+ last = start;
+ for_each_object(p, s, start) {
+ setup_object(s, page, p);
+ set_freepointer(s, last, p);
+ last = p;
+ }
+ set_freepointer(s, last, NULL);
+
+ page->freelist = start;
+ page->inuse = 0;
+out:
+ return page;
+}
+
+/*
+ * Free a slab page back to the page allocator
+ */
+static void __free_slab(struct kmem_cache *s, struct slqb_page *page)
+{
+ int pages = 1 << s->order;
+
+ if (unlikely(slab_debug(s))) {
+ void *p;
+
+ slab_pad_check(s, page);
+ for_each_free_object(p, s, page->freelist)
+ check_object(s, page, p, 0);
+ }
+
+ mod_zone_page_state(slqb_page_zone(page),
+ (s->flags & SLAB_RECLAIM_ACCOUNT) ?
+ NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
+ -pages);
+
+ __free_slqb_pages(page, s->order, pages);
+}
+
+static void rcu_free_slab(struct rcu_head *h)
+{
+ struct slqb_page *page;
+
+ page = container_of(h, struct slqb_page, rcu_head);
+ __free_slab(page->list->cache, page);
+}
+
+static void free_slab(struct kmem_cache *s, struct slqb_page *page)
+{
+ VM_BUG_ON(page->inuse);
+ if (unlikely(s->flags & SLAB_DESTROY_BY_RCU))
+ call_rcu(&page->rcu_head, rcu_free_slab);
+ else
+ __free_slab(s, page);
+}
+
+/*
+ * Return an object to its slab.
+ *
+ * Caller must be the owner CPU in the case of per-CPU list, or hold the node's
+ * list_lock in the case of per-node list.
+ */
+static int free_object_to_page(struct kmem_cache *s,
+ struct kmem_cache_list *l, struct slqb_page *page,
+ void *object)
+{
+ VM_BUG_ON(page->list != l);
+
+ set_freepointer(s, object, page->freelist);
+ page->freelist = object;
+ page->inuse--;
+
+ if (!page->inuse) {
+ if (likely(s->objects > 1)) {
+ l->nr_partial--;
+ list_del(&page->lru);
+ }
+ l->nr_slabs--;
+ free_slab(s, page);
+ slqb_stat_inc(l, FLUSH_SLAB_FREE);
+ return 1;
+
+ } else if (page->inuse + 1 == s->objects) {
+ l->nr_partial++;
+ list_add(&page->lru, &l->partial);
+ slqb_stat_inc(l, FLUSH_SLAB_PARTIAL);
+ return 0;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_SMP
+static void slab_free_to_remote(struct kmem_cache *s, struct slqb_page *page,
+ void *object, struct kmem_cache_cpu *c);
+#endif
+
+/*
+ * Flush the LIFO list of objects on a list. They are sent back to their pages
+ * in case the pages also belong to the list, or to our CPU's remote-free list
+ * in the case they do not.
+ *
+ * Doesn't flush the entire list. flush_free_list_all does.
+ *
+ * Caller must be the owner CPU in the case of per-CPU list, or hold the node's
+ * list_lock in the case of per-node list.
+ */
+static void flush_free_list(struct kmem_cache *s, struct kmem_cache_list *l)
+{
+ void **head;
+ int nr;
+ int locked = 0;
+
+ nr = l->freelist.nr;
+ if (unlikely(!nr))
+ return;
+
+ nr = min(slab_freebatch(s), nr);
+
+ slqb_stat_inc(l, FLUSH_FREE_LIST);
+ slqb_stat_add(l, FLUSH_FREE_LIST_OBJECTS, nr);
+
+ l->freelist.nr -= nr;
+ head = l->freelist.head;
+
+ do {
+ struct slqb_page *page;
+ void **object;
+
+ object = head;
+ VM_BUG_ON(!object);
+ head = get_freepointer(s, object);
+ page = virt_to_head_slqb_page(object);
+
+#ifdef CONFIG_SMP
+ if (page->list != l) {
+ struct kmem_cache_cpu *c;
+
+ if (locked) {
+ spin_unlock(&l->page_lock);
+ locked = 0;
+ }
+
+ c = get_cpu_slab(s, smp_processor_id());
+
+ slab_free_to_remote(s, page, object, c);
+ slqb_stat_inc(l, FLUSH_FREE_LIST_REMOTE);
+ } else
+#endif
+ {
+ if (!locked) {
+ spin_lock(&l->page_lock);
+ locked = 1;
+ }
+ free_object_to_page(s, l, page, object);
+ }
+
+ nr--;
+ } while (nr);
+
+ if (locked)
+ spin_unlock(&l->page_lock);
+
+ l->freelist.head = head;
+ if (!l->freelist.nr)
+ l->freelist.tail = NULL;
+}
+
+static void flush_free_list_all(struct kmem_cache *s, struct kmem_cache_list *l)
+{
+ while (l->freelist.nr)
+ flush_free_list(s, l);
+}
+
+#ifdef CONFIG_SMP
+/*
+ * If enough objects have been remotely freed back to this list,
+ * remote_free_check will be set. In which case, we'll eventually come here
+ * to take those objects off our remote_free list and onto our LIFO freelist.
+ *
+ * Caller must be the owner CPU in the case of per-CPU list, or hold the node's
+ * list_lock in the case of per-node list.
+ */
+static void claim_remote_free_list(struct kmem_cache *s,
+ struct kmem_cache_list *l)
+{
+ void **head, **tail;
+ int nr;
+
+ if (!l->remote_free.list.nr)
+ return;
+
+ spin_lock(&l->remote_free.lock);
+
+ l->remote_free_check = 0;
+ head = l->remote_free.list.head;
+ l->remote_free.list.head = NULL;
+ tail = l->remote_free.list.tail;
+ l->remote_free.list.tail = NULL;
+ nr = l->remote_free.list.nr;
+ l->remote_free.list.nr = 0;
+
+ spin_unlock(&l->remote_free.lock);
+
+ VM_BUG_ON(!nr);
+
+ if (!l->freelist.nr) {
+ /* Get head hot for likely subsequent allocation or flush */
+ prefetchw(head);
+ l->freelist.head = head;
+ } else
+ set_freepointer(s, l->freelist.tail, head);
+ l->freelist.tail = tail;
+
+ l->freelist.nr += nr;
+
+ slqb_stat_inc(l, CLAIM_REMOTE_LIST);
+ slqb_stat_add(l, CLAIM_REMOTE_LIST_OBJECTS, nr);
+}
+#else
+static inline void claim_remote_free_list(struct kmem_cache *s,
+ struct kmem_cache_list *l)
+{
+}
+#endif
+
+/*
+ * Allocation fastpath. Get an object from the list's LIFO freelist, or
+ * return NULL if it is empty.
+ *
+ * Caller must be the owner CPU in the case of per-CPU list, or hold the node's
+ * list_lock in the case of per-node list.
+ */
+static __always_inline void *__cache_list_get_object(struct kmem_cache *s,
+ struct kmem_cache_list *l)
+{
+ void *object;
+
+ object = l->freelist.head;
+ if (likely(object)) {
+ void *next = get_freepointer(s, object);
+
+ VM_BUG_ON(!l->freelist.nr);
+ l->freelist.nr--;
+ l->freelist.head = next;
+
+ return object;
+ }
+ VM_BUG_ON(l->freelist.nr);
+
+#ifdef CONFIG_SMP
+ if (unlikely(l->remote_free_check)) {
+ claim_remote_free_list(s, l);
+
+ if (l->freelist.nr > slab_hiwater(s))
+ flush_free_list(s, l);
+
+ /* repetition here helps gcc :( */
+ object = l->freelist.head;
+ if (likely(object)) {
+ void *next = get_freepointer(s, object);
+
+ VM_BUG_ON(!l->freelist.nr);
+ l->freelist.nr--;
+ l->freelist.head = next;
+
+ return object;
+ }
+ VM_BUG_ON(l->freelist.nr);
+ }
+#endif
+
+ return NULL;
+}
+
+/*
+ * Slow(er) path. Get a page from this list's existing pages. Will be a
+ * new empty page in the case that __slab_alloc_page has just been called
+ * (empty pages otherwise never get queued up on the lists), or a partial page
+ * already on the list.
+ *
+ * Caller must be the owner CPU in the case of per-CPU list, or hold the node's
+ * list_lock in the case of per-node list.
+ */
+static noinline void *__cache_list_get_page(struct kmem_cache *s,
+ struct kmem_cache_list *l)
+{
+ struct slqb_page *page;
+ void *object;
+
+ if (unlikely(!l->nr_partial))
+ return NULL;
+
+ page = list_first_entry(&l->partial, struct slqb_page, lru);
+ VM_BUG_ON(page->inuse == s->objects);
+ if (page->inuse + 1 == s->objects) {
+ l->nr_partial--;
+ list_del(&page->lru);
+ }
+
+ VM_BUG_ON(!page->freelist);
+
+ page->inuse++;
+
+ object = page->freelist;
+ page->freelist = get_freepointer(s, object);
+ if (page->freelist)
+ prefetchw(page->freelist);
+ VM_BUG_ON((page->inuse == s->objects) != (page->freelist == NULL));
+ slqb_stat_inc(l, ALLOC_SLAB_FILL);
+
+ return object;
+}
+
+static void *cache_list_get_page(struct kmem_cache *s,
+ struct kmem_cache_list *l)
+{
+ void *object;
+
+ if (unlikely(!l->nr_partial))
+ return NULL;
+
+ spin_lock(&l->page_lock);
+ object = __cache_list_get_page(s, l);
+ spin_unlock(&l->page_lock);
+
+ return object;
+}
+
+/*
+ * Allocation slowpath. Allocate a new slab page from the page allocator, and
+ * put it on the list's partial list. Must be followed by an allocation so
+ * that we don't have dangling empty pages on the partial list.
+ *
+ * Returns 0 on allocation failure.
+ *
+ * Must be called with interrupts disabled.
+ */
+static noinline void *__slab_alloc_page(struct kmem_cache *s,
+ gfp_t gfpflags, int node)
+{
+ struct slqb_page *page;
+ struct kmem_cache_list *l;
+ struct kmem_cache_cpu *c;
+ unsigned int colour;
+ void *object;
+
+ c = get_cpu_slab(s, smp_processor_id());
+ colour = c->colour_next;
+ c->colour_next += s->colour_off;
+ if (c->colour_next >= s->colour_range)
+ c->colour_next = 0;
+
+ /* Caller handles __GFP_ZERO */
+ gfpflags &= ~__GFP_ZERO;
+
+ if (gfpflags & __GFP_WAIT)
+ local_irq_enable();
+ page = new_slab_page(s, gfpflags, node, colour);
+ if (gfpflags & __GFP_WAIT)
+ local_irq_disable();
+ if (unlikely(!page))
+ return page;
+
+ if (!NUMA_BUILD || likely(slqb_page_to_nid(page) == numa_node_id())) {
+ struct kmem_cache_cpu *c;
+ int cpu = smp_processor_id();
+
+ c = get_cpu_slab(s, cpu);
+ l = &c->list;
+ page->list = l;
+
+ spin_lock(&l->page_lock);
+ l->nr_slabs++;
+ l->nr_partial++;
+ list_add(&page->lru, &l->partial);
+ slqb_stat_inc(l, ALLOC);
+ slqb_stat_inc(l, ALLOC_SLAB_NEW);
+ object = __cache_list_get_page(s, l);
+ spin_unlock(&l->page_lock);
+ } else {
+#ifdef CONFIG_NUMA
+ struct kmem_cache_node *n;
+
+ n = s->node_slab[slqb_page_to_nid(page)];
+ l = &n->list;
+ page->list = l;
+
+ spin_lock(&n->list_lock);
+ l->nr_slabs++;
+ l->nr_partial++;
+ list_add(&page->lru, &l->partial);
+ slqb_stat_inc(l, ALLOC);
+ slqb_stat_inc(l, ALLOC_SLAB_NEW);
+ object = __cache_list_get_page(s, l);
+ spin_unlock(&n->list_lock);
+#endif
+ }
+ VM_BUG_ON(!object);
+ return object;
+}
+
+#ifdef CONFIG_NUMA
+static noinline int alternate_nid(struct kmem_cache *s,
+ gfp_t gfpflags, int node)
+{
+ if (in_interrupt() || (gfpflags & __GFP_THISNODE))
+ return node;
+ if (cpuset_do_slab_mem_spread() && (s->flags & SLAB_MEM_SPREAD))
+ return cpuset_mem_spread_node();
+ else if (current->mempolicy)
+ return slab_node(current->mempolicy);
+ return node;
+}
+
+/*
+ * Allocate an object from a remote node. Return NULL if none could be found
+ * (in which case, caller should allocate a new slab)
+ *
+ * Must be called with interrupts disabled.
+ */
+static void *__remote_slab_alloc_node(struct kmem_cache *s,
+ gfp_t gfpflags, int node)
+{
+ struct kmem_cache_node *n;
+ struct kmem_cache_list *l;
+ void *object;
+
+ n = s->node_slab[node];
+ if (unlikely(!n)) /* node has no memory */
+ return NULL;
+ l = &n->list;
+
+ spin_lock(&n->list_lock);
+
+ object = __cache_list_get_object(s, l);
+ if (unlikely(!object)) {
+ object = cache_list_get_page(s, l);
+ if (unlikely(!object)) {
+ spin_unlock(&n->list_lock);
+ return __slab_alloc_page(s, gfpflags, node);
+ }
+ }
+ if (likely(object))
+ slqb_stat_inc(l, ALLOC);
+ spin_unlock(&n->list_lock);
+ return object;
+}
+
+static noinline void *__remote_slab_alloc(struct kmem_cache *s,
+ gfp_t gfpflags, int node)
+{
+ void *object;
+ struct zonelist *zonelist;
+ struct zoneref *z;
+ struct zone *zone;
+ enum zone_type high_zoneidx = gfp_zone(gfpflags);
+
+ object = __remote_slab_alloc_node(s, gfpflags, node);
+ if (likely(object || (gfpflags & __GFP_THISNODE)))
+ return object;
+
+ zonelist = node_zonelist(slab_node(current->mempolicy), gfpflags);
+ for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) {
+ if (!cpuset_zone_allowed_hardwall(zone, gfpflags))
+ continue;
+
+ node = zone_to_nid(zone);
+ object = __remote_slab_alloc_node(s, gfpflags, node);
+ if (likely(object))
+ return object;
+ }
+ return NULL;
+}
+#endif
+
+/*
+ * Main allocation path. Return an object, or NULL on allocation failure.
+ *
+ * Must be called with interrupts disabled.
+ */
+static __always_inline void *__slab_alloc(struct kmem_cache *s,
+ gfp_t gfpflags, int node)
+{
+ void *object;
+ struct kmem_cache_cpu *c;
+ struct kmem_cache_list *l;
+
+#ifdef CONFIG_NUMA
+ if (unlikely(node != -1) && unlikely(node != numa_node_id())) {
+try_remote:
+ return __remote_slab_alloc(s, gfpflags, node);
+ }
+#endif
+
+ c = get_cpu_slab(s, smp_processor_id());
+ VM_BUG_ON(!c);
+ l = &c->list;
+ object = __cache_list_get_object(s, l);
+ if (unlikely(!object)) {
+ object = cache_list_get_page(s, l);
+ if (unlikely(!object)) {
+ object = __slab_alloc_page(s, gfpflags, node);
+#ifdef CONFIG_NUMA
+ if (unlikely(!object)) {
+ node = numa_node_id();
+ goto try_remote;
+ }
+#endif
+ return object;
+ }
+ }
+ if (likely(object))
+ slqb_stat_inc(l, ALLOC);
+ return object;
+}
+
+/*
+ * Perform some interrupts-on processing around the main allocation path
+ * (debug checking and memset()ing).
+ */
+static __always_inline void *slab_alloc(struct kmem_cache *s,
+ gfp_t gfpflags, int node, unsigned long addr)
+{
+ void *object;
+ unsigned long flags;
+
+again:
+ local_irq_save(flags);
+ object = __slab_alloc(s, gfpflags, node);
+ local_irq_restore(flags);
+
+ if (unlikely(slab_debug(s)) && likely(object)) {
+ if (unlikely(!alloc_debug_processing(s, object, addr)))
+ goto again;
+ }
+
+ if (unlikely(gfpflags & __GFP_ZERO) && likely(object))
+ memset(object, 0, s->objsize);
+
+ return object;
+}
+
+static __always_inline void *__kmem_cache_alloc(struct kmem_cache *s,
+ gfp_t gfpflags, unsigned long caller)
+{
+ int node = -1;
+#ifdef CONFIG_NUMA
+ if (unlikely(current->flags & (PF_SPREAD_SLAB | PF_MEMPOLICY)))
+ node = alternate_nid(s, gfpflags, node);
+#endif
+ return slab_alloc(s, gfpflags, node, caller);
+}
+
+void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
+{
+ return __kmem_cache_alloc(s, gfpflags, _RET_IP_);
+}
+EXPORT_SYMBOL(kmem_cache_alloc);
+
+#ifdef CONFIG_NUMA
+void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node)
+{
+ return slab_alloc(s, gfpflags, node, _RET_IP_);
+}
+EXPORT_SYMBOL(kmem_cache_alloc_node);
+#endif
+
+#ifdef CONFIG_SMP
+/*
+ * Flush this CPU's remote free list of objects back to the list from where
+ * they originate. They end up on that list's remotely freed list, and
+ * eventually we set it's remote_free_check if there are enough objects on it.
+ *
+ * This seems convoluted, but it keeps is from stomping on the target CPU's
+ * fastpath cachelines.
+ *
+ * Must be called with interrupts disabled.
+ */
+static void flush_remote_free_cache(struct kmem_cache *s,
+ struct kmem_cache_cpu *c)
+{
+ struct kmlist *src;
+ struct kmem_cache_list *dst;
+ unsigned int nr;
+ int set;
+
+ src = &c->rlist;
+ nr = src->nr;
+ if (unlikely(!nr))
+ return;
+
+#ifdef CONFIG_SLQB_STATS
+ {
+ struct kmem_cache_list *l = &c->list;
+
+ slqb_stat_inc(l, FLUSH_RFREE_LIST);
+ slqb_stat_add(l, FLUSH_RFREE_LIST_OBJECTS, nr);
+ }
+#endif
+
+ dst = c->remote_cache_list;
+
+ /*
+ * Less common case, dst is filling up so free synchronously.
+ * No point in having remote CPU free thse as it will just
+ * free them back to the page list anyway.
+ */
+ if (unlikely(dst->remote_free.list.nr > (slab_hiwater(s) >> 1))) {
+ void **head;
+
+ head = src->head;
+ spin_lock(&dst->page_lock);
+ do {
+ struct slqb_page *page;
+ void **object;
+
+ object = head;
+ VM_BUG_ON(!object);
+ head = get_freepointer(s, object);
+ page = virt_to_head_slqb_page(object);
+
+ free_object_to_page(s, dst, page, object);
+ nr--;
+ } while (nr);
+ spin_unlock(&dst->page_lock);
+
+ src->head = NULL;
+ src->tail = NULL;
+ src->nr = 0;
+
+ return;
+ }
+
+ spin_lock(&dst->remote_free.lock);
+
+ if (!dst->remote_free.list.head)
+ dst->remote_free.list.head = src->head;
+ else
+ set_freepointer(s, dst->remote_free.list.tail, src->head);
+ dst->remote_free.list.tail = src->tail;
+
+ src->head = NULL;
+ src->tail = NULL;
+ src->nr = 0;
+
+ if (dst->remote_free.list.nr < slab_freebatch(s))
+ set = 1;
+ else
+ set = 0;
+
+ dst->remote_free.list.nr += nr;
+
+ if (unlikely(dst->remote_free.list.nr >= slab_freebatch(s) && set))
+ dst->remote_free_check = 1;
+
+ spin_unlock(&dst->remote_free.lock);
+}
+
+/*
+ * Free an object to this CPU's remote free list.
+ *
+ * Must be called with interrupts disabled.
+ */
+static noinline void slab_free_to_remote(struct kmem_cache *s,
+ struct slqb_page *page, void *object,
+ struct kmem_cache_cpu *c)
+{
+ struct kmlist *r;
+
+ /*
+ * Our remote free list corresponds to a different list. Must
+ * flush it and switch.
+ */
+ if (page->list != c->remote_cache_list) {
+ flush_remote_free_cache(s, c);
+ c->remote_cache_list = page->list;
+ }
+
+ r = &c->rlist;
+ if (!r->head)
+ r->head = object;
+ else
+ set_freepointer(s, r->tail, object);
+ set_freepointer(s, object, NULL);
+ r->tail = object;
+ r->nr++;
+
+ if (unlikely(r->nr >= slab_freebatch(s)))
+ flush_remote_free_cache(s, c);
+}
+#endif
+
+/*
+ * Main freeing path. Return an object, or NULL on allocation failure.
+ *
+ * Must be called with interrupts disabled.
+ */
+static __always_inline void __slab_free(struct kmem_cache *s,
+ struct slqb_page *page, void *object)
+{
+ struct kmem_cache_cpu *c;
+ struct kmem_cache_list *l;
+ int thiscpu = smp_processor_id();
+
+ c = get_cpu_slab(s, thiscpu);
+ l = &c->list;
+
+ slqb_stat_inc(l, FREE);
+
+ if (!NUMA_BUILD || !slab_numa(s) ||
+ likely(slqb_page_to_nid(page) == numa_node_id())) {
+ /*
+ * Freeing fastpath. Collects all local-node objects, not
+ * just those allocated from our per-CPU list. This allows
+ * fast transfer of objects from one CPU to another within
+ * a given node.
+ */
+ set_freepointer(s, object, l->freelist.head);
+ l->freelist.head = object;
+ if (!l->freelist.nr)
+ l->freelist.tail = object;
+ l->freelist.nr++;
+
+ if (unlikely(l->freelist.nr > slab_hiwater(s)))
+ flush_free_list(s, l);
+
+ } else {
+#ifdef CONFIG_SMP
+ /*
+ * Freeing an object that was allocated on a remote node.
+ */
+ slab_free_to_remote(s, page, object, c);
+ slqb_stat_inc(l, FREE_REMOTE);
+#endif
+ }
+}
+
+/*
+ * Perform some interrupts-on processing around the main freeing path
+ * (debug checking).
+ */
+static __always_inline void slab_free(struct kmem_cache *s,
+ struct slqb_page *page, void *object)
+{
+ unsigned long flags;
+
+ prefetchw(object);
+
+ debug_check_no_locks_freed(object, s->objsize);
+ if (likely(object) && unlikely(slab_debug(s))) {
+ if (unlikely(!free_debug_processing(s, object, _RET_IP_)))
+ return;
+ }
+
+ local_irq_save(flags);
+ __slab_free(s, page, object);
+ local_irq_restore(flags);
+}
+
+void kmem_cache_free(struct kmem_cache *s, void *object)
+{
+ struct slqb_page *page = NULL;
+
+ if (slab_numa(s))
+ page = virt_to_head_slqb_page(object);
+ slab_free(s, page, object);
+}
+EXPORT_SYMBOL(kmem_cache_free);
+
+/*
+ * Calculate the order of allocation given an slab object size.
+ *
+ * Order 0 allocations are preferred since order 0 does not cause fragmentation
+ * in the page allocator, and they have fastpaths in the page allocator. But
+ * also minimise external fragmentation with large objects.
+ */
+static int slab_order(int size, int max_order, int frac)
+{
+ int order;
+
+ if (fls(size - 1) <= PAGE_SHIFT)
+ order = 0;
+ else
+ order = fls(size - 1) - PAGE_SHIFT;
+ if (order < slqb_min_order)
+ order = slqb_min_order;
+
+ while (order <= max_order) {
+ unsigned long slab_size = PAGE_SIZE << order;
+ unsigned long objects;
+ unsigned long waste;
+
+ objects = slab_size / size;
+ if (!objects)
+ goto next;
+
+ if (order < MAX_ORDER && objects < slqb_min_objects) {
+ /*
+ * if we don't have enough objects for min_objects,
+ * then try the next size up. Unless we have reached
+ * our maximum possible page size.
+ */
+ goto next;
+ }
+
+ waste = slab_size - (objects * size);
+
+ if (waste * frac <= slab_size)
+ break;
+
+next:
+ order++;
+ }
+
+ return order;
+}
+
+static int calculate_order(int size)
+{
+ int order;
+
+ /*
+ * Attempt to find best configuration for a slab. This
+ * works by first attempting to generate a layout with
+ * the best configuration and backing off gradually.
+ */
+ order = slab_order(size, 1, 4);
+ if (order <= 1)
+ return order;
+
+ /*
+ * This size cannot fit in order-1. Allow bigger orders, but
+ * forget about trying to save space.
+ */
+ order = slab_order(size, MAX_ORDER - 1, 0);
+ if (order < MAX_ORDER)
+ return order;
+
+ return -ENOSYS;
+}
+
+/*
+ * Figure out what the alignment of the objects will be.
+ */
+static unsigned long calculate_alignment(unsigned long flags,
+ unsigned long align, unsigned long size)
+{
+ /*
+ * If the user wants hardware cache aligned objects then follow that
+ * suggestion if the object is sufficiently large.
+ *
+ * The hardware cache alignment cannot override the specified
+ * alignment though. If that is greater then use it.
+ */
+ if (flags & SLAB_HWCACHE_ALIGN) {
+ unsigned long ralign = cache_line_size();
+
+ while (size <= ralign / 2)
+ ralign /= 2;
+ align = max(align, ralign);
+ }
+
+ if (align < ARCH_SLAB_MINALIGN)
+ align = ARCH_SLAB_MINALIGN;
+
+ return ALIGN(align, sizeof(void *));
+}
+
+static void init_kmem_cache_list(struct kmem_cache *s,
+ struct kmem_cache_list *l)
+{
+ l->cache = s;
+ l->freelist.nr = 0;
+ l->freelist.head = NULL;
+ l->freelist.tail = NULL;
+ l->nr_partial = 0;
+ l->nr_slabs = 0;
+ INIT_LIST_HEAD(&l->partial);
+ spin_lock_init(&l->page_lock);
+
+#ifdef CONFIG_SMP
+ l->remote_free_check = 0;
+ spin_lock_init(&l->remote_free.lock);
+ l->remote_free.list.nr = 0;
+ l->remote_free.list.head = NULL;
+ l->remote_free.list.tail = NULL;
+#endif
+
+#ifdef CONFIG_SLQB_STATS
+ memset(l->stats, 0, sizeof(l->stats));
+#endif
+}
+
+static void init_kmem_cache_cpu(struct kmem_cache *s,
+ struct kmem_cache_cpu *c)
+{
+ init_kmem_cache_list(s, &c->list);
+
+ c->colour_next = 0;
+#ifdef CONFIG_SMP
+ c->rlist.nr = 0;
+ c->rlist.head = NULL;
+ c->rlist.tail = NULL;
+ c->remote_cache_list = NULL;
+#endif
+}
+
+#ifdef CONFIG_NUMA
+static void init_kmem_cache_node(struct kmem_cache *s,
+ struct kmem_cache_node *n)
+{
+ spin_lock_init(&n->list_lock);
+ init_kmem_cache_list(s, &n->list);
+}
+#endif
+
+/* Initial slabs. */
+#ifdef CONFIG_SMP
+static DEFINE_PER_CPU(struct kmem_cache_cpu, kmem_cache_cpus);
+#endif
+#ifdef CONFIG_NUMA
+/* XXX: really need a DEFINE_PER_NODE for per-node data, but this is better than
+ * a static array */
+static DEFINE_PER_CPU(struct kmem_cache_node, kmem_cache_nodes);
+#endif
+
+#ifdef CONFIG_SMP
+static struct kmem_cache kmem_cpu_cache;
+static DEFINE_PER_CPU(struct kmem_cache_cpu, kmem_cpu_cpus);
+#ifdef CONFIG_NUMA
+static DEFINE_PER_CPU(struct kmem_cache_node, kmem_cpu_nodes); /* XXX per-nid */
+#endif
+#endif
+
+#ifdef CONFIG_NUMA
+static struct kmem_cache kmem_node_cache;
+#ifdef CONFIG_SMP
+static DEFINE_PER_CPU(struct kmem_cache_cpu, kmem_node_cpus);
+#endif
+static DEFINE_PER_CPU(struct kmem_cache_node, kmem_node_nodes); /*XXX per-nid */
+#endif
+
+#ifdef CONFIG_SMP
+static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s,
+ int cpu)
+{
+ struct kmem_cache_cpu *c;
+ int node;
+
+ node = cpu_to_node(cpu);
+
+ c = kmem_cache_alloc_node(&kmem_cpu_cache, GFP_KERNEL, node);
+ if (!c)
+ return NULL;
+
+ init_kmem_cache_cpu(s, c);
+ return c;
+}
+
+static void free_kmem_cache_cpus(struct kmem_cache *s)
+{
+ int cpu;
+
+ for_each_online_cpu(cpu) {
+ struct kmem_cache_cpu *c;
+
+ c = s->cpu_slab[cpu];
+ if (c) {
+ kmem_cache_free(&kmem_cpu_cache, c);
+ s->cpu_slab[cpu] = NULL;
+ }
+ }
+}
+
+static int alloc_kmem_cache_cpus(struct kmem_cache *s)
+{
+ int cpu;
+
+ for_each_online_cpu(cpu) {
+ struct kmem_cache_cpu *c;
+
+ c = s->cpu_slab[cpu];
+ if (c)
+ continue;
+
+ c = alloc_kmem_cache_cpu(s, cpu);
+ if (!c) {
+ free_kmem_cache_cpus(s);
+ return 0;
+ }
+ s->cpu_slab[cpu] = c;
+ }
+ return 1;
+}
+
+#else
+static inline void free_kmem_cache_cpus(struct kmem_cache *s)
+{
+}
+
+static inline int alloc_kmem_cache_cpus(struct kmem_cache *s)
+{
+ init_kmem_cache_cpu(s, &s->cpu_slab);
+ return 1;
+}
+#endif
+
+#ifdef CONFIG_NUMA
+static void free_kmem_cache_nodes(struct kmem_cache *s)
+{
+ int node;
+
+ for_each_node_state(node, N_NORMAL_MEMORY) {
+ struct kmem_cache_node *n;
+
+ n = s->node_slab[node];
+ if (n) {
+ kmem_cache_free(&kmem_node_cache, n);
+ s->node_slab[node] = NULL;
+ }
+ }
+}
+
+static int alloc_kmem_cache_nodes(struct kmem_cache *s)
+{
+ int node;
+
+ for_each_node_state(node, N_NORMAL_MEMORY) {
+ struct kmem_cache_node *n;
+
+ n = kmem_cache_alloc_node(&kmem_node_cache, GFP_KERNEL, node);
+ if (!n) {
+ free_kmem_cache_nodes(s);
+ return 0;
+ }
+ init_kmem_cache_node(s, n);
+ s->node_slab[node] = n;
+ }
+ return 1;
+}
+#else
+static void free_kmem_cache_nodes(struct kmem_cache *s)
+{
+}
+
+static int alloc_kmem_cache_nodes(struct kmem_cache *s)
+{
+ return 1;
+}
+#endif
+
+/*
+ * calculate_sizes() determines the order and the distribution of data within
+ * a slab object.
+ */
+static int calculate_sizes(struct kmem_cache *s)
+{
+ unsigned long flags = s->flags;
+ unsigned long size = s->objsize;
+ unsigned long align = s->align;
+
+ /*
+ * Determine if we can poison the object itself. If the user of
+ * the slab may touch the object after free or before allocation
+ * then we should never poison the object itself.
+ */
+ if (slab_poison(s) && !(flags & SLAB_DESTROY_BY_RCU) && !s->ctor)
+ s->flags |= __OBJECT_POISON;
+ else
+ s->flags &= ~__OBJECT_POISON;
+
+ /*
+ * Round up object size to the next word boundary. We can only
+ * place the free pointer at word boundaries and this determines
+ * the possible location of the free pointer.
+ */
+ size = ALIGN(size, sizeof(void *));
+
+#ifdef CONFIG_SLQB_DEBUG
+ /*
+ * If we are Redzoning then check if there is some space between the
+ * end of the object and the free pointer. If not then add an
+ * additional word to have some bytes to store Redzone information.
+ */
+ if ((flags & SLAB_RED_ZONE) && size == s->objsize)
+ size += sizeof(void *);
+#endif
+
+ /*
+ * With that we have determined the number of bytes in actual use
+ * by the object. This is the potential offset to the free pointer.
+ */
+ s->inuse = size;
+
+ if (((flags & (SLAB_DESTROY_BY_RCU | SLAB_POISON)) || s->ctor)) {
+ /*
+ * Relocate free pointer after the object if it is not
+ * permitted to overwrite the first word of the object on
+ * kmem_cache_free.
+ *
+ * This is the case if we do RCU, have a constructor or
+ * destructor or are poisoning the objects.
+ */
+ s->offset = size;
+ size += sizeof(void *);
+ }
+
+#ifdef CONFIG_SLQB_DEBUG
+ if (flags & SLAB_STORE_USER) {
+ /*
+ * Need to store information about allocs and frees after
+ * the object.
+ */
+ size += 2 * sizeof(struct track);
+ }
+
+ if (flags & SLAB_RED_ZONE) {
+ /*
+ * Add some empty padding so that we can catch
+ * overwrites from earlier objects rather than let
+ * tracking information or the free pointer be
+ * corrupted if an user writes before the start
+ * of the object.
+ */
+ size += sizeof(void *);
+ }
+#endif
+
+ /*
+ * Determine the alignment based on various parameters that the
+ * user specified and the dynamic determination of cache line size
+ * on bootup.
+ */
+ align = calculate_alignment(flags, align, s->objsize);
+
+ /*
+ * SLQB stores one object immediately after another beginning from
+ * offset 0. In order to align the objects we have to simply size
+ * each object to conform to the alignment.
+ */
+ size = ALIGN(size, align);
+ s->size = size;
+ s->order = calculate_order(size);
+
+ if (s->order < 0)
+ return 0;
+
+ s->allocflags = 0;
+ if (s->order)
+ s->allocflags |= __GFP_COMP;
+
+ if (s->flags & SLAB_CACHE_DMA)
+ s->allocflags |= SLQB_DMA;
+
+ if (s->flags & SLAB_RECLAIM_ACCOUNT)
+ s->allocflags |= __GFP_RECLAIMABLE;
+
+ /*
+ * Determine the number of objects per slab
+ */
+ s->objects = (PAGE_SIZE << s->order) / size;
+
+ s->freebatch = max(4UL*PAGE_SIZE / size,
+ min(256UL, 64*PAGE_SIZE / size));
+ if (!s->freebatch)
+ s->freebatch = 1;
+ s->hiwater = s->freebatch << 2;
+
+ return !!s->objects;
+
+}
+
+#ifdef CONFIG_SMP
+/*
+ * Per-cpu allocator can't be used because it always uses slab allocator,
+ * and it can't do per-node allocations.
+ */
+static void *kmem_cache_dyn_array_alloc(int ids)
+{
+ size_t size = sizeof(void *) * ids;
+
+ BUG_ON(!size);
+
+ if (unlikely(!slab_is_available())) {
+ static void *nextmem;
+ static size_t nextleft;
+ void *ret;
+
+ /*
+ * Special case for setting up initial caches. These will
+ * never get freed by definition so we can do it rather
+ * simply.
+ */
+ if (size > nextleft) {
+ nextmem = alloc_pages_exact(size, GFP_KERNEL);
+ if (!nextmem)
+ return NULL;
+ nextleft = roundup(size, PAGE_SIZE);
+ }
+
+ ret = nextmem;
+ nextleft -= size;
+ nextmem += size;
+ memset(ret, 0, size);
+ return ret;
+ } else {
+ return kzalloc(size, GFP_KERNEL);
+ }
+}
+
+static void kmem_cache_dyn_array_free(void *array)
+{
+ if (unlikely(!slab_is_available()))
+ return; /* error case without crashing here (will panic soon) */
+ kfree(array);
+}
+#endif
+
+static int kmem_cache_open(struct kmem_cache *s,
+ const char *name, size_t size, size_t align,
+ unsigned long flags, void (*ctor)(void *), int alloc)
+{
+ unsigned int left_over;
+
+ memset(s, 0, sizeof(struct kmem_cache));
+ s->name = name;
+ s->ctor = ctor;
+ s->objsize = size;
+ s->align = align;
+ s->flags = kmem_cache_flags(size, flags, name, ctor);
+
+ if (!calculate_sizes(s))
+ goto error;
+
+ if (!slab_debug(s)) {
+ left_over = (PAGE_SIZE << s->order) - (s->objects * s->size);
+ s->colour_off = max(cache_line_size(), s->align);
+ s->colour_range = left_over;
+ } else {
+ s->colour_off = 0;
+ s->colour_range = 0;
+ }
+
+ /*
+ * Protect all alloc_kmem_cache_cpus/nodes allocations with slqb_lock
+ * to lock out hotplug, just in case (probably not strictly needed
+ * here).
+ */
+ down_write(&slqb_lock);
+#ifdef CONFIG_SMP
+ s->cpu_slab = kmem_cache_dyn_array_alloc(nr_cpu_ids);
+ if (!s->cpu_slab)
+ goto error_lock;
+# ifdef CONFIG_NUMA
+ s->node_slab = kmem_cache_dyn_array_alloc(nr_node_ids);
+ if (!s->node_slab)
+ goto error_cpu_array;
+# endif
+#endif
+
+ if (likely(alloc)) {
+ if (!alloc_kmem_cache_nodes(s))
+ goto error_node_array;
+
+ if (!alloc_kmem_cache_cpus(s))
+ goto error_nodes;
+ }
+
+ sysfs_slab_add(s);
+ list_add(&s->list, &slab_caches);
+ up_write(&slqb_lock);
+
+ return 1;
+
+error_nodes:
+ free_kmem_cache_nodes(s);
+error_node_array:
+#if defined(CONFIG_NUMA) && defined(CONFIG_SMP)
+ kmem_cache_dyn_array_free(s->node_slab);
+error_cpu_array:
+#endif
+#ifdef CONFIG_SMP
+ kmem_cache_dyn_array_free(s->cpu_slab);
+error_lock:
+#endif
+ up_write(&slqb_lock);
+error:
+ if (flags & SLAB_PANIC)
+ panic("%s: failed to create slab `%s'\n", __func__, name);
+ return 0;
+}
+
+/**
+ * kmem_ptr_validate - check if an untrusted pointer might be a slab entry.
+ * @s: the cache we're checking against
+ * @ptr: pointer to validate
+ *
+ * This verifies that the untrusted pointer looks sane;
+ * it is _not_ a guarantee that the pointer is actually
+ * part of the slab cache in question, but it at least
+ * validates that the pointer can be dereferenced and
+ * looks half-way sane.
+ *
+ * Currently only used for dentry validation.
+ */
+int kmem_ptr_validate(struct kmem_cache *s, const void *ptr)
+{
+ unsigned long addr = (unsigned long)ptr;
+ struct slqb_page *page;
+
+ if (unlikely(addr < PAGE_OFFSET))
+ goto out;
+ if (unlikely(addr > (unsigned long)high_memory - s->size))
+ goto out;
+ if (unlikely(!IS_ALIGNED(addr, s->align)))
+ goto out;
+ if (unlikely(!kern_addr_valid(addr)))
+ goto out;
+ if (unlikely(!kern_addr_valid(addr + s->size - 1)))
+ goto out;
+ if (unlikely(!pfn_valid(addr >> PAGE_SHIFT)))
+ goto out;
+ page = virt_to_head_slqb_page(ptr);
+ if (unlikely(!(page->flags & PG_SLQB_BIT)))
+ goto out;
+ if (unlikely(page->list->cache != s)) /* XXX: ouch, racy */
+ goto out;
+ return 1;
+out:
+ return 0;
+}
+EXPORT_SYMBOL(kmem_ptr_validate);
+
+/*
+ * Determine the size of a slab object
+ */
+unsigned int kmem_cache_size(struct kmem_cache *s)
+{
+ return s->objsize;
+}
+EXPORT_SYMBOL(kmem_cache_size);
+
+const char *kmem_cache_name(struct kmem_cache *s)
+{
+ return s->name;
+}
+EXPORT_SYMBOL(kmem_cache_name);
+
+/*
+ * Release all resources used by a slab cache. No more concurrency on the
+ * slab, so we can touch remote kmem_cache_cpu structures.
+ */
+void kmem_cache_destroy(struct kmem_cache *s)
+{
+#ifdef CONFIG_NUMA
+ int node;
+#endif
+ int cpu;
+
+ down_write(&slqb_lock);
+ list_del(&s->list);
+
+ local_irq_disable();
+#ifdef CONFIG_SMP
+ for_each_online_cpu(cpu) {
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+ struct kmem_cache_list *l = &c->list;
+
+ flush_free_list_all(s, l);
+ flush_remote_free_cache(s, c);
+ }
+#endif
+
+ for_each_online_cpu(cpu) {
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+ struct kmem_cache_list *l = &c->list;
+
+ claim_remote_free_list(s, l);
+ flush_free_list_all(s, l);
+
+ WARN_ON(l->freelist.nr);
+ WARN_ON(l->nr_slabs);
+ WARN_ON(l->nr_partial);
+ }
+
+ free_kmem_cache_cpus(s);
+
+#ifdef CONFIG_NUMA
+ for_each_node_state(node, N_NORMAL_MEMORY) {
+ struct kmem_cache_node *n;
+ struct kmem_cache_list *l;
+
+ n = s->node_slab[node];
+ if (!n)
+ continue;
+ l = &n->list;
+
+ claim_remote_free_list(s, l);
+ flush_free_list_all(s, l);
+
+ WARN_ON(l->freelist.nr);
+ WARN_ON(l->nr_slabs);
+ WARN_ON(l->nr_partial);
+ }
+
+ free_kmem_cache_nodes(s);
+#endif
+ local_irq_enable();
+
+ sysfs_slab_remove(s);
+ up_write(&slqb_lock);
+}
+EXPORT_SYMBOL(kmem_cache_destroy);
+
+/********************************************************************
+ * Kmalloc subsystem
+ *******************************************************************/
+
+struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_SLQB_HIGH + 1] __cacheline_aligned;
+EXPORT_SYMBOL(kmalloc_caches);
+
+#ifdef CONFIG_ZONE_DMA
+struct kmem_cache kmalloc_caches_dma[KMALLOC_SHIFT_SLQB_HIGH + 1] __cacheline_aligned;
+EXPORT_SYMBOL(kmalloc_caches_dma);
+#endif
+
+#ifndef ARCH_KMALLOC_FLAGS
+#define ARCH_KMALLOC_FLAGS SLAB_HWCACHE_ALIGN
+#endif
+
+static struct kmem_cache *open_kmalloc_cache(struct kmem_cache *s,
+ const char *name, int size, gfp_t gfp_flags)
+{
+ unsigned int flags = ARCH_KMALLOC_FLAGS | SLAB_PANIC;
+
+ if (gfp_flags & SLQB_DMA)
+ flags |= SLAB_CACHE_DMA;
+
+ kmem_cache_open(s, name, size, ARCH_KMALLOC_MINALIGN, flags, NULL, 1);
+
+ return s;
+}
+
+/*
+ * Conversion table for small slabs sizes / 8 to the index in the
+ * kmalloc array. This is necessary for slabs < 192 since we have non power
+ * of two cache sizes there. The size of larger slabs can be determined using
+ * fls.
+ */
+static s8 size_index[24] __cacheline_aligned = {
+ 3, /* 8 */
+ 4, /* 16 */
+ 5, /* 24 */
+ 5, /* 32 */
+ 6, /* 40 */
+ 6, /* 48 */
+ 6, /* 56 */
+ 6, /* 64 */
+#if L1_CACHE_BYTES < 64
+ 1, /* 72 */
+ 1, /* 80 */
+ 1, /* 88 */
+ 1, /* 96 */
+#else
+ 7,
+ 7,
+ 7,
+ 7,
+#endif
+ 7, /* 104 */
+ 7, /* 112 */
+ 7, /* 120 */
+ 7, /* 128 */
+#if L1_CACHE_BYTES < 128
+ 2, /* 136 */
+ 2, /* 144 */
+ 2, /* 152 */
+ 2, /* 160 */
+ 2, /* 168 */
+ 2, /* 176 */
+ 2, /* 184 */
+ 2 /* 192 */
+#else
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1
+#endif
+};
+
+static struct kmem_cache *get_slab(size_t size, gfp_t flags)
+{
+ int index;
+
+#if L1_CACHE_BYTES >= 128
+ if (size <= 128) {
+#else
+ if (size <= 192) {
+#endif
+ if (unlikely(!size))
+ return ZERO_SIZE_PTR;
+
+ index = size_index[(size - 1) / 8];
+ } else
+ index = fls(size - 1);
+
+ if (unlikely((flags & SLQB_DMA)))
+ return &kmalloc_caches_dma[index];
+ else
+ return &kmalloc_caches[index];
+}
+
+void *__kmalloc(size_t size, gfp_t flags)
+{
+ struct kmem_cache *s;
+
+ s = get_slab(size, flags);
+ if (unlikely(ZERO_OR_NULL_PTR(s)))
+ return s;
+
+ return __kmem_cache_alloc(s, flags, _RET_IP_);
+}
+EXPORT_SYMBOL(__kmalloc);
+
+#ifdef CONFIG_NUMA
+void *__kmalloc_node(size_t size, gfp_t flags, int node)
+{
+ struct kmem_cache *s;
+
+ s = get_slab(size, flags);
+ if (unlikely(ZERO_OR_NULL_PTR(s)))
+ return s;
+
+ return kmem_cache_alloc_node(s, flags, node);
+}
+EXPORT_SYMBOL(__kmalloc_node);
+#endif
+
+size_t ksize(const void *object)
+{
+ struct slqb_page *page;
+ struct kmem_cache *s;
+
+ BUG_ON(!object);
+ if (unlikely(object == ZERO_SIZE_PTR))
+ return 0;
+
+ page = virt_to_head_slqb_page(object);
+ BUG_ON(!(page->flags & PG_SLQB_BIT));
+
+ s = page->list->cache;
+
+ /*
+ * Debugging requires use of the padding between object
+ * and whatever may come after it.
+ */
+ if (s->flags & (SLAB_RED_ZONE | SLAB_POISON))
+ return s->objsize;
+
+ /*
+ * If we have the need to store the freelist pointer
+ * back there or track user information then we can
+ * only use the space before that information.
+ */
+ if (s->flags & (SLAB_DESTROY_BY_RCU | SLAB_STORE_USER))
+ return s->inuse;
+
+ /*
+ * Else we can use all the padding etc for the allocation
+ */
+ return s->size;
+}
+EXPORT_SYMBOL(ksize);
+
+void kfree(const void *object)
+{
+ struct kmem_cache *s;
+ struct slqb_page *page;
+
+ if (unlikely(ZERO_OR_NULL_PTR(object)))
+ return;
+
+ page = virt_to_head_slqb_page(object);
+ s = page->list->cache;
+
+ slab_free(s, page, (void *)object);
+}
+EXPORT_SYMBOL(kfree);
+
+static void kmem_cache_trim_percpu(void *arg)
+{
+ int cpu = smp_processor_id();
+ struct kmem_cache *s = arg;
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+ struct kmem_cache_list *l = &c->list;
+
+ claim_remote_free_list(s, l);
+ flush_free_list(s, l);
+#ifdef CONFIG_SMP
+ flush_remote_free_cache(s, c);
+#endif
+}
+
+int kmem_cache_shrink(struct kmem_cache *s)
+{
+#ifdef CONFIG_NUMA
+ int node;
+#endif
+
+ on_each_cpu(kmem_cache_trim_percpu, s, 1);
+
+#ifdef CONFIG_NUMA
+ for_each_node_state(node, N_NORMAL_MEMORY) {
+ struct kmem_cache_node *n;
+ struct kmem_cache_list *l;
+
+ n = s->node_slab[node];
+ if (!n)
+ continue;
+ l = &n->list;
+
+ spin_lock_irq(&n->list_lock);
+ claim_remote_free_list(s, l);
+ flush_free_list(s, l);
+ spin_unlock_irq(&n->list_lock);
+ }
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL(kmem_cache_shrink);
+
+#if defined(CONFIG_NUMA) && defined(CONFIG_MEMORY_HOTPLUG)
+static void kmem_cache_reap_percpu(void *arg)
+{
+ int cpu = smp_processor_id();
+ struct kmem_cache *s;
+ long phase = (long)arg;
+
+ list_for_each_entry(s, &slab_caches, list) {
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+ struct kmem_cache_list *l = &c->list;
+
+ if (phase == 0) {
+ flush_free_list_all(s, l);
+ flush_remote_free_cache(s, c);
+ }
+
+ if (phase == 1) {
+ claim_remote_free_list(s, l);
+ flush_free_list_all(s, l);
+ }
+ }
+}
+
+static void kmem_cache_reap(void)
+{
+ struct kmem_cache *s;
+ int node;
+
+ down_read(&slqb_lock);
+ on_each_cpu(kmem_cache_reap_percpu, (void *)0, 1);
+ on_each_cpu(kmem_cache_reap_percpu, (void *)1, 1);
+
+ list_for_each_entry(s, &slab_caches, list) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
+ struct kmem_cache_node *n;
+ struct kmem_cache_list *l;
+
+ n = s->node_slab[node];
+ if (!n)
+ continue;
+ l = &n->list;
+
+ spin_lock_irq(&n->list_lock);
+ claim_remote_free_list(s, l);
+ flush_free_list_all(s, l);
+ spin_unlock_irq(&n->list_lock);
+ }
+ }
+ up_read(&slqb_lock);
+}
+#endif
+
+static void cache_trim_worker(struct work_struct *w)
+{
+ struct delayed_work *work =
+ container_of(w, struct delayed_work, work);
+ struct kmem_cache *s;
+
+ if (!down_read_trylock(&slqb_lock))
+ goto out;
+
+ list_for_each_entry(s, &slab_caches, list) {
+#ifdef CONFIG_NUMA
+ int node = numa_node_id();
+ struct kmem_cache_node *n = s->node_slab[node];
+
+ if (n) {
+ struct kmem_cache_list *l = &n->list;
+
+ spin_lock_irq(&n->list_lock);
+ claim_remote_free_list(s, l);
+ flush_free_list(s, l);
+ spin_unlock_irq(&n->list_lock);
+ }
+#endif
+
+ local_irq_disable();
+ kmem_cache_trim_percpu(s);
+ local_irq_enable();
+ }
+
+ up_read(&slqb_lock);
+out:
+ schedule_delayed_work(work, round_jiffies_relative(3*HZ));
+}
+
+static DEFINE_PER_CPU(struct delayed_work, cache_trim_work);
+
+static void __cpuinit start_cpu_timer(int cpu)
+{
+ struct delayed_work *cache_trim_work = &per_cpu(cache_trim_work, cpu);
+
+ /*
+ * When this gets called from do_initcalls via cpucache_init(),
+ * init_workqueues() has already run, so keventd will be setup
+ * at that time.
+ */
+ if (keventd_up() && cache_trim_work->work.func == NULL) {
+ INIT_DELAYED_WORK(cache_trim_work, cache_trim_worker);
+ schedule_delayed_work_on(cpu, cache_trim_work,
+ __round_jiffies_relative(HZ, cpu));
+ }
+}
+
+static int __init cpucache_init(void)
+{
+ int cpu;
+
+ for_each_online_cpu(cpu)
+ start_cpu_timer(cpu);
+
+ return 0;
+}
+device_initcall(cpucache_init);
+
+#if defined(CONFIG_NUMA) && defined(CONFIG_MEMORY_HOTPLUG)
+static void slab_mem_going_offline_callback(void *arg)
+{
+ kmem_cache_reap();
+}
+
+static void slab_mem_offline_callback(void *arg)
+{
+ /* XXX: should release structures, see CPU offline comment */
+}
+
+static int slab_mem_going_online_callback(void *arg)
+{
+ struct kmem_cache *s;
+ struct kmem_cache_node *n;
+ struct memory_notify *marg = arg;
+ int nid = marg->status_change_nid;
+ int ret = 0;
+
+ /*
+ * If the node's memory is already available, then kmem_cache_node is
+ * already created. Nothing to do.
+ */
+ if (nid < 0)
+ return 0;
+
+ /*
+ * We are bringing a node online. No memory is availabe yet. We must
+ * allocate a kmem_cache_node structure in order to bring the node
+ * online.
+ */
+ down_write(&slqb_lock);
+ list_for_each_entry(s, &slab_caches, list) {
+ /*
+ * XXX: kmem_cache_alloc_node will fallback to other nodes
+ * since memory is not yet available from the node that
+ * is brought up.
+ */
+ if (s->node_slab[nid]) /* could be lefover from last online */
+ continue;
+ n = kmem_cache_alloc(&kmem_node_cache, GFP_KERNEL);
+ if (!n) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ init_kmem_cache_node(s, n);
+ s->node_slab[nid] = n;
+ }
+out:
+ up_write(&slqb_lock);
+ return ret;
+}
+
+static int slab_memory_callback(struct notifier_block *self,
+ unsigned long action, void *arg)
+{
+ int ret = 0;
+
+ switch (action) {
+ case MEM_GOING_ONLINE:
+ ret = slab_mem_going_online_callback(arg);
+ break;
+ case MEM_GOING_OFFLINE:
+ slab_mem_going_offline_callback(arg);
+ break;
+ case MEM_OFFLINE:
+ case MEM_CANCEL_ONLINE:
+ slab_mem_offline_callback(arg);
+ break;
+ case MEM_ONLINE:
+ case MEM_CANCEL_OFFLINE:
+ break;
+ }
+
+ ret = notifier_from_errno(ret);
+ return ret;
+}
+
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
+/********************************************************************
+ * Basic setup of slabs
+ *******************************************************************/
+
+void __init kmem_cache_init(void)
+{
+ int i;
+ unsigned int flags = SLAB_HWCACHE_ALIGN|SLAB_PANIC;
+
+ /*
+ * All the ifdefs are rather ugly here, but it's just the setup code,
+ * so it doesn't have to be too readable :)
+ */
+ kmem_cache_open(&kmem_cache_cache, "kmem_cache",
+ sizeof(struct kmem_cache), 0, flags, NULL, 0);
+#ifdef CONFIG_SMP
+ kmem_cache_open(&kmem_cpu_cache, "kmem_cache_cpu",
+ sizeof(struct kmem_cache_cpu), 0, flags, NULL, 0);
+#endif
+#ifdef CONFIG_NUMA
+ kmem_cache_open(&kmem_node_cache, "kmem_cache_node",
+ sizeof(struct kmem_cache_node), 0, flags, NULL, 0);
+#endif
+
+#ifdef CONFIG_SMP
+ for_each_possible_cpu(i) {
+ struct kmem_cache_cpu *c;
+
+ c = &per_cpu(kmem_cache_cpus, i);
+ init_kmem_cache_cpu(&kmem_cache_cache, c);
+ kmem_cache_cache.cpu_slab[i] = c;
+
+ c = &per_cpu(kmem_cpu_cpus, i);
+ init_kmem_cache_cpu(&kmem_cpu_cache, c);
+ kmem_cpu_cache.cpu_slab[i] = c;
+
+#ifdef CONFIG_NUMA
+ c = &per_cpu(kmem_node_cpus, i);
+ init_kmem_cache_cpu(&kmem_node_cache, c);
+ kmem_node_cache.cpu_slab[i] = c;
+#endif
+ }
+#else
+ init_kmem_cache_cpu(&kmem_cache_cache, &kmem_cache_cache.cpu_slab);
+#endif
+
+#ifdef CONFIG_NUMA
+ for_each_node_state(i, N_NORMAL_MEMORY) {
+ struct kmem_cache_node *n;
+
+ n = &per_cpu(kmem_cache_nodes, i);
+ init_kmem_cache_node(&kmem_cache_cache, n);
+ kmem_cache_cache.node_slab[i] = n;
+#ifdef CONFIG_SMP
+ n = &per_cpu(kmem_cpu_nodes, i);
+ init_kmem_cache_node(&kmem_cpu_cache, n);
+ kmem_cpu_cache.node_slab[i] = n;
+#endif
+ n = &per_cpu(kmem_node_nodes, i);
+ init_kmem_cache_node(&kmem_node_cache, n);
+ kmem_node_cache.node_slab[i] = n;
+ }
+#endif
+
+ /* Caches that are not of the two-to-the-power-of size */
+ if (L1_CACHE_BYTES < 64 && KMALLOC_MIN_SIZE <= 64) {
+ open_kmalloc_cache(&kmalloc_caches[1],
+ "kmalloc-96", 96, GFP_KERNEL);
+#ifdef CONFIG_ZONE_DMA
+ open_kmalloc_cache(&kmalloc_caches_dma[1],
+ "kmalloc_dma-96", 96, GFP_KERNEL|SLQB_DMA);
+#endif
+ }
+ if (L1_CACHE_BYTES < 128 && KMALLOC_MIN_SIZE <= 128) {
+ open_kmalloc_cache(&kmalloc_caches[2],
+ "kmalloc-192", 192, GFP_KERNEL);
+#ifdef CONFIG_ZONE_DMA
+ open_kmalloc_cache(&kmalloc_caches_dma[2],
+ "kmalloc_dma-192", 192, GFP_KERNEL|SLQB_DMA);
+#endif
+ }
+
+ for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_SLQB_HIGH; i++) {
+ open_kmalloc_cache(&kmalloc_caches[i],
+ "kmalloc", 1 << i, GFP_KERNEL);
+#ifdef CONFIG_ZONE_DMA
+ open_kmalloc_cache(&kmalloc_caches_dma[i],
+ "kmalloc_dma", 1 << i, GFP_KERNEL|SLQB_DMA);
+#endif
+ }
+
+ /*
+ * Patch up the size_index table if we have strange large alignment
+ * requirements for the kmalloc array. This is only the case for
+ * mips it seems. The standard arches will not generate any code here.
+ *
+ * Largest permitted alignment is 256 bytes due to the way we
+ * handle the index determination for the smaller caches.
+ *
+ * Make sure that nothing crazy happens if someone starts tinkering
+ * around with ARCH_KMALLOC_MINALIGN
+ */
+ BUILD_BUG_ON(KMALLOC_MIN_SIZE > 256 ||
+ (KMALLOC_MIN_SIZE & (KMALLOC_MIN_SIZE - 1)));
+
+ for (i = 8; i < KMALLOC_MIN_SIZE; i += 8)
+ size_index[(i - 1) / 8] = KMALLOC_SHIFT_LOW;
+
+ /* Provide the correct kmalloc names now that the caches are up */
+ for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_SLQB_HIGH; i++) {
+ kmalloc_caches[i].name =
+ kasprintf(GFP_KERNEL, "kmalloc-%d", 1 << i);
+#ifdef CONFIG_ZONE_DMA
+ kmalloc_caches_dma[i].name =
+ kasprintf(GFP_KERNEL, "kmalloc_dma-%d", 1 << i);
+#endif
+ }
+
+#ifdef CONFIG_SMP
+ register_cpu_notifier(&slab_notifier);
+#endif
+#ifdef CONFIG_NUMA
+ hotplug_memory_notifier(slab_memory_callback, 1);
+#endif
+ /*
+ * smp_init() has not yet been called, so no worries about memory
+ * ordering with __slab_is_available.
+ */
+ __slab_is_available = 1;
+}
+
+/*
+ * Some basic slab creation sanity checks
+ */
+static int kmem_cache_create_ok(const char *name, size_t size,
+ size_t align, unsigned long flags)
+{
+ struct kmem_cache *tmp;
+
+ /*
+ * Sanity checks... these are all serious usage bugs.
+ */
+ if (!name || in_interrupt() || (size < sizeof(void *))) {
+ printk(KERN_ERR "kmem_cache_create(): early error in slab %s\n",
+ name);
+ dump_stack();
+
+ return 0;
+ }
+
+ down_read(&slqb_lock);
+
+ list_for_each_entry(tmp, &slab_caches, list) {
+ char x;
+ int res;
+
+ /*
+ * This happens when the module gets unloaded and doesn't
+ * destroy its slab cache and no-one else reuses the vmalloc
+ * area of the module. Print a warning.
+ */
+ res = probe_kernel_address(tmp->name, x);
+ if (res) {
+ printk(KERN_ERR
+ "SLAB: cache with size %d has lost its name\n",
+ tmp->size);
+ continue;
+ }
+
+ if (!strcmp(tmp->name, name)) {
+ printk(KERN_ERR
+ "SLAB: duplicate cache %s\n", name);
+ dump_stack();
+ up_read(&slqb_lock);
+
+ return 0;
+ }
+ }
+
+ up_read(&slqb_lock);
+
+ WARN_ON(strchr(name, ' ')); /* It confuses parsers */
+ if (flags & SLAB_DESTROY_BY_RCU)
+ WARN_ON(flags & SLAB_POISON);
+
+ return 1;
+}
+
+struct kmem_cache *kmem_cache_create(const char *name, size_t size,
+ size_t align, unsigned long flags, void (*ctor)(void *))
+{
+ struct kmem_cache *s;
+
+ if (!kmem_cache_create_ok(name, size, align, flags))
+ goto err;
+
+ s = kmem_cache_alloc(&kmem_cache_cache, GFP_KERNEL);
+ if (!s)
+ goto err;
+
+ if (kmem_cache_open(s, name, size, align, flags, ctor, 1))
+ return s;
+
+ kmem_cache_free(&kmem_cache_cache, s);
+
+err:
+ if (flags & SLAB_PANIC)
+ panic("%s: failed to create slab `%s'\n", __func__, name);
+
+ return NULL;
+}
+EXPORT_SYMBOL(kmem_cache_create);
+
+#ifdef CONFIG_SMP
+/*
+ * Use the cpu notifier to insure that the cpu slabs are flushed when
+ * necessary.
+ */
+static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ long cpu = (long)hcpu;
+ struct kmem_cache *s;
+
+ switch (action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ down_write(&slqb_lock);
+ list_for_each_entry(s, &slab_caches, list) {
+ if (s->cpu_slab[cpu]) /* could be lefover last online */
+ continue;
+ s->cpu_slab[cpu] = alloc_kmem_cache_cpu(s, cpu);
+ if (!s->cpu_slab[cpu]) {
+ up_read(&slqb_lock);
+ return NOTIFY_BAD;
+ }
+ }
+ up_write(&slqb_lock);
+ break;
+
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ case CPU_DOWN_FAILED:
+ case CPU_DOWN_FAILED_FROZEN:
+ start_cpu_timer(cpu);
+ break;
+
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+ cancel_rearming_delayed_work(&per_cpu(cache_trim_work, cpu));
+ per_cpu(cache_trim_work, cpu).work.func = NULL;
+ break;
+
+ case CPU_UP_CANCELED:
+ case CPU_UP_CANCELED_FROZEN:
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ /*
+ * XXX: Freeing here doesn't work because objects can still be
+ * on this CPU's list. periodic timer needs to check if a CPU
+ * is offline and then try to cleanup from there. Same for node
+ * offline.
+ */
+ default:
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata slab_notifier = {
+ .notifier_call = slab_cpuup_callback
+};
+
+#endif
+
+#ifdef CONFIG_SLQB_DEBUG
+void *__kmalloc_track_caller(size_t size, gfp_t flags, unsigned long caller)
+{
+ struct kmem_cache *s;
+ int node = -1;
+
+ s = get_slab(size, flags);
+ if (unlikely(ZERO_OR_NULL_PTR(s)))
+ return s;
+
+#ifdef CONFIG_NUMA
+ if (unlikely(current->flags & (PF_SPREAD_SLAB | PF_MEMPOLICY)))
+ node = alternate_nid(s, flags, node);
+#endif
+ return slab_alloc(s, flags, node, caller);
+}
+
+void *__kmalloc_node_track_caller(size_t size, gfp_t flags, int node,
+ unsigned long caller)
+{
+ struct kmem_cache *s;
+
+ s = get_slab(size, flags);
+ if (unlikely(ZERO_OR_NULL_PTR(s)))
+ return s;
+
+ return slab_alloc(s, flags, node, caller);
+}
+#endif
+
+#if defined(CONFIG_SLQB_SYSFS) || defined(CONFIG_SLABINFO)
+struct stats_gather {
+ struct kmem_cache *s;
+ spinlock_t lock;
+ unsigned long nr_slabs;
+ unsigned long nr_partial;
+ unsigned long nr_inuse;
+ unsigned long nr_objects;
+
+#ifdef CONFIG_SLQB_STATS
+ unsigned long stats[NR_SLQB_STAT_ITEMS];
+#endif
+};
+
+static void __gather_stats(void *arg)
+{
+ unsigned long nr_slabs;
+ unsigned long nr_partial;
+ unsigned long nr_inuse;
+ struct stats_gather *gather = arg;
+ int cpu = smp_processor_id();
+ struct kmem_cache *s = gather->s;
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+ struct kmem_cache_list *l = &c->list;
+ struct slqb_page *page;
+#ifdef CONFIG_SLQB_STATS
+ int i;
+#endif
+
+ spin_lock(&l->page_lock);
+ nr_slabs = l->nr_slabs;
+ nr_partial = l->nr_partial;
+ nr_inuse = (nr_slabs - nr_partial) * s->objects;
+
+ list_for_each_entry(page, &l->partial, lru) {
+ nr_inuse += page->inuse;
+ }
+ spin_unlock(&l->page_lock);
+
+ spin_lock(&gather->lock);
+ gather->nr_slabs += nr_slabs;
+ gather->nr_partial += nr_partial;
+ gather->nr_inuse += nr_inuse;
+#ifdef CONFIG_SLQB_STATS
+ for (i = 0; i < NR_SLQB_STAT_ITEMS; i++)
+ gather->stats[i] += l->stats[i];
+#endif
+ spin_unlock(&gather->lock);
+}
+
+/* must be called with slqb_lock held */
+static void gather_stats_locked(struct kmem_cache *s,
+ struct stats_gather *stats)
+{
+#ifdef CONFIG_NUMA
+ int node;
+#endif
+
+ memset(stats, 0, sizeof(struct stats_gather));
+ stats->s = s;
+ spin_lock_init(&stats->lock);
+
+ on_each_cpu(__gather_stats, stats, 1);
+
+#ifdef CONFIG_NUMA
+ for_each_online_node(node) {
+ struct kmem_cache_node *n = s->node_slab[node];
+ struct kmem_cache_list *l = &n->list;
+ struct slqb_page *page;
+ unsigned long flags;
+#ifdef CONFIG_SLQB_STATS
+ int i;
+#endif
+
+ spin_lock_irqsave(&n->list_lock, flags);
+#ifdef CONFIG_SLQB_STATS
+ for (i = 0; i < NR_SLQB_STAT_ITEMS; i++)
+ stats->stats[i] += l->stats[i];
+#endif
+ stats->nr_slabs += l->nr_slabs;
+ stats->nr_partial += l->nr_partial;
+ stats->nr_inuse += (l->nr_slabs - l->nr_partial) * s->objects;
+
+ list_for_each_entry(page, &l->partial, lru) {
+ stats->nr_inuse += page->inuse;
+ }
+ spin_unlock_irqrestore(&n->list_lock, flags);
+ }
+#endif
+
+ stats->nr_objects = stats->nr_slabs * s->objects;
+}
+
+#ifdef CONFIG_SLQB_SYSFS
+static void gather_stats(struct kmem_cache *s, struct stats_gather *stats)
+{
+ down_read(&slqb_lock); /* hold off hotplug */
+ gather_stats_locked(s, stats);
+ up_read(&slqb_lock);
+}
+#endif
+#endif
+
+/*
+ * The /proc/slabinfo ABI
+ */
+#ifdef CONFIG_SLABINFO
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+ssize_t slabinfo_write(struct file *file, const char __user * buffer,
+ size_t count, loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+static void print_slabinfo_header(struct seq_file *m)
+{
+ seq_puts(m, "slabinfo - version: 2.1\n");
+ seq_puts(m, "# name <active_objs> <num_objs> <objsize> "
+ "<objperslab> <pagesperslab>");
+ seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>");
+ seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
+ seq_putc(m, '\n');
+}
+
+static void *s_start(struct seq_file *m, loff_t *pos)
+{
+ loff_t n = *pos;
+
+ down_read(&slqb_lock);
+ if (!n)
+ print_slabinfo_header(m);
+
+ return seq_list_start(&slab_caches, *pos);
+}
+
+static void *s_next(struct seq_file *m, void *p, loff_t *pos)
+{
+ return seq_list_next(p, &slab_caches, pos);
+}
+
+static void s_stop(struct seq_file *m, void *p)
+{
+ up_read(&slqb_lock);
+}
+
+static int s_show(struct seq_file *m, void *p)
+{
+ struct stats_gather stats;
+ struct kmem_cache *s;
+
+ s = list_entry(p, struct kmem_cache, list);
+
+ gather_stats_locked(s, &stats);
+
+ seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", s->name, stats.nr_inuse,
+ stats.nr_objects, s->size, s->objects, (1 << s->order));
+ seq_printf(m, " : tunables %4u %4u %4u", slab_hiwater(s),
+ slab_freebatch(s), 0);
+ seq_printf(m, " : slabdata %6lu %6lu %6lu", stats.nr_slabs,
+ stats.nr_slabs, 0UL);
+ seq_putc(m, '\n');
+ return 0;
+}
+
+static const struct seq_operations slabinfo_op = {
+ .start = s_start,
+ .next = s_next,
+ .stop = s_stop,
+ .show = s_show,
+};
+
+static int slabinfo_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &slabinfo_op);
+}
+
+static const struct file_operations proc_slabinfo_operations = {
+ .open = slabinfo_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int __init slab_proc_init(void)
+{
+ proc_create("slabinfo", S_IWUSR|S_IRUGO, NULL,
+ &proc_slabinfo_operations);
+ return 0;
+}
+module_init(slab_proc_init);
+#endif /* CONFIG_SLABINFO */
+
+#ifdef CONFIG_SLQB_SYSFS
+/*
+ * sysfs API
+ */
+#define to_slab_attr(n) container_of(n, struct slab_attribute, attr)
+#define to_slab(n) container_of(n, struct kmem_cache, kobj);
+
+struct slab_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct kmem_cache *s, char *buf);
+ ssize_t (*store)(struct kmem_cache *s, const char *x, size_t count);
+};
+
+#define SLAB_ATTR_RO(_name) \
+ static struct slab_attribute _name##_attr = __ATTR_RO(_name)
+
+#define SLAB_ATTR(_name) \
+ static struct slab_attribute _name##_attr = \
+ __ATTR(_name, 0644, _name##_show, _name##_store)
+
+static ssize_t slab_size_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->size);
+}
+SLAB_ATTR_RO(slab_size);
+
+static ssize_t align_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->align);
+}
+SLAB_ATTR_RO(align);
+
+static ssize_t object_size_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->objsize);
+}
+SLAB_ATTR_RO(object_size);
+
+static ssize_t objs_per_slab_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->objects);
+}
+SLAB_ATTR_RO(objs_per_slab);
+
+static ssize_t order_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->order);
+}
+SLAB_ATTR_RO(order);
+
+static ssize_t ctor_show(struct kmem_cache *s, char *buf)
+{
+ if (s->ctor) {
+ int n = sprint_symbol(buf, (unsigned long)s->ctor);
+
+ return n + sprintf(buf + n, "\n");
+ }
+ return 0;
+}
+SLAB_ATTR_RO(ctor);
+
+static ssize_t slabs_show(struct kmem_cache *s, char *buf)
+{
+ struct stats_gather stats;
+
+ gather_stats(s, &stats);
+
+ return sprintf(buf, "%lu\n", stats.nr_slabs);
+}
+SLAB_ATTR_RO(slabs);
+
+static ssize_t objects_show(struct kmem_cache *s, char *buf)
+{
+ struct stats_gather stats;
+
+ gather_stats(s, &stats);
+
+ return sprintf(buf, "%lu\n", stats.nr_inuse);
+}
+SLAB_ATTR_RO(objects);
+
+static ssize_t total_objects_show(struct kmem_cache *s, char *buf)
+{
+ struct stats_gather stats;
+
+ gather_stats(s, &stats);
+
+ return sprintf(buf, "%lu\n", stats.nr_objects);
+}
+SLAB_ATTR_RO(total_objects);
+
+static ssize_t reclaim_account_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_RECLAIM_ACCOUNT));
+}
+SLAB_ATTR_RO(reclaim_account);
+
+static ssize_t hwcache_align_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_HWCACHE_ALIGN));
+}
+SLAB_ATTR_RO(hwcache_align);
+
+#ifdef CONFIG_ZONE_DMA
+static ssize_t cache_dma_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_CACHE_DMA));
+}
+SLAB_ATTR_RO(cache_dma);
+#endif
+
+static ssize_t destroy_by_rcu_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_DESTROY_BY_RCU));
+}
+SLAB_ATTR_RO(destroy_by_rcu);
+
+static ssize_t red_zone_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_RED_ZONE));
+}
+SLAB_ATTR_RO(red_zone);
+
+static ssize_t poison_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_POISON));
+}
+SLAB_ATTR_RO(poison);
+
+static ssize_t store_user_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_STORE_USER));
+}
+SLAB_ATTR_RO(store_user);
+
+static ssize_t hiwater_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ long hiwater;
+ int err;
+
+ err = strict_strtol(buf, 10, &hiwater);
+ if (err)
+ return err;
+
+ if (hiwater < 0)
+ return -EINVAL;
+
+ s->hiwater = hiwater;
+
+ return length;
+}
+
+static ssize_t hiwater_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", slab_hiwater(s));
+}
+SLAB_ATTR(hiwater);
+
+static ssize_t freebatch_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ long freebatch;
+ int err;
+
+ err = strict_strtol(buf, 10, &freebatch);
+ if (err)
+ return err;
+
+ if (freebatch <= 0 || freebatch - 1 > s->hiwater)
+ return -EINVAL;
+
+ s->freebatch = freebatch;
+
+ return length;
+}
+
+static ssize_t freebatch_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", slab_freebatch(s));
+}
+SLAB_ATTR(freebatch);
+
+#ifdef CONFIG_SLQB_STATS
+static int show_stat(struct kmem_cache *s, char *buf, enum stat_item si)
+{
+ struct stats_gather stats;
+ int len;
+#ifdef CONFIG_SMP
+ int cpu;
+#endif
+
+ gather_stats(s, &stats);
+
+ len = sprintf(buf, "%lu", stats.stats[si]);
+
+#ifdef CONFIG_SMP
+ for_each_online_cpu(cpu) {
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+ struct kmem_cache_list *l = &c->list;
+
+ if (len < PAGE_SIZE - 20)
+ len += sprintf(buf+len, " C%d=%lu", cpu, l->stats[si]);
+ }
+#endif
+ return len + sprintf(buf + len, "\n");
+}
+
+#define STAT_ATTR(si, text) \
+static ssize_t text##_show(struct kmem_cache *s, char *buf) \
+{ \
+ return show_stat(s, buf, si); \
+} \
+SLAB_ATTR_RO(text); \
+
+STAT_ATTR(ALLOC, alloc);
+STAT_ATTR(ALLOC_SLAB_FILL, alloc_slab_fill);
+STAT_ATTR(ALLOC_SLAB_NEW, alloc_slab_new);
+STAT_ATTR(FREE, free);
+STAT_ATTR(FREE_REMOTE, free_remote);
+STAT_ATTR(FLUSH_FREE_LIST, flush_free_list);
+STAT_ATTR(FLUSH_FREE_LIST_OBJECTS, flush_free_list_objects);
+STAT_ATTR(FLUSH_FREE_LIST_REMOTE, flush_free_list_remote);
+STAT_ATTR(FLUSH_SLAB_PARTIAL, flush_slab_partial);
+STAT_ATTR(FLUSH_SLAB_FREE, flush_slab_free);
+STAT_ATTR(FLUSH_RFREE_LIST, flush_rfree_list);
+STAT_ATTR(FLUSH_RFREE_LIST_OBJECTS, flush_rfree_list_objects);
+STAT_ATTR(CLAIM_REMOTE_LIST, claim_remote_list);
+STAT_ATTR(CLAIM_REMOTE_LIST_OBJECTS, claim_remote_list_objects);
+#endif
+
+static struct attribute *slab_attrs[] = {
+ &slab_size_attr.attr,
+ &object_size_attr.attr,
+ &objs_per_slab_attr.attr,
+ &order_attr.attr,
+ &objects_attr.attr,
+ &total_objects_attr.attr,
+ &slabs_attr.attr,
+ &ctor_attr.attr,
+ &align_attr.attr,
+ &hwcache_align_attr.attr,
+ &reclaim_account_attr.attr,
+ &destroy_by_rcu_attr.attr,
+ &red_zone_attr.attr,
+ &poison_attr.attr,
+ &store_user_attr.attr,
+ &hiwater_attr.attr,
+ &freebatch_attr.attr,
+#ifdef CONFIG_ZONE_DMA
+ &cache_dma_attr.attr,
+#endif
+#ifdef CONFIG_SLQB_STATS
+ &alloc_attr.attr,
+ &alloc_slab_fill_attr.attr,
+ &alloc_slab_new_attr.attr,
+ &free_attr.attr,
+ &free_remote_attr.attr,
+ &flush_free_list_attr.attr,
+ &flush_free_list_objects_attr.attr,
+ &flush_free_list_remote_attr.attr,
+ &flush_slab_partial_attr.attr,
+ &flush_slab_free_attr.attr,
+ &flush_rfree_list_attr.attr,
+ &flush_rfree_list_objects_attr.attr,
+ &claim_remote_list_attr.attr,
+ &claim_remote_list_objects_attr.attr,
+#endif
+ NULL
+};
+
+static struct attribute_group slab_attr_group = {
+ .attrs = slab_attrs,
+};
+
+static ssize_t slab_attr_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ struct slab_attribute *attribute;
+ struct kmem_cache *s;
+ int err;
+
+ attribute = to_slab_attr(attr);
+ s = to_slab(kobj);
+
+ if (!attribute->show)
+ return -EIO;
+
+ err = attribute->show(s, buf);
+
+ return err;
+}
+
+static ssize_t slab_attr_store(struct kobject *kobj,
+ struct attribute *attr, const char *buf, size_t len)
+{
+ struct slab_attribute *attribute;
+ struct kmem_cache *s;
+ int err;
+
+ attribute = to_slab_attr(attr);
+ s = to_slab(kobj);
+
+ if (!attribute->store)
+ return -EIO;
+
+ err = attribute->store(s, buf, len);
+
+ return err;
+}
+
+static void kmem_cache_release(struct kobject *kobj)
+{
+ struct kmem_cache *s = to_slab(kobj);
+
+ kmem_cache_free(&kmem_cache_cache, s);
+}
+
+static struct sysfs_ops slab_sysfs_ops = {
+ .show = slab_attr_show,
+ .store = slab_attr_store,
+};
+
+static struct kobj_type slab_ktype = {
+ .sysfs_ops = &slab_sysfs_ops,
+ .release = kmem_cache_release
+};
+
+static int uevent_filter(struct kset *kset, struct kobject *kobj)
+{
+ struct kobj_type *ktype = get_ktype(kobj);
+
+ if (ktype == &slab_ktype)
+ return 1;
+ return 0;
+}
+
+static struct kset_uevent_ops slab_uevent_ops = {
+ .filter = uevent_filter,
+};
+
+static struct kset *slab_kset;
+
+static int sysfs_available __read_mostly;
+
+static int sysfs_slab_add(struct kmem_cache *s)
+{
+ int err;
+
+ if (!sysfs_available)
+ return 0;
+
+ s->kobj.kset = slab_kset;
+ err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, s->name);
+ if (err) {
+ kobject_put(&s->kobj);
+ return err;
+ }
+
+ err = sysfs_create_group(&s->kobj, &slab_attr_group);
+ if (err)
+ return err;
+
+ kobject_uevent(&s->kobj, KOBJ_ADD);
+
+ return 0;
+}
+
+static void sysfs_slab_remove(struct kmem_cache *s)
+{
+ kobject_uevent(&s->kobj, KOBJ_REMOVE);
+ kobject_del(&s->kobj);
+ kobject_put(&s->kobj);
+}
+
+static int __init slab_sysfs_init(void)
+{
+ struct kmem_cache *s;
+ int err;
+
+ slab_kset = kset_create_and_add("slab", &slab_uevent_ops, kernel_kobj);
+ if (!slab_kset) {
+ printk(KERN_ERR "Cannot register slab subsystem.\n");
+ return -ENOSYS;
+ }
+
+ down_write(&slqb_lock);
+
+ sysfs_available = 1;
+
+ list_for_each_entry(s, &slab_caches, list) {
+ err = sysfs_slab_add(s);
+ if (err)
+ printk(KERN_ERR "SLQB: Unable to add boot slab %s"
+ " to sysfs\n", s->name);
+ }
+
+ up_write(&slqb_lock);
+
+ return 0;
+}
+device_initcall(slab_sysfs_init);
+
+#endif
diff --git a/mm/slub.c b/mm/slub.c
index 7ab54ecbd3f3..5e805a6fe36c 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -9,6 +9,7 @@
*/
#include <linux/mm.h>
+#include <linux/swap.h> /* struct reclaim_state */
#include <linux/module.h>
#include <linux/bit_spinlock.h>
#include <linux/interrupt.h>
@@ -16,7 +17,7 @@
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <trace/kmemtrace.h>
+#include <linux/kmemtrace.h>
#include <linux/cpu.h>
#include <linux/cpuset.h>
#include <linux/mempolicy.h>
@@ -1170,6 +1171,8 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
__ClearPageSlab(page);
reset_page_mapcount(page);
+ if (current->reclaim_state)
+ current->reclaim_state->reclaimed_slab += pages;
__free_pages(page, order);
}
@@ -1909,7 +1912,7 @@ static inline int calculate_order(int size)
* Doh this slab cannot be placed using slub_max_order.
*/
order = slab_order(size, 1, MAX_ORDER, 1);
- if (order <= MAX_ORDER)
+ if (order < MAX_ORDER)
return order;
return -ENOSYS;
}
@@ -2522,6 +2525,7 @@ __setup("slub_min_order=", setup_slub_min_order);
static int __init setup_slub_max_order(char *str)
{
get_option(&str, &slub_max_order);
+ slub_max_order = min(slub_max_order, MAX_ORDER - 1);
return 1;
}
diff --git a/mm/util.c b/mm/util.c
index 55bef160b9f1..abc65aa7cdfc 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -4,9 +4,11 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/sched.h>
-#include <linux/tracepoint.h>
#include <asm/uaccess.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/kmem.h>
+
/**
* kstrdup - allocate space for and copy an existing string
* @s: the string to duplicate
@@ -255,13 +257,6 @@ int __attribute__((weak)) get_user_pages_fast(unsigned long start,
EXPORT_SYMBOL_GPL(get_user_pages_fast);
/* Tracepoints definitions. */
-DEFINE_TRACE(kmalloc);
-DEFINE_TRACE(kmem_cache_alloc);
-DEFINE_TRACE(kmalloc_node);
-DEFINE_TRACE(kmem_cache_alloc_node);
-DEFINE_TRACE(kfree);
-DEFINE_TRACE(kmem_cache_free);
-
EXPORT_TRACEPOINT_SYMBOL(kmalloc);
EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc);
EXPORT_TRACEPOINT_SYMBOL(kmalloc_node);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index fab19876b4d1..083716ea38c9 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -402,6 +402,7 @@ overflow:
printk(KERN_WARNING
"vmap allocation for size %lu failed: "
"use vmalloc=<size> to increase size.\n", size);
+ kfree(va);
return ERR_PTR(-EBUSY);
}
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index c67fe6f75653..7f7de1a04de6 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -114,9 +114,9 @@ int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
EXPORT_SYMBOL(vlan_gro_receive);
int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
- unsigned int vlan_tci, struct napi_gro_fraginfo *info)
+ unsigned int vlan_tci)
{
- struct sk_buff *skb = napi_fraginfo_skb(napi, info);
+ struct sk_buff *skb = napi_frags_skb(napi);
if (!skb)
return NET_RX_DROP;
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index b4b9068e55a7..25ba41e35338 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -671,13 +671,7 @@ static int vlan_ethtool_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
const struct vlan_dev_info *vlan = vlan_dev_info(dev);
- struct net_device *real_dev = vlan->real_dev;
-
- if (!real_dev->ethtool_ops ||
- !real_dev->ethtool_ops->get_settings)
- return -EOPNOTSUPP;
-
- return real_dev->ethtool_ops->get_settings(real_dev, cmd);
+ return dev_ethtool_get_settings(vlan->real_dev, cmd);
}
static void vlan_ethtool_get_drvinfo(struct net_device *dev,
@@ -691,24 +685,13 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev,
static u32 vlan_ethtool_get_rx_csum(struct net_device *dev)
{
const struct vlan_dev_info *vlan = vlan_dev_info(dev);
- struct net_device *real_dev = vlan->real_dev;
-
- if (real_dev->ethtool_ops == NULL ||
- real_dev->ethtool_ops->get_rx_csum == NULL)
- return 0;
- return real_dev->ethtool_ops->get_rx_csum(real_dev);
+ return dev_ethtool_get_rx_csum(vlan->real_dev);
}
static u32 vlan_ethtool_get_flags(struct net_device *dev)
{
const struct vlan_dev_info *vlan = vlan_dev_info(dev);
- struct net_device *real_dev = vlan->real_dev;
-
- if (!(real_dev->features & NETIF_F_HW_VLAN_RX) ||
- real_dev->ethtool_ops == NULL ||
- real_dev->ethtool_ops->get_flags == NULL)
- return 0;
- return real_dev->ethtool_ops->get_flags(real_dev);
+ return dev_ethtool_get_flags(vlan->real_dev);
}
static const struct ethtool_ops vlan_ethtool_ops = {
diff --git a/net/Kconfig b/net/Kconfig
index ce77db4fcec8..c19f549c8e74 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -119,12 +119,6 @@ menuconfig NETFILTER
<file:Documentation/Changes> under "iptables" for the location of
these packages.
- Make sure to say N to "Fast switching" below if you intend to say Y
- here, as Fast switching currently bypasses netfilter.
-
- Chances are that you should say Y here if you compile a kernel which
- will run as a router and N for regular hosts. If unsure, say N.
-
if NETFILTER
config NETFILTER_DEBUG
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 582d8877078c..a05d45eb3ba1 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -88,10 +88,13 @@ static struct device_type bt_link = {
static void add_conn(struct work_struct *work)
{
struct hci_conn *conn = container_of(work, struct hci_conn, work_add);
+ struct hci_dev *hdev = conn->hdev;
/* ensure previous del is complete */
flush_work(&conn->work_del);
+ dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
+
if (device_add(&conn->dev) < 0) {
BT_ERR("Failed to register connection device");
return;
@@ -154,12 +157,8 @@ void hci_conn_init_sysfs(struct hci_conn *conn)
void hci_conn_add_sysfs(struct hci_conn *conn)
{
- struct hci_dev *hdev = conn->hdev;
-
BT_DBG("conn %p", conn);
- dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
-
queue_work(bt_workq, &conn->work_add);
}
diff --git a/net/core/datagram.c b/net/core/datagram.c
index b01a76abe1d2..e2a36f05cdf7 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -260,7 +260,9 @@ int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
spin_unlock_bh(&sk->sk_receive_queue.lock);
}
- skb_free_datagram(sk, skb);
+ kfree_skb(skb);
+ sk_mem_reclaim_partial(sk);
+
return err;
}
@@ -351,17 +353,111 @@ fault:
}
/**
+ * skb_copy_datagram_const_iovec - Copy a datagram to an iovec.
+ * @skb: buffer to copy
+ * @offset: offset in the buffer to start copying from
+ * @to: io vector to copy to
+ * @to_offset: offset in the io vector to start copying to
+ * @len: amount of data to copy from buffer to iovec
+ *
+ * Returns 0 or -EFAULT.
+ * Note: the iovec is not modified during the copy.
+ */
+int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset,
+ const struct iovec *to, int to_offset,
+ int len)
+{
+ int start = skb_headlen(skb);
+ int i, copy = start - offset;
+
+ /* Copy header. */
+ if (copy > 0) {
+ if (copy > len)
+ copy = len;
+ if (memcpy_toiovecend(to, skb->data + offset, to_offset, copy))
+ goto fault;
+ if ((len -= copy) == 0)
+ return 0;
+ offset += copy;
+ to_offset += copy;
+ }
+
+ /* Copy paged appendix. Hmm... why does this look so complicated? */
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ int end;
+
+ WARN_ON(start > offset + len);
+
+ end = start + skb_shinfo(skb)->frags[i].size;
+ if ((copy = end - offset) > 0) {
+ int err;
+ u8 *vaddr;
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ struct page *page = frag->page;
+
+ if (copy > len)
+ copy = len;
+ vaddr = kmap(page);
+ err = memcpy_toiovecend(to, vaddr + frag->page_offset +
+ offset - start, to_offset, copy);
+ kunmap(page);
+ if (err)
+ goto fault;
+ if (!(len -= copy))
+ return 0;
+ offset += copy;
+ to_offset += copy;
+ }
+ start = end;
+ }
+
+ if (skb_shinfo(skb)->frag_list) {
+ struct sk_buff *list = skb_shinfo(skb)->frag_list;
+
+ for (; list; list = list->next) {
+ int end;
+
+ WARN_ON(start > offset + len);
+
+ end = start + list->len;
+ if ((copy = end - offset) > 0) {
+ if (copy > len)
+ copy = len;
+ if (skb_copy_datagram_const_iovec(list,
+ offset - start,
+ to, to_offset,
+ copy))
+ goto fault;
+ if ((len -= copy) == 0)
+ return 0;
+ offset += copy;
+ to_offset += copy;
+ }
+ start = end;
+ }
+ }
+ if (!len)
+ return 0;
+
+fault:
+ return -EFAULT;
+}
+EXPORT_SYMBOL(skb_copy_datagram_const_iovec);
+
+/**
* skb_copy_datagram_from_iovec - Copy a datagram from an iovec.
* @skb: buffer to copy
* @offset: offset in the buffer to start copying to
* @from: io vector to copy to
+ * @from_offset: offset in the io vector to start copying from
* @len: amount of data to copy to buffer from iovec
*
* Returns 0 or -EFAULT.
- * Note: the iovec is modified during the copy.
+ * Note: the iovec is not modified during the copy.
*/
int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
- struct iovec *from, int len)
+ const struct iovec *from, int from_offset,
+ int len)
{
int start = skb_headlen(skb);
int i, copy = start - offset;
@@ -370,11 +466,12 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
if (copy > 0) {
if (copy > len)
copy = len;
- if (memcpy_fromiovec(skb->data + offset, from, copy))
+ if (memcpy_fromiovecend(skb->data + offset, from, 0, copy))
goto fault;
if ((len -= copy) == 0)
return 0;
offset += copy;
+ from_offset += copy;
}
/* Copy paged appendix. Hmm... why does this look so complicated? */
@@ -393,8 +490,9 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
if (copy > len)
copy = len;
vaddr = kmap(page);
- err = memcpy_fromiovec(vaddr + frag->page_offset +
- offset - start, from, copy);
+ err = memcpy_fromiovecend(vaddr + frag->page_offset +
+ offset - start,
+ from, from_offset, copy);
kunmap(page);
if (err)
goto fault;
@@ -402,6 +500,7 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
if (!(len -= copy))
return 0;
offset += copy;
+ from_offset += copy;
}
start = end;
}
@@ -420,11 +519,14 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
copy = len;
if (skb_copy_datagram_from_iovec(list,
offset - start,
- from, copy))
+ from,
+ from_offset,
+ copy))
goto fault;
if ((len -= copy) == 0)
return 0;
offset += copy;
+ from_offset += copy;
}
start = end;
}
diff --git a/net/core/dev.c b/net/core/dev.c
index e2e9e4af3ace..14dd725aaab7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1735,8 +1735,12 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
{
u32 hash;
- if (skb_rx_queue_recorded(skb))
- return skb_get_rx_queue(skb) % dev->real_num_tx_queues;
+ if (skb_rx_queue_recorded(skb)) {
+ hash = skb_get_rx_queue(skb);
+ while (unlikely (hash >= dev->real_num_tx_queues))
+ hash -= dev->real_num_tx_queues;
+ return hash;
+ }
if (skb->sk && skb->sk->sk_hash)
hash = skb->sk->sk_hash;
@@ -2379,18 +2383,13 @@ void *skb_gro_header(struct sk_buff *skb, unsigned int hlen)
unsigned int offset = skb_gro_offset(skb);
hlen += offset;
- if (hlen <= skb_headlen(skb))
- return skb->data + offset;
-
- if (unlikely(!skb_shinfo(skb)->nr_frags ||
- skb_shinfo(skb)->frags[0].size <=
- hlen - skb_headlen(skb) ||
+ if (unlikely(skb_headlen(skb) ||
+ skb_shinfo(skb)->frags[0].size < hlen ||
PageHighMem(skb_shinfo(skb)->frags[0].page)))
return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
return page_address(skb_shinfo(skb)->frags[0].page) +
- skb_shinfo(skb)->frags[0].page_offset +
- offset - skb_headlen(skb);
+ skb_shinfo(skb)->frags[0].page_offset + offset;
}
EXPORT_SYMBOL(skb_gro_header);
@@ -2526,16 +2525,10 @@ void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
}
EXPORT_SYMBOL(napi_reuse_skb);
-struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi,
- struct napi_gro_fraginfo *info)
+struct sk_buff *napi_get_frags(struct napi_struct *napi)
{
struct net_device *dev = napi->dev;
struct sk_buff *skb = napi->skb;
- struct ethhdr *eth;
- skb_frag_t *frag;
- int i;
-
- napi->skb = NULL;
if (!skb) {
skb = netdev_alloc_skb(dev, GRO_MAX_HEAD + NET_IP_ALIGN);
@@ -2543,47 +2536,14 @@ struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi,
goto out;
skb_reserve(skb, NET_IP_ALIGN);
- }
-
- BUG_ON(info->nr_frags > MAX_SKB_FRAGS);
- frag = info->frags;
- for (i = 0; i < info->nr_frags; i++) {
- skb_fill_page_desc(skb, i, frag->page, frag->page_offset,
- frag->size);
- frag++;
+ napi->skb = skb;
}
- skb_shinfo(skb)->nr_frags = info->nr_frags;
-
- skb->data_len = info->len;
- skb->len += info->len;
- skb->truesize += info->len;
-
- skb_reset_mac_header(skb);
- skb_gro_reset_offset(skb);
-
- eth = skb_gro_header(skb, sizeof(*eth));
- if (!eth) {
- napi_reuse_skb(napi, skb);
- skb = NULL;
- goto out;
- }
-
- skb_gro_pull(skb, sizeof(*eth));
-
- /*
- * This works because the only protocols we care about don't require
- * special handling. We'll fix it up properly at the end.
- */
- skb->protocol = eth->h_proto;
-
- skb->ip_summed = info->ip_summed;
- skb->csum = info->csum;
out:
return skb;
}
-EXPORT_SYMBOL(napi_fraginfo_skb);
+EXPORT_SYMBOL(napi_get_frags);
int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret)
{
@@ -2613,9 +2573,39 @@ int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret)
}
EXPORT_SYMBOL(napi_frags_finish);
-int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info)
+struct sk_buff *napi_frags_skb(struct napi_struct *napi)
{
- struct sk_buff *skb = napi_fraginfo_skb(napi, info);
+ struct sk_buff *skb = napi->skb;
+ struct ethhdr *eth;
+
+ napi->skb = NULL;
+
+ skb_reset_mac_header(skb);
+ skb_gro_reset_offset(skb);
+
+ eth = skb_gro_header(skb, sizeof(*eth));
+ if (!eth) {
+ napi_reuse_skb(napi, skb);
+ skb = NULL;
+ goto out;
+ }
+
+ skb_gro_pull(skb, sizeof(*eth));
+
+ /*
+ * This works because the only protocols we care about don't require
+ * special handling. We'll fix it up properly at the end.
+ */
+ skb->protocol = eth->h_proto;
+
+out:
+ return skb;
+}
+EXPORT_SYMBOL(napi_frags_skb);
+
+int napi_gro_frags(struct napi_struct *napi)
+{
+ struct sk_buff *skb = napi_frags_skb(napi);
if (!skb)
return NET_RX_DROP;
@@ -2719,7 +2709,7 @@ void netif_napi_del(struct napi_struct *napi)
struct sk_buff *skb, *next;
list_del_init(&napi->dev_list);
- kfree_skb(napi->skb);
+ napi_free_frags(napi);
for (skb = napi->gro_list; skb; skb = next) {
next = skb->next;
@@ -3444,6 +3434,252 @@ void dev_set_rx_mode(struct net_device *dev)
netif_addr_unlock_bh(dev);
}
+/* hw addresses list handling functions */
+
+static int __hw_addr_add(struct list_head *list, unsigned char *addr,
+ int addr_len, unsigned char addr_type)
+{
+ struct netdev_hw_addr *ha;
+ int alloc_size;
+
+ if (addr_len > MAX_ADDR_LEN)
+ return -EINVAL;
+
+ alloc_size = sizeof(*ha);
+ if (alloc_size < L1_CACHE_BYTES)
+ alloc_size = L1_CACHE_BYTES;
+ ha = kmalloc(alloc_size, GFP_ATOMIC);
+ if (!ha)
+ return -ENOMEM;
+ memcpy(ha->addr, addr, addr_len);
+ ha->type = addr_type;
+ list_add_tail_rcu(&ha->list, list);
+ return 0;
+}
+
+static void ha_rcu_free(struct rcu_head *head)
+{
+ struct netdev_hw_addr *ha;
+
+ ha = container_of(head, struct netdev_hw_addr, rcu_head);
+ kfree(ha);
+}
+
+static int __hw_addr_del_ii(struct list_head *list, unsigned char *addr,
+ int addr_len, unsigned char addr_type,
+ int ignore_index)
+{
+ struct netdev_hw_addr *ha;
+ int i = 0;
+
+ list_for_each_entry(ha, list, list) {
+ if (i++ != ignore_index &&
+ !memcmp(ha->addr, addr, addr_len) &&
+ (ha->type == addr_type || !addr_type)) {
+ list_del_rcu(&ha->list);
+ call_rcu(&ha->rcu_head, ha_rcu_free);
+ return 0;
+ }
+ }
+ return -ENOENT;
+}
+
+static int __hw_addr_add_multiple_ii(struct list_head *to_list,
+ struct list_head *from_list,
+ int addr_len, unsigned char addr_type,
+ int ignore_index)
+{
+ int err;
+ struct netdev_hw_addr *ha, *ha2;
+ unsigned char type;
+
+ list_for_each_entry(ha, from_list, list) {
+ type = addr_type ? addr_type : ha->type;
+ err = __hw_addr_add(to_list, ha->addr, addr_len, type);
+ if (err)
+ goto unroll;
+ }
+ return 0;
+
+unroll:
+ list_for_each_entry(ha2, from_list, list) {
+ if (ha2 == ha)
+ break;
+ type = addr_type ? addr_type : ha2->type;
+ __hw_addr_del_ii(to_list, ha2->addr, addr_len, type,
+ ignore_index);
+ }
+ return err;
+}
+
+static void __hw_addr_del_multiple_ii(struct list_head *to_list,
+ struct list_head *from_list,
+ int addr_len, unsigned char addr_type,
+ int ignore_index)
+{
+ struct netdev_hw_addr *ha;
+ unsigned char type;
+
+ list_for_each_entry(ha, from_list, list) {
+ type = addr_type ? addr_type : ha->type;
+ __hw_addr_del_ii(to_list, ha->addr, addr_len, addr_type,
+ ignore_index);
+ }
+}
+
+static void __hw_addr_flush(struct list_head *list)
+{
+ struct netdev_hw_addr *ha, *tmp;
+
+ list_for_each_entry_safe(ha, tmp, list, list) {
+ list_del_rcu(&ha->list);
+ call_rcu(&ha->rcu_head, ha_rcu_free);
+ }
+}
+
+/* Device addresses handling functions */
+
+static void dev_addr_flush(struct net_device *dev)
+{
+ /* rtnl_mutex must be held here */
+
+ __hw_addr_flush(&dev->dev_addr_list);
+ dev->dev_addr = NULL;
+}
+
+static int dev_addr_init(struct net_device *dev)
+{
+ unsigned char addr[MAX_ADDR_LEN];
+ struct netdev_hw_addr *ha;
+ int err;
+
+ /* rtnl_mutex must be held here */
+
+ INIT_LIST_HEAD(&dev->dev_addr_list);
+ memset(addr, 0, sizeof(*addr));
+ err = __hw_addr_add(&dev->dev_addr_list, addr, sizeof(*addr),
+ NETDEV_HW_ADDR_T_LAN);
+ if (!err) {
+ /*
+ * Get the first (previously created) address from the list
+ * and set dev_addr pointer to this location.
+ */
+ ha = list_first_entry(&dev->dev_addr_list,
+ struct netdev_hw_addr, list);
+ dev->dev_addr = ha->addr;
+ }
+ return err;
+}
+
+/**
+ * dev_addr_add - Add a device address
+ * @dev: device
+ * @addr: address to add
+ * @addr_type: address type
+ *
+ * Add a device address to the device or increase the reference count if
+ * it already exists.
+ *
+ * The caller must hold the rtnl_mutex.
+ */
+int dev_addr_add(struct net_device *dev, unsigned char *addr,
+ unsigned char addr_type)
+{
+ int err;
+
+ ASSERT_RTNL();
+
+ err = __hw_addr_add(&dev->dev_addr_list, addr, dev->addr_len,
+ addr_type);
+ if (!err)
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+ return err;
+}
+EXPORT_SYMBOL(dev_addr_add);
+
+/**
+ * dev_addr_del - Release a device address.
+ * @dev: device
+ * @addr: address to delete
+ * @addr_type: address type
+ *
+ * Release reference to a device address and remove it from the device
+ * if the reference count drops to zero.
+ *
+ * The caller must hold the rtnl_mutex.
+ */
+int dev_addr_del(struct net_device *dev, unsigned char *addr,
+ unsigned char addr_type)
+{
+ int err;
+
+ ASSERT_RTNL();
+
+ err = __hw_addr_del_ii(&dev->dev_addr_list, addr, dev->addr_len,
+ addr_type, 0);
+ if (!err)
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+ return err;
+}
+EXPORT_SYMBOL(dev_addr_del);
+
+/**
+ * dev_addr_add_multiple - Add device addresses from another device
+ * @to_dev: device to which addresses will be added
+ * @from_dev: device from which addresses will be added
+ * @addr_type: address type - 0 means type will be used from from_dev
+ *
+ * Add device addresses of the one device to another.
+ **
+ * The caller must hold the rtnl_mutex.
+ */
+int dev_addr_add_multiple(struct net_device *to_dev,
+ struct net_device *from_dev,
+ unsigned char addr_type)
+{
+ int err;
+
+ ASSERT_RTNL();
+
+ if (from_dev->addr_len != to_dev->addr_len)
+ return -EINVAL;
+ err = __hw_addr_add_multiple_ii(&to_dev->dev_addr_list,
+ &from_dev->dev_addr_list,
+ to_dev->addr_len, addr_type, 0);
+ if (!err)
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev);
+ return err;
+}
+EXPORT_SYMBOL(dev_addr_add_multiple);
+
+/**
+ * dev_addr_del_multiple - Delete device addresses by another device
+ * @to_dev: device where the addresses will be deleted
+ * @from_dev: device by which addresses the addresses will be deleted
+ * @addr_type: address type - 0 means type will used from from_dev
+ *
+ * Deletes addresses in to device by the list of addresses in from device.
+ *
+ * The caller must hold the rtnl_mutex.
+ */
+int dev_addr_del_multiple(struct net_device *to_dev,
+ struct net_device *from_dev,
+ unsigned char addr_type)
+{
+ ASSERT_RTNL();
+
+ if (from_dev->addr_len != to_dev->addr_len)
+ return -EINVAL;
+ __hw_addr_del_multiple_ii(&to_dev->dev_addr_list,
+ &from_dev->dev_addr_list,
+ to_dev->addr_len, addr_type, 0);
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev);
+ return 0;
+}
+EXPORT_SYMBOL(dev_addr_del_multiple);
+
+/* unicast and multicast addresses handling functions */
+
int __dev_addr_delete(struct dev_addr_list **list, int *count,
void *addr, int alen, int glbl)
{
@@ -4771,13 +5007,16 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
if (!tx) {
printk(KERN_ERR "alloc_netdev: Unable to allocate "
"tx qdiscs.\n");
- kfree(p);
- return NULL;
+ goto free_p;
}
dev = (struct net_device *)
(((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
dev->padded = (char *)dev - (char *)p;
+
+ if (dev_addr_init(dev))
+ goto free_tx;
+
dev_net_set(dev, &init_net);
dev->_tx = tx;
@@ -4792,6 +5031,13 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
setup(dev);
strcpy(dev->name, name);
return dev;
+
+free_tx:
+ kfree(tx);
+
+free_p:
+ kfree(p);
+ return NULL;
}
EXPORT_SYMBOL(alloc_netdev_mq);
@@ -4811,6 +5057,9 @@ void free_netdev(struct net_device *dev)
kfree(dev->_tx);
+ /* Flush device addresses */
+ dev_addr_flush(dev);
+
list_for_each_entry_safe(p, n, &dev->napi_list, dev_list)
netif_napi_del(p);
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 9fd0dc3cca99..7668ff543123 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -23,7 +23,7 @@
#include <linux/bitops.h>
#include <net/genetlink.h>
-#include <trace/skb.h>
+#include <trace/events/skb.h>
#include <asm/unaligned.h>
@@ -51,7 +51,7 @@ static struct genl_family net_drop_monitor_family = {
.id = GENL_ID_GENERATE,
.hdrsize = 0,
.name = "NET_DM",
- .version = 1,
+ .version = 2,
.maxattr = NET_DM_CMD_MAX,
};
@@ -65,13 +65,17 @@ static void reset_per_cpu_data(struct per_cpu_dm_data *data)
{
size_t al;
struct net_dm_alert_msg *msg;
+ struct nlattr *nla;
al = sizeof(struct net_dm_alert_msg);
al += dm_hit_limit * sizeof(struct net_dm_drop_point);
+ al += sizeof(struct nlattr);
+
data->skb = genlmsg_new(al, GFP_KERNEL);
genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family,
0, NET_DM_CMD_ALERT);
- msg = __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_alert_msg));
+ nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg));
+ msg = nla_data(nla);
memset(msg, 0, al);
atomic_set(&data->dm_hit_count, dm_hit_limit);
}
@@ -115,6 +119,7 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
{
struct net_dm_alert_msg *msg;
struct nlmsghdr *nlh;
+ struct nlattr *nla;
int i;
struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
@@ -127,7 +132,8 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
}
nlh = (struct nlmsghdr *)data->skb->data;
- msg = genlmsg_data(nlmsg_data(nlh));
+ nla = genlmsg_data(nlmsg_data(nlh));
+ msg = nla_data(nla);
for (i = 0; i < msg->entries; i++) {
if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) {
msg->points[i].count++;
@@ -139,6 +145,7 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
* We need to create a new entry
*/
__nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point));
+ nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point));
memcpy(msg->points[msg->entries].pc, &location, sizeof(void *));
msg->points[msg->entries].count = 1;
msg->entries++;
diff --git a/net/core/iovec.c b/net/core/iovec.c
index 4c9c0121c9da..40a76ce19d9f 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -98,6 +98,31 @@ int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
}
/*
+ * Copy kernel to iovec. Returns -EFAULT on error.
+ */
+
+int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
+ int offset, int len)
+{
+ int copy;
+ for (; len > 0; ++iov) {
+ /* Skip over the finished iovecs */
+ if (unlikely(offset >= iov->iov_len)) {
+ offset -= iov->iov_len;
+ continue;
+ }
+ copy = min_t(unsigned int, iov->iov_len - offset, len);
+ offset = 0;
+ if (copy_to_user(iov->iov_base, kdata, copy))
+ return -EFAULT;
+ kdata += copy;
+ len -= copy;
+ }
+
+ return 0;
+}
+
+/*
* Copy iovec to kernel. Returns -EFAULT on error.
*
* Note: this modifies the original iovec.
@@ -122,10 +147,11 @@ int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
}
/*
- * For use with ip_build_xmit
+ * Copy iovec from kernel. Returns -EFAULT on error.
*/
-int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
- int len)
+
+int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
+ int offset, int len)
{
/* Skip over the finished iovecs */
while (offset >= iov->iov_len) {
@@ -236,3 +262,4 @@ EXPORT_SYMBOL(csum_partial_copy_fromiovecend);
EXPORT_SYMBOL(memcpy_fromiovec);
EXPORT_SYMBOL(memcpy_fromiovecend);
EXPORT_SYMBOL(memcpy_toiovec);
+EXPORT_SYMBOL(memcpy_toiovecend);
diff --git a/net/core/net-traces.c b/net/core/net-traces.c
index c8fb45665e4f..499a67eaf3ae 100644
--- a/net/core/net-traces.c
+++ b/net/core/net-traces.c
@@ -19,11 +19,11 @@
#include <linux/workqueue.h>
#include <linux/netlink.h>
#include <linux/net_dropmon.h>
-#include <trace/skb.h>
#include <asm/unaligned.h>
#include <asm/bitops.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/skb.h>
-DEFINE_TRACE(kfree_skb);
EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb);
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index e3bebd36f053..6b3edc9e6f19 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -115,41 +115,34 @@ static void net_free(struct net *net)
kmem_cache_free(net_cachep, net);
}
-struct net *copy_net_ns(unsigned long flags, struct net *old_net)
+static struct net *net_create(void)
{
- struct net *new_net = NULL;
- int err;
-
- get_net(old_net);
-
- if (!(flags & CLONE_NEWNET))
- return old_net;
-
- err = -ENOMEM;
- new_net = net_alloc();
- if (!new_net)
- goto out_err;
+ struct net *net;
+ int rv;
+ net = net_alloc();
+ if (!net)
+ return ERR_PTR(-ENOMEM);
mutex_lock(&net_mutex);
- err = setup_net(new_net);
- if (!err) {
+ rv = setup_net(net);
+ if (rv == 0) {
rtnl_lock();
- list_add_tail(&new_net->list, &net_namespace_list);
+ list_add_tail(&net->list, &net_namespace_list);
rtnl_unlock();
}
mutex_unlock(&net_mutex);
+ if (rv < 0) {
+ net_free(net);
+ return ERR_PTR(rv);
+ }
+ return net;
+}
- if (err)
- goto out_free;
-out:
- put_net(old_net);
- return new_net;
-
-out_free:
- net_free(new_net);
-out_err:
- new_net = ERR_PTR(err);
- goto out;
+struct net *copy_net_ns(unsigned long flags, struct net *old_net)
+{
+ if (!(flags & CLONE_NEWNET))
+ return get_net(old_net);
+ return net_create();
}
static void cleanup_net(struct work_struct *work)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f091a5a845c1..c4906bbcd60e 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -65,7 +65,7 @@
#include <asm/uaccess.h>
#include <asm/system.h>
-#include <trace/skb.h>
+#include <trace/events/skb.h>
#include "kmap_skb.h"
@@ -502,7 +502,9 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size)
shinfo->gso_segs = 0;
shinfo->gso_type = 0;
shinfo->ip6_frag_id = 0;
+ shinfo->tx_flags.flags = 0;
shinfo->frag_list = NULL;
+ memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps));
memset(skb, 0, offsetof(struct sk_buff, tail));
skb->data = skb->head + NET_SKB_PAD;
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c
index 5d8a2a56fd39..932408dca86d 100644
--- a/net/decnet/dn_nsp_in.c
+++ b/net/decnet/dn_nsp_in.c
@@ -578,6 +578,7 @@ out:
static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig, struct sk_buff_head *queue)
{
int err;
+ int skb_len;
/* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
number of warnings when compiling with -W --ANK
@@ -592,22 +593,12 @@ static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig
if (err)
goto out;
+ skb_len = skb->len;
skb_set_owner_r(skb, sk);
skb_queue_tail(queue, skb);
- /* This code only runs from BH or BH protected context.
- * Therefore the plain read_lock is ok here. -DaveM
- */
- read_lock(&sk->sk_callback_lock);
- if (!sock_flag(sk, SOCK_DEAD)) {
- struct socket *sock = sk->sk_socket;
- wake_up_interruptible(sk->sk_sleep);
- if (sock && sock->fasync_list &&
- !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
- __kill_fasync(sock->fasync_list, sig,
- (sig == SIGURG) ? POLL_PRI : POLL_IN);
- }
- read_unlock(&sk->sk_callback_lock);
+ if (!sock_flag(sk, SOCK_DEAD))
+ sk->sk_data_ready(sk, skb_len);
out:
return err;
}
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index b2cf91e4ccaa..9d26a3da37e5 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -407,7 +407,7 @@ config INET_XFRM_MODE_BEET
If unsure, say Y.
config INET_LRO
- tristate "Large Receive Offload (ipv4/tcp)"
+ bool "Large Receive Offload (ipv4/tcp)"
---help---
Support for Large Receive Offload (ipv4/tcp).
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 7f03373b8c07..170689681aa2 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1003,8 +1003,6 @@ void inet_register_protosw(struct inet_protosw *p)
out:
spin_unlock_bh(&inetsw_lock);
- synchronize_net();
-
return;
out_permanent:
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 588a7796e3e3..b0b273503e2a 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -198,8 +198,6 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
tmo = 0;
r->idiag_family = tw->tw_family;
- r->idiag_state = tw->tw_state;
- r->idiag_timer = 0;
r->idiag_retrans = 0;
r->id.idiag_if = tw->tw_bound_dev_if;
r->id.idiag_cookie[0] = (u32)(unsigned long)tw;
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index 8554d0ea1719..68a8d892c711 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -49,19 +49,22 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw,
inet_twsk_put(tw);
}
-void inet_twsk_put(struct inet_timewait_sock *tw)
+static noinline void inet_twsk_free(struct inet_timewait_sock *tw)
{
- if (atomic_dec_and_test(&tw->tw_refcnt)) {
- struct module *owner = tw->tw_prot->owner;
- twsk_destructor((struct sock *)tw);
+ struct module *owner = tw->tw_prot->owner;
+ twsk_destructor((struct sock *)tw);
#ifdef SOCK_REFCNT_DEBUG
- printk(KERN_DEBUG "%s timewait_sock %p released\n",
- tw->tw_prot->name, tw);
+ pr_debug("%s timewait_sock %p released\n", tw->tw_prot->name, tw);
#endif
- release_net(twsk_net(tw));
- kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
- module_put(owner);
- }
+ release_net(twsk_net(tw));
+ kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
+ module_put(owner);
+}
+
+void inet_twsk_put(struct inet_timewait_sock *tw)
+{
+ if (atomic_dec_and_test(&tw->tw_refcnt))
+ inet_twsk_free(tw);
}
EXPORT_SYMBOL_GPL(inet_twsk_put);
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 1a58a6fa1dc0..40f6206b2aa9 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -358,10 +358,12 @@ static int ip_rcv_finish(struct sk_buff *skb)
goto drop;
rt = skb->rtable;
- if (rt->rt_type == RTN_MULTICAST)
- IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCASTPKTS);
- else if (rt->rt_type == RTN_BROADCAST)
- IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCASTPKTS);
+ if (rt->rt_type == RTN_MULTICAST) {
+ IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCAST,
+ skb->len);
+ } else if (rt->rt_type == RTN_BROADCAST)
+ IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCAST,
+ skb->len);
return dst_input(skb);
@@ -384,7 +386,8 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
if (skb->pkt_type == PACKET_OTHERHOST)
goto drop;
- IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INRECEIVES);
+
+ IP_UPD_PO_STATS_BH(dev_net(dev), IPSTATS_MIB_IN, skb->len);
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 3e7e910c7c0f..ea19c37ccc0c 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -181,10 +181,10 @@ static inline int ip_finish_output2(struct sk_buff *skb)
struct net_device *dev = dst->dev;
unsigned int hh_len = LL_RESERVED_SPACE(dev);
- if (rt->rt_type == RTN_MULTICAST)
- IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTMCASTPKTS);
- else if (rt->rt_type == RTN_BROADCAST)
- IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTBCASTPKTS);
+ if (rt->rt_type == RTN_MULTICAST) {
+ IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len);
+ } else if (rt->rt_type == RTN_BROADCAST)
+ IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTBCAST, skb->len);
/* Be paranoid, rather than too clever. */
if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {
@@ -244,7 +244,7 @@ int ip_mc_output(struct sk_buff *skb)
/*
* If the indicated interface is up and running, send the packet.
*/
- IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS);
+ IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);
skb->dev = dev;
skb->protocol = htons(ETH_P_IP);
@@ -298,7 +298,7 @@ int ip_output(struct sk_buff *skb)
{
struct net_device *dev = skb->dst->dev;
- IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS);
+ IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);
skb->dev = dev;
skb->protocol = htons(ETH_P_IP);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index cf0cdeeb1db0..f25542c48b7d 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -90,14 +90,14 @@ static const struct file_operations sockstat_seq_fops = {
/* snmp items */
static const struct snmp_mib snmp4_ipstats_list[] = {
- SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES),
+ SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INPKTS),
SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS),
SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS),
SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS),
SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS),
SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS),
- SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTREQUESTS),
+ SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTPKTS),
SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS),
SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
@@ -118,6 +118,12 @@ static const struct snmp_mib snmp4_ipextstats_list[] = {
SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS),
SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS),
+ SNMP_MIB_ITEM("InOctets", IPSTATS_MIB_INOCTETS),
+ SNMP_MIB_ITEM("OutOctets", IPSTATS_MIB_OUTOCTETS),
+ SNMP_MIB_ITEM("InMcastOctets", IPSTATS_MIB_INMCASTOCTETS),
+ SNMP_MIB_ITEM("OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
+ SNMP_MIB_ITEM("InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
+ SNMP_MIB_ITEM("OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
SNMP_MIB_SENTINEL
};
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index b35a950d2e06..cd2b97f1b6e1 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -161,13 +161,12 @@ static __u16 const msstab[] = {
*/
__u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
{
- struct tcp_sock *tp = tcp_sk(sk);
const struct iphdr *iph = ip_hdr(skb);
const struct tcphdr *th = tcp_hdr(skb);
int mssind;
const __u16 mss = *mssp;
- tp->last_synq_overflow = jiffies;
+ tcp_synq_overflow(sk);
/* XXX sort msstab[] by probability? Binary search? */
for (mssind = 0; mss > msstab[mssind + 1]; mssind++)
@@ -268,7 +267,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
if (!sysctl_tcp_syncookies || !th->ack)
goto out;
- if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) ||
+ if (tcp_synq_no_recent_overflow(sk) ||
(mss = cookie_check(skb, cookie)) == 0) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
goto out;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index eec3e6f9956c..eeb8a92aa416 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -77,7 +77,7 @@ int sysctl_tcp_window_scaling __read_mostly = 1;
int sysctl_tcp_sack __read_mostly = 1;
int sysctl_tcp_fack __read_mostly = 1;
int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH;
-int sysctl_tcp_ecn __read_mostly;
+int sysctl_tcp_ecn __read_mostly = 2;
int sysctl_tcp_dsack __read_mostly = 1;
int sysctl_tcp_app_win __read_mostly = 31;
int sysctl_tcp_adv_win_scale __read_mostly = 2;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 5d427f86b414..fc79e3416288 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1593,7 +1593,7 @@ process:
#endif
{
if (!tcp_prequeue(sk, skb))
- ret = tcp_v4_do_rcv(sk, skb);
+ ret = tcp_v4_do_rcv(sk, skb);
}
} else
sk_add_backlog(sk, skb);
@@ -2343,7 +2343,7 @@ void tcp4_proc_exit(void)
struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb)
{
- struct iphdr *iph = ip_hdr(skb);
+ struct iphdr *iph = skb_gro_network_header(skb);
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 59aec609cec6..79c39dc9b01c 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -288,7 +288,7 @@ static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb)
struct tcp_sock *tp = tcp_sk(sk);
tp->ecn_flags = 0;
- if (sysctl_tcp_ecn) {
+ if (sysctl_tcp_ecn == 1) {
TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE | TCPCB_FLAG_CWR;
tp->ecn_flags = TCP_ECN_OK;
}
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 8f04bd9da274..bc1a920c34a1 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -70,7 +70,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
idev = __in6_dev_get(skb->dev);
- IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INRECEIVES);
+ IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_IN, skb->len);
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
!idev || unlikely(idev->cnf.disable_ipv6)) {
@@ -242,8 +242,9 @@ int ip6_mc_input(struct sk_buff *skb)
struct ipv6hdr *hdr;
int deliver;
- IP6_INC_STATS_BH(dev_net(skb->dst->dev),
- ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS);
+ IP6_UPD_PO_STATS_BH(dev_net(skb->dst->dev),
+ ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCAST,
+ skb->len);
hdr = ipv6_hdr(skb);
deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 9fb49c3b518a..735a2bf4b5f1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -159,7 +159,8 @@ static int ip6_output2(struct sk_buff *skb)
}
}
- IP6_INC_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCASTPKTS);
+ IP6_UPD_PO_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCAST,
+ skb->len);
}
return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
@@ -275,8 +276,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
mtu = dst_mtu(dst);
if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
- IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
- IPSTATS_MIB_OUTREQUESTS);
+ IP6_UPD_PO_STATS(net, ip6_dst_idev(skb->dst),
+ IPSTATS_MIB_OUT, skb->len);
return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
dst_output);
}
@@ -1516,7 +1517,7 @@ int ip6_push_pending_frames(struct sock *sk)
skb->mark = sk->sk_mark;
skb->dst = dst_clone(&rt->u.dst);
- IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
+ IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
if (proto == IPPROTO_ICMPV6) {
struct inet6_dev *idev = ip6_dst_idev(skb->dst);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index d994c55a5b16..af256d47fd35 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1100,8 +1100,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
struct ip6_tnl_parm *p = &t->parms;
struct flowi *fl = &t->fl;
- memcpy(&dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
- memcpy(&dev->broadcast, &p->raddr, sizeof(struct in6_addr));
+ memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
+ memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
/* Set up flowi template */
ipv6_addr_copy(&fl->fl6_src, &p->laddr);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index a51fb33e6864..4b48819a5b8d 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1449,7 +1449,8 @@ static void mld_sendpack(struct sk_buff *skb)
int err;
struct flowi fl;
- IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
+
payload_len = (skb->tail - skb->network_header) - sizeof(*pip6);
mldlen = skb->tail - skb->transport_header;
pip6->payload_len = htons(payload_len);
@@ -1473,13 +1474,15 @@ static void mld_sendpack(struct sk_buff *skb)
if (err)
goto err_out;
+ payload_len = skb->len;
+
err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
dst_output);
out:
if (!err) {
ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT);
ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
- IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTMCASTPKTS);
+ IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
} else
IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS);
@@ -1773,10 +1776,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
IPV6_TLV_PADN, 0 };
struct flowi fl;
- rcu_read_lock();
- IP6_INC_STATS(net, __in6_dev_get(dev),
- IPSTATS_MIB_OUTREQUESTS);
- rcu_read_unlock();
if (type == ICMPV6_MGM_REDUCTION)
snd_addr = &in6addr_linklocal_allrouters;
else
@@ -1786,6 +1785,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
payload_len = len + sizeof(ra);
full_len = sizeof(struct ipv6hdr) + payload_len;
+ rcu_read_lock();
+ IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
+ IPSTATS_MIB_OUT, full_len);
+ rcu_read_unlock();
+
skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
if (skb == NULL) {
@@ -1838,13 +1842,14 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
if (err)
goto err_out;
+
err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
dst_output);
out:
if (!err) {
ICMP6MSGOUT_INC_STATS(net, idev, type);
ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
- IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTMCASTPKTS);
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len);
} else
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 9f061d1adbc2..ab65cc51b00e 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -533,7 +533,7 @@ void ndisc_send_skb(struct sk_buff *skb,
skb->dst = dst;
idev = in6_dev_get(dst->dev);
- IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
dst_output);
@@ -1613,7 +1613,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
buff->dst = dst;
idev = in6_dev_get(dst->dev);
- IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
dst_output);
if (!err) {
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
index 14e6724d5672..91490ad9302c 100644
--- a/net/ipv6/netfilter/ip6t_ipv6header.c
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c
@@ -50,14 +50,14 @@ ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
struct ipv6_opt_hdr _hdr;
int hdrlen;
- /* Is there enough space for the next ext header? */
- if (len < (int)sizeof(struct ipv6_opt_hdr))
- return false;
/* No more exthdr -> evaluate */
if (nexthdr == NEXTHDR_NONE) {
temp |= MASK_NONE;
break;
}
+ /* Is there enough space for the next ext header? */
+ if (len < (int)sizeof(struct ipv6_opt_hdr))
+ return false;
/* ESP -> evaluate */
if (nexthdr == NEXTHDR_ESP) {
temp |= MASK_ESP;
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 97c17fdd6f75..590ddefb7ffc 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -61,7 +61,7 @@ static const struct file_operations sockstat6_seq_fops = {
static struct snmp_mib snmp6_ipstats_list[] = {
/* ipv6 mib according to RFC 2465 */
- SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES),
+ SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INPKTS),
SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS),
SNMP_MIB_ITEM("Ip6InTooBigErrors", IPSTATS_MIB_INTOOBIGERRORS),
SNMP_MIB_ITEM("Ip6InNoRoutes", IPSTATS_MIB_INNOROUTES),
@@ -71,7 +71,7 @@ static struct snmp_mib snmp6_ipstats_list[] = {
SNMP_MIB_ITEM("Ip6InDiscards", IPSTATS_MIB_INDISCARDS),
SNMP_MIB_ITEM("Ip6InDelivers", IPSTATS_MIB_INDELIVERS),
SNMP_MIB_ITEM("Ip6OutForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
- SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTREQUESTS),
+ SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTPKTS),
SNMP_MIB_ITEM("Ip6OutDiscards", IPSTATS_MIB_OUTDISCARDS),
SNMP_MIB_ITEM("Ip6OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
SNMP_MIB_ITEM("Ip6ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
@@ -83,6 +83,12 @@ static struct snmp_mib snmp6_ipstats_list[] = {
SNMP_MIB_ITEM("Ip6FragCreates", IPSTATS_MIB_FRAGCREATES),
SNMP_MIB_ITEM("Ip6InMcastPkts", IPSTATS_MIB_INMCASTPKTS),
SNMP_MIB_ITEM("Ip6OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
+ SNMP_MIB_ITEM("Ip6InOctets", IPSTATS_MIB_INOCTETS),
+ SNMP_MIB_ITEM("Ip6OutOctets", IPSTATS_MIB_OUTOCTETS),
+ SNMP_MIB_ITEM("Ip6InMcastOctets", IPSTATS_MIB_INMCASTOCTETS),
+ SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
+ SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
+ SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
SNMP_MIB_SENTINEL
};
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 61f6827e5906..e99307fba0b1 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -638,7 +638,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
if (err)
goto error_fault;
- IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
+ IP6_UPD_PO_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
dst_output);
if (err > 0)
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 711175e0571f..8c2513982b61 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -131,7 +131,7 @@ __u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
int mssind;
const __u16 mss = *mssp;
- tcp_sk(sk)->last_synq_overflow = jiffies;
+ tcp_synq_overflow(sk);
for (mssind = 0; mss > msstab[mssind + 1]; mssind++)
;
@@ -175,7 +175,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
if (!sysctl_tcp_syncookies || !th->ack)
goto out;
- if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) ||
+ if (tcp_synq_no_recent_overflow(sk) ||
(mss = cookie_check(skb, cookie)) == 0) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
goto out;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4b5aa1854260..d9dd94b6bf66 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -943,7 +943,7 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb)
struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb)
{
- struct ipv6hdr *iph = ipv6_hdr(skb);
+ struct ipv6hdr *iph = skb_gro_network_header(skb);
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index b51c9187c347..a9b3a6f9ea95 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -29,10 +29,7 @@
#include <net/iucv/iucv.h>
#include <net/iucv/af_iucv.h>
-#define CONFIG_IUCV_SOCK_DEBUG 1
-
-#define IPRMDATA 0x80
-#define VERSION "1.0"
+#define VERSION "1.1"
static char iucv_userid[80];
@@ -44,6 +41,19 @@ static struct proto iucv_proto = {
.obj_size = sizeof(struct iucv_sock),
};
+/* special AF_IUCV IPRM messages */
+static const u8 iprm_shutdown[8] =
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+
+#define TRGCLS_SIZE (sizeof(((struct iucv_message *)0)->class))
+
+/* macros to set/get socket control buffer at correct offset */
+#define CB_TAG(skb) ((skb)->cb) /* iucv message tag */
+#define CB_TAG_LEN (sizeof(((struct iucv_message *) 0)->tag))
+#define CB_TRGCLS(skb) ((skb)->cb + CB_TAG_LEN) /* iucv msg target class */
+#define CB_TRGCLS_LEN (TRGCLS_SIZE)
+
+
static void iucv_sock_kill(struct sock *sk);
static void iucv_sock_close(struct sock *sk);
@@ -54,6 +64,7 @@ static void iucv_callback_connack(struct iucv_path *, u8 ipuser[16]);
static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8],
u8 ipuser[16]);
static void iucv_callback_connrej(struct iucv_path *, u8 ipuser[16]);
+static void iucv_callback_shutdown(struct iucv_path *, u8 ipuser[16]);
static struct iucv_sock_list iucv_sk_list = {
.lock = __RW_LOCK_UNLOCKED(iucv_sk_list.lock),
@@ -65,7 +76,8 @@ static struct iucv_handler af_iucv_handler = {
.path_complete = iucv_callback_connack,
.path_severed = iucv_callback_connrej,
.message_pending = iucv_callback_rx,
- .message_complete = iucv_callback_txdone
+ .message_complete = iucv_callback_txdone,
+ .path_quiesced = iucv_callback_shutdown,
};
static inline void high_nmcpy(unsigned char *dst, char *src)
@@ -78,6 +90,37 @@ static inline void low_nmcpy(unsigned char *dst, char *src)
memcpy(&dst[8], src, 8);
}
+/**
+ * iucv_msg_length() - Returns the length of an iucv message.
+ * @msg: Pointer to struct iucv_message, MUST NOT be NULL
+ *
+ * The function returns the length of the specified iucv message @msg of data
+ * stored in a buffer and of data stored in the parameter list (PRMDATA).
+ *
+ * For IUCV_IPRMDATA, AF_IUCV uses the following convention to transport socket
+ * data:
+ * PRMDATA[0..6] socket data (max 7 bytes);
+ * PRMDATA[7] socket data length value (len is 0xff - PRMDATA[7])
+ *
+ * The socket data length is computed by substracting the socket data length
+ * value from 0xFF.
+ * If the socket data len is greater 7, then PRMDATA can be used for special
+ * notifications (see iucv_sock_shutdown); and further,
+ * if the socket data len is > 7, the function returns 8.
+ *
+ * Use this function to allocate socket buffers to store iucv message data.
+ */
+static inline size_t iucv_msg_length(struct iucv_message *msg)
+{
+ size_t datalen;
+
+ if (msg->flags & IUCV_IPRMDATA) {
+ datalen = 0xff - msg->rmmsg[7];
+ return (datalen < 8) ? datalen : 8;
+ }
+ return msg->length;
+}
+
/* Timers */
static void iucv_sock_timeout(unsigned long arg)
{
@@ -225,6 +268,8 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
spin_lock_init(&iucv_sk(sk)->message_q.lock);
skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q);
iucv_sk(sk)->send_tag = 0;
+ iucv_sk(sk)->flags = 0;
+ iucv_sk(sk)->msglimit = IUCV_QUEUELEN_DEFAULT;
iucv_sk(sk)->path = NULL;
memset(&iucv_sk(sk)->src_user_id , 0, 32);
@@ -248,11 +293,22 @@ static int iucv_sock_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
- if (sock->type != SOCK_STREAM)
- return -ESOCKTNOSUPPORT;
+ if (protocol && protocol != PF_IUCV)
+ return -EPROTONOSUPPORT;
sock->state = SS_UNCONNECTED;
- sock->ops = &iucv_sock_ops;
+
+ switch (sock->type) {
+ case SOCK_STREAM:
+ sock->ops = &iucv_sock_ops;
+ break;
+ case SOCK_SEQPACKET:
+ /* currently, proto ops can handle both sk types */
+ sock->ops = &iucv_sock_ops;
+ break;
+ default:
+ return -ESOCKTNOSUPPORT;
+ }
sk = iucv_sock_alloc(sock, protocol, GFP_KERNEL);
if (!sk)
@@ -463,11 +519,9 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
if (sk->sk_state != IUCV_OPEN && sk->sk_state != IUCV_BOUND)
return -EBADFD;
- if (sk->sk_type != SOCK_STREAM)
+ if (sk->sk_type != SOCK_STREAM && sk->sk_type != SOCK_SEQPACKET)
return -EINVAL;
- iucv = iucv_sk(sk);
-
if (sk->sk_state == IUCV_OPEN) {
err = iucv_sock_autobind(sk);
if (unlikely(err))
@@ -486,8 +540,8 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
iucv = iucv_sk(sk);
/* Create path. */
- iucv->path = iucv_path_alloc(IUCV_QUEUELEN_DEFAULT,
- IPRMDATA, GFP_KERNEL);
+ iucv->path = iucv_path_alloc(iucv->msglimit,
+ IUCV_IPRMDATA, GFP_KERNEL);
if (!iucv->path) {
err = -ENOMEM;
goto done;
@@ -521,8 +575,7 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
}
if (sk->sk_state == IUCV_DISCONN) {
- release_sock(sk);
- return -ECONNREFUSED;
+ err = -ECONNREFUSED;
}
if (err) {
@@ -545,7 +598,10 @@ static int iucv_sock_listen(struct socket *sock, int backlog)
lock_sock(sk);
err = -EINVAL;
- if (sk->sk_state != IUCV_BOUND || sock->type != SOCK_STREAM)
+ if (sk->sk_state != IUCV_BOUND)
+ goto done;
+
+ if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
goto done;
sk->sk_max_ack_backlog = backlog;
@@ -636,6 +692,30 @@ static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr,
return 0;
}
+/**
+ * iucv_send_iprm() - Send socket data in parameter list of an iucv message.
+ * @path: IUCV path
+ * @msg: Pointer to a struct iucv_message
+ * @skb: The socket data to send, skb->len MUST BE <= 7
+ *
+ * Send the socket data in the parameter list in the iucv message
+ * (IUCV_IPRMDATA). The socket data is stored at index 0 to 6 in the parameter
+ * list and the socket data len at index 7 (last byte).
+ * See also iucv_msg_length().
+ *
+ * Returns the error code from the iucv_message_send() call.
+ */
+static int iucv_send_iprm(struct iucv_path *path, struct iucv_message *msg,
+ struct sk_buff *skb)
+{
+ u8 prmdata[8];
+
+ memcpy(prmdata, (void *) skb->data, skb->len);
+ prmdata[7] = 0xff - (u8) skb->len;
+ return iucv_message_send(path, msg, IUCV_IPRMDATA, 0,
+ (void *) prmdata, 8);
+}
+
static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len)
{
@@ -643,6 +723,8 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
struct iucv_sock *iucv = iucv_sk(sk);
struct sk_buff *skb;
struct iucv_message txmsg;
+ struct cmsghdr *cmsg;
+ int cmsg_done;
char user_id[9];
char appl_id[9];
int err;
@@ -654,6 +736,10 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (msg->msg_flags & MSG_OOB)
return -EOPNOTSUPP;
+ /* SOCK_SEQPACKET: we do not support segmented records */
+ if (sk->sk_type == SOCK_SEQPACKET && !(msg->msg_flags & MSG_EOR))
+ return -EOPNOTSUPP;
+
lock_sock(sk);
if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -662,6 +748,52 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
}
if (sk->sk_state == IUCV_CONNECTED) {
+ /* initialize defaults */
+ cmsg_done = 0; /* check for duplicate headers */
+ txmsg.class = 0;
+
+ /* iterate over control messages */
+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg;
+ cmsg = CMSG_NXTHDR(msg, cmsg)) {
+
+ if (!CMSG_OK(msg, cmsg)) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (cmsg->cmsg_level != SOL_IUCV)
+ continue;
+
+ if (cmsg->cmsg_type & cmsg_done) {
+ err = -EINVAL;
+ goto out;
+ }
+ cmsg_done |= cmsg->cmsg_type;
+
+ switch (cmsg->cmsg_type) {
+ case SCM_IUCV_TRGCLS:
+ if (cmsg->cmsg_len != CMSG_LEN(TRGCLS_SIZE)) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* set iucv message target class */
+ memcpy(&txmsg.class,
+ (void *) CMSG_DATA(cmsg), TRGCLS_SIZE);
+
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ break;
+ }
+ }
+
+ /* allocate one skb for each iucv message:
+ * this is fine for SOCK_SEQPACKET (unless we want to support
+ * segmented records using the MSG_EOR flag), but
+ * for SOCK_STREAM we might want to improve it in future */
if (!(skb = sock_alloc_send_skb(sk, len,
msg->msg_flags & MSG_DONTWAIT,
&err)))
@@ -672,13 +804,33 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
goto fail;
}
- txmsg.class = 0;
- memcpy(&txmsg.class, skb->data, skb->len >= 4 ? 4 : skb->len);
+ /* increment and save iucv message tag for msg_completion cbk */
txmsg.tag = iucv->send_tag++;
- memcpy(skb->cb, &txmsg.tag, 4);
+ memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN);
skb_queue_tail(&iucv->send_skb_q, skb);
- err = iucv_message_send(iucv->path, &txmsg, 0, 0,
- (void *) skb->data, skb->len);
+
+ if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags)
+ && skb->len <= 7) {
+ err = iucv_send_iprm(iucv->path, &txmsg, skb);
+
+ /* on success: there is no message_complete callback
+ * for an IPRMDATA msg; remove skb from send queue */
+ if (err == 0) {
+ skb_unlink(skb, &iucv->send_skb_q);
+ kfree_skb(skb);
+ }
+
+ /* this error should never happen since the
+ * IUCV_IPRMDATA path flag is set... sever path */
+ if (err == 0x15) {
+ iucv_path_sever(iucv->path, NULL);
+ skb_unlink(skb, &iucv->send_skb_q);
+ err = -EPIPE;
+ goto fail;
+ }
+ } else
+ err = iucv_message_send(iucv->path, &txmsg, 0, 0,
+ (void *) skb->data, skb->len);
if (err) {
if (err == 3) {
user_id[8] = 0;
@@ -725,6 +877,10 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len)
if (!nskb)
return -ENOMEM;
+ /* copy target class to control buffer of new skb */
+ memcpy(CB_TRGCLS(nskb), CB_TRGCLS(skb), CB_TRGCLS_LEN);
+
+ /* copy data fragment */
memcpy(nskb->data, skb->data + copied, size);
copied += size;
dataleft -= size;
@@ -744,19 +900,33 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
struct iucv_message *msg)
{
int rc;
+ unsigned int len;
+
+ len = iucv_msg_length(msg);
- if (msg->flags & IPRMDATA) {
- skb->data = NULL;
- skb->len = 0;
+ /* store msg target class in the second 4 bytes of skb ctrl buffer */
+ /* Note: the first 4 bytes are reserved for msg tag */
+ memcpy(CB_TRGCLS(skb), &msg->class, CB_TRGCLS_LEN);
+
+ /* check for special IPRM messages (e.g. iucv_sock_shutdown) */
+ if ((msg->flags & IUCV_IPRMDATA) && len > 7) {
+ if (memcmp(msg->rmmsg, iprm_shutdown, 8) == 0) {
+ skb->data = NULL;
+ skb->len = 0;
+ }
} else {
- rc = iucv_message_receive(path, msg, 0, skb->data,
- msg->length, NULL);
+ rc = iucv_message_receive(path, msg, msg->flags & IUCV_IPRMDATA,
+ skb->data, len, NULL);
if (rc) {
kfree_skb(skb);
return;
}
- if (skb->truesize >= sk->sk_rcvbuf / 4) {
- rc = iucv_fragment_skb(sk, skb, msg->length);
+ /* we need to fragment iucv messages for SOCK_STREAM only;
+ * for SOCK_SEQPACKET, it is only relevant if we support
+ * record segmentation using MSG_EOR (see also recvmsg()) */
+ if (sk->sk_type == SOCK_STREAM &&
+ skb->truesize >= sk->sk_rcvbuf / 4) {
+ rc = iucv_fragment_skb(sk, skb, len);
kfree_skb(skb);
skb = NULL;
if (rc) {
@@ -767,7 +937,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
} else {
skb_reset_transport_header(skb);
skb_reset_network_header(skb);
- skb->len = msg->length;
+ skb->len = len;
}
}
@@ -782,7 +952,7 @@ static void iucv_process_message_q(struct sock *sk)
struct sock_msg_q *p, *n;
list_for_each_entry_safe(p, n, &iucv->message_q.list, list) {
- skb = alloc_skb(p->msg.length, GFP_ATOMIC | GFP_DMA);
+ skb = alloc_skb(iucv_msg_length(&p->msg), GFP_ATOMIC | GFP_DMA);
if (!skb)
break;
iucv_process_message(sk, skb, p->path, &p->msg);
@@ -799,7 +969,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
int noblock = flags & MSG_DONTWAIT;
struct sock *sk = sock->sk;
struct iucv_sock *iucv = iucv_sk(sk);
- int target, copied = 0;
+ unsigned int copied, rlen;
struct sk_buff *skb, *rskb, *cskb;
int err = 0;
@@ -812,8 +982,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (flags & (MSG_OOB))
return -EOPNOTSUPP;
- target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
-
/* receive/dequeue next skb:
* the function understands MSG_PEEK and, thus, does not dequeue skb */
skb = skb_recv_datagram(sk, flags, noblock, &err);
@@ -823,25 +991,45 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
return err;
}
- copied = min_t(unsigned int, skb->len, len);
+ rlen = skb->len; /* real length of skb */
+ copied = min_t(unsigned int, rlen, len);
cskb = skb;
if (memcpy_toiovec(msg->msg_iov, cskb->data, copied)) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- if (copied == 0)
- return -EFAULT;
- goto done;
+ if (!(flags & MSG_PEEK))
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ return -EFAULT;
}
- len -= copied;
+ /* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */
+ if (sk->sk_type == SOCK_SEQPACKET) {
+ if (copied < rlen)
+ msg->msg_flags |= MSG_TRUNC;
+ /* each iucv message contains a complete record */
+ msg->msg_flags |= MSG_EOR;
+ }
+
+ /* create control message to store iucv msg target class:
+ * get the trgcls from the control buffer of the skb due to
+ * fragmentation of original iucv message. */
+ err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS,
+ CB_TRGCLS_LEN, CB_TRGCLS(skb));
+ if (err) {
+ if (!(flags & MSG_PEEK))
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ return err;
+ }
/* Mark read part of skb as used */
if (!(flags & MSG_PEEK)) {
- skb_pull(skb, copied);
- if (skb->len) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- goto done;
+ /* SOCK_STREAM: re-queue skb if it contains unreceived data */
+ if (sk->sk_type == SOCK_STREAM) {
+ skb_pull(skb, copied);
+ if (skb->len) {
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ goto done;
+ }
}
kfree_skb(skb);
@@ -866,7 +1054,11 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
}
done:
- return err ? : copied;
+ /* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */
+ if (sk->sk_type == SOCK_SEQPACKET && (flags & MSG_TRUNC))
+ copied = rlen;
+
+ return copied;
}
static inline unsigned int iucv_accept_poll(struct sock *parent)
@@ -928,7 +1120,6 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
struct iucv_sock *iucv = iucv_sk(sk);
struct iucv_message txmsg;
int err = 0;
- u8 prmmsg[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
how++;
@@ -953,7 +1144,7 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
txmsg.class = 0;
txmsg.tag = 0;
err = iucv_message_send(iucv->path, &txmsg, IUCV_IPRMDATA, 0,
- (void *) prmmsg, 8);
+ (void *) iprm_shutdown, 8);
if (err) {
switch (err) {
case 1:
@@ -1007,6 +1198,98 @@ static int iucv_sock_release(struct socket *sock)
return err;
}
+/* getsockopt and setsockopt */
+static int iucv_sock_setsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, int optlen)
+{
+ struct sock *sk = sock->sk;
+ struct iucv_sock *iucv = iucv_sk(sk);
+ int val;
+ int rc;
+
+ if (level != SOL_IUCV)
+ return -ENOPROTOOPT;
+
+ if (optlen < sizeof(int))
+ return -EINVAL;
+
+ if (get_user(val, (int __user *) optval))
+ return -EFAULT;
+
+ rc = 0;
+
+ lock_sock(sk);
+ switch (optname) {
+ case SO_IPRMDATA_MSG:
+ if (val)
+ iucv->flags |= IUCV_IPRMDATA;
+ else
+ iucv->flags &= ~IUCV_IPRMDATA;
+ break;
+ case SO_MSGLIMIT:
+ switch (sk->sk_state) {
+ case IUCV_OPEN:
+ case IUCV_BOUND:
+ if (val < 1 || val > (u16)(~0))
+ rc = -EINVAL;
+ else
+ iucv->msglimit = val;
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
+ break;
+ default:
+ rc = -ENOPROTOOPT;
+ break;
+ }
+ release_sock(sk);
+
+ return rc;
+}
+
+static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, int __user *optlen)
+{
+ struct sock *sk = sock->sk;
+ struct iucv_sock *iucv = iucv_sk(sk);
+ int val, len;
+
+ if (level != SOL_IUCV)
+ return -ENOPROTOOPT;
+
+ if (get_user(len, optlen))
+ return -EFAULT;
+
+ if (len < 0)
+ return -EINVAL;
+
+ len = min_t(unsigned int, len, sizeof(int));
+
+ switch (optname) {
+ case SO_IPRMDATA_MSG:
+ val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
+ break;
+ case SO_MSGLIMIT:
+ lock_sock(sk);
+ val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
+ : iucv->msglimit; /* default */
+ release_sock(sk);
+ break;
+ default:
+ return -ENOPROTOOPT;
+ }
+
+ if (put_user(len, optlen))
+ return -EFAULT;
+ if (copy_to_user(optval, &val, len))
+ return -EFAULT;
+
+ return 0;
+}
+
+
/* Callback wrappers - called from iucv base support */
static int iucv_callback_connreq(struct iucv_path *path,
u8 ipvmid[8], u8 ipuser[16])
@@ -1060,7 +1343,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
}
/* Create the new socket */
- nsk = iucv_sock_alloc(NULL, SOCK_STREAM, GFP_ATOMIC);
+ nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
if (!nsk) {
err = iucv_path_sever(path, user_data);
iucv_path_free(path);
@@ -1083,7 +1366,9 @@ static int iucv_callback_connreq(struct iucv_path *path,
memcpy(nuser_data + 8, niucv->src_name, 8);
ASCEBC(nuser_data + 8, 8);
- path->msglim = IUCV_QUEUELEN_DEFAULT;
+ /* set message limit for path based on msglimit of accepting socket */
+ niucv->msglimit = iucv->msglimit;
+ path->msglim = iucv->msglimit;
err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk);
if (err) {
err = iucv_path_sever(path, user_data);
@@ -1131,19 +1416,17 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
goto save_message;
len = atomic_read(&sk->sk_rmem_alloc);
- len += msg->length + sizeof(struct sk_buff);
+ len += iucv_msg_length(msg) + sizeof(struct sk_buff);
if (len > sk->sk_rcvbuf)
goto save_message;
- skb = alloc_skb(msg->length, GFP_ATOMIC | GFP_DMA);
+ skb = alloc_skb(iucv_msg_length(msg), GFP_ATOMIC | GFP_DMA);
if (!skb)
goto save_message;
iucv_process_message(sk, skb, path, msg);
goto out_unlock;
- return;
-
save_message:
save_msg = kzalloc(sizeof(struct sock_msg_q), GFP_ATOMIC | GFP_DMA);
if (!save_msg)
@@ -1170,7 +1453,7 @@ static void iucv_callback_txdone(struct iucv_path *path,
spin_lock_irqsave(&list->lock, flags);
while (list_skb != (struct sk_buff *)list) {
- if (!memcmp(&msg->tag, list_skb->cb, 4)) {
+ if (!memcmp(&msg->tag, CB_TAG(list_skb), CB_TAG_LEN)) {
this = list_skb;
break;
}
@@ -1206,6 +1489,21 @@ static void iucv_callback_connrej(struct iucv_path *path, u8 ipuser[16])
sk->sk_state_change(sk);
}
+/* called if the other communication side shuts down its RECV direction;
+ * in turn, the callback sets SEND_SHUTDOWN to disable sending of data.
+ */
+static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16])
+{
+ struct sock *sk = path->private;
+
+ bh_lock_sock(sk);
+ if (sk->sk_state != IUCV_CLOSED) {
+ sk->sk_shutdown |= SEND_SHUTDOWN;
+ sk->sk_state_change(sk);
+ }
+ bh_unlock_sock(sk);
+}
+
static struct proto_ops iucv_sock_ops = {
.family = PF_IUCV,
.owner = THIS_MODULE,
@@ -1222,8 +1520,8 @@ static struct proto_ops iucv_sock_ops = {
.mmap = sock_no_mmap,
.socketpair = sock_no_socketpair,
.shutdown = iucv_sock_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt
+ .setsockopt = iucv_sock_setsockopt,
+ .getsockopt = iucv_sock_getsockopt,
};
static struct net_proto_family iucv_sock_family_ops = {
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index a35240f61ec3..61e8038a55ee 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -280,6 +280,7 @@ union iucv_param {
* Anchor for per-cpu IUCV command parameter block.
*/
static union iucv_param *iucv_param[NR_CPUS];
+static union iucv_param *iucv_param_irq[NR_CPUS];
/**
* iucv_call_b2f0
@@ -358,7 +359,7 @@ static void iucv_allow_cpu(void *data)
* 0x10 - Flag to allow priority message completion interrupts
* 0x08 - Flag to allow IUCV control interrupts
*/
- parm = iucv_param[cpu];
+ parm = iucv_param_irq[cpu];
memset(parm, 0, sizeof(union iucv_param));
parm->set_mask.ipmask = 0xf8;
iucv_call_b2f0(IUCV_SETMASK, parm);
@@ -379,7 +380,7 @@ static void iucv_block_cpu(void *data)
union iucv_param *parm;
/* Disable all iucv interrupts. */
- parm = iucv_param[cpu];
+ parm = iucv_param_irq[cpu];
memset(parm, 0, sizeof(union iucv_param));
iucv_call_b2f0(IUCV_SETMASK, parm);
@@ -403,7 +404,7 @@ static void iucv_declare_cpu(void *data)
return;
/* Declare interrupt buffer. */
- parm = iucv_param[cpu];
+ parm = iucv_param_irq[cpu];
memset(parm, 0, sizeof(union iucv_param));
parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]);
rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm);
@@ -460,7 +461,7 @@ static void iucv_retrieve_cpu(void *data)
iucv_block_cpu(NULL);
/* Retrieve interrupt buffer. */
- parm = iucv_param[cpu];
+ parm = iucv_param_irq[cpu];
iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm);
/* Clear indication that an iucv buffer exists for this cpu. */
@@ -574,11 +575,22 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self,
iucv_irq_data[cpu] = NULL;
return NOTIFY_BAD;
}
+ iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
+ GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+ if (!iucv_param_irq[cpu]) {
+ kfree(iucv_param[cpu]);
+ iucv_param[cpu] = NULL;
+ kfree(iucv_irq_data[cpu]);
+ iucv_irq_data[cpu] = NULL;
+ return NOTIFY_BAD;
+ }
break;
case CPU_UP_CANCELED:
case CPU_UP_CANCELED_FROZEN:
case CPU_DEAD:
case CPU_DEAD_FROZEN:
+ kfree(iucv_param_irq[cpu]);
+ iucv_param_irq[cpu] = NULL;
kfree(iucv_param[cpu]);
iucv_param[cpu] = NULL;
kfree(iucv_irq_data[cpu]);
@@ -625,7 +637,7 @@ static int iucv_sever_pathid(u16 pathid, u8 userdata[16])
{
union iucv_param *parm;
- parm = iucv_param[smp_processor_id()];
+ parm = iucv_param_irq[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
if (userdata)
memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
@@ -918,10 +930,8 @@ int iucv_path_sever(struct iucv_path *path, u8 userdata[16])
if (iucv_active_cpu != smp_processor_id())
spin_lock_bh(&iucv_table_lock);
rc = iucv_sever_pathid(path->pathid, userdata);
- if (!rc) {
- iucv_path_table[path->pathid] = NULL;
- list_del_init(&path->list);
- }
+ iucv_path_table[path->pathid] = NULL;
+ list_del_init(&path->list);
if (iucv_active_cpu != smp_processor_id())
spin_unlock_bh(&iucv_table_lock);
preempt_enable();
@@ -1378,6 +1388,8 @@ static void iucv_path_complete(struct iucv_irq_data *data)
struct iucv_path_complete *ipc = (void *) data;
struct iucv_path *path = iucv_path_table[ipc->ippathid];
+ if (path)
+ path->flags = ipc->ipflags1;
if (path && path->handler && path->handler->path_complete)
path->handler->path_complete(path, ipc->ipuser);
}
@@ -1413,7 +1425,7 @@ static void iucv_path_severed(struct iucv_irq_data *data)
else {
iucv_sever_pathid(path->pathid, NULL);
iucv_path_table[path->pathid] = NULL;
- list_del_init(&path->list);
+ list_del(&path->list);
iucv_path_free(path);
}
}
@@ -1717,6 +1729,13 @@ static int __init iucv_init(void)
rc = -ENOMEM;
goto out_free;
}
+ iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
+ GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+ if (!iucv_param_irq[cpu]) {
+ rc = -ENOMEM;
+ goto out_free;
+ }
+
}
rc = register_hotcpu_notifier(&iucv_cpu_notifier);
if (rc)
@@ -1734,6 +1753,8 @@ out_cpu:
unregister_hotcpu_notifier(&iucv_cpu_notifier);
out_free:
for_each_possible_cpu(cpu) {
+ kfree(iucv_param_irq[cpu]);
+ iucv_param_irq[cpu] = NULL;
kfree(iucv_param[cpu]);
iucv_param[cpu] = NULL;
kfree(iucv_irq_data[cpu]);
@@ -1764,6 +1785,8 @@ static void __exit iucv_exit(void)
spin_unlock_irq(&iucv_queue_lock);
unregister_hotcpu_notifier(&iucv_cpu_notifier);
for_each_possible_cpu(cpu) {
+ kfree(iucv_param_irq[cpu]);
+ iucv_param_irq[cpu] = NULL;
kfree(iucv_param[cpu]);
iucv_param[cpu] = NULL;
kfree(iucv_irq_data[cpu]);
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index febae702685c..9208cf5f2bd5 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -935,7 +935,7 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
if (llc->dev) {
sllc.sllc_arphrd = llc->dev->type;
- memcpy(&sllc.sllc_mac, &llc->dev->dev_addr,
+ memcpy(&sllc.sllc_mac, llc->dev->dev_addr,
IFHWADDRLEN);
}
}
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index ecc3faf9f11a..9cbf545e95a2 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -11,6 +11,22 @@ config MAC80211
This option enables the hardware independent IEEE 802.11
networking stack.
+config MAC80211_DEFAULT_PS
+ bool "enable powersave by default"
+ depends on MAC80211
+ default y
+ help
+ This option enables powersave mode by default.
+
+ If this causes your applications to misbehave you should fix your
+ applications instead -- they need to register their network
+ latency requirement, see Documentation/power/pm_qos_interface.txt.
+
+config MAC80211_DEFAULT_PS_VALUE
+ int
+ default 1 if MAC80211_DEFAULT_PS
+ default 0
+
menu "Rate control algorithm selection"
depends on MAC80211 != n
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 07656d830bc4..bc064d7933ff 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -16,12 +16,12 @@
#include <linux/ieee80211.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
u16 initiator, u16 reason)
{
struct ieee80211_local *local = sta->local;
- struct ieee80211_hw *hw = &local->hw;
int i;
/* check if TID is in operational state */
@@ -41,8 +41,8 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
sta->sta.addr, tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
- if (local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
- &sta->sta, tid, NULL))
+ if (drv_ampdu_action(local, IEEE80211_AMPDU_RX_STOP,
+ &sta->sta, tid, NULL))
printk(KERN_DEBUG "HW problem - can not stop rx "
"aggregation for tid %d\n", tid);
@@ -68,6 +68,7 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
spin_lock_bh(&sta->lock);
/* free resources */
kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
+ kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_time);
if (!sta->ampdu_mlme.tid_rx[tid]->shutdown) {
kfree(sta->ampdu_mlme.tid_rx[tid]);
@@ -268,19 +269,23 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
/* prepare reordering buffer */
tid_agg_rx->reorder_buf =
kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC);
- if (!tid_agg_rx->reorder_buf) {
+ tid_agg_rx->reorder_time =
+ kcalloc(buf_size, sizeof(unsigned long), GFP_ATOMIC);
+ if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) {
#ifdef CONFIG_MAC80211_HT_DEBUG
if (net_ratelimit())
printk(KERN_ERR "can not allocate reordering buffer "
"to tid %d\n", tid);
#endif
+ kfree(tid_agg_rx->reorder_buf);
+ kfree(tid_agg_rx->reorder_time);
kfree(sta->ampdu_mlme.tid_rx[tid]);
+ sta->ampdu_mlme.tid_rx[tid] = NULL;
goto end;
}
- if (local->ops->ampdu_action)
- ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
- &sta->sta, tid, &start_seq_num);
+ ret = drv_ampdu_action(local, IEEE80211_AMPDU_RX_START,
+ &sta->sta, tid, &start_seq_num);
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
#endif /* CONFIG_MAC80211_HT_DEBUG */
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 947aaaad35d2..43d00ffd3988 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -16,6 +16,7 @@
#include <linux/ieee80211.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "wme.h"
/**
@@ -134,8 +135,8 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
*state = HT_AGG_STATE_REQ_STOP_BA_MSK |
(initiator << HT_AGG_STATE_INITIATOR_SHIFT);
- ret = local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_STOP,
- &sta->sta, tid, NULL);
+ ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP,
+ &sta->sta, tid, NULL);
/* HW shall not deny going back to legacy */
if (WARN_ON(ret)) {
@@ -306,8 +307,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
start_seq_num = sta->tid_seq[tid];
- ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
- &sta->sta, tid, &start_seq_num);
+ ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START,
+ &sta->sta, tid, &start_seq_num);
if (ret) {
#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -418,8 +419,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
ieee80211_agg_splice_finish(local, sta, tid);
spin_unlock(&local->ampdu_lock);
- local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_OPERATIONAL,
- &sta->sta, tid, NULL);
+ drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL,
+ &sta->sta, tid, NULL);
}
void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e677b751d468..77e9ff5ec4f3 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -13,6 +13,7 @@
#include <linux/rcupdate.h>
#include <net/cfg80211.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "cfg.h"
#include "rate.h"
#include "mesh.h"
@@ -111,7 +112,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
}
static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
- u8 key_idx, u8 *mac_addr,
+ u8 key_idx, const u8 *mac_addr,
struct key_params *params)
{
struct ieee80211_sub_if_data *sdata;
@@ -140,7 +141,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
return -EINVAL;
}
- key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key);
+ key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
+ params->seq_len, params->seq);
if (!key)
return -ENOMEM;
@@ -165,7 +167,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
}
static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
- u8 key_idx, u8 *mac_addr)
+ u8 key_idx, const u8 *mac_addr)
{
struct ieee80211_sub_if_data *sdata;
struct sta_info *sta;
@@ -207,7 +209,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
}
static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
- u8 key_idx, u8 *mac_addr, void *cookie,
+ u8 key_idx, const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie,
struct key_params *params))
{
@@ -245,12 +247,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
iv32 = key->u.tkip.tx.iv32;
iv16 = key->u.tkip.tx.iv16;
- if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
- sdata->local->ops->get_tkip_seq)
- sdata->local->ops->get_tkip_seq(
- local_to_hw(sdata->local),
- key->conf.hw_key_idx,
- &iv32, &iv16);
+ if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
+ drv_get_tkip_seq(sdata->local,
+ key->conf.hw_key_idx,
+ &iv32, &iv16);
seq[0] = iv16 & 0xff;
seq[1] = (iv16 >> 8) & 0xff;
@@ -451,18 +451,11 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
* This is a kludge. beacon interval should really be part
* of the beacon information.
*/
- if (params->interval && (sdata->local->hw.conf.beacon_int !=
- params->interval)) {
- sdata->local->hw.conf.beacon_int = params->interval;
- err = ieee80211_hw_config(sdata->local,
- IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
- if (err < 0)
- return err;
- /*
- * We updated some parameter so if below bails out
- * it's not an error.
- */
- err = 0;
+ if (params->interval &&
+ (sdata->vif.bss_conf.beacon_int != params->interval)) {
+ sdata->vif.bss_conf.beacon_int = params->interval;
+ ieee80211_bss_info_change_notify(sdata,
+ BSS_CHANGED_BEACON_INT);
}
/* Need to have a beacon head if we don't have one yet */
@@ -528,8 +521,9 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
kfree(old);
- return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
- IEEE80211_IFCC_BEACON_ENABLED);
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
+ BSS_CHANGED_BEACON);
+ return 0;
}
static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
@@ -580,7 +574,8 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
synchronize_rcu();
kfree(old);
- return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED);
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
+ return 0;
}
/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
@@ -635,34 +630,38 @@ static void sta_apply_parameters(struct ieee80211_local *local,
int i, j;
struct ieee80211_supported_band *sband;
struct ieee80211_sub_if_data *sdata = sta->sdata;
+ u32 mask, set;
sband = local->hw.wiphy->bands[local->oper_channel->band];
- /*
- * FIXME: updating the flags is racy when this function is
- * called from ieee80211_change_station(), this will
- * be resolved in a future patch.
- */
+ spin_lock_bh(&sta->lock);
+ mask = params->sta_flags_mask;
+ set = params->sta_flags_set;
- if (params->station_flags & STATION_FLAG_CHANGED) {
- spin_lock_bh(&sta->lock);
+ if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
sta->flags &= ~WLAN_STA_AUTHORIZED;
- if (params->station_flags & STATION_FLAG_AUTHORIZED)
+ if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
sta->flags |= WLAN_STA_AUTHORIZED;
+ }
+ if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
- if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
+ if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
sta->flags |= WLAN_STA_SHORT_PREAMBLE;
+ }
+ if (mask & BIT(NL80211_STA_FLAG_WME)) {
sta->flags &= ~WLAN_STA_WME;
- if (params->station_flags & STATION_FLAG_WME)
+ if (set & BIT(NL80211_STA_FLAG_WME))
sta->flags |= WLAN_STA_WME;
+ }
+ if (mask & BIT(NL80211_STA_FLAG_MFP)) {
sta->flags &= ~WLAN_STA_MFP;
- if (params->station_flags & STATION_FLAG_MFP)
+ if (set & BIT(NL80211_STA_FLAG_MFP))
sta->flags |= WLAN_STA_MFP;
- spin_unlock_bh(&sta->lock);
}
+ spin_unlock_bh(&sta->lock);
/*
* FIXME: updating the following information is racy when this
@@ -1120,7 +1119,7 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
p.cw_max = params->cwmax;
p.cw_min = params->cwmin;
p.txop = params->txop;
- if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) {
+ if (drv_conf_tx(local, params->queue, &p)) {
printk(KERN_DEBUG "%s: failed to set TX queue "
"parameters for queue %d\n", local->mdev->name,
params->queue);
@@ -1167,7 +1166,8 @@ static int ieee80211_scan(struct wiphy *wiphy,
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
sdata->vif.type != NL80211_IFTYPE_ADHOC &&
- sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
+ sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
+ (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon))
return -EOPNOTSUPP;
return ieee80211_request_scan(sdata, req);
@@ -1258,6 +1258,19 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
if (ret)
return ret;
+ if (req->use_mfp) {
+ sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
+ sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED;
+ } else {
+ sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;
+ }
+
+ if (req->control_port)
+ sdata->u.mgd.flags |= IEEE80211_STA_CONTROL_PORT;
+ else
+ sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
+
sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
ieee80211_sta_req_auth(sdata);
@@ -1267,25 +1280,59 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_deauth_request *req)
{
- struct ieee80211_sub_if_data *sdata;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- /* TODO: req->ie */
+ /* TODO: req->ie, req->peer_addr */
return ieee80211_sta_deauthenticate(sdata, req->reason_code);
}
static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_disassoc_request *req)
{
- struct ieee80211_sub_if_data *sdata;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- /* TODO: req->ie */
+ /* TODO: req->ie, req->peer_addr */
return ieee80211_sta_disassociate(sdata, req->reason_code);
}
+static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ibss_params *params)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ return ieee80211_ibss_join(sdata, params);
+}
+
+static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ return ieee80211_ibss_leave(sdata);
+}
+
+static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+ int err;
+
+ if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+ err = drv_set_rts_threshold(local, wiphy->rts_threshold);
+
+ if (err)
+ return err;
+ }
+
+ if (changed & WIPHY_PARAM_RETRY_SHORT)
+ local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
+ if (changed & WIPHY_PARAM_RETRY_LONG)
+ local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
+ if (changed &
+ (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
+
+ return 0;
+}
+
struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -1322,4 +1369,7 @@ struct cfg80211_ops mac80211_config_ops = {
.assoc = ieee80211_assoc,
.deauth = ieee80211_deauth,
.disassoc = ieee80211_disassoc,
+ .join_ibss = ieee80211_join_ibss,
+ .leave_ibss = ieee80211_leave_ibss,
+ .set_wiphy_params = ieee80211_set_wiphy_params,
};
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 210b9b6fecd2..e7682fe1c590 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -10,6 +10,7 @@
#include <linux/debugfs.h>
#include <linux/rtnetlink.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "rate.h"
#include "debugfs.h"
@@ -52,13 +53,13 @@ static const struct file_operations name## _ops = { \
DEBUGFS_READONLY_FILE(frequency, 20, "%d",
local->hw.conf.channel->center_freq);
DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
- local->rts_threshold);
+ local->hw.wiphy->rts_threshold);
DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
- local->fragmentation_threshold);
+ local->hw.wiphy->frag_threshold);
DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
- local->hw.conf.short_frame_max_tx_count);
+ local->hw.wiphy->retry_short);
DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
- local->hw.conf.long_frame_max_tx_count);
+ local->hw.wiphy->retry_long);
DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d",
local->total_ps_buffered);
DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x",
@@ -70,11 +71,10 @@ static ssize_t tsf_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ieee80211_local *local = file->private_data;
- u64 tsf = 0;
+ u64 tsf;
char buf[100];
- if (local->ops->get_tsf)
- tsf = local->ops->get_tsf(local_to_hw(local));
+ tsf = drv_get_tsf(local);
snprintf(buf, sizeof(buf), "0x%016llx\n", (unsigned long long) tsf);
@@ -97,13 +97,13 @@ static ssize_t tsf_write(struct file *file,
if (strncmp(buf, "reset", 5) == 0) {
if (local->ops->reset_tsf) {
- local->ops->reset_tsf(local_to_hw(local));
+ drv_reset_tsf(local);
printk(KERN_INFO "%s: debugfs reset TSF\n", wiphy_name(local->hw.wiphy));
}
} else {
tsf = simple_strtoul(buf, NULL, 0);
if (local->ops->set_tsf) {
- local->ops->set_tsf(local_to_hw(local), tsf);
+ drv_set_tsf(local, tsf);
printk(KERN_INFO "%s: debugfs set TSF to %#018llx\n", wiphy_name(local->hw.wiphy), tsf);
}
}
@@ -135,6 +135,42 @@ static const struct file_operations reset_ops = {
.open = mac80211_open_file_generic,
};
+static ssize_t noack_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ int res;
+ char buf[10];
+
+ res = scnprintf(buf, sizeof(buf), "%d\n", local->wifi_wme_noack_test);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+}
+
+static ssize_t noack_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ char buf[10];
+ size_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+ buf[len] = '\0';
+
+ local->wifi_wme_noack_test = !!simple_strtoul(buf, NULL, 0);
+
+ return count;
+}
+
+static const struct file_operations noack_ops = {
+ .read = noack_read,
+ .write = noack_write,
+ .open = mac80211_open_file_generic
+};
+
/* statistics stuff */
#define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \
@@ -150,14 +186,12 @@ static ssize_t format_devstat_counter(struct ieee80211_local *local,
char buf[20];
int res;
- if (!local->ops->get_stats)
- return -EOPNOTSUPP;
-
rtnl_lock();
- res = local->ops->get_stats(local_to_hw(local), &stats);
+ res = drv_get_stats(local, &stats);
rtnl_unlock();
- if (!res)
- res = printvalue(&stats, buf, sizeof(buf));
+ if (res)
+ return res;
+ res = printvalue(&stats, buf, sizeof(buf));
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
@@ -277,6 +311,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
DEBUGFS_ADD(wep_iv);
DEBUGFS_ADD(tsf);
DEBUGFS_ADD_MODE(reset, 0200);
+ DEBUGFS_ADD(noack);
statsd = debugfs_create_dir("statistics", phyd);
local->debugfs.statistics = statsd;
@@ -332,6 +367,7 @@ void debugfs_hw_del(struct ieee80211_local *local)
DEBUGFS_DEL(wep_iv);
DEBUGFS_DEL(tsf);
DEBUGFS_DEL(reset);
+ DEBUGFS_DEL(noack);
DEBUGFS_STATS_DEL(transmitted_fragment_count);
DEBUGFS_STATS_DEL(multicast_transmitted_frame_count);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
new file mode 100644
index 000000000000..3912b5334b9c
--- /dev/null
+++ b/net/mac80211/driver-ops.h
@@ -0,0 +1,184 @@
+#ifndef __MAC80211_DRIVER_OPS
+#define __MAC80211_DRIVER_OPS
+
+#include <net/mac80211.h>
+#include "ieee80211_i.h"
+
+static inline int drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
+{
+ return local->ops->tx(&local->hw, skb);
+}
+
+static inline int drv_start(struct ieee80211_local *local)
+{
+ return local->ops->start(&local->hw);
+}
+
+static inline void drv_stop(struct ieee80211_local *local)
+{
+ local->ops->stop(&local->hw);
+}
+
+static inline int drv_add_interface(struct ieee80211_local *local,
+ struct ieee80211_if_init_conf *conf)
+{
+ return local->ops->add_interface(&local->hw, conf);
+}
+
+static inline void drv_remove_interface(struct ieee80211_local *local,
+ struct ieee80211_if_init_conf *conf)
+{
+ local->ops->remove_interface(&local->hw, conf);
+}
+
+static inline int drv_config(struct ieee80211_local *local, u32 changed)
+{
+ return local->ops->config(&local->hw, changed);
+}
+
+static inline void drv_bss_info_changed(struct ieee80211_local *local,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed)
+{
+ if (local->ops->bss_info_changed)
+ local->ops->bss_info_changed(&local->hw, vif, info, changed);
+}
+
+static inline void drv_configure_filter(struct ieee80211_local *local,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ local->ops->configure_filter(&local->hw, changed_flags, total_flags,
+ mc_count, mc_list);
+}
+
+static inline int drv_set_tim(struct ieee80211_local *local,
+ struct ieee80211_sta *sta, bool set)
+{
+ if (local->ops->set_tim)
+ return local->ops->set_tim(&local->hw, sta, set);
+ return 0;
+}
+
+static inline int drv_set_key(struct ieee80211_local *local,
+ enum set_key_cmd cmd, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ return local->ops->set_key(&local->hw, cmd, vif, sta, key);
+}
+
+static inline void drv_update_tkip_key(struct ieee80211_local *local,
+ struct ieee80211_key_conf *conf,
+ const u8 *address, u32 iv32,
+ u16 *phase1key)
+{
+ if (local->ops->update_tkip_key)
+ local->ops->update_tkip_key(&local->hw, conf, address,
+ iv32, phase1key);
+}
+
+static inline int drv_hw_scan(struct ieee80211_local *local,
+ struct cfg80211_scan_request *req)
+{
+ return local->ops->hw_scan(&local->hw, req);
+}
+
+static inline void drv_sw_scan_start(struct ieee80211_local *local)
+{
+ if (local->ops->sw_scan_start)
+ local->ops->sw_scan_start(&local->hw);
+}
+
+static inline void drv_sw_scan_complete(struct ieee80211_local *local)
+{
+ if (local->ops->sw_scan_complete)
+ local->ops->sw_scan_complete(&local->hw);
+}
+
+static inline int drv_get_stats(struct ieee80211_local *local,
+ struct ieee80211_low_level_stats *stats)
+{
+ if (!local->ops->get_stats)
+ return -EOPNOTSUPP;
+ return local->ops->get_stats(&local->hw, stats);
+}
+
+static inline void drv_get_tkip_seq(struct ieee80211_local *local,
+ u8 hw_key_idx, u32 *iv32, u16 *iv16)
+{
+ if (local->ops->get_tkip_seq)
+ local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
+}
+
+static inline int drv_set_rts_threshold(struct ieee80211_local *local,
+ u32 value)
+{
+ if (local->ops->set_rts_threshold)
+ return local->ops->set_rts_threshold(&local->hw, value);
+ return 0;
+}
+
+static inline void drv_sta_notify(struct ieee80211_local *local,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta)
+{
+ if (local->ops->sta_notify)
+ local->ops->sta_notify(&local->hw, vif, cmd, sta);
+}
+
+static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue,
+ const struct ieee80211_tx_queue_params *params)
+{
+ if (local->ops->conf_tx)
+ return local->ops->conf_tx(&local->hw, queue, params);
+ return -EOPNOTSUPP;
+}
+
+static inline int drv_get_tx_stats(struct ieee80211_local *local,
+ struct ieee80211_tx_queue_stats *stats)
+{
+ return local->ops->get_tx_stats(&local->hw, stats);
+}
+
+static inline u64 drv_get_tsf(struct ieee80211_local *local)
+{
+ if (local->ops->get_tsf)
+ return local->ops->get_tsf(&local->hw);
+ return -1ULL;
+}
+
+static inline void drv_set_tsf(struct ieee80211_local *local, u64 tsf)
+{
+ if (local->ops->set_tsf)
+ local->ops->set_tsf(&local->hw, tsf);
+}
+
+static inline void drv_reset_tsf(struct ieee80211_local *local)
+{
+ if (local->ops->reset_tsf)
+ local->ops->reset_tsf(&local->hw);
+}
+
+static inline int drv_tx_last_beacon(struct ieee80211_local *local)
+{
+ if (local->ops->tx_last_beacon)
+ return local->ops->tx_last_beacon(&local->hw);
+ return 1;
+}
+
+static inline int drv_ampdu_action(struct ieee80211_local *local,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid,
+ u16 *ssn)
+{
+ if (local->ops->ampdu_action)
+ return local->ops->ampdu_action(&local->hw, action,
+ sta, tid, ssn);
+ return -EOPNOTSUPP;
+}
+#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/event.c b/net/mac80211/event.c
index 0d95561c0ee0..f288d01a6344 100644
--- a/net/mac80211/event.c
+++ b/net/mac80211/event.c
@@ -12,12 +12,12 @@
#include "ieee80211_i.h"
/*
- * indicate a failed Michael MIC to userspace; the passed packet
- * (in the variable hdr) must be long enough to extract the TKIP
- * fields like TSC
+ * Indicate a failed Michael MIC to userspace. If the caller knows the TSC of
+ * the frame that generated the MIC failure (i.e., if it was provided by the
+ * driver or is still in the frame), it should provide that information.
*/
void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr *hdr, const u8 *tsc)
{
union iwreq_data wrqu;
char *buf = kmalloc(128, GFP_ATOMIC);
@@ -34,8 +34,9 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke
kfree(buf);
}
- /*
- * TODO: re-add support for sending MIC failure indication
- * with all info via nl80211
- */
+ cfg80211_michael_mic_failure(sdata->dev, hdr->addr2,
+ (hdr->addr1[0] & 0x01) ?
+ NL80211_KEYTYPE_GROUP :
+ NL80211_KEYTYPE_PAIRWISE,
+ keyidx, tsc);
}
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 4e3c72f20de7..0891bfb06996 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -14,7 +14,6 @@
*/
#include <linux/ieee80211.h>
-#include <net/wireless.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
#include "rate.h"
@@ -83,89 +82,6 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
ht_cap->mcs.rx_mask[32/8] |= 1;
}
-/*
- * ieee80211_enable_ht should be called only after the operating band
- * has been determined as ht configuration depends on the hw's
- * HT abilities for a specific band.
- */
-u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_ht_info *hti,
- u16 ap_ht_cap_flags)
-{
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_supported_band *sband;
- struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- struct ieee80211_bss_ht_conf ht;
- struct sta_info *sta;
- u32 changed = 0;
- bool enable_ht = true, ht_changed;
- enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
-
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
- memset(&ht, 0, sizeof(ht));
-
- /* HT is not supported */
- if (!sband->ht_cap.ht_supported)
- enable_ht = false;
-
- /* check that channel matches the right operating channel */
- if (local->hw.conf.channel->center_freq !=
- ieee80211_channel_to_frequency(hti->control_chan))
- enable_ht = false;
-
- if (enable_ht) {
- channel_type = NL80211_CHAN_HT20;
-
- if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
- (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
- (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
- switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
- case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
- channel_type = NL80211_CHAN_HT40PLUS;
- break;
- case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
- channel_type = NL80211_CHAN_HT40MINUS;
- break;
- }
- }
- }
-
- ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
- channel_type != local->hw.conf.channel_type;
-
- local->oper_channel_type = channel_type;
-
- if (ht_changed) {
- /* channel_type change automatically detected */
- ieee80211_hw_config(local, 0);
-
- rcu_read_lock();
-
- sta = sta_info_get(local, ifmgd->bssid);
- if (sta)
- rate_control_rate_update(local, sband, sta,
- IEEE80211_RC_HT_CHANGED);
-
- rcu_read_unlock();
-
- }
-
- /* disable HT */
- if (!enable_ht)
- return 0;
-
- ht.operation_mode = le16_to_cpu(hti->operation_mode);
-
- /* if bss configuration changed store the new one */
- if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) {
- changed |= BSS_CHANGED_HT;
- sdata->vif.bss_conf.ht = ht;
- }
-
- return changed;
-}
-
void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta)
{
int i;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 3201e1f96365..c236079ed38a 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -22,6 +22,7 @@
#include <asm/unaligned.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "rate.h"
#define IEEE80211_SCAN_INTERVAL (2 * HZ)
@@ -59,74 +60,65 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.bssid, 0);
}
-static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
- const u8 *bssid, const int beacon_int,
- const int freq,
- const size_t supp_rates_len,
- const u8 *supp_rates,
- const u16 capability, u64 tsf)
+static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+ const u8 *bssid, const int beacon_int,
+ struct ieee80211_channel *chan,
+ const u32 basic_rates,
+ const u16 capability, u64 tsf)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;
- int res = 0, rates, i, j;
+ int rates, i;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
u8 *pos;
struct ieee80211_supported_band *sband;
- union iwreq_data wrqu;
+ u32 bss_change;
+ u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
- if (local->ops->reset_tsf) {
- /* Reset own TSF to allow time synchronization work. */
- local->ops->reset_tsf(local_to_hw(local));
- }
+ /* Reset own TSF to allow time synchronization work. */
+ drv_reset_tsf(local);
- if ((ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) &&
- memcmp(ifibss->bssid, bssid, ETH_ALEN) == 0)
- return res;
+ skb = ifibss->skb;
+ rcu_assign_pointer(ifibss->presp, NULL);
+ synchronize_rcu();
+ skb->data = skb->head;
+ skb->len = 0;
+ skb_reset_tail_pointer(skb);
+ skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
- skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
- if (!skb) {
- printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
- "response\n", sdata->dev->name);
- return -ENOMEM;
- }
-
- if (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) {
- /* Remove possible STA entries from other IBSS networks. */
- sta_info_flush_delayed(sdata);
- }
+ if (memcmp(ifibss->bssid, bssid, ETH_ALEN))
+ sta_info_flush(sdata->local, sdata);
memcpy(ifibss->bssid, bssid, ETH_ALEN);
- res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
- if (res)
- return res;
-
- local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
- sdata->drop_unencrypted = capability &
- WLAN_CAPABILITY_PRIVACY ? 1 : 0;
+ sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
- res = ieee80211_set_freq(sdata, freq);
+ local->oper_channel = chan;
+ local->oper_channel_type = NL80211_CHAN_NO_HT;
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
- if (res)
- return res;
+ sband = local->hw.wiphy->bands[chan->band];
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ /* build supported rates array */
+ pos = supp_rates;
+ for (i = 0; i < sband->n_bitrates; i++) {
+ int rate = sband->bitrates[i].bitrate;
+ u8 basic = 0;
+ if (basic_rates & BIT(i))
+ basic = 0x80;
+ *pos++ = basic | (u8) (rate / 5);
+ }
/* Build IBSS probe response */
-
- skb_reserve(skb, local->hw.extra_tx_headroom);
-
- mgmt = (struct ieee80211_mgmt *)
- skb_put(skb, 24 + sizeof(mgmt->u.beacon));
+ mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_PROBE_RESP);
memset(mgmt->da, 0xff, ETH_ALEN);
memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
- mgmt->u.beacon.beacon_int =
- cpu_to_le16(local->hw.conf.beacon_int);
+ mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int);
mgmt->u.beacon.timestamp = cpu_to_le64(tsf);
mgmt->u.beacon.capab_info = cpu_to_le16(capability);
@@ -135,7 +127,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
*pos++ = ifibss->ssid_len;
memcpy(pos, ifibss->ssid, ifibss->ssid_len);
- rates = supp_rates_len;
+ rates = sband->n_bitrates;
if (rates > 8)
rates = 8;
pos = skb_put(skb, 2 + rates);
@@ -147,7 +139,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
pos = skb_put(skb, 2 + 1);
*pos++ = WLAN_EID_DS_PARAMS;
*pos++ = 1;
- *pos++ = ieee80211_frequency_to_channel(freq);
+ *pos++ = ieee80211_frequency_to_channel(chan->center_freq);
}
pos = skb_put(skb, 2 + 2);
@@ -157,51 +149,73 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
*pos++ = 0;
*pos++ = 0;
- if (supp_rates_len > 8) {
- rates = supp_rates_len - 8;
+ if (sband->n_bitrates > 8) {
+ rates = sband->n_bitrates - 8;
pos = skb_put(skb, 2 + rates);
*pos++ = WLAN_EID_EXT_SUPP_RATES;
*pos++ = rates;
memcpy(pos, &supp_rates[8], rates);
}
- ifibss->probe_resp = skb;
+ if (ifibss->ie_len)
+ memcpy(skb_put(skb, ifibss->ie_len),
+ ifibss->ie, ifibss->ie_len);
- ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
- IEEE80211_IFCC_BEACON_ENABLED);
+ rcu_assign_pointer(ifibss->presp, skb);
+ sdata->vif.bss_conf.beacon_int = beacon_int;
+ bss_change = BSS_CHANGED_BEACON_INT;
+ bss_change |= ieee80211_reset_erp_info(sdata);
+ bss_change |= BSS_CHANGED_BSSID;
+ bss_change |= BSS_CHANGED_BEACON;
+ bss_change |= BSS_CHANGED_BEACON_ENABLED;
+ ieee80211_bss_info_change_notify(sdata, bss_change);
- rates = 0;
- for (i = 0; i < supp_rates_len; i++) {
- int bitrate = (supp_rates[i] & 0x7f) * 5;
- for (j = 0; j < sband->n_bitrates; j++)
- if (sband->bitrates[j].bitrate == bitrate)
- rates |= BIT(j);
- }
-
- ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
+ ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates);
- ifibss->flags |= IEEE80211_IBSS_PREV_BSSID_SET;
ifibss->state = IEEE80211_IBSS_MLME_JOINED;
- mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
+ mod_timer(&ifibss->timer,
+ round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
- memset(&wrqu, 0, sizeof(wrqu));
- memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
- wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
-
- return res;
+ cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,
+ mgmt, skb->len, 0, GFP_KERNEL);
+ cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
}
-static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_bss *bss)
+static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_bss *bss)
{
- return __ieee80211_sta_join_ibss(sdata,
- bss->cbss.bssid,
- bss->cbss.beacon_interval,
- bss->cbss.channel->center_freq,
- bss->supp_rates_len, bss->supp_rates,
- bss->cbss.capability,
- bss->cbss.tsf);
+ struct ieee80211_supported_band *sband;
+ u32 basic_rates;
+ int i, j;
+ u16 beacon_int = bss->cbss.beacon_interval;
+
+ if (beacon_int < 10)
+ beacon_int = 10;
+
+ sband = sdata->local->hw.wiphy->bands[bss->cbss.channel->band];
+
+ basic_rates = 0;
+
+ for (i = 0; i < bss->supp_rates_len; i++) {
+ int rate = (bss->supp_rates[i] & 0x7f) * 5;
+ bool is_basic = !!(bss->supp_rates[i] & 0x80);
+
+ for (j = 0; j < sband->n_bitrates; j++) {
+ if (sband->bitrates[j].bitrate == rate) {
+ if (is_basic)
+ basic_rates |= BIT(j);
+ break;
+ }
+ }
+ }
+
+ __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid,
+ beacon_int,
+ bss->cbss.channel,
+ basic_rates,
+ bss->cbss.capability,
+ bss->cbss.tsf);
}
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -277,7 +291,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
goto put_bss;
/* we use a fixed BSSID */
- if (sdata->u.ibss.flags & IEEE80211_IBSS_BSSID_SET)
+ if (sdata->u.ibss.bssid)
goto put_bss;
/* not an IBSS */
@@ -322,12 +336,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
bitrates[rx_status->rate_idx].bitrate;
rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
- } else if (local && local->ops && local->ops->get_tsf)
- /* second best option: get current TSF */
- rx_timestamp = local->ops->get_tsf(local_to_hw(local));
- else
- /* can't merge without knowing the TSF */
- rx_timestamp = -1LLU;
+ } else {
+ /*
+ * second best option: get current TSF
+ * (will return -1 if not supported)
+ */
+ rx_timestamp = drv_get_tsf(local);
+ }
#ifdef CONFIG_MAC80211_IBSS_DEBUG
printk(KERN_DEBUG "RX beacon SA=%pM BSSID="
@@ -369,13 +384,14 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta;
int band = local->hw.conf.channel->band;
- /* TODO: Could consider removing the least recently used entry and
- * allow new one to be added. */
+ /*
+ * XXX: Consider removing the least recently used entry and
+ * allow new one to be added.
+ */
if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "%s: No room for a new IBSS STA "
- "entry %pM\n", sdata->dev->name, addr);
- }
+ if (net_ratelimit())
+ printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n",
+ sdata->dev->name, addr);
return NULL;
}
@@ -432,41 +448,33 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
- mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
+ mod_timer(&ifibss->timer,
+ round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
+
if (ieee80211_sta_active_ibss(sdata))
return;
- if ((ifibss->flags & IEEE80211_IBSS_BSSID_SET) &&
- (!(ifibss->flags & IEEE80211_IBSS_AUTO_CHANNEL_SEL)))
+ if (ifibss->fixed_channel)
return;
printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
"IBSS networks with same SSID (merge)\n", sdata->dev->name);
- /* XXX maybe racy? */
- if (sdata->local->scan_req)
- return;
-
- memcpy(sdata->local->int_scan_req.ssids[0].ssid,
- ifibss->ssid, IEEE80211_MAX_SSID_LEN);
- sdata->local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len;
- ieee80211_request_scan(sdata, &sdata->local->int_scan_req);
+ ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len);
}
-static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
+static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;
struct ieee80211_supported_band *sband;
- u8 *pos;
u8 bssid[ETH_ALEN];
- u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
u16 capability;
int i;
- if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) {
+ if (ifibss->fixed_bssid) {
memcpy(bssid, ifibss->bssid, ETH_ALEN);
} else {
/* Generate random, not broadcast, locally administered BSSID. Mix in
@@ -482,10 +490,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
sdata->dev->name, bssid);
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
- if (local->hw.conf.beacon_int == 0)
- local->hw.conf.beacon_int = 100;
+ sband = local->hw.wiphy->bands[ifibss->channel->band];
capability = WLAN_CAPABILITY_IBSS;
@@ -494,29 +499,20 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
else
sdata->drop_unencrypted = 0;
- pos = supp_rates;
- for (i = 0; i < sband->n_bitrates; i++) {
- int rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
- }
-
- return __ieee80211_sta_join_ibss(sdata,
- bssid, local->hw.conf.beacon_int,
- local->hw.conf.channel->center_freq,
- sband->n_bitrates, supp_rates,
- capability, 0);
+ __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
+ ifibss->channel, 3, /* first two are basic */
+ capability, 0);
}
-static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
+static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;
struct ieee80211_bss *bss;
+ struct ieee80211_channel *chan = NULL;
const u8 *bssid = NULL;
int active_ibss;
-
- if (ifibss->ssid_len == 0)
- return -EINVAL;
+ u16 capability;
active_ibss = ieee80211_sta_active_ibss(sdata);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
@@ -525,14 +521,23 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
if (active_ibss)
- return 0;
+ return;
+
+ capability = WLAN_CAPABILITY_IBSS;
+ if (sdata->default_key)
+ capability |= WLAN_CAPABILITY_PRIVACY;
- if (ifibss->flags & IEEE80211_IBSS_BSSID_SET)
+ if (ifibss->fixed_bssid)
bssid = ifibss->bssid;
- bss = (void *)cfg80211_get_bss(local->hw.wiphy, NULL, bssid,
+ if (ifibss->fixed_channel)
+ chan = ifibss->channel;
+ if (!is_zero_ether_addr(ifibss->bssid))
+ bssid = ifibss->bssid;
+ bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid,
ifibss->ssid, ifibss->ssid_len,
- WLAN_CAPABILITY_IBSS,
- WLAN_CAPABILITY_IBSS);
+ capability,
+ WLAN_CAPABILITY_IBSS |
+ WLAN_CAPABILITY_PRIVACY);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
if (bss)
@@ -540,18 +545,14 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
"%pM\n", bss->cbss.bssid, ifibss->bssid);
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
- if (bss &&
- (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) ||
- memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN))) {
- int ret;
-
+ if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) {
printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
" based on configured SSID\n",
sdata->dev->name, bss->cbss.bssid);
- ret = ieee80211_sta_join_ibss(sdata, bss);
+ ieee80211_sta_join_ibss(sdata, bss);
ieee80211_rx_bss_put(local, bss);
- return ret;
+ return;
} else if (bss)
ieee80211_rx_bss_put(local, bss);
@@ -562,29 +563,24 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
/* Selected IBSS not found in current scan results - try to scan */
if (ifibss->state == IEEE80211_IBSS_MLME_JOINED &&
!ieee80211_sta_active_ibss(sdata)) {
- mod_timer(&ifibss->timer, jiffies +
- IEEE80211_IBSS_MERGE_INTERVAL);
- } else if (time_after(jiffies, local->last_scan_completed +
+ mod_timer(&ifibss->timer,
+ round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
+ } else if (time_after(jiffies, ifibss->last_scan_completed +
IEEE80211_SCAN_INTERVAL)) {
printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
"join\n", sdata->dev->name);
- /* XXX maybe racy? */
- if (local->scan_req)
- return -EBUSY;
-
- memcpy(local->int_scan_req.ssids[0].ssid,
- ifibss->ssid, IEEE80211_MAX_SSID_LEN);
- local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len;
- return ieee80211_request_scan(sdata, &local->int_scan_req);
+ ieee80211_request_internal_scan(sdata, ifibss->ssid,
+ ifibss->ssid_len);
} else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) {
int interval = IEEE80211_SCAN_INTERVAL;
if (time_after(jiffies, ifibss->ibss_join_req +
IEEE80211_IBSS_JOIN_TIMEOUT)) {
- if (!(local->oper_channel->flags &
- IEEE80211_CHAN_NO_IBSS))
- return ieee80211_sta_create_ibss(sdata);
+ if (!(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) {
+ ieee80211_sta_create_ibss(sdata);
+ return;
+ }
printk(KERN_DEBUG "%s: IBSS not allowed on"
" %d MHz\n", sdata->dev->name,
local->hw.conf.channel->center_freq);
@@ -595,11 +591,9 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
}
ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
- mod_timer(&ifibss->timer, jiffies + interval);
- return 0;
+ mod_timer(&ifibss->timer,
+ round_jiffies(jiffies + interval));
}
-
- return 0;
}
static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
@@ -614,13 +608,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
u8 *pos, *end;
if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
- len < 24 + 2 || !ifibss->probe_resp)
+ len < 24 + 2 || !ifibss->presp)
return;
- if (local->ops->tx_last_beacon)
- tx_last_beacon = local->ops->tx_last_beacon(local_to_hw(local));
- else
- tx_last_beacon = 1;
+ tx_last_beacon = drv_tx_last_beacon(local);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM"
@@ -649,13 +640,13 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
}
if (pos[1] != 0 &&
(pos[1] != ifibss->ssid_len ||
- memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len) != 0)) {
+ !memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) {
/* Ignore ProbeReq for foreign SSID */
return;
}
/* Reply with ProbeResp */
- skb = skb_copy(ifibss->probe_resp, GFP_KERNEL);
+ skb = skb_copy(ifibss->presp, GFP_KERNEL);
if (!skb)
return;
@@ -794,89 +785,25 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
setup_timer(&ifibss->timer, ieee80211_ibss_timer,
(unsigned long) sdata);
skb_queue_head_init(&ifibss->skb_queue);
-
- ifibss->flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
- IEEE80211_IBSS_AUTO_CHANNEL_SEL;
-}
-
-int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata)
-{
- struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
-
- ifibss->flags &= ~IEEE80211_IBSS_PREV_BSSID_SET;
-
- if (ifibss->ssid_len)
- ifibss->flags |= IEEE80211_IBSS_SSID_SET;
- else
- ifibss->flags &= ~IEEE80211_IBSS_SSID_SET;
-
- ifibss->ibss_join_req = jiffies;
- ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
- set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
-
- return 0;
-}
-
-int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
-{
- struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
-
- if (len > IEEE80211_MAX_SSID_LEN)
- return -EINVAL;
-
- if (ifibss->ssid_len != len || memcmp(ifibss->ssid, ssid, len) != 0) {
- memset(ifibss->ssid, 0, sizeof(ifibss->ssid));
- memcpy(ifibss->ssid, ssid, len);
- ifibss->ssid_len = len;
- }
-
- return ieee80211_ibss_commit(sdata);
-}
-
-int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
-{
- struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
-
- memcpy(ssid, ifibss->ssid, ifibss->ssid_len);
- *len = ifibss->ssid_len;
-
- return 0;
-}
-
-int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
-{
- struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
-
- if (is_valid_ether_addr(bssid)) {
- memcpy(ifibss->bssid, bssid, ETH_ALEN);
- ifibss->flags |= IEEE80211_IBSS_BSSID_SET;
- } else {
- memset(ifibss->bssid, 0, ETH_ALEN);
- ifibss->flags &= ~IEEE80211_IBSS_BSSID_SET;
- }
-
- if (netif_running(sdata->dev)) {
- if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) {
- printk(KERN_DEBUG "%s: Failed to config new BSSID to "
- "the low-level driver\n", sdata->dev->name);
- }
- }
-
- return ieee80211_ibss_commit(sdata);
}
/* scan finished notification */
void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
{
- struct ieee80211_sub_if_data *sdata = local->scan_sdata;
- struct ieee80211_if_ibss *ifibss;
-
- if (sdata && sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- ifibss = &sdata->u.ibss;
- if ((!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) ||
- !ieee80211_sta_active_ibss(sdata))
- ieee80211_sta_find_ibss(sdata);
+ struct ieee80211_sub_if_data *sdata;
+
+ mutex_lock(&local->iflist_mtx);
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (!netif_running(sdata->dev))
+ continue;
+ if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
+ continue;
+ if (!sdata->u.ibss.ssid_len)
+ continue;
+ sdata->u.ibss.last_scan_completed = jiffies;
+ ieee80211_sta_find_ibss(sdata);
}
+ mutex_unlock(&local->iflist_mtx);
}
ieee80211_rx_result
@@ -906,3 +833,86 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
return RX_DROP_MONITOR;
}
+
+int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_ibss_params *params)
+{
+ struct sk_buff *skb;
+
+ if (params->bssid) {
+ memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
+ sdata->u.ibss.fixed_bssid = true;
+ } else
+ sdata->u.ibss.fixed_bssid = false;
+
+ sdata->vif.bss_conf.beacon_int = params->beacon_interval;
+
+ sdata->u.ibss.channel = params->channel;
+ sdata->u.ibss.fixed_channel = params->channel_fixed;
+
+ if (params->ie) {
+ sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len,
+ GFP_KERNEL);
+ if (sdata->u.ibss.ie)
+ sdata->u.ibss.ie_len = params->ie_len;
+ }
+
+ skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
+ 36 /* bitrates */ +
+ 34 /* SSID */ +
+ 3 /* DS params */ +
+ 4 /* IBSS params */ +
+ params->ie_len);
+ if (!skb)
+ return -ENOMEM;
+
+ sdata->u.ibss.skb = skb;
+ sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
+ sdata->u.ibss.ibss_join_req = jiffies;
+
+ memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
+
+ /*
+ * The ssid_len setting below is used to see whether
+ * we are active, and we need all other settings
+ * before that may get visible.
+ */
+ mb();
+
+ sdata->u.ibss.ssid_len = params->ssid_len;
+
+ ieee80211_recalc_idle(sdata->local);
+
+ set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
+ queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work);
+
+ return 0;
+}
+
+int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
+{
+ struct sk_buff *skb;
+
+ del_timer_sync(&sdata->u.ibss.timer);
+ clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
+ cancel_work_sync(&sdata->u.ibss.work);
+ clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
+
+ sta_info_flush(sdata->local, sdata);
+
+ /* remove beacon */
+ kfree(sdata->u.ibss.ie);
+ skb = sdata->u.ibss.presp;
+ rcu_assign_pointer(sdata->u.ibss.presp, NULL);
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
+ synchronize_rcu();
+ kfree_skb(skb);
+
+ skb_queue_purge(&sdata->u.ibss.skb_queue);
+ memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
+ sdata->u.ibss.ssid_len = 0;
+
+ ieee80211_recalc_idle(sdata->local);
+
+ return 0;
+}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e6ed78cb16b3..9d1514727f6e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -24,7 +24,6 @@
#include <linux/spinlock.h>
#include <linux/etherdevice.h>
#include <net/cfg80211.h>
-#include <net/wireless.h>
#include <net/iw_handler.h>
#include <net/mac80211.h>
#include "key.h"
@@ -236,7 +235,7 @@ struct mesh_preq_queue {
#define IEEE80211_STA_ASSOCIATED BIT(4)
#define IEEE80211_STA_PROBEREQ_POLL BIT(5)
#define IEEE80211_STA_CREATE_IBSS BIT(6)
-/* hole at 7, please re-use */
+#define IEEE80211_STA_CONTROL_PORT BIT(7)
#define IEEE80211_STA_WMM_ENABLED BIT(8)
/* hole at 9, please re-use */
#define IEEE80211_STA_AUTO_SSID_SEL BIT(10)
@@ -249,9 +248,8 @@ struct mesh_preq_queue {
#define IEEE80211_STA_EXT_SME BIT(17)
/* flags for MLME request */
#define IEEE80211_STA_REQ_SCAN 0
-#define IEEE80211_STA_REQ_DIRECT_PROBE 1
-#define IEEE80211_STA_REQ_AUTH 2
-#define IEEE80211_STA_REQ_RUN 3
+#define IEEE80211_STA_REQ_AUTH 1
+#define IEEE80211_STA_REQ_RUN 2
/* bitfield of allowed auth algs */
#define IEEE80211_AUTH_ALG_OPEN BIT(0)
@@ -295,6 +293,8 @@ struct ieee80211_if_managed {
int auth_tries; /* retries for auth req */
int assoc_tries; /* retries for assoc req */
+ bool powersave; /* powersave requested for this iface */
+
unsigned long request;
unsigned long last_probe;
@@ -306,6 +306,8 @@ struct ieee80211_if_managed {
int auth_alg; /* currently used IEEE 802.11 authentication algorithm */
int auth_transaction;
+ u32 beacon_crc;
+
enum {
IEEE80211_MFP_DISABLED,
IEEE80211_MFP_OPTIONAL,
@@ -319,14 +321,6 @@ struct ieee80211_if_managed {
size_t sme_auth_ie_len;
};
-enum ieee80211_ibss_flags {
- IEEE80211_IBSS_AUTO_CHANNEL_SEL = BIT(0),
- IEEE80211_IBSS_AUTO_BSSID_SEL = BIT(1),
- IEEE80211_IBSS_BSSID_SET = BIT(2),
- IEEE80211_IBSS_PREV_BSSID_SET = BIT(3),
- IEEE80211_IBSS_SSID_SET = BIT(4),
-};
-
enum ieee80211_ibss_request {
IEEE80211_IBSS_REQ_RUN = 0,
};
@@ -337,17 +331,20 @@ struct ieee80211_if_ibss {
struct sk_buff_head skb_queue;
- u8 ssid[IEEE80211_MAX_SSID_LEN];
- u8 ssid_len;
-
- u32 flags;
+ unsigned long request;
+ unsigned long last_scan_completed;
+ bool fixed_bssid;
+ bool fixed_channel;
u8 bssid[ETH_ALEN];
-
- unsigned long request;
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 ssid_len, ie_len;
+ u8 *ie;
+ struct ieee80211_channel *channel;
unsigned long ibss_join_req;
- struct sk_buff *probe_resp; /* ProbeResp template for IBSS */
+ /* probe response/beacon for IBSS */
+ struct sk_buff *presp, *skb;
enum {
IEEE80211_IBSS_MLME_SEARCH,
@@ -430,6 +427,12 @@ struct ieee80211_sub_if_data {
int drop_unencrypted;
+ /*
+ * keep track of whether the HT opmode (stored in
+ * vif.bss_info.ht_operation_mode) is valid.
+ */
+ bool ht_opmode_valid;
+
/* Fragment table for host-based reassembly */
struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
unsigned int fragment_next;
@@ -626,8 +629,6 @@ struct ieee80211_local {
spinlock_t sta_lock;
unsigned long num_sta;
struct list_head sta_list;
- struct list_head sta_flush_list;
- struct work_struct sta_flush_work;
struct sta_info *sta_hash[STA_HASH_SIZE];
struct timer_list sta_cleanup;
@@ -647,9 +648,6 @@ struct ieee80211_local {
struct rate_control_ref *rate_ctrl;
- int rts_threshold;
- int fragmentation_threshold;
-
struct crypto_blkcipher *wep_tx_tfm;
struct crypto_blkcipher *wep_rx_tfm;
u32 wep_iv;
@@ -666,15 +664,18 @@ struct ieee80211_local {
/* Scanning and BSS list */
+ struct mutex scan_mtx;
bool sw_scanning, hw_scanning;
struct cfg80211_ssid scan_ssid;
struct cfg80211_scan_request int_scan_req;
struct cfg80211_scan_request *scan_req;
struct ieee80211_channel *scan_channel;
+ const u8 *orig_ies;
+ int orig_ies_len;
int scan_channel_idx;
+ int scan_ies_len;
enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
- unsigned long last_scan_completed;
struct delayed_work scan_work;
struct ieee80211_sub_if_data *scan_sdata;
enum nl80211_channel_type oper_channel_type;
@@ -736,15 +737,22 @@ struct ieee80211_local {
int wifi_wme_noack_test;
unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
- bool powersave;
bool pspolling;
+ /*
+ * PS can only be enabled when we have exactly one managed
+ * interface (and monitors) in PS, this then points there.
+ */
+ struct ieee80211_sub_if_data *ps_sdata;
struct work_struct dynamic_ps_enable_work;
struct work_struct dynamic_ps_disable_work;
struct timer_list dynamic_ps_timer;
+ struct notifier_block network_latency_notifier;
int user_power_level; /* in dBm */
int power_constr_level; /* in dBm */
+ struct work_struct restart_work;
+
#ifdef CONFIG_MAC80211_DEBUGFS
struct local_debugfsdentries {
struct dentry *rcdir;
@@ -758,6 +766,7 @@ struct ieee80211_local {
struct dentry *wep_iv;
struct dentry *tsf;
struct dentry *reset;
+ struct dentry *noack;
struct dentry *statistics;
struct local_debugfsdentries_statsdentries {
struct dentry *transmitted_fragment_count;
@@ -830,7 +839,7 @@ struct ieee802_11_elems {
u8 *fh_params;
u8 *ds_params;
u8 *cf_params;
- u8 *tim;
+ struct ieee80211_tim_ie *tim;
u8 *ibss_params;
u8 *challenge;
u8 *wpa;
@@ -903,7 +912,6 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
-int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
u32 changed);
@@ -927,12 +935,11 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
void ieee80211_send_pspoll(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata);
+void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
+int ieee80211_max_network_latency(struct notifier_block *nb,
+ unsigned long data, void *dummy);
/* IBSS code */
-int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata);
-int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len);
-int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len);
-int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid);
void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
ieee80211_rx_result
@@ -940,9 +947,14 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
struct ieee80211_rx_status *rx_status);
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
u8 *bssid, u8 *addr, u32 supp_rates);
+int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_ibss_params *params);
+int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
/* scan/BSS handling */
void ieee80211_scan_work(struct work_struct *work);
+int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
+ const u8 *ssid, u8 ssid_len);
int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
struct cfg80211_scan_request *req);
int ieee80211_scan_results(struct ieee80211_local *local,
@@ -956,9 +968,6 @@ int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
const char *ie, size_t len);
void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
-void ieee80211_scan_failed(struct ieee80211_local *local);
-int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
- struct cfg80211_scan_request *req);
struct ieee80211_bss *
ieee80211_bss_info_update(struct ieee80211_local *local,
struct ieee80211_rx_status *rx_status,
@@ -983,6 +992,8 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
enum nl80211_iftype type);
void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
void ieee80211_remove_interfaces(struct ieee80211_local *local);
+u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
+void ieee80211_recalc_idle(struct ieee80211_local *local);
/* tx handling */
void ieee80211_clear_tx_pending(struct ieee80211_local *local);
@@ -995,9 +1006,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
struct ieee80211_ht_cap *ht_cap_ie,
struct ieee80211_sta_ht_cap *ht_cap);
-u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_ht_info *hti,
- u16 ap_ht_cap_flags);
void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
const u8 *da, u16 tid,
@@ -1036,15 +1044,22 @@ void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
u16 capab_info, u8 *pwr_constr_elem,
u8 pwr_constr_elem_len);
-/* Suspend/resume */
+/* Suspend/resume and hw reconfiguration */
+int ieee80211_reconfig(struct ieee80211_local *local);
+
#ifdef CONFIG_PM
int __ieee80211_suspend(struct ieee80211_hw *hw);
-int __ieee80211_resume(struct ieee80211_hw *hw);
+
+static inline int __ieee80211_resume(struct ieee80211_hw *hw)
+{
+ return ieee80211_reconfig(hw_to_local(hw));
+}
#else
static inline int __ieee80211_suspend(struct ieee80211_hw *hw)
{
return 0;
}
+
static inline int __ieee80211_resume(struct ieee80211_hw *hw)
{
return 0;
@@ -1060,12 +1075,15 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
int rate, int erp, int short_preamble);
void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
- struct ieee80211_hdr *hdr);
+ struct ieee80211_hdr *hdr, const u8 *tsc);
void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
int encrypt);
void ieee802_11_parse_elems(u8 *start, size_t len,
struct ieee802_11_elems *elems);
+u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
+ struct ieee802_11_elems *elems,
+ u64 filter, u32 crc);
int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
enum ieee80211_band band);
@@ -1093,9 +1111,11 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
u16 transaction, u16 auth_alg,
u8 *extra, size_t extra_len,
const u8 *bssid, int encrypt);
+int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
+ const u8 *ie, size_t ie_len);
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
- u8 *ssid, size_t ssid_len,
- u8 *ie, size_t ie_len);
+ const u8 *ssid, size_t ssid_len,
+ const u8 *ie, size_t ie_len);
void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
const size_t supp_rates_len,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 91e8e1bacaaa..8c9f1c722cdb 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -20,6 +20,7 @@
#include "debugfs_netdev.h"
#include "mesh.h"
#include "led.h"
+#include "driver-ops.h"
/**
* DOC: Interface list locking
@@ -164,9 +165,7 @@ static int ieee80211_open(struct net_device *dev)
}
if (local->open_count == 0) {
- res = 0;
- if (local->ops->start)
- res = local->ops->start(local_to_hw(local));
+ res = drv_start(local);
if (res)
goto err_del_bss;
/* we're brought up, everything changes */
@@ -199,8 +198,8 @@ static int ieee80211_open(struct net_device *dev)
* Validate the MAC address for this device.
*/
if (!is_valid_ether_addr(dev->dev_addr)) {
- if (!local->open_count && local->ops->stop)
- local->ops->stop(local_to_hw(local));
+ if (!local->open_count)
+ drv_stop(local);
return -EADDRNOTAVAIL;
}
@@ -235,17 +234,13 @@ static int ieee80211_open(struct net_device *dev)
netif_addr_unlock_bh(local->mdev);
break;
case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_ADHOC:
- if (sdata->vif.type == NL80211_IFTYPE_STATION)
- sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
- else
- sdata->u.ibss.flags &= ~IEEE80211_IBSS_PREV_BSSID_SET;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
/* fall through */
default:
conf.vif = &sdata->vif;
conf.type = sdata->vif.type;
conf.mac_addr = dev->dev_addr;
- res = local->ops->add_interface(local_to_hw(local), &conf);
+ res = drv_add_interface(local, &conf);
if (res)
goto err_stop;
@@ -306,6 +301,8 @@ static int ieee80211_open(struct net_device *dev)
if (sdata->flags & IEEE80211_SDATA_PROMISC)
atomic_inc(&local->iff_promiscs);
+ hw_reconf_flags |= __ieee80211_recalc_idle(local);
+
local->open_count++;
if (hw_reconf_flags) {
ieee80211_hw_config(local, hw_reconf_flags);
@@ -317,6 +314,8 @@ static int ieee80211_open(struct net_device *dev)
ieee80211_set_wmm_default(sdata);
}
+ ieee80211_recalc_ps(local, -1);
+
/*
* ieee80211_sta_work is disabled while network interface
* is down. Therefore, some configuration changes may not
@@ -325,17 +324,15 @@ static int ieee80211_open(struct net_device *dev)
*/
if (sdata->vif.type == NL80211_IFTYPE_STATION)
queue_work(local->hw.workqueue, &sdata->u.mgd.work);
- else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
- queue_work(local->hw.workqueue, &sdata->u.ibss.work);
netif_tx_start_all_queues(dev);
return 0;
err_del_interface:
- local->ops->remove_interface(local_to_hw(local), &conf);
+ drv_remove_interface(local, &conf);
err_stop:
- if (!local->open_count && local->ops->stop)
- local->ops->stop(local_to_hw(local));
+ if (!local->open_count)
+ drv_stop(local);
err_del_bss:
sdata->bss = NULL;
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
@@ -497,7 +494,6 @@ static int ieee80211_stop(struct net_device *dev)
/* fall through */
case NL80211_IFTYPE_ADHOC:
if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
del_timer_sync(&sdata->u.ibss.timer);
cancel_work_sync(&sdata->u.ibss.work);
synchronize_rcu();
@@ -549,17 +545,20 @@ static int ieee80211_stop(struct net_device *dev)
conf.mac_addr = dev->dev_addr;
/* disable all keys for as long as this netdev is down */
ieee80211_disable_keys(sdata);
- local->ops->remove_interface(local_to_hw(local), &conf);
+ drv_remove_interface(local, &conf);
}
sdata->bss = NULL;
+ hw_reconf_flags |= __ieee80211_recalc_idle(local);
+
+ ieee80211_recalc_ps(local, -1);
+
if (local->open_count == 0) {
if (netif_running(local->mdev))
dev_close(local->mdev);
- if (local->ops->stop)
- local->ops->stop(local_to_hw(local));
+ drv_stop(local);
ieee80211_led_radio(local, 0);
@@ -649,7 +648,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
mesh_rmc_free(sdata);
break;
case NL80211_IFTYPE_ADHOC:
- kfree_skb(sdata->u.ibss.probe_resp);
+ if (WARN_ON(sdata->u.ibss.presp))
+ kfree_skb(sdata->u.ibss.presp);
break;
case NL80211_IFTYPE_STATION:
kfree(sdata->u.mgd.extra_ie);
@@ -896,3 +896,74 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
unregister_netdevice(sdata->dev);
}
}
+
+static u32 ieee80211_idle_off(struct ieee80211_local *local,
+ const char *reason)
+{
+ if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
+ return 0;
+
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ printk(KERN_DEBUG "%s: device no longer idle - %s\n",
+ wiphy_name(local->hw.wiphy), reason);
+#endif
+
+ local->hw.conf.flags &= ~IEEE80211_CONF_IDLE;
+ return IEEE80211_CONF_CHANGE_IDLE;
+}
+
+static u32 ieee80211_idle_on(struct ieee80211_local *local)
+{
+ if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
+ return 0;
+
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ printk(KERN_DEBUG "%s: device now idle\n",
+ wiphy_name(local->hw.wiphy));
+#endif
+
+ local->hw.conf.flags |= IEEE80211_CONF_IDLE;
+ return IEEE80211_CONF_CHANGE_IDLE;
+}
+
+u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
+{
+ struct ieee80211_sub_if_data *sdata;
+ int count = 0;
+
+ if (local->hw_scanning || local->sw_scanning)
+ return ieee80211_idle_off(local, "scanning");
+
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (!netif_running(sdata->dev))
+ continue;
+ /* do not count disabled managed interfaces */
+ if (sdata->vif.type == NL80211_IFTYPE_STATION &&
+ sdata->u.mgd.state == IEEE80211_STA_MLME_DISABLED)
+ continue;
+ /* do not count unused IBSS interfaces */
+ if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
+ !sdata->u.ibss.ssid_len)
+ continue;
+ /* count everything else */
+ count++;
+ }
+
+ if (!count)
+ return ieee80211_idle_on(local);
+ else
+ return ieee80211_idle_off(local, "in use");
+
+ return 0;
+}
+
+void ieee80211_recalc_idle(struct ieee80211_local *local)
+{
+ u32 chg;
+
+ mutex_lock(&local->iflist_mtx);
+ chg = __ieee80211_recalc_idle(local);
+ mutex_unlock(&local->iflist_mtx);
+ if (chg)
+ ieee80211_hw_config(local, chg);
+}
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 687acf23054d..827ea8e6ee0a 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -16,6 +16,7 @@
#include <linux/rtnetlink.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "debugfs_key.h"
#include "aes_ccm.h"
#include "aes_cmac.h"
@@ -136,8 +137,7 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
struct ieee80211_sub_if_data,
u.ap);
- ret = key->local->ops->set_key(local_to_hw(key->local), SET_KEY,
- &sdata->vif, sta, &key->conf);
+ ret = drv_set_key(key->local, SET_KEY, &sdata->vif, sta, &key->conf);
if (!ret) {
spin_lock(&todo_lock);
@@ -179,8 +179,8 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
struct ieee80211_sub_if_data,
u.ap);
- ret = key->local->ops->set_key(local_to_hw(key->local), DISABLE_KEY,
- &sdata->vif, sta, &key->conf);
+ ret = drv_set_key(key->local, DISABLE_KEY, &sdata->vif,
+ sta, &key->conf);
if (ret)
printk(KERN_ERR "mac80211-%s: failed to remove key "
@@ -290,9 +290,11 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
int idx,
size_t key_len,
- const u8 *key_data)
+ const u8 *key_data,
+ size_t seq_len, const u8 *seq)
{
struct ieee80211_key *key;
+ int i, j;
BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
@@ -318,14 +320,31 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
case ALG_TKIP:
key->conf.iv_len = TKIP_IV_LEN;
key->conf.icv_len = TKIP_ICV_LEN;
+ if (seq && seq_len == 6) {
+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
+ key->u.tkip.rx[i].iv32 =
+ get_unaligned_le32(&seq[2]);
+ key->u.tkip.rx[i].iv16 =
+ get_unaligned_le16(seq);
+ }
+ }
break;
case ALG_CCMP:
key->conf.iv_len = CCMP_HDR_LEN;
key->conf.icv_len = CCMP_MIC_LEN;
+ if (seq && seq_len == CCMP_PN_LEN) {
+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
+ for (j = 0; j < CCMP_PN_LEN; j++)
+ key->u.ccmp.rx_pn[i][j] =
+ seq[CCMP_PN_LEN - j - 1];
+ }
break;
case ALG_AES_CMAC:
key->conf.iv_len = 0;
key->conf.icv_len = sizeof(struct ieee80211_mmie);
+ if (seq && seq_len == 6)
+ for (j = 0; j < 6; j++)
+ key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
break;
}
memcpy(key->conf.key, key_data, key_len);
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 215d3ef42a4f..9572e00f532c 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -144,7 +144,8 @@ struct ieee80211_key {
struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
int idx,
size_t key_len,
- const u8 *key_data);
+ const u8 *key_data,
+ size_t seq_len, const u8 *seq);
/*
* Insert a key into data structures (sdata, sta if necessary)
* to make it used, free old key.
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 14134193cd17..76df5eabf268 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -21,10 +21,12 @@
#include <linux/wireless.h>
#include <linux/rtnetlink.h>
#include <linux/bitmap.h>
+#include <linux/pm_qos_params.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "rate.h"
#include "mesh.h"
#include "wep.h"
@@ -80,10 +82,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
/* be a bit nasty */
new_flags |= (1<<31);
- local->ops->configure_filter(local_to_hw(local),
- changed_flags, &new_flags,
- local->mdev->mc_count,
- local->mdev->mc_list);
+ drv_configure_filter(local, changed_flags, &new_flags,
+ local->mdev->mc_count,
+ local->mdev->mc_list);
WARN_ON(new_flags & (1<<31));
@@ -151,93 +152,19 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev)
ieee80211_configure_filter(local);
}
-/* everything else */
-
-int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
-{
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_if_conf conf;
-
- if (WARN_ON(!netif_running(sdata->dev)))
- return 0;
-
- memset(&conf, 0, sizeof(conf));
-
- if (sdata->vif.type == NL80211_IFTYPE_STATION)
- conf.bssid = sdata->u.mgd.bssid;
- else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
- conf.bssid = sdata->u.ibss.bssid;
- else if (sdata->vif.type == NL80211_IFTYPE_AP)
- conf.bssid = sdata->dev->dev_addr;
- else if (ieee80211_vif_is_mesh(&sdata->vif)) {
- static const u8 zero[ETH_ALEN] = { 0 };
- conf.bssid = zero;
- } else {
- WARN_ON(1);
- return -EINVAL;
- }
-
- if (!local->ops->config_interface)
- return 0;
-
- switch (sdata->vif.type) {
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_MESH_POINT:
- break;
- default:
- /* do not warn to simplify caller in scan.c */
- changed &= ~IEEE80211_IFCC_BEACON_ENABLED;
- if (WARN_ON(changed & IEEE80211_IFCC_BEACON))
- return -EINVAL;
- changed &= ~IEEE80211_IFCC_BEACON;
- break;
- }
-
- if (changed & IEEE80211_IFCC_BEACON_ENABLED) {
- if (local->sw_scanning) {
- conf.enable_beacon = false;
- } else {
- /*
- * Beacon should be enabled, but AP mode must
- * check whether there is a beacon configured.
- */
- switch (sdata->vif.type) {
- case NL80211_IFTYPE_AP:
- conf.enable_beacon =
- !!rcu_dereference(sdata->u.ap.beacon);
- break;
- case NL80211_IFTYPE_ADHOC:
- conf.enable_beacon = !!sdata->u.ibss.probe_resp;
- break;
- case NL80211_IFTYPE_MESH_POINT:
- conf.enable_beacon = true;
- break;
- default:
- /* not reached */
- WARN_ON(1);
- break;
- }
- }
- }
-
- conf.changed = changed;
-
- return local->ops->config_interface(local_to_hw(local),
- &sdata->vif, &conf);
-}
-
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
{
- struct ieee80211_channel *chan;
+ struct ieee80211_channel *chan, *scan_chan;
int ret = 0;
int power;
enum nl80211_channel_type channel_type;
might_sleep();
- if (local->sw_scanning) {
- chan = local->scan_channel;
+ scan_chan = local->scan_channel;
+
+ if (scan_chan) {
+ chan = scan_chan;
channel_type = NL80211_CHAN_NO_HT;
} else {
chan = local->oper_channel;
@@ -251,7 +178,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
changed |= IEEE80211_CONF_CHANGE_CHANNEL;
}
- if (local->sw_scanning)
+ if (scan_chan)
power = chan->max_power;
else
power = local->power_constr_level ?
@@ -267,7 +194,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
}
if (changed && local->open_count) {
- ret = local->ops->config(local_to_hw(local), changed);
+ ret = drv_config(local, changed);
/*
* Goal:
* HW reconfiguration should never fail, the driver has told
@@ -293,17 +220,77 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_local *local = sdata->local;
- if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
+ if (!changed)
return;
- if (!changed)
+ if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
+ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
+ else if (sdata->vif.type == NL80211_IFTYPE_AP)
+ sdata->vif.bss_conf.bssid = sdata->dev->dev_addr;
+ else if (ieee80211_vif_is_mesh(&sdata->vif)) {
+ static const u8 zero[ETH_ALEN] = { 0 };
+ sdata->vif.bss_conf.bssid = zero;
+ } else {
+ WARN_ON(1);
return;
+ }
+
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
+ break;
+ default:
+ /* do not warn to simplify caller in scan.c */
+ changed &= ~BSS_CHANGED_BEACON_ENABLED;
+ if (WARN_ON(changed & BSS_CHANGED_BEACON))
+ return;
+ break;
+ }
- if (local->ops->bss_info_changed)
- local->ops->bss_info_changed(local_to_hw(local),
- &sdata->vif,
- &sdata->vif.bss_conf,
- changed);
+ if (changed & BSS_CHANGED_BEACON_ENABLED) {
+ if (local->sw_scanning) {
+ sdata->vif.bss_conf.enable_beacon = false;
+ } else {
+ /*
+ * Beacon should be enabled, but AP mode must
+ * check whether there is a beacon configured.
+ */
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_AP:
+ sdata->vif.bss_conf.enable_beacon =
+ !!rcu_dereference(sdata->u.ap.beacon);
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ sdata->vif.bss_conf.enable_beacon =
+ !!rcu_dereference(sdata->u.ibss.presp);
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ sdata->vif.bss_conf.enable_beacon = true;
+ break;
+ default:
+ /* not reached */
+ WARN_ON(1);
+ break;
+ }
+ }
+ }
+
+ drv_bss_info_changed(local, &sdata->vif,
+ &sdata->vif.bss_conf, changed);
+
+ /*
+ * DEPRECATED
+ *
+ * ~changed is just there to not do this at resume time
+ */
+ if (changed & BSS_CHANGED_BEACON_INT && ~changed) {
+ local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int;
+ ieee80211_hw_config(local,
+ _IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
+ }
}
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
@@ -696,6 +683,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
}
EXPORT_SYMBOL(ieee80211_tx_status);
+static void ieee80211_restart_work(struct work_struct *work)
+{
+ struct ieee80211_local *local =
+ container_of(work, struct ieee80211_local, restart_work);
+
+ rtnl_lock();
+ ieee80211_reconfig(local);
+ rtnl_unlock();
+}
+
+void ieee80211_restart_hw(struct ieee80211_hw *hw)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ /* use this reason, __ieee80211_resume will unblock it */
+ ieee80211_stop_queues_by_reason(hw,
+ IEEE80211_QUEUE_STOP_REASON_SUSPEND);
+
+ schedule_work(&local->restart_work);
+}
+EXPORT_SYMBOL(ieee80211_restart_hw);
+
struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
const struct ieee80211_ops *ops)
{
@@ -728,12 +737,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
return NULL;
wiphy->privid = mac80211_wiphy_privid;
- wiphy->max_scan_ssids = 4;
+
/* Yes, putting cfg80211_bss into ieee80211_bss is a hack */
wiphy->bss_priv_size = sizeof(struct ieee80211_bss) -
sizeof(struct cfg80211_bss);
local = wiphy_priv(wiphy);
+
local->hw.wiphy = wiphy;
local->hw.priv = (char *)local +
@@ -752,15 +762,14 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
/* set up some defaults */
local->hw.queues = 1;
local->hw.max_rates = 1;
- local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
- local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
- local->hw.conf.long_frame_max_tx_count = 4;
- local->hw.conf.short_frame_max_tx_count = 7;
+ local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
+ local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
local->hw.conf.radio_enabled = true;
local->user_power_level = -1;
INIT_LIST_HEAD(&local->interfaces);
mutex_init(&local->iflist_mtx);
+ mutex_init(&local->scan_mtx);
spin_lock_init(&local->key_lock);
@@ -768,6 +777,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
+ INIT_WORK(&local->restart_work, ieee80211_restart_work);
+
INIT_WORK(&local->dynamic_ps_enable_work,
ieee80211_dynamic_ps_enable_work);
INIT_WORK(&local->dynamic_ps_disable_work,
@@ -821,7 +832,17 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
enum ieee80211_band band;
struct net_device *mdev;
struct ieee80211_master_priv *mpriv;
- int channels, i, j;
+ int channels, i, j, max_bitrates;
+ bool supp_ht;
+ static const u32 cipher_suites[] = {
+ WLAN_CIPHER_SUITE_WEP40,
+ WLAN_CIPHER_SUITE_WEP104,
+ WLAN_CIPHER_SUITE_TKIP,
+ WLAN_CIPHER_SUITE_CCMP,
+
+ /* keep last -- depends on hw flags! */
+ WLAN_CIPHER_SUITE_AES_CMAC
+ };
/*
* generic code guarantees at least one band,
@@ -829,18 +850,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
* that hw.conf.channel is assigned
*/
channels = 0;
+ max_bitrates = 0;
+ supp_ht = false;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
struct ieee80211_supported_band *sband;
sband = local->hw.wiphy->bands[band];
- if (sband && !local->oper_channel) {
+ if (!sband)
+ continue;
+ if (!local->oper_channel) {
/* init channel we're on */
local->hw.conf.channel =
- local->oper_channel =
- local->scan_channel = &sband->channels[0];
+ local->oper_channel = &sband->channels[0];
+ local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
}
- if (sband)
- channels += sband->n_channels;
+ channels += sband->n_channels;
+
+ if (max_bitrates < sband->n_bitrates)
+ max_bitrates = sband->n_bitrates;
+ supp_ht = supp_ht || sband->ht_cap.ht_supported;
}
local->int_scan_req.n_channels = channels;
@@ -860,6 +888,37 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
+ /*
+ * Calculate scan IE length -- we need this to alloc
+ * memory and to subtract from the driver limit. It
+ * includes the (extended) supported rates and HT
+ * information -- SSID is the driver's responsibility.
+ */
+ local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */
+ if (supp_ht)
+ local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
+
+ if (!local->ops->hw_scan) {
+ /* For hw_scan, driver needs to set these up. */
+ local->hw.wiphy->max_scan_ssids = 4;
+ local->hw.wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
+ }
+
+ /*
+ * If the driver supports any scan IEs, then assume the
+ * limit includes the IEs mac80211 will add, otherwise
+ * leave it at zero and let the driver sort it out; we
+ * still pass our IEs to the driver but userspace will
+ * not be allowed to in that case.
+ */
+ if (local->hw.wiphy->max_scan_ie_len)
+ local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;
+
+ local->hw.wiphy->cipher_suites = cipher_suites;
+ local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+ if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE))
+ local->hw.wiphy->n_cipher_suites--;
+
result = wiphy_register(local->hw.wiphy);
if (result < 0)
goto fail_wiphy_register;
@@ -898,9 +957,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
debugfs_hw_add(local);
- if (local->hw.conf.beacon_int < 10)
- local->hw.conf.beacon_int = 100;
-
if (local->hw.max_listen_interval == 0)
local->hw.max_listen_interval = 1;
@@ -965,25 +1021,38 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
}
}
+ local->network_latency_notifier.notifier_call =
+ ieee80211_max_network_latency;
+ result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
+ &local->network_latency_notifier);
+
+ if (result) {
+ rtnl_lock();
+ goto fail_pm_qos;
+ }
+
return 0;
-fail_rate:
+ fail_pm_qos:
+ ieee80211_led_exit(local);
+ ieee80211_remove_interfaces(local);
+ fail_rate:
unregister_netdevice(local->mdev);
local->mdev = NULL;
-fail_dev:
+ fail_dev:
rtnl_unlock();
ieee80211_wep_free(local);
-fail_wep:
+ fail_wep:
sta_info_stop(local);
-fail_sta_info:
+ fail_sta_info:
debugfs_hw_del(local);
destroy_workqueue(local->hw.workqueue);
-fail_workqueue:
+ fail_workqueue:
if (local->mdev)
free_netdev(local->mdev);
-fail_mdev_alloc:
+ fail_mdev_alloc:
wiphy_unregister(local->hw.wiphy);
-fail_wiphy_register:
+ fail_wiphy_register:
kfree(local->int_scan_req.channels);
return result;
}
@@ -996,6 +1065,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
tasklet_kill(&local->tx_pending_tasklet);
tasklet_kill(&local->tasklet);
+ pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
+ &local->network_latency_notifier);
+
rtnl_lock();
/*
@@ -1038,6 +1110,7 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
struct ieee80211_local *local = hw_to_local(hw);
mutex_destroy(&local->iflist_mtx);
+ mutex_destroy(&local->scan_mtx);
wiphy_free(local->hw.wiphy);
}
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 9a3e5de0410a..9000b01a1671 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -417,7 +417,7 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
free_plinks = mesh_plink_availables(sdata);
if (free_plinks != sdata->u.mesh.accepting_plinks)
- ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
ifmsh->housekeeping = false;
mod_timer(&ifmsh->housekeeping_timer,
@@ -432,8 +432,8 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
ifmsh->housekeeping = true;
queue_work(local->hw.workqueue, &ifmsh->work);
- ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
- IEEE80211_IFCC_BEACON_ENABLED);
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
+ BSS_CHANGED_BEACON_ENABLED);
}
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 132938b073dc..ae030688771f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -17,10 +17,13 @@
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
+#include <linux/pm_qos_params.h>
+#include <linux/crc32.h>
#include <net/mac80211.h>
#include <asm/unaligned.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "rate.h"
#include "led.h"
@@ -30,6 +33,7 @@
#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
#define IEEE80211_ASSOC_MAX_TRIES 3
#define IEEE80211_MONITORING_INTERVAL (2 * HZ)
+#define IEEE80211_PROBE_WAIT (HZ / 20)
#define IEEE80211_PROBE_IDLE_TIME (60 * HZ)
#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)
@@ -80,6 +84,88 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
return count;
}
+/*
+ * ieee80211_enable_ht should be called only after the operating band
+ * has been determined as ht configuration depends on the hw's
+ * HT abilities for a specific band.
+ */
+static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_ht_info *hti,
+ u16 ap_ht_cap_flags)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ struct sta_info *sta;
+ u32 changed = 0;
+ u16 ht_opmode;
+ bool enable_ht = true, ht_changed;
+ enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
+
+ sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
+ /* HT is not supported */
+ if (!sband->ht_cap.ht_supported)
+ enable_ht = false;
+
+ /* check that channel matches the right operating channel */
+ if (local->hw.conf.channel->center_freq !=
+ ieee80211_channel_to_frequency(hti->control_chan))
+ enable_ht = false;
+
+ if (enable_ht) {
+ channel_type = NL80211_CHAN_HT20;
+
+ if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
+ (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
+ (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
+ switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+ channel_type = NL80211_CHAN_HT40PLUS;
+ break;
+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+ channel_type = NL80211_CHAN_HT40MINUS;
+ break;
+ }
+ }
+ }
+
+ ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
+ channel_type != local->hw.conf.channel_type;
+
+ local->oper_channel_type = channel_type;
+
+ if (ht_changed) {
+ /* channel_type change automatically detected */
+ ieee80211_hw_config(local, 0);
+
+ rcu_read_lock();
+
+ sta = sta_info_get(local, ifmgd->bssid);
+ if (sta)
+ rate_control_rate_update(local, sband, sta,
+ IEEE80211_RC_HT_CHANGED);
+
+ rcu_read_unlock();
+ }
+
+ /* disable HT */
+ if (!enable_ht)
+ return 0;
+
+ ht_opmode = le16_to_cpu(hti->operation_mode);
+
+ /* if bss configuration changed store the new one */
+ if (!sdata->ht_opmode_valid ||
+ sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
+ changed |= BSS_CHANGED_HT;
+ sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
+ sdata->ht_opmode_valid = true;
+ }
+
+ return changed;
+}
+
/* frame sending functions */
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
@@ -325,6 +411,10 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
/* u.deauth.reason_code == u.disassoc.reason_code */
mgmt->u.deauth.reason_code = cpu_to_le16(reason);
+ if (stype == IEEE80211_STYPE_DEAUTH)
+ cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len);
+ else
+ cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len);
ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
}
@@ -359,6 +449,173 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
ieee80211_tx_skb(sdata, skb, 0);
}
+void ieee80211_send_nullfunc(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ int powersave)
+{
+ struct sk_buff *skb;
+ struct ieee80211_hdr *nullfunc;
+ __le16 fc;
+
+ if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
+ return;
+
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
+ if (!skb) {
+ printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
+ "frame\n", sdata->dev->name);
+ return;
+ }
+ skb_reserve(skb, local->hw.extra_tx_headroom);
+
+ nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
+ memset(nullfunc, 0, 24);
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+ IEEE80211_FCTL_TODS);
+ if (powersave)
+ fc |= cpu_to_le16(IEEE80211_FCTL_PM);
+ nullfunc->frame_control = fc;
+ memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
+ memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
+ memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
+
+ ieee80211_tx_skb(sdata, skb, 0);
+}
+
+/* powersave */
+static void ieee80211_enable_ps(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_conf *conf = &local->hw.conf;
+
+ /*
+ * If we are scanning right now then the parameters will
+ * take effect when scan finishes.
+ */
+ if (local->hw_scanning || local->sw_scanning)
+ return;
+
+ if (conf->dynamic_ps_timeout > 0 &&
+ !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
+ mod_timer(&local->dynamic_ps_timer, jiffies +
+ msecs_to_jiffies(conf->dynamic_ps_timeout));
+ } else {
+ if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
+ ieee80211_send_nullfunc(local, sdata, 1);
+ conf->flags |= IEEE80211_CONF_PS;
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+ }
+}
+
+static void ieee80211_change_ps(struct ieee80211_local *local)
+{
+ struct ieee80211_conf *conf = &local->hw.conf;
+
+ if (local->ps_sdata) {
+ if (!(local->ps_sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
+ return;
+
+ ieee80211_enable_ps(local, local->ps_sdata);
+ } else if (conf->flags & IEEE80211_CONF_PS) {
+ conf->flags &= ~IEEE80211_CONF_PS;
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+ del_timer_sync(&local->dynamic_ps_timer);
+ cancel_work_sync(&local->dynamic_ps_enable_work);
+ }
+}
+
+/* need to hold RTNL or interface lock */
+void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
+{
+ struct ieee80211_sub_if_data *sdata, *found = NULL;
+ int count = 0;
+
+ if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) {
+ local->ps_sdata = NULL;
+ return;
+ }
+
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (!netif_running(sdata->dev))
+ continue;
+ if (sdata->vif.type != NL80211_IFTYPE_STATION)
+ continue;
+ found = sdata;
+ count++;
+ }
+
+ if (count == 1 && found->u.mgd.powersave) {
+ s32 beaconint_us;
+
+ if (latency < 0)
+ latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY);
+
+ beaconint_us = ieee80211_tu_to_usec(
+ found->vif.bss_conf.beacon_int);
+
+ if (beaconint_us > latency) {
+ local->ps_sdata = NULL;
+ } else {
+ u8 dtimper = found->vif.bss_conf.dtim_period;
+ int maxslp = 1;
+
+ if (dtimper > 1)
+ maxslp = min_t(int, dtimper,
+ latency / beaconint_us);
+
+ local->hw.conf.max_sleep_period = maxslp;
+ local->ps_sdata = found;
+ }
+ } else {
+ local->ps_sdata = NULL;
+ }
+
+ ieee80211_change_ps(local);
+}
+
+void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
+{
+ struct ieee80211_local *local =
+ container_of(work, struct ieee80211_local,
+ dynamic_ps_disable_work);
+
+ if (local->hw.conf.flags & IEEE80211_CONF_PS) {
+ local->hw.conf.flags &= ~IEEE80211_CONF_PS;
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+ }
+
+ ieee80211_wake_queues_by_reason(&local->hw,
+ IEEE80211_QUEUE_STOP_REASON_PS);
+}
+
+void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
+{
+ struct ieee80211_local *local =
+ container_of(work, struct ieee80211_local,
+ dynamic_ps_enable_work);
+ struct ieee80211_sub_if_data *sdata = local->ps_sdata;
+
+ /* can only happen when PS was just disabled anyway */
+ if (!sdata)
+ return;
+
+ if (local->hw.conf.flags & IEEE80211_CONF_PS)
+ return;
+
+ if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
+ ieee80211_send_nullfunc(local, sdata, 1);
+
+ local->hw.conf.flags |= IEEE80211_CONF_PS;
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+}
+
+void ieee80211_dynamic_ps_timer(unsigned long data)
+{
+ struct ieee80211_local *local = (void *) data;
+
+ queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
+}
+
/* MLME */
static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
struct ieee80211_if_managed *ifmgd,
@@ -427,38 +684,13 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
local->mdev->name, queue, aci, acm, params.aifs, params.cw_min,
params.cw_max, params.txop);
#endif
- if (local->ops->conf_tx &&
- local->ops->conf_tx(local_to_hw(local), queue, &params)) {
+ if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx)
printk(KERN_DEBUG "%s: failed to set TX queue "
- "parameters for queue %d\n", local->mdev->name, queue);
- }
+ "parameters for queue %d\n", local->mdev->name,
+ queue);
}
}
-static bool ieee80211_check_tim(struct ieee802_11_elems *elems, u16 aid)
-{
- u8 mask;
- u8 index, indexn1, indexn2;
- struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) elems->tim;
-
- if (unlikely(!tim || elems->tim_len < 4))
- return false;
-
- aid &= 0x3fff;
- index = aid / 8;
- mask = 1 << (aid & 7);
-
- indexn1 = tim->bitmap_ctrl & 0xfe;
- indexn2 = elems->tim_len + indexn1 - 4;
-
- if (index < indexn1 || index > indexn2)
- return false;
-
- index -= indexn1;
-
- return !!(tim->virtual_map[index] & mask);
-}
-
static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
u16 capab, bool erp_valid, u8 erp)
{
@@ -610,6 +842,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
sdata->vif.bss_conf.dtim_period = bss->dtim_period;
+ bss_info_changed |= BSS_CHANGED_BEACON_INT;
bss_info_changed |= ieee80211_handle_bss_capability(sdata,
bss->cbss.capability, bss->has_erp_value, bss->erp_value);
@@ -634,18 +867,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
bss_info_changed |= BSS_CHANGED_BASIC_RATES;
ieee80211_bss_info_change_notify(sdata, bss_info_changed);
- if (local->powersave) {
- if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) &&
- local->hw.conf.dynamic_ps_timeout > 0) {
- mod_timer(&local->dynamic_ps_timer, jiffies +
- msecs_to_jiffies(
- local->hw.conf.dynamic_ps_timeout));
- } else {
- if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
- ieee80211_send_nullfunc(local, sdata, 1);
- conf->flags |= IEEE80211_CONF_PS;
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
- }
+ /* will be same as sdata */
+ if (local->ps_sdata) {
+ mutex_lock(&local->iflist_mtx);
+ ieee80211_recalc_ps(local, -1);
+ mutex_unlock(&local->iflist_mtx);
}
netif_tx_start_all_queues(sdata->dev);
@@ -664,7 +890,8 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
sdata->dev->name, ifmgd->bssid);
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
- ieee80211_sta_send_apinfo(sdata);
+ ieee80211_recalc_idle(local);
+ cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
/*
* Most likely AP is not in the range so remove the
@@ -689,8 +916,6 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE;
- set_bit(IEEE80211_STA_REQ_DIRECT_PROBE, &ifmgd->request);
-
/* Direct probe is sent to broadcast address as some APs
* will not answer to direct packet in unassociated state.
*/
@@ -714,7 +939,8 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
" timed out\n",
sdata->dev->name, ifmgd->bssid);
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
- ieee80211_sta_send_apinfo(sdata);
+ ieee80211_recalc_idle(local);
+ cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
sdata->local->hw.conf.channel->center_freq,
ifmgd->ssid, ifmgd->ssid_len);
@@ -817,9 +1043,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
rcu_read_unlock();
+ ieee80211_set_wmm_default(sdata);
+
+ ieee80211_recalc_idle(local);
+
/* channel(_type) changes are handled by ieee80211_hw_config */
local->oper_channel_type = NL80211_CHAN_NO_HT;
+ /* on the next assoc, re-program HT parameters */
+ sdata->ht_opmode_valid = false;
+
local->power_constr_level = 0;
del_timer_sync(&local->dynamic_ps_timer);
@@ -897,7 +1130,8 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
" timed out\n",
sdata->dev->name, ifmgd->bssid);
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
- ieee80211_sta_send_apinfo(sdata);
+ ieee80211_recalc_idle(local);
+ cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid);
ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
sdata->local->hw.conf.channel->center_freq,
ifmgd->ssid, ifmgd->ssid_len);
@@ -917,6 +1151,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
"mixed-cell disabled - abort association\n", sdata->dev->name);
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
+ ieee80211_recalc_idle(local);
return;
}
@@ -948,6 +1183,17 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
u.mgd.beacon_loss_work);
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ /*
+ * The driver has already reported this event and we have
+ * already sent a probe request. Maybe the AP died and the
+ * driver keeps reporting until we disassociate... We have
+ * to ignore that because otherwise we would continually
+ * reset the timer and never check whether we received a
+ * probe response!
+ */
+ if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
+ return;
+
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM "
@@ -960,7 +1206,7 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
ifmgd->ssid_len, NULL, 0);
- mod_timer(&ifmgd->timer, jiffies + IEEE80211_MONITORING_INTERVAL);
+ mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);
}
void ieee80211_beacon_loss(struct ieee80211_vif *vif)
@@ -997,7 +1243,7 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
}
if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&
- time_after(jiffies, sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
+ time_after(jiffies, sta->last_rx + IEEE80211_PROBE_WAIT)) {
printk(KERN_DEBUG "%s: no probe response from AP %pM "
"- disassociating\n",
sdata->dev->name, ifmgd->bssid);
@@ -1055,6 +1301,7 @@ static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata)
if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
/* Wait for SME to request association */
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
+ ieee80211_recalc_idle(sdata->local);
} else
ieee80211_associate(sdata);
}
@@ -1187,7 +1434,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
ieee80211_set_disassoc(sdata, true, false, 0);
ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED;
- cfg80211_send_rx_deauth(sdata->dev, (u8 *) mgmt, len);
+ cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, len);
}
@@ -1218,7 +1465,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
}
ieee80211_set_disassoc(sdata, false, false, reason_code);
- cfg80211_send_rx_disassoc(sdata->dev, (u8 *) mgmt, len);
+ cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, len);
}
@@ -1287,6 +1534,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
* association next time. This works around some broken APs
* which do not correctly reject reassociation requests. */
ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
+ cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len);
+ if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
+ /* Wait for SME to decide what to do next */
+ ifmgd->state = IEEE80211_STA_MLME_DISABLED;
+ ieee80211_recalc_idle(local);
+ }
return;
}
@@ -1340,8 +1593,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
* to between the sta_info_alloc() and sta_info_insert() above.
*/
- set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
- WLAN_STA_AUTHORIZED);
+ set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP);
+ if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
+ set_sta_flags(sta, WLAN_STA_AUTHORIZED);
rates = 0;
basic_rates = 0;
@@ -1421,6 +1675,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
if (elems.wmm_param)
ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,
elems.wmm_param_len);
+ else
+ ieee80211_set_wmm_default(sdata);
if (elems.ht_info_elem && elems.wmm_param &&
(ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
@@ -1507,8 +1763,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
/* direct probe may be part of the association flow */
- if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE,
- &ifmgd->request)) {
+ if (ifmgd->state == IEEE80211_STA_MLME_DIRECT_PROBE) {
printk(KERN_DEBUG "%s direct probe responded\n",
sdata->dev->name);
ieee80211_authenticate(sdata);
@@ -1518,46 +1773,74 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
}
+/*
+ * This is the canonical list of information elements we care about,
+ * the filter code also gives us all changes to the Microsoft OUI
+ * (00:50:F2) vendor IE which is used for WMM which we need to track.
+ *
+ * We implement beacon filtering in software since that means we can
+ * avoid processing the frame here and in cfg80211, and userspace
+ * will not be able to tell whether the hardware supports it or not.
+ *
+ * XXX: This list needs to be dynamic -- userspace needs to be able to
+ * add items it requires. It also needs to be able to tell us to
+ * look out for other vendor IEs.
+ */
+static const u64 care_about_ies =
+ (1ULL << WLAN_EID_COUNTRY) |
+ (1ULL << WLAN_EID_ERP_INFO) |
+ (1ULL << WLAN_EID_CHANNEL_SWITCH) |
+ (1ULL << WLAN_EID_PWR_CONSTRAINT) |
+ (1ULL << WLAN_EID_HT_CAPABILITY) |
+ (1ULL << WLAN_EID_HT_INFORMATION);
+
static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
size_t len,
struct ieee80211_rx_status *rx_status)
{
- struct ieee80211_if_managed *ifmgd;
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
size_t baselen;
struct ieee802_11_elems elems;
struct ieee80211_local *local = sdata->local;
u32 changed = 0;
- bool erp_valid, directed_tim;
+ bool erp_valid, directed_tim = false;
u8 erp_value = 0;
+ u32 ncrc;
/* Process beacon from the current BSS */
baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
if (baselen > len)
return;
- ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
-
- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
-
- if (sdata->vif.type != NL80211_IFTYPE_STATION)
+ if (rx_status->freq != local->hw.conf.channel->center_freq)
return;
- ifmgd = &sdata->u.mgd;
-
if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED) ||
memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0)
return;
- if (rx_status->freq != local->hw.conf.channel->center_freq)
+ ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
+ ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
+ len - baselen, &elems,
+ care_about_ies, ncrc);
+
+ if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
+ directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
+ ifmgd->aid);
+
+ ncrc = crc32_be(ncrc, (void *)&directed_tim, sizeof(directed_tim));
+
+ if (ncrc == ifmgd->beacon_crc)
return;
+ ifmgd->beacon_crc = ncrc;
+
+ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,
elems.wmm_param_len);
if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
- directed_tim = ieee80211_check_tim(&elems, ifmgd->aid);
-
if (directed_tim) {
if (local->hw.conf.dynamic_ps_timeout > 0) {
local->hw.conf.flags &= ~IEEE80211_CONF_PS;
@@ -1723,10 +2006,8 @@ static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata)
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local;
- if (local->ops->reset_tsf) {
- /* Reset own TSF to allow time synchronization work. */
- local->ops->reset_tsf(local_to_hw(local));
- }
+ /* Reset own TSF to allow time synchronization work. */
+ drv_reset_tsf(local);
ifmgd->wmm_last_param_set = -1; /* allow any WMM update */
@@ -1814,25 +2095,18 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
return 0;
} else {
if (ifmgd->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
+
ifmgd->assoc_scan_tries++;
- /* XXX maybe racy? */
- if (local->scan_req)
- return -1;
- memcpy(local->int_scan_req.ssids[0].ssid,
- ifmgd->ssid, IEEE80211_MAX_SSID_LEN);
- if (ifmgd->flags & IEEE80211_STA_AUTO_SSID_SEL)
- local->int_scan_req.ssids[0].ssid_len = 0;
- else
- local->int_scan_req.ssids[0].ssid_len = ifmgd->ssid_len;
- if (ieee80211_start_scan(sdata, &local->int_scan_req))
- ieee80211_scan_failed(local);
+ ieee80211_request_internal_scan(sdata, ifmgd->ssid,
+ ssid_len);
ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE;
set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
} else {
ifmgd->assoc_scan_tries = 0;
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
+ ieee80211_recalc_idle(local);
}
}
return -1;
@@ -1864,14 +2138,8 @@ static void ieee80211_sta_work(struct work_struct *work)
ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE &&
ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE &&
test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) {
- /*
- * The call to ieee80211_start_scan can fail but ieee80211_request_scan
- * (which queued ieee80211_sta_work) did not return an error. Thus, call
- * ieee80211_scan_failed here if ieee80211_start_scan fails in order to
- * notify the scan requester.
- */
- if (ieee80211_start_scan(sdata, local->scan_req))
- ieee80211_scan_failed(local);
+ queue_delayed_work(local->hw.workqueue, &local->scan_work,
+ round_jiffies_relative(0));
return;
}
@@ -1882,6 +2150,8 @@ static void ieee80211_sta_work(struct work_struct *work)
} else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request))
return;
+ ieee80211_recalc_idle(local);
+
switch (ifmgd->state) {
case IEEE80211_STA_MLME_DISABLED:
break;
@@ -1930,6 +2200,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_managed *ifmgd;
+ u32 hw_flags;
ifmgd = &sdata->u.mgd;
INIT_WORK(&ifmgd->work, ieee80211_sta_work);
@@ -1949,6 +2220,13 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
IEEE80211_STA_AUTO_CHANNEL_SEL;
if (sdata->local->hw.queues >= 4)
ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
+
+ hw_flags = sdata->local->hw.flags;
+
+ if (hw_flags & IEEE80211_HW_SUPPORTS_PS) {
+ ifmgd->powersave = CONFIG_MAC80211_DEFAULT_PS_VALUE;
+ sdata->local->hw.conf.dynamic_ps_timeout = 500;
+ }
}
/* configuration hooks */
@@ -2032,12 +2310,8 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
ifmgd->flags &= ~IEEE80211_STA_BSSID_SET;
}
- if (netif_running(sdata->dev)) {
- if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) {
- printk(KERN_DEBUG "%s: Failed to config new BSSID to "
- "the low-level driver\n", sdata->dev->name);
- }
- }
+ if (netif_running(sdata->dev))
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
return ieee80211_sta_commit(sdata);
}
@@ -2068,9 +2342,6 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
sdata->dev->name, reason);
- if (sdata->vif.type != NL80211_IFTYPE_STATION)
- return -EINVAL;
-
ieee80211_set_disassoc(sdata, true, true, reason);
return 0;
}
@@ -2082,9 +2353,6 @@ int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
sdata->dev->name, reason);
- if (sdata->vif.type != NL80211_IFTYPE_STATION)
- return -EINVAL;
-
if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED))
return -ENOLINK;
@@ -2104,75 +2372,17 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
rcu_read_unlock();
}
-void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
-{
- struct ieee80211_local *local =
- container_of(work, struct ieee80211_local,
- dynamic_ps_disable_work);
-
- if (local->hw.conf.flags & IEEE80211_CONF_PS) {
- local->hw.conf.flags &= ~IEEE80211_CONF_PS;
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
- }
-
- ieee80211_wake_queues_by_reason(&local->hw,
- IEEE80211_QUEUE_STOP_REASON_PS);
-}
-
-void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
+int ieee80211_max_network_latency(struct notifier_block *nb,
+ unsigned long data, void *dummy)
{
+ s32 latency_usec = (s32) data;
struct ieee80211_local *local =
- container_of(work, struct ieee80211_local,
- dynamic_ps_enable_work);
- /* XXX: using scan_sdata is completely broken! */
- struct ieee80211_sub_if_data *sdata = local->scan_sdata;
-
- if (local->hw.conf.flags & IEEE80211_CONF_PS)
- return;
-
- if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK && sdata)
- ieee80211_send_nullfunc(local, sdata, 1);
-
- local->hw.conf.flags |= IEEE80211_CONF_PS;
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
-}
-
-void ieee80211_dynamic_ps_timer(unsigned long data)
-{
- struct ieee80211_local *local = (void *) data;
+ container_of(nb, struct ieee80211_local,
+ network_latency_notifier);
- queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
-}
-
-void ieee80211_send_nullfunc(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata,
- int powersave)
-{
- struct sk_buff *skb;
- struct ieee80211_hdr *nullfunc;
- __le16 fc;
-
- if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
- return;
-
- skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
- if (!skb) {
- printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
- "frame\n", sdata->dev->name);
- return;
- }
- skb_reserve(skb, local->hw.extra_tx_headroom);
+ mutex_lock(&local->iflist_mtx);
+ ieee80211_recalc_ps(local, latency_usec);
+ mutex_unlock(&local->iflist_mtx);
- nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
- memset(nullfunc, 0, 24);
- fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
- IEEE80211_FCTL_TODS);
- if (powersave)
- fc |= cpu_to_le16(IEEE80211_FCTL_PM);
- nullfunc->frame_control = fc;
- memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
- memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
- memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
-
- ieee80211_tx_skb(sdata, skb, 0);
+ return 0;
}
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 81985d27cbda..9d3d89abbb57 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -2,6 +2,7 @@
#include <net/rtnetlink.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "led.h"
int __ieee80211_suspend(struct ieee80211_hw *hw)
@@ -43,8 +44,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
struct ieee80211_sub_if_data,
u.ap);
- local->ops->sta_notify(hw, &sdata->vif,
- STA_NOTIFY_REMOVE, &sta->sta);
+ drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
+ &sta->sta);
}
spin_unlock_irqrestore(&local->sta_lock, flags);
}
@@ -57,7 +58,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
conf.vif = &sdata->vif;
conf.type = sdata->vif.type;
conf.mac_addr = sdata->dev->dev_addr;
- local->ops->remove_interface(hw, &conf);
+ drv_remove_interface(local, &conf);
}
}
@@ -67,124 +68,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
/* stop hardware */
if (local->open_count) {
ieee80211_led_radio(local, false);
- local->ops->stop(hw);
+ drv_stop(local);
}
return 0;
}
-int __ieee80211_resume(struct ieee80211_hw *hw)
-{
- struct ieee80211_local *local = hw_to_local(hw);
- struct ieee80211_sub_if_data *sdata;
- struct ieee80211_if_init_conf conf;
- struct sta_info *sta;
- unsigned long flags;
- int res;
-
- /* restart hardware */
- if (local->open_count) {
- res = local->ops->start(hw);
-
- ieee80211_led_radio(local, hw->conf.radio_enabled);
- }
-
- /* add interfaces */
- list_for_each_entry(sdata, &local->interfaces, list) {
- if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
- sdata->vif.type != NL80211_IFTYPE_MONITOR &&
- netif_running(sdata->dev)) {
- conf.vif = &sdata->vif;
- conf.type = sdata->vif.type;
- conf.mac_addr = sdata->dev->dev_addr;
- res = local->ops->add_interface(hw, &conf);
- }
- }
-
- /* add STAs back */
- if (local->ops->sta_notify) {
- spin_lock_irqsave(&local->sta_lock, flags);
- list_for_each_entry(sta, &local->sta_list, list) {
- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- sdata = container_of(sdata->bss,
- struct ieee80211_sub_if_data,
- u.ap);
-
- local->ops->sta_notify(hw, &sdata->vif,
- STA_NOTIFY_ADD, &sta->sta);
- }
- spin_unlock_irqrestore(&local->sta_lock, flags);
- }
-
- /* Clear Suspend state so that ADDBA requests can be processed */
-
- rcu_read_lock();
-
- if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
- list_for_each_entry_rcu(sta, &local->sta_list, list) {
- clear_sta_flags(sta, WLAN_STA_SUSPEND);
- }
- }
-
- rcu_read_unlock();
-
- /* add back keys */
- list_for_each_entry(sdata, &local->interfaces, list)
- if (netif_running(sdata->dev))
- ieee80211_enable_keys(sdata);
-
- /* setup RTS threshold */
- if (local->ops->set_rts_threshold)
- local->ops->set_rts_threshold(hw, local->rts_threshold);
-
- /* reconfigure hardware */
- ieee80211_hw_config(local, ~0);
-
- netif_addr_lock_bh(local->mdev);
- ieee80211_configure_filter(local);
- netif_addr_unlock_bh(local->mdev);
-
- /* Finally also reconfigure all the BSS information */
- list_for_each_entry(sdata, &local->interfaces, list) {
- u32 changed = ~0;
- if (!netif_running(sdata->dev))
- continue;
- switch (sdata->vif.type) {
- case NL80211_IFTYPE_STATION:
- /* disable beacon change bits */
- changed &= ~IEEE80211_IFCC_BEACON;
- /* fall through */
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_MESH_POINT:
- /*
- * Driver's config_interface can fail if rfkill is
- * enabled. Accommodate this return code.
- * FIXME: When mac80211 has knowledge of rfkill
- * state the code below can change back to:
- * WARN(ieee80211_if_config(sdata, changed));
- * ieee80211_bss_info_change_notify(sdata, ~0);
- */
- if (ieee80211_if_config(sdata, changed))
- printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
- sdata->dev->name);
- else
- ieee80211_bss_info_change_notify(sdata, ~0);
- break;
- case NL80211_IFTYPE_WDS:
- break;
- case NL80211_IFTYPE_AP_VLAN:
- case NL80211_IFTYPE_MONITOR:
- /* ignore virtual */
- break;
- case NL80211_IFTYPE_UNSPECIFIED:
- case __NL80211_IFTYPE_AFTER_LAST:
- WARN_ON(1);
- break;
- }
- }
-
- ieee80211_wake_queues_by_reason(hw,
- IEEE80211_QUEUE_STOP_REASON_SUSPEND);
-
- return 0;
-}
+/*
+ * __ieee80211_resume() is a static inline which just calls
+ * ieee80211_reconfig(), which is also needed for hardware
+ * hang/firmware failure/etc. recovery.
+ */
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 3824990d340b..0a11515341ba 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -80,8 +80,7 @@ use_low_rate(struct sk_buff *skb)
fc = le16_to_cpu(hdr->frame_control);
return ((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
- (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
- is_multicast_ether_addr(hdr->addr1));
+ (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA);
}
@@ -245,7 +244,10 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
if (!sta || !mi || use_low_rate(skb)) {
ar[0].idx = rate_lowest_index(sband, sta);
- ar[0].count = mp->max_retry;
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ ar[0].count = 1;
+ else
+ ar[0].count = mp->max_retry;
return;
}
@@ -476,8 +478,8 @@ minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
return NULL;
for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
- sband = hw->wiphy->bands[hw->conf.channel->band];
- if (sband->n_bitrates > max_rates)
+ sband = hw->wiphy->bands[i];
+ if (sband && sband->n_bitrates > max_rates)
max_rates = sband->n_bitrates;
}
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index b16801cde06f..a0bef767ceb5 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -289,13 +289,15 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
info->control.rates[0].count =
txrc->hw->conf.short_frame_max_tx_count;
- /* Send management frames and broadcast/multicast data using lowest
- * rate. */
+ /* Send management frames and NO_ACK data using lowest rate. */
fc = le16_to_cpu(hdr->frame_control);
if (!sta || !spinfo ||
(fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
- is_multicast_ether_addr(hdr->addr1)) {
+ info->flags & IEEE80211_TX_CTL_NO_ACK) {
info->control.rates[0].idx = rate_lowest_index(sband, sta);
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ info->control.rates[0].count = 1;
+
return;
}
@@ -317,13 +319,44 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta)
{
struct rc_pid_sta_info *spinfo = priv_sta;
+ struct rc_pid_info *pinfo = priv;
+ struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
struct sta_info *si;
+ int i, j, tmp;
+ bool s;
/* TODO: This routine should consider using RSSI from previous packets
* as we need to have IEEE 802.1X auth succeed immediately after assoc..
* Until that method is implemented, we will use the lowest supported
* rate as a workaround. */
+ /* Sort the rates. This is optimized for the most common case (i.e.
+ * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
+ * mapping too. */
+ for (i = 0; i < sband->n_bitrates; i++) {
+ rinfo[i].index = i;
+ rinfo[i].rev_index = i;
+ if (RC_PID_FAST_START)
+ rinfo[i].diff = 0;
+ else
+ rinfo[i].diff = i * pinfo->norm_offset;
+ }
+ for (i = 1; i < sband->n_bitrates; i++) {
+ s = 0;
+ for (j = 0; j < sband->n_bitrates - i; j++)
+ if (unlikely(sband->bitrates[rinfo[j].index].bitrate >
+ sband->bitrates[rinfo[j + 1].index].bitrate)) {
+ tmp = rinfo[j].index;
+ rinfo[j].index = rinfo[j + 1].index;
+ rinfo[j + 1].index = tmp;
+ rinfo[rinfo[j].index].rev_index = j;
+ rinfo[rinfo[j + 1].index].rev_index = j + 1;
+ s = 1;
+ }
+ if (!s)
+ break;
+ }
+
spinfo->txrate_idx = rate_lowest_index(sband, sta);
/* HACK */
si = container_of(sta, struct sta_info, sta);
@@ -336,21 +369,22 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
struct rc_pid_info *pinfo;
struct rc_pid_rateinfo *rinfo;
struct ieee80211_supported_band *sband;
- int i, j, tmp;
- bool s;
+ int i, max_rates = 0;
#ifdef CONFIG_MAC80211_DEBUGFS
struct rc_pid_debugfs_entries *de;
#endif
- sband = hw->wiphy->bands[hw->conf.channel->band];
-
pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
if (!pinfo)
return NULL;
- /* We can safely assume that sband won't change unless we get
- * reinitialized. */
- rinfo = kmalloc(sizeof(*rinfo) * sband->n_bitrates, GFP_ATOMIC);
+ for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
+ sband = hw->wiphy->bands[i];
+ if (sband && sband->n_bitrates > max_rates)
+ max_rates = sband->n_bitrates;
+ }
+
+ rinfo = kmalloc(sizeof(*rinfo) * max_rates, GFP_ATOMIC);
if (!rinfo) {
kfree(pinfo);
return NULL;
@@ -368,33 +402,6 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
pinfo->rinfo = rinfo;
pinfo->oldrate = 0;
- /* Sort the rates. This is optimized for the most common case (i.e.
- * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
- * mapping too. */
- for (i = 0; i < sband->n_bitrates; i++) {
- rinfo[i].index = i;
- rinfo[i].rev_index = i;
- if (RC_PID_FAST_START)
- rinfo[i].diff = 0;
- else
- rinfo[i].diff = i * pinfo->norm_offset;
- }
- for (i = 1; i < sband->n_bitrates; i++) {
- s = 0;
- for (j = 0; j < sband->n_bitrates - i; j++)
- if (unlikely(sband->bitrates[rinfo[j].index].bitrate >
- sband->bitrates[rinfo[j + 1].index].bitrate)) {
- tmp = rinfo[j].index;
- rinfo[j].index = rinfo[j + 1].index;
- rinfo[j + 1].index = tmp;
- rinfo[rinfo[j].index].rev_index = j;
- rinfo[rinfo[j + 1].index].rev_index = j + 1;
- s = 1;
- }
- if (!s)
- break;
- }
-
#ifdef CONFIG_MAC80211_DEBUGFS
de = &pinfo->dentries;
de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9776f73c51ad..f962bd1b16e2 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -19,6 +19,7 @@
#include <net/ieee80211_radiotap.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "led.h"
#include "mesh.h"
#include "wep.h"
@@ -629,15 +630,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
* possible.
*/
- if (!ieee80211_has_protected(hdr->frame_control)) {
- if (!ieee80211_is_mgmt(hdr->frame_control) ||
- rx->sta == NULL || !test_sta_flags(rx->sta, WLAN_STA_MFP))
- return RX_CONTINUE;
- mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
- if (mmie_keyidx < 0)
- return RX_CONTINUE;
- }
-
/*
* No point in finding a key and decrypting if the frame is neither
* addressed to us nor a multicast frame.
@@ -648,8 +640,14 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
if (rx->sta)
stakey = rcu_dereference(rx->sta->key);
+ if (!ieee80211_has_protected(hdr->frame_control))
+ mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
+
if (!is_multicast_ether_addr(hdr->addr1) && stakey) {
rx->key = stakey;
+ /* Skip decryption if the frame is not protected. */
+ if (!ieee80211_has_protected(hdr->frame_control))
+ return RX_CONTINUE;
} else if (mmie_keyidx >= 0) {
/* Broadcast/multicast robust management frame / BIP */
if ((rx->status->flag & RX_FLAG_DECRYPTED) &&
@@ -660,6 +658,21 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
return RX_DROP_MONITOR; /* unexpected BIP keyidx */
rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
+ } else if (!ieee80211_has_protected(hdr->frame_control)) {
+ /*
+ * The frame was not protected, so skip decryption. However, we
+ * need to set rx->key if there is a key that could have been
+ * used so that the frame may be dropped if encryption would
+ * have been expected.
+ */
+ struct ieee80211_key *key = NULL;
+ if (ieee80211_is_mgmt(hdr->frame_control) &&
+ is_multicast_ether_addr(hdr->addr1) &&
+ (key = rcu_dereference(rx->sdata->default_mgmt_key)))
+ rx->key = key;
+ else if ((key = rcu_dereference(rx->sdata->default_key)))
+ rx->key = key;
+ return RX_CONTINUE;
} else {
/*
* The device doesn't give us the IV so we won't be
@@ -773,9 +786,7 @@ static void ap_sta_ps_start(struct sta_info *sta)
atomic_inc(&sdata->bss->num_sta_ps);
set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
- if (local->ops->sta_notify)
- local->ops->sta_notify(local_to_hw(local), &sdata->vif,
- STA_NOTIFY_SLEEP, &sta->sta);
+ drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta);
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
sdata->dev->name, sta->sta.addr, sta->sta.aid);
@@ -792,9 +803,7 @@ static int ap_sta_ps_end(struct sta_info *sta)
atomic_dec(&sdata->bss->num_sta_ps);
clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
- if (local->ops->sta_notify)
- local->ops->sta_notify(local_to_hw(local), &sdata->vif,
- STA_NOTIFY_AWAKE, &sta->sta);
+ drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta);
if (!skb_queue_empty(&sta->ps_tx_buf))
sta_info_clear_tim_bit(sta);
@@ -1212,17 +1221,27 @@ ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
/* Drop unencrypted frames if key is set. */
if (unlikely(!ieee80211_has_protected(fc) &&
!ieee80211_is_nullfunc(fc) &&
- (!ieee80211_is_mgmt(fc) ||
- (ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
- rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP))) &&
- (rx->key || rx->sdata->drop_unencrypted)))
- return -EACCES;
- /* BIP does not use Protected field, so need to check MMIE */
- if (unlikely(rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP) &&
- ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
- ieee80211_get_mmie_keyidx(rx->skb) < 0 &&
+ ieee80211_is_data(fc) &&
(rx->key || rx->sdata->drop_unencrypted)))
return -EACCES;
+ if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
+ if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
+ rx->key))
+ return -EACCES;
+ /* BIP does not use Protected field, so need to check MMIE */
+ if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb)
+ && ieee80211_get_mmie_keyidx(rx->skb) < 0 &&
+ rx->key))
+ return -EACCES;
+ /*
+ * When using MFP, Action frames are not allowed prior to
+ * having configured keys.
+ */
+ if (unlikely(ieee80211_is_action(fc) && !rx->key &&
+ ieee80211_is_robust_mgmt_frame(
+ (struct ieee80211_hdr *) rx->skb->data)))
+ return -EACCES;
+ }
return 0;
}
@@ -1932,7 +1951,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
!ieee80211_is_auth(hdr->frame_control))
goto ignore;
- mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr);
+ mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL);
ignore:
dev_kfree_skb(rx->skb);
rx->skb = NULL;
@@ -2287,6 +2306,43 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
}
+static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
+ struct tid_ampdu_rx *tid_agg_rx,
+ int index)
+{
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_rate *rate;
+ struct ieee80211_rx_status status;
+
+ if (!tid_agg_rx->reorder_buf[index])
+ goto no_frame;
+
+ /* release the reordered frames to stack */
+ memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, sizeof(status));
+ sband = hw->wiphy->bands[status.band];
+ if (status.flag & RX_FLAG_HT)
+ rate = sband->bitrates; /* TODO: HT rates */
+ else
+ rate = &sband->bitrates[status.rate_idx];
+ __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
+ &status, rate);
+ tid_agg_rx->stored_mpdu_num--;
+ tid_agg_rx->reorder_buf[index] = NULL;
+
+no_frame:
+ tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
+}
+
+
+/*
+ * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If
+ * the skb was added to the buffer longer than this time ago, the earlier
+ * frames that have not yet been received are assumed to be lost and the skb
+ * can be released for processing. This may also release other skb's from the
+ * reorder buffer if there are no additional gaps between the frames.
+ */
+#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
+
/*
* As it function blongs to Rx path it must be called with
* the proper rcu_read_lock protection for its flow.
@@ -2298,12 +2354,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
u16 mpdu_seq_num,
int bar_req)
{
- struct ieee80211_local *local = hw_to_local(hw);
- struct ieee80211_rx_status status;
u16 head_seq_num, buf_size;
int index;
- struct ieee80211_supported_band *sband;
- struct ieee80211_rate *rate;
buf_size = tid_agg_rx->buf_size;
head_seq_num = tid_agg_rx->head_seq_num;
@@ -2328,28 +2380,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
index = seq_sub(tid_agg_rx->head_seq_num,
tid_agg_rx->ssn)
% tid_agg_rx->buf_size;
-
- if (tid_agg_rx->reorder_buf[index]) {
- /* release the reordered frames to stack */
- memcpy(&status,
- tid_agg_rx->reorder_buf[index]->cb,
- sizeof(status));
- sband = local->hw.wiphy->bands[status.band];
- if (status.flag & RX_FLAG_HT) {
- /* TODO: HT rates */
- rate = sband->bitrates;
- } else {
- rate = &sband->bitrates
- [status.rate_idx];
- }
- __ieee80211_rx_handle_packet(hw,
- tid_agg_rx->reorder_buf[index],
- &status, rate);
- tid_agg_rx->stored_mpdu_num--;
- tid_agg_rx->reorder_buf[index] = NULL;
- }
- tid_agg_rx->head_seq_num =
- seq_inc(tid_agg_rx->head_seq_num);
+ ieee80211_release_reorder_frame(hw, tid_agg_rx,
+ index);
}
if (bar_req)
return 1;
@@ -2376,26 +2408,50 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
/* put the frame in the reordering buffer */
tid_agg_rx->reorder_buf[index] = skb;
+ tid_agg_rx->reorder_time[index] = jiffies;
memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus,
sizeof(*rxstatus));
tid_agg_rx->stored_mpdu_num++;
/* release the buffer until next missing frame */
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn)
% tid_agg_rx->buf_size;
- while (tid_agg_rx->reorder_buf[index]) {
- /* release the reordered frame back to stack */
- memcpy(&status, tid_agg_rx->reorder_buf[index]->cb,
- sizeof(status));
- sband = local->hw.wiphy->bands[status.band];
- if (status.flag & RX_FLAG_HT)
- rate = sband->bitrates; /* TODO: HT rates */
- else
- rate = &sband->bitrates[status.rate_idx];
- __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
- &status, rate);
- tid_agg_rx->stored_mpdu_num--;
- tid_agg_rx->reorder_buf[index] = NULL;
- tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
+ if (!tid_agg_rx->reorder_buf[index] &&
+ tid_agg_rx->stored_mpdu_num > 1) {
+ /*
+ * No buffers ready to be released, but check whether any
+ * frames in the reorder buffer have timed out.
+ */
+ int j;
+ int skipped = 1;
+ for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
+ j = (j + 1) % tid_agg_rx->buf_size) {
+ if (tid_agg_rx->reorder_buf[j] == NULL) {
+ skipped++;
+ continue;
+ }
+ if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
+ HZ / 10))
+ break;
+
+#ifdef CONFIG_MAC80211_HT_DEBUG
+ if (net_ratelimit())
+ printk(KERN_DEBUG "%s: release an RX reorder "
+ "frame due to timeout on earlier "
+ "frames\n",
+ wiphy_name(hw->wiphy));
+#endif
+ ieee80211_release_reorder_frame(hw, tid_agg_rx, j);
+
+ /*
+ * Increment the head seq# also for the skipped slots.
+ */
+ tid_agg_rx->head_seq_num =
+ (tid_agg_rx->head_seq_num + skipped) &
+ SEQ_MASK;
+ skipped = 0;
+ }
+ } else while (tid_agg_rx->reorder_buf[index]) {
+ ieee80211_release_reorder_frame(hw, tid_agg_rx, index);
index = seq_sub(tid_agg_rx->head_seq_num,
tid_agg_rx->ssn) % tid_agg_rx->buf_size;
}
@@ -2517,6 +2573,18 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
return;
}
+ /*
+ * In theory, the block ack reordering should happen after duplicate
+ * removal (ieee80211_rx_h_check(), which is an RX handler). As such,
+ * the call to ieee80211_rx_reorder_ampdu() should really be moved to
+ * happen as a new RX handler between ieee80211_rx_h_check and
+ * ieee80211_rx_h_decrypt. This cleanup may eventually happen, but for
+ * the time being, the call can be here since RX reorder buf processing
+ * will implicitly skip duplicates. We could, in theory at least,
+ * process frames that ieee80211_rx_h_passive_scan would drop (e.g.,
+ * frames from other than operational channel), but that should not
+ * happen in normal networks.
+ */
if (!ieee80211_rx_reorder_ampdu(local, skb, status))
__ieee80211_rx_handle_packet(hw, skb, status, rate);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 3bf9839f5916..e65d74ba404b 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -21,6 +21,7 @@
#include <net/iw_handler.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "mesh.h"
#define IEEE80211_PROBE_DELAY (HZ / 33)
@@ -202,18 +203,6 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
return RX_QUEUED;
}
-void ieee80211_scan_failed(struct ieee80211_local *local)
-{
- if (WARN_ON(!local->scan_req))
- return;
-
- /* notify cfg80211 about the failed scan */
- if (local->scan_req != &local->int_scan_req)
- cfg80211_scan_done(local->scan_req, true);
-
- local->scan_req = NULL;
-}
-
/*
* inform AP that we will go to sleep so that it will buffer the frames
* while we scan
@@ -253,7 +242,7 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
- if (!local->powersave)
+ if (!local->ps_sdata)
ieee80211_send_nullfunc(local, sdata, 0);
else {
/*
@@ -274,51 +263,62 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
}
}
+static void ieee80211_restore_scan_ies(struct ieee80211_local *local)
+{
+ kfree(local->scan_req->ie);
+ local->scan_req->ie = local->orig_ies;
+ local->scan_req->ie_len = local->orig_ies_len;
+}
+
void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_sub_if_data *sdata;
+ bool was_hw_scan;
- if (WARN_ON(!local->hw_scanning && !local->sw_scanning))
+ mutex_lock(&local->scan_mtx);
+
+ if (WARN_ON(!local->hw_scanning && !local->sw_scanning)) {
+ mutex_unlock(&local->scan_mtx);
return;
+ }
- if (WARN_ON(!local->scan_req))
+ if (WARN_ON(!local->scan_req)) {
+ mutex_unlock(&local->scan_mtx);
return;
+ }
+
+ if (local->hw_scanning)
+ ieee80211_restore_scan_ies(local);
if (local->scan_req != &local->int_scan_req)
cfg80211_scan_done(local->scan_req, aborted);
local->scan_req = NULL;
- local->last_scan_completed = jiffies;
+ was_hw_scan = local->hw_scanning;
+ local->hw_scanning = false;
+ local->sw_scanning = false;
+ local->scan_channel = NULL;
- if (local->hw_scanning) {
- local->hw_scanning = false;
- /*
- * Somebody might have requested channel change during scan
- * that we won't have acted upon, try now. ieee80211_hw_config
- * will set the flag based on actual changes.
- */
- ieee80211_hw_config(local, 0);
- goto done;
- }
+ /* we only have to protect scan_req and hw/sw scan */
+ mutex_unlock(&local->scan_mtx);
- local->sw_scanning = false;
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
+ if (was_hw_scan)
+ goto done;
netif_tx_lock_bh(local->mdev);
netif_addr_lock(local->mdev);
local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
- local->ops->configure_filter(local_to_hw(local),
- FIF_BCN_PRBRESP_PROMISC,
- &local->filter_flags,
- local->mdev->mc_count,
- local->mdev->mc_list);
+ drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
+ &local->filter_flags,
+ local->mdev->mc_count,
+ local->mdev->mc_list);
netif_addr_unlock(local->mdev);
netif_tx_unlock_bh(local->mdev);
- if (local->ops->sw_scan_complete)
- local->ops->sw_scan_complete(local_to_hw(local));
+ drv_sw_scan_complete(local);
mutex_lock(&local->iflist_mtx);
list_for_each_entry(sdata, &local->interfaces, list) {
@@ -338,18 +338,160 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
if (sdata->vif.type == NL80211_IFTYPE_AP ||
sdata->vif.type == NL80211_IFTYPE_ADHOC ||
sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
- ieee80211_if_config(sdata,
- IEEE80211_IFCC_BEACON_ENABLED);
+ ieee80211_bss_info_change_notify(
+ sdata, BSS_CHANGED_BEACON_ENABLED);
}
mutex_unlock(&local->iflist_mtx);
done:
+ ieee80211_recalc_idle(local);
ieee80211_mlme_notify_scan_completed(local);
ieee80211_ibss_notify_scan_completed(local);
ieee80211_mesh_notify_scan_completed(local);
}
EXPORT_SYMBOL(ieee80211_scan_completed);
+static int ieee80211_start_sw_scan(struct ieee80211_local *local)
+{
+ struct ieee80211_sub_if_data *sdata;
+
+ /*
+ * Hardware/driver doesn't support hw_scan, so use software
+ * scanning instead. First send a nullfunc frame with power save
+ * bit on so that AP will buffer the frames for us while we are not
+ * listening, then send probe requests to each channel and wait for
+ * the responses. After all channels are scanned, tune back to the
+ * original channel and send a nullfunc frame with power save bit
+ * off to trigger the AP to send us all the buffered frames.
+ *
+ * Note that while local->sw_scanning is true everything else but
+ * nullfunc frames and probe requests will be dropped in
+ * ieee80211_tx_h_check_assoc().
+ */
+ drv_sw_scan_start(local);
+
+ mutex_lock(&local->iflist_mtx);
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (!netif_running(sdata->dev))
+ continue;
+
+ /* disable beaconing */
+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
+ sdata->vif.type == NL80211_IFTYPE_ADHOC ||
+ sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
+ ieee80211_bss_info_change_notify(
+ sdata, BSS_CHANGED_BEACON_ENABLED);
+
+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+ if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
+ netif_tx_stop_all_queues(sdata->dev);
+ ieee80211_scan_ps_enable(sdata);
+ }
+ } else
+ netif_tx_stop_all_queues(sdata->dev);
+ }
+ mutex_unlock(&local->iflist_mtx);
+
+ local->scan_state = SCAN_SET_CHANNEL;
+ local->scan_channel_idx = 0;
+
+ netif_addr_lock_bh(local->mdev);
+ local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
+ drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
+ &local->filter_flags,
+ local->mdev->mc_count,
+ local->mdev->mc_list);
+ netif_addr_unlock_bh(local->mdev);
+
+ /* TODO: start scan as soon as all nullfunc frames are ACKed */
+ queue_delayed_work(local->hw.workqueue, &local->scan_work,
+ IEEE80211_CHANNEL_TIME);
+
+ return 0;
+}
+
+
+static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_scan_request *req)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ int rc;
+
+ if (local->scan_req)
+ return -EBUSY;
+
+ if (local->ops->hw_scan) {
+ u8 *ies;
+ int ielen;
+
+ ies = kmalloc(2 + IEEE80211_MAX_SSID_LEN +
+ local->scan_ies_len + req->ie_len, GFP_KERNEL);
+ if (!ies)
+ return -ENOMEM;
+
+ ielen = ieee80211_build_preq_ies(local, ies,
+ req->ie, req->ie_len);
+ local->orig_ies = req->ie;
+ local->orig_ies_len = req->ie_len;
+ req->ie = ies;
+ req->ie_len = ielen;
+ }
+
+ local->scan_req = req;
+ local->scan_sdata = sdata;
+
+ if (req != &local->int_scan_req &&
+ sdata->vif.type == NL80211_IFTYPE_STATION &&
+ (ifmgd->state == IEEE80211_STA_MLME_DIRECT_PROBE ||
+ ifmgd->state == IEEE80211_STA_MLME_AUTHENTICATE ||
+ ifmgd->state == IEEE80211_STA_MLME_ASSOCIATE)) {
+ /* actually wait for the assoc to finish/time out */
+ set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
+ return 0;
+ }
+
+ if (local->ops->hw_scan)
+ local->hw_scanning = true;
+ else
+ local->sw_scanning = true;
+ /*
+ * Kicking off the scan need not be protected,
+ * only the scan variable stuff, since now
+ * local->scan_req is assigned and other callers
+ * will abort their scan attempts.
+ *
+ * This avoids getting a scan_mtx -> iflist_mtx
+ * dependency, so that the scan completed calls
+ * have more locking freedom.
+ */
+
+ ieee80211_recalc_idle(local);
+ mutex_unlock(&local->scan_mtx);
+
+ if (local->ops->hw_scan)
+ rc = drv_hw_scan(local, local->scan_req);
+ else
+ rc = ieee80211_start_sw_scan(local);
+
+ mutex_lock(&local->scan_mtx);
+
+ if (rc) {
+ if (local->ops->hw_scan) {
+ local->hw_scanning = false;
+ ieee80211_restore_scan_ies(local);
+ } else
+ local->sw_scanning = false;
+
+ ieee80211_recalc_idle(local);
+
+ local->scan_req = NULL;
+ local->scan_sdata = NULL;
+ }
+
+ return rc;
+}
+
void ieee80211_scan_work(struct work_struct *work)
{
struct ieee80211_local *local =
@@ -359,17 +501,41 @@ void ieee80211_scan_work(struct work_struct *work)
int skip, i;
unsigned long next_delay = 0;
+ mutex_lock(&local->scan_mtx);
+ if (!sdata || !local->scan_req) {
+ mutex_unlock(&local->scan_mtx);
+ return;
+ }
+
+ if (local->scan_req && !(local->sw_scanning || local->hw_scanning)) {
+ struct cfg80211_scan_request *req = local->scan_req;
+ int rc;
+
+ local->scan_req = NULL;
+
+ rc = __ieee80211_start_scan(sdata, req);
+ mutex_unlock(&local->scan_mtx);
+
+ if (rc)
+ ieee80211_scan_completed(&local->hw, true);
+ return;
+ }
+
+ mutex_unlock(&local->scan_mtx);
+
/*
* Avoid re-scheduling when the sdata is going away.
*/
- if (!netif_running(sdata->dev))
+ if (!netif_running(sdata->dev)) {
+ ieee80211_scan_completed(&local->hw, true);
return;
+ }
switch (local->scan_state) {
case SCAN_SET_CHANNEL:
/* if no more bands/channels left, complete scan */
if (local->scan_channel_idx >= local->scan_req->n_channels) {
- ieee80211_scan_completed(local_to_hw(local), false);
+ ieee80211_scan_completed(&local->hw, false);
return;
}
skip = 0;
@@ -393,24 +559,39 @@ void ieee80211_scan_work(struct work_struct *work)
if (skip)
break;
- next_delay = IEEE80211_PROBE_DELAY +
- usecs_to_jiffies(local->hw.channel_change_time);
+ /*
+ * Probe delay is used to update the NAV, cf. 11.1.3.2.2
+ * (which unfortunately doesn't say _why_ step a) is done,
+ * but it waits for the probe delay or until a frame is
+ * received - and the received frame would update the NAV).
+ * For now, we do not support waiting until a frame is
+ * received.
+ *
+ * In any case, it is not necessary for a passive scan.
+ */
+ if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
+ !local->scan_req->n_ssids) {
+ next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
+ break;
+ }
+
+ next_delay = IEEE80211_PROBE_DELAY;
local->scan_state = SCAN_SEND_PROBE;
break;
case SCAN_SEND_PROBE:
- next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
- local->scan_state = SCAN_SET_CHANNEL;
-
- if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
- !local->scan_req->n_ssids)
- break;
for (i = 0; i < local->scan_req->n_ssids; i++)
ieee80211_send_probe_req(
sdata, NULL,
local->scan_req->ssids[i].ssid,
local->scan_req->ssids[i].ssid_len,
local->scan_req->ie, local->scan_req->ie_len);
+
+ /*
+ * After sending probe requests, wait for probe responses
+ * on the channel.
+ */
next_delay = IEEE80211_CHANNEL_TIME;
+ local->scan_state = SCAN_SET_CHANNEL;
break;
}
@@ -418,150 +599,35 @@ void ieee80211_scan_work(struct work_struct *work)
next_delay);
}
-
-int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
- struct cfg80211_scan_request *req)
+int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_scan_request *req)
{
- struct ieee80211_local *local = scan_sdata->local;
- struct ieee80211_sub_if_data *sdata;
-
- if (!req)
- return -EINVAL;
+ int res;
- if (local->scan_req && local->scan_req != req)
- return -EBUSY;
-
- local->scan_req = req;
-
- /* MLME-SCAN.request (page 118) page 144 (11.1.3.1)
- * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
- * BSSID: MACAddress
- * SSID
- * ScanType: ACTIVE, PASSIVE
- * ProbeDelay: delay (in microseconds) to be used prior to transmitting
- * a Probe frame during active scanning
- * ChannelList
- * MinChannelTime (>= ProbeDelay), in TU
- * MaxChannelTime: (>= MinChannelTime), in TU
- */
-
- /* MLME-SCAN.confirm
- * BSSDescriptionSet
- * ResultCode: SUCCESS, INVALID_PARAMETERS
- */
+ mutex_lock(&sdata->local->scan_mtx);
+ res = __ieee80211_start_scan(sdata, req);
+ mutex_unlock(&sdata->local->scan_mtx);
- if (local->sw_scanning || local->hw_scanning) {
- if (local->scan_sdata == scan_sdata)
- return 0;
- return -EBUSY;
- }
-
- if (local->ops->hw_scan) {
- int rc;
-
- local->hw_scanning = true;
- rc = local->ops->hw_scan(local_to_hw(local), req);
- if (rc) {
- local->hw_scanning = false;
- return rc;
- }
- local->scan_sdata = scan_sdata;
- return 0;
- }
-
- /*
- * Hardware/driver doesn't support hw_scan, so use software
- * scanning instead. First send a nullfunc frame with power save
- * bit on so that AP will buffer the frames for us while we are not
- * listening, then send probe requests to each channel and wait for
- * the responses. After all channels are scanned, tune back to the
- * original channel and send a nullfunc frame with power save bit
- * off to trigger the AP to send us all the buffered frames.
- *
- * Note that while local->sw_scanning is true everything else but
- * nullfunc frames and probe requests will be dropped in
- * ieee80211_tx_h_check_assoc().
- */
- local->sw_scanning = true;
- if (local->ops->sw_scan_start)
- local->ops->sw_scan_start(local_to_hw(local));
-
- mutex_lock(&local->iflist_mtx);
- list_for_each_entry(sdata, &local->interfaces, list) {
- if (!netif_running(sdata->dev))
- continue;
-
- /* disable beaconing */
- if (sdata->vif.type == NL80211_IFTYPE_AP ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC ||
- sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
- ieee80211_if_config(sdata,
- IEEE80211_IFCC_BEACON_ENABLED);
-
- if (sdata->vif.type == NL80211_IFTYPE_STATION) {
- if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
- netif_tx_stop_all_queues(sdata->dev);
- ieee80211_scan_ps_enable(sdata);
- }
- } else
- netif_tx_stop_all_queues(sdata->dev);
- }
- mutex_unlock(&local->iflist_mtx);
-
- local->scan_state = SCAN_SET_CHANNEL;
- local->scan_channel_idx = 0;
- local->scan_sdata = scan_sdata;
- local->scan_req = req;
-
- netif_addr_lock_bh(local->mdev);
- local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
- local->ops->configure_filter(local_to_hw(local),
- FIF_BCN_PRBRESP_PROMISC,
- &local->filter_flags,
- local->mdev->mc_count,
- local->mdev->mc_list);
- netif_addr_unlock_bh(local->mdev);
-
- /* TODO: start scan as soon as all nullfunc frames are ACKed */
- queue_delayed_work(local->hw.workqueue, &local->scan_work,
- IEEE80211_CHANNEL_TIME);
-
- return 0;
+ return res;
}
-
-int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
- struct cfg80211_scan_request *req)
+int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
+ const u8 *ssid, u8 ssid_len)
{
struct ieee80211_local *local = sdata->local;
- struct ieee80211_if_managed *ifmgd;
+ int ret = -EBUSY;
- if (!req)
- return -EINVAL;
+ mutex_lock(&local->scan_mtx);
- if (local->scan_req && local->scan_req != req)
- return -EBUSY;
+ /* busy scanning */
+ if (local->scan_req)
+ goto unlock;
- local->scan_req = req;
+ memcpy(local->int_scan_req.ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
+ local->int_scan_req.ssids[0].ssid_len = ssid_len;
- if (sdata->vif.type != NL80211_IFTYPE_STATION)
- return ieee80211_start_scan(sdata, req);
-
- /*
- * STA has a state machine that might need to defer scanning
- * while it's trying to associate/authenticate, therefore we
- * queue it up to the state machine in that case.
- */
-
- if (local->sw_scanning || local->hw_scanning) {
- if (local->scan_sdata == sdata)
- return 0;
- return -EBUSY;
- }
-
- ifmgd = &sdata->u.mgd;
- set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
- queue_work(local->hw.workqueue, &ifmgd->work);
-
- return 0;
+ ret = __ieee80211_start_scan(sdata, &sdata->local->int_scan_req);
+ unlock:
+ mutex_unlock(&local->scan_mtx);
+ return ret;
}
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 5f7a2624ed74..48bf78e7fa7a 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -15,7 +15,7 @@
*/
#include <linux/ieee80211.h>
-#include <net/wireless.h>
+#include <net/cfg80211.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
#include "sta_info.h"
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index c5f14e6bbde2..a98ea273a155 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -19,6 +19,7 @@
#include <net/mac80211.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "rate.h"
#include "sta_info.h"
#include "debugfs_sta.h"
@@ -346,8 +347,7 @@ int sta_info_insert(struct sta_info *sta)
struct ieee80211_sub_if_data,
u.ap);
- local->ops->sta_notify(local_to_hw(local), &sdata->vif,
- STA_NOTIFY_ADD, &sta->sta);
+ drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta);
}
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -405,8 +405,7 @@ static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss,
if (sta->local->ops->set_tim) {
sta->local->tim_in_locked_section = true;
- sta->local->ops->set_tim(local_to_hw(sta->local),
- &sta->sta, true);
+ drv_set_tim(sta->local, &sta->sta, true);
sta->local->tim_in_locked_section = false;
}
}
@@ -431,8 +430,7 @@ static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss,
if (sta->local->ops->set_tim) {
sta->local->tim_in_locked_section = true;
- sta->local->ops->set_tim(local_to_hw(sta->local),
- &sta->sta, false);
+ drv_set_tim(sta->local, &sta->sta, false);
sta->local->tim_in_locked_section = false;
}
}
@@ -482,8 +480,8 @@ static void __sta_info_unlink(struct sta_info **sta)
struct ieee80211_sub_if_data,
u.ap);
- local->ops->sta_notify(local_to_hw(local), &sdata->vif,
- STA_NOTIFY_REMOVE, &(*sta)->sta);
+ drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
+ &(*sta)->sta);
}
if (ieee80211_vif_is_mesh(&sdata->vif)) {
@@ -543,9 +541,8 @@ void sta_info_unlink(struct sta_info **sta)
spin_unlock_irqrestore(&local->sta_lock, flags);
}
-static inline int sta_info_buffer_expired(struct ieee80211_local *local,
- struct sta_info *sta,
- struct sk_buff *skb)
+static int sta_info_buffer_expired(struct sta_info *sta,
+ struct sk_buff *skb)
{
struct ieee80211_tx_info *info;
int timeout;
@@ -556,8 +553,9 @@ static inline int sta_info_buffer_expired(struct ieee80211_local *local,
info = IEEE80211_SKB_CB(skb);
/* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */
- timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 /
- 15625) * HZ;
+ timeout = (sta->listen_interval *
+ sta->sdata->vif.bss_conf.beacon_int *
+ 32 / 15625) * HZ;
if (timeout < STA_TX_BUFFER_EXPIRE)
timeout = STA_TX_BUFFER_EXPIRE;
return time_after(jiffies, info->control.jiffies + timeout);
@@ -577,7 +575,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
for (;;) {
spin_lock_irqsave(&sta->ps_tx_buf.lock, flags);
skb = skb_peek(&sta->ps_tx_buf);
- if (sta_info_buffer_expired(local, sta, skb))
+ if (sta_info_buffer_expired(sta, skb))
skb = __skb_dequeue(&sta->ps_tx_buf);
else
skb = NULL;
@@ -686,41 +684,10 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
}
#endif
-static void __ieee80211_run_pending_flush(struct ieee80211_local *local)
-{
- struct sta_info *sta;
- unsigned long flags;
-
- ASSERT_RTNL();
-
- spin_lock_irqsave(&local->sta_lock, flags);
- while (!list_empty(&local->sta_flush_list)) {
- sta = list_first_entry(&local->sta_flush_list,
- struct sta_info, list);
- list_del(&sta->list);
- spin_unlock_irqrestore(&local->sta_lock, flags);
- sta_info_destroy(sta);
- spin_lock_irqsave(&local->sta_lock, flags);
- }
- spin_unlock_irqrestore(&local->sta_lock, flags);
-}
-
-static void ieee80211_sta_flush_work(struct work_struct *work)
-{
- struct ieee80211_local *local =
- container_of(work, struct ieee80211_local, sta_flush_work);
-
- rtnl_lock();
- __ieee80211_run_pending_flush(local);
- rtnl_unlock();
-}
-
void sta_info_init(struct ieee80211_local *local)
{
spin_lock_init(&local->sta_lock);
INIT_LIST_HEAD(&local->sta_list);
- INIT_LIST_HEAD(&local->sta_flush_list);
- INIT_WORK(&local->sta_flush_work, ieee80211_sta_flush_work);
setup_timer(&local->sta_cleanup, sta_info_cleanup,
(unsigned long)local);
@@ -741,7 +708,6 @@ int sta_info_start(struct ieee80211_local *local)
void sta_info_stop(struct ieee80211_local *local)
{
del_timer(&local->sta_cleanup);
- cancel_work_sync(&local->sta_flush_work);
#ifdef CONFIG_MAC80211_DEBUGFS
/*
* Make sure the debugfs adding work isn't pending after this
@@ -752,10 +718,7 @@ void sta_info_stop(struct ieee80211_local *local)
cancel_work_sync(&local->sta_debugfs_add);
#endif
- rtnl_lock();
sta_info_flush(local, NULL);
- __ieee80211_run_pending_flush(local);
- rtnl_unlock();
}
/**
@@ -767,7 +730,7 @@ void sta_info_stop(struct ieee80211_local *local)
* @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs
*/
int sta_info_flush(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata)
+ struct ieee80211_sub_if_data *sdata)
{
struct sta_info *sta, *tmp;
LIST_HEAD(tmp_list);
@@ -775,7 +738,6 @@ int sta_info_flush(struct ieee80211_local *local,
unsigned long flags;
might_sleep();
- ASSERT_RTNL();
spin_lock_irqsave(&local->sta_lock, flags);
list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
@@ -795,39 +757,6 @@ int sta_info_flush(struct ieee80211_local *local,
return ret;
}
-/**
- * sta_info_flush_delayed - flush matching STA entries from the STA table
- *
- * This function unlinks all stations for a given interface and queues
- * them for freeing. Note that the workqueue function scheduled here has
- * to run before any new keys can be added to the system to avoid set_key()
- * callback ordering issues.
- *
- * @sdata: the interface
- */
-void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata)
-{
- struct ieee80211_local *local = sdata->local;
- struct sta_info *sta, *tmp;
- unsigned long flags;
- bool work = false;
-
- spin_lock_irqsave(&local->sta_lock, flags);
- list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
- if (sdata == sta->sdata) {
- __sta_info_unlink(&sta);
- if (sta) {
- list_add_tail(&sta->list,
- &local->sta_flush_list);
- work = true;
- }
- }
- }
- if (work)
- schedule_work(&local->sta_flush_work);
- spin_unlock_irqrestore(&local->sta_lock, flags);
-}
-
void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
unsigned long exp_time)
{
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 5534d489f506..164b16cbe0a5 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -88,6 +88,7 @@ struct tid_ampdu_tx {
* struct tid_ampdu_rx - TID aggregation information (Rx).
*
* @reorder_buf: buffer to reorder incoming aggregated MPDUs
+ * @reorder_time: jiffies when skb was added
* @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
* @head_seq_num: head sequence number in reordering buffer.
* @stored_mpdu_num: number of MPDUs in reordering buffer
@@ -99,6 +100,7 @@ struct tid_ampdu_tx {
*/
struct tid_ampdu_rx {
struct sk_buff **reorder_buf;
+ unsigned long *reorder_time;
struct timer_list session_timer;
u16 head_seq_num;
u16 stored_mpdu_num;
@@ -442,8 +444,7 @@ void sta_info_init(struct ieee80211_local *local);
int sta_info_start(struct ieee80211_local *local);
void sta_info_stop(struct ieee80211_local *local);
int sta_info_flush(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata);
-void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata);
+ struct ieee80211_sub_if_data *sdata);
void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
unsigned long exp_time);
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 38fa111d2dc6..964b7faa7f17 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -13,6 +13,7 @@
#include <asm/unaligned.h>
#include <net/mac80211.h>
+#include "driver-ops.h"
#include "key.h"
#include "tkip.h"
#include "wep.h"
@@ -307,9 +308,8 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
if (is_multicast_ether_addr(ra))
sta_addr = bcast;
- key->local->ops->update_tkip_key(
- local_to_hw(key->local), &key->conf,
- sta_addr, iv32, key->u.tkip.rx[queue].p1k);
+ drv_update_tkip_key(key->local, &key->conf, sta_addr,
+ iv32, key->u.tkip.rx[queue].p1k);
}
}
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3fb04a86444d..8f68bf9746d0 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -25,6 +25,7 @@
#include <asm/unaligned.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "led.h"
#include "mesh.h"
#include "wep.h"
@@ -409,8 +410,24 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
sta->sta.addr);
}
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
- clear_sta_flags(sta, WLAN_STA_PSPOLL);
+ if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) {
+ /*
+ * The sleeping station with pending data is now snoozing.
+ * It queried us for its buffered frames and will go back
+ * to deep sleep once it got everything.
+ *
+ * inform the driver, in case the hardware does powersave
+ * frame filtering and keeps a station blacklist on its own
+ * (e.g: p54), so that frames can be delivered unimpeded.
+ *
+ * Note: It should be save to disable the filter now.
+ * As, it is really unlikely that we still have any pending
+ * frame for this station in the hw's buffers/fifos left,
+ * that is not rejected with a unsuccessful tx_status yet.
+ */
+ info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+ }
return TX_CONTINUE;
}
@@ -429,7 +446,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx)
static ieee80211_tx_result debug_noinline
ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
{
- struct ieee80211_key *key;
+ struct ieee80211_key *key = NULL;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
@@ -500,7 +517,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
sband = tx->local->hw.wiphy->bands[tx->channel->band];
len = min_t(int, tx->skb->len + FCS_LEN,
- tx->local->fragmentation_threshold);
+ tx->local->hw.wiphy->frag_threshold);
/* set up the tx rate control struct we give the RC algo */
txrc.hw = local_to_hw(tx->local);
@@ -511,8 +528,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx;
/* set up RTS protection if desired */
- if (tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD &&
- len > tx->local->rts_threshold) {
+ if (len > tx->local->hw.wiphy->rts_threshold) {
txrc.rts = rts = true;
}
@@ -542,6 +558,10 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
if (unlikely(!info->control.rates[0].count))
info->control.rates[0].count = 1;
+ if (WARN_ON_ONCE((info->control.rates[0].count > 1) &&
+ (info->flags & IEEE80211_TX_CTL_NO_ACK)))
+ info->control.rates[0].count = 1;
+
if (is_multicast_ether_addr(hdr->addr1)) {
/*
* XXX: verify the rate is in the basic rateset
@@ -754,7 +774,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
struct sk_buff *skb = tx->skb;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (void *)skb->data;
- int frag_threshold = tx->local->fragmentation_threshold;
+ int frag_threshold = tx->local->hw.wiphy->frag_threshold;
int hdrlen;
int fragnum;
@@ -772,7 +792,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
hdrlen = ieee80211_hdrlen(hdr->frame_control);
/* internal error, why is TX_FRAGMENTED set? */
- if (WARN_ON(skb->len <= frag_threshold))
+ if (WARN_ON(skb->len + FCS_LEN <= frag_threshold))
return TX_DROP;
/*
@@ -1067,12 +1087,15 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
info->flags |= IEEE80211_TX_CTL_NO_ACK;
} else {
tx->flags |= IEEE80211_TX_UNICAST;
- info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
+ if (unlikely(local->wifi_wme_noack_test))
+ info->flags |= IEEE80211_TX_CTL_NO_ACK;
+ else
+ info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
}
if (tx->flags & IEEE80211_TX_FRAGMENTED) {
if ((tx->flags & IEEE80211_TX_UNICAST) &&
- skb->len + FCS_LEN > local->fragmentation_threshold &&
+ skb->len + FCS_LEN > local->hw.wiphy->frag_threshold &&
!(info->flags & IEEE80211_TX_CTL_AMPDU))
tx->flags |= IEEE80211_TX_FRAGMENTED;
else
@@ -1147,7 +1170,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
next = skb->next;
len = skb->len;
- ret = local->ops->tx(local_to_hw(local), skb);
+ ret = drv_tx(local, skb);
if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
dev_kfree_skb(skb);
ret = NETDEV_TX_OK;
@@ -2086,18 +2109,18 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_hdr *hdr;
+ struct sk_buff *presp = rcu_dereference(ifibss->presp);
- if (!ifibss->probe_resp)
+ if (!presp)
goto out;
- skb = skb_copy(ifibss->probe_resp, GFP_ATOMIC);
+ skb = skb_copy(presp, GFP_ATOMIC);
if (!skb)
goto out;
hdr = (struct ieee80211_hdr *) skb->data;
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_BEACON);
-
} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
struct ieee80211_mgmt *mgmt;
u8 *pos;
@@ -2117,7 +2140,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
/* BSSID is left zeroed, wildcard value */
mgmt->u.beacon.beacon_int =
- cpu_to_le16(local->hw.conf.beacon_int);
+ cpu_to_le16(sdata->vif.bss_conf.beacon_int);
mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */
pos = skb_put(skb, 2);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index fdf432f14554..0689a8fbd1e6 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -20,14 +20,17 @@
#include <linux/if_arp.h>
#include <linux/wireless.h>
#include <linux/bitmap.h>
+#include <linux/crc32.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
#include <net/rtnetlink.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "rate.h"
#include "mesh.h"
#include "wme.h"
+#include "led.h"
/* privid for wiphys to determine whether they belong to us or not */
void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
@@ -536,8 +539,16 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
void ieee802_11_parse_elems(u8 *start, size_t len,
struct ieee802_11_elems *elems)
{
+ ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
+}
+
+u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
+ struct ieee802_11_elems *elems,
+ u64 filter, u32 crc)
+{
size_t left = len;
u8 *pos = start;
+ bool calc_crc = filter != 0;
memset(elems, 0, sizeof(*elems));
elems->ie_start = start;
@@ -551,7 +562,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
left -= 2;
if (elen > left)
- return;
+ break;
+
+ if (calc_crc && id < 64 && (filter & BIT(id)))
+ crc = crc32_be(crc, pos - 2, elen + 2);
switch (id) {
case WLAN_EID_SSID:
@@ -575,8 +589,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
elems->cf_params_len = elen;
break;
case WLAN_EID_TIM:
- elems->tim = pos;
- elems->tim_len = elen;
+ if (elen >= sizeof(struct ieee80211_tim_ie)) {
+ elems->tim = (void *)pos;
+ elems->tim_len = elen;
+ }
break;
case WLAN_EID_IBSS_PARAMS:
elems->ibss_params = pos;
@@ -586,15 +602,20 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
elems->challenge = pos;
elems->challenge_len = elen;
break;
- case WLAN_EID_WPA:
+ case WLAN_EID_VENDOR_SPECIFIC:
if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
pos[2] == 0xf2) {
/* Microsoft OUI (00:50:F2) */
+
+ if (calc_crc)
+ crc = crc32_be(crc, pos - 2, elen + 2);
+
if (pos[3] == 1) {
/* OUI Type 1 - WPA IE */
elems->wpa = pos;
elems->wpa_len = elen;
} else if (elen >= 5 && pos[3] == 2) {
+ /* OUI Type 2 - WMM IE */
if (pos[4] == 0) {
elems->wmm_info = pos;
elems->wmm_info_len = elen;
@@ -679,32 +700,70 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
left -= elen;
pos += elen;
}
+
+ return crc;
}
void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_tx_queue_params qparam;
- int i;
+ int queue;
+ bool use_11b;
+ int aCWmin, aCWmax;
if (!local->ops->conf_tx)
return;
memset(&qparam, 0, sizeof(qparam));
- qparam.aifs = 2;
-
- if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
- !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE))
- qparam.cw_min = 31;
- else
- qparam.cw_min = 15;
+ use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) &&
+ !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
- qparam.cw_max = 1023;
- qparam.txop = 0;
+ for (queue = 0; queue < local_to_hw(local)->queues; queue++) {
+ /* Set defaults according to 802.11-2007 Table 7-37 */
+ aCWmax = 1023;
+ if (use_11b)
+ aCWmin = 31;
+ else
+ aCWmin = 15;
+
+ switch (queue) {
+ case 3: /* AC_BK */
+ qparam.cw_max = aCWmin;
+ qparam.cw_min = aCWmax;
+ qparam.txop = 0;
+ qparam.aifs = 7;
+ break;
+ default: /* never happens but let's not leave undefined */
+ case 2: /* AC_BE */
+ qparam.cw_max = aCWmin;
+ qparam.cw_min = aCWmax;
+ qparam.txop = 0;
+ qparam.aifs = 3;
+ break;
+ case 1: /* AC_VI */
+ qparam.cw_max = aCWmin;
+ qparam.cw_min = (aCWmin + 1) / 2 - 1;
+ if (use_11b)
+ qparam.txop = 6016/32;
+ else
+ qparam.txop = 3008/32;
+ qparam.aifs = 2;
+ break;
+ case 0: /* AC_VO */
+ qparam.cw_max = (aCWmin + 1) / 2 - 1;
+ qparam.cw_min = (aCWmin + 1) / 4 - 1;
+ if (use_11b)
+ qparam.txop = 3264/32;
+ else
+ qparam.txop = 1504/32;
+ qparam.aifs = 2;
+ break;
+ }
- for (i = 0; i < local_to_hw(local)->queues; i++)
- local->ops->conf_tx(local_to_hw(local), i, &qparam);
+ drv_conf_tx(local, queue, &qparam);
+ }
}
void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
@@ -831,16 +890,73 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
ieee80211_tx_skb(sdata, skb, encrypt);
}
+int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
+ const u8 *ie, size_t ie_len)
+{
+ struct ieee80211_supported_band *sband;
+ u8 *pos, *supp_rates_len, *esupp_rates_len = NULL;
+ int i;
+
+ sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
+ pos = buffer;
+
+ *pos++ = WLAN_EID_SUPP_RATES;
+ supp_rates_len = pos;
+ *pos++ = 0;
+
+ for (i = 0; i < sband->n_bitrates; i++) {
+ struct ieee80211_rate *rate = &sband->bitrates[i];
+
+ if (esupp_rates_len) {
+ *esupp_rates_len += 1;
+ } else if (*supp_rates_len == 8) {
+ *pos++ = WLAN_EID_EXT_SUPP_RATES;
+ esupp_rates_len = pos;
+ *pos++ = 1;
+ } else
+ *supp_rates_len += 1;
+
+ *pos++ = rate->bitrate / 5;
+ }
+
+ if (sband->ht_cap.ht_supported) {
+ __le16 tmp = cpu_to_le16(sband->ht_cap.cap);
+
+ *pos++ = WLAN_EID_HT_CAPABILITY;
+ *pos++ = sizeof(struct ieee80211_ht_cap);
+ memset(pos, 0, sizeof(struct ieee80211_ht_cap));
+ memcpy(pos, &tmp, sizeof(u16));
+ pos += sizeof(u16);
+ /* TODO: needs a define here for << 2 */
+ *pos++ = sband->ht_cap.ampdu_factor |
+ (sband->ht_cap.ampdu_density << 2);
+ memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
+ pos += sizeof(sband->ht_cap.mcs);
+ pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
+ }
+
+ /*
+ * If adding more here, adjust code in main.c
+ * that calculates local->scan_ies_len.
+ */
+
+ if (ie) {
+ memcpy(pos, ie, ie_len);
+ pos += ie_len;
+ }
+
+ return pos - buffer;
+}
+
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
- u8 *ssid, size_t ssid_len,
- u8 *ie, size_t ie_len)
+ const u8 *ssid, size_t ssid_len,
+ const u8 *ie, size_t ie_len)
{
struct ieee80211_local *local = sdata->local;
- struct ieee80211_supported_band *sband;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
- u8 *pos, *supp_rates, *esupp_rates = NULL;
- int i;
+ u8 *pos;
skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
ie_len);
@@ -867,31 +983,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
*pos++ = WLAN_EID_SSID;
*pos++ = ssid_len;
memcpy(pos, ssid, ssid_len);
+ pos += ssid_len;
- supp_rates = skb_put(skb, 2);
- supp_rates[0] = WLAN_EID_SUPP_RATES;
- supp_rates[1] = 0;
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
- for (i = 0; i < sband->n_bitrates; i++) {
- struct ieee80211_rate *rate = &sband->bitrates[i];
- if (esupp_rates) {
- pos = skb_put(skb, 1);
- esupp_rates[1]++;
- } else if (supp_rates[1] == 8) {
- esupp_rates = skb_put(skb, 3);
- esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
- esupp_rates[1] = 1;
- pos = &esupp_rates[2];
- } else {
- pos = skb_put(skb, 1);
- supp_rates[1]++;
- }
- *pos = rate->bitrate / 5;
- }
-
- if (ie)
- memcpy(skb_put(skb, ie_len), ie, ie_len);
+ skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len));
ieee80211_tx_skb(sdata, skb, 0);
}
@@ -931,3 +1025,108 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
}
return supp_rates;
}
+
+int ieee80211_reconfig(struct ieee80211_local *local)
+{
+ struct ieee80211_hw *hw = &local->hw;
+ struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_if_init_conf conf;
+ struct sta_info *sta;
+ unsigned long flags;
+ int res;
+
+ /* restart hardware */
+ if (local->open_count) {
+ res = drv_start(local);
+
+ ieee80211_led_radio(local, hw->conf.radio_enabled);
+ }
+
+ /* add interfaces */
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+ sdata->vif.type != NL80211_IFTYPE_MONITOR &&
+ netif_running(sdata->dev)) {
+ conf.vif = &sdata->vif;
+ conf.type = sdata->vif.type;
+ conf.mac_addr = sdata->dev->dev_addr;
+ res = drv_add_interface(local, &conf);
+ }
+ }
+
+ /* add STAs back */
+ if (local->ops->sta_notify) {
+ spin_lock_irqsave(&local->sta_lock, flags);
+ list_for_each_entry(sta, &local->sta_list, list) {
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ sdata = container_of(sdata->bss,
+ struct ieee80211_sub_if_data,
+ u.ap);
+
+ drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD,
+ &sta->sta);
+ }
+ spin_unlock_irqrestore(&local->sta_lock, flags);
+ }
+
+ /* Clear Suspend state so that ADDBA requests can be processed */
+
+ rcu_read_lock();
+
+ if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
+ list_for_each_entry_rcu(sta, &local->sta_list, list) {
+ clear_sta_flags(sta, WLAN_STA_SUSPEND);
+ }
+ }
+
+ rcu_read_unlock();
+
+ /* setup RTS threshold */
+ drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
+
+ /* reconfigure hardware */
+ ieee80211_hw_config(local, ~0);
+
+ netif_addr_lock_bh(local->mdev);
+ ieee80211_configure_filter(local);
+ netif_addr_unlock_bh(local->mdev);
+
+ /* Finally also reconfigure all the BSS information */
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ u32 changed = ~0;
+ if (!netif_running(sdata->dev))
+ continue;
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_STATION:
+ /* disable beacon change bits */
+ changed &= ~(BSS_CHANGED_BEACON |
+ BSS_CHANGED_BEACON_ENABLED);
+ /* fall through */
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_MESH_POINT:
+ ieee80211_bss_info_change_notify(sdata, changed);
+ break;
+ case NL80211_IFTYPE_WDS:
+ break;
+ case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_MONITOR:
+ /* ignore virtual */
+ break;
+ case NL80211_IFTYPE_UNSPECIFIED:
+ case __NL80211_IFTYPE_AFTER_LAST:
+ WARN_ON(1);
+ break;
+ }
+ }
+
+ /* add back keys */
+ list_for_each_entry(sdata, &local->interfaces, list)
+ if (netif_running(sdata->dev))
+ ieee80211_enable_keys(sdata);
+
+ ieee80211_wake_queues_by_reason(hw,
+ IEEE80211_QUEUE_STOP_REASON_SUSPEND);
+
+ return 0;
+}
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 959aa8379ccf..c14394744a9c 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -27,100 +27,6 @@
#include "aes_ccm.h"
-static int ieee80211_set_encryption(struct ieee80211_sub_if_data *sdata, u8 *sta_addr,
- int idx, int alg, int remove,
- int set_tx_key, const u8 *_key,
- size_t key_len)
-{
- struct ieee80211_local *local = sdata->local;
- struct sta_info *sta;
- struct ieee80211_key *key;
- int err;
-
- if (alg == ALG_AES_CMAC) {
- if (idx < NUM_DEFAULT_KEYS ||
- idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
- printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d "
- "(BIP)\n", sdata->dev->name, idx);
- return -EINVAL;
- }
- } else if (idx < 0 || idx >= NUM_DEFAULT_KEYS) {
- printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
- sdata->dev->name, idx);
- return -EINVAL;
- }
-
- if (remove) {
- rcu_read_lock();
-
- err = 0;
-
- if (is_broadcast_ether_addr(sta_addr)) {
- key = sdata->keys[idx];
- } else {
- sta = sta_info_get(local, sta_addr);
- if (!sta) {
- err = -ENOENT;
- goto out_unlock;
- }
- key = sta->key;
- }
-
- ieee80211_key_free(key);
- } else {
- key = ieee80211_key_alloc(alg, idx, key_len, _key);
- if (!key)
- return -ENOMEM;
-
- sta = NULL;
- err = 0;
-
- rcu_read_lock();
-
- if (!is_broadcast_ether_addr(sta_addr)) {
- set_tx_key = 0;
- /*
- * According to the standard, the key index of a
- * pairwise key must be zero. However, some AP are
- * broken when it comes to WEP key indices, so we
- * work around this.
- */
- if (idx != 0 && alg != ALG_WEP) {
- ieee80211_key_free(key);
- err = -EINVAL;
- goto out_unlock;
- }
-
- sta = sta_info_get(local, sta_addr);
- if (!sta) {
- ieee80211_key_free(key);
- err = -ENOENT;
- goto out_unlock;
- }
- }
-
- if (alg == ALG_WEP &&
- key_len != LEN_WEP40 && key_len != LEN_WEP104) {
- ieee80211_key_free(key);
- err = -EINVAL;
- goto out_unlock;
- }
-
- ieee80211_key_link(key, sdata, sta);
-
- if (set_tx_key || (!sta && !sdata->default_key && key))
- ieee80211_set_default_key(sdata, idx);
- if (alg == ALG_AES_CMAC &&
- (set_tx_key || (!sta && !sdata->default_mgmt_key && key)))
- ieee80211_set_default_mgmt_key(sdata, idx);
- }
-
- out_unlock:
- rcu_read_unlock();
-
- return err;
-}
-
static int ieee80211_ioctl_siwgenie(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra)
@@ -135,6 +41,7 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
return ret;
sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
ieee80211_sta_req_auth(sdata);
return 0;
}
@@ -149,17 +56,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
- sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_CHANNEL_SEL;
+ return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
/* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
if (freq->e == 0) {
if (freq->m < 0) {
- if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
- sdata->u.ibss.flags |=
- IEEE80211_IBSS_AUTO_CHANNEL_SEL;
- else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ if (sdata->vif.type == NL80211_IFTYPE_STATION)
sdata->u.mgd.flags |=
IEEE80211_STA_AUTO_CHANNEL_SEL;
return 0;
@@ -183,8 +87,12 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev,
struct iw_freq *freq, char *extra)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
- freq->m = local->hw.conf.channel->center_freq;
+ freq->m = local->oper_channel->center_freq;
freq->e = 6;
return 0;
@@ -195,15 +103,17 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *ssid)
{
- struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
size_t len = data->length;
int ret;
+ if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
+
/* iwconfig uses nul termination in SSID.. */
if (len > 0 && ssid[len - 1] == '\0')
len--;
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
if (data->flags)
sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
@@ -215,10 +125,10 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
return ret;
sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
ieee80211_sta_req_auth(sdata);
return 0;
- } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
- return ieee80211_ibss_set_ssid(sdata, ssid, len);
+ }
return -EOPNOTSUPP;
}
@@ -229,9 +139,13 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
struct iw_point *data, char *ssid)
{
size_t len;
-
struct ieee80211_sub_if_data *sdata;
+
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
+
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
if (res == 0) {
@@ -240,14 +154,6 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
} else
data->flags = 0;
return res;
- } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- int res = ieee80211_ibss_get_ssid(sdata, ssid, &len);
- if (res == 0) {
- data->length = len;
- data->flags = 1;
- } else
- data->flags = 0;
- return res;
}
return -EOPNOTSUPP;
@@ -258,9 +164,11 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
struct iw_request_info *info,
struct sockaddr *ap_addr, char *extra)
{
- struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
int ret;
@@ -275,18 +183,9 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
if (ret)
return ret;
sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
ieee80211_sta_req_auth(sdata);
return 0;
- } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
- sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
- IEEE80211_IBSS_AUTO_CHANNEL_SEL;
- else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
- sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL;
- else
- sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_BSSID_SEL;
-
- return ieee80211_ibss_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
} else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
/*
* If it is necessary to update the WDS peer address
@@ -312,9 +211,11 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
struct iw_request_info *info,
struct sockaddr *ap_addr, char *extra)
{
- struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) {
ap_addr->sa_family = ARPHRD_ETHER;
@@ -322,13 +223,6 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
} else
memset(&ap_addr->sa_data, 0, ETH_ALEN);
return 0;
- } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- if (sdata->u.ibss.state == IEEE80211_IBSS_MLME_JOINED) {
- ap_addr->sa_family = ARPHRD_ETHER;
- memcpy(&ap_addr->sa_data, sdata->u.ibss.bssid, ETH_ALEN);
- } else
- memset(&ap_addr->sa_data, 0, ETH_ALEN);
- return 0;
} else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
ap_addr->sa_family = ARPHRD_ETHER;
memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
@@ -487,258 +381,6 @@ static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
return 0;
}
-static int ieee80211_ioctl_siwrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rts, char *extra)
-{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
- if (rts->disabled)
- local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
- else if (!rts->fixed)
- /* if the rts value is not fixed, then take default */
- local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
- else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD)
- return -EINVAL;
- else
- local->rts_threshold = rts->value;
-
- /* If the wlan card performs RTS/CTS in hardware/firmware,
- * configure it here */
-
- if (local->ops->set_rts_threshold)
- local->ops->set_rts_threshold(local_to_hw(local),
- local->rts_threshold);
-
- return 0;
-}
-
-static int ieee80211_ioctl_giwrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rts, char *extra)
-{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
- rts->value = local->rts_threshold;
- rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD);
- rts->fixed = 1;
-
- return 0;
-}
-
-
-static int ieee80211_ioctl_siwfrag(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frag, char *extra)
-{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
- if (frag->disabled)
- local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
- else if (!frag->fixed)
- local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
- else if (frag->value < 256 ||
- frag->value > IEEE80211_MAX_FRAG_THRESHOLD)
- return -EINVAL;
- else {
- /* Fragment length must be even, so strip LSB. */
- local->fragmentation_threshold = frag->value & ~0x1;
- }
-
- return 0;
-}
-
-static int ieee80211_ioctl_giwfrag(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frag, char *extra)
-{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
- frag->value = local->fragmentation_threshold;
- frag->disabled = (frag->value >= IEEE80211_MAX_FRAG_THRESHOLD);
- frag->fixed = 1;
-
- return 0;
-}
-
-
-static int ieee80211_ioctl_siwretry(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *retry, char *extra)
-{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
- if (retry->disabled ||
- (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
- return -EINVAL;
-
- if (retry->flags & IW_RETRY_MAX) {
- local->hw.conf.long_frame_max_tx_count = retry->value;
- } else if (retry->flags & IW_RETRY_MIN) {
- local->hw.conf.short_frame_max_tx_count = retry->value;
- } else {
- local->hw.conf.long_frame_max_tx_count = retry->value;
- local->hw.conf.short_frame_max_tx_count = retry->value;
- }
-
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
-
- return 0;
-}
-
-
-static int ieee80211_ioctl_giwretry(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *retry, char *extra)
-{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
- retry->disabled = 0;
- if (retry->flags == 0 || retry->flags & IW_RETRY_MIN) {
- /* first return min value, iwconfig will ask max value
- * later if needed */
- retry->flags |= IW_RETRY_LIMIT;
- retry->value = local->hw.conf.short_frame_max_tx_count;
- if (local->hw.conf.long_frame_max_tx_count !=
- local->hw.conf.short_frame_max_tx_count)
- retry->flags |= IW_RETRY_MIN;
- return 0;
- }
- if (retry->flags & IW_RETRY_MAX) {
- retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
- retry->value = local->hw.conf.long_frame_max_tx_count;
- }
-
- return 0;
-}
-
-static int ieee80211_ioctl_siwmlme(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
-{
- struct ieee80211_sub_if_data *sdata;
- struct iw_mlme *mlme = (struct iw_mlme *) extra;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (!(sdata->vif.type == NL80211_IFTYPE_STATION))
- return -EINVAL;
-
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- /* TODO: mlme->addr.sa_data */
- return ieee80211_sta_deauthenticate(sdata, mlme->reason_code);
- case IW_MLME_DISASSOC:
- /* TODO: mlme->addr.sa_data */
- return ieee80211_sta_disassociate(sdata, mlme->reason_code);
- default:
- return -EOPNOTSUPP;
- }
-}
-
-
-static int ieee80211_ioctl_siwencode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq, char *keybuf)
-{
- struct ieee80211_sub_if_data *sdata;
- int idx, i, alg = ALG_WEP;
- u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- int remove = 0, ret;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
- idx = erq->flags & IW_ENCODE_INDEX;
- if (idx == 0) {
- if (sdata->default_key)
- for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
- if (sdata->default_key == sdata->keys[i]) {
- idx = i;
- break;
- }
- }
- } else if (idx < 1 || idx > 4)
- return -EINVAL;
- else
- idx--;
-
- if (erq->flags & IW_ENCODE_DISABLED)
- remove = 1;
- else if (erq->length == 0) {
- /* No key data - just set the default TX key index */
- ieee80211_set_default_key(sdata, idx);
- return 0;
- }
-
- ret = ieee80211_set_encryption(
- sdata, bcaddr,
- idx, alg, remove,
- !sdata->default_key,
- keybuf, erq->length);
-
- if (!ret) {
- if (remove)
- sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED;
- else
- sdata->u.mgd.flags |= IEEE80211_STA_TKIP_WEP_USED;
- }
-
- return ret;
-}
-
-
-static int ieee80211_ioctl_giwencode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq, char *key)
-{
- struct ieee80211_sub_if_data *sdata;
- int idx, i;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
- idx = erq->flags & IW_ENCODE_INDEX;
- if (idx < 1 || idx > 4) {
- idx = -1;
- if (!sdata->default_key)
- idx = 0;
- else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
- if (sdata->default_key == sdata->keys[i]) {
- idx = i;
- break;
- }
- }
- if (idx < 0)
- return -EINVAL;
- } else
- idx--;
-
- erq->flags = idx + 1;
-
- if (!sdata->keys[idx]) {
- erq->length = 0;
- erq->flags |= IW_ENCODE_DISABLED;
- return 0;
- }
-
- memcpy(key, sdata->keys[idx]->conf.key,
- min_t(int, erq->length, sdata->keys[idx]->conf.keylen));
- erq->length = sdata->keys[idx]->conf.keylen;
- erq->flags |= IW_ENCODE_ENABLED;
-
- if (sdata->vif.type == NL80211_IFTYPE_STATION) {
- switch (sdata->u.mgd.auth_alg) {
- case WLAN_AUTH_OPEN:
- case WLAN_AUTH_LEAP:
- erq->flags |= IW_ENCODE_OPEN;
- break;
- case WLAN_AUTH_SHARED_KEY:
- erq->flags |= IW_ENCODE_RESTRICTED;
- break;
- }
- }
-
- return 0;
-}
-
static int ieee80211_ioctl_siwpower(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *wrq,
@@ -747,7 +389,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_conf *conf = &local->hw.conf;
- int ret = 0, timeout = 0;
+ int timeout = 0;
bool ps;
if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
@@ -779,42 +421,18 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
timeout = wrq->value / 1000;
set:
- if (ps == local->powersave && timeout == conf->dynamic_ps_timeout)
- return ret;
+ if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout)
+ return 0;
- local->powersave = ps;
+ sdata->u.mgd.powersave = ps;
conf->dynamic_ps_timeout = timeout;
if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
- ret = ieee80211_hw_config(local,
- IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT);
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
- if (!(sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
- return ret;
-
- if (conf->dynamic_ps_timeout > 0 &&
- !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
- mod_timer(&local->dynamic_ps_timer, jiffies +
- msecs_to_jiffies(conf->dynamic_ps_timeout));
- } else {
- if (local->powersave) {
- if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
- ieee80211_send_nullfunc(local, sdata, 1);
- conf->flags |= IEEE80211_CONF_PS;
- ret = ieee80211_hw_config(local,
- IEEE80211_CONF_CHANGE_PS);
- } else {
- conf->flags &= ~IEEE80211_CONF_PS;
- ret = ieee80211_hw_config(local,
- IEEE80211_CONF_CHANGE_PS);
- if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
- ieee80211_send_nullfunc(local, sdata, 0);
- del_timer_sync(&local->dynamic_ps_timer);
- cancel_work_sync(&local->dynamic_ps_enable_work);
- }
- }
+ ieee80211_recalc_ps(local, -1);
- return ret;
+ return 0;
}
static int ieee80211_ioctl_giwpower(struct net_device *dev,
@@ -822,9 +440,9 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev,
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);
- wrqu->power.disabled = !local->powersave;
+ wrqu->power.disabled = !sdata->u.mgd.powersave;
return 0;
}
@@ -997,82 +615,6 @@ static int ieee80211_ioctl_giwauth(struct net_device *dev,
}
-static int ieee80211_ioctl_siwencodeext(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq, char *extra)
-{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
- int uninitialized_var(alg), idx, i, remove = 0;
-
- switch (ext->alg) {
- case IW_ENCODE_ALG_NONE:
- remove = 1;
- break;
- case IW_ENCODE_ALG_WEP:
- alg = ALG_WEP;
- break;
- case IW_ENCODE_ALG_TKIP:
- alg = ALG_TKIP;
- break;
- case IW_ENCODE_ALG_CCMP:
- alg = ALG_CCMP;
- break;
- case IW_ENCODE_ALG_AES_CMAC:
- alg = ALG_AES_CMAC;
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- if (erq->flags & IW_ENCODE_DISABLED)
- remove = 1;
-
- idx = erq->flags & IW_ENCODE_INDEX;
- if (alg == ALG_AES_CMAC) {
- if (idx < NUM_DEFAULT_KEYS + 1 ||
- idx > NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
- idx = -1;
- if (!sdata->default_mgmt_key)
- idx = 0;
- else for (i = NUM_DEFAULT_KEYS;
- i < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS;
- i++) {
- if (sdata->default_mgmt_key == sdata->keys[i])
- {
- idx = i;
- break;
- }
- }
- if (idx < 0)
- return -EINVAL;
- } else
- idx--;
- } else {
- if (idx < 1 || idx > 4) {
- idx = -1;
- if (!sdata->default_key)
- idx = 0;
- else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
- if (sdata->default_key == sdata->keys[i]) {
- idx = i;
- break;
- }
- }
- if (idx < 0)
- return -EINVAL;
- } else
- idx--;
- }
-
- return ieee80211_set_encryption(sdata, ext->addr.sa_data, idx, alg,
- remove,
- ext->ext_flags &
- IW_ENCODE_EXT_SET_TX_KEY,
- ext->key, ext->key_len);
-}
-
-
/* Structures to export the Wireless Handlers */
static const iw_handler ieee80211_handler[] =
@@ -1099,7 +641,7 @@ static const iw_handler ieee80211_handler[] =
(iw_handler) NULL, /* SIOCGIWTHRSPY */
(iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */
(iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */
- (iw_handler) ieee80211_ioctl_siwmlme, /* SIOCSIWMLME */
+ (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */
(iw_handler) NULL, /* SIOCGIWAPLIST */
(iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
(iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
@@ -1111,16 +653,16 @@ static const iw_handler ieee80211_handler[] =
(iw_handler) NULL, /* -- hole -- */
(iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
(iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
- (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */
- (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */
- (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */
- (iw_handler) ieee80211_ioctl_giwfrag, /* SIOCGIWFRAG */
+ (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */
+ (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
+ (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
+ (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */
(iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */
(iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */
- (iw_handler) ieee80211_ioctl_siwretry, /* SIOCSIWRETRY */
- (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */
- (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */
- (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */
+ (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */
+ (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
+ (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
+ (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */
(iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */
(iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */
(iw_handler) NULL, /* -- hole -- */
@@ -1129,7 +671,7 @@ static const iw_handler ieee80211_handler[] =
(iw_handler) NULL, /* SIOCGIWGENIE */
(iw_handler) ieee80211_ioctl_siwauth, /* SIOCSIWAUTH */
(iw_handler) ieee80211_ioctl_giwauth, /* SIOCGIWAUTH */
- (iw_handler) ieee80211_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */
(iw_handler) NULL, /* SIOCGIWENCODEEXT */
(iw_handler) NULL, /* SIOCSIWPMKSA */
(iw_handler) NULL, /* -- hole -- */
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 0b8ad1f4ecdd..45b74f38b867 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -133,7 +133,7 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
u8 *p = ieee80211_get_qos_ctl(hdr);
u8 ack_policy = 0;
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
- if (local->wifi_wme_noack_test)
+ if (unlikely(local->wifi_wme_noack_test))
ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK <<
QOS_CONTROL_ACK_POLICY_SHIFT;
/* qos header is 2 bytes, second reserved */
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 4f8bfea278f2..dcfae8884b86 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -122,7 +122,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
return RX_DROP_UNUSABLE;
mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
- (void *) skb->data);
+ (void *) skb->data, NULL);
return RX_DROP_UNUSABLE;
}
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 60aba45023ff..77bfdfeb966e 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -260,7 +260,10 @@ struct ip_vs_conn *ip_vs_ct_in_get
list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
if (cp->af == af &&
ip_vs_addr_equal(af, s_addr, &cp->caddr) &&
- ip_vs_addr_equal(af, d_addr, &cp->vaddr) &&
+ /* protocol should only be IPPROTO_IP if
+ * d_addr is a fwmark */
+ ip_vs_addr_equal(protocol == IPPROTO_IP ? AF_UNSPEC : af,
+ d_addr, &cp->vaddr) &&
s_port == cp->cport && d_port == cp->vport &&
cp->flags & IP_VS_CONN_F_TEMPLATE &&
protocol == cp->protocol) {
@@ -698,7 +701,9 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,
cp->cport = cport;
ip_vs_addr_copy(af, &cp->vaddr, vaddr);
cp->vport = vport;
- ip_vs_addr_copy(af, &cp->daddr, daddr);
+ /* proto should only be IPPROTO_IP if d_addr is a fwmark */
+ ip_vs_addr_copy(proto == IPPROTO_IP ? AF_UNSPEC : af,
+ &cp->daddr, daddr);
cp->dport = dport;
cp->flags = flags;
spin_lock_init(&cp->lock);
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index cb3e031335eb..8dddb17a947a 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -278,7 +278,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
*/
if (svc->fwmark) {
union nf_inet_addr fwmark = {
- .all = { 0, 0, 0, htonl(svc->fwmark) }
+ .ip = htonl(svc->fwmark)
};
ct = ip_vs_ct_in_get(svc->af, IPPROTO_IP, &snet, 0,
@@ -306,7 +306,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
*/
if (svc->fwmark) {
union nf_inet_addr fwmark = {
- .all = { 0, 0, 0, htonl(svc->fwmark) }
+ .ip = htonl(svc->fwmark)
};
ct = ip_vs_conn_new(svc->af, IPPROTO_IP,
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index f13fc57e1ecb..c523f0b8cee5 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1186,28 +1186,6 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
return 0;
}
-static inline void
-ctnetlink_event_report(struct nf_conn *ct, u32 pid, int report)
-{
- unsigned int events = 0;
-
- if (test_bit(IPS_EXPECTED_BIT, &ct->status))
- events |= IPCT_RELATED;
- else
- events |= IPCT_NEW;
-
- nf_conntrack_event_report(IPCT_STATUS |
- IPCT_HELPER |
- IPCT_REFRESH |
- IPCT_PROTOINFO |
- IPCT_NATSEQADJ |
- IPCT_MARK |
- events,
- ct,
- pid,
- report);
-}
-
static struct nf_conn *
ctnetlink_create_conntrack(struct nlattr *cda[],
struct nf_conntrack_tuple *otuple,
@@ -1373,6 +1351,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE) {
struct nf_conn *ct;
+ enum ip_conntrack_events events;
ct = ctnetlink_create_conntrack(cda, &otuple,
&rtuple, u3);
@@ -1383,9 +1362,18 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
err = 0;
nf_conntrack_get(&ct->ct_general);
spin_unlock_bh(&nf_conntrack_lock);
- ctnetlink_event_report(ct,
- NETLINK_CB(skb).pid,
- nlmsg_report(nlh));
+ if (test_bit(IPS_EXPECTED_BIT, &ct->status))
+ events = IPCT_RELATED;
+ else
+ events = IPCT_NEW;
+
+ nf_conntrack_event_report(IPCT_STATUS |
+ IPCT_HELPER |
+ IPCT_PROTOINFO |
+ IPCT_NATSEQADJ |
+ IPCT_MARK | events,
+ ct, NETLINK_CB(skb).pid,
+ nlmsg_report(nlh));
nf_ct_put(ct);
} else
spin_unlock_bh(&nf_conntrack_lock);
@@ -1404,9 +1392,13 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
if (err == 0) {
nf_conntrack_get(&ct->ct_general);
spin_unlock_bh(&nf_conntrack_lock);
- ctnetlink_event_report(ct,
- NETLINK_CB(skb).pid,
- nlmsg_report(nlh));
+ nf_conntrack_event_report(IPCT_STATUS |
+ IPCT_HELPER |
+ IPCT_PROTOINFO |
+ IPCT_NATSEQADJ |
+ IPCT_MARK,
+ ct, NETLINK_CB(skb).pid,
+ nlmsg_report(nlh));
nf_ct_put(ct);
} else
spin_unlock_bh(&nf_conntrack_lock);
diff --git a/net/netfilter/xt_cluster.c b/net/netfilter/xt_cluster.c
index 6c4847662b85..69a639f35403 100644
--- a/net/netfilter/xt_cluster.c
+++ b/net/netfilter/xt_cluster.c
@@ -135,7 +135,13 @@ static bool xt_cluster_mt_checkentry(const struct xt_mtchk_param *par)
{
struct xt_cluster_match_info *info = par->matchinfo;
- if (info->node_mask >= (1 << info->total_nodes)) {
+ if (info->total_nodes > XT_CLUSTER_NODES_MAX) {
+ printk(KERN_ERR "xt_cluster: you have exceeded the maximum "
+ "number of cluster nodes (%u > %u)\n",
+ info->total_nodes, XT_CLUSTER_NODES_MAX);
+ return false;
+ }
+ if (info->node_mask >= (1ULL << info->total_nodes)) {
printk(KERN_ERR "xt_cluster: this node mask cannot be "
"higher than the total number of nodes\n");
return false;
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 20cf16fc572f..b11e7e527864 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -35,7 +35,6 @@
#include <linux/kernel.h>
#include <linux/in.h>
#include <linux/poll.h>
-#include <linux/version.h>
#include <net/sock.h>
#include "rds.h"
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 273f064930a8..d14445c48304 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -148,14 +148,12 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
if (conn)
goto out;
- conn = kmem_cache_alloc(rds_conn_slab, gfp);
+ conn = kmem_cache_zalloc(rds_conn_slab, gfp);
if (conn == NULL) {
conn = ERR_PTR(-ENOMEM);
goto out;
}
- memset(conn, 0, sizeof(*conn));
-
INIT_HLIST_NODE(&conn->c_hash_node);
conn->c_version = RDS_PROTOCOL_3_0;
conn->c_laddr = laddr;
diff --git a/net/rds/ib.c b/net/rds/ib.c
index 4933b380985e..b9bcd32431e1 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -224,8 +224,8 @@ static int rds_ib_laddr_check(__be32 addr)
* IB and iWARP capable NICs.
*/
cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP);
- if (!cm_id)
- return -EADDRNOTAVAIL;
+ if (IS_ERR(cm_id))
+ return PTR_ERR(cm_id);
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
diff --git a/net/rds/ib.h b/net/rds/ib.h
index 069206cae733..455ae73047fe 100644
--- a/net/rds/ib.h
+++ b/net/rds/ib.h
@@ -333,7 +333,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op);
void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits);
void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted);
int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted,
- u32 *adv_credits, int need_posted);
+ u32 *adv_credits, int need_posted, int max_posted);
/* ib_stats.c */
DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats);
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index 36d931573ff4..5709bad28329 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -524,7 +524,7 @@ void rds_ib_attempt_ack(struct rds_ib_connection *ic)
}
/* Can we get a send credit? */
- if (!rds_ib_send_grab_credits(ic, 1, &adv_credits, 0)) {
+ if (!rds_ib_send_grab_credits(ic, 1, &adv_credits, 0, RDS_MAX_ADV_CREDIT)) {
rds_ib_stats_inc(s_ib_tx_throttle);
clear_bit(IB_ACK_IN_FLIGHT, &ic->i_ack_flags);
return;
diff --git a/net/rds/ib_ring.c b/net/rds/ib_ring.c
index 99a6ccae964c..ff97e8eda858 100644
--- a/net/rds/ib_ring.c
+++ b/net/rds/ib_ring.c
@@ -137,7 +137,7 @@ int rds_ib_ring_empty(struct rds_ib_work_ring *ring)
int rds_ib_ring_low(struct rds_ib_work_ring *ring)
{
- return __rds_ib_ring_used(ring) <= (ring->w_nr >> 2);
+ return __rds_ib_ring_used(ring) <= (ring->w_nr >> 1);
}
/*
diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
index cb6c52cb1c4c..23bf830db2d5 100644
--- a/net/rds/ib_send.c
+++ b/net/rds/ib_send.c
@@ -311,7 +311,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context)
* and using atomic_cmpxchg when updating the two counters.
*/
int rds_ib_send_grab_credits(struct rds_ib_connection *ic,
- u32 wanted, u32 *adv_credits, int need_posted)
+ u32 wanted, u32 *adv_credits, int need_posted, int max_posted)
{
unsigned int avail, posted, got = 0, advertise;
long oldval, newval;
@@ -351,7 +351,7 @@ try_again:
* available.
*/
if (posted && (got || need_posted)) {
- advertise = min_t(unsigned int, posted, RDS_MAX_ADV_CREDIT);
+ advertise = min_t(unsigned int, posted, max_posted);
newval -= IB_SET_POST_CREDITS(advertise);
}
@@ -498,7 +498,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
credit_alloc = work_alloc;
if (ic->i_flowctl) {
- credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0);
+ credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT);
adv_credits += posted;
if (credit_alloc < work_alloc) {
rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc);
@@ -506,7 +506,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
flow_controlled++;
}
if (work_alloc == 0) {
- rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc);
+ set_bit(RDS_LL_SEND_FULL, &conn->c_flags);
rds_ib_stats_inc(s_ib_tx_throttle);
ret = -ENOMEM;
goto out;
@@ -571,7 +571,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
/*
* Update adv_credits since we reset the ACK_REQUIRED bit.
*/
- rds_ib_send_grab_credits(ic, 0, &posted, 1);
+ rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits);
adv_credits += posted;
BUG_ON(adv_credits > 255);
} else if (ic->i_rm != rm)
diff --git a/net/rds/info.c b/net/rds/info.c
index 1d885535214d..62aeef37aefe 100644
--- a/net/rds/info.c
+++ b/net/rds/info.c
@@ -188,10 +188,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
ret = -ENOMEM;
goto out;
}
- down_read(&current->mm->mmap_sem);
- ret = get_user_pages(current, current->mm, start, nr_pages, 1, 0,
- pages, NULL);
- up_read(&current->mm->mmap_sem);
+ ret = get_user_pages_fast(start, nr_pages, 1, pages);
if (ret != nr_pages) {
if (ret > 0)
nr_pages = ret;
diff --git a/net/rds/iw.c b/net/rds/iw.c
index b732efb5b634..d16e1cbc8e83 100644
--- a/net/rds/iw.c
+++ b/net/rds/iw.c
@@ -233,8 +233,8 @@ static int rds_iw_laddr_check(__be32 addr)
* IB and iWARP capable NICs.
*/
cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP);
- if (!cm_id)
- return -EADDRNOTAVAIL;
+ if (IS_ERR(cm_id))
+ return PTR_ERR(cm_id);
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
diff --git a/net/rds/iw.h b/net/rds/iw.h
index b4fb27252895..0715dde323e7 100644
--- a/net/rds/iw.h
+++ b/net/rds/iw.h
@@ -361,7 +361,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op);
void rds_iw_send_add_credits(struct rds_connection *conn, unsigned int credits);
void rds_iw_advertise_credits(struct rds_connection *conn, unsigned int posted);
int rds_iw_send_grab_credits(struct rds_iw_connection *ic, u32 wanted,
- u32 *adv_credits, int need_posted);
+ u32 *adv_credits, int need_posted, int max_posted);
/* ib_stats.c */
DECLARE_PER_CPU(struct rds_iw_statistics, rds_iw_stats);
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c
index fde470fa50d5..8683f5f66c4b 100644
--- a/net/rds/iw_recv.c
+++ b/net/rds/iw_recv.c
@@ -524,7 +524,7 @@ void rds_iw_attempt_ack(struct rds_iw_connection *ic)
}
/* Can we get a send credit? */
- if (!rds_iw_send_grab_credits(ic, 1, &adv_credits, 0)) {
+ if (!rds_iw_send_grab_credits(ic, 1, &adv_credits, 0, RDS_MAX_ADV_CREDIT)) {
rds_iw_stats_inc(s_iw_tx_throttle);
clear_bit(IB_ACK_IN_FLIGHT, &ic->i_ack_flags);
return;
diff --git a/net/rds/iw_ring.c b/net/rds/iw_ring.c
index d422d4b5deef..da8e3b63f663 100644
--- a/net/rds/iw_ring.c
+++ b/net/rds/iw_ring.c
@@ -137,7 +137,7 @@ int rds_iw_ring_empty(struct rds_iw_work_ring *ring)
int rds_iw_ring_low(struct rds_iw_work_ring *ring)
{
- return __rds_iw_ring_used(ring) <= (ring->w_nr >> 2);
+ return __rds_iw_ring_used(ring) <= (ring->w_nr >> 1);
}
diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c
index 22dd38ffd608..44a6a0551f28 100644
--- a/net/rds/iw_send.c
+++ b/net/rds/iw_send.c
@@ -347,7 +347,7 @@ void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context)
* and using atomic_cmpxchg when updating the two counters.
*/
int rds_iw_send_grab_credits(struct rds_iw_connection *ic,
- u32 wanted, u32 *adv_credits, int need_posted)
+ u32 wanted, u32 *adv_credits, int need_posted, int max_posted)
{
unsigned int avail, posted, got = 0, advertise;
long oldval, newval;
@@ -387,7 +387,7 @@ try_again:
* available.
*/
if (posted && (got || need_posted)) {
- advertise = min_t(unsigned int, posted, RDS_MAX_ADV_CREDIT);
+ advertise = min_t(unsigned int, posted, max_posted);
newval -= IB_SET_POST_CREDITS(advertise);
}
@@ -541,7 +541,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
credit_alloc = work_alloc;
if (ic->i_flowctl) {
- credit_alloc = rds_iw_send_grab_credits(ic, work_alloc, &posted, 0);
+ credit_alloc = rds_iw_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT);
adv_credits += posted;
if (credit_alloc < work_alloc) {
rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc);
@@ -549,7 +549,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
flow_controlled++;
}
if (work_alloc == 0) {
- rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc);
+ set_bit(RDS_LL_SEND_FULL, &conn->c_flags);
rds_iw_stats_inc(s_iw_tx_throttle);
ret = -ENOMEM;
goto out;
@@ -614,7 +614,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
/*
* Update adv_credits since we reset the ACK_REQUIRED bit.
*/
- rds_iw_send_grab_credits(ic, 0, &posted, 1);
+ rds_iw_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits);
adv_credits += posted;
BUG_ON(adv_credits > 255);
} else if (ic->i_rm != rm)
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index eaeeb91e1119..8dc83d2caa58 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -150,12 +150,9 @@ static int rds_pin_pages(unsigned long user_addr, unsigned int nr_pages,
{
int ret;
- down_read(&current->mm->mmap_sem);
- ret = get_user_pages(current, current->mm, user_addr,
- nr_pages, write, 0, pages, NULL);
- up_read(&current->mm->mmap_sem);
+ ret = get_user_pages_fast(user_addr, nr_pages, write, pages);
- if (0 <= ret && (unsigned) ret < nr_pages) {
+ if (ret >= 0 && ret < nr_pages) {
while (ret--)
put_page(pages[ret]);
ret = -EFAULT;
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
index 7b19024f9706..7d0f901c93d5 100644
--- a/net/rds/rdma_transport.c
+++ b/net/rds/rdma_transport.c
@@ -34,7 +34,7 @@
#include "rdma_transport.h"
-static struct rdma_cm_id *rds_iw_listen_id;
+static struct rdma_cm_id *rds_rdma_listen_id;
int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
struct rdma_cm_event *event)
@@ -161,7 +161,7 @@ static int __init rds_rdma_listen_init(void)
rdsdebug("cm %p listening on port %u\n", cm_id, RDS_PORT);
- rds_iw_listen_id = cm_id;
+ rds_rdma_listen_id = cm_id;
cm_id = NULL;
out:
if (cm_id)
@@ -171,10 +171,10 @@ out:
static void rds_rdma_listen_stop(void)
{
- if (rds_iw_listen_id) {
- rdsdebug("cm %p\n", rds_iw_listen_id);
- rdma_destroy_id(rds_iw_listen_id);
- rds_iw_listen_id = NULL;
+ if (rds_rdma_listen_id) {
+ rdsdebug("cm %p\n", rds_rdma_listen_id);
+ rdma_destroy_id(rds_rdma_listen_id);
+ rds_rdma_listen_id = NULL;
}
}
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 71794449ca4e..dbe111236783 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -132,7 +132,7 @@ struct rds_connection {
#define RDS_FLAG_CONG_BITMAP 0x01
#define RDS_FLAG_ACK_REQUIRED 0x02
#define RDS_FLAG_RETRANSMITTED 0x04
-#define RDS_MAX_ADV_CREDIT 127
+#define RDS_MAX_ADV_CREDIT 255
/*
* Maximum space available for extension headers.
diff --git a/net/rds/send.c b/net/rds/send.c
index 104fe033203d..a4a7f428cd76 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -854,11 +854,6 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
rm->m_daddr = daddr;
- /* Parse any control messages the user may have included. */
- ret = rds_cmsg_send(rs, rm, msg, &allocated_mr);
- if (ret)
- goto out;
-
/* rds_conn_create has a spinlock that runs with IRQ off.
* Caching the conn in the socket helps a lot. */
if (rs->rs_conn && rs->rs_conn->c_faddr == daddr)
@@ -874,6 +869,11 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
rs->rs_conn = conn;
}
+ /* Parse any control messages the user may have included. */
+ ret = rds_cmsg_send(rs, rm, msg, &allocated_mr);
+ if (ret)
+ goto out;
+
if ((rm->m_rdma_cookie || rm->m_rdma_op)
&& conn->c_trans->xmit_rdma == NULL) {
if (printk_ratelimit())
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index 84efde97c5a7..60a34f3b5f65 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -47,12 +47,6 @@ enum rfkill_global_sched_op {
RFKILL_GLOBAL_OP_UNBLOCK,
};
-/*
- * Currently, the code marked with RFKILL_NEED_SWSET is inactive.
- * If handling of EV_SW SW_WLAN/WWAN/BLUETOOTH/etc is needed in the
- * future, when such events are added, that code will be necessary.
- */
-
struct rfkill_task {
struct delayed_work dwork;
@@ -65,14 +59,6 @@ struct rfkill_task {
/* pending regular switch operations (1=pending) */
unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
-#ifdef RFKILL_NEED_SWSET
- /* set operation pending (1=pending) */
- unsigned long sw_setpending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
-
- /* desired state for pending set operation (1=unblock) */
- unsigned long sw_newstate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
-#endif
-
/* should the state be complemented (1=yes) */
unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
@@ -111,24 +97,6 @@ static void __rfkill_handle_global_op(enum rfkill_global_sched_op op)
}
}
-#ifdef RFKILL_NEED_SWSET
-static void __rfkill_handle_normal_op(const enum rfkill_type type,
- const bool sp, const bool s, const bool c)
-{
- enum rfkill_state state;
-
- if (sp)
- state = (s) ? RFKILL_STATE_UNBLOCKED :
- RFKILL_STATE_SOFT_BLOCKED;
- else
- state = rfkill_get_global_state(type);
-
- if (c)
- state = rfkill_state_complement(state);
-
- rfkill_switch_all(type, state);
-}
-#else
static void __rfkill_handle_normal_op(const enum rfkill_type type,
const bool c)
{
@@ -140,7 +108,6 @@ static void __rfkill_handle_normal_op(const enum rfkill_type type,
rfkill_switch_all(type, state);
}
-#endif
static void rfkill_task_handler(struct work_struct *work)
{
@@ -171,21 +138,11 @@ static void rfkill_task_handler(struct work_struct *work)
i < RFKILL_TYPE_MAX) {
if (test_and_clear_bit(i, task->sw_pending)) {
bool c;
-#ifdef RFKILL_NEED_SWSET
- bool sp, s;
- sp = test_and_clear_bit(i,
- task->sw_setpending);
- s = test_bit(i, task->sw_newstate);
-#endif
c = test_and_clear_bit(i,
task->sw_togglestate);
spin_unlock_irq(&task->lock);
-#ifdef RFKILL_NEED_SWSET
- __rfkill_handle_normal_op(i, sp, s, c);
-#else
__rfkill_handle_normal_op(i, c);
-#endif
spin_lock_irq(&task->lock);
}
@@ -238,32 +195,6 @@ static void rfkill_schedule_global_op(enum rfkill_global_sched_op op)
spin_unlock_irqrestore(&rfkill_task.lock, flags);
}
-#ifdef RFKILL_NEED_SWSET
-/* Use this if you need to add EV_SW SW_WLAN/WWAN/BLUETOOTH/etc handling */
-
-static void rfkill_schedule_set(enum rfkill_type type,
- enum rfkill_state desired_state)
-{
- unsigned long flags;
-
- if (rfkill_is_epo_lock_active())
- return;
-
- spin_lock_irqsave(&rfkill_task.lock, flags);
- if (!rfkill_task.global_op_pending) {
- set_bit(type, rfkill_task.sw_pending);
- set_bit(type, rfkill_task.sw_setpending);
- clear_bit(type, rfkill_task.sw_togglestate);
- if (desired_state)
- set_bit(type, rfkill_task.sw_newstate);
- else
- clear_bit(type, rfkill_task.sw_newstate);
- rfkill_schedule_ratelimited();
- }
- spin_unlock_irqrestore(&rfkill_task.lock, flags);
-}
-#endif
-
static void rfkill_schedule_toggle(enum rfkill_type type)
{
unsigned long flags;
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 3eaa39403c13..b770401b5bd0 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -75,6 +75,11 @@ static void rfkill_led_trigger_activate(struct led_classdev *led)
rfkill_led_trigger(rfkill, rfkill->state);
}
+#else
+static inline void rfkill_led_trigger(struct rfkill *rfkill,
+ enum rfkill_state state)
+{
+}
#endif /* CONFIG_RFKILL_LEDS */
static void rfkill_uevent(struct rfkill *rfkill)
@@ -96,6 +101,7 @@ static void update_rfkill_state(struct rfkill *rfkill)
}
mutex_unlock(&rfkill->mutex);
}
+ rfkill_led_trigger(rfkill, rfkill->state);
}
/**
@@ -136,8 +142,9 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
oldstate = rfkill->state;
if (rfkill->get_state && !force &&
- !rfkill->get_state(rfkill->data, &newstate))
+ !rfkill->get_state(rfkill->data, &newstate)) {
rfkill->state = newstate;
+ }
switch (state) {
case RFKILL_STATE_HARD_BLOCKED:
@@ -172,6 +179,7 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
if (force || rfkill->state != oldstate)
rfkill_uevent(rfkill);
+ rfkill_led_trigger(rfkill, rfkill->state);
return retval;
}
@@ -204,6 +212,7 @@ static void __rfkill_switch_all(const enum rfkill_type type,
mutex_lock(&rfkill->mutex);
rfkill_toggle_radio(rfkill, state, 0);
mutex_unlock(&rfkill->mutex);
+ rfkill_led_trigger(rfkill, rfkill->state);
}
}
}
@@ -256,6 +265,7 @@ void rfkill_epo(void)
RFKILL_STATE_SOFT_BLOCKED;
}
mutex_unlock(&rfkill_global_mutex);
+ rfkill_led_trigger(rfkill, rfkill->state);
}
EXPORT_SYMBOL_GPL(rfkill_epo);
@@ -358,6 +368,7 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
rfkill_uevent(rfkill);
mutex_unlock(&rfkill->mutex);
+ rfkill_led_trigger(rfkill, rfkill->state);
return 0;
}
@@ -559,6 +570,7 @@ static int rfkill_resume(struct device *dev)
1);
mutex_unlock(&rfkill->mutex);
+ rfkill_led_trigger(rfkill, rfkill->state);
}
return 0;
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 92cfc9d7e3b9..69188e8358b4 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -51,7 +51,7 @@ static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1;
if (sch->ops == &bfifo_qdisc_ops)
- limit *= qdisc_dev(sch)->mtu;
+ limit *= psched_mtu(qdisc_dev(sch));
q->limit = limit;
} else {
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 7d08f522ec84..f0c91df59d4e 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -412,6 +412,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
/* Build the SCTP header. */
sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
+ skb_reset_transport_header(nskb);
sh->source = htons(packet->source_port);
sh->dest = htons(packet->destination_port);
@@ -527,15 +528,25 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* Note: Adler-32 is no longer applicable, as has been replaced
* by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
*/
- if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) {
+ if (!sctp_checksum_disable &&
+ !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) {
__u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
/* 3) Put the resultant value into the checksum field in the
* common header, and leave the rest of the bits unchanged.
*/
sh->checksum = sctp_end_cksum(crc32);
- } else
- nskb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else {
+ if (dst->dev->features & NETIF_F_SCTP_CSUM) {
+ /* no need to seed psuedo checksum for SCTP */
+ nskb->ip_summed = CHECKSUM_PARTIAL;
+ nskb->csum_start = (skb_transport_header(nskb) -
+ nskb->head);
+ nskb->csum_offset = offsetof(struct sctphdr, checksum);
+ } else {
+ nskb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
+ }
/* IP layer ECN support
* From RFC 2481
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 5abab094441f..d00e8135f866 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -695,6 +695,19 @@ void rpc_force_rebind(struct rpc_clnt *clnt)
EXPORT_SYMBOL_GPL(rpc_force_rebind);
/*
+ * Restart an (async) RPC call from the call_prepare state.
+ * Usually called from within the exit handler.
+ */
+void
+rpc_restart_call_prepare(struct rpc_task *task)
+{
+ if (RPC_ASSASSINATED(task))
+ return;
+ task->tk_action = rpc_prepare_task;
+}
+EXPORT_SYMBOL_GPL(rpc_restart_call_prepare);
+
+/*
* Restart an (async) RPC call. Usually called from within the
* exit handler.
*/
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index ff50a0546865..1102ce1251f7 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -569,7 +569,7 @@ EXPORT_SYMBOL_GPL(rpc_delay);
/*
* Helper to call task->tk_ops->rpc_call_prepare
*/
-static void rpc_prepare_task(struct rpc_task *task)
+void rpc_prepare_task(struct rpc_task *task)
{
task->tk_ops->rpc_call_prepare(task, task->tk_calldata);
}
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index c200d92e57e4..6f33d33cc064 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -11,6 +11,7 @@
#include <net/sock.h>
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/svc_xprt.h>
+#include <linux/sunrpc/svcsock.h>
#define RPCDBG_FACILITY RPCDBG_SVCXPRT
@@ -1097,36 +1098,58 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
}
EXPORT_SYMBOL_GPL(svc_find_xprt);
-/*
- * Format a buffer with a list of the active transports. A zero for
- * the buflen parameter disables target buffer overflow checking.
+static int svc_one_xprt_name(const struct svc_xprt *xprt,
+ char *pos, int remaining)
+{
+ int len;
+
+ len = snprintf(pos, remaining, "%s %u\n",
+ xprt->xpt_class->xcl_name,
+ svc_xprt_local_port(xprt));
+ if (len >= remaining)
+ return -ENAMETOOLONG;
+ return len;
+}
+
+/**
+ * svc_xprt_names - format a buffer with a list of transport names
+ * @serv: pointer to an RPC service
+ * @buf: pointer to a buffer to be filled in
+ * @buflen: length of buffer to be filled in
+ *
+ * Fills in @buf with a string containing a list of transport names,
+ * each name terminated with '\n'.
+ *
+ * Returns positive length of the filled-in string on success; otherwise
+ * a negative errno value is returned if an error occurs.
*/
-int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen)
+int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen)
{
struct svc_xprt *xprt;
- char xprt_str[64];
- int totlen = 0;
- int len;
+ int len, totlen;
+ char *pos;
/* Sanity check args */
if (!serv)
return 0;
spin_lock_bh(&serv->sv_lock);
+
+ pos = buf;
+ totlen = 0;
list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
- len = snprintf(xprt_str, sizeof(xprt_str),
- "%s %d\n", xprt->xpt_class->xcl_name,
- svc_xprt_local_port(xprt));
- /* If the string was truncated, replace with error string */
- if (len >= sizeof(xprt_str))
- strcpy(xprt_str, "name-too-long\n");
- /* Don't overflow buffer */
- len = strlen(xprt_str);
- if (buflen && (len + totlen >= buflen))
+ len = svc_one_xprt_name(xprt, pos, buflen - totlen);
+ if (len < 0) {
+ *buf = '\0';
+ totlen = len;
+ }
+ if (len <= 0)
break;
- strcpy(buf+totlen, xprt_str);
+
+ pos += len;
totlen += len;
}
+
spin_unlock_bh(&serv->sv_lock);
return totlen;
}
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index af3198814c15..4e6d406264a0 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -240,42 +240,76 @@ out:
/*
* Report socket names for nfsdfs
*/
-static int one_sock_name(char *buf, struct svc_sock *svsk)
+static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining)
{
+ const struct sock *sk = svsk->sk_sk;
+ const char *proto_name = sk->sk_protocol == IPPROTO_UDP ?
+ "udp" : "tcp";
int len;
- switch(svsk->sk_sk->sk_family) {
- case AF_INET:
- len = sprintf(buf, "ipv4 %s %pI4 %d\n",
- svsk->sk_sk->sk_protocol == IPPROTO_UDP ?
- "udp" : "tcp",
- &inet_sk(svsk->sk_sk)->rcv_saddr,
- inet_sk(svsk->sk_sk)->num);
+ switch (sk->sk_family) {
+ case PF_INET:
+ len = snprintf(buf, remaining, "ipv4 %s %pI4 %d\n",
+ proto_name,
+ &inet_sk(sk)->rcv_saddr,
+ inet_sk(sk)->num);
+ break;
+ case PF_INET6:
+ len = snprintf(buf, remaining, "ipv6 %s %pI6 %d\n",
+ proto_name,
+ &inet6_sk(sk)->rcv_saddr,
+ inet_sk(sk)->num);
break;
default:
- len = sprintf(buf, "*unknown-%d*\n",
- svsk->sk_sk->sk_family);
+ len = snprintf(buf, remaining, "*unknown-%d*\n",
+ sk->sk_family);
+ }
+
+ if (len >= remaining) {
+ *buf = '\0';
+ return -ENAMETOOLONG;
}
return len;
}
-int
-svc_sock_names(char *buf, struct svc_serv *serv, char *toclose)
+/**
+ * svc_sock_names - construct a list of listener names in a string
+ * @serv: pointer to RPC service
+ * @buf: pointer to a buffer to fill in with socket names
+ * @buflen: size of the buffer to be filled
+ * @toclose: pointer to '\0'-terminated C string containing the name
+ * of a listener to be closed
+ *
+ * Fills in @buf with a '\n'-separated list of names of listener
+ * sockets. If @toclose is not NULL, the socket named by @toclose
+ * is closed, and is not included in the output list.
+ *
+ * Returns positive length of the socket name string, or a negative
+ * errno value on error.
+ */
+int svc_sock_names(struct svc_serv *serv, char *buf, const size_t buflen,
+ const char *toclose)
{
struct svc_sock *svsk, *closesk = NULL;
int len = 0;
if (!serv)
return 0;
+
spin_lock_bh(&serv->sv_lock);
list_for_each_entry(svsk, &serv->sv_permsocks, sk_xprt.xpt_list) {
- int onelen = one_sock_name(buf+len, svsk);
- if (toclose && strcmp(toclose, buf+len) == 0)
+ int onelen = svc_one_sock_name(svsk, buf + len, buflen - len);
+ if (onelen < 0) {
+ len = onelen;
+ break;
+ }
+ if (toclose && strcmp(toclose, buf + len) == 0)
closesk = svsk;
else
len += onelen;
}
spin_unlock_bh(&serv->sv_lock);
+
if (closesk)
/* Should unregister with portmap, but you cannot
* unregister just one protocol...
@@ -426,13 +460,14 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
long all[SVC_PKTINFO_SPACE / sizeof(long)];
} buffer;
struct cmsghdr *cmh = &buffer.hdr;
- int err, len;
struct msghdr msg = {
.msg_name = svc_addr(rqstp),
.msg_control = cmh,
.msg_controllen = sizeof(buffer),
.msg_flags = MSG_DONTWAIT,
};
+ size_t len;
+ int err;
if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags))
/* udp sockets need large rcvbuf as all pending
@@ -464,8 +499,8 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
return -EAGAIN;
}
len = svc_addr_len(svc_addr(rqstp));
- if (len < 0)
- return len;
+ if (len == 0)
+ return -EAFNOSUPPORT;
rqstp->rq_addrlen = len;
if (skb->tstamp.tv64 == 0) {
skb->tstamp = ktime_get_real();
@@ -1127,9 +1162,19 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
return svsk;
}
-int svc_addsock(struct svc_serv *serv,
- int fd,
- char *name_return)
+/**
+ * svc_addsock - add a listener socket to an RPC service
+ * @serv: pointer to RPC service to which to add a new listener
+ * @fd: file descriptor of the new listener
+ * @name_return: pointer to buffer to fill in with name of listener
+ * @len: size of the buffer
+ *
+ * Fills in socket name and returns positive length of name if successful.
+ * Name is terminated with '\n'. On error, returns a negative errno
+ * value.
+ */
+int svc_addsock(struct svc_serv *serv, const int fd, char *name_return,
+ const size_t len)
{
int err = 0;
struct socket *so = sockfd_lookup(fd, &err);
@@ -1169,7 +1214,7 @@ int svc_addsock(struct svc_serv *serv,
sockfd_put(so);
return err;
}
- return one_sock_name(name_return, svsk);
+ return svc_one_sock_name(svsk, name_return, len);
}
EXPORT_SYMBOL_GPL(svc_addsock);
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index 629a28764da9..42a6f9f20285 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -265,7 +265,7 @@ static int fast_reg_read_chunks(struct svcxprt_rdma *xprt,
frmr->page_list->page_list[page_no] =
ib_dma_map_single(xprt->sc_cm_id->device,
page_address(rqstp->rq_arg.pages[page_no]),
- PAGE_SIZE, DMA_TO_DEVICE);
+ PAGE_SIZE, DMA_FROM_DEVICE);
if (ib_dma_mapping_error(xprt->sc_cm_id->device,
frmr->page_list->page_list[page_no]))
goto fatal_err;
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 6c26a675435a..8b510c5e8777 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -183,6 +183,7 @@ static int fast_reg_xdr(struct svcxprt_rdma *xprt,
fatal_err:
printk("svcrdma: Error fast registering memory for xprt %p\n", xprt);
+ vec->frmr = NULL;
svc_rdma_put_frmr(xprt, frmr);
return -EIO;
}
@@ -516,6 +517,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
"svcrdma: could not post a receive buffer, err=%d."
"Closing transport %p.\n", ret, rdma);
set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
+ svc_rdma_put_frmr(rdma, vec->frmr);
svc_rdma_put_context(ctxt, 0);
return -ENOTCONN;
}
@@ -606,6 +608,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
return 0;
err:
+ svc_rdma_unmap_dma(ctxt);
svc_rdma_put_frmr(rdma, vec->frmr);
svc_rdma_put_context(ctxt, 1);
return -EIO;
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 3d810e7df3fb..4b0c2fa15e0b 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -520,8 +520,9 @@ int svc_rdma_post_recv(struct svcxprt_rdma *xprt)
svc_xprt_get(&xprt->sc_xprt);
ret = ib_post_recv(xprt->sc_qp, &recv_wr, &bad_recv_wr);
if (ret) {
- svc_xprt_put(&xprt->sc_xprt);
+ svc_rdma_unmap_dma(ctxt);
svc_rdma_put_context(ctxt, 1);
+ svc_xprt_put(&xprt->sc_xprt);
}
return ret;
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index f72ba774c246..524ba5696d4d 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -167,7 +167,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
tb_ptr->mtu = dev->mtu;
tb_ptr->blocked = 0;
tb_ptr->addr.type = htonl(TIPC_MEDIA_TYPE_ETH);
- memcpy(&tb_ptr->addr.dev_addr, &dev->dev_addr, ETH_ALEN);
+ memcpy(&tb_ptr->addr.dev_addr, dev->dev_addr, ETH_ALEN);
return 0;
}
diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c
index 5d149c1b5f0d..9ad4d893a566 100644
--- a/net/wimax/op-msg.c
+++ b/net/wimax/op-msg.c
@@ -149,7 +149,8 @@ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
}
result = nla_put(skb, WIMAX_GNL_MSG_DATA, size, msg);
if (result < 0) {
- dev_err(dev, "no memory to add payload in attribute\n");
+ dev_err(dev, "no memory to add payload (msg %p size %zu) in "
+ "attribute: %d\n", msg, size, result);
goto error_nla_put;
}
genlmsg_end(skb, genl_msg);
@@ -299,10 +300,10 @@ int wimax_msg(struct wimax_dev *wimax_dev, const char *pipe_name,
struct sk_buff *skb;
skb = wimax_msg_alloc(wimax_dev, pipe_name, buf, size, gfp_flags);
- if (skb == NULL)
- goto error_msg_new;
- result = wimax_msg_send(wimax_dev, skb);
-error_msg_new:
+ if (IS_ERR(skb))
+ result = PTR_ERR(skb);
+ else
+ result = wimax_msg_send(wimax_dev, skb);
return result;
}
EXPORT_SYMBOL_GPL(wimax_msg);
diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c
index 2b75aee04217..870032faece2 100644
--- a/net/wimax/op-rfkill.c
+++ b/net/wimax/op-rfkill.c
@@ -113,7 +113,7 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
if (state != wimax_dev->rf_hw) {
wimax_dev->rf_hw = state;
rfkill_state = state == WIMAX_RF_ON ?
- RFKILL_STATE_OFF : RFKILL_STATE_ON;
+ RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
if (wimax_dev->rf_hw == WIMAX_RF_ON
&& wimax_dev->rf_sw == WIMAX_RF_ON)
wimax_state = WIMAX_ST_READY;
@@ -259,10 +259,10 @@ int wimax_rfkill_toggle_radio(void *data, enum rfkill_state state)
d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state);
switch (state) {
- case RFKILL_STATE_ON:
+ case RFKILL_STATE_SOFT_BLOCKED:
rf_state = WIMAX_RF_OFF;
break;
- case RFKILL_STATE_OFF:
+ case RFKILL_STATE_UNBLOCKED:
rf_state = WIMAX_RF_ON;
break;
default:
@@ -361,7 +361,7 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
wimax_dev->rfkill = rfkill;
rfkill->name = wimax_dev->name;
- rfkill->state = RFKILL_STATE_OFF;
+ rfkill->state = RFKILL_STATE_UNBLOCKED;
rfkill->data = wimax_dev;
rfkill->toggle_radio = wimax_rfkill_toggle_radio;
rfkill->user_claim_unsupported = 1;
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index a0ee76b52510..933e1422b09f 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -338,8 +338,21 @@ out:
*/
void wimax_state_change(struct wimax_dev *wimax_dev, enum wimax_st new_state)
{
+ /*
+ * A driver cannot take the wimax_dev out of the
+ * __WIMAX_ST_NULL state unless by calling wimax_dev_add(). If
+ * the wimax_dev's state is still NULL, we ignore any request
+ * to change its state because it means it hasn't been yet
+ * registered.
+ *
+ * There is no need to complain about it, as routines that
+ * call this might be shared from different code paths that
+ * are called before or after wimax_dev_add() has done its
+ * job.
+ */
mutex_lock(&wimax_dev->mutex);
- __wimax_state_change(wimax_dev, new_state);
+ if (wimax_dev->state > __WIMAX_ST_NULL)
+ __wimax_state_change(wimax_dev, new_state);
mutex_unlock(&wimax_dev->mutex);
return;
}
@@ -376,7 +389,7 @@ EXPORT_SYMBOL_GPL(wimax_state_get);
void wimax_dev_init(struct wimax_dev *wimax_dev)
{
INIT_LIST_HEAD(&wimax_dev->id_table_node);
- __wimax_state_set(wimax_dev, WIMAX_ST_UNINITIALIZED);
+ __wimax_state_set(wimax_dev, __WIMAX_ST_NULL);
mutex_init(&wimax_dev->mutex);
mutex_init(&wimax_dev->mutex_reset);
}
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 6d1e7b27b752..14ea01c4a103 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
-cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o
+cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o
cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/wireless/core.c b/net/wireless/core.c
index d1f556535f6d..47c20eb0c04d 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1,7 +1,7 @@
/*
* This is the linux wireless configuration interface.
*
- * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>
*/
#include <linux/if.h>
@@ -14,7 +14,6 @@
#include <linux/device.h>
#include <net/genetlink.h>
#include <net/cfg80211.h>
-#include <net/wireless.h>
#include "nl80211.h"
#include "core.h"
#include "sysfs.h"
@@ -274,6 +273,16 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
drv->wiphy.dev.class = &ieee80211_class;
drv->wiphy.dev.platform_data = drv;
+ /*
+ * Initialize wiphy parameters to IEEE 802.11 MIB default values.
+ * Fragmentation and RTS threshold are disabled by default with the
+ * special -1 value.
+ */
+ drv->wiphy.retry_short = 7;
+ drv->wiphy.retry_long = 4;
+ drv->wiphy.frag_threshold = (u32) -1;
+ drv->wiphy.rts_threshold = (u32) -1;
+
return &drv->wiphy;
}
EXPORT_SYMBOL(wiphy_new);
@@ -448,8 +457,28 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
"symlink to netdev!\n");
}
dev->ieee80211_ptr->netdev = dev;
+#ifdef CONFIG_WIRELESS_EXT
+ dev->ieee80211_ptr->wext.default_key = -1;
+ dev->ieee80211_ptr->wext.default_mgmt_key = -1;
+#endif
mutex_unlock(&rdev->devlist_mtx);
break;
+ case NETDEV_GOING_DOWN:
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+ break;
+ if (!dev->ieee80211_ptr->ssid_len)
+ break;
+ cfg80211_leave_ibss(rdev, dev, true);
+ break;
+ case NETDEV_UP:
+#ifdef CONFIG_WIRELESS_EXT
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+ break;
+ if (!dev->ieee80211_ptr->wext.ibss.ssid_len)
+ break;
+ cfg80211_join_ibss(rdev, dev, &dev->ieee80211_ptr->wext.ibss);
+ break;
+#endif
case NETDEV_UNREGISTER:
mutex_lock(&rdev->devlist_mtx);
if (!list_empty(&dev->ieee80211_ptr->list)) {
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 0a592e4295f0..f14b6c5f4221 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -1,7 +1,7 @@
/*
* Wireless configuration interface internals.
*
- * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>
*/
#ifndef __NET_WIRELESS_CORE_H
#define __NET_WIRELESS_CORE_H
@@ -10,9 +10,7 @@
#include <linux/netdevice.h>
#include <linux/kref.h>
#include <linux/rbtree.h>
-#include <linux/mutex.h>
#include <net/genetlink.h>
-#include <net/wireless.h>
#include <net/cfg80211.h>
#include "reg.h"
@@ -74,10 +72,7 @@ bool wiphy_idx_valid(int wiphy_idx)
extern struct mutex cfg80211_mutex;
extern struct list_head cfg80211_drv_list;
-static inline void assert_cfg80211_lock(void)
-{
- WARN_ON(!mutex_is_locked(&cfg80211_mutex));
-}
+#define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex))
/*
* You can use this to mark a wiphy_idx as not having an associated wiphy.
@@ -148,4 +143,16 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
void cfg80211_bss_age(struct cfg80211_registered_device *dev,
unsigned long age_secs);
+/* IBSS */
+int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_ibss_params *params);
+void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
+int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, bool nowext);
+
+/* internal helpers */
+int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
+ const u8 *mac_addr);
+
#endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
new file mode 100644
index 000000000000..a4a1c3498ff2
--- /dev/null
+++ b/net/wireless/ibss.c
@@ -0,0 +1,369 @@
+/*
+ * Some IBSS support code for cfg80211.
+ *
+ * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <net/cfg80211.h>
+#include "nl80211.h"
+
+
+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_bss *bss;
+#ifdef CONFIG_WIRELESS_EXT
+ union iwreq_data wrqu;
+#endif
+
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return;
+
+ if (WARN_ON(!wdev->ssid_len))
+ return;
+
+ if (memcmp(bssid, wdev->bssid, ETH_ALEN) == 0)
+ return;
+
+ bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+ wdev->ssid, wdev->ssid_len,
+ WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
+
+ if (WARN_ON(!bss))
+ return;
+
+ if (wdev->current_bss) {
+ cfg80211_unhold_bss(wdev->current_bss);
+ cfg80211_put_bss(wdev->current_bss);
+ }
+
+ cfg80211_hold_bss(bss);
+ wdev->current_bss = bss;
+ memcpy(wdev->bssid, bssid, ETH_ALEN);
+
+ nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, gfp);
+#ifdef CONFIG_WIRELESS_EXT
+ memset(&wrqu, 0, sizeof(wrqu));
+ memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+ wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+EXPORT_SYMBOL(cfg80211_ibss_joined);
+
+int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_ibss_params *params)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ int err;
+
+ if (wdev->ssid_len)
+ return -EALREADY;
+
+#ifdef CONFIG_WIRELESS_EXT
+ wdev->wext.ibss.channel = params->channel;
+#endif
+ err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
+
+ if (err)
+ return err;
+
+ memcpy(wdev->ssid, params->ssid, params->ssid_len);
+ wdev->ssid_len = params->ssid_len;
+
+ return 0;
+}
+
+void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ if (wdev->current_bss) {
+ cfg80211_unhold_bss(wdev->current_bss);
+ cfg80211_put_bss(wdev->current_bss);
+ }
+
+ wdev->current_bss = NULL;
+ wdev->ssid_len = 0;
+ memset(wdev->bssid, 0, ETH_ALEN);
+#ifdef CONFIG_WIRELESS_EXT
+ if (!nowext)
+ wdev->wext.ibss.ssid_len = 0;
+#endif
+}
+
+int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, bool nowext)
+{
+ int err;
+
+ err = rdev->ops->leave_ibss(&rdev->wiphy, dev);
+
+ if (err)
+ return err;
+
+ cfg80211_clear_ibss(dev, nowext);
+
+ return 0;
+}
+
+#ifdef CONFIG_WIRELESS_EXT
+static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev)
+{
+ enum ieee80211_band band;
+ int i;
+
+ if (!wdev->wext.ibss.beacon_interval)
+ wdev->wext.ibss.beacon_interval = 100;
+
+ /* try to find an IBSS channel if none requested ... */
+ if (!wdev->wext.ibss.channel) {
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *chan;
+
+ sband = rdev->wiphy.bands[band];
+ if (!sband)
+ continue;
+
+ for (i = 0; i < sband->n_channels; i++) {
+ chan = &sband->channels[i];
+ if (chan->flags & IEEE80211_CHAN_NO_IBSS)
+ continue;
+ if (chan->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+ wdev->wext.ibss.channel = chan;
+ break;
+ }
+
+ if (wdev->wext.ibss.channel)
+ break;
+ }
+
+ if (!wdev->wext.ibss.channel)
+ return -EINVAL;
+ }
+
+ /* don't join -- SSID is not there */
+ if (!wdev->wext.ibss.ssid_len)
+ return 0;
+
+ if (!netif_running(wdev->netdev))
+ return 0;
+
+ return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy),
+ wdev->netdev, &wdev->wext.ibss);
+}
+
+int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct ieee80211_channel *chan;
+ int err;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+ return -EOPNOTSUPP;
+
+ chan = cfg80211_wext_freq(wdev->wiphy, freq);
+ if (chan && IS_ERR(chan))
+ return PTR_ERR(chan);
+
+ if (chan &&
+ (chan->flags & IEEE80211_CHAN_NO_IBSS ||
+ chan->flags & IEEE80211_CHAN_DISABLED))
+ return -EINVAL;
+
+ if (wdev->wext.ibss.channel == chan)
+ return 0;
+
+ if (wdev->ssid_len) {
+ err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
+ dev, true);
+ if (err)
+ return err;
+ }
+
+ if (chan) {
+ wdev->wext.ibss.channel = chan;
+ wdev->wext.ibss.channel_fixed = true;
+ } else {
+ /* cfg80211_ibss_wext_join will pick one if needed */
+ wdev->wext.ibss.channel_fixed = false;
+ }
+
+ return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
+
+int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct ieee80211_channel *chan = NULL;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ if (wdev->current_bss)
+ chan = wdev->current_bss->channel;
+ else if (wdev->wext.ibss.channel)
+ chan = wdev->wext.ibss.channel;
+
+ if (chan) {
+ freq->m = chan->center_freq;
+ freq->e = 6;
+ return 0;
+ }
+
+ /* no channel if not joining */
+ return -EINVAL;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq);
+
+int cfg80211_ibss_wext_siwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ size_t len = data->length;
+ int err;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+ return -EOPNOTSUPP;
+
+ if (wdev->ssid_len) {
+ err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
+ dev, true);
+ if (err)
+ return err;
+ }
+
+ /* iwconfig uses nul termination in SSID.. */
+ if (len > 0 && ssid[len - 1] == '\0')
+ len--;
+
+ wdev->wext.ibss.ssid = wdev->ssid;
+ memcpy(wdev->wext.ibss.ssid, ssid, len);
+ wdev->wext.ibss.ssid_len = len;
+
+ return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
+
+int cfg80211_ibss_wext_giwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ data->flags = 0;
+
+ if (wdev->ssid_len) {
+ data->flags = 1;
+ data->length = wdev->ssid_len;
+ memcpy(ssid, wdev->ssid, data->length);
+ } else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) {
+ data->flags = 1;
+ data->length = wdev->wext.ibss.ssid_len;
+ memcpy(ssid, wdev->wext.ibss.ssid, data->length);
+ }
+
+ return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid);
+
+int cfg80211_ibss_wext_siwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ u8 *bssid = ap_addr->sa_data;
+ int err;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+ return -EOPNOTSUPP;
+
+ if (ap_addr->sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ /* automatic mode */
+ if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
+ bssid = NULL;
+
+ /* both automatic */
+ if (!bssid && !wdev->wext.ibss.bssid)
+ return 0;
+
+ /* fixed already - and no change */
+ if (wdev->wext.ibss.bssid && bssid &&
+ compare_ether_addr(bssid, wdev->wext.ibss.bssid) == 0)
+ return 0;
+
+ if (wdev->ssid_len) {
+ err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
+ dev, true);
+ if (err)
+ return err;
+ }
+
+ if (bssid) {
+ memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
+ wdev->wext.ibss.bssid = wdev->wext.bssid;
+ } else
+ wdev->wext.ibss.bssid = NULL;
+
+ return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
+
+int cfg80211_ibss_wext_giwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ /* call only for ibss! */
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+ return -EINVAL;
+
+ ap_addr->sa_family = ARPHRD_ETHER;
+
+ if (wdev->wext.ibss.bssid) {
+ memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
+ return 0;
+ }
+
+ memcpy(ap_addr->sa_data, wdev->bssid, ETH_ALEN);
+ return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap);
+#endif
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index bec5721b6f99..42184361a109 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -28,19 +28,55 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
}
EXPORT_SYMBOL(cfg80211_send_rx_assoc);
-void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf, size_t len)
+void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
{
struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
- nl80211_send_rx_deauth(rdev, dev, buf, len);
+ nl80211_send_deauth(rdev, dev, buf, len);
}
-EXPORT_SYMBOL(cfg80211_send_rx_deauth);
+EXPORT_SYMBOL(cfg80211_send_deauth);
-void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf,
- size_t len)
+void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
{
struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
- nl80211_send_rx_disassoc(rdev, dev, buf, len);
+ nl80211_send_disassoc(rdev, dev, buf, len);
}
-EXPORT_SYMBOL(cfg80211_send_rx_disassoc);
+EXPORT_SYMBOL(cfg80211_send_disassoc);
+
+static void cfg80211_wext_disconnected(struct net_device *dev)
+{
+#ifdef CONFIG_WIRELESS_EXT
+ union iwreq_data wrqu;
+ memset(&wrqu, 0, sizeof(wrqu));
+ wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+
+void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
+{
+ struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+ nl80211_send_auth_timeout(rdev, dev, addr);
+ cfg80211_wext_disconnected(dev);
+}
+EXPORT_SYMBOL(cfg80211_send_auth_timeout);
+
+void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
+{
+ struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+ nl80211_send_assoc_timeout(rdev, dev, addr);
+ cfg80211_wext_disconnected(dev);
+}
+EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
+
+void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
+ enum nl80211_key_type key_type, int key_id,
+ const u8 *tsc)
+{
+ struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+ nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc);
+}
+EXPORT_SYMBOL(cfg80211_michael_mic_failure);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2456e4ee445e..f0fec2f49828 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1,7 +1,7 @@
/*
* This is the new netlink-based wireless configuration interface.
*
- * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>
*/
#include <linux/if.h>
@@ -61,6 +61,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
[NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
[NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
[NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
+ [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
+ [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
+ [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
+ [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
[NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
[NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -116,8 +120,45 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
.len = IEEE80211_MAX_SSID_LEN },
[NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
[NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
+ [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
+ [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
+ [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
+ [NL80211_ATTR_STA_FLAGS2] = {
+ .len = sizeof(struct nl80211_sta_flag_update),
+ },
+ [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
};
+/* IE validation */
+static bool is_valid_ie_attr(const struct nlattr *attr)
+{
+ const u8 *pos;
+ int len;
+
+ if (!attr)
+ return true;
+
+ pos = nla_data(attr);
+ len = nla_len(attr);
+
+ while (len) {
+ u8 elemlen;
+
+ if (len < 2)
+ return false;
+ len -= 2;
+
+ elemlen = pos[1];
+ if (elemlen > len)
+ return false;
+
+ len -= elemlen;
+ pos += 2 + elemlen;
+ }
+
+ return true;
+}
+
/* message building helper */
static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
int flags, u8 cmd)
@@ -126,6 +167,30 @@ static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
}
+static int nl80211_msg_put_channel(struct sk_buff *msg,
+ struct ieee80211_channel *chan)
+{
+ NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
+ chan->center_freq);
+
+ if (chan->flags & IEEE80211_CHAN_DISABLED)
+ NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
+ if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
+ if (chan->flags & IEEE80211_CHAN_NO_IBSS)
+ NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
+ if (chan->flags & IEEE80211_CHAN_RADAR)
+ NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
+
+ NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
+ DBM_TO_MBM(chan->max_power));
+
+ return 0;
+
+ nla_put_failure:
+ return -ENOBUFS;
+}
+
/* netlink command implementations */
static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
@@ -149,8 +214,24 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
+
+ NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
+ dev->wiphy.retry_short);
+ NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
+ dev->wiphy.retry_long);
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+ dev->wiphy.frag_threshold);
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
+ dev->wiphy.rts_threshold);
+
NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
dev->wiphy.max_scan_ssids);
+ NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
+ dev->wiphy.max_scan_ie_len);
+
+ NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
+ sizeof(u32) * dev->wiphy.n_cipher_suites,
+ dev->wiphy.cipher_suites);
nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
if (!nl_modes)
@@ -202,20 +283,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
goto nla_put_failure;
chan = &dev->wiphy.bands[band]->channels[i];
- NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
- chan->center_freq);
- if (chan->flags & IEEE80211_CHAN_DISABLED)
- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
- if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
- if (chan->flags & IEEE80211_CHAN_NO_IBSS)
- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
- if (chan->flags & IEEE80211_CHAN_RADAR)
- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
-
- NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
- DBM_TO_MBM(chan->max_power));
+ if (nl80211_msg_put_channel(msg, chan))
+ goto nla_put_failure;
nla_nest_end(msg, nl_freq);
}
@@ -273,6 +343,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
CMD(assoc, ASSOCIATE);
CMD(deauth, DEAUTHENTICATE);
CMD(disassoc, DISASSOCIATE);
+ CMD(join_ibss, JOIN_IBSS);
#undef CMD
nla_nest_end(msg, nl_cmds);
@@ -365,6 +436,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
struct cfg80211_registered_device *rdev;
int result = 0, rem_txq_params = 0;
struct nlattr *nl_txq_params;
+ u32 changed;
+ u8 retry_short = 0, retry_long = 0;
+ u32 frag_threshold = 0, rts_threshold = 0;
rtnl_lock();
@@ -479,6 +553,84 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
goto bad_res;
}
+ changed = 0;
+
+ if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
+ retry_short = nla_get_u8(
+ info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
+ if (retry_short == 0) {
+ result = -EINVAL;
+ goto bad_res;
+ }
+ changed |= WIPHY_PARAM_RETRY_SHORT;
+ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
+ retry_long = nla_get_u8(
+ info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
+ if (retry_long == 0) {
+ result = -EINVAL;
+ goto bad_res;
+ }
+ changed |= WIPHY_PARAM_RETRY_LONG;
+ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
+ frag_threshold = nla_get_u32(
+ info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
+ if (frag_threshold < 256) {
+ result = -EINVAL;
+ goto bad_res;
+ }
+ if (frag_threshold != (u32) -1) {
+ /*
+ * Fragments (apart from the last one) are required to
+ * have even length. Make the fragmentation code
+ * simpler by stripping LSB should someone try to use
+ * odd threshold value.
+ */
+ frag_threshold &= ~0x1;
+ }
+ changed |= WIPHY_PARAM_FRAG_THRESHOLD;
+ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
+ rts_threshold = nla_get_u32(
+ info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
+ changed |= WIPHY_PARAM_RTS_THRESHOLD;
+ }
+
+ if (changed) {
+ u8 old_retry_short, old_retry_long;
+ u32 old_frag_threshold, old_rts_threshold;
+
+ if (!rdev->ops->set_wiphy_params) {
+ result = -EOPNOTSUPP;
+ goto bad_res;
+ }
+
+ old_retry_short = rdev->wiphy.retry_short;
+ old_retry_long = rdev->wiphy.retry_long;
+ old_frag_threshold = rdev->wiphy.frag_threshold;
+ old_rts_threshold = rdev->wiphy.rts_threshold;
+
+ if (changed & WIPHY_PARAM_RETRY_SHORT)
+ rdev->wiphy.retry_short = retry_short;
+ if (changed & WIPHY_PARAM_RETRY_LONG)
+ rdev->wiphy.retry_long = retry_long;
+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
+ rdev->wiphy.frag_threshold = frag_threshold;
+ if (changed & WIPHY_PARAM_RTS_THRESHOLD)
+ rdev->wiphy.rts_threshold = rts_threshold;
+
+ result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
+ if (result) {
+ rdev->wiphy.retry_short = old_retry_short;
+ rdev->wiphy.retry_long = old_retry_long;
+ rdev->wiphy.frag_threshold = old_frag_threshold;
+ rdev->wiphy.rts_threshold = old_rts_threshold;
+ }
+ }
bad_res:
mutex_unlock(&rdev->mtx);
@@ -489,6 +641,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
+ struct cfg80211_registered_device *rdev,
struct net_device *dev)
{
void *hdr;
@@ -498,6 +651,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
return -1;
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
return genlmsg_end(msg, hdr);
@@ -532,7 +686,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
}
if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
- wdev->netdev) < 0) {
+ dev, wdev->netdev) < 0) {
mutex_unlock(&dev->devlist_mtx);
goto out;
}
@@ -566,7 +720,8 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
if (!msg)
goto out_err;
- if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0)
+ if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
+ dev, netdev) < 0)
goto out_free;
dev_put(netdev);
@@ -616,7 +771,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
struct cfg80211_registered_device *drv;
struct vif_params params;
int err, ifindex;
- enum nl80211_iftype type;
+ enum nl80211_iftype otype, ntype;
struct net_device *dev;
u32 _flags, *flags = NULL;
bool change = false;
@@ -630,30 +785,27 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
goto unlock_rtnl;
ifindex = dev->ifindex;
- type = dev->ieee80211_ptr->iftype;
+ otype = ntype = dev->ieee80211_ptr->iftype;
dev_put(dev);
if (info->attrs[NL80211_ATTR_IFTYPE]) {
- enum nl80211_iftype ntype;
-
ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
- if (type != ntype)
+ if (otype != ntype)
change = true;
- type = ntype;
- if (type > NL80211_IFTYPE_MAX) {
+ if (ntype > NL80211_IFTYPE_MAX) {
err = -EINVAL;
goto unlock;
}
}
if (!drv->ops->change_virtual_intf ||
- !(drv->wiphy.interface_modes & (1 << type))) {
+ !(drv->wiphy.interface_modes & (1 << ntype))) {
err = -EOPNOTSUPP;
goto unlock;
}
if (info->attrs[NL80211_ATTR_MESH_ID]) {
- if (type != NL80211_IFTYPE_MESH_POINT) {
+ if (ntype != NL80211_IFTYPE_MESH_POINT) {
err = -EINVAL;
goto unlock;
}
@@ -663,7 +815,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
}
if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
- if (type != NL80211_IFTYPE_MONITOR) {
+ if (ntype != NL80211_IFTYPE_MONITOR) {
err = -EINVAL;
goto unlock;
}
@@ -678,12 +830,17 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
if (change)
err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
- type, flags, &params);
+ ntype, flags, &params);
else
err = 0;
dev = __dev_get_by_index(&init_net, ifindex);
- WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
+ WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != ntype));
+
+ if (dev && !err && (ntype != otype)) {
+ if (otype == NL80211_IFTYPE_ADHOC)
+ cfg80211_clear_ibss(dev, false);
+ }
unlock:
cfg80211_put_dev(drv);
@@ -920,6 +1077,14 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
}
err = func(&drv->wiphy, dev, key_idx);
+#ifdef CONFIG_WIRELESS_EXT
+ if (!err) {
+ if (func == drv->ops->set_default_key)
+ dev->ieee80211_ptr->wext.default_key = key_idx;
+ else
+ dev->ieee80211_ptr->wext.default_mgmt_key = key_idx;
+ }
+#endif
out:
cfg80211_put_dev(drv);
@@ -934,7 +1099,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *drv;
- int err;
+ int err, i;
struct net_device *dev;
struct key_params params;
u8 key_idx = 0;
@@ -950,6 +1115,11 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
}
+ if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
+ params.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
+ params.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
+ }
+
if (info->attrs[NL80211_ATTR_KEY_IDX])
key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
@@ -958,44 +1128,8 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_MAC])
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
- if (key_idx > 5)
- return -EINVAL;
-
- /*
- * Disallow pairwise keys with non-zero index unless it's WEP
- * (because current deployments use pairwise WEP keys with
- * non-zero indizes but 802.11i clearly specifies to use zero)
- */
- if (mac_addr && key_idx &&
- params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
- params.cipher != WLAN_CIPHER_SUITE_WEP104)
- return -EINVAL;
-
- /* TODO: add definitions for the lengths to linux/ieee80211.h */
- switch (params.cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- if (params.key_len != 5)
- return -EINVAL;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- if (params.key_len != 32)
- return -EINVAL;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- if (params.key_len != 16)
- return -EINVAL;
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- if (params.key_len != 13)
- return -EINVAL;
- break;
- case WLAN_CIPHER_SUITE_AES_CMAC:
- if (params.key_len != 16)
- return -EINVAL;
- break;
- default:
+ if (cfg80211_validate_key_settings(&params, key_idx, mac_addr))
return -EINVAL;
- }
rtnl_lock();
@@ -1003,6 +1137,14 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
if (err)
goto unlock_rtnl;
+ for (i = 0; i < drv->wiphy.n_cipher_suites; i++)
+ if (params.cipher == drv->wiphy.cipher_suites[i])
+ break;
+ if (i == drv->wiphy.n_cipher_suites) {
+ err = -EINVAL;
+ goto out;
+ }
+
if (!drv->ops->add_key) {
err = -EOPNOTSUPP;
goto out;
@@ -1049,6 +1191,15 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
+#ifdef CONFIG_WIRELESS_EXT
+ if (!err) {
+ if (key_idx == dev->ieee80211_ptr->wext.default_key)
+ dev->ieee80211_ptr->wext.default_key = -1;
+ else if (key_idx == dev->ieee80211_ptr->wext.default_mgmt_key)
+ dev->ieee80211_ptr->wext.default_mgmt_key = -1;
+ }
+#endif
+
out:
cfg80211_put_dev(drv);
dev_put(dev);
@@ -1069,6 +1220,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
struct beacon_parameters params;
int haveinfo = 0;
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
+ return -EINVAL;
+
rtnl_lock();
err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -1186,15 +1340,36 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
[NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
[NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
[NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
+ [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
};
-static int parse_station_flags(struct nlattr *nla, u32 *staflags)
+static int parse_station_flags(struct genl_info *info,
+ struct station_parameters *params)
{
struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
+ struct nlattr *nla;
int flag;
- *staflags = 0;
+ /*
+ * Try parsing the new attribute first so userspace
+ * can specify both for older kernels.
+ */
+ nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
+ if (nla) {
+ struct nl80211_sta_flag_update *sta_flags;
+
+ sta_flags = nla_data(nla);
+ params->sta_flags_mask = sta_flags->mask;
+ params->sta_flags_set = sta_flags->set;
+ if ((params->sta_flags_mask |
+ params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
+ return -EINVAL;
+ return 0;
+ }
+
+ /* if present, parse the old attribute */
+ nla = info->attrs[NL80211_ATTR_STA_FLAGS];
if (!nla)
return 0;
@@ -1202,11 +1377,12 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags)
nla, sta_flags_policy))
return -EINVAL;
- *staflags = STATION_FLAG_CHANGED;
+ params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1;
+ params->sta_flags_mask &= ~1;
for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
if (flags[flag])
- *staflags |= (1<<flag);
+ params->sta_flags_set |= (1<<flag);
return 0;
}
@@ -1502,8 +1678,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
params.ht_capa =
nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
- if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
- &params.station_flags))
+ if (parse_station_flags(info, &params))
return -EINVAL;
if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
@@ -1572,8 +1747,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
params.ht_capa =
nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
- if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
- &params.station_flags))
+ if (parse_station_flags(info, &params))
return -EINVAL;
rtnl_lock();
@@ -1582,6 +1756,12 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
if (err)
goto out_rtnl;
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
+ err = -EINVAL;
+ goto out;
+ }
+
err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
if (err)
goto out;
@@ -1625,6 +1805,12 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
if (err)
goto out_rtnl;
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
+ err = -EINVAL;
+ goto out;
+ }
+
if (!drv->ops->del_station) {
err = -EOPNOTSUPP;
goto out;
@@ -2442,6 +2628,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
enum ieee80211_band band;
size_t ie_len;
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ return -EINVAL;
+
rtnl_lock();
err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2492,6 +2681,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
else
ie_len = 0;
+ if (ie_len > wiphy->max_scan_ie_len) {
+ err = -EINVAL;
+ goto out;
+ }
+
request = kzalloc(sizeof(*request)
+ sizeof(*ssid) * n_ssids
+ sizeof(channel) * n_channels
@@ -2554,7 +2748,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_IE]) {
request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
- memcpy(request->ie, nla_data(info->attrs[NL80211_ATTR_IE]),
+ memcpy((void *)request->ie,
+ nla_data(info->attrs[NL80211_ATTR_IE]),
request->ie_len);
}
@@ -2710,6 +2905,15 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
struct wiphy *wiphy;
int err;
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
+ return -EINVAL;
+
rtnl_lock();
err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2731,11 +2935,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
goto out;
}
- if (!info->attrs[NL80211_ATTR_MAC]) {
- err = -EINVAL;
- goto out;
- }
-
wiphy = &drv->wiphy;
memset(&req, 0, sizeof(req));
@@ -2761,13 +2960,10 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
- if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
- req.auth_type =
- nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
- if (!nl80211_valid_auth_type(req.auth_type)) {
- err = -EINVAL;
- goto out;
- }
+ req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
+ if (!nl80211_valid_auth_type(req.auth_type)) {
+ err = -EINVAL;
+ goto out;
}
err = drv->ops->auth(&drv->wiphy, dev, &req);
@@ -2788,6 +2984,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
struct wiphy *wiphy;
int err;
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_MAC] ||
+ !info->attrs[NL80211_ATTR_SSID])
+ return -EINVAL;
+
rtnl_lock();
err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2809,12 +3012,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
goto out;
}
- if (!info->attrs[NL80211_ATTR_MAC] ||
- !info->attrs[NL80211_ATTR_SSID]) {
- err = -EINVAL;
- goto out;
- }
-
wiphy = &drv->wiphy;
memset(&req, 0, sizeof(req));
@@ -2838,6 +3035,19 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
+ if (info->attrs[NL80211_ATTR_USE_MFP]) {
+ enum nl80211_mfp use_mfp =
+ nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
+ if (use_mfp == NL80211_MFP_REQUIRED)
+ req.use_mfp = true;
+ else if (use_mfp != NL80211_MFP_NO) {
+ err = -EINVAL;
+ goto out;
+ }
+ }
+
+ req.control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
+
err = drv->ops->assoc(&drv->wiphy, dev, &req);
out:
@@ -2856,6 +3066,15 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
struct wiphy *wiphy;
int err;
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_REASON_CODE])
+ return -EINVAL;
+
rtnl_lock();
err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2877,24 +3096,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
goto out;
}
- if (!info->attrs[NL80211_ATTR_MAC]) {
- err = -EINVAL;
- goto out;
- }
-
wiphy = &drv->wiphy;
memset(&req, 0, sizeof(req));
req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
- if (info->attrs[NL80211_ATTR_REASON_CODE]) {
- req.reason_code =
- nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
- if (req.reason_code == 0) {
- /* Reason Code 0 is reserved */
- err = -EINVAL;
- goto out;
- }
+ req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+ if (req.reason_code == 0) {
+ /* Reason Code 0 is reserved */
+ err = -EINVAL;
+ goto out;
}
if (info->attrs[NL80211_ATTR_IE]) {
@@ -2920,6 +3131,15 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
struct wiphy *wiphy;
int err;
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_REASON_CODE])
+ return -EINVAL;
+
rtnl_lock();
err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2941,24 +3161,16 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
goto out;
}
- if (!info->attrs[NL80211_ATTR_MAC]) {
- err = -EINVAL;
- goto out;
- }
-
wiphy = &drv->wiphy;
memset(&req, 0, sizeof(req));
req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
- if (info->attrs[NL80211_ATTR_REASON_CODE]) {
- req.reason_code =
- nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
- if (req.reason_code == 0) {
- /* Reason Code 0 is reserved */
- err = -EINVAL;
- goto out;
- }
+ req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+ if (req.reason_code == 0) {
+ /* Reason Code 0 is reserved */
+ err = -EINVAL;
+ goto out;
}
if (info->attrs[NL80211_ATTR_IE]) {
@@ -2976,6 +3188,124 @@ unlock_rtnl:
return err;
}
+static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *drv;
+ struct net_device *dev;
+ struct cfg80211_ibss_params ibss;
+ struct wiphy *wiphy;
+ int err;
+
+ memset(&ibss, 0, sizeof(ibss));
+
+ if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
+ !info->attrs[NL80211_ATTR_SSID] ||
+ !nla_len(info->attrs[NL80211_ATTR_SSID]))
+ return -EINVAL;
+
+ ibss.beacon_interval = 100;
+
+ if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
+ ibss.beacon_interval =
+ nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
+ if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000)
+ return -EINVAL;
+ }
+
+ rtnl_lock();
+
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+ if (err)
+ goto unlock_rtnl;
+
+ if (!drv->ops->join_ibss) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!netif_running(dev)) {
+ err = -ENETDOWN;
+ goto out;
+ }
+
+ wiphy = &drv->wiphy;
+
+ if (info->attrs[NL80211_ATTR_MAC])
+ ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+ ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+
+ if (info->attrs[NL80211_ATTR_IE]) {
+ ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+ ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+ }
+
+ ibss.channel = ieee80211_get_channel(wiphy,
+ nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+ if (!ibss.channel ||
+ ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
+ ibss.channel->flags & IEEE80211_CHAN_DISABLED) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
+
+ err = cfg80211_join_ibss(drv, dev, &ibss);
+
+out:
+ cfg80211_put_dev(drv);
+ dev_put(dev);
+unlock_rtnl:
+ rtnl_unlock();
+ return err;
+}
+
+static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *drv;
+ struct net_device *dev;
+ int err;
+
+ rtnl_lock();
+
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+ if (err)
+ goto unlock_rtnl;
+
+ if (!drv->ops->leave_ibss) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!netif_running(dev)) {
+ err = -ENETDOWN;
+ goto out;
+ }
+
+ err = cfg80211_leave_ibss(drv, dev, false);
+
+out:
+ cfg80211_put_dev(drv);
+ dev_put(dev);
+unlock_rtnl:
+ rtnl_unlock();
+ return err;
+}
+
static struct genl_ops nl80211_ops[] = {
{
.cmd = NL80211_CMD_GET_WIPHY,
@@ -3177,6 +3507,18 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
},
+ {
+ .cmd = NL80211_CMD_JOIN_IBSS,
+ .doit = nl80211_join_ibss,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = NL80211_CMD_LEAVE_IBSS,
+ .doit = nl80211_leave_ibss,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
.name = "mlme",
@@ -3375,22 +3717,197 @@ void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
}
-void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, const u8 *buf,
- size_t len)
+void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *buf, size_t len)
{
nl80211_send_mlme_event(rdev, netdev, buf, len,
NL80211_CMD_DEAUTHENTICATE);
}
-void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, const u8 *buf,
- size_t len)
+void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *buf,
+ size_t len)
{
nl80211_send_mlme_event(rdev, netdev, buf, len,
NL80211_CMD_DISASSOCIATE);
}
+static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, int cmd,
+ const u8 *addr)
+{
+ struct sk_buff *msg;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
+void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *addr)
+{
+ nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
+ addr);
+}
+
+void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *addr)
+{
+ nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE, addr);
+}
+
+void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *bssid,
+ gfp_t gfp)
+{
+ struct sk_buff *msg;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
+void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *addr,
+ enum nl80211_key_type key_type, int key_id,
+ const u8 *tsc)
+{
+ struct sk_buff *msg;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ if (addr)
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+ NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
+ NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
+ if (tsc)
+ NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
+void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
+ struct ieee80211_channel *channel_before,
+ struct ieee80211_channel *channel_after)
+{
+ struct sk_buff *msg;
+ void *hdr;
+ struct nlattr *nl_freq;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ /*
+ * Since we are applying the beacon hint to a wiphy we know its
+ * wiphy_idx is valid
+ */
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy));
+
+ /* Before */
+ nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
+ if (!nl_freq)
+ goto nla_put_failure;
+ if (nl80211_msg_put_channel(msg, channel_before))
+ goto nla_put_failure;
+ nla_nest_end(msg, nl_freq);
+
+ /* After */
+ nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
+ if (!nl_freq)
+ goto nla_put_failure;
+ if (nl80211_msg_put_channel(msg, channel_after))
+ goto nla_put_failure;
+ nla_nest_end(msg, nl_freq);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC);
+
+ return;
+
+nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
/* initialisation/exit functions */
int nl80211_init(void)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index b77af4ab80be..5c12ad13499b 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -17,11 +17,31 @@ extern void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
const u8 *buf, size_t len);
-extern void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev,
- struct net_device *netdev,
- const u8 *buf, size_t len);
-extern void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev,
- struct net_device *netdev,
- const u8 *buf, size_t len);
+extern void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ const u8 *buf, size_t len);
+extern void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ const u8 *buf, size_t len);
+extern void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ const u8 *addr);
+extern void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ const u8 *addr);
+extern void
+nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *addr,
+ enum nl80211_key_type key_type,
+ int key_id, const u8 *tsc);
+
+extern void
+nl80211_send_beacon_hint_event(struct wiphy *wiphy,
+ struct ieee80211_channel *channel_before,
+ struct ieee80211_channel *channel_after);
+
+void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *bssid,
+ gfp_t gfp);
#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 6c1993d99902..537af62ec42b 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -37,7 +37,6 @@
#include <linux/random.h>
#include <linux/nl80211.h>
#include <linux/platform_device.h>
-#include <net/wireless.h>
#include <net/cfg80211.h>
#include "core.h"
#include "reg.h"
@@ -907,6 +906,7 @@ EXPORT_SYMBOL(freq_reg_info);
int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth,
const struct ieee80211_reg_rule **reg_rule)
{
+ assert_cfg80211_lock();
return freq_reg_info_regd(wiphy, center_freq,
bandwidth, reg_rule, NULL);
}
@@ -1049,18 +1049,10 @@ static void handle_reg_beacon(struct wiphy *wiphy,
unsigned int chan_idx,
struct reg_beacon *reg_beacon)
{
-#ifdef CONFIG_CFG80211_REG_DEBUG
-#define REG_DEBUG_BEACON_FLAG(desc) \
- printk(KERN_DEBUG "cfg80211: Enabling " desc " on " \
- "frequency: %d MHz (Ch %d) on %s\n", \
- reg_beacon->chan.center_freq, \
- ieee80211_frequency_to_channel(reg_beacon->chan.center_freq), \
- wiphy_name(wiphy));
-#else
-#define REG_DEBUG_BEACON_FLAG(desc) do {} while (0)
-#endif
struct ieee80211_supported_band *sband;
struct ieee80211_channel *chan;
+ bool channel_changed = false;
+ struct ieee80211_channel chan_before;
assert_cfg80211_lock();
@@ -1070,18 +1062,28 @@ static void handle_reg_beacon(struct wiphy *wiphy,
if (likely(chan->center_freq != reg_beacon->chan.center_freq))
return;
- if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
+ if (chan->beacon_found)
+ return;
+
+ chan->beacon_found = true;
+
+ chan_before.center_freq = chan->center_freq;
+ chan_before.flags = chan->flags;
+
+ if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
+ !(chan->orig_flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
- REG_DEBUG_BEACON_FLAG("active scanning");
+ channel_changed = true;
}
- if (chan->flags & IEEE80211_CHAN_NO_IBSS) {
+ if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
+ !(chan->orig_flags & IEEE80211_CHAN_NO_IBSS)) {
chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
- REG_DEBUG_BEACON_FLAG("beaconing");
+ channel_changed = true;
}
- chan->beacon_found = true;
-#undef REG_DEBUG_BEACON_FLAG
+ if (channel_changed)
+ nl80211_send_beacon_hint_event(wiphy, &chan_before, chan);
}
/*
@@ -1133,7 +1135,8 @@ static bool reg_is_world_roaming(struct wiphy *wiphy)
if (is_world_regdom(cfg80211_regdomain->alpha2) ||
(wiphy->regd && is_world_regdom(wiphy->regd->alpha2)))
return true;
- if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
+ if (last_request &&
+ last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
wiphy->custom_regulatory)
return true;
return false;
@@ -1142,6 +1145,12 @@ static bool reg_is_world_roaming(struct wiphy *wiphy)
/* Reap the advantages of previously found beacons */
static void reg_process_beacons(struct wiphy *wiphy)
{
+ /*
+ * Means we are just firing up cfg80211, so no beacons would
+ * have been processed yet.
+ */
+ if (!last_request)
+ return;
if (!reg_is_world_roaming(wiphy))
return;
wiphy_update_beacon_reg(wiphy);
@@ -1176,6 +1185,8 @@ static void handle_channel_custom(struct wiphy *wiphy,
struct ieee80211_supported_band *sband;
struct ieee80211_channel *chan;
+ assert_cfg80211_lock();
+
sband = wiphy->bands[band];
BUG_ON(chan_idx >= sband->n_channels);
chan = &sband->channels[chan_idx];
@@ -1214,10 +1225,13 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
const struct ieee80211_regdomain *regd)
{
enum ieee80211_band band;
+
+ mutex_lock(&cfg80211_mutex);
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (wiphy->bands[band])
handle_band_custom(wiphy, band, regd);
}
+ mutex_unlock(&cfg80211_mutex);
}
EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
@@ -1423,7 +1437,7 @@ new_request:
return call_crda(last_request->alpha2);
}
-/* This currently only processes user and driver regulatory hints */
+/* This processes *all* regulatory hints */
static void reg_process_hint(struct regulatory_request *reg_request)
{
int r = 0;
@@ -2099,14 +2113,14 @@ void reg_device_remove(struct wiphy *wiphy)
assert_cfg80211_lock();
+ kfree(wiphy->regd);
+
if (last_request)
request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
- kfree(wiphy->regd);
- if (!last_request || !request_wiphy)
- return;
- if (request_wiphy != wiphy)
+ if (!request_wiphy || request_wiphy != wiphy)
return;
+
last_request->wiphy_idx = WIPHY_IDX_STALE;
last_request->country_ie_env = ENVIRON_ANY;
}
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 2ae65b39b529..df59440290e5 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -377,24 +377,23 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
size_t ielen = res->pub.len_information_elements;
- if (ksize(found) >= used + ielen) {
+ if (!found->ies_allocated && ksize(found) >= used + ielen) {
memcpy(found->pub.information_elements,
res->pub.information_elements, ielen);
found->pub.len_information_elements = ielen;
} else {
u8 *ies = found->pub.information_elements;
- if (found->ies_allocated) {
- if (ksize(ies) < ielen)
- ies = krealloc(ies, ielen,
- GFP_ATOMIC);
- } else
+ if (found->ies_allocated)
+ ies = krealloc(ies, ielen, GFP_ATOMIC);
+ else
ies = kmalloc(ielen, GFP_ATOMIC);
if (ies) {
memcpy(ies, res->pub.information_elements, ielen);
found->ies_allocated = true;
found->pub.information_elements = ies;
+ found->pub.len_information_elements = ielen;
}
}
}
@@ -414,6 +413,55 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
return found;
}
+struct cfg80211_bss*
+cfg80211_inform_bss(struct wiphy *wiphy,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
+ u64 timestamp, u16 capability, u16 beacon_interval,
+ const u8 *ie, size_t ielen,
+ s32 signal, gfp_t gfp)
+{
+ struct cfg80211_internal_bss *res;
+ size_t privsz;
+
+ if (WARN_ON(!wiphy))
+ return NULL;
+
+ privsz = wiphy->bss_priv_size;
+
+ if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC &&
+ (signal < 0 || signal > 100)))
+ return NULL;
+
+ res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
+ if (!res)
+ return NULL;
+
+ memcpy(res->pub.bssid, bssid, ETH_ALEN);
+ res->pub.channel = channel;
+ res->pub.signal = signal;
+ res->pub.tsf = timestamp;
+ res->pub.beacon_interval = beacon_interval;
+ res->pub.capability = capability;
+ /* point to after the private area */
+ res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz;
+ memcpy(res->pub.information_elements, ie, ielen);
+ res->pub.len_information_elements = ielen;
+
+ kref_init(&res->ref);
+
+ res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, 0);
+ if (!res)
+ return NULL;
+
+ if (res->pub.capability & WLAN_CAPABILITY_ESS)
+ regulatory_hint_found_beacon(wiphy, channel, gfp);
+
+ /* cfg80211_bss_update gives us a referenced result */
+ return &res->pub;
+}
+EXPORT_SYMBOL(cfg80211_inform_bss);
+
struct cfg80211_bss *
cfg80211_inform_bss_frame(struct wiphy *wiphy,
struct ieee80211_channel *channel,
@@ -604,7 +652,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
cfg80211_put_dev(rdev);
return err;
}
-EXPORT_SYMBOL(cfg80211_wext_siwscan);
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
static void ieee80211_scan_add_ies(struct iw_request_info *info,
struct cfg80211_bss *bss,
@@ -913,5 +961,5 @@ int cfg80211_wext_giwscan(struct net_device *dev,
cfg80211_put_dev(rdev);
return res;
}
-EXPORT_SYMBOL(cfg80211_wext_giwscan);
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
#endif
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 487cdd9bcffc..beb226e78cd7 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1,10 +1,10 @@
/*
* Wireless utility functions
*
- * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
*/
-#include <net/wireless.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
+#include <net/cfg80211.h>
#include "core.h"
struct ieee80211_rate *
@@ -138,3 +138,48 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
if (wiphy->bands[band])
set_mandatory_flags_band(wiphy->bands[band], band);
}
+
+int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
+ const u8 *mac_addr)
+{
+ if (key_idx > 5)
+ return -EINVAL;
+
+ /*
+ * Disallow pairwise keys with non-zero index unless it's WEP
+ * (because current deployments use pairwise WEP keys with
+ * non-zero indizes but 802.11i clearly specifies to use zero)
+ */
+ if (mac_addr && key_idx &&
+ params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
+ params->cipher != WLAN_CIPHER_SUITE_WEP104)
+ return -EINVAL;
+
+ /* TODO: add definitions for the lengths to linux/ieee80211.h */
+ switch (params->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ if (params->key_len != 5)
+ return -EINVAL;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ if (params->key_len != 32)
+ return -EINVAL;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ if (params->key_len != 16)
+ return -EINVAL;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ if (params->key_len != 13)
+ return -EINVAL;
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ if (params->key_len != 16)
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 0fd1db6e95bb..f98090b90fbf 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -5,13 +5,14 @@
* into cfg80211, when that happens all the exports here go away and
* we directly assign the wireless handlers of wireless interfaces.
*
- * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2008-2009 Johannes Berg <johannes@sipsolutions.net>
*/
#include <linux/wireless.h>
#include <linux/nl80211.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
#include <net/iw_handler.h>
-#include <net/wireless.h>
#include <net/cfg80211.h>
#include "core.h"
@@ -57,7 +58,7 @@ int cfg80211_wext_giwname(struct net_device *dev,
return 0;
}
-EXPORT_SYMBOL(cfg80211_wext_giwname);
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwname);
int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
u32 *mode, char *extra)
@@ -108,7 +109,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
return ret;
}
-EXPORT_SYMBOL(cfg80211_wext_siwmode);
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode);
int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
u32 *mode, char *extra)
@@ -143,7 +144,7 @@ int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
}
return 0;
}
-EXPORT_SYMBOL(cfg80211_wext_giwmode);
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwmode);
int cfg80211_wext_giwrange(struct net_device *dev,
@@ -206,7 +207,6 @@ int cfg80211_wext_giwrange(struct net_device *dev,
range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-
for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
int i;
struct ieee80211_supported_band *sband;
@@ -240,4 +240,500 @@ int cfg80211_wext_giwrange(struct net_device *dev,
return 0;
}
-EXPORT_SYMBOL(cfg80211_wext_giwrange);
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange);
+
+int cfg80211_wext_siwmlme(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct iw_mlme *mlme = (struct iw_mlme *)extra;
+ struct cfg80211_registered_device *rdev;
+ union {
+ struct cfg80211_disassoc_request disassoc;
+ struct cfg80211_deauth_request deauth;
+ } cmd;
+
+ if (!wdev)
+ return -EOPNOTSUPP;
+
+ rdev = wiphy_to_dev(wdev->wiphy);
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION)
+ return -EINVAL;
+
+ if (mlme->addr.sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ switch (mlme->cmd) {
+ case IW_MLME_DEAUTH:
+ if (!rdev->ops->deauth)
+ return -EOPNOTSUPP;
+ cmd.deauth.peer_addr = mlme->addr.sa_data;
+ cmd.deauth.reason_code = mlme->reason_code;
+ return rdev->ops->deauth(wdev->wiphy, dev, &cmd.deauth);
+ case IW_MLME_DISASSOC:
+ if (!rdev->ops->disassoc)
+ return -EOPNOTSUPP;
+ cmd.disassoc.peer_addr = mlme->addr.sa_data;
+ cmd.disassoc.reason_code = mlme->reason_code;
+ return rdev->ops->disassoc(wdev->wiphy, dev, &cmd.disassoc);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
+
+
+/**
+ * cfg80211_wext_freq - get wext frequency for non-"auto"
+ * @wiphy: the wiphy
+ * @freq: the wext freq encoding
+ *
+ * Returns a channel, %NULL for auto, or an ERR_PTR for errors!
+ */
+struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
+ struct iw_freq *freq)
+{
+ struct ieee80211_channel *chan;
+ int f;
+
+ /*
+ * Parse frequency - return NULL for auto and
+ * -EINVAL for impossible things.
+ */
+ if (freq->e == 0) {
+ if (freq->m < 0)
+ return NULL;
+ f = ieee80211_channel_to_frequency(freq->m);
+ } else {
+ int i, div = 1000000;
+ for (i = 0; i < freq->e; i++)
+ div /= 10;
+ if (div <= 0)
+ return ERR_PTR(-EINVAL);
+ f = freq->m / div;
+ }
+
+ /*
+ * Look up channel struct and return -EINVAL when
+ * it cannot be found.
+ */
+ chan = ieee80211_get_channel(wiphy, f);
+ if (!chan)
+ return ERR_PTR(-EINVAL);
+ return chan;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_freq);
+
+int cfg80211_wext_siwrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+ u32 orts = wdev->wiphy->rts_threshold;
+ int err;
+
+ if (rts->disabled || !rts->fixed)
+ wdev->wiphy->rts_threshold = (u32) -1;
+ else if (rts->value < 0)
+ return -EINVAL;
+ else
+ wdev->wiphy->rts_threshold = rts->value;
+
+ err = rdev->ops->set_wiphy_params(wdev->wiphy,
+ WIPHY_PARAM_RTS_THRESHOLD);
+ if (err)
+ wdev->wiphy->rts_threshold = orts;
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwrts);
+
+int cfg80211_wext_giwrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ rts->value = wdev->wiphy->rts_threshold;
+ rts->disabled = rts->value == (u32) -1;
+ rts->fixed = 1;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwrts);
+
+int cfg80211_wext_siwfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+ u32 ofrag = wdev->wiphy->frag_threshold;
+ int err;
+
+ if (frag->disabled || !frag->fixed)
+ wdev->wiphy->frag_threshold = (u32) -1;
+ else if (frag->value < 256)
+ return -EINVAL;
+ else {
+ /* Fragment length must be even, so strip LSB. */
+ wdev->wiphy->frag_threshold = frag->value & ~0x1;
+ }
+
+ err = rdev->ops->set_wiphy_params(wdev->wiphy,
+ WIPHY_PARAM_FRAG_THRESHOLD);
+ if (err)
+ wdev->wiphy->frag_threshold = ofrag;
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwfrag);
+
+int cfg80211_wext_giwfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ frag->value = wdev->wiphy->frag_threshold;
+ frag->disabled = frag->value == (u32) -1;
+ frag->fixed = 1;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag);
+
+int cfg80211_wext_siwretry(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+ u32 changed = 0;
+ u8 olong = wdev->wiphy->retry_long;
+ u8 oshort = wdev->wiphy->retry_short;
+ int err;
+
+ if (retry->disabled ||
+ (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
+ return -EINVAL;
+
+ if (retry->flags & IW_RETRY_LONG) {
+ wdev->wiphy->retry_long = retry->value;
+ changed |= WIPHY_PARAM_RETRY_LONG;
+ } else if (retry->flags & IW_RETRY_SHORT) {
+ wdev->wiphy->retry_short = retry->value;
+ changed |= WIPHY_PARAM_RETRY_SHORT;
+ } else {
+ wdev->wiphy->retry_short = retry->value;
+ wdev->wiphy->retry_long = retry->value;
+ changed |= WIPHY_PARAM_RETRY_LONG;
+ changed |= WIPHY_PARAM_RETRY_SHORT;
+ }
+
+ if (!changed)
+ return 0;
+
+ err = rdev->ops->set_wiphy_params(wdev->wiphy, changed);
+ if (err) {
+ wdev->wiphy->retry_short = oshort;
+ wdev->wiphy->retry_long = olong;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry);
+
+int cfg80211_wext_giwretry(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ retry->disabled = 0;
+
+ if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) {
+ /*
+ * First return short value, iwconfig will ask long value
+ * later if needed
+ */
+ retry->flags |= IW_RETRY_LIMIT;
+ retry->value = wdev->wiphy->retry_short;
+ if (wdev->wiphy->retry_long != wdev->wiphy->retry_short)
+ retry->flags |= IW_RETRY_LONG;
+
+ return 0;
+ }
+
+ if (retry->flags & IW_RETRY_LONG) {
+ retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
+ retry->value = wdev->wiphy->retry_long;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);
+
+static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, const u8 *addr,
+ bool remove, bool tx_key, int idx,
+ struct key_params *params)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ int err;
+
+ if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
+ if (!rdev->ops->set_default_mgmt_key)
+ return -EOPNOTSUPP;
+
+ if (idx < 4 || idx > 5)
+ return -EINVAL;
+ } else if (idx < 0 || idx > 3)
+ return -EINVAL;
+
+ if (remove) {
+ err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr);
+ if (!err) {
+ if (idx == wdev->wext.default_key)
+ wdev->wext.default_key = -1;
+ else if (idx == wdev->wext.default_mgmt_key)
+ wdev->wext.default_mgmt_key = -1;
+ }
+ return err;
+ } else {
+ if (addr)
+ tx_key = false;
+
+ if (cfg80211_validate_key_settings(params, idx, addr))
+ return -EINVAL;
+
+ err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params);
+ if (err)
+ return err;
+
+ if (tx_key || (!addr && wdev->wext.default_key == -1)) {
+ err = rdev->ops->set_default_key(&rdev->wiphy,
+ dev, idx);
+ if (!err)
+ wdev->wext.default_key = idx;
+ return err;
+ }
+
+ if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC &&
+ (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) {
+ err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
+ dev, idx);
+ if (!err)
+ wdev->wext.default_mgmt_key = idx;
+ return err;
+ }
+
+ return 0;
+ }
+}
+
+int cfg80211_wext_siwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *keybuf)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+ int idx, err;
+ bool remove = false;
+ struct key_params params;
+
+ /* no use -- only MFP (set_default_mgmt_key) is optional */
+ if (!rdev->ops->del_key ||
+ !rdev->ops->add_key ||
+ !rdev->ops->set_default_key)
+ return -EOPNOTSUPP;
+
+ idx = erq->flags & IW_ENCODE_INDEX;
+ if (idx == 0) {
+ idx = wdev->wext.default_key;
+ if (idx < 0)
+ idx = 0;
+ } else if (idx < 1 || idx > 4)
+ return -EINVAL;
+ else
+ idx--;
+
+ if (erq->flags & IW_ENCODE_DISABLED)
+ remove = true;
+ else if (erq->length == 0) {
+ /* No key data - just set the default TX key index */
+ err = rdev->ops->set_default_key(&rdev->wiphy, dev, idx);
+ if (!err)
+ wdev->wext.default_key = idx;
+ return err;
+ }
+
+ memset(&params, 0, sizeof(params));
+ params.key = keybuf;
+ params.key_len = erq->length;
+ if (erq->length == 5)
+ params.cipher = WLAN_CIPHER_SUITE_WEP40;
+ else if (erq->length == 13)
+ params.cipher = WLAN_CIPHER_SUITE_WEP104;
+ else if (!remove)
+ return -EINVAL;
+
+ return cfg80211_set_encryption(rdev, dev, NULL, remove,
+ wdev->wext.default_key == -1,
+ idx, &params);
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwencode);
+
+int cfg80211_wext_siwencodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+ struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
+ const u8 *addr;
+ int idx;
+ bool remove = false;
+ struct key_params params;
+ u32 cipher;
+
+ /* no use -- only MFP (set_default_mgmt_key) is optional */
+ if (!rdev->ops->del_key ||
+ !rdev->ops->add_key ||
+ !rdev->ops->set_default_key)
+ return -EOPNOTSUPP;
+
+ switch (ext->alg) {
+ case IW_ENCODE_ALG_NONE:
+ remove = true;
+ cipher = 0;
+ break;
+ case IW_ENCODE_ALG_WEP:
+ if (ext->key_len == 5)
+ cipher = WLAN_CIPHER_SUITE_WEP40;
+ else if (ext->key_len == 13)
+ cipher = WLAN_CIPHER_SUITE_WEP104;
+ else
+ return -EINVAL;
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ cipher = WLAN_CIPHER_SUITE_TKIP;
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ cipher = WLAN_CIPHER_SUITE_CCMP;
+ break;
+ case IW_ENCODE_ALG_AES_CMAC:
+ cipher = WLAN_CIPHER_SUITE_AES_CMAC;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ if (erq->flags & IW_ENCODE_DISABLED)
+ remove = true;
+
+ idx = erq->flags & IW_ENCODE_INDEX;
+ if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
+ if (idx < 4 || idx > 5) {
+ idx = wdev->wext.default_mgmt_key;
+ if (idx < 0)
+ return -EINVAL;
+ } else
+ idx--;
+ } else {
+ if (idx < 1 || idx > 4) {
+ idx = wdev->wext.default_key;
+ if (idx < 0)
+ return -EINVAL;
+ } else
+ idx--;
+ }
+
+ addr = ext->addr.sa_data;
+ if (is_broadcast_ether_addr(addr))
+ addr = NULL;
+
+ memset(&params, 0, sizeof(params));
+ params.key = ext->key;
+ params.key_len = ext->key_len;
+ params.cipher = cipher;
+
+ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ params.seq = ext->rx_seq;
+ params.seq_len = 6;
+ }
+
+ return cfg80211_set_encryption(
+ rdev, dev, addr, remove,
+ ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
+ idx, &params);
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext);
+
+struct giwencode_cookie {
+ size_t buflen;
+ char *keybuf;
+};
+
+static void giwencode_get_key_cb(void *cookie, struct key_params *params)
+{
+ struct giwencode_cookie *data = cookie;
+
+ if (!params->key) {
+ data->buflen = 0;
+ return;
+ }
+
+ data->buflen = min_t(size_t, data->buflen, params->key_len);
+ memcpy(data->keybuf, params->key, data->buflen);
+}
+
+int cfg80211_wext_giwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *keybuf)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+ int idx, err;
+ struct giwencode_cookie data = {
+ .keybuf = keybuf,
+ .buflen = erq->length,
+ };
+
+ if (!rdev->ops->get_key)
+ return -EOPNOTSUPP;
+
+ idx = erq->flags & IW_ENCODE_INDEX;
+ if (idx == 0) {
+ idx = wdev->wext.default_key;
+ if (idx < 0)
+ idx = 0;
+ } else if (idx < 1 || idx > 4)
+ return -EINVAL;
+ else
+ idx--;
+
+ erq->flags = idx + 1;
+
+ err = rdev->ops->get_key(&rdev->wiphy, dev, idx, NULL, &data,
+ giwencode_get_key_cb);
+ if (!err) {
+ erq->length = data.buflen;
+ erq->flags |= IW_ENCODE_ENABLED;
+ return 0;
+ }
+
+ if (err == -ENOENT) {
+ erq->flags |= IW_ENCODE_DISABLED;
+ erq->length = 0;
+ return 0;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index cb6a5bb85d80..d3bbef70cc7c 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -649,14 +649,26 @@ static int wireless_seq_show(struct seq_file *seq, void *v)
return 0;
}
+static void *wireless_dev_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ rtnl_lock();
+ return dev_seq_start(seq, pos);
+}
+
+static void wireless_dev_seq_stop(struct seq_file *seq, void *v)
+{
+ dev_seq_stop(seq, v);
+ rtnl_unlock();
+}
+
static const struct seq_operations wireless_seq_ops = {
- .start = dev_seq_start,
+ .start = wireless_dev_seq_start,
.next = dev_seq_next,
- .stop = dev_seq_stop,
+ .stop = wireless_dev_seq_stop,
.show = wireless_seq_show,
};
-static int wireless_seq_open(struct inode *inode, struct file *file)
+static int seq_open_wireless(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &wireless_seq_ops,
sizeof(struct seq_net_private));
@@ -664,7 +676,7 @@ static int wireless_seq_open(struct inode *inode, struct file *file)
static const struct file_operations wireless_seq_fops = {
.owner = THIS_MODULE,
- .open = wireless_seq_open,
+ .open = seq_open_wireless,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
diff --git a/samples/Kconfig b/samples/Kconfig
index 4b02f5a0e656..b75d28cba3f7 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -19,6 +19,12 @@ config SAMPLE_TRACEPOINTS
help
This build tracepoints example modules.
+config SAMPLE_TRACE_EVENTS
+ tristate "Build trace_events examples -- loadable modules only"
+ depends on EVENT_TRACING && m
+ help
+ This build trace event example modules.
+
config SAMPLE_KOBJECT
tristate "Build kobject examples"
help
diff --git a/samples/Makefile b/samples/Makefile
index 10eaca89fe17..13e4b470b539 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,3 +1,3 @@
# Makefile for Linux samples code
-obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/ tracepoints/
+obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/ tracepoints/ trace_events/
diff --git a/samples/trace_events/Makefile b/samples/trace_events/Makefile
new file mode 100644
index 000000000000..0d428dc67283
--- /dev/null
+++ b/samples/trace_events/Makefile
@@ -0,0 +1,6 @@
+# builds the trace events example kernel modules;
+# then to use one (as root): insmod <module_name.ko>
+
+CFLAGS_trace-events-sample.o := -I$(src)
+
+obj-$(CONFIG_SAMPLE_TRACE_EVENTS) += trace-events-sample.o
diff --git a/samples/trace_events/trace-events-sample.c b/samples/trace_events/trace-events-sample.c
new file mode 100644
index 000000000000..aabc4e970911
--- /dev/null
+++ b/samples/trace_events/trace-events-sample.c
@@ -0,0 +1,52 @@
+#include <linux/module.h>
+#include <linux/kthread.h>
+
+/*
+ * Any file that uses trace points, must include the header.
+ * But only one file, must include the header by defining
+ * CREATE_TRACE_POINTS first. This will make the C code that
+ * creates the handles for the trace points.
+ */
+#define CREATE_TRACE_POINTS
+#include "trace-events-sample.h"
+
+
+static void simple_thread_func(int cnt)
+{
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ trace_foo_bar("hello", cnt);
+}
+
+static int simple_thread(void *arg)
+{
+ int cnt = 0;
+
+ while (!kthread_should_stop())
+ simple_thread_func(cnt++);
+
+ return 0;
+}
+
+static struct task_struct *simple_tsk;
+
+static int __init trace_event_init(void)
+{
+ simple_tsk = kthread_run(simple_thread, NULL, "event-sample");
+ if (IS_ERR(simple_tsk))
+ return -1;
+
+ return 0;
+}
+
+static void __exit trace_event_exit(void)
+{
+ kthread_stop(simple_tsk);
+}
+
+module_init(trace_event_init);
+module_exit(trace_event_exit);
+
+MODULE_AUTHOR("Steven Rostedt");
+MODULE_DESCRIPTION("trace-events-sample");
+MODULE_LICENSE("GPL");
diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h
new file mode 100644
index 000000000000..128a897687c5
--- /dev/null
+++ b/samples/trace_events/trace-events-sample.h
@@ -0,0 +1,129 @@
+/*
+ * Notice that this file is not protected like a normal header.
+ * We also must allow for rereading of this file. The
+ *
+ * || defined(TRACE_HEADER_MULTI_READ)
+ *
+ * serves this purpose.
+ */
+#if !defined(_TRACE_EVENT_SAMPLE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_EVENT_SAMPLE_H
+
+/*
+ * All trace headers should include tracepoint.h, until we finally
+ * make it into a standard header.
+ */
+#include <linux/tracepoint.h>
+
+/*
+ * If TRACE_SYSTEM is defined, that will be the directory created
+ * in the ftrace directory under /debugfs/tracing/events/<system>
+ *
+ * The define_trace.h belowe will also look for a file name of
+ * TRACE_SYSTEM.h where TRACE_SYSTEM is what is defined here.
+ *
+ * If you want a different system than file name, you can override
+ * the header name by defining TRACE_INCLUDE_FILE
+ *
+ * If this file was called, goofy.h, then we would define:
+ *
+ * #define TRACE_INCLUDE_FILE goofy
+ *
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sample
+
+/*
+ * The TRACE_EVENT macro is broken up into 5 parts.
+ *
+ * name: name of the trace point. This is also how to enable the tracepoint.
+ * A function called trace_foo_bar() will be created.
+ *
+ * proto: the prototype of the function trace_foo_bar()
+ * Here it is trace_foo_bar(char *foo, int bar).
+ *
+ * args: must match the arguments in the prototype.
+ * Here it is simply "foo, bar".
+ *
+ * struct: This defines the way the data will be stored in the ring buffer.
+ * There are currently two types of elements. __field and __array.
+ * a __field is broken up into (type, name). Where type can be any
+ * type but an array.
+ * For an array. there are three fields. (type, name, size). The
+ * type of elements in the array, the name of the field and the size
+ * of the array.
+ *
+ * __array( char, foo, 10) is the same as saying char foo[10].
+ *
+ * fast_assign: This is a C like function that is used to store the items
+ * into the ring buffer.
+ *
+ * printk: This is a way to print out the data in pretty print. This is
+ * useful if the system crashes and you are logging via a serial line,
+ * the data can be printed to the console using this "printk" method.
+ *
+ * Note, that for both the assign and the printk, __entry is the handler
+ * to the data structure in the ring buffer, and is defined by the
+ * TP_STRUCT__entry.
+ */
+TRACE_EVENT(foo_bar,
+
+ TP_PROTO(char *foo, int bar),
+
+ TP_ARGS(foo, bar),
+
+ TP_STRUCT__entry(
+ __array( char, foo, 10 )
+ __field( int, bar )
+ ),
+
+ TP_fast_assign(
+ strncpy(__entry->foo, foo, 10);
+ __entry->bar = bar;
+ ),
+
+ TP_printk("foo %s %d", __entry->foo, __entry->bar)
+);
+#endif
+
+/***** NOTICE! The #if protection ends here. *****/
+
+
+/*
+ * There are several ways I could have done this. If I left out the
+ * TRACE_INCLUDE_PATH, then it would default to the kernel source
+ * include/trace/events directory.
+ *
+ * I could specify a path from the define_trace.h file back to this
+ * file.
+ *
+ * #define TRACE_INCLUDE_PATH ../../samples/trace_events
+ *
+ * But I chose to simply make it use the current directory and then in
+ * the Makefile I added:
+ *
+ * CFLAGS_trace-events-sample.o := -I$(PWD)/samples/trace_events/
+ *
+ * This will make sure the current path is part of the include
+ * structure for our file so that we can find it.
+ *
+ * I could have made only the top level directory the include:
+ *
+ * CFLAGS_trace-events-sample.o := -I$(PWD)
+ *
+ * And then let the path to this directory be the TRACE_INCLUDE_PATH:
+ *
+ * #define TRACE_INCLUDE_PATH samples/trace_events
+ *
+ * But then if something defines "samples" or "trace_events" then we
+ * could risk that being converted too, and give us an unexpected
+ * result.
+ */
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+/*
+ * TRACE_INCLUDE_FILE is not needed if the filename and TRACE_SYSTEM are equal
+ */
+#define TRACE_INCLUDE_FILE trace-events-sample
+#include <trace/define_trace.h>
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index cba61ca403ca..2b706617c89a 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -188,20 +188,34 @@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
# ---------------------------------------------------------------------------
quiet_cmd_gzip = GZIP $@
-cmd_gzip = gzip -f -9 < $< > $@
+cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \
+ (rm -f $@ ; false)
# Bzip2
# ---------------------------------------------------------------------------
-# Bzip2 does not include size in file... so we have to fake that
-size_append=$(CONFIG_SHELL) $(srctree)/scripts/bin_size
-
-quiet_cmd_bzip2 = BZIP2 $@
-cmd_bzip2 = (bzip2 -9 < $< && $(size_append) $<) > $@ || (rm -f $@ ; false)
+# Bzip2 and LZMA do not include size in file... so we have to fake that;
+# append the size as a 32-bit littleendian number as gzip does.
+size_append = echo -ne $(shell \
+dec_size=0; \
+for F in $1; do \
+ fsize=$$(stat -c "%s" $$F); \
+ dec_size=$$(expr $$dec_size + $$fsize); \
+done; \
+printf "%08x" $$dec_size | \
+ sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g' \
+)
+
+quiet_cmd_bzip2 = BZIP2 $@
+cmd_bzip2 = (cat $(filter-out FORCE,$^) | \
+ bzip2 -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
+ (rm -f $@ ; false)
# Lzma
# ---------------------------------------------------------------------------
quiet_cmd_lzma = LZMA $@
-cmd_lzma = (lzma -9 -c $< && $(size_append) $<) >$@ || (rm -f $@ ; false)
+cmd_lzma = (cat $(filter-out FORCE,$^) | \
+ lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
+ (rm -f $@ ; false)
diff --git a/scripts/bin_size b/scripts/bin_size
deleted file mode 100644
index 43e1b360cee6..000000000000
--- a/scripts/bin_size
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-if [ $# = 0 ] ; then
- echo Usage: $0 file
-fi
-
-size_dec=`stat -c "%s" $1`
-size_hex_echo_string=`printf "%08x" $size_dec |
- sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g'`
-/bin/echo -ne $size_hex_echo_string
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index b2a878c936d6..bcc6f19c3a35 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -41,7 +41,8 @@ static void print_item(WINDOW * win, int choice, int selected)
wmove(win, choice, check_x);
wattrset(win, selected ? dlg.check_selected.atr
: dlg.check.atr);
- wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
+ if (!item_is_tag(':'))
+ wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
mvwaddch(win, choice, item_x, item_str()[0]);
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 6841e95c0989..3bcacb4bfd3a 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -732,7 +732,12 @@ static void conf_choice(struct menu *menu)
for (child = menu->list; child; child = child->next) {
if (!menu_is_visible(child))
continue;
- item_make("%s", _(menu_get_prompt(child)));
+ if (child->sym)
+ item_make("%s", _(menu_get_prompt(child)));
+ else {
+ item_make("*** %s ***", _(menu_get_prompt(child)));
+ item_set_tag(':');
+ }
item_set_data(child);
if (child->sym == active)
item_set_selected(1);
@@ -748,6 +753,9 @@ static void conf_choice(struct menu *menu)
case 0:
if (selected) {
child = item_data();
+ if (!child->sym)
+ break;
+
sym_set_tristate_value(child->sym, yes);
}
return;
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 3208a3a7e7fe..acd8c4a8e3e0 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1828,6 +1828,25 @@ sub reset_state {
$state = 0;
}
+sub tracepoint_munge($) {
+ my $file = shift;
+ my $tracepointname = 0;
+ my $tracepointargs = 0;
+
+ if($prototype =~ m/TRACE_EVENT\((.*?),/) {
+ $tracepointname = $1;
+ }
+ if($prototype =~ m/TP_PROTO\((.*?)\)/) {
+ $tracepointargs = $1;
+ }
+ if (($tracepointname eq 0) || ($tracepointargs eq 0)) {
+ print STDERR "Warning(${file}:$.): Unrecognized tracepoint format: \n".
+ "$prototype\n";
+ } else {
+ $prototype = "static inline void trace_$tracepointname($tracepointargs)";
+ }
+}
+
sub syscall_munge() {
my $void = 0;
@@ -1882,6 +1901,9 @@ sub process_state3_function($$) {
if ($prototype =~ /SYSCALL_DEFINE/) {
syscall_munge();
}
+ if ($prototype =~ /TRACE_EVENT/) {
+ tracepoint_munge($file);
+ }
dump_function($prototype, $file);
reset_state();
}
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 1264b8e2829d..01c2d13dd020 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -1,38 +1,58 @@
#!/bin/sh
#
-# builddeb 1.2
+# builddeb 1.3
# Copyright 2003 Wichert Akkerman <wichert@wiggy.net>
#
# Simple script to generate a deb package for a Linux kernel. All the
-# complexity of what to do with a kernel after it is installer or removed
+# complexity of what to do with a kernel after it is installed or removed
# is left to other scripts and packages: they can install scripts in the
-# /etc/kernel/{pre,post}{inst,rm}.d/ directories that will be called on
-# package install and removal.
+# /etc/kernel/{pre,post}{inst,rm}.d/ directories (or an alternative location
+# specified in KDEB_HOOKDIR) that will be called on package install and
+# removal.
set -e
+create_package() {
+ local pname="$1" pdir="$2"
+
+ cp debian/copyright "$pdir/usr/share/doc/$pname/"
+
+ # Fix ownership and permissions
+ chown -R root:root "$pdir"
+ chmod -R go-w "$pdir"
+
+ # Create the package
+ dpkg-gencontrol -isp -p$pname -P"$pdir"
+ dpkg --build "$pdir" ..
+}
+
# Some variables and settings used throughout the script
version=$KERNELRELEASE
-revision=`cat .version`
+revision=$(cat .version)
+if [ -n "$KDEB_PKGVERSION" ]; then
+ packageversion=$KDEB_PKGVERSION
+else
+ packageversion=$version-$revision
+fi
tmpdir="$objtree/debian/tmp"
fwdir="$objtree/debian/fwtmp"
-packagename=linux-$version
+packagename=linux-image-$version
fwpackagename=linux-firmware-image
-if [ "$ARCH" == "um" ] ; then
+if [ "$ARCH" = "um" ] ; then
packagename=user-mode-linux-$version
fi
# Setup the directory structure
rm -rf "$tmpdir" "$fwdir"
-mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot"
-mkdir -p "$fwdir/DEBIAN" "$fwdir/lib"
-if [ "$ARCH" == "um" ] ; then
- mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/share/doc/$packagename" "$tmpdir/usr/bin"
+mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename"
+mkdir -p "$fwdir/DEBIAN" "$fwdir/lib" "$fwdir/usr/share/doc/$fwpackagename"
+if [ "$ARCH" = "um" ] ; then
+ mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/bin"
fi
# Build and install the kernel
-if [ "$ARCH" == "um" ] ; then
+if [ "$ARCH" = "um" ] ; then
$MAKE linux
cp System.map "$tmpdir/usr/lib/uml/modules/$version/System.map"
cp .config "$tmpdir/usr/share/doc/$packagename/config"
@@ -41,53 +61,100 @@ if [ "$ARCH" == "um" ] ; then
else
cp System.map "$tmpdir/boot/System.map-$version"
cp .config "$tmpdir/boot/config-$version"
- cp $KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"
+ # Not all arches include the boot path in KBUILD_IMAGE
+ if ! cp $KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"; then
+ cp arch/$ARCH/boot/$KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"
+ fi
fi
if grep -q '^CONFIG_MODULES=y' .config ; then
INSTALL_MOD_PATH="$tmpdir" make KBUILD_SRC= modules_install
- if [ "$ARCH" == "um" ] ; then
+ if [ "$ARCH" = "um" ] ; then
mv "$tmpdir/lib/modules/$version"/* "$tmpdir/usr/lib/uml/modules/$version/"
rmdir "$tmpdir/lib/modules/$version"
fi
fi
# Install the maintainer scripts
+# Note: hook scripts under /etc/kernel are also executed by official Debian
+# kernel packages, as well as kernel packages built using make-kpkg
+debhookdir=${KDEB_HOOKDIR:-/etc/kernel}
for script in postinst postrm preinst prerm ; do
- mkdir -p "$tmpdir/etc/kernel/$script.d"
+ mkdir -p "$tmpdir$debhookdir/$script.d"
cat <<EOF > "$tmpdir/DEBIAN/$script"
#!/bin/sh
set -e
-test -d /etc/kernel/$script.d && run-parts --arg="$version" /etc/kernel/$script.d
+# Pass maintainer script parameters to hook scripts
+export DEB_MAINT_PARAMS="\$@"
+
+test -d $debhookdir/$script.d && run-parts --arg="$version" $debhookdir/$script.d
exit 0
EOF
chmod 755 "$tmpdir/DEBIAN/$script"
done
-name="Kernel Compiler <$(id -nu)@$(hostname -f)>"
+# Try to determine maintainer and email values
+if [ -n "$DEBEMAIL" ]; then
+ email=$DEBEMAIL
+elif [ -n "$EMAIL" ]; then
+ email=$EMAIL
+else
+ email=$(id -nu)@$(hostname -f)
+fi
+if [ -n "$DEBFULLNAME" ]; then
+ name=$DEBFULLNAME
+elif [ -n "$NAME" ]; then
+ name=$NAME
+else
+ name="Anonymous"
+fi
+maintainer="$name <$email>"
+
# Generate a simple changelog template
cat <<EOF > debian/changelog
-linux ($version-$revision) unstable; urgency=low
+linux-upstream ($packageversion) unstable; urgency=low
- * A standard release
+ * Custom built Linux kernel.
- -- $name $(date -R)
+ -- $maintainer $(date -R)
EOF
-# Generate a control file
-if [ "$ARCH" == "um" ]; then
+# Generate copyright file
+cat <<EOF > debian/copyright
+This is a packacked upstream version of the Linux kernel.
+
+The sources may be found at most Linux ftp sites, including:
+ftp://ftp.kernel.org/pub/linux/kernel
+Copyright: 1991 - 2009 Linus Torvalds and others.
+
+The git repository for mainline kernel development is at:
+git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
+
+ 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 dated June, 1991.
+
+On Debian GNU/Linux systems, the complete text of the GNU General Public
+License version 2 can be found in \`/usr/share/common-licenses/GPL-2'.
+EOF
+
+# Generate a control file
cat <<EOF > debian/control
-Source: linux
-Section: base
+Source: linux-upstream
+Section: admin
Priority: optional
-Maintainer: $name
-Standards-Version: 3.6.1
+Maintainer: $maintainer
+Standards-Version: 3.8.1
+EOF
+
+if [ "$ARCH" = "um" ]; then
+ cat <<EOF >> debian/control
Package: $packagename
-Provides: kernel-image-$version, linux-image-$version
+Provides: linux-image, linux-image-2.6, linux-modules-$version
Architecture: any
Description: User Mode Linux kernel, version $version
User-mode Linux is a port of the Linux kernel to its own system call
@@ -97,30 +164,22 @@ Description: User Mode Linux kernel, version $version
many other things.
.
This package contains the Linux kernel, modules and corresponding other
- files version $version
+ files, version: $version.
EOF
else
-cat <<EOF > debian/control
-Source: linux
-Section: base
-Priority: optional
-Maintainer: $name
-Standards-Version: 3.6.1
+ cat <<EOF >> debian/control
Package: $packagename
-Provides: kernel-image-$version, linux-image-$version
+Provides: linux-image, linux-image-2.6, linux-modules-$version
Suggests: $fwpackagename
Architecture: any
Description: Linux kernel, version $version
This package contains the Linux kernel, modules and corresponding other
- files version $version
+ files, version: $version.
EOF
-fi
-# Fix some ownership and permissions
-chown -R root:root "$tmpdir"
-chmod -R go-w "$tmpdir"
+fi
# Do we have firmware? Move it out of the way and build it into a package.
if [ -e "$tmpdir/lib/firmware" ]; then
@@ -131,16 +190,12 @@ if [ -e "$tmpdir/lib/firmware" ]; then
Package: $fwpackagename
Architecture: all
Description: Linux kernel firmware, version $version
- This package contains firmware from the Linux kernel, version $version
+ This package contains firmware from the Linux kernel, version $version.
EOF
- dpkg-gencontrol -isp -p$fwpackagename -P"$fwdir"
- dpkg --build "$fwdir" ..
+ create_package "$fwpackagename" "$fwdir"
fi
-# Perform the final magic
-dpkg-gencontrol -isp -p$packagename
-dpkg --build "$tmpdir" ..
+create_package "$packagename" "$tmpdir"
exit 0
-
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 409596eca124..0fae7da0529c 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -26,7 +26,7 @@
# which will also be the location of that section after final link.
# e.g.
#
-# .section ".text.sched"
+# .section ".sched.text", "ax"
# .globl my_func
# my_func:
# [...]
@@ -39,7 +39,7 @@
# [...]
#
# Both relocation offsets for the mcounts in the above example will be
-# offset from .text.sched. If we make another file called tmp.s with:
+# offset from .sched.text. If we make another file called tmp.s with:
#
# .section __mcount_loc
# .quad my_func + 0x5
@@ -51,7 +51,7 @@
# But this gets hard if my_func is not globl (a static function).
# In such a case we have:
#
-# .section ".text.sched"
+# .section ".sched.text", "ax"
# my_func:
# [...]
# call mcount (offset: 0x5)
diff --git a/security/Makefile b/security/Makefile
index fa77021d9778..c67557cdaa85 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -16,6 +16,9 @@ obj-$(CONFIG_SECURITYFS) += inode.o
# Must precede capability.o in order to stack properly.
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
+ifeq ($(CONFIG_AUDIT),y)
+obj-$(CONFIG_SECURITY_SMACK) += lsm_audit.o
+endif
obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
diff --git a/security/commoncap.c b/security/commoncap.c
index beac0258c2a8..48b7e0228fa3 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -28,6 +28,28 @@
#include <linux/prctl.h>
#include <linux/securebits.h>
+/*
+ * If a non-root user executes a setuid-root binary in
+ * !secure(SECURE_NOROOT) mode, then we raise capabilities.
+ * However if fE is also set, then the intent is for only
+ * the file capabilities to be applied, and the setuid-root
+ * bit is left on either to change the uid (plausible) or
+ * to get full privilege on a kernel without file capabilities
+ * support. So in that case we do not raise capabilities.
+ *
+ * Warn if that happens, once per boot.
+ */
+static void warn_setuid_and_fcaps_mixed(char *fname)
+{
+ static int warned;
+ if (!warned) {
+ printk(KERN_INFO "warning: `%s' has both setuid-root and"
+ " effective capabilities. Therefore not raising all"
+ " capabilities.\n", fname);
+ warned = 1;
+ }
+}
+
int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
{
NETLINK_CB(skb).eff_cap = current_cap();
@@ -464,6 +486,15 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
if (!issecure(SECURE_NOROOT)) {
/*
+ * If the legacy file capability is set, then don't set privs
+ * for a setuid root binary run by a non-root user. Do set it
+ * for a root user just to cause least surprise to an admin.
+ */
+ if (effective && new->uid != 0 && new->euid == 0) {
+ warn_setuid_and_fcaps_mixed(bprm->filename);
+ goto skip;
+ }
+ /*
* To support inheritance of root-permissions and suid-root
* executables under compatibility mode, we override the
* capability sets for the file.
@@ -478,6 +509,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
if (new->euid == 0)
effective = true;
}
+skip:
/* Don't let someone trace a set[ug]id/setpcap binary with the revised
* credentials unless they have the appropriate permit
diff --git a/security/inode.c b/security/inode.c
index f3b91bfbe4cb..f7496c6a022b 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -287,7 +287,7 @@ void securityfs_remove(struct dentry *dentry)
{
struct dentry *parent;
- if (!dentry)
+ if (!dentry || IS_ERR(dentry))
return;
parent = dentry->d_parent;
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
index 1e082bb987be..ff513ff737f5 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/ima/ima_audit.c
@@ -22,18 +22,9 @@ static int ima_audit;
static int __init ima_audit_setup(char *str)
{
unsigned long audit;
- int rc, result = 0;
- char *op = "ima_audit";
- char *cause;
- rc = strict_strtoul(str, 0, &audit);
- if (rc || audit > 1)
- result = 1;
- else
- ima_audit = audit;
- cause = ima_audit ? "enabled" : "not_enabled";
- integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
- op, cause, result, 0);
+ if (!strict_strtoul(str, 0, &audit))
+ ima_audit = audit ? 1 : 0;
return 1;
}
__setup("ima_audit=", ima_audit_setup);
@@ -50,23 +41,14 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
audit_log_format(ab, "integrity: pid=%d uid=%u auid=%u ses=%u",
- current->pid, current->cred->uid,
+ current->pid, current_cred()->uid,
audit_get_loginuid(current),
audit_get_sessionid(current));
audit_log_task_context(ab);
- switch (audit_msgno) {
- case AUDIT_INTEGRITY_DATA:
- case AUDIT_INTEGRITY_METADATA:
- case AUDIT_INTEGRITY_PCR:
- case AUDIT_INTEGRITY_STATUS:
- audit_log_format(ab, " op=%s cause=%s", op, cause);
- break;
- case AUDIT_INTEGRITY_HASH:
- audit_log_format(ab, " op=%s hash=%s", op, cause);
- break;
- default:
- audit_log_format(ab, " op=%s", op);
- }
+ audit_log_format(ab, " op=");
+ audit_log_string(ab, op);
+ audit_log_format(ab, " cause=");
+ audit_log_string(ab, cause);
audit_log_format(ab, " comm=");
audit_log_untrustedstring(ab, current->comm);
if (fname) {
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index ffbe259700b1..510186f0b72e 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -84,8 +84,8 @@ static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
* against concurrent list-extension
*/
rcu_read_lock();
- qe = list_entry(rcu_dereference(qe->later.next),
- struct ima_queue_entry, later);
+ qe = list_entry_rcu(qe->later.next,
+ struct ima_queue_entry, later);
rcu_read_unlock();
(*pos)++;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index f4e7266f5aee..c4228c0eb2d0 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -29,20 +29,8 @@ int ima_initialized;
char *ima_hash = "sha1";
static int __init hash_setup(char *str)
{
- const char *op = "hash_setup";
- const char *hash = "sha1";
- int result = 0;
- int audit_info = 0;
-
- if (strncmp(str, "md5", 3) == 0) {
- hash = "md5";
- ima_hash = str;
- } else if (strncmp(str, "sha1", 4) != 0) {
- hash = "invalid_hash_type";
- result = 1;
- }
- integrity_audit_msg(AUDIT_INTEGRITY_HASH, NULL, NULL, op, hash,
- result, audit_info);
+ if (strncmp(str, "md5", 3) == 0)
+ ima_hash = "md5";
return 1;
}
__setup("ima_hash=", hash_setup);
@@ -128,10 +116,6 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
{
int rc = 0;
- if (IS_ERR(file)) {
- pr_info("%s dentry_open failed\n", filename);
- return rc;
- }
iint->opencount++;
iint->readcount++;
@@ -196,7 +180,14 @@ int ima_path_check(struct path *path, int mask)
struct dentry *dentry = dget(path->dentry);
struct vfsmount *mnt = mntget(path->mnt);
- file = dentry_open(dentry, mnt, O_RDONLY, current->cred);
+ file = dentry_open(dentry, mnt, O_RDONLY | O_LARGEFILE,
+ current_cred());
+ if (IS_ERR(file)) {
+ pr_info("%s dentry_open failed\n", dentry->d_name.name);
+ rc = PTR_ERR(file);
+ file = NULL;
+ goto out;
+ }
rc = get_path_measurement(iint, file, dentry->d_name.name);
}
out:
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index b5291ad5ef56..b168c1d595ce 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -96,7 +96,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
if ((rule->flags & IMA_UID) && rule->uid != tsk->cred->uid)
return false;
for (i = 0; i < MAX_LSM_RULES; i++) {
- int rc;
+ int rc = 0;
u32 osid, sid;
if (!rule->lsm[i].rule)
@@ -109,7 +109,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
security_inode_getsecid(inode, &osid);
rc = security_filter_rule_match(osid,
rule->lsm[i].type,
- AUDIT_EQUAL,
+ Audit_equal,
rule->lsm[i].rule,
NULL);
break;
@@ -119,7 +119,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
security_task_getsecid(tsk, &sid);
rc = security_filter_rule_match(sid,
rule->lsm[i].type,
- AUDIT_EQUAL,
+ Audit_equal,
rule->lsm[i].rule,
NULL);
default:
@@ -227,7 +227,7 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
entry->lsm[lsm_rule].type = audit_type;
result = security_filter_rule_init(entry->lsm[lsm_rule].type,
- AUDIT_EQUAL, args,
+ Audit_equal, args,
&entry->lsm[lsm_rule].rule);
return result;
}
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
new file mode 100644
index 000000000000..94b868494b31
--- /dev/null
+++ b/security/lsm_audit.c
@@ -0,0 +1,386 @@
+/*
+ * common LSM auditing functions
+ *
+ * Based on code written for SELinux by :
+ * Stephen Smalley, <sds@epoch.ncsc.mil>
+ * James Morris <jmorris@redhat.com>
+ * Author : Etienne Basset, <etienne.basset@ensta.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/types.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <net/sock.h>
+#include <linux/un.h>
+#include <net/af_unix.h>
+#include <linux/audit.h>
+#include <linux/ipv6.h>
+#include <linux/ip.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <linux/dccp.h>
+#include <linux/sctp.h>
+#include <linux/lsm_audit.h>
+
+/**
+ * ipv4_skb_to_auditdata : fill auditdata from skb
+ * @skb : the skb
+ * @ad : the audit data to fill
+ * @proto : the layer 4 protocol
+ *
+ * return 0 on success
+ */
+int ipv4_skb_to_auditdata(struct sk_buff *skb,
+ struct common_audit_data *ad, u8 *proto)
+{
+ int ret = 0;
+ struct iphdr *ih;
+
+ ih = ip_hdr(skb);
+ if (ih == NULL)
+ return -EINVAL;
+
+ ad->u.net.v4info.saddr = ih->saddr;
+ ad->u.net.v4info.daddr = ih->daddr;
+
+ if (proto)
+ *proto = ih->protocol;
+ /* non initial fragment */
+ if (ntohs(ih->frag_off) & IP_OFFSET)
+ return 0;
+
+ switch (ih->protocol) {
+ case IPPROTO_TCP: {
+ struct tcphdr *th = tcp_hdr(skb);
+ if (th == NULL)
+ break;
+
+ ad->u.net.sport = th->source;
+ ad->u.net.dport = th->dest;
+ break;
+ }
+ case IPPROTO_UDP: {
+ struct udphdr *uh = udp_hdr(skb);
+ if (uh == NULL)
+ break;
+
+ ad->u.net.sport = uh->source;
+ ad->u.net.dport = uh->dest;
+ break;
+ }
+ case IPPROTO_DCCP: {
+ struct dccp_hdr *dh = dccp_hdr(skb);
+ if (dh == NULL)
+ break;
+
+ ad->u.net.sport = dh->dccph_sport;
+ ad->u.net.dport = dh->dccph_dport;
+ break;
+ }
+ case IPPROTO_SCTP: {
+ struct sctphdr *sh = sctp_hdr(skb);
+ if (sh == NULL)
+ break;
+ ad->u.net.sport = sh->source;
+ ad->u.net.dport = sh->dest;
+ break;
+ }
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+/**
+ * ipv6_skb_to_auditdata : fill auditdata from skb
+ * @skb : the skb
+ * @ad : the audit data to fill
+ * @proto : the layer 4 protocol
+ *
+ * return 0 on success
+ */
+int ipv6_skb_to_auditdata(struct sk_buff *skb,
+ struct common_audit_data *ad, u8 *proto)
+{
+ int offset, ret = 0;
+ struct ipv6hdr *ip6;
+ u8 nexthdr;
+
+ ip6 = ipv6_hdr(skb);
+ if (ip6 == NULL)
+ return -EINVAL;
+ ipv6_addr_copy(&ad->u.net.v6info.saddr, &ip6->saddr);
+ ipv6_addr_copy(&ad->u.net.v6info.daddr, &ip6->daddr);
+ ret = 0;
+ /* IPv6 can have several extension header before the Transport header
+ * skip them */
+ offset = skb_network_offset(skb);
+ offset += sizeof(*ip6);
+ nexthdr = ip6->nexthdr;
+ offset = ipv6_skip_exthdr(skb, offset, &nexthdr);
+ if (offset < 0)
+ return 0;
+ if (proto)
+ *proto = nexthdr;
+ switch (nexthdr) {
+ case IPPROTO_TCP: {
+ struct tcphdr _tcph, *th;
+
+ th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
+ if (th == NULL)
+ break;
+
+ ad->u.net.sport = th->source;
+ ad->u.net.dport = th->dest;
+ break;
+ }
+ case IPPROTO_UDP: {
+ struct udphdr _udph, *uh;
+
+ uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
+ if (uh == NULL)
+ break;
+
+ ad->u.net.sport = uh->source;
+ ad->u.net.dport = uh->dest;
+ break;
+ }
+ case IPPROTO_DCCP: {
+ struct dccp_hdr _dccph, *dh;
+
+ dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
+ if (dh == NULL)
+ break;
+
+ ad->u.net.sport = dh->dccph_sport;
+ ad->u.net.dport = dh->dccph_dport;
+ break;
+ }
+ case IPPROTO_SCTP: {
+ struct sctphdr _sctph, *sh;
+
+ sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
+ if (sh == NULL)
+ break;
+ ad->u.net.sport = sh->source;
+ ad->u.net.dport = sh->dest;
+ break;
+ }
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif
+
+
+static inline void print_ipv6_addr(struct audit_buffer *ab,
+ struct in6_addr *addr, __be16 port,
+ char *name1, char *name2)
+{
+ if (!ipv6_addr_any(addr))
+ audit_log_format(ab, " %s=%pI6", name1, addr);
+ if (port)
+ audit_log_format(ab, " %s=%d", name2, ntohs(port));
+}
+
+static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
+ __be16 port, char *name1, char *name2)
+{
+ if (addr)
+ audit_log_format(ab, " %s=%pI4", name1, &addr);
+ if (port)
+ audit_log_format(ab, " %s=%d", name2, ntohs(port));
+}
+
+/**
+ * dump_common_audit_data - helper to dump common audit data
+ * @a : common audit data
+ *
+ */
+static void dump_common_audit_data(struct audit_buffer *ab,
+ struct common_audit_data *a)
+{
+ struct inode *inode = NULL;
+ struct task_struct *tsk = current;
+
+ if (a->tsk)
+ tsk = a->tsk;
+ if (tsk && tsk->pid) {
+ audit_log_format(ab, " pid=%d comm=", tsk->pid);
+ audit_log_untrustedstring(ab, tsk->comm);
+ }
+
+ switch (a->type) {
+ case LSM_AUDIT_DATA_IPC:
+ audit_log_format(ab, " key=%d ", a->u.ipc_id);
+ break;
+ case LSM_AUDIT_DATA_CAP:
+ audit_log_format(ab, " capability=%d ", a->u.cap);
+ break;
+ case LSM_AUDIT_DATA_FS:
+ if (a->u.fs.path.dentry) {
+ struct dentry *dentry = a->u.fs.path.dentry;
+ if (a->u.fs.path.mnt) {
+ audit_log_d_path(ab, "path=", &a->u.fs.path);
+ } else {
+ audit_log_format(ab, " name=");
+ audit_log_untrustedstring(ab,
+ dentry->d_name.name);
+ }
+ inode = dentry->d_inode;
+ } else if (a->u.fs.inode) {
+ struct dentry *dentry;
+ inode = a->u.fs.inode;
+ dentry = d_find_alias(inode);
+ if (dentry) {
+ audit_log_format(ab, " name=");
+ audit_log_untrustedstring(ab,
+ dentry->d_name.name);
+ dput(dentry);
+ }
+ }
+ if (inode)
+ audit_log_format(ab, " dev=%s ino=%lu",
+ inode->i_sb->s_id,
+ inode->i_ino);
+ break;
+ case LSM_AUDIT_DATA_TASK:
+ tsk = a->u.tsk;
+ if (tsk && tsk->pid) {
+ audit_log_format(ab, " pid=%d comm=", tsk->pid);
+ audit_log_untrustedstring(ab, tsk->comm);
+ }
+ break;
+ case LSM_AUDIT_DATA_NET:
+ if (a->u.net.sk) {
+ struct sock *sk = a->u.net.sk;
+ struct unix_sock *u;
+ int len = 0;
+ char *p = NULL;
+
+ switch (sk->sk_family) {
+ case AF_INET: {
+ struct inet_sock *inet = inet_sk(sk);
+
+ print_ipv4_addr(ab, inet->rcv_saddr,
+ inet->sport,
+ "laddr", "lport");
+ print_ipv4_addr(ab, inet->daddr,
+ inet->dport,
+ "faddr", "fport");
+ break;
+ }
+ case AF_INET6: {
+ struct inet_sock *inet = inet_sk(sk);
+ struct ipv6_pinfo *inet6 = inet6_sk(sk);
+
+ print_ipv6_addr(ab, &inet6->rcv_saddr,
+ inet->sport,
+ "laddr", "lport");
+ print_ipv6_addr(ab, &inet6->daddr,
+ inet->dport,
+ "faddr", "fport");
+ break;
+ }
+ case AF_UNIX:
+ u = unix_sk(sk);
+ if (u->dentry) {
+ struct path path = {
+ .dentry = u->dentry,
+ .mnt = u->mnt
+ };
+ audit_log_d_path(ab, "path=", &path);
+ break;
+ }
+ if (!u->addr)
+ break;
+ len = u->addr->len-sizeof(short);
+ p = &u->addr->name->sun_path[0];
+ audit_log_format(ab, " path=");
+ if (*p)
+ audit_log_untrustedstring(ab, p);
+ else
+ audit_log_n_hex(ab, p, len);
+ break;
+ }
+ }
+
+ switch (a->u.net.family) {
+ case AF_INET:
+ print_ipv4_addr(ab, a->u.net.v4info.saddr,
+ a->u.net.sport,
+ "saddr", "src");
+ print_ipv4_addr(ab, a->u.net.v4info.daddr,
+ a->u.net.dport,
+ "daddr", "dest");
+ break;
+ case AF_INET6:
+ print_ipv6_addr(ab, &a->u.net.v6info.saddr,
+ a->u.net.sport,
+ "saddr", "src");
+ print_ipv6_addr(ab, &a->u.net.v6info.daddr,
+ a->u.net.dport,
+ "daddr", "dest");
+ break;
+ }
+ if (a->u.net.netif > 0) {
+ struct net_device *dev;
+
+ /* NOTE: we always use init's namespace */
+ dev = dev_get_by_index(&init_net, a->u.net.netif);
+ if (dev) {
+ audit_log_format(ab, " netif=%s", dev->name);
+ dev_put(dev);
+ }
+ }
+ break;
+#ifdef CONFIG_KEYS
+ case LSM_AUDIT_DATA_KEY:
+ audit_log_format(ab, " key_serial=%u", a->u.key_struct.key);
+ if (a->u.key_struct.key_desc) {
+ audit_log_format(ab, " key_desc=");
+ audit_log_untrustedstring(ab, a->u.key_struct.key_desc);
+ }
+ break;
+#endif
+ } /* switch (a->type) */
+}
+
+/**
+ * common_lsm_audit - generic LSM auditing function
+ * @a: auxiliary audit data
+ *
+ * setup the audit buffer for common security information
+ * uses callback to print LSM specific information
+ */
+void common_lsm_audit(struct common_audit_data *a)
+{
+ struct audit_buffer *ab;
+
+ if (a == NULL)
+ return;
+ /* we use GFP_ATOMIC so we won't sleep */
+ ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
+
+ if (ab == NULL)
+ return;
+
+ if (a->lsm_pre_audit)
+ a->lsm_pre_audit(ab, a);
+
+ dump_common_audit_data(ab, a);
+
+ if (a->lsm_post_audit)
+ a->lsm_post_audit(ab, a);
+
+ audit_log_end(ab);
+}
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 7f9b5fac8779..b2ab60859832 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -927,7 +927,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
if (denied) {
if (flags & AVC_STRICT)
rc = -EACCES;
- else if (!selinux_enforcing || security_permissive_sid(ssid))
+ else if (!selinux_enforcing || (avd->flags & AVD_FLAGS_PERMISSIVE))
avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
tsid, tclass, avd->seqno);
else
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2fcad7c33eaf..195906bce266 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1980,10 +1980,6 @@ static int selinux_sysctl(ctl_table *table, int op)
u32 tsid, sid;
int rc;
- rc = secondary_ops->sysctl(table, op);
- if (rc)
- return rc;
-
sid = current_sid();
rc = selinux_sysctl_get_sid(table, (op == 0001) ?
@@ -2375,10 +2371,8 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
{
const struct task_security_struct *tsec = current_security();
struct itimerval itimer;
- struct sighand_struct *psig;
u32 osid, sid;
int rc, i;
- unsigned long flags;
osid = tsec->osid;
sid = tsec->sid;
@@ -2398,22 +2392,20 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
memset(&itimer, 0, sizeof itimer);
for (i = 0; i < 3; i++)
do_setitimer(i, &itimer, NULL);
- flush_signals(current);
spin_lock_irq(&current->sighand->siglock);
- flush_signal_handlers(current, 1);
- sigemptyset(&current->blocked);
- recalc_sigpending();
+ if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
+ __flush_signals(current);
+ flush_signal_handlers(current, 1);
+ sigemptyset(&current->blocked);
+ }
spin_unlock_irq(&current->sighand->siglock);
}
/* Wake up the parent if it is waiting so that it can recheck
* wait permission to the new task SID. */
- read_lock_irq(&tasklist_lock);
- psig = current->parent->sighand;
- spin_lock_irqsave(&psig->siglock, flags);
- wake_up_interruptible(&current->parent->signal->wait_chldexit);
- spin_unlock_irqrestore(&psig->siglock, flags);
- read_unlock_irq(&tasklist_lock);
+ read_lock(&tasklist_lock);
+ wake_up_interruptible(&current->real_parent->signal->wait_chldexit);
+ read_unlock(&tasklist_lock);
}
/* superblock security operations */
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 5c3434f7626f..a7be3f01fb08 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -91,9 +91,11 @@ struct av_decision {
u32 auditallow;
u32 auditdeny;
u32 seqno;
+ u32 flags;
};
-int security_permissive_sid(u32 sid);
+/* definitions of av_decision.flags */
+#define AVD_FLAGS_PERMISSIVE 0x0001
int security_compute_av(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 2d5136ec3d54..8d4007fbe0e9 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -527,10 +527,10 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
goto out2;
length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
- "%x %x %x %x %u",
+ "%x %x %x %x %u %x",
avd.allowed, 0xffffffff,
avd.auditallow, avd.auditdeny,
- avd.seqno);
+ avd.seqno, avd.flags);
out2:
kfree(tcon);
out:
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index deeec6c013ae..500e6f78e115 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -410,6 +410,7 @@ static int context_struct_compute_av(struct context *scontext,
avd->auditallow = 0;
avd->auditdeny = 0xffffffff;
avd->seqno = latest_granting;
+ avd->flags = 0;
/*
* Check for all the invalid cases.
@@ -528,31 +529,6 @@ inval_class:
return 0;
}
-/*
- * Given a sid find if the type has the permissive flag set
- */
-int security_permissive_sid(u32 sid)
-{
- struct context *context;
- u32 type;
- int rc;
-
- read_lock(&policy_rwlock);
-
- context = sidtab_search(&sidtab, sid);
- BUG_ON(!context);
-
- type = context->type;
- /*
- * we are intentionally using type here, not type-1, the 0th bit may
- * someday indicate that we are globally setting permissive in policy.
- */
- rc = ebitmap_get_bit(&policydb.permissive_map, type);
-
- read_unlock(&policy_rwlock);
- return rc;
-}
-
static int security_validtrans_handle_fail(struct context *ocontext,
struct context *ncontext,
struct context *tcontext,
@@ -767,6 +743,10 @@ int security_compute_av(u32 ssid,
rc = context_struct_compute_av(scontext, tcontext, tclass,
requested, avd);
+
+ /* permissive domain? */
+ if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
+ avd->flags |= AVD_FLAGS_PERMISSIVE;
out:
read_unlock(&policy_rwlock);
return rc;
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 42ef313f9856..243bec175be0 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -20,6 +20,7 @@
#include <net/netlabel.h>
#include <linux/list.h>
#include <linux/rculist.h>
+#include <linux/lsm_audit.h>
/*
* Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
@@ -179,6 +180,20 @@ struct smack_known {
#define MAY_NOT 0
/*
+ * Number of access types used by Smack (rwxa)
+ */
+#define SMK_NUM_ACCESS_TYPE 4
+
+/*
+ * Smack audit data; is empty if CONFIG_AUDIT not set
+ * to save some stack
+ */
+struct smk_audit_info {
+#ifdef CONFIG_AUDIT
+ struct common_audit_data a;
+#endif
+};
+/*
* These functions are in smack_lsm.c
*/
struct inode_smack *new_inode_smack(char *);
@@ -186,8 +201,8 @@ struct inode_smack *new_inode_smack(char *);
/*
* These functions are in smack_access.c
*/
-int smk_access(char *, char *, int);
-int smk_curacc(char *, u32);
+int smk_access(char *, char *, int, struct smk_audit_info *);
+int smk_curacc(char *, u32, struct smk_audit_info *);
int smack_to_cipso(const char *, struct smack_cipso *);
void smack_from_cipso(u32, char *, char *);
char *smack_from_secid(const u32);
@@ -237,4 +252,93 @@ static inline char *smk_of_inode(const struct inode *isp)
return sip->smk_inode;
}
+/*
+ * logging functions
+ */
+#define SMACK_AUDIT_DENIED 0x1
+#define SMACK_AUDIT_ACCEPT 0x2
+extern int log_policy;
+
+void smack_log(char *subject_label, char *object_label,
+ int request,
+ int result, struct smk_audit_info *auditdata);
+
+#ifdef CONFIG_AUDIT
+
+/*
+ * some inline functions to set up audit data
+ * they do nothing if CONFIG_AUDIT is not set
+ *
+ */
+static inline void smk_ad_init(struct smk_audit_info *a, const char *func,
+ char type)
+{
+ memset(a, 0, sizeof(*a));
+ a->a.type = type;
+ a->a.function = func;
+}
+
+static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a,
+ struct task_struct *t)
+{
+ a->a.u.tsk = t;
+}
+static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a,
+ struct dentry *d)
+{
+ a->a.u.fs.path.dentry = d;
+}
+static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a,
+ struct vfsmount *m)
+{
+ a->a.u.fs.path.mnt = m;
+}
+static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a,
+ struct inode *i)
+{
+ a->a.u.fs.inode = i;
+}
+static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
+ struct path p)
+{
+ a->a.u.fs.path = p;
+}
+static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
+ struct sock *sk)
+{
+ a->a.u.net.sk = sk;
+}
+
+#else /* no AUDIT */
+
+static inline void smk_ad_init(struct smk_audit_info *a, const char *func,
+ char type)
+{
+}
+static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a,
+ struct task_struct *t)
+{
+}
+static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a,
+ struct dentry *d)
+{
+}
+static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a,
+ struct vfsmount *m)
+{
+}
+static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a,
+ struct inode *i)
+{
+}
+static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
+ struct path p)
+{
+}
+static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
+ struct sock *sk)
+{
+}
+#endif
+
#endif /* _SECURITY_SMACK_H */
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index ac0a2707f6d4..513dc1aa16dd 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -59,11 +59,18 @@ LIST_HEAD(smack_known_list);
*/
static u32 smack_next_secid = 10;
+/*
+ * what events do we log
+ * can be overwritten at run-time by /smack/logging
+ */
+int log_policy = SMACK_AUDIT_DENIED;
+
/**
* smk_access - determine if a subject has a specific access to an object
* @subject_label: a pointer to the subject's Smack label
* @object_label: a pointer to the object's Smack label
* @request: the access requested, in "MAY" format
+ * @a : a pointer to the audit data
*
* This function looks up the subject/object pair in the
* access rule list and returns 0 if the access is permitted,
@@ -78,10 +85,12 @@ static u32 smack_next_secid = 10;
* will be on the list, so checking the pointers may be a worthwhile
* optimization.
*/
-int smk_access(char *subject_label, char *object_label, int request)
+int smk_access(char *subject_label, char *object_label, int request,
+ struct smk_audit_info *a)
{
u32 may = MAY_NOT;
struct smack_rule *srp;
+ int rc = 0;
/*
* Hardcoded comparisons.
@@ -89,8 +98,10 @@ int smk_access(char *subject_label, char *object_label, int request)
* A star subject can't access any object.
*/
if (subject_label == smack_known_star.smk_known ||
- strcmp(subject_label, smack_known_star.smk_known) == 0)
- return -EACCES;
+ strcmp(subject_label, smack_known_star.smk_known) == 0) {
+ rc = -EACCES;
+ goto out_audit;
+ }
/*
* An internet object can be accessed by any subject.
* Tasks cannot be assigned the internet label.
@@ -100,20 +111,20 @@ int smk_access(char *subject_label, char *object_label, int request)
subject_label == smack_known_web.smk_known ||
strcmp(object_label, smack_known_web.smk_known) == 0 ||
strcmp(subject_label, smack_known_web.smk_known) == 0)
- return 0;
+ goto out_audit;
/*
* A star object can be accessed by any subject.
*/
if (object_label == smack_known_star.smk_known ||
strcmp(object_label, smack_known_star.smk_known) == 0)
- return 0;
+ goto out_audit;
/*
* An object can be accessed in any way by a subject
* with the same label.
*/
if (subject_label == object_label ||
strcmp(subject_label, object_label) == 0)
- return 0;
+ goto out_audit;
/*
* A hat subject can read any object.
* A floor object can be read by any subject.
@@ -121,10 +132,10 @@ int smk_access(char *subject_label, char *object_label, int request)
if ((request & MAY_ANYREAD) == request) {
if (object_label == smack_known_floor.smk_known ||
strcmp(object_label, smack_known_floor.smk_known) == 0)
- return 0;
+ goto out_audit;
if (subject_label == smack_known_hat.smk_known ||
strcmp(subject_label, smack_known_hat.smk_known) == 0)
- return 0;
+ goto out_audit;
}
/*
* Beyond here an explicit relationship is required.
@@ -148,28 +159,36 @@ int smk_access(char *subject_label, char *object_label, int request)
* This is a bit map operation.
*/
if ((request & may) == request)
- return 0;
-
- return -EACCES;
+ goto out_audit;
+
+ rc = -EACCES;
+out_audit:
+#ifdef CONFIG_AUDIT
+ if (a)
+ smack_log(subject_label, object_label, request, rc, a);
+#endif
+ return rc;
}
/**
* smk_curacc - determine if current has a specific access to an object
* @obj_label: a pointer to the object's Smack label
* @mode: the access requested, in "MAY" format
+ * @a : common audit data
*
* This function checks the current subject label/object label pair
* in the access rule list and returns 0 if the access is permitted,
* non zero otherwise. It allows that current may have the capability
* to override the rules.
*/
-int smk_curacc(char *obj_label, u32 mode)
+int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
{
int rc;
+ char *sp = current_security();
- rc = smk_access(current_security(), obj_label, mode);
+ rc = smk_access(sp, obj_label, mode, NULL);
if (rc == 0)
- return 0;
+ goto out_audit;
/*
* Return if a specific label has been designated as the
@@ -177,14 +196,105 @@ int smk_curacc(char *obj_label, u32 mode)
* have that label.
*/
if (smack_onlycap != NULL && smack_onlycap != current->cred->security)
- return rc;
+ goto out_audit;
if (capable(CAP_MAC_OVERRIDE))
return 0;
+out_audit:
+#ifdef CONFIG_AUDIT
+ if (a)
+ smack_log(sp, obj_label, mode, rc, a);
+#endif
return rc;
}
+#ifdef CONFIG_AUDIT
+/**
+ * smack_str_from_perm : helper to transalate an int to a
+ * readable string
+ * @string : the string to fill
+ * @access : the int
+ *
+ */
+static inline void smack_str_from_perm(char *string, int access)
+{
+ int i = 0;
+ if (access & MAY_READ)
+ string[i++] = 'r';
+ if (access & MAY_WRITE)
+ string[i++] = 'w';
+ if (access & MAY_EXEC)
+ string[i++] = 'x';
+ if (access & MAY_APPEND)
+ string[i++] = 'a';
+ string[i] = '\0';
+}
+/**
+ * smack_log_callback - SMACK specific information
+ * will be called by generic audit code
+ * @ab : the audit_buffer
+ * @a : audit_data
+ *
+ */
+static void smack_log_callback(struct audit_buffer *ab, void *a)
+{
+ struct common_audit_data *ad = a;
+ struct smack_audit_data *sad = &ad->lsm_priv.smack_audit_data;
+ audit_log_format(ab, "lsm=SMACK fn=%s action=%s", ad->function,
+ sad->result ? "denied" : "granted");
+ audit_log_format(ab, " subject=");
+ audit_log_untrustedstring(ab, sad->subject);
+ audit_log_format(ab, " object=");
+ audit_log_untrustedstring(ab, sad->object);
+ audit_log_format(ab, " requested=%s", sad->request);
+}
+
+/**
+ * smack_log - Audit the granting or denial of permissions.
+ * @subject_label : smack label of the requester
+ * @object_label : smack label of the object being accessed
+ * @request: requested permissions
+ * @result: result from smk_access
+ * @a: auxiliary audit data
+ *
+ * Audit the granting or denial of permissions in accordance
+ * with the policy.
+ */
+void smack_log(char *subject_label, char *object_label, int request,
+ int result, struct smk_audit_info *ad)
+{
+ char request_buffer[SMK_NUM_ACCESS_TYPE + 1];
+ struct smack_audit_data *sad;
+ struct common_audit_data *a = &ad->a;
+
+ /* check if we have to log the current event */
+ if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
+ return;
+ if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
+ return;
+
+ if (a->function == NULL)
+ a->function = "unknown";
+
+ /* end preparing the audit data */
+ sad = &a->lsm_priv.smack_audit_data;
+ smack_str_from_perm(request_buffer, request);
+ sad->subject = subject_label;
+ sad->object = object_label;
+ sad->request = request_buffer;
+ sad->result = result;
+ a->lsm_pre_audit = smack_log_callback;
+
+ common_lsm_audit(a);
+}
+#else /* #ifdef CONFIG_AUDIT */
+void smack_log(char *subject_label, char *object_label, int request,
+ int result, struct smk_audit_info *ad)
+{
+}
+#endif
+
static DEFINE_MUTEX(smack_known_lock);
/**
@@ -209,7 +319,8 @@ struct smack_known *smk_import_entry(const char *string, int len)
if (found)
smack[i] = '\0';
else if (i >= len || string[i] > '~' || string[i] <= ' ' ||
- string[i] == '/') {
+ string[i] == '/' || string[i] == '"' ||
+ string[i] == '\\' || string[i] == '\'') {
smack[i] = '\0';
found = 1;
} else
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 98b3195347ab..0d030b4513c8 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -30,7 +30,6 @@
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
#include <linux/audit.h>
-
#include "smack.h"
#define task_security(task) (task_cred_xxx((task), security))
@@ -103,14 +102,24 @@ struct inode_smack *new_inode_smack(char *smack)
static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode)
{
int rc;
+ struct smk_audit_info ad;
+ char *sp, *tsp;
rc = cap_ptrace_may_access(ctp, mode);
if (rc != 0)
return rc;
- rc = smk_access(current_security(), task_security(ctp), MAY_READWRITE);
+ sp = current_security();
+ tsp = task_security(ctp);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+ smk_ad_setfield_u_tsk(&ad, ctp);
+
+ /* we won't log here, because rc can be overriden */
+ rc = smk_access(sp, tsp, MAY_READWRITE, NULL);
if (rc != 0 && capable(CAP_MAC_OVERRIDE))
- return 0;
+ rc = 0;
+
+ smack_log(sp, tsp, MAY_READWRITE, rc, &ad);
return rc;
}
@@ -125,14 +134,24 @@ static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode)
static int smack_ptrace_traceme(struct task_struct *ptp)
{
int rc;
+ struct smk_audit_info ad;
+ char *sp, *tsp;
rc = cap_ptrace_traceme(ptp);
if (rc != 0)
return rc;
- rc = smk_access(task_security(ptp), current_security(), MAY_READWRITE);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+ smk_ad_setfield_u_tsk(&ad, ptp);
+
+ sp = current_security();
+ tsp = task_security(ptp);
+ /* we won't log here, because rc can be overriden */
+ rc = smk_access(tsp, sp, MAY_READWRITE, NULL);
if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE))
- return 0;
+ rc = 0;
+
+ smack_log(tsp, sp, MAY_READWRITE, rc, &ad);
return rc;
}
@@ -327,8 +346,14 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
static int smack_sb_statfs(struct dentry *dentry)
{
struct superblock_smack *sbp = dentry->d_sb->s_security;
+ int rc;
+ struct smk_audit_info ad;
- return smk_curacc(sbp->smk_floor, MAY_READ);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+
+ rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
+ return rc;
}
/**
@@ -346,8 +371,12 @@ static int smack_sb_mount(char *dev_name, struct path *path,
char *type, unsigned long flags, void *data)
{
struct superblock_smack *sbp = path->mnt->mnt_sb->s_security;
+ struct smk_audit_info ad;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path(&ad, *path);
- return smk_curacc(sbp->smk_floor, MAY_WRITE);
+ return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
}
/**
@@ -361,10 +390,14 @@ static int smack_sb_mount(char *dev_name, struct path *path,
static int smack_sb_umount(struct vfsmount *mnt, int flags)
{
struct superblock_smack *sbp;
+ struct smk_audit_info ad;
- sbp = mnt->mnt_sb->s_security;
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_mountpoint);
+ smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
- return smk_curacc(sbp->smk_floor, MAY_WRITE);
+ sbp = mnt->mnt_sb->s_security;
+ return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
}
/*
@@ -441,15 +474,20 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *new_dentry)
{
- int rc;
char *isp;
+ struct smk_audit_info ad;
+ int rc;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
isp = smk_of_inode(old_dentry->d_inode);
- rc = smk_curacc(isp, MAY_WRITE);
+ rc = smk_curacc(isp, MAY_WRITE, &ad);
if (rc == 0 && new_dentry->d_inode != NULL) {
isp = smk_of_inode(new_dentry->d_inode);
- rc = smk_curacc(isp, MAY_WRITE);
+ smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
+ rc = smk_curacc(isp, MAY_WRITE, &ad);
}
return rc;
@@ -466,18 +504,24 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
{
struct inode *ip = dentry->d_inode;
+ struct smk_audit_info ad;
int rc;
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+
/*
* You need write access to the thing you're unlinking
*/
- rc = smk_curacc(smk_of_inode(ip), MAY_WRITE);
- if (rc == 0)
+ rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad);
+ if (rc == 0) {
/*
* You also need write access to the containing directory
*/
- rc = smk_curacc(smk_of_inode(dir), MAY_WRITE);
-
+ smk_ad_setfield_u_fs_path_dentry(&ad, NULL);
+ smk_ad_setfield_u_fs_inode(&ad, dir);
+ rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
+ }
return rc;
}
@@ -491,17 +535,24 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
*/
static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
{
+ struct smk_audit_info ad;
int rc;
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+
/*
* You need write access to the thing you're removing
*/
- rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
- if (rc == 0)
+ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
+ if (rc == 0) {
/*
* You also need write access to the containing directory
*/
- rc = smk_curacc(smk_of_inode(dir), MAY_WRITE);
+ smk_ad_setfield_u_fs_path_dentry(&ad, NULL);
+ smk_ad_setfield_u_fs_inode(&ad, dir);
+ rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
+ }
return rc;
}
@@ -525,15 +576,19 @@ static int smack_inode_rename(struct inode *old_inode,
{
int rc;
char *isp;
+ struct smk_audit_info ad;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
isp = smk_of_inode(old_dentry->d_inode);
- rc = smk_curacc(isp, MAY_READWRITE);
+ rc = smk_curacc(isp, MAY_READWRITE, &ad);
if (rc == 0 && new_dentry->d_inode != NULL) {
isp = smk_of_inode(new_dentry->d_inode);
- rc = smk_curacc(isp, MAY_READWRITE);
+ smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
+ rc = smk_curacc(isp, MAY_READWRITE, &ad);
}
-
return rc;
}
@@ -548,13 +603,15 @@ static int smack_inode_rename(struct inode *old_inode,
*/
static int smack_inode_permission(struct inode *inode, int mask)
{
+ struct smk_audit_info ad;
/*
* No permission to check. Existence test. Yup, it's there.
*/
if (mask == 0)
return 0;
-
- return smk_curacc(smk_of_inode(inode), mask);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_inode(&ad, inode);
+ return smk_curacc(smk_of_inode(inode), mask, &ad);
}
/**
@@ -566,13 +623,16 @@ static int smack_inode_permission(struct inode *inode, int mask)
*/
static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
{
+ struct smk_audit_info ad;
/*
* Need to allow for clearing the setuid bit.
*/
if (iattr->ia_valid & ATTR_FORCE)
return 0;
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
+ return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
}
/**
@@ -584,7 +644,12 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
*/
static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
{
- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ);
+ struct smk_audit_info ad;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+ smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
+ return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
}
/**
@@ -602,6 +667,7 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
static int smack_inode_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{
+ struct smk_audit_info ad;
int rc = 0;
if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
@@ -619,8 +685,11 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
} else
rc = cap_inode_setxattr(dentry, name, value, size, flags);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+
if (rc == 0)
- rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
+ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
return rc;
}
@@ -672,7 +741,12 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
*/
static int smack_inode_getxattr(struct dentry *dentry, const char *name)
{
- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ);
+ struct smk_audit_info ad;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+
+ return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
}
/*
@@ -686,6 +760,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
*/
static int smack_inode_removexattr(struct dentry *dentry, const char *name)
{
+ struct smk_audit_info ad;
int rc = 0;
if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
@@ -696,8 +771,10 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
} else
rc = cap_inode_removexattr(dentry, name);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
if (rc == 0)
- rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
+ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
return rc;
}
@@ -856,12 +933,16 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
int rc = 0;
+ struct smk_audit_info ad;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path(&ad, file->f_path);
if (_IOC_DIR(cmd) & _IOC_WRITE)
- rc = smk_curacc(file->f_security, MAY_WRITE);
+ rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ))
- rc = smk_curacc(file->f_security, MAY_READ);
+ rc = smk_curacc(file->f_security, MAY_READ, &ad);
return rc;
}
@@ -875,7 +956,11 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
*/
static int smack_file_lock(struct file *file, unsigned int cmd)
{
- return smk_curacc(file->f_security, MAY_WRITE);
+ struct smk_audit_info ad;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry);
+ return smk_curacc(file->f_security, MAY_WRITE, &ad);
}
/**
@@ -889,8 +974,12 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
static int smack_file_fcntl(struct file *file, unsigned int cmd,
unsigned long arg)
{
+ struct smk_audit_info ad;
int rc;
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
+ smk_ad_setfield_u_fs_path(&ad, file->f_path);
+
switch (cmd) {
case F_DUPFD:
case F_GETFD:
@@ -898,7 +987,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
case F_GETLK:
case F_GETOWN:
case F_GETSIG:
- rc = smk_curacc(file->f_security, MAY_READ);
+ rc = smk_curacc(file->f_security, MAY_READ, &ad);
break;
case F_SETFD:
case F_SETFL:
@@ -906,10 +995,10 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
case F_SETLKW:
case F_SETOWN:
case F_SETSIG:
- rc = smk_curacc(file->f_security, MAY_WRITE);
+ rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
break;
default:
- rc = smk_curacc(file->f_security, MAY_READWRITE);
+ rc = smk_curacc(file->f_security, MAY_READWRITE, &ad);
}
return rc;
@@ -944,14 +1033,21 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
{
struct file *file;
int rc;
+ char *tsp = tsk->cred->security;
+ struct smk_audit_info ad;
/*
* struct fown_struct is never outside the context of a struct file
*/
file = container_of(fown, struct file, f_owner);
- rc = smk_access(file->f_security, tsk->cred->security, MAY_WRITE);
+ /* we don't log here as rc can be overriden */
+ rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL);
if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
- return 0;
+ rc = 0;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+ smk_ad_setfield_u_tsk(&ad, tsk);
+ smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad);
return rc;
}
@@ -964,7 +1060,10 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
static int smack_file_receive(struct file *file)
{
int may = 0;
+ struct smk_audit_info ad;
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+ smk_ad_setfield_u_fs_path(&ad, file->f_path);
/*
* This code relies on bitmasks.
*/
@@ -973,7 +1072,7 @@ static int smack_file_receive(struct file *file)
if (file->f_mode & FMODE_WRITE)
may |= MAY_WRITE;
- return smk_curacc(file->f_security, may);
+ return smk_curacc(file->f_security, may, &ad);
}
/*
@@ -1053,6 +1152,22 @@ static int smack_kernel_create_files_as(struct cred *new,
}
/**
+ * smk_curacc_on_task - helper to log task related access
+ * @p: the task object
+ * @access : the access requested
+ *
+ * Return 0 if access is permitted
+ */
+static int smk_curacc_on_task(struct task_struct *p, int access)
+{
+ struct smk_audit_info ad;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+ smk_ad_setfield_u_tsk(&ad, p);
+ return smk_curacc(task_security(p), access, &ad);
+}
+
+/**
* smack_task_setpgid - Smack check on setting pgid
* @p: the task object
* @pgid: unused
@@ -1061,7 +1176,7 @@ static int smack_kernel_create_files_as(struct cred *new,
*/
static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
{
- return smk_curacc(task_security(p), MAY_WRITE);
+ return smk_curacc_on_task(p, MAY_WRITE);
}
/**
@@ -1072,7 +1187,7 @@ static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
*/
static int smack_task_getpgid(struct task_struct *p)
{
- return smk_curacc(task_security(p), MAY_READ);
+ return smk_curacc_on_task(p, MAY_READ);
}
/**
@@ -1083,7 +1198,7 @@ static int smack_task_getpgid(struct task_struct *p)
*/
static int smack_task_getsid(struct task_struct *p)
{
- return smk_curacc(task_security(p), MAY_READ);
+ return smk_curacc_on_task(p, MAY_READ);
}
/**
@@ -1111,7 +1226,7 @@ static int smack_task_setnice(struct task_struct *p, int nice)
rc = cap_task_setnice(p, nice);
if (rc == 0)
- rc = smk_curacc(task_security(p), MAY_WRITE);
+ rc = smk_curacc_on_task(p, MAY_WRITE);
return rc;
}
@@ -1128,7 +1243,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
rc = cap_task_setioprio(p, ioprio);
if (rc == 0)
- rc = smk_curacc(task_security(p), MAY_WRITE);
+ rc = smk_curacc_on_task(p, MAY_WRITE);
return rc;
}
@@ -1140,7 +1255,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
*/
static int smack_task_getioprio(struct task_struct *p)
{
- return smk_curacc(task_security(p), MAY_READ);
+ return smk_curacc_on_task(p, MAY_READ);
}
/**
@@ -1158,7 +1273,7 @@ static int smack_task_setscheduler(struct task_struct *p, int policy,
rc = cap_task_setscheduler(p, policy, lp);
if (rc == 0)
- rc = smk_curacc(task_security(p), MAY_WRITE);
+ rc = smk_curacc_on_task(p, MAY_WRITE);
return rc;
}
@@ -1170,7 +1285,7 @@ static int smack_task_setscheduler(struct task_struct *p, int policy,
*/
static int smack_task_getscheduler(struct task_struct *p)
{
- return smk_curacc(task_security(p), MAY_READ);
+ return smk_curacc_on_task(p, MAY_READ);
}
/**
@@ -1181,7 +1296,7 @@ static int smack_task_getscheduler(struct task_struct *p)
*/
static int smack_task_movememory(struct task_struct *p)
{
- return smk_curacc(task_security(p), MAY_WRITE);
+ return smk_curacc_on_task(p, MAY_WRITE);
}
/**
@@ -1199,18 +1314,23 @@ static int smack_task_movememory(struct task_struct *p)
static int smack_task_kill(struct task_struct *p, struct siginfo *info,
int sig, u32 secid)
{
+ struct smk_audit_info ad;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+ smk_ad_setfield_u_tsk(&ad, p);
/*
* Sending a signal requires that the sender
* can write the receiver.
*/
if (secid == 0)
- return smk_curacc(task_security(p), MAY_WRITE);
+ return smk_curacc(task_security(p), MAY_WRITE, &ad);
/*
* If the secid isn't 0 we're dealing with some USB IO
* specific behavior. This is not clean. For one thing
* we can't take privilege into account.
*/
- return smk_access(smack_from_secid(secid), task_security(p), MAY_WRITE);
+ return smk_access(smack_from_secid(secid), task_security(p),
+ MAY_WRITE, &ad);
}
/**
@@ -1221,11 +1341,15 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
*/
static int smack_task_wait(struct task_struct *p)
{
+ struct smk_audit_info ad;
+ char *sp = current_security();
+ char *tsp = task_security(p);
int rc;
- rc = smk_access(current_security(), task_security(p), MAY_WRITE);
+ /* we don't log here, we can be overriden */
+ rc = smk_access(sp, tsp, MAY_WRITE, NULL);
if (rc == 0)
- return 0;
+ goto out_log;
/*
* Allow the operation to succeed if either task
@@ -1239,8 +1363,12 @@ static int smack_task_wait(struct task_struct *p)
* the smack value.
*/
if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE))
- return 0;
-
+ rc = 0;
+ /* we log only if we didn't get overriden */
+ out_log:
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+ smk_ad_setfield_u_tsk(&ad, p);
+ smack_log(sp, tsp, MAY_WRITE, rc, &ad);
return rc;
}
@@ -1456,12 +1584,19 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
int sk_lbl;
char *hostsp;
struct socket_smack *ssp = sk->sk_security;
+ struct smk_audit_info ad;
rcu_read_lock();
hostsp = smack_host_label(sap);
if (hostsp != NULL) {
sk_lbl = SMACK_UNLABELED_SOCKET;
- rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE);
+#ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
+ ad.a.u.net.family = sap->sin_family;
+ ad.a.u.net.dport = sap->sin_port;
+ ad.a.u.net.v4info.daddr = sap->sin_addr.s_addr;
+#endif
+ rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad);
} else {
sk_lbl = SMACK_CIPSO_SOCKET;
rc = 0;
@@ -1657,6 +1792,25 @@ static void smack_shm_free_security(struct shmid_kernel *shp)
}
/**
+ * smk_curacc_shm : check if current has access on shm
+ * @shp : the object
+ * @access : access requested
+ *
+ * Returns 0 if current has the requested access, error code otherwise
+ */
+static int smk_curacc_shm(struct shmid_kernel *shp, int access)
+{
+ char *ssp = smack_of_shm(shp);
+ struct smk_audit_info ad;
+
+#ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
+ ad.a.u.ipc_id = shp->shm_perm.id;
+#endif
+ return smk_curacc(ssp, access, &ad);
+}
+
+/**
* smack_shm_associate - Smack access check for shm
* @shp: the object
* @shmflg: access requested
@@ -1665,11 +1819,10 @@ static void smack_shm_free_security(struct shmid_kernel *shp)
*/
static int smack_shm_associate(struct shmid_kernel *shp, int shmflg)
{
- char *ssp = smack_of_shm(shp);
int may;
may = smack_flags_to_may(shmflg);
- return smk_curacc(ssp, may);
+ return smk_curacc_shm(shp, may);
}
/**
@@ -1681,7 +1834,6 @@ static int smack_shm_associate(struct shmid_kernel *shp, int shmflg)
*/
static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
{
- char *ssp;
int may;
switch (cmd) {
@@ -1704,9 +1856,7 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
default:
return -EINVAL;
}
-
- ssp = smack_of_shm(shp);
- return smk_curacc(ssp, may);
+ return smk_curacc_shm(shp, may);
}
/**
@@ -1720,11 +1870,10 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
int shmflg)
{
- char *ssp = smack_of_shm(shp);
int may;
may = smack_flags_to_may(shmflg);
- return smk_curacc(ssp, may);
+ return smk_curacc_shm(shp, may);
}
/**
@@ -1766,6 +1915,25 @@ static void smack_sem_free_security(struct sem_array *sma)
}
/**
+ * smk_curacc_sem : check if current has access on sem
+ * @sma : the object
+ * @access : access requested
+ *
+ * Returns 0 if current has the requested access, error code otherwise
+ */
+static int smk_curacc_sem(struct sem_array *sma, int access)
+{
+ char *ssp = smack_of_sem(sma);
+ struct smk_audit_info ad;
+
+#ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
+ ad.a.u.ipc_id = sma->sem_perm.id;
+#endif
+ return smk_curacc(ssp, access, &ad);
+}
+
+/**
* smack_sem_associate - Smack access check for sem
* @sma: the object
* @semflg: access requested
@@ -1774,11 +1942,10 @@ static void smack_sem_free_security(struct sem_array *sma)
*/
static int smack_sem_associate(struct sem_array *sma, int semflg)
{
- char *ssp = smack_of_sem(sma);
int may;
may = smack_flags_to_may(semflg);
- return smk_curacc(ssp, may);
+ return smk_curacc_sem(sma, may);
}
/**
@@ -1790,7 +1957,6 @@ static int smack_sem_associate(struct sem_array *sma, int semflg)
*/
static int smack_sem_semctl(struct sem_array *sma, int cmd)
{
- char *ssp;
int may;
switch (cmd) {
@@ -1819,8 +1985,7 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd)
return -EINVAL;
}
- ssp = smack_of_sem(sma);
- return smk_curacc(ssp, may);
+ return smk_curacc_sem(sma, may);
}
/**
@@ -1837,9 +2002,7 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd)
static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
unsigned nsops, int alter)
{
- char *ssp = smack_of_sem(sma);
-
- return smk_curacc(ssp, MAY_READWRITE);
+ return smk_curacc_sem(sma, MAY_READWRITE);
}
/**
@@ -1881,6 +2044,25 @@ static char *smack_of_msq(struct msg_queue *msq)
}
/**
+ * smk_curacc_msq : helper to check if current has access on msq
+ * @msq : the msq
+ * @access : access requested
+ *
+ * return 0 if current has access, error otherwise
+ */
+static int smk_curacc_msq(struct msg_queue *msq, int access)
+{
+ char *msp = smack_of_msq(msq);
+ struct smk_audit_info ad;
+
+#ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
+ ad.a.u.ipc_id = msq->q_perm.id;
+#endif
+ return smk_curacc(msp, access, &ad);
+}
+
+/**
* smack_msg_queue_associate - Smack access check for msg_queue
* @msq: the object
* @msqflg: access requested
@@ -1889,11 +2071,10 @@ static char *smack_of_msq(struct msg_queue *msq)
*/
static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg)
{
- char *msp = smack_of_msq(msq);
int may;
may = smack_flags_to_may(msqflg);
- return smk_curacc(msp, may);
+ return smk_curacc_msq(msq, may);
}
/**
@@ -1905,7 +2086,6 @@ static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg)
*/
static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
{
- char *msp;
int may;
switch (cmd) {
@@ -1927,8 +2107,7 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
return -EINVAL;
}
- msp = smack_of_msq(msq);
- return smk_curacc(msp, may);
+ return smk_curacc_msq(msq, may);
}
/**
@@ -1942,11 +2121,10 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
int msqflg)
{
- char *msp = smack_of_msq(msq);
- int rc;
+ int may;
- rc = smack_flags_to_may(msqflg);
- return smk_curacc(msp, rc);
+ may = smack_flags_to_may(msqflg);
+ return smk_curacc_msq(msq, may);
}
/**
@@ -1962,9 +2140,7 @@ static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
struct task_struct *target, long type, int mode)
{
- char *msp = smack_of_msq(msq);
-
- return smk_curacc(msp, MAY_READWRITE);
+ return smk_curacc_msq(msq, MAY_READWRITE);
}
/**
@@ -1977,10 +2153,14 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
{
char *isp = ipp->security;
- int may;
+ int may = smack_flags_to_may(flag);
+ struct smk_audit_info ad;
- may = smack_flags_to_may(flag);
- return smk_curacc(isp, may);
+#ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
+ ad.a.u.ipc_id = ipp->id;
+#endif
+ return smk_curacc(isp, may, &ad);
}
/**
@@ -2239,8 +2419,12 @@ static int smack_unix_stream_connect(struct socket *sock,
{
struct inode *sp = SOCK_INODE(sock);
struct inode *op = SOCK_INODE(other);
+ struct smk_audit_info ad;
- return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_READWRITE);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
+ smk_ad_setfield_u_net_sk(&ad, other->sk);
+ return smk_access(smk_of_inode(sp), smk_of_inode(op),
+ MAY_READWRITE, &ad);
}
/**
@@ -2255,8 +2439,11 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
{
struct inode *sp = SOCK_INODE(sock);
struct inode *op = SOCK_INODE(other);
+ struct smk_audit_info ad;
- return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
+ smk_ad_setfield_u_net_sk(&ad, other->sk);
+ return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE, &ad);
}
/**
@@ -2371,7 +2558,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
char smack[SMK_LABELLEN];
char *csp;
int rc;
-
+ struct smk_audit_info ad;
if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
return 0;
@@ -2389,13 +2576,19 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
netlbl_secattr_destroy(&secattr);
+#ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
+ ad.a.u.net.family = sk->sk_family;
+ ad.a.u.net.netif = skb->iif;
+ ipv4_skb_to_auditdata(skb, &ad.a, NULL);
+#endif
/*
* Receiving a packet requires that the other end
* be able to write here. Read access is not required.
* This is the simplist possible security model
* for networking.
*/
- rc = smk_access(csp, ssp->smk_in, MAY_WRITE);
+ rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad);
if (rc != 0)
netlbl_skbuff_err(skb, rc, 0);
return rc;
@@ -2524,6 +2717,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
struct iphdr *hdr;
char smack[SMK_LABELLEN];
int rc;
+ struct smk_audit_info ad;
/* handle mapped IPv4 packets arriving via IPv6 sockets */
if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
@@ -2537,11 +2731,17 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN);
netlbl_secattr_destroy(&secattr);
+#ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
+ ad.a.u.net.family = family;
+ ad.a.u.net.netif = skb->iif;
+ ipv4_skb_to_auditdata(skb, &ad.a, NULL);
+#endif
/*
* Receiving a packet requires that the other end be able to write
* here. Read access is not required.
*/
- rc = smk_access(smack, ssp->smk_in, MAY_WRITE);
+ rc = smk_access(smack, ssp->smk_in, MAY_WRITE, &ad);
if (rc != 0)
return rc;
@@ -2643,6 +2843,7 @@ static int smack_key_permission(key_ref_t key_ref,
const struct cred *cred, key_perm_t perm)
{
struct key *keyp;
+ struct smk_audit_info ad;
keyp = key_ref_to_ptr(key_ref);
if (keyp == NULL)
@@ -2658,8 +2859,13 @@ static int smack_key_permission(key_ref_t key_ref,
*/
if (cred->security == NULL)
return -EACCES;
-
- return smk_access(cred->security, keyp->security, MAY_READWRITE);
+#ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
+ ad.a.u.key_struct.key = keyp->serial;
+ ad.a.u.key_struct.key_desc = keyp->description;
+#endif
+ return smk_access(cred->security, keyp->security,
+ MAY_READWRITE, &ad);
}
#endif /* CONFIG_KEYS */
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index e03a7e19c73b..ee1c9c932934 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -41,6 +41,7 @@ enum smk_inos {
SMK_AMBIENT = 7, /* internet ambient label */
SMK_NETLBLADDR = 8, /* single label hosts */
SMK_ONLYCAP = 9, /* the only "capable" label */
+ SMK_LOGGING = 10, /* logging */
};
/*
@@ -734,8 +735,8 @@ static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
return;
}
- m = list_entry(rcu_dereference(smk_netlbladdr_list.next),
- struct smk_netlbladdr, list);
+ m = list_entry_rcu(smk_netlbladdr_list.next,
+ struct smk_netlbladdr, list);
/* the comparison '>' is a bit hacky, but works */
if (new->smk_mask.s_addr > m->smk_mask.s_addr) {
@@ -748,8 +749,8 @@ static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
list_add_rcu(&new->list, &m->list);
return;
}
- m_next = list_entry(rcu_dereference(m->list.next),
- struct smk_netlbladdr, list);
+ m_next = list_entry_rcu(m->list.next,
+ struct smk_netlbladdr, list);
if (new->smk_mask.s_addr > m_next->smk_mask.s_addr) {
list_add_rcu(&new->list, &m->list);
return;
@@ -1192,6 +1193,69 @@ static const struct file_operations smk_onlycap_ops = {
};
/**
+ * smk_read_logging - read() for /smack/logging
+ * @filp: file pointer, not actually used
+ * @buf: where to put the result
+ * @cn: maximum to send along
+ * @ppos: where to start
+ *
+ * Returns number of bytes read or error code, as appropriate
+ */
+static ssize_t smk_read_logging(struct file *filp, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char temp[32];
+ ssize_t rc;
+
+ if (*ppos != 0)
+ return 0;
+
+ sprintf(temp, "%d\n", log_policy);
+ rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
+ return rc;
+}
+
+/**
+ * smk_write_logging - write() for /smack/logging
+ * @file: file pointer, not actually used
+ * @buf: where to get the data from
+ * @count: bytes sent
+ * @ppos: where to start
+ *
+ * Returns number of bytes written or error code, as appropriate
+ */
+static ssize_t smk_write_logging(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char temp[32];
+ int i;
+
+ if (!capable(CAP_MAC_ADMIN))
+ return -EPERM;
+
+ if (count >= sizeof(temp) || count == 0)
+ return -EINVAL;
+
+ if (copy_from_user(temp, buf, count) != 0)
+ return -EFAULT;
+
+ temp[count] = '\0';
+
+ if (sscanf(temp, "%d", &i) != 1)
+ return -EINVAL;
+ if (i < 0 || i > 3)
+ return -EINVAL;
+ log_policy = i;
+ return count;
+}
+
+
+
+static const struct file_operations smk_logging_ops = {
+ .read = smk_read_logging,
+ .write = smk_write_logging,
+};
+/**
* smk_fill_super - fill the /smackfs superblock
* @sb: the empty superblock
* @data: unused
@@ -1221,6 +1285,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
{"netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR},
[SMK_ONLYCAP] =
{"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
+ [SMK_LOGGING] =
+ {"logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
/* last one */ {""}
};
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index d4d41b3efc7c..ddfb9cccf468 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1720,14 +1720,14 @@ static bool tomoyo_policy_loader_exists(void)
* policies are not loaded yet.
* Thus, let do_execve() call this function everytime.
*/
- struct nameidata nd;
+ struct path path;
- if (path_lookup(tomoyo_loader, LOOKUP_FOLLOW, &nd)) {
+ if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
printk(KERN_INFO "Not activating Mandatory Access Control now "
"since %s doesn't exist.\n", tomoyo_loader);
return false;
}
- path_put(&nd.path);
+ path_put(&path);
return true;
}
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index bf8e2b451687..40927a84cb6e 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -165,11 +165,11 @@ char *tomoyo_realpath_from_path(struct path *path)
*/
char *tomoyo_realpath(const char *pathname)
{
- struct nameidata nd;
+ struct path path;
- if (pathname && path_lookup(pathname, LOOKUP_FOLLOW, &nd) == 0) {
- char *buf = tomoyo_realpath_from_path(&nd.path);
- path_put(&nd.path);
+ if (pathname && kern_path(pathname, LOOKUP_FOLLOW, &path) == 0) {
+ char *buf = tomoyo_realpath_from_path(&path);
+ path_put(&path);
return buf;
}
return NULL;
@@ -184,11 +184,11 @@ char *tomoyo_realpath(const char *pathname)
*/
char *tomoyo_realpath_nofollow(const char *pathname)
{
- struct nameidata nd;
+ struct path path;
- if (pathname && path_lookup(pathname, 0, &nd) == 0) {
- char *buf = tomoyo_realpath_from_path(&nd.path);
- path_put(&nd.path);
+ if (pathname && kern_path(pathname, 0, &path) == 0) {
+ char *buf = tomoyo_realpath_from_path(&path);
+ path_put(&path);
return buf;
}
return NULL;
diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c
index fbf5c933baa4..586965f9605f 100644
--- a/sound/aoa/fabrics/layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -1037,7 +1037,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
}
ldev->selfptr_headphone.ptr = ldev;
ldev->selfptr_lineout.ptr = ldev;
- sdev->ofdev.dev.driver_data = ldev;
+ dev_set_drvdata(&sdev->ofdev.dev, ldev);
list_add(&ldev->list, &layouts_list);
layouts_list_items++;
@@ -1081,7 +1081,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
{
- struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
+ struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
int i;
for (i=0; i<MAX_CODECS_PER_BUS; i++) {
@@ -1114,7 +1114,7 @@ static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
#ifdef CONFIG_PM
static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state)
{
- struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
+ struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
ldev->gpio.methods->all_amps_off(&ldev->gpio);
@@ -1124,7 +1124,7 @@ static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t sta
static int aoa_fabric_layout_resume(struct soundbus_dev *sdev)
{
- struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
+ struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
ldev->gpio.methods->all_amps_restore(&ldev->gpio);
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
index 418c84c99d69..4e3b819d4993 100644
--- a/sound/aoa/soundbus/i2sbus/core.c
+++ b/sound/aoa/soundbus/i2sbus/core.c
@@ -358,14 +358,14 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
return -ENODEV;
}
- dev->ofdev.dev.driver_data = control;
+ dev_set_drvdata(&dev->ofdev.dev, control);
return 0;
}
static int i2sbus_remove(struct macio_dev* dev)
{
- struct i2sbus_control *control = dev->ofdev.dev.driver_data;
+ struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
struct i2sbus_dev *i2sdev, *tmp;
list_for_each_entry_safe(i2sdev, tmp, &control->list, item)
@@ -377,7 +377,7 @@ static int i2sbus_remove(struct macio_dev* dev)
#ifdef CONFIG_PM
static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
{
- struct i2sbus_control *control = dev->ofdev.dev.driver_data;
+ struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
struct codec_info_item *cii;
struct i2sbus_dev* i2sdev;
int err, ret = 0;
@@ -407,7 +407,7 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
static int i2sbus_resume(struct macio_dev* dev)
{
- struct i2sbus_control *control = dev->ofdev.dev.driver_data;
+ struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
struct codec_info_item *cii;
struct i2sbus_dev* i2sdev;
int err, ret = 0;
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index a2c12d105c9a..6fdca97186e7 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -65,7 +65,7 @@ static void set_resetgpio_mode(int resetgpio_action)
switch (resetgpio_action) {
case RESETGPIO_NORMAL_ALTFUNC:
if (reset_gpio == 113)
- mode = 113 | GPIO_OUT | GPIO_DFLT_LOW;
+ mode = 113 | GPIO_ALT_FN_2_OUT;
if (reset_gpio == 95)
mode = 95 | GPIO_ALT_FN_1_OUT;
break;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index fc6f98e257df..cb769d415db7 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -587,14 +587,15 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
status->avail = snd_pcm_playback_avail(runtime);
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
- runtime->status->state == SNDRV_PCM_STATE_DRAINING)
+ runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
status->delay = runtime->buffer_size - status->avail;
- else
+ status->delay += runtime->delay;
+ } else
status->delay = 0;
} else {
status->avail = snd_pcm_capture_avail(runtime);
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
- status->delay = status->avail;
+ status->delay = status->avail + runtime->delay;
else
status->delay = 0;
}
@@ -2404,6 +2405,7 @@ static int snd_pcm_delay(struct snd_pcm_substream *substream,
n = snd_pcm_playback_hw_avail(runtime);
else
n = snd_pcm_capture_avail(runtime);
+ n += runtime->delay;
break;
case SNDRV_PCM_STATE_XRUN:
err = -EPIPE;
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index b2b6d50c9425..a25fb7b1f441 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -963,16 +963,11 @@ static int __devinit snd_serial_probe(struct platform_device *devptr)
if (err < 0)
goto _err;
- sprintf(card->longname, "%s at 0x%lx, irq %d speed %d div %d outs %d ins %d adaptor %s droponfull %d",
+ sprintf(card->longname, "%s [%s] at %#lx, irq %d",
card->shortname,
- uart->base,
- uart->irq,
- uart->speed,
- (int)uart->divisor,
- outs[dev],
- ins[dev],
adaptor_names[uart->adaptor],
- uart->drop_on_full);
+ uart->base,
+ uart->irq);
snd_card_set_dev(card, &devptr->dev);
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index c6942a4de99b..51a7e3777e17 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -177,15 +177,18 @@ config SND_ES18XX
will be called snd-es18xx.
config SND_SC6000
- tristate "Gallant SC-6000, Audio Excel DSP 16"
+ tristate "Gallant SC-6000/6600/7000 and Audio Excel DSP 16"
depends on HAS_IOPORT
select SND_WSS_LIB
select SND_OPL3_LIB
select SND_MPU401_UART
help
- Say Y here to include support for Gallant SC-6000 card and clones:
+ Say Y here to include support for Gallant SC-6000, SC-6600, SC-7000
+ cards and clones:
Audio Excel DSP 16 and Zoltrix AV302.
+ These cards are based on CompuMedia ASC-9308 or ASC-9408 chips.
+
To compile this driver as a module, choose M here: the module
will be called snd-sc6000.
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c
index 782010608ef4..9a8bbf6dd62a 100644
--- a/sound/isa/sc6000.c
+++ b/sound/isa/sc6000.c
@@ -2,6 +2,8 @@
* 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.
+ * SC-6600 and SC-7000 cards are also supported. They are based on
+ * CompuMedia ASC-9408 chip and CS4231 codec.
*
* Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl>
*
@@ -54,6 +56,7 @@ 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 */
+static bool joystick[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = false };
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for sc-6000 based soundcard.");
@@ -73,6 +76,8 @@ 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.");
+module_param_array(joystick, bool, NULL, 0444);
+MODULE_PARM_DESC(joystick, "Enable gameport.");
/*
* Commands of SC6000's DSP (SBPRO+special).
@@ -191,7 +196,7 @@ static __devinit unsigned char sc6000_mpu_irq_to_softcfg(int mpu_irq)
return val;
}
-static __devinit int sc6000_wait_data(char __iomem *vport)
+static int sc6000_wait_data(char __iomem *vport)
{
int loop = 1000;
unsigned char val = 0;
@@ -206,7 +211,7 @@ static __devinit int sc6000_wait_data(char __iomem *vport)
return -EAGAIN;
}
-static __devinit int sc6000_read(char __iomem *vport)
+static int sc6000_read(char __iomem *vport)
{
if (sc6000_wait_data(vport))
return -EBUSY;
@@ -215,7 +220,7 @@ static __devinit int sc6000_read(char __iomem *vport)
}
-static __devinit int sc6000_write(char __iomem *vport, int cmd)
+static int sc6000_write(char __iomem *vport, int cmd)
{
unsigned char val;
int loop = 500000;
@@ -276,8 +281,33 @@ static int __devinit sc6000_dsp_reset(char __iomem *vport)
}
/* detection and initialization */
-static int __devinit sc6000_cfg_write(char __iomem *vport,
- unsigned char softcfg)
+static int __devinit sc6000_hw_cfg_write(char __iomem *vport, const int *cfg)
+{
+ if (sc6000_write(vport, COMMAND_6C) < 0) {
+ snd_printk(KERN_WARNING "CMD 0x%x: failed!\n", COMMAND_6C);
+ return -EIO;
+ }
+ if (sc6000_write(vport, COMMAND_5C) < 0) {
+ snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_5C);
+ return -EIO;
+ }
+ if (sc6000_write(vport, cfg[0]) < 0) {
+ snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[0]);
+ return -EIO;
+ }
+ if (sc6000_write(vport, cfg[1]) < 0) {
+ snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[1]);
+ return -EIO;
+ }
+ if (sc6000_write(vport, COMMAND_C5) < 0) {
+ snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_C5);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int sc6000_cfg_write(char __iomem *vport, unsigned char softcfg)
{
if (sc6000_write(vport, WRITE_MDIRQ_CFG)) {
@@ -291,7 +321,7 @@ static int __devinit sc6000_cfg_write(char __iomem *vport,
return 0;
}
-static int __devinit sc6000_setup_board(char __iomem *vport, int config)
+static int sc6000_setup_board(char __iomem *vport, int config)
{
int loop = 10;
@@ -334,16 +364,39 @@ static int __devinit sc6000_init_mss(char __iomem *vport, int config,
return 0;
}
-static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma,
- char __iomem *vmss_port, int mpu_irq)
+static void __devinit sc6000_hw_cfg_encode(char __iomem *vport, int *cfg,
+ long xport, long xmpu,
+ long xmss_port, int joystick)
+{
+ cfg[0] = 0;
+ cfg[1] = 0;
+ if (xport == 0x240)
+ cfg[0] |= 1;
+ if (xmpu != SNDRV_AUTO_PORT) {
+ cfg[0] |= (xmpu & 0x30) >> 2;
+ cfg[1] |= 0x20;
+ }
+ if (xmss_port == 0xe80)
+ cfg[0] |= 0x10;
+ cfg[0] |= 0x40; /* always set */
+ if (!joystick)
+ cfg[0] |= 0x02;
+ cfg[1] |= 0x80; /* enable WSS system */
+ cfg[1] &= ~0x40; /* disable IDE */
+ snd_printd("hw cfg %x, %x\n", cfg[0], cfg[1]);
+}
+
+static int __devinit sc6000_init_board(char __iomem *vport,
+ char __iomem *vmss_port, int dev)
{
char answer[15];
char version[2];
- int mss_config = sc6000_irq_to_softcfg(irq) |
- sc6000_dma_to_softcfg(dma);
+ int mss_config = sc6000_irq_to_softcfg(irq[dev]) |
+ sc6000_dma_to_softcfg(dma[dev]);
int config = mss_config |
- sc6000_mpu_irq_to_softcfg(mpu_irq);
+ sc6000_mpu_irq_to_softcfg(mpu_irq[dev]);
int err;
+ int old = 0;
err = sc6000_dsp_reset(vport);
if (err < 0) {
@@ -360,7 +413,6 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma,
/*
* 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");
@@ -372,13 +424,32 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma,
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);
+ /* set configuration */
+ sc6000_write(vport, COMMAND_5C);
+ if (sc6000_read(vport) < 0)
+ old = 1;
+
+ if (!old) {
+ int cfg[2];
+ sc6000_hw_cfg_encode(vport, &cfg[0], port[dev], mpu_port[dev],
+ mss_port[dev], joystick[dev]);
+ if (sc6000_hw_cfg_write(vport, cfg) < 0) {
+ snd_printk(KERN_ERR "sc6000_hw_cfg_write: failed!\n");
+ return -EIO;
+ }
+ }
+ err = sc6000_setup_board(vport, config);
if (err < 0) {
- snd_printk(KERN_ERR "sc6000_cfg_write: failed!\n");
- return -EFAULT;
+ snd_printk(KERN_ERR "sc6000_setup_board: failed!\n");
+ return -ENODEV;
+ }
+
+ sc6000_dsp_reset(vport);
+
+ if (!old) {
+ sc6000_write(vport, COMMAND_60);
+ sc6000_write(vport, 0x02);
+ sc6000_dsp_reset(vport);
}
err = sc6000_setup_board(vport, config);
@@ -386,10 +457,9 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma,
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 "
+ snd_printk(KERN_ERR "Cannot initialize "
"Microsoft Sound System mode.\n");
return -ENODEV;
}
@@ -485,14 +555,16 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
struct snd_card *card;
struct snd_wss *chip;
struct snd_opl3 *opl3;
- char __iomem *vport;
+ char __iomem **vport;
char __iomem *vmss_port;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+ err = snd_card_create(index[dev], id[dev], THIS_MODULE, sizeof(vport),
+ &card);
if (err < 0)
return err;
+ vport = card->private_data;
if (xirq == SNDRV_AUTO_IRQ) {
xirq = snd_legacy_find_free_irq(possible_irqs);
if (xirq < 0) {
@@ -517,8 +589,8 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
err = -EBUSY;
goto err_exit;
}
- vport = devm_ioport_map(devptr, port[dev], 0x10);
- if (!vport) {
+ *vport = devm_ioport_map(devptr, port[dev], 0x10);
+ if (*vport == NULL) {
snd_printk(KERN_ERR PFX
"I/O port cannot be iomaped.\n");
err = -EBUSY;
@@ -533,7 +605,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
goto err_unmap1;
}
vmss_port = devm_ioport_map(devptr, mss_port[dev], 4);
- if (!vport) {
+ if (!vmss_port) {
snd_printk(KERN_ERR PFX
"MSS port I/O cannot be iomaped.\n");
err = -EBUSY;
@@ -544,7 +616,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
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]);
+ err = sc6000_init_board(*vport, vmss_port, dev);
if (err < 0)
goto err_unmap2;
@@ -552,7 +624,6 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
WSS_HW_DETECT, 0, &chip);
if (err < 0)
goto err_unmap2;
- card->private_data = chip;
err = snd_wss_pcm(chip, 0, NULL);
if (err < 0) {
@@ -608,6 +679,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
return 0;
err_unmap2:
+ sc6000_setup_board(*vport, 0);
release_region(mss_port[dev], 4);
err_unmap1:
release_region(port[dev], 0x10);
@@ -618,11 +690,17 @@ err_exit:
static int __devexit snd_sc6000_remove(struct device *devptr, unsigned int dev)
{
+ struct snd_card *card = dev_get_drvdata(devptr);
+ char __iomem **vport = card->private_data;
+
+ if (sc6000_setup_board(*vport, 0) < 0)
+ snd_printk(KERN_WARNING "sc6000_setup_board failed on exit!\n");
+
release_region(port[dev], 0x10);
release_region(mss_port[dev], 4);
- snd_card_free(dev_get_drvdata(devptr));
dev_set_drvdata(devptr, NULL);
+ snd_card_free(card);
return 0;
}
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 93422e3a3f0c..8366734e0154 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -532,6 +532,9 @@ config SND_HDSP
To compile this driver as a module, choose M here: the module
will be called snd-hdsp.
+comment "Don't forget to add built-in firmwares for HDSP driver"
+ depends on SND_HDSP=y
+
config SND_HDSPM
tristate "RME Hammerfall DSP MADI"
select SND_HWDEP
@@ -622,6 +625,16 @@ config SND_KORG1212
To compile this driver as a module, choose M here: the module
will be called snd-korg1212.
+config SND_LX6464ES
+ tristate "Digigram LX6464ES"
+ select SND_PCM
+ help
+ Say Y here to include support for Digigram LX6464ES boards.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-lx6464es.
+
+
config SND_MAESTRO3
tristate "ESS Allegro/Maestro3"
select SND_AC97_CODEC
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 65b25d221cd2..7d83e084dcf4 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_SND) += \
ca0106/ \
cs46xx/ \
cs5535audio/ \
+ lx6464es/ \
echoaudio/ \
emu10k1/ \
hda/ \
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index eb2a19b894a0..c710150d5065 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -139,6 +139,19 @@ config SND_HDA_CODEC_CONEXANT
snd-hda-codec-conexant.
This module is automatically loaded at probing.
+config SND_HDA_CODEC_CA0110
+ bool "Build Creative CA0110-IBG codec support"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to include Creative CA0110-IBG codec support in
+ snd-hda-intel driver, found on some Creative X-Fi cards.
+
+ When the HD-audio driver is built as a module, the codec
+ support code is also built as another module,
+ snd-hda-codec-ca0110.
+ This module is automatically loaded at probing.
+
config SND_HDA_CODEC_CMEDIA
bool "Build C-Media HD-audio codec support"
default y
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 50f9d0967251..e3081d4586cc 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -13,6 +13,7 @@ snd-hda-codec-analog-objs := patch_analog.o
snd-hda-codec-idt-objs := patch_sigmatel.o
snd-hda-codec-si3054-objs := patch_si3054.o
snd-hda-codec-atihdmi-objs := patch_atihdmi.o
+snd-hda-codec-ca0110-objs := patch_ca0110.o
snd-hda-codec-conexant-objs := patch_conexant.o
snd-hda-codec-via-objs := patch_via.o
snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o
@@ -40,6 +41,9 @@ endif
ifdef CONFIG_SND_HDA_CODEC_ATIHDMI
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o
endif
+ifdef CONFIG_SND_HDA_CODEC_CA0110
+obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o
+endif
ifdef CONFIG_SND_HDA_CODEC_CONEXANT
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o
endif
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 8820faf6c9d8..b91f6ed5cc58 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -48,6 +48,7 @@ static struct hda_vendor_id hda_vendor_ids[] = {
{ 0x1095, "Silicon Image" },
{ 0x10de, "Nvidia" },
{ 0x10ec, "Realtek" },
+ { 0x1102, "Creative" },
{ 0x1106, "VIA" },
{ 0x111d, "IDT" },
{ 0x11c1, "LSI" },
@@ -174,14 +175,23 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
unsigned int verb, unsigned int parm)
{
struct hda_bus *bus = codec->bus;
- unsigned int res;
+ unsigned int cmd, res;
+ int repeated = 0;
- res = make_codec_cmd(codec, nid, direct, verb, parm);
+ cmd = make_codec_cmd(codec, nid, direct, verb, parm);
snd_hda_power_up(codec);
mutex_lock(&bus->cmd_mutex);
- if (!bus->ops.command(bus, res))
+ again:
+ if (!bus->ops.command(bus, cmd)) {
res = bus->ops.get_response(bus);
- else
+ if (res == -1 && bus->rirb_error) {
+ if (repeated++ < 1) {
+ snd_printd(KERN_WARNING "hda_codec: "
+ "Trying verb 0x%08x again\n", cmd);
+ goto again;
+ }
+ }
+ } else
res = (unsigned int)-1;
mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec);
@@ -1055,6 +1065,8 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
/* FIXME: more better hash key? */
#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
+#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
+#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
#define INFO_AMP_CAPS (1<<0)
#define INFO_AMP_VOL(ch) (1 << (1 + (ch)))
@@ -1145,19 +1157,32 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
}
EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps);
-u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
+static unsigned int
+query_caps_hash(struct hda_codec *codec, hda_nid_t nid, u32 key,
+ unsigned int (*func)(struct hda_codec *, hda_nid_t))
{
struct hda_amp_info *info;
- info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid));
+ info = get_alloc_amp_hash(codec, key);
if (!info)
return 0;
if (!info->head.val) {
- info->amp_caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
info->head.val |= INFO_AMP_CAPS;
+ info->amp_caps = func(codec, nid);
}
return info->amp_caps;
}
+
+static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid)
+{
+ return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
+}
+
+u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
+{
+ return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid),
+ read_pin_cap);
+}
EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);
/*
@@ -1432,6 +1457,8 @@ _snd_hda_find_mixer_ctl(struct hda_codec *codec,
memset(&id, 0, sizeof(id));
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
id.index = idx;
+ if (snd_BUG_ON(strlen(name) >= sizeof(id.name)))
+ return NULL;
strcpy(id.name, name);
return snd_ctl_find_id(codec->bus->card, &id);
}
@@ -2321,7 +2348,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
if (wcaps & AC_WCAP_POWER) {
unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >>
AC_WCAP_TYPE_SHIFT;
- if (wid_type == AC_WID_PIN) {
+ if (power_state == AC_PWRST_D3 &&
+ wid_type == AC_WID_PIN) {
unsigned int pincap;
/*
* don't power down the widget if it controls
@@ -2333,7 +2361,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
nid, 0,
AC_VERB_GET_EAPD_BTLENABLE, 0);
eapd &= 0x02;
- if (power_state == AC_PWRST_D3 && eapd)
+ if (eapd)
continue;
}
}
@@ -2544,6 +2572,41 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
}
EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
+static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid)
+{
+ unsigned int val = 0;
+ if (nid != codec->afg &&
+ (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD))
+ val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
+ if (!val || val == -1)
+ val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
+ if (!val || val == -1)
+ return 0;
+ return val;
+}
+
+static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid)
+{
+ return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid),
+ get_pcm_param);
+}
+
+static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid)
+{
+ unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
+ if (!streams || streams == -1)
+ streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
+ if (!streams || streams == -1)
+ return 0;
+ return streams;
+}
+
+static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
+{
+ return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid),
+ get_stream_param);
+}
+
/**
* snd_hda_query_supported_pcm - query the supported PCM rates and formats
* @codec: the HDA codec
@@ -2562,15 +2625,8 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
{
unsigned int i, val, wcaps;
- val = 0;
wcaps = get_wcaps(codec, nid);
- if (nid != codec->afg && (wcaps & AC_WCAP_FORMAT_OVRD)) {
- val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
- if (val == -1)
- return -EIO;
- }
- if (!val)
- val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
+ val = query_pcm_param(codec, nid);
if (ratesp) {
u32 rates = 0;
@@ -2592,15 +2648,9 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
u64 formats = 0;
unsigned int streams, bps;
- streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
- if (streams == -1)
+ streams = query_stream_param(codec, nid);
+ if (!streams)
return -EIO;
- if (!streams) {
- streams = snd_hda_param_read(codec, codec->afg,
- AC_PAR_STREAM);
- if (streams == -1)
- return -EIO;
- }
bps = 0;
if (streams & AC_SUPFMT_PCM) {
@@ -2674,17 +2724,9 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
int i;
unsigned int val = 0, rate, stream;
- if (nid != codec->afg &&
- (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) {
- val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
- if (val == -1)
- return 0;
- }
- if (!val) {
- val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
- if (val == -1)
- return 0;
- }
+ val = query_pcm_param(codec, nid);
+ if (!val)
+ return 0;
rate = format & 0xff00;
for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
@@ -2696,12 +2738,8 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
if (i >= AC_PAR_PCM_RATE_BITS)
return 0;
- stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
- if (stream == -1)
- return 0;
- if (!stream && nid != codec->afg)
- stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
- if (!stream || stream == -1)
+ stream = query_stream_param(codec, nid);
+ if (!stream)
return 0;
if (stream & AC_SUPFMT_PCM) {
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 2fdecf4b0eb6..cd8979c7670b 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -623,6 +623,7 @@ struct hda_bus {
/* misc op flags */
unsigned int needs_damn_long_delay :1;
unsigned int shutdown :1; /* being unloaded */
+ unsigned int rirb_error:1; /* error in codec communication */
};
/*
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 21e99cfa8c49..04f19f8cad84 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -606,6 +606,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
}
if (!chip->rirb.cmds) {
smp_rmb();
+ bus->rirb_error = 0;
return chip->rirb.res; /* the last value */
}
if (time_after(jiffies, timeout))
@@ -625,8 +626,10 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
chip->irq = -1;
pci_disable_msi(chip->pci);
chip->msi = 0;
- if (azx_acquire_irq(chip, 1) < 0)
+ if (azx_acquire_irq(chip, 1) < 0) {
+ bus->rirb_error = 1;
return -1;
+ }
goto again;
}
@@ -646,14 +649,12 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
return -1;
}
- snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
- "switching to single_cmd mode: last cmd=0x%08x\n",
- chip->last_cmd);
- chip->rirb.rp = azx_readb(chip, RIRBWP);
- chip->rirb.cmds = 0;
- /* switch to single_cmd mode */
- chip->single_cmd = 1;
- azx_free_cmd_io(chip);
+ snd_printk(KERN_ERR "hda_intel: azx_get_response timeout (ERROR): "
+ "last cmd=0x%08x\n", chip->last_cmd);
+ spin_lock_irq(&chip->reg_lock);
+ chip->rirb.cmds = 0; /* reset the index */
+ bus->rirb_error = 1;
+ spin_unlock_irq(&chip->reg_lock);
return -1;
}
@@ -1830,7 +1831,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
&pcm);
if (err < 0)
return err;
- strcpy(pcm->name, cpcm->name);
+ strlcpy(pcm->name, cpcm->name, sizeof(pcm->name));
apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
if (apcm == NULL)
return -ENOMEM;
@@ -2358,9 +2359,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
}
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);
+ strlcpy(card->shortname, driver_short_names[chip->driver_type],
+ sizeof(card->shortname));
+ snprintf(card->longname, sizeof(card->longname),
+ "%s at 0x%lx irq %i",
+ card->shortname, chip->addr, chip->irq);
*rchip = chip;
return 0;
@@ -2513,6 +2516,11 @@ static struct pci_device_id azx_ids[] = {
{ PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
/* Teradici */
{ PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
+ /* Creative X-Fi (CA0110-IBG) */
+ { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
+ .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
+ .class_mask = 0xffffff,
+ .driver_data = AZX_DRIVER_GENERIC },
/* AMD Generic, PCI class code and Vendor ID for HD Audio */
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
new file mode 100644
index 000000000000..392d108c3558
--- /dev/null
+++ b/sound/pci/hda/patch_ca0110.c
@@ -0,0 +1,573 @@
+/*
+ * HD audio interface patch for Creative X-Fi CA0110-IBG chip
+ *
+ * Copyright (c) 2008 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 <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <sound/core.h>
+#include "hda_codec.h"
+#include "hda_local.h"
+
+/*
+ */
+
+struct ca0110_spec {
+ struct auto_pin_cfg autocfg;
+ struct hda_multi_out multiout;
+ hda_nid_t out_pins[AUTO_CFG_MAX_OUTS];
+ hda_nid_t dacs[AUTO_CFG_MAX_OUTS];
+ hda_nid_t hp_dac;
+ hda_nid_t input_pins[AUTO_PIN_LAST];
+ hda_nid_t adcs[AUTO_PIN_LAST];
+ hda_nid_t dig_out;
+ hda_nid_t dig_in;
+ unsigned int num_inputs;
+ const char *input_labels[AUTO_PIN_LAST];
+ struct hda_pcm pcm_rec[2]; /* PCM information */
+};
+
+/*
+ * PCM callbacks
+ */
+static int ca0110_playback_pcm_open(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ struct ca0110_spec *spec = codec->spec;
+ return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
+ hinfo);
+}
+
+static int ca0110_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct ca0110_spec *spec = codec->spec;
+ return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
+ stream_tag, format, substream);
+}
+
+static int ca0110_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ struct ca0110_spec *spec = codec->spec;
+ return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
+}
+
+/*
+ * Digital out
+ */
+static int ca0110_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ struct ca0110_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+}
+
+static int ca0110_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ struct ca0110_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+static int ca0110_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct ca0110_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+ format, substream);
+}
+
+/*
+ * Analog capture
+ */
+static int ca0110_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct ca0110_spec *spec = codec->spec;
+
+ snd_hda_codec_setup_stream(codec, spec->adcs[substream->number],
+ stream_tag, 0, format);
+ return 0;
+}
+
+static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ struct ca0110_spec *spec = codec->spec;
+
+ snd_hda_codec_cleanup_stream(codec, spec->adcs[substream->number]);
+ return 0;
+}
+
+/*
+ */
+
+static char *dirstr[2] = { "Playback", "Capture" };
+
+static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
+ int chan, int dir)
+{
+ char namestr[44];
+ int type = dir ? HDA_INPUT : HDA_OUTPUT;
+ struct snd_kcontrol_new knew =
+ HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
+ sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
+ return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
+}
+
+static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
+ int chan, int dir)
+{
+ char namestr[44];
+ int type = dir ? HDA_INPUT : HDA_OUTPUT;
+ struct snd_kcontrol_new knew =
+ HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
+ sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
+ return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
+}
+
+#define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0)
+#define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0)
+#define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1)
+#define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1)
+#define add_mono_switch(codec, nid, pfx, chan) \
+ _add_switch(codec, nid, pfx, chan, 0)
+#define add_mono_volume(codec, nid, pfx, chan) \
+ _add_volume(codec, nid, pfx, chan, 0)
+
+static int ca0110_build_controls(struct hda_codec *codec)
+{
+ struct ca0110_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ static char *prefix[AUTO_CFG_MAX_OUTS] = {
+ "Front", "Surround", NULL, "Side", "Multi"
+ };
+ hda_nid_t mutenid;
+ int i, err;
+
+ for (i = 0; i < spec->multiout.num_dacs; i++) {
+ if (get_wcaps(codec, spec->out_pins[i]) & AC_WCAP_OUT_AMP)
+ mutenid = spec->out_pins[i];
+ else
+ mutenid = spec->multiout.dac_nids[i];
+ if (!prefix[i]) {
+ err = add_mono_switch(codec, mutenid,
+ "Center", 1);
+ if (err < 0)
+ return err;
+ err = add_mono_switch(codec, mutenid,
+ "LFE", 1);
+ if (err < 0)
+ return err;
+ err = add_mono_volume(codec, spec->multiout.dac_nids[i],
+ "Center", 1);
+ if (err < 0)
+ return err;
+ err = add_mono_volume(codec, spec->multiout.dac_nids[i],
+ "LFE", 1);
+ if (err < 0)
+ return err;
+ } else {
+ err = add_out_switch(codec, mutenid,
+ prefix[i]);
+ if (err < 0)
+ return err;
+ err = add_out_volume(codec, spec->multiout.dac_nids[i],
+ prefix[i]);
+ if (err < 0)
+ return err;
+ }
+ }
+ if (cfg->hp_outs) {
+ if (get_wcaps(codec, cfg->hp_pins[0]) & AC_WCAP_OUT_AMP)
+ mutenid = cfg->hp_pins[0];
+ else
+ mutenid = spec->multiout.dac_nids[i];
+
+ err = add_out_switch(codec, mutenid, "Headphone");
+ if (err < 0)
+ return err;
+ if (spec->hp_dac) {
+ err = add_out_volume(codec, spec->hp_dac, "Headphone");
+ if (err < 0)
+ return err;
+ }
+ }
+ for (i = 0; i < spec->num_inputs; i++) {
+ const char *label = spec->input_labels[i];
+ if (get_wcaps(codec, spec->input_pins[i]) & AC_WCAP_IN_AMP)
+ mutenid = spec->input_pins[i];
+ else
+ mutenid = spec->adcs[i];
+ err = add_in_switch(codec, mutenid, label);
+ if (err < 0)
+ return err;
+ err = add_in_volume(codec, spec->adcs[i], label);
+ if (err < 0)
+ return err;
+ }
+
+ if (spec->dig_out) {
+ err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out);
+ if (err < 0)
+ return err;
+ err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
+ if (err < 0)
+ return err;
+ spec->multiout.share_spdif = 1;
+ }
+ if (spec->dig_in) {
+ err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
+ if (err < 0)
+ return err;
+ err = add_in_volume(codec, spec->dig_in, "IEC958");
+ }
+ return 0;
+}
+
+/*
+ */
+static struct hda_pcm_stream ca0110_pcm_analog_playback = {
+ .substreams = 1,
+ .channels_min = 2,
+ .channels_max = 8,
+ .ops = {
+ .open = ca0110_playback_pcm_open,
+ .prepare = ca0110_playback_pcm_prepare,
+ .cleanup = ca0110_playback_pcm_cleanup
+ },
+};
+
+static struct hda_pcm_stream ca0110_pcm_analog_capture = {
+ .substreams = 1,
+ .channels_min = 2,
+ .channels_max = 2,
+ .ops = {
+ .prepare = ca0110_capture_pcm_prepare,
+ .cleanup = ca0110_capture_pcm_cleanup
+ },
+};
+
+static struct hda_pcm_stream ca0110_pcm_digital_playback = {
+ .substreams = 1,
+ .channels_min = 2,
+ .channels_max = 2,
+ .ops = {
+ .open = ca0110_dig_playback_pcm_open,
+ .close = ca0110_dig_playback_pcm_close,
+ .prepare = ca0110_dig_playback_pcm_prepare
+ },
+};
+
+static struct hda_pcm_stream ca0110_pcm_digital_capture = {
+ .substreams = 1,
+ .channels_min = 2,
+ .channels_max = 2,
+};
+
+static int ca0110_build_pcms(struct hda_codec *codec)
+{
+ struct ca0110_spec *spec = codec->spec;
+ struct hda_pcm *info = spec->pcm_rec;
+
+ codec->pcm_info = info;
+ codec->num_pcms = 0;
+
+ info->name = "CA0110 Analog";
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0110_pcm_analog_playback;
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0];
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
+ spec->multiout.max_channels;
+ info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0110_pcm_analog_capture;
+ info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs;
+ info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
+ codec->num_pcms++;
+
+ if (!spec->dig_out && !spec->dig_in)
+ return 0;
+
+ info++;
+ info->name = "CA0110 Digital";
+ info->pcm_type = HDA_PCM_TYPE_SPDIF;
+ if (spec->dig_out) {
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
+ ca0110_pcm_digital_playback;
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out;
+ }
+ if (spec->dig_in) {
+ info->stream[SNDRV_PCM_STREAM_CAPTURE] =
+ ca0110_pcm_digital_capture;
+ info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
+ }
+ codec->num_pcms++;
+
+ return 0;
+}
+
+static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
+{
+ if (pin) {
+ snd_hda_codec_write(codec, pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+ if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
+ snd_hda_codec_write(codec, pin, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_OUT_UNMUTE);
+ }
+ if (dac)
+ snd_hda_codec_write(codec, dac, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO);
+}
+
+static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
+{
+ if (pin) {
+ snd_hda_codec_write(codec, pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80);
+ if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
+ snd_hda_codec_write(codec, pin, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_IN_UNMUTE(0));
+ }
+ if (adc)
+ snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_IN_UNMUTE(0));
+}
+
+static int ca0110_init(struct hda_codec *codec)
+{
+ struct ca0110_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ int i;
+
+ for (i = 0; i < spec->multiout.num_dacs; i++)
+ init_output(codec, spec->out_pins[i],
+ spec->multiout.dac_nids[i]);
+ init_output(codec, cfg->hp_pins[0], spec->hp_dac);
+ init_output(codec, cfg->dig_out_pins[0], spec->dig_out);
+
+ for (i = 0; i < spec->num_inputs; i++)
+ init_input(codec, spec->input_pins[i], spec->adcs[i]);
+ init_input(codec, cfg->dig_in_pin, spec->dig_in);
+ return 0;
+}
+
+static void ca0110_free(struct hda_codec *codec)
+{
+ kfree(codec->spec);
+}
+
+static struct hda_codec_ops ca0110_patch_ops = {
+ .build_controls = ca0110_build_controls,
+ .build_pcms = ca0110_build_pcms,
+ .init = ca0110_init,
+ .free = ca0110_free,
+};
+
+
+static void parse_line_outs(struct hda_codec *codec)
+{
+ struct ca0110_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ int i, n;
+ unsigned int def_conf;
+ hda_nid_t nid;
+
+ n = 0;
+ for (i = 0; i < cfg->line_outs; i++) {
+ nid = cfg->line_out_pins[i];
+ def_conf = snd_hda_codec_get_pincfg(codec, nid);
+ if (!def_conf)
+ continue; /* invalid pin */
+ if (snd_hda_get_connections(codec, nid, &spec->dacs[i], 1) != 1)
+ continue;
+ spec->out_pins[n++] = nid;
+ }
+ spec->multiout.dac_nids = spec->dacs;
+ spec->multiout.num_dacs = n;
+ spec->multiout.max_channels = n * 2;
+}
+
+static void parse_hp_out(struct hda_codec *codec)
+{
+ struct ca0110_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ int i;
+ unsigned int def_conf;
+ hda_nid_t nid, dac;
+
+ if (!cfg->hp_outs)
+ return;
+ nid = cfg->hp_pins[0];
+ def_conf = snd_hda_codec_get_pincfg(codec, nid);
+ if (!def_conf) {
+ cfg->hp_outs = 0;
+ return;
+ }
+ if (snd_hda_get_connections(codec, nid, &dac, 1) != 1)
+ return;
+
+ for (i = 0; i < cfg->line_outs; i++)
+ if (dac == spec->dacs[i])
+ break;
+ if (i >= cfg->line_outs) {
+ spec->hp_dac = dac;
+ spec->multiout.hp_nid = dac;
+ }
+}
+
+static void parse_input(struct hda_codec *codec)
+{
+ struct ca0110_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ hda_nid_t nid, pin;
+ int n, i, j;
+
+ n = 0;
+ nid = codec->start_nid;
+ for (i = 0; i < codec->num_nodes; i++, nid++) {
+ unsigned int wcaps = get_wcaps(codec, nid);
+ unsigned int type = (wcaps & AC_WCAP_TYPE) >>
+ AC_WCAP_TYPE_SHIFT;
+ if (type != AC_WID_AUD_IN)
+ continue;
+ if (snd_hda_get_connections(codec, nid, &pin, 1) != 1)
+ continue;
+ if (pin == cfg->dig_in_pin) {
+ spec->dig_in = nid;
+ continue;
+ }
+ for (j = 0; j < AUTO_PIN_LAST; j++)
+ if (cfg->input_pins[j] == pin)
+ break;
+ if (j >= AUTO_PIN_LAST)
+ continue;
+ spec->input_pins[n] = pin;
+ spec->input_labels[n] = auto_pin_cfg_labels[j];
+ spec->adcs[n] = nid;
+ n++;
+ }
+ spec->num_inputs = n;
+}
+
+static void parse_digital(struct hda_codec *codec)
+{
+ struct ca0110_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+
+ if (cfg->dig_outs &&
+ snd_hda_get_connections(codec, cfg->dig_out_pins[0],
+ &spec->dig_out, 1) == 1)
+ spec->multiout.dig_out_nid = cfg->dig_out_pins[0];
+}
+
+static int ca0110_parse_auto_config(struct hda_codec *codec)
+{
+ struct ca0110_spec *spec = codec->spec;
+ int err;
+
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
+ if (err < 0)
+ return err;
+
+ parse_line_outs(codec);
+ parse_hp_out(codec);
+ parse_digital(codec);
+ parse_input(codec);
+ return 0;
+}
+
+
+int patch_ca0110(struct hda_codec *codec)
+{
+ struct ca0110_spec *spec;
+ int err;
+
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+ if (!spec)
+ return -ENOMEM;
+ codec->spec = spec;
+
+ codec->bus->needs_damn_long_delay = 1;
+
+ err = ca0110_parse_auto_config(codec);
+ if (err < 0)
+ goto error;
+
+ codec->patch_ops = ca0110_patch_ops;
+
+ return 0;
+
+ error:
+ kfree(codec->spec);
+ codec->spec = NULL;
+ return err;
+}
+
+
+/*
+ * patch entries
+ */
+static struct hda_codec_preset snd_hda_preset_ca0110[] = {
+ { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 },
+ { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 },
+ { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 },
+ {} /* terminator */
+};
+
+MODULE_ALIAS("snd-hda-codec-id:1102000a");
+MODULE_ALIAS("snd-hda-codec-id:1102000b");
+MODULE_ALIAS("snd-hda-codec-id:1102000d");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec");
+
+static struct hda_codec_preset_list ca0110_list = {
+ .preset = snd_hda_preset_ca0110,
+ .owner = THIS_MODULE,
+};
+
+static int __init patch_ca0110_init(void)
+{
+ return snd_hda_add_codec_preset(&ca0110_list);
+}
+
+static void __exit patch_ca0110_exit(void)
+{
+ snd_hda_delete_codec_preset(&ca0110_list);
+}
+
+module_init(patch_ca0110_init)
+module_exit(patch_ca0110_exit)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b8a0d3e79272..51954bacaa01 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -190,6 +190,7 @@ enum {
ALC663_ASUS_MODE6,
ALC272_DELL,
ALC272_DELL_ZM1,
+ ALC272_SAMSUNG_NC10,
ALC662_AUTO,
ALC662_MODEL_LAST,
};
@@ -205,6 +206,7 @@ enum {
ALC882_ASUS_A7M,
ALC885_MACPRO,
ALC885_MBP3,
+ ALC885_MB5,
ALC885_IMAC24,
ALC882_AUTO,
ALC882_MODEL_LAST,
@@ -253,6 +255,15 @@ enum {
/* for GPIO Poll */
#define GPIO_MASK 0x03
+/* extra amp-initialization sequence types */
+enum {
+ ALC_INIT_NONE,
+ ALC_INIT_DEFAULT,
+ ALC_INIT_GPIO1,
+ ALC_INIT_GPIO2,
+ ALC_INIT_GPIO3,
+};
+
struct alc_spec {
/* codec parameterization */
struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -322,6 +333,7 @@ struct alc_spec {
/* other flags */
unsigned int no_analog :1; /* digital I/O only */
+ int init_amp;
/* for virtual master */
hda_nid_t vmaster_nid;
@@ -915,20 +927,26 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
alc_fix_pll(codec);
}
-static void alc_sku_automute(struct hda_codec *codec)
+static void alc_automute_pin(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
unsigned int present;
- unsigned int hp_nid = spec->autocfg.hp_pins[0];
- unsigned int sp_nid = spec->autocfg.speaker_pins[0];
+ unsigned int nid = spec->autocfg.hp_pins[0];
+ int i;
/* 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,
+ snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
+ present = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_PIN_SENSE, 0);
- spec->jack_present = (present & 0x80000000) != 0;
- snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- spec->jack_present ? 0 : PIN_OUT);
+ spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
+ for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
+ nid = spec->autocfg.speaker_pins[i];
+ if (!nid)
+ break;
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ spec->jack_present ? 0 : PIN_OUT);
+ }
}
#if 0 /* it's broken in some acses -- temporarily disabled */
@@ -963,16 +981,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
res >>= 28;
else
res >>= 26;
- if (res == ALC880_HP_EVENT)
- alc_sku_automute(codec);
-
- if (res == ALC880_MIC_EVENT)
+ switch (res) {
+ case ALC880_HP_EVENT:
+ alc_automute_pin(codec);
+ break;
+ case ALC880_MIC_EVENT:
alc_mic_automute(codec);
+ break;
+ }
}
static void alc_inithook(struct hda_codec *codec)
{
- alc_sku_automute(codec);
+ alc_automute_pin(codec);
alc_mic_automute(codec);
}
@@ -994,69 +1015,21 @@ static void alc888_coef_init(struct hda_codec *codec)
AC_VERB_SET_PROC_COEF, 0x3030);
}
-/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
- * 31 ~ 16 : Manufacture ID
- * 15 ~ 8 : SKU ID
- * 7 ~ 0 : Assembly ID
- * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
- */
-static void alc_subsystem_id(struct hda_codec *codec,
- unsigned int porta, unsigned int porte,
- unsigned int portd)
+static void alc_auto_init_amp(struct hda_codec *codec, int type)
{
- unsigned int ass, tmp, i;
- unsigned nid;
- struct alc_spec *spec = codec->spec;
-
- 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_get_pincfg(codec, nid);
- if (!(ass & 1) && !(ass & 0x100000))
- return;
- if ((ass >> 30) != 1) /* no physical connection */
- return;
+ unsigned int tmp;
- /* 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:
+ switch (type) {
+ case ALC_INIT_GPIO1:
snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
break;
- case 3:
+ case ALC_INIT_GPIO2:
snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
break;
- case 7:
+ case ALC_INIT_GPIO3:
snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
break;
- case 5: /* set EAPD output high */
+ case ALC_INIT_DEFAULT:
switch (codec->vendor_id) {
case 0x10ec0260:
snd_hda_codec_write(codec, 0x0f, 0,
@@ -1110,7 +1083,7 @@ do_sku:
tmp | 0x2010);
break;
case 0x10ec0888:
- /*alc888_coef_init(codec);*/ /* called in alc_init() */
+ alc888_coef_init(codec);
break;
case 0x10ec0267:
case 0x10ec0268:
@@ -1125,7 +1098,107 @@ do_sku:
tmp | 0x3000);
break;
}
- default:
+ break;
+ }
+}
+
+static void alc_init_auto_hp(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+
+ if (!spec->autocfg.hp_pins[0])
+ return;
+
+ if (!spec->autocfg.speaker_pins[0]) {
+ if (spec->autocfg.line_out_pins[0] &&
+ spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
+ spec->autocfg.speaker_pins[0] =
+ spec->autocfg.line_out_pins[0];
+ else
+ return;
+ }
+
+ snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
+ spec->autocfg.hp_pins[0]);
+ snd_hda_codec_write_cache(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;
+}
+
+/* check subsystem ID and set up device-specific initialization;
+ * return 1 if initialized, 0 if invalid SSID
+ */
+/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
+ * 31 ~ 16 : Manufacture ID
+ * 15 ~ 8 : SKU ID
+ * 7 ~ 0 : Assembly ID
+ * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
+ */
+static int alc_subsystem_id(struct hda_codec *codec,
+ hda_nid_t porta, hda_nid_t porte,
+ hda_nid_t portd)
+{
+ unsigned int ass, tmp, i;
+ unsigned nid;
+ struct alc_spec *spec = codec->spec;
+
+ ass = codec->subsystem_id & 0xffff;
+ if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
+ goto do_sku;
+
+ /* invalid SSID, check the special NID pin defcfg instead */
+ /*
+ * 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_get_pincfg(codec, nid);
+ snd_printd("realtek: No valid SSID, "
+ "checking pincfg 0x%08x for NID 0x%x\n",
+ ass, nid);
+ if (!(ass & 1) && !(ass & 0x100000))
+ return 0;
+ if ((ass >> 30) != 1) /* no physical connection */
+ return 0;
+
+ /* check sum */
+ tmp = 0;
+ for (i = 1; i < 16; i++) {
+ if ((ass >> i) & 1)
+ tmp++;
+ }
+ if (((ass >> 16) & 0xf) != tmp)
+ return 0;
+do_sku:
+ snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
+ ass & 0xffff, codec->vendor_id);
+ /*
+ * 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:
+ spec->init_amp = ALC_INIT_GPIO1;
+ break;
+ case 3:
+ spec->init_amp = ALC_INIT_GPIO2;
+ break;
+ case 7:
+ spec->init_amp = ALC_INIT_GPIO3;
+ break;
+ case 5:
+ spec->init_amp = ALC_INIT_DEFAULT;
break;
}
@@ -1133,7 +1206,7 @@ do_sku:
* when the external headphone out jack is plugged"
*/
if (!(ass & 0x8000))
- return;
+ return 1;
/*
* 10~8 : Jack location
* 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
@@ -1141,14 +1214,6 @@ do_sku:
* 15 : 1 --> enable the function "Mute internal speaker
* when the external headphone out jack is plugged"
*/
- if (!spec->autocfg.speaker_pins[0]) {
- if (spec->autocfg.line_out_pins[0])
- spec->autocfg.speaker_pins[0] =
- spec->autocfg.line_out_pins[0];
- else
- return;
- }
-
if (!spec->autocfg.hp_pins[0]) {
tmp = (ass >> 11) & 0x3; /* HP to chassis */
if (tmp == 0)
@@ -1158,23 +1223,23 @@ do_sku:
else if (tmp == 2)
spec->autocfg.hp_pins[0] = portd;
else
- return;
+ return 1;
}
- if (spec->autocfg.hp_pins[0])
- snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | ALC880_HP_EVENT);
-#if 0 /* it's broken in some acses -- temporarily disabled */
- if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
- spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
- snd_hda_codec_write(codec,
- spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | ALC880_MIC_EVENT);
-#endif /* disabled */
+ alc_init_auto_hp(codec);
+ return 1;
+}
- spec->unsol_event = alc_sku_unsol_event;
+static void alc_ssid_check(struct hda_codec *codec,
+ hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
+{
+ if (!alc_subsystem_id(codec, porta, porte, portd)) {
+ struct alc_spec *spec = codec->spec;
+ snd_printd("realtek: "
+ "Enable default setup for auto mode as fallback\n");
+ spec->init_amp = ALC_INIT_DEFAULT;
+ alc_init_auto_hp(codec);
+ }
}
/*
@@ -1309,32 +1374,58 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
{}
};
-static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
+static void alc_automute_amp(struct hda_codec *codec)
{
- unsigned int present;
- unsigned int bits;
- /* Line out presence */
- present = snd_hda_codec_read(codec, 0x17, 0,
- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- /* HP out presence */
- present = present || snd_hda_codec_read(codec, 0x1b, 0,
- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? HDA_AMP_MUTE : 0;
+ struct alc_spec *spec = codec->spec;
+ unsigned int val, mute;
+ hda_nid_t nid;
+ int i;
+
+ spec->jack_present = 0;
+ for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
+ nid = spec->autocfg.hp_pins[i];
+ if (!nid)
+ break;
+ val = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_PIN_SENSE, 0);
+ if (val & AC_PINSENSE_PRESENCE) {
+ spec->jack_present = 1;
+ break;
+ }
+ }
+
+ mute = spec->jack_present ? HDA_AMP_MUTE : 0;
/* Toggle internal speakers muting */
- snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
- /* Toggle internal bass muting */
- snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
+ for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
+ nid = spec->autocfg.speaker_pins[i];
+ if (!nid)
+ break;
+ snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+ }
}
-static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
- unsigned int res)
+static void alc_automute_amp_unsol_event(struct hda_codec *codec,
+ unsigned int res)
{
- if (res >> 26 == ALC880_HP_EVENT)
- alc888_fujitsu_xa3530_automute(codec);
+ if (codec->vendor_id == 0x10ec0880)
+ res >>= 28;
+ else
+ res >>= 26;
+ if (res == ALC880_HP_EVENT)
+ alc_automute_amp(codec);
}
+static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x17; /* line-out */
+ spec->autocfg.hp_pins[1] = 0x1b; /* hp */
+ spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
+ spec->autocfg.speaker_pins[1] = 0x15; /* bass */
+ alc_automute_amp(codec);
+}
/*
* ALC888 Acer Aspire 4930G model
@@ -1401,22 +1492,13 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
{ } /* end */
};
-static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
+static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
{
- unsigned int present;
- unsigned int bits;
- present = snd_hda_codec_read(codec, 0x15, 0,
- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? HDA_AMP_MUTE : 0;
- snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
-}
+ struct alc_spec *spec = codec->spec;
-static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if (res >> 26 == ALC880_HP_EVENT)
- alc888_acer_aspire_4930g_automute(codec);
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc_automute_amp(codec);
}
/*
@@ -2384,21 +2466,6 @@ static struct hda_verb alc880_beep_init_verbs[] = {
{ }
};
-/* toggle speaker-output according to the hp-jack state */
-static void alc880_uniwill_hp_automute(struct hda_codec *codec)
-{
- unsigned int present;
- unsigned char bits;
-
- present = snd_hda_codec_read(codec, 0x14, 0,
- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- 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 */
static void alc880_uniwill_mic_automute(struct hda_codec *codec)
{
@@ -2411,9 +2478,14 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec)
snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
}
-static void alc880_uniwill_automute(struct hda_codec *codec)
+static void alc880_uniwill_init_hook(struct hda_codec *codec)
{
- alc880_uniwill_hp_automute(codec);
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x16;
+ alc_automute_amp(codec);
alc880_uniwill_mic_automute(codec);
}
@@ -2424,24 +2496,22 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
* definition. 4bit tag is placed at 28 bit!
*/
switch (res >> 28) {
- case ALC880_HP_EVENT:
- alc880_uniwill_hp_automute(codec);
- break;
case ALC880_MIC_EVENT:
alc880_uniwill_mic_automute(codec);
break;
+ default:
+ alc_automute_amp_unsol_event(codec, res);
+ break;
}
}
-static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
+static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
{
- unsigned int present;
- unsigned char bits;
+ struct alc_spec *spec = codec->spec;
- present = snd_hda_codec_read(codec, 0x14, 0,
- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? HDA_AMP_MUTE : 0;
- snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
+ spec->autocfg.hp_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[0] = 0x15;
+ alc_automute_amp(codec);
}
static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
@@ -2463,10 +2533,10 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
/* Looks like the unsol event is incompatible with the standard
* definition. 4bit tag is placed at 28 bit!
*/
- if ((res >> 28) == ALC880_HP_EVENT)
- alc880_uniwill_p53_hp_automute(codec);
if ((res >> 28) == ALC880_DCVOL_EVENT)
alc880_uniwill_p53_dcvol_automute(codec);
+ else
+ alc_automute_amp_unsol_event(codec, res);
}
/*
@@ -2698,30 +2768,18 @@ static struct hda_verb alc880_lg_init_verbs[] = {
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
/* jack sense */
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
{ }
};
/* toggle speaker-output according to the hp-jack state */
-static void alc880_lg_automute(struct hda_codec *codec)
+static void alc880_lg_init_hook(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 ? HDA_AMP_MUTE : 0;
- snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
-}
+ struct alc_spec *spec = codec->spec;
-static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- /* Looks like the unsol event is incompatible with the standard
- * definition. 4bit tag is placed at 28 bit!
- */
- if ((res >> 28) == 0x01)
- alc880_lg_automute(codec);
+ spec->autocfg.hp_pins[0] = 0x1b;
+ spec->autocfg.speaker_pins[0] = 0x17;
+ alc_automute_amp(codec);
}
/*
@@ -2795,30 +2853,18 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = {
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
/* jack sense */
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
{ }
};
/* toggle speaker-output according to the hp-jack state */
-static void alc880_lg_lw_automute(struct hda_codec *codec)
+static void alc880_lg_lw_init_hook(struct hda_codec *codec)
{
- unsigned int present;
- unsigned char bits;
+ struct alc_spec *spec = codec->spec;
- present = snd_hda_codec_read(codec, 0x1b, 0,
- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- 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)
-{
- /* Looks like the unsol event is incompatible with the standard
- * definition. 4bit tag is placed at 28 bit!
- */
- if ((res >> 28) == 0x01)
- alc880_lg_lw_automute(codec);
+ spec->autocfg.hp_pins[0] = 0x1b;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc_automute_amp(codec);
}
static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
@@ -2865,16 +2911,10 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = {
/* toggle speaker-output according to the hp-jack state */
static void alc880_medion_rim_automute(struct hda_codec *codec)
{
- unsigned int present;
- unsigned char bits;
-
- present = snd_hda_codec_read(codec, 0x14, 0,
- AC_VERB_GET_PIN_SENSE, 0)
- & AC_PINSENSE_PRESENCE;
- bits = present ? HDA_AMP_MUTE : 0;
- snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
- if (present)
+ struct alc_spec *spec = codec->spec;
+ alc_automute_amp(codec);
+ /* toggle EAPD */
+ if (spec->jack_present)
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
else
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
@@ -2890,6 +2930,15 @@ static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
alc880_medion_rim_automute(codec);
}
+static void alc880_medion_rim_init_hook(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[0] = 0x1b;
+ alc880_medion_rim_automute(codec);
+}
+
#ifdef CONFIG_SND_HDA_POWER_SAVE
static struct hda_amp_list alc880_loopbacks[] = {
{ 0x0b, HDA_INPUT, 0 },
@@ -2918,8 +2967,7 @@ static int alc_init(struct hda_codec *codec)
unsigned int i;
alc_fix_pll(codec);
- if (codec->vendor_id == 0x10ec0888)
- alc888_coef_init(codec);
+ alc_auto_init_amp(codec, spec->init_amp);
for (i = 0; i < spec->num_init_verbs; i++)
snd_hda_sequence_write(codec, spec->init_verbs[i]);
@@ -3749,7 +3797,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_2_jack_modes,
.input_mux = &alc880_f1734_capture_source,
.unsol_event = alc880_uniwill_p53_unsol_event,
- .init_hook = alc880_uniwill_p53_hp_automute,
+ .init_hook = alc880_uniwill_p53_init_hook,
},
[ALC880_ASUS] = {
.mixers = { alc880_asus_mixer },
@@ -3826,7 +3874,7 @@ static struct alc_config_preset alc880_presets[] = {
.need_dac_fix = 1,
.input_mux = &alc880_capture_source,
.unsol_event = alc880_uniwill_unsol_event,
- .init_hook = alc880_uniwill_automute,
+ .init_hook = alc880_uniwill_init_hook,
},
[ALC880_UNIWILL_P53] = {
.mixers = { alc880_uniwill_p53_mixer },
@@ -3838,7 +3886,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_threestack_modes,
.input_mux = &alc880_capture_source,
.unsol_event = alc880_uniwill_p53_unsol_event,
- .init_hook = alc880_uniwill_p53_hp_automute,
+ .init_hook = alc880_uniwill_p53_init_hook,
},
[ALC880_FUJITSU] = {
.mixers = { alc880_fujitsu_mixer },
@@ -3852,7 +3900,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_2_jack_modes,
.input_mux = &alc880_capture_source,
.unsol_event = alc880_uniwill_p53_unsol_event,
- .init_hook = alc880_uniwill_p53_hp_automute,
+ .init_hook = alc880_uniwill_p53_init_hook,
},
[ALC880_CLEVO] = {
.mixers = { alc880_three_stack_mixer },
@@ -3877,8 +3925,8 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_lg_ch_modes,
.need_dac_fix = 1,
.input_mux = &alc880_lg_capture_source,
- .unsol_event = alc880_lg_unsol_event,
- .init_hook = alc880_lg_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc880_lg_init_hook,
#ifdef CONFIG_SND_HDA_POWER_SAVE
.loopbacks = alc880_lg_loopbacks,
#endif
@@ -3893,8 +3941,8 @@ static struct alc_config_preset alc880_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
.channel_mode = alc880_lg_lw_modes,
.input_mux = &alc880_lg_lw_capture_source,
- .unsol_event = alc880_lg_lw_unsol_event,
- .init_hook = alc880_lg_lw_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc880_lg_lw_init_hook,
},
[ALC880_MEDION_RIM] = {
.mixers = { alc880_medion_rim_mixer },
@@ -3908,7 +3956,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_2_jack_modes,
.input_mux = &alc880_medion_rim_capture_source,
.unsol_event = alc880_medion_rim_unsol_event,
- .init_hook = alc880_medion_rim_automute,
+ .init_hook = alc880_medion_rim_init_hook,
},
#ifdef CONFIG_SND_DEBUG
[ALC880_TEST] = {
@@ -4193,7 +4241,6 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int i;
- alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
for (i = 0; i < spec->autocfg.line_outs; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -4298,6 +4345,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
spec->num_mux_defs = 1;
spec->input_mux = &spec->private_imux[0];
+ alc_ssid_check(codec, 0x15, 0x1b, 0x14);
+
return 1;
}
@@ -5673,7 +5722,6 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
hda_nid_t nid;
- alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
nid = spec->autocfg.line_out_pins[0];
if (nid) {
int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -5783,6 +5831,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
spec->num_mux_defs = 1;
spec->input_mux = &spec->private_imux[0];
+ alc_ssid_check(codec, 0x10, 0x15, 0x0f);
+
return 1;
}
@@ -6109,6 +6159,16 @@ static struct hda_input_mux alc882_capture_source = {
{ "CD", 0x4 },
},
};
+
+static struct hda_input_mux mb5_capture_source = {
+ .num_items = 3,
+ .items = {
+ { "Mic", 0x1 },
+ { "Line", 0x2 },
+ { "CD", 0x4 },
+ },
+};
+
/*
* 2ch mode
*/
@@ -6238,6 +6298,20 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
{ } /* end */
};
+
+static struct snd_kcontrol_new alc885_mb5_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
+ HDA_BIND_MUTE ("Front Playback Switch", 0x0d, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
+ HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, 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, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x19, 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),
@@ -6465,6 +6539,38 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
{ }
};
+/* Macbook 5,1 */
+static struct hda_verb alc885_mb5_init_verbs[] = {
+ /* Front 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)},
+ /* LineOut mixer */
+ {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)},
+ /* Front Pin: output 0 (0x0d) */
+ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},
+ /* HP 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},
+ /* 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 */
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+
+ {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {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)},
+ { }
+};
+
/* Macbook Pro rev3 */
static struct hda_verb alc885_mbp3_init_verbs[] = {
/* Front mixer: unmute input/output amp left and right (volume = 0) */
@@ -6554,45 +6660,23 @@ static struct hda_verb alc885_imac24_init_verbs[] = {
};
/* Toggle speaker-output according to the hp-jack state */
-static void alc885_imac24_automute(struct hda_codec *codec)
+static void alc885_imac24_automute_init_hook(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, 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);
-}
+ struct alc_spec *spec = codec->spec;
-/* Processes unsolicited events. */
-static void alc885_imac24_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- /* Headphone insertion or removal. */
- if ((res >> 26) == ALC880_HP_EVENT)
- alc885_imac24_automute(codec);
+ spec->autocfg.hp_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[0] = 0x18;
+ spec->autocfg.speaker_pins[1] = 0x1a;
+ alc_automute_amp(codec);
}
-static void alc885_mbp3_automute(struct hda_codec *codec)
+static void alc885_mbp3_init_hook(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);
+ struct alc_spec *spec = codec->spec;
-}
-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);
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc_automute_amp(codec);
}
@@ -6617,24 +6701,25 @@ static struct hda_verb alc882_targa_verbs[] = {
/* toggle speaker-output according to the hp-jack state */
static void alc882_targa_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, 0x1b, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+ struct alc_spec *spec = codec->spec;
+ alc_automute_amp(codec);
snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
- present ? 1 : 3);
+ spec->jack_present ? 1 : 3);
+}
+
+static void alc882_targa_init_hook(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[0] = 0x1b;
+ alc882_targa_automute(codec);
}
static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
{
- /* Looks like the unsol event is incompatible with the standard
- * definition. 4bit tag is placed at 26 bit!
- */
- if (((res >> 26) == ALC880_HP_EVENT)) {
+ if ((res >> 26) == ALC880_HP_EVENT)
alc882_targa_automute(codec);
- }
}
static struct hda_verb alc882_asus_a7j_verbs[] = {
@@ -6716,7 +6801,7 @@ static void alc885_macpro_init_hook(struct hda_codec *codec)
static void alc885_imac24_init_hook(struct hda_codec *codec)
{
alc885_macpro_init_hook(codec);
- alc885_imac24_automute(codec);
+ alc885_imac24_automute_init_hook(codec);
}
/*
@@ -6809,6 +6894,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
[ALC882_ASUS_A7J] = "asus-a7j",
[ALC882_ASUS_A7M] = "asus-a7m",
[ALC885_MACPRO] = "macpro",
+ [ALC885_MB5] = "mb5",
[ALC885_MBP3] = "mbp3",
[ALC885_IMAC24] = "imac24",
[ALC882_AUTO] = "auto",
@@ -6886,8 +6972,20 @@ static struct alc_config_preset alc882_presets[] = {
.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,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc885_mbp3_init_hook,
+ },
+ [ALC885_MB5] = {
+ .mixers = { alc885_mb5_mixer },
+ .init_verbs = { alc885_mb5_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 = &mb5_capture_source,
+ .dig_out_nid = ALC882_DIGOUT_NID,
+ .dig_in_nid = ALC882_DIGIN_NID,
},
[ALC885_MACPRO] = {
.mixers = { alc882_macpro_mixer },
@@ -6911,7 +7009,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,
- .unsol_event = alc885_imac24_unsol_event,
+ .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc885_imac24_init_hook,
},
[ALC882_TARGA] = {
@@ -6928,7 +7026,7 @@ static struct alc_config_preset alc882_presets[] = {
.need_dac_fix = 1,
.input_mux = &alc882_capture_source,
.unsol_event = alc882_targa_unsol_event,
- .init_hook = alc882_targa_automute,
+ .init_hook = alc882_targa_init_hook,
},
[ALC882_ASUS_A7J] = {
.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
@@ -7008,7 +7106,6 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int i;
- alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
for (i = 0; i <= HDA_SIDE; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -7195,6 +7292,9 @@ static int patch_alc882(struct hda_codec *codec)
case 0x106b3800: /* MacbookPro4,1 - latter revision */
board_config = ALC885_MBP3;
break;
+ case 0x106b3f00: /* Macbook 5,1 */
+ board_config = ALC885_MB5;
+ break;
default:
/* ALC889A is handled better as ALC888-compatible */
if (codec->revision_id == 0x100101 ||
@@ -7776,8 +7876,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 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),
@@ -7926,16 +8024,14 @@ static struct hda_verb alc883_init_verbs[] = {
};
/* toggle speaker-output according to the hp-jack state */
-static void alc883_mitac_hp_automute(struct hda_codec *codec)
+static void alc883_mitac_init_hook(struct hda_codec *codec)
{
- unsigned int present;
+ struct alc_spec *spec = codec->spec;
- 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, 0x17, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[1] = 0x17;
+ alc_automute_amp(codec);
}
/* auto-toggle front mic */
@@ -7952,25 +8048,6 @@ static void alc883_mitac_mic_automute(struct hda_codec *codec)
}
*/
-static void alc883_mitac_automute(struct hda_codec *codec)
-{
- alc883_mitac_hp_automute(codec);
- /* alc883_mitac_mic_automute(codec); */
-}
-
-static void alc883_mitac_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- switch (res >> 26) {
- case ALC880_HP_EVENT:
- alc883_mitac_hp_automute(codec);
- break;
- case ALC880_MIC_EVENT:
- /* alc883_mitac_mic_automute(codec); */
- break;
- }
-}
-
static struct hda_verb alc883_mitac_verbs[] = {
/* HP */
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -8088,29 +8165,15 @@ static struct hda_verb alc888_6st_dell_verbs[] = {
{ }
};
-static void alc888_3st_hp_front_automute(struct hda_codec *codec)
+static void alc888_3st_hp_init_hook(struct hda_codec *codec)
{
- unsigned int present, bits;
+ struct alc_spec *spec = codec->spec;
- present = snd_hda_codec_read(codec, 0x1b, 0,
- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? HDA_AMP_MUTE : 0;
- snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
- snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
- snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
-}
-
-static void alc888_3st_hp_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- switch (res >> 26) {
- case ALC880_HP_EVENT:
- alc888_3st_hp_front_automute(codec);
- break;
- }
+ spec->autocfg.hp_pins[0] = 0x1b;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[1] = 0x16;
+ spec->autocfg.speaker_pins[2] = 0x18;
+ alc_automute_amp(codec);
}
static struct hda_verb alc888_3st_hp_verbs[] = {
@@ -8207,56 +8270,18 @@ static struct hda_verb alc883_medion_md2_verbs[] = {
};
/* toggle speaker-output according to the hp-jack state */
-static void alc883_medion_md2_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);
-}
-
-static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) == ALC880_HP_EVENT)
- alc883_medion_md2_automute(codec);
-}
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc883_tagra_automute(struct hda_codec *codec)
+static void alc883_medion_md2_init_hook(struct hda_codec *codec)
{
- unsigned int present;
- unsigned char bits;
-
- present = snd_hda_codec_read(codec, 0x14, 0,
- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- 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);
-}
+ struct alc_spec *spec = codec->spec;
-static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- if ((res >> 26) == ALC880_HP_EVENT)
- alc883_tagra_automute(codec);
+ spec->autocfg.hp_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[0] = 0x15;
+ alc_automute_amp(codec);
}
/* toggle speaker-output according to the hp-jack state */
-static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
-{
- unsigned int present;
- unsigned char bits;
-
- present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
- & AC_PINSENSE_PRESENCE;
- bits = present ? HDA_AMP_MUTE : 0;
- snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
-}
+#define alc883_tagra_init_hook alc882_targa_init_hook
+#define alc883_tagra_unsol_event alc882_targa_unsol_event
static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
{
@@ -8268,9 +8293,13 @@ static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
-static void alc883_clevo_m720_automute(struct hda_codec *codec)
+static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
{
- alc883_clevo_m720_hp_automute(codec);
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc_automute_amp(codec);
alc883_clevo_m720_mic_automute(codec);
}
@@ -8278,52 +8307,32 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
- case ALC880_HP_EVENT:
- alc883_clevo_m720_hp_automute(codec);
- break;
case ALC880_MIC_EVENT:
alc883_clevo_m720_mic_automute(codec);
break;
+ default:
+ alc_automute_amp_unsol_event(codec, res);
+ break;
}
}
/* toggle speaker-output according to the hp-jack state */
-static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
+static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
{
- unsigned int present;
- unsigned char bits;
+ struct alc_spec *spec = codec->spec;
- present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
- & AC_PINSENSE_PRESENCE;
- bits = present ? HDA_AMP_MUTE : 0;
- snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
+ spec->autocfg.hp_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[0] = 0x15;
+ alc_automute_amp(codec);
}
-static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
- unsigned int res)
+static void alc883_haier_w66_init_hook(struct hda_codec *codec)
{
- if ((res >> 26) == ALC880_HP_EVENT)
- alc883_2ch_fujitsu_pi2515_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);
-}
+ struct alc_spec *spec = codec->spec;
-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);
+ spec->autocfg.hp_pins[0] = 0x1b;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc_automute_amp(codec);
}
static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
@@ -8362,23 +8371,14 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
}
/* toggle speaker-output according to the hp-jack state */
-static void alc883_acer_aspire_automute(struct hda_codec *codec)
+static void alc883_acer_aspire_init_hook(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);
-}
+ struct alc_spec *spec = codec->spec;
-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);
+ spec->autocfg.hp_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[1] = 0x16;
+ alc_automute_amp(codec);
}
static struct hda_verb alc883_acer_eapd_verbs[] = {
@@ -8399,75 +8399,29 @@ static struct hda_verb alc883_acer_eapd_verbs[] = {
{ }
};
-static void alc888_6st_dell_front_automute(struct hda_codec *codec)
+static void alc888_6st_dell_init_hook(struct hda_codec *codec)
{
- unsigned int present;
+ struct alc_spec *spec = codec->spec;
- present = snd_hda_codec_read(codec, 0x1b, 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 ? HDA_AMP_MUTE : 0);
- snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
- snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+ spec->autocfg.hp_pins[0] = 0x1b;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[1] = 0x15;
+ spec->autocfg.speaker_pins[2] = 0x16;
+ spec->autocfg.speaker_pins[3] = 0x17;
+ alc_automute_amp(codec);
}
-static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
- unsigned int res)
+static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
{
- switch (res >> 26) {
- case ALC880_HP_EVENT:
- /* printk(KERN_DEBUG "hp_event\n"); */
- alc888_6st_dell_front_automute(codec);
- break;
- }
-}
-
-static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
-{
- unsigned int mute;
- unsigned int 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_stereo(codec, 0x14, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, HDA_AMP_MUTE);
- snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, HDA_AMP_MUTE);
- snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, HDA_AMP_MUTE);
- snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, HDA_AMP_MUTE);
- snd_hda_codec_amp_stereo(codec, 0x1a, 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_stereo(codec, 0x14, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
- snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
- snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
- snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
- snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
- }
-}
+ struct alc_spec *spec = codec->spec;
-static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) == ALC880_HP_EVENT)
- alc888_lenovo_sky_front_automute(codec);
+ spec->autocfg.hp_pins[0] = 0x1b;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[1] = 0x15;
+ spec->autocfg.speaker_pins[2] = 0x16;
+ spec->autocfg.speaker_pins[3] = 0x17;
+ spec->autocfg.speaker_pins[4] = 0x1a;
+ alc_automute_amp(codec);
}
/*
@@ -8555,39 +8509,33 @@ static void alc883_nb_mic_automute(struct hda_codec *codec)
0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
}
-static void alc883_M90V_speaker_automute(struct hda_codec *codec)
+static void alc883_M90V_init_hook(struct hda_codec *codec)
{
- unsigned int present;
- unsigned char bits;
+ struct alc_spec *spec = codec->spec;
- present = snd_hda_codec_read(codec, 0x1b, 0,
- AC_VERB_GET_PIN_SENSE, 0)
- & AC_PINSENSE_PRESENCE;
- bits = present ? 0 : PIN_OUT;
- snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- bits);
- snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- bits);
- snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- bits);
+ spec->autocfg.hp_pins[0] = 0x1b;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[1] = 0x15;
+ spec->autocfg.speaker_pins[2] = 0x16;
+ alc_automute_pin(codec);
}
static void alc883_mode2_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
- case ALC880_HP_EVENT:
- alc883_M90V_speaker_automute(codec);
- break;
case ALC880_MIC_EVENT:
alc883_nb_mic_automute(codec);
break;
+ default:
+ alc_sku_unsol_event(codec, res);
+ break;
}
}
static void alc883_mode2_inithook(struct hda_codec *codec)
{
- alc883_M90V_speaker_automute(codec);
+ alc883_M90V_init_hook(codec);
alc883_nb_mic_automute(codec);
}
@@ -8604,32 +8552,13 @@ static struct hda_verb alc888_asus_eee1601_verbs[] = {
{ } /* end */
};
-static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
-{
- unsigned int present;
- unsigned char bits;
-
- present = snd_hda_codec_read(codec, 0x14, 0,
- AC_VERB_GET_PIN_SENSE, 0)
- & AC_PINSENSE_PRESENCE;
- bits = present ? 0 : PIN_OUT;
- snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- bits);
-}
-
-static void alc883_eee1601_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- switch (res >> 26) {
- case ALC880_HP_EVENT:
- alc883_eee1601_speaker_automute(codec);
- break;
- }
-}
-
static void alc883_eee1601_inithook(struct hda_codec *codec)
{
- alc883_eee1601_speaker_automute(codec);
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[0] = 0x1b;
+ alc_automute_pin(codec);
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -8693,8 +8622,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
ALC888_ACER_ASPIRE_4930G),
SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
ALC888_ACER_ASPIRE_4930G),
- /* default Acer */
- SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER),
+ /* default Acer -- disabled as it causes more problems.
+ * model=auto should work fine now
+ */
+ /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
@@ -8842,7 +8773,7 @@ static struct alc_config_preset alc883_presets[] = {
.need_dac_fix = 1,
.input_mux = &alc883_capture_source,
.unsol_event = alc883_tagra_unsol_event,
- .init_hook = alc883_tagra_automute,
+ .init_hook = alc883_tagra_init_hook,
},
[ALC883_TARGA_2ch_DIG] = {
.mixers = { alc883_tagra_2ch_mixer},
@@ -8856,7 +8787,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
.unsol_event = alc883_tagra_unsol_event,
- .init_hook = alc883_tagra_automute,
+ .init_hook = alc883_tagra_init_hook,
},
[ALC883_ACER] = {
.mixers = { alc883_base_mixer },
@@ -8881,8 +8812,8 @@ static struct alc_config_preset alc883_presets[] = {
.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,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc883_acer_aspire_init_hook,
},
[ALC888_ACER_ASPIRE_4930G] = {
.mixers = { alc888_base_mixer,
@@ -8901,8 +8832,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_mux_defs =
ARRAY_SIZE(alc888_2_capture_sources),
.input_mux = alc888_2_capture_sources,
- .unsol_event = alc888_acer_aspire_4930g_unsol_event,
- .init_hook = alc888_acer_aspire_4930g_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc888_acer_aspire_4930g_init_hook,
},
[ALC883_MEDION] = {
.mixers = { alc883_fivestack_mixer,
@@ -8926,8 +8857,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
- .unsol_event = alc883_medion_md2_unsol_event,
- .init_hook = alc883_medion_md2_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc883_medion_md2_init_hook,
},
[ALC883_LAPTOP_EAPD] = {
.mixers = { alc883_base_mixer },
@@ -8948,7 +8879,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
.unsol_event = alc883_clevo_m720_unsol_event,
- .init_hook = alc883_clevo_m720_automute,
+ .init_hook = alc883_clevo_m720_init_hook,
},
[ALC883_LENOVO_101E_2ch] = {
.mixers = { alc883_lenovo_101e_2ch_mixer},
@@ -8972,8 +8903,8 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes,
.need_dac_fix = 1,
.input_mux = &alc883_lenovo_nb0763_capture_source,
- .unsol_event = alc883_medion_md2_unsol_event,
- .init_hook = alc883_medion_md2_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc883_medion_md2_init_hook,
},
[ALC888_LENOVO_MS7195_DIG] = {
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -8997,8 +8928,8 @@ static struct alc_config_preset alc883_presets[] = {
.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,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc883_haier_w66_init_hook,
},
[ALC888_3ST_HP] = {
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -9009,8 +8940,8 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc888_3st_hp_modes,
.need_dac_fix = 1,
.input_mux = &alc883_capture_source,
- .unsol_event = alc888_3st_hp_unsol_event,
- .init_hook = alc888_3st_hp_front_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc888_3st_hp_init_hook,
},
[ALC888_6ST_DELL] = {
.mixers = { alc883_base_mixer, alc883_chmode_mixer },
@@ -9022,8 +8953,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
.channel_mode = alc883_sixstack_modes,
.input_mux = &alc883_capture_source,
- .unsol_event = alc888_6st_dell_unsol_event,
- .init_hook = alc888_6st_dell_front_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc888_6st_dell_init_hook,
},
[ALC883_MITAC] = {
.mixers = { alc883_mitac_mixer },
@@ -9033,8 +8964,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
- .unsol_event = alc883_mitac_unsol_event,
- .init_hook = alc883_mitac_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc883_mitac_init_hook,
},
[ALC883_FUJITSU_PI2515] = {
.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
@@ -9046,8 +8977,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_fujitsu_pi2515_capture_source,
- .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
- .init_hook = alc883_2ch_fujitsu_pi2515_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
},
[ALC888_FUJITSU_XA3530] = {
.mixers = { alc888_base_mixer, alc883_chmode_mixer },
@@ -9064,8 +8995,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_mux_defs =
ARRAY_SIZE(alc888_2_capture_sources),
.input_mux = alc888_2_capture_sources,
- .unsol_event = alc888_fujitsu_xa3530_unsol_event,
- .init_hook = alc888_fujitsu_xa3530_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc888_fujitsu_xa3530_init_hook,
},
[ALC888_LENOVO_SKY] = {
.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
@@ -9077,8 +9008,8 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_sixstack_modes,
.need_dac_fix = 1,
.input_mux = &alc883_lenovo_sky_capture_source,
- .unsol_event = alc883_lenovo_sky_unsol_event,
- .init_hook = alc888_lenovo_sky_front_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc888_lenovo_sky_init_hook,
},
[ALC888_ASUS_M90V] = {
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -9106,7 +9037,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes,
.need_dac_fix = 1,
.input_mux = &alc883_asus_eee1601_capture_source,
- .unsol_event = alc883_eee1601_unsol_event,
+ .unsol_event = alc_sku_unsol_event,
.init_hook = alc883_eee1601_inithook,
},
[ALC1200_ASUS_P5Q] = {
@@ -9149,7 +9080,6 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int i;
- alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
for (i = 0; i <= HDA_SIDE; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -9312,6 +9242,7 @@ static int patch_alc883(struct hda_codec *codec)
if (!spec->capsrc_nids)
spec->capsrc_nids = alc883_capsrc_nids;
spec->capture_style = CAPT_MIX; /* matrix-style capture */
+ spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
break;
case 0x10ec0889:
spec->stream_name_analog = "ALC889 Analog";
@@ -9407,24 +9338,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
{ } /* end */
};
-static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x14, 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_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, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
- /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
/* update HP, line and mono-out pins according to the master switch */
static void alc262_hp_master_update(struct hda_codec *codec)
{
@@ -9480,14 +9393,7 @@ static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
alc262_hp_wildwest_automute(codec);
}
-static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- *ucontrol->value.integer.value = spec->master_sw;
- return 0;
-}
+#define alc262_hp_master_sw_get alc260_hp_master_sw_get
static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -9503,14 +9409,17 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
return 1;
}
+#define ALC262_HP_MASTER_SWITCH \
+ { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Master Playback Switch", \
+ .info = snd_ctl_boolean_mono_info, \
+ .get = alc262_hp_master_sw_get, \
+ .put = alc262_hp_master_sw_put, \
+ }
+
static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = alc262_hp_master_sw_get,
- .put = alc262_hp_master_sw_put,
- },
+ ALC262_HP_MASTER_SWITCH,
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -9534,13 +9443,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
};
static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = alc262_hp_master_sw_get,
- .put = alc262_hp_master_sw_put,
- },
+ ALC262_HP_MASTER_SWITCH,
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -9567,32 +9470,13 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
};
/* mute/unmute internal speaker according to the hp jack and mute state */
-static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
+static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- if (force || !spec->sense_updated) {
- unsigned int present;
- present = snd_hda_codec_read(codec, 0x15, 0,
- AC_VERB_GET_PIN_SENSE, 0);
- spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
- spec->sense_updated = 1;
- }
- snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
- spec->jack_present ? HDA_AMP_MUTE : 0);
-}
-
-static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) != ALC880_HP_EVENT)
- return;
- alc262_hp_t5735_automute(codec, 1);
-}
-
-static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
-{
- alc262_hp_t5735_automute(codec, 1);
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
+ alc_automute_amp(codec);
}
static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
@@ -9645,46 +9529,132 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = {
},
};
-/* 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)
+/* bind hp and internal speaker mute (with plug check) as master switch */
+static void alc262_hippo_master_update(struct hda_codec *codec)
{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change;
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
+ hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
+ hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
+ unsigned int mute;
- /* 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,
+ /* HP */
+ mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
+ snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+ /* mute internal speaker per jack sense */
+ if (spec->jack_present)
+ mute = HDA_AMP_MUTE;
+ if (line_nid)
+ snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
+ if (speaker_nid && speaker_nid != line_nid)
+ snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+}
+
+#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
+
+static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct alc_spec *spec = codec->spec;
+ int val = !!*ucontrol->value.integer.value;
+
+ if (val == spec->master_sw)
+ return 0;
+ spec->master_sw = val;
+ alc262_hippo_master_update(codec);
+ return 1;
+}
+
+#define ALC262_HIPPO_MASTER_SWITCH \
+ { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Master Playback Switch", \
+ .info = snd_ctl_boolean_mono_info, \
+ .get = alc262_hippo_master_sw_get, \
+ .put = alc262_hippo_master_sw_put, \
}
- return change;
+
+static struct snd_kcontrol_new alc262_hippo_mixer[] = {
+ ALC262_HIPPO_MASTER_SWITCH,
+ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 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_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, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+ { } /* end */
+};
+
+static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ ALC262_HIPPO_MASTER_SWITCH,
+ 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_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, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+ { } /* end */
+};
+
+/* mute/unmute internal speaker according to the hp jack and mute state */
+static void alc262_hippo_automute(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
+ unsigned int present;
+
+ /* 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;
+ alc262_hippo_master_update(codec);
}
+static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ if ((res >> 26) != ALC880_HP_EVENT)
+ return;
+ alc262_hippo_automute(codec);
+}
+
+static void alc262_hippo_init_hook(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc262_hippo_automute(codec);
+}
+
+static void alc262_hippo1_init_hook(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x1b;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc262_hippo_automute(codec);
+}
+
+
static struct snd_kcontrol_new alc262_sony_mixer[] = {
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),
- },
+ ALC262_HIPPO_MASTER_SWITCH,
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),
@@ -9693,8 +9663,8 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = {
};
static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ ALC262_HIPPO_MASTER_SWITCH,
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
@@ -9735,34 +9705,15 @@ static struct hda_verb alc262_tyan_verbs[] = {
};
/* unsolicited event for HP jack sensing */
-static void alc262_tyan_automute(struct hda_codec *codec)
+static void alc262_tyan_init_hook(struct hda_codec *codec)
{
- unsigned int mute;
- unsigned int present;
+ struct alc_spec *spec = codec->spec;
- 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 line output on ATX panel */
- snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, HDA_AMP_MUTE);
- } else {
- /* unmute line output if necessary */
- mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
- snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
- }
+ spec->autocfg.hp_pins[0] = 0x1b;
+ spec->autocfg.speaker_pins[0] = 0x15;
+ alc_automute_amp(codec);
}
-static void alc262_tyan_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) != ALC880_HP_EVENT)
- return;
- alc262_tyan_automute(codec);
-}
#define alc262_capture_mixer alc882_capture_mixer
#define alc262_capture_alt_mixer alc882_capture_alt_mixer
@@ -9917,99 +9868,25 @@ static void alc262_dmic_automute(struct hda_codec *codec)
AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
}
-/* toggle speaker-output according to the hp-jack state */
-static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
-{
- unsigned int present;
- unsigned char bits;
-
- present = snd_hda_codec_read(codec, 0x15, 0,
- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0 : PIN_OUT;
- snd_hda_codec_write(codec, 0x14, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
-}
-
-
/* unsolicited event for HP jack sensing */
static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
unsigned int res)
{
- if ((res >> 26) == ALC880_HP_EVENT)
- alc262_toshiba_s06_speaker_automute(codec);
if ((res >> 26) == ALC880_MIC_EVENT)
alc262_dmic_automute(codec);
-
+ else
+ alc_sku_unsol_event(codec, res);
}
static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
{
- alc262_toshiba_s06_speaker_automute(codec);
- alc262_dmic_automute(codec);
-}
-
-/* mute/unmute internal speaker according to the hp jack and mute state */
-static void alc262_hippo_automute(struct hda_codec *codec)
-{
struct alc_spec *spec = codec->spec;
- unsigned int mute;
- 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;
- if (spec->jack_present) {
- /* mute internal speaker */
- 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_stereo(codec, 0x14, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
- }
-}
-
-/* unsolicited event for HP jack sensing */
-static void alc262_hippo_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) != ALC880_HP_EVENT)
- return;
- alc262_hippo_automute(codec);
-}
-
-static void alc262_hippo1_automute(struct hda_codec *codec)
-{
- unsigned int mute;
- unsigned int 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_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_stereo(codec, 0x14, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
- }
-}
-/* unsolicited event for HP jack sensing */
-static void alc262_hippo1_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) != ALC880_HP_EVENT)
- return;
- alc262_hippo1_automute(codec);
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc_automute_pin(codec);
+ alc262_dmic_automute(codec);
}
/*
@@ -10279,14 +10156,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_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 = alc262_sony_master_sw_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
- },
+ ALC262_HIPPO_MASTER_SWITCH,
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),
@@ -10837,6 +10707,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
if (err < 0)
return err;
+ alc_ssid_check(codec, 0x15, 0x14, 0x1b);
+
return 1;
}
@@ -10939,7 +10811,7 @@ static struct alc_config_preset alc262_presets[] = {
.input_mux = &alc262_capture_source,
},
[ALC262_HIPPO] = {
- .mixers = { alc262_base_mixer },
+ .mixers = { alc262_hippo_mixer },
.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
.dac_nids = alc262_dac_nids,
@@ -10949,7 +10821,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,
+ .init_hook = alc262_hippo_init_hook,
},
[ALC262_HIPPO_1] = {
.mixers = { alc262_hippo1_mixer },
@@ -10961,8 +10833,8 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
.input_mux = &alc262_capture_source,
- .unsol_event = alc262_hippo1_unsol_event,
- .init_hook = alc262_hippo1_automute,
+ .unsol_event = alc262_hippo_unsol_event,
+ .init_hook = alc262_hippo1_init_hook,
},
[ALC262_FUJITSU] = {
.mixers = { alc262_fujitsu_mixer },
@@ -11024,7 +10896,7 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
.input_mux = &alc262_capture_source,
- .unsol_event = alc262_hp_t5735_unsol_event,
+ .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc262_hp_t5735_init_hook,
},
[ALC262_HP_RP5700] = {
@@ -11056,7 +10928,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,
+ .init_hook = alc262_hippo_init_hook,
},
[ALC262_BENQ_T31] = {
.mixers = { alc262_benq_t31_mixer },
@@ -11068,7 +10940,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,
+ .init_hook = alc262_hippo_init_hook,
},
[ALC262_ULTRA] = {
.mixers = { alc262_ultra_mixer },
@@ -11133,7 +11005,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,
+ .init_hook = alc262_hippo_init_hook,
},
[ALC262_TYAN] = {
.mixers = { alc262_tyan_mixer },
@@ -11145,8 +11017,8 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
.input_mux = &alc262_capture_source,
- .unsol_event = alc262_tyan_unsol_event,
- .init_hook = alc262_tyan_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc262_tyan_init_hook,
},
};
@@ -11290,6 +11162,17 @@ static struct snd_kcontrol_new alc268_base_mixer[] = {
{ }
};
+static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
+ /* output mixer control */
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
+ ALC262_HIPPO_MASTER_SWITCH,
+ 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),
+ { }
+};
+
/* bind Beep switches of both NID 0x0f and 0x10 */
static struct hda_bind_ctls alc268_bind_beep_sw = {
.ops = &snd_hda_bind_sw,
@@ -11313,8 +11196,6 @@ static struct hda_verb alc268_eapd_verbs[] = {
};
/* 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 */
@@ -11450,13 +11331,8 @@ static struct hda_verb alc268_acer_verbs[] = {
};
/* 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);
-}
+#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
+#define alc268_toshiba_init_hook alc262_hippo_init_hook
static void alc268_acer_unsol_event(struct hda_codec *codec,
unsigned int res)
@@ -11531,30 +11407,15 @@ static struct hda_verb alc268_dell_verbs[] = {
};
/* mute/unmute internal speaker according to the hp jack and mute state */
-static void alc268_dell_automute(struct hda_codec *codec)
+static void alc268_dell_init_hook(struct hda_codec *codec)
{
- unsigned int present;
- unsigned int mute;
-
- present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
- if (present & 0x80000000)
- 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);
-}
+ struct alc_spec *spec = codec->spec;
-static void alc268_dell_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) != ALC880_HP_EVENT)
- return;
- alc268_dell_automute(codec);
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc_automute_pin(codec);
}
-#define alc268_dell_init_hook alc268_dell_automute
-
static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -11573,16 +11434,6 @@ static struct hda_verb alc267_quanta_il1_verbs[] = {
{ }
};
-static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
-{
- unsigned int present;
-
- present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
- & AC_PINSENSE_PRESENCE;
- snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- present ? 0 : PIN_OUT);
-}
-
static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
{
unsigned int present;
@@ -11594,9 +11445,13 @@ static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
present ? 0x00 : 0x01);
}
-static void alc267_quanta_il1_automute(struct hda_codec *codec)
+static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
{
- alc267_quanta_il1_hp_automute(codec);
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc_automute_pin(codec);
alc267_quanta_il1_mic_automute(codec);
}
@@ -11604,12 +11459,12 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
- case ALC880_HP_EVENT:
- alc267_quanta_il1_hp_automute(codec);
- break;
case ALC880_MIC_EVENT:
alc267_quanta_il1_mic_automute(codec);
break;
+ default:
+ alc_sku_unsol_event(codec, res);
+ break;
}
}
@@ -12083,7 +11938,7 @@ static struct alc_config_preset alc268_presets[] = {
.channel_mode = alc268_modes,
.input_mux = &alc268_capture_source,
.unsol_event = alc267_quanta_il1_unsol_event,
- .init_hook = alc267_quanta_il1_automute,
+ .init_hook = alc267_quanta_il1_init_hook,
},
[ALC268_3ST] = {
.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
@@ -12101,7 +11956,7 @@ static struct alc_config_preset alc268_presets[] = {
.input_mux = &alc268_capture_source,
},
[ALC268_TOSHIBA] = {
- .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
+ .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
alc268_beep_mixer },
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_toshiba_verbs },
@@ -12115,7 +11970,7 @@ static struct alc_config_preset alc268_presets[] = {
.channel_mode = alc268_modes,
.input_mux = &alc268_capture_source,
.unsol_event = alc268_toshiba_unsol_event,
- .init_hook = alc268_toshiba_automute,
+ .init_hook = alc268_toshiba_init_hook,
},
[ALC268_ACER] = {
.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
@@ -12178,7 +12033,7 @@ static struct alc_config_preset alc268_presets[] = {
.hp_nid = 0x02,
.num_channel_mode = ARRAY_SIZE(alc268_modes),
.channel_mode = alc268_modes,
- .unsol_event = alc268_dell_unsol_event,
+ .unsol_event = alc_sku_unsol_event,
.init_hook = alc268_dell_init_hook,
.input_mux = &alc268_capture_source,
},
@@ -12198,7 +12053,7 @@ static struct alc_config_preset alc268_presets[] = {
.channel_mode = alc268_modes,
.input_mux = &alc268_capture_source,
.unsol_event = alc268_toshiba_unsol_event,
- .init_hook = alc268_toshiba_automute
+ .init_hook = alc268_toshiba_init_hook
},
#ifdef CONFIG_SND_DEBUG
[ALC268_TEST] = {
@@ -13920,7 +13775,6 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int i;
- alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
for (i = 0; i < spec->autocfg.line_outs; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -14003,6 +13857,8 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
set_capture_mixer(spec);
+ alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
+
return 1;
}
@@ -14611,19 +14467,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
{}
};
-/* toggle speaker-output according to the hp-jack state */
-static void alc861vd_lenovo_hp_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 ? 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)
{
unsigned int present;
@@ -14636,9 +14479,13 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
HDA_AMP_MUTE, bits);
}
-static void alc861vd_lenovo_automute(struct hda_codec *codec)
+static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
{
- alc861vd_lenovo_hp_automute(codec);
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x1b;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc_automute_amp(codec);
alc861vd_lenovo_mic_automute(codec);
}
@@ -14646,12 +14493,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
- case ALC880_HP_EVENT:
- alc861vd_lenovo_hp_automute(codec);
- break;
case ALC880_MIC_EVENT:
alc861vd_lenovo_mic_automute(codec);
break;
+ default:
+ alc_automute_amp_unsol_event(codec, res);
+ break;
}
}
@@ -14701,20 +14548,13 @@ static struct hda_verb alc861vd_dallas_verbs[] = {
};
/* toggle speaker-output according to the hp-jack state */
-static void alc861vd_dallas_automute(struct hda_codec *codec)
+static void alc861vd_dallas_init_hook(struct hda_codec *codec)
{
- unsigned int present;
+ struct alc_spec *spec = codec->spec;
- 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);
-}
-
-static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- if ((res >> 26) == ALC880_HP_EVENT)
- alc861vd_dallas_automute(codec);
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ alc_automute_amp(codec);
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -14828,7 +14668,7 @@ static struct alc_config_preset alc861vd_presets[] = {
.channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_capture_source,
.unsol_event = alc861vd_lenovo_unsol_event,
- .init_hook = alc861vd_lenovo_automute,
+ .init_hook = alc861vd_lenovo_init_hook,
},
[ALC861VD_DALLAS] = {
.mixers = { alc861vd_dallas_mixer },
@@ -14838,8 +14678,8 @@ static struct alc_config_preset alc861vd_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
.channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_dallas_capture_source,
- .unsol_event = alc861vd_dallas_unsol_event,
- .init_hook = alc861vd_dallas_automute,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc861vd_dallas_init_hook,
},
[ALC861VD_HP] = {
.mixers = { alc861vd_hp_mixer },
@@ -14850,8 +14690,8 @@ static struct alc_config_preset alc861vd_presets[] = {
.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,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .init_hook = alc861vd_dallas_init_hook,
},
[ALC660VD_ASUS_V1S] = {
.mixers = { alc861vd_lenovo_mixer },
@@ -14866,7 +14706,7 @@ static struct alc_config_preset alc861vd_presets[] = {
.channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_capture_source,
.unsol_event = alc861vd_lenovo_unsol_event,
- .init_hook = alc861vd_lenovo_automute,
+ .init_hook = alc861vd_lenovo_init_hook,
},
};
@@ -14884,7 +14724,6 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int i;
- alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
for (i = 0; i <= HDA_SIDE; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -15102,6 +14941,8 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
if (err < 0)
return err;
+ alc_ssid_check(codec, 0x15, 0x1b, 0x14);
+
return 1;
}
@@ -15282,6 +15123,38 @@ static struct hda_input_mux alc663_m51va_capture_source = {
},
};
+#if 1 /* set to 0 for testing other input sources below */
+static struct hda_input_mux alc272_nc10_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "Autoselect Mic", 0x0 },
+ { "Internal Mic", 0x1 },
+ },
+};
+#else
+static struct hda_input_mux alc272_nc10_capture_source = {
+ .num_items = 16,
+ .items = {
+ { "Autoselect Mic", 0x0 },
+ { "Internal Mic", 0x1 },
+ { "In-0x02", 0x2 },
+ { "In-0x03", 0x3 },
+ { "In-0x04", 0x4 },
+ { "In-0x05", 0x5 },
+ { "In-0x06", 0x6 },
+ { "In-0x07", 0x7 },
+ { "In-0x08", 0x8 },
+ { "In-0x09", 0x9 },
+ { "In-0x0a", 0x0a },
+ { "In-0x0b", 0x0b },
+ { "In-0x0c", 0x0c },
+ { "In-0x0d", 0x0d },
+ { "In-0x0e", 0x0e },
+ { "In-0x0f", 0x0f },
+ },
+};
+#endif
+
/*
* 2ch mode
*/
@@ -15421,10 +15294,8 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
};
static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-
- HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ ALC262_HIPPO_MASTER_SWITCH,
HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -15437,15 +15308,11 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
};
static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
- HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ ALC262_HIPPO_MASTER_SWITCH,
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
@@ -15953,51 +15820,25 @@ static void alc662_eeepc_mic_automute(struct hda_codec *codec)
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);
+ else
+ alc262_hippo_unsol_event(codec, res);
}
static void alc662_eeepc_inithook(struct hda_codec *codec)
{
- alc262_hippo1_automute( codec );
+ alc262_hippo1_init_hook(codec);
alc662_eeepc_mic_automute(codec);
}
-static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
-{
- unsigned int mute;
- unsigned int present;
-
- snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
- present = snd_hda_codec_read(codec, 0x14, 0,
- AC_VERB_GET_PIN_SENSE, 0);
- present = (present & 0x80000000) != 0;
- if (present) {
- /* mute internal speaker */
- snd_hda_codec_amp_stereo(codec, 0x1b, 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_stereo(codec, 0x1b, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
- }
-}
-
-/* unsolicited event for HP jack sensing */
-static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) == ALC880_HP_EVENT)
- alc662_eeepc_ep20_automute(codec);
-}
-
static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
{
- alc662_eeepc_ep20_automute(codec);
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x14;
+ spec->autocfg.speaker_pins[0] = 0x1b;
+ alc262_hippo_master_update(codec);
}
static void alc663_m51va_speaker_automute(struct hda_codec *codec)
@@ -16331,35 +16172,9 @@ static void alc663_g50v_inithook(struct hda_codec *codec)
alc662_eeepc_mic_automute(codec);
}
-/* bind hp and internal speaker mute (with plug check) */
-static int alc662_ecs_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, 0x1b, 0, HDA_OUTPUT, 0,
- HDA_AMP_MUTE,
- valp[0] ? 0 : HDA_AMP_MUTE);
- change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
- HDA_AMP_MUTE,
- valp[1] ? 0 : HDA_AMP_MUTE);
- if (change)
- alc262_hippo1_automute(codec);
- return change;
-}
-
static struct snd_kcontrol_new alc662_ecs_mixer[] = {
HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 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 = alc662_ecs_master_sw_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
- },
+ ALC262_HIPPO_MASTER_SWITCH,
HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -16371,6 +16186,23 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc272_nc10_mixer[] = {
+ /* Master Playback automatically created from Speaker and Headphone */
+ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 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),
+ HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
+ { } /* end */
+};
+
#ifdef CONFIG_SND_HDA_POWER_SAVE
#define alc662_loopbacks alc880_loopbacks
#endif
@@ -16404,6 +16236,9 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
[ALC663_ASUS_MODE4] = "asus-mode4",
[ALC663_ASUS_MODE5] = "asus-mode5",
[ALC663_ASUS_MODE6] = "asus-mode6",
+ [ALC272_DELL] = "dell",
+ [ALC272_DELL_ZM1] = "dell-zm1",
+ [ALC272_SAMSUNG_NC10] = "samsung-nc10",
[ALC662_AUTO] = "auto",
};
@@ -16461,6 +16296,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
ALC662_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
ALC662_3ST_6ch_DIG),
SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
@@ -16551,7 +16387,7 @@ static struct alc_config_preset alc662_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
.channel_mode = alc662_3ST_6ch_modes,
.input_mux = &alc662_lenovo_101e_capture_source,
- .unsol_event = alc662_eeepc_ep20_unsol_event,
+ .unsol_event = alc662_eeepc_unsol_event,
.init_hook = alc662_eeepc_ep20_inithook,
},
[ALC662_ECS] = {
@@ -16732,6 +16568,18 @@ static struct alc_config_preset alc662_presets[] = {
.unsol_event = alc663_m51va_unsol_event,
.init_hook = alc663_m51va_inithook,
},
+ [ALC272_SAMSUNG_NC10] = {
+ .mixers = { alc272_nc10_mixer },
+ .init_verbs = { alc662_init_verbs,
+ alc663_21jd_amic_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc272_dac_nids),
+ .dac_nids = alc272_dac_nids,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc272_nc10_capture_source,
+ .unsol_event = alc663_mode4_unsol_event,
+ .init_hook = alc663_mode4_inithook,
+ },
};
@@ -16926,7 +16774,6 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int i;
- alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
for (i = 0; i <= HDA_SIDE; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -17023,6 +16870,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
if (err < 0)
return err;
+ alc_ssid_check(codec, 0x15, 0x1b, 0x14);
+
return 1;
}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 917bc5d3ac2c..ecf53f755a09 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -100,6 +100,7 @@ enum {
STAC_HP_M4,
STAC_HP_DV5,
STAC_HP_HDX,
+ STAC_HP_DV4_1222NR,
STAC_92HD71BXX_MODELS
};
@@ -1836,6 +1837,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
[STAC_HP_M4] = NULL,
[STAC_HP_DV5] = NULL,
[STAC_HP_HDX] = NULL,
+ [STAC_HP_DV4_1222NR] = NULL,
};
static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
@@ -1847,6 +1849,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
[STAC_HP_M4] = "hp-m4",
[STAC_HP_DV5] = "hp-dv5",
[STAC_HP_HDX] = "hp-hdx",
+ [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr",
};
static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
@@ -1855,6 +1858,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
"DFI LanParty", STAC_92HD71BXX_REF),
SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
"DFI LanParty", STAC_92HD71BXX_REF),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb,
+ "HP dv4-1222nr", STAC_HP_DV4_1222NR),
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
"HP", STAC_HP_DV5),
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
@@ -4079,7 +4084,12 @@ static int stac92xx_init(struct hda_codec *codec)
pinctl = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
/* if PINCTL already set then skip */
- if (!(pinctl & AC_PINCTL_IN_EN)) {
+ /* Also, if both INPUT and OUTPUT are set,
+ * it must be a BIOS bug; need to override, too
+ */
+ if (!(pinctl & AC_PINCTL_IN_EN) ||
+ (pinctl & AC_PINCTL_OUT_EN)) {
+ pinctl &= ~AC_PINCTL_OUT_EN;
pinctl |= AC_PINCTL_IN_EN;
stac92xx_auto_set_pinctl(codec, nid,
pinctl);
@@ -4520,27 +4530,38 @@ static int stac92xx_resume(struct hda_codec *codec)
return 0;
}
-
/*
- * using power check for controlling mute led of HP HDX notebooks
+ * using power check for controlling mute led of HP notebooks
* check for mute state only on Speakers (nid = 0x10)
*
* For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise
* the LED is NOT working properly !
+ *
+ * Changed name to reflect that it now works for any designated
+ * model, not just HP HDX.
*/
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int stac92xx_hp_hdx_check_power_status(struct hda_codec *codec,
+static int stac92xx_hp_check_power_status(struct hda_codec *codec,
hda_nid_t nid)
{
struct sigmatel_spec *spec = codec->spec;
+ unsigned int gpio_bit = 0; /* gets rid of compiler warning */
+
+ switch (spec->board_config) {
+ case STAC_HP_DV4_1222NR:
+ gpio_bit = 0x01;
+ break;
+ case STAC_HP_HDX:
+ gpio_bit = 0x08;
+ }
if (nid == 0x10) {
if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
HDA_AMP_MUTE)
- spec->gpio_data &= ~0x08; /* orange */
+ spec->gpio_data &= ~gpio_bit; /* orange */
else
- spec->gpio_data |= 0x08; /* white */
+ spec->gpio_data |= gpio_bit; /* white */
stac_gpio_set(codec, spec->gpio_mask,
spec->gpio_dir,
@@ -5219,6 +5240,22 @@ again:
spec->num_smuxes = 0;
spec->num_dmuxes = 1;
break;
+ case STAC_HP_DV4_1222NR:
+ spec->num_dmics = 1;
+ /* I don't know if it needs 1 or 2 smuxes - will wait for
+ * bug reports to fix if needed
+ */
+ spec->num_smuxes = 1;
+ spec->num_dmuxes = 1;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ /* This controls MUTE LED */
+ spec->gpio_mask |= 0x01;
+ spec->gpio_dir |= 0x01;
+ spec->gpio_data |= 0x01;
+ codec->patch_ops.check_power_status =
+ stac92xx_hp_check_power_status;
+#endif
+ /* fallthrough */
case STAC_HP_DV5:
snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
@@ -5239,7 +5276,7 @@ again:
/* register check_power_status callback. */
codec->patch_ops.check_power_status =
- stac92xx_hp_hdx_check_power_status;
+ stac92xx_hp_check_power_status;
#endif
break;
};
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index b25a5cc637d6..8e004fb6961a 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -205,7 +205,7 @@ struct via_spec {
/* playback */
struct hda_multi_out multiout;
- hda_nid_t extra_dig_out_nid;
+ hda_nid_t slave_dig_outs[2];
/* capture */
unsigned int num_adc_nids;
@@ -731,21 +731,6 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}
-/* setup SPDIF output stream */
-static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid,
- unsigned int stream_tag, unsigned int format)
-{
- /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
- if (codec->spdif_ctls & AC_DIG1_ENABLE)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
- codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
- snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
- /* turn on again (if needed) */
- if (codec->spdif_ctls & AC_DIG1_ENABLE)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
- codec->spdif_ctls & 0xff);
-}
-
static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
@@ -753,19 +738,16 @@ static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct via_spec *spec = codec->spec;
- hda_nid_t nid;
-
- /* 1st or 2nd S/PDIF */
- if (substream->number == 0)
- nid = spec->multiout.dig_out_nid;
- else if (substream->number == 1)
- nid = spec->extra_dig_out_nid;
- else
- return -1;
+ return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+ stream_tag, format, substream);
+}
- mutex_lock(&codec->spdif_mutex);
- setup_dig_playback_stream(codec, nid, stream_tag, format);
- mutex_unlock(&codec->spdif_mutex);
+static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ struct via_spec *spec = codec->spec;
+ snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
return 0;
}
@@ -842,7 +824,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = {
.ops = {
.open = via_dig_playback_pcm_open,
.close = via_dig_playback_pcm_close,
- .prepare = via_dig_playback_pcm_prepare
+ .prepare = via_dig_playback_pcm_prepare,
+ .cleanup = via_dig_playback_pcm_cleanup
},
};
@@ -874,13 +857,6 @@ static int via_build_controls(struct hda_codec *codec)
if (err < 0)
return err;
spec->multiout.share_spdif = 1;
-
- if (spec->extra_dig_out_nid) {
- err = snd_hda_create_spdif_out_ctls(codec,
- spec->extra_dig_out_nid);
- if (err < 0)
- return err;
- }
}
if (spec->dig_in_nid) {
err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
@@ -1013,10 +989,6 @@ static void via_unsol_event(struct hda_codec *codec,
via_gpio_control(codec);
}
-static hda_nid_t slave_dig_outs[] = {
- 0,
-};
-
static int via_init(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
@@ -1051,8 +1023,9 @@ static int via_init(struct hda_codec *codec)
snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
- /* no slave outs */
- codec->slave_dig_outs = slave_dig_outs;
+ /* assign slave outs */
+ if (spec->slave_dig_outs[0])
+ codec->slave_dig_outs = spec->slave_dig_outs;
return 0;
}
@@ -2134,7 +2107,8 @@ static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
.ops = {
.open = via_dig_playback_pcm_open,
.close = via_dig_playback_pcm_close,
- .prepare = via_dig_playback_pcm_prepare
+ .prepare = via_dig_playback_pcm_prepare,
+ .cleanup = via_dig_playback_pcm_cleanup
},
};
@@ -2589,14 +2563,15 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
};
static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
- .substreams = 2,
+ .substreams = 1,
.channels_min = 2,
.channels_max = 2,
/* NID is set in via_build_pcms */
.ops = {
.open = via_dig_playback_pcm_open,
.close = via_dig_playback_pcm_close,
- .prepare = via_dig_playback_pcm_prepare
+ .prepare = via_dig_playback_pcm_prepare,
+ .cleanup = via_dig_playback_pcm_cleanup
},
};
@@ -2805,14 +2780,37 @@ static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
return 0;
}
+/* fill out digital output widgets; one for master and one for slave outputs */
+static void fill_dig_outs(struct hda_codec *codec)
+{
+ struct via_spec *spec = codec->spec;
+ int i;
+
+ for (i = 0; i < spec->autocfg.dig_outs; i++) {
+ hda_nid_t nid;
+ int conn;
+
+ nid = spec->autocfg.dig_out_pins[i];
+ if (!nid)
+ continue;
+ conn = snd_hda_get_connections(codec, nid, &nid, 1);
+ if (conn < 1)
+ continue;
+ if (!spec->multiout.dig_out_nid)
+ spec->multiout.dig_out_nid = nid;
+ else {
+ spec->slave_dig_outs[0] = nid;
+ break; /* at most two dig outs */
+ }
+ }
+}
+
static int vt1708S_parse_auto_config(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
int err;
- static hda_nid_t vt1708s_ignore[] = {0x21, 0};
- err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
- vt1708s_ignore);
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
if (err < 0)
return err;
err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
@@ -2833,10 +2831,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- if (spec->autocfg.dig_outs)
- spec->multiout.dig_out_nid = VT1708S_DIGOUT_NID;
-
- spec->extra_dig_out_nid = 0x15;
+ fill_dig_outs(codec);
if (spec->kctls.list)
spec->mixers[spec->num_mixers++] = spec->kctls.list;
@@ -3000,7 +2995,8 @@ static struct hda_pcm_stream vt1702_pcm_digital_playback = {
.ops = {
.open = via_dig_playback_pcm_open,
.close = via_dig_playback_pcm_close,
- .prepare = via_dig_playback_pcm_prepare
+ .prepare = via_dig_playback_pcm_prepare,
+ .cleanup = via_dig_playback_pcm_cleanup
},
};
@@ -3128,10 +3124,8 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
int err;
- static hda_nid_t vt1702_ignore[] = {0x1C, 0};
- err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
- vt1702_ignore);
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
if (err < 0)
return err;
err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
@@ -3152,10 +3146,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- if (spec->autocfg.dig_outs)
- spec->multiout.dig_out_nid = VT1702_DIGOUT_NID;
-
- spec->extra_dig_out_nid = 0x1B;
+ fill_dig_outs(codec);
if (spec->kctls.list)
spec->mixers[spec->num_mixers++] = spec->kctls.list;
diff --git a/sound/pci/lx6464es/Makefile b/sound/pci/lx6464es/Makefile
new file mode 100644
index 000000000000..eb04a6c73d8b
--- /dev/null
+++ b/sound/pci/lx6464es/Makefile
@@ -0,0 +1,2 @@
+snd-lx6464es-objs := lx6464es.o lx_core.o
+obj-$(CONFIG_SND_LX6464ES) += snd-lx6464es.o
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
new file mode 100644
index 000000000000..870bfc58c697
--- /dev/null
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -0,0 +1,1152 @@
+/* -*- linux-c -*- *
+ *
+ * ALSA driver for the digigram lx6464es interface
+ *
+ * Copyright (c) 2008, 2009 Tim Blechmann <tim@klingt.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; see the file COPYING. 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/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <sound/info.h>
+
+#include "lx6464es.h"
+
+MODULE_AUTHOR("Tim Blechmann");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("digigram lx6464es");
+MODULE_SUPPORTED_DEVICE("{digigram lx6464es{}}");
+
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+static const char card_name[] = "LX6464ES";
+
+
+#define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056
+
+static struct pci_device_id snd_lx6464es_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES),
+ .subvendor = PCI_VENDOR_ID_DIGIGRAM,
+ .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM
+ }, /* LX6464ES */
+ { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES),
+ .subvendor = PCI_VENDOR_ID_DIGIGRAM,
+ .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_CAE_SERIAL_SUBSYSTEM
+ }, /* LX6464ES-CAE */
+ { 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, snd_lx6464es_ids);
+
+
+
+/* PGO pour USERo dans le registre pci_0x06/loc_0xEC */
+#define CHIPSC_RESET_XILINX (1L<<16)
+
+
+/* alsa callbacks */
+static struct snd_pcm_hardware lx_caps = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S24_3BE),
+ .rates = (SNDRV_PCM_RATE_CONTINUOUS |
+ SNDRV_PCM_RATE_8000_192000),
+ .rate_min = 8000,
+ .rate_max = 192000,
+ .channels_min = 2,
+ .channels_max = 64,
+ .buffer_bytes_max = 64*2*3*MICROBLAZE_IBL_MAX*MAX_STREAM_BUFFER,
+ .period_bytes_min = (2*2*MICROBLAZE_IBL_MIN*2),
+ .period_bytes_max = (4*64*MICROBLAZE_IBL_MAX*MAX_STREAM_BUFFER),
+ .periods_min = 2,
+ .periods_max = MAX_STREAM_BUFFER,
+};
+
+static int lx_set_granularity(struct lx6464es *chip, u32 gran);
+
+
+static int lx_hardware_open(struct lx6464es *chip,
+ struct snd_pcm_substream *substream)
+{
+ int err = 0;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int channels = runtime->channels;
+ int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+
+ snd_pcm_uframes_t period_size = runtime->period_size;
+
+ snd_printd(LXP "allocating pipe for %d channels\n", channels);
+ err = lx_pipe_allocate(chip, 0, is_capture, channels);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "allocating pipe failed\n");
+ return err;
+ }
+
+ err = lx_set_granularity(chip, period_size);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "setting granularity to %ld failed\n",
+ period_size);
+ return err;
+ }
+
+ return 0;
+}
+
+static int lx_hardware_start(struct lx6464es *chip,
+ struct snd_pcm_substream *substream)
+{
+ int err = 0;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+
+ snd_printd(LXP "setting stream format\n");
+ err = lx_stream_set_format(chip, runtime, 0, is_capture);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "setting stream format failed\n");
+ return err;
+ }
+
+ snd_printd(LXP "starting pipe\n");
+ err = lx_pipe_start(chip, 0, is_capture);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "starting pipe failed\n");
+ return err;
+ }
+
+ snd_printd(LXP "waiting for pipe to start\n");
+ err = lx_pipe_wait_for_start(chip, 0, is_capture);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "waiting for pipe failed\n");
+ return err;
+ }
+
+ return err;
+}
+
+
+static int lx_hardware_stop(struct lx6464es *chip,
+ struct snd_pcm_substream *substream)
+{
+ int err = 0;
+ int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+
+ snd_printd(LXP "pausing pipe\n");
+ err = lx_pipe_pause(chip, 0, is_capture);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "pausing pipe failed\n");
+ return err;
+ }
+
+ snd_printd(LXP "waiting for pipe to become idle\n");
+ err = lx_pipe_wait_for_idle(chip, 0, is_capture);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "waiting for pipe failed\n");
+ return err;
+ }
+
+ snd_printd(LXP "stopping pipe\n");
+ err = lx_pipe_stop(chip, 0, is_capture);
+ if (err < 0) {
+ snd_printk(LXP "stopping pipe failed\n");
+ return err;
+ }
+
+ return err;
+}
+
+
+static int lx_hardware_close(struct lx6464es *chip,
+ struct snd_pcm_substream *substream)
+{
+ int err = 0;
+ int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+
+ snd_printd(LXP "releasing pipe\n");
+ err = lx_pipe_release(chip, 0, is_capture);
+ if (err < 0) {
+ snd_printk(LXP "releasing pipe failed\n");
+ return err;
+ }
+
+ return err;
+}
+
+
+static int lx_pcm_open(struct snd_pcm_substream *substream)
+{
+ struct lx6464es *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int err = 0;
+ int board_rate;
+
+ snd_printdd("->lx_pcm_open\n");
+ mutex_lock(&chip->setup_mutex);
+
+ /* copy the struct snd_pcm_hardware struct */
+ runtime->hw = lx_caps;
+
+#if 0
+ /* buffer-size should better be multiple of period-size */
+ err = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0) {
+ snd_printk(KERN_WARNING LXP "could not constrain periods\n");
+ goto exit;
+ }
+#endif
+
+ /* the clock rate cannot be changed */
+ board_rate = chip->board_sample_rate;
+ err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
+ board_rate, board_rate);
+
+ if (err < 0) {
+ snd_printk(KERN_WARNING LXP "could not constrain periods\n");
+ goto exit;
+ }
+
+ /* constrain period size */
+ err = snd_pcm_hw_constraint_minmax(runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ MICROBLAZE_IBL_MIN,
+ MICROBLAZE_IBL_MAX);
+ if (err < 0) {
+ snd_printk(KERN_WARNING LXP
+ "could not constrain period size\n");
+ goto exit;
+ }
+
+ snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);
+
+ snd_pcm_set_sync(substream);
+ err = 0;
+
+exit:
+ runtime->private_data = chip;
+
+ mutex_unlock(&chip->setup_mutex);
+ snd_printdd("<-lx_pcm_open, %d\n", err);
+ return err;
+}
+
+static int lx_pcm_close(struct snd_pcm_substream *substream)
+{
+ int err = 0;
+ snd_printdd("->lx_pcm_close\n");
+ return err;
+}
+
+static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream
+ *substream)
+{
+ struct lx6464es *chip = snd_pcm_substream_chip(substream);
+ snd_pcm_uframes_t pos;
+ unsigned long flags;
+ int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+
+ struct lx_stream *lx_stream = is_capture ? &chip->capture_stream :
+ &chip->playback_stream;
+
+ snd_printdd("->lx_pcm_stream_pointer\n");
+
+ spin_lock_irqsave(&chip->lock, flags);
+ pos = lx_stream->frame_pos * substream->runtime->period_size;
+ spin_unlock_irqrestore(&chip->lock, flags);
+
+ snd_printdd(LXP "stream_pointer at %ld\n", pos);
+ return pos;
+}
+
+static int lx_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ struct lx6464es *chip = snd_pcm_substream_chip(substream);
+ int err = 0;
+ const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+
+ snd_printdd("->lx_pcm_prepare\n");
+
+ mutex_lock(&chip->setup_mutex);
+
+ if (chip->hardware_running[is_capture]) {
+ err = lx_hardware_stop(chip, substream);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "failed to stop hardware. "
+ "Error code %d\n", err);
+ goto exit;
+ }
+
+ err = lx_hardware_close(chip, substream);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "failed to close hardware. "
+ "Error code %d\n", err);
+ goto exit;
+ }
+ }
+
+ snd_printd(LXP "opening hardware\n");
+ err = lx_hardware_open(chip, substream);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "failed to open hardware. "
+ "Error code %d\n", err);
+ goto exit;
+ }
+
+ err = lx_hardware_start(chip, substream);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "failed to start hardware. "
+ "Error code %d\n", err);
+ goto exit;
+ }
+
+ chip->hardware_running[is_capture] = 1;
+
+ if (chip->board_sample_rate != substream->runtime->rate) {
+ if (!err)
+ chip->board_sample_rate = substream->runtime->rate;
+ }
+
+exit:
+ mutex_unlock(&chip->setup_mutex);
+ return err;
+}
+
+static int lx_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params, int is_capture)
+{
+ struct lx6464es *chip = snd_pcm_substream_chip(substream);
+ int err = 0;
+
+ snd_printdd("->lx_pcm_hw_params\n");
+
+ mutex_lock(&chip->setup_mutex);
+
+ /* set dma buffer */
+ err = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+
+ if (is_capture)
+ chip->capture_stream.stream = substream;
+ else
+ chip->playback_stream.stream = substream;
+
+ mutex_unlock(&chip->setup_mutex);
+ return err;
+}
+
+static int lx_pcm_hw_params_playback(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ return lx_pcm_hw_params(substream, hw_params, 0);
+}
+
+static int lx_pcm_hw_params_capture(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ return lx_pcm_hw_params(substream, hw_params, 1);
+}
+
+static int lx_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ struct lx6464es *chip = snd_pcm_substream_chip(substream);
+ int err = 0;
+ int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+
+ snd_printdd("->lx_pcm_hw_free\n");
+ mutex_lock(&chip->setup_mutex);
+
+ if (chip->hardware_running[is_capture]) {
+ err = lx_hardware_stop(chip, substream);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "failed to stop hardware. "
+ "Error code %d\n", err);
+ goto exit;
+ }
+
+ err = lx_hardware_close(chip, substream);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "failed to close hardware. "
+ "Error code %d\n", err);
+ goto exit;
+ }
+
+ chip->hardware_running[is_capture] = 0;
+ }
+
+ err = snd_pcm_lib_free_pages(substream);
+
+ if (is_capture)
+ chip->capture_stream.stream = 0;
+ else
+ chip->playback_stream.stream = 0;
+
+exit:
+ mutex_unlock(&chip->setup_mutex);
+ return err;
+}
+
+static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream)
+{
+ struct snd_pcm_substream *substream = lx_stream->stream;
+ const int is_capture = lx_stream->is_capture;
+
+ int err;
+
+ const u32 channels = substream->runtime->channels;
+ const u32 bytes_per_frame = channels * 3;
+ const u32 period_size = substream->runtime->period_size;
+ const u32 periods = substream->runtime->periods;
+ const u32 period_bytes = period_size * bytes_per_frame;
+
+ dma_addr_t buf = substream->dma_buffer.addr;
+ int i;
+
+ u32 needed, freed;
+ u32 size_array[5];
+
+ for (i = 0; i != periods; ++i) {
+ u32 buffer_index = 0;
+
+ err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed,
+ size_array);
+ snd_printdd(LXP "starting: needed %d, freed %d\n",
+ needed, freed);
+
+ err = lx_buffer_give(chip, 0, is_capture, period_bytes,
+ lower_32_bits(buf), upper_32_bits(buf),
+ &buffer_index);
+
+ snd_printdd(LXP "starting: buffer index %x on %p (%d bytes)\n",
+ buffer_index, (void *)buf, period_bytes);
+ buf += period_bytes;
+ }
+
+ err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array);
+ snd_printdd(LXP "starting: needed %d, freed %d\n", needed, freed);
+
+ snd_printd(LXP "starting: starting stream\n");
+ err = lx_stream_start(chip, 0, is_capture);
+ if (err < 0)
+ snd_printk(KERN_ERR LXP "couldn't start stream\n");
+ else
+ lx_stream->status = LX_STREAM_STATUS_RUNNING;
+
+ lx_stream->frame_pos = 0;
+}
+
+static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream)
+{
+ const int is_capture = lx_stream->is_capture;
+ int err;
+
+ snd_printd(LXP "stopping: stopping stream\n");
+ err = lx_stream_stop(chip, 0, is_capture);
+ if (err < 0)
+ snd_printk(KERN_ERR LXP "couldn't stop stream\n");
+ else
+ lx_stream->status = LX_STREAM_STATUS_FREE;
+
+}
+
+static void lx_trigger_tasklet_dispatch_stream(struct lx6464es *chip,
+ struct lx_stream *lx_stream)
+{
+ switch (lx_stream->status) {
+ case LX_STREAM_STATUS_SCHEDULE_RUN:
+ lx_trigger_start(chip, lx_stream);
+ break;
+
+ case LX_STREAM_STATUS_SCHEDULE_STOP:
+ lx_trigger_stop(chip, lx_stream);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void lx_trigger_tasklet(unsigned long data)
+{
+ struct lx6464es *chip = (struct lx6464es *)data;
+ unsigned long flags;
+
+ snd_printdd("->lx_trigger_tasklet\n");
+
+ spin_lock_irqsave(&chip->lock, flags);
+ lx_trigger_tasklet_dispatch_stream(chip, &chip->capture_stream);
+ lx_trigger_tasklet_dispatch_stream(chip, &chip->playback_stream);
+ spin_unlock_irqrestore(&chip->lock, flags);
+}
+
+static int lx_pcm_trigger_dispatch(struct lx6464es *chip,
+ struct lx_stream *lx_stream, int cmd)
+{
+ int err = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN;
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ lx_stream->status = LX_STREAM_STATUS_SCHEDULE_STOP;
+ break;
+
+ default:
+ err = -EINVAL;
+ goto exit;
+ }
+ tasklet_schedule(&chip->trigger_tasklet);
+
+exit:
+ return err;
+}
+
+
+static int lx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct lx6464es *chip = snd_pcm_substream_chip(substream);
+ const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+ struct lx_stream *stream = is_capture ? &chip->capture_stream :
+ &chip->playback_stream;
+
+ snd_printdd("->lx_pcm_trigger\n");
+
+ return lx_pcm_trigger_dispatch(chip, stream, cmd);
+}
+
+static int snd_lx6464es_free(struct lx6464es *chip)
+{
+ snd_printdd("->snd_lx6464es_free\n");
+
+ lx_irq_disable(chip);
+
+ if (chip->irq >= 0)
+ free_irq(chip->irq, chip);
+
+ iounmap(chip->port_dsp_bar);
+ ioport_unmap(chip->port_plx_remapped);
+
+ pci_release_regions(chip->pci);
+ pci_disable_device(chip->pci);
+
+ kfree(chip);
+
+ return 0;
+}
+
+static int snd_lx6464es_dev_free(struct snd_device *device)
+{
+ return snd_lx6464es_free(device->device_data);
+}
+
+/* reset the dsp during initialization */
+static int __devinit lx_init_xilinx_reset(struct lx6464es *chip)
+{
+ int i;
+ u32 plx_reg = lx_plx_reg_read(chip, ePLX_CHIPSC);
+
+ snd_printdd("->lx_init_xilinx_reset\n");
+
+ /* activate reset of xilinx */
+ plx_reg &= ~CHIPSC_RESET_XILINX;
+
+ lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg);
+ msleep(1);
+
+ lx_plx_reg_write(chip, ePLX_MBOX3, 0);
+ msleep(1);
+
+ plx_reg |= CHIPSC_RESET_XILINX;
+ lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg);
+
+ /* deactivate reset of xilinx */
+ for (i = 0; i != 100; ++i) {
+ u32 reg_mbox3;
+ msleep(10);
+ reg_mbox3 = lx_plx_reg_read(chip, ePLX_MBOX3);
+ if (reg_mbox3) {
+ snd_printd(LXP "xilinx reset done\n");
+ snd_printdd(LXP "xilinx took %d loops\n", i);
+ break;
+ }
+ }
+
+ /* todo: add some error handling? */
+
+ /* clear mr */
+ lx_dsp_reg_write(chip, eReg_CSM, 0);
+
+ /* le xilinx ES peut ne pas etre encore pret, on attend. */
+ msleep(600);
+
+ return 0;
+}
+
+static int __devinit lx_init_xilinx_test(struct lx6464es *chip)
+{
+ u32 reg;
+
+ snd_printdd("->lx_init_xilinx_test\n");
+
+ /* TEST if we have access to Xilinx/MicroBlaze */
+ lx_dsp_reg_write(chip, eReg_CSM, 0);
+
+ reg = lx_dsp_reg_read(chip, eReg_CSM);
+
+ if (reg) {
+ snd_printk(KERN_ERR LXP "Problem: Reg_CSM %x.\n", reg);
+
+ /* PCI9056_SPACE0_REMAP */
+ lx_plx_reg_write(chip, ePLX_PCICR, 1);
+
+ reg = lx_dsp_reg_read(chip, eReg_CSM);
+ if (reg) {
+ snd_printk(KERN_ERR LXP "Error: Reg_CSM %x.\n", reg);
+ return -EAGAIN; /* seems to be appropriate */
+ }
+ }
+
+ snd_printd(LXP "Xilinx/MicroBlaze access test successful\n");
+
+ return 0;
+}
+
+/* initialize ethersound */
+static int __devinit lx_init_ethersound_config(struct lx6464es *chip)
+{
+ int i;
+ u32 orig_conf_es = lx_dsp_reg_read(chip, eReg_CONFES);
+
+ u32 default_conf_es = (64 << IOCR_OUTPUTS_OFFSET) |
+ (64 << IOCR_INPUTS_OFFSET) |
+ (FREQ_RATIO_SINGLE_MODE << FREQ_RATIO_OFFSET);
+
+ u32 conf_es = (orig_conf_es & CONFES_READ_PART_MASK)
+ | (default_conf_es & CONFES_WRITE_PART_MASK);
+
+ snd_printdd("->lx_init_ethersound\n");
+
+ chip->freq_ratio = FREQ_RATIO_SINGLE_MODE;
+
+ /*
+ * write it to the card !
+ * this actually kicks the ES xilinx, the first time since poweron.
+ * the MAC address in the Reg_ADMACESMSB Reg_ADMACESLSB registers
+ * is not ready before this is done, and the bit 2 in Reg_CSES is set.
+ * */
+ lx_dsp_reg_write(chip, eReg_CONFES, conf_es);
+
+ for (i = 0; i != 1000; ++i) {
+ if (lx_dsp_reg_read(chip, eReg_CSES) & 4) {
+ snd_printd(LXP "ethersound initialized after %dms\n",
+ i);
+ goto ethersound_initialized;
+ }
+ msleep(1);
+ }
+ snd_printk(KERN_WARNING LXP
+ "ethersound could not be initialized after %dms\n", i);
+ return -ETIMEDOUT;
+
+ ethersound_initialized:
+ snd_printd(LXP "ethersound initialized\n");
+ return 0;
+}
+
+static int __devinit lx_init_get_version_features(struct lx6464es *chip)
+{
+ u32 dsp_version;
+
+ int err;
+
+ snd_printdd("->lx_init_get_version_features\n");
+
+ err = lx_dsp_get_version(chip, &dsp_version);
+
+ if (err == 0) {
+ u32 freq;
+
+ snd_printk(LXP "DSP version: V%02d.%02d #%d\n",
+ (dsp_version>>16) & 0xff, (dsp_version>>8) & 0xff,
+ dsp_version & 0xff);
+
+ /* later: what firmware version do we expect? */
+
+ /* retrieve Play/Rec features */
+ /* done here because we may have to handle alternate
+ * DSP files. */
+ /* later */
+
+ /* init the EtherSound sample rate */
+ err = lx_dsp_get_clock_frequency(chip, &freq);
+ if (err == 0)
+ chip->board_sample_rate = freq;
+ snd_printd(LXP "actual clock frequency %d\n", freq);
+ } else {
+ snd_printk(KERN_ERR LXP "DSP corrupted \n");
+ err = -EAGAIN;
+ }
+
+ return err;
+}
+
+static int lx_set_granularity(struct lx6464es *chip, u32 gran)
+{
+ int err = 0;
+ u32 snapped_gran = MICROBLAZE_IBL_MIN;
+
+ snd_printdd("->lx_set_granularity\n");
+
+ /* blocksize is a power of 2 */
+ while ((snapped_gran < gran) &&
+ (snapped_gran < MICROBLAZE_IBL_MAX)) {
+ snapped_gran *= 2;
+ }
+
+ if (snapped_gran == chip->pcm_granularity)
+ return 0;
+
+ err = lx_dsp_set_granularity(chip, snapped_gran);
+ if (err < 0) {
+ snd_printk(KERN_WARNING LXP "could not set granularity\n");
+ err = -EAGAIN;
+ }
+
+ if (snapped_gran != gran)
+ snd_printk(LXP "snapped blocksize to %d\n", snapped_gran);
+
+ snd_printd(LXP "set blocksize on board %d\n", snapped_gran);
+ chip->pcm_granularity = snapped_gran;
+
+ return err;
+}
+
+/* initialize and test the xilinx dsp chip */
+static int __devinit lx_init_dsp(struct lx6464es *chip)
+{
+ int err;
+ u8 mac_address[6];
+ int i;
+
+ snd_printdd("->lx_init_dsp\n");
+
+ snd_printd(LXP "initialize board\n");
+ err = lx_init_xilinx_reset(chip);
+ if (err)
+ return err;
+
+ snd_printd(LXP "testing board\n");
+ err = lx_init_xilinx_test(chip);
+ if (err)
+ return err;
+
+ snd_printd(LXP "initialize ethersound configuration\n");
+ err = lx_init_ethersound_config(chip);
+ if (err)
+ return err;
+
+ lx_irq_enable(chip);
+
+ /** \todo the mac address should be ready by not, but it isn't,
+ * so we wait for it */
+ for (i = 0; i != 1000; ++i) {
+ err = lx_dsp_get_mac(chip, mac_address);
+ if (err)
+ return err;
+ if (mac_address[0] || mac_address[1] || mac_address[2] ||
+ mac_address[3] || mac_address[4] || mac_address[5])
+ goto mac_ready;
+ msleep(1);
+ }
+ return -ETIMEDOUT;
+
+mac_ready:
+ snd_printd(LXP "mac address ready read after: %dms\n", i);
+ snd_printk(LXP "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n",
+ mac_address[0], mac_address[1], mac_address[2],
+ mac_address[3], mac_address[4], mac_address[5]);
+
+ err = lx_init_get_version_features(chip);
+ if (err)
+ return err;
+
+ lx_set_granularity(chip, MICROBLAZE_IBL_DEFAULT);
+
+ chip->playback_mute = 0;
+
+ return err;
+}
+
+static struct snd_pcm_ops lx_ops_playback = {
+ .open = lx_pcm_open,
+ .close = lx_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .prepare = lx_pcm_prepare,
+ .hw_params = lx_pcm_hw_params_playback,
+ .hw_free = lx_pcm_hw_free,
+ .trigger = lx_pcm_trigger,
+ .pointer = lx_pcm_stream_pointer,
+};
+
+static struct snd_pcm_ops lx_ops_capture = {
+ .open = lx_pcm_open,
+ .close = lx_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .prepare = lx_pcm_prepare,
+ .hw_params = lx_pcm_hw_params_capture,
+ .hw_free = lx_pcm_hw_free,
+ .trigger = lx_pcm_trigger,
+ .pointer = lx_pcm_stream_pointer,
+};
+
+static int __devinit lx_pcm_create(struct lx6464es *chip)
+{
+ int err;
+ struct snd_pcm *pcm;
+
+ u32 size = 64 * /* channels */
+ 3 * /* 24 bit samples */
+ MAX_STREAM_BUFFER * /* periods */
+ MICROBLAZE_IBL_MAX * /* frames per period */
+ 2; /* duplex */
+
+ size = PAGE_ALIGN(size);
+
+ /* hardcoded device name & channel count */
+ err = snd_pcm_new(chip->card, (char *)card_name, 0,
+ 1, 1, &pcm);
+
+ pcm->private_data = chip;
+
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &lx_ops_playback);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &lx_ops_capture);
+
+ pcm->info_flags = 0;
+ strcpy(pcm->name, card_name);
+
+ err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ snd_dma_pci_data(chip->pci),
+ size, size);
+ if (err < 0)
+ return err;
+
+ chip->pcm = pcm;
+ chip->capture_stream.is_capture = 1;
+
+ return 0;
+}
+
+static int lx_control_playback_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 lx_control_playback_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct lx6464es *chip = snd_kcontrol_chip(kcontrol);
+ ucontrol->value.integer.value[0] = chip->playback_mute;
+ return 0;
+}
+
+static int lx_control_playback_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct lx6464es *chip = snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ int current_value = chip->playback_mute;
+
+ if (current_value != ucontrol->value.integer.value[0]) {
+ lx_level_unmute(chip, 0, !current_value);
+ chip->playback_mute = !current_value;
+ changed = 1;
+ }
+ return changed;
+}
+
+static struct snd_kcontrol_new lx_control_playback_switch __devinitdata = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "PCM Playback Switch",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0,
+ .info = lx_control_playback_info,
+ .get = lx_control_playback_get,
+ .put = lx_control_playback_put
+};
+
+
+
+static void lx_proc_levels_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
+{
+ u32 levels[64];
+ int err;
+ int i, j;
+ struct lx6464es *chip = entry->private_data;
+
+ snd_iprintf(buffer, "capture levels:\n");
+ err = lx_level_peaks(chip, 1, 64, levels);
+ if (err < 0)
+ return;
+
+ for (i = 0; i != 8; ++i) {
+ for (j = 0; j != 8; ++j)
+ snd_iprintf(buffer, "%08x ", levels[i*8+j]);
+ snd_iprintf(buffer, "\n");
+ }
+
+ snd_iprintf(buffer, "\nplayback levels:\n");
+
+ err = lx_level_peaks(chip, 0, 64, levels);
+ if (err < 0)
+ return;
+
+ for (i = 0; i != 8; ++i) {
+ for (j = 0; j != 8; ++j)
+ snd_iprintf(buffer, "%08x ", levels[i*8+j]);
+ snd_iprintf(buffer, "\n");
+ }
+
+ snd_iprintf(buffer, "\n");
+}
+
+static int __devinit lx_proc_create(struct snd_card *card, struct lx6464es *chip)
+{
+ struct snd_info_entry *entry;
+ int err = snd_card_proc_new(card, "levels", &entry);
+ if (err < 0)
+ return err;
+
+ snd_info_set_text_ops(entry, chip, lx_proc_levels_read);
+ return 0;
+}
+
+
+static int __devinit snd_lx6464es_create(struct snd_card *card,
+ struct pci_dev *pci,
+ struct lx6464es **rchip)
+{
+ struct lx6464es *chip;
+ int err;
+
+ static struct snd_device_ops ops = {
+ .dev_free = snd_lx6464es_dev_free,
+ };
+
+ snd_printdd("->snd_lx6464es_create\n");
+
+ *rchip = NULL;
+
+ /* enable PCI device */
+ err = pci_enable_device(pci);
+ if (err < 0)
+ return err;
+
+ pci_set_master(pci);
+
+ /* check if we can restrict PCI DMA transfers to 32 bits */
+ err = pci_set_dma_mask(pci, DMA_32BIT_MASK);
+ if (err < 0) {
+ snd_printk(KERN_ERR "architecture does not support "
+ "32bit PCI busmaster DMA\n");
+ pci_disable_device(pci);
+ return -ENXIO;
+ }
+
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ if (chip == NULL) {
+ err = -ENOMEM;
+ goto alloc_failed;
+ }
+
+ chip->card = card;
+ chip->pci = pci;
+ chip->irq = -1;
+
+ /* initialize synchronization structs */
+ spin_lock_init(&chip->lock);
+ spin_lock_init(&chip->msg_lock);
+ mutex_init(&chip->setup_mutex);
+ tasklet_init(&chip->trigger_tasklet, lx_trigger_tasklet,
+ (unsigned long)chip);
+ tasklet_init(&chip->tasklet_capture, lx_tasklet_capture,
+ (unsigned long)chip);
+ tasklet_init(&chip->tasklet_playback, lx_tasklet_playback,
+ (unsigned long)chip);
+
+ /* request resources */
+ err = pci_request_regions(pci, card_name);
+ if (err < 0)
+ goto request_regions_failed;
+
+ /* plx port */
+ chip->port_plx = pci_resource_start(pci, 1);
+ chip->port_plx_remapped = ioport_map(chip->port_plx,
+ pci_resource_len(pci, 1));
+
+ /* dsp port */
+ chip->port_dsp_bar = pci_ioremap_bar(pci, 2);
+
+ err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED,
+ card_name, chip);
+ if (err) {
+ snd_printk(KERN_ERR LXP "unable to grab IRQ %d\n", pci->irq);
+ goto request_irq_failed;
+ }
+ chip->irq = pci->irq;
+
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0)
+ goto device_new_failed;
+
+ err = lx_init_dsp(chip);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "error during DSP initialization\n");
+ return err;
+ }
+
+ err = lx_pcm_create(chip);
+ if (err < 0)
+ return err;
+
+ err = lx_proc_create(card, chip);
+ if (err < 0)
+ return err;
+
+ err = snd_ctl_add(card, snd_ctl_new1(&lx_control_playback_switch,
+ chip));
+ if (err < 0)
+ return err;
+
+ snd_card_set_dev(card, &pci->dev);
+
+ *rchip = chip;
+ return 0;
+
+device_new_failed:
+ free_irq(pci->irq, chip);
+
+request_irq_failed:
+ pci_release_regions(pci);
+
+request_regions_failed:
+ kfree(chip);
+
+alloc_failed:
+ pci_disable_device(pci);
+
+ return err;
+}
+
+static int __devinit snd_lx6464es_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ static int dev;
+ struct snd_card *card;
+ struct lx6464es *chip;
+ int err;
+
+ snd_printdd("->snd_lx6464es_probe\n");
+
+ if (dev >= SNDRV_CARDS)
+ return -ENODEV;
+ if (!enable[dev]) {
+ dev++;
+ return -ENOENT;
+ }
+
+ err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+ if (err < 0)
+ return err;
+
+ err = snd_lx6464es_create(card, pci, &chip);
+ if (err < 0) {
+ snd_printk(KERN_ERR LXP "error during snd_lx6464es_create\n");
+ goto out_free;
+ }
+
+ strcpy(card->driver, "lx6464es");
+ strcpy(card->shortname, "Digigram LX6464ES");
+ sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i",
+ card->shortname, chip->port_plx,
+ chip->port_dsp_bar, chip->irq);
+
+ err = snd_card_register(card);
+ if (err < 0)
+ goto out_free;
+
+ snd_printdd(LXP "initialization successful\n");
+ pci_set_drvdata(pci, card);
+ dev++;
+ return 0;
+
+out_free:
+ snd_card_free(card);
+ return err;
+
+}
+
+static void __devexit snd_lx6464es_remove(struct pci_dev *pci)
+{
+ snd_card_free(pci_get_drvdata(pci));
+ pci_set_drvdata(pci, NULL);
+}
+
+
+static struct pci_driver driver = {
+ .name = "Digigram LX6464ES",
+ .id_table = snd_lx6464es_ids,
+ .probe = snd_lx6464es_probe,
+ .remove = __devexit_p(snd_lx6464es_remove),
+};
+
+
+/* module initialization */
+static int __init mod_init(void)
+{
+ return pci_register_driver(&driver);
+}
+
+static void __exit mod_exit(void)
+{
+ pci_unregister_driver(&driver);
+}
+
+module_init(mod_init);
+module_exit(mod_exit);
diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h
new file mode 100644
index 000000000000..012c010c8c89
--- /dev/null
+++ b/sound/pci/lx6464es/lx6464es.h
@@ -0,0 +1,114 @@
+/* -*- linux-c -*- *
+ *
+ * ALSA driver for the digigram lx6464es interface
+ *
+ * Copyright (c) 2009 Tim Blechmann <tim@klingt.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; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef LX6464ES_H
+#define LX6464ES_H
+
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+#include "lx_core.h"
+
+#define LXP "LX6464ES: "
+
+enum {
+ ES_cmd_free = 0, /* no command executing */
+ ES_cmd_processing = 1, /* execution of a read/write command */
+ ES_read_pending = 2, /* a asynchron read command is pending */
+ ES_read_finishing = 3, /* a read command has finished waiting (set by
+ * Interrupt or CancelIrp) */
+};
+
+enum lx_stream_status {
+ LX_STREAM_STATUS_FREE,
+/* LX_STREAM_STATUS_OPEN, */
+ LX_STREAM_STATUS_SCHEDULE_RUN,
+/* LX_STREAM_STATUS_STARTED, */
+ LX_STREAM_STATUS_RUNNING,
+ LX_STREAM_STATUS_SCHEDULE_STOP,
+/* LX_STREAM_STATUS_STOPPED, */
+/* LX_STREAM_STATUS_PAUSED */
+};
+
+
+struct lx_stream {
+ struct snd_pcm_substream *stream;
+ snd_pcm_uframes_t frame_pos;
+ enum lx_stream_status status; /* free, open, running, draining
+ * pause */
+ int is_capture:1;
+};
+
+
+struct lx6464es {
+ struct snd_card *card;
+ struct pci_dev *pci;
+ int irq;
+
+ spinlock_t lock; /* interrupt spinlock */
+ struct mutex setup_mutex; /* mutex used in hw_params, open
+ * and close */
+
+ struct tasklet_struct trigger_tasklet; /* trigger tasklet */
+ struct tasklet_struct tasklet_capture;
+ struct tasklet_struct tasklet_playback;
+
+ /* ports */
+ unsigned long port_plx; /* io port (size=256) */
+ void __iomem *port_plx_remapped; /* remapped plx port */
+ void __iomem *port_dsp_bar; /* memory port (32-bit,
+ * non-prefetchable,
+ * size=8K) */
+
+ /* messaging */
+ spinlock_t msg_lock; /* message spinlock */
+ atomic_t send_message_locked;
+ struct lx_rmh rmh;
+
+ /* configuration */
+ uint freq_ratio : 2;
+ uint playback_mute : 1;
+ uint hardware_running[2];
+ u32 board_sample_rate; /* sample rate read from
+ * board */
+ u32 sample_rate; /* our sample rate */
+ u16 pcm_granularity; /* board blocksize */
+
+ /* dma */
+ struct snd_dma_buffer capture_dma_buf;
+ struct snd_dma_buffer playback_dma_buf;
+
+ /* pcm */
+ struct snd_pcm *pcm;
+
+ /* streams */
+ struct lx_stream capture_stream;
+ struct lx_stream playback_stream;
+};
+
+
+#endif /* LX6464ES_H */
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c
new file mode 100644
index 000000000000..5812780d6e89
--- /dev/null
+++ b/sound/pci/lx6464es/lx_core.c
@@ -0,0 +1,1444 @@
+/* -*- linux-c -*- *
+ *
+ * ALSA driver for the digigram lx6464es interface
+ * low-level interface
+ *
+ * Copyright (c) 2009 Tim Blechmann <tim@klingt.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; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/* #define RMH_DEBUG 1 */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#include "lx6464es.h"
+#include "lx_core.h"
+
+/* low-level register access */
+
+static const unsigned long dsp_port_offsets[] = {
+ 0,
+ 0x400,
+ 0x401,
+ 0x402,
+ 0x403,
+ 0x404,
+ 0x405,
+ 0x406,
+ 0x407,
+ 0x408,
+ 0x409,
+ 0x40a,
+ 0x40b,
+ 0x40c,
+
+ 0x410,
+ 0x411,
+ 0x412,
+ 0x413,
+ 0x414,
+ 0x415,
+ 0x416,
+
+ 0x420,
+ 0x430,
+ 0x431,
+ 0x432,
+ 0x433,
+ 0x434,
+ 0x440
+};
+
+static void __iomem *lx_dsp_register(struct lx6464es *chip, int port)
+{
+ void __iomem *base_address = chip->port_dsp_bar;
+ return base_address + dsp_port_offsets[port]*4;
+}
+
+unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port)
+{
+ void __iomem *address = lx_dsp_register(chip, port);
+ return ioread32(address);
+}
+
+void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len)
+{
+ void __iomem *address = lx_dsp_register(chip, port);
+ memcpy_fromio(data, address, len*sizeof(u32));
+}
+
+
+void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data)
+{
+ void __iomem *address = lx_dsp_register(chip, port);
+ iowrite32(data, address);
+}
+
+void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data,
+ u32 len)
+{
+ void __iomem *address = lx_dsp_register(chip, port);
+ memcpy_toio(address, data, len*sizeof(u32));
+}
+
+
+static const unsigned long plx_port_offsets[] = {
+ 0x04,
+ 0x40,
+ 0x44,
+ 0x48,
+ 0x4c,
+ 0x50,
+ 0x54,
+ 0x58,
+ 0x5c,
+ 0x64,
+ 0x68,
+ 0x6C
+};
+
+static void __iomem *lx_plx_register(struct lx6464es *chip, int port)
+{
+ void __iomem *base_address = chip->port_plx_remapped;
+ return base_address + plx_port_offsets[port];
+}
+
+unsigned long lx_plx_reg_read(struct lx6464es *chip, int port)
+{
+ void __iomem *address = lx_plx_register(chip, port);
+ return ioread32(address);
+}
+
+void lx_plx_reg_write(struct lx6464es *chip, int port, u32 data)
+{
+ void __iomem *address = lx_plx_register(chip, port);
+ iowrite32(data, address);
+}
+
+u32 lx_plx_mbox_read(struct lx6464es *chip, int mbox_nr)
+{
+ int index;
+
+ switch (mbox_nr) {
+ case 1:
+ index = ePLX_MBOX1; break;
+ case 2:
+ index = ePLX_MBOX2; break;
+ case 3:
+ index = ePLX_MBOX3; break;
+ case 4:
+ index = ePLX_MBOX4; break;
+ case 5:
+ index = ePLX_MBOX5; break;
+ case 6:
+ index = ePLX_MBOX6; break;
+ case 7:
+ index = ePLX_MBOX7; break;
+ case 0: /* reserved for HF flags */
+ snd_BUG();
+ default:
+ return 0xdeadbeef;
+ }
+
+ return lx_plx_reg_read(chip, index);
+}
+
+int lx_plx_mbox_write(struct lx6464es *chip, int mbox_nr, u32 value)
+{
+ int index = -1;
+
+ switch (mbox_nr) {
+ case 1:
+ index = ePLX_MBOX1; break;
+ case 3:
+ index = ePLX_MBOX3; break;
+ case 4:
+ index = ePLX_MBOX4; break;
+ case 5:
+ index = ePLX_MBOX5; break;
+ case 6:
+ index = ePLX_MBOX6; break;
+ case 7:
+ index = ePLX_MBOX7; break;
+ case 0: /* reserved for HF flags */
+ case 2: /* reserved for Pipe States
+ * the DSP keeps an image of it */
+ snd_BUG();
+ return -EBADRQC;
+ }
+
+ lx_plx_reg_write(chip, index, value);
+ return 0;
+}
+
+
+/* rmh */
+
+#ifdef CONFIG_SND_DEBUG
+#define CMD_NAME(a) a
+#else
+#define CMD_NAME(a) NULL
+#endif
+
+#define Reg_CSM_MR 0x00000002
+#define Reg_CSM_MC 0x00000001
+
+struct dsp_cmd_info {
+ u32 dcCodeOp; /* Op Code of the command (usually 1st 24-bits
+ * word).*/
+ u16 dcCmdLength; /* Command length in words of 24 bits.*/
+ u16 dcStatusType; /* Status type: 0 for fixed length, 1 for
+ * random. */
+ u16 dcStatusLength; /* Status length (if fixed).*/
+ char *dcOpName;
+};
+
+/*
+ Initialization and control data for the Microblaze interface
+ - OpCode:
+ the opcode field of the command set at the proper offset
+ - CmdLength
+ the number of command words
+ - StatusType
+ offset in the status registers: 0 means that the return value may be
+ different from 0, and must be read
+ - StatusLength
+ the number of status words (in addition to the return value)
+*/
+
+static struct dsp_cmd_info dsp_commands[] =
+{
+ { (CMD_00_INFO_DEBUG << OPCODE_OFFSET) , 1 /*custom*/
+ , 1 , 0 /**/ , CMD_NAME("INFO_DEBUG") },
+ { (CMD_01_GET_SYS_CFG << OPCODE_OFFSET) , 1 /**/
+ , 1 , 2 /**/ , CMD_NAME("GET_SYS_CFG") },
+ { (CMD_02_SET_GRANULARITY << OPCODE_OFFSET) , 1 /**/
+ , 1 , 0 /**/ , CMD_NAME("SET_GRANULARITY") },
+ { (CMD_03_SET_TIMER_IRQ << OPCODE_OFFSET) , 1 /**/
+ , 1 , 0 /**/ , CMD_NAME("SET_TIMER_IRQ") },
+ { (CMD_04_GET_EVENT << OPCODE_OFFSET) , 1 /**/
+ , 1 , 0 /*up to 10*/ , CMD_NAME("GET_EVENT") },
+ { (CMD_05_GET_PIPES << OPCODE_OFFSET) , 1 /**/
+ , 1 , 2 /*up to 4*/ , CMD_NAME("GET_PIPES") },
+ { (CMD_06_ALLOCATE_PIPE << OPCODE_OFFSET) , 1 /**/
+ , 0 , 0 /**/ , CMD_NAME("ALLOCATE_PIPE") },
+ { (CMD_07_RELEASE_PIPE << OPCODE_OFFSET) , 1 /**/
+ , 0 , 0 /**/ , CMD_NAME("RELEASE_PIPE") },
+ { (CMD_08_ASK_BUFFERS << OPCODE_OFFSET) , 1 /**/
+ , 1 , MAX_STREAM_BUFFER , CMD_NAME("ASK_BUFFERS") },
+ { (CMD_09_STOP_PIPE << OPCODE_OFFSET) , 1 /**/
+ , 0 , 0 /*up to 2*/ , CMD_NAME("STOP_PIPE") },
+ { (CMD_0A_GET_PIPE_SPL_COUNT << OPCODE_OFFSET) , 1 /**/
+ , 1 , 1 /*up to 2*/ , CMD_NAME("GET_PIPE_SPL_COUNT") },
+ { (CMD_0B_TOGGLE_PIPE_STATE << OPCODE_OFFSET) , 1 /*up to 5*/
+ , 1 , 0 /**/ , CMD_NAME("TOGGLE_PIPE_STATE") },
+ { (CMD_0C_DEF_STREAM << OPCODE_OFFSET) , 1 /*up to 4*/
+ , 1 , 0 /**/ , CMD_NAME("DEF_STREAM") },
+ { (CMD_0D_SET_MUTE << OPCODE_OFFSET) , 3 /**/
+ , 1 , 0 /**/ , CMD_NAME("SET_MUTE") },
+ { (CMD_0E_GET_STREAM_SPL_COUNT << OPCODE_OFFSET) , 1/**/
+ , 1 , 2 /**/ , CMD_NAME("GET_STREAM_SPL_COUNT") },
+ { (CMD_0F_UPDATE_BUFFER << OPCODE_OFFSET) , 3 /*up to 4*/
+ , 0 , 1 /**/ , CMD_NAME("UPDATE_BUFFER") },
+ { (CMD_10_GET_BUFFER << OPCODE_OFFSET) , 1 /**/
+ , 1 , 4 /**/ , CMD_NAME("GET_BUFFER") },
+ { (CMD_11_CANCEL_BUFFER << OPCODE_OFFSET) , 1 /**/
+ , 1 , 1 /*up to 4*/ , CMD_NAME("CANCEL_BUFFER") },
+ { (CMD_12_GET_PEAK << OPCODE_OFFSET) , 1 /**/
+ , 1 , 1 /**/ , CMD_NAME("GET_PEAK") },
+ { (CMD_13_SET_STREAM_STATE << OPCODE_OFFSET) , 1 /**/
+ , 1 , 0 /**/ , CMD_NAME("SET_STREAM_STATE") },
+};
+
+static void lx_message_init(struct lx_rmh *rmh, enum cmd_mb_opcodes cmd)
+{
+ snd_BUG_ON(cmd >= CMD_14_INVALID);
+
+ rmh->cmd[0] = dsp_commands[cmd].dcCodeOp;
+ rmh->cmd_len = dsp_commands[cmd].dcCmdLength;
+ rmh->stat_len = dsp_commands[cmd].dcStatusLength;
+ rmh->dsp_stat = dsp_commands[cmd].dcStatusType;
+ rmh->cmd_idx = cmd;
+ memset(&rmh->cmd[1], 0, (REG_CRM_NUMBER - 1) * sizeof(u32));
+
+#ifdef CONFIG_SND_DEBUG
+ memset(rmh->stat, 0, REG_CRM_NUMBER * sizeof(u32));
+#endif
+#ifdef RMH_DEBUG
+ rmh->cmd_idx = cmd;
+#endif
+}
+
+#ifdef RMH_DEBUG
+#define LXRMH "lx6464es rmh: "
+static void lx_message_dump(struct lx_rmh *rmh)
+{
+ u8 idx = rmh->cmd_idx;
+ int i;
+
+ snd_printk(LXRMH "command %s\n", dsp_commands[idx].dcOpName);
+
+ for (i = 0; i != rmh->cmd_len; ++i)
+ snd_printk(LXRMH "\tcmd[%d] %08x\n", i, rmh->cmd[i]);
+
+ for (i = 0; i != rmh->stat_len; ++i)
+ snd_printk(LXRMH "\tstat[%d]: %08x\n", i, rmh->stat[i]);
+ snd_printk("\n");
+}
+#else
+static inline void lx_message_dump(struct lx_rmh *rmh)
+{}
+#endif
+
+
+
+/* sleep 500 - 100 = 400 times 100us -> the timeout is >= 40 ms */
+#define XILINX_TIMEOUT_MS 40
+#define XILINX_POLL_NO_SLEEP 100
+#define XILINX_POLL_ITERATIONS 150
+
+#if 0 /* not used now */
+static int lx_message_send(struct lx6464es *chip, struct lx_rmh *rmh)
+{
+ u32 reg = ED_DSP_TIMED_OUT;
+ int dwloop;
+ int answer_received;
+
+ if (lx_dsp_reg_read(chip, eReg_CSM) & (Reg_CSM_MC | Reg_CSM_MR)) {
+ snd_printk(KERN_ERR LXP "PIOSendMessage eReg_CSM %x\n", reg);
+ return -EBUSY;
+ }
+
+ /* write command */
+ lx_dsp_reg_writebuf(chip, eReg_CRM1, rmh->cmd, rmh->cmd_len);
+
+ snd_BUG_ON(atomic_read(&chip->send_message_locked) != 0);
+ atomic_set(&chip->send_message_locked, 1);
+
+ /* MicoBlaze gogogo */
+ lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC);
+
+ /* wait for interrupt to answer */
+ for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS; ++dwloop) {
+ answer_received = atomic_read(&chip->send_message_locked);
+ if (answer_received == 0)
+ break;
+ msleep(1);
+ }
+
+ if (answer_received == 0) {
+ /* in Debug mode verify Reg_CSM_MR */
+ snd_BUG_ON(!(lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR));
+
+ /* command finished, read status */
+ if (rmh->dsp_stat == 0)
+ reg = lx_dsp_reg_read(chip, eReg_CRM1);
+ else
+ reg = 0;
+ } else {
+ int i;
+ snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send! "
+ "Interrupts disabled?\n");
+
+ /* attente bit Reg_CSM_MR */
+ for (i = 0; i != XILINX_POLL_ITERATIONS; i++) {
+ if ((lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR)) {
+ if (rmh->dsp_stat == 0)
+ reg = lx_dsp_reg_read(chip, eReg_CRM1);
+ else
+ reg = 0;
+ goto polling_successful;
+ }
+
+ if (i > XILINX_POLL_NO_SLEEP)
+ msleep(1);
+ }
+ snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send! "
+ "polling failed\n");
+
+polling_successful:
+ atomic_set(&chip->send_message_locked, 0);
+ }
+
+ if ((reg & ERROR_VALUE) == 0) {
+ /* read response */
+ if (rmh->stat_len) {
+ snd_BUG_ON(rmh->stat_len >= (REG_CRM_NUMBER-1));
+
+ lx_dsp_reg_readbuf(chip, eReg_CRM2, rmh->stat,
+ rmh->stat_len);
+ }
+ } else
+ snd_printk(KERN_WARNING LXP "lx_message_send: error_value %x\n",
+ reg);
+
+ /* clear Reg_CSM_MR */
+ lx_dsp_reg_write(chip, eReg_CSM, 0);
+
+ switch (reg) {
+ case ED_DSP_TIMED_OUT:
+ snd_printk(KERN_WARNING LXP "lx_message_send: dsp timeout\n");
+ return -ETIMEDOUT;
+
+ case ED_DSP_CRASHED:
+ snd_printk(KERN_WARNING LXP "lx_message_send: dsp crashed\n");
+ return -EAGAIN;
+ }
+
+ lx_message_dump(rmh);
+ return 0;
+}
+#endif /* not used now */
+
+static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh)
+{
+ u32 reg = ED_DSP_TIMED_OUT;
+ int dwloop;
+
+ if (lx_dsp_reg_read(chip, eReg_CSM) & (Reg_CSM_MC | Reg_CSM_MR)) {
+ snd_printk(KERN_ERR LXP "PIOSendMessage eReg_CSM %x\n", reg);
+ return -EBUSY;
+ }
+
+ /* write command */
+ lx_dsp_reg_writebuf(chip, eReg_CRM1, rmh->cmd, rmh->cmd_len);
+
+ /* MicoBlaze gogogo */
+ lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC);
+
+ /* wait for interrupt to answer */
+ for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS * 1000; ++dwloop) {
+ if (lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR) {
+ if (rmh->dsp_stat == 0)
+ reg = lx_dsp_reg_read(chip, eReg_CRM1);
+ else
+ reg = 0;
+ goto polling_successful;
+ } else
+ udelay(1);
+ }
+ snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send_atomic! "
+ "polling failed\n");
+
+polling_successful:
+ if ((reg & ERROR_VALUE) == 0) {
+ /* read response */
+ if (rmh->stat_len) {
+ snd_BUG_ON(rmh->stat_len >= (REG_CRM_NUMBER-1));
+ lx_dsp_reg_readbuf(chip, eReg_CRM2, rmh->stat,
+ rmh->stat_len);
+ }
+ } else
+ snd_printk(LXP "rmh error: %08x\n", reg);
+
+ /* clear Reg_CSM_MR */
+ lx_dsp_reg_write(chip, eReg_CSM, 0);
+
+ switch (reg) {
+ case ED_DSP_TIMED_OUT:
+ snd_printk(KERN_WARNING LXP "lx_message_send: dsp timeout\n");
+ return -ETIMEDOUT;
+
+ case ED_DSP_CRASHED:
+ snd_printk(KERN_WARNING LXP "lx_message_send: dsp crashed\n");
+ return -EAGAIN;
+ }
+
+ lx_message_dump(rmh);
+
+ return reg;
+}
+
+
+/* low-level dsp access */
+int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version)
+{
+ u16 ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+
+ lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG);
+ ret = lx_message_send_atomic(chip, &chip->rmh);
+
+ *rdsp_version = chip->rmh.stat[1];
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return ret;
+}
+
+int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
+{
+ u16 ret = 0;
+ unsigned long flags;
+ u32 freq_raw = 0;
+ u32 freq = 0;
+ u32 frequency = 0;
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+
+ lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG);
+ ret = lx_message_send_atomic(chip, &chip->rmh);
+
+ if (ret == 0) {
+ freq_raw = chip->rmh.stat[0] >> FREQ_FIELD_OFFSET;
+ freq = freq_raw & XES_FREQ_COUNT8_MASK;
+
+ if ((freq < XES_FREQ_COUNT8_48_MAX) ||
+ (freq > XES_FREQ_COUNT8_44_MIN))
+ frequency = 0; /* unknown */
+ else if (freq >= XES_FREQ_COUNT8_44_MAX)
+ frequency = 44100;
+ else
+ frequency = 48000;
+ }
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+
+ *rfreq = frequency * chip->freq_ratio;
+
+ return ret;
+}
+
+int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address)
+{
+ u32 macmsb, maclsb;
+
+ macmsb = lx_dsp_reg_read(chip, eReg_ADMACESMSB) & 0x00FFFFFF;
+ maclsb = lx_dsp_reg_read(chip, eReg_ADMACESLSB) & 0x00FFFFFF;
+
+ /* todo: endianess handling */
+ mac_address[5] = ((u8 *)(&maclsb))[0];
+ mac_address[4] = ((u8 *)(&maclsb))[1];
+ mac_address[3] = ((u8 *)(&maclsb))[2];
+ mac_address[2] = ((u8 *)(&macmsb))[0];
+ mac_address[1] = ((u8 *)(&macmsb))[1];
+ mac_address[0] = ((u8 *)(&macmsb))[2];
+
+ return 0;
+}
+
+
+int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+
+ lx_message_init(&chip->rmh, CMD_02_SET_GRANULARITY);
+ chip->rmh.cmd[0] |= gran;
+
+ ret = lx_message_send_atomic(chip, &chip->rmh);
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return ret;
+}
+
+int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+
+ lx_message_init(&chip->rmh, CMD_04_GET_EVENT);
+ chip->rmh.stat_len = 9; /* we don't necessarily need the full length */
+
+ ret = lx_message_send_atomic(chip, &chip->rmh);
+
+ if (!ret)
+ memcpy(data, chip->rmh.stat, chip->rmh.stat_len * sizeof(u32));
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return ret;
+}
+
+#define CSES_TIMEOUT 100 /* microseconds */
+#define CSES_CE 0x0001
+#define CSES_BROADCAST 0x0002
+#define CSES_UPDATE_LDSV 0x0004
+
+int lx_dsp_es_check_pipeline(struct lx6464es *chip)
+{
+ int i;
+
+ for (i = 0; i != CSES_TIMEOUT; ++i) {
+ /*
+ * le bit CSES_UPDATE_LDSV est à 1 dés que le macprog
+ * est pret. il re-passe à 0 lorsque le premier read a
+ * été fait. pour l'instant on retire le test car ce bit
+ * passe a 1 environ 200 à 400 ms aprés que le registre
+ * confES à été écrit (kick du xilinx ES).
+ *
+ * On ne teste que le bit CE.
+ * */
+
+ u32 cses = lx_dsp_reg_read(chip, eReg_CSES);
+
+ if ((cses & CSES_CE) == 0)
+ return 0;
+
+ udelay(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
+
+#define PIPE_INFO_TO_CMD(capture, pipe) \
+ ((u32)((u32)(pipe) | ((capture) ? ID_IS_CAPTURE : 0L)) << ID_OFFSET)
+
+
+
+/* low-level pipe handling */
+int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture,
+ int channels)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_06_ALLOCATE_PIPE);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+ chip->rmh.cmd[0] |= channels;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+
+ if (err != 0)
+ snd_printk(KERN_ERR "lx6464es: could not allocate pipe\n");
+
+ return err;
+}
+
+int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_07_RELEASE_PIPE);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+
+ return err;
+}
+
+int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
+ u32 *r_needed, u32 *r_freed, u32 *size_array)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+#ifdef CONFIG_SND_DEBUG
+ if (size_array)
+ memset(size_array, 0, sizeof(u32)*MAX_STREAM_BUFFER);
+#endif
+
+ *r_needed = 0;
+ *r_freed = 0;
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_08_ASK_BUFFERS);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ if (!err) {
+ int i;
+ for (i = 0; i < MAX_STREAM_BUFFER; ++i) {
+ u32 stat = chip->rmh.stat[i];
+ if (stat & (BF_EOB << BUFF_FLAGS_OFFSET)) {
+ /* finished */
+ *r_freed += 1;
+ if (size_array)
+ size_array[i] = stat & MASK_DATA_SIZE;
+ } else if ((stat & (BF_VALID << BUFF_FLAGS_OFFSET))
+ == 0)
+ /* free */
+ *r_needed += 1;
+ }
+
+#if 0
+ snd_printdd(LXP "CMD_08_ASK_BUFFERS: needed %d, freed %d\n",
+ *r_needed, *r_freed);
+ for (i = 0; i < MAX_STREAM_BUFFER; ++i) {
+ for (i = 0; i != chip->rmh.stat_len; ++i)
+ snd_printdd(" stat[%d]: %x, %x\n", i,
+ chip->rmh.stat[i],
+ chip->rmh.stat[i] & MASK_DATA_SIZE);
+ }
+#endif
+ }
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+
+int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_09_STOP_PIPE);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+static int lx_pipe_toggle_state(struct lx6464es *chip, u32 pipe, int is_capture)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_0B_TOGGLE_PIPE_STATE);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+
+int lx_pipe_start(struct lx6464es *chip, u32 pipe, int is_capture)
+{
+ int err;
+
+ err = lx_pipe_wait_for_idle(chip, pipe, is_capture);
+ if (err < 0)
+ return err;
+
+ err = lx_pipe_toggle_state(chip, pipe, is_capture);
+
+ return err;
+}
+
+int lx_pipe_pause(struct lx6464es *chip, u32 pipe, int is_capture)
+{
+ int err = 0;
+
+ err = lx_pipe_wait_for_start(chip, pipe, is_capture);
+ if (err < 0)
+ return err;
+
+ err = lx_pipe_toggle_state(chip, pipe, is_capture);
+
+ return err;
+}
+
+
+int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture,
+ u64 *rsample_count)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+ chip->rmh.stat_len = 2; /* need all words here! */
+
+ err = lx_message_send_atomic(chip, &chip->rmh); /* don't sleep! */
+
+ if (err != 0)
+ snd_printk(KERN_ERR
+ "lx6464es: could not query pipe's sample count\n");
+ else {
+ *rsample_count = ((u64)(chip->rmh.stat[0] & MASK_SPL_COUNT_HI)
+ << 24) /* hi part */
+ + chip->rmh.stat[1]; /* lo part */
+ }
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ if (err != 0)
+ snd_printk(KERN_ERR "lx6464es: could not query pipe's state\n");
+ else
+ *rstate = (chip->rmh.stat[0] >> PSTATE_OFFSET) & 0x0F;
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+static int lx_pipe_wait_for_state(struct lx6464es *chip, u32 pipe,
+ int is_capture, u16 state)
+{
+ int i;
+
+ /* max 2*PCMOnlyGranularity = 2*1024 at 44100 = < 50 ms:
+ * timeout 50 ms */
+ for (i = 0; i != 50; ++i) {
+ u16 current_state;
+ int err = lx_pipe_state(chip, pipe, is_capture, &current_state);
+
+ if (err < 0)
+ return err;
+
+ if (current_state == state)
+ return 0;
+
+ mdelay(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
+int lx_pipe_wait_for_start(struct lx6464es *chip, u32 pipe, int is_capture)
+{
+ return lx_pipe_wait_for_state(chip, pipe, is_capture, PSTATE_RUN);
+}
+
+int lx_pipe_wait_for_idle(struct lx6464es *chip, u32 pipe, int is_capture)
+{
+ return lx_pipe_wait_for_state(chip, pipe, is_capture, PSTATE_IDLE);
+}
+
+/* low-level stream handling */
+int lx_stream_set_state(struct lx6464es *chip, u32 pipe,
+ int is_capture, enum stream_state_t state)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_13_SET_STREAM_STATE);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+ chip->rmh.cmd[0] |= state;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+
+ return err;
+}
+
+int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
+ u32 pipe, int is_capture)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ u32 channels = runtime->channels;
+
+ if (runtime->channels != channels)
+ snd_printk(KERN_ERR LXP "channel count mismatch: %d vs %d",
+ runtime->channels, channels);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_0C_DEF_STREAM);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+
+ if (runtime->sample_bits == 16)
+ /* 16 bit format */
+ chip->rmh.cmd[0] |= (STREAM_FMT_16b << STREAM_FMT_OFFSET);
+
+ if (snd_pcm_format_little_endian(runtime->format))
+ /* little endian/intel format */
+ chip->rmh.cmd[0] |= (STREAM_FMT_intel << STREAM_FMT_OFFSET);
+
+ chip->rmh.cmd[0] |= channels-1;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+
+ return err;
+}
+
+int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,
+ int *rstate)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ *rstate = (chip->rmh.stat[0] & SF_START) ? START_STATE : PAUSE_STATE;
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture,
+ u64 *r_bytepos)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ *r_bytepos = ((u64) (chip->rmh.stat[0] & MASK_SPL_COUNT_HI)
+ << 32) /* hi part */
+ + chip->rmh.stat[1]; /* lo part */
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+/* low-level buffer handling */
+int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture,
+ u32 buffer_size, u32 buf_address_lo, u32 buf_address_hi,
+ u32 *r_buffer_index)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_0F_UPDATE_BUFFER);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+ chip->rmh.cmd[0] |= BF_NOTIFY_EOB; /* request interrupt notification */
+
+ /* todo: pause request, circular buffer */
+
+ chip->rmh.cmd[1] = buffer_size & MASK_DATA_SIZE;
+ chip->rmh.cmd[2] = buf_address_lo;
+
+ if (buf_address_hi) {
+ chip->rmh.cmd_len = 4;
+ chip->rmh.cmd[3] = buf_address_hi;
+ chip->rmh.cmd[0] |= BF_64BITS_ADR;
+ }
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ if (err == 0) {
+ *r_buffer_index = chip->rmh.stat[0];
+ goto done;
+ }
+
+ if (err == EB_RBUFFERS_TABLE_OVERFLOW)
+ snd_printk(LXP "lx_buffer_give EB_RBUFFERS_TABLE_OVERFLOW\n");
+
+ if (err == EB_INVALID_STREAM)
+ snd_printk(LXP "lx_buffer_give EB_INVALID_STREAM\n");
+
+ if (err == EB_CMD_REFUSED)
+ snd_printk(LXP "lx_buffer_give EB_CMD_REFUSED\n");
+
+ done:
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture,
+ u32 *r_buffer_size)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+ chip->rmh.cmd[0] |= MASK_BUFFER_ID; /* ask for the current buffer: the
+ * microblaze will seek for it */
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ if (err == 0)
+ *r_buffer_size = chip->rmh.stat[0] & MASK_DATA_SIZE;
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture,
+ u32 buffer_index)
+{
+ int err;
+ unsigned long flags;
+
+ u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER);
+
+ chip->rmh.cmd[0] |= pipe_cmd;
+ chip->rmh.cmd[0] |= buffer_index;
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+
+/* low-level gain/peak handling
+ *
+ * \todo: can we unmute capture/playback channels independently?
+ *
+ * */
+int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute)
+{
+ int err;
+ unsigned long flags;
+
+ /* bit set to 1: channel muted */
+ u64 mute_mask = unmute ? 0 : 0xFFFFFFFFFFFFFFFFLLU;
+
+ spin_lock_irqsave(&chip->msg_lock, flags);
+ lx_message_init(&chip->rmh, CMD_0D_SET_MUTE);
+
+ chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, 0);
+
+ chip->rmh.cmd[1] = (u32)(mute_mask >> (u64)32); /* hi part */
+ chip->rmh.cmd[2] = (u32)(mute_mask & (u64)0xFFFFFFFF); /* lo part */
+
+ snd_printk("mute %x %x %x\n", chip->rmh.cmd[0], chip->rmh.cmd[1],
+ chip->rmh.cmd[2]);
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+static u32 peak_map[] = {
+ 0x00000109, /* -90.308dB */
+ 0x0000083B, /* -72.247dB */
+ 0x000020C4, /* -60.205dB */
+ 0x00008273, /* -48.030dB */
+ 0x00020756, /* -36.005dB */
+ 0x00040C37, /* -30.001dB */
+ 0x00081385, /* -24.002dB */
+ 0x00101D3F, /* -18.000dB */
+ 0x0016C310, /* -15.000dB */
+ 0x002026F2, /* -12.001dB */
+ 0x002D6A86, /* -9.000dB */
+ 0x004026E6, /* -6.004dB */
+ 0x005A9DF6, /* -3.000dB */
+ 0x0065AC8B, /* -2.000dB */
+ 0x00721481, /* -1.000dB */
+ 0x007FFFFF, /* FS */
+};
+
+int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels,
+ u32 *r_levels)
+{
+ int err = 0;
+ unsigned long flags;
+ int i;
+ spin_lock_irqsave(&chip->msg_lock, flags);
+
+ for (i = 0; i < channels; i += 4) {
+ u32 s0, s1, s2, s3;
+
+ lx_message_init(&chip->rmh, CMD_12_GET_PEAK);
+ chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, i);
+
+ err = lx_message_send_atomic(chip, &chip->rmh);
+
+ if (err == 0) {
+ s0 = peak_map[chip->rmh.stat[0] & 0x0F];
+ s1 = peak_map[(chip->rmh.stat[0] >> 4) & 0xf];
+ s2 = peak_map[(chip->rmh.stat[0] >> 8) & 0xf];
+ s3 = peak_map[(chip->rmh.stat[0] >> 12) & 0xf];
+ } else
+ s0 = s1 = s2 = s3 = 0;
+
+ r_levels[0] = s0;
+ r_levels[1] = s1;
+ r_levels[2] = s2;
+ r_levels[3] = s3;
+
+ r_levels += 4;
+ }
+
+ spin_unlock_irqrestore(&chip->msg_lock, flags);
+ return err;
+}
+
+/* interrupt handling */
+#define PCX_IRQ_NONE 0
+#define IRQCS_ACTIVE_PCIDB 0x00002000L /* Bit nø 13 */
+#define IRQCS_ENABLE_PCIIRQ 0x00000100L /* Bit nø 08 */
+#define IRQCS_ENABLE_PCIDB 0x00000200L /* Bit nø 09 */
+
+static u32 lx_interrupt_test_ack(struct lx6464es *chip)
+{
+ u32 irqcs = lx_plx_reg_read(chip, ePLX_IRQCS);
+
+ /* Test if PCI Doorbell interrupt is active */
+ if (irqcs & IRQCS_ACTIVE_PCIDB) {
+ u32 temp;
+ irqcs = PCX_IRQ_NONE;
+
+ while ((temp = lx_plx_reg_read(chip, ePLX_L2PCIDB))) {
+ /* RAZ interrupt */
+ irqcs |= temp;
+ lx_plx_reg_write(chip, ePLX_L2PCIDB, temp);
+ }
+
+ return irqcs;
+ }
+ return PCX_IRQ_NONE;
+}
+
+static int lx_interrupt_ack(struct lx6464es *chip, u32 *r_irqsrc,
+ int *r_async_pending, int *r_async_escmd)
+{
+ u32 irq_async;
+ u32 irqsrc = lx_interrupt_test_ack(chip);
+
+ if (irqsrc == PCX_IRQ_NONE)
+ return 0;
+
+ *r_irqsrc = irqsrc;
+
+ irq_async = irqsrc & MASK_SYS_ASYNC_EVENTS; /* + EtherSound response
+ * (set by xilinx) + EOB */
+
+ if (irq_async & MASK_SYS_STATUS_ESA) {
+ irq_async &= ~MASK_SYS_STATUS_ESA;
+ *r_async_escmd = 1;
+ }
+
+ if (irqsrc & MASK_SYS_STATUS_CMD_DONE)
+ /* xilinx command notification */
+ atomic_set(&chip->send_message_locked, 0);
+
+ if (irq_async) {
+ /* snd_printd("interrupt: async event pending\n"); */
+ *r_async_pending = 1;
+ }
+
+ return 1;
+}
+
+static int lx_interrupt_handle_async_events(struct lx6464es *chip, u32 irqsrc,
+ int *r_freq_changed,
+ u64 *r_notified_in_pipe_mask,
+ u64 *r_notified_out_pipe_mask)
+{
+ int err;
+ u32 stat[9]; /* answer from CMD_04_GET_EVENT */
+
+ /* On peut optimiser pour ne pas lire les evenements vides
+ * les mots de réponse sont dans l'ordre suivant :
+ * Stat[0] mot de status général
+ * Stat[1] fin de buffer OUT pF
+ * Stat[2] fin de buffer OUT pf
+ * Stat[3] fin de buffer IN pF
+ * Stat[4] fin de buffer IN pf
+ * Stat[5] underrun poid fort
+ * Stat[6] underrun poid faible
+ * Stat[7] overrun poid fort
+ * Stat[8] overrun poid faible
+ * */
+
+ u64 orun_mask;
+ u64 urun_mask;
+#if 0
+ int has_underrun = (irqsrc & MASK_SYS_STATUS_URUN) ? 1 : 0;
+ int has_overrun = (irqsrc & MASK_SYS_STATUS_ORUN) ? 1 : 0;
+#endif
+ int eb_pending_out = (irqsrc & MASK_SYS_STATUS_EOBO) ? 1 : 0;
+ int eb_pending_in = (irqsrc & MASK_SYS_STATUS_EOBI) ? 1 : 0;
+
+ *r_freq_changed = (irqsrc & MASK_SYS_STATUS_FREQ) ? 1 : 0;
+
+ err = lx_dsp_read_async_events(chip, stat);
+ if (err < 0)
+ return err;
+
+ if (eb_pending_in) {
+ *r_notified_in_pipe_mask = ((u64)stat[3] << 32)
+ + stat[4];
+ snd_printdd(LXP "interrupt: EOBI pending %llx\n",
+ *r_notified_in_pipe_mask);
+ }
+ if (eb_pending_out) {
+ *r_notified_out_pipe_mask = ((u64)stat[1] << 32)
+ + stat[2];
+ snd_printdd(LXP "interrupt: EOBO pending %llx\n",
+ *r_notified_out_pipe_mask);
+ }
+
+ orun_mask = ((u64)stat[7] << 32) + stat[8];
+ urun_mask = ((u64)stat[5] << 32) + stat[6];
+
+ /* todo: handle xrun notification */
+
+ return err;
+}
+
+static int lx_interrupt_request_new_buffer(struct lx6464es *chip,
+ struct lx_stream *lx_stream)
+{
+ struct snd_pcm_substream *substream = lx_stream->stream;
+ int is_capture = lx_stream->is_capture;
+ int err;
+ unsigned long flags;
+
+ const u32 channels = substream->runtime->channels;
+ const u32 bytes_per_frame = channels * 3;
+ const u32 period_size = substream->runtime->period_size;
+ const u32 period_bytes = period_size * bytes_per_frame;
+ const u32 pos = lx_stream->frame_pos;
+ const u32 next_pos = ((pos+1) == substream->runtime->periods) ?
+ 0 : pos + 1;
+
+ dma_addr_t buf = substream->dma_buffer.addr + pos * period_bytes;
+ u32 buf_hi = 0;
+ u32 buf_lo = 0;
+ u32 buffer_index = 0;
+
+ u32 needed, freed;
+ u32 size_array[MAX_STREAM_BUFFER];
+
+ snd_printdd("->lx_interrupt_request_new_buffer\n");
+
+ spin_lock_irqsave(&chip->lock, flags);
+
+ err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array);
+ snd_printdd(LXP "interrupt: needed %d, freed %d\n", needed, freed);
+
+ unpack_pointer(buf, &buf_lo, &buf_hi);
+ err = lx_buffer_give(chip, 0, is_capture, period_bytes, buf_lo, buf_hi,
+ &buffer_index);
+ snd_printdd(LXP "interrupt: gave buffer index %x on %p (%d bytes)\n",
+ buffer_index, (void *)buf, period_bytes);
+
+ lx_stream->frame_pos = next_pos;
+ spin_unlock_irqrestore(&chip->lock, flags);
+
+ return err;
+}
+
+void lx_tasklet_playback(unsigned long data)
+{
+ struct lx6464es *chip = (struct lx6464es *)data;
+ struct lx_stream *lx_stream = &chip->playback_stream;
+ int err;
+
+ snd_printdd("->lx_tasklet_playback\n");
+
+ err = lx_interrupt_request_new_buffer(chip, lx_stream);
+ if (err < 0)
+ snd_printk(KERN_ERR LXP
+ "cannot request new buffer for playback\n");
+
+ snd_pcm_period_elapsed(lx_stream->stream);
+}
+
+void lx_tasklet_capture(unsigned long data)
+{
+ struct lx6464es *chip = (struct lx6464es *)data;
+ struct lx_stream *lx_stream = &chip->capture_stream;
+ int err;
+
+ snd_printdd("->lx_tasklet_capture\n");
+ err = lx_interrupt_request_new_buffer(chip, lx_stream);
+ if (err < 0)
+ snd_printk(KERN_ERR LXP
+ "cannot request new buffer for capture\n");
+
+ snd_pcm_period_elapsed(lx_stream->stream);
+}
+
+
+
+static int lx_interrupt_handle_audio_transfer(struct lx6464es *chip,
+ u64 notified_in_pipe_mask,
+ u64 notified_out_pipe_mask)
+{
+ int err = 0;
+
+ if (notified_in_pipe_mask) {
+ snd_printdd(LXP "requesting audio transfer for capture\n");
+ tasklet_hi_schedule(&chip->tasklet_capture);
+ }
+
+ if (notified_out_pipe_mask) {
+ snd_printdd(LXP "requesting audio transfer for playback\n");
+ tasklet_hi_schedule(&chip->tasklet_playback);
+ }
+
+ return err;
+}
+
+
+irqreturn_t lx_interrupt(int irq, void *dev_id)
+{
+ struct lx6464es *chip = dev_id;
+ int async_pending, async_escmd;
+ u32 irqsrc;
+
+ spin_lock(&chip->lock);
+
+ snd_printdd("**************************************************\n");
+
+ if (!lx_interrupt_ack(chip, &irqsrc, &async_pending, &async_escmd)) {
+ spin_unlock(&chip->lock);
+ snd_printdd("IRQ_NONE\n");
+ return IRQ_NONE; /* this device did not cause the interrupt */
+ }
+
+ if (irqsrc & MASK_SYS_STATUS_CMD_DONE)
+ goto exit;
+
+#if 0
+ if (irqsrc & MASK_SYS_STATUS_EOBI)
+ snd_printdd(LXP "interrupt: EOBI\n");
+
+ if (irqsrc & MASK_SYS_STATUS_EOBO)
+ snd_printdd(LXP "interrupt: EOBO\n");
+
+ if (irqsrc & MASK_SYS_STATUS_URUN)
+ snd_printdd(LXP "interrupt: URUN\n");
+
+ if (irqsrc & MASK_SYS_STATUS_ORUN)
+ snd_printdd(LXP "interrupt: ORUN\n");
+#endif
+
+ if (async_pending) {
+ u64 notified_in_pipe_mask = 0;
+ u64 notified_out_pipe_mask = 0;
+ int freq_changed;
+ int err;
+
+ /* handle async events */
+ err = lx_interrupt_handle_async_events(chip, irqsrc,
+ &freq_changed,
+ &notified_in_pipe_mask,
+ &notified_out_pipe_mask);
+ if (err)
+ snd_printk(KERN_ERR LXP
+ "error handling async events\n");
+
+ err = lx_interrupt_handle_audio_transfer(chip,
+ notified_in_pipe_mask,
+ notified_out_pipe_mask
+ );
+ if (err)
+ snd_printk(KERN_ERR LXP
+ "error during audio transfer\n");
+ }
+
+ if (async_escmd) {
+#if 0
+ /* backdoor for ethersound commands
+ *
+ * for now, we do not need this
+ *
+ * */
+
+ snd_printdd("lx6464es: interrupt requests escmd handling\n");
+#endif
+ }
+
+exit:
+ spin_unlock(&chip->lock);
+ return IRQ_HANDLED; /* this device caused the interrupt */
+}
+
+
+static void lx_irq_set(struct lx6464es *chip, int enable)
+{
+ u32 reg = lx_plx_reg_read(chip, ePLX_IRQCS);
+
+ /* enable/disable interrupts
+ *
+ * Set the Doorbell and PCI interrupt enable bits
+ *
+ * */
+ if (enable)
+ reg |= (IRQCS_ENABLE_PCIIRQ | IRQCS_ENABLE_PCIDB);
+ else
+ reg &= ~(IRQCS_ENABLE_PCIIRQ | IRQCS_ENABLE_PCIDB);
+ lx_plx_reg_write(chip, ePLX_IRQCS, reg);
+}
+
+void lx_irq_enable(struct lx6464es *chip)
+{
+ snd_printdd("->lx_irq_enable\n");
+ lx_irq_set(chip, 1);
+}
+
+void lx_irq_disable(struct lx6464es *chip)
+{
+ snd_printdd("->lx_irq_disable\n");
+ lx_irq_set(chip, 0);
+}
diff --git a/sound/pci/lx6464es/lx_core.h b/sound/pci/lx6464es/lx_core.h
new file mode 100644
index 000000000000..6bd9cbbbc68d
--- /dev/null
+++ b/sound/pci/lx6464es/lx_core.h
@@ -0,0 +1,242 @@
+/* -*- linux-c -*- *
+ *
+ * ALSA driver for the digigram lx6464es interface
+ * low-level interface
+ *
+ * Copyright (c) 2009 Tim Blechmann <tim@klingt.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; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef LX_CORE_H
+#define LX_CORE_H
+
+#include <linux/interrupt.h>
+
+#include "lx_defs.h"
+
+#define REG_CRM_NUMBER 12
+
+struct lx6464es;
+
+/* low-level register access */
+
+/* dsp register access */
+enum {
+ eReg_BASE,
+ eReg_CSM,
+ eReg_CRM1,
+ eReg_CRM2,
+ eReg_CRM3,
+ eReg_CRM4,
+ eReg_CRM5,
+ eReg_CRM6,
+ eReg_CRM7,
+ eReg_CRM8,
+ eReg_CRM9,
+ eReg_CRM10,
+ eReg_CRM11,
+ eReg_CRM12,
+
+ eReg_ICR,
+ eReg_CVR,
+ eReg_ISR,
+ eReg_RXHTXH,
+ eReg_RXMTXM,
+ eReg_RHLTXL,
+ eReg_RESETDSP,
+
+ eReg_CSUF,
+ eReg_CSES,
+ eReg_CRESMSB,
+ eReg_CRESLSB,
+ eReg_ADMACESMSB,
+ eReg_ADMACESLSB,
+ eReg_CONFES,
+
+ eMaxPortLx
+};
+
+unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port);
+void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len);
+void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data);
+void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data,
+ u32 len);
+
+/* plx register access */
+enum {
+ ePLX_PCICR,
+
+ ePLX_MBOX0,
+ ePLX_MBOX1,
+ ePLX_MBOX2,
+ ePLX_MBOX3,
+ ePLX_MBOX4,
+ ePLX_MBOX5,
+ ePLX_MBOX6,
+ ePLX_MBOX7,
+
+ ePLX_L2PCIDB,
+ ePLX_IRQCS,
+ ePLX_CHIPSC,
+
+ eMaxPort
+};
+
+unsigned long lx_plx_reg_read(struct lx6464es *chip, int port);
+void lx_plx_reg_write(struct lx6464es *chip, int port, u32 data);
+
+/* rhm */
+struct lx_rmh {
+ u16 cmd_len; /* length of the command to send (WORDs) */
+ u16 stat_len; /* length of the status received (WORDs) */
+ u16 dsp_stat; /* status type, RMP_SSIZE_XXX */
+ u16 cmd_idx; /* index of the command */
+ u32 cmd[REG_CRM_NUMBER];
+ u32 stat[REG_CRM_NUMBER];
+};
+
+
+/* low-level dsp access */
+int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version);
+int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq);
+int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran);
+int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data);
+int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address);
+
+
+/* low-level pipe handling */
+int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture,
+ int channels);
+int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture);
+int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture,
+ u64 *rsample_count);
+int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate);
+int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture);
+int lx_pipe_start(struct lx6464es *chip, u32 pipe, int is_capture);
+int lx_pipe_pause(struct lx6464es *chip, u32 pipe, int is_capture);
+
+int lx_pipe_wait_for_start(struct lx6464es *chip, u32 pipe, int is_capture);
+int lx_pipe_wait_for_idle(struct lx6464es *chip, u32 pipe, int is_capture);
+
+/* low-level stream handling */
+int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
+ u32 pipe, int is_capture);
+int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,
+ int *rstate);
+int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture,
+ u64 *r_bytepos);
+
+int lx_stream_set_state(struct lx6464es *chip, u32 pipe,
+ int is_capture, enum stream_state_t state);
+
+static inline int lx_stream_start(struct lx6464es *chip, u32 pipe,
+ int is_capture)
+{
+ snd_printdd("->lx_stream_start\n");
+ return lx_stream_set_state(chip, pipe, is_capture, SSTATE_RUN);
+}
+
+static inline int lx_stream_pause(struct lx6464es *chip, u32 pipe,
+ int is_capture)
+{
+ snd_printdd("->lx_stream_pause\n");
+ return lx_stream_set_state(chip, pipe, is_capture, SSTATE_PAUSE);
+}
+
+static inline int lx_stream_stop(struct lx6464es *chip, u32 pipe,
+ int is_capture)
+{
+ snd_printdd("->lx_stream_stop\n");
+ return lx_stream_set_state(chip, pipe, is_capture, SSTATE_STOP);
+}
+
+/* low-level buffer handling */
+int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
+ u32 *r_needed, u32 *r_freed, u32 *size_array);
+int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture,
+ u32 buffer_size, u32 buf_address_lo, u32 buf_address_hi,
+ u32 *r_buffer_index);
+int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture,
+ u32 *r_buffer_size);
+int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture,
+ u32 buffer_index);
+
+/* low-level gain/peak handling */
+int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute);
+int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels,
+ u32 *r_levels);
+
+
+/* interrupt handling */
+irqreturn_t lx_interrupt(int irq, void *dev_id);
+void lx_irq_enable(struct lx6464es *chip);
+void lx_irq_disable(struct lx6464es *chip);
+
+void lx_tasklet_capture(unsigned long data);
+void lx_tasklet_playback(unsigned long data);
+
+
+/* Stream Format Header Defines (for LIN and IEEE754) */
+#define HEADER_FMT_BASE HEADER_FMT_BASE_LIN
+#define HEADER_FMT_BASE_LIN 0xFED00000
+#define HEADER_FMT_BASE_FLOAT 0xFAD00000
+#define HEADER_FMT_MONO 0x00000080 /* bit 23 in header_lo. WARNING: old
+ * bit 22 is ignored in float
+ * format */
+#define HEADER_FMT_INTEL 0x00008000
+#define HEADER_FMT_16BITS 0x00002000
+#define HEADER_FMT_24BITS 0x00004000
+#define HEADER_FMT_UPTO11 0x00000200 /* frequency is less or equ. to 11k.
+ * */
+#define HEADER_FMT_UPTO32 0x00000100 /* frequency is over 11k and less
+ * then 32k.*/
+
+
+#define BIT_FMP_HEADER 23
+#define BIT_FMP_SD 22
+#define BIT_FMP_MULTICHANNEL 19
+
+#define START_STATE 1
+#define PAUSE_STATE 0
+
+
+
+
+
+/* from PcxAll_e.h */
+/* Start/Pause condition for pipes (PCXStartPipe, PCXPausePipe) */
+#define START_PAUSE_IMMEDIATE 0
+#define START_PAUSE_ON_SYNCHRO 1
+#define START_PAUSE_ON_TIME_CODE 2
+
+
+/* Pipe / Stream state */
+#define START_STATE 1
+#define PAUSE_STATE 0
+
+static inline void unpack_pointer(dma_addr_t ptr, u32 *r_low, u32 *r_high)
+{
+ *r_low = (u32)(ptr & 0xffffffff);
+#if BITS_PER_LONG == 32
+ *r_high = 0;
+#else
+ *r_high = (u32)((u64)ptr>>32);
+#endif
+}
+
+#endif /* LX_CORE_H */
diff --git a/sound/pci/lx6464es/lx_defs.h b/sound/pci/lx6464es/lx_defs.h
new file mode 100644
index 000000000000..49d36bdd512c
--- /dev/null
+++ b/sound/pci/lx6464es/lx_defs.h
@@ -0,0 +1,376 @@
+/* -*- linux-c -*- *
+ *
+ * ALSA driver for the digigram lx6464es interface
+ * adapted upstream headers
+ *
+ * Copyright (c) 2009 Tim Blechmann <tim@klingt.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; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef LX_DEFS_H
+#define LX_DEFS_H
+
+/* code adapted from ethersound.h */
+#define XES_FREQ_COUNT8_MASK 0x00001FFF /* compteur 25MHz entre 8 ech. */
+#define XES_FREQ_COUNT8_44_MIN 0x00001288 /* 25M /
+ * [ 44k - ( 44.1k + 48k ) / 2 ]
+ * * 8 */
+#define XES_FREQ_COUNT8_44_MAX 0x000010F0 /* 25M / [ ( 44.1k + 48k ) / 2 ]
+ * * 8 */
+#define XES_FREQ_COUNT8_48_MAX 0x00000F08 /* 25M /
+ * [ 48k + ( 44.1k + 48k ) / 2 ]
+ * * 8 */
+
+/* code adapted from LXES_registers.h */
+
+#define IOCR_OUTPUTS_OFFSET 0 /* (rw) offset for the number of OUTs in the
+ * ConfES register. */
+#define IOCR_INPUTS_OFFSET 8 /* (rw) offset for the number of INs in the
+ * ConfES register. */
+#define FREQ_RATIO_OFFSET 19 /* (rw) offset for frequency ratio in the
+ * ConfES register. */
+#define FREQ_RATIO_SINGLE_MODE 0x01 /* value for single mode frequency ratio:
+ * sample rate = frequency rate. */
+
+#define CONFES_READ_PART_MASK 0x00070000
+#define CONFES_WRITE_PART_MASK 0x00F80000
+
+/* code adapted from if_drv_mb.h */
+
+#define MASK_SYS_STATUS_ERROR (1L << 31) /* events that lead to a PCI irq if
+ * not yet pending */
+#define MASK_SYS_STATUS_URUN (1L << 30)
+#define MASK_SYS_STATUS_ORUN (1L << 29)
+#define MASK_SYS_STATUS_EOBO (1L << 28)
+#define MASK_SYS_STATUS_EOBI (1L << 27)
+#define MASK_SYS_STATUS_FREQ (1L << 26)
+#define MASK_SYS_STATUS_ESA (1L << 25) /* reserved, this is set by the
+ * XES */
+#define MASK_SYS_STATUS_TIMER (1L << 24)
+
+#define MASK_SYS_ASYNC_EVENTS (MASK_SYS_STATUS_ERROR | \
+ MASK_SYS_STATUS_URUN | \
+ MASK_SYS_STATUS_ORUN | \
+ MASK_SYS_STATUS_EOBO | \
+ MASK_SYS_STATUS_EOBI | \
+ MASK_SYS_STATUS_FREQ | \
+ MASK_SYS_STATUS_ESA)
+
+#define MASK_SYS_PCI_EVENTS (MASK_SYS_ASYNC_EVENTS | \
+ MASK_SYS_STATUS_TIMER)
+
+#define MASK_SYS_TIMER_COUNT 0x0000FFFF
+
+#define MASK_SYS_STATUS_EOT_PLX (1L << 22) /* event that remains
+ * internal: reserved fo end
+ * of plx dma */
+#define MASK_SYS_STATUS_XES (1L << 21) /* event that remains
+ * internal: pending XES
+ * IRQ */
+#define MASK_SYS_STATUS_CMD_DONE (1L << 20) /* alternate command
+ * management: notify driver
+ * instead of polling */
+
+
+#define MAX_STREAM_BUFFER 5 /* max amount of stream buffers. */
+
+#define MICROBLAZE_IBL_MIN 32
+#define MICROBLAZE_IBL_DEFAULT 128
+#define MICROBLAZE_IBL_MAX 512
+/* #define MASK_GRANULARITY (2*MICROBLAZE_IBL_MAX-1) */
+
+
+
+/* command opcodes, see reference for details */
+
+/*
+ the capture bit position in the object_id field in driver commands
+ depends upon the number of managed channels. For now, 64 IN + 64 OUT are
+ supported. HOwever, the communication protocol forsees 1024 channels, hence
+ bit 10 indicates a capture (input) object).
+*/
+#define ID_IS_CAPTURE (1L << 10)
+#define ID_OFFSET 13 /* object ID is at the 13th bit in the
+ * 1st command word.*/
+#define ID_CH_MASK 0x3F
+#define OPCODE_OFFSET 24 /* offset of the command opcode in the first
+ * command word.*/
+
+enum cmd_mb_opcodes {
+ CMD_00_INFO_DEBUG = 0x00,
+ CMD_01_GET_SYS_CFG = 0x01,
+ CMD_02_SET_GRANULARITY = 0x02,
+ CMD_03_SET_TIMER_IRQ = 0x03,
+ CMD_04_GET_EVENT = 0x04,
+ CMD_05_GET_PIPES = 0x05,
+
+ CMD_06_ALLOCATE_PIPE = 0x06,
+ CMD_07_RELEASE_PIPE = 0x07,
+ CMD_08_ASK_BUFFERS = 0x08,
+ CMD_09_STOP_PIPE = 0x09,
+ CMD_0A_GET_PIPE_SPL_COUNT = 0x0a,
+ CMD_0B_TOGGLE_PIPE_STATE = 0x0b,
+
+ CMD_0C_DEF_STREAM = 0x0c,
+ CMD_0D_SET_MUTE = 0x0d,
+ CMD_0E_GET_STREAM_SPL_COUNT = 0x0e,
+ CMD_0F_UPDATE_BUFFER = 0x0f,
+ CMD_10_GET_BUFFER = 0x10,
+ CMD_11_CANCEL_BUFFER = 0x11,
+ CMD_12_GET_PEAK = 0x12,
+ CMD_13_SET_STREAM_STATE = 0x13,
+ CMD_14_INVALID = 0x14,
+};
+
+/* pipe states */
+enum pipe_state_t {
+ PSTATE_IDLE = 0, /* the pipe is not processed in the XES_IRQ
+ * (free or stopped, or paused). */
+ PSTATE_RUN = 1, /* sustained play/record state. */
+ PSTATE_PURGE = 2, /* the ES channels are now off, render pipes do
+ * not DMA, record pipe do a last DMA. */
+ PSTATE_ACQUIRE = 3, /* the ES channels are now on, render pipes do
+ * not yet increase their sample count, record
+ * pipes do not DMA. */
+ PSTATE_CLOSING = 4, /* the pipe is releasing, and may not yet
+ * receive an "alloc" command. */
+};
+
+/* stream states */
+enum stream_state_t {
+ SSTATE_STOP = 0x00, /* setting to stop resets the stream spl
+ * count.*/
+ SSTATE_RUN = (0x01 << 0), /* start DMA and spl count handling. */
+ SSTATE_PAUSE = (0x01 << 1), /* pause DMA and spl count handling. */
+};
+
+/* buffer flags */
+enum buffer_flags {
+ BF_VALID = 0x80, /* set if the buffer is valid, clear if free.*/
+ BF_CURRENT = 0x40, /* set if this is the current buffer (there is
+ * always a current buffer).*/
+ BF_NOTIFY_EOB = 0x20, /* set if this buffer must cause a PCI event
+ * when finished.*/
+ BF_CIRCULAR = 0x10, /* set if buffer[1] must be copied to buffer[0]
+ * by the end of this buffer.*/
+ BF_64BITS_ADR = 0x08, /* set if the hi part of the address is valid.*/
+ BF_xx = 0x04, /* future extension.*/
+ BF_EOB = 0x02, /* set if finished, but not yet free.*/
+ BF_PAUSE = 0x01, /* pause stream at buffer end.*/
+ BF_ZERO = 0x00, /* no flags (init).*/
+};
+
+/**
+* Stream Flags definitions
+*/
+enum stream_flags {
+ SF_ZERO = 0x00000000, /* no flags (stream invalid). */
+ SF_VALID = 0x10000000, /* the stream has a valid DMA_conf
+ * info (setstreamformat). */
+ SF_XRUN = 0x20000000, /* the stream is un x-run state. */
+ SF_START = 0x40000000, /* the DMA is running.*/
+ SF_ASIO = 0x80000000, /* ASIO.*/
+};
+
+
+#define MASK_SPL_COUNT_HI 0x00FFFFFF /* 4 MSBits are status bits */
+#define PSTATE_OFFSET 28 /* 4 MSBits are status bits */
+
+
+#define MASK_STREAM_HAS_MAPPING (1L << 12)
+#define MASK_STREAM_IS_ASIO (1L << 9)
+#define STREAM_FMT_OFFSET 10 /* the stream fmt bits start at the 10th
+ * bit in the command word. */
+
+#define STREAM_FMT_16b 0x02
+#define STREAM_FMT_intel 0x01
+
+#define FREQ_FIELD_OFFSET 15 /* offset of the freq field in the response
+ * word */
+
+#define BUFF_FLAGS_OFFSET 24 /* offset of the buffer flags in the
+ * response word. */
+#define MASK_DATA_SIZE 0x00FFFFFF /* this must match the field size of
+ * datasize in the buffer_t structure. */
+
+#define MASK_BUFFER_ID 0xFF /* the cancel command awaits a buffer ID,
+ * may be 0xFF for "current". */
+
+
+/* code adapted from PcxErr_e.h */
+
+/* Bits masks */
+
+#define ERROR_MASK 0x8000
+
+#define SOURCE_MASK 0x7800
+
+#define E_SOURCE_BOARD 0x4000 /* 8 >> 1 */
+#define E_SOURCE_DRV 0x2000 /* 4 >> 1 */
+#define E_SOURCE_API 0x1000 /* 2 >> 1 */
+/* Error tools */
+#define E_SOURCE_TOOLS 0x0800 /* 1 >> 1 */
+/* Error pcxaudio */
+#define E_SOURCE_AUDIO 0x1800 /* 3 >> 1 */
+/* Error virtual pcx */
+#define E_SOURCE_VPCX 0x2800 /* 5 >> 1 */
+/* Error dispatcher */
+#define E_SOURCE_DISPATCHER 0x3000 /* 6 >> 1 */
+/* Error from CobraNet firmware */
+#define E_SOURCE_COBRANET 0x3800 /* 7 >> 1 */
+
+#define E_SOURCE_USER 0x7800
+
+#define CLASS_MASK 0x0700
+
+#define CODE_MASK 0x00FF
+
+/* Bits values */
+
+/* Values for the error/warning bit */
+#define ERROR_VALUE 0x8000
+#define WARNING_VALUE 0x0000
+
+/* Class values */
+#define E_CLASS_GENERAL 0x0000
+#define E_CLASS_INVALID_CMD 0x0100
+#define E_CLASS_INVALID_STD_OBJECT 0x0200
+#define E_CLASS_RSRC_IMPOSSIBLE 0x0300
+#define E_CLASS_WRONG_CONTEXT 0x0400
+#define E_CLASS_BAD_SPECIFIC_PARAMETER 0x0500
+#define E_CLASS_REAL_TIME_ERROR 0x0600
+#define E_CLASS_DIRECTSHOW 0x0700
+#define E_CLASS_FREE 0x0700
+
+
+/* Complete DRV error code for the general class */
+#define ED_GN (ERROR_VALUE | E_SOURCE_DRV | E_CLASS_GENERAL)
+#define ED_CONCURRENCY (ED_GN | 0x01)
+#define ED_DSP_CRASHED (ED_GN | 0x02)
+#define ED_UNKNOWN_BOARD (ED_GN | 0x03)
+#define ED_NOT_INSTALLED (ED_GN | 0x04)
+#define ED_CANNOT_OPEN_SVC_MANAGER (ED_GN | 0x05)
+#define ED_CANNOT_READ_REGISTRY (ED_GN | 0x06)
+#define ED_DSP_VERSION_MISMATCH (ED_GN | 0x07)
+#define ED_UNAVAILABLE_FEATURE (ED_GN | 0x08)
+#define ED_CANCELLED (ED_GN | 0x09)
+#define ED_NO_RESPONSE_AT_IRQA (ED_GN | 0x10)
+#define ED_INVALID_ADDRESS (ED_GN | 0x11)
+#define ED_DSP_CORRUPTED (ED_GN | 0x12)
+#define ED_PENDING_OPERATION (ED_GN | 0x13)
+#define ED_NET_ALLOCATE_MEMORY_IMPOSSIBLE (ED_GN | 0x14)
+#define ED_NET_REGISTER_ERROR (ED_GN | 0x15)
+#define ED_NET_THREAD_ERROR (ED_GN | 0x16)
+#define ED_NET_OPEN_ERROR (ED_GN | 0x17)
+#define ED_NET_CLOSE_ERROR (ED_GN | 0x18)
+#define ED_NET_NO_MORE_PACKET (ED_GN | 0x19)
+#define ED_NET_NO_MORE_BUFFER (ED_GN | 0x1A)
+#define ED_NET_SEND_ERROR (ED_GN | 0x1B)
+#define ED_NET_RECEIVE_ERROR (ED_GN | 0x1C)
+#define ED_NET_WRONG_MSG_SIZE (ED_GN | 0x1D)
+#define ED_NET_WAIT_ERROR (ED_GN | 0x1E)
+#define ED_NET_EEPROM_ERROR (ED_GN | 0x1F)
+#define ED_INVALID_RS232_COM_NUMBER (ED_GN | 0x20)
+#define ED_INVALID_RS232_INIT (ED_GN | 0x21)
+#define ED_FILE_ERROR (ED_GN | 0x22)
+#define ED_INVALID_GPIO_CMD (ED_GN | 0x23)
+#define ED_RS232_ALREADY_OPENED (ED_GN | 0x24)
+#define ED_RS232_NOT_OPENED (ED_GN | 0x25)
+#define ED_GPIO_ALREADY_OPENED (ED_GN | 0x26)
+#define ED_GPIO_NOT_OPENED (ED_GN | 0x27)
+#define ED_REGISTRY_ERROR (ED_GN | 0x28) /* <- NCX */
+#define ED_INVALID_SERVICE (ED_GN | 0x29) /* <- NCX */
+
+#define ED_READ_FILE_ALREADY_OPENED (ED_GN | 0x2a) /* <- Decalage
+ * pour RCX
+ * (old 0x28)
+ * */
+#define ED_READ_FILE_INVALID_COMMAND (ED_GN | 0x2b) /* ~ */
+#define ED_READ_FILE_INVALID_PARAMETER (ED_GN | 0x2c) /* ~ */
+#define ED_READ_FILE_ALREADY_CLOSED (ED_GN | 0x2d) /* ~ */
+#define ED_READ_FILE_NO_INFORMATION (ED_GN | 0x2e) /* ~ */
+#define ED_READ_FILE_INVALID_HANDLE (ED_GN | 0x2f) /* ~ */
+#define ED_READ_FILE_END_OF_FILE (ED_GN | 0x30) /* ~ */
+#define ED_READ_FILE_ERROR (ED_GN | 0x31) /* ~ */
+
+#define ED_DSP_CRASHED_EXC_DSPSTACK_OVERFLOW (ED_GN | 0x32) /* <- Decalage pour
+ * PCX (old 0x14) */
+#define ED_DSP_CRASHED_EXC_SYSSTACK_OVERFLOW (ED_GN | 0x33) /* ~ */
+#define ED_DSP_CRASHED_EXC_ILLEGAL (ED_GN | 0x34) /* ~ */
+#define ED_DSP_CRASHED_EXC_TIMER_REENTRY (ED_GN | 0x35) /* ~ */
+#define ED_DSP_CRASHED_EXC_FATAL_ERROR (ED_GN | 0x36) /* ~ */
+
+#define ED_FLASH_PCCARD_NOT_PRESENT (ED_GN | 0x37)
+
+#define ED_NO_CURRENT_CLOCK (ED_GN | 0x38)
+
+/* Complete DRV error code for real time class */
+#define ED_RT (ERROR_VALUE | E_SOURCE_DRV | E_CLASS_REAL_TIME_ERROR)
+#define ED_DSP_TIMED_OUT (ED_RT | 0x01)
+#define ED_DSP_CHK_TIMED_OUT (ED_RT | 0x02)
+#define ED_STREAM_OVERRUN (ED_RT | 0x03)
+#define ED_DSP_BUSY (ED_RT | 0x04)
+#define ED_DSP_SEMAPHORE_TIME_OUT (ED_RT | 0x05)
+#define ED_BOARD_TIME_OUT (ED_RT | 0x06)
+#define ED_XILINX_ERROR (ED_RT | 0x07)
+#define ED_COBRANET_ITF_NOT_RESPONDING (ED_RT | 0x08)
+
+/* Complete BOARD error code for the invaid standard object class */
+#define EB_ISO (ERROR_VALUE | E_SOURCE_BOARD | \
+ E_CLASS_INVALID_STD_OBJECT)
+#define EB_INVALID_EFFECT (EB_ISO | 0x00)
+#define EB_INVALID_PIPE (EB_ISO | 0x40)
+#define EB_INVALID_STREAM (EB_ISO | 0x80)
+#define EB_INVALID_AUDIO (EB_ISO | 0xC0)
+
+/* Complete BOARD error code for impossible resource allocation class */
+#define EB_RI (ERROR_VALUE | E_SOURCE_BOARD | E_CLASS_RSRC_IMPOSSIBLE)
+#define EB_ALLOCATE_ALL_STREAM_TRANSFERT_BUFFERS_IMPOSSIBLE (EB_RI | 0x01)
+#define EB_ALLOCATE_PIPE_SAMPLE_BUFFER_IMPOSSIBLE (EB_RI | 0x02)
+
+#define EB_ALLOCATE_MEM_STREAM_IMPOSSIBLE \
+ EB_ALLOCATE_ALL_STREAM_TRANSFERT_BUFFERS_IMPOSSIBLE
+#define EB_ALLOCATE_MEM_PIPE_IMPOSSIBLE \
+ EB_ALLOCATE_PIPE_SAMPLE_BUFFER_IMPOSSIBLE
+
+#define EB_ALLOCATE_DIFFERED_CMD_IMPOSSIBLE (EB_RI | 0x03)
+#define EB_TOO_MANY_DIFFERED_CMD (EB_RI | 0x04)
+#define EB_RBUFFERS_TABLE_OVERFLOW (EB_RI | 0x05)
+#define EB_ALLOCATE_EFFECTS_IMPOSSIBLE (EB_RI | 0x08)
+#define EB_ALLOCATE_EFFECT_POS_IMPOSSIBLE (EB_RI | 0x09)
+#define EB_RBUFFER_NOT_AVAILABLE (EB_RI | 0x0A)
+#define EB_ALLOCATE_CONTEXT_LIII_IMPOSSIBLE (EB_RI | 0x0B)
+#define EB_STATUS_DIALOG_IMPOSSIBLE (EB_RI | 0x1D)
+#define EB_CONTROL_CMD_IMPOSSIBLE (EB_RI | 0x1E)
+#define EB_STATUS_SEND_IMPOSSIBLE (EB_RI | 0x1F)
+#define EB_ALLOCATE_PIPE_IMPOSSIBLE (EB_RI | 0x40)
+#define EB_ALLOCATE_STREAM_IMPOSSIBLE (EB_RI | 0x80)
+#define EB_ALLOCATE_AUDIO_IMPOSSIBLE (EB_RI | 0xC0)
+
+/* Complete BOARD error code for wrong call context class */
+#define EB_WCC (ERROR_VALUE | E_SOURCE_BOARD | E_CLASS_WRONG_CONTEXT)
+#define EB_CMD_REFUSED (EB_WCC | 0x00)
+#define EB_START_STREAM_REFUSED (EB_WCC | 0xFC)
+#define EB_SPC_REFUSED (EB_WCC | 0xFD)
+#define EB_CSN_REFUSED (EB_WCC | 0xFE)
+#define EB_CSE_REFUSED (EB_WCC | 0xFF)
+
+
+
+
+#endif /* LX_DEFS_H */
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 314e73531bd1..d0d46295b652 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -402,9 +402,9 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
#define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES)
#define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024)
-/* use hotplug firmeare loader? */
+/* use hotplug firmware loader? */
#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-#if !defined(HDSP_USE_HWDEP_LOADER) && !defined(CONFIG_SND_HDSP)
+#if !defined(HDSP_USE_HWDEP_LOADER)
#define HDSP_FW_LOADER
#endif
#endif
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 809b233dd4a3..1ef58c51c213 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1687,7 +1687,7 @@ static int snd_via8233_pcmdxs_volume_put(struct snd_kcontrol *kcontrol,
return change;
}
-static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -9450, 150, 1);
+static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1);
static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = {
.name = "PCM Playback Volume",
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 3d2bb6fc6dcc..3304f9dd92fa 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -32,6 +32,7 @@ source "sound/soc/fsl/Kconfig"
source "sound/soc/omap/Kconfig"
source "sound/soc/pxa/Kconfig"
source "sound/soc/s3c24xx/Kconfig"
+source "sound/soc/s6000/Kconfig"
source "sound/soc/sh/Kconfig"
# Supported codecs
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 0237879fd412..8943a140c818 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_SND_SOC) += fsl/
obj-$(CONFIG_SND_SOC) += omap/
obj-$(CONFIG_SND_SOC) += pxa/
obj-$(CONFIG_SND_SOC) += s3c24xx/
+obj-$(CONFIG_SND_SOC) += s6000/
obj-$(CONFIG_SND_SOC) += sh/
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index a608d7009dbd..e720d5e6f04c 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -41,3 +41,11 @@ config SND_AT32_SOC_PLAYPAQ_SLAVE
and FRAME signals on the PlayPaq. Unless you want to play
with the AT32 as the SSC master, you probably want to say N here,
as this will give you better sound quality.
+
+config SND_AT91_SOC_AFEB9260
+ tristate "SoC Audio support for AFEB9260 board"
+ depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
+ select SND_ATMEL_SOC_SSC
+ select SND_SOC_TLV320AIC23
+ help
+ Say Y here to support sound on AFEB9260 board.
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index f54a7cc68e66..e7ea56bd5f82 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -13,3 +13,4 @@ snd-soc-playpaq-objs := playpaq_wm8510.o
obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
+obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
new file mode 100644
index 000000000000..23349de27313
--- /dev/null
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -0,0 +1,203 @@
+/*
+ * afeb9260.c -- SoC audio for AFEB9260
+ *
+ * Copyright (C) 2009 Sergey Lapin <slapin@ossfans.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.
+ *
+ * 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/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <linux/atmel-ssc.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <linux/gpio.h>
+
+#include "../codecs/tlv320aic23.h"
+#include "atmel-pcm.h"
+#include "atmel_ssc_dai.h"
+
+#define CODEC_CLOCK 12000000
+
+static int afeb9260_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_dai *codec_dai = rtd->dai->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ int err;
+
+ /* Set codec DAI configuration */
+ err = snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_I2S|
+ SND_SOC_DAIFMT_NB_IF |
+ SND_SOC_DAIFMT_CBM_CFM);
+ if (err < 0) {
+ printk(KERN_ERR "can't set codec DAI configuration\n");
+ return err;
+ }
+
+ /* Set cpu DAI configuration */
+ err = snd_soc_dai_set_fmt(cpu_dai,
+ SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_IF |
+ SND_SOC_DAIFMT_CBM_CFM);
+ if (err < 0) {
+ printk(KERN_ERR "can't set cpu DAI configuration\n");
+ return err;
+ }
+
+ /* Set the codec system clock for DAC and ADC */
+ err =
+ snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
+
+ if (err < 0) {
+ printk(KERN_ERR "can't set codec system clock\n");
+ return err;
+ }
+
+ return err;
+}
+
+static struct snd_soc_ops afeb9260_ops = {
+ .hw_params = afeb9260_hw_params,
+};
+
+static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_LINE("Line In", NULL),
+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ {"Headphone Jack", NULL, "LHPOUT"},
+ {"Headphone Jack", NULL, "RHPOUT"},
+
+ {"LLINEIN", NULL, "Line In"},
+ {"RLINEIN", NULL, "Line In"},
+
+ {"MICIN", NULL, "Mic Jack"},
+};
+
+static int afeb9260_tlv320aic23_init(struct snd_soc_codec *codec)
+{
+
+ /* Add afeb9260 specific widgets */
+ snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
+ ARRAY_SIZE(tlv320aic23_dapm_widgets));
+
+ /* Set up afeb9260 specific audio path audio_map */
+ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+
+ snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_enable_pin(codec, "Line In");
+ snd_soc_dapm_enable_pin(codec, "Mic Jack");
+
+ snd_soc_dapm_sync(codec);
+
+ return 0;
+}
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link afeb9260_dai = {
+ .name = "TLV320AIC23",
+ .stream_name = "AIC23",
+ .cpu_dai = &atmel_ssc_dai[0],
+ .codec_dai = &tlv320aic23_dai,
+ .init = afeb9260_tlv320aic23_init,
+ .ops = &afeb9260_ops,
+};
+
+/* Audio machine driver */
+static struct snd_soc_card snd_soc_machine_afeb9260 = {
+ .name = "AFEB9260",
+ .platform = &atmel_soc_platform,
+ .dai_link = &afeb9260_dai,
+ .num_links = 1,
+};
+
+/* Audio subsystem */
+static struct snd_soc_device afeb9260_snd_devdata = {
+ .card = &snd_soc_machine_afeb9260,
+ .codec_dev = &soc_codec_dev_tlv320aic23,
+};
+
+static struct platform_device *afeb9260_snd_device;
+
+static int __init afeb9260_soc_init(void)
+{
+ int err;
+ struct device *dev;
+ struct atmel_ssc_info *ssc_p = afeb9260_dai.cpu_dai->private_data;
+ struct ssc_device *ssc = NULL;
+
+ if (!(machine_is_afeb9260()))
+ return -ENODEV;
+
+ ssc = ssc_request(0);
+ if (IS_ERR(ssc)) {
+ printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
+ err = PTR_ERR(ssc);
+ ssc = NULL;
+ goto err_ssc;
+ }
+ ssc_p->ssc = ssc;
+
+ afeb9260_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!afeb9260_snd_device) {
+ printk(KERN_ERR "ASoC: Platform device allocation failed\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(afeb9260_snd_device, &afeb9260_snd_devdata);
+ afeb9260_snd_devdata.dev = &afeb9260_snd_device->dev;
+ err = platform_device_add(afeb9260_snd_device);
+ if (err)
+ goto err1;
+
+ dev = &afeb9260_snd_device->dev;
+
+ return 0;
+err1:
+ platform_device_del(afeb9260_snd_device);
+ platform_device_put(afeb9260_snd_device);
+err_ssc:
+ return err;
+
+}
+
+static void __exit afeb9260_soc_exit(void)
+{
+ platform_device_unregister(afeb9260_snd_device);
+}
+
+module_init(afeb9260_soc_init);
+module_exit(afeb9260_soc_exit);
+
+MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>");
+MODULE_DESCRIPTION("ALSA SoC for AFEB9260");
+MODULE_LICENSE("GPL");
+
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index b6c7f7a01cb0..1c19ad54a9f9 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -35,7 +35,10 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8900 if I2C
select SND_SOC_WM8903 if I2C
+ select SND_SOC_WM8940 if I2C
+ select SND_SOC_WM8960 if I2C
select SND_SOC_WM8971 if I2C
+ select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8990 if I2C
select SND_SOC_WM9705 if SND_SOC_AC97_BUS
select SND_SOC_WM9712 if SND_SOC_AC97_BUS
@@ -138,9 +141,18 @@ config SND_SOC_WM8900
config SND_SOC_WM8903
tristate
+config SND_SOC_WM8940
+ tristate
+
+config SND_SOC_WM8960
+ tristate
+
config SND_SOC_WM8971
tristate
+config SND_SOC_WM8988
+ tristate
+
config SND_SOC_WM8990
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f2653803ede8..3d31b6bea834 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -23,7 +23,10 @@ snd-soc-wm8750-objs := wm8750.o
snd-soc-wm8753-objs := wm8753.o
snd-soc-wm8900-objs := wm8900.o
snd-soc-wm8903-objs := wm8903.o
+snd-soc-wm8940-objs := wm8940.o
+snd-soc-wm8960-objs := wm8960.o
snd-soc-wm8971-objs := wm8971.o
+snd-soc-wm8988-objs := wm8988.o
snd-soc-wm8990-objs := wm8990.o
snd-soc-wm9705-objs := wm9705.o
snd-soc-wm9712-objs := wm9712.o
@@ -55,6 +58,9 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
+obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
+obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
+obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index b0d4af145b87..932299bb5d1e 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -53,13 +53,13 @@ struct snd_soc_dai ac97_dai = {
.channels_min = 1,
.channels_max = 2,
.rates = STD_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .formats = SND_SOC_STD_AC97_FMTS,},
.capture = {
.stream_name = "AC97 Capture",
.channels_min = 1,
.channels_max = 2,
.rates = STD_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .formats = SND_SOC_STD_AC97_FMTS,},
.ops = &ac97_dai_ops,
};
EXPORT_SYMBOL_GPL(ac97_dai);
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index ddb3b08ac23c..d7440a982d22 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -137,13 +137,13 @@ struct snd_soc_dai ad1980_dai = {
.channels_min = 2,
.channels_max = 6,
.rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE, },
+ .formats = SND_SOC_STD_AC97_FMTS, },
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE, },
+ .formats = SND_SOC_STD_AC97_FMTS, },
};
EXPORT_SYMBOL_GPL(ad1980_dai);
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 7fa09a387622..a32b8226c8a4 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -18,7 +18,7 @@
* - The machine driver's 'startup' function must call
* cs4270_set_dai_sysclk() with the value of MCLK.
* - Only I2S and left-justified modes are supported
- * - Power management is not supported
+ * - Power management is supported
*/
#include <linux/module.h>
@@ -27,6 +27,7 @@
#include <sound/soc.h>
#include <sound/initval.h>
#include <linux/i2c.h>
+#include <linux/delay.h>
#include "cs4270.h"
@@ -56,6 +57,7 @@
#define CS4270_FIRSTREG 0x01
#define CS4270_LASTREG 0x08
#define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1)
+#define CS4270_I2C_INCR 0x80
/* Bit masks for the CS4270 registers */
#define CS4270_CHIPID_ID 0xF0
@@ -64,6 +66,8 @@
#define CS4270_PWRCTL_PDN_ADC 0x20
#define CS4270_PWRCTL_PDN_DAC 0x02
#define CS4270_PWRCTL_PDN 0x01
+#define CS4270_PWRCTL_PDN_ALL \
+ (CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN)
#define CS4270_MODE_SPEED_MASK 0x30
#define CS4270_MODE_1X 0x00
#define CS4270_MODE_2X 0x10
@@ -109,6 +113,7 @@ struct cs4270_private {
unsigned int mclk; /* Input frequency of the MCLK pin */
unsigned int mode; /* The mode (I2S or left-justified) */
unsigned int slave_mode;
+ unsigned int manual_mute;
};
/**
@@ -295,7 +300,7 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec)
s32 length;
length = i2c_smbus_read_i2c_block_data(i2c_client,
- CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache);
+ CS4270_FIRSTREG | CS4270_I2C_INCR, CS4270_NUMREGS, cache);
if (length != CS4270_NUMREGS) {
dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
@@ -453,7 +458,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
}
/**
- * cs4270_mute - enable/disable the CS4270 external mute
+ * cs4270_dai_mute - enable/disable the CS4270 external mute
* @dai: the SOC DAI
* @mute: 0 = disable mute, 1 = enable mute
*
@@ -462,21 +467,52 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
* 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_dai *dai, int mute)
+static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
+ struct cs4270_private *cs4270 = codec->private_data;
int reg6;
reg6 = snd_soc_read(codec, CS4270_MUTE);
if (mute)
reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
- else
+ else {
reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
+ reg6 |= cs4270->manual_mute;
+ }
return snd_soc_write(codec, CS4270_MUTE, reg6);
}
+/**
+ * cs4270_soc_put_mute - put callback for the 'Master Playback switch'
+ * alsa control.
+ * @kcontrol: mixer control
+ * @ucontrol: control element information
+ *
+ * This function basically passes the arguments on to the generic
+ * snd_soc_put_volsw() function and saves the mute information in
+ * our private data structure. This is because we want to prevent
+ * cs4270_dai_mute() neglecting the user's decision to manually
+ * mute the codec's output.
+ *
+ * Returns 0 for success.
+ */
+static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct cs4270_private *cs4270 = codec->private_data;
+ int left = !ucontrol->value.integer.value[0];
+ int right = !ucontrol->value.integer.value[1];
+
+ cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) |
+ (right ? CS4270_MUTE_DAC_B : 0);
+
+ return snd_soc_put_volsw(kcontrol, ucontrol);
+}
+
/* 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",
@@ -486,7 +522,9 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
- SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 0)
+ SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
+ SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1,
+ snd_soc_get_volsw, cs4270_soc_put_mute),
};
/*
@@ -506,7 +544,7 @@ static struct snd_soc_dai_ops cs4270_dai_ops = {
.hw_params = cs4270_hw_params,
.set_sysclk = cs4270_set_dai_sysclk,
.set_fmt = cs4270_set_dai_fmt,
- .digital_mute = cs4270_mute,
+ .digital_mute = cs4270_dai_mute,
};
struct snd_soc_dai cs4270_dai = {
@@ -753,6 +791,57 @@ static struct i2c_device_id cs4270_id[] = {
};
MODULE_DEVICE_TABLE(i2c, cs4270_id);
+#ifdef CONFIG_PM
+
+/* This suspend/resume implementation can handle both - a simple standby
+ * where the codec remains powered, and a full suspend, where the voltage
+ * domain the codec is connected to is teared down and/or any other hardware
+ * reset condition is asserted.
+ *
+ * The codec's own power saving features are enabled in the suspend callback,
+ * and all registers are written back to the hardware when resuming.
+ */
+
+static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct cs4270_private *cs4270 = i2c_get_clientdata(client);
+ struct snd_soc_codec *codec = &cs4270->codec;
+ int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
+
+ return snd_soc_write(codec, CS4270_PWRCTL, reg);
+}
+
+static int cs4270_i2c_resume(struct i2c_client *client)
+{
+ struct cs4270_private *cs4270 = i2c_get_clientdata(client);
+ struct snd_soc_codec *codec = &cs4270->codec;
+ int reg;
+
+ /* In case the device was put to hard reset during sleep, we need to
+ * wait 500ns here before any I2C communication. */
+ ndelay(500);
+
+ /* first restore the entire register cache ... */
+ for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
+ u8 val = snd_soc_read(codec, reg);
+
+ if (i2c_smbus_write_byte_data(client, reg, val)) {
+ dev_err(codec->dev, "i2c write failed\n");
+ return -EIO;
+ }
+ }
+
+ /* ... then disable the power-down bits */
+ reg = snd_soc_read(codec, CS4270_PWRCTL);
+ reg &= ~CS4270_PWRCTL_PDN_ALL;
+
+ return snd_soc_write(codec, CS4270_PWRCTL, reg);
+}
+#else
+#define cs4270_i2c_suspend NULL
+#define cs4270_i2c_resume NULL
+#endif /* CONFIG_PM */
+
/*
* cs4270_i2c_driver - I2C device identification
*
@@ -767,6 +856,8 @@ static struct i2c_driver cs4270_i2c_driver = {
.id_table = cs4270_id,
.probe = cs4270_i2c_probe,
.remove = cs4270_i2c_remove,
+ .suspend = cs4270_i2c_suspend,
+ .resume = cs4270_i2c_resume,
};
/*
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index c3f4afb5d017..21f69df9994c 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -523,6 +523,8 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
case SND_SOC_DAIFMT_I2S:
iface_reg |= TLV320AIC23_FOR_I2S;
break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface_reg |= TLV320AIC23_LRP_ON;
case SND_SOC_DAIFMT_DSP_B:
iface_reg |= TLV320AIC23_FOR_DSP;
break;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index df7c8c281d2f..eaf91ab465b4 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -125,6 +125,11 @@ struct twl4030_priv {
struct snd_pcm_substream *master_substream;
struct snd_pcm_substream *slave_substream;
+
+ unsigned int configured;
+ unsigned int rate;
+ unsigned int sample_bits;
+ unsigned int channels;
};
/*
@@ -232,7 +237,7 @@ static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute)
TWL4030_REG_PRECKL_CTL);
reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL);
twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
- reg_val & (~TWL4030_PRECKL_GAIN),
+ reg_val & (~TWL4030_PRECKR_GAIN),
TWL4030_REG_PRECKR_CTL);
/* Disable PLL */
@@ -316,104 +321,60 @@ static void twl4030_power_down(struct snd_soc_codec *codec)
}
/* Earpiece */
-static const char *twl4030_earpiece_texts[] =
- {"Off", "DACL1", "DACL2", "DACR1"};
-
-static const unsigned int twl4030_earpiece_values[] =
- {0x0, 0x1, 0x2, 0x4};
-
-static const struct soc_enum twl4030_earpiece_enum =
- SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7,
- ARRAY_SIZE(twl4030_earpiece_texts),
- twl4030_earpiece_texts,
- twl4030_earpiece_values);
-
-static const struct snd_kcontrol_new twl4030_dapm_earpiece_control =
-SOC_DAPM_VALUE_ENUM("Route", twl4030_earpiece_enum);
+static const struct snd_kcontrol_new twl4030_dapm_earpiece_controls[] = {
+ SOC_DAPM_SINGLE("Voice", TWL4030_REG_EAR_CTL, 0, 1, 0),
+ SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_EAR_CTL, 1, 1, 0),
+ SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_EAR_CTL, 2, 1, 0),
+ SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_EAR_CTL, 3, 1, 0),
+};
/* PreDrive Left */
-static const char *twl4030_predrivel_texts[] =
- {"Off", "DACL1", "DACL2", "DACR2"};
-
-static const unsigned int twl4030_predrivel_values[] =
- {0x0, 0x1, 0x2, 0x4};
-
-static const struct soc_enum twl4030_predrivel_enum =
- SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7,
- ARRAY_SIZE(twl4030_predrivel_texts),
- twl4030_predrivel_texts,
- twl4030_predrivel_values);
-
-static const struct snd_kcontrol_new twl4030_dapm_predrivel_control =
-SOC_DAPM_VALUE_ENUM("Route", twl4030_predrivel_enum);
+static const struct snd_kcontrol_new twl4030_dapm_predrivel_controls[] = {
+ SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDL_CTL, 0, 1, 0),
+ SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PREDL_CTL, 1, 1, 0),
+ SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDL_CTL, 2, 1, 0),
+ SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDL_CTL, 3, 1, 0),
+};
/* PreDrive Right */
-static const char *twl4030_predriver_texts[] =
- {"Off", "DACR1", "DACR2", "DACL2"};
-
-static const unsigned int twl4030_predriver_values[] =
- {0x0, 0x1, 0x2, 0x4};
-
-static const struct soc_enum twl4030_predriver_enum =
- SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7,
- ARRAY_SIZE(twl4030_predriver_texts),
- twl4030_predriver_texts,
- twl4030_predriver_values);
-
-static const struct snd_kcontrol_new twl4030_dapm_predriver_control =
-SOC_DAPM_VALUE_ENUM("Route", twl4030_predriver_enum);
+static const struct snd_kcontrol_new twl4030_dapm_predriver_controls[] = {
+ SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDR_CTL, 0, 1, 0),
+ SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PREDR_CTL, 1, 1, 0),
+ SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDR_CTL, 2, 1, 0),
+ SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDR_CTL, 3, 1, 0),
+};
/* Headset Left */
-static const char *twl4030_hsol_texts[] =
- {"Off", "DACL1", "DACL2"};
-
-static const struct soc_enum twl4030_hsol_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1,
- ARRAY_SIZE(twl4030_hsol_texts),
- twl4030_hsol_texts);
-
-static const struct snd_kcontrol_new twl4030_dapm_hsol_control =
-SOC_DAPM_ENUM("Route", twl4030_hsol_enum);
+static const struct snd_kcontrol_new twl4030_dapm_hsol_controls[] = {
+ SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 0, 1, 0),
+ SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_HS_SEL, 1, 1, 0),
+ SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_HS_SEL, 2, 1, 0),
+};
/* Headset Right */
-static const char *twl4030_hsor_texts[] =
- {"Off", "DACR1", "DACR2"};
-
-static const struct soc_enum twl4030_hsor_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4,
- ARRAY_SIZE(twl4030_hsor_texts),
- twl4030_hsor_texts);
-
-static const struct snd_kcontrol_new twl4030_dapm_hsor_control =
-SOC_DAPM_ENUM("Route", twl4030_hsor_enum);
+static const struct snd_kcontrol_new twl4030_dapm_hsor_controls[] = {
+ SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 3, 1, 0),
+ SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_HS_SEL, 4, 1, 0),
+ SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_HS_SEL, 5, 1, 0),
+};
/* Carkit Left */
-static const char *twl4030_carkitl_texts[] =
- {"Off", "DACL1", "DACL2"};
-
-static const struct soc_enum twl4030_carkitl_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1,
- ARRAY_SIZE(twl4030_carkitl_texts),
- twl4030_carkitl_texts);
-
-static const struct snd_kcontrol_new twl4030_dapm_carkitl_control =
-SOC_DAPM_ENUM("Route", twl4030_carkitl_enum);
+static const struct snd_kcontrol_new twl4030_dapm_carkitl_controls[] = {
+ SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKL_CTL, 0, 1, 0),
+ SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PRECKL_CTL, 1, 1, 0),
+ SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PRECKL_CTL, 2, 1, 0),
+};
/* Carkit Right */
-static const char *twl4030_carkitr_texts[] =
- {"Off", "DACR1", "DACR2"};
-
-static const struct soc_enum twl4030_carkitr_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1,
- ARRAY_SIZE(twl4030_carkitr_texts),
- twl4030_carkitr_texts);
-
-static const struct snd_kcontrol_new twl4030_dapm_carkitr_control =
-SOC_DAPM_ENUM("Route", twl4030_carkitr_enum);
+static const struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = {
+ SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKR_CTL, 0, 1, 0),
+ SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PRECKR_CTL, 1, 1, 0),
+ SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PRECKR_CTL, 2, 1, 0),
+};
/* Handsfree Left */
static const char *twl4030_handsfreel_texts[] =
- {"Voice", "DACL1", "DACL2", "DACR2"};
+ {"Voice", "AudioL1", "AudioL2", "AudioR2"};
static const struct soc_enum twl4030_handsfreel_enum =
SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
@@ -425,7 +386,7 @@ SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
/* Handsfree Right */
static const char *twl4030_handsfreer_texts[] =
- {"Voice", "DACR1", "DACR2", "DACL2"};
+ {"Voice", "AudioR1", "AudioR2", "AudioL2"};
static const struct soc_enum twl4030_handsfreer_enum =
SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
@@ -435,37 +396,44 @@ static const struct soc_enum twl4030_handsfreer_enum =
static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
-/* Left analog microphone selection */
-static const char *twl4030_analoglmic_texts[] =
- {"Off", "Main mic", "Headset mic", "AUXL", "Carkit mic"};
+/* Vibra */
+/* Vibra audio path selection */
+static const char *twl4030_vibra_texts[] =
+ {"AudioL1", "AudioR1", "AudioL2", "AudioR2"};
-static const unsigned int twl4030_analoglmic_values[] =
- {0x0, 0x1, 0x2, 0x4, 0x8};
+static const struct soc_enum twl4030_vibra_enum =
+ SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 2,
+ ARRAY_SIZE(twl4030_vibra_texts),
+ twl4030_vibra_texts);
-static const struct soc_enum twl4030_analoglmic_enum =
- SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0, 0xf,
- ARRAY_SIZE(twl4030_analoglmic_texts),
- twl4030_analoglmic_texts,
- twl4030_analoglmic_values);
+static const struct snd_kcontrol_new twl4030_dapm_vibra_control =
+SOC_DAPM_ENUM("Route", twl4030_vibra_enum);
-static const struct snd_kcontrol_new twl4030_dapm_analoglmic_control =
-SOC_DAPM_VALUE_ENUM("Route", twl4030_analoglmic_enum);
+/* Vibra path selection: local vibrator (PWM) or audio driven */
+static const char *twl4030_vibrapath_texts[] =
+ {"Local vibrator", "Audio"};
-/* Right analog microphone selection */
-static const char *twl4030_analogrmic_texts[] =
- {"Off", "Sub mic", "AUXR"};
+static const struct soc_enum twl4030_vibrapath_enum =
+ SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 4,
+ ARRAY_SIZE(twl4030_vibrapath_texts),
+ twl4030_vibrapath_texts);
-static const unsigned int twl4030_analogrmic_values[] =
- {0x0, 0x1, 0x4};
+static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control =
+SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum);
-static const struct soc_enum twl4030_analogrmic_enum =
- SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0, 0x5,
- ARRAY_SIZE(twl4030_analogrmic_texts),
- twl4030_analogrmic_texts,
- twl4030_analogrmic_values);
+/* Left analog microphone selection */
+static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = {
+ SOC_DAPM_SINGLE("Main mic", TWL4030_REG_ANAMICL, 0, 1, 0),
+ SOC_DAPM_SINGLE("Headset mic", TWL4030_REG_ANAMICL, 1, 1, 0),
+ SOC_DAPM_SINGLE("AUXL", TWL4030_REG_ANAMICL, 2, 1, 0),
+ SOC_DAPM_SINGLE("Carkit mic", TWL4030_REG_ANAMICL, 3, 1, 0),
+};
-static const struct snd_kcontrol_new twl4030_dapm_analogrmic_control =
-SOC_DAPM_VALUE_ENUM("Route", twl4030_analogrmic_enum);
+/* Right analog microphone selection */
+static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = {
+ SOC_DAPM_SINGLE("Sub mic", TWL4030_REG_ANAMICR, 0, 1, 0),
+ SOC_DAPM_SINGLE("AUXR", TWL4030_REG_ANAMICR, 1, 1, 0),
+};
/* TX1 L/R Analog/Digital microphone selection */
static const char *twl4030_micpathtx1_texts[] =
@@ -507,6 +475,10 @@ static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control =
static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control =
SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0);
+/* Analog bypass for Voice */
+static const struct snd_kcontrol_new twl4030_dapm_abypassv_control =
+ SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0);
+
/* Digital bypass gain, 0 mutes the bypass */
static const unsigned int twl4030_dapm_dbypass_tlv[] = {
TLV_DB_RANGE_HEAD(2),
@@ -526,6 +498,18 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control =
TWL4030_REG_ATX2ARXPGA, 0, 7, 0,
twl4030_dapm_dbypass_tlv);
+/*
+ * Voice Sidetone GAIN volume control:
+ * from -51 to -10 dB in 1 dB steps (mute instead of -51 dB)
+ */
+static DECLARE_TLV_DB_SCALE(twl4030_dapm_dbypassv_tlv, -5100, 100, 1);
+
+/* Digital bypass voice: sidetone (VUL -> VDL)*/
+static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
+ SOC_DAPM_SINGLE_TLV("Volume",
+ TWL4030_REG_VSTPGA, 0, 0x29, 0,
+ twl4030_dapm_dbypassv_tlv);
+
static int micpath_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -624,7 +608,7 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
struct soc_mixer_control *m =
(struct soc_mixer_control *)w->kcontrols->private_value;
struct twl4030_priv *twl4030 = w->codec->private_data;
- unsigned char reg;
+ unsigned char reg, misc;
reg = twl4030_read_reg_cache(w->codec, m->reg);
@@ -636,14 +620,34 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
else
twl4030->bypass_state &=
~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
+ } else if (m->reg == TWL4030_REG_VDL_APGA_CTL) {
+ /* Analog voice bypass */
+ if (reg & (1 << m->shift))
+ twl4030->bypass_state |= (1 << 4);
+ else
+ twl4030->bypass_state &= ~(1 << 4);
+ } else if (m->reg == TWL4030_REG_VSTPGA) {
+ /* Voice digital bypass */
+ if (reg)
+ twl4030->bypass_state |= (1 << 5);
+ else
+ twl4030->bypass_state &= ~(1 << 5);
} else {
/* Digital bypass */
if (reg & (0x7 << m->shift))
- twl4030->bypass_state |= (1 << (m->shift ? 5 : 4));
+ twl4030->bypass_state |= (1 << (m->shift ? 7 : 6));
else
- twl4030->bypass_state &= ~(1 << (m->shift ? 5 : 4));
+ twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6));
}
+ /* Enable master analog loopback mode if any analog switch is enabled*/
+ misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1);
+ if (twl4030->bypass_state & 0x1F)
+ misc |= TWL4030_FMLOOP_EN;
+ else
+ misc &= ~TWL4030_FMLOOP_EN;
+ twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc);
+
if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
if (twl4030->bypass_state)
twl4030_codec_mute(w->codec, 0);
@@ -824,6 +828,12 @@ static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);
/*
+ * Voice Downlink GAIN volume control:
+ * from -37 to 12 dB in 1 dB steps (mute instead of -37 dB)
+ */
+static DECLARE_TLV_DB_SCALE(digital_voice_downlink_tlv, -3700, 100, 1);
+
+/*
* Analog playback gain
* -24 dB to 12 dB in 2 dB steps
*/
@@ -864,6 +874,26 @@ static const struct soc_enum twl4030_rampdelay_enum =
ARRAY_SIZE(twl4030_rampdelay_texts),
twl4030_rampdelay_texts);
+/* Vibra H-bridge direction mode */
+static const char *twl4030_vibradirmode_texts[] = {
+ "Vibra H-bridge direction", "Audio data MSB",
+};
+
+static const struct soc_enum twl4030_vibradirmode_enum =
+ SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 5,
+ ARRAY_SIZE(twl4030_vibradirmode_texts),
+ twl4030_vibradirmode_texts);
+
+/* Vibra H-bridge direction */
+static const char *twl4030_vibradir_texts[] = {
+ "Positive polarity", "Negative polarity",
+};
+
+static const struct soc_enum twl4030_vibradir_enum =
+ SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 1,
+ ARRAY_SIZE(twl4030_vibradir_texts),
+ twl4030_vibradir_texts);
+
static const struct snd_kcontrol_new twl4030_snd_controls[] = {
/* Common playback gain controls */
SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
@@ -893,6 +923,16 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
1, 1, 0),
+ /* Common voice downlink gain controls */
+ SOC_SINGLE_TLV("DAC Voice Digital Downlink Volume",
+ TWL4030_REG_VRXPGA, 0, 0x31, 0, digital_voice_downlink_tlv),
+
+ SOC_SINGLE_TLV("DAC Voice Analog Downlink Volume",
+ TWL4030_REG_VDL_APGA_CTL, 3, 0x12, 1, analog_tlv),
+
+ SOC_SINGLE("DAC Voice Analog Downlink Switch",
+ TWL4030_REG_VDL_APGA_CTL, 1, 1, 0),
+
/* Separate output gain controls */
SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume",
TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
@@ -920,6 +960,9 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
0, 3, 5, 0, input_gain_tlv),
SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum),
+
+ SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
+ SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum),
};
static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
@@ -947,6 +990,7 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("CARKITR"),
SND_SOC_DAPM_OUTPUT("HFL"),
SND_SOC_DAPM_OUTPUT("HFR"),
+ SND_SOC_DAPM_OUTPUT("VIBRA"),
/* DACs */
SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback",
@@ -957,6 +1001,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
+ SND_SOC_NOPM, 0, 0),
/* Analog PGAs */
SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
@@ -967,6 +1013,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
0, 0, NULL, 0),
SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL,
0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("VDL_APGA", TWL4030_REG_VDL_APGA_CTL,
+ 0, 0, NULL, 0),
/* Analog bypasses */
SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
@@ -981,6 +1029,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_abypassl2_control,
bypass_event, SND_SOC_DAPM_POST_REG),
+ SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_abypassv_control,
+ bypass_event, SND_SOC_DAPM_POST_REG),
/* Digital bypasses */
SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
@@ -989,6 +1040,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_dbypassr_control, bypass_event,
SND_SOC_DAPM_POST_REG),
+ SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_dbypassv_control, bypass_event,
+ SND_SOC_DAPM_POST_REG),
SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", TWL4030_REG_AVDAC_CTL,
0, 0, NULL, 0),
@@ -998,27 +1052,38 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
2, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL,
3, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer", TWL4030_REG_AVDAC_CTL,
+ 4, 0, NULL, 0),
- /* Output MUX controls */
+ /* Output MIXER controls */
/* Earpiece */
- SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_earpiece_control),
+ SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_earpiece_controls[0],
+ ARRAY_SIZE(twl4030_dapm_earpiece_controls)),
/* PreDrivL/R */
- SND_SOC_DAPM_VALUE_MUX("PredriveL Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_predrivel_control),
- SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_predriver_control),
+ SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_predrivel_controls[0],
+ ARRAY_SIZE(twl4030_dapm_predrivel_controls)),
+ SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_predriver_controls[0],
+ ARRAY_SIZE(twl4030_dapm_predriver_controls)),
/* HeadsetL/R */
- SND_SOC_DAPM_MUX_E("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_hsol_control, headsetl_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_hsor_control),
+ SND_SOC_DAPM_MIXER_E("HeadsetL Mixer", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_hsol_controls[0],
+ ARRAY_SIZE(twl4030_dapm_hsol_controls), headsetl_event,
+ SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER("HeadsetR Mixer", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_hsor_controls[0],
+ ARRAY_SIZE(twl4030_dapm_hsor_controls)),
/* CarkitL/R */
- SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_carkitl_control),
- SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_carkitr_control),
+ SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_carkitl_controls[0],
+ ARRAY_SIZE(twl4030_dapm_carkitl_controls)),
+ SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_carkitr_controls[0],
+ ARRAY_SIZE(twl4030_dapm_carkitr_controls)),
+
+ /* Output MUX controls */
/* HandsfreeL/R */
SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0,
&twl4030_dapm_handsfreel_control, handsfree_event,
@@ -1026,6 +1091,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0,
&twl4030_dapm_handsfreer_control, handsfree_event,
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+ /* Vibra */
+ SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
+ &twl4030_dapm_vibra_control),
+ SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
+ &twl4030_dapm_vibrapath_control),
/* Introducing four virtual ADC, since TWL4030 have four channel for
capture */
@@ -1050,11 +1120,15 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
SND_SOC_DAPM_POST_REG),
- /* Analog input muxes with switch for the capture amplifiers */
- SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route",
- TWL4030_REG_ANAMICL, 4, 0, &twl4030_dapm_analoglmic_control),
- SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route",
- TWL4030_REG_ANAMICR, 4, 0, &twl4030_dapm_analogrmic_control),
+ /* Analog input mixers for the capture amplifiers */
+ SND_SOC_DAPM_MIXER("Analog Left Capture Route",
+ TWL4030_REG_ANAMICL, 4, 0,
+ &twl4030_dapm_analoglmic_controls[0],
+ ARRAY_SIZE(twl4030_dapm_analoglmic_controls)),
+ SND_SOC_DAPM_MIXER("Analog Right Capture Route",
+ TWL4030_REG_ANAMICR, 4, 0,
+ &twl4030_dapm_analogrmic_controls[0],
+ ARRAY_SIZE(twl4030_dapm_analogrmic_controls)),
SND_SOC_DAPM_PGA("ADC Physical Left",
TWL4030_REG_AVADC_CTL, 3, 0, NULL, 0),
@@ -1077,58 +1151,76 @@ static const struct snd_soc_dapm_route intercon[] = {
{"Analog R1 Playback Mixer", NULL, "DAC Right1"},
{"Analog L2 Playback Mixer", NULL, "DAC Left2"},
{"Analog R2 Playback Mixer", NULL, "DAC Right2"},
+ {"Analog Voice Playback Mixer", NULL, "DAC Voice"},
{"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"},
{"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"},
{"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"},
{"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"},
+ {"VDL_APGA", NULL, "Analog Voice Playback Mixer"},
/* Internal playback routings */
/* Earpiece */
- {"Earpiece Mux", "DACL1", "ARXL1_APGA"},
- {"Earpiece Mux", "DACL2", "ARXL2_APGA"},
- {"Earpiece Mux", "DACR1", "ARXR1_APGA"},
+ {"Earpiece Mixer", "Voice", "VDL_APGA"},
+ {"Earpiece Mixer", "AudioL1", "ARXL1_APGA"},
+ {"Earpiece Mixer", "AudioL2", "ARXL2_APGA"},
+ {"Earpiece Mixer", "AudioR1", "ARXR1_APGA"},
/* PreDrivL */
- {"PredriveL Mux", "DACL1", "ARXL1_APGA"},
- {"PredriveL Mux", "DACL2", "ARXL2_APGA"},
- {"PredriveL Mux", "DACR2", "ARXR2_APGA"},
+ {"PredriveL Mixer", "Voice", "VDL_APGA"},
+ {"PredriveL Mixer", "AudioL1", "ARXL1_APGA"},
+ {"PredriveL Mixer", "AudioL2", "ARXL2_APGA"},
+ {"PredriveL Mixer", "AudioR2", "ARXR2_APGA"},
/* PreDrivR */
- {"PredriveR Mux", "DACR1", "ARXR1_APGA"},
- {"PredriveR Mux", "DACR2", "ARXR2_APGA"},
- {"PredriveR Mux", "DACL2", "ARXL2_APGA"},
+ {"PredriveR Mixer", "Voice", "VDL_APGA"},
+ {"PredriveR Mixer", "AudioR1", "ARXR1_APGA"},
+ {"PredriveR Mixer", "AudioR2", "ARXR2_APGA"},
+ {"PredriveR Mixer", "AudioL2", "ARXL2_APGA"},
/* HeadsetL */
- {"HeadsetL Mux", "DACL1", "ARXL1_APGA"},
- {"HeadsetL Mux", "DACL2", "ARXL2_APGA"},
+ {"HeadsetL Mixer", "Voice", "VDL_APGA"},
+ {"HeadsetL Mixer", "AudioL1", "ARXL1_APGA"},
+ {"HeadsetL Mixer", "AudioL2", "ARXL2_APGA"},
/* HeadsetR */
- {"HeadsetR Mux", "DACR1", "ARXR1_APGA"},
- {"HeadsetR Mux", "DACR2", "ARXR2_APGA"},
+ {"HeadsetR Mixer", "Voice", "VDL_APGA"},
+ {"HeadsetR Mixer", "AudioR1", "ARXR1_APGA"},
+ {"HeadsetR Mixer", "AudioR2", "ARXR2_APGA"},
/* CarkitL */
- {"CarkitL Mux", "DACL1", "ARXL1_APGA"},
- {"CarkitL Mux", "DACL2", "ARXL2_APGA"},
+ {"CarkitL Mixer", "Voice", "VDL_APGA"},
+ {"CarkitL Mixer", "AudioL1", "ARXL1_APGA"},
+ {"CarkitL Mixer", "AudioL2", "ARXL2_APGA"},
/* CarkitR */
- {"CarkitR Mux", "DACR1", "ARXR1_APGA"},
- {"CarkitR Mux", "DACR2", "ARXR2_APGA"},
+ {"CarkitR Mixer", "Voice", "VDL_APGA"},
+ {"CarkitR Mixer", "AudioR1", "ARXR1_APGA"},
+ {"CarkitR Mixer", "AudioR2", "ARXR2_APGA"},
/* HandsfreeL */
- {"HandsfreeL Mux", "DACL1", "ARXL1_APGA"},
- {"HandsfreeL Mux", "DACL2", "ARXL2_APGA"},
- {"HandsfreeL Mux", "DACR2", "ARXR2_APGA"},
+ {"HandsfreeL Mux", "Voice", "VDL_APGA"},
+ {"HandsfreeL Mux", "AudioL1", "ARXL1_APGA"},
+ {"HandsfreeL Mux", "AudioL2", "ARXL2_APGA"},
+ {"HandsfreeL Mux", "AudioR2", "ARXR2_APGA"},
/* HandsfreeR */
- {"HandsfreeR Mux", "DACR1", "ARXR1_APGA"},
- {"HandsfreeR Mux", "DACR2", "ARXR2_APGA"},
- {"HandsfreeR Mux", "DACL2", "ARXL2_APGA"},
+ {"HandsfreeR Mux", "Voice", "VDL_APGA"},
+ {"HandsfreeR Mux", "AudioR1", "ARXR1_APGA"},
+ {"HandsfreeR Mux", "AudioR2", "ARXR2_APGA"},
+ {"HandsfreeR Mux", "AudioL2", "ARXL2_APGA"},
+ /* Vibra */
+ {"Vibra Mux", "AudioL1", "DAC Left1"},
+ {"Vibra Mux", "AudioR1", "DAC Right1"},
+ {"Vibra Mux", "AudioL2", "DAC Left2"},
+ {"Vibra Mux", "AudioR2", "DAC Right2"},
/* outputs */
{"OUTL", NULL, "ARXL2_APGA"},
{"OUTR", NULL, "ARXR2_APGA"},
- {"EARPIECE", NULL, "Earpiece Mux"},
- {"PREDRIVEL", NULL, "PredriveL Mux"},
- {"PREDRIVER", NULL, "PredriveR Mux"},
- {"HSOL", NULL, "HeadsetL Mux"},
- {"HSOR", NULL, "HeadsetR Mux"},
- {"CARKITL", NULL, "CarkitL Mux"},
- {"CARKITR", NULL, "CarkitR Mux"},
+ {"EARPIECE", NULL, "Earpiece Mixer"},
+ {"PREDRIVEL", NULL, "PredriveL Mixer"},
+ {"PREDRIVER", NULL, "PredriveR Mixer"},
+ {"HSOL", NULL, "HeadsetL Mixer"},
+ {"HSOR", NULL, "HeadsetR Mixer"},
+ {"CARKITL", NULL, "CarkitL Mixer"},
+ {"CARKITR", NULL, "CarkitR Mixer"},
{"HFL", NULL, "HandsfreeL Mux"},
{"HFR", NULL, "HandsfreeR Mux"},
+ {"Vibra Route", "Audio", "Vibra Mux"},
+ {"VIBRA", NULL, "Vibra Route"},
/* Capture path */
{"Analog Left Capture Route", "Main mic", "MAINMIC"},
@@ -1168,18 +1260,22 @@ static const struct snd_soc_dapm_route intercon[] = {
{"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"},
{"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"},
{"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"},
+ {"Voice Analog Loopback", "Switch", "Analog Left Capture Route"},
{"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
{"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
{"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
{"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"},
+ {"Analog Voice Playback Mixer", NULL, "Voice Analog Loopback"},
/* Digital bypass routes */
{"Right Digital Loopback", "Volume", "TX1 Capture Route"},
{"Left Digital Loopback", "Volume", "TX1 Capture Route"},
+ {"Voice Digital Loopback", "Volume", "TX2 Capture Route"},
{"Analog R2 Playback Mixer", NULL, "Right Digital Loopback"},
{"Analog L2 Playback Mixer", NULL, "Left Digital Loopback"},
+ {"Analog Voice Playback Mixer", NULL, "Voice Digital Loopback"},
};
@@ -1226,6 +1322,58 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
+static void twl4030_constraints(struct twl4030_priv *twl4030,
+ struct snd_pcm_substream *mst_substream)
+{
+ struct snd_pcm_substream *slv_substream;
+
+ /* Pick the stream, which need to be constrained */
+ if (mst_substream == twl4030->master_substream)
+ slv_substream = twl4030->slave_substream;
+ else if (mst_substream == twl4030->slave_substream)
+ slv_substream = twl4030->master_substream;
+ else /* This should not happen.. */
+ return;
+
+ /* Set the constraints according to the already configured stream */
+ snd_pcm_hw_constraint_minmax(slv_substream->runtime,
+ SNDRV_PCM_HW_PARAM_RATE,
+ twl4030->rate,
+ twl4030->rate);
+
+ snd_pcm_hw_constraint_minmax(slv_substream->runtime,
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+ twl4030->sample_bits,
+ twl4030->sample_bits);
+
+ snd_pcm_hw_constraint_minmax(slv_substream->runtime,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ twl4030->channels,
+ twl4030->channels);
+}
+
+/* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for
+ * capture has to be enabled/disabled. */
+static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
+ int enable)
+{
+ u8 reg, mask;
+
+ reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION);
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK)
+ mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN;
+ else
+ mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN;
+
+ if (enable)
+ reg |= mask;
+ else
+ reg &= ~mask;
+
+ twl4030_write(codec, TWL4030_REG_OPTION, reg);
+}
+
static int twl4030_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -1234,26 +1382,25 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = socdev->card->codec;
struct twl4030_priv *twl4030 = codec->private_data;
- /* If we already have a playback or capture going then constrain
- * this substream to match it.
- */
if (twl4030->master_substream) {
- struct snd_pcm_runtime *master_runtime;
- master_runtime = twl4030->master_substream->runtime;
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_RATE,
- master_runtime->rate,
- master_runtime->rate);
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- master_runtime->sample_bits,
- master_runtime->sample_bits);
-
twl4030->slave_substream = substream;
- } else
+ /* The DAI has one configuration for playback and capture, so
+ * if the DAI has been already configured then constrain this
+ * substream to match it. */
+ if (twl4030->configured)
+ twl4030_constraints(twl4030, twl4030->master_substream);
+ } else {
+ if (!(twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) &
+ TWL4030_OPTION_1)) {
+ /* In option2 4 channel is not supported, set the
+ * constraint for the first stream for channels, the
+ * second stream will 'inherit' this cosntraint */
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ 2, 2);
+ }
twl4030->master_substream = substream;
+ }
return 0;
}
@@ -1270,6 +1417,17 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream,
twl4030->master_substream = twl4030->slave_substream;
twl4030->slave_substream = NULL;
+
+ /* If all streams are closed, or the remaining stream has not yet
+ * been configured than set the DAI as not configured. */
+ if (!twl4030->master_substream)
+ twl4030->configured = 0;
+ else if (!twl4030->master_substream->runtime->channels)
+ twl4030->configured = 0;
+
+ /* If the closing substream had 4 channel, do the necessary cleanup */
+ if (substream->runtime->channels == 4)
+ twl4030_tdm_enable(codec, substream->stream, 0);
}
static int twl4030_hw_params(struct snd_pcm_substream *substream,
@@ -1282,8 +1440,18 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
struct twl4030_priv *twl4030 = codec->private_data;
u8 mode, old_mode, format, old_format;
- if (substream == twl4030->slave_substream)
- /* Ignoring hw_params for slave substream */
+ /* If the substream has 4 channel, do the necessary setup */
+ if (params_channels(params) == 4) {
+ /* Safety check: are we in the correct operating mode? */
+ if ((twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) &
+ TWL4030_OPTION_1))
+ twl4030_tdm_enable(codec, substream->stream, 1);
+ else
+ return -EINVAL;
+ }
+
+ if (twl4030->configured)
+ /* Ignoring hw_params for already configured DAI */
return 0;
/* bit rate */
@@ -1363,6 +1531,21 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
/* set CODECPDZ afterwards */
twl4030_codec_enable(codec, 1);
}
+
+ /* Store the important parameters for the DAI configuration and set
+ * the DAI as configured */
+ twl4030->configured = 1;
+ twl4030->rate = params_rate(params);
+ twl4030->sample_bits = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
+ twl4030->channels = params_channels(params);
+
+ /* If both playback and capture streams are open, and one of them
+ * is setting the hw parameters right now (since we are here), set
+ * constraints to the other stream to match the current one. */
+ if (twl4030->slave_substream)
+ twl4030_constraints(twl4030, substream);
+
return 0;
}
@@ -1424,6 +1607,9 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
case SND_SOC_DAIFMT_I2S:
format |= TWL4030_AIF_FORMAT_CODEC;
break;
+ case SND_SOC_DAIFMT_DSP_A:
+ format |= TWL4030_AIF_FORMAT_TDM;
+ break;
default:
return -EINVAL;
}
@@ -1443,6 +1629,144 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
return 0;
}
+static int twl4030_voice_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->card->codec;
+ u8 infreq;
+ u8 mode;
+
+ /* If the system master clock is not 26MHz, the voice PCM interface is
+ * not avilable.
+ */
+ infreq = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL)
+ & TWL4030_APLL_INFREQ;
+
+ if (infreq != TWL4030_APLL_INFREQ_26000KHZ) {
+ printk(KERN_ERR "TWL4030 voice startup: "
+ "MCLK is not 26MHz, call set_sysclk() on init\n");
+ return -EINVAL;
+ }
+
+ /* If the codec mode is not option2, the voice PCM interface is not
+ * avilable.
+ */
+ mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
+ & TWL4030_OPT_MODE;
+
+ if (mode != TWL4030_OPTION_2) {
+ printk(KERN_ERR "TWL4030 voice startup: "
+ "the codec mode is not option2\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->card->codec;
+ u8 old_mode, mode;
+
+ /* bit rate */
+ old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
+ & ~(TWL4030_CODECPDZ);
+ mode = old_mode;
+
+ switch (params_rate(params)) {
+ case 8000:
+ mode &= ~(TWL4030_SEL_16K);
+ break;
+ case 16000:
+ mode |= TWL4030_SEL_16K;
+ break;
+ default:
+ printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n",
+ params_rate(params));
+ return -EINVAL;
+ }
+
+ if (mode != old_mode) {
+ /* change rate and set CODECPDZ */
+ twl4030_codec_enable(codec, 0);
+ twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
+ twl4030_codec_enable(codec, 1);
+ }
+
+ return 0;
+}
+
+static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u8 infreq;
+
+ switch (freq) {
+ case 26000000:
+ infreq = TWL4030_APLL_INFREQ_26000KHZ;
+ break;
+ default:
+ printk(KERN_ERR "TWL4030 voice set sysclk: unknown rate %d\n",
+ freq);
+ return -EINVAL;
+ }
+
+ infreq |= TWL4030_APLL_EN;
+ twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
+
+ return 0;
+}
+
+static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u8 old_format, format;
+
+ /* get format */
+ old_format = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
+ format = old_format;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFM:
+ format &= ~(TWL4030_VIF_SLAVE_EN);
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ format |= TWL4030_VIF_SLAVE_EN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_IB_NF:
+ format &= ~(TWL4030_VIF_FORMAT);
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ format |= TWL4030_VIF_FORMAT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (format != old_format) {
+ /* change format and set CODECPDZ */
+ twl4030_codec_enable(codec, 0);
+ twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
+ twl4030_codec_enable(codec, 1);
+ }
+
+ return 0;
+}
+
#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
@@ -1454,21 +1778,46 @@ static struct snd_soc_dai_ops twl4030_dai_ops = {
.set_fmt = twl4030_set_dai_fmt,
};
-struct snd_soc_dai twl4030_dai = {
+static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
+ .startup = twl4030_voice_startup,
+ .hw_params = twl4030_voice_hw_params,
+ .set_sysclk = twl4030_voice_set_dai_sysclk,
+ .set_fmt = twl4030_voice_set_dai_fmt,
+};
+
+struct snd_soc_dai twl4030_dai[] = {
+{
.name = "twl4030",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
- .channels_max = 2,
+ .channels_max = 4,
.rates = TWL4030_RATES | SNDRV_PCM_RATE_96000,
.formats = TWL4030_FORMATS,},
.capture = {
.stream_name = "Capture",
.channels_min = 2,
- .channels_max = 2,
+ .channels_max = 4,
.rates = TWL4030_RATES,
.formats = TWL4030_FORMATS,},
.ops = &twl4030_dai_ops,
+},
+{
+ .name = "twl4030 Voice",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 1,
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .ops = &twl4030_dai_voice_ops,
+},
};
EXPORT_SYMBOL_GPL(twl4030_dai);
@@ -1509,8 +1858,8 @@ static int twl4030_init(struct snd_soc_device *socdev)
codec->read = twl4030_read_reg_cache;
codec->write = twl4030_write;
codec->set_bias_level = twl4030_set_bias_level;
- codec->dai = &twl4030_dai;
- codec->num_dai = 1;
+ codec->dai = twl4030_dai;
+ codec->num_dai = ARRAY_SIZE(twl4030_dai),
codec->reg_cache_size = sizeof(twl4030_reg);
codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
GFP_KERNEL);
@@ -1604,13 +1953,13 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
static int __init twl4030_modinit(void)
{
- return snd_soc_register_dai(&twl4030_dai);
+ return snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
}
module_init(twl4030_modinit);
static void __exit twl4030_exit(void)
{
- snd_soc_unregister_dai(&twl4030_dai);
+ snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
}
module_exit(twl4030_exit);
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index cb63765db1df..3441115136f6 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -113,6 +113,19 @@
#define TWL4030_SEL_16K 0x04
#define TWL4030_CODECPDZ 0x02
#define TWL4030_OPT_MODE 0x01
+#define TWL4030_OPTION_1 (1 << 0)
+#define TWL4030_OPTION_2 (0 << 0)
+
+/* TWL4030_OPTION (0x02) Fields */
+
+#define TWL4030_ATXL1_EN (1 << 0)
+#define TWL4030_ATXR1_EN (1 << 1)
+#define TWL4030_ATXL2_VTXL_EN (1 << 2)
+#define TWL4030_ATXR2_VTXR_EN (1 << 3)
+#define TWL4030_ARXL1_VRX_EN (1 << 4)
+#define TWL4030_ARXR1_EN (1 << 5)
+#define TWL4030_ARXL2_EN (1 << 6)
+#define TWL4030_ARXR2_EN (1 << 7)
/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
@@ -171,6 +184,17 @@
#define TWL4030_CLK256FS_EN 0x02
#define TWL4030_AIF_EN 0x01
+/* VOICE_IF (0x0F) Fields */
+
+#define TWL4030_VIF_SLAVE_EN 0x80
+#define TWL4030_VIF_DIN_EN 0x40
+#define TWL4030_VIF_DOUT_EN 0x20
+#define TWL4030_VIF_SWAP 0x10
+#define TWL4030_VIF_FORMAT 0x08
+#define TWL4030_VIF_TRI_EN 0x04
+#define TWL4030_VIF_SUB_EN 0x02
+#define TWL4030_VIF_EN 0x01
+
/* EAR_CTL (0x21) */
#define TWL4030_EAR_GAIN 0x30
@@ -236,7 +260,10 @@
#define TWL4030_SMOOTH_ANAVOL_EN 0x02
#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
-extern struct snd_soc_dai twl4030_dai;
+#define TWL4030_DAI_HIFI 0
+#define TWL4030_DAI_VOICE 1
+
+extern struct snd_soc_dai twl4030_dai[2];
extern struct snd_soc_codec_device soc_codec_dev_twl4030;
#endif /* End of __TWL4030_AUDIO_H__ */
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
index d11bd9288cf9..d088eb4b88bb 100644
--- a/sound/soc/codecs/wm8350.h
+++ b/sound/soc/codecs/wm8350.h
@@ -13,6 +13,7 @@
#define _WM8350_H
#include <sound/soc.h>
+#include <linux/mfd/wm8350/audio.h>
extern struct snd_soc_dai wm8350_dai;
extern struct snd_soc_codec_device soc_codec_dev_wm8350;
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 510efa604008..e4547de8eec2 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -1473,8 +1473,8 @@ static int wm8400_codec_probe(struct platform_device *dev)
codec = &priv->codec;
codec->private_data = priv;
- codec->control_data = dev->dev.driver_data;
- priv->wm8400 = dev->dev.driver_data;
+ codec->control_data = dev_get_drvdata(&dev->dev);
+ priv->wm8400 = dev_get_drvdata(&dev->dev);
ret = regulator_bulk_get(priv->wm8400->dev,
ARRAY_SIZE(power), &power[0]);
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index e043e3f60008..7a205876ef4f 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -666,14 +666,14 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi)
codec->hw_write = (hw_write_t)wm8731_spi_write;
codec->dev = &spi->dev;
- spi->dev.driver_data = wm8731;
+ dev_set_drvdata(&spi->dev, wm8731);
return wm8731_register(wm8731);
}
static int __devexit wm8731_spi_remove(struct spi_device *spi)
{
- struct wm8731_priv *wm8731 = spi->dev.driver_data;
+ struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev);
wm8731_unregister(wm8731);
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index a6e8f3f7f052..d121e58cae2b 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1822,14 +1822,14 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi)
codec->hw_write = (hw_write_t)wm8753_spi_write;
codec->dev = &spi->dev;
- spi->dev.driver_data = wm8753;
+ dev_set_drvdata(&spi->dev, wm8753);
return wm8753_register(wm8753);
}
static int __devexit wm8753_spi_remove(struct spi_device *spi)
{
- struct wm8753_priv *wm8753 = spi->dev.driver_data;
+ struct wm8753_priv *wm8753 = dev_get_drvdata(&spi->dev);
wm8753_unregister(wm8753);
return 0;
}
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 8cf571f1a803..d8a9222fbf74 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -217,7 +217,6 @@ struct wm8903_priv {
int sysclk;
/* Reference counts */
- int charge_pump_users;
int class_w_users;
int playback_active;
int capture_active;
@@ -373,6 +372,15 @@ static void wm8903_reset(struct snd_soc_codec *codec)
#define WM8903_OUTPUT_INT 0x2
#define WM8903_OUTPUT_IN 0x1
+static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ WARN_ON(event != SND_SOC_DAPM_POST_PMU);
+ mdelay(4);
+
+ return 0;
+}
+
/*
* Event for headphone and line out amplifier power changes. Special
* power up/down sequences are required in order to maximise pop/click
@@ -382,19 +390,20 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
- struct wm8903_priv *wm8903 = codec->private_data;
- struct i2c_client *i2c = codec->control_data;
u16 val;
u16 reg;
+ u16 dcs_reg;
+ u16 dcs_bit;
int shift;
- u16 cp_reg = wm8903_read(codec, WM8903_CHARGE_PUMP_0);
switch (w->reg) {
case WM8903_POWER_MANAGEMENT_2:
reg = WM8903_ANALOGUE_HP_0;
+ dcs_bit = 0 + w->shift;
break;
case WM8903_POWER_MANAGEMENT_3:
reg = WM8903_ANALOGUE_LINEOUT_0;
+ dcs_bit = 2 + w->shift;
break;
default:
BUG();
@@ -419,18 +428,6 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
/* Short the output */
val &= ~(WM8903_OUTPUT_SHORT << shift);
wm8903_write(codec, reg, val);
-
- wm8903->charge_pump_users++;
-
- dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
- wm8903->charge_pump_users);
-
- if (wm8903->charge_pump_users == 1) {
- dev_dbg(&i2c->dev, "Enabling charge pump\n");
- wm8903_write(codec, WM8903_CHARGE_PUMP_0,
- cp_reg | WM8903_CP_ENA);
- mdelay(4);
- }
}
if (event & SND_SOC_DAPM_POST_PMU) {
@@ -446,6 +443,11 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
val |= (WM8903_OUTPUT_OUT << shift);
wm8903_write(codec, reg, val);
+ /* Enable the DC servo */
+ dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0);
+ dcs_reg |= dcs_bit;
+ wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg);
+
/* Remove the short */
val |= (WM8903_OUTPUT_SHORT << shift);
wm8903_write(codec, reg, val);
@@ -458,25 +460,17 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
val &= ~(WM8903_OUTPUT_SHORT << shift);
wm8903_write(codec, reg, val);
+ /* Disable the DC servo */
+ dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0);
+ dcs_reg &= ~dcs_bit;
+ wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg);
+
/* Then disable the intermediate and output stages */
val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT |
WM8903_OUTPUT_IN) << shift);
wm8903_write(codec, reg, val);
}
- if (event & SND_SOC_DAPM_POST_PMD) {
- wm8903->charge_pump_users--;
-
- dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
- wm8903->charge_pump_users);
-
- if (wm8903->charge_pump_users == 0) {
- dev_dbg(&i2c->dev, "Disabling charge pump\n");
- wm8903_write(codec, WM8903_CHARGE_PUMP_0,
- cp_reg & ~WM8903_CP_ENA);
- }
- }
-
return 0;
}
@@ -539,6 +533,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
/* ALSA can only do steps of .01dB */
static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
+static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0);
static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0);
@@ -657,6 +652,16 @@ static const struct soc_enum rinput_inv_enum =
SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 4, 3, rinput_mux_text);
+static const char *sidetone_text[] = {
+ "None", "Left", "Right"
+};
+
+static const struct soc_enum lsidetone_enum =
+ SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 2, 3, sidetone_text);
+
+static const struct soc_enum rsidetone_enum =
+ SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text);
+
static const struct snd_kcontrol_new wm8903_snd_controls[] = {
/* Input PGAs - No TLV since the scale depends on PGA mode */
@@ -700,6 +705,9 @@ SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
SOC_ENUM("ADC Companding Mode", adc_companding),
SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0),
+SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8,
+ 12, 0, digital_sidetone_tlv),
+
/* DAC */
SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
@@ -762,6 +770,12 @@ static const struct snd_kcontrol_new rinput_mux =
static const struct snd_kcontrol_new rinput_inv_mux =
SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum);
+static const struct snd_kcontrol_new lsidetone_mux =
+ SOC_DAPM_ENUM("DACL Sidetone Mux", lsidetone_enum);
+
+static const struct snd_kcontrol_new rsidetone_mux =
+ SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
+
static const struct snd_kcontrol_new left_output_mixer[] = {
SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
@@ -828,6 +842,9 @@ SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0),
SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0),
+SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux),
+SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux),
+
SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0),
SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0),
@@ -844,26 +861,29 @@ SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
1, 0, NULL, 0, wm8903_output_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
0, 0, NULL, 0, wm8903_output_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0,
NULL, 0, wm8903_output_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0,
NULL, 0, wm8903_output_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
NULL, 0),
SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
NULL, 0),
+SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0,
+ wm8903_cp_event, SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
};
static const struct snd_soc_dapm_route intercon[] = {
@@ -909,7 +929,19 @@ static const struct snd_soc_dapm_route intercon[] = {
{ "Right Input PGA", NULL, "Right Input Mode Mux" },
{ "ADCL", NULL, "Left Input PGA" },
+ { "ADCL", NULL, "CLK_DSP" },
{ "ADCR", NULL, "Right Input PGA" },
+ { "ADCR", NULL, "CLK_DSP" },
+
+ { "DACL Sidetone", "Left", "ADCL" },
+ { "DACL Sidetone", "Right", "ADCR" },
+ { "DACR Sidetone", "Left", "ADCL" },
+ { "DACR Sidetone", "Right", "ADCR" },
+
+ { "DACL", NULL, "DACL Sidetone" },
+ { "DACL", NULL, "CLK_DSP" },
+ { "DACR", NULL, "DACR Sidetone" },
+ { "DACR", NULL, "CLK_DSP" },
{ "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" },
{ "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" },
@@ -951,6 +983,11 @@ static const struct snd_soc_dapm_route intercon[] = {
{ "ROP", NULL, "Right Speaker PGA" },
{ "RON", NULL, "Right Speaker PGA" },
+
+ { "Left Headphone Output PGA", NULL, "Charge Pump" },
+ { "Right Headphone Output PGA", NULL, "Charge Pump" },
+ { "Left Line Output PGA", NULL, "Charge Pump" },
+ { "Right Line Output PGA", NULL, "Charge Pump" },
};
static int wm8903_add_widgets(struct snd_soc_codec *codec)
@@ -985,6 +1022,11 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
wm8903_write(codec, WM8903_CLOCK_RATES_2,
WM8903_CLK_SYS_ENA);
+ /* Change DC servo dither level in startup sequence */
+ wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11);
+ wm8903_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257);
+ wm8903_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2);
+
wm8903_run_sequence(codec, 0);
wm8903_sync_reg_cache(codec, codec->reg_cache);
@@ -1277,14 +1319,8 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
if (wm8903->master_substream) {
master_runtime = wm8903->master_substream->runtime;
- dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n",
- master_runtime->sample_bits,
- master_runtime->rate);
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_RATE,
- master_runtime->rate,
- master_runtime->rate);
+ dev_dbg(&i2c->dev, "Constraining to %d bits\n",
+ master_runtime->sample_bits);
snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
@@ -1523,6 +1559,7 @@ struct snd_soc_dai wm8903_dai = {
.formats = WM8903_FORMATS,
},
.ops = &wm8903_dai_ops,
+ .symmetric_rates = 1,
};
EXPORT_SYMBOL_GPL(wm8903_dai);
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
new file mode 100644
index 000000000000..a66dacc7cc83
--- /dev/null
+++ b/sound/soc/codecs/wm8940.c
@@ -0,0 +1,955 @@
+/*
+ * wm8940.c -- WM8940 ALSA Soc Audio driver
+ *
+ * Author: Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ * Based on wm8510.c
+ * Copyright 2006 Wolfson Microelectronics PLC.
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
+ *
+ * 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.
+ *
+ * Not currently handled:
+ * Notch filter control
+ * AUXMode (inverting vs mixer)
+ * No means to obtain current gain if alc enabled.
+ * No use made of gpio
+ * Fast VMID discharge for power down
+ * Soft Start
+ * DLR and ALR Swaps not enabled
+ * Digital Sidetone not supported
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8940.h"
+
+struct wm8940_priv {
+ unsigned int sysclk;
+ u16 reg_cache[WM8940_CACHEREGNUM];
+ struct snd_soc_codec codec;
+};
+
+static u16 wm8940_reg_defaults[] = {
+ 0x8940, /* Soft Reset */
+ 0x0000, /* Power 1 */
+ 0x0000, /* Power 2 */
+ 0x0000, /* Power 3 */
+ 0x0010, /* Interface Control */
+ 0x0000, /* Companding Control */
+ 0x0140, /* Clock Control */
+ 0x0000, /* Additional Controls */
+ 0x0000, /* GPIO Control */
+ 0x0002, /* Auto Increment Control */
+ 0x0000, /* DAC Control */
+ 0x00FF, /* DAC Volume */
+ 0,
+ 0,
+ 0x0100, /* ADC Control */
+ 0x00FF, /* ADC Volume */
+ 0x0000, /* Notch Filter 1 Control 1 */
+ 0x0000, /* Notch Filter 1 Control 2 */
+ 0x0000, /* Notch Filter 2 Control 1 */
+ 0x0000, /* Notch Filter 2 Control 2 */
+ 0x0000, /* Notch Filter 3 Control 1 */
+ 0x0000, /* Notch Filter 3 Control 2 */
+ 0x0000, /* Notch Filter 4 Control 1 */
+ 0x0000, /* Notch Filter 4 Control 2 */
+ 0x0032, /* DAC Limit Control 1 */
+ 0x0000, /* DAC Limit Control 2 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x0038, /* ALC Control 1 */
+ 0x000B, /* ALC Control 2 */
+ 0x0032, /* ALC Control 3 */
+ 0x0000, /* Noise Gate */
+ 0x0041, /* PLLN */
+ 0x000C, /* PLLK1 */
+ 0x0093, /* PLLK2 */
+ 0x00E9, /* PLLK3 */
+ 0,
+ 0,
+ 0x0030, /* ALC Control 4 */
+ 0,
+ 0x0002, /* Input Control */
+ 0x0050, /* PGA Gain */
+ 0,
+ 0x0002, /* ADC Boost Control */
+ 0,
+ 0x0002, /* Output Control */
+ 0x0000, /* Speaker Mixer Control */
+ 0,
+ 0,
+ 0,
+ 0x0079, /* Speaker Volume */
+ 0,
+ 0x0000, /* Mono Mixer Control */
+};
+
+static inline unsigned int wm8940_read_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ u16 *cache = codec->reg_cache;
+
+ if (reg >= ARRAY_SIZE(wm8940_reg_defaults))
+ return -1;
+
+ return cache[reg];
+}
+
+static inline int wm8940_write_reg_cache(struct snd_soc_codec *codec,
+ u16 reg, unsigned int value)
+{
+ u16 *cache = codec->reg_cache;
+
+ if (reg >= ARRAY_SIZE(wm8940_reg_defaults))
+ return -1;
+
+ cache[reg] = value;
+
+ return 0;
+}
+
+static int wm8940_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ int ret;
+ u8 data[3] = { reg,
+ (value & 0xff00) >> 8,
+ (value & 0x00ff)
+ };
+
+ wm8940_write_reg_cache(codec, reg, value);
+
+ ret = codec->hw_write(codec->control_data, data, 3);
+
+ if (ret < 0)
+ return ret;
+ else if (ret != 3)
+ return -EIO;
+ return 0;
+}
+
+static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" };
+static const struct soc_enum wm8940_adc_companding_enum
+= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding);
+static const struct soc_enum wm8940_dac_companding_enum
+= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 3, 4, wm8940_companding);
+
+static const char *wm8940_alc_mode_text[] = {"ALC", "Limiter"};
+static const struct soc_enum wm8940_alc_mode_enum
+= SOC_ENUM_SINGLE(WM8940_ALC3, 8, 2, wm8940_alc_mode_text);
+
+static const char *wm8940_mic_bias_level_text[] = {"0.9", "0.65"};
+static const struct soc_enum wm8940_mic_bias_level_enum
+= SOC_ENUM_SINGLE(WM8940_INPUTCTL, 8, 2, wm8940_mic_bias_level_text);
+
+static const char *wm8940_filter_mode_text[] = {"Audio", "Application"};
+static const struct soc_enum wm8940_filter_mode_enum
+= SOC_ENUM_SINGLE(WM8940_ADC, 7, 2, wm8940_filter_mode_text);
+
+static DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1);
+static DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_pga_vol_tlv, -1200, 75, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_alc_min_tlv, -1200, 600, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_alc_max_tlv, 675, 600, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_alc_tar_tlv, -2250, 50, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_lim_boost_tlv, 0, 100, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_lim_thresh_tlv, -600, 100, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_adc_tlv, -12750, 50, 1);
+static DECLARE_TLV_DB_SCALE(wm8940_capture_boost_vol_tlv, 0, 2000, 0);
+
+static const struct snd_kcontrol_new wm8940_snd_controls[] = {
+ SOC_SINGLE("Digital Loopback Switch", WM8940_COMPANDINGCTL,
+ 6, 1, 0),
+ SOC_ENUM("DAC Companding", wm8940_dac_companding_enum),
+ SOC_ENUM("ADC Companding", wm8940_adc_companding_enum),
+
+ SOC_ENUM("ALC Mode", wm8940_alc_mode_enum),
+ SOC_SINGLE("ALC Switch", WM8940_ALC1, 8, 1, 0),
+ SOC_SINGLE_TLV("ALC Capture Max Gain", WM8940_ALC1,
+ 3, 7, 1, wm8940_alc_max_tlv),
+ SOC_SINGLE_TLV("ALC Capture Min Gain", WM8940_ALC1,
+ 0, 7, 0, wm8940_alc_min_tlv),
+ SOC_SINGLE_TLV("ALC Capture Target", WM8940_ALC2,
+ 0, 14, 0, wm8940_alc_tar_tlv),
+ SOC_SINGLE("ALC Capture Hold", WM8940_ALC2, 4, 10, 0),
+ SOC_SINGLE("ALC Capture Decay", WM8940_ALC3, 4, 10, 0),
+ SOC_SINGLE("ALC Capture Attach", WM8940_ALC3, 0, 10, 0),
+ SOC_SINGLE("ALC ZC Switch", WM8940_ALC4, 1, 1, 0),
+ SOC_SINGLE("ALC Capture Noise Gate Switch", WM8940_NOISEGATE,
+ 3, 1, 0),
+ SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8940_NOISEGATE,
+ 0, 7, 0),
+
+ SOC_SINGLE("DAC Playback Limiter Switch", WM8940_DACLIM1, 8, 1, 0),
+ SOC_SINGLE("DAC Playback Limiter Attack", WM8940_DACLIM1, 0, 9, 0),
+ SOC_SINGLE("DAC Playback Limiter Decay", WM8940_DACLIM1, 4, 11, 0),
+ SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8940_DACLIM2,
+ 4, 9, 1, wm8940_lim_thresh_tlv),
+ SOC_SINGLE_TLV("DAC Playback Limiter Boost", WM8940_DACLIM2,
+ 0, 12, 0, wm8940_lim_boost_tlv),
+
+ SOC_SINGLE("Capture PGA ZC Switch", WM8940_PGAGAIN, 7, 1, 0),
+ SOC_SINGLE_TLV("Capture PGA Volume", WM8940_PGAGAIN,
+ 0, 63, 0, wm8940_pga_vol_tlv),
+ SOC_SINGLE_TLV("Digital Playback Volume", WM8940_DACVOL,
+ 0, 255, 0, wm8940_adc_tlv),
+ SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL,
+ 0, 255, 0, wm8940_adc_tlv),
+ SOC_ENUM("Mic Bias Level", wm8940_mic_bias_level_enum),
+ SOC_SINGLE_TLV("Capture Boost Volue", WM8940_ADCBOOST,
+ 8, 1, 0, wm8940_capture_boost_vol_tlv),
+ SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL,
+ 0, 63, 0, wm8940_spk_vol_tlv),
+ SOC_SINGLE("Speaker Playback Switch", WM8940_SPKVOL, 6, 1, 1),
+
+ SOC_SINGLE_TLV("Speaker Mixer Line Bypass Volume", WM8940_SPKVOL,
+ 8, 1, 1, wm8940_att_tlv),
+ SOC_SINGLE("Speaker Playback ZC Switch", WM8940_SPKVOL, 7, 1, 0),
+
+ SOC_SINGLE("Mono Out Switch", WM8940_MONOMIX, 6, 1, 1),
+ SOC_SINGLE_TLV("Mono Mixer Line Bypass Volume", WM8940_MONOMIX,
+ 7, 1, 1, wm8940_att_tlv),
+
+ SOC_SINGLE("High Pass Filter Switch", WM8940_ADC, 8, 1, 0),
+ SOC_ENUM("High Pass Filter Mode", wm8940_filter_mode_enum),
+ SOC_SINGLE("High Pass Filter Cut Off", WM8940_ADC, 4, 7, 0),
+ SOC_SINGLE("ADC Inversion Switch", WM8940_ADC, 0, 1, 0),
+ SOC_SINGLE("DAC Inversion Switch", WM8940_DAC, 0, 1, 0),
+ SOC_SINGLE("DAC Auto Mute Switch", WM8940_DAC, 2, 1, 0),
+ SOC_SINGLE("ZC Timeout Clock Switch", WM8940_ADDCNTRL, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8940_speaker_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_SPKMIX, 1, 1, 0),
+ SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_SPKMIX, 5, 1, 0),
+ SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_SPKMIX, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8940_mono_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_MONOMIX, 1, 1, 0),
+ SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_MONOMIX, 2, 1, 0),
+ SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_MONOMIX, 0, 1, 0),
+};
+
+static DECLARE_TLV_DB_SCALE(wm8940_boost_vol_tlv, -1500, 300, 1);
+static const struct snd_kcontrol_new wm8940_input_boost_controls[] = {
+ SOC_DAPM_SINGLE("Mic PGA Switch", WM8940_PGAGAIN, 6, 1, 1),
+ SOC_DAPM_SINGLE_TLV("Aux Volume", WM8940_ADCBOOST,
+ 0, 7, 0, wm8940_boost_vol_tlv),
+ SOC_DAPM_SINGLE_TLV("Mic Volume", WM8940_ADCBOOST,
+ 4, 7, 0, wm8940_boost_vol_tlv),
+};
+
+static const struct snd_kcontrol_new wm8940_micpga_controls[] = {
+ SOC_DAPM_SINGLE("AUX Switch", WM8940_INPUTCTL, 2, 1, 0),
+ SOC_DAPM_SINGLE("MICP Switch", WM8940_INPUTCTL, 0, 1, 0),
+ SOC_DAPM_SINGLE("MICN Switch", WM8940_INPUTCTL, 1, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget wm8940_dapm_widgets[] = {
+ SND_SOC_DAPM_MIXER("Speaker Mixer", WM8940_POWER3, 2, 0,
+ &wm8940_speaker_mixer_controls[0],
+ ARRAY_SIZE(wm8940_speaker_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Mono Mixer", WM8940_POWER3, 3, 0,
+ &wm8940_mono_mixer_controls[0],
+ ARRAY_SIZE(wm8940_mono_mixer_controls)),
+ SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8940_POWER3, 0, 0),
+
+ SND_SOC_DAPM_PGA("SpkN Out", WM8940_POWER3, 5, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("SpkP Out", WM8940_POWER3, 6, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Mono Out", WM8940_POWER3, 7, 0, NULL, 0),
+ SND_SOC_DAPM_OUTPUT("MONOOUT"),
+ SND_SOC_DAPM_OUTPUT("SPKOUTP"),
+ SND_SOC_DAPM_OUTPUT("SPKOUTN"),
+
+ SND_SOC_DAPM_PGA("Aux Input", WM8940_POWER1, 6, 0, NULL, 0),
+ SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8940_POWER2, 0, 0),
+ SND_SOC_DAPM_MIXER("Mic PGA", WM8940_POWER2, 2, 0,
+ &wm8940_micpga_controls[0],
+ ARRAY_SIZE(wm8940_micpga_controls)),
+ SND_SOC_DAPM_MIXER("Boost Mixer", WM8940_POWER2, 4, 0,
+ &wm8940_input_boost_controls[0],
+ ARRAY_SIZE(wm8940_input_boost_controls)),
+ SND_SOC_DAPM_MICBIAS("Mic Bias", WM8940_POWER1, 4, 0),
+
+ SND_SOC_DAPM_INPUT("MICN"),
+ SND_SOC_DAPM_INPUT("MICP"),
+ SND_SOC_DAPM_INPUT("AUX"),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ /* Mono output mixer */
+ {"Mono Mixer", "PCM Playback Switch", "DAC"},
+ {"Mono Mixer", "Aux Playback Switch", "Aux Input"},
+ {"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
+
+ /* Speaker output mixer */
+ {"Speaker Mixer", "PCM Playback Switch", "DAC"},
+ {"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
+ {"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
+
+ /* Outputs */
+ {"Mono Out", NULL, "Mono Mixer"},
+ {"MONOOUT", NULL, "Mono Out"},
+ {"SpkN Out", NULL, "Speaker Mixer"},
+ {"SpkP Out", NULL, "Speaker Mixer"},
+ {"SPKOUTN", NULL, "SpkN Out"},
+ {"SPKOUTP", NULL, "SpkP Out"},
+
+ /* Microphone PGA */
+ {"Mic PGA", "MICN Switch", "MICN"},
+ {"Mic PGA", "MICP Switch", "MICP"},
+ {"Mic PGA", "AUX Switch", "AUX"},
+
+ /* Boost Mixer */
+ {"Boost Mixer", "Mic PGA Switch", "Mic PGA"},
+ {"Boost Mixer", "Mic Volume", "MICP"},
+ {"Boost Mixer", "Aux Volume", "Aux Input"},
+
+ {"ADC", NULL, "Boost Mixer"},
+};
+
+static int wm8940_add_widgets(struct snd_soc_codec *codec)
+{
+ int ret;
+
+ ret = snd_soc_dapm_new_controls(codec, wm8940_dapm_widgets,
+ ARRAY_SIZE(wm8940_dapm_widgets));
+ if (ret)
+ goto error_ret;
+ ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ if (ret)
+ goto error_ret;
+ ret = snd_soc_dapm_new_widgets(codec);
+
+error_ret:
+ return ret;
+}
+
+#define wm8940_reset(c) wm8940_write(c, WM8940_SOFTRESET, 0);
+
+static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 iface = wm8940_read_reg_cache(codec, WM8940_IFACE) & 0xFE67;
+ u16 clk = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0x1fe;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ clk |= 1;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+ wm8940_write(codec, WM8940_CLOCK, clk);
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= (2 << 3);
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= (1 << 3);
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= (3 << 3);
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= (3 << 3) | (1 << 7);
+ break;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface |= (1 << 7);
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= (1 << 8);
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= (1 << 8) | (1 << 7);
+ break;
+ }
+
+ wm8940_write(codec, WM8940_IFACE, iface);
+
+ return 0;
+}
+
+static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->card->codec;
+ u16 iface = wm8940_read_reg_cache(codec, WM8940_IFACE) & 0xFD9F;
+ u16 addcntrl = wm8940_read_reg_cache(codec, WM8940_ADDCNTRL) & 0xFFF1;
+ u16 companding = wm8940_read_reg_cache(codec,
+ WM8940_COMPANDINGCTL) & 0xFFDF;
+ int ret;
+
+ /* LoutR control */
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE
+ && params_channels(params) == 2)
+ iface |= (1 << 9);
+
+ switch (params_rate(params)) {
+ case SNDRV_PCM_RATE_8000:
+ addcntrl |= (0x5 << 1);
+ break;
+ case SNDRV_PCM_RATE_11025:
+ addcntrl |= (0x4 << 1);
+ break;
+ case SNDRV_PCM_RATE_16000:
+ addcntrl |= (0x3 << 1);
+ break;
+ case SNDRV_PCM_RATE_22050:
+ addcntrl |= (0x2 << 1);
+ break;
+ case SNDRV_PCM_RATE_32000:
+ addcntrl |= (0x1 << 1);
+ break;
+ case SNDRV_PCM_RATE_44100:
+ case SNDRV_PCM_RATE_48000:
+ break;
+ }
+ ret = wm8940_write(codec, WM8940_ADDCNTRL, addcntrl);
+ if (ret)
+ goto error_ret;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S8:
+ companding = companding | (1 << 5);
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= (1 << 5);
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= (2 << 5);
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= (3 << 5);
+ break;
+ }
+ ret = wm8940_write(codec, WM8940_COMPANDINGCTL, companding);
+ if (ret)
+ goto error_ret;
+ ret = wm8940_write(codec, WM8940_IFACE, iface);
+
+error_ret:
+ return ret;
+}
+
+static int wm8940_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 mute_reg = wm8940_read_reg_cache(codec, WM8940_DAC) & 0xffbf;
+
+ if (mute)
+ mute_reg |= 0x40;
+
+ return wm8940_write(codec, WM8940_DAC, mute_reg);
+}
+
+static int wm8940_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ u16 val;
+ u16 pwr_reg = wm8940_read_reg_cache(codec, WM8940_POWER1) & 0x1F0;
+ int ret = 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ /* ensure bufioen and biasen */
+ pwr_reg |= (1 << 2) | (1 << 3);
+ /* Enable thermal shutdown */
+ val = wm8940_read_reg_cache(codec, WM8940_OUTPUTCTL);
+ ret = wm8940_write(codec, WM8940_OUTPUTCTL, val | 0x2);
+ if (ret)
+ break;
+ /* set vmid to 75k */
+ ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x1);
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ /* ensure bufioen and biasen */
+ pwr_reg |= (1 << 2) | (1 << 3);
+ ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x1);
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ /* ensure bufioen and biasen */
+ pwr_reg |= (1 << 2) | (1 << 3);
+ /* set vmid to 300k for standby */
+ ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x2);
+ break;
+ case SND_SOC_BIAS_OFF:
+ ret = wm8940_write(codec, WM8940_POWER1, pwr_reg);
+ break;
+ }
+
+ return ret;
+}
+
+struct pll_ {
+ unsigned int pre_scale:2;
+ unsigned int n:4;
+ unsigned int k;
+};
+
+static struct pll_ pll_div;
+
+/* The size in bits of the pll divide multiplied by 10
+ * to allow rounding later */
+#define FIXED_PLL_SIZE ((1 << 24) * 10)
+static void pll_factors(unsigned int target, unsigned int source)
+{
+ unsigned long long Kpart;
+ unsigned int K, Ndiv, Nmod;
+ /* The left shift ist to avoid accuracy loss when right shifting */
+ Ndiv = target / source;
+
+ if (Ndiv > 12) {
+ source <<= 1;
+ /* Multiply by 2 */
+ pll_div.pre_scale = 0;
+ Ndiv = target / source;
+ } else if (Ndiv < 3) {
+ source >>= 2;
+ /* Divide by 4 */
+ pll_div.pre_scale = 3;
+ Ndiv = target / source;
+ } else if (Ndiv < 6) {
+ source >>= 1;
+ /* divide by 2 */
+ pll_div.pre_scale = 2;
+ Ndiv = target / source;
+ } else
+ pll_div.pre_scale = 1;
+
+ if ((Ndiv < 6) || (Ndiv > 12))
+ printk(KERN_WARNING
+ "WM8940 N value %d outwith recommended range!d\n",
+ Ndiv);
+
+ pll_div.n = Ndiv;
+ Nmod = target % source;
+ Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+
+ do_div(Kpart, source);
+
+ K = Kpart & 0xFFFFFFFF;
+
+ /* Check if we need to round */
+ if ((K % 10) >= 5)
+ K += 5;
+
+ /* Move down to proper range now rounding is done */
+ K /= 10;
+
+ pll_div.k = K;
+}
+
+/* Untested at the moment */
+static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai,
+ int pll_id, unsigned int freq_in, unsigned int freq_out)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 reg;
+
+ /* Turn off PLL */
+ reg = wm8940_read_reg_cache(codec, WM8940_POWER1);
+ wm8940_write(codec, WM8940_POWER1, reg & 0x1df);
+
+ if (freq_in == 0 || freq_out == 0) {
+ /* Clock CODEC directly from MCLK */
+ reg = wm8940_read_reg_cache(codec, WM8940_CLOCK);
+ wm8940_write(codec, WM8940_CLOCK, reg & 0x0ff);
+ /* Pll power down */
+ wm8940_write(codec, WM8940_PLLN, (1 << 7));
+ return 0;
+ }
+
+ /* Pll is followed by a frequency divide by 4 */
+ pll_factors(freq_out*4, freq_in);
+ if (pll_div.k)
+ wm8940_write(codec, WM8940_PLLN,
+ (pll_div.pre_scale << 4) | pll_div.n | (1 << 6));
+ else /* No factional component */
+ wm8940_write(codec, WM8940_PLLN,
+ (pll_div.pre_scale << 4) | pll_div.n);
+ wm8940_write(codec, WM8940_PLLK1, pll_div.k >> 18);
+ wm8940_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff);
+ wm8940_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff);
+ /* Enable the PLL */
+ reg = wm8940_read_reg_cache(codec, WM8940_POWER1);
+ wm8940_write(codec, WM8940_POWER1, reg | 0x020);
+
+ /* Run CODEC from PLL instead of MCLK */
+ reg = wm8940_read_reg_cache(codec, WM8940_CLOCK);
+ wm8940_write(codec, WM8940_CLOCK, reg | 0x100);
+
+ return 0;
+}
+
+static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct wm8940_priv *wm8940 = codec->private_data;
+
+ switch (freq) {
+ case 11289600:
+ case 12000000:
+ case 12288000:
+ case 16934400:
+ case 18432000:
+ wm8940->sysclk = freq;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ int div_id, int div)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 reg;
+ int ret = 0;
+
+ switch (div_id) {
+ case WM8940_BCLKDIV:
+ reg = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0xFFEF3;
+ ret = wm8940_write(codec, WM8940_CLOCK, reg | (div << 2));
+ break;
+ case WM8940_MCLKDIV:
+ reg = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0xFF1F;
+ ret = wm8940_write(codec, WM8940_CLOCK, reg | (div << 5));
+ break;
+ case WM8940_OPCLKDIV:
+ reg = wm8940_read_reg_cache(codec, WM8940_ADDCNTRL) & 0xFFCF;
+ ret = wm8940_write(codec, WM8940_ADDCNTRL, reg | (div << 4));
+ break;
+ }
+ return ret;
+}
+
+#define WM8940_RATES SNDRV_PCM_RATE_8000_48000
+
+#define WM8940_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
+ SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops wm8940_dai_ops = {
+ .hw_params = wm8940_i2s_hw_params,
+ .set_sysclk = wm8940_set_dai_sysclk,
+ .digital_mute = wm8940_mute,
+ .set_fmt = wm8940_set_dai_fmt,
+ .set_clkdiv = wm8940_set_dai_clkdiv,
+ .set_pll = wm8940_set_dai_pll,
+};
+
+struct snd_soc_dai wm8940_dai = {
+ .name = "WM8940",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8940_RATES,
+ .formats = WM8940_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8940_RATES,
+ .formats = WM8940_FORMATS,
+ },
+ .ops = &wm8940_dai_ops,
+ .symmetric_rates = 1,
+};
+EXPORT_SYMBOL_GPL(wm8940_dai);
+
+static int wm8940_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+
+ return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
+}
+
+static int wm8940_resume(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+ int i;
+ int ret;
+ u8 data[3];
+ u16 *cache = codec->reg_cache;
+
+ /* Sync reg_cache with the hardware
+ * Could use auto incremented writes to speed this up
+ */
+ for (i = 0; i < ARRAY_SIZE(wm8940_reg_defaults); i++) {
+ data[0] = i;
+ data[1] = (cache[i] & 0xFF00) >> 8;
+ data[2] = cache[i] & 0x00FF;
+ ret = codec->hw_write(codec->control_data, data, 3);
+ if (ret < 0)
+ goto error_ret;
+ else if (ret != 3) {
+ ret = -EIO;
+ goto error_ret;
+ }
+ }
+ ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ if (ret)
+ goto error_ret;
+ ret = wm8940_set_bias_level(codec, codec->suspend_bias_level);
+
+error_ret:
+ return ret;
+}
+
+static struct snd_soc_codec *wm8940_codec;
+
+static int wm8940_probe(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec;
+
+ int ret = 0;
+
+ if (wm8940_codec == NULL) {
+ dev_err(&pdev->dev, "Codec device not registered\n");
+ return -ENODEV;
+ }
+
+ socdev->card->codec = wm8940_codec;
+ codec = wm8940_codec;
+
+ mutex_init(&codec->mutex);
+ /* register pcms */
+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to create pcms: %d\n", ret);
+ goto pcm_err;
+ }
+
+ ret = snd_soc_add_controls(codec, wm8940_snd_controls,
+ ARRAY_SIZE(wm8940_snd_controls));
+ if (ret)
+ goto error_free_pcms;
+ ret = wm8940_add_widgets(codec);
+ if (ret)
+ goto error_free_pcms;
+
+ ret = snd_soc_init_card(socdev);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to register card: %d\n", ret);
+ goto error_free_pcms;
+ }
+
+ return ret;
+
+error_free_pcms:
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+pcm_err:
+ return ret;
+}
+
+static int wm8940_remove(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+
+ return 0;
+}
+
+struct snd_soc_codec_device soc_codec_dev_wm8940 = {
+ .probe = wm8940_probe,
+ .remove = wm8940_remove,
+ .suspend = wm8940_suspend,
+ .resume = wm8940_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_wm8940);
+
+static int wm8940_register(struct wm8940_priv *wm8940)
+{
+ struct wm8940_setup_data *pdata = wm8940->codec.dev->platform_data;
+ struct snd_soc_codec *codec = &wm8940->codec;
+ int ret;
+ u16 reg;
+ if (wm8940_codec) {
+ dev_err(codec->dev, "Another WM8940 is registered\n");
+ return -EINVAL;
+ }
+
+ INIT_LIST_HEAD(&codec->dapm_widgets);
+ INIT_LIST_HEAD(&codec->dapm_paths);
+
+ codec->private_data = wm8940;
+ codec->name = "WM8940";
+ codec->owner = THIS_MODULE;
+ codec->read = wm8940_read_reg_cache;
+ codec->write = wm8940_write;
+ codec->bias_level = SND_SOC_BIAS_OFF;
+ codec->set_bias_level = wm8940_set_bias_level;
+ codec->dai = &wm8940_dai;
+ codec->num_dai = 1;
+ codec->reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults);
+ codec->reg_cache = &wm8940->reg_cache;
+
+ memcpy(codec->reg_cache, wm8940_reg_defaults,
+ sizeof(wm8940_reg_defaults));
+
+ ret = wm8940_reset(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset\n");
+ return ret;
+ }
+
+ wm8940_dai.dev = codec->dev;
+
+ wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ ret = wm8940_write(codec, WM8940_POWER1, 0x180);
+ if (ret < 0)
+ return ret;
+
+ if (!pdata)
+ dev_warn(codec->dev, "No platform data supplied\n");
+ else {
+ reg = wm8940_read_reg_cache(codec, WM8940_OUTPUTCTL);
+ ret = wm8940_write(codec, WM8940_OUTPUTCTL, reg | pdata->vroi);
+ if (ret < 0)
+ return ret;
+ }
+
+
+ wm8940_codec = codec;
+
+ ret = snd_soc_register_codec(codec);
+ if (ret) {
+ dev_err(codec->dev, "Failed to register codec: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_register_dai(&wm8940_dai);
+ if (ret) {
+ dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
+ snd_soc_unregister_codec(codec);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void wm8940_unregister(struct wm8940_priv *wm8940)
+{
+ wm8940_set_bias_level(&wm8940->codec, SND_SOC_BIAS_OFF);
+ snd_soc_unregister_dai(&wm8940_dai);
+ snd_soc_unregister_codec(&wm8940->codec);
+ kfree(wm8940);
+ wm8940_codec = NULL;
+}
+
+static int wm8940_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8940_priv *wm8940;
+ struct snd_soc_codec *codec;
+
+ wm8940 = kzalloc(sizeof *wm8940, GFP_KERNEL);
+ if (wm8940 == NULL)
+ return -ENOMEM;
+
+ codec = &wm8940->codec;
+ codec->hw_write = (hw_write_t)i2c_master_send;
+ i2c_set_clientdata(i2c, wm8940);
+ codec->control_data = i2c;
+ codec->dev = &i2c->dev;
+
+ return wm8940_register(wm8940);
+}
+
+static int wm8940_i2c_remove(struct i2c_client *client)
+{
+ struct wm8940_priv *wm8940 = i2c_get_clientdata(client);
+
+ wm8940_unregister(wm8940);
+
+ return 0;
+}
+
+static const struct i2c_device_id wm8940_i2c_id[] = {
+ { "wm8940", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id);
+
+static struct i2c_driver wm8940_i2c_driver = {
+ .driver = {
+ .name = "WM8940 I2C Codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8940_i2c_probe,
+ .remove = __devexit_p(wm8940_i2c_remove),
+ .id_table = wm8940_i2c_id,
+};
+
+static int __init wm8940_modinit(void)
+{
+ int ret;
+
+ ret = i2c_add_driver(&wm8940_i2c_driver);
+ if (ret)
+ printk(KERN_ERR "Failed to register WM8940 I2C driver: %d\n",
+ ret);
+ return ret;
+}
+module_init(wm8940_modinit);
+
+static void __exit wm8940_exit(void)
+{
+ i2c_del_driver(&wm8940_i2c_driver);
+}
+module_exit(wm8940_exit);
+
+MODULE_DESCRIPTION("ASoC WM8940 driver");
+MODULE_AUTHOR("Jonathan Cameron");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8940.h b/sound/soc/codecs/wm8940.h
new file mode 100644
index 000000000000..8410eed3ef84
--- /dev/null
+++ b/sound/soc/codecs/wm8940.h
@@ -0,0 +1,104 @@
+/*
+ * wm8940.h -- WM8940 Soc Audio driver
+ *
+ * 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 _WM8940_H
+#define _WM8940_H
+
+struct wm8940_setup_data {
+ /* Vref to analogue output resistance */
+#define WM8940_VROI_1K 0
+#define WM8940_VROI_30K 1
+ unsigned int vroi:1;
+};
+extern struct snd_soc_dai wm8940_dai;
+extern struct snd_soc_codec_device soc_codec_dev_wm8940;
+
+/* WM8940 register space */
+#define WM8940_SOFTRESET 0x00
+#define WM8940_POWER1 0x01
+#define WM8940_POWER2 0x02
+#define WM8940_POWER3 0x03
+#define WM8940_IFACE 0x04
+#define WM8940_COMPANDINGCTL 0x05
+#define WM8940_CLOCK 0x06
+#define WM8940_ADDCNTRL 0x07
+#define WM8940_GPIO 0x08
+#define WM8940_CTLINT 0x09
+#define WM8940_DAC 0x0A
+#define WM8940_DACVOL 0x0B
+
+#define WM8940_ADC 0x0E
+#define WM8940_ADCVOL 0x0F
+#define WM8940_NOTCH1 0x10
+#define WM8940_NOTCH2 0x11
+#define WM8940_NOTCH3 0x12
+#define WM8940_NOTCH4 0x13
+#define WM8940_NOTCH5 0x14
+#define WM8940_NOTCH6 0x15
+#define WM8940_NOTCH7 0x16
+#define WM8940_NOTCH8 0x17
+#define WM8940_DACLIM1 0x18
+#define WM8940_DACLIM2 0x19
+
+#define WM8940_ALC1 0x20
+#define WM8940_ALC2 0x21
+#define WM8940_ALC3 0x22
+#define WM8940_NOISEGATE 0x23
+#define WM8940_PLLN 0x24
+#define WM8940_PLLK1 0x25
+#define WM8940_PLLK2 0x26
+#define WM8940_PLLK3 0x27
+
+#define WM8940_ALC4 0x2A
+
+#define WM8940_INPUTCTL 0x2C
+#define WM8940_PGAGAIN 0x2D
+
+#define WM8940_ADCBOOST 0x2F
+
+#define WM8940_OUTPUTCTL 0x31
+#define WM8940_SPKMIX 0x32
+
+#define WM8940_SPKVOL 0x36
+
+#define WM8940_MONOMIX 0x38
+
+#define WM8940_CACHEREGNUM 0x57
+
+
+/* Clock divider Id's */
+#define WM8940_BCLKDIV 0
+#define WM8940_MCLKDIV 1
+#define WM8940_OPCLKDIV 2
+
+/* MCLK clock dividers */
+#define WM8940_MCLKDIV_1 0
+#define WM8940_MCLKDIV_1_5 1
+#define WM8940_MCLKDIV_2 2
+#define WM8940_MCLKDIV_3 3
+#define WM8940_MCLKDIV_4 4
+#define WM8940_MCLKDIV_6 5
+#define WM8940_MCLKDIV_8 6
+#define WM8940_MCLKDIV_12 7
+
+/* BCLK clock dividers */
+#define WM8940_BCLKDIV_1 0
+#define WM8940_BCLKDIV_2 1
+#define WM8940_BCLKDIV_4 2
+#define WM8940_BCLKDIV_8 3
+#define WM8940_BCLKDIV_16 4
+#define WM8940_BCLKDIV_32 5
+
+/* PLL Out Dividers */
+#define WM8940_OPCLKDIV_1 0
+#define WM8940_OPCLKDIV_2 1
+#define WM8940_OPCLKDIV_3 2
+#define WM8940_OPCLKDIV_4 3
+
+#endif /* _WM8940_H */
+
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
new file mode 100644
index 000000000000..e224d8add170
--- /dev/null
+++ b/sound/soc/codecs/wm8960.c
@@ -0,0 +1,969 @@
+/*
+ * wm8960.c -- WM8960 ALSA SoC Audio driver
+ *
+ * Author: Liam Girdwood
+ *
+ * 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/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8960.h"
+
+#define AUDIO_NAME "wm8960"
+
+struct snd_soc_codec_device soc_codec_dev_wm8960;
+
+/* R25 - Power 1 */
+#define WM8960_VREF 0x40
+
+/* R28 - Anti-pop 1 */
+#define WM8960_POBCTRL 0x80
+#define WM8960_BUFDCOPEN 0x10
+#define WM8960_BUFIOEN 0x08
+#define WM8960_SOFT_ST 0x04
+#define WM8960_HPSTBY 0x01
+
+/* R29 - Anti-pop 2 */
+#define WM8960_DISOP 0x40
+
+/*
+ * wm8960 register cache
+ * We can't read the WM8960 register space when we are
+ * using 2 wire for device control, so we cache them instead.
+ */
+static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
+ 0x0097, 0x0097, 0x0000, 0x0000,
+ 0x0000, 0x0008, 0x0000, 0x000a,
+ 0x01c0, 0x0000, 0x00ff, 0x00ff,
+ 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x007b, 0x0100, 0x0032,
+ 0x0000, 0x00c3, 0x00c3, 0x01c0,
+ 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0100, 0x0100, 0x0050, 0x0050,
+ 0x0050, 0x0050, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0040, 0x0000,
+ 0x0000, 0x0050, 0x0050, 0x0000,
+ 0x0002, 0x0037, 0x004d, 0x0080,
+ 0x0008, 0x0031, 0x0026, 0x00e9,
+};
+
+struct wm8960_priv {
+ u16 reg_cache[WM8960_CACHEREGNUM];
+ struct snd_soc_codec codec;
+};
+
+/*
+ * read wm8960 register cache
+ */
+static inline unsigned int wm8960_read_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ u16 *cache = codec->reg_cache;
+ if (reg == WM8960_RESET)
+ return 0;
+ if (reg >= WM8960_CACHEREGNUM)
+ return -1;
+ return cache[reg];
+}
+
+/*
+ * write wm8960 register cache
+ */
+static inline void wm8960_write_reg_cache(struct snd_soc_codec *codec,
+ u16 reg, unsigned int value)
+{
+ u16 *cache = codec->reg_cache;
+ if (reg >= WM8960_CACHEREGNUM)
+ return;
+ cache[reg] = value;
+}
+
+static inline unsigned int wm8960_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ return wm8960_read_reg_cache(codec, reg);
+}
+
+/*
+ * write to the WM8960 register space
+ */
+static int wm8960_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ u8 data[2];
+
+ /* data is
+ * D15..D9 WM8960 register offset
+ * D8...D0 register data
+ */
+ data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+ data[1] = value & 0x00ff;
+
+ wm8960_write_reg_cache(codec, reg, value);
+ if (codec->hw_write(codec->control_data, data, 2) == 2)
+ return 0;
+ else
+ return -EIO;
+}
+
+#define wm8960_reset(c) wm8960_write(c, WM8960_RESET, 0)
+
+/* enumerated controls */
+static const char *wm8960_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
+static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
+ "Right Inverted", "Stereo Inversion"};
+static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"};
+static const char *wm8960_3d_lower_cutoff[] = {"Low", "High"};
+static const char *wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"};
+static const char *wm8960_alcmode[] = {"ALC", "Limiter"};
+
+static const struct soc_enum wm8960_enum[] = {
+ SOC_ENUM_SINGLE(WM8960_DACCTL1, 1, 4, wm8960_deemph),
+ SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity),
+ SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity),
+ SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff),
+ SOC_ENUM_SINGLE(WM8960_3D, 5, 2, wm8960_3d_lower_cutoff),
+ SOC_ENUM_SINGLE(WM8960_ALC1, 7, 4, wm8960_alcfunc),
+ SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode),
+};
+
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0);
+static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
+static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
+static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
+
+static const struct snd_kcontrol_new wm8960_snd_controls[] = {
+SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL,
+ 0, 63, 0, adc_tlv),
+SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL,
+ 6, 1, 0),
+SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL,
+ 7, 1, 0),
+
+SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC,
+ 0, 255, 0, dac_tlv),
+
+SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8960_LOUT1, WM8960_ROUT1,
+ 0, 127, 0, out_tlv),
+SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8960_LOUT1, WM8960_ROUT1,
+ 7, 1, 0),
+
+SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8960_LOUT2, WM8960_ROUT2,
+ 0, 127, 0, out_tlv),
+SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8960_LOUT2, WM8960_ROUT2,
+ 7, 1, 0),
+SOC_SINGLE("Speaker DC Volume", WM8960_CLASSD3, 3, 5, 0),
+SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0),
+
+SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0),
+SOC_ENUM("ADC Polarity", wm8960_enum[1]),
+SOC_ENUM("Playback De-emphasis", wm8960_enum[0]),
+SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0),
+
+SOC_ENUM("DAC Polarity", wm8960_enum[2]),
+
+SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[3]),
+SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[4]),
+SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0),
+SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0),
+
+SOC_ENUM("ALC Function", wm8960_enum[5]),
+SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0),
+SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1),
+SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0),
+SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0),
+SOC_ENUM("ALC Mode", wm8960_enum[6]),
+SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0),
+SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0),
+
+SOC_SINGLE("Noise Gate Threshold", WM8960_NOISEG, 3, 31, 0),
+SOC_SINGLE("Noise Gate Switch", WM8960_NOISEG, 0, 1, 0),
+
+SOC_DOUBLE_R("ADC PCM Capture Volume", WM8960_LINPATH, WM8960_RINPATH,
+ 0, 127, 0),
+
+SOC_SINGLE_TLV("Left Output Mixer Boost Bypass Volume",
+ WM8960_BYPASS1, 4, 7, 1, bypass_tlv),
+SOC_SINGLE_TLV("Left Output Mixer LINPUT3 Volume",
+ WM8960_LOUTMIX, 4, 7, 1, bypass_tlv),
+SOC_SINGLE_TLV("Right Output Mixer Boost Bypass Volume",
+ WM8960_BYPASS2, 4, 7, 1, bypass_tlv),
+SOC_SINGLE_TLV("Right Output Mixer RINPUT3 Volume",
+ WM8960_ROUTMIX, 4, 7, 1, bypass_tlv),
+};
+
+static const struct snd_kcontrol_new wm8960_lin_boost[] = {
+SOC_DAPM_SINGLE("LINPUT2 Switch", WM8960_LINPATH, 6, 1, 0),
+SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LINPATH, 7, 1, 0),
+SOC_DAPM_SINGLE("LINPUT1 Switch", WM8960_LINPATH, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_lin[] = {
+SOC_DAPM_SINGLE("Boost Switch", WM8960_LINPATH, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_rin_boost[] = {
+SOC_DAPM_SINGLE("RINPUT2 Switch", WM8960_RINPATH, 6, 1, 0),
+SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_RINPATH, 7, 1, 0),
+SOC_DAPM_SINGLE("RINPUT1 Switch", WM8960_RINPATH, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_rin[] = {
+SOC_DAPM_SINGLE("Boost Switch", WM8960_RINPATH, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_loutput_mixer[] = {
+SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_LOUTMIX, 8, 1, 0),
+SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LOUTMIX, 7, 1, 0),
+SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS1, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_routput_mixer[] = {
+SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_ROUTMIX, 8, 1, 0),
+SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_ROUTMIX, 7, 1, 0),
+SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS2, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_mono_out[] = {
+SOC_DAPM_SINGLE("Left Switch", WM8960_MONOMIX1, 7, 1, 0),
+SOC_DAPM_SINGLE("Right Switch", WM8960_MONOMIX2, 7, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget wm8960_dapm_widgets[] = {
+SND_SOC_DAPM_INPUT("LINPUT1"),
+SND_SOC_DAPM_INPUT("RINPUT1"),
+SND_SOC_DAPM_INPUT("LINPUT2"),
+SND_SOC_DAPM_INPUT("RINPUT2"),
+SND_SOC_DAPM_INPUT("LINPUT3"),
+SND_SOC_DAPM_INPUT("RINPUT3"),
+
+SND_SOC_DAPM_MICBIAS("MICB", WM8960_POWER1, 1, 0),
+
+SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8960_POWER1, 5, 0,
+ wm8960_lin_boost, ARRAY_SIZE(wm8960_lin_boost)),
+SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8960_POWER1, 4, 0,
+ wm8960_rin_boost, ARRAY_SIZE(wm8960_rin_boost)),
+
+SND_SOC_DAPM_MIXER("Left Input Mixer", WM8960_POWER3, 5, 0,
+ wm8960_lin, ARRAY_SIZE(wm8960_lin)),
+SND_SOC_DAPM_MIXER("Right Input Mixer", WM8960_POWER3, 4, 0,
+ wm8960_rin, ARRAY_SIZE(wm8960_rin)),
+
+SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER2, 3, 0),
+SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER2, 2, 0),
+
+SND_SOC_DAPM_DAC("Left DAC", "Playback", WM8960_POWER2, 8, 0),
+SND_SOC_DAPM_DAC("Right DAC", "Playback", WM8960_POWER2, 7, 0),
+
+SND_SOC_DAPM_MIXER("Left Output Mixer", WM8960_POWER3, 3, 0,
+ &wm8960_loutput_mixer[0],
+ ARRAY_SIZE(wm8960_loutput_mixer)),
+SND_SOC_DAPM_MIXER("Right Output Mixer", WM8960_POWER3, 2, 0,
+ &wm8960_routput_mixer[0],
+ ARRAY_SIZE(wm8960_routput_mixer)),
+
+SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0,
+ &wm8960_mono_out[0],
+ ARRAY_SIZE(wm8960_mono_out)),
+
+SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("Left Speaker PGA", WM8960_POWER2, 4, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Speaker PGA", WM8960_POWER2, 3, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("Right Speaker Output", WM8960_CLASSD1, 7, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left Speaker Output", WM8960_CLASSD1, 6, 0, NULL, 0),
+
+SND_SOC_DAPM_OUTPUT("SPK_LP"),
+SND_SOC_DAPM_OUTPUT("SPK_LN"),
+SND_SOC_DAPM_OUTPUT("HP_L"),
+SND_SOC_DAPM_OUTPUT("HP_R"),
+SND_SOC_DAPM_OUTPUT("SPK_RP"),
+SND_SOC_DAPM_OUTPUT("SPK_RN"),
+SND_SOC_DAPM_OUTPUT("OUT3"),
+};
+
+static const struct snd_soc_dapm_route audio_paths[] = {
+ { "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" },
+ { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" },
+ { "Left Boost Mixer", "LINPUT3 Switch", "LINPUT3" },
+
+ { "Left Input Mixer", "Boost Switch", "Left Boost Mixer", },
+ { "Left Input Mixer", NULL, "LINPUT1", }, /* Really Boost Switch */
+ { "Left Input Mixer", NULL, "LINPUT2" },
+ { "Left Input Mixer", NULL, "LINPUT3" },
+
+ { "Right Boost Mixer", "RINPUT1 Switch", "RINPUT1" },
+ { "Right Boost Mixer", "RINPUT2 Switch", "RINPUT2" },
+ { "Right Boost Mixer", "RINPUT3 Switch", "RINPUT3" },
+
+ { "Right Input Mixer", "Boost Switch", "Right Boost Mixer", },
+ { "Right Input Mixer", NULL, "RINPUT1", }, /* Really Boost Switch */
+ { "Right Input Mixer", NULL, "RINPUT2" },
+ { "Right Input Mixer", NULL, "LINPUT3" },
+
+ { "Left ADC", NULL, "Left Input Mixer" },
+ { "Right ADC", NULL, "Right Input Mixer" },
+
+ { "Left Output Mixer", "LINPUT3 Switch", "LINPUT3" },
+ { "Left Output Mixer", "Boost Bypass Switch", "Left Boost Mixer"} ,
+ { "Left Output Mixer", "PCM Playback Switch", "Left DAC" },
+
+ { "Right Output Mixer", "RINPUT3 Switch", "RINPUT3" },
+ { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } ,
+ { "Right Output Mixer", "PCM Playback Switch", "Right DAC" },
+
+ { "Mono Output Mixer", "Left Switch", "Left Output Mixer" },
+ { "Mono Output Mixer", "Right Switch", "Right Output Mixer" },
+
+ { "LOUT1 PGA", NULL, "Left Output Mixer" },
+ { "ROUT1 PGA", NULL, "Right Output Mixer" },
+
+ { "HP_L", NULL, "LOUT1 PGA" },
+ { "HP_R", NULL, "ROUT1 PGA" },
+
+ { "Left Speaker PGA", NULL, "Left Output Mixer" },
+ { "Right Speaker PGA", NULL, "Right Output Mixer" },
+
+ { "Left Speaker Output", NULL, "Left Speaker PGA" },
+ { "Right Speaker Output", NULL, "Right Speaker PGA" },
+
+ { "SPK_LN", NULL, "Left Speaker Output" },
+ { "SPK_LP", NULL, "Left Speaker Output" },
+ { "SPK_RN", NULL, "Right Speaker Output" },
+ { "SPK_RP", NULL, "Right Speaker Output" },
+
+ { "OUT3", NULL, "Mono Output Mixer", }
+};
+
+static int wm8960_add_widgets(struct snd_soc_codec *codec)
+{
+ snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets,
+ ARRAY_SIZE(wm8960_dapm_widgets));
+
+ snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+
+ snd_soc_dapm_new_widgets(codec);
+ return 0;
+}
+
+static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 iface = 0;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ iface |= 0x0040;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= 0x0002;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= 0x0001;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= 0x0003;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= 0x0013;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= 0x0090;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= 0x0080;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface |= 0x0010;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set iface */
+ wm8960_write(codec, WM8960_IFACE1, iface);
+ return 0;
+}
+
+static int wm8960_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->card->codec;
+ u16 iface = wm8960_read(codec, WM8960_IFACE1) & 0xfff3;
+
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x0004;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= 0x0008;
+ break;
+ }
+
+ /* set iface */
+ wm8960_write(codec, WM8960_IFACE1, iface);
+ return 0;
+}
+
+static int wm8960_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 mute_reg = wm8960_read(codec, WM8960_DACCTL1) & 0xfff7;
+
+ if (mute)
+ wm8960_write(codec, WM8960_DACCTL1, mute_reg | 0x8);
+ else
+ wm8960_write(codec, WM8960_DACCTL1, mute_reg);
+ return 0;
+}
+
+static int wm8960_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct wm8960_data *pdata = codec->dev->platform_data;
+ u16 reg;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ /* Set VMID to 2x50k */
+ reg = wm8960_read(codec, WM8960_POWER1);
+ reg &= ~0x180;
+ reg |= 0x80;
+ wm8960_write(codec, WM8960_POWER1, reg);
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ /* Enable anti-pop features */
+ wm8960_write(codec, WM8960_APOP1,
+ WM8960_POBCTRL | WM8960_SOFT_ST |
+ WM8960_BUFDCOPEN | WM8960_BUFIOEN);
+
+ /* Discharge HP output */
+ reg = WM8960_DISOP;
+ if (pdata)
+ reg |= pdata->dres << 4;
+ wm8960_write(codec, WM8960_APOP2, reg);
+
+ msleep(400);
+
+ wm8960_write(codec, WM8960_APOP2, 0);
+
+ /* Enable & ramp VMID at 2x50k */
+ reg = wm8960_read(codec, WM8960_POWER1);
+ reg |= 0x80;
+ wm8960_write(codec, WM8960_POWER1, reg);
+ msleep(100);
+
+ /* Enable VREF */
+ wm8960_write(codec, WM8960_POWER1, reg | WM8960_VREF);
+
+ /* Disable anti-pop features */
+ wm8960_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
+ }
+
+ /* Set VMID to 2x250k */
+ reg = wm8960_read(codec, WM8960_POWER1);
+ reg &= ~0x180;
+ reg |= 0x100;
+ wm8960_write(codec, WM8960_POWER1, reg);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ /* Enable anti-pop features */
+ wm8960_write(codec, WM8960_APOP1,
+ WM8960_POBCTRL | WM8960_SOFT_ST |
+ WM8960_BUFDCOPEN | WM8960_BUFIOEN);
+
+ /* Disable VMID and VREF, let them discharge */
+ wm8960_write(codec, WM8960_POWER1, 0);
+ msleep(600);
+
+ wm8960_write(codec, WM8960_APOP1, 0);
+ break;
+ }
+
+ codec->bias_level = level;
+
+ return 0;
+}
+
+/* PLL divisors */
+struct _pll_div {
+ u32 pre_div:1;
+ u32 n:4;
+ u32 k:24;
+};
+
+/* The size in bits of the pll divide multiplied by 10
+ * to allow rounding later */
+#define FIXED_PLL_SIZE ((1 << 24) * 10)
+
+static int pll_factors(unsigned int source, unsigned int target,
+ struct _pll_div *pll_div)
+{
+ unsigned long long Kpart;
+ unsigned int K, Ndiv, Nmod;
+
+ pr_debug("WM8960 PLL: setting %dHz->%dHz\n", source, target);
+
+ /* Scale up target to PLL operating frequency */
+ target *= 4;
+
+ Ndiv = target / source;
+ if (Ndiv < 6) {
+ source >>= 1;
+ pll_div->pre_div = 1;
+ Ndiv = target / source;
+ } else
+ pll_div->pre_div = 0;
+
+ if ((Ndiv < 6) || (Ndiv > 12)) {
+ pr_err("WM8960 PLL: Unsupported N=%d\n", Ndiv);
+ return -EINVAL;
+ }
+
+ pll_div->n = Ndiv;
+ Nmod = target % source;
+ Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+
+ do_div(Kpart, source);
+
+ K = Kpart & 0xFFFFFFFF;
+
+ /* Check if we need to round */
+ if ((K % 10) >= 5)
+ K += 5;
+
+ /* Move down to proper range now rounding is done */
+ K /= 10;
+
+ pll_div->k = K;
+
+ pr_debug("WM8960 PLL: N=%x K=%x pre_div=%d\n",
+ pll_div->n, pll_div->k, pll_div->pre_div);
+
+ return 0;
+}
+
+static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai,
+ int pll_id, unsigned int freq_in, unsigned int freq_out)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 reg;
+ static struct _pll_div pll_div;
+ int ret;
+
+ if (freq_in && freq_out) {
+ ret = pll_factors(freq_in, freq_out, &pll_div);
+ if (ret != 0)
+ return ret;
+ }
+
+ /* Disable the PLL: even if we are changing the frequency the
+ * PLL needs to be disabled while we do so. */
+ wm8960_write(codec, WM8960_CLOCK1,
+ wm8960_read(codec, WM8960_CLOCK1) & ~1);
+ wm8960_write(codec, WM8960_POWER2,
+ wm8960_read(codec, WM8960_POWER2) & ~1);
+
+ if (!freq_in || !freq_out)
+ return 0;
+
+ reg = wm8960_read(codec, WM8960_PLL1) & ~0x3f;
+ reg |= pll_div.pre_div << 4;
+ reg |= pll_div.n;
+
+ if (pll_div.k) {
+ reg |= 0x20;
+
+ wm8960_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f);
+ wm8960_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff);
+ wm8960_write(codec, WM8960_PLL4, pll_div.k & 0x1ff);
+ }
+ wm8960_write(codec, WM8960_PLL1, reg);
+
+ /* Turn it on */
+ wm8960_write(codec, WM8960_POWER2,
+ wm8960_read(codec, WM8960_POWER2) | 1);
+ msleep(250);
+ wm8960_write(codec, WM8960_CLOCK1,
+ wm8960_read(codec, WM8960_CLOCK1) | 1);
+
+ return 0;
+}
+
+static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ int div_id, int div)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 reg;
+
+ switch (div_id) {
+ case WM8960_SYSCLKSEL:
+ reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1fe;
+ wm8960_write(codec, WM8960_CLOCK1, reg | div);
+ break;
+ case WM8960_SYSCLKDIV:
+ reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1f9;
+ wm8960_write(codec, WM8960_CLOCK1, reg | div);
+ break;
+ case WM8960_DACDIV:
+ reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1c7;
+ wm8960_write(codec, WM8960_CLOCK1, reg | div);
+ break;
+ case WM8960_OPCLKDIV:
+ reg = wm8960_read(codec, WM8960_PLL1) & 0x03f;
+ wm8960_write(codec, WM8960_PLL1, reg | div);
+ break;
+ case WM8960_DCLKDIV:
+ reg = wm8960_read(codec, WM8960_CLOCK2) & 0x03f;
+ wm8960_write(codec, WM8960_CLOCK2, reg | div);
+ break;
+ case WM8960_TOCLKSEL:
+ reg = wm8960_read(codec, WM8960_ADDCTL1) & 0x1fd;
+ wm8960_write(codec, WM8960_ADDCTL1, reg | div);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+#define WM8960_RATES SNDRV_PCM_RATE_8000_48000
+
+#define WM8960_FORMATS \
+ (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static struct snd_soc_dai_ops wm8960_dai_ops = {
+ .hw_params = wm8960_hw_params,
+ .digital_mute = wm8960_mute,
+ .set_fmt = wm8960_set_dai_fmt,
+ .set_clkdiv = wm8960_set_dai_clkdiv,
+ .set_pll = wm8960_set_dai_pll,
+};
+
+struct snd_soc_dai wm8960_dai = {
+ .name = "WM8960",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8960_RATES,
+ .formats = WM8960_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8960_RATES,
+ .formats = WM8960_FORMATS,},
+ .ops = &wm8960_dai_ops,
+ .symmetric_rates = 1,
+};
+EXPORT_SYMBOL_GPL(wm8960_dai);
+
+static int wm8960_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+
+ wm8960_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int wm8960_resume(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+ int i;
+ u8 data[2];
+ u16 *cache = codec->reg_cache;
+
+ /* Sync reg_cache with the hardware */
+ for (i = 0; i < ARRAY_SIZE(wm8960_reg); i++) {
+ data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
+ data[1] = cache[i] & 0x00ff;
+ codec->hw_write(codec->control_data, data, 2);
+ }
+
+ wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ wm8960_set_bias_level(codec, codec->suspend_bias_level);
+ return 0;
+}
+
+static struct snd_soc_codec *wm8960_codec;
+
+static int wm8960_probe(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec;
+ int ret = 0;
+
+ if (wm8960_codec == NULL) {
+ dev_err(&pdev->dev, "Codec device not registered\n");
+ return -ENODEV;
+ }
+
+ socdev->card->codec = wm8960_codec;
+ codec = wm8960_codec;
+
+ /* register pcms */
+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to create pcms: %d\n", ret);
+ goto pcm_err;
+ }
+
+ snd_soc_add_controls(codec, wm8960_snd_controls,
+ ARRAY_SIZE(wm8960_snd_controls));
+ wm8960_add_widgets(codec);
+ ret = snd_soc_init_card(socdev);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to register card: %d\n", ret);
+ goto card_err;
+ }
+
+ return ret;
+
+card_err:
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+pcm_err:
+ return ret;
+}
+
+/* power down chip */
+static int wm8960_remove(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+
+ return 0;
+}
+
+struct snd_soc_codec_device soc_codec_dev_wm8960 = {
+ .probe = wm8960_probe,
+ .remove = wm8960_remove,
+ .suspend = wm8960_suspend,
+ .resume = wm8960_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960);
+
+static int wm8960_register(struct wm8960_priv *wm8960)
+{
+ struct wm8960_data *pdata = wm8960->codec.dev->platform_data;
+ struct snd_soc_codec *codec = &wm8960->codec;
+ int ret;
+ u16 reg;
+
+ if (wm8960_codec) {
+ dev_err(codec->dev, "Another WM8960 is registered\n");
+ return -EINVAL;
+ }
+
+ if (!pdata) {
+ dev_warn(codec->dev, "No platform data supplied\n");
+ } else {
+ if (pdata->dres > WM8960_DRES_MAX) {
+ dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres);
+ pdata->dres = 0;
+ }
+ }
+
+ mutex_init(&codec->mutex);
+ INIT_LIST_HEAD(&codec->dapm_widgets);
+ INIT_LIST_HEAD(&codec->dapm_paths);
+
+ codec->private_data = wm8960;
+ codec->name = "WM8960";
+ codec->owner = THIS_MODULE;
+ codec->read = wm8960_read_reg_cache;
+ codec->write = wm8960_write;
+ codec->bias_level = SND_SOC_BIAS_OFF;
+ codec->set_bias_level = wm8960_set_bias_level;
+ codec->dai = &wm8960_dai;
+ codec->num_dai = 1;
+ codec->reg_cache_size = WM8960_CACHEREGNUM;
+ codec->reg_cache = &wm8960->reg_cache;
+
+ memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg));
+
+ ret = wm8960_reset(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset\n");
+ return ret;
+ }
+
+ wm8960_dai.dev = codec->dev;
+
+ wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* Latch the update bits */
+ reg = wm8960_read(codec, WM8960_LINVOL);
+ wm8960_write(codec, WM8960_LINVOL, reg | 0x100);
+ reg = wm8960_read(codec, WM8960_RINVOL);
+ wm8960_write(codec, WM8960_RINVOL, reg | 0x100);
+ reg = wm8960_read(codec, WM8960_LADC);
+ wm8960_write(codec, WM8960_LADC, reg | 0x100);
+ reg = wm8960_read(codec, WM8960_RADC);
+ wm8960_write(codec, WM8960_RADC, reg | 0x100);
+ reg = wm8960_read(codec, WM8960_LDAC);
+ wm8960_write(codec, WM8960_LDAC, reg | 0x100);
+ reg = wm8960_read(codec, WM8960_RDAC);
+ wm8960_write(codec, WM8960_RDAC, reg | 0x100);
+ reg = wm8960_read(codec, WM8960_LOUT1);
+ wm8960_write(codec, WM8960_LOUT1, reg | 0x100);
+ reg = wm8960_read(codec, WM8960_ROUT1);
+ wm8960_write(codec, WM8960_ROUT1, reg | 0x100);
+ reg = wm8960_read(codec, WM8960_LOUT2);
+ wm8960_write(codec, WM8960_LOUT2, reg | 0x100);
+ reg = wm8960_read(codec, WM8960_ROUT2);
+ wm8960_write(codec, WM8960_ROUT2, reg | 0x100);
+
+ wm8960_codec = codec;
+
+ ret = snd_soc_register_codec(codec);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to register codec: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_register_dai(&wm8960_dai);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
+ snd_soc_unregister_codec(codec);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void wm8960_unregister(struct wm8960_priv *wm8960)
+{
+ wm8960_set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF);
+ snd_soc_unregister_dai(&wm8960_dai);
+ snd_soc_unregister_codec(&wm8960->codec);
+ kfree(wm8960);
+ wm8960_codec = NULL;
+}
+
+static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8960_priv *wm8960;
+ struct snd_soc_codec *codec;
+
+ wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL);
+ if (wm8960 == NULL)
+ return -ENOMEM;
+
+ codec = &wm8960->codec;
+ codec->hw_write = (hw_write_t)i2c_master_send;
+
+ i2c_set_clientdata(i2c, wm8960);
+ codec->control_data = i2c;
+
+ codec->dev = &i2c->dev;
+
+ return wm8960_register(wm8960);
+}
+
+static __devexit int wm8960_i2c_remove(struct i2c_client *client)
+{
+ struct wm8960_priv *wm8960 = i2c_get_clientdata(client);
+ wm8960_unregister(wm8960);
+ return 0;
+}
+
+static const struct i2c_device_id wm8960_i2c_id[] = {
+ { "wm8960", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);
+
+static struct i2c_driver wm8960_i2c_driver = {
+ .driver = {
+ .name = "WM8960 I2C Codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8960_i2c_probe,
+ .remove = __devexit_p(wm8960_i2c_remove),
+ .id_table = wm8960_i2c_id,
+};
+
+static int __init wm8960_modinit(void)
+{
+ int ret;
+
+ ret = i2c_add_driver(&wm8960_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
+ ret);
+ }
+
+ return ret;
+}
+module_init(wm8960_modinit);
+
+static void __exit wm8960_exit(void)
+{
+ i2c_del_driver(&wm8960_i2c_driver);
+}
+module_exit(wm8960_exit);
+
+
+MODULE_DESCRIPTION("ASoC WM8960 driver");
+MODULE_AUTHOR("Liam Girdwood");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8960.h b/sound/soc/codecs/wm8960.h
new file mode 100644
index 000000000000..c9af56c9d9d4
--- /dev/null
+++ b/sound/soc/codecs/wm8960.h
@@ -0,0 +1,127 @@
+/*
+ * wm8960.h -- WM8960 Soc Audio driver
+ *
+ * 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 _WM8960_H
+#define _WM8960_H
+
+/* WM8960 register space */
+
+
+#define WM8960_CACHEREGNUM 56
+
+#define WM8960_LINVOL 0x0
+#define WM8960_RINVOL 0x1
+#define WM8960_LOUT1 0x2
+#define WM8960_ROUT1 0x3
+#define WM8960_CLOCK1 0x4
+#define WM8960_DACCTL1 0x5
+#define WM8960_DACCTL2 0x6
+#define WM8960_IFACE1 0x7
+#define WM8960_CLOCK2 0x8
+#define WM8960_IFACE2 0x9
+#define WM8960_LDAC 0xa
+#define WM8960_RDAC 0xb
+
+#define WM8960_RESET 0xf
+#define WM8960_3D 0x10
+#define WM8960_ALC1 0x11
+#define WM8960_ALC2 0x12
+#define WM8960_ALC3 0x13
+#define WM8960_NOISEG 0x14
+#define WM8960_LADC 0x15
+#define WM8960_RADC 0x16
+#define WM8960_ADDCTL1 0x17
+#define WM8960_ADDCTL2 0x18
+#define WM8960_POWER1 0x19
+#define WM8960_POWER2 0x1a
+#define WM8960_ADDCTL3 0x1b
+#define WM8960_APOP1 0x1c
+#define WM8960_APOP2 0x1d
+
+#define WM8960_LINPATH 0x20
+#define WM8960_RINPATH 0x21
+#define WM8960_LOUTMIX 0x22
+
+#define WM8960_ROUTMIX 0x25
+#define WM8960_MONOMIX1 0x26
+#define WM8960_MONOMIX2 0x27
+#define WM8960_LOUT2 0x28
+#define WM8960_ROUT2 0x29
+#define WM8960_MONO 0x2a
+#define WM8960_INBMIX1 0x2b
+#define WM8960_INBMIX2 0x2c
+#define WM8960_BYPASS1 0x2d
+#define WM8960_BYPASS2 0x2e
+#define WM8960_POWER3 0x2f
+#define WM8960_ADDCTL4 0x30
+#define WM8960_CLASSD1 0x31
+
+#define WM8960_CLASSD3 0x33
+#define WM8960_PLL1 0x34
+#define WM8960_PLL2 0x35
+#define WM8960_PLL3 0x36
+#define WM8960_PLL4 0x37
+
+
+/*
+ * WM8960 Clock dividers
+ */
+#define WM8960_SYSCLKDIV 0
+#define WM8960_DACDIV 1
+#define WM8960_OPCLKDIV 2
+#define WM8960_DCLKDIV 3
+#define WM8960_TOCLKSEL 4
+#define WM8960_SYSCLKSEL 5
+
+#define WM8960_SYSCLK_DIV_1 (0 << 1)
+#define WM8960_SYSCLK_DIV_2 (2 << 1)
+
+#define WM8960_SYSCLK_MCLK (0 << 0)
+#define WM8960_SYSCLK_PLL (1 << 0)
+
+#define WM8960_DAC_DIV_1 (0 << 3)
+#define WM8960_DAC_DIV_1_5 (1 << 3)
+#define WM8960_DAC_DIV_2 (2 << 3)
+#define WM8960_DAC_DIV_3 (3 << 3)
+#define WM8960_DAC_DIV_4 (4 << 3)
+#define WM8960_DAC_DIV_5_5 (5 << 3)
+#define WM8960_DAC_DIV_6 (6 << 3)
+
+#define WM8960_DCLK_DIV_1_5 (0 << 6)
+#define WM8960_DCLK_DIV_2 (1 << 6)
+#define WM8960_DCLK_DIV_3 (2 << 6)
+#define WM8960_DCLK_DIV_4 (3 << 6)
+#define WM8960_DCLK_DIV_6 (4 << 6)
+#define WM8960_DCLK_DIV_8 (5 << 6)
+#define WM8960_DCLK_DIV_12 (6 << 6)
+#define WM8960_DCLK_DIV_16 (7 << 6)
+
+#define WM8960_TOCLK_F19 (0 << 1)
+#define WM8960_TOCLK_F21 (1 << 1)
+
+#define WM8960_OPCLK_DIV_1 (0 << 0)
+#define WM8960_OPCLK_DIV_2 (1 << 0)
+#define WM8960_OPCLK_DIV_3 (2 << 0)
+#define WM8960_OPCLK_DIV_4 (3 << 0)
+#define WM8960_OPCLK_DIV_5_5 (4 << 0)
+#define WM8960_OPCLK_DIV_6 (5 << 0)
+
+extern struct snd_soc_dai wm8960_dai;
+extern struct snd_soc_codec_device soc_codec_dev_wm8960;
+
+#define WM8960_DRES_400R 0
+#define WM8960_DRES_200R 1
+#define WM8960_DRES_600R 2
+#define WM8960_DRES_150R 3
+#define WM8960_DRES_MAX 3
+
+struct wm8960_data {
+ int dres;
+};
+
+#endif
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
new file mode 100644
index 000000000000..c05f71803aa8
--- /dev/null
+++ b/sound/soc/codecs/wm8988.c
@@ -0,0 +1,1097 @@
+/*
+ * wm8988.c -- WM8988 ALSA SoC audio driver
+ *
+ * Copyright 2009 Wolfson Microelectronics plc
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/tlv.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+
+#include "wm8988.h"
+
+/*
+ * wm8988 register cache
+ * We can't read the WM8988 register space when we
+ * are using 2 wire for device control, so we cache them instead.
+ */
+static const u16 wm8988_reg[] = {
+ 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */
+ 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */
+ 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */
+ 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */
+ 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */
+ 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */
+ 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */
+ 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */
+ 0x0079, 0x0079, 0x0079, /* 40 */
+};
+
+/* codec private data */
+struct wm8988_priv {
+ unsigned int sysclk;
+ struct snd_soc_codec codec;
+ struct snd_pcm_hw_constraint_list *sysclk_constraints;
+ u16 reg_cache[WM8988_NUM_REG];
+};
+
+
+/*
+ * read wm8988 register cache
+ */
+static inline unsigned int wm8988_read_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ u16 *cache = codec->reg_cache;
+ if (reg > WM8988_NUM_REG)
+ return -1;
+ return cache[reg];
+}
+
+/*
+ * write wm8988 register cache
+ */
+static inline void wm8988_write_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ u16 *cache = codec->reg_cache;
+ if (reg > WM8988_NUM_REG)
+ return;
+ cache[reg] = value;
+}
+
+static int wm8988_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ u8 data[2];
+
+ /* data is
+ * D15..D9 WM8753 register offset
+ * D8...D0 register data
+ */
+ data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+ data[1] = value & 0x00ff;
+
+ wm8988_write_reg_cache(codec, reg, value);
+ if (codec->hw_write(codec->control_data, data, 2) == 2)
+ return 0;
+ else
+ return -EIO;
+}
+
+#define wm8988_reset(c) wm8988_write(c, WM8988_RESET, 0)
+
+/*
+ * WM8988 Controls
+ */
+
+static const char *bass_boost_txt[] = {"Linear Control", "Adaptive Boost"};
+static const struct soc_enum bass_boost =
+ SOC_ENUM_SINGLE(WM8988_BASS, 7, 2, bass_boost_txt);
+
+static const char *bass_filter_txt[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" };
+static const struct soc_enum bass_filter =
+ SOC_ENUM_SINGLE(WM8988_BASS, 6, 2, bass_filter_txt);
+
+static const char *treble_txt[] = {"8kHz", "4kHz"};
+static const struct soc_enum treble =
+ SOC_ENUM_SINGLE(WM8988_TREBLE, 6, 2, treble_txt);
+
+static const char *stereo_3d_lc_txt[] = {"200Hz", "500Hz"};
+static const struct soc_enum stereo_3d_lc =
+ SOC_ENUM_SINGLE(WM8988_3D, 5, 2, stereo_3d_lc_txt);
+
+static const char *stereo_3d_uc_txt[] = {"2.2kHz", "1.5kHz"};
+static const struct soc_enum stereo_3d_uc =
+ SOC_ENUM_SINGLE(WM8988_3D, 6, 2, stereo_3d_uc_txt);
+
+static const char *stereo_3d_func_txt[] = {"Capture", "Playback"};
+static const struct soc_enum stereo_3d_func =
+ SOC_ENUM_SINGLE(WM8988_3D, 7, 2, stereo_3d_func_txt);
+
+static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"};
+static const struct soc_enum alc_func =
+ SOC_ENUM_SINGLE(WM8988_ALC1, 7, 4, alc_func_txt);
+
+static const char *ng_type_txt[] = {"Constant PGA Gain",
+ "Mute ADC Output"};
+static const struct soc_enum ng_type =
+ SOC_ENUM_SINGLE(WM8988_NGATE, 1, 2, ng_type_txt);
+
+static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"};
+static const struct soc_enum deemph =
+ SOC_ENUM_SINGLE(WM8988_ADCDAC, 1, 4, deemph_txt);
+
+static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert",
+ "L + R Invert"};
+static const struct soc_enum adcpol =
+ SOC_ENUM_SINGLE(WM8988_ADCDAC, 5, 4, adcpol_txt);
+
+static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
+static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
+
+static const struct snd_kcontrol_new wm8988_snd_controls[] = {
+
+SOC_ENUM("Bass Boost", bass_boost),
+SOC_ENUM("Bass Filter", bass_filter),
+SOC_SINGLE("Bass Volume", WM8988_BASS, 0, 15, 1),
+
+SOC_SINGLE("Treble Volume", WM8988_TREBLE, 0, 15, 0),
+SOC_ENUM("Treble Cut-off", treble),
+
+SOC_SINGLE("3D Switch", WM8988_3D, 0, 1, 0),
+SOC_SINGLE("3D Volume", WM8988_3D, 1, 15, 0),
+SOC_ENUM("3D Lower Cut-off", stereo_3d_lc),
+SOC_ENUM("3D Upper Cut-off", stereo_3d_uc),
+SOC_ENUM("3D Mode", stereo_3d_func),
+
+SOC_SINGLE("ALC Capture Target Volume", WM8988_ALC1, 0, 7, 0),
+SOC_SINGLE("ALC Capture Max Volume", WM8988_ALC1, 4, 7, 0),
+SOC_ENUM("ALC Capture Function", alc_func),
+SOC_SINGLE("ALC Capture ZC Switch", WM8988_ALC2, 7, 1, 0),
+SOC_SINGLE("ALC Capture Hold Time", WM8988_ALC2, 0, 15, 0),
+SOC_SINGLE("ALC Capture Decay Time", WM8988_ALC3, 4, 15, 0),
+SOC_SINGLE("ALC Capture Attack Time", WM8988_ALC3, 0, 15, 0),
+SOC_SINGLE("ALC Capture NG Threshold", WM8988_NGATE, 3, 31, 0),
+SOC_ENUM("ALC Capture NG Type", ng_type),
+SOC_SINGLE("ALC Capture NG Switch", WM8988_NGATE, 0, 1, 0),
+
+SOC_SINGLE("ZC Timeout Switch", WM8988_ADCTL1, 0, 1, 0),
+
+SOC_DOUBLE_R_TLV("Capture Digital Volume", WM8988_LADC, WM8988_RADC,
+ 0, 255, 0, adc_tlv),
+SOC_DOUBLE_R_TLV("Capture Volume", WM8988_LINVOL, WM8988_RINVOL,
+ 0, 63, 0, pga_tlv),
+SOC_DOUBLE_R("Capture ZC Switch", WM8988_LINVOL, WM8988_RINVOL, 6, 1, 0),
+SOC_DOUBLE_R("Capture Switch", WM8988_LINVOL, WM8988_RINVOL, 7, 1, 1),
+
+SOC_ENUM("Playback De-emphasis", deemph),
+
+SOC_ENUM("Capture Polarity", adcpol),
+SOC_SINGLE("Playback 6dB Attenuate", WM8988_ADCDAC, 7, 1, 0),
+SOC_SINGLE("Capture 6dB Attenuate", WM8988_ADCDAC, 8, 1, 0),
+
+SOC_DOUBLE_R_TLV("PCM Volume", WM8988_LDAC, WM8988_RDAC, 0, 255, 0, dac_tlv),
+
+SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", WM8988_LOUTM1, 4, 7, 1,
+ bypass_tlv),
+SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", WM8988_LOUTM2, 4, 7, 1,
+ bypass_tlv),
+SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", WM8988_ROUTM1, 4, 7, 1,
+ bypass_tlv),
+SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", WM8988_ROUTM2, 4, 7, 1,
+ bypass_tlv),
+
+SOC_DOUBLE_R("Output 1 Playback ZC Switch", WM8988_LOUT1V,
+ WM8988_ROUT1V, 7, 1, 0),
+SOC_DOUBLE_R_TLV("Output 1 Playback Volume", WM8988_LOUT1V, WM8988_ROUT1V,
+ 0, 127, 0, out_tlv),
+
+SOC_DOUBLE_R("Output 2 Playback ZC Switch", WM8988_LOUT2V,
+ WM8988_ROUT2V, 7, 1, 0),
+SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V,
+ 0, 127, 0, out_tlv),
+
+};
+
+/*
+ * DAPM Controls
+ */
+
+static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ u16 adctl2 = wm8988_read_reg_cache(codec, WM8988_ADCTL2);
+
+ /* Use the DAC to gate LRC if active, otherwise use ADC */
+ if (wm8988_read_reg_cache(codec, WM8988_PWR2) & 0x180)
+ adctl2 &= ~0x4;
+ else
+ adctl2 |= 0x4;
+
+ return wm8988_write(codec, WM8988_ADCTL2, adctl2);
+}
+
+static const char *wm8988_line_texts[] = {
+ "Line 1", "Line 2", "PGA", "Differential"};
+
+static const unsigned int wm8988_line_values[] = {
+ 0, 1, 3, 4};
+
+static const struct soc_enum wm8988_lline_enum =
+ SOC_VALUE_ENUM_SINGLE(WM8988_LOUTM1, 0, 7,
+ ARRAY_SIZE(wm8988_line_texts),
+ wm8988_line_texts,
+ wm8988_line_values);
+static const struct snd_kcontrol_new wm8988_left_line_controls =
+ SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum);
+
+static const struct soc_enum wm8988_rline_enum =
+ SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7,
+ ARRAY_SIZE(wm8988_line_texts),
+ wm8988_line_texts,
+ wm8988_line_values);
+static const struct snd_kcontrol_new wm8988_right_line_controls =
+ SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum);
+
+/* Left Mixer */
+static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Playback Switch", WM8988_LOUTM1, 8, 1, 0),
+ SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_LOUTM1, 7, 1, 0),
+ SOC_DAPM_SINGLE("Right Playback Switch", WM8988_LOUTM2, 8, 1, 0),
+ SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_LOUTM2, 7, 1, 0),
+};
+
+/* Right Mixer */
+static const struct snd_kcontrol_new wm8988_right_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Left Playback Switch", WM8988_ROUTM1, 8, 1, 0),
+ SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_ROUTM1, 7, 1, 0),
+ SOC_DAPM_SINGLE("Playback Switch", WM8988_ROUTM2, 8, 1, 0),
+ SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_ROUTM2, 7, 1, 0),
+};
+
+static const char *wm8988_pga_sel[] = {"Line 1", "Line 2", "Differential"};
+static const unsigned int wm8988_pga_val[] = { 0, 1, 3 };
+
+/* Left PGA Mux */
+static const struct soc_enum wm8988_lpga_enum =
+ SOC_VALUE_ENUM_SINGLE(WM8988_LADCIN, 6, 3,
+ ARRAY_SIZE(wm8988_pga_sel),
+ wm8988_pga_sel,
+ wm8988_pga_val);
+static const struct snd_kcontrol_new wm8988_left_pga_controls =
+ SOC_DAPM_VALUE_ENUM("Route", wm8988_lpga_enum);
+
+/* Right PGA Mux */
+static const struct soc_enum wm8988_rpga_enum =
+ SOC_VALUE_ENUM_SINGLE(WM8988_RADCIN, 6, 3,
+ ARRAY_SIZE(wm8988_pga_sel),
+ wm8988_pga_sel,
+ wm8988_pga_val);
+static const struct snd_kcontrol_new wm8988_right_pga_controls =
+ SOC_DAPM_VALUE_ENUM("Route", wm8988_rpga_enum);
+
+/* Differential Mux */
+static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"};
+static const struct soc_enum diffmux =
+ SOC_ENUM_SINGLE(WM8988_ADCIN, 8, 2, wm8988_diff_sel);
+static const struct snd_kcontrol_new wm8988_diffmux_controls =
+ SOC_DAPM_ENUM("Route", diffmux);
+
+/* Mono ADC Mux */
+static const char *wm8988_mono_mux[] = {"Stereo", "Mono (Left)",
+ "Mono (Right)", "Digital Mono"};
+static const struct soc_enum monomux =
+ SOC_ENUM_SINGLE(WM8988_ADCIN, 6, 4, wm8988_mono_mux);
+static const struct snd_kcontrol_new wm8988_monomux_controls =
+ SOC_DAPM_ENUM("Route", monomux);
+
+static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = {
+ SND_SOC_DAPM_MICBIAS("Mic Bias", WM8988_PWR1, 1, 0),
+
+ SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
+ &wm8988_diffmux_controls),
+ SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
+ &wm8988_monomux_controls),
+ SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
+ &wm8988_monomux_controls),
+
+ SND_SOC_DAPM_MUX("Left PGA Mux", WM8988_PWR1, 5, 0,
+ &wm8988_left_pga_controls),
+ SND_SOC_DAPM_MUX("Right PGA Mux", WM8988_PWR1, 4, 0,
+ &wm8988_right_pga_controls),
+
+ SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
+ &wm8988_left_line_controls),
+ SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
+ &wm8988_right_line_controls),
+
+ SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8988_PWR1, 2, 0),
+ SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8988_PWR1, 3, 0),
+
+ SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8988_PWR2, 7, 0),
+ SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8988_PWR2, 8, 0),
+
+ SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
+ &wm8988_left_mixer_controls[0],
+ ARRAY_SIZE(wm8988_left_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
+ &wm8988_right_mixer_controls[0],
+ ARRAY_SIZE(wm8988_right_mixer_controls)),
+
+ SND_SOC_DAPM_PGA("Right Out 2", WM8988_PWR2, 3, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Left Out 2", WM8988_PWR2, 4, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Right Out 1", WM8988_PWR2, 5, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Left Out 1", WM8988_PWR2, 6, 0, NULL, 0),
+
+ SND_SOC_DAPM_POST("LRC control", wm8988_lrc_control),
+
+ SND_SOC_DAPM_OUTPUT("LOUT1"),
+ SND_SOC_DAPM_OUTPUT("ROUT1"),
+ SND_SOC_DAPM_OUTPUT("LOUT2"),
+ SND_SOC_DAPM_OUTPUT("ROUT2"),
+ SND_SOC_DAPM_OUTPUT("VREF"),
+
+ SND_SOC_DAPM_INPUT("LINPUT1"),
+ SND_SOC_DAPM_INPUT("LINPUT2"),
+ SND_SOC_DAPM_INPUT("RINPUT1"),
+ SND_SOC_DAPM_INPUT("RINPUT2"),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+
+ { "Left Line Mux", "Line 1", "LINPUT1" },
+ { "Left Line Mux", "Line 2", "LINPUT2" },
+ { "Left Line Mux", "PGA", "Left PGA Mux" },
+ { "Left Line Mux", "Differential", "Differential Mux" },
+
+ { "Right Line Mux", "Line 1", "RINPUT1" },
+ { "Right Line Mux", "Line 2", "RINPUT2" },
+ { "Right Line Mux", "PGA", "Right PGA Mux" },
+ { "Right Line Mux", "Differential", "Differential Mux" },
+
+ { "Left PGA Mux", "Line 1", "LINPUT1" },
+ { "Left PGA Mux", "Line 2", "LINPUT2" },
+ { "Left PGA Mux", "Differential", "Differential Mux" },
+
+ { "Right PGA Mux", "Line 1", "RINPUT1" },
+ { "Right PGA Mux", "Line 2", "RINPUT2" },
+ { "Right PGA Mux", "Differential", "Differential Mux" },
+
+ { "Differential Mux", "Line 1", "LINPUT1" },
+ { "Differential Mux", "Line 1", "RINPUT1" },
+ { "Differential Mux", "Line 2", "LINPUT2" },
+ { "Differential Mux", "Line 2", "RINPUT2" },
+
+ { "Left ADC Mux", "Stereo", "Left PGA Mux" },
+ { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" },
+ { "Left ADC Mux", "Digital Mono", "Left PGA Mux" },
+
+ { "Right ADC Mux", "Stereo", "Right PGA Mux" },
+ { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" },
+ { "Right ADC Mux", "Digital Mono", "Right PGA Mux" },
+
+ { "Left ADC", NULL, "Left ADC Mux" },
+ { "Right ADC", NULL, "Right ADC Mux" },
+
+ { "Left Line Mux", "Line 1", "LINPUT1" },
+ { "Left Line Mux", "Line 2", "LINPUT2" },
+ { "Left Line Mux", "PGA", "Left PGA Mux" },
+ { "Left Line Mux", "Differential", "Differential Mux" },
+
+ { "Right Line Mux", "Line 1", "RINPUT1" },
+ { "Right Line Mux", "Line 2", "RINPUT2" },
+ { "Right Line Mux", "PGA", "Right PGA Mux" },
+ { "Right Line Mux", "Differential", "Differential Mux" },
+
+ { "Left Mixer", "Playback Switch", "Left DAC" },
+ { "Left Mixer", "Left Bypass Switch", "Left Line Mux" },
+ { "Left Mixer", "Right Playback Switch", "Right DAC" },
+ { "Left Mixer", "Right Bypass Switch", "Right Line Mux" },
+
+ { "Right Mixer", "Left Playback Switch", "Left DAC" },
+ { "Right Mixer", "Left Bypass Switch", "Left Line Mux" },
+ { "Right Mixer", "Playback Switch", "Right DAC" },
+ { "Right Mixer", "Right Bypass Switch", "Right Line Mux" },
+
+ { "Left Out 1", NULL, "Left Mixer" },
+ { "LOUT1", NULL, "Left Out 1" },
+ { "Right Out 1", NULL, "Right Mixer" },
+ { "ROUT1", NULL, "Right Out 1" },
+
+ { "Left Out 2", NULL, "Left Mixer" },
+ { "LOUT2", NULL, "Left Out 2" },
+ { "Right Out 2", NULL, "Right Mixer" },
+ { "ROUT2", NULL, "Right Out 2" },
+};
+
+struct _coeff_div {
+ u32 mclk;
+ u32 rate;
+ u16 fs;
+ u8 sr:5;
+ u8 usb:1;
+};
+
+/* codec hifi mclk clock divider coefficients */
+static const struct _coeff_div coeff_div[] = {
+ /* 8k */
+ {12288000, 8000, 1536, 0x6, 0x0},
+ {11289600, 8000, 1408, 0x16, 0x0},
+ {18432000, 8000, 2304, 0x7, 0x0},
+ {16934400, 8000, 2112, 0x17, 0x0},
+ {12000000, 8000, 1500, 0x6, 0x1},
+
+ /* 11.025k */
+ {11289600, 11025, 1024, 0x18, 0x0},
+ {16934400, 11025, 1536, 0x19, 0x0},
+ {12000000, 11025, 1088, 0x19, 0x1},
+
+ /* 16k */
+ {12288000, 16000, 768, 0xa, 0x0},
+ {18432000, 16000, 1152, 0xb, 0x0},
+ {12000000, 16000, 750, 0xa, 0x1},
+
+ /* 22.05k */
+ {11289600, 22050, 512, 0x1a, 0x0},
+ {16934400, 22050, 768, 0x1b, 0x0},
+ {12000000, 22050, 544, 0x1b, 0x1},
+
+ /* 32k */
+ {12288000, 32000, 384, 0xc, 0x0},
+ {18432000, 32000, 576, 0xd, 0x0},
+ {12000000, 32000, 375, 0xa, 0x1},
+
+ /* 44.1k */
+ {11289600, 44100, 256, 0x10, 0x0},
+ {16934400, 44100, 384, 0x11, 0x0},
+ {12000000, 44100, 272, 0x11, 0x1},
+
+ /* 48k */
+ {12288000, 48000, 256, 0x0, 0x0},
+ {18432000, 48000, 384, 0x1, 0x0},
+ {12000000, 48000, 250, 0x0, 0x1},
+
+ /* 88.2k */
+ {11289600, 88200, 128, 0x1e, 0x0},
+ {16934400, 88200, 192, 0x1f, 0x0},
+ {12000000, 88200, 136, 0x1f, 0x1},
+
+ /* 96k */
+ {12288000, 96000, 128, 0xe, 0x0},
+ {18432000, 96000, 192, 0xf, 0x0},
+ {12000000, 96000, 125, 0xe, 0x1},
+};
+
+static inline int get_coeff(int mclk, int rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+/* The set of rates we can generate from the above for each SYSCLK */
+
+static unsigned int rates_12288[] = {
+ 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_12288 = {
+ .count = ARRAY_SIZE(rates_12288),
+ .list = rates_12288,
+};
+
+static unsigned int rates_112896[] = {
+ 8000, 11025, 22050, 44100,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_112896 = {
+ .count = ARRAY_SIZE(rates_112896),
+ .list = rates_112896,
+};
+
+static unsigned int rates_12[] = {
+ 8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000,
+ 48000, 88235, 96000,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_12 = {
+ .count = ARRAY_SIZE(rates_12),
+ .list = rates_12,
+};
+
+/*
+ * Note that this should be called from init rather than from hw_params.
+ */
+static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct wm8988_priv *wm8988 = codec->private_data;
+
+ switch (freq) {
+ case 11289600:
+ case 18432000:
+ case 22579200:
+ case 36864000:
+ wm8988->sysclk_constraints = &constraints_112896;
+ wm8988->sysclk = freq;
+ return 0;
+
+ case 12288000:
+ case 16934400:
+ case 24576000:
+ case 33868800:
+ wm8988->sysclk_constraints = &constraints_12288;
+ wm8988->sysclk = freq;
+ return 0;
+
+ case 12000000:
+ case 24000000:
+ wm8988->sysclk_constraints = &constraints_12;
+ wm8988->sysclk = freq;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 iface = 0;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ iface = 0x0040;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= 0x0002;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= 0x0001;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= 0x0003;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= 0x0013;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= 0x0090;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= 0x0080;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface |= 0x0010;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ wm8988_write(codec, WM8988_IFACE, iface);
+ return 0;
+}
+
+static int wm8988_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct wm8988_priv *wm8988 = codec->private_data;
+
+ /* The set of sample rates that can be supported depends on the
+ * MCLK supplied to the CODEC - enforce this.
+ */
+ if (!wm8988->sysclk) {
+ dev_err(codec->dev,
+ "No MCLK configured, call set_sysclk() on init\n");
+ return -EINVAL;
+ }
+
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ wm8988->sysclk_constraints);
+
+ return 0;
+}
+
+static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->card->codec;
+ struct wm8988_priv *wm8988 = codec->private_data;
+ u16 iface = wm8988_read_reg_cache(codec, WM8988_IFACE) & 0x1f3;
+ u16 srate = wm8988_read_reg_cache(codec, WM8988_SRATE) & 0x180;
+ int coeff;
+
+ coeff = get_coeff(wm8988->sysclk, params_rate(params));
+ if (coeff < 0) {
+ coeff = get_coeff(wm8988->sysclk / 2, params_rate(params));
+ srate |= 0x40;
+ }
+ if (coeff < 0) {
+ dev_err(codec->dev,
+ "Unable to configure sample rate %dHz with %dHz MCLK\n",
+ params_rate(params), wm8988->sysclk);
+ return coeff;
+ }
+
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x0004;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= 0x0008;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x000c;
+ break;
+ }
+
+ /* set iface & srate */
+ wm8988_write(codec, WM8988_IFACE, iface);
+ if (coeff >= 0)
+ wm8988_write(codec, WM8988_SRATE, srate |
+ (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
+
+ return 0;
+}
+
+static int wm8988_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 mute_reg = wm8988_read_reg_cache(codec, WM8988_ADCDAC) & 0xfff7;
+
+ if (mute)
+ wm8988_write(codec, WM8988_ADCDAC, mute_reg | 0x8);
+ else
+ wm8988_write(codec, WM8988_ADCDAC, mute_reg);
+ return 0;
+}
+
+static int wm8988_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ u16 pwr_reg = wm8988_read_reg_cache(codec, WM8988_PWR1) & ~0x1c1;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ /* VREF, VMID=2x50k, digital enabled */
+ wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x00c0);
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ /* VREF, VMID=2x5k */
+ wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
+
+ /* Charge caps */
+ msleep(100);
+ }
+
+ /* VREF, VMID=2*500k, digital stopped */
+ wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x0141);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ wm8988_write(codec, WM8988_PWR1, 0x0000);
+ break;
+ }
+ codec->bias_level = level;
+ return 0;
+}
+
+#define WM8988_RATES SNDRV_PCM_RATE_8000_96000
+
+#define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static struct snd_soc_dai_ops wm8988_ops = {
+ .startup = wm8988_pcm_startup,
+ .hw_params = wm8988_pcm_hw_params,
+ .set_fmt = wm8988_set_dai_fmt,
+ .set_sysclk = wm8988_set_dai_sysclk,
+ .digital_mute = wm8988_mute,
+};
+
+struct snd_soc_dai wm8988_dai = {
+ .name = "WM8988",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8988_RATES,
+ .formats = WM8988_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8988_RATES,
+ .formats = WM8988_FORMATS,
+ },
+ .ops = &wm8988_ops,
+ .symmetric_rates = 1,
+};
+EXPORT_SYMBOL_GPL(wm8988_dai);
+
+static int wm8988_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+
+ wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int wm8988_resume(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+ int i;
+ u8 data[2];
+ u16 *cache = codec->reg_cache;
+
+ /* Sync reg_cache with the hardware */
+ for (i = 0; i < WM8988_NUM_REG; i++) {
+ if (i == WM8988_RESET)
+ continue;
+ data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
+ data[1] = cache[i] & 0x00ff;
+ codec->hw_write(codec->control_data, data, 2);
+ }
+
+ wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return 0;
+}
+
+static struct snd_soc_codec *wm8988_codec;
+
+static int wm8988_probe(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec;
+ int ret = 0;
+
+ if (wm8988_codec == NULL) {
+ dev_err(&pdev->dev, "Codec device not registered\n");
+ return -ENODEV;
+ }
+
+ socdev->card->codec = wm8988_codec;
+ codec = wm8988_codec;
+
+ /* register pcms */
+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to create pcms: %d\n", ret);
+ goto pcm_err;
+ }
+
+ snd_soc_add_controls(codec, wm8988_snd_controls,
+ ARRAY_SIZE(wm8988_snd_controls));
+ snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
+ ARRAY_SIZE(wm8988_dapm_widgets));
+ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_widgets(codec);
+
+ ret = snd_soc_init_card(socdev);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to register card: %d\n", ret);
+ goto card_err;
+ }
+
+ return ret;
+
+card_err:
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+pcm_err:
+ return ret;
+}
+
+static int wm8988_remove(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+
+ return 0;
+}
+
+struct snd_soc_codec_device soc_codec_dev_wm8988 = {
+ .probe = wm8988_probe,
+ .remove = wm8988_remove,
+ .suspend = wm8988_suspend,
+ .resume = wm8988_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988);
+
+static int wm8988_register(struct wm8988_priv *wm8988)
+{
+ struct snd_soc_codec *codec = &wm8988->codec;
+ int ret;
+ u16 reg;
+
+ if (wm8988_codec) {
+ dev_err(codec->dev, "Another WM8988 is registered\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ mutex_init(&codec->mutex);
+ INIT_LIST_HEAD(&codec->dapm_widgets);
+ INIT_LIST_HEAD(&codec->dapm_paths);
+
+ codec->private_data = wm8988;
+ codec->name = "WM8988";
+ codec->owner = THIS_MODULE;
+ codec->read = wm8988_read_reg_cache;
+ codec->write = wm8988_write;
+ codec->dai = &wm8988_dai;
+ codec->num_dai = 1;
+ codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache);
+ codec->reg_cache = &wm8988->reg_cache;
+ codec->bias_level = SND_SOC_BIAS_OFF;
+ codec->set_bias_level = wm8988_set_bias_level;
+
+ memcpy(codec->reg_cache, wm8988_reg,
+ sizeof(wm8988_reg));
+
+ ret = wm8988_reset(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset\n");
+ return ret;
+ }
+
+ /* set the update bits (we always update left then right) */
+ reg = wm8988_read_reg_cache(codec, WM8988_RADC);
+ wm8988_write(codec, WM8988_RADC, reg | 0x100);
+ reg = wm8988_read_reg_cache(codec, WM8988_RDAC);
+ wm8988_write(codec, WM8988_RDAC, reg | 0x0100);
+ reg = wm8988_read_reg_cache(codec, WM8988_ROUT1V);
+ wm8988_write(codec, WM8988_ROUT1V, reg | 0x0100);
+ reg = wm8988_read_reg_cache(codec, WM8988_ROUT2V);
+ wm8988_write(codec, WM8988_ROUT2V, reg | 0x0100);
+ reg = wm8988_read_reg_cache(codec, WM8988_RINVOL);
+ wm8988_write(codec, WM8988_RINVOL, reg | 0x0100);
+
+ wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY);
+
+ wm8988_dai.dev = codec->dev;
+
+ wm8988_codec = codec;
+
+ ret = snd_soc_register_codec(codec);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to register codec: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_register_dai(&wm8988_dai);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
+ snd_soc_unregister_codec(codec);
+ return ret;
+ }
+
+ return 0;
+
+err:
+ kfree(wm8988);
+ return ret;
+}
+
+static void wm8988_unregister(struct wm8988_priv *wm8988)
+{
+ wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_OFF);
+ snd_soc_unregister_dai(&wm8988_dai);
+ snd_soc_unregister_codec(&wm8988->codec);
+ kfree(wm8988);
+ wm8988_codec = NULL;
+}
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static int wm8988_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8988_priv *wm8988;
+ struct snd_soc_codec *codec;
+
+ wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
+ if (wm8988 == NULL)
+ return -ENOMEM;
+
+ codec = &wm8988->codec;
+ codec->hw_write = (hw_write_t)i2c_master_send;
+
+ i2c_set_clientdata(i2c, wm8988);
+ codec->control_data = i2c;
+
+ codec->dev = &i2c->dev;
+
+ return wm8988_register(wm8988);
+}
+
+static int wm8988_i2c_remove(struct i2c_client *client)
+{
+ struct wm8988_priv *wm8988 = i2c_get_clientdata(client);
+ wm8988_unregister(wm8988);
+ return 0;
+}
+
+static const struct i2c_device_id wm8988_i2c_id[] = {
+ { "wm8988", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
+
+static struct i2c_driver wm8988_i2c_driver = {
+ .driver = {
+ .name = "WM8988",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8988_i2c_probe,
+ .remove = wm8988_i2c_remove,
+ .id_table = wm8988_i2c_id,
+};
+#endif
+
+#if defined(CONFIG_SPI_MASTER)
+static int wm8988_spi_write(struct spi_device *spi, const char *data, int len)
+{
+ struct spi_transfer t;
+ struct spi_message m;
+ u8 msg[2];
+
+ if (len <= 0)
+ return 0;
+
+ msg[0] = data[0];
+ msg[1] = data[1];
+
+ spi_message_init(&m);
+ memset(&t, 0, (sizeof t));
+
+ t.tx_buf = &msg[0];
+ t.len = len;
+
+ spi_message_add_tail(&t, &m);
+ spi_sync(spi, &m);
+
+ return len;
+}
+
+static int __devinit wm8988_spi_probe(struct spi_device *spi)
+{
+ struct wm8988_priv *wm8988;
+ struct snd_soc_codec *codec;
+
+ wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
+ if (wm8988 == NULL)
+ return -ENOMEM;
+
+ codec = &wm8988->codec;
+ codec->hw_write = (hw_write_t)wm8988_spi_write;
+ codec->control_data = spi;
+ codec->dev = &spi->dev;
+
+ spi->dev.driver_data = wm8988;
+
+ return wm8988_register(wm8988);
+}
+
+static int __devexit wm8988_spi_remove(struct spi_device *spi)
+{
+ struct wm8988_priv *wm8988 = spi->dev.driver_data;
+
+ wm8988_unregister(wm8988);
+
+ return 0;
+}
+
+static struct spi_driver wm8988_spi_driver = {
+ .driver = {
+ .name = "wm8988",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8988_spi_probe,
+ .remove = __devexit_p(wm8988_spi_remove),
+};
+#endif
+
+static int __init wm8988_modinit(void)
+{
+ int ret;
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8988_i2c_driver);
+ if (ret != 0)
+ pr_err("WM8988: Unable to register I2C driver: %d\n", ret);
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ ret = spi_register_driver(&wm8988_spi_driver);
+ if (ret != 0)
+ pr_err("WM8988: Unable to register SPI driver: %d\n", ret);
+#endif
+ return ret;
+}
+module_init(wm8988_modinit);
+
+static void __exit wm8988_exit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&wm8988_i2c_driver);
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ spi_unregister_driver(&wm8988_spi_driver);
+#endif
+}
+module_exit(wm8988_exit);
+
+
+MODULE_DESCRIPTION("ASoC WM8988 driver");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8988.h b/sound/soc/codecs/wm8988.h
new file mode 100644
index 000000000000..4552d37fdd41
--- /dev/null
+++ b/sound/soc/codecs/wm8988.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <richard@openedhand.com>
+ *
+ * Based on WM8753.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _WM8988_H
+#define _WM8988_H
+
+/* WM8988 register space */
+
+#define WM8988_LINVOL 0x00
+#define WM8988_RINVOL 0x01
+#define WM8988_LOUT1V 0x02
+#define WM8988_ROUT1V 0x03
+#define WM8988_ADCDAC 0x05
+#define WM8988_IFACE 0x07
+#define WM8988_SRATE 0x08
+#define WM8988_LDAC 0x0a
+#define WM8988_RDAC 0x0b
+#define WM8988_BASS 0x0c
+#define WM8988_TREBLE 0x0d
+#define WM8988_RESET 0x0f
+#define WM8988_3D 0x10
+#define WM8988_ALC1 0x11
+#define WM8988_ALC2 0x12
+#define WM8988_ALC3 0x13
+#define WM8988_NGATE 0x14
+#define WM8988_LADC 0x15
+#define WM8988_RADC 0x16
+#define WM8988_ADCTL1 0x17
+#define WM8988_ADCTL2 0x18
+#define WM8988_PWR1 0x19
+#define WM8988_PWR2 0x1a
+#define WM8988_ADCTL3 0x1b
+#define WM8988_ADCIN 0x1f
+#define WM8988_LADCIN 0x20
+#define WM8988_RADCIN 0x21
+#define WM8988_LOUTM1 0x22
+#define WM8988_LOUTM2 0x23
+#define WM8988_ROUTM1 0x24
+#define WM8988_ROUTM2 0x25
+#define WM8988_LOUT2V 0x28
+#define WM8988_ROUT2V 0x29
+#define WM8988_LPPB 0x43
+#define WM8988_NUM_REG 0x44
+
+#define WM8988_SYSCLK 0
+
+extern struct snd_soc_dai wm8988_dai;
+extern struct snd_soc_codec_device soc_codec_dev_wm8988;
+
+#endif
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index c518c3e5aa3f..40cd274eb1ef 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -729,7 +729,7 @@ SND_SOC_DAPM_MIXER_E("INMIXL", WM8990_INTDRIVBITS, WM8990_INMIXL_PWR_BIT, 0,
inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
/* AINLMUX */
-SND_SOC_DAPM_MUX_E("AILNMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0,
+SND_SOC_DAPM_MUX_E("AINLMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0,
&wm8990_dapm_ainlmux_controls, inmixer_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -740,7 +740,7 @@ SND_SOC_DAPM_MIXER_E("INMIXR", WM8990_INTDRIVBITS, WM8990_INMIXR_PWR_BIT, 0,
inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
/* AINRMUX */
-SND_SOC_DAPM_MUX_E("AIRNMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0,
+SND_SOC_DAPM_MUX_E("AINRMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0,
&wm8990_dapm_ainrmux_controls, inmixer_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -848,40 +848,40 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"LIN12 PGA", "LIN2 Switch", "LIN2"},
/* LIN34 PGA */
{"LIN34 PGA", "LIN3 Switch", "LIN3"},
- {"LIN34 PGA", "LIN4 Switch", "LIN4"},
+ {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"},
/* INMIXL */
{"INMIXL", "Record Left Volume", "LOMIX"},
{"INMIXL", "LIN2 Volume", "LIN2"},
{"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
{"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
- /* AILNMUX */
- {"AILNMUX", "INMIXL Mix", "INMIXL"},
- {"AILNMUX", "DIFFINL Mix", "LIN12PGA"},
- {"AILNMUX", "DIFFINL Mix", "LIN34PGA"},
- {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"},
- {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"},
+ /* AINLMUX */
+ {"AINLMUX", "INMIXL Mix", "INMIXL"},
+ {"AINLMUX", "DIFFINL Mix", "LIN12 PGA"},
+ {"AINLMUX", "DIFFINL Mix", "LIN34 PGA"},
+ {"AINLMUX", "RXVOICE Mix", "LIN4/RXN"},
+ {"AINLMUX", "RXVOICE Mix", "RIN4/RXP"},
/* ADC */
- {"Left ADC", NULL, "AILNMUX"},
+ {"Left ADC", NULL, "AINLMUX"},
/* RIN12 PGA */
{"RIN12 PGA", "RIN1 Switch", "RIN1"},
{"RIN12 PGA", "RIN2 Switch", "RIN2"},
/* RIN34 PGA */
{"RIN34 PGA", "RIN3 Switch", "RIN3"},
- {"RIN34 PGA", "RIN4 Switch", "RIN4"},
+ {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"},
/* INMIXL */
{"INMIXR", "Record Right Volume", "ROMIX"},
{"INMIXR", "RIN2 Volume", "RIN2"},
{"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
{"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
- /* AIRNMUX */
- {"AIRNMUX", "INMIXR Mix", "INMIXR"},
- {"AIRNMUX", "DIFFINR Mix", "RIN12PGA"},
- {"AIRNMUX", "DIFFINR Mix", "RIN34PGA"},
- {"AIRNMUX", "RXVOICE Mix", "RIN4/RXN"},
- {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"},
+ /* AINRMUX */
+ {"AINRMUX", "INMIXR Mix", "INMIXR"},
+ {"AINRMUX", "DIFFINR Mix", "RIN12 PGA"},
+ {"AINRMUX", "DIFFINR Mix", "RIN34 PGA"},
+ {"AINRMUX", "RXVOICE Mix", "LIN4/RXN"},
+ {"AINRMUX", "RXVOICE Mix", "RIN4/RXP"},
/* ADC */
- {"Right ADC", NULL, "AIRNMUX"},
+ {"Right ADC", NULL, "AINRMUX"},
/* LOMIX */
{"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
@@ -922,7 +922,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
/* OUT3MIX */
- {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXP"},
+ {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"},
{"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
/* OUT4MIX */
@@ -949,7 +949,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
/* Output Pins */
{"LON", NULL, "LONMIX"},
{"LOP", NULL, "LOPMIX"},
- {"OUT", NULL, "OUT3MIX"},
+ {"OUT3", NULL, "OUT3MIX"},
{"LOUT", NULL, "LOUT PGA"},
{"SPKN", NULL, "SPKMIX"},
{"ROUT", NULL, "ROUT PGA"},
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index c2d1a7a18fa3..fa88b463e71f 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -282,14 +282,14 @@ struct snd_soc_dai wm9705_dai[] = {
.channels_min = 1,
.channels_max = 2,
.rates = WM9705_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .formats = SND_SOC_STD_AC97_FMTS,
},
.capture = {
.stream_name = "HiFi Capture",
.channels_min = 1,
.channels_max = 2,
.rates = WM9705_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .formats = SND_SOC_STD_AC97_FMTS,
},
.ops = &wm9705_dai_ops,
},
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 765cf1e7369e..550c903f23bf 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -534,13 +534,13 @@ struct snd_soc_dai wm9712_dai[] = {
.channels_min = 1,
.channels_max = 2,
.rates = WM9712_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .formats = SND_SOC_STD_AC97_FMTS,},
.capture = {
.stream_name = "HiFi Capture",
.channels_min = 1,
.channels_max = 2,
.rates = WM9712_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .formats = SND_SOC_STD_AC97_FMTS,},
.ops = &wm9712_dai_ops_hifi,
},
{
@@ -550,7 +550,7 @@ struct snd_soc_dai wm9712_dai[] = {
.channels_min = 1,
.channels_max = 1,
.rates = WM9712_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .formats = SND_SOC_STD_AC97_FMTS,},
.ops = &wm9712_dai_ops_aux,
}
};
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 523bad077fa0..d1744e96f303 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -189,6 +189,26 @@ SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
};
+static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ u16 status, rate;
+
+ BUG_ON(event != SND_SOC_DAPM_PRE_PMD);
+
+ /* Gracefully shut down the voice interface. */
+ status = ac97_read(codec, AC97_EXTENDED_MID) | 0x1000;
+ rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
+ ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
+ schedule_timeout_interruptible(msecs_to_jiffies(1));
+ ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00);
+ ac97_write(codec, AC97_EXTENDED_MID, status);
+
+ return 0;
+}
+
+
/* We have to create a fake left and right HP mixers because
* the codec only has a single control that is shared by both channels.
* This makes it impossible to determine the audio path using the current
@@ -400,7 +420,8 @@ SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1),
+SND_SOC_DAPM_DAC_E("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1,
+ wm9713_voice_shutdown, SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1),
SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0),
SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0),
@@ -936,21 +957,6 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static void wm9713_voiceshutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 status, rate;
-
- /* Gracefully shut down the voice interface. */
- status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000;
- rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
- ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
- schedule_timeout_interruptible(msecs_to_jiffies(1));
- ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00);
- ac97_write(codec, AC97_EXTENDED_MID, status);
-}
-
static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -1019,7 +1025,6 @@ static struct snd_soc_dai_ops wm9713_dai_ops_aux = {
static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
.hw_params = wm9713_pcm_hw_params,
- .shutdown = wm9713_voiceshutdown,
.set_clkdiv = wm9713_set_dai_clkdiv,
.set_pll = wm9713_set_dai_pll,
.set_fmt = wm9713_set_dai_fmt,
@@ -1035,13 +1040,13 @@ struct snd_soc_dai wm9713_dai[] = {
.channels_min = 1,
.channels_max = 2,
.rates = WM9713_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .formats = SND_SOC_STD_AC97_FMTS,},
.capture = {
.stream_name = "HiFi Capture",
.channels_min = 1,
.channels_max = 2,
.rates = WM9713_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .formats = SND_SOC_STD_AC97_FMTS,},
.ops = &wm9713_dai_ops_hifi,
},
{
@@ -1051,7 +1056,7 @@ struct snd_soc_dai wm9713_dai[] = {
.channels_min = 1,
.channels_max = 1,
.rates = WM9713_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .formats = SND_SOC_STD_AC97_FMTS,},
.ops = &wm9713_dai_ops_aux,
},
{
@@ -1069,6 +1074,7 @@ struct snd_soc_dai wm9713_dai[] = {
.rates = WM9713_PCM_RATES,
.formats = WM9713_PCM_FORMATS,},
.ops = &wm9713_dai_ops_voice,
+ .symmetric_rates = 1,
},
};
EXPORT_SYMBOL_GPL(wm9713_dai);
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 91ef17992de5..b60b1dfbc435 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -383,10 +383,9 @@ static int __init n810_soc_init(void)
clk_set_parent(sys_clkout2_src, func96m_clk);
clk_set_rate(sys_clkout2, 12000000);
- if (gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0)
- BUG();
- if (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0)
- BUG();
+ BUG_ON((gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) ||
+ (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0));
+
gpio_direction_output(N810_HEADSET_AMP_GPIO, 0);
gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0);
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 912614283848..a5d46a7b196a 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -215,8 +215,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
- int wlen, channels;
+ int wlen, channels, wpf;
unsigned long port;
+ unsigned int format;
if (cpu_class_is_omap1()) {
dma = omap1_dma_reqs[bus_id][substream->stream];
@@ -244,18 +245,24 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
return 0;
}
- channels = params_channels(params);
+ format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+ wpf = channels = params_channels(params);
switch (channels) {
case 2:
- /* Use dual-phase frames */
- regs->rcr2 |= RPHASE;
- regs->xcr2 |= XPHASE;
+ if (format == SND_SOC_DAIFMT_I2S) {
+ /* Use dual-phase frames */
+ regs->rcr2 |= RPHASE;
+ regs->xcr2 |= XPHASE;
+ /* Set 1 word per (McBSP) frame for phase1 and phase2 */
+ wpf--;
+ regs->rcr2 |= RFRLEN2(wpf - 1);
+ regs->xcr2 |= XFRLEN2(wpf - 1);
+ }
case 1:
- /* Set 1 word per (McBSP) frame */
- regs->rcr2 |= RFRLEN2(1 - 1);
- regs->rcr1 |= RFRLEN1(1 - 1);
- regs->xcr2 |= XFRLEN2(1 - 1);
- regs->xcr1 |= XFRLEN1(1 - 1);
+ case 4:
+ /* Set word per (McBSP) frame for phase1 */
+ regs->rcr1 |= RFRLEN1(wpf - 1);
+ regs->xcr1 |= XFRLEN1(wpf - 1);
break;
default:
/* Unsupported number of channels */
@@ -277,11 +284,12 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
}
/* Set FS period and length in terms of bit clock periods */
- switch (mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ switch (format) {
case SND_SOC_DAIFMT_I2S:
- regs->srgr2 |= FPER(wlen * 2 - 1);
+ regs->srgr2 |= FPER(wlen * channels - 1);
regs->srgr1 |= FWID(wlen - 1);
break;
+ case SND_SOC_DAIFMT_DSP_A:
case SND_SOC_DAIFMT_DSP_B:
regs->srgr2 |= FPER(wlen * channels - 1);
regs->srgr1 |= FWID(0);
@@ -326,6 +334,13 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
regs->rcr2 |= RDATDLY(1);
regs->xcr2 |= XDATDLY(1);
break;
+ case SND_SOC_DAIFMT_DSP_A:
+ /* 1-bit data delay */
+ regs->rcr2 |= RDATDLY(1);
+ regs->xcr2 |= XDATDLY(1);
+ /* Invert FS polarity configuration */
+ temp_fmt ^= SND_SOC_DAIFMT_NB_IF;
+ break;
case SND_SOC_DAIFMT_DSP_B:
/* 0-bit data delay */
regs->rcr2 |= RDATDLY(0);
@@ -492,13 +507,13 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = {
.id = (link_id), \
.playback = { \
.channels_min = 1, \
- .channels_max = 2, \
+ .channels_max = 4, \
.rates = OMAP_MCBSP_RATES, \
.formats = SNDRV_PCM_FMTBIT_S16_LE, \
}, \
.capture = { \
.channels_min = 1, \
- .channels_max = 2, \
+ .channels_max = 4, \
.rates = OMAP_MCBSP_RATES, \
.formats = SNDRV_PCM_FMTBIT_S16_LE, \
}, \
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 07cf7f46b584..6454e15f7d28 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -87,8 +87,10 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data;
int err = 0;
+ /* return if this is a bufferless transfer e.g.
+ * codec <--> BT codec or GSM modem -- lg FIXME */
if (!dma_data)
- return -ENODEV;
+ return 0;
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
runtime->dma_bytes = params_buffer_bytes(params);
@@ -134,6 +136,11 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
struct omap_pcm_dma_data *dma_data = prtd->dma_data;
struct omap_dma_channel_params dma_params;
+ /* return if this is a bufferless transfer e.g.
+ * codec <--> BT codec or GSM modem -- lg FIXME */
+ if (!prtd->dma_data)
+ return 0;
+
memset(&dma_params, 0, sizeof(dma_params));
/*
* Note: Regardless of interface data formats supported by OMAP McBSP
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
index 0c2322dcf02a..027e1a40f8a1 100644
--- a/sound/soc/omap/omap2evm.c
+++ b/sound/soc/omap/omap2evm.c
@@ -86,7 +86,7 @@ static struct snd_soc_dai_link omap2evm_dai = {
.name = "TWL4030",
.stream_name = "TWL4030",
.cpu_dai = &omap_mcbsp_dai[0],
- .codec_dai = &twl4030_dai,
+ .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
.ops = &omap2evm_ops,
};
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index fd24a4acd2f5..b0cff9f33b7e 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -41,23 +41,33 @@ static int omap3beagle_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ unsigned int fmt;
int ret;
+ switch (params_channels(params)) {
+ case 2: /* Stereo I2S mode */
+ fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ break;
+ case 4: /* Four channel TDM mode */
+ fmt = SND_SOC_DAIFMT_DSP_A |
+ SND_SOC_DAIFMT_IB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
/* Set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
if (ret < 0) {
printk(KERN_ERR "can't set codec DAI configuration\n");
return ret;
}
/* Set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
printk(KERN_ERR "can't set cpu DAI configuration\n");
return ret;
@@ -83,7 +93,7 @@ static struct snd_soc_dai_link omap3beagle_dai = {
.name = "TWL4030",
.stream_name = "TWL4030",
.cpu_dai = &omap_mcbsp_dai[0],
- .codec_dai = &twl4030_dai,
+ .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
.ops = &omap3beagle_ops,
};
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index fe282d4ef422..ad219aaf7cb8 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -228,14 +228,14 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
.name = "PCM1773",
.stream_name = "HiFi Out",
.cpu_dai = &omap_mcbsp_dai[0],
- .codec_dai = &twl4030_dai,
+ .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
.ops = &omap3pandora_out_ops,
.init = omap3pandora_out_init,
}, {
.name = "TWL4030",
.stream_name = "Line/Mic In",
.cpu_dai = &omap_mcbsp_dai[1],
- .codec_dai = &twl4030_dai,
+ .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
.ops = &omap3pandora_in_ops,
.init = omap3pandora_in_init,
}
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index a72dc4e159e5..ec4f8fd8b3a2 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -83,7 +83,7 @@ static struct snd_soc_dai_link overo_dai = {
.name = "TWL4030",
.stream_name = "TWL4030",
.cpu_dai = &omap_mcbsp_dai[0],
- .codec_dai = &twl4030_dai,
+ .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
.ops = &overo_ops,
};
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 10f1c867f11d..1c7974101a0b 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -197,7 +197,7 @@ static struct snd_soc_dai_link sdp3430_dai = {
.name = "TWL4030",
.stream_name = "TWL4030",
.cpu_dai = &omap_mcbsp_dai[0],
- .codec_dai = &twl4030_dai,
+ .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
.init = sdp3430_twl4030_init,
.ops = &sdp3430_ops,
};
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index ad8a10fe6298..6375b4ea525d 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -89,22 +89,23 @@ config SND_PXA2XX_SOC_E800
Toshiba e800 PDA
config SND_PXA2XX_SOC_EM_X270
- tristate "SoC Audio support for CompuLab EM-x270"
+ tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300"
depends on SND_PXA2XX_SOC && MACH_EM_X270
select SND_PXA2XX_SOC_AC97
select SND_SOC_WM9712
help
Say Y if you want to add support for SoC audio on
- CompuLab EM-x270.
+ CompuLab EM-x270, eXeda and CM-X300 machines.
config SND_PXA2XX_SOC_PALM27X
- bool "SoC Audio support for Palm T|X, T5 and LifeDrive"
- depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || MACH_PALMT5)
+ bool "SoC Audio support for Palm T|X, T5, E2 and LifeDrive"
+ depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || \
+ MACH_PALMT5 || MACH_PALMTE2)
select SND_PXA2XX_SOC_AC97
select SND_SOC_WM9712
help
Say Y if you want to add support for SoC audio on
- Palm T|X, T5 or LifeDrive handheld computer.
+ Palm T|X, T5, E2 or LifeDrive handheld computer.
config SND_SOC_ZYLONITE
tristate "SoC Audio support for Marvell Zylonite"
@@ -134,3 +135,12 @@ config SND_PXA2XX_SOC_MIOA701
help
Say Y if you want to add support for SoC audio on the
MIO A701.
+
+config SND_PXA2XX_SOC_IMOTE2
+ tristate "SoC Audio support for IMote 2"
+ depends on SND_PXA2XX_SOC && MACH_INTELMOTE2
+ select SND_PXA2XX_SOC_I2S
+ select SND_SOC_WM8940
+ help
+ Say Y if you want to add support for SoC audio on the
+ IMote 2.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 4b90c3ccae45..6e096b480335 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o
snd-soc-zylonite-objs := zylonite.o
snd-soc-magician-objs := magician.o
snd-soc-mioa701-objs := mioa701_wm9713.o
+snd-soc-imote2-objs := imote2.o
obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -35,3 +36,4 @@ obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
+obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index 949be9c2a01b..f4756e4025fd 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -1,7 +1,7 @@
/*
- * em-x270.c -- SoC audio for EM-X270
+ * SoC audio driver for EM-X270, eXeda and CM-X300
*
- * Copyright 2007 CompuLab, Ltd.
+ * Copyright 2007, 2009 CompuLab, Ltd.
*
* Author: Mike Rapoport <mike@compulab.co.il>
*
@@ -68,7 +68,8 @@ static int __init em_x270_init(void)
{
int ret;
- if (!machine_is_em_x270())
+ if (!(machine_is_em_x270() || machine_is_exeda()
+ || machine_is_cm_x300()))
return -ENODEV;
em_x270_snd_device = platform_device_alloc("soc-audio", -1);
@@ -95,5 +96,5 @@ module_exit(em_x270_exit);
/* Module information */
MODULE_AUTHOR("Mike Rapoport");
-MODULE_DESCRIPTION("ALSA SoC EM-X270");
+MODULE_DESCRIPTION("ALSA SoC EM-X270, eXeda and CM-X300");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
new file mode 100644
index 000000000000..405587a01160
--- /dev/null
+++ b/sound/soc/pxa/imote2.c
@@ -0,0 +1,114 @@
+
+#include <linux/module.h>
+#include <sound/soc.h>
+
+#include <asm/mach-types.h>
+
+#include "../codecs/wm8940.h"
+#include "pxa2xx-i2s.h"
+#include "pxa2xx-pcm.h"
+
+static int imote2_asoc_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_dai *codec_dai = rtd->dai->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ unsigned int clk = 0;
+ int ret;
+
+ switch (params_rate(params)) {
+ case 8000:
+ case 16000:
+ case 48000:
+ case 96000:
+ clk = 12288000;
+ break;
+ case 11025:
+ case 22050:
+ case 44100:
+ clk = 11289600;
+ break;
+ }
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ /* CPU should be clock master */
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ return ret;
+
+ /* set the I2S system clock as input (unused) */
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, clk,
+ SND_SOC_CLOCK_OUT);
+
+ return ret;
+}
+
+static struct snd_soc_ops imote2_asoc_ops = {
+ .hw_params = imote2_asoc_hw_params,
+};
+
+static struct snd_soc_dai_link imote2_dai = {
+ .name = "WM8940",
+ .stream_name = "WM8940",
+ .cpu_dai = &pxa_i2s_dai,
+ .codec_dai = &wm8940_dai,
+ .ops = &imote2_asoc_ops,
+};
+
+static struct snd_soc_card snd_soc_imote2 = {
+ .name = "Imote2",
+ .platform = &pxa2xx_soc_platform,
+ .dai_link = &imote2_dai,
+ .num_links = 1,
+};
+
+static struct snd_soc_device imote2_snd_devdata = {
+ .card = &snd_soc_imote2,
+ .codec_dev = &soc_codec_dev_wm8940,
+};
+
+static struct platform_device *imote2_snd_device;
+
+static int __init imote2_asoc_init(void)
+{
+ int ret;
+
+ if (!machine_is_intelmote2())
+ return -ENODEV;
+ imote2_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!imote2_snd_device)
+ return -ENOMEM;
+
+ platform_set_drvdata(imote2_snd_device, &imote2_snd_devdata);
+ imote2_snd_devdata.dev = &imote2_snd_device->dev;
+ ret = platform_device_add(imote2_snd_device);
+ if (ret)
+ platform_device_put(imote2_snd_device);
+
+ return ret;
+}
+module_init(imote2_asoc_init);
+
+static void __exit imote2_asoc_exit(void)
+{
+ platform_device_unregister(imote2_snd_device);
+}
+module_exit(imote2_asoc_exit);
+
+MODULE_AUTHOR("Jonathan Cameron");
+MODULE_DESCRIPTION("ALSA SoC Imote 2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 44fcc4e01e08..e6102fda0a7f 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -205,7 +205,7 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
int ret;
if (!(machine_is_palmtx() || machine_is_palmt5() ||
- machine_is_palmld()))
+ machine_is_palmld() || machine_is_palmte2()))
return -ENODEV;
if (pdev->dev.platform_data)
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 286be31545df..6fc787610ad7 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -50,139 +50,6 @@ struct ssp_priv {
#endif
};
-#define PXA2xx_SSP1_BASE 0x41000000
-#define PXA27x_SSP2_BASE 0x41700000
-#define PXA27x_SSP3_BASE 0x41900000
-#define PXA3xx_SSP4_BASE 0x41a00000
-
-static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_out = {
- .name = "SSP1 PCM Mono out",
- .dev_addr = PXA2xx_SSP1_BASE + SSDR,
- .drcmr = &DRCMR(14),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_in = {
- .name = "SSP1 PCM Mono in",
- .dev_addr = PXA2xx_SSP1_BASE + SSDR,
- .drcmr = &DRCMR(13),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_out = {
- .name = "SSP1 PCM Stereo out",
- .dev_addr = PXA2xx_SSP1_BASE + SSDR,
- .drcmr = &DRCMR(14),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST16 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_in = {
- .name = "SSP1 PCM Stereo in",
- .dev_addr = PXA2xx_SSP1_BASE + SSDR,
- .drcmr = &DRCMR(13),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST16 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_out = {
- .name = "SSP2 PCM Mono out",
- .dev_addr = PXA27x_SSP2_BASE + SSDR,
- .drcmr = &DRCMR(16),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_in = {
- .name = "SSP2 PCM Mono in",
- .dev_addr = PXA27x_SSP2_BASE + SSDR,
- .drcmr = &DRCMR(15),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_out = {
- .name = "SSP2 PCM Stereo out",
- .dev_addr = PXA27x_SSP2_BASE + SSDR,
- .drcmr = &DRCMR(16),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST16 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_in = {
- .name = "SSP2 PCM Stereo in",
- .dev_addr = PXA27x_SSP2_BASE + SSDR,
- .drcmr = &DRCMR(15),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST16 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_out = {
- .name = "SSP3 PCM Mono out",
- .dev_addr = PXA27x_SSP3_BASE + SSDR,
- .drcmr = &DRCMR(67),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_in = {
- .name = "SSP3 PCM Mono in",
- .dev_addr = PXA27x_SSP3_BASE + SSDR,
- .drcmr = &DRCMR(66),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_out = {
- .name = "SSP3 PCM Stereo out",
- .dev_addr = PXA27x_SSP3_BASE + SSDR,
- .drcmr = &DRCMR(67),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST16 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_in = {
- .name = "SSP3 PCM Stereo in",
- .dev_addr = PXA27x_SSP3_BASE + SSDR,
- .drcmr = &DRCMR(66),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST16 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_out = {
- .name = "SSP4 PCM Mono out",
- .dev_addr = PXA3xx_SSP4_BASE + SSDR,
- .drcmr = &DRCMR(67),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_in = {
- .name = "SSP4 PCM Mono in",
- .dev_addr = PXA3xx_SSP4_BASE + SSDR,
- .drcmr = &DRCMR(66),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_out = {
- .name = "SSP4 PCM Stereo out",
- .dev_addr = PXA3xx_SSP4_BASE + SSDR,
- .drcmr = &DRCMR(67),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST16 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_in = {
- .name = "SSP4 PCM Stereo in",
- .dev_addr = PXA3xx_SSP4_BASE + SSDR,
- .drcmr = &DRCMR(66),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST16 | DCMD_WIDTH4,
-};
-
static void dump_registers(struct ssp_device *ssp)
{
dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
@@ -194,25 +61,33 @@ static void dump_registers(struct ssp_device *ssp)
ssp_read_reg(ssp, SSACD));
}
-static struct pxa2xx_pcm_dma_params *ssp_dma_params[4][4] = {
- {
- &pxa_ssp1_pcm_mono_out, &pxa_ssp1_pcm_mono_in,
- &pxa_ssp1_pcm_stereo_out, &pxa_ssp1_pcm_stereo_in,
- },
- {
- &pxa_ssp2_pcm_mono_out, &pxa_ssp2_pcm_mono_in,
- &pxa_ssp2_pcm_stereo_out, &pxa_ssp2_pcm_stereo_in,
- },
- {
- &pxa_ssp3_pcm_mono_out, &pxa_ssp3_pcm_mono_in,
- &pxa_ssp3_pcm_stereo_out, &pxa_ssp3_pcm_stereo_in,
- },
- {
- &pxa_ssp4_pcm_mono_out, &pxa_ssp4_pcm_mono_in,
- &pxa_ssp4_pcm_stereo_out, &pxa_ssp4_pcm_stereo_in,
- },
+struct pxa2xx_pcm_dma_data {
+ struct pxa2xx_pcm_dma_params params;
+ char name[20];
};
+static struct pxa2xx_pcm_dma_params *
+ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
+{
+ struct pxa2xx_pcm_dma_data *dma;
+
+ dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL);
+ if (dma == NULL)
+ return NULL;
+
+ snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id,
+ width4 ? "32-bit" : "16-bit", out ? "out" : "in");
+
+ dma->params.name = dma->name;
+ dma->params.drcmr = &DRCMR(out ? ssp->drcmr_tx : ssp->drcmr_rx);
+ dma->params.dcmd = (out ? (DCMD_INCSRCADDR | DCMD_FLOWTRG) :
+ (DCMD_INCTRGADDR | DCMD_FLOWSRC)) |
+ (width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16;
+ dma->params.dev_addr = ssp->phys_base + SSDR;
+
+ return &dma->params;
+}
+
static int pxa_ssp_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -227,6 +102,11 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
clk_enable(priv->dev.ssp->clk);
ssp_disable(&priv->dev);
}
+
+ if (cpu_dai->dma_data) {
+ kfree(cpu_dai->dma_data);
+ cpu_dai->dma_data = NULL;
+ }
return ret;
}
@@ -241,6 +121,11 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
ssp_disable(&priv->dev);
clk_disable(priv->dev.ssp->clk);
}
+
+ if (cpu_dai->dma_data) {
+ kfree(cpu_dai->dma_data);
+ cpu_dai->dma_data = NULL;
+ }
}
#ifdef CONFIG_PM
@@ -589,7 +474,10 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
case SND_SOC_DAIFMT_NB_IF:
break;
case SND_SOC_DAIFMT_IB_IF:
- sspsp |= SSPSP_SCMODE(3);
+ sspsp |= SSPSP_SCMODE(2);
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
break;
default:
return -EINVAL;
@@ -606,7 +494,13 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
case SND_SOC_DAIFMT_NB_NF:
sspsp |= SSPSP_SFRMP;
break;
+ case SND_SOC_DAIFMT_NB_IF:
+ break;
case SND_SOC_DAIFMT_IB_IF:
+ sspsp |= SSPSP_SCMODE(2);
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
break;
default:
return -EINVAL;
@@ -644,25 +538,23 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct ssp_priv *priv = cpu_dai->private_data;
struct ssp_device *ssp = priv->dev.ssp;
- int dma = 0, chn = params_channels(params);
+ int chn = params_channels(params);
u32 sscr0;
u32 sspsp;
int width = snd_pcm_format_physical_width(params_format(params));
int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
- /* select correct DMA params */
- if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
- dma = 1; /* capture DMA offset is 1,3 */
+ /* generate correct DMA params */
+ if (cpu_dai->dma_data)
+ kfree(cpu_dai->dma_data);
+
/* Network mode with one active slot (ttsa == 1) can be used
* to force 16-bit frame width on the wire (for S16_LE), even
* with two channels. Use 16-bit DMA transfers for this case.
*/
- if (((chn == 2) && (ttsa != 1)) || (width == 32))
- dma += 2; /* 32-bit DMA offset is 2, 16-bit is 0 */
-
- cpu_dai->dma_data = ssp_dma_params[cpu_dai->id][dma];
-
- dev_dbg(&ssp->pdev->dev, "pxa_ssp_hw_params: dma %d\n", dma);
+ cpu_dai->dma_data = ssp_get_dma_params(ssp,
+ ((chn == 2) && (ttsa != 1)) || (width == 32),
+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
/* we can only change the settings if the port is not in use */
if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 2f4b6e489b78..60145770aeba 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -329,6 +329,7 @@ struct snd_soc_dai pxa_i2s_dai = {
.rates = PXA2XX_I2S_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.ops = &pxa_i2s_dai_ops,
+ .symmetric_rates = 1,
};
EXPORT_SYMBOL_GPL(pxa_i2s_dai);
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index ab680aac3fcb..972c27684198 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -37,6 +37,20 @@
#include "s3c-i2s-v2.h"
+#undef S3C_IIS_V2_SUPPORTED
+
+#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
+#define S3C_IIS_V2_SUPPORTED
+#endif
+
+#ifdef CONFIG_PLAT_S3C64XX
+#define S3C_IIS_V2_SUPPORTED
+#endif
+
+#ifndef S3C_IIS_V2_SUPPORTED
+#error Unsupported CPU model
+#endif
+
#define S3C2412_I2S_DEBUG_CON 0
static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
@@ -75,7 +89,7 @@ static inline void dbg_showcon(const char *fn, u32 con)
/* Turn on or off the transmission path. */
-void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
+static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
{
void __iomem *regs = i2s->regs;
u32 fic, con, mod;
@@ -105,7 +119,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
break;
default:
- dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n");
+ dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n",
+ mod & S3C2412_IISMOD_MODE_MASK);
+ break;
}
writel(con, regs + S3C2412_IISCON);
@@ -132,7 +148,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
break;
default:
- dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n");
+ dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n",
+ mod & S3C2412_IISMOD_MODE_MASK);
+ break;
}
writel(mod, regs + S3C2412_IISMOD);
@@ -143,9 +161,8 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
dbg_showcon(__func__, con);
pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
}
-EXPORT_SYMBOL_GPL(s3c2412_snd_txctrl);
-void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
+static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
{
void __iomem *regs = i2s->regs;
u32 fic, con, mod;
@@ -175,7 +192,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
break;
default:
- dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n");
+ dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n",
+ mod & S3C2412_IISMOD_MODE_MASK);
}
writel(mod, regs + S3C2412_IISMOD);
@@ -199,7 +217,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
break;
default:
- dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n");
+ dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n",
+ mod & S3C2412_IISMOD_MODE_MASK);
}
writel(con, regs + S3C2412_IISCON);
@@ -209,7 +228,6 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
fic = readl(regs + S3C2412_IISFIC);
pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
}
-EXPORT_SYMBOL_GPL(s3c2412_snd_rxctrl);
/*
* Wait for the LR signal to allow synchronisation to the L/R clock
@@ -266,7 +284,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
*/
#define IISMOD_MASTER_MASK (1 << 11)
#define IISMOD_SLAVE (1 << 11)
-#define IISMOD_MASTER (0x0)
+#define IISMOD_MASTER (0 << 11)
#endif
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -281,7 +299,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
iismod |= IISMOD_MASTER;
break;
default:
- pr_debug("unknwon master/slave format\n");
+ pr_err("unknwon master/slave format\n");
return -EINVAL;
}
@@ -298,7 +316,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
iismod |= S3C2412_IISMOD_SDF_IIS;
break;
default:
- pr_debug("Unknown data format\n");
+ pr_err("Unknown data format\n");
return -EINVAL;
}
@@ -327,6 +345,7 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
iismod = readl(i2s->regs + S3C2412_IISMOD);
pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
+#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8:
iismod |= S3C2412_IISMOD_8BIT;
@@ -335,6 +354,25 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
iismod &= ~S3C2412_IISMOD_8BIT;
break;
}
+#endif
+
+#ifdef CONFIG_PLAT_S3C64XX
+ iismod &= ~0x606;
+ /* Sample size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S8:
+ /* 8 bit sample, 16fs BCLK */
+ iismod |= 0x2004;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ /* 16 bit sample, 32fs BCLK */
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ /* 24 bit sample, 48fs BCLK */
+ iismod |= 0x4002;
+ break;
+ }
+#endif
writel(iismod, i2s->regs + S3C2412_IISMOD);
pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
@@ -489,6 +527,8 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
unsigned int best_rate = 0;
unsigned int best_deviation = INT_MAX;
+ pr_debug("Input clock rate %ldHz\n", clkrate);
+
if (fstab == NULL)
fstab = iis_fs_tab;
@@ -539,12 +579,31 @@ int s3c_i2sv2_probe(struct platform_device *pdev,
unsigned long base)
{
struct device *dev = &pdev->dev;
+ unsigned int iismod;
i2s->dev = dev;
/* record our i2s structure for later use in the callbacks */
dai->private_data = i2s;
+ if (!base) {
+ struct resource *res = platform_get_resource(pdev,
+ IORESOURCE_MEM,
+ 0);
+ if (!res) {
+ dev_err(dev, "Unable to get register resource\n");
+ return -ENXIO;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res),
+ "s3c64xx-i2s-v4")) {
+ dev_err(dev, "Unable to request register region\n");
+ return -EBUSY;
+ }
+
+ base = res->start;
+ }
+
i2s->regs = ioremap(base, 0x100);
if (i2s->regs == NULL) {
dev_err(dev, "cannot ioremap registers\n");
@@ -560,12 +619,16 @@ int s3c_i2sv2_probe(struct platform_device *pdev,
clk_enable(i2s->iis_pclk);
+ /* Mark ourselves as in TXRX mode so we can run through our cleanup
+ * process without warnings. */
+ iismod = readl(i2s->regs + S3C2412_IISMOD);
+ iismod |= S3C2412_IISMOD_MODE_TXRX;
+ writel(iismod, i2s->regs + S3C2412_IISMOD);
s3c2412_snd_txctrl(i2s, 0);
s3c2412_snd_rxctrl(i2s, 0);
return 0;
}
-
EXPORT_SYMBOL_GPL(s3c_i2sv2_probe);
#ifdef CONFIG_PM
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index b7e0b3f0bfc8..168a088ba761 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -120,7 +120,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk");
if (s3c2412_i2s.iis_cclk == NULL) {
- pr_debug("failed to get i2sclk clock\n");
+ pr_err("failed to get i2sclk clock\n");
iounmap(s3c2412_i2s.regs);
return -ENODEV;
}
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 33c5de7e255f..3c06c401d0fb 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -108,48 +108,19 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
return 0;
}
-
-unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai)
+struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
{
struct s3c_i2sv2_info *i2s = to_info(dai);
- return clk_get_rate(i2s->iis_cclk);
+ return i2s->iis_cclk;
}
-EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate);
+EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
static int s3c64xx_i2s_probe(struct platform_device *pdev,
struct snd_soc_dai *dai)
{
- struct device *dev = &pdev->dev;
- struct s3c_i2sv2_info *i2s;
- int ret;
-
- dev_dbg(dev, "%s: probing dai %d\n", __func__, pdev->id);
-
- if (pdev->id < 0 || pdev->id > ARRAY_SIZE(s3c64xx_i2s)) {
- dev_err(dev, "id %d out of range\n", pdev->id);
- return -EINVAL;
- }
-
- i2s = &s3c64xx_i2s[pdev->id];
-
- ret = s3c_i2sv2_probe(pdev, dai, i2s,
- pdev->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0);
- if (ret)
- return ret;
-
- i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
- i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
-
- i2s->iis_cclk = clk_get(dev, "audio-bus");
- if (IS_ERR(i2s->iis_cclk)) {
- dev_err(dev, "failed to get audio-bus");
- iounmap(i2s->regs);
- return -ENODEV;
- }
-
/* configure GPIO for i2s port */
- switch (pdev->id) {
+ switch (dai->id) {
case 0:
s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK);
s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK);
@@ -175,41 +146,122 @@ static int s3c64xx_i2s_probe(struct platform_device *pdev,
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
#define S3C64XX_I2S_FMTS \
- (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE)
+ (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE)
static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
.set_sysclk = s3c64xx_i2s_set_sysclk,
};
-struct snd_soc_dai s3c64xx_i2s_dai = {
- .name = "s3c64xx-i2s",
- .id = 0,
- .probe = s3c64xx_i2s_probe,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,
+struct snd_soc_dai s3c64xx_i2s_dai[] = {
+ {
+ .name = "s3c64xx-i2s",
+ .id = 0,
+ .probe = s3c64xx_i2s_probe,
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = S3C64XX_I2S_RATES,
+ .formats = S3C64XX_I2S_FMTS,
+ },
+ .capture = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = S3C64XX_I2S_RATES,
+ .formats = S3C64XX_I2S_FMTS,
+ },
+ .ops = &s3c64xx_i2s_dai_ops,
+ .symmetric_rates = 1,
},
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,
+ {
+ .name = "s3c64xx-i2s",
+ .id = 1,
+ .probe = s3c64xx_i2s_probe,
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = S3C64XX_I2S_RATES,
+ .formats = S3C64XX_I2S_FMTS,
+ },
+ .capture = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = S3C64XX_I2S_RATES,
+ .formats = S3C64XX_I2S_FMTS,
+ },
+ .ops = &s3c64xx_i2s_dai_ops,
+ .symmetric_rates = 1,
},
- .ops = &s3c64xx_i2s_dai_ops,
};
EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
+static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
+{
+ struct s3c_i2sv2_info *i2s;
+ struct snd_soc_dai *dai;
+ int ret;
+
+ if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) {
+ dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
+ return -EINVAL;
+ }
+
+ i2s = &s3c64xx_i2s[pdev->id];
+ dai = &s3c64xx_i2s_dai[pdev->id];
+ dai->dev = &pdev->dev;
+
+ i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
+ i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
+
+ i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
+ if (IS_ERR(i2s->iis_cclk)) {
+ dev_err(&pdev->dev, "failed to get audio-bus\n");
+ ret = PTR_ERR(i2s->iis_cclk);
+ goto err;
+ }
+
+ ret = s3c_i2sv2_probe(pdev, dai, i2s, 0);
+ if (ret)
+ goto err_clk;
+
+ ret = s3c_i2sv2_register_dai(dai);
+ if (ret != 0)
+ goto err_i2sv2;
+
+ return 0;
+
+err_i2sv2:
+ /* Not implemented for I2Sv2 core yet */
+err_clk:
+ clk_put(i2s->iis_cclk);
+err:
+ return ret;
+}
+
+static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev)
+{
+ dev_err(&pdev->dev, "Device removal not yet supported\n");
+ return 0;
+}
+
+static struct platform_driver s3c64xx_iis_driver = {
+ .probe = s3c64xx_iis_dev_probe,
+ .remove = s3c64xx_iis_dev_remove,
+ .driver = {
+ .name = "s3c64xx-iis",
+ .owner = THIS_MODULE,
+ },
+};
+
static int __init s3c64xx_i2s_init(void)
{
- return s3c_i2sv2_register_dai(&s3c64xx_i2s_dai);
+ return platform_driver_register(&s3c64xx_iis_driver);
}
module_init(s3c64xx_i2s_init);
static void __exit s3c64xx_i2s_exit(void)
{
- snd_soc_unregister_dai(&s3c64xx_i2s_dai);
+ platform_driver_unregister(&s3c64xx_iis_driver);
}
module_exit(s3c64xx_i2s_exit);
@@ -217,6 +269,3 @@ module_exit(s3c64xx_i2s_exit);
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_DESCRIPTION("S3C64XX I2S SoC Interface");
MODULE_LICENSE("GPL");
-
-
-
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
index b7ffe3c38b66..02148cee2613 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -15,6 +15,8 @@
#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H
#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__
+struct clk;
+
#include "s3c-i2s-v2.h"
#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK
@@ -24,8 +26,8 @@
#define S3C64XX_CLKSRC_PCLK (0)
#define S3C64XX_CLKSRC_MUX (1)
-extern struct snd_soc_dai s3c64xx_i2s_dai;
+extern struct snd_soc_dai s3c64xx_i2s_dai[];
-extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai);
+extern struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai);
#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */
diff --git a/sound/soc/s6000/Kconfig b/sound/soc/s6000/Kconfig
new file mode 100644
index 000000000000..c74eb3d4a47c
--- /dev/null
+++ b/sound/soc/s6000/Kconfig
@@ -0,0 +1,19 @@
+config SND_S6000_SOC
+ tristate "SoC Audio for the Stretch s6000 family"
+ depends on XTENSA_VARIANT_S6000
+ help
+ Say Y or M if you want to add support for codecs attached to
+ s6000 family chips. You will also need to select the platform
+ to support below.
+
+config SND_S6000_SOC_I2S
+ tristate
+
+config SND_S6000_SOC_S6IPCAM
+ tristate "SoC Audio support for Stretch 6105 IP Camera"
+ depends on SND_S6000_SOC && XTENSA_PLATFORM_S6105
+ select SND_S6000_SOC_I2S
+ select SND_SOC_TLV320AIC3X
+ help
+ Say Y if you want to add support for SoC audio on the
+ Stretch s6105 IP Camera Reference Design.
diff --git a/sound/soc/s6000/Makefile b/sound/soc/s6000/Makefile
new file mode 100644
index 000000000000..7a613612e010
--- /dev/null
+++ b/sound/soc/s6000/Makefile
@@ -0,0 +1,11 @@
+# s6000 Platform Support
+snd-soc-s6000-objs := s6000-pcm.o
+snd-soc-s6000-i2s-objs := s6000-i2s.o
+
+obj-$(CONFIG_SND_S6000_SOC) += snd-soc-s6000.o
+obj-$(CONFIG_SND_S6000_SOC_I2S) += snd-soc-s6000-i2s.o
+
+# s6105 Machine Support
+snd-soc-s6ipcam-objs := s6105-ipcam.o
+
+obj-$(CONFIG_SND_S6000_SOC_S6IPCAM) += snd-soc-s6ipcam.o
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
new file mode 100644
index 000000000000..c5cda187ecab
--- /dev/null
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -0,0 +1,629 @@
+/*
+ * ALSA SoC I2S Audio Layer for the Stretch S6000 family
+ *
+ * Author: Daniel Gloeckner, <dg@emlix.com>
+ * Copyright: (C) 2009 emlix GmbH <info@emlix.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/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+
+#include "s6000-i2s.h"
+#include "s6000-pcm.h"
+
+struct s6000_i2s_dev {
+ dma_addr_t sifbase;
+ u8 __iomem *scbbase;
+ unsigned int wide;
+ unsigned int channel_in;
+ unsigned int channel_out;
+ unsigned int lines_in;
+ unsigned int lines_out;
+ struct s6000_pcm_dma_params dma_params;
+};
+
+#define S6_I2S_INTERRUPT_STATUS 0x00
+#define S6_I2S_INT_OVERRUN 1
+#define S6_I2S_INT_UNDERRUN 2
+#define S6_I2S_INT_ALIGNMENT 4
+#define S6_I2S_INTERRUPT_ENABLE 0x04
+#define S6_I2S_INTERRUPT_RAW 0x08
+#define S6_I2S_INTERRUPT_CLEAR 0x0C
+#define S6_I2S_INTERRUPT_SET 0x10
+#define S6_I2S_MODE 0x20
+#define S6_I2S_DUAL 0
+#define S6_I2S_WIDE 1
+#define S6_I2S_TX_DEFAULT 0x24
+#define S6_I2S_DATA_CFG(c) (0x40 + 0x10 * (c))
+#define S6_I2S_IN 0
+#define S6_I2S_OUT 1
+#define S6_I2S_UNUSED 2
+#define S6_I2S_INTERFACE_CFG(c) (0x44 + 0x10 * (c))
+#define S6_I2S_DIV_MASK 0x001fff
+#define S6_I2S_16BIT 0x000000
+#define S6_I2S_20BIT 0x002000
+#define S6_I2S_24BIT 0x004000
+#define S6_I2S_32BIT 0x006000
+#define S6_I2S_BITS_MASK 0x006000
+#define S6_I2S_MEM_16BIT 0x000000
+#define S6_I2S_MEM_32BIT 0x008000
+#define S6_I2S_MEM_MASK 0x008000
+#define S6_I2S_CHANNELS_SHIFT 16
+#define S6_I2S_CHANNELS_MASK 0x030000
+#define S6_I2S_SCK_IN 0x000000
+#define S6_I2S_SCK_OUT 0x040000
+#define S6_I2S_SCK_DIR 0x040000
+#define S6_I2S_WS_IN 0x000000
+#define S6_I2S_WS_OUT 0x080000
+#define S6_I2S_WS_DIR 0x080000
+#define S6_I2S_LEFT_FIRST 0x000000
+#define S6_I2S_RIGHT_FIRST 0x100000
+#define S6_I2S_FIRST 0x100000
+#define S6_I2S_CUR_SCK 0x200000
+#define S6_I2S_CUR_WS 0x400000
+#define S6_I2S_ENABLE(c) (0x48 + 0x10 * (c))
+#define S6_I2S_DISABLE_IF 0x02
+#define S6_I2S_ENABLE_IF 0x03
+#define S6_I2S_IS_BUSY 0x04
+#define S6_I2S_DMA_ACTIVE 0x08
+#define S6_I2S_IS_ENABLED 0x10
+
+#define S6_I2S_NUM_LINES 4
+
+#define S6_I2S_SIF_PORT0 0x0000000
+#define S6_I2S_SIF_PORT1 0x0000080 /* docs say 0x0000010 */
+
+static inline void s6_i2s_write_reg(struct s6000_i2s_dev *dev, int reg, u32 val)
+{
+ writel(val, dev->scbbase + reg);
+}
+
+static inline u32 s6_i2s_read_reg(struct s6000_i2s_dev *dev, int reg)
+{
+ return readl(dev->scbbase + reg);
+}
+
+static inline void s6_i2s_mod_reg(struct s6000_i2s_dev *dev, int reg,
+ u32 mask, u32 val)
+{
+ val ^= s6_i2s_read_reg(dev, reg) & ~mask;
+ s6_i2s_write_reg(dev, reg, val);
+}
+
+static void s6000_i2s_start_channel(struct s6000_i2s_dev *dev, int channel)
+{
+ int i, j, cur, prev;
+
+ /*
+ * Wait for WCLK to toggle 5 times before enabling the channel
+ * s6000 Family Datasheet 3.6.4:
+ * "At least two cycles of WS must occur between commands
+ * to disable or enable the interface"
+ */
+ j = 0;
+ prev = ~S6_I2S_CUR_WS;
+ for (i = 1000000; --i && j < 6; ) {
+ cur = s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(channel))
+ & S6_I2S_CUR_WS;
+ if (prev != cur) {
+ prev = cur;
+ j++;
+ }
+ }
+ if (j < 6)
+ printk(KERN_WARNING "s6000-i2s: timeout waiting for WCLK\n");
+
+ s6_i2s_write_reg(dev, S6_I2S_ENABLE(channel), S6_I2S_ENABLE_IF);
+}
+
+static void s6000_i2s_stop_channel(struct s6000_i2s_dev *dev, int channel)
+{
+ s6_i2s_write_reg(dev, S6_I2S_ENABLE(channel), S6_I2S_DISABLE_IF);
+}
+
+static void s6000_i2s_start(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data;
+ int channel;
+
+ channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+ dev->channel_out : dev->channel_in;
+
+ s6000_i2s_start_channel(dev, channel);
+}
+
+static void s6000_i2s_stop(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data;
+ int channel;
+
+ channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+ dev->channel_out : dev->channel_in;
+
+ s6000_i2s_stop_channel(dev, channel);
+}
+
+static int s6000_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+ int after)
+{
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ^ !after)
+ s6000_i2s_start(substream);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (!after)
+ s6000_i2s_stop(substream);
+ }
+ return 0;
+}
+
+static unsigned int s6000_i2s_int_sources(struct s6000_i2s_dev *dev)
+{
+ unsigned int pending;
+ pending = s6_i2s_read_reg(dev, S6_I2S_INTERRUPT_RAW);
+ pending &= S6_I2S_INT_ALIGNMENT |
+ S6_I2S_INT_UNDERRUN |
+ S6_I2S_INT_OVERRUN;
+ s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR, pending);
+
+ return pending;
+}
+
+static unsigned int s6000_i2s_check_xrun(struct snd_soc_dai *cpu_dai)
+{
+ struct s6000_i2s_dev *dev = cpu_dai->private_data;
+ unsigned int errors;
+ unsigned int ret;
+
+ errors = s6000_i2s_int_sources(dev);
+ if (likely(!errors))
+ return 0;
+
+ ret = 0;
+ if (errors & S6_I2S_INT_ALIGNMENT)
+ printk(KERN_ERR "s6000-i2s: WCLK misaligned\n");
+ if (errors & S6_I2S_INT_UNDERRUN)
+ ret |= 1 << SNDRV_PCM_STREAM_PLAYBACK;
+ if (errors & S6_I2S_INT_OVERRUN)
+ ret |= 1 << SNDRV_PCM_STREAM_CAPTURE;
+ return ret;
+}
+
+static void s6000_i2s_wait_disabled(struct s6000_i2s_dev *dev)
+{
+ int channel;
+ int n = 50;
+ for (channel = 0; channel < 2; channel++) {
+ while (--n >= 0) {
+ int v = s6_i2s_read_reg(dev, S6_I2S_ENABLE(channel));
+ if ((v & S6_I2S_IS_ENABLED)
+ || !(v & (S6_I2S_DMA_ACTIVE | S6_I2S_IS_BUSY)))
+ break;
+ udelay(20);
+ }
+ }
+ if (n < 0)
+ printk(KERN_WARNING "s6000-i2s: timeout disabling interfaces");
+}
+
+static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+ unsigned int fmt)
+{
+ struct s6000_i2s_dev *dev = cpu_dai->private_data;
+ u32 w;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ w = S6_I2S_SCK_IN | S6_I2S_WS_IN;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ w = S6_I2S_SCK_OUT | S6_I2S_WS_IN;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ w = S6_I2S_SCK_IN | S6_I2S_WS_OUT;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ w = S6_I2S_SCK_OUT | S6_I2S_WS_OUT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ w |= S6_I2S_LEFT_FIRST;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ w |= S6_I2S_RIGHT_FIRST;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(0),
+ S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w);
+ s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(1),
+ S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w);
+
+ return 0;
+}
+
+static int s6000_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
+{
+ struct s6000_i2s_dev *dev = dai->private_data;
+
+ if (!div || (div & 1) || div > (S6_I2S_DIV_MASK + 1) * 2)
+ return -EINVAL;
+
+ s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(div_id),
+ S6_I2S_DIV_MASK, div / 2 - 1);
+ return 0;
+}
+
+static int s6000_i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct s6000_i2s_dev *dev = dai->private_data;
+ int interf;
+ u32 w = 0;
+
+ if (dev->wide)
+ interf = 0;
+ else {
+ w |= (((params_channels(params) - 2) / 2)
+ << S6_I2S_CHANNELS_SHIFT) & S6_I2S_CHANNELS_MASK;
+ interf = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ ? dev->channel_out : dev->channel_in;
+ }
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ w |= S6_I2S_16BIT | S6_I2S_MEM_16BIT;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ w |= S6_I2S_32BIT | S6_I2S_MEM_32BIT;
+ break;
+ default:
+ printk(KERN_WARNING "s6000-i2s: unsupported PCM format %x\n",
+ params_format(params));
+ return -EINVAL;
+ }
+
+ if (s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(interf))
+ & S6_I2S_IS_ENABLED) {
+ printk(KERN_ERR "s6000-i2s: interface already enabled\n");
+ return -EBUSY;
+ }
+
+ s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(interf),
+ S6_I2S_CHANNELS_MASK|S6_I2S_MEM_MASK|S6_I2S_BITS_MASK,
+ w);
+
+ return 0;
+}
+
+static int s6000_i2s_dai_probe(struct platform_device *pdev,
+ struct snd_soc_dai *dai)
+{
+ struct s6000_i2s_dev *dev = dai->private_data;
+ struct s6000_snd_platform_data *pdata = pdev->dev.platform_data;
+
+ if (!pdata)
+ return -EINVAL;
+
+ dev->wide = pdata->wide;
+ dev->channel_in = pdata->channel_in;
+ dev->channel_out = pdata->channel_out;
+ dev->lines_in = pdata->lines_in;
+ dev->lines_out = pdata->lines_out;
+
+ s6_i2s_write_reg(dev, S6_I2S_MODE,
+ dev->wide ? S6_I2S_WIDE : S6_I2S_DUAL);
+
+ if (dev->wide) {
+ int i;
+
+ if (dev->lines_in + dev->lines_out > S6_I2S_NUM_LINES)
+ return -EINVAL;
+
+ dev->channel_in = 0;
+ dev->channel_out = 1;
+ dai->capture.channels_min = 2 * dev->lines_in;
+ dai->capture.channels_max = dai->capture.channels_min;
+ dai->playback.channels_min = 2 * dev->lines_out;
+ dai->playback.channels_max = dai->playback.channels_min;
+
+ for (i = 0; i < dev->lines_out; i++)
+ s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_OUT);
+
+ for (; i < S6_I2S_NUM_LINES - dev->lines_in; i++)
+ s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i),
+ S6_I2S_UNUSED);
+
+ for (; i < S6_I2S_NUM_LINES; i++)
+ s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_IN);
+ } else {
+ unsigned int cfg[2] = {S6_I2S_UNUSED, S6_I2S_UNUSED};
+
+ if (dev->lines_in > 1 || dev->lines_out > 1)
+ return -EINVAL;
+
+ dai->capture.channels_min = 2 * dev->lines_in;
+ dai->capture.channels_max = 8 * dev->lines_in;
+ dai->playback.channels_min = 2 * dev->lines_out;
+ dai->playback.channels_max = 8 * dev->lines_out;
+
+ if (dev->lines_in)
+ cfg[dev->channel_in] = S6_I2S_IN;
+ if (dev->lines_out)
+ cfg[dev->channel_out] = S6_I2S_OUT;
+
+ s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(0), cfg[0]);
+ s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(1), cfg[1]);
+ }
+
+ if (dev->lines_out) {
+ if (dev->lines_in) {
+ if (!dev->dma_params.dma_out)
+ return -ENODEV;
+ } else {
+ dev->dma_params.dma_out = dev->dma_params.dma_in;
+ dev->dma_params.dma_in = 0;
+ }
+ }
+ dev->dma_params.sif_in = dev->sifbase + (dev->channel_in ?
+ S6_I2S_SIF_PORT1 : S6_I2S_SIF_PORT0);
+ dev->dma_params.sif_out = dev->sifbase + (dev->channel_out ?
+ S6_I2S_SIF_PORT1 : S6_I2S_SIF_PORT0);
+ dev->dma_params.same_rate = pdata->same_rate | pdata->wide;
+ return 0;
+}
+
+#define S6000_I2S_RATES (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \
+ SNDRV_PCM_RATE_8000_192000)
+#define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops s6000_i2s_dai_ops = {
+ .set_fmt = s6000_i2s_set_dai_fmt,
+ .set_clkdiv = s6000_i2s_set_clkdiv,
+ .hw_params = s6000_i2s_hw_params,
+};
+
+struct snd_soc_dai s6000_i2s_dai = {
+ .name = "s6000-i2s",
+ .id = 0,
+ .probe = s6000_i2s_dai_probe,
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 8,
+ .formats = S6000_I2S_FORMATS,
+ .rates = S6000_I2S_RATES,
+ .rate_min = 0,
+ .rate_max = 1562500,
+ },
+ .capture = {
+ .channels_min = 2,
+ .channels_max = 8,
+ .formats = S6000_I2S_FORMATS,
+ .rates = S6000_I2S_RATES,
+ .rate_min = 0,
+ .rate_max = 1562500,
+ },
+ .ops = &s6000_i2s_dai_ops,
+}
+EXPORT_SYMBOL_GPL(s6000_i2s_dai);
+
+static int __devinit s6000_i2s_probe(struct platform_device *pdev)
+{
+ struct s6000_i2s_dev *dev;
+ struct resource *scbmem, *sifmem, *region, *dma1, *dma2;
+ u8 __iomem *mmio;
+ int ret;
+
+ scbmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!scbmem) {
+ dev_err(&pdev->dev, "no mem resource?\n");
+ ret = -ENODEV;
+ goto err_release_none;
+ }
+
+ region = request_mem_region(scbmem->start,
+ scbmem->end - scbmem->start + 1,
+ pdev->name);
+ if (!region) {
+ dev_err(&pdev->dev, "I2S SCB region already claimed\n");
+ ret = -EBUSY;
+ goto err_release_none;
+ }
+
+ mmio = ioremap(scbmem->start, scbmem->end - scbmem->start + 1);
+ if (!mmio) {
+ dev_err(&pdev->dev, "can't ioremap SCB region\n");
+ ret = -ENOMEM;
+ goto err_release_scb;
+ }
+
+ sifmem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!sifmem) {
+ dev_err(&pdev->dev, "no second mem resource?\n");
+ ret = -ENODEV;
+ goto err_release_map;
+ }
+
+ region = request_mem_region(sifmem->start,
+ sifmem->end - sifmem->start + 1,
+ pdev->name);
+ if (!region) {
+ dev_err(&pdev->dev, "I2S SIF region already claimed\n");
+ ret = -EBUSY;
+ goto err_release_map;
+ }
+
+ dma1 = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!dma1) {
+ dev_err(&pdev->dev, "no dma resource?\n");
+ ret = -ENODEV;
+ goto err_release_sif;
+ }
+
+ region = request_mem_region(dma1->start, dma1->end - dma1->start + 1,
+ pdev->name);
+ if (!region) {
+ dev_err(&pdev->dev, "I2S DMA region already claimed\n");
+ ret = -EBUSY;
+ goto err_release_sif;
+ }
+
+ dma2 = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (dma2) {
+ region = request_mem_region(dma2->start,
+ dma2->end - dma2->start + 1,
+ pdev->name);
+ if (!region) {
+ dev_err(&pdev->dev,
+ "I2S DMA region already claimed\n");
+ ret = -EBUSY;
+ goto err_release_dma1;
+ }
+ }
+
+ dev = kzalloc(sizeof(struct s6000_i2s_dev), GFP_KERNEL);
+ if (!dev) {
+ ret = -ENOMEM;
+ goto err_release_dma2;
+ }
+
+ s6000_i2s_dai.dev = &pdev->dev;
+ s6000_i2s_dai.private_data = dev;
+ s6000_i2s_dai.dma_data = &dev->dma_params;
+
+ dev->sifbase = sifmem->start;
+ dev->scbbase = mmio;
+
+ s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0);
+ s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR,
+ S6_I2S_INT_ALIGNMENT |
+ S6_I2S_INT_UNDERRUN |
+ S6_I2S_INT_OVERRUN);
+
+ s6000_i2s_stop_channel(dev, 0);
+ s6000_i2s_stop_channel(dev, 1);
+ s6000_i2s_wait_disabled(dev);
+
+ dev->dma_params.check_xrun = s6000_i2s_check_xrun;
+ dev->dma_params.trigger = s6000_i2s_trigger;
+ dev->dma_params.dma_in = dma1->start;
+ dev->dma_params.dma_out = dma2 ? dma2->start : 0;
+ dev->dma_params.irq = platform_get_irq(pdev, 0);
+ if (dev->dma_params.irq < 0) {
+ dev_err(&pdev->dev, "no irq resource?\n");
+ ret = -ENODEV;
+ goto err_release_dev;
+ }
+
+ s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE,
+ S6_I2S_INT_ALIGNMENT |
+ S6_I2S_INT_UNDERRUN |
+ S6_I2S_INT_OVERRUN);
+
+ ret = snd_soc_register_dai(&s6000_i2s_dai);
+ if (ret)
+ goto err_release_dev;
+
+ return 0;
+
+err_release_dev:
+ kfree(dev);
+err_release_dma2:
+ if (dma2)
+ release_mem_region(dma2->start, dma2->end - dma2->start + 1);
+err_release_dma1:
+ release_mem_region(dma1->start, dma1->end - dma1->start + 1);
+err_release_sif:
+ release_mem_region(sifmem->start, (sifmem->end - sifmem->start) + 1);
+err_release_map:
+ iounmap(mmio);
+err_release_scb:
+ release_mem_region(scbmem->start, (scbmem->end - scbmem->start) + 1);
+err_release_none:
+ return ret;
+}
+
+static void __devexit s6000_i2s_remove(struct platform_device *pdev)
+{
+ struct s6000_i2s_dev *dev = s6000_i2s_dai.private_data;
+ struct resource *region;
+ void __iomem *mmio = dev->scbbase;
+
+ snd_soc_unregister_dai(&s6000_i2s_dai);
+
+ s6000_i2s_stop_channel(dev, 0);
+ s6000_i2s_stop_channel(dev, 1);
+
+ s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0);
+ s6000_i2s_dai.private_data = 0;
+ kfree(dev);
+
+ region = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ release_mem_region(region->start, region->end - region->start + 1);
+
+ region = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (region)
+ release_mem_region(region->start,
+ region->end - region->start + 1);
+
+ region = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(region->start, (region->end - region->start) + 1);
+
+ iounmap(mmio);
+ region = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ release_mem_region(region->start, (region->end - region->start) + 1);
+}
+
+static struct platform_driver s6000_i2s_driver = {
+ .probe = s6000_i2s_probe,
+ .remove = __devexit_p(s6000_i2s_remove),
+ .driver = {
+ .name = "s6000-i2s",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init s6000_i2s_init(void)
+{
+ return platform_driver_register(&s6000_i2s_driver);
+}
+module_init(s6000_i2s_init);
+
+static void __exit s6000_i2s_exit(void)
+{
+ platform_driver_unregister(&s6000_i2s_driver);
+}
+module_exit(s6000_i2s_exit);
+
+MODULE_AUTHOR("Daniel Gloeckner");
+MODULE_DESCRIPTION("Stretch s6000 family I2S SoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/s6000/s6000-i2s.h b/sound/soc/s6000/s6000-i2s.h
new file mode 100644
index 000000000000..2375fdfe6dba
--- /dev/null
+++ b/sound/soc/s6000/s6000-i2s.h
@@ -0,0 +1,25 @@
+/*
+ * ALSA SoC I2S Audio Layer for the Stretch s6000 family
+ *
+ * Author: Daniel Gloeckner, <dg@emlix.com>
+ * Copyright: (C) 2009 emlix GmbH <info@emlix.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 _S6000_I2S_H
+#define _S6000_I2S_H
+
+extern struct snd_soc_dai s6000_i2s_dai;
+
+struct s6000_snd_platform_data {
+ int lines_in;
+ int lines_out;
+ int channel_in;
+ int channel_out;
+ int wide;
+ int same_rate;
+};
+#endif
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
new file mode 100644
index 000000000000..83b8028e209d
--- /dev/null
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -0,0 +1,497 @@
+/*
+ * ALSA PCM interface for the Stetch s6000 family
+ *
+ * Author: Daniel Gloeckner, <dg@emlix.com>
+ * Copyright: (C) 2009 emlix GmbH <info@emlix.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/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <asm/dma.h>
+#include <variant/dmac.h>
+
+#include "s6000-pcm.h"
+
+#define S6_PCM_PREALLOCATE_SIZE (96 * 1024)
+#define S6_PCM_PREALLOCATE_MAX (2048 * 1024)
+
+static struct snd_pcm_hardware s6000_pcm_hardware = {
+ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_JOINT_DUPLEX),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE),
+ .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \
+ SNDRV_PCM_RATE_8000_192000),
+ .rate_min = 0,
+ .rate_max = 1562500,
+ .channels_min = 2,
+ .channels_max = 8,
+ .buffer_bytes_max = 0x7ffffff0,
+ .period_bytes_min = 16,
+ .period_bytes_max = 0xfffff0,
+ .periods_min = 2,
+ .periods_max = 1024, /* no limit */
+ .fifo_size = 0,
+};
+
+struct s6000_runtime_data {
+ spinlock_t lock;
+ int period; /* current DMA period */
+};
+
+static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s6000_runtime_data *prtd = runtime->private_data;
+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+ struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ int channel;
+ unsigned int period_size;
+ unsigned int dma_offset;
+ dma_addr_t dma_pos;
+ dma_addr_t src, dst;
+
+ period_size = snd_pcm_lib_period_bytes(substream);
+ dma_offset = prtd->period * period_size;
+ dma_pos = runtime->dma_addr + dma_offset;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ src = dma_pos;
+ dst = par->sif_out;
+ channel = par->dma_out;
+ } else {
+ src = par->sif_in;
+ dst = dma_pos;
+ channel = par->dma_in;
+ }
+
+ if (!s6dmac_channel_enabled(DMA_MASK_DMAC(channel),
+ DMA_INDEX_CHNL(channel)))
+ return;
+
+ if (s6dmac_fifo_full(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel))) {
+ printk(KERN_ERR "s6000-pcm: fifo full\n");
+ return;
+ }
+
+ BUG_ON(period_size & 15);
+ s6dmac_put_fifo(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel),
+ src, dst, period_size);
+
+ prtd->period++;
+ if (unlikely(prtd->period >= runtime->periods))
+ prtd->period = 0;
+}
+
+static irqreturn_t s6000_pcm_irq(int irq, void *data)
+{
+ struct snd_pcm *pcm = data;
+ struct snd_soc_pcm_runtime *runtime = pcm->private_data;
+ struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+ struct s6000_runtime_data *prtd;
+ unsigned int has_xrun;
+ int i, ret = IRQ_NONE;
+ u32 channel[2] = {
+ [SNDRV_PCM_STREAM_PLAYBACK] = params->dma_out,
+ [SNDRV_PCM_STREAM_CAPTURE] = params->dma_in
+ };
+
+ has_xrun = params->check_xrun(runtime->dai->cpu_dai);
+
+ for (i = 0; i < ARRAY_SIZE(channel); ++i) {
+ struct snd_pcm_substream *substream = pcm->streams[i].substream;
+ unsigned int pending;
+
+ if (!channel[i])
+ continue;
+
+ if (unlikely(has_xrun & (1 << i)) &&
+ substream->runtime &&
+ snd_pcm_running(substream)) {
+ dev_dbg(pcm->dev, "xrun\n");
+ snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
+ ret = IRQ_HANDLED;
+ }
+
+ pending = s6dmac_int_sources(DMA_MASK_DMAC(channel[i]),
+ DMA_INDEX_CHNL(channel[i]));
+
+ if (pending & 1) {
+ ret = IRQ_HANDLED;
+ if (likely(substream->runtime &&
+ snd_pcm_running(substream))) {
+ snd_pcm_period_elapsed(substream);
+ dev_dbg(pcm->dev, "period elapsed %x %x\n",
+ s6dmac_cur_src(DMA_MASK_DMAC(channel[i]),
+ DMA_INDEX_CHNL(channel[i])),
+ s6dmac_cur_dst(DMA_MASK_DMAC(channel[i]),
+ DMA_INDEX_CHNL(channel[i])));
+ prtd = substream->runtime->private_data;
+ spin_lock(&prtd->lock);
+ s6000_pcm_enqueue_dma(substream);
+ spin_unlock(&prtd->lock);
+ }
+ }
+
+ if (unlikely(pending & ~7)) {
+ if (pending & (1 << 3))
+ printk(KERN_WARNING
+ "s6000-pcm: DMA %x Underflow\n",
+ channel[i]);
+ if (pending & (1 << 4))
+ printk(KERN_WARNING
+ "s6000-pcm: DMA %x Overflow\n",
+ channel[i]);
+ if (pending & 0x1e0)
+ printk(KERN_WARNING
+ "s6000-pcm: DMA %x Master Error "
+ "(mask %x)\n",
+ channel[i], pending >> 5);
+
+ }
+ }
+
+ return ret;
+}
+
+static int s6000_pcm_start(struct snd_pcm_substream *substream)
+{
+ struct s6000_runtime_data *prtd = substream->runtime->private_data;
+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+ struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ unsigned long flags;
+ int srcinc;
+ u32 dma;
+
+ spin_lock_irqsave(&prtd->lock, flags);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ srcinc = 1;
+ dma = par->dma_out;
+ } else {
+ srcinc = 0;
+ dma = par->dma_in;
+ }
+ s6dmac_enable_chan(DMA_MASK_DMAC(dma), DMA_INDEX_CHNL(dma),
+ 1 /* priority 1 (0 is max) */,
+ 0 /* peripheral requests w/o xfer length mode */,
+ srcinc /* source address increment */,
+ srcinc^1 /* destination address increment */,
+ 0 /* chunksize 0 (skip impossible on this dma) */,
+ 0 /* source skip after chunk (impossible) */,
+ 0 /* destination skip after chunk (impossible) */,
+ 4 /* 16 byte burst size */,
+ -1 /* don't conserve bandwidth */,
+ 0 /* low watermark irq descriptor theshold */,
+ 0 /* disable hardware timestamps */,
+ 1 /* enable channel */);
+
+ s6000_pcm_enqueue_dma(substream);
+ s6000_pcm_enqueue_dma(substream);
+
+ spin_unlock_irqrestore(&prtd->lock, flags);
+
+ return 0;
+}
+
+static int s6000_pcm_stop(struct snd_pcm_substream *substream)
+{
+ struct s6000_runtime_data *prtd = substream->runtime->private_data;
+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+ struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ unsigned long flags;
+ u32 channel;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ channel = par->dma_out;
+ else
+ channel = par->dma_in;
+
+ s6dmac_set_terminal_count(DMA_MASK_DMAC(channel),
+ DMA_INDEX_CHNL(channel), 0);
+
+ spin_lock_irqsave(&prtd->lock, flags);
+
+ s6dmac_disable_chan(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel));
+
+ spin_unlock_irqrestore(&prtd->lock, flags);
+
+ return 0;
+}
+
+static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+ struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ int ret;
+
+ ret = par->trigger(substream, cmd, 0);
+ if (ret < 0)
+ return ret;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ret = s6000_pcm_start(substream);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ ret = s6000_pcm_stop(substream);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ if (ret < 0)
+ return ret;
+
+ return par->trigger(substream, cmd, 1);
+}
+
+static int s6000_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ struct s6000_runtime_data *prtd = substream->runtime->private_data;
+
+ prtd->period = 0;
+
+ return 0;
+}
+
+static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+ struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s6000_runtime_data *prtd = runtime->private_data;
+ unsigned long flags;
+ unsigned int offset;
+ dma_addr_t count;
+
+ spin_lock_irqsave(&prtd->lock, flags);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ count = s6dmac_cur_src(DMA_MASK_DMAC(par->dma_out),
+ DMA_INDEX_CHNL(par->dma_out));
+ else
+ count = s6dmac_cur_dst(DMA_MASK_DMAC(par->dma_in),
+ DMA_INDEX_CHNL(par->dma_in));
+
+ count -= runtime->dma_addr;
+
+ spin_unlock_irqrestore(&prtd->lock, flags);
+
+ offset = bytes_to_frames(runtime, count);
+ if (unlikely(offset >= runtime->buffer_size))
+ offset = 0;
+
+ return offset;
+}
+
+static int s6000_pcm_open(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+ struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s6000_runtime_data *prtd;
+ int ret;
+
+ snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
+
+ ret = snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 16);
+ if (ret < 0)
+ return ret;
+ ret = snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
+ if (ret < 0)
+ return ret;
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ return ret;
+
+ if (par->same_rate) {
+ int rate;
+ spin_lock(&par->lock); /* needed? */
+ rate = par->rate;
+ spin_unlock(&par->lock);
+ if (rate != -1) {
+ ret = snd_pcm_hw_constraint_minmax(runtime,
+ SNDRV_PCM_HW_PARAM_RATE,
+ rate, rate);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ prtd = kzalloc(sizeof(struct s6000_runtime_data), GFP_KERNEL);
+ if (prtd == NULL)
+ return -ENOMEM;
+
+ spin_lock_init(&prtd->lock);
+
+ runtime->private_data = prtd;
+
+ return 0;
+}
+
+static int s6000_pcm_close(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s6000_runtime_data *prtd = runtime->private_data;
+
+ kfree(prtd);
+
+ return 0;
+}
+
+static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+ struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ int ret;
+ ret = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+ if (ret < 0) {
+ printk(KERN_WARNING "s6000-pcm: allocation of memory failed\n");
+ return ret;
+ }
+
+ if (par->same_rate) {
+ spin_lock(&par->lock);
+ if (par->rate == -1 ||
+ !(par->in_use & ~(1 << substream->stream))) {
+ par->rate = params_rate(hw_params);
+ par->in_use |= 1 << substream->stream;
+ } else if (params_rate(hw_params) != par->rate) {
+ snd_pcm_lib_free_pages(substream);
+ par->in_use &= ~(1 << substream->stream);
+ ret = -EBUSY;
+ }
+ spin_unlock(&par->lock);
+ }
+ return ret;
+}
+
+static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+ struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+
+ spin_lock(&par->lock);
+ par->in_use &= ~(1 << substream->stream);
+ if (!par->in_use)
+ par->rate = -1;
+ spin_unlock(&par->lock);
+
+ return snd_pcm_lib_free_pages(substream);
+}
+
+static struct snd_pcm_ops s6000_pcm_ops = {
+ .open = s6000_pcm_open,
+ .close = s6000_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = s6000_pcm_hw_params,
+ .hw_free = s6000_pcm_hw_free,
+ .trigger = s6000_pcm_trigger,
+ .prepare = s6000_pcm_prepare,
+ .pointer = s6000_pcm_pointer,
+};
+
+static void s6000_pcm_free(struct snd_pcm *pcm)
+{
+ struct snd_soc_pcm_runtime *runtime = pcm->private_data;
+ struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+
+ free_irq(params->irq, pcm);
+ snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static u64 s6000_pcm_dmamask = DMA_32BIT_MASK;
+
+static int s6000_pcm_new(struct snd_card *card,
+ struct snd_soc_dai *dai, struct snd_pcm *pcm)
+{
+ struct snd_soc_pcm_runtime *runtime = pcm->private_data;
+ struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+ int res;
+
+ if (!card->dev->dma_mask)
+ card->dev->dma_mask = &s6000_pcm_dmamask;
+ if (!card->dev->coherent_dma_mask)
+ card->dev->coherent_dma_mask = DMA_32BIT_MASK;
+
+ if (params->dma_in) {
+ s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_in),
+ DMA_INDEX_CHNL(params->dma_in));
+ s6dmac_int_sources(DMA_MASK_DMAC(params->dma_in),
+ DMA_INDEX_CHNL(params->dma_in));
+ }
+
+ if (params->dma_out) {
+ s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_out),
+ DMA_INDEX_CHNL(params->dma_out));
+ s6dmac_int_sources(DMA_MASK_DMAC(params->dma_out),
+ DMA_INDEX_CHNL(params->dma_out));
+ }
+
+ res = request_irq(params->irq, s6000_pcm_irq, IRQF_SHARED,
+ s6000_soc_platform.name, pcm);
+ if (res) {
+ printk(KERN_ERR "s6000-pcm couldn't get IRQ\n");
+ return res;
+ }
+
+ res = snd_pcm_lib_preallocate_pages_for_all(pcm,
+ SNDRV_DMA_TYPE_DEV,
+ card->dev,
+ S6_PCM_PREALLOCATE_SIZE,
+ S6_PCM_PREALLOCATE_MAX);
+ if (res)
+ printk(KERN_WARNING "s6000-pcm: preallocation failed\n");
+
+ spin_lock_init(&params->lock);
+ params->in_use = 0;
+ params->rate = -1;
+ return 0;
+}
+
+struct snd_soc_platform s6000_soc_platform = {
+ .name = "s6000-audio",
+ .pcm_ops = &s6000_pcm_ops,
+ .pcm_new = s6000_pcm_new,
+ .pcm_free = s6000_pcm_free,
+};
+EXPORT_SYMBOL_GPL(s6000_soc_platform);
+
+static int __init s6000_pcm_init(void)
+{
+ return snd_soc_register_platform(&s6000_soc_platform);
+}
+module_init(s6000_pcm_init);
+
+static void __exit s6000_pcm_exit(void)
+{
+ snd_soc_unregister_platform(&s6000_soc_platform);
+}
+module_exit(s6000_pcm_exit);
+
+MODULE_AUTHOR("Daniel Gloeckner");
+MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/s6000/s6000-pcm.h b/sound/soc/s6000/s6000-pcm.h
new file mode 100644
index 000000000000..96f23f6f52bf
--- /dev/null
+++ b/sound/soc/s6000/s6000-pcm.h
@@ -0,0 +1,35 @@
+/*
+ * ALSA PCM interface for the Stretch s6000 family
+ *
+ * Author: Daniel Gloeckner, <dg@emlix.com>
+ * Copyright: (C) 2009 emlix GmbH <info@emlix.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 _S6000_PCM_H
+#define _S6000_PCM_H
+
+struct snd_soc_dai;
+struct snd_pcm_substream;
+
+struct s6000_pcm_dma_params {
+ unsigned int (*check_xrun)(struct snd_soc_dai *cpu_dai);
+ int (*trigger)(struct snd_pcm_substream *substream, int cmd, int after);
+ dma_addr_t sif_in;
+ dma_addr_t sif_out;
+ u32 dma_in;
+ u32 dma_out;
+ int irq;
+ int same_rate;
+
+ spinlock_t lock;
+ int in_use;
+ int rate;
+};
+
+extern struct snd_soc_platform s6000_soc_platform;
+
+#endif
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
new file mode 100644
index 000000000000..b5f95f9781c1
--- /dev/null
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -0,0 +1,244 @@
+/*
+ * ASoC driver for Stretch s6105 IP camera platform
+ *
+ * Author: Daniel Gloeckner, <dg@emlix.com>
+ * Copyright: (C) 2009 emlix GmbH <info@emlix.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/module.h>
+#include <linux/moduleparam.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <variant/dmac.h>
+
+#include "../codecs/tlv320aic3x.h"
+#include "s6000-pcm.h"
+#include "s6000-i2s.h"
+
+#define S6105_CAM_CODEC_CLOCK 12288000
+
+static int s6105_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_dai *codec_dai = rtd->dai->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ int ret = 0;
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_CBM_CFM);
+ if (ret < 0)
+ return ret;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM |
+ SND_SOC_DAIFMT_NB_NF);
+ if (ret < 0)
+ return ret;
+
+ /* set the codec system clock */
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, S6105_CAM_CODEC_CLOCK,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static struct snd_soc_ops s6105_ops = {
+ .hw_params = s6105_hw_params,
+};
+
+/* s6105 machine dapm widgets */
+static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
+ SND_SOC_DAPM_LINE("Audio Out Differential", NULL),
+ SND_SOC_DAPM_LINE("Audio Out Stereo", NULL),
+ SND_SOC_DAPM_LINE("Audio In", NULL),
+};
+
+/* s6105 machine audio_mapnections to the codec pins */
+static const struct snd_soc_dapm_route audio_map[] = {
+ /* Audio Out connected to HPLOUT, HPLCOM, HPROUT */
+ {"Audio Out Differential", NULL, "HPLOUT"},
+ {"Audio Out Differential", NULL, "HPLCOM"},
+ {"Audio Out Stereo", NULL, "HPLOUT"},
+ {"Audio Out Stereo", NULL, "HPROUT"},
+
+ /* Audio In connected to LINE1L, LINE1R */
+ {"LINE1L", NULL, "Audio In"},
+ {"LINE1R", NULL, "Audio In"},
+};
+
+static int output_type_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 2;
+ if (uinfo->value.enumerated.item) {
+ uinfo->value.enumerated.item = 1;
+ strcpy(uinfo->value.enumerated.name, "HPLOUT/HPROUT");
+ } else {
+ strcpy(uinfo->value.enumerated.name, "HPLOUT/HPLCOM");
+ }
+ return 0;
+}
+
+static int output_type_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.enumerated.item[0] = kcontrol->private_value;
+ return 0;
+}
+
+static int output_type_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = kcontrol->private_data;
+ unsigned int val = (ucontrol->value.enumerated.item[0] != 0);
+ char *differential = "Audio Out Differential";
+ char *stereo = "Audio Out Stereo";
+
+ if (kcontrol->private_value == val)
+ return 0;
+ kcontrol->private_value = val;
+ snd_soc_dapm_disable_pin(codec, val ? differential : stereo);
+ snd_soc_dapm_sync(codec);
+ snd_soc_dapm_enable_pin(codec, val ? stereo : differential);
+ snd_soc_dapm_sync(codec);
+
+ return 1;
+}
+
+static const struct snd_kcontrol_new audio_out_mux = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Master Output Mux",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = output_type_info,
+ .get = output_type_get,
+ .put = output_type_put,
+ .private_value = 1 /* default to stereo */
+};
+
+/* Logic for a aic3x as connected on the s6105 ip camera ref design */
+static int s6105_aic3x_init(struct snd_soc_codec *codec)
+{
+ /* Add s6105 specific widgets */
+ snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
+ ARRAY_SIZE(aic3x_dapm_widgets));
+
+ /* Set up s6105 specific audio path audio_map */
+ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+
+ /* not present */
+ snd_soc_dapm_nc_pin(codec, "MONO_LOUT");
+ snd_soc_dapm_nc_pin(codec, "LINE2L");
+ snd_soc_dapm_nc_pin(codec, "LINE2R");
+
+ /* not connected */
+ snd_soc_dapm_nc_pin(codec, "MIC3L"); /* LINE2L on this chip */
+ snd_soc_dapm_nc_pin(codec, "MIC3R"); /* LINE2R on this chip */
+ snd_soc_dapm_nc_pin(codec, "LLOUT");
+ snd_soc_dapm_nc_pin(codec, "RLOUT");
+ snd_soc_dapm_nc_pin(codec, "HPRCOM");
+
+ /* always connected */
+ snd_soc_dapm_enable_pin(codec, "Audio In");
+
+ /* must correspond to audio_out_mux.private_value initializer */
+ snd_soc_dapm_disable_pin(codec, "Audio Out Differential");
+ snd_soc_dapm_sync(codec);
+ snd_soc_dapm_enable_pin(codec, "Audio Out Stereo");
+
+ snd_soc_dapm_sync(codec);
+
+ snd_ctl_add(codec->card, snd_ctl_new1(&audio_out_mux, codec));
+
+ return 0;
+}
+
+/* s6105 digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link s6105_dai = {
+ .name = "TLV320AIC31",
+ .stream_name = "AIC31",
+ .cpu_dai = &s6000_i2s_dai,
+ .codec_dai = &aic3x_dai,
+ .init = s6105_aic3x_init,
+ .ops = &s6105_ops,
+};
+
+/* s6105 audio machine driver */
+static struct snd_soc_card snd_soc_card_s6105 = {
+ .name = "Stretch IP Camera",
+ .platform = &s6000_soc_platform,
+ .dai_link = &s6105_dai,
+ .num_links = 1,
+};
+
+/* s6105 audio private data */
+static struct aic3x_setup_data s6105_aic3x_setup = {
+ .i2c_bus = 0,
+ .i2c_address = 0x18,
+};
+
+/* s6105 audio subsystem */
+static struct snd_soc_device s6105_snd_devdata = {
+ .card = &snd_soc_card_s6105,
+ .codec_dev = &soc_codec_dev_aic3x,
+ .codec_data = &s6105_aic3x_setup,
+};
+
+static struct s6000_snd_platform_data __initdata s6105_snd_data = {
+ .wide = 0,
+ .channel_in = 0,
+ .channel_out = 1,
+ .lines_in = 1,
+ .lines_out = 1,
+ .same_rate = 1,
+};
+
+static struct platform_device *s6105_snd_device;
+
+static int __init s6105_init(void)
+{
+ int ret;
+
+ s6105_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!s6105_snd_device)
+ return -ENOMEM;
+
+ platform_set_drvdata(s6105_snd_device, &s6105_snd_devdata);
+ s6105_snd_devdata.dev = &s6105_snd_device->dev;
+ platform_device_add_data(s6105_snd_device, &s6105_snd_data,
+ sizeof(s6105_snd_data));
+
+ ret = platform_device_add(s6105_snd_device);
+ if (ret)
+ platform_device_put(s6105_snd_device);
+
+ return ret;
+}
+
+static void __exit s6105_exit(void)
+{
+ platform_device_unregister(s6105_snd_device);
+}
+
+module_init(s6105_init);
+module_exit(s6105_exit);
+
+MODULE_AUTHOR("Daniel Gloeckner");
+MODULE_DESCRIPTION("Stretch s6105 IP camera ASoC driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 99712f652d0d..c0e706645ec4 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -113,6 +113,35 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
}
#endif
+static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_card *card = socdev->card;
+ struct snd_soc_dai_link *machine = rtd->dai;
+ struct snd_soc_dai *cpu_dai = machine->cpu_dai;
+ struct snd_soc_dai *codec_dai = machine->codec_dai;
+ int ret;
+
+ if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates ||
+ machine->symmetric_rates) {
+ dev_dbg(card->dev, "Symmetry forces %dHz rate\n",
+ machine->rate);
+
+ ret = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_RATE,
+ machine->rate,
+ machine->rate);
+ if (ret < 0) {
+ dev_err(card->dev,
+ "Unable to apply rate symmetry constraint: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
/*
* Called by ALSA when a PCM substream is opened, the runtime->hw record is
* then initialized and any private data can be allocated. This also calls
@@ -221,6 +250,13 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
goto machine_err;
}
+ /* Symmetry only applies if we've already got an active stream. */
+ if (cpu_dai->active || codec_dai->active) {
+ ret = soc_pcm_apply_symmetry(substream);
+ if (ret != 0)
+ goto machine_err;
+ }
+
pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
@@ -521,6 +557,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
}
}
+ machine->rate = params_rate(params);
+
out:
mutex_unlock(&pcm_mutex);
return ret;
@@ -954,6 +992,9 @@ static int soc_remove(struct platform_device *pdev)
struct snd_soc_platform *platform = card->platform;
struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
+ if (!card->instantiated)
+ return 0;
+
run_delayed_work(&card->delayed_work);
if (platform->remove)
@@ -1741,7 +1782,7 @@ int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
{
int max = kcontrol->private_value;
- if (max == 1)
+ if (max == 1 && !strstr(kcontrol->id.name, " Volume"))
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
else
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -1771,7 +1812,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
unsigned int shift = mc->shift;
unsigned int rshift = mc->rshift;
- if (max == 1)
+ if (max == 1 && !strstr(kcontrol->id.name, " Volume"))
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
else
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -1878,7 +1919,7 @@ int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
(struct soc_mixer_control *)kcontrol->private_value;
int max = mc->max;
- if (max == 1)
+ if (max == 1 && !strstr(kcontrol->id.name, " Volume"))
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
else
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -2062,7 +2103,7 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
unsigned int freq, int dir)
{
- if (dai->ops->set_sysclk)
+ if (dai->ops && dai->ops->set_sysclk)
return dai->ops->set_sysclk(dai, clk_id, freq, dir);
else
return -EINVAL;
@@ -2082,7 +2123,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
int div_id, int div)
{
- if (dai->ops->set_clkdiv)
+ if (dai->ops && dai->ops->set_clkdiv)
return dai->ops->set_clkdiv(dai, div_id, div);
else
return -EINVAL;
@@ -2101,7 +2142,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
int pll_id, unsigned int freq_in, unsigned int freq_out)
{
- if (dai->ops->set_pll)
+ if (dai->ops && dai->ops->set_pll)
return dai->ops->set_pll(dai, pll_id, freq_in, freq_out);
else
return -EINVAL;
@@ -2117,7 +2158,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
*/
int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
- if (dai->ops->set_fmt)
+ if (dai->ops && dai->ops->set_fmt)
return dai->ops->set_fmt(dai, fmt);
else
return -EINVAL;
@@ -2136,7 +2177,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
unsigned int mask, int slots)
{
- if (dai->ops->set_sysclk)
+ if (dai->ops && dai->ops->set_tdm_slot)
return dai->ops->set_tdm_slot(dai, mask, slots);
else
return -EINVAL;
@@ -2152,7 +2193,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
*/
int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
{
- if (dai->ops->set_sysclk)
+ if (dai->ops && dai->ops->set_tristate)
return dai->ops->set_tristate(dai, tristate);
else
return -EINVAL;
@@ -2168,7 +2209,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
*/
int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
{
- if (dai->ops->digital_mute)
+ if (dai->ops && dai->ops->digital_mute)
return dai->ops->digital_mute(dai, mute);
else
return -EINVAL;
@@ -2349,6 +2390,39 @@ void snd_soc_unregister_platform(struct snd_soc_platform *platform)
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
+static u64 codec_format_map[] = {
+ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE,
+ SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE,
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE,
+ SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE,
+ SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE,
+ SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE,
+ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3BE,
+ SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_U24_3BE,
+ SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE,
+ SNDRV_PCM_FMTBIT_U20_3LE | SNDRV_PCM_FMTBIT_U20_3BE,
+ SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE,
+ SNDRV_PCM_FMTBIT_U18_3LE | SNDRV_PCM_FMTBIT_U18_3BE,
+ SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE,
+ SNDRV_PCM_FMTBIT_FLOAT64_LE | SNDRV_PCM_FMTBIT_FLOAT64_BE,
+ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
+ | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE,
+};
+
+/* Fix up the DAI formats for endianness: codecs don't actually see
+ * the endianness of the data but we're using the CPU format
+ * definitions which do need to include endianness so we ensure that
+ * codec DAIs always have both big and little endian variants set.
+ */
+static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(codec_format_map); i++)
+ if (stream->formats & codec_format_map[i])
+ stream->formats |= codec_format_map[i];
+}
+
/**
* snd_soc_register_codec - Register a codec with the ASoC core
*
@@ -2356,6 +2430,8 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
*/
int snd_soc_register_codec(struct snd_soc_codec *codec)
{
+ int i;
+
if (!codec->name)
return -EINVAL;
@@ -2365,6 +2441,11 @@ int snd_soc_register_codec(struct snd_soc_codec *codec)
INIT_LIST_HEAD(&codec->list);
+ for (i = 0; i < codec->num_dai; i++) {
+ fixup_codec_formats(&codec->dai[i].playback);
+ fixup_codec_formats(&codec->dai[i].capture);
+ }
+
mutex_lock(&client_mutex);
list_add(&codec->list, &codec_list);
snd_soc_instantiate_cards();
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 735903a74675..7847f80e96d1 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -52,17 +52,19 @@
/* dapm power sequences - make this per codec in the future */
static int dapm_up_seq[] = {
- snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic,
- snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac,
- snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_pga,
- snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post
+ snd_soc_dapm_pre, snd_soc_dapm_supply, snd_soc_dapm_micbias,
+ snd_soc_dapm_mic, snd_soc_dapm_mux, snd_soc_dapm_value_mux,
+ snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl,
+ snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
+ snd_soc_dapm_post
};
static int dapm_down_seq[] = {
snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer,
snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias,
- snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_post
+ snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_supply,
+ snd_soc_dapm_post
};
static int dapm_status = 1;
@@ -165,6 +167,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
case snd_soc_dapm_dac:
case snd_soc_dapm_micbias:
case snd_soc_dapm_vmid:
+ case snd_soc_dapm_supply:
p->connect = 1;
break;
/* does effect routing - dynamically connected */
@@ -357,8 +360,9 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
path->long_name);
ret = snd_ctl_add(codec->card, path->kcontrol);
if (ret < 0) {
- printk(KERN_ERR "asoc: failed to add dapm kcontrol %s\n",
- path->long_name);
+ printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n",
+ path->long_name,
+ ret);
kfree(path->long_name);
path->long_name = NULL;
return ret;
@@ -434,6 +438,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
struct snd_soc_dapm_path *path;
int con = 0;
+ if (widget->id == snd_soc_dapm_supply)
+ return 0;
+
if (widget->id == snd_soc_dapm_adc && widget->active)
return 1;
@@ -470,6 +477,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
struct snd_soc_dapm_path *path;
int con = 0;
+ if (widget->id == snd_soc_dapm_supply)
+ return 0;
+
/* active stream ? */
if (widget->id == snd_soc_dapm_dac && widget->active)
return 1;
@@ -521,39 +531,137 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
}
EXPORT_SYMBOL_GPL(dapm_reg_event);
-/*
- * Scan a single DAPM widget for a complete audio path and update the
- * power status appropriately.
+/* Standard power change method, used to apply power changes to most
+ * widgets.
*/
-static int dapm_power_widget(struct snd_soc_codec *codec, int event,
- struct snd_soc_dapm_widget *w)
+static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
{
- int in, out, power_change, power, ret;
+ int ret;
- /* vmid - no action */
- if (w->id == snd_soc_dapm_vmid)
- return 0;
+ /* call any power change event handlers */
+ if (w->event)
+ pr_debug("power %s event for %s flags %x\n",
+ w->power ? "on" : "off",
+ w->name, w->event_flags);
+
+ /* power up pre event */
+ if (w->power && w->event &&
+ (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
+ ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
+ if (ret < 0)
+ return ret;
+ }
- /* active ADC */
- if (w->id == snd_soc_dapm_adc && w->active) {
+ /* power down pre event */
+ if (!w->power && w->event &&
+ (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
+ ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* Lower PGA volume to reduce pops */
+ if (w->id == snd_soc_dapm_pga && !w->power)
+ dapm_set_pga(w, w->power);
+
+ dapm_update_bits(w);
+
+ /* Raise PGA volume to reduce pops */
+ if (w->id == snd_soc_dapm_pga && w->power)
+ dapm_set_pga(w, w->power);
+
+ /* power up post event */
+ if (w->power && w->event &&
+ (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
+ ret = w->event(w,
+ NULL, SND_SOC_DAPM_POST_PMU);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* power down post event */
+ if (!w->power && w->event &&
+ (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
+ ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Generic check to see if a widget should be powered.
+ */
+static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
+{
+ int in, out;
+
+ in = is_connected_input_ep(w);
+ dapm_clear_walk(w->codec);
+ out = is_connected_output_ep(w);
+ dapm_clear_walk(w->codec);
+ return out != 0 && in != 0;
+}
+
+/* Check to see if an ADC has power */
+static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
+{
+ int in;
+
+ if (w->active) {
in = is_connected_input_ep(w);
dapm_clear_walk(w->codec);
- w->power = (in != 0) ? 1 : 0;
- dapm_update_bits(w);
- return 0;
+ return in != 0;
+ } else {
+ return dapm_generic_check_power(w);
}
+}
- /* active DAC */
- if (w->id == snd_soc_dapm_dac && w->active) {
+/* Check to see if a DAC has power */
+static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
+{
+ int out;
+
+ if (w->active) {
out = is_connected_output_ep(w);
dapm_clear_walk(w->codec);
- w->power = (out != 0) ? 1 : 0;
- dapm_update_bits(w);
- return 0;
+ return out != 0;
+ } else {
+ return dapm_generic_check_power(w);
+ }
+}
+
+/* Check to see if a power supply is needed */
+static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
+{
+ struct snd_soc_dapm_path *path;
+ int power = 0;
+
+ /* Check if one of our outputs is connected */
+ list_for_each_entry(path, &w->sinks, list_source) {
+ if (path->sink && path->sink->power_check &&
+ path->sink->power_check(path->sink)) {
+ power = 1;
+ break;
+ }
}
- /* pre and post event widgets */
- if (w->id == snd_soc_dapm_pre) {
+ dapm_clear_walk(w->codec);
+
+ return power;
+}
+
+/*
+ * Scan a single DAPM widget for a complete audio path and update the
+ * power status appropriately.
+ */
+static int dapm_power_widget(struct snd_soc_codec *codec, int event,
+ struct snd_soc_dapm_widget *w)
+{
+ int power, ret;
+
+ switch (w->id) {
+ case snd_soc_dapm_pre:
if (!w->event)
return 0;
@@ -569,8 +677,8 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event,
return ret;
}
return 0;
- }
- if (w->id == snd_soc_dapm_post) {
+
+ case snd_soc_dapm_post:
if (!w->event)
return 0;
@@ -586,70 +694,20 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event,
return ret;
}
return 0;
- }
-
- /* all other widgets */
- in = is_connected_input_ep(w);
- dapm_clear_walk(w->codec);
- out = is_connected_output_ep(w);
- dapm_clear_walk(w->codec);
- power = (out != 0 && in != 0) ? 1 : 0;
- power_change = (w->power == power) ? 0 : 1;
- w->power = power;
- if (!power_change)
- return 0;
-
- /* call any power change event handlers */
- if (w->event)
- pr_debug("power %s event for %s flags %x\n",
- w->power ? "on" : "off",
- w->name, w->event_flags);
-
- /* power up pre event */
- if (power && w->event &&
- (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
- ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
- if (ret < 0)
- return ret;
- }
-
- /* power down pre event */
- if (!power && w->event &&
- (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
- ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
- if (ret < 0)
- return ret;
+ default:
+ break;
}
- /* Lower PGA volume to reduce pops */
- if (w->id == snd_soc_dapm_pga && !power)
- dapm_set_pga(w, power);
-
- dapm_update_bits(w);
-
- /* Raise PGA volume to reduce pops */
- if (w->id == snd_soc_dapm_pga && power)
- dapm_set_pga(w, power);
-
- /* power up post event */
- if (power && w->event &&
- (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
- ret = w->event(w,
- NULL, SND_SOC_DAPM_POST_PMU);
- if (ret < 0)
- return ret;
- }
+ if (!w->power_check)
+ return 0;
- /* power down post event */
- if (!power && w->event &&
- (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
- ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
- if (ret < 0)
- return ret;
- }
+ power = w->power_check(w);
+ if (w->power == power)
+ return 0;
+ w->power = power;
- return 0;
+ return dapm_generic_apply_power(w);
}
/*
@@ -723,6 +781,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
case snd_soc_dapm_pga:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
+ case snd_soc_dapm_supply:
if (w->name) {
in = is_connected_input_ep(w);
dapm_clear_walk(w->codec);
@@ -851,6 +910,7 @@ static ssize_t dapm_widget_show(struct device *dev,
case snd_soc_dapm_pga:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
+ case snd_soc_dapm_supply:
if (w->name)
count += sprintf(buf + count, "%s: %s\n",
w->name, w->power ? "On":"Off");
@@ -1015,6 +1075,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
case snd_soc_dapm_vmid:
case snd_soc_dapm_pre:
case snd_soc_dapm_post:
+ case snd_soc_dapm_supply:
list_add(&path->list, &codec->dapm_paths);
list_add(&path->list_sink, &wsink->sources);
list_add(&path->list_source, &wsource->sinks);
@@ -1108,15 +1169,22 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
case snd_soc_dapm_switch:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
+ w->power_check = dapm_generic_check_power;
dapm_new_mixer(codec, w);
break;
case snd_soc_dapm_mux:
case snd_soc_dapm_value_mux:
+ w->power_check = dapm_generic_check_power;
dapm_new_mux(codec, w);
break;
case snd_soc_dapm_adc:
+ w->power_check = dapm_adc_check_power;
+ break;
case snd_soc_dapm_dac:
+ w->power_check = dapm_dac_check_power;
+ break;
case snd_soc_dapm_pga:
+ w->power_check = dapm_generic_check_power;
dapm_new_pga(codec, w);
break;
case snd_soc_dapm_input:
@@ -1126,6 +1194,10 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
case snd_soc_dapm_hp:
case snd_soc_dapm_mic:
case snd_soc_dapm_line:
+ w->power_check = dapm_generic_check_power;
+ break;
+ case snd_soc_dapm_supply:
+ w->power_check = dapm_supply_check_power;
case snd_soc_dapm_vmid:
case snd_soc_dapm_pre:
case snd_soc_dapm_post:
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 823296d7d578..6c25fa23f702 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -627,6 +627,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
subs->hwptr_done += offs;
if (subs->hwptr_done >= runtime->buffer_size)
subs->hwptr_done -= runtime->buffer_size;
+ runtime->delay += offs;
spin_unlock_irqrestore(&subs->lock, flags);
urb->transfer_buffer_length = offs * stride;
if (period_elapsed)
@@ -636,12 +637,22 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
/*
* process after playback data complete
- * - nothing to do
+ * - decrease the delay count again
*/
static int retire_playback_urb(struct snd_usb_substream *subs,
struct snd_pcm_runtime *runtime,
struct urb *urb)
{
+ unsigned long flags;
+ int stride = runtime->frame_bits >> 3;
+ int processed = urb->transfer_buffer_length / stride;
+
+ spin_lock_irqsave(&subs->lock, flags);
+ if (processed > runtime->delay)
+ runtime->delay = 0;
+ else
+ runtime->delay -= processed;
+ spin_unlock_irqrestore(&subs->lock, flags);
return 0;
}
@@ -1520,6 +1531,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
subs->hwptr_done = 0;
subs->transfer_done = 0;
subs->phase = 0;
+ runtime->delay = 0;
/* clear urbs (to be sure) */
deactivate_urbs(subs, 0, 1);
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index c3b99def9cbc..1eddae94bab3 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -85,7 +85,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
{
- union ioapic_redir_entry *pent;
+ union kvm_ioapic_redirect_entry *pent;
int injected = -1;
pent = &ioapic->redirtbl[idx];
@@ -142,149 +142,40 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
}
}
-static int ioapic_inj_irq(struct kvm_ioapic *ioapic,
- struct kvm_vcpu *vcpu,
- u8 vector, u8 trig_mode, u8 delivery_mode)
-{
- ioapic_debug("irq %d trig %d deliv %d\n", vector, trig_mode,
- delivery_mode);
-
- ASSERT((delivery_mode == IOAPIC_FIXED) ||
- (delivery_mode == IOAPIC_LOWEST_PRIORITY));
-
- return kvm_apic_set_irq(vcpu, vector, trig_mode);
-}
-
-static void ioapic_inj_nmi(struct kvm_vcpu *vcpu)
-{
- kvm_inject_nmi(vcpu);
- kvm_vcpu_kick(vcpu);
-}
-
-u32 kvm_ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest,
- u8 dest_mode)
-{
- u32 mask = 0;
- int i;
- struct kvm *kvm = ioapic->kvm;
- struct kvm_vcpu *vcpu;
-
- ioapic_debug("dest %d dest_mode %d\n", dest, dest_mode);
-
- if (dest_mode == 0) { /* Physical mode. */
- if (dest == 0xFF) { /* Broadcast. */
- for (i = 0; i < KVM_MAX_VCPUS; ++i)
- if (kvm->vcpus[i] && kvm->vcpus[i]->arch.apic)
- mask |= 1 << i;
- return mask;
- }
- for (i = 0; i < KVM_MAX_VCPUS; ++i) {
- vcpu = kvm->vcpus[i];
- if (!vcpu)
- continue;
- if (kvm_apic_match_physical_addr(vcpu->arch.apic, dest)) {
- if (vcpu->arch.apic)
- mask = 1 << i;
- break;
- }
- }
- } else if (dest != 0) /* Logical mode, MDA non-zero. */
- for (i = 0; i < KVM_MAX_VCPUS; ++i) {
- vcpu = kvm->vcpus[i];
- if (!vcpu)
- continue;
- if (vcpu->arch.apic &&
- kvm_apic_match_logical_addr(vcpu->arch.apic, dest))
- mask |= 1 << vcpu->vcpu_id;
- }
- ioapic_debug("mask %x\n", mask);
- return mask;
-}
-
static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
{
- u8 dest = ioapic->redirtbl[irq].fields.dest_id;
- u8 dest_mode = ioapic->redirtbl[irq].fields.dest_mode;
- u8 delivery_mode = ioapic->redirtbl[irq].fields.delivery_mode;
- u8 vector = ioapic->redirtbl[irq].fields.vector;
- u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode;
- u32 deliver_bitmask;
- struct kvm_vcpu *vcpu;
- int vcpu_id, r = -1;
+ union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq];
+ struct kvm_lapic_irq irqe;
ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x "
"vector=%x trig_mode=%x\n",
- dest, dest_mode, delivery_mode, vector, trig_mode);
-
- deliver_bitmask = kvm_ioapic_get_delivery_bitmask(ioapic, dest,
- dest_mode);
- if (!deliver_bitmask) {
- ioapic_debug("no target on destination\n");
- return 0;
- }
+ entry->fields.dest, entry->fields.dest_mode,
+ entry->fields.delivery_mode, entry->fields.vector,
+ entry->fields.trig_mode);
+
+ irqe.dest_id = entry->fields.dest_id;
+ irqe.vector = entry->fields.vector;
+ irqe.dest_mode = entry->fields.dest_mode;
+ irqe.trig_mode = entry->fields.trig_mode;
+ irqe.delivery_mode = entry->fields.delivery_mode << 8;
+ irqe.level = 1;
+ irqe.shorthand = 0;
- switch (delivery_mode) {
- case IOAPIC_LOWEST_PRIORITY:
- vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, vector,
- deliver_bitmask);
#ifdef CONFIG_X86
- if (irq == 0)
- vcpu = ioapic->kvm->vcpus[0];
-#endif
- if (vcpu != NULL)
- r = ioapic_inj_irq(ioapic, vcpu, vector,
- trig_mode, delivery_mode);
- else
- ioapic_debug("null lowest prio vcpu: "
- "mask=%x vector=%x delivery_mode=%x\n",
- deliver_bitmask, vector, IOAPIC_LOWEST_PRIORITY);
- break;
- case IOAPIC_FIXED:
-#ifdef CONFIG_X86
- if (irq == 0)
- deliver_bitmask = 1;
-#endif
- for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) {
- if (!(deliver_bitmask & (1 << vcpu_id)))
- continue;
- deliver_bitmask &= ~(1 << vcpu_id);
- vcpu = ioapic->kvm->vcpus[vcpu_id];
- if (vcpu) {
- if (r < 0)
- r = 0;
- r += ioapic_inj_irq(ioapic, vcpu, vector,
- trig_mode, delivery_mode);
- }
- }
- break;
- case IOAPIC_NMI:
- for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) {
- if (!(deliver_bitmask & (1 << vcpu_id)))
- continue;
- deliver_bitmask &= ~(1 << vcpu_id);
- vcpu = ioapic->kvm->vcpus[vcpu_id];
- if (vcpu) {
- ioapic_inj_nmi(vcpu);
- r = 1;
- }
- else
- ioapic_debug("NMI to vcpu %d failed\n",
- vcpu->vcpu_id);
- }
- break;
- default:
- printk(KERN_WARNING "Unsupported delivery mode %d\n",
- delivery_mode);
- break;
+ /* Always delivery PIT interrupt to vcpu 0 */
+ if (irq == 0) {
+ irqe.dest_mode = 0; /* Physical mode. */
+ irqe.dest_id = ioapic->kvm->vcpus[0]->vcpu_id;
}
- return r;
+#endif
+ return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe);
}
int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
{
u32 old_irr = ioapic->irr;
u32 mask = 1 << irq;
- union ioapic_redir_entry entry;
+ union kvm_ioapic_redirect_entry entry;
int ret = 1;
if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
@@ -305,7 +196,7 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int pin,
int trigger_mode)
{
- union ioapic_redir_entry *ent;
+ union kvm_ioapic_redirect_entry *ent;
ent = &ioapic->redirtbl[pin];
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
index a34bd5e6436b..7080b713c160 100644
--- a/virt/kvm/ioapic.h
+++ b/virt/kvm/ioapic.h
@@ -40,22 +40,7 @@ struct kvm_ioapic {
u32 id;
u32 irr;
u32 pad;
- union ioapic_redir_entry {
- u64 bits;
- struct {
- u8 vector;
- u8 delivery_mode:3;
- u8 dest_mode:1;
- u8 delivery_status:1;
- u8 polarity:1;
- u8 remote_irr:1;
- u8 trig_mode:1;
- u8 mask:1;
- u8 reserve:7;
- u8 reserved[4];
- u8 dest_id;
- } fields;
- } redirtbl[IOAPIC_NUM_PINS];
+ union kvm_ioapic_redirect_entry redirtbl[IOAPIC_NUM_PINS];
struct kvm_io_device dev;
struct kvm *kvm;
void (*ack_notifier)(void *opaque, int irq);
@@ -79,13 +64,13 @@ static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
return kvm->arch.vioapic;
}
-struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
- unsigned long bitmap);
+int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
+ int short_hand, int dest, int dest_mode);
+int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2);
void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode);
int kvm_ioapic_init(struct kvm *kvm);
int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);
void kvm_ioapic_reset(struct kvm_ioapic *ioapic);
-u32 kvm_ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest,
- u8 dest_mode);
-
+int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
+ struct kvm_lapic_irq *irq);
#endif
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
index 4c4037503600..15147583abd1 100644
--- a/virt/kvm/iommu.c
+++ b/virt/kvm/iommu.c
@@ -39,11 +39,16 @@ int kvm_iommu_map_pages(struct kvm *kvm,
pfn_t pfn;
int i, r = 0;
struct iommu_domain *domain = kvm->arch.iommu_domain;
+ int flags;
/* check if iommu exists and in use */
if (!domain)
return 0;
+ flags = IOMMU_READ | IOMMU_WRITE;
+ if (kvm->arch.iommu_flags & KVM_IOMMU_CACHE_COHERENCY)
+ flags |= IOMMU_CACHE;
+
for (i = 0; i < npages; i++) {
/* check if already mapped */
if (iommu_iova_to_phys(domain, gfn_to_gpa(gfn)))
@@ -53,8 +58,7 @@ int kvm_iommu_map_pages(struct kvm *kvm,
r = iommu_map_range(domain,
gfn_to_gpa(gfn),
pfn_to_hpa(pfn),
- PAGE_SIZE,
- IOMMU_READ | IOMMU_WRITE);
+ PAGE_SIZE, flags);
if (r) {
printk(KERN_ERR "kvm_iommu_map_address:"
"iommu failed to map pfn=%lx\n", pfn);
@@ -88,7 +92,7 @@ int kvm_assign_device(struct kvm *kvm,
{
struct pci_dev *pdev = NULL;
struct iommu_domain *domain = kvm->arch.iommu_domain;
- int r;
+ int r, last_flags;
/* check if iommu exists and in use */
if (!domain)
@@ -107,12 +111,29 @@ int kvm_assign_device(struct kvm *kvm,
return r;
}
+ last_flags = kvm->arch.iommu_flags;
+ if (iommu_domain_has_cap(kvm->arch.iommu_domain,
+ IOMMU_CAP_CACHE_COHERENCY))
+ kvm->arch.iommu_flags |= KVM_IOMMU_CACHE_COHERENCY;
+
+ /* Check if need to update IOMMU page table for guest memory */
+ if ((last_flags ^ kvm->arch.iommu_flags) ==
+ KVM_IOMMU_CACHE_COHERENCY) {
+ kvm_iommu_unmap_memslots(kvm);
+ r = kvm_iommu_map_memslots(kvm);
+ if (r)
+ goto out_unmap;
+ }
+
printk(KERN_DEBUG "assign device: host bdf = %x:%x:%x\n",
assigned_dev->host_busnr,
PCI_SLOT(assigned_dev->host_devfn),
PCI_FUNC(assigned_dev->host_devfn));
return 0;
+out_unmap:
+ kvm_iommu_unmap_memslots(kvm);
+ return r;
}
int kvm_deassign_device(struct kvm *kvm,
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 864ac5483baa..a8bd466d00cc 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -22,6 +22,9 @@
#include <linux/kvm_host.h>
#include <asm/msidef.h>
+#ifdef CONFIG_IA64
+#include <asm/iosapic.h>
+#endif
#include "irq.h"
@@ -43,57 +46,73 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
return kvm_ioapic_set_irq(kvm->arch.vioapic, e->irqchip.pin, level);
}
-static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
- struct kvm *kvm, int level)
+inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq)
{
- int vcpu_id, r = -1;
- struct kvm_vcpu *vcpu;
- struct kvm_ioapic *ioapic = ioapic_irqchip(kvm);
- int dest_id = (e->msi.address_lo & MSI_ADDR_DEST_ID_MASK)
- >> MSI_ADDR_DEST_ID_SHIFT;
- int vector = (e->msi.data & MSI_DATA_VECTOR_MASK)
- >> MSI_DATA_VECTOR_SHIFT;
- int dest_mode = test_bit(MSI_ADDR_DEST_MODE_SHIFT,
- (unsigned long *)&e->msi.address_lo);
- int trig_mode = test_bit(MSI_DATA_TRIGGER_SHIFT,
- (unsigned long *)&e->msi.data);
- int delivery_mode = test_bit(MSI_DATA_DELIVERY_MODE_SHIFT,
- (unsigned long *)&e->msi.data);
- u32 deliver_bitmask;
-
- BUG_ON(!ioapic);
-
- deliver_bitmask = kvm_ioapic_get_delivery_bitmask(ioapic,
- dest_id, dest_mode);
- /* IOAPIC delivery mode value is the same as MSI here */
- switch (delivery_mode) {
- case IOAPIC_LOWEST_PRIORITY:
- vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, vector,
- deliver_bitmask);
- if (vcpu != NULL)
- r = kvm_apic_set_irq(vcpu, vector, trig_mode);
- else
- printk(KERN_INFO "kvm: null lowest priority vcpu!\n");
- break;
- case IOAPIC_FIXED:
- for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) {
- if (!(deliver_bitmask & (1 << vcpu_id)))
- continue;
- deliver_bitmask &= ~(1 << vcpu_id);
- vcpu = ioapic->kvm->vcpus[vcpu_id];
- if (vcpu) {
- if (r < 0)
- r = 0;
- r += kvm_apic_set_irq(vcpu, vector, trig_mode);
- }
+#ifdef CONFIG_IA64
+ return irq->delivery_mode ==
+ (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
+#else
+ return irq->delivery_mode == APIC_DM_LOWEST;
+#endif
+}
+
+int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
+ struct kvm_lapic_irq *irq)
+{
+ int i, r = -1;
+ struct kvm_vcpu *vcpu, *lowest = NULL;
+
+ if (irq->dest_mode == 0 && irq->dest_id == 0xff &&
+ kvm_is_dm_lowest_prio(irq))
+ printk(KERN_INFO "kvm: apic: phys broadcast and lowest prio\n");
+
+ for (i = 0; i < KVM_MAX_VCPUS; i++) {
+ vcpu = kvm->vcpus[i];
+
+ if (!vcpu || !kvm_apic_present(vcpu))
+ continue;
+
+ if (!kvm_apic_match_dest(vcpu, src, irq->shorthand,
+ irq->dest_id, irq->dest_mode))
+ continue;
+
+ if (!kvm_is_dm_lowest_prio(irq)) {
+ if (r < 0)
+ r = 0;
+ r += kvm_apic_set_irq(vcpu, irq);
+ } else {
+ if (!lowest)
+ lowest = vcpu;
+ else if (kvm_apic_compare_prio(vcpu, lowest) < 0)
+ lowest = vcpu;
}
- break;
- default:
- break;
}
+
+ if (lowest)
+ r = kvm_apic_set_irq(lowest, irq);
+
return r;
}
+static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
+ struct kvm *kvm, int level)
+{
+ struct kvm_lapic_irq irq;
+
+ irq.dest_id = (e->msi.address_lo &
+ MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
+ irq.vector = (e->msi.data &
+ MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT;
+ irq.dest_mode = (1 << MSI_ADDR_DEST_MODE_SHIFT) & e->msi.address_lo;
+ irq.trig_mode = (1 << MSI_DATA_TRIGGER_SHIFT) & e->msi.data;
+ irq.delivery_mode = e->msi.data & 0x700;
+ irq.level = 1;
+ irq.shorthand = 0;
+
+ /* TODO Deal with RH bit of MSI message address */
+ return kvm_irq_delivery_to_apic(kvm, NULL, &irq);
+}
+
/* This should be called with the kvm->lock mutex held
* Return value:
* < 0 Interrupt was ignored (masked or not delivered for other reasons)
@@ -252,7 +271,7 @@ static int setup_routing_entry(struct kvm_kernel_irq_routing_entry *e,
delta = 8;
break;
case KVM_IRQCHIP_IOAPIC:
- e->set = kvm_set_ioapic_irq;
+ e->set = kvm_set_ioapic_irq;
break;
default:
goto out;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 1ecbe2391c8b..4d00942e5d0a 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -41,6 +41,8 @@
#include <linux/pagemap.h>
#include <linux/mman.h>
#include <linux/swap.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -60,9 +62,6 @@
MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");
-static int msi2intx = 1;
-module_param(msi2intx, bool, 0);
-
DEFINE_SPINLOCK(kvm_lock);
LIST_HEAD(vm_list);
@@ -95,38 +94,96 @@ static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *h
return NULL;
}
+static int find_index_from_host_irq(struct kvm_assigned_dev_kernel
+ *assigned_dev, int irq)
+{
+ int i, index;
+ struct msix_entry *host_msix_entries;
+
+ host_msix_entries = assigned_dev->host_msix_entries;
+
+ index = -1;
+ for (i = 0; i < assigned_dev->entries_nr; i++)
+ if (irq == host_msix_entries[i].vector) {
+ index = i;
+ break;
+ }
+ if (index < 0) {
+ printk(KERN_WARNING "Fail to find correlated MSI-X entry!\n");
+ return 0;
+ }
+
+ return index;
+}
+
static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work)
{
struct kvm_assigned_dev_kernel *assigned_dev;
+ struct kvm *kvm;
+ int irq, i;
assigned_dev = container_of(work, struct kvm_assigned_dev_kernel,
interrupt_work);
+ kvm = assigned_dev->kvm;
/* This is taken to safely inject irq inside the guest. When
* the interrupt injection (or the ioapic code) uses a
* finer-grained lock, update this
*/
- mutex_lock(&assigned_dev->kvm->lock);
- kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id,
- assigned_dev->guest_irq, 1);
-
- if (assigned_dev->irq_requested_type & KVM_ASSIGNED_DEV_GUEST_MSI) {
- enable_irq(assigned_dev->host_irq);
- assigned_dev->host_irq_disabled = false;
+ mutex_lock(&kvm->lock);
+ spin_lock_irq(&assigned_dev->assigned_dev_lock);
+ if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) {
+ struct kvm_guest_msix_entry *guest_entries =
+ assigned_dev->guest_msix_entries;
+ for (i = 0; i < assigned_dev->entries_nr; i++) {
+ if (!(guest_entries[i].flags &
+ KVM_ASSIGNED_MSIX_PENDING))
+ continue;
+ guest_entries[i].flags &= ~KVM_ASSIGNED_MSIX_PENDING;
+ kvm_set_irq(assigned_dev->kvm,
+ assigned_dev->irq_source_id,
+ guest_entries[i].vector, 1);
+ irq = assigned_dev->host_msix_entries[i].vector;
+ if (irq != 0)
+ enable_irq(irq);
+ assigned_dev->host_irq_disabled = false;
+ }
+ } else {
+ kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id,
+ assigned_dev->guest_irq, 1);
+ if (assigned_dev->irq_requested_type &
+ KVM_DEV_IRQ_GUEST_MSI) {
+ enable_irq(assigned_dev->host_irq);
+ assigned_dev->host_irq_disabled = false;
+ }
}
+
+ spin_unlock_irq(&assigned_dev->assigned_dev_lock);
mutex_unlock(&assigned_dev->kvm->lock);
}
static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id)
{
+ unsigned long flags;
struct kvm_assigned_dev_kernel *assigned_dev =
(struct kvm_assigned_dev_kernel *) dev_id;
+ spin_lock_irqsave(&assigned_dev->assigned_dev_lock, flags);
+ if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) {
+ int index = find_index_from_host_irq(assigned_dev, irq);
+ if (index < 0)
+ goto out;
+ assigned_dev->guest_msix_entries[index].flags |=
+ KVM_ASSIGNED_MSIX_PENDING;
+ }
+
schedule_work(&assigned_dev->interrupt_work);
disable_irq_nosync(irq);
assigned_dev->host_irq_disabled = true;
+out:
+ spin_unlock_irqrestore(&assigned_dev->assigned_dev_lock, flags);
return IRQ_HANDLED;
}
@@ -134,6 +191,7 @@ static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id)
static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
{
struct kvm_assigned_dev_kernel *dev;
+ unsigned long flags;
if (kian->gsi == -1)
return;
@@ -146,28 +204,30 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
/* The guest irq may be shared so this ack may be
* from another device.
*/
+ spin_lock_irqsave(&dev->assigned_dev_lock, flags);
if (dev->host_irq_disabled) {
enable_irq(dev->host_irq);
dev->host_irq_disabled = false;
}
+ spin_unlock_irqrestore(&dev->assigned_dev_lock, flags);
}
-/* The function implicit hold kvm->lock mutex due to cancel_work_sync() */
-static void kvm_free_assigned_irq(struct kvm *kvm,
- struct kvm_assigned_dev_kernel *assigned_dev)
+static void deassign_guest_irq(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *assigned_dev)
{
- if (!irqchip_in_kernel(kvm))
- return;
-
kvm_unregister_irq_ack_notifier(&assigned_dev->ack_notifier);
+ assigned_dev->ack_notifier.gsi = -1;
if (assigned_dev->irq_source_id != -1)
kvm_free_irq_source_id(kvm, assigned_dev->irq_source_id);
assigned_dev->irq_source_id = -1;
+ assigned_dev->irq_requested_type &= ~(KVM_DEV_IRQ_GUEST_MASK);
+}
- if (!assigned_dev->irq_requested_type)
- return;
-
+/* The function implicit hold kvm->lock mutex due to cancel_work_sync() */
+static void deassign_host_irq(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *assigned_dev)
+{
/*
* In kvm_free_device_irq, cancel_work_sync return true if:
* 1. work is scheduled, and then cancelled.
@@ -184,17 +244,64 @@ static void kvm_free_assigned_irq(struct kvm *kvm,
* now, the kvm state is still legal for probably we also have to wait
* interrupt_work done.
*/
- disable_irq_nosync(assigned_dev->host_irq);
- cancel_work_sync(&assigned_dev->interrupt_work);
+ if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) {
+ int i;
+ for (i = 0; i < assigned_dev->entries_nr; i++)
+ disable_irq_nosync(assigned_dev->
+ host_msix_entries[i].vector);
+
+ cancel_work_sync(&assigned_dev->interrupt_work);
+
+ for (i = 0; i < assigned_dev->entries_nr; i++)
+ free_irq(assigned_dev->host_msix_entries[i].vector,
+ (void *)assigned_dev);
+
+ assigned_dev->entries_nr = 0;
+ kfree(assigned_dev->host_msix_entries);
+ kfree(assigned_dev->guest_msix_entries);
+ pci_disable_msix(assigned_dev->dev);
+ } else {
+ /* Deal with MSI and INTx */
+ disable_irq_nosync(assigned_dev->host_irq);
+ cancel_work_sync(&assigned_dev->interrupt_work);
- free_irq(assigned_dev->host_irq, (void *)assigned_dev);
+ free_irq(assigned_dev->host_irq, (void *)assigned_dev);
- if (assigned_dev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI)
- pci_disable_msi(assigned_dev->dev);
+ if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSI)
+ pci_disable_msi(assigned_dev->dev);
+ }
- assigned_dev->irq_requested_type = 0;
+ assigned_dev->irq_requested_type &= ~(KVM_DEV_IRQ_HOST_MASK);
}
+static int kvm_deassign_irq(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *assigned_dev,
+ unsigned long irq_requested_type)
+{
+ unsigned long guest_irq_type, host_irq_type;
+
+ if (!irqchip_in_kernel(kvm))
+ return -EINVAL;
+ /* no irq assignment to deassign */
+ if (!assigned_dev->irq_requested_type)
+ return -ENXIO;
+
+ host_irq_type = irq_requested_type & KVM_DEV_IRQ_HOST_MASK;
+ guest_irq_type = irq_requested_type & KVM_DEV_IRQ_GUEST_MASK;
+
+ if (host_irq_type)
+ deassign_host_irq(kvm, assigned_dev);
+ if (guest_irq_type)
+ deassign_guest_irq(kvm, assigned_dev);
+
+ return 0;
+}
+
+static void kvm_free_assigned_irq(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *assigned_dev)
+{
+ kvm_deassign_irq(kvm, assigned_dev, assigned_dev->irq_requested_type);
+}
static void kvm_free_assigned_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel
@@ -226,190 +333,244 @@ void kvm_free_all_assigned_devices(struct kvm *kvm)
}
}
-static int assigned_device_update_intx(struct kvm *kvm,
- struct kvm_assigned_dev_kernel *adev,
- struct kvm_assigned_irq *airq)
+static int assigned_device_enable_host_intx(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *dev)
{
- adev->guest_irq = airq->guest_irq;
- adev->ack_notifier.gsi = airq->guest_irq;
+ dev->host_irq = dev->dev->irq;
+ /* Even though this is PCI, we don't want to use shared
+ * interrupts. Sharing host devices with guest-assigned devices
+ * on the same interrupt line is not a happy situation: there
+ * are going to be long delays in accepting, acking, etc.
+ */
+ if (request_irq(dev->host_irq, kvm_assigned_dev_intr,
+ 0, "kvm_assigned_intx_device", (void *)dev))
+ return -EIO;
+ return 0;
+}
- if (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_INTX)
- return 0;
+#ifdef __KVM_HAVE_MSI
+static int assigned_device_enable_host_msi(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *dev)
+{
+ int r;
- if (irqchip_in_kernel(kvm)) {
- if (!msi2intx &&
- (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI)) {
- free_irq(adev->host_irq, (void *)adev);
- pci_disable_msi(adev->dev);
- }
+ if (!dev->dev->msi_enabled) {
+ r = pci_enable_msi(dev->dev);
+ if (r)
+ return r;
+ }
- if (!capable(CAP_SYS_RAWIO))
- return -EPERM;
+ dev->host_irq = dev->dev->irq;
+ if (request_irq(dev->host_irq, kvm_assigned_dev_intr, 0,
+ "kvm_assigned_msi_device", (void *)dev)) {
+ pci_disable_msi(dev->dev);
+ return -EIO;
+ }
- if (airq->host_irq)
- adev->host_irq = airq->host_irq;
- else
- adev->host_irq = adev->dev->irq;
+ return 0;
+}
+#endif
- /* Even though this is PCI, we don't want to use shared
- * interrupts. Sharing host devices with guest-assigned devices
- * on the same interrupt line is not a happy situation: there
- * are going to be long delays in accepting, acking, etc.
- */
- if (request_irq(adev->host_irq, kvm_assigned_dev_intr,
- 0, "kvm_assigned_intx_device", (void *)adev))
- return -EIO;
+#ifdef __KVM_HAVE_MSIX
+static int assigned_device_enable_host_msix(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *dev)
+{
+ int i, r = -EINVAL;
+
+ /* host_msix_entries and guest_msix_entries should have been
+ * initialized */
+ if (dev->entries_nr == 0)
+ return r;
+
+ r = pci_enable_msix(dev->dev, dev->host_msix_entries, dev->entries_nr);
+ if (r)
+ return r;
+
+ for (i = 0; i < dev->entries_nr; i++) {
+ r = request_irq(dev->host_msix_entries[i].vector,
+ kvm_assigned_dev_intr, 0,
+ "kvm_assigned_msix_device",
+ (void *)dev);
+ /* FIXME: free requested_irq's on failure */
+ if (r)
+ return r;
}
- adev->irq_requested_type = KVM_ASSIGNED_DEV_GUEST_INTX |
- KVM_ASSIGNED_DEV_HOST_INTX;
return 0;
}
-#ifdef CONFIG_X86
-static int assigned_device_update_msi(struct kvm *kvm,
- struct kvm_assigned_dev_kernel *adev,
- struct kvm_assigned_irq *airq)
+#endif
+
+static int assigned_device_enable_guest_intx(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *dev,
+ struct kvm_assigned_irq *irq)
{
- int r;
+ dev->guest_irq = irq->guest_irq;
+ dev->ack_notifier.gsi = irq->guest_irq;
+ return 0;
+}
- adev->guest_irq = airq->guest_irq;
- if (airq->flags & KVM_DEV_IRQ_ASSIGN_ENABLE_MSI) {
- /* x86 don't care upper address of guest msi message addr */
- adev->irq_requested_type |= KVM_ASSIGNED_DEV_GUEST_MSI;
- adev->irq_requested_type &= ~KVM_ASSIGNED_DEV_GUEST_INTX;
- adev->ack_notifier.gsi = -1;
- } else if (msi2intx) {
- adev->irq_requested_type |= KVM_ASSIGNED_DEV_GUEST_INTX;
- adev->irq_requested_type &= ~KVM_ASSIGNED_DEV_GUEST_MSI;
- adev->ack_notifier.gsi = airq->guest_irq;
- } else {
- /*
- * Guest require to disable device MSI, we disable MSI and
- * re-enable INTx by default again. Notice it's only for
- * non-msi2intx.
- */
- assigned_device_update_intx(kvm, adev, airq);
- return 0;
+#ifdef __KVM_HAVE_MSI
+static int assigned_device_enable_guest_msi(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *dev,
+ struct kvm_assigned_irq *irq)
+{
+ dev->guest_irq = irq->guest_irq;
+ dev->ack_notifier.gsi = -1;
+ return 0;
+}
+#endif
+#ifdef __KVM_HAVE_MSIX
+static int assigned_device_enable_guest_msix(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *dev,
+ struct kvm_assigned_irq *irq)
+{
+ dev->guest_irq = irq->guest_irq;
+ dev->ack_notifier.gsi = -1;
+ return 0;
+}
+#endif
+
+static int assign_host_irq(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *dev,
+ __u32 host_irq_type)
+{
+ int r = -EEXIST;
+
+ if (dev->irq_requested_type & KVM_DEV_IRQ_HOST_MASK)
+ return r;
+
+ switch (host_irq_type) {
+ case KVM_DEV_IRQ_HOST_INTX:
+ r = assigned_device_enable_host_intx(kvm, dev);
+ break;
+#ifdef __KVM_HAVE_MSI
+ case KVM_DEV_IRQ_HOST_MSI:
+ r = assigned_device_enable_host_msi(kvm, dev);
+ break;
+#endif
+#ifdef __KVM_HAVE_MSIX
+ case KVM_DEV_IRQ_HOST_MSIX:
+ r = assigned_device_enable_host_msix(kvm, dev);
+ break;
+#endif
+ default:
+ r = -EINVAL;
}
- if (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI)
- return 0;
+ if (!r)
+ dev->irq_requested_type |= host_irq_type;
+
+ return r;
+}
- if (irqchip_in_kernel(kvm)) {
- if (!msi2intx) {
- if (adev->irq_requested_type &
- KVM_ASSIGNED_DEV_HOST_INTX)
- free_irq(adev->host_irq, (void *)adev);
+static int assign_guest_irq(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *dev,
+ struct kvm_assigned_irq *irq,
+ unsigned long guest_irq_type)
+{
+ int id;
+ int r = -EEXIST;
- r = pci_enable_msi(adev->dev);
- if (r)
- return r;
- }
+ if (dev->irq_requested_type & KVM_DEV_IRQ_GUEST_MASK)
+ return r;
+
+ id = kvm_request_irq_source_id(kvm);
+ if (id < 0)
+ return id;
+
+ dev->irq_source_id = id;
- adev->host_irq = adev->dev->irq;
- if (request_irq(adev->host_irq, kvm_assigned_dev_intr, 0,
- "kvm_assigned_msi_device", (void *)adev))
- return -EIO;
+ switch (guest_irq_type) {
+ case KVM_DEV_IRQ_GUEST_INTX:
+ r = assigned_device_enable_guest_intx(kvm, dev, irq);
+ break;
+#ifdef __KVM_HAVE_MSI
+ case KVM_DEV_IRQ_GUEST_MSI:
+ r = assigned_device_enable_guest_msi(kvm, dev, irq);
+ break;
+#endif
+#ifdef __KVM_HAVE_MSIX
+ case KVM_DEV_IRQ_GUEST_MSIX:
+ r = assigned_device_enable_guest_msix(kvm, dev, irq);
+ break;
+#endif
+ default:
+ r = -EINVAL;
}
- if (!msi2intx)
- adev->irq_requested_type = KVM_ASSIGNED_DEV_GUEST_MSI;
+ if (!r) {
+ dev->irq_requested_type |= guest_irq_type;
+ kvm_register_irq_ack_notifier(kvm, &dev->ack_notifier);
+ } else
+ kvm_free_irq_source_id(kvm, dev->irq_source_id);
- adev->irq_requested_type |= KVM_ASSIGNED_DEV_HOST_MSI;
- return 0;
+ return r;
}
-#endif
+/* TODO Deal with KVM_DEV_IRQ_ASSIGNED_MASK_MSIX */
static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
- struct kvm_assigned_irq
- *assigned_irq)
+ struct kvm_assigned_irq *assigned_irq)
{
- int r = 0;
+ int r = -EINVAL;
struct kvm_assigned_dev_kernel *match;
- u32 current_flags = 0, changed_flags;
+ unsigned long host_irq_type, guest_irq_type;
- mutex_lock(&kvm->lock);
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+
+ if (!irqchip_in_kernel(kvm))
+ return r;
+ mutex_lock(&kvm->lock);
+ r = -ENODEV;
match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
assigned_irq->assigned_dev_id);
- if (!match) {
- mutex_unlock(&kvm->lock);
- return -EINVAL;
- }
-
- if (!match->irq_requested_type) {
- INIT_WORK(&match->interrupt_work,
- kvm_assigned_dev_interrupt_work_handler);
- if (irqchip_in_kernel(kvm)) {
- /* Register ack nofitier */
- match->ack_notifier.gsi = -1;
- match->ack_notifier.irq_acked =
- kvm_assigned_dev_ack_irq;
- kvm_register_irq_ack_notifier(kvm,
- &match->ack_notifier);
-
- /* Request IRQ source ID */
- r = kvm_request_irq_source_id(kvm);
- if (r < 0)
- goto out_release;
- else
- match->irq_source_id = r;
-
-#ifdef CONFIG_X86
- /* Determine host device irq type, we can know the
- * result from dev->msi_enabled */
- if (msi2intx)
- pci_enable_msi(match->dev);
-#endif
- }
- }
+ if (!match)
+ goto out;
- if ((match->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI) &&
- (match->irq_requested_type & KVM_ASSIGNED_DEV_GUEST_MSI))
- current_flags |= KVM_DEV_IRQ_ASSIGN_ENABLE_MSI;
+ host_irq_type = (assigned_irq->flags & KVM_DEV_IRQ_HOST_MASK);
+ guest_irq_type = (assigned_irq->flags & KVM_DEV_IRQ_GUEST_MASK);
- changed_flags = assigned_irq->flags ^ current_flags;
+ r = -EINVAL;
+ /* can only assign one type at a time */
+ if (hweight_long(host_irq_type) > 1)
+ goto out;
+ if (hweight_long(guest_irq_type) > 1)
+ goto out;
+ if (host_irq_type == 0 && guest_irq_type == 0)
+ goto out;
- if ((changed_flags & KVM_DEV_IRQ_ASSIGN_MSI_ACTION) ||
- (msi2intx && match->dev->msi_enabled)) {
-#ifdef CONFIG_X86
- r = assigned_device_update_msi(kvm, match, assigned_irq);
- if (r) {
- printk(KERN_WARNING "kvm: failed to enable "
- "MSI device!\n");
- goto out_release;
- }
-#else
- r = -ENOTTY;
-#endif
- } else if (assigned_irq->host_irq == 0 && match->dev->irq == 0) {
- /* Host device IRQ 0 means don't support INTx */
- if (!msi2intx) {
- printk(KERN_WARNING
- "kvm: wait device to enable MSI!\n");
- r = 0;
- } else {
- printk(KERN_WARNING
- "kvm: failed to enable MSI device!\n");
- r = -ENOTTY;
- goto out_release;
- }
- } else {
- /* Non-sharing INTx mode */
- r = assigned_device_update_intx(kvm, match, assigned_irq);
- if (r) {
- printk(KERN_WARNING "kvm: failed to enable "
- "INTx device!\n");
- goto out_release;
- }
- }
+ r = 0;
+ if (host_irq_type)
+ r = assign_host_irq(kvm, match, host_irq_type);
+ if (r)
+ goto out;
+ if (guest_irq_type)
+ r = assign_guest_irq(kvm, match, assigned_irq, guest_irq_type);
+out:
mutex_unlock(&kvm->lock);
return r;
-out_release:
+}
+
+static int kvm_vm_ioctl_deassign_dev_irq(struct kvm *kvm,
+ struct kvm_assigned_irq
+ *assigned_irq)
+{
+ int r = -ENODEV;
+ struct kvm_assigned_dev_kernel *match;
+
+ mutex_lock(&kvm->lock);
+
+ match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+ assigned_irq->assigned_dev_id);
+ if (!match)
+ goto out;
+
+ r = kvm_deassign_irq(kvm, match, assigned_irq->flags);
+out:
mutex_unlock(&kvm->lock);
- kvm_free_assigned_device(kvm, match);
return r;
}
@@ -427,7 +588,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
assigned_dev->assigned_dev_id);
if (match) {
/* device already assigned */
- r = -EINVAL;
+ r = -EEXIST;
goto out;
}
@@ -464,8 +625,12 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
match->host_devfn = assigned_dev->devfn;
match->flags = assigned_dev->flags;
match->dev = dev;
+ spin_lock_init(&match->assigned_dev_lock);
match->irq_source_id = -1;
match->kvm = kvm;
+ match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq;
+ INIT_WORK(&match->interrupt_work,
+ kvm_assigned_dev_interrupt_work_handler);
list_add(&match->list, &kvm->arch.assigned_dev_head);
@@ -878,6 +1043,8 @@ static void kvm_destroy_vm(struct kvm *kvm)
#endif
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
+#else
+ kvm_arch_flush_shadow(kvm);
#endif
kvm_arch_destroy_vm(kvm);
mmdrop(mm);
@@ -1454,12 +1621,14 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
for (;;) {
prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
- if (kvm_cpu_has_interrupt(vcpu) ||
- kvm_cpu_has_pending_timer(vcpu) ||
- kvm_arch_vcpu_runnable(vcpu)) {
+ if ((kvm_arch_interrupt_allowed(vcpu) &&
+ kvm_cpu_has_interrupt(vcpu)) ||
+ kvm_arch_vcpu_runnable(vcpu)) {
set_bit(KVM_REQ_UNHALT, &vcpu->requests);
break;
}
+ if (kvm_cpu_has_pending_timer(vcpu))
+ break;
if (signal_pending(current))
break;
@@ -1593,6 +1762,88 @@ static int kvm_vcpu_ioctl_set_sigmask(struct kvm_vcpu *vcpu, sigset_t *sigset)
return 0;
}
+#ifdef __KVM_HAVE_MSIX
+static int kvm_vm_ioctl_set_msix_nr(struct kvm *kvm,
+ struct kvm_assigned_msix_nr *entry_nr)
+{
+ int r = 0;
+ struct kvm_assigned_dev_kernel *adev;
+
+ mutex_lock(&kvm->lock);
+
+ adev = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+ entry_nr->assigned_dev_id);
+ if (!adev) {
+ r = -EINVAL;
+ goto msix_nr_out;
+ }
+
+ if (adev->entries_nr == 0) {
+ adev->entries_nr = entry_nr->entry_nr;
+ if (adev->entries_nr == 0 ||
+ adev->entries_nr >= KVM_MAX_MSIX_PER_DEV) {
+ r = -EINVAL;
+ goto msix_nr_out;
+ }
+
+ adev->host_msix_entries = kzalloc(sizeof(struct msix_entry) *
+ entry_nr->entry_nr,
+ GFP_KERNEL);
+ if (!adev->host_msix_entries) {
+ r = -ENOMEM;
+ goto msix_nr_out;
+ }
+ adev->guest_msix_entries = kzalloc(
+ sizeof(struct kvm_guest_msix_entry) *
+ entry_nr->entry_nr, GFP_KERNEL);
+ if (!adev->guest_msix_entries) {
+ kfree(adev->host_msix_entries);
+ r = -ENOMEM;
+ goto msix_nr_out;
+ }
+ } else /* Not allowed set MSI-X number twice */
+ r = -EINVAL;
+msix_nr_out:
+ mutex_unlock(&kvm->lock);
+ return r;
+}
+
+static int kvm_vm_ioctl_set_msix_entry(struct kvm *kvm,
+ struct kvm_assigned_msix_entry *entry)
+{
+ int r = 0, i;
+ struct kvm_assigned_dev_kernel *adev;
+
+ mutex_lock(&kvm->lock);
+
+ adev = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+ entry->assigned_dev_id);
+
+ if (!adev) {
+ r = -EINVAL;
+ goto msix_entry_out;
+ }
+
+ for (i = 0; i < adev->entries_nr; i++)
+ if (adev->guest_msix_entries[i].vector == 0 ||
+ adev->guest_msix_entries[i].entry == entry->entry) {
+ adev->guest_msix_entries[i].entry = entry->entry;
+ adev->guest_msix_entries[i].vector = entry->gsi;
+ adev->host_msix_entries[i].entry = entry->entry;
+ break;
+ }
+ if (i == adev->entries_nr) {
+ r = -ENOSPC;
+ goto msix_entry_out;
+ }
+
+msix_entry_out:
+ mutex_unlock(&kvm->lock);
+
+ return r;
+}
+#endif
+
static long kvm_vcpu_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
@@ -1864,6 +2115,11 @@ static long kvm_vm_ioctl(struct file *filp,
break;
}
case KVM_ASSIGN_IRQ: {
+ r = -EOPNOTSUPP;
+ break;
+ }
+#ifdef KVM_CAP_ASSIGN_DEV_IRQ
+ case KVM_ASSIGN_DEV_IRQ: {
struct kvm_assigned_irq assigned_irq;
r = -EFAULT;
@@ -1874,6 +2130,18 @@ static long kvm_vm_ioctl(struct file *filp,
goto out;
break;
}
+ case KVM_DEASSIGN_DEV_IRQ: {
+ struct kvm_assigned_irq assigned_irq;
+
+ r = -EFAULT;
+ if (copy_from_user(&assigned_irq, argp, sizeof assigned_irq))
+ goto out;
+ r = kvm_vm_ioctl_deassign_dev_irq(kvm, &assigned_irq);
+ if (r)
+ goto out;
+ break;
+ }
+#endif
#endif
#ifdef KVM_CAP_DEVICE_DEASSIGNMENT
case KVM_DEASSIGN_PCI_DEVICE: {
@@ -1917,7 +2185,29 @@ static long kvm_vm_ioctl(struct file *filp,
vfree(entries);
break;
}
+#ifdef __KVM_HAVE_MSIX
+ case KVM_ASSIGN_SET_MSIX_NR: {
+ struct kvm_assigned_msix_nr entry_nr;
+ r = -EFAULT;
+ if (copy_from_user(&entry_nr, argp, sizeof entry_nr))
+ goto out;
+ r = kvm_vm_ioctl_set_msix_nr(kvm, &entry_nr);
+ if (r)
+ goto out;
+ break;
+ }
+ case KVM_ASSIGN_SET_MSIX_ENTRY: {
+ struct kvm_assigned_msix_entry entry;
+ r = -EFAULT;
+ if (copy_from_user(&entry, argp, sizeof entry))
+ goto out;
+ r = kvm_vm_ioctl_set_msix_entry(kvm, &entry);
+ if (r)
+ goto out;
+ break;
+ }
#endif
+#endif /* KVM_CAP_IRQ_ROUTING */
default:
r = kvm_arch_vm_ioctl(filp, ioctl, arg);
}
@@ -2112,15 +2402,15 @@ EXPORT_SYMBOL_GPL(kvm_handle_fault_on_reboot);
static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
void *v)
{
- if (val == SYS_RESTART) {
- /*
- * Some (well, at least mine) BIOSes hang on reboot if
- * in vmx root mode.
- */
- printk(KERN_INFO "kvm: exiting hardware virtualization\n");
- kvm_rebooting = true;
- on_each_cpu(hardware_disable, NULL, 1);
- }
+ /*
+ * Some (well, at least mine) BIOSes hang on reboot if
+ * in vmx root mode.
+ *
+ * And Intel TXT required VMX off for all cpu when system shutdown.
+ */
+ printk(KERN_INFO "kvm: exiting hardware virtualization\n");
+ kvm_rebooting = true;
+ on_each_cpu(hardware_disable, NULL, 1);
return NOTIFY_OK;
}
@@ -2353,9 +2643,6 @@ int kvm_init(void *opaque, unsigned int vcpu_size,
kvm_preempt_ops.sched_in = kvm_sched_in;
kvm_preempt_ops.sched_out = kvm_sched_out;
-#ifndef CONFIG_X86
- msi2intx = 0;
-#endif
return 0;